summaryrefslogtreecommitdiff
path: root/libc/sysdeps
diff options
context:
space:
mode:
authorgcc <gcc@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2006-08-17 01:18:26 +0000
committergcc <gcc@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2006-08-17 01:18:26 +0000
commit15f34685e7a9b5caf761af2ebf6afa20438d440b (patch)
treedc04ce3cdf040f198743c15b64557824de174680 /libc/sysdeps
parent1e848e0e775a36f6359161f5deb890942ef42ff3 (diff)
Import glibc-mainline for 2006-08-16
git-svn-id: svn://svn.eglibc.org/fsf/trunk@4 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/sysdeps')
-rw-r--r--libc/sysdeps/alpha/Implies6
-rw-r--r--libc/sysdeps/alpha/Makefile47
-rw-r--r--libc/sysdeps/alpha/Subdirs1
-rw-r--r--libc/sysdeps/alpha/Versions13
-rw-r--r--libc/sysdeps/alpha/__longjmp.S64
-rw-r--r--libc/sysdeps/alpha/_mcount.S107
-rw-r--r--libc/sysdeps/alpha/add_n.s120
-rw-r--r--libc/sysdeps/alpha/addmul_1.s92
-rw-r--r--libc/sysdeps/alpha/alphaev5/add_n.s148
-rw-r--r--libc/sysdeps/alpha/alphaev5/lshift.s174
-rw-r--r--libc/sysdeps/alpha/alphaev5/rshift.s172
-rw-r--r--libc/sysdeps/alpha/alphaev5/sub_n.s149
-rw-r--r--libc/sysdeps/alpha/alphaev6/Implies1
-rw-r--r--libc/sysdeps/alpha/alphaev6/addmul_1.s479
-rw-r--r--libc/sysdeps/alpha/alphaev6/fpu/e_sqrt.S45
-rw-r--r--libc/sysdeps/alpha/alphaev6/fpu/e_sqrtf.S45
-rw-r--r--libc/sysdeps/alpha/alphaev6/memchr.S193
-rw-r--r--libc/sysdeps/alpha/alphaev6/memcpy.S256
-rw-r--r--libc/sysdeps/alpha/alphaev6/memset.S224
-rw-r--r--libc/sysdeps/alpha/alphaev6/stxcpy.S328
-rw-r--r--libc/sysdeps/alpha/alphaev6/stxncpy.S403
-rw-r--r--libc/sysdeps/alpha/alphaev67/Implies1
-rw-r--r--libc/sysdeps/alpha/alphaev67/ffs.S51
-rw-r--r--libc/sysdeps/alpha/alphaev67/ffsll.S45
-rw-r--r--libc/sysdeps/alpha/alphaev67/fpu/Implies1
-rw-r--r--libc/sysdeps/alpha/alphaev67/rawmemchr.S93
-rw-r--r--libc/sysdeps/alpha/alphaev67/stpcpy.S54
-rw-r--r--libc/sysdeps/alpha/alphaev67/stpncpy.S116
-rw-r--r--libc/sysdeps/alpha/alphaev67/strcat.S62
-rw-r--r--libc/sysdeps/alpha/alphaev67/strchr.S101
-rw-r--r--libc/sysdeps/alpha/alphaev67/strlen.S61
-rw-r--r--libc/sysdeps/alpha/alphaev67/strncat.S88
-rw-r--r--libc/sysdeps/alpha/alphaev67/strrchr.S117
-rw-r--r--libc/sysdeps/alpha/backtrace.c1
-rw-r--r--libc/sysdeps/alpha/bb_init_func.S87
-rw-r--r--libc/sysdeps/alpha/bits/atomic.h369
-rw-r--r--libc/sysdeps/alpha/bits/endian.h7
-rw-r--r--libc/sysdeps/alpha/bits/link.h69
-rw-r--r--libc/sysdeps/alpha/bits/mathdef.h80
-rw-r--r--libc/sysdeps/alpha/bits/setjmp.h62
-rw-r--r--libc/sysdeps/alpha/bsd-_setjmp.S1
-rw-r--r--libc/sysdeps/alpha/bsd-setjmp.S1
-rw-r--r--libc/sysdeps/alpha/bzero.S120
-rw-r--r--libc/sysdeps/alpha/div.S88
-rw-r--r--libc/sysdeps/alpha/div_libc.h164
-rw-r--r--libc/sysdeps/alpha/divl.S84
-rw-r--r--libc/sysdeps/alpha/divlu.S4
-rw-r--r--libc/sysdeps/alpha/divq.S274
-rw-r--r--libc/sysdeps/alpha/divqu.S257
-rw-r--r--libc/sysdeps/alpha/dl-dtprocnum.h3
-rw-r--r--libc/sysdeps/alpha/dl-machine.h522
-rw-r--r--libc/sysdeps/alpha/dl-sysdep.h24
-rw-r--r--libc/sysdeps/alpha/dl-tls.h29
-rw-r--r--libc/sysdeps/alpha/dl-trampoline.S541
-rwxr-xr-xlibc/sysdeps/alpha/elf/configure106
-rw-r--r--libc/sysdeps/alpha/elf/configure.in78
-rw-r--r--libc/sysdeps/alpha/elf/initfini.c110
-rw-r--r--libc/sysdeps/alpha/elf/start.S87
-rw-r--r--libc/sysdeps/alpha/ffs.S91
-rw-r--r--libc/sysdeps/alpha/ffsll.S1
-rw-r--r--libc/sysdeps/alpha/fpu/Versions23
-rw-r--r--libc/sysdeps/alpha/fpu/bits/fenv.h123
-rw-r--r--libc/sysdeps/alpha/fpu/bits/mathinline.h183
-rw-r--r--libc/sysdeps/alpha/fpu/cabsf.c42
-rw-r--r--libc/sysdeps/alpha/fpu/cargf.c42
-rw-r--r--libc/sysdeps/alpha/fpu/cfloat-compat.h74
-rw-r--r--libc/sysdeps/alpha/fpu/cimagf.c41
-rw-r--r--libc/sysdeps/alpha/fpu/conjf.c43
-rw-r--r--libc/sysdeps/alpha/fpu/crealf.c41
-rw-r--r--libc/sysdeps/alpha/fpu/e_sqrt.c165
-rw-r--r--libc/sysdeps/alpha/fpu/fclrexcpt.c47
-rw-r--r--libc/sysdeps/alpha/fpu/fedisblxcpt.c36
-rw-r--r--libc/sysdeps/alpha/fpu/feenablxcpt.c36
-rw-r--r--libc/sysdeps/alpha/fpu/fegetenv.c47
-rw-r--r--libc/sysdeps/alpha/fpu/fegetexcept.c31
-rw-r--r--libc/sysdeps/alpha/fpu/fegetround.c31
-rw-r--r--libc/sysdeps/alpha/fpu/feholdexcpt.c34
-rw-r--r--libc/sysdeps/alpha/fpu/fenv_libc.h36
-rw-r--r--libc/sysdeps/alpha/fpu/fesetenv.c57
-rw-r--r--libc/sysdeps/alpha/fpu/fesetround.c43
-rw-r--r--libc/sysdeps/alpha/fpu/feupdateenv.c49
-rw-r--r--libc/sysdeps/alpha/fpu/fgetexcptflg.c44
-rw-r--r--libc/sysdeps/alpha/fpu/fpu_control.h106
-rw-r--r--libc/sysdeps/alpha/fpu/fsetexcptflg.c47
-rw-r--r--libc/sysdeps/alpha/fpu/ftestexcept.c32
-rw-r--r--libc/sysdeps/alpha/fpu/libm-test-ulps886
-rw-r--r--libc/sysdeps/alpha/fpu/s_cacosf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_cacoshf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_casinf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_casinhf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_catanf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_catanhf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_ccosf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_ccoshf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_ceil.c58
-rw-r--r--libc/sysdeps/alpha/fpu/s_ceilf.c55
-rw-r--r--libc/sysdeps/alpha/fpu/s_cexpf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_clog10f.c61
-rw-r--r--libc/sysdeps/alpha/fpu/s_clogf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_copysign.c41
-rw-r--r--libc/sysdeps/alpha/fpu/s_copysignf.c29
-rw-r--r--libc/sysdeps/alpha/fpu/s_cpowf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_cprojf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_csinf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_csinhf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_csqrtf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_ctanf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_ctanhf.c51
-rw-r--r--libc/sysdeps/alpha/fpu/s_fabs.c41
-rw-r--r--libc/sysdeps/alpha/fpu/s_fabsf.c33
-rw-r--r--libc/sysdeps/alpha/fpu/s_floor.c59
-rw-r--r--libc/sysdeps/alpha/fpu/s_floorf.c56
-rw-r--r--libc/sysdeps/alpha/fpu/s_rint.c54
-rw-r--r--libc/sysdeps/alpha/fpu/s_rintf.c52
-rw-r--r--libc/sysdeps/alpha/gccframe.h22
-rw-r--r--libc/sysdeps/alpha/hp-timing.h118
-rw-r--r--libc/sysdeps/alpha/htonl.S44
-rw-r--r--libc/sysdeps/alpha/htons.S40
-rw-r--r--libc/sysdeps/alpha/jmpbuf-offsets.h36
-rw-r--r--libc/sysdeps/alpha/jmpbuf-unwind.h48
-rw-r--r--libc/sysdeps/alpha/ldiv.S218
-rw-r--r--libc/sysdeps/alpha/libc-tls.c37
-rw-r--r--libc/sysdeps/alpha/lldiv.S1
-rw-r--r--libc/sysdeps/alpha/lshift.s109
-rw-r--r--libc/sysdeps/alpha/machine-gmon.h26
-rw-r--r--libc/sysdeps/alpha/memchr.S176
-rw-r--r--libc/sysdeps/alpha/memset.S137
-rw-r--r--libc/sysdeps/alpha/memusage.h21
-rw-r--r--libc/sysdeps/alpha/mul_1.s85
-rw-r--r--libc/sysdeps/alpha/nscd-types.h22
-rw-r--r--libc/sysdeps/alpha/rawmemchr.S90
-rw-r--r--libc/sysdeps/alpha/reml.S87
-rw-r--r--libc/sysdeps/alpha/remlu.S4
-rw-r--r--libc/sysdeps/alpha/remq.S269
-rw-r--r--libc/sysdeps/alpha/remqu.S272
-rw-r--r--libc/sysdeps/alpha/rshift.s107
-rw-r--r--libc/sysdeps/alpha/setjmp.S120
-rw-r--r--libc/sysdeps/alpha/soft-fp/Makefile10
-rw-r--r--libc/sysdeps/alpha/soft-fp/Versions8
-rw-r--r--libc/sysdeps/alpha/soft-fp/e_sqrtl.c40
-rw-r--r--libc/sysdeps/alpha/soft-fp/local-soft-fp.h44
-rw-r--r--libc/sysdeps/alpha/soft-fp/ots_add.c39
-rw-r--r--libc/sysdeps/alpha/soft-fp/ots_cmp.c64
-rw-r--r--libc/sysdeps/alpha/soft-fp/ots_cmpe.c83
-rw-r--r--libc/sysdeps/alpha/soft-fp/ots_cvtqux.c40
-rw-r--r--libc/sysdeps/alpha/soft-fp/ots_cvtqx.c39
-rw-r--r--libc/sysdeps/alpha/soft-fp/ots_cvttx.c48
-rw-r--r--libc/sysdeps/alpha/soft-fp/ots_cvtxq.c44
-rw-r--r--libc/sysdeps/alpha/soft-fp/ots_cvtxt.c44
-rw-r--r--libc/sysdeps/alpha/soft-fp/ots_div.c39
-rw-r--r--libc/sysdeps/alpha/soft-fp/ots_mul.c39
-rw-r--r--libc/sysdeps/alpha/soft-fp/ots_nintxq.c52
-rw-r--r--libc/sysdeps/alpha/soft-fp/ots_sub.c39
-rw-r--r--libc/sysdeps/alpha/soft-fp/sfp-machine.h94
-rw-r--r--libc/sysdeps/alpha/stackinfo.h28
-rw-r--r--libc/sysdeps/alpha/stpcpy.S56
-rw-r--r--libc/sysdeps/alpha/stpncpy.S107
-rw-r--r--libc/sysdeps/alpha/strcat.S72
-rw-r--r--libc/sysdeps/alpha/strchr.S95
-rw-r--r--libc/sysdeps/alpha/strcmp.S195
-rw-r--r--libc/sysdeps/alpha/strcpy.S42
-rw-r--r--libc/sysdeps/alpha/strlen.S77
-rw-r--r--libc/sysdeps/alpha/strncat.S95
-rw-r--r--libc/sysdeps/alpha/strncmp.S247
-rw-r--r--libc/sysdeps/alpha/strncpy.S88
-rw-r--r--libc/sysdeps/alpha/strrchr.S111
-rw-r--r--libc/sysdeps/alpha/stxcpy.S307
-rw-r--r--libc/sysdeps/alpha/stxncpy.S363
-rw-r--r--libc/sysdeps/alpha/sub_n.s120
-rw-r--r--libc/sysdeps/alpha/submul_1.s92
-rw-r--r--libc/sysdeps/alpha/udiv_qrnnd.S161
-rw-r--r--libc/sysdeps/generic/Makefile30
-rw-r--r--libc/sysdeps/generic/_G_config.h95
-rw-r--r--libc/sysdeps/generic/a.out.h339
-rw-r--r--libc/sysdeps/generic/abort-instr.h2
-rw-r--r--libc/sysdeps/generic/aio_misc.h48
-rw-r--r--libc/sysdeps/generic/allocalim.h4
-rw-r--r--libc/sysdeps/generic/asm-syntax.h3
-rw-r--r--libc/sysdeps/generic/bp-checks.h129
-rw-r--r--libc/sysdeps/generic/bp-semctl.h67
-rw-r--r--libc/sysdeps/generic/bp-start.h72
-rw-r--r--libc/sysdeps/generic/bp-sym.h26
-rw-r--r--libc/sysdeps/generic/bp-thunks.h70
-rw-r--r--libc/sysdeps/generic/confstr.h4
-rw-r--r--libc/sysdeps/generic/device-nrs.h28
-rw-r--r--libc/sysdeps/generic/dirstream.h30
-rw-r--r--libc/sysdeps/generic/dl-cache.h105
-rw-r--r--libc/sysdeps/generic/dl-dtprocnum.h22
-rw-r--r--libc/sysdeps/generic/dl-fptr.h46
-rw-r--r--libc/sysdeps/generic/dl-hash.h75
-rw-r--r--libc/sysdeps/generic/dl-librecon.h26
-rw-r--r--libc/sysdeps/generic/dl-lookupcfg.h29
-rw-r--r--libc/sysdeps/generic/dl-machine.h135
-rw-r--r--libc/sysdeps/generic/dl-osinfo.h12
-rw-r--r--libc/sysdeps/generic/dl-procinfo.c1
-rw-r--r--libc/sysdeps/generic/dl-procinfo.h46
-rw-r--r--libc/sysdeps/generic/dl-sysdep.h35
-rw-r--r--libc/sysdeps/generic/dl-tls.h2
-rw-r--r--libc/sysdeps/generic/dwarf2.h585
-rw-r--r--libc/sysdeps/generic/elf/backtracesyms.c102
-rw-r--r--libc/sysdeps/generic/elf/backtracesymsfd.c110
-rw-r--r--libc/sysdeps/generic/entry.h5
-rw-r--r--libc/sysdeps/generic/errqueue.h7
-rw-r--r--libc/sysdeps/generic/fd_to_filename.h26
-rw-r--r--libc/sysdeps/generic/fork.h8
-rw-r--r--libc/sysdeps/generic/fpu_control.h39
-rw-r--r--libc/sysdeps/generic/frame.h24
-rw-r--r--libc/sysdeps/generic/framestate.c52
-rw-r--r--libc/sysdeps/generic/gccframe.h50
-rw-r--r--libc/sysdeps/generic/gmp-mparam.h28
-rw-r--r--libc/sysdeps/generic/hp-timing.h83
-rw-r--r--libc/sysdeps/generic/ifreq.h44
-rw-r--r--libc/sysdeps/generic/initfini.c139
-rw-r--r--libc/sysdeps/generic/intr-msg.h15
-rw-r--r--libc/sysdeps/generic/inttypes.h461
-rw-r--r--libc/sysdeps/generic/ldconfig.h72
-rw-r--r--libc/sysdeps/generic/ldsodefs.h1080
-rw-r--r--libc/sysdeps/generic/libm-test-ulps5
-rw-r--r--libc/sysdeps/generic/local-setxid.h4
-rw-r--r--libc/sysdeps/generic/machine-gmon.h54
-rw-r--r--libc/sysdeps/generic/machine-lock.h64
-rw-r--r--libc/sysdeps/generic/machine-sp.h36
-rw-r--r--libc/sysdeps/generic/malloc-machine.h68
-rw-r--r--libc/sysdeps/generic/math_ldbl.h5
-rw-r--r--libc/sysdeps/generic/math_ldbl_opt.h14
-rw-r--r--libc/sysdeps/generic/memcopy.h150
-rw-r--r--libc/sysdeps/generic/memusage.h51
-rw-r--r--libc/sysdeps/generic/net/if.h50
-rw-r--r--libc/sysdeps/generic/netinet/if_ether.h33
-rw-r--r--libc/sysdeps/generic/netinet/in_systm.h41
-rw-r--r--libc/sysdeps/generic/netinet/ip.h249
-rw-r--r--libc/sysdeps/generic/netinet/tcp.h108
-rw-r--r--libc/sysdeps/generic/nfs/nfs.h32
-rw-r--r--libc/sysdeps/generic/not-cancel.h47
-rw-r--r--libc/sysdeps/generic/nscd-types.h22
-rw-r--r--libc/sysdeps/generic/pagecopy.h75
-rw-r--r--libc/sysdeps/generic/paths.h74
-rw-r--r--libc/sysdeps/generic/profil-counter.h27
-rw-r--r--libc/sysdeps/generic/pty-private.h45
-rw-r--r--libc/sysdeps/generic/register-dump.h21
-rw-r--r--libc/sysdeps/generic/sigcontextinfo.h27
-rw-r--r--libc/sysdeps/generic/siglist.h75
-rw-r--r--libc/sysdeps/generic/sigset-cvt-mask.h64
-rw-r--r--libc/sysdeps/generic/stackinfo.h21
-rw-r--r--libc/sysdeps/generic/stdint.h320
-rw-r--r--libc/sysdeps/generic/symbol-hacks.h1
-rw-r--r--libc/sysdeps/generic/sys/param.h15
-rw-r--r--libc/sysdeps/generic/sys/ptrace.h138
-rw-r--r--libc/sysdeps/generic/sys/reboot.h9
-rw-r--r--libc/sysdeps/generic/sys/socketvar.h3
-rw-r--r--libc/sysdeps/generic/sys/swap.h33
-rw-r--r--libc/sysdeps/generic/sys/syscall.h2
-rw-r--r--libc/sysdeps/generic/sys/sysinfo.h41
-rw-r--r--libc/sysdeps/generic/sys/sysmacros.h31
-rw-r--r--libc/sysdeps/generic/sys/ttydefaults.h100
-rw-r--r--libc/sysdeps/generic/sys/ucontext.h45
-rw-r--r--libc/sysdeps/generic/sysdep-cancel.h7
-rw-r--r--libc/sysdeps/generic/sysdep.h137
-rw-r--r--libc/sysdeps/generic/testrtsig.h28
-rw-r--r--libc/sysdeps/generic/thread_state.h47
-rw-r--r--libc/sysdeps/generic/tls-macros.h12
-rw-r--r--libc/sysdeps/generic/tls.h81
-rw-r--r--libc/sysdeps/generic/tst-audit.h11
-rw-r--r--libc/sysdeps/generic/tst-stack-align.h35
-rw-r--r--libc/sysdeps/generic/unsecvars.h25
-rw-r--r--libc/sysdeps/generic/unwind-dw2-fde-glibc.c278
-rw-r--r--libc/sysdeps/generic/unwind-dw2-fde.c1063
-rw-r--r--libc/sysdeps/generic/unwind-dw2-fde.h171
-rw-r--r--libc/sysdeps/generic/unwind-dw2.c1300
-rw-r--r--libc/sysdeps/generic/unwind-pe.c5
-rw-r--r--libc/sysdeps/generic/unwind-pe.h306
-rw-r--r--libc/sysdeps/generic/unwind.h220
-rw-r--r--libc/sysdeps/generic/utmp-equal.h53
-rw-r--r--libc/sysdeps/gnu/Makefile79
-rw-r--r--libc/sysdeps/gnu/_G_config.h103
-rw-r--r--libc/sysdeps/gnu/bits/ipc.h52
-rw-r--r--libc/sysdeps/gnu/bits/msq.h77
-rw-r--r--libc/sysdeps/gnu/bits/sem.h88
-rw-r--r--libc/sysdeps/gnu/bits/shm.h97
-rw-r--r--libc/sysdeps/gnu/bits/utmp.h125
-rw-r--r--libc/sysdeps/gnu/bits/utmpx.h103
-rw-r--r--libc/sysdeps/gnu/errlist-compat.awk129
-rw-r--r--libc/sysdeps/gnu/errlist.awk121
-rw-r--r--libc/sysdeps/gnu/errlist.c1472
-rw-r--r--libc/sysdeps/gnu/getutmp.c33
-rw-r--r--libc/sysdeps/gnu/getutmpx.c1
-rw-r--r--libc/sysdeps/gnu/glob64.c25
-rw-r--r--libc/sysdeps/gnu/ifaddrs.c163
-rw-r--r--libc/sysdeps/gnu/net/if.h205
-rw-r--r--libc/sysdeps/gnu/netinet/ip_icmp.h283
-rw-r--r--libc/sysdeps/gnu/netinet/tcp.h225
-rw-r--r--libc/sysdeps/gnu/netinet/udp.h79
-rw-r--r--libc/sysdeps/gnu/siglist.c77
-rw-r--r--libc/sysdeps/gnu/sys/mtio.h277
-rw-r--r--libc/sysdeps/gnu/updwtmp.c30
-rw-r--r--libc/sysdeps/gnu/utmp_file.c30
-rw-r--r--libc/sysdeps/gnu/utmpx.h127
-rw-r--r--libc/sysdeps/i386/Implies4
-rw-r--r--libc/sysdeps/i386/Makefile67
-rw-r--r--libc/sysdeps/i386/Versions29
-rw-r--r--libc/sysdeps/i386/__longjmp.S78
-rw-r--r--libc/sysdeps/i386/abort-instr.h2
-rw-r--r--libc/sysdeps/i386/add_n.S123
-rw-r--r--libc/sysdeps/i386/addmul_1.S97
-rw-r--r--libc/sysdeps/i386/asm-syntax.h41
-rw-r--r--libc/sysdeps/i386/backtrace.c144
-rw-r--r--libc/sysdeps/i386/bits/byteswap.h133
-rw-r--r--libc/sysdeps/i386/bits/endian.h7
-rw-r--r--libc/sysdeps/i386/bits/huge_vall.h43
-rw-r--r--libc/sysdeps/i386/bits/link.h60
-rw-r--r--libc/sysdeps/i386/bits/linkmap.h5
-rw-r--r--libc/sysdeps/i386/bits/mathdef.h46
-rw-r--r--libc/sysdeps/i386/bits/select.h72
-rw-r--r--libc/sysdeps/i386/bits/setjmp.h32
-rw-r--r--libc/sysdeps/i386/bp-asm.h144
-rw-r--r--libc/sysdeps/i386/bsd-_setjmp.S60
-rw-r--r--libc/sysdeps/i386/bsd-setjmp.S70
-rw-r--r--libc/sysdeps/i386/bzero.c83
-rwxr-xr-xlibc/sysdeps/i386/configure54
-rw-r--r--libc/sysdeps/i386/configure.in35
-rw-r--r--libc/sysdeps/i386/dl-machine.h600
-rw-r--r--libc/sysdeps/i386/dl-procinfo.c83
-rw-r--r--libc/sysdeps/i386/dl-procinfo.h110
-rw-r--r--libc/sysdeps/i386/dl-tls.h60
-rw-r--r--libc/sysdeps/i386/dl-trampoline.S184
-rw-r--r--libc/sysdeps/i386/elf/Versions6
-rwxr-xr-xlibc/sysdeps/i386/elf/configure53
-rw-r--r--libc/sysdeps/i386/elf/configure.in38
-rw-r--r--libc/sysdeps/i386/elf/start.S143
-rw-r--r--libc/sysdeps/i386/ffs.c51
-rw-r--r--libc/sysdeps/i386/fpu/Makefile3
-rw-r--r--libc/sysdeps/i386/fpu/Versions6
-rw-r--r--libc/sysdeps/i386/fpu/bits/fenv.h90
-rw-r--r--libc/sysdeps/i386/fpu/bits/mathinline.h755
-rw-r--r--libc/sysdeps/i386/fpu/branred.c1
-rw-r--r--libc/sysdeps/i386/fpu/doasin.c1
-rw-r--r--libc/sysdeps/i386/fpu/dosincos.c1
-rw-r--r--libc/sysdeps/i386/fpu/e_acos.S21
-rw-r--r--libc/sysdeps/i386/fpu/e_acosf.S22
-rw-r--r--libc/sysdeps/i386/fpu/e_acosh.S103
-rw-r--r--libc/sysdeps/i386/fpu/e_acoshf.S103
-rw-r--r--libc/sysdeps/i386/fpu/e_acoshl.S110
-rw-r--r--libc/sysdeps/i386/fpu/e_acosl.c25
-rw-r--r--libc/sysdeps/i386/fpu/e_asin.S20
-rw-r--r--libc/sysdeps/i386/fpu/e_asinf.S21
-rw-r--r--libc/sysdeps/i386/fpu/e_atan2.S15
-rw-r--r--libc/sysdeps/i386/fpu/e_atan2f.S15
-rw-r--r--libc/sysdeps/i386/fpu/e_atan2l.c18
-rw-r--r--libc/sysdeps/i386/fpu/e_atanh.S116
-rw-r--r--libc/sysdeps/i386/fpu/e_atanhf.S109
-rw-r--r--libc/sysdeps/i386/fpu/e_atanhl.S120
-rw-r--r--libc/sysdeps/i386/fpu/e_exp.S41
-rw-r--r--libc/sysdeps/i386/fpu/e_exp10.S38
-rw-r--r--libc/sysdeps/i386/fpu/e_exp10f.S38
-rw-r--r--libc/sysdeps/i386/fpu/e_exp10l.S38
-rw-r--r--libc/sysdeps/i386/fpu/e_exp2.S37
-rw-r--r--libc/sysdeps/i386/fpu/e_exp2f.S37
-rw-r--r--libc/sysdeps/i386/fpu/e_exp2l.S37
-rw-r--r--libc/sysdeps/i386/fpu/e_expf.S42
-rw-r--r--libc/sysdeps/i386/fpu/e_expl.c77
-rw-r--r--libc/sysdeps/i386/fpu/e_fmod.S19
-rw-r--r--libc/sysdeps/i386/fpu/e_fmodf.S20
-rw-r--r--libc/sysdeps/i386/fpu/e_fmodl.c22
-rw-r--r--libc/sysdeps/i386/fpu/e_hypot.S62
-rw-r--r--libc/sysdeps/i386/fpu/e_hypotf.S62
-rw-r--r--libc/sysdeps/i386/fpu/e_log.S57
-rw-r--r--libc/sysdeps/i386/fpu/e_log10.S66
-rw-r--r--libc/sysdeps/i386/fpu/e_log10f.S67
-rw-r--r--libc/sysdeps/i386/fpu/e_log10l.S68
-rw-r--r--libc/sysdeps/i386/fpu/e_log2.S65
-rw-r--r--libc/sysdeps/i386/fpu/e_log2f.S65
-rw-r--r--libc/sysdeps/i386/fpu/e_log2l.S65
-rw-r--r--libc/sysdeps/i386/fpu/e_logf.S58
-rw-r--r--libc/sysdeps/i386/fpu/e_logl.S58
-rw-r--r--libc/sysdeps/i386/fpu/e_pow.S360
-rw-r--r--libc/sysdeps/i386/fpu/e_powf.S348
-rw-r--r--libc/sysdeps/i386/fpu/e_powl.S360
-rw-r--r--libc/sysdeps/i386/fpu/e_rem_pio2.c3
-rw-r--r--libc/sysdeps/i386/fpu/e_rem_pio2f.c3
-rw-r--r--libc/sysdeps/i386/fpu/e_rem_pio2l.c3
-rw-r--r--libc/sysdeps/i386/fpu/e_remainder.S19
-rw-r--r--libc/sysdeps/i386/fpu/e_remainderf.S19
-rw-r--r--libc/sysdeps/i386/fpu/e_remainderl.S21
-rw-r--r--libc/sysdeps/i386/fpu/e_scalb.S102
-rw-r--r--libc/sysdeps/i386/fpu/e_scalbf.S104
-rw-r--r--libc/sysdeps/i386/fpu/e_scalbl.S104
-rw-r--r--libc/sysdeps/i386/fpu/e_sqrt.S14
-rw-r--r--libc/sysdeps/i386/fpu/e_sqrtf.S14
-rw-r--r--libc/sysdeps/i386/fpu/e_sqrtl.c18
-rw-r--r--libc/sysdeps/i386/fpu/fclrexcpt.c69
-rw-r--r--libc/sysdeps/i386/fpu/fedisblxcpt.c55
-rw-r--r--libc/sysdeps/i386/fpu/feenablxcpt.c55
-rw-r--r--libc/sysdeps/i386/fpu/fegetenv.c43
-rw-r--r--libc/sysdeps/i386/fpu/fegetexcept.c32
-rw-r--r--libc/sysdeps/i386/fpu/fegetround.c31
-rw-r--r--libc/sysdeps/i386/fpu/feholdexcpt.c54
-rw-r--r--libc/sysdeps/i386/fpu/fesetenv.c88
-rw-r--r--libc/sysdeps/i386/fpu/fesetround.c53
-rw-r--r--libc/sysdeps/i386/fpu/feupdateenv.c51
-rw-r--r--libc/sysdeps/i386/fpu/fgetexcptflg.c44
-rw-r--r--libc/sysdeps/i386/fpu/fraiseexcpt.c124
-rw-r--r--libc/sysdeps/i386/fpu/fsetexcptflg.c71
-rw-r--r--libc/sysdeps/i386/fpu/ftestexcept.c40
-rw-r--r--libc/sysdeps/i386/fpu/halfulp.c1
-rw-r--r--libc/sysdeps/i386/fpu/k_rem_pio2.c3
-rw-r--r--libc/sysdeps/i386/fpu/k_rem_pio2f.c3
-rw-r--r--libc/sysdeps/i386/fpu/k_rem_pio2l.c3
-rw-r--r--libc/sysdeps/i386/fpu/libm-test-ulps1236
-rw-r--r--libc/sysdeps/i386/fpu/mpa.c1
-rw-r--r--libc/sysdeps/i386/fpu/mpatan.c1
-rw-r--r--libc/sysdeps/i386/fpu/mpatan2.c1
-rw-r--r--libc/sysdeps/i386/fpu/mpexp.c1
-rw-r--r--libc/sysdeps/i386/fpu/mplog.c1
-rw-r--r--libc/sysdeps/i386/fpu/mpsqrt.c1
-rw-r--r--libc/sysdeps/i386/fpu/mptan.c1
-rw-r--r--libc/sysdeps/i386/fpu/s_asinh.S135
-rw-r--r--libc/sysdeps/i386/fpu/s_asinhf.S135
-rw-r--r--libc/sysdeps/i386/fpu/s_asinhl.S143
-rw-r--r--libc/sysdeps/i386/fpu/s_atan.S16
-rw-r--r--libc/sysdeps/i386/fpu/s_atanf.S16
-rw-r--r--libc/sysdeps/i386/fpu/s_atanl.c22
-rw-r--r--libc/sysdeps/i386/fpu/s_cbrt.S205
-rw-r--r--libc/sysdeps/i386/fpu/s_cbrtf.S182
-rw-r--r--libc/sysdeps/i386/fpu/s_cbrtl.S233
-rw-r--r--libc/sysdeps/i386/fpu/s_ceil.S32
-rw-r--r--libc/sysdeps/i386/fpu/s_ceilf.S32
-rw-r--r--libc/sysdeps/i386/fpu/s_ceill.S33
-rw-r--r--libc/sysdeps/i386/fpu/s_cexp.S257
-rw-r--r--libc/sysdeps/i386/fpu/s_cexpf.S261
-rw-r--r--libc/sysdeps/i386/fpu/s_cexpl.S260
-rw-r--r--libc/sysdeps/i386/fpu/s_copysign.S20
-rw-r--r--libc/sysdeps/i386/fpu/s_copysignf.S20
-rw-r--r--libc/sysdeps/i386/fpu/s_copysignl.S21
-rw-r--r--libc/sysdeps/i386/fpu/s_cos.S29
-rw-r--r--libc/sysdeps/i386/fpu/s_cosf.S29
-rw-r--r--libc/sysdeps/i386/fpu/s_cosl.S31
-rw-r--r--libc/sysdeps/i386/fpu/s_expm1.S86
-rw-r--r--libc/sysdeps/i386/fpu/s_expm1f.S86
-rw-r--r--libc/sysdeps/i386/fpu/s_expm1l.S87
-rw-r--r--libc/sysdeps/i386/fpu/s_fabs.S9
-rw-r--r--libc/sysdeps/i386/fpu/s_fabsf.S9
-rw-r--r--libc/sysdeps/i386/fpu/s_fabsl.S9
-rw-r--r--libc/sysdeps/i386/fpu/s_fdim.S52
-rw-r--r--libc/sysdeps/i386/fpu/s_fdimf.S52
-rw-r--r--libc/sysdeps/i386/fpu/s_fdiml.S52
-rw-r--r--libc/sysdeps/i386/fpu/s_finite.S17
-rw-r--r--libc/sysdeps/i386/fpu/s_finitef.S16
-rw-r--r--libc/sysdeps/i386/fpu/s_finitel.S15
-rw-r--r--libc/sysdeps/i386/fpu/s_floor.S32
-rw-r--r--libc/sysdeps/i386/fpu/s_floorf.S32
-rw-r--r--libc/sysdeps/i386/fpu/s_floorl.S33
-rw-r--r--libc/sysdeps/i386/fpu/s_fma.S31
-rw-r--r--libc/sysdeps/i386/fpu/s_fmaf.S31
-rw-r--r--libc/sysdeps/i386/fpu/s_fmal.S32
-rw-r--r--libc/sysdeps/i386/fpu/s_fmax.S44
-rw-r--r--libc/sysdeps/i386/fpu/s_fmaxf.S44
-rw-r--r--libc/sysdeps/i386/fpu/s_fmaxl.S44
-rw-r--r--libc/sysdeps/i386/fpu/s_fmin.S44
-rw-r--r--libc/sysdeps/i386/fpu/s_fminf.S44
-rw-r--r--libc/sysdeps/i386/fpu/s_fminl.S44
-rw-r--r--libc/sysdeps/i386/fpu/s_fpclassifyl.c43
-rw-r--r--libc/sysdeps/i386/fpu/s_frexp.S93
-rw-r--r--libc/sysdeps/i386/fpu/s_frexpf.S90
-rw-r--r--libc/sysdeps/i386/fpu/s_frexpl.S95
-rw-r--r--libc/sysdeps/i386/fpu/s_ilogb.S38
-rw-r--r--libc/sysdeps/i386/fpu/s_ilogbf.S38
-rw-r--r--libc/sysdeps/i386/fpu/s_ilogbl.S39
-rw-r--r--libc/sysdeps/i386/fpu/s_isinfl.c37
-rw-r--r--libc/sysdeps/i386/fpu/s_isnanl.c48
-rw-r--r--libc/sysdeps/i386/fpu/s_llrint.S37
-rw-r--r--libc/sysdeps/i386/fpu/s_llrintf.S37
-rw-r--r--libc/sysdeps/i386/fpu/s_llrintl.S37
-rw-r--r--libc/sysdeps/i386/fpu/s_log1p.S69
-rw-r--r--libc/sysdeps/i386/fpu/s_log1pf.S69
-rw-r--r--libc/sysdeps/i386/fpu/s_log1pl.S76
-rw-r--r--libc/sysdeps/i386/fpu/s_logb.S16
-rw-r--r--libc/sysdeps/i386/fpu/s_logbf.S16
-rw-r--r--libc/sysdeps/i386/fpu/s_logbl.c19
-rw-r--r--libc/sysdeps/i386/fpu/s_lrint.S35
-rw-r--r--libc/sysdeps/i386/fpu/s_lrintf.S35
-rw-r--r--libc/sysdeps/i386/fpu/s_lrintl.S35
-rw-r--r--libc/sysdeps/i386/fpu/s_nearbyint.S29
-rw-r--r--libc/sysdeps/i386/fpu/s_nearbyintf.S29
-rw-r--r--libc/sysdeps/i386/fpu/s_nearbyintl.S29
-rw-r--r--libc/sysdeps/i386/fpu/s_nextafterl.c124
-rw-r--r--libc/sysdeps/i386/fpu/s_nexttoward.c106
-rw-r--r--libc/sysdeps/i386/fpu/s_nexttowardf.c86
-rw-r--r--libc/sysdeps/i386/fpu/s_remquo.S50
-rw-r--r--libc/sysdeps/i386/fpu/s_remquof.S50
-rw-r--r--libc/sysdeps/i386/fpu/s_remquol.S50
-rw-r--r--libc/sysdeps/i386/fpu/s_rint.S15
-rw-r--r--libc/sysdeps/i386/fpu/s_rintf.S15
-rw-r--r--libc/sysdeps/i386/fpu/s_rintl.c18
-rw-r--r--libc/sysdeps/i386/fpu/s_scalbln.c2
-rw-r--r--libc/sysdeps/i386/fpu/s_scalblnf.c2
-rw-r--r--libc/sysdeps/i386/fpu/s_scalblnl.c2
-rw-r--r--libc/sysdeps/i386/fpu/s_scalbn.S19
-rw-r--r--libc/sysdeps/i386/fpu/s_scalbnf.S19
-rw-r--r--libc/sysdeps/i386/fpu/s_scalbnl.S20
-rw-r--r--libc/sysdeps/i386/fpu/s_significand.S16
-rw-r--r--libc/sysdeps/i386/fpu/s_significandf.S16
-rw-r--r--libc/sysdeps/i386/fpu/s_significandl.c19
-rw-r--r--libc/sysdeps/i386/fpu/s_sin.S29
-rw-r--r--libc/sysdeps/i386/fpu/s_sincos.S65
-rw-r--r--libc/sysdeps/i386/fpu/s_sincosf.S65
-rw-r--r--libc/sysdeps/i386/fpu/s_sincosl.S65
-rw-r--r--libc/sysdeps/i386/fpu/s_sinf.S29
-rw-r--r--libc/sysdeps/i386/fpu/s_sinl.S31
-rw-r--r--libc/sysdeps/i386/fpu/s_tan.S30
-rw-r--r--libc/sysdeps/i386/fpu/s_tanf.S30
-rw-r--r--libc/sysdeps/i386/fpu/s_tanl.S32
-rw-r--r--libc/sysdeps/i386/fpu/s_trunc.S36
-rw-r--r--libc/sysdeps/i386/fpu/s_truncf.S36
-rw-r--r--libc/sysdeps/i386/fpu/s_truncl.S36
-rw-r--r--libc/sysdeps/i386/fpu/sincos32.c1
-rw-r--r--libc/sysdeps/i386/fpu/slowexp.c1
-rw-r--r--libc/sysdeps/i386/fpu/slowpow.c1
-rw-r--r--libc/sysdeps/i386/fpu/t_exp.c1
-rw-r--r--libc/sysdeps/i386/fpu_control.h102
-rw-r--r--libc/sysdeps/i386/gccframe.h28
-rw-r--r--libc/sysdeps/i386/gmp-mparam.h29
-rw-r--r--libc/sysdeps/i386/htonl.S37
-rw-r--r--libc/sysdeps/i386/htons.S36
-rw-r--r--libc/sysdeps/i386/i386-mcount.S55
-rw-r--r--libc/sysdeps/i386/i486/Versions13
-rw-r--r--libc/sysdeps/i386/i486/bits/atomic.h366
-rw-r--r--libc/sysdeps/i386/i486/bits/string.h1970
-rw-r--r--libc/sysdeps/i386/i486/htonl.S35
-rw-r--r--libc/sysdeps/i386/i486/strcat.S274
-rw-r--r--libc/sysdeps/i386/i486/string-inlines.c65
-rw-r--r--libc/sysdeps/i386/i486/strlen.S139
-rw-r--r--libc/sysdeps/i386/i586/Implies2
-rw-r--r--libc/sysdeps/i386/i586/add_n.S155
-rw-r--r--libc/sysdeps/i386/i586/addmul_1.S105
-rw-r--r--libc/sysdeps/i386/i586/bzero.S3
-rw-r--r--libc/sysdeps/i386/i586/lshift.S267
-rw-r--r--libc/sysdeps/i386/i586/memcopy.h96
-rw-r--r--libc/sysdeps/i386/i586/memcpy.S129
-rw-r--r--libc/sysdeps/i386/i586/mempcpy.S6
-rw-r--r--libc/sysdeps/i386/i586/memset.S121
-rw-r--r--libc/sysdeps/i386/i586/memusage.h1
-rw-r--r--libc/sysdeps/i386/i586/mul_1.S101
-rw-r--r--libc/sysdeps/i386/i586/rshift.S267
-rw-r--r--libc/sysdeps/i386/i586/stpcpy.S8
-rw-r--r--libc/sysdeps/i386/i586/strchr.S357
-rw-r--r--libc/sysdeps/i386/i586/strcpy.S178
-rw-r--r--libc/sysdeps/i386/i586/strlen.S189
-rw-r--r--libc/sysdeps/i386/i586/sub_n.S155
-rw-r--r--libc/sysdeps/i386/i586/submul_1.S105
-rw-r--r--libc/sysdeps/i386/i686/Implies4
-rw-r--r--libc/sysdeps/i386/i686/Makefile7
-rw-r--r--libc/sysdeps/i386/i686/add_n.S122
-rw-r--r--libc/sysdeps/i386/i686/bzero.S3
-rw-r--r--libc/sysdeps/i386/i686/dl-hash.h79
-rw-r--r--libc/sysdeps/i386/i686/ffs.c49
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fdim.S44
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fdimf.S44
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fdiml.S44
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fmax.S40
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fmaxf.S40
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fmaxl.S40
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fmin.S38
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fminf.S38
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fminl.S38
-rw-r--r--libc/sysdeps/i386/i686/hp-timing.c24
-rw-r--r--libc/sysdeps/i386/i686/hp-timing.h157
-rw-r--r--libc/sysdeps/i386/i686/memcmp.S423
-rw-r--r--libc/sysdeps/i386/i686/memcpy.S69
-rw-r--r--libc/sysdeps/i386/i686/memcpy_chk.S35
-rw-r--r--libc/sysdeps/i386/i686/memmove.S115
-rw-r--r--libc/sysdeps/i386/i686/memmove_chk.S35
-rw-r--r--libc/sysdeps/i386/i686/mempcpy.S73
-rw-r--r--libc/sysdeps/i386/i686/mempcpy_chk.S35
-rw-r--r--libc/sysdeps/i386/i686/memset.S113
-rw-r--r--libc/sysdeps/i386/i686/memset_chk.S35
-rw-r--r--libc/sysdeps/i386/i686/memusage.h22
-rw-r--r--libc/sysdeps/i386/i686/strcmp.S72
-rw-r--r--libc/sysdeps/i386/i686/strtok.S281
-rw-r--r--libc/sysdeps/i386/i686/strtok_r.S5
-rw-r--r--libc/sysdeps/i386/i686/tst-stack-align.h45
-rw-r--r--libc/sysdeps/i386/i786/Implies2
-rw-r--r--libc/sysdeps/i386/init-first.c73
-rw-r--r--libc/sysdeps/i386/jmpbuf-offsets.h26
-rw-r--r--libc/sysdeps/i386/jmpbuf-unwind.h48
-rw-r--r--libc/sysdeps/i386/ldbl2mpn.c114
-rw-r--r--libc/sysdeps/i386/lshift.S113
-rw-r--r--libc/sysdeps/i386/machine-gmon.h41
-rw-r--r--libc/sysdeps/i386/memchr.S340
-rw-r--r--libc/sysdeps/i386/memcmp.S82
-rw-r--r--libc/sysdeps/i386/memcopy.h93
-rw-r--r--libc/sysdeps/i386/memset.c86
-rw-r--r--libc/sysdeps/i386/memusage.h21
-rw-r--r--libc/sysdeps/i386/mp_clz_tab.c1
-rw-r--r--libc/sysdeps/i386/mul_1.S97
-rw-r--r--libc/sysdeps/i386/rawmemchr.S230
-rw-r--r--libc/sysdeps/i386/rshift.S119
-rw-r--r--libc/sysdeps/i386/setfpucw.c55
-rw-r--r--libc/sysdeps/i386/setjmp.S62
-rw-r--r--libc/sysdeps/i386/soft-fp/sfp-machine.h89
-rw-r--r--libc/sysdeps/i386/stackinfo.h28
-rw-r--r--libc/sysdeps/i386/stpcpy.S98
-rw-r--r--libc/sysdeps/i386/stpncpy.S161
-rw-r--r--libc/sysdeps/i386/strchr.S301
-rw-r--r--libc/sysdeps/i386/strchrnul.S286
-rw-r--r--libc/sysdeps/i386/strcspn.S247
-rw-r--r--libc/sysdeps/i386/string-inlines.c189
-rw-r--r--libc/sysdeps/i386/strlen.c36
-rw-r--r--libc/sysdeps/i386/strpbrk.S256
-rw-r--r--libc/sysdeps/i386/strrchr.S342
-rw-r--r--libc/sysdeps/i386/strspn.S247
-rw-r--r--libc/sysdeps/i386/strtok.S395
-rw-r--r--libc/sysdeps/i386/strtok_r.S5
-rw-r--r--libc/sysdeps/i386/sub_n.S124
-rw-r--r--libc/sysdeps/i386/submul_1.S97
-rw-r--r--libc/sysdeps/i386/sys/ucontext.h120
-rw-r--r--libc/sysdeps/i386/sysdep.h175
-rw-r--r--libc/sysdeps/i386/tst-stack-align.h42
-rw-r--r--libc/sysdeps/ia64/Implies5
-rw-r--r--libc/sysdeps/ia64/Makefile24
-rw-r--r--libc/sysdeps/ia64/Versions21
-rw-r--r--libc/sysdeps/ia64/_mcount.S92
-rw-r--r--libc/sysdeps/ia64/abort-instr.h3
-rw-r--r--libc/sysdeps/ia64/backtrace.c93
-rw-r--r--libc/sysdeps/ia64/bcopy.S10
-rw-r--r--libc/sysdeps/ia64/bits/atomic.h119
-rw-r--r--libc/sysdeps/ia64/bits/byteswap.h110
-rw-r--r--libc/sysdeps/ia64/bits/fenv.h87
-rw-r--r--libc/sysdeps/ia64/bits/huge_vall.h42
-rw-r--r--libc/sysdeps/ia64/bits/link.h63
-rw-r--r--libc/sysdeps/ia64/bits/linkmap.h5
-rw-r--r--libc/sysdeps/ia64/bits/mathdef.h37
-rw-r--r--libc/sysdeps/ia64/bits/xtitypes.h34
-rw-r--r--libc/sysdeps/ia64/bzero.S315
-rw-r--r--libc/sysdeps/ia64/dl-dtprocnum.h22
-rw-r--r--libc/sysdeps/ia64/dl-fptr.h36
-rw-r--r--libc/sysdeps/ia64/dl-lookupcfg.h72
-rw-r--r--libc/sysdeps/ia64/dl-machine.h512
-rw-r--r--libc/sysdeps/ia64/dl-sysdep.h24
-rw-r--r--libc/sysdeps/ia64/dl-tls.h30
-rw-r--r--libc/sysdeps/ia64/dl-trampoline.S539
-rw-r--r--libc/sysdeps/ia64/elf/configure51
-rw-r--r--libc/sysdeps/ia64/elf/configure.in36
-rw-r--r--libc/sysdeps/ia64/elf/entry.h10
-rw-r--r--libc/sysdeps/ia64/elf/initfini.c152
-rw-r--r--libc/sysdeps/ia64/elf/start.S120
-rw-r--r--libc/sysdeps/ia64/fpu/Makefile34
-rw-r--r--libc/sysdeps/ia64/fpu/README50
-rw-r--r--libc/sysdeps/ia64/fpu/Versions10
-rw-r--r--libc/sysdeps/ia64/fpu/bits/mathinline.h54
-rw-r--r--libc/sysdeps/ia64/fpu/branred.c1
-rw-r--r--libc/sysdeps/ia64/fpu/doasin.c1
-rw-r--r--libc/sysdeps/ia64/fpu/dosincos.c1
-rw-r--r--libc/sysdeps/ia64/fpu/e_acos.S878
-rw-r--r--libc/sysdeps/ia64/fpu/e_acosf.S694
-rw-r--r--libc/sysdeps/ia64/fpu/e_acosh.S1202
-rw-r--r--libc/sysdeps/ia64/fpu/e_acoshf.S1030
-rw-r--r--libc/sysdeps/ia64/fpu/e_acoshl.S1716
-rw-r--r--libc/sysdeps/ia64/fpu/e_acosl.S2552
-rw-r--r--libc/sysdeps/ia64/fpu/e_asin.S854
-rw-r--r--libc/sysdeps/ia64/fpu/e_asinf.S675
-rw-r--r--libc/sysdeps/ia64/fpu/e_asinl.S2528
-rw-r--r--libc/sysdeps/ia64/fpu/e_atan2.S1049
-rw-r--r--libc/sysdeps/ia64/fpu/e_atan2f.S900
-rw-r--r--libc/sysdeps/ia64/fpu/e_atan2l.c1
-rw-r--r--libc/sysdeps/ia64/fpu/e_atanh.S1071
-rw-r--r--libc/sysdeps/ia64/fpu/e_atanhf.S845
-rw-r--r--libc/sysdeps/ia64/fpu/e_atanhl.S1156
-rw-r--r--libc/sysdeps/ia64/fpu/e_cosh.S866
-rw-r--r--libc/sysdeps/ia64/fpu/e_coshf.S711
-rw-r--r--libc/sysdeps/ia64/fpu/e_coshl.S1095
-rw-r--r--libc/sysdeps/ia64/fpu/e_exp.S793
-rw-r--r--libc/sysdeps/ia64/fpu/e_exp10.S605
-rw-r--r--libc/sysdeps/ia64/fpu/e_exp10f.S557
-rw-r--r--libc/sysdeps/ia64/fpu/e_exp10l.S811
-rw-r--r--libc/sysdeps/ia64/fpu/e_exp2.S564
-rw-r--r--libc/sysdeps/ia64/fpu/e_exp2f.S539
-rw-r--r--libc/sysdeps/ia64/fpu/e_exp2l.S807
-rw-r--r--libc/sysdeps/ia64/fpu/e_expf.S716
-rw-r--r--libc/sysdeps/ia64/fpu/e_expl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/e_fmod.S559
-rw-r--r--libc/sysdeps/ia64/fpu/e_fmodf.S571
-rw-r--r--libc/sysdeps/ia64/fpu/e_fmodl.S672
-rw-r--r--libc/sysdeps/ia64/fpu/e_gamma_r.c1
-rw-r--r--libc/sysdeps/ia64/fpu/e_gammaf_r.c1
-rw-r--r--libc/sysdeps/ia64/fpu/e_gammal_r.c1
-rw-r--r--libc/sysdeps/ia64/fpu/e_hypot.S440
-rw-r--r--libc/sysdeps/ia64/fpu/e_hypotf.S395
-rw-r--r--libc/sysdeps/ia64/fpu/e_hypotl.S478
-rw-r--r--libc/sysdeps/ia64/fpu/e_lgamma_r.c71
-rw-r--r--libc/sysdeps/ia64/fpu/e_lgammaf_r.c71
-rw-r--r--libc/sysdeps/ia64/fpu/e_lgammal_r.c70
-rw-r--r--libc/sysdeps/ia64/fpu/e_log.S1729
-rw-r--r--libc/sysdeps/ia64/fpu/e_log10.c1
-rw-r--r--libc/sysdeps/ia64/fpu/e_log10f.c1
-rw-r--r--libc/sysdeps/ia64/fpu/e_log10l.c1
-rw-r--r--libc/sysdeps/ia64/fpu/e_log2.S711
-rw-r--r--libc/sysdeps/ia64/fpu/e_log2f.S551
-rw-r--r--libc/sysdeps/ia64/fpu/e_log2l.S817
-rw-r--r--libc/sysdeps/ia64/fpu/e_logf.S1159
-rw-r--r--libc/sysdeps/ia64/fpu/e_logl.S1200
-rw-r--r--libc/sysdeps/ia64/fpu/e_pow.S2297
-rw-r--r--libc/sysdeps/ia64/fpu/e_powf.S2066
-rw-r--r--libc/sysdeps/ia64/fpu/e_powl.S2810
-rw-r--r--libc/sysdeps/ia64/fpu/e_rem_pio2.c1
-rw-r--r--libc/sysdeps/ia64/fpu/e_rem_pio2f.c1
-rw-r--r--libc/sysdeps/ia64/fpu/e_remainder.S590
-rw-r--r--libc/sysdeps/ia64/fpu/e_remainderf.S609
-rw-r--r--libc/sysdeps/ia64/fpu/e_remainderl.S617
-rw-r--r--libc/sysdeps/ia64/fpu/e_scalb.S599
-rw-r--r--libc/sysdeps/ia64/fpu/e_scalbf.S599
-rw-r--r--libc/sysdeps/ia64/fpu/e_scalbl.S599
-rw-r--r--libc/sysdeps/ia64/fpu/e_sinh.S905
-rw-r--r--libc/sysdeps/ia64/fpu/e_sinhf.S748
-rw-r--r--libc/sysdeps/ia64/fpu/e_sinhl.S1117
-rw-r--r--libc/sysdeps/ia64/fpu/e_sqrt.S342
-rw-r--r--libc/sysdeps/ia64/fpu/e_sqrtf.S260
-rw-r--r--libc/sysdeps/ia64/fpu/e_sqrtl.S275
-rw-r--r--libc/sysdeps/ia64/fpu/fclrexcpt.c39
-rw-r--r--libc/sysdeps/ia64/fpu/fedisblxcpt.c37
-rw-r--r--libc/sysdeps/ia64/fpu/feenablxcpt.c37
-rw-r--r--libc/sysdeps/ia64/fpu/fegetenv.c29
-rw-r--r--libc/sysdeps/ia64/fpu/fegetexcept.c31
-rw-r--r--libc/sysdeps/ia64/fpu/fegetround.c31
-rw-r--r--libc/sysdeps/ia64/fpu/feholdexcpt.c34
-rw-r--r--libc/sysdeps/ia64/fpu/fesetenv.c42
-rw-r--r--libc/sysdeps/ia64/fpu/fesetround.c42
-rw-r--r--libc/sysdeps/ia64/fpu/feupdateenv.c42
-rw-r--r--libc/sysdeps/ia64/fpu/fgetexcptflg.c35
-rw-r--r--libc/sysdeps/ia64/fpu/fraiseexcpt.c79
-rw-r--r--libc/sysdeps/ia64/fpu/fsetexcptflg.c41
-rw-r--r--libc/sysdeps/ia64/fpu/ftestexcept.c32
-rw-r--r--libc/sysdeps/ia64/fpu/gen_import_file_list90
-rw-r--r--libc/sysdeps/ia64/fpu/halfulp.c1
-rw-r--r--libc/sysdeps/ia64/fpu/import_check81
-rw-r--r--libc/sysdeps/ia64/fpu/import_diffs7
-rw-r--r--libc/sysdeps/ia64/fpu/import_file.awk151
-rw-r--r--libc/sysdeps/ia64/fpu/import_intel_libm106
-rw-r--r--libc/sysdeps/ia64/fpu/k_rem_pio2.c1
-rw-r--r--libc/sysdeps/ia64/fpu/k_rem_pio2f.c1
-rw-r--r--libc/sysdeps/ia64/fpu/k_rem_pio2l.c1
-rw-r--r--libc/sysdeps/ia64/fpu/libc_libm_error.c14
-rw-r--r--libc/sysdeps/ia64/fpu/libm-symbols.h64
-rw-r--r--libc/sysdeps/ia64/fpu/libm-test-ulps1146
-rw-r--r--libc/sysdeps/ia64/fpu/libm_cpu_defs.h156
-rw-r--r--libc/sysdeps/ia64/fpu/libm_error.c4295
-rw-r--r--libc/sysdeps/ia64/fpu/libm_error_codes.h211
-rw-r--r--libc/sysdeps/ia64/fpu/libm_frexp.S209
-rw-r--r--libc/sysdeps/ia64/fpu/libm_frexp4.S199
-rw-r--r--libc/sysdeps/ia64/fpu/libm_frexp4f.S199
-rw-r--r--libc/sysdeps/ia64/fpu/libm_frexp4l.S198
-rw-r--r--libc/sysdeps/ia64/fpu/libm_frexpf.S209
-rw-r--r--libc/sysdeps/ia64/fpu/libm_frexpl.S209
-rw-r--r--libc/sysdeps/ia64/fpu/libm_lgamma.S3623
-rw-r--r--libc/sysdeps/ia64/fpu/libm_lgammaf.S2199
-rw-r--r--libc/sysdeps/ia64/fpu/libm_lgammal.S7678
-rw-r--r--libc/sysdeps/ia64/fpu/libm_reduce.S1578
-rw-r--r--libc/sysdeps/ia64/fpu/libm_scalblnf.S450
-rw-r--r--libc/sysdeps/ia64/fpu/libm_sincos.S783
-rw-r--r--libc/sysdeps/ia64/fpu/libm_sincos_large.S2757
-rw-r--r--libc/sysdeps/ia64/fpu/libm_sincosf.S745
-rw-r--r--libc/sysdeps/ia64/fpu/libm_sincosl.S2528
-rw-r--r--libc/sysdeps/ia64/fpu/libm_support.h1051
-rw-r--r--libc/sysdeps/ia64/fpu/libm_tan.S3332
-rw-r--r--libc/sysdeps/ia64/fpu/math_ldbl.h100
-rw-r--r--libc/sysdeps/ia64/fpu/mpa.c1
-rw-r--r--libc/sysdeps/ia64/fpu/mpatan.c1
-rw-r--r--libc/sysdeps/ia64/fpu/mpatan2.c1
-rw-r--r--libc/sysdeps/ia64/fpu/mpexp.c1
-rw-r--r--libc/sysdeps/ia64/fpu/mplog.c1
-rw-r--r--libc/sysdeps/ia64/fpu/mpsqrt.c1
-rw-r--r--libc/sysdeps/ia64/fpu/mptan.c1
-rw-r--r--libc/sysdeps/ia64/fpu/printf_fphex.c81
-rw-r--r--libc/sysdeps/ia64/fpu/s_asinh.S1138
-rw-r--r--libc/sysdeps/ia64/fpu/s_asinhf.S937
-rw-r--r--libc/sysdeps/ia64/fpu/s_asinhl.S1347
-rw-r--r--libc/sysdeps/ia64/fpu/s_atan.S753
-rw-r--r--libc/sysdeps/ia64/fpu/s_atanf.S556
-rw-r--r--libc/sysdeps/ia64/fpu/s_atanl.S2007
-rw-r--r--libc/sysdeps/ia64/fpu/s_cbrt.S767
-rw-r--r--libc/sysdeps/ia64/fpu/s_cbrtf.S765
-rw-r--r--libc/sysdeps/ia64/fpu/s_cbrtl.S986
-rw-r--r--libc/sysdeps/ia64/fpu/s_ceil.S224
-rw-r--r--libc/sysdeps/ia64/fpu/s_ceilf.S224
-rw-r--r--libc/sysdeps/ia64/fpu/s_ceill.S224
-rw-r--r--libc/sysdeps/ia64/fpu/s_copysign.S38
-rw-r--r--libc/sysdeps/ia64/fpu/s_copysignf.S1
-rw-r--r--libc/sysdeps/ia64/fpu/s_copysignl.S1
-rw-r--r--libc/sysdeps/ia64/fpu/s_cos.S768
-rw-r--r--libc/sysdeps/ia64/fpu/s_cosf.S717
-rw-r--r--libc/sysdeps/ia64/fpu/s_cosl.S2365
-rw-r--r--libc/sysdeps/ia64/fpu/s_erf.S926
-rw-r--r--libc/sysdeps/ia64/fpu/s_erfc.S1199
-rw-r--r--libc/sysdeps/ia64/fpu/s_erfcf.S983
-rw-r--r--libc/sysdeps/ia64/fpu/s_erfcl.S2066
-rw-r--r--libc/sysdeps/ia64/fpu/s_erff.S558
-rw-r--r--libc/sysdeps/ia64/fpu/s_erfl.S1240
-rw-r--r--libc/sysdeps/ia64/fpu/s_expm1.S886
-rw-r--r--libc/sysdeps/ia64/fpu/s_expm1f.S671
-rw-r--r--libc/sysdeps/ia64/fpu/s_expm1l.S1431
-rw-r--r--libc/sysdeps/ia64/fpu/s_fabs.S82
-rw-r--r--libc/sysdeps/ia64/fpu/s_fabsf.S82
-rw-r--r--libc/sysdeps/ia64/fpu/s_fabsl.S82
-rw-r--r--libc/sysdeps/ia64/fpu/s_fdim.S228
-rw-r--r--libc/sysdeps/ia64/fpu/s_fdimf.S228
-rw-r--r--libc/sysdeps/ia64/fpu/s_fdiml.S228
-rw-r--r--libc/sysdeps/ia64/fpu/s_finite.S45
-rw-r--r--libc/sysdeps/ia64/fpu/s_finitef.S1
-rw-r--r--libc/sysdeps/ia64/fpu/s_finitel.S1
-rw-r--r--libc/sysdeps/ia64/fpu/s_floor.S216
-rw-r--r--libc/sysdeps/ia64/fpu/s_floorf.S215
-rw-r--r--libc/sysdeps/ia64/fpu/s_floorl.S215
-rw-r--r--libc/sysdeps/ia64/fpu/s_fma.S71
-rw-r--r--libc/sysdeps/ia64/fpu/s_fmaf.S71
-rw-r--r--libc/sysdeps/ia64/fpu/s_fmal.S71
-rw-r--r--libc/sysdeps/ia64/fpu/s_fmax.S114
-rw-r--r--libc/sysdeps/ia64/fpu/s_fmaxf.S114
-rw-r--r--libc/sysdeps/ia64/fpu/s_fmaxl.S114
-rw-r--r--libc/sysdeps/ia64/fpu/s_fpclassify.S62
-rw-r--r--libc/sysdeps/ia64/fpu/s_fpclassifyf.S1
-rw-r--r--libc/sysdeps/ia64/fpu/s_fpclassifyl.S1
-rw-r--r--libc/sysdeps/ia64/fpu/s_frexp.c67
-rw-r--r--libc/sysdeps/ia64/fpu/s_frexpf.c67
-rw-r--r--libc/sysdeps/ia64/fpu/s_frexpl.c67
-rw-r--r--libc/sysdeps/ia64/fpu/s_ilogb.S268
-rw-r--r--libc/sysdeps/ia64/fpu/s_ilogbf.S268
-rw-r--r--libc/sysdeps/ia64/fpu/s_ilogbl.S268
-rw-r--r--libc/sysdeps/ia64/fpu/s_isinf.S58
-rw-r--r--libc/sysdeps/ia64/fpu/s_isinff.S1
-rw-r--r--libc/sysdeps/ia64/fpu/s_isinfl.S1
-rw-r--r--libc/sysdeps/ia64/fpu/s_isnan.S51
-rw-r--r--libc/sysdeps/ia64/fpu/s_isnanf.S1
-rw-r--r--libc/sysdeps/ia64/fpu/s_isnanl.S1
-rw-r--r--libc/sysdeps/ia64/fpu/s_ldexp.c61
-rw-r--r--libc/sysdeps/ia64/fpu/s_ldexpf.c61
-rw-r--r--libc/sysdeps/ia64/fpu/s_ldexpl.c61
-rw-r--r--libc/sysdeps/ia64/fpu/s_libm_ldexp.S452
-rw-r--r--libc/sysdeps/ia64/fpu/s_libm_ldexpf.S452
-rw-r--r--libc/sysdeps/ia64/fpu/s_libm_ldexpl.S452
-rw-r--r--libc/sysdeps/ia64/fpu/s_libm_scalbn.S452
-rw-r--r--libc/sysdeps/ia64/fpu/s_libm_scalbnf.S452
-rw-r--r--libc/sysdeps/ia64/fpu/s_libm_scalbnl.S452
-rw-r--r--libc/sysdeps/ia64/fpu/s_log1p.S1103
-rw-r--r--libc/sysdeps/ia64/fpu/s_log1pf.S789
-rw-r--r--libc/sysdeps/ia64/fpu/s_log1pl.S1200
-rw-r--r--libc/sysdeps/ia64/fpu/s_logb.S281
-rw-r--r--libc/sysdeps/ia64/fpu/s_logbf.S281
-rw-r--r--libc/sysdeps/ia64/fpu/s_logbl.S281
-rw-r--r--libc/sysdeps/ia64/fpu/s_matherrf.c33
-rw-r--r--libc/sysdeps/ia64/fpu/s_matherrl.c33
-rw-r--r--libc/sysdeps/ia64/fpu/s_modf.S278
-rw-r--r--libc/sysdeps/ia64/fpu/s_modff.S278
-rw-r--r--libc/sysdeps/ia64/fpu/s_modfl.S273
-rw-r--r--libc/sysdeps/ia64/fpu/s_nearbyint.S217
-rw-r--r--libc/sysdeps/ia64/fpu/s_nearbyintf.S217
-rw-r--r--libc/sysdeps/ia64/fpu/s_nearbyintl.S217
-rw-r--r--libc/sysdeps/ia64/fpu/s_nextafter.S498
-rw-r--r--libc/sysdeps/ia64/fpu/s_nextafterf.S504
-rw-r--r--libc/sysdeps/ia64/fpu/s_nextafterl.S503
-rw-r--r--libc/sysdeps/ia64/fpu/s_nexttoward.S490
-rw-r--r--libc/sysdeps/ia64/fpu/s_nexttowardf.S496
-rw-r--r--libc/sysdeps/ia64/fpu/s_nexttowardl.S494
-rw-r--r--libc/sysdeps/ia64/fpu/s_rint.S229
-rw-r--r--libc/sysdeps/ia64/fpu/s_rintf.S229
-rw-r--r--libc/sysdeps/ia64/fpu/s_rintl.S229
-rw-r--r--libc/sysdeps/ia64/fpu/s_round.S233
-rw-r--r--libc/sysdeps/ia64/fpu/s_roundf.S233
-rw-r--r--libc/sysdeps/ia64/fpu/s_roundl.S233
-rw-r--r--libc/sysdeps/ia64/fpu/s_scalblnf.c61
-rw-r--r--libc/sysdeps/ia64/fpu/s_scalbn.c61
-rw-r--r--libc/sysdeps/ia64/fpu/s_scalbnf.c61
-rw-r--r--libc/sysdeps/ia64/fpu/s_scalbnl.c61
-rw-r--r--libc/sysdeps/ia64/fpu/s_signbit.S37
-rw-r--r--libc/sysdeps/ia64/fpu/s_signbitf.S1
-rw-r--r--libc/sysdeps/ia64/fpu/s_signbitl.S1
-rw-r--r--libc/sysdeps/ia64/fpu/s_significand.S153
-rw-r--r--libc/sysdeps/ia64/fpu/s_significandf.S152
-rw-r--r--libc/sysdeps/ia64/fpu/s_significandl.S153
-rw-r--r--libc/sysdeps/ia64/fpu/s_sin.c1
-rw-r--r--libc/sysdeps/ia64/fpu/s_sincos.c1
-rw-r--r--libc/sysdeps/ia64/fpu/s_sincosf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/s_sincosl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/s_sinf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/s_sinl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/s_tan.S878
-rw-r--r--libc/sysdeps/ia64/fpu/s_tanf.S692
-rw-r--r--libc/sysdeps/ia64/fpu/s_tanh.S986
-rw-r--r--libc/sysdeps/ia64/fpu/s_tanhf.S581
-rw-r--r--libc/sysdeps/ia64/fpu/s_tanhl.S1348
-rw-r--r--libc/sysdeps/ia64/fpu/s_tanl.S3248
-rw-r--r--libc/sysdeps/ia64/fpu/s_trunc.S166
-rw-r--r--libc/sysdeps/ia64/fpu/s_truncf.S166
-rw-r--r--libc/sysdeps/ia64/fpu/s_truncl.S166
-rw-r--r--libc/sysdeps/ia64/fpu/sincos32.c1
-rw-r--r--libc/sysdeps/ia64/fpu/slowexp.c1
-rw-r--r--libc/sysdeps/ia64/fpu/slowpow.c1
-rw-r--r--libc/sysdeps/ia64/fpu/t_exp.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_acos.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_acosf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_acosh.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_acoshf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_acoshl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_acosl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_asin.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_asinf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_asinl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_atan2.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_atan2f.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_atan2l.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_atanh.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_atanhf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_atanhl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_cosh.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_coshf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_coshl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_exp.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_exp10.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_exp10f.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_exp10l.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_exp2.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_exp2f.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_exp2l.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_expf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_expl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_fmod.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_fmodf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_fmodl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_hypot.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_hypotf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_hypotl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_lgamma.c80
-rw-r--r--libc/sysdeps/ia64/fpu/w_lgamma_r.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_lgammaf.c80
-rw-r--r--libc/sysdeps/ia64/fpu/w_lgammaf_r.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_lgammal.c79
-rw-r--r--libc/sysdeps/ia64/fpu/w_lgammal_r.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_log.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_log10.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_log10f.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_log10l.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_log2.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_log2f.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_log2l.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_logf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_logl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_pow.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_powf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_powl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_remainder.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_remainderf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_remainderl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_scalb.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_scalbf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_scalbl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_sinh.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_sinhf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_sinhl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_sqrt.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_sqrtf.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_sqrtl.c1
-rw-r--r--libc/sysdeps/ia64/fpu/w_tgamma.S1836
-rw-r--r--libc/sysdeps/ia64/fpu/w_tgammaf.S1331
-rw-r--r--libc/sysdeps/ia64/fpu/w_tgammal.S4487
-rw-r--r--libc/sysdeps/ia64/gccframe.h32
-rw-r--r--libc/sysdeps/ia64/hp-timing.c24
-rw-r--r--libc/sysdeps/ia64/hp-timing.h148
-rw-r--r--libc/sysdeps/ia64/htonl.S31
-rw-r--r--libc/sysdeps/ia64/htons.S31
-rw-r--r--libc/sysdeps/ia64/ia64libgcc.S350
-rw-r--r--libc/sysdeps/ia64/ieee754.h205
-rw-r--r--libc/sysdeps/ia64/jmpbuf-unwind.h44
-rw-r--r--libc/sysdeps/ia64/libc-tls.c36
-rw-r--r--libc/sysdeps/ia64/machine-gmon.h26
-rw-r--r--libc/sysdeps/ia64/memccpy.S250
-rw-r--r--libc/sysdeps/ia64/memchr.S133
-rw-r--r--libc/sysdeps/ia64/memcmp.S165
-rw-r--r--libc/sysdeps/ia64/memcpy.S436
-rw-r--r--libc/sysdeps/ia64/memmove.S251
-rw-r--r--libc/sysdeps/ia64/memset.S400
-rw-r--r--libc/sysdeps/ia64/memusage.h30
-rw-r--r--libc/sysdeps/ia64/softpipe.h29
-rw-r--r--libc/sysdeps/ia64/stackinfo.h29
-rw-r--r--libc/sysdeps/ia64/strcat.c27
-rw-r--r--libc/sysdeps/ia64/strchr.S112
-rw-r--r--libc/sysdeps/ia64/strcmp.S54
-rw-r--r--libc/sysdeps/ia64/strcpy.S145
-rw-r--r--libc/sysdeps/ia64/strlen.S98
-rw-r--r--libc/sysdeps/ia64/strncmp.S62
-rw-r--r--libc/sysdeps/ia64/strncpy.S232
-rw-r--r--libc/sysdeps/ia64/sysdep.h63
-rw-r--r--libc/sysdeps/ieee754/Makefile5
-rw-r--r--libc/sysdeps/ieee754/bits/huge_val.h55
-rw-r--r--libc/sysdeps/ieee754/bits/huge_valf.h53
-rw-r--r--libc/sysdeps/ieee754/bits/inf.h30
-rw-r--r--libc/sysdeps/ieee754/bits/nan.h53
-rw-r--r--libc/sysdeps/ieee754/dbl-64/MathLib.h103
-rw-r--r--libc/sysdeps/ieee754/dbl-64/asincos.tbl5169
-rw-r--r--libc/sysdeps/ieee754/dbl-64/atnat.h167
-rw-r--r--libc/sysdeps/ieee754/dbl-64/atnat2.h185
-rw-r--r--libc/sysdeps/ieee754/dbl-64/branred.c144
-rw-r--r--libc/sysdeps/ieee754/dbl-64/branred.h80
-rw-r--r--libc/sysdeps/ieee754/dbl-64/dbl2mpn.c108
-rw-r--r--libc/sysdeps/ieee754/dbl-64/dla.h174
-rw-r--r--libc/sysdeps/ieee754/dbl-64/doasin.c76
-rw-r--r--libc/sysdeps/ieee754/dbl-64/doasin.h64
-rw-r--r--libc/sysdeps/ieee754/dbl-64/dosincos.c189
-rw-r--r--libc/sysdeps/ieee754/dbl-64/dosincos.h81
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_acos.c1
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_acosh.c69
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_asin.c637
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_atan2.c406
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_atanh.c74
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_cosh.c92
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_exp.c252
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_exp2.c135
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_fmod.c140
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_gamma_r.c57
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_hypot.c128
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_j0.c529
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_j1.c530
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_jn.c287
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_lgamma_r.c312
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_log.c203
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_log10.c98
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_log2.c130
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_pow.c388
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_rem_pio2.c183
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_remainder.c130
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_sinh.c86
-rw-r--r--libc/sysdeps/ieee754/dbl-64/e_sqrt.c88
-rw-r--r--libc/sysdeps/ieee754/dbl-64/halfulp.c123
-rw-r--r--libc/sysdeps/ieee754/dbl-64/k_cos.c1
-rw-r--r--libc/sysdeps/ieee754/dbl-64/k_rem_pio2.c320
-rw-r--r--libc/sysdeps/ieee754/dbl-64/k_sin.c1
-rw-r--r--libc/sysdeps/ieee754/dbl-64/k_tan.c145
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mpa.c508
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mpa.h85
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mpa2.h95
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mpatan.c102
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mpatan.h174
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mpatan2.c70
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mpexp.c105
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mpexp.h158
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mplog.c72
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mplog.h45
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mpn2dbl.c48
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mpsqrt.c103
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mpsqrt.h51
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mptan.c60
-rw-r--r--libc/sysdeps/ieee754/dbl-64/mydefs.h38
-rw-r--r--libc/sysdeps/ieee754/dbl-64/powtwo.tbl32
-rw-r--r--libc/sysdeps/ieee754/dbl-64/root.tbl58
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_asinh.c70
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_atan.c230
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_cbrt.c76
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_ceil.c85
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_copysign.c43
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_cos.c1
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_erf.c431
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_expm1.c243
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_fabs.c40
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_finite.c41
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_floor.c86
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_fpclassify.c44
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_frexp.c64
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_ilogb.c64
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_isinf.c33
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_isnan.c44
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_llrint.c98
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_llround.c81
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_log1p.c191
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_logb.c47
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_lrint.c98
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_lround.c81
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_modf.c85
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_nearbyint.c98
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_nexttoward.c1
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_remquo.c113
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_rint.c91
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_round.c97
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_scalbln.c70
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_scalbn.c70
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_signbit.c32
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_sin.c1129
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_sincos.c51
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_tan.c486
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_tanh.c93
-rw-r--r--libc/sysdeps/ieee754/dbl-64/s_trunc.c61
-rw-r--r--libc/sysdeps/ieee754/dbl-64/sincos.tbl912
-rw-r--r--libc/sysdeps/ieee754/dbl-64/sincos32.c352
-rw-r--r--libc/sysdeps/ieee754/dbl-64/sincos32.h82
-rw-r--r--libc/sysdeps/ieee754/dbl-64/slowexp.c66
-rw-r--r--libc/sysdeps/ieee754/dbl-64/slowpow.c74
-rw-r--r--libc/sysdeps/ieee754/dbl-64/t_exp.c436
-rw-r--r--libc/sysdeps/ieee754/dbl-64/t_exp2.h585
-rw-r--r--libc/sysdeps/ieee754/dbl-64/uasncs.h70
-rw-r--r--libc/sysdeps/ieee754/dbl-64/uatan.tbl11135
-rw-r--r--libc/sysdeps/ieee754/dbl-64/uexp.h70
-rw-r--r--libc/sysdeps/ieee754/dbl-64/uexp.tbl1787
-rw-r--r--libc/sysdeps/ieee754/dbl-64/ulog.h200
-rw-r--r--libc/sysdeps/ieee754/dbl-64/ulog.tbl3327
-rw-r--r--libc/sysdeps/ieee754/dbl-64/upow.h81
-rw-r--r--libc/sysdeps/ieee754/dbl-64/upow.tbl10189
-rw-r--r--libc/sysdeps/ieee754/dbl-64/urem.h51
-rw-r--r--libc/sysdeps/ieee754/dbl-64/uroot.h44
-rw-r--r--libc/sysdeps/ieee754/dbl-64/usncs.h80
-rw-r--r--libc/sysdeps/ieee754/dbl-64/utan.h280
-rw-r--r--libc/sysdeps/ieee754/dbl-64/utan.tbl1526
-rw-r--r--libc/sysdeps/ieee754/dbl-64/w_exp.c58
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_acosf.c89
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_acoshf.c57
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_asinf.c110
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_atan2f.c105
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_atanhf.c58
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_coshf.c72
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_exp2f.c128
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_expf.c140
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_fmodf.c113
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_gammaf_r.c56
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_hypotf.c87
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_j0f.c442
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_j1f.c442
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_jnf.c212
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_lgammaf_r.c248
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_log10f.c67
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_log2f.c90
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_logf.c99
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_powf.c257
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_rem_pio2f.c196
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_remainderf.c73
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_sinhf.c68
-rw-r--r--libc/sysdeps/ieee754/flt-32/e_sqrtf.c97
-rw-r--r--libc/sysdeps/ieee754/flt-32/k_cosf.c64
-rw-r--r--libc/sysdeps/ieee754/flt-32/k_rem_pio2f.c213
-rw-r--r--libc/sysdeps/ieee754/flt-32/k_sinf.c54
-rw-r--r--libc/sysdeps/ieee754/flt-32/k_tanf.c101
-rw-r--r--libc/sysdeps/ieee754/flt-32/mpn2flt.c42
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_asinhf.c58
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_atanf.c120
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_cbrtf.c64
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_ceilf.c62
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_copysignf.c42
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_cosf.c60
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_erff.c225
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_expm1f.c136
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_fabsf.c39
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_finitef.c40
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_floorf.c71
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_fpclassifyf.c43
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_frexpf.c53
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_ilogbf.c50
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_isinff.c29
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_isnanf.c42
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_llrintf.c78
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_llroundf.c63
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_log1pf.c115
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_logbf.c40
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_lrintf.c78
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_lroundf.c63
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_modff.c66
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_nearbyintf.c77
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_nextafterf.c77
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_remquof.c108
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_rintf.c72
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_roundf.c73
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_scalblnf.c63
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_scalbnf.c63
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_signbitf.c32
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_sincosf.c74
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_sinf.c54
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_tanf.c49
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_tanhf.c67
-rw-r--r--libc/sysdeps/ieee754/flt-32/s_truncf.c52
-rw-r--r--libc/sysdeps/ieee754/flt-32/t_exp2f.h352
-rw-r--r--libc/sysdeps/ieee754/flt-32/w_expf.c59
-rw-r--r--libc/sysdeps/ieee754/ieee754.h199
-rw-r--r--libc/sysdeps/ieee754/k_standard.c997
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/bits/huge_vall.h51
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_acoshl.c68
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_acosl.c328
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_asinl.c265
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_atan2l.c129
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_atanhl.c84
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_coshl.c120
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_expl.c249
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_fmodl.c138
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_gammal_r.c58
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_hypotl.c132
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_j0l.c922
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_j1l.c929
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_jnl.c400
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_lgammal_r.c1036
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_log10l.c258
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_log2l.c250
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_logl.c279
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_powl.c447
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_rem_pio2l.c274
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_remainderl.c78
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/e_sinhl.c123
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/ieee754.h171
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/k_cosl.c128
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/k_sincosl.c163
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/k_sinl.c132
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/k_tanl.c164
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/ldbl2mpn.c141
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/math_ldbl.h90
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/mpn2ldbl.c54
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/printf_fphex.c106
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_asinhl.c87
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_atanl.c233
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_cbrtl.c135
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_ceill.c84
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_copysignl.c43
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_cosl.c83
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_erfl.c951
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_expm1l.c161
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_fabsl.c39
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_finitel.c41
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_floorl.c85
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_fpclassifyl.c45
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_frexpl.c63
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_ilogbl.c62
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_isinfl.c29
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_isnanl.c43
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_llrintl.c75
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_llroundl.c77
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_log1pl.c256
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_logbl.c46
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_lrintl.c94
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_lroundl.c77
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_modfl.c88
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_nearbyintl.c93
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_nextafterl.c85
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_nexttoward.c104
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_nexttowardf.c81
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_remquol.c110
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_rintl.c90
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_roundl.c94
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_scalblnl.c70
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_scalbnl.c70
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_signbitl.c32
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_sincosl.c71
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_sinl.c83
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_tanhl.c106
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_tanl.c77
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/s_truncl.c57
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/strtold_l.c45
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/t_expl.h971
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/t_sincosl.c694
-rw-r--r--libc/sysdeps/ieee754/ldbl-128/w_expl.c58
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/Makefile5
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c69
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_acosl.c328
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_asinl.c265
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c124
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c79
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_coshl.c90
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_expl.c257
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c145
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c58
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c131
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_j0l.c3
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_j1l.c2
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_jnl.c402
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c3
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_log10l.c258
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_log2l.c250
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_logl.c281
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_powl.c441
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c278
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c78
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c84
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c109
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/ieee754.h210
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/k_cosl.c146
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c182
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/k_sinl.c150
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/k_tanl.c164
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c175
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h181
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c103
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c138
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c67
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_atanl.c234
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_ceill.c91
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_copysignl.c45
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_cosl.c88
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_cprojl.c54
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_ctanhl.c87
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_ctanl.c88
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_erfl.c958
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c160
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c43
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_finitel.c45
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_floorl.c85
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c82
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c92
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_ilogbl.c63
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c35
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c43
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c150
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c130
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c257
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_logbl.c47
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_lrintl.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_lroundl.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_modfl.c94
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c125
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c108
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c106
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c83
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_remquol.c111
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_rintl.c119
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_roundl.c98
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c105
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c109
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c37
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c72
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_sinl.c84
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c90
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_tanl.c78
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/s_truncl.c102
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/strtold_l.c63
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/t_sincosl.c694
-rw-r--r--libc/sysdeps/ieee754/ldbl-128ibm/w_expl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_asinhl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_atanl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_cbrtl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_ceill.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_copysignl.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_cosl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_erfl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_expm1l.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_fabsl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_finitel.c17
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_floorl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_fpclassifyl.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_frexpl.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_ilogbl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_isinfl.c16
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_isnanl.c16
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_llrintl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_llroundl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_log1pl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_logbl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_lrintl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_lroundl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_modfl.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_nearbyintl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_nextafterl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_nexttoward.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_nexttowardf.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_remquol.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_rintl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_roundl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_scalblnl.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_scalbnl.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_signbitl.c11
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_sincosl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_sinl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_tanhl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_tanl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/s_truncl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/strtold_l.c63
-rw-r--r--libc/sysdeps/ieee754/ldbl-64-128/w_expl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_acoshl.c72
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_asinl.c161
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_atan2l.c136
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_atanhl.c79
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_coshl.c93
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_gammal_r.c62
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_hypotl.c133
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_j0l.c644
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_j1l.c651
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_jnl.c386
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_lgammal_r.c446
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_remainderl.c83
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/e_sinhl.c91
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/ldbl2mpn.c95
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/math_ldbl.h98
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/mpn2ldbl.c47
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/printf_fphex.c93
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_asinhl.c70
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_cbrtl.c71
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_ceill.c94
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_copysignl.c43
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_cosl.c88
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_erfl.c454
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_fabsl.c40
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_finitel.c41
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_floorl.c95
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_fpclassifyl.c45
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_frexpl.c70
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_ilogbl.c65
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_isinfl.c30
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_isnanl.c45
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_llrintl.c77
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_llroundl.c81
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_logbl.c47
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_lrintl.c89
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_lroundl.c81
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_modfl.c85
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_nearbyintl.c95
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_nextafterl.c101
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_nexttoward.c101
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_nexttowardf.c78
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_remquol.c109
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_rintl.c91
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_roundl.c106
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_scalblnl.c71
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_scalbnl.c71
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_signbitl.c32
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_sincosl.c74
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_sinl.c88
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_tanhl.c95
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_tanl.c81
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/s_truncl.c57
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/strtold_l.c45
-rw-r--r--libc/sysdeps/ieee754/ldbl-96/w_expl.c60
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/Makefile43
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/Versions87
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/cabs.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/cabsl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/carg.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/cargl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/cimag.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/cimagl.c6
-rwxr-xr-xlibc/sysdeps/ieee754/ldbl-opt/configure69
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/configure.in19
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/conj.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/conjl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/creal.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/creall.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.c3
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h52
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-acos.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-acosh.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-asin.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-asinh.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-asprintf.c17
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-atan.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-atan2.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-atanh.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-cabs.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-cacos.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-cacosh.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-carg.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-casin.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-casinh.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-catan.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-catanh.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-cbrt.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-ccos.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-ccosh.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-ceil.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-cexp.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-cimag.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-clog.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-clog10.c11
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-compat.c852
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-compat.h87
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-conj.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-copysign.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-cos.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-cosh.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-cpow.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-cproj.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-creal.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-csin.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-csinh.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-csqrt.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-ctan.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-ctanh.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-dprintf.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-drem.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-erf.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-erfc.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-exp.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-exp10.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-exp2.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-expm1.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-fabs.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-fdim.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-finite.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-floor.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-fma.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-fmax.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-fmin.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-fmod.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-fprintf.c17
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-fprintf_chk.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-frexp.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-fwprintf.c16
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-fwprintf_chk.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-gamma.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-hypot.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-ilogb.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-isinf.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-isnan.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-j0.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-j1.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-jn.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-ldexp.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-lgamma.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-lgamma_r.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-llrint.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-llround.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-log.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-log10.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-log1p.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-log2.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-logb.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-lrint.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-lround.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-modf.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-nan.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-nearbyint.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-nextafter.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-nexttoward.c14
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-nexttowardf.c12
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-obstack_printf.c13
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-obstack_vprintf.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-pow.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-pow10.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-printf.c17
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-printf_chk.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-printf_fp.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-printf_size.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-qecvt.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-qecvt_r.c11
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-qfcvt.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-qfcvt_r.c11
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-qgcvt.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-remainder.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-remquo.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-rint.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-round.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-scalb.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-scalbln.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-scalbn.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-scanf.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-signbit.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-significand.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-sin.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-sincos.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-sinh.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-snprintf.c16
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-snprintf_chk.c16
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-sprintf.c17
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-sprintf_chk.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-sqrt.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c17
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-strfmon.c14
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-strfmon_l.c16
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-strtold.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-strtold_l.c20
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-strtoldint.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-swprintf.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-swprintf_chk.c16
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-syslog.c11
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-syslog_chk.c12
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-tan.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-tanh.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-tgamma.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-trunc.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vasprintf.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vdprintf.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vfprintf.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vfprintf_chk.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vfwprintf.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vfwprintf_chk.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vprintf.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vprintf_chk.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vsnprintf.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vsnprintf_chk.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vsprintf.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vsprintf_chk.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vswprintf.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vswprintf_chk.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vsyslog.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vsyslog_chk.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vwprintf.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vwprintf_chk.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-wcstold.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-wcstold_l.c14
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-wcstoldint.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-wprintf.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-wprintf_chk.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c15
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-y0.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-y1.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/nldbl-yn.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_asinh.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_atan.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_cacos.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_cacosh.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_cacoshl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_cacosl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_casin.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_casinh.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_casinhl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_casinl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_catan.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_catanh.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_catanhl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_catanl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_cbrt.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_ccos.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_ccosh.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_ccoshl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_ccosl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_ceil.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_cexp.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_cexpl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_clog.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_clog10.c7
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_clog10l.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_clogl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_copysign.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_cpow.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_cpowl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_cproj.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_cprojl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_csin.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_csinh.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_csinhl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_csinl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_csqrt.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_csqrtl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_ctan.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_ctanh.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_ctanhl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_ctanl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_erf.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_expm1.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_fabs.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_fdim.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_fdiml.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_finite.c18
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_floor.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_fma.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_fmal.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_fmax.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_fmaxl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_fmin.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_fminl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_frexp.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_ilogb.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_isinf.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_isnan.c8
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_ldexp.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_ldexpl.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_llrint.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_llround.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_log1p.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_logb.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_lrint.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_lround.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_modf.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_nan.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_nanl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_nearbyint.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_nextafter.c12
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c77
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_remquo.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_rint.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_round.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_scalbln.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_scalbn.c9
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_significand.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_significandl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_sin.c10
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_sincos.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_tan.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_tanh.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/s_trunc.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_acos.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_acosh.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_acoshl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_acosl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_asin.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_asinl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_atan2.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_atan2l.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_atanh.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_atanhl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_cosh.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_coshl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_drem.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_dreml.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_exp.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_exp10.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_exp10l.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_fmod.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_fmodl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_hypot.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_hypotl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_j0.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_j0l.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_j1.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_j1l.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_jn.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_jnl.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_lgamma.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_lgamma_r.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_lgammal.c6
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_lgammal_r.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_log.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_log10.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_log10l.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_log2.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_log2l.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_logl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_pow.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_powl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_remainder.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_remainderl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_scalb.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_scalbl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_sinh.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_sinhl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_sqrt.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_sqrtl.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_tgamma.c5
-rw-r--r--libc/sysdeps/ieee754/ldbl-opt/w_tgammal.c5
-rw-r--r--libc/sysdeps/ieee754/s_lib_version.c40
-rw-r--r--libc/sysdeps/ieee754/s_matherr.c35
-rw-r--r--libc/sysdeps/ieee754/s_signgam.c3
-rw-r--r--libc/sysdeps/ieee754/support.c520
-rw-r--r--libc/sysdeps/mach/Makefile52
-rw-r--r--libc/sysdeps/mach/Subdirs9
-rw-r--r--libc/sysdeps/mach/_strerror.c121
-rw-r--r--libc/sysdeps/mach/adjtime.c45
-rw-r--r--libc/sysdeps/mach/alpha/machine-lock.h80
-rw-r--r--libc/sysdeps/mach/alpha/machine-sp.h36
-rw-r--r--libc/sysdeps/mach/alpha/setfpucw.c69
-rw-r--r--libc/sysdeps/mach/alpha/syscall.S37
-rw-r--r--libc/sysdeps/mach/alpha/sysdep.h59
-rw-r--r--libc/sysdeps/mach/alpha/thread_state.h39
-rw-r--r--libc/sysdeps/mach/bits/libc-lock.h144
-rw-r--r--libc/sysdeps/mach/configure678
-rw-r--r--libc/sysdeps/mach/configure.in125
-rw-r--r--libc/sysdeps/mach/getloadavg.c54
-rw-r--r--libc/sysdeps/mach/getpagesize.c29
-rw-r--r--libc/sysdeps/mach/getsysstats.c102
-rw-r--r--libc/sysdeps/mach/gettimeofday.c48
-rw-r--r--libc/sysdeps/mach/hurd/.cvsignore4
-rw-r--r--libc/sysdeps/mach/hurd/Implies5
-rw-r--r--libc/sysdeps/mach/hurd/Makeconfig4
-rw-r--r--libc/sysdeps/mach/hurd/Makefile209
-rw-r--r--libc/sysdeps/mach/hurd/Subdirs9
-rw-r--r--libc/sysdeps/mach/hurd/Versions37
-rw-r--r--libc/sysdeps/mach/hurd/_G_config.h102
-rw-r--r--libc/sysdeps/mach/hurd/_exit.c56
-rw-r--r--libc/sysdeps/mach/hurd/accept.c87
-rw-r--r--libc/sysdeps/mach/hurd/access.c149
-rw-r--r--libc/sysdeps/mach/hurd/adjtime.c51
-rw-r--r--libc/sysdeps/mach/hurd/alpha/bits/sigcontext.h73
-rw-r--r--libc/sysdeps/mach/hurd/alpha/exc2signal.c75
-rw-r--r--libc/sysdeps/mach/hurd/alpha/init-first.c302
-rw-r--r--libc/sysdeps/mach/hurd/alpha/intr-msg.h100
-rw-r--r--libc/sysdeps/mach/hurd/alpha/longjmp-ts.c49
-rw-r--r--libc/sysdeps/mach/hurd/alpha/sigreturn.c211
-rw-r--r--libc/sysdeps/mach/hurd/alpha/static-start.S30
-rw-r--r--libc/sysdeps/mach/hurd/alpha/trampoline.c249
-rw-r--r--libc/sysdeps/mach/hurd/bind.c125
-rw-r--r--libc/sysdeps/mach/hurd/bits/errno.h321
-rw-r--r--libc/sysdeps/mach/hurd/bits/fcntl.h210
-rw-r--r--libc/sysdeps/mach/hurd/bits/ioctls.h371
-rw-r--r--libc/sysdeps/mach/hurd/bits/libc-lock.h203
-rw-r--r--libc/sysdeps/mach/hurd/bits/libc-tsd.h34
-rw-r--r--libc/sysdeps/mach/hurd/bits/local_lim.h46
-rw-r--r--libc/sysdeps/mach/hurd/bits/posix_opt.h165
-rw-r--r--libc/sysdeps/mach/hurd/bits/stat.h196
-rw-r--r--libc/sysdeps/mach/hurd/bits/statfs.h87
-rw-r--r--libc/sysdeps/mach/hurd/bits/statvfs.h94
-rw-r--r--libc/sysdeps/mach/hurd/bits/typesizes.h66
-rw-r--r--libc/sysdeps/mach/hurd/brk.c153
-rw-r--r--libc/sysdeps/mach/hurd/chdir.c33
-rw-r--r--libc/sysdeps/mach/hurd/check_fds.c108
-rw-r--r--libc/sysdeps/mach/hurd/chflags.c39
-rw-r--r--libc/sysdeps/mach/hurd/chmod.c41
-rw-r--r--libc/sysdeps/mach/hurd/chown.c42
-rw-r--r--libc/sysdeps/mach/hurd/chroot.c63
-rw-r--r--libc/sysdeps/mach/hurd/clock.c54
-rw-r--r--libc/sysdeps/mach/hurd/close.c35
-rw-r--r--libc/sysdeps/mach/hurd/closedir.c61
-rwxr-xr-xlibc/sysdeps/mach/hurd/configure92
-rw-r--r--libc/sysdeps/mach/hurd/configure.in38
-rw-r--r--libc/sysdeps/mach/hurd/connect.c78
-rw-r--r--libc/sysdeps/mach/hurd/cthreads.c66
-rw-r--r--libc/sysdeps/mach/hurd/device-nrs.h28
-rw-r--r--libc/sysdeps/mach/hurd/dirfd.c41
-rw-r--r--libc/sysdeps/mach/hurd/dirstream.h42
-rw-r--r--libc/sysdeps/mach/hurd/dl-cache.c29
-rw-r--r--libc/sysdeps/mach/hurd/dl-execstack.c52
-rw-r--r--libc/sysdeps/mach/hurd/dl-sysdep.c669
-rw-r--r--libc/sysdeps/mach/hurd/dl-sysdep.h31
-rw-r--r--libc/sysdeps/mach/hurd/dup2.c134
-rw-r--r--libc/sysdeps/mach/hurd/enbl-secure.c24
-rw-r--r--libc/sysdeps/mach/hurd/err_hurd.sub12
-rw-r--r--libc/sysdeps/mach/hurd/errlist.c29
-rw-r--r--libc/sysdeps/mach/hurd/errno-loc.c29
-rw-r--r--libc/sysdeps/mach/hurd/errno.c1
-rw-r--r--libc/sysdeps/mach/hurd/errnos.awk169
-rw-r--r--libc/sysdeps/mach/hurd/euidaccess.c60
-rw-r--r--libc/sysdeps/mach/hurd/execve.c46
-rw-r--r--libc/sysdeps/mach/hurd/faccessat.c70
-rw-r--r--libc/sysdeps/mach/hurd/fchdir.c34
-rw-r--r--libc/sysdeps/mach/hurd/fchflags.c37
-rw-r--r--libc/sysdeps/mach/hurd/fchmod.c39
-rw-r--r--libc/sysdeps/mach/hurd/fchmodat.c44
-rw-r--r--libc/sysdeps/mach/hurd/fchown.c40
-rw-r--r--libc/sysdeps/mach/hurd/fchownat.c46
-rw-r--r--libc/sysdeps/mach/hurd/fcntl.c207
-rw-r--r--libc/sysdeps/mach/hurd/fdatasync.c32
-rw-r--r--libc/sysdeps/mach/hurd/fdopendir.c58
-rw-r--r--libc/sysdeps/mach/hurd/fexecve.c34
-rw-r--r--libc/sysdeps/mach/hurd/fgetxattr.c34
-rw-r--r--libc/sysdeps/mach/hurd/flistxattr.c34
-rw-r--r--libc/sysdeps/mach/hurd/flock.c39
-rw-r--r--libc/sysdeps/mach/hurd/fork.c706
-rw-r--r--libc/sysdeps/mach/hurd/fpathconf.c38
-rw-r--r--libc/sysdeps/mach/hurd/fremovexattr.c34
-rw-r--r--libc/sysdeps/mach/hurd/fsetxattr.c34
-rw-r--r--libc/sysdeps/mach/hurd/fstatfs.c32
-rw-r--r--libc/sysdeps/mach/hurd/fstatfs64.c36
-rw-r--r--libc/sysdeps/mach/hurd/fstatvfs.c29
-rw-r--r--libc/sysdeps/mach/hurd/fstatvfs64.c28
-rw-r--r--libc/sysdeps/mach/hurd/fsync.c33
-rw-r--r--libc/sysdeps/mach/hurd/ftruncate.c37
-rw-r--r--libc/sysdeps/mach/hurd/futimes.c47
-rw-r--r--libc/sysdeps/mach/hurd/fxstat.c33
-rw-r--r--libc/sysdeps/mach/hurd/fxstat64.c43
-rw-r--r--libc/sysdeps/mach/hurd/fxstatat.c33
-rw-r--r--libc/sysdeps/mach/hurd/fxstatat64.c46
-rw-r--r--libc/sysdeps/mach/hurd/getclktck.c37
-rw-r--r--libc/sysdeps/mach/hurd/getcwd.c324
-rw-r--r--libc/sysdeps/mach/hurd/getdents.c1
-rw-r--r--libc/sysdeps/mach/hurd/getdomain.c32
-rw-r--r--libc/sysdeps/mach/hurd/getdtsz.c44
-rw-r--r--libc/sysdeps/mach/hurd/getegid.c57
-rw-r--r--libc/sysdeps/mach/hurd/geteuid.c57
-rw-r--r--libc/sysdeps/mach/hurd/getgid.c54
-rw-r--r--libc/sysdeps/mach/hurd/getgroups.c69
-rw-r--r--libc/sysdeps/mach/hurd/gethostid.c35
-rw-r--r--libc/sysdeps/mach/hurd/gethostname.c35
-rw-r--r--libc/sysdeps/mach/hurd/getitimer.c104
-rw-r--r--libc/sysdeps/mach/hurd/getlogin.c39
-rw-r--r--libc/sysdeps/mach/hurd/getlogin_r.c42
-rw-r--r--libc/sysdeps/mach/hurd/getpeername.c70
-rw-r--r--libc/sysdeps/mach/hurd/getpgid.c44
-rw-r--r--libc/sysdeps/mach/hurd/getpid.c32
-rw-r--r--libc/sysdeps/mach/hurd/getppid.c33
-rw-r--r--libc/sysdeps/mach/hurd/getpriority.c85
-rw-r--r--libc/sysdeps/mach/hurd/getresgid.c62
-rw-r--r--libc/sysdeps/mach/hurd/getresuid.c62
-rw-r--r--libc/sysdeps/mach/hurd/getrlimit.c47
-rw-r--r--libc/sysdeps/mach/hurd/getrusage.c94
-rw-r--r--libc/sysdeps/mach/hurd/getsid.c39
-rw-r--r--libc/sysdeps/mach/hurd/getsockname.c63
-rw-r--r--libc/sysdeps/mach/hurd/getsockopt.c56
-rw-r--r--libc/sysdeps/mach/hurd/getuid.c54
-rw-r--r--libc/sysdeps/mach/hurd/getxattr.c35
-rw-r--r--libc/sysdeps/mach/hurd/group_member.c56
-rw-r--r--libc/sysdeps/mach/hurd/i386/Makefile4
-rw-r--r--libc/sysdeps/mach/hurd/i386/Versions10
-rw-r--r--libc/sysdeps/mach/hurd/i386/bits/sigcontext.h120
-rw-r--r--libc/sysdeps/mach/hurd/i386/dl-machine.h7
-rw-r--r--libc/sysdeps/mach/hurd/i386/exc2signal.c166
-rw-r--r--libc/sysdeps/mach/hurd/i386/init-first.c393
-rw-r--r--libc/sysdeps/mach/hurd/i386/intr-msg.h113
-rw-r--r--libc/sysdeps/mach/hurd/i386/ioperm.c54
-rw-r--r--libc/sysdeps/mach/hurd/i386/longjmp-ts.c40
-rw-r--r--libc/sysdeps/mach/hurd/i386/sigcontextinfo.h25
-rw-r--r--libc/sysdeps/mach/hurd/i386/sigreturn.c140
-rw-r--r--libc/sysdeps/mach/hurd/i386/static-start.S28
-rw-r--r--libc/sysdeps/mach/hurd/i386/sys/io.h178
-rw-r--r--libc/sysdeps/mach/hurd/i386/tls.h174
-rw-r--r--libc/sysdeps/mach/hurd/i386/trampoline.c264
-rw-r--r--libc/sysdeps/mach/hurd/if_index.c190
-rw-r--r--libc/sysdeps/mach/hurd/ifreq.c65
-rw-r--r--libc/sysdeps/mach/hurd/init-posix.c2
-rw-r--r--libc/sysdeps/mach/hurd/ioctl.c324
-rw-r--r--libc/sysdeps/mach/hurd/isatty.c39
-rw-r--r--libc/sysdeps/mach/hurd/jmp-unwind.c80
-rw-r--r--libc/sysdeps/mach/hurd/kill.c150
-rw-r--r--libc/sysdeps/mach/hurd/lchmod.c39
-rw-r--r--libc/sysdeps/mach/hurd/lchown.c44
-rw-r--r--libc/sysdeps/mach/hurd/lgetxattr.c36
-rw-r--r--libc/sysdeps/mach/hurd/libc-ldscript6
-rw-r--r--libc/sysdeps/mach/hurd/libc_p-ldscript6
-rw-r--r--libc/sysdeps/mach/hurd/link.c61
-rw-r--r--libc/sysdeps/mach/hurd/linkat.c66
-rw-r--r--libc/sysdeps/mach/hurd/listen.c40
-rw-r--r--libc/sysdeps/mach/hurd/listxattr.c35
-rw-r--r--libc/sysdeps/mach/hurd/lseek.c31
-rw-r--r--libc/sysdeps/mach/hurd/lseek64.c34
-rw-r--r--libc/sysdeps/mach/hurd/lsetxattr.c37
-rw-r--r--libc/sysdeps/mach/hurd/lutimes.c53
-rw-r--r--libc/sysdeps/mach/hurd/lxstat.c32
-rw-r--r--libc/sysdeps/mach/hurd/lxstat64.c44
-rw-r--r--libc/sysdeps/mach/hurd/malloc-machine.h68
-rw-r--r--libc/sysdeps/mach/hurd/mig-reply.c88
-rw-r--r--libc/sysdeps/mach/hurd/mkdir.c42
-rw-r--r--libc/sysdeps/mach/hurd/mkdirat.c42
-rw-r--r--libc/sysdeps/mach/hurd/mlock.c47
-rw-r--r--libc/sysdeps/mach/hurd/mmap.c168
-rw-r--r--libc/sysdeps/mach/hurd/munlock.c45
-rw-r--r--libc/sysdeps/mach/hurd/net/ethernet.h76
-rw-r--r--libc/sysdeps/mach/hurd/net/if_arp.h145
-rw-r--r--libc/sysdeps/mach/hurd/net/if_ether.h85
-rw-r--r--libc/sysdeps/mach/hurd/net/if_ppp.h169
-rw-r--r--libc/sysdeps/mach/hurd/net/route.h141
-rw-r--r--libc/sysdeps/mach/hurd/open.c59
-rw-r--r--libc/sysdeps/mach/hurd/open64.c1
-rw-r--r--libc/sysdeps/mach/hurd/openat.c62
-rw-r--r--libc/sysdeps/mach/hurd/openat64.c1
-rw-r--r--libc/sysdeps/mach/hurd/opendir.c93
-rw-r--r--libc/sysdeps/mach/hurd/pathconf.c41
-rw-r--r--libc/sysdeps/mach/hurd/pipe.c51
-rw-r--r--libc/sysdeps/mach/hurd/poll.c51
-rw-r--r--libc/sysdeps/mach/hurd/powerpc/bits/sigcontext.h80
-rw-r--r--libc/sysdeps/mach/hurd/powerpc/exc2signal.c74
-rw-r--r--libc/sysdeps/mach/hurd/powerpc/init-first.c339
-rw-r--r--libc/sysdeps/mach/hurd/powerpc/intr-msg.h99
-rw-r--r--libc/sysdeps/mach/hurd/powerpc/longjmp-ts.c57
-rw-r--r--libc/sysdeps/mach/hurd/powerpc/register-dump.h120
-rw-r--r--libc/sysdeps/mach/hurd/powerpc/sigreturn.c186
-rw-r--r--libc/sysdeps/mach/hurd/powerpc/static-start.S59
-rw-r--r--libc/sysdeps/mach/hurd/powerpc/trampoline.c257
-rw-r--r--libc/sysdeps/mach/hurd/ppoll.c30
-rw-r--r--libc/sysdeps/mach/hurd/pread.c33
-rw-r--r--libc/sysdeps/mach/hurd/pread64.c39
-rw-r--r--libc/sysdeps/mach/hurd/prof-freq.c2
-rw-r--r--libc/sysdeps/mach/hurd/profil.c285
-rw-r--r--libc/sysdeps/mach/hurd/pselect.c45
-rw-r--r--libc/sysdeps/mach/hurd/ptrace.c386
-rw-r--r--libc/sysdeps/mach/hurd/ptsname.c65
-rw-r--r--libc/sysdeps/mach/hurd/pwrite.c35
-rw-r--r--libc/sysdeps/mach/hurd/pwrite64.c40
-rw-r--r--libc/sysdeps/mach/hurd/read.c33
-rw-r--r--libc/sysdeps/mach/hurd/readdir.c67
-rw-r--r--libc/sysdeps/mach/hurd/readdir64.c102
-rw-r--r--libc/sysdeps/mach/hurd/readdir64_r.c112
-rw-r--r--libc/sysdeps/mach/hurd/readdir_r.c65
-rw-r--r--libc/sysdeps/mach/hurd/readlink.c65
-rw-r--r--libc/sysdeps/mach/hurd/reboot.c50
-rw-r--r--libc/sysdeps/mach/hurd/recv.c64
-rw-r--r--libc/sysdeps/mach/hurd/recvfrom.c107
-rw-r--r--libc/sysdeps/mach/hurd/recvmsg.c145
-rw-r--r--libc/sysdeps/mach/hurd/removexattr.c35
-rw-r--r--libc/sysdeps/mach/hurd/rename.c48
-rw-r--r--libc/sysdeps/mach/hurd/revoke.c40
-rw-r--r--libc/sysdeps/mach/hurd/rewinddir.c31
-rw-r--r--libc/sysdeps/mach/hurd/rmdir.c41
-rw-r--r--libc/sysdeps/mach/hurd/sbrk.c42
-rw-r--r--libc/sysdeps/mach/hurd/seekdir.c40
-rw-r--r--libc/sysdeps/mach/hurd/select.c50
-rw-r--r--libc/sysdeps/mach/hurd/send.c44
-rw-r--r--libc/sysdeps/mach/hurd/sendfile.c37
-rw-r--r--libc/sysdeps/mach/hurd/sendfile64.c60
-rw-r--r--libc/sysdeps/mach/hurd/sendmsg.c156
-rw-r--r--libc/sysdeps/mach/hurd/sendto.c85
-rw-r--r--libc/sysdeps/mach/hurd/setdomain.c32
-rw-r--r--libc/sysdeps/mach/hurd/setegid.c69
-rw-r--r--libc/sysdeps/mach/hurd/seteuid.c69
-rw-r--r--libc/sysdeps/mach/hurd/setgid.c96
-rw-r--r--libc/sysdeps/mach/hurd/setgroups.c65
-rw-r--r--libc/sysdeps/mach/hurd/sethostid.c44
-rw-r--r--libc/sysdeps/mach/hurd/sethostname.c33
-rw-r--r--libc/sysdeps/mach/hurd/setitimer.c374
-rw-r--r--libc/sysdeps/mach/hurd/setlogin.c32
-rw-r--r--libc/sysdeps/mach/hurd/setpgid.c57
-rw-r--r--libc/sysdeps/mach/hurd/setpriority.c98
-rw-r--r--libc/sysdeps/mach/hurd/setregid.c98
-rw-r--r--libc/sysdeps/mach/hurd/setresgid.c78
-rw-r--r--libc/sysdeps/mach/hurd/setresuid.c78
-rw-r--r--libc/sysdeps/mach/hurd/setreuid.c98
-rw-r--r--libc/sysdeps/mach/hurd/setrlimit.c57
-rw-r--r--libc/sysdeps/mach/hurd/setsid.c73
-rw-r--r--libc/sysdeps/mach/hurd/setsockopt.c43
-rw-r--r--libc/sysdeps/mach/hurd/settimeofday.c55
-rw-r--r--libc/sysdeps/mach/hurd/setuid.c101
-rw-r--r--libc/sysdeps/mach/hurd/setxattr.c36
-rw-r--r--libc/sysdeps/mach/hurd/shutdown.c41
-rw-r--r--libc/sysdeps/mach/hurd/sigaction.c94
-rw-r--r--libc/sysdeps/mach/hurd/sigaltstack.c63
-rw-r--r--libc/sysdeps/mach/hurd/siglist.h23
-rw-r--r--libc/sysdeps/mach/hurd/sigpending.c47
-rw-r--r--libc/sysdeps/mach/hurd/sigprocmask.c87
-rw-r--r--libc/sysdeps/mach/hurd/sigstack.c44
-rw-r--r--libc/sysdeps/mach/hurd/sigsuspend.c83
-rw-r--r--libc/sysdeps/mach/hurd/sigwait.c133
-rw-r--r--libc/sysdeps/mach/hurd/socket.c68
-rw-r--r--libc/sysdeps/mach/hurd/socketpair.c95
-rw-r--r--libc/sysdeps/mach/hurd/spawni.c756
-rw-r--r--libc/sysdeps/mach/hurd/statfs.c32
-rw-r--r--libc/sysdeps/mach/hurd/statfs64.c38
-rw-r--r--libc/sysdeps/mach/hurd/statfsconv.c49
-rw-r--r--libc/sysdeps/mach/hurd/statvfs.c29
-rw-r--r--libc/sysdeps/mach/hurd/statvfs64.c28
-rw-r--r--libc/sysdeps/mach/hurd/symlink.c69
-rw-r--r--libc/sysdeps/mach/hurd/symlinkat.c74
-rw-r--r--libc/sysdeps/mach/hurd/sync.c31
-rw-r--r--libc/sysdeps/mach/hurd/sys/param.h132
-rw-r--r--libc/sysdeps/mach/hurd/telldir.c33
-rw-r--r--libc/sysdeps/mach/hurd/times.c75
-rw-r--r--libc/sysdeps/mach/hurd/tls.h77
-rw-r--r--libc/sysdeps/mach/hurd/tmpfile.c69
-rw-r--r--libc/sysdeps/mach/hurd/tmpfile64.c1
-rw-r--r--libc/sysdeps/mach/hurd/truncate.c44
-rw-r--r--libc/sysdeps/mach/hurd/ttyname.c38
-rw-r--r--libc/sysdeps/mach/hurd/ttyname_r.c50
-rw-r--r--libc/sysdeps/mach/hurd/umask.c34
-rw-r--r--libc/sysdeps/mach/hurd/uname.c48
-rw-r--r--libc/sysdeps/mach/hurd/unlink.c46
-rw-r--r--libc/sysdeps/mach/hurd/unlinkat.c55
-rw-r--r--libc/sysdeps/mach/hurd/utimes.c54
-rw-r--r--libc/sysdeps/mach/hurd/wait4.c55
-rw-r--r--libc/sysdeps/mach/hurd/write.c33
-rw-r--r--libc/sysdeps/mach/hurd/xmknod.c35
-rw-r--r--libc/sysdeps/mach/hurd/xmknodat.c118
-rw-r--r--libc/sysdeps/mach/hurd/xstat.c32
-rw-r--r--libc/sysdeps/mach/hurd/xstat64.c47
-rw-r--r--libc/sysdeps/mach/hurd/xstatconv.c68
-rw-r--r--libc/sysdeps/mach/i386/machine-lock.h66
-rw-r--r--libc/sysdeps/mach/i386/machine-sp.h31
-rw-r--r--libc/sysdeps/mach/i386/syscall.S27
-rw-r--r--libc/sysdeps/mach/i386/sysdep.h60
-rw-r--r--libc/sysdeps/mach/i386/thread_state.h38
-rw-r--r--libc/sysdeps/mach/mprotect.c51
-rw-r--r--libc/sysdeps/mach/msync.c57
-rw-r--r--libc/sysdeps/mach/munmap.c40
-rw-r--r--libc/sysdeps/mach/nanosleep.c54
-rw-r--r--libc/sysdeps/mach/pagecopy.h36
-rw-r--r--libc/sysdeps/mach/powerpc/machine-lock.h78
-rw-r--r--libc/sysdeps/mach/powerpc/machine-sp.h42
-rw-r--r--libc/sysdeps/mach/powerpc/syscall.S30
-rw-r--r--libc/sysdeps/mach/powerpc/sysdep.h51
-rw-r--r--libc/sysdeps/mach/powerpc/thread_state.h39
-rw-r--r--libc/sysdeps/mach/readonly-area.c57
-rw-r--r--libc/sysdeps/mach/sched_yield.c32
-rw-r--r--libc/sysdeps/mach/sleep.c45
-rw-r--r--libc/sysdeps/mach/start.c104
-rw-r--r--libc/sysdeps/mach/sys/reboot.h171
-rw-r--r--libc/sysdeps/mach/sys/syscall.h1
-rw-r--r--libc/sysdeps/mach/sysdep.h93
-rw-r--r--libc/sysdeps/mach/thread_state.h87
-rw-r--r--libc/sysdeps/mach/usleep.c42
-rw-r--r--libc/sysdeps/mach/xpg-strerror.c83
-rw-r--r--libc/sysdeps/posix/Makefile5
-rw-r--r--libc/sysdeps/posix/clock.c32
-rw-r--r--libc/sysdeps/posix/clock_getres.c118
-rw-r--r--libc/sysdeps/posix/ctermid.c36
-rw-r--r--libc/sysdeps/posix/cuserid.c48
-rw-r--r--libc/sysdeps/posix/dup.c32
-rw-r--r--libc/sysdeps/posix/dup2.c59
-rw-r--r--libc/sysdeps/posix/euidaccess.c220
-rw-r--r--libc/sysdeps/posix/flock.c59
-rw-r--r--libc/sysdeps/posix/fpathconf.c241
-rw-r--r--libc/sysdeps/posix/gai_strerror-strs.h17
-rw-r--r--libc/sysdeps/posix/gai_strerror.c70
-rw-r--r--libc/sysdeps/posix/getaddrinfo.c2154
-rw-r--r--libc/sysdeps/posix/getcwd.c428
-rw-r--r--libc/sysdeps/posix/getdtsz.c36
-rw-r--r--libc/sysdeps/posix/getpagesize.c29
-rw-r--r--libc/sysdeps/posix/gettimeofday.c72
-rw-r--r--libc/sysdeps/posix/isatty.c32
-rw-r--r--libc/sysdeps/posix/isfdtype.c38
-rw-r--r--libc/sysdeps/posix/killpg.c38
-rw-r--r--libc/sysdeps/posix/libc_fatal.c150
-rw-r--r--libc/sysdeps/posix/open64.c52
-rw-r--r--libc/sysdeps/posix/pathconf.c237
-rw-r--r--libc/sysdeps/posix/pause.c57
-rw-r--r--libc/sysdeps/posix/posix_fallocate.c94
-rw-r--r--libc/sysdeps/posix/posix_fallocate64.c113
-rw-r--r--libc/sysdeps/posix/pread.c63
-rw-r--r--libc/sysdeps/posix/pread64.c63
-rw-r--r--libc/sysdeps/posix/profil.c121
-rw-r--r--libc/sysdeps/posix/pwrite.c63
-rw-r--r--libc/sysdeps/posix/pwrite64.c64
-rw-r--r--libc/sysdeps/posix/raise.c30
-rw-r--r--libc/sysdeps/posix/readv.c101
-rw-r--r--libc/sysdeps/posix/remove.c39
-rw-r--r--libc/sysdeps/posix/rename.c51
-rw-r--r--libc/sysdeps/posix/shm_open.c85
-rw-r--r--libc/sysdeps/posix/shm_unlink.c61
-rw-r--r--libc/sysdeps/posix/sigblock.c40
-rw-r--r--libc/sysdeps/posix/sigignore.c40
-rw-r--r--libc/sysdeps/posix/sigintr.c57
-rw-r--r--libc/sysdeps/posix/signal.c56
-rw-r--r--libc/sysdeps/posix/sigpause.c91
-rw-r--r--libc/sysdeps/posix/sigset.c93
-rw-r--r--libc/sysdeps/posix/sigsetmask.c39
-rw-r--r--libc/sysdeps/posix/sigsuspend.c53
-rw-r--r--libc/sysdeps/posix/sigvec.c182
-rw-r--r--libc/sysdeps/posix/sigwait.c109
-rw-r--r--libc/sysdeps/posix/sleep.c106
-rw-r--r--libc/sysdeps/posix/spawni.c293
-rw-r--r--libc/sysdeps/posix/sprofil.c356
-rw-r--r--libc/sysdeps/posix/sysconf.c1241
-rw-r--r--libc/sysdeps/posix/system.c212
-rw-r--r--libc/sysdeps/posix/sysv_signal.c62
-rw-r--r--libc/sysdeps/posix/tempname.c346
-rw-r--r--libc/sysdeps/posix/truncate.c42
-rw-r--r--libc/sysdeps/posix/ttyname.c136
-rw-r--r--libc/sysdeps/posix/ttyname_r.c166
-rw-r--r--libc/sysdeps/posix/utimes.c43
-rw-r--r--libc/sysdeps/posix/wait.c31
-rw-r--r--libc/sysdeps/posix/wait3.c40
-rw-r--r--libc/sysdeps/posix/waitid.c171
-rw-r--r--libc/sysdeps/posix/writev.c97
-rw-r--r--libc/sysdeps/powerpc/Implies4
-rw-r--r--libc/sysdeps/powerpc/Makefile30
-rw-r--r--libc/sysdeps/powerpc/Versions17
-rw-r--r--libc/sysdeps/powerpc/abort-instr.h2
-rw-r--r--libc/sysdeps/powerpc/bits/atomic.h290
-rw-r--r--libc/sysdeps/powerpc/bits/endian.h37
-rw-r--r--libc/sysdeps/powerpc/bits/fenv.h145
-rw-r--r--libc/sysdeps/powerpc/bits/link.h111
-rw-r--r--libc/sysdeps/powerpc/bits/mathdef.h64
-rw-r--r--libc/sysdeps/powerpc/bits/setjmp.h52
-rwxr-xr-xlibc/sysdeps/powerpc/configure38
-rw-r--r--libc/sysdeps/powerpc/configure.in21
-rw-r--r--libc/sysdeps/powerpc/dl-procinfo.c66
-rw-r--r--libc/sysdeps/powerpc/dl-procinfo.h75
-rw-r--r--libc/sysdeps/powerpc/dl-tls.h49
-rw-r--r--libc/sysdeps/powerpc/elf/rtld-global-offsets.sym7
-rw-r--r--libc/sysdeps/powerpc/ffs.c47
-rw-r--r--libc/sysdeps/powerpc/fpu/Makefile6
-rw-r--r--libc/sysdeps/powerpc/fpu/bits/fenvinline.h61
-rw-r--r--libc/sysdeps/powerpc/fpu/bits/mathinline.h182
-rw-r--r--libc/sysdeps/powerpc/fpu/e_sqrt.c184
-rw-r--r--libc/sysdeps/powerpc/fpu/e_sqrtf.c161
-rw-r--r--libc/sysdeps/powerpc/fpu/fclrexcpt.c48
-rw-r--r--libc/sysdeps/powerpc/fpu/fe_nomask.c32
-rw-r--r--libc/sysdeps/powerpc/fpu/fedisblxcpt.c50
-rw-r--r--libc/sysdeps/powerpc/fpu/feenablxcpt.c55
-rw-r--r--libc/sysdeps/powerpc/fpu/fegetenv.c38
-rw-r--r--libc/sysdeps/powerpc/fpu/fegetexcept.c43
-rw-r--r--libc/sysdeps/powerpc/fpu/fegetround.c27
-rw-r--r--libc/sysdeps/powerpc/fpu/feholdexcpt.c39
-rw-r--r--libc/sysdeps/powerpc/fpu/fenv_const.c33
-rw-r--r--libc/sysdeps/powerpc/fpu/fenv_libc.h141
-rw-r--r--libc/sysdeps/powerpc/fpu/fesetenv.c39
-rw-r--r--libc/sysdeps/powerpc/fpu/fesetround.c32
-rw-r--r--libc/sysdeps/powerpc/fpu/feupdateenv.c49
-rw-r--r--libc/sysdeps/powerpc/fpu/fgetexcptflg.c44
-rw-r--r--libc/sysdeps/powerpc/fpu/fpu_control.h69
-rw-r--r--libc/sysdeps/powerpc/fpu/fraiseexcpt.c66
-rw-r--r--libc/sysdeps/powerpc/fpu/fsetexcptflg.c60
-rw-r--r--libc/sysdeps/powerpc/fpu/ftestexcept.c33
-rw-r--r--libc/sysdeps/powerpc/fpu/libm-test-ulps1328
-rw-r--r--libc/sysdeps/powerpc/fpu/math_ldbl.h189
-rw-r--r--libc/sysdeps/powerpc/fpu/s_fabs.S37
-rw-r--r--libc/sysdeps/powerpc/fpu/s_fabsf.S1
-rw-r--r--libc/sysdeps/powerpc/fpu/s_fdim.c31
-rw-r--r--libc/sysdeps/powerpc/fpu/s_fdimf.c27
-rw-r--r--libc/sysdeps/powerpc/fpu/s_fmax.S43
-rw-r--r--libc/sysdeps/powerpc/fpu/s_fmaxf.S1
-rw-r--r--libc/sysdeps/powerpc/fpu/s_fmin.S43
-rw-r--r--libc/sysdeps/powerpc/fpu/s_fminf.S1
-rw-r--r--libc/sysdeps/powerpc/fpu/s_isnan.c64
-rw-r--r--libc/sysdeps/powerpc/fpu/s_isnanf.S1
-rw-r--r--libc/sysdeps/powerpc/fpu/s_llround.c50
-rw-r--r--libc/sysdeps/powerpc/fpu/s_llroundf.c46
-rw-r--r--libc/sysdeps/powerpc/fpu/s_lrintf.S1
-rw-r--r--libc/sysdeps/powerpc/fpu/s_rint.c47
-rw-r--r--libc/sysdeps/powerpc/fpu/s_rintf.c43
-rw-r--r--libc/sysdeps/powerpc/fpu/t_sqrt.c144
-rw-r--r--libc/sysdeps/powerpc/fpu/w_sqrt.c51
-rw-r--r--libc/sysdeps/powerpc/fpu/w_sqrtf.c53
-rw-r--r--libc/sysdeps/powerpc/gccframe.h22
-rw-r--r--libc/sysdeps/powerpc/jmpbuf-offsets.h39
-rw-r--r--libc/sysdeps/powerpc/jmpbuf-unwind.h48
-rw-r--r--libc/sysdeps/powerpc/longjmp.c62
-rw-r--r--libc/sysdeps/powerpc/machine-gmon.h31
-rw-r--r--libc/sysdeps/powerpc/memusage.h21
-rw-r--r--libc/sysdeps/powerpc/mp_clz_tab.c1
-rw-r--r--libc/sysdeps/powerpc/novmx-longjmp.c64
-rw-r--r--libc/sysdeps/powerpc/novmx-sigjmp.c45
-rw-r--r--libc/sysdeps/powerpc/novmxsetjmp.h133
-rw-r--r--libc/sysdeps/powerpc/powerpc32/Implies1
-rw-r--r--libc/sysdeps/powerpc/powerpc32/Makefile44
-rw-r--r--libc/sysdeps/powerpc/powerpc32/Versions34
-rw-r--r--libc/sysdeps/powerpc/powerpc32/__longjmp-common.S63
-rw-r--r--libc/sysdeps/powerpc/powerpc32/__longjmp.S39
-rw-r--r--libc/sysdeps/powerpc/powerpc32/add_n.S77
-rw-r--r--libc/sysdeps/powerpc/powerpc32/addmul_1.S56
-rw-r--r--libc/sysdeps/powerpc/powerpc32/backtrace.c67
-rw-r--r--libc/sysdeps/powerpc/powerpc32/bits/atomic.h118
-rw-r--r--libc/sysdeps/powerpc/powerpc32/bits/wordsize.h8
-rw-r--r--libc/sysdeps/powerpc/powerpc32/bp-asm.h114
-rw-r--r--libc/sysdeps/powerpc/powerpc32/bsd-_setjmp.S59
-rw-r--r--libc/sysdeps/powerpc/powerpc32/bsd-setjmp.S41
-rw-r--r--libc/sysdeps/powerpc/powerpc32/configure62
-rw-r--r--libc/sysdeps/powerpc/powerpc32/configure.in32
-rw-r--r--libc/sysdeps/powerpc/powerpc32/dl-dtprocnum.h3
-rw-r--r--libc/sysdeps/powerpc/powerpc32/dl-machine.c620
-rw-r--r--libc/sysdeps/powerpc/powerpc32/dl-machine.h402
-rw-r--r--libc/sysdeps/powerpc/powerpc32/dl-start.S110
-rw-r--r--libc/sysdeps/powerpc/powerpc32/dl-trampoline.S186
-rw-r--r--libc/sysdeps/powerpc/powerpc32/elf/bzero.S37
-rwxr-xr-xlibc/sysdeps/powerpc/powerpc32/elf/configure52
-rw-r--r--libc/sysdeps/powerpc/powerpc32/elf/configure.in38
-rw-r--r--libc/sysdeps/powerpc/powerpc32/elf/start.S101
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/Makefile3
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S164
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/__longjmp.S42
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/fprrest.S95
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/fprsave.S112
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_ceil.S83
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S75
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_copysign.S60
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_copysignf.S1
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S50
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_fabs.S5
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S36
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_fdim.c5
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_floor.S83
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_floorf.S75
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_fmax.S5
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_fmin.S5
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_isnan.c7
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_llrint.c35
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_llrintf.c27
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_lrint.S45
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_lround.S99
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_lroundf.S2
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_rint.S79
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_rintf.S68
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_round.S103
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_roundf.S95
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_trunc.S90
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/s_truncf.S82
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S184
-rw-r--r--libc/sysdeps/powerpc/powerpc32/fpu/setjmp.S45
-rw-r--r--libc/sysdeps/powerpc/powerpc32/gprrest0.S70
-rw-r--r--libc/sysdeps/powerpc/powerpc32/gprrest1.S64
-rw-r--r--libc/sysdeps/powerpc/powerpc32/gprsave0.S88
-rw-r--r--libc/sysdeps/powerpc/powerpc32/gprsave1.S64
-rw-r--r--libc/sysdeps/powerpc/powerpc32/hp-timing.h82
-rw-r--r--libc/sysdeps/powerpc/powerpc32/libgcc-compat.S144
-rw-r--r--libc/sysdeps/powerpc/powerpc32/lshift.S133
-rw-r--r--libc/sysdeps/powerpc/powerpc32/memset.S342
-rw-r--r--libc/sysdeps/powerpc/powerpc32/mul_1.S53
-rw-r--r--libc/sysdeps/powerpc/powerpc32/ppc-mcount.S81
-rw-r--r--libc/sysdeps/powerpc/powerpc32/register-dump.h121
-rw-r--r--libc/sysdeps/powerpc/powerpc32/rshift.S63
-rw-r--r--libc/sysdeps/powerpc/powerpc32/setjmp-common.S74
-rw-r--r--libc/sysdeps/powerpc/powerpc32/setjmp.S44
-rw-r--r--libc/sysdeps/powerpc/powerpc32/stpcpy.S122
-rw-r--r--libc/sysdeps/powerpc/powerpc32/strchr.S131
-rw-r--r--libc/sysdeps/powerpc/powerpc32/strcmp.S127
-rw-r--r--libc/sysdeps/powerpc/powerpc32/strcpy.S121
-rw-r--r--libc/sysdeps/powerpc/powerpc32/strlen.S160
-rw-r--r--libc/sysdeps/powerpc/powerpc32/strncmp.S161
-rw-r--r--libc/sysdeps/powerpc/powerpc32/sub_n.S78
-rw-r--r--libc/sysdeps/powerpc/powerpc32/submul_1.S59
-rw-r--r--libc/sysdeps/powerpc/powerpc32/sysdep.h153
-rw-r--r--libc/sysdeps/powerpc/powerpc64/Implies1
-rw-r--r--libc/sysdeps/powerpc/powerpc64/Makefile45
-rw-r--r--libc/sysdeps/powerpc/powerpc64/__longjmp-common.S165
-rw-r--r--libc/sysdeps/powerpc/powerpc64/__longjmp.S40
-rw-r--r--libc/sysdeps/powerpc/powerpc64/backtrace.c70
-rw-r--r--libc/sysdeps/powerpc/powerpc64/bits/atomic.h227
-rw-r--r--libc/sysdeps/powerpc/powerpc64/bits/wordsize.h8
-rw-r--r--libc/sysdeps/powerpc/powerpc64/bp-asm.h115
-rw-r--r--libc/sysdeps/powerpc/powerpc64/bsd-_setjmp.S66
-rw-r--r--libc/sysdeps/powerpc/powerpc64/bsd-setjmp.S45
-rw-r--r--libc/sysdeps/powerpc/powerpc64/configure68
-rw-r--r--libc/sysdeps/powerpc/powerpc64/configure.in42
-rw-r--r--libc/sysdeps/powerpc/powerpc64/dl-dtprocnum.h22
-rw-r--r--libc/sysdeps/powerpc/powerpc64/dl-machine.c48
-rw-r--r--libc/sysdeps/powerpc/powerpc64/dl-machine.h814
-rw-r--r--libc/sysdeps/powerpc/powerpc64/dl-trampoline.S442
-rw-r--r--libc/sysdeps/powerpc/powerpc64/elf/Makefile11
-rw-r--r--libc/sysdeps/powerpc/powerpc64/elf/bzero.S21
-rw-r--r--libc/sysdeps/powerpc/powerpc64/elf/configure72
-rw-r--r--libc/sysdeps/powerpc/powerpc64/elf/configure.in58
-rw-r--r--libc/sysdeps/powerpc/powerpc64/elf/entry.h34
-rw-r--r--libc/sysdeps/powerpc/powerpc64/elf/start.S86
-rw-r--r--libc/sysdeps/powerpc/powerpc64/ffsll.c38
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c29
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c29
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_ceil.S64
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S56
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_ceill.S133
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_copysign.S63
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_copysignf.S1
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_copysignl.S51
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_fabs.S5
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_fabsl.S36
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_fdim.c5
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_floor.S64
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_floorf.S56
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_floorl.S134
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_fmax.S5
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_fmin.S5
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_isnan.c7
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_llrint.S48
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_llrintf.S37
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_llround.S73
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S60
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_lrint.S2
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_lround.S2
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_lroundf.S2
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S114
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_rint.S60
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_rintf.S49
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_round.S79
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_roundf.S71
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_roundl.S133
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_trunc.S71
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_truncf.S63
-rw-r--r--libc/sysdeps/powerpc/powerpc64/fpu/s_truncl.S121
-rw-r--r--libc/sysdeps/powerpc/powerpc64/hp-timing.c25
-rw-r--r--libc/sysdeps/powerpc/powerpc64/hp-timing.h136
-rw-r--r--libc/sysdeps/powerpc/powerpc64/memcpy.S369
-rw-r--r--libc/sysdeps/powerpc/powerpc64/memset.S292
-rw-r--r--libc/sysdeps/powerpc/powerpc64/ppc-mcount.S40
-rw-r--r--libc/sysdeps/powerpc/powerpc64/register-dump.h125
-rw-r--r--libc/sysdeps/powerpc/powerpc64/setjmp-common.S196
-rw-r--r--libc/sysdeps/powerpc/powerpc64/setjmp.S45
-rw-r--r--libc/sysdeps/powerpc/powerpc64/stpcpy.S123
-rw-r--r--libc/sysdeps/powerpc/powerpc64/strchr.S142
-rw-r--r--libc/sysdeps/powerpc/powerpc64/strcmp.S148
-rw-r--r--libc/sysdeps/powerpc/powerpc64/strcpy.S145
-rw-r--r--libc/sysdeps/powerpc/powerpc64/strlen.S175
-rw-r--r--libc/sysdeps/powerpc/powerpc64/strncmp.S165
-rw-r--r--libc/sysdeps/powerpc/powerpc64/sysdep.h266
-rw-r--r--libc/sysdeps/powerpc/sigjmp.c40
-rw-r--r--libc/sysdeps/powerpc/soft-fp/Makefile36
-rw-r--r--libc/sysdeps/powerpc/soft-fp/Subdirs1
-rw-r--r--libc/sysdeps/powerpc/soft-fp/Versions9
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_add.c39
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_cmp.c41
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_cmpe.c42
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_div.c39
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_dtoq.c44
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_feq.c40
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_fge.c40
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_fgt.c40
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_fle.c40
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_flt.c40
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_fne.c40
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_itoq.c38
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_lltoq.c38
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_mul.c39
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_neg.c47
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_qtod.c45
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_qtoi.c38
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_qtoll.c38
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_qtos.c45
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_qtou.c38
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_qtoull.c38
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_sqrt.c38
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_stoq.c43
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_sub.c39
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_ulltoq.c38
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_util.c57
-rw-r--r--libc/sysdeps/powerpc/soft-fp/q_utoq.c38
-rw-r--r--libc/sysdeps/powerpc/soft-fp/sfp-machine.h62
-rw-r--r--libc/sysdeps/powerpc/stackinfo.h28
-rw-r--r--libc/sysdeps/powerpc/strcat.c31
-rw-r--r--libc/sysdeps/powerpc/sysdep.h173
-rw-r--r--libc/sysdeps/powerpc/test-arith.c605
-rw-r--r--libc/sysdeps/powerpc/test-arithf.c6
-rw-r--r--libc/sysdeps/powerpc/tst-stack-align.h47
-rw-r--r--libc/sysdeps/pthread/Versions5
-rw-r--r--libc/sysdeps/pthread/aio_cancel.c159
-rw-r--r--libc/sysdeps/pthread/aio_fsync.c60
-rw-r--r--libc/sysdeps/pthread/aio_misc.c720
-rw-r--r--libc/sysdeps/pthread/aio_misc.h144
-rw-r--r--libc/sysdeps/pthread/aio_notify.c177
-rw-r--r--libc/sysdeps/pthread/aio_read.c32
-rw-r--r--libc/sysdeps/pthread/aio_read64.c32
-rw-r--r--libc/sysdeps/pthread/aio_suspend.c247
-rw-r--r--libc/sysdeps/pthread/aio_write.c32
-rw-r--r--libc/sysdeps/pthread/aio_write64.c32
-rw-r--r--libc/sysdeps/pthread/configure3
-rw-r--r--libc/sysdeps/pthread/lio_listio.c266
-rw-r--r--libc/sysdeps/pthread/lio_listio64.c34
-rw-r--r--libc/sysdeps/s390/Implies3
-rw-r--r--libc/sysdeps/s390/Versions6
-rw-r--r--libc/sysdeps/s390/abort-instr.h2
-rw-r--r--libc/sysdeps/s390/asm-syntax.h41
-rw-r--r--libc/sysdeps/s390/bits/atomic.h76
-rw-r--r--libc/sysdeps/s390/bits/byteswap.h158
-rw-r--r--libc/sysdeps/s390/bits/endian.h7
-rw-r--r--libc/sysdeps/s390/bits/link.h111
-rw-r--r--libc/sysdeps/s390/bits/linkmap.h13
-rw-r--r--libc/sysdeps/s390/bits/mathdef.h38
-rw-r--r--libc/sysdeps/s390/bits/setjmp.h48
-rw-r--r--libc/sysdeps/s390/bits/string.h231
-rw-r--r--libc/sysdeps/s390/bits/xtitypes.h34
-rw-r--r--libc/sysdeps/s390/dl-tls.h77
-rw-r--r--libc/sysdeps/s390/ffs.c71
-rw-r--r--libc/sysdeps/s390/fpu/bits/fenv.h82
-rw-r--r--libc/sysdeps/s390/fpu/bits/mathinline.h101
-rw-r--r--libc/sysdeps/s390/fpu/e_sqrt.c29
-rw-r--r--libc/sysdeps/s390/fpu/e_sqrtf.c29
-rw-r--r--libc/sysdeps/s390/fpu/e_sqrtl.c30
-rw-r--r--libc/sysdeps/s390/fpu/fclrexcpt.c40
-rw-r--r--libc/sysdeps/s390/fpu/fedisblxcpt.c35
-rw-r--r--libc/sysdeps/s390/fpu/feenablxcpt.c35
-rw-r--r--libc/sysdeps/s390/fpu/fegetenv.c43
-rw-r--r--libc/sysdeps/s390/fpu/fegetexcept.c31
-rw-r--r--libc/sysdeps/s390/fpu/fegetround.c32
-rw-r--r--libc/sysdeps/s390/fpu/feholdexcpt.c35
-rw-r--r--libc/sysdeps/s390/fpu/fenv_libc.h40
-rw-r--r--libc/sysdeps/s390/fpu/fesetenv.c57
-rw-r--r--libc/sysdeps/s390/fpu/fesetround.c38
-rw-r--r--libc/sysdeps/s390/fpu/feupdateenv.c40
-rw-r--r--libc/sysdeps/s390/fpu/fgetexcptflg.c36
-rw-r--r--libc/sysdeps/s390/fpu/fpu_control.h44
-rw-r--r--libc/sysdeps/s390/fpu/fraiseexcpt.c73
-rw-r--r--libc/sysdeps/s390/fpu/fsetexcptflg.c46
-rw-r--r--libc/sysdeps/s390/fpu/ftestexcept.c33
-rw-r--r--libc/sysdeps/s390/fpu/libm-test-ulps1332
-rw-r--r--libc/sysdeps/s390/gccframe.h22
-rw-r--r--libc/sysdeps/s390/gmp-mparam.h31
-rw-r--r--libc/sysdeps/s390/jmpbuf-offsets.h29
-rw-r--r--libc/sysdeps/s390/jmpbuf-unwind.h55
-rw-r--r--libc/sysdeps/s390/libc-tls.c37
-rw-r--r--libc/sysdeps/s390/machine-gmon.h36
-rw-r--r--libc/sysdeps/s390/memusage.h21
-rw-r--r--libc/sysdeps/s390/s390-32/Implies1
-rw-r--r--libc/sysdeps/s390/s390-32/Makefile11
-rw-r--r--libc/sysdeps/s390/s390-32/Versions6
-rw-r--r--libc/sysdeps/s390/s390-32/__longjmp.c61
-rw-r--r--libc/sysdeps/s390/s390-32/add_n.S64
-rw-r--r--libc/sysdeps/s390/s390-32/addmul_1.S59
-rw-r--r--libc/sysdeps/s390/s390-32/backtrace.c145
-rw-r--r--libc/sysdeps/s390/s390-32/bcopy.S86
-rw-r--r--libc/sysdeps/s390/s390-32/bits/wordsize.h18
-rw-r--r--libc/sysdeps/s390/s390-32/bsd-_setjmp.S47
-rw-r--r--libc/sysdeps/s390/s390-32/bsd-setjmp.S46
-rw-r--r--libc/sysdeps/s390/s390-32/bzero.S43
-rw-r--r--libc/sysdeps/s390/s390-32/dl-machine.h451
-rw-r--r--libc/sysdeps/s390/s390-32/dl-trampoline.S134
-rw-r--r--libc/sysdeps/s390/s390-32/elf/bsd-_setjmp.S1
-rw-r--r--libc/sysdeps/s390/s390-32/elf/bsd-setjmp.S1
-rw-r--r--libc/sysdeps/s390/s390-32/elf/configure52
-rw-r--r--libc/sysdeps/s390/s390-32/elf/configure.in37
-rw-r--r--libc/sysdeps/s390/s390-32/elf/setjmp.S81
-rw-r--r--libc/sysdeps/s390/s390-32/elf/start.S123
-rw-r--r--libc/sysdeps/s390/s390-32/initfini.c157
-rw-r--r--libc/sysdeps/s390/s390-32/memchr.S42
-rw-r--r--libc/sysdeps/s390/s390-32/memcpy.S59
-rw-r--r--libc/sysdeps/s390/s390-32/memset.S45
-rw-r--r--libc/sysdeps/s390/s390-32/mul_1.S56
-rw-r--r--libc/sysdeps/s390/s390-32/s390-mcount.S84
-rw-r--r--libc/sysdeps/s390/s390-32/setjmp.S64
-rw-r--r--libc/sysdeps/s390/s390-32/strcmp.S42
-rw-r--r--libc/sysdeps/s390/s390-32/strcpy.S37
-rw-r--r--libc/sysdeps/s390/s390-32/strncpy.S80
-rw-r--r--libc/sysdeps/s390/s390-32/sub_n.S63
-rw-r--r--libc/sysdeps/s390/s390-32/sysdep.h119
-rw-r--r--libc/sysdeps/s390/s390-64/Implies1
-rw-r--r--libc/sysdeps/s390/s390-64/Makefile11
-rw-r--r--libc/sysdeps/s390/s390-64/__longjmp.c63
-rw-r--r--libc/sysdeps/s390/s390-64/add_n.S64
-rw-r--r--libc/sysdeps/s390/s390-64/backtrace.c144
-rw-r--r--libc/sysdeps/s390/s390-64/bcopy.S72
-rw-r--r--libc/sysdeps/s390/s390-64/bits/wordsize.h18
-rw-r--r--libc/sysdeps/s390/s390-64/bsd-_setjmp.S35
-rw-r--r--libc/sysdeps/s390/s390-64/bsd-setjmp.S34
-rw-r--r--libc/sysdeps/s390/s390-64/bzero.S42
-rw-r--r--libc/sysdeps/s390/s390-64/dl-machine.h442
-rw-r--r--libc/sysdeps/s390/s390-64/dl-trampoline.S128
-rw-r--r--libc/sysdeps/s390/s390-64/elf/bsd-_setjmp.S1
-rw-r--r--libc/sysdeps/s390/s390-64/elf/bsd-setjmp.S1
-rw-r--r--libc/sysdeps/s390/s390-64/elf/configure52
-rw-r--r--libc/sysdeps/s390/s390-64/elf/configure.in37
-rw-r--r--libc/sysdeps/s390/s390-64/elf/setjmp.S72
-rw-r--r--libc/sysdeps/s390/s390-64/elf/start.S101
-rw-r--r--libc/sysdeps/s390/s390-64/initfini.c144
-rw-r--r--libc/sysdeps/s390/s390-64/memchr.S41
-rw-r--r--libc/sysdeps/s390/s390-64/memcpy.S58
-rw-r--r--libc/sysdeps/s390/s390-64/memset.S44
-rw-r--r--libc/sysdeps/s390/s390-64/s390x-mcount.S72
-rw-r--r--libc/sysdeps/s390/s390-64/setjmp.S54
-rw-r--r--libc/sysdeps/s390/s390-64/strcmp.S42
-rw-r--r--libc/sysdeps/s390/s390-64/strcpy.S36
-rw-r--r--libc/sysdeps/s390/s390-64/strncpy.S91
-rw-r--r--libc/sysdeps/s390/s390-64/sub_n.S61
-rw-r--r--libc/sysdeps/s390/s390-64/sysdep.h112
-rw-r--r--libc/sysdeps/s390/stackinfo.h28
-rw-r--r--libc/sysdeps/sh/Implies3
-rw-r--r--libc/sysdeps/sh/Makefile3
-rw-r--r--libc/sysdeps/sh/_mcount.S79
-rw-r--r--libc/sysdeps/sh/bits/endian.h13
-rw-r--r--libc/sysdeps/sh/bits/huge_val.h56
-rw-r--r--libc/sysdeps/sh/bits/link.h70
-rw-r--r--libc/sysdeps/sh/bits/linkmap.h5
-rw-r--r--libc/sysdeps/sh/bits/setjmp.h47
-rw-r--r--libc/sysdeps/sh/bsd-_setjmp.S52
-rw-r--r--libc/sysdeps/sh/bsd-setjmp.S51
-rw-r--r--libc/sysdeps/sh/dl-machine.h474
-rw-r--r--libc/sysdeps/sh/dl-tls.h29
-rw-r--r--libc/sysdeps/sh/dl-trampoline.S431
-rw-r--r--libc/sysdeps/sh/elf/configure47
-rw-r--r--libc/sysdeps/sh/elf/configure.in32
-rw-r--r--libc/sysdeps/sh/elf/initfini.c159
-rw-r--r--libc/sysdeps/sh/elf/start.S112
-rw-r--r--libc/sysdeps/sh/gccframe.h22
-rw-r--r--libc/sysdeps/sh/gmp-mparam.h30
-rw-r--r--libc/sysdeps/sh/init-first.c73
-rw-r--r--libc/sysdeps/sh/jmpbuf-offsets.h20
-rw-r--r--libc/sysdeps/sh/jmpbuf-unwind.h47
-rw-r--r--libc/sysdeps/sh/machine-gmon.h32
-rw-r--r--libc/sysdeps/sh/memcpy.S200
-rw-r--r--libc/sysdeps/sh/memset.S89
-rw-r--r--libc/sysdeps/sh/memusage.h21
-rw-r--r--libc/sysdeps/sh/sh3/__longjmp.S57
-rw-r--r--libc/sysdeps/sh/sh3/setjmp.S81
-rw-r--r--libc/sysdeps/sh/sh4/Versions5
-rw-r--r--libc/sysdeps/sh/sh4/__longjmp.S62
-rw-r--r--libc/sysdeps/sh/sh4/bits/mathdef.h69
-rw-r--r--libc/sysdeps/sh/sh4/dl-trampoline.S2
-rw-r--r--libc/sysdeps/sh/sh4/fpu/bits/fenv.h72
-rw-r--r--libc/sysdeps/sh/sh4/fpu/fclrexcpt.c42
-rw-r--r--libc/sysdeps/sh/sh4/fpu/fegetenv.c31
-rw-r--r--libc/sysdeps/sh/sh4/fpu/fegetround.c33
-rw-r--r--libc/sysdeps/sh/sh4/fpu/feholdexcpt.c38
-rw-r--r--libc/sysdeps/sh/sh4/fpu/fesetenv.c35
-rw-r--r--libc/sysdeps/sh/sh4/fpu/fesetround.c44
-rw-r--r--libc/sysdeps/sh/sh4/fpu/fpu_control.h56
-rw-r--r--libc/sysdeps/sh/sh4/fpu/fraiseexcpt.c36
-rw-r--r--libc/sysdeps/sh/sh4/fpu/fsetexcptflg.c40
-rw-r--r--libc/sysdeps/sh/sh4/fpu/ftestexcept.c32
-rw-r--r--libc/sysdeps/sh/sh4/fpu/libm-test-ulps1094
-rw-r--r--libc/sysdeps/sh/sh4/setjmp.S86
-rw-r--r--libc/sysdeps/sh/stackinfo.h28
-rw-r--r--libc/sysdeps/sh/strlen.S85
-rw-r--r--libc/sysdeps/sh/sys/ucontext.h99
-rw-r--r--libc/sysdeps/sh/sysdep.h91
-rw-r--r--libc/sysdeps/sparc/Makefile6
-rw-r--r--libc/sysdeps/sparc/Subdirs1
-rw-r--r--libc/sysdeps/sparc/abort-instr.h2
-rw-r--r--libc/sysdeps/sparc/bits/endian.h12
-rw-r--r--libc/sysdeps/sparc/bits/huge_vall.h49
-rw-r--r--libc/sysdeps/sparc/bits/link.h100
-rw-r--r--libc/sysdeps/sparc/bits/mathdef.h58
-rw-r--r--libc/sysdeps/sparc/bits/string.h26
-rw-r--r--libc/sysdeps/sparc/dl-dtprocnum.h22
-rw-r--r--libc/sysdeps/sparc/dl-procinfo.c62
-rw-r--r--libc/sysdeps/sparc/dl-procinfo.h79
-rw-r--r--libc/sysdeps/sparc/dl-sysdep.h24
-rw-r--r--libc/sysdeps/sparc/dl-tls.h29
-rw-r--r--libc/sysdeps/sparc/fpu/bits/fenv.h85
-rw-r--r--libc/sysdeps/sparc/fpu/bits/mathinline.h292
-rw-r--r--libc/sysdeps/sparc/fpu/fclrexcpt.c43
-rw-r--r--libc/sysdeps/sparc/fpu/fedisblxcpt.c36
-rw-r--r--libc/sysdeps/sparc/fpu/feenablxcpt.c36
-rw-r--r--libc/sysdeps/sparc/fpu/fegetenv.c37
-rw-r--r--libc/sysdeps/sparc/fpu/fegetexcept.c30
-rw-r--r--libc/sysdeps/sparc/fpu/fegetround.c30
-rw-r--r--libc/sysdeps/sparc/fpu/feholdexcpt.c36
-rw-r--r--libc/sysdeps/sparc/fpu/fesetenv.c55
-rw-r--r--libc/sysdeps/sparc/fpu/fesetround.c38
-rw-r--r--libc/sysdeps/sparc/fpu/feupdateenv.c49
-rw-r--r--libc/sysdeps/sparc/fpu/fgetexcptflg.c42
-rw-r--r--libc/sysdeps/sparc/fpu/fpu_control.h73
-rw-r--r--libc/sysdeps/sparc/fpu/fraiseexcpt.c91
-rw-r--r--libc/sysdeps/sparc/fpu/fsetexcptflg.c45
-rw-r--r--libc/sysdeps/sparc/fpu/ftestexcept.c30
-rw-r--r--libc/sysdeps/sparc/gccframe.h22
-rw-r--r--libc/sysdeps/sparc/memusage.h21
-rw-r--r--libc/sysdeps/sparc/sparc32/Implies6
-rw-r--r--libc/sysdeps/sparc/sparc32/Makefile53
-rw-r--r--libc/sysdeps/sparc/sparc32/Versions5
-rw-r--r--libc/sysdeps/sparc/sparc32/__longjmp.S97
-rw-r--r--libc/sysdeps/sparc/sparc32/add_n.S238
-rw-r--r--libc/sysdeps/sparc/sparc32/addmul_1.S147
-rw-r--r--libc/sysdeps/sparc/sparc32/alloca.S33
-rw-r--r--libc/sysdeps/sparc/sparc32/bcopy.c1
-rw-r--r--libc/sysdeps/sparc/sparc32/bits/atomic.h327
-rw-r--r--libc/sysdeps/sparc/sparc32/bits/setjmp.h27
-rw-r--r--libc/sysdeps/sparc/sparc32/bits/wordsize.h8
-rw-r--r--libc/sysdeps/sparc/sparc32/bsd-_setjmp.S1
-rw-r--r--libc/sysdeps/sparc/sparc32/bsd-setjmp.S1
-rw-r--r--libc/sysdeps/sparc/sparc32/bzero.c1
-rw-r--r--libc/sysdeps/sparc/sparc32/divrem.m4232
-rw-r--r--libc/sysdeps/sparc/sparc32/dl-machine.h575
-rw-r--r--libc/sysdeps/sparc/sparc32/dl-trampoline.S184
-rw-r--r--libc/sysdeps/sparc/sparc32/dotmul.S127
-rw-r--r--libc/sysdeps/sparc/sparc32/e_sqrt.c34
-rw-r--r--libc/sysdeps/sparc/sparc32/elf/Makefile4
-rw-r--r--libc/sysdeps/sparc/sparc32/elf/configure89
-rw-r--r--libc/sysdeps/sparc/sparc32/elf/configure.in62
-rw-r--r--libc/sysdeps/sparc/sparc32/elf/start.S104
-rw-r--r--libc/sysdeps/sparc/sparc32/fpu/e_sqrtl.c1
-rw-r--r--libc/sysdeps/sparc/sparc32/fpu/libm-test-ulps1322
-rw-r--r--libc/sysdeps/sparc/sparc32/fpu/s_fabs.c11
-rw-r--r--libc/sysdeps/sparc/sparc32/fpu/s_fabsf.S29
-rw-r--r--libc/sysdeps/sparc/sparc32/fpu/s_fabsl.c8
-rw-r--r--libc/sysdeps/sparc/sparc32/ieee754.h171
-rw-r--r--libc/sysdeps/sparc/sparc32/jmpbuf-offsets.h22
-rw-r--r--libc/sysdeps/sparc/sparc32/jmpbuf-unwind.h48
-rw-r--r--libc/sysdeps/sparc/sparc32/lshift.S97
-rw-r--r--libc/sysdeps/sparc/sparc32/memchr.S146
-rw-r--r--libc/sysdeps/sparc/sparc32/memcopy.h21
-rw-r--r--libc/sysdeps/sparc/sparc32/memcpy.S972
-rw-r--r--libc/sysdeps/sparc/sparc32/memmove.c1
-rw-r--r--libc/sysdeps/sparc/sparc32/memset.S155
-rw-r--r--libc/sysdeps/sparc/sparc32/mul_1.S199
-rw-r--r--libc/sysdeps/sparc/sparc32/rem.S363
-rw-r--r--libc/sysdeps/sparc/sparc32/rshift.S94
-rw-r--r--libc/sysdeps/sparc/sparc32/sdiv.S363
-rw-r--r--libc/sysdeps/sparc/sparc32/setjmp.S60
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/Makefile30
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/Versions8
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_add.c39
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_cmp.c41
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_cmpe.c42
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_div.c39
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_dtoq.c44
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_feq.c40
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_fge.c40
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_fgt.c40
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_fle.c40
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_flt.c40
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_fne.c40
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_itoq.c38
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_lltoq.c38
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_mul.c39
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_neg.c47
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_qtod.c45
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_qtoi.c38
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_qtoll.c38
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_qtos.c45
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_qtou.c38
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_qtoull.c38
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_sqrt.c39
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_stoq.c43
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_sub.c39
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_ulltoq.c38
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_util.c57
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/q_utoq.c38
-rw-r--r--libc/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h213
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv8/Makefile1
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv8/addmul_1.S119
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv8/dotmul.S13
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv8/mul_1.S103
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv8/rem.S21
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv8/sdiv.S20
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv8/submul_1.S58
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv8/udiv.S15
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv8/udiv_qrnnd.S215
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv8/umul.S13
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv8/urem.S18
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/Makefile13
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/bcopy.c1
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h94
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/bzero.c1
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/dotmul.S17
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/hp-timing.c24
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/hp-timing.h87
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/memchr.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/memcmp.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/memcpy.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/memmove.c1
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/memset.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/rawmemchr.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/rem.S22
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/sdiv.S20
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/stpcpy.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/stpncpy.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/strcat.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/strchr.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/strcmp.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/strcpy.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/strcspn.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/strlen.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/strncmp.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/strncpy.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/strpbrk.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/strrchr.c1
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/strspn.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/udiv.S17
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/umul.S17
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9/urem.S19
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9b/memcpy.S4
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9v/memcpy.S2
-rw-r--r--libc/sysdeps/sparc/sparc32/sparcv9v/memset.S2
-rw-r--r--libc/sysdeps/sparc/sparc32/stpcpy.S167
-rw-r--r--libc/sysdeps/sparc/sparc32/strcat.S353
-rw-r--r--libc/sysdeps/sparc/sparc32/strchr.S285
-rw-r--r--libc/sysdeps/sparc/sparc32/strcmp.S260
-rw-r--r--libc/sysdeps/sparc/sparc32/strcpy.S277
-rw-r--r--libc/sysdeps/sparc/sparc32/strlen.S106
-rw-r--r--libc/sysdeps/sparc/sparc32/strrchr.c1
-rw-r--r--libc/sysdeps/sparc/sparc32/sub_n.S329
-rw-r--r--libc/sysdeps/sparc/sparc32/submul_1.S147
-rw-r--r--libc/sysdeps/sparc/sparc32/udiv.S346
-rw-r--r--libc/sysdeps/sparc/sparc32/udiv_qrnnd.S168
-rw-r--r--libc/sysdeps/sparc/sparc32/umul.S155
-rw-r--r--libc/sysdeps/sparc/sparc32/urem.S346
-rw-r--r--libc/sysdeps/sparc/sparc64/Implies6
-rw-r--r--libc/sysdeps/sparc/sparc64/Makefile4
-rw-r--r--libc/sysdeps/sparc/sparc64/Versions14
-rw-r--r--libc/sysdeps/sparc/sparc64/add_n.S58
-rw-r--r--libc/sysdeps/sparc/sparc64/addmul_1.S84
-rw-r--r--libc/sysdeps/sparc/sparc64/bcopy.c1
-rw-r--r--libc/sysdeps/sparc/sparc64/bits/atomic.h109
-rw-r--r--libc/sysdeps/sparc/sparc64/bits/wordsize.h8
-rw-r--r--libc/sysdeps/sparc/sparc64/bzero.c1
-rw-r--r--libc/sysdeps/sparc/sparc64/dl-machine.h771
-rw-r--r--libc/sysdeps/sparc/sparc64/dl-trampoline.S327
-rw-r--r--libc/sysdeps/sparc/sparc64/elf/Makefile4
-rw-r--r--libc/sysdeps/sparc/sparc64/elf/configure90
-rw-r--r--libc/sysdeps/sparc/sparc64/elf/configure.in63
-rw-r--r--libc/sysdeps/sparc/sparc64/elf/start.S105
-rw-r--r--libc/sysdeps/sparc/sparc64/fpu/e_sqrtl.c31
-rw-r--r--libc/sysdeps/sparc/sparc64/fpu/libm-test-ulps1322
-rw-r--r--libc/sysdeps/sparc/sparc64/fpu/s_fabs.c5
-rw-r--r--libc/sysdeps/sparc/sparc64/fpu/s_fabsf.c5
-rw-r--r--libc/sysdeps/sparc/sparc64/fpu/s_fabsl.c5
-rw-r--r--libc/sysdeps/sparc/sparc64/hp-timing.c24
-rw-r--r--libc/sysdeps/sparc/sparc64/hp-timing.h82
-rw-r--r--libc/sysdeps/sparc/sparc64/jmpbuf-unwind.h37
-rw-r--r--libc/sysdeps/sparc/sparc64/lshift.S96
-rw-r--r--libc/sysdeps/sparc/sparc64/memchr.S263
-rw-r--r--libc/sysdeps/sparc/sparc64/memcmp.S143
-rw-r--r--libc/sysdeps/sparc/sparc64/memcpy.S925
-rw-r--r--libc/sysdeps/sparc/sparc64/memmove.c1
-rw-r--r--libc/sysdeps/sparc/sparc64/memset.S315
-rw-r--r--libc/sysdeps/sparc/sparc64/mul_1.S83
-rw-r--r--libc/sysdeps/sparc/sparc64/rawmemchr.S179
-rw-r--r--libc/sysdeps/sparc/sparc64/rshift.S93
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/Makefile34
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/Versions8
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_add.c45
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_cmp.c51
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_cmpe.c52
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_div.c45
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_dtoq.c46
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_feq.c51
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_fge.c51
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_fgt.c51
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_fle.c51
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_flt.c51
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_fne.c52
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_itoq.c35
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_mul.c50
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_neg.S31
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_qtod.c49
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_qtoi.c47
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_qtos.c50
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_qtoui.c47
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_qtoux.c47
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_qtox.c47
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_sqrt.c42
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_stoq.c46
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_sub.c45
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_uitoq.c35
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_util.c57
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_uxtoq.c35
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/qp_xtoq.c35
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/s_frexpl.c52
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/s_ilogbl.c82
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/s_scalblnl.c55
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/s_scalbnl.c55
-rw-r--r--libc/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h144
-rw-r--r--libc/sysdeps/sparc/sparc64/sparcv9b/memcpy.S610
-rw-r--r--libc/sysdeps/sparc/sparc64/sparcv9v/memcpy.S593
-rw-r--r--libc/sysdeps/sparc/sparc64/sparcv9v/memset.S127
-rw-r--r--libc/sysdeps/sparc/sparc64/stpcpy.S275
-rw-r--r--libc/sysdeps/sparc/sparc64/stpncpy.S425
-rw-r--r--libc/sysdeps/sparc/sparc64/strcat.S340
-rw-r--r--libc/sysdeps/sparc/sparc64/strchr.S483
-rw-r--r--libc/sysdeps/sparc/sparc64/strcmp.S280
-rw-r--r--libc/sysdeps/sparc/sparc64/strcpy.S245
-rw-r--r--libc/sysdeps/sparc/sparc64/strcspn.S213
-rw-r--r--libc/sysdeps/sparc/sparc64/strlen.S174
-rw-r--r--libc/sysdeps/sparc/sparc64/strncmp.S364
-rw-r--r--libc/sysdeps/sparc/sparc64/strncpy.S397
-rw-r--r--libc/sysdeps/sparc/sparc64/strpbrk.S231
-rw-r--r--libc/sysdeps/sparc/sparc64/strrchr.c1
-rw-r--r--libc/sysdeps/sparc/sparc64/strspn.S213
-rw-r--r--libc/sysdeps/sparc/sparc64/sub_n.S55
-rw-r--r--libc/sysdeps/sparc/sparc64/submul_1.S83
-rw-r--r--libc/sysdeps/sparc/stackinfo.h28
-rw-r--r--libc/sysdeps/sparc/sys/trap.h7
-rw-r--r--libc/sysdeps/unix/Implies1
-rw-r--r--libc/sysdeps/unix/Makefile346
-rw-r--r--libc/sysdeps/unix/Subdirs1
-rw-r--r--libc/sysdeps/unix/_exit.S25
-rw-r--r--libc/sysdeps/unix/alarm.c51
-rw-r--r--libc/sysdeps/unix/alpha/Makefile3
-rw-r--r--libc/sysdeps/unix/alpha/pipe.S32
-rw-r--r--libc/sysdeps/unix/alpha/rt-sysdep.S1
-rw-r--r--libc/sysdeps/unix/alpha/sysdep.S135
-rw-r--r--libc/sysdeps/unix/alpha/sysdep.h438
-rw-r--r--libc/sysdeps/unix/bsd/Implies5
-rw-r--r--libc/sysdeps/unix/bsd/bits/dirent.h33
-rw-r--r--libc/sysdeps/unix/bsd/bits/fcntl.h139
-rw-r--r--libc/sysdeps/unix/bsd/bits/posix_opt.h5
-rw-r--r--libc/sysdeps/unix/bsd/bits/signum.h74
-rw-r--r--libc/sysdeps/unix/bsd/bits/stat.h86
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/Implies2
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/Makefile3
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/Versions6
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/bits/dirent.h55
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/bits/errno.h164
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/bits/fcntl.h113
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/bits/ioctls.h288
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/bits/sockaddr.h43
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/bits/socket.h341
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/cmsg_nxthdr.c2
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/environments.h72
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h66
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/freebsd/sys/sysmacros.h28
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/isatty.c3
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/sigblock.c1
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/sigsetmask.c1
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/sigvec.c1
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/syscalls.list8
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/system.c2
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/tcdrain.c28
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/tcgetattr.c41
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/tcsetattr.c63
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/wait.c33
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/wait3.c37
-rw-r--r--libc/sysdeps/unix/bsd/bsd4.4/waitpid.c44
-rw-r--r--libc/sysdeps/unix/bsd/bsdstat.h112
-rw-r--r--libc/sysdeps/unix/bsd/bsdtty.h218
-rw-r--r--libc/sysdeps/unix/bsd/clock.c44
-rw-r--r--libc/sysdeps/unix/bsd/confstr.h1
-rw-r--r--libc/sysdeps/unix/bsd/ftime.c42
-rw-r--r--libc/sysdeps/unix/bsd/getpt.c93
-rw-r--r--libc/sysdeps/unix/bsd/gtty.c29
-rw-r--r--libc/sysdeps/unix/bsd/i386/vfork.S40
-rw-r--r--libc/sysdeps/unix/bsd/i386/wait3.S44
-rw-r--r--libc/sysdeps/unix/bsd/init-posix.c33
-rw-r--r--libc/sysdeps/unix/bsd/isatty.c32
-rw-r--r--libc/sysdeps/unix/bsd/poll.c199
-rw-r--r--libc/sysdeps/unix/bsd/ptsname.c76
-rw-r--r--libc/sysdeps/unix/bsd/seekdir.c1
-rw-r--r--libc/sysdeps/unix/bsd/setegid.c35
-rw-r--r--libc/sysdeps/unix/bsd/seteuid.c35
-rw-r--r--libc/sysdeps/unix/bsd/setgid.c35
-rw-r--r--libc/sysdeps/unix/bsd/setrgid.c27
-rw-r--r--libc/sysdeps/unix/bsd/setruid.c27
-rw-r--r--libc/sysdeps/unix/bsd/setsid.c58
-rw-r--r--libc/sysdeps/unix/bsd/setuid.c35
-rw-r--r--libc/sysdeps/unix/bsd/sigaction.c63
-rw-r--r--libc/sysdeps/unix/bsd/sigprocmask.c66
-rw-r--r--libc/sysdeps/unix/bsd/sigsuspend.c48
-rw-r--r--libc/sysdeps/unix/bsd/stty.c29
-rw-r--r--libc/sysdeps/unix/bsd/sys/reboot.h84
-rw-r--r--libc/sysdeps/unix/bsd/syscalls.list14
-rw-r--r--libc/sysdeps/unix/bsd/tcdrain.c38
-rw-r--r--libc/sysdeps/unix/bsd/tcflow.c58
-rw-r--r--libc/sysdeps/unix/bsd/tcflush.c51
-rw-r--r--libc/sysdeps/unix/bsd/tcgetattr.c130
-rw-r--r--libc/sysdeps/unix/bsd/tcgetpgrp.c35
-rw-r--r--libc/sysdeps/unix/bsd/tcsendbrk.c56
-rw-r--r--libc/sysdeps/unix/bsd/tcsetattr.c188
-rw-r--r--libc/sysdeps/unix/bsd/tcsetpgrp.c31
-rw-r--r--libc/sysdeps/unix/bsd/telldir.c116
-rw-r--r--libc/sysdeps/unix/bsd/times.c72
-rw-r--r--libc/sysdeps/unix/bsd/ualarm.c43
-rw-r--r--libc/sysdeps/unix/bsd/ulimit.c92
-rw-r--r--libc/sysdeps/unix/bsd/unlockpt.c37
-rw-r--r--libc/sysdeps/unix/bsd/usleep.c35
-rw-r--r--libc/sysdeps/unix/clock_gettime.c134
-rw-r--r--libc/sysdeps/unix/clock_nanosleep.c101
-rw-r--r--libc/sysdeps/unix/clock_settime.c129
-rw-r--r--libc/sysdeps/unix/closedir.c54
-rw-r--r--libc/sysdeps/unix/common/.cvsignore4
-rw-r--r--libc/sysdeps/unix/common/bits/dirent.h33
-rw-r--r--libc/sysdeps/unix/common/bits/fcntl.h120
-rw-r--r--libc/sysdeps/unix/common/lxstat.c39
-rw-r--r--libc/sysdeps/unix/common/syscalls.list16
-rw-r--r--libc/sysdeps/unix/common/tcsendbrk.c46
-rw-r--r--libc/sysdeps/unix/confstr.h1
-rw-r--r--libc/sysdeps/unix/dirfd.c30
-rw-r--r--libc/sysdeps/unix/dirstream.h48
-rw-r--r--libc/sysdeps/unix/errnos-tmpl.c99
-rw-r--r--libc/sysdeps/unix/errnos.awk12
-rw-r--r--libc/sysdeps/unix/execve.S33
-rw-r--r--libc/sysdeps/unix/fdopendir.c52
-rw-r--r--libc/sysdeps/unix/fork.S34
-rw-r--r--libc/sysdeps/unix/fxstat.c40
-rw-r--r--libc/sysdeps/unix/get_child_max.c37
-rw-r--r--libc/sysdeps/unix/getdents.c36
-rw-r--r--libc/sysdeps/unix/getegid.S30
-rw-r--r--libc/sysdeps/unix/geteuid.S30
-rw-r--r--libc/sysdeps/unix/getlogin.c73
-rw-r--r--libc/sysdeps/unix/getlogin_r.c99
-rw-r--r--libc/sysdeps/unix/getpagesize.c40
-rw-r--r--libc/sysdeps/unix/getppid.S30
-rw-r--r--libc/sysdeps/unix/grantpt.c216
-rw-r--r--libc/sysdeps/unix/i386/brk.S47
-rw-r--r--libc/sysdeps/unix/i386/dl-brk.S1
-rw-r--r--libc/sysdeps/unix/i386/fork.S32
-rw-r--r--libc/sysdeps/unix/i386/pipe.S30
-rw-r--r--libc/sysdeps/unix/i386/sigreturn.S27
-rw-r--r--libc/sysdeps/unix/i386/start.c2
-rw-r--r--libc/sysdeps/unix/i386/syscall.S28
-rw-r--r--libc/sysdeps/unix/i386/sysdep.S106
-rw-r--r--libc/sysdeps/unix/i386/sysdep.h36
-rw-r--r--libc/sysdeps/unix/i386/vfork.S24
-rw-r--r--libc/sysdeps/unix/i386/wait.S29
-rw-r--r--libc/sysdeps/unix/inet/Subdirs7
-rw-r--r--libc/sysdeps/unix/inet/syscalls.list23
-rw-r--r--libc/sysdeps/unix/ioctls-tmpl.c134
-rw-r--r--libc/sysdeps/unix/ioctls.awk10
-rw-r--r--libc/sysdeps/unix/make-syscalls.sh342
-rw-r--r--libc/sysdeps/unix/mk-local_lim.c126
-rw-r--r--libc/sysdeps/unix/mkdir.c98
-rw-r--r--libc/sysdeps/unix/mkfifo.c30
-rw-r--r--libc/sysdeps/unix/mkfifoat.c32
-rw-r--r--libc/sysdeps/unix/mman/syscalls.list11
-rw-r--r--libc/sysdeps/unix/nice.c53
-rw-r--r--libc/sysdeps/unix/opendir.c179
-rw-r--r--libc/sysdeps/unix/powerpc/sysdep.h26
-rw-r--r--libc/sysdeps/unix/readdir.c120
-rw-r--r--libc/sysdeps/unix/readdir_r.c127
-rw-r--r--libc/sysdeps/unix/rewinddir.c37
-rw-r--r--libc/sysdeps/unix/rmdir.c78
-rw-r--r--libc/sysdeps/unix/s-proto-bp.S4
-rw-r--r--libc/sysdeps/unix/s-proto-cancel.S5
-rw-r--r--libc/sysdeps/unix/s-proto.S4
-rw-r--r--libc/sysdeps/unix/seekdir.c38
-rw-r--r--libc/sysdeps/unix/setxid.h4
-rw-r--r--libc/sysdeps/unix/sh/sysdep.S110
-rw-r--r--libc/sysdeps/unix/sh/sysdep.h29
-rw-r--r--libc/sysdeps/unix/siglist.c62
-rwxr-xr-xlibc/sysdeps/unix/snarf-ioctls49
-rw-r--r--libc/sysdeps/unix/sockatmark.c30
-rw-r--r--libc/sysdeps/unix/sparc/brk.S51
-rw-r--r--libc/sysdeps/unix/sparc/dl-brk.S1
-rw-r--r--libc/sysdeps/unix/sparc/fork.S31
-rw-r--r--libc/sysdeps/unix/sparc/pipe.S30
-rw-r--r--libc/sysdeps/unix/sparc/start.c189
-rw-r--r--libc/sysdeps/unix/sparc/sysdep.S47
-rw-r--r--libc/sysdeps/unix/sparc/sysdep.h74
-rw-r--r--libc/sysdeps/unix/sparc/vfork.S35
-rw-r--r--libc/sysdeps/unix/start.c105
-rw-r--r--libc/sysdeps/unix/stime.c41
-rw-r--r--libc/sysdeps/unix/syscall.S30
-rw-r--r--libc/sysdeps/unix/syscalls.list65
-rw-r--r--libc/sysdeps/unix/sysdep.h59
-rw-r--r--libc/sysdeps/unix/system.c2
-rw-r--r--libc/sysdeps/unix/sysv/Makefile42
-rw-r--r--libc/sysdeps/unix/sysv/Versions5
-rw-r--r--libc/sysdeps/unix/sysv/bits/dirent.h28
-rw-r--r--libc/sysdeps/unix/sysv/bits/fcntl.h94
-rw-r--r--libc/sysdeps/unix/sysv/bits/local_lim.h32
-rw-r--r--libc/sysdeps/unix/sysv/bits/signum.h56
-rw-r--r--libc/sysdeps/unix/sysv/bits/stat.h65
-rw-r--r--libc/sysdeps/unix/sysv/bits/utmp.h54
-rw-r--r--libc/sysdeps/unix/sysv/bits/utsname.h23
-rw-r--r--libc/sysdeps/unix/sysv/direct.h10
-rw-r--r--libc/sysdeps/unix/sysv/getdents.c39
-rw-r--r--libc/sysdeps/unix/sysv/gethostname.c49
-rw-r--r--libc/sysdeps/unix/sysv/i386/sysdep.h4
-rw-r--r--libc/sysdeps/unix/sysv/i386/time.S30
-rw-r--r--libc/sysdeps/unix/sysv/linux/Implies14
-rw-r--r--libc/sysdeps/unix/sysv/linux/Makefile159
-rw-r--r--libc/sysdeps/unix/sysv/linux/Versions133
-rw-r--r--libc/sysdeps/unix/sysv/linux/_exit.c43
-rw-r--r--libc/sysdeps/unix/sysv/linux/a.out.h138
-rw-r--r--libc/sysdeps/unix/sysv/linux/accept.S6
-rw-r--r--libc/sysdeps/unix/sysv/linux/adjtime.c98
-rw-r--r--libc/sysdeps/unix/sysv/linux/aio_sigqueue.c57
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/Implies4
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/Makefile38
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/Versions94
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/a.out.h197
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/adjtime.c220
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/alpha/ptrace.h18
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/alpha/regdef.h44
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/a.out.h9
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/dirent.h55
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/elfclass.h14
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/errno.h58
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h228
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/ioctls.h37
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/ipc.h55
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/mman.h118
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/msq.h74
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/netdb.h35
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/resource.h225
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/sem.h85
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/shm.h101
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/sigaction.h74
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/siginfo.h303
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/signum.h82
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/sigstack.h55
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/stat.h151
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/statfs.h67
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/termios.h226
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h66
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/bits/wordsize.h30
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/brk.S81
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/clone.S149
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/dl-brk.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/dl-sysdep.c59
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/fraiseexcpt.c92
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/fxstat.c64
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/fxstatat.c99
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/getclktck.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/getcontext.S188
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/getdents.c3
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/getdents64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/gethostname.c47
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/getitimer.S113
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/getrusage.S149
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/getsysstats.c57
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/gettimeofday.S120
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/glob.c52
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S61
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S61
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/ioperm.c878
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/ipc_priv.h47
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h15
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/kernel_stat.h88
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/kernel_sysinfo.h6
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/kernel_termios.h44
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/lxstat.c64
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/makecontext.S164
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/msgctl.c121
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/nldbl-abi.h8
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/oldglob.c100
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/pipe.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/register-dump.h157
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S120
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/select.S241
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/semctl.c136
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/setcontext.S35
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/setfpucw.c80
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/setitimer.S137
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/setregid.c31
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/setresgid.c33
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/setresuid.c33
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/setreuid.c31
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/settimeofday.S118
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/shmctl.c135
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/sigaction.c39
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h25
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/sigprocmask.c58
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/sigsuspend.S33
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/sizes.h24
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/swapcontext.S51
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/sys/acct.h66
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/sys/io.h95
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/sys/procfs.h115
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/sys/ucontext.h61
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/sys/user.h50
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/syscall.S77
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/syscalls.list57
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/sysconf.c152
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/sysdep.h99
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/ucontext-offsets.sym18
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/utimes.S123
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/wait4.S156
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/wordexp.c60
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/xstat.c64
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/xstatconv.c123
-rw-r--r--libc/sysdeps/unix/sysv/linux/alpha/xstatconv.h24
-rw-r--r--libc/sysdeps/unix/sysv/linux/bind.S5
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/a.out.h7
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/dirent.h53
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/errno.h59
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/fcntl.h3
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/in.h170
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/initspin.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/ioctl-types.h78
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/ioctls.h109
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/ipc.h56
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/local_lim.h68
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/mqueue.h32
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/msq.h77
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/poll.h50
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/posix_opt.h96
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/resource.h225
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/sched.h130
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/sem.h87
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/shm.h103
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/sigaction.h77
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/sigcontext.h29
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/siginfo.h313
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/signum.h80
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/sigset.h125
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/sigstack.h55
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/socket.h320
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/stat.h163
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/statfs.h67
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/statvfs.h107
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/sys_errlist.h33
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/termios.h218
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/uio.h50
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/utsname.h29
-rw-r--r--libc/sysdeps/unix/sysv/linux/bits/waitflags.h38
-rw-r--r--libc/sysdeps/unix/sysv/linux/check_pf.c268
-rw-r--r--libc/sysdeps/unix/sysv/linux/clock.c45
-rw-r--r--libc/sysdeps/unix/sysv/linux/clock_getcpuclockid.c103
-rw-r--r--libc/sysdeps/unix/sysv/linux/clock_getres.c193
-rw-r--r--libc/sysdeps/unix/sysv/linux/clock_gettime.c193
-rw-r--r--libc/sysdeps/unix/sysv/linux/clock_nanosleep.c96
-rw-r--r--libc/sysdeps/unix/sysv/linux/clock_settime.c149
-rw-r--r--libc/sysdeps/unix/sysv/linux/cmsg_nxthdr.c39
-rw-r--r--libc/sysdeps/unix/sysv/linux/configure367
-rw-r--r--libc/sysdeps/unix/sysv/linux/configure.in292
-rw-r--r--libc/sysdeps/unix/sysv/linux/connect.S7
-rw-r--r--libc/sysdeps/unix/sysv/linux/device-nrs.h46
-rw-r--r--libc/sysdeps/unix/sysv/linux/dl-brk.c5
-rw-r--r--libc/sysdeps/unix/sysv/linux/dl-execstack.c154
-rw-r--r--libc/sysdeps/unix/sysv/linux/dl-librecon.h61
-rw-r--r--libc/sysdeps/unix/sysv/linux/dl-origin.c81
-rw-r--r--libc/sysdeps/unix/sysv/linux/dl-osinfo.h180
-rw-r--r--libc/sysdeps/unix/sysv/linux/dl-sbrk.c5
-rw-r--r--libc/sysdeps/unix/sysv/linux/dl-sysdep.c56
-rw-r--r--libc/sysdeps/unix/sysv/linux/dl-sysdep.h27
-rw-r--r--libc/sysdeps/unix/sysv/linux/errqueue.h46
-rw-r--r--libc/sysdeps/unix/sysv/linux/execve.c63
-rw-r--r--libc/sysdeps/unix/sysv/linux/exit-thread.S23
-rw-r--r--libc/sysdeps/unix/sysv/linux/faccessat.c143
-rw-r--r--libc/sysdeps/unix/sysv/linux/fatal-prepare.h39
-rw-r--r--libc/sysdeps/unix/sysv/linux/fchmodat.c106
-rw-r--r--libc/sysdeps/unix/sysv/linux/fchownat.c99
-rw-r--r--libc/sysdeps/unix/sysv/linux/fcntl.c69
-rw-r--r--libc/sysdeps/unix/sysv/linux/fd_to_filename.h46
-rw-r--r--libc/sysdeps/unix/sysv/linux/fexecve.c59
-rw-r--r--libc/sysdeps/unix/sysv/linux/fpathconf.c51
-rw-r--r--libc/sysdeps/unix/sysv/linux/fstatfs64.c72
-rw-r--r--libc/sysdeps/unix/sysv/linux/fstatvfs.c45
-rw-r--r--libc/sysdeps/unix/sysv/linux/fstatvfs64.c74
-rw-r--r--libc/sysdeps/unix/sysv/linux/ftime.c3
-rw-r--r--libc/sysdeps/unix/sysv/linux/ftruncate64.c77
-rw-r--r--libc/sysdeps/unix/sysv/linux/futimes.c101
-rw-r--r--libc/sysdeps/unix/sysv/linux/futimesat.c134
-rw-r--r--libc/sysdeps/unix/sysv/linux/fxstat.c64
-rw-r--r--libc/sysdeps/unix/sysv/linux/fxstat64.c94
-rw-r--r--libc/sysdeps/unix/sysv/linux/fxstatat.c141
-rw-r--r--libc/sysdeps/unix/sysv/linux/fxstatat64.c167
-rw-r--r--libc/sysdeps/unix/sysv/linux/gai_sigqueue.c56
-rw-r--r--libc/sysdeps/unix/sysv/linux/getclktck.c32
-rw-r--r--libc/sysdeps/unix/sysv/linux/getcwd.c222
-rw-r--r--libc/sysdeps/unix/sysv/linux/getdents.c299
-rw-r--r--libc/sysdeps/unix/sysv/linux/getdents64.c3
-rw-r--r--libc/sysdeps/unix/sysv/linux/getdirentries.c42
-rw-r--r--libc/sysdeps/unix/sysv/linux/getdirentries64.c3
-rw-r--r--libc/sysdeps/unix/sysv/linux/getdtsz.c22
-rw-r--r--libc/sysdeps/unix/sysv/linux/gethostid.c121
-rw-r--r--libc/sysdeps/unix/sysv/linux/getipv4sourcefilter.c73
-rw-r--r--libc/sysdeps/unix/sysv/linux/getloadavg.c69
-rw-r--r--libc/sysdeps/unix/sysv/linux/getpagesize.c46
-rw-r--r--libc/sysdeps/unix/sysv/linux/getpeername.S3
-rw-r--r--libc/sysdeps/unix/sysv/linux/getpriority.c45
-rw-r--r--libc/sysdeps/unix/sysv/linux/getpt.c100
-rw-r--r--libc/sysdeps/unix/sysv/linux/getsockname.S5
-rw-r--r--libc/sysdeps/unix/sysv/linux/getsockopt.S3
-rw-r--r--libc/sysdeps/unix/sysv/linux/getsourcefilter.c146
-rw-r--r--libc/sysdeps/unix/sysv/linux/getsysstats.c214
-rw-r--r--libc/sysdeps/unix/sysv/linux/grantpt.c81
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/Makefile18
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/Versions47
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/_exit.S44
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/alphasort64.c49
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/bits/a.out.h3
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/bits/environments.h62
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/bits/fcntl.h236
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/bits/mman.h103
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/bits/wchar.h26
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/bp-thunks.h4
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/brk.c53
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/call_pselect6.S65
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/chown.c159
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/clone.S159
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/dl-librecon.h63
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/dl-procinfo.h43
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/fchown.c68
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/fchownat.c196
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/fcntl.c169
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/fxstat.c101
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/fxstatat.c176
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/get_clockfreq.c91
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/getcontext.S85
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/getdents64.c40
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/getegid.c61
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/geteuid.c61
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/getgid.c62
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/getgroups.c81
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/getmsg.c38
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/getresgid.c85
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/getresuid.c84
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/getrlimit.c82
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/getrlimit64.c25
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/getuid.c65
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/glob64.c54
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/lchown.c74
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/ldconfig.h25
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/lockf64.c194
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/lxstat.c101
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/makecontext.S117
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/mmap.S107
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/mmap64.S170
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/msgctl.c159
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/olddirent.h44
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c58
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/posix_fadvise64.S162
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/profil-counter.h32
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/pselect.c18
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/putmsg.c38
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/readdir64.c44
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/readdir64_r.c44
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/readelflib.c82
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/register-dump.h256
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/scandir64.c47
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/semctl.c185
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/semtimedop.S75
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/setcontext.S97
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/setegid.c62
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/seteuid.c60
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/setfsgid.c70
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/setfsuid.c71
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/setgid.c76
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/setgroups.c87
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/setregid.c75
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/setresgid.c86
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/setresuid.c86
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/setreuid.c75
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/setrlimit.c78
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/setuid.c75
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/shmctl.c178
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sigaction.c204
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h51
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/socket.S124
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/swapcontext.S112
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sync_file_range.S72
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sys/debugreg.h91
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sys/elf.h26
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sys/io.h181
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sys/perm.h36
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sys/procfs.h131
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sys/reg.h43
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sys/ucontext.h129
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sys/user.h103
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sys/vm86.h35
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/syscall.S37
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/syscalls.list8
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sysconf.c410
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sysdep.S41
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/sysdep.h581
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/ucontext_i.sym30
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/versionsort64.c49
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/vfork.S88
-rw-r--r--libc/sysdeps/unix/sysv/linux/i386/xstat.c99
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/Implies1
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/Makefile27
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/Versions25
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S163
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/__start_context.S52
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/endian.h7
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/fcntl.h230
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/ipc.h54
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/mman.h104
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/msq.h69
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/sem.h87
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/setjmp.h35
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/shm.h94
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/sigaction.h73
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h79
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h339
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/sigstack.h63
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bits/stat.h140
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/brk.S52
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bsd-_setjmp.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/bsd-setjmp.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c32
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/clone.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/clone2.S106
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/dl-brk.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/dl-cache.h25
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/dl-static.c69
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/fork.S41
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c89
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/getclktck.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/getcontext.S158
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/getpagesize.c39
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c52
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/ioperm.c217
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/kernel_stat.h21
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/ldconfig.h25
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed1
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/ldsodefs.h33
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/makecontext.c93
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/pipe.S38
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/profil-counter.h32
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/readelflib.c60
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/register-dump.h182
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/rt-sysdep.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/setcontext.S153
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/setjmp.S199
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sigaction.c59
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sigcontext-offsets.sym16
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h26
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sigpending.c39
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sigprocmask.c45
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/swapcontext.c40
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sys/io.h68
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sys/procfs.h130
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sys/ptrace.h135
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sys/rse.h78
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sys/ucontext.h66
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sys/user.h54
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/syscall.S30
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/syscalls.list50
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sysconf.c45
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sysdep.S89
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/sysdep.h384
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/system.c35
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/ucontext_i.h47
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/umount.c31
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/vfork.S44
-rw-r--r--libc/sysdeps/unix/sysv/linux/ia64/wordexp.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/if_index.c474
-rw-r--r--libc/sysdeps/unix/sysv/linux/ifaddrs.c863
-rw-r--r--libc/sysdeps/unix/sysv/linux/ifreq.c101
-rw-r--r--libc/sysdeps/unix/sysv/linux/init-first.c109
-rw-r--r--libc/sysdeps/unix/sysv/linux/internal_statvfs.c239
-rw-r--r--libc/sysdeps/unix/sysv/linux/internal_statvfs64.c4
-rw-r--r--libc/sysdeps/unix/sysv/linux/ipc_priv.h47
-rw-r--r--libc/sysdeps/unix/sysv/linux/kernel-features.h460
-rw-r--r--libc/sysdeps/unix/sysv/linux/kernel-posix-cpu-timers.h18
-rw-r--r--libc/sysdeps/unix/sysv/linux/kernel_sigaction.h19
-rw-r--r--libc/sysdeps/unix/sysv/linux/kernel_stat.h35
-rw-r--r--libc/sysdeps/unix/sysv/linux/kernel_termios.h35
-rw-r--r--libc/sysdeps/unix/sysv/linux/ldd-rewrite.sed11
-rw-r--r--libc/sysdeps/unix/sysv/linux/lddlibc4.c88
-rw-r--r--libc/sysdeps/unix/sysv/linux/ldsodefs.h56
-rw-r--r--libc/sysdeps/unix/sysv/linux/libc_fatal.c183
-rw-r--r--libc/sysdeps/unix/sysv/linux/linkat.c115
-rw-r--r--libc/sysdeps/unix/sysv/linux/linux_fsinfo.h156
-rw-r--r--libc/sysdeps/unix/sysv/linux/listen.S5
-rw-r--r--libc/sysdeps/unix/sysv/linux/llseek.c47
-rw-r--r--libc/sysdeps/unix/sysv/linux/local-setxid.h23
-rw-r--r--libc/sysdeps/unix/sysv/linux/lseek64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/lxstat.c64
-rw-r--r--libc/sysdeps/unix/sysv/linux/lxstat64.c93
-rw-r--r--libc/sysdeps/unix/sysv/linux/makedev.c41
-rw-r--r--libc/sysdeps/unix/sysv/linux/mkdirat.c86
-rw-r--r--libc/sysdeps/unix/sysv/linux/mmap64.c89
-rw-r--r--libc/sysdeps/unix/sysv/linux/mq_close.c35
-rw-r--r--libc/sysdeps/unix/sysv/linux/mq_getattr.c35
-rw-r--r--libc/sysdeps/unix/sysv/linux/mq_notify.c44
-rw-r--r--libc/sysdeps/unix/sysv/linux/mq_open.c60
-rw-r--r--libc/sysdeps/unix/sysv/linux/mq_receive.c37
-rw-r--r--libc/sysdeps/unix/sysv/linux/mq_send.c36
-rw-r--r--libc/sysdeps/unix/sysv/linux/mq_unlink.c54
-rw-r--r--libc/sysdeps/unix/sysv/linux/msgctl.c135
-rw-r--r--libc/sysdeps/unix/sysv/linux/msgget.c37
-rw-r--r--libc/sysdeps/unix/sysv/linux/msgrcv.c66
-rw-r--r--libc/sysdeps/unix/sysv/linux/msgsnd.c49
-rw-r--r--libc/sysdeps/unix/sysv/linux/net/ethernet.h76
-rw-r--r--libc/sysdeps/unix/sysv/linux/net/if_arp.h182
-rw-r--r--libc/sysdeps/unix/sysv/linux/net/if_packet.h37
-rw-r--r--libc/sysdeps/unix/sysv/linux/net/if_ppp.h169
-rw-r--r--libc/sysdeps/unix/sysv/linux/net/if_shaper.h59
-rw-r--r--libc/sysdeps/unix/sysv/linux/net/if_slip.h25
-rw-r--r--libc/sysdeps/unix/sysv/linux/net/ppp-comp.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/net/ppp_defs.h10
-rw-r--r--libc/sysdeps/unix/sysv/linux/net/route.h145
-rw-r--r--libc/sysdeps/unix/sysv/linux/netash/ash.h40
-rw-r--r--libc/sysdeps/unix/sysv/linux/netatalk/at.h30
-rw-r--r--libc/sysdeps/unix/sysv/linux/netax25/ax25.h171
-rw-r--r--libc/sysdeps/unix/sysv/linux/neteconet/ec.h52
-rw-r--r--libc/sysdeps/unix/sysv/linux/netinet/if_ether.h105
-rw-r--r--libc/sysdeps/unix/sysv/linux/netinet/if_fddi.h37
-rw-r--r--libc/sysdeps/unix/sysv/linux/netinet/if_tr.h111
-rw-r--r--libc/sysdeps/unix/sysv/linux/netipx/ipx.h113
-rw-r--r--libc/sysdeps/unix/sysv/linux/netlinkaccess.h61
-rw-r--r--libc/sysdeps/unix/sysv/linux/netpacket/packet.h64
-rw-r--r--libc/sysdeps/unix/sysv/linux/netrom/netrom.h84
-rw-r--r--libc/sysdeps/unix/sysv/linux/netrose/rose.h116
-rw-r--r--libc/sysdeps/unix/sysv/linux/nfs/nfs.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/nice.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/not-cancel.h105
-rw-r--r--libc/sysdeps/unix/sysv/linux/nscd_setup_thread.c47
-rw-r--r--libc/sysdeps/unix/sysv/linux/ntp_gettime.c42
-rw-r--r--libc/sysdeps/unix/sysv/linux/open64.c53
-rw-r--r--libc/sysdeps/unix/sysv/linux/openat.c173
-rw-r--r--libc/sysdeps/unix/sysv/linux/openat64.c4
-rw-r--r--libc/sysdeps/unix/sysv/linux/opendir.c26
-rw-r--r--libc/sysdeps/unix/sysv/linux/opensock.c119
-rw-r--r--libc/sysdeps/unix/sysv/linux/pathconf.c181
-rw-r--r--libc/sysdeps/unix/sysv/linux/pathconf.h34
-rw-r--r--libc/sysdeps/unix/sysv/linux/paths.h74
-rw-r--r--libc/sysdeps/unix/sysv/linux/poll.c105
-rw-r--r--libc/sysdeps/unix/sysv/linux/posix_fadvise.c40
-rw-r--r--libc/sysdeps/unix/sysv/linux/posix_fadvise64.c82
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/Implies4
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/Makefile12
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/Versions7
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-dirent.h19
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-errno.h125
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-stat.h76
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-termios.h85
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/aix/direntconv.c49
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/aix/errnoconv.c143
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/aix/statconv.c53
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/aix/tcgetattr.c156
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/aix/tcsetattr.c171
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/environments.h87
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h236
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/ioctl-types.h5
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/ipc.h79
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h36
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/mman.h104
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/msq.h83
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/sem.h92
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/shm.h113
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/stat.h267
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/termios.h319
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h19
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/chown.c132
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/configure135
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/configure.in37
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/dl-brk.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/dl-cache.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c71
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/dl-vdso.c59
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/dl-vdso.h27
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/fchownat.c223
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c117
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/getdents64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/getmsg.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/getrlimit.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/getrlimit64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c42
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/ioctl.c65
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/ipc_priv.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/kernel_termios.h54
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/lchown.S39
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/ldconfig.h27
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/ldd-rewrite.sed15
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/libc-start.c130
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/nldbl-abi.h8
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/oldgetrlimit64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile3
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions30
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S64
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S149
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fcntl.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_nomask.c68
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/Implies2
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c78
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstatat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S286
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S84
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h49
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/lockf64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/lxstat.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S219
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/posix_fadvise.c40
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/posix_fadvise64.c78
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c87
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c88
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c87
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c89
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S293
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S85
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S121
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S517
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S84
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list5
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h297
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c79
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.sym26
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S59
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/xstat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Implies1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions22
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S50
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S143
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/dl-cache.h25
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c72
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_nomask.c43
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies2
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S411
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/kernel_stat.h21
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h77
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S187
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c85
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c84
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c85
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c85
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S469
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S123
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S769
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list3
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h311
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym50
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/umount.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S57
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/profil-counter.h2
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/putmsg.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/readdir64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/readdir64_r.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/readelflib.c61
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/rt-sysdep.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/scandir64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/setrlimit.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h27
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/sys/procfs.h140
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h99
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h177
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/sys/user.h40
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/syscall.S31
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/syscalls.list3
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/sysdep.c29
-rw-r--r--libc/sysdeps/unix/sysv/linux/ppoll.c76
-rw-r--r--libc/sysdeps/unix/sysv/linux/pread.c96
-rw-r--r--libc/sysdeps/unix/sysv/linux/pread64.c93
-rw-r--r--libc/sysdeps/unix/sysv/linux/prof-freq.c51
-rw-r--r--libc/sysdeps/unix/sysv/linux/profil.c3
-rw-r--r--libc/sysdeps/unix/sysv/linux/pselect.c100
-rw-r--r--libc/sysdeps/unix/sysv/linux/ptrace.c113
-rw-r--r--libc/sysdeps/unix/sysv/linux/ptsname.c167
-rw-r--r--libc/sysdeps/unix/sysv/linux/pwrite.c96
-rw-r--r--libc/sysdeps/unix/sysv/linux/pwrite64.c94
-rw-r--r--libc/sysdeps/unix/sysv/linux/readahead.c48
-rw-r--r--libc/sysdeps/unix/sysv/linux/readdir64.c7
-rw-r--r--libc/sysdeps/unix/sysv/linux/readdir64_r.c7
-rw-r--r--libc/sysdeps/unix/sysv/linux/readlinkat.c90
-rw-r--r--libc/sysdeps/unix/sysv/linux/readonly-area.c103
-rw-r--r--libc/sysdeps/unix/sysv/linux/readv.c76
-rw-r--r--libc/sysdeps/unix/sysv/linux/reboot.c30
-rw-r--r--libc/sysdeps/unix/sysv/linux/recv.S6
-rw-r--r--libc/sysdeps/unix/sysv/linux/recvfrom.S6
-rw-r--r--libc/sysdeps/unix/sysv/linux/recvmsg.S6
-rw-r--r--libc/sysdeps/unix/sysv/linux/renameat.c184
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/Implies3
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/Makefile8
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/elfclass.h39
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/environments.h87
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/fcntl.h256
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/ipc.h61
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/mman.h104
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/msq.h84
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/sem.h92
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/shm.h110
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/sigaction.h110
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/siginfo.h311
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/stat.h256
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/statfs.h67
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h72
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/brk.c56
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/dl-cache.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/fpu/Implies2
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/ldconfig.h26
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/ldd-rewrite.sed15
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/nldbl-abi.h8
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/readelflib.c60
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/rt-sysdep.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/Makefile15
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/Versions29
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/alphasort64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/chown.c120
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/clone.S76
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/fchown.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c159
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/fcntl.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/fxstat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/fxstatat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S75
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/getdents64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/getegid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/geteuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/getgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/getgroups.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/getresgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/getresuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/getrlimit.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/getrlimit64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/getuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/lchown.c69
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/lockf64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/lxstat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c101
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S84
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S113
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/msgctl.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/oldgetrlimit64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c91
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h27
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/readdir64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/readdir64_r.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/register-dump.h130
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/scandir64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/semctl.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S72
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setegid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/seteuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setfsgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setfsuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setgroups.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setregid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setresgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setresuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setreuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setrlimit.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setuid.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/shmctl.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/socket.S143
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S108
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/syscall.S68
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list5
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S137
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h301
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/versionsort64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/xstat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/Implies1
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/Makefile11
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/Versions7
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/clone.S79
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/dl-cache.h25
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S75
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h21
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c100
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/mmap.S79
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h27
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/register-dump.h133
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S72
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c55
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/sigpending.c38
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/sigprocmask.c41
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/socket.S137
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S108
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/syscall.S69
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list35
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S123
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h304
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/semtimedop.c38
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h28
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/sys/elf.h26
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/sys/procfs.h176
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/sys/ptrace.h138
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/sys/ucontext.h88
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/sys/user.h83
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/system.c34
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/ucontext_i.sym23
-rw-r--r--libc/sysdeps/unix/sysv/linux/sa_len.c59
-rw-r--r--libc/sysdeps/unix/sysv/linux/sched_getaffinity.c59
-rw-r--r--libc/sysdeps/unix/sysv/linux/sched_setaffinity.c88
-rw-r--r--libc/sysdeps/unix/sysv/linux/scsi/scsi.h226
-rw-r--r--libc/sysdeps/unix/sysv/linux/scsi/scsi_ioctl.h34
-rw-r--r--libc/sysdeps/unix/sysv/linux/scsi/sg.h275
-rw-r--r--libc/sysdeps/unix/sysv/linux/segfault.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/semctl.c192
-rw-r--r--libc/sysdeps/unix/sysv/linux/semget.c38
-rw-r--r--libc/sysdeps/unix/sysv/linux/semop.c38
-rw-r--r--libc/sysdeps/unix/sysv/linux/semtimedop.c40
-rw-r--r--libc/sysdeps/unix/sysv/linux/send.S7
-rw-r--r--libc/sysdeps/unix/sysv/linux/sendmsg.S6
-rw-r--r--libc/sysdeps/unix/sysv/linux/sendto.S6
-rw-r--r--libc/sysdeps/unix/sysv/linux/setegid.c61
-rw-r--r--libc/sysdeps/unix/sysv/linux/seteuid.c61
-rw-r--r--libc/sysdeps/unix/sysv/linux/setgid.c31
-rw-r--r--libc/sysdeps/unix/sysv/linux/sethostid.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/setipv4sourcefilter.c65
-rw-r--r--libc/sysdeps/unix/sysv/linux/setregid.c31
-rw-r--r--libc/sysdeps/unix/sysv/linux/setresgid.c32
-rw-r--r--libc/sysdeps/unix/sysv/linux/setresuid.c32
-rw-r--r--libc/sysdeps/unix/sysv/linux/setreuid.c31
-rw-r--r--libc/sysdeps/unix/sysv/linux/setsockopt.S5
-rw-r--r--libc/sysdeps/unix/sysv/linux/setsourcefilter.c78
-rw-r--r--libc/sysdeps/unix/sysv/linux/setuid.c30
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/Makefile11
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/Versions27
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/bits/atomic.h419
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/bits/fcntl.h236
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/bits/mman.h103
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/brk.c48
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/chown.c69
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/clone.S132
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/fchown.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/fchownat.c140
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/fcntl.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/fxstat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/fxstatat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/getegid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/geteuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/getgroups.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/getresgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/getresuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/getrlimit.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/getrlimit64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/getuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/lchown.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/lockf64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/lxstat.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/makecontext.S145
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/msgctl.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/pipe.S43
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/pread.c93
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/pread64.c94
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/profil-counter.h33
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/pwrite.c93
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/pwrite64.c96
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/semctl.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/setegid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/seteuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/setfsgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/setfsuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/setgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/setgroups.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/setregid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/setresgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/setresuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/setreuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/setrlimit.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/setuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh3/getcontext.S88
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh3/register-dump.h151
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh3/setcontext.S99
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh3/swapcontext.S132
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh3/sys/ucontext.h102
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh3/ucontext_i.sym38
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh4/getcontext.S131
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh4/register-dump.h262
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh4/setcontext.S139
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S214
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh4/sys/ucontext.h115
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh4/sysdep.h4
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sh4/ucontext_i.sym73
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/shmctl.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h27
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/socket.S180
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sys/io.h48
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sys/procfs.h115
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sys/user.h28
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/syscall.S44
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/syscalls.list3
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sysdep.S34
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/sysdep.h391
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/vfork.S71
-rw-r--r--libc/sysdeps/unix/sysv/linux/sh/xstat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/shm_open.c248
-rw-r--r--libc/sysdeps/unix/sysv/linux/shm_unlink.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/shmat.c59
-rw-r--r--libc/sysdeps/unix/sysv/linux/shmctl.c161
-rw-r--r--libc/sysdeps/unix/sysv/linux/shmdt.c35
-rw-r--r--libc/sysdeps/unix/sysv/linux/shmget.c38
-rw-r--r--libc/sysdeps/unix/sysv/linux/shutdown.S3
-rw-r--r--libc/sysdeps/unix/sysv/linux/sigaction.c140
-rw-r--r--libc/sysdeps/unix/sysv/linux/siglist.h25
-rw-r--r--libc/sysdeps/unix/sysv/linux/signal.c3
-rw-r--r--libc/sysdeps/unix/sysv/linux/sigpending.c64
-rw-r--r--libc/sysdeps/unix/sysv/linux/sigprocmask.c91
-rw-r--r--libc/sysdeps/unix/sysv/linux/sigqueue.c52
-rw-r--r--libc/sysdeps/unix/sysv/linux/sigreturn.c3
-rw-r--r--libc/sysdeps/unix/sysv/linux/sigset-cvt-mask.h44
-rw-r--r--libc/sysdeps/unix/sysv/linux/sigstack.c69
-rw-r--r--libc/sysdeps/unix/sysv/linux/sigsuspend.c95
-rw-r--r--libc/sysdeps/unix/sysv/linux/sigtimedwait.c93
-rw-r--r--libc/sysdeps/unix/sysv/linux/sigwait.c111
-rw-r--r--libc/sysdeps/unix/sysv/linux/sigwaitinfo.c94
-rw-r--r--libc/sysdeps/unix/sysv/linux/sizes.h24
-rw-r--r--libc/sysdeps/unix/sysv/linux/sleep.c149
-rw-r--r--libc/sysdeps/unix/sysv/linux/socketcall.h48
-rw-r--r--libc/sysdeps/unix/sysv/linux/socketpair.S3
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/Makefile5
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/Versions28
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/a.out.h174
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/a.out.h13
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/environments.h87
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/errno.h58
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h255
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h37
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/ipc.h62
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/mman.h106
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/msq.h84
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/poll.h50
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/resource.h241
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/sem.h92
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/setjmp.h69
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/shm.h111
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/sigaction.h76
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/sigcontext.h78
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/siginfo.h318
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/signum.h84
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/sigstack.h55
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/stat.h165
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/termios.h233
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h66
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h20
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/dl-cache.h39
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/fork.S30
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/getsysstats.c55
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/kernel_termios.h38
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/ldd-rewrite.sed3
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/readelflib.c62
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/rt-sysdep.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/Implies3
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile21
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/Versions23
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/brk.c55
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/chown.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S109
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/fchown.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/fcntl.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Implies2
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/fxstat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/fxstatat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/getdents64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/getegid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/geteuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/getgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/getgroups.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c46
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/getuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h32
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/lchown.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/lockf64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/lxstat.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/msgctl.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/nldbl-abi.h8
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S40
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h26
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64_r.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h336
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/semctl.c208
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/setfsgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/setfsuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/setgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/setgroups.c2
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/setregid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/setreuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/setuid.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/shmctl.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c161
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h29
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S117
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/get_clockfreq.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S37
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list6
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h160
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc32/xstat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/Implies1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile2
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/Versions11
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/__longjmp.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S98
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-_setjmp.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-setjmp.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S121
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/dl-brk.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/dl-cache.h25
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/fxstat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/fxstatat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c238
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/getcontext.S65
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h47
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S52
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/lxstat.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c67
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/msgctl.c38
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S41
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h26
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h257
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/semctl.c58
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S39
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S67
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/shmctl.c37
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c85
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h32
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigjmp.S1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigpending.c36
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigprocmask.c39
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/sizes.h24
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S119
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/swapcontext.c48
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S39
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list20
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h175
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/time.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/ucontext_i.h28
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/wordexp.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c8
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sparc64/xstatconv.c127
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sys/procfs.h211
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sys/ptrace.h183
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sys/trap.h7
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sys/ucontext.h270
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sys/user.h85
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/syscalls.list3
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sysdep.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sysdep.h153
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/system.c34
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/vfork.S29
-rw-r--r--libc/sysdeps/unix/sysv/linux/speed.c111
-rw-r--r--libc/sysdeps/unix/sysv/linux/statfs64.c74
-rw-r--r--libc/sysdeps/unix/sysv/linux/statvfs.c46
-rw-r--r--libc/sysdeps/unix/sysv/linux/statvfs64.c74
-rw-r--r--libc/sysdeps/unix/sysv/linux/symlinkat.c87
-rw-r--r--libc/sysdeps/unix/sysv/linux/sync_file_range.c47
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/acct.h77
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/epoll.h110
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/fsuid.h36
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/inotify.h92
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/kd.h35
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/kdaemon.h33
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/klog.h34
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/mount.h119
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/param.h72
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/pci.h25
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/personality.h73
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/prctl.h32
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/procfs.h115
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/ptrace.h129
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/quota.h225
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/raw.h39
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/reboot.h49
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/soundcard.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/swap.h43
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/syscall.h35
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/sysctl.h72
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/sysinfo.h48
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/sysmacros.h69
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/timex.h127
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/ttydefaults.h100
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/ultrasound.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/user.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/vt.h1
-rw-r--r--libc/sysdeps/unix/sysv/linux/syscalls.list97
-rw-r--r--libc/sysdeps/unix/sysv/linux/sysconf.c118
-rw-r--r--libc/sysdeps/unix/sysv/linux/sysctl.c49
-rw-r--r--libc/sysdeps/unix/sysv/linux/syslog.c10
-rw-r--r--libc/sysdeps/unix/sysv/linux/system.c78
-rw-r--r--libc/sysdeps/unix/sysv/linux/tcdrain.c41
-rw-r--r--libc/sysdeps/unix/sysv/linux/tcflow.c31
-rw-r--r--libc/sysdeps/unix/sysv/linux/tcflush.c31
-rw-r--r--libc/sysdeps/unix/sysv/linux/tcgetattr.c82
-rw-r--r--libc/sysdeps/unix/sysv/linux/tcgetpgrp.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/tcsetattr.c85
-rw-r--r--libc/sysdeps/unix/sysv/linux/tcsetpgrp.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/termio.h6
-rw-r--r--libc/sysdeps/unix/sysv/linux/testrtsig.h36
-rw-r--r--libc/sysdeps/unix/sysv/linux/time.c43
-rw-r--r--libc/sysdeps/unix/sysv/linux/truncate64.c76
-rw-r--r--libc/sysdeps/unix/sysv/linux/tst-clone.c56
-rw-r--r--libc/sysdeps/unix/sysv/linux/ttyname.c200
-rw-r--r--libc/sysdeps/unix/sysv/linux/ttyname_r.c203
-rw-r--r--libc/sysdeps/unix/sysv/linux/ualarm.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/ulimit.c86
-rw-r--r--libc/sysdeps/unix/sysv/linux/umount.S12
-rw-r--r--libc/sysdeps/unix/sysv/linux/umount2.S13
-rw-r--r--libc/sysdeps/unix/sysv/linux/unlinkat.c97
-rw-r--r--libc/sysdeps/unix/sysv/linux/unlockpt.c49
-rw-r--r--libc/sysdeps/unix/sysv/linux/updwtmp.c34
-rw-r--r--libc/sysdeps/unix/sysv/linux/usleep.c34
-rw-r--r--libc/sysdeps/unix/sysv/linux/ustat.c42
-rw-r--r--libc/sysdeps/unix/sysv/linux/utimes.c60
-rw-r--r--libc/sysdeps/unix/sysv/linux/utmp_file.c34
-rw-r--r--libc/sysdeps/unix/sysv/linux/vfork.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wait.c45
-rw-r--r--libc/sysdeps/unix/sysv/linux/wait3.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/waitid.c71
-rw-r--r--libc/sysdeps/unix/sysv/linux/waitpid.c50
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/fstatfs64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/fstatvfs.c5
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/fstatvfs64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/ftruncate64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/fxstat.c48
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/fxstat64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c109
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/fxstatat64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/getdents.c4
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/getdents64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/getrlimit64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/glob64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/internal_statvfs64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/lxstat.c48
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/lxstat64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/mmap64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/posix_fadvise.c41
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/posix_fadvise64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/pread64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/pwrite64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/readdir.c7
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/readdir64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/readdir64_r.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c4
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/sendfile64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/setrlimit64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/statfs64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/statvfs.c5
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/statvfs64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list17
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/truncate64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/xstat.c47
-rw-r--r--libc/sysdeps/unix/sysv/linux/wordsize-64/xstat64.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/writev.c75
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/Implies1
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/Makefile15
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/Versions9
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/__start_context.S49
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/bits/a.out.h13
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/bits/environments.h87
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h250
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/bits/mman.h104
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/bits/msq.h83
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/bits/sem.h87
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/bits/shm.h110
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/bits/sigcontext.h159
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/bits/stat.h203
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/brk.c42
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/clone.S120
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/dl-cache.h25
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c5
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h5
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/get_clockfreq.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/getcontext.S88
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S44
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h21
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/ldconfig.h26
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed3
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/makecontext.c113
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/profil-counter.h32
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/readelflib.c62
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/recv.c42
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/register-dump.h346
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/send.c41
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/setcontext.S105
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sigaction.c112
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h26
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sigpending.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sigprocmask.c1
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/swapcontext.S123
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sys/debugreg.h88
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h110
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sys/io.h181
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sys/perm.h36
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sys/procfs.h142
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sys/reg.h79
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sys/ucontext.h248
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sys/user.h175
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/syscall.S44
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/syscalls.list36
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sysconf.c326
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sysdep.S41
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h341
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/time.S42
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym34
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/umount.c31
-rw-r--r--libc/sysdeps/unix/sysv/linux/x86_64/vfork.S61
-rw-r--r--libc/sysdeps/unix/sysv/linux/xmknod.c57
-rw-r--r--libc/sysdeps/unix/sysv/linux/xmknodat.c95
-rw-r--r--libc/sysdeps/unix/sysv/linux/xstat.c64
-rw-r--r--libc/sysdeps/unix/sysv/linux/xstat64.c97
-rw-r--r--libc/sysdeps/unix/sysv/linux/xstatconv.c285
-rw-r--r--libc/sysdeps/unix/sysv/linux/xstatconv.h27
-rw-r--r--libc/sysdeps/unix/sysv/setrlimit.c57
-rw-r--r--libc/sysdeps/unix/sysv/settimeofday.c48
-rw-r--r--libc/sysdeps/unix/sysv/sigaction.c84
-rw-r--r--libc/sysdeps/unix/sysv/syscalls.list16
-rw-r--r--libc/sysdeps/unix/sysv/sysv_termio.h155
-rw-r--r--libc/sysdeps/unix/sysv/tcdrain.c33
-rw-r--r--libc/sysdeps/unix/sysv/tcflow.c47
-rw-r--r--libc/sysdeps/unix/sysv/tcflush.c45
-rw-r--r--libc/sysdeps/unix/sysv/tcgetattr.c171
-rw-r--r--libc/sysdeps/unix/sysv/tcgetpgrp.c36
-rw-r--r--libc/sysdeps/unix/sysv/tcsendbrk.c44
-rw-r--r--libc/sysdeps/unix/sysv/tcsetattr.c210
-rw-r--r--libc/sysdeps/unix/sysv/tcsetpgrp.c32
-rw-r--r--libc/sysdeps/unix/telldir.c28
-rw-r--r--libc/sysdeps/unix/time.c42
-rw-r--r--libc/sysdeps/unix/utime.c50
-rw-r--r--libc/sysdeps/unix/x86_64/sysdep.S90
-rw-r--r--libc/sysdeps/unix/x86_64/sysdep.h35
-rw-r--r--libc/sysdeps/unix/xmknod.c42
-rw-r--r--libc/sysdeps/unix/xstat.c39
-rw-r--r--libc/sysdeps/wordsize-32/Makefile7
-rw-r--r--libc/sysdeps/wordsize-32/Versions7
-rw-r--r--libc/sysdeps/wordsize-32/bits/wordsize.h19
-rw-r--r--libc/sysdeps/wordsize-32/divdi3.c344
-rw-r--r--libc/sysdeps/wordsize-32/llabs.c23
-rw-r--r--libc/sysdeps/wordsize-32/lldiv.c27
-rw-r--r--libc/sysdeps/wordsize-32/strtoimax.c28
-rw-r--r--libc/sysdeps/wordsize-32/strtoumax.c28
-rw-r--r--libc/sysdeps/wordsize-32/symbol-hacks.h30
-rw-r--r--libc/sysdeps/wordsize-32/wcstoimax.c29
-rw-r--r--libc/sysdeps/wordsize-32/wcstoumax.c29
-rw-r--r--libc/sysdeps/wordsize-64/Versions6
-rw-r--r--libc/sysdeps/wordsize-64/bits/wordsize.h19
-rw-r--r--libc/sysdeps/wordsize-64/glob.c8
-rw-r--r--libc/sysdeps/wordsize-64/labs.c23
-rw-r--r--libc/sysdeps/wordsize-64/ldiv.c27
-rw-r--r--libc/sysdeps/wordsize-64/strtoimax.c28
-rw-r--r--libc/sysdeps/wordsize-64/strtol.c14
-rw-r--r--libc/sysdeps/wordsize-64/strtol_l.c14
-rw-r--r--libc/sysdeps/wordsize-64/strtoll.c1
-rw-r--r--libc/sysdeps/wordsize-64/strtoll_l.c1
-rw-r--r--libc/sysdeps/wordsize-64/strtoul.c14
-rw-r--r--libc/sysdeps/wordsize-64/strtoul_l.c14
-rw-r--r--libc/sysdeps/wordsize-64/strtoull.c1
-rw-r--r--libc/sysdeps/wordsize-64/strtoull_l.c1
-rw-r--r--libc/sysdeps/wordsize-64/strtoumax.c28
-rw-r--r--libc/sysdeps/wordsize-64/wcstoimax.c29
-rw-r--r--libc/sysdeps/wordsize-64/wcstol.c14
-rw-r--r--libc/sysdeps/wordsize-64/wcstol_l.c13
-rw-r--r--libc/sysdeps/wordsize-64/wcstoll.c1
-rw-r--r--libc/sysdeps/wordsize-64/wcstoll_l.c1
-rw-r--r--libc/sysdeps/wordsize-64/wcstoul.c14
-rw-r--r--libc/sysdeps/wordsize-64/wcstoul_l.c13
-rw-r--r--libc/sysdeps/wordsize-64/wcstoull.c1
-rw-r--r--libc/sysdeps/wordsize-64/wcstoull_l.c1
-rw-r--r--libc/sysdeps/wordsize-64/wcstoumax.c29
-rw-r--r--libc/sysdeps/x86_64/Implies4
-rw-r--r--libc/sysdeps/x86_64/Makefile11
-rw-r--r--libc/sysdeps/x86_64/Versions7
-rw-r--r--libc/sysdeps/x86_64/__longjmp.S57
-rw-r--r--libc/sysdeps/x86_64/_mcount.S67
-rw-r--r--libc/sysdeps/x86_64/abort-instr.h2
-rw-r--r--libc/sysdeps/x86_64/backtrace.c1
-rw-r--r--libc/sysdeps/x86_64/bits/atomic.h324
-rw-r--r--libc/sysdeps/x86_64/bits/byteswap.h133
-rw-r--r--libc/sysdeps/x86_64/bits/endian.h7
-rw-r--r--libc/sysdeps/x86_64/bits/link.h117
-rw-r--r--libc/sysdeps/x86_64/bits/linkmap.h14
-rw-r--r--libc/sysdeps/x86_64/bits/mathdef.h48
-rw-r--r--libc/sysdeps/x86_64/bits/setjmp.h39
-rw-r--r--libc/sysdeps/x86_64/bits/string.h26
-rw-r--r--libc/sysdeps/x86_64/bits/wordsize.h8
-rw-r--r--libc/sysdeps/x86_64/bits/xtitypes.h34
-rw-r--r--libc/sysdeps/x86_64/bp-asm.h141
-rw-r--r--libc/sysdeps/x86_64/bsd-_setjmp.S41
-rw-r--r--libc/sysdeps/x86_64/bsd-setjmp.S40
-rw-r--r--libc/sysdeps/x86_64/bzero.S3
-rw-r--r--libc/sysdeps/x86_64/dl-machine.h442
-rw-r--r--libc/sysdeps/x86_64/dl-tls.h29
-rw-r--r--libc/sysdeps/x86_64/dl-trampoline.S189
-rwxr-xr-xlibc/sysdeps/x86_64/elf/configure49
-rw-r--r--libc/sysdeps/x86_64/elf/configure.in34
-rw-r--r--libc/sysdeps/x86_64/elf/initfini.c108
-rw-r--r--libc/sysdeps/x86_64/elf/start.S124
-rw-r--r--libc/sysdeps/x86_64/ffs.c39
-rw-r--r--libc/sysdeps/x86_64/ffsll.c41
-rw-r--r--libc/sysdeps/x86_64/fpu/bits/fenv.h97
-rw-r--r--libc/sysdeps/x86_64/fpu/bits/mathinline.h53
-rw-r--r--libc/sysdeps/x86_64/fpu/e_acosl.c1
-rw-r--r--libc/sysdeps/x86_64/fpu/e_atan2l.c2
-rw-r--r--libc/sysdeps/x86_64/fpu/e_exp2l.S38
-rw-r--r--libc/sysdeps/x86_64/fpu/e_expl.c1
-rw-r--r--libc/sysdeps/x86_64/fpu/e_fmodl.S22
-rw-r--r--libc/sysdeps/x86_64/fpu/e_log10l.S66
-rw-r--r--libc/sysdeps/x86_64/fpu/e_log2l.S63
-rw-r--r--libc/sysdeps/x86_64/fpu/e_logl.S56
-rw-r--r--libc/sysdeps/x86_64/fpu/e_powl.S338
-rw-r--r--libc/sysdeps/x86_64/fpu/e_rem_pio2l.c3
-rw-r--r--libc/sysdeps/x86_64/fpu/e_remainderl.S20
-rw-r--r--libc/sysdeps/x86_64/fpu/e_scalbl.S100
-rw-r--r--libc/sysdeps/x86_64/fpu/e_sqrt.c30
-rw-r--r--libc/sysdeps/x86_64/fpu/e_sqrtf.c30
-rw-r--r--libc/sysdeps/x86_64/fpu/e_sqrtl.c1
-rw-r--r--libc/sysdeps/x86_64/fpu/fclrexcpt.c52
-rw-r--r--libc/sysdeps/x86_64/fpu/fedisblxcpt.c49
-rw-r--r--libc/sysdeps/x86_64/fpu/feenablxcpt.c49
-rw-r--r--libc/sysdeps/x86_64/fpu/fegetenv.c30
-rw-r--r--libc/sysdeps/x86_64/fpu/fegetexcept.c32
-rw-r--r--libc/sysdeps/x86_64/fpu/fegetround.c33
-rw-r--r--libc/sysdeps/x86_64/fpu/feholdexcpt.c42
-rw-r--r--libc/sysdeps/x86_64/fpu/fesetenv.c89
-rw-r--r--libc/sysdeps/x86_64/fpu/fesetround.c47
-rw-r--r--libc/sysdeps/x86_64/fpu/fgetexcptflg.c36
-rw-r--r--libc/sysdeps/x86_64/fpu/fraiseexcpt.c120
-rw-r--r--libc/sysdeps/x86_64/fpu/fsetexcptflg.c54
-rw-r--r--libc/sysdeps/x86_64/fpu/ftestexcept.c33
-rw-r--r--libc/sysdeps/x86_64/fpu/libm-test-ulps1308
-rw-r--r--libc/sysdeps/x86_64/fpu/math_ldbl.h79
-rw-r--r--libc/sysdeps/x86_64/fpu/printf_fphex.c92
-rw-r--r--libc/sysdeps/x86_64/fpu/s_atanl.c1
-rw-r--r--libc/sysdeps/x86_64/fpu/s_ceill.S31
-rw-r--r--libc/sysdeps/x86_64/fpu/s_copysign.S52
-rw-r--r--libc/sysdeps/x86_64/fpu/s_copysignf.S49
-rw-r--r--libc/sysdeps/x86_64/fpu/s_copysignl.S22
-rw-r--r--libc/sysdeps/x86_64/fpu/s_cosl.S32
-rw-r--r--libc/sysdeps/x86_64/fpu/s_expm1l.S84
-rw-r--r--libc/sysdeps/x86_64/fpu/s_fabs.c27
-rw-r--r--libc/sysdeps/x86_64/fpu/s_fabsf.c27
-rw-r--r--libc/sysdeps/x86_64/fpu/s_fabsl.S28
-rw-r--r--libc/sysdeps/x86_64/fpu/s_fdiml.S44
-rw-r--r--libc/sysdeps/x86_64/fpu/s_finitel.S16
-rw-r--r--libc/sysdeps/x86_64/fpu/s_floorl.S30
-rw-r--r--libc/sysdeps/x86_64/fpu/s_fmax.S36
-rw-r--r--libc/sysdeps/x86_64/fpu/s_fmaxf.S36
-rw-r--r--libc/sysdeps/x86_64/fpu/s_fmaxl.S40
-rw-r--r--libc/sysdeps/x86_64/fpu/s_fmin.S36
-rw-r--r--libc/sysdeps/x86_64/fpu/s_fminf.S36
-rw-r--r--libc/sysdeps/x86_64/fpu/s_fminl.S38
-rw-r--r--libc/sysdeps/x86_64/fpu/s_fpclassifyl.c2
-rw-r--r--libc/sysdeps/x86_64/fpu/s_ilogbl.S35
-rw-r--r--libc/sysdeps/x86_64/fpu/s_isinfl.c1
-rw-r--r--libc/sysdeps/x86_64/fpu/s_isnanl.c1
-rw-r--r--libc/sysdeps/x86_64/fpu/s_llrint.S31
-rw-r--r--libc/sysdeps/x86_64/fpu/s_llrintf.S31
-rw-r--r--libc/sysdeps/x86_64/fpu/s_llrintl.S34
-rw-r--r--libc/sysdeps/x86_64/fpu/s_log1pl.S71
-rw-r--r--libc/sysdeps/x86_64/fpu/s_logbl.c1
-rw-r--r--libc/sysdeps/x86_64/fpu/s_lrint.S1
-rw-r--r--libc/sysdeps/x86_64/fpu/s_lrintf.S1
-rw-r--r--libc/sysdeps/x86_64/fpu/s_lrintl.S1
-rw-r--r--libc/sysdeps/x86_64/fpu/s_nearbyintl.S21
-rw-r--r--libc/sysdeps/x86_64/fpu/s_nextafterl.c1
-rw-r--r--libc/sysdeps/x86_64/fpu/s_nexttoward.c1
-rw-r--r--libc/sysdeps/x86_64/fpu/s_nexttowardf.c1
-rw-r--r--libc/sysdeps/x86_64/fpu/s_rintl.c1
-rw-r--r--libc/sysdeps/x86_64/fpu/s_scalbnl.S18
-rw-r--r--libc/sysdeps/x86_64/fpu/s_significandl.c1
-rw-r--r--libc/sysdeps/x86_64/fpu/s_sincos.S61
-rw-r--r--libc/sysdeps/x86_64/fpu/s_sincosl.S60
-rw-r--r--libc/sysdeps/x86_64/fpu/s_sinl.S30
-rw-r--r--libc/sysdeps/x86_64/fpu/s_tanl.S33
-rw-r--r--libc/sysdeps/x86_64/fpu/s_truncl.S34
-rw-r--r--libc/sysdeps/x86_64/fpu_control.h101
-rw-r--r--libc/sysdeps/x86_64/hp-timing.c2
-rw-r--r--libc/sysdeps/x86_64/hp-timing.h41
-rw-r--r--libc/sysdeps/x86_64/htonl.S35
-rw-r--r--libc/sysdeps/x86_64/jmpbuf-offsets.h30
-rw-r--r--libc/sysdeps/x86_64/jmpbuf-unwind.h48
-rw-r--r--libc/sysdeps/x86_64/machine-gmon.h39
-rw-r--r--libc/sysdeps/x86_64/memcpy.S101
-rw-r--r--libc/sysdeps/x86_64/memcpy_chk.S34
-rw-r--r--libc/sysdeps/x86_64/mempcpy.S7
-rw-r--r--libc/sysdeps/x86_64/mempcpy_chk.S34
-rw-r--r--libc/sysdeps/x86_64/memset.S146
-rw-r--r--libc/sysdeps/x86_64/memset_chk.S34
-rw-r--r--libc/sysdeps/x86_64/memusage.h22
-rw-r--r--libc/sysdeps/x86_64/setjmp.S62
-rw-r--r--libc/sysdeps/x86_64/soft-fp/sfp-machine.h51
-rw-r--r--libc/sysdeps/x86_64/stackinfo.h28
-rw-r--r--libc/sysdeps/x86_64/stpcpy.S8
-rw-r--r--libc/sysdeps/x86_64/stpcpy_chk.S3
-rw-r--r--libc/sysdeps/x86_64/strcat.S260
-rw-r--r--libc/sysdeps/x86_64/strchr.S291
-rw-r--r--libc/sysdeps/x86_64/strcmp.S45
-rw-r--r--libc/sysdeps/x86_64/strcpy.S159
-rw-r--r--libc/sysdeps/x86_64/strcpy_chk.S211
-rw-r--r--libc/sysdeps/x86_64/strcspn.S127
-rw-r--r--libc/sysdeps/x86_64/strlen.S139
-rw-r--r--libc/sysdeps/x86_64/strpbrk.S2
-rw-r--r--libc/sysdeps/x86_64/strspn.S117
-rw-r--r--libc/sysdeps/x86_64/strtok.S212
-rw-r--r--libc/sysdeps/x86_64/strtok_r.S5
-rw-r--r--libc/sysdeps/x86_64/sysdep.h114
-rw-r--r--libc/sysdeps/x86_64/tst-stack-align.h47
4277 files changed, 495375 insertions, 0 deletions
diff --git a/libc/sysdeps/alpha/Implies b/libc/sysdeps/alpha/Implies
new file mode 100644
index 000000000..18c35908c
--- /dev/null
+++ b/libc/sysdeps/alpha/Implies
@@ -0,0 +1,6 @@
+wordsize-64
+# Alpha uses IEEE 754 single, double and quad precision floating point.
+ieee754/ldbl-128
+ieee754/dbl-64
+ieee754/flt-32
+alpha/soft-fp
diff --git a/libc/sysdeps/alpha/Makefile b/libc/sysdeps/alpha/Makefile
new file mode 100644
index 000000000..1e74d82f5
--- /dev/null
+++ b/libc/sysdeps/alpha/Makefile
@@ -0,0 +1,47 @@
+# Copyright (C) 1993, 94, 95, 96, 97, 99 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Brendan Kehoe (brendan@zen.org).
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifeq ($(subdir),db2)
+CPPFLAGS += -DHAVE_SPINLOCKS=1 -DHAVE_ASSEM_ALPHA=1
+endif
+
+ifeq ($(subdir),gmon)
+sysdep_routines += _mcount
+endif
+
+ifeq ($(subdir),gnulib)
+sysdep_routines += divl divlu divq divqu reml remlu remq remqu
+endif
+
+ifeq ($(subdir),string)
+sysdep_routines += stxcpy stxncpy
+endif
+
+ifeq ($(subdir),elf)
+# The ld.so startup code cannot use literals until it self-relocates.
+CFLAGS-rtld.c = -mbuild-constants
+endif
+
+# For now, build everything with full IEEE math support.
+# TODO: build separate libm and libm-ieee.
+sysdep-CFLAGS += -mieee
+
+# libc.so requires about 16k for the small data area, which is well
+# below the 64k maximum.
+pic-ccflag = -fpic
diff --git a/libc/sysdeps/alpha/Subdirs b/libc/sysdeps/alpha/Subdirs
new file mode 100644
index 000000000..87eadf302
--- /dev/null
+++ b/libc/sysdeps/alpha/Subdirs
@@ -0,0 +1 @@
+soft-fp
diff --git a/libc/sysdeps/alpha/Versions b/libc/sysdeps/alpha/Versions
new file mode 100644
index 000000000..76b67a6b9
--- /dev/null
+++ b/libc/sysdeps/alpha/Versions
@@ -0,0 +1,13 @@
+libc {
+ GLIBC_2.0 {
+ # functions with special/multiple interfaces
+ __divqu; __remqu; __divqs; __remqs; __divlu; __remlu; __divls;
+ __remls; __divl; __reml; __divq; __remq; __divqu; __remqu;
+ }
+}
+libm {
+ GLIBC_2.0 {
+ # used in inline functions.
+ __atan2;
+ }
+}
diff --git a/libc/sysdeps/alpha/__longjmp.S b/libc/sysdeps/alpha/__longjmp.S
new file mode 100644
index 000000000..bed26658d
--- /dev/null
+++ b/libc/sysdeps/alpha/__longjmp.S
@@ -0,0 +1,64 @@
+/* Copyright (C) 1992, 1994, 1997, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __ASSEMBLY__
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+
+
+ENTRY(__longjmp)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ mov a1, v0
+ ldq s0, JB_S0*8(a0)
+ ldq s1, JB_S1*8(a0)
+ ldq s2, JB_S2*8(a0)
+ ldq s3, JB_S3*8(a0)
+ ldq s4, JB_S4*8(a0)
+ ldq s5, JB_S5*8(a0)
+ ldq ra, JB_PC*8(a0)
+ ldq fp, JB_FP*8(a0)
+ ldq t0, JB_SP*8(a0)
+ ldt $f2, JB_F2*8(a0)
+ ldt $f3, JB_F3*8(a0)
+ ldt $f4, JB_F4*8(a0)
+ ldt $f5, JB_F5*8(a0)
+ ldt $f6, JB_F6*8(a0)
+ ldt $f7, JB_F7*8(a0)
+ ldt $f8, JB_F8*8(a0)
+ ldt $f9, JB_F9*8(a0)
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE(ra, t1)
+ PTR_DEMANGLE2(t0, t1)
+ PTR_DEMANGLE2(fp, t1)
+#endif
+ cmoveq v0, 1, v0
+ mov t0, sp
+ ret
+
+END(__longjmp)
diff --git a/libc/sysdeps/alpha/_mcount.S b/libc/sysdeps/alpha/_mcount.S
new file mode 100644
index 000000000..c4c921b4f
--- /dev/null
+++ b/libc/sysdeps/alpha/_mcount.S
@@ -0,0 +1,107 @@
+/* Machine-specific calling sequence for `mcount' profiling function. alpha
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by David Mosberger (davidm@cs.arizona.edu).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Assembly stub to invoke _mcount(). Compiler generated code calls
+ this stub after executing a function's prologue and without saving any
+ registers. It is therefore necessary to preserve a0..a5 as they may
+ contain function arguments. To work correctly with frame- less
+ functions, it is also necessary to preserve ra. Finally, division
+ routines are invoked with a special calling convention and the
+ compiler treats those calls as if they were instructions. In
+ particular, it doesn't save any of the temporary registers (caller
+ saved registers). It is therefore necessary to preserve all
+ caller-saved registers as well.
+
+ Upon entering _mcount, register $at holds the return address and ra
+ holds the return address of the function's caller (selfpc and frompc,
+ respectively in gmon.c language...). */
+
+#include <sysdep.h>
+
+ .set noat
+ .set noreorder
+
+LEAF(_mcount, 0xb0)
+ .prologue 0
+
+ subq sp, 0xb0, sp
+ stq a0, 0x00(sp)
+ mov ra, a0 # a0 = caller-pc
+ stq a1, 0x08(sp)
+ mov $at, a1 # a1 = self-pc
+ stq $at, 0x10(sp)
+
+ stq a2, 0x18(sp)
+ stq a3, 0x20(sp)
+ stq a4, 0x28(sp)
+ stq a5, 0x30(sp)
+ stq ra, 0x38(sp)
+ stq gp, 0x40(sp)
+
+ br gp, 1f
+1: ldgp gp, 0(gp)
+
+ stq t0, 0x48(sp)
+ stq t1, 0x50(sp)
+ stq t2, 0x58(sp)
+ stq t3, 0x60(sp)
+ stq t4, 0x68(sp)
+ stq t5, 0x70(sp)
+ stq t6, 0x78(sp)
+
+ stq t7, 0x80(sp)
+ stq t8, 0x88(sp)
+ stq t9, 0x90(sp)
+ stq t10, 0x98(sp)
+ stq t11, 0xa0(sp)
+ stq v0, 0xa8(sp)
+
+ jsr ra, __mcount
+
+ ldq a0, 0x00(sp)
+ ldq a1, 0x08(sp)
+ ldq $at, 0x10(sp) # restore self-pc
+ ldq a2, 0x18(sp)
+ ldq a3, 0x20(sp)
+ ldq a4, 0x28(sp)
+ ldq a5, 0x30(sp)
+ ldq ra, 0x38(sp)
+ ldq gp, 0x40(sp)
+ mov $at, pv # make pv point to return address
+ ldq t0, 0x48(sp) # this is important under OSF/1 to
+ ldq t1, 0x50(sp) # ensure that the code that we return
+ ldq t2, 0x58(sp) # can correctly compute its gp
+ ldq t3, 0x60(sp)
+ ldq t4, 0x68(sp)
+ ldq t5, 0x70(sp)
+ ldq t6, 0x78(sp)
+ ldq t7, 0x80(sp)
+ ldq t8, 0x88(sp)
+ ldq t9, 0x90(sp)
+ ldq t10, 0x98(sp)
+ ldq t11, 0xa0(sp)
+ ldq v0, 0xa8(sp)
+
+ addq sp, 0xb0, sp
+ ret zero,($at),1
+
+ END(_mcount)
+
+weak_alias (_mcount, mcount)
diff --git a/libc/sysdeps/alpha/add_n.s b/libc/sysdeps/alpha/add_n.s
new file mode 100644
index 000000000..e0dc2fd0c
--- /dev/null
+++ b/libc/sysdeps/alpha/add_n.s
@@ -0,0 +1,120 @@
+ # Alpha __mpn_add_n -- Add two limb vectors of the same length > 0 and
+ # store sum in a third limb vector.
+
+ # Copyright (C) 1995 Free Software Foundation, Inc.
+
+ # This file is part of the GNU MP Library.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published by
+ # the Free Software Foundation; either version 2.1 of the License, or (at your
+ # option) any later version.
+
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+
+ # INPUT PARAMETERS
+ # res_ptr $16
+ # s1_ptr $17
+ # s2_ptr $18
+ # size $19
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __mpn_add_n
+ .ent __mpn_add_n
+__mpn_add_n:
+ .frame $30,0,$26,0
+
+ ldq $3,0($17)
+ ldq $4,0($18)
+
+ subq $19,1,$19
+ and $19,4-1,$2 # number of limbs in first loop
+ bis $31,$31,$0
+ beq $2,.L0 # if multiple of 4 limbs, skip first loop
+
+ subq $19,$2,$19
+
+.Loop0: subq $2,1,$2
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ addq $17,8,$17
+ addq $18,8,$18
+ bis $5,$5,$3
+ bis $6,$6,$4
+ addq $16,8,$16
+ bne $2,.Loop0
+
+.L0: beq $19,.Lend
+
+ .align 3
+.Loop: subq $19,4,$19
+
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ ldq $3,16($17)
+ addq $6,$0,$6
+ ldq $4,16($18)
+ cmpult $6,$0,$1
+ addq $5,$6,$6
+ cmpult $6,$5,$0
+ stq $6,8($16)
+ or $0,$1,$0
+
+ ldq $5,24($17)
+ addq $4,$0,$4
+ ldq $6,24($18)
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,16($16)
+ or $0,$1,$0
+
+ ldq $3,32($17)
+ addq $6,$0,$6
+ ldq $4,32($18)
+ cmpult $6,$0,$1
+ addq $5,$6,$6
+ cmpult $6,$5,$0
+ stq $6,24($16)
+ or $0,$1,$0
+
+ addq $17,32,$17
+ addq $18,32,$18
+ addq $16,32,$16
+ bne $19,.Loop
+
+.Lend: addq $4,$0,$4
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,0($16)
+ or $0,$1,$0
+ ret $31,($26),1
+
+ .end __mpn_add_n
diff --git a/libc/sysdeps/alpha/addmul_1.s b/libc/sysdeps/alpha/addmul_1.s
new file mode 100644
index 000000000..da26c692a
--- /dev/null
+++ b/libc/sysdeps/alpha/addmul_1.s
@@ -0,0 +1,92 @@
+ # Alpha 21064 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ # the result to a second limb vector.
+
+ # Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+ # This file is part of the GNU MP Library.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published by
+ # the Free Software Foundation; either version 2.1 of the License, or (at your
+ # option) any later version.
+
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+
+ # INPUT PARAMETERS
+ # res_ptr r16
+ # s1_ptr r17
+ # size r18
+ # s2_limb r19
+
+ # This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5.
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __mpn_addmul_1
+ .ent __mpn_addmul_1 2
+__mpn_addmul_1:
+ .frame $30,0,$26
+
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ umulh $2,$19,$0 # $0 = prod_high
+ beq $18,.Lend1 # jump if size was == 1
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ addq $5,$3,$3
+ cmpult $3,$5,$4
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ beq $18,.Lend2 # jump if size was == 2
+
+ .align 3
+.Loop: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ subq $18,1,$18 # size--
+ umulh $2,$19,$4 # $4 = cy_limb
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ addq $5,$3,$3
+ cmpult $3,$5,$5
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ addq $5,$0,$0 # combine carries
+ bne $18,.Loop
+
+.Lend2: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ umulh $2,$19,$4 # $4 = cy_limb
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ addq $5,$3,$3
+ cmpult $3,$5,$5
+ stq $3,0($16)
+ addq $5,$0,$0 # combine carries
+ addq $4,$0,$0 # cy_limb = prod_high + cy
+ ret $31,($26),1
+.Lend1: addq $5,$3,$3
+ cmpult $3,$5,$5
+ stq $3,0($16)
+ addq $0,$5,$0
+ ret $31,($26),1
+
+ .end __mpn_addmul_1
diff --git a/libc/sysdeps/alpha/alphaev5/add_n.s b/libc/sysdeps/alpha/alphaev5/add_n.s
new file mode 100644
index 000000000..1ff8e9543
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev5/add_n.s
@@ -0,0 +1,148 @@
+ # Alpha __mpn_add_n -- Add two limb vectors of the same length > 0 and
+ # store sum in a third limb vector.
+
+ # Copyright (C) 1995 Free Software Foundation, Inc.
+
+ # This file is part of the GNU MP Library.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published by
+ # the Free Software Foundation; either version 2.1 of the License, or (at your
+ # option) any later version.
+
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+
+ # INPUT PARAMETERS
+ # res_ptr $16
+ # s1_ptr $17
+ # s2_ptr $18
+ # size $19
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __mpn_add_n
+ .ent __mpn_add_n
+__mpn_add_n:
+ .frame $30,0,$26,0
+
+ or $31,$31,$25 # clear cy
+ subq $19,4,$19 # decr loop cnt
+ blt $19,.Lend2 # if less than 4 limbs, goto 2nd loop
+ # Start software pipeline for 1st loop
+ ldq $0,0($18)
+ ldq $1,8($18)
+ ldq $4,0($17)
+ ldq $5,8($17)
+ addq $17,32,$17 # update s1_ptr
+ ldq $2,16($18)
+ addq $0,$4,$20 # 1st main add
+ ldq $3,24($18)
+ subq $19,4,$19 # decr loop cnt
+ ldq $6,-16($17)
+ cmpult $20,$0,$25 # compute cy from last add
+ ldq $7,-8($17)
+ addq $1,$25,$28 # cy add
+ addq $18,32,$18 # update s2_ptr
+ addq $5,$28,$21 # 2nd main add
+ cmpult $28,$25,$8 # compute cy from last add
+ blt $19,.Lend1 # if less than 4 limbs remain, jump
+ # 1st loop handles groups of 4 limbs in a software pipeline
+ .align 4
+.Loop: cmpult $21,$28,$25 # compute cy from last add
+ ldq $0,0($18)
+ or $8,$25,$25 # combine cy from the two adds
+ ldq $1,8($18)
+ addq $2,$25,$28 # cy add
+ ldq $4,0($17)
+ addq $28,$6,$22 # 3rd main add
+ ldq $5,8($17)
+ cmpult $28,$25,$8 # compute cy from last add
+ cmpult $22,$28,$25 # compute cy from last add
+ stq $20,0($16)
+ or $8,$25,$25 # combine cy from the two adds
+ stq $21,8($16)
+ addq $3,$25,$28 # cy add
+ addq $28,$7,$23 # 4th main add
+ cmpult $28,$25,$8 # compute cy from last add
+ cmpult $23,$28,$25 # compute cy from last add
+ addq $17,32,$17 # update s1_ptr
+ or $8,$25,$25 # combine cy from the two adds
+ addq $16,32,$16 # update res_ptr
+ addq $0,$25,$28 # cy add
+ ldq $2,16($18)
+ addq $4,$28,$20 # 1st main add
+ ldq $3,24($18)
+ cmpult $28,$25,$8 # compute cy from last add
+ ldq $6,-16($17)
+ cmpult $20,$28,$25 # compute cy from last add
+ ldq $7,-8($17)
+ or $8,$25,$25 # combine cy from the two adds
+ subq $19,4,$19 # decr loop cnt
+ stq $22,-16($16)
+ addq $1,$25,$28 # cy add
+ stq $23,-8($16)
+ addq $5,$28,$21 # 2nd main add
+ addq $18,32,$18 # update s2_ptr
+ cmpult $28,$25,$8 # compute cy from last add
+ bge $19,.Loop
+ # Finish software pipeline for 1st loop
+.Lend1: cmpult $21,$28,$25 # compute cy from last add
+ or $8,$25,$25 # combine cy from the two adds
+ addq $2,$25,$28 # cy add
+ addq $28,$6,$22 # 3rd main add
+ cmpult $28,$25,$8 # compute cy from last add
+ cmpult $22,$28,$25 # compute cy from last add
+ stq $20,0($16)
+ or $8,$25,$25 # combine cy from the two adds
+ stq $21,8($16)
+ addq $3,$25,$28 # cy add
+ addq $28,$7,$23 # 4th main add
+ cmpult $28,$25,$8 # compute cy from last add
+ cmpult $23,$28,$25 # compute cy from last add
+ or $8,$25,$25 # combine cy from the two adds
+ addq $16,32,$16 # update res_ptr
+ stq $22,-16($16)
+ stq $23,-8($16)
+.Lend2: addq $19,4,$19 # restore loop cnt
+ beq $19,.Lret
+ # Start software pipeline for 2nd loop
+ ldq $0,0($18)
+ ldq $4,0($17)
+ subq $19,1,$19
+ beq $19,.Lend0
+ # 2nd loop handles remaining 1-3 limbs
+ .align 4
+.Loop0: addq $0,$25,$28 # cy add
+ ldq $0,8($18)
+ addq $4,$28,$20 # main add
+ ldq $4,8($17)
+ addq $18,8,$18
+ cmpult $28,$25,$8 # compute cy from last add
+ addq $17,8,$17
+ stq $20,0($16)
+ cmpult $20,$28,$25 # compute cy from last add
+ subq $19,1,$19 # decr loop cnt
+ or $8,$25,$25 # combine cy from the two adds
+ addq $16,8,$16
+ bne $19,.Loop0
+.Lend0: addq $0,$25,$28 # cy add
+ addq $4,$28,$20 # main add
+ cmpult $28,$25,$8 # compute cy from last add
+ cmpult $20,$28,$25 # compute cy from last add
+ stq $20,0($16)
+ or $8,$25,$25 # combine cy from the two adds
+
+.Lret: or $25,$31,$0 # return cy
+ ret $31,($26),1
+ .end __mpn_add_n
diff --git a/libc/sysdeps/alpha/alphaev5/lshift.s b/libc/sysdeps/alpha/alphaev5/lshift.s
new file mode 100644
index 000000000..e41ce9a91
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev5/lshift.s
@@ -0,0 +1,174 @@
+ # Alpha EV5 __mpn_lshift --
+
+ # Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+ # This file is part of the GNU MP Library.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published by
+ # the Free Software Foundation; either version 2.1 of the License, or (at your
+ # option) any later version.
+
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+
+ # INPUT PARAMETERS
+ # res_ptr r16
+ # s1_ptr r17
+ # size r18
+ # cnt r19
+
+ # This code runs at 3.25 cycles/limb on the EV5.
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __mpn_lshift
+ .ent __mpn_lshift
+__mpn_lshift:
+ .frame $30,0,$26,0
+
+ s8addq $18,$17,$17 # make r17 point at end of s1
+ ldq $4,-8($17) # load first limb
+ subq $31,$19,$20
+ s8addq $18,$16,$16 # make r16 point at end of RES
+ subq $18,1,$18
+ and $18,4-1,$28 # number of limbs in first loop
+ srl $4,$20,$0 # compute function result
+
+ beq $28,.L0
+ subq $18,$28,$18
+
+ .align 3
+.Loop0: ldq $3,-16($17)
+ subq $16,8,$16
+ sll $4,$19,$5
+ subq $17,8,$17
+ subq $28,1,$28
+ srl $3,$20,$6
+ or $3,$3,$4
+ or $5,$6,$8
+ stq $8,0($16)
+ bne $28,.Loop0
+
+.L0: sll $4,$19,$24
+ beq $18,.Lend
+ # warm up phase 1
+ ldq $1,-16($17)
+ subq $18,4,$18
+ ldq $2,-24($17)
+ ldq $3,-32($17)
+ ldq $4,-40($17)
+ beq $18,.Lend1
+ # warm up phase 2
+ srl $1,$20,$7
+ sll $1,$19,$21
+ srl $2,$20,$8
+ ldq $1,-48($17)
+ sll $2,$19,$22
+ ldq $2,-56($17)
+ srl $3,$20,$5
+ or $7,$24,$7
+ sll $3,$19,$23
+ or $8,$21,$8
+ srl $4,$20,$6
+ ldq $3,-64($17)
+ sll $4,$19,$24
+ ldq $4,-72($17)
+ subq $18,4,$18
+ beq $18,.Lend2
+ .align 4
+ # main loop
+.Loop: stq $7,-8($16)
+ or $5,$22,$5
+ stq $8,-16($16)
+ or $6,$23,$6
+
+ srl $1,$20,$7
+ subq $18,4,$18
+ sll $1,$19,$21
+ unop # ldq $31,-96($17)
+
+ srl $2,$20,$8
+ ldq $1,-80($17)
+ sll $2,$19,$22
+ ldq $2,-88($17)
+
+ stq $5,-24($16)
+ or $7,$24,$7
+ stq $6,-32($16)
+ or $8,$21,$8
+
+ srl $3,$20,$5
+ unop # ldq $31,-96($17)
+ sll $3,$19,$23
+ subq $16,32,$16
+
+ srl $4,$20,$6
+ ldq $3,-96($17)
+ sll $4,$19,$24
+ ldq $4,-104($17)
+
+ subq $17,32,$17
+ bne $18,.Loop
+ # cool down phase 2/1
+.Lend2: stq $7,-8($16)
+ or $5,$22,$5
+ stq $8,-16($16)
+ or $6,$23,$6
+ srl $1,$20,$7
+ sll $1,$19,$21
+ srl $2,$20,$8
+ sll $2,$19,$22
+ stq $5,-24($16)
+ or $7,$24,$7
+ stq $6,-32($16)
+ or $8,$21,$8
+ srl $3,$20,$5
+ sll $3,$19,$23
+ srl $4,$20,$6
+ sll $4,$19,$24
+ # cool down phase 2/2
+ stq $7,-40($16)
+ or $5,$22,$5
+ stq $8,-48($16)
+ or $6,$23,$6
+ stq $5,-56($16)
+ stq $6,-64($16)
+ # cool down phase 2/3
+ stq $24,-72($16)
+ ret $31,($26),1
+
+ # cool down phase 1/1
+.Lend1: srl $1,$20,$7
+ sll $1,$19,$21
+ srl $2,$20,$8
+ sll $2,$19,$22
+ srl $3,$20,$5
+ or $7,$24,$7
+ sll $3,$19,$23
+ or $8,$21,$8
+ srl $4,$20,$6
+ sll $4,$19,$24
+ # cool down phase 1/2
+ stq $7,-8($16)
+ or $5,$22,$5
+ stq $8,-16($16)
+ or $6,$23,$6
+ stq $5,-24($16)
+ stq $6,-32($16)
+ stq $24,-40($16)
+ ret $31,($26),1
+
+.Lend: stq $24,-8($16)
+ ret $31,($26),1
+ .end __mpn_lshift
diff --git a/libc/sysdeps/alpha/alphaev5/rshift.s b/libc/sysdeps/alpha/alphaev5/rshift.s
new file mode 100644
index 000000000..9948e5000
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev5/rshift.s
@@ -0,0 +1,172 @@
+ # Alpha EV5 __mpn_rshift --
+
+ # Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+ # This file is part of the GNU MP Library.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published by
+ # the Free Software Foundation; either version 2.1 of the License, or (at your
+ # option) any later version.
+
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+
+ # INPUT PARAMETERS
+ # res_ptr r16
+ # s1_ptr r17
+ # size r18
+ # cnt r19
+
+ # This code runs at 3.25 cycles/limb on the EV5.
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __mpn_rshift
+ .ent __mpn_rshift
+__mpn_rshift:
+ .frame $30,0,$26,0
+
+ ldq $4,0($17) # load first limb
+ subq $31,$19,$20
+ subq $18,1,$18
+ and $18,4-1,$28 # number of limbs in first loop
+ sll $4,$20,$0 # compute function result
+
+ beq $28,.L0
+ subq $18,$28,$18
+
+ .align 3
+.Loop0: ldq $3,8($17)
+ addq $16,8,$16
+ srl $4,$19,$5
+ addq $17,8,$17
+ subq $28,1,$28
+ sll $3,$20,$6
+ or $3,$3,$4
+ or $5,$6,$8
+ stq $8,-8($16)
+ bne $28,.Loop0
+
+.L0: srl $4,$19,$24
+ beq $18,.Lend
+ # warm up phase 1
+ ldq $1,8($17)
+ subq $18,4,$18
+ ldq $2,16($17)
+ ldq $3,24($17)
+ ldq $4,32($17)
+ beq $18,.Lend1
+ # warm up phase 2
+ sll $1,$20,$7
+ srl $1,$19,$21
+ sll $2,$20,$8
+ ldq $1,40($17)
+ srl $2,$19,$22
+ ldq $2,48($17)
+ sll $3,$20,$5
+ or $7,$24,$7
+ srl $3,$19,$23
+ or $8,$21,$8
+ sll $4,$20,$6
+ ldq $3,56($17)
+ srl $4,$19,$24
+ ldq $4,64($17)
+ subq $18,4,$18
+ beq $18,.Lend2
+ .align 4
+ # main loop
+.Loop: stq $7,0($16)
+ or $5,$22,$5
+ stq $8,8($16)
+ or $6,$23,$6
+
+ sll $1,$20,$7
+ subq $18,4,$18
+ srl $1,$19,$21
+ unop # ldq $31,-96($17)
+
+ sll $2,$20,$8
+ ldq $1,72($17)
+ srl $2,$19,$22
+ ldq $2,80($17)
+
+ stq $5,16($16)
+ or $7,$24,$7
+ stq $6,24($16)
+ or $8,$21,$8
+
+ sll $3,$20,$5
+ unop # ldq $31,-96($17)
+ srl $3,$19,$23
+ addq $16,32,$16
+
+ sll $4,$20,$6
+ ldq $3,88($17)
+ srl $4,$19,$24
+ ldq $4,96($17)
+
+ addq $17,32,$17
+ bne $18,.Loop
+ # cool down phase 2/1
+.Lend2: stq $7,0($16)
+ or $5,$22,$5
+ stq $8,8($16)
+ or $6,$23,$6
+ sll $1,$20,$7
+ srl $1,$19,$21
+ sll $2,$20,$8
+ srl $2,$19,$22
+ stq $5,16($16)
+ or $7,$24,$7
+ stq $6,24($16)
+ or $8,$21,$8
+ sll $3,$20,$5
+ srl $3,$19,$23
+ sll $4,$20,$6
+ srl $4,$19,$24
+ # cool down phase 2/2
+ stq $7,32($16)
+ or $5,$22,$5
+ stq $8,40($16)
+ or $6,$23,$6
+ stq $5,48($16)
+ stq $6,56($16)
+ # cool down phase 2/3
+ stq $24,64($16)
+ ret $31,($26),1
+
+ # cool down phase 1/1
+.Lend1: sll $1,$20,$7
+ srl $1,$19,$21
+ sll $2,$20,$8
+ srl $2,$19,$22
+ sll $3,$20,$5
+ or $7,$24,$7
+ srl $3,$19,$23
+ or $8,$21,$8
+ sll $4,$20,$6
+ srl $4,$19,$24
+ # cool down phase 1/2
+ stq $7,0($16)
+ or $5,$22,$5
+ stq $8,8($16)
+ or $6,$23,$6
+ stq $5,16($16)
+ stq $6,24($16)
+ stq $24,32($16)
+ ret $31,($26),1
+
+.Lend: stq $24,0($16)
+ ret $31,($26),1
+ .end __mpn_rshift
diff --git a/libc/sysdeps/alpha/alphaev5/sub_n.s b/libc/sysdeps/alpha/alphaev5/sub_n.s
new file mode 100644
index 000000000..3c706cf23
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev5/sub_n.s
@@ -0,0 +1,149 @@
+ # Alpha __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+ # store difference in a third limb vector.
+
+ # Copyright (C) 1995 Free Software Foundation, Inc.
+
+ # This file is part of the GNU MP Library.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published by
+ # the Free Software Foundation; either version 2.1 of the License, or (at your
+ # option) any later version.
+
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+
+ # INPUT PARAMETERS
+ # res_ptr $16
+ # s1_ptr $17
+ # s2_ptr $18
+ # size $19
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __mpn_sub_n
+ .ent __mpn_sub_n
+__mpn_sub_n:
+ .frame $30,0,$26,0
+
+ or $31,$31,$25 # clear cy
+ subq $19,4,$19 # decr loop cnt
+ blt $19,.Lend2 # if less than 4 limbs, goto 2nd loop
+ # Start software pipeline for 1st loop
+ ldq $0,0($18)
+ ldq $1,8($18)
+ ldq $4,0($17)
+ ldq $5,8($17)
+ addq $17,32,$17 # update s1_ptr
+ ldq $2,16($18)
+ subq $4,$0,$20 # 1st main sub
+ ldq $3,24($18)
+ subq $19,4,$19 # decr loop cnt
+ ldq $6,-16($17)
+ cmpult $4,$20,$25 # compute cy from last sub
+ ldq $7,-8($17)
+ addq $1,$25,$28 # cy add
+ addq $18,32,$18 # update s2_ptr
+ subq $5,$28,$21 # 2nd main sub
+ cmpult $28,$25,$8 # compute cy from last add
+ blt $19,.Lend1 # if less than 4 limbs remain, jump
+ # 1st loop handles groups of 4 limbs in a software pipeline
+ .align 4
+.Loop: cmpult $5,$21,$25 # compute cy from last add
+ ldq $0,0($18)
+ or $8,$25,$25 # combine cy from the two adds
+ ldq $1,8($18)
+ addq $2,$25,$28 # cy add
+ ldq $4,0($17)
+ subq $6,$28,$22 # 3rd main sub
+ ldq $5,8($17)
+ cmpult $28,$25,$8 # compute cy from last add
+ cmpult $6,$22,$25 # compute cy from last add
+ stq $20,0($16)
+ or $8,$25,$25 # combine cy from the two adds
+ stq $21,8($16)
+ addq $3,$25,$28 # cy add
+ subq $7,$28,$23 # 4th main sub
+ cmpult $28,$25,$8 # compute cy from last add
+ cmpult $7,$23,$25 # compute cy from last add
+ addq $17,32,$17 # update s1_ptr
+ or $8,$25,$25 # combine cy from the two adds
+ addq $16,32,$16 # update res_ptr
+ addq $0,$25,$28 # cy add
+ ldq $2,16($18)
+ subq $4,$28,$20 # 1st main sub
+ ldq $3,24($18)
+ cmpult $28,$25,$8 # compute cy from last add
+ ldq $6,-16($17)
+ cmpult $4,$20,$25 # compute cy from last add
+ ldq $7,-8($17)
+ or $8,$25,$25 # combine cy from the two adds
+ subq $19,4,$19 # decr loop cnt
+ stq $22,-16($16)
+ addq $1,$25,$28 # cy add
+ stq $23,-8($16)
+ subq $5,$28,$21 # 2nd main sub
+ addq $18,32,$18 # update s2_ptr
+ cmpult $28,$25,$8 # compute cy from last add
+ bge $19,.Loop
+ # Finish software pipeline for 1st loop
+.Lend1: cmpult $5,$21,$25 # compute cy from last add
+ or $8,$25,$25 # combine cy from the two adds
+ addq $2,$25,$28 # cy add
+ subq $6,$28,$22 # 3rd main sub
+ cmpult $28,$25,$8 # compute cy from last add
+ cmpult $6,$22,$25 # compute cy from last add
+ stq $20,0($16)
+ or $8,$25,$25 # combine cy from the two adds
+ stq $21,8($16)
+ addq $3,$25,$28 # cy add
+ subq $7,$28,$23 # 4th main sub
+ cmpult $28,$25,$8 # compute cy from last add
+ cmpult $7,$23,$25 # compute cy from last add
+ or $8,$25,$25 # combine cy from the two adds
+ addq $16,32,$16 # update res_ptr
+ stq $22,-16($16)
+ stq $23,-8($16)
+.Lend2: addq $19,4,$19 # restore loop cnt
+ beq $19,.Lret
+ # Start software pipeline for 2nd loop
+ ldq $0,0($18)
+ ldq $4,0($17)
+ subq $19,1,$19
+ beq $19,.Lend0
+ # 2nd loop handles remaining 1-3 limbs
+ .align 4
+.Loop0: addq $0,$25,$28 # cy add
+ ldq $0,8($18)
+ subq $4,$28,$20 # main sub
+ ldq $1,8($17)
+ addq $18,8,$18
+ cmpult $28,$25,$8 # compute cy from last add
+ addq $17,8,$17
+ stq $20,0($16)
+ cmpult $4,$20,$25 # compute cy from last add
+ subq $19,1,$19 # decr loop cnt
+ or $8,$25,$25 # combine cy from the two adds
+ addq $16,8,$16
+ or $1,$31,$4
+ bne $19,.Loop0
+.Lend0: addq $0,$25,$28 # cy add
+ subq $4,$28,$20 # main sub
+ cmpult $28,$25,$8 # compute cy from last add
+ cmpult $4,$20,$25 # compute cy from last add
+ stq $20,0($16)
+ or $8,$25,$25 # combine cy from the two adds
+
+.Lret: or $25,$31,$0 # return cy
+ ret $31,($26),1
+ .end __mpn_sub_n
diff --git a/libc/sysdeps/alpha/alphaev6/Implies b/libc/sysdeps/alpha/alphaev6/Implies
new file mode 100644
index 000000000..0e7fc170b
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev6/Implies
@@ -0,0 +1 @@
+alpha/alphaev5
diff --git a/libc/sysdeps/alpha/alphaev6/addmul_1.s b/libc/sysdeps/alpha/alphaev6/addmul_1.s
new file mode 100644
index 000000000..a061fb9ed
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev6/addmul_1.s
@@ -0,0 +1,479 @@
+ # Alpha ev6 mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ # the result to a second limb vector.
+ #
+ # Copyright (C) 2000 Free Software Foundation, Inc.
+ #
+ # This file is part of the GNU MP Library.
+ #
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published
+ # by the Free Software Foundation; either version 2.1 of the License, or (at
+ # your option) any later version.
+ #
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+ #
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+ # INPUT PARAMETERS
+ # res_ptr $16
+ # s1_ptr $17
+ # size $18
+ # s2_limb $19
+ #
+ # This code runs at 42 cycles/limb on EV4, 18 cycles/limb on EV5, and
+ # exactly 3.625 cycles/limb on EV6...
+ #
+ # This code was written in close cooperation with ev6 pipeline expert
+ # Steve Root (root@toober.hlo.dec.com). Any errors are tege's fault, though.
+ #
+ # Register usages for unrolled loop:
+ # 0-3 mul's
+ # 4-7 acc's
+ # 8-15 mul results
+ # 20,21 carry's
+ # 22,23 save for stores
+ #
+ # Sustains 8 mul-adds in 29 cycles in the unrolled inner loop.
+ #
+ # The stores can issue a cycle late so we have paired no-op's to 'catch'
+ # them, so that further disturbance to the schedule is damped.
+ #
+ # We couldn't pair the loads, because the entangled schedule of the
+ # carry's has to happen on one side {0} of the machine. Note, the total
+ # use of U0, and the total use of L0 (after attending to the stores).
+ # which is part of the reason why....
+ #
+ # This is a great schedule for the d_cache, a poor schedule for the
+ # b_cache. The lockup on U0 means that any stall can't be recovered
+ # from. Consider a ldq in L1. say that load gets stalled because it
+ # collides with a fill from the b_Cache. On the next cycle, this load
+ # gets priority. If first looks at L0, and goes there. The instruction
+ # we intended for L0 gets to look at L1, which is NOT where we want
+ # it. It either stalls 1, because it can't go in L0, or goes there, and
+ # causes a further instruction to stall.
+ #
+ # So for b_cache, we're likely going to want to put one or more cycles
+ # back into the code! And, of course, put in prefetches. For the
+ # accumulator, lds, intent to modify. For the multiplier, you might
+ # want ldq, evict next, if you're not wanting to use it again soon. Use
+ # 256 ahead of present pointer value. At a place where we have an mt
+ # followed by a bookkeeping, put the bookkeeping in upper, and the
+ # prefetch into lower.
+ #
+ # Note, the usage of physical registers per cycle is smoothed off, as
+ # much as possible.
+ #
+ # Note, the ldq's and stq's are at the end of the quadpacks. note, we'd
+ # like not to have a ldq or stq to preceded a conditional branch in a
+ # quadpack. The conditional branch moves the retire pointer one cycle
+ # later.
+ #
+ # Optimization notes:
+ # Callee-saves regs: $9 $10 $11 $12 $13 $14 $15 $26 ?$27?
+ # Reserved regs: $29 $30 $31
+ # Free caller-saves regs in unrolled code: $24 $25 $28
+ # We should swap some of the callee-saves regs for some of the free
+ # caller-saves regs, saving some overhead cycles.
+ # Most importantly, we should write fast code for the 0-7 case.
+ # The code we use there are for the 21164, and runs at 7 cycles/limb
+ # on the 21264. Should not be hard, if we write specialized code for
+ # 1-7 limbs (the one for 0 limbs should be straightforward). We then just
+ # need a jump table indexed by the low 3 bits of the count argument.
+
+ .set noreorder
+ .set noat
+ .text
+
+ .globl __mpn_addmul_1
+ .ent __mpn_addmul_1
+__mpn_addmul_1:
+ .frame $30,0,$26,0
+ .prologue 0
+
+ cmpult $18, 8, $1
+ beq $1, $Large
+
+ ldq $2, 0($17) # $2 = s1_limb
+ addq $17, 8, $17 # s1_ptr++
+ subq $18, 1, $18 # size--
+ mulq $2, $19, $3 # $3 = prod_low
+ ldq $5, 0($16) # $5 = *res_ptr
+ umulh $2, $19, $0 # $0 = prod_high
+ beq $18, $Lend0b # jump if size was == 1
+ ldq $2, 0($17) # $2 = s1_limb
+ addq $17, 8, $17 # s1_ptr++
+ subq $18, 1, $18 # size--
+ addq $5, $3, $3
+ cmpult $3, $5, $4
+ stq $3, 0($16)
+ addq $16, 8, $16 # res_ptr++
+ beq $18, $Lend0a # jump if size was == 2
+
+ .align 3
+$Loop0: mulq $2, $19, $3 # $3 = prod_low
+ ldq $5, 0($16) # $5 = *res_ptr
+ addq $4, $0, $0 # cy_limb = cy_limb + 'cy'
+ subq $18, 1, $18 # size--
+ umulh $2, $19, $4 # $4 = cy_limb
+ ldq $2, 0($17) # $2 = s1_limb
+ addq $17, 8, $17 # s1_ptr++
+ addq $3, $0, $3 # $3 = cy_limb + prod_low
+ cmpult $3, $0, $0 # $0 = carry from (cy_limb + prod_low)
+ addq $5, $3, $3
+ cmpult $3, $5, $5
+ stq $3, 0($16)
+ addq $16, 8, $16 # res_ptr++
+ addq $5, $0, $0 # combine carries
+ bne $18, $Loop0
+$Lend0a:
+ mulq $2, $19, $3 # $3 = prod_low
+ ldq $5, 0($16) # $5 = *res_ptr
+ addq $4, $0, $0 # cy_limb = cy_limb + 'cy'
+ umulh $2, $19, $4 # $4 = cy_limb
+ addq $3, $0, $3 # $3 = cy_limb + prod_low
+ cmpult $3, $0, $0 # $0 = carry from (cy_limb + prod_low)
+ addq $5, $3, $3
+ cmpult $3, $5, $5
+ stq $3, 0($16)
+ addq $5, $0, $0 # combine carries
+ addq $4, $0, $0 # cy_limb = prod_high + cy
+ ret $31, ($26), 1
+$Lend0b:
+ addq $5, $3, $3
+ cmpult $3, $5, $5
+ stq $3, 0($16)
+ addq $0, $5, $0
+ ret $31, ($26), 1
+
+$Large:
+ lda $30, -240($30)
+ stq $9, 8($30)
+ stq $10, 16($30)
+ stq $11, 24($30)
+ stq $12, 32($30)
+ stq $13, 40($30)
+ stq $14, 48($30)
+ stq $15, 56($30)
+
+ and $18, 7, $20 # count for the first loop, 0-7
+ srl $18, 3, $18 # count for unrolled loop
+ bis $31, $31, $0
+ beq $20, $Lunroll
+ ldq $2, 0($17) # $2 = s1_limb
+ addq $17, 8, $17 # s1_ptr++
+ subq $20, 1, $20 # size--
+ mulq $2, $19, $3 # $3 = prod_low
+ ldq $5, 0($16) # $5 = *res_ptr
+ umulh $2, $19, $0 # $0 = prod_high
+ beq $20, $Lend1b # jump if size was == 1
+ ldq $2, 0($17) # $2 = s1_limb
+ addq $17, 8, $17 # s1_ptr++
+ subq $20, 1, $20 # size--
+ addq $5, $3, $3
+ cmpult $3, $5, $4
+ stq $3, 0($16)
+ addq $16, 8, $16 # res_ptr++
+ beq $20, $Lend1a # jump if size was == 2
+
+ .align 3
+$Loop1: mulq $2, $19, $3 # $3 = prod_low
+ ldq $5, 0($16) # $5 = *res_ptr
+ addq $4, $0, $0 # cy_limb = cy_limb + 'cy'
+ subq $20, 1, $20 # size--
+ umulh $2, $19, $4 # $4 = cy_limb
+ ldq $2, 0($17) # $2 = s1_limb
+ addq $17, 8, $17 # s1_ptr++
+ addq $3, $0, $3 # $3 = cy_limb + prod_low
+ cmpult $3, $0, $0 # $0 = carry from (cy_limb + prod_low)
+ addq $5, $3, $3
+ cmpult $3, $5, $5
+ stq $3, 0($16)
+ addq $16, 8, $16 # res_ptr++
+ addq $5, $0, $0 # combine carries
+ bne $20, $Loop1
+
+$Lend1a:
+ mulq $2, $19, $3 # $3 = prod_low
+ ldq $5, 0($16) # $5 = *res_ptr
+ addq $4, $0, $0 # cy_limb = cy_limb + 'cy'
+ umulh $2, $19, $4 # $4 = cy_limb
+ addq $3, $0, $3 # $3 = cy_limb + prod_low
+ cmpult $3, $0, $0 # $0 = carry from (cy_limb + prod_low)
+ addq $5, $3, $3
+ cmpult $3, $5, $5
+ stq $3, 0($16)
+ addq $16, 8, $16 # res_ptr++
+ addq $5, $0, $0 # combine carries
+ addq $4, $0, $0 # cy_limb = prod_high + cy
+ br $31, $Lunroll
+$Lend1b:
+ addq $5, $3, $3
+ cmpult $3, $5, $5
+ stq $3, 0($16)
+ addq $16, 8, $16 # res_ptr++
+ addq $0, $5, $0
+
+$Lunroll:
+ lda $17, -16($17) # L1 bookkeeping
+ lda $16, -16($16) # L1 bookkeeping
+ bis $0, $31, $12
+
+ # ____ UNROLLED LOOP SOFTWARE PIPELINE STARTUP ____
+
+ ldq $2, 16($17) # L1
+ ldq $3, 24($17) # L1
+ lda $18, -1($18) # L1 bookkeeping
+ ldq $6, 16($16) # L1
+ ldq $7, 24($16) # L1
+ ldq $0, 32($17) # L1
+ mulq $19, $2, $13 # U1
+ ldq $1, 40($17) # L1
+ umulh $19, $2, $14 # U1
+ mulq $19, $3, $15 # U1
+ lda $17, 64($17) # L1 bookkeeping
+ ldq $4, 32($16) # L1
+ ldq $5, 40($16) # L1
+ umulh $19, $3, $8 # U1
+ ldq $2, -16($17) # L1
+ mulq $19, $0, $9 # U1
+ ldq $3, -8($17) # L1
+ umulh $19, $0, $10 # U1
+ addq $6, $13, $6 # L0 lo + acc
+ mulq $19, $1, $11 # U1
+ cmpult $6, $13, $20 # L0 lo add => carry
+ lda $16, 64($16) # L1 bookkeeping
+ addq $6, $12, $22 # U0 hi add => answer
+ cmpult $22, $12, $21 # L0 hi add => carry
+ addq $14, $20, $14 # U0 hi mul + carry
+ ldq $6, -16($16) # L1
+ addq $7, $15, $23 # L0 lo + acc
+ addq $14, $21, $14 # U0 hi mul + carry
+ ldq $7, -8($16) # L1
+ umulh $19, $1, $12 # U1
+ cmpult $23, $15, $20 # L0 lo add => carry
+ addq $23, $14, $23 # U0 hi add => answer
+ ldq $0, 0($17) # L1
+ mulq $19, $2, $13 # U1
+ cmpult $23, $14, $21 # L0 hi add => carry
+ addq $8, $20, $8 # U0 hi mul + carry
+ ldq $1, 8($17) # L1
+ umulh $19, $2, $14 # U1
+ addq $4, $9, $4 # L0 lo + acc
+ stq $22, -48($16) # L0
+ stq $23, -40($16) # L1
+ mulq $19, $3, $15 # U1
+ addq $8, $21, $8 # U0 hi mul + carry
+ cmpult $4, $9, $20 # L0 lo add => carry
+ addq $4, $8, $22 # U0 hi add => answer
+ ble $18, $Lend # U1 bookkeeping
+
+ # ____ MAIN UNROLLED LOOP ____
+ .align 4
+$Loop:
+ bis $31, $31, $31 # U1 mt
+ cmpult $22, $8, $21 # L0 hi add => carry
+ addq $10, $20, $10 # U0 hi mul + carry
+ ldq $4, 0($16) # L1
+
+ bis $31, $31, $31 # U1 mt
+ addq $5, $11, $23 # L0 lo + acc
+ addq $10, $21, $10 # L0 hi mul + carry
+ ldq $5, 8($16) # L1
+
+ umulh $19, $3, $8 # U1
+ cmpult $23, $11, $20 # L0 lo add => carry
+ addq $23, $10, $23 # U0 hi add => answer
+ ldq $2, 16($17) # L1
+
+ mulq $19, $0, $9 # U1
+ cmpult $23, $10, $21 # L0 hi add => carry
+ addq $12, $20, $12 # U0 hi mul + carry
+ ldq $3, 24($17) # L1
+
+ umulh $19, $0, $10 # U1
+ addq $6, $13, $6 # L0 lo + acc
+ stq $22, -32($16) # L0
+ stq $23, -24($16) # L1
+
+ bis $31, $31, $31 # L0 st slosh
+ mulq $19, $1, $11 # U1
+ bis $31, $31, $31 # L1 st slosh
+ addq $12, $21, $12 # U0 hi mul + carry
+
+ cmpult $6, $13, $20 # L0 lo add => carry
+ bis $31, $31, $31 # U1 mt
+ lda $18, -1($18) # L1 bookkeeping
+ addq $6, $12, $22 # U0 hi add => answer
+
+ bis $31, $31, $31 # U1 mt
+ cmpult $22, $12, $21 # L0 hi add => carry
+ addq $14, $20, $14 # U0 hi mul + carry
+ ldq $6, 16($16) # L1
+
+ bis $31, $31, $31 # U1 mt
+ addq $7, $15, $23 # L0 lo + acc
+ addq $14, $21, $14 # U0 hi mul + carry
+ ldq $7, 24($16) # L1
+
+ umulh $19, $1, $12 # U1
+ cmpult $23, $15, $20 # L0 lo add => carry
+ addq $23, $14, $23 # U0 hi add => answer
+ ldq $0, 32($17) # L1
+
+ mulq $19, $2, $13 # U1
+ cmpult $23, $14, $21 # L0 hi add => carry
+ addq $8, $20, $8 # U0 hi mul + carry
+ ldq $1, 40($17) # L1
+
+ umulh $19, $2, $14 # U1
+ addq $4, $9, $4 # U0 lo + acc
+ stq $22, -16($16) # L0
+ stq $23, -8($16) # L1
+
+ bis $31, $31, $31 # L0 st slosh
+ mulq $19, $3, $15 # U1
+ bis $31, $31, $31 # L1 st slosh
+ addq $8, $21, $8 # L0 hi mul + carry
+
+ cmpult $4, $9, $20 # L0 lo add => carry
+ bis $31, $31, $31 # U1 mt
+ lda $17, 64($17) # L1 bookkeeping
+ addq $4, $8, $22 # U0 hi add => answer
+
+ bis $31, $31, $31 # U1 mt
+ cmpult $22, $8, $21 # L0 hi add => carry
+ addq $10, $20, $10 # U0 hi mul + carry
+ ldq $4, 32($16) # L1
+
+ bis $31, $31, $31 # U1 mt
+ addq $5, $11, $23 # L0 lo + acc
+ addq $10, $21, $10 # L0 hi mul + carry
+ ldq $5, 40($16) # L1
+
+ umulh $19, $3, $8 # U1
+ cmpult $23, $11, $20 # L0 lo add => carry
+ addq $23, $10, $23 # U0 hi add => answer
+ ldq $2, -16($17) # L1
+
+ mulq $19, $0, $9 # U1
+ cmpult $23, $10, $21 # L0 hi add => carry
+ addq $12, $20, $12 # U0 hi mul + carry
+ ldq $3, -8($17) # L1
+
+ umulh $19, $0, $10 # U1
+ addq $6, $13, $6 # L0 lo + acc
+ stq $22, 0($16) # L0
+ stq $23, 8($16) # L1
+
+ bis $31, $31, $31 # L0 st slosh
+ mulq $19, $1, $11 # U1
+ bis $31, $31, $31 # L1 st slosh
+ addq $12, $21, $12 # U0 hi mul + carry
+
+ cmpult $6, $13, $20 # L0 lo add => carry
+ bis $31, $31, $31 # U1 mt
+ lda $16, 64($16) # L1 bookkeeping
+ addq $6, $12, $22 # U0 hi add => answer
+
+ bis $31, $31, $31 # U1 mt
+ cmpult $22, $12, $21 # L0 hi add => carry
+ addq $14, $20, $14 # U0 hi mul + carry
+ ldq $6, -16($16) # L1
+
+ bis $31, $31, $31 # U1 mt
+ addq $7, $15, $23 # L0 lo + acc
+ addq $14, $21, $14 # U0 hi mul + carry
+ ldq $7, -8($16) # L1
+
+ umulh $19, $1, $12 # U1
+ cmpult $23, $15, $20 # L0 lo add => carry
+ addq $23, $14, $23 # U0 hi add => answer
+ ldq $0, 0($17) # L1
+
+ mulq $19, $2, $13 # U1
+ cmpult $23, $14, $21 # L0 hi add => carry
+ addq $8, $20, $8 # U0 hi mul + carry
+ ldq $1, 8($17) # L1
+
+ umulh $19, $2, $14 # U1
+ addq $4, $9, $4 # L0 lo + acc
+ stq $22, -48($16) # L0
+ stq $23, -40($16) # L1
+
+ bis $31, $31, $31 # L0 st slosh
+ mulq $19, $3, $15 # U1
+ bis $31, $31, $31 # L1 st slosh
+ addq $8, $21, $8 # U0 hi mul + carry
+
+ cmpult $4, $9, $20 # L0 lo add => carry
+ addq $4, $8, $22 # U0 hi add => answer
+ bis $31, $31, $31 # L1 mt
+ bgt $18, $Loop # U1 bookkeeping
+
+# ____ UNROLLED LOOP SOFTWARE PIPELINE FINISH ____
+$Lend:
+ cmpult $22, $8, $21 # L0 hi add => carry
+ addq $10, $20, $10 # U0 hi mul + carry
+ ldq $4, 0($16) # L1
+ addq $5, $11, $23 # L0 lo + acc
+ addq $10, $21, $10 # L0 hi mul + carry
+ ldq $5, 8($16) # L1
+ umulh $19, $3, $8 # U1
+ cmpult $23, $11, $20 # L0 lo add => carry
+ addq $23, $10, $23 # U0 hi add => answer
+ mulq $19, $0, $9 # U1
+ cmpult $23, $10, $21 # L0 hi add => carry
+ addq $12, $20, $12 # U0 hi mul + carry
+ umulh $19, $0, $10 # U1
+ addq $6, $13, $6 # L0 lo + acc
+ stq $22, -32($16) # L0
+ stq $23, -24($16) # L1
+ mulq $19, $1, $11 # U1
+ addq $12, $21, $12 # U0 hi mul + carry
+ cmpult $6, $13, $20 # L0 lo add => carry
+ addq $6, $12, $22 # U0 hi add => answer
+ cmpult $22, $12, $21 # L0 hi add => carry
+ addq $14, $20, $14 # U0 hi mul + carry
+ addq $7, $15, $23 # L0 lo + acc
+ addq $14, $21, $14 # U0 hi mul + carry
+ umulh $19, $1, $12 # U1
+ cmpult $23, $15, $20 # L0 lo add => carry
+ addq $23, $14, $23 # U0 hi add => answer
+ cmpult $23, $14, $21 # L0 hi add => carry
+ addq $8, $20, $8 # U0 hi mul + carry
+ addq $4, $9, $4 # U0 lo + acc
+ stq $22, -16($16) # L0
+ stq $23, -8($16) # L1
+ bis $31, $31, $31 # L0 st slosh
+ addq $8, $21, $8 # L0 hi mul + carry
+ cmpult $4, $9, $20 # L0 lo add => carry
+ addq $4, $8, $22 # U0 hi add => answer
+ cmpult $22, $8, $21 # L0 hi add => carry
+ addq $10, $20, $10 # U0 hi mul + carry
+ addq $5, $11, $23 # L0 lo + acc
+ addq $10, $21, $10 # L0 hi mul + carry
+ cmpult $23, $11, $20 # L0 lo add => carry
+ addq $23, $10, $23 # U0 hi add => answer
+ cmpult $23, $10, $21 # L0 hi add => carry
+ addq $12, $20, $12 # U0 hi mul + carry
+ stq $22, 0($16) # L0
+ stq $23, 8($16) # L1
+ addq $12, $21, $0 # U0 hi mul + carry
+
+ ldq $9, 8($30)
+ ldq $10, 16($30)
+ ldq $11, 24($30)
+ ldq $12, 32($30)
+ ldq $13, 40($30)
+ ldq $14, 48($30)
+ ldq $15, 56($30)
+ lda $30, 240($30)
+ ret $31, ($26), 1
+
+ .end __mpn_addmul_1
diff --git a/libc/sysdeps/alpha/alphaev6/fpu/e_sqrt.S b/libc/sysdeps/alpha/alphaev6/fpu/e_sqrt.S
new file mode 100644
index 000000000..64a08826f
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev6/fpu/e_sqrt.S
@@ -0,0 +1,45 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .set noat
+
+ENTRY(__ieee754_sqrt)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ .align 4
+#ifdef _IEEE_FP_INEXACT
+ sqrtt/sui $f16, $f0
+#else
+ sqrtt/su $f16, $f0
+#endif
+ ret
+ nop
+ nop
+
+END(__ieee754_sqrt)
diff --git a/libc/sysdeps/alpha/alphaev6/fpu/e_sqrtf.S b/libc/sysdeps/alpha/alphaev6/fpu/e_sqrtf.S
new file mode 100644
index 000000000..3500e832c
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev6/fpu/e_sqrtf.S
@@ -0,0 +1,45 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .set noat
+
+ENTRY(__ieee754_sqrtf)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ .align 4
+#ifdef _IEEE_FP_INEXACT
+ sqrts/sui $f16, $f0
+#else
+ sqrts/su $f16, $f0
+#endif
+ ret
+ nop
+ nop
+
+END(__ieee754_sqrtf)
diff --git a/libc/sysdeps/alpha/alphaev6/memchr.S b/libc/sysdeps/alpha/alphaev6/memchr.S
new file mode 100644
index 000000000..88e91fa98
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev6/memchr.S
@@ -0,0 +1,193 @@
+/* Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger (davidm@cs.arizona.edu).
+ EV6 optimized by Rick Gorton <rick.gorton@alpha-processor.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .set noat
+
+ENTRY(__memchr)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ # Hack -- if someone passes in (size_t)-1, hoping to just
+ # search til the end of the address space, we will overflow
+ # below when we find the address of the last byte. Given
+ # that we will never have a 56-bit address space, cropping
+ # the length is the easiest way to avoid trouble.
+ zap $18, 0x80, $5 # U : Bound length
+ beq $18, $not_found # U :
+ ldq_u $1, 0($16) # L : load first quadword Latency=3
+ and $17, 0xff, $17 # E : L L U U : 00000000000000ch
+
+ insbl $17, 1, $2 # U : 000000000000ch00
+ cmpult $18, 9, $4 # E : small (< 1 quad) string?
+ or $2, $17, $17 # E : 000000000000chch
+ lda $3, -1($31) # E : U L L U
+
+ sll $17, 16, $2 # U : 00000000chch0000
+ addq $16, $5, $5 # E : Max search address
+ or $2, $17, $17 # E : 00000000chchchch
+ sll $17, 32, $2 # U : U L L U : chchchch00000000
+
+ or $2, $17, $17 # E : chchchchchchchch
+ extql $1, $16, $7 # U : $7 is upper bits
+ beq $4, $first_quad # U :
+ ldq_u $6, -1($5) # L : L U U L : eight or less bytes to search Latency=3
+
+ extqh $6, $16, $6 # U : 2 cycle stall for $6
+ mov $16, $0 # E :
+ nop # E :
+ or $7, $6, $1 # E : L U L U $1 = quadword starting at $16
+
+ # Deal with the case where at most 8 bytes remain to be searched
+ # in $1. E.g.:
+ # $18 = 6
+ # $1 = ????c6c5c4c3c2c1
+$last_quad:
+ negq $18, $6 # E :
+ xor $17, $1, $1 # E :
+ srl $3, $6, $6 # U : $6 = mask of $18 bits set
+ cmpbge $31, $1, $2 # E : L U L U
+
+ nop
+ nop
+ and $2, $6, $2 # E :
+ beq $2, $not_found # U : U L U L
+
+$found_it:
+#if defined(__alpha_fix__) && defined(__alpha_cix__)
+ /*
+ * Since we are guaranteed to have set one of the bits, we don't
+ * have to worry about coming back with a 0x40 out of cttz...
+ */
+ cttz $2, $3 # U0 :
+ addq $0, $3, $0 # E : All done
+ nop # E :
+ ret # L0 : L U L U
+#else
+ /*
+ * Slow and clunky. It can probably be improved.
+ * An exercise left for others.
+ */
+ negq $2, $3 # E :
+ and $2, $3, $2 # E :
+ and $2, 0x0f, $1 # E :
+ addq $0, 4, $3 # E :
+
+ cmoveq $1, $3, $0 # E : Latency 2, extra map cycle
+ nop # E : keep with cmov
+ and $2, 0x33, $1 # E :
+ addq $0, 2, $3 # E : U L U L : 2 cycle stall on $0
+
+ cmoveq $1, $3, $0 # E : Latency 2, extra map cycle
+ nop # E : keep with cmov
+ and $2, 0x55, $1 # E :
+ addq $0, 1, $3 # E : U L U L : 2 cycle stall on $0
+
+ cmoveq $1, $3, $0 # E : Latency 2, extra map cycle
+ nop
+ nop
+ ret # L0 : L U L U
+#endif
+
+ # Deal with the case where $18 > 8 bytes remain to be
+ # searched. $16 may not be aligned.
+ .align 4
+$first_quad:
+ andnot $16, 0x7, $0 # E :
+ insqh $3, $16, $2 # U : $2 = 0000ffffffffffff ($16<0:2> ff)
+ xor $1, $17, $1 # E :
+ or $1, $2, $1 # E : U L U L $1 = ====ffffffffffff
+
+ cmpbge $31, $1, $2 # E :
+ bne $2, $found_it # U :
+ # At least one byte left to process.
+ ldq $1, 8($0) # L :
+ subq $5, 1, $18 # E : U L U L
+
+ addq $0, 8, $0 # E :
+ # Make $18 point to last quad to be accessed (the
+ # last quad may or may not be partial).
+ andnot $18, 0x7, $18 # E :
+ cmpult $0, $18, $2 # E :
+ beq $2, $final # U : U L U L
+
+ # At least two quads remain to be accessed.
+
+ subq $18, $0, $4 # E : $4 <- nr quads to be processed
+ and $4, 8, $4 # E : odd number of quads?
+ bne $4, $odd_quad_count # U :
+ # At least three quads remain to be accessed
+ mov $1, $4 # E : L U L U : move prefetched value to correct reg
+
+ .align 4
+$unrolled_loop:
+ ldq $1, 8($0) # L : prefetch $1
+ xor $17, $4, $2 # E :
+ cmpbge $31, $2, $2 # E :
+ bne $2, $found_it # U : U L U L
+
+ addq $0, 8, $0 # E :
+ nop # E :
+ nop # E :
+ nop # E :
+
+$odd_quad_count:
+ xor $17, $1, $2 # E :
+ ldq $4, 8($0) # L : prefetch $4
+ cmpbge $31, $2, $2 # E :
+ addq $0, 8, $6 # E :
+
+ bne $2, $found_it # U :
+ cmpult $6, $18, $6 # E :
+ addq $0, 8, $0 # E :
+ nop # E :
+
+ bne $6, $unrolled_loop # U :
+ mov $4, $1 # E : move prefetched value into $1
+ nop # E :
+ nop # E :
+
+$final: subq $5, $0, $18 # E : $18 <- number of bytes left to do
+ nop # E :
+ nop # E :
+ bne $18, $last_quad # U :
+
+$not_found:
+ mov $31, $0 # E :
+ nop # E :
+ nop # E :
+ ret # L0 :
+
+ END(__memchr)
+
+weak_alias (__memchr, memchr)
+#if !__BOUNDED_POINTERS__
+weak_alias (__memchr, __ubp_memchr)
+#endif
+libc_hidden_builtin_def (memchr)
diff --git a/libc/sysdeps/alpha/alphaev6/memcpy.S b/libc/sysdeps/alpha/alphaev6/memcpy.S
new file mode 100644
index 000000000..7cff521da
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev6/memcpy.S
@@ -0,0 +1,256 @@
+/* Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ EV6 optimized by Rick Gorton <rick.gorton@alpha-processor.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * Much of the information about 21264 scheduling/coding comes from:
+ * Compiler Writer's Guide for the Alpha 21264
+ * abbreviated as 'CWG' in other comments here
+ * ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html
+ * Scheduling notation:
+ * E - either cluster
+ * U - upper subcluster; U0 - subcluster U0; U1 - subcluster U1
+ * L - lower subcluster; L0 - subcluster L0; L1 - subcluster L1
+ *
+ * Temp usage notes:
+ * $0 - destination address
+ * $1,$2, - scratch
+ */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .set noat
+
+ENTRY(memcpy)
+ .prologue 0
+
+ mov $16, $0 # E : copy dest to return
+ ble $18, $nomoredata # U : done with the copy?
+ xor $16, $17, $1 # E : are source and dest alignments the same?
+ and $1, 7, $1 # E : are they the same mod 8?
+
+ bne $1, $misaligned # U : Nope - gotta do this the slow way
+ /* source and dest are same mod 8 address */
+ and $16, 7, $1 # E : Are both 0mod8?
+ beq $1, $both_0mod8 # U : Yes
+ nop # E :
+
+ /*
+ * source and dest are same misalignment. move a byte at a time
+ * until a 0mod8 alignment for both is reached.
+ * At least one byte more to move
+ */
+
+$head_align:
+ ldbu $1, 0($17) # L : grab a byte
+ subq $18, 1, $18 # E : count--
+ addq $17, 1, $17 # E : src++
+ stb $1, 0($16) # L :
+ addq $16, 1, $16 # E : dest++
+ and $16, 7, $1 # E : Are we at 0mod8 yet?
+ ble $18, $nomoredata # U : done with the copy?
+ bne $1, $head_align # U :
+
+$both_0mod8:
+ cmple $18, 127, $1 # E : Can we unroll the loop?
+ bne $1, $no_unroll # U :
+ and $16, 63, $1 # E : get mod64 alignment
+ beq $1, $do_unroll # U : no single quads to fiddle
+
+$single_head_quad:
+ ldq $1, 0($17) # L : get 8 bytes
+ subq $18, 8, $18 # E : count -= 8
+ addq $17, 8, $17 # E : src += 8
+ nop # E :
+
+ stq $1, 0($16) # L : store
+ addq $16, 8, $16 # E : dest += 8
+ and $16, 63, $1 # E : get mod64 alignment
+ bne $1, $single_head_quad # U : still not fully aligned
+
+$do_unroll:
+ addq $16, 64, $7 # E : Initial (+1 trip) wh64 address
+ cmple $18, 127, $1 # E : Can we go through the unrolled loop?
+ bne $1, $tail_quads # U : Nope
+ nop # E :
+
+$unroll_body:
+ wh64 ($7) # L1 : memory subsystem hint: 64 bytes at
+ # ($7) are about to be over-written
+ ldq $6, 0($17) # L0 : bytes 0..7
+ nop # E :
+ nop # E :
+
+ ldq $4, 8($17) # L : bytes 8..15
+ ldq $5, 16($17) # L : bytes 16..23
+ addq $7, 64, $7 # E : Update next wh64 address
+ nop # E :
+
+ ldq $3, 24($17) # L : bytes 24..31
+ addq $16, 64, $1 # E : fallback value for wh64
+ nop # E :
+ nop # E :
+
+ addq $17, 32, $17 # E : src += 32 bytes
+ stq $6, 0($16) # L : bytes 0..7
+ nop # E :
+ nop # E :
+
+ stq $4, 8($16) # L : bytes 8..15
+ stq $5, 16($16) # L : bytes 16..23
+ subq $18, 192, $2 # E : At least two more trips to go?
+ nop # E :
+
+ stq $3, 24($16) # L : bytes 24..31
+ addq $16, 32, $16 # E : dest += 32 bytes
+ nop # E :
+ nop # E :
+
+ ldq $6, 0($17) # L : bytes 0..7
+ ldq $4, 8($17) # L : bytes 8..15
+ cmovlt $2, $1, $7 # E : Latency 2, extra map slot - Use
+ # fallback wh64 address if < 2 more trips
+ nop # E :
+
+ ldq $5, 16($17) # L : bytes 16..23
+ ldq $3, 24($17) # L : bytes 24..31
+ addq $16, 32, $16 # E : dest += 32
+ subq $18, 64, $18 # E : count -= 64
+
+ addq $17, 32, $17 # E : src += 32
+ stq $6, -32($16) # L : bytes 0..7
+ stq $4, -24($16) # L : bytes 8..15
+ cmple $18, 63, $1 # E : At least one more trip?
+
+ stq $5, -16($16) # L : bytes 16..23
+ stq $3, -8($16) # L : bytes 24..31
+ nop # E :
+ beq $1, $unroll_body
+
+$tail_quads:
+$no_unroll:
+ .align 4
+ subq $18, 8, $18 # E : At least a quad left?
+ blt $18, $less_than_8 # U : Nope
+ nop # E :
+ nop # E :
+
+$move_a_quad:
+ ldq $1, 0($17) # L : fetch 8
+ subq $18, 8, $18 # E : count -= 8
+ addq $17, 8, $17 # E : src += 8
+ nop # E :
+
+ stq $1, 0($16) # L : store 8
+ addq $16, 8, $16 # E : dest += 8
+ bge $18, $move_a_quad # U :
+ nop # E :
+
+$less_than_8:
+ .align 4
+ addq $18, 8, $18 # E : add back for trailing bytes
+ ble $18, $nomoredata # U : All-done
+ nop # E :
+ nop # E :
+
+ /* Trailing bytes */
+$tail_bytes:
+ subq $18, 1, $18 # E : count--
+ ldbu $1, 0($17) # L : fetch a byte
+ addq $17, 1, $17 # E : src++
+ nop # E :
+
+ stb $1, 0($16) # L : store a byte
+ addq $16, 1, $16 # E : dest++
+ bgt $18, $tail_bytes # U : more to be done?
+ nop # E :
+
+ /* branching to exit takes 3 extra cycles, so replicate exit here */
+ ret $31, ($26), 1 # L0 :
+ nop # E :
+ nop # E :
+ nop # E :
+
+$misaligned:
+ mov $0, $4 # E : dest temp
+ and $0, 7, $1 # E : dest alignment mod8
+ beq $1, $dest_0mod8 # U : life doesnt totally suck
+ nop
+
+$aligndest:
+ ble $18, $nomoredata # U :
+ ldbu $1, 0($17) # L : fetch a byte
+ subq $18, 1, $18 # E : count--
+ addq $17, 1, $17 # E : src++
+
+ stb $1, 0($4) # L : store it
+ addq $4, 1, $4 # E : dest++
+ and $4, 7, $1 # E : dest 0mod8 yet?
+ bne $1, $aligndest # U : go until we are aligned.
+
+ /* Source has unknown alignment, but dest is known to be 0mod8 */
+$dest_0mod8:
+ subq $18, 8, $18 # E : At least a quad left?
+ blt $18, $misalign_tail # U : Nope
+ ldq_u $3, 0($17) # L : seed (rotating load) of 8 bytes
+ nop # E :
+
+$mis_quad:
+ ldq_u $16, 8($17) # L : Fetch next 8
+ extql $3, $17, $3 # U : masking
+ extqh $16, $17, $1 # U : masking
+ bis $3, $1, $1 # E : merged bytes to store
+
+ subq $18, 8, $18 # E : count -= 8
+ addq $17, 8, $17 # E : src += 8
+ stq $1, 0($4) # L : store 8 (aligned)
+ mov $16, $3 # E : "rotate" source data
+
+ addq $4, 8, $4 # E : dest += 8
+ bge $18, $mis_quad # U : More quads to move
+ nop
+ nop
+
+$misalign_tail:
+ addq $18, 8, $18 # E : account for tail stuff
+ ble $18, $nomoredata # U :
+ nop
+ nop
+
+$misalign_byte:
+ ldbu $1, 0($17) # L : fetch 1
+ subq $18, 1, $18 # E : count--
+ addq $17, 1, $17 # E : src++
+ nop # E :
+
+ stb $1, 0($4) # L : store
+ addq $4, 1, $4 # E : dest++
+ bgt $18, $misalign_byte # U : more to go?
+ nop
+
+
+$nomoredata:
+ ret $31, ($26), 1 # L0 :
+ nop # E :
+ nop # E :
+ nop # E :
+
+END(memcpy)
+libc_hidden_builtin_def (memcpy)
diff --git a/libc/sysdeps/alpha/alphaev6/memset.S b/libc/sysdeps/alpha/alphaev6/memset.S
new file mode 100644
index 000000000..3b3c4ba06
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev6/memset.S
@@ -0,0 +1,224 @@
+/* Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu)
+ EV6 optimized by Rick Gorton <rick.gorton@alpha-processor.com>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noat
+ .set noreorder
+
+ENTRY(memset)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ /*
+ * Serious stalling happens. The only way to mitigate this is to
+ * undertake a major re-write to interleave the constant materialization
+ * with other parts of the fall-through code. This is important, even
+ * though it makes maintenance tougher.
+ * Do this later.
+ */
+ and $17, 255, $1 # E : 00000000000000ch
+ insbl $17, 1, $2 # U : 000000000000ch00
+ mov $16, $0 # E : return value
+ ble $18, $end # U : zero length requested?
+
+ addq $18, $16, $6 # E : max address to write to
+ or $1, $2, $17 # E : 000000000000chch
+ insbl $1, 2, $3 # U : 0000000000ch0000
+ insbl $1, 3, $4 # U : 00000000ch000000
+
+ or $3, $4, $3 # E : 00000000chch0000
+ inswl $17, 4, $5 # U : 0000chch00000000
+ xor $16, $6, $1 # E : will complete write be within one quadword?
+ inswl $17, 6, $2 # U : chch000000000000
+
+ or $17, $3, $17 # E : 00000000chchchch
+ or $2, $5, $2 # E : chchchch00000000
+ bic $1, 7, $1 # E : fit within a single quadword?
+ and $16, 7, $3 # E : Target addr misalignment
+
+ or $17, $2, $17 # E : chchchchchchchch
+ beq $1, $within_quad # U :
+ nop # E :
+ beq $3, $aligned # U : target is 0mod8
+
+ /*
+ * Target address is misaligned, and won't fit within a quadword.
+ */
+ ldq_u $4, 0($16) # L : Fetch first partial
+ mov $16, $5 # E : Save the address
+ insql $17, $16, $2 # U : Insert new bytes
+ subq $3, 8, $3 # E : Invert (for addressing uses)
+
+ addq $18, $3, $18 # E : $18 is new count ($3 is negative)
+ mskql $4, $16, $4 # U : clear relevant parts of the quad
+ subq $16, $3, $16 # E : $16 is new aligned destination
+ or $2, $4, $1 # E : Final bytes
+
+ nop
+ stq_u $1,0($5) # L : Store result
+ nop
+ nop
+
+ .align 4
+$aligned:
+ /*
+ * We are now guaranteed to be quad aligned, with at least
+ * one partial quad to write.
+ */
+
+ sra $18, 3, $3 # U : Number of remaining quads to write
+ and $18, 7, $18 # E : Number of trailing bytes to write
+ mov $16, $5 # E : Save dest address
+ beq $3, $no_quad # U : tail stuff only
+
+ /*
+ * It's worth the effort to unroll this and use wh64 if possible.
+ * At this point, entry values are:
+ * $16 Current destination address
+ * $5 A copy of $16
+ * $6 The max quadword address to write to
+ * $18 Number trailer bytes
+ * $3 Number quads to write
+ */
+
+ and $16, 0x3f, $2 # E : Forward work (only useful for unrolled loop)
+ subq $3, 16, $4 # E : Only try to unroll if > 128 bytes
+ subq $2, 0x40, $1 # E : bias counter (aligning stuff 0mod64)
+ blt $4, $loop # U :
+
+ /*
+ * We know we've got at least 16 quads, minimum of one trip
+ * through unrolled loop. Do a quad at a time to get us 0mod64
+ * aligned.
+ */
+
+ nop # E :
+ nop # E :
+ nop # E :
+ beq $1, $bigalign # U :
+
+$alignmod64:
+ stq $17, 0($5) # L :
+ subq $3, 1, $3 # E : For consistency later
+ addq $1, 8, $1 # E : Increment towards zero for alignment
+ addq $5, 8, $4 # E : Initial wh64 address (filler instruction)
+
+ nop
+ nop
+ addq $5, 8, $5 # E : Inc address
+ blt $1, $alignmod64 # U :
+
+$bigalign:
+ /*
+ * $3 - number quads left to go
+ * $5 - target address (aligned 0mod64)
+ * $17 - mask of stuff to store
+ * Scratch registers available: $7, $2, $4, $1
+ * We know that we'll be taking a minimum of one trip through.
+ * CWG Section 3.7.6: do not expect a sustained store rate of > 1/cycle
+ * Assumes the wh64 needs to be for 2 trips through the loop in the future.
+ * The wh64 is issued on for the starting destination address for trip +2
+ * through the loop, and if there are less than two trips left, the target
+ * address will be for the current trip.
+ */
+
+$do_wh64:
+ wh64 ($4) # L1 : memory subsystem write hint
+ subq $3, 24, $2 # E : For determining future wh64 addresses
+ stq $17, 0($5) # L :
+ nop # E :
+
+ addq $5, 128, $4 # E : speculative target of next wh64
+ stq $17, 8($5) # L :
+ stq $17, 16($5) # L :
+ addq $5, 64, $7 # E : Fallback address for wh64 (== next trip addr)
+
+ stq $17, 24($5) # L :
+ stq $17, 32($5) # L :
+ cmovlt $2, $7, $4 # E : Latency 2, extra mapping cycle
+ nop
+
+ stq $17, 40($5) # L :
+ stq $17, 48($5) # L :
+ subq $3, 16, $2 # E : Repeat the loop at least once more?
+ nop
+
+ stq $17, 56($5) # L :
+ addq $5, 64, $5 # E :
+ subq $3, 8, $3 # E :
+ bge $2, $do_wh64 # U :
+
+ nop
+ nop
+ nop
+ beq $3, $no_quad # U : Might have finished already
+
+ .align 4
+ /*
+ * Simple loop for trailing quadwords, or for small amounts
+ * of data (where we can't use an unrolled loop and wh64)
+ */
+$loop:
+ stq $17, 0($5) # L :
+ subq $3, 1, $3 # E : Decrement number quads left
+ addq $5, 8, $5 # E : Inc address
+ bne $3, $loop # U : more?
+
+$no_quad:
+ /*
+ * Write 0..7 trailing bytes.
+ */
+ nop # E :
+ beq $18, $end # U : All done?
+ ldq $7, 0($5) # L :
+ mskqh $7, $6, $2 # U : Mask final quad
+
+ insqh $17, $6, $4 # U : New bits
+ or $2, $4, $1 # E : Put it all together
+ stq $1, 0($5) # L : And back to memory
+ ret $31,($26),1 # L0 :
+
+$within_quad:
+ ldq_u $1, 0($16) # L :
+ insql $17, $16, $2 # U : New bits
+ mskql $1, $16, $4 # U : Clear old
+ or $2, $4, $2 # E : New result
+
+ mskql $2, $6, $4 # U :
+ mskqh $1, $6, $2 # U :
+ or $2, $4, $1 # E :
+ stq_u $1, 0($16) # L :
+
+$end:
+ nop
+ nop
+ nop
+ ret $31,($26),1 # L0 :
+
+ END(memset)
+libc_hidden_builtin_def (memset)
diff --git a/libc/sysdeps/alpha/alphaev6/stxcpy.S b/libc/sysdeps/alpha/alphaev6/stxcpy.S
new file mode 100644
index 000000000..3c3e7d72b
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev6/stxcpy.S
@@ -0,0 +1,328 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu)
+ EV6 optimized by Rick Gorton <rick.gorton@alpha-processor.com>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copy a null-terminated string from SRC to DST.
+
+ This is an internal routine used by strcpy, stpcpy, and strcat.
+ As such, it uses special linkage conventions to make implementation
+ of these public functions more efficient.
+
+ On input:
+ t9 = return address
+ a0 = DST
+ a1 = SRC
+
+ On output:
+ t8 = bitmask (with one bit set) indicating the last byte written
+ a0 = unaligned address of the last *word* written
+
+ Furthermore, v0, a3-a5, t11, and t12 are untouched.
+*/
+
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noat
+ .set noreorder
+ .text
+
+/* There is a problem with either gdb (as of 4.16) or gas (as of 2.7) that
+ doesn't like putting the entry point for a procedure somewhere in the
+ middle of the procedure descriptor. Work around this by putting the
+ aligned copy in its own procedure descriptor */
+
+
+ .ent stxcpy_aligned
+ .align 4
+stxcpy_aligned:
+ .frame sp, 0, t9
+ .prologue 0
+
+ /* On entry to this basic block:
+ t0 == the first destination word for masking back in
+ t1 == the first source word. */
+
+ /* Create the 1st output word and detect 0's in the 1st input word. */
+ lda t2, -1 # E : build a mask against false zero
+ mskqh t2, a1, t2 # U : detection in the src word (stall)
+ mskqh t1, a1, t3 # U :
+ ornot t1, t2, t2 # E : (stall)
+
+ mskql t0, a1, t0 # U : assemble the first output word
+ cmpbge zero, t2, t10 # E : bits set iff null found
+ or t0, t3, t1 # E : (stall)
+ bne t10, $a_eos # U : (stall)
+
+ /* On entry to this basic block:
+ t0 == the first destination word for masking back in
+ t1 == a source word not containing a null. */
+ /* Nops here to separate store quads from load quads */
+
+$a_loop:
+ stq_u t1, 0(a0) # L :
+ addq a0, 8, a0 # E :
+ nop
+ nop
+
+ ldq_u t1, 0(a1) # L : Latency=3
+ addq a1, 8, a1 # E :
+ cmpbge zero, t1, t10 # E : (3 cycle stall)
+ beq t10, $a_loop # U : (stall for t10)
+
+ /* Take care of the final (partial) word store.
+ On entry to this basic block we have:
+ t1 == the source word containing the null
+ t10 == the cmpbge mask that found it. */
+$a_eos:
+ negq t10, t6 # E : find low bit set
+ and t10, t6, t8 # E : (stall)
+ /* For the sake of the cache, don't read a destination word
+ if we're not going to need it. */
+ and t8, 0x80, t6 # E : (stall)
+ bne t6, 1f # U : (stall)
+
+ /* We're doing a partial word store and so need to combine
+ our source and original destination words. */
+ ldq_u t0, 0(a0) # L : Latency=3
+ subq t8, 1, t6 # E :
+ zapnot t1, t6, t1 # U : clear src bytes >= null (stall)
+ or t8, t6, t10 # E : (stall)
+
+ zap t0, t10, t0 # E : clear dst bytes <= null
+ or t0, t1, t1 # E : (stall)
+ nop
+ nop
+
+1: stq_u t1, 0(a0) # L :
+ ret (t9) # L0 : Latency=3
+ nop
+ nop
+
+ .end stxcpy_aligned
+
+ .align 4
+ .ent __stxcpy
+ .globl __stxcpy
+__stxcpy:
+ .frame sp, 0, t9
+ .prologue 0
+
+ /* Are source and destination co-aligned? */
+ xor a0, a1, t0 # E :
+ unop # E :
+ and t0, 7, t0 # E : (stall)
+ bne t0, $unaligned # U : (stall)
+
+ /* We are co-aligned; take care of a partial first word. */
+ ldq_u t1, 0(a1) # L : load first src word
+ and a0, 7, t0 # E : take care not to load a word ...
+ addq a1, 8, a1 # E :
+ beq t0, stxcpy_aligned # U : ... if we wont need it (stall)
+
+ ldq_u t0, 0(a0) # L :
+ br stxcpy_aligned # L0 : Latency=3
+ nop
+ nop
+
+
+/* The source and destination are not co-aligned. Align the destination
+ and cope. We have to be very careful about not reading too much and
+ causing a SEGV. */
+
+ .align 4
+$u_head:
+ /* We know just enough now to be able to assemble the first
+ full source word. We can still find a zero at the end of it
+ that prevents us from outputting the whole thing.
+
+ On entry to this basic block:
+ t0 == the first dest word, for masking back in, if needed else 0
+ t1 == the low bits of the first source word
+ t6 == bytemask that is -1 in dest word bytes */
+
+ ldq_u t2, 8(a1) # L :
+ addq a1, 8, a1 # E :
+ extql t1, a1, t1 # U : (stall on a1)
+ extqh t2, a1, t4 # U : (stall on a1)
+
+ mskql t0, a0, t0 # U :
+ or t1, t4, t1 # E :
+ mskqh t1, a0, t1 # U : (stall on t1)
+ or t0, t1, t1 # E : (stall on t1)
+
+ or t1, t6, t6 # E :
+ cmpbge zero, t6, t10 # E : (stall)
+ lda t6, -1 # E : for masking just below
+ bne t10, $u_final # U : (stall)
+
+ mskql t6, a1, t6 # U : mask out the bits we have
+ or t6, t2, t2 # E : already extracted before (stall)
+ cmpbge zero, t2, t10 # E : testing eos (stall)
+ bne t10, $u_late_head_exit # U : (stall)
+
+ /* Finally, we've got all the stupid leading edge cases taken care
+ of and we can set up to enter the main loop. */
+
+ stq_u t1, 0(a0) # L : store first output word
+ addq a0, 8, a0 # E :
+ extql t2, a1, t0 # U : position ho-bits of lo word
+ ldq_u t2, 8(a1) # U : read next high-order source word
+
+ addq a1, 8, a1 # E :
+ cmpbge zero, t2, t10 # E : (stall for t2)
+ nop # E :
+ bne t10, $u_eos # U : (stall)
+
+ /* Unaligned copy main loop. In order to avoid reading too much,
+ the loop is structured to detect zeros in aligned source words.
+ This has, unfortunately, effectively pulled half of a loop
+ iteration out into the head and half into the tail, but it does
+ prevent nastiness from accumulating in the very thing we want
+ to run as fast as possible.
+
+ On entry to this basic block:
+ t0 == the shifted high-order bits from the previous source word
+ t2 == the unshifted current source word
+
+ We further know that t2 does not contain a null terminator. */
+
+ .align 3
+$u_loop:
+ extqh t2, a1, t1 # U : extract high bits for current word
+ addq a1, 8, a1 # E : (stall)
+ extql t2, a1, t3 # U : extract low bits for next time (stall)
+ addq a0, 8, a0 # E :
+
+ or t0, t1, t1 # E : current dst word now complete
+ ldq_u t2, 0(a1) # L : Latency=3 load high word for next time
+ stq_u t1, -8(a0) # L : save the current word (stall)
+ mov t3, t0 # E :
+
+ cmpbge zero, t2, t10 # E : test new word for eos
+ beq t10, $u_loop # U : (stall)
+ nop
+ nop
+
+ /* We've found a zero somewhere in the source word we just read.
+ If it resides in the lower half, we have one (probably partial)
+ word to write out, and if it resides in the upper half, we
+ have one full and one partial word left to write out.
+
+ On entry to this basic block:
+ t0 == the shifted high-order bits from the previous source word
+ t2 == the unshifted current source word. */
+$u_eos:
+ extqh t2, a1, t1 # U :
+ or t0, t1, t1 # E : first (partial) source word complete (stall)
+ cmpbge zero, t1, t10 # E : is the null in this first bit? (stall)
+ bne t10, $u_final # U : (stall)
+
+$u_late_head_exit:
+ stq_u t1, 0(a0) # L : the null was in the high-order bits
+ addq a0, 8, a0 # E :
+ extql t2, a1, t1 # U :
+ cmpbge zero, t1, t10 # E : (stall)
+
+ /* Take care of a final (probably partial) result word.
+ On entry to this basic block:
+ t1 == assembled source word
+ t10 == cmpbge mask that found the null. */
+$u_final:
+ negq t10, t6 # E : isolate low bit set
+ and t6, t10, t8 # E : (stall)
+ and t8, 0x80, t6 # E : avoid dest word load if we can (stall)
+ bne t6, 1f # U : (stall)
+
+ ldq_u t0, 0(a0) # E :
+ subq t8, 1, t6 # E :
+ or t6, t8, t10 # E : (stall)
+ zapnot t1, t6, t1 # U : kill source bytes >= null (stall)
+
+ zap t0, t10, t0 # U : kill dest bytes <= null (2 cycle data stall)
+ or t0, t1, t1 # E : (stall)
+ nop
+ nop
+
+1: stq_u t1, 0(a0) # L :
+ ret (t9) # L0 : Latency=3
+ nop
+ nop
+
+ /* Unaligned copy entry point. */
+ .align 4
+$unaligned:
+
+ ldq_u t1, 0(a1) # L : load first source word
+ and a0, 7, t4 # E : find dest misalignment
+ and a1, 7, t5 # E : find src misalignment
+ /* Conditionally load the first destination word and a bytemask
+ with 0xff indicating that the destination byte is sacrosanct. */
+ mov zero, t0 # E :
+
+ mov zero, t6 # E :
+ beq t4, 1f # U :
+ ldq_u t0, 0(a0) # L :
+ lda t6, -1 # E :
+
+ mskql t6, a0, t6 # U :
+ nop
+ nop
+ nop
+1:
+ subq a1, t4, a1 # E : sub dest misalignment from src addr
+ /* If source misalignment is larger than dest misalignment, we need
+ extra startup checks to avoid SEGV. */
+ cmplt t4, t5, t8 # E :
+ beq t8, $u_head # U :
+ lda t2, -1 # E : mask out leading garbage in source
+
+ mskqh t2, t5, t2 # U :
+ ornot t1, t2, t3 # E : (stall)
+ cmpbge zero, t3, t10 # E : is there a zero? (stall)
+ beq t10, $u_head # U : (stall)
+
+ /* At this point we've found a zero in the first partial word of
+ the source. We need to isolate the valid source data and mask
+ it into the original destination data. (Incidentally, we know
+ that we'll need at least one byte of that original dest word.) */
+
+ ldq_u t0, 0(a0) # L :
+ negq t10, t6 # E : build bitmask of bytes <= zero
+ and t6, t10, t8 # E : (stall)
+ and a1, 7, t5 # E :
+
+ subq t8, 1, t6 # E :
+ or t6, t8, t10 # E : (stall)
+ srl t8, t5, t8 # U : adjust final null return value
+ zapnot t2, t10, t2 # U : prepare source word; mirror changes (stall)
+
+ and t1, t2, t1 # E : to source validity mask
+ extql t2, a1, t2 # U :
+ extql t1, a1, t1 # U : (stall)
+ andnot t0, t2, t0 # .. e1 : zero place for source to reside (stall)
+
+ or t0, t1, t1 # e1 : and put it there
+ stq_u t1, 0(a0) # .. e0 : (stall)
+ ret (t9) # e1 :
+ nop
+
+ .end __stxcpy
+
diff --git a/libc/sysdeps/alpha/alphaev6/stxncpy.S b/libc/sysdeps/alpha/alphaev6/stxncpy.S
new file mode 100644
index 000000000..f39c23a88
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev6/stxncpy.S
@@ -0,0 +1,403 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu)
+ EV6 optimized by Rick Gorton <rick.gorton@alpha-processor.com>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copy no more than COUNT bytes of the null-terminated string from
+ SRC to DST.
+
+ This is an internal routine used by strncpy, stpncpy, and strncat.
+ As such, it uses special linkage conventions to make implementation
+ of these public functions more efficient.
+
+ On input:
+ t9 = return address
+ a0 = DST
+ a1 = SRC
+ a2 = COUNT
+
+ Furthermore, COUNT may not be zero.
+
+ On output:
+ t0 = last word written
+ t8 = bitmask (with one bit set) indicating the last byte written
+ t10 = bitmask (with one bit set) indicating the byte position of
+ the end of the range specified by COUNT
+ a0 = unaligned address of the last *word* written
+ a2 = the number of full words left in COUNT
+
+ Furthermore, v0, a3-a5, t11, and t12 are untouched.
+*/
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noat
+ .set noreorder
+
+/* There is a problem with either gdb (as of 4.16) or gas (as of 2.7) that
+ doesn't like putting the entry point for a procedure somewhere in the
+ middle of the procedure descriptor. Work around this by putting the
+ aligned copy in its own procedure descriptor */
+
+
+ .ent stxncpy_aligned
+ .align 4
+stxncpy_aligned:
+ .frame sp, 0, t9, 0
+ .prologue 0
+
+ /* On entry to this basic block:
+ t0 == the first destination word for masking back in
+ t1 == the first source word. */
+
+ /* Create the 1st output word and detect 0's in the 1st input word. */
+ lda t2, -1 # E : build a mask against false zero
+ mskqh t2, a1, t2 # U : detection in the src word (stall)
+ mskqh t1, a1, t3 # U :
+ ornot t1, t2, t2 # E : (stall)
+
+ mskql t0, a1, t0 # U : assemble the first output word
+ cmpbge zero, t2, t7 # E : bits set iff null found
+ or t0, t3, t0 # E : (stall)
+ beq a2, $a_eoc # U :
+
+ bne t7, $a_eos # U :
+ nop
+ nop
+ nop
+
+ /* On entry to this basic block:
+ t0 == a source word not containing a null. */
+
+ /*
+ * nops here to:
+ * separate store quads from load quads
+ * limit of 1 bcond/quad to permit training
+ */
+$a_loop:
+ stq_u t0, 0(a0) # L :
+ addq a0, 8, a0 # E :
+ subq a2, 1, a2 # E :
+ nop
+
+ ldq_u t0, 0(a1) # L :
+ addq a1, 8, a1 # E :
+ cmpbge zero, t0, t7 # E :
+ beq a2, $a_eoc # U :
+
+ beq t7, $a_loop # U :
+ nop
+ nop
+ nop
+
+ /* Take care of the final (partial) word store. At this point
+ the end-of-count bit is set in t7 iff it applies.
+
+ On entry to this basic block we have:
+ t0 == the source word containing the null
+ t7 == the cmpbge mask that found it. */
+
+$a_eos:
+ negq t7, t8 # E : find low bit set
+ and t7, t8, t8 # E : (stall)
+ /* For the sake of the cache, don't read a destination word
+ if we're not going to need it. */
+ and t8, 0x80, t6 # E : (stall)
+ bne t6, 1f # U : (stall)
+
+ /* We're doing a partial word store and so need to combine
+ our source and original destination words. */
+ ldq_u t1, 0(a0) # L :
+ subq t8, 1, t6 # E :
+ or t8, t6, t7 # E : (stall)
+ zapnot t0, t7, t0 # U : clear src bytes > null (stall)
+
+ zap t1, t7, t1 # .. e1 : clear dst bytes <= null
+ or t0, t1, t0 # e1 : (stall)
+ nop
+ nop
+
+1: stq_u t0, 0(a0) # L :
+ ret (t9) # L0 : Latency=3
+ nop
+ nop
+
+ /* Add the end-of-count bit to the eos detection bitmask. */
+$a_eoc:
+ or t10, t7, t7 # E :
+ br $a_eos # L0 : Latency=3
+ nop
+ nop
+
+ .end stxncpy_aligned
+
+ .align 4
+ .ent __stxncpy
+ .globl __stxncpy
+__stxncpy:
+ .frame sp, 0, t9, 0
+ .prologue 0
+
+ /* Are source and destination co-aligned? */
+ xor a0, a1, t1 # E :
+ and a0, 7, t0 # E : find dest misalignment
+ and t1, 7, t1 # E : (stall)
+ addq a2, t0, a2 # E : bias count by dest misalignment (stall)
+
+ subq a2, 1, a2 # E :
+ and a2, 7, t2 # E : (stall)
+ srl a2, 3, a2 # U : a2 = loop counter = (count - 1)/8 (stall)
+ addq zero, 1, t10 # E :
+
+ sll t10, t2, t10 # U : t10 = bitmask of last count byte
+ bne t1, $unaligned # U :
+ /* We are co-aligned; take care of a partial first word. */
+ ldq_u t1, 0(a1) # L : load first src word
+ addq a1, 8, a1 # E :
+
+ beq t0, stxncpy_aligned # U : avoid loading dest word if not needed
+ ldq_u t0, 0(a0) # L :
+ nop
+ nop
+
+ br stxncpy_aligned # .. e1 :
+ nop
+ nop
+ nop
+
+
+
+/* The source and destination are not co-aligned. Align the destination
+ and cope. We have to be very careful about not reading too much and
+ causing a SEGV. */
+
+ .align 4
+$u_head:
+ /* We know just enough now to be able to assemble the first
+ full source word. We can still find a zero at the end of it
+ that prevents us from outputting the whole thing.
+
+ On entry to this basic block:
+ t0 == the first dest word, unmasked
+ t1 == the shifted low bits of the first source word
+ t6 == bytemask that is -1 in dest word bytes */
+
+ ldq_u t2, 8(a1) # L : Latency=3 load second src word
+ addq a1, 8, a1 # E :
+ mskql t0, a0, t0 # U : mask trailing garbage in dst
+ extqh t2, a1, t4 # U : (3 cycle stall on t2)
+
+ or t1, t4, t1 # E : first aligned src word complete (stall)
+ mskqh t1, a0, t1 # U : mask leading garbage in src (stall)
+ or t0, t1, t0 # E : first output word complete (stall)
+ or t0, t6, t6 # E : mask original data for zero test (stall)
+
+ cmpbge zero, t6, t7 # E :
+ beq a2, $u_eocfin # U :
+ lda t6, -1 # E :
+ nop
+
+ bne t7, $u_final # U :
+ mskql t6, a1, t6 # U : mask out bits already seen
+ stq_u t0, 0(a0) # L : store first output word
+ or t6, t2, t2 # E :
+
+ cmpbge zero, t2, t7 # E : find nulls in second partial
+ addq a0, 8, a0 # E :
+ subq a2, 1, a2 # E :
+ bne t7, $u_late_head_exit # U :
+
+ /* Finally, we've got all the stupid leading edge cases taken care
+ of and we can set up to enter the main loop. */
+ extql t2, a1, t1 # U : position hi-bits of lo word
+ beq a2, $u_eoc # U :
+ ldq_u t2, 8(a1) # L : read next high-order source word
+ addq a1, 8, a1 # E :
+
+ extqh t2, a1, t0 # U : position lo-bits of hi word (stall)
+ cmpbge zero, t2, t7 # E :
+ nop
+ bne t7, $u_eos # U :
+
+ /* Unaligned copy main loop. In order to avoid reading too much,
+ the loop is structured to detect zeros in aligned source words.
+ This has, unfortunately, effectively pulled half of a loop
+ iteration out into the head and half into the tail, but it does
+ prevent nastiness from accumulating in the very thing we want
+ to run as fast as possible.
+
+ On entry to this basic block:
+ t0 == the shifted low-order bits from the current source word
+ t1 == the shifted high-order bits from the previous source word
+ t2 == the unshifted current source word
+
+ We further know that t2 does not contain a null terminator. */
+
+ .align 4
+$u_loop:
+ or t0, t1, t0 # E : current dst word now complete
+ subq a2, 1, a2 # E : decrement word count
+ extql t2, a1, t1 # U : extract high bits for next time
+ addq a0, 8, a0 # E :
+
+ stq_u t0, -8(a0) # L : save the current word
+ beq a2, $u_eoc # U :
+ ldq_u t2, 8(a1) # L : Latency=3 load high word for next time
+ addq a1, 8, a1 # E :
+
+ extqh t2, a1, t0 # U : extract low bits (2 cycle stall)
+ cmpbge zero, t2, t7 # E : test new word for eos
+ nop
+ beq t7, $u_loop # U :
+
+ /* We've found a zero somewhere in the source word we just read.
+ If it resides in the lower half, we have one (probably partial)
+ word to write out, and if it resides in the upper half, we
+ have one full and one partial word left to write out.
+
+ On entry to this basic block:
+ t0 == the shifted low-order bits from the current source word
+ t1 == the shifted high-order bits from the previous source word
+ t2 == the unshifted current source word. */
+$u_eos:
+ or t0, t1, t0 # E : first (partial) source word complete
+ nop
+ cmpbge zero, t0, t7 # E : is the null in this first bit? (stall)
+ bne t7, $u_final # U : (stall)
+
+ stq_u t0, 0(a0) # L : the null was in the high-order bits
+ addq a0, 8, a0 # E :
+ subq a2, 1, a2 # E :
+ nop
+
+$u_late_head_exit:
+ extql t2, a1, t0 # U :
+ cmpbge zero, t0, t7 # E :
+ or t7, t10, t6 # E : (stall)
+ cmoveq a2, t6, t7 # E : Latency=2, extra map slot (stall)
+
+ /* Take care of a final (probably partial) result word.
+ On entry to this basic block:
+ t0 == assembled source word
+ t7 == cmpbge mask that found the null. */
+$u_final:
+ negq t7, t6 # E : isolate low bit set
+ and t6, t7, t8 # E : (stall)
+ and t8, 0x80, t6 # E : avoid dest word load if we can (stall)
+ bne t6, 1f # U : (stall)
+
+ ldq_u t1, 0(a0) # L :
+ subq t8, 1, t6 # E :
+ or t6, t8, t7 # E : (stall)
+ zapnot t0, t7, t0 # U : kill source bytes > null
+
+ zap t1, t7, t1 # U : kill dest bytes <= null
+ or t0, t1, t0 # E : (stall)
+ nop
+ nop
+
+1: stq_u t0, 0(a0) # L :
+ ret (t9) # L0 : Latency=3
+
+ /* Got to end-of-count before end of string.
+ On entry to this basic block:
+ t1 == the shifted high-order bits from the previous source word */
+$u_eoc:
+ and a1, 7, t6 # E :
+ sll t10, t6, t6 # U : (stall)
+ and t6, 0xff, t6 # E : (stall)
+ bne t6, 1f # U : (stall)
+
+ ldq_u t2, 8(a1) # L : load final src word
+ nop
+ extqh t2, a1, t0 # U : extract low bits for last word (stall)
+ or t1, t0, t1 # E : (stall)
+
+1: cmpbge zero, t1, t7 # E :
+ mov t1, t0
+
+$u_eocfin: # end-of-count, final word
+ or t10, t7, t7 # E :
+ br $u_final # L0 : Latency=3
+
+ /* Unaligned copy entry point. */
+ .align 4
+$unaligned:
+
+ ldq_u t1, 0(a1) # L : load first source word
+ and a0, 7, t4 # E : find dest misalignment
+ and a1, 7, t5 # E : find src misalignment
+ /* Conditionally load the first destination word and a bytemask
+ with 0xff indicating that the destination byte is sacrosanct. */
+ mov zero, t0 # E :
+
+ mov zero, t6 # E :
+ beq t4, 1f # U :
+ ldq_u t0, 0(a0) # L :
+ lda t6, -1 # E :
+
+ mskql t6, a0, t6 # U :
+ nop
+ nop
+1: subq a1, t4, a1 # E : sub dest misalignment from src addr
+
+ /* If source misalignment is larger than dest misalignment, we need
+ extra startup checks to avoid SEGV. */
+
+ cmplt t4, t5, t8 # E :
+ extql t1, a1, t1 # U : shift src into place
+ lda t2, -1 # E : for creating masks later
+ beq t8, $u_head # U : (stall)
+
+ mskqh t2, t5, t2 # U : begin src byte validity mask
+ cmpbge zero, t1, t7 # E : is there a zero?
+ extql t2, a1, t2 # U :
+ or t7, t10, t5 # E : test for end-of-count too
+
+ cmpbge zero, t2, t3 # E :
+ cmoveq a2, t5, t7 # E : Latency=2, extra map slot
+ nop # E : keep with cmoveq
+ andnot t7, t3, t7 # E : (stall)
+
+ beq t7, $u_head # U :
+ /* At this point we've found a zero in the first partial word of
+ the source. We need to isolate the valid source data and mask
+ it into the original destination data. (Incidentally, we know
+ that we'll need at least one byte of that original dest word.) */
+ ldq_u t0, 0(a0) # L :
+ negq t7, t6 # E : build bitmask of bytes <= zero
+ mskqh t1, t4, t1 # U :
+
+ and t6, t7, t8 # E :
+ subq t8, 1, t6 # E : (stall)
+ or t6, t8, t7 # E : (stall)
+ zapnot t2, t7, t2 # U : prepare source word; mirror changes (stall)
+
+ zapnot t1, t7, t1 # U : to source validity mask
+ andnot t0, t2, t0 # E : zero place for source to reside
+ or t0, t1, t0 # E : and put it there (stall both t0, t1)
+ stq_u t0, 0(a0) # L : (stall)
+
+ ret (t9) # L0 : Latency=3
+ nop
+ nop
+ nop
+
+ .end __stxncpy
+
diff --git a/libc/sysdeps/alpha/alphaev67/Implies b/libc/sysdeps/alpha/alphaev67/Implies
new file mode 100644
index 000000000..49d19c4ad
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev67/Implies
@@ -0,0 +1 @@
+alpha/alphaev6
diff --git a/libc/sysdeps/alpha/alphaev67/ffs.S b/libc/sysdeps/alpha/alphaev67/ffs.S
new file mode 100644
index 000000000..fb1cdd932
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev67/ffs.S
@@ -0,0 +1,51 @@
+/* Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Finds the first bit set in an integer. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .set noat
+
+
+ENTRY(__ffs)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ zap $16, 0xF0, $16
+ cttz $16, $0
+ addq $0, 1, $0
+ cmoveq $16, 0, $0
+
+ nop
+ nop
+ nop
+ ret
+
+END(__ffs)
+
+weak_alias (__ffs, ffs)
+libc_hidden_builtin_def (ffs)
diff --git a/libc/sysdeps/alpha/alphaev67/ffsll.S b/libc/sysdeps/alpha/alphaev67/ffsll.S
new file mode 100644
index 000000000..72ef09418
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev67/ffsll.S
@@ -0,0 +1,45 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Finds the first bit set in a long. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .set noat
+
+ENTRY(ffsl)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ cttz $16, $0
+ addq $0, 1, $0
+ cmoveq $16, 0, $0
+ ret
+
+END(ffsl)
+
+weak_extern (ffsl)
+weak_alias (ffsl, ffsll)
diff --git a/libc/sysdeps/alpha/alphaev67/fpu/Implies b/libc/sysdeps/alpha/alphaev67/fpu/Implies
new file mode 100644
index 000000000..9e3f12d0a
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev67/fpu/Implies
@@ -0,0 +1 @@
+alpha/alphaev6/fpu
diff --git a/libc/sysdeps/alpha/alphaev67/rawmemchr.S b/libc/sysdeps/alpha/alphaev67/rawmemchr.S
new file mode 100644
index 000000000..8c7e9423b
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev67/rawmemchr.S
@@ -0,0 +1,93 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return pointer to first occurrence of CH in STR. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .set noat
+
+ENTRY(__rawmemchr)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ ldq_u t0, 0(a0) # L : load first quadword Latency=3
+ and a1, 0xff, t3 # E : 00000000000000ch
+ insbl a1, 1, t5 # U : 000000000000ch00
+ insbl a1, 7, a2 # U : ch00000000000000
+
+ insbl t3, 6, a3 # U : 00ch000000000000
+ or t5, t3, a1 # E : 000000000000chch
+ andnot a0, 7, v0 # E : align our loop pointer
+ lda t4, -1 # E : build garbage mask
+
+ mskqh t4, a0, t4 # U : only want relevant part of first quad
+ or a2, a3, a2 # E : chch000000000000
+ inswl a1, 2, t5 # E : 00000000chch0000
+ inswl a1, 4, a3 # E : 0000chch00000000
+
+ or a1, a2, a1 # E : chch00000000chch
+ or a3, t5, t5 # E : 0000chchchch0000
+ cmpbge zero, t4, t4 # E : bits set iff byte is garbage
+ nop # E :
+
+ /* This quad is _very_ serialized. Lots of stalling happens */
+ or t5, a1, a1 # E : chchchchchchchch
+ xor t0, a1, t1 # E : make bytes == c zero
+ cmpbge zero, t1, t0 # E : bits set iff byte == c
+ andnot t0, t4, t0 # E : clear garbage bits
+
+ cttz t0, a2 # U0 : speculative (in case we get a match)
+ nop # E :
+ nop # E :
+ bne t0, $found # U :
+
+ /*
+ * Yuk. This loop is going to stall like crazy waiting for the
+ * data to be loaded. Not much can be done about it unless it's
+ * unrolled multiple times, which is generally unsafe.
+ */
+$loop:
+ ldq t0, 8(v0) # L : Latency=3
+ addq v0, 8, v0 # E :
+ xor t0, a1, t1 # E :
+ cmpbge zero, t1, t0 # E : bits set iff byte == c
+
+ cttz t0, a2 # U0 : speculative (in case we get a match)
+ nop # E :
+ nop # E :
+ beq t0, $loop # U :
+
+$found:
+ negq t0, t1 # E : clear all but least set bit
+ and t0, t1, t0 # E :
+ addq v0, a2, v0 # E : Add in the bit number from above
+ ret # L0 :
+
+ END(__rawmemchr)
+
+libc_hidden_def (__rawmemchr)
+weak_alias (__rawmemchr, rawmemchr)
diff --git a/libc/sysdeps/alpha/alphaev67/stpcpy.S b/libc/sysdeps/alpha/alphaev67/stpcpy.S
new file mode 100644
index 000000000..b5da4e05d
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev67/stpcpy.S
@@ -0,0 +1,54 @@
+/* Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copy SRC to DEST returning the address of the terminating 0 in DEST. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .set noat
+ .text
+
+ENTRY(__stpcpy)
+ ldgp gp, 0(pv)
+#ifdef PROF
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+#endif
+ .prologue 1
+
+ .align 4
+ mov a0, v0
+ nop
+ jsr t9, __stxcpy
+
+ # t8 = bitmask (with one bit set) indicating the last byte written
+ # a0 = unaligned address of the last *word* written
+
+ cttz t8, t8
+ andnot a0, 7, a0
+ addq a0, t8, v0
+ ret
+
+ END(__stpcpy)
+
+weak_alias (__stpcpy, stpcpy)
+libc_hidden_def (__stpcpy)
+libc_hidden_builtin_def (stpcpy)
diff --git a/libc/sysdeps/alpha/alphaev67/stpncpy.S b/libc/sysdeps/alpha/alphaev67/stpncpy.S
new file mode 100644
index 000000000..4d61d7131
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev67/stpncpy.S
@@ -0,0 +1,116 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@redhat.com)
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copy no more then N bytes from SRC to DEST, returning the address of
+ the terminating '\0' in DEST. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noat
+ .set noreorder
+ .text
+
+ENTRY(__stpncpy)
+ ldgp gp, 0(pv)
+#ifdef PROF
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+#endif
+ .prologue 1
+
+ mov a0, v0
+ beq a2, $zerocount
+
+ .align 4
+ nop
+ nop
+ jsr t9, __stxncpy # do the work of the copy
+
+ cttz t8, t4
+ zapnot t0, t8, t5
+ andnot a0, 7, a0
+ bne a2, $multiword # do we have full words left?
+
+ subq t8, 1, t2
+ subq t10, 1, t3
+ cmpult zero, t5, t5
+ addq a0, t4, v0
+
+ or t2, t8, t2
+ or t3, t10, t3
+ addq v0, t5, v0
+ andnot t3, t2, t3
+
+ zap t0, t3, t0
+ nop
+ stq t0, 0(a0)
+ ret
+
+$multiword:
+ subq t8, 1, t7 # clear the final bits in the prev word
+ cmpult zero, t5, t5
+ or t7, t8, t7
+ zapnot t0, t7, t0
+
+ subq a2, 1, a2
+ stq t0, 0(a0)
+ addq a0, 8, a1
+ beq a2, 1f # loop over full words remaining
+
+ nop
+ nop
+ nop
+ blbc a2, 0f
+
+ stq zero, 0(a1)
+ subq a2, 1, a2
+ addq a1, 8, a1
+ beq a2, 1f
+
+0: stq zero, 0(a1)
+ subq a2, 2, a2
+ nop
+ nop
+
+ stq zero, 8(a1)
+ addq a1, 16, a1
+ nop
+ bne a2, 0b
+
+1: ldq t0, 0(a1) # clear the leading bits in the final word
+ subq t10, 1, t7
+ addq a0, t4, v0
+ nop
+
+ or t7, t10, t7
+ addq v0, t5, v0
+ zap t0, t7, t0
+ stq t0, 0(a1)
+
+$zerocount:
+ nop
+ nop
+ nop
+ ret
+
+ END(__stpncpy)
+
+libc_hidden_def (__stpncpy)
+weak_alias (__stpncpy, stpncpy)
diff --git a/libc/sysdeps/alpha/alphaev67/strcat.S b/libc/sysdeps/alpha/alphaev67/strcat.S
new file mode 100644
index 000000000..ae7c48808
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev67/strcat.S
@@ -0,0 +1,62 @@
+/* Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1996.
+ EV67 optimized by Rick Gorton <rick.gorton@alpha-processor.com>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Append a null-terminated string from SRC to DST. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .text
+
+ENTRY(strcat)
+ ldgp gp, 0(pv)
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ mov $16, $0 # E : set up return value
+ /* Find the end of the string. */
+ ldq_u $1, 0($16) # L : load first quadword (a0 may be misaligned)
+ lda $2, -1 # E :
+ insqh $2, $16, $2 # U :
+
+ andnot $16, 7, $16 # E :
+ or $2, $1, $1 # E :
+ cmpbge $31, $1, $2 # E : bits set iff byte == 0
+ bne $2, $found # U :
+
+$loop: ldq $1, 8($16) # L :
+ addq $16, 8, $16 # E :
+ cmpbge $31, $1, $2 # E :
+ beq $2, $loop # U :
+
+$found: cttz $2, $3 # U0 :
+ addq $16, $3, $16 # E :
+ /* Now do the append. */
+ mov $26, $23 # E :
+ jmp $31, __stxcpy # L0 :
+
+ END(strcat)
+libc_hidden_builtin_def (strcat)
diff --git a/libc/sysdeps/alpha/alphaev67/strchr.S b/libc/sysdeps/alpha/alphaev67/strchr.S
new file mode 100644
index 000000000..101c7d489
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev67/strchr.S
@@ -0,0 +1,101 @@
+/* Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1996.
+ EV67 optimized by Rick Gorton <rick.gorton@alpha-processor.com>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return the address of a given character within a null-terminated
+ string, or null if it is not found. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .set noat
+
+ENTRY(strchr)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ ldq_u t0, 0(a0) # L : load first quadword Latency=3
+ and a1, 0xff, t3 # E : 00000000000000ch
+ insbl a1, 1, t5 # U : 000000000000ch00
+ insbl a1, 7, a2 # U : ch00000000000000
+
+ insbl t3, 6, a3 # U : 00ch000000000000
+ or t5, t3, a1 # E : 000000000000chch
+ andnot a0, 7, v0 # E : align our loop pointer
+ lda t4, -1 # E : build garbage mask
+
+ mskqh t4, a0, t4 # U : only want relevant part of first quad
+ or a2, a3, a2 # E : chch000000000000
+ inswl a1, 2, t5 # E : 00000000chch0000
+ inswl a1, 4, a3 # E : 0000chch00000000
+
+ or a1, a2, a1 # E : chch00000000chch
+ or a3, t5, t5 # E : 0000chchchch0000
+ cmpbge zero, t0, t2 # E : bits set iff byte == zero
+ cmpbge zero, t4, t4 # E : bits set iff byte is garbage
+
+ /* This quad is _very_ serialized. Lots of stalling happens */
+ or t5, a1, a1 # E : chchchchchchchch
+ xor t0, a1, t1 # E : make bytes == c zero
+ cmpbge zero, t1, t3 # E : bits set iff byte == c
+ or t2, t3, t0 # E : bits set iff char match or zero match
+
+ andnot t0, t4, t0 # E : clear garbage bits
+ cttz t0, a2 # U0 : speculative (in case we get a match)
+ nop # E :
+ bne t0, $found # U :
+
+ /*
+ * Yuk. This loop is going to stall like crazy waiting for the
+ * data to be loaded. Not much can be done about it unless it's
+ * unrolled multiple times, which is generally unsafe.
+ */
+$loop:
+ ldq t0, 8(v0) # L : Latency=3
+ addq v0, 8, v0 # E :
+ xor t0, a1, t1 # E :
+ cmpbge zero, t0, t2 # E : bits set iff byte == 0
+
+ cmpbge zero, t1, t3 # E : bits set iff byte == c
+ or t2, t3, t0 # E :
+ cttz t3, a2 # U0 : speculative (in case we get a match)
+ beq t0, $loop # U :
+
+$found:
+ negq t0, t1 # E : clear all but least set bit
+ and t0, t1, t0 # E :
+ and t0, t3, t1 # E : bit set iff byte was the char
+ addq v0, a2, v0 # E : Add in the bit number from above
+
+ cmoveq t1, $31, v0 # E : Two mapping slots, latency = 2
+ nop
+ nop
+ ret # L0 :
+
+ END(strchr)
+
+weak_alias (strchr, index)
+libc_hidden_builtin_def (strchr)
diff --git a/libc/sysdeps/alpha/alphaev67/strlen.S b/libc/sysdeps/alpha/alphaev67/strlen.S
new file mode 100644
index 000000000..b83eaccea
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev67/strlen.S
@@ -0,0 +1,61 @@
+/* Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ Contributed by David Mosberger (davidm@cs.arizona.edu).
+ EV67 optimized by Rick Gorton <rick.gorton@alpha-processor.com>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Finds length of a 0-terminated string. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .set noat
+
+ENTRY(strlen)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ ldq_u $1, 0($16) # L : load first quadword ($16 may be misaligned)
+ lda $2, -1($31) # E :
+ insqh $2, $16, $2 # U :
+ andnot $16, 7, $0 # E :
+
+ or $2, $1, $1 # E :
+ cmpbge $31, $1, $2 # E : $2 <- bitmask: bit i == 1 <==> i-th byte == 0
+ nop # E :
+ bne $2, $found # U :
+
+$loop: ldq $1, 8($0) # L :
+ addq $0, 8, $0 # E : addr += 8
+ cmpbge $31, $1, $2 # E :
+ beq $2, $loop # U :
+
+$found:
+ cttz $2, $3 # U0 :
+ addq $0, $3, $0 # E :
+ subq $0, $16, $0 # E :
+ ret $31, ($26) # L0 :
+
+ END(strlen)
+libc_hidden_builtin_def (strlen)
diff --git a/libc/sysdeps/alpha/alphaev67/strncat.S b/libc/sysdeps/alpha/alphaev67/strncat.S
new file mode 100644
index 000000000..ae3257ca4
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev67/strncat.S
@@ -0,0 +1,88 @@
+/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1996.
+ EV67 optimized by Rick Gorton <rick.gorton@alpha-processor.com>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Append no more than COUNT characters from the null-terminated string SRC
+ to the null-terminated string DST. Always null-terminate the new DST. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .text
+
+ENTRY(strncat)
+ ldgp gp, 0(pv)
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ mov a0, v0 # set up return value
+ beq a2, $zerocount # U :
+ /* Find the end of the string. */
+ ldq_u t0, 0(a0) # L : load first quadword (a0 may be misaligned)
+ lda t1, -1 # E :
+
+ insqh t1, v0, t1 # U :
+ andnot a0, 7, a0 # E :
+ nop # E :
+ or t1, t0, t0 # E :
+
+ nop # E :
+ nop # E :
+ cmpbge zero, t0, t1 # E : bits set iff byte == 0
+ bne t1, $found # U :
+
+$loop: ldq t0, 8(a0) # L :
+ addq a0, 8, a0 # E :
+ cmpbge zero, t0, t1 # E :
+ beq t1, $loop # U :
+
+$found: cttz t1, t2 # U0 :
+ addq a0, t2, a0 # E :
+ jsr t9, __stxncpy # L0 : Now do the append.
+
+ /* Worry about the null termination. */
+
+ cttz t10, t2 # U0: byte offset of end-of-count.
+ bic a0, 7, a0 # E : word align the last write address.
+ zapnot t0, t8, t1 # U : was last byte a null?
+ nop # E :
+
+ bne t1, 0f # U :
+ nop # E :
+ nop # E :
+ ret # L0 :
+
+0: addq t2, a0, a0 # E : address of end-of-count
+ stb zero, 1(a0) # L :
+ nop # E :
+ ret # L0 :
+
+$zerocount:
+ nop # E :
+ nop # E :
+ nop # E :
+ ret # L0 :
+
+ END(strncat)
diff --git a/libc/sysdeps/alpha/alphaev67/strrchr.S b/libc/sysdeps/alpha/alphaev67/strrchr.S
new file mode 100644
index 000000000..c46a3df4f
--- /dev/null
+++ b/libc/sysdeps/alpha/alphaev67/strrchr.S
@@ -0,0 +1,117 @@
+/* Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ EV67 optimized by Rick Gorton <rick.gorton@alpha-processor.com>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return the address of the last occurrence of a given character
+ within a null-terminated string, or null if it is not found. */
+
+#include <sysdep.h>
+
+ .arch ev6
+ .set noreorder
+ .set noat
+
+ENTRY(strrchr)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ and a1, 0xff, t2 # E : 00000000000000ch
+ insbl a1, 1, t4 # U : 000000000000ch00
+ insbl a1, 2, t5 # U : 0000000000ch0000
+ ldq_u t0, 0(a0) # L : load first quadword Latency=3
+
+ mov zero, t6 # E : t6 is last match aligned addr
+ or t2, t4, a1 # E : 000000000000chch
+ sll t5, 8, t3 # U : 00000000ch000000
+ mov zero, t8 # E : t8 is last match byte compare mask
+
+ andnot a0, 7, v0 # E : align source addr
+ or t5, t3, t3 # E : 00000000chch0000
+ sll a1, 32, t2 # U : 0000chch00000000
+ sll a1, 48, t4 # U : chch000000000000
+
+ or t4, a1, a1 # E : chch00000000chch
+ or t2, t3, t2 # E : 0000chchchch0000
+ or a1, t2, a1 # E : chchchchchchchch
+ lda t5, -1 # E : build garbage mask
+
+ cmpbge zero, t0, t1 # E : bits set iff byte == zero
+ mskqh t5, a0, t4 # E : Complete garbage mask
+ xor t0, a1, t2 # E : make bytes == c zero
+ cmpbge zero, t4, t4 # E : bits set iff byte is garbage
+
+ cmpbge zero, t2, t3 # E : bits set iff byte == c
+ andnot t1, t4, t1 # E : clear garbage from null test
+ andnot t3, t4, t3 # E : clear garbage from char test
+ bne t1, $eos # U : did we already hit the terminator?
+
+ /* Character search main loop */
+$loop:
+ ldq t0, 8(v0) # L : load next quadword
+ cmovne t3, v0, t6 # E : save previous comparisons match
+ nop # : Latency=2, extra map slot (keep nop with cmov)
+ nop
+
+ cmovne t3, t3, t8 # E : Latency=2, extra map slot
+ nop # : keep with cmovne
+ addq v0, 8, v0 # E :
+ xor t0, a1, t2 # E :
+
+ cmpbge zero, t0, t1 # E : bits set iff byte == zero
+ cmpbge zero, t2, t3 # E : bits set iff byte == c
+ beq t1, $loop # U : if we havnt seen a null, loop
+ nop
+
+ /* Mask out character matches after terminator */
+$eos:
+ negq t1, t4 # E : isolate first null byte match
+ and t1, t4, t4 # E :
+ subq t4, 1, t5 # E : build a mask of the bytes upto...
+ or t4, t5, t4 # E : ... and including the null
+
+ and t3, t4, t3 # E : mask out char matches after null
+ cmovne t3, t3, t8 # E : save it, if match found Latency=2, extra map slot
+ nop # : Keep with cmovne
+ nop
+
+ cmovne t3, v0, t6 # E :
+ nop # : Keep with cmovne
+ /* Locate the address of the last matched character */
+ ctlz t8, t2 # U0 : Latency=3 (0x40 for t8=0)
+ nop
+
+ cmoveq t8, 0x3f, t2 # E : Compensate for case when no match is seen
+ nop # E : hide the cmov latency (2) behind ctlz latency
+ lda t5, 0x3f($31) # E :
+ subq t5, t2, t5 # E : Normalize leading zero count
+
+ addq t6, t5, v0 # E : and add to quadword address
+ ret # L0 : Latency=3
+ nop
+ nop
+
+END(strrchr)
+
+weak_alias (strrchr, rindex)
+libc_hidden_builtin_def (strrchr)
diff --git a/libc/sysdeps/alpha/backtrace.c b/libc/sysdeps/alpha/backtrace.c
new file mode 100644
index 000000000..297029456
--- /dev/null
+++ b/libc/sysdeps/alpha/backtrace.c
@@ -0,0 +1 @@
+#include <sysdeps/ia64/backtrace.c>
diff --git a/libc/sysdeps/alpha/bb_init_func.S b/libc/sysdeps/alpha/bb_init_func.S
new file mode 100644
index 000000000..f711c8cb7
--- /dev/null
+++ b/libc/sysdeps/alpha/bb_init_func.S
@@ -0,0 +1,87 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by David Mosberger (davidm@cs.arizona.edu).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* __bb_init_func is invoked at the beginning of each function, before
+ any registers have been saved. It is therefore safe to use any
+ caller-saved (call-used) registers (except for argument registers
+ a1-a5). */
+
+#include <sysdep.h>
+
+/*
+ * These offsets should match with "struct bb" declared in gcc/libgcc2.c.
+ */
+#define ZERO_WORD 0x00
+#define NEXT 0x20
+
+ .set noat
+ .set noreorder
+
+ENTRY(__bb_init_func)
+ .prologue 0
+
+ ldq t0, ZERO_WORD(a0) /* t0 <- blocks->zero_word */
+ beq t0, init /* not initialized yet -> */
+ ret
+
+END(__bb_init_func)
+
+ .ent init
+init:
+ .frame sp, 0x38, ra, 0
+ subq sp, 0x38, sp
+ .prologue 0
+
+ stq pv, 0x30(sp)
+ br pv, 1f
+1: ldgp gp, 0(pv)
+
+ ldiq t1, __bb_head
+ lda t3, _gmonparam
+ ldq t2, 0(t1)
+ ldl t3, 0(t3) /* t3 = _gmonparam.state */
+ lda t0, 1
+ stq t0, ZERO_WORD(a0) /* blocks->zero_word = 1 */
+ stq t2, NEXT(a0) /* blocks->next = __bb_head */
+ stq a0, 0(t1)
+ bne t2, $leave
+ beq t3, $leave /* t3 == GMON_PROF_ON? yes -> */
+
+ /* also need to initialize destructor: */
+ stq ra, 0x00(sp)
+ lda a0, __bb_exit_func
+ stq a1, 0x08(sp)
+ lda pv, atexit
+ stq a2, 0x10(sp)
+ stq a3, 0x18(sp)
+ stq a4, 0x20(sp)
+ stq a5, 0x28(sp)
+ jsr ra, (pv), atexit
+ ldq ra, 0x00(sp)
+ ldq a1, 0x08(sp)
+ ldq a2, 0x10(sp)
+ ldq a3, 0x18(sp)
+ ldq a4, 0x20(sp)
+ ldq a5, 0x28(sp)
+
+$leave: ldq pv, 0x30(sp)
+ addq sp, 0x38, sp
+ ret
+
+ .end init
diff --git a/libc/sysdeps/alpha/bits/atomic.h b/libc/sysdeps/alpha/bits/atomic.h
new file mode 100644
index 000000000..36a740c75
--- /dev/null
+++ b/libc/sysdeps/alpha/bits/atomic.h
@@ -0,0 +1,369 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+
+#ifdef UP
+# define __MB /* nothing */
+#else
+# define __MB " mb\n"
+#endif
+
+
+/* Compare and exchange. For all of the "xxx" routines, we expect a
+ "__prev" and a "__cmp" variable to be provided by the enclosing scope,
+ in which values are returned. */
+
+#define __arch_compare_and_exchange_xxx_8_int(mem, new, old, mb1, mb2) \
+({ \
+ unsigned long __tmp, __snew, __addr64; \
+ __asm__ __volatile__ ( \
+ mb1 \
+ " andnot %[__addr8],7,%[__addr64]\n" \
+ " insbl %[__new],%[__addr8],%[__snew]\n" \
+ "1: ldq_l %[__tmp],0(%[__addr64])\n" \
+ " extbl %[__tmp],%[__addr8],%[__prev]\n" \
+ " cmpeq %[__prev],%[__old],%[__cmp]\n" \
+ " beq %[__cmp],2f\n" \
+ " mskbl %[__tmp],%[__addr8],%[__tmp]\n" \
+ " or %[__snew],%[__tmp],%[__tmp]\n" \
+ " stq_c %[__tmp],0(%[__addr64])\n" \
+ " beq %[__tmp],1b\n" \
+ mb2 \
+ "2:" \
+ : [__prev] "=&r" (__prev), \
+ [__snew] "=&r" (__snew), \
+ [__tmp] "=&r" (__tmp), \
+ [__cmp] "=&r" (__cmp), \
+ [__addr64] "=&r" (__addr64) \
+ : [__addr8] "r" (mem), \
+ [__old] "Ir" ((uint64_t)(uint8_t)(uint64_t)(old)), \
+ [__new] "r" (new) \
+ : "memory"); \
+})
+
+#define __arch_compare_and_exchange_xxx_16_int(mem, new, old, mb1, mb2) \
+({ \
+ unsigned long __tmp, __snew, __addr64; \
+ __asm__ __volatile__ ( \
+ mb1 \
+ " andnot %[__addr16],7,%[__addr64]\n" \
+ " inswl %[__new],%[__addr16],%[__snew]\n" \
+ "1: ldq_l %[__tmp],0(%[__addr64])\n" \
+ " extwl %[__tmp],%[__addr16],%[__prev]\n" \
+ " cmpeq %[__prev],%[__old],%[__cmp]\n" \
+ " beq %[__cmp],2f\n" \
+ " mskwl %[__tmp],%[__addr16],%[__tmp]\n" \
+ " or %[__snew],%[__tmp],%[__tmp]\n" \
+ " stq_c %[__tmp],0(%[__addr64])\n" \
+ " beq %[__tmp],1b\n" \
+ mb2 \
+ "2:" \
+ : [__prev] "=&r" (__prev), \
+ [__snew] "=&r" (__snew), \
+ [__tmp] "=&r" (__tmp), \
+ [__cmp] "=&r" (__cmp), \
+ [__addr64] "=&r" (__addr64) \
+ : [__addr16] "r" (mem), \
+ [__old] "Ir" ((uint64_t)(uint16_t)(uint64_t)(old)), \
+ [__new] "r" (new) \
+ : "memory"); \
+})
+
+#define __arch_compare_and_exchange_xxx_32_int(mem, new, old, mb1, mb2) \
+({ \
+ __asm__ __volatile__ ( \
+ mb1 \
+ "1: ldl_l %[__prev],%[__mem]\n" \
+ " cmpeq %[__prev],%[__old],%[__cmp]\n" \
+ " beq %[__cmp],2f\n" \
+ " mov %[__new],%[__cmp]\n" \
+ " stl_c %[__cmp],%[__mem]\n" \
+ " beq %[__cmp],1b\n" \
+ mb2 \
+ "2:" \
+ : [__prev] "=&r" (__prev), \
+ [__cmp] "=&r" (__cmp) \
+ : [__mem] "m" (*(mem)), \
+ [__old] "Ir" ((uint64_t)(atomic32_t)(uint64_t)(old)), \
+ [__new] "Ir" (new) \
+ : "memory"); \
+})
+
+#define __arch_compare_and_exchange_xxx_64_int(mem, new, old, mb1, mb2) \
+({ \
+ __asm__ __volatile__ ( \
+ mb1 \
+ "1: ldq_l %[__prev],%[__mem]\n" \
+ " cmpeq %[__prev],%[__old],%[__cmp]\n" \
+ " beq %[__cmp],2f\n" \
+ " mov %[__new],%[__cmp]\n" \
+ " stq_c %[__cmp],%[__mem]\n" \
+ " beq %[__cmp],1b\n" \
+ mb2 \
+ "2:" \
+ : [__prev] "=&r" (__prev), \
+ [__cmp] "=&r" (__cmp) \
+ : [__mem] "m" (*(mem)), \
+ [__old] "Ir" ((uint64_t)(old)), \
+ [__new] "Ir" (new) \
+ : "memory"); \
+})
+
+/* For all "bool" routines, we return FALSE if exchange succesful. */
+
+#define __arch_compare_and_exchange_bool_8_int(mem, new, old, mb1, mb2) \
+({ unsigned long __prev; int __cmp; \
+ __arch_compare_and_exchange_xxx_8_int(mem, new, old, mb1, mb2); \
+ !__cmp; })
+
+#define __arch_compare_and_exchange_bool_16_int(mem, new, old, mb1, mb2) \
+({ unsigned long __prev; int __cmp; \
+ __arch_compare_and_exchange_xxx_16_int(mem, new, old, mb1, mb2); \
+ !__cmp; })
+
+#define __arch_compare_and_exchange_bool_32_int(mem, new, old, mb1, mb2) \
+({ unsigned long __prev; int __cmp; \
+ __arch_compare_and_exchange_xxx_32_int(mem, new, old, mb1, mb2); \
+ !__cmp; })
+
+#define __arch_compare_and_exchange_bool_64_int(mem, new, old, mb1, mb2) \
+({ unsigned long __prev; int __cmp; \
+ __arch_compare_and_exchange_xxx_64_int(mem, new, old, mb1, mb2); \
+ !__cmp; })
+
+/* For all "val" routines, return the old value whether exchange
+ successful or not. */
+
+#define __arch_compare_and_exchange_val_8_int(mem, new, old, mb1, mb2) \
+({ unsigned long __prev; int __cmp; \
+ __arch_compare_and_exchange_xxx_8_int(mem, new, old, mb1, mb2); \
+ (typeof (*mem))__prev; })
+
+#define __arch_compare_and_exchange_val_16_int(mem, new, old, mb1, mb2) \
+({ unsigned long __prev; int __cmp; \
+ __arch_compare_and_exchange_xxx_16_int(mem, new, old, mb1, mb2); \
+ (typeof (*mem))__prev; })
+
+#define __arch_compare_and_exchange_val_32_int(mem, new, old, mb1, mb2) \
+({ unsigned long __prev; int __cmp; \
+ __arch_compare_and_exchange_xxx_32_int(mem, new, old, mb1, mb2); \
+ (typeof (*mem))__prev; })
+
+#define __arch_compare_and_exchange_val_64_int(mem, new, old, mb1, mb2) \
+({ unsigned long __prev; int __cmp; \
+ __arch_compare_and_exchange_xxx_64_int(mem, new, old, mb1, mb2); \
+ (typeof (*mem))__prev; })
+
+/* Compare and exchange with "acquire" semantics, ie barrier after. */
+
+#define atomic_compare_and_exchange_bool_acq(mem, new, old) \
+ __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
+ mem, new, old, "", __MB)
+
+#define atomic_compare_and_exchange_val_acq(mem, new, old) \
+ __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
+ mem, new, old, "", __MB)
+
+/* Compare and exchange with "release" semantics, ie barrier before. */
+
+#define atomic_compare_and_exchange_bool_rel(mem, new, old) \
+ __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
+ mem, new, old, __MB, "")
+
+#define atomic_compare_and_exchange_val_rel(mem, new, old) \
+ __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
+ mem, new, old, __MB, "")
+
+
+/* Atomically store value and return the previous value. */
+
+#define __arch_exchange_8_int(mem, value, mb1, mb2) \
+({ \
+ unsigned long __ret, __tmp, __addr64, __sval; \
+ __asm__ __volatile__ ( \
+ mb1 \
+ " andnot %[__addr8],7,%[__addr64]\n" \
+ " insbl %[__value],%[__addr8],%[__sval]\n" \
+ "1: ldq_l %[__tmp],0(%[__addr64])\n" \
+ " extbl %[__tmp],%[__addr8],%[__ret]\n" \
+ " mskbl %[__tmp],%[__addr8],%[__tmp]\n" \
+ " or %[__sval],%[__tmp],%[__tmp]\n" \
+ " stq_c %[__tmp],0(%[__addr64])\n" \
+ " beq %[__tmp],1b\n" \
+ mb2 \
+ : [__ret] "=&r" (__ret), \
+ [__sval] "=&r" (__sval), \
+ [__tmp] "=&r" (__tmp), \
+ [__addr64] "=&r" (__addr64) \
+ : [__addr8] "r" (mem), \
+ [__value] "r" (value) \
+ : "memory"); \
+ __ret; })
+
+#define __arch_exchange_16_int(mem, value, mb1, mb2) \
+({ \
+ unsigned long __ret, __tmp, __addr64, __sval; \
+ __asm__ __volatile__ ( \
+ mb1 \
+ " andnot %[__addr16],7,%[__addr64]\n" \
+ " inswl %[__value],%[__addr16],%[__sval]\n" \
+ "1: ldq_l %[__tmp],0(%[__addr64])\n" \
+ " extwl %[__tmp],%[__addr16],%[__ret]\n" \
+ " mskwl %[__tmp],%[__addr16],%[__tmp]\n" \
+ " or %[__sval],%[__tmp],%[__tmp]\n" \
+ " stq_c %[__tmp],0(%[__addr64])\n" \
+ " beq %[__tmp],1b\n" \
+ mb2 \
+ : [__ret] "=&r" (__ret), \
+ [__sval] "=&r" (__sval), \
+ [__tmp] "=&r" (__tmp), \
+ [__addr64] "=&r" (__addr64) \
+ : [__addr16] "r" (mem), \
+ [__value] "r" (value) \
+ : "memory"); \
+ __ret; })
+
+#define __arch_exchange_32_int(mem, value, mb1, mb2) \
+({ \
+ signed int __ret, __tmp; \
+ __asm__ __volatile__ ( \
+ mb1 \
+ "1: ldl_l %[__ret],%[__mem]\n" \
+ " mov %[__val],%[__tmp]\n" \
+ " stl_c %[__tmp],%[__mem]\n" \
+ " beq %[__tmp],1b\n" \
+ mb2 \
+ : [__ret] "=&r" (__ret), \
+ [__tmp] "=&r" (__tmp) \
+ : [__mem] "m" (*(mem)), \
+ [__val] "Ir" (value) \
+ : "memory"); \
+ __ret; })
+
+#define __arch_exchange_64_int(mem, value, mb1, mb2) \
+({ \
+ unsigned long __ret, __tmp; \
+ __asm__ __volatile__ ( \
+ mb1 \
+ "1: ldq_l %[__ret],%[__mem]\n" \
+ " mov %[__val],%[__tmp]\n" \
+ " stq_c %[__tmp],%[__mem]\n" \
+ " beq %[__tmp],1b\n" \
+ mb2 \
+ : [__ret] "=&r" (__ret), \
+ [__tmp] "=&r" (__tmp) \
+ : [__mem] "m" (*(mem)), \
+ [__val] "Ir" (value) \
+ : "memory"); \
+ __ret; })
+
+#define atomic_exchange_acq(mem, value) \
+ __atomic_val_bysize (__arch_exchange, int, mem, value, "", __MB)
+
+#define atomic_exchange_rel(mem, value) \
+ __atomic_val_bysize (__arch_exchange, int, mem, value, __MB, "")
+
+
+/* Atomically add value and return the previous (unincremented) value. */
+
+#define __arch_exchange_and_add_8_int(mem, value, mb1, mb2) \
+ ({ __builtin_trap (); 0; })
+
+#define __arch_exchange_and_add_16_int(mem, value, mb1, mb2) \
+ ({ __builtin_trap (); 0; })
+
+#define __arch_exchange_and_add_32_int(mem, value, mb1, mb2) \
+({ \
+ signed int __ret, __tmp; \
+ __asm__ __volatile__ ( \
+ mb1 \
+ "1: ldl_l %[__ret],%[__mem]\n" \
+ " addl %[__ret],%[__val],%[__tmp]\n" \
+ " stl_c %[__tmp],%[__mem]\n" \
+ " beq %[__tmp],1b\n" \
+ mb2 \
+ : [__ret] "=&r" (__ret), \
+ [__tmp] "=&r" (__tmp) \
+ : [__mem] "m" (*(mem)), \
+ [__val] "Ir" ((signed int)(value)) \
+ : "memory"); \
+ __ret; })
+
+#define __arch_exchange_and_add_64_int(mem, value, mb1, mb2) \
+({ \
+ unsigned long __ret, __tmp; \
+ __asm__ __volatile__ ( \
+ mb1 \
+ "1: ldq_l %[__ret],%[__mem]\n" \
+ " addq %[__ret],%[__val],%[__tmp]\n" \
+ " stq_c %[__tmp],%[__mem]\n" \
+ " beq %[__tmp],1b\n" \
+ mb2 \
+ : [__ret] "=&r" (__ret), \
+ [__tmp] "=&r" (__tmp) \
+ : [__mem] "m" (*(mem)), \
+ [__val] "Ir" ((unsigned long)(value)) \
+ : "memory"); \
+ __ret; })
+
+/* ??? Barrier semantics for atomic_exchange_and_add appear to be
+ undefined. Use full barrier for now, as that's safe. */
+#define atomic_exchange_and_add(mem, value) \
+ __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, __MB, __MB)
+
+
+/* ??? Blah, I'm lazy. Implement these later. Can do better than the
+ compare-and-exchange loop provided by generic code.
+
+#define atomic_decrement_if_positive(mem)
+#define atomic_bit_test_set(mem, bit)
+
+*/
+
+#ifndef UP
+# define atomic_full_barrier() __asm ("mb" : : : "memory");
+# define atomic_read_barrier() __asm ("mb" : : : "memory");
+# define atomic_write_barrier() __asm ("wmb" : : : "memory");
+#endif
diff --git a/libc/sysdeps/alpha/bits/endian.h b/libc/sysdeps/alpha/bits/endian.h
new file mode 100644
index 000000000..8a16e14e2
--- /dev/null
+++ b/libc/sysdeps/alpha/bits/endian.h
@@ -0,0 +1,7 @@
+/* Alpha is little-endian. */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
diff --git a/libc/sysdeps/alpha/bits/link.h b/libc/sysdeps/alpha/bits/link.h
new file mode 100644
index 000000000..429faff43
--- /dev/null
+++ b/libc/sysdeps/alpha/bits/link.h
@@ -0,0 +1,69 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+
+/* Registers for entry into PLT on Alpha. */
+typedef struct La_alpha_regs
+{
+ uint64_t lr_r26;
+ uint64_t lr_sp;
+ uint64_t lr_r16;
+ uint64_t lr_r17;
+ uint64_t lr_r18;
+ uint64_t lr_r19;
+ uint64_t lr_r20;
+ uint64_t lr_r21;
+ double lr_f16;
+ double lr_f17;
+ double lr_f18;
+ double lr_f19;
+ double lr_f20;
+ double lr_f21;
+} La_alpha_regs;
+
+/* Return values for calls from PLT on Alpha. */
+typedef struct La_alpha_retval
+{
+ uint64_t lrv_r0;
+ uint64_t lrv_r1;
+ double lrv_f0;
+ double lrv_f1;
+} La_alpha_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf64_Addr la_alpha_gnu_pltenter (Elf64_Sym *__sym, unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_alpha_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_alpha_gnu_pltexit (Elf64_Sym *__sym, unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_alpha_regs *__inregs,
+ La_alpha_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
diff --git a/libc/sysdeps/alpha/bits/mathdef.h b/libc/sysdeps/alpha/bits/mathdef.h
new file mode 100644
index 000000000..cbfaf68e2
--- /dev/null
+++ b/libc/sysdeps/alpha/bits/mathdef.h
@@ -0,0 +1,80 @@
+/* Copyright (C) 1997,1998,1999,2000,2003,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+/* FIXME! This file describes properties of the compiler, not the machine;
+ it should not be part of libc! */
+
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
+# ifdef __GNUC__
+# if __STDC__ == 1
+
+/* In GNU or ANSI mode, gcc leaves `float' expressions as-is. */
+typedef float float_t;
+typedef double double_t;
+
+# else
+
+/* For `gcc -traditional', `float' expressions are evaluated as `double'. */
+typedef double float_t;
+typedef double double_t;
+
+# endif
+# else
+
+/* Wild guess at types for float_t and double_t. */
+typedef double float_t;
+typedef double double_t;
+
+# endif
+
+/* The values returned by `ilogb' for 0 and NaN respectively. */
+# define FP_ILOGB0 (-2147483647)
+# define FP_ILOGBNAN (2147483647)
+
+#endif /* ISO C99 && MATH_H */
+
+#if defined _COMPLEX_H && !defined _COMPLEX_H_MATHDEF
+# define _COMPLEX_H_MATHDEF 1
+# if defined(__GNUC__) && !__GNUC_PREREQ(3,4)
+
+/* Due to an ABI change, we need to remap the complex float symbols. */
+# define _Mdouble_ float
+# define __MATHCALL(function, args) \
+ __MATHDECL (_Complex float, function, args)
+# define __MATHDECL(type, function, args) \
+ __MATHDECL_1(type, function##f, args, __c1_##function##f); \
+ __MATHDECL_1(type, __##function##f, args, __c1_##function##f)
+# define __MATHDECL_1(type, function, args, alias) \
+ extern type function args __asm__(#alias) __THROW
+
+# include <bits/cmathcalls.h>
+
+# undef _Mdouble_
+# undef __MATHCALL
+# undef __MATHDECL
+# undef __MATHDECL_1
+
+# endif /* GNUC before 3.4 */
+#endif /* COMPLEX_H */
diff --git a/libc/sysdeps/alpha/bits/setjmp.h b/libc/sysdeps/alpha/bits/setjmp.h
new file mode 100644
index 000000000..eb0b478fb
--- /dev/null
+++ b/libc/sysdeps/alpha/bits/setjmp.h
@@ -0,0 +1,62 @@
+/* Define the machine-dependent type `jmp_buf'. Alpha version.
+ Copyright (C) 1992,1997,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H 1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+/* The previous bits/setjmp.h had __jmp_buf defined as a structure.
+ We use an array of 'long int' instead, to make writing the
+ assembler easier. Naturally, user code should not depend on
+ either representation. */
+
+/*
+ * Integer registers:
+ * $0 is the return value (va);
+ * $1-$8, $22-$25, $28 are call-used (t0-t7, t8-t11, at);
+ * $9-$14 we save here (s0-s5);
+ * $15 is the FP and we save it here (fp or s6);
+ * $16-$21 are input arguments (call-used) (a0-a5);
+ * $26 is the return PC and we save it here (ra);
+ * $27 is the procedure value (i.e., the address of __setjmp) (pv or t12);
+ * $29 is the global pointer, which the caller will reconstruct
+ * from the return address restored in $26 (gp);
+ * $30 is the stack pointer and we save it here (sp);
+ * $31 is always zero (zero).
+ *
+ * Floating-point registers:
+ * $f0 is the floating return value;
+ * $f1, $f10-$f15, $f22-$f30 are call-used;
+ * $f2-$f9 we save here;
+ * $f16-$21 are input args (call-used);
+ * $f31 is always zero.
+ *
+ * Note that even on Alpha hardware that does not have an FPU (there
+ * isn't such a thing currently) it is required to implement the FP
+ * registers.
+ */
+
+#ifndef __ASSEMBLY__
+typedef long int __jmp_buf[17];
+#endif
+
+#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/alpha/bsd-_setjmp.S b/libc/sysdeps/alpha/bsd-_setjmp.S
new file mode 100644
index 000000000..4e6a2da56
--- /dev/null
+++ b/libc/sysdeps/alpha/bsd-_setjmp.S
@@ -0,0 +1 @@
+/* _setjmp is in setjmp.S */
diff --git a/libc/sysdeps/alpha/bsd-setjmp.S b/libc/sysdeps/alpha/bsd-setjmp.S
new file mode 100644
index 000000000..1da848d2f
--- /dev/null
+++ b/libc/sysdeps/alpha/bsd-setjmp.S
@@ -0,0 +1 @@
+/* setjmp is in setjmp.S */
diff --git a/libc/sysdeps/alpha/bzero.S b/libc/sysdeps/alpha/bzero.S
new file mode 100644
index 000000000..87e575bab
--- /dev/null
+++ b/libc/sysdeps/alpha/bzero.S
@@ -0,0 +1,120 @@
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu)
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Fill a block of memory with zeros. Optimized for the Alpha architecture:
+
+ - memory accessed as aligned quadwords only
+ - destination memory not read unless needed for good cache behaviour
+ - basic blocks arranged to optimize branch prediction for full-quadword
+ aligned memory blocks.
+ - partial head and tail quadwords constructed with byte-mask instructions
+
+ This is generally scheduled for the EV5 (got to look out for my own
+ interests :-), but with EV4 needs in mind. There *should* be no more
+ stalls for the EV4 than there are for the EV5.
+*/
+
+
+#include <sysdep.h>
+
+ .set noat
+ .set noreorder
+
+ .text
+
+/* There is a problem with either gdb (as of 4.16) or gas (as of 2.7) that
+ doesn't like putting the entry point for a procedure somewhere in the
+ middle of the procedure descriptor. Work around this by putting the main
+ loop in its own procedure descriptor. */
+
+ /* On entry to this basic block:
+ t3 == loop counter
+ t4 == bytes in partial final word
+ a0 == possibly misaligned destination pointer */
+
+ .ent bzero_loop
+ .align 3
+bzero_loop:
+ .frame sp, 0, ra, 0
+ .prologue 0
+
+ beq t3, $tail #
+ blbc t3, 0f # skip single store if count even
+
+ stq_u zero, 0(a0) # e0 : store one word
+ subq t3, 1, t3 # .. e1 :
+ addq a0, 8, a0 # e0 :
+ beq t3, $tail # .. e1 :
+
+0: stq_u zero, 0(a0) # e0 : store two words
+ subq t3, 2, t3 # .. e1 :
+ stq_u zero, 8(a0) # e0 :
+ addq a0, 16, a0 # .. e1 :
+ bne t3, 0b # e1 :
+
+$tail: bne t4, 1f # is there a tail to do?
+ ret # no
+
+1: ldq_u t0, 0(a0) # yes, load original data
+ mskqh t0, t4, t0 #
+ stq_u t0, 0(a0) #
+ ret #
+
+ .end bzero_loop
+
+ENTRY(__bzero)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ mov a0, v0 # e0 : move return value in place
+ beq a1, $done # .. e1 : early exit for zero-length store
+ and a0, 7, t1 # e0 :
+ addq a1, t1, a1 # e1 : add dest misalignment to count
+ srl a1, 3, t3 # e0 : loop = count >> 3
+ and a1, 7, t4 # .. e1 : find number of bytes in tail
+ unop # :
+ beq t1, bzero_loop # e1 : aligned head, jump right in
+
+ ldq_u t0, 0(a0) # e0 : load original data to mask into
+ cmpult a1, 8, t2 # .. e1 : is this a sub-word set?
+ bne t2, $oneq # e1 :
+
+ mskql t0, a0, t0 # e0 : we span words. finish this partial
+ subq t3, 1, t3 # e0 :
+ addq a0, 8, a0 # .. e1 :
+ stq_u t0, -8(a0) # e0 :
+ br bzero_loop # .. e1 :
+
+ .align 3
+$oneq:
+ mskql t0, a0, t2 # e0 :
+ mskqh t0, a1, t3 # e0 :
+ or t2, t3, t0 # e1 :
+ stq_u t0, 0(a0) # e0 :
+
+$done: ret
+
+ END(__bzero)
+weak_alias (__bzero, bzero)
diff --git a/libc/sysdeps/alpha/div.S b/libc/sysdeps/alpha/div.S
new file mode 100644
index 000000000..d1a724d37
--- /dev/null
+++ b/libc/sysdeps/alpha/div.S
@@ -0,0 +1,88 @@
+/* Copyright (C) 1996, 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "div_libc.h"
+
+#undef FRAME
+#ifdef __alpha_fix__
+#define FRAME 0
+#else
+#define FRAME 16
+#endif
+
+ .set noat
+
+ .align 4
+ .globl div
+ .ent div
+div:
+ .frame sp, FRAME, ra
+#if FRAME > 0
+ lda sp, -FRAME(sp)
+#endif
+#ifdef PROF
+ .set macro
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set nomacro
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ beq $18, $divbyzero
+ excb
+ mf_fpcr $f10
+
+ _ITOFT2 $17, $f0, 0, $18, $f1, 8
+
+ cvtqt $f0, $f0
+ cvtqt $f1, $f1
+ divt/c $f0, $f1, $f0
+ cvttq/c $f0, $f0
+ excb
+ mt_fpcr $f10
+ _FTOIT $f0, $0, 0
+
+ mull $0, $18, $1
+ subl $17, $1, $1
+
+ stl $0, 0(a0)
+ stl $1, 4(a0)
+ mov a0, v0
+
+#if FRAME > 0
+ lda sp, FRAME(sp)
+#endif
+ ret
+
+$divbyzero:
+ mov a0, v0
+ lda a0, GEN_INTDIV
+ call_pal PAL_gentrap
+ stl zero, 0(v0)
+ stl zero, 4(v0)
+
+#if FRAME > 0
+ lda sp, FRAME(sp)
+#endif
+ ret
+
+ .end div
diff --git a/libc/sysdeps/alpha/div_libc.h b/libc/sysdeps/alpha/div_libc.h
new file mode 100644
index 000000000..b731b02e2
--- /dev/null
+++ b/libc/sysdeps/alpha/div_libc.h
@@ -0,0 +1,164 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Common bits for implementing software divide. */
+
+#include <sysdep.h>
+#ifdef __linux__
+# include <asm/gentrap.h>
+# include <asm/pal.h>
+#else
+# include <machine/pal.h>
+#endif
+
+/* These are not normal C functions. Argument registers are t10 and t11;
+ the result goes in t12; the return address is in t9. Only t12 and AT
+ may be clobbered. */
+#define X t10
+#define Y t11
+#define RV t12
+#define RA t9
+
+/* The secureplt format does not allow the division routines to be called
+ via plt; there aren't enough registers free to be clobbered. Avoid
+ setting the symbol type to STT_FUNC, so that the linker won't be tempted
+ to create a plt entry. */
+#define funcnoplt notype
+
+/* None of these functions should use implicit anything. */
+ .set nomacro
+ .set noat
+
+/* Code fragment to invoke _mcount for profiling. This should be invoked
+ directly after allocation of the stack frame. */
+.macro CALL_MCOUNT
+#ifdef PROF
+ stq ra, 0(sp)
+ stq pv, 8(sp)
+ stq gp, 16(sp)
+ cfi_rel_offset (ra, 0)
+ cfi_rel_offset (pv, 8)
+ cfi_rel_offset (gp, 16)
+ br AT, 1f
+ .set macro
+1: ldgp gp, 0(AT)
+ mov RA, ra
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set nomacro
+ ldq ra, 0(sp)
+ ldq pv, 8(sp)
+ ldq gp, 16(sp)
+ cfi_restore (ra)
+ cfi_restore (pv)
+ cfi_restore (gp)
+ /* Realign subsequent code with what we'd have without this
+ macro at all. This means aligned with one arithmetic insn
+ used within the bundle. */
+ .align 4
+ nop
+#endif
+.endm
+
+/* In order to make the below work, all top-level divide routines must
+ use the same frame size. */
+#define FRAME 64
+
+/* Code fragment to generate an integer divide-by-zero fault. When
+ building libc.so, we arrange for there to be one copy of this code
+ placed late in the dso, such that all branches are forward. When
+ building libc.a, we use multiple copies to avoid having an out of
+ range branch. Users should jump to DIVBYZERO. */
+
+.macro DO_DIVBYZERO
+#ifdef PIC
+#define DIVBYZERO __divbyzero
+ .section .gnu.linkonce.t.divbyzero, "ax", @progbits
+ .globl __divbyzero
+ .type __divbyzero, @function
+ .usepv __divbyzero, no
+ .hidden __divbyzero
+#else
+#define DIVBYZERO $divbyzero
+#endif
+
+ .align 4
+DIVBYZERO:
+ cfi_startproc
+ cfi_return_column (RA)
+ cfi_def_cfa_offset (FRAME)
+
+ mov a0, RV
+ unop
+ lda a0, GEN_INTDIV
+ call_pal PAL_gentrap
+
+ mov RV, a0
+ clr RV
+ lda sp, FRAME(sp)
+ cfi_def_cfa_offset (0)
+ ret $31, (RA), 1
+
+ cfi_endproc
+ .size DIVBYZERO, .-DIVBYZERO
+.endm
+
+/* Like the ev6 instructions, but fall back to stack use on prior machines. */
+
+ .arch ev6
+
+.macro _ITOFS gr, fr, slot
+#ifdef __alpha_fix__
+ itofs \gr, \fr
+#else
+ stl \gr, \slot(sp)
+ lds \fr, \slot(sp)
+#endif
+.endm
+
+.macro _ITOFT gr, fr, slot
+#ifdef __alpha_fix__
+ itoft \gr, \fr
+#else
+ stq \gr, \slot(sp)
+ ldt \fr, \slot(sp)
+#endif
+.endm
+
+.macro _FTOIT fr, gr, slot
+#ifdef __alpha_fix__
+ ftoit \fr, \gr
+#else
+ stt \fr, \slot(sp)
+ ldq \gr, \slot(sp)
+#endif
+.endm
+
+/* Similarly, but move two registers. Schedules better for pre-ev6. */
+
+.macro _ITOFT2 gr1, fr1, slot1, gr2, fr2, slot2
+#ifdef __alpha_fix__
+ itoft \gr1, \fr1
+ itoft \gr2, \fr2
+#else
+ stq \gr1, \slot1(sp)
+ stq \gr2, \slot2(sp)
+ ldt \fr1, \slot1(sp)
+ ldt \fr2, \slot2(sp)
+#endif
+.endm
diff --git a/libc/sysdeps/alpha/divl.S b/libc/sysdeps/alpha/divl.S
new file mode 100644
index 000000000..9bac0450d
--- /dev/null
+++ b/libc/sysdeps/alpha/divl.S
@@ -0,0 +1,84 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "div_libc.h"
+
+/* 32-bit signed int divide. This is not a normal C function. Argument
+ registers are t10 and t11, the result goes in t12. Only t12 and AT may
+ be clobbered.
+
+ The FPU can handle all input values except zero. Whee!
+
+ The FPCR save/restore is due to the fact that the EV6 _will_ set FPCR_INE
+ for cvttq/c even without /sui being set. It will not, however, properly
+ raise the exception, so we don't have to worry about FPCR_INED being clear
+ and so dying by SIGFPE. */
+
+#ifndef EXTEND
+#define EXTEND(S,D) sextl S, D
+#endif
+
+ .text
+ .align 4
+ .globl __divl
+ .type __divl, @funcnoplt
+ .usepv __divl, no
+
+ cfi_startproc
+ cfi_return_column (RA)
+__divl:
+ lda sp, -FRAME(sp)
+ cfi_def_cfa_offset (FRAME)
+ CALL_MCOUNT
+ stt $f0, 0(sp)
+ excb
+ beq Y, DIVBYZERO
+
+ stt $f1, 8(sp)
+ stt $f2, 16(sp)
+ cfi_rel_offset ($f0, 0)
+ cfi_rel_offset ($f1, 8)
+ cfi_rel_offset ($f2, 16)
+ mf_fpcr $f2
+
+ EXTEND (X, RV)
+ EXTEND (Y, AT)
+ _ITOFT2 RV, $f0, 24, AT, $f1, 32
+ cvtqt $f0, $f0
+ cvtqt $f1, $f1
+ divt/c $f0, $f1, $f0
+ cvttq/c $f0, $f0
+ excb
+ mt_fpcr $f2
+ _FTOIT $f0, RV, 24
+
+ ldt $f0, 0(sp)
+ ldt $f1, 8(sp)
+ ldt $f2, 16(sp)
+ lda sp, FRAME(sp)
+ cfi_restore ($f0)
+ cfi_restore ($f1)
+ cfi_restore ($f2)
+ cfi_def_cfa_offset (0)
+ sextl RV, RV
+ ret $31, (RA), 1
+
+ cfi_endproc
+ .size __divl, .-__divl
+
+ DO_DIVBYZERO
diff --git a/libc/sysdeps/alpha/divlu.S b/libc/sysdeps/alpha/divlu.S
new file mode 100644
index 000000000..5c54bb54c
--- /dev/null
+++ b/libc/sysdeps/alpha/divlu.S
@@ -0,0 +1,4 @@
+#define UNSIGNED
+#define EXTEND(S,D) zapnot S, 15, D
+#define __divl __divlu
+#include <divl.S>
diff --git a/libc/sysdeps/alpha/divq.S b/libc/sysdeps/alpha/divq.S
new file mode 100644
index 000000000..d2ed2c5af
--- /dev/null
+++ b/libc/sysdeps/alpha/divq.S
@@ -0,0 +1,274 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "div_libc.h"
+
+
+/* 64-bit signed long divide. These are not normal C functions. Argument
+ registers are t10 and t11, the result goes in t12. Only t12 and AT may
+ be clobbered.
+
+ Theory of operation here is that we can use the FPU divider for virtually
+ all operands that we see: all dividend values between -2**53 and 2**53-1
+ can be computed directly. Note that divisor values need not be checked
+ against that range because the rounded fp value will be close enough such
+ that the quotient is < 1, which will properly be truncated to zero when we
+ convert back to integer.
+
+ When the dividend is outside the range for which we can compute exact
+ results, we use the fp quotent as an estimate from which we begin refining
+ an exact integral value. This reduces the number of iterations in the
+ shift-and-subtract loop significantly.
+
+ The FPCR save/restore is due to the fact that the EV6 _will_ set FPCR_INE
+ for cvttq/c even without /sui being set. It will not, however, properly
+ raise the exception, so we don't have to worry about FPCR_INED being clear
+ and so dying by SIGFPE. */
+
+ .text
+ .align 4
+ .globl __divq
+ .type __divq, @funcnoplt
+ .usepv __divq, no
+
+ cfi_startproc
+ cfi_return_column (RA)
+__divq:
+ lda sp, -FRAME(sp)
+ cfi_def_cfa_offset (FRAME)
+ CALL_MCOUNT
+
+ /* Get the fp divide insn issued as quickly as possible. After
+ that's done, we have at least 22 cycles until its results are
+ ready -- all the time in the world to figure out how we're
+ going to use the results. */
+ stt $f0, 0(sp)
+ excb
+ beq Y, DIVBYZERO
+
+ stt $f1, 8(sp)
+ stt $f3, 48(sp)
+ cfi_rel_offset ($f0, 0)
+ cfi_rel_offset ($f1, 8)
+ cfi_rel_offset ($f3, 48)
+ mf_fpcr $f3
+
+ _ITOFT2 X, $f0, 16, Y, $f1, 24
+ cvtqt $f0, $f0
+ cvtqt $f1, $f1
+ divt/c $f0, $f1, $f0
+
+ /* Check to see if X fit in the double as an exact value. */
+ sll X, (64-53), AT
+ ldt $f1, 8(sp)
+ sra AT, (64-53), AT
+ cmpeq X, AT, AT
+ beq AT, $x_big
+
+ /* If we get here, we're expecting exact results from the division.
+ Do nothing else besides convert and clean up. */
+ cvttq/c $f0, $f0
+ excb
+ mt_fpcr $f3
+ _FTOIT $f0, RV, 16
+
+ ldt $f0, 0(sp)
+ ldt $f3, 48(sp)
+ cfi_restore ($f1)
+ cfi_remember_state
+ cfi_restore ($f0)
+ cfi_restore ($f3)
+ cfi_def_cfa_offset (0)
+ lda sp, FRAME(sp)
+ ret $31, (RA), 1
+
+ .align 4
+ cfi_restore_state
+$x_big:
+ /* If we get here, X is large enough that we don't expect exact
+ results, and neither X nor Y got mis-translated for the fp
+ division. Our task is to take the fp result, figure out how
+ far it's off from the correct result and compute a fixup. */
+ stq t0, 16(sp)
+ stq t1, 24(sp)
+ stq t2, 32(sp)
+ stq t5, 40(sp)
+ cfi_rel_offset (t0, 16)
+ cfi_rel_offset (t1, 24)
+ cfi_rel_offset (t2, 32)
+ cfi_rel_offset (t5, 40)
+
+#define Q RV /* quotient */
+#define R t0 /* remainder */
+#define SY t1 /* scaled Y */
+#define S t2 /* scalar */
+#define QY t3 /* Q*Y */
+
+ /* The fixup code below can only handle unsigned values. */
+ or X, Y, AT
+ mov $31, t5
+ blt AT, $fix_sign_in
+$fix_sign_in_ret1:
+ cvttq/c $f0, $f0
+
+ _FTOIT $f0, Q, 8
+ .align 3
+$fix_sign_in_ret2:
+ ldt $f0, 0(sp)
+ stq t3, 0(sp)
+ cfi_restore ($f0)
+ cfi_rel_offset (t3, 0)
+
+ mulq Q, Y, QY
+ excb
+ stq t4, 8(sp)
+ mt_fpcr $f3
+ cfi_rel_offset (t4, 8)
+
+ subq QY, X, R
+ mov Y, SY
+ mov 1, S
+ bgt R, $q_high
+
+$q_high_ret:
+ subq X, QY, R
+ mov Y, SY
+ mov 1, S
+ bgt R, $q_low
+
+$q_low_ret:
+ ldq t0, 16(sp)
+ ldq t1, 24(sp)
+ ldq t2, 32(sp)
+ bne t5, $fix_sign_out
+
+$fix_sign_out_ret:
+ ldq t3, 0(sp)
+ ldq t4, 8(sp)
+ ldq t5, 40(sp)
+ ldt $f3, 48(sp)
+ lda sp, FRAME(sp)
+ cfi_remember_state
+ cfi_restore (t0)
+ cfi_restore (t1)
+ cfi_restore (t2)
+ cfi_restore (t3)
+ cfi_restore (t4)
+ cfi_restore (t5)
+ cfi_restore ($f3)
+ cfi_def_cfa_offset (0)
+ ret $31, (RA), 1
+
+ .align 4
+ cfi_restore_state
+ /* The quotient that we computed was too large. We need to reduce
+ it by S such that Y*S >= R. Obviously the closer we get to the
+ correct value the better, but overshooting high is ok, as we'll
+ fix that up later. */
+0:
+ addq SY, SY, SY
+ addq S, S, S
+$q_high:
+ cmpult SY, R, AT
+ bne AT, 0b
+
+ subq Q, S, Q
+ unop
+ subq QY, SY, QY
+ br $q_high_ret
+
+ .align 4
+ /* The quotient that we computed was too small. Divide Y by the
+ current remainder (R) and add that to the existing quotient (Q).
+ The expectation, of course, is that R is much smaller than X. */
+ /* Begin with a shift-up loop. Compute S such that Y*S >= R. We
+ already have a copy of Y in SY and the value 1 in S. */
+0:
+ addq SY, SY, SY
+ addq S, S, S
+$q_low:
+ cmpult SY, R, AT
+ bne AT, 0b
+
+ /* Shift-down and subtract loop. Each iteration compares our scaled
+ Y (SY) with the remainder (R); if SY <= R then X is divisible by
+ Y's scalar (S) so add it to the quotient (Q). */
+2: addq Q, S, t3
+ srl S, 1, S
+ cmpule SY, R, AT
+ subq R, SY, t4
+
+ cmovne AT, t3, Q
+ cmovne AT, t4, R
+ srl SY, 1, SY
+ bne S, 2b
+
+ br $q_low_ret
+
+ .align 4
+$fix_sign_in:
+ /* If we got here, then X|Y is negative. Need to adjust everything
+ such that we're doing unsigned division in the fixup loop. */
+ /* T5 records the changes we had to make:
+ bit 0: set if result should be negative.
+ bit 2: set if X was negated.
+ bit 3: set if Y was negated.
+ */
+ xor X, Y, AT
+ cmplt AT, 0, t5
+ cmplt X, 0, AT
+ negq X, t0
+
+ s4addq AT, t5, t5
+ cmovne AT, t0, X
+ cmplt Y, 0, AT
+ negq Y, t0
+
+ s8addq AT, t5, t5
+ cmovne AT, t0, Y
+ unop
+ blbc t5, $fix_sign_in_ret1
+
+ cvttq/c $f0, $f0
+ _FTOIT $f0, Q, 8
+ .align 3
+ negq Q, Q
+ br $fix_sign_in_ret2
+
+ .align 4
+$fix_sign_out:
+ /* Now we get to undo what we did above. */
+ /* ??? Is this really faster than just increasing the size of
+ the stack frame and storing X and Y in memory? */
+ and t5, 8, AT
+ negq Y, t4
+ cmovne AT, t4, Y
+
+ and t5, 4, AT
+ negq X, t4
+ cmovne AT, t4, X
+
+ negq RV, t4
+ cmovlbs t5, t4, RV
+
+ br $fix_sign_out_ret
+
+ cfi_endproc
+ .size __divq, .-__divq
+
+ DO_DIVBYZERO
diff --git a/libc/sysdeps/alpha/divqu.S b/libc/sysdeps/alpha/divqu.S
new file mode 100644
index 000000000..ef3cdb1b2
--- /dev/null
+++ b/libc/sysdeps/alpha/divqu.S
@@ -0,0 +1,257 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "div_libc.h"
+
+
+/* 64-bit unsigned long divide. These are not normal C functions. Argument
+ registers are t10 and t11, the result goes in t12. Only t12 and AT may be
+ clobbered.
+
+ Theory of operation here is that we can use the FPU divider for virtually
+ all operands that we see: all dividend values between -2**53 and 2**53-1
+ can be computed directly. Note that divisor values need not be checked
+ against that range because the rounded fp value will be close enough such
+ that the quotient is < 1, which will properly be truncated to zero when we
+ convert back to integer.
+
+ When the dividend is outside the range for which we can compute exact
+ results, we use the fp quotent as an estimate from which we begin refining
+ an exact integral value. This reduces the number of iterations in the
+ shift-and-subtract loop significantly.
+
+ The FPCR save/restore is due to the fact that the EV6 _will_ set FPCR_INE
+ for cvttq/c even without /sui being set. It will not, however, properly
+ raise the exception, so we don't have to worry about FPCR_INED being clear
+ and so dying by SIGFPE. */
+
+ .text
+ .align 4
+ .globl __divqu
+ .type __divqu, @funcnoplt
+ .usepv __divqu, no
+
+ cfi_startproc
+ cfi_return_column (RA)
+__divqu:
+ lda sp, -FRAME(sp)
+ cfi_def_cfa_offset (FRAME)
+ CALL_MCOUNT
+
+ /* Get the fp divide insn issued as quickly as possible. After
+ that's done, we have at least 22 cycles until its results are
+ ready -- all the time in the world to figure out how we're
+ going to use the results. */
+ stt $f0, 0(sp)
+ excb
+ beq Y, DIVBYZERO
+
+ stt $f1, 8(sp)
+ stt $f3, 48(sp)
+ cfi_rel_offset ($f0, 0)
+ cfi_rel_offset ($f1, 8)
+ cfi_rel_offset ($f3, 48)
+ mf_fpcr $f3
+
+ _ITOFT2 X, $f0, 16, Y, $f1, 24
+ cvtqt $f0, $f0
+ cvtqt $f1, $f1
+ blt X, $x_is_neg
+ divt/c $f0, $f1, $f0
+
+ /* Check to see if Y was mis-converted as signed value. */
+ ldt $f1, 8(sp)
+ blt Y, $y_is_neg
+
+ /* Check to see if X fit in the double as an exact value. */
+ srl X, 53, AT
+ bne AT, $x_big
+
+ /* If we get here, we're expecting exact results from the division.
+ Do nothing else besides convert and clean up. */
+ cvttq/c $f0, $f0
+ excb
+ mt_fpcr $f3
+ _FTOIT $f0, RV, 16
+
+ ldt $f0, 0(sp)
+ ldt $f3, 48(sp)
+ cfi_remember_state
+ cfi_restore ($f0)
+ cfi_restore ($f1)
+ cfi_restore ($f3)
+ cfi_def_cfa_offset (0)
+ lda sp, FRAME(sp)
+ ret $31, (RA), 1
+
+ .align 4
+ cfi_restore_state
+$x_is_neg:
+ /* If we get here, X is so big that bit 63 is set, which made the
+ conversion come out negative. Fix it up lest we not even get
+ a good estimate. */
+ ldah AT, 0x5f80 /* 2**64 as float. */
+ stt $f2, 24(sp)
+ cfi_rel_offset ($f2, 24)
+ _ITOFS AT, $f2, 16
+
+ .align 4
+ addt $f0, $f2, $f0
+ unop
+ divt/c $f0, $f1, $f0
+ unop
+
+ /* Ok, we've now the divide issued. Continue with other checks. */
+ ldt $f1, 8(sp)
+ unop
+ ldt $f2, 24(sp)
+ blt Y, $y_is_neg
+ cfi_restore ($f1)
+ cfi_restore ($f2)
+ cfi_remember_state /* for y_is_neg */
+
+ .align 4
+$x_big:
+ /* If we get here, X is large enough that we don't expect exact
+ results, and neither X nor Y got mis-translated for the fp
+ division. Our task is to take the fp result, figure out how
+ far it's off from the correct result and compute a fixup. */
+ stq t0, 16(sp)
+ stq t1, 24(sp)
+ stq t2, 32(sp)
+ stq t3, 40(sp)
+ cfi_rel_offset (t0, 16)
+ cfi_rel_offset (t1, 24)
+ cfi_rel_offset (t2, 32)
+ cfi_rel_offset (t3, 40)
+
+#define Q RV /* quotient */
+#define R t0 /* remainder */
+#define SY t1 /* scaled Y */
+#define S t2 /* scalar */
+#define QY t3 /* Q*Y */
+
+ cvttq/c $f0, $f0
+ _FTOIT $f0, Q, 8
+ mulq Q, Y, QY
+
+ .align 4
+ stq t4, 8(sp)
+ excb
+ ldt $f0, 0(sp)
+ mt_fpcr $f3
+ cfi_rel_offset (t4, 8)
+ cfi_restore ($f0)
+
+ subq QY, X, R
+ mov Y, SY
+ mov 1, S
+ bgt R, $q_high
+
+$q_high_ret:
+ subq X, QY, R
+ mov Y, SY
+ mov 1, S
+ bgt R, $q_low
+
+$q_low_ret:
+ ldq t4, 8(sp)
+ ldq t0, 16(sp)
+ ldq t1, 24(sp)
+ ldq t2, 32(sp)
+
+ ldq t3, 40(sp)
+ ldt $f3, 48(sp)
+ lda sp, FRAME(sp)
+ cfi_remember_state
+ cfi_restore (t0)
+ cfi_restore (t1)
+ cfi_restore (t2)
+ cfi_restore (t3)
+ cfi_restore (t4)
+ cfi_restore ($f3)
+ cfi_def_cfa_offset (0)
+ ret $31, (RA), 1
+
+ .align 4
+ cfi_restore_state
+ /* The quotient that we computed was too large. We need to reduce
+ it by S such that Y*S >= R. Obviously the closer we get to the
+ correct value the better, but overshooting high is ok, as we'll
+ fix that up later. */
+0:
+ addq SY, SY, SY
+ addq S, S, S
+$q_high:
+ cmpult SY, R, AT
+ bne AT, 0b
+
+ subq Q, S, Q
+ unop
+ subq QY, SY, QY
+ br $q_high_ret
+
+ .align 4
+ /* The quotient that we computed was too small. Divide Y by the
+ current remainder (R) and add that to the existing quotient (Q).
+ The expectation, of course, is that R is much smaller than X. */
+ /* Begin with a shift-up loop. Compute S such that Y*S >= R. We
+ already have a copy of Y in SY and the value 1 in S. */
+0:
+ addq SY, SY, SY
+ addq S, S, S
+$q_low:
+ cmpult SY, R, AT
+ bne AT, 0b
+
+ /* Shift-down and subtract loop. Each iteration compares our scaled
+ Y (SY) with the remainder (R); if SY <= R then X is divisible by
+ Y's scalar (S) so add it to the quotient (Q). */
+2: addq Q, S, t3
+ srl S, 1, S
+ cmpule SY, R, AT
+ subq R, SY, t4
+
+ cmovne AT, t3, Q
+ cmovne AT, t4, R
+ srl SY, 1, SY
+ bne S, 2b
+
+ br $q_low_ret
+
+ .align 4
+ cfi_restore_state
+$y_is_neg:
+ /* If we get here, Y is so big that bit 63 is set. The results
+ from the divide will be completely wrong. Fortunately, the
+ quotient must be either 0 or 1, so just compute it directly. */
+ cmpule Y, X, RV
+ excb
+ mt_fpcr $f3
+ ldt $f0, 0(sp)
+ ldt $f3, 48(sp)
+ lda sp, FRAME(sp)
+ cfi_restore ($f0)
+ cfi_restore ($f3)
+ cfi_def_cfa_offset (0)
+ ret $31, (RA), 1
+
+ cfi_endproc
+ .size __divqu, .-__divqu
+
+ DO_DIVBYZERO
diff --git a/libc/sysdeps/alpha/dl-dtprocnum.h b/libc/sysdeps/alpha/dl-dtprocnum.h
new file mode 100644
index 000000000..67845cdd6
--- /dev/null
+++ b/libc/sysdeps/alpha/dl-dtprocnum.h
@@ -0,0 +1,3 @@
+/* Number of extra dynamic section entries for this architecture. By
+ default there are none. */
+#define DT_THISPROCNUM DT_ALPHA_NUM
diff --git a/libc/sysdeps/alpha/dl-machine.h b/libc/sysdeps/alpha/dl-machine.h
new file mode 100644
index 000000000..88c357ea0
--- /dev/null
+++ b/libc/sysdeps/alpha/dl-machine.h
@@ -0,0 +1,522 @@
+/* Machine-dependent ELF dynamic relocation inline functions. Alpha version.
+ Copyright (C) 1996-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This was written in the absence of an ABI -- don't expect
+ it to remain unchanged. */
+
+#ifndef dl_machine_h
+#define dl_machine_h 1
+
+#define ELF_MACHINE_NAME "alpha"
+
+#include <string.h>
+
+
+/* Mask identifying addresses reserved for the user program,
+ where the dynamic linker should not map anything. */
+#define ELF_MACHINE_USER_ADDRESS_MASK 0x120000000UL
+
+/* Translate a processor specific dynamic tag to the index in l_info array. */
+#define DT_ALPHA(x) (DT_ALPHA_##x - DT_LOPROC + DT_NUM)
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int
+elf_machine_matches_host (const Elf64_Ehdr *ehdr)
+{
+ return ehdr->e_machine == EM_ALPHA;
+}
+
+/* Return the link-time address of _DYNAMIC. The multiple-got-capable
+ linker no longer allocates the first .got entry for this. But not to
+ worry, no special tricks are needed. */
+static inline Elf64_Addr
+elf_machine_dynamic (void)
+{
+#ifndef NO_AXP_MULTI_GOT_LD
+ return (Elf64_Addr) &_DYNAMIC;
+#else
+ register Elf64_Addr *gp __asm__ ("$29");
+ return gp[-4096];
+#endif
+}
+
+/* Return the run-time load address of the shared object. */
+
+static inline Elf64_Addr
+elf_machine_load_address (void)
+{
+ /* This relies on the compiler using gp-relative addresses for static symbols. */
+ static void *dot = &dot;
+ return (void *)&dot - dot;
+}
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int
+elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
+{
+ extern char _dl_runtime_resolve_new[] attribute_hidden;
+ extern char _dl_runtime_profile_new[] attribute_hidden;
+ extern char _dl_runtime_resolve_old[] attribute_hidden;
+ extern char _dl_runtime_profile_old[] attribute_hidden;
+
+ struct pltgot {
+ char *resolve;
+ struct link_map *link;
+ };
+
+ struct pltgot *pg;
+ long secureplt;
+ char *resolve;
+
+ if (map->l_info[DT_JMPREL] == 0 || !lazy)
+ return lazy;
+
+ /* Check to see if we're using the read-only plt form. */
+ secureplt = map->l_info[DT_ALPHA(PLTRO)] != 0;
+
+ /* If the binary uses the read-only secure plt format, PG points to
+ the .got.plt section, which is the right place for ld.so to place
+ its hooks. Otherwise, PG is currently pointing at the start of
+ the plt; the hooks go at offset 16. */
+ pg = (struct pltgot *) D_PTR (map, l_info[DT_PLTGOT]);
+ pg += !secureplt;
+
+ /* This function will be called to perform the relocation. They're
+ not declared as functions to convince the compiler to use gp
+ relative relocations for them. */
+ if (secureplt)
+ resolve = _dl_runtime_resolve_new;
+ else
+ resolve = _dl_runtime_resolve_old;
+
+ if (__builtin_expect (profile, 0))
+ {
+ if (secureplt)
+ resolve = _dl_runtime_profile_new;
+ else
+ resolve = _dl_runtime_profile_old;
+
+ if (GLRO(dl_profile) && _dl_name_match_p (GLRO(dl_profile), map))
+ {
+ /* This is the object we are looking for. Say that we really
+ want profiling and the timers are started. */
+ GL(dl_profile_map) = map;
+ }
+ }
+
+ pg->resolve = resolve;
+ pg->link = map;
+
+ return lazy;
+}
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+
+#define RTLD_START asm ("\
+ .section .text \n\
+ .set at \n\
+ .globl _start \n\
+ .ent _start \n\
+_start: \n\
+ .frame $31,0,$31,0 \n\
+ br $gp, 0f \n\
+0: ldgp $gp, 0($gp) \n\
+ .prologue 0 \n\
+ /* Pass pointer to argument block to _dl_start. */ \n\
+ mov $sp, $16 \n\
+ bsr $26, _dl_start !samegp \n\
+ .end _start \n\
+ /* FALLTHRU */ \n\
+ .globl _dl_start_user \n\
+ .ent _dl_start_user \n\
+_dl_start_user: \n\
+ .frame $31,0,$31,0 \n\
+ .prologue 0 \n\
+ /* Save the user entry point address in s0. */ \n\
+ mov $0, $9 \n\
+ /* See if we were run as a command with the executable \n\
+ file name as an extra leading argument. */ \n\
+ ldah $1, _dl_skip_args($gp) !gprelhigh \n\
+ ldl $1, _dl_skip_args($1) !gprellow \n\
+ bne $1, $fixup_stack \n\
+$fixup_stack_ret: \n\
+ /* The special initializer gets called with the stack \n\
+ just as the application's entry point will see it; \n\
+ it can switch stacks if it moves these contents \n\
+ over. */ \n\
+" RTLD_START_SPECIAL_INIT " \n\
+ /* Call _dl_init(_dl_loaded, argc, argv, envp) to run \n\
+ initializers. */ \n\
+ ldah $16, _rtld_local($gp) !gprelhigh \n\
+ ldq $16, _rtld_local($16) !gprellow \n\
+ ldq $17, 0($sp) \n\
+ lda $18, 8($sp) \n\
+ s8addq $17, 8, $19 \n\
+ addq $19, $18, $19 \n\
+ bsr $26, _dl_init_internal !samegp \n\
+ /* Pass our finalizer function to the user in $0. */ \n\
+ ldah $0, _dl_fini($gp) !gprelhigh \n\
+ lda $0, _dl_fini($0) !gprellow \n\
+ /* Jump to the user's entry point. */ \n\
+ mov $9, $27 \n\
+ jmp ($9) \n\
+$fixup_stack: \n\
+ /* Adjust the stack pointer to skip _dl_skip_args words.\n\
+ This involves copying everything down, since the \n\
+ stack pointer must always be 16-byte aligned. */ \n\
+ ldah $7, _dl_argv_internal($gp) !gprelhigh \n\
+ ldq $2, 0($sp) \n\
+ ldq $5, _dl_argv_internal($7) !gprellow \n\
+ subq $31, $1, $6 \n\
+ subq $2, $1, $2 \n\
+ s8addq $6, $5, $5 \n\
+ mov $sp, $4 \n\
+ s8addq $1, $sp, $3 \n\
+ stq $2, 0($sp) \n\
+ stq $5, _dl_argv_internal($7) !gprellow \n\
+ /* Copy down argv. */ \n\
+0: ldq $5, 8($3) \n\
+ addq $4, 8, $4 \n\
+ addq $3, 8, $3 \n\
+ stq $5, 0($4) \n\
+ bne $5, 0b \n\
+ /* Copy down envp. */ \n\
+1: ldq $5, 8($3) \n\
+ addq $4, 8, $4 \n\
+ addq $3, 8, $3 \n\
+ stq $5, 0($4) \n\
+ bne $5, 1b \n\
+ /* Copy down auxiliary table. */ \n\
+2: ldq $5, 8($3) \n\
+ ldq $6, 16($3) \n\
+ addq $4, 16, $4 \n\
+ addq $3, 16, $3 \n\
+ stq $5, -8($4) \n\
+ stq $6, 0($4) \n\
+ bne $5, 2b \n\
+ br $fixup_stack_ret \n\
+ .end _dl_start_user \n\
+ .set noat \n\
+.previous");
+
+#ifndef RTLD_START_SPECIAL_INIT
+#define RTLD_START_SPECIAL_INIT /* nothing */
+#endif
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry
+ or TLS variables, so undefined references should not be allowed
+ to define the value.
+
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve
+ to one of the main executable's symbols, as for a COPY reloc.
+ This is unused on Alpha. */
+
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#define elf_machine_type_class(type) \
+ (((type) == R_ALPHA_JMP_SLOT \
+ || (type) == R_ALPHA_DTPMOD64 \
+ || (type) == R_ALPHA_DTPREL64 \
+ || (type) == R_ALPHA_TPREL64) * ELF_RTYPE_CLASS_PLT)
+#else
+#define elf_machine_type_class(type) \
+ (((type) == R_ALPHA_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)
+#endif
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_ALPHA_JMP_SLOT
+
+/* The alpha never uses Elf64_Rel relocations. */
+#define ELF_MACHINE_NO_REL 1
+
+/* Fix up the instructions of a PLT entry to invoke the function
+ rather than the dynamic linker. */
+static inline Elf64_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf64_Rela *reloc,
+ Elf64_Addr *got_addr, Elf64_Addr value)
+{
+ const Elf64_Rela *rela_plt;
+ Elf64_Word *plte;
+ long int edisp;
+
+ /* Store the value we are going to load. */
+ *got_addr = value;
+
+ /* If this binary uses the read-only secure plt format, we're done. */
+ if (map->l_info[DT_ALPHA(PLTRO)])
+ return value;
+
+ /* Otherwise we have to modify the plt entry in place to do the branch. */
+
+ /* Recover the PLT entry address by calculating reloc's index into the
+ .rela.plt, and finding that entry in the .plt. */
+ rela_plt = (const Elf64_Rela *) D_PTR (map, l_info[DT_JMPREL]);
+ plte = (Elf64_Word *) (D_PTR (map, l_info[DT_PLTGOT]) + 32);
+ plte += 3 * (reloc - rela_plt);
+
+ /* Find the displacement from the plt entry to the function. */
+ edisp = (long int) (value - (Elf64_Addr)&plte[3]) / 4;
+
+ if (edisp >= -0x100000 && edisp < 0x100000)
+ {
+ /* If we are in range, use br to perfect branch prediction and
+ elide the dependency on the address load. This case happens,
+ e.g., when a shared library call is resolved to the same library. */
+
+ int hi, lo;
+ hi = value - (Elf64_Addr)&plte[0];
+ lo = (short int) hi;
+ hi = (hi - lo) >> 16;
+
+ /* Emit "lda $27,lo($27)" */
+ plte[1] = 0x237b0000 | (lo & 0xffff);
+
+ /* Emit "br $31,function" */
+ plte[2] = 0xc3e00000 | (edisp & 0x1fffff);
+
+ /* Think about thread-safety -- the previous instructions must be
+ committed to memory before the first is overwritten. */
+ __asm__ __volatile__("wmb" : : : "memory");
+
+ /* Emit "ldah $27,hi($27)" */
+ plte[0] = 0x277b0000 | (hi & 0xffff);
+ }
+ else
+ {
+ /* Don't bother with the hint since we already know the hint is
+ wrong. Eliding it prevents the wrong page from getting pulled
+ into the cache. */
+
+ int hi, lo;
+ hi = (Elf64_Addr)got_addr - (Elf64_Addr)&plte[0];
+ lo = (short)hi;
+ hi = (hi - lo) >> 16;
+
+ /* Emit "ldq $27,lo($27)" */
+ plte[1] = 0xa77b0000 | (lo & 0xffff);
+
+ /* Emit "jmp $31,($27)" */
+ plte[2] = 0x6bfb0000;
+
+ /* Think about thread-safety -- the previous instructions must be
+ committed to memory before the first is overwritten. */
+ __asm__ __volatile__("wmb" : : : "memory");
+
+ /* Emit "ldah $27,hi($27)" */
+ plte[0] = 0x277b0000 | (hi & 0xffff);
+ }
+
+ /* At this point, if we've been doing runtime resolution, Icache is dirty.
+ This will be taken care of in _dl_runtime_resolve. If instead we are
+ doing this as part of non-lazy startup relocation, that bit of code
+ hasn't made it into Icache yet, so there's nothing to clean up. */
+
+ return value;
+}
+
+/* Return the final value of a plt relocation. */
+static inline Elf64_Addr
+elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
+ Elf64_Addr value)
+{
+ return value + reloc->r_addend;
+}
+
+/* Names of the architecture-specific auditing callback functions. */
+#define ARCH_LA_PLTENTER alpha_gnu_pltenter
+#define ARCH_LA_PLTEXIT alpha_gnu_pltexit
+
+#endif /* !dl_machine_h */
+
+#ifdef RESOLVE_MAP
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ MAP is the object containing the reloc. */
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map,
+ const Elf64_Rela *reloc,
+ const Elf64_Sym *sym,
+ const struct r_found_version *version,
+ void *const reloc_addr_arg)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+ unsigned long int const r_type = ELF64_R_TYPE (reloc->r_info);
+
+#if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC && !defined SHARED
+ /* This is defined in rtld.c, but nowhere in the static libc.a; make the
+ reference weak so static programs can still link. This declaration
+ cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
+ because rtld.c contains the common defn for _dl_rtld_map, which is
+ incompatible with a weak decl in the same file. */
+ weak_extern (_dl_rtld_map);
+#endif
+
+ /* We cannot use a switch here because we cannot locate the switch
+ jump table until we've self-relocated. */
+
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+ if (__builtin_expect (r_type == R_ALPHA_RELATIVE, 0))
+ {
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ /* Already done in dynamic linker. */
+ if (map != &GL(dl_rtld_map))
+# endif
+ {
+ /* XXX Make some timings. Maybe it's preferable to test for
+ unaligned access and only do it the complex way if necessary. */
+ Elf64_Addr reloc_addr_val;
+
+ /* Load value without causing unaligned trap. */
+ memcpy (&reloc_addr_val, reloc_addr_arg, 8);
+ reloc_addr_val += map->l_addr;
+
+ /* Store value without causing unaligned trap. */
+ memcpy (reloc_addr_arg, &reloc_addr_val, 8);
+ }
+ }
+ else
+#endif
+ if (__builtin_expect (r_type == R_ALPHA_NONE, 0))
+ return;
+ else
+ {
+ struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+ Elf64_Addr sym_value;
+ Elf64_Addr sym_raw_value;
+
+ sym_raw_value = sym_value = reloc->r_addend;
+ if (sym_map)
+ {
+ sym_raw_value += sym->st_value;
+ sym_value = sym_raw_value + sym_map->l_addr;
+ }
+
+ if (r_type == R_ALPHA_GLOB_DAT)
+ *reloc_addr = sym_value;
+#ifdef RESOLVE_CONFLICT_FIND_MAP
+ /* In .gnu.conflict section, R_ALPHA_JMP_SLOT relocations have
+ R_ALPHA_JMP_SLOT in lower 8 bits and the remaining 24 bits
+ are .rela.plt index. */
+ else if ((r_type & 0xff) == R_ALPHA_JMP_SLOT)
+ {
+ /* elf_machine_fixup_plt needs the map reloc_addr points into,
+ while in _dl_resolve_conflicts map is _dl_loaded. */
+ RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr);
+ reloc = ((const Elf64_Rela *) D_PTR (map, l_info[DT_JMPREL]))
+ + (r_type >> 8);
+ elf_machine_fixup_plt (map, 0, reloc, reloc_addr, sym_value);
+ }
+#else
+ else if (r_type == R_ALPHA_JMP_SLOT)
+ elf_machine_fixup_plt (map, 0, reloc, reloc_addr, sym_value);
+#endif
+#ifndef RTLD_BOOTSTRAP
+ else if (r_type == R_ALPHA_REFQUAD)
+ {
+ /* Store value without causing unaligned trap. */
+ memcpy (reloc_addr_arg, &sym_value, 8);
+ }
+#endif
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+ else if (r_type == R_ALPHA_DTPMOD64)
+ {
+#ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always index 1. */
+ *reloc_addr = 1;
+#else
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+#endif
+ }
+ else if (r_type == R_ALPHA_DTPREL64)
+ {
+#ifndef RTLD_BOOTSTRAP
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ *reloc_addr = sym_raw_value;
+#endif
+ }
+ else if (r_type == R_ALPHA_TPREL64)
+ {
+#ifdef RTLD_BOOTSTRAP
+ *reloc_addr = sym_raw_value + map->l_tls_offset;
+#else
+ if (sym_map)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = sym_raw_value + sym_map->l_tls_offset;
+ }
+#endif
+ }
+#endif /* USE_TLS */
+ else
+ _dl_reloc_bad_type (map, r_type, 0);
+ }
+}
+
+/* Let do-rel.h know that on Alpha if l_addr is 0, all RELATIVE relocs
+ can be skipped. */
+#define ELF_MACHINE_REL_RELATIVE 1
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ /* XXX Make some timings. Maybe it's preferable to test for
+ unaligned access and only do it the complex way if necessary. */
+ Elf64_Addr reloc_addr_val;
+
+ /* Load value without causing unaligned trap. */
+ memcpy (&reloc_addr_val, reloc_addr_arg, 8);
+ reloc_addr_val += l_addr;
+
+ /* Store value without causing unaligned trap. */
+ memcpy (reloc_addr_arg, &reloc_addr_val, 8);
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf64_Addr l_addr, const Elf64_Rela *reloc)
+{
+ Elf64_Addr * const reloc_addr = (void *)(l_addr + reloc->r_offset);
+ unsigned long int const r_type = ELF64_R_TYPE (reloc->r_info);
+
+ if (r_type == R_ALPHA_JMP_SLOT)
+ {
+ /* Perform a RELATIVE reloc on the .got entry that transfers
+ to the .plt. */
+ *reloc_addr += l_addr;
+ }
+ else if (r_type == R_ALPHA_NONE)
+ return;
+ else
+ _dl_reloc_bad_type (map, r_type, 1);
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/libc/sysdeps/alpha/dl-sysdep.h b/libc/sysdeps/alpha/dl-sysdep.h
new file mode 100644
index 000000000..cd678f4e4
--- /dev/null
+++ b/libc/sysdeps/alpha/dl-sysdep.h
@@ -0,0 +1,24 @@
+/* System-specific settings for dynamic linker code. Alpha version.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include_next <dl-sysdep.h>
+
+/* _dl_argv cannot be attribute_relro, because _dl_start_user
+ might write into it after _dl_start returns. */
+#define DL_ARGV_NOT_RELRO 1
diff --git a/libc/sysdeps/alpha/dl-tls.h b/libc/sysdeps/alpha/dl-tls.h
new file mode 100644
index 000000000..f81f95d75
--- /dev/null
+++ b/libc/sysdeps/alpha/dl-tls.h
@@ -0,0 +1,29 @@
+/* Thread-local storage handling in the ELF dynamic linker. Alpha version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* Type used for the representation of TLS information in the GOT. */
+typedef struct
+{
+ unsigned long int ti_module;
+ unsigned long int ti_offset;
+} tls_index;
+
+
+extern void *__tls_get_addr (tls_index *ti);
diff --git a/libc/sysdeps/alpha/dl-trampoline.S b/libc/sysdeps/alpha/dl-trampoline.S
new file mode 100644
index 000000000..c52efbb3b
--- /dev/null
+++ b/libc/sysdeps/alpha/dl-trampoline.S
@@ -0,0 +1,541 @@
+/* PLT trampolines. Alpha version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .set noat
+
+.macro savei regno, offset
+ stq $\regno, \offset($30)
+ cfi_rel_offset(\regno, \offset)
+.endm
+
+.macro savef regno, offset
+ stt $f\regno, \offset($30)
+ cfi_rel_offset(\regno+32, \offset)
+.endm
+
+ .align 4
+ .globl _dl_runtime_resolve_new
+ .ent _dl_runtime_resolve_new
+
+#undef FRAMESIZE
+#define FRAMESIZE 14*8
+
+_dl_runtime_resolve_new:
+ .frame $30, FRAMESIZE, $26, 0
+ .mask 0x4000000, 0
+
+ ldah $29, 0($27) !gpdisp!1
+ lda $30, -FRAMESIZE($30)
+ stq $26, 0*8($30)
+ stq $16, 2*8($30)
+
+ stq $17, 3*8($30)
+ lda $29, 0($29) !gpdisp!1
+ stq $18, 4*8($30)
+ mov $28, $16 /* link_map from .got.plt */
+
+ stq $19, 5*8($30)
+ mov $25, $17 /* offset of reloc entry */
+ stq $20, 6*8($30)
+ mov $26, $18 /* return address */
+
+ stq $21, 7*8($30)
+ stt $f16, 8*8($30)
+ stt $f17, 9*8($30)
+ stt $f18, 10*8($30)
+
+ stt $f19, 11*8($30)
+ stt $f20, 12*8($30)
+ stt $f21, 13*8($30)
+ .prologue 2
+
+ bsr $26, _dl_fixup !samegp
+ mov $0, $27
+
+ ldq $26, 0*8($30)
+ ldq $16, 2*8($30)
+ ldq $17, 3*8($30)
+ ldq $18, 4*8($30)
+ ldq $19, 5*8($30)
+ ldq $20, 6*8($30)
+ ldq $21, 7*8($30)
+ ldt $f16, 8*8($30)
+ ldt $f17, 9*8($30)
+ ldt $f18, 10*8($30)
+ ldt $f19, 11*8($30)
+ ldt $f20, 12*8($30)
+ ldt $f21, 13*8($30)
+ lda $30, FRAMESIZE($30)
+ jmp $31, ($27), 0
+ .end _dl_runtime_resolve_new
+
+ .globl _dl_runtime_profile_new
+ .type _dl_runtime_profile_new, @function
+
+#undef FRAMESIZE
+#define FRAMESIZE 20*8
+
+ /* We save the registers in a different order than desired by
+ .mask/.fmask, so we have to use explicit cfi directives. */
+ cfi_startproc
+
+_dl_runtime_profile_new:
+ ldah $29, 0($27) !gpdisp!2
+ lda $30, -FRAMESIZE($30)
+ savei 26, 0*8
+ stq $16, 2*8($30)
+
+ stq $17, 3*8($30)
+ lda $29, 0($29) !gpdisp!2
+ stq $18, 4*8($30)
+ lda $1, FRAMESIZE($30) /* incoming sp value */
+
+ stq $1, 1*8($30)
+ stq $19, 5*8($30)
+ stq $20, 6*8($30)
+ mov $28, $16 /* link_map from .got.plt */
+
+ stq $21, 7*8($30)
+ mov $25, $17 /* offset of reloc entry */
+ stt $f16, 8*8($30)
+ mov $26, $18 /* return address */
+
+ stt $f17, 9*8($30)
+ mov $30, $19 /* La_alpha_regs address */
+ stt $f18, 10*8($30)
+ lda $20, 14*8($30) /* framesize address */
+
+ stt $f19, 11*8($30)
+ stt $f20, 12*8($30)
+ stt $f21, 13*8($30)
+ stq $28, 16*8($30)
+ stq $25, 17*8($30)
+
+ bsr $26, _dl_profile_fixup !samegp
+ mov $0, $27
+
+ /* Discover if we're wrapping this call. */
+ ldq $18, 14*8($30)
+ bge $18, 1f
+
+ ldq $26, 0*8($30)
+ ldq $16, 2*8($30)
+ ldq $17, 3*8($30)
+ ldq $18, 4*8($30)
+ ldq $19, 5*8($30)
+ ldq $20, 6*8($30)
+ ldq $21, 7*8($30)
+ ldt $f16, 8*8($30)
+ ldt $f17, 9*8($30)
+ ldt $f18, 10*8($30)
+ ldt $f19, 11*8($30)
+ ldt $f20, 12*8($30)
+ ldt $f21, 13*8($30)
+ lda $30, FRAMESIZE($30)
+ jmp $31, ($27), 0
+
+1:
+ /* Create a frame pointer and allocate a new argument frame. */
+ savei 15, 15*8
+ mov $30, $15
+ cfi_def_cfa_register (15)
+ addq $18, 15, $18
+ bic $18, 15, $18
+ subq $30, $18, $30
+
+ /* Save the call destination around memcpy. */
+ stq $0, 14*8($30)
+
+ /* Copy the stack arguments into place. */
+ lda $16, 0($30)
+ lda $17, FRAMESIZE($15)
+ jsr $26, memcpy
+ ldgp $29, 0($26)
+
+ /* Reload the argument registers. */
+ ldq $27, 14*8($30)
+ ldq $16, 2*8($15)
+ ldq $17, 3*8($15)
+ ldq $18, 4*8($15)
+ ldq $19, 5*8($15)
+ ldq $20, 6*8($15)
+ ldq $21, 7*8($15)
+ ldt $f16, 8*8($15)
+ ldt $f17, 9*8($15)
+ ldt $f18, 10*8($15)
+ ldt $f19, 11*8($15)
+ ldt $f20, 12*8($15)
+ ldt $f21, 13*8($15)
+
+ jsr $26, ($27), 0
+ ldgp $29, 0($26)
+
+ /* Set up for call to _dl_call_pltexit. */
+ ldq $16, 16*8($15)
+ ldq $17, 17*8($15)
+ stq $0, 16*8($15)
+ lda $18, 0($15)
+ stq $1, 17*8($15)
+ lda $19, 16*8($15)
+ stt $f0, 18*8($15)
+ stt $f1, 19*8($15)
+ bsr $26, _dl_call_pltexit !samegp
+
+ mov $15, $30
+ cfi_def_cfa_register (30)
+ ldq $26, 0($30)
+ ldq $15, 15*8($30)
+ lda $30, FRAMESIZE($30)
+ ret
+
+ cfi_endproc
+ .size _dl_runtime_profile_new, .-_dl_runtime_profile_new
+
+ .align 4
+ .globl _dl_runtime_resolve_old
+ .ent _dl_runtime_resolve_old
+
+#undef FRAMESIZE
+#define FRAMESIZE 44*8
+
+_dl_runtime_resolve_old:
+ lda $30, -FRAMESIZE($30)
+ .frame $30, FRAMESIZE, $26
+ /* Preserve all registers that C normally doesn't. */
+ stq $26, 0*8($30)
+ stq $0, 1*8($30)
+ stq $1, 2*8($30)
+ stq $2, 3*8($30)
+ stq $3, 4*8($30)
+ stq $4, 5*8($30)
+ stq $5, 6*8($30)
+ stq $6, 7*8($30)
+ stq $7, 8*8($30)
+ stq $8, 9*8($30)
+ stq $16, 10*8($30)
+ stq $17, 11*8($30)
+ stq $18, 12*8($30)
+ stq $19, 13*8($30)
+ stq $20, 14*8($30)
+ stq $21, 15*8($30)
+ stq $22, 16*8($30)
+ stq $23, 17*8($30)
+ stq $24, 18*8($30)
+ stq $25, 19*8($30)
+ stq $29, 20*8($30)
+ stt $f0, 21*8($30)
+ stt $f1, 22*8($30)
+ stt $f10, 23*8($30)
+ stt $f11, 24*8($30)
+ stt $f12, 25*8($30)
+ stt $f13, 26*8($30)
+ stt $f14, 27*8($30)
+ stt $f15, 28*8($30)
+ stt $f16, 29*8($30)
+ stt $f17, 30*8($30)
+ stt $f18, 31*8($30)
+ stt $f19, 32*8($30)
+ stt $f20, 33*8($30)
+ stt $f21, 34*8($30)
+ stt $f22, 35*8($30)
+ stt $f23, 36*8($30)
+ stt $f24, 37*8($30)
+ stt $f25, 38*8($30)
+ stt $f26, 39*8($30)
+ stt $f27, 40*8($30)
+ stt $f28, 41*8($30)
+ stt $f29, 42*8($30)
+ stt $f30, 43*8($30)
+ .mask 0x27ff01ff, -FRAMESIZE
+ .fmask 0xfffffc03, -FRAMESIZE+21*8
+ /* Set up our GP. */
+ br $29, .+4
+ ldgp $29, 0($29)
+ .prologue 0
+ /* Set up the arguments for _dl_fixup:
+ $16 = link_map out of plt0
+ $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24
+ $18 = return address
+ */
+ subq $28, $27, $17
+ ldq $16, 8($27)
+ subq $17, 20, $17
+ mov $26, $18
+ addq $17, $17, $17
+ bsr $26, _dl_fixup !samegp
+
+ /* Move the destination address into position. */
+ mov $0, $27
+ /* Restore program registers. */
+ ldq $26, 0*8($30)
+ ldq $0, 1*8($30)
+ ldq $1, 2*8($30)
+ ldq $2, 3*8($30)
+ ldq $3, 4*8($30)
+ ldq $4, 5*8($30)
+ ldq $5, 6*8($30)
+ ldq $6, 7*8($30)
+ ldq $7, 8*8($30)
+ ldq $8, 9*8($30)
+ ldq $16, 10*8($30)
+ ldq $17, 11*8($30)
+ ldq $18, 12*8($30)
+ ldq $19, 13*8($30)
+ ldq $20, 14*8($30)
+ ldq $21, 15*8($30)
+ ldq $22, 16*8($30)
+ ldq $23, 17*8($30)
+ ldq $24, 18*8($30)
+ ldq $25, 19*8($30)
+ ldq $29, 20*8($30)
+ ldt $f0, 21*8($30)
+ ldt $f1, 22*8($30)
+ ldt $f10, 23*8($30)
+ ldt $f11, 24*8($30)
+ ldt $f12, 25*8($30)
+ ldt $f13, 26*8($30)
+ ldt $f14, 27*8($30)
+ ldt $f15, 28*8($30)
+ ldt $f16, 29*8($30)
+ ldt $f17, 30*8($30)
+ ldt $f18, 31*8($30)
+ ldt $f19, 32*8($30)
+ ldt $f20, 33*8($30)
+ ldt $f21, 34*8($30)
+ ldt $f22, 35*8($30)
+ ldt $f23, 36*8($30)
+ ldt $f24, 37*8($30)
+ ldt $f25, 38*8($30)
+ ldt $f26, 39*8($30)
+ ldt $f27, 40*8($30)
+ ldt $f28, 41*8($30)
+ ldt $f29, 42*8($30)
+ ldt $f30, 43*8($30)
+ /* Flush the Icache after having modified the .plt code. */
+ imb
+ /* Clean up and turn control to the destination */
+ lda $30, FRAMESIZE($30)
+ jmp $31, ($27)
+
+ .end _dl_runtime_resolve_old
+
+ .globl _dl_runtime_profile_old
+ .usepv _dl_runtime_profile_old, no
+ .type _dl_runtime_profile_old, @function
+
+ /* We save the registers in a different order than desired by
+ .mask/.fmask, so we have to use explicit cfi directives. */
+ cfi_startproc
+
+#undef FRAMESIZE
+#define FRAMESIZE 50*8
+
+ .align 4
+_dl_runtime_profile_old:
+ lda $30, -FRAMESIZE($30)
+ cfi_adjust_cfa_offset (FRAMESIZE)
+
+ /* Preserve all argument registers. This also constructs the
+ La_alpha_regs structure. */
+ savei 26, 0*8
+ savei 16, 2*8
+ savei 17, 3*8
+ savei 18, 4*8
+ savei 19, 5*8
+ savei 20, 6*8
+ savei 21, 7*8
+ lda $16, FRAMESIZE($30)
+ savef 16, 8*8
+ savef 17, 9*8
+ savef 18, 10*8
+ savef 19, 11*8
+ savef 20, 12*8
+ savef 21, 13*8
+ stq $16, 1*8($30)
+
+ /* Preserve all registers that C normally doesn't. */
+ savei 0, 14*8
+ savei 1, 15*8
+ savei 2, 16*8
+ savei 3, 17*8
+ savei 4, 18*8
+ savei 5, 19*8
+ savei 6, 20*8
+ savei 7, 21*8
+ savei 8, 22*8
+ savei 22, 23*8
+ savei 23, 24*8
+ savei 24, 25*8
+ savei 25, 26*8
+ savei 29, 27*8
+ savef 0, 28*8
+ savef 1, 29*8
+ savef 10, 30*8
+ savef 11, 31*8
+ savef 12, 32*8
+ savef 13, 33*8
+ savef 14, 34*8
+ savef 15, 35*8
+ savef 22, 36*8
+ savef 23, 37*8
+ savef 24, 38*8
+ savef 25, 39*8
+ savef 26, 40*8
+ savef 27, 41*8
+ savef 28, 42*8
+ savef 29, 43*8
+ savef 30, 44*8
+
+ /* Set up our GP. */
+ br $29, .+4
+ ldgp $29, 0($29)
+
+ /* Set up the arguments for _dl_profile_fixup:
+ $16 = link_map out of plt0
+ $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24
+ $18 = return address
+ $19 = La_alpha_regs address
+ $20 = framesize address
+ */
+ subq $28, $27, $17
+ ldq $16, 8($27)
+ subq $17, 20, $17
+ mov $26, $18
+ addq $17, $17, $17
+ lda $19, 0($30)
+ lda $20, 45*8($30)
+ stq $16, 48*8($30)
+ stq $17, 49*8($30)
+
+ bsr $26, _dl_profile_fixup !samegp
+
+ /* Discover if we're wrapping this call. */
+ ldq $18, 45*8($30)
+ bge $18, 1f
+
+ /* Move the destination address into position. */
+ mov $0, $27
+ /* Restore program registers. */
+ ldq $26, 0*8($30)
+ ldq $16, 2*8($30)
+ ldq $17, 3*8($30)
+ ldq $18, 4*8($30)
+ ldq $19, 5*8($30)
+ ldq $20, 6*8($30)
+ ldq $21, 7*8($30)
+ ldt $f16, 8*8($30)
+ ldt $f17, 9*8($30)
+ ldt $f18, 10*8($30)
+ ldt $f19, 11*8($30)
+ ldt $f20, 12*8($30)
+ ldt $f21, 13*8($30)
+ ldq $0, 14*8($30)
+ ldq $1, 15*8($30)
+ ldq $2, 16*8($30)
+ ldq $3, 17*8($30)
+ ldq $4, 18*8($30)
+ ldq $5, 19*8($30)
+ ldq $6, 20*8($30)
+ ldq $7, 21*8($30)
+ ldq $8, 22*8($30)
+ ldq $22, 23*8($30)
+ ldq $23, 24*8($30)
+ ldq $24, 25*8($30)
+ ldq $25, 26*8($30)
+ ldq $29, 27*8($30)
+ ldt $f0, 28*8($30)
+ ldt $f1, 29*8($30)
+ ldt $f10, 30*8($30)
+ ldt $f11, 31*8($30)
+ ldt $f12, 32*8($30)
+ ldt $f13, 33*8($30)
+ ldt $f14, 34*8($30)
+ ldt $f15, 35*8($30)
+ ldt $f22, 36*8($30)
+ ldt $f23, 37*8($30)
+ ldt $f24, 38*8($30)
+ ldt $f25, 39*8($30)
+ ldt $f26, 40*8($30)
+ ldt $f27, 41*8($30)
+ ldt $f28, 42*8($30)
+ ldt $f29, 43*8($30)
+ ldt $f30, 44*8($30)
+
+ /* Clean up and turn control to the destination. */
+ lda $30, FRAMESIZE($30)
+ jmp $31, ($27)
+
+1:
+ /* Create a frame pointer and allocate a new argument frame. */
+ savei 15, 45*8
+ mov $30, $15
+ cfi_def_cfa_register (15)
+ addq $18, 15, $18
+ bic $18, 15, $18
+ subq $30, $18, $30
+
+ /* Save the call destination around memcpy. */
+ stq $0, 46*8($30)
+
+ /* Copy the stack arguments into place. */
+ lda $16, 0($30)
+ lda $17, FRAMESIZE($15)
+ jsr $26, memcpy
+ ldgp $29, 0($26)
+
+ /* Reload the argument registers. */
+ ldq $27, 46*8($30)
+ ldq $16, 2*8($15)
+ ldq $17, 3*8($15)
+ ldq $18, 4*8($15)
+ ldq $19, 5*8($15)
+ ldq $20, 6*8($15)
+ ldq $21, 7*8($15)
+ ldt $f16, 8*8($15)
+ ldt $f17, 9*8($15)
+ ldt $f18, 10*8($15)
+ ldt $f19, 11*8($15)
+ ldt $f20, 12*8($15)
+ ldt $f21, 13*8($15)
+
+ jsr $26, ($27), 0
+ ldgp $29, 0($26)
+
+ /* Set up for call to _dl_call_pltexit. */
+ ldq $16, 48*8($15)
+ ldq $17, 49*8($15)
+ stq $0, 46*8($15)
+ lda $18, 0($15)
+ stq $1, 47*8($15)
+ lda $19, 46*8($15)
+ stt $f0, 48*8($15)
+ stt $f1, 49*8($15)
+ bsr $26, _dl_call_pltexit !samegp
+
+ mov $15, $30
+ cfi_def_cfa_register (30)
+ ldq $26, 0($30)
+ ldq $15, 45*8($30)
+ lda $30, FRAMESIZE($30)
+ ret
+
+ cfi_endproc
+ .size _dl_runtime_profile_old, .-_dl_runtime_profile_old
diff --git a/libc/sysdeps/alpha/elf/configure b/libc/sysdeps/alpha/elf/configure
new file mode 100755
index 000000000..ea99e3541
--- /dev/null
+++ b/libc/sysdeps/alpha/elf/configure
@@ -0,0 +1,106 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/alpha/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+echo "$as_me:$LINENO: checking for Alpha TLS support" >&5
+echo $ECHO_N "checking for Alpha TLS support... $ECHO_C" >&6
+if test "${libc_cv_alpha_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<\EOF
+ .section ".tdata", "awT", @progbits
+ .globl foo
+foo: .quad 1
+ .section ".tbss", "awT", @nobits
+ .globl bar
+bar: .skip 8
+ .text
+baz:
+ .set nomacro
+ ldq $27, __tls_get_addr($29) !literal!1
+ ldq $16, a($29) !tlsgd!1
+ jsr $26, ($27), __tls_get_addr !lituse_tlsgd!1
+
+ jsr $26, ($27), __tls_get_addr !lituse_tlsldm!2
+ ldq $27, __tls_get_addr($29) !literal!2
+ ldq $16, b($29) !tlsldm!2
+
+ ldq $16, c($29) !tlsgd
+ ldq $16, d($29) !tlsldm
+
+ ldq $16, e($29) !tlsgd!3
+ ldq $16, f($29) !tlsldm!4
+
+ ldq $16, g($29) !gotdtprel
+ ldah $16, h($31) !dtprelhi
+ lda $16, i($16) !dtprello
+ lda $16, j($31) !dtprel
+
+ ldq $16, k($29) !gottprel
+ ldah $16, l($31) !tprelhi
+ lda $16, m($16) !tprello
+ lda $16, n($31) !tprel
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_alpha_tls=yes
+else
+ libc_cv_alpha_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_alpha_tls" >&5
+echo "${ECHO_T}$libc_cv_alpha_tls" >&6
+if test $libc_cv_alpha_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+echo "$as_me:$LINENO: checking for GP relative module local relocs" >&5
+echo $ECHO_N "checking for GP relative module local relocs... $ECHO_C" >&6
+if test "${libc_cv_alpha_hidden_gprel+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.c <<\EOF
+static int bar;
+int baz __attribute__((visibility("hidden")));
+
+int foo (void)
+{
+ return bar + baz;
+}
+EOF
+
+libc_cv_alpha_hidden_gprel=no
+if { ac_try='${CC-cc} -S $CFLAGS -O2 -fpic conftest.c 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if grep -q 'bar.*!gprel' conftest.s \
+ && grep -q 'baz.*!gprel' conftest.s \
+ && ! grep -q 'bar.*!literal' conftest.s \
+ && ! grep -q 'baz.*!literal' conftest.s; then
+ libc_cv_alpha_hidden_gprel=yes
+ fi
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_alpha_hidden_gprel" >&5
+echo "${ECHO_T}$libc_cv_alpha_hidden_gprel" >&6
+if test $libc_cv_alpha_hidden_gprel = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define PI_STATIC_AND_HIDDEN 1
+_ACEOF
+
+fi
diff --git a/libc/sysdeps/alpha/elf/configure.in b/libc/sysdeps/alpha/elf/configure.in
new file mode 100644
index 000000000..798681454
--- /dev/null
+++ b/libc/sysdeps/alpha/elf/configure.in
@@ -0,0 +1,78 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/alpha/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for Alpha TLS support, libc_cv_alpha_tls, [dnl
+cat > conftest.s <<\EOF
+ .section ".tdata", "awT", @progbits
+ .globl foo
+foo: .quad 1
+ .section ".tbss", "awT", @nobits
+ .globl bar
+bar: .skip 8
+ .text
+baz:
+ .set nomacro
+ ldq $27, __tls_get_addr($29) !literal!1
+ ldq $16, a($29) !tlsgd!1
+ jsr $26, ($27), __tls_get_addr !lituse_tlsgd!1
+
+ jsr $26, ($27), __tls_get_addr !lituse_tlsldm!2
+ ldq $27, __tls_get_addr($29) !literal!2
+ ldq $16, b($29) !tlsldm!2
+
+ ldq $16, c($29) !tlsgd
+ ldq $16, d($29) !tlsldm
+
+ ldq $16, e($29) !tlsgd!3
+ ldq $16, f($29) !tlsldm!4
+
+ ldq $16, g($29) !gotdtprel
+ ldah $16, h($31) !dtprelhi
+ lda $16, i($16) !dtprello
+ lda $16, j($31) !dtprel
+
+ ldq $16, k($29) !gottprel
+ ldah $16, l($31) !tprelhi
+ lda $16, m($16) !tprello
+ lda $16, n($31) !tprel
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_alpha_tls=yes
+else
+ libc_cv_alpha_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_alpha_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
+AC_CACHE_CHECK(for GP relative module local relocs, libc_cv_alpha_hidden_gprel, [dnl
+cat > conftest.c <<\EOF
+static int bar;
+int baz __attribute__((visibility("hidden")));
+
+int foo (void)
+{
+ return bar + baz;
+}
+EOF
+dnl
+
+libc_cv_alpha_hidden_gprel=no
+if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS -O2 -fpic conftest.c 1>&AS_MESSAGE_LOG_FD); then
+ if grep -q 'bar.*!gprel' conftest.s \
+ && grep -q 'baz.*!gprel' conftest.s \
+ && ! grep -q 'bar.*!literal' conftest.s \
+ && ! grep -q 'baz.*!literal' conftest.s; then
+ libc_cv_alpha_hidden_gprel=yes
+ fi
+fi
+rm -f conftest*])
+if test $libc_cv_alpha_hidden_gprel = yes; then
+ AC_DEFINE(PI_STATIC_AND_HIDDEN)
+fi
diff --git a/libc/sysdeps/alpha/elf/initfini.c b/libc/sysdeps/alpha/elf/initfini.c
new file mode 100644
index 000000000..4d3342db9
--- /dev/null
+++ b/libc/sysdeps/alpha/elf/initfini.c
@@ -0,0 +1,110 @@
+/* Special .init and .fini section support for Alpha.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file is compiled into assembly code which is then munged by a sed
+ script into two files: crti.s and crtn.s.
+
+ * crti.s puts a function prologue at the beginning of the .init and .fini
+ sections and defines global symbols for those addresses, so they can be
+ called as functions.
+
+ * crtn.s puts the corresponding function epilogues in the .init and .fini
+ sections.
+
+ This differs from what would be generated by the generic code in that
+ we save and restore the GP within the function. In order for linker
+ relaxation to work, the value in the GP register on exit from a function
+ must be valid for the function entry point. Normally, a function is
+ contained within one object file and this is not an issue, provided
+ that the function reloads the gp after making any function calls.
+ However, _init and _fini are constructed from pieces of many object
+ files, all of which may have different GP values. So we must reload
+ the GP value from crti.o in crtn.o. */
+
+__asm__ (" \n\
+#include \"defs.h\" \n\
+ \n\
+/*@HEADER_ENDS*/ \n\
+ \n\
+/*@_init_PROLOG_BEGINS*/ \n\
+ .section .init, \"ax\", @progbits \n\
+ .globl _init \n\
+ .type _init, @function \n\
+ .usepv _init, std \n\
+_init: \n\
+ ldgp $29, 0($27) \n\
+ subq $30, 16, $30 \n\
+ lda $27, __gmon_start__ \n\
+ stq $26, 0($30) \n\
+ stq $29, 8($30) \n\
+ beq $27, 1f \n\
+ jsr $26, ($27), __gmon_start__ \n\
+ ldq $29, 8($30) \n\
+ .align 3 \n\
+1: \n\
+/*@_init_PROLOG_ENDS*/ \n\
+ \n\
+/*@_init_EPILOG_BEGINS*/ \n\
+ .section .init, \"ax\", @progbits \n\
+ ldq $26, 0($30) \n\
+ ldq $29, 8($30) \n\
+ addq $30, 16, $30 \n\
+ ret \n\
+/*@_init_EPILOG_ENDS*/ \n\
+ \n\
+/*@_fini_PROLOG_BEGINS*/ \n\
+ .section .fini, \"ax\", @progbits \n\
+ .globl _fini \n\
+ .type _fini,@function \n\
+ .usepv _fini,std \n\
+_fini: \n\
+ ldgp $29, 0($27) \n\
+ subq $30, 16, $30 \n\
+ stq $26, 0($30) \n\
+ stq $29, 8($30) \n\
+ .align 3 \n\
+/*@_fini_PROLOG_ENDS*/ \n\
+ \n\
+/*@_fini_EPILOG_BEGINS*/ \n\
+ .section .fini, \"ax\", @progbits \n\
+ ldq $26, 0($30) \n\
+ ldq $29, 8($30) \n\
+ addq $30, 16, $30 \n\
+ ret \n\
+/*@_fini_EPILOG_ENDS*/ \n\
+ \n\
+/*@TRAILER_BEGINS*/ \n\
+");
diff --git a/libc/sysdeps/alpha/elf/start.S b/libc/sysdeps/alpha/elf/start.S
new file mode 100644
index 000000000..ebe14b4c8
--- /dev/null
+++ b/libc/sysdeps/alpha/elf/start.S
@@ -0,0 +1,87 @@
+/* Startup code for Alpha/ELF.
+ Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ .align 3
+ .globl _start
+ .ent _start, 0
+ .type _start,@function
+_start:
+ .frame $15, 0, $15
+ br gp, 1f
+1: ldgp gp, 0(gp)
+ subq sp, 16, sp
+ mov 0, $15
+ .prologue 0
+
+ /* Load address of the user's main function. */
+ lda a0, main
+
+ ldl a1, 16(sp) /* get argc */
+ lda a2, 24(sp) /* get argv */
+
+ /* Load address of our own entry points to .fini and .init. */
+ lda a3, __libc_csu_init
+ lda a4, __libc_csu_fini
+
+ /* Store address of the shared library termination function. */
+ mov v0, a5
+
+ /* Provide the highest stack address to the user code. */
+ stq sp, 0(sp)
+
+ /* Call the user's main function, and exit with its value.
+ But let the libc call main. */
+ jsr ra, __libc_start_main
+
+ /* Die very horribly if exit returns. Call_pal hlt is callable from
+ kernel mode only; this will result in an illegal instruction trap. */
+ call_pal 0
+ .end _start
+
+/* For ECOFF backwards compatibility. */
+weak_alias (_start, __start)
+
+/* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+ .weak data_start
+ data_start = __data_start
diff --git a/libc/sysdeps/alpha/ffs.S b/libc/sysdeps/alpha/ffs.S
new file mode 100644
index 000000000..5f2074ee7
--- /dev/null
+++ b/libc/sysdeps/alpha/ffs.S
@@ -0,0 +1,91 @@
+/* Copyright (C) 1996, 1997, 1998, 2004 Free Software Foundation, Inc.
+ Contributed by David Mosberger (davidm@cs.arizona.edu).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Finds the first bit set in an integer. Optimized for the Alpha
+ architecture. */
+
+#include <sysdep.h>
+
+ .set noreorder
+ .set noat
+
+
+ENTRY(__ffs)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+ zap $16, 0xF0, $16
+ br $ffsl..ng
+#else
+ .prologue 0
+ zap $16, 0xF0, $16
+ # FALLTHRU
+#endif
+END(__ffs)
+
+ .align 4
+ENTRY(ffsl)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+$ffsl..ng:
+#else
+ .prologue 0
+#endif
+ not $16, $1 # e0 :
+ ldi $2, -1 # .. e1 :
+ cmpbge $1, $2, $3 # e0 : bit N == 1 for byte N == 0
+ clr $0 # .. e1 :
+ addq $3, 1, $4 # e0 :
+ bic $4, $3, $3 # e1 : bit N == 1 for first byte N != 0
+ and $3, 0xF0, $4 # e0 :
+ and $3, 0xCC, $5 # .. e1 :
+ and $3, 0xAA, $6 # e0 :
+ cmovne $4, 4, $0 # .. e1 :
+ cmovne $5, 2, $5 # e0 :
+ cmovne $6, 1, $6 # .. e1 :
+ addl $0, $5, $0 # e0 :
+ addl $0, $6, $0 # e1 : $0 == N
+ extbl $16, $0, $1 # e0 : $1 == byte N
+ ldi $2, 1 # .. e1 :
+ negq $1, $3 # e0 :
+ and $3, $1, $3 # e1 : bit N == least bit set of byte N
+ and $3, 0xF0, $4 # e0 :
+ and $3, 0xCC, $5 # .. e1 :
+ and $3, 0xAA, $6 # e0 :
+ cmovne $4, 5, $2 # .. e1 :
+ cmovne $5, 2, $5 # e0 :
+ cmovne $6, 1, $6 # .. e1 :
+ s8addl $0, $2, $0 # e0 : mult byte ofs by 8 and sum
+ addl $5, $6, $5 # .. e1 :
+ addl $0, $5, $0 # e0 :
+ nop # .. e1 :
+ cmoveq $16, 0, $0 # e0 : trap input == 0 case.
+ ret # .. e1 : 18
+
+END(ffsl)
+
+weak_alias (__ffs, ffs)
+libc_hidden_builtin_def (ffs)
+weak_extern (ffsl)
+weak_alias (ffsl, ffsll)
diff --git a/libc/sysdeps/alpha/ffsll.S b/libc/sysdeps/alpha/ffsll.S
new file mode 100644
index 000000000..b2f46d899
--- /dev/null
+++ b/libc/sysdeps/alpha/ffsll.S
@@ -0,0 +1 @@
+/* This function is defined in ffs.S. */
diff --git a/libc/sysdeps/alpha/fpu/Versions b/libc/sysdeps/alpha/fpu/Versions
new file mode 100644
index 000000000..c9b0e03a9
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/Versions
@@ -0,0 +1,23 @@
+libc {
+ GLIBC_2.0 {
+ # functions used in other libraries
+ __ieee_get_fp_control; __ieee_set_fp_control;
+ }
+}
+libm {
+ GLIBC_2.3.4 {
+ # functions implementing old complex float abi
+ __c1_cabsf; __c1_cacosf; __c1_cacoshf; __c1_cargf; __c1_casinf;
+ __c1_casinhf; __c1_catanf; __c1_catanhf; __c1_ccosf; __c1_ccoshf;
+ __c1_cexpf; __c1_cimagf; __c1_clog10f; __c1_clogf; __c1_conjf;
+ __c1_cpowf; __c1_cprojf; __c1_crealf; __c1_csinf; __c1_csinhf;
+ __c1_csqrtf; __c1_ctanf; __c1_ctanhf;
+
+ # functions implementing new complex float abi
+ cabsf; cacosf; cacoshf; cargf; casinf;
+ casinhf; catanf; catanhf; ccosf; ccoshf;
+ cexpf; cimagf; clog10f; clogf; conjf;
+ cpowf; cprojf; crealf; csinf; csinhf;
+ csqrtf; ctanf; ctanhf;
+ }
+}
diff --git a/libc/sysdeps/alpha/fpu/bits/fenv.h b/libc/sysdeps/alpha/fpu/bits/fenv.h
new file mode 100644
index 000000000..a9e89b498
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/bits/fenv.h
@@ -0,0 +1,123 @@
+/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+
+/* Define the bits representing the exception.
+
+ Note that these are the bit positions as defined by the OSF/1
+ ieee_{get,set}_control_word interface and not by the hardware fpcr.
+
+ See the Alpha Architecture Handbook section 4.7.7.3 for details,
+ but in summary, trap shadows mean the hardware register can acquire
+ extra exception bits so for proper IEEE support the tracking has to
+ be done in software -- in this case with kernel support.
+
+ As to why the system call interface isn't in the same format as
+ the hardware register, only those crazy folks at DEC can tell you. */
+
+enum
+ {
+#ifdef __USE_GNU
+ FE_DENORMAL = 1UL << 22,
+#define FE_DENORMAL FE_DENORMAL
+#endif
+
+ FE_INEXACT = 1UL << 21,
+#define FE_INEXACT FE_INEXACT
+
+ FE_UNDERFLOW = 1UL << 20,
+#define FE_UNDERFLOW FE_UNDERFLOW
+
+ FE_OVERFLOW = 1UL << 19,
+#define FE_OVERFLOW FE_OVERFLOW
+
+ FE_DIVBYZERO = 1UL << 18,
+#define FE_DIVBYZERO FE_DIVBYZERO
+
+ FE_INVALID = 1UL << 17,
+#define FE_INVALID FE_INVALID
+
+ FE_ALL_EXCEPT = 0x3f << 17
+#define FE_ALL_EXCEPT FE_ALL_EXCEPT
+ };
+
+/* Alpha chips support all four defined rouding modes.
+
+ Note that code must be compiled to use dynamic rounding (/d) instructions
+ to see these changes. For gcc this is -mfp-rounding-mode=d; for DEC cc
+ this is -fprm d. The default for both is static rounding to nearest.
+
+ These are shifted down 58 bits from the hardware fpcr because the
+ functions are declared to take integers. */
+
+enum
+ {
+ FE_TOWARDZERO = 0,
+#define FE_TOWARDZERO FE_TOWARDZERO
+
+ FE_DOWNWARD = 1,
+#define FE_DOWNWARD FE_DOWNWARD
+
+ FE_TONEAREST = 2,
+#define FE_TONEAREST FE_TONEAREST
+
+ FE_UPWARD = 3,
+#define FE_UPWARD FE_UPWARD
+ };
+
+#ifdef __USE_GNU
+/* On later hardware, and later kernels for earlier hardware, we can forcibly
+ underflow denormal inputs and outputs. This can speed up certain programs
+ significantly, usually without affecting accuracy. */
+enum
+ {
+ FE_MAP_DMZ = 1UL << 12, /* Map denorm inputs to zero */
+#define FE_MAP_DMZ FE_MAP_DMZ
+
+ FE_MAP_UMZ = 1UL << 13, /* Map underflowed outputs to zero */
+#define FE_MAP_UMZ FE_MAP_UMZ
+ };
+#endif
+
+/* Type representing exception flags. */
+typedef unsigned long int fexcept_t;
+
+/* Type representing floating-point environment. */
+typedef unsigned long int fenv_t;
+
+/* If the default argument is used we use this value. Note that due to
+ architecture-specified page mappings, no user-space pointer will ever
+ have its two high bits set. Co-opt one. */
+#define FE_DFL_ENV ((__const fenv_t *) 0x8800000000000000UL)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exceptions are masked. */
+# define FE_NOMASK_ENV ((__const fenv_t *) 0x880000000000003eUL)
+
+/* Floating-point environment with (processor-dependent) non-IEEE floating
+ point. In this case, mapping denormals to zero. */
+# define FE_NONIEEE_ENV ((__const fenv_t *) 0x8800000000003000UL)
+#endif
+
+/* The system calls to talk to the kernel's FP code. */
+extern unsigned long int __ieee_get_fp_control (void) __THROW;
+extern void __ieee_set_fp_control (unsigned long int __value) __THROW;
diff --git a/libc/sysdeps/alpha/fpu/bits/mathinline.h b/libc/sysdeps/alpha/fpu/bits/mathinline.h
new file mode 100644
index 000000000..87d40058c
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/bits/mathinline.h
@@ -0,0 +1,183 @@
+/* Inline math functions for Alpha.
+ Copyright (C) 1996, 1997, 1999-2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
+#endif
+
+#ifdef __cplusplus
+# define __MATH_INLINE __inline
+#else
+# define __MATH_INLINE extern __inline
+#endif
+
+#if defined __USE_ISOC99 && defined __GNUC__ && !__GNUC_PREREQ(3,0)
+# undef isgreater
+# undef isgreaterequal
+# undef isless
+# undef islessequal
+# undef islessgreater
+# undef isunordered
+# define isunordered(u, v) \
+ (__extension__ \
+ ({ double __r, __u = (u), __v = (v); \
+ __asm ("cmptun/su %1,%2,%0\n\ttrapb" \
+ : "=&f" (__r) : "f" (__u), "f"(__v)); \
+ __r != 0; }))
+#endif /* ISO C99 */
+
+#if (!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \
+ && defined __OPTIMIZE__
+
+#if !__GNUC_PREREQ (4, 0)
+# define __inline_copysign(NAME, TYPE) \
+__MATH_INLINE TYPE \
+__NTH (NAME (TYPE __x, TYPE __y)) \
+{ \
+ TYPE __z; \
+ __asm ("cpys %1, %2, %0" : "=f" (__z) : "f" (__y), "f" (__x)); \
+ return __z; \
+}
+
+__inline_copysign (__copysignf, float)
+__inline_copysign (copysignf, float)
+__inline_copysign (__copysign, double)
+__inline_copysign (copysign, double)
+
+# undef __inline_copysign
+#endif
+
+
+#if !__GNUC_PREREQ (2, 8)
+# define __inline_fabs(NAME, TYPE) \
+__MATH_INLINE TYPE \
+__NTH (NAME (TYPE __x)) \
+{ \
+ TYPE __z; \
+ __asm ("cpys $f31, %1, %0" : "=f" (__z) : "f" (__x)); \
+ return __z; \
+}
+
+__inline_fabs (__fabsf, float)
+__inline_fabs (fabsf, float)
+__inline_fabs (__fabs, double)
+__inline_fabs (fabs, double)
+
+# undef __inline_fabs
+#endif
+
+
+/* Use the -inf rounding mode conversion instructions to implement
+ floor. We note when the exponent is large enough that the value
+ must be integral, as this avoids unpleasant integer overflows. */
+
+__MATH_INLINE float
+__NTH (__floorf (float __x))
+{
+ /* Check not zero since floor(-0) == -0. */
+ if (__x != 0 && fabsf (__x) < 16777216.0f) /* 1 << FLT_MANT_DIG */
+ {
+ /* Note that Alpha S_Floating is stored in registers in a
+ restricted T_Floating format, so we don't even need to
+ convert back to S_Floating in the end. The initial
+ conversion to T_Floating is needed to handle denormals. */
+
+ float __tmp1, __tmp2;
+
+ __asm ("cvtst/s %3,%2\n\t"
+#ifdef _IEEE_FP_INEXACT
+ "cvttq/svim %2,%1\n\t"
+#else
+ "cvttq/svm %2,%1\n\t"
+#endif
+ "cvtqt/m %1,%0\n\t"
+ : "=f"(__x), "=&f"(__tmp1), "=&f"(__tmp2)
+ : "f"(__x));
+ }
+ return __x;
+}
+
+__MATH_INLINE double
+__NTH (__floor (double __x))
+{
+ if (__x != 0 && fabs (__x) < 9007199254740992.0) /* 1 << DBL_MANT_DIG */
+ {
+ double __tmp1;
+ __asm (
+#ifdef _IEEE_FP_INEXACT
+ "cvttq/svim %2,%1\n\t"
+#else
+ "cvttq/svm %2,%1\n\t"
+#endif
+ "cvtqt/m %1,%0\n\t"
+ : "=f"(__x), "=&f"(__tmp1)
+ : "f"(__x));
+ }
+ return __x;
+}
+
+__MATH_INLINE float __NTH (floorf (float __x)) { return __floorf(__x); }
+__MATH_INLINE double __NTH (floor (double __x)) { return __floor(__x); }
+
+
+#ifdef __USE_ISOC99
+
+__MATH_INLINE float
+__NTH (__fdimf (float __x, float __y))
+{
+ return __x <= __y ? 0.0f : __x - __y;
+}
+
+__MATH_INLINE float
+__NTH (fdimf (float __x, float __y))
+{
+ return __x <= __y ? 0.0f : __x - __y;
+}
+
+__MATH_INLINE double
+__NTH (__fdim (double __x, double __y))
+{
+ return __x <= __y ? 0.0 : __x - __y;
+}
+
+__MATH_INLINE double
+__NTH (fdim (double __x, double __y))
+{
+ return __x <= __y ? 0.0 : __x - __y;
+}
+
+/* Test for negative number. Used in the signbit() macro. */
+__MATH_INLINE int
+__NTH (__signbitf (float __x))
+{
+ __extension__ union { float __f; int __i; } __u = { __f: __x };
+ return __u.__i < 0;
+}
+
+__MATH_INLINE int
+__NTH (__signbit (double __x))
+{
+ __extension__ union { double __d; long __i; } __u = { __d: __x };
+ return __u.__i < 0;
+}
+
+#endif /* C99 */
+
+#endif /* __NO_MATH_INLINES */
diff --git a/libc/sysdeps/alpha/fpu/cabsf.c b/libc/sysdeps/alpha/fpu/cabsf.c
new file mode 100644
index 000000000..de8e6b554
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/cabsf.c
@@ -0,0 +1,42 @@
+/* Return the complex absolute value of float complex value.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __cabsf __cabsf_not_defined
+#define cabsf cabsf_not_defined
+
+#include <complex.h>
+#include <math.h>
+#include "cfloat-compat.h"
+
+#undef __cabsf
+#undef cabsf
+
+float
+__c1_cabsf (c1_cfloat_decl (z))
+{
+ return __hypotf (c1_cfloat_real (z), c1_cfloat_imag (z));
+}
+
+float
+__c2_cabsf (c2_cfloat_decl (z))
+{
+ return __hypotf (c2_cfloat_real (z), c2_cfloat_imag (z));
+}
+
+cfloat_versions (cabsf);
diff --git a/libc/sysdeps/alpha/fpu/cargf.c b/libc/sysdeps/alpha/fpu/cargf.c
new file mode 100644
index 000000000..1d96e5897
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/cargf.c
@@ -0,0 +1,42 @@
+/* Compute argument of complex float value.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __cargf __cargf_not_defined
+#define cargf cargf_not_defined
+
+#include <complex.h>
+#include <math.h>
+#include "cfloat-compat.h"
+
+#undef __cargf
+#undef cargf
+
+float
+__c1_cargf (c1_cfloat_decl (x))
+{
+ return __atan2f (c1_cfloat_imag (x), c1_cfloat_real (x));
+}
+
+float
+__c2_cargf (c2_cfloat_decl (x))
+{
+ return __atan2f (c2_cfloat_imag (x), c2_cfloat_real (x));
+}
+
+cfloat_versions (cargf);
diff --git a/libc/sysdeps/alpha/fpu/cfloat-compat.h b/libc/sysdeps/alpha/fpu/cfloat-compat.h
new file mode 100644
index 000000000..d325a7650
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/cfloat-compat.h
@@ -0,0 +1,74 @@
+/* Compatibility macros for old and new Alpha complex float ABI.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The behaviour of complex float changed between GCC 3.3 and 3.4.
+
+ In 3.3 and before (below, complex version 1, or "c1"), complex float
+ values were packed into one floating point register.
+
+ In 3.4 and later (below, complex version 2, or "c2"), GCC changed to
+ follow the official Tru64 ABI, which passes the components of a complex
+ as separate parameters. */
+
+#if __GNUC_PREREQ(3,4)
+ typedef union { double d; _Complex float cf; } c1_compat;
+# define c1_cfloat_decl(x) double x
+# define c1_cfloat_real(x) __real__ c1_cfloat_value (x)
+# define c1_cfloat_imag(x) __imag__ c1_cfloat_value (x)
+# define c1_cfloat_value(x) (((c1_compat *)(void *)&x)->cf)
+# define c1_cfloat_rettype double
+# define c1_cfloat_return(x) ({ c1_compat _; _.cf = (x); _.d; })
+# define c2_cfloat_decl(x) _Complex float x
+# define c2_cfloat_real(x) __real__ x
+# define c2_cfloat_imag(x) __imag__ x
+# define c2_cfloat_value(x) x
+# define c2_cfloat_rettype _Complex float
+# define c2_cfloat_return(x) x
+#else
+# define c1_cfloat_decl(x) _Complex float x
+# define c1_cfloat_real(x) __real__ x
+# define c1_cfloat_imag(x) __imag__ x
+# define c1_cfloat_value(x) x
+# define c1_cfloat_rettype _Complex float
+# define c1_cfloat_return(x) x
+# define c2_cfloat_decl(x) float x ## r, float x ## i
+# define c2_cfloat_real(x) x ## r
+# define c2_cfloat_imag(x) x ## i
+# define c2_cfloat_value(x) \
+ ({ _Complex float _; __real__ _ = x##r; __imag__ _ = x##i; _; })
+# define c2_cfloat_rettype double _Complex
+# define c2_cfloat_return(x) x
+#endif
+
+/* Get the proper symbol versions defined for each function. */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_3_4)
+#define cfloat_versions_compat(func) \
+ compat_symbol (libm, __c1_##func, func, GLIBC_2_1)
+#else
+#define cfloat_versions_compat(func)
+#endif
+
+#define cfloat_versions(func) \
+ cfloat_versions_compat(func); \
+ versioned_symbol (libm, __c2_##func, func, GLIBC_2_3_4); \
+ extern typeof(__c2_##func) __##func attribute_hidden; \
+ strong_alias (__c2_##func, __##func)
diff --git a/libc/sysdeps/alpha/fpu/cimagf.c b/libc/sysdeps/alpha/fpu/cimagf.c
new file mode 100644
index 000000000..a9b351f18
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/cimagf.c
@@ -0,0 +1,41 @@
+/* Return imaginary part of complex float value.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __cimagf __cimagf_not_defined
+#define cimagf cimagf_not_defined
+
+#include <complex.h>
+#include "cfloat-compat.h"
+
+#undef __cimagf
+#undef cimagf
+
+float
+__c1_cimagf (c1_cfloat_decl (z))
+{
+ return c1_cfloat_imag (z);
+}
+
+float
+__c2_cimagf (c2_cfloat_decl (z))
+{
+ return c2_cfloat_imag (z);
+}
+
+cfloat_versions (cimagf);
diff --git a/libc/sysdeps/alpha/fpu/conjf.c b/libc/sysdeps/alpha/fpu/conjf.c
new file mode 100644
index 000000000..6ff92b994
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/conjf.c
@@ -0,0 +1,43 @@
+/* Return complex conjugate of complex float value.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __conjf __conjf_not_defined
+#define conjf conjf_not_defined
+
+#include <complex.h>
+#include "cfloat-compat.h"
+
+#undef __conjf
+#undef conjf
+
+c1_cfloat_rettype
+__c1_conjf (c1_cfloat_decl (z))
+{
+ _Complex float r = ~ c1_cfloat_value (z);
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_conjf (c2_cfloat_decl (z))
+{
+ _Complex float r = ~ c2_cfloat_value (z);
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (conjf);
diff --git a/libc/sysdeps/alpha/fpu/crealf.c b/libc/sysdeps/alpha/fpu/crealf.c
new file mode 100644
index 000000000..52ab27173
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/crealf.c
@@ -0,0 +1,41 @@
+/* Return real part of complex float value.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __crealf __crealf_not_defined
+#define crealf crealf_not_defined
+
+#include <complex.h>
+#include "cfloat-compat.h"
+
+#undef __crealf
+#undef crealf
+
+float
+__c1_crealf (c1_cfloat_decl (z))
+{
+ return c1_cfloat_real (z);
+}
+
+float
+__c2_crealf (c2_cfloat_decl (z))
+{
+ return c2_cfloat_real (z);
+}
+
+cfloat_versions (crealf);
diff --git a/libc/sysdeps/alpha/fpu/e_sqrt.c b/libc/sysdeps/alpha/fpu/e_sqrt.c
new file mode 100644
index 000000000..c5ab25f16
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/e_sqrt.c
@@ -0,0 +1,165 @@
+/* Copyright (C) 1996,1997,1998,2002,2003 Free Software Foundation, Inc.
+ Contributed by David Mosberger (davidm@cs.arizona.edu).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <features.h>
+
+#if !defined(_IEEE_FP_INEXACT)
+
+/*
+ * This version is much faster than generic sqrt implementation, but
+ * it doesn't handle the inexact flag. It doesn't handle exceptional
+ * values either, but will defer to the full ieee754_sqrt routine which
+ * can.
+ */
+
+/* Careful with rearranging this without consulting the assembly below. */
+const static struct sqrt_data_struct {
+ unsigned long dn, up, half, almost_three_half;
+ unsigned long one_and_a_half, two_to_minus_30, one, nan;
+ const int T2[64];
+} sqrt_data __attribute__((used)) = {
+ 0x3fefffffffffffff, /* __dn = nextafter(1,-Inf) */
+ 0x3ff0000000000001, /* __up = nextafter(1,+Inf) */
+ 0x3fe0000000000000, /* half */
+ 0x3ff7ffffffc00000, /* almost_three_half = 1.5-2^-30 */
+ 0x3ff8000000000000, /* one_and_a_half */
+ 0x3e10000000000000, /* two_to_minus_30 */
+ 0x3ff0000000000000, /* one */
+ 0xffffffffffffffff, /* nan */
+
+ { 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866,
+ 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
+ 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
+ 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
+ 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
+ 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
+ 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
+ 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd }
+};
+
+asm ("\
+ /* Define offsets into the structure defined in C above. */ \n\
+ $DN = 0*8 \n\
+ $UP = 1*8 \n\
+ $HALF = 2*8 \n\
+ $ALMOST_THREE_HALF = 3*8 \n\
+ $NAN = 7*8 \n\
+ $T2 = 8*8 \n\
+ \n\
+ /* Stack variables. */ \n\
+ $K = 0 \n\
+ $Y = 8 \n\
+ \n\
+ .text \n\
+ .align 5 \n\
+ .globl __ieee754_sqrt \n\
+ .ent __ieee754_sqrt \n\
+__ieee754_sqrt: \n\
+ ldgp $29, 0($27) \n\
+ subq $sp, 16, $sp \n\
+ .frame $sp, 16, $26, 0\n"
+#ifdef PROF
+" lda $28, _mcount \n\
+ jsr $28, ($28), _mcount\n"
+#endif
+" .prologue 1 \n\
+ \n\
+ .align 4 \n\
+ stt $f16, $K($sp) # e0 : \n\
+ mult $f31, $f31, $f31 # .. fm : \n\
+ lda $4, sqrt_data # e0 : \n\
+ fblt $f16, $fixup # .. fa : \n\
+ \n\
+ ldah $2, 0x5fe8 # e0 : \n\
+ ldq $3, $K($sp) # .. e1 : \n\
+ ldt $f12, $HALF($4) # e0 : \n\
+ ldt $f18, $ALMOST_THREE_HALF($4) # .. e1 : \n\
+ \n\
+ sll $3, 52, $5 # e0 : \n\
+ lda $6, 0x7fd # .. e1 : \n\
+ fnop # .. fa : \n\
+ fnop # .. fm : \n\
+ \n\
+ subq $5, 1, $5 # e1 : \n\
+ srl $3, 33, $1 # .. e0 : \n\
+ cmpule $5, $6, $5 # e0 : \n\
+ beq $5, $fixup # .. e1 : \n\
+ \n\
+ mult $f16, $f12, $f11 # fm : $f11 = x * 0.5 \n\
+ subl $2, $1, $2 # .. e0 : \n\
+ addt $f12, $f12, $f17 # .. fa : $f17 = 1.0 \n\
+ srl $2, 12, $1 # e0 : \n\
+ \n\
+ and $1, 0xfc, $1 # e0 : \n\
+ addq $1, $4, $1 # e1 : \n\
+ ldl $1, $T2($1) # e0 : \n\
+ addt $f12, $f17, $f15 # .. fa : $f15 = 1.5 \n\
+ \n\
+ subl $2, $1, $2 # e0 : \n\
+ ldt $f14, $DN($4) # .. e1 : \n\
+ sll $2, 32, $2 # e0 : \n\
+ stq $2, $Y($sp) # e0 : \n\
+ \n\
+ ldt $f13, $Y($sp) # e0 : \n\
+ mult/su $f11, $f13, $f10 # fm 2: $f10 = (x * 0.5) * y \n\
+ mult $f10, $f13, $f10 # fm 4: $f10 = ((x*0.5)*y)*y \n\
+ subt $f15, $f10, $f1 # fa 4: $f1 = (1.5-0.5*x*y*y) \n\
+ \n\
+ mult $f13, $f1, $f13 # fm 4: yp = y*(1.5-0.5*x*y^2)\n\
+ mult/su $f11, $f13, $f1 # fm 4: $f11 = x * 0.5 * yp \n\
+ mult $f1, $f13, $f11 # fm 4: $f11 = (x*0.5*yp)*yp \n\
+ subt $f18, $f11, $f1 # fa 4: $f1=(1.5-2^-30)-x/2*yp^2\n\
+ \n\
+ mult $f13, $f1, $f13 # fm 4: ypp = $f13 = yp*$f1 \n\
+ subt $f15, $f12, $f1 # .. fa : $f1 = (1.5 - 0.5) \n\
+ ldt $f15, $UP($4) # .. e0 : \n\
+ mult/su $f16, $f13, $f10 # fm 4: z = $f10 = x * ypp \n\
+ \n\
+ mult $f10, $f13, $f11 # fm 4: $f11 = z*ypp \n\
+ mult $f10, $f12, $f12 # fm : $f12 = z*0.5 \n\
+ subt $f1, $f11, $f1 # fa 4: $f1 = 1 - z*ypp \n\
+ mult $f12, $f1, $f12 # fm 4: $f12 = z/2*(1 - z*ypp)\n\
+ \n\
+ addt $f10, $f12, $f0 # fa 4: zp=res= z+z/2*(1-z*ypp)\n\
+ mult/c $f0, $f14, $f12 # fm 4: zmi = zp * DN \n\
+ mult/c $f0, $f15, $f11 # fm : zpl = zp * UP \n\
+ mult/c $f0, $f12, $f1 # fm : $f1 = zp * zmi \n\
+ \n\
+ mult/c $f0, $f11, $f15 # fm : $f15 = zp * zpl \n\
+ subt/su $f1, $f16, $f13 # .. fa : y1 = zp*zmi - x \n\
+ subt/su $f15, $f16, $f14 # fa 4: y2 = zp*zpl - x \n\
+ fcmovge $f13, $f12, $f0 # fa 3: res = (y1>=0)?zmi:res \n\
+ \n\
+ fcmovlt $f14, $f11, $f0 # fa 4: res = (y2<0)?zpl:res \n\
+ addq $sp, 16, $sp # .. e0 : \n\
+ ret # .. e1 : \n\
+ \n\
+ .align 4 \n\
+$fixup: \n\
+ addq $sp, 16, $sp \n\
+ br __full_ieee754_sqrt !samegp \n\
+ \n\
+ .end __ieee754_sqrt");
+
+static double __full_ieee754_sqrt(double) __attribute_used__;
+#define __ieee754_sqrt __full_ieee754_sqrt
+
+#endif /* _IEEE_FP_INEXACT */
+
+#include <sysdeps/ieee754/dbl-64/e_sqrt.c>
diff --git a/libc/sysdeps/alpha/fpu/fclrexcpt.c b/libc/sysdeps/alpha/fpu/fclrexcpt.c
new file mode 100644
index 000000000..b7176e097
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/fclrexcpt.c
@@ -0,0 +1,47 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+__feclearexcept (int excepts)
+{
+ unsigned long int swcr;
+
+ /* Get the current state. */
+ swcr = __ieee_get_fp_control ();
+
+ /* Clear the relevant bits. */
+ swcr &= ~((unsigned long int) excepts & SWCR_STATUS_MASK);
+
+ /* Put the new state in effect. */
+ __ieee_set_fp_control (swcr);
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feclearexcept, __old_feclearexcept)
+compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
diff --git a/libc/sysdeps/alpha/fpu/fedisblxcpt.c b/libc/sysdeps/alpha/fpu/fedisblxcpt.c
new file mode 100644
index 000000000..98c33ca84
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/fedisblxcpt.c
@@ -0,0 +1,36 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+fedisableexcept (int excepts)
+{
+ unsigned long int new_exc, old_exc;
+
+ new_exc = __ieee_get_fp_control ();
+
+ old_exc = (new_exc & SWCR_ENABLE_MASK) << SWCR_ENABLE_SHIFT;
+ new_exc &= ~((excepts >> SWCR_ENABLE_SHIFT) & SWCR_ENABLE_MASK);
+
+ __ieee_set_fp_control (new_exc);
+
+ return old_exc;
+}
diff --git a/libc/sysdeps/alpha/fpu/feenablxcpt.c b/libc/sysdeps/alpha/fpu/feenablxcpt.c
new file mode 100644
index 000000000..80d657e4b
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/feenablxcpt.c
@@ -0,0 +1,36 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+feenableexcept (int excepts)
+{
+ unsigned long int new_exc, old_exc;
+
+ new_exc = __ieee_get_fp_control ();
+
+ old_exc = (new_exc & SWCR_ENABLE_MASK) << SWCR_ENABLE_SHIFT;
+ new_exc |= (excepts >> SWCR_ENABLE_SHIFT) & SWCR_ENABLE_MASK;
+
+ __ieee_set_fp_control (new_exc);
+
+ return old_exc;
+}
diff --git a/libc/sysdeps/alpha/fpu/fegetenv.c b/libc/sysdeps/alpha/fpu/fegetenv.c
new file mode 100644
index 000000000..c1950fa3b
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/fegetenv.c
@@ -0,0 +1,47 @@
+/* Store current floating-point environment.
+ Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1997
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+__fegetenv (fenv_t *envp)
+{
+ unsigned long int fpcr;
+ unsigned long int swcr;
+
+ /* Get status from software and hardware. Note that we don't need an
+ excb because the callsys is an implied trap barrier. */
+ swcr = __ieee_get_fp_control ();
+ __asm__ __volatile__ ("mf_fpcr %0" : "=f" (fpcr));
+
+ /* Merge the two bits of information. */
+ *envp = ((fpcr & FPCR_ROUND_MASK) | (swcr & SWCR_ALL_MASK));
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fegetenv, __old_fegetenv)
+compat_symbol (libm, __old_fegetenv, fegetenv, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __fegetenv, fegetenv, GLIBC_2_2);
diff --git a/libc/sysdeps/alpha/fpu/fegetexcept.c b/libc/sysdeps/alpha/fpu/fegetexcept.c
new file mode 100644
index 000000000..ccc79e405
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/fegetexcept.c
@@ -0,0 +1,31 @@
+/* Get enabled floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+fegetexcept (void)
+{
+ unsigned long int exc;
+
+ exc = __ieee_get_fp_control ();
+
+ return (exc & SWCR_ENABLE_MASK) << SWCR_ENABLE_SHIFT;
+}
diff --git a/libc/sysdeps/alpha/fpu/fegetround.c b/libc/sysdeps/alpha/fpu/fegetround.c
new file mode 100644
index 000000000..995aee80d
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/fegetround.c
@@ -0,0 +1,31 @@
+/* Return current rounding direction.
+ Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1997
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+fegetround (void)
+{
+ unsigned long fpcr;
+
+ __asm__ __volatile__("excb; mf_fpcr %0" : "=f"(fpcr));
+
+ return (fpcr >> FPCR_ROUND_SHIFT) & 3;
+}
diff --git a/libc/sysdeps/alpha/fpu/feholdexcpt.c b/libc/sysdeps/alpha/fpu/feholdexcpt.c
new file mode 100644
index 000000000..79aa970ac
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/feholdexcpt.c
@@ -0,0 +1,34 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 1997, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1997
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ /* Save the current state. */
+ fegetenv(envp);
+
+ /* Clear all exception status bits and exception enable bits. */
+ __ieee_set_fp_control(*envp & SWCR_MAP_MASK);
+
+ return 0;
+}
+libm_hidden_def (feholdexcept)
diff --git a/libc/sysdeps/alpha/fpu/fenv_libc.h b/libc/sysdeps/alpha/fpu/fenv_libc.h
new file mode 100644
index 000000000..f1d187d9e
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/fenv_libc.h
@@ -0,0 +1,36 @@
+/* Internal libc stuff for floating point environment routines.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FENV_LIBC_H
+#define _FENV_LIBC_H 1
+
+#include <fenv.h>
+
+#define FPCR_ROUND_MASK (3UL << 58)
+#define FPCR_ROUND_SHIFT 58
+
+#define SWCR_MAP_MASK (3UL << 12)
+#define SWCR_ENABLE_SHIFT 16
+#define SWCR_ENABLE_MASK (FE_ALL_EXCEPT >> SWCR_ENABLE_SHIFT)
+#define SWCR_STATUS_MASK (FE_ALL_EXCEPT)
+#define SWCR_ALL_MASK (SWCR_ENABLE_MASK \
+ | SWCR_MAP_MASK \
+ | SWCR_STATUS_MASK)
+
+#endif /* fenv_libc.h */
diff --git a/libc/sysdeps/alpha/fpu/fesetenv.c b/libc/sysdeps/alpha/fpu/fesetenv.c
new file mode 100644
index 000000000..c76e88289
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/fesetenv.c
@@ -0,0 +1,57 @@
+/* Install given floating-point environment.
+ Copyright (C) 1997,99,2000,01,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1997
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+__fesetenv (const fenv_t *envp)
+{
+ unsigned long int fpcr;
+ fenv_t env;
+
+ /* Magic encoding of default values: high bit set (never possible for a
+ user-space address) is not indirect. And we don't even have to get
+ rid of it since we mask things around just below. */
+ if ((long int) envp >= 0)
+ env = *envp;
+ else
+ env = (unsigned long int) envp;
+
+ /* Reset the rounding mode with the hardware fpcr. Note that the following
+ system call is an implied trap barrier for our modification. */
+ __asm__ __volatile__ ("excb; mf_fpcr %0" : "=f" (fpcr));
+ fpcr = (fpcr & ~FPCR_ROUND_MASK) | (env & FPCR_ROUND_MASK);
+ __asm__ __volatile__ ("mt_fpcr %0" : : "f" (fpcr));
+
+ /* Reset the exception status and mask with the kernel's FP code. */
+ __ieee_set_fp_control (env & SWCR_ALL_MASK);
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fesetenv, __old_fesetenv)
+compat_symbol (libm, __old_fesetenv, fesetenv, GLIBC_2_1);
+#endif
+
+libm_hidden_ver (__fesetenv, fesetenv)
+versioned_symbol (libm, __fesetenv, fesetenv, GLIBC_2_2);
diff --git a/libc/sysdeps/alpha/fpu/fesetround.c b/libc/sysdeps/alpha/fpu/fesetround.c
new file mode 100644
index 000000000..54b2bcf67
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/fesetround.c
@@ -0,0 +1,43 @@
+/* Set current rounding direction.
+ Copyright (C) 1997, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1997
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+fesetround (int round)
+{
+ unsigned long fpcr;
+
+ if (round & ~3)
+ return 1;
+
+ /* Get the current state. */
+ __asm__ __volatile__("excb; mf_fpcr %0" : "=f"(fpcr));
+
+ /* Set the relevant bits. */
+ fpcr = ((fpcr & ~FPCR_ROUND_MASK)
+ | ((unsigned long)round << FPCR_ROUND_SHIFT));
+
+ /* Put the new state in effect. */
+ __asm__ __volatile__("mt_fpcr %0; excb" : : "f"(fpcr));
+
+ return 0;
+}
+libm_hidden_def (fesetround)
diff --git a/libc/sysdeps/alpha/fpu/feupdateenv.c b/libc/sysdeps/alpha/fpu/feupdateenv.c
new file mode 100644
index 000000000..c798070bb
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/feupdateenv.c
@@ -0,0 +1,49 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+__feupdateenv (const fenv_t *envp)
+{
+ unsigned long int tmp;
+
+ /* Get the current exception state. */
+ tmp = __ieee_get_fp_control ();
+
+ /* Install new environment. */
+ fesetenv (envp);
+
+ /* Raise the saved exception. Incidently for us the implementation
+ defined format of the values in objects of type fexcept_t is the
+ same as the ones specified using the FE_* constants. */
+ feraiseexcept (tmp & SWCR_STATUS_MASK);
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feupdateenv, __old_feupdateenv)
+compat_symbol (libm, __old_feupdateenv, feupdateenv, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __feupdateenv, feupdateenv, GLIBC_2_2);
diff --git a/libc/sysdeps/alpha/fpu/fgetexcptflg.c b/libc/sysdeps/alpha/fpu/fgetexcptflg.c
new file mode 100644
index 000000000..c28e91335
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/fgetexcptflg.c
@@ -0,0 +1,44 @@
+/* Store current representation for exceptions.
+ Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+__fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ unsigned long int tmp;
+
+ /* Get the current state. */
+ tmp = __ieee_get_fp_control();
+
+ /* Return that portion that corresponds to the requested exceptions. */
+ *flagp = tmp & excepts & SWCR_STATUS_MASK;
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fegetexceptflag, __old_fegetexceptflag)
+compat_symbol (libm, __old_fegetexceptflag, fegetexceptflag, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __fegetexceptflag, fegetexceptflag, GLIBC_2_2);
diff --git a/libc/sysdeps/alpha/fpu/fpu_control.h b/libc/sysdeps/alpha/fpu/fpu_control.h
new file mode 100644
index 000000000..28acdf170
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/fpu_control.h
@@ -0,0 +1,106 @@
+/* FPU control word bits. Alpha-mapped-to-Intel version.
+ Copyright (C) 1996, 1998, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Olaf Flebbe.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _ALPHA_FPU_CONTROL_H
+#define _ALPHA_FPU_CONTROL_H
+
+/*
+ * Since many programs seem to hardcode the values passed to __setfpucw()
+ * (rather than using the manifest constants) we emulate the x87 interface
+ * here (at least where this makes sense).
+ *
+ * 15-13 12 11-10 9-8 7-6 5 4 3 2 1 0
+ * | reserved | IC | RC | PC | reserved | PM | UM | OM | ZM | DM | IM
+ *
+ * IM: Invalid operation mask
+ * DM: Denormalized operand mask
+ * ZM: Zero-divide mask
+ * OM: Overflow mask
+ * UM: Underflow mask
+ * PM: Precision (inexact result) mask
+ *
+ * Mask bit is 1 means no interrupt.
+ *
+ * PC: Precision control
+ * 11 - round to extended precision
+ * 10 - round to double precision
+ * 00 - round to single precision
+ *
+ * RC: Rounding control
+ * 00 - rounding to nearest
+ * 01 - rounding down (toward - infinity)
+ * 10 - rounding up (toward + infinity)
+ * 11 - rounding toward zero
+ *
+ * IC: Infinity control
+ * That is for 8087 and 80287 only.
+ *
+ * The hardware default is 0x037f. I choose 0x1372.
+ */
+
+#include <features.h>
+
+/* masking of interrupts */
+#define _FPU_MASK_IM 0x01
+#define _FPU_MASK_DM 0x02
+#define _FPU_MASK_ZM 0x04
+#define _FPU_MASK_OM 0x08
+#define _FPU_MASK_UM 0x10
+#define _FPU_MASK_PM 0x20
+
+/* precision control -- without effect on Alpha */
+#define _FPU_EXTENDED 0x300 /* RECOMMENDED */
+#define _FPU_DOUBLE 0x200
+#define _FPU_SINGLE 0x0 /* DO NOT USE */
+
+/*
+ * rounding control---notice that on the Alpha this affects only
+ * instructions with the dynamic rounding mode qualifier (/d).
+ */
+#define _FPU_RC_NEAREST 0x000 /* RECOMMENDED */
+#define _FPU_RC_DOWN 0x400
+#define _FPU_RC_UP 0x800
+#define _FPU_RC_ZERO 0xC00
+
+#define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */
+
+
+/* Now two recommended cw */
+
+/* Linux default:
+ - extended precision
+ - rounding to positive infinity. There is no /p instruction
+ qualifier. By setting the dynamic rounding mode to +infinity,
+ one can use /d to get round to +infinity with no extra overhead
+ (so long as the default isn't changed, of course...)
+ - no exceptions enabled. */
+
+#define _FPU_DEFAULT 0x137f
+
+/* IEEE: same as above. */
+#define _FPU_IEEE 0x137f
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t;
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* _ALPHA_FPU_CONTROL */
diff --git a/libc/sysdeps/alpha/fpu/fsetexcptflg.c b/libc/sysdeps/alpha/fpu/fsetexcptflg.c
new file mode 100644
index 000000000..d19873186
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/fsetexcptflg.c
@@ -0,0 +1,47 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 1997,98,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+__fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ unsigned long int tmp;
+
+ /* Get the current exception state. */
+ tmp = __ieee_get_fp_control ();
+
+ /* Set all the bits that were called for. */
+ tmp = (tmp & ~SWCR_STATUS_MASK) | (*flagp & excepts & SWCR_STATUS_MASK);
+
+ /* And store it back. */
+ __ieee_set_fp_control (tmp);
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fesetexceptflag, __old_fesetexceptflag)
+compat_symbol (libm, __old_fesetexceptflag, fesetexceptflag, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __fesetexceptflag, fesetexceptflag, GLIBC_2_2);
diff --git a/libc/sysdeps/alpha/fpu/ftestexcept.c b/libc/sysdeps/alpha/fpu/ftestexcept.c
new file mode 100644
index 000000000..a4b308187
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/ftestexcept.c
@@ -0,0 +1,32 @@
+/* Test exception in current environment.
+ Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+fetestexcept (int excepts)
+{
+ unsigned long tmp;
+
+ /* Get current exceptions. */
+ tmp = __ieee_get_fp_control();
+
+ return tmp & excepts & SWCR_STATUS_MASK;
+}
diff --git a/libc/sysdeps/alpha/fpu/libm-test-ulps b/libc/sysdeps/alpha/fpu/libm-test-ulps
new file mode 100644
index 000000000..6b882e388
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/libm-test-ulps
@@ -0,0 +1,886 @@
+# Begin of automatic generation
+
+# atan2
+Test "atan2 (-0.00756827042671106339, -.001792735857538728036) == -1.80338464113663849327153994379639112":
+float: 6
+ifloat: 6
+Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025":
+float: 3
+ifloat: 3
+Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025":
+float: 3
+ifloat: 3
+Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772":
+float: 1
+ifloat: 1
+
+# atanh
+Test "atanh (0.75) == 0.972955074527656652552676371721589865":
+float: 1
+ifloat: 1
+
+# cacosh
+Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+
+# casin
+Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# casinh
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# catan
+Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+float: 3
+ifloat: 3
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+float: 4
+ifloat: 4
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 4
+idouble: 4
+Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+float: 4
+ifloat: 4
+Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+float: 6
+ifloat: 6
+
+# cbrt
+Test "cbrt (-27.0) == -3.0":
+double: 1
+idouble: 1
+Test "cbrt (0.75) == 0.908560296416069829445605878163630251":
+double: 1
+idouble: 1
+Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217":
+double: 1
+idouble: 1
+
+# ccos
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+float: 1
+ifloat: 1
+
+# ccosh
+Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+float: 1
+ifloat: 1
+
+# cexp
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+float: 1
+ifloat: 1
+Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+float: 1
+ifloat: 1
+
+# clog
+Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+float: 3
+ifloat: 3
+Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+float: 1
+ifloat: 1
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+float: 1
+ifloat: 1
+
+# cos
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "cos (pi/2) == 0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# cpow
+Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 2
+ifloat: 2
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+# csinh
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+
+# csqrt
+Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+
+# ctan
+Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+double: 1
+idouble: 1
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+ifloat: 1
+Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+idouble: 1
+
+# erf
+Test "erf (1.25) == 0.922900128256458230136523481197281140":
+double: 1
+idouble: 1
+
+# erfc
+Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
+double: 1
+idouble: 1
+Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8":
+double: 1
+idouble: 1
+
+# exp10
+Test "exp10 (-1) == 0.1":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "exp10 (3) == 1000":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+
+# expm1
+Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+double: 1
+idouble: 1
+Test "expm1 (1) == M_El - 1.0":
+float: 1
+ifloat: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+
+# j0
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "j0 (0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+
+# j1
+Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+
+# jn
+Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (0, 0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+float: 4
+ifloat: 4
+Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# lgamma
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# log10
+Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "log10 (e) == log10(e)":
+float: 1
+ifloat: 1
+
+# log1p
+Test "log1p (-0.25) == -0.287682072451780927439219005993827432":
+float: 1
+ifloat: 1
+
+# sincos
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
+float: 1
+ifloat: 1
+
+# tan
+Test "tan (pi/4) == 1":
+double: 1
+idouble: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+ifloat: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# y0
+Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+ifloat: 1
+Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# y1
+Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "y1 (1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# yn
+Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+ifloat: 1
+Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "yn (1, 1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "yn (1, 2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+double: 1
+idouble: 1
+Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+double: 1
+idouble: 1
+Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+double: 2
+idouble: 2
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+idouble: 1
+Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+double: 1
+idouble: 1
+
+# Maximal error of functions:
+Function: "atan2":
+float: 6
+ifloat: 6
+
+Function: "atanh":
+float: 1
+ifloat: 1
+
+Function: Real part of "cacosh":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+
+Function: Real part of "catan":
+float: 4
+ifloat: 4
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "catanh":
+double: 4
+idouble: 4
+
+Function: Imaginary part of "catanh":
+float: 6
+ifloat: 6
+
+Function: "cbrt":
+double: 1
+idouble: 1
+
+Function: Real part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ccos":
+float: 1
+ifloat: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ccosh":
+float: 1
+ifloat: 1
+
+Function: Real part of "cexp":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "cexp":
+float: 1
+ifloat: 1
+
+Function: Real part of "clog":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "clog":
+float: 3
+ifloat: 3
+
+Function: Real part of "clog10":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: Real part of "cpow":
+double: 2
+float: 4
+idouble: 2
+ifloat: 4
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: Real part of "csinh":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "csqrt":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "ctan":
+double: 1
+idouble: 1
+
+Function: Real part of "ctanh":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: Imaginary part of "ctanh":
+float: 1
+ifloat: 1
+
+Function: "erf":
+double: 1
+idouble: 1
+
+Function: "erfc":
+double: 1
+idouble: 1
+
+Function: "exp10":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+
+Function: "expm1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "hypot":
+float: 1
+ifloat: 1
+
+Function: "j0":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "jn":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "log10":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "log1p":
+float: 1
+ifloat: 1
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "tan":
+double: 1
+idouble: 1
+
+Function: "tgamma":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+
+# end of automatic generation
diff --git a/libc/sysdeps/alpha/fpu/s_cacosf.c b/libc/sysdeps/alpha/fpu/s_cacosf.c
new file mode 100644
index 000000000..46dca5aeb
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_cacosf.c
@@ -0,0 +1,51 @@
+/* Return arc cosine of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __cacosf __cacosf_not_defined
+#define cacosf cacosf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __cacosf
+#undef cacosf
+#define __cacosf internal_cacosf
+
+static _Complex float internal_cacosf (_Complex float x);
+
+#include <math/s_cacosf.c>
+#include "cfloat-compat.h"
+
+#undef __cacosf
+
+c1_cfloat_rettype
+__c1_cacosf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_cacosf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_cacosf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_cacosf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (cacosf);
diff --git a/libc/sysdeps/alpha/fpu/s_cacoshf.c b/libc/sysdeps/alpha/fpu/s_cacoshf.c
new file mode 100644
index 000000000..6b61d1dda
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_cacoshf.c
@@ -0,0 +1,51 @@
+/* Return arc hyperbole cosine of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __cacoshf __cacoshf_not_defined
+#define cacoshf cacoshf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __cacoshf
+#undef cacoshf
+#define __cacoshf internal_cacoshf
+
+static _Complex float internal_cacoshf (_Complex float x);
+
+#include <math/s_cacoshf.c>
+#include "cfloat-compat.h"
+
+#undef __cacoshf
+
+c1_cfloat_rettype
+__c1_cacoshf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_cacoshf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_cacoshf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_cacoshf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (cacoshf);
diff --git a/libc/sysdeps/alpha/fpu/s_casinf.c b/libc/sysdeps/alpha/fpu/s_casinf.c
new file mode 100644
index 000000000..fd41042ec
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_casinf.c
@@ -0,0 +1,51 @@
+/* Return arc sine of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __casinf __casinf_not_defined
+#define casinf casinf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __casinf
+#undef casinf
+#define __casinf internal_casinf
+
+static _Complex float internal_casinf (_Complex float x);
+
+#include <math/s_casinf.c>
+#include "cfloat-compat.h"
+
+#undef __casinf
+
+c1_cfloat_rettype
+__c1_casinf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_casinf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_casinf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_casinf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (casinf);
diff --git a/libc/sysdeps/alpha/fpu/s_casinhf.c b/libc/sysdeps/alpha/fpu/s_casinhf.c
new file mode 100644
index 000000000..0b72a24d5
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_casinhf.c
@@ -0,0 +1,51 @@
+/* Return arc hyperbole sine of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __casinhf __casinhf_not_defined
+#define casinhf casinhf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __casinhf
+#undef casinhf
+#define __casinhf internal_casinhf
+
+static _Complex float internal_casinhf (_Complex float x);
+
+#include <math/s_casinhf.c>
+#include "cfloat-compat.h"
+
+#undef __casinhf
+
+c1_cfloat_rettype
+__c1_casinhf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_casinhf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_casinhf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_casinhf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (casinhf);
diff --git a/libc/sysdeps/alpha/fpu/s_catanf.c b/libc/sysdeps/alpha/fpu/s_catanf.c
new file mode 100644
index 000000000..8f4061661
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_catanf.c
@@ -0,0 +1,51 @@
+/* Return arc tangent of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __catanf __catanf_not_defined
+#define catanf catanf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __catanf
+#undef catanf
+#define __catanf internal_catanf
+
+static _Complex float internal_catanf (_Complex float x);
+
+#include <math/s_catanf.c>
+#include "cfloat-compat.h"
+
+#undef __catanf
+
+c1_cfloat_rettype
+__c1_catanf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_catanf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_catanf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_catanf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (catanf);
diff --git a/libc/sysdeps/alpha/fpu/s_catanhf.c b/libc/sysdeps/alpha/fpu/s_catanhf.c
new file mode 100644
index 000000000..ac1194572
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_catanhf.c
@@ -0,0 +1,51 @@
+/* Return arc hyperbole tangent of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __catanhf __catanhf_not_defined
+#define catanhf catanhf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __catanhf
+#undef catanhf
+#define __catanhf internal_catanhf
+
+static _Complex float internal_catanhf (_Complex float x);
+
+#include <math/s_catanhf.c>
+#include "cfloat-compat.h"
+
+#undef __catanhf
+
+c1_cfloat_rettype
+__c1_catanhf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_catanhf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_catanhf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_catanhf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (catanhf);
diff --git a/libc/sysdeps/alpha/fpu/s_ccosf.c b/libc/sysdeps/alpha/fpu/s_ccosf.c
new file mode 100644
index 000000000..04036f461
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_ccosf.c
@@ -0,0 +1,51 @@
+/* Return cosine of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __ccosf __ccosf_not_defined
+#define ccosf ccosf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __ccosf
+#undef ccosf
+#define __ccosf internal_ccosf
+
+static _Complex float internal_ccosf (_Complex float x);
+
+#include <math/s_ccosf.c>
+#include "cfloat-compat.h"
+
+#undef __ccosf
+
+c1_cfloat_rettype
+__c1_ccosf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_ccosf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_ccosf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_ccosf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (ccosf);
diff --git a/libc/sysdeps/alpha/fpu/s_ccoshf.c b/libc/sysdeps/alpha/fpu/s_ccoshf.c
new file mode 100644
index 000000000..e9fb34ce4
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_ccoshf.c
@@ -0,0 +1,51 @@
+/* Return hyperbole cosine of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __ccoshf __ccoshf_not_defined
+#define ccoshf ccoshf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __ccoshf
+#undef ccoshf
+#define __ccoshf internal_ccoshf
+
+static _Complex float internal_ccoshf (_Complex float x);
+
+#include <math/s_ccoshf.c>
+#include "cfloat-compat.h"
+
+#undef __ccoshf
+
+c1_cfloat_rettype
+__c1_ccoshf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_ccoshf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_ccoshf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_ccoshf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (ccoshf);
diff --git a/libc/sysdeps/alpha/fpu/s_ceil.c b/libc/sysdeps/alpha/fpu/s_ceil.c
new file mode 100644
index 000000000..ec58fd948
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_ceil.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1998, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+/* Use the -inf rounding mode conversion instructions to implement
+ ceil, via something akin to -floor(-x). This is much faster than
+ playing with the fpcr to achieve +inf rounding mode. */
+
+double
+__ceil (double x)
+{
+ if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */
+ {
+ double tmp1, new_x;
+
+ new_x = -x;
+ __asm (
+#ifdef _IEEE_FP_INEXACT
+ "cvttq/svim %2,%1\n\t"
+#else
+ "cvttq/svm %2,%1\n\t"
+#endif
+ "cvtqt/m %1,%0\n\t"
+ : "=f"(new_x), "=&f"(tmp1)
+ : "f"(new_x));
+
+ /* Fix up the negation we did above, as well as handling -0 properly. */
+ x = copysign(new_x, x);
+ }
+ return x;
+}
+
+weak_alias (__ceil, ceil)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__ceil, __ceill)
+weak_alias (__ceil, ceill)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __ceil, ceill, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/alpha/fpu/s_ceilf.c b/libc/sysdeps/alpha/fpu/s_ceilf.c
new file mode 100644
index 000000000..aba1697a5
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_ceilf.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+/* Use the -inf rounding mode conversion instructions to implement
+ ceil, via something akin to -floor(-x). This is much faster than
+ playing with the fpcr to achieve +inf rounding mode. */
+
+float
+__ceilf (float x)
+{
+ if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */
+ {
+ /* Note that Alpha S_Floating is stored in registers in a
+ restricted T_Floating format, so we don't even need to
+ convert back to S_Floating in the end. The initial
+ conversion to T_Floating is needed to handle denormals. */
+
+ float tmp1, tmp2, new_x;
+
+ new_x = -x;
+ __asm ("cvtst/s %3,%2\n\t"
+#ifdef _IEEE_FP_INEXACT
+ "cvttq/svim %2,%1\n\t"
+#else
+ "cvttq/svm %2,%1\n\t"
+#endif
+ "cvtqt/m %1,%0\n\t"
+ : "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2)
+ : "f"(new_x));
+
+ /* Fix up the negation we did above, as well as handling -0 properly. */
+ x = copysignf(new_x, x);
+ }
+ return x;
+}
+
+weak_alias (__ceilf, ceilf)
diff --git a/libc/sysdeps/alpha/fpu/s_cexpf.c b/libc/sysdeps/alpha/fpu/s_cexpf.c
new file mode 100644
index 000000000..4a28dcd9b
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_cexpf.c
@@ -0,0 +1,51 @@
+/* Return exponent of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __cexpf __cexpf_not_defined
+#define cexpf cexpf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __cexpf
+#undef cexpf
+#define __cexpf internal_cexpf
+
+static _Complex float internal_cexpf (_Complex float x);
+
+#include <math/s_cexpf.c>
+#include "cfloat-compat.h"
+
+#undef __cexpf
+
+c1_cfloat_rettype
+__c1_cexpf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_cexpf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_cexpf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_cexpf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (cexpf);
diff --git a/libc/sysdeps/alpha/fpu/s_clog10f.c b/libc/sysdeps/alpha/fpu/s_clog10f.c
new file mode 100644
index 000000000..e7dc7bb23
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_clog10f.c
@@ -0,0 +1,61 @@
+/* Return base 10 logarithm of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __clog10f __clog10f_not_defined
+#define clog10f clog10f_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __clog10f
+#undef clog10f
+#define __clog10f internal_clog10f
+
+static _Complex float internal_clog10f (_Complex float x);
+
+#include <math/s_clog10f.c>
+#include "cfloat-compat.h"
+
+#undef __clog10f
+
+c1_cfloat_rettype
+__c1_clog10f (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_clog10f (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_clog10f (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_clog10f (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+/* Ug. __clog10f was exported from GLIBC_2.1. This is the only
+ complex function whose double-underscore symbol was exported,
+ so we get to handle that specially. */
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_3_4)
+strong_alias (__c1_clog10f, __c1_clog10f_2);
+compat_symbol (libm, __c1_clog10f, clog10f, GLIBC_2_1);
+compat_symbol (libm, __c1_clog10f_2, __clog10f, GLIBC_2_1);
+#endif
+versioned_symbol (libm, __c2_clog10f, clog10f, GLIBC_2_3_4);
+extern typeof(__c2_clog10f) __clog10f attribute_hidden;
+strong_alias (__c2_clog10f, __clog10f)
diff --git a/libc/sysdeps/alpha/fpu/s_clogf.c b/libc/sysdeps/alpha/fpu/s_clogf.c
new file mode 100644
index 000000000..364dcec88
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_clogf.c
@@ -0,0 +1,51 @@
+/* Return natural logarithm of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __clogf __clogf_not_defined
+#define clogf clogf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __clogf
+#undef clogf
+#define __clogf internal_clogf
+
+static _Complex float internal_clogf (_Complex float x);
+
+#include <math/s_clogf.c>
+#include "cfloat-compat.h"
+
+#undef __clogf
+
+c1_cfloat_rettype
+__c1_clogf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_clogf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_clogf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_clogf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (clogf);
diff --git a/libc/sysdeps/alpha/fpu/s_copysign.c b/libc/sysdeps/alpha/fpu/s_copysign.c
new file mode 100644
index 000000000..52c632ec4
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_copysign.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+double
+__copysign (double x, double y)
+{
+ __asm ("cpys %1, %2, %0" : "=f" (x) : "f" (y), "f" (x));
+ return x;
+}
+
+weak_alias (__copysign, copysign)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__copysign, __copysignl)
+weak_alias (__copysign, copysignl)
+#endif
+#ifdef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __copysign, copysignl, GLIBC_2_0);
+# endif
+#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __copysign, copysignl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/alpha/fpu/s_copysignf.c b/libc/sysdeps/alpha/fpu/s_copysignf.c
new file mode 100644
index 000000000..f4b846bcb
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_copysignf.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+float
+__copysignf (float x, float y)
+{
+ __asm ("cpys %1, %2, %0" : "=f" (x) : "f" (y), "f" (x));
+ return x;
+}
+
+weak_alias (__copysignf, copysignf)
diff --git a/libc/sysdeps/alpha/fpu/s_cpowf.c b/libc/sysdeps/alpha/fpu/s_cpowf.c
new file mode 100644
index 000000000..cc61b1895
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_cpowf.c
@@ -0,0 +1,51 @@
+/* Return power of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __cpowf __cpowf_not_defined
+#define cpowf cpowf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __cpowf
+#undef cpowf
+#define __cpowf internal_cpowf
+
+static _Complex float internal_cpowf (_Complex float x, _Complex float c);
+
+#include <math/s_cpowf.c>
+#include "cfloat-compat.h"
+
+#undef __cpowf
+
+c1_cfloat_rettype
+__c1_cpowf (c1_cfloat_decl (x), c1_cfloat_decl (c))
+{
+ _Complex float r = internal_cpowf (c1_cfloat_value (x), c1_cfloat_value (c));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_cpowf (c2_cfloat_decl (x), c2_cfloat_decl (c))
+{
+ _Complex float r = internal_cpowf (c2_cfloat_value (x), c2_cfloat_value (c));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (cpowf);
diff --git a/libc/sysdeps/alpha/fpu/s_cprojf.c b/libc/sysdeps/alpha/fpu/s_cprojf.c
new file mode 100644
index 000000000..5cfb52667
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_cprojf.c
@@ -0,0 +1,51 @@
+/* Return projection of complex float value to Riemann sphere.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __cprojf __cprojf_not_defined
+#define cprojf cprojf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __cprojf
+#undef cprojf
+#define __cprojf internal_cprojf
+
+static _Complex float internal_cprojf (_Complex float x);
+
+#include <math/s_cprojf.c>
+#include "cfloat-compat.h"
+
+#undef __cprojf
+
+c1_cfloat_rettype
+__c1_cprojf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_cprojf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_cprojf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_cprojf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (cprojf);
diff --git a/libc/sysdeps/alpha/fpu/s_csinf.c b/libc/sysdeps/alpha/fpu/s_csinf.c
new file mode 100644
index 000000000..8eb9a1019
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_csinf.c
@@ -0,0 +1,51 @@
+/* Return sine of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __csinf __csinf_not_defined
+#define csinf csinf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __csinf
+#undef csinf
+#define __csinf internal_csinf
+
+static _Complex float internal_csinf (_Complex float x);
+
+#include <math/s_csinf.c>
+#include "cfloat-compat.h"
+
+#undef __csinf
+
+c1_cfloat_rettype
+__c1_csinf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_csinf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_csinf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_csinf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (csinf);
diff --git a/libc/sysdeps/alpha/fpu/s_csinhf.c b/libc/sysdeps/alpha/fpu/s_csinhf.c
new file mode 100644
index 000000000..0e2c18674
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_csinhf.c
@@ -0,0 +1,51 @@
+/* Return hyperbole sine of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __csinhf __csinhf_not_defined
+#define csinhf csinhf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __csinhf
+#undef csinhf
+#define __csinhf internal_csinhf
+
+static _Complex float internal_csinhf (_Complex float x);
+
+#include <math/s_csinhf.c>
+#include "cfloat-compat.h"
+
+#undef __csinhf
+
+c1_cfloat_rettype
+__c1_csinhf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_csinhf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_csinhf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_csinhf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (csinhf);
diff --git a/libc/sysdeps/alpha/fpu/s_csqrtf.c b/libc/sysdeps/alpha/fpu/s_csqrtf.c
new file mode 100644
index 000000000..ebf23a828
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_csqrtf.c
@@ -0,0 +1,51 @@
+/* Return square root of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __csqrtf __csinhf_not_defined
+#define csqrtf csqrtf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __csqrtf
+#undef csqrtf
+#define __csqrtf internal_csqrtf
+
+static _Complex float internal_csqrtf (_Complex float x);
+
+#include <math/s_csqrtf.c>
+#include "cfloat-compat.h"
+
+#undef __csqrtf
+
+c1_cfloat_rettype
+__c1_csqrtf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_csqrtf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_csqrtf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_csqrtf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (csqrtf);
diff --git a/libc/sysdeps/alpha/fpu/s_ctanf.c b/libc/sysdeps/alpha/fpu/s_ctanf.c
new file mode 100644
index 000000000..e26db963e
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_ctanf.c
@@ -0,0 +1,51 @@
+/* Return tangent of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __ctanf __ctanf_not_defined
+#define ctanf ctanf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __ctanf
+#undef ctanf
+#define __ctanf internal_ctanf
+
+static _Complex float internal_ctanf (_Complex float x);
+
+#include <math/s_ctanf.c>
+#include "cfloat-compat.h"
+
+#undef __ctanf
+
+c1_cfloat_rettype
+__c1_ctanf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_ctanf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_ctanf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_ctanf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (ctanf);
diff --git a/libc/sysdeps/alpha/fpu/s_ctanhf.c b/libc/sysdeps/alpha/fpu/s_ctanhf.c
new file mode 100644
index 000000000..5d047bd46
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_ctanhf.c
@@ -0,0 +1,51 @@
+/* Return hyperbole tangent of complex float value.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __ctanhf __ctanhf_not_defined
+#define ctanhf ctanhf_not_defined
+
+#include <complex.h>
+#include <math.h>
+
+#undef __ctanhf
+#undef ctanhf
+#define __ctanhf internal_ctanhf
+
+static _Complex float internal_ctanhf (_Complex float x);
+
+#include <math/s_ctanhf.c>
+#include "cfloat-compat.h"
+
+#undef __ctanhf
+
+c1_cfloat_rettype
+__c1_ctanhf (c1_cfloat_decl (x))
+{
+ _Complex float r = internal_ctanhf (c1_cfloat_value (x));
+ return c1_cfloat_return (r);
+}
+
+c2_cfloat_rettype
+__c2_ctanhf (c2_cfloat_decl (x))
+{
+ _Complex float r = internal_ctanhf (c2_cfloat_value (x));
+ return c2_cfloat_return (r);
+}
+
+cfloat_versions (ctanhf);
diff --git a/libc/sysdeps/alpha/fpu/s_fabs.c b/libc/sysdeps/alpha/fpu/s_fabs.c
new file mode 100644
index 000000000..9bc42f68d
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_fabs.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+double
+__fabs (double x)
+{
+#if __GNUC_PREREQ (2, 8)
+ return __builtin_fabs (x);
+#else
+ __asm ("cpys $f31, %1, %0" : "=f" (x) : "f" (x));
+ return x;
+#endif
+}
+
+weak_alias (__fabs, fabs)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__fabs, __fabsl)
+weak_alias (__fabs, fabsl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __fabs, fabsl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/alpha/fpu/s_fabsf.c b/libc/sysdeps/alpha/fpu/s_fabsf.c
new file mode 100644
index 000000000..35e16bf65
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_fabsf.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+float
+__fabsf (float x)
+{
+#if __GNUC_PREREQ (2, 8)
+ return __builtin_fabsf (x);
+#else
+ __asm ("cpys $f31, %1, %0" : "=f" (x) : "f" (x));
+ return x;
+#endif
+}
+
+weak_alias (__fabsf, fabsf)
diff --git a/libc/sysdeps/alpha/fpu/s_floor.c b/libc/sysdeps/alpha/fpu/s_floor.c
new file mode 100644
index 000000000..b22c52303
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_floor.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1998, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+
+/* Use the -inf rounding mode conversion instructions to implement
+ floor. We note when the exponent is large enough that the value
+ must be integral, as this avoids unpleasant integer overflows. */
+
+double
+__floor (double x)
+{
+ if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */
+ {
+ double tmp1, new_x;
+
+ __asm (
+#ifdef _IEEE_FP_INEXACT
+ "cvttq/svim %2,%1\n\t"
+#else
+ "cvttq/svm %2,%1\n\t"
+#endif
+ "cvtqt/m %1,%0\n\t"
+ : "=f"(new_x), "=&f"(tmp1)
+ : "f"(x));
+
+ /* floor(-0) == -0, and in general we'll always have the same
+ sign as our input. */
+ x = copysign(new_x, x);
+ }
+ return x;
+}
+
+weak_alias (__floor, floor)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__floor, __floorl)
+weak_alias (__floor, floorl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __floor, floorl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/alpha/fpu/s_floorf.c b/libc/sysdeps/alpha/fpu/s_floorf.c
new file mode 100644
index 000000000..fd1ddab6b
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_floorf.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+
+/* Use the -inf rounding mode conversion instructions to implement
+ floor. We note when the exponent is large enough that the value
+ must be integral, as this avoids unpleasant integer overflows. */
+
+float
+__floorf (float x)
+{
+ if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */
+ {
+ /* Note that Alpha S_Floating is stored in registers in a
+ restricted T_Floating format, so we don't even need to
+ convert back to S_Floating in the end. The initial
+ conversion to T_Floating is needed to handle denormals. */
+
+ float tmp1, tmp2, new_x;
+
+ __asm ("cvtst/s %3,%2\n\t"
+#ifdef _IEEE_FP_INEXACT
+ "cvttq/svim %2,%1\n\t"
+#else
+ "cvttq/svm %2,%1\n\t"
+#endif
+ "cvtqt/m %1,%0\n\t"
+ : "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2)
+ : "f"(x));
+
+ /* floor(-0) == -0, and in general we'll always have the same
+ sign as our input. */
+ x = copysignf(new_x, x);
+ }
+ return x;
+}
+
+weak_alias (__floorf, floorf)
diff --git a/libc/sysdeps/alpha/fpu/s_rint.c b/libc/sysdeps/alpha/fpu/s_rint.c
new file mode 100644
index 000000000..be09651b3
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_rint.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+
+double
+__rint (double x)
+{
+ if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */
+ {
+ double tmp1, new_x;
+ __asm (
+#ifdef _IEEE_FP_INEXACT
+ "cvttq/svid %2,%1\n\t"
+#else
+ "cvttq/svd %2,%1\n\t"
+#endif
+ "cvtqt/d %1,%0\n\t"
+ : "=f"(new_x), "=&f"(tmp1)
+ : "f"(x));
+
+ /* rint(-0.1) == -0, and in general we'll always have the same
+ sign as our input. */
+ x = copysign(new_x, x);
+ }
+ return x;
+}
+
+weak_alias (__rint, rint)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__rint, __rintl)
+weak_alias (__rint, rintl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __rint, rintl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/alpha/fpu/s_rintf.c b/libc/sysdeps/alpha/fpu/s_rintf.c
new file mode 100644
index 000000000..d5d019d70
--- /dev/null
+++ b/libc/sysdeps/alpha/fpu/s_rintf.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+
+float
+__rintf (float x)
+{
+ if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */
+ {
+ /* Note that Alpha S_Floating is stored in registers in a
+ restricted T_Floating format, so we don't even need to
+ convert back to S_Floating in the end. The initial
+ conversion to T_Floating is needed to handle denormals. */
+
+ float tmp1, tmp2, new_x;
+
+ __asm ("cvtst/s %3,%2\n\t"
+#ifdef _IEEE_FP_INEXACT
+ "cvttq/svid %2,%1\n\t"
+#else
+ "cvttq/svd %2,%1\n\t"
+#endif
+ "cvtqt/d %1,%0\n\t"
+ : "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2)
+ : "f"(x));
+
+ /* rint(-0.1) == -0, and in general we'll always have the same
+ sign as our input. */
+ x = copysignf(new_x, x);
+ }
+ return x;
+}
+
+weak_alias (__rintf, rintf)
diff --git a/libc/sysdeps/alpha/gccframe.h b/libc/sysdeps/alpha/gccframe.h
new file mode 100644
index 000000000..b67022548
--- /dev/null
+++ b/libc/sysdeps/alpha/gccframe.h
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. alpha version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FIRST_PSEUDO_REGISTER 64
+
+#include <sysdeps/generic/gccframe.h>
diff --git a/libc/sysdeps/alpha/hp-timing.h b/libc/sysdeps/alpha/hp-timing.h
new file mode 100644
index 000000000..ccae06b48
--- /dev/null
+++ b/libc/sysdeps/alpha/hp-timing.h
@@ -0,0 +1,118 @@
+/* High precision, low overhead timing functions. Alpha version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@redhat.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H 1
+
+#include <string.h>
+#include <sys/param.h>
+#include <stdio-common/_itoa.h>
+
+/* The macros defined here use the timestamp counter in IA-64. They
+ provide a very accurate way to measure the time with very little
+ overhead. The time values themself have no real meaning, only
+ differences are interesting.
+
+ The list of macros we need includes the following:
+
+ - HP_TIMING_AVAIL: test for availability.
+
+ - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
+ implemented using function calls but instead uses some inlined code
+ which might simply consist of a few assembler instructions. We have to
+ know this since we might want to use the macros here in places where we
+ cannot make function calls.
+
+ - hp_timing_t: This is the type for variables used to store the time
+ values.
+
+ - HP_TIMING_ZERO: clear `hp_timing_t' object.
+
+ - HP_TIMING_NOW: place timestamp for current time in variable given as
+ parameter.
+
+ - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
+ HP_TIMING_DIFF macro.
+
+ - HP_TIMING_DIFF: compute difference between two times and store it
+ in a third. Source and destination might overlap.
+
+ - HP_TIMING_ACCUM: add time difference to another variable. This might
+ be a bit more complicated to implement for some platforms as the
+ operation should be thread-safe and 64bit arithmetic on 32bit platforms
+ is not.
+
+ - HP_TIMING_ACCUM_NT: this is the variant for situations where we know
+ there are no threads involved.
+
+ - HP_TIMING_PRINT: write decimal representation of the timing value into
+ the given string. This operation need not be inline even though
+ HP_TIMING_INLINE is specified.
+*/
+
+/* We always have the timestamp register, but it's got only a 4 second
+ range. Use it for ld.so profiling only. */
+#define HP_TIMING_AVAIL (0)
+#define HP_SMALL_TIMING_AVAIL (1)
+
+/* We indeed have inlined functions. */
+#define HP_TIMING_INLINE (1)
+
+/* We use 32 bit values for the times. */
+typedef unsigned int hp_timing_t;
+
+/* Set timestamp value to zero. */
+#define HP_TIMING_ZERO(VAR) (VAR) = (0)
+
+/* The "rpcc" instruction returns a 32-bit counting half and a 32-bit
+ "virtual cycle counter displacement". Subtracting the two gives us
+ a virtual cycle count. */
+#define HP_TIMING_NOW(VAR) \
+ do { \
+ unsigned long int x_; \
+ asm volatile ("rpcc %0" : "=r"(x_)); \
+ (VAR) = (int) (x_) - (int) (x_ >> 32); \
+ } while (0)
+
+/* ??? Two rpcc instructions can be scheduled simultaneously. */
+#define HP_TIMING_DIFF_INIT() do { } while (0)
+
+/* It's simple arithmetic for us. */
+#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start))
+
+/* ??? Don't bother, since we're only used for ld.so. */
+#define HP_TIMING_ACCUM(Sum, Diff) not implemented
+
+/* No threads, no extra work. */
+#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff)
+
+/* Print the time value. */
+#define HP_TIMING_PRINT(Buf, Len, Val) \
+ do { \
+ char __buf[20]; \
+ char *__cp = _itoa_word (Val, __buf + sizeof (__buf), 10, 0); \
+ int __len = (Len); \
+ char *__dest = (Buf); \
+ while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \
+ *__dest++ = *__cp++; \
+ memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles"))); \
+ } while (0)
+
+#endif /* hp-timing.h */
diff --git a/libc/sysdeps/alpha/htonl.S b/libc/sysdeps/alpha/htonl.S
new file mode 100644
index 000000000..ef2a57599
--- /dev/null
+++ b/libc/sysdeps/alpha/htonl.S
@@ -0,0 +1,44 @@
+/* Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY(htonl)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ inslh a0, 7, t0 # t0 = 0000000000AABBCC
+ inswl a0, 3, t1 # t1 = 000000CCDD000000
+ or t1, t0, t1 # t1 = 000000CCDDAABBCC
+ srl t1, 16, t2 # t2 = 0000000000CCDDAA
+ zapnot t1, 0x0A, t0 # t0 = 00000000DD00BB00
+ zapnot t2, 0x05, t3 # t3 = 0000000000CC00AA
+ addl t0, t3, v0 # v0 = ssssssssDDCCBBAA
+ ret
+
+ END(htonl)
+
+weak_alias (htonl, ntohl)
diff --git a/libc/sysdeps/alpha/htons.S b/libc/sysdeps/alpha/htons.S
new file mode 100644
index 000000000..7c6270226
--- /dev/null
+++ b/libc/sysdeps/alpha/htons.S
@@ -0,0 +1,40 @@
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY(htons)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ extwh a0, 7, t1 # t1 = bb00
+ extbl a0, 1, v0 # v0 = 00aa
+ bis v0, t1, v0 # v0 = bbaa
+ ret
+
+ END(htons)
+
+weak_alias (htons, ntohs)
diff --git a/libc/sysdeps/alpha/jmpbuf-offsets.h b/libc/sysdeps/alpha/jmpbuf-offsets.h
new file mode 100644
index 000000000..c2503d442
--- /dev/null
+++ b/libc/sysdeps/alpha/jmpbuf-offsets.h
@@ -0,0 +1,36 @@
+/* Private macros for accessing __jmp_buf contents. Alpha version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define JB_S0 0
+#define JB_S1 1
+#define JB_S2 2
+#define JB_S3 3
+#define JB_S4 4
+#define JB_S5 5
+#define JB_PC 6
+#define JB_FP 7
+#define JB_SP 8
+#define JB_F2 9
+#define JB_F3 10
+#define JB_F4 11
+#define JB_F5 12
+#define JB_F6 13
+#define JB_F7 14
+#define JB_F8 15
+#define JB_F9 16
diff --git a/libc/sysdeps/alpha/jmpbuf-unwind.h b/libc/sysdeps/alpha/jmpbuf-unwind.h
new file mode 100644
index 000000000..ca5f693d5
--- /dev/null
+++ b/libc/sysdeps/alpha/jmpbuf-unwind.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <stdint.h>
+#include <unwind.h>
+#include <sysdep.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame containing a local
+ variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(_jmpbuf, _address, _demangle) \
+ ((void *)(_address) < (void *) _demangle ((_jmpbuf)[JB_SP]))
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+static inline uintptr_t __attribute__ ((unused))
+_jmpbuf_sp (__jmp_buf regs)
+{
+ uintptr_t sp = regs[JB_SP];
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (sp);
+#endif
+ return sp;
+}
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
+
+/* We use the normal longjmp for unwinding. */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libc/sysdeps/alpha/ldiv.S b/libc/sysdeps/alpha/ldiv.S
new file mode 100644
index 000000000..0a971a7ed
--- /dev/null
+++ b/libc/sysdeps/alpha/ldiv.S
@@ -0,0 +1,218 @@
+/* Copyright (C) 1996, 1997, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "div_libc.h"
+
+#undef FRAME
+#ifdef __alpha_fix__
+#define FRAME 0
+#else
+#define FRAME 16
+#endif
+
+#undef X
+#undef Y
+#define X $17
+#define Y $18
+
+ .set noat
+
+ .align 4
+ .globl ldiv
+ .ent ldiv
+ldiv:
+ .frame sp, FRAME, ra
+#if FRAME > 0
+ lda sp, -FRAME(sp)
+#endif
+#ifdef PROF
+ .set macro
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set nomacro
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ beq Y, $divbyzero
+ excb
+ mf_fpcr $f10
+
+ _ITOFT2 X, $f0, 0, Y, $f1, 8
+
+ .align 4
+ cvtqt $f0, $f0
+ cvtqt $f1, $f1
+ divt/c $f0, $f1, $f0
+ unop
+
+ /* Check to see if X fit in the double as an exact value. */
+ sll X, (64-53), AT
+ sra AT, (64-53), AT
+ cmpeq X, AT, AT
+ beq AT, $x_big
+
+ /* If we get here, we're expecting exact results from the division.
+ Do nothing else besides convert and clean up. */
+ cvttq/c $f0, $f0
+ excb
+ mt_fpcr $f10
+ _FTOIT $f0, $0, 0
+
+$egress:
+ mulq $0, Y, $1
+ subq X, $1, $1
+
+ stq $0, 0($16)
+ stq $1, 8($16)
+ mov $16, $0
+
+#if FRAME > 0
+ lda sp, FRAME(sp)
+#endif
+ ret
+
+ .align 4
+$x_big:
+ /* If we get here, X is large enough that we don't expect exact
+ results, and neither X nor Y got mis-translated for the fp
+ division. Our task is to take the fp result, figure out how
+ far it's off from the correct result and compute a fixup. */
+
+#define Q v0 /* quotient */
+#define R t0 /* remainder */
+#define SY t1 /* scaled Y */
+#define S t2 /* scalar */
+#define QY t3 /* Q*Y */
+
+ /* The fixup code below can only handle unsigned values. */
+ or X, Y, AT
+ mov $31, t5
+ blt AT, $fix_sign_in
+$fix_sign_in_ret1:
+ cvttq/c $f0, $f0
+
+ _FTOIT $f0, Q, 8
+$fix_sign_in_ret2:
+ mulq Q, Y, QY
+ excb
+ mt_fpcr $f10
+
+ .align 4
+ subq QY, X, R
+ mov Y, SY
+ mov 1, S
+ bgt R, $q_high
+
+$q_high_ret:
+ subq X, QY, R
+ mov Y, SY
+ mov 1, S
+ bgt R, $q_low
+
+$q_low_ret:
+ negq Q, t4
+ cmovlbs t5, t4, Q
+ br $egress
+
+ .align 4
+ /* The quotient that we computed was too large. We need to reduce
+ it by S such that Y*S >= R. Obviously the closer we get to the
+ correct value the better, but overshooting high is ok, as we'll
+ fix that up later. */
+0:
+ addq SY, SY, SY
+ addq S, S, S
+$q_high:
+ cmpult SY, R, AT
+ bne AT, 0b
+
+ subq Q, S, Q
+ unop
+ subq QY, SY, QY
+ br $q_high_ret
+
+ .align 4
+ /* The quotient that we computed was too small. Divide Y by the
+ current remainder (R) and add that to the existing quotient (Q).
+ The expectation, of course, is that R is much smaller than X. */
+ /* Begin with a shift-up loop. Compute S such that Y*S >= R. We
+ already have a copy of Y in SY and the value 1 in S. */
+0:
+ addq SY, SY, SY
+ addq S, S, S
+$q_low:
+ cmpult SY, R, AT
+ bne AT, 0b
+
+ /* Shift-down and subtract loop. Each iteration compares our scaled
+ Y (SY) with the remainder (R); if SY <= R then X is divisible by
+ Y's scalar (S) so add it to the quotient (Q). */
+2: addq Q, S, t3
+ srl S, 1, S
+ cmpule SY, R, AT
+ subq R, SY, t4
+
+ cmovne AT, t3, Q
+ cmovne AT, t4, R
+ srl SY, 1, SY
+ bne S, 2b
+
+ br $q_low_ret
+
+ .align 4
+$fix_sign_in:
+ /* If we got here, then X|Y is negative. Need to adjust everything
+ such that we're doing unsigned division in the fixup loop. */
+ /* T5 is true if result should be negative. */
+ xor X, Y, AT
+ cmplt AT, 0, t5
+ cmplt X, 0, AT
+ negq X, t0
+
+ cmovne AT, t0, X
+ cmplt Y, 0, AT
+ negq Y, t0
+
+ cmovne AT, t0, Y
+ blbc t5, $fix_sign_in_ret1
+
+ cvttq/c $f0, $f0
+ _FTOIT $f0, Q, 8
+ .align 3
+ negq Q, Q
+ br $fix_sign_in_ret2
+
+$divbyzero:
+ mov a0, v0
+ lda a0, GEN_INTDIV
+ call_pal PAL_gentrap
+ stq zero, 0(v0)
+ stq zero, 8(v0)
+
+#if FRAME > 0
+ lda sp, FRAME(sp)
+#endif
+ ret
+
+ .end ldiv
+
+weak_alias (ldiv, lldiv)
diff --git a/libc/sysdeps/alpha/libc-tls.c b/libc/sysdeps/alpha/libc-tls.c
new file mode 100644
index 000000000..24629e9ac
--- /dev/null
+++ b/libc/sysdeps/alpha/libc-tls.c
@@ -0,0 +1,37 @@
+/* Thread-local storage handling in the ELF dynamic linker. Alpha version.
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <csu/libc-tls.c>
+#include <dl-tls.h>
+
+#if USE_TLS
+
+/* On Alpha, linker optimizations are not required, so __tls_get_addr
+ can be called even in statically linked binaries. In this case module
+ must be always 1 and PT_TLS segment exist in the binary, otherwise it
+ would not link. */
+
+void *
+__tls_get_addr (tls_index *ti)
+{
+ dtv_t *dtv = THREAD_DTV ();
+ return (char *) dtv[1].pointer.val + ti->ti_offset;
+}
+
+#endif
diff --git a/libc/sysdeps/alpha/lldiv.S b/libc/sysdeps/alpha/lldiv.S
new file mode 100644
index 000000000..80c450a3f
--- /dev/null
+++ b/libc/sysdeps/alpha/lldiv.S
@@ -0,0 +1 @@
+/* lldiv is the same as ldiv on the Alpha. */
diff --git a/libc/sysdeps/alpha/lshift.s b/libc/sysdeps/alpha/lshift.s
new file mode 100644
index 000000000..42fb430dd
--- /dev/null
+++ b/libc/sysdeps/alpha/lshift.s
@@ -0,0 +1,109 @@
+ # Alpha 21064 __mpn_lshift --
+
+ # Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+ # This file is part of the GNU MP Library.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published by
+ # the Free Software Foundation; either version 2.1 of the License, or (at your
+ # option) any later version.
+
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+
+ # INPUT PARAMETERS
+ # res_ptr r16
+ # s1_ptr r17
+ # size r18
+ # cnt r19
+
+ # This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling,
+ # it would take 4 cycles/limb. It should be possible to get down to 3
+ # cycles/limb since both ldq and stq can be paired with the other used
+ # instructions. But there are many restrictions in the 21064 pipeline that
+ # makes it hard, if not impossible, to get down to 3 cycles/limb:
+
+ # 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay.
+ # 2. Only aligned instruction pairs can be paired.
+ # 3. The store buffer or silo might not be able to deal with the bandwidth.
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __mpn_lshift
+ .ent __mpn_lshift
+__mpn_lshift:
+ .frame $30,0,$26,0
+
+ s8addq $18,$17,$17 # make r17 point at end of s1
+ ldq $4,-8($17) # load first limb
+ subq $17,8,$17
+ subq $31,$19,$7
+ s8addq $18,$16,$16 # make r16 point at end of RES
+ subq $18,1,$18
+ and $18,4-1,$20 # number of limbs in first loop
+ srl $4,$7,$0 # compute function result
+
+ beq $20,.L0
+ subq $18,$20,$18
+
+ .align 3
+.Loop0:
+ ldq $3,-8($17)
+ subq $16,8,$16
+ subq $17,8,$17
+ subq $20,1,$20
+ sll $4,$19,$5
+ srl $3,$7,$6
+ bis $3,$3,$4
+ bis $5,$6,$8
+ stq $8,0($16)
+ bne $20,.Loop0
+
+.L0: beq $18,.Lend
+
+ .align 3
+.Loop: ldq $3,-8($17)
+ subq $16,32,$16
+ subq $18,4,$18
+ sll $4,$19,$5
+ srl $3,$7,$6
+
+ ldq $4,-16($17)
+ sll $3,$19,$1
+ bis $5,$6,$8
+ stq $8,24($16)
+ srl $4,$7,$2
+
+ ldq $3,-24($17)
+ sll $4,$19,$5
+ bis $1,$2,$8
+ stq $8,16($16)
+ srl $3,$7,$6
+
+ ldq $4,-32($17)
+ sll $3,$19,$1
+ bis $5,$6,$8
+ stq $8,8($16)
+ srl $4,$7,$2
+
+ subq $17,32,$17
+ bis $1,$2,$8
+ stq $8,0($16)
+
+ bgt $18,.Loop
+
+.Lend: sll $4,$19,$8
+ stq $8,-8($16)
+ ret $31,($26),1
+ .end __mpn_lshift
diff --git a/libc/sysdeps/alpha/machine-gmon.h b/libc/sysdeps/alpha/machine-gmon.h
new file mode 100644
index 000000000..5f5522c0b
--- /dev/null
+++ b/libc/sysdeps/alpha/machine-gmon.h
@@ -0,0 +1,26 @@
+/* Machine-specific calling sequence for `mcount' profiling function. alpha
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define _MCOUNT_DECL(from, self) \
+ void __mcount (u_long from, u_long self)
+
+/* Call __mcount with our the return PC for our caller, and the return
+ PC our caller will return to. Empty since we use an assembly stub
+ instead. */
+#define MCOUNT
diff --git a/libc/sysdeps/alpha/memchr.S b/libc/sysdeps/alpha/memchr.S
new file mode 100644
index 000000000..5d713d53b
--- /dev/null
+++ b/libc/sysdeps/alpha/memchr.S
@@ -0,0 +1,176 @@
+/* Copyright (C) 1996, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger (davidm@cs.arizona.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Finds characters in a memory area. Optimized for the Alpha:
+
+ - memory accessed as aligned quadwords only
+ - uses cmpbge to compare 8 bytes in parallel
+ - does binary search to find 0 byte in last
+ quadword (HAKMEM needed 12 instructions to
+ do this instead of the 9 instructions that
+ binary search needs).
+
+For correctness consider that:
+
+ - only minimum number of quadwords may be accessed
+ - the third argument is an unsigned long
+*/
+
+#include <sysdep.h>
+
+ .set noreorder
+ .set noat
+
+ENTRY(__memchr)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ # Hack -- if someone passes in (size_t)-1, hoping to just
+ # search til the end of the address space, we will overflow
+ # below when we find the address of the last byte. Given
+ # that we will never have a 56-bit address space, cropping
+ # the length is the easiest way to avoid trouble.
+ zap a2, 0x80, t4 #-e0 :
+
+ beq a2, $not_found # .. e1 :
+ ldq_u t0, 0(a0) # e1 : load first quadword
+ insbl a1, 1, t1 # .. e0 : t1 = 000000000000ch00
+ and a1, 0xff, a1 #-e0 : a1 = 00000000000000ch
+ cmpult a2, 9, t3 # .. e1 :
+ or t1, a1, a1 # e0 : a1 = 000000000000chch
+ lda t2, -1(zero) # .. e1 :
+ sll a1, 16, t1 #-e0 : t1 = 00000000chch0000
+ addq a0, t4, t4 # .. e1 :
+ or t1, a1, a1 # e1 : a1 = 00000000chchchch
+ unop # :
+ sll a1, 32, t1 #-e0 : t1 = chchchch00000000
+ or t1, a1, a1 # e1 : a1 = chchchchchchchch
+ extql t0, a0, t6 # e0 :
+ beq t3, $first_quad # .. e1 :
+
+ ldq_u t5, -1(t4) #-e1 : eight or less bytes to search
+ extqh t5, a0, t5 # .. e0 :
+ mov a0, v0 # e0 :
+ or t6, t5, t0 # .. e1 : t0 = quadword starting at a0
+
+ # Deal with the case where at most 8 bytes remain to be searched
+ # in t0. E.g.:
+ # a2 = 6
+ # t0 = ????c6c5c4c3c2c1
+$last_quad:
+ negq a2, t5 #-e0 :
+ xor a1, t0, t0 # .. e1 :
+ srl t2, t5, t5 # e0 : t5 = mask of a2 bits set
+ cmpbge zero, t0, t1 # .. e1 :
+ and t1, t5, t1 #-e0 :
+ beq t1, $not_found # .. e1 :
+
+$found_it:
+ # Now, determine which byte matched:
+ negq t1, t2 # e0 :
+ and t1, t2, t1 # e1 :
+
+ and t1, 0x0f, t0 #-e0 :
+ addq v0, 4, t2 # .. e1 :
+ cmoveq t0, t2, v0 # e0 :
+
+ addq v0, 2, t2 # .. e1 :
+ and t1, 0x33, t0 #-e0 :
+ cmoveq t0, t2, v0 # .. e1 :
+
+ and t1, 0x55, t0 # e0 :
+ addq v0, 1, t2 # .. e1 :
+ cmoveq t0, t2, v0 #-e0 :
+
+$done: ret # .. e1 :
+
+ # Deal with the case where a2 > 8 bytes remain to be
+ # searched. a0 may not be aligned.
+ .align 4
+$first_quad:
+ andnot a0, 0x7, v0 #-e1 :
+ insqh t2, a0, t1 # .. e0 : t1 = 0000ffffffffffff (a0<0:2> ff)
+ xor t0, a1, t0 # e0 :
+ or t0, t1, t0 # e1 : t0 = ====ffffffffffff
+ cmpbge zero, t0, t1 #-e0 :
+ bne t1, $found_it # .. e1 :
+
+ # At least one byte left to process.
+
+ ldq t0, 8(v0) # e0 :
+ subq t4, 1, a2 # .. e1 :
+ addq v0, 8, v0 #-e0 :
+
+ # Make a2 point to last quad to be accessed (the
+ # last quad may or may not be partial).
+
+ andnot a2, 0x7, a2 # .. e1 :
+ cmpult v0, a2, t1 # e0 :
+ beq t1, $final # .. e1 :
+
+ # At least two quads remain to be accessed.
+
+ subq a2, v0, t3 #-e0 : t3 <- nr quads to be processed
+ and t3, 8, t3 # e1 : odd number of quads?
+ bne t3, $odd_quad_count # e1 :
+
+ # At least three quads remain to be accessed
+
+ mov t0, t3 # e0 : move prefetched value to correct reg
+
+ .align 4
+$unrolled_loop:
+ ldq t0, 8(v0) #-e0 : prefetch t0
+ xor a1, t3, t1 # .. e1 :
+ cmpbge zero, t1, t1 # e0 :
+ bne t1, $found_it # .. e1 :
+
+ addq v0, 8, v0 #-e0 :
+$odd_quad_count:
+ xor a1, t0, t1 # .. e1 :
+ ldq t3, 8(v0) # e0 : prefetch t3
+ cmpbge zero, t1, t1 # .. e1 :
+ addq v0, 8, t5 #-e0 :
+ bne t1, $found_it # .. e1 :
+
+ cmpult t5, a2, t5 # e0 :
+ addq v0, 8, v0 # .. e1 :
+ bne t5, $unrolled_loop #-e1 :
+
+ mov t3, t0 # e0 : move prefetched value into t0
+$final: subq t4, v0, a2 # .. e1 : a2 <- number of bytes left to do
+ bne a2, $last_quad # e1 :
+
+$not_found:
+ mov zero, v0 #-e0 :
+ ret # .. e1 :
+
+ END(__memchr)
+
+weak_alias (__memchr, memchr)
+#if !__BOUNDED_POINTERS__
+weak_alias (__memchr, __ubp_memchr)
+#endif
+libc_hidden_builtin_def (memchr)
diff --git a/libc/sysdeps/alpha/memset.S b/libc/sysdeps/alpha/memset.S
new file mode 100644
index 000000000..e34af2b31
--- /dev/null
+++ b/libc/sysdeps/alpha/memset.S
@@ -0,0 +1,137 @@
+/* Copyright (C) 1996, 1997, 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu)
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Fill a block of memory with a character. Optimized for the Alpha
+ architecture:
+
+ - memory accessed as aligned quadwords only
+ - destination memory not read unless needed for good cache behaviour
+ - basic blocks arranged to optimize branch prediction for full-quadword
+ aligned memory blocks.
+ - partial head and tail quadwords constructed with byte-mask instructions
+
+ This is generally scheduled for the EV5 (got to look out for my own
+ interests :-), but with EV4 needs in mind. There *should* be no more
+ stalls for the EV4 than there are for the EV5.
+*/
+
+
+#include <sysdep.h>
+
+ .set noat
+ .set noreorder
+
+ .text
+
+/* There is a problem with either gdb (as of 4.16) or gas (as of 2.7) that
+ doesn't like putting the entry point for a procedure somewhere in the
+ middle of the procedure descriptor. Work around this by putting the main
+ loop in its own procedure descriptor. */
+
+ /* On entry to this basic block:
+ t3 == loop counter
+ t4 == bytes in partial final word
+ a0 == possibly misaligned destination pointer
+ a1 == replicated source character */
+
+ .ent memset_loop
+ .align 3
+memset_loop:
+ .frame sp, 0, ra, 0
+ .prologue 0
+
+ beq t3, $tail
+ blbc t3, 0f # skip single store if count even
+
+ stq_u a1, 0(a0) # e0 : store one word
+ subq t3, 1, t3 # .. e1 :
+ addq a0, 8, a0 # e0 :
+ beq t3, $tail # .. e1 :
+
+0: stq_u a1, 0(a0) # e0 : store two words
+ subq t3, 2, t3 # .. e1 :
+ stq_u a1, 8(a0) # e0 :
+ addq a0, 16, a0 # .. e1 :
+ bne t3, 0b # e1 :
+
+$tail: bne t4, 1f # is there a tail to do?
+ ret # no
+
+ .align 3
+1: ldq_u t0, 0(a0) # e1 : yes, load original data
+ mskql a1, t4, t1 # .. e0 :
+ mskqh t0, t4, t0 # e0 :
+ or t0, t1, t0 # e1 (stall)
+ stq_u t0, 0(a0) # e0 :
+ ret # .. e1 :
+
+ .end memset_loop
+
+ENTRY(memset)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ zapnot a1, 1, a1 # e0 : zero extend input character
+ mov a0, v0 # .. e1 : move return value in place
+ sll a1, 8, t0 # e0 : begin replicating the char
+ beq a2, $done # .. e1 : early exit for zero-length store
+ or t0, a1, a1 # e0 :
+ and a0, 7, t1 # .. e1 : dest misalignment
+ sll a1, 16, t0 # e0 :
+ addq a2, t1, a2 # .. e1 : add dest misalignment to count
+ or t0, a1, a1 # e0 :
+ srl a2, 3, t3 # .. e1 : loop = count >> 3
+ sll a1, 32, t0 # e0 :
+ and a2, 7, t4 # .. e1 : find number of bytes in tail
+ or t0, a1, a1 # e0 : character replication done
+
+ beq t1, memset_loop # .. e1 : aligned head, jump right in
+
+ ldq_u t0, 0(a0) # e1 : load original data to mask into
+ mskqh a1, a0, t1 # .. e0 :
+
+ cmpult a2, 8, t2 # e0 : is this a sub-word set?
+ bne t2, $oneq # .. e1 (zdb)
+
+ mskql t0, a0, t0 # e0 : we span words. finish this partial
+ subq t3, 1, t3 # .. e1 :
+ addq a0, 8, a0 # e0 :
+ or t0, t1, t0 # .. e1 :
+ stq_u t0, -8(a0) # e0 :
+ br memset_loop # .. e1 :
+
+ .align 3
+$oneq:
+ mskql t1, a2, t1 # e0 : entire operation within one word
+ mskql t0, a0, t2 # e0 :
+ mskqh t0, a2, t3 # e0 :
+ or t1, t2, t0 # .. e1 :
+ or t0, t3, t0 # e1 :
+ stq_u t0, 0(a0) # e0 (stall)
+
+$done: ret
+
+ END(memset)
+libc_hidden_builtin_def (memset)
diff --git a/libc/sysdeps/alpha/memusage.h b/libc/sysdeps/alpha/memusage.h
new file mode 100644
index 000000000..3d8416033
--- /dev/null
+++ b/libc/sysdeps/alpha/memusage.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("$30"); stack_ptr; })
+
+#include <sysdeps/generic/memusage.h>
diff --git a/libc/sysdeps/alpha/mul_1.s b/libc/sysdeps/alpha/mul_1.s
new file mode 100644
index 000000000..165c281ac
--- /dev/null
+++ b/libc/sysdeps/alpha/mul_1.s
@@ -0,0 +1,85 @@
+ # Alpha 21064 __mpn_mul_1 -- Multiply a limb vector with a limb and store
+ # the result in a second limb vector.
+
+ # Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+ # This file is part of the GNU MP Library.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published by
+ # the Free Software Foundation; either version 2.1 of the License, or (at your
+ # option) any later version.
+
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+
+ # INPUT PARAMETERS
+ # res_ptr r16
+ # s1_ptr r17
+ # size r18
+ # s2_limb r19
+
+ # This code runs at 42 cycles/limb on the EV4 and 18 cycles/limb on the EV5.
+
+ # To improve performance for long multiplications, we would use
+ # 'fetch' for S1 and 'fetch_m' for RES. It's not obvious how to use
+ # these instructions without slowing down the general code: 1. We can
+ # only have two prefetches in operation at any time in the Alpha
+ # architecture. 2. There will seldom be any special alignment
+ # between RES_PTR and S1_PTR. Maybe we can simply divide the current
+ # loop into an inner and outer loop, having the inner loop handle
+ # exactly one prefetch block?
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __mpn_mul_1
+ .ent __mpn_mul_1 2
+__mpn_mul_1:
+ .frame $30,0,$26
+
+ ldq $2,0($17) # $2 = s1_limb
+ subq $18,1,$18 # size--
+ mulq $2,$19,$3 # $3 = prod_low
+ bic $31,$31,$4 # clear cy_limb
+ umulh $2,$19,$0 # $0 = prod_high
+ beq $18,Lend1 # jump if size was == 1
+ ldq $2,8($17) # $2 = s1_limb
+ subq $18,1,$18 # size--
+ stq $3,0($16)
+ beq $18,Lend2 # jump if size was == 2
+
+ .align 3
+Loop: mulq $2,$19,$3 # $3 = prod_low
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ subq $18,1,$18 # size--
+ umulh $2,$19,$4 # $4 = cy_limb
+ ldq $2,16($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ stq $3,8($16)
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ addq $16,8,$16 # res_ptr++
+ bne $18,Loop
+
+Lend2: mulq $2,$19,$3 # $3 = prod_low
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ umulh $2,$19,$4 # $4 = cy_limb
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ stq $3,8($16)
+ addq $4,$0,$0 # cy_limb = prod_high + cy
+ ret $31,($26),1
+Lend1: stq $3,0($16)
+ ret $31,($26),1
+
+ .end __mpn_mul_1
diff --git a/libc/sysdeps/alpha/nscd-types.h b/libc/sysdeps/alpha/nscd-types.h
new file mode 100644
index 000000000..957edaf29
--- /dev/null
+++ b/libc/sysdeps/alpha/nscd-types.h
@@ -0,0 +1,22 @@
+/* Types for the NSCD implementation. Alpha version.
+ Copyright (c) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+
+typedef int64_t nscd_ssize_t;
diff --git a/libc/sysdeps/alpha/rawmemchr.S b/libc/sysdeps/alpha/rawmemchr.S
new file mode 100644
index 000000000..d3a69fa63
--- /dev/null
+++ b/libc/sysdeps/alpha/rawmemchr.S
@@ -0,0 +1,90 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return pointer to first occurrence of CH in STR. */
+
+#include <sysdep.h>
+
+ .set noreorder
+ .set noat
+
+ENTRY(__rawmemchr)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ zapnot a1, 1, a1 # e0 : zero extend the search character
+ ldq_u t0, 0(a0) # .. e1 : load first quadword
+ sll a1, 8, t5 # e0 : replicate the search character
+ andnot a0, 7, v0 # .. e1 : align our loop pointer
+
+ or t5, a1, a1 # e0 :
+ lda t4, -1 # .. e1 : build garbage mask
+ sll a1, 16, t5 # e0 :
+ unop # :
+
+ mskqh t4, a0, t4 # e0 :
+ or t5, a1, a1 # .. e1 :
+ sll a1, 32, t5 # e0 :
+ cmpbge zero, t4, t4 # .. e1 : bits set iff byte is garbage
+
+ or t5, a1, a1 # e0 :
+ xor t0, a1, t1 # .. e1 : make bytes == c zero
+ cmpbge zero, t1, t3 # e0 : bits set iff byte == c
+ unop # :
+
+ andnot t3, t4, t0 # e0 : clear garbage bits
+ fnop # .. fa :
+ unop # :
+ bne t0, $found # .. e1 (zdb)
+
+ .align 4
+$loop:
+ ldq t0, 8(v0) # e0 :
+ addq v0, 8, v0 # .. e1 :
+ nop # e0 :
+ xor t0, a1, t1 # .. e1 (ev5 data stall)
+
+ cmpbge zero, t1, t0 # e0 : bits set iff byte == c
+ beq t0, $loop # .. e1 (zdb)
+
+$found:
+ negq t0, t1 # e0 : clear all but least set bit
+ and t0, t1, t0 # e1 (stall)
+ and t0, 0xf0, t2 # e0 : binary search for that set bit
+ and t0, 0xcc, t3 # .. e1 :
+
+ and t0, 0xaa, t4 # e0 :
+ cmovne t2, 4, t2 # .. e1 :
+ cmovne t3, 2, t3 # e0 :
+ cmovne t4, 1, t4 # .. e1 :
+
+ addq t2, t3, t2 # e0 :
+ addq v0, t4, v0 # .. e1 :
+ addq v0, t2, v0 # e0 :
+ ret # .. e1 :
+
+ END(__rawmemchr)
+
+libc_hidden_def (__rawmemchr)
+weak_alias (__rawmemchr, rawmemchr)
diff --git a/libc/sysdeps/alpha/reml.S b/libc/sysdeps/alpha/reml.S
new file mode 100644
index 000000000..ae291b050
--- /dev/null
+++ b/libc/sysdeps/alpha/reml.S
@@ -0,0 +1,87 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@twiddle.net>
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "div_libc.h"
+
+/* 32-bit signed int remainder. This is not a normal C function. Argument
+ registers are t10 and t11, the result goes in t12. Only t12 and AT may
+ be clobbered.
+
+ The FPU can handle the division for all input values except zero.
+ All we have to do is compute the remainder via multiply-and-subtract.
+
+ The FPCR save/restore is due to the fact that the EV6 _will_ set FPCR_INE
+ for cvttq/c even without /sui being set. It will not, however, properly
+ raise the exception, so we don't have to worry about FPCR_INED being clear
+ and so dying by SIGFPE. */
+
+#ifndef EXTEND
+#define EXTEND(S,D) sextl S, D
+#endif
+
+ .text
+ .align 4
+ .globl __reml
+ .type __reml, @funcnoplt
+ .usepv __reml, no
+
+ cfi_startproc
+ cfi_return_column (RA)
+__reml:
+ lda sp, -FRAME(sp)
+ cfi_def_cfa_offset (FRAME)
+ CALL_MCOUNT
+ stt $f0, 0(sp)
+ excb
+ beq Y, DIVBYZERO
+
+ stt $f1, 8(sp)
+ stt $f2, 16(sp)
+ cfi_rel_offset ($f0, 0)
+ cfi_rel_offset ($f1, 8)
+ cfi_rel_offset ($f2, 16)
+ mf_fpcr $f2
+
+ EXTEND (X, RV)
+ EXTEND (Y, AT)
+ _ITOFT2 RV, $f0, 24, AT, $f1, 32
+ cvtqt $f0, $f0
+ cvtqt $f1, $f1
+ divt/c $f0, $f1, $f0
+ cvttq/c $f0, $f0
+ excb
+ mt_fpcr $f2
+ _FTOIT $f0, RV, 24
+
+ ldt $f0, 0(sp)
+ mull RV, Y, RV
+ ldt $f1, 8(sp)
+ ldt $f2, 16(sp)
+ lda sp, FRAME(sp)
+ cfi_restore ($f0)
+ cfi_restore ($f1)
+ cfi_restore ($f2)
+ cfi_def_cfa_offset (0)
+ subl X, RV, RV
+ ret $31, (RA), 1
+
+ cfi_endproc
+ .size __reml, .-__reml
+
+ DO_DIVBYZERO
diff --git a/libc/sysdeps/alpha/remlu.S b/libc/sysdeps/alpha/remlu.S
new file mode 100644
index 000000000..f8691e19a
--- /dev/null
+++ b/libc/sysdeps/alpha/remlu.S
@@ -0,0 +1,4 @@
+#define UNSIGNED
+#define EXTEND(S,D) zapnot S, 15, D
+#define __reml __remlu
+#include <reml.S>
diff --git a/libc/sysdeps/alpha/remq.S b/libc/sysdeps/alpha/remq.S
new file mode 100644
index 000000000..64e958bb9
--- /dev/null
+++ b/libc/sysdeps/alpha/remq.S
@@ -0,0 +1,269 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "div_libc.h"
+
+
+/* 64-bit signed long remainder. These are not normal C functions. Argument
+ registers are t10 and t11, the result goes in t12. Only t12 and AT may
+ be clobbered.
+
+ Theory of operation here is that we can use the FPU divider for virtually
+ all operands that we see: all dividend values between -2**53 and 2**53-1
+ can be computed directly. Note that divisor values need not be checked
+ against that range because the rounded fp value will be close enough such
+ that the quotient is < 1, which will properly be truncated to zero when we
+ convert back to integer.
+
+ When the dividend is outside the range for which we can compute exact
+ results, we use the fp quotent as an estimate from which we begin refining
+ an exact integral value. This reduces the number of iterations in the
+ shift-and-subtract loop significantly.
+
+ The FPCR save/restore is due to the fact that the EV6 _will_ set FPCR_INE
+ for cvttq/c even without /sui being set. It will not, however, properly
+ raise the exception, so we don't have to worry about FPCR_INED being clear
+ and so dying by SIGFPE. */
+
+ .text
+ .align 4
+ .globl __remq
+ .type __remq, @funcnoplt
+ .usepv __remq, no
+
+ cfi_startproc
+ cfi_return_column (RA)
+__remq:
+ lda sp, -FRAME(sp)
+ cfi_def_cfa_offset (FRAME)
+ CALL_MCOUNT
+
+ /* Get the fp divide insn issued as quickly as possible. After
+ that's done, we have at least 22 cycles until its results are
+ ready -- all the time in the world to figure out how we're
+ going to use the results. */
+ stt $f0, 0(sp)
+ excb
+ beq Y, DIVBYZERO
+
+ stt $f1, 8(sp)
+ stt $f3, 48(sp)
+ cfi_rel_offset ($f0, 0)
+ cfi_rel_offset ($f1, 8)
+ cfi_rel_offset ($f3, 48)
+ mf_fpcr $f3
+
+ _ITOFT2 X, $f0, 16, Y, $f1, 24
+ cvtqt $f0, $f0
+ cvtqt $f1, $f1
+ divt/c $f0, $f1, $f0
+
+ /* Check to see if X fit in the double as an exact value. */
+ sll X, (64-53), AT
+ ldt $f1, 8(sp)
+ sra AT, (64-53), AT
+ cmpeq X, AT, AT
+ beq AT, $x_big
+
+ /* If we get here, we're expecting exact results from the division.
+ Do nothing else besides convert, compute remainder, clean up. */
+ cvttq/c $f0, $f0
+ excb
+ mt_fpcr $f3
+ _FTOIT $f0, AT, 16
+ mulq AT, Y, AT
+ ldt $f0, 0(sp)
+ ldt $f3, 48(sp)
+ cfi_restore ($f1)
+ cfi_remember_state
+ cfi_restore ($f0)
+ cfi_restore ($f3)
+ cfi_def_cfa_offset (0)
+ lda sp, FRAME(sp)
+ subq X, AT, RV
+ ret $31, (RA), 1
+
+ .align 4
+ cfi_restore_state
+$x_big:
+ /* If we get here, X is large enough that we don't expect exact
+ results, and neither X nor Y got mis-translated for the fp
+ division. Our task is to take the fp result, figure out how
+ far it's off from the correct result and compute a fixup. */
+ stq t0, 16(sp)
+ stq t1, 24(sp)
+ stq t2, 32(sp)
+ stq t5, 40(sp)
+ cfi_rel_offset (t0, 16)
+ cfi_rel_offset (t1, 24)
+ cfi_rel_offset (t2, 32)
+ cfi_rel_offset (t5, 40)
+
+#define Q t0 /* quotient */
+#define R RV /* remainder */
+#define SY t1 /* scaled Y */
+#define S t2 /* scalar */
+#define QY t3 /* Q*Y */
+
+ /* The fixup code below can only handle unsigned values. */
+ or X, Y, AT
+ mov $31, t5
+ blt AT, $fix_sign_in
+$fix_sign_in_ret1:
+ cvttq/c $f0, $f0
+
+ _FTOIT $f0, Q, 8
+ .align 3
+$fix_sign_in_ret2:
+ ldt $f0, 0(sp)
+ stq t3, 0(sp)
+ cfi_restore ($f0)
+ cfi_rel_offset (t3, 0)
+
+ mulq Q, Y, QY
+ excb
+ stq t4, 8(sp)
+ mt_fpcr $f3
+ cfi_rel_offset (t4, 8)
+
+ subq QY, X, R
+ mov Y, SY
+ mov 1, S
+ bgt R, $q_high
+
+$q_high_ret:
+ subq X, QY, R
+ mov Y, SY
+ mov 1, S
+ bgt R, $q_low
+
+$q_low_ret:
+ ldq t0, 16(sp)
+ ldq t1, 24(sp)
+ ldq t2, 32(sp)
+ bne t5, $fix_sign_out
+
+$fix_sign_out_ret:
+ ldq t3, 0(sp)
+ ldq t4, 8(sp)
+ ldq t5, 40(sp)
+ ldt $f3, 48(sp)
+ lda sp, FRAME(sp)
+ cfi_remember_state
+ cfi_restore (t0)
+ cfi_restore (t1)
+ cfi_restore (t2)
+ cfi_restore (t3)
+ cfi_restore (t4)
+ cfi_restore (t5)
+ cfi_restore ($f3)
+ cfi_def_cfa_offset (0)
+ ret $31, (RA), 1
+
+ .align 4
+ cfi_restore_state
+ /* The quotient that we computed was too large. We need to reduce
+ it by S such that Y*S >= R. Obviously the closer we get to the
+ correct value the better, but overshooting high is ok, as we'll
+ fix that up later. */
+0:
+ addq SY, SY, SY
+ addq S, S, S
+$q_high:
+ cmpult SY, R, AT
+ bne AT, 0b
+
+ subq Q, S, Q
+ unop
+ subq QY, SY, QY
+ br $q_high_ret
+
+ .align 4
+ /* The quotient that we computed was too small. Divide Y by the
+ current remainder (R) and add that to the existing quotient (Q).
+ The expectation, of course, is that R is much smaller than X. */
+ /* Begin with a shift-up loop. Compute S such that Y*S >= R. We
+ already have a copy of Y in SY and the value 1 in S. */
+0:
+ addq SY, SY, SY
+ addq S, S, S
+$q_low:
+ cmpult SY, R, AT
+ bne AT, 0b
+
+ /* Shift-down and subtract loop. Each iteration compares our scaled
+ Y (SY) with the remainder (R); if SY <= R then X is divisible by
+ Y's scalar (S) so add it to the quotient (Q). */
+2: addq Q, S, t3
+ srl S, 1, S
+ cmpule SY, R, AT
+ subq R, SY, t4
+
+ cmovne AT, t3, Q
+ cmovne AT, t4, R
+ srl SY, 1, SY
+ bne S, 2b
+
+ br $q_low_ret
+
+ .align 4
+$fix_sign_in:
+ /* If we got here, then X|Y is negative. Need to adjust everything
+ such that we're doing unsigned division in the fixup loop. */
+ /* T5 records the changes we had to make:
+ bit 0: set if X was negated. Note that the sign of the
+ remainder follows the sign of the divisor.
+ bit 2: set if Y was negated.
+ */
+ xor X, Y, t1
+ cmplt X, 0, t5
+ negq X, t0
+ cmovne t5, t0, X
+
+ cmplt Y, 0, AT
+ negq Y, t0
+ s4addq AT, t5, t5
+ cmovne AT, t0, Y
+
+ bge t1, $fix_sign_in_ret1
+ cvttq/c $f0, $f0
+ _FTOIT $f0, Q, 8
+ .align 3
+ negq Q, Q
+ br $fix_sign_in_ret2
+
+ .align 4
+$fix_sign_out:
+ /* Now we get to undo what we did above. */
+ /* ??? Is this really faster than just increasing the size of
+ the stack frame and storing X and Y in memory? */
+ and t5, 4, AT
+ negq Y, t4
+ cmovne AT, t4, Y
+
+ negq X, t4
+ cmovlbs t5, t4, X
+ negq RV, t4
+ cmovlbs t5, t4, RV
+
+ br $fix_sign_out_ret
+
+ cfi_endproc
+ .size __remq, .-__remq
+
+ DO_DIVBYZERO
diff --git a/libc/sysdeps/alpha/remqu.S b/libc/sysdeps/alpha/remqu.S
new file mode 100644
index 000000000..398a345a1
--- /dev/null
+++ b/libc/sysdeps/alpha/remqu.S
@@ -0,0 +1,272 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "div_libc.h"
+
+
+/* 64-bit unsigned long remainder. These are not normal C functions. Argument
+ registers are t10 and t11, the result goes in t12. Only t12 and AT may be
+ clobbered.
+
+ Theory of operation here is that we can use the FPU divider for virtually
+ all operands that we see: all dividend values between -2**53 and 2**53-1
+ can be computed directly. Note that divisor values need not be checked
+ against that range because the rounded fp value will be close enough such
+ that the quotient is < 1, which will properly be truncated to zero when we
+ convert back to integer.
+
+ When the dividend is outside the range for which we can compute exact
+ results, we use the fp quotent as an estimate from which we begin refining
+ an exact integral value. This reduces the number of iterations in the
+ shift-and-subtract loop significantly.
+
+ The FPCR save/restore is due to the fact that the EV6 _will_ set FPCR_INE
+ for cvttq/c even without /sui being set. It will not, however, properly
+ raise the exception, so we don't have to worry about FPCR_INED being clear
+ and so dying by SIGFPE. */
+
+ .text
+ .align 4
+ .globl __remqu
+ .type __remqu, @funcnoplt
+ .usepv __remqu, no
+
+ cfi_startproc
+ cfi_return_column (RA)
+__remqu:
+ lda sp, -FRAME(sp)
+ cfi_def_cfa_offset (FRAME)
+ CALL_MCOUNT
+
+ /* Get the fp divide insn issued as quickly as possible. After
+ that's done, we have at least 22 cycles until its results are
+ ready -- all the time in the world to figure out how we're
+ going to use the results. */
+ subq Y, 1, AT
+ stt $f0, 0(sp)
+ and Y, AT, AT
+
+ stt $f1, 8(sp)
+ excb
+ stt $f3, 48(sp)
+ beq AT, $powerof2
+ cfi_rel_offset ($f0, 0)
+ cfi_rel_offset ($f1, 8)
+ cfi_rel_offset ($f3, 48)
+
+ _ITOFT2 X, $f0, 16, Y, $f1, 24
+ mf_fpcr $f3
+ cvtqt $f0, $f0
+ cvtqt $f1, $f1
+
+ blt X, $x_is_neg
+ divt/c $f0, $f1, $f0
+
+ /* Check to see if Y was mis-converted as signed value. */
+ ldt $f1, 8(sp)
+ blt Y, $y_is_neg
+
+ /* Check to see if X fit in the double as an exact value. */
+ srl X, 53, AT
+ bne AT, $x_big
+
+ /* If we get here, we're expecting exact results from the division.
+ Do nothing else besides convert, compute remainder, clean up. */
+ cvttq/c $f0, $f0
+ excb
+ mt_fpcr $f3
+ _FTOIT $f0, AT, 16
+
+ mulq AT, Y, AT
+ ldt $f0, 0(sp)
+ ldt $f3, 48(sp)
+ lda sp, FRAME(sp)
+ cfi_remember_state
+ cfi_restore ($f0)
+ cfi_restore ($f1)
+ cfi_restore ($f3)
+ cfi_def_cfa_offset (0)
+
+ .align 4
+ subq X, AT, RV
+ ret $31, (RA), 1
+
+ .align 4
+ cfi_restore_state
+$x_is_neg:
+ /* If we get here, X is so big that bit 63 is set, which made the
+ conversion come out negative. Fix it up lest we not even get
+ a good estimate. */
+ ldah AT, 0x5f80 /* 2**64 as float. */
+ stt $f2, 24(sp)
+ cfi_rel_offset ($f2, 24)
+ _ITOFS AT, $f2, 16
+
+ addt $f0, $f2, $f0
+ divt/c $f0, $f1, $f0
+
+ /* Ok, we've now the divide issued. Continue with other checks. */
+ .align 4
+ ldt $f1, 8(sp)
+ unop
+ ldt $f2, 24(sp)
+ blt Y, $y_is_neg
+ cfi_restore ($f1)
+ cfi_restore ($f2)
+ cfi_remember_state /* for y_is_neg */
+
+ .align 4
+$x_big:
+ /* If we get here, X is large enough that we don't expect exact
+ results, and neither X nor Y got mis-translated for the fp
+ division. Our task is to take the fp result, figure out how
+ far it's off from the correct result and compute a fixup. */
+ stq t0, 16(sp)
+ stq t1, 24(sp)
+ stq t2, 32(sp)
+ stq t3, 40(sp)
+ cfi_rel_offset (t0, 16)
+ cfi_rel_offset (t1, 24)
+ cfi_rel_offset (t2, 32)
+ cfi_rel_offset (t3, 40)
+
+#define Q t0 /* quotient */
+#define R RV /* remainder */
+#define SY t1 /* scaled Y */
+#define S t2 /* scalar */
+#define QY t3 /* Q*Y */
+
+ cvttq/c $f0, $f0
+ _FTOIT $f0, Q, 8
+ mulq Q, Y, QY
+
+ .align 4
+ stq t4, 8(sp)
+ excb
+ ldt $f0, 0(sp)
+ mt_fpcr $f3
+ cfi_rel_offset (t4, 8)
+ cfi_restore ($f0)
+
+ subq QY, X, R
+ mov Y, SY
+ mov 1, S
+ bgt R, $q_high
+
+$q_high_ret:
+ subq X, QY, R
+ mov Y, SY
+ mov 1, S
+ bgt R, $q_low
+
+$q_low_ret:
+ ldq t4, 8(sp)
+ ldq t0, 16(sp)
+ ldq t1, 24(sp)
+ ldq t2, 32(sp)
+
+ ldq t3, 40(sp)
+ ldt $f3, 48(sp)
+ lda sp, FRAME(sp)
+ cfi_remember_state
+ cfi_restore (t0)
+ cfi_restore (t1)
+ cfi_restore (t2)
+ cfi_restore (t3)
+ cfi_restore (t4)
+ cfi_restore ($f3)
+ cfi_def_cfa_offset (0)
+ ret $31, (RA), 1
+
+ .align 4
+ cfi_restore_state
+ /* The quotient that we computed was too large. We need to reduce
+ it by S such that Y*S >= R. Obviously the closer we get to the
+ correct value the better, but overshooting high is ok, as we'll
+ fix that up later. */
+0:
+ addq SY, SY, SY
+ addq S, S, S
+$q_high:
+ cmpult SY, R, AT
+ bne AT, 0b
+
+ subq Q, S, Q
+ unop
+ subq QY, SY, QY
+ br $q_high_ret
+
+ .align 4
+ /* The quotient that we computed was too small. Divide Y by the
+ current remainder (R) and add that to the existing quotient (Q).
+ The expectation, of course, is that R is much smaller than X. */
+ /* Begin with a shift-up loop. Compute S such that Y*S >= R. We
+ already have a copy of Y in SY and the value 1 in S. */
+0:
+ addq SY, SY, SY
+ addq S, S, S
+$q_low:
+ cmpult SY, R, AT
+ bne AT, 0b
+
+ /* Shift-down and subtract loop. Each iteration compares our scaled
+ Y (SY) with the remainder (R); if SY <= R then X is divisible by
+ Y's scalar (S) so add it to the quotient (Q). */
+2: addq Q, S, t3
+ srl S, 1, S
+ cmpule SY, R, AT
+ subq R, SY, t4
+
+ cmovne AT, t3, Q
+ cmovne AT, t4, R
+ srl SY, 1, SY
+ bne S, 2b
+
+ br $q_low_ret
+
+ .align 4
+ cfi_restore_state
+$y_is_neg:
+ /* If we get here, Y is so big that bit 63 is set. The results
+ from the divide will be completely wrong. Fortunately, the
+ quotient must be either 0 or 1, so the remainder must be X
+ or X-Y, so just compute it directly. */
+ cmpule Y, X, AT
+ subq X, Y, RV
+ ldt $f0, 0(sp)
+ cmoveq AT, X, RV
+
+ lda sp, FRAME(sp)
+ cfi_restore ($f0)
+ cfi_def_cfa_offset (0)
+ ret $31, (RA), 1
+
+ .align 4
+ cfi_def_cfa_offset (FRAME)
+$powerof2:
+ subq Y, 1, AT
+ beq Y, DIVBYZERO
+ and X, AT, RV
+ lda sp, FRAME(sp)
+ cfi_def_cfa_offset (0)
+ ret $31, (RA), 1
+
+ cfi_endproc
+ .size __remqu, .-__remqu
+
+ DO_DIVBYZERO
diff --git a/libc/sysdeps/alpha/rshift.s b/libc/sysdeps/alpha/rshift.s
new file mode 100644
index 000000000..7c230f193
--- /dev/null
+++ b/libc/sysdeps/alpha/rshift.s
@@ -0,0 +1,107 @@
+ # Alpha 21064 __mpn_rshift --
+
+ # Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+ # This file is part of the GNU MP Library.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published by
+ # the Free Software Foundation; either version 2.1 of the License, or (at your
+ # option) any later version.
+
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+
+ # INPUT PARAMETERS
+ # res_ptr r16
+ # s1_ptr r17
+ # size r18
+ # cnt r19
+
+ # This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling,
+ # it would take 4 cycles/limb. It should be possible to get down to 3
+ # cycles/limb since both ldq and stq can be paired with the other used
+ # instructions. But there are many restrictions in the 21064 pipeline that
+ # makes it hard, if not impossible, to get down to 3 cycles/limb:
+
+ # 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay.
+ # 2. Only aligned instruction pairs can be paired.
+ # 3. The store buffer or silo might not be able to deal with the bandwidth.
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __mpn_rshift
+ .ent __mpn_rshift
+__mpn_rshift:
+ .frame $30,0,$26,0
+
+ ldq $4,0($17) # load first limb
+ addq $17,8,$17
+ subq $31,$19,$7
+ subq $18,1,$18
+ and $18,4-1,$20 # number of limbs in first loop
+ sll $4,$7,$0 # compute function result
+
+ beq $20,.L0
+ subq $18,$20,$18
+
+ .align 3
+.Loop0:
+ ldq $3,0($17)
+ addq $16,8,$16
+ addq $17,8,$17
+ subq $20,1,$20
+ srl $4,$19,$5
+ sll $3,$7,$6
+ bis $3,$3,$4
+ bis $5,$6,$8
+ stq $8,-8($16)
+ bne $20,.Loop0
+
+.L0: beq $18,.Lend
+
+ .align 3
+.Loop: ldq $3,0($17)
+ addq $16,32,$16
+ subq $18,4,$18
+ srl $4,$19,$5
+ sll $3,$7,$6
+
+ ldq $4,8($17)
+ srl $3,$19,$1
+ bis $5,$6,$8
+ stq $8,-32($16)
+ sll $4,$7,$2
+
+ ldq $3,16($17)
+ srl $4,$19,$5
+ bis $1,$2,$8
+ stq $8,-24($16)
+ sll $3,$7,$6
+
+ ldq $4,24($17)
+ srl $3,$19,$1
+ bis $5,$6,$8
+ stq $8,-16($16)
+ sll $4,$7,$2
+
+ addq $17,32,$17
+ bis $1,$2,$8
+ stq $8,-8($16)
+
+ bgt $18,.Loop
+
+.Lend: srl $4,$19,$8
+ stq $8,0($16)
+ ret $31,($26),1
+ .end __mpn_rshift
diff --git a/libc/sysdeps/alpha/setjmp.S b/libc/sysdeps/alpha/setjmp.S
new file mode 100644
index 000000000..bc5da0f5b
--- /dev/null
+++ b/libc/sysdeps/alpha/setjmp.S
@@ -0,0 +1,120 @@
+/* Copyright (C) 1992,1994,1996,1997,2002,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __ASSEMBLY__
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+
+ .ent __sigsetjmp
+ .global __sigsetjmp
+__sigsetjmp:
+ ldgp gp, 0(pv)
+
+$sigsetjmp_local:
+#ifndef PIC
+#define FRAME 16
+ subq sp, FRAME, sp
+ .frame sp, FRAME, ra, 0
+ stq ra, 0(sp)
+ .mask 0x04000000, -FRAME
+#else
+#define FRAME 0
+ .frame sp, FRAME, ra, 0
+#endif
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ stq s0, JB_S0*8(a0)
+ stq s1, JB_S1*8(a0)
+ stq s2, JB_S2*8(a0)
+ stq s3, JB_S3*8(a0)
+ stq s4, JB_S4*8(a0)
+ stq s5, JB_S5*8(a0)
+#ifdef PTR_MANGLE
+ PTR_MANGLE(t1, ra, t0)
+ stq t1, JB_PC*8(a0)
+#else
+ stq ra, JB_PC*8(a0)
+#endif
+#if defined(PTR_MANGLE) && FRAME == 0
+ PTR_MANGLE2(t1, sp, t0)
+#else
+ addq sp, FRAME, t1
+# ifdef PTR_MANGLE
+ PTR_MANGLE2(t1, t1, t0)
+# endif
+#endif
+ stq t1, JB_SP*8(a0)
+#ifdef PTR_MANGLE
+ PTR_MANGLE2(t1, fp, t0)
+ stq t1, JB_FP*8(a0)
+#else
+ stq fp, JB_FP*8(a0)
+#endif
+ stt $f2, JB_F2*8(a0)
+ stt $f3, JB_F3*8(a0)
+ stt $f4, JB_F4*8(a0)
+ stt $f5, JB_F5*8(a0)
+ stt $f6, JB_F6*8(a0)
+ stt $f7, JB_F7*8(a0)
+ stt $f8, JB_F8*8(a0)
+ stt $f9, JB_F9*8(a0)
+
+#ifndef PIC
+ /* Call to C to (potentially) save our signal mask. */
+ jsr ra, __sigjmp_save
+ ldq ra, 0(sp)
+ addq sp, 16, sp
+ ret
+#elif defined NOT_IN_libc && defined IS_IN_rtld
+ /* In ld.so we never save the signal mask. */
+ mov 0, v0
+ ret
+#else
+ /* Tailcall to save the signal mask. */
+ br $31, __sigjmp_save !samegp
+#endif
+
+END(__sigsetjmp)
+
+/* Put these traditional entry points in the same file so that we can
+ elide much of the nonsense in trying to jmp to the real function. */
+
+ENTRY(_setjmp)
+ ldgp gp, 0(pv)
+ .prologue 1
+ mov 0, a1
+ br $sigsetjmp_local
+END(_setjmp)
+libc_hidden_def (_setjmp)
+
+ENTRY(setjmp)
+ ldgp gp, 0(pv)
+ .prologue 1
+ mov 1, a1
+ br $sigsetjmp_local
+END(setjmp)
+
+weak_extern(_setjmp)
+weak_extern(setjmp)
diff --git a/libc/sysdeps/alpha/soft-fp/Makefile b/libc/sysdeps/alpha/soft-fp/Makefile
new file mode 100644
index 000000000..5410a7898
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/Makefile
@@ -0,0 +1,10 @@
+# Software floating-point emulation.
+
+ifeq ($(subdir),soft-fp)
+sysdep_routines += ots_add ots_sub ots_mul ots_div ots_cmp ots_cmpe \
+ ots_cvtxq ots_cvtqx ots_cvtqux ots_cvttx ots_cvtxt ots_nintxq
+endif
+
+ifeq ($(subdir),math)
+CPPFLAGS += -I../soft-fp
+endif
diff --git a/libc/sysdeps/alpha/soft-fp/Versions b/libc/sysdeps/alpha/soft-fp/Versions
new file mode 100644
index 000000000..390128711
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/Versions
@@ -0,0 +1,8 @@
+libc {
+ GLIBC_2.3.4 {
+ _OtsAddX; _OtsSubX; _OtsMulX; _OtsDivX;
+ _OtsEqlX; _OtsNeqX; _OtsLssX; _OtsLeqX; _OtsGtrX; _OtsGeqX;
+ _OtsCvtQX; _OtsCvtQUX; _OtsCvtXQ; _OtsNintXQ;
+ _OtsConvertFloatTX; _OtsConvertFloatXT;
+ }
+}
diff --git a/libc/sysdeps/alpha/soft-fp/e_sqrtl.c b/libc/sysdeps/alpha/soft-fp/e_sqrtl.c
new file mode 100644
index 000000000..717d17012
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/e_sqrtl.c
@@ -0,0 +1,40 @@
+/* long double square root in software floating-point emulation.
+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+#include <soft-fp.h>
+#include <quad.h>
+
+long double
+__ieee754_sqrtl (const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(C);
+ long double c;
+ long _round = 4; /* dynamic rounding */
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_Q(A, a);
+ FP_SQRT_Q(C, A);
+ FP_PACK_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/alpha/soft-fp/local-soft-fp.h b/libc/sysdeps/alpha/soft-fp/local-soft-fp.h
new file mode 100644
index 000000000..e93a2ad06
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/local-soft-fp.h
@@ -0,0 +1,44 @@
+#include <stdlib.h>
+#include <soft-fp.h>
+#include <quad.h>
+
+/* Helpers for the Ots functions which receive long double arguments
+ in two integer registers, and return values in $16+$17. */
+
+#undef _FP_UNPACK_RAW_2
+#define _FP_UNPACK_RAW_2(fs, X, val) \
+ do { \
+ union _FP_UNION_##fs _flo; \
+ _flo.longs.a = val##l; \
+ _flo.longs.b = val##h; \
+ X##_f0 = _flo.bits.frac0; \
+ X##_f1 = _flo.bits.frac1; \
+ X##_e = _flo.bits.exp; \
+ X##_s = _flo.bits.sign; \
+ } while (0)
+
+#undef _FP_PACK_RAW_2
+#define _FP_PACK_RAW_2(fs, val, X) \
+ do { \
+ union _FP_UNION_##fs _flo; \
+ _flo.bits.frac0 = X##_f0; \
+ _flo.bits.frac1 = X##_f1; \
+ _flo.bits.exp = X##_e; \
+ _flo.bits.sign = X##_s; \
+ val##l = _flo.longs.a; \
+ val##h = _flo.longs.b; \
+ } while (0)
+
+#define FP_DECL_RETURN(X) \
+ long X##l, X##h
+
+/* ??? We don't have a real way to tell the compiler that we're wanting
+ to return values in $16+$17. Instead use a volatile asm to make sure
+ that the values are live, and just hope that nothing kills the values
+ in between here and the end of the function. */
+#define FP_RETURN(X) \
+do { \
+ register long r16 __asm__("16") = X##l; \
+ register long r17 __asm__("17") = X##h; \
+ asm volatile ("" : : "r"(r16), "r"(r17)); \
+} while (0)
diff --git a/libc/sysdeps/alpha/soft-fp/ots_add.c b/libc/sysdeps/alpha/soft-fp/ots_add.c
new file mode 100644
index 000000000..acf66f316
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/ots_add.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation: addition.
+ Copyright (C) 1997,1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "local-soft-fp.h"
+
+void
+_OtsAddX(long al, long ah, long bl, long bh, long _round)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ FP_DECL_RETURN(c);
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+ FP_UNPACK_SEMIRAW_Q(B, b);
+ FP_ADD_Q(C, A, B);
+ FP_PACK_SEMIRAW_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+
+ FP_RETURN(c);
+}
diff --git a/libc/sysdeps/alpha/soft-fp/ots_cmp.c b/libc/sysdeps/alpha/soft-fp/ots_cmp.c
new file mode 100644
index 000000000..c356b4848
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/ots_cmp.c
@@ -0,0 +1,64 @@
+/* Software floating-point emulation: comparison.
+ Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "local-soft-fp.h"
+
+static long
+internal_equality (long al, long ah, long bl, long bh, long neq)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ long r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+
+ if ((A_e == _FP_EXPMAX_Q && !_FP_FRAC_ZEROP_2(A))
+ || (B_e == _FP_EXPMAX_Q && !_FP_FRAC_ZEROP_2(B)))
+ {
+ /* EQ and NE signal invalid operation only if either operand is SNaN. */
+ if (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))
+ {
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+ }
+ return -1;
+ }
+
+ r = (A_e == B_e
+ && _FP_FRAC_EQ_2 (A, B)
+ && (A_s == B_s || (!A_e && _FP_FRAC_ZEROP_2(A))));
+ r ^= neq;
+
+ return r;
+}
+
+long
+_OtsEqlX (long al, long ah, long bl, long bh)
+{
+ return internal_equality (al, ah, bl, bh, 0);
+}
+
+long
+_OtsNeqX (long al, long ah, long bl, long bh)
+{
+ return internal_equality (al, ah, bl, bh, 1);
+}
diff --git a/libc/sysdeps/alpha/soft-fp/ots_cmpe.c b/libc/sysdeps/alpha/soft-fp/ots_cmpe.c
new file mode 100644
index 000000000..001eb75a9
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/ots_cmpe.c
@@ -0,0 +1,83 @@
+/* Software floating-point emulation: comparison.
+ Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "local-soft-fp.h"
+
+static long
+internal_compare (long al, long ah, long bl, long bh)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ long r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q (r, A, B, 2);
+
+ /* Relative comparisons signal invalid operation if either operand is NaN. */
+ if (r == 2)
+ {
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+ }
+
+ return r;
+}
+
+long
+_OtsLssX (long al, long ah, long bl, long bh)
+{
+ long r = internal_compare (al, ah, bl, bh);
+ if (r == 2)
+ return -1;
+ else
+ return r < 0;
+}
+
+long
+_OtsLeqX (long al, long ah, long bl, long bh)
+{
+ long r = internal_compare (al, ah, bl, bh);
+ if (r == 2)
+ return -1;
+ else
+ return r <= 0;
+}
+
+long
+_OtsGtrX (long al, long ah, long bl, long bh)
+{
+ long r = internal_compare (al, ah, bl, bh);
+ if (r == 2)
+ return -1;
+ else
+ return r > 0;
+}
+
+long
+_OtsGeqX (long al, long ah, long bl, long bh)
+{
+ long r = internal_compare (al, ah, bl, bh);
+ if (r == 2)
+ return -1;
+ else
+ return r >= 0;
+}
diff --git a/libc/sysdeps/alpha/soft-fp/ots_cvtqux.c b/libc/sysdeps/alpha/soft-fp/ots_cvtqux.c
new file mode 100644
index 000000000..82c50806c
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/ots_cvtqux.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation: unsigned integer to float conversion.
+ Copyright (C) 1997,1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "local-soft-fp.h"
+
+/* Should never actually be used, since we've more bits of precision
+ than the incomming long, but needed for linkage. */
+#undef FP_ROUNDMODE
+#define FP_ROUNDMODE FP_RND_ZERO
+
+void
+_OtsCvtQUX (unsigned long a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ FP_DECL_RETURN(c);
+
+ FP_FROM_INT_Q(C, a, 64, unsigned long);
+ FP_PACK_RAW_Q(c, C);
+
+ FP_RETURN(c);
+}
diff --git a/libc/sysdeps/alpha/soft-fp/ots_cvtqx.c b/libc/sysdeps/alpha/soft-fp/ots_cvtqx.c
new file mode 100644
index 000000000..dc8029150
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/ots_cvtqx.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation: signed integer to float conversion.
+ Copyright (C) 1997,1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "local-soft-fp.h"
+
+/* Should never actually be used, since we've more bits of precision
+ than the incomming long, but needed for linkage. */
+#undef FP_ROUNDMODE
+#define FP_ROUNDMODE FP_RND_ZERO
+
+void
+_OtsCvtQX (long a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ FP_DECL_RETURN(c);
+
+ FP_FROM_INT_Q(C, a, 64, unsigned long);
+ FP_PACK_RAW_Q(c, C);
+ FP_RETURN(c);
+}
diff --git a/libc/sysdeps/alpha/soft-fp/ots_cvttx.c b/libc/sysdeps/alpha/soft-fp/ots_cvttx.c
new file mode 100644
index 000000000..2d0bc9bca
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/ots_cvttx.c
@@ -0,0 +1,48 @@
+/* Software floating-point emulation: floating point extension.
+ Copyright (C) 1997,1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "local-soft-fp.h"
+#include "double.h"
+
+/* Should never actually be used, since we're extending, but needed
+ for linkage. */
+#undef FP_ROUNDMODE
+#define FP_ROUNDMODE FP_RND_ZERO
+
+void
+_OtsConvertFloatTX(double a)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ FP_DECL_Q(C);
+ FP_DECL_RETURN(c);
+
+ FP_UNPACK_RAW_D(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_EXTEND(Q,D,4,2,C,A);
+#else
+ FP_EXTEND(Q,D,2,1,C,A);
+#endif
+ FP_PACK_RAW_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+
+ FP_RETURN(c);
+}
diff --git a/libc/sysdeps/alpha/soft-fp/ots_cvtxq.c b/libc/sysdeps/alpha/soft-fp/ots_cvtxq.c
new file mode 100644
index 000000000..2c9df529d
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/ots_cvtxq.c
@@ -0,0 +1,44 @@
+/* Software floating-point emulation: float to integer conversion.
+ Copyright (C) 1997,1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "local-soft-fp.h"
+
+long
+_OtsCvtXQ (long al, long ah, long _round)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned long r;
+ long s;
+
+ /* If bit 3 is set, then integer overflow detection is requested. */
+ s = _round & 8 ? 1 : -1;
+ _round = _round & 3;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, 64, s);
+
+ if (s > 0 && (_fex &= FP_EX_INVALID))
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/alpha/soft-fp/ots_cvtxt.c b/libc/sysdeps/alpha/soft-fp/ots_cvtxt.c
new file mode 100644
index 000000000..6221a2365
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/ots_cvtxt.c
@@ -0,0 +1,44 @@
+/* Software floating-point emulation: floating point truncation.
+ Copyright (C) 1997,1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "local-soft-fp.h"
+#include "double.h"
+
+double
+_OtsConvertFloatXT (long al, long ah, long _round)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ FP_DECL_D(R);
+ double r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_TRUNC(D,Q,2,4,R,A);
+#else
+ FP_TRUNC(D,Q,1,2,R,A);
+#endif
+ FP_PACK_SEMIRAW_D(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/alpha/soft-fp/ots_div.c b/libc/sysdeps/alpha/soft-fp/ots_div.c
new file mode 100644
index 000000000..eb0748928
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/ots_div.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation: division.
+ Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "local-soft-fp.h"
+
+void
+_OtsDivX(long al, long ah, long bl, long bh, long _round)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ FP_DECL_RETURN(c);
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_Q(A, a);
+ FP_UNPACK_Q(B, b);
+ FP_DIV_Q(C, A, B);
+ FP_PACK_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+
+ FP_RETURN(c);
+}
diff --git a/libc/sysdeps/alpha/soft-fp/ots_mul.c b/libc/sysdeps/alpha/soft-fp/ots_mul.c
new file mode 100644
index 000000000..f88ee33fb
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/ots_mul.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation: multiplication.
+ Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "local-soft-fp.h"
+
+void
+_OtsMulX(long al, long ah, long bl, long bh, long _round)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ FP_DECL_RETURN(c);
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_Q(A, a);
+ FP_UNPACK_Q(B, b);
+ FP_MUL_Q(C, A, B);
+ FP_PACK_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+
+ FP_RETURN(c);
+}
diff --git a/libc/sysdeps/alpha/soft-fp/ots_nintxq.c b/libc/sysdeps/alpha/soft-fp/ots_nintxq.c
new file mode 100644
index 000000000..a718372af
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/ots_nintxq.c
@@ -0,0 +1,52 @@
+/* Software floating-point emulation: convert to fortran nearest.
+ Copyright (C) 1997,1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "local-soft-fp.h"
+
+long
+_OtsNintXQ (long al, long ah, long _round)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ unsigned long r;
+ long s;
+
+ /* If bit 3 is set, then integer overflow detection is requested. */
+ s = _round & 8 ? 1 : -1;
+ _round = _round & 3;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+
+ /* Build 0.5 * sign(A) */
+ B_e = _FP_EXPBIAS_Q;
+ __FP_FRAC_SET_2 (B, 0, 0);
+ B_s = A_s;
+
+ FP_ADD_Q(C, A, B);
+ _FP_FRAC_SRL_2(C, _FP_WORKBITS);
+ _FP_FRAC_HIGH_RAW_Q(C) &= ~(_FP_W_TYPE)_FP_IMPLBIT_Q;
+ FP_TO_INT_Q(r, C, 64, s);
+ if (s > 0 && (_fex &= FP_EX_INVALID))
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/alpha/soft-fp/ots_sub.c b/libc/sysdeps/alpha/soft-fp/ots_sub.c
new file mode 100644
index 000000000..5147266a0
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/ots_sub.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation: subtraction.
+ Copyright (C) 1997,1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "local-soft-fp.h"
+
+void
+_OtsSubX(long al, long ah, long bl, long bh, long _round)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ FP_DECL_RETURN(c);
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+ FP_UNPACK_SEMIRAW_Q(B, b);
+ FP_SUB_Q(C, A, B);
+ FP_PACK_SEMIRAW_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+
+ FP_RETURN(c);
+}
diff --git a/libc/sysdeps/alpha/soft-fp/sfp-machine.h b/libc/sysdeps/alpha/soft-fp/sfp-machine.h
new file mode 100644
index 000000000..2bad4e9dc
--- /dev/null
+++ b/libc/sysdeps/alpha/soft-fp/sfp-machine.h
@@ -0,0 +1,94 @@
+/* Machine-dependent software floating-point definitions.
+ Alpha userland IEEE 128-bit version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz) and
+ David S. Miller (davem@redhat.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+#define _FP_W_TYPE_SIZE 64
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+#define _FP_MUL_MEAT_S(R,X,Y) \
+ _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y) \
+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y) \
+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1)
+#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1
+#define _FP_NANSIGN_S 0
+#define _FP_NANSIGN_D 0
+#define _FP_NANSIGN_Q 0
+
+#define _FP_KEEPNANFRACP 1
+
+/* Alpha Architecture Handbook, 4.7.10.4 sez that we should prefer any
+ type of NaN in Fb, then Fa. */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+/* Rounding mode settings. */
+#define FP_RND_NEAREST FE_TONEAREST
+#define FP_RND_ZERO FE_TOWARDZERO
+#define FP_RND_PINF FE_UPWARD
+#define FP_RND_MINF FE_DOWNWARD
+
+/* Obtain the current rounding mode. It's given as an argument to
+ all the Ots functions, with 4 meaning "dynamic". */
+#define FP_ROUNDMODE _round
+
+/* Exception flags. */
+#define FP_EX_INVALID FE_INVALID
+#define FP_EX_OVERFLOW FE_OVERFLOW
+#define FP_EX_UNDERFLOW FE_UNDERFLOW
+#define FP_EX_DIVZERO FE_DIVBYZERO
+#define FP_EX_INEXACT FE_INEXACT
+
+#define FP_INIT_ROUNDMODE \
+do { \
+ if (__builtin_expect (_round == 4, 0)) \
+ { \
+ unsigned long t; \
+ __asm__ __volatile__("excb; mf_fpcr %0" : "=f"(t)); \
+ _round = (t >> FPCR_ROUND_SHIFT) & 3; \
+ } \
+} while (0)
+
+#define FP_HANDLE_EXCEPTIONS \
+do { \
+ if (__builtin_expect (_fex, 0)) \
+ { \
+ unsigned long t = __ieee_get_fp_control (); \
+ __ieee_set_fp_control (t | _fex); \
+ } \
+} while (0)
diff --git a/libc/sysdeps/alpha/stackinfo.h b/libc/sysdeps/alpha/stackinfo.h
new file mode 100644
index 000000000..0a281bd43
--- /dev/null
+++ b/libc/sysdeps/alpha/stackinfo.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file contains a bit of information about the stack allocation
+ of the processor. */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H 1
+
+/* On Alpha the stack grows down. */
+#define _STACK_GROWS_DOWN 1
+
+#endif /* stackinfo.h */
diff --git a/libc/sysdeps/alpha/stpcpy.S b/libc/sysdeps/alpha/stpcpy.S
new file mode 100644
index 000000000..b73e85f21
--- /dev/null
+++ b/libc/sysdeps/alpha/stpcpy.S
@@ -0,0 +1,56 @@
+/* Copyright (C) 1996, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copy a null-terminated string from SRC to DST. Return a pointer
+ to the null-terminator in the source. */
+
+#include <sysdep.h>
+
+ .text
+
+ENTRY(__stpcpy)
+ ldgp gp, 0(pv)
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ jsr t9, __stxcpy # do the work of the copy
+
+ and t8, 0xf0, t2 # binary search for byte offset of the
+ and t8, 0xcc, t1 # last byte written.
+ and t8, 0xaa, t0
+ andnot a0, 7, a0
+ cmovne t2, 4, t2
+ cmovne t1, 2, t1
+ cmovne t0, 1, t0
+ addq a0, t2, v0
+ addq t0, t1, t0
+ addq v0, t0, v0
+
+ ret
+
+ END(__stpcpy)
+
+weak_alias (__stpcpy, stpcpy)
+libc_hidden_def (__stpcpy)
+libc_hidden_builtin_def (stpcpy)
diff --git a/libc/sysdeps/alpha/stpncpy.S b/libc/sysdeps/alpha/stpncpy.S
new file mode 100644
index 000000000..e877cf176
--- /dev/null
+++ b/libc/sysdeps/alpha/stpncpy.S
@@ -0,0 +1,107 @@
+/* Copyright (C) 1996, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@tamu.edu)
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copy no more than COUNT bytes of the null-terminated string from
+ SRC to DST. If SRC does not cover all of COUNT, the balance is
+ zeroed. Return the address of the terminating null in DEST, if
+ any, else DEST + COUNT. */
+
+#include <sysdep.h>
+
+ .set noat
+ .set noreorder
+
+ .text
+
+ENTRY(__stpncpy)
+ ldgp gp, 0(pv)
+#ifdef PROF
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+#endif
+ .prologue 1
+
+ beq a2, $zerocount
+ jsr t9, __stxncpy # do the work of the copy
+
+ and t8, 0xf0, t3 # binary search for byte offset of the
+ and t8, 0xcc, t2 # last byte written.
+ and t8, 0xaa, t1
+ andnot a0, 7, v0
+ cmovne t3, 4, t3
+ cmovne t2, 2, t2
+ cmovne t1, 1, t1
+ addq v0, t3, v0
+ addq t1, t2, t1
+ addq v0, t1, v0
+
+ bne a2, $multiword # do we have full words left?
+
+ .align 3
+ zapnot t0, t8, t4 # e0 : was last byte a null?
+ subq t8, 1, t2 # .. e1 :
+ addq v0, 1, t5 # e0 :
+ subq t10, 1, t3 # .. e1 :
+ or t2, t8, t2 # e0 : clear the bits between the last
+ or t3, t10, t3 # .. e1 : written byte and the last byte in
+ andnot t3, t2, t3 # e0 : COUNT
+ cmovne t4, t5, v0 # .. e1 : if last written wasnt null, inc v0
+ zap t0, t3, t0 # e0 :
+ stq_u t0, 0(a0) # e1 :
+ ret # .. e1 :
+
+ .align 3
+$multiword:
+ subq t8, 1, t7 # e0 : clear the final bits in the prev
+ or t7, t8, t7 # e1 : word
+ zapnot t0, t7, t0 # e0 :
+ subq a2, 1, a2 # .. e1 :
+ stq_u t0, 0(a0) # e0 :
+ addq a0, 8, a0 # .. e1 :
+
+ beq a2, 1f # e1 :
+ blbc a2, 0f # e1 :
+
+ stq_u zero, 0(a0) # e0 : zero one word
+ subq a2, 1, a2 # .. e1 :
+ addq a0, 8, a0 # e0 :
+ beq a2, 1f # .. e1 :
+
+0: stq_u zero, 0(a0) # e0 : zero two words
+ subq a2, 2, a2 # .. e1 :
+ stq_u zero, 8(a0) # e0 :
+ addq a0, 16, a0 # .. e1 :
+ bne a2, 0b # e1 :
+ unop
+
+1: ldq_u t0, 0(a0) # e0 : clear the leading bits in the final
+ subq t10, 1, t7 # .. e1 : word
+ or t7, t10, t7 # e0 :
+ zap t0, t7, t0 # e1 (stall)
+ stq_u t0, 0(a0) # e0 :
+ ret # .. e1 :
+
+$zerocount:
+ mov a0, v0
+ ret
+
+ END(__stpncpy)
+
+libc_hidden_def (__stpncpy)
+weak_alias (__stpncpy, stpncpy)
diff --git a/libc/sysdeps/alpha/strcat.S b/libc/sysdeps/alpha/strcat.S
new file mode 100644
index 000000000..d8ef8f154
--- /dev/null
+++ b/libc/sysdeps/alpha/strcat.S
@@ -0,0 +1,72 @@
+/* Copyright (C) 1996, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Append a null-terminated string from SRC to DST. */
+
+#include <sysdep.h>
+
+ .text
+
+ENTRY(strcat)
+ ldgp gp, 0(pv)
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ mov a0, v0 # set up return value
+
+ /* Find the end of the string. */
+
+ ldq_u t0, 0(a0) # load first quadword (a0 may be misaligned)
+ lda t1, -1(zero)
+ insqh t1, a0, t1
+ andnot a0, 7, a0
+ or t1, t0, t0
+ cmpbge zero, t0, t1 # t1 <- bitmask: bit i == 1 <==> i-th byte == 0
+ bne t1, $found
+
+$loop: ldq t0, 8(a0)
+ addq a0, 8, a0 # addr += 8
+ cmpbge zero, t0, t1
+ beq t1, $loop
+
+$found: negq t1, t2 # clear all but least set bit
+ and t1, t2, t1
+
+ and t1, 0xf0, t2 # binary search for that set bit
+ and t1, 0xcc, t3
+ and t1, 0xaa, t4
+ cmovne t2, 4, t2
+ cmovne t3, 2, t3
+ cmovne t4, 1, t4
+ addq t2, t3, t2
+ addq a0, t4, a0
+ addq a0, t2, a0
+
+ /* Now do the append. */
+
+ mov ra, t9
+ jmp $31, __stxcpy
+
+ END(strcat)
+libc_hidden_builtin_def (strcat)
diff --git a/libc/sysdeps/alpha/strchr.S b/libc/sysdeps/alpha/strchr.S
new file mode 100644
index 000000000..e0b17415a
--- /dev/null
+++ b/libc/sysdeps/alpha/strchr.S
@@ -0,0 +1,95 @@
+/* Copyright (C) 1996, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@tamu.edu)
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return the address of a given character within a null-terminated
+ string, or null if it is not found.
+
+ This is generally scheduled for the EV5 (got to look out for my own
+ interests :-), but with EV4 needs in mind. There *should* be no more
+ stalls for the EV4 than there are for the EV5.
+*/
+
+#include <sysdep.h>
+
+ .set noreorder
+ .set noat
+
+ENTRY(strchr)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ zapnot a1, 1, a1 # e0 : zero extend the search character
+ ldq_u t0, 0(a0) # .. e1 : load first quadword
+ sll a1, 8, t5 # e0 : replicate the search character
+ andnot a0, 7, v0 # .. e1 : align our loop pointer
+ or t5, a1, a1 # e0 :
+ lda t4, -1 # .. e1 : build garbage mask
+ sll a1, 16, t5 # e0 :
+ cmpbge zero, t0, t2 # .. e1 : bits set iff byte == zero
+ mskqh t4, a0, t4 # e0 :
+ or t5, a1, a1 # .. e1 :
+ sll a1, 32, t5 # e0 :
+ cmpbge zero, t4, t4 # .. e1 : bits set iff byte is garbage
+ or t5, a1, a1 # e0 :
+ xor t0, a1, t1 # .. e1 : make bytes == c zero
+ cmpbge zero, t1, t3 # e0 : bits set iff byte == c
+ or t2, t3, t0 # e1 : bits set iff char match or zero match
+ andnot t0, t4, t0 # e0 : clear garbage bits
+ bne t0, $found # .. e1 (zdb)
+
+$loop: ldq t0, 8(v0) # e0 :
+ addq v0, 8, v0 # .. e1 :
+ nop # e0 :
+ xor t0, a1, t1 # .. e1 (ev5 data stall)
+ cmpbge zero, t0, t2 # e0 : bits set iff byte == 0
+ cmpbge zero, t1, t3 # .. e1 : bits set iff byte == c
+ or t2, t3, t0 # e0 :
+ beq t0, $loop # .. e1 (zdb)
+
+$found: negq t0, t1 # e0 : clear all but least set bit
+ and t0, t1, t0 # e1 (stall)
+
+ and t0, t3, t1 # e0 : bit set iff byte was the char
+ beq t1, $retnull # .. e1 (zdb)
+
+ and t0, 0xf0, t2 # e0 : binary search for that set bit
+ and t0, 0xcc, t3 # .. e1 :
+ and t0, 0xaa, t4 # e0 :
+ cmovne t2, 4, t2 # .. e1 :
+ cmovne t3, 2, t3 # e0 :
+ cmovne t4, 1, t4 # .. e1 :
+ addq t2, t3, t2 # e0 :
+ addq v0, t4, v0 # .. e1 :
+ addq v0, t2, v0 # e0 :
+ ret # .. e1 :
+
+$retnull:
+ mov zero, v0 # e0 :
+ ret # .. e1 :
+
+ END(strchr)
+
+weak_alias (strchr, index)
+libc_hidden_builtin_def (strchr)
diff --git a/libc/sysdeps/alpha/strcmp.S b/libc/sysdeps/alpha/strcmp.S
new file mode 100644
index 000000000..9196be2ce
--- /dev/null
+++ b/libc/sysdeps/alpha/strcmp.S
@@ -0,0 +1,195 @@
+/* Copyright (C) 1996, 1997, 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu)
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Bytewise compare two null-terminated strings. */
+
+#include <sysdep.h>
+
+ .set noat
+ .set noreorder
+
+ .text
+
+ENTRY(strcmp)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jmp AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ ldq_u t0, 0(a0) # e0 : give cache time to catch up
+ xor a0, a1, t2 # .. e1 : are s1 and s2 co-aligned?
+ ldq_u t1, 0(a1) # e0 :
+ and t2, 7, t2 # .. e1 :
+ lda t3, -1 # e0 :
+ bne t2, $unaligned # .. e1 :
+
+ /* On entry to this basic block:
+ t0 == the first destination word for masking back in
+ t1 == the first source word.
+ t3 == -1. */
+
+$aligned:
+ mskqh t3, a0, t3 # e0 :
+ nop # .. e1 :
+ ornot t1, t3, t1 # e0 :
+ ornot t0, t3, t0 # .. e1 :
+ cmpbge zero, t1, t7 # e0 : bits set iff null found
+ bne t7, $eos # e1 (zdb)
+
+ /* Aligned compare main loop.
+ On entry to this basic block:
+ t0 == an s1 word.
+ t1 == an s2 word not containing a null. */
+
+$a_loop:
+ xor t0, t1, t2 # e0 :
+ bne t2, $wordcmp # .. e1 (zdb)
+ ldq_u t1, 8(a1) # e0 :
+ ldq_u t0, 8(a0) # .. e1 :
+ addq a1, 8, a1 # e0 :
+ addq a0, 8, a0 # .. e1 :
+ cmpbge zero, t1, t7 # e0 :
+ beq t7, $a_loop # .. e1 (zdb)
+ br $eos # e1 :
+
+ /* The two strings are not co-aligned. Align s1 and cope. */
+
+$unaligned:
+ and a0, 7, t4 # e0 : find s1 misalignment
+ and a1, 7, t5 # .. e1 : find s2 misalignment
+ subq a1, t4, a1 # e0 :
+
+ /* If s2 misalignment is larger than s2 misalignment, we need
+ extra startup checks to avoid SEGV. */
+
+ cmplt t4, t5, t8 # .. e1 :
+ beq t8, $u_head # e1 :
+
+ mskqh t3, t5, t3 # e0 :
+ ornot t1, t3, t3 # e0 :
+ cmpbge zero, t3, t7 # e1 : is there a zero?
+ beq t7, $u_head # e1 :
+
+ /* We've found a zero in the first partial word of s2. Align
+ our current s1 and s2 words and compare what we've got. */
+
+ extql t1, t5, t1 # e0 :
+ extql t0, a0, t0 # e0 :
+ cmpbge zero, t1, t7 # .. e1 : find that zero again
+ br $eos # e1 : and finish up
+
+ .align 3
+$u_head:
+ /* We know just enough now to be able to assemble the first
+ full word of s2. We can still find a zero at the end of it.
+
+ On entry to this basic block:
+ t0 == first word of s1
+ t1 == first partial word of s2. */
+
+ ldq_u t2, 8(a1) # e0 : load second partial s2 word
+ lda t3, -1 # .. e1 : create leading garbage mask
+ extql t1, a1, t1 # e0 : create first s2 word
+ mskqh t3, a0, t3 # e0 :
+ extqh t2, a1, t4 # e0 :
+ ornot t0, t3, t0 # .. e1 : kill s1 garbage
+ or t1, t4, t1 # e0 : s2 word now complete
+ cmpbge zero, t0, t7 # .. e1 : find zero in first s1 word
+ ornot t1, t3, t1 # e0 : kill s2 garbage
+ lda t3, -1 # .. e1 :
+ mskql t3, a1, t3 # e0 : mask for s2[1] bits we have seen
+ bne t7, $eos # .. e1 :
+ xor t0, t1, t4 # e0 : compare aligned words
+ bne t4, $wordcmp # .. e1 (zdb)
+ or t2, t3, t3 # e0 :
+ cmpbge zero, t3, t7 # e1 :
+ bne t7, $u_final # e1 :
+
+ /* Unaligned copy main loop. In order to avoid reading too much,
+ the loop is structured to detect zeros in aligned words from s2.
+ This has, unfortunately, effectively pulled half of a loop
+ iteration out into the head and half into the tail, but it does
+ prevent nastiness from accumulating in the very thing we want
+ to run as fast as possible.
+
+ On entry to this basic block:
+ t2 == the unshifted low-bits from the next s2 word. */
+
+ .align 3
+$u_loop:
+ extql t2, a1, t3 # e0 :
+ ldq_u t2, 16(a1) # .. e1 : load next s2 high bits
+ ldq_u t0, 8(a0) # e0 : load next s1 word
+ addq a1, 8, a1 # .. e1 :
+ addq a0, 8, a0 # e0 :
+ nop # .. e1 :
+ extqh t2, a1, t1 # e0 :
+ cmpbge zero, t0, t7 # .. e1 : find zero in current s1 word
+ or t1, t3, t1 # e0 :
+ bne t7, $eos # .. e1 :
+ xor t0, t1, t4 # e0 : compare the words
+ bne t4, $wordcmp # .. e1 (zdb)
+ cmpbge zero, t2, t4 # e0 : find zero in next low bits
+ beq t4, $u_loop # .. e1 (zdb)
+
+ /* We've found a zero in the low bits of the last s2 word. Get
+ the next s1 word and align them. */
+$u_final:
+ ldq_u t0, 8(a0) # e1 :
+ extql t2, a1, t1 # .. e0 :
+ cmpbge zero, t1, t7 # e0 :
+
+ /* We've found a zero somewhere in a word we just read.
+ On entry to this basic block:
+ t0 == s1 word
+ t1 == s2 word
+ t7 == cmpbge mask containing the zero. */
+
+ .align 3
+$eos:
+ negq t7, t6 # e0 : create bytemask of valid data
+ and t6, t7, t8 # e1 :
+ subq t8, 1, t6 # e0 :
+ or t6, t8, t7 # e1 :
+ zapnot t0, t7, t0 # e0 : kill the garbage
+ zapnot t1, t7, t1 # .. e1 :
+ xor t0, t1, v0 # e0 : and compare
+ beq v0, $done # .. e1 :
+
+ /* Here we have two differing co-aligned words in t0 & t1.
+ Bytewise compare them and return (t0 > t1 ? 1 : -1). */
+$wordcmp:
+ cmpbge t0, t1, t2 # e0 : comparison yields bit mask of ge
+ cmpbge t1, t0, t3 # .. e1 :
+ xor t2, t3, t0 # e0 : bits set iff t0/t1 bytes differ
+ negq t0, t1 # e1 : clear all but least bit
+ and t0, t1, t0 # e0 :
+ lda v0, -1 # .. e1 :
+ and t0, t2, t1 # e0 : was bit set in t0 > t1?
+ cmovne t1, 1, v0 # .. e1 (zdb)
+
+$done:
+ ret # e1 :
+
+ END(strcmp)
+libc_hidden_builtin_def (strcmp)
diff --git a/libc/sysdeps/alpha/strcpy.S b/libc/sysdeps/alpha/strcpy.S
new file mode 100644
index 000000000..02bfe5240
--- /dev/null
+++ b/libc/sysdeps/alpha/strcpy.S
@@ -0,0 +1,42 @@
+/* Copyright (C) 1996, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copy a null-terminated string from SRC to DST. Return a pointer
+ to the null-terminator in the source. */
+
+#include <sysdep.h>
+
+ .text
+
+ENTRY(strcpy)
+ ldgp gp, 0(pv)
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ mov a0, v0 # set up return value
+ mov ra, t9
+ jmp $31, __stxcpy # do the copy
+
+ END(strcpy)
+libc_hidden_builtin_def (strcpy)
diff --git a/libc/sysdeps/alpha/strlen.S b/libc/sysdeps/alpha/strlen.S
new file mode 100644
index 000000000..2560b973c
--- /dev/null
+++ b/libc/sysdeps/alpha/strlen.S
@@ -0,0 +1,77 @@
+/* Copyright (C) 1996, 1997, 2003 Free Software Foundation, Inc.
+ Contributed by David Mosberger (davidm@cs.arizona.edu).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Finds length of a 0-terminated string. Optimized for the Alpha
+ architecture:
+
+ - memory accessed as aligned quadwords only
+ - uses cmpbge to compare 8 bytes in parallel
+ - does binary search to find 0 byte in last quadword (HAKMEM
+ needed 12 instructions to do this instead of the 8 instructions
+ that the binary search needs).
+*/
+
+#include <sysdep.h>
+
+ .set noreorder
+ .set noat
+
+ENTRY(strlen)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ ldq_u t0, 0(a0) # load first quadword (a0 may be misaligned)
+ lda t1, -1(zero)
+ insqh t1, a0, t1
+ andnot a0, 7, v0
+ or t1, t0, t0
+ nop # dual issue the next two on ev5
+ cmpbge zero, t0, t1 # t1 <- bitmask: bit i == 1 <==> i-th byte == 0
+ bne t1, $found
+
+$loop: ldq t0, 8(v0)
+ addq v0, 8, v0 # addr += 8
+ cmpbge zero, t0, t1
+ beq t1, $loop
+
+$found: negq t1, t2 # clear all but least set bit
+ and t1, t2, t1
+
+ and t1, 0xf0, t2 # binary search for that set bit
+ and t1, 0xcc, t3
+ and t1, 0xaa, t4
+ cmovne t2, 4, t2
+ cmovne t3, 2, t3
+ cmovne t4, 1, t4
+ addq t2, t3, t2
+ addq v0, t4, v0
+ addq v0, t2, v0
+ nop # dual issue next two on ev4 and ev5
+
+ subq v0, a0, v0
+ ret
+
+ END(strlen)
+libc_hidden_builtin_def (strlen)
diff --git a/libc/sysdeps/alpha/strncat.S b/libc/sysdeps/alpha/strncat.S
new file mode 100644
index 000000000..ddf686f57
--- /dev/null
+++ b/libc/sysdeps/alpha/strncat.S
@@ -0,0 +1,95 @@
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Append no more than COUNT characters from the null-terminated string SRC
+ to the null-terminated string DST. Always null-terminate the new DST. */
+
+#include <sysdep.h>
+
+ .text
+
+ENTRY(strncat)
+ ldgp gp, 0(pv)
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ mov a0, v0 # set up return value
+ beq a2, $zerocount
+
+ /* Find the end of the string. */
+
+ ldq_u t0, 0(a0) # load first quadword (a0 may be misaligned)
+ lda t1, -1(zero)
+ insqh t1, a0, t1
+ andnot a0, 7, a0
+ or t1, t0, t0
+ cmpbge zero, t0, t1 # t1 <- bitmask: bit i == 1 <==> i-th byte == 0
+ bne t1, $found
+
+$loop: ldq t0, 8(a0)
+ addq a0, 8, a0 # addr += 8
+ cmpbge zero, t0, t1
+ beq t1, $loop
+
+$found: negq t1, t2 # clear all but least set bit
+ and t1, t2, t1
+
+ and t1, 0xf0, t2 # binary search for that set bit
+ and t1, 0xcc, t3
+ and t1, 0xaa, t4
+ cmovne t2, 4, t2
+ cmovne t3, 2, t3
+ cmovne t4, 1, t4
+ addq t2, t3, t2
+ addq a0, t4, a0
+ addq a0, t2, a0
+
+ /* Now do the append. */
+
+ jsr t9, __stxncpy
+
+ /* Worry about the null termination. */
+
+ zapnot t0, t8, t1 # was last byte a null?
+ bne t1, 0f
+ ret
+
+0: and t10, 0x80, t1
+ bne t1, 1f
+
+ /* Here there are bytes left in the current word. Clear one. */
+ addq t10, t10, t10 # end-of-count bit <<= 1
+ zap t0, t10, t0
+ stq_u t0, 0(a0)
+ ret
+
+1: /* Here we must read the next DST word and clear the first byte. */
+ ldq_u t0, 8(a0)
+ zap t0, 1, t0
+ stq_u t0, 8(a0)
+
+$zerocount:
+ ret
+
+ END(strncat)
diff --git a/libc/sysdeps/alpha/strncmp.S b/libc/sysdeps/alpha/strncmp.S
new file mode 100644
index 000000000..ff199eb74
--- /dev/null
+++ b/libc/sysdeps/alpha/strncmp.S
@@ -0,0 +1,247 @@
+/* Copyright (C) 1996, 1997, 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu)
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Bytewise compare two null-terminated strings of length no longer than N. */
+
+#include <sysdep.h>
+
+ .set noat
+ .set noreorder
+
+ .text
+
+ENTRY(strncmp)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ xor a0, a1, t2 # e0 : are s1 and s2 co-aligned?
+ beq a2, $zerolength # .. e1 :
+ ldq_u t0, 0(a0) # e0 : give cache time to catch up
+ ldq_u t1, 0(a1) # .. e1 :
+ and t2, 7, t2 # e0 :
+ and a0, 7, t4 # .. e1 : find s1 misalignment
+ lda t3, -1 # e0 :
+ addq a2, t4, a2 # .. e1 : bias count by s1 misalignment
+ and a2, 7, t10 # e1 : ofs of last byte in last word
+ srl a2, 3, a2 # .. e0 : remaining full words in count
+ and a1, 7, t5 # e0 : find s2 misalignment
+ bne t2, $unaligned # .. e1 :
+
+ /* On entry to this basic block:
+ t0 == the first word of s1.
+ t1 == the first word of s2.
+ t3 == -1. */
+
+$aligned:
+ mskqh t3, a1, t3 # e0 : mask off leading garbage
+ nop # .. e1 :
+ ornot t1, t3, t1 # e0 :
+ ornot t0, t3, t0 # .. e1 :
+ cmpbge zero, t1, t7 # e0 : bits set iff null found
+ beq a2, $eoc # .. e1 : check end of count
+ unop # e0 :
+ bne t7, $eos # .. e1 :
+ unop # e0 :
+ beq t10, $ant_loop # .. e1 :
+
+ /* Aligned compare main loop.
+ On entry to this basic block:
+ t0 == an s1 word.
+ t1 == an s2 word not containing a null. */
+
+$a_loop:
+ xor t0, t1, t2 # e0 :
+ bne t2, $wordcmp # .. e1 (zdb)
+ ldq_u t1, 8(a1) # e0 :
+ ldq_u t0, 8(a0) # .. e1 :
+ subq a2, 1, a2 # e0 :
+ addq a1, 8, a1 # .. e1 :
+ addq a0, 8, a0 # e0 :
+ beq a2, $eoc # .. e1 :
+ cmpbge zero, t1, t7 # e0 :
+ beq t7, $a_loop # .. e1 :
+ unop # e0 :
+ br $eos # .. e1 :
+
+ /* Alternate aligned compare loop, for when there's no trailing
+ bytes on the count. We have to avoid reading too much data. */
+$ant_loop:
+ xor t0, t1, t2 # e0 :
+ bne t2, $wordcmp # .. e1 (zdb)
+ subq a2, 1, a2 # e0 :
+ beq a2, $zerolength # .. e1 :
+ ldq_u t1, 8(a1) # e0 :
+ ldq_u t0, 8(a0) # .. e1 :
+ addq a1, 8, a1 # e0 :
+ addq a0, 8, a0 # .. e1 :
+ cmpbge zero, t1, t7 # e0 :
+ beq t7, $ant_loop # .. e1 :
+ unop # e0 :
+ br $eos # .. e1 :
+
+ /* The two strings are not co-aligned. Align s1 and cope. */
+$unaligned:
+ subq a1, t4, a1 # e0 :
+ unop # :
+
+ /* If s2 misalignment is larger than s2 misalignment, we need
+ extra startup checks to avoid SEGV. */
+
+ cmplt t4, t5, t8 # .. e1 :
+ beq t8, $u_head # e1 :
+
+ mskqh t3, t5, t3 # e0 :
+ ornot t1, t3, t3 # e0 :
+ cmpbge zero, t3, t7 # e1 : is there a zero?
+ beq t7, $u_head # e1 :
+
+ /* We've found a zero in the first partial word of s2. Align
+ our current s1 and s2 words and compare what we've got. */
+
+ extql t1, t5, t1 # e0 :
+ lda t3, -1 # .. e1 :
+ insql t1, a0, t1 # e0 :
+ mskqh t3, a0, t3 # e0 :
+ ornot t1, t3, t1 # e0 :
+ ornot t0, t3, t0 # .. e1 :
+ cmpbge zero, t1, t7 # e0 : find that zero again
+ beq a2, $eoc # .. e1 : and finish up
+ br $eos # e1 :
+
+ .align 3
+$u_head:
+ /* We know just enough now to be able to assemble the first
+ full word of s2. We can still find a zero at the end of it.
+
+ On entry to this basic block:
+ t0 == first word of s1
+ t1 == first partial word of s2. */
+
+ ldq_u t2, 8(a1) # e0 : load second partial s2 word
+ lda t3, -1 # .. e1 : create leading garbage mask
+ extql t1, a1, t1 # e0 : create first s2 word
+ mskqh t3, a0, t3 # e0 :
+ extqh t2, a1, t4 # e0 :
+ ornot t0, t3, t0 # .. e1 : kill s1 garbage
+ or t1, t4, t1 # e0 : s2 word now complete
+ ornot t1, t3, t1 # e1 : kill s2 garbage
+ cmpbge zero, t0, t7 # e0 : find zero in first s1 word
+ beq a2, $eoc # .. e1 :
+ lda t3, -1 # e0 :
+ bne t7, $eos # .. e1 :
+ subq a2, 1, a2 # e0 :
+ xor t0, t1, t4 # .. e1 : compare aligned words
+ mskql t3, a1, t3 # e0 : mask out s2[1] bits we have seen
+ bne t4, $wordcmp # .. e1 :
+ or t2, t3, t3 # e0 :
+ cmpbge zero, t3, t7 # e1 : find zero in high bits of s2[1]
+ bne t7, $u_final # e1 :
+
+ /* Unaligned copy main loop. In order to avoid reading too much,
+ the loop is structured to detect zeros in aligned words from s2.
+ This has, unfortunately, effectively pulled half of a loop
+ iteration out into the head and half into the tail, but it does
+ prevent nastiness from accumulating in the very thing we want
+ to run as fast as possible.
+
+ On entry to this basic block:
+ t2 == the unshifted low-bits from the next s2 word. */
+
+ .align 3
+$u_loop:
+ extql t2, a1, t3 # e0 :
+ ldq_u t2, 16(a1) # .. e1 : load next s2 high bits
+ ldq_u t0, 8(a0) # e0 : load next s1 word
+ addq a1, 8, a1 # .. e1 :
+ addq a0, 8, a0 # e0 :
+ nop # .. e1 :
+ extqh t2, a1, t1 # e0 :
+ cmpbge zero, t0, t7 # .. e1 : find zero in current s1 word
+ or t1, t3, t1 # e0 :
+ beq a2, $eoc # .. e1 : check for end of count
+ subq a2, 1, a2 # e0 :
+ bne t7, $eos # .. e1 :
+ xor t0, t1, t4 # e0 : compare the words
+ bne t4, $wordcmp # .. e1 (zdb)
+ cmpbge zero, t2, t4 # e0 : find zero in next low bits
+ beq t4, $u_loop # .. e1 (zdb)
+
+ /* We've found a zero in the low bits of the last s2 word. Get
+ the next s1 word and align them. */
+$u_final:
+ ldq_u t0, 8(a0) # e1 :
+ extql t2, a1, t1 # .. e0 :
+ cmpbge zero, t1, t7 # e0 :
+ bne a2, $eos # .. e1 :
+
+ /* We've hit end of count. Zero everything after the count
+ and compare whats left. */
+
+ .align 3
+$eoc:
+ mskql t0, t10, t0
+ mskql t1, t10, t1
+ unop
+ cmpbge zero, t1, t7
+
+ /* We've found a zero somewhere in a word we just read.
+ On entry to this basic block:
+ t0 == s1 word
+ t1 == s2 word
+ t7 == cmpbge mask containing the zero. */
+
+$eos:
+ negq t7, t6 # e0 : create bytemask of valid data
+ and t6, t7, t8 # e1 :
+ subq t8, 1, t6 # e0 :
+ or t6, t8, t7 # e1 :
+ zapnot t0, t7, t0 # e0 : kill the garbage
+ zapnot t1, t7, t1 # .. e1 :
+ xor t0, t1, v0 # e0 : and compare
+ beq v0, $done # .. e1 :
+
+ /* Here we have two differing co-aligned words in t0 & t1.
+ Bytewise compare them and return (t0 > t1 ? 1 : -1). */
+ .align 3
+$wordcmp:
+ cmpbge t0, t1, t2 # e0 : comparison yields bit mask of ge
+ cmpbge t1, t0, t3 # .. e1 :
+ xor t2, t3, t0 # e0 : bits set iff t0/t1 bytes differ
+ negq t0, t1 # e1 : clear all but least bit
+ and t0, t1, t0 # e0 :
+ lda v0, -1 # .. e1 :
+ and t0, t2, t1 # e0 : was bit set in t0 > t1?
+ cmovne t1, 1, v0 # .. e1 (zdb)
+
+$done:
+ ret # e1 :
+
+ .align 3
+$zerolength:
+ clr v0
+ ret
+
+ END(strncmp)
+libc_hidden_builtin_def (strncmp)
diff --git a/libc/sysdeps/alpha/strncpy.S b/libc/sysdeps/alpha/strncpy.S
new file mode 100644
index 000000000..5d3e72e28
--- /dev/null
+++ b/libc/sysdeps/alpha/strncpy.S
@@ -0,0 +1,88 @@
+/* Copyright (C) 1996, 1997, 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu)
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copy no more than COUNT bytes of the null-terminated string from
+ SRC to DST. If SRC does not cover all of COUNT, the balance is
+ zeroed. */
+
+#include <sysdep.h>
+
+ .set noat
+ .set noreorder
+
+ .text
+
+ENTRY(strncpy)
+ ldgp gp, 0(pv)
+#ifdef PROF
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+#endif
+ .prologue 1
+
+ mov a0, v0 # set return value now
+ beq a2, $zerocount
+ jsr t9, __stxncpy # do the work of the copy
+
+ bne a2, $multiword # do we have full words left?
+
+ .align 3
+ subq t8, 1, t2 # e0 : guess not
+ subq t10, 1, t3 # .. e1 :
+ or t2, t8, t2 # e0 : clear the bits between the last
+ or t3, t10, t3 # .. e1 : written byte and the last byte in
+ andnot t3, t2, t3 # e0 : COUNT
+ zap t0, t3, t0 # e1 :
+ stq_u t0, 0(a0) # e0 :
+ ret # .. e1 :
+
+$multiword:
+ subq t8, 1, t7 # e0 : clear the final bits in the prev
+ or t7, t8, t7 # e1 : word
+ zapnot t0, t7, t0 # e0 :
+ subq a2, 1, a2 # .. e1 :
+ stq_u t0, 0(a0) # e0 :
+ addq a0, 8, a0 # .. e1 :
+
+ beq a2, 1f # e1 :
+ blbc a2, 0f # e1 :
+
+ stq_u zero, 0(a0) # e0 : zero one word
+ subq a2, 1, a2 # .. e1 :
+ addq a0, 8, a0 # e0 :
+ beq a2, 1f # .. e1 :
+
+0: stq_u zero, 0(a0) # e0 : zero two words
+ subq a2, 2, a2 # .. e1 :
+ stq_u zero, 8(a0) # e0 :
+ addq a0, 16, a0 # .. e1 :
+ bne a2, 0b # e1 :
+ unop
+
+1: ldq_u t0, 0(a0) # e0 : clear the leading bits in the final
+ subq t10, 1, t7 # .. e1 : word
+ or t7, t10, t7 # e0 :
+ zap t0, t7, t0 # e1 (stall)
+ stq_u t0, 0(a0) # e0 :
+
+$zerocount:
+ ret # .. e1 :
+
+ END(strncpy)
+libc_hidden_builtin_def (strncpy)
diff --git a/libc/sysdeps/alpha/strrchr.S b/libc/sysdeps/alpha/strrchr.S
new file mode 100644
index 000000000..248181f70
--- /dev/null
+++ b/libc/sysdeps/alpha/strrchr.S
@@ -0,0 +1,111 @@
+/* Copyright (C) 1996, 1997, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return the address of the last occurrence of a given character
+ within a null-terminated string, or null if it is not found.
+
+ This is generally scheduled for the EV5 (got to look out for my own
+ interests :-), but with EV4 needs in mind. There are, in fact, fewer
+ stalls on the EV4 than there are on the EV5.
+*/
+
+#include <sysdep.h>
+
+ .set noreorder
+ .set noat
+
+ENTRY(strrchr)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ and a1, 0xff, a1 # e0 : zero extend our test character
+ mov zero, t6 # .. e1 : t6 is last match aligned addr
+ sll a1, 8, t5 # e0 : replicate our test character
+ mov zero, t7 # .. e1 : t7 is last match byte compare mask
+ or t5, a1, a1 # e0 :
+ ldq_u t0, 0(a0) # .. e1 : load first quadword
+ sll a1, 16, t5 # e0 :
+ andnot a0, 7, v0 # .. e1 : align source addr
+ or t5, a1, a1 # e0 :
+ lda t4, -1 # .. e1 : build garbage mask
+ sll a1, 32, t5 # e0 :
+ cmpbge zero, t0, t1 # .. e1 : bits set iff byte == zero
+ mskqh t4, a0, t4 # e0 :
+ or t5, a1, a1 # .. e1 : character replication complete
+ xor t0, a1, t2 # e0 : make bytes == c zero
+ cmpbge zero, t4, t4 # .. e1 : bits set iff byte is garbage
+ cmpbge zero, t2, t3 # e0 : bits set iff byte == c
+ andnot t1, t4, t1 # .. e1 : clear garbage from null test
+ andnot t3, t4, t3 # e0 : clear garbage from char test
+ bne t1, $eos # .. e1 : did we already hit the terminator?
+
+ /* Character search main loop */
+$loop:
+ ldq t0, 8(v0) # e0 : load next quadword
+ cmovne t3, v0, t6 # .. e1 : save previous comparisons match
+ cmovne t3, t3, t7 # e0 :
+ addq v0, 8, v0 # .. e1 :
+ xor t0, a1, t2 # e0 :
+ cmpbge zero, t0, t1 # .. e1 : bits set iff byte == zero
+ cmpbge zero, t2, t3 # e0 : bits set iff byte == c
+ beq t1, $loop # .. e1 : if we havnt seen a null, loop
+
+ /* Mask out character matches after terminator */
+$eos:
+ negq t1, t4 # e0 : isolate first null byte match
+ and t1, t4, t4 # e1 :
+ subq t4, 1, t5 # e0 : build a mask of the bytes upto...
+ or t4, t5, t4 # e1 : ... and including the null
+
+ and t3, t4, t3 # e0 : mask out char matches after null
+ cmovne t3, t3, t7 # .. e1 : save it, if match found
+ cmovne t3, v0, t6 # e0 :
+
+ /* Locate the address of the last matched character */
+
+ /* Retain the early exit for the ev4 -- the ev5 mispredict penalty
+ is 5 cycles -- the same as just falling through. */
+ beq t7, $retnull # .. e1 :
+
+ and t7, 0xf0, t2 # e0 : binary search for the high bit set
+ cmovne t2, t2, t7 # .. e1 (zdb)
+ cmovne t2, 4, t2 # e0 :
+ and t7, 0xcc, t1 # .. e1 :
+ cmovne t1, t1, t7 # e0 :
+ cmovne t1, 2, t1 # .. e1 :
+ and t7, 0xaa, t0 # e0 :
+ cmovne t0, 1, t0 # .. e1 (zdb)
+ addq t2, t1, t1 # e0 :
+ addq t6, t0, v0 # .. e1 : add our aligned base ptr to the mix
+ addq v0, t1, v0 # e0 :
+ ret # .. e1 :
+
+$retnull:
+ mov zero, v0 # e0 :
+ ret # .. e1 :
+
+ END(strrchr)
+
+weak_alias (strrchr, rindex)
+libc_hidden_builtin_def (strrchr)
diff --git a/libc/sysdeps/alpha/stxcpy.S b/libc/sysdeps/alpha/stxcpy.S
new file mode 100644
index 000000000..5ba2d43e5
--- /dev/null
+++ b/libc/sysdeps/alpha/stxcpy.S
@@ -0,0 +1,307 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu)
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copy a null-terminated string from SRC to DST.
+
+ This is an internal routine used by strcpy, stpcpy, and strcat.
+ As such, it uses special linkage conventions to make implementation
+ of these public functions more efficient.
+
+ On input:
+ t9 = return address
+ a0 = DST
+ a1 = SRC
+
+ On output:
+ t8 = bitmask (with one bit set) indicating the last byte written
+ a0 = unaligned address of the last *word* written
+
+ Furthermore, v0, a3-a5, t11, and t12 are untouched.
+*/
+
+/* This is generally scheduled for the EV5, but should still be pretty
+ good for the EV4 too. */
+
+#include <sysdep.h>
+
+ .set noat
+ .set noreorder
+
+ .text
+
+/* There is a problem with either gdb (as of 4.16) or gas (as of 2.7) that
+ doesn't like putting the entry point for a procedure somewhere in the
+ middle of the procedure descriptor. Work around this by putting the
+ aligned copy in its own procedure descriptor */
+
+ .ent stxcpy_aligned
+ .align 3
+stxcpy_aligned:
+ .frame sp, 0, t9
+ .prologue 0
+
+ /* On entry to this basic block:
+ t0 == the first destination word for masking back in
+ t1 == the first source word. */
+
+ /* Create the 1st output word and detect 0's in the 1st input word. */
+ lda t2, -1 # e1 : build a mask against false zero
+ mskqh t2, a1, t2 # e0 : detection in the src word
+ mskqh t1, a1, t3 # e0 :
+ ornot t1, t2, t2 # .. e1 :
+ mskql t0, a1, t0 # e0 : assemble the first output word
+ cmpbge zero, t2, t7 # .. e1 : bits set iff null found
+ or t0, t3, t1 # e0 :
+ bne t7, $a_eos # .. e1 :
+
+ /* On entry to this basic block:
+ t0 == the first destination word for masking back in
+ t1 == a source word not containing a null. */
+
+$a_loop:
+ stq_u t1, 0(a0) # e0 :
+ addq a0, 8, a0 # .. e1 :
+ ldq_u t1, 0(a1) # e0 :
+ addq a1, 8, a1 # .. e1 :
+ cmpbge zero, t1, t7 # e0 (stall)
+ beq t7, $a_loop # .. e1 (zdb)
+
+ /* Take care of the final (partial) word store.
+ On entry to this basic block we have:
+ t1 == the source word containing the null
+ t7 == the cmpbge mask that found it. */
+$a_eos:
+ negq t7, t6 # e0 : find low bit set
+ and t7, t6, t8 # e1 (stall)
+
+ /* For the sake of the cache, don't read a destination word
+ if we're not going to need it. */
+ and t8, 0x80, t6 # e0 :
+ bne t6, 1f # .. e1 (zdb)
+
+ /* We're doing a partial word store and so need to combine
+ our source and original destination words. */
+ ldq_u t0, 0(a0) # e0 :
+ subq t8, 1, t6 # .. e1 :
+ zapnot t1, t6, t1 # e0 : clear src bytes >= null
+ or t8, t6, t7 # .. e1 :
+ zap t0, t7, t0 # e0 : clear dst bytes <= null
+ or t0, t1, t1 # e1 :
+
+1: stq_u t1, 0(a0) # e0 :
+ ret (t9) # .. e1 :
+
+ .end stxcpy_aligned
+
+ .align 3
+ .ent __stxcpy
+ .globl __stxcpy
+__stxcpy:
+ .frame sp, 0, t9
+ .prologue 0
+
+ /* Are source and destination co-aligned? */
+ xor a0, a1, t0 # e0 :
+ unop # :
+ and t0, 7, t0 # e0 :
+ bne t0, $unaligned # .. e1 :
+
+ /* We are co-aligned; take care of a partial first word. */
+ ldq_u t1, 0(a1) # e0 : load first src word
+ and a0, 7, t0 # .. e1 : take care not to load a word ...
+ addq a1, 8, a1 # e0 :
+ beq t0, stxcpy_aligned # .. e1 : ... if we wont need it
+ ldq_u t0, 0(a0) # e0 :
+ br stxcpy_aligned # .. e1 :
+
+
+/* The source and destination are not co-aligned. Align the destination
+ and cope. We have to be very careful about not reading too much and
+ causing a SEGV. */
+
+ .align 3
+$u_head:
+ /* We know just enough now to be able to assemble the first
+ full source word. We can still find a zero at the end of it
+ that prevents us from outputting the whole thing.
+
+ On entry to this basic block:
+ t0 == the first dest word, for masking back in, if needed else 0
+ t1 == the low bits of the first source word
+ t6 == bytemask that is -1 in dest word bytes */
+
+ ldq_u t2, 8(a1) # e0 :
+ addq a1, 8, a1 # .. e1 :
+
+ extql t1, a1, t1 # e0 :
+ extqh t2, a1, t4 # e0 :
+ mskql t0, a0, t0 # e0 :
+ or t1, t4, t1 # .. e1 :
+ mskqh t1, a0, t1 # e0 :
+ or t0, t1, t1 # e1 :
+
+ or t1, t6, t6 # e0 :
+ cmpbge zero, t6, t7 # .. e1 :
+ lda t6, -1 # e0 : for masking just below
+ bne t7, $u_final # .. e1 :
+
+ mskql t6, a1, t6 # e0 : mask out the bits we have
+ or t6, t2, t2 # e1 : already extracted before
+ cmpbge zero, t2, t7 # e0 : testing eos
+ bne t7, $u_late_head_exit # .. e1 (zdb)
+
+ /* Finally, we've got all the stupid leading edge cases taken care
+ of and we can set up to enter the main loop. */
+
+ stq_u t1, 0(a0) # e0 : store first output word
+ addq a0, 8, a0 # .. e1 :
+ extql t2, a1, t0 # e0 : position ho-bits of lo word
+ ldq_u t2, 8(a1) # .. e1 : read next high-order source word
+ addq a1, 8, a1 # e0 :
+ cmpbge zero, t2, t7 # .. e1 :
+ nop # e0 :
+ bne t7, $u_eos # .. e1 :
+
+ /* Unaligned copy main loop. In order to avoid reading too much,
+ the loop is structured to detect zeros in aligned source words.
+ This has, unfortunately, effectively pulled half of a loop
+ iteration out into the head and half into the tail, but it does
+ prevent nastiness from accumulating in the very thing we want
+ to run as fast as possible.
+
+ On entry to this basic block:
+ t0 == the shifted high-order bits from the previous source word
+ t2 == the unshifted current source word
+
+ We further know that t2 does not contain a null terminator. */
+
+ .align 3
+$u_loop:
+ extqh t2, a1, t1 # e0 : extract high bits for current word
+ addq a1, 8, a1 # .. e1 :
+ extql t2, a1, t3 # e0 : extract low bits for next time
+ addq a0, 8, a0 # .. e1 :
+ or t0, t1, t1 # e0 : current dst word now complete
+ ldq_u t2, 0(a1) # .. e1 : load high word for next time
+ stq_u t1, -8(a0) # e0 : save the current word
+ mov t3, t0 # .. e1 :
+ cmpbge zero, t2, t7 # e0 : test new word for eos
+ beq t7, $u_loop # .. e1 :
+
+ /* We've found a zero somewhere in the source word we just read.
+ If it resides in the lower half, we have one (probably partial)
+ word to write out, and if it resides in the upper half, we
+ have one full and one partial word left to write out.
+
+ On entry to this basic block:
+ t0 == the shifted high-order bits from the previous source word
+ t2 == the unshifted current source word. */
+$u_eos:
+ extqh t2, a1, t1 # e0 :
+ or t0, t1, t1 # e1 : first (partial) source word complete
+
+ cmpbge zero, t1, t7 # e0 : is the null in this first bit?
+ bne t7, $u_final # .. e1 (zdb)
+
+$u_late_head_exit:
+ stq_u t1, 0(a0) # e0 : the null was in the high-order bits
+ addq a0, 8, a0 # .. e1 :
+ extql t2, a1, t1 # e0 :
+ cmpbge zero, t1, t7 # .. e1 :
+
+ /* Take care of a final (probably partial) result word.
+ On entry to this basic block:
+ t1 == assembled source word
+ t7 == cmpbge mask that found the null. */
+$u_final:
+ negq t7, t6 # e0 : isolate low bit set
+ and t6, t7, t8 # e1 :
+
+ and t8, 0x80, t6 # e0 : avoid dest word load if we can
+ bne t6, 1f # .. e1 (zdb)
+
+ ldq_u t0, 0(a0) # e0 :
+ subq t8, 1, t6 # .. e1 :
+ or t6, t8, t7 # e0 :
+ zapnot t1, t6, t1 # .. e1 : kill source bytes >= null
+ zap t0, t7, t0 # e0 : kill dest bytes <= null
+ or t0, t1, t1 # e1 :
+
+1: stq_u t1, 0(a0) # e0 :
+ ret (t9) # .. e1 :
+
+ /* Unaligned copy entry point. */
+ .align 3
+$unaligned:
+
+ ldq_u t1, 0(a1) # e0 : load first source word
+
+ and a0, 7, t4 # .. e1 : find dest misalignment
+ and a1, 7, t5 # e0 : find src misalignment
+
+ /* Conditionally load the first destination word and a bytemask
+ with 0xff indicating that the destination byte is sacrosanct. */
+
+ mov zero, t0 # .. e1 :
+ mov zero, t6 # e0 :
+ beq t4, 1f # .. e1 :
+ ldq_u t0, 0(a0) # e0 :
+ lda t6, -1 # .. e1 :
+ mskql t6, a0, t6 # e0 :
+1:
+ subq a1, t4, a1 # .. e1 : sub dest misalignment from src addr
+
+ /* If source misalignment is larger than dest misalignment, we need
+ extra startup checks to avoid SEGV. */
+
+ cmplt t4, t5, t8 # e0 :
+ beq t8, $u_head # .. e1 (zdb)
+
+ lda t2, -1 # e1 : mask out leading garbage in source
+ mskqh t2, t5, t2 # e0 :
+ nop # e0 :
+ ornot t1, t2, t3 # .. e1 :
+ cmpbge zero, t3, t7 # e0 : is there a zero?
+ beq t7, $u_head # .. e1 (zdb)
+
+ /* At this point we've found a zero in the first partial word of
+ the source. We need to isolate the valid source data and mask
+ it into the original destination data. (Incidentally, we know
+ that we'll need at least one byte of that original dest word.) */
+
+ ldq_u t0, 0(a0) # e0 :
+
+ negq t7, t6 # .. e1 : build bitmask of bytes <= zero
+ and t6, t7, t8 # e0 :
+ and a1, 7, t5 # .. e1 :
+ subq t8, 1, t6 # e0 :
+ or t6, t8, t7 # e1 :
+ srl t8, t5, t8 # e0 : adjust final null return value
+
+ zapnot t2, t7, t2 # .. e1 : prepare source word; mirror changes
+ and t1, t2, t1 # e1 : to source validity mask
+ extql t2, a1, t2 # .. e0 :
+ extql t1, a1, t1 # e0 :
+
+ andnot t0, t2, t0 # .. e1 : zero place for source to reside
+ or t0, t1, t1 # e1 : and put it there
+ stq_u t1, 0(a0) # .. e0 :
+ ret (t9)
+
+ .end __stxcpy
diff --git a/libc/sysdeps/alpha/stxncpy.S b/libc/sysdeps/alpha/stxncpy.S
new file mode 100644
index 000000000..73bcd36e4
--- /dev/null
+++ b/libc/sysdeps/alpha/stxncpy.S
@@ -0,0 +1,363 @@
+/* Copyright (C) 1996, 1997, 2002 Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@tamu.edu)
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copy no more than COUNT bytes of the null-terminated string from
+ SRC to DST.
+
+ This is an internal routine used by strncpy, stpncpy, and strncat.
+ As such, it uses special linkage conventions to make implementation
+ of these public functions more efficient.
+
+ On input:
+ t9 = return address
+ a0 = DST
+ a1 = SRC
+ a2 = COUNT
+
+ Furthermore, COUNT may not be zero.
+
+ On output:
+ t0 = last word written
+ t8 = bitmask (with one bit set) indicating the last byte written
+ t10 = bitmask (with one bit set) indicating the byte position of
+ the end of the range specified by COUNT
+ a0 = unaligned address of the last *word* written
+ a2 = the number of full words left in COUNT
+
+ Furthermore, v0, a3-a5, t11, and t12 are untouched.
+*/
+
+
+/* This is generally scheduled for the EV5, but should still be pretty
+ good for the EV4 too. */
+
+#include <sysdep.h>
+
+ .set noat
+ .set noreorder
+
+ .text
+
+/* There is a problem with either gdb (as of 4.16) or gas (as of 2.7) that
+ doesn't like putting the entry point for a procedure somewhere in the
+ middle of the procedure descriptor. Work around this by putting the
+ aligned copy in its own procedure descriptor */
+
+ .ent stxncpy_aligned
+ .align 3
+stxncpy_aligned:
+ .frame sp, 0, t9, 0
+ .prologue 0
+
+ /* On entry to this basic block:
+ t0 == the first destination word for masking back in
+ t1 == the first source word. */
+
+ /* Create the 1st output word and detect 0's in the 1st input word. */
+ lda t2, -1 # e1 : build a mask against false zero
+ mskqh t2, a1, t2 # e0 : detection in the src word
+ mskqh t1, a1, t3 # e0 :
+ ornot t1, t2, t2 # .. e1 :
+ mskql t0, a1, t0 # e0 : assemble the first output word
+ cmpbge zero, t2, t7 # .. e1 : bits set iff null found
+ or t0, t3, t0 # e0 :
+ beq a2, $a_eoc # .. e1 :
+ bne t7, $a_eos # .. e1 :
+
+ /* On entry to this basic block:
+ t0 == a source word not containing a null. */
+
+$a_loop:
+ stq_u t0, 0(a0) # e0 :
+ addq a0, 8, a0 # .. e1 :
+ ldq_u t0, 0(a1) # e0 :
+ addq a1, 8, a1 # .. e1 :
+ subq a2, 1, a2 # e0 :
+ cmpbge zero, t0, t7 # .. e1 (stall)
+ beq a2, $a_eoc # e1 :
+ beq t7, $a_loop # e1 :
+
+ /* Take care of the final (partial) word store. At this point
+ the end-of-count bit is set in t7 iff it applies.
+
+ On entry to this basic block we have:
+ t0 == the source word containing the null
+ t7 == the cmpbge mask that found it. */
+
+$a_eos:
+ negq t7, t8 # e0 : find low bit set
+ and t7, t8, t8 # e1 (stall)
+
+ /* For the sake of the cache, don't read a destination word
+ if we're not going to need it. */
+ and t8, 0x80, t6 # e0 :
+ bne t6, 1f # .. e1 (zdb)
+
+ /* We're doing a partial word store and so need to combine
+ our source and original destination words. */
+ ldq_u t1, 0(a0) # e0 :
+ subq t8, 1, t6 # .. e1 :
+ or t8, t6, t7 # e0 :
+ unop #
+ zapnot t0, t7, t0 # e0 : clear src bytes > null
+ zap t1, t7, t1 # .. e1 : clear dst bytes <= null
+ or t0, t1, t0 # e1 :
+
+1: stq_u t0, 0(a0) # e0 :
+ ret (t9) # e1 :
+
+ /* Add the end-of-count bit to the eos detection bitmask. */
+$a_eoc:
+ or t10, t7, t7
+ br $a_eos
+
+ .end stxncpy_aligned
+
+ .align 3
+ .ent __stxncpy
+ .globl __stxncpy
+__stxncpy:
+ .frame sp, 0, t9, 0
+ .prologue 0
+
+ /* Are source and destination co-aligned? */
+ xor a0, a1, t1 # e0 :
+ and a0, 7, t0 # .. e1 : find dest misalignment
+ and t1, 7, t1 # e0 :
+ addq a2, t0, a2 # .. e1 : bias count by dest misalignment
+ subq a2, 1, a2 # e0 :
+ and a2, 7, t2 # e1 :
+ srl a2, 3, a2 # e0 : a2 = loop counter = (count - 1)/8
+ addq zero, 1, t10 # .. e1 :
+ sll t10, t2, t10 # e0 : t10 = bitmask of last count byte
+ bne t1, $unaligned # .. e1 :
+
+ /* We are co-aligned; take care of a partial first word. */
+
+ ldq_u t1, 0(a1) # e0 : load first src word
+ addq a1, 8, a1 # .. e1 :
+
+ beq t0, stxncpy_aligned # avoid loading dest word if not needed
+ ldq_u t0, 0(a0) # e0 :
+ br stxncpy_aligned # .. e1 :
+
+
+/* The source and destination are not co-aligned. Align the destination
+ and cope. We have to be very careful about not reading too much and
+ causing a SEGV. */
+
+ .align 3
+$u_head:
+ /* We know just enough now to be able to assemble the first
+ full source word. We can still find a zero at the end of it
+ that prevents us from outputting the whole thing.
+
+ On entry to this basic block:
+ t0 == the first dest word, unmasked
+ t1 == the shifted low bits of the first source word
+ t6 == bytemask that is -1 in dest word bytes */
+
+ ldq_u t2, 8(a1) # e0 : load second src word
+ addq a1, 8, a1 # .. e1 :
+ mskql t0, a0, t0 # e0 : mask trailing garbage in dst
+ extqh t2, a1, t4 # e0 :
+ or t1, t4, t1 # e1 : first aligned src word complete
+ mskqh t1, a0, t1 # e0 : mask leading garbage in src
+ or t0, t1, t0 # e0 : first output word complete
+ or t0, t6, t6 # e1 : mask original data for zero test
+ cmpbge zero, t6, t7 # e0 :
+ beq a2, $u_eocfin # .. e1 :
+ lda t6, -1 # e0 :
+ bne t7, $u_final # .. e1 :
+
+ mskql t6, a1, t6 # e0 : mask out bits already seen
+ nop # .. e1 :
+ stq_u t0, 0(a0) # e0 : store first output word
+ or t6, t2, t2 # .. e1 :
+ cmpbge zero, t2, t7 # e0 : find nulls in second partial
+ addq a0, 8, a0 # .. e1 :
+ subq a2, 1, a2 # e0 :
+ bne t7, $u_late_head_exit # .. e1 :
+
+ /* Finally, we've got all the stupid leading edge cases taken care
+ of and we can set up to enter the main loop. */
+
+ extql t2, a1, t1 # e0 : position hi-bits of lo word
+ beq a2, $u_eoc # .. e1 :
+ ldq_u t2, 8(a1) # e0 : read next high-order source word
+ addq a1, 8, a1 # .. e1 :
+ extqh t2, a1, t0 # e0 : position lo-bits of hi word
+ cmpbge zero, t2, t7 # .. e1 : test new word for eos
+ nop # e0 :
+ bne t7, $u_eos # .. e1 :
+
+ /* Unaligned copy main loop. In order to avoid reading too much,
+ the loop is structured to detect zeros in aligned source words.
+ This has, unfortunately, effectively pulled half of a loop
+ iteration out into the head and half into the tail, but it does
+ prevent nastiness from accumulating in the very thing we want
+ to run as fast as possible.
+
+ On entry to this basic block:
+ t0 == the shifted low-order bits from the current source word
+ t1 == the shifted high-order bits from the previous source word
+ t2 == the unshifted current source word
+
+ We further know that t2 does not contain a null terminator. */
+
+ .align 3
+$u_loop:
+ or t0, t1, t0 # e0 : current dst word now complete
+ subq a2, 1, a2 # .. e1 : decrement word count
+ stq_u t0, 0(a0) # e0 : save the current word
+ addq a0, 8, a0 # .. e1 :
+ extql t2, a1, t1 # e0 : extract high bits for next time
+ beq a2, $u_eoc # .. e1 :
+ ldq_u t2, 8(a1) # e0 : load high word for next time
+ addq a1, 8, a1 # .. e1 :
+ nop # e0 :
+ cmpbge zero, t2, t7 # .. e1 : test new word for eos
+ extqh t2, a1, t0 # e0 : extract low bits for current word
+ beq t7, $u_loop # .. e1 :
+
+ /* We've found a zero somewhere in the source word we just read.
+ If it resides in the lower half, we have one (probably partial)
+ word to write out, and if it resides in the upper half, we
+ have one full and one partial word left to write out.
+
+ On entry to this basic block:
+ t0 == the shifted low-order bits from the current source word
+ t1 == the shifted high-order bits from the previous source word
+ t2 == the unshifted current source word. */
+$u_eos:
+ or t0, t1, t0 # e0 : first (partial) source word complete
+ cmpbge zero, t0, t7 # e0 : is the null in this first bit?
+ bne t7, $u_final # .. e1 (zdb)
+
+ stq_u t0, 0(a0) # e0 : the null was in the high-order bits
+ addq a0, 8, a0 # .. e1 :
+ subq a2, 1, a2 # e0 :
+
+$u_late_head_exit:
+ extql t2, a1, t0 # e0 :
+ cmpbge zero, t0, t7 # e0 :
+ or t7, t10, t6 # e1 :
+ cmoveq a2, t6, t7 # e0 :
+
+ /* Take care of a final (probably partial) result word.
+ On entry to this basic block:
+ t0 == assembled source word
+ t7 == cmpbge mask that found the null. */
+$u_final:
+ negq t7, t6 # e0 : isolate low bit set
+ and t6, t7, t8 # e1 :
+
+ and t8, 0x80, t6 # e0 : avoid dest word load if we can
+ bne t6, 1f # .. e1 (zdb)
+
+ ldq_u t1, 0(a0) # e0 :
+ subq t8, 1, t6 # .. e1 :
+ or t6, t8, t7 # e0 :
+ zapnot t0, t7, t0 # .. e1 : kill source bytes > null
+ zap t1, t7, t1 # e0 : kill dest bytes <= null
+ or t0, t1, t0 # e1 :
+
+1: stq_u t0, 0(a0) # e0 :
+ ret (t9) # .. e1 :
+
+ /* Got to end-of-count before end of string.
+ On entry to this basic block:
+ t1 == the shifted high-order bits from the previous source word */
+$u_eoc:
+ and a1, 7, t6 # e1 :
+ sll t10, t6, t6 # e0 :
+ and t6, 0xff, t6 # e0 :
+ bne t6, 1f # e1 : avoid src word load if we can
+
+ ldq_u t2, 8(a1) # e0 : load final src word
+ nop # .. e1 :
+ extqh t2, a1, t0 # e0 : extract high bits for last word
+ or t1, t0, t1 # e1 :
+
+1: cmpbge zero, t1, t7
+ mov t1, t0
+
+$u_eocfin: # end-of-count, final word
+ or t10, t7, t7
+ br $u_final
+
+ /* Unaligned copy entry point. */
+ .align 3
+$unaligned:
+
+ ldq_u t1, 0(a1) # e0 : load first source word
+
+ and a0, 7, t4 # .. e1 : find dest misalignment
+ and a1, 7, t5 # e0 : find src misalignment
+
+ /* Conditionally load the first destination word and a bytemask
+ with 0xff indicating that the destination byte is sacrosanct. */
+
+ mov zero, t0 # .. e1 :
+ mov zero, t6 # e0 :
+ beq t4, 1f # .. e1 :
+ ldq_u t0, 0(a0) # e0 :
+ lda t6, -1 # .. e1 :
+ mskql t6, a0, t6 # e0 :
+1:
+ subq a1, t4, a1 # .. e1 : sub dest misalignment from src addr
+
+ /* If source misalignment is larger than dest misalignment, we need
+ extra startup checks to avoid SEGV. */
+
+ cmplt t4, t5, t8 # e1 :
+ extql t1, a1, t1 # .. e0 : shift src into place
+ lda t2, -1 # e0 : for creating masks later
+ beq t8, $u_head # e1 :
+
+ mskqh t2, t5, t2 # e0 : begin src byte validity mask
+ cmpbge zero, t1, t7 # .. e1 : is there a zero?
+ extql t2, a1, t2 # e0 :
+ or t7, t10, t5 # .. e1 : test for end-of-count too
+ cmpbge zero, t2, t3 # e0 :
+ cmoveq a2, t5, t7 # .. e1 :
+ andnot t7, t3, t7 # e0 :
+ beq t7, $u_head # .. e1 (zdb)
+
+ /* At this point we've found a zero in the first partial word of
+ the source. We need to isolate the valid source data and mask
+ it into the original destination data. (Incidentally, we know
+ that we'll need at least one byte of that original dest word.) */
+
+ ldq_u t0, 0(a0) # e0 :
+ negq t7, t6 # .. e1 : build bitmask of bytes <= zero
+ mskqh t1, t4, t1 # e0 :
+ and t6, t7, t8 # .. e1 :
+ subq t8, 1, t6 # e0 :
+ or t6, t8, t7 # e1 :
+
+ zapnot t2, t7, t2 # e0 : prepare source word; mirror changes
+ zapnot t1, t7, t1 # .. e1 : to source validity mask
+
+ andnot t0, t2, t0 # e0 : zero place for source to reside
+ or t0, t1, t0 # e1 : and put it there
+ stq_u t0, 0(a0) # e0 :
+ ret (t9) # .. e1 :
+
+ .end __stxncpy
diff --git a/libc/sysdeps/alpha/sub_n.s b/libc/sysdeps/alpha/sub_n.s
new file mode 100644
index 000000000..e0a6d5c6b
--- /dev/null
+++ b/libc/sysdeps/alpha/sub_n.s
@@ -0,0 +1,120 @@
+ # Alpha __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+ # store difference in a third limb vector.
+
+ # Copyright (C) 1995 Free Software Foundation, Inc.
+
+ # This file is part of the GNU MP Library.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published by
+ # the Free Software Foundation; either version 2.1 of the License, or (at your
+ # option) any later version.
+
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+
+ # INPUT PARAMETERS
+ # res_ptr $16
+ # s1_ptr $17
+ # s2_ptr $18
+ # size $19
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __mpn_sub_n
+ .ent __mpn_sub_n
+__mpn_sub_n:
+ .frame $30,0,$26,0
+
+ ldq $3,0($17)
+ ldq $4,0($18)
+
+ subq $19,1,$19
+ and $19,4-1,$2 # number of limbs in first loop
+ bis $31,$31,$0
+ beq $2,.L0 # if multiple of 4 limbs, skip first loop
+
+ subq $19,$2,$19
+
+.Loop0: subq $2,1,$2
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ addq $17,8,$17
+ addq $18,8,$18
+ bis $5,$5,$3
+ bis $6,$6,$4
+ addq $16,8,$16
+ bne $2,.Loop0
+
+.L0: beq $19,.Lend
+
+ .align 3
+.Loop: subq $19,4,$19
+
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ ldq $3,16($17)
+ addq $6,$0,$6
+ ldq $4,16($18)
+ cmpult $6,$0,$1
+ subq $5,$6,$6
+ cmpult $5,$6,$0
+ stq $6,8($16)
+ or $0,$1,$0
+
+ ldq $5,24($17)
+ addq $4,$0,$4
+ ldq $6,24($18)
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,16($16)
+ or $0,$1,$0
+
+ ldq $3,32($17)
+ addq $6,$0,$6
+ ldq $4,32($18)
+ cmpult $6,$0,$1
+ subq $5,$6,$6
+ cmpult $5,$6,$0
+ stq $6,24($16)
+ or $0,$1,$0
+
+ addq $17,32,$17
+ addq $18,32,$18
+ addq $16,32,$16
+ bne $19,.Loop
+
+.Lend: addq $4,$0,$4
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,0($16)
+ or $0,$1,$0
+ ret $31,($26),1
+
+ .end __mpn_sub_n
diff --git a/libc/sysdeps/alpha/submul_1.s b/libc/sysdeps/alpha/submul_1.s
new file mode 100644
index 000000000..5343f67d8
--- /dev/null
+++ b/libc/sysdeps/alpha/submul_1.s
@@ -0,0 +1,92 @@
+ # Alpha 21064 __mpn_submul_1 -- Multiply a limb vector with a limb and
+ # subtract the result from a second limb vector.
+
+ # Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+ # This file is part of the GNU MP Library.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published by
+ # the Free Software Foundation; either version 2.1 of the License, or (at your
+ # option) any later version.
+
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+
+ # INPUT PARAMETERS
+ # res_ptr r16
+ # s1_ptr r17
+ # size r18
+ # s2_limb r19
+
+ # This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5.
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __mpn_submul_1
+ .ent __mpn_submul_1 2
+__mpn_submul_1:
+ .frame $30,0,$26
+
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ umulh $2,$19,$0 # $0 = prod_high
+ beq $18,.Lend1 # jump if size was == 1
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ subq $5,$3,$3
+ cmpult $5,$3,$4
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ beq $18,.Lend2 # jump if size was == 2
+
+ .align 3
+.Loop: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ subq $18,1,$18 # size--
+ umulh $2,$19,$4 # $4 = cy_limb
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ subq $5,$3,$3
+ cmpult $5,$3,$5
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ addq $5,$0,$0 # combine carries
+ bne $18,.Loop
+
+.Lend2: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ umulh $2,$19,$4 # $4 = cy_limb
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ subq $5,$3,$3
+ cmpult $5,$3,$5
+ stq $3,0($16)
+ addq $5,$0,$0 # combine carries
+ addq $4,$0,$0 # cy_limb = prod_high + cy
+ ret $31,($26),1
+.Lend1: subq $5,$3,$3
+ cmpult $5,$3,$5
+ stq $3,0($16)
+ addq $0,$5,$0
+ ret $31,($26),1
+
+ .end __mpn_submul_1
diff --git a/libc/sysdeps/alpha/udiv_qrnnd.S b/libc/sysdeps/alpha/udiv_qrnnd.S
new file mode 100644
index 000000000..d4ca795aa
--- /dev/null
+++ b/libc/sysdeps/alpha/udiv_qrnnd.S
@@ -0,0 +1,161 @@
+ # Alpha 21064 __udiv_qrnnd
+
+ # Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+ # This file is part of the GNU MP Library.
+
+ # The GNU MP Library is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU Lesser General Public License as published by
+ # the Free Software Foundation; either version 2.1 of the License, or (at your
+ # option) any later version.
+
+ # The GNU MP Library is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ # License for more details.
+
+ # You should have received a copy of the GNU Lesser General Public License
+ # along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+#include <sysdep.h>
+
+ .set noreorder
+ .set noat
+
+ .text
+
+LEAF(__udiv_qrnnd, 0)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+#define cnt $2
+#define tmp $3
+#define rem_ptr $16
+#define n1 $17
+#define n0 $18
+#define d $19
+#define qb $20
+
+ ldiq cnt,16
+ blt d,$largedivisor
+
+$loop1: cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ subq cnt,1,cnt
+ bgt cnt,$loop1
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+$largedivisor:
+ and n0,1,$4
+
+ srl n0,1,n0
+ sll n1,63,tmp
+ or tmp,n0,n0
+ srl n1,1,n1
+
+ and d,1,$6
+ srl d,1,$5
+ addq $5,$6,$5
+
+$loop2: cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ subq cnt,1,cnt
+ bgt cnt,$loop2
+
+ addq n1,n1,n1
+ addq $4,n1,n1
+ bne $6,$Odd
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+$Odd:
+ /* q' in n0. r' in n1 */
+ addq n1,n0,n1
+
+ cmpult n1,n0,tmp # tmp := carry from addq
+ subq n1,d,AT
+ addq n0,tmp,n0
+ cmovne tmp,AT,n1
+
+ cmpult n1,d,tmp
+ addq n0,1,AT
+ cmoveq tmp,AT,n0
+ subq n1,d,AT
+ cmoveq tmp,AT,n1
+
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+ .end __udiv_qrnnd
diff --git a/libc/sysdeps/generic/Makefile b/libc/sysdeps/generic/Makefile
new file mode 100644
index 000000000..972d46973
--- /dev/null
+++ b/libc/sysdeps/generic/Makefile
@@ -0,0 +1,30 @@
+# Copyright (C) 1992,93,94,95,96,97,99,2002,2005
+# Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifeq ($(subdir),string)
+CFLAGS-wordcopy.c += -Wno-uninitialized
+endif
+
+ifeq ($(subdir),elf)
+ifeq (yes:yes,$(build-shared):$(unwind-find-fde))
+# This is needed to support g++ v2 and v3.
+sysdep_routines += framestate unwind-pe
+shared-only-routines += framestate unwind-pe
+endif
+endif
diff --git a/libc/sysdeps/generic/_G_config.h b/libc/sysdeps/generic/_G_config.h
new file mode 100644
index 000000000..a152b070c
--- /dev/null
+++ b/libc/sysdeps/generic/_G_config.h
@@ -0,0 +1,95 @@
+/* This file is needed by libio to define various configuration parameters.
+ These are always the same in the GNU C library. */
+
+#ifndef _G_config_h
+#define _G_config_h 1
+
+/* Define types for libio in terms of the standard internal type names. */
+
+#include <bits/types.h>
+#define __need_size_t
+#define __need_wchar_t
+#define __need_wint_t
+#define __need_NULL
+#include <stddef.h>
+#ifndef _WINT_T
+/* Integral type unchanged by default argument promotions that can
+ hold any value corresponding to members of the extended character
+ set, as well as at least one value that does not correspond to any
+ member of the extended character set. */
+# define _WINT_T
+typedef unsigned int wint_t;
+#endif
+#define __need_mbstate_t
+#include <wchar.h>
+#define _G_size_t size_t
+typedef struct
+{
+ __off_t __pos;
+ __mbstate_t __state;
+} _G_fpos_t;
+typedef struct
+{
+ __off64_t __pos;
+ __mbstate_t __state;
+} _G_fpos64_t;
+#define _G_ssize_t __ssize_t
+#define _G_off_t __off_t
+#define _G_off64_t __off_t
+#define _G_pid_t __pid_t
+#define _G_uid_t __uid_t
+#define _G_wchar_t wchar_t
+#define _G_wint_t wint_t
+#define _G_stat64 stat
+#include <gconv.h>
+typedef union
+{
+ struct __gconv_info __cd;
+ struct
+ {
+ struct __gconv_info __cd;
+ struct __gconv_step_data __data;
+ } __combined;
+} _G_iconv_t;
+
+typedef int _G_int16_t __attribute__ ((__mode__ (__HI__)));
+typedef int _G_int32_t __attribute__ ((__mode__ (__SI__)));
+typedef unsigned int _G_uint16_t __attribute__ ((__mode__ (__HI__)));
+typedef unsigned int _G_uint32_t __attribute__ ((__mode__ (__SI__)));
+
+#define _G_HAVE_BOOL 1
+
+
+/* These library features are always available in the GNU C library. */
+#define _G_HAVE_ATEXIT 1
+#define _G_HAVE_SYS_CDEFS 1
+#define _G_HAVE_SYS_WAIT 1
+#define _G_NEED_STDARG_H 1
+#define _G_va_list __gnuc_va_list
+
+#define _G_HAVE_PRINTF_FP 1
+#define _G_HAVE_MMAP 1
+#define _G_HAVE_LONG_DOUBLE_IO 1
+#define _G_HAVE_IO_FILE_OPEN 1
+#define _G_HAVE_IO_GETLINE_INFO 1
+
+#define _G_IO_IO_FILE_VERSION 0x20001
+
+/* This is defined by <bits/stat.h> if `st_blksize' exists. */
+#define _G_HAVE_ST_BLKSIZE defined (_STATBUF_ST_BLKSIZE)
+
+#define _G_BUFSIZ 8192
+
+/* These are the vtbl details for ELF. */
+#define _G_NAMES_HAVE_UNDERSCORE 0
+#define _G_VTABLE_LABEL_PREFIX "_vt."
+#define _G_VTABLE_LABEL_HAS_LENGTH 1
+
+
+#if defined __cplusplus || defined __STDC__
+# define _G_ARGS(ARGLIST) ARGLIST
+#else
+# define _G_ARGS(ARGLIST) ()
+#endif
+
+#endif /* _G_config.h */
diff --git a/libc/sysdeps/generic/a.out.h b/libc/sysdeps/generic/a.out.h
new file mode 100644
index 000000000..2c1376270
--- /dev/null
+++ b/libc/sysdeps/generic/a.out.h
@@ -0,0 +1,339 @@
+#ifndef __A_OUT_GNU_H__
+#define __A_OUT_GNU_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __GNU_EXEC_MACROS__
+
+#ifndef __STRUCT_EXEC_OVERRIDE__
+
+struct exec
+{
+ unsigned long a_info; /* Use macros N_MAGIC, etc for access */
+ unsigned a_text; /* size of text, in bytes */
+ unsigned a_data; /* size of data, in bytes */
+ unsigned a_bss; /* size of uninitialized data area, in bytes */
+ unsigned a_syms; /* length of symbol table data, in bytes */
+ unsigned a_entry; /* start address */
+ unsigned a_trsize; /* size of reloc info for text, in bytes */
+ unsigned a_drsize; /* size of reloc info for data, in bytes */
+
+#if defined (sequent) && defined (i386)
+ struct gdtbl
+ { /* Global Descriptor Table */
+ unsigned g_code[2];
+ unsigned g_data[2];
+ unsigned g_desc[2];
+ } a_gdtbl;
+ unsigned a_shdata; /* size of initialized shared data */
+ unsigned a_shbss; /* size of uninitialized shared data */
+ unsigned a_shdrsize; /* size of shared data relocation */
+ unsigned a_bootstrap[11]; /* bootstrap for standalone */
+ unsigned a_reserved[3]; /* reserved for future use */
+ unsigned a_version; /* object version */
+#endif /* Sequent Symmetry, Dynix 3.x */
+};
+
+#endif /* __STRUCT_EXEC_OVERRIDE__ */
+
+/* these go in the N_MACHTYPE field */
+enum machine_type {
+#if defined (M_OLDSUN2)
+ M__OLDSUN2 = M_OLDSUN2,
+#else
+ M_OLDSUN2 = 0,
+#endif
+#if defined (M_68010)
+ M__68010 = M_68010,
+#else
+ M_68010 = 1,
+#endif
+#if defined (M_68020)
+ M__68020 = M_68020,
+#else
+ M_68020 = 2,
+#endif
+#if defined (M_SPARC)
+ M__SPARC = M_SPARC,
+#else
+ M_SPARC = 3,
+#endif
+ /* skip a bunch so we don't run into any of sun's numbers */
+ M_386 = 100
+};
+
+#if defined (sequent) && defined (i386)
+
+/* Dynix 3 wants the magic number to be the whole first longword. */
+
+#define N_MAGIC(exec) ((exec).a_info)
+#define N_MACHTYPE(exec) 0
+#define N_FLAGS(exec) 0
+#define N_SET_INFO(exec, magic, type, flags) N_SET_MAGIC ((exec), (magic))
+#define N_SET_MAGIC(exec, magic) ((exec).a_info = (magic))
+#define N_SET_MACHTYPE(exec, machtype) ((void) 0)
+#define N_SET_FLAGS(exec, flags) ((void) 0)
+#define OMAGIC 0x12eb /* impure format - for .o's */
+#define ZMAGIC 0x22eb /* demand load format - zero at zero */
+#define NMAGIC you lose /* syntax error -- no pure format */
+#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != ZMAGIC)
+#define N_ADDRADJ(x) (N_MAGIC(x) == ZMAGIC ? SEGMENT_SIZE : 0)
+#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text - N_ADDRADJ(x))
+#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data + (x).a_shdata)
+#define N_SYMOFF(x) (N_DRELOFF(x) + (x).a_drsize + (x).a_shdrsize)
+#define N_TXTADDR(x) SEGMENT_SIZE
+#define N_COMM 0x0a /** conflicts with N_INDR **/
+#define N_FN 0x0c
+/* Note that the Dynix binutils believe that N_SET[TDB] are
+ N_SH{DATA,BSS,COMM} -- be wary when mixing GNU & Dynix objects. */
+#define PAGE_SIZE 4096
+#define SEGMENT_SIZE PAGE_SIZE
+
+#else /* !(sequent && i386) */
+
+#if !defined (N_MAGIC)
+#define N_MAGIC(exec) ((exec).a_info & 0xffff)
+#endif
+#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
+#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
+#define N_SET_INFO(exec, magic, type, flags) \
+ ((exec).a_info = ((magic) & 0xffff) \
+ | (((int)(type) & 0xff) << 16) \
+ | (((flags) & 0xff) << 24))
+#define N_SET_MAGIC(exec, magic) \
+ ((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
+
+#define N_SET_MACHTYPE(exec, machtype) \
+ ((exec).a_info = \
+ ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
+
+#define N_SET_FLAGS(exec, flags) \
+ ((exec).a_info = \
+ ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
+
+#endif /* sequent && i386 */
+
+#ifndef OMAGIC
+/* Code indicating object file or impure executable. */
+#define OMAGIC 0407
+/* Code indicating pure executable. */
+#define NMAGIC 0410
+/* Code indicating demand-paged executable. */
+#define ZMAGIC 0413
+#endif /* not OMAGIC */
+
+#if !defined (N_BADMAG)
+#define N_BADMAG(x) \
+ (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC)
+#endif
+
+#define _N_BADMAG(x) \
+ (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC)
+
+#ifndef sparc
+#define _N_HDROFF(x) (SEGMENT_SIZE - sizeof (struct exec))
+#else
+#define _N_HDROFF(x) (- sizeof (struct exec))
+#endif
+
+#if !defined (N_TXTOFF)
+#define N_TXTOFF(x) \
+ (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : sizeof (struct exec))
+#endif
+
+#if !defined (N_DATOFF)
+#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
+#endif
+
+#if !defined (N_TRELOFF)
+#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
+#endif
+
+#if !defined (N_DRELOFF)
+#define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize)
+#endif
+
+#if !defined (N_SYMOFF)
+#define N_SYMOFF(x) (N_DRELOFF(x) + (x).a_drsize)
+#endif
+
+#if !defined (N_STROFF)
+#define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms)
+#endif
+
+/* Address of text segment in memory after it is loaded. */
+#if !defined (N_TXTADDR)
+#define N_TXTADDR(x) 0
+#endif
+
+/* Address of data segment in memory after it is loaded.
+ Note that it is up to you to define SEGMENT_SIZE
+ on machines not listed here. */
+#if defined (hp300) || defined (mips)
+#define PAGE_SIZE 4096
+#endif
+#if defined (sparc) || defined (NeXT)
+#define PAGE_SIZE 0x2000
+#endif
+#if defined (sony) || (defined (sun) && defined (mc68000))
+#define SEGMENT_SIZE 0x2000
+#endif /* Sony or 68k Sun. */
+#ifdef is68k
+#define SEGMENT_SIZE 0x20000
+#endif
+#if defined(m68k) && defined(PORTAR)
+#define PAGE_SIZE 0x400
+#endif
+#if defined(i386) && !defined(sequent)
+/* For COFF encapsulation. */
+#define SEGMENT_SIZE 0x400000
+#endif
+#ifndef SEGMENT_SIZE
+/* This used to be first in this paragraph and under:
+ if (defined(vax) || defined(hp300) || defined(pyr) || defined(sparc) \
+ || (defined(m68k) && defined(PORTAR)) \
+ || defined (NeXT) || defined (mips)) */
+#define SEGMENT_SIZE PAGE_SIZE
+#endif
+#ifndef PAGE_SIZE
+/* This value is for i386-minix, but that has no predefine.
+ Making it default will only cause confusion on machines
+ which have no proper value defined. */
+#define PAGE_SIZE 16
+#endif
+
+#define PAGSIZ PAGE_SIZE
+#define SEGSIZ SEGMENT_SIZE
+
+#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1))
+
+#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
+
+#ifndef N_DATADDR
+#define N_DATADDR(x) \
+ (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
+ : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
+#endif
+
+/* Address of bss segment in memory after it is loaded. */
+#if !defined (N_BSSADDR)
+#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
+#endif
+
+#if !defined (N_NLIST_DECLARED)
+struct nlist {
+ union {
+ char *n_name;
+ struct nlist *n_next;
+ long n_strx;
+ } n_un;
+ unsigned char n_type;
+ char n_other;
+ short n_desc;
+ unsigned long n_value;
+};
+#endif /* no N_NLIST_DECLARED. */
+
+#if !defined (N_UNDF)
+#define N_UNDF 0
+#endif
+#if !defined (N_ABS)
+#define N_ABS 2
+#endif
+#if !defined (N_TEXT)
+#define N_TEXT 4
+#endif
+#if !defined (N_DATA)
+#define N_DATA 6
+#endif
+#if !defined (N_BSS)
+#define N_BSS 8
+#endif
+#if !defined (N_COMM)
+#define N_COMM 18
+#endif
+#if !defined (N_FN)
+#define N_FN 15
+#endif
+
+#if !defined (N_EXT)
+#define N_EXT 1
+#endif
+#if !defined (N_TYPE)
+#define N_TYPE 036
+#endif
+#if !defined (N_STAB)
+#define N_STAB 0340
+#endif
+
+/* The following type indicates the definition of a symbol as being
+ an indirect reference to another symbol. The other symbol
+ appears as an undefined reference, immediately following this symbol.
+
+ Indirection is asymmetrical. The other symbol's value will be used
+ to satisfy requests for the indirect symbol, but not vice versa.
+ If the other symbol does not have a definition, libraries will
+ be searched to find a definition. */
+#define N_INDR 0xa
+
+/* The following symbols refer to set elements.
+ All the N_SET[ATDB] symbols with the same name form one set.
+ Space is allocated for the set in the text section, and each set
+ element's value is stored into one word of the space.
+ The first word of the space is the length of the set (number of elements).
+
+ The address of the set is made into an N_SETV symbol
+ whose name is the same as the name of the set.
+ This symbol acts like a N_DATA global symbol
+ in that it can satisfy undefined external references. */
+
+/* These appear as input to LD, in a .o file. */
+#define N_SETA 0x14 /* Absolute set element symbol */
+#define N_SETT 0x16 /* Text set element symbol */
+#define N_SETD 0x18 /* Data set element symbol */
+#define N_SETB 0x1A /* Bss set element symbol */
+
+/* This is output from LD. */
+#define N_SETV 0x1C /* Pointer to set vector in data area. */
+
+#if !defined (N_RELOCATION_INFO_DECLARED)
+/* This structure describes a single relocation to be performed.
+ The text-relocation section of the file is a vector of these structures,
+ all of which apply to the text section.
+ Likewise, the data-relocation section applies to the data section. */
+
+struct relocation_info
+{
+ /* Address (within segment) to be relocated. */
+ int r_address;
+ /* The meaning of r_symbolnum depends on r_extern. */
+ unsigned int r_symbolnum:24;
+ /* Nonzero means value is a pc-relative offset
+ and it should be relocated for changes in its own address
+ as well as for changes in the symbol or section specified. */
+ unsigned int r_pcrel:1;
+ /* Length (as exponent of 2) of the field to be relocated.
+ Thus, a value of 2 indicates 1<<2 bytes. */
+ unsigned int r_length:2;
+ /* 1 => relocate with value of symbol.
+ r_symbolnum is the index of the symbol
+ in file's the symbol table.
+ 0 => relocate with the address of a segment.
+ r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
+ (the N_EXT bit may be set also, but signifies nothing). */
+ unsigned int r_extern:1;
+ /* Four bits that aren't used, but when writing an object file
+ it is desirable to clear them. */
+ unsigned int r_pad:4;
+};
+#endif /* no N_RELOCATION_INFO_DECLARED. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __A_OUT_GNU_H__ */
diff --git a/libc/sysdeps/generic/abort-instr.h b/libc/sysdeps/generic/abort-instr.h
new file mode 100644
index 000000000..106a330b2
--- /dev/null
+++ b/libc/sysdeps/generic/abort-instr.h
@@ -0,0 +1,2 @@
+/* We cannot give any generic instruction to crash the program.
+ abort() will have to make sure it never returns. */
diff --git a/libc/sysdeps/generic/aio_misc.h b/libc/sysdeps/generic/aio_misc.h
new file mode 100644
index 000000000..d5c753210
--- /dev/null
+++ b/libc/sysdeps/generic/aio_misc.h
@@ -0,0 +1,48 @@
+/* Internal declarations for <aio.h> functions implementation. Stub version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _AIO_MISC_H
+#define _AIO_MISC_H 1
+
+#include <aio.h>
+
+
+/* Extend the operation enum. */
+enum
+{
+ LIO_DSYNC = LIO_READ + 1,
+ LIO_SYNC,
+ LIO_READ64 = LIO_READ | 128,
+ LIO_WRITE64 = LIO_WRITE | 128
+};
+
+/* Union of the two request types. */
+typedef union
+ {
+ struct aiocb aiocb;
+ struct aiocb64 aiocb64;
+ } aiocb_union;
+
+
+/* Send the signal. */
+extern int __aio_sigqueue (int sig, const union sigval val, pid_t caller_pid)
+ internal_function;
+
+
+#endif /* aio_misc.h */
diff --git a/libc/sysdeps/generic/allocalim.h b/libc/sysdeps/generic/allocalim.h
new file mode 100644
index 000000000..2491129a7
--- /dev/null
+++ b/libc/sysdeps/generic/allocalim.h
@@ -0,0 +1,4 @@
+extern inline int __libc_use_alloca (size_t size)
+{
+ return size <= __MAX_ALLOCA_CUTOFF;
+}
diff --git a/libc/sysdeps/generic/asm-syntax.h b/libc/sysdeps/generic/asm-syntax.h
new file mode 100644
index 000000000..a36150984
--- /dev/null
+++ b/libc/sysdeps/generic/asm-syntax.h
@@ -0,0 +1,3 @@
+/* On some machines the mpn function from GNU MP use a file called
+ "asm-syntax.h" to define macros for assembly source code to use. */
+
diff --git a/libc/sysdeps/generic/bp-checks.h b/libc/sysdeps/generic/bp-checks.h
new file mode 100644
index 000000000..efbb84716
--- /dev/null
+++ b/libc/sysdeps/generic/bp-checks.h
@@ -0,0 +1,129 @@
+/* Bounded-pointer checking macros for C.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Greg McGary <greg@mcgary.org>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _bp_checks_h_
+#define _bp_checks_h_ 1
+
+#if __BOUNDED_POINTERS__
+
+# define BOUNDS_VIOLATED (__builtin_trap (), 0)
+
+/* Verify that pointer's value >= low. Return pointer value. */
+# define CHECK_BOUNDS_LOW(ARG) \
+ (((__ptrvalue (ARG) < __ptrlow (ARG)) && BOUNDS_VIOLATED), \
+ __ptrvalue (ARG))
+
+/* Verify that pointer's value < high. Return pointer value. */
+# define CHECK_BOUNDS_HIGH(ARG) \
+ (((__ptrvalue (ARG) > __ptrhigh (ARG)) && BOUNDS_VIOLATED), \
+ __ptrvalue (ARG))
+
+# define _CHECK_N(ARG, N, COND) \
+ (((COND) \
+ && (__ptrvalue (ARG) < __ptrlow (ARG) \
+ || __ptrvalue (ARG) + (N) > __ptrhigh (ARG)) \
+ && BOUNDS_VIOLATED), \
+ __ptrvalue (ARG))
+
+extern void *__unbounded __ubp_memchr (const void *__unbounded, int, unsigned);
+
+# define _CHECK_STRING(ARG, COND) \
+ (((COND) \
+ && (__ptrvalue (ARG) < __ptrlow (ARG) \
+ || !__ubp_memchr (__ptrvalue (ARG), '\0', \
+ (__ptrhigh (ARG) - __ptrvalue (ARG)))) \
+ && BOUNDS_VIOLATED), \
+ __ptrvalue (ARG))
+
+/* Check bounds of a pointer seated to an array of N objects. */
+# define CHECK_N(ARG, N) _CHECK_N ((ARG), (N), 1)
+/* Same as CHECK_N, but tolerate ARG == NULL. */
+# define CHECK_N_NULL_OK(ARG, N) _CHECK_N ((ARG), (N), __ptrvalue (ARG))
+
+/* Check bounds of a pointer seated to a single object. */
+# define CHECK_1(ARG) CHECK_N ((ARG), 1)
+/* Same as CHECK_1, but tolerate ARG == NULL. */
+# define CHECK_1_NULL_OK(ARG) CHECK_N_NULL_OK ((ARG), 1)
+
+/* Check for NUL-terminator within string's bounds. */
+# define CHECK_STRING(ARG) _CHECK_STRING ((ARG), 1)
+/* Same as CHECK_STRING, but tolerate ARG == NULL. */
+# define CHECK_STRING_NULL_OK(ARG) _CHECK_STRING ((ARG), __ptrvalue (ARG))
+
+/* Check bounds of signal syscall args with type sigset_t. */
+# define CHECK_SIGSET(SET) CHECK_N ((SET), _NSIG / (8 * sizeof *(SET)))
+/* Same as CHECK_SIGSET, but tolerate SET == NULL. */
+# define CHECK_SIGSET_NULL_OK(SET) CHECK_N_NULL_OK ((SET), _NSIG / (8 * sizeof *(SET)))
+
+# if defined (_IOC_SIZESHIFT) && defined (_IOC_SIZEBITS)
+/* Extract the size of the ioctl data and check its bounds. */
+# define CHECK_IOCTL(ARG, CMD) \
+ CHECK_N ((const char *) (ARG), \
+ (((CMD) >> _IOC_SIZESHIFT) & ((1 << _IOC_SIZEBITS) - 1)))
+# else
+/* We don't know the size of the ioctl data, so the best we can do
+ is check that the first byte is within bounds. */
+# define CHECK_IOCTL(ARG, CMD) CHECK_1 ((const char *) ARG)
+# endif
+
+/* Check bounds of `struct flock *' for the locking fcntl commands. */
+# define CHECK_FCNTL(ARG, CMD) \
+ (((CMD) == F_GETLK || (CMD) == F_SETLK || (CMD) == F_SETLKW) \
+ ? CHECK_1 ((struct flock *) ARG) : (unsigned long) (ARG))
+
+/* Check bounds of an array of mincore residency-status flags that
+ cover a region of NBYTES. Such a vector occupies one byte per page
+ of memory. */
+# define CHECK_N_PAGES(ARG, NBYTES) \
+ ({ int _page_size_ = sysconf (_SC_PAGE_SIZE); \
+ CHECK_N ((const char *) (ARG), \
+ ((NBYTES) + _page_size_ - 1) / _page_size_); })
+
+/* Return a bounded pointer with value PTR that satisfies CHECK_N (PTR, N). */
+# define BOUNDED_N(PTR, N) \
+ ({ __typeof (PTR) __bounded _p_; \
+ __ptrvalue _p_ = __ptrlow _p_ = __ptrvalue (PTR); \
+ __ptrhigh _p_ = __ptrvalue _p_ + (N); \
+ _p_; })
+
+#else /* !__BOUNDED_POINTERS__ */
+
+/* Do nothing if not compiling with -fbounded-pointers. */
+
+# define BOUNDS_VIOLATED
+# define CHECK_BOUNDS_LOW(ARG) (ARG)
+# define CHECK_BOUNDS_HIGH(ARG) (ARG)
+# define CHECK_1(ARG) (ARG)
+# define CHECK_1_NULL_OK(ARG) (ARG)
+# define CHECK_N(ARG, N) (ARG)
+# define CHECK_N_NULL_OK(ARG, N) (ARG)
+# define CHECK_STRING(ARG) (ARG)
+# define CHECK_SIGSET(SET) (SET)
+# define CHECK_SIGSET_NULL_OK(SET) (SET)
+# define CHECK_IOCTL(ARG, CMD) (ARG)
+# define CHECK_FCNTL(ARG, CMD) (ARG)
+# define CHECK_N_PAGES(ARG, NBYTES) (ARG)
+# define BOUNDED_N(PTR, N) (PTR)
+
+#endif /* !__BOUNDED_POINTERS__ */
+
+#define BOUNDED_1(PTR) BOUNDED_N (PTR, 1)
+
+#endif /* _bp_checks_h_ */
diff --git a/libc/sysdeps/generic/bp-semctl.h b/libc/sysdeps/generic/bp-semctl.h
new file mode 100644
index 000000000..d33ed2b35
--- /dev/null
+++ b/libc/sysdeps/generic/bp-semctl.h
@@ -0,0 +1,67 @@
+/* Bounded-pointer checking macros for C.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Greg McGary <greg@mcgary.org>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _bp_semctl_h_
+#define _bp_semctl_h_ 1
+
+#if __BOUNDED_POINTERS__
+
+# define CHECK_SEMCTL(ARGP, SEMID, CMD) check_semctl (ARGP, SEMID, CMD)
+
+union semun *__unbounded
+check_semctl (union semun *arg, int semid, int cmd)
+{
+ int ipc64 = (cmd & __IPC_64);
+
+ switch (cmd & ~__IPC_64)
+ {
+ case IPC_STAT:
+ case IPC_SET:
+ (void) CHECK_1 (arg->buf);
+ break;
+
+ case GETALL:
+ case SETALL:
+ {
+ struct semid_ds ds;
+ union semun un = { .buf = &ds };
+ unsigned int length = ~0;
+
+ /* It's unfortunate that we need to make a recursive
+ system call to get the size of the semaphore set... */
+ if (semctl (semid, 0, IPC_STAT | ipc64, un) == 0)
+ length = ds.sem_nsems;
+ (void) CHECK_N (arg->array, length);
+ break;
+ }
+
+ case IPC_INFO:
+ (void) CHECK_1 (arg->__buf);
+ break;
+ }
+
+ return __ptrvalue (arg);
+}
+
+#else
+# define CHECK_SEMCTL(ARGP, SEMID, CMD) (ARGP)
+#endif
+
+#endif /* _bp_semctl_h_ */
diff --git a/libc/sysdeps/generic/bp-start.h b/libc/sysdeps/generic/bp-start.h
new file mode 100644
index 000000000..02765a577
--- /dev/null
+++ b/libc/sysdeps/generic/bp-start.h
@@ -0,0 +1,72 @@
+/* Bounded-pointer checking macros for C.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Greg McGary <greg@mcgary.org>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#if __BOUNDED_POINTERS__
+
+ /* The command-line arg vector and environment vector come to us from
+ the OS as an unbounded pointer to an array of unbounded strings.
+ The user's main expects argv and __environ to be bounded pointers
+ to arrays of bounded strings. */
+# define INIT_ARGV_and_ENVIRON \
+ do { \
+ int envc; \
+ for (envc = 0; *ubp_ev; ubp_ev++, envc++) \
+ ; \
+ ubp_ev -= envc; \
+ \
+ /* GKM FIXME: we could save some space by allocating only enough for \
+ the additional low & high words, and destructively rewriting \
+ argv in place. */ \
+ __ptrvalue (argv) = __ptrlow (argv) \
+ = alloca ((argc + envc + 2) * sizeof (*argv)); \
+ __ptrhigh (argv) = __ptrvalue (argv) + argc + 1; \
+ __ptrvalue (__environ) = __ptrlow (__environ) = __ptrhigh (argv); \
+ __ptrhigh (__environ) = __ptrvalue (__environ) + envc + 1; \
+ boundify_vector (__environ, ubp_ev); \
+ boundify_vector (argv, ubp_av); \
+ } while (0)
+
+
+/* Copy an unbounded vector of unbounded strings into a bounded
+ counterpart. */
+
+static void
+boundify_vector (char **dest, char *__unbounded *__unbounded src)
+{
+ char *__unbounded s;
+ for (; *src; src++, dest++)
+ {
+ __ptrvalue (*dest) = __ptrlow (*dest) = *src;
+ __ptrhigh (*dest) = src[1];
+ }
+ *dest = 0;
+ /* The OS lays out strings contiguously in vector order,
+ so */
+ for (s = __ptrvalue (dest[-1]); *s; s++)
+ ;
+ __ptrhigh (dest[-1]) = ++s;
+}
+
+#else
+
+# define INIT_ARGV_and_ENVIRON __environ = ubp_ev
+
+#endif
diff --git a/libc/sysdeps/generic/bp-sym.h b/libc/sysdeps/generic/bp-sym.h
new file mode 100644
index 000000000..1aeb2364e
--- /dev/null
+++ b/libc/sysdeps/generic/bp-sym.h
@@ -0,0 +1,26 @@
+/* Bounded-pointer symbol modifier.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Greg McGary <greg@mcgary.org>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define BP_SYM(name) _BP_SYM (name)
+#if __BOUNDED_POINTERS__
+# define _BP_SYM(name) __BP_##name
+#else
+# define _BP_SYM(name) name
+#endif
diff --git a/libc/sysdeps/generic/bp-thunks.h b/libc/sysdeps/generic/bp-thunks.h
new file mode 100644
index 000000000..85f398fee
--- /dev/null
+++ b/libc/sysdeps/generic/bp-thunks.h
@@ -0,0 +1,70 @@
+/* Bounded-pointer syscall thunk support.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Greg McGary <greg@mcgary.org>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _bpthunks_h_
+#define _bpthunks_h_
+
+#ifndef __ASSEMBLER__
+
+/* This header is included by the syscall BP thunks defined in
+ sysd-syscalls, as created by sysdeps/unix/make-syscalls.sh. It
+ includes all headers that contain prototype declarations for system
+ call functions. */
+
+#include <libc-symbols.h>
+#include <bp-sym.h>
+#include <bp-checks.h>
+
+/* Get `struct timeval' definition for select. */
+#define __need_timeval
+#include <bits/time.h>
+
+#include <stddef.h>
+#include <unistd.h>
+#include <sched.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <time.h>
+#include <utime.h>
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/klog.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/quota.h>
+#include <sys/resource.h>
+#include <sys/select.h>
+#include <io/sys/sendfile.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/swap.h>
+#include <sys/sysinfo.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/timex.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
+
+#endif /* Not __ASSEMBLER__. */
+
+#endif /* _bpthunks_h_ */
diff --git a/libc/sysdeps/generic/confstr.h b/libc/sysdeps/generic/confstr.h
new file mode 100644
index 000000000..988ec88c0
--- /dev/null
+++ b/libc/sysdeps/generic/confstr.h
@@ -0,0 +1,4 @@
+/* This file should define values for the strings returned by `confstr'.
+ If _NAME is passed to `confstr', define NAME. */
+
+#define CS_PATH ""
diff --git a/libc/sysdeps/generic/device-nrs.h b/libc/sysdeps/generic/device-nrs.h
new file mode 100644
index 000000000..d9a13e509
--- /dev/null
+++ b/libc/sysdeps/generic/device-nrs.h
@@ -0,0 +1,28 @@
+/* Device numbers of devices used in the implementation. Generic version.
+ Copyright (C) 2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DEVICE_NRS_H
+#define _DEVICE_NRS_H 1
+
+/* By default we know no device numbers. */
+
+/* We cannot check whether a given device is a tty. */
+#define DEV_TTY_P(statp) (0)
+
+#endif /* device-nrs.h */
diff --git a/libc/sysdeps/generic/dirstream.h b/libc/sysdeps/generic/dirstream.h
new file mode 100644
index 000000000..9f80b5b01
--- /dev/null
+++ b/libc/sysdeps/generic/dirstream.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DIRSTREAM_H
+
+#define _DIRSTREAM_H 1
+
+
+/* This file should define a type `struct __dirstream', the data type of
+ directory stream objects returned by `opendir'. */
+
+#error "No system-dependent definition of `struct __dirstream'."
+
+
+#endif /* dirstream.h */
diff --git a/libc/sysdeps/generic/dl-cache.h b/libc/sysdeps/generic/dl-cache.h
new file mode 100644
index 000000000..c2b72874c
--- /dev/null
+++ b/libc/sysdeps/generic/dl-cache.h
@@ -0,0 +1,105 @@
+/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
+ Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+
+#ifndef _DL_CACHE_DEFAULT_ID
+# define _DL_CACHE_DEFAULT_ID 3
+#endif
+
+#ifndef _dl_cache_check_flags
+# define _dl_cache_check_flags(flags) \
+ ((flags) == 1 || (flags) == _DL_CACHE_DEFAULT_ID)
+#endif
+
+#ifndef LD_SO_CACHE
+# define LD_SO_CACHE SYSCONFDIR "/ld.so.cache"
+#endif
+
+#ifndef add_system_dir
+# define add_system_dir(dir) add_dir (dir)
+#endif
+
+#define CACHEMAGIC "ld.so-1.7.0"
+
+/* libc5 and glibc 2.0/2.1 use the same format. For glibc 2.2 another
+ format has been added in a compatible way:
+ The beginning of the string table is used for the new table:
+ old_magic
+ nlibs
+ libs[0]
+ ...
+ libs[nlibs-1]
+ pad, new magic needs to be aligned
+ - this is string[0] for the old format
+ new magic - this is string[0] for the new format
+ newnlibs
+ ...
+ newlibs[0]
+ ...
+ newlibs[newnlibs-1]
+ string 1
+ string 2
+ ...
+*/
+struct file_entry
+{
+ int flags; /* This is 1 for an ELF library. */
+ unsigned int key, value; /* String table indices. */
+};
+
+struct cache_file
+{
+ char magic[sizeof CACHEMAGIC - 1];
+ unsigned int nlibs;
+ struct file_entry libs[0];
+};
+
+#define CACHEMAGIC_NEW "glibc-ld.so.cache"
+#define CACHE_VERSION "1.1"
+#define CACHEMAGIC_VERSION_NEW CACHEMAGIC_NEW CACHE_VERSION
+
+
+struct file_entry_new
+{
+ int32_t flags; /* This is 1 for an ELF library. */
+ uint32_t key, value; /* String table indices. */
+ uint32_t osversion; /* Required OS version. */
+ uint64_t hwcap; /* Hwcap entry. */
+};
+
+struct cache_file_new
+{
+ char magic[sizeof CACHEMAGIC_NEW - 1];
+ char version[sizeof CACHE_VERSION - 1];
+ uint32_t nlibs; /* Number of entries. */
+ uint32_t len_strings; /* Size of string table. */
+ uint32_t unused[5]; /* Leave space for future extensions
+ and align to 8 byte boundary. */
+ struct file_entry_new libs[0]; /* Entries describing libraries. */
+ /* After this the string table of size len_strings is found. */
+};
+
+/* Used to align cache_file_new. */
+#define ALIGN_CACHE(addr) \
+(((addr) + __alignof__ (struct cache_file_new) -1) \
+ & (~(__alignof__ (struct cache_file_new) - 1)))
+
+extern int _dl_cache_libcmp (const char *p1, const char *p2)
+ internal_function;
diff --git a/libc/sysdeps/generic/dl-dtprocnum.h b/libc/sysdeps/generic/dl-dtprocnum.h
new file mode 100644
index 000000000..41eb8d089
--- /dev/null
+++ b/libc/sysdeps/generic/dl-dtprocnum.h
@@ -0,0 +1,22 @@
+/* Configuration of lookup functions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Number of extra dynamic section entries for this architecture. By
+ default there are none. */
+#define DT_THISPROCNUM 0
diff --git a/libc/sysdeps/generic/dl-fptr.h b/libc/sysdeps/generic/dl-fptr.h
new file mode 100644
index 000000000..d47fb7b63
--- /dev/null
+++ b/libc/sysdeps/generic/dl-fptr.h
@@ -0,0 +1,46 @@
+/* Function descriptors. Generic version.
+ Copyright (C) 1995, 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef dl_fptr_h
+#define dl_fptr_h 1
+
+/* An FDESC is a function descriptor. */
+
+struct fdesc
+ {
+ ElfW(Addr) ip; /* code entry point */
+ ElfW(Addr) gp; /* global pointer */
+ };
+
+struct fdesc_table
+ {
+ struct fdesc_table *next;
+ unsigned int len; /* # of entries in fdesc table */
+ volatile unsigned int first_unused; /* index of first available entry */
+ struct fdesc fdesc[0];
+ };
+
+struct link_map;
+
+extern ElfW(Addr) _dl_boot_fptr_table [];
+
+extern ElfW(Addr) _dl_make_fptr (struct link_map *, const ElfW(Sym) *,
+ ElfW(Addr));
+
+#endif /* !dl_fptr_h */
diff --git a/libc/sysdeps/generic/dl-hash.h b/libc/sysdeps/generic/dl-hash.h
new file mode 100644
index 000000000..243ae14b5
--- /dev/null
+++ b/libc/sysdeps/generic/dl-hash.h
@@ -0,0 +1,75 @@
+/* Compute hash value for given string according to ELF standard.
+ Copyright (C) 1995,1996,1997,1998,2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DL_HASH_H
+#define _DL_HASH_H 1
+
+
+/* This is the hashing function specified by the ELF ABI. In the
+ first five operations no overflow is possible so we optimized it a
+ bit. */
+static unsigned int
+_dl_elf_hash (const char *name_arg)
+{
+ const unsigned char *name = (const unsigned char *) name_arg;
+ unsigned long int hash = 0;
+ if (*name != '\0')
+ {
+ hash = *name++;
+ if (*name != '\0')
+ {
+ hash = (hash << 4) + *name++;
+ if (*name != '\0')
+ {
+ hash = (hash << 4) + *name++;
+ if (*name != '\0')
+ {
+ hash = (hash << 4) + *name++;
+ if (*name != '\0')
+ {
+ hash = (hash << 4) + *name++;
+ while (*name != '\0')
+ {
+ unsigned long int hi;
+ hash = (hash << 4) + *name++;
+ hi = hash & 0xf0000000;
+
+ /* The algorithm specified in the ELF ABI is as
+ follows:
+
+ if (hi != 0)
+ hash ^= hi >> 24;
+
+ hash &= ~hi;
+
+ But the following is equivalent and a lot
+ faster, especially on modern processors. */
+
+ hash ^= hi;
+ hash ^= hi >> 24;
+ }
+ }
+ }
+ }
+ }
+ }
+ return hash;
+}
+
+#endif /* dl-hash.h */
diff --git a/libc/sysdeps/generic/dl-librecon.h b/libc/sysdeps/generic/dl-librecon.h
new file mode 100644
index 000000000..bd821a39b
--- /dev/null
+++ b/libc/sysdeps/generic/dl-librecon.h
@@ -0,0 +1,26 @@
+/* Optional code to distinguish library flavours.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DL_LIBRECON_H
+#define _DL_LIBRECON_H 1
+
+/* In the general case we don't do anything. */
+
+#endif /* dl-librecon.h */
diff --git a/libc/sysdeps/generic/dl-lookupcfg.h b/libc/sysdeps/generic/dl-lookupcfg.h
new file mode 100644
index 000000000..2b2998960
--- /dev/null
+++ b/libc/sysdeps/generic/dl-lookupcfg.h
@@ -0,0 +1,29 @@
+/* Configuration of lookup functions.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The type of the return value of fixup/profile_fixup. */
+#define DL_FIXUP_VALUE_TYPE ElfW(Addr)
+/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address
+ and a link map. */
+#define DL_FIXUP_MAKE_VALUE(map, addr) (addr)
+/* Extract the code address from a value of type DL_FIXUP_MAKE_VALUE.
+ */
+#define DL_FIXUP_VALUE_CODE_ADDR(value) (value)
+#define DL_FIXUP_VALUE_ADDR(value) (value)
+#define DL_FIXUP_ADDR_VALUE(addr) (addr)
diff --git a/libc/sysdeps/generic/dl-machine.h b/libc/sysdeps/generic/dl-machine.h
new file mode 100644
index 000000000..c3459f5e3
--- /dev/null
+++ b/libc/sysdeps/generic/dl-machine.h
@@ -0,0 +1,135 @@
+/* Machine-dependent ELF dynamic relocation inline functions. Stub version.
+ Copyright (C) 1995, 1996, 1997, 1999, 2000, 2001, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define ELF_MACHINE_NAME "stub"
+
+#include <string.h>
+#include <link.h>
+
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int
+elf_machine_matches_host (const Elf32_Ehdr *ehdr)
+{
+ switch (ehdr->e_machine)
+ {
+ default:
+ return 0;
+ }
+}
+
+
+/* Return the link-time address of _DYNAMIC. */
+static inline Elf32_Addr
+elf_machine_dynamic (void)
+{
+#error "Damn, no _DYNAMIC"
+}
+
+
+/* Return the run-time load address of the shared object. */
+static inline Elf32_Addr
+elf_machine_load_address (void)
+{
+#error "Where am I?"
+}
+
+/* Fixup a PLT entry to bounce directly to the function at VALUE. */
+
+static inline Elf32_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf32_Rel *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+ return *reloc_addr = value;
+}
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ LOADADDR is the load address of the object; INFO is an array indexed
+ by DT_* of the .dynamic section info. */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
+ const Elf32_Rel *reloc, const Elf32_Sym *sym,
+ Elf32_Addr (*resolve) (const Elf32_Sym **ref,
+ Elf32_Addr reloc_addr,
+ int noplt))
+{
+ Elf32_Addr *const reloc_addr = (Elf32_Addr *) reloc->r_offset;
+ Elf32_Addr loadbase;
+
+ switch (ELF32_R_TYPE (reloc->r_info))
+ {
+ case R_MACHINE_COPY:
+ loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
+ memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size);
+ break;
+ default:
+ _dl_reloc_bad_type (map, ELF32_R_TYPE (reloc->r_info), 0);
+ break;
+ }
+}
+
+
+auto inline Elf32_Addr
+__attribute__ ((always_inline))
+elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
+ const Elf32_Rel *reloc, const Elf32_Sym *sym,
+ Elf32_Addr (*resolve) (const Elf32_Sym **ref,
+ Elf32_Addr reloc_addr,
+ int noplt))
+{
+ _dl_signal_error (0, "Elf32_Rela relocation requested -- unused on "
+ NULL, ELF_MACHINE_NAME);
+}
+
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int
+elf_machine_runtime_setup (struct link_map *l, int lazy)
+{
+ extern void _dl_runtime_resolve (Elf32_Word);
+
+ if (lazy)
+ {
+ /* The GOT entries for functions in the PLT have not yet been filled
+ in. Their initial contents will arrange when called to push an
+ offset into the .rel.plt section, push _GLOBAL_OFFSET_TABLE_[1],
+ and then jump to _GLOBAL_OFFSET_TABLE[2]. */
+ Elf32_Addr *got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
+ got[1] = (Elf32_Addr) l; /* Identify this shared object. */
+
+ /* This function will get called to fix up the GOT entry indicated by
+ the offset on the stack, and then jump to the resolved address. */
+ got[2] = (Elf32_Addr) &_dl_runtime_resolve;
+ }
+
+ return lazy;
+}
+
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+
+#define RTLD_START #error need some startup code
diff --git a/libc/sysdeps/generic/dl-osinfo.h b/libc/sysdeps/generic/dl-osinfo.h
new file mode 100644
index 000000000..60b84a900
--- /dev/null
+++ b/libc/sysdeps/generic/dl-osinfo.h
@@ -0,0 +1,12 @@
+#include <stdint.h>
+
+static inline uintptr_t __attribute__ ((always_inline))
+_dl_setup_stack_chk_guard (void)
+{
+ uintptr_t ret = 0;
+ unsigned char *p = (unsigned char *) &ret;
+ p[sizeof (ret) - 1] = 255;
+ p[sizeof (ret) - 2] = '\n';
+ p[0] = 0;
+ return ret;
+}
diff --git a/libc/sysdeps/generic/dl-procinfo.c b/libc/sysdeps/generic/dl-procinfo.c
new file mode 100644
index 000000000..a05618469
--- /dev/null
+++ b/libc/sysdeps/generic/dl-procinfo.c
@@ -0,0 +1 @@
+/* No architecture specific definitions. */
diff --git a/libc/sysdeps/generic/dl-procinfo.h b/libc/sysdeps/generic/dl-procinfo.h
new file mode 100644
index 000000000..3f8103522
--- /dev/null
+++ b/libc/sysdeps/generic/dl-procinfo.h
@@ -0,0 +1,46 @@
+/* Stub version of processor capability information handling macros.
+ Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DL_PROCINFO_H
+#define _DL_PROCINFO_H 1
+
+/* We cannot provide a general printing function. */
+#define _dl_procinfo(word) -1
+
+/* There are no hardware capabilities defined. */
+#define _dl_hwcap_string(idx) ""
+
+/* There are no different platforms defined. */
+#define _dl_platform_string(idx) ""
+
+/* By default there is no important hardware capability. */
+#define HWCAP_IMPORTANT (0)
+
+/* There're no platforms to filter out. */
+#define _DL_HWCAP_PLATFORM 0
+
+/* We don't have any hardware capabilities. */
+#define _DL_HWCAP_COUNT 0
+
+#define _dl_string_hwcap(str) (-1)
+
+#define _dl_string_platform(str) (-1)
+
+#endif /* dl-procinfo.h */
diff --git a/libc/sysdeps/generic/dl-sysdep.h b/libc/sysdeps/generic/dl-sysdep.h
new file mode 100644
index 000000000..c99fd3ea3
--- /dev/null
+++ b/libc/sysdeps/generic/dl-sysdep.h
@@ -0,0 +1,35 @@
+/* System-specific settings for dynamic linker code. Generic version.
+ Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* No multiple inclusion protection need here because it's just macros.
+ We don't want to use _DL_SYSDEP_H in case we are #include_next'd. */
+
+/* This macro must be defined to either 0 or 1.
+
+ If 1, then an errno global variable hidden in ld.so will work right with
+ all the errno-using libc code compiled for ld.so, and there is never a
+ need to share the errno location with libc. This is appropriate only if
+ all the libc functions that ld.so uses are called without PLT and always
+ get the versions linked into ld.so rather than the libc ones. */
+
+#ifdef IS_IN_rtld
+# define RTLD_PRIVATE_ERRNO 1
+#else
+# define RTLD_PRIVATE_ERRNO 0
+#endif
diff --git a/libc/sysdeps/generic/dl-tls.h b/libc/sysdeps/generic/dl-tls.h
new file mode 100644
index 000000000..7703a9752
--- /dev/null
+++ b/libc/sysdeps/generic/dl-tls.h
@@ -0,0 +1,2 @@
+/* There has to be an architecture specific version of this file. */
+#error "architecture-specific version of <dl-tls.h> missing"
diff --git a/libc/sysdeps/generic/dwarf2.h b/libc/sysdeps/generic/dwarf2.h
new file mode 100644
index 000000000..9fca4c00e
--- /dev/null
+++ b/libc/sysdeps/generic/dwarf2.h
@@ -0,0 +1,585 @@
+/* Declarations and definitions of codes relating to the DWARF2 symbolic
+ debugging information format.
+ Copyright (C) 1992, 1993, 1995, 1996, 1997, 2000
+ Free Software Foundation, Inc.
+ Contributed by Gary Funck (gary@intrepid.com). Derived from the
+ DWARF 1 implementation written by Ron Guilmette (rfg@monkeys.com).
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file is derived from the DWARF specification (a public document)
+ Revision 2.0.0 (July 27, 1993) developed by the UNIX International
+ Programming Languages Special Interest Group (UI/PLSIG) and distributed
+ by UNIX International. Copies of this specification are available from
+ UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054. */
+
+/* This file is shared between GCC and GDB, and should not contain
+ prototypes. */
+
+/* Tag names and codes. */
+
+enum dwarf_tag
+ {
+ DW_TAG_padding = 0x00,
+ DW_TAG_array_type = 0x01,
+ DW_TAG_class_type = 0x02,
+ DW_TAG_entry_point = 0x03,
+ DW_TAG_enumeration_type = 0x04,
+ DW_TAG_formal_parameter = 0x05,
+ DW_TAG_imported_declaration = 0x08,
+ DW_TAG_label = 0x0a,
+ DW_TAG_lexical_block = 0x0b,
+ DW_TAG_member = 0x0d,
+ DW_TAG_pointer_type = 0x0f,
+ DW_TAG_reference_type = 0x10,
+ DW_TAG_compile_unit = 0x11,
+ DW_TAG_string_type = 0x12,
+ DW_TAG_structure_type = 0x13,
+ DW_TAG_subroutine_type = 0x15,
+ DW_TAG_typedef = 0x16,
+ DW_TAG_union_type = 0x17,
+ DW_TAG_unspecified_parameters = 0x18,
+ DW_TAG_variant = 0x19,
+ DW_TAG_common_block = 0x1a,
+ DW_TAG_common_inclusion = 0x1b,
+ DW_TAG_inheritance = 0x1c,
+ DW_TAG_inlined_subroutine = 0x1d,
+ DW_TAG_module = 0x1e,
+ DW_TAG_ptr_to_member_type = 0x1f,
+ DW_TAG_set_type = 0x20,
+ DW_TAG_subrange_type = 0x21,
+ DW_TAG_with_stmt = 0x22,
+ DW_TAG_access_declaration = 0x23,
+ DW_TAG_base_type = 0x24,
+ DW_TAG_catch_block = 0x25,
+ DW_TAG_const_type = 0x26,
+ DW_TAG_constant = 0x27,
+ DW_TAG_enumerator = 0x28,
+ DW_TAG_file_type = 0x29,
+ DW_TAG_friend = 0x2a,
+ DW_TAG_namelist = 0x2b,
+ DW_TAG_namelist_item = 0x2c,
+ DW_TAG_packed_type = 0x2d,
+ DW_TAG_subprogram = 0x2e,
+ DW_TAG_template_type_param = 0x2f,
+ DW_TAG_template_value_param = 0x30,
+ DW_TAG_thrown_type = 0x31,
+ DW_TAG_try_block = 0x32,
+ DW_TAG_variant_part = 0x33,
+ DW_TAG_variable = 0x34,
+ DW_TAG_volatile_type = 0x35,
+ /* SGI/MIPS Extensions */
+ DW_TAG_MIPS_loop = 0x4081,
+ /* GNU extensions */
+ DW_TAG_format_label = 0x4101, /* for FORTRAN 77 and Fortran 90 */
+ DW_TAG_function_template = 0x4102, /* for C++ */
+ DW_TAG_class_template = 0x4103, /* for C++ */
+ DW_TAG_GNU_BINCL = 0x4104,
+ DW_TAG_GNU_EINCL = 0x4105
+ };
+
+#define DW_TAG_lo_user 0x4080
+#define DW_TAG_hi_user 0xffff
+
+/* flag that tells whether entry has a child or not */
+#define DW_children_no 0
+#define DW_children_yes 1
+
+/* Form names and codes. */
+enum dwarf_form
+ {
+ DW_FORM_addr = 0x01,
+ DW_FORM_block2 = 0x03,
+ DW_FORM_block4 = 0x04,
+ DW_FORM_data2 = 0x05,
+ DW_FORM_data4 = 0x06,
+ DW_FORM_data8 = 0x07,
+ DW_FORM_string = 0x08,
+ DW_FORM_block = 0x09,
+ DW_FORM_block1 = 0x0a,
+ DW_FORM_data1 = 0x0b,
+ DW_FORM_flag = 0x0c,
+ DW_FORM_sdata = 0x0d,
+ DW_FORM_strp = 0x0e,
+ DW_FORM_udata = 0x0f,
+ DW_FORM_ref_addr = 0x10,
+ DW_FORM_ref1 = 0x11,
+ DW_FORM_ref2 = 0x12,
+ DW_FORM_ref4 = 0x13,
+ DW_FORM_ref8 = 0x14,
+ DW_FORM_ref_udata = 0x15,
+ DW_FORM_indirect = 0x16
+ };
+
+/* Attribute names and codes. */
+
+enum dwarf_attribute
+ {
+ DW_AT_sibling = 0x01,
+ DW_AT_location = 0x02,
+ DW_AT_name = 0x03,
+ DW_AT_ordering = 0x09,
+ DW_AT_subscr_data = 0x0a,
+ DW_AT_byte_size = 0x0b,
+ DW_AT_bit_offset = 0x0c,
+ DW_AT_bit_size = 0x0d,
+ DW_AT_element_list = 0x0f,
+ DW_AT_stmt_list = 0x10,
+ DW_AT_low_pc = 0x11,
+ DW_AT_high_pc = 0x12,
+ DW_AT_language = 0x13,
+ DW_AT_member = 0x14,
+ DW_AT_discr = 0x15,
+ DW_AT_discr_value = 0x16,
+ DW_AT_visibility = 0x17,
+ DW_AT_import = 0x18,
+ DW_AT_string_length = 0x19,
+ DW_AT_common_reference = 0x1a,
+ DW_AT_comp_dir = 0x1b,
+ DW_AT_const_value = 0x1c,
+ DW_AT_containing_type = 0x1d,
+ DW_AT_default_value = 0x1e,
+ DW_AT_inline = 0x20,
+ DW_AT_is_optional = 0x21,
+ DW_AT_lower_bound = 0x22,
+ DW_AT_producer = 0x25,
+ DW_AT_prototyped = 0x27,
+ DW_AT_return_addr = 0x2a,
+ DW_AT_start_scope = 0x2c,
+ DW_AT_stride_size = 0x2e,
+ DW_AT_upper_bound = 0x2f,
+ DW_AT_abstract_origin = 0x31,
+ DW_AT_accessibility = 0x32,
+ DW_AT_address_class = 0x33,
+ DW_AT_artificial = 0x34,
+ DW_AT_base_types = 0x35,
+ DW_AT_calling_convention = 0x36,
+ DW_AT_count = 0x37,
+ DW_AT_data_member_location = 0x38,
+ DW_AT_decl_column = 0x39,
+ DW_AT_decl_file = 0x3a,
+ DW_AT_decl_line = 0x3b,
+ DW_AT_declaration = 0x3c,
+ DW_AT_discr_list = 0x3d,
+ DW_AT_encoding = 0x3e,
+ DW_AT_external = 0x3f,
+ DW_AT_frame_base = 0x40,
+ DW_AT_friend = 0x41,
+ DW_AT_identifier_case = 0x42,
+ DW_AT_macro_info = 0x43,
+ DW_AT_namelist_items = 0x44,
+ DW_AT_priority = 0x45,
+ DW_AT_segment = 0x46,
+ DW_AT_specification = 0x47,
+ DW_AT_static_link = 0x48,
+ DW_AT_type = 0x49,
+ DW_AT_use_location = 0x4a,
+ DW_AT_variable_parameter = 0x4b,
+ DW_AT_virtuality = 0x4c,
+ DW_AT_vtable_elem_location = 0x4d,
+ /* SGI/MIPS Extensions */
+ DW_AT_MIPS_fde = 0x2001,
+ DW_AT_MIPS_loop_begin = 0x2002,
+ DW_AT_MIPS_tail_loop_begin = 0x2003,
+ DW_AT_MIPS_epilog_begin = 0x2004,
+ DW_AT_MIPS_loop_unroll_factor = 0x2005,
+ DW_AT_MIPS_software_pipeline_depth = 0x2006,
+ DW_AT_MIPS_linkage_name = 0x2007,
+ DW_AT_MIPS_stride = 0x2008,
+ DW_AT_MIPS_abstract_name = 0x2009,
+ DW_AT_MIPS_clone_origin = 0x200a,
+ DW_AT_MIPS_has_inlines = 0x200b,
+ /* GNU extensions. */
+ DW_AT_sf_names = 0x2101,
+ DW_AT_src_info = 0x2102,
+ DW_AT_mac_info = 0x2103,
+ DW_AT_src_coords = 0x2104,
+ DW_AT_body_begin = 0x2105,
+ DW_AT_body_end = 0x2106
+ };
+
+#define DW_AT_lo_user 0x2000 /* implementation-defined range start */
+#define DW_AT_hi_user 0x3ff0 /* implementation-defined range end */
+
+/* Location atom names and codes. */
+
+enum dwarf_location_atom
+ {
+ DW_OP_addr = 0x03,
+ DW_OP_deref = 0x06,
+ DW_OP_const1u = 0x08,
+ DW_OP_const1s = 0x09,
+ DW_OP_const2u = 0x0a,
+ DW_OP_const2s = 0x0b,
+ DW_OP_const4u = 0x0c,
+ DW_OP_const4s = 0x0d,
+ DW_OP_const8u = 0x0e,
+ DW_OP_const8s = 0x0f,
+ DW_OP_constu = 0x10,
+ DW_OP_consts = 0x11,
+ DW_OP_dup = 0x12,
+ DW_OP_drop = 0x13,
+ DW_OP_over = 0x14,
+ DW_OP_pick = 0x15,
+ DW_OP_swap = 0x16,
+ DW_OP_rot = 0x17,
+ DW_OP_xderef = 0x18,
+ DW_OP_abs = 0x19,
+ DW_OP_and = 0x1a,
+ DW_OP_div = 0x1b,
+ DW_OP_minus = 0x1c,
+ DW_OP_mod = 0x1d,
+ DW_OP_mul = 0x1e,
+ DW_OP_neg = 0x1f,
+ DW_OP_not = 0x20,
+ DW_OP_or = 0x21,
+ DW_OP_plus = 0x22,
+ DW_OP_plus_uconst = 0x23,
+ DW_OP_shl = 0x24,
+ DW_OP_shr = 0x25,
+ DW_OP_shra = 0x26,
+ DW_OP_xor = 0x27,
+ DW_OP_bra = 0x28,
+ DW_OP_eq = 0x29,
+ DW_OP_ge = 0x2a,
+ DW_OP_gt = 0x2b,
+ DW_OP_le = 0x2c,
+ DW_OP_lt = 0x2d,
+ DW_OP_ne = 0x2e,
+ DW_OP_skip = 0x2f,
+ DW_OP_lit0 = 0x30,
+ DW_OP_lit1 = 0x31,
+ DW_OP_lit2 = 0x32,
+ DW_OP_lit3 = 0x33,
+ DW_OP_lit4 = 0x34,
+ DW_OP_lit5 = 0x35,
+ DW_OP_lit6 = 0x36,
+ DW_OP_lit7 = 0x37,
+ DW_OP_lit8 = 0x38,
+ DW_OP_lit9 = 0x39,
+ DW_OP_lit10 = 0x3a,
+ DW_OP_lit11 = 0x3b,
+ DW_OP_lit12 = 0x3c,
+ DW_OP_lit13 = 0x3d,
+ DW_OP_lit14 = 0x3e,
+ DW_OP_lit15 = 0x3f,
+ DW_OP_lit16 = 0x40,
+ DW_OP_lit17 = 0x41,
+ DW_OP_lit18 = 0x42,
+ DW_OP_lit19 = 0x43,
+ DW_OP_lit20 = 0x44,
+ DW_OP_lit21 = 0x45,
+ DW_OP_lit22 = 0x46,
+ DW_OP_lit23 = 0x47,
+ DW_OP_lit24 = 0x48,
+ DW_OP_lit25 = 0x49,
+ DW_OP_lit26 = 0x4a,
+ DW_OP_lit27 = 0x4b,
+ DW_OP_lit28 = 0x4c,
+ DW_OP_lit29 = 0x4d,
+ DW_OP_lit30 = 0x4e,
+ DW_OP_lit31 = 0x4f,
+ DW_OP_reg0 = 0x50,
+ DW_OP_reg1 = 0x51,
+ DW_OP_reg2 = 0x52,
+ DW_OP_reg3 = 0x53,
+ DW_OP_reg4 = 0x54,
+ DW_OP_reg5 = 0x55,
+ DW_OP_reg6 = 0x56,
+ DW_OP_reg7 = 0x57,
+ DW_OP_reg8 = 0x58,
+ DW_OP_reg9 = 0x59,
+ DW_OP_reg10 = 0x5a,
+ DW_OP_reg11 = 0x5b,
+ DW_OP_reg12 = 0x5c,
+ DW_OP_reg13 = 0x5d,
+ DW_OP_reg14 = 0x5e,
+ DW_OP_reg15 = 0x5f,
+ DW_OP_reg16 = 0x60,
+ DW_OP_reg17 = 0x61,
+ DW_OP_reg18 = 0x62,
+ DW_OP_reg19 = 0x63,
+ DW_OP_reg20 = 0x64,
+ DW_OP_reg21 = 0x65,
+ DW_OP_reg22 = 0x66,
+ DW_OP_reg23 = 0x67,
+ DW_OP_reg24 = 0x68,
+ DW_OP_reg25 = 0x69,
+ DW_OP_reg26 = 0x6a,
+ DW_OP_reg27 = 0x6b,
+ DW_OP_reg28 = 0x6c,
+ DW_OP_reg29 = 0x6d,
+ DW_OP_reg30 = 0x6e,
+ DW_OP_reg31 = 0x6f,
+ DW_OP_breg0 = 0x70,
+ DW_OP_breg1 = 0x71,
+ DW_OP_breg2 = 0x72,
+ DW_OP_breg3 = 0x73,
+ DW_OP_breg4 = 0x74,
+ DW_OP_breg5 = 0x75,
+ DW_OP_breg6 = 0x76,
+ DW_OP_breg7 = 0x77,
+ DW_OP_breg8 = 0x78,
+ DW_OP_breg9 = 0x79,
+ DW_OP_breg10 = 0x7a,
+ DW_OP_breg11 = 0x7b,
+ DW_OP_breg12 = 0x7c,
+ DW_OP_breg13 = 0x7d,
+ DW_OP_breg14 = 0x7e,
+ DW_OP_breg15 = 0x7f,
+ DW_OP_breg16 = 0x80,
+ DW_OP_breg17 = 0x81,
+ DW_OP_breg18 = 0x82,
+ DW_OP_breg19 = 0x83,
+ DW_OP_breg20 = 0x84,
+ DW_OP_breg21 = 0x85,
+ DW_OP_breg22 = 0x86,
+ DW_OP_breg23 = 0x87,
+ DW_OP_breg24 = 0x88,
+ DW_OP_breg25 = 0x89,
+ DW_OP_breg26 = 0x8a,
+ DW_OP_breg27 = 0x8b,
+ DW_OP_breg28 = 0x8c,
+ DW_OP_breg29 = 0x8d,
+ DW_OP_breg30 = 0x8e,
+ DW_OP_breg31 = 0x8f,
+ DW_OP_regx = 0x90,
+ DW_OP_fbreg = 0x91,
+ DW_OP_bregx = 0x92,
+ DW_OP_piece = 0x93,
+ DW_OP_deref_size = 0x94,
+ DW_OP_xderef_size = 0x95,
+ DW_OP_nop = 0x96
+ };
+
+#define DW_OP_lo_user 0x80 /* implementation-defined range start */
+#define DW_OP_hi_user 0xff /* implementation-defined range end */
+
+/* Type encodings. */
+
+enum dwarf_type
+ {
+ DW_ATE_void = 0x0,
+ DW_ATE_address = 0x1,
+ DW_ATE_boolean = 0x2,
+ DW_ATE_complex_float = 0x3,
+ DW_ATE_float = 0x4,
+ DW_ATE_signed = 0x5,
+ DW_ATE_signed_char = 0x6,
+ DW_ATE_unsigned = 0x7,
+ DW_ATE_unsigned_char = 0x8
+ };
+
+#define DW_ATE_lo_user 0x80
+#define DW_ATE_hi_user 0xff
+
+/* Array ordering names and codes. */
+enum dwarf_array_dim_ordering
+ {
+ DW_ORD_row_major = 0,
+ DW_ORD_col_major = 1
+ };
+
+/* access attribute */
+enum dwarf_access_attribute
+ {
+ DW_ACCESS_public = 1,
+ DW_ACCESS_protected = 2,
+ DW_ACCESS_private = 3
+ };
+
+/* visibility */
+enum dwarf_visibility_attribute
+ {
+ DW_VIS_local = 1,
+ DW_VIS_exported = 2,
+ DW_VIS_qualified = 3
+ };
+
+/* virtuality */
+enum dwarf_virtuality_attribute
+ {
+ DW_VIRTUALITY_none = 0,
+ DW_VIRTUALITY_virtual = 1,
+ DW_VIRTUALITY_pure_virtual = 2
+ };
+
+/* case sensitivity */
+enum dwarf_id_case
+ {
+ DW_ID_case_sensitive = 0,
+ DW_ID_up_case = 1,
+ DW_ID_down_case = 2,
+ DW_ID_case_insensitive = 3
+ };
+
+/* calling convention */
+enum dwarf_calling_convention
+ {
+ DW_CC_normal = 0x1,
+ DW_CC_program = 0x2,
+ DW_CC_nocall = 0x3
+ };
+
+#define DW_CC_lo_user 0x40
+#define DW_CC_hi_user 0xff
+
+/* inline attribute */
+enum dwarf_inline_attribute
+ {
+ DW_INL_not_inlined = 0,
+ DW_INL_inlined = 1,
+ DW_INL_declared_not_inlined = 2,
+ DW_INL_declared_inlined = 3
+ };
+
+/* discriminant lists */
+enum dwarf_discrim_list
+ {
+ DW_DSC_label = 0,
+ DW_DSC_range = 1
+ };
+
+/* line number opcodes */
+enum dwarf_line_number_ops
+ {
+ DW_LNS_extended_op = 0,
+ DW_LNS_copy = 1,
+ DW_LNS_advance_pc = 2,
+ DW_LNS_advance_line = 3,
+ DW_LNS_set_file = 4,
+ DW_LNS_set_column = 5,
+ DW_LNS_negate_stmt = 6,
+ DW_LNS_set_basic_block = 7,
+ DW_LNS_const_add_pc = 8,
+ DW_LNS_fixed_advance_pc = 9
+ };
+
+/* line number extended opcodes */
+enum dwarf_line_number_x_ops
+ {
+ DW_LNE_end_sequence = 1,
+ DW_LNE_set_address = 2,
+ DW_LNE_define_file = 3
+ };
+
+/* call frame information */
+enum dwarf_call_frame_info
+ {
+ DW_CFA_advance_loc = 0x40,
+ DW_CFA_offset = 0x80,
+ DW_CFA_restore = 0xc0,
+ DW_CFA_nop = 0x00,
+ DW_CFA_set_loc = 0x01,
+ DW_CFA_advance_loc1 = 0x02,
+ DW_CFA_advance_loc2 = 0x03,
+ DW_CFA_advance_loc4 = 0x04,
+ DW_CFA_offset_extended = 0x05,
+ DW_CFA_restore_extended = 0x06,
+ DW_CFA_undefined = 0x07,
+ DW_CFA_same_value = 0x08,
+ DW_CFA_register = 0x09,
+ DW_CFA_remember_state = 0x0a,
+ DW_CFA_restore_state = 0x0b,
+ DW_CFA_def_cfa = 0x0c,
+ DW_CFA_def_cfa_register = 0x0d,
+ DW_CFA_def_cfa_offset = 0x0e,
+ DW_CFA_def_cfa_expression = 0x0f,
+ DW_CFA_expression = 0x10,
+ /* Dwarf 2.1 */
+ DW_CFA_offset_extended_sf = 0x11,
+ DW_CFA_def_cfa_sf = 0x12,
+ DW_CFA_def_cfa_offset_sf = 0x13,
+
+ /* SGI/MIPS specific */
+ DW_CFA_MIPS_advance_loc8 = 0x1d,
+
+ /* GNU extensions */
+ DW_CFA_GNU_window_save = 0x2d,
+ DW_CFA_GNU_args_size = 0x2e,
+ DW_CFA_GNU_negative_offset_extended = 0x2f
+ };
+
+#define DW_CIE_ID 0xffffffff
+#define DW_CIE_VERSION 1
+
+#define DW_CFA_extended 0
+#define DW_CFA_low_user 0x1c
+#define DW_CFA_high_user 0x3f
+
+#define DW_CHILDREN_no 0x00
+#define DW_CHILDREN_yes 0x01
+
+#define DW_ADDR_none 0
+
+/* Source language names and codes. */
+
+enum dwarf_source_language
+ {
+ DW_LANG_C89 = 0x0001,
+ DW_LANG_C = 0x0002,
+ DW_LANG_Ada83 = 0x0003,
+ DW_LANG_C_plus_plus = 0x0004,
+ DW_LANG_Cobol74 = 0x0005,
+ DW_LANG_Cobol85 = 0x0006,
+ DW_LANG_Fortran77 = 0x0007,
+ DW_LANG_Fortran90 = 0x0008,
+ DW_LANG_Pascal83 = 0x0009,
+ DW_LANG_Modula2 = 0x000a,
+ DW_LANG_Java = 0x000b,
+ DW_LANG_Mips_Assembler = 0x8001
+ };
+
+
+#define DW_LANG_lo_user 0x8000 /* implementation-defined range start */
+#define DW_LANG_hi_user 0xffff /* implementation-defined range start */
+
+/* Names and codes for macro information. */
+
+enum dwarf_macinfo_record_type
+ {
+ DW_MACINFO_define = 1,
+ DW_MACINFO_undef = 2,
+ DW_MACINFO_start_file = 3,
+ DW_MACINFO_end_file = 4,
+ DW_MACINFO_vendor_ext = 255
+ };
+
+
+/* @@@ For use with GNU frame unwind information. */
+
+#define DW_EH_PE_absptr 0x00
+#define DW_EH_PE_omit 0xff
+
+#define DW_EH_PE_uleb128 0x01
+#define DW_EH_PE_udata2 0x02
+#define DW_EH_PE_udata4 0x03
+#define DW_EH_PE_udata8 0x04
+#define DW_EH_PE_sleb128 0x09
+#define DW_EH_PE_sdata2 0x0A
+#define DW_EH_PE_sdata4 0x0B
+#define DW_EH_PE_sdata8 0x0C
+#define DW_EH_PE_signed 0x08
+
+#define DW_EH_PE_pcrel 0x10
+#define DW_EH_PE_textrel 0x20
+#define DW_EH_PE_datarel 0x30
+#define DW_EH_PE_funcrel 0x40
+#define DW_EH_PE_aligned 0x50
+
+#define DW_EH_PE_indirect 0x80
diff --git a/libc/sysdeps/generic/elf/backtracesyms.c b/libc/sysdeps/generic/elf/backtracesyms.c
new file mode 100644
index 000000000..b31be6ac5
--- /dev/null
+++ b/libc/sysdeps/generic/elf/backtracesyms.c
@@ -0,0 +1,102 @@
+/* Return list with names for address in backtrace.
+ Copyright (C) 1998,1999,2000,2001,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <execinfo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ldsodefs.h>
+
+#if __ELF_NATIVE_CLASS == 32
+# define WORD_WIDTH 8
+#else
+/* We assyme 64bits. */
+# define WORD_WIDTH 16
+#endif
+
+
+char **
+__backtrace_symbols (array, size)
+ void *const *array;
+ int size;
+{
+ Dl_info info[size];
+ int status[size];
+ int cnt;
+ size_t total = 0;
+ char **result;
+
+ /* Fill in the information we can get from `dladdr'. */
+ for (cnt = 0; cnt < size; ++cnt)
+ {
+ status[cnt] = _dl_addr (array[cnt], &info[cnt], NULL, NULL);
+ if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0')
+ /* We have some info, compute the length of the string which will be
+ "<file-name>(<sym-name>) [+offset]. */
+ total += (strlen (info[cnt].dli_fname ?: "")
+ + (info[cnt].dli_sname
+ ? strlen (info[cnt].dli_sname) + 3 + WORD_WIDTH + 3
+ : 1)
+ + WORD_WIDTH + 5);
+ else
+ total += 5 + WORD_WIDTH;
+ }
+
+ /* Allocate memory for the result. */
+ result = (char **) malloc (size * sizeof (char *) + total);
+ if (result != NULL)
+ {
+ char *last = (char *) (result + size);
+
+ for (cnt = 0; cnt < size; ++cnt)
+ {
+ result[cnt] = last;
+
+ if (status[cnt] && info[cnt].dli_fname
+ && info[cnt].dli_fname[0] != '\0')
+ {
+ char buf[20];
+
+ if (array[cnt] >= (void *) info[cnt].dli_saddr)
+ sprintf (buf, "+%#lx",
+ (unsigned long)(array[cnt] - info[cnt].dli_saddr));
+ else
+ sprintf (buf, "-%#lx",
+ (unsigned long)(info[cnt].dli_saddr - array[cnt]));
+
+ last += 1 + sprintf (last, "%s%s%s%s%s[%p]",
+ info[cnt].dli_fname ?: "",
+ info[cnt].dli_sname ? "(" : "",
+ info[cnt].dli_sname ?: "",
+ info[cnt].dli_sname ? buf : "",
+ info[cnt].dli_sname ? ") " : " ",
+ array[cnt]);
+ }
+ else
+ last += 1 + sprintf (last, "[%p]", array[cnt]);
+ }
+ assert (last <= (char *) result + size * sizeof (char *) + total);
+ }
+
+ return result;
+}
+weak_alias (__backtrace_symbols, backtrace_symbols)
diff --git a/libc/sysdeps/generic/elf/backtracesymsfd.c b/libc/sysdeps/generic/elf/backtracesymsfd.c
new file mode 100644
index 000000000..6754d145b
--- /dev/null
+++ b/libc/sysdeps/generic/elf/backtracesymsfd.c
@@ -0,0 +1,110 @@
+/* Write formatted list with names for addresses in backtrace to a file.
+ Copyright (C) 1998, 2000, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <execinfo.h>
+#include <string.h>
+#include <sys/uio.h>
+
+#include <stdio-common/_itoa.h>
+#include <ldsodefs.h>
+
+#if __ELF_NATIVE_CLASS == 32
+# define WORD_WIDTH 8
+#else
+/* We assyme 64bits. */
+# define WORD_WIDTH 16
+#endif
+
+
+void
+__backtrace_symbols_fd (array, size, fd)
+ void *const *array;
+ int size;
+ int fd;
+{
+ struct iovec iov[9];
+ int cnt;
+
+ for (cnt = 0; cnt < size; ++cnt)
+ {
+ char buf[WORD_WIDTH];
+ Dl_info info;
+ size_t last = 0;
+
+ if (_dl_addr (array[cnt], &info, NULL, NULL)
+ && info.dli_fname && info.dli_fname[0] != '\0')
+ {
+ /* Name of the file. */
+ iov[0].iov_base = (void *) info.dli_fname;
+ iov[0].iov_len = strlen (info.dli_fname);
+ last = 1;
+
+ /* Symbol name. */
+ if (info.dli_sname != NULL)
+ {
+ char buf2[WORD_WIDTH];
+ size_t diff;
+
+ iov[1].iov_base = (void *) "(";
+ iov[1].iov_len = 1;
+ iov[2].iov_base = (void *) info.dli_sname;
+ iov[2].iov_len = strlen (info.dli_sname);
+
+ if (array[cnt] >= (void *) info.dli_saddr)
+ {
+ iov[3].iov_base = (void *) "+0x";
+ diff = array[cnt] - info.dli_saddr;
+ }
+ else
+ {
+ iov[3].iov_base = (void *) "-0x";
+ diff = info.dli_saddr - array[cnt];
+ }
+ iov[3].iov_len = 3;
+
+ iov[4].iov_base = _itoa_word ((unsigned long int) diff,
+ &buf2[WORD_WIDTH], 16, 0);
+ iov[4].iov_len = &buf2[WORD_WIDTH] - (char *) iov[4].iov_base;
+
+ iov[5].iov_base = (void *) ")";
+ iov[5].iov_len = 1;
+
+ last = 6;
+ }
+ }
+
+ iov[last].iov_base = (void *) "[0x";
+ iov[last].iov_len = 3;
+ ++last;
+
+ iov[last].iov_base = _itoa_word ((unsigned long int) array[cnt],
+ &buf[WORD_WIDTH], 16, 0);
+ iov[last].iov_len = &buf[WORD_WIDTH] - (char *) iov[last].iov_base;
+ ++last;
+
+ iov[last].iov_base = (void *) "]\n";
+ iov[last].iov_len = 2;
+ ++last;
+
+ __writev (fd, iov, last);
+ }
+}
+weak_alias (__backtrace_symbols_fd, backtrace_symbols_fd)
+libc_hidden_def (__backtrace_symbols_fd)
diff --git a/libc/sysdeps/generic/entry.h b/libc/sysdeps/generic/entry.h
new file mode 100644
index 000000000..16d3e3045
--- /dev/null
+++ b/libc/sysdeps/generic/entry.h
@@ -0,0 +1,5 @@
+#ifndef __ASSEMBLY__
+extern void _start (void) attribute_hidden;
+#endif
+
+#define ENTRY_POINT _start
diff --git a/libc/sysdeps/generic/errqueue.h b/libc/sysdeps/generic/errqueue.h
new file mode 100644
index 000000000..dac2bd386
--- /dev/null
+++ b/libc/sysdeps/generic/errqueue.h
@@ -0,0 +1,7 @@
+#ifndef _BITS_ERRQUEUE_H
+#define _BITS_ERRQUEUE_H 1
+
+/* This platform does not support socket error reporting
+ via MSG_ERRQUEUE. */
+
+#endif /* bits/errqueue.h */
diff --git a/libc/sysdeps/generic/fd_to_filename.h b/libc/sysdeps/generic/fd_to_filename.h
new file mode 100644
index 000000000..bc0347f73
--- /dev/null
+++ b/libc/sysdeps/generic/fd_to_filename.h
@@ -0,0 +1,26 @@
+/* Query filename corresponding to an open FD. Generic version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* In general there is no generic way to query filename for an open
+ file descriptor. */
+static inline const char *
+fd_to_filename (int fd)
+{
+ return NULL;
+}
diff --git a/libc/sysdeps/generic/fork.h b/libc/sysdeps/generic/fork.h
new file mode 100644
index 000000000..623cae28d
--- /dev/null
+++ b/libc/sysdeps/generic/fork.h
@@ -0,0 +1,8 @@
+/* Stub version of header for fork handling. Mainly to handle pthread_atfork
+ and friends. Outside dependencies:
+
+ UNREGISTER_ATFORK
+ If defined it must expand to a function call which takes one void*
+ parameter which is the DSO handle for the DSO which gets unloaded.
+ The function so called has to remove the atfork handlers registered
+ by this module. */
diff --git a/libc/sysdeps/generic/fpu_control.h b/libc/sysdeps/generic/fpu_control.h
new file mode 100644
index 000000000..4a1b07d23
--- /dev/null
+++ b/libc/sysdeps/generic/fpu_control.h
@@ -0,0 +1,39 @@
+/* FPU control word definitions. Stub version.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H
+
+#define _FPU_RESERVED 0xffffffff /* These bits are reserved and not changed. */
+
+/* The fdlibm code requires no interrupts for exceptions. Don't
+ change the rounding mode, it would break long double I/O! */
+#define _FPU_DEFAULT 0x00000000 /* Default value. */
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t;
+
+/* Macros for accessing the hardware control word. */
+#define _FPU_GETCW(cw) 0
+#define _FPU_SETCW(cw) do { } while (0)
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* _FPU_CONTROL_H */
diff --git a/libc/sysdeps/generic/frame.h b/libc/sysdeps/generic/frame.h
new file mode 100644
index 000000000..d39621880
--- /dev/null
+++ b/libc/sysdeps/generic/frame.h
@@ -0,0 +1,24 @@
+/* Definition of stack frame structure. Generic version.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+struct layout
+{
+ void *__unbounded next;
+ void *__unbounded return_address;
+};
diff --git a/libc/sysdeps/generic/framestate.c b/libc/sysdeps/generic/framestate.c
new file mode 100644
index 000000000..a912a8c37
--- /dev/null
+++ b/libc/sysdeps/generic/framestate.c
@@ -0,0 +1,52 @@
+/* __frame_state_for unwinder helper function wrapper.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#define STATIC static
+#define __frame_state_for fallback_frame_state_for
+#include <unwind-dw2.c>
+#undef __frame_state_for
+
+typedef struct frame_state * (*framesf)(void *pc, struct frame_state *);
+struct frame_state *__frame_state_for (void *pc,
+ struct frame_state *frame_state);
+
+struct frame_state *
+__frame_state_for (void *pc, struct frame_state *frame_state)
+{
+ static framesf frame_state_for;
+
+ if (frame_state_for == NULL)
+ {
+ void *handle = __libc_dlopen ("libgcc_s.so.1");
+
+ if (handle == NULL
+ || (frame_state_for
+ = (framesf) __libc_dlsym (handle, "__frame_state_for")) == NULL)
+#ifndef __USING_SJLJ_EXCEPTIONS__
+ frame_state_for = fallback_frame_state_for;
+#else
+ frame_state_for = abort;
+#endif
+ }
+
+ return frame_state_for (pc, frame_state);
+}
diff --git a/libc/sysdeps/generic/gccframe.h b/libc/sysdeps/generic/gccframe.h
new file mode 100644
index 000000000..1df7d713c
--- /dev/null
+++ b/libc/sysdeps/generic/gccframe.h
@@ -0,0 +1,50 @@
+/* Definition of object in frame unwind info. Generic version.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+
+struct dwarf_fde;
+struct fde_vector;
+
+struct object
+{
+ void *pc_begin;
+ void *tbase;
+ void *dbase;
+ union {
+ struct dwarf_fde *single;
+ struct dwarf_fde **array;
+ struct fde_vector *sort;
+ } u;
+
+ union {
+ struct {
+ unsigned long sorted : 1;
+ unsigned long from_array : 1;
+ unsigned long mixed_encoding : 1;
+ unsigned long encoding : 8;
+ /* ??? Wish there was an easy way to detect a 64-bit host here;
+ we've got 32 bits left to play with... */
+ unsigned long count : 21;
+ } b;
+ size_t i;
+ } s;
+
+ struct object *next;
+};
diff --git a/libc/sysdeps/generic/gmp-mparam.h b/libc/sysdeps/generic/gmp-mparam.h
new file mode 100644
index 000000000..6fc742987
--- /dev/null
+++ b/libc/sysdeps/generic/gmp-mparam.h
@@ -0,0 +1,28 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+Copyright (C) 1991,93,94,2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at your
+option) any later version.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <bits/wordsize.h>
+
+#define BITS_PER_MP_LIMB __WORDSIZE
+#define BYTES_PER_MP_LIMB (__WORDSIZE / 8)
+#define BITS_PER_LONGINT __WORDSIZE
+#define BITS_PER_INT 32
+#define BITS_PER_SHORTINT 16
+#define BITS_PER_CHAR 8
diff --git a/libc/sysdeps/generic/hp-timing.h b/libc/sysdeps/generic/hp-timing.h
new file mode 100644
index 000000000..099342db8
--- /dev/null
+++ b/libc/sysdeps/generic/hp-timing.h
@@ -0,0 +1,83 @@
+/* High precision, low overhead timing functions. Generic version.
+ Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H 1
+
+
+/* There are no generic definitions for the times. We could write something
+ using the `gettimeofday' system call where available but the overhead of
+ the system call might be too high.
+
+ In case a platform supports timers in the hardware the following macros
+ and types must be defined:
+
+ - HP_TIMING_AVAIL: test for availability.
+
+ - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
+ implemented using function calls but instead uses some inlined code
+ which might simply consist of a few assembler instructions. We have to
+ know this since we might want to use the macros here in places where we
+ cannot make function calls.
+
+ - hp_timing_t: This is the type for variables used to store the time
+ values.
+
+ - HP_TIMING_ZERO: clear `hp_timing_t' object.
+
+ - HP_TIMING_NOW: place timestamp for current time in variable given as
+ parameter.
+
+ - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
+ HP_TIMING_DIFF macro.
+
+ - HP_TIMING_DIFF: compute difference between two times and store it
+ in a third. Source and destination might overlap.
+
+ - HP_TIMING_ACCUM: add time difference to another variable. This might
+ be a bit more complicated to implement for some platforms as the
+ operation should be thread-safe and 64bit arithmetic on 32bit platforms
+ is not.
+
+ - HP_TIMING_ACCUM_NT: this is the variant for situations where we know
+ there are no threads involved.
+
+ - HP_TIMING_PRINT: write decimal representation of the timing value into
+ the given string. This operation need not be inline even though
+ HP_TIMING_INLINE is specified.
+
+*/
+
+/* Provide dummy definitions. */
+#define HP_TIMING_AVAIL (0)
+#define HP_TIMING_INLINE (0)
+typedef int hp_timing_t;
+#define HP_TIMING_ZERO(Var)
+#define HP_TIMING_NOW(var)
+#define HP_TIMING_DIFF_INIT()
+#define HP_TIMING_DIFF(Diff, Start, End)
+#define HP_TIMING_ACCUM(Sum, Diff)
+#define HP_TIMING_ACCUM_NT(Sum, Diff)
+#define HP_TIMING_PRINT(Buf, Len, Val)
+
+/* Since this implementation is not available we tell the user about it. */
+#define HP_TIMING_NONAVAIL 1
+
+#endif /* hp-timing.h */
diff --git a/libc/sysdeps/generic/ifreq.h b/libc/sysdeps/generic/ifreq.h
new file mode 100644
index 000000000..73340d4c9
--- /dev/null
+++ b/libc/sysdeps/generic/ifreq.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+static inline struct ifreq *
+__if_nextreq (struct ifreq *ifr)
+{
+#ifdef _HAVE_SA_LEN
+ if (ifr->ifr_addr.sa_len > sizeof ifr->ifr_addr)
+ return (struct ifreq *) ((char *) &ifr->ifr_addr + ifr->ifr_addr.sa_len);
+#endif
+ return ifr + 1;
+}
+
+extern void __ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd);
+
+
+static inline void
+__if_freereq (struct ifreq *ifreqs, int num_ifs)
+{
+ free (ifreqs);
+}
diff --git a/libc/sysdeps/generic/initfini.c b/libc/sysdeps/generic/initfini.c
new file mode 100644
index 000000000..2b8412a42
--- /dev/null
+++ b/libc/sysdeps/generic/initfini.c
@@ -0,0 +1,139 @@
+/* Special .init and .fini section support.
+ Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file is compiled into assembly code which is then munged by a sed
+ script into two files: crti.s and crtn.s.
+
+ * crti.s puts a function prologue at the beginning of the
+ .init and .fini sections and defines global symbols for
+ those addresses, so they can be called as functions.
+
+ * crtn.s puts the corresponding function epilogues
+ in the .init and .fini sections. */
+
+#include <stdlib.h>
+
+/* We use embedded asm for .section unconditionally, as this makes it
+ easier to insert the necessary directives into crtn.S. */
+#define SECTION(x) asm (".section " x )
+
+/* Embed an #include to pull in the alignment and .end directives. */
+asm ("\n#include \"defs.h\"");
+
+/* The initial common code ends here. */
+asm ("\n/*@HEADER_ENDS*/");
+
+/* To determine whether we need .end and .align: */
+asm ("\n/*@TESTS_BEGIN*/");
+extern void dummy (void (*foo) (void));
+void
+dummy (void (*foo) (void))
+{
+ if (foo)
+ (*foo) ();
+}
+asm ("\n/*@TESTS_END*/");
+
+/* The beginning of _init: */
+asm ("\n/*@_init_PROLOG_BEGINS*/");
+
+static void
+call_gmon_start(void)
+{
+ extern void __gmon_start__ (void) __attribute__ ((weak)); /*weak_extern (__gmon_start__);*/
+ void (*gmon_start) (void) = __gmon_start__;
+
+ if (gmon_start)
+ gmon_start ();
+}
+
+SECTION (".init");
+extern void _init (void);
+void
+_init (void)
+{
+ /* We cannot use the normal constructor mechanism in gcrt1.o because it
+ appears before crtbegin.o in the link, so the header elt of .ctors
+ would come after the elt for __gmon_start__. One approach is for
+ gcrt1.o to reference a symbol which would be defined by some library
+ module which has a constructor; but then user code's constructors
+ would come first, and not be profiled. */
+ call_gmon_start ();
+
+ asm ("ALIGN");
+ asm("END_INIT");
+ /* Now the epilog. */
+ asm ("\n/*@_init_PROLOG_ENDS*/");
+ asm ("\n/*@_init_EPILOG_BEGINS*/");
+ SECTION(".init");
+}
+asm ("END_INIT");
+
+/* End of the _init epilog, beginning of the _fini prolog. */
+asm ("\n/*@_init_EPILOG_ENDS*/");
+asm ("\n/*@_fini_PROLOG_BEGINS*/");
+
+SECTION (".fini");
+extern void _fini (void);
+void
+_fini (void)
+{
+
+ /* End of the _fini prolog. */
+ asm ("ALIGN");
+ asm ("END_FINI");
+ asm ("\n/*@_fini_PROLOG_ENDS*/");
+
+ {
+ /* Let GCC know that _fini is not a leaf function by having a dummy
+ function call here. We arrange for this call to be omitted from
+ either crt file. */
+ extern void i_am_not_a_leaf (void);
+ i_am_not_a_leaf ();
+ }
+
+ /* Beginning of the _fini epilog. */
+ asm ("\n/*@_fini_EPILOG_BEGINS*/");
+ SECTION (".fini");
+}
+asm ("END_FINI");
+
+/* End of the _fini epilog. Any further generated assembly (e.g. .ident)
+ is shared between both crt files. */
+asm ("\n/*@_fini_EPILOG_ENDS*/");
+asm ("\n/*@TRAILER_BEGINS*/");
+
+/* End of file. */
diff --git a/libc/sysdeps/generic/intr-msg.h b/libc/sysdeps/generic/intr-msg.h
new file mode 100644
index 000000000..0186aa332
--- /dev/null
+++ b/libc/sysdeps/generic/intr-msg.h
@@ -0,0 +1,15 @@
+/* Stubby version of intr-msg.h. */
+
+/* This file must be written in machine-dependent form for each hurd port.
+ and define the following:
+
+ INTR_MSG_TRAP
+ INTR_MSG_BACK_OUT
+ SYSCALL_EXAMINE
+ struct mach_msg_trap_args
+ MSG_EXAMINE
+
+ See sysdeps/mach/hurd/i386/intr-msg.h for an example. */
+
+
+#error Could not find machine-dependent intr-msg.h file.
diff --git a/libc/sysdeps/generic/inttypes.h b/libc/sysdeps/generic/inttypes.h
new file mode 100644
index 000000000..87f532f1d
--- /dev/null
+++ b/libc/sysdeps/generic/inttypes.h
@@ -0,0 +1,461 @@
+/* Copyright (C) 1997-2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * ISO C99: 7.8 Format conversion of integer types <inttypes.h>
+ */
+
+#ifndef _INTTYPES_H
+#define _INTTYPES_H 1
+
+#include <features.h>
+/* Get the type definitions. */
+#include <stdint.h>
+
+/* Get a definition for wchar_t. But we must not define wchar_t itself. */
+#ifndef ____gwchar_t_defined
+# ifdef __cplusplus
+# define __gwchar_t wchar_t
+# elif defined __WCHAR_TYPE__
+typedef __WCHAR_TYPE__ __gwchar_t;
+# else
+# define __need_wchar_t
+# include <stddef.h>
+typedef wchar_t __gwchar_t;
+# endif
+# define ____gwchar_t_defined 1
+#endif
+
+
+/* The ISO C99 standard specifies that these macros must only be
+ defined if explicitly requested. */
+#if !defined __cplusplus || defined __STDC_FORMAT_MACROS
+
+# if __WORDSIZE == 64
+# define __PRI64_PREFIX "l"
+# define __PRIPTR_PREFIX "l"
+# else
+# define __PRI64_PREFIX "ll"
+# define __PRIPTR_PREFIX
+# endif
+
+/* Macros for printing format specifiers. */
+
+/* Decimal notation. */
+# define PRId8 "d"
+# define PRId16 "d"
+# define PRId32 "d"
+# define PRId64 __PRI64_PREFIX "d"
+
+# define PRIdLEAST8 "d"
+# define PRIdLEAST16 "d"
+# define PRIdLEAST32 "d"
+# define PRIdLEAST64 __PRI64_PREFIX "d"
+
+# define PRIdFAST8 "d"
+# define PRIdFAST16 __PRIPTR_PREFIX "d"
+# define PRIdFAST32 __PRIPTR_PREFIX "d"
+# define PRIdFAST64 __PRI64_PREFIX "d"
+
+
+# define PRIi8 "i"
+# define PRIi16 "i"
+# define PRIi32 "i"
+# define PRIi64 __PRI64_PREFIX "i"
+
+# define PRIiLEAST8 "i"
+# define PRIiLEAST16 "i"
+# define PRIiLEAST32 "i"
+# define PRIiLEAST64 __PRI64_PREFIX "i"
+
+# define PRIiFAST8 "i"
+# define PRIiFAST16 __PRIPTR_PREFIX "i"
+# define PRIiFAST32 __PRIPTR_PREFIX "i"
+# define PRIiFAST64 __PRI64_PREFIX "i"
+
+/* Octal notation. */
+# define PRIo8 "o"
+# define PRIo16 "o"
+# define PRIo32 "o"
+# define PRIo64 __PRI64_PREFIX "o"
+
+# define PRIoLEAST8 "o"
+# define PRIoLEAST16 "o"
+# define PRIoLEAST32 "o"
+# define PRIoLEAST64 __PRI64_PREFIX "o"
+
+# define PRIoFAST8 "o"
+# define PRIoFAST16 __PRIPTR_PREFIX "o"
+# define PRIoFAST32 __PRIPTR_PREFIX "o"
+# define PRIoFAST64 __PRI64_PREFIX "o"
+
+/* Unsigned integers. */
+# define PRIu8 "u"
+# define PRIu16 "u"
+# define PRIu32 "u"
+# define PRIu64 __PRI64_PREFIX "u"
+
+# define PRIuLEAST8 "u"
+# define PRIuLEAST16 "u"
+# define PRIuLEAST32 "u"
+# define PRIuLEAST64 __PRI64_PREFIX "u"
+
+# define PRIuFAST8 "u"
+# define PRIuFAST16 __PRIPTR_PREFIX "u"
+# define PRIuFAST32 __PRIPTR_PREFIX "u"
+# define PRIuFAST64 __PRI64_PREFIX "u"
+
+/* lowercase hexadecimal notation. */
+# define PRIx8 "x"
+# define PRIx16 "x"
+# define PRIx32 "x"
+# define PRIx64 __PRI64_PREFIX "x"
+
+# define PRIxLEAST8 "x"
+# define PRIxLEAST16 "x"
+# define PRIxLEAST32 "x"
+# define PRIxLEAST64 __PRI64_PREFIX "x"
+
+# define PRIxFAST8 "x"
+# define PRIxFAST16 __PRIPTR_PREFIX "x"
+# define PRIxFAST32 __PRIPTR_PREFIX "x"
+# define PRIxFAST64 __PRI64_PREFIX "x"
+
+/* UPPERCASE hexadecimal notation. */
+# define PRIX8 "X"
+# define PRIX16 "X"
+# define PRIX32 "X"
+# define PRIX64 __PRI64_PREFIX "X"
+
+# define PRIXLEAST8 "X"
+# define PRIXLEAST16 "X"
+# define PRIXLEAST32 "X"
+# define PRIXLEAST64 __PRI64_PREFIX "X"
+
+# define PRIXFAST8 "X"
+# define PRIXFAST16 __PRIPTR_PREFIX "X"
+# define PRIXFAST32 __PRIPTR_PREFIX "X"
+# define PRIXFAST64 __PRI64_PREFIX "X"
+
+
+/* Macros for printing `intmax_t' and `uintmax_t'. */
+# define PRIdMAX __PRI64_PREFIX "d"
+# define PRIiMAX __PRI64_PREFIX "i"
+# define PRIoMAX __PRI64_PREFIX "o"
+# define PRIuMAX __PRI64_PREFIX "u"
+# define PRIxMAX __PRI64_PREFIX "x"
+# define PRIXMAX __PRI64_PREFIX "X"
+
+
+/* Macros for printing `intptr_t' and `uintptr_t'. */
+# define PRIdPTR __PRIPTR_PREFIX "d"
+# define PRIiPTR __PRIPTR_PREFIX "i"
+# define PRIoPTR __PRIPTR_PREFIX "o"
+# define PRIuPTR __PRIPTR_PREFIX "u"
+# define PRIxPTR __PRIPTR_PREFIX "x"
+# define PRIXPTR __PRIPTR_PREFIX "X"
+
+
+/* Macros for scanning format specifiers. */
+
+/* Signed decimal notation. */
+# define SCNd8 "hhd"
+# define SCNd16 "hd"
+# define SCNd32 "d"
+# define SCNd64 __PRI64_PREFIX "d"
+
+# define SCNdLEAST8 "hhd"
+# define SCNdLEAST16 "hd"
+# define SCNdLEAST32 "d"
+# define SCNdLEAST64 __PRI64_PREFIX "d"
+
+# define SCNdFAST8 "hhd"
+# define SCNdFAST16 __PRIPTR_PREFIX "d"
+# define SCNdFAST32 __PRIPTR_PREFIX "d"
+# define SCNdFAST64 __PRI64_PREFIX "d"
+
+/* Signed decimal notation. */
+# define SCNi8 "hhi"
+# define SCNi16 "hi"
+# define SCNi32 "i"
+# define SCNi64 __PRI64_PREFIX "i"
+
+# define SCNiLEAST8 "hhi"
+# define SCNiLEAST16 "hi"
+# define SCNiLEAST32 "i"
+# define SCNiLEAST64 __PRI64_PREFIX "i"
+
+# define SCNiFAST8 "hhi"
+# define SCNiFAST16 __PRIPTR_PREFIX "i"
+# define SCNiFAST32 __PRIPTR_PREFIX "i"
+# define SCNiFAST64 __PRI64_PREFIX "i"
+
+/* Unsigned decimal notation. */
+# define SCNu8 "hhu"
+# define SCNu16 "hu"
+# define SCNu32 "u"
+# define SCNu64 __PRI64_PREFIX "u"
+
+# define SCNuLEAST8 "hhu"
+# define SCNuLEAST16 "hu"
+# define SCNuLEAST32 "u"
+# define SCNuLEAST64 __PRI64_PREFIX "u"
+
+# define SCNuFAST8 "hhu"
+# define SCNuFAST16 __PRIPTR_PREFIX "u"
+# define SCNuFAST32 __PRIPTR_PREFIX "u"
+# define SCNuFAST64 __PRI64_PREFIX "u"
+
+/* Octal notation. */
+# define SCNo8 "hho"
+# define SCNo16 "ho"
+# define SCNo32 "o"
+# define SCNo64 __PRI64_PREFIX "o"
+
+# define SCNoLEAST8 "hho"
+# define SCNoLEAST16 "ho"
+# define SCNoLEAST32 "o"
+# define SCNoLEAST64 __PRI64_PREFIX "o"
+
+# define SCNoFAST8 "hho"
+# define SCNoFAST16 __PRIPTR_PREFIX "o"
+# define SCNoFAST32 __PRIPTR_PREFIX "o"
+# define SCNoFAST64 __PRI64_PREFIX "o"
+
+/* Hexadecimal notation. */
+# define SCNx8 "hhx"
+# define SCNx16 "hx"
+# define SCNx32 "x"
+# define SCNx64 __PRI64_PREFIX "x"
+
+# define SCNxLEAST8 "hhx"
+# define SCNxLEAST16 "hx"
+# define SCNxLEAST32 "x"
+# define SCNxLEAST64 __PRI64_PREFIX "x"
+
+# define SCNxFAST8 "hhx"
+# define SCNxFAST16 __PRIPTR_PREFIX "x"
+# define SCNxFAST32 __PRIPTR_PREFIX "x"
+# define SCNxFAST64 __PRI64_PREFIX "x"
+
+
+/* Macros for scanning `intmax_t' and `uintmax_t'. */
+# define SCNdMAX __PRI64_PREFIX "d"
+# define SCNiMAX __PRI64_PREFIX "i"
+# define SCNoMAX __PRI64_PREFIX "o"
+# define SCNuMAX __PRI64_PREFIX "u"
+# define SCNxMAX __PRI64_PREFIX "x"
+
+/* Macros for scaning `intptr_t' and `uintptr_t'. */
+# define SCNdPTR __PRIPTR_PREFIX "d"
+# define SCNiPTR __PRIPTR_PREFIX "i"
+# define SCNoPTR __PRIPTR_PREFIX "o"
+# define SCNuPTR __PRIPTR_PREFIX "u"
+# define SCNxPTR __PRIPTR_PREFIX "x"
+
+#endif /* C++ && format macros */
+
+
+__BEGIN_DECLS
+
+#if __WORDSIZE == 64
+
+/* We have to define the `uintmax_t' type using `ldiv_t'. */
+typedef struct
+ {
+ long int quot; /* Quotient. */
+ long int rem; /* Remainder. */
+ } imaxdiv_t;
+
+#else
+
+/* We have to define the `uintmax_t' type using `lldiv_t'. */
+typedef struct
+ {
+ long long int quot; /* Quotient. */
+ long long int rem; /* Remainder. */
+ } imaxdiv_t;
+
+#endif
+
+
+/* Compute absolute value of N. */
+extern intmax_t imaxabs (intmax_t __n) __THROW __attribute__ ((__const__));
+
+/* Return the `imaxdiv_t' representation of the value of NUMER over DENOM. */
+extern imaxdiv_t imaxdiv (intmax_t __numer, intmax_t __denom)
+ __THROW __attribute__ ((__const__));
+
+/* Like `strtol' but convert to `intmax_t'. */
+extern intmax_t strtoimax (__const char *__restrict __nptr,
+ char **__restrict __endptr, int __base) __THROW;
+
+/* Like `strtoul' but convert to `uintmax_t'. */
+extern uintmax_t strtoumax (__const char *__restrict __nptr,
+ char ** __restrict __endptr, int __base) __THROW;
+
+/* Like `wcstol' but convert to `intmax_t'. */
+extern intmax_t wcstoimax (__const __gwchar_t *__restrict __nptr,
+ __gwchar_t **__restrict __endptr, int __base)
+ __THROW;
+
+/* Like `wcstoul' but convert to `uintmax_t'. */
+extern uintmax_t wcstoumax (__const __gwchar_t *__restrict __nptr,
+ __gwchar_t ** __restrict __endptr, int __base)
+ __THROW;
+
+#ifdef __USE_EXTERN_INLINES
+
+# if __WORDSIZE == 64
+
+/* Like `strtol' but convert to `intmax_t'. */
+# ifndef __strtol_internal_defined
+extern long int __strtol_internal (__const char *__restrict __nptr,
+ char **__restrict __endptr,
+ int __base, int __group) __THROW;
+# define __strtol_internal_defined 1
+# endif
+extern __inline intmax_t
+__NTH (strtoimax (__const char *__restrict nptr, char **__restrict endptr,
+ int base))
+{
+ return __strtol_internal (nptr, endptr, base, 0);
+}
+
+/* Like `strtoul' but convert to `uintmax_t'. */
+# ifndef __strtoul_internal_defined
+extern unsigned long int __strtoul_internal (__const char *
+ __restrict __nptr,
+ char ** __restrict __endptr,
+ int __base, int __group) __THROW;
+# define __strtoul_internal_defined 1
+# endif
+extern __inline uintmax_t
+__NTH (strtoumax (__const char *__restrict nptr, char **__restrict endptr,
+ int base))
+{
+ return __strtoul_internal (nptr, endptr, base, 0);
+}
+
+/* Like `wcstol' but convert to `intmax_t'. */
+# ifndef __wcstol_internal_defined
+extern long int __wcstol_internal (__const __gwchar_t * __restrict __nptr,
+ __gwchar_t **__restrict __endptr,
+ int __base, int __group) __THROW;
+# define __wcstol_internal_defined 1
+# endif
+extern __inline intmax_t
+__NTH (wcstoimax (__const __gwchar_t *__restrict nptr,
+ __gwchar_t **__restrict endptr, int base))
+{
+ return __wcstol_internal (nptr, endptr, base, 0);
+}
+
+
+/* Like `wcstoul' but convert to `uintmax_t'. */
+# ifndef __wcstoul_internal_defined
+extern unsigned long int __wcstoul_internal (__const __gwchar_t *
+ __restrict __nptr,
+ __gwchar_t **
+ __restrict __endptr,
+ int __base, int __group) __THROW;
+# define __wcstoul_internal_defined 1
+# endif
+extern __inline uintmax_t
+__NTH (wcstoumax (__const __gwchar_t *__restrict nptr,
+ __gwchar_t **__restrict endptr, int base))
+{
+ return __wcstoul_internal (nptr, endptr, base, 0);
+}
+
+# else /* __WORDSIZE == 32 */
+
+/* Like `strtol' but convert to `intmax_t'. */
+# ifndef __strtoll_internal_defined
+__extension__
+extern long long int __strtoll_internal (__const char *__restrict __nptr,
+ char **__restrict __endptr,
+ int __base, int __group) __THROW;
+# define __strtoll_internal_defined 1
+# endif
+extern __inline intmax_t
+__NTH (strtoimax (__const char *__restrict nptr, char **__restrict endptr,
+ int base))
+{
+ return __strtoll_internal (nptr, endptr, base, 0);
+}
+
+/* Like `strtoul' but convert to `uintmax_t'. */
+# ifndef __strtoull_internal_defined
+__extension__
+extern unsigned long long int __strtoull_internal (__const char *
+ __restrict __nptr,
+ char **
+ __restrict __endptr,
+ int __base,
+ int __group) __THROW;
+# define __strtoull_internal_defined 1
+# endif
+extern __inline uintmax_t
+__NTH (strtoumax (__const char *__restrict nptr, char **__restrict endptr,
+ int base))
+{
+ return __strtoull_internal (nptr, endptr, base, 0);
+}
+
+/* Like `wcstol' but convert to `intmax_t'. */
+# ifndef __wcstoll_internal_defined
+__extension__
+extern long long int __wcstoll_internal (__const __gwchar_t *
+ __restrict __nptr,
+ __gwchar_t **__restrict __endptr,
+ int __base, int __group) __THROW;
+# define __wcstoll_internal_defined 1
+# endif
+extern __inline intmax_t
+__NTH (wcstoimax (__const __gwchar_t *__restrict nptr,
+ __gwchar_t **__restrict endptr, int base))
+{
+ return __wcstoll_internal (nptr, endptr, base, 0);
+}
+
+
+/* Like `wcstoul' but convert to `uintmax_t'. */
+# ifndef __wcstoull_internal_defined
+__extension__
+extern unsigned long long int __wcstoull_internal (__const __gwchar_t *
+ __restrict __nptr,
+ __gwchar_t **
+ __restrict __endptr,
+ int __base,
+ int __group) __THROW;
+# define __wcstoull_internal_defined 1
+# endif
+extern __inline uintmax_t
+__NTH (wcstoumax (__const __gwchar_t *__restrict nptr,
+ __gwchar_t **__restrict endptr, int base))
+{
+ return __wcstoull_internal (nptr, endptr, base, 0);
+}
+
+# endif /* __WORDSIZE == 32 */
+#endif /* Use extern inlines. */
+
+__END_DECLS
+
+#endif /* inttypes.h */
diff --git a/libc/sysdeps/generic/ldconfig.h b/libc/sysdeps/generic/ldconfig.h
new file mode 100644
index 000000000..9da8d6b3d
--- /dev/null
+++ b/libc/sysdeps/generic/ldconfig.h
@@ -0,0 +1,72 @@
+/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LDCONFIG_H
+#define _LDCONFIG_H
+
+#define FLAG_ANY -1
+#define FLAG_TYPE_MASK 0x00ff
+#define FLAG_LIBC4 0x0000
+#define FLAG_ELF 0x0001
+#define FLAG_ELF_LIBC5 0x0002
+#define FLAG_ELF_LIBC6 0x0003
+#define FLAG_REQUIRED_MASK 0xff00
+#define FLAG_SPARC_LIB64 0x0100
+#define FLAG_IA64_LIB64 0x0200
+#define FLAG_X8664_LIB64 0x0300
+#define FLAG_S390_LIB64 0x0400
+#define FLAG_POWERPC_LIB64 0x0500
+#define FLAG_MIPS64_LIBN32 0x0600
+#define FLAG_MIPS64_LIBN64 0x0700
+
+/* Declared in cache.c. */
+extern void print_cache (const char *cache_name);
+
+extern void init_cache (void);
+
+extern void save_cache (const char *cache_name);
+
+extern void add_to_cache (const char *path, const char *lib, int flags,
+ unsigned int osversion, uint64_t hwcap);
+
+/* Declared in readlib.c. */
+extern int process_file (const char *real_file_name, const char *file_name,
+ const char *lib, int *flag, unsigned int *osversion,
+ char **soname, int is_link);
+
+/* Declared in readelflib.c. */
+extern int process_elf_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+
+/* Declared in chroot_canon.c. */
+extern char *chroot_canon (const char *chroot, const char *name);
+
+/* Declared in ldconfig.c. */
+extern int opt_verbose;
+
+extern int opt_format;
+
+/* Prototypes for a few program-wide used functions. */
+extern void *xmalloc (size_t __n);
+extern void *xcalloc (size_t __n, size_t __size);
+extern void *xrealloc (void *__p, size_t __n);
+extern char *xstrdup (const char *__str);
+
+#endif /* ! _LDCONFIG_H */
diff --git a/libc/sysdeps/generic/ldsodefs.h b/libc/sysdeps/generic/ldsodefs.h
new file mode 100644
index 000000000..ef2b68539
--- /dev/null
+++ b/libc/sysdeps/generic/ldsodefs.h
@@ -0,0 +1,1080 @@
+/* Run-time dynamic linker data structures for loaded ELF shared objects.
+ Copyright (C) 1995-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LDSODEFS_H
+#define _LDSODEFS_H 1
+
+#include <features.h>
+
+#include <stdbool.h>
+#define __need_size_t
+#define __need_NULL
+#include <stddef.h>
+#include <string.h>
+
+#include <elf.h>
+#include <dlfcn.h>
+#include <fpu_control.h>
+#include <sys/mman.h>
+#include <link.h>
+#include <dl-lookupcfg.h>
+#include <dl-sysdep.h>
+#include <bits/libc-lock.h>
+#include <hp-timing.h>
+#include <tls.h>
+
+__BEGIN_DECLS
+
+/* We use this macro to refer to ELF types independent of the native wordsize.
+ `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */
+#define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type)
+
+/* All references to the value of l_info[DT_PLTGOT],
+ l_info[DT_STRTAB], l_info[DT_SYMTAB], l_info[DT_RELA],
+ l_info[DT_REL], l_info[DT_JMPREL], and l_info[VERSYMIDX (DT_VERSYM)]
+ have to be accessed via the D_PTR macro. The macro is needed since for
+ most architectures the entry is already relocated - but for some not
+ and we need to relocate at access time. */
+#ifdef DL_RO_DYN_SECTION
+# define D_PTR(map, i) ((map)->i->d_un.d_ptr + (map)->l_addr)
+#else
+# define D_PTR(map, i) (map)->i->d_un.d_ptr
+#endif
+
+/* Result of the lookup functions and how to retrieve the base address. */
+typedef struct link_map *lookup_t;
+# define LOOKUP_VALUE(map) map
+# define LOOKUP_VALUE_ADDRESS(map) ((map) ? (map)->l_addr : 0)
+
+/* On some architectures a pointer to a function is not just a pointer
+ to the actual code of the function but rather an architecture
+ specific descriptor. */
+#ifndef ELF_FUNCTION_PTR_IS_SPECIAL
+# define DL_SYMBOL_ADDRESS(map, ref) \
+ (void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value)
+# define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr))
+# define DL_DT_INIT_ADDRESS(map, start) (start)
+# define DL_DT_FINI_ADDRESS(map, start) (start)
+#endif
+
+/* On some architectures dladdr can't use st_size of all symbols this way. */
+#define DL_ADDR_SYM_MATCH(L, SYM, MATCHSYM, ADDR) \
+ ((ADDR) >= (L)->l_addr + (SYM)->st_value \
+ && (((SYM)->st_size == 0 \
+ && (ADDR) == (L)->l_addr + (SYM)->st_value) \
+ || (ADDR) < (L)->l_addr + (SYM)->st_value + (SYM)->st_size) \
+ && ((MATCHSYM) == NULL || (MATCHSYM)->st_value < (SYM)->st_value))
+
+/* Unmap a loaded object, called by _dl_close (). */
+#ifndef DL_UNMAP_IS_SPECIAL
+# define DL_UNMAP(map) \
+ __munmap ((void *) (map)->l_map_start, \
+ (map)->l_map_end - (map)->l_map_start)
+#endif
+
+/* By default we do not need special support to initialize DSOs loaded
+ by statically linked binaries. */
+#ifndef DL_STATIC_INIT
+# define DL_STATIC_INIT(map)
+#endif
+
+/* Reloc type classes as returned by elf_machine_type_class().
+ ELF_RTYPE_CLASS_PLT means this reloc should not be satisfied by
+ some PLT symbol, ELF_RTYPE_CLASS_COPY means this reloc should not be
+ satisfied by any symbol in the executable. Some architectures do
+ not support copy relocations. In this case we define the macro to
+ zero so that the code for handling them gets automatically optimized
+ out. */
+#define ELF_RTYPE_CLASS_PLT 1
+#ifndef DL_NO_COPY_RELOCS
+# define ELF_RTYPE_CLASS_COPY 2
+#else
+# define ELF_RTYPE_CLASS_COPY 0
+#endif
+
+/* ELF uses the PF_x macros to specify the segment permissions, mmap
+ uses PROT_xxx. In most cases the three macros have the values 1, 2,
+ and 3 but not in a matching order. The following macros allows
+ converting from the PF_x values to PROT_xxx values. */
+#define PF_TO_PROT \
+ ((PROT_READ << (PF_R * 4)) \
+ | (PROT_WRITE << (PF_W * 4)) \
+ | (PROT_EXEC << (PF_X * 4)) \
+ | ((PROT_READ | PROT_WRITE) << ((PF_R | PF_W) * 4)) \
+ | ((PROT_READ | PROT_EXEC) << ((PF_R | PF_X) * 4)) \
+ | ((PROT_WRITE | PROT_EXEC) << (PF_W | PF_X) * 4) \
+ | ((PROT_READ | PROT_WRITE | PROT_EXEC) << ((PF_R | PF_W | PF_X) * 4)))
+
+
+/* For the version handling we need an array with only names and their
+ hash values. */
+struct r_found_version
+ {
+ const char *name;
+ ElfW(Word) hash;
+
+ int hidden;
+ const char *filename;
+ };
+
+/* We want to cache information about the searches for shared objects. */
+
+enum r_dir_status { unknown, nonexisting, existing };
+
+struct r_search_path_elem
+ {
+ /* This link is only used in the `all_dirs' member of `r_search_path'. */
+ struct r_search_path_elem *next;
+
+ /* Strings saying where the definition came from. */
+ const char *what;
+ const char *where;
+
+ /* Basename for this search path element. The string must end with
+ a slash character. */
+ const char *dirname;
+ size_t dirnamelen;
+
+ enum r_dir_status status[0];
+ };
+
+struct r_strlenpair
+ {
+ const char *str;
+ size_t len;
+ };
+
+
+/* A data structure for a simple single linked list of strings. */
+struct libname_list
+ {
+ const char *name; /* Name requested (before search). */
+ struct libname_list *next; /* Link to next name for this object. */
+ int dont_free; /* Flag whether this element should be freed
+ if the object is not entirely unloaded. */
+ };
+
+
+/* Bit masks for the objects which valid callers can come from to
+ functions with restricted interface. */
+enum allowmask
+ {
+ allow_libc = 1,
+ allow_libdl = 2,
+ allow_libpthread = 4,
+ allow_ldso = 8
+ };
+
+
+/* Type for list of auditing interfaces. */
+struct La_i86_regs;
+struct La_i86_retval;
+struct La_x86_64_regs;
+struct La_x86_64_retval;
+struct La_ppc32_regs;
+struct La_ppc32_retval;
+struct La_ppc64_regs;
+struct La_ppc64_retval;
+struct La_sh_regs;
+struct La_sh_retval;
+struct La_alpha_regs;
+struct La_alpha_retval;
+struct La_s390_32_regs;
+struct La_s390_32_retval;
+struct La_s390_64_regs;
+struct La_s390_64_retval;
+struct La_ia64_regs;
+struct La_ia64_retval;
+struct La_sparc32_regs;
+struct La_sparc32_retval;
+struct La_sparc64_regs;
+struct La_sparc64_retval;
+
+struct audit_ifaces
+{
+ void (*activity) (uintptr_t *, unsigned int);
+ char *(*objsearch) (const char *, uintptr_t *, unsigned int);
+ unsigned int (*objopen) (struct link_map *, Lmid_t, uintptr_t *);
+ void (*preinit) (uintptr_t *);
+ union
+ {
+ uintptr_t (*symbind32) (Elf32_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, unsigned int *, const char *);
+ uintptr_t (*symbind64) (Elf64_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, unsigned int *, const char *);
+ };
+ union
+ {
+ Elf32_Addr (*i86_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, struct La_i86_regs *,
+ unsigned int *, const char *name,
+ long int *framesizep);
+ Elf64_Addr (*x86_64_gnu_pltenter) (Elf64_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, struct La_x86_64_regs *,
+ unsigned int *, const char *name,
+ long int *framesizep);
+ Elf32_Addr (*ppc32_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, struct La_ppc32_regs *,
+ unsigned int *, const char *name,
+ long int *framesizep);
+ Elf64_Addr (*ppc64_gnu_pltenter) (Elf64_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, struct La_ppc64_regs *,
+ unsigned int *, const char *name,
+ long int *framesizep);
+ uintptr_t (*sh_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, const struct La_sh_regs *,
+ unsigned int *, const char *name,
+ long int *framesizep);
+ Elf64_Addr (*alpha_gnu_pltenter) (Elf64_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, struct La_alpha_regs *,
+ unsigned int *, const char *name,
+ long int *framesizep);
+ Elf32_Addr (*s390_32_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, struct La_s390_32_regs *,
+ unsigned int *, const char *name,
+ long int *framesizep);
+ Elf64_Addr (*s390_64_gnu_pltenter) (Elf64_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, struct La_s390_64_regs *,
+ unsigned int *, const char *name,
+ long int *framesizep);
+ Elf64_Addr (*ia64_gnu_pltenter) (Elf64_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, struct La_ia64_regs *,
+ unsigned int *, const char *name,
+ long int *framesizep);
+ Elf32_Addr (*sparc32_gnu_pltenter) (Elf32_Sym *, unsigned int,
+ uintptr_t *, uintptr_t *,
+ const struct La_sparc32_regs *,
+ unsigned int *, const char *name,
+ long int *framesizep);
+ Elf64_Addr (*sparc64_gnu_pltenter) (Elf64_Sym *, unsigned int,
+ uintptr_t *, uintptr_t *,
+ const struct La_sparc64_regs *,
+ unsigned int *, const char *name,
+ long int *framesizep);
+#ifdef ARCH_PLTENTER_MEMBERS
+ ARCH_PLTENTER_MEMBERS;
+#endif
+ };
+ union
+ {
+ unsigned int (*i86_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, const struct La_i86_regs *,
+ struct La_i86_retval *, const char *);
+ unsigned int (*x86_64_gnu_pltexit) (Elf64_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *,
+ const struct La_x86_64_regs *,
+ struct La_x86_64_retval *,
+ const char *);
+ unsigned int (*ppc32_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *,
+ const struct La_ppc32_regs *,
+ struct La_ppc32_retval *, const char *);
+ unsigned int (*ppc64_gnu_pltexit) (Elf64_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *,
+ const struct La_ppc64_regs *,
+ struct La_ppc64_retval *, const char *);
+ unsigned int (*sh_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *, const struct La_sh_regs *,
+ struct La_sh_retval *, const char *);
+ unsigned int (*alpha_gnu_pltexit) (Elf64_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *,
+ const struct La_alpha_regs *,
+ struct La_alpha_retval *, const char *);
+ unsigned int (*s390_32_gnu_pltexit) (Elf32_Sym *, unsigned int,
+ uintptr_t *, uintptr_t *,
+ const struct La_s390_32_regs *,
+ struct La_s390_32_retval *,
+ const char *);
+ unsigned int (*s390_64_gnu_pltexit) (Elf64_Sym *, unsigned int,
+ uintptr_t *, uintptr_t *,
+ const struct La_s390_64_regs *,
+ struct La_s390_64_retval *,
+ const char *);
+ unsigned int (*ia64_gnu_pltexit) (Elf64_Sym *, unsigned int, uintptr_t *,
+ uintptr_t *,
+ const struct La_ia64_regs *,
+ struct La_ia64_retval *, const char *);
+ unsigned int (*sparc32_gnu_pltexit) (Elf32_Sym *, unsigned int,
+ uintptr_t *, uintptr_t *,
+ const struct La_sparc32_regs *,
+ struct La_sparc32_retval *,
+ const char *);
+ unsigned int (*sparc64_gnu_pltexit) (Elf64_Sym *, unsigned int,
+ uintptr_t *, uintptr_t *,
+ const struct La_sparc32_regs *,
+ struct La_sparc32_retval *,
+ const char *);
+#ifdef ARCH_PLTEXIT_MEMBERS
+ ARCH_PLTEXIT_MEMBERS;
+#endif
+ };
+ unsigned int (*objclose) (uintptr_t *);
+
+ struct audit_ifaces *next;
+};
+
+
+/* Test whether given NAME matches any of the names of the given object. */
+extern int _dl_name_match_p (const char *__name, const struct link_map *__map)
+ internal_function;
+
+/* Function used as argument for `_dl_receive_error' function. The
+ arguments are the error code, error string, and the objname the
+ error occurred in. */
+typedef void (*receiver_fct) (int, const char *, const char *);
+
+/* Internal functions of the run-time dynamic linker.
+ These can be accessed if you link again the dynamic linker
+ as a shared library, as in `-lld' or `/lib/ld.so' explicitly;
+ but are not normally of interest to user programs.
+
+ The `-ldl' library functions in <dlfcn.h> provide a simple
+ user interface to run-time dynamic linking. */
+
+
+#ifndef SHARED
+# define EXTERN extern
+# define GL(name) _##name
+#else
+# define EXTERN
+# ifdef IS_IN_rtld
+# define GL(name) _rtld_local._##name
+# else
+# define GL(name) _rtld_global._##name
+# endif
+struct rtld_global
+{
+#endif
+ /* Don't change the order of the following elements. 'dl_loaded'
+ must remain the first element. Forever. */
+
+/* Non-shared code has no support for multiple namespaces. */
+#ifdef SHARED
+# define DL_NNS 16
+#else
+# define DL_NNS 1
+#endif
+ EXTERN struct link_namespaces
+ {
+ /* A pointer to the map for the main map. */
+ struct link_map *_ns_loaded;
+ /* Number of object in the _dl_loaded list. */
+ unsigned int _ns_nloaded;
+ /* Array representing global scope. */
+ struct r_scope_elem *_ns_global_scope[2];
+ /* Direct pointer to the searchlist of the main object. */
+ struct r_scope_elem *_ns_main_searchlist;
+ /* This is zero at program start to signal that the global scope map is
+ allocated by rtld. Later it keeps the size of the map. It might be
+ reset if in _dl_close if the last global object is removed. */
+ size_t _ns_global_scope_alloc;
+ /* Keep track of changes to each namespace' list. */
+ struct r_debug _ns_debug;
+ } _dl_ns[DL_NNS];
+
+ /* During the program run we must not modify the global data of
+ loaded shared object simultanously in two threads. Therefore we
+ protect `_dl_open' and `_dl_close' in dl-close.c.
+
+ This must be a recursive lock since the initializer function of
+ the loaded object might as well require a call to this function.
+ At this time it is not anymore a problem to modify the tables. */
+ __rtld_lock_define_recursive (EXTERN, _dl_load_lock)
+
+ /* Incremented whenever something may have been added to dl_loaded. */
+ EXTERN unsigned long long _dl_load_adds;
+
+#ifndef MAP_ANON
+ /* File descriptor referring to the zero-fill device. */
+ EXTERN int _dl_zerofd;
+#endif
+
+ /* The object to be initialized first. */
+ EXTERN struct link_map *_dl_initfirst;
+
+#if HP_TIMING_AVAIL || HP_SMALL_TIMING_AVAIL
+ /* Start time on CPU clock. */
+ EXTERN hp_timing_t _dl_cpuclock_offset;
+#endif
+
+ /* Map of shared object to be profiled. */
+ EXTERN struct link_map *_dl_profile_map;
+
+ /* Counters for the number of relocations performed. */
+ EXTERN unsigned long int _dl_num_relocations;
+ EXTERN unsigned long int _dl_num_cache_relocations;
+
+ /* List of search directories. */
+ EXTERN struct r_search_path_elem *_dl_all_dirs;
+
+#ifdef _LIBC_REENTRANT
+ EXTERN void **(*_dl_error_catch_tsd) (void) __attribute__ ((const));
+#endif
+
+ /* Structure describing the dynamic linker itself. We need to
+ reserve memory for the data the audit libraries need. */
+ EXTERN struct link_map _dl_rtld_map;
+#ifdef SHARED
+ struct auditstate audit_data[DL_NNS];
+#endif
+
+#if defined SHARED && defined _LIBC_REENTRANT \
+ && defined __rtld_lock_default_lock_recursive
+ EXTERN void (*_dl_rtld_lock_recursive) (void *);
+ EXTERN void (*_dl_rtld_unlock_recursive) (void *);
+#endif
+
+ /* Prevailing state of the stack, PF_X indicating it's executable. */
+ EXTERN ElfW(Word) _dl_stack_flags;
+
+ /* If loading a shared object requires that we make the stack executable
+ when it was not, we do it by calling this function.
+ It returns an errno code or zero on success. */
+ EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function;
+
+ /* Keep the conditional TLS members at the end so the layout of the
+ structure used by !USE_TLS code matches the prefix of the layout in
+ the USE_TLS rtld. Note that `struct link_map' is conditionally
+ defined as well, so _dl_rtld_map needs to be last before this. */
+#ifdef USE_TLS
+ /* Highest dtv index currently needed. */
+ EXTERN size_t _dl_tls_max_dtv_idx;
+ /* Flag signalling whether there are gaps in the module ID allocation. */
+ EXTERN bool _dl_tls_dtv_gaps;
+ /* Information about the dtv slots. */
+ EXTERN struct dtv_slotinfo_list
+ {
+ size_t len;
+ struct dtv_slotinfo_list *next;
+ struct dtv_slotinfo
+ {
+ size_t gen;
+ struct link_map *map;
+ } slotinfo[0];
+ } *_dl_tls_dtv_slotinfo_list;
+ /* Number of modules in the static TLS block. */
+ EXTERN size_t _dl_tls_static_nelem;
+ /* Size of the static TLS block. */
+ EXTERN size_t _dl_tls_static_size;
+ /* Size actually allocated in the static TLS block. */
+ EXTERN size_t _dl_tls_static_used;
+ /* Alignment requirement of the static TLS block. */
+ EXTERN size_t _dl_tls_static_align;
+
+/* Number of additional entries in the slotinfo array of each slotinfo
+ list element. A large number makes it almost certain take we never
+ have to iterate beyond the first element in the slotinfo list. */
+# define TLS_SLOTINFO_SURPLUS (62)
+
+/* Number of additional slots in the dtv allocated. */
+# define DTV_SURPLUS (14)
+
+ /* Initial dtv of the main thread, not allocated with normal malloc. */
+ EXTERN void *_dl_initial_dtv;
+ /* Generation counter for the dtv. */
+ EXTERN size_t _dl_tls_generation;
+
+ EXTERN void (*_dl_init_static_tls) (struct link_map *);
+#endif
+
+#ifdef SHARED
+};
+# define __rtld_global_attribute__
+# ifdef IS_IN_rtld
+# ifdef HAVE_VISIBILITY_ATTRIBUTE
+# ifdef HAVE_SDATA_SECTION
+# define __rtld_local_attribute__ \
+ __attribute__ ((visibility ("hidden"), section (".sdata")))
+# undef __rtld_global_attribute__
+# define __rtld_global_attribute__ __attribute__ ((section (".sdata")))
+# else
+# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden")))
+# endif
+# else
+# define __rtld_local_attribute__
+# endif
+extern struct rtld_global _rtld_local __rtld_local_attribute__;
+# undef __rtld_local_attribute__
+# endif
+extern struct rtld_global _rtld_global __rtld_global_attribute__;
+# undef __rtld_global_attribute__
+#endif
+
+#ifndef SHARED
+# define GLRO(name) _##name
+#else
+# ifdef IS_IN_rtld
+# define GLRO(name) _rtld_local_ro._##name
+# else
+# define GLRO(name) _rtld_global_ro._##name
+# endif
+struct rtld_global_ro
+{
+#endif
+
+ /* If nonzero the appropriate debug information is printed. */
+ EXTERN int _dl_debug_mask;
+#define DL_DEBUG_LIBS (1 << 0)
+#define DL_DEBUG_IMPCALLS (1 << 1)
+#define DL_DEBUG_BINDINGS (1 << 2)
+#define DL_DEBUG_SYMBOLS (1 << 3)
+#define DL_DEBUG_VERSIONS (1 << 4)
+#define DL_DEBUG_RELOC (1 << 5)
+#define DL_DEBUG_FILES (1 << 6)
+#define DL_DEBUG_STATISTICS (1 << 7)
+#define DL_DEBUG_UNUSED (1 << 8)
+/* These two are used only internally. */
+#define DL_DEBUG_HELP (1 << 9)
+#define DL_DEBUG_PRELINK (1 << 10)
+
+ /* Cached value of `getpagesize ()'. */
+ EXTERN size_t _dl_pagesize;
+
+ /* OS version. */
+ EXTERN unsigned int _dl_osversion;
+ /* Platform name. */
+ EXTERN const char *_dl_platform;
+ EXTERN size_t _dl_platformlen;
+
+ /* Copy of the content of `_dl_main_searchlist' at startup time. */
+ EXTERN struct r_scope_elem _dl_initial_searchlist;
+
+ /* CLK_TCK as reported by the kernel. */
+ EXTERN int _dl_clktck;
+
+ /* If nonzero print warnings messages. */
+ EXTERN int _dl_verbose;
+
+ /* File descriptor to write debug messages to. */
+ EXTERN int _dl_debug_fd;
+
+ /* Do we do lazy relocations? */
+ EXTERN int _dl_lazy;
+
+ /* Nonzero if runtime lookups should not update the .got/.plt. */
+ EXTERN int _dl_bind_not;
+
+ /* Nonzero if references should be treated as weak during runtime
+ linking. */
+ EXTERN int _dl_dynamic_weak;
+
+ /* Default floating-point control word. */
+ EXTERN fpu_control_t _dl_fpu_control;
+
+ /* Expected cache ID. */
+ EXTERN int _dl_correct_cache_id;
+
+ /* 0 if internal pointer values should not be guarded, 1 if they should. */
+ EXTERN int _dl_pointer_guard;
+
+ /* Mask for hardware capabilities that are available. */
+ EXTERN uint64_t _dl_hwcap;
+
+ /* Mask for important hardware capabilities we honour. */
+ EXTERN uint64_t _dl_hwcap_mask;
+
+ /* Get architecture specific definitions. */
+#define PROCINFO_DECL
+#ifndef PROCINFO_CLASS
+# define PROCINFO_CLASS EXTERN
+#endif
+#include <dl-procinfo.c>
+
+ /* Names of shared object for which the RPATH should be ignored. */
+ EXTERN const char *_dl_inhibit_rpath;
+
+ /* Location of the binary. */
+ EXTERN const char *_dl_origin_path;
+
+ /* -1 if the dynamic linker should honor library load bias,
+ 0 if not, -2 use the default (honor biases for normal
+ binaries, don't honor for PIEs). */
+ EXTERN ElfW(Addr) _dl_use_load_bias;
+
+ /* Name of the shared object to be profiled (if any). */
+ EXTERN const char *_dl_profile;
+ /* Filename of the output file. */
+ EXTERN const char *_dl_profile_output;
+ /* Name of the object we want to trace the prelinking. */
+ EXTERN const char *_dl_trace_prelink;
+ /* Map of shared object to be prelink traced. */
+ EXTERN struct link_map *_dl_trace_prelink_map;
+
+ /* All search directories defined at startup. */
+ EXTERN struct r_search_path_elem *_dl_init_all_dirs;
+
+#if HP_TIMING_AVAIL || HP_SMALL_TIMING_AVAIL
+ /* Overhead of a high-precision timing measurement. */
+ EXTERN hp_timing_t _dl_hp_timing_overhead;
+#endif
+
+#ifdef NEED_DL_SYSINFO
+ /* Syscall handling improvements. This is very specific to x86. */
+ EXTERN uintptr_t _dl_sysinfo;
+#endif
+
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
+ /* The vsyscall page is a virtual DSO pre-mapped by the kernel.
+ This points to its ELF header. */
+ EXTERN const ElfW(Ehdr) *_dl_sysinfo_dso;
+
+ /* At startup time we set up the normal DSO data structure for it,
+ and this points to it. */
+ EXTERN struct link_map *_dl_sysinfo_map;
+#endif
+
+#ifdef SHARED
+ /* We add a function table to _rtld_global which is then used to
+ call the function instead of going through the PLT. The result
+ is that we can avoid exporting the functions and we do not jump
+ PLT relocations in libc.so. */
+ void (*_dl_debug_printf) (const char *, ...)
+ __attribute__ ((__format__ (__printf__, 1, 2)));
+ int (internal_function *_dl_catch_error) (const char **, const char **,
+ bool *, void (*) (void *), void *);
+ void (internal_function *_dl_signal_error) (int, const char *, const char *,
+ const char *);
+ void (*_dl_mcount) (ElfW(Addr) frompc, ElfW(Addr) selfpc);
+ lookup_t (internal_function *_dl_lookup_symbol_x) (const char *,
+ struct link_map *,
+ const ElfW(Sym) **,
+ struct r_scope_elem *[],
+ const struct r_found_version *,
+ int, int,
+ struct link_map *);
+ int (*_dl_check_caller) (const void *, enum allowmask);
+ void *(*_dl_open) (const char *file, int mode, const void *caller_dlopen,
+ Lmid_t nsid, int argc, char *argv[], char *env[]);
+ void (*_dl_close) (void *map);
+
+ /* List of auditing interfaces. */
+ struct audit_ifaces *_dl_audit;
+ unsigned int _dl_naudit;
+};
+# define __rtld_global_attribute__
+# ifdef IS_IN_rtld
+# ifdef HAVE_VISIBILITY_ATTRIBUTE
+# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden")))
+# else
+# define __rtld_local_attribute__
+# endif
+extern struct rtld_global_ro _rtld_local_ro
+ attribute_relro __rtld_local_attribute__;
+extern struct rtld_global_ro _rtld_global_ro
+ attribute_relro __rtld_global_attribute__;
+# undef __rtld_local_attribute__
+# else
+/* We cheat a bit here. We declare the variable as as const even
+ though it is at startup. */
+extern const struct rtld_global_ro _rtld_global_ro
+ attribute_relro __rtld_global_attribute__;
+# endif
+# undef __rtld_global_attribute__
+#endif
+#undef EXTERN
+
+#ifdef IS_IN_rtld
+/* This is the initial value of GL(dl_error_catch_tsd).
+ A non-TLS libpthread will change it. */
+extern void **_dl_initial_error_catch_tsd (void) __attribute__ ((const))
+ attribute_hidden;
+#endif
+
+/* This is the initial value of GL(dl_make_stack_executable_hook).
+ A threads library can change it. */
+extern int _dl_make_stack_executable (void **stack_endp) internal_function;
+rtld_hidden_proto (_dl_make_stack_executable)
+
+/* Variable pointing to the end of the stack (or close to it). This value
+ must be constant over the runtime of the application. Some programs
+ might use the variable which results in copy relocations on some
+ platforms. But this does not matter, ld.so can always use the local
+ copy. */
+extern void *__libc_stack_end attribute_relro;
+rtld_hidden_proto (__libc_stack_end)
+
+/* Parameters passed to the dynamic linker. */
+extern int _dl_argc attribute_hidden attribute_relro;
+extern char **_dl_argv
+#ifndef DL_ARGV_NOT_RELRO
+ attribute_relro
+#endif
+ ;
+#ifdef IS_IN_rtld
+extern char **_dl_argv_internal attribute_hidden
+# ifndef DL_ARGV_NOT_RELRO
+ attribute_relro
+# endif
+ ;
+# define rtld_progname (INTUSE(_dl_argv)[0])
+#else
+# define rtld_progname _dl_argv[0]
+#endif
+
+/* Flag set at startup and cleared when the last initializer has run. */
+extern int _dl_starting_up;
+weak_extern (_dl_starting_up)
+#ifdef IS_IN_rtld
+extern int _dl_starting_up_internal attribute_hidden;
+#endif
+
+/* OS-dependent function to open the zero-fill device. */
+extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */
+
+
+/* Write message on the debug file descriptor. The parameters are
+ interpreted as for a `printf' call. All the lines start with a
+ tag showing the PID. */
+extern void _dl_debug_printf (const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 1, 2))) attribute_hidden;
+
+/* Write message on the debug file descriptor. The parameters are
+ interpreted as for a `printf' call. All the lines buf the first
+ start with a tag showing the PID. */
+extern void _dl_debug_printf_c (const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 1, 2)));
+
+
+/* Write a message on the specified descriptor FD. The parameters are
+ interpreted as for a `printf' call. */
+extern void _dl_dprintf (int fd, const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 2, 3)))
+ attribute_hidden;
+
+/* Write a message on the specified descriptor standard output. The
+ parameters are interpreted as for a `printf' call. */
+#define _dl_printf(fmt, args...) \
+ _dl_dprintf (STDOUT_FILENO, fmt, ##args)
+
+/* Write a message on the specified descriptor standard error. The
+ parameters are interpreted as for a `printf' call. */
+#define _dl_error_printf(fmt, args...) \
+ _dl_dprintf (STDERR_FILENO, fmt, ##args)
+
+/* Write a message on the specified descriptor standard error and exit
+ the program. The parameters are interpreted as for a `printf' call. */
+#define _dl_fatal_printf(fmt, args...) \
+ do \
+ { \
+ _dl_dprintf (STDERR_FILENO, fmt, ##args); \
+ _exit (127); \
+ } \
+ while (1)
+
+
+/* This function is called by all the internal dynamic linker functions
+ when they encounter an error. ERRCODE is either an `errno' code or
+ zero; OBJECT is the name of the problematical shared object, or null if
+ it is a general problem; ERRSTRING is a string describing the specific
+ problem. */
+extern void _dl_signal_error (int errcode, const char *object,
+ const char *occurred, const char *errstring)
+ internal_function __attribute__ ((__noreturn__)) attribute_hidden;
+
+/* Like _dl_signal_error, but may return when called in the context of
+ _dl_receive_error. */
+extern void _dl_signal_cerror (int errcode, const char *object,
+ const char *occation, const char *errstring)
+ internal_function;
+
+/* Call OPERATE, receiving errors from `dl_signal_cerror'. Unlike
+ `_dl_catch_error' the operation is resumed after the OPERATE
+ function returns.
+ ARGS is passed as argument to OPERATE. */
+extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *),
+ void *args)
+ internal_function;
+
+
+/* Open the shared object NAME and map in its segments.
+ LOADER's DT_RPATH is used in searching for NAME.
+ If the object is already opened, returns its existing map.
+ For preloaded shared objects PRELOADED is set to a non-zero
+ value to allow additional security checks. */
+extern struct link_map *_dl_map_object (struct link_map *loader,
+ const char *name, int preloaded,
+ int type, int trace_mode, int mode,
+ Lmid_t nsid)
+ internal_function attribute_hidden;
+
+/* Call _dl_map_object on the dependencies of MAP, and set up
+ MAP->l_searchlist. PRELOADS points to a vector of NPRELOADS previously
+ loaded objects that will be inserted into MAP->l_searchlist after MAP
+ but before its dependencies. */
+extern void _dl_map_object_deps (struct link_map *map,
+ struct link_map **preloads,
+ unsigned int npreloads, int trace_mode,
+ int open_mode)
+ internal_function attribute_hidden;
+
+/* Cache the locations of MAP's hash table. */
+extern void _dl_setup_hash (struct link_map *map)
+ internal_function attribute_hidden;
+
+
+/* Collect the directories in the search path for LOADER's dependencies.
+ The data structure is defined in <dlfcn.h>. If COUNTING is true,
+ SI->dls_cnt and SI->dls_size are set; if false, those must be as set
+ by a previous call with COUNTING set, and SI must point to SI->dls_size
+ bytes to be used in filling in the result. */
+extern void _dl_rtld_di_serinfo (struct link_map *loader,
+ Dl_serinfo *si, bool counting)
+ internal_function;
+
+
+/* Search loaded objects' symbol tables for a definition of the symbol
+ referred to by UNDEF. *SYM is the symbol table entry containing the
+ reference; it is replaced with the defining symbol, and the base load
+ address of the defining object is returned. SYMBOL_SCOPE is a
+ null-terminated list of object scopes to search; each object's
+ l_searchlist (i.e. the segment of the dependency tree starting at that
+ object) is searched in turn. REFERENCE_NAME should name the object
+ containing the reference; it is used in error messages.
+ TYPE_CLASS describes the type of symbol we are looking for. */
+enum
+ {
+ /* If necessary add dependency between user and provider object. */
+ DL_LOOKUP_ADD_DEPENDENCY = 1,
+ /* Return most recent version instead of default version for
+ unversioned lookup. */
+ DL_LOOKUP_RETURN_NEWEST = 2
+ };
+
+/* Lookup versioned symbol. */
+extern lookup_t _dl_lookup_symbol_x (const char *undef,
+ struct link_map *undef_map,
+ const ElfW(Sym) **sym,
+ struct r_scope_elem *symbol_scope[],
+ const struct r_found_version *version,
+ int type_class, int explicit,
+ struct link_map *skip_map)
+ internal_function attribute_hidden;
+
+
+/* Look up symbol NAME in MAP's scope and return its run-time address. */
+extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name)
+ internal_function;
+
+/* Allocate a `struct link_map' for a new object being loaded,
+ and enter it into the _dl_main_map list. */
+extern struct link_map *_dl_new_object (char *realname, const char *libname,
+ int type, struct link_map *loader,
+ int mode, Lmid_t nsid)
+ internal_function attribute_hidden;
+
+/* Relocate the given object (if it hasn't already been).
+ SCOPE is passed to _dl_lookup_symbol in symbol lookups.
+ If LAZY is nonzero, don't relocate its PLT. */
+extern void _dl_relocate_object (struct link_map *map,
+ struct r_scope_elem *scope[],
+ int lazy, int consider_profiling)
+ attribute_hidden;
+
+/* Protect PT_GNU_RELRO area. */
+extern void _dl_protect_relro (struct link_map *map)
+ internal_function attribute_hidden;
+
+/* Call _dl_signal_error with a message about an unhandled reloc type.
+ TYPE is the result of ELFW(R_TYPE) (r_info), i.e. an R_<CPU>_* value.
+ PLT is nonzero if this was a PLT reloc; it just affects the message. */
+extern void _dl_reloc_bad_type (struct link_map *map,
+ unsigned int type, int plt)
+ internal_function __attribute__ ((__noreturn__));
+
+/* Resolve conflicts if prelinking. */
+extern void _dl_resolve_conflicts (struct link_map *l,
+ ElfW(Rela) *conflict,
+ ElfW(Rela) *conflictend);
+
+/* Check the version dependencies of all objects available through
+ MAP. If VERBOSE print some more diagnostics. */
+extern int _dl_check_all_versions (struct link_map *map, int verbose,
+ int trace_mode)
+ internal_function;
+
+/* Check the version dependencies for MAP. If VERBOSE print some more
+ diagnostics. */
+extern int _dl_check_map_versions (struct link_map *map, int verbose,
+ int trace_mode)
+ internal_function;
+
+/* Initialize the object in SCOPE by calling the constructors with
+ ARGC, ARGV, and ENV as the parameters. */
+extern void _dl_init (struct link_map *main_map, int argc, char **argv,
+ char **env) internal_function attribute_hidden;
+
+/* Call the finalizer functions of all shared objects whose
+ initializer functions have completed. */
+extern void _dl_fini (void) internal_function;
+
+/* Sort array MAPS according to dependencies of the contained objects. */
+extern void _dl_sort_fini (struct link_map *l, struct link_map **maps,
+ size_t nmaps, char *used, Lmid_t ns)
+ internal_function;
+
+/* The dynamic linker calls this function before and having changing
+ any shared object mappings. The `r_state' member of `struct r_debug'
+ says what change is taking place. This function's address is
+ the value of the `r_brk' member. */
+extern void _dl_debug_state (void);
+rtld_hidden_proto (_dl_debug_state)
+
+/* Initialize `struct r_debug' if it has not already been done. The
+ argument is the run-time load address of the dynamic linker, to be put
+ in the `r_ldbase' member. Returns the address of the structure. */
+extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns)
+ internal_function;
+
+/* Initialize the basic data structure for the search paths. */
+extern void _dl_init_paths (const char *library_path) internal_function;
+
+/* Gather the information needed to install the profiling tables and start
+ the timers. */
+extern void _dl_start_profile (void) internal_function attribute_hidden;
+
+/* The actual functions used to keep book on the calls. */
+extern void _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc);
+extern void _dl_mcount_internal (ElfW(Addr) frompc, ElfW(Addr) selfpc)
+ attribute_hidden;
+
+/* This function is simply a wrapper around the _dl_mcount function
+ which does not require a FROMPC parameter since this is the
+ calling function. */
+extern void _dl_mcount_wrapper (void *selfpc);
+
+/* Show the members of the auxiliary array passed up from the kernel. */
+extern void _dl_show_auxv (void) internal_function;
+
+/* Return all environment variables starting with `LD_', one after the
+ other. */
+extern char *_dl_next_ld_env_entry (char ***position) internal_function;
+
+/* Return an array with the names of the important hardware capabilities. */
+extern const struct r_strlenpair *_dl_important_hwcaps (const char *platform,
+ size_t paltform_len,
+ size_t *sz,
+ size_t *max_capstrlen)
+ internal_function;
+
+/* Look up NAME in ld.so.cache and return the file name stored there,
+ or null if none is found. */
+extern const char *_dl_load_cache_lookup (const char *name)
+ internal_function;
+
+/* If the system does not support MAP_COPY we cannot leave the file open
+ all the time since this would create problems when the file is replaced.
+ Therefore we provide this function to close the file and open it again
+ once needed. */
+extern void _dl_unload_cache (void) attribute_hidden;
+
+/* System-dependent function to read a file's whole contents in the
+ most convenient manner available. *SIZEP gets the size of the
+ file. On error MAP_FAILED is returned. */
+extern void *_dl_sysdep_read_whole_file (const char *file, size_t *sizep,
+ int prot)
+ internal_function attribute_hidden;
+
+/* System-specific function to do initial startup for the dynamic linker.
+ After this, file access calls and getenv must work. This is responsible
+ for setting __libc_enable_secure if we need to be secure (e.g. setuid),
+ and for setting _dl_argc and _dl_argv, and then calling _dl_main. */
+extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
+ void (*dl_main) (const ElfW(Phdr) *phdr,
+ ElfW(Word) phnum,
+ ElfW(Addr) *user_entry))
+ attribute_hidden;
+
+extern void _dl_sysdep_start_cleanup (void)
+ internal_function attribute_hidden;
+
+
+/* Determine next available module ID. */
+extern size_t _dl_next_tls_modid (void) internal_function attribute_hidden;
+
+/* Calculate offset of the TLS blocks in the static TLS block. */
+extern void _dl_determine_tlsoffset (void) internal_function attribute_hidden;
+
+/* Set up the data structures for TLS, when they were not set up at startup.
+ Returns nonzero on malloc failure.
+ This is called from _dl_map_object_from_fd or by libpthread. */
+extern int _dl_tls_setup (void) internal_function;
+rtld_hidden_proto (_dl_tls_setup)
+
+/* Allocate memory for static TLS block (unless MEM is nonzero) and dtv. */
+extern void *_dl_allocate_tls (void *mem) internal_function;
+rtld_hidden_proto (_dl_allocate_tls)
+
+/* Get size and alignment requirements of the static TLS block. */
+extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp)
+ internal_function;
+
+extern void _dl_allocate_static_tls (struct link_map *map)
+ internal_function attribute_hidden;
+
+/* These are internal entry points to the two halves of _dl_allocate_tls,
+ only used within rtld.c itself at startup time. */
+extern void *_dl_allocate_tls_storage (void)
+ internal_function attribute_hidden;
+extern void *_dl_allocate_tls_init (void *) internal_function;
+rtld_hidden_proto (_dl_allocate_tls_init)
+
+/* Deallocate memory allocated with _dl_allocate_tls. */
+extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb) internal_function;
+rtld_hidden_proto (_dl_deallocate_tls)
+
+#if defined USE_TLS
+extern void _dl_nothread_init_static_tls (struct link_map *) attribute_hidden;
+#endif
+
+/* Find origin of the executable. */
+extern const char *_dl_get_origin (void) attribute_hidden;
+
+/* Count DSTs. */
+extern size_t _dl_dst_count (const char *name, int is_path) attribute_hidden;
+
+/* Substitute DST values. */
+extern char *_dl_dst_substitute (struct link_map *l, const char *name,
+ char *result, int is_path) attribute_hidden;
+
+/* Check validity of the caller. */
+extern int _dl_check_caller (const void *caller, enum allowmask mask)
+ attribute_hidden;
+
+/* Open the shared object NAME, relocate it, and run its initializer if it
+ hasn't already been run. MODE is as for `dlopen' (see <dlfcn.h>). If
+ the object is already opened, returns its existing map. */
+extern void *_dl_open (const char *name, int mode, const void *caller,
+ Lmid_t nsid, int argc, char *argv[], char *env[])
+ attribute_hidden;
+
+/* Add module to slot information data. */
+extern void _dl_add_to_slotinfo (struct link_map *l) attribute_hidden;
+
+/* Update slot information data for at least the generation of the
+ module with the given index. */
+extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid);
+
+/* Look up the module's TLS block as for __tls_get_addr,
+ but never touch anything. Return null if it's not allocated yet. */
+extern void *_dl_tls_get_addr_soft (struct link_map *l) internal_function;
+
+
+__END_DECLS
+
+#endif /* ldsodefs.h */
diff --git a/libc/sysdeps/generic/libm-test-ulps b/libc/sysdeps/generic/libm-test-ulps
new file mode 100644
index 000000000..7cfa1f828
--- /dev/null
+++ b/libc/sysdeps/generic/libm-test-ulps
@@ -0,0 +1,5 @@
+# File with deltas for math/libm-test
+# This file is the fallback and contains
+# no data
+# You can create a new file with e.g. `test-double -u'
+# followed by `gen-libm-test.pl -u ULPs -n'.
diff --git a/libc/sysdeps/generic/local-setxid.h b/libc/sysdeps/generic/local-setxid.h
new file mode 100644
index 000000000..b70d9ffb3
--- /dev/null
+++ b/libc/sysdeps/generic/local-setxid.h
@@ -0,0 +1,4 @@
+/* No special support. Fall back to the regular functions. */
+
+#define local_seteuid(id) seteuid (id)
+#define local_setegid(id) setegid (id)
diff --git a/libc/sysdeps/generic/machine-gmon.h b/libc/sysdeps/generic/machine-gmon.h
new file mode 100644
index 000000000..eb046b068
--- /dev/null
+++ b/libc/sysdeps/generic/machine-gmon.h
@@ -0,0 +1,54 @@
+/* Machine-dependent definitions for profiling support. Generic GCC 2 version.
+ Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* GCC version 2 gives us a perfect magical function to get
+ just the information we need:
+ void *__builtin_return_address (unsigned int N)
+ returns the return address of the frame N frames up. */
+
+/* Be warned that GCC cannot usefully compile __builtin_return_address(N)
+ for N != 0 on all machines. In this case, you may have to write
+ your own version of _mcount(). */
+
+#if __GNUC__ < 2
+ #error "This file uses __builtin_return_address, a GCC 2 extension."
+#endif
+
+#include <sysdep.h>
+#ifndef NO_UNDERSCORES
+/* The asm symbols for C functions are `_function'.
+ The canonical name for the counter function is `mcount', no _. */
+void _mcount (void) asm ("mcount");
+#else
+/* The canonical name for the function is `_mcount' in both C and asm,
+ but some old asm code might assume it's `mcount'. */
+void _mcount (void);
+weak_alias (_mcount, mcount)
+#endif
+
+static void mcount_internal (u_long frompc, u_long selfpc);
+
+#define _MCOUNT_DECL(frompc, selfpc) \
+static inline void mcount_internal (u_long frompc, u_long selfpc)
+
+#define MCOUNT \
+void _mcount (void) \
+{ \
+ mcount_internal ((u_long) RETURN_ADDRESS (1), (u_long) RETURN_ADDRESS (0)); \
+}
diff --git a/libc/sysdeps/generic/machine-lock.h b/libc/sysdeps/generic/machine-lock.h
new file mode 100644
index 000000000..c7cadf512
--- /dev/null
+++ b/libc/sysdeps/generic/machine-lock.h
@@ -0,0 +1,64 @@
+/* Machine-specific definition for spin locks. Stub version.
+ Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MACHINE_LOCK_H
+#define _MACHINE_LOCK_H
+
+/* The type of a spin lock variable. */
+
+typedef volatile int __spin_lock_t;
+
+/* Value to initialize `__spin_lock_t' variables to. */
+
+#define __SPIN_LOCK_INITIALIZER 0
+
+
+#ifndef _EXTERN_INLINE
+#define _EXTERN_INLINE extern __inline
+#endif
+
+/* Unlock LOCK. */
+
+_EXTERN_INLINE void
+__spin_unlock (__spin_lock_t *__lock)
+{
+ *__lock = 0;
+}
+
+/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */
+
+_EXTERN_INLINE int
+__spin_try_lock (__spin_lock_t *__lock)
+{
+ if (*__lock)
+ return 0;
+ *__lock = 1;
+ return 1;
+}
+
+/* Return nonzero if LOCK is locked. */
+
+_EXTERN_INLINE int
+__spin_lock_locked (__spin_lock_t *__lock)
+{
+ return *__lock != 0;
+}
+
+
+#endif /* machine-lock.h */
diff --git a/libc/sysdeps/generic/machine-sp.h b/libc/sysdeps/generic/machine-sp.h
new file mode 100644
index 000000000..a8be7c0f6
--- /dev/null
+++ b/libc/sysdeps/generic/machine-sp.h
@@ -0,0 +1,36 @@
+/* Machine-specific function to return the stack pointer. Stub version.
+ Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MACHINE_SP_H
+#define _MACHINE_SP_H
+
+/* Return the current stack pointer. */
+
+#ifndef _EXTERN_INLINE
+#define _EXTERN_INLINE extern __inline
+#endif
+
+_EXTERN_INLINE void *
+__thread_stack_pointer (void)
+{
+ register void *__sp__ ("{STACK-POINTER}");
+ return __sp__;
+}
+
+#endif /* machine-sp.h */
diff --git a/libc/sysdeps/generic/malloc-machine.h b/libc/sysdeps/generic/malloc-machine.h
new file mode 100644
index 000000000..345137060
--- /dev/null
+++ b/libc/sysdeps/generic/malloc-machine.h
@@ -0,0 +1,68 @@
+/* Basic platform-independent macro definitions for mutexes,
+ thread-specific data and parameters for malloc.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _GENERIC_MALLOC_MACHINE_H
+#define _GENERIC_MALLOC_MACHINE_H
+
+#include <atomic.h>
+
+#ifndef mutex_init /* No threads, provide dummy macros */
+
+# define NO_THREADS
+
+/* The mutex functions used to do absolutely nothing, i.e. lock,
+ trylock and unlock would always just return 0. However, even
+ without any concurrently active threads, a mutex can be used
+ legitimately as an `in use' flag. To make the code that is
+ protected by a mutex async-signal safe, these macros would have to
+ be based on atomic test-and-set operations, for example. */
+typedef int mutex_t;
+
+# define mutex_init(m) (*(m) = 0)
+# define mutex_lock(m) ((*(m) = 1), 0)
+# define mutex_trylock(m) (*(m) ? 1 : ((*(m) = 1), 0))
+# define mutex_unlock(m) (*(m) = 0)
+
+typedef void *tsd_key_t;
+# define tsd_key_create(key, destr) do {} while(0)
+# define tsd_setspecific(key, data) ((key) = (data))
+# define tsd_getspecific(key, vptr) (vptr = (key))
+
+# define thread_atfork(prepare, parent, child) do {} while(0)
+
+#endif /* !defined mutex_init */
+
+#ifndef atomic_full_barrier
+# define atomic_full_barrier() __asm ("" ::: "memory")
+#endif
+
+#ifndef atomic_read_barrier
+# define atomic_read_barrier() atomic_full_barrier ()
+#endif
+
+#ifndef atomic_write_barrier
+# define atomic_write_barrier() atomic_full_barrier ()
+#endif
+
+#ifndef DEFAULT_TOP_PAD
+# define DEFAULT_TOP_PAD 131072
+#endif
+
+#endif /* !defined(_GENERIC_MALLOC_MACHINE_H) */
diff --git a/libc/sysdeps/generic/math_ldbl.h b/libc/sysdeps/generic/math_ldbl.h
new file mode 100644
index 000000000..f0b97ef8f
--- /dev/null
+++ b/libc/sysdeps/generic/math_ldbl.h
@@ -0,0 +1,5 @@
+#ifndef _MATH_PRIVATE_H_
+#error "Never use <math_ldbl.h> directly; include <math_private.h> instead."
+#endif
+
+/* This is empty. Any machine using long double type will override this header. */
diff --git a/libc/sysdeps/generic/math_ldbl_opt.h b/libc/sysdeps/generic/math_ldbl_opt.h
new file mode 100644
index 000000000..8a5d8ba10
--- /dev/null
+++ b/libc/sysdeps/generic/math_ldbl_opt.h
@@ -0,0 +1,14 @@
+/* -mlong-double-64 compatibility mode macros. Stub version.
+
+ These macros are used by some math/ and sysdeps/ieee754/ code.
+ These are the generic definitions for when no funny business is going on.
+ sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h defines them differently
+ for platforms where compatibility symbols are required for a previous
+ ABI that defined long double functions as aliases for the double code. */
+
+#define LONG_DOUBLE_COMPAT(lib, introduced) 0
+#define long_double_symbol(lib, local, symbol)
+#define ldbl_hidden_def(local, name) libc_hidden_def (name)
+#define ldbl_strong_alias(name, aliasname) strong_alias (name, aliasname)
+#define ldbl_weak_alias(name, aliasname) weak_alias (name, aliasname)
+#define __ldbl_is_dbl 0
diff --git a/libc/sysdeps/generic/memcopy.h b/libc/sysdeps/generic/memcopy.h
new file mode 100644
index 000000000..bc5c18d4a
--- /dev/null
+++ b/libc/sysdeps/generic/memcopy.h
@@ -0,0 +1,150 @@
+/* memcopy.h -- definitions for memory copy functions. Generic C version.
+ Copyright (C) 1991, 1992, 1993, 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The strategy of the memory functions is:
+
+ 1. Copy bytes until the destination pointer is aligned.
+
+ 2. Copy words in unrolled loops. If the source and destination
+ are not aligned in the same way, use word memory operations,
+ but shift and merge two read words before writing.
+
+ 3. Copy the few remaining bytes.
+
+ This is fast on processors that have at least 10 registers for
+ allocation by GCC, and that can access memory at reg+const in one
+ instruction.
+
+ I made an "exhaustive" test of this memmove when I wrote it,
+ exhaustive in the sense that I tried all alignment and length
+ combinations, with and without overlap. */
+
+#include <sys/cdefs.h>
+#include <endian.h>
+
+/* The macros defined in this file are:
+
+ BYTE_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_to_copy)
+
+ BYTE_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_to_copy)
+
+ WORD_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_remaining, nbytes_to_copy)
+
+ WORD_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_remaining, nbytes_to_copy)
+
+ MERGE(old_word, sh_1, new_word, sh_2)
+ [I fail to understand. I feel stupid. --roland]
+*/
+
+/* Type to use for aligned memory operations.
+ This should normally be the biggest type supported by a single load
+ and store. */
+#define op_t unsigned long int
+#define OPSIZ (sizeof(op_t))
+
+/* Type to use for unaligned operations. */
+typedef unsigned char byte;
+
+/* Optimal type for storing bytes in registers. */
+#define reg_char char
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
+#endif
+
+/* Copy exactly NBYTES bytes from SRC_BP to DST_BP,
+ without any assumptions about alignment of the pointers. */
+#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \
+ do \
+ { \
+ size_t __nbytes = (nbytes); \
+ while (__nbytes > 0) \
+ { \
+ byte __x = ((byte *) src_bp)[0]; \
+ src_bp += 1; \
+ __nbytes -= 1; \
+ ((byte *) dst_bp)[0] = __x; \
+ dst_bp += 1; \
+ } \
+ } while (0)
+
+/* Copy exactly NBYTES_TO_COPY bytes from SRC_END_PTR to DST_END_PTR,
+ beginning at the bytes right before the pointers and continuing towards
+ smaller addresses. Don't assume anything about alignment of the
+ pointers. */
+#define BYTE_COPY_BWD(dst_ep, src_ep, nbytes) \
+ do \
+ { \
+ size_t __nbytes = (nbytes); \
+ while (__nbytes > 0) \
+ { \
+ byte __x; \
+ src_ep -= 1; \
+ __x = ((byte *) src_ep)[0]; \
+ dst_ep -= 1; \
+ __nbytes -= 1; \
+ ((byte *) dst_ep)[0] = __x; \
+ } \
+ } while (0)
+
+/* Copy *up to* NBYTES bytes from SRC_BP to DST_BP, with
+ the assumption that DST_BP is aligned on an OPSIZ multiple. If
+ not all bytes could be easily copied, store remaining number of bytes
+ in NBYTES_LEFT, otherwise store 0. */
+extern void _wordcopy_fwd_aligned (long int, long int, size_t) __THROW;
+extern void _wordcopy_fwd_dest_aligned (long int, long int, size_t) __THROW;
+#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \
+ do \
+ { \
+ if (src_bp % OPSIZ == 0) \
+ _wordcopy_fwd_aligned (dst_bp, src_bp, (nbytes) / OPSIZ); \
+ else \
+ _wordcopy_fwd_dest_aligned (dst_bp, src_bp, (nbytes) / OPSIZ); \
+ src_bp += (nbytes) & -OPSIZ; \
+ dst_bp += (nbytes) & -OPSIZ; \
+ (nbytes_left) = (nbytes) % OPSIZ; \
+ } while (0)
+
+/* Copy *up to* NBYTES_TO_COPY bytes from SRC_END_PTR to DST_END_PTR,
+ beginning at the words (of type op_t) right before the pointers and
+ continuing towards smaller addresses. May take advantage of that
+ DST_END_PTR is aligned on an OPSIZ multiple. If not all bytes could be
+ easily copied, store remaining number of bytes in NBYTES_REMAINING,
+ otherwise store 0. */
+extern void _wordcopy_bwd_aligned (long int, long int, size_t) __THROW;
+extern void _wordcopy_bwd_dest_aligned (long int, long int, size_t) __THROW;
+#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes) \
+ do \
+ { \
+ if (src_ep % OPSIZ == 0) \
+ _wordcopy_bwd_aligned (dst_ep, src_ep, (nbytes) / OPSIZ); \
+ else \
+ _wordcopy_bwd_dest_aligned (dst_ep, src_ep, (nbytes) / OPSIZ); \
+ src_ep -= (nbytes) & -OPSIZ; \
+ dst_ep -= (nbytes) & -OPSIZ; \
+ (nbytes_left) = (nbytes) % OPSIZ; \
+ } while (0)
+
+
+/* Threshold value for when to enter the unrolled loops. */
+#define OP_T_THRES 16
diff --git a/libc/sysdeps/generic/memusage.h b/libc/sysdeps/generic/memusage.h
new file mode 100644
index 000000000..a1205cec5
--- /dev/null
+++ b/libc/sysdeps/generic/memusage.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#include <limits.h>
+#include <atomic.h>
+
+#ifndef GETSP
+# warning "GETSP is not defined for this architecture."
+# define GETSP 0
+#endif
+
+#ifndef GETTIME
+# define GETTIME(low,high) \
+ { \
+ struct timeval tval; \
+ uint64_t usecs; \
+ gettimeofday (&tval, NULL); \
+ usecs = (uint64_t) tval.tv_usec + (uint64_t) tval.tv_usec * 1000000; \
+ low = usecs & 0xffffffff; \
+ high = usecs >> 32; \
+ }
+#endif
+
+#if LONG_BIT == 32
+# define memusage_cntr_t uatomic32_t
+#else
+# define memusage_cntr_t uatomic64_t
+#endif
+#ifndef memusage_size_t
+# if LONG_BIT == 32
+# define memusage_size_t uatomic32_t
+# else
+# define memusage_size_t uatomic64_t
+# endif
+#endif
diff --git a/libc/sysdeps/generic/net/if.h b/libc/sysdeps/generic/net/if.h
new file mode 100644
index 000000000..a497d0861
--- /dev/null
+++ b/libc/sysdeps/generic/net/if.h
@@ -0,0 +1,50 @@
+/* net/if.h -- declarations for inquiring about network interfaces
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NET_IF_H
+
+#define _NET_IF_H 1
+#include <features.h>
+
+
+__BEGIN_DECLS
+
+/* Convert an interface name to an index, and vice versa. */
+
+extern unsigned int if_nametoindex (__const char *__ifname) __THROW;
+extern char *if_indextoname (unsigned int __ifindex, char *__ifname) __THROW;
+
+/* Return a list of all interfaces and their indices. */
+
+struct if_nameindex
+ {
+ unsigned int if_index; /* 1, 2, ... */
+ char *if_name; /* null terminated name: "eth0", ... */
+ };
+
+extern struct if_nameindex *if_nameindex (void) __THROW;
+
+/* Free the data returned from if_nameindex. */
+
+extern void if_freenameindex (struct if_nameindex *__ptr) __THROW;
+
+__END_DECLS
+
+
+#endif /* net/if.h */
diff --git a/libc/sysdeps/generic/netinet/if_ether.h b/libc/sysdeps/generic/netinet/if_ether.h
new file mode 100644
index 000000000..7f66b571f
--- /dev/null
+++ b/libc/sysdeps/generic/netinet/if_ether.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __NETINET_IF_ETHER_H
+
+#define __NETINET_IF_ETHER_H 1
+#include <features.h>
+
+#include <sys/types.h>
+
+/* This is a name for the 48 bit ethernet address available on many
+ systems. */
+struct ether_addr
+{
+ u_int8_t ether_addr_octet[6];
+} __attribute__ ((__packed__));
+
+#endif /* netinet/if_ether.h */
diff --git a/libc/sysdeps/generic/netinet/in_systm.h b/libc/sysdeps/generic/netinet/in_systm.h
new file mode 100644
index 000000000..51a08e176
--- /dev/null
+++ b/libc/sysdeps/generic/netinet/in_systm.h
@@ -0,0 +1,41 @@
+/* System specific type definitions for networking code.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NETINET_IN_SYSTM_H
+#define _NETINET_IN_SYSTM_H 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+/*
+ * Network order versions of various data types. Unfortunately, BSD
+ * assumes specific sizes for shorts (16 bit) and longs (32 bit) which
+ * don't hold in general. As a consequence, the network order versions
+ * may not reflect the actual size of the native data types.
+ */
+
+typedef u_int16_t n_short; /* short as received from the net */
+typedef u_int32_t n_long; /* long as received from the net */
+typedef u_int32_t n_time; /* ms since 00:00 GMT, byte rev */
+
+__END_DECLS
+
+#endif /* netinet/in_systm.h */
diff --git a/libc/sysdeps/generic/netinet/ip.h b/libc/sysdeps/generic/netinet/ip.h
new file mode 100644
index 000000000..fc9144052
--- /dev/null
+++ b/libc/sysdeps/generic/netinet/ip.h
@@ -0,0 +1,249 @@
+/* Copyright (C) 1991,92,93,95,96,97,98,99,2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __NETINET_IP_H
+#define __NETINET_IP_H 1
+
+#include <features.h>
+#include <sys/types.h>
+
+#include <netinet/in.h>
+
+__BEGIN_DECLS
+
+struct timestamp
+ {
+ u_int8_t len;
+ u_int8_t ptr;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int flags:4;
+ unsigned int overflow:4;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int overflow:4;
+ unsigned int flags:4;
+#else
+# error "Please fix <bits/endian.h>"
+#endif
+ u_int32_t data[9];
+ };
+
+struct iphdr
+ {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ihl:4;
+ unsigned int version:4;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int version:4;
+ unsigned int ihl:4;
+#else
+# error "Please fix <bits/endian.h>"
+#endif
+ u_int8_t tos;
+ u_int16_t tot_len;
+ u_int16_t id;
+ u_int16_t frag_off;
+ u_int8_t ttl;
+ u_int8_t protocol;
+ u_int16_t check;
+ u_int32_t saddr;
+ u_int32_t daddr;
+ /*The options start here. */
+ };
+
+#ifdef __USE_BSD
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)ip.h 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Definitions for internet protocol version 4.
+ * Per RFC 791, September 1981.
+ */
+
+/*
+ * Structure of an internet header, naked of options.
+ */
+struct ip
+ {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ip_hl:4; /* header length */
+ unsigned int ip_v:4; /* version */
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int ip_v:4; /* version */
+ unsigned int ip_hl:4; /* header length */
+#endif
+ u_int8_t ip_tos; /* type of service */
+ u_short ip_len; /* total length */
+ u_short ip_id; /* identification */
+ u_short ip_off; /* fragment offset field */
+#define IP_RF 0x8000 /* reserved fragment flag */
+#define IP_DF 0x4000 /* dont fragment flag */
+#define IP_MF 0x2000 /* more fragments flag */
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ u_int8_t ip_ttl; /* time to live */
+ u_int8_t ip_p; /* protocol */
+ u_short ip_sum; /* checksum */
+ struct in_addr ip_src, ip_dst; /* source and dest address */
+ };
+
+/*
+ * Time stamp option structure.
+ */
+struct ip_timestamp
+ {
+ u_int8_t ipt_code; /* IPOPT_TS */
+ u_int8_t ipt_len; /* size of structure (variable) */
+ u_int8_t ipt_ptr; /* index of current entry */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ipt_flg:4; /* flags, see below */
+ unsigned int ipt_oflw:4; /* overflow counter */
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int ipt_oflw:4; /* overflow counter */
+ unsigned int ipt_flg:4; /* flags, see below */
+#endif
+ u_int32_t data[9];
+ };
+#endif /* __USE_BSD */
+
+#define IPVERSION 4 /* IP version number */
+#define IP_MAXPACKET 65535 /* maximum packet size */
+
+/*
+ * Definitions for IP type of service (ip_tos)
+ */
+#define IPTOS_TOS_MASK 0x1E
+#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_RELIABILITY 0x04
+#define IPTOS_LOWCOST 0x02
+#define IPTOS_MINCOST IPTOS_LOWCOST
+
+/*
+ * Definitions for IP precedence (also in ip_tos) (hopefully unused)
+ */
+#define IPTOS_PREC_MASK 0xe0
+#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK)
+#define IPTOS_PREC_NETCONTROL 0xe0
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+#define IPTOS_PREC_CRITIC_ECP 0xa0
+#define IPTOS_PREC_FLASHOVERRIDE 0x80
+#define IPTOS_PREC_FLASH 0x60
+#define IPTOS_PREC_IMMEDIATE 0x40
+#define IPTOS_PREC_PRIORITY 0x20
+#define IPTOS_PREC_ROUTINE 0x00
+
+/*
+ * Definitions for options.
+ */
+#define IPOPT_COPY 0x80
+#define IPOPT_CLASS_MASK 0x60
+#define IPOPT_NUMBER_MASK 0x1f
+
+#define IPOPT_COPIED(o) ((o) & IPOPT_COPY)
+#define IPOPT_CLASS(o) ((o) & IPOPT_CLASS_MASK)
+#define IPOPT_NUMBER(o) ((o) & IPOPT_NUMBER_MASK)
+
+#define IPOPT_CONTROL 0x00
+#define IPOPT_RESERVED1 0x20
+#define IPOPT_DEBMEAS 0x40
+#define IPOPT_MEASUREMENT IPOPT_DEBMEAS
+#define IPOPT_RESERVED2 0x60
+
+#define IPOPT_EOL 0 /* end of option list */
+#define IPOPT_END IPOPT_EOL
+#define IPOPT_NOP 1 /* no operation */
+#define IPOPT_NOOP IPOPT_NOP
+
+#define IPOPT_RR 7 /* record packet route */
+#define IPOPT_TS 68 /* timestamp */
+#define IPOPT_TIMESTAMP IPOPT_TS
+#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
+#define IPOPT_SEC IPOPT_SECURITY
+#define IPOPT_LSRR 131 /* loose source route */
+#define IPOPT_SATID 136 /* satnet id */
+#define IPOPT_SID IPOPT_SATID
+#define IPOPT_SSRR 137 /* strict source route */
+#define IPOPT_RA 148 /* router alert */
+
+/*
+ * Offsets to fields in options other than EOL and NOP.
+ */
+#define IPOPT_OPTVAL 0 /* option ID */
+#define IPOPT_OLEN 1 /* option length */
+#define IPOPT_OFFSET 2 /* offset within option */
+#define IPOPT_MINOFF 4 /* min value of above */
+
+#define MAX_IPOPTLEN 40
+
+/* flag bits for ipt_flg */
+#define IPOPT_TS_TSONLY 0 /* timestamps only */
+#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
+#define IPOPT_TS_PRESPEC 3 /* specified modules only */
+
+/* bits for security (not byte swapped) */
+#define IPOPT_SECUR_UNCLASS 0x0000
+#define IPOPT_SECUR_CONFID 0xf135
+#define IPOPT_SECUR_EFTO 0x789a
+#define IPOPT_SECUR_MMMM 0xbc4d
+#define IPOPT_SECUR_RESTR 0xaf13
+#define IPOPT_SECUR_SECRET 0xd788
+#define IPOPT_SECUR_TOPSECRET 0x6bc5
+
+/*
+ * Internet implementation parameters.
+ */
+#define MAXTTL 255 /* maximum time to live (seconds) */
+#define IPDEFTTL 64 /* default ttl, from RFC 1340 */
+#define IPFRAGTTL 60 /* time to live for frags, slowhz */
+#define IPTTLDEC 1 /* subtracted when forwarding */
+
+#define IP_MSS 576 /* default maximum segment size */
+
+__END_DECLS
+
+#endif /* netinet/ip.h */
diff --git a/libc/sysdeps/generic/netinet/tcp.h b/libc/sysdeps/generic/netinet/tcp.h
new file mode 100644
index 000000000..0d7190330
--- /dev/null
+++ b/libc/sysdeps/generic/netinet/tcp.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_TCP_H
+
+#define _NETINET_TCP_H 1
+#include <sys/cdefs.h>
+
+
+__BEGIN_DECLS
+
+typedef unsigned int tcp_seq;
+/*
+ * TCP header.
+ * Per RFC 793, September, 1981.
+ */
+struct tcphdr {
+ u_short th_sport; /* source port */
+ u_short th_dport; /* destination port */
+ tcp_seq th_seq; /* sequence number */
+ tcp_seq th_ack; /* acknowledgement number */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ u_char th_x2:4, /* (unused) */
+ th_off:4; /* data offset */
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN
+ u_char th_off:4, /* data offset */
+ th_x2:4; /* (unused) */
+#endif
+ u_char th_flags;
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+ u_short th_win; /* window */
+ u_short th_sum; /* checksum */
+ u_short th_urp; /* urgent pointer */
+};
+
+#define TCPOPT_EOL 0
+#define TCPOPT_NOP 1
+#define TCPOPT_MAXSEG 2
+#define TCPOLEN_MAXSEG 4
+#define TCPOPT_WINDOW 3
+#define TCPOLEN_WINDOW 3
+#define TCPOPT_SACK_PERMITTED 4 /* Experimental */
+#define TCPOLEN_SACK_PERMITTED 2
+#define TCPOPT_SACK 5 /* Experimental */
+#define TCPOPT_TIMESTAMP 8
+#define TCPOLEN_TIMESTAMP 10
+#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
+
+#define TCPOPT_TSTAMP_HDR \
+ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
+
+/*
+ * Default maximum segment size for TCP.
+ * With an IP MSS of 576, this is 536,
+ * but 512 is probably more convenient.
+ * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
+ */
+#define TCP_MSS 512
+
+#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */
+
+#define TCP_MAX_WINSHIFT 14 /* maximum window shift */
+
+/*
+ * User-settable options (used with setsockopt).
+ */
+#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
+#define TCP_MAXSEG 0x02 /* set maximum segment size */
+
+#define SOL_TCP 6 /* TCP level */
+
+__END_DECLS
+
+#endif /* netinet/tcp.h */
diff --git a/libc/sysdeps/generic/nfs/nfs.h b/libc/sysdeps/generic/nfs/nfs.h
new file mode 100644
index 000000000..e83a874fe
--- /dev/null
+++ b/libc/sysdeps/generic/nfs/nfs.h
@@ -0,0 +1,32 @@
+/* <nfs/nfs.h> -- ill-specified NFS-related definitions
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NFS_NFS_H
+#define _NFS_NFS_H 1
+
+/* This file is empty for now. Its contents do not seem to be
+ standardized in any way. It exists solely for the sake of
+ <rpcsvc/bootparam_prot.h> which insists on including <nfs/nfs.h>.
+
+ For the time being, we just provide this file here to smooth building
+ the libc distribution (i.e. librpcsvc). We do not install this file for
+ users, since we haven't really figured out what the right thing to go
+ here is. */
+
+#endif /* nfs/nfs.h */
diff --git a/libc/sysdeps/generic/not-cancel.h b/libc/sysdeps/generic/not-cancel.h
new file mode 100644
index 000000000..427be6475
--- /dev/null
+++ b/libc/sysdeps/generic/not-cancel.h
@@ -0,0 +1,47 @@
+/* Uncancelable versions of cancelable interfaces. Generic version.
+ Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* By default we have none. Map the name to the normal functions. */
+#define open_not_cancel(name, flags, mode) \
+ __libc_open (name, flags, mode)
+#define open_not_cancel_2(name, flags) \
+ __libc_open (name, flags)
+#define openat_not_cancel(fd, name, flags, mode) \
+ __openat (fd, name, flags, mode)
+#define openat_not_cancel_3(fd, name, flags) \
+ __openat (fd, name, flags, 0)
+#define openat64_not_cancel(fd, name, flags, mode) \
+ __openat64 (fd, name, flags, mode)
+#define openat64_not_cancel_3(fd, name, flags) \
+ __openat64 (fd, name, flags, 0)
+#define close_not_cancel(fd) \
+ __close (fd)
+#define close_not_cancel_no_status(fd) \
+ (void) __close (fd)
+#define read_not_cancel(fd, buf, n) \
+ __read (fd, buf, n)
+#define write_not_cancel(fd, buf, n) \
+ __write (fd, buf, n)
+#define writev_not_cancel_no_status(fd, iov, n) \
+ (void) __writev (fd, iov, n)
+#define fcntl_not_cancel(fd, cmd, val) \
+ __fcntl (fd, cmd, val)
+# define waitpid_not_cancel(pid, stat_loc, options) \
+ __waitpid (pid, stat_loc, options)
diff --git a/libc/sysdeps/generic/nscd-types.h b/libc/sysdeps/generic/nscd-types.h
new file mode 100644
index 000000000..dbe43b8bc
--- /dev/null
+++ b/libc/sysdeps/generic/nscd-types.h
@@ -0,0 +1,22 @@
+/* Types for the NSCD implementation. Generic version.
+ Copyright (c) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+
+typedef int32_t nscd_ssize_t;
diff --git a/libc/sysdeps/generic/pagecopy.h b/libc/sysdeps/generic/pagecopy.h
new file mode 100644
index 000000000..5a0ada1fa
--- /dev/null
+++ b/libc/sysdeps/generic/pagecopy.h
@@ -0,0 +1,75 @@
+/* Macros for copying by pages; used in memcpy, memmove. Generic macros.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file defines the macro:
+
+ PAGE_COPY_FWD_MAYBE (dstp, srcp, nbytes_left, nbytes)
+
+ which is invoked like WORD_COPY_FWD et al. The pointers should be at
+ least word aligned. This will check if virtual copying by pages can and
+ should be done and do it if so.
+
+ System-specific pagecopy.h files should define these macros and then
+ #include this file:
+
+ PAGE_COPY_THRESHOLD
+ -- Minimum size for which virtual copying by pages is worthwhile.
+
+ PAGE_SIZE
+ -- Size of a page.
+
+ PAGE_COPY_FWD (dstp, srcp, nbytes_left, nbytes)
+ -- Macro to perform the virtual copy operation.
+ The pointers will be aligned to PAGE_SIZE bytes.
+*/
+
+
+#if PAGE_COPY_THRESHOLD
+
+#include <assert.h>
+
+#define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes) \
+ do \
+ { \
+ if ((nbytes) >= PAGE_COPY_THRESHOLD && \
+ PAGE_OFFSET ((dstp) - (srcp)) == 0) \
+ { \
+ /* The amount to copy is past the threshold for copying \
+ pages virtually with kernel VM operations, and the \
+ source and destination addresses have the same alignment. */ \
+ size_t nbytes_before = PAGE_OFFSET (-(dstp)); \
+ if (nbytes_before != 0) \
+ { \
+ /* First copy the words before the first page boundary. */ \
+ WORD_COPY_FWD (dstp, srcp, nbytes_left, nbytes_before); \
+ assert (nbytes_left == 0); \
+ nbytes -= nbytes_before; \
+ } \
+ PAGE_COPY_FWD (dstp, srcp, nbytes_left, nbytes); \
+ } \
+ } while (0)
+
+/* The page size is always a power of two, so we can avoid modulo division. */
+#define PAGE_OFFSET(n) ((n) & (PAGE_SIZE - 1))
+
+#else
+
+#define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes) /* nada */
+
+#endif
diff --git a/libc/sysdeps/generic/paths.h b/libc/sysdeps/generic/paths.h
new file mode 100644
index 000000000..03bf0f355
--- /dev/null
+++ b/libc/sysdeps/generic/paths.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)paths.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _PATHS_H_
+#define _PATHS_H_
+
+/* Default search path. */
+#define _PATH_DEFPATH "/usr/bin:/bin"
+/* All standard utilities path. */
+#define _PATH_STDPATH \
+ "/usr/bin:/bin:/usr/sbin:/sbin:/usr/contrib/bin:/usr/old/bin"
+
+#define _PATH_BSHELL "/bin/sh"
+#define _PATH_CONSOLE "/dev/console"
+#define _PATH_CSHELL "/bin/csh"
+#define _PATH_DEVDB "/var/run/dev.db"
+#define _PATH_DEVNULL "/dev/null"
+#define _PATH_DRUM "/dev/drum"
+#define _PATH_KMEM "/dev/kmem"
+#define _PATH_MAILDIR "/var/mail"
+#define _PATH_LASTLOG "/var/log/lastlog"
+#define _PATH_MAN "/usr/man"
+#define _PATH_MEM "/dev/mem"
+#define _PATH_MNTTAB "/etc/fstab"
+#define _PATH_MOUNTED "/var/run/mtab"
+#define _PATH_NOLOGIN "/etc/nologin"
+#define _PATH_PRESERVE "/var/preserve"
+#define _PATH_RWHODIR "/var/rwho"
+#define _PATH_SENDMAIL "/usr/sbin/sendmail"
+#define _PATH_SHADOW "/etc/shadow"
+#define _PATH_SHELLS "/etc/shells"
+#define _PATH_TTY "/dev/tty"
+#define _PATH_UNIX "/vmunix"
+#define _PATH_UTMP "/var/run/utmp"
+#define _PATH_UTMP_DB "/var/run/utmp.db"
+#define _PATH_VI "/usr/bin/vi"
+#define _PATH_WTMP "/var/log/wtmp"
+
+/* Provide trailing slash, since mostly used for building pathnames. */
+#define _PATH_DEV "/dev/"
+#define _PATH_TMP "/tmp/"
+#define _PATH_VARDB "/var/db/"
+#define _PATH_VARRUN "/var/run/"
+#define _PATH_VARTMP "/var/tmp/"
+
+#endif /* !_PATHS_H_ */
diff --git a/libc/sysdeps/generic/profil-counter.h b/libc/sysdeps/generic/profil-counter.h
new file mode 100644
index 000000000..9cae5840d
--- /dev/null
+++ b/libc/sysdeps/generic/profil-counter.h
@@ -0,0 +1,27 @@
+/* Machine-dependent SIGPROF signal handler. "Generic" version w/ sigcontext
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* In many Unix systems signal handlers are called like this
+ and the interrupted PC is easily findable in the `struct sigcontext'. */
+
+static void
+profil_counter (int signr, int code, struct sigcontext *scp)
+{
+ profil_count ((void *) scp->sc_pc);
+}
diff --git a/libc/sysdeps/generic/pty-private.h b/libc/sysdeps/generic/pty-private.h
new file mode 100644
index 000000000..d6ec2cee6
--- /dev/null
+++ b/libc/sysdeps/generic/pty-private.h
@@ -0,0 +1,45 @@
+/* Internal defenitions and declarations for pseudo terminal functions.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _PTY_PRIVATE_H
+#define _PTY_PRIVATE_H 1
+
+/* The group slave pseudo terminals belong to. */
+#define TTY_GROUP "tty"
+
+/* The file descriptor connected to the master pseudo terminal. */
+#define PTY_FILENO 3
+
+/* Path to the helper program that implements `grantpt' in user space. */
+#define _PATH_PT_CHOWN LIBEXECDIR "/pt_chown"
+
+/* Test whether given TTY is really a Unix98 pseudo terminal. */
+/* #define unix98_pseudo_p(Dev) ... */
+
+/* Exit codes for the helper program. */
+enum /* failure modes */
+{
+ FAIL_EBADF = 1,
+ FAIL_EINVAL,
+ FAIL_EACCES,
+ FAIL_EXEC
+};
+
+#endif /* pty-private.h */
diff --git a/libc/sysdeps/generic/register-dump.h b/libc/sysdeps/generic/register-dump.h
new file mode 100644
index 000000000..41388bc20
--- /dev/null
+++ b/libc/sysdeps/generic/register-dump.h
@@ -0,0 +1,21 @@
+/* Dump registers.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* In general we cannot do anything. */
diff --git a/libc/sysdeps/generic/sigcontextinfo.h b/libc/sysdeps/generic/sigcontextinfo.h
new file mode 100644
index 000000000..40305b488
--- /dev/null
+++ b/libc/sysdeps/generic/sigcontextinfo.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* In general we cannot provide any information. */
+#define SIGCONTEXT struct sigcontext *
+#define SIGCONTEXT_EXTRA_ARGS
+#define GET_PC(ctx) ((void *) 0)
+#define GET_FRAME(ctx) ((void *) 0)
+#define GET_STACK(ctx) ((void *) 0)
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/libc/sysdeps/generic/siglist.h b/libc/sysdeps/generic/siglist.h
new file mode 100644
index 000000000..dacd4a1f2
--- /dev/null
+++ b/libc/sysdeps/generic/siglist.h
@@ -0,0 +1,75 @@
+/* Canonical list of all signal names.
+ Copyright (C) 1996,97,98,99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file should be usable for any platform, since it just associates
+ the SIG* macros with text names and descriptions. The actual values
+ come from <bits/signum.h> (via <signal.h>). For any signal macros do not
+ exist on every platform, we can use #ifdef tests here and still use
+ this single common file for all platforms. */
+
+/* This file is included multiple times. */
+
+/* Standard signals */
+ init_sig (SIGHUP, "HUP", N_("Hangup"))
+ init_sig (SIGINT, "INT", N_("Interrupt"))
+ init_sig (SIGQUIT, "QUIT", N_("Quit"))
+ init_sig (SIGILL, "ILL", N_("Illegal instruction"))
+ init_sig (SIGTRAP, "TRAP", N_("Trace/breakpoint trap"))
+ init_sig (SIGABRT, "ABRT", N_("Aborted"))
+ init_sig (SIGFPE, "FPE", N_("Floating point exception"))
+ init_sig (SIGKILL, "KILL", N_("Killed"))
+ init_sig (SIGBUS, "BUS", N_("Bus error"))
+ init_sig (SIGSEGV, "SEGV", N_("Segmentation fault"))
+ init_sig (SIGPIPE, "PIPE", N_("Broken pipe"))
+ init_sig (SIGALRM, "ALRM", N_("Alarm clock"))
+ init_sig (SIGTERM, "TERM", N_("Terminated"))
+ init_sig (SIGURG, "URG", N_("Urgent I/O condition"))
+ init_sig (SIGSTOP, "STOP", N_("Stopped (signal)"))
+ init_sig (SIGTSTP, "TSTP", N_("Stopped"))
+ init_sig (SIGCONT, "CONT", N_("Continued"))
+ init_sig (SIGCHLD, "CHLD", N_("Child exited"))
+ init_sig (SIGTTIN, "TTIN", N_("Stopped (tty input)"))
+ init_sig (SIGTTOU, "TTOU", N_("Stopped (tty output)"))
+ init_sig (SIGIO, "IO", N_("I/O possible"))
+ init_sig (SIGXCPU, "XCPU", N_("CPU time limit exceeded"))
+ init_sig (SIGXFSZ, "XFSZ", N_("File size limit exceeded"))
+ init_sig (SIGVTALRM, "VTALRM", N_("Virtual timer expired"))
+ init_sig (SIGPROF, "PROF", N_("Profiling timer expired"))
+ init_sig (SIGWINCH, "WINCH", N_("Window changed"))
+ init_sig (SIGUSR1, "USR1", N_("User defined signal 1"))
+ init_sig (SIGUSR2, "USR2", N_("User defined signal 2"))
+
+/* Variations */
+#ifdef SIGEMT
+ init_sig (SIGEMT, "EMT", N_("EMT trap"))
+#endif
+#ifdef SIGSYS
+ init_sig (SIGSYS, "SYS", N_("Bad system call"))
+#endif
+#ifdef SIGSTKFLT
+ init_sig (SIGSTKFLT, "STKFLT", N_("Stack fault"))
+#endif
+#ifdef SIGINFO
+ init_sig (SIGINFO, "INFO", N_("Information request"))
+#elif defined(SIGPWR) && (!defined(SIGLOST) || (SIGPWR != SIGLOST))
+ init_sig (SIGPWR, "PWR", N_("Power failure"))
+#endif
+#ifdef SIGLOST
+ init_sig (SIGLOST, "LOST", N_("Resource lost"))
+#endif
diff --git a/libc/sysdeps/generic/sigset-cvt-mask.h b/libc/sysdeps/generic/sigset-cvt-mask.h
new file mode 100644
index 000000000..95473f5ca
--- /dev/null
+++ b/libc/sysdeps/generic/sigset-cvt-mask.h
@@ -0,0 +1,64 @@
+/* Convert between lowlevel sigmask and libc representation of sigset_t.
+ Generic version.
+ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Joe Keane <jgk@jgk.org>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Convert between an old-style 32-bit signal mask and a POSIX sigset_t. */
+
+/* Perform *SET = MASK. Unused bits of *SET are set to 0.
+ Returns zero for success or -1 for errors (from sigaddset/sigemptyset). */
+static inline int __attribute__ ((unused))
+sigset_set_old_mask (sigset_t *set, int mask)
+{
+ if (sizeof (__sigset_t) == sizeof (unsigned int))
+ *set = (unsigned int) mask;
+ else
+ {
+ register unsigned int __sig;
+
+ if (__sigemptyset (set) < 0)
+ return -1;
+
+ for (__sig = 1; __sig < NSIG && __sig <= sizeof (mask) * 8; __sig++)
+ if (mask & sigmask (__sig))
+ if (__sigaddset (set, __sig) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+/* Return the sigmask corresponding to *SET.
+ Unused bits of *SET are thrown away. */
+static inline int __attribute__ ((unused))
+sigset_get_old_mask (const sigset_t *set)
+{
+ if (sizeof (sigset_t) == sizeof (unsigned int))
+ return (unsigned int) *set;
+ else
+ {
+ unsigned int mask = 0;
+ register unsigned int sig;
+
+ for (sig = 1; sig < NSIG && sig <= sizeof (mask) * 8; sig++)
+ if (__sigismember (set, sig))
+ mask |= sigmask (sig);
+
+ return mask;
+ }
+}
diff --git a/libc/sysdeps/generic/stackinfo.h b/libc/sysdeps/generic/stackinfo.h
new file mode 100644
index 000000000..7c43801e6
--- /dev/null
+++ b/libc/sysdeps/generic/stackinfo.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file contains a bit of information about the stack allocation
+ of the processor. Since there is no general truth we can't say
+ anything here. */
diff --git a/libc/sysdeps/generic/stdint.h b/libc/sysdeps/generic/stdint.h
new file mode 100644
index 000000000..2c729ad2f
--- /dev/null
+++ b/libc/sysdeps/generic/stdint.h
@@ -0,0 +1,320 @@
+/* Copyright (C) 1997,1998,1999,2000,2001,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * ISO C99: 7.18 Integer types <stdint.h>
+ */
+
+#ifndef _STDINT_H
+#define _STDINT_H 1
+
+#include <features.h>
+#include <bits/wchar.h>
+#include <bits/wordsize.h>
+
+/* Exact integral types. */
+
+/* Signed. */
+
+/* There is some amount of overlap with <sys/types.h> as known by inet code */
+#ifndef __int8_t_defined
+# define __int8_t_defined
+typedef signed char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
+# if __WORDSIZE == 64
+typedef long int int64_t;
+# else
+__extension__
+typedef long long int int64_t;
+# endif
+#endif
+
+/* Unsigned. */
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+#ifndef __uint32_t_defined
+typedef unsigned int uint32_t;
+# define __uint32_t_defined
+#endif
+#if __WORDSIZE == 64
+typedef unsigned long int uint64_t;
+#else
+__extension__
+typedef unsigned long long int uint64_t;
+#endif
+
+
+/* Small types. */
+
+/* Signed. */
+typedef signed char int_least8_t;
+typedef short int int_least16_t;
+typedef int int_least32_t;
+#if __WORDSIZE == 64
+typedef long int int_least64_t;
+#else
+__extension__
+typedef long long int int_least64_t;
+#endif
+
+/* Unsigned. */
+typedef unsigned char uint_least8_t;
+typedef unsigned short int uint_least16_t;
+typedef unsigned int uint_least32_t;
+#if __WORDSIZE == 64
+typedef unsigned long int uint_least64_t;
+#else
+__extension__
+typedef unsigned long long int uint_least64_t;
+#endif
+
+
+/* Fast types. */
+
+/* Signed. */
+typedef signed char int_fast8_t;
+#if __WORDSIZE == 64
+typedef long int int_fast16_t;
+typedef long int int_fast32_t;
+typedef long int int_fast64_t;
+#else
+typedef int int_fast16_t;
+typedef int int_fast32_t;
+__extension__
+typedef long long int int_fast64_t;
+#endif
+
+/* Unsigned. */
+typedef unsigned char uint_fast8_t;
+#if __WORDSIZE == 64
+typedef unsigned long int uint_fast16_t;
+typedef unsigned long int uint_fast32_t;
+typedef unsigned long int uint_fast64_t;
+#else
+typedef unsigned int uint_fast16_t;
+typedef unsigned int uint_fast32_t;
+__extension__
+typedef unsigned long long int uint_fast64_t;
+#endif
+
+
+/* Types for `void *' pointers. */
+#if __WORDSIZE == 64
+# ifndef __intptr_t_defined
+typedef long int intptr_t;
+# define __intptr_t_defined
+# endif
+typedef unsigned long int uintptr_t;
+#else
+# ifndef __intptr_t_defined
+typedef int intptr_t;
+# define __intptr_t_defined
+# endif
+typedef unsigned int uintptr_t;
+#endif
+
+
+/* Largest integral types. */
+#if __WORDSIZE == 64
+typedef long int intmax_t;
+typedef unsigned long int uintmax_t;
+#else
+__extension__
+typedef long long int intmax_t;
+__extension__
+typedef unsigned long long int uintmax_t;
+#endif
+
+
+/* The ISO C99 standard specifies that in C++ implementations these
+ macros should only be defined if explicitly requested. */
+#if !defined __cplusplus || defined __STDC_LIMIT_MACROS
+
+# if __WORDSIZE == 64
+# define __INT64_C(c) c ## L
+# define __UINT64_C(c) c ## UL
+# else
+# define __INT64_C(c) c ## LL
+# define __UINT64_C(c) c ## ULL
+# endif
+
+/* Limits of integral types. */
+
+/* Minimum of signed integral types. */
+# define INT8_MIN (-128)
+# define INT16_MIN (-32767-1)
+# define INT32_MIN (-2147483647-1)
+# define INT64_MIN (-__INT64_C(9223372036854775807)-1)
+/* Maximum of signed integral types. */
+# define INT8_MAX (127)
+# define INT16_MAX (32767)
+# define INT32_MAX (2147483647)
+# define INT64_MAX (__INT64_C(9223372036854775807))
+
+/* Maximum of unsigned integral types. */
+# define UINT8_MAX (255)
+# define UINT16_MAX (65535)
+# define UINT32_MAX (4294967295U)
+# define UINT64_MAX (__UINT64_C(18446744073709551615))
+
+
+/* Minimum of signed integral types having a minimum size. */
+# define INT_LEAST8_MIN (-128)
+# define INT_LEAST16_MIN (-32767-1)
+# define INT_LEAST32_MIN (-2147483647-1)
+# define INT_LEAST64_MIN (-__INT64_C(9223372036854775807)-1)
+/* Maximum of signed integral types having a minimum size. */
+# define INT_LEAST8_MAX (127)
+# define INT_LEAST16_MAX (32767)
+# define INT_LEAST32_MAX (2147483647)
+# define INT_LEAST64_MAX (__INT64_C(9223372036854775807))
+
+/* Maximum of unsigned integral types having a minimum size. */
+# define UINT_LEAST8_MAX (255)
+# define UINT_LEAST16_MAX (65535)
+# define UINT_LEAST32_MAX (4294967295U)
+# define UINT_LEAST64_MAX (__UINT64_C(18446744073709551615))
+
+
+/* Minimum of fast signed integral types having a minimum size. */
+# define INT_FAST8_MIN (-128)
+# if __WORDSIZE == 64
+# define INT_FAST16_MIN (-9223372036854775807L-1)
+# define INT_FAST32_MIN (-9223372036854775807L-1)
+# else
+# define INT_FAST16_MIN (-2147483647-1)
+# define INT_FAST32_MIN (-2147483647-1)
+# endif
+# define INT_FAST64_MIN (-__INT64_C(9223372036854775807)-1)
+/* Maximum of fast signed integral types having a minimum size. */
+# define INT_FAST8_MAX (127)
+# if __WORDSIZE == 64
+# define INT_FAST16_MAX (9223372036854775807L)
+# define INT_FAST32_MAX (9223372036854775807L)
+# else
+# define INT_FAST16_MAX (2147483647)
+# define INT_FAST32_MAX (2147483647)
+# endif
+# define INT_FAST64_MAX (__INT64_C(9223372036854775807))
+
+/* Maximum of fast unsigned integral types having a minimum size. */
+# define UINT_FAST8_MAX (255)
+# if __WORDSIZE == 64
+# define UINT_FAST16_MAX (18446744073709551615UL)
+# define UINT_FAST32_MAX (18446744073709551615UL)
+# else
+# define UINT_FAST16_MAX (4294967295U)
+# define UINT_FAST32_MAX (4294967295U)
+# endif
+# define UINT_FAST64_MAX (__UINT64_C(18446744073709551615))
+
+
+/* Values to test for integral types holding `void *' pointer. */
+# if __WORDSIZE == 64
+# define INTPTR_MIN (-9223372036854775807L-1)
+# define INTPTR_MAX (9223372036854775807L)
+# define UINTPTR_MAX (18446744073709551615UL)
+# else
+# define INTPTR_MIN (-2147483647-1)
+# define INTPTR_MAX (2147483647)
+# define UINTPTR_MAX (4294967295U)
+# endif
+
+
+/* Minimum for largest signed integral type. */
+# define INTMAX_MIN (-__INT64_C(9223372036854775807)-1)
+/* Maximum for largest signed integral type. */
+# define INTMAX_MAX (__INT64_C(9223372036854775807))
+
+/* Maximum for largest unsigned integral type. */
+# define UINTMAX_MAX (__UINT64_C(18446744073709551615))
+
+
+/* Limits of other integer types. */
+
+/* Limits of `ptrdiff_t' type. */
+# if __WORDSIZE == 64
+# define PTRDIFF_MIN (-9223372036854775807L-1)
+# define PTRDIFF_MAX (9223372036854775807L)
+# else
+# define PTRDIFF_MIN (-2147483647-1)
+# define PTRDIFF_MAX (2147483647)
+# endif
+
+/* Limits of `sig_atomic_t'. */
+# define SIG_ATOMIC_MIN (-2147483647-1)
+# define SIG_ATOMIC_MAX (2147483647)
+
+/* Limit of `size_t' type. */
+# if __WORDSIZE == 64
+# define SIZE_MAX (18446744073709551615UL)
+# else
+# define SIZE_MAX (4294967295U)
+# endif
+
+/* Limits of `wchar_t'. */
+# ifndef WCHAR_MIN
+/* These constants might also be defined in <wchar.h>. */
+# define WCHAR_MIN __WCHAR_MIN
+# define WCHAR_MAX __WCHAR_MAX
+# endif
+
+/* Limits of `wint_t'. */
+# define WINT_MIN (0u)
+# define WINT_MAX (4294967295u)
+
+#endif /* C++ && limit macros */
+
+
+/* The ISO C99 standard specifies that in C++ implementations these
+ should only be defined if explicitly requested. */
+#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS
+
+/* Signed. */
+# define INT8_C(c) c
+# define INT16_C(c) c
+# define INT32_C(c) c
+# if __WORDSIZE == 64
+# define INT64_C(c) c ## L
+# else
+# define INT64_C(c) c ## LL
+# endif
+
+/* Unsigned. */
+# define UINT8_C(c) c
+# define UINT16_C(c) c
+# define UINT32_C(c) c ## U
+# if __WORDSIZE == 64
+# define UINT64_C(c) c ## UL
+# else
+# define UINT64_C(c) c ## ULL
+# endif
+
+/* Maximal type. */
+# if __WORDSIZE == 64
+# define INTMAX_C(c) c ## L
+# define UINTMAX_C(c) c ## UL
+# else
+# define INTMAX_C(c) c ## LL
+# define UINTMAX_C(c) c ## ULL
+# endif
+
+#endif /* C++ && constant macros */
+
+#endif /* stdint.h */
diff --git a/libc/sysdeps/generic/symbol-hacks.h b/libc/sysdeps/generic/symbol-hacks.h
new file mode 100644
index 000000000..bc7b4c444
--- /dev/null
+++ b/libc/sysdeps/generic/symbol-hacks.h
@@ -0,0 +1 @@
+/* Fortunately nothing to do. */
diff --git a/libc/sysdeps/generic/sys/param.h b/libc/sysdeps/generic/sys/param.h
new file mode 100644
index 000000000..0e10a0ea9
--- /dev/null
+++ b/libc/sysdeps/generic/sys/param.h
@@ -0,0 +1,15 @@
+/* This file should contain various parameter macros appropriate for the
+ machine and operating system. There is no standard set of macros; this
+ file is just for compatibility with programs written for Unix that
+ expect it to define things. On Unix systems that do not have their own
+ sysdep version of this file, it is generated at build time by examining
+ the installed headers on the system. */
+
+#include <limits.h>
+
+#define MAXSYMLINKS 1
+#define MAXPATHLEN 256
+
+/* Macros for min/max. */
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX(a,b) (((a)>(b))?(a):(b))
diff --git a/libc/sysdeps/generic/sys/ptrace.h b/libc/sysdeps/generic/sys/ptrace.h
new file mode 100644
index 000000000..3cc3ee013
--- /dev/null
+++ b/libc/sysdeps/generic/sys/ptrace.h
@@ -0,0 +1,138 @@
+/* `ptrace' debugger support interface. Generic version; constants are common.
+ Copyright (C) 1991, 1992, 1996, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _PTRACE_H
+
+#define _PTRACE_H 1
+#include <features.h>
+
+__BEGIN_DECLS
+
+
+/* Type of the REQUEST argument to `ptrace.' */
+enum __ptrace_request
+{
+ /* Indicate that the process making this request should be traced.
+ All signals received by this process can be intercepted by its
+ parent, and its parent can use the other `ptrace' requests. */
+ PTRACE_TRACEME = 0,
+#define PT_TRACE_ME PTRACE_TRACEME
+
+ /* Return the word in the process's text space at address ADDR. */
+ PTRACE_PEEKTEXT,
+#define PT_READ_I PTRACE_PEEKTEXT
+
+ /* Return the word in the process's data space at address ADDR. */
+ PTRACE_PEEKDATA,
+#define PT_READ_D PTRACE_PEEKDATA
+
+ /* Return the word in the process's user area at offset ADDR. */
+ PTRACE_PEEKUSER,
+#define PT_READ_U PTRACE_PEEKUSER
+
+ /* Write the word DATA into the process's text space at address ADDR. */
+ PTRACE_POKETEXT,
+#define PT_WRITE_I PTRACE_POKETEXT
+
+ /* Write the word DATA into the process's data space at address ADDR. */
+ PTRACE_POKEDATA,
+#define PT_WRITE_D PTRACE_POKEDATA
+
+ /* Write the word DATA into the process's user space at offset ADDR. */
+ PTRACE_POKEUSER,
+#define PT_WRITE_U PTRACE_POKEUSER
+
+ /* Continue the process. */
+ PTRACE_CONT,
+#define PT_CONTINUE PTRACE_CONT
+
+ /* Kill the process. */
+ PTRACE_KILL,
+#define PT_KILL PTRACE_KILL
+
+ /* Single step the process.
+ This is not supported on all machines. */
+ PTRACE_SINGLESTEP,
+#define PT_STEP PTRACE_SINGLESTEP
+
+ /* Attach to a process that is already running. */
+ PTRACE_ATTACH,
+#define PT_ATTACH PTRACE_ATTACH
+
+ /* Detach from a process attached to with PTRACE_ATTACH. */
+ PTRACE_DETACH,
+#define PT_DETACH PTRACE_DETACH
+
+ /* Get the process's registers (not including floating-point registers)
+ and put them in the `struct regs' (see <machine/regs.h>) at ADDR. */
+ PTRACE_GETREGS = 12,
+
+ /* Set the process's registers (not including floating-point registers)
+ to the contents of the `struct regs' (see <machine/regs.h>) at ADDR. */
+ PTRACE_SETREGS,
+
+ /* Get the process's floating point registers and put them
+ in the `struct fp_status' (see <machine/regs.h>) at ADDR. */
+ PTRACE_GETFPREGS = 14,
+
+ /* Set the process's floating point registers to the contents
+ of the `struct fp_status' (see <machine/regs.h>) at ADDR. */
+ PTRACE_SETFPREGS,
+
+ /* Read DATA bytes from the process's data space at address ADDR.
+ Put the result starting at address ADDR2 in the caller's
+ address space. */
+ PTRACE_READDATA = 16,
+
+ /* Write DATA bytes from ADDR2 in the caller's address space into
+ the process's data space at address ADDR. */
+ PTRACE_WRITEDATA,
+
+ /* Read DATA bytes from the process's text space at address ADDR.
+ Put the result starting at address ADDR2 in the caller's
+ address space. */
+ PTRACE_READTEXT = 18,
+
+ /* Write DATA bytes from ADDR2 in the caller's address space into
+ the process's text space at address ADDR. */
+ PTRACE_WRITETEXT,
+
+ /* Read the floating-point accelerator unit registers and
+ put them into the `struct fpa_regs' (see <machine/regs.h>) at ADDR. */
+ PTRACE_GETFPAREGS = 20,
+
+ /* Write the floating-point accelerator unit registers from
+ the contents of the `struct fpa_regs' at ADDR. */
+ PTRACE_SETFPAREGS
+};
+
+/* Perform process tracing functions. REQUEST is one of the values
+ above, and determines the action to be taken.
+ For all requests except PTRACE_TRACEME, PID specifies the process to be
+ traced.
+
+ PID and the other arguments described above for the various requests should
+ appear (those that are used for the particular request) as:
+ pid_t PID, void *ADDR, int DATA, void *ADDR2
+ after REQUEST. */
+extern int ptrace (enum __ptrace_request __request, ...);
+
+__END_DECLS
+
+#endif /* ptrace.h */
diff --git a/libc/sysdeps/generic/sys/reboot.h b/libc/sysdeps/generic/sys/reboot.h
new file mode 100644
index 000000000..bada28dd6
--- /dev/null
+++ b/libc/sysdeps/generic/sys/reboot.h
@@ -0,0 +1,9 @@
+/* This file should define RB_* macros to be used as flag
+ bits in the argument to the `reboot' system call. */
+
+#ifndef _SYS_REBOOT_H
+#define _SYS_REBOOT_H
+
+#define RB_AUTOBOOT 0
+
+#endif /* <sys/reboot.h> */
diff --git a/libc/sysdeps/generic/sys/socketvar.h b/libc/sysdeps/generic/sys/socketvar.h
new file mode 100644
index 000000000..b177158d0
--- /dev/null
+++ b/libc/sysdeps/generic/sys/socketvar.h
@@ -0,0 +1,3 @@
+/* This header is used on many systems but for GNU we have everything
+ already defined in the standard header. */
+#include <sys/socket.h>
diff --git a/libc/sysdeps/generic/sys/swap.h b/libc/sysdeps/generic/sys/swap.h
new file mode 100644
index 000000000..c7b58b99e
--- /dev/null
+++ b/libc/sysdeps/generic/sys/swap.h
@@ -0,0 +1,33 @@
+/* Calls to enable and disable swapping on specified locations. Unix version.
+ Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __SYS_SWAP_H
+
+#define __SYS_SWAP_H 1
+#include <features.h>
+
+
+/* Make the block special device PATH available to the system for swapping.
+ This call is restricted to the super-user. */
+extern int swapon (__const char *__path) __THROW;
+
+/* Stop using block special device PATH for swapping. */
+extern int swapoff (__const char *__path) __THROW;
+
+#endif /* sys/swap.h */
diff --git a/libc/sysdeps/generic/sys/syscall.h b/libc/sysdeps/generic/sys/syscall.h
new file mode 100644
index 000000000..719bd0890
--- /dev/null
+++ b/libc/sysdeps/generic/sys/syscall.h
@@ -0,0 +1,2 @@
+/* For Unix-like systems, this file should contain definitions
+ of macros SYS_call for each system call, giving the call numbers. */
diff --git a/libc/sysdeps/generic/sys/sysinfo.h b/libc/sysdeps/generic/sys/sysinfo.h
new file mode 100644
index 000000000..e3ed75c3c
--- /dev/null
+++ b/libc/sysdeps/generic/sys/sysinfo.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 1996-1997, 1999, 2000-2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SYSINFO_H
+#define _SYS_SYSINFO_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Return number of configured processors. */
+extern int get_nprocs_conf (void) __THROW;
+
+/* Return number of available processors. */
+extern int get_nprocs (void) __THROW;
+
+
+/* Return number of physical pages of memory in the system. */
+extern long int get_phys_pages (void) __THROW;
+
+/* Return number of available physical pages of memory in the system. */
+extern long int get_avphys_pages (void) __THROW;
+
+__END_DECLS
+
+#endif /* sys/sysinfo.h */
diff --git a/libc/sysdeps/generic/sys/sysmacros.h b/libc/sysdeps/generic/sys/sysmacros.h
new file mode 100644
index 000000000..393a29238
--- /dev/null
+++ b/libc/sysdeps/generic/sys/sysmacros.h
@@ -0,0 +1,31 @@
+/* Definitions of macros to access `dev_t' values.
+ Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SYSMACROS_H
+#define _SYS_SYSMACROS_H 1
+
+/* For compatibility we provide alternative names.
+
+ The problem here is that compilers other than GCC probably don't
+ have the `long long' type and so `dev_t' is actually an array. */
+#define major(dev) ((int)(((unsigned int) (dev) >> 8) & 0xff))
+#define minor(dev) ((int)((dev) & 0xff))
+#define makedev(major, minor) (((major) << 8) | (minor))
+
+#endif /* sys/sysmacros.h */
diff --git a/libc/sysdeps/generic/sys/ttydefaults.h b/libc/sysdeps/generic/sys/ttydefaults.h
new file mode 100644
index 000000000..683dc8d80
--- /dev/null
+++ b/libc/sysdeps/generic/sys/ttydefaults.h
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)ttydefaults.h 8.4 (Berkeley) 1/21/94
+ */
+
+/*
+ * System wide defaults for terminal state. 4.4 BSD/generic GNU version.
+ */
+#ifndef _SYS_TTYDEFAULTS_H_
+#define _SYS_TTYDEFAULTS_H_
+
+/*
+ * Defaults on "first" open.
+ */
+#define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY)
+#define TTYDEF_OFLAG (OPOST | ONLCR | OXTABS)
+#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)
+#define TTYDEF_CFLAG (CREAD | CS7 | PARENB | HUPCL)
+#define TTYDEF_SPEED (B9600)
+
+/*
+ * Control Character Defaults
+ */
+#define CTRL(x) (x&037)
+#define CEOF CTRL('d')
+#ifdef _POSIX_VDISABLE
+# define CEOL _POSIX_VDISABLE
+#else
+# define CEOL ((unsigned char)'\377') /* XXX avoid _POSIX_VDISABLE */
+#endif
+#define CERASE 0177
+#define CINTR CTRL('c')
+#ifdef _POSIX_VDISABLE
+# define CSTATUS _POSIX_VDISABLE
+#else
+# define CSTATUS ((unsigned char)'\377') /* XXX avoid _POSIX_VDISABLE */
+#endif
+#define CKILL CTRL('u')
+#define CMIN 1
+#define CQUIT 034 /* FS, ^\ */
+#define CSUSP CTRL('z')
+#define CTIME 0
+#define CDSUSP CTRL('y')
+#define CSTART CTRL('q')
+#define CSTOP CTRL('s')
+#define CLNEXT CTRL('v')
+#define CDISCARD CTRL('o')
+#define CWERASE CTRL('w')
+#define CREPRINT CTRL('r')
+#define CEOT CEOF
+/* compat */
+#define CBRK CEOL
+#define CRPRNT CREPRINT
+#define CFLUSH CDISCARD
+
+/* PROTECTED INCLUSION ENDS HERE */
+#endif /* !_SYS_TTYDEFAULTS_H_ */
+
+/*
+ * #define TTYDEFCHARS to include an array of default control characters.
+ */
+#ifdef TTYDEFCHARS
+cc_t ttydefchars[NCCS] = {
+ CEOF, CEOL, CEOL, CERASE, CWERASE, CKILL, CREPRINT,
+ _POSIX_VDISABLE, CINTR, CQUIT, CSUSP, CDSUSP, CSTART, CSTOP, CLNEXT,
+ CDISCARD, CMIN, CTIME, CSTATUS, _POSIX_VDISABLE
+};
+#undef TTYDEFCHARS
+#endif
diff --git a/libc/sysdeps/generic/sys/ucontext.h b/libc/sysdeps/generic/sys/ucontext.h
new file mode 100644
index 000000000..d643dfbfc
--- /dev/null
+++ b/libc/sysdeps/generic/sys/ucontext.h
@@ -0,0 +1,45 @@
+/* Data structures for user-level context switching. Generic version.
+ Copyright (C) 1997,98,99,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file's definitions suffice for any platform where all
+ the machine-specific state is described in `struct sigcontext'. */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+
+/* We need the signal context definitions even if they are not used
+ included in <signal.h>. */
+#include <bits/sigcontext.h>
+
+typedef struct sigcontext mcontext_t;
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ __sigset_t uc_sigmask;
+ } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/generic/sysdep-cancel.h b/libc/sysdeps/generic/sysdep-cancel.h
new file mode 100644
index 000000000..f07b784f2
--- /dev/null
+++ b/libc/sysdeps/generic/sysdep-cancel.h
@@ -0,0 +1,7 @@
+#include <sysdep.h>
+
+/* No multi-thread handling enabled. */
+#define SINGLE_THREAD_P (1)
+#define LIBC_CANCEL_ASYNC() 0 /* Just a dummy value. */
+#define LIBC_CANCEL_RESET(val) ((void)(val)) /* Nothing, but evaluate it. */
+#define LIBC_CANCEL_HANDLED() /* Nothing. */
diff --git a/libc/sysdeps/generic/sysdep.h b/libc/sysdeps/generic/sysdep.h
new file mode 100644
index 000000000..15d951c77
--- /dev/null
+++ b/libc/sysdeps/generic/sysdep.h
@@ -0,0 +1,137 @@
+/* Generic asm macros used on many machines.
+ Copyright (C) 1991,92,93,96,98,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef C_LABEL
+
+/* Define a macro we can use to construct the asm name for a C symbol. */
+#ifdef NO_UNDERSCORES
+#ifdef __STDC__
+#define C_LABEL(name) name##:
+#else
+#define C_LABEL(name) name/**/:
+#endif
+#else
+#ifdef __STDC__
+#define C_LABEL(name) _##name##:
+#else
+#define C_LABEL(name) _/**/name/**/:
+#endif
+#endif
+
+#endif
+
+#ifdef __ASSEMBLER__
+/* Mark the end of function named SYM. This is used on some platforms
+ to generate correct debugging information. */
+#ifndef END
+#define END(sym)
+#endif
+
+#ifndef JUMPTARGET
+#define JUMPTARGET(sym) sym
+#endif
+
+/* Makros to generate eh_frame unwind information. */
+# ifdef HAVE_ASM_CFI_DIRECTIVES
+# define cfi_startproc .cfi_startproc
+# define cfi_endproc .cfi_endproc
+# define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off
+# define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg
+# define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off
+# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
+# define cfi_offset(reg, off) .cfi_offset reg, off
+# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
+# define cfi_register(r1, r2) .cfi_register r1, r2
+# define cfi_return_column(reg) .cfi_return_column reg
+# define cfi_restore(reg) .cfi_restore reg
+# define cfi_same_value(reg) .cfi_same_value reg
+# define cfi_undefined(reg) .cfi_undefined reg
+# define cfi_remember_state .cfi_remember_state
+# define cfi_restore_state .cfi_restore_state
+# define cfi_window_save .cfi_window_save
+# else
+# define cfi_startproc
+# define cfi_endproc
+# define cfi_def_cfa(reg, off)
+# define cfi_def_cfa_register(reg)
+# define cfi_def_cfa_offset(off)
+# define cfi_adjust_cfa_offset(off)
+# define cfi_offset(reg, off)
+# define cfi_rel_offset(reg, off)
+# define cfi_register(r1, r2)
+# define cfi_return_column(reg)
+# define cfi_restore(reg)
+# define cfi_same_value(reg)
+# define cfi_undefined(reg)
+# define cfi_remember_state
+# define cfi_restore_state
+# define cfi_window_save
+# endif
+
+#else /* ! ASSEMBLER */
+# ifdef HAVE_ASM_CFI_DIRECTIVES
+# define CFI_STRINGIFY(Name) CFI_STRINGIFY2 (Name)
+# define CFI_STRINGIFY2(Name) #Name
+# define CFI_STARTPROC ".cfi_startproc"
+# define CFI_ENDPROC ".cfi_endproc"
+# define CFI_DEF_CFA(reg, off) \
+ ".cfi_def_cfa " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off)
+# define CFI_DEF_CFA_REGISTER(reg) \
+ ".cfi_def_cfa_register " CFI_STRINGIFY(reg)
+# define CFI_DEF_CFA_OFFSET(off) \
+ ".cfi_def_cfa_offset " CFI_STRINGIFY(off)
+# define CFI_ADJUST_CFA_OFFSET(off) \
+ ".cfi_adjust_cfa_offset " CFI_STRINGIFY(off)
+# define CFI_OFFSET(reg, off) \
+ ".cfi_offset " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off)
+# define CFI_REL_OFFSET(reg, off) \
+ ".cfi_rel_offset " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off)
+# define CFI_REGISTER(r1, r2) \
+ ".cfi_register " CFI_STRINGIFY(r1) "," CFI_STRINGIFY(r2)
+# define CFI_RETURN_COLUMN(reg) \
+ ".cfi_return_column " CFI_STRINGIFY(reg)
+# define CFI_RESTORE(reg) \
+ ".cfi_restore " CFI_STRINGIFY(reg)
+# define CFI_UNDEFINED(reg) \
+ ".cfi_undefined " CFI_STRINGIFY(reg)
+# define CFI_REMEMBER_STATE \
+ ".cfi_remember_state"
+# define CFI_RESTORE_STATE \
+ ".cfi_restore_state"
+# define CFI_WINDOW_SAVE \
+ ".cfi_window_save"
+# else
+# define CFI_STARTPROC
+# define CFI_ENDPROC
+# define CFI_DEF_CFA(reg, off)
+# define CFI_DEF_CFA_REGISTER(reg)
+# define CFI_DEF_CFA_OFFSET(off)
+# define CFI_ADJUST_CFA_OFFSET(off)
+# define CFI_OFFSET(reg, off)
+# define CFI_REL_OFFSET(reg, off)
+# define CFI_REGISTER(r1, r2)
+# define CFI_RETURN_COLUMN(reg)
+# define CFI_RESTORE(reg)
+# define CFI_UNDEFINED(reg)
+# define CFI_REMEMBER_STATE
+# define CFI_RESTORE_STATE
+# define CFI_WINDOW_SAVE
+# endif
+
+#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/generic/testrtsig.h b/libc/sysdeps/generic/testrtsig.h
new file mode 100644
index 000000000..f8346b7af
--- /dev/null
+++ b/libc/sysdeps/generic/testrtsig.h
@@ -0,0 +1,28 @@
+/* Test whether RT signals are really available.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <sys/utsname.h>
+
+static int
+kernel_has_rtsig (void)
+{
+ return 0;
+}
diff --git a/libc/sysdeps/generic/thread_state.h b/libc/sysdeps/generic/thread_state.h
new file mode 100644
index 000000000..7f8c0f84e
--- /dev/null
+++ b/libc/sysdeps/generic/thread_state.h
@@ -0,0 +1,47 @@
+/* Mach thread state definitions for machine-independent code. Stub version.
+ Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Everything else is called `thread_state', but CMU's header file is
+ called `thread_status'. Oh boy. */
+#include <mach/thread_state.h>
+
+/* Replace <machine> with "i386" or "mips" or whatever. */
+
+#define MACHINE_THREAD_STATE_FLAVOR <machine>_THREAD_STATE
+#define MACHINE_THREAD_STATE_COUNT <machine>_THREAD_STATE_COUNT
+
+#define machine_thread_state <machine>_thread_state
+
+/* Define these to the member names in `struct <machine>_thread_state'
+ for the PC and stack pointer. */
+#define PC ?
+#define SP ?
+
+/* This structure should contain all of the different flavors of thread
+ state structures which are meaningful for this machine. Every machine's
+ definition of this structure should have a member `int set' which is a
+ bit mask (1 << FLAVOR) of the flavors of thread state in the structure
+ which are filled in; and a member `struct machine_thread_state basic'.
+ On some machines those are the only members (e.g. i386); on others,
+ there are several relevant flavors of thread state (e.g. mips). */
+struct machine_thread_all_state
+ {
+ int set; /* Mask of bits (1 << FLAVOR). */
+ struct <machine>_thread_state basic;
+ };
diff --git a/libc/sysdeps/generic/tls-macros.h b/libc/sysdeps/generic/tls-macros.h
new file mode 100644
index 000000000..0a08f7c14
--- /dev/null
+++ b/libc/sysdeps/generic/tls-macros.h
@@ -0,0 +1,12 @@
+/* Macros to support TLS testing in times of missing compiler support.
+ Stub version.
+
+ These macros should yield int * expressions for the TLS symbol X
+ accessed using the various TLS access models. Macros for some machines
+ are defined in elf/tls-macros.h, but ports can instead provide this file.
+
+#define TLS_LE(x)
+#define TLS_IE(x)
+#define TLS_LD(x)
+#define TLS_GD(x)
+*/
diff --git a/libc/sysdeps/generic/tls.h b/libc/sysdeps/generic/tls.h
new file mode 100644
index 000000000..6a23ec05e
--- /dev/null
+++ b/libc/sysdeps/generic/tls.h
@@ -0,0 +1,81 @@
+/* Definition for thread-local data handling. Generic version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* By default no TLS support is available. This is signaled by the
+ absence of the symbol USE_TLS. */
+#undef USE_TLS
+
+
+/* An architecture-specific version of this file has to defined a
+ number of symbols:
+
+ TLS_TCB_AT_TP or TLS_DTV_AT_TP
+
+ The presence of one of these symbols signals which variant of
+ the TLS ABI is used. There are in the moment two variants
+ available:
+
+ * the thread pointer points to a thread control block
+
+ * the thread pointer points to the dynamic thread vector
+
+
+ TLS_TCB_SIZE
+
+ This is the size of the thread control block structure. How
+ this is actually defined depends on the ABI. The thread control
+ block could be internal descriptor of the thread library or
+ just a data structure which allows finding the DTV.
+
+ TLS_INIT_TCB_SIZE
+
+ Similarly, but this value is only used at startup and in the
+ dynamic linker itself. There are no threads in use at that time.
+
+
+ TLS_TCB_ALIGN
+
+ Alignment requirements for the TCB structure.
+
+ TLS_INIT_TCB_ALIGN
+
+ Similarly, but for the structure used at startup time.
+
+
+ INSTALL_DTV(tcb, init_dtv)
+
+ This macro must install the given initial DTV into the thread control
+ block TCB. The normal runtime functionality must then be able to
+ use the value.
+
+
+ TLS_INIT_TP(tcb, firstcall)
+
+ This macro must initialize the thread pointer to enable normal TLS
+ operation. The first parameter is a pointer to the thread control
+ block. The second parameter specifies whether this is the first
+ call for the TCB. ld.so calls this macro more than once.
+
+
+ THREAD_DTV()
+
+ This macro returns the address of the DTV of the current thread.
+ This normally is done using the the thread register which points
+ to the dtv or the TCB (from which the DTV can found).
+ */
diff --git a/libc/sysdeps/generic/tst-audit.h b/libc/sysdeps/generic/tst-audit.h
new file mode 100644
index 000000000..402e7c066
--- /dev/null
+++ b/libc/sysdeps/generic/tst-audit.h
@@ -0,0 +1,11 @@
+/* Some machines have these macros defined in elf/tst-auditmod1.c directly.
+ New machines can supply a tst-audit.h to define these macros used there.
+
+
+# define pltenter la_CPU_gnu_pltenter
+# define pltexit la_CPU_gnu_pltexit
+# define La_regs La_CPU_regs
+# define La_retval La_CPU_retval
+# define int_retval lrv_RETVALREG
+
+*/
diff --git a/libc/sysdeps/generic/tst-stack-align.h b/libc/sysdeps/generic/tst-stack-align.h
new file mode 100644
index 000000000..59b1e656a
--- /dev/null
+++ b/libc/sysdeps/generic/tst-stack-align.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#define TEST_STACK_ALIGN() \
+ ({ \
+ double _d = 12.0; \
+ long double _ld = 15.0; \
+ int _ret = 0; \
+ printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
+ if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
+ _ret = 1; \
+ \
+ printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
+ if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
+ _ret = 1; \
+ _ret; \
+ })
diff --git a/libc/sysdeps/generic/unsecvars.h b/libc/sysdeps/generic/unsecvars.h
new file mode 100644
index 000000000..a7378b742
--- /dev/null
+++ b/libc/sysdeps/generic/unsecvars.h
@@ -0,0 +1,25 @@
+/* Environment variable to be removed for SUID programs. The names are
+ all stuffed in a single string which means they have to be terminated
+ with a '\0' explicitly. */
+#define UNSECURE_ENVVARS \
+ "GCONV_PATH\0" \
+ "GETCONF_DIR\0" \
+ "HOSTALIASES\0" \
+ "LD_AUDIT\0" \
+ "LD_DEBUG\0" \
+ "LD_DEBUG_OUTPUT\0" \
+ "LD_DYNAMIC_WEAK\0" \
+ "LD_LIBRARY_PATH\0" \
+ "LD_ORIGIN_PATH\0" \
+ "LD_PRELOAD\0" \
+ "LD_PROFILE\0" \
+ "LD_SHOW_AUXV\0" \
+ "LD_USE_LOAD_BIAS\0" \
+ "LOCALDOMAIN\0" \
+ "LOCPATH\0" \
+ "MALLOC_TRACE\0" \
+ "NLSPATH\0" \
+ "RESOLV_HOST_CONF\0" \
+ "RES_OPTIONS\0" \
+ "TMPDIR\0" \
+ "TZDIR\0"
diff --git a/libc/sysdeps/generic/unwind-dw2-fde-glibc.c b/libc/sysdeps/generic/unwind-dw2-fde-glibc.c
new file mode 100644
index 000000000..0038a0cbf
--- /dev/null
+++ b/libc/sysdeps/generic/unwind-dw2-fde-glibc.c
@@ -0,0 +1,278 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Locate the FDE entry for a given address, using PT_GNU_EH_FRAME ELF
+ segment and dl_iterate_phdr to avoid register/deregister calls at
+ DSO load/unload. */
+
+#ifdef _LIBC
+# include <shlib-compat.h>
+#endif
+
+#if !defined _LIBC || SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2_5)
+
+#include <link.h>
+#include <stddef.h>
+
+#define _Unwind_Find_FDE _Unwind_Find_registered_FDE
+
+#include <unwind-dw2-fde.c>
+
+#undef _Unwind_Find_FDE
+
+extern fde * _Unwind_Find_registered_FDE (void *pc,
+ struct dwarf_eh_bases *bases);
+extern fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
+
+struct unw_eh_callback_data
+{
+ _Unwind_Ptr pc;
+ void *tbase;
+ void *dbase;
+ void *func;
+ fde *ret;
+};
+
+struct unw_eh_frame_hdr
+{
+ unsigned char version;
+ unsigned char eh_frame_ptr_enc;
+ unsigned char fde_count_enc;
+ unsigned char table_enc;
+};
+
+/* Like base_of_encoded_value, but take the base from a struct object
+ instead of an _Unwind_Context. */
+
+static _Unwind_Ptr
+base_from_cb_data (unsigned char encoding, struct unw_eh_callback_data *data)
+{
+ if (encoding == DW_EH_PE_omit)
+ return 0;
+
+ switch (encoding & 0x70)
+ {
+ case DW_EH_PE_absptr:
+ case DW_EH_PE_pcrel:
+ case DW_EH_PE_aligned:
+ return 0;
+
+ case DW_EH_PE_textrel:
+ return (_Unwind_Ptr) data->tbase;
+ case DW_EH_PE_datarel:
+ return (_Unwind_Ptr) data->dbase;
+ }
+ abort ();
+}
+
+static int
+_Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
+{
+ struct unw_eh_callback_data *data = (struct unw_eh_callback_data *) ptr;
+ const ElfW(Phdr) *phdr, *p_eh_frame_hdr, *p_dynamic;
+ long n, match;
+ _Unwind_Ptr load_base;
+ const unsigned char *p;
+ const struct unw_eh_frame_hdr *hdr;
+ _Unwind_Ptr eh_frame;
+ struct object ob;
+
+ /* Make sure struct dl_phdr_info is at least as big as we need. */
+ if (size < offsetof (struct dl_phdr_info, dlpi_phnum)
+ + sizeof (info->dlpi_phnum))
+ return -1;
+
+ match = 0;
+ phdr = info->dlpi_phdr;
+ load_base = info->dlpi_addr;
+ p_eh_frame_hdr = NULL;
+ p_dynamic = NULL;
+
+ /* See if PC falls into one of the loaded segments. Find the eh_frame
+ segment at the same time. */
+ for (n = info->dlpi_phnum; --n >= 0; phdr++)
+ {
+ if (phdr->p_type == PT_LOAD)
+ {
+ _Unwind_Ptr vaddr = phdr->p_vaddr + load_base;
+ if (data->pc >= vaddr && data->pc < vaddr + phdr->p_memsz)
+ match = 1;
+ }
+ else if (phdr->p_type == PT_GNU_EH_FRAME)
+ p_eh_frame_hdr = phdr;
+ else if (phdr->p_type == PT_DYNAMIC)
+ p_dynamic = phdr;
+ }
+ if (!match || !p_eh_frame_hdr)
+ return 0;
+
+ /* Read .eh_frame_hdr header. */
+ hdr = (const struct unw_eh_frame_hdr *)
+ (p_eh_frame_hdr->p_vaddr + load_base);
+ if (hdr->version != 1)
+ return 1;
+
+#ifdef CRT_GET_RFIB_DATA
+# ifdef __i386__
+ data->dbase = NULL;
+ if (p_dynamic)
+ {
+ /* For dynamicly linked executables and shared libraries,
+ DT_PLTGOT is the gp value for that object. */
+ ElfW(Dyn) *dyn = (ElfW(Dyn) *)(p_dynamic->p_vaddr + load_base);
+ for (; dyn->d_tag != DT_NULL ; dyn++)
+ if (dyn->d_tag == DT_PLTGOT)
+ {
+ /* On IA-32, _DYNAMIC is writable and GLIBC has relocated it. */
+ data->dbase = (void *) dyn->d_un.d_ptr;
+ break;
+ }
+ }
+# else
+# error What is DW_EH_PE_datarel base on this platform?
+# endif
+#endif
+#ifdef CRT_GET_RFIB_TEXT
+# error What is DW_EH_PE_textrel base on this platform?
+#endif
+
+ p = read_encoded_value_with_base (hdr->eh_frame_ptr_enc,
+ base_from_cb_data (hdr->eh_frame_ptr_enc,
+ data),
+ (const unsigned char *) (hdr + 1),
+ &eh_frame);
+
+ /* We require here specific table encoding to speed things up.
+ Also, DW_EH_PE_datarel here means using PT_GNU_EH_FRAME start
+ as base, not the processor specific DW_EH_PE_datarel. */
+ if (hdr->fde_count_enc != DW_EH_PE_omit
+ && hdr->table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
+ {
+ _Unwind_Ptr fde_count;
+
+ p = read_encoded_value_with_base (hdr->fde_count_enc,
+ base_from_cb_data (hdr->fde_count_enc,
+ data),
+ p, &fde_count);
+ /* Shouldn't happen. */
+ if (fde_count == 0)
+ return 1;
+ if ((((_Unwind_Ptr) p) & 3) == 0)
+ {
+ struct fde_table {
+ signed initial_loc __attribute__ ((mode (SI)));
+ signed fde __attribute__ ((mode (SI)));
+ };
+ const struct fde_table *table = (const struct fde_table *) p;
+ size_t lo, hi, mid;
+ _Unwind_Ptr data_base = (_Unwind_Ptr) hdr;
+ fde *f;
+ unsigned int f_enc, f_enc_size;
+ _Unwind_Ptr range;
+
+ mid = fde_count - 1;
+ if (data->pc < table[0].initial_loc + data_base)
+ return 1;
+ else if (data->pc < table[mid].initial_loc + data_base)
+ {
+ lo = 0;
+ hi = mid;
+
+ while (lo < hi)
+ {
+ mid = (lo + hi) / 2;
+ if (data->pc < table[mid].initial_loc + data_base)
+ hi = mid;
+ else if (data->pc >= table[mid + 1].initial_loc + data_base)
+ lo = mid + 1;
+ else
+ break;
+ }
+
+ if (lo >= hi)
+ __gxx_abort ();
+ }
+
+ f = (fde *) (table[mid].fde + data_base);
+ f_enc = get_fde_encoding (f);
+ f_enc_size = size_of_encoded_value (f_enc);
+ read_encoded_value_with_base (f_enc & 0x0f, 0,
+ &f->pc_begin[f_enc_size], &range);
+ if (data->pc < table[mid].initial_loc + data_base + range)
+ data->ret = f;
+ data->func = (void *) (table[mid].initial_loc + data_base);
+ return 1;
+ }
+ }
+
+ /* We have no sorted search table, so need to go the slow way.
+ As soon as GLIBC will provide API so to notify that a library has been
+ removed, we could cache this (and thus use search_object). */
+ ob.pc_begin = NULL;
+ ob.tbase = data->tbase;
+ ob.dbase = data->dbase;
+ ob.u.single = (fde *) eh_frame;
+ ob.s.i = 0;
+ ob.s.b.mixed_encoding = 1; /* Need to assume worst case. */
+ data->ret = linear_search_fdes (&ob, (fde *) eh_frame, (void *) data->pc);
+ if (data->ret != NULL)
+ {
+ unsigned int encoding = get_fde_encoding (data->ret);
+ read_encoded_value_with_base (encoding,
+ base_from_cb_data (encoding, data),
+ data->ret->pc_begin,
+ (_Unwind_Ptr *)&data->func);
+ }
+ return 1;
+}
+
+# ifdef _LIBC
+# define dl_iterate_phdr __dl_iterate_phdr
+# endif
+
+fde *
+_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
+{
+ struct unw_eh_callback_data data;
+ fde *ret;
+
+ ret = _Unwind_Find_registered_FDE (pc, bases);
+ if (ret != NULL)
+ return ret;
+
+ data.pc = (_Unwind_Ptr) pc;
+ data.tbase = NULL;
+ data.dbase = NULL;
+ data.func = NULL;
+ data.ret = NULL;
+
+ if (dl_iterate_phdr (_Unwind_IteratePhdrCallback, &data) < 0)
+ return NULL;
+
+ if (data.ret)
+ {
+ bases->tbase = data.tbase;
+ bases->dbase = data.dbase;
+ bases->func = data.func;
+ }
+ return data.ret;
+}
+
+#endif
diff --git a/libc/sysdeps/generic/unwind-dw2-fde.c b/libc/sysdeps/generic/unwind-dw2-fde.c
new file mode 100644
index 000000000..13945b971
--- /dev/null
+++ b/libc/sysdeps/generic/unwind-dw2-fde.c
@@ -0,0 +1,1063 @@
+/* Subroutines needed for unwinding stack frames for exception handling. */
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2006
+ Free Software Foundation, Inc.
+ Contributed by Jason Merrill <jason@cygnus.com>.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef _LIBC
+# include <shlib-compat.h>
+#endif
+
+#if !defined _LIBC || SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2_5)
+
+#ifdef _LIBC
+#include <stdlib.h>
+#include <string.h>
+#include <bits/libc-lock.h>
+#include <dwarf2.h>
+#include <unwind.h>
+#define NO_BASE_OF_ENCODED_VALUE
+#include <unwind-pe.h>
+#include <unwind-dw2-fde.h>
+#else
+#ifndef _Unwind_Find_FDE
+#include "tconfig.h"
+#include "tsystem.h"
+#include "dwarf2.h"
+#include "unwind.h"
+#define NO_BASE_OF_ENCODED_VALUE
+#include "unwind-pe.h"
+#include "unwind-dw2-fde.h"
+#include "gthr.h"
+#endif
+#endif
+
+/* The unseen_objects list contains objects that have been registered
+ but not yet categorized in any way. The seen_objects list has had
+ it's pc_begin and count fields initialized at minimum, and is sorted
+ by decreasing value of pc_begin. */
+static struct object *unseen_objects;
+static struct object *seen_objects;
+
+#ifdef _LIBC
+
+__libc_lock_define_initialized (static, object_mutex)
+#define init_object_mutex_once()
+#define __gthread_mutex_lock(m) __libc_lock_lock (*(m))
+#define __gthread_mutex_unlock(m) __libc_lock_unlock (*(m))
+
+void __register_frame_info_bases_internal (void *begin, struct object *ob,
+ void *tbase, void *dbase);
+void __register_frame_info_table_bases_internal (void *begin,
+ struct object *ob,
+ void *tbase, void *dbase);
+void *__deregister_frame_info_bases_internal (void *begin);
+
+#else
+
+#ifdef __GTHREAD_MUTEX_INIT
+static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
+#else
+static __gthread_mutex_t object_mutex;
+#endif
+
+#ifdef __GTHREAD_MUTEX_INIT_FUNCTION
+static void
+init_object_mutex (void)
+{
+ __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex);
+}
+
+static void
+init_object_mutex_once (void)
+{
+ static __gthread_once_t once = __GTHREAD_ONCE_INIT;
+ __gthread_once (&once, init_object_mutex);
+}
+#else
+#define init_object_mutex_once()
+#endif
+
+#endif /* _LIBC */
+
+/* Called from crtbegin.o to register the unwind info for an object. */
+
+void
+__register_frame_info_bases (void *begin, struct object *ob,
+ void *tbase, void *dbase)
+{
+ /* If .eh_frame is empty, don't register at all. */
+ if (*(uword *) begin == 0)
+ return;
+
+ ob->pc_begin = (void *)-1;
+ ob->tbase = tbase;
+ ob->dbase = dbase;
+ ob->u.single = begin;
+ ob->s.i = 0;
+ ob->s.b.encoding = DW_EH_PE_omit;
+#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
+ ob->fde_end = NULL;
+#endif
+
+ init_object_mutex_once ();
+ __gthread_mutex_lock (&object_mutex);
+
+ ob->next = unseen_objects;
+ unseen_objects = ob;
+
+ __gthread_mutex_unlock (&object_mutex);
+}
+INTDEF(__register_frame_info_bases)
+
+void
+__register_frame_info (void *begin, struct object *ob)
+{
+ INTUSE(__register_frame_info_bases) (begin, ob, 0, 0);
+}
+
+void
+__register_frame (void *begin)
+{
+ struct object *ob;
+
+ /* If .eh_frame is empty, don't register at all. */
+ if (*(uword *) begin == 0)
+ return;
+
+ ob = (struct object *) malloc (sizeof (struct object));
+ INTUSE(__register_frame_info_bases) (begin, ob, 0, 0);
+}
+
+/* Similar, but BEGIN is actually a pointer to a table of unwind entries
+ for different translation units. Called from the file generated by
+ collect2. */
+
+void
+__register_frame_info_table_bases (void *begin, struct object *ob,
+ void *tbase, void *dbase)
+{
+ ob->pc_begin = (void *)-1;
+ ob->tbase = tbase;
+ ob->dbase = dbase;
+ ob->u.array = begin;
+ ob->s.i = 0;
+ ob->s.b.from_array = 1;
+ ob->s.b.encoding = DW_EH_PE_omit;
+
+ init_object_mutex_once ();
+ __gthread_mutex_lock (&object_mutex);
+
+ ob->next = unseen_objects;
+ unseen_objects = ob;
+
+ __gthread_mutex_unlock (&object_mutex);
+}
+INTDEF(__register_frame_info_table_bases)
+
+void
+__register_frame_info_table (void *begin, struct object *ob)
+{
+ INTUSE(__register_frame_info_table_bases) (begin, ob, 0, 0);
+}
+
+void
+__register_frame_table (void *begin)
+{
+ struct object *ob = (struct object *) malloc (sizeof (struct object));
+ INTUSE(__register_frame_info_table_bases) (begin, ob, 0, 0);
+}
+
+/* Called from crtbegin.o to deregister the unwind info for an object. */
+/* ??? Glibc has for a while now exported __register_frame_info and
+ __deregister_frame_info. If we call __register_frame_info_bases
+ from crtbegin (wherein it is declared weak), and this object does
+ not get pulled from libgcc.a for other reasons, then the
+ invocation of __deregister_frame_info will be resolved from glibc.
+ Since the registration did not happen there, we'll abort.
+
+ Therefore, declare a new deregistration entry point that does the
+ exact same thing, but will resolve to the same library as
+ implements __register_frame_info_bases. */
+
+void *
+__deregister_frame_info_bases (void *begin)
+{
+ struct object **p;
+ struct object *ob = 0;
+
+ /* If .eh_frame is empty, we haven't registered. */
+ if (*(uword *) begin == 0)
+ return ob;
+
+ init_object_mutex_once ();
+ __gthread_mutex_lock (&object_mutex);
+
+ for (p = &unseen_objects; *p ; p = &(*p)->next)
+ if ((*p)->u.single == begin)
+ {
+ ob = *p;
+ *p = ob->next;
+ goto out;
+ }
+
+ for (p = &seen_objects; *p ; p = &(*p)->next)
+ if ((*p)->s.b.sorted)
+ {
+ if ((*p)->u.sort->orig_data == begin)
+ {
+ ob = *p;
+ *p = ob->next;
+ free (ob->u.sort);
+ goto out;
+ }
+ }
+ else
+ {
+ if ((*p)->u.single == begin)
+ {
+ ob = *p;
+ *p = ob->next;
+ goto out;
+ }
+ }
+
+ __gthread_mutex_unlock (&object_mutex);
+ abort ();
+
+ out:
+ __gthread_mutex_unlock (&object_mutex);
+ return (void *) ob;
+}
+INTDEF(__deregister_frame_info_bases)
+
+void *
+__deregister_frame_info (void *begin)
+{
+ return INTUSE(__deregister_frame_info_bases) (begin);
+}
+
+void
+__deregister_frame (void *begin)
+{
+ /* If .eh_frame is empty, we haven't registered. */
+ if (*(uword *) begin != 0)
+ free (INTUSE(__deregister_frame_info_bases) (begin));
+}
+
+
+/* Like base_of_encoded_value, but take the base from a struct object
+ instead of an _Unwind_Context. */
+
+static _Unwind_Ptr
+base_from_object (unsigned char encoding, struct object *ob)
+{
+ if (encoding == DW_EH_PE_omit)
+ return 0;
+
+ switch (encoding & 0x70)
+ {
+ case DW_EH_PE_absptr:
+ case DW_EH_PE_pcrel:
+ case DW_EH_PE_aligned:
+ return 0;
+
+ case DW_EH_PE_textrel:
+ return (_Unwind_Ptr) ob->tbase;
+ case DW_EH_PE_datarel:
+ return (_Unwind_Ptr) ob->dbase;
+ }
+ abort ();
+}
+
+/* Return the FDE pointer encoding from the CIE. */
+/* ??? This is a subset of extract_cie_info from unwind-dw2.c. */
+
+static int
+get_cie_encoding (struct dwarf_cie *cie)
+{
+ const unsigned char *aug, *p;
+ _Unwind_Ptr dummy;
+ _Unwind_Word utmp;
+ _Unwind_Sword stmp;
+
+ aug = cie->augmentation;
+ if (aug[0] != 'z')
+ return DW_EH_PE_absptr;
+
+ p = aug + strlen (aug) + 1; /* Skip the augmentation string. */
+ p = read_uleb128 (p, &utmp); /* Skip code alignment. */
+ p = read_sleb128 (p, &stmp); /* Skip data alignment. */
+ p++; /* Skip return address column. */
+
+ aug++; /* Skip 'z' */
+ p = read_uleb128 (p, &utmp); /* Skip augmentation length. */
+ while (1)
+ {
+ /* This is what we're looking for. */
+ if (*aug == 'R')
+ return *p;
+ /* Personality encoding and pointer. */
+ else if (*aug == 'P')
+ {
+ /* ??? Avoid dereferencing indirect pointers, since we're
+ faking the base address. Gotta keep DW_EH_PE_aligned
+ intact, however. */
+ p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy);
+ }
+ /* LSDA encoding. */
+ else if (*aug == 'L')
+ p++;
+ /* Otherwise end of string, or unknown augmentation. */
+ else
+ return DW_EH_PE_absptr;
+ aug++;
+ }
+}
+
+static inline int
+get_fde_encoding (struct dwarf_fde *f)
+{
+ return get_cie_encoding (get_cie (f));
+}
+
+
+/* Sorting an array of FDEs by address.
+ (Ideally we would have the linker sort the FDEs so we don't have to do
+ it at run time. But the linkers are not yet prepared for this.) */
+
+/* Comparison routines. Three variants of increasing complexity. */
+
+static int
+fde_unencoded_compare (struct object *ob __attribute__((unused)),
+ fde *x, fde *y)
+{
+ _Unwind_Ptr x_ptr = *(_Unwind_Ptr *) x->pc_begin;
+ _Unwind_Ptr y_ptr = *(_Unwind_Ptr *) y->pc_begin;
+
+ if (x_ptr > y_ptr)
+ return 1;
+ if (x_ptr < y_ptr)
+ return -1;
+ return 0;
+}
+
+static int
+fde_single_encoding_compare (struct object *ob, fde *x, fde *y)
+{
+ _Unwind_Ptr base, x_ptr, y_ptr;
+
+ base = base_from_object (ob->s.b.encoding, ob);
+ read_encoded_value_with_base (ob->s.b.encoding, base, x->pc_begin, &x_ptr);
+ read_encoded_value_with_base (ob->s.b.encoding, base, y->pc_begin, &y_ptr);
+
+ if (x_ptr > y_ptr)
+ return 1;
+ if (x_ptr < y_ptr)
+ return -1;
+ return 0;
+}
+
+static int
+fde_mixed_encoding_compare (struct object *ob, fde *x, fde *y)
+{
+ int x_encoding, y_encoding;
+ _Unwind_Ptr x_ptr, y_ptr;
+
+ x_encoding = get_fde_encoding (x);
+ read_encoded_value_with_base (x_encoding, base_from_object (x_encoding, ob),
+ x->pc_begin, &x_ptr);
+
+ y_encoding = get_fde_encoding (y);
+ read_encoded_value_with_base (y_encoding, base_from_object (y_encoding, ob),
+ y->pc_begin, &y_ptr);
+
+ if (x_ptr > y_ptr)
+ return 1;
+ if (x_ptr < y_ptr)
+ return -1;
+ return 0;
+}
+
+typedef int (*fde_compare_t) (struct object *, fde *, fde *);
+
+
+/* This is a special mix of insertion sort and heap sort, optimized for
+ the data sets that actually occur. They look like
+ 101 102 103 127 128 105 108 110 190 111 115 119 125 160 126 129 130.
+ I.e. a linearly increasing sequence (coming from functions in the text
+ section), with additionally a few unordered elements (coming from functions
+ in gnu_linkonce sections) whose values are higher than the values in the
+ surrounding linear sequence (but not necessarily higher than the values
+ at the end of the linear sequence!).
+ The worst-case total run time is O(N) + O(n log (n)), where N is the
+ total number of FDEs and n is the number of erratic ones. */
+
+struct fde_accumulator
+{
+ struct fde_vector *linear;
+ struct fde_vector *erratic;
+};
+
+static int
+start_fde_sort (struct fde_accumulator *accu, size_t count)
+{
+ size_t size;
+ if (! count)
+ return 0;
+
+ size = sizeof (struct fde_vector) + sizeof (fde *) * count;
+ if ((accu->linear = (struct fde_vector *) malloc (size)))
+ {
+ accu->linear->count = 0;
+ if ((accu->erratic = (struct fde_vector *) malloc (size)))
+ accu->erratic->count = 0;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+static inline void
+fde_insert (struct fde_accumulator *accu, fde *this_fde)
+{
+ if (accu->linear)
+ accu->linear->array[accu->linear->count++] = this_fde;
+}
+
+/* Split LINEAR into a linear sequence with low values and an erratic
+ sequence with high values, put the linear one (of longest possible
+ length) into LINEAR and the erratic one into ERRATIC. This is O(N).
+
+ Because the longest linear sequence we are trying to locate within the
+ incoming LINEAR array can be interspersed with (high valued) erratic
+ entries. We construct a chain indicating the sequenced entries.
+ To avoid having to allocate this chain, we overlay it onto the space of
+ the ERRATIC array during construction. A final pass iterates over the
+ chain to determine what should be placed in the ERRATIC array, and
+ what is the linear sequence. This overlay is safe from aliasing. */
+
+static void
+fde_split (struct object *ob, fde_compare_t fde_compare,
+ struct fde_vector *linear, struct fde_vector *erratic)
+{
+ static fde *marker;
+ size_t count = linear->count;
+ fde **chain_end = &marker;
+ size_t i, j, k;
+
+ /* This should optimize out, but it is wise to make sure this assumption
+ is correct. Should these have different sizes, we cannot cast between
+ them and the overlaying onto ERRATIC will not work. */
+ if (sizeof (fde *) != sizeof (fde **))
+ abort ();
+
+ for (i = 0; i < count; i++)
+ {
+ fde **probe;
+
+ for (probe = chain_end;
+ probe != &marker && fde_compare (ob, linear->array[i], *probe) < 0;
+ probe = chain_end)
+ {
+ chain_end = (fde **) erratic->array[probe - linear->array];
+ erratic->array[probe - linear->array] = NULL;
+ }
+ erratic->array[i] = (fde *) chain_end;
+ chain_end = &linear->array[i];
+ }
+
+ /* Each entry in LINEAR which is part of the linear sequence we have
+ discovered will correspond to a non-NULL entry in the chain we built in
+ the ERRATIC array. */
+ for (i = j = k = 0; i < count; i++)
+ if (erratic->array[i])
+ linear->array[j++] = linear->array[i];
+ else
+ erratic->array[k++] = linear->array[i];
+ linear->count = j;
+ erratic->count = k;
+}
+
+/* This is O(n log(n)). BSD/OS defines heapsort in stdlib.h, so we must
+ use a name that does not conflict. */
+
+static void
+frame_heapsort (struct object *ob, fde_compare_t fde_compare,
+ struct fde_vector *erratic)
+{
+ /* For a description of this algorithm, see:
+ Samuel P. Harbison, Guy L. Steele Jr.: C, a reference manual, 2nd ed.,
+ p. 60-61. */
+ fde ** a = erratic->array;
+ /* A portion of the array is called a "heap" if for all i>=0:
+ If i and 2i+1 are valid indices, then a[i] >= a[2i+1].
+ If i and 2i+2 are valid indices, then a[i] >= a[2i+2]. */
+#define SWAP(x,y) do { fde * tmp = x; x = y; y = tmp; } while (0)
+ size_t n = erratic->count;
+ size_t m = n;
+ size_t i;
+
+ while (m > 0)
+ {
+ /* Invariant: a[m..n-1] is a heap. */
+ m--;
+ for (i = m; 2*i+1 < n; )
+ {
+ if (2*i+2 < n
+ && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
+ && fde_compare (ob, a[2*i+2], a[i]) > 0)
+ {
+ SWAP (a[i], a[2*i+2]);
+ i = 2*i+2;
+ }
+ else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
+ {
+ SWAP (a[i], a[2*i+1]);
+ i = 2*i+1;
+ }
+ else
+ break;
+ }
+ }
+ while (n > 1)
+ {
+ /* Invariant: a[0..n-1] is a heap. */
+ n--;
+ SWAP (a[0], a[n]);
+ for (i = 0; 2*i+1 < n; )
+ {
+ if (2*i+2 < n
+ && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
+ && fde_compare (ob, a[2*i+2], a[i]) > 0)
+ {
+ SWAP (a[i], a[2*i+2]);
+ i = 2*i+2;
+ }
+ else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
+ {
+ SWAP (a[i], a[2*i+1]);
+ i = 2*i+1;
+ }
+ else
+ break;
+ }
+ }
+#undef SWAP
+}
+
+/* Merge V1 and V2, both sorted, and put the result into V1. */
+static void
+fde_merge (struct object *ob, fde_compare_t fde_compare,
+ struct fde_vector *v1, struct fde_vector *v2)
+{
+ size_t i1, i2;
+ fde * fde2;
+
+ i2 = v2->count;
+ if (i2 > 0)
+ {
+ i1 = v1->count;
+ do
+ {
+ i2--;
+ fde2 = v2->array[i2];
+ while (i1 > 0 && fde_compare (ob, v1->array[i1-1], fde2) > 0)
+ {
+ v1->array[i1+i2] = v1->array[i1-1];
+ i1--;
+ }
+ v1->array[i1+i2] = fde2;
+ }
+ while (i2 > 0);
+ v1->count += v2->count;
+ }
+}
+
+static void
+end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
+{
+ fde_compare_t fde_compare;
+
+ if (accu->linear->count != count)
+ abort ();
+
+ if (ob->s.b.mixed_encoding)
+ fde_compare = fde_mixed_encoding_compare;
+ else if (ob->s.b.encoding == DW_EH_PE_absptr)
+ fde_compare = fde_unencoded_compare;
+ else
+ fde_compare = fde_single_encoding_compare;
+
+ if (accu->erratic)
+ {
+ fde_split (ob, fde_compare, accu->linear, accu->erratic);
+ if (accu->linear->count + accu->erratic->count != count)
+ abort ();
+ frame_heapsort (ob, fde_compare, accu->erratic);
+ fde_merge (ob, fde_compare, accu->linear, accu->erratic);
+ free (accu->erratic);
+ }
+ else
+ {
+ /* We've not managed to malloc an erratic array,
+ so heap sort in the linear one. */
+ frame_heapsort (ob, fde_compare, accu->linear);
+ }
+}
+
+
+/* Update encoding, mixed_encoding, and pc_begin for OB for the
+ fde array beginning at THIS_FDE. Return the number of fdes
+ encountered along the way. */
+
+static size_t
+classify_object_over_fdes (struct object *ob, fde *this_fde)
+{
+ struct dwarf_cie *last_cie = 0;
+ size_t count = 0;
+ int encoding = DW_EH_PE_absptr;
+ _Unwind_Ptr base = 0;
+
+ for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
+ {
+ struct dwarf_cie *this_cie;
+ _Unwind_Ptr mask, pc_begin;
+
+ /* Skip CIEs. */
+ if (this_fde->CIE_delta == 0)
+ continue;
+
+ /* Determine the encoding for this FDE. Note mixed encoded
+ objects for later. */
+ this_cie = get_cie (this_fde);
+ if (this_cie != last_cie)
+ {
+ last_cie = this_cie;
+ encoding = get_cie_encoding (this_cie);
+ base = base_from_object (encoding, ob);
+ if (ob->s.b.encoding == DW_EH_PE_omit)
+ ob->s.b.encoding = encoding;
+ else if (ob->s.b.encoding != encoding)
+ ob->s.b.mixed_encoding = 1;
+ }
+
+ read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
+ &pc_begin);
+
+ /* Take care to ignore link-once functions that were removed.
+ In these cases, the function address will be NULL, but if
+ the encoding is smaller than a pointer a true NULL may not
+ be representable. Assume 0 in the representable bits is NULL. */
+ mask = size_of_encoded_value (encoding);
+ if (mask < sizeof (void *))
+ mask = (1L << (mask << 3)) - 1;
+ else
+ mask = -1;
+
+ if ((pc_begin & mask) == 0)
+ continue;
+
+ count += 1;
+ if ((void *) pc_begin < ob->pc_begin)
+ ob->pc_begin = (void *) pc_begin;
+ }
+
+ return count;
+}
+
+static void
+add_fdes (struct object *ob, struct fde_accumulator *accu, fde *this_fde)
+{
+ struct dwarf_cie *last_cie = 0;
+ int encoding = ob->s.b.encoding;
+ _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
+
+ for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
+ {
+ struct dwarf_cie *this_cie;
+
+ /* Skip CIEs. */
+ if (this_fde->CIE_delta == 0)
+ continue;
+
+ if (ob->s.b.mixed_encoding)
+ {
+ /* Determine the encoding for this FDE. Note mixed encoded
+ objects for later. */
+ this_cie = get_cie (this_fde);
+ if (this_cie != last_cie)
+ {
+ last_cie = this_cie;
+ encoding = get_cie_encoding (this_cie);
+ base = base_from_object (encoding, ob);
+ }
+ }
+
+ if (encoding == DW_EH_PE_absptr)
+ {
+ if (*(_Unwind_Ptr *) this_fde->pc_begin == 0)
+ continue;
+ }
+ else
+ {
+ _Unwind_Ptr pc_begin, mask;
+
+ read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
+ &pc_begin);
+
+ /* Take care to ignore link-once functions that were removed.
+ In these cases, the function address will be NULL, but if
+ the encoding is smaller than a pointer a true NULL may not
+ be representable. Assume 0 in the representable bits is NULL. */
+ mask = size_of_encoded_value (encoding);
+ if (mask < sizeof (void *))
+ mask = (1L << (mask << 3)) - 1;
+ else
+ mask = -1;
+
+ if ((pc_begin & mask) == 0)
+ continue;
+ }
+
+ fde_insert (accu, this_fde);
+ }
+}
+
+/* Set up a sorted array of pointers to FDEs for a loaded object. We
+ count up the entries before allocating the array because it's likely to
+ be faster. We can be called multiple times, should we have failed to
+ allocate a sorted fde array on a previous occasion. */
+
+static void
+init_object (struct object* ob)
+{
+ struct fde_accumulator accu;
+ size_t count;
+
+ count = ob->s.b.count;
+ if (count == 0)
+ {
+ if (ob->s.b.from_array)
+ {
+ fde **p = ob->u.array;
+ for (count = 0; *p; ++p)
+ count += classify_object_over_fdes (ob, *p);
+ }
+ else
+ count = classify_object_over_fdes (ob, ob->u.single);
+
+ /* The count field we have in the main struct object is somewhat
+ limited, but should suffice for virtually all cases. If the
+ counted value doesn't fit, re-write a zero. The worst that
+ happens is that we re-count next time -- admittedly non-trivial
+ in that this implies some 2M fdes, but at least we function. */
+ ob->s.b.count = count;
+ if (ob->s.b.count != count)
+ ob->s.b.count = 0;
+ }
+
+ if (!start_fde_sort (&accu, count))
+ return;
+
+ if (ob->s.b.from_array)
+ {
+ fde **p;
+ for (p = ob->u.array; *p; ++p)
+ add_fdes (ob, &accu, *p);
+ }
+ else
+ add_fdes (ob, &accu, ob->u.single);
+
+ end_fde_sort (ob, &accu, count);
+
+ /* Save the original fde pointer, since this is the key by which the
+ DSO will deregister the object. */
+ accu.linear->orig_data = ob->u.single;
+ ob->u.sort = accu.linear;
+
+ ob->s.b.sorted = 1;
+}
+
+/* A linear search through a set of FDEs for the given PC. This is
+ used when there was insufficient memory to allocate and sort an
+ array. */
+
+static fde *
+linear_search_fdes (struct object *ob, fde *this_fde, void *pc)
+{
+ struct dwarf_cie *last_cie = 0;
+ int encoding = ob->s.b.encoding;
+ _Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
+
+ for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
+ {
+ struct dwarf_cie *this_cie;
+ _Unwind_Ptr pc_begin, pc_range;
+
+ /* Skip CIEs. */
+ if (this_fde->CIE_delta == 0)
+ continue;
+
+ if (ob->s.b.mixed_encoding)
+ {
+ /* Determine the encoding for this FDE. Note mixed encoded
+ objects for later. */
+ this_cie = get_cie (this_fde);
+ if (this_cie != last_cie)
+ {
+ last_cie = this_cie;
+ encoding = get_cie_encoding (this_cie);
+ base = base_from_object (encoding, ob);
+ }
+ }
+
+ if (encoding == DW_EH_PE_absptr)
+ {
+ pc_begin = ((_Unwind_Ptr *) this_fde->pc_begin)[0];
+ pc_range = ((_Unwind_Ptr *) this_fde->pc_begin)[1];
+ if (pc_begin == 0)
+ continue;
+ }
+ else
+ {
+ _Unwind_Ptr mask;
+ const char *p;
+
+ p = read_encoded_value_with_base (encoding, base,
+ this_fde->pc_begin, &pc_begin);
+ read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
+
+ /* Take care to ignore link-once functions that were removed.
+ In these cases, the function address will be NULL, but if
+ the encoding is smaller than a pointer a true NULL may not
+ be representable. Assume 0 in the representable bits is NULL. */
+ mask = size_of_encoded_value (encoding);
+ if (mask < sizeof (void *))
+ mask = (1L << (mask << 3)) - 1;
+ else
+ mask = -1;
+
+ if ((pc_begin & mask) == 0)
+ continue;
+ }
+
+ if ((_Unwind_Ptr) pc - pc_begin < pc_range)
+ return this_fde;
+ }
+
+ return NULL;
+}
+
+/* Binary search for an FDE containing the given PC. Here are three
+ implementations of increasing complexity. */
+
+static fde *
+binary_search_unencoded_fdes (struct object *ob, void *pc)
+{
+ struct fde_vector *vec = ob->u.sort;
+ size_t lo, hi;
+
+ for (lo = 0, hi = vec->count; lo < hi; )
+ {
+ size_t i = (lo + hi) / 2;
+ fde *f = vec->array[i];
+ void *pc_begin;
+ uaddr pc_range;
+
+ pc_begin = ((void **) f->pc_begin)[0];
+ pc_range = ((uaddr *) f->pc_begin)[1];
+
+ if (pc < pc_begin)
+ hi = i;
+ else if (pc >= pc_begin + pc_range)
+ lo = i + 1;
+ else
+ return f;
+ }
+
+ return NULL;
+}
+
+static fde *
+binary_search_single_encoding_fdes (struct object *ob, void *pc)
+{
+ struct fde_vector *vec = ob->u.sort;
+ int encoding = ob->s.b.encoding;
+ _Unwind_Ptr base = base_from_object (encoding, ob);
+ size_t lo, hi;
+
+ for (lo = 0, hi = vec->count; lo < hi; )
+ {
+ size_t i = (lo + hi) / 2;
+ fde *f = vec->array[i];
+ _Unwind_Ptr pc_begin, pc_range;
+ const char *p;
+
+ p = read_encoded_value_with_base (encoding, base, f->pc_begin,
+ &pc_begin);
+ read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
+
+ if ((_Unwind_Ptr) pc < pc_begin)
+ hi = i;
+ else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
+ lo = i + 1;
+ else
+ return f;
+ }
+
+ return NULL;
+}
+
+static fde *
+binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
+{
+ struct fde_vector *vec = ob->u.sort;
+ size_t lo, hi;
+
+ for (lo = 0, hi = vec->count; lo < hi; )
+ {
+ size_t i = (lo + hi) / 2;
+ fde *f = vec->array[i];
+ _Unwind_Ptr pc_begin, pc_range;
+ const char *p;
+ int encoding;
+
+ encoding = get_fde_encoding (f);
+ p = read_encoded_value_with_base (encoding,
+ base_from_object (encoding, ob),
+ f->pc_begin, &pc_begin);
+ read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);
+
+ if ((_Unwind_Ptr) pc < pc_begin)
+ hi = i;
+ else if ((_Unwind_Ptr) pc >= pc_begin + pc_range)
+ lo = i + 1;
+ else
+ return f;
+ }
+
+ return NULL;
+}
+
+static fde *
+search_object (struct object* ob, void *pc)
+{
+ /* If the data hasn't been sorted, try to do this now. We may have
+ more memory available than last time we tried. */
+ if (! ob->s.b.sorted)
+ {
+ init_object (ob);
+
+ /* Despite the above comment, the normal reason to get here is
+ that we've not processed this object before. A quick range
+ check is in order. */
+ if (pc < ob->pc_begin)
+ return NULL;
+ }
+
+ if (ob->s.b.sorted)
+ {
+ if (ob->s.b.mixed_encoding)
+ return binary_search_mixed_encoding_fdes (ob, pc);
+ else if (ob->s.b.encoding == DW_EH_PE_absptr)
+ return binary_search_unencoded_fdes (ob, pc);
+ else
+ return binary_search_single_encoding_fdes (ob, pc);
+ }
+ else
+ {
+ /* Long slow labourious linear search, cos we've no memory. */
+ if (ob->s.b.from_array)
+ {
+ fde **p;
+ for (p = ob->u.array; *p ; p++)
+ {
+ fde *f = linear_search_fdes (ob, *p, pc);
+ if (f)
+ return f;
+ }
+ return NULL;
+ }
+ else
+ return linear_search_fdes (ob, ob->u.single, pc);
+ }
+}
+
+fde *
+_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
+{
+ struct object *ob;
+ fde *f = NULL;
+
+ init_object_mutex_once ();
+ __gthread_mutex_lock (&object_mutex);
+
+ /* Linear search through the classified objects, to find the one
+ containing the pc. Note that pc_begin is sorted descending, and
+ we expect objects to be non-overlapping. */
+ for (ob = seen_objects; ob; ob = ob->next)
+ if (pc >= ob->pc_begin)
+ {
+ f = search_object (ob, pc);
+ if (f)
+ goto fini;
+ break;
+ }
+
+ /* Classify and search the objects we've not yet processed. */
+ while ((ob = unseen_objects))
+ {
+ struct object **p;
+
+ unseen_objects = ob->next;
+ f = search_object (ob, pc);
+
+ /* Insert the object into the classified list. */
+ for (p = &seen_objects; *p ; p = &(*p)->next)
+ if ((*p)->pc_begin < ob->pc_begin)
+ break;
+ ob->next = *p;
+ *p = ob;
+
+ if (f)
+ goto fini;
+ }
+
+ fini:
+ __gthread_mutex_unlock (&object_mutex);
+
+ if (f)
+ {
+ int encoding;
+
+ bases->tbase = ob->tbase;
+ bases->dbase = ob->dbase;
+
+ encoding = ob->s.b.encoding;
+ if (ob->s.b.mixed_encoding)
+ encoding = get_fde_encoding (f);
+ read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
+ f->pc_begin, (_Unwind_Ptr *)&bases->func);
+ }
+
+ return f;
+}
+
+#endif
diff --git a/libc/sysdeps/generic/unwind-dw2-fde.h b/libc/sysdeps/generic/unwind-dw2-fde.h
new file mode 100644
index 000000000..01d4f099d
--- /dev/null
+++ b/libc/sysdeps/generic/unwind-dw2-fde.h
@@ -0,0 +1,171 @@
+/* Subroutines needed for unwinding stack frames for exception handling. */
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
+ Contributed by Jason Merrill <jason@cygnus.com>.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+struct fde_vector
+{
+ void *orig_data;
+ size_t count;
+ struct dwarf_fde *array __flexarr;
+};
+
+#ifdef _LIBC
+#include <gccframe.h>
+#else
+struct object
+{
+ void *pc_begin;
+ void *tbase;
+ void *dbase;
+ union {
+ struct dwarf_fde *single;
+ struct dwarf_fde **array;
+ struct fde_vector *sort;
+ } u;
+
+ union {
+ struct {
+ unsigned long sorted : 1;
+ unsigned long from_array : 1;
+ unsigned long mixed_encoding : 1;
+ unsigned long encoding : 8;
+ /* ??? Wish there was an easy way to detect a 64-bit host here;
+ we've got 32 bits left to play with... */
+ unsigned long count : 21;
+ } b;
+ size_t i;
+ } s;
+
+#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
+ char *fde_end;
+#endif
+
+ struct object *next;
+};
+#endif
+
+/* This is the original definition of struct object. While the struct
+ itself was opaque to users, they did know how large it was, and
+ allocate one statically in crtbegin for each DSO. Keep this around
+ so that we're aware of the static size limitations for the new struct. */
+struct old_object
+{
+ void *pc_begin;
+ void *pc_end;
+ struct dwarf_fde *fde_begin;
+ struct dwarf_fde **fde_array;
+ size_t count;
+ struct old_object *next;
+};
+
+struct dwarf_eh_bases
+{
+ void *tbase;
+ void *dbase;
+ void *func;
+};
+
+
+extern void __register_frame_info_bases (void *, struct object *,
+ void *, void *);
+extern void __register_frame_info (void *, struct object *);
+extern void __register_frame (void *);
+extern void __register_frame_info_table_bases (void *, struct object *,
+ void *, void *);
+extern void __register_frame_info_table (void *, struct object *);
+extern void __register_frame_table (void *);
+extern void *__deregister_frame_info (void *);
+extern void *__deregister_frame_info_bases (void *);
+extern void __deregister_frame (void *);
+
+
+typedef int sword __attribute__ ((mode (SI)));
+typedef unsigned int uword __attribute__ ((mode (SI)));
+typedef unsigned int uaddr __attribute__ ((mode (pointer)));
+typedef int saddr __attribute__ ((mode (pointer)));
+typedef unsigned char ubyte;
+
+/* Terminology:
+ CIE - Common Information Element
+ FDE - Frame Descriptor Element
+
+ There is one per function, and it describes where the function code
+ is located, and what the register lifetimes and stack layout are
+ within the function.
+
+ The data structures are defined in the DWARF specification, although
+ not in a very readable way (see LITERATURE).
+
+ Every time an exception is thrown, the code needs to locate the FDE
+ for the current function, and starts to look for exception regions
+ from that FDE. This works in a two-level search:
+ a) in a linear search, find the shared image (i.e. DLL) containing
+ the PC
+ b) using the FDE table for that shared object, locate the FDE using
+ binary search (which requires the sorting). */
+
+/* The first few fields of a CIE. The CIE_id field is 0 for a CIE,
+ to distinguish it from a valid FDE. FDEs are aligned to an addressing
+ unit boundary, but the fields within are unaligned. */
+struct dwarf_cie
+{
+ uword length;
+ sword CIE_id;
+ ubyte version;
+ unsigned char augmentation __flexarr;
+} __attribute__ ((packed, aligned (__alignof__ (void *))));
+
+/* The first few fields of an FDE. */
+struct dwarf_fde
+{
+ uword length;
+ sword CIE_delta;
+ unsigned char pc_begin __flexarr;
+} __attribute__ ((packed, aligned (__alignof__ (void *))));
+
+typedef struct dwarf_fde fde;
+
+/* Locate the CIE for a given FDE. */
+
+static inline struct dwarf_cie *
+get_cie (struct dwarf_fde *f)
+{
+ return (void *)&f->CIE_delta - f->CIE_delta;
+}
+
+static inline fde *
+next_fde (fde *f)
+{
+ return (fde *) ((char *) f + f->length + sizeof (f->length));
+}
+
+extern fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
+
+static inline int
+last_fde (struct object *obj __attribute__ ((__unused__)), fde *f)
+{
+#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
+ return (char *)f == obj->fde_end || f->length == 0;
+#else
+ return f->length == 0;
+#endif
+}
diff --git a/libc/sysdeps/generic/unwind-dw2.c b/libc/sysdeps/generic/unwind-dw2.c
new file mode 100644
index 000000000..d818e5dfd
--- /dev/null
+++ b/libc/sysdeps/generic/unwind-dw2.c
@@ -0,0 +1,1300 @@
+/* DWARF2 exception handling and frame unwind runtime interface routines.
+ Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2005,2006
+ Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef _LIBC
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+#include <libintl.h>
+#include <dwarf2.h>
+#include <stdio.h>
+#include <unwind.h>
+#include <unwind-pe.h>
+#include <unwind-dw2-fde.h>
+#else
+#include "tconfig.h"
+#include "tsystem.h"
+#include "dwarf2.h"
+#include "unwind.h"
+#include "unwind-pe.h"
+#include "unwind-dw2-fde.h"
+#include "gthr.h"
+#endif
+
+
+
+#ifndef STACK_GROWS_DOWNWARD
+#define STACK_GROWS_DOWNWARD 0
+#else
+#undef STACK_GROWS_DOWNWARD
+#define STACK_GROWS_DOWNWARD 1
+#endif
+
+/* A target can override (perhaps for backward compatibility) how
+ many dwarf2 columns are unwound. */
+#ifndef DWARF_FRAME_REGISTERS
+#define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
+#endif
+
+/* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
+#ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
+#define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
+#endif
+
+/* This is the register and unwind state for a particular frame. This
+ provides the information necessary to unwind up past a frame and return
+ to its caller. */
+struct _Unwind_Context
+{
+ void *reg[DWARF_FRAME_REGISTERS+1];
+ void *cfa;
+ void *ra;
+ void *lsda;
+ struct dwarf_eh_bases bases;
+ _Unwind_Word args_size;
+};
+
+#ifndef _LIBC
+/* Byte size of every register managed by these routines. */
+static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
+#endif
+
+
+/* The result of interpreting the frame unwind info for a frame.
+ This is all symbolic at this point, as none of the values can
+ be resolved until the target pc is located. */
+typedef struct
+{
+ /* Each register save state can be described in terms of a CFA slot,
+ another register, or a location expression. */
+ struct frame_state_reg_info
+ {
+ struct {
+ union {
+ _Unwind_Word reg;
+ _Unwind_Sword offset;
+ const unsigned char *exp;
+ } loc;
+ enum {
+ REG_UNSAVED,
+ REG_SAVED_OFFSET,
+ REG_SAVED_REG,
+ REG_SAVED_EXP,
+ } how;
+ } reg[DWARF_FRAME_REGISTERS+1];
+
+ /* Used to implement DW_CFA_remember_state. */
+ struct frame_state_reg_info *prev;
+ } regs;
+
+ /* The CFA can be described in terms of a reg+offset or a
+ location expression. */
+ _Unwind_Sword cfa_offset;
+ _Unwind_Word cfa_reg;
+ const unsigned char *cfa_exp;
+ enum {
+ CFA_UNSET,
+ CFA_REG_OFFSET,
+ CFA_EXP,
+ } cfa_how;
+
+ /* The PC described by the current frame state. */
+ void *pc;
+
+ /* The information we care about from the CIE/FDE. */
+ _Unwind_Personality_Fn personality;
+ _Unwind_Sword data_align;
+ _Unwind_Word code_align;
+ unsigned char retaddr_column;
+ unsigned char fde_encoding;
+ unsigned char lsda_encoding;
+ unsigned char saw_z;
+ void *eh_ptr;
+} _Unwind_FrameState;
+
+/* Read unaligned data from the instruction buffer. */
+
+union unaligned
+{
+ void *p;
+ unsigned u2 __attribute__ ((mode (HI)));
+ unsigned u4 __attribute__ ((mode (SI)));
+ unsigned u8 __attribute__ ((mode (DI)));
+ signed s2 __attribute__ ((mode (HI)));
+ signed s4 __attribute__ ((mode (SI)));
+ signed s8 __attribute__ ((mode (DI)));
+} __attribute__ ((packed));
+
+static inline void *
+read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
+
+static inline int
+read_1u (const void *p) { return *(const unsigned char *) p; }
+
+static inline int
+read_1s (const void *p) { return *(const signed char *) p; }
+
+static inline int
+read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
+
+static inline int
+read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
+
+static inline unsigned int
+read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
+
+static inline int
+read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
+
+static inline unsigned long
+read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
+
+static inline unsigned long
+read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
+
+/* Get the value of register REG as saved in CONTEXT. */
+
+inline _Unwind_Word
+_Unwind_GetGR (struct _Unwind_Context *context, int index)
+{
+ /* This will segfault if the register hasn't been saved. */
+ return * (_Unwind_Word *) context->reg[index];
+}
+
+/* Get the value of the CFA as saved in CONTEXT. */
+
+_Unwind_Word
+_Unwind_GetCFA (struct _Unwind_Context *context)
+{
+ return (_Unwind_Ptr) context->cfa;
+}
+
+/* Overwrite the saved value for register REG in CONTEXT with VAL. */
+
+inline void
+_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
+{
+ * (_Unwind_Word *) context->reg[index] = val;
+}
+
+/* Retrieve the return address for CONTEXT. */
+
+inline _Unwind_Ptr
+_Unwind_GetIP (struct _Unwind_Context *context)
+{
+ return (_Unwind_Ptr) context->ra;
+}
+
+/* Overwrite the return address for CONTEXT with VAL. */
+
+inline void
+_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
+{
+ context->ra = (void *) val;
+}
+
+void *
+_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
+{
+ return context->lsda;
+}
+
+_Unwind_Ptr
+_Unwind_GetRegionStart (struct _Unwind_Context *context)
+{
+ return (_Unwind_Ptr) context->bases.func;
+}
+
+void *
+_Unwind_FindEnclosingFunction (void *pc)
+{
+ struct dwarf_eh_bases bases;
+ struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
+ if (fde)
+ return bases.func;
+ else
+ return NULL;
+}
+
+#ifndef __ia64__
+_Unwind_Ptr
+_Unwind_GetDataRelBase (struct _Unwind_Context *context)
+{
+ return (_Unwind_Ptr) context->bases.dbase;
+}
+
+_Unwind_Ptr
+_Unwind_GetTextRelBase (struct _Unwind_Context *context)
+{
+ return (_Unwind_Ptr) context->bases.tbase;
+}
+#endif
+
+/* Extract any interesting information from the CIE for the translation
+ unit F belongs to. Return a pointer to the byte after the augmentation,
+ or NULL if we encountered an undecipherable augmentation. */
+
+static const unsigned char *
+extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
+ _Unwind_FrameState *fs)
+{
+ const unsigned char *aug = cie->augmentation;
+ const unsigned char *p = aug + strlen ((const char *) aug) + 1;
+ const unsigned char *ret = NULL;
+ _Unwind_Word utmp;
+
+ /* g++ v2 "eh" has pointer immediately following augmentation string,
+ so it must be handled first. */
+ if (aug[0] == 'e' && aug[1] == 'h')
+ {
+ fs->eh_ptr = read_pointer (p);
+ p += sizeof (void *);
+ aug += 2;
+ }
+
+ /* Immediately following the augmentation are the code and
+ data alignment and return address column. */
+ p = read_uleb128 (p, &fs->code_align);
+ p = read_sleb128 (p, &fs->data_align);
+ fs->retaddr_column = *p++;
+ fs->lsda_encoding = DW_EH_PE_omit;
+
+ /* If the augmentation starts with 'z', then a uleb128 immediately
+ follows containing the length of the augmentation field following
+ the size. */
+ if (*aug == 'z')
+ {
+ p = read_uleb128 (p, &utmp);
+ ret = p + utmp;
+
+ fs->saw_z = 1;
+ ++aug;
+ }
+
+ /* Iterate over recognized augmentation subsequences. */
+ while (*aug != '\0')
+ {
+ /* "L" indicates a byte showing how the LSDA pointer is encoded. */
+ if (aug[0] == 'L')
+ {
+ fs->lsda_encoding = *p++;
+ aug += 1;
+ }
+
+ /* "R" indicates a byte indicating how FDE addresses are encoded. */
+ else if (aug[0] == 'R')
+ {
+ fs->fde_encoding = *p++;
+ aug += 1;
+ }
+
+ /* "P" indicates a personality routine in the CIE augmentation. */
+ else if (aug[0] == 'P')
+ {
+ p = read_encoded_value (context, *p, p + 1,
+ (_Unwind_Ptr *) &fs->personality);
+ aug += 1;
+ }
+
+ /* Otherwise we have an unknown augmentation string.
+ Bail unless we saw a 'z' prefix. */
+ else
+ return ret;
+ }
+
+ return ret ? ret : p;
+}
+
+#ifndef _LIBC
+/* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
+ onto the stack to start. */
+
+static _Unwind_Word
+execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
+ struct _Unwind_Context *context, _Unwind_Word initial)
+{
+ _Unwind_Word stack[64]; /* ??? Assume this is enough. */
+ int stack_elt;
+
+ stack[0] = initial;
+ stack_elt = 1;
+
+ while (op_ptr < op_end)
+ {
+ enum dwarf_location_atom op = *op_ptr++;
+ _Unwind_Word result, reg, utmp;
+ _Unwind_Sword offset, stmp;
+
+ switch (op)
+ {
+ case DW_OP_lit0:
+ case DW_OP_lit1:
+ case DW_OP_lit2:
+ case DW_OP_lit3:
+ case DW_OP_lit4:
+ case DW_OP_lit5:
+ case DW_OP_lit6:
+ case DW_OP_lit7:
+ case DW_OP_lit8:
+ case DW_OP_lit9:
+ case DW_OP_lit10:
+ case DW_OP_lit11:
+ case DW_OP_lit12:
+ case DW_OP_lit13:
+ case DW_OP_lit14:
+ case DW_OP_lit15:
+ case DW_OP_lit16:
+ case DW_OP_lit17:
+ case DW_OP_lit18:
+ case DW_OP_lit19:
+ case DW_OP_lit20:
+ case DW_OP_lit21:
+ case DW_OP_lit22:
+ case DW_OP_lit23:
+ case DW_OP_lit24:
+ case DW_OP_lit25:
+ case DW_OP_lit26:
+ case DW_OP_lit27:
+ case DW_OP_lit28:
+ case DW_OP_lit29:
+ case DW_OP_lit30:
+ case DW_OP_lit31:
+ result = op - DW_OP_lit0;
+ break;
+
+ case DW_OP_addr:
+ result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
+ op_ptr += sizeof (void *);
+ break;
+
+ case DW_OP_const1u:
+ result = read_1u (op_ptr);
+ op_ptr += 1;
+ break;
+ case DW_OP_const1s:
+ result = read_1s (op_ptr);
+ op_ptr += 1;
+ break;
+ case DW_OP_const2u:
+ result = read_2u (op_ptr);
+ op_ptr += 2;
+ break;
+ case DW_OP_const2s:
+ result = read_2s (op_ptr);
+ op_ptr += 2;
+ break;
+ case DW_OP_const4u:
+ result = read_4u (op_ptr);
+ op_ptr += 4;
+ break;
+ case DW_OP_const4s:
+ result = read_4s (op_ptr);
+ op_ptr += 4;
+ break;
+ case DW_OP_const8u:
+ result = read_8u (op_ptr);
+ op_ptr += 8;
+ break;
+ case DW_OP_const8s:
+ result = read_8s (op_ptr);
+ op_ptr += 8;
+ break;
+ case DW_OP_constu:
+ op_ptr = read_uleb128 (op_ptr, &result);
+ break;
+ case DW_OP_consts:
+ op_ptr = read_sleb128 (op_ptr, &stmp);
+ result = stmp;
+ break;
+
+ case DW_OP_reg0:
+ case DW_OP_reg1:
+ case DW_OP_reg2:
+ case DW_OP_reg3:
+ case DW_OP_reg4:
+ case DW_OP_reg5:
+ case DW_OP_reg6:
+ case DW_OP_reg7:
+ case DW_OP_reg8:
+ case DW_OP_reg9:
+ case DW_OP_reg10:
+ case DW_OP_reg11:
+ case DW_OP_reg12:
+ case DW_OP_reg13:
+ case DW_OP_reg14:
+ case DW_OP_reg15:
+ case DW_OP_reg16:
+ case DW_OP_reg17:
+ case DW_OP_reg18:
+ case DW_OP_reg19:
+ case DW_OP_reg20:
+ case DW_OP_reg21:
+ case DW_OP_reg22:
+ case DW_OP_reg23:
+ case DW_OP_reg24:
+ case DW_OP_reg25:
+ case DW_OP_reg26:
+ case DW_OP_reg27:
+ case DW_OP_reg28:
+ case DW_OP_reg29:
+ case DW_OP_reg30:
+ case DW_OP_reg31:
+ result = _Unwind_GetGR (context, op - DW_OP_reg0);
+ break;
+ case DW_OP_regx:
+ op_ptr = read_uleb128 (op_ptr, &reg);
+ result = _Unwind_GetGR (context, reg);
+ break;
+
+ case DW_OP_breg0:
+ case DW_OP_breg1:
+ case DW_OP_breg2:
+ case DW_OP_breg3:
+ case DW_OP_breg4:
+ case DW_OP_breg5:
+ case DW_OP_breg6:
+ case DW_OP_breg7:
+ case DW_OP_breg8:
+ case DW_OP_breg9:
+ case DW_OP_breg10:
+ case DW_OP_breg11:
+ case DW_OP_breg12:
+ case DW_OP_breg13:
+ case DW_OP_breg14:
+ case DW_OP_breg15:
+ case DW_OP_breg16:
+ case DW_OP_breg17:
+ case DW_OP_breg18:
+ case DW_OP_breg19:
+ case DW_OP_breg20:
+ case DW_OP_breg21:
+ case DW_OP_breg22:
+ case DW_OP_breg23:
+ case DW_OP_breg24:
+ case DW_OP_breg25:
+ case DW_OP_breg26:
+ case DW_OP_breg27:
+ case DW_OP_breg28:
+ case DW_OP_breg29:
+ case DW_OP_breg30:
+ case DW_OP_breg31:
+ op_ptr = read_sleb128 (op_ptr, &offset);
+ result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
+ break;
+ case DW_OP_bregx:
+ op_ptr = read_uleb128 (op_ptr, &reg);
+ op_ptr = read_sleb128 (op_ptr, &offset);
+ result = _Unwind_GetGR (context, reg) + offset;
+ break;
+
+ case DW_OP_dup:
+ if (stack_elt < 1)
+ abort ();
+ result = stack[stack_elt - 1];
+ break;
+
+ case DW_OP_drop:
+ if (--stack_elt < 0)
+ abort ();
+ goto no_push;
+
+ case DW_OP_pick:
+ offset = *op_ptr++;
+ if (offset >= stack_elt - 1)
+ abort ();
+ result = stack[stack_elt - 1 - offset];
+ break;
+
+ case DW_OP_over:
+ if (stack_elt < 2)
+ abort ();
+ result = stack[stack_elt - 2];
+ break;
+
+ case DW_OP_rot:
+ {
+ _Unwind_Word t1, t2, t3;
+
+ if (stack_elt < 3)
+ abort ();
+ t1 = stack[stack_elt - 1];
+ t2 = stack[stack_elt - 2];
+ t3 = stack[stack_elt - 3];
+ stack[stack_elt - 1] = t2;
+ stack[stack_elt - 2] = t3;
+ stack[stack_elt - 3] = t1;
+ goto no_push;
+ }
+
+ case DW_OP_deref:
+ case DW_OP_deref_size:
+ case DW_OP_abs:
+ case DW_OP_neg:
+ case DW_OP_not:
+ case DW_OP_plus_uconst:
+ /* Unary operations. */
+ if (--stack_elt < 0)
+ abort ();
+ result = stack[stack_elt];
+
+ switch (op)
+ {
+ case DW_OP_deref:
+ {
+ void *ptr = (void *) (_Unwind_Ptr) result;
+ result = (_Unwind_Ptr) read_pointer (ptr);
+ }
+ break;
+
+ case DW_OP_deref_size:
+ {
+ void *ptr = (void *) (_Unwind_Ptr) result;
+ switch (*op_ptr++)
+ {
+ case 1:
+ result = read_1u (ptr);
+ break;
+ case 2:
+ result = read_2u (ptr);
+ break;
+ case 4:
+ result = read_4u (ptr);
+ break;
+ case 8:
+ result = read_8u (ptr);
+ break;
+ default:
+ abort ();
+ }
+ }
+ break;
+
+ case DW_OP_abs:
+ if ((_Unwind_Sword) result < 0)
+ result = -result;
+ break;
+ case DW_OP_neg:
+ result = -result;
+ break;
+ case DW_OP_not:
+ result = ~result;
+ break;
+ case DW_OP_plus_uconst:
+ op_ptr = read_uleb128 (op_ptr, &utmp);
+ result += utmp;
+ break;
+
+ default:
+ abort ();
+ }
+ break;
+
+ case DW_OP_and:
+ case DW_OP_div:
+ case DW_OP_minus:
+ case DW_OP_mod:
+ case DW_OP_mul:
+ case DW_OP_or:
+ case DW_OP_plus:
+ case DW_OP_le:
+ case DW_OP_ge:
+ case DW_OP_eq:
+ case DW_OP_lt:
+ case DW_OP_gt:
+ case DW_OP_ne:
+ {
+ /* Binary operations. */
+ _Unwind_Word first, second;
+ if ((stack_elt -= 2) < 0)
+ abort ();
+ second = stack[stack_elt];
+ first = stack[stack_elt + 1];
+
+ switch (op)
+ {
+ case DW_OP_and:
+ result = second & first;
+ break;
+ case DW_OP_div:
+ result = (_Unwind_Sword) second / (_Unwind_Sword) first;
+ break;
+ case DW_OP_minus:
+ result = second - first;
+ break;
+ case DW_OP_mod:
+ result = (_Unwind_Sword) second % (_Unwind_Sword) first;
+ break;
+ case DW_OP_mul:
+ result = second * first;
+ break;
+ case DW_OP_or:
+ result = second | first;
+ break;
+ case DW_OP_plus:
+ result = second + first;
+ break;
+ case DW_OP_shl:
+ result = second << first;
+ break;
+ case DW_OP_shr:
+ result = second >> first;
+ break;
+ case DW_OP_shra:
+ result = (_Unwind_Sword) second >> first;
+ break;
+ case DW_OP_xor:
+ result = second ^ first;
+ break;
+ case DW_OP_le:
+ result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
+ break;
+ case DW_OP_ge:
+ result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
+ break;
+ case DW_OP_eq:
+ result = (_Unwind_Sword) first == (_Unwind_Sword) second;
+ break;
+ case DW_OP_lt:
+ result = (_Unwind_Sword) first < (_Unwind_Sword) second;
+ break;
+ case DW_OP_gt:
+ result = (_Unwind_Sword) first > (_Unwind_Sword) second;
+ break;
+ case DW_OP_ne:
+ result = (_Unwind_Sword) first != (_Unwind_Sword) second;
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ break;
+
+ case DW_OP_skip:
+ offset = read_2s (op_ptr);
+ op_ptr += 2;
+ op_ptr += offset;
+ goto no_push;
+
+ case DW_OP_bra:
+ if (--stack_elt < 0)
+ abort ();
+ offset = read_2s (op_ptr);
+ op_ptr += 2;
+ if (stack[stack_elt] != 0)
+ op_ptr += offset;
+ goto no_push;
+
+ case DW_OP_nop:
+ goto no_push;
+
+ default:
+ abort ();
+ }
+
+ /* Most things push a result value. */
+ if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
+ abort ();
+ stack[stack_elt++] = result;
+ no_push:;
+ }
+
+ /* We were executing this program to get a value. It should be
+ at top of stack. */
+ if (--stack_elt < 0)
+ abort ();
+ return stack[stack_elt];
+}
+#endif
+
+/* Decode DWARF 2 call frame information. Takes pointers the
+ instruction sequence to decode, current register information and
+ CIE info, and the PC range to evaluate. */
+
+static void
+execute_cfa_program (const unsigned char *insn_ptr,
+ const unsigned char *insn_end,
+ struct _Unwind_Context *context,
+ _Unwind_FrameState *fs)
+{
+ struct frame_state_reg_info *unused_rs = NULL;
+
+ /* Don't allow remember/restore between CIE and FDE programs. */
+ fs->regs.prev = NULL;
+
+ /* The comparison with the return address uses < rather than <= because
+ we are only interested in the effects of code before the call; for a
+ noreturn function, the return address may point to unrelated code with
+ a different stack configuration that we are not interested in. We
+ assume that the call itself is unwind info-neutral; if not, or if
+ there are delay instructions that adjust the stack, these must be
+ reflected at the point immediately before the call insn. */
+ while (insn_ptr < insn_end && fs->pc < context->ra)
+ {
+ unsigned char insn = *insn_ptr++;
+ _Unwind_Word reg, utmp;
+ _Unwind_Sword offset, stmp;
+
+ if ((insn & 0xc0) == DW_CFA_advance_loc)
+ fs->pc += (insn & 0x3f) * fs->code_align;
+ else if ((insn & 0xc0) == DW_CFA_offset)
+ {
+ reg = insn & 0x3f;
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
+ offset = (_Unwind_Sword) utmp * fs->data_align;
+ fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+ fs->regs.reg[reg].loc.offset = offset;
+ }
+ else if ((insn & 0xc0) == DW_CFA_restore)
+ {
+ reg = insn & 0x3f;
+ fs->regs.reg[reg].how = REG_UNSAVED;
+ }
+ else switch (insn)
+ {
+ case DW_CFA_set_loc:
+ insn_ptr = read_encoded_value (context, fs->fde_encoding,
+ insn_ptr, (_Unwind_Ptr *) &fs->pc);
+ break;
+
+ case DW_CFA_advance_loc1:
+ fs->pc += read_1u (insn_ptr) * fs->code_align;
+ insn_ptr += 1;
+ break;
+ case DW_CFA_advance_loc2:
+ fs->pc += read_2u (insn_ptr) * fs->code_align;
+ insn_ptr += 2;
+ break;
+ case DW_CFA_advance_loc4:
+ fs->pc += read_4u (insn_ptr) * fs->code_align;
+ insn_ptr += 4;
+ break;
+
+ case DW_CFA_offset_extended:
+ insn_ptr = read_uleb128 (insn_ptr, &reg);
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
+ offset = (_Unwind_Sword) utmp * fs->data_align;
+ fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+ fs->regs.reg[reg].loc.offset = offset;
+ break;
+
+ case DW_CFA_restore_extended:
+ insn_ptr = read_uleb128 (insn_ptr, &reg);
+ fs->regs.reg[reg].how = REG_UNSAVED;
+ break;
+
+ case DW_CFA_undefined:
+ case DW_CFA_same_value:
+ insn_ptr = read_uleb128 (insn_ptr, &reg);
+ break;
+
+ case DW_CFA_nop:
+ break;
+
+ case DW_CFA_register:
+ {
+ _Unwind_Word reg2;
+ insn_ptr = read_uleb128 (insn_ptr, &reg);
+ insn_ptr = read_uleb128 (insn_ptr, &reg2);
+ fs->regs.reg[reg].how = REG_SAVED_REG;
+ fs->regs.reg[reg].loc.reg = reg2;
+ }
+ break;
+
+ case DW_CFA_remember_state:
+ {
+ struct frame_state_reg_info *new_rs;
+ if (unused_rs)
+ {
+ new_rs = unused_rs;
+ unused_rs = unused_rs->prev;
+ }
+ else
+ new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
+
+ *new_rs = fs->regs;
+ fs->regs.prev = new_rs;
+ }
+ break;
+
+ case DW_CFA_restore_state:
+ {
+ struct frame_state_reg_info *old_rs = fs->regs.prev;
+#ifdef _LIBC
+ if (old_rs == NULL)
+ __libc_fatal ("invalid DWARF unwind data");
+ else
+#endif
+ {
+ fs->regs = *old_rs;
+ old_rs->prev = unused_rs;
+ unused_rs = old_rs;
+ }
+ }
+ break;
+
+ case DW_CFA_def_cfa:
+ insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
+ fs->cfa_offset = utmp;
+ fs->cfa_how = CFA_REG_OFFSET;
+ break;
+
+ case DW_CFA_def_cfa_register:
+ insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
+ fs->cfa_how = CFA_REG_OFFSET;
+ break;
+
+ case DW_CFA_def_cfa_offset:
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
+ fs->cfa_offset = utmp;
+ /* cfa_how deliberately not set. */
+ break;
+
+ case DW_CFA_def_cfa_expression:
+ fs->cfa_exp = insn_ptr;
+ fs->cfa_how = CFA_EXP;
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
+ insn_ptr += utmp;
+ break;
+
+ case DW_CFA_expression:
+ insn_ptr = read_uleb128 (insn_ptr, &reg);
+ fs->regs.reg[reg].how = REG_SAVED_EXP;
+ fs->regs.reg[reg].loc.exp = insn_ptr;
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
+ insn_ptr += utmp;
+ break;
+
+ /* From the 2.1 draft. */
+ case DW_CFA_offset_extended_sf:
+ insn_ptr = read_uleb128 (insn_ptr, &reg);
+ insn_ptr = read_sleb128 (insn_ptr, &stmp);
+ offset = stmp * fs->data_align;
+ fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+ fs->regs.reg[reg].loc.offset = offset;
+ break;
+
+ case DW_CFA_def_cfa_sf:
+ insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
+ insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
+ fs->cfa_how = CFA_REG_OFFSET;
+ break;
+
+ case DW_CFA_def_cfa_offset_sf:
+ insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
+ /* cfa_how deliberately not set. */
+ break;
+
+ case DW_CFA_GNU_window_save:
+ /* ??? Hardcoded for SPARC register window configuration.
+ At least do not do anything for archs which explicitly
+ define a lower register number. */
+#if DWARF_FRAME_REGISTERS >= 32
+ for (reg = 16; reg < 32; ++reg)
+ {
+ fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+ fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
+ }
+#endif
+ break;
+
+ case DW_CFA_GNU_args_size:
+ insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
+ break;
+
+ case DW_CFA_GNU_negative_offset_extended:
+ /* Obsoleted by DW_CFA_offset_extended_sf, but used by
+ older PowerPC code. */
+ insn_ptr = read_uleb128 (insn_ptr, &reg);
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
+ offset = (_Unwind_Word) utmp * fs->data_align;
+ fs->regs.reg[reg].how = REG_SAVED_OFFSET;
+ fs->regs.reg[reg].loc.offset = -offset;
+ break;
+
+ default:
+ abort ();
+ }
+ }
+}
+
+/* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
+ its caller and decode it into FS. This function also sets the
+ args_size and lsda members of CONTEXT, as they are really information
+ about the caller's frame. */
+
+static _Unwind_Reason_Code
+uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+ struct dwarf_fde *fde;
+ struct dwarf_cie *cie;
+ const unsigned char *aug, *insn, *end;
+
+ memset (fs, 0, sizeof (*fs));
+ context->args_size = 0;
+ context->lsda = 0;
+
+ fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
+ if (fde == NULL)
+ {
+ /* Couldn't find frame unwind info for this function. Try a
+ target-specific fallback mechanism. This will necessarily
+ not provide a personality routine or LSDA. */
+#ifdef MD_FALLBACK_FRAME_STATE_FOR
+ MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
+ return _URC_END_OF_STACK;
+ success:
+ return _URC_NO_REASON;
+#else
+ return _URC_END_OF_STACK;
+#endif
+ }
+
+ fs->pc = context->bases.func;
+
+ cie = get_cie (fde);
+ insn = extract_cie_info (cie, context, fs);
+ if (insn == NULL)
+ /* CIE contained unknown augmentation. */
+ return _URC_FATAL_PHASE1_ERROR;
+
+ /* First decode all the insns in the CIE. */
+ end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
+ execute_cfa_program (insn, end, context, fs);
+
+ /* Locate augmentation for the fde. */
+ aug = (unsigned char *) fde + sizeof (*fde);
+ aug += 2 * size_of_encoded_value (fs->fde_encoding);
+ insn = NULL;
+ if (fs->saw_z)
+ {
+ _Unwind_Word i;
+ aug = read_uleb128 (aug, &i);
+ insn = aug + i;
+ }
+ if (fs->lsda_encoding != DW_EH_PE_omit)
+ aug = read_encoded_value (context, fs->lsda_encoding, aug,
+ (_Unwind_Ptr *) &context->lsda);
+
+ /* Then the insns in the FDE up to our target PC. */
+ if (insn == NULL)
+ insn = aug;
+ end = (unsigned char *) next_fde (fde);
+ execute_cfa_program (insn, end, context, fs);
+
+ return _URC_NO_REASON;
+}
+
+typedef struct frame_state
+{
+ void *cfa;
+ void *eh_ptr;
+ long cfa_offset;
+ long args_size;
+ long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
+ unsigned short cfa_reg;
+ unsigned short retaddr_column;
+ char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
+} frame_state;
+
+#ifndef STATIC
+# define STATIC
+#endif
+
+STATIC
+struct frame_state * __frame_state_for (void *, struct frame_state *);
+
+/* Called from pre-G++ 3.0 __throw to find the registers to restore for
+ a given PC_TARGET. The caller should allocate a local variable of
+ `struct frame_state' and pass its address to STATE_IN. */
+
+STATIC
+struct frame_state *
+__frame_state_for (void *pc_target, struct frame_state *state_in)
+{
+ struct _Unwind_Context context;
+ _Unwind_FrameState fs;
+ int reg;
+
+ memset (&context, 0, sizeof (struct _Unwind_Context));
+ context.ra = pc_target + 1;
+
+ if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
+ return 0;
+
+ /* We have no way to pass a location expression for the CFA to our
+ caller. It wouldn't understand it anyway. */
+ if (fs.cfa_how == CFA_EXP)
+ return 0;
+
+ for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
+ {
+ state_in->saved[reg] = fs.regs.reg[reg].how;
+ switch (state_in->saved[reg])
+ {
+ case REG_SAVED_REG:
+ state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
+ break;
+ case REG_SAVED_OFFSET:
+ state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
+ break;
+ default:
+ state_in->reg_or_offset[reg] = 0;
+ break;
+ }
+ }
+
+ state_in->cfa_offset = fs.cfa_offset;
+ state_in->cfa_reg = fs.cfa_reg;
+ state_in->retaddr_column = fs.retaddr_column;
+ state_in->args_size = context.args_size;
+ state_in->eh_ptr = fs.eh_ptr;
+
+ return state_in;
+}
+
+#ifndef _LIBC
+
+static void
+uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+ struct _Unwind_Context orig_context = *context;
+ void *cfa;
+ long i;
+
+#ifdef EH_RETURN_STACKADJ_RTX
+ /* Special handling here: Many machines do not use a frame pointer,
+ and track the CFA only through offsets from the stack pointer from
+ one frame to the next. In this case, the stack pointer is never
+ stored, so it has no saved address in the context. What we do
+ have is the CFA from the previous stack frame.
+
+ In very special situations (such as unwind info for signal return),
+ there may be location expressions that use the stack pointer as well.
+
+ Do this conditionally for one frame. This allows the unwind info
+ for one frame to save a copy of the stack pointer from the previous
+ frame, and be able to use much easier CFA mechanisms to do it.
+ Always zap the saved stack pointer value for the next frame; carrying
+ the value over from one frame to another doesn't make sense. */
+
+ _Unwind_Word tmp_sp;
+
+ if (!orig_context.reg[__builtin_dwarf_sp_column ()])
+ {
+ tmp_sp = (_Unwind_Ptr) context->cfa;
+ orig_context.reg[__builtin_dwarf_sp_column ()] = &tmp_sp;
+ }
+ context->reg[__builtin_dwarf_sp_column ()] = NULL;
+#endif
+
+ /* Compute this frame's CFA. */
+ switch (fs->cfa_how)
+ {
+ case CFA_REG_OFFSET:
+ cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (&orig_context, fs->cfa_reg);
+ cfa += fs->cfa_offset;
+ break;
+
+ case CFA_EXP:
+ {
+ const unsigned char *exp = fs->cfa_exp;
+ _Unwind_Word len;
+
+ exp = read_uleb128 (exp, &len);
+ cfa = (void *) (_Unwind_Ptr)
+ execute_stack_op (exp, exp + len, &orig_context, 0);
+ break;
+ }
+
+ default:
+ abort ();
+ }
+ context->cfa = cfa;
+
+ /* Compute the addresses of all registers saved in this frame. */
+ for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
+ switch (fs->regs.reg[i].how)
+ {
+ case REG_UNSAVED:
+ break;
+
+ case REG_SAVED_OFFSET:
+ context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
+ break;
+
+ case REG_SAVED_REG:
+ context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
+ break;
+
+ case REG_SAVED_EXP:
+ {
+ const unsigned char *exp = fs->regs.reg[i].loc.exp;
+ _Unwind_Word len;
+ _Unwind_Ptr val;
+
+ exp = read_uleb128 (exp, &len);
+ val = execute_stack_op (exp, exp + len, &orig_context,
+ (_Unwind_Ptr) cfa);
+ context->reg[i] = (void *) val;
+ }
+ break;
+ }
+}
+
+/* CONTEXT describes the unwind state for a frame, and FS describes the FDE
+ of its caller. Update CONTEXT to refer to the caller as well. Note
+ that the args_size and lsda members are not updated here, but later in
+ uw_frame_state_for. */
+
+static void
+uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+ uw_update_context_1 (context, fs);
+
+ /* Compute the return address now, since the return address column
+ can change from frame to frame. */
+ context->ra = __builtin_extract_return_addr
+ ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
+}
+
+/* Fill in CONTEXT for top-of-stack. The only valid registers at this
+ level will be the return address and the CFA. */
+
+#define uw_init_context(CONTEXT) \
+ do \
+ { \
+ /* Do any necessary initialization to access arbitrary stack frames. \
+ On the SPARC, this means flushing the register windows. */ \
+ __builtin_unwind_init (); \
+ uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
+ __builtin_return_address (0)); \
+ } \
+ while (0)
+
+static void
+uw_init_context_1 (struct _Unwind_Context *context,
+ void *outer_cfa, void *outer_ra)
+{
+ void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
+ _Unwind_FrameState fs;
+ _Unwind_Word sp_slot;
+
+ memset (context, 0, sizeof (struct _Unwind_Context));
+ context->ra = ra;
+
+ if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
+ abort ();
+
+ /* Force the frame state to use the known cfa value. */
+ sp_slot = (_Unwind_Ptr) outer_cfa;
+ context->reg[__builtin_dwarf_sp_column ()] = &sp_slot;
+ fs.cfa_how = CFA_REG_OFFSET;
+ fs.cfa_reg = __builtin_dwarf_sp_column ();
+ fs.cfa_offset = 0;
+
+ uw_update_context_1 (context, &fs);
+
+ /* If the return address column was saved in a register in the
+ initialization context, then we can't see it in the given
+ call frame data. So have the initialization context tell us. */
+ context->ra = __builtin_extract_return_addr (outer_ra);
+}
+
+
+/* Install TARGET into CURRENT so that we can return to it. This is a
+ macro because __builtin_eh_return must be invoked in the context of
+ our caller. */
+
+#define uw_install_context(CURRENT, TARGET) \
+ do \
+ { \
+ long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
+ void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
+ __builtin_eh_return (offset, handler); \
+ } \
+ while (0)
+
+static inline void
+init_dwarf_reg_size_table (void)
+{
+ __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
+}
+
+static long
+uw_install_context_1 (struct _Unwind_Context *current,
+ struct _Unwind_Context *target)
+{
+ long i;
+
+#if __GTHREADS
+ {
+ static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
+ if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
+ || dwarf_reg_size_table[0] == 0)
+ init_dwarf_reg_size_table ();
+ }
+#else
+ if (dwarf_reg_size_table[0] == 0)
+ init_dwarf_reg_size_table ();
+#endif
+
+ for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
+ {
+ void *c = current->reg[i];
+ void *t = target->reg[i];
+ if (t && c && t != c)
+ memcpy (c, t, dwarf_reg_size_table[i]);
+ }
+
+#ifdef EH_RETURN_STACKADJ_RTX
+ {
+ void *target_cfa;
+
+ /* If the last frame records a saved stack pointer, use it. */
+ if (target->reg[__builtin_dwarf_sp_column ()])
+ target_cfa = (void *)(_Unwind_Ptr)
+ _Unwind_GetGR (target, __builtin_dwarf_sp_column ());
+ else
+ target_cfa = target->cfa;
+
+ /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
+ if (STACK_GROWS_DOWNWARD)
+ return target_cfa - current->cfa + target->args_size;
+ else
+ return current->cfa - target_cfa - target->args_size;
+ }
+#else
+ return 0;
+#endif
+}
+
+static inline _Unwind_Ptr
+uw_identify_context (struct _Unwind_Context *context)
+{
+ return _Unwind_GetIP (context);
+}
+
+
+#include "unwind.inc"
+
+#endif /* _LIBC */
diff --git a/libc/sysdeps/generic/unwind-pe.c b/libc/sysdeps/generic/unwind-pe.c
new file mode 100644
index 000000000..4085eb2bd
--- /dev/null
+++ b/libc/sysdeps/generic/unwind-pe.c
@@ -0,0 +1,5 @@
+#include <stdlib.h>
+#include <unwind.h>
+
+#define _LIBC_DEFINITIONS
+#include "unwind-pe.h"
diff --git a/libc/sysdeps/generic/unwind-pe.h b/libc/sysdeps/generic/unwind-pe.h
new file mode 100644
index 000000000..a31b4892b
--- /dev/null
+++ b/libc/sysdeps/generic/unwind-pe.h
@@ -0,0 +1,306 @@
+/* Exception handling and frame unwind runtime interface routines.
+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* @@@ Really this should be out of line, but this also causes link
+ compatibility problems with the base ABI. This is slightly better
+ than duplicating code, however. */
+
+/* If using C++, references to abort have to be qualified with std::. */
+#if __cplusplus
+#define __gxx_abort std::abort
+#else
+#define __gxx_abort abort
+#endif
+
+/* Pointer encodings, from dwarf2.h. */
+#define DW_EH_PE_absptr 0x00
+#define DW_EH_PE_omit 0xff
+
+#define DW_EH_PE_uleb128 0x01
+#define DW_EH_PE_udata2 0x02
+#define DW_EH_PE_udata4 0x03
+#define DW_EH_PE_udata8 0x04
+#define DW_EH_PE_sleb128 0x09
+#define DW_EH_PE_sdata2 0x0A
+#define DW_EH_PE_sdata4 0x0B
+#define DW_EH_PE_sdata8 0x0C
+#define DW_EH_PE_signed 0x08
+
+#define DW_EH_PE_pcrel 0x10
+#define DW_EH_PE_textrel 0x20
+#define DW_EH_PE_datarel 0x30
+#define DW_EH_PE_funcrel 0x40
+#define DW_EH_PE_aligned 0x50
+
+#define DW_EH_PE_indirect 0x80
+
+
+#if defined(_LIBC)
+
+/* Prototypes. */
+extern unsigned int size_of_encoded_value (unsigned char encoding)
+ attribute_hidden;
+
+extern const unsigned char *read_encoded_value_with_base
+ (unsigned char encoding, _Unwind_Ptr base,
+ const unsigned char *p, _Unwind_Ptr *val)
+ attribute_hidden;
+
+extern const unsigned char * read_encoded_value
+ (struct _Unwind_Context *context, unsigned char encoding,
+ const unsigned char *p, _Unwind_Ptr *val)
+ attribute_hidden;
+
+extern const unsigned char * read_uleb128 (const unsigned char *p,
+ _Unwind_Word *val)
+ attribute_hidden;
+extern const unsigned char * read_sleb128 (const unsigned char *p,
+ _Unwind_Sword *val)
+ attribute_hidden;
+
+#endif
+#if defined(_LIBC) && defined(_LIBC_DEFINITIONS)
+
+#ifdef _LIBC
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+/* Given an encoding, return the number of bytes the format occupies.
+ This is only defined for fixed-size encodings, and so does not
+ include leb128. */
+
+STATIC unsigned int
+size_of_encoded_value (unsigned char encoding)
+{
+ if (encoding == DW_EH_PE_omit)
+ return 0;
+
+ switch (encoding & 0x07)
+ {
+ case DW_EH_PE_absptr:
+ return sizeof (void *);
+ case DW_EH_PE_udata2:
+ return 2;
+ case DW_EH_PE_udata4:
+ return 4;
+ case DW_EH_PE_udata8:
+ return 8;
+ }
+ __gxx_abort ();
+}
+
+#ifndef NO_BASE_OF_ENCODED_VALUE
+
+/* Given an encoding and an _Unwind_Context, return the base to which
+ the encoding is relative. This base may then be passed to
+ read_encoded_value_with_base for use when the _Unwind_Context is
+ not available. */
+
+STATIC _Unwind_Ptr
+base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
+{
+ if (encoding == DW_EH_PE_omit)
+ return 0;
+
+ switch (encoding & 0x70)
+ {
+ case DW_EH_PE_absptr:
+ case DW_EH_PE_pcrel:
+ case DW_EH_PE_aligned:
+ return 0;
+
+ case DW_EH_PE_textrel:
+ return _Unwind_GetTextRelBase (context);
+ case DW_EH_PE_datarel:
+ return _Unwind_GetDataRelBase (context);
+ case DW_EH_PE_funcrel:
+ return _Unwind_GetRegionStart (context);
+ }
+ __gxx_abort ();
+}
+
+#endif
+
+/* Read an unsigned leb128 value from P, store the value in VAL, return
+ P incremented past the value. We assume that a word is large enough to
+ hold any value so encoded; if it is smaller than a pointer on some target,
+ pointers should not be leb128 encoded on that target. */
+
+STATIC const unsigned char *
+read_uleb128 (const unsigned char *p, _Unwind_Word *val)
+{
+ unsigned int shift = 0;
+ unsigned char byte;
+ _Unwind_Word result;
+
+ result = 0;
+ do
+ {
+ byte = *p++;
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+ }
+ while (byte & 0x80);
+
+ *val = result;
+ return p;
+}
+
+/* Similar, but read a signed leb128 value. */
+
+STATIC const unsigned char *
+read_sleb128 (const unsigned char *p, _Unwind_Sword *val)
+{
+ unsigned int shift = 0;
+ unsigned char byte;
+ _Unwind_Word result;
+
+ result = 0;
+ do
+ {
+ byte = *p++;
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+ }
+ while (byte & 0x80);
+
+ /* Sign-extend a negative value. */
+ if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
+ result |= -(1L << shift);
+
+ *val = (_Unwind_Sword) result;
+ return p;
+}
+
+/* Load an encoded value from memory at P. The value is returned in VAL;
+ The function returns P incremented past the value. BASE is as given
+ by base_of_encoded_value for this encoding in the appropriate context. */
+
+STATIC const unsigned char *
+read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
+ const unsigned char *p, _Unwind_Ptr *val)
+{
+ union unaligned
+ {
+ void *ptr;
+ unsigned u2 __attribute__ ((mode (HI)));
+ unsigned u4 __attribute__ ((mode (SI)));
+ unsigned u8 __attribute__ ((mode (DI)));
+ signed s2 __attribute__ ((mode (HI)));
+ signed s4 __attribute__ ((mode (SI)));
+ signed s8 __attribute__ ((mode (DI)));
+ } __attribute__((__packed__));
+
+ union unaligned *u = (union unaligned *) p;
+ _Unwind_Internal_Ptr result;
+
+ if (encoding == DW_EH_PE_aligned)
+ {
+ _Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
+ a = (a + sizeof (void *) - 1) & - sizeof(void *);
+ result = *(_Unwind_Internal_Ptr *) a;
+ p = (const unsigned char *) (a + sizeof (void *));
+ }
+ else
+ {
+ switch (encoding & 0x0f)
+ {
+ case DW_EH_PE_absptr:
+ result = (_Unwind_Internal_Ptr) u->ptr;
+ p += sizeof (void *);
+ break;
+
+ case DW_EH_PE_uleb128:
+ {
+ _Unwind_Word tmp;
+ p = read_uleb128 (p, &tmp);
+ result = (_Unwind_Internal_Ptr) tmp;
+ }
+ break;
+
+ case DW_EH_PE_sleb128:
+ {
+ _Unwind_Sword tmp;
+ p = read_sleb128 (p, &tmp);
+ result = (_Unwind_Internal_Ptr) tmp;
+ }
+ break;
+
+ case DW_EH_PE_udata2:
+ result = u->u2;
+ p += 2;
+ break;
+ case DW_EH_PE_udata4:
+ result = u->u4;
+ p += 4;
+ break;
+ case DW_EH_PE_udata8:
+ result = u->u8;
+ p += 8;
+ break;
+
+ case DW_EH_PE_sdata2:
+ result = u->s2;
+ p += 2;
+ break;
+ case DW_EH_PE_sdata4:
+ result = u->s4;
+ p += 4;
+ break;
+ case DW_EH_PE_sdata8:
+ result = u->s8;
+ p += 8;
+ break;
+
+ default:
+ __gxx_abort ();
+ }
+
+ if (result != 0)
+ {
+ result += ((encoding & 0x70) == DW_EH_PE_pcrel
+ ? (_Unwind_Internal_Ptr) u : base);
+ if (encoding & DW_EH_PE_indirect)
+ result = *(_Unwind_Internal_Ptr *) result;
+ }
+ }
+
+ *val = result;
+ return p;
+}
+
+#ifndef NO_BASE_OF_ENCODED_VALUE
+
+/* Like read_encoded_value_with_base, but get the base from the context
+ rather than providing it directly. */
+
+STATIC const unsigned char *
+read_encoded_value (struct _Unwind_Context *context, unsigned char encoding,
+ const unsigned char *p, _Unwind_Ptr *val)
+{
+ return read_encoded_value_with_base (encoding,
+ base_of_encoded_value (encoding, context),
+ p, val);
+}
+
+#endif
+#endif /* _LIBC */
diff --git a/libc/sysdeps/generic/unwind.h b/libc/sysdeps/generic/unwind.h
new file mode 100644
index 000000000..81fc4db55
--- /dev/null
+++ b/libc/sysdeps/generic/unwind.h
@@ -0,0 +1,220 @@
+/* Exception handling and frame unwind runtime interface routines.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This is derived from the C++ ABI for IA-64. Where we diverge
+ for cross-architecture compatibility are noted with "@@@". */
+
+#ifndef _UNWIND_H
+#define _UNWIND_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Level 1: Base ABI */
+
+/* @@@ The IA-64 ABI uses uint64 throughout. Most places this is
+ inefficient for 32-bit and smaller machines. */
+typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));
+typedef signed _Unwind_Sword __attribute__((__mode__(__word__)));
+#if defined(__ia64__) && defined(__hpux__)
+typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__)));
+#else
+typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
+#endif
+typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__)));
+
+/* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and
+ consumer of an exception. We'll go along with this for now even on
+ 32-bit machines. We'll need to provide some other option for
+ 16-bit machines and for machines with > 8 bits per byte. */
+typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__)));
+
+/* The unwind interface uses reason codes in several contexts to
+ identify the reasons for failures or other actions. */
+typedef enum
+{
+ _URC_NO_REASON = 0,
+ _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+ _URC_FATAL_PHASE2_ERROR = 2,
+ _URC_FATAL_PHASE1_ERROR = 3,
+ _URC_NORMAL_STOP = 4,
+ _URC_END_OF_STACK = 5,
+ _URC_HANDLER_FOUND = 6,
+ _URC_INSTALL_CONTEXT = 7,
+ _URC_CONTINUE_UNWIND = 8
+} _Unwind_Reason_Code;
+
+
+/* The unwind interface uses a pointer to an exception header object
+ as its representation of an exception being thrown. In general, the
+ full representation of an exception object is language- and
+ implementation-specific, but it will be prefixed by a header
+ understood by the unwind interface. */
+
+struct _Unwind_Exception;
+
+typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code,
+ struct _Unwind_Exception *);
+
+struct _Unwind_Exception
+{
+ _Unwind_Exception_Class exception_class;
+ _Unwind_Exception_Cleanup_Fn exception_cleanup;
+ _Unwind_Word private_1;
+ _Unwind_Word private_2;
+
+ /* @@@ The IA-64 ABI says that this structure must be double-word aligned.
+ Taking that literally does not make much sense generically. Instead we
+ provide the maximum alignment required by any type for the machine. */
+} __attribute__((__aligned__));
+
+
+/* The ACTIONS argument to the personality routine is a bitwise OR of one
+ or more of the following constants. */
+typedef int _Unwind_Action;
+
+#define _UA_SEARCH_PHASE 1
+#define _UA_CLEANUP_PHASE 2
+#define _UA_HANDLER_FRAME 4
+#define _UA_FORCE_UNWIND 8
+#define _UA_END_OF_STACK 16
+
+/* This is an opaque type used to refer to a system-specific data
+ structure used by the system unwinder. This context is created and
+ destroyed by the system, and passed to the personality routine
+ during unwinding. */
+struct _Unwind_Context;
+
+/* Raise an exception, passing along the given exception object. */
+extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
+
+/* Raise an exception for forced unwinding. */
+
+typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
+ (int, _Unwind_Action, _Unwind_Exception_Class,
+ struct _Unwind_Exception *, struct _Unwind_Context *, void *);
+
+extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,
+ _Unwind_Stop_Fn,
+ void *);
+
+/* Helper to invoke the exception_cleanup routine. */
+extern void _Unwind_DeleteException (struct _Unwind_Exception *);
+
+/* Resume propagation of an existing exception. This is used after
+ e.g. executing cleanup code, and not to implement rethrowing. */
+extern void _Unwind_Resume (struct _Unwind_Exception *);
+
+/* @@@ Use unwind data to perform a stack backtrace. The trace callback
+ is called for every stack frame in the call chain, but no cleanup
+ actions are performed. */
+typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)
+ (struct _Unwind_Context *, void *);
+
+extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *);
+
+/* These functions are used for communicating information about the unwind
+ context (i.e. the unwind descriptors and the user register state) between
+ the unwind library and the personality routine and landing pad. Only
+ selected registers maybe manipulated. */
+
+extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int);
+extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
+
+extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
+extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
+
+/* @@@ Retrieve the CFA of the given context. */
+extern _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *);
+
+extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *);
+
+extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *);
+
+
+/* The personality routine is the function in the C++ (or other language)
+ runtime library which serves as an interface between the system unwind
+ library and language-specific exception handling semantics. It is
+ specific to the code fragment described by an unwind info block, and
+ it is always referenced via the pointer in the unwind info block, and
+ hence it has no ABI-specified name.
+
+ Note that this implies that two different C++ implementations can
+ use different names, and have different contents in the language
+ specific data area. Moreover, that the language specific data
+ area contains no version info because name of the function invoked
+ provides more effective versioning by detecting at link time the
+ lack of code to handle the different data format. */
+
+typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)
+ (int, _Unwind_Action, _Unwind_Exception_Class,
+ struct _Unwind_Exception *, struct _Unwind_Context *);
+
+/* @@@ The following alternate entry points are for setjmp/longjmp
+ based unwinding. */
+
+struct SjLj_Function_Context;
+extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *);
+extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *);
+
+extern _Unwind_Reason_Code _Unwind_SjLj_RaiseException
+ (struct _Unwind_Exception *);
+extern _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind
+ (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
+extern void _Unwind_SjLj_Resume (struct _Unwind_Exception *);
+
+/* @@@ The following provide access to the base addresses for text
+ and data-relative addressing in the LDSA. In order to stay link
+ compatible with the standard ABI for IA-64, we inline these. */
+
+#ifdef __ia64__
+#include <stdlib.h>
+
+static inline _Unwind_Ptr
+_Unwind_GetDataRelBase (struct _Unwind_Context *_C)
+{
+ /* The GP is stored in R1. */
+ return _Unwind_GetGR (_C, 1);
+}
+
+static inline _Unwind_Ptr
+_Unwind_GetTextRelBase (struct _Unwind_Context *_C)
+{
+ abort ();
+ return 0;
+}
+
+/* @@@ Retrieve the Backing Store Pointer of the given context. */
+extern _Unwind_Word _Unwind_GetBSP (struct _Unwind_Context *);
+#else
+extern _Unwind_Ptr _Unwind_GetDataRelBase (struct _Unwind_Context *);
+extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *);
+#endif
+
+/* @@@ Given an address, return the entry point of the function that
+ contains it. */
+extern void * _Unwind_FindEnclosingFunction (void *pc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* unwind.h */
diff --git a/libc/sysdeps/generic/utmp-equal.h b/libc/sysdeps/generic/utmp-equal.h
new file mode 100644
index 000000000..bd16bed5e
--- /dev/null
+++ b/libc/sysdeps/generic/utmp-equal.h
@@ -0,0 +1,53 @@
+/* Helper function for utmp functions to see if two entries are equal.
+ Copyright (C) 1996,97,98,99,2000,01,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>
+ and Paul Janzen <pcj@primenet.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <utmp.h>
+
+#include "utmp-private.h"
+
+/* Test whether two entries match. */
+static int
+__utmp_equal (const struct utmp *entry, const struct utmp *match)
+{
+ return
+ (
+#if _HAVE_UT_TYPE - 0
+ (entry->ut_type == INIT_PROCESS
+ || entry->ut_type == LOGIN_PROCESS
+ || entry->ut_type == USER_PROCESS
+ || entry->ut_type == DEAD_PROCESS)
+ &&
+ (match->ut_type == INIT_PROCESS
+ || match->ut_type == LOGIN_PROCESS
+ || match->ut_type == USER_PROCESS
+ || match->ut_type == DEAD_PROCESS)
+ &&
+#endif
+#if _HAVE_UT_ID - 0
+ (entry->ut_id[0] && match->ut_id[0]
+ ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0
+ : strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0)
+#else
+ strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0
+#endif
+ );
+}
diff --git a/libc/sysdeps/gnu/Makefile b/libc/sysdeps/gnu/Makefile
new file mode 100644
index 000000000..5b9a0a56e
--- /dev/null
+++ b/libc/sysdeps/gnu/Makefile
@@ -0,0 +1,79 @@
+# Copyright (C) 1996,1997,1998,1999,2001,2002,2003,2004,2005,2006
+# Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+# Generate the list of strings for errno codes from the section of the
+# manual which documents the codes.
+
+$(..)sysdeps/gnu/errlist.c: $(..)sysdeps/gnu/errlist.awk \
+ $(..)manual/errno.texi
+ $(AWK) -f $^ > $@-tmp
+# Make it unwritable so noone will edit it by mistake.
+ -chmod a-w $@-tmp
+ mv -f $@-tmp $@
+ifeq ($(with-cvs),yes)
+ test ! -d CVS || cvs commit -m'Regenerated from $^' $@
+endif
+
+ifeq ($(subdir),stdio-common)
+
+errlist-c = $(firstword $(wildcard $(addsuffix /errlist.c,$(sysdirs) .)))
+
+ifeq ($(versioning),yes)
+$(objpfx)errlist-compat.c: $(errlist-c) $(..)sysdeps/gnu/errlist-compat.awk \
+ $(common-objpfx)Versions.v.i $(before-compile)
+else
+$(objpfx)errlist-compat.c: $(errlist-c) $(..)sysdeps/gnu/errlist-compat.awk \
+ $(before-compile)
+endif
+ $(make-target-directory)
+ $(AWK) -v maxerr=`\
+ $(CC) -S $(CPPFLAGS) $(CFLAGS) -DNOT_IN_libc -DEMIT_ERR_MAX $< -o - \
+ | sed -n 's/^.*@@@[^0-9]*\([0-9]*\)[^0-9]*@@@.*$$/\1/p'` \
+ -f $(..)sysdeps/gnu/errlist-compat.awk \
+ $(wildcard $(sysdirs:=/Versions)) > $@T
+# Make it unwritable so noone will edit it by mistake.
+ -chmod a-w $@T
+ mv -f $@T $@
+$(objpfx)errlist-compat.h: $(objpfx)errlist-compat.c
+ sed -n '1p;/ERR_MAX/p' $< > $@T
+ -chmod a-w $@T
+ mv -f $@T $@
+generated += errlist-compat.c errlist-compat.h
+
+# This will force the generation above to happy if need be.
+$(foreach o,$(object-suffixes) $(object-suffixes:=.d),\
+ $(objpfx)errlist$o): $(objpfx)errlist-compat.h
+endif
+
+ifeq ($(subdir),login)
+sysdep_routines += setutxent getutxent endutxent getutxid getutxline \
+ pututxline utmpxname updwtmpx getutmpx getutmp
+
+sysdep_headers += utmpx.h bits/utmpx.h
+endif
+
+
+ifeq ($(subdir),inet)
+sysdep_headers += netinet/udp.h netinet/ip_icmp.h
+endif
+
+
+ifeq ($(subdir),misc)
+sysdep_headers += sys/mtio.h
+endif
diff --git a/libc/sysdeps/gnu/_G_config.h b/libc/sysdeps/gnu/_G_config.h
new file mode 100644
index 000000000..83c78f0b9
--- /dev/null
+++ b/libc/sysdeps/gnu/_G_config.h
@@ -0,0 +1,103 @@
+/* This file is needed by libio to define various configuration parameters.
+ These are always the same in the GNU C library. */
+
+#ifndef _G_config_h
+#define _G_config_h 1
+
+/* Define types for libio in terms of the standard internal type names. */
+
+#include <bits/types.h>
+#define __need_size_t
+#define __need_wchar_t
+#define __need_wint_t
+#define __need_NULL
+#include <stddef.h>
+#ifndef _WINT_T
+/* Integral type unchanged by default argument promotions that can
+ hold any value corresponding to members of the extended character
+ set, as well as at least one value that does not correspond to any
+ member of the extended character set. */
+# define _WINT_T
+typedef unsigned int wint_t;
+#endif
+#define __need_mbstate_t
+#include <wchar.h>
+#define _G_size_t size_t
+typedef struct
+{
+ __off_t __pos;
+ __mbstate_t __state;
+} _G_fpos_t;
+typedef struct
+{
+ __off64_t __pos;
+ __mbstate_t __state;
+} _G_fpos64_t;
+#define _G_ssize_t __ssize_t
+#define _G_off_t __off_t
+#define _G_off64_t __off64_t
+#define _G_pid_t __pid_t
+#define _G_uid_t __uid_t
+#define _G_wchar_t wchar_t
+#define _G_wint_t wint_t
+#define _G_stat64 stat64
+#include <gconv.h>
+typedef union
+{
+ struct __gconv_info __cd;
+ struct
+ {
+ struct __gconv_info __cd;
+ struct __gconv_step_data __data;
+ } __combined;
+} _G_iconv_t;
+
+typedef int _G_int16_t __attribute__ ((__mode__ (__HI__)));
+typedef int _G_int32_t __attribute__ ((__mode__ (__SI__)));
+typedef unsigned int _G_uint16_t __attribute__ ((__mode__ (__HI__)));
+typedef unsigned int _G_uint32_t __attribute__ ((__mode__ (__SI__)));
+
+#define _G_HAVE_BOOL 1
+
+
+/* These library features are always available in the GNU C library. */
+#define _G_HAVE_ATEXIT 1
+#define _G_HAVE_SYS_CDEFS 1
+#define _G_HAVE_SYS_WAIT 1
+#define _G_NEED_STDARG_H 1
+#define _G_va_list __gnuc_va_list
+
+#define _G_HAVE_PRINTF_FP 1
+#define _G_HAVE_MMAP 1
+#define _G_HAVE_MREMAP 1
+#define _G_HAVE_LONG_DOUBLE_IO 1
+#define _G_HAVE_IO_FILE_OPEN 1
+#define _G_HAVE_IO_GETLINE_INFO 1
+
+#define _G_IO_IO_FILE_VERSION 0x20001
+
+#define _G_OPEN64 __open64
+#define _G_LSEEK64 __lseek64
+#define _G_MMAP64 __mmap64
+#define _G_FSTAT64(fd,buf) __fxstat64 (_STAT_VER, fd, buf)
+
+/* This is defined by <bits/stat.h> if `st_blksize' exists. */
+#define _G_HAVE_ST_BLKSIZE defined (_STATBUF_ST_BLKSIZE)
+
+#define _G_BUFSIZ 8192
+
+/* These are the vtbl details for ELF. */
+#define _G_NAMES_HAVE_UNDERSCORE 0
+#define _G_VTABLE_LABEL_HAS_LENGTH 1
+#define _G_USING_THUNKS 1
+#define _G_VTABLE_LABEL_PREFIX "__vt_"
+#define _G_VTABLE_LABEL_PREFIX_ID __vt_
+
+
+#if defined __cplusplus || defined __STDC__
+# define _G_ARGS(ARGLIST) ARGLIST
+#else
+# define _G_ARGS(ARGLIST) ()
+#endif
+
+#endif /* _G_config.h */
diff --git a/libc/sysdeps/gnu/bits/ipc.h b/libc/sysdeps/gnu/bits/ipc.h
new file mode 100644
index 000000000..36cdf0e19
--- /dev/null
+++ b/libc/sysdeps/gnu/bits/ipc.h
@@ -0,0 +1,52 @@
+/* Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IPC_H
+# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Mode bits for `msgget', `semget', and `shmget'. */
+#define IPC_CREAT 01000 /* Create key if key does not exist. */
+#define IPC_EXCL 02000 /* Fail if key exists. */
+#define IPC_NOWAIT 04000 /* Return error on wait. */
+
+/* Control commands for `msgctl', `semctl', and `shmctl'. */
+#define IPC_RMID 0 /* Remove identifier. */
+#define IPC_SET 1 /* Set `ipc_perm' options. */
+#define IPC_STAT 2 /* Get `ipc_perm' options. */
+#ifdef __USE_GNU
+# define IPC_INFO 3 /* See ipcs. */
+#endif
+
+/* Special key values. */
+#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
+
+
+/* Data structure used to pass permission information to IPC operations. */
+struct ipc_perm
+ {
+ __key_t __key; /* Key. */
+ unsigned short int uid; /* Owner's user ID. */
+ unsigned short int gid; /* Owner's group ID. */
+ unsigned short int cuid; /* Creator's user ID. */
+ unsigned short int cgid; /* Creator's group ID. */
+ unsigned short int mode; /* Read/write permission. */
+ unsigned short int __seq; /* Sequence number. */
+ };
diff --git a/libc/sysdeps/gnu/bits/msq.h b/libc/sysdeps/gnu/bits/msq.h
new file mode 100644
index 000000000..5ca58ba39
--- /dev/null
+++ b/libc/sysdeps/gnu/bits/msq.h
@@ -0,0 +1,77 @@
+/* Copyright (C) 1995, 1996, 1997, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/ipctypes.h>
+
+/* Define options for message queue functions. */
+#define MSG_NOERROR 010000 /* no error if message is too big */
+#ifdef __USE_GNU
+# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+#endif
+
+/* Types used in the structure definition. */
+typedef unsigned short int msgqnum_t;
+typedef unsigned short int msglen_t;
+
+
+/* Structure of record for one message inside the kernel.
+ The type `struct msg' is opaque. */
+struct msqid_ds
+{
+ struct ipc_perm msg_perm; /* structure describing operation permission */
+ struct msg *__unbounded __msg_first; /* pointer to first message on queue */
+ struct msg *__unbounded __msg_last; /* pointer to last message on queue */
+ __time_t msg_stime; /* time of last msgsnd command */
+ __time_t msg_rtime; /* time of last msgrcv command */
+ __time_t msg_ctime; /* time of last change */
+ struct wait_queue *__unbounded __wwait; /* ??? */
+ struct wait_queue *__unbounded __rwait; /* ??? */
+ unsigned short int __msg_cbytes;/* current number of bytes on queue */
+ msgqnum_t msg_qnum; /* number of messages currently on queue */
+ msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+ __ipc_pid_t msg_lspid; /* pid of last msgsnd() */
+ __ipc_pid_t msg_lrpid; /* pid of last msgrcv() */
+};
+
+#ifdef __USE_MISC
+
+# define msg_cbytes __msg_cbytes
+
+/* ipcs ctl commands */
+# define MSG_STAT 11
+# define MSG_INFO 12
+
+/* buffer for msgctl calls IPC_INFO, MSG_INFO */
+struct msginfo
+ {
+ int msgpool;
+ int msgmap;
+ int msgmax;
+ int msgmnb;
+ int msgmni;
+ int msgssz;
+ int msgtql;
+ unsigned short int msgseg;
+ };
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/gnu/bits/sem.h b/libc/sysdeps/gnu/bits/sem.h
new file mode 100644
index 000000000..a2eea0d83
--- /dev/null
+++ b/libc/sysdeps/gnu/bits/sem.h
@@ -0,0 +1,88 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SEM_H
+# error "Never include <bits/sem.h> directly; use <sys/sem.h> instead."
+#endif
+
+#include <sys/types.h>
+
+/* Flags for `semop'. */
+#define SEM_UNDO 0x1000 /* undo the operation on exit */
+
+/* Commands for `semctl'. */
+#define GETPID 11 /* get sempid */
+#define GETVAL 12 /* get semval */
+#define GETALL 13 /* get all semval's */
+#define GETNCNT 14 /* get semncnt */
+#define GETZCNT 15 /* get semzcnt */
+#define SETVAL 16 /* set semval */
+#define SETALL 17 /* set all semval's */
+
+
+/* Data structure describing a set of semaphores. */
+struct semid_ds
+{
+ struct ipc_perm sem_perm; /* operation permission struct */
+ __time_t sem_otime; /* last semop() time */
+ __time_t sem_ctime; /* last time changed by semctl() */
+ struct sem *__sembase; /* ptr to first semaphore in array */
+ struct __sem_queue *__sem_pending; /* pending operations */
+ struct __sem_queue *__sem_pending_last;/* last pending operation */
+ struct __sem_undo *__undo; /* ondo requests on this array */
+ unsigned short int sem_nsems; /* number of semaphores in set */
+};
+
+
+/* The user should define a union like the following to use it for arguments
+ for `semctl'.
+
+ union semun
+ {
+ int val; <= value for SETVAL
+ struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET
+ unsigned short int *array; <= array for GETALL & SETALL
+ struct seminfo *__buf; <= buffer for IPC_INFO
+ };
+
+ Previous versions of this file used to define this union but this is
+ incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether
+ one must define the union or not. */
+#define _SEM_SEMUN_UNDEFINED 1
+
+#ifdef __USE_MISC
+
+/* ipcs ctl cmds */
+# define SEM_STAT 18
+# define SEM_INFO 19
+
+struct seminfo
+{
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvmx;
+ int semaem;
+};
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/gnu/bits/shm.h b/libc/sysdeps/gnu/bits/shm.h
new file mode 100644
index 000000000..cbda9cebb
--- /dev/null
+++ b/libc/sysdeps/gnu/bits/shm.h
@@ -0,0 +1,97 @@
+/* Copyright (C) 1995, 1996, 1997, 2000, 2002, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/ipctypes.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple. */
+#define SHMLBA (__getpagesize ())
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+
+/* Type to count number of attaches. */
+typedef unsigned short int shmatt_t;
+
+/* Data structure describing a set of semaphores. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+ int shm_segsz; /* size of segment in bytes */
+ __time_t shm_atime; /* time of last shmat() */
+ __time_t shm_dtime; /* time of last shmdt() */
+ __time_t shm_ctime; /* time of last change by shmctl() */
+ __ipc_pid_t shm_cpid; /* pid of creator */
+ __ipc_pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned short int __shm_npages; /* size of segment (pages) */
+ unsigned long int *__shm_pages; /* array of ptrs to frames -> SHMMAX */
+ struct vm_area_struct *__attaches; /* descriptors for attaches */
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+
+struct shminfo
+ {
+ int shmmax;
+ int shmmin;
+ int shmmni;
+ int shmseg;
+ int shmall;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
+
+__END_DECLS
diff --git a/libc/sysdeps/gnu/bits/utmp.h b/libc/sysdeps/gnu/bits/utmp.h
new file mode 100644
index 000000000..e855ad73f
--- /dev/null
+++ b/libc/sysdeps/gnu/bits/utmp.h
@@ -0,0 +1,125 @@
+/* The `struct utmp' type, describing entries in the utmp file. GNU version.
+ Copyright (C) 1993, 1996, 1997, 1998, 1999, 2002
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _UTMP_H
+# error "Never include <bits/utmp.h> directly; use <utmp.h> instead."
+#endif
+
+#include <paths.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <bits/wordsize.h>
+
+
+#define UT_LINESIZE 32
+#define UT_NAMESIZE 32
+#define UT_HOSTSIZE 256
+
+
+/* The structure describing an entry in the database of
+ previous logins. */
+struct lastlog
+ {
+#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
+ int32_t ll_time;
+#else
+ __time_t ll_time;
+#endif
+ char ll_line[UT_LINESIZE];
+ char ll_host[UT_HOSTSIZE];
+ };
+
+
+/* The structure describing the status of a terminated process. This
+ type is used in `struct utmp' below. */
+struct exit_status
+ {
+ short int e_termination; /* Process termination status. */
+ short int e_exit; /* Process exit status. */
+ };
+
+
+/* The structure describing an entry in the user accounting database. */
+struct utmp
+{
+ short int ut_type; /* Type of login. */
+ pid_t ut_pid; /* Process ID of login process. */
+ char ut_line[UT_LINESIZE]; /* Devicename. */
+ char ut_id[4]; /* Inittab ID. */
+ char ut_user[UT_NAMESIZE]; /* Username. */
+ char ut_host[UT_HOSTSIZE]; /* Hostname for remote login. */
+ struct exit_status ut_exit; /* Exit status of a process marked
+ as DEAD_PROCESS. */
+/* The ut_session and ut_tv fields must be the same size when compiled
+ 32- and 64-bit. This allows data files and shared memory to be
+ shared between 32- and 64-bit applications. */
+#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
+ int32_t ut_session; /* Session ID, used for windowing. */
+ struct
+ {
+ int32_t tv_sec; /* Seconds. */
+ int32_t tv_usec; /* Microseconds. */
+ } ut_tv; /* Time entry was made. */
+#else
+ long int ut_session; /* Session ID, used for windowing. */
+ struct timeval ut_tv; /* Time entry was made. */
+#endif
+
+ int32_t ut_addr_v6[4]; /* Internet address of remote host. */
+ char __unused[20]; /* Reserved for future use. */
+};
+
+/* Backwards compatibility hacks. */
+#define ut_name ut_user
+#ifndef _NO_UT_TIME
+/* We have a problem here: `ut_time' is also used otherwise. Define
+ _NO_UT_TIME if the compiler complains. */
+# define ut_time ut_tv.tv_sec
+#endif
+#define ut_xtime ut_tv.tv_sec
+#define ut_addr ut_addr_v6[0]
+
+
+/* Values for the `ut_type' field of a `struct utmp'. */
+#define EMPTY 0 /* No valid user accounting information. */
+
+#define RUN_LVL 1 /* The system's runlevel. */
+#define BOOT_TIME 2 /* Time of system boot. */
+#define NEW_TIME 3 /* Time after system clock changed. */
+#define OLD_TIME 4 /* Time when system clock changed. */
+
+#define INIT_PROCESS 5 /* Process spawned by the init process. */
+#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */
+#define USER_PROCESS 7 /* Normal process. */
+#define DEAD_PROCESS 8 /* Terminated process. */
+
+#define ACCOUNTING 9
+
+/* Old Linux name for the EMPTY type. */
+#define UT_UNKNOWN EMPTY
+
+
+/* Tell the user that we have a modern system with UT_HOST, UT_PID,
+ UT_TYPE, UT_ID and UT_TV fields. */
+#define _HAVE_UT_TYPE 1
+#define _HAVE_UT_PID 1
+#define _HAVE_UT_ID 1
+#define _HAVE_UT_TV 1
+#define _HAVE_UT_HOST 1
diff --git a/libc/sysdeps/gnu/bits/utmpx.h b/libc/sysdeps/gnu/bits/utmpx.h
new file mode 100644
index 000000000..c84cda6fe
--- /dev/null
+++ b/libc/sysdeps/gnu/bits/utmpx.h
@@ -0,0 +1,103 @@
+/* Structures and definitions for the user accounting database. GNU version.
+ Copyright (C) 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _UTMPX_H
+# error "Never include <bits/utmpx.h> directly; use <utmpx.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <sys/time.h>
+#include <bits/wordsize.h>
+
+
+#ifdef __USE_GNU
+# include <paths.h>
+# define _PATH_UTMPX _PATH_UTMP
+# define _PATH_WTMPX _PATH_WTMP
+#endif
+
+
+#define __UT_LINESIZE 32
+#define __UT_NAMESIZE 32
+#define __UT_HOSTSIZE 256
+
+
+/* The structure describing the status of a terminated process. This
+ type is used in `struct utmpx' below. */
+struct __exit_status
+ {
+#ifdef __USE_GNU
+ short int e_termination; /* Process termination status. */
+ short int e_exit; /* Process exit status. */
+#else
+ short int __e_termination; /* Process termination status. */
+ short int __e_exit; /* Process exit status. */
+#endif
+ };
+
+
+/* The structure describing an entry in the user accounting database. */
+struct utmpx
+{
+ short int ut_type; /* Type of login. */
+ __pid_t ut_pid; /* Process ID of login process. */
+ char ut_line[__UT_LINESIZE]; /* Devicename. */
+ char ut_id[4]; /* Inittab ID. */
+ char ut_user[__UT_NAMESIZE]; /* Username. */
+ char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */
+ struct __exit_status ut_exit; /* Exit status of a process marked
+ as DEAD_PROCESS. */
+
+/* The fields ut_session and ut_tv must be the same size when compiled
+ 32- and 64-bit. This allows files and shared memory to be shared
+ between 32- and 64-bit applications. */
+#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
+ __int32_t ut_session; /* Session ID, used for windowing. */
+ struct
+ {
+ __int32_t tv_sec; /* Seconds. */
+ __int32_t tv_usec; /* Microseconds. */
+ } ut_tv; /* Time entry was made. */
+#else
+ long int ut_session; /* Session ID, used for windowing. */
+ struct timeval ut_tv; /* Time entry was made. */
+#endif
+ __int32_t ut_addr_v6[4]; /* Internet address of remote host. */
+ char __unused[20]; /* Reserved for future use. */
+};
+
+
+/* Values for the `ut_type' field of a `struct utmpx'. */
+#define EMPTY 0 /* No valid user accounting information. */
+
+#ifdef __USE_GNU
+# define RUN_LVL 1 /* The system's runlevel. */
+#endif
+#define BOOT_TIME 2 /* Time of system boot. */
+#define NEW_TIME 3 /* Time after system clock changed. */
+#define OLD_TIME 4 /* Time when system clock changed. */
+
+#define INIT_PROCESS 5 /* Process spawned by the init process. */
+#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */
+#define USER_PROCESS 7 /* Normal process. */
+#define DEAD_PROCESS 8 /* Terminated process. */
+
+#ifdef __USE_GNU
+# define ACCOUNTING 9 /* System accounting. */
+#endif
diff --git a/libc/sysdeps/gnu/errlist-compat.awk b/libc/sysdeps/gnu/errlist-compat.awk
new file mode 100644
index 000000000..ab67a18f6
--- /dev/null
+++ b/libc/sysdeps/gnu/errlist-compat.awk
@@ -0,0 +1,129 @@
+# awk script to generate errlist-compat.c
+# Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+#
+# This script takes the Versions file as input and looks for #errlist-compat
+# magic comments, which have the form:
+# #errlist-compat NNN
+# where NNN is the number of elements in the sys_errlist for that version set.
+# We need the awk variable `maxerr' defined to the current size of sys_errlist.
+#
+# If there is no magic comment matching the current size, we barf.
+# Otherwise we generate code (errlist-compat.c) to define all the
+# necessary compatibility symbols for older, smaller versions of sys_errlist.
+#
+
+# These two rules catch the Versions file contents.
+NF == 2 && $2 == "{" { last_version = $1; next }
+$1 == "#errlist-compat" {
+ # Don't process any further Versions files
+ ARGC = ARGIND + 1;
+ cnt = $2 + 0;
+ if (cnt < 80) {
+ print "*** this line seems bogus:", $0 > "/dev/stderr";
+ exit 1;
+ }
+ version[pos + 0] = cnt SUBSEP last_version;
+ pos++;
+ if (cnt < highest) {
+ printf "*** %s #errlist-compat counts are not sorted\n", ARGV[ARGIND];
+ exit 1;
+ }
+ if (cnt > highest)
+ highest = cnt;
+ highest_version = last_version;
+ next;
+}
+
+END {
+ if (! highest_version) {
+ print "/* No sys_errlist/sys_nerr symbols defined on this platform. */";
+ exit 0;
+ }
+
+ count = maxerr + 1;
+
+ if (highest < count) {
+ printf "*** errlist.c count %d vs Versions sys_errlist@%s count %d\n", \
+ count, highest_version, highest > "/dev/stderr";
+ exit 1;
+ }
+
+ lastv = "";
+ for (n = 0; n < pos; ++n) {
+ split(version[n], t, SUBSEP)
+ v = t[2];
+ gsub(/[^A-Z0-9_]/, "_", v);
+ if (lastv != "")
+ compat[lastv] = v;
+ lastv = v;
+ vcount[v] = t[1];
+ }
+
+ print "/* This file was generated by errlist-compat.awk; DO NOT EDIT! */\n";
+ print "#include <shlib-compat.h>\n";
+
+ if (highest > count) {
+ printf "*** errlist.c count %d inflated to %s count %d (old errno.h?)\n", \
+ count, highest_version, highest > "/dev/stderr";
+ printf "#define ERR_MAX %d\n\n", highest;
+ }
+
+ for (old in compat) {
+ new = compat[old];
+ n = vcount[old];
+ printf "#if SHLIB_COMPAT (libc, %s, %s)\n", old, new;
+ printf "# include <bits/wordsize.h>\n";
+ printf "extern const char *const __sys_errlist_%s[NERR];\n", old;
+ printf "const int __sys_nerr_%s = %d;\n", old, n;
+ printf "strong_alias (_sys_errlist_internal, __sys_errlist_%s)\n", old;
+ printf "declare_symbol (__sys_errlist_%s, object, __WORDSIZE/8*%d)\n", \
+ old, n;
+ printf "compat_symbol (libc, __sys_errlist_%s, sys_errlist, %s);\n", \
+ old, old;
+ printf "compat_symbol (libc, __sys_nerr_%s, sys_nerr, %s);\n", old, old;
+
+ printf "extern const char *const ___sys_errlist_%s[NERR];\n", old;
+ printf "extern const int __sys_nerr_%s;\n", old;
+ printf "strong_alias (__sys_errlist_%s, ___sys_errlist_%s)\n", old, old;
+ printf "strong_alias (__sys_nerr_%s, ___sys_nerr_%s)\n", old, old;
+ printf "compat_symbol (libc, ___sys_errlist_%s, _sys_errlist, %s);\n", \
+ old, old;
+ printf "compat_symbol (libc, ___sys_nerr_%s, _sys_nerr, %s);\n", old, old;
+ printf "#endif\n\n";
+ }
+
+ printf "\
+extern const char *const __sys_errlist_internal[NERR];\n\
+extern const int __sys_nerr_internal;\n\
+strong_alias (_sys_errlist_internal, __sys_errlist_internal)\n\
+strong_alias (_sys_nerr_internal, __sys_nerr_internal)\n\
+extern const char *const sys_errlist[NERR];\n\
+versioned_symbol (libc, _sys_errlist_internal, sys_errlist, %s);\n\
+versioned_symbol (libc, __sys_errlist_internal, _sys_errlist, %s);\n\
+versioned_symbol (libc, _sys_nerr_internal, sys_nerr, %s);\n\
+versioned_symbol (libc, __sys_nerr_internal, _sys_nerr, %s);\n", \
+ lastv, lastv, lastv, lastv;
+
+ print "\n\
+link_warning (sys_errlist, \"\
+`sys_errlist' is deprecated; use `strerror' or `strerror_r' instead\")\n\
+link_warning (sys_nerr, \"\
+`sys_nerr' is deprecated; use `strerror' or `strerror_r' instead\")";
+}
diff --git a/libc/sysdeps/gnu/errlist.awk b/libc/sysdeps/gnu/errlist.awk
new file mode 100644
index 000000000..365ac817c
--- /dev/null
+++ b/libc/sysdeps/gnu/errlist.awk
@@ -0,0 +1,121 @@
+# Copyright (C) 1991-1999,2002,2004,2005 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+# errno.texi contains lines like:
+# @comment errno.h
+# @comment POSIX.1: Function not implemented
+# @deftypevr Macro int ENOSYS
+# @comment errno 78
+# Descriptive paragraph...
+# @end deftypevr
+
+BEGIN {
+
+ # Here we list the E* names that might be duplicate names for the
+ # same integer value on some systems. This causes the code below
+ # to generate ``#if defined (ALIAS) && ALIAS != ORIGINAL'' in the code,
+ # so the output does not presume that these are in fact aliases.
+ # We list here all the known potential cases on any system,
+ # so that the C source we produce will do the right thing based
+ # on the actual #define'd values it's compiled with.
+ alias["EWOULDBLOCK"]= "EAGAIN";
+ alias["EDEADLOCK"] = "EDEADLK";
+ alias["ENOTSUP"] = "EOPNOTSUPP";
+
+ print "/* This file is generated from errno.texi by errlist.awk. */"
+ print "";
+ print "#include <errno.h>";
+ print "#include <libintl.h>";
+ print "";
+ print "#ifndef ERR_REMAP";
+ print "# define ERR_REMAP(n) n";
+ print "#endif";
+ print "";
+
+ print "#if !defined EMIT_ERR_MAX && !defined ERRLIST_NO_COMPAT";
+ print "# include <errlist-compat.h>";
+ print "#endif";
+ print "#ifdef ERR_MAX";
+ print "# define ERRLIST_SIZE ERR_MAX + 1";
+ print "#else"
+ print "# define ERRLIST_SIZE";
+ print "#endif";
+
+ print "const char *const _sys_errlist_internal[ERRLIST_SIZE] =";
+ print " {";
+ print " [0] = N_(\"Success\"),"
+ }
+
+$1 == "@comment" && $2 == "errno.h" { errnoh=1; next }
+errnoh == 1 && $1 == "@comment" \
+ {
+ ++errnoh;
+ etext = $3;
+ for (i = 4; i <= NF; ++i)
+ etext = etext " " $i;
+ next;
+ }
+errnoh == 2 && $1 == "@deftypevr" && $2 == "Macro" && $3 == "int" \
+ {
+ e = $4; errnoh++; next;
+ }
+errnoh == 3 && $1 == "@comment" && $2 == "errno" \
+ {
+ errno = $3 + 0;
+ if (alias[e])
+ printf "#if defined (%s) && %s != %s\n", e, e, alias[e];
+ else
+ printf "#ifdef %s\n", e;
+ errnoh = 4;
+ desc="";
+ next;
+ }
+errnoh == 4 && $1 == "@end" && $2 == "deftypevr" \
+ {
+ printf "/*%s */\n", desc;
+ printf " [ERR_REMAP (%s)] = N_(\"%s\"),\n", e, etext;
+ printf "# if %s > ERR_MAX\n", e;
+ print "# undef ERR_MAX";
+ printf "# define ERR_MAX %s\n", e;
+ print "# endif";
+ print "#endif";
+ errnoh = 0;
+ next;
+ }
+errnoh == 4 \
+ {
+ # This magic tag in C comments gets them copied into libc.pot.
+ desc = desc "\nTRANS " $0; next
+ }
+{ errnoh=0 }
+END {
+ print " };";
+ print "";
+ print "#define NERR \\";
+ print " (sizeof _sys_errlist_internal / sizeof _sys_errlist_internal [0])";
+ print "const int _sys_nerr_internal = NERR;"
+ print "";
+ print "#if !defined NOT_IN_libc && !ERRLIST_NO_COMPAT";
+ print "# include <errlist-compat.c>";
+ print "#endif";
+ print "";
+ print "#ifdef EMIT_ERR_MAX";
+ print "void dummy (void)"
+ print "{ asm volatile (\" @@@ %0 @@@ \" : : \"i\" (ERR_REMAP (ERR_MAX))); }"
+ print "#endif";
+}
diff --git a/libc/sysdeps/gnu/errlist.c b/libc/sysdeps/gnu/errlist.c
new file mode 100644
index 000000000..56da01756
--- /dev/null
+++ b/libc/sysdeps/gnu/errlist.c
@@ -0,0 +1,1472 @@
+/* This file is generated from errno.texi by errlist.awk. */
+
+#include <errno.h>
+#include <libintl.h>
+
+#ifndef ERR_REMAP
+# define ERR_REMAP(n) n
+#endif
+
+#if !defined EMIT_ERR_MAX && !defined ERRLIST_NO_COMPAT
+# include <errlist-compat.h>
+#endif
+#ifdef ERR_MAX
+# define ERRLIST_SIZE ERR_MAX + 1
+#else
+# define ERRLIST_SIZE
+#endif
+const char *const _sys_errlist_internal[ERRLIST_SIZE] =
+ {
+ [0] = N_("Success"),
+#ifdef EPERM
+/*
+TRANS Operation not permitted; only the owner of the file (or other resource)
+TRANS or processes with special privileges can perform the operation. */
+ [ERR_REMAP (EPERM)] = N_("Operation not permitted"),
+# if EPERM > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EPERM
+# endif
+#endif
+#ifdef ENOENT
+/*
+TRANS No such file or directory. This is a ``file doesn't exist'' error
+TRANS for ordinary files that are referenced in contexts where they are
+TRANS expected to already exist. */
+ [ERR_REMAP (ENOENT)] = N_("No such file or directory"),
+# if ENOENT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOENT
+# endif
+#endif
+#ifdef ESRCH
+/*
+TRANS No process matches the specified process ID. */
+ [ERR_REMAP (ESRCH)] = N_("No such process"),
+# if ESRCH > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ESRCH
+# endif
+#endif
+#ifdef EINTR
+/*
+TRANS Interrupted function call; an asynchronous signal occurred and prevented
+TRANS completion of the call. When this happens, you should try the call
+TRANS again.
+TRANS
+TRANS You can choose to have functions resume after a signal that is handled,
+TRANS rather than failing with @code{EINTR}; see @ref{Interrupted
+TRANS Primitives}. */
+ [ERR_REMAP (EINTR)] = N_("Interrupted system call"),
+# if EINTR > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EINTR
+# endif
+#endif
+#ifdef EIO
+/*
+TRANS Input/output error; usually used for physical read or write errors. */
+ [ERR_REMAP (EIO)] = N_("Input/output error"),
+# if EIO > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EIO
+# endif
+#endif
+#ifdef ENXIO
+/*
+TRANS No such device or address. The system tried to use the device
+TRANS represented by a file you specified, and it couldn't find the device.
+TRANS This can mean that the device file was installed incorrectly, or that
+TRANS the physical device is missing or not correctly attached to the
+TRANS computer. */
+ [ERR_REMAP (ENXIO)] = N_("No such device or address"),
+# if ENXIO > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENXIO
+# endif
+#endif
+#ifdef E2BIG
+/*
+TRANS Argument list too long; used when the arguments passed to a new program
+TRANS being executed with one of the @code{exec} functions (@pxref{Executing a
+TRANS File}) occupy too much memory space. This condition never arises in the
+TRANS GNU system. */
+ [ERR_REMAP (E2BIG)] = N_("Argument list too long"),
+# if E2BIG > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX E2BIG
+# endif
+#endif
+#ifdef ENOEXEC
+/*
+TRANS Invalid executable file format. This condition is detected by the
+TRANS @code{exec} functions; see @ref{Executing a File}. */
+ [ERR_REMAP (ENOEXEC)] = N_("Exec format error"),
+# if ENOEXEC > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOEXEC
+# endif
+#endif
+#ifdef EBADF
+/*
+TRANS Bad file descriptor; for example, I/O on a descriptor that has been
+TRANS closed or reading from a descriptor open only for writing (or vice
+TRANS versa). */
+ [ERR_REMAP (EBADF)] = N_("Bad file descriptor"),
+# if EBADF > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EBADF
+# endif
+#endif
+#ifdef ECHILD
+/*
+TRANS There are no child processes. This error happens on operations that are
+TRANS supposed to manipulate child processes, when there aren't any processes
+TRANS to manipulate. */
+ [ERR_REMAP (ECHILD)] = N_("No child processes"),
+# if ECHILD > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ECHILD
+# endif
+#endif
+#ifdef EDEADLK
+/*
+TRANS Deadlock avoided; allocating a system resource would have resulted in a
+TRANS deadlock situation. The system does not guarantee that it will notice
+TRANS all such situations. This error means you got lucky and the system
+TRANS noticed; it might just hang. @xref{File Locks}, for an example. */
+ [ERR_REMAP (EDEADLK)] = N_("Resource deadlock avoided"),
+# if EDEADLK > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EDEADLK
+# endif
+#endif
+#ifdef ENOMEM
+/*
+TRANS No memory available. The system cannot allocate more virtual memory
+TRANS because its capacity is full. */
+ [ERR_REMAP (ENOMEM)] = N_("Cannot allocate memory"),
+# if ENOMEM > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOMEM
+# endif
+#endif
+#ifdef EACCES
+/*
+TRANS Permission denied; the file permissions do not allow the attempted operation. */
+ [ERR_REMAP (EACCES)] = N_("Permission denied"),
+# if EACCES > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EACCES
+# endif
+#endif
+#ifdef EFAULT
+/*
+TRANS Bad address; an invalid pointer was detected.
+TRANS In the GNU system, this error never happens; you get a signal instead. */
+ [ERR_REMAP (EFAULT)] = N_("Bad address"),
+# if EFAULT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EFAULT
+# endif
+#endif
+#ifdef ENOTBLK
+/*
+TRANS A file that isn't a block special file was given in a situation that
+TRANS requires one. For example, trying to mount an ordinary file as a file
+TRANS system in Unix gives this error. */
+ [ERR_REMAP (ENOTBLK)] = N_("Block device required"),
+# if ENOTBLK > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOTBLK
+# endif
+#endif
+#ifdef EBUSY
+/*
+TRANS Resource busy; a system resource that can't be shared is already in use.
+TRANS For example, if you try to delete a file that is the root of a currently
+TRANS mounted filesystem, you get this error. */
+ [ERR_REMAP (EBUSY)] = N_("Device or resource busy"),
+# if EBUSY > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EBUSY
+# endif
+#endif
+#ifdef EEXIST
+/*
+TRANS File exists; an existing file was specified in a context where it only
+TRANS makes sense to specify a new file. */
+ [ERR_REMAP (EEXIST)] = N_("File exists"),
+# if EEXIST > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EEXIST
+# endif
+#endif
+#ifdef EXDEV
+/*
+TRANS An attempt to make an improper link across file systems was detected.
+TRANS This happens not only when you use @code{link} (@pxref{Hard Links}) but
+TRANS also when you rename a file with @code{rename} (@pxref{Renaming Files}). */
+ [ERR_REMAP (EXDEV)] = N_("Invalid cross-device link"),
+# if EXDEV > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EXDEV
+# endif
+#endif
+#ifdef ENODEV
+/*
+TRANS The wrong type of device was given to a function that expects a
+TRANS particular sort of device. */
+ [ERR_REMAP (ENODEV)] = N_("No such device"),
+# if ENODEV > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENODEV
+# endif
+#endif
+#ifdef ENOTDIR
+/*
+TRANS A file that isn't a directory was specified when a directory is required. */
+ [ERR_REMAP (ENOTDIR)] = N_("Not a directory"),
+# if ENOTDIR > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOTDIR
+# endif
+#endif
+#ifdef EISDIR
+/*
+TRANS File is a directory; you cannot open a directory for writing,
+TRANS or create or remove hard links to it. */
+ [ERR_REMAP (EISDIR)] = N_("Is a directory"),
+# if EISDIR > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EISDIR
+# endif
+#endif
+#ifdef EINVAL
+/*
+TRANS Invalid argument. This is used to indicate various kinds of problems
+TRANS with passing the wrong argument to a library function. */
+ [ERR_REMAP (EINVAL)] = N_("Invalid argument"),
+# if EINVAL > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EINVAL
+# endif
+#endif
+#ifdef EMFILE
+/*
+TRANS The current process has too many files open and can't open any more.
+TRANS Duplicate descriptors do count toward this limit.
+TRANS
+TRANS In BSD and GNU, the number of open files is controlled by a resource
+TRANS limit that can usually be increased. If you get this error, you might
+TRANS want to increase the @code{RLIMIT_NOFILE} limit or make it unlimited;
+TRANS @pxref{Limits on Resources}. */
+ [ERR_REMAP (EMFILE)] = N_("Too many open files"),
+# if EMFILE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EMFILE
+# endif
+#endif
+#ifdef ENFILE
+/*
+TRANS There are too many distinct file openings in the entire system. Note
+TRANS that any number of linked channels count as just one file opening; see
+TRANS @ref{Linked Channels}. This error never occurs in the GNU system. */
+ [ERR_REMAP (ENFILE)] = N_("Too many open files in system"),
+# if ENFILE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENFILE
+# endif
+#endif
+#ifdef ENOTTY
+/*
+TRANS Inappropriate I/O control operation, such as trying to set terminal
+TRANS modes on an ordinary file. */
+ [ERR_REMAP (ENOTTY)] = N_("Inappropriate ioctl for device"),
+# if ENOTTY > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOTTY
+# endif
+#endif
+#ifdef ETXTBSY
+/*
+TRANS An attempt to execute a file that is currently open for writing, or
+TRANS write to a file that is currently being executed. Often using a
+TRANS debugger to run a program is considered having it open for writing and
+TRANS will cause this error. (The name stands for ``text file busy''.) This
+TRANS is not an error in the GNU system; the text is copied as necessary. */
+ [ERR_REMAP (ETXTBSY)] = N_("Text file busy"),
+# if ETXTBSY > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ETXTBSY
+# endif
+#endif
+#ifdef EFBIG
+/*
+TRANS File too big; the size of a file would be larger than allowed by the system. */
+ [ERR_REMAP (EFBIG)] = N_("File too large"),
+# if EFBIG > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EFBIG
+# endif
+#endif
+#ifdef ENOSPC
+/*
+TRANS No space left on device; write operation on a file failed because the
+TRANS disk is full. */
+ [ERR_REMAP (ENOSPC)] = N_("No space left on device"),
+# if ENOSPC > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOSPC
+# endif
+#endif
+#ifdef ESPIPE
+/*
+TRANS Invalid seek operation (such as on a pipe). */
+ [ERR_REMAP (ESPIPE)] = N_("Illegal seek"),
+# if ESPIPE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ESPIPE
+# endif
+#endif
+#ifdef EROFS
+/*
+TRANS An attempt was made to modify something on a read-only file system. */
+ [ERR_REMAP (EROFS)] = N_("Read-only file system"),
+# if EROFS > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EROFS
+# endif
+#endif
+#ifdef EMLINK
+/*
+TRANS Too many links; the link count of a single file would become too large.
+TRANS @code{rename} can cause this error if the file being renamed already has
+TRANS as many links as it can take (@pxref{Renaming Files}). */
+ [ERR_REMAP (EMLINK)] = N_("Too many links"),
+# if EMLINK > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EMLINK
+# endif
+#endif
+#ifdef EPIPE
+/*
+TRANS Broken pipe; there is no process reading from the other end of a pipe.
+TRANS Every library function that returns this error code also generates a
+TRANS @code{SIGPIPE} signal; this signal terminates the program if not handled
+TRANS or blocked. Thus, your program will never actually see @code{EPIPE}
+TRANS unless it has handled or blocked @code{SIGPIPE}. */
+ [ERR_REMAP (EPIPE)] = N_("Broken pipe"),
+# if EPIPE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EPIPE
+# endif
+#endif
+#ifdef EDOM
+/*
+TRANS Domain error; used by mathematical functions when an argument value does
+TRANS not fall into the domain over which the function is defined. */
+ [ERR_REMAP (EDOM)] = N_("Numerical argument out of domain"),
+# if EDOM > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EDOM
+# endif
+#endif
+#ifdef ERANGE
+/*
+TRANS Range error; used by mathematical functions when the result value is
+TRANS not representable because of overflow or underflow. */
+ [ERR_REMAP (ERANGE)] = N_("Numerical result out of range"),
+# if ERANGE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ERANGE
+# endif
+#endif
+#ifdef EAGAIN
+/*
+TRANS Resource temporarily unavailable; the call might work if you try again
+TRANS later. The macro @code{EWOULDBLOCK} is another name for @code{EAGAIN};
+TRANS they are always the same in the GNU C library.
+TRANS
+TRANS This error can happen in a few different situations:
+TRANS
+TRANS @itemize @bullet
+TRANS @item
+TRANS An operation that would block was attempted on an object that has
+TRANS non-blocking mode selected. Trying the same operation again will block
+TRANS until some external condition makes it possible to read, write, or
+TRANS connect (whatever the operation). You can use @code{select} to find out
+TRANS when the operation will be possible; @pxref{Waiting for I/O}.
+TRANS
+TRANS @strong{Portability Note:} In many older Unix systems, this condition
+TRANS was indicated by @code{EWOULDBLOCK}, which was a distinct error code
+TRANS different from @code{EAGAIN}. To make your program portable, you should
+TRANS check for both codes and treat them the same.
+TRANS
+TRANS @item
+TRANS A temporary resource shortage made an operation impossible. @code{fork}
+TRANS can return this error. It indicates that the shortage is expected to
+TRANS pass, so your program can try the call again later and it may succeed.
+TRANS It is probably a good idea to delay for a few seconds before trying it
+TRANS again, to allow time for other processes to release scarce resources.
+TRANS Such shortages are usually fairly serious and affect the whole system,
+TRANS so usually an interactive program should report the error to the user
+TRANS and return to its command loop.
+TRANS @end itemize */
+ [ERR_REMAP (EAGAIN)] = N_("Resource temporarily unavailable"),
+# if EAGAIN > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EAGAIN
+# endif
+#endif
+#if defined (EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
+/*
+TRANS In the GNU C library, this is another name for @code{EAGAIN} (above).
+TRANS The values are always the same, on every operating system.
+TRANS
+TRANS C libraries in many older Unix systems have @code{EWOULDBLOCK} as a
+TRANS separate error code. */
+ [ERR_REMAP (EWOULDBLOCK)] = N_("Operation would block"),
+# if EWOULDBLOCK > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EWOULDBLOCK
+# endif
+#endif
+#ifdef EINPROGRESS
+/*
+TRANS An operation that cannot complete immediately was initiated on an object
+TRANS that has non-blocking mode selected. Some functions that must always
+TRANS block (such as @code{connect}; @pxref{Connecting}) never return
+TRANS @code{EAGAIN}. Instead, they return @code{EINPROGRESS} to indicate that
+TRANS the operation has begun and will take some time. Attempts to manipulate
+TRANS the object before the call completes return @code{EALREADY}. You can
+TRANS use the @code{select} function to find out when the pending operation
+TRANS has completed; @pxref{Waiting for I/O}. */
+ [ERR_REMAP (EINPROGRESS)] = N_("Operation now in progress"),
+# if EINPROGRESS > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EINPROGRESS
+# endif
+#endif
+#ifdef EALREADY
+/*
+TRANS An operation is already in progress on an object that has non-blocking
+TRANS mode selected. */
+ [ERR_REMAP (EALREADY)] = N_("Operation already in progress"),
+# if EALREADY > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EALREADY
+# endif
+#endif
+#ifdef ENOTSOCK
+/*
+TRANS A file that isn't a socket was specified when a socket is required. */
+ [ERR_REMAP (ENOTSOCK)] = N_("Socket operation on non-socket"),
+# if ENOTSOCK > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOTSOCK
+# endif
+#endif
+#ifdef EMSGSIZE
+/*
+TRANS The size of a message sent on a socket was larger than the supported
+TRANS maximum size. */
+ [ERR_REMAP (EMSGSIZE)] = N_("Message too long"),
+# if EMSGSIZE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EMSGSIZE
+# endif
+#endif
+#ifdef EPROTOTYPE
+/*
+TRANS The socket type does not support the requested communications protocol. */
+ [ERR_REMAP (EPROTOTYPE)] = N_("Protocol wrong type for socket"),
+# if EPROTOTYPE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EPROTOTYPE
+# endif
+#endif
+#ifdef ENOPROTOOPT
+/*
+TRANS You specified a socket option that doesn't make sense for the
+TRANS particular protocol being used by the socket. @xref{Socket Options}. */
+ [ERR_REMAP (ENOPROTOOPT)] = N_("Protocol not available"),
+# if ENOPROTOOPT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOPROTOOPT
+# endif
+#endif
+#ifdef EPROTONOSUPPORT
+/*
+TRANS The socket domain does not support the requested communications protocol
+TRANS (perhaps because the requested protocol is completely invalid).
+TRANS @xref{Creating a Socket}. */
+ [ERR_REMAP (EPROTONOSUPPORT)] = N_("Protocol not supported"),
+# if EPROTONOSUPPORT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EPROTONOSUPPORT
+# endif
+#endif
+#ifdef ESOCKTNOSUPPORT
+/*
+TRANS The socket type is not supported. */
+ [ERR_REMAP (ESOCKTNOSUPPORT)] = N_("Socket type not supported"),
+# if ESOCKTNOSUPPORT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ESOCKTNOSUPPORT
+# endif
+#endif
+#ifdef EOPNOTSUPP
+/*
+TRANS The operation you requested is not supported. Some socket functions
+TRANS don't make sense for all types of sockets, and others may not be
+TRANS implemented for all communications protocols. In the GNU system, this
+TRANS error can happen for many calls when the object does not support the
+TRANS particular operation; it is a generic indication that the server knows
+TRANS nothing to do for that call. */
+ [ERR_REMAP (EOPNOTSUPP)] = N_("Operation not supported"),
+# if EOPNOTSUPP > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EOPNOTSUPP
+# endif
+#endif
+#ifdef EPFNOSUPPORT
+/*
+TRANS The socket communications protocol family you requested is not supported. */
+ [ERR_REMAP (EPFNOSUPPORT)] = N_("Protocol family not supported"),
+# if EPFNOSUPPORT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EPFNOSUPPORT
+# endif
+#endif
+#ifdef EAFNOSUPPORT
+/*
+TRANS The address family specified for a socket is not supported; it is
+TRANS inconsistent with the protocol being used on the socket. @xref{Sockets}. */
+ [ERR_REMAP (EAFNOSUPPORT)] = N_("Address family not supported by protocol"),
+# if EAFNOSUPPORT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EAFNOSUPPORT
+# endif
+#endif
+#ifdef EADDRINUSE
+/*
+TRANS The requested socket address is already in use. @xref{Socket Addresses}. */
+ [ERR_REMAP (EADDRINUSE)] = N_("Address already in use"),
+# if EADDRINUSE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EADDRINUSE
+# endif
+#endif
+#ifdef EADDRNOTAVAIL
+/*
+TRANS The requested socket address is not available; for example, you tried
+TRANS to give a socket a name that doesn't match the local host name.
+TRANS @xref{Socket Addresses}. */
+ [ERR_REMAP (EADDRNOTAVAIL)] = N_("Cannot assign requested address"),
+# if EADDRNOTAVAIL > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EADDRNOTAVAIL
+# endif
+#endif
+#ifdef ENETDOWN
+/*
+TRANS A socket operation failed because the network was down. */
+ [ERR_REMAP (ENETDOWN)] = N_("Network is down"),
+# if ENETDOWN > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENETDOWN
+# endif
+#endif
+#ifdef ENETUNREACH
+/*
+TRANS A socket operation failed because the subnet containing the remote host
+TRANS was unreachable. */
+ [ERR_REMAP (ENETUNREACH)] = N_("Network is unreachable"),
+# if ENETUNREACH > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENETUNREACH
+# endif
+#endif
+#ifdef ENETRESET
+/*
+TRANS A network connection was reset because the remote host crashed. */
+ [ERR_REMAP (ENETRESET)] = N_("Network dropped connection on reset"),
+# if ENETRESET > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENETRESET
+# endif
+#endif
+#ifdef ECONNABORTED
+/*
+TRANS A network connection was aborted locally. */
+ [ERR_REMAP (ECONNABORTED)] = N_("Software caused connection abort"),
+# if ECONNABORTED > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ECONNABORTED
+# endif
+#endif
+#ifdef ECONNRESET
+/*
+TRANS A network connection was closed for reasons outside the control of the
+TRANS local host, such as by the remote machine rebooting or an unrecoverable
+TRANS protocol violation. */
+ [ERR_REMAP (ECONNRESET)] = N_("Connection reset by peer"),
+# if ECONNRESET > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ECONNRESET
+# endif
+#endif
+#ifdef ENOBUFS
+/*
+TRANS The kernel's buffers for I/O operations are all in use. In GNU, this
+TRANS error is always synonymous with @code{ENOMEM}; you may get one or the
+TRANS other from network operations. */
+ [ERR_REMAP (ENOBUFS)] = N_("No buffer space available"),
+# if ENOBUFS > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOBUFS
+# endif
+#endif
+#ifdef EISCONN
+/*
+TRANS You tried to connect a socket that is already connected.
+TRANS @xref{Connecting}. */
+ [ERR_REMAP (EISCONN)] = N_("Transport endpoint is already connected"),
+# if EISCONN > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EISCONN
+# endif
+#endif
+#ifdef ENOTCONN
+/*
+TRANS The socket is not connected to anything. You get this error when you
+TRANS try to transmit data over a socket, without first specifying a
+TRANS destination for the data. For a connectionless socket (for datagram
+TRANS protocols, such as UDP), you get @code{EDESTADDRREQ} instead. */
+ [ERR_REMAP (ENOTCONN)] = N_("Transport endpoint is not connected"),
+# if ENOTCONN > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOTCONN
+# endif
+#endif
+#ifdef EDESTADDRREQ
+/*
+TRANS No default destination address was set for the socket. You get this
+TRANS error when you try to transmit data over a connectionless socket,
+TRANS without first specifying a destination for the data with @code{connect}. */
+ [ERR_REMAP (EDESTADDRREQ)] = N_("Destination address required"),
+# if EDESTADDRREQ > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EDESTADDRREQ
+# endif
+#endif
+#ifdef ESHUTDOWN
+/*
+TRANS The socket has already been shut down. */
+ [ERR_REMAP (ESHUTDOWN)] = N_("Cannot send after transport endpoint shutdown"),
+# if ESHUTDOWN > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ESHUTDOWN
+# endif
+#endif
+#ifdef ETOOMANYREFS
+/*
+TRANS ??? */
+ [ERR_REMAP (ETOOMANYREFS)] = N_("Too many references: cannot splice"),
+# if ETOOMANYREFS > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ETOOMANYREFS
+# endif
+#endif
+#ifdef ETIMEDOUT
+/*
+TRANS A socket operation with a specified timeout received no response during
+TRANS the timeout period. */
+ [ERR_REMAP (ETIMEDOUT)] = N_("Connection timed out"),
+# if ETIMEDOUT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ETIMEDOUT
+# endif
+#endif
+#ifdef ECONNREFUSED
+/*
+TRANS A remote host refused to allow the network connection (typically because
+TRANS it is not running the requested service). */
+ [ERR_REMAP (ECONNREFUSED)] = N_("Connection refused"),
+# if ECONNREFUSED > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ECONNREFUSED
+# endif
+#endif
+#ifdef ELOOP
+/*
+TRANS Too many levels of symbolic links were encountered in looking up a file name.
+TRANS This often indicates a cycle of symbolic links. */
+ [ERR_REMAP (ELOOP)] = N_("Too many levels of symbolic links"),
+# if ELOOP > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ELOOP
+# endif
+#endif
+#ifdef ENAMETOOLONG
+/*
+TRANS Filename too long (longer than @code{PATH_MAX}; @pxref{Limits for
+TRANS Files}) or host name too long (in @code{gethostname} or
+TRANS @code{sethostname}; @pxref{Host Identification}). */
+ [ERR_REMAP (ENAMETOOLONG)] = N_("File name too long"),
+# if ENAMETOOLONG > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENAMETOOLONG
+# endif
+#endif
+#ifdef EHOSTDOWN
+/*
+TRANS The remote host for a requested network connection is down. */
+ [ERR_REMAP (EHOSTDOWN)] = N_("Host is down"),
+# if EHOSTDOWN > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EHOSTDOWN
+# endif
+#endif
+#ifdef EHOSTUNREACH
+/*
+TRANS The remote host for a requested network connection is not reachable. */
+ [ERR_REMAP (EHOSTUNREACH)] = N_("No route to host"),
+# if EHOSTUNREACH > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EHOSTUNREACH
+# endif
+#endif
+#ifdef ENOTEMPTY
+/*
+TRANS Directory not empty, where an empty directory was expected. Typically,
+TRANS this error occurs when you are trying to delete a directory. */
+ [ERR_REMAP (ENOTEMPTY)] = N_("Directory not empty"),
+# if ENOTEMPTY > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOTEMPTY
+# endif
+#endif
+#ifdef EPROCLIM
+/*
+TRANS This means that the per-user limit on new process would be exceeded by
+TRANS an attempted @code{fork}. @xref{Limits on Resources}, for details on
+TRANS the @code{RLIMIT_NPROC} limit. */
+ [ERR_REMAP (EPROCLIM)] = N_("Too many processes"),
+# if EPROCLIM > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EPROCLIM
+# endif
+#endif
+#ifdef EUSERS
+/*
+TRANS The file quota system is confused because there are too many users.
+TRANS @c This can probably happen in a GNU system when using NFS. */
+ [ERR_REMAP (EUSERS)] = N_("Too many users"),
+# if EUSERS > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EUSERS
+# endif
+#endif
+#ifdef EDQUOT
+/*
+TRANS The user's disk quota was exceeded. */
+ [ERR_REMAP (EDQUOT)] = N_("Disk quota exceeded"),
+# if EDQUOT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EDQUOT
+# endif
+#endif
+#ifdef ESTALE
+/*
+TRANS Stale NFS file handle. This indicates an internal confusion in the NFS
+TRANS system which is due to file system rearrangements on the server host.
+TRANS Repairing this condition usually requires unmounting and remounting
+TRANS the NFS file system on the local host. */
+ [ERR_REMAP (ESTALE)] = N_("Stale NFS file handle"),
+# if ESTALE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ESTALE
+# endif
+#endif
+#ifdef EREMOTE
+/*
+TRANS An attempt was made to NFS-mount a remote file system with a file name that
+TRANS already specifies an NFS-mounted file.
+TRANS (This is an error on some operating systems, but we expect it to work
+TRANS properly on the GNU system, making this error code impossible.) */
+ [ERR_REMAP (EREMOTE)] = N_("Object is remote"),
+# if EREMOTE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EREMOTE
+# endif
+#endif
+#ifdef EBADRPC
+/*
+TRANS ??? */
+ [ERR_REMAP (EBADRPC)] = N_("RPC struct is bad"),
+# if EBADRPC > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EBADRPC
+# endif
+#endif
+#ifdef ERPCMISMATCH
+/*
+TRANS ??? */
+ [ERR_REMAP (ERPCMISMATCH)] = N_("RPC version wrong"),
+# if ERPCMISMATCH > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ERPCMISMATCH
+# endif
+#endif
+#ifdef EPROGUNAVAIL
+/*
+TRANS ??? */
+ [ERR_REMAP (EPROGUNAVAIL)] = N_("RPC program not available"),
+# if EPROGUNAVAIL > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EPROGUNAVAIL
+# endif
+#endif
+#ifdef EPROGMISMATCH
+/*
+TRANS ??? */
+ [ERR_REMAP (EPROGMISMATCH)] = N_("RPC program version wrong"),
+# if EPROGMISMATCH > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EPROGMISMATCH
+# endif
+#endif
+#ifdef EPROCUNAVAIL
+/*
+TRANS ??? */
+ [ERR_REMAP (EPROCUNAVAIL)] = N_("RPC bad procedure for program"),
+# if EPROCUNAVAIL > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EPROCUNAVAIL
+# endif
+#endif
+#ifdef ENOLCK
+/*
+TRANS No locks available. This is used by the file locking facilities; see
+TRANS @ref{File Locks}. This error is never generated by the GNU system, but
+TRANS it can result from an operation to an NFS server running another
+TRANS operating system. */
+ [ERR_REMAP (ENOLCK)] = N_("No locks available"),
+# if ENOLCK > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOLCK
+# endif
+#endif
+#ifdef EFTYPE
+/*
+TRANS Inappropriate file type or format. The file was the wrong type for the
+TRANS operation, or a data file had the wrong format.
+TRANS
+TRANS On some systems @code{chmod} returns this error if you try to set the
+TRANS sticky bit on a non-directory file; @pxref{Setting Permissions}. */
+ [ERR_REMAP (EFTYPE)] = N_("Inappropriate file type or format"),
+# if EFTYPE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EFTYPE
+# endif
+#endif
+#ifdef EAUTH
+/*
+TRANS ??? */
+ [ERR_REMAP (EAUTH)] = N_("Authentication error"),
+# if EAUTH > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EAUTH
+# endif
+#endif
+#ifdef ENEEDAUTH
+/*
+TRANS ??? */
+ [ERR_REMAP (ENEEDAUTH)] = N_("Need authenticator"),
+# if ENEEDAUTH > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENEEDAUTH
+# endif
+#endif
+#ifdef ENOSYS
+/*
+TRANS Function not implemented. This indicates that the function called is
+TRANS not implemented at all, either in the C library itself or in the
+TRANS operating system. When you get this error, you can be sure that this
+TRANS particular function will always fail with @code{ENOSYS} unless you
+TRANS install a new version of the C library or the operating system. */
+ [ERR_REMAP (ENOSYS)] = N_("Function not implemented"),
+# if ENOSYS > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOSYS
+# endif
+#endif
+#if defined (ENOTSUP) && ENOTSUP != EOPNOTSUPP
+/*
+TRANS Not supported. A function returns this error when certain parameter
+TRANS values are valid, but the functionality they request is not available.
+TRANS This can mean that the function does not implement a particular command
+TRANS or option value or flag bit at all. For functions that operate on some
+TRANS object given in a parameter, such as a file descriptor or a port, it
+TRANS might instead mean that only @emph{that specific object} (file
+TRANS descriptor, port, etc.) is unable to support the other parameters given;
+TRANS different file descriptors might support different ranges of parameter
+TRANS values.
+TRANS
+TRANS If the entire function is not available at all in the implementation,
+TRANS it returns @code{ENOSYS} instead. */
+ [ERR_REMAP (ENOTSUP)] = N_("Not supported"),
+# if ENOTSUP > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOTSUP
+# endif
+#endif
+#ifdef EILSEQ
+/*
+TRANS While decoding a multibyte character the function came along an invalid
+TRANS or an incomplete sequence of bytes or the given wide character is invalid. */
+ [ERR_REMAP (EILSEQ)] = N_("Invalid or incomplete multibyte or wide character"),
+# if EILSEQ > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EILSEQ
+# endif
+#endif
+#ifdef EBACKGROUND
+/*
+TRANS In the GNU system, servers supporting the @code{term} protocol return
+TRANS this error for certain operations when the caller is not in the
+TRANS foreground process group of the terminal. Users do not usually see this
+TRANS error because functions such as @code{read} and @code{write} translate
+TRANS it into a @code{SIGTTIN} or @code{SIGTTOU} signal. @xref{Job Control},
+TRANS for information on process groups and these signals. */
+ [ERR_REMAP (EBACKGROUND)] = N_("Inappropriate operation for background process"),
+# if EBACKGROUND > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EBACKGROUND
+# endif
+#endif
+#ifdef EDIED
+/*
+TRANS In the GNU system, opening a file returns this error when the file is
+TRANS translated by a program and the translator program dies while starting
+TRANS up, before it has connected to the file. */
+ [ERR_REMAP (EDIED)] = N_("Translator died"),
+# if EDIED > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EDIED
+# endif
+#endif
+#ifdef ED
+/*
+TRANS The experienced user will know what is wrong.
+TRANS @c This error code is a joke. Its perror text is part of the joke.
+TRANS @c Don't change it. */
+ [ERR_REMAP (ED)] = N_("?"),
+# if ED > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ED
+# endif
+#endif
+#ifdef EGREGIOUS
+/*
+TRANS You did @strong{what}? */
+ [ERR_REMAP (EGREGIOUS)] = N_("You really blew it this time"),
+# if EGREGIOUS > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EGREGIOUS
+# endif
+#endif
+#ifdef EIEIO
+/*
+TRANS Go home and have a glass of warm, dairy-fresh milk. */
+ [ERR_REMAP (EIEIO)] = N_("Computer bought the farm"),
+# if EIEIO > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EIEIO
+# endif
+#endif
+#ifdef EGRATUITOUS
+/*
+TRANS This error code has no purpose. */
+ [ERR_REMAP (EGRATUITOUS)] = N_("Gratuitous error"),
+# if EGRATUITOUS > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EGRATUITOUS
+# endif
+#endif
+#ifdef EBADMSG
+/* */
+ [ERR_REMAP (EBADMSG)] = N_("Bad message"),
+# if EBADMSG > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EBADMSG
+# endif
+#endif
+#ifdef EIDRM
+/* */
+ [ERR_REMAP (EIDRM)] = N_("Identifier removed"),
+# if EIDRM > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EIDRM
+# endif
+#endif
+#ifdef EMULTIHOP
+/* */
+ [ERR_REMAP (EMULTIHOP)] = N_("Multihop attempted"),
+# if EMULTIHOP > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EMULTIHOP
+# endif
+#endif
+#ifdef ENODATA
+/* */
+ [ERR_REMAP (ENODATA)] = N_("No data available"),
+# if ENODATA > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENODATA
+# endif
+#endif
+#ifdef ENOLINK
+/* */
+ [ERR_REMAP (ENOLINK)] = N_("Link has been severed"),
+# if ENOLINK > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOLINK
+# endif
+#endif
+#ifdef ENOMSG
+/* */
+ [ERR_REMAP (ENOMSG)] = N_("No message of desired type"),
+# if ENOMSG > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOMSG
+# endif
+#endif
+#ifdef ENOSR
+/* */
+ [ERR_REMAP (ENOSR)] = N_("Out of streams resources"),
+# if ENOSR > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOSR
+# endif
+#endif
+#ifdef ENOSTR
+/* */
+ [ERR_REMAP (ENOSTR)] = N_("Device not a stream"),
+# if ENOSTR > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOSTR
+# endif
+#endif
+#ifdef EOVERFLOW
+/* */
+ [ERR_REMAP (EOVERFLOW)] = N_("Value too large for defined data type"),
+# if EOVERFLOW > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EOVERFLOW
+# endif
+#endif
+#ifdef EPROTO
+/* */
+ [ERR_REMAP (EPROTO)] = N_("Protocol error"),
+# if EPROTO > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EPROTO
+# endif
+#endif
+#ifdef ETIME
+/* */
+ [ERR_REMAP (ETIME)] = N_("Timer expired"),
+# if ETIME > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ETIME
+# endif
+#endif
+#ifdef ECANCELED
+/*
+TRANS Operation canceled; an asynchronous operation was canceled before it
+TRANS completed. @xref{Asynchronous I/O}. When you call @code{aio_cancel},
+TRANS the normal result is for the operations affected to complete with this
+TRANS error; @pxref{Cancel AIO Operations}. */
+ [ERR_REMAP (ECANCELED)] = N_("Operation canceled"),
+# if ECANCELED > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ECANCELED
+# endif
+#endif
+#ifdef ERESTART
+/* */
+ [ERR_REMAP (ERESTART)] = N_("Interrupted system call should be restarted"),
+# if ERESTART > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ERESTART
+# endif
+#endif
+#ifdef ECHRNG
+/* */
+ [ERR_REMAP (ECHRNG)] = N_("Channel number out of range"),
+# if ECHRNG > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ECHRNG
+# endif
+#endif
+#ifdef EL2NSYNC
+/* */
+ [ERR_REMAP (EL2NSYNC)] = N_("Level 2 not synchronized"),
+# if EL2NSYNC > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EL2NSYNC
+# endif
+#endif
+#ifdef EL3HLT
+/* */
+ [ERR_REMAP (EL3HLT)] = N_("Level 3 halted"),
+# if EL3HLT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EL3HLT
+# endif
+#endif
+#ifdef EL3RST
+/* */
+ [ERR_REMAP (EL3RST)] = N_("Level 3 reset"),
+# if EL3RST > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EL3RST
+# endif
+#endif
+#ifdef ELNRNG
+/* */
+ [ERR_REMAP (ELNRNG)] = N_("Link number out of range"),
+# if ELNRNG > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ELNRNG
+# endif
+#endif
+#ifdef EUNATCH
+/* */
+ [ERR_REMAP (EUNATCH)] = N_("Protocol driver not attached"),
+# if EUNATCH > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EUNATCH
+# endif
+#endif
+#ifdef ENOCSI
+/* */
+ [ERR_REMAP (ENOCSI)] = N_("No CSI structure available"),
+# if ENOCSI > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOCSI
+# endif
+#endif
+#ifdef EL2HLT
+/* */
+ [ERR_REMAP (EL2HLT)] = N_("Level 2 halted"),
+# if EL2HLT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EL2HLT
+# endif
+#endif
+#ifdef EBADE
+/* */
+ [ERR_REMAP (EBADE)] = N_("Invalid exchange"),
+# if EBADE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EBADE
+# endif
+#endif
+#ifdef EBADR
+/* */
+ [ERR_REMAP (EBADR)] = N_("Invalid request descriptor"),
+# if EBADR > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EBADR
+# endif
+#endif
+#ifdef EXFULL
+/* */
+ [ERR_REMAP (EXFULL)] = N_("Exchange full"),
+# if EXFULL > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EXFULL
+# endif
+#endif
+#ifdef ENOANO
+/* */
+ [ERR_REMAP (ENOANO)] = N_("No anode"),
+# if ENOANO > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOANO
+# endif
+#endif
+#ifdef EBADRQC
+/* */
+ [ERR_REMAP (EBADRQC)] = N_("Invalid request code"),
+# if EBADRQC > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EBADRQC
+# endif
+#endif
+#ifdef EBADSLT
+/* */
+ [ERR_REMAP (EBADSLT)] = N_("Invalid slot"),
+# if EBADSLT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EBADSLT
+# endif
+#endif
+#if defined (EDEADLOCK) && EDEADLOCK != EDEADLK
+/* */
+ [ERR_REMAP (EDEADLOCK)] = N_("File locking deadlock error"),
+# if EDEADLOCK > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EDEADLOCK
+# endif
+#endif
+#ifdef EBFONT
+/* */
+ [ERR_REMAP (EBFONT)] = N_("Bad font file format"),
+# if EBFONT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EBFONT
+# endif
+#endif
+#ifdef ENONET
+/* */
+ [ERR_REMAP (ENONET)] = N_("Machine is not on the network"),
+# if ENONET > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENONET
+# endif
+#endif
+#ifdef ENOPKG
+/* */
+ [ERR_REMAP (ENOPKG)] = N_("Package not installed"),
+# if ENOPKG > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOPKG
+# endif
+#endif
+#ifdef EADV
+/* */
+ [ERR_REMAP (EADV)] = N_("Advertise error"),
+# if EADV > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EADV
+# endif
+#endif
+#ifdef ESRMNT
+/* */
+ [ERR_REMAP (ESRMNT)] = N_("Srmount error"),
+# if ESRMNT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ESRMNT
+# endif
+#endif
+#ifdef ECOMM
+/* */
+ [ERR_REMAP (ECOMM)] = N_("Communication error on send"),
+# if ECOMM > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ECOMM
+# endif
+#endif
+#ifdef EDOTDOT
+/* */
+ [ERR_REMAP (EDOTDOT)] = N_("RFS specific error"),
+# if EDOTDOT > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EDOTDOT
+# endif
+#endif
+#ifdef ENOTUNIQ
+/* */
+ [ERR_REMAP (ENOTUNIQ)] = N_("Name not unique on network"),
+# if ENOTUNIQ > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOTUNIQ
+# endif
+#endif
+#ifdef EBADFD
+/* */
+ [ERR_REMAP (EBADFD)] = N_("File descriptor in bad state"),
+# if EBADFD > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EBADFD
+# endif
+#endif
+#ifdef EREMCHG
+/* */
+ [ERR_REMAP (EREMCHG)] = N_("Remote address changed"),
+# if EREMCHG > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EREMCHG
+# endif
+#endif
+#ifdef ELIBACC
+/* */
+ [ERR_REMAP (ELIBACC)] = N_("Can not access a needed shared library"),
+# if ELIBACC > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ELIBACC
+# endif
+#endif
+#ifdef ELIBBAD
+/* */
+ [ERR_REMAP (ELIBBAD)] = N_("Accessing a corrupted shared library"),
+# if ELIBBAD > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ELIBBAD
+# endif
+#endif
+#ifdef ELIBSCN
+/* */
+ [ERR_REMAP (ELIBSCN)] = N_(".lib section in a.out corrupted"),
+# if ELIBSCN > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ELIBSCN
+# endif
+#endif
+#ifdef ELIBMAX
+/* */
+ [ERR_REMAP (ELIBMAX)] = N_("Attempting to link in too many shared libraries"),
+# if ELIBMAX > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ELIBMAX
+# endif
+#endif
+#ifdef ELIBEXEC
+/* */
+ [ERR_REMAP (ELIBEXEC)] = N_("Cannot exec a shared library directly"),
+# if ELIBEXEC > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ELIBEXEC
+# endif
+#endif
+#ifdef ESTRPIPE
+/* */
+ [ERR_REMAP (ESTRPIPE)] = N_("Streams pipe error"),
+# if ESTRPIPE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ESTRPIPE
+# endif
+#endif
+#ifdef EUCLEAN
+/* */
+ [ERR_REMAP (EUCLEAN)] = N_("Structure needs cleaning"),
+# if EUCLEAN > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EUCLEAN
+# endif
+#endif
+#ifdef ENOTNAM
+/* */
+ [ERR_REMAP (ENOTNAM)] = N_("Not a XENIX named type file"),
+# if ENOTNAM > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOTNAM
+# endif
+#endif
+#ifdef ENAVAIL
+/* */
+ [ERR_REMAP (ENAVAIL)] = N_("No XENIX semaphores available"),
+# if ENAVAIL > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENAVAIL
+# endif
+#endif
+#ifdef EISNAM
+/* */
+ [ERR_REMAP (EISNAM)] = N_("Is a named type file"),
+# if EISNAM > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EISNAM
+# endif
+#endif
+#ifdef EREMOTEIO
+/* */
+ [ERR_REMAP (EREMOTEIO)] = N_("Remote I/O error"),
+# if EREMOTEIO > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EREMOTEIO
+# endif
+#endif
+#ifdef ENOMEDIUM
+/* */
+ [ERR_REMAP (ENOMEDIUM)] = N_("No medium found"),
+# if ENOMEDIUM > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOMEDIUM
+# endif
+#endif
+#ifdef EMEDIUMTYPE
+/* */
+ [ERR_REMAP (EMEDIUMTYPE)] = N_("Wrong medium type"),
+# if EMEDIUMTYPE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EMEDIUMTYPE
+# endif
+#endif
+#ifdef ENOKEY
+/* */
+ [ERR_REMAP (ENOKEY)] = N_("Required key not available"),
+# if ENOKEY > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOKEY
+# endif
+#endif
+#ifdef EKEYEXPIRED
+/* */
+ [ERR_REMAP (EKEYEXPIRED)] = N_("Key has expired"),
+# if EKEYEXPIRED > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EKEYEXPIRED
+# endif
+#endif
+#ifdef EKEYREVOKED
+/* */
+ [ERR_REMAP (EKEYREVOKED)] = N_("Key has been revoked"),
+# if EKEYREVOKED > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EKEYREVOKED
+# endif
+#endif
+#ifdef EKEYREJECTED
+/* */
+ [ERR_REMAP (EKEYREJECTED)] = N_("Key was rejected by service"),
+# if EKEYREJECTED > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EKEYREJECTED
+# endif
+#endif
+#ifdef EOWNERDEAD
+/* */
+ [ERR_REMAP (EOWNERDEAD)] = N_("Owner died"),
+# if EOWNERDEAD > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX EOWNERDEAD
+# endif
+#endif
+#ifdef ENOTRECOVERABLE
+/* */
+ [ERR_REMAP (ENOTRECOVERABLE)] = N_("State not recoverable"),
+# if ENOTRECOVERABLE > ERR_MAX
+# undef ERR_MAX
+# define ERR_MAX ENOTRECOVERABLE
+# endif
+#endif
+ };
+
+#define NERR \
+ (sizeof _sys_errlist_internal / sizeof _sys_errlist_internal [0])
+const int _sys_nerr_internal = NERR;
+
+#if !defined NOT_IN_libc && !ERRLIST_NO_COMPAT
+# include <errlist-compat.c>
+#endif
+
+#ifdef EMIT_ERR_MAX
+void dummy (void)
+{ asm volatile (" @@@ %0 @@@ " : : "i" (ERR_REMAP (ERR_MAX))); }
+#endif
diff --git a/libc/sysdeps/gnu/getutmp.c b/libc/sysdeps/gnu/getutmp.c
new file mode 100644
index 000000000..7b6d7713e
--- /dev/null
+++ b/libc/sysdeps/gnu/getutmp.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <string.h>
+#include <utmp.h>
+/* This is an ugly hack but we must not see the getutmpx declaration. */
+#define getutmpx XXXgetutmpx
+#include <utmpx.h>
+#undef getutmpx
+
+void
+getutmp (const struct utmpx *utmpx, struct utmp *utmp)
+{
+ assert (sizeof (struct utmp) == sizeof (struct utmpx));
+ memcpy (utmp, utmpx, sizeof (struct utmp));
+}
+strong_alias (getutmp, getutmpx)
diff --git a/libc/sysdeps/gnu/getutmpx.c b/libc/sysdeps/gnu/getutmpx.c
new file mode 100644
index 000000000..f393734a6
--- /dev/null
+++ b/libc/sysdeps/gnu/getutmpx.c
@@ -0,0 +1 @@
+/* We don't need a separate version. it is the same as getutmp(). */
diff --git a/libc/sysdeps/gnu/glob64.c b/libc/sysdeps/gnu/glob64.c
new file mode 100644
index 000000000..d1e4e6f0d
--- /dev/null
+++ b/libc/sysdeps/gnu/glob64.c
@@ -0,0 +1,25 @@
+#include <dirent.h>
+#include <glob.h>
+#include <sys/stat.h>
+
+#define dirent dirent64
+#define __readdir(dirp) __readdir64 (dirp)
+
+#define glob_t glob64_t
+#define glob(pattern, flags, errfunc, pglob) \
+ glob64 (pattern, flags, errfunc, pglob)
+#define globfree(pglob) globfree64 (pglob)
+
+#undef stat
+#define stat stat64
+#undef __stat
+#define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
+
+#define NO_GLOB_PATTERN_P 1
+
+#define COMPILE_GLOB64 1
+
+#include <posix/glob.c>
+
+libc_hidden_def (glob64)
+libc_hidden_def (globfree64)
diff --git a/libc/sysdeps/gnu/ifaddrs.c b/libc/sysdeps/gnu/ifaddrs.c
new file mode 100644
index 000000000..5bc3224be
--- /dev/null
+++ b/libc/sysdeps/gnu/ifaddrs.c
@@ -0,0 +1,163 @@
+/* getifaddrs -- get names and addresses of all network interfaces
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <netinet/in.h>
+
+#include "ifreq.h"
+
+/* Create a linked list of `struct ifaddrs' structures, one for each
+ network interface on the host machine. If successful, store the
+ list in *IFAP and return 0. On errors, return -1 and set `errno'. */
+int
+getifaddrs (struct ifaddrs **ifap)
+{
+ /* This implementation handles only IPv4 interfaces.
+ The various ioctls below will only work on an AF_INET socket.
+ Some different mechanism entirely must be used for IPv6. */
+ int fd = __socket (AF_INET, SOCK_DGRAM, 0);
+ struct ifreq *ifreqs;
+ int nifs;
+
+ if (fd < 0)
+ return -1;
+
+ __ifreq (&ifreqs, &nifs, fd);
+ if (ifreqs == NULL) /* XXX doesn't distinguish error vs none */
+ {
+ __close (fd);
+ return -1;
+ }
+
+ /* Now we have the list of interfaces and each one's address.
+ Put it into the expected format and fill in the remaining details. */
+ if (nifs == 0)
+ *ifap = NULL;
+ else
+ {
+ struct
+ {
+ struct ifaddrs ia;
+ struct sockaddr addr, netmask, broadaddr;
+ char name[IF_NAMESIZE];
+ } *storage;
+ struct ifreq *ifr;
+ int i;
+
+ storage = malloc (nifs * sizeof storage[0]);
+ if (storage == NULL)
+ {
+ __close (fd);
+ __if_freereq (ifreqs, nifs);
+ return -1;
+ }
+
+ i = 0;
+ ifr = ifreqs;
+ do
+ {
+ /* Fill in pointers to the storage we've already allocated. */
+ storage[i].ia.ifa_next = &storage[i + 1].ia;
+ storage[i].ia.ifa_addr = &storage[i].addr;
+
+ /* Now copy the information we already have from SIOCGIFCONF. */
+ storage[i].ia.ifa_name = strncpy (storage[i].name, ifr->ifr_name,
+ sizeof storage[i].name);
+ storage[i].addr = ifr->ifr_addr;
+
+ /* The SIOCGIFCONF call filled in only the name and address.
+ Now we must also ask for the other information we need. */
+
+ if (__ioctl (fd, SIOCGIFFLAGS, ifr) < 0)
+ break;
+ storage[i].ia.ifa_flags = ifr->ifr_flags;
+
+ ifr->ifr_addr = storage[i].addr;
+
+ if (__ioctl (fd, SIOCGIFNETMASK, ifr) < 0)
+ storage[i].ia.ifa_netmask = NULL;
+ else
+ {
+ storage[i].ia.ifa_netmask = &storage[i].netmask;
+ storage[i].netmask = ifr->ifr_netmask;
+ }
+
+ if (ifr->ifr_flags & IFF_BROADCAST)
+ {
+ ifr->ifr_addr = storage[i].addr;
+ if (__ioctl (fd, SIOCGIFBRDADDR, ifr) < 0)
+ storage[i].ia.ifa_broadaddr = NULL;
+ {
+ storage[i].ia.ifa_broadaddr = &storage[i].broadaddr;
+ storage[i].broadaddr = ifr->ifr_broadaddr;
+ }
+ }
+ else if (ifr->ifr_flags & IFF_POINTOPOINT)
+ {
+ ifr->ifr_addr = storage[i].addr;
+ if (__ioctl (fd, SIOCGIFDSTADDR, ifr) < 0)
+ storage[i].ia.ifa_broadaddr = NULL;
+ else
+ {
+ storage[i].ia.ifa_broadaddr = &storage[i].broadaddr;
+ storage[i].broadaddr = ifr->ifr_dstaddr;
+ }
+ }
+ else
+ storage[i].ia.ifa_broadaddr = NULL;
+
+ storage[i].ia.ifa_data = NULL; /* Nothing here for now. */
+
+ ifr = __if_nextreq (ifr);
+ } while (++i < nifs);
+ if (i < nifs) /* Broke out early on error. */
+ {
+ __close (fd);
+ free (storage);
+ __if_freereq (ifreqs, nifs);
+ return -1;
+ }
+
+ storage[i - 1].ia.ifa_next = NULL;
+
+ *ifap = &storage[0].ia;
+
+ __close (fd);
+ __if_freereq (ifreqs, nifs);
+ }
+
+ return 0;
+}
+#ifndef getifaddrs
+libc_hidden_def (getifaddrs)
+#endif
+
+void
+freeifaddrs (struct ifaddrs *ifa)
+{
+ free (ifa);
+}
+libc_hidden_def (freeifaddrs)
diff --git a/libc/sysdeps/gnu/net/if.h b/libc/sysdeps/gnu/net/if.h
new file mode 100644
index 000000000..ebb3e9f30
--- /dev/null
+++ b/libc/sysdeps/gnu/net/if.h
@@ -0,0 +1,205 @@
+/* net/if.h -- declarations for inquiring about network interfaces
+ Copyright (C) 1997,98,99,2000,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NET_IF_H
+#define _NET_IF_H 1
+
+#include <features.h>
+
+#ifdef __USE_MISC
+# include <sys/types.h>
+# include <sys/socket.h>
+#endif
+
+
+/* Length of interface name. */
+#define IF_NAMESIZE 16
+
+struct if_nameindex
+ {
+ unsigned int if_index; /* 1, 2, ... */
+ char *if_name; /* null terminated name: "eth0", ... */
+ };
+
+
+#ifdef __USE_MISC
+/* Standard interface flags. */
+enum
+ {
+ IFF_UP = 0x1, /* Interface is up. */
+# define IFF_UP IFF_UP
+ IFF_BROADCAST = 0x2, /* Broadcast address valid. */
+# define IFF_BROADCAST IFF_BROADCAST
+ IFF_DEBUG = 0x4, /* Turn on debugging. */
+# define IFF_DEBUG IFF_DEBUG
+ IFF_LOOPBACK = 0x8, /* Is a loopback net. */
+# define IFF_LOOPBACK IFF_LOOPBACK
+ IFF_POINTOPOINT = 0x10, /* Interface is point-to-point link. */
+# define IFF_POINTOPOINT IFF_POINTOPOINT
+ IFF_NOTRAILERS = 0x20, /* Avoid use of trailers. */
+# define IFF_NOTRAILERS IFF_NOTRAILERS
+ IFF_RUNNING = 0x40, /* Resources allocated. */
+# define IFF_RUNNING IFF_RUNNING
+ IFF_NOARP = 0x80, /* No address resolution protocol. */
+# define IFF_NOARP IFF_NOARP
+ IFF_PROMISC = 0x100, /* Receive all packets. */
+# define IFF_PROMISC IFF_PROMISC
+
+ /* Not supported */
+ IFF_ALLMULTI = 0x200, /* Receive all multicast packets. */
+# define IFF_ALLMULTI IFF_ALLMULTI
+
+ IFF_MASTER = 0x400, /* Master of a load balancer. */
+# define IFF_MASTER IFF_MASTER
+ IFF_SLAVE = 0x800, /* Slave of a load balancer. */
+# define IFF_SLAVE IFF_SLAVE
+
+ IFF_MULTICAST = 0x1000, /* Supports multicast. */
+# define IFF_MULTICAST IFF_MULTICAST
+
+ IFF_PORTSEL = 0x2000, /* Can set media type. */
+# define IFF_PORTSEL IFF_PORTSEL
+ IFF_AUTOMEDIA = 0x4000, /* Auto media select active. */
+# define IFF_AUTOMEDIA IFF_AUTOMEDIA
+ IFF_DYNAMIC = 0x8000 /* Dialup device with changing addresses. */
+# define IFF_DYNAMIC IFF_DYNAMIC
+ };
+
+/* The ifaddr structure contains information about one address of an
+ interface. They are maintained by the different address families,
+ are allocated and attached when an address is set, and are linked
+ together so all addresses for an interface can be located. */
+
+struct ifaddr
+ {
+ struct sockaddr ifa_addr; /* Address of interface. */
+ union
+ {
+ struct sockaddr ifu_broadaddr;
+ struct sockaddr ifu_dstaddr;
+ } ifa_ifu;
+ struct iface *ifa_ifp; /* Back-pointer to interface. */
+ struct ifaddr *ifa_next; /* Next address for interface. */
+ };
+
+# define ifa_broadaddr ifa_ifu.ifu_broadaddr /* broadcast address */
+# define ifa_dstaddr ifa_ifu.ifu_dstaddr /* other end of link */
+
+/* Device mapping structure. I'd just gone off and designed a
+ beautiful scheme using only loadable modules with arguments for
+ driver options and along come the PCMCIA people 8)
+
+ Ah well. The get() side of this is good for WDSETUP, and it'll be
+ handy for debugging things. The set side is fine for now and being
+ very small might be worth keeping for clean configuration. */
+
+struct ifmap
+ {
+ unsigned long int mem_start;
+ unsigned long int mem_end;
+ unsigned short int base_addr;
+ unsigned char irq;
+ unsigned char dma;
+ unsigned char port;
+ /* 3 bytes spare */
+ };
+
+/* Interface request structure used for socket ioctl's. All interface
+ ioctl's must have parameter definitions which begin with ifr_name.
+ The remainder may be interface specific. */
+
+struct ifreq
+ {
+# define IFHWADDRLEN 6
+# define IFNAMSIZ IF_NAMESIZE
+ union
+ {
+ char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */
+ } ifr_ifrn;
+
+ union
+ {
+ struct sockaddr ifru_addr;
+ struct sockaddr ifru_dstaddr;
+ struct sockaddr ifru_broadaddr;
+ struct sockaddr ifru_netmask;
+ struct sockaddr ifru_hwaddr;
+ short int ifru_flags;
+ int ifru_ivalue;
+ int ifru_mtu;
+ struct ifmap ifru_map;
+ char ifru_slave[IFNAMSIZ]; /* Just fits the size */
+ char ifru_newname[IFNAMSIZ];
+ __caddr_t ifru_data;
+ } ifr_ifru;
+ };
+# define ifr_name ifr_ifrn.ifrn_name /* interface name */
+# define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
+# define ifr_addr ifr_ifru.ifru_addr /* address */
+# define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
+# define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
+# define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
+# define ifr_flags ifr_ifru.ifru_flags /* flags */
+# define ifr_metric ifr_ifru.ifru_ivalue /* metric */
+# define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
+# define ifr_map ifr_ifru.ifru_map /* device map */
+# define ifr_slave ifr_ifru.ifru_slave /* slave device */
+# define ifr_data ifr_ifru.ifru_data /* for use by interface */
+# define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
+# define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
+# define ifr_qlen ifr_ifru.ifru_ivalue /* queue length */
+# define ifr_newname ifr_ifru.ifru_newname /* New name */
+# define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
+# define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
+# define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
+
+
+/* Structure used in SIOCGIFCONF request. Used to retrieve interface
+ configuration for machine (useful for programs which must know all
+ networks accessible). */
+
+struct ifconf
+ {
+ int ifc_len; /* Size of buffer. */
+ union
+ {
+ __caddr_t ifcu_buf;
+ struct ifreq *ifcu_req;
+ } ifc_ifcu;
+ };
+# define ifc_buf ifc_ifcu.ifcu_buf /* Buffer address. */
+# define ifc_req ifc_ifcu.ifcu_req /* Array of structures. */
+# define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0) /* not right */
+#endif /* Misc. */
+
+__BEGIN_DECLS
+
+/* Convert an interface name to an index, and vice versa. */
+extern unsigned int if_nametoindex (__const char *__ifname) __THROW;
+extern char *if_indextoname (unsigned int __ifindex, char *__ifname) __THROW;
+
+/* Return a list of all interfaces and their indices. */
+extern struct if_nameindex *if_nameindex (void) __THROW;
+
+/* Free the data returned from if_nameindex. */
+extern void if_freenameindex (struct if_nameindex *__ptr) __THROW;
+
+__END_DECLS
+
+#endif /* net/if.h */
diff --git a/libc/sysdeps/gnu/netinet/ip_icmp.h b/libc/sysdeps/gnu/netinet/ip_icmp.h
new file mode 100644
index 000000000..2fc8e9c1c
--- /dev/null
+++ b/libc/sysdeps/gnu/netinet/ip_icmp.h
@@ -0,0 +1,283 @@
+/* Copyright (C) 1991, 92, 93, 95, 96, 97, 99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __NETINET_IP_ICMP_H
+#define __NETINET_IP_ICMP_H 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+struct icmphdr
+{
+ u_int8_t type; /* message type */
+ u_int8_t code; /* type sub-code */
+ u_int16_t checksum;
+ union
+ {
+ struct
+ {
+ u_int16_t id;
+ u_int16_t sequence;
+ } echo; /* echo datagram */
+ u_int32_t gateway; /* gateway address */
+ struct
+ {
+ u_int16_t __unused;
+ u_int16_t mtu;
+ } frag; /* path mtu discovery */
+ } un;
+};
+
+#define ICMP_ECHOREPLY 0 /* Echo Reply */
+#define ICMP_DEST_UNREACH 3 /* Destination Unreachable */
+#define ICMP_SOURCE_QUENCH 4 /* Source Quench */
+#define ICMP_REDIRECT 5 /* Redirect (change route) */
+#define ICMP_ECHO 8 /* Echo Request */
+#define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */
+#define ICMP_PARAMETERPROB 12 /* Parameter Problem */
+#define ICMP_TIMESTAMP 13 /* Timestamp Request */
+#define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */
+#define ICMP_INFO_REQUEST 15 /* Information Request */
+#define ICMP_INFO_REPLY 16 /* Information Reply */
+#define ICMP_ADDRESS 17 /* Address Mask Request */
+#define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */
+#define NR_ICMP_TYPES 18
+
+
+/* Codes for UNREACH. */
+#define ICMP_NET_UNREACH 0 /* Network Unreachable */
+#define ICMP_HOST_UNREACH 1 /* Host Unreachable */
+#define ICMP_PROT_UNREACH 2 /* Protocol Unreachable */
+#define ICMP_PORT_UNREACH 3 /* Port Unreachable */
+#define ICMP_FRAG_NEEDED 4 /* Fragmentation Needed/DF set */
+#define ICMP_SR_FAILED 5 /* Source Route failed */
+#define ICMP_NET_UNKNOWN 6
+#define ICMP_HOST_UNKNOWN 7
+#define ICMP_HOST_ISOLATED 8
+#define ICMP_NET_ANO 9
+#define ICMP_HOST_ANO 10
+#define ICMP_NET_UNR_TOS 11
+#define ICMP_HOST_UNR_TOS 12
+#define ICMP_PKT_FILTERED 13 /* Packet filtered */
+#define ICMP_PREC_VIOLATION 14 /* Precedence violation */
+#define ICMP_PREC_CUTOFF 15 /* Precedence cut off */
+#define NR_ICMP_UNREACH 15 /* instead of hardcoding immediate value */
+
+/* Codes for REDIRECT. */
+#define ICMP_REDIR_NET 0 /* Redirect Net */
+#define ICMP_REDIR_HOST 1 /* Redirect Host */
+#define ICMP_REDIR_NETTOS 2 /* Redirect Net for TOS */
+#define ICMP_REDIR_HOSTTOS 3 /* Redirect Host for TOS */
+
+/* Codes for TIME_EXCEEDED. */
+#define ICMP_EXC_TTL 0 /* TTL count exceeded */
+#define ICMP_EXC_FRAGTIME 1 /* Fragment Reass time exceeded */
+
+
+#ifdef __USE_BSD
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93
+ */
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+
+/*
+ * Internal of an ICMP Router Advertisement
+ */
+struct icmp_ra_addr
+{
+ u_int32_t ira_addr;
+ u_int32_t ira_preference;
+};
+
+struct icmp
+{
+ u_int8_t icmp_type; /* type of message, see below */
+ u_int8_t icmp_code; /* type sub code */
+ u_int16_t icmp_cksum; /* ones complement checksum of struct */
+ union
+ {
+ u_char ih_pptr; /* ICMP_PARAMPROB */
+ struct in_addr ih_gwaddr; /* gateway address */
+ struct ih_idseq /* echo datagram */
+ {
+ u_int16_t icd_id;
+ u_int16_t icd_seq;
+ } ih_idseq;
+ u_int32_t ih_void;
+
+ /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
+ struct ih_pmtu
+ {
+ u_int16_t ipm_void;
+ u_int16_t ipm_nextmtu;
+ } ih_pmtu;
+
+ struct ih_rtradv
+ {
+ u_int8_t irt_num_addrs;
+ u_int8_t irt_wpa;
+ u_int16_t irt_lifetime;
+ } ih_rtradv;
+ } icmp_hun;
+#define icmp_pptr icmp_hun.ih_pptr
+#define icmp_gwaddr icmp_hun.ih_gwaddr
+#define icmp_id icmp_hun.ih_idseq.icd_id
+#define icmp_seq icmp_hun.ih_idseq.icd_seq
+#define icmp_void icmp_hun.ih_void
+#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
+#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
+#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
+#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
+#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
+ union
+ {
+ struct
+ {
+ u_int32_t its_otime;
+ u_int32_t its_rtime;
+ u_int32_t its_ttime;
+ } id_ts;
+ struct
+ {
+ struct ip idi_ip;
+ /* options and then 64 bits of data */
+ } id_ip;
+ struct icmp_ra_addr id_radv;
+ u_int32_t id_mask;
+ u_int8_t id_data[1];
+ } icmp_dun;
+#define icmp_otime icmp_dun.id_ts.its_otime
+#define icmp_rtime icmp_dun.id_ts.its_rtime
+#define icmp_ttime icmp_dun.id_ts.its_ttime
+#define icmp_ip icmp_dun.id_ip.idi_ip
+#define icmp_radv icmp_dun.id_radv
+#define icmp_mask icmp_dun.id_mask
+#define icmp_data icmp_dun.id_data
+};
+
+/*
+ * Lower bounds on packet lengths for various types.
+ * For the error advice packets must first insure that the
+ * packet is large enough to contain the returned ip header.
+ * Only then can we do the check to see if 64 bits of packet
+ * data have been returned, since we need to check the returned
+ * ip header length.
+ */
+#define ICMP_MINLEN 8 /* abs minimum */
+#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */
+#define ICMP_MASKLEN 12 /* address mask */
+#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
+#ifndef _IP_VHL
+#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
+ /* N.B.: must separately check that ip_hl >= 5 */
+#else
+#define ICMP_ADVLEN(p) (8 + (IP_VHL_HL((p)->icmp_ip.ip_vhl) << 2) + 8)
+ /* N.B.: must separately check that header length >= 5 */
+#endif
+
+/* Definition of type and code fields. */
+/* defined above: ICMP_ECHOREPLY, ICMP_REDIRECT, ICMP_ECHO */
+#define ICMP_UNREACH 3 /* dest unreachable, codes: */
+#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */
+#define ICMP_ROUTERADVERT 9 /* router advertisement */
+#define ICMP_ROUTERSOLICIT 10 /* router solicitation */
+#define ICMP_TIMXCEED 11 /* time exceeded, code: */
+#define ICMP_PARAMPROB 12 /* ip header bad */
+#define ICMP_TSTAMP 13 /* timestamp request */
+#define ICMP_TSTAMPREPLY 14 /* timestamp reply */
+#define ICMP_IREQ 15 /* information request */
+#define ICMP_IREQREPLY 16 /* information reply */
+#define ICMP_MASKREQ 17 /* address mask request */
+#define ICMP_MASKREPLY 18 /* address mask reply */
+
+#define ICMP_MAXTYPE 18
+
+/* UNREACH codes */
+#define ICMP_UNREACH_NET 0 /* bad net */
+#define ICMP_UNREACH_HOST 1 /* bad host */
+#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */
+#define ICMP_UNREACH_PORT 3 /* bad port */
+#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
+#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
+#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */
+#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */
+#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */
+#define ICMP_UNREACH_NET_PROHIB 9 /* net denied */
+#define ICMP_UNREACH_HOST_PROHIB 10 /* host denied */
+#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */
+#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */
+#define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohib */
+#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host prec vio. */
+#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* prec cutoff */
+
+/* REDIRECT codes */
+#define ICMP_REDIRECT_NET 0 /* for network */
+#define ICMP_REDIRECT_HOST 1 /* for host */
+#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */
+#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */
+
+/* TIMEXCEED codes */
+#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */
+#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */
+
+/* PARAMPROB code */
+#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */
+
+#define ICMP_INFOTYPE(type) \
+ ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
+ (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
+ (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
+ (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
+ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
+
+#endif /* __USE_BSD */
+
+__END_DECLS
+
+#endif /* netinet/ip_icmp.h */
diff --git a/libc/sysdeps/gnu/netinet/tcp.h b/libc/sysdeps/gnu/netinet/tcp.h
new file mode 100644
index 000000000..87099ec14
--- /dev/null
+++ b/libc/sysdeps/gnu/netinet/tcp.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_TCP_H
+#define _NETINET_TCP_H 1
+
+#include <features.h>
+
+/*
+ * User-settable options (used with setsockopt).
+ */
+#define TCP_NODELAY 1 /* Don't delay send to coalesce packets */
+#define TCP_MAXSEG 2 /* Set maximum segment size */
+#define TCP_CORK 3 /* Control sending of partial frames */
+#define TCP_KEEPIDLE 4 /* Start keeplives after this period */
+#define TCP_KEEPINTVL 5 /* Interval between keepalives */
+#define TCP_KEEPCNT 6 /* Number of keepalives before death */
+#define TCP_SYNCNT 7 /* Number of SYN retransmits */
+#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */
+#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */
+#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */
+#define TCP_INFO 11 /* Information about this connection. */
+#define TCP_QUICKACK 12 /* Bock/reenable quick ACKs. */
+
+#ifdef __USE_MISC
+# include <sys/types.h>
+
+# ifdef __FAVOR_BSD
+typedef u_int32_t tcp_seq;
+/*
+ * TCP header.
+ * Per RFC 793, September, 1981.
+ */
+struct tcphdr
+ {
+ u_int16_t th_sport; /* source port */
+ u_int16_t th_dport; /* destination port */
+ tcp_seq th_seq; /* sequence number */
+ tcp_seq th_ack; /* acknowledgement number */
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ u_int8_t th_x2:4; /* (unused) */
+ u_int8_t th_off:4; /* data offset */
+# endif
+# if __BYTE_ORDER == __BIG_ENDIAN
+ u_int8_t th_off:4; /* data offset */
+ u_int8_t th_x2:4; /* (unused) */
+# endif
+ u_int8_t th_flags;
+# define TH_FIN 0x01
+# define TH_SYN 0x02
+# define TH_RST 0x04
+# define TH_PUSH 0x08
+# define TH_ACK 0x10
+# define TH_URG 0x20
+ u_int16_t th_win; /* window */
+ u_int16_t th_sum; /* checksum */
+ u_int16_t th_urp; /* urgent pointer */
+};
+
+# else /* !__FAVOR_BSD */
+struct tcphdr
+ {
+ u_int16_t source;
+ u_int16_t dest;
+ u_int32_t seq;
+ u_int32_t ack_seq;
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ u_int16_t res1:4;
+ u_int16_t doff:4;
+ u_int16_t fin:1;
+ u_int16_t syn:1;
+ u_int16_t rst:1;
+ u_int16_t psh:1;
+ u_int16_t ack:1;
+ u_int16_t urg:1;
+ u_int16_t res2:2;
+# elif __BYTE_ORDER == __BIG_ENDIAN
+ u_int16_t doff:4;
+ u_int16_t res1:4;
+ u_int16_t res2:2;
+ u_int16_t urg:1;
+ u_int16_t ack:1;
+ u_int16_t psh:1;
+ u_int16_t rst:1;
+ u_int16_t syn:1;
+ u_int16_t fin:1;
+# else
+# error "Adjust your <bits/endian.h> defines"
+# endif
+ u_int16_t window;
+ u_int16_t check;
+ u_int16_t urg_ptr;
+};
+# endif /* __FAVOR_BSD */
+
+enum
+{
+ TCP_ESTABLISHED = 1,
+ TCP_SYN_SENT,
+ TCP_SYN_RECV,
+ TCP_FIN_WAIT1,
+ TCP_FIN_WAIT2,
+ TCP_TIME_WAIT,
+ TCP_CLOSE,
+ TCP_CLOSE_WAIT,
+ TCP_LAST_ACK,
+ TCP_LISTEN,
+ TCP_CLOSING /* now a valid state */
+};
+
+# define TCPOPT_EOL 0
+# define TCPOPT_NOP 1
+# define TCPOPT_MAXSEG 2
+# define TCPOLEN_MAXSEG 4
+# define TCPOPT_WINDOW 3
+# define TCPOLEN_WINDOW 3
+# define TCPOPT_SACK_PERMITTED 4 /* Experimental */
+# define TCPOLEN_SACK_PERMITTED 2
+# define TCPOPT_SACK 5 /* Experimental */
+# define TCPOPT_TIMESTAMP 8
+# define TCPOLEN_TIMESTAMP 10
+# define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
+
+# define TCPOPT_TSTAMP_HDR \
+ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
+
+/*
+ * Default maximum segment size for TCP.
+ * With an IP MSS of 576, this is 536,
+ * but 512 is probably more convenient.
+ * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
+ */
+# define TCP_MSS 512
+
+# define TCP_MAXWIN 65535 /* largest value for (unscaled) window */
+
+# define TCP_MAX_WINSHIFT 14 /* maximum window shift */
+
+# define SOL_TCP 6 /* TCP level */
+
+
+# define TCPI_OPT_TIMESTAMPS 1
+# define TCPI_OPT_SACK 2
+# define TCPI_OPT_WSCALE 4
+# define TCPI_OPT_ECN 8
+
+/* Values for tcpi_state. */
+enum tcp_ca_state
+{
+ TCP_CA_Open = 0,
+ TCP_CA_Disorder = 1,
+ TCP_CA_CWR = 2,
+ TCP_CA_Recovery = 3,
+ TCP_CA_Loss = 4
+};
+
+struct tcp_info
+{
+ u_int8_t tcpi_state;
+ u_int8_t tcpi_ca_state;
+ u_int8_t tcpi_retransmits;
+ u_int8_t tcpi_probes;
+ u_int8_t tcpi_backoff;
+ u_int8_t tcpi_options;
+ u_int8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
+
+ u_int32_t tcpi_rto;
+ u_int32_t tcpi_ato;
+ u_int32_t tcpi_snd_mss;
+ u_int32_t tcpi_rcv_mss;
+
+ u_int32_t tcpi_unacked;
+ u_int32_t tcpi_sacked;
+ u_int32_t tcpi_lost;
+ u_int32_t tcpi_retrans;
+ u_int32_t tcpi_fackets;
+
+ /* Times. */
+ u_int32_t tcpi_last_data_sent;
+ u_int32_t tcpi_last_ack_sent; /* Not remembered, sorry. */
+ u_int32_t tcpi_last_data_recv;
+ u_int32_t tcpi_last_ack_recv;
+
+ /* Metrics. */
+ u_int32_t tcpi_pmtu;
+ u_int32_t tcpi_rcv_ssthresh;
+ u_int32_t tcpi_rtt;
+ u_int32_t tcpi_rttvar;
+ u_int32_t tcpi_snd_ssthresh;
+ u_int32_t tcpi_snd_cwnd;
+ u_int32_t tcpi_advmss;
+ u_int32_t tcpi_reordering;
+};
+
+#endif /* Misc. */
+
+#endif /* netinet/tcp.h */
diff --git a/libc/sysdeps/gnu/netinet/udp.h b/libc/sysdeps/gnu/netinet/udp.h
new file mode 100644
index 000000000..45b69f749
--- /dev/null
+++ b/libc/sysdeps/gnu/netinet/udp.h
@@ -0,0 +1,79 @@
+/* Copyright (C) 1991, 92, 93, 95, 96, 97, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * Copyright (C) 1982, 1986 Regents of the University of California.
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+#ifndef __NETINET_UDP_H
+#define __NETINET_UDP_H 1
+
+#include <features.h>
+#include <sys/types.h>
+
+
+/* UDP header as specified by RFC 768, August 1980. */
+#ifdef __FAVOR_BSD
+
+struct udphdr
+{
+ u_int16_t uh_sport; /* source port */
+ u_int16_t uh_dport; /* destination port */
+ u_int16_t uh_ulen; /* udp length */
+ u_int16_t uh_sum; /* udp checksum */
+};
+
+#else
+
+struct udphdr
+{
+ u_int16_t source;
+ u_int16_t dest;
+ u_int16_t len;
+ u_int16_t check;
+};
+#endif
+
+#define SOL_UDP 17 /* sockopt level for UDP */
+
+#endif /* netinet/udp.h */
diff --git a/libc/sysdeps/gnu/siglist.c b/libc/sysdeps/gnu/siglist.c
new file mode 100644
index 000000000..cb1875f9e
--- /dev/null
+++ b/libc/sysdeps/gnu/siglist.c
@@ -0,0 +1,77 @@
+/* Define list of all signal numbers and their names.
+ Copyright (C) 1997-2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <signal.h>
+#include <libintl.h>
+#include <shlib-compat.h>
+#include <bits/wordsize.h>
+
+const char *const __new_sys_siglist[NSIG] =
+{
+#define init_sig(sig, abbrev, desc) [sig] = desc,
+#include <siglist.h>
+#undef init_sig
+};
+strong_alias (__new_sys_siglist, _sys_siglist_internal)
+
+const char *const __new_sys_sigabbrev[NSIG] =
+{
+#define init_sig(sig, abbrev, desc) [sig] = abbrev,
+#include <siglist.h>
+#undef init_sig
+};
+strong_alias (__new_sys_sigabbrev, _sys_sigabbrev_internal)
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+strong_alias (_sys_siglist_internal, __old_sys_siglist)
+declare_symbol (__old_sys_siglist, object, OLD_SIGLIST_SIZE * __WORDSIZE / 8)
+
+strong_alias (_sys_sigabbrev_internal, __old_sys_sigabbrev)
+declare_symbol (__old_sys_sigabbrev, object, OLD_SIGLIST_SIZE * __WORDSIZE / 8)
+
+strong_alias (__old_sys_siglist, _old_sys_siglist)
+compat_symbol (libc, __old_sys_siglist, _sys_siglist, GLIBC_2_0);
+compat_symbol (libc, _old_sys_siglist, sys_siglist, GLIBC_2_0);
+compat_symbol (libc, __old_sys_sigabbrev, sys_sigabbrev, GLIBC_2_0);
+#endif
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3) && defined OLD2_SIGLIST_SIZE
+strong_alias (_sys_siglist_internal, __old2_sys_siglist)
+declare_symbol (__old2_sys_siglist, object, OLD2_SIGLIST_SIZE * __WORDSIZE / 8)
+
+strong_alias (_sys_sigabbrev_internal, __old2_sys_sigabbrev)
+declare_symbol (__old2_sys_sigabbrev, object,
+ OLD2_SIGLIST_SIZE * __WORDSIZE / 8)
+
+strong_alias (__old2_sys_siglist, _old2_sys_siglist)
+compat_symbol (libc, __old2_sys_siglist, _sys_siglist, GLIBC_2_1);
+compat_symbol (libc, _old2_sys_siglist, sys_siglist, GLIBC_2_1);
+compat_symbol (libc, __old2_sys_sigabbrev, sys_sigabbrev, GLIBC_2_1);
+
+strong_alias (__new_sys_siglist, _new_sys_siglist)
+versioned_symbol (libc, __new_sys_siglist, _sys_siglist, GLIBC_2_3_3);
+versioned_symbol (libc, _new_sys_siglist, sys_siglist, GLIBC_2_3_3);
+versioned_symbol (libc, __new_sys_sigabbrev, sys_sigabbrev, GLIBC_2_3_3);
+#else
+strong_alias (__new_sys_siglist, _new_sys_siglist)
+versioned_symbol (libc, __new_sys_siglist, _sys_siglist, GLIBC_2_1);
+versioned_symbol (libc, _new_sys_siglist, sys_siglist, GLIBC_2_1);
+versioned_symbol (libc, __new_sys_sigabbrev, sys_sigabbrev, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/gnu/sys/mtio.h b/libc/sysdeps/gnu/sys/mtio.h
new file mode 100644
index 000000000..51fa550cd
--- /dev/null
+++ b/libc/sysdeps/gnu/sys/mtio.h
@@ -0,0 +1,277 @@
+/* Structures and definitions for magnetic tape I/O control commands.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Written by H. Bergman <hennus@cybercomm.nl>. */
+
+#ifndef _SYS_MTIO_H
+#define _SYS_MTIO_H 1
+
+/* Get necessary definitions from system and kernel headers. */
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+
+/* Structure for MTIOCTOP - magnetic tape operation command. */
+struct mtop
+ {
+ short int mt_op; /* Operations defined below. */
+ int mt_count; /* How many of them. */
+ };
+#define _IOT_mtop /* Hurd ioctl type field. */ \
+ _IOT (_IOTS (short), 1, _IOTS (int), 1, 0, 0)
+
+/* Magnetic Tape operations [Not all operations supported by all drivers]. */
+#define MTRESET 0 /* +reset drive in case of problems. */
+#define MTFSF 1 /* Forward space over FileMark,
+ * position at first record of next file. */
+#define MTBSF 2 /* Backward space FileMark (position before FM). */
+#define MTFSR 3 /* Forward space record. */
+#define MTBSR 4 /* Backward space record. */
+#define MTWEOF 5 /* Write an end-of-file record (mark). */
+#define MTREW 6 /* Rewind. */
+#define MTOFFL 7 /* Rewind and put the drive offline (eject?). */
+#define MTNOP 8 /* No op, set status only (read with MTIOCGET). */
+#define MTRETEN 9 /* Retension tape. */
+#define MTBSFM 10 /* +backward space FileMark, position at FM. */
+#define MTFSFM 11 /* +forward space FileMark, position at FM. */
+#define MTEOM 12 /* Goto end of recorded media (for appending files).
+ MTEOM positions after the last FM, ready for
+ appending another file. */
+#define MTERASE 13 /* Erase tape -- be careful! */
+
+#define MTRAS1 14 /* Run self test 1 (nondestructive). */
+#define MTRAS2 15 /* Run self test 2 (destructive). */
+#define MTRAS3 16 /* Reserved for self test 3. */
+
+#define MTSETBLK 20 /* Set block length (SCSI). */
+#define MTSETDENSITY 21 /* Set tape density (SCSI). */
+#define MTSEEK 22 /* Seek to block (Tandberg, etc.). */
+#define MTTELL 23 /* Tell block (Tandberg, etc.). */
+#define MTSETDRVBUFFER 24 /* Set the drive buffering according to SCSI-2.
+ Ordinary buffered operation with code 1. */
+#define MTFSS 25 /* Space forward over setmarks. */
+#define MTBSS 26 /* Space backward over setmarks. */
+#define MTWSM 27 /* Write setmarks. */
+
+#define MTLOCK 28 /* Lock the drive door. */
+#define MTUNLOCK 29 /* Unlock the drive door. */
+#define MTLOAD 30 /* Execute the SCSI load command. */
+#define MTUNLOAD 31 /* Execute the SCSI unload command. */
+#define MTCOMPRESSION 32/* Control compression with SCSI mode page 15. */
+#define MTSETPART 33 /* Change the active tape partition. */
+#define MTMKPART 34 /* Format the tape with one or two partitions. */
+
+/* structure for MTIOCGET - mag tape get status command */
+
+struct mtget
+ {
+ long int mt_type; /* Type of magtape device. */
+ long int mt_resid; /* Residual count: (not sure)
+ number of bytes ignored, or
+ number of files not skipped, or
+ number of records not skipped. */
+ /* The following registers are device dependent. */
+ long int mt_dsreg; /* Status register. */
+ long int mt_gstat; /* Generic (device independent) status. */
+ long int mt_erreg; /* Error register. */
+ /* The next two fields are not always used. */
+ __daddr_t mt_fileno; /* Number of current file on tape. */
+ __daddr_t mt_blkno; /* Current block number. */
+ };
+#define _IOT_mtget /* Hurd ioctl type field. */ \
+ _IOT (_IOTS (long), 7, 0, 0, 0, 0)
+
+
+/* Constants for mt_type. Not all of these are supported, and
+ these are not all of the ones that are supported. */
+#define MT_ISUNKNOWN 0x01
+#define MT_ISQIC02 0x02 /* Generic QIC-02 tape streamer. */
+#define MT_ISWT5150 0x03 /* Wangtek 5150EQ, QIC-150, QIC-02. */
+#define MT_ISARCHIVE_5945L2 0x04 /* Archive 5945L-2, QIC-24, QIC-02?. */
+#define MT_ISCMSJ500 0x05 /* CMS Jumbo 500 (QIC-02?). */
+#define MT_ISTDC3610 0x06 /* Tandberg 6310, QIC-24. */
+#define MT_ISARCHIVE_VP60I 0x07 /* Archive VP60i, QIC-02. */
+#define MT_ISARCHIVE_2150L 0x08 /* Archive Viper 2150L. */
+#define MT_ISARCHIVE_2060L 0x09 /* Archive Viper 2060L. */
+#define MT_ISARCHIVESC499 0x0A /* Archive SC-499 QIC-36 controller. */
+#define MT_ISQIC02_ALL_FEATURES 0x0F /* Generic QIC-02 with all features. */
+#define MT_ISWT5099EEN24 0x11 /* Wangtek 5099-een24, 60MB, QIC-24. */
+#define MT_ISTEAC_MT2ST 0x12 /* Teac MT-2ST 155mb drive,
+ Teac DC-1 card (Wangtek type). */
+#define MT_ISEVEREX_FT40A 0x32 /* Everex FT40A (QIC-40). */
+#define MT_ISDDS1 0x51 /* DDS device without partitions. */
+#define MT_ISDDS2 0x52 /* DDS device with partitions. */
+#define MT_ISSCSI1 0x71 /* Generic ANSI SCSI-1 tape unit. */
+#define MT_ISSCSI2 0x72 /* Generic ANSI SCSI-2 tape unit. */
+
+/* QIC-40/80/3010/3020 ftape supported drives.
+ 20bit vendor ID + 0x800000 (see vendors.h in ftape distribution). */
+#define MT_ISFTAPE_UNKNOWN 0x800000 /* obsolete */
+#define MT_ISFTAPE_FLAG 0x800000
+
+struct mt_tape_info
+ {
+ long int t_type; /* Device type id (mt_type). */
+ char *t_name; /* Descriptive name. */
+ };
+
+#define MT_TAPE_INFO \
+ { \
+ {MT_ISUNKNOWN, "Unknown type of tape device"}, \
+ {MT_ISQIC02, "Generic QIC-02 tape streamer"}, \
+ {MT_ISWT5150, "Wangtek 5150, QIC-150"}, \
+ {MT_ISARCHIVE_5945L2, "Archive 5945L-2"}, \
+ {MT_ISCMSJ500, "CMS Jumbo 500"}, \
+ {MT_ISTDC3610, "Tandberg TDC 3610, QIC-24"}, \
+ {MT_ISARCHIVE_VP60I, "Archive VP60i, QIC-02"}, \
+ {MT_ISARCHIVE_2150L, "Archive Viper 2150L"}, \
+ {MT_ISARCHIVE_2060L, "Archive Viper 2060L"}, \
+ {MT_ISARCHIVESC499, "Archive SC-499 QIC-36 controller"}, \
+ {MT_ISQIC02_ALL_FEATURES, "Generic QIC-02 tape, all features"}, \
+ {MT_ISWT5099EEN24, "Wangtek 5099-een24, 60MB"}, \
+ {MT_ISTEAC_MT2ST, "Teac MT-2ST 155mb data cassette drive"}, \
+ {MT_ISEVEREX_FT40A, "Everex FT40A, QIC-40"}, \
+ {MT_ISSCSI1, "Generic SCSI-1 tape"}, \
+ {MT_ISSCSI2, "Generic SCSI-2 tape"}, \
+ {0, NULL} \
+ }
+
+
+/* Structure for MTIOCPOS - mag tape get position command. */
+
+struct mtpos
+ {
+ long int mt_blkno; /* Current block number. */
+ };
+#define _IOT_mtpos /* Hurd ioctl type field. */ \
+ _IOT_SIMPLE (long)
+
+
+/* Structure for MTIOCGETCONFIG/MTIOCSETCONFIG primarily intended
+ as an interim solution for QIC-02 until DDI is fully implemented. */
+struct mtconfiginfo
+ {
+ long int mt_type; /* Drive type. */
+ long int ifc_type; /* Interface card type. */
+ unsigned short int irqnr; /* IRQ number to use. */
+ unsigned short int dmanr; /* DMA channel to use. */
+ unsigned short int port; /* IO port base address. */
+
+ unsigned long int debug; /* Debugging flags. */
+
+ unsigned have_dens:1;
+ unsigned have_bsf:1;
+ unsigned have_fsr:1;
+ unsigned have_bsr:1;
+ unsigned have_eod:1;
+ unsigned have_seek:1;
+ unsigned have_tell:1;
+ unsigned have_ras1:1;
+ unsigned have_ras2:1;
+ unsigned have_ras3:1;
+ unsigned have_qfa:1;
+
+ unsigned pad1:5;
+ char reserved[10];
+ };
+#define _IOT_mtconfiginfo /* Hurd ioctl type field. */ \
+ _IOT (_IOTS (long), 2, _IOTS (short), 3, _IOTS (long), 1) /* XXX wrong */
+
+
+/* Magnetic tape I/O control commands. */
+#define MTIOCTOP _IOW('m', 1, struct mtop) /* Do a mag tape op. */
+#define MTIOCGET _IOR('m', 2, struct mtget) /* Get tape status. */
+#define MTIOCPOS _IOR('m', 3, struct mtpos) /* Get tape position.*/
+
+/* The next two are used by the QIC-02 driver for runtime reconfiguration.
+ See tpqic02.h for struct mtconfiginfo. */
+#define MTIOCGETCONFIG _IOR('m', 4, struct mtconfiginfo) /* Get tape config.*/
+#define MTIOCSETCONFIG _IOW('m', 5, struct mtconfiginfo) /* Set tape config.*/
+
+/* Generic Mag Tape (device independent) status macros for examining
+ mt_gstat -- HP-UX compatible.
+ There is room for more generic status bits here, but I don't
+ know which of them are reserved. At least three or so should
+ be added to make this really useful. */
+#define GMT_EOF(x) ((x) & 0x80000000)
+#define GMT_BOT(x) ((x) & 0x40000000)
+#define GMT_EOT(x) ((x) & 0x20000000)
+#define GMT_SM(x) ((x) & 0x10000000) /* DDS setmark */
+#define GMT_EOD(x) ((x) & 0x08000000) /* DDS EOD */
+#define GMT_WR_PROT(x) ((x) & 0x04000000)
+/* #define GMT_ ? ((x) & 0x02000000) */
+#define GMT_ONLINE(x) ((x) & 0x01000000)
+#define GMT_D_6250(x) ((x) & 0x00800000)
+#define GMT_D_1600(x) ((x) & 0x00400000)
+#define GMT_D_800(x) ((x) & 0x00200000)
+/* #define GMT_ ? ((x) & 0x00100000) */
+/* #define GMT_ ? ((x) & 0x00080000) */
+#define GMT_DR_OPEN(x) ((x) & 0x00040000) /* Door open (no tape). */
+/* #define GMT_ ? ((x) & 0x00020000) */
+#define GMT_IM_REP_EN(x) ((x) & 0x00010000) /* Immediate report mode.*/
+/* 16 generic status bits unused. */
+
+
+/* SCSI-tape specific definitions. Bitfield shifts in the status */
+#define MT_ST_BLKSIZE_SHIFT 0
+#define MT_ST_BLKSIZE_MASK 0xffffff
+#define MT_ST_DENSITY_SHIFT 24
+#define MT_ST_DENSITY_MASK 0xff000000
+
+#define MT_ST_SOFTERR_SHIFT 0
+#define MT_ST_SOFTERR_MASK 0xffff
+
+/* Bitfields for the MTSETDRVBUFFER ioctl. */
+#define MT_ST_OPTIONS 0xf0000000
+#define MT_ST_BOOLEANS 0x10000000
+#define MT_ST_SETBOOLEANS 0x30000000
+#define MT_ST_CLEARBOOLEANS 0x40000000
+#define MT_ST_WRITE_THRESHOLD 0x20000000
+#define MT_ST_DEF_BLKSIZE 0x50000000
+#define MT_ST_DEF_OPTIONS 0x60000000
+
+#define MT_ST_BUFFER_WRITES 0x1
+#define MT_ST_ASYNC_WRITES 0x2
+#define MT_ST_READ_AHEAD 0x4
+#define MT_ST_DEBUGGING 0x8
+#define MT_ST_TWO_FM 0x10
+#define MT_ST_FAST_MTEOM 0x20
+#define MT_ST_AUTO_LOCK 0x40
+#define MT_ST_DEF_WRITES 0x80
+#define MT_ST_CAN_BSR 0x100
+#define MT_ST_NO_BLKLIMS 0x200
+#define MT_ST_CAN_PARTITIONS 0x400
+#define MT_ST_SCSI2LOGICAL 0x800
+
+/* The mode parameters to be controlled. Parameter chosen with bits 20-28. */
+#define MT_ST_CLEAR_DEFAULT 0xfffff
+#define MT_ST_DEF_DENSITY (MT_ST_DEF_OPTIONS | 0x100000)
+#define MT_ST_DEF_COMPRESSION (MT_ST_DEF_OPTIONS | 0x200000)
+#define MT_ST_DEF_DRVBUFFER (MT_ST_DEF_OPTIONS | 0x300000)
+
+/* The offset for the arguments for the special HP changer load command. */
+#define MT_ST_HPLOADER_OFFSET 10000
+
+
+/* Specify default tape device. */
+#ifndef DEFTAPE
+# define DEFTAPE "/dev/tape"
+#endif
+
+#endif /* mtio.h */
diff --git a/libc/sysdeps/gnu/updwtmp.c b/libc/sysdeps/gnu/updwtmp.c
new file mode 100644
index 000000000..e4f63088a
--- /dev/null
+++ b/libc/sysdeps/gnu/updwtmp.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1998, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <unistd.h>
+
+#define TRANSFORM_UTMP_FILE_NAME(file_name) \
+ ((strcmp (file_name, _PATH_UTMP "x") == 0 \
+ && __access (_PATH_UTMP "x", F_OK) != 0) ? _PATH_UTMP : \
+ ((strcmp (file_name, _PATH_WTMP "x") == 0 \
+ && __access (_PATH_WTMP "x", F_OK) != 0) ? _PATH_WTMP : \
+ file_name))
+
+#include <login/updwtmp.c>
diff --git a/libc/sysdeps/gnu/utmp_file.c b/libc/sysdeps/gnu/utmp_file.c
new file mode 100644
index 000000000..5ef6f306c
--- /dev/null
+++ b/libc/sysdeps/gnu/utmp_file.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1998, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <unistd.h>
+
+#define TRANSFORM_UTMP_FILE_NAME(file_name) \
+ ((strcmp (file_name, _PATH_UTMP "x") == 0 \
+ && __access (_PATH_UTMP "x", F_OK) != 0) ? _PATH_UTMP : \
+ ((strcmp (file_name, _PATH_WTMP "x") == 0 \
+ && __access (_PATH_WTMP "x", F_OK) != 0) ? _PATH_WTMP : \
+ file_name))
+
+#include <login/utmp_file.c>
diff --git a/libc/sysdeps/gnu/utmpx.h b/libc/sysdeps/gnu/utmpx.h
new file mode 100644
index 000000000..8622916a9
--- /dev/null
+++ b/libc/sysdeps/gnu/utmpx.h
@@ -0,0 +1,127 @@
+/* Copyright (C) 1997, 1998, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _UTMPX_H
+#define _UTMPX_H 1
+
+#include <features.h>
+#include <sys/time.h>
+
+/* Required according to Unix98. */
+#ifndef __pid_t_defined
+typedef __pid_t pid_t;
+# define __pid_t_defined
+#endif
+
+/* Get system dependent values and data structures. */
+#include <bits/utmpx.h>
+
+#ifdef __USE_GNU
+/* Compatibility names for the strings of the canonical file names. */
+# define UTMPX_FILE _PATH_UTMPX
+# define UTMPX_FILENAME _PATH_UTMPX
+# define WTMPX_FILE _PATH_WTMPX
+# define WTMPX_FILENAME _PATH_WTMPX
+#endif
+
+/* For the getutmp{,x} functions we need the `struct utmp'. */
+#ifdef __USE_GNU
+struct utmp;
+#endif
+
+
+__BEGIN_DECLS
+
+/* Open user accounting database.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern void setutxent (void);
+
+/* Close user accounting database.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern void endutxent (void);
+
+/* Get the next entry from the user accounting database.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern struct utmpx *getutxent (void);
+
+/* Get the user accounting database entry corresponding to ID.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern struct utmpx *getutxid (__const struct utmpx *__id);
+
+/* Get the user accounting database entry corresponding to LINE.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern struct utmpx *getutxline (__const struct utmpx *__line);
+
+/* Write the entry UTMPX into the user accounting database.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern struct utmpx *pututxline (__const struct utmpx *__utmpx);
+
+
+#ifdef __USE_GNU
+/* Change name of the utmpx file to be examined.
+
+ This function is not part of POSIX and therefore no official
+ cancellation point. But due to similarity with an POSIX interface
+ or due to the implementation it is a cancellation point and
+ therefore not marked with __THROW. */
+extern int utmpxname (__const char *__file);
+
+/* Append entry UTMP to the wtmpx-like file WTMPX_FILE.
+
+ This function is not part of POSIX and therefore no official
+ cancellation point. But due to similarity with an POSIX interface
+ or due to the implementation it is a cancellation point and
+ therefore not marked with __THROW. */
+extern void updwtmpx (__const char *__wtmpx_file,
+ __const struct utmpx *__utmpx);
+
+
+/* Copy the information in UTMPX to UTMP.
+
+ This function is not part of POSIX and therefore no official
+ cancellation point. But due to similarity with an POSIX interface
+ or due to the implementation it is a cancellation point and
+ therefore not marked with __THROW. */
+extern void getutmp (__const struct utmpx *__utmpx,
+ struct utmp *__utmp);
+
+/* Copy the information in UTMP to UTMPX.
+
+ This function is not part of POSIX and therefore no official
+ cancellation point. But due to similarity with an POSIX interface
+ or due to the implementation it is a cancellation point and
+ therefore not marked with __THROW. */
+extern void getutmpx (__const struct utmp *__utmp,
+ struct utmpx *__utmpx);
+#endif
+
+__END_DECLS
+
+#endif /* utmpx.h */
diff --git a/libc/sysdeps/i386/Implies b/libc/sysdeps/i386/Implies
new file mode 100644
index 000000000..3a32442d6
--- /dev/null
+++ b/libc/sysdeps/i386/Implies
@@ -0,0 +1,4 @@
+wordsize-32
+ieee754/ldbl-96
+ieee754/dbl-64
+ieee754/flt-32
diff --git a/libc/sysdeps/i386/Makefile b/libc/sysdeps/i386/Makefile
new file mode 100644
index 000000000..ddd3d04e0
--- /dev/null
+++ b/libc/sysdeps/i386/Makefile
@@ -0,0 +1,67 @@
+# The mpn functions need a #define for asm syntax flavor.
+# Every i386 port in use uses gas syntax (I think).
+asm-CPPFLAGS += -DGAS_SYNTAX
+
+# The i386 `long double' is a distinct type we support.
+long-double-fcts = yes
+
+ifeq ($(subdir),csu)
+# On i686 we must avoid generating the trampoline functions generated
+# to get the GOT pointer.
+CFLAGS-initfini.s += -march=i386 -mtune=i386
+endif
+
+ifeq ($(subdir),gmon)
+sysdep_routines += i386-mcount
+endif
+
+ifeq ($(subdir),elf)
+CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused
+CFLAGS-dl-load.c += -Wno-unused
+CFLAGS-dl-reloc.c += -Wno-unused
+endif
+
+ifeq ($(subdir),debug)
+CFLAGS-backtrace.c += -fexceptions
+endif
+
+# Most of the glibc routines don't ever call user defined callbacks
+# nor use any FPU or SSE* and as such don't need bigger %esp alignment
+# than 4 bytes.
+# Lots of routines in math will use FPU, so make math subdir an exception
+# here.
+ifeq ($(subdir),math)
+sysdep-CFLAGS += -mpreferred-stack-boundary=4
+else
+ifeq ($(subdir),csu)
+sysdep-CFLAGS += -mpreferred-stack-boundary=4
+else
+sysdep-CFLAGS += -mpreferred-stack-boundary=2
+# Likewise, any function which calls user callbacks
+uses-callbacks += -mpreferred-stack-boundary=4
+# Likewise, any stack alignment tests
+stack-align-test-flags += -malign-double -mpreferred-stack-boundary=4
+endif
+endif
+
+# And a couple of other routines
+ifeq ($(subdir),stdlib)
+CFLAGS-exit.c += -mpreferred-stack-boundary=4
+endif
+ifeq ($(subdir),elf)
+CFLAGS-dl-init.c += -mpreferred-stack-boundary=4
+CFLAGS-dl-fini.c += -mpreferred-stack-boundary=4
+CFLAGS-dl-open.c += -mpreferred-stack-boundary=4
+CFLAGS-dl-close.c += -mpreferred-stack-boundary=4
+CFLAGS-dl-error.c += -mpreferred-stack-boundary=4
+endif
+ifeq ($(subdir),dlfcn)
+CFLAGS-dlopen.c += -mpreferred-stack-boundary=4
+CFLAGS-dlopenold.c += -mpreferred-stack-boundary=4
+CFLAGS-dlclose.c += -mpreferred-stack-boundary=4
+CFLAGS-dlerror.c += -mpreferred-stack-boundary=4
+endif
+
+ifneq (,$(filter -mno-tls-direct-seg-refs,$(CFLAGS)))
+defines += -DNO_TLS_DIRECT_SEG_REFS
+endif
diff --git a/libc/sysdeps/i386/Versions b/libc/sysdeps/i386/Versions
new file mode 100644
index 000000000..b0230d31c
--- /dev/null
+++ b/libc/sysdeps/i386/Versions
@@ -0,0 +1,29 @@
+libc {
+ GLIBC_2.0 {
+ # Functions from libgcc.
+ __divdi3; __moddi3; __udivdi3; __umoddi3;
+ }
+ GLIBC_2.1 {
+ # global variable
+ _fp_hw;
+ }
+ GLIBC_2.1.1 {
+ # extern inline functions used by <bits/string.h>
+ __memcpy_c; __memset_cc; __memset_cg; __memset_gg;
+ __memcpy_by2; __memcpy_by4; __memcpy_g; __mempcpy_by2; __mempcpy_by4;
+ __mempcpy_byn; __memset_ccn_by2; __memset_ccn_by4; __memset_gcn_by2;
+ __memset_gcn_by4; __stpcpy_g; __strcat_c; __strcat_g; __strchr_c;
+ __strchr_g; __strchrnul_c; __strchrnul_g; __strcmp_gg; __strcpy_g;
+ __strcspn_c1; __strcspn_cg; __strcspn_g; __strlen_g; __strncat_g;
+ __strncmp_g; __strncpy_by2; __strncpy_by4; __strncpy_byn; __strncpy_gg;
+ __strpbrk_cg; __strpbrk_g; __strrchr_c; __strrchr_g; __strspn_c1;
+ __strspn_cg; __strspn_g; __strstr_cg; __strstr_g;
+ }
+}
+libm {
+ GLIBC_2.1 {
+ # A generic bug got this omitted from other configurations' version
+ # sets, but we always had it.
+ exp2l;
+ }
+}
diff --git a/libc/sysdeps/i386/__longjmp.S b/libc/sysdeps/i386/__longjmp.S
new file mode 100644
index 000000000..559d56b25
--- /dev/null
+++ b/libc/sysdeps/i386/__longjmp.S
@@ -0,0 +1,78 @@
+/* longjmp for i386.
+ Copyright (C) 1995-1998,2000,2002,2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+#include <asm-syntax.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define JBUF PARMS
+#define VAL JBUF+PTR_SIZE
+
+ENTRY (BP_SYM (__longjmp))
+ ENTER
+
+#ifdef PTR_DEMANGLE
+ movl JBUF(%esp), %eax /* User's jmp_buf in %eax. */
+ CHECK_BOUNDS_BOTH_WIDE (%eax, JBUF(%esp), $JB_SIZE)
+
+ /* Save the return address now. */
+ movl (JB_PC*4)(%eax), %edx
+ /* Get the stack pointer. */
+ movl (JB_SP*4)(%eax), %ecx
+ PTR_DEMANGLE (%edx)
+ PTR_DEMANGLE (%ecx)
+ cfi_def_cfa(%eax, 0)
+ cfi_register(%eip, %edx)
+ cfi_register(%esp, %ecx)
+ cfi_offset(%ebx, JB_BX*4)
+ cfi_offset(%esi, JB_SI*4)
+ cfi_offset(%edi, JB_DI*4)
+ cfi_offset(%ebp, JB_BP*4)
+ /* Restore registers. */
+ movl (JB_BX*4)(%eax), %ebx
+ movl (JB_SI*4)(%eax), %esi
+ movl (JB_DI*4)(%eax), %edi
+ movl (JB_BP*4)(%eax), %ebp
+ cfi_restore(%ebx)
+ cfi_restore(%esi)
+ cfi_restore(%edi)
+ cfi_restore(%ebp)
+
+ movl VAL(%esp), %eax /* Second argument is return value. */
+ movl %ecx, %esp
+#else
+ movl JBUF(%esp), %ecx /* User's jmp_buf in %ecx. */
+ CHECK_BOUNDS_BOTH_WIDE (%ecx, JBUF(%esp), $JB_SIZE)
+
+ movl VAL(%esp), %eax /* Second argument is return value. */
+ /* Save the return address now. */
+ movl (JB_PC*4)(%ecx), %edx
+ /* Restore registers. */
+ movl (JB_BX*4)(%ecx), %ebx
+ movl (JB_SI*4)(%ecx), %esi
+ movl (JB_DI*4)(%ecx), %edi
+ movl (JB_BP*4)(%ecx), %ebp
+ movl (JB_SP*4)(%ecx), %esp
+#endif
+ /* Jump to saved PC. */
+ jmp *%edx
+END (BP_SYM (__longjmp))
diff --git a/libc/sysdeps/i386/abort-instr.h b/libc/sysdeps/i386/abort-instr.h
new file mode 100644
index 000000000..810f10379
--- /dev/null
+++ b/libc/sysdeps/i386/abort-instr.h
@@ -0,0 +1,2 @@
+/* An instruction which should crash any program is `hlt'. */
+#define ABORT_INSTRUCTION asm ("hlt")
diff --git a/libc/sysdeps/i386/add_n.S b/libc/sysdeps/i386/add_n.S
new file mode 100644
index 000000000..c7a5ce721
--- /dev/null
+++ b/libc/sysdeps/i386/add_n.S
@@ -0,0 +1,123 @@
+/* Add two limb vectors of the same length > 0 and store sum in a third
+ limb vector.
+ Copyright (C) 1992,94,95,97,98,2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+8 /* space for 2 saved regs */
+#define RES PARMS
+#define S1 RES+PTR_SIZE
+#define S2 S1+PTR_SIZE
+#define SIZE S2+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__mpn_add_n))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp),%edi
+ cfi_rel_offset (edi, 4)
+ movl S1(%esp),%esi
+ cfi_rel_offset (esi, 0)
+ movl S2(%esp),%edx
+ movl SIZE(%esp),%ecx
+#if __BOUNDED_POINTERS__
+ shll $2, %ecx /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, S1(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%edx, S2(%esp), %ecx)
+ shrl $2, %ecx
+#endif
+ movl %ecx,%eax
+ shrl $3,%ecx /* compute count for unrolled loop */
+ negl %eax
+ andl $7,%eax /* get index where to start loop */
+ jz L(oop) /* necessary special case for 0 */
+ incl %ecx /* adjust loop count */
+ shll $2,%eax /* adjustment for pointers... */
+ subl %eax,%edi /* ... since they are offset ... */
+ subl %eax,%esi /* ... by a constant when we ... */
+ subl %eax,%edx /* ... enter the loop */
+ shrl $2,%eax /* restore previous value */
+#ifdef PIC
+/* Calculate start address in loop for PIC. Due to limitations in some
+ assemblers, Loop-L0-3 cannot be put into the leal */
+ call L(0)
+ cfi_adjust_cfa_offset (4)
+L(0): leal (%eax,%eax,8),%eax
+ addl (%esp),%eax
+ addl $(L(oop)-L(0)-3),%eax
+ addl $4,%esp
+ cfi_adjust_cfa_offset (-4)
+#else
+/* Calculate start address in loop for non-PIC. */
+ leal (L(oop) - 3)(%eax,%eax,8),%eax
+#endif
+ jmp *%eax /* jump into loop */
+ ALIGN (3)
+L(oop): movl (%esi),%eax
+ adcl (%edx),%eax
+ movl %eax,(%edi)
+ movl 4(%esi),%eax
+ adcl 4(%edx),%eax
+ movl %eax,4(%edi)
+ movl 8(%esi),%eax
+ adcl 8(%edx),%eax
+ movl %eax,8(%edi)
+ movl 12(%esi),%eax
+ adcl 12(%edx),%eax
+ movl %eax,12(%edi)
+ movl 16(%esi),%eax
+ adcl 16(%edx),%eax
+ movl %eax,16(%edi)
+ movl 20(%esi),%eax
+ adcl 20(%edx),%eax
+ movl %eax,20(%edi)
+ movl 24(%esi),%eax
+ adcl 24(%edx),%eax
+ movl %eax,24(%edi)
+ movl 28(%esi),%eax
+ adcl 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz L(oop)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+END (BP_SYM (__mpn_add_n))
diff --git a/libc/sysdeps/i386/addmul_1.S b/libc/sysdeps/i386/addmul_1.S
new file mode 100644
index 000000000..df501726c
--- /dev/null
+++ b/libc/sysdeps/i386/addmul_1.S
@@ -0,0 +1,97 @@
+/* i80386 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ the result to a second limb vector.
+ Copyright (C) 1992,1994,1997,1998,2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+16 /* space for 4 saved regs */
+#define RES PARMS
+#define S1 RES+PTR_SIZE
+#define SIZE S1+PTR_SIZE
+#define S2LIMB SIZE+4
+
+#define res_ptr edi
+#define s1_ptr esi
+#define sizeP ecx
+#define s2_limb ebx
+
+ .text
+ENTRY (BP_SYM (__mpn_addmul_1))
+ ENTER
+
+ pushl %res_ptr
+ cfi_adjust_cfa_offset (4)
+ pushl %s1_ptr
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %s2_limb
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp), %res_ptr
+ cfi_rel_offset (res_ptr, 12)
+ movl S1(%esp), %s1_ptr
+ cfi_rel_offset (s1_ptr, 8)
+ movl SIZE(%esp), %sizeP
+ movl S2LIMB(%esp), %s2_limb
+ cfi_rel_offset (s2_limb, 0)
+#if __BOUNDED_POINTERS__
+ shll $2, %sizeP /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%res_ptr, RES(%esp), %sizeP)
+ CHECK_BOUNDS_BOTH_WIDE (%s1_ptr, S1(%esp), %sizeP)
+ shrl $2, %sizeP
+#endif
+ leal (%res_ptr,%sizeP,4), %res_ptr
+ leal (%s1_ptr,%sizeP,4), %s1_ptr
+ negl %sizeP
+ xorl %ebp, %ebp
+ cfi_rel_offset (ebp, 4)
+ ALIGN (3)
+L(oop):
+ movl (%s1_ptr,%sizeP,4), %eax
+ mull %s2_limb
+ addl %ebp, %eax
+ adcl $0, %edx
+ addl %eax, (%res_ptr,%sizeP,4)
+ adcl $0, %edx
+ movl %edx, %ebp
+
+ incl %sizeP
+ jnz L(oop)
+ movl %ebp, %eax
+
+ popl %s2_limb
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (s2_limb)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %s1_ptr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (s1_ptr)
+ popl %res_ptr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (res_ptr)
+
+ LEAVE
+ ret
+END (BP_SYM (__mpn_addmul_1))
diff --git a/libc/sysdeps/i386/asm-syntax.h b/libc/sysdeps/i386/asm-syntax.h
new file mode 100644
index 000000000..e59e63322
--- /dev/null
+++ b/libc/sysdeps/i386/asm-syntax.h
@@ -0,0 +1,41 @@
+/* Definitions for x86 syntax variations.
+ Copyright (C) 1992, 1994, 1995, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library. Its master source is NOT part of
+ the C library, however. The master source lives in the GNU MP Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#undef ALIGN
+#if defined NOLOG_ALIGN || defined HAVE_ELF
+# define ALIGN(log) .align 1<<log
+#else
+# define ALIGN(log) .align log
+#endif
+
+#undef L
+#ifdef __ELF__
+# ifdef __STDC__
+# define L(body) .L##body
+# else
+# define L(body) .L/**/body
+# endif
+#else
+# ifdef __STDC__
+# define L(body) L##body
+# else
+# define L(body) L/**/body
+# endif
+#endif
diff --git a/libc/sysdeps/i386/backtrace.c b/libc/sysdeps/i386/backtrace.c
new file mode 100644
index 000000000..8b61913dd
--- /dev/null
+++ b/libc/sysdeps/i386/backtrace.c
@@ -0,0 +1,144 @@
+/* Return backtrace of current program state.
+ Copyright (C) 1998, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <bits/libc-lock.h>
+#include <dlfcn.h>
+#include <execinfo.h>
+#include <stdlib.h>
+#include <unwind.h>
+
+struct trace_arg
+{
+ void **array;
+ int cnt, size;
+ void *lastebp, *lastesp;
+};
+
+#ifdef SHARED
+static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
+static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *);
+static _Unwind_Ptr (*unwind_getcfa) (struct _Unwind_Context *);
+static _Unwind_Ptr (*unwind_getgr) (struct _Unwind_Context *, int);
+
+static void
+init (void)
+{
+ void *handle = __libc_dlopen ("libgcc_s.so.1");
+
+ if (handle == NULL)
+ return;
+
+ unwind_backtrace = __libc_dlsym (handle, "_Unwind_Backtrace");
+ unwind_getip = __libc_dlsym (handle, "_Unwind_GetIP");
+ unwind_getcfa = __libc_dlsym (handle, "_Unwind_GetCFA");
+ unwind_getgr = __libc_dlsym (handle, "_Unwind_GetGR");
+ if (unwind_getip == NULL || unwind_getgr == NULL || unwind_getcfa == NULL)
+ unwind_backtrace = NULL;
+}
+#else
+# define unwind_backtrace _Unwind_Backtrace
+# define unwind_getip _Unwind_GetIP
+# define unwind_getcfa _Unwind_GetCFA
+# define unwind_getgr _Unwind_GetGR
+#endif
+
+static _Unwind_Reason_Code
+backtrace_helper (struct _Unwind_Context *ctx, void *a)
+{
+ struct trace_arg *arg = a;
+
+ /* We are first called with address in the __backtrace function.
+ Skip it. */
+ if (arg->cnt != -1)
+ arg->array[arg->cnt] = (void *) unwind_getip (ctx);
+ if (++arg->cnt == arg->size)
+ return _URC_END_OF_STACK;
+
+ /* %ebp is DWARF2 register 5 on IA-32. */
+ arg->lastebp = (void *) unwind_getgr (ctx, 5);
+ arg->lastesp = (void *) unwind_getcfa (ctx);
+ return _URC_NO_REASON;
+}
+
+
+/* This is a global variable set at program start time. It marks the
+ highest used stack address. */
+extern void *__libc_stack_end;
+
+
+/* This is the stack layout we see with every stack frame
+ if not compiled without frame pointer.
+
+ +-----------------+ +-----------------+
+ %ebp -> | %ebp last frame--------> | %ebp last frame--->...
+ | | | |
+ | return address | | return address |
+ +-----------------+ +-----------------+
+
+ First try as far to get as far as possible using
+ _Unwind_Backtrace which handles -fomit-frame-pointer
+ as well, but requires .eh_frame info. Then fall back to
+ walking the stack manually. */
+
+struct layout
+{
+ struct layout *ebp;
+ void *ret;
+};
+
+
+int
+__backtrace (array, size)
+ void **array;
+ int size;
+{
+ struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
+#ifdef SHARED
+ __libc_once_define (static, once);
+
+ __libc_once (once, init);
+ if (unwind_backtrace == NULL)
+ return 0;
+#endif
+
+ if (size >= 1)
+ unwind_backtrace (backtrace_helper, &arg);
+
+ if (arg.cnt > 1 && arg.array[arg.cnt - 1] == NULL)
+ --arg.cnt;
+ else if (arg.cnt < size)
+ {
+ struct layout *ebp = (struct layout *) arg.lastebp;
+
+ while (arg.cnt < size)
+ {
+ /* Check for out of range. */
+ if ((void *) ebp < arg.lastesp || (void *) ebp > __libc_stack_end
+ || ((long) ebp & 3))
+ break;
+
+ array[arg.cnt++] = ebp->ret;
+ ebp = ebp->ebp;
+ }
+ }
+ return arg.cnt != -1 ? arg.cnt : 0;
+}
+weak_alias (__backtrace, backtrace)
+libc_hidden_def (__backtrace)
diff --git a/libc/sysdeps/i386/bits/byteswap.h b/libc/sysdeps/i386/bits/byteswap.h
new file mode 100644
index 000000000..33af20888
--- /dev/null
+++ b/libc/sysdeps/i386/bits/byteswap.h
@@ -0,0 +1,133 @@
+/* Macros to swap the order of bytes in integer values.
+ Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
+# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
+#endif
+
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H 1
+
+/* Swap bytes in 16 bit value. */
+#define __bswap_constant_16(x) \
+ ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+
+#ifdef __GNUC__
+# if __GNUC__ >= 2
+# define __bswap_16(x) \
+ (__extension__ \
+ ({ register unsigned short int __v, __x = (x); \
+ if (__builtin_constant_p (__x)) \
+ __v = __bswap_constant_16 (__x); \
+ else \
+ __asm__ ("rorw $8, %w0" \
+ : "=r" (__v) \
+ : "0" (__x) \
+ : "cc"); \
+ __v; }))
+# else
+/* This is better than nothing. */
+# define __bswap_16(x) \
+ (__extension__ \
+ ({ register unsigned short int __x = (x); __bswap_constant_16 (__x); }))
+# endif
+#else
+static __inline unsigned short int
+__bswap_16 (unsigned short int __bsx)
+{
+ return __bswap_constant_16 (__bsx);
+}
+#endif
+
+/* Swap bytes in 32 bit value. */
+#define __bswap_constant_32(x) \
+ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
+ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+
+#ifdef __GNUC__
+# if __GNUC__ >= 2
+/* To swap the bytes in a word the i486 processors and up provide the
+ `bswap' opcode. On i386 we have to use three instructions. */
+# if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ \
+ && !defined __pentium4__
+# define __bswap_32(x) \
+ (__extension__ \
+ ({ register unsigned int __v, __x = (x); \
+ if (__builtin_constant_p (__x)) \
+ __v = __bswap_constant_32 (__x); \
+ else \
+ __asm__ ("rorw $8, %w0;" \
+ "rorl $16, %0;" \
+ "rorw $8, %w0" \
+ : "=r" (__v) \
+ : "0" (__x) \
+ : "cc"); \
+ __v; }))
+# else
+# define __bswap_32(x) \
+ (__extension__ \
+ ({ register unsigned int __v, __x = (x); \
+ if (__builtin_constant_p (__x)) \
+ __v = __bswap_constant_32 (__x); \
+ else \
+ __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \
+ __v; }))
+# endif
+# else
+# define __bswap_32(x) \
+ (__extension__ \
+ ({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
+# endif
+#else
+static __inline unsigned int
+__bswap_32 (unsigned int __bsx)
+{
+ return __bswap_constant_32 (__bsx);
+}
+#endif
+
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* Swap bytes in 64 bit value. */
+#define __bswap_constant_64(x) \
+ ((((x) & 0xff00000000000000ull) >> 56) \
+ | (((x) & 0x00ff000000000000ull) >> 40) \
+ | (((x) & 0x0000ff0000000000ull) >> 24) \
+ | (((x) & 0x000000ff00000000ull) >> 8) \
+ | (((x) & 0x00000000ff000000ull) << 8) \
+ | (((x) & 0x0000000000ff0000ull) << 24) \
+ | (((x) & 0x000000000000ff00ull) << 40) \
+ | (((x) & 0x00000000000000ffull) << 56))
+
+# define __bswap_64(x) \
+ (__extension__ \
+ ({ union { __extension__ unsigned long long int __ll; \
+ unsigned long int __l[2]; } __w, __r; \
+ if (__builtin_constant_p (x)) \
+ __r.__ll = __bswap_constant_64 (x); \
+ else \
+ { \
+ __w.__ll = (x); \
+ __r.__l[0] = __bswap_32 (__w.__l[1]); \
+ __r.__l[1] = __bswap_32 (__w.__l[0]); \
+ } \
+ __r.__ll; }))
+#endif
+
+#endif /* _BITS_BYTESWAP_H */
diff --git a/libc/sysdeps/i386/bits/endian.h b/libc/sysdeps/i386/bits/endian.h
new file mode 100644
index 000000000..54bd9d14b
--- /dev/null
+++ b/libc/sysdeps/i386/bits/endian.h
@@ -0,0 +1,7 @@
+/* i386 is little-endian. */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
diff --git a/libc/sysdeps/i386/bits/huge_vall.h b/libc/sysdeps/i386/bits/huge_vall.h
new file mode 100644
index 000000000..0678c7cd3
--- /dev/null
+++ b/libc/sysdeps/i386/bits/huge_vall.h
@@ -0,0 +1,43 @@
+/* `HUGE_VALL' constant for ix86 (where it is infinity).
+ Used by <stdlib.h> and <math.h> functions for overflow.
+ Copyright (C) 1992, 1995, 1996, 1997, 1999, 2000, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/huge_vall.h> directly; include <math.h> instead."
+#endif
+
+#if __GNUC_PREREQ(3,3)
+# define HUGE_VALL (__builtin_huge_vall())
+#elif __GNUC_PREREQ(2,96)
+# define HUGE_VALL (__extension__ 0x1.0p32767L)
+#else
+
+# define __HUGE_VALL_bytes { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0x7f, 0, 0 }
+
+# define __huge_vall_t union { unsigned char __c[12]; long double __ld; }
+# ifdef __GNUC__
+# define HUGE_VALL (__extension__ \
+ ((__huge_vall_t) { __c: __HUGE_VALL_bytes }).__ld)
+# else /* Not GCC. */
+static __huge_vall_t __huge_vall = { __HUGE_VALL_bytes };
+# define HUGE_VALL (__huge_vall.__ld)
+# endif /* GCC. */
+
+#endif /* GCC 2.95 */
diff --git a/libc/sysdeps/i386/bits/link.h b/libc/sysdeps/i386/bits/link.h
new file mode 100644
index 000000000..985d04041
--- /dev/null
+++ b/libc/sysdeps/i386/bits/link.h
@@ -0,0 +1,60 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+
+/* Registers for entry into PLT on IA-32. */
+typedef struct La_i86_regs
+{
+ uint32_t lr_edx;
+ uint32_t lr_ecx;
+ uint32_t lr_eax;
+ uint32_t lr_ebp;
+ uint32_t lr_esp;
+} La_i86_regs;
+
+/* Return values for calls from PLT on IA-32. */
+typedef struct La_i86_retval
+{
+ uint32_t lrv_eax;
+ uint32_t lrv_edx;
+ long double lrv_st0;
+ long double lrv_st1;
+} La_i86_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf32_Addr la_i86_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_i86_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_i86_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_i86_regs *__inregs,
+ La_i86_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
diff --git a/libc/sysdeps/i386/bits/linkmap.h b/libc/sysdeps/i386/bits/linkmap.h
new file mode 100644
index 000000000..3be9b7eae
--- /dev/null
+++ b/libc/sysdeps/i386/bits/linkmap.h
@@ -0,0 +1,5 @@
+struct link_map_machine
+ {
+ Elf32_Addr plt; /* Address of .plt + 0x16 */
+ Elf32_Addr gotplt; /* Address of .got + 0x0c */
+ };
diff --git a/libc/sysdeps/i386/bits/mathdef.h b/libc/sysdeps/i386/bits/mathdef.h
new file mode 100644
index 000000000..ec42ed5df
--- /dev/null
+++ b/libc/sysdeps/i386/bits/mathdef.h
@@ -0,0 +1,46 @@
+/* Copyright (C) 1997, 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
+# if defined __FLT_EVAL_METHOD__ && __FLT_EVAL_METHOD__ == 0
+/* When using -mfpmath=sse, values are computed with the precission of the
+ used type. */
+typedef float float_t; /* `float' expressions are evaluated as `float'. */
+typedef double double_t; /* `double' expressions are evaluated as
+ `double'. */
+# else
+/* The ix87 FPUs evaluate all values in the 80 bit floating-point format
+ which is also available for the user as `long double'. Therefore we
+ define: */
+typedef long double float_t; /* `float' expressions are evaluated as
+ `long double'. */
+typedef long double double_t; /* `double' expressions are evaluated as
+ `long double'. */
+# endif
+
+/* The values returned by `ilogb' for 0 and NaN respectively. */
+# define FP_ILOGB0 (-2147483647 - 1)
+# define FP_ILOGBNAN (-2147483647 - 1)
+
+#endif /* ISO C99 */
diff --git a/libc/sysdeps/i386/bits/select.h b/libc/sysdeps/i386/bits/select.h
new file mode 100644
index 000000000..972bfb685
--- /dev/null
+++ b/libc/sysdeps/i386/bits/select.h
@@ -0,0 +1,72 @@
+/* Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SELECT_H
+# error "Never use <bits/select.h> directly; include <sys/select.h> instead."
+#endif
+
+
+#if defined __GNUC__ && __GNUC__ >= 2
+
+# define __FD_ZERO(fdsp) \
+ do { \
+ int __d0, __d1; \
+ __asm__ __volatile__ ("cld; rep; stosl" \
+ : "=c" (__d0), "=D" (__d1) \
+ : "a" (0), "0" (sizeof (fd_set) \
+ / sizeof (__fd_mask)), \
+ "1" (&__FDS_BITS (fdsp)[0]) \
+ : "memory"); \
+ } while (0)
+
+# define __FD_SET(fd, fdsp) \
+ __asm__ __volatile__ ("btsl %1,%0" \
+ : "=m" (__FDS_BITS (fdsp)[__FDELT (fd)]) \
+ : "r" (((int) (fd)) % __NFDBITS) \
+ : "cc","memory")
+# define __FD_CLR(fd, fdsp) \
+ __asm__ __volatile__ ("btrl %1,%0" \
+ : "=m" (__FDS_BITS (fdsp)[__FDELT (fd)]) \
+ : "r" (((int) (fd)) % __NFDBITS) \
+ : "cc","memory")
+# define __FD_ISSET(fd, fdsp) \
+ (__extension__ \
+ ({register char __result; \
+ __asm__ __volatile__ ("btl %1,%2 ; setcb %b0" \
+ : "=q" (__result) \
+ : "r" (((int) (fd)) % __NFDBITS), \
+ "m" (__FDS_BITS (fdsp)[__FDELT (fd)]) \
+ : "cc"); \
+ __result; }))
+
+#else /* ! GNU CC */
+
+/* We don't use `memset' because this would require a prototype and
+ the array isn't too big. */
+# define __FD_ZERO(set) \
+ do { \
+ unsigned int __i; \
+ fd_set *__arr = (set); \
+ for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \
+ __FDS_BITS (__arr)[__i] = 0; \
+ } while (0)
+# define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d))
+# define __FD_CLR(d, set) (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d))
+# define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d))
+
+#endif /* GNU CC */
diff --git a/libc/sysdeps/i386/bits/setjmp.h b/libc/sysdeps/i386/bits/setjmp.h
new file mode 100644
index 000000000..0133c40e7
--- /dev/null
+++ b/libc/sysdeps/i386/bits/setjmp.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 1997,1998,2000,2001,2003,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Define the machine-dependent type `jmp_buf'. Intel 386 version. */
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H 1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#ifndef _ASM
+typedef int __jmp_buf[6];
+#endif
+
+#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/i386/bp-asm.h b/libc/sysdeps/i386/bp-asm.h
new file mode 100644
index 000000000..34d5227a6
--- /dev/null
+++ b/libc/sysdeps/i386/bp-asm.h
@@ -0,0 +1,144 @@
+/* Bounded-pointer definitions for x86 assembler.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Greg McGary <greg@mcgary.org>
+ This file is part of the GNU C Library. Its master source is NOT part of
+ the C library, however. The master source lives in the GNU MP Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _bp_asm_h_
+# define _bp_asm_h_ 1
+
+# if __ASSEMBLER__
+
+# if __BOUNDED_POINTERS__
+
+/* Bounded pointers occupy three words. */
+# define PTR_SIZE 12
+/* Bounded pointer return values are passed back through a hidden
+ argument that points to caller-allocate space. The hidden arg
+ occupies one word on the stack. */
+# define RTN_SIZE 4
+/* Although the caller pushes the hidden arg, the callee is
+ responsible for popping it. */
+# define RET_PTR ret $RTN_SIZE
+/* Maintain frame pointer chain in leaf assembler functions for the benefit
+ of debugging stack traces when bounds violations occur. */
+# define ENTER pushl %ebp; movl %esp, %ebp
+# define LEAVE movl %ebp, %esp; popl %ebp
+/* Stack space overhead of procedure-call linkage: return address and
+ frame pointer. */
+# define LINKAGE 8
+/* Stack offset of return address after calling ENTER. */
+# define PCOFF 4
+
+/* Int 5 is the "bound range" exception also raised by the "bound"
+ instruction. */
+# define BOUNDS_VIOLATED int $5
+
+# define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM) \
+ cmpl 4+BP_MEM, VAL_REG; \
+ jae 0f; /* continue if value >= low */ \
+ BOUNDS_VIOLATED; \
+ 0:
+
+# define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc) \
+ cmpl 8+BP_MEM, VAL_REG; \
+ Jcc 0f; /* continue if value < high */ \
+ BOUNDS_VIOLATED; \
+ 0:
+
+# define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM) \
+ cmpl 4+BP_MEM, VAL_REG; \
+ jb 1f; /* die if value < low */ \
+ cmpl 8+BP_MEM, VAL_REG; \
+ jb 0f; /* continue if value < high */ \
+ 1: BOUNDS_VIOLATED; \
+ 0:
+
+# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH) \
+ CHECK_BOUNDS_LOW(VAL_REG, BP_MEM); \
+ addl LENGTH, VAL_REG; \
+ cmpl 8+BP_MEM, VAL_REG; \
+ jbe 0f; /* continue if value <= high */ \
+ BOUNDS_VIOLATED; \
+ 0: subl LENGTH, VAL_REG /* restore value */
+
+/* Take bounds from BP_MEM and affix them to the pointer
+ value in %eax, stuffing all into memory at RTN(%esp).
+ Use %edx as a scratch register. */
+
+# define RETURN_BOUNDED_POINTER(BP_MEM) \
+ movl RTN(%esp), %edx; \
+ movl %eax, 0(%edx); \
+ movl 4+BP_MEM, %eax; \
+ movl %eax, 4(%edx); \
+ movl 8+BP_MEM, %eax; \
+ movl %eax, 8(%edx)
+
+# define RETURN_NULL_BOUNDED_POINTER \
+ movl RTN(%esp), %edx; \
+ movl %eax, 0(%edx); \
+ movl %eax, 4(%edx); \
+ movl %eax, 8(%edx)
+
+/* The caller of __errno_location is responsible for allocating space
+ for the three-word BP return-value and passing pushing its address
+ as an implicit first argument. */
+# define PUSH_ERRNO_LOCATION_RETURN \
+ subl $8, %esp; \
+ subl $4, %esp; \
+ pushl %esp
+
+/* __errno_location is responsible for popping the implicit first
+ argument, but we must pop the space for the BP itself. We also
+ dereference the return value in order to dig out the pointer value. */
+# define POP_ERRNO_LOCATION_RETURN \
+ popl %eax; \
+ addl $8, %esp
+
+# else /* !__BOUNDED_POINTERS__ */
+
+/* Unbounded pointers occupy one word. */
+# define PTR_SIZE 4
+/* Unbounded pointer return values are passed back in the register %eax. */
+# define RTN_SIZE 0
+/* Use simple return instruction for unbounded pointer values. */
+# define RET_PTR ret
+/* Don't maintain frame pointer chain for leaf assembler functions. */
+# define ENTER
+# define LEAVE
+/* Stack space overhead of procedure-call linkage: return address only. */
+# define LINKAGE 4
+/* Stack offset of return address after calling ENTER. */
+# define PCOFF 0
+
+# define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM)
+# define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc)
+# define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM)
+# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH)
+# define RETURN_BOUNDED_POINTER(BP_MEM)
+
+# define RETURN_NULL_BOUNDED_POINTER
+
+# define PUSH_ERRNO_LOCATION_RETURN
+# define POP_ERRNO_LOCATION_RETURN
+
+# endif /* !__BOUNDED_POINTERS__ */
+
+# endif /* __ASSEMBLER__ */
+
+#endif /* _bp_asm_h_ */
diff --git a/libc/sysdeps/i386/bsd-_setjmp.S b/libc/sysdeps/i386/bsd-_setjmp.S
new file mode 100644
index 000000000..ee329ee86
--- /dev/null
+++ b/libc/sysdeps/i386/bsd-_setjmp.S
@@ -0,0 +1,60 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. i386 version.
+ Copyright (C) 1994-1997,2000-2002,2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define JMPBUF PARMS
+#define SIGMSK JMPBUF+PTR_SIZE
+
+ENTRY (BP_SYM (_setjmp))
+ ENTER
+
+ xorl %eax, %eax
+ movl JMPBUF(%esp), %edx
+ CHECK_BOUNDS_BOTH_WIDE (%edx, JMPBUF(%esp), $(JB_SIZE+4))
+
+ /* Save registers. */
+ movl %ebx, (JB_BX*4)(%edx)
+ movl %esi, (JB_SI*4)(%edx)
+ movl %edi, (JB_DI*4)(%edx)
+ leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%ecx)
+#endif
+ movl %ecx, (JB_SP*4)(%edx)
+ movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%ecx)
+#endif
+ movl %ecx, (JB_PC*4)(%edx)
+ LEAVE
+ movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */
+
+ movl %eax, JB_SIZE(%edx) /* No signal mask set. */
+ ret
+END (BP_SYM (_setjmp))
+libc_hidden_def (_setjmp)
diff --git a/libc/sysdeps/i386/bsd-setjmp.S b/libc/sysdeps/i386/bsd-setjmp.S
new file mode 100644
index 000000000..c9af0e147
--- /dev/null
+++ b/libc/sysdeps/i386/bsd-setjmp.S
@@ -0,0 +1,70 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. i386 version.
+ Copyright (C) 1994-1997,2000,2001,2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define JMPBUF PARMS
+#define SIGMSK JMPBUF+PTR_SIZE
+
+ENTRY (BP_SYM (setjmp))
+ /* Note that we have to use a non-exported symbol in the next
+ jump since otherwise gas will emit it as a jump through the
+ PLT which is what we cannot use here. */
+ ENTER
+
+ movl JMPBUF(%esp), %eax
+ CHECK_BOUNDS_BOTH_WIDE (%eax, JMPBUF(%esp), $JB_SIZE)
+
+ /* Save registers. */
+ movl %ebx, (JB_BX*4)(%eax)
+ movl %esi, (JB_SI*4)(%eax)
+ movl %edi, (JB_DI*4)(%eax)
+ leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%ecx)
+#endif
+ movl %ecx, (JB_SP*4)(%eax)
+ movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%ecx)
+#endif
+ movl %ecx, (JB_PC*4)(%eax)
+ LEAVE /* pop frame pointer to prepare for tail-call. */
+ movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */
+
+ /* Call __sigjmp_save. */
+ pushl $1
+ cfi_adjust_cfa_offset (4)
+ pushl 8(%esp)
+ cfi_adjust_cfa_offset (4)
+ call BP_SYM (__sigjmp_save)
+ popl %ecx
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ ret
+END (BP_SYM (setjmp))
diff --git a/libc/sysdeps/i386/bzero.c b/libc/sysdeps/i386/bzero.c
new file mode 100644
index 000000000..a1cfe36ba
--- /dev/null
+++ b/libc/sysdeps/i386/bzero.c
@@ -0,0 +1,83 @@
+/* bzero -- set a block of memory to zero. For Intel 80x86, x>=3.
+ This file is part of the GNU C Library.
+ Copyright (C) 1991,92,93,97,98,99, 05 Free Software Foundation, Inc.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <memcopy.h>
+
+#undef bzero
+#undef __bzero
+
+#ifdef __GNUC__
+
+void
+__bzero (dstpp, len)
+ void *dstpp;
+ size_t len;
+{
+ /* N.B.: This code is almost verbatim from memset.c. */
+ int d0;
+ unsigned long int dstp = (unsigned long int) dstpp;
+
+ /* This explicit register allocation
+ improves code very much indeed. */
+ register op_t x asm ("ax");
+
+ x = 0;
+
+ /* Clear the direction flag, so filling will move forward. */
+ asm volatile ("cld");
+
+ /* This threshold value is optimal. */
+ if (len >= 12)
+ {
+ /* Adjust LEN for the bytes handled in the first loop. */
+ len -= (-dstp) % OPSIZ;
+
+ /* There are at least some bytes to set.
+ No need to test for LEN == 0 in this alignment loop. */
+
+ /* Fill bytes until DSTP is aligned on a longword boundary. */
+ asm volatile ("rep\n"
+ "stosb" /* %0, %2, %3 */ :
+ "=D" (dstp), "=c" (d0) :
+ "0" (dstp), "1" ((-dstp) % OPSIZ), "a" (x) :
+ "memory");
+
+ /* Fill longwords. */
+ asm volatile ("rep\n"
+ "stosl" /* %0, %2, %3 */ :
+ "=D" (dstp), "=c" (d0) :
+ "0" (dstp), "1" (len / OPSIZ), "a" (x) :
+ "memory");
+ len %= OPSIZ;
+ }
+
+ /* Write the last few bytes. */
+ asm volatile ("rep\n"
+ "stosb" /* %0, %2, %3 */ :
+ "=D" (dstp), "=c" (d0) :
+ "0" (dstp), "c" (len), "a" (x) :
+ "memory");
+}
+weak_alias (__bzero, bzero)
+
+#else
+#include <string/bzero.c>
+#endif
diff --git a/libc/sysdeps/i386/configure b/libc/sysdeps/i386/configure
new file mode 100755
index 000000000..d1d4dc15a
--- /dev/null
+++ b/libc/sysdeps/i386/configure
@@ -0,0 +1,54 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/i386.
+
+echo "$as_me:$LINENO: checking if -g produces usable source locations for assembler-with-cpp" >&5
+echo $ECHO_N "checking if -g produces usable source locations for assembler-with-cpp... $ECHO_C" >&6
+if test "${libc_cv_cpp_asm_debuginfo+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.S <<EOF
+#include "confdefs.h"
+
+/* comment on
+ two lines */
+ ${libc_cv_dot_text}
+ ${libc_cv_asm_global_directive} foo
+foo:
+ /* Unfortunately this test only works for a real instruction,
+ not for any of the machine-independent pseudo-ops.
+ So we just have to assume everybody has a "nop". */
+ nop
+ /* comment */
+ nop
+ /* comment */
+ nop
+EOF
+if { ac_try='${CC-cc} $CPPFLAGS $ASFLAGS -g -c conftest.S 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } && {
+ ac_pattern='conftest\.S'
+ { ac_try='readelf --debug-dump=line conftest.o |
+ grep $ac_pattern 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ }; then
+ libc_cv_cpp_asm_debuginfo=yes
+else
+ libc_cv_cpp_asm_debuginfo=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_cpp_asm_debuginfo" >&5
+echo "${ECHO_T}$libc_cv_cpp_asm_debuginfo" >&6
+if test $libc_cv_cpp_asm_debuginfo = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_CPP_ASM_DEBUGINFO 1
+_ACEOF
+
+fi
diff --git a/libc/sysdeps/i386/configure.in b/libc/sysdeps/i386/configure.in
new file mode 100644
index 000000000..028e1ae8e
--- /dev/null
+++ b/libc/sysdeps/i386/configure.in
@@ -0,0 +1,35 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/i386.
+
+AC_CACHE_CHECK(if -g produces usable source locations for assembler-with-cpp,
+ libc_cv_cpp_asm_debuginfo, [dnl
+cat > conftest.S <<EOF
+#include "confdefs.h"
+
+/* comment on
+ two lines */
+ ${libc_cv_dot_text}
+ ${libc_cv_asm_global_directive} foo
+foo:
+ /* Unfortunately this test only works for a real instruction,
+ not for any of the machine-independent pseudo-ops.
+ So we just have to assume everybody has a "nop". */
+ nop
+ /* comment */
+ nop
+ /* comment */
+ nop
+EOF
+if AC_TRY_COMMAND([${CC-cc} $CPPFLAGS $ASFLAGS -g -c conftest.S 1>&AS_MESSAGE_LOG_FD]) && {
+ ac_pattern='conftest\.S'
+ AC_TRY_COMMAND([readelf --debug-dump=line conftest.o |
+ grep $ac_pattern 1>&AS_MESSAGE_LOG_FD])
+ }; then
+ libc_cv_cpp_asm_debuginfo=yes
+else
+ libc_cv_cpp_asm_debuginfo=no
+fi
+rm -f conftest*])AC_SUBST(libc_cv_cpp_asm_debuginfo)
+if test $libc_cv_cpp_asm_debuginfo = yes; then
+ AC_DEFINE(HAVE_CPP_ASM_DEBUGINFO)
+fi
diff --git a/libc/sysdeps/i386/dl-machine.h b/libc/sysdeps/i386/dl-machine.h
new file mode 100644
index 000000000..df3edf546
--- /dev/null
+++ b/libc/sysdeps/i386/dl-machine.h
@@ -0,0 +1,600 @@
+/* Machine-dependent ELF dynamic relocation inline functions. i386 version.
+ Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "i386"
+
+#include <sys/param.h>
+#include <sysdep.h>
+#include <tls.h>
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int __attribute__ ((unused))
+elf_machine_matches_host (const Elf32_Ehdr *ehdr)
+{
+ return ehdr->e_machine == EM_386;
+}
+
+
+#if defined PI_STATIC_AND_HIDDEN \
+ && defined HAVE_VISIBILITY_ATTRIBUTE && defined HAVE_HIDDEN \
+ && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE
+
+/* Return the link-time address of _DYNAMIC. Conveniently, this is the
+ first element of the GOT, a special entry that is never relocated. */
+static inline Elf32_Addr __attribute__ ((unused, const))
+elf_machine_dynamic (void)
+{
+ /* This produces a GOTOFF reloc that resolves to zero at link time, so in
+ fact just loads from the GOT register directly. By doing it without
+ an asm we can let the compiler choose any register. */
+ extern const Elf32_Addr _GLOBAL_OFFSET_TABLE_[] attribute_hidden;
+ return _GLOBAL_OFFSET_TABLE_[0];
+}
+
+/* Return the run-time load address of the shared object. */
+static inline Elf32_Addr __attribute__ ((unused))
+elf_machine_load_address (void)
+{
+ /* Compute the difference between the runtime address of _DYNAMIC as seen
+ by a GOTOFF reference, and the link-time address found in the special
+ unrelocated first GOT entry. */
+ extern Elf32_Dyn bygotoff[] asm ("_DYNAMIC") attribute_hidden;
+ return (Elf32_Addr) &bygotoff - elf_machine_dynamic ();
+}
+
+#else /* Without .hidden support, we can't compile the code above. */
+
+/* Return the link-time address of _DYNAMIC. Conveniently, this is the
+ first element of the GOT. This must be inlined in a function which
+ uses global data. */
+static inline Elf32_Addr __attribute__ ((unused))
+elf_machine_dynamic (void)
+{
+ register Elf32_Addr *got asm ("%ebx");
+ return *got;
+}
+
+
+/* Return the run-time load address of the shared object. */
+static inline Elf32_Addr __attribute__ ((unused))
+elf_machine_load_address (void)
+{
+ /* It doesn't matter what variable this is, the reference never makes
+ it to assembly. We need a dummy reference to some global variable
+ via the GOT to make sure the compiler initialized %ebx in time. */
+ extern int _dl_argc;
+ Elf32_Addr addr;
+ asm ("leal _dl_start@GOTOFF(%%ebx), %0\n"
+ "subl _dl_start@GOT(%%ebx), %0"
+ : "=r" (addr) : "m" (_dl_argc) : "cc");
+ return addr;
+}
+
+#endif
+
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int __attribute__ ((unused, always_inline))
+elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+{
+ Elf32_Addr *got;
+ extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden;
+ extern void _dl_runtime_profile (Elf32_Word) attribute_hidden;
+
+ if (l->l_info[DT_JMPREL] && lazy)
+ {
+ /* The GOT entries for functions in the PLT have not yet been filled
+ in. Their initial contents will arrange when called to push an
+ offset into the .rel.plt section, push _GLOBAL_OFFSET_TABLE_[1],
+ and then jump to _GLOBAL_OFFSET_TABLE[2]. */
+ got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
+ /* If a library is prelinked but we have to relocate anyway,
+ we have to be able to undo the prelinking of .got.plt.
+ The prelinker saved us here address of .plt + 0x16. */
+ if (got[1])
+ {
+ l->l_mach.plt = got[1] + l->l_addr;
+ l->l_mach.gotplt = (Elf32_Addr) &got[3];
+ }
+ got[1] = (Elf32_Addr) l; /* Identify this shared object. */
+
+ /* The got[2] entry contains the address of a function which gets
+ called to get the address of a so far unresolved function and
+ jump to it. The profiling extension of the dynamic linker allows
+ to intercept the calls to collect information. In this case we
+ don't store the address in the GOT so that all future calls also
+ end in this function. */
+ if (__builtin_expect (profile, 0))
+ {
+ got[2] = (Elf32_Addr) &_dl_runtime_profile;
+
+ if (GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), l))
+ /* This is the object we are looking for. Say that we really
+ want profiling and the timers are started. */
+ GL(dl_profile_map) = l;
+ }
+ else
+ /* This function will get called to fix up the GOT entry indicated by
+ the offset on the stack, and then jump to the resolved address. */
+ got[2] = (Elf32_Addr) &_dl_runtime_resolve;
+ }
+
+ return lazy;
+}
+
+#ifdef IN_DL_RUNTIME
+
+# if !defined PROF && !__BOUNDED_POINTERS__
+/* We add a declaration of this function here so that in dl-runtime.c
+ the ELF_MACHINE_RUNTIME_TRAMPOLINE macro really can pass the parameters
+ in registers.
+
+ We cannot use this scheme for profiling because the _mcount call
+ destroys the passed register information. */
+/* GKM FIXME: Fix trampoline to pass bounds so we can do
+ without the `__unbounded' qualifier. */
+#define ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), stdcall, unused))
+
+extern ElfW(Addr) _dl_fixup (struct link_map *__unbounded l,
+ ElfW(Word) reloc_offset)
+ ARCH_FIXUP_ATTRIBUTE;
+extern ElfW(Addr) _dl_profile_fixup (struct link_map *l,
+ ElfW(Word) reloc_offset,
+ ElfW(Addr) retaddr, void *regs,
+ long int *framesizep)
+ ARCH_FIXUP_ATTRIBUTE;
+# endif
+
+#endif
+
+/* Mask identifying addresses reserved for the user program,
+ where the dynamic linker should not map anything. */
+#define ELF_MACHINE_USER_ADDRESS_MASK 0xf8000000UL
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+
+#define RTLD_START asm ("\n\
+ .text\n\
+ .align 16\n\
+0: movl (%esp), %ebx\n\
+ ret\n\
+ .align 16\n\
+.globl _start\n\
+.globl _dl_start_user\n\
+_start:\n\
+ # Note that _dl_start gets the parameter in %eax.\n\
+ movl %esp, %eax\n\
+ call _dl_start\n\
+_dl_start_user:\n\
+ # Save the user entry point address in %edi.\n\
+ movl %eax, %edi\n\
+ # Point %ebx at the GOT.\n\
+ call 0b\n\
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx\n\
+ # See if we were run as a command with the executable file\n\
+ # name as an extra leading argument.\n\
+ movl _dl_skip_args@GOTOFF(%ebx), %eax\n\
+ # Pop the original argument count.\n\
+ popl %edx\n\
+ # Adjust the stack pointer to skip _dl_skip_args words.\n\
+ leal (%esp,%eax,4), %esp\n\
+ # Subtract _dl_skip_args from argc.\n\
+ subl %eax, %edx\n\
+ # Push argc back on the stack.\n\
+ push %edx\n\
+ # The special initializer gets called with the stack just\n\
+ # as the application's entry point will see it; it can\n\
+ # switch stacks if it moves these contents over.\n\
+" RTLD_START_SPECIAL_INIT "\n\
+ # Load the parameters again.\n\
+ # (eax, edx, ecx, *--esp) = (_dl_loaded, argc, argv, envp)\n\
+ movl _rtld_local@GOTOFF(%ebx), %eax\n\
+ leal 8(%esp,%edx,4), %esi\n\
+ leal 4(%esp), %ecx\n\
+ movl %esp, %ebp\n\
+ # Make sure _dl_init is run with 16 byte aligned stack.\n\
+ andl $-16, %esp\n\
+ pushl %eax\n\
+ pushl %eax\n\
+ pushl %ebp\n\
+ pushl %esi\n\
+ # Clear %ebp, so that even constructors have terminated backchain.\n\
+ xorl %ebp, %ebp\n\
+ # Call the function to run the initializers.\n\
+ call _dl_init_internal@PLT\n\
+ # Pass our finalizer function to the user in %edx, as per ELF ABI.\n\
+ leal _dl_fini@GOTOFF(%ebx), %edx\n\
+ # Restore %esp _start expects.\n\
+ movl (%esp), %esp\n\
+ # Jump to the user's entry point.\n\
+ jmp *%edi\n\
+ .previous\n\
+");
+
+#ifndef RTLD_START_SPECIAL_INIT
+# define RTLD_START_SPECIAL_INIT /* nothing */
+#endif
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+# define elf_machine_type_class(type) \
+ ((((type) == R_386_JMP_SLOT || (type) == R_386_TLS_DTPMOD32 \
+ || (type) == R_386_TLS_DTPOFF32 || (type) == R_386_TLS_TPOFF32 \
+ || (type) == R_386_TLS_TPOFF) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_386_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+# define elf_machine_type_class(type) \
+ ((((type) == R_386_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_386_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_386_JMP_SLOT
+
+/* The i386 never uses Elf32_Rela relocations for the dynamic linker.
+ Prelinked libraries may use Elf32_Rela though. */
+#define ELF_MACHINE_PLT_REL 1
+
+/* We define an initialization functions. This is called very early in
+ _dl_sysdep_start. */
+#define DL_PLATFORM_INIT dl_platform_init ()
+
+static inline void __attribute__ ((unused))
+dl_platform_init (void)
+{
+ if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
+ /* Avoid an empty string which would disturb us. */
+ GLRO(dl_platform) = NULL;
+}
+
+static inline Elf32_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf32_Rel *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+ return *reloc_addr = value;
+}
+
+/* Return the final value of a plt relocation. */
+static inline Elf32_Addr
+elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
+ Elf32_Addr value)
+{
+ return value;
+}
+
+
+/* Names of the architecture-specific auditing callback functions. */
+#define ARCH_LA_PLTENTER i86_gnu_pltenter
+#define ARCH_LA_PLTEXIT i86_gnu_pltexit
+
+#endif /* !dl_machine_h */
+
+/* The i386 never uses Elf32_Rela relocations for the dynamic linker.
+ Prelinked libraries may use Elf32_Rela though. */
+#define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP
+
+#ifdef RESOLVE_MAP
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ MAP is the object containing the reloc. */
+
+auto inline void
+__attribute ((always_inline))
+elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
+ const Elf32_Sym *sym, const struct r_found_version *version,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+ if (__builtin_expect (r_type == R_386_RELATIVE, 0))
+ {
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ /* This is defined in rtld.c, but nowhere in the static libc.a;
+ make the reference weak so static programs can still link.
+ This declaration cannot be done when compiling rtld.c
+ (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the
+ common defn for _dl_rtld_map, which is incompatible with a
+ weak decl in the same file. */
+# ifndef SHARED
+ weak_extern (_dl_rtld_map);
+# endif
+ if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
+# endif
+ *reloc_addr += map->l_addr;
+ }
+# ifndef RTLD_BOOTSTRAP
+ else if (__builtin_expect (r_type == R_386_NONE, 0))
+ return;
+# endif
+ else
+#endif /* !RTLD_BOOTSTRAP and have no -z combreloc */
+ {
+ const Elf32_Sym *const refsym = sym;
+ struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+ Elf32_Addr value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+
+ switch (r_type)
+ {
+ case R_386_GLOB_DAT:
+ case R_386_JMP_SLOT:
+ *reloc_addr = value;
+ break;
+
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+ case R_386_TLS_DTPMOD32:
+# ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always the module
+ with index 1.
+ XXX If this relocation is necessary move before RESOLVE
+ call. */
+ *reloc_addr = 1;
+# else
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+# endif
+ break;
+ case R_386_TLS_DTPOFF32:
+# ifndef RTLD_BOOTSTRAP
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ if (sym != NULL)
+ *reloc_addr = sym->st_value;
+# endif
+ break;
+ case R_386_TLS_TPOFF32:
+ /* The offset is positive, backward from the thread pointer. */
+# ifdef RTLD_BOOTSTRAP
+ *reloc_addr += map->l_tls_offset - sym->st_value;
+# else
+ /* We know the offset of object the symbol is contained in.
+ It is a positive value which will be subtracted from the
+ thread pointer. To get the variable position in the TLS
+ block we subtract the offset from that of the TLS block. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr += sym_map->l_tls_offset - sym->st_value;
+ }
+# endif
+ break;
+ case R_386_TLS_TPOFF:
+ /* The offset is negative, forward from the thread pointer. */
+# ifdef RTLD_BOOTSTRAP
+ *reloc_addr += sym->st_value - map->l_tls_offset;
+# else
+ /* We know the offset of object the symbol is contained in.
+ It is a negative value which will be added to the
+ thread pointer. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr += sym->st_value - sym_map->l_tls_offset;
+ }
+# endif
+ break;
+#endif /* use TLS */
+
+#ifndef RTLD_BOOTSTRAP
+ case R_386_32:
+ *reloc_addr += value;
+ break;
+ case R_386_PC32:
+ *reloc_addr += (value - (Elf32_Addr) reloc_addr);
+ break;
+ case R_386_COPY:
+ if (sym == NULL)
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
+ if (__builtin_expect (sym->st_size > refsym->st_size, 0)
+ || (__builtin_expect (sym->st_size < refsym->st_size, 0)
+ && GLRO(dl_verbose)))
+ {
+ const char *strtab;
+
+ strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
+ _dl_error_printf ("\
+%s: Symbol `%s' has different size in shared object, consider re-linking\n",
+ rtld_progname ?: "<program name unknown>",
+ strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr_arg, (void *) value,
+ MIN (sym->st_size, refsym->st_size));
+ break;
+ default:
+ _dl_reloc_bad_type (map, r_type, 0);
+ break;
+#endif /* !RTLD_BOOTSTRAP */
+ }
+ }
+}
+
+#ifndef RTLD_BOOTSTRAP
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
+ const Elf32_Sym *sym, const struct r_found_version *version,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+
+ if (ELF32_R_TYPE (reloc->r_info) == R_386_RELATIVE)
+ *reloc_addr = map->l_addr + reloc->r_addend;
+ else if (r_type != R_386_NONE)
+ {
+# ifndef RESOLVE_CONFLICT_FIND_MAP
+ const Elf32_Sym *const refsym = sym;
+# endif
+ struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+ Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+
+ switch (ELF32_R_TYPE (reloc->r_info))
+ {
+ case R_386_GLOB_DAT:
+ case R_386_JMP_SLOT:
+ case R_386_32:
+ *reloc_addr = value + reloc->r_addend;
+ break;
+# ifndef RESOLVE_CONFLICT_FIND_MAP
+ /* Not needed for dl-conflict.c. */
+ case R_386_PC32:
+ *reloc_addr = (value + reloc->r_addend - (Elf32_Addr) reloc_addr);
+ break;
+
+# ifdef USE_TLS
+ case R_386_TLS_DTPMOD32:
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+ break;
+ case R_386_TLS_DTPOFF32:
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
+ break;
+ case R_386_TLS_TPOFF32:
+ /* The offset is positive, backward from the thread pointer. */
+ /* We know the offset of object the symbol is contained in.
+ It is a positive value which will be subtracted from the
+ thread pointer. To get the variable position in the TLS
+ block we subtract the offset from that of the TLS block. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = sym_map->l_tls_offset - sym->st_value
+ + reloc->r_addend;
+ }
+ break;
+ case R_386_TLS_TPOFF:
+ /* The offset is negative, forward from the thread pointer. */
+ /* We know the offset of object the symbol is contained in.
+ It is a negative value which will be added to the
+ thread pointer. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = sym->st_value - sym_map->l_tls_offset
+ + reloc->r_addend;
+ }
+ break;
+# endif /* use TLS */
+ case R_386_COPY:
+ if (sym == NULL)
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
+ if (__builtin_expect (sym->st_size > refsym->st_size, 0)
+ || (__builtin_expect (sym->st_size < refsym->st_size, 0)
+ && GLRO(dl_verbose)))
+ {
+ const char *strtab;
+
+ strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
+ _dl_error_printf ("\
+%s: Symbol `%s' has different size in shared object, consider re-linking\n",
+ rtld_progname ?: "<program name unknown>",
+ strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr_arg, (void *) value,
+ MIN (sym->st_size, refsym->st_size));
+ break;
+# endif /* !RESOLVE_CONFLICT_FIND_MAP */
+ default:
+ /* We add these checks in the version to relocate ld.so only
+ if we are still debugging. */
+ _dl_reloc_bad_type (map, r_type, 0);
+ break;
+ }
+ }
+}
+#endif /* !RTLD_BOOTSTRAP */
+
+auto inline void
+__attribute ((always_inline))
+elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ assert (ELF32_R_TYPE (reloc->r_info) == R_386_RELATIVE);
+ *reloc_addr += l_addr;
+}
+
+#ifndef RTLD_BOOTSTRAP
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ *reloc_addr = l_addr + reloc->r_addend;
+}
+#endif /* !RTLD_BOOTSTRAP */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf32_Addr l_addr, const Elf32_Rel *reloc)
+{
+ Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
+ const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+ /* Check for unexpected PLT reloc type. */
+ if (__builtin_expect (r_type == R_386_JMP_SLOT, 1))
+ {
+ if (__builtin_expect (map->l_mach.plt, 0) == 0)
+ *reloc_addr += l_addr;
+ else
+ *reloc_addr = (map->l_mach.plt
+ + (((Elf32_Addr) reloc_addr) - map->l_mach.gotplt) * 4);
+ }
+ else
+ _dl_reloc_bad_type (map, r_type, 1);
+}
+
+#ifndef RTLD_BOOTSTRAP
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_lazy_rela (struct link_map *map,
+ Elf32_Addr l_addr, const Elf32_Rela *reloc)
+{
+}
+
+#endif /* !RTLD_BOOTSTRAP */
+
+#endif /* RESOLVE_MAP */
diff --git a/libc/sysdeps/i386/dl-procinfo.c b/libc/sysdeps/i386/dl-procinfo.c
new file mode 100644
index 000000000..2108f22cb
--- /dev/null
+++ b/libc/sysdeps/i386/dl-procinfo.c
@@ -0,0 +1,83 @@
+/* Data for i386 version of processor capability information.
+ Copyright (C) 2001,2002,2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This information must be kept in sync with the _DL_HWCAP_COUNT and
+ _DL_PLATFORM_COUNT definitions in procinfo.h.
+
+ If anything should be added here check whether the size of each string
+ is still ok with the given array size.
+
+ All the #ifdefs in the definitions are quite irritating but
+ necessary if we want to avoid duplicating the information. There
+ are three different modes:
+
+ - PROCINFO_DECL is defined. This means we are only interested in
+ declarations.
+
+ - PROCINFO_DECL is not defined:
+
+ + if SHARED is defined the file is included in an array
+ initializer. The .element = { ... } syntax is needed.
+
+ + if SHARED is not defined a normal array initialization is
+ needed.
+ */
+
+#ifndef PROCINFO_CLASS
+# define PROCINFO_CLASS
+#endif
+
+#if !defined PROCINFO_DECL && defined SHARED
+ ._dl_x86_cap_flags
+#else
+PROCINFO_CLASS const char _dl_x86_cap_flags[32][8]
+#endif
+#ifndef PROCINFO_DECL
+= {
+ "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+ "cx8", "apic", "10", "sep", "mtrr", "pge", "mca", "cmov",
+ "pat", "pse36", "pn", "clflush", "20", "dts", "acpi", "mmx",
+ "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe"
+ }
+#endif
+#if !defined SHARED || defined PROCINFO_DECL
+;
+#else
+,
+#endif
+
+#if !defined PROCINFO_DECL && defined SHARED
+ ._dl_x86_platforms
+#else
+PROCINFO_CLASS const char _dl_x86_platforms[4][5]
+#endif
+#ifndef PROCINFO_DECL
+= {
+ "i386", "i486", "i586", "i686"
+ }
+#endif
+#if !defined SHARED || defined PROCINFO_DECL
+;
+#else
+,
+#endif
+
+#undef PROCINFO_DECL
+#undef PROCINFO_CLASS
diff --git a/libc/sysdeps/i386/dl-procinfo.h b/libc/sysdeps/i386/dl-procinfo.h
new file mode 100644
index 000000000..d114fec79
--- /dev/null
+++ b/libc/sysdeps/i386/dl-procinfo.h
@@ -0,0 +1,110 @@
+/* i386 version of processor capability information handling macros.
+ Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DL_PROCINFO_H
+#define _DL_PROCINFO_H 1
+#include <ldsodefs.h>
+
+#define _DL_HWCAP_COUNT 32
+
+#define _DL_PLATFORMS_COUNT 4
+
+/* Start at 48 to reserve some space. */
+#define _DL_FIRST_PLATFORM 48
+/* Mask to filter out platforms. */
+#define _DL_HWCAP_PLATFORM (((1ULL << _DL_PLATFORMS_COUNT) - 1) \
+ << _DL_FIRST_PLATFORM)
+
+enum
+{
+ HWCAP_I386_FPU = 1 << 0,
+ HWCAP_I386_VME = 1 << 1,
+ HWCAP_I386_DE = 1 << 2,
+ HWCAP_I386_PSE = 1 << 3,
+ HWCAP_I386_TSC = 1 << 4,
+ HWCAP_I386_MSR = 1 << 5,
+ HWCAP_I386_PAE = 1 << 6,
+ HWCAP_I386_MCE = 1 << 7,
+ HWCAP_I386_CX8 = 1 << 8,
+ HWCAP_I386_APIC = 1 << 9,
+ HWCAP_I386_SEP = 1 << 11,
+ HWCAP_I386_MTRR = 1 << 12,
+ HWCAP_I386_PGE = 1 << 13,
+ HWCAP_I386_MCA = 1 << 14,
+ HWCAP_I386_CMOV = 1 << 15,
+ HWCAP_I386_FCMOV = 1 << 16,
+ HWCAP_I386_MMX = 1 << 23,
+ HWCAP_I386_OSFXSR = 1 << 24,
+ HWCAP_I386_XMM = 1 << 25,
+ HWCAP_I386_XMM2 = 1 << 26,
+ HWCAP_I386_AMD3D = 1 << 31,
+
+ /* XXX Which others to add here? */
+ HWCAP_IMPORTANT = (HWCAP_I386_XMM2)
+
+};
+
+/* We cannot provide a general printing function. */
+#define _dl_procinfo(word) -1
+
+static inline const char *
+__attribute__ ((unused))
+_dl_hwcap_string (int idx)
+{
+ return GLRO(dl_x86_cap_flags)[idx];
+};
+
+static inline const char *
+__attribute__ ((unused))
+_dl_platform_string (int idx)
+{
+ return GLRO(dl_x86_platforms)[idx - _DL_FIRST_PLATFORM];
+};
+
+static inline int
+__attribute__ ((unused, always_inline))
+_dl_string_hwcap (const char *str)
+{
+ int i;
+
+ for (i = 0; i < _DL_HWCAP_COUNT; i++)
+ {
+ if (strcmp (str, GLRO(dl_x86_cap_flags)[i]) == 0)
+ return i;
+ }
+ return -1;
+};
+
+static inline int
+__attribute__ ((unused, always_inline))
+_dl_string_platform (const char *str)
+{
+ int i;
+
+ if (str != NULL)
+ for (i = 0; i < _DL_PLATFORMS_COUNT; ++i)
+ {
+ if (strcmp (str, GLRO(dl_x86_platforms)[i]) == 0)
+ return _DL_FIRST_PLATFORM + i;
+ }
+ return -1;
+};
+
+#endif /* dl-procinfo.h */
diff --git a/libc/sysdeps/i386/dl-tls.h b/libc/sysdeps/i386/dl-tls.h
new file mode 100644
index 000000000..a1707197c
--- /dev/null
+++ b/libc/sysdeps/i386/dl-tls.h
@@ -0,0 +1,60 @@
+/* Thread-local storage handling in the ELF dynamic linker. i386 version.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* Type used for the representation of TLS information in the GOT. */
+typedef struct
+{
+ unsigned long int ti_module;
+ unsigned long int ti_offset;
+} tls_index;
+
+
+#ifdef SHARED
+/* This is the prototype for the GNU version. */
+extern void *___tls_get_addr (tls_index *ti)
+ __attribute__ ((__regparm__ (1)));
+extern void *___tls_get_addr_internal (tls_index *ti)
+ __attribute__ ((__regparm__ (1))) attribute_hidden;
+
+# ifdef IS_IN_rtld
+/* The special thing about the x86 TLS ABI is that we have two
+ variants of the __tls_get_addr function with different calling
+ conventions. The GNU version, which we are mostly concerned here,
+ takes the parameter in a register. The name is changed by adding
+ an additional underscore at the beginning. The Sun version uses
+ the normal calling convention. */
+void *
+__tls_get_addr (tls_index *ti)
+{
+ return ___tls_get_addr_internal (ti);
+}
+
+
+/* Prepare using the definition of __tls_get_addr in the generic
+ version of this file. */
+# define __tls_get_addr __attribute__ ((__regparm__ (1))) ___tls_get_addr
+strong_alias (___tls_get_addr, ___tls_get_addr_internal)
+#else
+
+/* Users should get the better interface. */
+# define __tls_get_addr ___tls_get_addr
+
+# endif
+#endif
diff --git a/libc/sysdeps/i386/dl-trampoline.S b/libc/sysdeps/i386/dl-trampoline.S
new file mode 100644
index 000000000..fd87eb711
--- /dev/null
+++ b/libc/sysdeps/i386/dl-trampoline.S
@@ -0,0 +1,184 @@
+/* PLT trampolines. i386 version.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ .globl _dl_runtime_resolve
+ .type _dl_runtime_resolve, @function
+ cfi_startproc
+ .align 16
+_dl_runtime_resolve:
+ cfi_adjust_cfa_offset (8)
+ pushl %eax # Preserve registers otherwise clobbered.
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %edx
+ cfi_adjust_cfa_offset (4)
+ movl 16(%esp), %edx # Copy args pushed by PLT in register. Note
+ movl 12(%esp), %eax # that `fixup' takes its parameters in regs.
+ call _dl_fixup # Call resolver.
+ popl %edx # Get register content back.
+ cfi_adjust_cfa_offset (-4)
+ popl %ecx
+ cfi_adjust_cfa_offset (-4)
+ xchgl %eax, (%esp) # Get %eax contents end store function address.
+ ret $8 # Jump to function address.
+ cfi_endproc
+ .size _dl_runtime_resolve, .-_dl_runtime_resolve
+
+
+#ifndef PROF
+ .globl _dl_runtime_profile
+ .type _dl_runtime_profile, @function
+ cfi_startproc
+ .align 16
+_dl_runtime_profile:
+ cfi_adjust_cfa_offset (8)
+ pushl %esp
+ cfi_adjust_cfa_offset (4)
+ addl $8, (%esp) # Account for the pushed PLT data
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %eax # Preserve registers otherwise clobbered.
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %edx
+ cfi_adjust_cfa_offset (4)
+ movl %esp, %ecx
+ subl $8, %esp
+ cfi_adjust_cfa_offset (8)
+ movl $-1, 4(%esp)
+ leal 4(%esp), %edx
+ movl %edx, (%esp)
+ pushl %ecx # Address of the register structure
+ cfi_adjust_cfa_offset (4)
+ movl 40(%esp), %ecx # Load return address
+ movl 36(%esp), %edx # Copy args pushed by PLT in register. Note
+ movl 32(%esp), %eax # that `fixup' takes its parameters in regs.
+ call _dl_profile_fixup # Call resolver.
+ cfi_adjust_cfa_offset (-8)
+ movl (%esp), %edx
+ testl %edx, %edx
+ jns 1f
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ popl %edx # Get register content back.
+ cfi_adjust_cfa_offset (-4)
+ popl %ecx
+ cfi_adjust_cfa_offset (-4)
+ xchgl %eax, (%esp) # Get %eax contents end store function address.
+ ret $16 # Jump to function address.
+
+ /*
+ +32 return address
+ +28 PLT1
+ +24 PLT2
+ +20 %esp
+ +16 %ebp
+ +12 %eax
+ +8 %ecx
+ +4 %edx
+ %esp free
+ */
+ cfi_adjust_cfa_offset (12)
+1: movl %ebx, (%esp)
+ cfi_rel_offset (3, 0)
+ movl %edx, %ebx # This is the frame buffer size
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (7, 0)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (6, 0)
+ leal 44(%esp), %esi
+ movl %ebx, %ecx
+ movl %esp, %edi
+ subl %ebx, %edi
+ andl $0xfffffff0, %edi # Align stack
+ movl %esp, %ebx
+ cfi_def_cfa_register (3)
+ movl %edi, %esp
+ shrl $2, %ecx
+ rep
+ movsl
+ movl (%edi), %esi
+ cfi_restore (6)
+ movl 4(%edi), %edi
+ cfi_restore (7)
+ /*
+ %ebx+40 return address
+ %ebx+36 PLT1
+ %ebx+32 PLT2
+ %ebx+28 %esp
+ %ebx+24 %ebp
+ %ebx+20 %eax
+ %ebx+16 %ecx
+ %ebx+12 %edx
+ %ebx+8 %ebx
+ %ebx+4 free
+ %ebx free
+ %esp copied stack frame
+ */
+ movl %eax, (%ebx)
+ movl 12(%ebx), %edx
+ movl 16(%ebx), %ecx
+ movl 20(%ebx), %eax
+ call *(%ebx)
+ movl %ebx, %esp
+ cfi_def_cfa_register (4)
+ movl 8(%esp), %ebx
+ cfi_restore (3)
+ /*
+ +40 return address
+ +36 PLT1
+ +32 PLT2
+ +28 %esp
+ +24 %ebp
+ +20 %eax
+ +16 %ecx
+ +12 %edx
+ +8 free
+ +4 free
+ %esp free
+ */
+ subl $20, %esp
+ cfi_adjust_cfa_offset (20)
+ movl %eax, (%esp)
+ movl %edx, 4(%esp)
+ fstpt 8(%esp)
+ fstpt 20(%esp)
+ pushl %esp
+ cfi_adjust_cfa_offset (4)
+ leal 36(%esp), %ecx
+ movl 56(%esp), %eax
+ movl 60(%esp), %edx
+ call _dl_call_pltexit
+ movl (%esp), %eax
+ movl 4(%esp), %edx
+ fldt 20(%esp)
+ fldt 8(%esp)
+ addl $60, %esp
+ cfi_adjust_cfa_offset (-60)
+ ret
+ cfi_endproc
+ .size _dl_runtime_profile, .-_dl_runtime_profile
+#endif
diff --git a/libc/sysdeps/i386/elf/Versions b/libc/sysdeps/i386/elf/Versions
new file mode 100644
index 000000000..5ca6686b8
--- /dev/null
+++ b/libc/sysdeps/i386/elf/Versions
@@ -0,0 +1,6 @@
+ld {
+ GLIBC_2.3 {
+ # The alternative i386 runtime interface to TLS.
+ ___tls_get_addr;
+ }
+}
diff --git a/libc/sysdeps/i386/elf/configure b/libc/sysdeps/i386/elf/configure
new file mode 100755
index 000000000..1182d974b
--- /dev/null
+++ b/libc/sysdeps/i386/elf/configure
@@ -0,0 +1,53 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/i386/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+echo "$as_me:$LINENO: checking for i386 TLS support" >&5
+echo $ECHO_N "checking for i386 TLS support... $ECHO_C" >&6
+if test "${libc_cv_386_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<\EOF
+ .section ".tdata", "awT", @progbits
+ .globl foo
+foo: .long 1
+ .section ".tbss", "awT", @nobits
+ .globl bar
+bar: .skip 4
+ .text
+baz: leal bar@TLSLDM(%ebx), %eax
+ leal bar@DTPOFF(%eax), %edx
+ subl foo@GOTTPOFF(%edx), %eax
+ subl $bar@TPOFF, %eax
+ movl foo@GOTNTPOFF(%edx), %ecx
+ movl %gs:(%ecx), %eax
+ movl %gs:bar@NTPOFF, %eax
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_386_tls=yes
+else
+ libc_cv_386_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_386_tls" >&5
+echo "${ECHO_T}$libc_cv_386_tls" >&6
+if test $libc_cv_386_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+cat >>confdefs.h <<\_ACEOF
+#define PI_STATIC_AND_HIDDEN 1
+_ACEOF
+
diff --git a/libc/sysdeps/i386/elf/configure.in b/libc/sysdeps/i386/elf/configure.in
new file mode 100644
index 000000000..ca607adeb
--- /dev/null
+++ b/libc/sysdeps/i386/elf/configure.in
@@ -0,0 +1,38 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/i386/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for i386 TLS support, libc_cv_386_tls, [dnl
+cat > conftest.s <<\EOF
+ .section ".tdata", "awT", @progbits
+ .globl foo
+foo: .long 1
+ .section ".tbss", "awT", @nobits
+ .globl bar
+bar: .skip 4
+ .text
+baz: leal bar@TLSLDM(%ebx), %eax
+ leal bar@DTPOFF(%eax), %edx
+ subl foo@GOTTPOFF(%edx), %eax
+ subl $bar@TPOFF, %eax
+ movl foo@GOTNTPOFF(%edx), %ecx
+ movl %gs:(%ecx), %eax
+ movl %gs:bar@NTPOFF, %eax
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_386_tls=yes
+else
+ libc_cv_386_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_386_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
+dnl It is always possible to access static and hidden symbols in an
+dnl position independent way.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
diff --git a/libc/sysdeps/i386/elf/start.S b/libc/sysdeps/i386/elf/start.S
new file mode 100644
index 000000000..d2275a399
--- /dev/null
+++ b/libc/sysdeps/i386/elf/start.S
@@ -0,0 +1,143 @@
+/* Startup code compliant to the ELF i386 ABI.
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This is the canonical entry point, usually the first thing in the text
+ segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
+ point runs, most registers' values are unspecified, except for:
+
+ %edx Contains a function pointer to be registered with `atexit'.
+ This is how the dynamic linker arranges to have DT_FINI
+ functions called for shared libraries that have been loaded
+ before this code runs.
+
+ %esp The stack contains the arguments and environment:
+ 0(%esp) argc
+ 4(%esp) argv[0]
+ ...
+ (4*argc)(%esp) NULL
+ (4*(argc+1))(%esp) envp[0]
+ ...
+ NULL
+*/
+
+#include "bp-sym.h"
+
+ .text
+ .globl _start
+ .type _start,@function
+_start:
+ /* Clear the frame pointer. The ABI suggests this be done, to mark
+ the outermost frame obviously. */
+ xorl %ebp, %ebp
+
+ /* Extract the arguments as encoded on the stack and set up
+ the arguments for `main': argc, argv. envp will be determined
+ later in __libc_start_main. */
+ popl %esi /* Pop the argument count. */
+ movl %esp, %ecx /* argv starts just at the current stack top.*/
+
+ /* Before pushing the arguments align the stack to a 16-byte
+ (SSE needs 16-byte alignment) boundary to avoid penalties from
+ misaligned accesses. Thanks to Edward Seidl <seidl@janed.com>
+ for pointing this out. */
+ andl $0xfffffff0, %esp
+ pushl %eax /* Push garbage because we allocate
+ 28 more bytes. */
+
+ /* Provide the highest stack address to the user code (for stacks
+ which grow downwards). */
+ pushl %esp
+
+ pushl %edx /* Push address of the shared library
+ termination function. */
+
+#ifdef SHARED
+ /* Load PIC register. */
+ call 1f
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+
+ /* Push address of our own entry points to .fini and .init. */
+ leal __libc_csu_fini@GOTOFF(%ebx), %eax
+ pushl %eax
+ leal __libc_csu_init@GOTOFF(%ebx), %eax
+ pushl %eax
+
+ pushl %ecx /* Push second argument: argv. */
+ pushl %esi /* Push first argument: argc. */
+
+ pushl BP_SYM (main)@GOT(%ebx)
+
+ /* Call the user's main function, and exit with its value.
+ But let the libc call main. */
+ call BP_SYM (__libc_start_main)@PLT
+#else
+ /* Push address of our own entry points to .fini and .init. */
+ pushl $__libc_csu_fini
+ pushl $__libc_csu_init
+
+ pushl %ecx /* Push second argument: argv. */
+ pushl %esi /* Push first argument: argc. */
+
+ pushl $BP_SYM (main)
+
+ /* Call the user's main function, and exit with its value.
+ But let the libc call main. */
+ call BP_SYM (__libc_start_main)
+#endif
+
+ hlt /* Crash if somehow `exit' does return. */
+
+#ifdef SHARED
+1: movl (%esp), %ebx
+ ret
+#endif
+
+/* To fulfill the System V/i386 ABI we need this symbol. Yuck, it's so
+ meaningless since we don't support machines < 80386. */
+ .section .rodata
+ .globl _fp_hw
+_fp_hw: .long 3
+ .size _fp_hw, 4
+ .type _fp_hw,@object
+
+/* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+ .long 0
+ .weak data_start
+ data_start = __data_start
diff --git a/libc/sysdeps/i386/ffs.c b/libc/sysdeps/i386/ffs.c
new file mode 100644
index 000000000..b6aac64dd
--- /dev/null
+++ b/libc/sysdeps/i386/ffs.c
@@ -0,0 +1,51 @@
+/* ffs -- find first set bit in a word, counted from least significant end.
+ For Intel 80x86, x>=3.
+ This file is part of the GNU C Library.
+ Copyright (C) 1991, 92, 93, 94, 97, 98, 2004, 2005 Free Software Foundation, Inc.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define ffsl __something_else
+#include <string.h>
+
+#undef ffs
+
+#ifdef __GNUC__
+
+int
+__ffs (x)
+ int x;
+{
+ int cnt;
+ int tmp;
+
+ asm ("xorl %0,%0\n" /* Set CNT to zero. */
+ "bsfl %2,%1\n" /* Count low bits in X and store in %1. */
+ "jz 1f\n" /* Jump if OK, i.e. X was non-zero. */
+ "leal 1(%1),%0\n" /* Return bsfl-result plus one on %0. */
+ "1:" : "=&a" (cnt), "=r" (tmp) : "rm" (x));
+
+ return cnt;
+}
+weak_alias (__ffs, ffs)
+libc_hidden_builtin_def (ffs)
+#undef ffsl
+weak_alias (__ffs, ffsl)
+
+#else
+#include <string/ffs.c>
+#endif
diff --git a/libc/sysdeps/i386/fpu/Makefile b/libc/sysdeps/i386/fpu/Makefile
new file mode 100644
index 000000000..1309b64c1
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),math)
+$(objpfx)libm.so: $(elfobjdir)/ld.so
+endif
diff --git a/libc/sysdeps/i386/fpu/Versions b/libc/sysdeps/i386/fpu/Versions
new file mode 100644
index 000000000..a2eec371f
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/Versions
@@ -0,0 +1,6 @@
+libm {
+ GLIBC_2.2 {
+ # functions used in inline functions or macros
+ __expl; __expm1l;
+ }
+}
diff --git a/libc/sysdeps/i386/fpu/bits/fenv.h b/libc/sysdeps/i386/fpu/bits/fenv.h
new file mode 100644
index 000000000..ef3fcb384
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/bits/fenv.h
@@ -0,0 +1,90 @@
+/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+
+/* Define bits representing the exception. We use the bit positions
+ of the appropriate bits in the FPU control word. */
+enum
+ {
+ FE_INVALID = 0x01,
+#define FE_INVALID FE_INVALID
+ __FE_DENORM = 0x02,
+ FE_DIVBYZERO = 0x04,
+#define FE_DIVBYZERO FE_DIVBYZERO
+ FE_OVERFLOW = 0x08,
+#define FE_OVERFLOW FE_OVERFLOW
+ FE_UNDERFLOW = 0x10,
+#define FE_UNDERFLOW FE_UNDERFLOW
+ FE_INEXACT = 0x20
+#define FE_INEXACT FE_INEXACT
+ };
+
+#define FE_ALL_EXCEPT \
+ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+/* The ix87 FPU supports all of the four defined rounding modes. We
+ use again the bit positions in the FPU control word as the values
+ for the appropriate macros. */
+enum
+ {
+ FE_TONEAREST = 0,
+#define FE_TONEAREST FE_TONEAREST
+ FE_DOWNWARD = 0x400,
+#define FE_DOWNWARD FE_DOWNWARD
+ FE_UPWARD = 0x800,
+#define FE_UPWARD FE_UPWARD
+ FE_TOWARDZERO = 0xc00
+#define FE_TOWARDZERO FE_TOWARDZERO
+ };
+
+
+/* Type representing exception flags. */
+typedef unsigned short int fexcept_t;
+
+
+/* Type representing floating-point environment. This function corresponds
+ to the layout of the block written by the `fstenv'. */
+typedef struct
+ {
+ unsigned short int __control_word;
+ unsigned short int __unused1;
+ unsigned short int __status_word;
+ unsigned short int __unused2;
+ unsigned short int __tags;
+ unsigned short int __unused3;
+ unsigned int __eip;
+ unsigned short int __cs_selector;
+ unsigned int __opcode:11;
+ unsigned int __unused4:5;
+ unsigned int __data_offset;
+ unsigned short int __data_selector;
+ unsigned short int __unused5;
+ }
+fenv_t;
+
+/* If the default argument is used we use this value. */
+#define FE_DFL_ENV ((__const fenv_t *) -1)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exception is masked. */
+# define FE_NOMASK_ENV ((__const fenv_t *) -2)
+#endif
diff --git a/libc/sysdeps/i386/fpu/bits/mathinline.h b/libc/sysdeps/i386/fpu/bits/mathinline.h
new file mode 100644
index 000000000..e04ce9509
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/bits/mathinline.h
@@ -0,0 +1,755 @@
+/* Inline math functions for i387.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by John C. Bowman <bowman@math.ualberta.ca>, 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
+#endif
+
+#ifdef __cplusplus
+# define __MATH_INLINE __inline
+#else
+# define __MATH_INLINE extern __inline
+#endif
+
+
+#if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2
+/* GCC 2.97 and up have builtins that actually can be used. */
+# if !__GNUC_PREREQ (2,97)
+/* ISO C99 defines some macros to perform unordered comparisons. The
+ ix87 FPU supports this with special opcodes and we should use them.
+ These must not be inline functions since we have to be able to handle
+ all floating-point types. */
+# undef isgreater
+# undef isgreaterequal
+# undef isless
+# undef islessequal
+# undef islessgreater
+# undef isunordered
+# ifdef __i686__
+/* For the PentiumPro and more recent processors we can provide
+ better code. */
+# define isgreater(x, y) \
+ ({ register char __result; \
+ __asm__ ("fucomip %%st(1), %%st; seta %%al" \
+ : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
+ __result; })
+# define isgreaterequal(x, y) \
+ ({ register char __result; \
+ __asm__ ("fucomip %%st(1), %%st; setae %%al" \
+ : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
+ __result; })
+
+# define isless(x, y) \
+ ({ register char __result; \
+ __asm__ ("fucomip %%st(1), %%st; seta %%al" \
+ : "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \
+ __result; })
+
+# define islessequal(x, y) \
+ ({ register char __result; \
+ __asm__ ("fucomip %%st(1), %%st; setae %%al" \
+ : "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \
+ __result; })
+
+# define islessgreater(x, y) \
+ ({ register char __result; \
+ __asm__ ("fucomip %%st(1), %%st; setne %%al" \
+ : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
+ __result; })
+
+# define isunordered(x, y) \
+ ({ register char __result; \
+ __asm__ ("fucomip %%st(1), %%st; setp %%al" \
+ : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
+ __result; })
+# else
+/* This is the dumb, portable code for i386 and above. */
+# define isgreater(x, y) \
+ ({ register char __result; \
+ __asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \
+ : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
+ __result; })
+
+# define isgreaterequal(x, y) \
+ ({ register char __result; \
+ __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \
+ : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
+ __result; })
+
+# define isless(x, y) \
+ ({ register char __result; \
+ __asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \
+ : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
+ __result; })
+
+# define islessequal(x, y) \
+ ({ register char __result; \
+ __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \
+ : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
+ __result; })
+
+# define islessgreater(x, y) \
+ ({ register char __result; \
+ __asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al" \
+ : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
+ __result; })
+
+# define isunordered(x, y) \
+ ({ register char __result; \
+ __asm__ ("fucompp; fnstsw; sahf; setp %%al" \
+ : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
+ __result; })
+# endif /* __i686__ */
+# endif /* GCC 2.97 */
+
+/* The gcc, version 2.7 or below, has problems with all this inlining
+ code. So disable it for this version of the compiler. */
+# if __GNUC_PREREQ (2, 8)
+/* Test for negative number. Used in the signbit() macro. */
+__MATH_INLINE int
+__NTH (__signbitf (float __x))
+{
+ __extension__ union { float __f; int __i; } __u = { __f: __x };
+ return __u.__i < 0;
+}
+__MATH_INLINE int
+__NTH (__signbit (double __x))
+{
+ __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
+ return __u.__i[1] < 0;
+}
+__MATH_INLINE int
+__NTH (__signbitl (long double __x))
+{
+ __extension__ union { long double __l; int __i[3]; } __u = { __l: __x };
+ return (__u.__i[2] & 0x8000) != 0;
+}
+# endif
+#endif
+
+
+/* The gcc, version 2.7 or below, has problems with all this inlining
+ code. So disable it for this version of the compiler. */
+#if __GNUC_PREREQ (2, 8)
+
+#if ((!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \
+ && defined __OPTIMIZE__)
+
+/* A macro to define float, double, and long double versions of various
+ math functions for the ix87 FPU. FUNC is the function name (which will
+ be suffixed with f and l for the float and long double version,
+ respectively). OP is the name of the FPU operation.
+ We define two sets of macros. The set with the additional NP
+ doesn't add a prototype declaration. */
+
+#if defined __USE_MISC || defined __USE_ISOC99
+# define __inline_mathop(func, op) \
+ __inline_mathop_ (double, func, op) \
+ __inline_mathop_ (float, __CONCAT(func,f), op) \
+ __inline_mathop_ (long double, __CONCAT(func,l), op)
+# define __inline_mathopNP(func, op) \
+ __inline_mathopNP_ (double, func, op) \
+ __inline_mathopNP_ (float, __CONCAT(func,f), op) \
+ __inline_mathopNP_ (long double, __CONCAT(func,l), op)
+#else
+# define __inline_mathop(func, op) \
+ __inline_mathop_ (double, func, op)
+# define __inline_mathopNP(func, op) \
+ __inline_mathopNP_ (double, func, op)
+#endif
+
+#define __inline_mathop_(float_type, func, op) \
+ __inline_mathop_decl_ (float_type, func, op, "0" (__x))
+#define __inline_mathopNP_(float_type, func, op) \
+ __inline_mathop_declNP_ (float_type, func, op, "0" (__x))
+
+
+#if defined __USE_MISC || defined __USE_ISOC99
+# define __inline_mathop_decl(func, op, params...) \
+ __inline_mathop_decl_ (double, func, op, params) \
+ __inline_mathop_decl_ (float, __CONCAT(func,f), op, params) \
+ __inline_mathop_decl_ (long double, __CONCAT(func,l), op, params)
+# define __inline_mathop_declNP(func, op, params...) \
+ __inline_mathop_declNP_ (double, func, op, params) \
+ __inline_mathop_declNP_ (float, __CONCAT(func,f), op, params) \
+ __inline_mathop_declNP_ (long double, __CONCAT(func,l), op, params)
+#else
+# define __inline_mathop_decl(func, op, params...) \
+ __inline_mathop_decl_ (double, func, op, params)
+# define __inline_mathop_declNP(func, op, params...) \
+ __inline_mathop_declNP_ (double, func, op, params)
+#endif
+
+#define __inline_mathop_decl_(float_type, func, op, params...) \
+ __MATH_INLINE float_type func (float_type) __THROW; \
+ __inline_mathop_declNP_ (float_type, func, op, params)
+
+#define __inline_mathop_declNP_(float_type, func, op, params...) \
+ __MATH_INLINE float_type __NTH (func (float_type __x)) \
+ { \
+ register float_type __result; \
+ __asm __volatile__ (op : "=t" (__result) : params); \
+ return __result; \
+ }
+
+
+#if defined __USE_MISC || defined __USE_ISOC99
+# define __inline_mathcode(func, arg, code) \
+ __inline_mathcode_ (double, func, arg, code) \
+ __inline_mathcode_ (float, __CONCAT(func,f), arg, code) \
+ __inline_mathcode_ (long double, __CONCAT(func,l), arg, code)
+# define __inline_mathcodeNP(func, arg, code) \
+ __inline_mathcodeNP_ (double, func, arg, code) \
+ __inline_mathcodeNP_ (float, __CONCAT(func,f), arg, code) \
+ __inline_mathcodeNP_ (long double, __CONCAT(func,l), arg, code)
+# define __inline_mathcode2(func, arg1, arg2, code) \
+ __inline_mathcode2_ (double, func, arg1, arg2, code) \
+ __inline_mathcode2_ (float, __CONCAT(func,f), arg1, arg2, code) \
+ __inline_mathcode2_ (long double, __CONCAT(func,l), arg1, arg2, code)
+# define __inline_mathcodeNP2(func, arg1, arg2, code) \
+ __inline_mathcodeNP2_ (double, func, arg1, arg2, code) \
+ __inline_mathcodeNP2_ (float, __CONCAT(func,f), arg1, arg2, code) \
+ __inline_mathcodeNP2_ (long double, __CONCAT(func,l), arg1, arg2, code)
+# define __inline_mathcode3(func, arg1, arg2, arg3, code) \
+ __inline_mathcode3_ (double, func, arg1, arg2, arg3, code) \
+ __inline_mathcode3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
+ __inline_mathcode3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
+# define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
+ __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code) \
+ __inline_mathcodeNP3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
+ __inline_mathcodeNP3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
+#else
+# define __inline_mathcode(func, arg, code) \
+ __inline_mathcode_ (double, func, (arg), code)
+# define __inline_mathcodeNP(func, arg, code) \
+ __inline_mathcodeNP_ (double, func, (arg), code)
+# define __inline_mathcode2(func, arg1, arg2, code) \
+ __inline_mathcode2_ (double, func, arg1, arg2, code)
+# define __inline_mathcodeNP2(func, arg1, arg2, code) \
+ __inline_mathcodeNP2_ (double, func, arg1, arg2, code)
+# define __inline_mathcode3(func, arg1, arg2, arg3, code) \
+ __inline_mathcode3_ (double, func, arg1, arg2, arg3, code)
+# define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
+ __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code)
+#endif
+
+#define __inline_mathcode_(float_type, func, arg, code) \
+ __MATH_INLINE float_type func (float_type) __THROW; \
+ __inline_mathcodeNP_(float_type, func, arg, code)
+
+#define __inline_mathcodeNP_(float_type, func, arg, code) \
+ __MATH_INLINE float_type __NTH (func (float_type arg)) \
+ { \
+ code; \
+ }
+
+
+#define __inline_mathcode2_(float_type, func, arg1, arg2, code) \
+ __MATH_INLINE float_type func (float_type, float_type) __THROW; \
+ __inline_mathcodeNP2_ (float_type, func, arg1, arg2, code)
+
+#define __inline_mathcodeNP2_(float_type, func, arg1, arg2, code) \
+ __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2)) \
+ { \
+ code; \
+ }
+
+#define __inline_mathcode3_(float_type, func, arg1, arg2, arg3, code) \
+ __MATH_INLINE float_type func (float_type, float_type, float_type) __THROW; \
+ __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code)
+
+#define __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code) \
+ __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2, \
+ float_type arg3)) \
+ { \
+ code; \
+ }
+#endif
+
+
+#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
+/* Miscellaneous functions */
+
+__inline_mathcode (__sgn, __x, \
+ return __x == 0.0 ? 0.0 : (__x > 0.0 ? 1.0 : -1.0))
+
+/* __FAST_MATH__ is defined by gcc -ffast-math. */
+#ifdef __FAST_MATH__
+__inline_mathcode (__pow2, __x, \
+ register long double __value; \
+ register long double __exponent; \
+ __extension__ long long int __p = (long long int) __x; \
+ if (__x == (long double) __p) \
+ { \
+ __asm __volatile__ \
+ ("fscale" \
+ : "=t" (__value) : "0" (1.0), "u" (__x)); \
+ return __value; \
+ } \
+ __asm __volatile__ \
+ ("fld %%st(0)\n\t" \
+ "frndint # int(x)\n\t" \
+ "fxch\n\t" \
+ "fsub %%st(1) # fract(x)\n\t" \
+ "f2xm1 # 2^(fract(x)) - 1\n\t" \
+ : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
+ __value += 1.0; \
+ __asm __volatile__ \
+ ("fscale" \
+ : "=t" (__value) : "0" (__value), "u" (__exponent)); \
+ return __value)
+
+# ifdef __USE_GNU
+# define __sincos_code \
+ register long double __cosr; \
+ register long double __sinr; \
+ __asm __volatile__ \
+ ("fsincos\n\t" \
+ "fnstsw %%ax\n\t" \
+ "testl $0x400, %%eax\n\t" \
+ "jz 1f\n\t" \
+ "fldpi\n\t" \
+ "fadd %%st(0)\n\t" \
+ "fxch %%st(1)\n\t" \
+ "2: fprem1\n\t" \
+ "fnstsw %%ax\n\t" \
+ "testl $0x400, %%eax\n\t" \
+ "jnz 2b\n\t" \
+ "fstp %%st(1)\n\t" \
+ "fsincos\n\t" \
+ "1:" \
+ : "=t" (__cosr), "=u" (__sinr) : "0" (__x)); \
+ *__sinx = __sinr; \
+ *__cosx = __cosr
+
+__MATH_INLINE void
+__NTH (__sincos (double __x, double *__sinx, double *__cosx))
+{
+ __sincos_code;
+}
+
+__MATH_INLINE void
+__NTH (__sincosf (float __x, float *__sinx, float *__cosx))
+{
+ __sincos_code;
+}
+
+__MATH_INLINE void
+__NTH (__sincosl (long double __x, long double *__sinx, long double *__cosx))
+{
+ __sincos_code;
+}
+# endif
+
+
+/* Optimized inline implementation, sometimes with reduced precision
+ and/or argument range. */
+
+# if __GNUC_PREREQ (3, 5)
+# define __expm1_code \
+ register long double __temp; \
+ __temp = __builtin_expm1l (__x); \
+ return __temp ? __temp : __x
+# else
+# define __expm1_code \
+ register long double __value; \
+ register long double __exponent; \
+ register long double __temp; \
+ __asm __volatile__ \
+ ("fldl2e # e^x - 1 = 2^(x * log2(e)) - 1\n\t" \
+ "fmul %%st(1) # x * log2(e)\n\t" \
+ "fst %%st(1)\n\t" \
+ "frndint # int(x * log2(e))\n\t" \
+ "fxch\n\t" \
+ "fsub %%st(1) # fract(x * log2(e))\n\t" \
+ "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
+ "fscale # 2^(x * log2(e)) - 2^(int(x * log2(e)))\n\t" \
+ : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
+ __asm __volatile__ \
+ ("fscale # 2^int(x * log2(e))\n\t" \
+ : "=t" (__temp) : "0" (1.0), "u" (__exponent)); \
+ __temp -= 1.0; \
+ __temp += __value; \
+ return __temp ? __temp : __x
+# endif
+__inline_mathcodeNP_ (long double, __expm1l, __x, __expm1_code)
+
+# if __GNUC_PREREQ (3, 4)
+__inline_mathcodeNP_ (long double, __expl, __x, return __builtin_expl (__x))
+# else
+# define __exp_code \
+ register long double __value; \
+ register long double __exponent; \
+ __asm __volatile__ \
+ ("fldl2e # e^x = 2^(x * log2(e))\n\t" \
+ "fmul %%st(1) # x * log2(e)\n\t" \
+ "fst %%st(1)\n\t" \
+ "frndint # int(x * log2(e))\n\t" \
+ "fxch\n\t" \
+ "fsub %%st(1) # fract(x * log2(e))\n\t" \
+ "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
+ : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
+ __value += 1.0; \
+ __asm __volatile__ \
+ ("fscale" \
+ : "=t" (__value) : "0" (__value), "u" (__exponent)); \
+ return __value
+__inline_mathcodeNP (exp, __x, __exp_code)
+__inline_mathcodeNP_ (long double, __expl, __x, __exp_code)
+# endif
+
+
+# if !__GNUC_PREREQ (3, 5)
+__inline_mathcodeNP (tan, __x, \
+ register long double __value; \
+ register long double __value2 __attribute__ ((__unused__)); \
+ __asm __volatile__ \
+ ("fptan" \
+ : "=t" (__value2), "=u" (__value) : "0" (__x)); \
+ return __value)
+# endif
+#endif /* __FAST_MATH__ */
+
+
+#if __GNUC_PREREQ (3, 4)
+__inline_mathcodeNP2_ (long double, __atan2l, __y, __x,
+ return __builtin_atan2l (__y, __x))
+#else
+# define __atan2_code \
+ register long double __value; \
+ __asm __volatile__ \
+ ("fpatan" \
+ : "=t" (__value) : "0" (__x), "u" (__y) : "st(1)"); \
+ return __value
+# ifdef __FAST_MATH__
+__inline_mathcodeNP2 (atan2, __y, __x, __atan2_code)
+# endif
+__inline_mathcodeNP2_ (long double, __atan2l, __y, __x, __atan2_code)
+#endif
+
+
+#if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
+__inline_mathcodeNP2 (fmod, __x, __y, \
+ register long double __value; \
+ __asm __volatile__ \
+ ("1: fprem\n\t" \
+ "fnstsw %%ax\n\t" \
+ "sahf\n\t" \
+ "jp 1b" \
+ : "=t" (__value) : "0" (__x), "u" (__y) : "ax", "cc"); \
+ return __value)
+#endif
+
+
+#ifdef __FAST_MATH__
+# if !__GNUC_PREREQ (3,3)
+__inline_mathopNP (sqrt, "fsqrt")
+__inline_mathopNP_ (long double, __sqrtl, "fsqrt")
+# define __libc_sqrtl(n) __sqrtl (n)
+# else
+# define __libc_sqrtl(n) __builtin_sqrtl (n)
+# endif
+#endif
+
+#if __GNUC_PREREQ (2, 8)
+__inline_mathcodeNP_ (double, fabs, __x, return __builtin_fabs (__x))
+# if defined __USE_MISC || defined __USE_ISOC99
+__inline_mathcodeNP_ (float, fabsf, __x, return __builtin_fabsf (__x))
+__inline_mathcodeNP_ (long double, fabsl, __x, return __builtin_fabsl (__x))
+# endif
+__inline_mathcodeNP_ (long double, __fabsl, __x, return __builtin_fabsl (__x))
+#else
+__inline_mathop (fabs, "fabs")
+__inline_mathop_ (long double, __fabsl, "fabs")
+#endif
+
+#ifdef __FAST_MATH__
+# if !__GNUC_PREREQ (3, 4)
+/* The argument range of this inline version is reduced. */
+__inline_mathopNP (sin, "fsin")
+/* The argument range of this inline version is reduced. */
+__inline_mathopNP (cos, "fcos")
+
+__inline_mathop_declNP (log, "fldln2; fxch; fyl2x", "0" (__x) : "st(1)")
+# endif
+
+# if !__GNUC_PREREQ (3, 5)
+__inline_mathop_declNP (log10, "fldlg2; fxch; fyl2x", "0" (__x) : "st(1)")
+
+__inline_mathcodeNP (asin, __x, return __atan2l (__x, __libc_sqrtl (1.0 - __x * __x)))
+__inline_mathcodeNP (acos, __x, return __atan2l (__libc_sqrtl (1.0 - __x * __x), __x))
+# endif
+
+# if !__GNUC_PREREQ (3, 4)
+__inline_mathop_declNP (atan, "fld1; fpatan", "0" (__x) : "st(1)")
+# endif
+#endif /* __FAST_MATH__ */
+
+__inline_mathcode_ (long double, __sgn1l, __x, \
+ __extension__ union { long double __xld; unsigned int __xi[3]; } __n = \
+ { __xld: __x }; \
+ __n.__xi[2] = (__n.__xi[2] & 0x8000) | 0x3fff; \
+ __n.__xi[1] = 0x80000000; \
+ __n.__xi[0] = 0; \
+ return __n.__xld)
+
+
+#ifdef __FAST_MATH__
+/* The argument range of the inline version of sinhl is slightly reduced. */
+__inline_mathcodeNP (sinh, __x, \
+ register long double __exm1 = __expm1l (__fabsl (__x)); \
+ return 0.5 * (__exm1 / (__exm1 + 1.0) + __exm1) * __sgn1l (__x))
+
+__inline_mathcodeNP (cosh, __x, \
+ register long double __ex = __expl (__x); \
+ return 0.5 * (__ex + 1.0 / __ex))
+
+__inline_mathcodeNP (tanh, __x, \
+ register long double __exm1 = __expm1l (-__fabsl (__x + __x)); \
+ return __exm1 / (__exm1 + 2.0) * __sgn1l (-__x))
+#endif
+
+__inline_mathcodeNP (floor, __x, \
+ register long double __value; \
+ __volatile unsigned short int __cw; \
+ __volatile unsigned short int __cwtmp; \
+ __asm __volatile ("fnstcw %0" : "=m" (__cw)); \
+ __cwtmp = (__cw & 0xf3ff) | 0x0400; /* rounding down */ \
+ __asm __volatile ("fldcw %0" : : "m" (__cwtmp)); \
+ __asm __volatile ("frndint" : "=t" (__value) : "0" (__x)); \
+ __asm __volatile ("fldcw %0" : : "m" (__cw)); \
+ return __value)
+
+__inline_mathcodeNP (ceil, __x, \
+ register long double __value; \
+ __volatile unsigned short int __cw; \
+ __volatile unsigned short int __cwtmp; \
+ __asm __volatile ("fnstcw %0" : "=m" (__cw)); \
+ __cwtmp = (__cw & 0xf3ff) | 0x0800; /* rounding up */ \
+ __asm __volatile ("fldcw %0" : : "m" (__cwtmp)); \
+ __asm __volatile ("frndint" : "=t" (__value) : "0" (__x)); \
+ __asm __volatile ("fldcw %0" : : "m" (__cw)); \
+ return __value)
+
+#ifdef __FAST_MATH__
+# define __ldexp_code \
+ register long double __value; \
+ __asm __volatile__ \
+ ("fscale" \
+ : "=t" (__value) : "0" (__x), "u" ((long double) __y)); \
+ return __value
+
+__MATH_INLINE double
+__NTH (ldexp (double __x, int __y))
+{
+ __ldexp_code;
+}
+#endif
+
+
+/* Optimized versions for some non-standardized functions. */
+#if defined __USE_ISOC99 || defined __USE_MISC
+
+# ifdef __FAST_MATH__
+__inline_mathcodeNP (expm1, __x, __expm1_code)
+
+/* We cannot rely on M_SQRT being defined. So we do it for ourself
+ here. */
+# define __M_SQRT2 1.41421356237309504880L /* sqrt(2) */
+
+# if !__GNUC_PREREQ (3, 5)
+__inline_mathcodeNP (log1p, __x, \
+ register long double __value; \
+ if (__fabsl (__x) >= 1.0 - 0.5 * __M_SQRT2) \
+ __value = logl (1.0 + __x); \
+ else \
+ __asm __volatile__ \
+ ("fldln2\n\t" \
+ "fxch\n\t" \
+ "fyl2xp1" \
+ : "=t" (__value) : "0" (__x) : "st(1)"); \
+ return __value)
+# endif
+
+
+/* The argument range of the inline version of asinhl is slightly reduced. */
+__inline_mathcodeNP (asinh, __x, \
+ register long double __y = __fabsl (__x); \
+ return (log1pl (__y * __y / (__libc_sqrtl (__y * __y + 1.0) + 1.0) + __y) \
+ * __sgn1l (__x)))
+
+__inline_mathcodeNP (acosh, __x, \
+ return logl (__x + __libc_sqrtl (__x - 1.0) * __libc_sqrtl (__x + 1.0)))
+
+__inline_mathcodeNP (atanh, __x, \
+ register long double __y = __fabsl (__x); \
+ return -0.5 * log1pl (-(__y + __y) / (1.0 + __y)) * __sgn1l (__x))
+
+/* The argument range of the inline version of hypotl is slightly reduced. */
+__inline_mathcodeNP2 (hypot, __x, __y,
+ return __libc_sqrtl (__x * __x + __y * __y))
+
+# if !__GNUC_PREREQ (3, 5)
+__inline_mathcodeNP(logb, __x, \
+ register long double __value; \
+ register long double __junk; \
+ __asm __volatile__ \
+ ("fxtract\n\t" \
+ : "=t" (__junk), "=u" (__value) : "0" (__x)); \
+ return __value)
+# endif
+
+# endif
+#endif
+
+#ifdef __USE_ISOC99
+# ifdef __FAST_MATH__
+
+# if !__GNUC_PREREQ (3, 5)
+__inline_mathop_declNP (log2, "fld1; fxch; fyl2x", "0" (__x) : "st(1)")
+# endif
+
+__MATH_INLINE float
+__NTH (ldexpf (float __x, int __y))
+{
+ __ldexp_code;
+}
+
+__MATH_INLINE long double
+__NTH (ldexpl (long double __x, int __y))
+{
+ __ldexp_code;
+}
+
+__inline_mathcodeNP3 (fma, __x, __y, __z, return (__x * __y) + __z)
+
+__inline_mathopNP (rint, "frndint")
+# endif /* __FAST_MATH__ */
+
+# define __lrint_code \
+ long int __lrintres; \
+ __asm__ __volatile__ \
+ ("fistpl %0" \
+ : "=m" (__lrintres) : "t" (__x) : "st"); \
+ return __lrintres
+__MATH_INLINE long int
+__NTH (lrintf (float __x))
+{
+ __lrint_code;
+}
+__MATH_INLINE long int
+__NTH (lrint (double __x))
+{
+ __lrint_code;
+}
+__MATH_INLINE long int
+__NTH (lrintl (long double __x))
+{
+ __lrint_code;
+}
+# undef __lrint_code
+
+# define __llrint_code \
+ long long int __llrintres; \
+ __asm__ __volatile__ \
+ ("fistpll %0" \
+ : "=m" (__llrintres) : "t" (__x) : "st"); \
+ return __llrintres
+__MATH_INLINE long long int
+__NTH (llrintf (float __x))
+{
+ __llrint_code;
+}
+__MATH_INLINE long long int
+__NTH (llrint (double __x))
+{
+ __llrint_code;
+}
+__MATH_INLINE long long int
+__NTH (llrintl (long double __x))
+{
+ __llrint_code;
+}
+# undef __llrint_code
+
+#endif
+
+
+#ifdef __USE_MISC
+
+# if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
+__inline_mathcodeNP2 (drem, __x, __y, \
+ register double __value; \
+ register int __clobbered; \
+ __asm __volatile__ \
+ ("1: fprem1\n\t" \
+ "fstsw %%ax\n\t" \
+ "sahf\n\t" \
+ "jp 1b" \
+ : "=t" (__value), "=&a" (__clobbered) : "0" (__x), "u" (__y) : "cc"); \
+ return __value)
+# endif
+
+
+/* This function is used in the `isfinite' macro. */
+__MATH_INLINE int
+__NTH (__finite (double __x))
+{
+ return (__extension__
+ (((((union { double __d; int __i[2]; }) {__d: __x}).__i[1]
+ | 0x800fffffu) + 1) >> 31));
+}
+
+/* Miscellaneous functions */
+# ifdef __FAST_MATH__
+__inline_mathcode (__coshm1, __x, \
+ register long double __exm1 = __expm1l (__fabsl (__x)); \
+ return 0.5 * (__exm1 / (__exm1 + 1.0)) * __exm1)
+
+__inline_mathcode (__acosh1p, __x, \
+ return log1pl (__x + __libc_sqrtl (__x) * __libc_sqrtl (__x + 2.0)))
+
+# endif /* __FAST_MATH__ */
+#endif /* __USE_MISC */
+
+/* Undefine some of the large macros which are not used anymore. */
+#undef __atan2_code
+#ifdef __FAST_MATH__
+# undef __expm1_code
+# undef __exp_code
+# undef __sincos_code
+#endif /* __FAST_MATH__ */
+
+#endif /* __NO_MATH_INLINES */
+
+
+/* This code is used internally in the GNU libc. */
+#ifdef __LIBC_INTERNAL_MATH_INLINES
+__inline_mathop (__ieee754_sqrt, "fsqrt")
+__inline_mathcode2 (__ieee754_atan2, __y, __x,
+ register long double __value;
+ __asm __volatile__ ("fpatan\n\t"
+ : "=t" (__value)
+ : "0" (__x), "u" (__y) : "st(1)");
+ return __value;)
+#endif
+
+#endif /* __GNUC__ */
diff --git a/libc/sysdeps/i386/fpu/branred.c b/libc/sysdeps/i386/fpu/branred.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/branred.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/doasin.c b/libc/sysdeps/i386/fpu/doasin.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/doasin.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/dosincos.c b/libc/sysdeps/i386/fpu/dosincos.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/dosincos.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/e_acos.S b/libc/sysdeps/i386/fpu/e_acos.S
new file mode 100644
index 000000000..b9d07b109
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_acos.S
@@ -0,0 +1,21 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_acos.S,v 1.4 1995/05/08 23:44:37 jtc Exp $")
+
+/* acos = atan (sqrt(1 - x^2) / x) */
+ENTRY(__ieee754_acos)
+ fldl 4(%esp) /* x */
+ fld %st /* x : x */
+ fmul %st(0) /* x^2 : x */
+ fld1 /* 1 : x^2 : x */
+ fsubp /* 1 - x^2 : x */
+ fsqrt /* sqrt (1 - x^2) : x */
+ fxch %st(1) /* x : sqrt (1 - x^2) */
+ fpatan /* atan (sqrt(1 - x^2) / x) */
+ ret
+END (__ieee754_acos)
diff --git a/libc/sysdeps/i386/fpu/e_acosf.S b/libc/sysdeps/i386/fpu/e_acosf.S
new file mode 100644
index 000000000..50b13fd1b
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_acosf.S
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+/* acos = atan (sqrt(1 - x^2) / x) */
+ENTRY(__ieee754_acosf)
+ flds 4(%esp) /* x */
+ fld %st
+ fmul %st(0) /* x^2 */
+ fld1
+ fsubp /* 1 - x^2 */
+ fsqrt /* sqrt (1 - x^2) */
+ fxch %st(1)
+ fpatan
+ ret
+END (__ieee754_acosf)
diff --git a/libc/sysdeps/i386/fpu/e_acosh.S b/libc/sysdeps/i386/fpu/e_acosh.S
new file mode 100644
index 000000000..62a232471
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_acosh.S
@@ -0,0 +1,103 @@
+/* ix87 specific implementation of arcsinh.
+ Copyright (C) 1996, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_acosh)
+ movl 8(%esp), %ecx
+ cmpl $0x3ff00000, %ecx
+ jl 5f // < 1 => invalid
+ fldln2 // log(2)
+ fldl 4(%esp) // x : log(2)
+ cmpl $0x41b00000, %ecx
+ ja 3f // x > 2^28
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ cmpl $0x40000000, %ecx
+ ja 4f // x > 2
+
+ // 1 <= x <= 2 => y = log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
+ fsubl MO(one) // x-1 : log(2)
+ fld %st // x-1 : x-1 : log(2)
+ fmul %st(1) // (x-1)^2 : x-1 : log(2)
+ fadd %st(1) // x-1+(x-1)^2 : x-1 : log(2)
+ fadd %st(1) // 2*(x-1)+(x-1)^2 : x-1 : log(2)
+ fsqrt // sqrt(2*(x-1)+(x-1)^2) : x-1 : log(2)
+ faddp // x-1+sqrt(2*(x-1)+(x-1)^2) : log(2)
+ fcoml MO(limit)
+ fnstsw
+ sahf
+ ja 2f
+ fyl2xp1 // log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
+ ret
+
+2: faddl MO(one) // x+sqrt(2*(x-1)+(x-1)^2) : log(2)
+ fyl2x // log(x+sqrt(2*(x-1)+(x-1)^2))
+ ret
+
+ // x > 2^28 => y = log(x) + log(2)
+ .align ALIGNARG(4)
+3: fyl2x // log(x)
+ fldln2 // log(2) : log(x)
+ faddp // log(x)+log(2)
+ ret
+
+ // 2^28 > x > 2 => y = log(2*x - 1/(x+sqrt(x*x-1)))
+ .align ALIGNARG(4)
+4: fld %st // x : x : log(2)
+ fadd %st, %st(1) // x : 2*x : log(2)
+ fld %st // x : x : 2*x : log(2)
+ fmul %st(1) // x^2 : x : 2*x : log(2)
+ fsubl MO(one) // x^2-1 : x : 2*x : log(2)
+ fsqrt // sqrt(x^2-1) : x : 2*x : log(2)
+ faddp // x+sqrt(x^2-1) : 2*x : log(2)
+ fdivrl MO(one) // 1/(x+sqrt(x^2-1)) : 2*x : log(2)
+ fsubrp // 2*x+1/(x+sqrt(x^2)-1) : log(2)
+ fyl2x // log(2*x+1/(x+sqrt(x^2-1)))
+ ret
+
+ // x < 1 => NaN
+ .align ALIGNARG(4)
+5: fldz
+ fdiv %st, %st(0)
+ ret
+END(__ieee754_acosh)
diff --git a/libc/sysdeps/i386/fpu/e_acoshf.S b/libc/sysdeps/i386/fpu/e_acoshf.S
new file mode 100644
index 000000000..1906c6057
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_acoshf.S
@@ -0,0 +1,103 @@
+/* ix87 specific implementation of arcsinh.
+ Copyright (C) 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_acoshf)
+ movl 4(%esp), %ecx
+ cmpl $0x3f800000, %ecx
+ jl 5f // < 1 => invalid
+ fldln2 // log(2)
+ flds 4(%esp) // x : log(2)
+ cmpl $0x47000000, %ecx
+ ja 3f // x > 2^14
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ cmpl $0x40000000, %ecx
+ ja 4f // x > 2
+
+ // 1 <= x <= 2 => y = log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
+ fsubl MO(one) // x-1 : log(2)
+ fld %st // x-1 : x-1 : log(2)
+ fmul %st(1) // (x-1)^2 : x-1 : log(2)
+ fadd %st(1) // x-1+(x-1)^2 : x-1 : log(2)
+ fadd %st(1) // 2*(x-1)+(x-1)^2 : x-1 : log(2)
+ fsqrt // sqrt(2*(x-1)+(x-1)^2) : x-1 : log(2)
+ faddp // x-1+sqrt(2*(x-1)+(x-1)^2) : log(2)
+ fcoml MO(limit)
+ fnstsw
+ sahf
+ ja 2f
+ fyl2xp1 // log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
+ ret
+
+2: faddl MO(one) // x+sqrt(2*(x-1)+(x-1)^2) : log(2)
+ fyl2x // log(x+sqrt(2*(x-1)+(x-1)^2))
+ ret
+
+ // x > 2^14 => y = log(x) + log(2)
+ .align ALIGNARG(4)
+3: fyl2x // log(x)
+ fldln2 // log(2) : log(x)
+ faddp // log(x)+log(2)
+ ret
+
+ // 2^28 > x > 2 => y = log(2*x - 1/(x+sqrt(x*x-1)))
+ .align ALIGNARG(4)
+4: fld %st // x : x : log(2)
+ fadd %st, %st(1) // x : 2*x : log(2)
+ fld %st // x : x : 2*x : log(2)
+ fmul %st(1) // x^2 : x : 2*x : log(2)
+ fsubl MO(one) // x^2-1 : x : 2*x : log(2)
+ fsqrt // sqrt(x^2-1) : x : 2*x : log(2)
+ faddp // x+sqrt(x^2-1) : 2*x : log(2)
+ fdivrl MO(one) // 1/(x+sqrt(x^2-1)) : 2*x : log(2)
+ fsubrp // 2*x+1/(x+sqrt(x^2)-1) : log(2)
+ fyl2x // log(2*x+1/(x+sqrt(x^2-1)))
+ ret
+
+ // x < 1 => NaN
+ .align ALIGNARG(4)
+5: fldz
+ fdiv %st, %st(0)
+ ret
+END(__ieee754_acoshf)
diff --git a/libc/sysdeps/i386/fpu/e_acoshl.S b/libc/sysdeps/i386/fpu/e_acoshl.S
new file mode 100644
index 000000000..c7b548d25
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_acoshl.S
@@ -0,0 +1,110 @@
+/* ix87 specific implementation of arcsinh.
+ Copyright (C) 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ /* Please note that we use double value for 1.0. This number
+ has an exact representation and so we don't get accuracy
+ problems. The advantage is that the code is simpler. */
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_acoshl)
+ movl 12(%esp), %ecx
+ andl $0xffff, %ecx
+ cmpl $0x3fff, %ecx
+ jl 5f // < 1 => invalid
+ fldln2 // log(2)
+ fldt 4(%esp) // x : log(2)
+ cmpl $0x4020, %ecx
+ ja 3f // x > 2^34
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ cmpl $0x4000, %ecx
+ ja 4f // x > 2
+
+ // 1 <= x <= 2 => y = log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
+ fsubl MO(one) // x-1 : log(2)
+ fld %st // x-1 : x-1 : log(2)
+ fmul %st(1) // (x-1)^2 : x-1 : log(2)
+ fadd %st(1) // x-1+(x-1)^2 : x-1 : log(2)
+ fadd %st(1) // 2*(x-1)+(x-1)^2 : x-1 : log(2)
+ fsqrt // sqrt(2*(x-1)+(x-1)^2) : x-1 : log(2)
+ faddp // x-1+sqrt(2*(x-1)+(x-1)^2) : log(2)
+ fcoml MO(limit)
+ fnstsw
+ sahf
+ ja 2f
+ fyl2xp1 // log1p(x-1+sqrt(2*(x-1)+(x-1)^2))
+ ret
+
+2: faddl MO(one) // x+sqrt(2*(x-1)+(x-1)^2) : log(2)
+ fyl2x // log(x+sqrt(2*(x-1)+(x-1)^2))
+ ret
+
+ // x > 2^34 => y = log(x) + log(2)
+ .align ALIGNARG(4)
+3: fyl2x // log(x)
+ fldln2 // log(2) : log(x)
+ faddp // log(x)+log(2)
+ ret
+
+ // 2^34 > x > 2 => y = log(2*x - 1/(x+sqrt(x*x-1)))
+ .align ALIGNARG(4)
+4: fld %st // x : x : log(2)
+ fadd %st, %st(1) // x : 2*x : log(2)
+ fld %st // x : x : 2*x : log(2)
+ fmul %st(1) // x^2 : x : 2*x : log(2)
+ fsubl MO(one) // x^2-1 : x : 2*x : log(2)
+ fsqrt // sqrt(x^2-1) : x : 2*x : log(2)
+ faddp // x+sqrt(x^2-1) : 2*x : log(2)
+ fdivrl MO(one) // 1/(x+sqrt(x^2-1)) : 2*x : log(2)
+ fsubrp // 2*x+1/(x+sqrt(x^2)-1) : log(2)
+ fyl2x // log(2*x+1/(x+sqrt(x^2-1)))
+ ret
+
+ // x < 1 => NaN
+ .align ALIGNARG(4)
+5: fldz
+ fdiv %st, %st(0)
+ ret
+END(__ieee754_acoshl)
diff --git a/libc/sysdeps/i386/fpu/e_acosl.c b/libc/sysdeps/i386/fpu/e_acosl.c
new file mode 100644
index 000000000..0c3e03945
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_acosl.c
@@ -0,0 +1,25 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <math_private.h>
+
+long double
+__ieee754_acosl (long double x)
+{
+ long double res;
+
+ /* acosl = atanl (sqrtl(1 - x^2) / x) */
+ asm ( "fld %%st\n"
+ "fmul %%st(0)\n" /* x^2 */
+ "fld1\n"
+ "fsubp\n" /* 1 - x^2 */
+ "fsqrt\n" /* sqrtl (1 - x^2) */
+ "fxch %%st(1)\n"
+ "fpatan"
+ : "=t" (res) : "0" (x) : "st(1)");
+ return res;
+}
diff --git a/libc/sysdeps/i386/fpu/e_asin.S b/libc/sysdeps/i386/fpu/e_asin.S
new file mode 100644
index 000000000..945e30824
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_asin.S
@@ -0,0 +1,20 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_asin.S,v 1.4 1995/05/08 23:45:40 jtc Exp $")
+
+/* asin = atan (x / sqrt(1 - x^2)) */
+ENTRY(__ieee754_asin)
+ fldl 4(%esp) /* x */
+ fld %st
+ fmul %st(0) /* x^2 */
+ fld1
+ fsubp /* 1 - x^2 */
+ fsqrt /* sqrt (1 - x^2) */
+ fpatan
+ ret
+END (__ieee754_asin)
diff --git a/libc/sysdeps/i386/fpu/e_asinf.S b/libc/sysdeps/i386/fpu/e_asinf.S
new file mode 100644
index 000000000..d450e9a74
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_asinf.S
@@ -0,0 +1,21 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+/* asin = atan (x / sqrt(1 - x^2)) */
+ENTRY(__ieee754_asinf)
+ flds 4(%esp) /* x */
+ fld %st
+ fmul %st(0) /* x^2 */
+ fld1
+ fsubp /* 1 - x^2 */
+ fsqrt /* sqrt (1 - x^2) */
+ fpatan
+ ret
+END (__ieee754_asinf)
diff --git a/libc/sysdeps/i386/fpu/e_atan2.S b/libc/sysdeps/i386/fpu/e_atan2.S
new file mode 100644
index 000000000..8df04e485
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_atan2.S
@@ -0,0 +1,15 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_atan2.S,v 1.4 1995/05/08 23:46:28 jtc Exp $")
+
+ENTRY(__ieee754_atan2)
+ fldl 4(%esp)
+ fldl 12(%esp)
+ fpatan
+ ret
+END (__ieee754_atan2)
diff --git a/libc/sysdeps/i386/fpu/e_atan2f.S b/libc/sysdeps/i386/fpu/e_atan2f.S
new file mode 100644
index 000000000..fc6621f18
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_atan2f.S
@@ -0,0 +1,15 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_atan2f.S,v 1.1 1995/05/08 23:35:10 jtc Exp $")
+
+ENTRY(__ieee754_atan2f)
+ flds 4(%esp)
+ flds 8(%esp)
+ fpatan
+ ret
+END (__ieee754_atan2f)
diff --git a/libc/sysdeps/i386/fpu/e_atan2l.c b/libc/sysdeps/i386/fpu/e_atan2l.c
new file mode 100644
index 000000000..19a2a6062
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_atan2l.c
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <math_private.h>
+
+long double
+__ieee754_atan2l (long double y, long double x)
+{
+ long double res;
+
+ asm ("fpatan" : "=t" (res) : "u" (y), "0" (x) : "st(1)");
+
+ return res;
+}
diff --git a/libc/sysdeps/i386/fpu/e_atanh.S b/libc/sysdeps/i386/fpu/e_atanh.S
new file mode 100644
index 000000000..3566ec6ef
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_atanh.S
@@ -0,0 +1,116 @@
+/* ix87 specific implementation of arctanh function.
+ Copyright (C) 1996, 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(half,@object)
+half: .double 0.5
+ ASM_SIZE_DIRECTIVE(half)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+ ASM_TYPE_DIRECTIVE(ln2_2,@object)
+ln2_2: .tfloat 0.3465735902799726547086160
+ ASM_SIZE_DIRECTIVE(ln2_2)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_atanh)
+ movl 8(%esp), %ecx
+
+ movl %ecx, %eax
+ andl $0x7fffffff, %eax
+ cmpl $0x7ff00000, %eax
+ jae 5f
+7:
+
+#ifdef PIC
+ call 1f
+ cfi_adjust_cfa_offset (4)
+1: popl %edx
+ cfi_adjust_cfa_offset (-4)
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+
+ andl $0x80000000, %ecx // ECX == 0 iff X >= 0
+
+ fldt MO(ln2_2) // 0.5*ln2
+ xorl %ecx, 8(%esp)
+ fldl 4(%esp) // |x| : 0.5*ln2
+ fcoml MO(half) // |x| : 0.5*ln2
+ fld %st // |x| : |x| : 0.5*ln2
+ fnstsw // |x| : |x| : 0.5*ln2
+ sahf
+ jae 2f
+ fadd %st, %st(1) // |x| : 2*|x| : 0.5*ln2
+ fld %st // |x| : |x| : 2*|x| : 0.5*ln2
+ fsubrl MO(one) // 1-|x| : |x| : 2*|x| : 0.5*ln2
+ fxch // |x| : 1-|x| : 2*|x| : 0.5*ln2
+ fmul %st(2) // 2*|x|^2 : 1-|x| : 2*|x| : 0.5*ln2
+ fdivp // (2*|x|^2)/(1-|x|) : 2*|x| : 0.5*ln2
+ faddp // 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+ fcoml MO(limit) // 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+ fnstsw // 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+ sahf
+ jae 4f
+ fyl2xp1 // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
+ jecxz 3f
+ fchs // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
+3: ret
+
+ .align ALIGNARG(4)
+4: faddl MO(one) // 1+2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+ fyl2x // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
+ jecxz 3f
+ fchs // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
+3: ret
+
+ .align ALIGNARG(4)
+2: faddl MO(one) // 1+|x| : |x| : 0.5*ln2
+ fxch // |x| : 1+|x| : 0.5*ln2
+ fsubrl MO(one) // 1-|x| : 1+|x| : 0.5*ln2
+ fdivrp // (1+|x|)/(1-|x|) : 0.5*ln2
+ fyl2x // 0.5*ln2*ld((1+|x|)/(1-|x|))
+ jecxz 3f
+ fchs // 0.5*ln2*ld((1+x)/(1-x))
+3: ret
+
+ // x == NaN or ±Inf
+5: ja 6f
+ cmpl $0, 4(%esp)
+ je 7b
+6: fldl 4(%esp)
+ ret
+END(__ieee754_atanh)
diff --git a/libc/sysdeps/i386/fpu/e_atanhf.S b/libc/sysdeps/i386/fpu/e_atanhf.S
new file mode 100644
index 000000000..10ce6aed9
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_atanhf.S
@@ -0,0 +1,109 @@
+/* ix87 specific implementation of arctanh function.
+ Copyright (C) 1996, 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(half,@object)
+half: .double 0.5
+ ASM_SIZE_DIRECTIVE(half)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(ln2_2,@object)
+ln2_2: .tfloat 0.3465735902799726547086160
+ ASM_SIZE_DIRECTIVE(ln2_2)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_atanhf)
+ movl 4(%esp), %ecx
+
+ movl %ecx, %eax
+ andl $0x7fffffff, %eax
+ cmpl $0x7f800000, %eax
+ ja 5f
+
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+
+ andl $0x80000000, %ecx // ECX == 0 iff X >= 0
+
+ fldt MO(ln2_2) // 0.5*ln2
+ xorl %ecx, 4(%esp)
+ flds 4(%esp) // |x| : 0.5*ln2
+ fcoml MO(half) // |x| : 0.5*ln2
+ fld %st(0) // |x| : |x| : 0.5*ln2
+ fnstsw // |x| : |x| : 0.5*ln2
+ sahf
+ jae 2f
+ fadd %st, %st(1) // |x| : 2*|x| : 0.5*ln2
+ fld %st // |x| : |x| : 2*|x| : 0.5*ln2
+ fsubrl MO(one) // 1-|x| : |x| : 2*|x| : 0.5*ln2
+ fxch // |x| : 1-|x| : 2*|x| : 0.5*ln2
+ fmul %st(2) // 2*|x|^2 : 1-|x| : 2*|x| : 0.5*ln2
+ fdivp // (2*|x|^2)/(1-|x|) : 2*|x| : 0.5*ln2
+ faddp // 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+ fcoml MO(limit) // 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+ fnstsw // 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+ sahf
+ jae 4f
+ fyl2xp1 // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
+ jecxz 3f
+ fchs // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
+3: ret
+
+ .align ALIGNARG(4)
+4: faddl MO(one) // 1+2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+ fyl2x // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
+ jecxz 3f
+ fchs // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
+3: ret
+
+ .align ALIGNARG(4)
+2: faddl MO(one) // 1+|x| : |x| : 0.5*ln2
+ fxch // |x| : 1+|x| : 0.5*ln2
+ fsubrl MO(one) // 1-|x| : 1+|x| : 0.5*ln2
+ fdivrp // (1+|x|)/(1-|x|) : 0.5*ln2
+ fyl2x // 0.5*ln2*ld((1+|x|)/(1-|x|))
+ jecxz 3f
+ fchs // 0.5*ln2*ld((1+x)/(1-x))
+3: ret
+
+ // x == NaN
+5: flds 4(%esp)
+ ret
+END(__ieee754_atanhf)
diff --git a/libc/sysdeps/i386/fpu/e_atanhl.S b/libc/sysdeps/i386/fpu/e_atanhl.S
new file mode 100644
index 000000000..8618c3fb3
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_atanhl.S
@@ -0,0 +1,120 @@
+/* ix87 specific implementation of arctanh function.
+ Copyright (C) 1996, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ /* Please note that we use double values for 0.5 and 1.0. These
+ numbers have exact representations and so we don't get accuracy
+ problems. The advantage is that the code is simpler. */
+ ASM_TYPE_DIRECTIVE(half,@object)
+half: .double 0.5
+ ASM_SIZE_DIRECTIVE(half)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(ln2_2,@object)
+ln2_2: .tfloat 0.3465735902799726547086160
+ ASM_SIZE_DIRECTIVE(ln2_2)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_atanhl)
+ movl 12(%esp), %ecx
+
+ movl %ecx, %eax
+ andl $0x7fff, %eax
+ cmpl $0x7fff, %eax
+ je 5f
+7:
+
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+
+ andl $0x8000, %ecx // ECX == 0 iff X >= 0
+
+ fldt MO(ln2_2) // 0.5*ln2
+ xorl %ecx, 12(%esp)
+ fldt 4(%esp) // |x| : 0.5*ln2
+ fcoml MO(half) // |x| : 0.5*ln2
+ fld %st(0) // |x| : |x| : 0.5*ln2
+ fnstsw // |x| : |x| : 0.5*ln2
+ sahf
+ jae 2f
+ fadd %st, %st(1) // |x| : 2*|x| : 0.5*ln2
+ fld %st // |x| : |x| : 2*|x| : 0.5*ln2
+ fsubrl MO(one) // 1-|x| : |x| : 2*|x| : 0.5*ln2
+ fxch // |x| : 1-|x| : 2*|x| : 0.5*ln2
+ fmul %st(2) // 2*|x|^2 : 1-|x| : 2*|x| : 0.5*ln2
+ fdivp // (2*|x|^2)/(1-|x|) : 2*|x| : 0.5*ln2
+ faddp // 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+ fcoml MO(limit) // 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+ fnstsw // 2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+ sahf
+ jae 4f
+ fyl2xp1 // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
+ jecxz 3f
+ fchs // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
+3: ret
+
+ .align ALIGNARG(4)
+4: faddl MO(one) // 1+2*|x|+(2*|x|^2)/(1-|x|) : 0.5*ln2
+ fyl2x // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
+ jecxz 3f
+ fchs // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
+3: ret
+
+ .align ALIGNARG(4)
+2: faddl MO(one) // 1+|x| : |x| : 0.5*ln2
+ fxch // |x| : 1+|x| : 0.5*ln2
+ fsubrl MO(one) // 1-|x| : 1+|x| : 0.5*ln2
+ fdivrp // (1+|x|)/(1-|x|) : 0.5*ln2
+ fyl2x // 0.5*ln2*ld((1+|x|)/(1-|x|))
+ jecxz 3f
+ fchs // 0.5*ln2*ld((1+x)/(1-x))
+3: ret
+
+ // x == NaN or ±Inf
+5: cmpl $0x80000000, 8(%esp)
+ ja 6f
+ cmpl $0, 4(%esp)
+ je 7b
+6: fldt 4(%esp)
+ ret
+END(__ieee754_atanhl)
diff --git a/libc/sysdeps/i386/fpu/e_exp.S b/libc/sysdeps/i386/fpu/e_exp.S
new file mode 100644
index 000000000..4a75fa1d1
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_exp.S
@@ -0,0 +1,41 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_exp.S,v 1.7 1996/07/03 17:31:28 jtc Exp $")
+
+/* e^x = 2^(x * log2(e)) */
+ENTRY(__ieee754_exp)
+ fldl 4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+ fldl2e
+ fmulp /* x * log2(e) */
+ fld %st
+ frndint /* int(x * log2(e)) */
+ fsubr %st,%st(1) /* fract(x * log2(e)) */
+ fxch
+ f2xm1 /* 2^(fract(x * log2(e))) - 1 */
+ fld1
+ faddp /* 2^(fract(x * log2(e))) */
+ fscale /* e^x */
+ fstp %st(1)
+ ret
+
+1: testl $0x200, %eax /* Test sign. */
+ jz 2f /* If positive, jump. */
+ fstp %st
+ fldz /* Set result to 0. */
+2: ret
+END (__ieee754_exp)
diff --git a/libc/sysdeps/i386/fpu/e_exp10.S b/libc/sysdeps/i386/fpu/e_exp10.S
new file mode 100644
index 000000000..6bfcdbb72
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_exp10.S
@@ -0,0 +1,38 @@
+/*
+ * Written by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+/* 10^x = 2^(x * log2(10)) */
+ENTRY(__ieee754_exp10)
+ fldl 4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+ fldl2t
+ fmulp /* x * log2(10) */
+ fld %st
+ frndint /* int(x * log2(10)) */
+ fsubr %st,%st(1) /* fract(x * log2(10)) */
+ fxch
+ f2xm1 /* 2^(fract(x * log2(10))) - 1 */
+ fld1
+ faddp /* 2^(fract(x * log2(10))) */
+ fscale /* e^x */
+ fstp %st(1)
+ ret
+
+1: testl $0x200, %eax /* Test sign. */
+ jz 2f /* If positive, jump. */
+ fstp %st
+ fldz /* Set result to 0. */
+2: ret
+END (__ieee754_exp10)
diff --git a/libc/sysdeps/i386/fpu/e_exp10f.S b/libc/sysdeps/i386/fpu/e_exp10f.S
new file mode 100644
index 000000000..4791b99af
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_exp10f.S
@@ -0,0 +1,38 @@
+/*
+ * Written by Ulrich Drepper.
+ */
+
+#include <machine/asm.h>
+
+/* e^x = 2^(x * log2(10)) */
+ENTRY(__ieee754_exp10f)
+ flds 4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+ fldl2t
+ fmulp /* x * log2(10) */
+ fld %st
+ frndint /* int(x * log2(10)) */
+ fsubr %st,%st(1) /* fract(x * log2(10)) */
+ fxch
+ f2xm1 /* 2^(fract(x * log2(10))) - 1 */
+ fld1
+ faddp /* 2^(fract(x * log2(10))) */
+ fscale /* e^x */
+ fstp %st(1)
+ ret
+
+1: testl $0x200, %eax /* Test sign. */
+ jz 2f /* If positive, jump. */
+ fstp %st
+ fldz /* Set result to 0. */
+2: ret
+END (__ieee754_exp10f)
diff --git a/libc/sysdeps/i386/fpu/e_exp10l.S b/libc/sysdeps/i386/fpu/e_exp10l.S
new file mode 100644
index 000000000..71f0da792
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_exp10l.S
@@ -0,0 +1,38 @@
+/*
+ * Written by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+/* e^x = 2^(x * log2l(10)) */
+ENTRY(__ieee754_exp10l)
+ fldt 4(%esp)
+/* I added the following ugly construct because expl(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+ fldl2t
+ fmulp /* x * log2(10) */
+ fld %st
+ frndint /* int(x * log2(10)) */
+ fsubr %st,%st(1) /* fract(x * log2(10)) */
+ fxch
+ f2xm1 /* 2^(fract(x * log2(10))) - 1 */
+ fld1
+ faddp /* 2^(fract(x * log2(10))) */
+ fscale /* e^x */
+ fstp %st(1)
+ ret
+
+1: testl $0x200, %eax /* Test sign. */
+ jz 2f /* If positive, jump. */
+ fstp %st
+ fldz /* Set result to 0. */
+2: ret
+END (__ieee754_exp10l)
diff --git a/libc/sysdeps/i386/fpu/e_exp2.S b/libc/sysdeps/i386/fpu/e_exp2.S
new file mode 100644
index 000000000..778c0c0eb
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_exp2.S
@@ -0,0 +1,37 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__ieee754_exp2)
+ fldl 4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+ fld %st
+ frndint /* int(x) */
+ fsubr %st,%st(1) /* fract(x) */
+ fxch
+ f2xm1 /* 2^(fract(x)) - 1 */
+ fld1
+ faddp /* 2^(fract(x)) */
+ fscale /* e^x */
+ fstp %st(1)
+ ret
+
+1: testl $0x200, %eax /* Test sign. */
+ jz 2f /* If positive, jump. */
+ fstp %st
+ fldz /* Set result to 0. */
+2: ret
+END (__ieee754_exp2)
diff --git a/libc/sysdeps/i386/fpu/e_exp2f.S b/libc/sysdeps/i386/fpu/e_exp2f.S
new file mode 100644
index 000000000..c2d1af1af
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_exp2f.S
@@ -0,0 +1,37 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__ieee754_exp2f)
+ flds 4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+ fld %st
+ frndint /* int(x) */
+ fsubr %st,%st(1) /* fract(x) */
+ fxch
+ f2xm1 /* 2^(fract(x)) - 1 */
+ fld1
+ faddp /* 2^(fract(x)) */
+ fscale /* e^x */
+ fstp %st(1)
+ ret
+
+1: testl $0x200, %eax /* Test sign. */
+ jz 2f /* If positive, jump. */
+ fstp %st
+ fldz /* Set result to 0. */
+2: ret
+END (__ieee754_exp2f)
diff --git a/libc/sysdeps/i386/fpu/e_exp2l.S b/libc/sysdeps/i386/fpu/e_exp2l.S
new file mode 100644
index 000000000..fa1fdc923
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_exp2l.S
@@ -0,0 +1,37 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__ieee754_exp2l)
+ fldt 4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+ fld %st
+ frndint /* int(x) */
+ fsubr %st,%st(1) /* fract(x) */
+ fxch
+ f2xm1 /* 2^(fract(x)) - 1 */
+ fld1
+ faddp /* 2^(fract(x)) */
+ fscale /* e^x */
+ fstp %st(1)
+ ret
+
+1: testl $0x200, %eax /* Test sign. */
+ jz 2f /* If positive, jump. */
+ fstp %st
+ fldz /* Set result to 0. */
+2: ret
+END (__ieee754_exp2l)
diff --git a/libc/sysdeps/i386/fpu/e_expf.S b/libc/sysdeps/i386/fpu/e_expf.S
new file mode 100644
index 000000000..5fd49b89f
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_expf.S
@@ -0,0 +1,42 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+/* e^x = 2^(x * log2(e)) */
+ENTRY(__ieee754_expf)
+ flds 4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+ fldl2e
+ fmulp /* x * log2(e) */
+ fld %st
+ frndint /* int(x * log2(e)) */
+ fsubr %st,%st(1) /* fract(x * log2(e)) */
+ fxch
+ f2xm1 /* 2^(fract(x * log2(e))) - 1 */
+ fld1
+ faddp /* 2^(fract(x * log2(e))) */
+ fscale /* e^x */
+ fstp %st(1)
+ ret
+
+1: testl $0x200, %eax /* Test sign. */
+ jz 2f /* If positive, jump. */
+ fstp %st
+ fldz /* Set result to 0. */
+2: ret
+END (__ieee754_expf)
diff --git a/libc/sysdeps/i386/fpu/e_expl.c b/libc/sysdeps/i386/fpu/e_expl.c
new file mode 100644
index 000000000..2240ceac4
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_expl.c
@@ -0,0 +1,77 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+/*
+ * The 8087 method for the exponential function is to calculate
+ * exp(x) = 2^(x log2(e))
+ * after separating integer and fractional parts
+ * x log2(e) = i + f, |f| <= .5
+ * 2^i is immediate but f needs to be precise for long double accuracy.
+ * Suppress range reduction error in computing f by the following.
+ * Separate x into integer and fractional parts
+ * x = xi + xf, |xf| <= .5
+ * Separate log2(e) into the sum of an exact number c0 and small part c1.
+ * c0 + c1 = log2(e) to extra precision
+ * Then
+ * f = (c0 xi - i) + c0 xf + c1 x
+ * where c0 xi is exact and so also is (c0 xi - i).
+ * -- moshier@na-net.ornl.gov
+ */
+
+#include <math_private.h>
+
+static const long double c0 = 1.44268798828125L;
+static const long double c1 = 7.05260771340735992468e-6L;
+
+long double
+__ieee754_expl (long double x)
+{
+ long double res;
+
+/* I added the following ugly construct because expl(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ asm ("fxam\n\t" /* Is NaN or +-Inf? */
+ "fstsw %%ax\n\t"
+ "movb $0x45, %%dh\n\t"
+ "andb %%ah, %%dh\n\t"
+ "cmpb $0x05, %%dh\n\t"
+ "je 1f\n\t" /* Is +-Inf, jump. */
+ "fldl2e\n\t" /* 1 log2(e) */
+ "fmul %%st(1),%%st\n\t" /* 1 x log2(e) */
+ "frndint\n\t" /* 1 i */
+ "fld %%st(1)\n\t" /* 2 x */
+ "frndint\n\t" /* 2 xi */
+ "fld %%st(1)\n\t" /* 3 i */
+ "fldt %2\n\t" /* 4 c0 */
+ "fld %%st(2)\n\t" /* 5 xi */
+ "fmul %%st(1),%%st\n\t" /* 5 c0 xi */
+ "fsubp %%st,%%st(2)\n\t" /* 4 f = c0 xi - i */
+ "fld %%st(4)\n\t" /* 5 x */
+ "fsub %%st(3),%%st\n\t" /* 5 xf = x - xi */
+ "fmulp %%st,%%st(1)\n\t" /* 4 c0 xf */
+ "faddp %%st,%%st(1)\n\t" /* 3 f = f + c0 xf */
+ "fldt %3\n\t" /* 4 */
+ "fmul %%st(4),%%st\n\t" /* 4 c1 * x */
+ "faddp %%st,%%st(1)\n\t" /* 3 f = f + c1 * x */
+ "f2xm1\n\t" /* 3 2^(fract(x * log2(e))) - 1 */
+ "fld1\n\t" /* 4 1.0 */
+ "faddp\n\t" /* 3 2^(fract(x * log2(e))) */
+ "fstp %%st(1)\n\t" /* 2 */
+ "fscale\n\t" /* 2 scale factor is st(1); e^x */
+ "fstp %%st(1)\n\t" /* 1 */
+ "fstp %%st(1)\n\t" /* 0 */
+ "jmp 2f\n\t"
+ "1:\ttestl $0x200, %%eax\n\t" /* Test sign. */
+ "jz 2f\n\t" /* If positive, jump. */
+ "fstp %%st\n\t"
+ "fldz\n\t" /* Set result to 0. */
+ "2:\t\n"
+ : "=t" (res) : "0" (x), "m" (c0), "m" (c1) : "ax", "dx");
+ return res;
+}
diff --git a/libc/sysdeps/i386/fpu/e_fmod.S b/libc/sysdeps/i386/fpu/e_fmod.S
new file mode 100644
index 000000000..4cf6e9205
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_fmod.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_fmod.S,v 1.4 1995/05/08 23:47:56 jtc Exp $")
+
+ENTRY(__ieee754_fmod)
+ fldl 12(%esp)
+ fldl 4(%esp)
+1: fprem
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ ret
+END (__ieee754_fmod)
diff --git a/libc/sysdeps/i386/fpu/e_fmodf.S b/libc/sysdeps/i386/fpu/e_fmodf.S
new file mode 100644
index 000000000..bbce40976
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_fmodf.S
@@ -0,0 +1,20 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ieee754_fmodf)
+ flds 8(%esp)
+ flds 4(%esp)
+1: fprem
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ ret
+END(__ieee754_fmodf)
diff --git a/libc/sysdeps/i386/fpu/e_fmodl.c b/libc/sysdeps/i386/fpu/e_fmodl.c
new file mode 100644
index 000000000..c7c9a6045
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_fmodl.c
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <math_private.h>
+
+long double
+__ieee754_fmodl (long double x, long double y)
+{
+ long double res;
+
+ asm ("1:\tfprem\n"
+ "fstsw %%ax\n"
+ "sahf\n"
+ "jp 1b\n"
+ "fstp %%st(1)"
+ : "=t" (res) : "0" (x), "u" (y) : "ax", "st(1)");
+ return res;
+}
diff --git a/libc/sysdeps/i386/fpu/e_hypot.S b/libc/sysdeps/i386/fpu/e_hypot.S
new file mode 100644
index 000000000..043585730
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_hypot.S
@@ -0,0 +1,62 @@
+/* Compute the hypothenuse of X and Y.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__ieee754_hypot)
+ fldl 4(%esp) // x
+ fxam
+ fnstsw
+ fldl 12(%esp) // y : x
+ movb %ah, %ch
+ fxam
+ fnstsw
+ movb %ah, %al
+ orb %ch, %ah
+ sahf
+ jc 1f
+ fmul %st(0) // y * y : x
+ fxch // x : y * y
+ fmul %st(0) // x * x : y * y
+ faddp // x * x + y * y
+ fsqrt
+2: ret
+
+ // We have to test whether any of the parameters is Inf.
+ // In this case the result is infinity.
+1: andb $0x45, %al
+ cmpb $5, %al
+ je 3f // jump if y is Inf
+ andb $0x45, %ch
+ cmpb $5, %ch
+ jne 4f // jump if x is not Inf
+ fxch
+3: fstp %st(1)
+ fabs
+ jmp 2b
+
+4: testb $1, %al
+ jnz 5f // y is NaN
+ fxch
+5: fstp %st(1)
+ jmp 2b
+
+END(__ieee754_hypot)
diff --git a/libc/sysdeps/i386/fpu/e_hypotf.S b/libc/sysdeps/i386/fpu/e_hypotf.S
new file mode 100644
index 000000000..5967dae21
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_hypotf.S
@@ -0,0 +1,62 @@
+/* Compute the hypothenuse of X and Y.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__ieee754_hypotf)
+ flds 4(%esp) // x
+ fxam
+ fnstsw
+ flds 8(%esp) // y : x
+ movb %ah, %ch
+ fxam
+ fnstsw
+ movb %ah, %al
+ orb %ch, %ah
+ sahf
+ jc 1f
+ fmul %st(0) // y * y : x
+ fxch // x : y * y
+ fmul %st(0) // x * x : y * y
+ faddp // x * x + y * y
+ fsqrt
+2: ret
+
+ // We have to test whether any of the parameters is Inf.
+ // In this case the result is infinity.
+1: andb $0x45, %al
+ cmpb $5, %al
+ je 3f // jump if y is Inf
+ andb $0x45, %ch
+ cmpb $5, %ch
+ jne 4f // jump if x is not Inf
+ fxch
+3: fstp %st(1)
+ fabs
+ jmp 2b
+
+4: testb $1, %al
+ jnz 5f // y is NaN
+ fxch
+5: fstp %st(1)
+ jmp 2b
+
+END(__ieee754_hypotf)
diff --git a/libc/sysdeps/i386/fpu/e_log.S b/libc/sysdeps/i386/fpu/e_log.S
new file mode 100644
index 000000000..5604e638f
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_log.S
@@ -0,0 +1,57 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_log.S,v 1.4 1995/05/08 23:48:39 jtc Exp $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_log)
+ fldln2 // log(2)
+ fldl 4(%esp) // x : log(2)
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ fld %st // x : x : log(2)
+ fsubl MO(one) // x-1 : x : log(2)
+ fld %st // x-1 : x-1 : x : log(2)
+ fabs // |x-1| : x-1 : x : log(2)
+ fcompl MO(limit) // x-1 : x : log(2)
+ fnstsw // x-1 : x : log(2)
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : log(2)
+ fyl2xp1 // log(x)
+ ret
+
+2: fstp %st(0) // x : log(2)
+ fyl2x // log(x)
+ ret
+END (__ieee754_log)
diff --git a/libc/sysdeps/i386/fpu/e_log10.S b/libc/sysdeps/i386/fpu/e_log10.S
new file mode 100644
index 000000000..525f08c96
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_log10.S
@@ -0,0 +1,66 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_log10.S,v 1.4 1995/05/08 23:49:24 jtc Exp $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_log10)
+ fldlg2 // log10(2)
+ fldl 4(%esp) // x : log10(2)
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ fxam
+ fnstsw
+ fld %st // x : x : log10(2)
+ sahf
+ jc 3f // in case x is NaN or ±Inf
+4: fsubl MO(one) // x-1 : x : log10(2)
+ fld %st // x-1 : x-1 : x : log10(2)
+ fabs // |x-1| : x-1 : x : log10(2)
+ fcompl MO(limit) // x-1 : x : log10(2)
+ fnstsw // x-1 : x : log10(2)
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : log10(2)
+ fyl2xp1 // log10(x)
+ ret
+
+2: fstp %st(0) // x : log10(2)
+ fyl2x // log10(x)
+ ret
+
+3: jp 4b // in case x is ±Inf
+ fstp %st(1)
+ fstp %st(1)
+ ret
+END (__ieee754_log10)
diff --git a/libc/sysdeps/i386/fpu/e_log10f.S b/libc/sysdeps/i386/fpu/e_log10f.S
new file mode 100644
index 000000000..da5069d58
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_log10f.S
@@ -0,0 +1,67 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_log10f)
+ fldlg2 // log10(2)
+ flds 4(%esp) // x : log10(2)
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ fxam
+ fnstsw
+ fld %st // x : x : log10(2)
+ sahf
+ jc 3f // in case x is NaN or ±Inf
+4: fsubl MO(one) // x-1 : x : log10(2)
+ fld %st // x-1 : x-1 : x : log10(2)
+ fabs // |x-1| : x-1 : x : log10(2)
+ fcompl MO(limit) // x-1 : x : log10(2)
+ fnstsw // x-1 : x : log10(2)
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : log10(2)
+ fyl2xp1 // log10(x)
+ ret
+
+2: fstp %st(0) // x : log10(2)
+ fyl2x // log10(x)
+ ret
+
+3: jp 4b // in case x is ±Inf
+ fstp %st(1)
+ fstp %st(1)
+ ret
+END (__ieee754_log10f)
diff --git a/libc/sysdeps/i386/fpu/e_log10l.S b/libc/sysdeps/i386/fpu/e_log10l.S
new file mode 100644
index 000000000..3811516be
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_log10l.S
@@ -0,0 +1,68 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_log10l)
+ fldlg2 // log10(2)
+ fldt 4(%esp) // x : log10(2)
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ fxam
+ fnstsw
+ fld %st // x : x : log10(2)
+ sahf
+ jc 3f // in case x is NaN or ±Inf
+4: fsubl MO(one) // x-1 : x : log10(2)
+ fld %st // x-1 : x-1 : x : log10(2)
+ fabs // |x-1| : x-1 : x : log10(2)
+ fcompl MO(limit) // x-1 : x : log10(2)
+ fnstsw // x-1 : x : log10(2)
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : log10(2)
+ fyl2xp1 // log10(x)
+ ret
+
+2: fstp %st(0) // x : log10(2)
+ fyl2x // log10(x)
+ ret
+
+3: jp 4b // in case x is ±Inf
+ fstp %st(1)
+ fstp %st(1)
+ ret
+END(__ieee754_log10l)
diff --git a/libc/sysdeps/i386/fpu/e_log2.S b/libc/sysdeps/i386/fpu/e_log2.S
new file mode 100644
index 000000000..d80bf8023
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_log2.S
@@ -0,0 +1,65 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_log2)
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ fldl MO(one)
+ fldl 4(%esp) // x : 1
+ fxam
+ fnstsw
+ fld %st // x : x : 1
+ sahf
+ jc 3f // in case x is NaN or ±Inf
+4: fsub %st(2), %st // x-1 : x : 1
+ fld %st // x-1 : x-1 : x : 1
+ fabs // |x-1| : x-1 : x : 1
+ fcompl MO(limit) // x-1 : x : 1
+ fnstsw // x-1 : x : 1
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : 1
+ fyl2xp1 // log(x)
+ ret
+
+2: fstp %st(0) // x : 1
+ fyl2x // log(x)
+ ret
+
+3: jp 4b // in case x is ±Inf
+ fstp %st(1)
+ fstp %st(1)
+ ret
+END (__ieee754_log2)
diff --git a/libc/sysdeps/i386/fpu/e_log2f.S b/libc/sysdeps/i386/fpu/e_log2f.S
new file mode 100644
index 000000000..9eb7b2a82
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_log2f.S
@@ -0,0 +1,65 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_log2f)
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ fldl MO(one)
+ flds 4(%esp) // x : 1
+ fxam
+ fnstsw
+ fld %st // x : x : 1
+ sahf
+ jc 3f // in case x is NaN or ±Inf
+4: fsub %st(2), %st // x-1 : x : 1
+ fld %st // x-1 : x-1 : x : 1
+ fabs // |x-1| : x-1 : x : 1
+ fcompl MO(limit) // x-1 : x : 1
+ fnstsw // x-1 : x : 1
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : 1
+ fyl2xp1 // log(x)
+ ret
+
+2: fstp %st(0) // x : 1
+ fyl2x // log(x)
+ ret
+
+3: jp 4b // in case x is ±Inf
+ fstp %st(1)
+ fstp %st(1)
+ ret
+END (__ieee754_log2f)
diff --git a/libc/sysdeps/i386/fpu/e_log2l.S b/libc/sysdeps/i386/fpu/e_log2l.S
new file mode 100644
index 000000000..9de08f5de
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_log2l.S
@@ -0,0 +1,65 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_log2l)
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ fldl MO(one)
+ fldt 4(%esp) // x : 1
+ fxam
+ fnstsw
+ fld %st // x : x : 1
+ sahf
+ jc 3f // in case x is NaN or ±Inf
+4: fsub %st(2), %st // x-1 : x : 1
+ fld %st // x-1 : x-1 : x : 1
+ fabs // |x-1| : x-1 : x : 1
+ fcompl MO(limit) // x-1 : x : 1
+ fnstsw // x-1 : x : 1
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : 1
+ fyl2xp1 // log(x)
+ ret
+
+2: fstp %st(0) // x : 1
+ fyl2x // log(x)
+ ret
+
+3: jp 4b // in case x is ±Inf
+ fstp %st(1)
+ fstp %st(1)
+ ret
+END (__ieee754_log2l)
diff --git a/libc/sysdeps/i386/fpu/e_logf.S b/libc/sysdeps/i386/fpu/e_logf.S
new file mode 100644
index 000000000..128bb2754
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_logf.S
@@ -0,0 +1,58 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float by Ulrich Drepper <drepper@cygnus.com>.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_log.S,v 1.4 1995/05/08 23:48:39 jtc Exp $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_logf)
+ fldln2 // log(2)
+ flds 4(%esp) // x : log(2)
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ fld %st // x : x : log(2)
+ fsubl MO(one) // x-1 : x : log(2)
+ fld %st // x-1 : x-1 : x : log(2)
+ fabs // |x-1| : x-1 : x : log(2)
+ fcompl MO(limit) // x-1 : x : log(2)
+ fnstsw // x-1 : x : log(2)
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : log(2)
+ fyl2xp1 // log(x)
+ ret
+
+2: fstp %st(0) // x : log(2)
+ fyl2x // log(x)
+ ret
+END (__ieee754_logf)
diff --git a/libc/sysdeps/i386/fpu/e_logl.S b/libc/sysdeps/i386/fpu/e_logl.S
new file mode 100644
index 000000000..5023d3012
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_logl.S
@@ -0,0 +1,58 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_logl)
+ fldln2 // log(2)
+ fldt 4(%esp) // x : log(2)
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ fld %st // x : x : log(2)
+ fsubl MO(one) // x-1 : x : log(2)
+ fld %st // x-1 : x-1 : x : log(2)
+ fabs // |x-1| : x-1 : x : log(2)
+ fcompl MO(limit) // x-1 : x : log(2)
+ fnstsw // x-1 : x : log(2)
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : log(2)
+ fyl2xp1 // log(x)
+ ret
+
+2: fstp %st(0) // x : log(2)
+ fyl2x // log(x)
+ ret
+END (__ieee754_logl)
diff --git a/libc/sysdeps/i386/fpu/e_pow.S b/libc/sysdeps/i386/fpu/e_pow.S
new file mode 100644
index 000000000..c554ca4ec
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_pow.S
@@ -0,0 +1,360 @@
+/* ix87 specific implementation of pow function.
+ Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(infinity,@object)
+inf_zero:
+infinity:
+ .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+ ASM_SIZE_DIRECTIVE(infinity)
+ ASM_TYPE_DIRECTIVE(zero,@object)
+zero: .double 0.0
+ ASM_SIZE_DIRECTIVE(zero)
+ ASM_TYPE_DIRECTIVE(minf_mzero,@object)
+minf_mzero:
+minfinity:
+ .byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff
+mzero:
+ .byte 0, 0, 0, 0, 0, 0, 0, 0x80
+ ASM_SIZE_DIRECTIVE(minf_mzero)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+ ASM_TYPE_DIRECTIVE(p63,@object)
+p63: .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43
+ ASM_SIZE_DIRECTIVE(p63)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ecx)
+#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
+#else
+#define MO(op) op
+#define MOX(op,x,f) op(,x,f)
+#endif
+
+ .text
+ENTRY(__ieee754_pow)
+ fldl 12(%esp) // y
+ fxam
+
+#ifdef PIC
+ LOAD_PIC_REG (cx)
+#endif
+
+ fnstsw
+ movb %ah, %dl
+ andb $0x45, %ah
+ cmpb $0x40, %ah // is y == 0 ?
+ je 11f
+
+ cmpb $0x05, %ah // is y == ±inf ?
+ je 12f
+
+ cmpb $0x01, %ah // is y == NaN ?
+ je 30f
+
+ fldl 4(%esp) // x : y
+
+ subl $8,%esp
+ cfi_adjust_cfa_offset (8)
+
+ fxam
+ fnstsw
+ movb %ah, %dh
+ andb $0x45, %ah
+ cmpb $0x40, %ah
+ je 20f // x is ±0
+
+ cmpb $0x05, %ah
+ je 15f // x is ±inf
+
+ fxch // y : x
+
+ /* fistpll raises invalid exception for |y| >= 1L<<63. */
+ fld %st // y : y : x
+ fabs // |y| : y : x
+ fcompl MO(p63) // y : x
+ fnstsw
+ sahf
+ jnc 2f
+
+ /* First see whether `y' is a natural number. In this case we
+ can use a more precise algorithm. */
+ fld %st // y : y : x
+ fistpll (%esp) // y : x
+ fildll (%esp) // int(y) : y : x
+ fucomp %st(1) // y : x
+ fnstsw
+ sahf
+ jne 2f
+
+ /* OK, we have an integer value for y. */
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ orl $0, %edx
+ fstp %st(0) // x
+ jns 4f // y >= 0, jump
+ fdivrl MO(one) // 1/x (now referred to as x)
+ negl %eax
+ adcl $0, %edx
+ negl %edx
+4: fldl MO(one) // 1 : x
+ fxch
+
+6: shrdl $1, %edx, %eax
+ jnc 5f
+ fxch
+ fmul %st(1) // x : ST*x
+ fxch
+5: fmul %st(0), %st // x*x : ST*x
+ shrl $1, %edx
+ movl %eax, %ecx
+ orl %edx, %ecx
+ jnz 6b
+ fstp %st(0) // ST*x
+ ret
+
+ /* y is ±NAN */
+30: fldl 4(%esp) // x : y
+ fldl MO(one) // 1.0 : x : y
+ fucomp %st(1) // x : y
+ fnstsw
+ sahf
+ je 31f
+ fxch // y : x
+31: fstp %st(1)
+ ret
+
+ cfi_adjust_cfa_offset (8)
+ .align ALIGNARG(4)
+2: /* y is a real number. */
+ fxch // x : y
+ fldl MO(one) // 1.0 : x : y
+ fld %st(1) // x : 1.0 : x : y
+ fsub %st(1) // x-1 : 1.0 : x : y
+ fabs // |x-1| : 1.0 : x : y
+ fcompl MO(limit) // 1.0 : x : y
+ fnstsw
+ fxch // x : 1.0 : y
+ sahf
+ ja 7f
+ fsub %st(1) // x-1 : 1.0 : y
+ fyl2xp1 // log2(x) : y
+ jmp 8f
+
+7: fyl2x // log2(x) : y
+8: fmul %st(1) // y*log2(x) : y
+ fst %st(1) // y*log2(x) : y*log2(x)
+ frndint // int(y*log2(x)) : y*log2(x)
+ fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x))
+ fxch // fract(y*log2(x)) : int(y*log2(x))
+ f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x))
+ faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x))
+ fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x))
+ addl $8, %esp
+ cfi_adjust_cfa_offset (-8)
+ fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x))
+ ret
+
+
+ // pow(x,±0) = 1
+ .align ALIGNARG(4)
+11: fstp %st(0) // pop y
+ fldl MO(one)
+ ret
+
+ // y == ±inf
+ .align ALIGNARG(4)
+12: fstp %st(0) // pop y
+ fldl 4(%esp) // x
+ fabs
+ fcompl MO(one) // < 1, == 1, or > 1
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x45, %ah
+ je 13f // jump if x is NaN
+
+ cmpb $0x40, %ah
+ je 14f // jump if |x| == 1
+
+ shlb $1, %ah
+ xorb %ah, %dl
+ andl $2, %edx
+ fldl MOX(inf_zero, %edx, 4)
+ ret
+
+ .align ALIGNARG(4)
+14: fldl MO(one)
+ ret
+
+ .align ALIGNARG(4)
+13: fldl 4(%esp) // load x == NaN
+ ret
+
+ cfi_adjust_cfa_offset (8)
+ .align ALIGNARG(4)
+ // x is ±inf
+15: fstp %st(0) // y
+ testb $2, %dh
+ jz 16f // jump if x == +inf
+
+ // We must find out whether y is an odd integer.
+ fld %st // y : y
+ fistpll (%esp) // y
+ fildll (%esp) // int(y) : y
+ fucompp // <empty>
+ fnstsw
+ sahf
+ jne 17f
+
+ // OK, the value is an integer, but is the number of bits small
+ // enough so that all are coming from the mantissa?
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ andb $1, %al
+ jz 18f // jump if not odd
+ movl %edx, %eax
+ orl %edx, %edx
+ jns 155f
+ negl %eax
+155: cmpl $0x00200000, %eax
+ ja 18f // does not fit in mantissa bits
+ // It's an odd integer.
+ shrl $31, %edx
+ fldl MOX(minf_mzero, %edx, 8)
+ ret
+
+ cfi_adjust_cfa_offset (8)
+ .align ALIGNARG(4)
+16: fcompl MO(zero)
+ addl $8, %esp
+ cfi_adjust_cfa_offset (-8)
+ fnstsw
+ shrl $5, %eax
+ andl $8, %eax
+ fldl MOX(inf_zero, %eax, 1)
+ ret
+
+ cfi_adjust_cfa_offset (8)
+ .align ALIGNARG(4)
+17: shll $30, %edx // sign bit for y in right position
+ addl $8, %esp
+ cfi_adjust_cfa_offset (-8)
+18: shrl $31, %edx
+ fldl MOX(inf_zero, %edx, 8)
+ ret
+
+ cfi_adjust_cfa_offset (8)
+ .align ALIGNARG(4)
+ // x is ±0
+20: fstp %st(0) // y
+ testb $2, %dl
+ jz 21f // y > 0
+
+ // x is ±0 and y is < 0. We must find out whether y is an odd integer.
+ testb $2, %dh
+ jz 25f
+
+ fld %st // y : y
+ fistpll (%esp) // y
+ fildll (%esp) // int(y) : y
+ fucompp // <empty>
+ fnstsw
+ sahf
+ jne 26f
+
+ // OK, the value is an integer, but is the number of bits small
+ // enough so that all are coming from the mantissa?
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ andb $1, %al
+ jz 27f // jump if not odd
+ cmpl $0xffe00000, %edx
+ jbe 27f // does not fit in mantissa bits
+ // It's an odd integer.
+ // Raise divide-by-zero exception and get minus infinity value.
+ fldl MO(one)
+ fdivl MO(zero)
+ fchs
+ ret
+
+ cfi_adjust_cfa_offset (8)
+25: fstp %st(0)
+26: addl $8, %esp
+ cfi_adjust_cfa_offset (-8)
+27: // Raise divide-by-zero exception and get infinity value.
+ fldl MO(one)
+ fdivl MO(zero)
+ ret
+
+ cfi_adjust_cfa_offset (8)
+ .align ALIGNARG(4)
+ // x is ±0 and y is > 0. We must find out whether y is an odd integer.
+21: testb $2, %dh
+ jz 22f
+
+ fld %st // y : y
+ fistpll (%esp) // y
+ fildll (%esp) // int(y) : y
+ fucompp // <empty>
+ fnstsw
+ sahf
+ jne 23f
+
+ // OK, the value is an integer, but is the number of bits small
+ // enough so that all are coming from the mantissa?
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ andb $1, %al
+ jz 24f // jump if not odd
+ cmpl $0xffe00000, %edx
+ jae 24f // does not fit in mantissa bits
+ // It's an odd integer.
+ fldl MO(mzero)
+ ret
+
+ cfi_adjust_cfa_offset (8)
+22: fstp %st(0)
+23: addl $8, %esp // Don't use 2 x pop
+ cfi_adjust_cfa_offset (-8)
+24: fldl MO(zero)
+ ret
+
+END(__ieee754_pow)
diff --git a/libc/sysdeps/i386/fpu/e_powf.S b/libc/sysdeps/i386/fpu/e_powf.S
new file mode 100644
index 000000000..c835b978b
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_powf.S
@@ -0,0 +1,348 @@
+/* ix87 specific implementation of pow function.
+ Copyright (C) 1996, 1997, 1999, 2001, 2004, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(infinity,@object)
+inf_zero:
+infinity:
+ .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+ ASM_SIZE_DIRECTIVE(infinity)
+ ASM_TYPE_DIRECTIVE(zero,@object)
+zero: .double 0.0
+ ASM_SIZE_DIRECTIVE(zero)
+ ASM_TYPE_DIRECTIVE(minf_mzero,@object)
+minf_mzero:
+minfinity:
+ .byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff
+mzero:
+ .byte 0, 0, 0, 0, 0, 0, 0, 0x80
+ ASM_SIZE_DIRECTIVE(minf_mzero)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+ ASM_TYPE_DIRECTIVE(p31,@object)
+p31: .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x41
+ ASM_SIZE_DIRECTIVE(p31)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ecx)
+#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
+#else
+#define MO(op) op
+#define MOX(op,x,f) op(,x,f)
+#endif
+
+ .text
+ENTRY(__ieee754_powf)
+ flds 8(%esp) // y
+ fxam
+
+#ifdef PIC
+ LOAD_PIC_REG (cx)
+#endif
+
+ fnstsw
+ movb %ah, %dl
+ andb $0x45, %ah
+ cmpb $0x40, %ah // is y == 0 ?
+ je 11f
+
+ cmpb $0x05, %ah // is y == ±inf ?
+ je 12f
+
+ cmpb $0x01, %ah // is y == NaN ?
+ je 30f
+
+ flds 4(%esp) // x : y
+
+ subl $4, %esp
+ cfi_adjust_cfa_offset (4)
+
+ fxam
+ fnstsw
+ movb %ah, %dh
+ andb $0x45, %ah
+ cmpb $0x40, %ah
+ je 20f // x is ±0
+
+ cmpb $0x05, %ah
+ je 15f // x is ±inf
+
+ fxch // y : x
+
+ /* fistpl raises invalid exception for |y| >= 1L<<31. */
+ fld %st // y : y : x
+ fabs // |y| : y : x
+ fcompl MO(p31) // y : x
+ fnstsw
+ sahf
+ jnc 2f
+
+ /* First see whether `y' is a natural number. In this case we
+ can use a more precise algorithm. */
+ fld %st // y : y : x
+ fistpl (%esp) // y : x
+ fildl (%esp) // int(y) : y : x
+ fucomp %st(1) // y : x
+ fnstsw
+ sahf
+ jne 2f
+
+ /* OK, we have an integer value for y. */
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ orl $0, %edx
+ fstp %st(0) // x
+ jns 4f // y >= 0, jump
+ fdivrl MO(one) // 1/x (now referred to as x)
+ negl %edx
+4: fldl MO(one) // 1 : x
+ fxch
+
+6: shrl $1, %edx
+ jnc 5f
+ fxch
+ fmul %st(1) // x : ST*x
+ fxch
+5: fmul %st(0), %st // x*x : ST*x
+ testl %edx, %edx
+ jnz 6b
+ fstp %st(0) // ST*x
+ ret
+
+ /* y is ±NAN */
+30: flds 4(%esp) // x : y
+ fldl MO(one) // 1.0 : x : y
+ fucomp %st(1) // x : y
+ fnstsw
+ sahf
+ je 31f
+ fxch // y : x
+31: fstp %st(1)
+ ret
+
+ cfi_adjust_cfa_offset (4)
+ .align ALIGNARG(4)
+2: /* y is a real number. */
+ fxch // x : y
+ fldl MO(one) // 1.0 : x : y
+ fld %st(1) // x : 1.0 : x : y
+ fsub %st(1) // x-1 : 1.0 : x : y
+ fabs // |x-1| : 1.0 : x : y
+ fcompl MO(limit) // 1.0 : x : y
+ fnstsw
+ fxch // x : 1.0 : y
+ sahf
+ ja 7f
+ fsub %st(1) // x-1 : 1.0 : y
+ fyl2xp1 // log2(x) : y
+ jmp 8f
+
+7: fyl2x // log2(x) : y
+8: fmul %st(1) // y*log2(x) : y
+ fst %st(1) // y*log2(x) : y*log2(x)
+ frndint // int(y*log2(x)) : y*log2(x)
+ fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x))
+ fxch // fract(y*log2(x)) : int(y*log2(x))
+ f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x))
+ faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x))
+ fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x))
+ addl $4, %esp
+ cfi_adjust_cfa_offset (-4)
+ fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x))
+ ret
+
+
+ // pow(x,±0) = 1
+ .align ALIGNARG(4)
+11: fstp %st(0) // pop y
+ fldl MO(one)
+ ret
+
+ // y == ±inf
+ .align ALIGNARG(4)
+12: fstp %st(0) // pop y
+ flds 4(%esp) // x
+ fabs
+ fcompl MO(one) // < 1, == 1, or > 1
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x45, %ah
+ je 13f // jump if x is NaN
+
+ cmpb $0x40, %ah
+ je 14f // jump if |x| == 1
+
+ shlb $1, %ah
+ xorb %ah, %dl
+ andl $2, %edx
+ fldl MOX(inf_zero, %edx, 4)
+ ret
+
+ .align ALIGNARG(4)
+14: fldl MO(one)
+ ret
+
+ .align ALIGNARG(4)
+13: flds 4(%esp) // load x == NaN
+ ret
+
+ cfi_adjust_cfa_offset (4)
+ .align ALIGNARG(4)
+ // x is ±inf
+15: fstp %st(0) // y
+ testb $2, %dh
+ jz 16f // jump if x == +inf
+
+ // We must find out whether y is an odd integer.
+ fld %st // y : y
+ fistpl (%esp) // y
+ fildl (%esp) // int(y) : y
+ fucompp // <empty>
+ fnstsw
+ sahf
+ jne 17f
+
+ // OK, the value is an integer, but is the number of bits small
+ // enough so that all are coming from the mantissa?
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ testb $1, %dl
+ jz 18f // jump if not odd
+ movl %edx, %eax
+ orl %edx, %edx
+ jns 155f
+ negl %eax
+155: cmpl $0x01000000, %eax
+ ja 18f // does not fit in mantissa bits
+ // It's an odd integer.
+ shrl $31, %edx
+ fldl MOX(minf_mzero, %edx, 8)
+ ret
+
+ cfi_adjust_cfa_offset (4)
+ .align ALIGNARG(4)
+16: fcompl MO(zero)
+ addl $4, %esp
+ cfi_adjust_cfa_offset (-4)
+ fnstsw
+ shrl $5, %eax
+ andl $8, %eax
+ fldl MOX(inf_zero, %eax, 1)
+ ret
+
+ cfi_adjust_cfa_offset (4)
+ .align ALIGNARG(4)
+17: shll $30, %edx // sign bit for y in right position
+ addl $4, %esp
+ cfi_adjust_cfa_offset (-4)
+18: shrl $31, %edx
+ fldl MOX(inf_zero, %edx, 8)
+ ret
+
+ cfi_adjust_cfa_offset (4)
+ .align ALIGNARG(4)
+ // x is ±0
+20: fstp %st(0) // y
+ testb $2, %dl
+ jz 21f // y > 0
+
+ // x is ±0 and y is < 0. We must find out whether y is an odd integer.
+ testb $2, %dh
+ jz 25f
+
+ fld %st // y : y
+ fistpl (%esp) // y
+ fildl (%esp) // int(y) : y
+ fucompp // <empty>
+ fnstsw
+ sahf
+ jne 26f
+
+ // OK, the value is an integer, but is the number of bits small
+ // enough so that all are coming from the mantissa?
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ testb $1, %dl
+ jz 27f // jump if not odd
+ cmpl $0xff000000, %edx
+ jbe 27f // does not fit in mantissa bits
+ // It's an odd integer.
+ // Raise divide-by-zero exception and get minus infinity value.
+ fldl MO(one)
+ fdivl MO(zero)
+ fchs
+ ret
+
+ cfi_adjust_cfa_offset (4)
+25: fstp %st(0)
+26: addl $4, %esp
+ cfi_adjust_cfa_offset (-4)
+27: // Raise divide-by-zero exception and get infinity value.
+ fldl MO(one)
+ fdivl MO(zero)
+ ret
+
+ cfi_adjust_cfa_offset (4)
+ .align ALIGNARG(4)
+ // x is ±0 and y is > 0. We must find out whether y is an odd integer.
+21: testb $2, %dh
+ jz 22f
+
+ fld %st // y : y
+ fistpl (%esp) // y
+ fildl (%esp) // int(y) : y
+ fucompp // <empty>
+ fnstsw
+ sahf
+ jne 23f
+
+ // OK, the value is an integer, but is the number of bits small
+ // enough so that all are coming from the mantissa?
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ testb $1, %dl
+ jz 24f // jump if not odd
+ cmpl $0xff000000, %edx
+ jae 24f // does not fit in mantissa bits
+ // It's an odd integer.
+ fldl MO(mzero)
+ ret
+
+ cfi_adjust_cfa_offset (4)
+22: fstp %st(0)
+23: addl $4, %esp // Don't use pop.
+ cfi_adjust_cfa_offset (-4)
+24: fldl MO(zero)
+ ret
+
+END(__ieee754_powf)
diff --git a/libc/sysdeps/i386/fpu/e_powl.S b/libc/sysdeps/i386/fpu/e_powl.S
new file mode 100644
index 000000000..74f422816
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_powl.S
@@ -0,0 +1,360 @@
+/* ix87 specific implementation of pow function.
+ Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(infinity,@object)
+inf_zero:
+infinity:
+ .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+ ASM_SIZE_DIRECTIVE(infinity)
+ ASM_TYPE_DIRECTIVE(zero,@object)
+zero: .double 0.0
+ ASM_SIZE_DIRECTIVE(zero)
+ ASM_TYPE_DIRECTIVE(minf_mzero,@object)
+minf_mzero:
+minfinity:
+ .byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff
+mzero:
+ .byte 0, 0, 0, 0, 0, 0, 0, 0x80
+ ASM_SIZE_DIRECTIVE(minf_mzero)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+ ASM_TYPE_DIRECTIVE(p63,@object)
+p63: .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43
+ ASM_SIZE_DIRECTIVE(p63)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ecx)
+#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
+#else
+#define MO(op) op
+#define MOX(op,x,f) op(,x,f)
+#endif
+
+ .text
+ENTRY(__ieee754_powl)
+ fldt 16(%esp) // y
+ fxam
+
+#ifdef PIC
+ LOAD_PIC_REG (cx)
+#endif
+
+ fnstsw
+ movb %ah, %dl
+ andb $0x45, %ah
+ cmpb $0x40, %ah // is y == 0 ?
+ je 11f
+
+ cmpb $0x05, %ah // is y == ±inf ?
+ je 12f
+
+ cmpb $0x01, %ah // is y == NaN ?
+ je 30f
+
+ fldt 4(%esp) // x : y
+
+ subl $8,%esp
+ cfi_adjust_cfa_offset (8)
+
+ fxam
+ fnstsw
+ movb %ah, %dh
+ andb $0x45, %ah
+ cmpb $0x40, %ah
+ je 20f // x is ±0
+
+ cmpb $0x05, %ah
+ je 15f // x is ±inf
+
+ fxch // y : x
+
+ /* fistpll raises invalid exception for |y| >= 1L<<63. */
+ fld %st // y : y : x
+ fabs // |y| : y : x
+ fcompl MO(p63) // y : x
+ fnstsw
+ sahf
+ jnc 2f
+
+ /* First see whether `y' is a natural number. In this case we
+ can use a more precise algorithm. */
+ fld %st // y : y : x
+ fistpll (%esp) // y : x
+ fildll (%esp) // int(y) : y : x
+ fucomp %st(1) // y : x
+ fnstsw
+ sahf
+ jne 2f
+
+ /* OK, we have an integer value for y. */
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ orl $0, %edx
+ fstp %st(0) // x
+ jns 4f // y >= 0, jump
+ fdivrl MO(one) // 1/x (now referred to as x)
+ negl %eax
+ adcl $0, %edx
+ negl %edx
+4: fldl MO(one) // 1 : x
+ fxch
+
+6: shrdl $1, %edx, %eax
+ jnc 5f
+ fxch
+ fmul %st(1) // x : ST*x
+ fxch
+5: fmul %st(0), %st // x*x : ST*x
+ shrl $1, %edx
+ movl %eax, %ecx
+ orl %edx, %ecx
+ jnz 6b
+ fstp %st(0) // ST*x
+ ret
+
+ /* y is ±NAN */
+30: fldt 4(%esp) // x : y
+ fldl MO(one) // 1.0 : x : y
+ fucomp %st(1) // x : y
+ fnstsw
+ sahf
+ je 31f
+ fxch // y : x
+31: fstp %st(1)
+ ret
+
+ cfi_adjust_cfa_offset (8)
+ .align ALIGNARG(4)
+2: /* y is a real number. */
+ fxch // x : y
+ fldl MO(one) // 1.0 : x : y
+ fld %st(1) // x : 1.0 : x : y
+ fsub %st(1) // x-1 : 1.0 : x : y
+ fabs // |x-1| : 1.0 : x : y
+ fcompl MO(limit) // 1.0 : x : y
+ fnstsw
+ fxch // x : 1.0 : y
+ sahf
+ ja 7f
+ fsub %st(1) // x-1 : 1.0 : y
+ fyl2xp1 // log2(x) : y
+ jmp 8f
+
+7: fyl2x // log2(x) : y
+8: fmul %st(1) // y*log2(x) : y
+ fxam
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x05, %ah // is y*log2(x) == ±inf ?
+ je 28f
+ fst %st(1) // y*log2(x) : y*log2(x)
+ frndint // int(y*log2(x)) : y*log2(x)
+ fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x))
+ fxch // fract(y*log2(x)) : int(y*log2(x))
+ f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x))
+ faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x))
+ fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x))
+ addl $8, %esp
+ cfi_adjust_cfa_offset (-8)
+ fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x))
+ ret
+
+ cfi_adjust_cfa_offset (8)
+28: fstp %st(1) // y*log2(x)
+ fldl MO(one) // 1 : y*log2(x)
+ fscale // 2^(y*log2(x)) : y*log2(x)
+ addl $8, %esp
+ cfi_adjust_cfa_offset (-8)
+ fstp %st(1) // 2^(y*log2(x))
+ ret
+
+ // pow(x,±0) = 1
+ .align ALIGNARG(4)
+11: fstp %st(0) // pop y
+ fldl MO(one)
+ ret
+
+ // y == ±inf
+ .align ALIGNARG(4)
+12: fstp %st(0) // pop y
+ fldt 4(%esp) // x
+ fabs
+ fcompl MO(one) // < 1, == 1, or > 1
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x45, %ah
+ je 13f // jump if x is NaN
+
+ cmpb $0x40, %ah
+ je 14f // jump if |x| == 1
+
+ shlb $1, %ah
+ xorb %ah, %dl
+ andl $2, %edx
+ fldl MOX(inf_zero, %edx, 4)
+ ret
+
+ .align ALIGNARG(4)
+14: fldl MO(one)
+ ret
+
+ .align ALIGNARG(4)
+13: fldt 4(%esp) // load x == NaN
+ ret
+
+ cfi_adjust_cfa_offset (8)
+ .align ALIGNARG(4)
+ // x is ±inf
+15: fstp %st(0) // y
+ testb $2, %dh
+ jz 16f // jump if x == +inf
+
+ // We must find out whether y is an odd integer.
+ fld %st // y : y
+ fistpll (%esp) // y
+ fildll (%esp) // int(y) : y
+ fucompp // <empty>
+ fnstsw
+ sahf
+ jne 17f
+
+ // OK, the value is an integer, but is it odd?
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ andb $1, %al
+ jz 18f // jump if not odd
+ // It's an odd integer.
+ shrl $31, %edx
+ fldl MOX(minf_mzero, %edx, 8)
+ ret
+
+ cfi_adjust_cfa_offset (8)
+ .align ALIGNARG(4)
+16: fcompl MO(zero)
+ addl $8, %esp
+ cfi_adjust_cfa_offset (-8)
+ fnstsw
+ shrl $5, %eax
+ andl $8, %eax
+ fldl MOX(inf_zero, %eax, 1)
+ ret
+
+ cfi_adjust_cfa_offset (8)
+ .align ALIGNARG(4)
+17: shll $30, %edx // sign bit for y in right position
+ addl $8, %esp
+ cfi_adjust_cfa_offset (-8)
+18: shrl $31, %edx
+ fldl MOX(inf_zero, %edx, 8)
+ ret
+
+ cfi_adjust_cfa_offset (8)
+ .align ALIGNARG(4)
+ // x is ±0
+20: fstp %st(0) // y
+ testb $2, %dl
+ jz 21f // y > 0
+
+ // x is ±0 and y is < 0. We must find out whether y is an odd integer.
+ testb $2, %dh
+ jz 25f
+
+ fld %st // y : y
+ fistpll (%esp) // y
+ fildll (%esp) // int(y) : y
+ fucompp // <empty>
+ fnstsw
+ sahf
+ jne 26f
+
+ // OK, the value is an integer, but is it odd?
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ andb $1, %al
+ jz 27f // jump if not odd
+ // It's an odd integer.
+ // Raise divide-by-zero exception and get minus infinity value.
+ fldl MO(one)
+ fdivl MO(zero)
+ fchs
+ ret
+
+ cfi_adjust_cfa_offset (8)
+25: fstp %st(0)
+26: addl $8, %esp
+ cfi_adjust_cfa_offset (-8)
+27: // Raise divide-by-zero exception and get infinity value.
+ fldl MO(one)
+ fdivl MO(zero)
+ ret
+
+ cfi_adjust_cfa_offset (8)
+ .align ALIGNARG(4)
+ // x is ±0 and y is > 0. We must find out whether y is an odd integer.
+21: testb $2, %dh
+ jz 22f
+
+ fld %st // y : y
+ fistpll (%esp) // y
+ fildll (%esp) // int(y) : y
+ fucompp // <empty>
+ fnstsw
+ sahf
+ jne 23f
+
+ // OK, the value is an integer, but is it odd?
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ andb $1, %al
+ jz 24f // jump if not odd
+ // It's an odd integer.
+ fldl MO(mzero)
+ ret
+
+ cfi_adjust_cfa_offset (8)
+22: fstp %st(0)
+23: addl $8, %esp // Don't use 2 x pop
+ cfi_adjust_cfa_offset (-8)
+24: fldl MO(zero)
+ ret
+
+END(__ieee754_powl)
diff --git a/libc/sysdeps/i386/fpu/e_rem_pio2.c b/libc/sysdeps/i386/fpu/e_rem_pio2.c
new file mode 100644
index 000000000..1347b0468
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_rem_pio2.c
@@ -0,0 +1,3 @@
+/* Empty. This file is only meant to avoid compiling the file with the
+ same name in the libm-ieee754 directory. The code is not used since
+ there is an assembler version for all users of this file. */
diff --git a/libc/sysdeps/i386/fpu/e_rem_pio2f.c b/libc/sysdeps/i386/fpu/e_rem_pio2f.c
new file mode 100644
index 000000000..1347b0468
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_rem_pio2f.c
@@ -0,0 +1,3 @@
+/* Empty. This file is only meant to avoid compiling the file with the
+ same name in the libm-ieee754 directory. The code is not used since
+ there is an assembler version for all users of this file. */
diff --git a/libc/sysdeps/i386/fpu/e_rem_pio2l.c b/libc/sysdeps/i386/fpu/e_rem_pio2l.c
new file mode 100644
index 000000000..1347b0468
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_rem_pio2l.c
@@ -0,0 +1,3 @@
+/* Empty. This file is only meant to avoid compiling the file with the
+ same name in the libm-ieee754 directory. The code is not used since
+ there is an assembler version for all users of this file. */
diff --git a/libc/sysdeps/i386/fpu/e_remainder.S b/libc/sysdeps/i386/fpu/e_remainder.S
new file mode 100644
index 000000000..2f43cb894
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_remainder.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_remainder.S,v 1.4 1995/05/08 23:49:37 jtc Exp $")
+
+ENTRY(__ieee754_remainder)
+ fldl 12(%esp)
+ fldl 4(%esp)
+1: fprem1
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ ret
+END (__ieee754_remainder)
diff --git a/libc/sysdeps/i386/fpu/e_remainderf.S b/libc/sysdeps/i386/fpu/e_remainderf.S
new file mode 100644
index 000000000..79f821993
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_remainderf.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_remainderf.S,v 1.2 1995/05/08 23:49:47 jtc Exp $")
+
+ENTRY(__ieee754_remainderf)
+ flds 8(%esp)
+ flds 4(%esp)
+1: fprem1
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ ret
+END (__ieee754_remainderf)
diff --git a/libc/sysdeps/i386/fpu/e_remainderl.S b/libc/sysdeps/i386/fpu/e_remainderl.S
new file mode 100644
index 000000000..5f50b626a
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_remainderl.S
@@ -0,0 +1,21 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ieee754_remainderl)
+ fldt 16(%esp)
+ fldt 4(%esp)
+1: fprem1
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ ret
+END (__ieee754_remainderl)
diff --git a/libc/sysdeps/i386/fpu/e_scalb.S b/libc/sysdeps/i386/fpu/e_scalb.S
new file mode 100644
index 000000000..7e334a361
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_scalb.S
@@ -0,0 +1,102 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Correct handling of y==-inf <drepper@gnu>
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_scalb.S,v 1.4 1995/05/08 23:49:52 jtc Exp $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(zero_nan,@object)
+zero_nan:
+ .double 0.0
+nan: .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+minus_zero:
+ .byte 0, 0, 0, 0, 0, 0, 0, 0x80
+ .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+ ASM_SIZE_DIRECTIVE(zero_nan)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ecx)
+#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
+#else
+#define MO(op) op
+#define MOX(op,x,f) op(,x,f)
+#endif
+
+ .text
+ENTRY(__ieee754_scalb)
+ fldl 12(%esp)
+ fxam
+ fnstsw
+ fldl 4(%esp)
+ andl $0x4700, %eax
+ cmpl $0x0700, %eax
+ je 1f
+ andl $0x4500, %eax
+ cmpl $0x0100, %eax
+ je 2f
+ fxam
+ fnstsw
+ andl $0x4500, %eax
+ cmpl $0x0100, %eax
+ je 3f
+ fld %st(1)
+ frndint
+ fcomp %st(2)
+ fnstsw
+ sahf
+ jne 4f
+ fscale
+ fstp %st(1)
+ ret
+
+ /* y is -inf */
+1: fxam
+#ifdef PIC
+ LOAD_PIC_REG (cx)
+#endif
+ fnstsw
+ movl 8(%esp), %edx
+ shrl $5, %eax
+ fstp %st
+ fstp %st
+ andl $0x80000000, %edx
+ andl $8, %eax
+ jnz 4f
+ shrl $27, %edx
+ addl %edx, %eax
+ fldl MOX(zero_nan, %eax, 1)
+ ret
+
+ /* The result is NaN, but we must not raise an exception.
+ So use a variable. */
+2: fstp %st
+ fstp %st
+#ifdef PIC
+ LOAD_PIC_REG (cx)
+#endif
+ fldl MO(nan)
+ ret
+
+ /* The first parameter is a NaN. Return it. */
+3: fstp %st(1)
+ ret
+
+ /* Return NaN and raise the invalid exception. */
+4: fstp %st
+ fstp %st
+ fldz
+ fdiv %st
+ ret
+END(__ieee754_scalb)
diff --git a/libc/sysdeps/i386/fpu/e_scalbf.S b/libc/sysdeps/i386/fpu/e_scalbf.S
new file mode 100644
index 000000000..e99ee92cb
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_scalbf.S
@@ -0,0 +1,104 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
+ *
+ * Correct handling of y==-inf <drepper@gnu>
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(zero_nan,@object)
+zero_nan:
+ .double 0.0
+nan: .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+minus_zero:
+ .byte 0, 0, 0, 0, 0, 0, 0, 0x80
+ .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+ ASM_SIZE_DIRECTIVE(zero_nan)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ecx)
+#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
+#else
+#define MO(op) op
+#define MOX(op,x,f) op(,x,f)
+#endif
+
+
+ .text
+ENTRY(__ieee754_scalbf)
+ flds 8(%esp)
+ fxam
+ fnstsw
+ flds 4(%esp)
+ andl $0x4700, %eax
+ cmpl $0x0700, %eax
+ je 1f
+ andl $0x4500, %eax
+ cmpl $0x0100, %eax
+ je 2f
+ fxam
+ fnstsw
+ andl $0x4500, %eax
+ cmpl $0x0100, %eax
+ je 3f
+ fld %st(1)
+ frndint
+ fcomp %st(2)
+ fnstsw
+ sahf
+ jne 4f
+ fscale
+ fstp %st(1)
+ ret
+
+ /* y is -inf */
+1: fxam
+#ifdef PIC
+ LOAD_PIC_REG (cx)
+#endif
+ fnstsw
+ movl 4(%esp), %edx
+ shrl $5, %eax
+ fstp %st
+ fstp %st
+ andl $0x80000000, %edx
+ andl $8, %eax
+ jnz 4f
+ shrl $27, %edx
+ addl %edx, %eax
+ fldl MOX(zero_nan, %eax, 1)
+ ret
+
+ /* The result is NaN, but we must not raise an exception.
+ So use a variable. */
+2: fstp %st
+ fstp %st
+#ifdef PIC
+ LOAD_PIC_REG (cx)
+#endif
+ fldl MO(nan)
+ ret
+
+ /* The first parameter is a NaN. Return it. */
+3: fstp %st(1)
+ ret
+
+ /* Return NaN and raise the invalid exception. */
+4: fstp %st
+ fstp %st
+ fldz
+ fdiv %st
+ ret
+END(__ieee754_scalbf)
diff --git a/libc/sysdeps/i386/fpu/e_scalbl.S b/libc/sysdeps/i386/fpu/e_scalbl.S
new file mode 100644
index 000000000..3f67d0bef
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_scalbl.S
@@ -0,0 +1,104 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ *
+ * Correct handling of y==-inf <drepper@gnu>
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(zero_nan,@object)
+zero_nan:
+ .double 0.0
+nan: .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+minus_zero:
+ .byte 0, 0, 0, 0, 0, 0, 0, 0x80
+ .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+ ASM_SIZE_DIRECTIVE(zero_nan)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ecx)
+#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
+#else
+#define MO(op) op
+#define MOX(op,x,f) op(,x,f)
+#endif
+
+ .text
+ENTRY(__ieee754_scalbl)
+ fldt 16(%esp)
+ fxam
+ fnstsw
+ fldt 4(%esp)
+ andl $0x4700, %eax
+ cmpl $0x0700, %eax
+ je 1f
+ andl $0x4500, %eax
+ cmpl $0x0100, %eax
+ je 2f
+ fxam
+ fnstsw
+ andl $0x4500, %eax
+ cmpl $0x0100, %eax
+ je 3f
+ fld %st(1)
+ frndint
+ fcomp %st(2)
+ fnstsw
+ sahf
+ jne 4f
+ fscale
+ fstp %st(1)
+ ret
+
+ /* y is -inf */
+1: fxam
+#ifdef PIC
+ LOAD_PIC_REG (cx)
+#endif
+ fnstsw
+ movl 12(%esp), %edx
+ shrl $5, %eax
+ fstp %st
+ fstp %st
+ andl $0x8000, %edx
+ andl $8, %eax
+ jnz 4f
+ shrl $11, %edx
+ addl %edx, %eax
+ fldl MOX(zero_nan, %eax, 1)
+ ret
+
+ /* The result is NaN, but we must not raise an exception.
+ So use a variable. */
+2: fstp %st
+ fstp %st
+#ifdef PIC
+ LOAD_PIC_REG (cx)
+#endif
+ fldl MO(nan)
+ ret
+
+ /* The first parameter is a NaN. Return it. */
+3: fstp %st(1)
+ ret
+
+ /* Return NaN and raise the invalid exception. */
+4: fstp %st
+ fstp %st
+ fldz
+ fdiv %st
+ ret
+END(__ieee754_scalbl)
diff --git a/libc/sysdeps/i386/fpu/e_sqrt.S b/libc/sysdeps/i386/fpu/e_sqrt.S
new file mode 100644
index 000000000..6f253d51a
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_sqrt.S
@@ -0,0 +1,14 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_sqrt.S,v 1.4 1995/05/08 23:49:57 jtc Exp $")
+
+ENTRY(__ieee754_sqrt)
+ fldl 4(%esp)
+ fsqrt
+ ret
+END (__ieee754_sqrt)
diff --git a/libc/sysdeps/i386/fpu/e_sqrtf.S b/libc/sysdeps/i386/fpu/e_sqrtf.S
new file mode 100644
index 000000000..5ce1ad054
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_sqrtf.S
@@ -0,0 +1,14 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: e_sqrtf.S,v 1.2 1995/05/08 23:50:14 jtc Exp $")
+
+ENTRY(__ieee754_sqrtf)
+ flds 4(%esp)
+ fsqrt
+ ret
+END (__ieee754_sqrtf)
diff --git a/libc/sysdeps/i386/fpu/e_sqrtl.c b/libc/sysdeps/i386/fpu/e_sqrtl.c
new file mode 100644
index 000000000..85f61bb38
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/e_sqrtl.c
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <math_private.h>
+
+long double
+__ieee754_sqrtl (long double x)
+{
+ long double res;
+
+ asm ("fsqrt" : "=t" (res) : "0" (x));
+
+ return res;
+}
diff --git a/libc/sysdeps/i386/fpu/fclrexcpt.c b/libc/sysdeps/i386/fpu/fclrexcpt.c
new file mode 100644
index 000000000..34ef07071
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/fclrexcpt.c
@@ -0,0 +1,69 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 1997,99,2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+int
+__feclearexcept (int excepts)
+{
+ fenv_t temp;
+
+ /* Mask out unsupported bits/exceptions. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Bah, we have to clear selected exceptions. Since there is no
+ `fldsw' instruction we have to do it the hard way. */
+ __asm__ ("fnstenv %0" : "=m" (*&temp));
+
+ /* Clear the relevant bits. */
+ temp.__status_word &= excepts ^ FE_ALL_EXCEPT;
+
+ /* Put the new data in effect. */
+ __asm__ ("fldenv %0" : : "m" (*&temp));
+
+ /* If the CPU supports SSE, we clear the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xnew_exc;
+
+ /* Get the current MXCSR. */
+ __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
+
+ /* Clear the relevant bits. */
+ xnew_exc &= ~excepts;
+
+ /* Put the new data in effect. */
+ __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
+ }
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feclearexcept, __old_feclearexcept)
+compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
diff --git a/libc/sysdeps/i386/fpu/fedisblxcpt.c b/libc/sysdeps/i386/fpu/fedisblxcpt.c
new file mode 100644
index 000000000..6b0977fb3
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/fedisblxcpt.c
@@ -0,0 +1,55 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+int
+fedisableexcept (int excepts)
+{
+ unsigned short int new_exc, old_exc;
+
+ /* Get the current control word. */
+ __asm__ ("fstcw %0" : "=m" (*&new_exc));
+
+ old_exc = (~new_exc) & FE_ALL_EXCEPT;
+
+ excepts &= FE_ALL_EXCEPT;
+
+ new_exc |= excepts;
+ __asm__ ("fldcw %0" : : "m" (*&new_exc));
+
+ /* If the CPU supports SSE we set the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xnew_exc;
+
+ /* Get the current control word. */
+ __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
+
+ xnew_exc |= excepts << 7;
+
+ __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
+ }
+
+ return old_exc;
+}
diff --git a/libc/sysdeps/i386/fpu/feenablxcpt.c b/libc/sysdeps/i386/fpu/feenablxcpt.c
new file mode 100644
index 000000000..afd8dc774
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/feenablxcpt.c
@@ -0,0 +1,55 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+int
+feenableexcept (int excepts)
+{
+ unsigned short int new_exc;
+ unsigned short int old_exc;
+
+ /* Get the current control word. */
+ __asm__ ("fstcw %0" : "=m" (*&new_exc));
+
+ excepts &= FE_ALL_EXCEPT;
+ old_exc = (~new_exc) & FE_ALL_EXCEPT;
+
+ new_exc &= ~excepts;
+ __asm__ ("fldcw %0" : : "m" (*&new_exc));
+
+ /* If the CPU supports SSE we set the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xnew_exc;
+
+ /* Get the current control word. */
+ __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
+
+ xnew_exc &= ~(excepts << 7);
+
+ __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
+ }
+
+ return old_exc;
+}
diff --git a/libc/sysdeps/i386/fpu/fegetenv.c b/libc/sysdeps/i386/fpu/fegetenv.c
new file mode 100644
index 000000000..fb955cf56
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/fegetenv.c
@@ -0,0 +1,43 @@
+/* Store current floating-point environment.
+ Copyright (C) 1997,1999,2000,2001,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <bp-sym.h>
+
+int
+__fegetenv (fenv_t *envp)
+{
+ __asm__ ("fnstenv %0" : "=m" (*envp));
+ /* And load it right back since the processor changes the mask.
+ Intel thought this opcode to be used in interrupt handlers which
+ would block all exceptions. */
+ __asm__ ("fldenv %0" : : "m" (*envp));
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fegetenv, __old_fegetenv)
+compat_symbol (libm, BP_SYM (__old_fegetenv), BP_SYM (fegetenv), GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, BP_SYM (__fegetenv), BP_SYM (fegetenv), GLIBC_2_2);
diff --git a/libc/sysdeps/i386/fpu/fegetexcept.c b/libc/sysdeps/i386/fpu/fegetexcept.c
new file mode 100644
index 000000000..71bac788b
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/fegetexcept.c
@@ -0,0 +1,32 @@
+/* Get enabled floating-point exceptions.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetexcept (void)
+{
+ unsigned short int exc;
+
+ /* Get the current control word. */
+ __asm__ ("fstcw %0" : "=m" (*&exc));
+
+ return (~exc) & FE_ALL_EXCEPT;
+}
diff --git a/libc/sysdeps/i386/fpu/fegetround.c b/libc/sysdeps/i386/fpu/fegetround.c
new file mode 100644
index 000000000..8ae0c3aff
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/fegetround.c
@@ -0,0 +1,31 @@
+/* Return current rounding direction.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetround (void)
+{
+ int cw;
+
+ __asm__ ("fnstcw %0" : "=m" (*&cw));
+
+ return cw & 0xc00;
+}
diff --git a/libc/sysdeps/i386/fpu/feholdexcpt.c b/libc/sysdeps/i386/fpu/feholdexcpt.c
new file mode 100644
index 000000000..feaa24b8d
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/feholdexcpt.c
@@ -0,0 +1,54 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 1997, 1999, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ unsigned short int work;
+
+ /* Store the environment. */
+ __asm__ ("fnstenv %0" : "=m" (*envp));
+
+ /* Now set all exceptions to non-stop. */
+ work = envp->__control_word | 0x3f;
+ __asm__ ("fldcw %0" : : "m" (*&work));
+
+ /* If the CPU supports SSE we set the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xwork;
+
+ /* Get the current control word. */
+ __asm__ ("stmxcsr %0" : "=m" (*&xwork));
+
+ /* Set all exceptions to non-stop. */
+ xwork |= 0x1f80;
+
+ __asm__ ("ldmxcsr %0" : : "m" (*&xwork));
+ }
+
+ return 0;
+}
+libm_hidden_def (feholdexcept)
diff --git a/libc/sysdeps/i386/fpu/fesetenv.c b/libc/sysdeps/i386/fpu/fesetenv.c
new file mode 100644
index 000000000..667d50857
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/fesetenv.c
@@ -0,0 +1,88 @@
+/* Install given floating-point environment.
+ Copyright (C) 1997,98,99,2000,01,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <assert.h>
+#include <bp-sym.h>
+
+
+int
+__fesetenv (const fenv_t *envp)
+{
+ fenv_t temp;
+
+ /* The memory block used by fstenv/fldenv has a size of 28 bytes. */
+ assert (sizeof (fenv_t) == 28);
+
+ /* Install the environment specified by ENVP. But there are a few
+ values which we do not want to come from the saved environment.
+ Therefore, we get the current environment and replace the values
+ we want to use from the environment specified by the parameter. */
+ __asm__ ("fnstenv %0" : "=m" (*&temp));
+
+ if (envp == FE_DFL_ENV)
+ {
+ temp.__control_word |= FE_ALL_EXCEPT;
+ temp.__control_word &= ~FE_TOWARDZERO;
+ temp.__status_word &= ~FE_ALL_EXCEPT;
+ temp.__eip = 0;
+ temp.__cs_selector = 0;
+ temp.__opcode = 0;
+ temp.__data_offset = 0;
+ temp.__data_selector = 0;
+ }
+ else if (envp == FE_NOMASK_ENV)
+ {
+ temp.__control_word &= ~(FE_ALL_EXCEPT | FE_TOWARDZERO);
+ temp.__status_word &= ~FE_ALL_EXCEPT;
+ temp.__eip = 0;
+ temp.__cs_selector = 0;
+ temp.__opcode = 0;
+ temp.__data_offset = 0;
+ temp.__data_selector = 0;
+ }
+ else
+ {
+ temp.__control_word &= ~(FE_ALL_EXCEPT | FE_TOWARDZERO);
+ temp.__control_word |= (envp->__control_word
+ & (FE_ALL_EXCEPT | FE_TOWARDZERO));
+ temp.__status_word &= ~FE_ALL_EXCEPT;
+ temp.__status_word |= envp->__status_word & FE_ALL_EXCEPT;
+ temp.__eip = envp->__eip;
+ temp.__cs_selector = envp->__cs_selector;
+ temp.__opcode = envp->__opcode;
+ temp.__data_offset = envp->__data_offset;
+ temp.__data_selector = envp->__data_selector;
+ }
+
+ __asm__ ("fldenv %0" : : "m" (temp));
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fesetenv, __old_fesetenv)
+compat_symbol (libm, BP_SYM (__old_fesetenv), BP_SYM (fesetenv), GLIBC_2_1);
+#endif
+
+libm_hidden_ver (__fesetenv, fesetenv)
+versioned_symbol (libm, BP_SYM (__fesetenv), BP_SYM (fesetenv), GLIBC_2_2);
diff --git a/libc/sysdeps/i386/fpu/fesetround.c b/libc/sysdeps/i386/fpu/fesetround.c
new file mode 100644
index 000000000..a868f275f
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/fesetround.c
@@ -0,0 +1,53 @@
+/* Set current rounding direction.
+ Copyright (C) 1997, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+int
+fesetround (int round)
+{
+ unsigned short int cw;
+
+ if ((round & ~0xc00) != 0)
+ /* ROUND is no valid rounding mode. */
+ return 1;
+
+ __asm__ ("fnstcw %0" : "=m" (*&cw));
+ cw &= ~0xc00;
+ cw |= round;
+ __asm__ ("fldcw %0" : : "m" (*&cw));
+
+ /* If the CPU supports SSE we set the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xcw;
+
+ __asm__ ("stmxcsr %0" : "=m" (*&xcw));
+ xcw &= ~0x6000;
+ xcw |= round << 3;
+ __asm__ ("ldmxcsr %0" : : "m" (*&xcw));
+ }
+
+ return 0;
+}
+libm_hidden_def (fesetround)
diff --git a/libc/sysdeps/i386/fpu/feupdateenv.c b/libc/sysdeps/i386/fpu/feupdateenv.c
new file mode 100644
index 000000000..a443f500b
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/feupdateenv.c
@@ -0,0 +1,51 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <bp-sym.h>
+
+int
+__feupdateenv (const fenv_t *envp)
+{
+ fexcept_t temp;
+
+ /* Save current exceptions. */
+ __asm__ ("fnstsw %0" : "=m" (*&temp));
+ temp &= FE_ALL_EXCEPT;
+
+ /* Install new environment. */
+ fesetenv (envp);
+
+ /* Raise the safed exception. Incidently for us the implementation
+ defined format of the values in objects of type fexcept_t is the
+ same as the ones specified using the FE_* constants. */
+ feraiseexcept ((int) temp);
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feupdateenv, __old_feupdateenv)
+compat_symbol (libm, BP_SYM (__old_feupdateenv), BP_SYM (feupdateenv), GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, BP_SYM (__feupdateenv), BP_SYM (feupdateenv), GLIBC_2_2);
diff --git a/libc/sysdeps/i386/fpu/fgetexcptflg.c b/libc/sysdeps/i386/fpu/fgetexcptflg.c
new file mode 100644
index 000000000..5f60511b6
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/fgetexcptflg.c
@@ -0,0 +1,44 @@
+/* Store current representation for exceptions.
+ Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <bp-sym.h>
+
+int
+__fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ fexcept_t temp;
+
+ /* Get the current exceptions. */
+ __asm__ ("fnstsw %0" : "=m" (*&temp));
+
+ *flagp = temp & excepts & FE_ALL_EXCEPT;
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fegetexceptflag, __old_fegetexceptflag)
+compat_symbol (libm, BP_SYM (__old_fegetexceptflag), BP_SYM (fegetexceptflag), GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, BP_SYM (__fegetexceptflag), BP_SYM (fegetexceptflag), GLIBC_2_2);
diff --git a/libc/sysdeps/i386/fpu/fraiseexcpt.c b/libc/sysdeps/i386/fpu/fraiseexcpt.c
new file mode 100644
index 000000000..be50e5ede
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/fraiseexcpt.c
@@ -0,0 +1,124 @@
+/* Raise given exceptions.
+ Copyright (C) 1997,99,2000,01,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <math.h>
+
+int
+__feraiseexcept (int excepts)
+{
+ /* Raise exceptions represented by EXPECTS. But we must raise only
+ one signal at a time. It is important that if the overflow/underflow
+ exception and the inexact exception are given at the same time,
+ the overflow/underflow exception follows the inexact exception. */
+
+ /* First: invalid exception. */
+ if ((FE_INVALID & excepts) != 0)
+ {
+ /* One example of a invalid operation is 0.0 / 0.0. */
+ double d;
+ __asm__ __volatile__ ("fldz; fdiv %%st, %%st(0); fwait" : "=t" (d));
+ (void) &d;
+ }
+
+ /* Next: division by zero. */
+ if ((FE_DIVBYZERO & excepts) != 0)
+ {
+ double d;
+ __asm__ __volatile__ ("fldz; fld1; fdivp %%st, %%st(1); fwait"
+ : "=t" (d));
+ (void) &d;
+ }
+
+ /* Next: overflow. */
+ if ((FE_OVERFLOW & excepts) != 0)
+ {
+ /* There is no way to raise only the overflow flag. Do it the
+ hard way. */
+ fenv_t temp;
+
+ /* Bah, we have to clear selected exceptions. Since there is no
+ `fldsw' instruction we have to do it the hard way. */
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
+
+ /* Set the relevant bits. */
+ temp.__status_word |= FE_OVERFLOW;
+
+ /* Put the new data in effect. */
+ __asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
+
+ /* And raise the exception. */
+ __asm__ __volatile__ ("fwait");
+ }
+
+ /* Next: underflow. */
+ if ((FE_UNDERFLOW & excepts) != 0)
+ {
+ /* There is no way to raise only the underflow flag. Do it the
+ hard way. */
+ fenv_t temp;
+
+ /* Bah, we have to clear selected exceptions. Since there is no
+ `fldsw' instruction we have to do it the hard way. */
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
+
+ /* Set the relevant bits. */
+ temp.__status_word |= FE_UNDERFLOW;
+
+ /* Put the new data in effect. */
+ __asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
+
+ /* And raise the exception. */
+ __asm__ __volatile__ ("fwait");
+ }
+
+ /* Last: inexact. */
+ if ((FE_INEXACT & excepts) != 0)
+ {
+ /* There is no way to raise only the inexact flag. Do it the
+ hard way. */
+ fenv_t temp;
+
+ /* Bah, we have to clear selected exceptions. Since there is no
+ `fldsw' instruction we have to do it the hard way. */
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
+
+ /* Set the relevant bits. */
+ temp.__status_word |= FE_INEXACT;
+
+ /* Put the new data in effect. */
+ __asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
+
+ /* And raise the exception. */
+ __asm__ __volatile__ ("fwait");
+ }
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feraiseexcept, __old_feraiseexcept)
+compat_symbol (libm, __old_feraiseexcept, feraiseexcept, GLIBC_2_1);
+#endif
+
+libm_hidden_ver (__feraiseexcept, feraiseexcept)
+versioned_symbol (libm, __feraiseexcept, feraiseexcept, GLIBC_2_2);
diff --git a/libc/sysdeps/i386/fpu/fsetexcptflg.c b/libc/sysdeps/i386/fpu/fsetexcptflg.c
new file mode 100644
index 000000000..03eeef359
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/fsetexcptflg.c
@@ -0,0 +1,71 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 1997,99,2000,01, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <math.h>
+#include <bp-sym.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+int
+__fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fenv_t temp;
+
+ /* Get the current environment. We have to do this since we cannot
+ separately set the status word. */
+ __asm__ ("fnstenv %0" : "=m" (*&temp));
+
+ temp.__status_word &= ~(excepts & FE_ALL_EXCEPT);
+ temp.__status_word |= *flagp & excepts & FE_ALL_EXCEPT;
+
+ /* Store the new status word (along with the rest of the environment.
+ Possibly new exceptions are set but they won't get executed unless
+ the next floating-point instruction. */
+ __asm__ ("fldenv %0" : : "m" (*&temp));
+
+ /* If the CPU supports SSE, we set the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xnew_exc;
+
+ /* Get the current MXCSR. */
+ __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
+
+ /* Set the relevant bits. */
+ xnew_exc &= ~(excepts & FE_ALL_EXCEPT);
+ xnew_exc |= *flagp & excepts & FE_ALL_EXCEPT;
+
+ /* Put the new data in effect. */
+ __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
+ }
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fesetexceptflag, __old_fesetexceptflag)
+compat_symbol (libm, BP_SYM (__old_fesetexceptflag), BP_SYM (fesetexceptflag), GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, BP_SYM (__fesetexceptflag), BP_SYM (fesetexceptflag), GLIBC_2_2);
diff --git a/libc/sysdeps/i386/fpu/ftestexcept.c b/libc/sysdeps/i386/fpu/ftestexcept.c
new file mode 100644
index 000000000..9038e04c3
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/ftestexcept.c
@@ -0,0 +1,40 @@
+/* Test exception in current environment.
+ Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+#include <dl-procinfo.h>
+#include <ldsodefs.h>
+
+int
+fetestexcept (int excepts)
+{
+ int temp;
+ int xtemp = 0;
+
+ /* Get current exceptions. */
+ __asm__ ("fnstsw %0" : "=a" (temp));
+
+ /* If the CPU supports SSE we test the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ __asm__ ("stmxcsr %0" : "=m" (*&xtemp));
+
+ return (temp | xtemp) & excepts & FE_ALL_EXCEPT;
+}
diff --git a/libc/sysdeps/i386/fpu/halfulp.c b/libc/sysdeps/i386/fpu/halfulp.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/halfulp.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/k_rem_pio2.c b/libc/sysdeps/i386/fpu/k_rem_pio2.c
new file mode 100644
index 000000000..1347b0468
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/k_rem_pio2.c
@@ -0,0 +1,3 @@
+/* Empty. This file is only meant to avoid compiling the file with the
+ same name in the libm-ieee754 directory. The code is not used since
+ there is an assembler version for all users of this file. */
diff --git a/libc/sysdeps/i386/fpu/k_rem_pio2f.c b/libc/sysdeps/i386/fpu/k_rem_pio2f.c
new file mode 100644
index 000000000..1347b0468
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/k_rem_pio2f.c
@@ -0,0 +1,3 @@
+/* Empty. This file is only meant to avoid compiling the file with the
+ same name in the libm-ieee754 directory. The code is not used since
+ there is an assembler version for all users of this file. */
diff --git a/libc/sysdeps/i386/fpu/k_rem_pio2l.c b/libc/sysdeps/i386/fpu/k_rem_pio2l.c
new file mode 100644
index 000000000..1347b0468
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/k_rem_pio2l.c
@@ -0,0 +1,3 @@
+/* Empty. This file is only meant to avoid compiling the file with the
+ same name in the libm-ieee754 directory. The code is not used since
+ there is an assembler version for all users of this file. */
diff --git a/libc/sysdeps/i386/fpu/libm-test-ulps b/libc/sysdeps/i386/fpu/libm-test-ulps
new file mode 100644
index 000000000..4efc714b2
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/libm-test-ulps
@@ -0,0 +1,1236 @@
+# Begin of automatic generation
+
+# acos
+Test "acos (0.75) == 0.722734247813415611178377352641333362":
+ildouble: 1
+ldouble: 1
+
+# asin
+Test "asin (-0.5) == -pi/6":
+ildouble: 1
+ldouble: 1
+Test "asin (-1.0) == -pi/2":
+ildouble: 1
+ldouble: 1
+Test "asin (0.5) == pi/6":
+ildouble: 1
+ldouble: 1
+Test "asin (0.75) == 0.848062078981481008052944338998418080":
+ildouble: 1
+ldouble: 1
+Test "asin (1.0) == pi/2":
+ildouble: 1
+ldouble: 1
+
+# atanh
+Test "atanh (0.75) == 0.972955074527656652552676371721589865":
+ildouble: 2
+ldouble: 1
+
+# cacos
+Test "Imaginary part of: cacos (0.75 + 1.25 i) == 1.11752014915610270578240049553777969 - 1.13239363160530819522266333696834467 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+# cacosh
+Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 9
+idouble: 1
+ifloat: 9
+ildouble: 6
+ldouble: 6
+Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+ildouble: 1
+ldouble: 1
+Test "Real part of: cacosh (0.75 + 1.25 i) == 1.13239363160530819522266333696834467 + 1.11752014915610270578240049553777969 i":
+ildouble: 1
+ldouble: 1
+
+# casin
+Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+# casinh
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 5
+ldouble: 5
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 5
+ldouble: 5
+Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# catan
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+double: 1
+idouble: 1
+
+# cbrt
+Test "cbrt (-27.0) == -3.0":
+ildouble: 1
+ldouble: 1
+Test "cbrt (0.75) == 0.908560296416069829445605878163630251":
+ildouble: 1
+ldouble: 1
+
+# ccos
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+ildouble: 1
+ldouble: 1
+
+# ccosh
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# cexp
+Test "Real part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+ildouble: 1
+ldouble: 1
+
+# clog
+Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# cos
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "cos (pi/2) == 0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# cosh
+Test "cosh (0.75) == 1.29468328467684468784170818539018176":
+ildouble: 1
+
+# cpow
+Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+float: 3
+ifloat: 3
+ildouble: 6
+ldouble: 6
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i":
+float: 1
+ifloat: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 3
+ldouble: 3
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+# csin
+Test "Real part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
+float: 1
+ifloat: 1
+
+# csinh
+Test "Real part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+
+# ctan
+Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+double: 1
+idouble: 1
+ildouble: 439
+ldouble: 439
+Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Real part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+ildouble: 5
+ldouble: 5
+Test "Imaginary part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+float: 1
+ifloat: 1
+ildouble: 25
+ldouble: 25
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+ifloat: 1
+Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# erf
+Test "erf (1.25) == 0.922900128256458230136523481197281140":
+double: 1
+idouble: 1
+
+# erfc
+Test "erfc (0.75) == 0.288844366346484868401062165408589223":
+float: 1
+ifloat: 1
+Test "erfc (1.25) == 0.0770998717435417698634765188027188596":
+ildouble: 1
+ldouble: 1
+Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
+double: 1
+idouble: 1
+Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# exp
+Test "exp (0.75) == 2.11700001661267466854536981983709561":
+ildouble: 1
+Test "exp (1000.0) == 0.197007111401704699388887935224332313e435":
+ildouble: 754
+Test "exp (50.0) == 5184705528587072464087.45332293348538":
+ildouble: 16
+
+# exp10
+Test "exp10 (-1) == 0.1":
+ildouble: 1
+ldouble: 1
+Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+ildouble: 2
+ldouble: 2
+Test "exp10 (3) == 1000":
+ildouble: 8
+ldouble: 8
+
+# gamma
+Test "gamma (-0.5) == log(2*sqrt(pi))":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+
+# j0
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+
+# j1
+Test "j1 (0.75) == 0.349243602174862192523281016426251335":
+double: 1
+idouble: 1
+Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# jn
+Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+Test "jn (1, 0.75) == 0.349243602174862192523281016426251335":
+double: 1
+idouble: 1
+Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, -1.0) == 0.263061512368745320699785368779050294e-9":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "jn (10, 1.0) == 0.263061512368745320699785368779050294e-9":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+double: 5
+float: 2
+idouble: 5
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+double: 2
+idouble: 2
+ildouble: 1
+ldouble: 1
+Test "jn (3, -1.0) == -0.0195633539826684059189053216217515083":
+ildouble: 1
+ldouble: 1
+Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 1.0) == 0.0195633539826684059189053216217515083":
+ildouble: 1
+ldouble: 1
+Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+double: 5
+float: 2
+idouble: 5
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# lgamma
+Test "lgamma (-0.5) == log(2*sqrt(pi))":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# log
+Test "log (e) == 1":
+float: 1
+ifloat: 1
+
+# log10
+Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+ildouble: 1
+ldouble: 1
+Test "log10 (e) == log10(e)":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# sincos
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# sinh
+Test "sinh (0.75) == 0.822316731935829980703661634446913849":
+double: 1
+ildouble: 1
+
+# tan
+Test "tan (pi/4) == 1":
+double: 1
+idouble: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+ifloat: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "tgamma (4) == 6":
+ildouble: 1
+ldouble: 1
+
+# y0
+Test "y0 (0.125) == -1.38968062514384052915582277745018693":
+ildouble: 1
+ldouble: 1
+Test "y0 (0.75) == -0.137172769385772397522814379396581855":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# y1
+Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+ildouble: 1
+ldouble: 1
+Test "y1 (1.0) == -0.781212821300288716547150000047964821":
+double: 1
+idouble: 1
+Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# yn
+Test "yn (0, 0.125) == -1.38968062514384052915582277745018693":
+ildouble: 1
+ldouble: 1
+Test "yn (0, 0.75) == -0.137172769385772397522814379396581855":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+ildouble: 1
+ldouble: 1
+Test "yn (1, 1.0) == -0.781212821300288716547150000047964821":
+double: 1
+idouble: 1
+Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+Test "yn (1, 2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+float: 1
+ifloat: 1
+ildouble: 4
+ldouble: 4
+Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+ildouble: 1
+ldouble: 1
+Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# Maximal error of functions:
+Function: "acos":
+ildouble: 622
+ldouble: 622
+
+Function: "asin":
+ildouble: 1
+ldouble: 1
+
+Function: "atanh":
+ildouble: 2
+ldouble: 1
+
+Function: Imaginary part of "cacos":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cacosh":
+double: 1
+float: 9
+idouble: 1
+ifloat: 9
+ildouble: 6
+ldouble: 6
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "casin":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "catanh":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cbrt":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccos":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccos":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cexp":
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "cexp":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cosh":
+ildouble: 1
+
+Function: Real part of "cpow":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+ildouble: 763
+ldouble: 763
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csin":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csin":
+float: 1
+ifloat: 1
+
+Function: Real part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "ctan":
+double: 1
+idouble: 1
+ildouble: 439
+ldouble: 439
+
+Function: Imaginary part of "ctan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "ctanh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "ctanh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 25
+ldouble: 25
+
+Function: "erf":
+double: 1
+idouble: 1
+
+Function: "erfc":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "exp":
+ildouble: 754
+
+Function: "exp10":
+ildouble: 8
+ldouble: 8
+
+Function: "gamma":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "hypot":
+float: 1
+
+Function: "j0":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "j1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "jn":
+double: 5
+float: 2
+idouble: 5
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log":
+float: 1
+ifloat: 1
+
+Function: "log10":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "sinh":
+double: 1
+ildouble: 1
+
+Function: "tan":
+double: 1
+idouble: 1
+
+Function: "tgamma":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "y1":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "yn":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+# end of automatic generation
diff --git a/libc/sysdeps/i386/fpu/mpa.c b/libc/sysdeps/i386/fpu/mpa.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/mpa.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/mpatan.c b/libc/sysdeps/i386/fpu/mpatan.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/mpatan.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/mpatan2.c b/libc/sysdeps/i386/fpu/mpatan2.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/mpatan2.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/mpexp.c b/libc/sysdeps/i386/fpu/mpexp.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/mpexp.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/mplog.c b/libc/sysdeps/i386/fpu/mplog.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/mplog.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/mpsqrt.c b/libc/sysdeps/i386/fpu/mpsqrt.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/mpsqrt.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/mptan.c b/libc/sysdeps/i386/fpu/mptan.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/mptan.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/s_asinh.S b/libc/sysdeps/i386/fpu/s_asinh.S
new file mode 100644
index 000000000..ca042b414
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_asinh.S
@@ -0,0 +1,135 @@
+/* ix87 specific implementation of arcsinh.
+ Copyright (C) 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(huge,@object)
+huge: .double 1e+300
+ ASM_SIZE_DIRECTIVE(huge)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__asinh)
+ movl 8(%esp), %ecx
+ movl $0x7fffffff, %eax
+ andl %ecx, %eax
+ andl $0x80000000, %ecx
+ movl %eax, %edx
+ orl $0x800fffff, %edx
+ incl %edx
+ jz 7f // x in ±Inf or NaN
+ xorl %ecx, 8(%esp)
+ fldl 4(%esp) // |x|
+ cmpl $0x3e300000, %eax
+ jb 2f // |x| < 2^-28
+ fldln2 // log(2) : |x|
+ cmpl $0x41b00000, %eax
+ fxch // |x| : log(2)
+ ja 3f // |x| > 2^28
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ cmpl $0x40000000, %eax
+ ja 5f // |x| > 2
+
+ // 2^-28 <= |x| <= 2 => y = sign(x)*log1p(|x|+|x|^2/(1+sqrt(1+|x|^2)))
+ fld %st // |x| : |x| : log(2)
+ fmul %st(1) // |x|^2 : |x| : log(2)
+ fld %st // |x|^2 : |x|^2 : |x| : log(2)
+ faddl MO(one) // 1+|x|^2 : |x|^2 : |x| : log(2)
+ fsqrt // sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
+ faddl MO(one) // 1+sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
+ fdivrp // |x|^2/(1+sqrt(1+|x|^2)) : |x| : log(2)
+ faddp // |x|+|x|^2/(1+sqrt(1+|x|^2)) : log(2)
+ fcoml MO(limit)
+ fnstsw
+ sahf
+ ja 6f
+ fyl2xp1
+ jecxz 4f
+ fchs
+4: ret
+
+7: fldl 4(%esp)
+ ret
+
+6: faddl MO(one)
+ fyl2x
+ jecxz 4f
+ fchs
+4: ret
+
+ // |x| < 2^-28 => y = x (inexact iff |x| != 0.0)
+ .align ALIGNARG(4)
+2:
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ jecxz 4f
+ fchs // x
+4: fld %st // x : x
+ faddl MO(huge) // huge+x : x
+ fstp %st(0) // x
+ ret
+
+ // |x| > 2^28 => y = sign(x) * (log(|x|) + log(2))
+ .align ALIGNARG(4)
+3: fyl2x // log(|x|)
+ fldln2 // log(2) : log(|x|)
+ faddp // log(|x|)+log(2)
+ jecxz 4f
+ fchs
+4: ret
+
+ // |x| > 2 => y = sign(x) * log(2*|x| + 1/(|x|+sqrt(x*x+1)))
+ .align ALIGNARG(4)
+5: fld %st // |x| : |x| : log(2)
+ fadd %st, %st(1) // |x| : 2*|x| : log(2)
+ fld %st // |x| : |x| : 2*|x| : log(2)
+ fmul %st(1) // |x|^2 : |x| : 2*|x| : log(2)
+ faddl MO(one) // 1+|x|^2 : |x| : 2*|x| : log(2)
+ fsqrt // sqrt(1+|x|^2) : |x| : 2*|x| : log(2)
+ faddp // |x|+sqrt(1+|x|^2) : 2*|x| : log(2)
+ fdivrl MO(one) // 1/(|x|+sqrt(1+|x|^2)) : 2*|x| : log(2)
+ faddp // 2*|x|+1/(|x|+sqrt(1+|x|^2)) : log(2)
+ fyl2x // log(2*|x|+1/(|x|+sqrt(1+|x|^2)))
+ jecxz 4f
+ fchs
+4: ret
+END(__asinh)
+weak_alias (__asinh, asinh)
diff --git a/libc/sysdeps/i386/fpu/s_asinhf.S b/libc/sysdeps/i386/fpu/s_asinhf.S
new file mode 100644
index 000000000..d0ce6afc2
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_asinhf.S
@@ -0,0 +1,135 @@
+/* ix87 specific implementation of arcsinh.
+ Copyright (C) 1996, 1997, 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(huge,@object)
+huge: .double 1e+36
+ ASM_SIZE_DIRECTIVE(huge)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__asinhf)
+ movl 4(%esp), %ecx
+ movl $0x7fffffff, %eax
+ andl %ecx, %eax
+ andl $0x80000000, %ecx
+ movl %eax, %edx
+ orl $0x807fffff, %edx
+ incl %edx
+ jz 7f // x in ±Inf or NaN
+ xorl %ecx, 4(%esp)
+ flds 4(%esp) // |x|
+ cmpl $0x38000000, %eax
+ jb 2f // |x| < 2^-14
+ fldln2 // log(2) : |x|
+ cmpl $0x47000000, %eax
+ fxch // |x| : log(2)
+ ja 3f // |x| > 2^14
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ cmpl $0x40000000, %eax
+ ja 5f // |x| > 2
+
+ // 2^-14 <= |x| <= 2 => y = sign(x)*log1p(|x|+|x|^2/(1+sqrt(1+|x|^2)))
+ fld %st // |x| : |x| : log(2)
+ fmul %st(1) // |x|^2 : |x| : log(2)
+ fld %st // |x|^2 : |x|^2 : |x| : log(2)
+ faddl MO(one) // 1+|x|^2 : |x|^2 : |x| : log(2)
+ fsqrt // sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
+ faddl MO(one) // 1+sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
+ fdivrp // |x|^2/(1+sqrt(1+|x|^2)) : |x| : log(2)
+ faddp // |x|+|x|^2/(1+sqrt(1+|x|^2)) : log(2)
+ fcoml MO(limit)
+ fnstsw
+ sahf
+ ja 6f
+ fyl2xp1
+ jecxz 4f
+ fchs
+4: ret
+
+7: flds 4(%esp)
+ ret
+
+6: faddl MO(one)
+ fyl2x
+ jecxz 4f
+ fchs
+4: ret
+
+ // |x| < 2^-14 => y = x (inexact iff |x| != 0.0)
+ .align ALIGNARG(4)
+2:
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ jecxz 4f
+ fchs // x
+4: fld %st // x : x
+ faddl MO(huge) // huge+x : x
+ fstp %st(0) // x
+ ret
+
+ // |x| > 2^14 => y = sign(x) * (log(|x|) + log(2))
+ .align ALIGNARG(4)
+3: fyl2x // log(|x|)
+ fldln2 // log(2) : log(|x|)
+ faddp // log(|x|)+log(2)
+ jecxz 4f
+ fchs
+4: ret
+
+ // |x| > 2 => y = sign(x) * log(2*|x| + 1/(|x|+sqrt(x*x+1)))
+ .align ALIGNARG(4)
+5: fld %st // |x| : |x| : log(2)
+ fadd %st, %st(1) // |x| : 2*|x| : log(2)
+ fld %st // |x| : |x| : 2*|x| : log(2)
+ fmul %st(1) // |x|^2 : |x| : 2*|x| : log(2)
+ faddl MO(one) // 1+|x|^2 : |x| : 2*|x| : log(2)
+ fsqrt // sqrt(1+|x|^2) : |x| : 2*|x| : log(2)
+ faddp // |x|+sqrt(1+|x|^2) : 2*|x| : log(2)
+ fdivrl MO(one) // 1/(|x|+sqrt(1+|x|^2)) : 2*|x| : log(2)
+ faddp // 2*|x|+1/(|x|+sqrt(1+|x|^2)) : log(2)
+ fyl2x // log(2*|x|+1/(|x|+sqrt(1+|x|^2)))
+ jecxz 4f
+ fchs
+4: ret
+END(__asinhf)
+weak_alias (__asinhf, asinhf)
diff --git a/libc/sysdeps/i386/fpu/s_asinhl.S b/libc/sysdeps/i386/fpu/s_asinhl.S
new file mode 100644
index 000000000..1040eead1
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_asinhl.S
@@ -0,0 +1,143 @@
+/* ix87 specific implementation of arcsinh.
+ Copyright (C) 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(huge,@object)
+huge: .tfloat 1e+4930
+ ASM_SIZE_DIRECTIVE(huge)
+ .align ALIGNARG(4)
+ /* Please note that we use double value for 1.0. This number
+ has an exact representation and so we don't get accuracy
+ problems. The advantage is that the code is simpler. */
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__asinhl)
+ movl 12(%esp), %ecx
+ movl $0x7fff, %eax
+ andl %ecx, %eax
+ andl $0x8000, %ecx
+ movl %eax, %edx
+ orl $0xffff8000, %edx
+ incl %edx
+ jz 7f // x in ±Inf or NaN
+ xorl %ecx, 12(%esp)
+ fldt 4(%esp) // |x|
+ cmpl $0x3fde, %eax
+ jb 2f // |x| < 2^-34
+ fldln2 // log(2) : |x|
+ cmpl $0x4020, %eax
+ fxch // |x| : log(2)
+ ja 3f // |x| > 2^34
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ cmpl $0x4000, %eax
+ ja 5f // |x| > 2
+
+ // 2^-34 <= |x| <= 2 => y = sign(x)*log1p(|x|+|x|^2/(1+sqrt(1+|x|^2)))
+ fld %st // |x| : |x| : log(2)
+ fmul %st(1) // |x|^2 : |x| : log(2)
+ fld %st // |x|^2 : |x|^2 : |x| : log(2)
+ faddl MO(one) // 1+|x|^2 : |x|^2 : |x| : log(2)
+ fsqrt // sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
+ faddl MO(one) // 1+sqrt(1+|x|^2) : |x|^2 : |x| : log(2)
+ fdivrp // |x|^2/(1+sqrt(1+|x|^2)) : |x| : log(2)
+ faddp // |x|+|x|^2/(1+sqrt(1+|x|^2)) : log(2)
+ fcoml MO(limit)
+ fnstsw
+ sahf
+ ja 6f
+ fyl2xp1
+ jecxz 4f
+ fchs
+4: ret
+
+7: fldt 4(%esp)
+ ret
+
+6: faddl MO(one)
+ fyl2x
+ jecxz 4f
+ fchs
+4: ret
+
+ // |x| < 2^-34 => y = x (inexact iff |x| != 0.0)
+ .align ALIGNARG(4)
+2:
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ jecxz 4f
+ fchs // x
+4: fld %st // x : x
+ fldt MO(huge) // huge : x : x
+ faddp // huge+x : x
+ fstp %st(0) // x
+ ret
+
+ // |x| > 2^34 => y = sign(x) * (log(|x|) + log(2))
+ .align ALIGNARG(4)
+3: fyl2x // log(|x|)
+ fldln2 // log(2) : log(|x|)
+ faddp // log(|x|)+log(2)
+ jecxz 4f
+ fchs
+4: ret
+
+ // |x| > 2 => y = sign(x) * log(2*|x| + 1/(|x|+sqrt(x*x+1)))
+ .align ALIGNARG(4)
+5: fld %st // |x| : |x| : log(2)
+ fadd %st, %st(1) // |x| : 2*|x| : log(2)
+ fld %st // |x| : |x| : 2*|x| : log(2)
+ fmul %st(1) // |x|^2 : |x| : 2*|x| : log(2)
+ faddl MO(one) // 1+|x|^2 : |x| : 2*|x| : log(2)
+ fsqrt // sqrt(1+|x|^2) : |x| : 2*|x| : log(2)
+ faddp // |x|+sqrt(1+|x|^2) : 2*|x| : log(2)
+ fdivrl MO(one) // 1/(|x|+sqrt(1+|x|^2)) : 2*|x| : log(2)
+ faddp // 2*|x|+1/(|x|+sqrt(1+|x|^2)) : log(2)
+ fyl2x // log(2*|x|+1/(|x|+sqrt(1+|x|^2)))
+ jecxz 4f
+ fchs
+4: ret
+END(__asinhl)
+weak_alias (__asinhl, asinhl)
diff --git a/libc/sysdeps/i386/fpu/s_atan.S b/libc/sysdeps/i386/fpu/s_atan.S
new file mode 100644
index 000000000..7502f6d82
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_atan.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_atan.S,v 1.4 1995/05/08 23:50:41 jtc Exp $")
+
+ENTRY(__atan)
+ fldl 4(%esp)
+ fld1
+ fpatan
+ ret
+END (__atan)
+weak_alias (__atan, atan)
diff --git a/libc/sysdeps/i386/fpu/s_atanf.S b/libc/sysdeps/i386/fpu/s_atanf.S
new file mode 100644
index 000000000..70232c824
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_atanf.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_atanf.S,v 1.3 1995/05/08 23:51:33 jtc Exp $")
+
+ENTRY(__atanf)
+ flds 4(%esp)
+ fld1
+ fpatan
+ ret
+END (__atanf)
+weak_alias (__atanf, atanf)
diff --git a/libc/sysdeps/i386/fpu/s_atanl.c b/libc/sysdeps/i386/fpu/s_atanl.c
new file mode 100644
index 000000000..b7dba88aa
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_atanl.c
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <math_private.h>
+
+long double
+__atanl (long double x)
+{
+ long double res;
+
+ asm ("fld1\n"
+ "fpatan"
+ : "=t" (res) : "0" (x));
+
+ return res;
+}
+
+weak_alias (__atanl, atanl)
diff --git a/libc/sysdeps/i386/fpu/s_cbrt.S b/libc/sysdeps/i386/fpu/s_cbrt.S
new file mode 100644
index 000000000..e180b1546
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_cbrt.S
@@ -0,0 +1,205 @@
+/* Compute cubic root of double value.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
+ Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(f7,@object)
+f7: .double -0.145263899385486377
+ ASM_SIZE_DIRECTIVE(f7)
+ ASM_TYPE_DIRECTIVE(f6,@object)
+f6: .double 0.784932344976639262
+ ASM_SIZE_DIRECTIVE(f6)
+ ASM_TYPE_DIRECTIVE(f5,@object)
+f5: .double -1.83469277483613086
+ ASM_SIZE_DIRECTIVE(f5)
+ ASM_TYPE_DIRECTIVE(f4,@object)
+f4: .double 2.44693122563534430
+ ASM_SIZE_DIRECTIVE(f4)
+ ASM_TYPE_DIRECTIVE(f3,@object)
+f3: .double -2.11499494167371287
+ ASM_SIZE_DIRECTIVE(f3)
+ ASM_TYPE_DIRECTIVE(f2,@object)
+f2: .double 1.50819193781584896
+ ASM_SIZE_DIRECTIVE(f2)
+ ASM_TYPE_DIRECTIVE(f1,@object)
+f1: .double 0.354895765043919860
+ ASM_SIZE_DIRECTIVE(f1)
+
+#define CBRT2 1.2599210498948731648
+#define ONE_CBRT2 0.793700525984099737355196796584
+#define SQR_CBRT2 1.5874010519681994748
+#define ONE_SQR_CBRT2 0.629960524947436582364439673883
+
+ ASM_TYPE_DIRECTIVE(factor,@object)
+factor: .double ONE_SQR_CBRT2
+ .double ONE_CBRT2
+ .double 1.0
+ .double CBRT2
+ .double SQR_CBRT2
+ ASM_SIZE_DIRECTIVE(factor)
+
+ ASM_TYPE_DIRECTIVE(two54,@object)
+two54: .byte 0, 0, 0, 0, 0, 0, 0x50, 0x43
+ ASM_SIZE_DIRECTIVE(two54)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ebx)
+#define MOX(op,x) op##@GOTOFF(%ebx,x,1)
+#else
+#define MO(op) op
+#define MOX(op,x) op(x)
+#endif
+
+ .text
+ENTRY(__cbrt)
+ movl 4(%esp), %ecx
+ movl 8(%esp), %eax
+ movl %eax, %edx
+ andl $0x7fffffff, %eax
+ orl %eax, %ecx
+ jz 1f
+ xorl %ecx, %ecx
+ cmpl $0x7ff00000, %eax
+ jae 1f
+
+#ifdef PIC
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebx, 0)
+ LOAD_PIC_REG (bx)
+#endif
+
+ cmpl $0x00100000, %eax
+ jae 2f
+
+#ifdef PIC
+ fldl 8(%esp)
+#else
+ fldl 4(%esp)
+#endif
+ fmull MO(two54)
+ movl $-54, %ecx
+#ifdef PIC
+ fstpl 8(%esp)
+ movl 12(%esp), %eax
+#else
+ fstpl 4(%esp)
+ movl 8(%esp), %eax
+#endif
+ movl %eax, %edx
+ andl $0x7fffffff, %eax
+
+2: shrl $20, %eax
+ andl $0x800fffff, %edx
+ subl $1022, %eax
+ orl $0x3fe00000, %edx
+ addl %eax, %ecx
+#ifdef PIC
+ movl %edx, 12(%esp)
+
+ fldl 8(%esp) /* xm */
+#else
+ movl %edx, 8(%esp)
+
+ fldl 4(%esp) /* xm */
+#endif
+ fabs
+
+ /* The following code has two tracks:
+ a) compute the normalized cbrt value
+ b) compute xe/3 and xe%3
+ The right track computes the value for b) and this is done
+ in an optimized way by avoiding division.
+
+ But why two tracks at all? Very easy: efficiency. Some FP
+ instruction can overlap with a certain amount of integer (and
+ FP) instructions. So we get (except for the imull) all
+ instructions for free. */
+
+ fld %st(0) /* xm : xm */
+
+ fmull MO(f7) /* f7*xm : xm */
+ movl $1431655766, %eax
+ faddl MO(f6) /* f6+f7*xm : xm */
+ imull %ecx
+ fmul %st(1) /* (f6+f7*xm)*xm : xm */
+ movl %ecx, %eax
+ faddl MO(f5) /* f5+(f6+f7*xm)*xm : xm */
+ sarl $31, %eax
+ fmul %st(1) /* (f5+(f6+f7*xm)*xm)*xm : xm */
+ subl %eax, %edx
+ faddl MO(f4) /* f4+(f5+(f6+f7*xm)*xm)*xm : xm */
+ fmul %st(1) /* (f4+(f5+(f6+f7*xm)*xm)*xm)*xm : xm */
+ faddl MO(f3) /* f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm : xm */
+ fmul %st(1) /* (f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm : xm */
+ faddl MO(f2) /* f2+(f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm : xm */
+ fmul %st(1) /* (f2+(f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm)*xm : xm */
+ faddl MO(f1) /* u:=f1+(f2+(f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm)*xm : xm */
+
+ fld %st /* u : u : xm */
+ fmul %st(1) /* u*u : u : xm */
+ fld %st(2) /* xm : u*u : u : xm */
+ fadd %st /* 2*xm : u*u : u : xm */
+ fxch %st(1) /* u*u : 2*xm : u : xm */
+ fmul %st(2) /* t2:=u*u*u : 2*xm : u : xm */
+ movl %edx, %eax
+ fadd %st, %st(1) /* t2 : t2+2*xm : u : xm */
+ leal (%edx,%edx,2),%edx
+ fadd %st(0) /* 2*t2 : t2+2*xm : u : xm */
+ subl %edx, %ecx
+ faddp %st, %st(3) /* t2+2*xm : u : 2*t2+xm */
+ shll $3, %ecx
+ fmulp /* u*(t2+2*xm) : 2*t2+xm */
+ fdivp %st, %st(1) /* u*(t2+2*xm)/(2*t2+xm) */
+ fmull MOX(16+factor,%ecx) /* u*(t2+2*xm)/(2*t2+xm)*FACT */
+ pushl %eax
+ cfi_adjust_cfa_offset (4)
+ fildl (%esp) /* xe/3 : u*(t2+2*xm)/(2*t2+xm)*FACT */
+ fxch /* u*(t2+2*xm)/(2*t2+xm)*FACT : xe/3 */
+ fscale /* u*(t2+2*xm)/(2*t2+xm)*FACT*2^xe/3 */
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+#ifdef PIC
+ movl 12(%esp), %eax
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+#else
+ movl 8(%esp), %eax
+#endif
+ testl %eax, %eax
+ fstp %st(1)
+ jns 4f
+ fchs
+4: ret
+
+ /* Return the argument. */
+1: fldl 4(%esp)
+ ret
+END(__cbrt)
+weak_alias (__cbrt, cbrt)
diff --git a/libc/sysdeps/i386/fpu/s_cbrtf.S b/libc/sysdeps/i386/fpu/s_cbrtf.S
new file mode 100644
index 000000000..2ff4f6e08
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_cbrtf.S
@@ -0,0 +1,182 @@
+/* Compute cubic root of float value.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
+ Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(f3,@object)
+f3: .double 0.191502161678719066
+ ASM_SIZE_DIRECTIVE(f3)
+ ASM_TYPE_DIRECTIVE(f2,@object)
+f2: .double 0.697570460207922770
+ ASM_SIZE_DIRECTIVE(f2)
+ ASM_TYPE_DIRECTIVE(f1,@object)
+f1: .double 0.492659620528969547
+ ASM_SIZE_DIRECTIVE(f1)
+
+#define CBRT2 1.2599210498948731648
+#define ONE_CBRT2 0.793700525984099737355196796584
+#define SQR_CBRT2 1.5874010519681994748
+#define ONE_SQR_CBRT2 0.629960524947436582364439673883
+
+ ASM_TYPE_DIRECTIVE(factor,@object)
+ .align ALIGNARG(4)
+factor: .double ONE_SQR_CBRT2
+ .double ONE_CBRT2
+ .double 1.0
+ .double CBRT2
+ .double SQR_CBRT2
+ ASM_SIZE_DIRECTIVE(factor)
+
+ ASM_TYPE_DIRECTIVE(two25,@object)
+two25: .byte 0, 0, 0, 0x4c
+ ASM_SIZE_DIRECTIVE(two25)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ebx)
+#define MOX(op,x) op##@GOTOFF(%ebx,x,1)
+#else
+#define MO(op) op
+#define MOX(op,x) op(x)
+#endif
+
+ .text
+ENTRY(__cbrtf)
+ movl 4(%esp), %eax
+ xorl %ecx, %ecx
+ movl %eax, %edx
+ andl $0x7fffffff, %eax
+ jz 1f
+ cmpl $0x7f800000, %eax
+ jae 1f
+
+#ifdef PIC
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebx, 0)
+ LOAD_PIC_REG (bx)
+#endif
+
+ cmpl $0x00800000, %eax
+ jae 2f
+
+#ifdef PIC
+ flds 8(%esp)
+#else
+ flds 4(%esp)
+#endif
+ fmuls MO(two25)
+ movl $-25, %ecx
+#ifdef PIC
+ fstps 8(%esp)
+ movl 8(%esp), %eax
+#else
+ fstps 4(%esp)
+ movl 4(%esp), %eax
+#endif
+ movl %eax, %edx
+ andl $0x7fffffff, %eax
+
+2: shrl $23, %eax
+ andl $0x807fffff, %edx
+ subl $126, %eax
+ orl $0x3f000000, %edx
+ addl %eax, %ecx
+#ifdef PIC
+ movl %edx, 8(%esp)
+
+ flds 8(%esp) /* xm */
+#else
+ movl %edx, 4(%esp)
+
+ flds 4(%esp) /* xm */
+#endif
+ fabs
+
+ /* The following code has two tracks:
+ a) compute the normalized cbrt value
+ b) compute xe/3 and xe%3
+ The right track computes the value for b) and this is done
+ in an optimized way by avoiding division.
+
+ But why two tracks at all? Very easy: efficiency. Some FP
+ instruction can overlap with a certain amount of integer (and
+ FP) instructions. So we get (except for the imull) all
+ instructions for free. */
+
+ fld %st(0) /* xm : xm */
+ fmull MO(f3) /* f3*xm : xm */
+ movl $1431655766, %eax
+ fsubrl MO(f2) /* f2-f3*xm : xm */
+ imull %ecx
+ fmul %st(1) /* (f2-f3*xm)*xm : xm */
+ movl %ecx, %eax
+ faddl MO(f1) /* u:=f1+(f2-f3*xm)*xm : xm */
+ sarl $31, %eax
+ fld %st /* u : u : xm */
+ subl %eax, %edx
+ fmul %st(1) /* u*u : u : xm */
+ fld %st(2) /* xm : u*u : u : xm */
+ fadd %st /* 2*xm : u*u : u : xm */
+ fxch %st(1) /* u*u : 2*xm : u : xm */
+ fmul %st(2) /* t2:=u*u*u : 2*xm : u : xm */
+ movl %edx, %eax
+ fadd %st, %st(1) /* t2 : t2+2*xm : u : xm */
+ leal (%edx,%edx,2),%edx
+ fadd %st(0) /* 2*t2 : t2+2*xm : u : xm */
+ subl %edx, %ecx
+ faddp %st, %st(3) /* t2+2*xm : u : 2*t2+xm */
+ shll $3, %ecx
+ fmulp /* u*(t2+2*xm) : 2*t2+xm */
+ fdivp %st, %st(1) /* u*(t2+2*xm)/(2*t2+xm) */
+ fmull MOX(16+factor,%ecx) /* u*(t2+2*xm)/(2*t2+xm)*FACT */
+ pushl %eax
+ cfi_adjust_cfa_offset (4)
+ fildl (%esp) /* xe/3 : u*(t2+2*xm)/(2*t2+xm)*FACT */
+ fxch /* u*(t2+2*xm)/(2*t2+xm)*FACT : xe/3 */
+ fscale /* u*(t2+2*xm)/(2*t2+xm)*FACT*2^xe/3 */
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+#ifdef PIC
+ movl 8(%esp), %eax
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+#else
+ movl 4(%esp), %eax
+#endif
+ testl %eax, %eax
+ fstp %st(1)
+ jns 4f
+ fchs
+4: ret
+
+ /* Return the argument. */
+1: flds 4(%esp)
+ ret
+END(__cbrtf)
+weak_alias (__cbrtf, cbrtf)
diff --git a/libc/sysdeps/i386/fpu/s_cbrtl.S b/libc/sysdeps/i386/fpu/s_cbrtl.S
new file mode 100644
index 000000000..637ad729c
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_cbrtl.S
@@ -0,0 +1,233 @@
+/* Compute cubic root of long double value.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
+ Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(f8,@object)
+f8: .tfloat 0.161617097923756032
+ ASM_SIZE_DIRECTIVE(f8)
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(f7,@object)
+f7: .tfloat -0.988553671195413709
+ ASM_SIZE_DIRECTIVE(f7)
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(f6,@object)
+f6: .tfloat 2.65298938441952296
+ ASM_SIZE_DIRECTIVE(f6)
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(f5,@object)
+f5: .tfloat -4.11151425200350531
+ ASM_SIZE_DIRECTIVE(f5)
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(f4,@object)
+f4: .tfloat 4.09559907378707839
+ ASM_SIZE_DIRECTIVE(f4)
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(f3,@object)
+f3: .tfloat -2.82414939754975962
+ ASM_SIZE_DIRECTIVE(f3)
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(f2,@object)
+f2: .tfloat 1.67595307700780102
+ ASM_SIZE_DIRECTIVE(f2)
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(f1,@object)
+f1: .tfloat 0.338058687610520237
+ ASM_SIZE_DIRECTIVE(f1)
+
+#define CBRT2 1.2599210498948731648
+#define ONE_CBRT2 0.793700525984099737355196796584
+#define SQR_CBRT2 1.5874010519681994748
+#define ONE_SQR_CBRT2 0.629960524947436582364439673883
+
+ /* We make the entries in the following table all 16 bytes
+ wide to avoid having to implement a multiplication by 10. */
+ ASM_TYPE_DIRECTIVE(factor,@object)
+ .align ALIGNARG(4)
+factor: .tfloat ONE_SQR_CBRT2
+ .byte 0, 0, 0, 0, 0, 0
+ .tfloat ONE_CBRT2
+ .byte 0, 0, 0, 0, 0, 0
+ .tfloat 1.0
+ .byte 0, 0, 0, 0, 0, 0
+ .tfloat CBRT2
+ .byte 0, 0, 0, 0, 0, 0
+ .tfloat SQR_CBRT2
+ ASM_SIZE_DIRECTIVE(factor)
+
+ ASM_TYPE_DIRECTIVE(two64,@object)
+ .align ALIGNARG(4)
+two64: .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x43
+ ASM_SIZE_DIRECTIVE(two64)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ebx)
+#define MOX(op,x) op##@GOTOFF(%ebx,x,1)
+#else
+#define MO(op) op
+#define MOX(op,x) op(x)
+#endif
+
+ .text
+ENTRY(__cbrtl)
+ movl 4(%esp), %ecx
+ movl 12(%esp), %eax
+ orl 8(%esp), %ecx
+ movl %eax, %edx
+ andl $0x7fff, %eax
+ orl %eax, %ecx
+ jz 1f
+ xorl %ecx, %ecx
+ cmpl $0x7fff, %eax
+ je 1f
+
+#ifdef PIC
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebx, 0)
+ LOAD_PIC_REG (bx)
+#endif
+
+ cmpl $0, %eax
+ jne 2f
+
+#ifdef PIC
+ fldt 8(%esp)
+#else
+ fldt 4(%esp)
+#endif
+ fmull MO(two64)
+ movl $-64, %ecx
+#ifdef PIC
+ fstpt 8(%esp)
+ movl 16(%esp), %eax
+#else
+ fstpt 4(%esp)
+ movl 12(%esp), %eax
+#endif
+ movl %eax, %edx
+ andl $0x7fff, %eax
+
+2: andl $0x8000, %edx
+ subl $16382, %eax
+ orl $0x3ffe, %edx
+ addl %eax, %ecx
+#ifdef PIC
+ movl %edx, 16(%esp)
+
+ fldt 8(%esp) /* xm */
+#else
+ movl %edx, 12(%esp)
+
+ fldt 4(%esp) /* xm */
+#endif
+ fabs
+
+ /* The following code has two tracks:
+ a) compute the normalized cbrt value
+ b) compute xe/3 and xe%3
+ The right track computes the value for b) and this is done
+ in an optimized way by avoiding division.
+
+ But why two tracks at all? Very easy: efficiency. Some FP
+ instruction can overlap with a certain amount of integer (and
+ FP) instructions. So we get (except for the imull) all
+ instructions for free. */
+
+ fldt MO(f8) /* f8 : xm */
+ fmul %st(1) /* f8*xm : xm */
+
+ fldt MO(f7)
+ faddp /* f7+f8*xm : xm */
+ fmul %st(1) /* (f7+f8*xm)*xm : xm */
+ movl $1431655766, %eax
+ fldt MO(f6)
+ faddp /* f6+(f7+f8*xm)*xm : xm */
+ imull %ecx
+ fmul %st(1) /* (f6+(f7+f8*xm)*xm)*xm : xm */
+ movl %ecx, %eax
+ fldt MO(f5)
+ faddp /* f5+(f6+(f7+f8*xm)*xm)*xm : xm */
+ sarl $31, %eax
+ fmul %st(1) /* (f5+(f6+(f7+f8*xm)*xm)*xm)*xm : xm */
+ subl %eax, %edx
+ fldt MO(f4)
+ faddp /* f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm : xm */
+ fmul %st(1) /* (f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm)*xm : xm */
+ fldt MO(f3)
+ faddp /* f3+(f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm)*xm : xm */
+ fmul %st(1) /* (f3+(f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm)*xm)*xm : xm */
+ fldt MO(f2)
+ faddp /* f2+(f3+(f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm)*xm)*xm : xm */
+ fmul %st(1) /* (f2+(f3+(f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm)*xm)*xm)*xm : xm */
+ fldt MO(f1)
+ faddp /* u:=f1+(f2+(f3+(f4+(f5+(f6+(f7+f8*xm)*xm)*xm)*xm)*xm)*xm)*xm : xm */
+
+ fld %st /* u : u : xm */
+ fmul %st(1) /* u*u : u : xm */
+ fld %st(2) /* xm : u*u : u : xm */
+ fadd %st /* 2*xm : u*u : u : xm */
+ fxch %st(1) /* u*u : 2*xm : u : xm */
+ fmul %st(2) /* t2:=u*u*u : 2*xm : u : xm */
+ movl %edx, %eax
+ fadd %st, %st(1) /* t2 : t2+2*xm : u : xm */
+ leal (%edx,%edx,2),%edx
+ fadd %st(0) /* 2*t2 : t2+2*xm : u : xm */
+ subl %edx, %ecx
+ faddp %st, %st(3) /* t2+2*xm : u : 2*t2+xm */
+ shll $4, %ecx
+ fmulp /* u*(t2+2*xm) : 2*t2+xm */
+ fdivp %st, %st(1) /* u*(t2+2*xm)/(2*t2+xm) */
+ fldt MOX(32+factor,%ecx)
+ fmulp /* u*(t2+2*xm)/(2*t2+xm)*FACT */
+ pushl %eax
+ cfi_adjust_cfa_offset (4)
+ fildl (%esp) /* xe/3 : u*(t2+2*xm)/(2*t2+xm)*FACT */
+ fxch /* u*(t2+2*xm)/(2*t2+xm)*FACT : xe/3 */
+ fscale /* u*(t2+2*xm)/(2*t2+xm)*FACT*2^xe/3 */
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+#ifdef PIC
+ movl 16(%esp), %eax
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+#else
+ movl 12(%esp), %eax
+#endif
+ testl $0x8000, %eax
+ fstp %st(1)
+ jz 4f
+ fchs
+4: ret
+
+ /* Return the argument. */
+1: fldt 4(%esp)
+ ret
+END(__cbrtl)
+weak_alias (__cbrtl, cbrtl)
diff --git a/libc/sysdeps/i386/fpu/s_ceil.S b/libc/sysdeps/i386/fpu/s_ceil.S
new file mode 100644
index 000000000..b0159128a
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_ceil.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ceil.S,v 1.4 1995/05/08 23:52:13 jtc Exp $")
+
+ENTRY(__ceil)
+ fldl 4(%esp)
+ subl $8,%esp
+
+ fstcw 4(%esp) /* store fpu control word */
+
+ /* We use here %edx although only the low 1 bits are defined.
+ But none of the operations should care and they are faster
+ than the 16 bit operations. */
+ movl $0x0800,%edx /* round towards +oo */
+ orl 4(%esp),%edx
+ andl $0xfbff,%edx
+ movl %edx,(%esp)
+ fldcw (%esp) /* load modified control word */
+
+ frndint /* round */
+
+ fldcw 4(%esp) /* restore original control word */
+
+ addl $8,%esp
+ ret
+END (__ceil)
+weak_alias (__ceil, ceil)
diff --git a/libc/sysdeps/i386/fpu/s_ceilf.S b/libc/sysdeps/i386/fpu/s_ceilf.S
new file mode 100644
index 000000000..352d40d7c
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_ceilf.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ceilf.S,v 1.3 1995/05/08 23:52:44 jtc Exp $")
+
+ENTRY(__ceilf)
+ flds 4(%esp)
+ subl $8,%esp
+
+ fstcw 4(%esp) /* store fpu control word */
+
+ /* We use here %edx although only the low 1 bits are defined.
+ But none of the operations should care and they are faster
+ than the 16 bit operations. */
+ movl $0x0800,%edx /* round towards +oo */
+ orl 4(%esp),%edx
+ andl $0xfbff,%edx
+ movl %edx,(%esp)
+ fldcw (%esp) /* load modified control word */
+
+ frndint /* round */
+
+ fldcw 4(%esp) /* restore original control word */
+
+ addl $8,%esp
+ ret
+END (__ceilf)
+weak_alias (__ceilf, ceilf)
diff --git a/libc/sysdeps/i386/fpu/s_ceill.S b/libc/sysdeps/i386/fpu/s_ceill.S
new file mode 100644
index 000000000..0128966eb
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_ceill.S
@@ -0,0 +1,33 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ceill)
+ fldt 4(%esp)
+ subl $8,%esp
+
+ fstcw 4(%esp) /* store fpu control word */
+
+ /* We use here %edx although only the low 1 bits are defined.
+ But none of the operations should care and they are faster
+ than the 16 bit operations. */
+ movl $0x0800,%edx /* round towards +oo */
+ orl 4(%esp),%edx
+ andl $0xfbff,%edx
+ movl %edx,(%esp)
+ fldcw (%esp) /* load modified control word */
+
+ frndint /* round */
+
+ fldcw 4(%esp) /* restore original control word */
+
+ addl $8,%esp
+ ret
+END (__ceill)
+weak_alias (__ceill, ceill)
diff --git a/libc/sysdeps/i386/fpu/s_cexp.S b/libc/sysdeps/i386/fpu/s_cexp.S
new file mode 100644
index 000000000..47e3eb66a
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_cexp.S
@@ -0,0 +1,257 @@
+/* ix87 specific implementation of complex exponential function for double.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(huge_nan_null_null,@object)
+huge_nan_null_null:
+ .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+ .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+ .double 0.0
+zero: .double 0.0
+infinity:
+ .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+ .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+ .double 0.0
+ .byte 0, 0, 0, 0, 0, 0, 0, 0x80
+ ASM_SIZE_DIRECTIVE(huge_nan_null_null)
+
+ ASM_TYPE_DIRECTIVE(twopi,@object)
+twopi:
+ .byte 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0xf, 0xc9, 0x1, 0x40
+ .byte 0, 0, 0, 0, 0, 0
+ ASM_SIZE_DIRECTIVE(twopi)
+
+ ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e:
+ .byte 0xbc, 0xf0, 0x17, 0x5c, 0x29, 0x3b, 0xaa, 0xb8, 0xff, 0x3f
+ .byte 0, 0, 0, 0, 0, 0
+ ASM_SIZE_DIRECTIVE(l2e)
+
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ecx)
+#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
+#else
+#define MO(op) op
+#define MOX(op,x,f) op(,x,f)
+#endif
+
+ .text
+ENTRY(__cexp)
+ fldl 8(%esp) /* x */
+ fxam
+ fnstsw
+ fldl 16(%esp) /* y : x */
+#ifdef PIC
+ LOAD_PIC_REG (cx)
+#endif
+ movb %ah, %dh
+ andb $0x45, %ah
+ cmpb $0x05, %ah
+ je 1f /* Jump if real part is +-Inf */
+ cmpb $0x01, %ah
+ je 2f /* Jump if real part is NaN */
+
+ fxam /* y : x */
+ fnstsw
+ /* If the imaginary part is not finite we return NaN+i NaN, as
+ for the case when the real part is NaN. A test for +-Inf and
+ NaN would be necessary. But since we know the stack register
+ we applied `fxam' to is not empty we can simply use one test.
+ Check your FPU manual for more information. */
+ andb $0x01, %ah
+ cmpb $0x01, %ah
+ je 20f
+
+ /* We have finite numbers in the real and imaginary part. Do
+ the real work now. */
+ fxch /* x : y */
+ fldt MO(l2e) /* log2(e) : x : y */
+ fmulp /* x * log2(e) : y */
+ fld %st /* x * log2(e) : x * log2(e) : y */
+ frndint /* int(x * log2(e)) : x * log2(e) : y */
+ fsubr %st, %st(1) /* int(x * log2(e)) : frac(x * log2(e)) : y */
+ fxch /* frac(x * log2(e)) : int(x * log2(e)) : y */
+ f2xm1 /* 2^frac(x * log2(e))-1 : int(x * log2(e)) : y */
+ faddl MO(one) /* 2^frac(x * log2(e)) : int(x * log2(e)) : y */
+ fscale /* e^x : int(x * log2(e)) : y */
+ fst %st(1) /* e^x : e^x : y */
+ fxch %st(2) /* y : e^x : e^x */
+ fsincos /* cos(y) : sin(y) : e^x : e^x */
+ fnstsw
+ testl $0x400, %eax
+ jnz 7f
+ fmulp %st, %st(3) /* sin(y) : e^x : e^x * cos(y) */
+ fmulp %st, %st(1) /* e^x * sin(y) : e^x * cos(y) */
+ movl 4(%esp), %eax /* Pointer to memory for result. */
+ fstpl 8(%eax)
+ fstpl (%eax)
+ ret $4
+
+ /* We have to reduce the argument to fsincos. */
+ .align ALIGNARG(4)
+7: fldt MO(twopi) /* 2*pi : y : e^x : e^x */
+ fxch /* y : 2*pi : e^x : e^x */
+8: fprem1 /* y%(2*pi) : 2*pi : e^x : e^x */
+ fnstsw
+ testl $0x400, %eax
+ jnz 8b
+ fstp %st(1) /* y%(2*pi) : e^x : e^x */
+ fsincos /* cos(y) : sin(y) : e^x : e^x */
+ fmulp %st, %st(3)
+ fmulp %st, %st(1)
+ movl 4(%esp), %eax /* Pointer to memory for result. */
+ fstpl 8(%eax)
+ fstpl (%eax)
+ ret $4
+
+ /* The real part is +-inf. We must make further differences. */
+ .align ALIGNARG(4)
+1: fxam /* y : x */
+ fnstsw
+ movb %ah, %dl
+ testb $0x01, %ah /* See above why 0x01 is usable here. */
+ jne 3f
+
+
+ /* The real part is +-Inf and the imaginary part is finite. */
+ andl $0x245, %edx
+ cmpb $0x40, %dl /* Imaginary part == 0? */
+ je 4f /* Yes -> */
+
+ fxch /* x : y */
+ shrl $5, %edx
+ fstp %st(0) /* y */ /* Drop the real part. */
+ andl $16, %edx /* This puts the sign bit of the real part
+ in bit 4. So we can use it to index a
+ small array to select 0 or Inf. */
+ fsincos /* cos(y) : sin(y) */
+ fnstsw
+ testl $0x0400, %eax
+ jnz 5f
+ fldl MOX(huge_nan_null_null,%edx,1)
+ movl 4(%esp), %edx /* Pointer to memory for result. */
+ fstl 8(%edx)
+ fstpl (%edx)
+ ftst
+ fnstsw
+ shll $23, %eax
+ andl $0x80000000, %eax
+ orl %eax, 4(%edx)
+ fstp %st(0)
+ ftst
+ fnstsw
+ shll $23, %eax
+ andl $0x80000000, %eax
+ orl %eax, 12(%edx)
+ fstp %st(0)
+ ret $4
+ /* We must reduce the argument to fsincos. */
+ .align ALIGNARG(4)
+5: fldt MO(twopi)
+ fxch
+6: fprem1
+ fnstsw
+ testl $0x400, %eax
+ jnz 6b
+ fstp %st(1)
+ fsincos
+ fldl MOX(huge_nan_null_null,%edx,1)
+ movl 4(%esp), %edx /* Pointer to memory for result. */
+ fstl 8(%edx)
+ fstpl (%edx)
+ ftst
+ fnstsw
+ shll $23, %eax
+ andl $0x80000000, %eax
+ orl %eax, 4(%edx)
+ fstp %st(0)
+ ftst
+ fnstsw
+ shll $23, %eax
+ andl $0x80000000, %eax
+ orl %eax, 12(%edx)
+ fstp %st(0)
+ ret $4
+
+ /* The real part is +-Inf and the imaginary part is +-0. So return
+ +-Inf+-0i. */
+ .align ALIGNARG(4)
+4: movl 4(%esp), %eax /* Pointer to memory for result. */
+ fstpl 8(%eax)
+ shrl $5, %edx
+ fstp %st(0)
+ andl $16, %edx
+ fldl MOX(huge_nan_null_null,%edx,1)
+ fstpl (%eax)
+ ret $4
+
+ /* The real part is +-Inf, the imaginary is also is not finite. */
+ .align ALIGNARG(4)
+3: fstp %st(0)
+ fstp %st(0) /* <empty> */
+ andb $0x45, %ah
+ andb $0x47, %dh
+ xorb %dh, %ah
+ jnz 30f
+ fldl MO(infinity) /* Raise invalid exception. */
+ fmull MO(zero)
+ fstp %st(0)
+30: movl %edx, %eax
+ shrl $5, %edx
+ shll $4, %eax
+ andl $16, %edx
+ andl $32, %eax
+ orl %eax, %edx
+ movl 4(%esp), %eax /* Pointer to memory for result. */
+
+ fldl MOX(huge_nan_null_null,%edx,1)
+ fldl MOX(huge_nan_null_null+8,%edx,1)
+ fxch
+ fstpl (%eax)
+ fstpl 8(%eax)
+ ret $4
+
+ /* The real part is NaN. */
+ .align ALIGNARG(4)
+20: fldl MO(infinity) /* Raise invalid exception. */
+ fmull MO(zero)
+ fstp %st(0)
+2: fstp %st(0)
+ fstp %st(0)
+ movl 4(%esp), %eax /* Pointer to memory for result. */
+ fldl MO(huge_nan_null_null+8)
+ fstl (%eax)
+ fstpl 8(%eax)
+ ret $4
+
+END(__cexp)
+weak_alias (__cexp, cexp)
diff --git a/libc/sysdeps/i386/fpu/s_cexpf.S b/libc/sysdeps/i386/fpu/s_cexpf.S
new file mode 100644
index 000000000..f11685409
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_cexpf.S
@@ -0,0 +1,261 @@
+/* ix87 specific implementation of complex exponential function for double.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(huge_nan_null_null,@object)
+huge_nan_null_null:
+ .byte 0, 0, 0x80, 0x7f
+ .byte 0, 0, 0xc0, 0x7f
+ .float 0.0
+zero: .float 0.0
+infinity:
+ .byte 0, 0, 0x80, 0x7f
+ .byte 0, 0, 0xc0, 0x7f
+ .float 0.0
+ .byte 0, 0, 0, 0x80
+ ASM_SIZE_DIRECTIVE(huge_nan_null_null)
+
+ ASM_TYPE_DIRECTIVE(twopi,@object)
+twopi:
+ .byte 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0xf, 0xc9, 0x1, 0x40
+ .byte 0, 0, 0, 0, 0, 0
+ ASM_SIZE_DIRECTIVE(twopi)
+
+ ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e:
+ .byte 0xbc, 0xf0, 0x17, 0x5c, 0x29, 0x3b, 0xaa, 0xb8, 0xff, 0x3f
+ .byte 0, 0, 0, 0, 0, 0
+ ASM_SIZE_DIRECTIVE(l2e)
+
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ecx)
+#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
+#else
+#define MO(op) op
+#define MOX(op,x,f) op(,x,f)
+#endif
+
+ .text
+ENTRY(__cexpf)
+ flds 4(%esp) /* x */
+ fxam
+ fnstsw
+ flds 8(%esp) /* y : x */
+#ifdef PIC
+ LOAD_PIC_REG (cx)
+#endif
+ movb %ah, %dh
+ andb $0x45, %ah
+ cmpb $0x05, %ah
+ je 1f /* Jump if real part is +-Inf */
+ cmpb $0x01, %ah
+ je 2f /* Jump if real part is NaN */
+
+ fxam /* y : x */
+ fnstsw
+ /* If the imaginary part is not finite we return NaN+i NaN, as
+ for the case when the real part is NaN. A test for +-Inf and
+ NaN would be necessary. But since we know the stack register
+ we applied `fxam' to is not empty we can simply use one test.
+ Check your FPU manual for more information. */
+ andb $0x01, %ah
+ cmpb $0x01, %ah
+ je 20f
+
+ /* We have finite numbers in the real and imaginary part. Do
+ the real work now. */
+ fxch /* x : y */
+ fldt MO(l2e) /* log2(e) : x : y */
+ fmulp /* x * log2(e) : y */
+ fld %st /* x * log2(e) : x * log2(e) : y */
+ frndint /* int(x * log2(e)) : x * log2(e) : y */
+ fsubr %st, %st(1) /* int(x * log2(e)) : frac(x * log2(e)) : y */
+ fxch /* frac(x * log2(e)) : int(x * log2(e)) : y */
+ f2xm1 /* 2^frac(x * log2(e))-1 : int(x * log2(e)) : y */
+ faddl MO(one) /* 2^frac(x * log2(e)) : int(x * log2(e)) : y */
+ fscale /* e^x : int(x * log2(e)) : y */
+ fst %st(1) /* e^x : e^x : y */
+ fxch %st(2) /* y : e^x : e^x */
+ fsincos /* cos(y) : sin(y) : e^x : e^x */
+ fnstsw
+ testl $0x400, %eax
+ jnz 7f
+ fmulp %st, %st(3) /* sin(y) : e^x : e^x * cos(y) */
+ fmulp %st, %st(1) /* e^x * sin(y) : e^x * cos(y) */
+ subl $8, %esp
+ cfi_adjust_cfa_offset (8)
+ fstps 4(%esp)
+ fstps (%esp)
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ ret
+
+ /* We have to reduce the argument to fsincos. */
+ .align ALIGNARG(4)
+7: fldt MO(twopi) /* 2*pi : y : e^x : e^x */
+ fxch /* y : 2*pi : e^x : e^x */
+8: fprem1 /* y%(2*pi) : 2*pi : e^x : e^x */
+ fnstsw
+ testl $0x400, %eax
+ jnz 8b
+ fstp %st(1) /* y%(2*pi) : e^x : e^x */
+ fsincos /* cos(y) : sin(y) : e^x : e^x */
+ fmulp %st, %st(3)
+ fmulp %st, %st(1)
+ subl $8, %esp
+ cfi_adjust_cfa_offset (8)
+ fstps 4(%esp)
+ fstps (%esp)
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ ret
+
+ /* The real part is +-inf. We must make further differences. */
+ .align ALIGNARG(4)
+1: fxam /* y : x */
+ fnstsw
+ movb %ah, %dl
+ testb $0x01, %ah /* See above why 0x01 is usable here. */
+ jne 3f
+
+
+ /* The real part is +-Inf and the imaginary part is finite. */
+ andl $0x245, %edx
+ cmpb $0x40, %dl /* Imaginary part == 0? */
+ je 4f /* Yes -> */
+
+ fxch /* x : y */
+ shrl $6, %edx
+ fstp %st(0) /* y */ /* Drop the real part. */
+ andl $8, %edx /* This puts the sign bit of the real part
+ in bit 3. So we can use it to index a
+ small array to select 0 or Inf. */
+ fsincos /* cos(y) : sin(y) */
+ fnstsw
+ testl $0x0400, %eax
+ jnz 5f
+ fxch
+ ftst
+ fnstsw
+ fstp %st(0)
+ shll $23, %eax
+ andl $0x80000000, %eax
+ orl MOX(huge_nan_null_null,%edx,1), %eax
+ movl MOX(huge_nan_null_null,%edx,1), %ecx
+ movl %eax, %edx
+ ftst
+ fnstsw
+ fstp %st(0)
+ shll $23, %eax
+ andl $0x80000000, %eax
+ orl %ecx, %eax
+ ret
+ /* We must reduce the argument to fsincos. */
+ .align ALIGNARG(4)
+5: fldt MO(twopi)
+ fxch
+6: fprem1
+ fnstsw
+ testl $0x400, %eax
+ jnz 6b
+ fstp %st(1)
+ fsincos
+ fxch
+ ftst
+ fnstsw
+ fstp %st(0)
+ shll $23, %eax
+ andl $0x80000000, %eax
+ orl MOX(huge_nan_null_null,%edx,1), %eax
+ movl MOX(huge_nan_null_null,%edx,1), %ecx
+ movl %eax, %edx
+ ftst
+ fnstsw
+ fstp %st(0)
+ shll $23, %eax
+ andl $0x80000000, %eax
+ orl %ecx, %eax
+ ret
+
+ /* The real part is +-Inf and the imaginary part is +-0. So return
+ +-Inf+-0i. */
+ .align ALIGNARG(4)
+4: subl $4, %esp
+ cfi_adjust_cfa_offset (4)
+ fstps (%esp)
+ shrl $6, %edx
+ fstp %st(0)
+ andl $8, %edx
+ movl MOX(huge_nan_null_null,%edx,1), %eax
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ ret
+
+ /* The real part is +-Inf, the imaginary is also is not finite. */
+ .align ALIGNARG(4)
+3: fstp %st(0)
+ fstp %st(0) /* <empty> */
+ andb $0x45, %ah
+ andb $0x47, %dh
+ xorb %dh, %ah
+ jnz 30f
+ flds MO(infinity) /* Raise invalid exception. */
+ fmuls MO(zero)
+ fstp %st(0)
+30: movl %edx, %eax
+ shrl $6, %edx
+ shll $3, %eax
+ andl $8, %edx
+ andl $16, %eax
+ orl %eax, %edx
+
+ movl MOX(huge_nan_null_null,%edx,1), %eax
+ movl MOX(huge_nan_null_null+4,%edx,1), %edx
+ ret
+
+ /* The real part is NaN. */
+ .align ALIGNARG(4)
+20: flds MO(infinity) /* Raise invalid exception. */
+ fmuls MO(zero)
+ fstp %st(0)
+2: fstp %st(0)
+ fstp %st(0)
+ movl MO(huge_nan_null_null+4), %eax
+ movl %eax, %edx
+ ret
+
+END(__cexpf)
+weak_alias (__cexpf, cexpf)
diff --git a/libc/sysdeps/i386/fpu/s_cexpl.S b/libc/sysdeps/i386/fpu/s_cexpl.S
new file mode 100644
index 000000000..8bb0680bc
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_cexpl.S
@@ -0,0 +1,260 @@
+/* ix87 specific implementation of complex exponential function for double.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(huge_nan_null_null,@object)
+huge_nan_null_null:
+ .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+ .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+ .double 0.0
+zero: .double 0.0
+infinity:
+ .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+ .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+ .double 0.0
+ .byte 0, 0, 0, 0, 0, 0, 0, 0x80
+ ASM_SIZE_DIRECTIVE(huge_nan_null_null)
+
+ ASM_TYPE_DIRECTIVE(twopi,@object)
+twopi:
+ .byte 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0xf, 0xc9, 0x1, 0x40
+ .byte 0, 0, 0, 0, 0, 0
+ ASM_SIZE_DIRECTIVE(twopi)
+
+ ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e:
+ .byte 0xbc, 0xf0, 0x17, 0x5c, 0x29, 0x3b, 0xaa, 0xb8, 0xff, 0x3f
+ .byte 0, 0, 0, 0, 0, 0
+ ASM_SIZE_DIRECTIVE(l2e)
+
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%ecx)
+#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
+#else
+#define MO(op) op
+#define MOX(op,x,f) op(,x,f)
+#endif
+
+ .text
+ENTRY(__cexpl)
+ fldt 8(%esp) /* x */
+ fxam
+ fnstsw
+ fldt 20(%esp) /* y : x */
+#ifdef PIC
+ LOAD_PIC_REG (cx)
+#endif
+ movb %ah, %dh
+ andb $0x45, %ah
+ cmpb $0x05, %ah
+ je 1f /* Jump if real part is +-Inf */
+ cmpb $0x01, %ah
+ je 2f /* Jump if real part is NaN */
+
+ fxam /* y : x */
+ fnstsw
+ /* If the imaginary part is not finite we return NaN+i NaN, as
+ for the case when the real part is NaN. A test for +-Inf and
+ NaN would be necessary. But since we know the stack register
+ we applied `fxam' to is not empty we can simply use one test.
+ Check your FPU manual for more information. */
+ andb $0x01, %ah
+ cmpb $0x01, %ah
+ je 20f
+
+ /* We have finite numbers in the real and imaginary part. Do
+ the real work now. */
+ fxch /* x : y */
+ fldt MO(l2e) /* log2(e) : x : y */
+ fmulp /* x * log2(e) : y */
+ fld %st /* x * log2(e) : x * log2(e) : y */
+ frndint /* int(x * log2(e)) : x * log2(e) : y */
+ fsubr %st, %st(1) /* int(x * log2(e)) : frac(x * log2(e)) : y */
+ fxch /* frac(x * log2(e)) : int(x * log2(e)) : y */
+ f2xm1 /* 2^frac(x * log2(e))-1 : int(x * log2(e)) : y */
+ faddl MO(one) /* 2^frac(x * log2(e)) : int(x * log2(e)) : y */
+ fscale /* e^x : int(x * log2(e)) : y */
+ fst %st(1) /* e^x : e^x : y */
+ fxch %st(2) /* y : e^x : e^x */
+ fsincos /* cos(y) : sin(y) : e^x : e^x */
+ fnstsw
+ testl $0x400, %eax
+ jnz 7f
+ fmulp %st, %st(3) /* sin(y) : e^x : e^x * cos(y) */
+ fmulp %st, %st(1) /* e^x * sin(y) : e^x * cos(y) */
+ movl 4(%esp), %eax /* Pointer to memory for result. */
+ fstpt 12(%eax)
+ fstpt (%eax)
+ ret $4
+
+ /* We have to reduce the argument to fsincos. */
+ .align ALIGNARG(4)
+7: fldt MO(twopi) /* 2*pi : y : e^x : e^x */
+ fxch /* y : 2*pi : e^x : e^x */
+8: fprem1 /* y%(2*pi) : 2*pi : e^x : e^x */
+ fnstsw
+ testl $0x400, %eax
+ jnz 8b
+ fstp %st(1) /* y%(2*pi) : e^x : e^x */
+ fsincos /* cos(y) : sin(y) : e^x : e^x */
+ fmulp %st, %st(3)
+ fmulp %st, %st(1)
+ movl 4(%esp), %eax /* Pointer to memory for result. */
+ fstpt 12(%eax)
+ fstpt (%eax)
+ ret $4
+
+ /* The real part is +-inf. We must make further differences. */
+ .align ALIGNARG(4)
+1: fxam /* y : x */
+ fnstsw
+ movb %ah, %dl
+ testb $0x01, %ah /* See above why 0x01 is usable here. */
+ jne 3f
+
+
+ /* The real part is +-Inf and the imaginary part is finite. */
+ andl $0x245, %edx
+ cmpb $0x40, %dl /* Imaginary part == 0? */
+ je 4f /* Yes -> */
+
+ fxch /* x : y */
+ shrl $5, %edx
+ fstp %st(0) /* y */ /* Drop the real part. */
+ andl $16, %edx /* This puts the sign bit of the real part
+ in bit 4. So we can use it to index a
+ small array to select 0 or Inf. */
+ fsincos /* cos(y) : sin(y) */
+ fnstsw
+ testl $0x0400, %eax
+ jnz 5f
+ fldl MOX(huge_nan_null_null,%edx,1)
+ movl 4(%esp), %edx /* Pointer to memory for result. */
+ fld %st
+ fstpt 12(%edx)
+ fstpt (%edx)
+ ftst
+ fnstsw
+ shll $7, %eax
+ andl $0x8000, %eax
+ orl %eax, 8(%edx)
+ fstp %st(0)
+ ftst
+ fnstsw
+ shll $7, %eax
+ andl $0x8000, %eax
+ orl %eax, 20(%edx)
+ fstp %st(0)
+ ret $4
+ /* We must reduce the argument to fsincos. */
+ .align ALIGNARG(4)
+5: fldt MO(twopi)
+ fxch
+6: fprem1
+ fnstsw
+ testl $0x400, %eax
+ jnz 6b
+ fstp %st(1)
+ fsincos
+ fldl MOX(huge_nan_null_null,%edx,1)
+ movl 4(%esp), %edx /* Pointer to memory for result. */
+ fld %st
+ fstpt 12(%edx)
+ fstpt (%edx)
+ ftst
+ fnstsw
+ shll $7, %eax
+ andl $0x8000, %eax
+ orl %eax, 8(%edx)
+ fstp %st(0)
+ ftst
+ fnstsw
+ shll $7, %eax
+ andl $0x8000, %eax
+ orl %eax, 20(%edx)
+ fstp %st(0)
+ ret $4
+
+ /* The real part is +-Inf and the imaginary part is +-0. So return
+ +-Inf+-0i. */
+ .align ALIGNARG(4)
+4: movl 4(%esp), %eax /* Pointer to memory for result. */
+ fstpt 12(%eax)
+ shrl $5, %edx
+ fstp %st(0)
+ andl $16, %edx
+ fldl MOX(huge_nan_null_null,%edx,1)
+ fstpt (%eax)
+ ret $4
+
+ /* The real part is +-Inf, the imaginary is also is not finite. */
+ .align ALIGNARG(4)
+3: fstp %st(0)
+ fstp %st(0) /* <empty> */
+ andb $0x45, %ah
+ andb $0x47, %dh
+ xorb %dh, %ah
+ jnz 30f
+ fldl MO(infinity) /* Raise invalid exception. */
+ fmull MO(zero)
+ fstp %st(0)
+30: movl %edx, %eax
+ shrl $5, %edx
+ shll $4, %eax
+ andl $16, %edx
+ andl $32, %eax
+ orl %eax, %edx
+ movl 4(%esp), %eax /* Pointer to memory for result. */
+
+ fldl MOX(huge_nan_null_null,%edx,1)
+ fldl MOX(huge_nan_null_null+8,%edx,1)
+ fxch
+ fstpt (%eax)
+ fstpt 12(%eax)
+ ret $4
+
+ /* The real part is NaN. */
+ .align ALIGNARG(4)
+20: fldl MO(infinity) /* Raise invalid exception. */
+ fmull MO(zero)
+ fstp %st(0)
+2: fstp %st(0)
+ fstp %st(0)
+ movl 4(%esp), %eax /* Pointer to memory for result. */
+ fldl MO(huge_nan_null_null+8)
+ fld %st(0)
+ fstpt (%eax)
+ fstpt 12(%eax)
+ ret $4
+
+END(__cexpl)
+weak_alias (__cexpl, cexpl)
diff --git a/libc/sysdeps/i386/fpu/s_copysign.S b/libc/sysdeps/i386/fpu/s_copysign.S
new file mode 100644
index 000000000..2520a9442
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_copysign.S
@@ -0,0 +1,20 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_copysign.S,v 1.4 1995/05/08 23:53:02 jtc Exp $")
+
+ENTRY(__copysign)
+ movl 16(%esp),%edx
+ movl 8(%esp),%eax
+ andl $0x80000000,%edx
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,8(%esp)
+ fldl 4(%esp)
+ ret
+END (__copysign)
+weak_alias (__copysign, copysign)
diff --git a/libc/sysdeps/i386/fpu/s_copysignf.S b/libc/sysdeps/i386/fpu/s_copysignf.S
new file mode 100644
index 000000000..57b1a6f11
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_copysignf.S
@@ -0,0 +1,20 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_copysignf.S,v 1.3 1995/05/08 23:53:25 jtc Exp $")
+
+ENTRY(__copysignf)
+ movl 8(%esp),%edx
+ movl 4(%esp),%eax
+ andl $0x80000000,%edx
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,4(%esp)
+ flds 4(%esp)
+ ret
+END (__copysignf)
+weak_alias (__copysignf, copysignf)
diff --git a/libc/sysdeps/i386/fpu/s_copysignl.S b/libc/sysdeps/i386/fpu/s_copysignl.S
new file mode 100644
index 000000000..2163e7b01
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_copysignl.S
@@ -0,0 +1,21 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__copysignl)
+ movl 24(%esp),%edx
+ movl 12(%esp),%eax
+ andl $0x8000,%edx
+ andl $0x7fff,%eax
+ orl %edx,%eax
+ movl %eax,12(%esp)
+ fldt 4(%esp)
+ ret
+END (__copysignl)
+weak_alias (__copysignl, copysignl)
diff --git a/libc/sysdeps/i386/fpu/s_cos.S b/libc/sysdeps/i386/fpu/s_cos.S
new file mode 100644
index 000000000..ac8b1459d
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_cos.S
@@ -0,0 +1,29 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_cos.S,v 1.5 1995/05/08 23:54:00 jtc Exp $")
+
+ENTRY(__cos)
+ fldl 4(%esp)
+ fcos
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ ret
+ .align ALIGNARG(4)
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fcos
+ ret
+END (__cos)
+weak_alias (__cos, cos)
diff --git a/libc/sysdeps/i386/fpu/s_cosf.S b/libc/sysdeps/i386/fpu/s_cosf.S
new file mode 100644
index 000000000..21f87aa87
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_cosf.S
@@ -0,0 +1,29 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_cosf.S,v 1.3 1995/05/08 23:55:16 jtc Exp $")
+
+ENTRY(__cosf)
+ flds 4(%esp)
+ fcos
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ ret
+ .align ALIGNARG(4)
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fcos
+ ret
+END (__cosf)
+weak_alias (__cosf, cosf)
diff --git a/libc/sysdeps/i386/fpu/s_cosl.S b/libc/sysdeps/i386/fpu/s_cosl.S
new file mode 100644
index 000000000..61c9010c9
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_cosl.S
@@ -0,0 +1,31 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__cosl)
+ fldt 4(%esp)
+ fcos
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ ret
+ .align ALIGNARG(4)
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fcos
+ ret
+END (__cosl)
+weak_alias (__cosl, cosl)
diff --git a/libc/sysdeps/i386/fpu/s_expm1.S b/libc/sysdeps/i386/fpu/s_expm1.S
new file mode 100644
index 000000000..e76118363
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_expm1.S
@@ -0,0 +1,86 @@
+/* ix87 specific implementation of exp(x)-1.
+ Copyright (C) 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+ Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>.
+ Corrections by H.J. Lu (hjl@gnu.ai.mit.edu), 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+ /* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(minus1,@object)
+minus1: .double -1.0
+ ASM_SIZE_DIRECTIVE(minus1)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e: .tfloat 1.442695040888963407359924681002
+ ASM_SIZE_DIRECTIVE(l2e)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__expm1)
+ fldl 4(%esp) // x
+ fxam // Is NaN or +-Inf?
+ fstsw %ax
+ movb $0x45, %ch
+ andb %ah, %ch
+ cmpb $0x40, %ch
+ je 3f // If +-0, jump.
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ cmpb $0x05, %ch
+ je 2f // If +-Inf, jump.
+
+ fldt MO(l2e) // log2(e) : x
+ fmulp // log2(e)*x
+ fld %st // log2(e)*x : log2(e)*x
+ frndint // int(log2(e)*x) : log2(e)*x
+ fsubr %st, %st(1) // int(log2(e)*x) : fract(log2(e)*x)
+ fxch // fract(log2(e)*x) : int(log2(e)*x)
+ f2xm1 // 2^fract(log2(e)*x)-1 : int(log2(e)*x)
+ fscale // 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x)
+ fxch // int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fldl MO(one) // 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fscale // 2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fsubrl MO(one) // 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fstp %st(1) // 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fsubrp %st, %st(1) // 2^(log2(e)*x)
+ ret
+
+2: testl $0x200, %eax // Test sign.
+ jz 3f // If positive, jump.
+ fstp %st
+ fldl MO(minus1) // Set result to -1.0.
+3: ret
+END(__expm1)
+weak_alias (__expm1, expm1)
diff --git a/libc/sysdeps/i386/fpu/s_expm1f.S b/libc/sysdeps/i386/fpu/s_expm1f.S
new file mode 100644
index 000000000..88adb75b8
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_expm1f.S
@@ -0,0 +1,86 @@
+/* ix87 specific implementation of exp(x)-1.
+ Copyright (C) 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+ Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>.
+ Corrections by H.J. Lu (hjl@gnu.ai.mit.edu), 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+ /* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(minus1,@object)
+minus1: .double -1.0
+ ASM_SIZE_DIRECTIVE(minus1)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e: .tfloat 1.442695040888963407359924681002
+ ASM_SIZE_DIRECTIVE(l2e)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__expm1f)
+ flds 4(%esp) // x
+ fxam // Is NaN or +-Inf?
+ fstsw %ax
+ movb $0x45, %ch
+ andb %ah, %ch
+ cmpb $0x40, %ch
+ je 3f // If +-0, jump.
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ cmpb $0x05, %ch
+ je 2f // If +-Inf, jump.
+
+ fldt MO(l2e) // log2(e) : x
+ fmulp // log2(e)*x
+ fld %st // log2(e)*x : log2(e)*x
+ frndint // int(log2(e)*x) : log2(e)*x
+ fsubr %st, %st(1) // int(log2(e)*x) : fract(log2(e)*x)
+ fxch // fract(log2(e)*x) : int(log2(e)*x)
+ f2xm1 // 2^fract(log2(e)*x)-1 : int(log2(e)*x)
+ fscale // 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x)
+ fxch // int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fldl MO(one) // 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fscale // 2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fsubrl MO(one) // 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fstp %st(1) // 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fsubrp %st, %st(1) // 2^(log2(e)*x)
+ ret
+
+2: testl $0x200, %eax // Test sign.
+ jz 3f // If positive, jump.
+ fstp %st
+ fldl MO(minus1) // Set result to -1.0.
+3: ret
+END(__expm1f)
+weak_alias (__expm1f, expm1f)
diff --git a/libc/sysdeps/i386/fpu/s_expm1l.S b/libc/sysdeps/i386/fpu/s_expm1l.S
new file mode 100644
index 000000000..2dc379b79
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_expm1l.S
@@ -0,0 +1,87 @@
+/* ix87 specific implementation of exp(x)-1.
+ Copyright (C) 1996, 1997, 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+ Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>.
+ Corrections by H.J. Lu (hjl@gnu.ai.mit.edu), 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+ /* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(minus1,@object)
+minus1: .double -1.0
+ ASM_SIZE_DIRECTIVE(minus1)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e: .tfloat 1.442695040888963407359924681002
+ ASM_SIZE_DIRECTIVE(l2e)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__expm1l)
+ fldt 4(%esp) // x
+ fxam // Is NaN or +-Inf?
+ fstsw %ax
+ movb $0x45, %ch
+ andb %ah, %ch
+ cmpb $0x40, %ch
+ je 3f // If +-0, jump.
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ cmpb $0x05, %ch
+ je 2f // If +-Inf, jump.
+
+ fldt MO(l2e) // log2(e) : x
+ fmulp // log2(e)*x
+ fld %st // log2(e)*x : log2(e)*x
+ frndint // int(log2(e)*x) : log2(e)*x
+ fsubr %st, %st(1) // int(log2(e)*x) : fract(log2(e)*x)
+ fxch // fract(log2(e)*x) : int(log2(e)*x)
+ f2xm1 // 2^fract(log2(e)*x)-1 : int(log2(e)*x)
+ fscale // 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x)
+ fxch // int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fldl MO(one) // 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fscale // 2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fsubrl MO(one) // 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fstp %st(1) // 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fsubrp %st, %st(1) // 2^(log2(e)*x)
+ ret
+
+2: testl $0x200, %eax // Test sign.
+ jz 3f // If positive, jump.
+ fstp %st
+ fldl MO(minus1) // Set result to -1.0.
+3: ret
+END(__expm1l)
+libm_hidden_def (__expm1l)
+weak_alias (__expm1l, expm1l)
diff --git a/libc/sysdeps/i386/fpu/s_fabs.S b/libc/sysdeps/i386/fpu/s_fabs.S
new file mode 100644
index 000000000..23ae9dccb
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fabs.S
@@ -0,0 +1,9 @@
+#include <sysdep.h>
+
+ .text
+ENTRY(__fabs)
+ fldl 4(%esp)
+ fabs
+ ret
+END(__fabs)
+weak_alias (__fabs, fabs)
diff --git a/libc/sysdeps/i386/fpu/s_fabsf.S b/libc/sysdeps/i386/fpu/s_fabsf.S
new file mode 100644
index 000000000..c0407a883
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fabsf.S
@@ -0,0 +1,9 @@
+#include <sysdep.h>
+
+ .text
+ENTRY(__fabsf)
+ flds 4(%esp)
+ fabs
+ ret
+END(__fabsf)
+weak_alias (__fabsf, fabsf)
diff --git a/libc/sysdeps/i386/fpu/s_fabsl.S b/libc/sysdeps/i386/fpu/s_fabsl.S
new file mode 100644
index 000000000..a12a3e050
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fabsl.S
@@ -0,0 +1,9 @@
+#include <sysdep.h>
+
+ .text
+ENTRY(__fabsl)
+ fldt 4(%esp)
+ fabs
+ ret
+END(__fabsl)
+weak_alias (__fabsl, fabsl)
diff --git a/libc/sysdeps/i386/fpu/s_fdim.S b/libc/sysdeps/i386/fpu/s_fdim.S
new file mode 100644
index 000000000..92deb15d8
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fdim.S
@@ -0,0 +1,52 @@
+/* Compute positive difference.
+ Copyright (C) 1997, 1999, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fdim)
+ fldl 4(%esp) // x
+ fldl 12(%esp) // x : y
+
+ fucom %st(1)
+ fnstsw
+ sahf
+ jp 1f
+
+ jc 3f
+
+ fstp %st(1)
+ fldz
+ jmp 2f
+
+3: fsubrp %st, %st(1)
+ ret
+
+1: fxam
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x01, %ah
+ je 2f
+
+ fxch
+2: fstp %st(1)
+ ret
+END(__fdim)
+weak_alias (__fdim, fdim)
diff --git a/libc/sysdeps/i386/fpu/s_fdimf.S b/libc/sysdeps/i386/fpu/s_fdimf.S
new file mode 100644
index 000000000..905cec2fa
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fdimf.S
@@ -0,0 +1,52 @@
+/* Compute positive difference.
+ Copyright (C) 1997, 1999, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fdimf)
+ flds 4(%esp) // x
+ flds 8(%esp) // x : y
+
+ fucom %st(1)
+ fnstsw
+ sahf
+ jp 1f
+
+ jc 3f
+
+ fstp %st(1)
+ fldz
+ jmp 2f
+
+3: fsubrp %st, %st(1)
+ ret
+
+1: fxam
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x01, %ah
+ je 2f
+
+ fxch
+2: fstp %st(1)
+ ret
+END(__fdimf)
+weak_alias (__fdimf, fdimf)
diff --git a/libc/sysdeps/i386/fpu/s_fdiml.S b/libc/sysdeps/i386/fpu/s_fdiml.S
new file mode 100644
index 000000000..754b221de
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fdiml.S
@@ -0,0 +1,52 @@
+/* Compute positive difference.
+ Copyright (C) 1997, 1999, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fdiml)
+ fldt 4(%esp) // x
+ fldt 16(%esp) // x : y
+
+ fucom %st(1)
+ fnstsw
+ sahf
+ jp 1f
+
+ jc 3f
+
+ fstp %st(1)
+ fldz
+ jmp 2f
+
+3: fsubrp %st, %st(1)
+ ret
+
+1: fxam
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x01, %ah
+ je 2f
+
+ fxch
+2: fstp %st(1)
+ ret
+END(__fdiml)
+weak_alias (__fdiml, fdiml)
diff --git a/libc/sysdeps/i386/fpu/s_finite.S b/libc/sysdeps/i386/fpu/s_finite.S
new file mode 100644
index 000000000..1ae4aed45
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_finite.S
@@ -0,0 +1,17 @@
+/*
+ * Written by Joe Keane <jgk@jgk.org>.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__finite)
+ movl 8(%esp),%eax
+ movl $0xFFEFFFFF,%ecx
+ subl %eax,%ecx
+ xorl %ecx,%eax
+ shrl $31, %eax
+ ret
+END (__finite)
+weak_alias (__finite, finite)
+hidden_def (__finite)
+
diff --git a/libc/sysdeps/i386/fpu/s_finitef.S b/libc/sysdeps/i386/fpu/s_finitef.S
new file mode 100644
index 000000000..69e72facf
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_finitef.S
@@ -0,0 +1,16 @@
+/*
+ * Written by Joe Keane <jgk@jgk.org>.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__finitef)
+ movl 4(%esp),%eax
+ movl $0xFF7FFFFF,%ecx
+ subl %eax,%ecx
+ xorl %ecx,%eax
+ shrl $31,%eax
+ ret
+END (__finitef)
+weak_alias (__finitef, finitef)
+hidden_def (__finitef)
diff --git a/libc/sysdeps/i386/fpu/s_finitel.S b/libc/sysdeps/i386/fpu/s_finitel.S
new file mode 100644
index 000000000..cce90e18f
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_finitel.S
@@ -0,0 +1,15 @@
+/*
+ * Written by Joe Keane <jgk@jgk.org>.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__finitel)
+ movl 12(%esp),%eax
+ orl $0xffff8000, %eax
+ incl %eax
+ shrl $31, %eax
+ ret
+END (__finitel)
+weak_alias (__finitel, finitel)
+hidden_def (__finitel)
diff --git a/libc/sysdeps/i386/fpu/s_floor.S b/libc/sysdeps/i386/fpu/s_floor.S
new file mode 100644
index 000000000..20a866042
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_floor.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_floor.S,v 1.4 1995/05/09 00:01:59 jtc Exp $")
+
+ENTRY(__floor)
+ fldl 4(%esp)
+ subl $8,%esp
+
+ fstcw 4(%esp) /* store fpu control word */
+
+ /* We use here %edx although only the low 1 bits are defined.
+ But none of the operations should care and they are faster
+ than the 16 bit operations. */
+ movl $0x400,%edx /* round towards -oo */
+ orl 4(%esp),%edx
+ andl $0xf7ff,%edx
+ movl %edx,(%esp)
+ fldcw (%esp) /* load modified control word */
+
+ frndint /* round */
+
+ fldcw 4(%esp) /* restore original control word */
+
+ addl $8,%esp
+ ret
+END (__floor)
+weak_alias (__floor, floor)
diff --git a/libc/sysdeps/i386/fpu/s_floorf.S b/libc/sysdeps/i386/fpu/s_floorf.S
new file mode 100644
index 000000000..eca93a2aa
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_floorf.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_floorf.S,v 1.3 1995/05/09 00:04:32 jtc Exp $")
+
+ENTRY(__floorf)
+ flds 4(%esp)
+ subl $8,%esp
+
+ fstcw 4(%esp) /* store fpu control word */
+
+ /* We use here %edx although only the low 1 bits are defined.
+ But none of the operations should care and they are faster
+ than the 16 bit operations. */
+ movl $0x400,%edx /* round towards -oo */
+ orl 4(%esp),%edx
+ andl $0xf7ff,%edx
+ movl %edx,(%esp)
+ fldcw (%esp) /* load modified control word */
+
+ frndint /* round */
+
+ fldcw 4(%esp) /* restore original control word */
+
+ addl $8,%esp
+ ret
+END (__floorf)
+weak_alias (__floorf, floorf)
diff --git a/libc/sysdeps/i386/fpu/s_floorl.S b/libc/sysdeps/i386/fpu/s_floorl.S
new file mode 100644
index 000000000..c2bf091d7
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_floorl.S
@@ -0,0 +1,33 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__floorl)
+ fldt 4(%esp)
+ subl $8,%esp
+
+ fstcw 4(%esp) /* store fpu control word */
+
+ /* We use here %edx although only the low 1 bits are defined.
+ But none of the operations should care and they are faster
+ than the 16 bit operations. */
+ movl $0x400,%edx /* round towards -oo */
+ orl 4(%esp),%edx
+ andl $0xf7ff,%edx
+ movl %edx,(%esp)
+ fldcw (%esp) /* load modified control word */
+
+ frndint /* round */
+
+ fldcw 4(%esp) /* restore original control word */
+
+ addl $8,%esp
+ ret
+END (__floorl)
+weak_alias (__floorl, floorl)
diff --git a/libc/sysdeps/i386/fpu/s_fma.S b/libc/sysdeps/i386/fpu/s_fma.S
new file mode 100644
index 000000000..db4959ccf
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fma.S
@@ -0,0 +1,31 @@
+/* Compute (X * Y) + Z as ternary operation.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fma)
+ fldl 4(%esp) // x
+ fmull 12(%esp) // x * y
+ fldl 20(%esp) // z : x * y
+ faddp // (x * y) + z
+ ret
+END(__fma)
+weak_alias (__fma, fma)
diff --git a/libc/sysdeps/i386/fpu/s_fmaf.S b/libc/sysdeps/i386/fpu/s_fmaf.S
new file mode 100644
index 000000000..5f875532a
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fmaf.S
@@ -0,0 +1,31 @@
+/* Compute (X * Y) + Z as ternary operation.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmaf)
+ flds 4(%esp) // x
+ fmuls 8(%esp) // x * y
+ flds 12(%esp) // z : x * y
+ faddp // (x * y) + z
+ ret
+END(__fmaf)
+weak_alias (__fmaf, fmaf)
diff --git a/libc/sysdeps/i386/fpu/s_fmal.S b/libc/sysdeps/i386/fpu/s_fmal.S
new file mode 100644
index 000000000..1837f848c
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fmal.S
@@ -0,0 +1,32 @@
+/* Compute (X * Y) + Z as ternary operation.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmal)
+ fldt 4(%esp) // x
+ fldt 16(%esp) // x : y
+ fmulp // x * y
+ fldt 28(%esp) // z : x * y
+ faddp // (x * y) + z
+ ret
+END(__fmal)
+weak_alias (__fmal, fmal)
diff --git a/libc/sysdeps/i386/fpu/s_fmax.S b/libc/sysdeps/i386/fpu/s_fmax.S
new file mode 100644
index 000000000..fd8cfae53
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fmax.S
@@ -0,0 +1,44 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmax)
+ fldl 12(%esp) // y
+ fxam
+ fnstsw
+ fldl 4(%esp) // y : x
+
+ andb $0x45, %ah
+ cmpb $0x01, %ah
+ je 1f // y == NaN
+
+ fucom %st(1)
+ fnstsw
+ sahf
+ jnc 1f
+
+ fxch %st(1)
+1: fstp %st(1)
+
+ ret
+END(__fmax)
+weak_alias (__fmax, fmax)
diff --git a/libc/sysdeps/i386/fpu/s_fmaxf.S b/libc/sysdeps/i386/fpu/s_fmaxf.S
new file mode 100644
index 000000000..4e286f13a
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fmaxf.S
@@ -0,0 +1,44 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmaxf)
+ flds 8(%esp) // y
+ fxam
+ fnstsw
+ flds 4(%esp) // y : x
+
+ andb $0x45, %ah
+ cmpb $0x01, %ah
+ je 1f // y == NaN
+
+ fucom %st(1)
+ fnstsw
+ sahf
+ jnc 1f
+
+ fxch %st(1)
+1: fstp %st(1)
+
+ ret
+END(__fmaxf)
+weak_alias (__fmaxf, fmaxf)
diff --git a/libc/sysdeps/i386/fpu/s_fmaxl.S b/libc/sysdeps/i386/fpu/s_fmaxl.S
new file mode 100644
index 000000000..4e3105bbb
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fmaxl.S
@@ -0,0 +1,44 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmaxl)
+ fldt 16(%esp) // y
+ fxam
+ fnstsw
+ fldt 4(%esp) // y : x
+
+ andb $0x45, %ah
+ cmpb $0x01, %ah
+ je 1f // y == NaN
+
+ fucom %st(1)
+ fnstsw
+ sahf
+ jnc 1f
+
+ fxch %st(1)
+1: fstp %st(1)
+
+ ret
+END(__fmaxl)
+weak_alias (__fmaxl, fmaxl)
diff --git a/libc/sysdeps/i386/fpu/s_fmin.S b/libc/sysdeps/i386/fpu/s_fmin.S
new file mode 100644
index 000000000..b8e72106d
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fmin.S
@@ -0,0 +1,44 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmin)
+ fldl 4(%esp) // x
+ fldl 12(%esp) // x : y
+
+ fxam
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x01, %ah
+ je 1f // y == NaN
+
+ fucom %st(1)
+ fnstsw
+ sahf
+ jc 2f
+
+1: fxch %st(1)
+2: fstp %st(1)
+
+ ret
+END(__fmin)
+weak_alias (__fmin, fmin)
diff --git a/libc/sysdeps/i386/fpu/s_fminf.S b/libc/sysdeps/i386/fpu/s_fminf.S
new file mode 100644
index 000000000..a81f8c9e1
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fminf.S
@@ -0,0 +1,44 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fminf)
+ flds 4(%esp) // x
+ flds 8(%esp) // x : y
+
+ fxam
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x01, %ah
+ je 1f // y == NaN
+
+ fucom %st(1)
+ fnstsw
+ sahf
+ jc 2f
+
+1: fxch %st(1)
+2: fstp %st(1)
+
+ ret
+END(__fminf)
+weak_alias (__fminf, fminf)
diff --git a/libc/sysdeps/i386/fpu/s_fminl.S b/libc/sysdeps/i386/fpu/s_fminl.S
new file mode 100644
index 000000000..baf15f64c
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fminl.S
@@ -0,0 +1,44 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fminl)
+ fldt 4(%esp) // x
+ fldt 16(%esp) // x : y
+
+ fxam
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x01, %ah
+ je 1f // y == NaN
+
+ fucom %st(1)
+ fnstsw
+ sahf
+ jc 2f
+
+1: fxch %st(1)
+2: fstp %st(1)
+
+ ret
+END(__fminl)
+weak_alias (__fminl, fminl)
diff --git a/libc/sysdeps/i386/fpu/s_fpclassifyl.c b/libc/sysdeps/i386/fpu/s_fpclassifyl.c
new file mode 100644
index 000000000..679e721d3
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_fpclassifyl.c
@@ -0,0 +1,43 @@
+/* Return classification value corresponding to argument.
+ Copyright (C) 1997, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+int
+__fpclassifyl (long double x)
+{
+ u_int32_t ex, hx, lx;
+ int retval = FP_NORMAL;
+
+ GET_LDOUBLE_WORDS (ex, hx, lx, x);
+ ex &= 0x7fff;
+ if ((ex | lx | hx) == 0)
+ retval = FP_ZERO;
+ else if (ex == 0 && (hx & 0x80000000) == 0)
+ retval = FP_SUBNORMAL;
+ else if (ex == 0x7fff)
+ retval = ((hx & 0x7fffffff) | lx) != 0 ? FP_NAN : FP_INFINITE;
+
+ return retval;
+}
+libm_hidden_def (__fpclassifyl)
diff --git a/libc/sysdeps/i386/fpu/s_frexp.S b/libc/sysdeps/i386/fpu/s_frexp.S
new file mode 100644
index 000000000..cfc822106
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_frexp.S
@@ -0,0 +1,93 @@
+/* ix87 specific frexp implementation for double.
+ Copyright (C) 1997, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(two54,@object)
+two54: .byte 0, 0, 0, 0, 0, 0, 0x50, 0x43
+ ASM_SIZE_DIRECTIVE(two54)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define VAL0 PARMS
+#define VAL1 VAL0+4
+#define EXPP VAL1+4
+
+ .text
+ENTRY (BP_SYM (__frexp))
+ ENTER
+
+ movl VAL0(%esp), %ecx
+ movl VAL1(%esp), %eax
+ movl %eax, %edx
+ andl $0x7fffffff, %eax
+ orl %eax, %ecx
+ jz 1f
+ xorl %ecx, %ecx
+ cmpl $0x7ff00000, %eax
+ jae 1f
+
+ cmpl $0x00100000, %eax
+ jae 2f
+
+ fldl VAL0(%esp)
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ fmull MO(two54)
+ movl $-54, %ecx
+ fstpl VAL0(%esp)
+ fwait
+ movl VAL1(%esp), %eax
+ movl %eax, %edx
+ andl $0x7fffffff, %eax
+
+2: shrl $20, %eax
+ andl $0x800fffff, %edx
+ subl $1022, %eax
+ orl $0x3fe00000, %edx
+ addl %eax, %ecx
+ movl %edx, VAL1(%esp)
+
+ /* Store %ecx in the variable pointed to by the second argument,
+ get the factor from the stack and return. */
+1: movl EXPP(%esp), %eax
+ CHECK_BOUNDS_BOTH_WIDE (%eax, EXPP(%esp), $4)
+ fldl VAL0(%esp)
+ movl %ecx, (%eax)
+
+ LEAVE
+ ret
+END (BP_SYM (__frexp))
+weak_alias (BP_SYM (__frexp), BP_SYM (frexp))
diff --git a/libc/sysdeps/i386/fpu/s_frexpf.S b/libc/sysdeps/i386/fpu/s_frexpf.S
new file mode 100644
index 000000000..8640bbc22
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_frexpf.S
@@ -0,0 +1,90 @@
+/* ix87 specific frexp implementation for float.
+ Copyright (C) 1997, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(two25,@object)
+two25: .byte 0, 0, 0, 0x4c
+ ASM_SIZE_DIRECTIVE(two25)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define VAL PARMS
+#define EXPP VAL+4
+
+ .text
+ENTRY (BP_SYM (__frexpf))
+ ENTER
+
+ movl VAL(%esp), %eax
+ xorl %ecx, %ecx
+ movl %eax, %edx
+ andl $0x7fffffff, %eax
+ jz 1f
+ cmpl $0x7f800000, %eax
+ jae 1f
+
+ cmpl $0x00800000, %eax
+ jae 2f
+
+ flds VAL(%esp)
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+ fmuls MO(two25)
+ movl $-25, %ecx
+ fstps VAL(%esp)
+ fwait
+ movl VAL(%esp), %eax
+ movl %eax, %edx
+ andl $0x7fffffff, %eax
+
+2: shrl $23, %eax
+ andl $0x807fffff, %edx
+ subl $126, %eax
+ orl $0x3f000000, %edx
+ addl %eax, %ecx
+ movl %edx, VAL(%esp)
+
+ /* Store %ecx in the variable pointed to by the second argument,
+ get the factor from the stack and return. */
+1: movl EXPP(%esp), %eax
+ CHECK_BOUNDS_BOTH_WIDE (%eax, EXPP(%esp), $4)
+ flds VAL(%esp)
+ movl %ecx, (%eax)
+
+ LEAVE
+ ret
+END (BP_SYM (__frexpf))
+weak_alias (BP_SYM (__frexpf), BP_SYM (frexpf))
diff --git a/libc/sysdeps/i386/fpu/s_frexpl.S b/libc/sysdeps/i386/fpu/s_frexpl.S
new file mode 100644
index 000000000..60ae57ee3
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_frexpl.S
@@ -0,0 +1,95 @@
+/* ix87 specific frexp implementation for long double.
+ Copyright (C) 1997, 2000, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(two64,@object)
+two64: .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x43
+ ASM_SIZE_DIRECTIVE(two64)
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define VAL0 PARMS
+#define VAL1 VAL0+4
+#define VAL2 VAL1+4
+#define EXPP VAL2+4
+
+ .text
+ENTRY (BP_SYM (__frexpl))
+ ENTER
+
+ movl VAL0(%esp), %ecx
+ movl VAL2(%esp), %eax
+ orl VAL1(%esp), %ecx
+ movl %eax, %edx
+ andl $0x7fff, %eax
+ orl %eax, %ecx
+ jz 1f
+ xorl %ecx, %ecx
+ cmpl $0x7fff, %eax
+ je 1f
+
+ cmpl $0, %eax
+ jne 2f
+
+ fldt VAL0(%esp)
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+
+ fmull MO(two64) /* It's not necessary to use a 80bit factor */
+ movl $-64, %ecx
+ fstpt VAL0(%esp)
+ fwait
+ movl VAL2(%esp), %eax
+ movl %eax, %edx
+ andl $0x7fff, %eax
+
+2: andl $0x8000, %edx
+ subl $16382, %eax
+ orl $0x3ffe, %edx
+ addl %eax, %ecx
+ movl %edx, VAL2(%esp)
+
+ /* Store %ecx in the variable pointed to by the second argument,
+ get the factor from the stack and return. */
+1: movl EXPP(%esp), %eax
+ CHECK_BOUNDS_BOTH_WIDE (%eax, EXPP(%esp), $4)
+ fldt VAL0(%esp)
+ movl %ecx, (%eax)
+
+ LEAVE
+ ret
+END (BP_SYM (__frexpl))
+weak_alias (BP_SYM (__frexpl), BP_SYM (frexpl))
diff --git a/libc/sysdeps/i386/fpu/s_ilogb.S b/libc/sysdeps/i386/fpu/s_ilogb.S
new file mode 100644
index 000000000..0cf1ad741
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_ilogb.S
@@ -0,0 +1,38 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ilogb.S,v 1.5 1995/10/12 15:53:09 jtc Exp $")
+
+ENTRY(__ilogb)
+ fldl 4(%esp)
+/* I added the following ugly construct because ilogb(+-Inf) is
+ required to return INT_MAX in ISO C99.
+ -- jakub@redhat.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+
+ fxtract
+ pushl %eax
+ cfi_adjust_cfa_offset (4)
+ fstp %st
+
+ fistpl (%esp)
+ fwait
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+
+ ret
+
+1: fstp %st
+ movl $0x7fffffff, %eax
+ ret
+END (__ilogb)
+weak_alias (__ilogb, ilogb)
diff --git a/libc/sysdeps/i386/fpu/s_ilogbf.S b/libc/sysdeps/i386/fpu/s_ilogbf.S
new file mode 100644
index 000000000..99e53edd7
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_ilogbf.S
@@ -0,0 +1,38 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_ilogbf.S,v 1.4 1995/10/22 20:32:43 pk Exp $")
+
+ENTRY(__ilogbf)
+ flds 4(%esp)
+/* I added the following ugly construct because ilogb(+-Inf) is
+ required to return INT_MAX in ISO C99.
+ -- jakub@redhat.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+
+ fxtract
+ pushl %eax
+ cfi_adjust_cfa_offset (4)
+ fstp %st
+
+ fistpl (%esp)
+ fwait
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+
+ ret
+
+1: fstp %st
+ movl $0x7fffffff, %eax
+ ret
+END (__ilogbf)
+weak_alias (__ilogbf, ilogbf)
diff --git a/libc/sysdeps/i386/fpu/s_ilogbl.S b/libc/sysdeps/i386/fpu/s_ilogbl.S
new file mode 100644
index 000000000..1f559b311
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_ilogbl.S
@@ -0,0 +1,39 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ilogbl)
+ fldt 4(%esp)
+/* I added the following ugly construct because ilogb(+-Inf) is
+ required to return INT_MAX in ISO C99.
+ -- jakub@redhat.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+
+ fxtract
+ pushl %eax
+ cfi_adjust_cfa_offset (4)
+ fstp %st
+
+ fistpl (%esp)
+ fwait
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+
+ ret
+
+1: fstp %st
+ movl $0x7fffffff, %eax
+ ret
+END (__ilogbl)
+weak_alias (__ilogbl, ilogbl)
diff --git a/libc/sysdeps/i386/fpu/s_isinfl.c b/libc/sysdeps/i386/fpu/s_isinfl.c
new file mode 100644
index 000000000..72e4ae813
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_isinfl.c
@@ -0,0 +1,37 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Change for long double by Ulrich Drepper <drepper@cygnus.com>.
+ * Intel i387 specific version.
+ * Public domain.
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/*
+ * isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __isinfl(long double x)
+#else
+ int __isinfl(x)
+ long double x;
+#endif
+{
+ int32_t se,hx,lx;
+ GET_LDOUBLE_WORDS(se,hx,lx,x);
+ /* This additional ^ 0x80000000 is necessary because in Intel's
+ internal representation of the implicit one is explicit. */
+ lx |= (hx ^ 0x80000000) | ((se & 0x7fff) ^ 0x7fff);
+ lx |= -lx;
+ se &= 0x8000;
+ return ~(lx >> 31) & (1 - (se >> 14));
+}
+hidden_def (__isinfl)
+weak_alias (__isinfl, isinfl)
diff --git a/libc/sysdeps/i386/fpu/s_isnanl.c b/libc/sysdeps/i386/fpu/s_isnanl.c
new file mode 100644
index 000000000..aa459956e
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_isnanl.c
@@ -0,0 +1,48 @@
+/* s_isnanl.c -- long double version for i387 of s_isnan.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * isnanl(x) returns 1 is x is nan, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __isnanl(long double x)
+#else
+ int __isnanl(x)
+ long double x;
+#endif
+{
+ int32_t se,hx,lx;
+ GET_LDOUBLE_WORDS(se,hx,lx,x);
+ se = (se & 0x7fff) << 1;
+ /* The additional & 0x7fffffff is required because Intel's
+ extended format has the normally implicit 1 explicit
+ present. Sigh! */
+ lx |= hx & 0x7fffffff;
+ se |= (u_int32_t)(lx|(-lx))>>31;
+ se = 0xfffe - se;
+ return (int)((u_int32_t)(se))>>16;
+}
+hidden_def (__isnanl)
+weak_alias (__isnanl, isnanl)
diff --git a/libc/sysdeps/i386/fpu/s_llrint.S b/libc/sysdeps/i386/fpu/s_llrint.S
new file mode 100644
index 000000000..23bbec602
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_llrint.S
@@ -0,0 +1,37 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__llrint)
+ fldl 4(%esp)
+ subl $8, %esp
+ cfi_adjust_cfa_offset (8)
+ fistpll (%esp)
+ fwait
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ ret
+END(__llrint)
+weak_alias (__llrint, llrint)
diff --git a/libc/sysdeps/i386/fpu/s_llrintf.S b/libc/sysdeps/i386/fpu/s_llrintf.S
new file mode 100644
index 000000000..3de73f666
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_llrintf.S
@@ -0,0 +1,37 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__llrintf)
+ flds 4(%esp)
+ subl $8, %esp
+ cfi_adjust_cfa_offset (8)
+ fistpll (%esp)
+ fwait
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ ret
+END(__llrintf)
+weak_alias (__llrintf, llrintf)
diff --git a/libc/sysdeps/i386/fpu/s_llrintl.S b/libc/sysdeps/i386/fpu/s_llrintl.S
new file mode 100644
index 000000000..f6545e9fc
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_llrintl.S
@@ -0,0 +1,37 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__llrintl)
+ fldt 4(%esp)
+ subl $8, %esp
+ cfi_adjust_cfa_offset (8)
+ fistpll (%esp)
+ fwait
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+ ret
+END(__llrintl)
+weak_alias (__llrintl, llrintl)
diff --git a/libc/sysdeps/i386/fpu/s_log1p.S b/libc/sysdeps/i386/fpu/s_log1p.S
new file mode 100644
index 000000000..ec777fdf9
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_log1p.S
@@ -0,0 +1,69 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_log1p.S,v 1.7 1995/05/09 00:10:58 jtc Exp $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ /* The fyl2xp1 can only be used for values in
+ -1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
+ 0.29 is a safe value.
+ */
+limit: .double 0.29
+one: .double 1.0
+
+/*
+ * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
+ * otherwise fyl2x with the needed extra computation.
+ */
+ .text
+ENTRY(__log1p)
+ fldln2
+
+ fldl 4(%esp)
+
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+
+ fxam
+ fnstsw
+ fld %st
+ sahf
+ jc 3f // in case x is NaN or ±Inf
+4: fabs
+#ifdef PIC
+ fcompl limit@GOTOFF(%edx)
+#else
+ fcompl limit
+#endif
+ fnstsw
+ sahf
+ jc 2f
+
+#ifdef PIC
+ faddl one@GOTOFF(%edx)
+#else
+ faddl one
+#endif
+ fyl2x
+ ret
+
+2: fyl2xp1
+ ret
+
+3: jp 4b // in case x is ±Inf
+ fstp %st(1)
+ fstp %st(1)
+ ret
+
+END (__log1p)
+weak_alias (__log1p, log1p)
diff --git a/libc/sysdeps/i386/fpu/s_log1pf.S b/libc/sysdeps/i386/fpu/s_log1pf.S
new file mode 100644
index 000000000..6919ac902
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_log1pf.S
@@ -0,0 +1,69 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_log1pf.S,v 1.4 1995/05/09 00:13:05 jtc Exp $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ /* The fyl2xp1 can only be used for values in
+ -1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
+ 0.29 is a safe value.
+ */
+limit: .float 0.29
+one: .float 1.0
+
+/*
+ * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
+ * otherwise fyl2x with the needed extra computation.
+ */
+ .text
+ENTRY(__log1pf)
+ fldln2
+
+ flds 4(%esp)
+
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+
+ fxam
+ fnstsw
+ fld %st
+ sahf
+ jc 3f // in case x is NaN or ±Inf
+4: fabs
+#ifdef PIC
+ fcomps limit@GOTOFF(%edx)
+#else
+ fcomps limit
+#endif
+ fnstsw
+ sahf
+ jc 2f
+
+#ifdef PIC
+ fadds one@GOTOFF(%edx)
+#else
+ fadds one
+#endif
+ fyl2x
+ ret
+
+2: fyl2xp1
+ ret
+
+3: jp 4b // in case x is ±Inf
+ fstp %st(1)
+ fstp %st(1)
+ ret
+
+END (__log1pf)
+weak_alias (__log1pf, log1pf)
diff --git a/libc/sysdeps/i386/fpu/s_log1pl.S b/libc/sysdeps/i386/fpu/s_log1pl.S
new file mode 100644
index 000000000..4bca67d6b
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_log1pl.S
@@ -0,0 +1,76 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_log1p.S,v 1.7 1995/05/09 00:10:58 jtc Exp $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ /* The fyl2xp1 can only be used for values in
+ -1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
+ 0.29 is a safe value.
+ */
+limit: .tfloat 0.29
+ /* Please note: we use a double value here. Since 1.0 has
+ an exact representation this does not effect the accuracy
+ but it helps to optimize the code. */
+one: .double 1.0
+
+/*
+ * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
+ * otherwise fyl2x with the needed extra computation.
+ */
+ .text
+ENTRY(__log1pl)
+ fldln2
+
+ fldt 4(%esp)
+
+#ifdef PIC
+ LOAD_PIC_REG (dx)
+#endif
+
+ fxam
+ fnstsw
+ fld %st
+ sahf
+ jc 3f // in case x is NaN or ±Inf
+4:
+ fabs
+#ifdef PIC
+ fldt limit@GOTOFF(%edx)
+#else
+ fldt limit
+#endif
+ fcompp
+ fnstsw
+ sahf
+ jnc 2f
+
+#ifdef PIC
+ faddl one@GOTOFF(%edx)
+#else
+ faddl one
+#endif
+ fyl2x
+ ret
+
+2: fyl2xp1
+ ret
+
+3: jp 4b // in case x is ±Inf
+ fstp %st(1)
+ fstp %st(1)
+ ret
+
+END (__log1pl)
+weak_alias (__log1pl, log1pl)
diff --git a/libc/sysdeps/i386/fpu/s_logb.S b/libc/sysdeps/i386/fpu/s_logb.S
new file mode 100644
index 000000000..f78c091c8
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_logb.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_logb.S,v 1.4 1995/05/09 00:14:30 jtc Exp $")
+
+ENTRY(__logb)
+ fldl 4(%esp)
+ fxtract
+ fstp %st
+ ret
+END (__logb)
+weak_alias (__logb, logb)
diff --git a/libc/sysdeps/i386/fpu/s_logbf.S b/libc/sysdeps/i386/fpu/s_logbf.S
new file mode 100644
index 000000000..91eb3d292
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_logbf.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_logbf.S,v 1.3 1995/05/09 00:15:12 jtc Exp $")
+
+ENTRY(__logbf)
+ flds 4(%esp)
+ fxtract
+ fstp %st
+ ret
+END (__logbf)
+weak_alias (__logbf, logbf)
diff --git a/libc/sysdeps/i386/fpu/s_logbl.c b/libc/sysdeps/i386/fpu/s_logbl.c
new file mode 100644
index 000000000..391e2db48
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_logbl.c
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <math_private.h>
+
+long double
+__logbl (long double x)
+{
+ long double res;
+
+ asm ("fxtract\n"
+ "fstp %%st" : "=t" (res) : "0" (x));
+ return res;
+}
+
+weak_alias (__logbl, logbl)
diff --git a/libc/sysdeps/i386/fpu/s_lrint.S b/libc/sysdeps/i386/fpu/s_lrint.S
new file mode 100644
index 000000000..799875b33
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_lrint.S
@@ -0,0 +1,35 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__lrint)
+ fldl 4(%esp)
+ subl $4, %esp
+ cfi_adjust_cfa_offset (4)
+ fistpl (%esp)
+ fwait
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ ret
+END(__lrint)
+weak_alias (__lrint, lrint)
diff --git a/libc/sysdeps/i386/fpu/s_lrintf.S b/libc/sysdeps/i386/fpu/s_lrintf.S
new file mode 100644
index 000000000..2aa1a4e83
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_lrintf.S
@@ -0,0 +1,35 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__lrintf)
+ flds 4(%esp)
+ subl $4, %esp
+ cfi_adjust_cfa_offset (4)
+ fistpl (%esp)
+ fwait
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ ret
+END(__lrintf)
+weak_alias (__lrintf, lrintf)
diff --git a/libc/sysdeps/i386/fpu/s_lrintl.S b/libc/sysdeps/i386/fpu/s_lrintl.S
new file mode 100644
index 000000000..c0211c11d
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_lrintl.S
@@ -0,0 +1,35 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__lrintl)
+ fldt 4(%esp)
+ subl $4, %esp
+ cfi_adjust_cfa_offset (4)
+ fistpl (%esp)
+ fwait
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ ret
+END(__lrintl)
+weak_alias (__lrintl, lrintl)
diff --git a/libc/sysdeps/i386/fpu/s_nearbyint.S b/libc/sysdeps/i386/fpu/s_nearbyint.S
new file mode 100644
index 000000000..52909139a
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_nearbyint.S
@@ -0,0 +1,29 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+/* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>. */
+
+#include <machine/asm.h>
+
+ENTRY(__nearbyint)
+ fldl 4(%esp)
+ pushl %eax
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ fnstcw (%esp)
+ movl (%esp), %eax
+ orl $0x20, %eax
+ movl %eax, 4(%esp)
+ fldcw 4(%esp)
+ frndint
+ fclex
+ fldcw (%esp)
+ popl %ecx
+ cfi_adjust_cfa_offset (-4)
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ ret
+END (__nearbyint)
+weak_alias (__nearbyint, nearbyint)
diff --git a/libc/sysdeps/i386/fpu/s_nearbyintf.S b/libc/sysdeps/i386/fpu/s_nearbyintf.S
new file mode 100644
index 000000000..6a6b1d6c2
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_nearbyintf.S
@@ -0,0 +1,29 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+/* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>. */
+
+#include <machine/asm.h>
+
+ENTRY(__nearbyintf)
+ flds 4(%esp)
+ pushl %eax
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ fnstcw (%esp)
+ movl (%esp), %eax
+ orl $0x20, %eax
+ movl %eax, 4(%esp)
+ fldcw 4(%esp)
+ frndint
+ fclex
+ fldcw (%esp)
+ popl %ecx
+ cfi_adjust_cfa_offset (-4)
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ ret
+END (__nearbyintf)
+weak_alias (__nearbyintf, nearbyintf)
diff --git a/libc/sysdeps/i386/fpu/s_nearbyintl.S b/libc/sysdeps/i386/fpu/s_nearbyintl.S
new file mode 100644
index 000000000..819af63a8
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_nearbyintl.S
@@ -0,0 +1,29 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+/* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>. */
+
+#include <machine/asm.h>
+
+ENTRY(__nearbyintl)
+ fldt 4(%esp)
+ pushl %eax
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ fnstcw (%esp)
+ movl (%esp), %eax
+ orl $0x20, %eax
+ movl %eax, 4(%esp)
+ fldcw 4(%esp)
+ frndint
+ fclex
+ fldcw (%esp)
+ popl %ecx
+ cfi_adjust_cfa_offset (-4)
+ popl %eax
+ cfi_adjust_cfa_offset (-4)
+ ret
+END (__nearbyintl)
+weak_alias (__nearbyintl, nearbyintl)
diff --git a/libc/sysdeps/i386/fpu/s_nextafterl.c b/libc/sysdeps/i386/fpu/s_nextafterl.c
new file mode 100644
index 000000000..5b617cb4e
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_nextafterl.c
@@ -0,0 +1,124 @@
+/* s_nextafterl.c -- long double version of s_nextafter.c.
+ * Special version for i387.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* IEEE functions
+ * nextafterl(x,y)
+ * return the next machine floating-point number of x in the
+ * direction toward y.
+ * Special cases:
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __nextafterl(long double x, long double y)
+#else
+ long double __nextafterl(x,y)
+ long double x,y;
+#endif
+{
+ u_int32_t hx,hy,ix,iy;
+ u_int32_t lx,ly;
+ int32_t esx,esy;
+
+ GET_LDOUBLE_WORDS(esx,hx,lx,x);
+ GET_LDOUBLE_WORDS(esy,hy,ly,y);
+ ix = esx&0x7fff; /* |x| */
+ iy = esy&0x7fff; /* |y| */
+
+ /* Intel's extended format has the normally implicit 1 explicit
+ present. Sigh! */
+ if(((ix==0x7fff)&&(((hx&0x7fffffff)|lx)!=0)) || /* x is nan */
+ ((iy==0x7fff)&&(((hy&0x7fffffff)|ly)!=0))) /* y is nan */
+ return x+y;
+ if(x==y) return y; /* x=y, return y */
+ if((ix|hx|lx)==0) { /* x == 0 */
+ SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */
+ y = x*x;
+ if(y==x) return y; else return x; /* raise underflow flag */
+ }
+ if(esx>=0) { /* x > 0 */
+ if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
+ /* x > y, x -= ulp */
+ if(lx==0) {
+ if (hx <= 0x80000000) {
+ if (esx == 0) {
+ --hx;
+ } else {
+ esx -= 1;
+ hx = hx - 1;
+ if (esx > 0)
+ hx |= 0x80000000;
+ }
+ } else
+ hx -= 1;
+ }
+ lx -= 1;
+ } else { /* x < y, x += ulp */
+ lx += 1;
+ if(lx==0) {
+ hx += 1;
+ if (hx==0 || (esx == 0 && hx == 0x80000000)) {
+ esx += 1;
+ hx |= 0x80000000;
+ }
+ }
+ }
+ } else { /* x < 0 */
+ if(esy>=0||(esx>esy||((esx==esy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){
+ /* x < y, x -= ulp */
+ if(lx==0) {
+ if (hx <= 0x80000000) {
+ esx -= 1;
+ hx = hx - 1;
+ if ((esx&0x7fff) > 0)
+ hx |= 0x80000000;
+ } else
+ hx -= 1;
+ }
+ lx -= 1;
+ } else { /* x > y, x += ulp */
+ lx += 1;
+ if(lx==0) {
+ hx += 1;
+ if (hx==0 || (esx == 0xffff8000 && hx == 0x80000000)) {
+ esx += 1;
+ hx |= 0x80000000;
+ }
+ }
+ }
+ }
+ esy = esx&0x7fff;
+ if(esy==0x7fff) return x+x; /* overflow */
+ if(esy==0) { /* underflow */
+ y = x*x;
+ if(y!=x) { /* raise underflow flag */
+ SET_LDOUBLE_WORDS(y,esx,hx,lx);
+ return y;
+ }
+ }
+ SET_LDOUBLE_WORDS(x,esx,hx,lx);
+ return x;
+}
+weak_alias (__nextafterl, nextafterl)
+strong_alias (__nextafterl, __nexttowardl)
+weak_alias (__nextafterl, nexttowardl)
diff --git a/libc/sysdeps/i386/fpu/s_nexttoward.c b/libc/sysdeps/i386/fpu/s_nexttoward.c
new file mode 100644
index 000000000..2bd768e44
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_nexttoward.c
@@ -0,0 +1,106 @@
+/* s_nexttoward.c
+ * Special i387 version
+ * Conversion from s_nextafter.c by Ulrich Drepper, Cygnus Support,
+ * drepper@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: $";
+#endif
+
+/* IEEE functions
+ * nexttoward(x,y)
+ * return the next machine floating-point number of x in the
+ * direction toward y.
+ * Special cases:
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __nexttoward(double x, long double y)
+#else
+ double __nexttoward(x,y)
+ double x;
+ long double y;
+#endif
+{
+ int32_t hx,ix,iy;
+ u_int32_t lx,hy,ly,esy;
+
+ EXTRACT_WORDS(hx,lx,x);
+ GET_LDOUBLE_WORDS(esy,hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = esy&0x7fff; /* |y| */
+
+ /* Intel's extended format has the normally implicit 1 explicit
+ present. Sigh! */
+ if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */
+ ((iy>=0x7fff)&&((hy&0x7fffffff)|ly)!=0)) /* y is nan */
+ return x+y;
+ if((long double) x==y) return y; /* x=y, return y */
+ if((ix|lx)==0) { /* x == 0 */
+ double x2;
+ INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */
+ x2 = x*x;
+ if(x2==x) return x2; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00
+ || (((ix>>20)&0x7ff)==iy-0x3c00
+ && (((hx<<11)|(lx>>21))>(hy&0x7fffffff)
+ || (((hx<<11)|(lx>>21))==(hy&0x7fffffff)
+ && (lx<<11)>ly)))) { /* x > y, x -= ulp */
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { /* x < y, x += ulp */
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ } else { /* x < 0 */
+ if (esy<0x8000||((ix>>20)&0x7ff)>iy-0x3c00
+ || (((ix>>20)&0x7ff)==iy-0x3c00
+ && (((hx<<11)|(lx>>21))>(hy&0x7fffffff)
+ || (((hx<<11)|(lx>>21))==(hy&0x7fffffff)
+ && (lx<<11)>ly)))) {/* x < y, x -= ulp */
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { /* x > y, x += ulp */
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ }
+ hy = hx&0x7ff00000;
+ if(hy>=0x7ff00000) {
+ x = x+x; /* overflow */
+ /* Force conversion to double. */
+ asm ("" : "=m"(x) : "m"(x));
+ return x;
+ }
+ if(hy<0x00100000) { /* underflow */
+ double x2 = x*x;
+ if(x2!=x) { /* raise underflow flag */
+ INSERT_WORDS(x2,hx,lx);
+ return x2;
+ }
+ }
+ INSERT_WORDS(x,hx,lx);
+ return x;
+}
+weak_alias (__nexttoward, nexttoward)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__nexttoward, __nexttowardl)
+weak_alias (__nexttoward, nexttowardl)
+#endif
diff --git a/libc/sysdeps/i386/fpu/s_nexttowardf.c b/libc/sysdeps/i386/fpu/s_nexttowardf.c
new file mode 100644
index 000000000..3fbe53c33
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_nexttowardf.c
@@ -0,0 +1,86 @@
+/* s_nexttowardf.c -- float version of s_nextafter.c.
+ * Special i387 version.
+ * 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: $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float __nexttowardf(float x, long double y)
+#else
+ float __nexttowardf(x,y)
+ float x;
+ long double y;
+#endif
+{
+ int32_t hx,ix,iy;
+ u_int32_t hy,ly,esy;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_LDOUBLE_WORDS(esy,hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = esy&0x7fff; /* |y| */
+
+ /* Intel's extended format has the normally implicit 1 explicit
+ present. Sigh! */
+ if((ix>0x7f800000) || /* x is nan */
+ (iy>=0x7fff&&(((hy&0x7fffffff)|ly)!=0))) /* y is nan */
+ return x+y;
+ if((long double) x==y) return y; /* x=y, return y */
+ if(ix==0) { /* x == 0 */
+ float x2;
+ SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/
+ x2 = x*x;
+ if(x2==x) return x2; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80
+ || (((ix>>23)&0xff)==iy-0x3f80
+ && ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x > y, x -= ulp */
+ hx -= 1;
+ } else { /* x < y, x += ulp */
+ hx += 1;
+ }
+ } else { /* x < 0 */
+ if(esy<0x8000||((ix>>23)&0xff)>iy-0x3f80
+ || (((ix>>23)&0xff)==iy-0x3f80
+ && ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x < y, x -= ulp */
+ hx -= 1;
+ } else { /* x > y, x += ulp */
+ hx += 1;
+ }
+ }
+ hy = hx&0x7f800000;
+ if(hy>=0x7f800000) {
+ x = x+x; /* overflow */
+ /* Force conversion to float. */
+ asm ("" : "=m"(x) : "m"(x));
+ return x;
+ }
+ if(hy<0x00800000) { /* underflow */
+ float x2 = x*x;
+ if(x2!=x) { /* raise underflow flag */
+ SET_FLOAT_WORD(x2,hx);
+ return x2;
+ }
+ }
+ SET_FLOAT_WORD(x,hx);
+ return x;
+}
+weak_alias (__nexttowardf, nexttowardf)
diff --git a/libc/sysdeps/i386/fpu/s_remquo.S b/libc/sysdeps/i386/fpu/s_remquo.S
new file mode 100644
index 000000000..505659321
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_remquo.S
@@ -0,0 +1,50 @@
+/*
+ * Written by Ulrich Drepper <drepper@cygnus.com>.
+ * Based on e_remainder by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define DVDND PARMS
+#define DVSOR DVDND+8
+#define QUOP DVSOR+8
+
+ .text
+ENTRY (BP_SYM (__remquo))
+ ENTER
+
+ fldl DVSOR(%esp)
+ fldl DVDND(%esp)
+1: fprem1
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ /* Compute the congruent of the quotient. */
+ movl %eax, %ecx
+ shrl $8, %eax
+ shrl $12, %ecx
+ andl $4, %ecx
+ andl $3, %eax
+ orl %eax, %ecx
+ leal (%ecx,%ecx,2),%ecx
+ movl $0xef2a60, %eax
+ shrl %cl, %eax
+ andl $7, %eax
+ movl QUOP(%esp), %ecx
+ CHECK_BOUNDS_BOTH_WIDE (%ecx, QUOP(%esp), $4)
+ movl DVDND+4(%esp), %edx
+ xorl DVSOR+4(%esp), %edx
+ testl $0x80000000, %edx
+ jz 1f
+ negl %eax
+1: movl %eax, (%ecx)
+
+ LEAVE
+ ret
+END (BP_SYM (__remquo))
+weak_alias (BP_SYM (__remquo), BP_SYM (remquo))
diff --git a/libc/sysdeps/i386/fpu/s_remquof.S b/libc/sysdeps/i386/fpu/s_remquof.S
new file mode 100644
index 000000000..d3c5965be
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_remquof.S
@@ -0,0 +1,50 @@
+/*
+ * Written by Ulrich Drepper <drepper@cygnus.com>.
+ * Based on e_remainder by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define DVDND PARMS
+#define DVSOR DVDND+4
+#define QUOP DVSOR+4
+
+ .text
+ENTRY (BP_SYM (__remquof))
+ ENTER
+
+ flds DVSOR(%esp)
+ flds DVDND(%esp)
+1: fprem1
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ /* Compute the congruent of the quotient. */
+ movl %eax, %ecx
+ shrl $8, %eax
+ shrl $12, %ecx
+ andl $4, %ecx
+ andl $3, %eax
+ orl %eax, %ecx
+ leal (%ecx,%ecx,2),%ecx
+ movl $0xef2a60, %eax
+ shrl %cl, %eax
+ andl $7, %eax
+ movl QUOP(%esp), %ecx
+ CHECK_BOUNDS_BOTH_WIDE (%ecx, QUOP(%esp), $4)
+ movl DVDND(%esp), %edx
+ xorl DVSOR(%esp), %edx
+ testl $0x80000000, %edx
+ jz 1f
+ negl %eax
+1: movl %eax, (%ecx)
+
+ LEAVE
+ ret
+END (BP_SYM (__remquof))
+weak_alias (BP_SYM (__remquof), BP_SYM (remquof))
diff --git a/libc/sysdeps/i386/fpu/s_remquol.S b/libc/sysdeps/i386/fpu/s_remquol.S
new file mode 100644
index 000000000..65240adbe
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_remquol.S
@@ -0,0 +1,50 @@
+/*
+ * Written by Ulrich Drepper <drepper@cygnus.com>.
+ * Based on e_remainder by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define DVDND PARMS
+#define DVSOR DVDND+12
+#define QUOP DVSOR+12
+
+ .text
+ENTRY (BP_SYM (__remquol))
+ ENTER
+
+ fldt DVSOR(%esp)
+ fldt DVDND(%esp)
+1: fprem1
+ fstsw %ax
+ sahf
+ jp 1b
+ fstp %st(1)
+ /* Compute the congruent of the quotient. */
+ movl %eax, %ecx
+ shrl $8, %eax
+ shrl $12, %ecx
+ andl $4, %ecx
+ andl $3, %eax
+ orl %eax, %ecx
+ leal (%ecx,%ecx,2),%ecx
+ movl $0xef2a60, %eax
+ shrl %cl, %eax
+ andl $7, %eax
+ movl QUOP(%esp), %ecx
+ CHECK_BOUNDS_BOTH_WIDE (%ecx, QUOP(%esp), $4)
+ movl DVDND+8(%esp), %edx
+ xorl DVSOR+8(%esp), %edx
+ testl $0x8000, %edx
+ jz 1f
+ negl %eax
+1: movl %eax, (%ecx)
+
+ LEAVE
+ ret
+END (BP_SYM (__remquol))
+weak_alias (BP_SYM (__remquol), BP_SYM (remquol))
diff --git a/libc/sysdeps/i386/fpu/s_rint.S b/libc/sysdeps/i386/fpu/s_rint.S
new file mode 100644
index 000000000..be36c5f0c
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_rint.S
@@ -0,0 +1,15 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_rint.S,v 1.4 1995/05/09 00:16:08 jtc Exp $")
+
+ENTRY(__rint)
+ fldl 4(%esp)
+ frndint
+ ret
+END (__rint)
+weak_alias (__rint, rint)
diff --git a/libc/sysdeps/i386/fpu/s_rintf.S b/libc/sysdeps/i386/fpu/s_rintf.S
new file mode 100644
index 000000000..2b358c1cf
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_rintf.S
@@ -0,0 +1,15 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_rintf.S,v 1.3 1995/05/09 00:17:22 jtc Exp $")
+
+ENTRY(__rintf)
+ flds 4(%esp)
+ frndint
+ ret
+END (__rintf)
+weak_alias (__rintf, rintf)
diff --git a/libc/sysdeps/i386/fpu/s_rintl.c b/libc/sysdeps/i386/fpu/s_rintl.c
new file mode 100644
index 000000000..66af9cb67
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_rintl.c
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <math_private.h>
+
+long double
+__rintl (long double x)
+{
+ long double res;
+
+ asm ("frndint" : "=t" (res) : "0" (x));
+ return res;
+}
+
+weak_alias (__rintl, rintl)
diff --git a/libc/sysdeps/i386/fpu/s_scalbln.c b/libc/sysdeps/i386/fpu/s_scalbln.c
new file mode 100644
index 000000000..1009713fb
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_scalbln.c
@@ -0,0 +1,2 @@
+/* Nothing to do. This function is the same as scalbn. So we define an
+ alias. */
diff --git a/libc/sysdeps/i386/fpu/s_scalblnf.c b/libc/sysdeps/i386/fpu/s_scalblnf.c
new file mode 100644
index 000000000..5e558c354
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_scalblnf.c
@@ -0,0 +1,2 @@
+/* Nothing to do. This function is the same as scalbnf. So we define an
+ alias. */
diff --git a/libc/sysdeps/i386/fpu/s_scalblnl.c b/libc/sysdeps/i386/fpu/s_scalblnl.c
new file mode 100644
index 000000000..cda2ec11c
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_scalblnl.c
@@ -0,0 +1,2 @@
+/* Nothing to do. This function is the same as scalbnl. So we define an
+ alias. */
diff --git a/libc/sysdeps/i386/fpu/s_scalbn.S b/libc/sysdeps/i386/fpu/s_scalbn.S
new file mode 100644
index 000000000..ea9e25f09
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_scalbn.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_scalbn.S,v 1.4 1995/05/09 00:19:06 jtc Exp $")
+
+ENTRY(__scalbn)
+ fildl 12(%esp)
+ fldl 4(%esp)
+ fscale
+ fstp %st(1)
+ ret
+END (__scalbn)
+weak_alias (__scalbn, scalbn)
+strong_alias (__scalbn, __scalbln)
+weak_alias (__scalbn, scalbln)
diff --git a/libc/sysdeps/i386/fpu/s_scalbnf.S b/libc/sysdeps/i386/fpu/s_scalbnf.S
new file mode 100644
index 000000000..dc8cfb429
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_scalbnf.S
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_scalbnf.S,v 1.3 1995/05/09 00:19:59 jtc Exp $")
+
+ENTRY(__scalbnf)
+ fildl 8(%esp)
+ flds 4(%esp)
+ fscale
+ fstp %st(1)
+ ret
+END (__scalbnf)
+weak_alias (__scalbnf, scalbnf)
+strong_alias (__scalbnf, __scalblnf)
+weak_alias (__scalbnf, scalblnf)
diff --git a/libc/sysdeps/i386/fpu/s_scalbnl.S b/libc/sysdeps/i386/fpu/s_scalbnl.S
new file mode 100644
index 000000000..295494b3d
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_scalbnl.S
@@ -0,0 +1,20 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__scalbnl)
+ fildl 16(%esp)
+ fldt 4(%esp)
+ fscale
+ fstp %st(1)
+ ret
+END (__scalbnl)
+weak_alias (__scalbnl, scalbnl)
+strong_alias (__scalbnl, __scalblnl)
+weak_alias (__scalbnl, scalblnl)
diff --git a/libc/sysdeps/i386/fpu/s_significand.S b/libc/sysdeps/i386/fpu/s_significand.S
new file mode 100644
index 000000000..4859b7ed7
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_significand.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_significand.S,v 1.4 1995/05/09 00:21:47 jtc Exp $")
+
+ENTRY(__significand)
+ fldl 4(%esp)
+ fxtract
+ fstp %st(1)
+ ret
+END (__significand)
+weak_alias (__significand, significand)
diff --git a/libc/sysdeps/i386/fpu/s_significandf.S b/libc/sysdeps/i386/fpu/s_significandf.S
new file mode 100644
index 000000000..3a2de9775
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_significandf.S
@@ -0,0 +1,16 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_significandf.S,v 1.3 1995/05/09 00:24:07 jtc Exp $")
+
+ENTRY(__significandf)
+ flds 4(%esp)
+ fxtract
+ fstp %st(1)
+ ret
+END (__significandf)
+weak_alias (__significandf, significandf)
diff --git a/libc/sysdeps/i386/fpu/s_significandl.c b/libc/sysdeps/i386/fpu/s_significandl.c
new file mode 100644
index 000000000..b8cb09350
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_significandl.c
@@ -0,0 +1,19 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Public domain.
+ */
+
+#include <math_private.h>
+
+long double
+__significandl (long double x)
+{
+ long double res;
+
+ asm ("fxtract\n"
+ "fstp %%st(1)" : "=t" (res) : "0" (x));
+ return res;
+}
+
+weak_alias (__significandl, significandl)
diff --git a/libc/sysdeps/i386/fpu/s_sin.S b/libc/sysdeps/i386/fpu/s_sin.S
new file mode 100644
index 000000000..eb22d7e98
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_sin.S
@@ -0,0 +1,29 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_sin.S,v 1.5 1995/05/09 00:25:54 jtc Exp $")
+
+ENTRY(__sin)
+ fldl 4(%esp)
+ fsin
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ ret
+ .align ALIGNARG(4)
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fsin
+ ret
+END (__sin)
+weak_alias (__sin, sin)
diff --git a/libc/sysdeps/i386/fpu/s_sincos.S b/libc/sysdeps/i386/fpu/s_sincos.S
new file mode 100644
index 000000000..087a24cdb
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_sincos.S
@@ -0,0 +1,65 @@
+/* Compute sine and cosine of argument.
+ Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define ANGLE PARMS
+#define SINP ANGLE+8
+#define COSP SINP+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__sincos))
+ ENTER
+
+ fldl ANGLE(%esp)
+ fsincos
+ movl SINP(%esp), %ecx
+ CHECK_BOUNDS_BOTH_WIDE (%ecx, SINP(%esp), $8)
+ movl COSP(%esp), %edx
+ CHECK_BOUNDS_BOTH_WIDE (%edx, COSP(%esp), $8)
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ fstpl (%edx)
+ fstpl (%ecx)
+
+ LEAVE
+ ret
+
+ .align ALIGNARG(4)
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fsincos
+ fstpl (%edx)
+ fstpl (%ecx)
+
+ LEAVE
+ ret
+END (BP_SYM (__sincos))
+weak_alias (BP_SYM (__sincos), BP_SYM (sincos))
diff --git a/libc/sysdeps/i386/fpu/s_sincosf.S b/libc/sysdeps/i386/fpu/s_sincosf.S
new file mode 100644
index 000000000..b8120dc50
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_sincosf.S
@@ -0,0 +1,65 @@
+/* Compute sine and cosine of argument.
+ Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define ANGLE PARMS
+#define SINP ANGLE+4
+#define COSP SINP+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__sincosf))
+ ENTER
+
+ flds ANGLE(%esp)
+ fsincos
+ movl SINP(%esp), %ecx
+ CHECK_BOUNDS_BOTH_WIDE (%ecx, SINP(%esp), $4)
+ movl COSP(%esp), %edx
+ CHECK_BOUNDS_BOTH_WIDE (%edx, COSP(%esp), $4)
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ fstps (%edx)
+ fstps (%ecx)
+
+ LEAVE
+ ret
+
+ .align ALIGNARG(4)
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fsincos
+ fstps (%edx)
+ fstps (%ecx)
+
+ LEAVE
+ ret
+END (BP_SYM (__sincosf))
+weak_alias (BP_SYM (__sincosf), BP_SYM (sincosf))
diff --git a/libc/sysdeps/i386/fpu/s_sincosl.S b/libc/sysdeps/i386/fpu/s_sincosl.S
new file mode 100644
index 000000000..f9b58c2f3
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_sincosl.S
@@ -0,0 +1,65 @@
+/* Compute sine and cosine of argument.
+ Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define ANGLE PARMS
+#define SINP ANGLE+12
+#define COSP SINP+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__sincosl))
+ ENTER
+
+ fldt ANGLE(%esp)
+ fsincos
+ movl SINP(%esp), %ecx
+ CHECK_BOUNDS_BOTH_WIDE (%ecx, SINP(%esp), $12)
+ movl COSP(%esp), %edx
+ CHECK_BOUNDS_BOTH_WIDE (%edx, COSP(%esp), $12)
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ fstpt (%edx)
+ fstpt (%ecx)
+
+ LEAVE
+ ret
+
+ .align ALIGNARG(4)
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fsincos
+ fstpt (%edx)
+ fstpt (%ecx)
+
+ LEAVE
+ ret
+END (BP_SYM (__sincosl))
+weak_alias (BP_SYM (__sincosl), BP_SYM (sincosl))
diff --git a/libc/sysdeps/i386/fpu/s_sinf.S b/libc/sysdeps/i386/fpu/s_sinf.S
new file mode 100644
index 000000000..5ca45f52e
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_sinf.S
@@ -0,0 +1,29 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_sinf.S,v 1.3 1995/05/09 00:27:53 jtc Exp $")
+
+ENTRY(__sinf)
+ flds 4(%esp)
+ fsin
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ ret
+ .align ALIGNARG(4)
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fsin
+ ret
+END (__sinf)
+weak_alias (__sinf, sinf)
diff --git a/libc/sysdeps/i386/fpu/s_sinl.S b/libc/sysdeps/i386/fpu/s_sinl.S
new file mode 100644
index 000000000..3e215de5e
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_sinl.S
@@ -0,0 +1,31 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__sinl)
+ fldt 4(%esp)
+ fsin
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ ret
+ .align ALIGNARG(4)
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fsin
+ ret
+END (__sinl)
+weak_alias (__sinl, sinl)
diff --git a/libc/sysdeps/i386/fpu/s_tan.S b/libc/sysdeps/i386/fpu/s_tan.S
new file mode 100644
index 000000000..7b3547af4
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_tan.S
@@ -0,0 +1,30 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_tan.S,v 1.5 1995/05/09 00:30:00 jtc Exp $")
+
+ENTRY(__tan)
+ fldl 4(%esp)
+ fptan
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ fstp %st(0)
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fptan
+ fstp %st(0)
+ ret
+END (__tan)
+weak_alias (__tan, tan)
diff --git a/libc/sysdeps/i386/fpu/s_tanf.S b/libc/sysdeps/i386/fpu/s_tanf.S
new file mode 100644
index 000000000..355dff9c8
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_tanf.S
@@ -0,0 +1,30 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_tanf.S,v 1.3 1995/05/09 00:31:09 jtc Exp $")
+
+ENTRY(__tanf)
+ flds 4(%esp)
+ fptan
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ fstp %st(0)
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fptan
+ fstp %st(0)
+ ret
+END (__tanf)
+weak_alias (__tanf, tanf)
diff --git a/libc/sysdeps/i386/fpu/s_tanl.S b/libc/sysdeps/i386/fpu/s_tanl.S
new file mode 100644
index 000000000..f2bdd6a60
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_tanl.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__tanl)
+ fldt 4(%esp)
+ fptan
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ fstp %st(0)
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fptan
+ fstp %st(0)
+ ret
+END (__tanl)
+weak_alias (__tanl, tanl)
diff --git a/libc/sysdeps/i386/fpu/s_trunc.S b/libc/sysdeps/i386/fpu/s_trunc.S
new file mode 100644
index 000000000..5e6c3b4a9
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_trunc.S
@@ -0,0 +1,36 @@
+/* Truncate double value.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+ENTRY(__trunc)
+ fldl 4(%esp)
+ subl $8, %esp
+ fstcw 4(%esp)
+ movl $0xc00, %edx
+ orl 4(%esp), %edx
+ movl %edx, (%esp)
+ fldcw (%esp)
+ frndint
+ fldcw 4(%esp)
+ addl $8, %esp
+ ret
+END(__trunc)
+weak_alias (__trunc, trunc)
diff --git a/libc/sysdeps/i386/fpu/s_truncf.S b/libc/sysdeps/i386/fpu/s_truncf.S
new file mode 100644
index 000000000..bbe282368
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_truncf.S
@@ -0,0 +1,36 @@
+/* Truncate float value.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+ENTRY(__truncf)
+ flds 4(%esp)
+ subl $8, %esp
+ fstcw 4(%esp)
+ movl $0xc00, %edx
+ orl 4(%esp), %edx
+ movl %edx, (%esp)
+ fldcw (%esp)
+ frndint
+ fldcw 4(%esp)
+ addl $8, %esp
+ ret
+END(__truncf)
+weak_alias (__truncf, truncf)
diff --git a/libc/sysdeps/i386/fpu/s_truncl.S b/libc/sysdeps/i386/fpu/s_truncl.S
new file mode 100644
index 000000000..4ff1f6f41
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/s_truncl.S
@@ -0,0 +1,36 @@
+/* Truncate long double value.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+ENTRY(__truncl)
+ fldt 4(%esp)
+ subl $8, %esp
+ fstcw 4(%esp)
+ movl $0xc00, %edx
+ orl 4(%esp), %edx
+ movl %edx, (%esp)
+ fldcw (%esp)
+ frndint
+ fldcw 4(%esp)
+ addl $8, %esp
+ ret
+END(__truncl)
+weak_alias (__truncl, truncl)
diff --git a/libc/sysdeps/i386/fpu/sincos32.c b/libc/sysdeps/i386/fpu/sincos32.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/sincos32.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/slowexp.c b/libc/sysdeps/i386/fpu/slowexp.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/slowexp.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/slowpow.c b/libc/sysdeps/i386/fpu/slowpow.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/slowpow.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/i386/fpu/t_exp.c b/libc/sysdeps/i386/fpu/t_exp.c
new file mode 100644
index 000000000..fd37963b0
--- /dev/null
+++ b/libc/sysdeps/i386/fpu/t_exp.c
@@ -0,0 +1 @@
+/* Empty. Not needed. */
diff --git a/libc/sysdeps/i386/fpu_control.h b/libc/sysdeps/i386/fpu_control.h
new file mode 100644
index 000000000..0a9b57c30
--- /dev/null
+++ b/libc/sysdeps/i386/fpu_control.h
@@ -0,0 +1,102 @@
+/* FPU control word bits. i387 version.
+ Copyright (C) 1993,1995-1998,2000,2001,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Olaf Flebbe.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H 1
+
+/* Here is the dirty part. Set up your 387 through the control word
+ * (cw) register.
+ *
+ * 15-13 12 11-10 9-8 7-6 5 4 3 2 1 0
+ * | reserved | IC | RC | PC | reserved | PM | UM | OM | ZM | DM | IM
+ *
+ * IM: Invalid operation mask
+ * DM: Denormalized operand mask
+ * ZM: Zero-divide mask
+ * OM: Overflow mask
+ * UM: Underflow mask
+ * PM: Precision (inexact result) mask
+ *
+ * Mask bit is 1 means no interrupt.
+ *
+ * PC: Precision control
+ * 11 - round to extended precision
+ * 10 - round to double precision
+ * 00 - round to single precision
+ *
+ * RC: Rounding control
+ * 00 - rounding to nearest
+ * 01 - rounding down (toward - infinity)
+ * 10 - rounding up (toward + infinity)
+ * 11 - rounding toward zero
+ *
+ * IC: Infinity control
+ * That is for 8087 and 80287 only.
+ *
+ * The hardware default is 0x037f which we use.
+ */
+
+#include <features.h>
+
+/* masking of interrupts */
+#define _FPU_MASK_IM 0x01
+#define _FPU_MASK_DM 0x02
+#define _FPU_MASK_ZM 0x04
+#define _FPU_MASK_OM 0x08
+#define _FPU_MASK_UM 0x10
+#define _FPU_MASK_PM 0x20
+
+/* precision control */
+#define _FPU_EXTENDED 0x300 /* libm requires double extended precision. */
+#define _FPU_DOUBLE 0x200
+#define _FPU_SINGLE 0x0
+
+/* rounding control */
+#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
+#define _FPU_RC_DOWN 0x400
+#define _FPU_RC_UP 0x800
+#define _FPU_RC_ZERO 0xC00
+
+#define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */
+
+
+/* The fdlibm code requires strict IEEE double precision arithmetic,
+ and no interrupts for exceptions, rounding to nearest. */
+
+#define _FPU_DEFAULT 0x037f
+
+/* IEEE: same as above. */
+#define _FPU_IEEE 0x037f
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
+
+/* Macros for accessing the hardware control word.
+
+ Note that the use of these macros is no sufficient anymore with
+ recent hardware. Some floating point operations are executed in
+ the SSE/SSE2 engines which have their own control and status register. */
+#define _FPU_GETCW(cw) __asm__ __volatile__ ("fnstcw %0" : "=m" (*&cw))
+#define _FPU_SETCW(cw) __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw))
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* fpu_control.h */
diff --git a/libc/sysdeps/i386/gccframe.h b/libc/sysdeps/i386/gccframe.h
new file mode 100644
index 000000000..412fa974d
--- /dev/null
+++ b/libc/sysdeps/i386/gccframe.h
@@ -0,0 +1,28 @@
+/* Definition of object in frame unwind info. i386 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define DWARF_FRAME_REGISTERS 17
+
+#define CRT_GET_RFIB_DATA(BASE) \
+ { \
+ register void *__ebx __asm__("ebx");\
+ BASE = __ebx; \
+ }
+
+#include <sysdeps/generic/gccframe.h>
diff --git a/libc/sysdeps/i386/gmp-mparam.h b/libc/sysdeps/i386/gmp-mparam.h
new file mode 100644
index 000000000..1ebfa19c5
--- /dev/null
+++ b/libc/sysdeps/i386/gmp-mparam.h
@@ -0,0 +1,29 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at your
+option) any later version.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#define BITS_PER_MP_LIMB 32
+#define BYTES_PER_MP_LIMB 4
+#define BITS_PER_LONGINT 32
+#define BITS_PER_INT 32
+#define BITS_PER_SHORTINT 16
+#define BITS_PER_CHAR 8
+
+#define IEEE_DOUBLE_BIG_ENDIAN 0
diff --git a/libc/sysdeps/i386/htonl.S b/libc/sysdeps/i386/htonl.S
new file mode 100644
index 000000000..0ee4f9883
--- /dev/null
+++ b/libc/sysdeps/i386/htonl.S
@@ -0,0 +1,37 @@
+/* Change byte order in word. For Intel 80386.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+/*
+ INPUT PARAMETERS:
+ word (sp + 4)
+*/
+
+ .text
+ENTRY (htonl)
+ movl 4(%esp), %eax
+ rorw $8, %ax
+ rorl $16, %eax
+ rorw $8, %ax
+ ret
+END (htonl)
+
+weak_alias (htonl, ntohl)
diff --git a/libc/sysdeps/i386/htons.S b/libc/sysdeps/i386/htons.S
new file mode 100644
index 000000000..81c895198
--- /dev/null
+++ b/libc/sysdeps/i386/htons.S
@@ -0,0 +1,36 @@
+/* Change byte order in word. For Intel 80x86, x >= 3.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+/*
+ INPUT PARAMETERS:
+ word (sp + 4)
+*/
+
+ .text
+ENTRY (htons)
+ movl 4(%esp), %eax
+ andl $0xffff, %eax
+ rorw $8, %ax
+ ret
+END (htons)
+
+weak_alias (htons, ntohs)
diff --git a/libc/sysdeps/i386/i386-mcount.S b/libc/sysdeps/i386/i386-mcount.S
new file mode 100644
index 000000000..8b11adb2e
--- /dev/null
+++ b/libc/sysdeps/i386/i386-mcount.S
@@ -0,0 +1,55 @@
+/* i386-specific implemetation of profiling support.
+ Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* We need a special version of the `mcount' function since for ix86 it
+ must not clobber any register. This has several reasons:
+ - there is a bug in gcc as of version 2.7.2.2 which prohibits the
+ use of profiling together with nested functions
+ - the ELF `fixup' function uses GCC's regparm feature
+ - some (future) systems might want to pass parameters in registers. */
+
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(_mcount)
+ ASM_TYPE_DIRECTIVE(C_SYMBOL_NAME(_mcount), @function)
+ .align ALIGNARG(4)
+C_LABEL(_mcount)
+ /* Save the caller-clobbered registers. */
+ pushl %eax
+ pushl %ecx
+ pushl %edx
+
+ movl 12(%esp), %edx
+ movl 4(%ebp), %eax
+
+ /* No need to access the PLT or GOT, __mcount_internal is an
+ internal function and we can make a relative call. */
+ call C_SYMBOL_NAME(__mcount_internal)
+
+ /* Pop the saved registers. Please note that `mcount' has no
+ return value. */
+ popl %edx
+ popl %ecx
+ popl %eax
+ ret
+ ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(_mcount))
+
+#undef mcount
+weak_alias (_mcount, mcount)
diff --git a/libc/sysdeps/i386/i486/Versions b/libc/sysdeps/i386/i486/Versions
new file mode 100644
index 000000000..b33fa127a
--- /dev/null
+++ b/libc/sysdeps/i386/i486/Versions
@@ -0,0 +1,13 @@
+libc {
+ GLIBC_2.1.1 {
+ # extern inline functions used by <bits/string.h>
+ __memcpy_by2; __memcpy_by4; __memcpy_g; __mempcpy_by2; __mempcpy_by4;
+ __mempcpy_byn; __memset_ccn_by2; __memset_ccn_by4; __memset_gcn_by2;
+ __memset_gcn_by4; __stpcpy_g; __strcat_c; __strcat_g; __strchr_c;
+ __strchr_g; __strchrnul_c; __strchrnul_g; __strcmp_gg; __strcpy_g;
+ __strcspn_c1; __strcspn_cg; __strcspn_g; __strlen_g; __strncat_g;
+ __strncmp_g; __strncpy_by2; __strncpy_by4; __strncpy_byn; __strncpy_gg;
+ __strpbrk_cg; __strpbrk_g; __strrchr_c; __strrchr_g; __strspn_c1;
+ __strspn_cg; __strspn_g; __strstr_cg; __strstr_g;
+ }
+}
diff --git a/libc/sysdeps/i386/i486/bits/atomic.h b/libc/sysdeps/i386/i486/bits/atomic.h
new file mode 100644
index 000000000..c74876175
--- /dev/null
+++ b/libc/sysdeps/i386/i486/bits/atomic.h
@@ -0,0 +1,366 @@
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+
+#ifndef LOCK_PREFIX
+# ifdef UP
+# define LOCK_PREFIX /* nothing */
+# else
+# define LOCK_PREFIX "lock;"
+# endif
+#endif
+
+
+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile (LOCK_PREFIX "cmpxchgb %b2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "q" (newval), "m" (*mem), "0" (oldval)); \
+ ret; })
+
+#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile (LOCK_PREFIX "cmpxchgw %w2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "r" (newval), "m" (*mem), "0" (oldval)); \
+ ret; })
+
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile (LOCK_PREFIX "cmpxchgl %2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "r" (newval), "m" (*mem), "0" (oldval)); \
+ ret; })
+
+/* XXX We do not really need 64-bit compare-and-exchange. At least
+ not in the moment. Using it would mean causing portability
+ problems since not many other 32-bit architectures have support for
+ such an operation. So don't define any code for now. If it is
+ really going to be used the code below can be used on Intel Pentium
+ and later, but NOT on i486. */
+#if 1
+# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret = *(mem); abort (); ret = (newval); ret = (oldval); })
+#else
+# ifdef __PIC__
+# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile ("xchgl %2, %%ebx\n\t" \
+ LOCK_PREFIX "cmpxchg8b %1\n\t" \
+ "xchgl %2, %%ebx" \
+ : "=A" (ret), "=m" (*mem) \
+ : "DS" (((unsigned long long int) (newval)) \
+ & 0xffffffff), \
+ "c" (((unsigned long long int) (newval)) >> 32), \
+ "m" (*mem), "a" (((unsigned long long int) (oldval)) \
+ & 0xffffffff), \
+ "d" (((unsigned long long int) (oldval)) >> 32)); \
+ ret; })
+# else
+# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile (LOCK_PREFIX "cmpxchg8b %1" \
+ : "=A" (ret), "=m" (*mem) \
+ : "b" (((unsigned long long int) (newval)) \
+ & 0xffffffff), \
+ "c" (((unsigned long long int) (newval)) >> 32), \
+ "m" (*mem), "a" (((unsigned long long int) (oldval)) \
+ & 0xffffffff), \
+ "d" (((unsigned long long int) (oldval)) >> 32)); \
+ ret; })
+# endif
+#endif
+
+
+/* Note that we need no lock prefix. */
+#define atomic_exchange_acq(mem, newvalue) \
+ ({ __typeof (*mem) result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile ("xchgb %b0, %1" \
+ : "=r" (result), "=m" (*mem) \
+ : "0" (newvalue), "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile ("xchgw %w0, %1" \
+ : "=r" (result), "=m" (*mem) \
+ : "0" (newvalue), "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile ("xchgl %0, %1" \
+ : "=r" (result), "=m" (*mem) \
+ : "0" (newvalue), "m" (*mem)); \
+ else \
+ { \
+ result = 0; \
+ abort (); \
+ } \
+ result; })
+
+
+#define atomic_exchange_and_add(mem, value) \
+ ({ __typeof (*mem) __result; \
+ __typeof (value) __addval = (value); \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "xaddb %b0, %1" \
+ : "=r" (__result), "=m" (*mem) \
+ : "0" (__addval), "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "xaddw %w0, %1" \
+ : "=r" (__result), "=m" (*mem) \
+ : "0" (__addval), "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "xaddl %0, %1" \
+ : "=r" (__result), "=m" (*mem) \
+ : "0" (__addval), "m" (*mem)); \
+ else \
+ { \
+ __typeof (mem) __memp = (mem); \
+ __typeof (*mem) __tmpval; \
+ __result = *__memp; \
+ do \
+ __tmpval = __result; \
+ while ((__result = __arch_compare_and_exchange_val_64_acq \
+ (__memp, __result + __addval, __result)) == __tmpval); \
+ } \
+ __result; })
+
+
+#define atomic_add(mem, value) \
+ (void) ({ if (__builtin_constant_p (value) && (value) == 1) \
+ atomic_increment (mem); \
+ else if (__builtin_constant_p (value) && (value) == -1) \
+ atomic_decrement (mem); \
+ else if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "addb %b1, %0" \
+ : "=m" (*mem) \
+ : "ir" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "addw %w1, %0" \
+ : "=m" (*mem) \
+ : "ir" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "addl %1, %0" \
+ : "=m" (*mem) \
+ : "ir" (value), "m" (*mem)); \
+ else \
+ { \
+ __typeof (value) __addval = (value); \
+ __typeof (mem) __memp = (mem); \
+ __typeof (*mem) __oldval = *__memp; \
+ __typeof (*mem) __tmpval; \
+ do \
+ __tmpval = __oldval; \
+ while ((__oldval = __arch_compare_and_exchange_val_64_acq \
+ (__memp, __oldval + __addval, __oldval)) == __tmpval); \
+ } \
+ })
+
+
+#define atomic_add_negative(mem, value) \
+ ({ unsigned char __result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "addb %b2, %0; sets %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "iq" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "addw %w2, %0; sets %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "addl %2, %0; sets %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" (value), "m" (*mem)); \
+ else \
+ abort (); \
+ __result; })
+
+
+#define atomic_add_zero(mem, value) \
+ ({ unsigned char __result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "addb %b2, %0; setz %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "addw %w2, %0; setz %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "addl %2, %0; setz %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" (value), "m" (*mem)); \
+ else \
+ abort (); \
+ __result; })
+
+
+#define atomic_increment(mem) \
+ (void) ({ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "incb %b0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "incw %w0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "incl %0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ else \
+ { \
+ __typeof (mem) __memp = (mem); \
+ __typeof (*mem) __oldval = *__memp; \
+ __typeof (*mem) __tmpval; \
+ do \
+ __tmpval = __oldval; \
+ while ((__oldval = __arch_compare_and_exchange_val_64_acq \
+ (__memp, __oldval + 1, __oldval)) == __tmpval); \
+ } \
+ })
+
+
+#define atomic_increment_and_test(mem) \
+ ({ unsigned char __result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "incb %0; sete %b1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "incw %0; sete %w1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "incl %0; sete %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ else \
+ abort (); \
+ __result; })
+
+
+#define atomic_decrement(mem) \
+ (void) ({ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "decb %b0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "decw %w0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "decl %0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ else \
+ { \
+ __typeof (mem) __memp = (mem); \
+ __typeof (*mem) __oldval = *__memp; \
+ __typeof (*mem) __tmpval; \
+ do \
+ __tmpval = __oldval; \
+ while ((__oldval = __arch_compare_and_exchange_val_64_acq \
+ (__memp, __oldval - 1, __oldval)) == __tmpval); \
+ } \
+ })
+
+
+#define atomic_decrement_and_test(mem) \
+ ({ unsigned char __result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "decb %b0; sete %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "decw %w0; sete %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "decl %0; sete %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ else \
+ abort (); \
+ __result; })
+
+
+#define atomic_bit_set(mem, bit) \
+ (void) ({ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "orb %b2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "ir" (1 << (bit))); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "orw %w2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "ir" (1 << (bit))); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "orl %2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "ir" (1 << (bit))); \
+ else \
+ abort (); \
+ })
+
+
+#define atomic_bit_test_set(mem, bit) \
+ ({ unsigned char __result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "btsb %3, %1; setc %0" \
+ : "=q" (__result), "=m" (*mem) \
+ : "m" (*mem), "ir" (bit)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "btsw %3, %1; setc %0" \
+ : "=q" (__result), "=m" (*mem) \
+ : "m" (*mem), "ir" (bit)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "btsl %3, %1; setc %0" \
+ : "=q" (__result), "=m" (*mem) \
+ : "m" (*mem), "ir" (bit)); \
+ else \
+ abort (); \
+ __result; })
+
+
+#define atomic_delay() asm ("rep; nop")
diff --git a/libc/sysdeps/i386/i486/bits/string.h b/libc/sysdeps/i386/i486/bits/string.h
new file mode 100644
index 000000000..203907b14
--- /dev/null
+++ b/libc/sysdeps/i386/i486/bits/string.h
@@ -0,0 +1,1970 @@
+/* Optimized, inlined string functions. i486 version.
+ Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _STRING_H
+# error "Never use <bits/string.h> directly; include <string.h> instead."
+#endif
+
+/* The ix86 processors can access unaligned multi-byte variables. */
+#define _STRING_ARCH_unaligned 1
+
+
+/* We only provide optimizations if the user selects them and if
+ GNU CC is used. */
+#if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
+ && defined __GNUC__ && __GNUC__ >= 2 && !__BOUNDED_POINTERS__
+
+#ifndef __STRING_INLINE
+# ifdef __cplusplus
+# define __STRING_INLINE inline
+# else
+# define __STRING_INLINE extern __inline
+# endif
+#endif
+
+/* The macros are used in some of the optimized implementations below. */
+#define __STRING_SMALL_GET16(src, idx) \
+ ((((__const unsigned char *) (src))[idx + 1] << 8) \
+ | ((__const unsigned char *) (src))[idx])
+#define __STRING_SMALL_GET32(src, idx) \
+ (((((__const unsigned char *) (src))[idx + 3] << 8 \
+ | ((__const unsigned char *) (src))[idx + 2]) << 8 \
+ | ((__const unsigned char *) (src))[idx + 1]) << 8 \
+ | ((__const unsigned char *) (src))[idx])
+
+
+/* Copy N bytes of SRC to DEST. */
+#define _HAVE_STRING_ARCH_memcpy 1
+#define memcpy(dest, src, n) \
+ (__extension__ (__builtin_constant_p (n) \
+ ? __memcpy_c ((dest), (src), (n)) \
+ : __memcpy_g ((dest), (src), (n))))
+#define __memcpy_c(dest, src, n) \
+ ((n) == 0 \
+ ? (dest) \
+ : (((n) % 4 == 0) \
+ ? __memcpy_by4 (dest, src, n) \
+ : (((n) % 2 == 0) \
+ ? __memcpy_by2 (dest, src, n) \
+ : __memcpy_g (dest, src, n))))
+
+__STRING_INLINE void *__memcpy_by4 (void *__dest, __const void *__src,
+ size_t __n);
+
+__STRING_INLINE void *
+__memcpy_by4 (void *__dest, __const void *__src, size_t __n)
+{
+ register unsigned long int __d0, __d1;
+ register void *__tmp = __dest;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movl (%2),%0\n\t"
+ "leal 4(%2),%2\n\t"
+ "movl %0,(%1)\n\t"
+ "leal 4(%1),%1\n\t"
+ "decl %3\n\t"
+ "jnz 1b"
+ : "=&r" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
+ : "1" (__tmp), "2" (__src), "3" (__n / 4)
+ : "memory", "cc");
+ return __dest;
+}
+
+__STRING_INLINE void *__memcpy_by2 (void *__dest, __const void *__src,
+ size_t __n);
+
+__STRING_INLINE void *
+__memcpy_by2 (void *__dest, __const void *__src, size_t __n)
+{
+ register unsigned long int __d0, __d1;
+ register void *__tmp = __dest;
+ __asm__ __volatile__
+ ("shrl $1,%3\n\t"
+ "jz 2f\n" /* only a word */
+ "1:\n\t"
+ "movl (%2),%0\n\t"
+ "leal 4(%2),%2\n\t"
+ "movl %0,(%1)\n\t"
+ "leal 4(%1),%1\n\t"
+ "decl %3\n\t"
+ "jnz 1b\n"
+ "2:\n\t"
+ "movw (%2),%w0\n\t"
+ "movw %w0,(%1)"
+ : "=&q" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
+ : "1" (__tmp), "2" (__src), "3" (__n / 2)
+ : "memory", "cc");
+ return __dest;
+}
+
+__STRING_INLINE void *__memcpy_g (void *__dest, __const void *__src,
+ size_t __n);
+
+__STRING_INLINE void *
+__memcpy_g (void *__dest, __const void *__src, size_t __n)
+{
+ register unsigned long int __d0, __d1, __d2;
+ register void *__tmp = __dest;
+ __asm__ __volatile__
+ ("cld\n\t"
+ "shrl $1,%%ecx\n\t"
+ "jnc 1f\n\t"
+ "movsb\n"
+ "1:\n\t"
+ "shrl $1,%%ecx\n\t"
+ "jnc 2f\n\t"
+ "movsw\n"
+ "2:\n\t"
+ "rep; movsl"
+ : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2),
+ "=m" ( *(struct { __extension__ char __x[__n]; } *)__dest)
+ : "0" (__n), "1" (__tmp), "2" (__src),
+ "m" ( *(struct { __extension__ char __x[__n]; } *)__src)
+ : "cc");
+ return __dest;
+}
+
+#define _HAVE_STRING_ARCH_memmove 1
+#ifndef _FORCE_INLINES
+/* Copy N bytes of SRC to DEST, guaranteeing
+ correct behavior for overlapping strings. */
+__STRING_INLINE void *
+memmove (void *__dest, __const void *__src, size_t __n)
+{
+ register unsigned long int __d0, __d1, __d2;
+ register void *__tmp = __dest;
+ if (__dest < __src)
+ __asm__ __volatile__
+ ("cld\n\t"
+ "rep; movsb"
+ : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2),
+ "=m" ( *(struct { __extension__ char __x[__n]; } *)__dest)
+ : "0" (__n), "1" (__src), "2" (__tmp),
+ "m" ( *(struct { __extension__ char __x[__n]; } *)__src));
+ else
+ __asm__ __volatile__
+ ("std\n\t"
+ "rep; movsb\n\t"
+ "cld"
+ : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2),
+ "=m" ( *(struct { __extension__ char __x[__n]; } *)__dest)
+ : "0" (__n), "1" (__n - 1 + (__const char *) __src),
+ "2" (__n - 1 + (char *) __tmp),
+ "m" ( *(struct { __extension__ char __x[__n]; } *)__src));
+ return __dest;
+}
+#endif
+
+/* Compare N bytes of S1 and S2. */
+#define _HAVE_STRING_ARCH_memcmp 1
+#ifndef _FORCE_INLINES
+# ifndef __PIC__
+/* gcc has problems to spill registers when using PIC. */
+__STRING_INLINE int
+memcmp (__const void *__s1, __const void *__s2, size_t __n)
+{
+ register unsigned long int __d0, __d1, __d2;
+ register int __res;
+ __asm__ __volatile__
+ ("cld\n\t"
+ "testl %3,%3\n\t"
+ "repe; cmpsb\n\t"
+ "je 1f\n\t"
+ "sbbl %0,%0\n\t"
+ "orl $1,%0\n"
+ "1:"
+ : "=&a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
+ : "0" (0), "1" (__s1), "2" (__s2), "3" (__n),
+ "m" ( *(struct { __extension__ char __x[__n]; } *)__s1),
+ "m" ( *(struct { __extension__ char __x[__n]; } *)__s2)
+ : "cc");
+ return __res;
+}
+# endif
+#endif
+
+/* Set N bytes of S to C. */
+#define _HAVE_STRING_ARCH_memset 1
+#define _USE_STRING_ARCH_memset 1
+#define memset(s, c, n) \
+ (__extension__ (__builtin_constant_p (n) && (n) <= 16 \
+ ? ((n) == 1 \
+ ? __memset_c1 ((s), (c)) \
+ : __memset_gc ((s), (c), (n))) \
+ : (__builtin_constant_p (c) \
+ ? (__builtin_constant_p (n) \
+ ? __memset_ccn ((s), (c), (n)) \
+ : memset ((s), (c), (n))) \
+ : (__builtin_constant_p (n) \
+ ? __memset_gcn ((s), (c), (n)) \
+ : memset ((s), (c), (n))))))
+
+#define __memset_c1(s, c) ({ void *__s = (s); \
+ *((unsigned char *) __s) = (unsigned char) (c); \
+ __s; })
+
+#define __memset_gc(s, c, n) \
+ ({ void *__s = (s); \
+ union { \
+ unsigned int __ui; \
+ unsigned short int __usi; \
+ unsigned char __uc; \
+ } *__u = __s; \
+ unsigned int __c = ((unsigned int) ((unsigned char) (c))) * 0x01010101; \
+ \
+ /* We apply a trick here. `gcc' would implement the following \
+ assignments using immediate operands. But this uses to much \
+ memory (7, instead of 4 bytes). So we force the value in a \
+ registers. */ \
+ if ((n) == 3 || (n) >= 5) \
+ __asm__ __volatile__ ("" : "=r" (__c) : "0" (__c)); \
+ \
+ /* This `switch' statement will be removed at compile-time. */ \
+ switch (n) \
+ { \
+ case 15: \
+ __u->__ui = __c; \
+ __u = __extension__ ((void *) __u + 4); \
+ case 11: \
+ __u->__ui = __c; \
+ __u = __extension__ ((void *) __u + 4); \
+ case 7: \
+ __u->__ui = __c; \
+ __u = __extension__ ((void *) __u + 4); \
+ case 3: \
+ __u->__usi = (unsigned short int) __c; \
+ __u = __extension__ ((void *) __u + 2); \
+ __u->__uc = (unsigned char) __c; \
+ break; \
+ \
+ case 14: \
+ __u->__ui = __c; \
+ __u = __extension__ ((void *) __u + 4); \
+ case 10: \
+ __u->__ui = __c; \
+ __u = __extension__ ((void *) __u + 4); \
+ case 6: \
+ __u->__ui = __c; \
+ __u = __extension__ ((void *) __u + 4); \
+ case 2: \
+ __u->__usi = (unsigned short int) __c; \
+ break; \
+ \
+ case 13: \
+ __u->__ui = __c; \
+ __u = __extension__ ((void *) __u + 4); \
+ case 9: \
+ __u->__ui = __c; \
+ __u = __extension__ ((void *) __u + 4); \
+ case 5: \
+ __u->__ui = __c; \
+ __u = __extension__ ((void *) __u + 4); \
+ case 1: \
+ __u->__uc = (unsigned char) __c; \
+ break; \
+ \
+ case 16: \
+ __u->__ui = __c; \
+ __u = __extension__ ((void *) __u + 4); \
+ case 12: \
+ __u->__ui = __c; \
+ __u = __extension__ ((void *) __u + 4); \
+ case 8: \
+ __u->__ui = __c; \
+ __u = __extension__ ((void *) __u + 4); \
+ case 4: \
+ __u->__ui = __c; \
+ case 0: \
+ break; \
+ } \
+ \
+ __s; })
+
+#define __memset_ccn(s, c, n) \
+ (((n) % 4 == 0) \
+ ? __memset_ccn_by4 (s, ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
+ n) \
+ : (((n) % 2 == 0) \
+ ? __memset_ccn_by2 (s, \
+ ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
+ n) \
+ : memset (s, c, n)))
+
+__STRING_INLINE void *__memset_ccn_by4 (void *__s, unsigned int __c,
+ size_t __n);
+
+__STRING_INLINE void *
+__memset_ccn_by4 (void *__s, unsigned int __c, size_t __n)
+{
+ register void *__tmp = __s;
+ register unsigned long int __d0;
+#ifdef __i686__
+ __asm__ __volatile__
+ ("cld\n\t"
+ "rep; stosl"
+ : "=&a" (__c), "=&D" (__tmp), "=&c" (__d0),
+ "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
+ : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
+ : "cc");
+#else
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movl %0,(%1)\n\t"
+ "addl $4,%1\n\t"
+ "decl %2\n\t"
+ "jnz 1b\n"
+ : "=&r" (__c), "=&r" (__tmp), "=&r" (__d0),
+ "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
+ : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
+ : "cc");
+#endif
+ return __s;
+}
+
+__STRING_INLINE void *__memset_ccn_by2 (void *__s, unsigned int __c,
+ size_t __n);
+
+__STRING_INLINE void *
+__memset_ccn_by2 (void *__s, unsigned int __c, size_t __n)
+{
+ register unsigned long int __d0, __d1;
+ register void *__tmp = __s;
+#ifdef __i686__
+ __asm__ __volatile__
+ ("cld\n\t"
+ "rep; stosl\n"
+ "stosw"
+ : "=&a" (__d0), "=&D" (__tmp), "=&c" (__d1),
+ "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
+ : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
+ : "cc");
+#else
+ __asm__ __volatile__
+ ("1:\tmovl %0,(%1)\n\t"
+ "leal 4(%1),%1\n\t"
+ "decl %2\n\t"
+ "jnz 1b\n"
+ "movw %w0,(%1)"
+ : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1),
+ "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
+ : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
+ : "cc");
+#endif
+ return __s;
+}
+
+#define __memset_gcn(s, c, n) \
+ (((n) % 4 == 0) \
+ ? __memset_gcn_by4 (s, c, n) \
+ : (((n) % 2 == 0) \
+ ? __memset_gcn_by2 (s, c, n) \
+ : memset (s, c, n)))
+
+__STRING_INLINE void *__memset_gcn_by4 (void *__s, int __c, size_t __n);
+
+__STRING_INLINE void *
+__memset_gcn_by4 (void *__s, int __c, size_t __n)
+{
+ register void *__tmp = __s;
+ register unsigned long int __d0;
+ __asm__ __volatile__
+ ("movb %b0,%h0\n"
+ "pushw %w0\n\t"
+ "shll $16,%0\n\t"
+ "popw %w0\n"
+ "1:\n\t"
+ "movl %0,(%1)\n\t"
+ "addl $4,%1\n\t"
+ "decl %2\n\t"
+ "jnz 1b\n"
+ : "=&q" (__c), "=&r" (__tmp), "=&r" (__d0),
+ "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
+ : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
+ : "cc");
+ return __s;
+}
+
+__STRING_INLINE void *__memset_gcn_by2 (void *__s, int __c, size_t __n);
+
+__STRING_INLINE void *
+__memset_gcn_by2 (void *__s, int __c, size_t __n)
+{
+ register unsigned long int __d0, __d1;
+ register void *__tmp = __s;
+ __asm__ __volatile__
+ ("movb %b0,%h0\n\t"
+ "pushw %w0\n\t"
+ "shll $16,%0\n\t"
+ "popw %w0\n"
+ "1:\n\t"
+ "movl %0,(%1)\n\t"
+ "leal 4(%1),%1\n\t"
+ "decl %2\n\t"
+ "jnz 1b\n"
+ "movw %w0,(%1)"
+ : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1),
+ "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
+ : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
+ : "cc");
+ return __s;
+}
+
+
+/* Search N bytes of S for C. */
+#define _HAVE_STRING_ARCH_memchr 1
+#ifndef _FORCE_INLINES
+__STRING_INLINE void *
+memchr (__const void *__s, int __c, size_t __n)
+{
+ register unsigned long int __d0;
+#ifdef __i686__
+ register unsigned long int __d1;
+#endif
+ register unsigned char *__res;
+ if (__n == 0)
+ return NULL;
+#ifdef __i686__
+ __asm__ __volatile__
+ ("cld\n\t"
+ "repne; scasb\n\t"
+ "cmovne %2,%0"
+ : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
+ : "a" (__c), "0" (__s), "1" (__n), "2" (1),
+ "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
+ : "cc");
+#else
+ __asm__ __volatile__
+ ("cld\n\t"
+ "repne; scasb\n\t"
+ "je 1f\n\t"
+ "movl $1,%0\n"
+ "1:"
+ : "=D" (__res), "=&c" (__d0)
+ : "a" (__c), "0" (__s), "1" (__n),
+ "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
+ : "cc");
+#endif
+ return __res - 1;
+}
+#endif
+
+#define _HAVE_STRING_ARCH_memrchr 1
+#ifndef _FORCE_INLINES
+__STRING_INLINE void *__memrchr (__const void *__s, int __c, size_t __n);
+
+__STRING_INLINE void *
+__memrchr (__const void *__s, int __c, size_t __n)
+{
+ register unsigned long int __d0;
+# ifdef __i686__
+ register unsigned long int __d1;
+# endif
+ register void *__res;
+ if (__n == 0)
+ return NULL;
+# ifdef __i686__
+ __asm__ __volatile__
+ ("std\n\t"
+ "repne; scasb\n\t"
+ "cmovne %2,%0\n\t"
+ "cld\n\t"
+ "incl %0"
+ : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
+ : "a" (__c), "0" (__s + __n - 1), "1" (__n), "2" (-1),
+ "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
+ : "cc");
+# else
+ __asm__ __volatile__
+ ("std\n\t"
+ "repne; scasb\n\t"
+ "je 1f\n\t"
+ "orl $-1,%0\n"
+ "1:\tcld\n\t"
+ "incl %0"
+ : "=D" (__res), "=&c" (__d0)
+ : "a" (__c), "0" (__s + __n - 1), "1" (__n),
+ "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
+ : "cc");
+# endif
+ return __res;
+}
+# ifdef __USE_GNU
+# define memrchr(s, c, n) __memrchr ((s), (c), (n))
+# endif
+#endif
+
+/* Return pointer to C in S. */
+#define _HAVE_STRING_ARCH_rawmemchr 1
+__STRING_INLINE void *__rawmemchr (const void *__s, int __c);
+
+#ifndef _FORCE_INLINES
+__STRING_INLINE void *
+__rawmemchr (const void *__s, int __c)
+{
+ register unsigned long int __d0;
+ register unsigned char *__res;
+ __asm__ __volatile__
+ ("cld\n\t"
+ "repne; scasb\n\t"
+ : "=D" (__res), "=&c" (__d0)
+ : "a" (__c), "0" (__s), "1" (0xffffffff),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s)
+ : "cc");
+ return __res - 1;
+}
+# ifdef __USE_GNU
+__STRING_INLINE void *
+rawmemchr (const void *__s, int __c)
+{
+ return __rawmemchr (__s, __c);
+}
+# endif /* use GNU */
+#endif
+
+
+/* Return the length of S. */
+#define _HAVE_STRING_ARCH_strlen 1
+#define strlen(str) \
+ (__extension__ (__builtin_constant_p (str) \
+ ? __builtin_strlen (str) \
+ : __strlen_g (str)))
+__STRING_INLINE size_t __strlen_g (__const char *__str);
+
+__STRING_INLINE size_t
+__strlen_g (__const char *__str)
+{
+ register char __dummy;
+ register __const char *__tmp = __str;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movb (%0),%b1\n\t"
+ "leal 1(%0),%0\n\t"
+ "testb %b1,%b1\n\t"
+ "jne 1b"
+ : "=r" (__tmp), "=&q" (__dummy)
+ : "0" (__str),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__str)
+ : "cc" );
+ return __tmp - __str - 1;
+}
+
+
+/* Copy SRC to DEST. */
+#define _HAVE_STRING_ARCH_strcpy 1
+#define strcpy(dest, src) \
+ (__extension__ (__builtin_constant_p (src) \
+ ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8 \
+ ? __strcpy_a_small ((dest), (src), strlen (src) + 1) \
+ : (char *) memcpy ((char *) (dest), \
+ (__const char *) (src), \
+ strlen (src) + 1)) \
+ : __strcpy_g ((dest), (src))))
+
+#define __strcpy_a_small(dest, src, srclen) \
+ (__extension__ ({ char *__dest = (dest); \
+ union { \
+ unsigned int __ui; \
+ unsigned short int __usi; \
+ unsigned char __uc; \
+ char __c; \
+ } *__u = (void *) __dest; \
+ switch (srclen) \
+ { \
+ case 1: \
+ __u->__uc = '\0'; \
+ break; \
+ case 2: \
+ __u->__usi = __STRING_SMALL_GET16 (src, 0); \
+ break; \
+ case 3: \
+ __u->__usi = __STRING_SMALL_GET16 (src, 0); \
+ __u = __extension__ ((void *) __u + 2); \
+ __u->__uc = '\0'; \
+ break; \
+ case 4: \
+ __u->__ui = __STRING_SMALL_GET32 (src, 0); \
+ break; \
+ case 5: \
+ __u->__ui = __STRING_SMALL_GET32 (src, 0); \
+ __u = __extension__ ((void *) __u + 4); \
+ __u->__uc = '\0'; \
+ break; \
+ case 6: \
+ __u->__ui = __STRING_SMALL_GET32 (src, 0); \
+ __u = __extension__ ((void *) __u + 4); \
+ __u->__usi = __STRING_SMALL_GET16 (src, 4); \
+ break; \
+ case 7: \
+ __u->__ui = __STRING_SMALL_GET32 (src, 0); \
+ __u = __extension__ ((void *) __u + 4); \
+ __u->__usi = __STRING_SMALL_GET16 (src, 4); \
+ __u = __extension__ ((void *) __u + 2); \
+ __u->__uc = '\0'; \
+ break; \
+ case 8: \
+ __u->__ui = __STRING_SMALL_GET32 (src, 0); \
+ __u = __extension__ ((void *) __u + 4); \
+ __u->__ui = __STRING_SMALL_GET32 (src, 4); \
+ break; \
+ } \
+ (char *) __dest; }))
+
+__STRING_INLINE char *__strcpy_g (char *__dest, __const char *__src);
+
+__STRING_INLINE char *
+__strcpy_g (char *__dest, __const char *__src)
+{
+ register char *__tmp = __dest;
+ register char __dummy;
+ __asm__ __volatile__
+ (
+ "1:\n\t"
+ "movb (%0),%b2\n\t"
+ "leal 1(%0),%0\n\t"
+ "movb %b2,(%1)\n\t"
+ "leal 1(%1),%1\n\t"
+ "testb %b2,%b2\n\t"
+ "jne 1b"
+ : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy),
+ "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
+ : "0" (__src), "1" (__tmp),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__src)
+ : "cc");
+ return __dest;
+}
+
+
+#ifdef __USE_GNU
+# define _HAVE_STRING_ARCH_stpcpy 1
+/* Copy SRC to DEST. */
+# define __stpcpy(dest, src) \
+ (__extension__ (__builtin_constant_p (src) \
+ ? (strlen (src) + 1 <= 8 \
+ ? __stpcpy_a_small ((dest), (src), strlen (src) + 1) \
+ : __stpcpy_c ((dest), (src), strlen (src) + 1)) \
+ : __stpcpy_g ((dest), (src))))
+# define __stpcpy_c(dest, src, srclen) \
+ ((srclen) % 4 == 0 \
+ ? __mempcpy_by4 (dest, src, srclen) - 1 \
+ : ((srclen) % 2 == 0 \
+ ? __mempcpy_by2 (dest, src, srclen) - 1 \
+ : __mempcpy_byn (dest, src, srclen) - 1))
+
+/* In glibc itself we use this symbol for namespace reasons. */
+# define stpcpy(dest, src) __stpcpy ((dest), (src))
+
+# define __stpcpy_a_small(dest, src, srclen) \
+ (__extension__ ({ union { \
+ unsigned int __ui; \
+ unsigned short int __usi; \
+ unsigned char __uc; \
+ char __c; \
+ } *__u = (void *) (dest); \
+ switch (srclen) \
+ { \
+ case 1: \
+ __u->__uc = '\0'; \
+ break; \
+ case 2: \
+ __u->__usi = __STRING_SMALL_GET16 (src, 0); \
+ __u = __extension__ ((void *) __u + 1); \
+ break; \
+ case 3: \
+ __u->__usi = __STRING_SMALL_GET16 (src, 0); \
+ __u = __extension__ ((void *) __u + 2); \
+ __u->__uc = '\0'; \
+ break; \
+ case 4: \
+ __u->__ui = __STRING_SMALL_GET32 (src, 0); \
+ __u = __extension__ ((void *) __u + 3); \
+ break; \
+ case 5: \
+ __u->__ui = __STRING_SMALL_GET32 (src, 0); \
+ __u = __extension__ ((void *) __u + 4); \
+ __u->__uc = '\0'; \
+ break; \
+ case 6: \
+ __u->__ui = __STRING_SMALL_GET32 (src, 0); \
+ __u = __extension__ ((void *) __u + 4); \
+ __u->__usi = __STRING_SMALL_GET16 (src, 4); \
+ __u = __extension__ ((void *) __u + 1); \
+ break; \
+ case 7: \
+ __u->__ui = __STRING_SMALL_GET32 (src, 0); \
+ __u = __extension__ ((void *) __u + 4); \
+ __u->__usi = __STRING_SMALL_GET16 (src, 4); \
+ __u = __extension__ ((void *) __u + 2); \
+ __u->__uc = '\0'; \
+ break; \
+ case 8: \
+ __u->__ui = __STRING_SMALL_GET32 (src, 0); \
+ __u = __extension__ ((void *) __u + 4); \
+ __u->__ui = __STRING_SMALL_GET32 (src, 4); \
+ __u = __extension__ ((void *) __u + 3); \
+ break; \
+ } \
+ (char *) __u; }))
+
+__STRING_INLINE char *__mempcpy_by4 (char *__dest, __const char *__src,
+ size_t __srclen);
+
+__STRING_INLINE char *
+__mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
+{
+ register char *__tmp = __dest;
+ register unsigned long int __d0, __d1;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movl (%2),%0\n\t"
+ "leal 4(%2),%2\n\t"
+ "movl %0,(%1)\n\t"
+ "leal 4(%1),%1\n\t"
+ "decl %3\n\t"
+ "jnz 1b"
+ : "=&r" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
+ : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
+ : "memory", "cc");
+ return __tmp;
+}
+
+__STRING_INLINE char *__mempcpy_by2 (char *__dest, __const char *__src,
+ size_t __srclen);
+
+__STRING_INLINE char *
+__mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
+{
+ register char *__tmp = __dest;
+ register unsigned long int __d0, __d1;
+ __asm__ __volatile__
+ ("shrl $1,%3\n\t"
+ "jz 2f\n" /* only a word */
+ "1:\n\t"
+ "movl (%2),%0\n\t"
+ "leal 4(%2),%2\n\t"
+ "movl %0,(%1)\n\t"
+ "leal 4(%1),%1\n\t"
+ "decl %3\n\t"
+ "jnz 1b\n"
+ "2:\n\t"
+ "movw (%2),%w0\n\t"
+ "movw %w0,(%1)"
+ : "=&q" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1),
+ "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
+ : "1" (__tmp), "2" (__src), "3" (__srclen / 2),
+ "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
+ : "cc");
+ return __tmp + 2;
+}
+
+__STRING_INLINE char *__mempcpy_byn (char *__dest, __const char *__src,
+ size_t __srclen);
+
+__STRING_INLINE char *
+__mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
+{
+ register unsigned long __d0, __d1;
+ register char *__tmp = __dest;
+ __asm__ __volatile__
+ ("cld\n\t"
+ "shrl $1,%%ecx\n\t"
+ "jnc 1f\n\t"
+ "movsb\n"
+ "1:\n\t"
+ "shrl $1,%%ecx\n\t"
+ "jnc 2f\n\t"
+ "movsw\n"
+ "2:\n\t"
+ "rep; movsl"
+ : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1),
+ "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
+ : "0" (__tmp), "1" (__srclen), "2" (__src),
+ "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
+ : "cc");
+ return __tmp;
+}
+
+__STRING_INLINE char *__stpcpy_g (char *__dest, __const char *__src);
+
+__STRING_INLINE char *
+__stpcpy_g (char *__dest, __const char *__src)
+{
+ register char *__tmp = __dest;
+ register char __dummy;
+ __asm__ __volatile__
+ (
+ "1:\n\t"
+ "movb (%0),%b2\n\t"
+ "leal 1(%0),%0\n\t"
+ "movb %b2,(%1)\n\t"
+ "leal 1(%1),%1\n\t"
+ "testb %b2,%b2\n\t"
+ "jne 1b"
+ : "=&r" (__src), "=r" (__tmp), "=&q" (__dummy),
+ "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
+ : "0" (__src), "1" (__tmp),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__src)
+ : "cc");
+ return __tmp - 1;
+}
+#endif
+
+
+/* Copy no more than N characters of SRC to DEST. */
+#define _HAVE_STRING_ARCH_strncpy 1
+#define strncpy(dest, src, n) \
+ (__extension__ (__builtin_constant_p (src) \
+ ? ((strlen (src) + 1 >= ((size_t) (n)) \
+ ? (char *) memcpy ((char *) (dest), \
+ (__const char *) (src), n) \
+ : __strncpy_cg ((dest), (src), strlen (src) + 1, n))) \
+ : __strncpy_gg ((dest), (src), n)))
+#define __strncpy_cg(dest, src, srclen, n) \
+ (((srclen) % 4 == 0) \
+ ? __strncpy_by4 (dest, src, srclen, n) \
+ : (((srclen) % 2 == 0) \
+ ? __strncpy_by2 (dest, src, srclen, n) \
+ : __strncpy_byn (dest, src, srclen, n)))
+
+__STRING_INLINE char *__strncpy_by4 (char *__dest, __const char __src[],
+ size_t __srclen, size_t __n);
+
+__STRING_INLINE char *
+__strncpy_by4 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
+{
+ register char *__tmp = __dest;
+ register int __dummy1, __dummy2;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movl (%2),%0\n\t"
+ "leal 4(%2),%2\n\t"
+ "movl %0,(%1)\n\t"
+ "leal 4(%1),%1\n\t"
+ "decl %3\n\t"
+ "jnz 1b"
+ : "=&r" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2),
+ "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
+ : "1" (__tmp), "2" (__src), "3" (__srclen / 4),
+ "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
+ : "cc");
+ (void) memset (__tmp, '\0', __n - __srclen);
+ return __dest;
+}
+
+__STRING_INLINE char *__strncpy_by2 (char *__dest, __const char __src[],
+ size_t __srclen, size_t __n);
+
+__STRING_INLINE char *
+__strncpy_by2 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
+{
+ register char *__tmp = __dest;
+ register int __dummy1, __dummy2;
+ __asm__ __volatile__
+ ("shrl $1,%3\n\t"
+ "jz 2f\n" /* only a word */
+ "1:\n\t"
+ "movl (%2),%0\n\t"
+ "leal 4(%2),%2\n\t"
+ "movl %0,(%1)\n\t"
+ "leal 4(%1),%1\n\t"
+ "decl %3\n\t"
+ "jnz 1b\n"
+ "2:\n\t"
+ "movw (%2),%w0\n\t"
+ "movw %w0,(%1)\n\t"
+ : "=&q" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2),
+ "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
+ : "1" (__tmp), "2" (__src), "3" (__srclen / 2),
+ "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
+ : "cc");
+ (void) memset (__tmp + 2, '\0', __n - __srclen);
+ return __dest;
+}
+
+__STRING_INLINE char *__strncpy_byn (char *__dest, __const char __src[],
+ size_t __srclen, size_t __n);
+
+__STRING_INLINE char *
+__strncpy_byn (char *__dest, __const char __src[], size_t __srclen, size_t __n)
+{
+ register unsigned long int __d0, __d1;
+ register char *__tmp = __dest;
+ __asm__ __volatile__
+ ("cld\n\t"
+ "shrl $1,%1\n\t"
+ "jnc 1f\n\t"
+ "movsb\n"
+ "1:\n\t"
+ "shrl $1,%1\n\t"
+ "jnc 2f\n\t"
+ "movsw\n"
+ "2:\n\t"
+ "rep; movsl"
+ : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1),
+ "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
+ : "1" (__srclen), "0" (__tmp),"2" (__src),
+ "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
+ : "cc");
+ (void) memset (__tmp, '\0', __n - __srclen);
+ return __dest;
+}
+
+__STRING_INLINE char *__strncpy_gg (char *__dest, __const char *__src,
+ size_t __n);
+
+__STRING_INLINE char *
+__strncpy_gg (char *__dest, __const char *__src, size_t __n)
+{
+ register char *__tmp = __dest;
+ register char __dummy;
+ if (__n > 0)
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movb (%0),%2\n\t"
+ "incl %0\n\t"
+ "movb %2,(%1)\n\t"
+ "incl %1\n\t"
+ "decl %3\n\t"
+ "je 3f\n\t"
+ "testb %2,%2\n\t"
+ "jne 1b\n\t"
+ "2:\n\t"
+ "movb %2,(%1)\n\t"
+ "incl %1\n\t"
+ "decl %3\n\t"
+ "jne 2b\n\t"
+ "3:"
+ : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy), "=&r" (__n)
+ : "0" (__src), "1" (__tmp), "3" (__n)
+ : "memory", "cc");
+
+ return __dest;
+}
+
+
+/* Append SRC onto DEST. */
+#define _HAVE_STRING_ARCH_strcat 1
+#define strcat(dest, src) \
+ (__extension__ (__builtin_constant_p (src) \
+ ? __strcat_c ((dest), (src), strlen (src) + 1) \
+ : __strcat_g ((dest), (src))))
+
+__STRING_INLINE char *__strcat_c (char *__dest, __const char __src[],
+ size_t __srclen);
+
+__STRING_INLINE char *
+__strcat_c (char *__dest, __const char __src[], size_t __srclen)
+{
+#ifdef __i686__
+ register unsigned long int __d0;
+ register char *__tmp;
+ __asm__ __volatile__
+ ("repne; scasb"
+ : "=D" (__tmp), "=&c" (__d0),
+ "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
+ : "0" (__dest), "1" (0xffffffff), "a" (0),
+ "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
+ : "cc");
+ --__tmp;
+#else
+ register char *__tmp = __dest - 1;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "incl %0\n\t"
+ "cmpb $0,(%0)\n\t"
+ "jne 1b\n"
+ : "=r" (__tmp),
+ "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
+ : "0" (__tmp),
+ "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
+ : "cc");
+#endif
+ (void) memcpy (__tmp, __src, __srclen);
+ return __dest;
+}
+
+__STRING_INLINE char *__strcat_g (char *__dest, __const char *__src);
+
+__STRING_INLINE char *
+__strcat_g (char *__dest, __const char *__src)
+{
+ register char *__tmp = __dest - 1;
+ register char __dummy;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "incl %1\n\t"
+ "cmpb $0,(%1)\n\t"
+ "jne 1b\n"
+ "2:\n\t"
+ "movb (%2),%b0\n\t"
+ "incl %2\n\t"
+ "movb %b0,(%1)\n\t"
+ "incl %1\n\t"
+ "testb %b0,%b0\n\t"
+ "jne 2b\n"
+ : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src),
+ "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
+ : "1" (__tmp), "2" (__src),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__src)
+ : "memory", "cc");
+ return __dest;
+}
+
+
+/* Append no more than N characters from SRC onto DEST. */
+#define _HAVE_STRING_ARCH_strncat 1
+#define strncat(dest, src, n) \
+ (__extension__ ({ char *__dest = (dest); \
+ __builtin_constant_p (src) && __builtin_constant_p (n) \
+ ? (strlen (src) < ((size_t) (n)) \
+ ? strcat (__dest, (src)) \
+ : (*(char *)__mempcpy (strchr (__dest, '\0'), \
+ (__const char *) (src), \
+ (n)) = 0, __dest)) \
+ : __strncat_g (__dest, (src), (n)); }))
+
+__STRING_INLINE char *__strncat_g (char *__dest, __const char __src[],
+ size_t __n);
+
+__STRING_INLINE char *
+__strncat_g (char *__dest, __const char __src[], size_t __n)
+{
+ register char *__tmp = __dest;
+ register char __dummy;
+#ifdef __i686__
+ __asm__ __volatile__
+ ("repne; scasb\n"
+ "movl %4, %3\n\t"
+ "decl %1\n\t"
+ "1:\n\t"
+ "decl %3\n\t"
+ "js 2f\n\t"
+ "movb (%2),%b0\n\t"
+ "movsb\n\t"
+ "testb %b0,%b0\n\t"
+ "jne 1b\n\t"
+ "decl %1\n"
+ "2:\n\t"
+ "movb $0,(%1)"
+ : "=&a" (__dummy), "=&D" (__tmp), "=&S" (__src), "=&c" (__n)
+ : "g" (__n), "0" (0), "1" (__tmp), "2" (__src), "3" (0xffffffff)
+ : "memory", "cc");
+#else
+ --__tmp;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "cmpb $0,1(%1)\n\t"
+ "leal 1(%1),%1\n\t"
+ "jne 1b\n"
+ "2:\n\t"
+ "decl %3\n\t"
+ "js 3f\n\t"
+ "movb (%2),%b0\n\t"
+ "leal 1(%2),%2\n\t"
+ "movb %b0,(%1)\n\t"
+ "leal 1(%1),%1\n\t"
+ "testb %b0,%b0\n\t"
+ "jne 2b\n\t"
+ "decl %1\n"
+ "3:\n\t"
+ "movb $0,(%1)"
+ : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src), "=&r" (__n)
+ : "1" (__tmp), "2" (__src), "3" (__n)
+ : "memory", "cc");
+#endif
+ return __dest;
+}
+
+
+/* Compare S1 and S2. */
+#define _HAVE_STRING_ARCH_strcmp 1
+#define strcmp(s1, s2) \
+ (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
+ && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4) \
+ && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4) \
+ ? memcmp ((__const char *) (s1), (__const char *) (s2), \
+ (strlen (s1) < strlen (s2) \
+ ? strlen (s1) : strlen (s2)) + 1) \
+ : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1 \
+ && sizeof ((s2)[0]) == 1 && strlen (s1) < 4 \
+ ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1 \
+ ? __strcmp_cc ((__const unsigned char *) (s1), \
+ (__const unsigned char *) (s2), \
+ strlen (s1)) \
+ : __strcmp_cg ((__const unsigned char *) (s1), \
+ (__const unsigned char *) (s2), \
+ strlen (s1))) \
+ : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1 \
+ && sizeof ((s2)[0]) == 1 && strlen (s2) < 4 \
+ ? (__builtin_constant_p (s1) \
+ ? __strcmp_cc ((__const unsigned char *) (s1), \
+ (__const unsigned char *) (s2), \
+ strlen (s2)) \
+ : __strcmp_gc ((__const unsigned char *) (s1), \
+ (__const unsigned char *) (s2), \
+ strlen (s2))) \
+ : __strcmp_gg ((s1), (s2))))))
+
+#define __strcmp_cc(s1, s2, l) \
+ (__extension__ ({ register int __result = (s1)[0] - (s2)[0]; \
+ if (l > 0 && __result == 0) \
+ { \
+ __result = (s1)[1] - (s2)[1]; \
+ if (l > 1 && __result == 0) \
+ { \
+ __result = (s1)[2] - (s2)[2]; \
+ if (l > 2 && __result == 0) \
+ __result = (s1)[3] - (s2)[3]; \
+ } \
+ } \
+ __result; }))
+
+#define __strcmp_cg(s1, s2, l1) \
+ (__extension__ ({ __const unsigned char *__s2 = (s2); \
+ register int __result = (s1)[0] - __s2[0]; \
+ if (l1 > 0 && __result == 0) \
+ { \
+ __result = (s1)[1] - __s2[1]; \
+ if (l1 > 1 && __result == 0) \
+ { \
+ __result = (s1)[2] - __s2[2]; \
+ if (l1 > 2 && __result == 0) \
+ __result = (s1)[3] - __s2[3]; \
+ } \
+ } \
+ __result; }))
+
+#define __strcmp_gc(s1, s2, l2) \
+ (__extension__ ({ __const unsigned char *__s1 = (s1); \
+ register int __result = __s1[0] - (s2)[0]; \
+ if (l2 > 0 && __result == 0) \
+ { \
+ __result = __s1[1] - (s2)[1]; \
+ if (l2 > 1 && __result == 0) \
+ { \
+ __result = __s1[2] - (s2)[2]; \
+ if (l2 > 2 && __result == 0) \
+ __result = __s1[3] - (s2)[3]; \
+ } \
+ } \
+ __result; }))
+
+__STRING_INLINE int __strcmp_gg (__const char *__s1, __const char *__s2);
+
+__STRING_INLINE int
+__strcmp_gg (__const char *__s1, __const char *__s2)
+{
+ register int __res;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movb (%1),%b0\n\t"
+ "leal 1(%1),%1\n\t"
+ "cmpb %b0,(%2)\n\t"
+ "jne 2f\n\t"
+ "leal 1(%2),%2\n\t"
+ "testb %b0,%b0\n\t"
+ "jne 1b\n\t"
+ "xorl %0,%0\n\t"
+ "jmp 3f\n"
+ "2:\n\t"
+ "movl $1,%0\n\t"
+ "jb 3f\n\t"
+ "negl %0\n"
+ "3:"
+ : "=q" (__res), "=&r" (__s1), "=&r" (__s2)
+ : "1" (__s1), "2" (__s2),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s1),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s2)
+ : "cc");
+ return __res;
+}
+
+
+/* Compare N characters of S1 and S2. */
+#define _HAVE_STRING_ARCH_strncmp 1
+#define strncmp(s1, s2, n) \
+ (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
+ ? strcmp ((s1), (s2)) \
+ : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
+ ? strcmp ((s1), (s2)) \
+ : __strncmp_g ((s1), (s2), (n)))))
+
+__STRING_INLINE int __strncmp_g (__const char *__s1, __const char *__s2,
+ size_t __n);
+
+__STRING_INLINE int
+__strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
+{
+ register int __res;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "decl %3\n\t"
+ "js 2f\n\t"
+ "movb (%1),%b0\n\t"
+ "incl %1\n\t"
+ "cmpb %b0,(%2)\n\t"
+ "jne 3f\n\t"
+ "incl %2\n\t"
+ "testb %b0,%b0\n\t"
+ "jne 1b\n"
+ "2:\n\t"
+ "xorl %0,%0\n\t"
+ "jmp 4f\n"
+ "3:\n\t"
+ "movl $1,%0\n\t"
+ "jb 4f\n\t"
+ "negl %0\n"
+ "4:"
+ : "=q" (__res), "=&r" (__s1), "=&r" (__s2), "=&r" (__n)
+ : "1" (__s1), "2" (__s2), "3" (__n),
+ "m" ( *(struct { __extension__ char __x[__n]; } *)__s1),
+ "m" ( *(struct { __extension__ char __x[__n]; } *)__s2)
+ : "cc");
+ return __res;
+}
+
+
+/* Find the first occurrence of C in S. */
+#define _HAVE_STRING_ARCH_strchr 1
+#define _USE_STRING_ARCH_strchr 1
+#define strchr(s, c) \
+ (__extension__ (__builtin_constant_p (c) \
+ ? ((c) == '\0' \
+ ? (char *) __rawmemchr ((s), (c)) \
+ : __strchr_c ((s), ((c) & 0xff) << 8)) \
+ : __strchr_g ((s), (c))))
+
+__STRING_INLINE char *__strchr_c (__const char *__s, int __c);
+
+__STRING_INLINE char *
+__strchr_c (__const char *__s, int __c)
+{
+ register unsigned long int __d0;
+ register char *__res;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movb (%0),%%al\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "je 2f\n\t"
+ "leal 1(%0),%0\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n\t"
+ "xorl %0,%0\n"
+ "2:"
+ : "=r" (__res), "=&a" (__d0)
+ : "0" (__s), "1" (__c),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s)
+ : "cc");
+ return __res;
+}
+
+__STRING_INLINE char *__strchr_g (__const char *__s, int __c);
+
+__STRING_INLINE char *
+__strchr_g (__const char *__s, int __c)
+{
+ register unsigned long int __d0;
+ register char *__res;
+ __asm__ __volatile__
+ ("movb %%al,%%ah\n"
+ "1:\n\t"
+ "movb (%0),%%al\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "je 2f\n\t"
+ "leal 1(%0),%0\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n\t"
+ "xorl %0,%0\n"
+ "2:"
+ : "=r" (__res), "=&a" (__d0)
+ : "0" (__s), "1" (__c),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s)
+ : "cc");
+ return __res;
+}
+
+
+/* Find the first occurrence of C in S or the final NUL byte. */
+#define _HAVE_STRING_ARCH_strchrnul 1
+#define __strchrnul(s, c) \
+ (__extension__ (__builtin_constant_p (c) \
+ ? ((c) == '\0' \
+ ? (char *) __rawmemchr ((s), c) \
+ : __strchrnul_c ((s), ((c) & 0xff) << 8)) \
+ : __strchrnul_g ((s), c)))
+
+__STRING_INLINE char *__strchrnul_c (__const char *__s, int __c);
+
+__STRING_INLINE char *
+__strchrnul_c (__const char *__s, int __c)
+{
+ register unsigned long int __d0;
+ register char *__res;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movb (%0),%%al\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "je 2f\n\t"
+ "leal 1(%0),%0\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n\t"
+ "decl %0\n"
+ "2:"
+ : "=r" (__res), "=&a" (__d0)
+ : "0" (__s), "1" (__c),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s)
+ : "cc");
+ return __res;
+}
+
+__STRING_INLINE char *__strchrnul_g (__const char *__s, int __c);
+
+__STRING_INLINE char *
+__strchrnul_g (__const char *__s, int __c)
+{
+ register unsigned long int __d0;
+ register char *__res;
+ __asm__ __volatile__
+ ("movb %%al,%%ah\n"
+ "1:\n\t"
+ "movb (%0),%%al\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "je 2f\n\t"
+ "leal 1(%0),%0\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n\t"
+ "decl %0\n"
+ "2:"
+ : "=r" (__res), "=&a" (__d0)
+ : "0" (__s), "1" (__c),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s)
+ : "cc");
+ return __res;
+}
+#ifdef __USE_GNU
+# define strchrnul(s, c) __strchrnul ((s), (c))
+#endif
+
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+/* Find the first occurrence of C in S. This is the BSD name. */
+# define _HAVE_STRING_ARCH_index 1
+# define index(s, c) \
+ (__extension__ (__builtin_constant_p (c) \
+ ? __strchr_c ((s), ((c) & 0xff) << 8) \
+ : __strchr_g ((s), (c))))
+#endif
+
+
+/* Find the last occurrence of C in S. */
+#define _HAVE_STRING_ARCH_strrchr 1
+#define strrchr(s, c) \
+ (__extension__ (__builtin_constant_p (c) \
+ ? __strrchr_c ((s), ((c) & 0xff) << 8) \
+ : __strrchr_g ((s), (c))))
+
+#ifdef __i686__
+__STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
+
+__STRING_INLINE char *
+__strrchr_c (__const char *__s, int __c)
+{
+ register unsigned long int __d0, __d1;
+ register char *__res;
+ __asm__ __volatile__
+ ("cld\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "cmpb %h2,%b2\n\t"
+ "cmove %1,%0\n\t"
+ "testb %b2,%b2\n\t"
+ "jne 1b"
+ : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
+ : "0" (1), "1" (__s), "2" (__c),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s)
+ : "cc");
+ return __res - 1;
+}
+
+__STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
+
+__STRING_INLINE char *
+__strrchr_g (__const char *__s, int __c)
+{
+ register unsigned long int __d0, __d1;
+ register char *__res;
+ __asm__ __volatile__
+ ("movb %b2,%h2\n"
+ "cld\n\t"
+ "1:\n\t"
+ "lodsb\n\t"
+ "cmpb %h2,%b2\n\t"
+ "cmove %1,%0\n\t"
+ "testb %b2,%b2\n\t"
+ "jne 1b"
+ : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
+ : "0" (1), "1" (__s), "2" (__c),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s)
+ : "cc");
+ return __res - 1;
+}
+#else
+__STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
+
+__STRING_INLINE char *
+__strrchr_c (__const char *__s, int __c)
+{
+ register unsigned long int __d0, __d1;
+ register char *__res;
+ __asm__ __volatile__
+ ("cld\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "jne 2f\n\t"
+ "leal -1(%%esi),%0\n"
+ "2:\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b"
+ : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
+ : "0" (0), "1" (__s), "2" (__c),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s)
+ : "cc");
+ return __res;
+}
+
+__STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
+
+__STRING_INLINE char *
+__strrchr_g (__const char *__s, int __c)
+{
+ register unsigned long int __d0, __d1;
+ register char *__res;
+ __asm__ __volatile__
+ ("movb %%al,%%ah\n"
+ "cld\n\t"
+ "1:\n\t"
+ "lodsb\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "jne 2f\n\t"
+ "leal -1(%%esi),%0\n"
+ "2:\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b"
+ : "=r" (__res), "=&S" (__d0), "=&a" (__d1)
+ : "0" (0), "1" (__s), "2" (__c),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s)
+ : "cc");
+ return __res;
+}
+#endif
+
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+/* Find the last occurrence of C in S. This is the BSD name. */
+# define _HAVE_STRING_ARCH_rindex 1
+# define rindex(s, c) \
+ (__extension__ (__builtin_constant_p (c) \
+ ? __strrchr_c ((s), ((c) & 0xff) << 8) \
+ : __strrchr_g ((s), (c))))
+#endif
+
+
+/* Return the length of the initial segment of S which
+ consists entirely of characters not in REJECT. */
+#define _HAVE_STRING_ARCH_strcspn 1
+#define strcspn(s, reject) \
+ (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
+ ? ((reject)[0] == '\0' \
+ ? strlen (s) \
+ : ((reject)[1] == '\0' \
+ ? __strcspn_c1 ((s), (((reject)[0] << 8) & 0xff00)) \
+ : __strcspn_cg ((s), (reject), strlen (reject)))) \
+ : __strcspn_g ((s), (reject))))
+
+__STRING_INLINE size_t __strcspn_c1 (__const char *__s, int __reject);
+
+#ifndef _FORCE_INLINES
+__STRING_INLINE size_t
+__strcspn_c1 (__const char *__s, int __reject)
+{
+ register unsigned long int __d0;
+ register char *__res;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movb (%0),%%al\n\t"
+ "leal 1(%0),%0\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "je 2f\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n"
+ "2:"
+ : "=r" (__res), "=&a" (__d0)
+ : "0" (__s), "1" (__reject),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s)
+ : "cc");
+ return (__res - 1) - __s;
+}
+#endif
+
+__STRING_INLINE size_t __strcspn_cg (__const char *__s, __const char __reject[],
+ size_t __reject_len);
+
+__STRING_INLINE size_t
+__strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
+{
+ register unsigned long int __d0, __d1, __d2;
+ register __const char *__res;
+ __asm__ __volatile__
+ ("cld\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %5,%%edi\n\t"
+ "movl %6,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "jne 1b\n"
+ "2:"
+ : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
+ : "0" (__s), "d" (__reject), "g" (__reject_len)
+ : "memory", "cc");
+ return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t __strcspn_g (__const char *__s, __const char *__reject);
+#ifdef __PIC__
+
+__STRING_INLINE size_t
+__strcspn_g (__const char *__s, __const char *__reject)
+{
+ register unsigned long int __d0, __d1, __d2;
+ register __const char *__res;
+ __asm__ __volatile__
+ ("pushl %%ebx\n\t"
+ "movl %4,%%edi\n\t"
+ "cld\n\t"
+ "repne; scasb\n\t"
+ "notl %%ecx\n\t"
+ "leal -1(%%ecx),%%ebx\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %4,%%edi\n\t"
+ "movl %%ebx,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "jne 1b\n"
+ "2:\n\t"
+ "popl %%ebx"
+ : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
+ : "r" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
+ : "memory", "cc");
+ return (__res - 1) - __s;
+}
+#else
+__STRING_INLINE size_t
+__strcspn_g (__const char *__s, __const char *__reject)
+{
+ register unsigned long int __d0, __d1, __d2, __d3;
+ register __const char *__res;
+ __asm__ __volatile__
+ ("cld\n\t"
+ "repne; scasb\n\t"
+ "notl %%ecx\n\t"
+ "leal -1(%%ecx),%%edx\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %%ebx,%%edi\n\t"
+ "movl %%edx,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "jne 1b\n"
+ "2:"
+ : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
+ : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__reject), "b" (__reject)
+ /* Clobber memory, otherwise GCC cannot handle this. */
+ : "memory", "cc");
+ return (__res - 1) - __s;
+}
+#endif
+
+
+/* Return the length of the initial segment of S which
+ consists entirely of characters in ACCEPT. */
+#define _HAVE_STRING_ARCH_strspn 1
+#define strspn(s, accept) \
+ (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
+ ? ((accept)[0] == '\0' \
+ ? ((void) (s), 0) \
+ : ((accept)[1] == '\0' \
+ ? __strspn_c1 ((s), (((accept)[0] << 8 ) & 0xff00)) \
+ : __strspn_cg ((s), (accept), strlen (accept)))) \
+ : __strspn_g ((s), (accept))))
+
+#ifndef _FORCE_INLINES
+__STRING_INLINE size_t __strspn_c1 (__const char *__s, int __accept);
+
+__STRING_INLINE size_t
+__strspn_c1 (__const char *__s, int __accept)
+{
+ register unsigned long int __d0;
+ register char *__res;
+ /* Please note that __accept never can be '\0'. */
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movb (%0),%b1\n\t"
+ "leal 1(%0),%0\n\t"
+ "cmpb %h1,%b1\n\t"
+ "je 1b"
+ : "=r" (__res), "=&q" (__d0)
+ : "0" (__s), "1" (__accept),
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s)
+ : "cc");
+ return (__res - 1) - __s;
+}
+#endif
+
+__STRING_INLINE size_t __strspn_cg (__const char *__s, __const char __accept[],
+ size_t __accept_len);
+
+__STRING_INLINE size_t
+__strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
+{
+ register unsigned long int __d0, __d1, __d2;
+ register __const char *__res;
+ __asm__ __volatile__
+ ("cld\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %5,%%edi\n\t"
+ "movl %6,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "je 1b\n"
+ "2:"
+ : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
+ : "0" (__s), "g" (__accept), "g" (__accept_len),
+ /* Since we do not know how large the memory we access it, use a
+ really large amount. */
+ "m" ( *(struct { char __x[0xfffffff]; } *)__s),
+ "m" ( *(struct { __extension__ char __x[__accept_len]; } *)__accept)
+ : "cc");
+ return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t __strspn_g (__const char *__s, __const char *__accept);
+#ifdef __PIC__
+
+__STRING_INLINE size_t
+__strspn_g (__const char *__s, __const char *__accept)
+{
+ register unsigned long int __d0, __d1, __d2;
+ register __const char *__res;
+ __asm__ __volatile__
+ ("pushl %%ebx\n\t"
+ "cld\n\t"
+ "repne; scasb\n\t"
+ "notl %%ecx\n\t"
+ "leal -1(%%ecx),%%ebx\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %%edx,%%edi\n\t"
+ "movl %%ebx,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "je 1b\n"
+ "2:\n\t"
+ "popl %%ebx"
+ : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
+ : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept)
+ : "memory", "cc");
+ return (__res - 1) - __s;
+}
+#else
+__STRING_INLINE size_t
+__strspn_g (__const char *__s, __const char *__accept)
+{
+ register unsigned long int __d0, __d1, __d2, __d3;
+ register __const char *__res;
+ __asm__ __volatile__
+ ("cld\n\t"
+ "repne; scasb\n\t"
+ "notl %%ecx\n\t"
+ "leal -1(%%ecx),%%edx\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %%ebx,%%edi\n\t"
+ "movl %%edx,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "je 1b\n"
+ "2:"
+ : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
+ : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept), "b" (__accept)
+ : "memory", "cc");
+ return (__res - 1) - __s;
+}
+#endif
+
+
+/* Find the first occurrence in S of any character in ACCEPT. */
+#define _HAVE_STRING_ARCH_strpbrk 1
+#define strpbrk(s, accept) \
+ (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
+ ? ((accept)[0] == '\0' \
+ ? ((void) (s), (char *) 0) \
+ : ((accept)[1] == '\0' \
+ ? strchr ((s), (accept)[0]) \
+ : __strpbrk_cg ((s), (accept), strlen (accept)))) \
+ : __strpbrk_g ((s), (accept))))
+
+__STRING_INLINE char *__strpbrk_cg (__const char *__s, __const char __accept[],
+ size_t __accept_len);
+
+__STRING_INLINE char *
+__strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
+{
+ register unsigned long int __d0, __d1, __d2;
+ register char *__res;
+ __asm__ __volatile__
+ ("cld\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %5,%%edi\n\t"
+ "movl %6,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "jne 1b\n\t"
+ "decl %0\n\t"
+ "jmp 3f\n"
+ "2:\n\t"
+ "xorl %0,%0\n"
+ "3:"
+ : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
+ : "0" (__s), "d" (__accept), "g" (__accept_len)
+ : "memory", "cc");
+ return __res;
+}
+
+__STRING_INLINE char *__strpbrk_g (__const char *__s, __const char *__accept);
+#ifdef __PIC__
+
+__STRING_INLINE char *
+__strpbrk_g (__const char *__s, __const char *__accept)
+{
+ register unsigned long int __d0, __d1, __d2;
+ register char *__res;
+ __asm__ __volatile__
+ ("pushl %%ebx\n\t"
+ "movl %%edx,%%edi\n\t"
+ "cld\n\t"
+ "repne; scasb\n\t"
+ "notl %%ecx\n\t"
+ "leal -1(%%ecx),%%ebx\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %%edx,%%edi\n\t"
+ "movl %%ebx,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "jne 1b\n\t"
+ "decl %0\n\t"
+ "jmp 3f\n"
+ "2:\n\t"
+ "xorl %0,%0\n"
+ "3:\n\t"
+ "popl %%ebx"
+ : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
+ : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
+ : "memory", "cc");
+ return __res;
+}
+#else
+__STRING_INLINE char *
+__strpbrk_g (__const char *__s, __const char *__accept)
+{
+ register unsigned long int __d0, __d1, __d2, __d3;
+ register char *__res;
+ __asm__ __volatile__
+ ("movl %%ebx,%%edi\n\t"
+ "cld\n\t"
+ "repne; scasb\n\t"
+ "notl %%ecx\n\t"
+ "leal -1(%%ecx),%%edx\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %%ebx,%%edi\n\t"
+ "movl %%edx,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "jne 1b\n\t"
+ "decl %0\n\t"
+ "jmp 3f\n"
+ "2:\n\t"
+ "xorl %0,%0\n"
+ "3:"
+ : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
+ : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
+ : "memory", "cc");
+ return __res;
+}
+#endif
+
+
+/* Find the first occurrence of NEEDLE in HAYSTACK. */
+#define _HAVE_STRING_ARCH_strstr 1
+#define strstr(haystack, needle) \
+ (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
+ ? ((needle)[0] == '\0' \
+ ? (haystack) \
+ : ((needle)[1] == '\0' \
+ ? strchr ((haystack), (needle)[0]) \
+ : __strstr_cg ((haystack), (needle), \
+ strlen (needle)))) \
+ : __strstr_g ((haystack), (needle))))
+
+/* Please note that this function need not handle NEEDLEs with a
+ length shorter than two. */
+__STRING_INLINE char *__strstr_cg (__const char *__haystack, __const char __needle[],
+ size_t __needle_len);
+
+__STRING_INLINE char *
+__strstr_cg (__const char *__haystack, __const char __needle[],
+ size_t __needle_len)
+{
+ register unsigned long int __d0, __d1, __d2;
+ register char *__res;
+ __asm__ __volatile__
+ ("cld\n" \
+ "1:\n\t"
+ "movl %6,%%edi\n\t"
+ "movl %5,%%eax\n\t"
+ "movl %4,%%ecx\n\t"
+ "repe; cmpsb\n\t"
+ "je 2f\n\t"
+ "cmpb $0,-1(%%esi)\n\t"
+ "leal 1(%%eax),%5\n\t"
+ "jne 1b\n\t"
+ "xorl %%eax,%%eax\n"
+ "2:"
+ : "=&a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
+ : "g" (__needle_len), "1" (__haystack), "d" (__needle)
+ : "memory", "cc");
+ return __res;
+}
+
+__STRING_INLINE char *__strstr_g (__const char *__haystack, __const char *__needle);
+#ifdef __PIC__
+
+__STRING_INLINE char *
+__strstr_g (__const char *__haystack, __const char *__needle)
+{
+ register unsigned long int __d0, __d1, __d2;
+ register char *__res;
+ __asm__ __volatile__
+ ("cld\n\t"
+ "repne; scasb\n\t"
+ "notl %%ecx\n\t"
+ "pushl %%ebx\n\t"
+ "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
+ "movl %%ecx,%%ebx\n"
+ "1:\n\t"
+ "movl %%edx,%%edi\n\t"
+ "movl %%esi,%%eax\n\t"
+ "movl %%ebx,%%ecx\n\t"
+ "repe; cmpsb\n\t"
+ "je 2f\n\t" /* also works for empty string, see above */
+ "cmpb $0,-1(%%esi)\n\t"
+ "leal 1(%%eax),%%esi\n\t"
+ "jne 1b\n\t"
+ "xorl %%eax,%%eax\n"
+ "2:\n\t"
+ "popl %%ebx"
+ : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
+ : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
+ "d" (__needle)
+ : "memory", "cc");
+ return __res;
+}
+#else
+__STRING_INLINE char *
+__strstr_g (__const char *__haystack, __const char *__needle)
+{
+ register unsigned long int __d0, __d1, __d2, __d3;
+ register char *__res;
+ __asm__ __volatile__
+ ("cld\n\t"
+ "repne; scasb\n\t"
+ "notl %%ecx\n\t"
+ "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
+ "movl %%ecx,%%edx\n"
+ "1:\n\t"
+ "movl %%ebx,%%edi\n\t"
+ "movl %%esi,%%eax\n\t"
+ "movl %%edx,%%ecx\n\t"
+ "repe; cmpsb\n\t"
+ "je 2f\n\t" /* also works for empty string, see above */
+ "cmpb $0,-1(%%esi)\n\t"
+ "leal 1(%%eax),%%esi\n\t"
+ "jne 1b\n\t"
+ "xorl %%eax,%%eax\n"
+ "2:"
+ : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=&d" (__d3)
+ : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
+ "b" (__needle)
+ : "memory", "cc");
+ return __res;
+}
+#endif
+
+
+/* Bit find functions. We define only the i686 version since for the other
+ processors gcc generates good code. */
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+# ifdef __i686__
+# define _HAVE_STRING_ARCH_ffs 1
+# define ffs(word) (__builtin_constant_p (word) \
+ ? __builtin_ffs (word) \
+ : ({ int __cnt, __tmp; \
+ __asm__ __volatile__ \
+ ("bsfl %2,%0\n\t" \
+ "cmovel %1,%0" \
+ : "=&r" (__cnt), "=r" (__tmp) \
+ : "rm" (word), "1" (-1)); \
+ __cnt + 1; }))
+
+# ifndef ffsl
+# define ffsl(word) ffs(word)
+# endif
+# endif /* i686 */
+#endif /* BSD || X/Open */
+
+#ifndef _FORCE_INLINES
+# undef __STRING_INLINE
+#endif
+
+#endif /* use string inlines && GNU CC */
diff --git a/libc/sysdeps/i386/i486/htonl.S b/libc/sysdeps/i386/i486/htonl.S
new file mode 100644
index 000000000..d67f892f1
--- /dev/null
+++ b/libc/sysdeps/i386/i486/htonl.S
@@ -0,0 +1,35 @@
+/* Change byte order in word. For Intel 80x86, x >= 4.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+/*
+ INPUT PARAMETERS:
+ word (sp + 4)
+*/
+
+ .text
+ENTRY (htonl)
+ movl 4(%esp), %eax
+ bswap %eax
+ ret
+END (htonl)
+
+weak_alias (htonl, ntohl)
diff --git a/libc/sysdeps/i386/i486/strcat.S b/libc/sysdeps/i386/i486/strcat.S
new file mode 100644
index 000000000..ec7d4c80b
--- /dev/null
+++ b/libc/sysdeps/i386/i486/strcat.S
@@ -0,0 +1,274 @@
+/* strcat(dest, src) -- Append SRC on the end of DEST.
+ For Intel 80x86, x>=4.
+ Copyright (C) 1994-1997,2000,2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>.
+ Optimised a little by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+4 /* space for 1 saved reg */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#define SRC DEST+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (strcat))
+ ENTER
+
+ pushl %edi /* Save callee-safe register. */
+ cfi_adjust_cfa_offset (4)
+
+ movl DEST(%esp), %edx
+ movl SRC(%esp), %ecx
+ CHECK_BOUNDS_LOW (%edx, DEST(%esp))
+ CHECK_BOUNDS_LOW (%ecx, SRC(%esp))
+
+ testb $0xff, (%ecx) /* Is source string empty? */
+ jz L(8) /* yes => return */
+
+ /* Test the first bytes separately until destination is aligned. */
+ testl $3, %edx /* destination pointer aligned? */
+ jz L(1) /* yes => begin scan loop */
+ testb $0xff, (%edx) /* is end of string? */
+ jz L(2) /* yes => start appending */
+ incl %edx /* increment source pointer */
+
+ testl $3, %edx /* destination pointer aligned? */
+ jz L(1) /* yes => begin scan loop */
+ testb $0xff, (%edx) /* is end of string? */
+ jz L(2) /* yes => start appending */
+ incl %edx /* increment source pointer */
+
+ testl $3, %edx /* destination pointer aligned? */
+ jz L(1) /* yes => begin scan loop */
+ testb $0xff, (%edx) /* is end of string? */
+ jz L(2) /* yes => start appending */
+ incl %edx /* increment source pointer */
+
+ /* Now we are aligned. Begin scan loop. */
+ jmp L(1)
+
+ cfi_rel_offset (edi, 0)
+ ALIGN(4)
+
+L(4): addl $16,%edx /* increment destination pointer for round */
+
+L(1): movl (%edx), %eax /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+
+ /* If you compare this with the algorithm in memchr.S you will
+ notice that here is an `xorl' statement missing. But you must
+ not forget that we are looking for C == 0 and `xorl $0, %eax'
+ is a no-op. */
+
+ addl %eax, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+
+ /* According to the algorithm we had to reverse the effect of the
+ XOR first and then test the overflow bits. But because the
+ following XOR would destroy the carry flag and it would (in a
+ representation with more than 32 bits) not alter then last
+ overflow, we can now test this condition. If no carry is signaled
+ no overflow must have occurred in the last byte => it was 0. */
+ jnc L(3)
+
+ /* We are only interested in carry bits that change due to the
+ previous add, so remove original bits */
+ xorl %eax, %edi /* ((word^charmask)+magic)^(word^charmask) */
+
+ /* Now test for the other three overflow bits. */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ /* If at least one byte of the word is C we don't get 0 in %ecx. */
+ jnz L(3)
+
+ movl 4(%edx), %eax /* get word from source */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %eax, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(5) /* highest byte is C => stop copying */
+ xorl %eax, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(5) /* one byte is NUL => stop copying */
+
+ movl 8(%edx), %eax /* get word from source */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %eax, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(6) /* highest byte is C => stop copying */
+ xorl %eax, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(6) /* one byte is NUL => stop copying */
+
+ movl 12(%edx), %eax /* get word from source */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %eax, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(7) /* highest byte is C => stop copying */
+ xorl %eax, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jz L(4) /* no byte is NUL => carry on copying */
+
+L(7): addl $4, %edx /* adjust source pointer */
+L(6): addl $4, %edx
+L(5): addl $4, %edx
+
+L(3): testb %al, %al /* is first byte NUL? */
+ jz L(2) /* yes => start copying */
+ incl %edx /* increment source pointer */
+
+ testb %ah, %ah /* is second byte NUL? */
+ jz L(2) /* yes => start copying */
+ incl %edx /* increment source pointer */
+
+ testl $0xff0000, %eax /* is third byte NUL? */
+ jz L(2) /* yes => start copying */
+ incl %edx /* increment source pointer */
+
+L(2): subl %ecx, %edx /* reduce number of loop variants */
+
+ /* Now we have to align the source pointer. */
+ testl $3, %ecx /* pointer correctly aligned? */
+ jz L(29) /* yes => start copy loop */
+ movb (%ecx), %al /* get first byte */
+ movb %al, (%ecx,%edx) /* and store it */
+ andb %al, %al /* is byte NUL? */
+ jz L(8) /* yes => return */
+ incl %ecx /* increment pointer */
+
+ testl $3, %ecx /* pointer correctly aligned? */
+ jz L(29) /* yes => start copy loop */
+ movb (%ecx), %al /* get first byte */
+ movb %al, (%ecx,%edx) /* and store it */
+ andb %al, %al /* is byte NUL? */
+ jz L(8) /* yes => return */
+ incl %ecx /* increment pointer */
+
+ testl $3, %ecx /* pointer correctly aligned? */
+ jz L(29) /* yes => start copy loop */
+ movb (%ecx), %al /* get first byte */
+ movb %al, (%ecx,%edx) /* and store it */
+ andb %al, %al /* is byte NUL? */
+ jz L(8) /* yes => return */
+ incl %ecx /* increment pointer */
+
+ /* Now we are aligned. */
+ jmp L(29) /* start copy loop */
+
+ ALIGN(4)
+
+L(28): movl %eax, 12(%ecx,%edx)/* store word at destination */
+ addl $16, %ecx /* adjust pointer for full round */
+
+L(29): movl (%ecx), %eax /* get word from source */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %eax, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(9) /* highest byte is C => stop copying */
+ xorl %eax, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(9) /* one byte is NUL => stop copying */
+ movl %eax, (%ecx,%edx) /* store word to destination */
+
+ movl 4(%ecx), %eax /* get word from source */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %eax, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(91) /* highest byte is C => stop copying */
+ xorl %eax, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(91) /* one byte is NUL => stop copying */
+ movl %eax, 4(%ecx,%edx) /* store word to destination */
+
+ movl 8(%ecx), %eax /* get word from source */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %eax, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(92) /* highest byte is C => stop copying */
+ xorl %eax, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(92) /* one byte is NUL => stop copying */
+ movl %eax, 8(%ecx,%edx) /* store word to destination */
+
+ movl 12(%ecx), %eax /* get word from source */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %eax, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(93) /* highest byte is C => stop copying */
+ xorl %eax, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jz L(28) /* no is NUL => carry on copying */
+
+L(93): addl $4, %ecx /* adjust pointer */
+L(92): addl $4, %ecx
+L(91): addl $4, %ecx
+
+L(9): movb %al, (%ecx,%edx) /* store first byte of last word */
+ orb %al, %al /* is it NUL? */
+ jz L(8) /* yes => return */
+
+ movb %ah, 1(%ecx,%edx) /* store second byte of last word */
+ orb %ah, %ah /* is it NUL? */
+ jz L(8) /* yes => return */
+
+ shrl $16, %eax /* make upper bytes accessible */
+ movb %al, 2(%ecx,%edx) /* store third byte of last word */
+ orb %al, %al /* is it NUL? */
+ jz L(8) /* yes => return */
+
+ movb %ah, 3(%ecx,%edx) /* store fourth byte of last word */
+
+L(8): /* GKM FIXME: check high bounds */
+ movl DEST(%esp), %eax /* start address of destination is result */
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+ popl %edi /* restore saved register */
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (strcat))
+libc_hidden_builtin_def (strcat)
diff --git a/libc/sysdeps/i386/i486/string-inlines.c b/libc/sysdeps/i386/i486/string-inlines.c
new file mode 100644
index 000000000..7136d2c60
--- /dev/null
+++ b/libc/sysdeps/i386/i486/string-inlines.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* <bits/string.h> and <bits/string2.h> declare some extern inline
+ functions. These functions are declared additionally here if
+ inlining is not possible. */
+
+#undef __USE_STRING_INLINES
+#define __USE_STRING_INLINES
+#define _FORCE_INLINES
+#define __STRING_INLINE /* empty */
+#define __NO_INLINE__
+
+/* This is to avoid PLT entries for the x86 version. */
+#define __memcpy_g __memcpy_g_internal
+#define __strchr_g __strchr_g_internal
+
+#include <string.h>
+#undef index
+#undef rindex
+
+#undef __NO_INLINE__
+#include <bits/string.h>
+#include <bits/string2.h>
+
+void *
+(__memcpy_c) (void *d, const void *s, size_t n)
+{
+ return memcpy (d, s, n);
+}
+
+void *
+__memset_cc (void *s, unsigned long int pattern, size_t n)
+{
+ return memset (s, pattern & 0xff, n);
+}
+strong_alias (__memset_cc, __memset_cg)
+
+void *
+__memset_gg (void *s, char c, size_t n)
+{
+ return memset (s, c, n);
+}
+
+#ifdef __memcpy_c
+# undef __memcpy_g
+strong_alias (__memcpy_g_internal, __memcpy_g)
+# undef __strchr_g
+strong_alias (__strchr_g_internal, __strchr_g)
+#endif
diff --git a/libc/sysdeps/i386/i486/strlen.S b/libc/sysdeps/i386/i486/strlen.S
new file mode 100644
index 000000000..7557b2d21
--- /dev/null
+++ b/libc/sysdeps/i386/i486/strlen.S
@@ -0,0 +1,139 @@
+/* strlen(str) -- determine the length of the string STR.
+ Optimized for Intel 80x86, x>=4.
+ Copyright (C) 1991-1997, 2000, 2003 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define STR PARMS
+
+ .text
+ENTRY (BP_SYM (strlen))
+ ENTER
+
+ movl STR(%esp), %ecx
+ CHECK_BOUNDS_LOW (%ecx, STR(%esp))
+ movl %ecx, %eax /* duplicate it */
+
+ andl $3, %ecx /* mask alignment bits */
+ jz L(1) /* aligned => start loop */
+ cmpb %ch, (%eax) /* is byte NUL? */
+ je L(2) /* yes => return */
+ incl %eax /* increment pointer */
+
+ xorl $3, %ecx /* was alignment = 3? */
+ jz L(1) /* yes => now it is aligned and start loop */
+ cmpb %ch, (%eax) /* is byte NUL? */
+ je L(2) /* yes => return */
+ addl $1, %eax /* increment pointer */
+
+ subl $1, %ecx /* was alignment = 2? */
+ jz L(1) /* yes => now it is aligned and start loop */
+ cmpb %ch, (%eax) /* is byte NUL? */
+ je L(2) /* yes => return */
+
+/* Don't change the above `addl $1,%eax' and `subl $1, %ecx' into `incl %eax'
+ and `decl %ecx' resp. The additional two byte per instruction make the
+ label 4 to be aligned on a 16 byte boundary with nops.
+
+ The following `sub $15, %eax' is part of this trick, too. Together with
+ the next instruction (`addl $16, %eax') it is in fact a `incl %eax', just
+ as expected from the algorithm. But doing so has the advantage that
+ no jump to label 1 is necessary and so the pipeline is not flushed. */
+
+ subl $15, %eax /* effectively +1 */
+
+
+L(4): addl $16, %eax /* adjust pointer for full loop */
+
+L(1): movl (%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edx /* magic value */
+ addl %ecx, %edx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(3) /* highest byte is NUL => return pointer */
+ xorl %ecx, %edx /* (word+magic)^word */
+ orl $0xfefefeff, %edx /* set all non-carry bits */
+ incl %edx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(3) /* found NUL => return pointer */
+
+ movl 4(%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edx /* magic value */
+ addl %ecx, %edx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(5) /* highest byte is NUL => return pointer */
+ xorl %ecx, %edx /* (word+magic)^word */
+ orl $0xfefefeff, %edx /* set all non-carry bits */
+ incl %edx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(5) /* found NUL => return pointer */
+
+ movl 8(%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edx /* magic value */
+ addl %ecx, %edx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(6) /* highest byte is NUL => return pointer */
+ xorl %ecx, %edx /* (word+magic)^word */
+ orl $0xfefefeff, %edx /* set all non-carry bits */
+ incl %edx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(6) /* found NUL => return pointer */
+
+ movl 12(%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edx /* magic value */
+ addl %ecx, %edx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(7) /* highest byte is NUL => return pointer */
+ xorl %ecx, %edx /* (word+magic)^word */
+ orl $0xfefefeff, %edx /* set all non-carry bits */
+ incl %edx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jz L(4) /* no NUL found => continue loop */
+
+L(7): addl $4, %eax /* adjust pointer */
+L(6): addl $4, %eax
+L(5): addl $4, %eax
+
+L(3): testb %cl, %cl /* is first byte NUL? */
+ jz L(2) /* yes => return */
+ incl %eax /* increment pointer */
+
+ testb %ch, %ch /* is second byte NUL? */
+ jz L(2) /* yes => return */
+ incl %eax /* increment pointer */
+
+ testl $0xff0000, %ecx /* is third byte NUL? */
+ jz L(2) /* yes => return pointer */
+ incl %eax /* increment pointer */
+
+L(2): CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
+ subl STR(%esp), %eax /* compute difference to string start */
+
+ LEAVE
+ ret
+END (BP_SYM (strlen))
+libc_hidden_builtin_def (strlen)
diff --git a/libc/sysdeps/i386/i586/Implies b/libc/sysdeps/i386/i586/Implies
new file mode 100644
index 000000000..477cd741c
--- /dev/null
+++ b/libc/sysdeps/i386/i586/Implies
@@ -0,0 +1,2 @@
+# Code optimized for i486 is better than simple i386 code.
+i386/i486
diff --git a/libc/sysdeps/i386/i586/add_n.S b/libc/sysdeps/i386/i586/add_n.S
new file mode 100644
index 000000000..57706b23b
--- /dev/null
+++ b/libc/sysdeps/i386/i586/add_n.S
@@ -0,0 +1,155 @@
+/* Pentium __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+ sum in a third limb vector.
+ Copyright (C) 1992,94,95,96,97,98,2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+16 /* space for 4 saved regs */
+#define RES PARMS
+#define S1 RES+PTR_SIZE
+#define S2 S1+PTR_SIZE
+#define SIZE S2+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__mpn_add_n))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp),%edi
+ cfi_rel_offset (edi, 12)
+ movl S1(%esp),%esi
+ cfi_rel_offset (esi, 8)
+ movl S2(%esp),%ebx
+ cfi_rel_offset (ebx, 0)
+ movl SIZE(%esp),%ecx
+#if __BOUNDED_POINTERS__
+ shll $2, %ecx /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, S1(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%ebx, S2(%esp), %ecx)
+ shrl $2, %ecx
+#endif
+ movl (%ebx),%ebp
+ cfi_rel_offset (ebp, 4)
+
+ decl %ecx
+ movl %ecx,%edx
+ shrl $3,%ecx
+ andl $7,%edx
+ testl %ecx,%ecx /* zero carry flag */
+ jz L(end)
+ pushl %edx
+ cfi_adjust_cfa_offset (4)
+
+ ALIGN (3)
+L(oop): movl 28(%edi),%eax /* fetch destination cache line */
+ leal 32(%edi),%edi
+
+L(1): movl (%esi),%eax
+ movl 4(%esi),%edx
+ adcl %ebp,%eax
+ movl 4(%ebx),%ebp
+ adcl %ebp,%edx
+ movl 8(%ebx),%ebp
+ movl %eax,-32(%edi)
+ movl %edx,-28(%edi)
+
+L(2): movl 8(%esi),%eax
+ movl 12(%esi),%edx
+ adcl %ebp,%eax
+ movl 12(%ebx),%ebp
+ adcl %ebp,%edx
+ movl 16(%ebx),%ebp
+ movl %eax,-24(%edi)
+ movl %edx,-20(%edi)
+
+L(3): movl 16(%esi),%eax
+ movl 20(%esi),%edx
+ adcl %ebp,%eax
+ movl 20(%ebx),%ebp
+ adcl %ebp,%edx
+ movl 24(%ebx),%ebp
+ movl %eax,-16(%edi)
+ movl %edx,-12(%edi)
+
+L(4): movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ adcl %ebp,%eax
+ movl 28(%ebx),%ebp
+ adcl %ebp,%edx
+ movl 32(%ebx),%ebp
+ movl %eax,-8(%edi)
+ movl %edx,-4(%edi)
+
+ leal 32(%esi),%esi
+ leal 32(%ebx),%ebx
+ decl %ecx
+ jnz L(oop)
+
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+L(end):
+ decl %edx /* test %edx w/o clobbering carry */
+ js L(end2)
+ incl %edx
+L(oop2):
+ leal 4(%edi),%edi
+ movl (%esi),%eax
+ adcl %ebp,%eax
+ movl 4(%ebx),%ebp
+ movl %eax,-4(%edi)
+ leal 4(%esi),%esi
+ leal 4(%ebx),%ebx
+ decl %edx
+ jnz L(oop2)
+L(end2):
+ movl (%esi),%eax
+ adcl %ebp,%eax
+ movl %eax,(%edi)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+END (BP_SYM (__mpn_add_n))
diff --git a/libc/sysdeps/i386/i586/addmul_1.S b/libc/sysdeps/i386/i586/addmul_1.S
new file mode 100644
index 000000000..1890c5dfa
--- /dev/null
+++ b/libc/sysdeps/i386/i586/addmul_1.S
@@ -0,0 +1,105 @@
+/* Pentium __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ the result to a second limb vector.
+ Copyright (C) 1992, 94, 96, 97, 98, 00, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+16 /* space for 4 saved regs */
+#define RES PARMS
+#define S1 RES+PTR_SIZE
+#define SIZE S1+PTR_SIZE
+#define S2LIMB SIZE+4
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebx
+
+ .text
+ENTRY (BP_SYM (__mpn_addmul_1))
+ ENTER
+
+ pushl %res_ptr
+ cfi_adjust_cfa_offset (4)
+ pushl %s1_ptr
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %s2_limb
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp), %res_ptr
+ cfi_rel_offset (res_ptr, 12)
+ movl S1(%esp), %s1_ptr
+ cfi_rel_offset (s1_ptr, 8)
+ movl SIZE(%esp), %size
+ movl S2LIMB(%esp), %s2_limb
+ cfi_rel_offset (s2_limb, 0)
+#if __BOUNDED_POINTERS__
+ shll $2, %size /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%res_ptr, RES(%esp), %size)
+ CHECK_BOUNDS_BOTH_WIDE (%s1_ptr, S1(%esp), %size)
+ shrl $2, %size
+#endif
+ leal (%res_ptr,%size,4), %res_ptr
+ leal (%s1_ptr,%size,4), %s1_ptr
+ negl %size
+ xorl %ebp, %ebp
+ cfi_rel_offset (ebp, 4)
+ ALIGN (3)
+
+L(oop): adcl $0, %ebp
+ movl (%s1_ptr,%size,4), %eax
+
+ mull %s2_limb
+
+ addl %ebp, %eax
+ movl (%res_ptr,%size,4), %ebp
+
+ adcl $0, %edx
+ addl %eax, %ebp
+
+ movl %ebp, (%res_ptr,%size,4)
+ incl %size
+
+ movl %edx, %ebp
+ jnz L(oop)
+
+ adcl $0, %ebp
+ movl %ebp, %eax
+ popl %s2_limb
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (s2_limb)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %s1_ptr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (s1_ptr)
+ popl %res_ptr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (res_ptr)
+
+ LEAVE
+ ret
+#undef size
+END (BP_SYM (__mpn_addmul_1))
diff --git a/libc/sysdeps/i386/i586/bzero.S b/libc/sysdeps/i386/i586/bzero.S
new file mode 100644
index 000000000..220aa47c3
--- /dev/null
+++ b/libc/sysdeps/i386/i586/bzero.S
@@ -0,0 +1,3 @@
+#define memset __bzero
+#include <sysdeps/i386/i586/memset.S>
+weak_alias (BP_SYM (__bzero), BP_SYM (bzero))
diff --git a/libc/sysdeps/i386/i586/lshift.S b/libc/sysdeps/i386/i586/lshift.S
new file mode 100644
index 000000000..bc73ee6f3
--- /dev/null
+++ b/libc/sysdeps/i386/i586/lshift.S
@@ -0,0 +1,267 @@
+/* Pentium optimized __mpn_lshift --
+ Copyright (C) 1992,94,95,96,97,98,2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+16 /* space for 4 saved regs */
+#define RES PARMS
+#define S RES+PTR_SIZE
+#define SIZE S+PTR_SIZE
+#define CNT SIZE+4
+
+ .text
+ENTRY (BP_SYM (__mpn_lshift))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebp, 0)
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp),%edi
+ cfi_rel_offset (edi, 12)
+ movl S(%esp),%esi
+ cfi_rel_offset (esi, 8)
+ movl SIZE(%esp),%ebx
+ cfi_rel_offset (ebx, 0)
+ movl CNT(%esp),%ecx
+#if __BOUNDED_POINTERS__
+ shll $2, %ebx /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ebx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, S(%esp), %ebx)
+ shrl $2, %ebx
+#endif
+
+/* We can use faster code for shift-by-1 under certain conditions. */
+ cmp $1,%ecx
+ jne L(normal)
+ leal 4(%esi),%eax
+ cmpl %edi,%eax
+ jnc L(special) /* jump if s_ptr + 1 >= res_ptr */
+ leal (%esi,%ebx,4),%eax
+ cmpl %eax,%edi
+ jnc L(special) /* jump if res_ptr >= s_ptr + size */
+
+L(normal):
+ leal -4(%edi,%ebx,4),%edi
+ leal -4(%esi,%ebx,4),%esi
+
+ movl (%esi),%edx
+ subl $4,%esi
+ xorl %eax,%eax
+ shldl %cl,%edx,%eax /* compute carry limb */
+ pushl %eax /* push carry limb onto stack */
+ cfi_adjust_cfa_offset (4)
+
+ decl %ebx
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ shrl $3,%ebx
+ jz L(end)
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+L(oop): movl -28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebp
+
+ movl (%esi),%eax
+ movl -4(%esi),%edx
+ shldl %cl,%eax,%ebp
+ shldl %cl,%edx,%eax
+ movl %ebp,(%edi)
+ movl %eax,-4(%edi)
+
+ movl -8(%esi),%ebp
+ movl -12(%esi),%eax
+ shldl %cl,%ebp,%edx
+ shldl %cl,%eax,%ebp
+ movl %edx,-8(%edi)
+ movl %ebp,-12(%edi)
+
+ movl -16(%esi),%edx
+ movl -20(%esi),%ebp
+ shldl %cl,%edx,%eax
+ shldl %cl,%ebp,%edx
+ movl %eax,-16(%edi)
+ movl %edx,-20(%edi)
+
+ movl -24(%esi),%eax
+ movl -28(%esi),%edx
+ shldl %cl,%eax,%ebp
+ shldl %cl,%edx,%eax
+ movl %ebp,-24(%edi)
+ movl %eax,-28(%edi)
+
+ subl $32,%esi
+ subl $32,%edi
+ decl %ebx
+ jnz L(oop)
+
+L(end): popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ andl $7,%ebx
+ jz L(end2)
+L(oop2):
+ movl (%esi),%eax
+ shldl %cl,%eax,%edx
+ movl %edx,(%edi)
+ movl %eax,%edx
+ subl $4,%esi
+ subl $4,%edi
+ decl %ebx
+ jnz L(oop2)
+
+L(end2):
+ shll %cl,%edx /* compute least significant limb */
+ movl %edx,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+ cfi_adjust_cfa_offset (-4)
+
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+
+/* We loop from least significant end of the arrays, which is only
+ permissible if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination.
+*/
+
+ cfi_adjust_cfa_offset (16)
+ cfi_rel_offset (edi, 12)
+ cfi_rel_offset (esi, 8)
+ cfi_rel_offset (ebp, 4)
+ cfi_rel_offset (ebx, 0)
+L(special):
+ movl (%esi),%edx
+ addl $4,%esi
+
+ decl %ebx
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ shrl $3,%ebx
+
+ addl %edx,%edx
+ incl %ebx
+ decl %ebx
+ jz L(Lend)
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+L(Loop):
+ movl 28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebp
+
+ movl (%esi),%eax
+ movl 4(%esi),%edx
+ adcl %eax,%eax
+ movl %ebp,(%edi)
+ adcl %edx,%edx
+ movl %eax,4(%edi)
+
+ movl 8(%esi),%ebp
+ movl 12(%esi),%eax
+ adcl %ebp,%ebp
+ movl %edx,8(%edi)
+ adcl %eax,%eax
+ movl %ebp,12(%edi)
+
+ movl 16(%esi),%edx
+ movl 20(%esi),%ebp
+ adcl %edx,%edx
+ movl %eax,16(%edi)
+ adcl %ebp,%ebp
+ movl %edx,20(%edi)
+
+ movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ adcl %eax,%eax
+ movl %ebp,24(%edi)
+ adcl %edx,%edx
+ movl %eax,28(%edi)
+
+ leal 32(%esi),%esi /* use leal not to clobber carry */
+ leal 32(%edi),%edi
+ decl %ebx
+ jnz L(Loop)
+
+L(Lend):
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ sbbl %eax,%eax /* save carry in %eax */
+ andl $7,%ebx
+ jz L(Lend2)
+ addl %eax,%eax /* restore carry from eax */
+L(Loop2):
+ movl %edx,%ebp
+ movl (%esi),%edx
+ adcl %edx,%edx
+ movl %ebp,(%edi)
+
+ leal 4(%esi),%esi /* use leal not to clobber carry */
+ leal 4(%edi),%edi
+ decl %ebx
+ jnz L(Loop2)
+
+ jmp L(L1)
+L(Lend2):
+ addl %eax,%eax /* restore carry from eax */
+L(L1): movl %edx,(%edi) /* store last limb */
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+END (BP_SYM (__mpn_lshift))
diff --git a/libc/sysdeps/i386/i586/memcopy.h b/libc/sysdeps/i386/i586/memcopy.h
new file mode 100644
index 000000000..d300d7c96
--- /dev/null
+++ b/libc/sysdeps/i386/i586/memcopy.h
@@ -0,0 +1,96 @@
+/* memcopy.h -- definitions for memory copy functions. Pentium version.
+ Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Get the i386 definitions. We will override some of them below. */
+#include <sysdeps/i386/memcopy.h>
+
+/* Written like this, the Pentium pipeline can execute the loop at a
+ sustained rate of 2 instructions/clock, or asymptotically 480
+ Mbytes/second at 60Mhz. */
+
+#undef WORD_COPY_FWD
+#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \
+ do \
+ { \
+ asm volatile ("subl $32,%2\n" \
+ "js 2f\n" \
+ "movl 0(%0),%%edx\n" /* alloc dest line */ \
+ "1:\n" \
+ "movl 28(%0),%%eax\n" /* alloc dest line */ \
+ "subl $32,%2\n" /* decr loop count */ \
+ "movl 0(%1),%%eax\n" /* U pipe */ \
+ "movl 4(%1),%%edx\n" /* V pipe */ \
+ "movl %%eax,0(%0)\n" /* U pipe */ \
+ "movl %%edx,4(%0)\n" /* V pipe */ \
+ "movl 8(%1),%%eax\n" \
+ "movl 12(%1),%%edx\n" \
+ "movl %%eax,8(%0)\n" \
+ "movl %%edx,12(%0)\n" \
+ "movl 16(%1),%%eax\n" \
+ "movl 20(%1),%%edx\n" \
+ "movl %%eax,16(%0)\n" \
+ "movl %%edx,20(%0)\n" \
+ "movl 24(%1),%%eax\n" \
+ "movl 28(%1),%%edx\n" \
+ "movl %%eax,24(%0)\n" \
+ "movl %%edx,28(%0)\n" \
+ "leal 32(%1),%1\n" /* update src ptr */ \
+ "leal 32(%0),%0\n" /* update dst ptr */ \
+ "jns 1b\n" \
+ "2: addl $32,%2" : \
+ "=r" (dst_bp), "=r" (src_bp), "=r" (nbytes_left) : \
+ "0" (dst_bp), "1" (src_bp), "2" (nbytes) : \
+ "ax", "dx"); \
+ } while (0)
+
+#undef WORD_COPY_BWD
+#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes) \
+ do \
+ { \
+ asm volatile ("subl $32,%2\n" \
+ "js 2f\n" \
+ "movl -4(%0),%%edx\n" \
+ "1:\n" \
+ "movl -32(%0),%%eax\n" \
+ "subl $32,%2\n" \
+ "movl -4(%1),%%eax\n" \
+ "movl -8(%1),%%edx\n" \
+ "movl %%eax,-4(%0)\n" \
+ "movl %%edx,-8(%0)\n" \
+ "movl -12(%1),%%eax\n" \
+ "movl -16(%1),%%edx\n" \
+ "movl %%eax,-12(%0)\n" \
+ "movl %%edx,-16(%0)\n" \
+ "movl -20(%1),%%eax\n" \
+ "movl -24(%1),%%edx\n" \
+ "movl %%eax,-20(%0)\n" \
+ "movl %%edx,-24(%0)\n" \
+ "movl -28(%1),%%eax\n" \
+ "movl -32(%1),%%edx\n" \
+ "movl %%eax,-28(%0)\n" \
+ "movl %%edx,-32(%0)\n" \
+ "leal -32(%1),%1\n" \
+ "leal -32(%0),%0\n" \
+ "jns 1b\n" \
+ "2: addl $32,%2" : \
+ "=r" (dst_ep), "=r" (src_ep), "=r" (nbytes_left) : \
+ "0" (dst_ep), "1" (src_ep), "2" (nbytes) : \
+ "ax", "dx"); \
+ } while (0)
diff --git a/libc/sysdeps/i386/i586/memcpy.S b/libc/sysdeps/i386/i586/memcpy.S
new file mode 100644
index 000000000..6ab457fc5
--- /dev/null
+++ b/libc/sysdeps/i386/i586/memcpy.S
@@ -0,0 +1,129 @@
+/* Highly optimized version for i586.
+ Copyright (C) 1997, 2000, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+/* BEWARE: `#ifdef memcpy' means that memcpy is redefined as `mempcpy',
+ and the return value is the byte after the last one copied in
+ the destination. */
+#define MEMPCPY_P (defined memcpy)
+
+#define PARMS LINKAGE+8 /* space for 2 saved regs */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#define SRC DEST+PTR_SIZE
+#define LEN SRC+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (memcpy))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+
+ movl DEST(%esp), %edi
+ cfi_rel_offset (edi, 4)
+ movl SRC(%esp), %esi
+ cfi_rel_offset (esi, 0)
+ movl LEN(%esp), %ecx
+ CHECK_BOUNDS_BOTH_WIDE (%edi, DEST(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, SRC(%esp), %ecx)
+ movl %edi, %eax
+
+ /* We need this in any case. */
+ cld
+
+ /* Cutoff for the big loop is a size of 32 bytes since otherwise
+ the loop will never be entered. */
+ cmpl $32, %ecx
+ jbe L(1)
+
+ negl %eax
+ andl $3, %eax
+ subl %eax, %ecx
+ xchgl %eax, %ecx
+
+ rep; movsb
+
+ movl %eax, %ecx
+ subl $32, %ecx
+ js L(2)
+
+ /* Read ahead to make sure we write in the cache since the stupid
+ i586 designers haven't implemented read-on-write-miss. */
+ movl (%edi), %eax
+L(3): movl 28(%edi), %edx
+
+ /* Now correct the loop counter. Please note that in the following
+ code the flags are not changed anymore. */
+ subl $32, %ecx
+
+ movl (%esi), %eax
+ movl 4(%esi), %edx
+ movl %eax, (%edi)
+ movl %edx, 4(%edi)
+ movl 8(%esi), %eax
+ movl 12(%esi), %edx
+ movl %eax, 8(%edi)
+ movl %edx, 12(%edi)
+ movl 16(%esi), %eax
+ movl 20(%esi), %edx
+ movl %eax, 16(%edi)
+ movl %edx, 20(%edi)
+ movl 24(%esi), %eax
+ movl 28(%esi), %edx
+ movl %eax, 24(%edi)
+ movl %edx, 28(%edi)
+
+ leal 32(%esi), %esi
+ leal 32(%edi), %edi
+
+ jns L(3)
+
+ /* Correct extra loop counter modification. */
+L(2): addl $32, %ecx
+#if !MEMPCPY_P
+ movl DEST(%esp), %eax
+#endif
+
+L(1): rep; movsb
+
+#if MEMPCPY_P
+ movl %edi, %eax
+#endif
+
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (memcpy))
+#if !MEMPCPY_P
+libc_hidden_builtin_def (memcpy)
+#endif
diff --git a/libc/sysdeps/i386/i586/mempcpy.S b/libc/sysdeps/i386/i586/mempcpy.S
new file mode 100644
index 000000000..0c9520e3b
--- /dev/null
+++ b/libc/sysdeps/i386/i586/mempcpy.S
@@ -0,0 +1,6 @@
+#define memcpy __mempcpy
+#include <sysdeps/i386/i586/memcpy.S>
+
+libc_hidden_def (BP_SYM (__mempcpy))
+weak_alias (BP_SYM (__mempcpy), BP_SYM (mempcpy))
+libc_hidden_builtin_def (mempcpy)
diff --git a/libc/sysdeps/i386/i586/memset.S b/libc/sysdeps/i386/i586/memset.S
new file mode 100644
index 000000000..c21e9f7a7
--- /dev/null
+++ b/libc/sysdeps/i386/i586/memset.S
@@ -0,0 +1,121 @@
+/* memset/bzero -- set memory area to CH/0
+ Highly optimized version for ix86, x>=5.
+ Copyright (C) 1996, 1997, 2000, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Torbjorn Granlund, <tege@matematik.su.se>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+/* BEWARE: `#ifdef memset' means that memset is redefined as `bzero' */
+#define BZERO_P (defined memset)
+
+#define PARMS LINKAGE+4 /* space for 1 saved reg */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#if BZERO_P
+# define LEN DEST+PTR_SIZE
+#else
+# define CHR DEST+PTR_SIZE
+# define LEN CHR+4
+#endif
+
+ .text
+ENTRY (BP_SYM (memset))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+
+ movl DEST(%esp), %edi
+ cfi_rel_offset (edi, 0)
+ movl LEN(%esp), %edx
+ CHECK_BOUNDS_BOTH_WIDE (%edi, DEST(%esp), %edx)
+#if BZERO_P
+ xorl %eax, %eax /* we fill with 0 */
+#else
+ movb CHR(%esp), %al
+ movb %al, %ah
+ movl %eax, %ecx
+ shll $16, %eax
+ movw %cx, %ax
+#endif
+ cld
+
+/* If less than 36 bytes to write, skip tricky code (it wouldn't work). */
+ cmpl $36, %edx
+ movl %edx, %ecx /* needed when branch is taken! */
+ jl L(2)
+
+/* First write 0-3 bytes to make the pointer 32-bit aligned. */
+ movl %edi, %ecx /* Copy ptr to ecx... */
+ negl %ecx /* ...and negate that and... */
+ andl $3, %ecx /* ...mask to get byte count. */
+ subl %ecx, %edx /* adjust global byte count */
+ rep
+ stosb
+
+ subl $32, %edx /* offset count for unrolled loop */
+ movl (%edi), %ecx /* Fetch destination cache line */
+
+ .align 2, 0x90 /* supply 0x90 for broken assemblers */
+L(1): movl 28(%edi), %ecx /* allocate cache line for destination */
+ subl $32, %edx /* decr loop count */
+ movl %eax, 0(%edi) /* store words pairwise */
+ movl %eax, 4(%edi)
+ movl %eax, 8(%edi)
+ movl %eax, 12(%edi)
+ movl %eax, 16(%edi)
+ movl %eax, 20(%edi)
+ movl %eax, 24(%edi)
+ movl %eax, 28(%edi)
+ leal 32(%edi), %edi /* update destination pointer */
+ jge L(1)
+
+ leal 32(%edx), %ecx /* reset offset count */
+
+/* Write last 0-7 full 32-bit words (up to 8 words if loop was skipped). */
+L(2): shrl $2, %ecx /* convert byte count to longword count */
+ rep
+ stosl
+
+/* Finally write the last 0-3 bytes. */
+ movl %edx, %ecx
+ andl $3, %ecx
+ rep
+ stosb
+
+#if !BZERO_P
+ /* Load result (only if used as memset). */
+ movl DEST(%esp), %eax /* start address of destination is result */
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+#endif
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+#if BZERO_P
+ ret
+#else
+ RET_PTR
+#endif
+END (BP_SYM (memset))
+libc_hidden_builtin_def (memset)
diff --git a/libc/sysdeps/i386/i586/memusage.h b/libc/sysdeps/i386/i586/memusage.h
new file mode 100644
index 000000000..c8170874d
--- /dev/null
+++ b/libc/sysdeps/i386/i586/memusage.h
@@ -0,0 +1 @@
+#include "../i686/memusage.h"
diff --git a/libc/sysdeps/i386/i586/mul_1.S b/libc/sysdeps/i386/i586/mul_1.S
new file mode 100644
index 000000000..15765d758
--- /dev/null
+++ b/libc/sysdeps/i386/i586/mul_1.S
@@ -0,0 +1,101 @@
+/* Pentium __mpn_mul_1 -- Multiply a limb vector with a limb and store
+ the result in a second limb vector.
+ Copyright (C) 1992, 94, 96, 97, 98, 00, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+16 /* space for 4 saved regs */
+#define RES PARMS
+#define S1 RES+PTR_SIZE
+#define SIZE S1+PTR_SIZE
+#define S2LIMB SIZE+4
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebx
+
+ .text
+ENTRY (BP_SYM (__mpn_mul_1))
+ ENTER
+
+ pushl %res_ptr
+ cfi_adjust_cfa_offset (4)
+ pushl %s1_ptr
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %s2_limb
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp), %res_ptr
+ cfi_rel_offset (res_ptr, 12)
+ movl S1(%esp), %s1_ptr
+ cfi_rel_offset (s1_ptr, 8)
+ movl SIZE(%esp), %size
+ movl S2LIMB(%esp), %s2_limb
+ cfi_rel_offset (s2_limb, 0)
+#if __BOUNDED_POINTERS__
+ shll $2, %size /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%res_ptr, RES(%esp), %size)
+ CHECK_BOUNDS_BOTH_WIDE (%s1_ptr, S1(%esp), %size)
+ shrl $2, %size
+#endif
+ leal (%res_ptr,%size,4), %res_ptr
+ leal (%s1_ptr,%size,4), %s1_ptr
+ negl %size
+ xorl %ebp, %ebp
+ cfi_rel_offset (ebp, 4)
+ ALIGN (3)
+
+L(oop): adcl $0, %ebp
+ movl (%s1_ptr,%size,4), %eax
+
+ mull %s2_limb
+
+ addl %eax, %ebp
+
+ movl %ebp, (%res_ptr,%size,4)
+ incl %size
+
+ movl %edx, %ebp
+ jnz L(oop)
+
+ adcl $0, %ebp
+ movl %ebp, %eax
+ popl %s2_limb
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (s2_limb)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %s1_ptr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (s1_ptr)
+ popl %res_ptr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (res_ptr)
+
+ LEAVE
+ ret
+#undef size
+END (BP_SYM (__mpn_mul_1))
diff --git a/libc/sysdeps/i386/i586/rshift.S b/libc/sysdeps/i386/i586/rshift.S
new file mode 100644
index 000000000..7b88289d3
--- /dev/null
+++ b/libc/sysdeps/i386/i586/rshift.S
@@ -0,0 +1,267 @@
+/* Pentium optimized __mpn_rshift --
+ Copyright (C) 1992,94,95,96,97,98,2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+16 /* space for 4 saved regs */
+#define RES PARMS
+#define S RES+PTR_SIZE
+#define SIZE S+PTR_SIZE
+#define CNT SIZE+4
+
+ .text
+ENTRY (BP_SYM (__mpn_rshift))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebp, 0)
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp),%edi
+ cfi_rel_offset (edi, 12)
+ movl S(%esp),%esi
+ cfi_rel_offset (esi, 8)
+ movl SIZE(%esp),%ebx
+ cfi_rel_offset (ebx, 0)
+ movl CNT(%esp),%ecx
+#if __BOUNDED_POINTERS__
+ shll $2, %ebx /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ebx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, S(%esp), %ebx)
+ shrl $2, %ebx
+#endif
+
+/* We can use faster code for shift-by-1 under certain conditions. */
+ cmp $1,%ecx
+ jne L(normal)
+ leal 4(%edi),%eax
+ cmpl %esi,%eax
+ jnc L(special) /* jump if res_ptr + 1 >= s_ptr */
+ leal (%edi,%ebx,4),%eax
+ cmpl %eax,%esi
+ jnc L(special) /* jump if s_ptr >= res_ptr + size */
+
+L(normal):
+ movl (%esi),%edx
+ addl $4,%esi
+ xorl %eax,%eax
+ shrdl %cl,%edx,%eax /* compute carry limb */
+ pushl %eax /* push carry limb onto stack */
+ cfi_adjust_cfa_offset (4)
+
+ decl %ebx
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ shrl $3,%ebx
+ jz L(end)
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+L(oop): movl 28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebp
+
+ movl (%esi),%eax
+ movl 4(%esi),%edx
+ shrdl %cl,%eax,%ebp
+ shrdl %cl,%edx,%eax
+ movl %ebp,(%edi)
+ movl %eax,4(%edi)
+
+ movl 8(%esi),%ebp
+ movl 12(%esi),%eax
+ shrdl %cl,%ebp,%edx
+ shrdl %cl,%eax,%ebp
+ movl %edx,8(%edi)
+ movl %ebp,12(%edi)
+
+ movl 16(%esi),%edx
+ movl 20(%esi),%ebp
+ shrdl %cl,%edx,%eax
+ shrdl %cl,%ebp,%edx
+ movl %eax,16(%edi)
+ movl %edx,20(%edi)
+
+ movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ shrdl %cl,%eax,%ebp
+ shrdl %cl,%edx,%eax
+ movl %ebp,24(%edi)
+ movl %eax,28(%edi)
+
+ addl $32,%esi
+ addl $32,%edi
+ decl %ebx
+ jnz L(oop)
+
+L(end): popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ andl $7,%ebx
+ jz L(end2)
+L(oop2):
+ movl (%esi),%eax
+ shrdl %cl,%eax,%edx /* compute result limb */
+ movl %edx,(%edi)
+ movl %eax,%edx
+ addl $4,%esi
+ addl $4,%edi
+ decl %ebx
+ jnz L(oop2)
+
+L(end2):
+ shrl %cl,%edx /* compute most significant limb */
+ movl %edx,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+ cfi_adjust_cfa_offset (-4)
+
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+
+/* We loop from least significant end of the arrays, which is only
+ permissible if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination.
+*/
+
+ cfi_adjust_cfa_offset (16)
+ cfi_rel_offset (edi, 12)
+ cfi_rel_offset (esi, 8)
+ cfi_rel_offset (ebp, 4)
+ cfi_rel_offset (ebx, 0)
+L(special):
+ leal -4(%edi,%ebx,4),%edi
+ leal -4(%esi,%ebx,4),%esi
+
+ movl (%esi),%edx
+ subl $4,%esi
+
+ decl %ebx
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ shrl $3,%ebx
+
+ shrl $1,%edx
+ incl %ebx
+ decl %ebx
+ jz L(Lend)
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+L(Loop):
+ movl -28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebp
+
+ movl (%esi),%eax
+ movl -4(%esi),%edx
+ rcrl $1,%eax
+ movl %ebp,(%edi)
+ rcrl $1,%edx
+ movl %eax,-4(%edi)
+
+ movl -8(%esi),%ebp
+ movl -12(%esi),%eax
+ rcrl $1,%ebp
+ movl %edx,-8(%edi)
+ rcrl $1,%eax
+ movl %ebp,-12(%edi)
+
+ movl -16(%esi),%edx
+ movl -20(%esi),%ebp
+ rcrl $1,%edx
+ movl %eax,-16(%edi)
+ rcrl $1,%ebp
+ movl %edx,-20(%edi)
+
+ movl -24(%esi),%eax
+ movl -28(%esi),%edx
+ rcrl $1,%eax
+ movl %ebp,-24(%edi)
+ rcrl $1,%edx
+ movl %eax,-28(%edi)
+
+ leal -32(%esi),%esi /* use leal not to clobber carry */
+ leal -32(%edi),%edi
+ decl %ebx
+ jnz L(Loop)
+
+L(Lend):
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ sbbl %eax,%eax /* save carry in %eax */
+ andl $7,%ebx
+ jz L(Lend2)
+ addl %eax,%eax /* restore carry from eax */
+L(Loop2):
+ movl %edx,%ebp
+ movl (%esi),%edx
+ rcrl $1,%edx
+ movl %ebp,(%edi)
+
+ leal -4(%esi),%esi /* use leal not to clobber carry */
+ leal -4(%edi),%edi
+ decl %ebx
+ jnz L(Loop2)
+
+ jmp L(L1)
+L(Lend2):
+ addl %eax,%eax /* restore carry from eax */
+L(L1): movl %edx,(%edi) /* store last limb */
+
+ movl $0,%eax
+ rcrl $1,%eax
+
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+END (BP_SYM (__mpn_rshift))
diff --git a/libc/sysdeps/i386/i586/stpcpy.S b/libc/sysdeps/i386/i586/stpcpy.S
new file mode 100644
index 000000000..8691efd01
--- /dev/null
+++ b/libc/sysdeps/i386/i586/stpcpy.S
@@ -0,0 +1,8 @@
+#define USE_AS_STPCPY
+#define STRCPY __stpcpy
+
+#include <sysdeps/i386/i586/strcpy.S>
+
+weak_alias (__stpcpy, stpcpy)
+libc_hidden_def (__stpcpy)
+libc_hidden_builtin_def (stpcpy)
diff --git a/libc/sysdeps/i386/i586/strchr.S b/libc/sysdeps/i386/i586/strchr.S
new file mode 100644
index 000000000..136b19a3f
--- /dev/null
+++ b/libc/sysdeps/i386/i586/strchr.S
@@ -0,0 +1,357 @@
+/* Find character CH in a NUL terminated string.
+ Highly optimized version for ix85, x>=5.
+ Copyright (C) 1995,1996,1997,2000,2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+/* This version is especially optimized for the i586 (and following?)
+ processors. This is mainly done by using the two pipelines. The
+ version optimized for i486 is weak in this aspect because to get
+ as much parallelism we have to execute some *more* instructions.
+
+ The code below is structured to reflect the pairing of the instructions
+ as *I think* it is. I have no processor data book to verify this.
+ If you find something you think is incorrect let me know. */
+
+
+/* The magic value which is used throughout in the whole code. */
+#define magic 0xfefefeff
+
+#define PARMS LINKAGE+16 /* space for 4 saved regs */
+#define RTN PARMS
+#define STR RTN+RTN_SIZE
+#define CHR STR+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (strchr))
+ ENTER
+
+ pushl %edi /* Save callee-safe registers. */
+ cfi_adjust_cfa_offset (-4)
+ pushl %esi
+ cfi_adjust_cfa_offset (-4)
+
+ pushl %ebx
+ cfi_adjust_cfa_offset (-4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (-4)
+
+ movl STR(%esp), %eax
+ movl CHR(%esp), %edx
+ CHECK_BOUNDS_LOW (%eax, STR(%esp))
+
+ movl %eax, %edi /* duplicate string pointer for later */
+ cfi_rel_offset (edi, 12)
+ xorl %ecx, %ecx /* clear %ecx */
+
+ /* At the moment %edx contains C. What we need for the
+ algorithm is C in all bytes of the dword. Avoid
+ operations on 16 bit words because these require an
+ prefix byte (and one more cycle). */
+ movb %dl, %dh /* now it is 0|0|c|c */
+ movb %dl, %cl /* we construct the lower half in %ecx */
+
+ shll $16, %edx /* now %edx is c|c|0|0 */
+ movb %cl, %ch /* now %ecx is 0|0|c|c */
+
+ orl %ecx, %edx /* and finally c|c|c|c */
+ andl $3, %edi /* mask alignment bits */
+
+ jz L(11) /* alignment is 0 => start loop */
+
+ movb %dl, %cl /* 0 is needed below */
+ jp L(0) /* exactly two bits set */
+
+ xorb (%eax), %cl /* is byte the one we are looking for? */
+ jz L(2) /* yes => return pointer */
+
+ xorb %dl, %cl /* load single byte and test for NUL */
+ je L(3) /* yes => return NULL */
+
+ movb 1(%eax), %cl /* load single byte */
+ incl %eax
+
+ cmpb %cl, %dl /* is byte == C? */
+ je L(2) /* aligned => return pointer */
+
+ cmpb $0, %cl /* is byte NUL? */
+ je L(3) /* yes => return NULL */
+
+ incl %eax
+ decl %edi
+
+ jne L(11)
+
+L(0): movb (%eax), %cl /* load single byte */
+
+ cmpb %cl, %dl /* is byte == C? */
+ je L(2) /* aligned => return pointer */
+
+ cmpb $0, %cl /* is byte NUL? */
+ je L(3) /* yes => return NULL */
+
+ incl %eax /* increment pointer */
+
+ cfi_rel_offset (esi, 8)
+ cfi_rel_offset (ebx, 4)
+ cfi_rel_offset (ebp, 0)
+
+ /* The following code is the preparation for the loop. The
+ four instruction up to `L1' will not be executed in the loop
+ because the same code is found at the end of the loop, but
+ there it is executed in parallel with other instructions. */
+L(11): movl (%eax), %ecx
+ movl $magic, %ebp
+
+ movl $magic, %edi
+ addl %ecx, %ebp
+
+ /* The main loop: it looks complex and indeed it is. I would
+ love to say `it was hard to write, so it should he hard to
+ read' but I will give some more hints. To fully understand
+ this code you should first take a look at the i486 version.
+ The basic algorithm is the same, but here the code organized
+ in a way which permits to use both pipelines all the time.
+
+ I tried to make it a bit more understandable by indenting
+ the code according to stage in the algorithm. It goes as
+ follows:
+ check for 0 in 1st word
+ check for C in 1st word
+ check for 0 in 2nd word
+ check for C in 2nd word
+ check for 0 in 3rd word
+ check for C in 3rd word
+ check for 0 in 4th word
+ check for C in 4th word
+
+ Please note that doing the test for NUL before the test for
+ C allows us to overlap the test for 0 in the next word with
+ the test for C. */
+
+L(1): xorl %ecx, %ebp /* (word^magic) */
+ addl %ecx, %edi /* add magic word */
+
+ leal 4(%eax), %eax /* increment pointer */
+ jnc L(4) /* previous addl caused overflow? */
+
+ movl %ecx, %ebx /* duplicate original word */
+ orl $magic, %ebp /* (word^magic)|magic */
+
+ addl $1, %ebp /* (word^magic)|magic == 0xffffffff? */
+ jne L(4) /* yes => we found word with NUL */
+
+ movl $magic, %esi /* load magic value */
+ xorl %edx, %ebx /* clear words which are C */
+
+ movl (%eax), %ecx
+ addl %ebx, %esi /* (word+magic) */
+
+ movl $magic, %edi
+ jnc L(5) /* previous addl caused overflow? */
+
+ movl %edi, %ebp
+ xorl %ebx, %esi /* (word+magic)^word */
+
+ addl %ecx, %ebp
+ orl $magic, %esi /* ((word+magic)^word)|magic */
+
+ addl $1, %esi /* ((word+magic)^word)|magic==0xf..f?*/
+ jne L(5) /* yes => we found word with C */
+
+ xorl %ecx, %ebp
+ addl %ecx, %edi
+
+ leal 4(%eax), %eax
+ jnc L(4)
+
+ movl %ecx, %ebx
+ orl $magic, %ebp
+
+ addl $1, %ebp
+ jne L(4)
+
+ movl $magic, %esi
+ xorl %edx, %ebx
+
+ movl (%eax), %ecx
+ addl %ebx, %esi
+
+ movl $magic, %edi
+ jnc L(5)
+
+ movl %edi, %ebp
+ xorl %ebx, %esi
+
+ addl %ecx, %ebp
+ orl $magic, %esi
+
+ addl $1, %esi
+ jne L(5)
+
+ xorl %ecx, %ebp
+ addl %ecx, %edi
+
+ leal 4(%eax), %eax
+ jnc L(4)
+
+ movl %ecx, %ebx
+ orl $magic, %ebp
+
+ addl $1, %ebp
+ jne L(4)
+
+ movl $magic, %esi
+ xorl %edx, %ebx
+
+ movl (%eax), %ecx
+ addl %ebx, %esi
+
+ movl $magic, %edi
+ jnc L(5)
+
+ movl %edi, %ebp
+ xorl %ebx, %esi
+
+ addl %ecx, %ebp
+ orl $magic, %esi
+
+ addl $1, %esi
+ jne L(5)
+
+ xorl %ecx, %ebp
+ addl %ecx, %edi
+
+ leal 4(%eax), %eax
+ jnc L(4)
+
+ movl %ecx, %ebx
+ orl $magic, %ebp
+
+ addl $1, %ebp
+ jne L(4)
+
+ movl $magic, %esi
+ xorl %edx, %ebx
+
+ movl (%eax), %ecx
+ addl %ebx, %esi
+
+ movl $magic, %edi
+ jnc L(5)
+
+ movl %edi, %ebp
+ xorl %ebx, %esi
+
+ addl %ecx, %ebp
+ orl $magic, %esi
+
+ addl $1, %esi
+
+ je L(1)
+
+ /* We know there is no NUL byte but a C byte in the word.
+ %ebx contains NUL in this particular byte. */
+L(5): subl $4, %eax /* adjust pointer */
+ testb %bl, %bl /* first byte == C? */
+
+ jz L(2) /* yes => return pointer */
+
+ incl %eax /* increment pointer */
+ testb %bh, %bh /* second byte == C? */
+
+ jz L(2) /* yes => return pointer */
+
+ shrl $16, %ebx /* make upper bytes accessible */
+ incl %eax /* increment pointer */
+
+ cmp $0, %bl /* third byte == C */
+ je L(2) /* yes => return pointer */
+
+ incl %eax /* increment pointer */
+
+L(2): CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
+ RETURN_BOUNDED_POINTER (STR(%esp))
+L(out): popl %ebp /* restore saved registers */
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+
+ cfi_adjust_cfa_offset (16)
+ cfi_rel_offset (edi, 12)
+ cfi_rel_offset (esi, 8)
+ cfi_rel_offset (ebx, 4)
+ cfi_rel_offset (ebp, 0)
+ /* We know there is a NUL byte in the word. But we have to test
+ whether there is an C byte before it in the word. */
+L(4): subl $4, %eax /* adjust pointer */
+ cmpb %dl, %cl /* first byte == C? */
+
+ je L(2) /* yes => return pointer */
+
+ cmpb $0, %cl /* first byte == NUL? */
+ je L(3) /* yes => return NULL */
+
+ incl %eax /* increment pointer */
+
+ cmpb %dl, %ch /* second byte == C? */
+ je L(2) /* yes => return pointer */
+
+ cmpb $0, %ch /* second byte == NUL? */
+ je L(3) /* yes => return NULL */
+
+ shrl $16, %ecx /* make upper bytes accessible */
+ incl %eax /* increment pointer */
+
+ cmpb %dl, %cl /* third byte == C? */
+ je L(2) /* yes => return pointer */
+
+ cmpb $0, %cl /* third byte == NUL? */
+ je L(3) /* yes => return NULL */
+
+ incl %eax /* increment pointer */
+
+ /* The test four the fourth byte is necessary! */
+ cmpb %dl, %ch /* fourth byte == C? */
+ je L(2) /* yes => return pointer */
+
+L(3): xorl %eax, %eax
+ RETURN_NULL_BOUNDED_POINTER
+ jmp L(out)
+END (BP_SYM (strchr))
+
+#undef index
+weak_alias (BP_SYM (strchr), BP_SYM (index))
+libc_hidden_builtin_def (strchr)
diff --git a/libc/sysdeps/i386/i586/strcpy.S b/libc/sysdeps/i386/i586/strcpy.S
new file mode 100644
index 000000000..5426e5974
--- /dev/null
+++ b/libc/sysdeps/i386/i586/strcpy.S
@@ -0,0 +1,178 @@
+/* strcpy/stpcpy implementation for i586.
+ Copyright (C) 1997, 2000, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+12 /* space for 3 saved regs */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#define SRC DEST+PTR_SIZE
+
+#ifndef USE_AS_STPCPY
+# define STRCPY strcpy
+#endif
+
+#define magic 0xfefefeff
+
+ .text
+ENTRY (BP_SYM (STRCPY))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+
+ movl DEST(%esp), %edi
+ cfi_rel_offset (edi, 8)
+ movl SRC(%esp), %esi
+ cfi_rel_offset (esi, 4)
+ CHECK_BOUNDS_LOW (%edi, DEST(%esp))
+ CHECK_BOUNDS_LOW (%esi, SRC(%esp))
+
+ xorl %eax, %eax
+ leal -1(%esi), %ecx
+
+ movl $magic, %ebx
+ cfi_rel_offset (ebx, 0)
+ andl $3, %ecx
+
+#ifdef PIC
+ call 2f
+ cfi_adjust_cfa_offset (4)
+2: popl %edx
+ cfi_adjust_cfa_offset (-4)
+ /* 0xb is the distance between 2: and 1: but we avoid writing
+ 1f-2b because the assembler generates worse code. */
+ leal 0xb(%edx,%ecx,8), %ecx
+#else
+ leal 1f(,%ecx,8), %ecx
+#endif
+
+ jmp *%ecx
+
+ .align 8
+1:
+ orb (%esi), %al
+ jz L(end)
+ stosb
+ xorl %eax, %eax
+ incl %esi
+
+ orb (%esi), %al
+ jz L(end)
+ stosb
+ xorl %eax, %eax
+ incl %esi
+
+ orb (%esi), %al
+ jz L(end)
+ stosb
+ xorl %eax, %eax
+ incl %esi
+
+L(1): movl (%esi), %ecx
+ leal 4(%esi),%esi
+
+ subl %ecx, %eax
+ addl %ebx, %ecx
+
+ decl %eax
+ jnc L(3)
+
+ movl %ecx, %edx
+ xorl %ecx, %eax
+
+ subl %ebx, %edx
+ andl $~magic, %eax
+
+ jne L(4)
+
+ movl %edx, (%edi)
+ leal 4(%edi),%edi
+
+ jmp L(1)
+
+L(3): movl %ecx, %edx
+
+ subl %ebx, %edx
+
+L(4): movb %dl, (%edi)
+ testb %dl, %dl
+
+ movl %edx, %eax
+ jz L(end2)
+
+ shrl $16, %eax
+ movb %dh, 1(%edi)
+#ifdef USE_AS_STPCPY
+ addl $1, %edi
+#endif
+
+ cmpb $0, %dh
+ jz L(end2)
+
+#ifdef USE_AS_STPCPY
+ movb %al, 1(%edi)
+ addl $1, %edi
+
+ cmpb $0, %al
+ jz L(end2)
+
+ addl $1, %edi
+#else
+ movb %al, 2(%edi)
+ testb %al, %al
+
+ leal 3(%edi), %edi
+ jz L(end2)
+#endif
+
+L(end): movb %ah, (%edi)
+
+L(end2):
+ /* GKM FIXME: check high bounds */
+#ifdef USE_AS_STPCPY
+ movl %edi, %eax
+#else
+ movl DEST(%esp), %eax
+#endif
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (STRCPY))
+#ifndef USE_AS_STPCPY
+libc_hidden_builtin_def (strcpy)
+#endif
diff --git a/libc/sysdeps/i386/i586/strlen.S b/libc/sysdeps/i386/i586/strlen.S
new file mode 100644
index 000000000..9ef22b0c7
--- /dev/null
+++ b/libc/sysdeps/i386/i586/strlen.S
@@ -0,0 +1,189 @@
+/* strlen -- Compute length of NUL terminated string.
+ Highly optimized version for ix86, x>=5.
+ Copyright (C) 1995,1996,1997,2000,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+/* This version is especially optimized for the i586 (and following?)
+ processors. This is mainly done by using the two pipelines. The
+ version optimized for i486 is weak in this aspect because to get
+ as much parallelism we have to execute some *more* instructions.
+
+ The code below is structured to reflect the pairing of the instructions
+ as *I think* it is. I have no processor data book to verify this.
+ If you find something you think is incorrect let me know. */
+
+
+/* The magic value which is used throughout in the whole code. */
+#define magic 0xfefefeff
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define STR PARMS
+
+ .text
+ENTRY (BP_SYM (strlen))
+ ENTER
+
+ movl STR(%esp), %eax
+ CHECK_BOUNDS_LOW (%eax, STR(%esp))
+ movl $3, %edx /* load mask (= 3) */
+
+ andl %eax, %edx /* separate last two bits of address */
+
+ jz L(1) /* aligned => start loop */
+ jp L(0) /* exactly two bits set */
+
+ cmpb %dh, (%eax) /* is byte NUL? */
+ je L(2) /* yes => return */
+
+ incl %eax /* increment pointer */
+ cmpb %dh, (%eax) /* is byte NUL? */
+
+ je L(2) /* yes => return */
+
+ incl %eax /* increment pointer */
+ xorl $2, %edx
+
+ jz L(1)
+
+L(0): cmpb %dh, (%eax) /* is byte NUL? */
+ je L(2) /* yes => return */
+
+ incl %eax /* increment pointer */
+ xorl %edx, %edx /* We need %edx == 0 for later */
+
+ /* We exit the loop if adding MAGIC_BITS to LONGWORD fails to
+ change any of the hole bits of LONGWORD.
+
+ 1) Is this safe? Will it catch all the zero bytes?
+ Suppose there is a byte with all zeros. Any carry bits
+ propagating from its left will fall into the hole at its
+ least significant bit and stop. Since there will be no
+ carry from its most significant bit, the LSB of the
+ byte to the left will be unchanged, and the zero will be
+ detected.
+
+ 2) Is this worthwhile? Will it ignore everything except
+ zero bytes? Suppose every byte of LONGWORD has a bit set
+ somewhere. There will be a carry into bit 8. If bit 8
+ is set, this will carry into bit 16. If bit 8 is clear,
+ one of bits 9-15 must be set, so there will be a carry
+ into bit 16. Similarly, there will be a carry into bit
+ 24. If one of bits 24-31 is set, there will be a carry
+ into bit 32 (=carry flag), so all of the hole bits will
+ be changed.
+
+ Note: %edx == 0 in any case here. */
+
+L(1):
+ movl (%eax), %ecx /* get word (= 4 bytes) in question */
+ addl $4, %eax /* adjust pointer for *next* word */
+
+ subl %ecx, %edx /* first step to negate word */
+ addl $magic, %ecx /* add magic word */
+
+ decl %edx /* complete negation of word */
+ jnc L(3) /* previous addl caused overflow? */
+
+ xorl %ecx, %edx /* (word+magic)^word */
+
+ andl $~magic, %edx /* any of the carry flags set? */
+
+ jne L(3) /* yes => determine byte */
+
+
+ movl (%eax), %ecx /* get word (= 4 bytes) in question */
+ addl $4, %eax /* adjust pointer for *next* word */
+
+ subl %ecx, %edx /* first step to negate word */
+ addl $magic, %ecx /* add magic word */
+
+ decl %edx /* complete negation of word */
+ jnc L(3) /* previous addl caused overflow? */
+
+ xorl %ecx, %edx /* (word+magic)^word */
+
+ andl $~magic, %edx /* any of the carry flags set? */
+
+ jne L(3) /* yes => determine byte */
+
+
+ movl (%eax), %ecx /* get word (= 4 bytes) in question */
+ addl $4, %eax /* adjust pointer for *next* word */
+
+ subl %ecx, %edx /* first step to negate word */
+ addl $magic, %ecx /* add magic word */
+
+ decl %edx /* complete negation of word */
+ jnc L(3) /* previous addl caused overflow? */
+
+ xorl %ecx, %edx /* (word+magic)^word */
+
+ andl $~magic, %edx /* any of the carry flags set? */
+
+ jne L(3) /* yes => determine byte */
+
+
+ movl (%eax), %ecx /* get word (= 4 bytes) in question */
+ addl $4, %eax /* adjust pointer for *next* word */
+
+ subl %ecx, %edx /* first step to negate word */
+ addl $magic, %ecx /* add magic word */
+
+ decl %edx /* complete negation of word */
+ jnc L(3) /* previous addl caused overflow? */
+
+ xorl %ecx, %edx /* (word+magic)^word */
+
+ andl $~magic, %edx /* any of the carry flags set? */
+
+ je L(1) /* no => start loop again */
+
+
+L(3): subl $4, %eax /* correct too early pointer increment */
+ subl $magic, %ecx
+
+ cmpb $0, %cl /* lowest byte NUL? */
+ jz L(2) /* yes => return */
+
+ inc %eax /* increment pointer */
+ testb %ch, %ch /* second byte NUL? */
+
+ jz L(2) /* yes => return */
+
+ shrl $16, %ecx /* make upper bytes accessible */
+ incl %eax /* increment pointer */
+
+ cmpb $0, %cl /* is third byte NUL? */
+ jz L(2) /* yes => return */
+
+ incl %eax /* increment pointer */
+
+L(2): CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
+ subl STR(%esp), %eax /* now compute the length as difference
+ between start and terminating NUL
+ character */
+ LEAVE
+ ret
+END (BP_SYM (strlen))
+libc_hidden_builtin_def (strlen)
diff --git a/libc/sysdeps/i386/i586/sub_n.S b/libc/sysdeps/i386/i586/sub_n.S
new file mode 100644
index 000000000..7c32c1adb
--- /dev/null
+++ b/libc/sysdeps/i386/i586/sub_n.S
@@ -0,0 +1,155 @@
+/* Pentium __mpn_sub_n -- Subtract two limb vectors of the same length > 0
+ and store difference in a third limb vector.
+ Copyright (C) 1992,94,95,96,97,98,2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+16 /* space for 4 saved regs */
+#define RES PARMS
+#define S1 RES+PTR_SIZE
+#define S2 S1+PTR_SIZE
+#define SIZE S2+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__mpn_sub_n))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp),%edi
+ cfi_rel_offset (edi, 12)
+ movl S1(%esp),%esi
+ cfi_rel_offset (esi, 8)
+ movl S2(%esp),%ebx
+ cfi_rel_offset (ebx, 0)
+ movl SIZE(%esp),%ecx
+#if __BOUNDED_POINTERS__
+ shll $2, %ecx /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, S1(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%ebx, S2(%esp), %ecx)
+ shrl $2, %ecx
+#endif
+ movl (%ebx),%ebp
+ cfi_rel_offset (ebp, 4)
+
+ decl %ecx
+ movl %ecx,%edx
+ shrl $3,%ecx
+ andl $7,%edx
+ testl %ecx,%ecx /* zero carry flag */
+ jz L(end)
+ pushl %edx
+ cfi_adjust_cfa_offset (4)
+
+ ALIGN (3)
+L(oop): movl 28(%edi),%eax /* fetch destination cache line */
+ leal 32(%edi),%edi
+
+L(1): movl (%esi),%eax
+ movl 4(%esi),%edx
+ sbbl %ebp,%eax
+ movl 4(%ebx),%ebp
+ sbbl %ebp,%edx
+ movl 8(%ebx),%ebp
+ movl %eax,-32(%edi)
+ movl %edx,-28(%edi)
+
+L(2): movl 8(%esi),%eax
+ movl 12(%esi),%edx
+ sbbl %ebp,%eax
+ movl 12(%ebx),%ebp
+ sbbl %ebp,%edx
+ movl 16(%ebx),%ebp
+ movl %eax,-24(%edi)
+ movl %edx,-20(%edi)
+
+L(3): movl 16(%esi),%eax
+ movl 20(%esi),%edx
+ sbbl %ebp,%eax
+ movl 20(%ebx),%ebp
+ sbbl %ebp,%edx
+ movl 24(%ebx),%ebp
+ movl %eax,-16(%edi)
+ movl %edx,-12(%edi)
+
+L(4): movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ sbbl %ebp,%eax
+ movl 28(%ebx),%ebp
+ sbbl %ebp,%edx
+ movl 32(%ebx),%ebp
+ movl %eax,-8(%edi)
+ movl %edx,-4(%edi)
+
+ leal 32(%esi),%esi
+ leal 32(%ebx),%ebx
+ decl %ecx
+ jnz L(oop)
+
+ popl %edx
+ cfi_adjust_cfa_offset (-4)
+L(end):
+ decl %edx /* test %edx w/o clobbering carry */
+ js L(end2)
+ incl %edx
+L(oop2):
+ leal 4(%edi),%edi
+ movl (%esi),%eax
+ sbbl %ebp,%eax
+ movl 4(%ebx),%ebp
+ movl %eax,-4(%edi)
+ leal 4(%esi),%esi
+ leal 4(%ebx),%ebx
+ decl %edx
+ jnz L(oop2)
+L(end2):
+ movl (%esi),%eax
+ sbbl %ebp,%eax
+ movl %eax,(%edi)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+END (BP_SYM (__mpn_sub_n))
diff --git a/libc/sysdeps/i386/i586/submul_1.S b/libc/sysdeps/i386/i586/submul_1.S
new file mode 100644
index 000000000..e8bc6478c
--- /dev/null
+++ b/libc/sysdeps/i386/i586/submul_1.S
@@ -0,0 +1,105 @@
+/* Pentium __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+ the result from a second limb vector.
+ Copyright (C) 1992, 94, 96, 97, 98, 00, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+16 /* space for 4 saved regs */
+#define RES PARMS
+#define S1 RES+PTR_SIZE
+#define SIZE S1+PTR_SIZE
+#define S2LIMB SIZE+4
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebx
+
+ .text
+ENTRY (BP_SYM (__mpn_submul_1))
+ ENTER
+
+ pushl %res_ptr
+ cfi_adjust_cfa_offset (4)
+ pushl %s1_ptr
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %s2_limb
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp), %res_ptr
+ cfi_rel_offset (res_ptr, 12)
+ movl S1(%esp), %s1_ptr
+ cfi_rel_offset (s1_ptr, 8)
+ movl SIZE(%esp), %size
+ movl S2LIMB(%esp), %s2_limb
+ cfi_rel_offset (s2_limb, 0)
+#if __BOUNDED_POINTERS__
+ shll $2, %sizeP /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%res_ptr, RES(%esp), %sizeP)
+ CHECK_BOUNDS_BOTH_WIDE (%s1_ptr, S1(%esp), %sizeP)
+ shrl $2, %sizeP
+#endif
+ leal (%res_ptr,%size,4), %res_ptr
+ leal (%s1_ptr,%size,4), %s1_ptr
+ negl %size
+ xorl %ebp, %ebp
+ cfi_rel_offset (ebp, 4)
+ ALIGN (3)
+
+L(oop): adcl $0, %ebp
+ movl (%s1_ptr,%size,4), %eax
+
+ mull %s2_limb
+
+ addl %ebp, %eax
+ movl (%res_ptr,%size,4), %ebp
+
+ adcl $0, %edx
+ subl %eax, %ebp
+
+ movl %ebp, (%res_ptr,%size,4)
+ incl %size
+
+ movl %edx, %ebp
+ jnz L(oop)
+
+ adcl $0, %ebp
+ movl %ebp, %eax
+ popl %s2_limb
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (s2_limb)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %s1_ptr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (s1_ptr)
+ popl %res_ptr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (res_ptr)
+
+ LEAVE
+ ret
+#undef size
+END (BP_SYM (__mpn_submul_1))
diff --git a/libc/sysdeps/i386/i686/Implies b/libc/sysdeps/i386/i686/Implies
new file mode 100644
index 000000000..e1fcccd5f
--- /dev/null
+++ b/libc/sysdeps/i386/i686/Implies
@@ -0,0 +1,4 @@
+# Due to the reordering and the other nifty extensions in the i686 it is
+# not really good to use heavily i586 optimized code on a i686. It's
+# better to use i486/i386 code.
+i386/i486
diff --git a/libc/sysdeps/i386/i686/Makefile b/libc/sysdeps/i386/i686/Makefile
new file mode 100644
index 000000000..c7378ab21
--- /dev/null
+++ b/libc/sysdeps/i386/i686/Makefile
@@ -0,0 +1,7 @@
+ifeq ($(subdir),csu)
+sysdep_routines += hp-timing
+elide-routines.os += hp-timing
+endif
+
+# So that we can test __m128's alignment
+stack-align-test-flags += -msse
diff --git a/libc/sysdeps/i386/i686/add_n.S b/libc/sysdeps/i386/i686/add_n.S
new file mode 100644
index 000000000..3cce33acf
--- /dev/null
+++ b/libc/sysdeps/i386/i686/add_n.S
@@ -0,0 +1,122 @@
+/* Add two limb vectors of the same length > 0 and store sum in a third
+ limb vector.
+ Copyright (C) 1992,94,95,97,98,2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+8 /* space for 2 saved regs */
+#define RES PARMS
+#define S1 RES+PTR_SIZE
+#define S2 S1+PTR_SIZE
+#define SIZE S2+PTR_SIZE
+
+ .text
+#ifdef PIC
+L(1): addl (%esp), %eax
+ ret
+#endif
+ENTRY (BP_SYM (__mpn_add_n))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp),%edi
+ cfi_rel_offset (edi, 4)
+ movl S1(%esp),%esi
+ cfi_rel_offset (esi, 0)
+ movl S2(%esp),%edx
+ movl SIZE(%esp),%ecx
+#if __BOUNDED_POINTERS__
+ shll $2, %ecx /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, S1(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%edx, S2(%esp), %ecx)
+ shrl $2, %ecx
+#endif
+ movl %ecx,%eax
+ shrl $3,%ecx /* compute count for unrolled loop */
+ negl %eax
+ andl $7,%eax /* get index where to start loop */
+ jz L(oop) /* necessary special case for 0 */
+ incl %ecx /* adjust loop count */
+ shll $2,%eax /* adjustment for pointers... */
+ subl %eax,%edi /* ... since they are offset ... */
+ subl %eax,%esi /* ... by a constant when we ... */
+ subl %eax,%edx /* ... enter the loop */
+ shrl $2,%eax /* restore previous value */
+#ifdef PIC
+/* Calculate start address in loop for PIC. */
+ leal (L(oop)-L(0)-3)(%eax,%eax,8),%eax
+ call L(1)
+L(0):
+#else
+/* Calculate start address in loop for non-PIC. */
+ leal (L(oop) - 3)(%eax,%eax,8),%eax
+#endif
+ jmp *%eax /* jump into loop */
+ ALIGN (3)
+L(oop): movl (%esi),%eax
+ adcl (%edx),%eax
+ movl %eax,(%edi)
+ movl 4(%esi),%eax
+ adcl 4(%edx),%eax
+ movl %eax,4(%edi)
+ movl 8(%esi),%eax
+ adcl 8(%edx),%eax
+ movl %eax,8(%edi)
+ movl 12(%esi),%eax
+ adcl 12(%edx),%eax
+ movl %eax,12(%edi)
+ movl 16(%esi),%eax
+ adcl 16(%edx),%eax
+ movl %eax,16(%edi)
+ movl 20(%esi),%eax
+ adcl 20(%edx),%eax
+ movl %eax,20(%edi)
+ movl 24(%esi),%eax
+ adcl 24(%edx),%eax
+ movl %eax,24(%edi)
+ movl 28(%esi),%eax
+ adcl 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz L(oop)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+END (BP_SYM (__mpn_add_n))
diff --git a/libc/sysdeps/i386/i686/bzero.S b/libc/sysdeps/i386/i686/bzero.S
new file mode 100644
index 000000000..c1e4a6d50
--- /dev/null
+++ b/libc/sysdeps/i386/i686/bzero.S
@@ -0,0 +1,3 @@
+#define memset __bzero
+#include <sysdeps/i386/i686/memset.S>
+weak_alias (BP_SYM (__bzero), BP_SYM (bzero))
diff --git a/libc/sysdeps/i386/i686/dl-hash.h b/libc/sysdeps/i386/i686/dl-hash.h
new file mode 100644
index 000000000..4bdd998aa
--- /dev/null
+++ b/libc/sysdeps/i386/i686/dl-hash.h
@@ -0,0 +1,79 @@
+/* Compute hash alue for given string according to ELF standard.
+ Copyright (C) 1998, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DL_HASH_H
+#define _DL_HASH_H 1
+
+
+/* This is the hashing function specified by the ELF ABI. It is highly
+ optimized for the PII processors. Though it will run on i586 it
+ would be much slower than the generic C implementation. So don't
+ use it. */
+static unsigned int
+_dl_elf_hash (const char *name)
+{
+ unsigned int result;
+ unsigned int temp0;
+ unsigned int temp1;
+
+ __asm__ __volatile__
+ ("movzbl (%1),%2\n\t"
+ "testl %2, %2\n\t"
+ "jz 1f\n\t"
+ "movl %2, %0\n\t"
+ "movzbl 1(%1), %2\n\t"
+ "jecxz 1f\n\t"
+ "shll $4, %0\n\t"
+ "addl %2, %0\n\t"
+ "movzbl 2(%1), %2\n\t"
+ "jecxz 1f\n\t"
+ "shll $4, %0\n\t"
+ "addl %2, %0\n\t"
+ "movzbl 3(%1), %2\n\t"
+ "jecxz 1f\n\t"
+ "shll $4, %0\n\t"
+ "addl %2, %0\n\t"
+ "movzbl 4(%1), %2\n\t"
+ "jecxz 1f\n\t"
+ "shll $4, %0\n\t"
+ "addl $5, %1\n\t"
+ "addl %2, %0\n\t"
+ "movzbl (%1), %2\n\t"
+ "jecxz 1f\n"
+ "2:\t"
+ "shll $4, %0\n\t"
+ "movl $0xf0000000, %3\n\t"
+ "incl %1\n\t"
+ "addl %2, %0\n\t"
+ "andl %0, %3\n\t"
+ "andl $0x0fffffff, %0\n\t"
+ "shrl $24, %3\n\t"
+ "movzbl (%1), %2\n\t"
+ "xorl %3, %0\n\t"
+ "testl %2, %2\n\t"
+ "jnz 2b\n"
+ "1:\t"
+ : "=&r" (result), "=r" (name), "=&c" (temp0), "=&r" (temp1)
+ : "0" (0), "1" ((const unsigned char *) name));
+
+ return result;
+}
+
+#endif /* dl-hash.h */
diff --git a/libc/sysdeps/i386/i686/ffs.c b/libc/sysdeps/i386/i686/ffs.c
new file mode 100644
index 000000000..684ae2182
--- /dev/null
+++ b/libc/sysdeps/i386/i686/ffs.c
@@ -0,0 +1,49 @@
+/* ffs -- find first set bit in a word, counted from least significant end.
+ For Intel 80x86, x>=6.
+ This file is part of the GNU C Library.
+ Copyright (C) 1991, 92, 93, 94, 97, 98, 2004, 2005 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define ffsl __something_else
+#include <string.h>
+
+#undef ffs
+
+#ifdef __GNUC__
+
+int
+__ffs (x)
+ int x;
+{
+ int cnt;
+ int tmp;
+
+ asm ("bsfl %2,%0\n" /* Count low bits in X and store in %1. */
+ "cmovel %1,%0\n" /* If number was zero, use -1 as result. */
+ : "=&r" (cnt), "=r" (tmp) : "rm" (x), "1" (-1));
+
+ return cnt + 1;
+}
+weak_alias (__ffs, ffs)
+libc_hidden_builtin_def (ffs)
+#undef ffsl
+weak_alias (__ffs, ffsl)
+
+#else
+#include <string/ffs.c>
+#endif
diff --git a/libc/sysdeps/i386/i686/fpu/s_fdim.S b/libc/sysdeps/i386/i686/fpu/s_fdim.S
new file mode 100644
index 000000000..30ecff4e7
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fdim.S
@@ -0,0 +1,44 @@
+/* Compute positive difference.
+ Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fdim)
+ fldl 4(%esp) // x
+ fldl 12(%esp) // x : y
+
+ fucomi %st(1), %st
+ jp 1f
+
+ jc 3f
+ fstp %st(1)
+ fldz
+ jmp 2f
+
+3: fsubrp %st, %st(1)
+ ret
+
+1: fucomi %st(0), %st
+ fcmovnu %st(1), %st
+2: fstp %st(1)
+ ret
+END(__fdim)
+weak_alias (__fdim, fdim)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fdimf.S b/libc/sysdeps/i386/i686/fpu/s_fdimf.S
new file mode 100644
index 000000000..888df14b6
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fdimf.S
@@ -0,0 +1,44 @@
+/* Compute positive difference.
+ Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fdimf)
+ flds 4(%esp) // x
+ flds 8(%esp) // x : y
+
+ fucomi %st(1), %st
+ jp 1f
+
+ jc 3f
+ fstp %st(1)
+ fldz
+ jmp 2f
+
+3: fsubrp %st, %st(1)
+ ret
+
+1: fucomi %st(0), %st
+ fcmovnu %st(1), %st
+2: fstp %st(1)
+ ret
+END(__fdimf)
+weak_alias (__fdimf, fdimf)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fdiml.S b/libc/sysdeps/i386/i686/fpu/s_fdiml.S
new file mode 100644
index 000000000..cb0e26e36
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fdiml.S
@@ -0,0 +1,44 @@
+/* Compute positive difference.
+ Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fdiml)
+ fldt 4(%esp) // x
+ fldt 16(%esp) // x : y
+
+ fucomi %st(1), %st
+ jp 1f
+
+ jc 3f
+ fstp %st(1)
+ fldz
+ jmp 2f
+
+3: fsubrp %st, %st(1)
+ ret
+
+1: fucomi %st(0), %st
+ fcmovnu %st(1), %st
+2: fstp %st(1)
+ ret
+END(__fdiml)
+weak_alias (__fdiml, fdiml)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fmax.S b/libc/sysdeps/i386/i686/fpu/s_fmax.S
new file mode 100644
index 000000000..b28226987
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fmax.S
@@ -0,0 +1,40 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmax)
+ fldl 4(%esp) // x
+ fldl 12(%esp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fxch
+
+ fucomi %st(1), %st
+ fcmovb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fmax)
+weak_alias (__fmax, fmax)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fmaxf.S b/libc/sysdeps/i386/i686/fpu/s_fmaxf.S
new file mode 100644
index 000000000..fbf3e5bff
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fmaxf.S
@@ -0,0 +1,40 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmaxf)
+ flds 4(%esp) // x
+ flds 8(%esp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fxch
+
+ fucomi %st(1), %st
+ fcmovb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fmaxf)
+weak_alias (__fmaxf, fmaxf)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fmaxl.S b/libc/sysdeps/i386/i686/fpu/s_fmaxl.S
new file mode 100644
index 000000000..229febf52
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fmaxl.S
@@ -0,0 +1,40 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmaxl)
+ fldt 4(%esp) // x
+ fldt 16(%esp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fxch
+
+ fucomi %st(1), %st
+ fcmovb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fmaxl)
+weak_alias (__fmaxl, fmaxl)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fmin.S b/libc/sysdeps/i386/i686/fpu/s_fmin.S
new file mode 100644
index 000000000..d821cda2f
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fmin.S
@@ -0,0 +1,38 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmin)
+ fldl 4(%esp) // x
+ fldl 12(%esp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fucomi %st(1), %st
+ fcmovnb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fmin)
+weak_alias (__fmin, fmin)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fminf.S b/libc/sysdeps/i386/i686/fpu/s_fminf.S
new file mode 100644
index 000000000..8ef12035e
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fminf.S
@@ -0,0 +1,38 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fminf)
+ flds 4(%esp) // x
+ flds 8(%esp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fucomi %st(1), %st
+ fcmovnb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fminf)
+weak_alias (__fminf, fminf)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fminl.S b/libc/sysdeps/i386/i686/fpu/s_fminl.S
new file mode 100644
index 000000000..e158ff895
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fminl.S
@@ -0,0 +1,38 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fminl)
+ fldt 4(%esp) // x
+ fldt 16(%esp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fucomi %st(1), %st
+ fcmovnb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fminl)
+weak_alias (__fminl, fminl)
diff --git a/libc/sysdeps/i386/i686/hp-timing.c b/libc/sysdeps/i386/i686/hp-timing.c
new file mode 100644
index 000000000..c8c88650c
--- /dev/null
+++ b/libc/sysdeps/i386/i686/hp-timing.c
@@ -0,0 +1,24 @@
+/* Support for high precision, low overhead timing functions. i686 version.
+ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hp-timing.h>
+
+/* We have to define the variable for the overhead. */
+hp_timing_t _dl_hp_timing_overhead;
diff --git a/libc/sysdeps/i386/i686/hp-timing.h b/libc/sysdeps/i386/i686/hp-timing.h
new file mode 100644
index 000000000..b92486964
--- /dev/null
+++ b/libc/sysdeps/i386/i686/hp-timing.h
@@ -0,0 +1,157 @@
+/* High precision, low overhead timing functions. i686 version.
+ Copyright (C) 1998, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H 1
+
+#include <string.h>
+#include <sys/param.h>
+#include <stdio-common/_itoa.h>
+
+/* The macros defined here use the timestamp counter in i586 and up versions
+ of the x86 processors. They provide a very accurate way to measure the
+ time with very little overhead. The time values themself have no real
+ meaning, only differences are interesting.
+
+ This version is for the i686 processors. The difference to the i586
+ version is that the timerstamp register is unconditionally used. This is
+ not the case for the i586 version where we have to perform runtime test
+ whether the processor really has this capability. We have to make this
+ distinction since the sysdeps/i386/i586 code is supposed to work on all
+ platforms while the i686 already contains i686-specific code.
+
+ The list of macros we need includes the following:
+
+ - HP_TIMING_AVAIL: test for availability.
+
+ - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
+ implemented using function calls but instead uses some inlined code
+ which might simply consist of a few assembler instructions. We have to
+ know this since we might want to use the macros here in places where we
+ cannot make function calls.
+
+ - hp_timing_t: This is the type for variables used to store the time
+ values.
+
+ - HP_TIMING_ZERO: clear `hp_timing_t' object.
+
+ - HP_TIMING_NOW: place timestamp for current time in variable given as
+ parameter.
+
+ - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
+ HP_TIMING_DIFF macro.
+
+ - HP_TIMING_DIFF: compute difference between two times and store it
+ in a third. Source and destination might overlap.
+
+ - HP_TIMING_ACCUM: add time difference to another variable. This might
+ be a bit more complicated to implement for some platforms as the
+ operation should be thread-safe and 64bit arithmetic on 32bit platforms
+ is not.
+
+ - HP_TIMING_ACCUM_NT: this is the variant for situations where we know
+ there are no threads involved.
+
+ - HP_TIMING_PRINT: write decimal representation of the timing value into
+ the given string. This operation need not be inline even though
+ HP_TIMING_INLINE is specified.
+
+*/
+
+/* We always assume having the timestamp register. */
+#define HP_TIMING_AVAIL (1)
+
+/* We indeed have inlined functions. */
+#define HP_TIMING_INLINE (1)
+
+/* We use 64bit values for the times. */
+typedef unsigned long long int hp_timing_t;
+
+/* Set timestamp value to zero. */
+#define HP_TIMING_ZERO(Var) (Var) = (0)
+
+/* That's quite simple. Use the `rdtsc' instruction. Note that the value
+ might not be 100% accurate since there might be some more instructions
+ running in this moment. This could be changed by using a barrier like
+ 'cpuid' right before the `rdtsc' instruciton. But we are not interested
+ in accurate clock cycles here so we don't do this. */
+#define HP_TIMING_NOW(Var) __asm__ __volatile__ ("rdtsc" : "=A" (Var))
+
+/* Use two 'rdtsc' instructions in a row to find out how long it takes. */
+#define HP_TIMING_DIFF_INIT() \
+ do { \
+ if (GLRO(dl_hp_timing_overhead) == 0) \
+ { \
+ int __cnt = 5; \
+ GLRO(dl_hp_timing_overhead) = ~0ull; \
+ do \
+ { \
+ hp_timing_t __t1, __t2; \
+ HP_TIMING_NOW (__t1); \
+ HP_TIMING_NOW (__t2); \
+ if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \
+ GLRO(dl_hp_timing_overhead) = __t2 - __t1; \
+ } \
+ while (--__cnt > 0); \
+ } \
+ } while (0)
+
+/* It's simple arithmetic for us. */
+#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start))
+
+/* We have to jump through hoops to get this correctly implemented. */
+#define HP_TIMING_ACCUM(Sum, Diff) \
+ do { \
+ int __not_done; \
+ hp_timing_t __oldval = (Sum); \
+ hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \
+ do \
+ { \
+ hp_timing_t __newval = __oldval + __diff; \
+ int __temp0, __temp1; \
+ __asm__ __volatile__ ("xchgl %0, %%ebx\n\t" \
+ "lock; cmpxchg8b %1\n\t" \
+ "sete %%bl\n\t" \
+ "xchgl %0, %%ebx" \
+ : "=SD" (__not_done), "=m" (Sum), \
+ "=A" (__oldval), "=c" (__temp0) \
+ : "m" (Sum), "2" (__oldval), \
+ "3" ((unsigned int) (__newval >> 32)), \
+ "0" ((unsigned int) __newval)); \
+ } \
+ while ((unsigned char) __not_done); \
+ } while (0)
+
+/* No threads, no extra work. */
+#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff)
+
+/* Print the time value. */
+#define HP_TIMING_PRINT(Buf, Len, Val) \
+ do { \
+ char __buf[20]; \
+ char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \
+ size_t __len = (Len); \
+ char *__dest = (Buf); \
+ while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \
+ *__dest++ = *__cp++; \
+ memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles"))); \
+ } while (0)
+
+#endif /* hp-timing.h */
diff --git a/libc/sysdeps/i386/i686/memcmp.S b/libc/sysdeps/i386/i686/memcmp.S
new file mode 100644
index 000000000..4bd5394be
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memcmp.S
@@ -0,0 +1,423 @@
+/* Compare two memory blocks for differences in the first COUNT bytes.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+4 /* Preserve EBX. */
+#define BLK1 PARMS
+#define BLK2 BLK1+PTR_SIZE
+#define LEN BLK2+PTR_SIZE
+#define ENTRANCE pushl %ebx; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (ebx, 0); ENTER
+#define RETURN popl %ebx; cfi_adjust_cfa_offset (-4); \
+ cfi_restore (ebx); LEAVE; ret; \
+ cfi_adjust_cfa_offset (4); cfi_rel_offset (ebx, 0);
+
+/* Load an entry in a jump table into EBX. TABLE is a jump table
+ with relative offsets. INDEX is a register contains the index
+ into the jump table. */
+#define LOAD_JUMP_TABLE_ENTRY(TABLE, INDEX) \
+ /* We first load PC into EBX. */ \
+ call __i686.get_pc_thunk.bx; \
+ /* Get the address of the jump table. */ \
+ addl $(TABLE - .), %ebx; \
+ /* Get the entry and convert the relative offset to the \
+ absolute address. */ \
+ addl (%ebx,INDEX,4), %ebx
+
+#ifdef HAVE_HIDDEN
+ .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
+ .globl __i686.get_pc_thunk.bx
+ .hidden __i686.get_pc_thunk.bx
+#else
+ .text
+#endif
+ ALIGN (4)
+ .type __i686.get_pc_thunk.bx,@function
+__i686.get_pc_thunk.bx:
+ movl (%esp), %ebx
+ ret
+
+ .text
+ ALIGN (4)
+ENTRY (BP_SYM (memcmp))
+ ENTRANCE
+
+ movl BLK1(%esp), %eax
+ movl BLK2(%esp), %edx
+ movl LEN(%esp), %ecx
+
+ cmpl $1, %ecx
+ jne L(not_1)
+ movzbl (%eax), %ecx /* LEN == 1 */
+ cmpb (%edx), %cl
+ jne L(neq)
+L(bye):
+ xorl %eax, %eax
+ RETURN
+
+L(neq):
+ sbbl %eax, %eax
+ sbbl $-1, %eax
+ RETURN
+
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebx, 0)
+L(not_1):
+ jl L(bye) /* LEN == 0 */
+
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ movl %eax, %esi
+ cfi_rel_offset (esi, 0)
+ cmpl $32, %ecx;
+ jge L(32bytesormore) /* LEN => 32 */
+
+ LOAD_JUMP_TABLE_ENTRY (L(table_32bytes), %ecx)
+ addl %ecx, %edx
+ addl %ecx, %esi
+ jmp *%ebx
+
+ ALIGN (4)
+L(28bytes):
+ movl -28(%esi), %eax
+ movl -28(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(24bytes):
+ movl -24(%esi), %eax
+ movl -24(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(20bytes):
+ movl -20(%esi), %eax
+ movl -20(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(16bytes):
+ movl -16(%esi), %eax
+ movl -16(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(12bytes):
+ movl -12(%esi), %eax
+ movl -12(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(8bytes):
+ movl -8(%esi), %eax
+ movl -8(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(4bytes):
+ movl -4(%esi), %eax
+ movl -4(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(0bytes):
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ xorl %eax, %eax
+ RETURN
+
+ cfi_adjust_cfa_offset (8)
+ cfi_rel_offset (esi, 0)
+ cfi_rel_offset (ebx, 4)
+L(29bytes):
+ movl -29(%esi), %eax
+ movl -29(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(25bytes):
+ movl -25(%esi), %eax
+ movl -25(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(21bytes):
+ movl -21(%esi), %eax
+ movl -21(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(17bytes):
+ movl -17(%esi), %eax
+ movl -17(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(13bytes):
+ movl -13(%esi), %eax
+ movl -13(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(9bytes):
+ movl -9(%esi), %eax
+ movl -9(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(5bytes):
+ movl -5(%esi), %eax
+ movl -5(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(1bytes):
+ movzbl -1(%esi), %eax
+ cmpb -1(%edx), %al
+ jne L(set)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ xorl %eax, %eax
+ RETURN
+
+ cfi_adjust_cfa_offset (8)
+ cfi_rel_offset (esi, 0)
+ cfi_rel_offset (ebx, 4)
+L(30bytes):
+ movl -30(%esi), %eax
+ movl -30(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(26bytes):
+ movl -26(%esi), %eax
+ movl -26(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(22bytes):
+ movl -22(%esi), %eax
+ movl -22(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(18bytes):
+ movl -18(%esi), %eax
+ movl -18(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(14bytes):
+ movl -14(%esi), %eax
+ movl -14(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(10bytes):
+ movl -10(%esi), %eax
+ movl -10(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(6bytes):
+ movl -6(%esi), %eax
+ movl -6(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(2bytes):
+ movzwl -2(%esi), %eax
+ movzwl -2(%edx), %ecx
+ cmpb %cl, %al
+ jne L(set)
+ cmpl %ecx, %eax
+ jne L(set)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ xorl %eax, %eax
+ RETURN
+
+ cfi_adjust_cfa_offset (8)
+ cfi_rel_offset (esi, 0)
+ cfi_rel_offset (ebx, 4)
+L(31bytes):
+ movl -31(%esi), %eax
+ movl -31(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(27bytes):
+ movl -27(%esi), %eax
+ movl -27(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(23bytes):
+ movl -23(%esi), %eax
+ movl -23(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(19bytes):
+ movl -19(%esi), %eax
+ movl -19(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(15bytes):
+ movl -15(%esi), %eax
+ movl -15(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(11bytes):
+ movl -11(%esi), %eax
+ movl -11(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(7bytes):
+ movl -7(%esi), %eax
+ movl -7(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(3bytes):
+ movzwl -3(%esi), %eax
+ movzwl -3(%edx), %ecx
+ cmpb %cl, %al
+ jne L(set)
+ cmpl %ecx, %eax
+ jne L(set)
+ movzbl -1(%esi), %eax
+ cmpb -1(%edx), %al
+ jne L(set)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ xorl %eax, %eax
+ RETURN
+
+ cfi_adjust_cfa_offset (8)
+ cfi_rel_offset (esi, 0)
+ cfi_rel_offset (ebx, 4)
+ ALIGN (4)
+/* ECX >= 32. */
+L(32bytesormore):
+ subl $32, %ecx
+
+ movl (%esi), %eax
+ cmpl (%edx), %eax
+ jne L(load_ecx)
+
+ movl 4(%esi), %eax
+ cmpl 4(%edx), %eax
+ jne L(load_ecx_4)
+
+ movl 8(%esi), %eax
+ cmpl 8(%edx), %eax
+ jne L(load_ecx_8)
+
+ movl 12(%esi), %eax
+ cmpl 12(%edx), %eax
+ jne L(load_ecx_12)
+
+ movl 16(%esi), %eax
+ cmpl 16(%edx), %eax
+ jne L(load_ecx_16)
+
+ movl 20(%esi), %eax
+ cmpl 20(%edx), %eax
+ jne L(load_ecx_20)
+
+ movl 24(%esi), %eax
+ cmpl 24(%edx), %eax
+ jne L(load_ecx_24)
+
+ movl 28(%esi), %eax
+ cmpl 28(%edx), %eax
+ jne L(load_ecx_28)
+
+ addl $32, %esi
+ addl $32, %edx
+ cmpl $32, %ecx
+ jge L(32bytesormore)
+
+ LOAD_JUMP_TABLE_ENTRY (L(table_32bytes), %ecx)
+ addl %ecx, %edx
+ addl %ecx, %esi
+ jmp *%ebx
+
+L(load_ecx_28):
+ addl $0x4, %edx
+L(load_ecx_24):
+ addl $0x4, %edx
+L(load_ecx_20):
+ addl $0x4, %edx
+L(load_ecx_16):
+ addl $0x4, %edx
+L(load_ecx_12):
+ addl $0x4, %edx
+L(load_ecx_8):
+ addl $0x4, %edx
+L(load_ecx_4):
+ addl $0x4, %edx
+L(load_ecx):
+ movl (%edx), %ecx
+
+L(find_diff):
+ cmpb %cl, %al
+ jne L(set)
+ cmpb %ch, %ah
+ jne L(set)
+ shrl $16,%eax
+ shrl $16,%ecx
+ cmpb %cl, %al
+ jne L(set)
+ /* We get there only if we already know there is a
+ difference. */
+ cmpl %ecx, %eax
+L(set):
+ sbbl %eax, %eax
+ sbbl $-1, %eax
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ RETURN
+END (BP_SYM (memcmp))
+
+ .section .rodata
+ ALIGN (2)
+L(table_32bytes) :
+ .long L(0bytes) - . + 0x0
+ .long L(1bytes) - . + 0x4
+ .long L(2bytes) - . + 0x8
+ .long L(3bytes) - . + 0xc
+ .long L(4bytes) - . + 0x10
+ .long L(5bytes) - . + 0x14
+ .long L(6bytes) - . + 0x18
+ .long L(7bytes) - . + 0x1c
+ .long L(8bytes) - . + 0x20
+ .long L(9bytes) - . + 0x24
+ .long L(10bytes) - . + 0x28
+ .long L(11bytes) - . + 0x2c
+ .long L(12bytes) - . + 0x30
+ .long L(13bytes) - . + 0x34
+ .long L(14bytes) - . + 0x38
+ .long L(15bytes) - . + 0x3c
+ .long L(16bytes) - . + 0x40
+ .long L(17bytes) - . + 0x44
+ .long L(18bytes) - . + 0x48
+ .long L(19bytes) - . + 0x4c
+ .long L(20bytes) - . + 0x50
+ .long L(21bytes) - . + 0x54
+ .long L(22bytes) - . + 0x58
+ .long L(23bytes) - . + 0x5c
+ .long L(24bytes) - . + 0x60
+ .long L(25bytes) - . + 0x64
+ .long L(26bytes) - . + 0x68
+ .long L(27bytes) - . + 0x6c
+ .long L(28bytes) - . + 0x70
+ .long L(29bytes) - . + 0x74
+ .long L(30bytes) - . + 0x78
+ .long L(31bytes) - . + 0x7c
+
+
+#undef bcmp
+weak_alias (BP_SYM (memcmp), BP_SYM (bcmp))
+libc_hidden_builtin_def (BP_SYM (memcmp))
diff --git a/libc/sysdeps/i386/i686/memcpy.S b/libc/sysdeps/i386/i686/memcpy.S
new file mode 100644
index 000000000..00e84ec2e
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memcpy.S
@@ -0,0 +1,69 @@
+/* Copy memory block and return pointer to beginning of destination block
+ For Intel 80x86, x>=6.
+ This file is part of the GNU C Library.
+ Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#define SRC DEST+PTR_SIZE
+#define LEN SRC+PTR_SIZE
+
+ .text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__memcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memcpy_chk)
+#endif
+ENTRY (BP_SYM (memcpy))
+ ENTER
+
+ movl LEN(%esp), %ecx
+ movl %edi, %eax
+ movl DEST(%esp), %edi
+ movl %esi, %edx
+ movl SRC(%esp), %esi
+ CHECK_BOUNDS_BOTH_WIDE (%edi, DEST(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, SRC(%esp), %ecx)
+
+ cld
+ shrl $1, %ecx
+ jnc 1f
+ movsb
+1: shrl $1, %ecx
+ jnc 2f
+ movsw
+2: rep
+ movsl
+ movl %eax, %edi
+ movl %edx, %esi
+ movl DEST(%esp), %eax
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (memcpy))
+libc_hidden_builtin_def (memcpy)
diff --git a/libc/sysdeps/i386/i686/memcpy_chk.S b/libc/sysdeps/i386/i686/memcpy_chk.S
new file mode 100644
index 000000000..2893911cd
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memcpy_chk.S
@@ -0,0 +1,35 @@
+/* Checking memcpy for i686.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memcpy.S.
+ For libc.a, this is a separate source to avoid
+ memcpy bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp memcpy
+END (__memcpy_chk)
+#endif
diff --git a/libc/sysdeps/i386/i686/memmove.S b/libc/sysdeps/i386/i686/memmove.S
new file mode 100644
index 000000000..b93b5c729
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memmove.S
@@ -0,0 +1,115 @@
+/* Copy memory block and return pointer to beginning of destination block
+ For Intel 80x86, x>=6.
+ This file is part of the GNU C Library.
+ Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+4 /* one spilled register */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#define SRC DEST+PTR_SIZE
+#define LEN SRC+PTR_SIZE
+
+ .text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__memmove_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memmove_chk)
+#endif
+ENTRY (BP_SYM (memmove))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+
+ movl LEN(%esp), %ecx
+ movl DEST(%esp), %edi
+ cfi_rel_offset (edi, 0)
+ movl %esi, %edx
+ movl SRC(%esp), %esi
+ cfi_register (esi, edx)
+ CHECK_BOUNDS_BOTH_WIDE (%edi, DEST(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, SRC(%esp), %ecx)
+
+ movl %edi, %eax
+ subl %esi, %eax
+ cmpl %eax, %edi
+ jae 3f
+
+ cld
+ shrl $1, %ecx
+ jnc 1f
+ movsb
+1: shrl $1, %ecx
+ jnc 2f
+ movsw
+2: rep
+ movsl
+ movl %edx, %esi
+ cfi_restore (esi)
+ movl DEST(%esp), %eax
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (edi, 0)
+ cfi_register (esi, edx)
+
+ /* Backward copying. */
+3: std
+ leal -1(%edi, %ecx), %edi
+ leal -1(%esi, %ecx), %esi
+ shrl $1, %ecx
+ jnc 1f
+ movsb
+1: subl $1, %edi
+ subl $1, %esi
+ shrl $1, %ecx
+ jnc 2f
+ movsw
+2: subl $2, %edi
+ subl $2, %esi
+ rep
+ movsl
+ movl %edx, %esi
+ cfi_restore (esi)
+ movl DEST(%esp), %eax
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+
+ cld
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (memmove))
+libc_hidden_builtin_def (memmove)
diff --git a/libc/sysdeps/i386/i686/memmove_chk.S b/libc/sysdeps/i386/i686/memmove_chk.S
new file mode 100644
index 000000000..23382ea8b
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memmove_chk.S
@@ -0,0 +1,35 @@
+/* Checking memmove for x86-64.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memmove.S.
+ For libc.a, this is a separate source to avoid
+ memmove bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memmove_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp memmove
+END (__memmove_chk)
+#endif
diff --git a/libc/sysdeps/i386/i686/mempcpy.S b/libc/sysdeps/i386/i686/mempcpy.S
new file mode 100644
index 000000000..6437e4a5d
--- /dev/null
+++ b/libc/sysdeps/i386/i686/mempcpy.S
@@ -0,0 +1,73 @@
+/* Copy memory block and return pointer to following byte.
+ For Intel 80x86, x>=6.
+ This file is part of the GNU C Library.
+ Copyright (C) 1998,1999,2000,2002,2004,2005 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#define SRC DEST+PTR_SIZE
+#define LEN SRC+PTR_SIZE
+
+ .text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__mempcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__mempcpy_chk)
+#endif
+ENTRY (BP_SYM (__mempcpy))
+ ENTER
+
+ movl LEN(%esp), %ecx
+ movl %edi, %eax
+ cfi_register (edi, eax)
+ movl DEST(%esp), %edi
+ CHECK_BOUNDS_BOTH_WIDE (%edi, DEST(%esp), %ecx)
+ movl %esi, %edx
+ cfi_register (esi, edx)
+ movl SRC(%esp), %esi
+ CHECK_BOUNDS_BOTH_WIDE (%esi, SRC(%esp), %ecx)
+ cld
+ shrl $1, %ecx
+ jnc 1f
+ movsb
+1: shrl $1, %ecx
+ jnc 2f
+ movsw
+2: rep
+ movsl
+ xchgl %edi, %eax
+ cfi_restore (edi)
+ movl %edx, %esi
+ cfi_restore (esi)
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (__mempcpy))
+libc_hidden_def (BP_SYM (__mempcpy))
+weak_alias (BP_SYM (__mempcpy), BP_SYM (mempcpy))
+libc_hidden_builtin_def (mempcpy)
diff --git a/libc/sysdeps/i386/i686/mempcpy_chk.S b/libc/sysdeps/i386/i686/mempcpy_chk.S
new file mode 100644
index 000000000..dc9c6095f
--- /dev/null
+++ b/libc/sysdeps/i386/i686/mempcpy_chk.S
@@ -0,0 +1,35 @@
+/* Checking mempcpy for x86-64.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in mempcpy.S.
+ For libc.a, this is a separate source to avoid
+ mempcpy bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__mempcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp mempcpy
+END (__mempcpy_chk)
+#endif
diff --git a/libc/sysdeps/i386/i686/memset.S b/libc/sysdeps/i386/i686/memset.S
new file mode 100644
index 000000000..dfa1aa701
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memset.S
@@ -0,0 +1,113 @@
+/* memset/bzero -- set memory area to CH/0
+ Highly optimized version for ix86, x>=6.
+ Copyright (C) 1999,2000,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+/* BEWARE: `#ifdef memset' means that memset is redefined as `bzero' */
+#define BZERO_P (defined memset)
+
+#define PARMS LINKAGE+4 /* space for 1 saved reg */
+#if BZERO_P
+# define DEST PARMS
+# define LEN DEST+PTR_SIZE
+#else
+# define RTN PARMS
+# define DEST RTN+RTN_SIZE
+# define CHR DEST+PTR_SIZE
+# define LEN CHR+4
+#endif
+
+ .text
+#if defined PIC && !defined NOT_IN_libc && !BZERO_P
+ENTRY (__memset_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memset_chk)
+#endif
+ENTRY (BP_SYM (memset))
+ ENTER
+
+ cld
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ movl DEST(%esp), %edx
+ movl LEN(%esp), %ecx
+ CHECK_BOUNDS_BOTH_WIDE (%edx, DEST(%esp), %ecx)
+#if BZERO_P
+ xorl %eax, %eax /* fill with 0 */
+#else
+ movzbl CHR(%esp), %eax
+#endif
+ jecxz 1f
+ movl %edx, %edi
+ cfi_rel_offset (edi, 0)
+ andl $3, %edx
+ jz 2f /* aligned */
+ jp 3f /* misaligned at 3, store just one byte below */
+ stosb /* misaligned at 1 or 2, store two bytes */
+ decl %ecx
+ jz 1f
+3: stosb
+ decl %ecx
+ jz 1f
+ xorl $1, %edx
+ jnz 2f /* was misaligned at 2 or 3, now aligned */
+ stosb /* was misaligned at 1, store third byte */
+ decl %ecx
+2: movl %ecx, %edx
+ shrl $2, %ecx
+ andl $3, %edx
+#if !BZERO_P
+ imul $0x01010101, %eax
+#endif
+ rep
+ stosl
+ movl %edx, %ecx
+ rep
+ stosb
+
+1:
+#if !BZERO_P
+ movl DEST(%esp), %eax /* start address of destination is result */
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+#endif
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+#if BZERO_P
+ ret
+#else
+ RET_PTR
+#endif
+END (BP_SYM (memset))
+libc_hidden_builtin_def (memset)
+
+#if defined PIC && !defined NOT_IN_libc && !BZERO_P
+strong_alias (__memset_chk, __memset_zero_constant_len_parameter)
+ .section .gnu.warning.__memset_zero_constant_len_parameter
+ .string "memset used with constant zero length parameter; this could be due to transposed parameters"
+#endif
diff --git a/libc/sysdeps/i386/i686/memset_chk.S b/libc/sysdeps/i386/i686/memset_chk.S
new file mode 100644
index 000000000..cd93d5ee1
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memset_chk.S
@@ -0,0 +1,35 @@
+/* Checking memset for i686.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memset.S.
+ For libc.a, this is a separate source to avoid
+ memset bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memset_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp memset
+END (__memset_chk)
+#endif
diff --git a/libc/sysdeps/i386/i686/memusage.h b/libc/sysdeps/i386/i686/memusage.h
new file mode 100644
index 000000000..235c3fc72
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memusage.h
@@ -0,0 +1,22 @@
+/* Copyright (C) 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("esp"); stack_ptr; })
+#define GETTIME(low,high) asm ("rdtsc" : "=a" (low), "=d" (high))
+
+#include <sysdeps/generic/memusage.h>
diff --git a/libc/sysdeps/i386/i686/strcmp.S b/libc/sysdeps/i386/i686/strcmp.S
new file mode 100644
index 000000000..8601c1ca0
--- /dev/null
+++ b/libc/sysdeps/i386/i686/strcmp.S
@@ -0,0 +1,72 @@
+/* Highly optimized version for ix86, x>=6.
+ Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define STR1 PARMS
+#define STR2 STR1+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (strcmp))
+ ENTER
+
+ movl STR1(%esp), %ecx
+ movl STR2(%esp), %edx
+ CHECK_BOUNDS_LOW (%ecx, STR1(%esp))
+ CHECK_BOUNDS_LOW (%edx, STR2(%esp))
+
+L(oop): movb (%ecx), %al
+ cmpb (%edx), %al
+ jne L(neq)
+ incl %ecx
+ incl %edx
+ testb %al, %al
+ jnz L(oop)
+
+ xorl %eax, %eax
+ /* when strings are equal, pointers rest one beyond
+ the end of the NUL terminators. */
+ CHECK_BOUNDS_HIGH (%ecx, STR1(%esp), jbe)
+ CHECK_BOUNDS_HIGH (%edx, STR2(%esp), jbe)
+ LEAVE
+ ret
+
+#ifndef __BOUNDED_POINTERS__
+L(neq): movl $1, %eax
+ movl $-1, %ecx
+ cmovbl %ecx, %eax
+#else
+L(neq): movl $1, %eax
+ ja L(chk)
+ negl %eax
+ /* When strings differ, pointers rest on
+ the unequal characters. */
+L(chk): CHECK_BOUNDS_HIGH (%ecx, STR1(%esp), jb)
+ CHECK_BOUNDS_HIGH (%edx, STR2(%esp), jb)
+#endif
+
+ LEAVE
+ ret
+END (BP_SYM (strcmp))
+libc_hidden_builtin_def (strcmp)
diff --git a/libc/sysdeps/i386/i686/strtok.S b/libc/sysdeps/i386/i686/strtok.S
new file mode 100644
index 000000000..fe225e548
--- /dev/null
+++ b/libc/sysdeps/i386/i686/strtok.S
@@ -0,0 +1,281 @@
+/* strtok (str, delim) -- Return next DELIM separated token from STR.
+ For Intel 80686.
+ Copyright (C) 1998, 2000, 2001, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+/* This file can be used for three variants of the strtok function:
+
+ strtok:
+ INPUT PARAMETER:
+ str (sp + 4)
+ delim (sp + 8)
+
+ strtok_r:
+ INPUT PARAMETER:
+ str (sp + 4)
+ delim (sp + 8)
+ save_ptr (sp + 12)
+
+ We do a common implementation here. */
+
+#ifdef USE_AS_STRTOK_R
+# define SAVE_PTR 0(%ecx)
+#else
+ .bss
+ .local save_ptr
+ ASM_TYPE_DIRECTIVE (save_ptr, @object)
+ .size save_ptr, 4
+save_ptr:
+# if __BOUNDED_POINTERS__
+ .space 12
+# else
+ .space 4
+# endif
+
+# ifdef PIC
+# define SAVE_PTR save_ptr@GOTOFF(%ebx)
+# else
+# define SAVE_PTR save_ptr
+# endif
+
+# define FUNCTION strtok
+#endif
+
+#if !defined USE_AS_STRTOK_R && defined PIC
+# define PARMS LINKAGE+256+4 /* space for table and saved PIC register */
+#else
+# define PARMS LINKAGE+256 /* space for table */
+#endif
+#define RTN PARMS
+#define STR RTN+RTN_SIZE
+#define DELIM STR+PTR_SIZE
+#ifdef USE_AS_STRTOK_R
+# define SAVE DELIM+PTR_SIZE
+#endif
+
+ .text
+
+#if !defined USE_AS_STRTOK_R && defined PIC
+0: movl (%esp), %ebx
+ ret
+#endif
+
+ENTRY (BP_SYM (FUNCTION))
+ ENTER
+
+#if !defined USE_AS_STRTOK_R && defined PIC
+ pushl %ebx /* Save PIC register. */
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebx, 0)
+ call 0b
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+#endif
+
+ /* First we create a table with flags for all possible characters.
+ For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
+ supported by the C string functions we have 256 characters.
+ Before inserting marks for the stop characters we clear the whole
+ table. */
+ movl %edi, %edx
+ subl $256, %esp
+ cfi_adjust_cfa_offset (256)
+ movl $64, %ecx
+ movl %esp, %edi
+ xorl %eax, %eax
+ cld
+ rep
+ stosl
+
+ /* Note: %ecx = 0 !!! */
+ movl %edx, %edi
+
+ movl STR(%esp), %edx /* Get start of string. */
+
+#ifdef USE_AS_STRTOK_R
+ /* The value is stored in the third argument. */
+ movl SAVE(%esp), %eax
+ movl (%eax), %eax
+#else
+ /* The value is in the local variable defined above. But
+ we have to take care for PIC code. */
+ movl SAVE_PTR, %eax
+#endif
+
+ /* If the pointer is NULL we have to use the stored value of
+ the last run. */
+ cmpl $0, %edx
+ cmove %eax, %edx
+ testl %edx, %edx
+ jz L(returnNULL)
+#if __BOUNDED_POINTERS__
+# ifdef USE_AS_STRTOK_R
+ movl SAVE(%esp), %ecx /* borrow %ecx for a moment */
+# endif
+ je L(0)
+ /* Save bounds of incoming non-NULL STR into save area. */
+ movl 4+STR(%esp), %eax
+ movl %eax, 4+SAVE_PTR
+ movl 8+STR(%esp), %eax
+ movl %eax, 8+SAVE_PTR
+L(0): CHECK_BOUNDS_LOW (%edx, SAVE_PTR)
+# ifdef USE_AS_STRTOK_R
+ xorl %ecx, %ecx /* restore %ecx to zero */
+# endif
+#endif
+ movl DELIM(%esp), %eax /* Get start of delimiter set. */
+ CHECK_BOUNDS_LOW (%eax, DELIM(%esp))
+
+/* For understanding the following code remember that %ecx == 0 now.
+ Although all the following instruction only modify %cl we always
+ have a correct zero-extended 32-bit value in %ecx. */
+
+L(2): movb (%eax), %cl /* get byte from stopset */
+ testb %cl, %cl /* is NUL char? */
+ jz L(1_1) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 1(%eax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1_2) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 2(%eax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1_3) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 3(%eax), %cl /* get byte from stopset */
+ addl $4, %eax /* increment stopset pointer */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+ testb $0xff, %cl /* is NUL char? */
+ jnz L(2) /* no => process next dword from stopset */
+
+#if __BOUNDED_POINTERS__
+ jmp L(1_0) /* pointer is correct for bounds check */
+L(1_3): incl %eax /* adjust pointer for bounds check */
+L(1_2): incl %eax /* ditto */
+L(1_1): incl %eax /* ditto */
+L(1_0): CHECK_BOUNDS_HIGH (%eax, DELIM(%esp), jbe)
+#else
+L(1_3):; L(1_2):; L(1_1): /* fall through */
+#endif
+ leal -4(%edx), %eax /* prepare loop */
+
+ /* We use a neat trick for the following loop. Normally we would
+ have to test for two termination conditions
+ 1. a character in the stopset was found
+ and
+ 2. the end of the string was found
+ As a sign that the character is in the stopset we store its
+ value in the table. The value of NUL is NUL so the loop
+ terminates for NUL in every case. */
+
+L(3): addl $4, %eax /* adjust pointer for full loop round */
+
+ movb (%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jz L(4) /* no => start of token */
+
+ movb 1(%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jz L(5) /* no => start of token */
+
+ movb 2(%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jz L(6) /* no => start of token */
+
+ movb 3(%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jnz L(3) /* yes => start of loop */
+
+ incl %eax /* adjust pointer */
+L(6): incl %eax
+L(5): incl %eax
+
+ /* Now we have to terminate the string. */
+
+L(4): leal -4(%eax), %edx /* We use %EDX for the next run. */
+
+L(7): addl $4, %edx /* adjust pointer for full loop round */
+
+ movb (%edx), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ je L(8) /* yes => return */
+
+ movb 1(%edx), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ je L(9) /* yes => return */
+
+ movb 2(%edx), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ je L(10) /* yes => return */
+
+ movb 3(%edx), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ jne L(7) /* no => start loop again */
+
+ incl %edx /* adjust pointer */
+L(10): incl %edx
+L(9): incl %edx
+
+L(8): cmpl %eax, %edx
+ je L(returnNULL) /* There was no token anymore. */
+
+ movb $0, (%edx) /* Terminate string. */
+
+ /* Are we at end of string? */
+ cmpb $0, %cl
+ leal 1(%edx), %ecx
+ cmovne %ecx, %edx
+
+ /* Store the pointer to the next character. */
+#ifdef USE_AS_STRTOK_R
+ movl SAVE(%esp), %ecx
+#endif
+ movl %edx, SAVE_PTR
+ CHECK_BOUNDS_HIGH (%edx, SAVE_PTR, jb)
+ RETURN_BOUNDED_POINTER (SAVE_PTR)
+
+L(epilogue):
+ /* Remove the stopset table. */
+ addl $256, %esp
+ cfi_adjust_cfa_offset (-256)
+#if !defined USE_AS_STRTOK_R && defined PIC
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+#endif
+ LEAVE
+ RET_PTR
+
+L(returnNULL):
+ xorl %eax, %eax
+#ifdef USE_AS_STRTOK_R
+ movl SAVE(%esp), %ecx
+#endif
+ movl %edx, SAVE_PTR
+ RETURN_NULL_BOUNDED_POINTER
+ jmp L(epilogue)
+
+END (BP_SYM (FUNCTION))
diff --git a/libc/sysdeps/i386/i686/strtok_r.S b/libc/sysdeps/i386/i686/strtok_r.S
new file mode 100644
index 000000000..1c24ca85f
--- /dev/null
+++ b/libc/sysdeps/i386/i686/strtok_r.S
@@ -0,0 +1,5 @@
+#define FUNCTION __strtok_r
+#define USE_AS_STRTOK_R 1
+#include <sysdeps/i386/i686/strtok.S>
+weak_alias (BP_SYM (__strtok_r), BP_SYM (strtok_r))
+strong_alias (BP_SYM (__strtok_r), BP_SYM (__GI___strtok_r))
diff --git a/libc/sysdeps/i386/i686/tst-stack-align.h b/libc/sysdeps/i386/i686/tst-stack-align.h
new file mode 100644
index 000000000..e1894c65e
--- /dev/null
+++ b/libc/sysdeps/i386/i686/tst-stack-align.h
@@ -0,0 +1,45 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __SSE__
+#include_next <tst-stack-align.h>
+#else
+#include <xmmintrin.h>
+
+#define TEST_STACK_ALIGN() \
+ ({ \
+ __m128 _m; \
+ double _d = 12.0; \
+ long double _ld = 15.0; \
+ int _ret = 0; \
+ printf ("__m128: %p %zu\n", &_m, __alignof (__m128)); \
+ if ((((uintptr_t) &_m) & (__alignof (__m128) - 1)) != 0) \
+ _ret = 1; \
+ \
+ printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
+ if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
+ _ret = 1; \
+ \
+ printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
+ if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
+ _ret = 1; \
+ _ret; \
+ })
+#endif
diff --git a/libc/sysdeps/i386/i786/Implies b/libc/sysdeps/i386/i786/Implies
new file mode 100644
index 000000000..1cd29f63c
--- /dev/null
+++ b/libc/sysdeps/i386/i786/Implies
@@ -0,0 +1,2 @@
+# The PPro and PII cores are mostly the same.
+i386/i686
diff --git a/libc/sysdeps/i386/init-first.c b/libc/sysdeps/i386/init-first.c
new file mode 100644
index 000000000..c6355a8b7
--- /dev/null
+++ b/libc/sysdeps/i386/init-first.c
@@ -0,0 +1,73 @@
+/* Initialization code run first thing by the ELF startup code. For i386/Unix.
+ Copyright (C) 1995,1996,1997,2000,2001,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+
+extern void __libc_init (int, char **, char **);
+#ifdef USE_NONOPTION_FLAGS
+extern void __getopt_clean_environment (char **);
+#endif
+extern void __libc_global_ctors (void);
+
+int __libc_multiple_libcs attribute_hidden = 1;
+
+static void
+init (int *data)
+{
+ int argc = *data;
+ char **argv = (void *) (data + 1);
+ char **envp = &argv[argc + 1];
+
+ __environ = envp;
+ __libc_init (argc, argv, envp);
+
+#ifdef USE_NONOPTION_FLAGS
+ /* This is a hack to make the special getopt in GNU libc working. */
+ __getopt_clean_environment (envp);
+#endif
+}
+
+#ifdef SHARED
+/* This function is called to initialize the shared C library.
+ It is called just before the user _start code from i386/elf/start.S,
+ with the stack set up as that code gets it. */
+
+/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
+ pointer in the dynamic section based solely on that. It is convention
+ for this function to be in the `.init' section, but the symbol name is
+ the only thing that really matters!! */
+/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/
+
+void
+_init (int argc, ...)
+{
+ init (&argc);
+
+ __libc_global_ctors ();
+}
+#endif
+
+
+void
+__libc_init_first (int argc __attribute__ ((unused)), ...)
+{
+#ifndef SHARED
+ init (&argc);
+#endif
+}
diff --git a/libc/sysdeps/i386/jmpbuf-offsets.h b/libc/sysdeps/i386/jmpbuf-offsets.h
new file mode 100644
index 000000000..c53d539ed
--- /dev/null
+++ b/libc/sysdeps/i386/jmpbuf-offsets.h
@@ -0,0 +1,26 @@
+/* Private macros for accessing __jmp_buf contents. i386 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define JB_BX 0
+#define JB_SI 1
+#define JB_DI 2
+#define JB_BP 3
+#define JB_SP 4
+#define JB_PC 5
+#define JB_SIZE 24
diff --git a/libc/sysdeps/i386/jmpbuf-unwind.h b/libc/sysdeps/i386/jmpbuf-unwind.h
new file mode 100644
index 000000000..360493fb3
--- /dev/null
+++ b/libc/sysdeps/i386/jmpbuf-unwind.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <stdint.h>
+#include <unwind.h>
+#include <sysdep.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame
+ containing a local variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \
+ ((void *) (address) < (void *) demangle ((jmpbuf)[JB_SP]))
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+static inline uintptr_t __attribute__ ((unused))
+_jmpbuf_sp (__jmp_buf regs)
+{
+ uintptr_t sp = regs[JB_SP];
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (sp);
+#endif
+ return sp;
+}
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
+
+/* We use the normal longjmp for unwinding. */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libc/sysdeps/i386/ldbl2mpn.c b/libc/sysdeps/i386/ldbl2mpn.c
new file mode 100644
index 000000000..bf4e4ff43
--- /dev/null
+++ b/libc/sysdeps/i386/ldbl2mpn.c
@@ -0,0 +1,114 @@
+/* Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "ieee754.h"
+#include <float.h>
+#include <stdlib.h>
+
+/* Convert a `long double' in IEEE854 standard double-precision format to a
+ multi-precision integer representing the significand scaled up by its
+ number of bits (64 for long double) and an integral power of two
+ (MPN frexpl). */
+
+mp_size_t
+__mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
+ int *expt, int *is_neg,
+ long double value)
+{
+ union ieee854_long_double u;
+ u.d = value;
+
+ *is_neg = u.ieee.negative;
+ *expt = (int) u.ieee.exponent - IEEE854_LONG_DOUBLE_BIAS;
+
+#if BITS_PER_MP_LIMB == 32
+ res_ptr[0] = u.ieee.mantissa1; /* Low-order 32 bits of fraction. */
+ res_ptr[1] = u.ieee.mantissa0; /* High-order 32 bits. */
+ #define N 2
+#elif BITS_PER_MP_LIMB == 64
+ /* Hopefully the compiler will combine the two bitfield extracts
+ and this composition into just the original quadword extract. */
+ res_ptr[0] = ((unsigned long int) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
+ #define N 1
+#else
+ #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+
+ if (u.ieee.exponent == 0)
+ {
+ /* A biased exponent of zero is a special case.
+ Either it is a zero or it is a denormal number. */
+ if (res_ptr[0] == 0 && res_ptr[N - 1] == 0) /* Assumes N<=2. */
+ /* It's zero. */
+ *expt = 0;
+ else
+ {
+ /* It is a denormal number, meaning it has no implicit leading
+ one bit, and its exponent is in fact the format minimum. */
+ int cnt;
+
+ /* One problem with Intel's 80-bit format is that the explicit
+ leading one in the normalized representation has to be zero
+ for denormalized number. If it is one, the number is according
+ to Intel's specification an invalid number. We make the
+ representation unique by explicitly clearing this bit. */
+ res_ptr[N - 1] &= ~(1L << ((LDBL_MANT_DIG - 1) % BITS_PER_MP_LIMB));
+
+ if (res_ptr[N - 1] != 0)
+ {
+ count_leading_zeros (cnt, res_ptr[N - 1]);
+ if (cnt != 0)
+ {
+#if N == 2
+ res_ptr[N - 1] = res_ptr[N - 1] << cnt
+ | (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt));
+ res_ptr[0] <<= cnt;
+#else
+ res_ptr[N - 1] <<= cnt;
+#endif
+ }
+ *expt = LDBL_MIN_EXP - 1 - cnt;
+ }
+ else if (res_ptr[0] != 0)
+ {
+ count_leading_zeros (cnt, res_ptr[0]);
+ res_ptr[N - 1] = res_ptr[0] << cnt;
+ res_ptr[0] = 0;
+ *expt = LDBL_MIN_EXP - 1 - BITS_PER_MP_LIMB - cnt;
+ }
+ else
+ {
+ /* This is the special case of the pseudo denormal number
+ with only the implicit leading bit set. The value is
+ in fact a normal number and so we have to treat this
+ case differently. */
+#if N == 2
+ res_ptr[N - 1] = 0x80000000ul;
+#else
+ res_ptr[0] = 0x8000000000000000ul;
+#endif
+ *expt = LDBL_MIN_EXP - 1;
+ }
+ }
+ }
+
+ return N;
+}
diff --git a/libc/sysdeps/i386/lshift.S b/libc/sysdeps/i386/lshift.S
new file mode 100644
index 000000000..536d9878e
--- /dev/null
+++ b/libc/sysdeps/i386/lshift.S
@@ -0,0 +1,113 @@
+/* i80386 __mpn_lshift --
+ Copyright (C) 1992, 1994, 1997-2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+12 /* space for 3 saved regs */
+#define RES PARMS
+#define S RES+PTR_SIZE
+#define SIZE S+PTR_SIZE
+#define CNT SIZE+4
+
+ .text
+ENTRY (BP_SYM (__mpn_lshift))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp),%edi
+ cfi_rel_offset (edi, 8)
+ movl S(%esp),%esi
+ cfi_rel_offset (esi, 4)
+ movl SIZE(%esp),%edx
+ movl CNT(%esp),%ecx
+#if __BOUNDED_POINTERS__
+ shll $2, %edx /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %edx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, S(%esp), %edx)
+ shrl $2, %edx
+#endif
+ subl $4,%esi /* adjust s_ptr */
+
+ movl (%esi,%edx,4),%ebx /* read most significant limb */
+ cfi_rel_offset (ebx, 0)
+ xorl %eax,%eax
+ shldl %cl,%ebx,%eax /* compute carry limb */
+ decl %edx
+ jz L(end)
+ pushl %eax /* push carry limb onto stack */
+ cfi_adjust_cfa_offset (4)
+ testb $1,%dl
+ jnz L(1) /* enter loop in the middle */
+ movl %ebx,%eax
+
+ ALIGN (3)
+L(oop): movl (%esi,%edx,4),%ebx /* load next lower limb */
+ shldl %cl,%ebx,%eax /* compute result limb */
+ movl %eax,(%edi,%edx,4) /* store it */
+ decl %edx
+L(1): movl (%esi,%edx,4),%eax
+ shldl %cl,%eax,%ebx
+ movl %ebx,(%edi,%edx,4)
+ decl %edx
+ jnz L(oop)
+
+ shll %cl,%eax /* compute least significant limb */
+ movl %eax,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+ cfi_adjust_cfa_offset (-4)
+
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+
+L(end): shll %cl,%ebx /* compute least significant limb */
+ movl %ebx,(%edi) /* store it */
+
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+END (BP_SYM (__mpn_lshift))
diff --git a/libc/sysdeps/i386/machine-gmon.h b/libc/sysdeps/i386/machine-gmon.h
new file mode 100644
index 000000000..21aba79f3
--- /dev/null
+++ b/libc/sysdeps/i386/machine-gmon.h
@@ -0,0 +1,41 @@
+/* i386-specific implementation of profiling support.
+ Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* We need a special version of the `mcount' function since for ix86 it
+ must not clobber any register. This has several reasons:
+ - there is a bug in gcc as of version 2.7.2.2 which prohibits the
+ use of profiling together with nested functions
+ - the ELF `fixup' function uses GCC's regparm feature
+ - some (future) systems might want to pass parameters in registers. */
+
+/* We must not pollute the global namespace. */
+#define mcount_internal __mcount_internal
+
+extern void mcount_internal (u_long frompc, u_long selfpc) internal_function;
+
+#define _MCOUNT_DECL(frompc, selfpc) \
+void internal_function mcount_internal (u_long frompc, u_long selfpc)
+
+
+/* Define MCOUNT as empty since we have the implementation in another
+ file. */
+#define MCOUNT
diff --git a/libc/sysdeps/i386/memchr.S b/libc/sysdeps/i386/memchr.S
new file mode 100644
index 000000000..08989397b
--- /dev/null
+++ b/libc/sysdeps/i386/memchr.S
@@ -0,0 +1,340 @@
+/* memchr (str, chr, len) -- Return pointer to first occurrence of CHR in STR
+ less than LEN. For Intel 80x86, x>=3.
+ Copyright (C) 1994-1998, 2000, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+ Optimised a little by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>
+ This version is developed using the same algorithm as the fast C
+ version which carries the following introduction:
+ Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+ with help from Dan Sahlin (dan@sics.se) and
+ commentary by Jim Blandy (jimb@ai.mit.edu);
+ adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+ and implemented by Roland McGrath (roland@ai.mit.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+8 /* space for 2 saved regs */
+#define RTN PARMS
+#define STR RTN+RTN_SIZE
+#define CHR STR+PTR_SIZE
+#define LEN CHR+4
+
+ .text
+ENTRY (BP_SYM (__memchr))
+ ENTER
+
+ /* Save callee-safe registers used in this function. */
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (edi, 0)
+
+ /* Load parameters into registers. */
+ movl STR(%esp), %eax /* str: pointer to memory block. */
+ movl CHR(%esp), %edx /* c: byte we are looking for. */
+ movl LEN(%esp), %esi /* len: length of memory block. */
+ cfi_rel_offset (esi, 4)
+ CHECK_BOUNDS_LOW (%eax, STR(%esp))
+
+ /* If my must not test more than three characters test
+ them one by one. This is especially true for 0. */
+ cmpl $4, %esi
+ jb L(3)
+
+ /* At the moment %edx contains CHR. What we need for the
+ algorithm is CHR in all bytes of the dword. Avoid
+ operations on 16 bit words because these require an
+ prefix byte (and one more cycle). */
+ movb %dl, %dh /* Now it is 0|0|c|c */
+ movl %edx, %ecx
+ shll $16, %edx /* Now c|c|0|0 */
+ movw %cx, %dx /* And finally c|c|c|c */
+
+ /* Better performance can be achieved if the word (32
+ bit) memory access is aligned on a four-byte-boundary.
+ So process first bytes one by one until boundary is
+ reached. Don't use a loop for better performance. */
+
+ testb $3, %al /* correctly aligned ? */
+ je L(2) /* yes => begin loop */
+ cmpb %dl, (%eax) /* compare byte */
+ je L(9) /* target found => return */
+ incl %eax /* increment source pointer */
+ decl %esi /* decrement length counter */
+ je L(4) /* len==0 => return NULL */
+
+ testb $3, %al /* correctly aligned ? */
+ je L(2) /* yes => begin loop */
+ cmpb %dl, (%eax) /* compare byte */
+ je L(9) /* target found => return */
+ incl %eax /* increment source pointer */
+ decl %esi /* decrement length counter */
+ je L(4) /* len==0 => return NULL */
+
+ testb $3, %al /* correctly aligned ? */
+ je L(2) /* yes => begin loop */
+ cmpb %dl, (%eax) /* compare byte */
+ je L(9) /* target found => return */
+ incl %eax /* increment source pointer */
+ decl %esi /* decrement length counter */
+ /* no test for len==0 here, because this is done in the
+ loop head */
+ jmp L(2)
+
+ /* We exit the loop if adding MAGIC_BITS to LONGWORD fails to
+ change any of the hole bits of LONGWORD.
+
+ 1) Is this safe? Will it catch all the zero bytes?
+ Suppose there is a byte with all zeros. Any carry bits
+ propagating from its left will fall into the hole at its
+ least significant bit and stop. Since there will be no
+ carry from its most significant bit, the LSB of the
+ byte to the left will be unchanged, and the zero will be
+ detected.
+
+ 2) Is this worthwhile? Will it ignore everything except
+ zero bytes? Suppose every byte of LONGWORD has a bit set
+ somewhere. There will be a carry into bit 8. If bit 8
+ is set, this will carry into bit 16. If bit 8 is clear,
+ one of bits 9-15 must be set, so there will be a carry
+ into bit 16. Similarly, there will be a carry into bit
+ 24. If one of bits 24-31 is set, there will be a carry
+ into bit 32 (=carry flag), so all of the hole bits will
+ be changed.
+
+ 3) But wait! Aren't we looking for CHR, not zero?
+ Good point. So what we do is XOR LONGWORD with a longword,
+ each of whose bytes is CHR. This turns each byte that is CHR
+ into a zero. */
+
+
+ /* Each round the main loop processes 16 bytes. */
+
+ ALIGN (4)
+
+L(1): movl (%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+
+ /* According to the algorithm we had to reverse the effect of the
+ XOR first and then test the overflow bits. But because the
+ following XOR would destroy the carry flag and it would (in a
+ representation with more than 32 bits) not alter then last
+ overflow, we can now test this condition. If no carry is signaled
+ no overflow must have occurred in the last byte => it was 0. */
+ jnc L(8)
+
+ /* We are only interested in carry bits that change due to the
+ previous add, so remove original bits */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+
+ /* Now test for the other three overflow bits. */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ /* If at least one byte of the word is CHR we don't get 0 in %edi. */
+ jnz L(8) /* found it => return pointer */
+
+ /* This process is unfolded four times for better performance.
+ we don't increment the source pointer each time. Instead we
+ use offsets and increment by 16 in each run of the loop. But
+ before probing for the matching byte we need some extra code
+ (following LL(13) below). Even the len can be compared with
+ constants instead of decrementing each time. */
+
+ movl 4(%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(7) /* highest byte is CHR => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(7) /* found it => return pointer */
+
+ movl 8(%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(6) /* highest byte is CHR => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(6) /* found it => return pointer */
+
+ movl 12(%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(5) /* highest byte is CHR => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(5) /* found it => return pointer */
+
+ /* Adjust both counters for a full round, i.e. 16 bytes. */
+ addl $16, %eax
+L(2): subl $16, %esi
+ jae L(1) /* Still more than 16 bytes remaining */
+
+ /* Process remaining bytes separately. */
+ cmpl $4-16, %esi /* rest < 4 bytes? */
+ jb L(3) /* yes, than test byte by byte */
+
+ movl (%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(8) /* highest byte is CHR => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jne L(8) /* found it => return pointer */
+ addl $4, %eax /* adjust source pointer */
+
+ cmpl $8-16, %esi /* rest < 8 bytes? */
+ jb L(3) /* yes, than test byte by byte */
+
+ movl (%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(8) /* highest byte is CHR => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jne L(8) /* found it => return pointer */
+ addl $4, %eax /* adjust source pointer */
+
+ cmpl $12-16, %esi /* rest < 12 bytes? */
+ jb L(3) /* yes, than test byte by byte */
+
+ movl (%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(8) /* highest byte is CHR => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jne L(8) /* found it => return pointer */
+ addl $4, %eax /* adjust source pointer */
+
+ /* Check the remaining bytes one by one. */
+L(3): andl $3, %esi /* mask out uninteresting bytes */
+ jz L(4) /* no remaining bytes => return NULL */
+
+ cmpb %dl, (%eax) /* compare byte with CHR */
+ je L(9) /* equal, than return pointer */
+ incl %eax /* increment source pointer */
+ decl %esi /* decrement length */
+ jz L(4) /* no remaining bytes => return NULL */
+
+ cmpb %dl, (%eax) /* compare byte with CHR */
+ je L(9) /* equal, than return pointer */
+ incl %eax /* increment source pointer */
+ decl %esi /* decrement length */
+ jz L(4) /* no remaining bytes => return NULL */
+
+ cmpb %dl, (%eax) /* compare byte with CHR */
+ je L(9) /* equal, than return pointer */
+
+L(4): /* no byte found => return NULL */
+ xorl %eax, %eax
+ jmp L(9)
+
+ /* add missing source pointer increments */
+L(5): addl $4, %eax
+L(6): addl $4, %eax
+L(7): addl $4, %eax
+
+ /* Test for the matching byte in the word. %ecx contains a NUL
+ char in the byte which originally was the byte we are looking
+ at. */
+L(8): testb %cl, %cl /* test first byte in dword */
+ jz L(9) /* if zero => return pointer */
+ incl %eax /* increment source pointer */
+
+ testb %ch, %ch /* test second byte in dword */
+ jz L(9) /* if zero => return pointer */
+ incl %eax /* increment source pointer */
+
+ testl $0xff0000, %ecx /* test third byte in dword */
+ jz L(9) /* if zero => return pointer */
+ incl %eax /* increment source pointer */
+
+ /* No further test needed we we know it is one of the four bytes. */
+L(9):
+#if __BOUNDED_POINTERS__
+ CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
+ /* If RTN pointer is phony, don't copy return value into it. */
+ movl RTN(%esp), %ecx
+ testl %ecx, %ecx
+ jz L(pop)
+ RETURN_BOUNDED_POINTER (STR(%esp))
+#endif
+L(pop): popl %edi /* pop saved registers */
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (__memchr))
+
+weak_alias (BP_SYM (__memchr), BP_SYM (memchr))
+#if !__BOUNDED_POINTERS__
+weak_alias (__memchr, __ubp_memchr)
+#endif
+libc_hidden_builtin_def (memchr)
diff --git a/libc/sysdeps/i386/memcmp.S b/libc/sysdeps/i386/memcmp.S
new file mode 100644
index 000000000..60b75126b
--- /dev/null
+++ b/libc/sysdeps/i386/memcmp.S
@@ -0,0 +1,82 @@
+/* Compare two memory blocks for differences in the first COUNT bytes.
+ Copyright (C) 1995,1996,1997,2000,2004,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+4 /* space for 1 saved reg */
+#define BLK1 PARMS
+#define BLK2 BLK1+PTR_SIZE
+#define LEN BLK2+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (memcmp))
+ ENTER
+
+ pushl %esi /* Save callee-safe registers. */
+ cfi_adjust_cfa_offset (4)
+ movl %edi, %edx /* Note that %edx is not used and can
+ so be used to save %edi. It's faster. */
+ cfi_register (edi, edx)
+
+ movl BLK1(%esp), %esi
+ cfi_rel_offset (esi, 0)
+ movl BLK2(%esp), %edi
+ movl LEN(%esp), %ecx
+ CHECK_BOUNDS_LOW (%esi, BLK1(%esp))
+ CHECK_BOUNDS_LOW (%edi, BLK2(%esp))
+
+ cld /* Set direction of comparison. */
+
+ xorl %eax, %eax /* Default result. */
+
+ repe /* Compare at most %ecx bytes. */
+ cmpsb
+ jz L(1) /* If even last byte was equal we return 0. */
+
+ /* The memory blocks are not equal. So result of the last
+ subtraction is present in the carry flag. It is set when
+ the byte in block #2 is bigger. In this case we have to
+ return -1 (=0xffffffff), else 1. */
+ sbbl %eax, %eax /* This is tricky. %eax == 0 and carry is set
+ or not depending on last subtraction. */
+
+ /* At this point %eax == 0, if the byte of block #1 was bigger, and
+ 0xffffffff if the last byte of block #2 was bigger. The latter
+ case is already correct but the former needs a little adjustment.
+ Note that the following operation does not change 0xffffffff. */
+ orb $1, %al /* Change 0 to 1. */
+
+L(1): CHECK_BOUNDS_HIGH (%esi, BLK1(%esp), jbe)
+ CHECK_BOUNDS_HIGH (%edi, BLK2(%esp), jbe)
+ popl %esi /* Restore registers. */
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ movl %edx, %edi
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+END (BP_SYM (memcmp))
+
+#undef bcmp
+weak_alias (BP_SYM (memcmp), BP_SYM (bcmp))
+libc_hidden_builtin_def (BP_SYM (memcmp))
diff --git a/libc/sysdeps/i386/memcopy.h b/libc/sysdeps/i386/memcopy.h
new file mode 100644
index 000000000..7f4e20865
--- /dev/null
+++ b/libc/sysdeps/i386/memcopy.h
@@ -0,0 +1,93 @@
+/* memcopy.h -- definitions for memory copy functions. i386 version.
+ Copyright (C) 1991, 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/memcopy.h>
+
+#undef OP_T_THRES
+#define OP_T_THRES 8
+
+#undef BYTE_COPY_FWD
+#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \
+ do { \
+ int __d0; \
+ asm volatile(/* Clear the direction flag, so copying goes forward. */ \
+ "cld\n" \
+ /* Copy bytes. */ \
+ "rep\n" \
+ "movsb" : \
+ "=D" (dst_bp), "=S" (src_bp), "=c" (__d0) : \
+ "0" (dst_bp), "1" (src_bp), "2" (nbytes) : \
+ "memory"); \
+ } while (0)
+
+#undef BYTE_COPY_BWD
+#define BYTE_COPY_BWD(dst_ep, src_ep, nbytes) \
+ do \
+ { \
+ int __d0; \
+ asm volatile(/* Set the direction flag, so copying goes backwards. */ \
+ "std\n" \
+ /* Copy bytes. */ \
+ "rep\n" \
+ "movsb\n" \
+ /* Clear the dir flag. Convention says it should be 0. */ \
+ "cld" : \
+ "=D" (dst_ep), "=S" (src_ep), "=c" (__d0) : \
+ "0" (dst_ep - 1), "1" (src_ep - 1), "2" (nbytes) : \
+ "memory"); \
+ dst_ep += 1; \
+ src_ep += 1; \
+ } while (0)
+
+#undef WORD_COPY_FWD
+#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \
+ do \
+ { \
+ int __d0; \
+ asm volatile(/* Clear the direction flag, so copying goes forward. */ \
+ "cld\n" \
+ /* Copy longwords. */ \
+ "rep\n" \
+ "movsl" : \
+ "=D" (dst_bp), "=S" (src_bp), "=c" (__d0) : \
+ "0" (dst_bp), "1" (src_bp), "2" ((nbytes) / 4) : \
+ "memory"); \
+ (nbytes_left) = (nbytes) % 4; \
+ } while (0)
+
+#undef WORD_COPY_BWD
+#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes) \
+ do \
+ { \
+ int __d0; \
+ asm volatile(/* Set the direction flag, so copying goes backwards. */ \
+ "std\n" \
+ /* Copy longwords. */ \
+ "rep\n" \
+ "movsl\n" \
+ /* Clear the dir flag. Convention says it should be 0. */ \
+ "cld" : \
+ "=D" (dst_ep), "=S" (src_ep), "=c" (__d0) : \
+ "0" (dst_ep - 4), "1" (src_ep - 4), "2" ((nbytes) / 4) : \
+ "memory"); \
+ dst_ep += 4; \
+ src_ep += 4; \
+ (nbytes_left) = (nbytes) % 4; \
+ } while (0)
diff --git a/libc/sysdeps/i386/memset.c b/libc/sysdeps/i386/memset.c
new file mode 100644
index 000000000..120df94d6
--- /dev/null
+++ b/libc/sysdeps/i386/memset.c
@@ -0,0 +1,86 @@
+/* Set a block of memory to some byte value.
+ For Intel 80x86, x>=3.
+ Copyright (C) 1991,1992,1993,1997,1998,2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <memcopy.h>
+
+#ifdef __GNUC__
+
+#undef memset
+
+void *
+memset (void *dstpp, int c, size_t len)
+{
+ int d0;
+ unsigned long int dstp = (unsigned long int) dstpp;
+
+ /* This explicit register allocation
+ improves code very much indeed. */
+ register op_t x asm("ax");
+
+ x = (unsigned char) c;
+
+ /* Clear the direction flag, so filling will move forward. */
+ asm volatile("cld");
+
+ /* This threshold value is optimal. */
+ if (len >= 12)
+ {
+ /* Fill X with four copies of the char we want to fill with. */
+ x |= (x << 8);
+ x |= (x << 16);
+
+ /* Adjust LEN for the bytes handled in the first loop. */
+ len -= (-dstp) % OPSIZ;
+
+ /* There are at least some bytes to set.
+ No need to test for LEN == 0 in this alignment loop. */
+
+ /* Fill bytes until DSTP is aligned on a longword boundary. */
+ asm volatile("rep\n"
+ "stosb" /* %0, %2, %3 */ :
+ "=D" (dstp), "=c" (d0) :
+ "0" (dstp), "1" ((-dstp) % OPSIZ), "a" (x) :
+ "memory");
+
+ /* Fill longwords. */
+ asm volatile("rep\n"
+ "stosl" /* %0, %2, %3 */ :
+ "=D" (dstp), "=c" (d0) :
+ "0" (dstp), "1" (len / OPSIZ), "a" (x) :
+ "memory");
+ len %= OPSIZ;
+ }
+
+ /* Write the last few bytes. */
+ asm volatile("rep\n"
+ "stosb" /* %0, %2, %3 */ :
+ "=D" (dstp), "=c" (d0) :
+ "0" (dstp), "1" (len), "a" (x) :
+ "memory");
+
+ return dstpp;
+}
+libc_hidden_builtin_def (memset)
+
+#else
+#include <string/memset.c>
+#endif
diff --git a/libc/sysdeps/i386/memusage.h b/libc/sysdeps/i386/memusage.h
new file mode 100644
index 000000000..8d5749f65
--- /dev/null
+++ b/libc/sysdeps/i386/memusage.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("esp"); stack_ptr; })
+
+#include <sysdeps/generic/memusage.h>
diff --git a/libc/sysdeps/i386/mp_clz_tab.c b/libc/sysdeps/i386/mp_clz_tab.c
new file mode 100644
index 000000000..860f98cc6
--- /dev/null
+++ b/libc/sysdeps/i386/mp_clz_tab.c
@@ -0,0 +1 @@
+/* __clz_tab not needed on i386. */
diff --git a/libc/sysdeps/i386/mul_1.S b/libc/sysdeps/i386/mul_1.S
new file mode 100644
index 000000000..0d0c07e7c
--- /dev/null
+++ b/libc/sysdeps/i386/mul_1.S
@@ -0,0 +1,97 @@
+/* i80386 __mpn_mul_1 -- Multiply a limb vector with a limb and store
+ the result in a second limb vector.
+ Copyright (C) 1992,1994,1997,1998,2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+16 /* space for 4 saved regs */
+#define RES PARMS
+#define S1 RES+PTR_SIZE
+#define SIZE S1+PTR_SIZE
+#define S2LIMB SIZE+4
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebx
+
+ .text
+ENTRY (BP_SYM (__mpn_mul_1))
+ ENTER
+
+ pushl %res_ptr
+ cfi_adjust_cfa_offset (4)
+ pushl %s1_ptr
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %s2_limb
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp), %res_ptr
+ cfi_rel_offset (res_ptr, 12)
+ movl S1(%esp), %s1_ptr
+ cfi_rel_offset (s1_ptr, 8)
+ movl SIZE(%esp), %size
+ movl S2LIMB(%esp), %s2_limb
+ cfi_rel_offset (s2_limb, 0)
+#if __BOUNDED_POINTERS__
+ shll $2, %size /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%res_ptr, RES(%esp), %size)
+ CHECK_BOUNDS_BOTH_WIDE (%s1_ptr, S1(%esp), %size)
+ shrl $2, %size
+#endif
+ leal (%res_ptr,%size,4), %res_ptr
+ leal (%s1_ptr,%size,4), %s1_ptr
+ negl %size
+ xorl %ebp, %ebp
+ cfi_rel_offset (ebp, 4)
+ ALIGN (3)
+L(oop):
+ movl (%s1_ptr,%size,4), %eax
+ mull %s2_limb
+ addl %ebp, %eax
+ movl %eax, (%res_ptr,%size,4)
+ adcl $0, %edx
+ movl %edx, %ebp
+
+ incl %size
+ jnz L(oop)
+ movl %ebp, %eax
+
+ popl %s2_limb
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (s2_limb)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %s1_ptr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (s1_ptr)
+ popl %res_ptr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (res_ptr)
+
+ LEAVE
+ ret
+#undef size
+END (BP_SYM (__mpn_mul_1))
diff --git a/libc/sysdeps/i386/rawmemchr.S b/libc/sysdeps/i386/rawmemchr.S
new file mode 100644
index 000000000..ddb9d5216
--- /dev/null
+++ b/libc/sysdeps/i386/rawmemchr.S
@@ -0,0 +1,230 @@
+/* rawmemchr (str, ch) -- Return pointer to first occurrence of CH in STR.
+ For Intel 80x86, x>=3.
+ Copyright (C) 1994-2000,2002,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+ Optimised a little by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>
+ This version is developed using the same algorithm as the fast C
+ version which carries the following introduction:
+ Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+ with help from Dan Sahlin (dan@sics.se) and
+ commentary by Jim Blandy (jimb@ai.mit.edu);
+ adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+ and implemented by Roland McGrath (roland@ai.mit.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+4 /* space for 1 saved reg */
+#define RTN PARMS
+#define STR RTN+RTN_SIZE
+#define CHR STR+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__rawmemchr))
+ ENTER
+
+ /* Save callee-safe register used in this function. */
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (edi, 0)
+
+ /* Load parameters into registers. */
+ movl STR(%esp), %eax
+ movl CHR(%esp), %edx
+ CHECK_BOUNDS_LOW (%eax, STR(%esp))
+
+ /* At the moment %edx contains C. What we need for the
+ algorithm is C in all bytes of the dword. Avoid
+ operations on 16 bit words because these require an
+ prefix byte (and one more cycle). */
+ movb %dl, %dh /* Now it is 0|0|c|c */
+ movl %edx, %ecx
+ shll $16, %edx /* Now c|c|0|0 */
+ movw %cx, %dx /* And finally c|c|c|c */
+
+ /* Better performance can be achieved if the word (32
+ bit) memory access is aligned on a four-byte-boundary.
+ So process first bytes one by one until boundary is
+ reached. Don't use a loop for better performance. */
+
+ testb $3, %al /* correctly aligned ? */
+ je L(1) /* yes => begin loop */
+ cmpb %dl, (%eax) /* compare byte */
+ je L(9) /* target found => return */
+ incl %eax /* increment source pointer */
+
+ testb $3, %al /* correctly aligned ? */
+ je L(1) /* yes => begin loop */
+ cmpb %dl, (%eax) /* compare byte */
+ je L(9) /* target found => return */
+ incl %eax /* increment source pointer */
+
+ testb $3, %al /* correctly aligned ? */
+ je L(1) /* yes => begin loop */
+ cmpb %dl, (%eax) /* compare byte */
+ je L(9) /* target found => return */
+ incl %eax /* increment source pointer */
+
+ /* We exit the loop if adding MAGIC_BITS to LONGWORD fails to
+ change any of the hole bits of LONGWORD.
+
+ 1) Is this safe? Will it catch all the zero bytes?
+ Suppose there is a byte with all zeros. Any carry bits
+ propagating from its left will fall into the hole at its
+ least significant bit and stop. Since there will be no
+ carry from its most significant bit, the LSB of the
+ byte to the left will be unchanged, and the zero will be
+ detected.
+
+ 2) Is this worthwhile? Will it ignore everything except
+ zero bytes? Suppose every byte of LONGWORD has a bit set
+ somewhere. There will be a carry into bit 8. If bit 8
+ is set, this will carry into bit 16. If bit 8 is clear,
+ one of bits 9-15 must be set, so there will be a carry
+ into bit 16. Similarly, there will be a carry into bit
+ 24. If one of bits 24-31 is set, there will be a carry
+ into bit 32 (=carry flag), so all of the hole bits will
+ be changed.
+
+ 3) But wait! Aren't we looking for C, not zero?
+ Good point. So what we do is XOR LONGWORD with a longword,
+ each of whose bytes is C. This turns each byte that is C
+ into a zero. */
+
+
+ /* Each round the main loop processes 16 bytes. */
+ ALIGN (4)
+
+L(1): movl (%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+
+ /* According to the algorithm we had to reverse the effect of the
+ XOR first and then test the overflow bits. But because the
+ following XOR would destroy the carry flag and it would (in a
+ representation with more than 32 bits) not alter then last
+ overflow, we can now test this condition. If no carry is signaled
+ no overflow must have occurred in the last byte => it was 0. */
+ jnc L(8)
+
+ /* We are only interested in carry bits that change due to the
+ previous add, so remove original bits */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+
+ /* Now test for the other three overflow bits. */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ /* If at least one byte of the word is C we don't get 0 in %edi. */
+ jnz L(8) /* found it => return pointer */
+
+ /* This process is unfolded four times for better performance.
+ we don't increment the source pointer each time. Instead we
+ use offsets and increment by 16 in each run of the loop. But
+ before probing for the matching byte we need some extra code
+ (following LL(13) below). Even the len can be compared with
+ constants instead of decrementing each time. */
+
+ movl 4(%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(7) /* highest byte is C => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(7) /* found it => return pointer */
+
+ movl 8(%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(6) /* highest byte is C => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(6) /* found it => return pointer */
+
+ movl 12(%eax), %ecx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(5) /* highest byte is C => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(5) /* found it => return pointer */
+
+ /* Adjust both counters for a full round, i.e. 16 bytes. */
+ addl $16, %eax
+ jmp L(1)
+ /* add missing source pointer increments */
+L(5): addl $4, %eax
+L(6): addl $4, %eax
+L(7): addl $4, %eax
+
+ /* Test for the matching byte in the word. %ecx contains a NUL
+ char in the byte which originally was the byte we are looking
+ at. */
+L(8): testb %cl, %cl /* test first byte in dword */
+ jz L(9) /* if zero => return pointer */
+ incl %eax /* increment source pointer */
+
+ testb %ch, %ch /* test second byte in dword */
+ jz L(9) /* if zero => return pointer */
+ incl %eax /* increment source pointer */
+
+ testl $0xff0000, %ecx /* test third byte in dword */
+ jz L(9) /* if zero => return pointer */
+ incl %eax /* increment source pointer */
+
+ /* No further test needed we we know it is one of the four bytes. */
+
+L(9):
+ CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
+ RETURN_BOUNDED_POINTER (STR(%esp))
+ popl %edi /* pop saved register */
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (__rawmemchr))
+
+libc_hidden_def (BP_SYM (__rawmemchr))
+weak_alias (BP_SYM (__rawmemchr), BP_SYM (rawmemchr))
diff --git a/libc/sysdeps/i386/rshift.S b/libc/sysdeps/i386/rshift.S
new file mode 100644
index 000000000..3fd0afe82
--- /dev/null
+++ b/libc/sysdeps/i386/rshift.S
@@ -0,0 +1,119 @@
+/* i80386 __mpn_rshift --
+ Copyright (C) 1992,1994,1997-2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+12 /* space for 3 saved regs */
+#define RES PARMS
+#define S RES+PTR_SIZE
+#define SIZE S+PTR_SIZE
+#define CNT SIZE+4
+
+ .text
+ENTRY (BP_SYM (__mpn_rshift))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp),%edi
+ cfi_rel_offset (edi, 8)
+ movl S(%esp),%esi
+ cfi_rel_offset (esi, 4)
+ movl SIZE(%esp),%edx
+ movl CNT(%esp),%ecx
+#if __BOUNDED_POINTERS__
+ shll $2, %edx /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %edx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, S(%esp), %edx)
+ shrl $2, %edx
+#endif
+ leal -4(%edi,%edx,4),%edi
+ leal (%esi,%edx,4),%esi
+ negl %edx
+
+ movl (%esi,%edx,4),%ebx /* read least significant limb */
+ cfi_rel_offset (ebx, 0)
+ xorl %eax,%eax
+ shrdl %cl,%ebx,%eax /* compute carry limb */
+ incl %edx
+ jz L(end)
+ pushl %eax /* push carry limb onto stack */
+ cfi_adjust_cfa_offset (4)
+ testb $1,%dl
+ jnz L(1) /* enter loop in the middle */
+ movl %ebx,%eax
+
+ ALIGN (3)
+L(oop): movl (%esi,%edx,4),%ebx /* load next higher limb */
+ shrdl %cl,%ebx,%eax /* compute result limb */
+ movl %eax,(%edi,%edx,4) /* store it */
+ incl %edx
+L(1): movl (%esi,%edx,4),%eax
+ shrdl %cl,%eax,%ebx
+ movl %ebx,(%edi,%edx,4)
+ incl %edx
+ jnz L(oop)
+
+ shrl %cl,%eax /* compute most significant limb */
+ movl %eax,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+ cfi_adjust_cfa_offset (-4)
+
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+
+ cfi_adjust_cfa_offset (12)
+ cfi_rel_offset (edi, 8)
+ cfi_rel_offset (esi, 4)
+ cfi_rel_offset (ebx, 0)
+L(end): shrl %cl,%ebx /* compute most significant limb */
+ movl %ebx,(%edi) /* store it */
+
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+END (BP_SYM (__mpn_rshift))
diff --git a/libc/sysdeps/i386/setfpucw.c b/libc/sysdeps/i386/setfpucw.c
new file mode 100644
index 000000000..1ca2d3cbd
--- /dev/null
+++ b/libc/sysdeps/i386/setfpucw.c
@@ -0,0 +1,55 @@
+/* Set the FPU control word for x86.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <fpu_control.h>
+#include <fenv.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+void
+__setfpucw (fpu_control_t set)
+{
+ fpu_control_t cw;
+
+ /* Fetch the current control word. */
+ __asm__ ("fnstcw %0" : "=m" (*&cw));
+
+ /* Preserve the reserved bits, and set the rest as the user
+ specified (or the default, if the user gave zero). */
+ cw &= _FPU_RESERVED;
+ cw |= set & ~_FPU_RESERVED;
+
+ __asm__ ("fldcw %0" : : "m" (*&cw));
+
+ /* If the CPU supports SSE, we set the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xnew_exc;
+
+ /* Get the current MXCSR. */
+ __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
+
+ xnew_exc &= ~((0xc00 << 3) | (FE_ALL_EXCEPT << 7));
+ xnew_exc |= ((set & 0xc00) << 3) | ((set & FE_ALL_EXCEPT) << 7);
+
+ __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
+ }
+}
diff --git a/libc/sysdeps/i386/setjmp.S b/libc/sysdeps/i386/setjmp.S
new file mode 100644
index 000000000..56c3994f6
--- /dev/null
+++ b/libc/sysdeps/i386/setjmp.S
@@ -0,0 +1,62 @@
+/* setjmp for i386.
+ Copyright (C) 1995,1996,1997,2000,2001,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+#include <asm-syntax.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define JMPBUF PARMS
+#define SIGMSK JMPBUF+PTR_SIZE
+
+ENTRY (BP_SYM (__sigsetjmp))
+ ENTER
+
+ movl JMPBUF(%esp), %eax
+ CHECK_BOUNDS_BOTH_WIDE (%eax, JMPBUF(%esp), $JB_SIZE)
+
+ /* Save registers. */
+ movl %ebx, (JB_BX*4)(%eax)
+ movl %esi, (JB_SI*4)(%eax)
+ movl %edi, (JB_DI*4)(%eax)
+ leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%ecx)
+#endif
+ movl %ecx, (JB_SP*4)(%eax)
+ movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%ecx)
+#endif
+ movl %ecx, (JB_PC*4)(%eax)
+ LEAVE /* pop frame pointer to prepare for tail-call. */
+ movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */
+
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ /* In ld.so we never save the signal mask. */
+ xorl %eax, %eax
+ ret
+#else
+ /* Make a tail call to __sigjmp_save; it takes the same args. */
+ jmp __sigjmp_save
+#endif
+END (BP_SYM (__sigsetjmp))
diff --git a/libc/sysdeps/i386/soft-fp/sfp-machine.h b/libc/sysdeps/i386/soft-fp/sfp-machine.h
new file mode 100644
index 000000000..ed71ae418
--- /dev/null
+++ b/libc/sysdeps/i386/soft-fp/sfp-machine.h
@@ -0,0 +1,89 @@
+#define _FP_W_TYPE_SIZE 32
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \
+ __asm__("addl %5,%1; adcl %3,%0" \
+ : "=r"(rh), "=r"(rl) \
+ : "%0"(xh), "g"(yh), "%1"(xl), "g"(yl) \
+ : "cc")
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
+ do { \
+ __asm__ volatile("addl %5,%1; adcl %3,%0" \
+ : "=r"(r1), "=r"(r0) \
+ : "%0"(x1), "g"(y1), "%1"(x0), "g"(y0) \
+ : "cc"); \
+ __asm__ volatile("adcl %5,%1; adcl %3,%0" \
+ : "=r"(r3), "=r"(r2) \
+ : "%0"(x3), "g"(y3), "%1"(x2), "g"(y2) \
+ : "cc"); \
+ } while (0)
+
+#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \
+ __asm__("subl %5,%1; sbbl %4,%0" \
+ : "=r"(rh), "=r"(rl) \
+ : "0"(xh), "1"(xl), "g"(yh), "g"(yl) \
+ : "cc")
+
+#define __FP_CLZ(r, x) \
+ do { \
+ __asm__("bsrl %1,%0" : "=r"(r) : "g"(x) : "cc"); \
+ r ^= 31; \
+ } while (0)
+
+#define _i386_mul_32_64(rh, rl, x, y) \
+ __asm__("mull %2" : "=d"(rh), "=a"(rl) : "%g"(x), "1"(y) : "cc")
+
+#define _i386_div_64_32(q, r, nh, nl, d) \
+ __asm__ ("divl %4" : "=a"(q), "=d"(r) : "0"(nl), "1"(nh), "g"(d) : "cc")
+
+
+#define _FP_MUL_MEAT_S(R,X,Y) \
+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,_i386_mul_32_64)
+#define _FP_MUL_MEAT_D(R,X,Y) \
+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,_i386_mul_32_64)
+
+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+
+#define _FP_NANFRAC_S _FP_QNANBIT_S
+#define _FP_NANFRAC_D _FP_QNANBIT_D, 0
+#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S 1
+#define _FP_NANSIGN_D 1
+#define _FP_NANSIGN_Q 1
+
+#define _FP_KEEPNANFRACP 1
+/* Here is something Intel misdesigned: the specs don't define
+ the case where we have two NaNs with same mantissas, but
+ different sign. Different operations pick up different NaNs.
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if (_FP_FRAC_GT_##wc(X, Y) \
+ || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ } \
+ else \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,Y); \
+ } \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+#define FP_EX_INVALID (1 << 0)
+#define FP_EX_DENORM (1 << 1)
+#define FP_EX_DIVZERO (1 << 2)
+#define FP_EX_OVERFLOW (1 << 3)
+#define FP_EX_UNDERFLOW (1 << 4)
+#define FP_EX_INEXACT (1 << 5)
+
+#define FP_RND_NEAREST 0
+#define FP_RND_ZERO 3
+#define FP_RND_PINF 2
+#define FP_RND_MINF 1
diff --git a/libc/sysdeps/i386/stackinfo.h b/libc/sysdeps/i386/stackinfo.h
new file mode 100644
index 000000000..a9a6745aa
--- /dev/null
+++ b/libc/sysdeps/i386/stackinfo.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file contains a bit of information about the stack allocation
+ of the processor. */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H 1
+
+/* On x86 the stack grows down. */
+#define _STACK_GROWS_DOWN 1
+
+#endif /* stackinfo.h */
diff --git a/libc/sysdeps/i386/stpcpy.S b/libc/sysdeps/i386/stpcpy.S
new file mode 100644
index 000000000..50f9c5ea5
--- /dev/null
+++ b/libc/sysdeps/i386/stpcpy.S
@@ -0,0 +1,98 @@
+/* Copy SRC to DEST returning the address of the terminating '\0' in DEST.
+ For Intel 80x86, x>=3.
+ Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper (drepper@gnu.ai.mit.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This function is defined neither in ANSI nor POSIX standards but is
+ also not invented here. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#define SRC DEST+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__stpcpy))
+ ENTER
+
+ movl DEST(%esp), %eax
+ movl SRC(%esp), %ecx
+ CHECK_BOUNDS_LOW (%eax, DEST(%esp))
+ CHECK_BOUNDS_LOW (%ecx, SRC(%esp))
+ subl %eax, %ecx /* magic: reduce number of loop variants
+ to one using addressing mode */
+
+ /* Here we would like to write
+
+ subl $4, %eax
+ ALIGN (4)
+
+ but the assembler is too smart and optimizes for the shortest
+ form where the number only needs one byte. But if we could
+ have the long form we would not need the alignment. */
+
+ .byte 0x81, 0xe8 /* This is `subl $0x00000004, %eax' */
+ .long 0x00000004
+
+ /* Four times unfolded loop with only one loop counter. This
+ is achieved by the use of index+base addressing mode. As the
+ loop counter we use the destination address because this is
+ also the result. */
+L(1): addl $4, %eax /* increment loop counter */
+
+ movb (%eax,%ecx), %dl /* load current char */
+ movb %dl, (%eax) /* and store it */
+ testb %dl, %dl /* was it NUL? */
+ jz L(2) /* yes, then exit */
+
+ movb 1(%eax,%ecx), %dl /* load current char */
+ movb %dl, 1(%eax) /* and store it */
+ testb %dl, %dl /* was it NUL? */
+ jz L(3) /* yes, then exit */
+
+ movb 2(%eax,%ecx), %dl /* load current char */
+ movb %dl, 2(%eax) /* and store it */
+ testb %dl, %dl /* was it NUL? */
+ jz L(4) /* yes, then exit */
+
+ movb 3(%eax,%ecx), %dl /* load current char */
+ movb %dl, 3(%eax) /* and store it */
+ testb %dl, %dl /* was it NUL? */
+ jnz L(1) /* no, then continue loop */
+
+ incl %eax /* correct loop counter */
+L(4): incl %eax
+L(3): incl %eax
+L(2):
+ CHECK_BOUNDS_HIGH (%eax, DEST(%esp), jb)
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (__stpcpy))
+
+weak_alias (BP_SYM (__stpcpy), BP_SYM (stpcpy))
+libc_hidden_def (__stpcpy)
+libc_hidden_builtin_def (stpcpy)
diff --git a/libc/sysdeps/i386/stpncpy.S b/libc/sysdeps/i386/stpncpy.S
new file mode 100644
index 000000000..c163a3359
--- /dev/null
+++ b/libc/sysdeps/i386/stpncpy.S
@@ -0,0 +1,161 @@
+/* copy no more then N bytes from SRC to DEST, returning the address of
+ the terminating '\0' in DEST.
+ For Intel 80x86, x>=3.
+ Copyright (C) 1994-1997,2000,2002,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+ Some bug fixes by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>
+ - original wrote n+1 chars in some cases.
+ - stpncpy() ought to behave like strncpy() ie. not null-terminate
+ if limited by n. glibc-1.09 stpncpy() does this.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+4 /* space for 1 saved reg */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#define SRC DEST+PTR_SIZE
+#define LEN SRC+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__stpncpy))
+ ENTER
+
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+
+ movl DEST(%esp), %eax
+ movl SRC(%esp), %esi
+ cfi_rel_offset (esi, 0)
+ movl LEN(%esp), %ecx
+ CHECK_BOUNDS_LOW (%eax, DEST(%esp))
+ CHECK_BOUNDS_LOW (%esi, SRC(%esp))
+
+ subl %eax, %esi /* magic: reduce number of loop variants
+ to one using addressing mode */
+ jmp L(1) /* jump to loop "head" */
+
+ ALIGN(4)
+
+ /* Four times unfolded loop with two loop counters. We get the
+ the third value (the source address) by using the index+base
+ addressing mode. */
+L(2): movb (%eax,%esi), %dl /* load current char */
+ movb %dl, (%eax) /* and store it */
+ testb %dl, %dl /* was it NUL? */
+ jz L(7) /* yes, then exit */
+
+ movb 1(%eax,%esi), %dl /* load current char */
+ movb %dl, 1(%eax) /* and store it */
+ testb %dl, %dl /* was it NUL? */
+ jz L(6) /* yes, then exit */
+
+ movb 2(%eax,%esi), %dl /* load current char */
+ movb %dl, 2(%eax) /* and store it */
+ testb %dl, %dl /* was it NUL? */
+ jz L(5) /* yes, then exit */
+
+ movb 3(%eax,%esi), %dl /* load current char */
+ movb %dl, 3(%eax) /* and store it */
+ testb %dl, %dl /* was it NUL? */
+ jz L(4) /* yes, then exit */
+
+ addl $4, %eax /* increment loop counter for full round */
+
+L(1): subl $4, %ecx /* still more than 4 bytes allowed? */
+ jae L(2) /* yes, then go to start of loop */
+
+ /* The maximal remaining 15 bytes are not processed in a loop. */
+
+ addl $4, %ecx /* correct above subtraction */
+ jz L(9) /* maximal allowed char reached => go to end */
+
+ movb (%eax,%esi), %dl /* load current char */
+ movb %dl, (%eax) /* and store it */
+ testb %dl, %dl /* was it NUL? */
+ jz L(3) /* yes, then exit */
+
+ incl %eax /* increment pointer */
+ decl %ecx /* decrement length counter */
+ jz L(9) /* no more allowed => exit */
+
+ movb (%eax,%esi), %dl /* load current char */
+ movb %dl, (%eax) /* and store it */
+ testb %dl, %dl /* was it NUL? */
+ jz L(3) /* yes, then exit */
+
+ incl %eax /* increment pointer */
+ decl %ecx /* decrement length counter */
+ jz L(9) /* no more allowed => exit */
+
+ movb (%eax,%esi), %dl /* load current char */
+ movb %dl, (%eax) /* and store it */
+ testb %dl, %dl /* was it NUL? */
+ jz L(3) /* yes, then exit */
+
+ incl %eax /* increment pointer */
+ jmp L(9) /* we don't have to test for counter underflow
+ because we know we had a most 3 bytes
+ remaining => exit */
+
+ /* When coming from the main loop we have to adjust the pointer. */
+L(4): decl %ecx /* decrement counter */
+ incl %eax /* increment pointer */
+
+L(5): decl %ecx /* increment pointer */
+ incl %eax /* increment pointer */
+
+L(6): decl %ecx /* increment pointer */
+ incl %eax /* increment pointer */
+L(7):
+
+ addl $3, %ecx /* correct pre-decrementation of counter
+ at the beginning of the loop; but why 3
+ and not 4? Very simple, we have to count
+ the NUL char we already wrote. */
+ jz L(9) /* counter is also 0 => exit */
+
+ /* We now have to fill the rest of the buffer with NUL. This
+ is done in a tricky way. Please note that the addressing mode
+ used below is not the same we used above. Here we use the
+ %ecx register. */
+L(8):
+ movb $0, (%ecx,%eax) /* store NUL char */
+L(3): decl %ecx /* all bytes written? */
+ jnz L(8) /* no, then again */
+
+L(9):
+#if __BOUNDED_POINTERS__
+ addl %eax, %esi /* undo magic: %esi now points beyond end of SRC */
+ CHECK_BOUNDS_HIGH (%esi, SRC(%esp), jbe)
+ CHECK_BOUNDS_HIGH (%eax, DEST(%esp), jbe)
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+#endif
+ popl %esi /* restore saved register content */
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (__stpncpy))
+
+libc_hidden_def (BP_SYM (__stpncpy))
+weak_alias (BP_SYM (__stpncpy), BP_SYM (stpncpy))
diff --git a/libc/sysdeps/i386/strchr.S b/libc/sysdeps/i386/strchr.S
new file mode 100644
index 000000000..93b4cce8d
--- /dev/null
+++ b/libc/sysdeps/i386/strchr.S
@@ -0,0 +1,301 @@
+/* strchr (str, ch) -- Return pointer to first occurrence of CH in STR.
+ For Intel 80x86, x>=3.
+ Copyright (C) 1994-1997,1999,2000,2002,2003,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+ Some optimisations by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+4 /* space for 1 saved reg */
+#define RTN PARMS
+#define STR RTN+RTN_SIZE
+#define CHR STR+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (strchr))
+ ENTER
+
+ pushl %edi /* Save callee-safe registers used here. */
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (edi, 0)
+ movl STR(%esp), %eax
+ movl CHR(%esp), %edx
+ CHECK_BOUNDS_LOW (%eax, STR(%esp))
+
+ /* At the moment %edx contains C. What we need for the
+ algorithm is C in all bytes of the dword. Avoid
+ operations on 16 bit words because these require an
+ prefix byte (and one more cycle). */
+ movb %dl, %dh /* now it is 0|0|c|c */
+ movl %edx, %ecx
+ shll $16, %edx /* now it is c|c|0|0 */
+ movw %cx, %dx /* and finally c|c|c|c */
+
+ /* Before we start with the main loop we process single bytes
+ until the source pointer is aligned. This has two reasons:
+ 1. aligned 32-bit memory access is faster
+ and (more important)
+ 2. we process in the main loop 32 bit in one step although
+ we don't know the end of the string. But accessing at
+ 4-byte alignment guarantees that we never access illegal
+ memory if this would not also be done by the trivial
+ implementation (this is because all processor inherent
+ boundaries are multiples of 4. */
+
+ testb $3, %al /* correctly aligned ? */
+ jz L(11) /* yes => begin loop */
+ movb (%eax), %cl /* load byte in question (we need it twice) */
+ cmpb %cl, %dl /* compare byte */
+ je L(6) /* target found => return */
+ testb %cl, %cl /* is NUL? */
+ jz L(2) /* yes => return NULL */
+ incl %eax /* increment pointer */
+
+ testb $3, %al /* correctly aligned ? */
+ jz L(11) /* yes => begin loop */
+ movb (%eax), %cl /* load byte in question (we need it twice) */
+ cmpb %cl, %dl /* compare byte */
+ je L(6) /* target found => return */
+ testb %cl, %cl /* is NUL? */
+ jz L(2) /* yes => return NULL */
+ incl %eax /* increment pointer */
+
+ testb $3, %al /* correctly aligned ? */
+ jz L(11) /* yes => begin loop */
+ movb (%eax), %cl /* load byte in question (we need it twice) */
+ cmpb %cl, %dl /* compare byte */
+ je L(6) /* target found => return */
+ testb %cl, %cl /* is NUL? */
+ jz L(2) /* yes => return NULL */
+ incl %eax /* increment pointer */
+
+ /* No we have reached alignment. */
+ jmp L(11) /* begin loop */
+
+ /* We exit the loop if adding MAGIC_BITS to LONGWORD fails to
+ change any of the hole bits of LONGWORD.
+
+ 1) Is this safe? Will it catch all the zero bytes?
+ Suppose there is a byte with all zeros. Any carry bits
+ propagating from its left will fall into the hole at its
+ least significant bit and stop. Since there will be no
+ carry from its most significant bit, the LSB of the
+ byte to the left will be unchanged, and the zero will be
+ detected.
+
+ 2) Is this worthwhile? Will it ignore everything except
+ zero bytes? Suppose every byte of LONGWORD has a bit set
+ somewhere. There will be a carry into bit 8. If bit 8
+ is set, this will carry into bit 16. If bit 8 is clear,
+ one of bits 9-15 must be set, so there will be a carry
+ into bit 16. Similarly, there will be a carry into bit
+ 24. If one of bits 24-31 is set, there will be a carry
+ into bit 32 (=carry flag), so all of the hole bits will
+ be changed.
+
+ 3) But wait! Aren't we looking for C, not zero?
+ Good point. So what we do is XOR LONGWORD with a longword,
+ each of whose bytes is C. This turns each byte that is C
+ into a zero. */
+
+ /* Each round the main loop processes 16 bytes. */
+
+ ALIGN(4)
+
+L(1): addl $16, %eax /* adjust pointer for whole round */
+
+L(11): movl (%eax), %ecx /* get word (= 4 bytes) in question */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* C */
+
+ /* According to the algorithm we had to reverse the effect of the
+ XOR first and then test the overflow bits. But because the
+ following XOR would destroy the carry flag and it would (in a
+ representation with more than 32 bits) not alter then last
+ overflow, we can now test this condition. If no carry is signaled
+ no overflow must have occurred in the last byte => it was 0. */
+ jnc L(7)
+
+ /* We are only interested in carry bits that change due to the
+ previous add, so remove original bits */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+
+ /* Now test for the other three overflow bits. */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ /* If at least one byte of the word is C we don't get 0 in %edi. */
+ jnz L(7) /* found it => return pointer */
+
+ /* Now we made sure the dword does not contain the character we are
+ looking for. But because we deal with strings we have to check
+ for the end of string before testing the next dword. */
+
+ xorl %edx, %ecx /* restore original dword without reload */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(2) /* highest byte is NUL => return NULL */
+ xorl %ecx, %edi /* (word+magic)^word */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(2) /* found NUL => return NULL */
+
+ movl 4(%eax), %ecx /* get word (= 4 bytes) in question */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* C */
+ jnc L(71) /* highest byte is C => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(71) /* found it => return pointer */
+ xorl %edx, %ecx /* restore original dword without reload */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(2) /* highest byte is NUL => return NULL */
+ xorl %ecx, %edi /* (word+magic)^word */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(2) /* found NUL => return NULL */
+
+ movl 8(%eax), %ecx /* get word (= 4 bytes) in question */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* C */
+ jnc L(72) /* highest byte is C => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(72) /* found it => return pointer */
+ xorl %edx, %ecx /* restore original dword without reload */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(2) /* highest byte is NUL => return NULL */
+ xorl %ecx, %edi /* (word+magic)^word */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(2) /* found NUL => return NULL */
+
+ movl 12(%eax), %ecx /* get word (= 4 bytes) in question */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* C */
+ jnc L(73) /* highest byte is C => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(73) /* found it => return pointer */
+ xorl %edx, %ecx /* restore original dword without reload */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(2) /* highest byte is NUL => return NULL */
+ xorl %ecx, %edi /* (word+magic)^word */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jz L(1) /* no NUL found => restart loop */
+
+L(2): /* Return NULL. */
+ xorl %eax, %eax
+ RETURN_NULL_BOUNDED_POINTER
+ popl %edi /* restore saved register content */
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (edi, 0)
+L(73): addl $4, %eax /* adjust pointer */
+L(72): addl $4, %eax
+L(71): addl $4, %eax
+
+ /* We now scan for the byte in which the character was matched.
+ But we have to take care of the case that a NUL char is
+ found before this in the dword. Note that we XORed %ecx
+ with the byte we're looking for, therefore the tests below look
+ reversed. */
+
+L(7): testb %cl, %cl /* is first byte C? */
+ jz L(6) /* yes => return pointer */
+ cmpb %dl, %cl /* is first byte NUL? */
+ je L(2) /* yes => return NULL */
+ incl %eax /* it's not in the first byte */
+
+ testb %ch, %ch /* is second byte C? */
+ jz L(6) /* yes => return pointer */
+ cmpb %dl, %ch /* is second byte NUL? */
+ je L(2) /* yes => return NULL? */
+ incl %eax /* it's not in the second byte */
+
+ shrl $16, %ecx /* make upper byte accessible */
+ testb %cl, %cl /* is third byte C? */
+ jz L(6) /* yes => return pointer */
+ cmpb %dl, %cl /* is third byte NUL? */
+ je L(2) /* yes => return NULL */
+
+ /* It must be in the fourth byte and it cannot be NUL. */
+ incl %eax
+
+L(6):
+ CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
+ RETURN_BOUNDED_POINTER (STR(%esp))
+ popl %edi /* restore saved register content */
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (strchr))
+
+weak_alias (BP_SYM (strchr), BP_SYM (index))
+libc_hidden_builtin_def (strchr)
diff --git a/libc/sysdeps/i386/strchrnul.S b/libc/sysdeps/i386/strchrnul.S
new file mode 100644
index 000000000..8d1f7b2a5
--- /dev/null
+++ b/libc/sysdeps/i386/strchrnul.S
@@ -0,0 +1,286 @@
+/* strchrnul (str, chr) -- Return pointer to first occurrence of CHR in STR
+ or the final NUL byte.
+ For Intel 80x86, x>=3.
+ Copyright (C) 1994-1997, 1999, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.org>
+ Some optimisations by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+4 /* space for 1 saved reg */
+#define RTN PARMS
+#define STR RTN+RTN_SIZE
+#define CHR STR+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__strchrnul))
+ ENTER
+
+ pushl %edi /* Save callee-safe registers used here. */
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (edi, 0)
+
+ movl STR(%esp), %eax
+ movl CHR(%esp), %edx
+ CHECK_BOUNDS_LOW (%eax, STR(%esp))
+
+ /* At the moment %edx contains CHR. What we need for the
+ algorithm is CHR in all bytes of the dword. Avoid
+ operations on 16 bit words because these require an
+ prefix byte (and one more cycle). */
+ movb %dl, %dh /* now it is 0|0|c|c */
+ movl %edx, %ecx
+ shll $16, %edx /* now it is c|c|0|0 */
+ movw %cx, %dx /* and finally c|c|c|c */
+
+ /* Before we start with the main loop we process single bytes
+ until the source pointer is aligned. This has two reasons:
+ 1. aligned 32-bit memory access is faster
+ and (more important)
+ 2. we process in the main loop 32 bit in one step although
+ we don't know the end of the string. But accessing at
+ 4-byte alignment guarantees that we never access illegal
+ memory if this would not also be done by the trivial
+ implementation (this is because all processor inherent
+ boundaries are multiples of 4. */
+
+ testb $3, %al /* correctly aligned ? */
+ jz L(11) /* yes => begin loop */
+ movb (%eax), %cl /* load byte in question (we need it twice) */
+ cmpb %cl, %dl /* compare byte */
+ je L(6) /* target found => return */
+ testb %cl, %cl /* is NUL? */
+ jz L(6) /* yes => return NULL */
+ incl %eax /* increment pointer */
+
+ testb $3, %al /* correctly aligned ? */
+ jz L(11) /* yes => begin loop */
+ movb (%eax), %cl /* load byte in question (we need it twice) */
+ cmpb %cl, %dl /* compare byte */
+ je L(6) /* target found => return */
+ testb %cl, %cl /* is NUL? */
+ jz L(6) /* yes => return NULL */
+ incl %eax /* increment pointer */
+
+ testb $3, %al /* correctly aligned ? */
+ jz L(11) /* yes => begin loop */
+ movb (%eax), %cl /* load byte in question (we need it twice) */
+ cmpb %cl, %dl /* compare byte */
+ je L(6) /* target found => return */
+ testb %cl, %cl /* is NUL? */
+ jz L(6) /* yes => return NULL */
+ incl %eax /* increment pointer */
+
+ /* No we have reached alignment. */
+ jmp L(11) /* begin loop */
+
+ /* We exit the loop if adding MAGIC_BITS to LONGWORD fails to
+ change any of the hole bits of LONGWORD.
+
+ 1) Is this safe? Will it catch all the zero bytes?
+ Suppose there is a byte with all zeros. Any carry bits
+ propagating from its left will fall into the hole at its
+ least significant bit and stop. Since there will be no
+ carry from its most significant bit, the LSB of the
+ byte to the left will be unchanged, and the zero will be
+ detected.
+
+ 2) Is this worthwhile? Will it ignore everything except
+ zero bytes? Suppose every byte of LONGWORD has a bit set
+ somewhere. There will be a carry into bit 8. If bit 8
+ is set, this will carry into bit 16. If bit 8 is clear,
+ one of bits 9-15 must be set, so there will be a carry
+ into bit 16. Similarly, there will be a carry into bit
+ 24. If one of bits 24-31 is set, there will be a carry
+ into bit 32 (=carry flag), so all of the hole bits will
+ be changed.
+
+ 3) But wait! Aren't we looking for CHR, not zero?
+ Good point. So what we do is XOR LONGWORD with a longword,
+ each of whose bytes is CHR. This turns each byte that is CHR
+ into a zero. */
+
+ /* Each round the main loop processes 16 bytes. */
+
+ ALIGN(4)
+
+L(1): addl $16, %eax /* adjust pointer for whole round */
+
+L(11): movl (%eax), %ecx /* get word (= 4 bytes) in question */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* CHR */
+
+ /* According to the algorithm we had to reverse the effect of the
+ XOR first and then test the overflow bits. But because the
+ following XOR would destroy the carry flag and it would (in a
+ representation with more than 32 bits) not alter then last
+ overflow, we can now test this condition. If no carry is signaled
+ no overflow must have occurred in the last byte => it was 0. */
+ jnc L(7)
+
+ /* We are only interested in carry bits that change due to the
+ previous add, so remove original bits */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+
+ /* Now test for the other three overflow bits. */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ /* If at least one byte of the word is CHR we don't get 0 in %edi. */
+ jnz L(7) /* found it => return pointer */
+
+ /* Now we made sure the dword does not contain the character we are
+ looking for. But because we deal with strings we have to check
+ for the end of string before testing the next dword. */
+
+ xorl %edx, %ecx /* restore original dword without reload */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(7) /* highest byte is NUL => return NULL */
+ xorl %ecx, %edi /* (word+magic)^word */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(7) /* found NUL => return NULL */
+
+ movl 4(%eax), %ecx /* get word (= 4 bytes) in question */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* CHR */
+ jnc L(71) /* highest byte is CHR => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(71) /* found it => return pointer */
+ xorl %edx, %ecx /* restore original dword without reload */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(71) /* highest byte is NUL => return NULL */
+ xorl %ecx, %edi /* (word+magic)^word */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(71) /* found NUL => return NULL */
+
+ movl 8(%eax), %ecx /* get word (= 4 bytes) in question */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* CHR */
+ jnc L(72) /* highest byte is CHR => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(72) /* found it => return pointer */
+ xorl %edx, %ecx /* restore original dword without reload */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(72) /* highest byte is NUL => return NULL */
+ xorl %ecx, %edi /* (word+magic)^word */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(72) /* found NUL => return NULL */
+
+ movl 12(%eax), %ecx /* get word (= 4 bytes) in question */
+ xorl %edx, %ecx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* CHR */
+ jnc L(73) /* highest byte is CHR => return pointer */
+ xorl %ecx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(73) /* found it => return pointer */
+ xorl %edx, %ecx /* restore original dword without reload */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %ecx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(73) /* highest byte is NUL => return NULL */
+ xorl %ecx, %edi /* (word+magic)^word */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jz L(1) /* no NUL found => restart loop */
+
+L(73): addl $4, %eax /* adjust pointer */
+L(72): addl $4, %eax
+L(71): addl $4, %eax
+
+ /* We now scan for the byte in which the character was matched.
+ But we have to take care of the case that a NUL char is
+ found before this in the dword. */
+
+L(7): testb %cl, %cl /* is first byte CHR? */
+ jz L(6) /* yes => return pointer */
+ cmpb %dl, %cl /* is first byte NUL? */
+ je L(6) /* yes => return NULL */
+ incl %eax /* it's not in the first byte */
+
+ testb %ch, %ch /* is second byte CHR? */
+ jz L(6) /* yes => return pointer */
+ cmpb %dl, %ch /* is second byte NUL? */
+ je L(6) /* yes => return NULL? */
+ incl %eax /* it's not in the second byte */
+
+ shrl $16, %ecx /* make upper byte accessible */
+ testb %cl, %cl /* is third byte CHR? */
+ jz L(6) /* yes => return pointer */
+ cmpb %dl, %cl /* is third byte NUL? */
+ je L(6) /* yes => return NULL */
+
+ /* It must be in the fourth byte and it cannot be NUL. */
+ incl %eax
+
+L(6): CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
+ RETURN_BOUNDED_POINTER (STR(%esp))
+ popl %edi /* restore saved register content */
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (__strchrnul))
+
+weak_alias (BP_SYM (__strchrnul), BP_SYM (strchrnul))
diff --git a/libc/sysdeps/i386/strcspn.S b/libc/sysdeps/i386/strcspn.S
new file mode 100644
index 000000000..df6a13660
--- /dev/null
+++ b/libc/sysdeps/i386/strcspn.S
@@ -0,0 +1,247 @@
+/* strcspn (str, ss) -- Return the length of the initial segment of STR
+ which contains no characters from SS.
+ For Intel 80x86, x>=3.
+ Copyright (C) 1994-1997,2000,2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+ Bug fixes by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define STR PARMS
+#define STOP STR+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (strcspn))
+ ENTER
+
+ movl STR(%esp), %edx
+ movl STOP(%esp), %eax
+ CHECK_BOUNDS_LOW (%edx, STR(%esp))
+
+ /* First we create a table with flags for all possible characters.
+ For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
+ supported by the C string functions we have 256 characters.
+ Before inserting marks for the stop characters we clear the whole
+ table. The unrolled form is much faster than a loop. */
+ xorl %ecx, %ecx /* %ecx = 0 !!! */
+
+ pushl %ecx /* make a 256 bytes long block filled with 0 */
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl $0 /* These immediate values make the label 2 */
+ cfi_adjust_cfa_offset (4)
+ pushl $0 /* to be aligned on a 16 byte boundary to */
+ cfi_adjust_cfa_offset (4)
+ pushl $0 /* get a better performance of the loop. */
+ cfi_adjust_cfa_offset (4)
+ pushl $0
+ cfi_adjust_cfa_offset (4)
+ pushl $0
+ cfi_adjust_cfa_offset (4)
+ pushl $0
+ cfi_adjust_cfa_offset (4)
+
+/* For understanding the following code remember that %ecx == 0 now.
+ Although all the following instruction only modify %cl we always
+ have a correct zero-extended 32-bit value in %ecx. */
+
+/* Don't change the "testb $0xff,%%cl" to "testb %%cl,%%cl". We want
+ longer instructions so that the next loop aligns without adding nops. */
+
+L(2): movb (%eax), %cl /* get byte from stopset */
+ testb %cl, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 1(%eax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 2(%eax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 3(%eax), %cl /* get byte from stopset */
+ addl $4, %eax /* increment stopset pointer */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+ testb $0xff, %cl /* is NUL char? */
+ jnz L(2) /* no => process next dword from stopset */
+
+L(1): leal -4(%edx), %eax /* prepare loop */
+
+ /* We use a neat trick for the following loop. Normally we would
+ have to test for two termination conditions
+ 1. a character in the stopset was found
+ and
+ 2. the end of the string was found
+ But as a sign that the character is in the stopset we store its
+ value in the table. But the value of NUL is NUL so the loop
+ terminates for NUL in every case. */
+
+L(3): addl $4, %eax /* adjust pointer for full loop round */
+
+ movb (%eax), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ je L(4) /* yes => return */
+
+ movb 1(%eax), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ je L(5) /* yes => return */
+
+ movb 2(%eax), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ je L(6) /* yes => return */
+
+ movb 3(%eax), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jne L(3) /* yes => return */
+
+ incl %eax /* adjust pointer */
+L(6): incl %eax
+L(5): incl %eax
+
+L(4): addl $256, %esp /* remove stopset */
+ cfi_adjust_cfa_offset (-256)
+ CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
+ subl %edx, %eax /* we have to return the number of valid
+ characters, so compute distance to first
+ non-valid character */
+ LEAVE
+ ret
+END (BP_SYM (strcspn))
+libc_hidden_builtin_def (strcspn)
diff --git a/libc/sysdeps/i386/string-inlines.c b/libc/sysdeps/i386/string-inlines.c
new file mode 100644
index 000000000..72a04b7d9
--- /dev/null
+++ b/libc/sysdeps/i386/string-inlines.c
@@ -0,0 +1,189 @@
+/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* <bits/string.h> and <bits/string2.h> declare some extern inline
+ functions. These functions are declared additionally here if
+ inlining is not possible. */
+
+#undef __USE_STRING_INLINES
+#define __USE_STRING_INLINES
+#define _FORCE_INLINES
+#define __STRING_INLINE /* empty */
+#define __NO_INLINE__
+
+#include <string.h>
+#undef index
+#undef rindex
+
+#undef __NO_INLINE__
+#include <bits/string.h>
+#include <bits/string2.h>
+
+/* Functions which are inlines in i486 but not i386. */
+void *
+__memcpy_by2 (void *dest, const void *src, size_t n)
+{
+ return memcpy (dest, src, n);
+}
+strong_alias (__memcpy_by2, __memcpy_by4)
+strong_alias (__memcpy_by2, __memcpy_g)
+strong_alias (__memcpy_by2, __memcpy_g_internal)
+
+void *
+__memset_ccn_by2 (void *s, unsigned int c, size_t n)
+{
+ return memset (s, c & 0xff, n);
+}
+strong_alias (__memset_ccn_by2, __memset_ccn_by4)
+
+void *
+__memset_gcn_by2 (void *s, int c, size_t n)
+{
+ return memset (s, c, n);
+}
+strong_alias (__memset_gcn_by2, __memset_gcn_by4)
+
+size_t
+__strlen_g (const char *s)
+{
+ return strlen (s);
+}
+
+char *
+__strcpy_g (char *d, const char *s)
+{
+ return strcpy (d, s);
+}
+
+char *
+__mempcpy_by2 (char *d, const char *s, size_t n)
+{
+ return mempcpy (d, s, n);
+}
+strong_alias (__mempcpy_by2, __mempcpy_by4)
+strong_alias (__mempcpy_by2, __mempcpy_byn)
+
+char *
+__stpcpy_g (char *d, const char *s)
+{
+ return stpcpy (d, s);
+}
+
+char *
+__strncpy_by2 (char *d, const char s[], size_t srclen, size_t n)
+{
+ return strncpy (d, s, n);
+}
+strong_alias (__strncpy_by2, __strncpy_by4)
+strong_alias (__strncpy_by2, __strncpy_byn)
+
+char *
+__strncpy_gg (char *d, const char *s, size_t n)
+{
+ return strncpy (d, s, n);
+}
+
+char *
+__strcat_c (char *d, const char s[], size_t srclen)
+{
+ return strcat (d, s);
+}
+
+char *
+__strcat_g (char *d, const char *s)
+{
+ return strcat (d, s);
+}
+
+char *
+__strncat_g (char *d, const char s[], size_t n)
+{
+ return strncat (d, s, n);
+}
+
+int
+__strcmp_gg (const char *s1, const char *s2)
+{
+ return strcmp (s1, s2);
+}
+
+int
+__strncmp_g (const char *s1, const char *s2, size_t n)
+{
+ return strncmp (s1, s2, n);
+}
+
+char *
+__strrchr_c (const char *s, int c)
+{
+ return strrchr (s, c >> 8);
+}
+
+char *
+__strrchr_g (const char *s, int c)
+{
+ return strrchr (s, c);
+}
+
+size_t
+__strcspn_cg (const char *s, const char reject[], size_t reject_len)
+{
+ return strcspn (s, reject);
+}
+
+size_t
+__strcspn_g (const char *s, const char *reject)
+{
+ return strcspn (s, reject);
+}
+
+size_t
+__strspn_cg (const char *s, const char accept[], size_t accept_len)
+{
+ return strspn (s, accept);
+}
+
+size_t
+__strspn_g (const char *s, const char *accept)
+{
+ return strspn (s, accept);
+}
+
+char *
+__strpbrk_cg (const char *s, const char accept[], size_t accept_len)
+{
+ return strpbrk (s, accept);
+}
+
+char *
+__strpbrk_g (const char *s, const char *accept)
+{
+ return strpbrk (s, accept);
+}
+
+char *
+__strstr_cg (const char *haystack, const char needle[], size_t needle_len)
+{
+ return strstr (haystack, needle);
+}
+
+char *
+__strstr_g (const char *haystack, const char needle[])
+{
+ return strstr (haystack, needle);
+}
diff --git a/libc/sysdeps/i386/strlen.c b/libc/sysdeps/i386/strlen.c
new file mode 100644
index 000000000..93bf1506e
--- /dev/null
+++ b/libc/sysdeps/i386/strlen.c
@@ -0,0 +1,36 @@
+/* Determine the length of a string. For Intel 80x86, x>=3.
+ Copyright (C) 1991,1992,1993,1996,1997,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+
+size_t
+strlen (const char *str)
+{
+ int cnt;
+
+ asm("cld\n" /* Search forward. */
+ /* Some old versions of gas need `repne' instead of `repnz'. */
+ "repnz\n" /* Look for a zero byte. */
+ "scasb" /* %0, %1, %3 */ :
+ "=c" (cnt) : "D" (str), "0" (-1), "a" (0));
+
+ return -2 - cnt;
+}
+libc_hidden_builtin_def (strlen)
diff --git a/libc/sysdeps/i386/strpbrk.S b/libc/sysdeps/i386/strpbrk.S
new file mode 100644
index 000000000..1f78e2064
--- /dev/null
+++ b/libc/sysdeps/i386/strpbrk.S
@@ -0,0 +1,256 @@
+/* strcspn (str, ss) -- Return the length of the initial segement of STR
+ which contains no characters from SS.
+ For Intel 80x86, x>=3.
+ Copyright (C) 1994-1997, 2000, 2003, 2005 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+ Bug fixes by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define RTN PARMS
+#define STR RTN+RTN_SIZE
+#define STOP STR+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (strpbrk))
+ ENTER
+
+ movl STR(%esp), %edx
+ movl STOP(%esp), %eax
+ CHECK_BOUNDS_LOW (%edx, STR(%esp))
+
+ /* First we create a table with flags for all possible characters.
+ For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
+ supported by the C string functions we have 256 characters.
+ Before inserting marks for the stop characters we clear the whole
+ table. The unrolled form is much faster than a loop. */
+ xorl %ecx, %ecx /* %ecx = 0 !!! */
+
+ pushl %ecx /* make a 256 bytes long block filled with 0 */
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl $0 /* These immediate values make the label 2 */
+ cfi_adjust_cfa_offset (4)
+ pushl $0 /* to be aligned on a 16 byte boundary to */
+ cfi_adjust_cfa_offset (4)
+ pushl $0 /* get a better performance of the loop. */
+ cfi_adjust_cfa_offset (4)
+ pushl $0
+ cfi_adjust_cfa_offset (4)
+ pushl $0
+ cfi_adjust_cfa_offset (4)
+ pushl $0
+ cfi_adjust_cfa_offset (4)
+
+/* For understanding the following code remember that %ecx == 0 now.
+ Although all the following instruction only modify %cl we always
+ have a correct zero-extended 32-bit value in %ecx. */
+
+/* Don't change the "testb $0xff,%%cl" to "testb %%cl,%%cl". We want
+ longer instructions so that the next loop aligns without adding nops. */
+
+L(2): movb (%eax), %cl /* get byte from stopset */
+ testb %cl, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 1(%eax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 2(%eax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 3(%eax), %cl /* get byte from stopset */
+ addl $4, %eax /* increment stopset pointer */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+ testb $0xff, %cl /* is NUL char? */
+ jnz L(2) /* no => process next dword from stopset */
+
+L(1): leal -4(%edx), %eax /* prepare loop */
+
+ /* We use a neat trick for the following loop. Normally we would
+ have to test for two termination conditions
+ 1. a character in the stopset was found
+ and
+ 2. the end of the string was found
+ But as a sign that the chracter is in the stopset we store its
+ value in the table. But the value of NUL is NUL so the loop
+ terminates for NUL in every case. */
+
+L(3): addl $4, %eax /* adjust pointer for full loop round */
+
+ movb (%eax), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ je L(4) /* yes => return */
+
+ movb 1(%eax), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ je L(5) /* yes => return */
+
+ movb 2(%eax), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ je L(6) /* yes => return */
+
+ movb 3(%eax), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jne L(3) /* yes => return */
+
+ incl %eax /* adjust pointer */
+L(6): incl %eax
+L(5): incl %eax
+
+L(4): addl $256, %esp /* remove stopset */
+ cfi_adjust_cfa_offset (-256)
+
+ CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
+ orb %cl, %cl /* was last character NUL? */
+ jnz L(7) /* no => return pointer */
+ xorl %eax, %eax
+ RETURN_NULL_BOUNDED_POINTER
+
+ LEAVE
+ RET_PTR
+
+L(7): RETURN_BOUNDED_POINTER (STR(%esp))
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (strpbrk))
+libc_hidden_builtin_def (strpbrk)
diff --git a/libc/sysdeps/i386/strrchr.S b/libc/sysdeps/i386/strrchr.S
new file mode 100644
index 000000000..98c0c08bd
--- /dev/null
+++ b/libc/sysdeps/i386/strrchr.S
@@ -0,0 +1,342 @@
+/* strrchr (str, ch) -- Return pointer to last occurrence of CH in STR.
+ For Intel 80x86, x>=3.
+ Copyright (C) 1994-1997, 2000, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+ Some optimisations by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+8 /* space for 2 saved regs */
+#define RTN PARMS
+#define STR RTN+RTN_SIZE
+#define CHR STR+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (strrchr))
+ ENTER
+
+ pushl %edi /* Save callee-safe registers used here. */
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (edi, 0)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+
+ xorl %eax, %eax
+ movl STR(%esp), %esi
+ cfi_rel_offset (esi, 0)
+ movl CHR(%esp), %ecx
+ CHECK_BOUNDS_LOW (%esi, STR(%esp))
+
+ /* At the moment %ecx contains C. What we need for the
+ algorithm is C in all bytes of the dword. Avoid
+ operations on 16 bit words because these require an
+ prefix byte (and one more cycle). */
+ movb %cl, %ch /* now it is 0|0|c|c */
+ movl %ecx, %edx
+ shll $16, %ecx /* now it is c|c|0|0 */
+ movw %dx, %cx /* and finally c|c|c|c */
+
+ /* Before we start with the main loop we process single bytes
+ until the source pointer is aligned. This has two reasons:
+ 1. aligned 32-bit memory access is faster
+ and (more important)
+ 2. we process in the main loop 32 bit in one step although
+ we don't know the end of the string. But accessing at
+ 4-byte alignment guarantees that we never access illegal
+ memory if this would not also be done by the trivial
+ implementation (this is because all processor inherent
+ boundaries are multiples of 4. */
+
+ testl $3, %esi /* correctly aligned ? */
+ jz L(19) /* yes => begin loop */
+ movb (%esi), %dl /* load byte in question (we need it twice) */
+ cmpb %dl, %cl /* compare byte */
+ jne L(11) /* target found => return */
+ movl %esi, %eax /* remember pointer as possible result */
+L(11): orb %dl, %dl /* is NUL? */
+ jz L(2) /* yes => return NULL */
+ incl %esi /* increment pointer */
+
+ testl $3, %esi /* correctly aligned ? */
+ jz L(19) /* yes => begin loop */
+ movb (%esi), %dl /* load byte in question (we need it twice) */
+ cmpb %dl, %cl /* compare byte */
+ jne L(12) /* target found => return */
+ movl %esi, %eax /* remember pointer as result */
+L(12): orb %dl, %dl /* is NUL? */
+ jz L(2) /* yes => return NULL */
+ incl %esi /* increment pointer */
+
+ testl $3, %esi /* correctly aligned ? */
+ jz L(19) /* yes => begin loop */
+ movb (%esi), %dl /* load byte in question (we need it twice) */
+ cmpb %dl, %cl /* compare byte */
+ jne L(13) /* target found => return */
+ movl %esi, %eax /* remember pointer as result */
+L(13): orb %dl, %dl /* is NUL? */
+ jz L(2) /* yes => return NULL */
+ incl %esi /* increment pointer */
+
+ /* No we have reached alignment. */
+ jmp L(19) /* begin loop */
+
+ /* We exit the loop if adding MAGIC_BITS to LONGWORD fails to
+ change any of the hole bits of LONGWORD.
+
+ 1) Is this safe? Will it catch all the zero bytes?
+ Suppose there is a byte with all zeros. Any carry bits
+ propagating from its left will fall into the hole at its
+ least significant bit and stop. Since there will be no
+ carry from its most significant bit, the LSB of the
+ byte to the left will be unchanged, and the zero will be
+ detected.
+
+ 2) Is this worthwhile? Will it ignore everything except
+ zero bytes? Suppose every byte of LONGWORD has a bit set
+ somewhere. There will be a carry into bit 8. If bit 8
+ is set, this will carry into bit 16. If bit 8 is clear,
+ one of bits 9-15 must be set, so there will be a carry
+ into bit 16. Similarly, there will be a carry into bit
+ 24. If one of bits 24-31 is set, there will be a carry
+ into bit 32 (=carry flag), so all of the hole bits will
+ be changed.
+
+ 3) But wait! Aren't we looking for C, not zero?
+ Good point. So what we do is XOR LONGWORD with a longword,
+ each of whose bytes is C. This turns each byte that is C
+ into a zero. */
+
+ /* Each round the main loop processes 16 bytes. */
+
+ /* Jump to here when the character is detected. We chose this
+ way around because the character one is looking for is not
+ as frequent as the rest and taking a conditional jump is more
+ expensive than ignoring it.
+
+ Some more words to the code below: it might not be obvious why
+ we decrement the source pointer here. In the loop the pointer
+ is not pre-incremented and so it still points before the word
+ we are looking at. But you should take a look at the instruction
+ which gets executed before we get into the loop: `addl $16, %esi'.
+ This makes the following subs into adds. */
+
+ /* These fill bytes make the main loop be correctly aligned.
+ We cannot use align because it is not the following instruction
+ which should be aligned. */
+ .byte 0, 0
+#ifndef PROF
+ /* Profiling adds some code and so changes the alignment. */
+ .byte 0
+#endif
+
+L(4): subl $4, %esi /* adjust pointer */
+L(41): subl $4, %esi
+L(42): subl $4, %esi
+L(43): testl $0xff000000, %edx /* is highest byte == C? */
+ jnz L(33) /* no => try other bytes */
+ leal 15(%esi), %eax /* store address as result */
+ jmp L(1) /* and start loop again */
+
+L(3): subl $4, %esi /* adjust pointer */
+L(31): subl $4, %esi
+L(32): subl $4, %esi
+L(33): testl $0xff0000, %edx /* is C in third byte? */
+ jnz L(51) /* no => try other bytes */
+ leal 14(%esi), %eax /* store address as result */
+ jmp L(1) /* and start loop again */
+
+L(51):
+ /* At this point we know that the byte is in one of the lower bytes.
+ We make a guess and correct it if necessary. This reduces the
+ number of necessary jumps. */
+ leal 12(%esi), %eax /* guess address of lowest byte as result */
+ testb %dh, %dh /* is guess correct? */
+ jnz L(1) /* yes => start loop */
+ leal 13(%esi), %eax /* correct guess to second byte */
+
+L(1): addl $16, %esi /* increment pointer for full round */
+
+L(19): movl (%esi), %edx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %edx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+
+ /* According to the algorithm we had to reverse the effect of the
+ XOR first and then test the overflow bits. But because the
+ following XOR would destroy the carry flag and it would (in a
+ representation with more than 32 bits) not alter then last
+ overflow, we can now test this condition. If no carry is signaled
+ no overflow must have occurred in the last byte => it was 0. */
+
+ jnc L(20) /* found NUL => check last word */
+
+ /* We are only interested in carry bits that change due to the
+ previous add, so remove original bits */
+ xorl %edx, %edi /* (word+magic)^word */
+
+ /* Now test for the other three overflow bits. */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ /* If at least one byte of the word is C we don't get 0 in %edi. */
+ jnz L(20) /* found NUL => check last word */
+
+ /* Now we made sure the dword does not contain the character we are
+ looking for. But because we deal with strings we have to check
+ for the end of string before testing the next dword. */
+
+ xorl %ecx, %edx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %edx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(4) /* highest byte is C => examine dword */
+ xorl %edx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(3) /* C is detected in the word => examine it */
+
+ movl 4(%esi), %edx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %edx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(21) /* found NUL => check last word */
+ xorl %edx, %edi /* (word+magic)^word */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(21) /* found NUL => check last word */
+ xorl %ecx, %edx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %edx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(41) /* highest byte is C => examine dword */
+ xorl %edx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(31) /* C is detected in the word => examine it */
+
+ movl 8(%esi), %edx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %edx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(22) /* found NUL => check last word */
+ xorl %edx, %edi /* (word+magic)^word */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(22) /* found NUL => check last word */
+ xorl %ecx, %edx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %edx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(42) /* highest byte is C => examine dword */
+ xorl %edx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(32) /* C is detected in the word => examine it */
+
+ movl 12(%esi), %edx /* get word (= 4 bytes) in question */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %edx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(23) /* found NUL => check last word */
+ xorl %edx, %edi /* (word+magic)^word */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz L(23) /* found NUL => check last word */
+ xorl %ecx, %edx /* XOR with word c|c|c|c => bytes of str == c
+ are now 0 */
+ movl $0xfefefeff, %edi /* magic value */
+ addl %edx, %edi /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc L(43) /* highest byte is C => examine dword */
+ xorl %edx, %edi /* ((word^charmask)+magic)^(word^charmask) */
+ orl $0xfefefeff, %edi /* set all non-carry bits */
+ incl %edi /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jz L(1) /* C is not detected => restart loop */
+ jmp L(33) /* examine word */
+
+L(23): addl $4, %esi /* adjust pointer */
+L(22): addl $4, %esi
+L(21): addl $4, %esi
+
+ /* What remains to do is to test which byte the NUL char is and
+ whether the searched character appears in one of the bytes
+ before. A special case is that the searched byte maybe NUL.
+ In this case a pointer to the terminating NUL char has to be
+ returned. */
+
+L(20): cmpb %cl, %dl /* is first byte == C? */
+ jne L(24) /* no => skip */
+ movl %esi, %eax /* store address as result */
+L(24): testb %dl, %dl /* is first byte == NUL? */
+ jz L(2) /* yes => return */
+
+ cmpb %cl, %dh /* is second byte == C? */
+ jne L(25) /* no => skip */
+ leal 1(%esi), %eax /* store address as result */
+L(25): testb %dh, %dh /* is second byte == NUL? */
+ jz L(2) /* yes => return */
+
+ shrl $16,%edx /* make upper bytes accessible */
+ cmpb %cl, %dl /* is third byte == C */
+ jne L(26) /* no => skip */
+ leal 2(%esi), %eax /* store address as result */
+L(26): testb %dl, %dl /* is third byte == NUL */
+ jz L(2) /* yes => return */
+
+ cmpb %cl, %dh /* is fourth byte == C */
+ jne L(2) /* no => skip */
+ leal 3(%esi), %eax /* store address as result */
+
+L(2): CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
+ RETURN_BOUNDED_POINTER (STR(%esp))
+ popl %esi /* restore saved register content */
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (strrchr))
+
+weak_alias (BP_SYM (strrchr), BP_SYM (rindex))
+libc_hidden_builtin_def (strrchr)
diff --git a/libc/sysdeps/i386/strspn.S b/libc/sysdeps/i386/strspn.S
new file mode 100644
index 000000000..c061438a0
--- /dev/null
+++ b/libc/sysdeps/i386/strspn.S
@@ -0,0 +1,247 @@
+/* strcspn (str, ss) -- Return the length of the initial segment of STR
+ which contains only characters from SS.
+ For Intel 80x86, x>=3.
+ Copyright (C) 1994-1997, 2000, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+ Bug fixes by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define STR PARMS
+#define SKIP STR+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (strspn))
+ ENTER
+
+ movl STR(%esp), %edx
+ movl SKIP(%esp), %eax
+ CHECK_BOUNDS_LOW (%edx, STR(%esp))
+
+ /* First we create a table with flags for all possible characters.
+ For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
+ supported by the C string functions we have 256 characters.
+ Before inserting marks for the stop characters we clear the whole
+ table. The unrolled form is much faster than a loop. */
+ xorl %ecx, %ecx /* %ecx = 0 !!! */
+
+ pushl %ecx /* make a 256 bytes long block filled with 0 */
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl $0 /* These immediate values make the label 2 */
+ cfi_adjust_cfa_offset (4)
+ pushl $0 /* to be aligned on a 16 byte boundary to */
+ cfi_adjust_cfa_offset (4)
+ pushl $0 /* get a better performance of the loop. */
+ cfi_adjust_cfa_offset (4)
+ pushl $0
+ cfi_adjust_cfa_offset (4)
+ pushl $0
+ cfi_adjust_cfa_offset (4)
+ pushl $0
+ cfi_adjust_cfa_offset (4)
+
+/* For understanding the following code remember that %ecx == 0 now.
+ Although all the following instruction only modify %cl we always
+ have a correct zero-extended 32-bit value in %ecx. */
+
+/* Don't change the "testb $0xff,%%cl" to "testb %%cl,%%cl". We want
+ longer instructions so that the next loop aligns without adding nops. */
+
+L(2): movb (%eax), %cl /* get byte from stopset */
+ testb %cl, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 1(%eax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 2(%eax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 3(%eax), %cl /* get byte from stopset */
+ addl $4, %eax /* increment stopset pointer */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+ testb $0xff, %cl /* is NUL char? */
+ jnz L(2) /* no => process next dword from stopset */
+
+L(1): leal -4(%edx), %eax /* prepare loop */
+
+ /* We use a neat trick for the following loop. Normally we would
+ have to test for two termination conditions
+ 1. a character in the stopset was found
+ and
+ 2. the end of the string was found
+ But as a sign that the character is in the stopset we store its
+ value in the table. But the value of NUL is NUL so the loop
+ terminates for NUL in every case. */
+
+L(3): addl $4, %eax /* adjust pointer for full loop round */
+
+ movb (%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ jz L(4) /* no => return */
+
+ movb 1(%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ jz L(5) /* no => return */
+
+ movb 2(%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ jz L(6) /* no => return */
+
+ movb 3(%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ jnz L(3) /* yes => start loop again */
+
+ incl %eax /* adjust pointer */
+L(6): incl %eax
+L(5): incl %eax
+
+L(4): addl $256, %esp /* remove stopset */
+ cfi_adjust_cfa_offset (-256)
+ CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
+ subl %edx, %eax /* we have to return the number of valid
+ characters, so compute distance to first
+ non-valid character */
+ LEAVE
+ ret
+END (BP_SYM (strspn))
+libc_hidden_builtin_def (strspn)
diff --git a/libc/sysdeps/i386/strtok.S b/libc/sysdeps/i386/strtok.S
new file mode 100644
index 000000000..c5f40a83b
--- /dev/null
+++ b/libc/sysdeps/i386/strtok.S
@@ -0,0 +1,395 @@
+/* strtok (str, delim) -- Return next DELIM separated token from STR.
+ For Intel 80x86, x>=3.
+ Copyright (C) 1996-1998,2000,2001,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+/* This file can be used for three variants of the strtok function:
+
+ strtok:
+ INPUT PARAMETER:
+ str (sp + 4)
+ delim (sp + 8)
+
+ strtok_r:
+ INPUT PARAMETER:
+ str (sp + 4)
+ delim (sp + 8)
+ save_ptr (sp + 12)
+
+ We do a common implementation here. */
+
+#ifdef USE_AS_STRTOK_R
+# define SAVE_PTR 0(%ecx)
+#else
+ .bss
+ .local save_ptr
+ ASM_TYPE_DIRECTIVE (save_ptr, @object)
+ .size save_ptr, 4
+save_ptr:
+# if __BOUNDED_POINTERS__
+ .space 12
+# else
+ .space 4
+# endif
+
+# ifdef PIC
+# define SAVE_PTR save_ptr@GOTOFF(%ebx)
+# else
+# define SAVE_PTR save_ptr
+# endif
+
+# define FUNCTION strtok
+#endif
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define RTN PARMS
+#define STR RTN+RTN_SIZE
+#define DELIM STR+PTR_SIZE
+#define SAVE DELIM+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (FUNCTION))
+ ENTER
+
+ movl STR(%esp), %edx
+ movl DELIM(%esp), %eax
+ CHECK_BOUNDS_LOW (%eax, DELIM(%esp))
+
+#if !defined USE_AS_STRTOK_R && defined PIC
+ pushl %ebx /* Save PIC register. */
+ cfi_adjust_cfa_offset (4)
+ call L(here)
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebx, 0)
+L(here):
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ebx
+#endif
+
+ /* If the pointer is NULL we have to use the stored value of
+ the last run. */
+ cmpl $0, %edx
+#if __BOUNDED_POINTERS__
+ movl SAVE(%esp), %ecx
+ je L(0)
+ /* Save bounds of incoming non-NULL STR into save area. */
+ movl 4+STR(%esp), %eax
+ movl %eax, 4+SAVE_PTR
+ movl 8+STR(%esp), %eax
+ movl %eax, 8+SAVE_PTR
+ CHECK_BOUNDS_LOW (%edx, SAVE_PTR)
+ jmp L(1)
+L(0): movl SAVE_PTR, %edx
+ CHECK_BOUNDS_LOW (%edx, SAVE_PTR)
+ jmp L(1)
+#else
+ jne L(1)
+#endif
+
+#ifdef USE_AS_STRTOK_R
+ /* The value is stored in the third argument. */
+ movl SAVE(%esp), %edx
+ movl (%edx), %edx
+#else
+ /* The value is in the local variable defined above. But
+ we have to take care for PIC code. */
+ movl SAVE_PTR, %edx
+#endif
+ testl %edx, %edx
+ jz L(returnNULL)
+
+L(1):
+ /* First we create a table with flags for all possible characters.
+ For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
+ supported by the C string functions we have 256 characters.
+ Before inserting marks for the stop characters we clear the whole
+ table. The unrolled form is much faster than a loop. */
+ xorl %ecx, %ecx /* %ecx = 0 !!! */
+
+ pushl %ecx /* make a 256 bytes long block filled with 0 */
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+ pushl $0 /* These immediate values make the label 2 */
+ cfi_adjust_cfa_offset (4)
+ pushl $0 /* to be aligned on a 16 byte boundary to */
+ cfi_adjust_cfa_offset (4)
+ pushl $0 /* get a better performance of the loop. */
+ cfi_adjust_cfa_offset (4)
+ pushl $0
+ cfi_adjust_cfa_offset (4)
+ pushl $0
+ cfi_adjust_cfa_offset (4)
+ pushl $0
+ cfi_adjust_cfa_offset (4)
+
+/* For understanding the following code remember that %ecx == 0 now.
+ Although all the following instruction only modify %cl we always
+ have a correct zero-extended 32-bit value in %ecx. */
+
+L(2): movb (%eax), %cl /* get byte from stopset */
+ testb %cl, %cl /* is NUL char? */
+ jz L(1_1) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 1(%eax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1_2) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 2(%eax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1_3) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 3(%eax), %cl /* get byte from stopset */
+ addl $4, %eax /* increment stopset pointer */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+ testb $0xff, %cl /* is NUL char? */
+ jnz L(2) /* no => process next dword from stopset */
+
+#if __BOUNDED_POINTERS__
+ jmp L(1_0) /* pointer is correct for bounds check */
+L(1_3): incl %eax /* adjust pointer for bounds check */
+L(1_2): incl %eax /* ditto */
+L(1_1): incl %eax /* ditto */
+L(1_0): CHECK_BOUNDS_HIGH (%eax, DELIM(%esp), jbe)
+#else
+L(1_3):; L(1_2):; L(1_1): /* fall through */
+#endif
+ leal -4(%edx), %eax /* prepare loop */
+
+ /* We use a neat trick for the following loop. Normally we would
+ have to test for two termination conditions
+ 1. a character in the stopset was found
+ and
+ 2. the end of the string was found
+ As a sign that the character is in the stopset we store its
+ value in the table. The value of NUL is NUL so the loop
+ terminates for NUL in every case. */
+
+L(3): addl $4, %eax /* adjust pointer for full loop round */
+
+ movb (%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jz L(4) /* no => start of token */
+
+ movb 1(%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jz L(5) /* no => start of token */
+
+ movb 2(%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jz L(6) /* no => start of token */
+
+ movb 3(%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jnz L(3) /* yes => start of loop */
+
+ incl %eax /* adjust pointer */
+L(6): incl %eax
+L(5): incl %eax
+
+ /* Now we have to terminate the string. */
+
+L(4): leal -4(%eax), %edx /* We use %EDX for the next run. */
+
+L(7): addl $4, %edx /* adjust pointer for full loop round */
+
+ movb (%edx), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ je L(8) /* yes => return */
+
+ movb 1(%edx), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ je L(9) /* yes => return */
+
+ movb 2(%edx), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ je L(10) /* yes => return */
+
+ movb 3(%edx), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ jne L(7) /* no => start loop again */
+
+ incl %edx /* adjust pointer */
+L(10): incl %edx
+L(9): incl %edx
+
+L(8): /* Remove the stopset table. */
+ addl $256, %esp
+ cfi_adjust_cfa_offset (-256)
+
+ cmpl %eax, %edx
+ je L(returnNULL) /* There was no token anymore. */
+
+ movb $0, (%edx) /* Terminate string. */
+
+ /* Are we at end of string? */
+ cmpb $0, %cl
+ je L(11)
+
+ incl %edx
+L(11):
+
+ /* Store the pointer to the next character. */
+#ifdef USE_AS_STRTOK_R
+ movl SAVE(%esp), %ecx
+#endif
+ movl %edx, SAVE_PTR
+ CHECK_BOUNDS_HIGH (%edx, SAVE_PTR, jb)
+ RETURN_BOUNDED_POINTER (SAVE_PTR)
+
+L(epilogue):
+#if !defined USE_AS_STRTOK_R && defined PIC
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+#endif
+ LEAVE
+ RET_PTR
+
+L(returnNULL):
+ xorl %eax, %eax
+#ifdef USE_AS_STRTOK_R
+ movl SAVE(%esp), %ecx
+#endif
+ movl %edx, SAVE_PTR
+ RETURN_NULL_BOUNDED_POINTER
+ jmp L(epilogue)
+
+END (BP_SYM (FUNCTION))
diff --git a/libc/sysdeps/i386/strtok_r.S b/libc/sysdeps/i386/strtok_r.S
new file mode 100644
index 000000000..f4a6a2c40
--- /dev/null
+++ b/libc/sysdeps/i386/strtok_r.S
@@ -0,0 +1,5 @@
+#define FUNCTION __strtok_r
+#define USE_AS_STRTOK_R 1
+#include <sysdeps/i386/strtok.S>
+weak_alias (BP_SYM (__strtok_r), BP_SYM (strtok_r))
+strong_alias (BP_SYM (__strtok_r), BP_SYM (__GI___strtok_r))
diff --git a/libc/sysdeps/i386/sub_n.S b/libc/sysdeps/i386/sub_n.S
new file mode 100644
index 000000000..e1e62b89d
--- /dev/null
+++ b/libc/sysdeps/i386/sub_n.S
@@ -0,0 +1,124 @@
+/* i80386 __mpn_sub_n -- Add two limb vectors of the same length > 0 and store
+ sum in a third limb vector.
+ Copyright (C) 1992,1994,1995,1997,1998,2000,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+8 /* space for 2 saved regs */
+#define RES PARMS
+#define S1 RES+PTR_SIZE
+#define S2 S1+PTR_SIZE
+#define SIZE S2+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__mpn_sub_n))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp),%edi
+ cfi_rel_offset (edi, 4)
+ movl S1(%esp),%esi
+ cfi_rel_offset (esi, 0)
+ movl S2(%esp),%edx
+ movl SIZE(%esp),%ecx
+#if __BOUNDED_POINTERS__
+ shll $2, %ecx /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, S1(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%edx, S2(%esp), %ecx)
+ shrl $2, %ecx
+#endif
+ movl %ecx,%eax
+ shrl $3,%ecx /* compute count for unrolled loop */
+ negl %eax
+ andl $7,%eax /* get index where to start loop */
+ jz L(oop) /* necessary special case for 0 */
+ incl %ecx /* adjust loop count */
+ shll $2,%eax /* adjustment for pointers... */
+ subl %eax,%edi /* ... since they are offset ... */
+ subl %eax,%esi /* ... by a constant when we ... */
+ subl %eax,%edx /* ... enter the loop */
+ shrl $2,%eax /* restore previous value */
+#ifdef PIC
+/* Calculate start address in loop for PIC. Due to limitations in some
+ assemblers, Loop-L0-3 cannot be put into the leal */
+ call L(0)
+ cfi_adjust_cfa_offset (4)
+L(0): leal (%eax,%eax,8),%eax
+ addl (%esp),%eax
+ addl $(L(oop)-L(0)-3),%eax
+ addl $4,%esp
+ cfi_adjust_cfa_offset (-4)
+#else
+/* Calculate start address in loop for non-PIC. */
+ leal (L(oop) - 3)(%eax,%eax,8),%eax
+#endif
+ jmp *%eax /* jump into loop */
+ ALIGN (3)
+L(oop): movl (%esi),%eax
+ sbbl (%edx),%eax
+ movl %eax,(%edi)
+ movl 4(%esi),%eax
+ sbbl 4(%edx),%eax
+ movl %eax,4(%edi)
+ movl 8(%esi),%eax
+ sbbl 8(%edx),%eax
+ movl %eax,8(%edi)
+ movl 12(%esi),%eax
+ sbbl 12(%edx),%eax
+ movl %eax,12(%edi)
+ movl 16(%esi),%eax
+ sbbl 16(%edx),%eax
+ movl %eax,16(%edi)
+ movl 20(%esi),%eax
+ sbbl 20(%edx),%eax
+ movl %eax,20(%edi)
+ movl 24(%esi),%eax
+ sbbl 24(%edx),%eax
+ movl %eax,24(%edi)
+ movl 28(%esi),%eax
+ sbbl 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz L(oop)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+END (BP_SYM (__mpn_sub_n))
diff --git a/libc/sysdeps/i386/submul_1.S b/libc/sysdeps/i386/submul_1.S
new file mode 100644
index 000000000..7f8523d96
--- /dev/null
+++ b/libc/sysdeps/i386/submul_1.S
@@ -0,0 +1,97 @@
+/* i80386 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+ the result from a second limb vector.
+ Copyright (C) 1992,1994,1997,1998,2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+16 /* space for 4 saved regs */
+#define RES PARMS
+#define S1 RES+PTR_SIZE
+#define SIZE S1+PTR_SIZE
+#define S2LIMB SIZE+4
+
+#define res_ptr edi
+#define s1_ptr esi
+#define sizeP ecx
+#define s2_limb ebx
+
+ .text
+ENTRY (BP_SYM (__mpn_submul_1))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (edi, 12)
+ cfi_rel_offset (esi, 8)
+ cfi_rel_offset (ebp, 4)
+ cfi_rel_offset (ebx, 0)
+
+ movl RES(%esp), %res_ptr
+ movl S1(%esp), %s1_ptr
+ movl SIZE(%esp), %sizeP
+ movl S2LIMB(%esp), %s2_limb
+#if __BOUNDED_POINTERS__
+ shll $2, %sizeP /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%res_ptr, RES(%esp), %sizeP)
+ CHECK_BOUNDS_BOTH_WIDE (%s1_ptr, S1(%esp), %sizeP)
+ shrl $2, %sizeP
+#endif
+ leal (%res_ptr,%sizeP,4), %res_ptr
+ leal (%s1_ptr,%sizeP,4), %s1_ptr
+ negl %sizeP
+ xorl %ebp, %ebp
+ ALIGN (3)
+L(oop):
+ movl (%s1_ptr,%sizeP,4), %eax
+ mull %s2_limb
+ addl %ebp, %eax
+ adcl $0, %edx
+ subl %eax, (%res_ptr,%sizeP,4)
+ adcl $0, %edx
+ movl %edx, %ebp
+
+ incl %sizeP
+ jnz L(oop)
+ movl %ebp, %eax
+
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+END (BP_SYM (__mpn_submul_1))
diff --git a/libc/sysdeps/i386/sys/ucontext.h b/libc/sysdeps/i386/sys/ucontext.h
new file mode 100644
index 000000000..0202eb0e0
--- /dev/null
+++ b/libc/sysdeps/i386/sys/ucontext.h
@@ -0,0 +1,120 @@
+/* Copyright (C) 1997,99,2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* System V/i386 ABI compliant context switching support. */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+
+/* Type for general register. */
+typedef int greg_t;
+
+/* Number of general registers. */
+#define NGREG 19
+
+/* Container for all general registers. */
+typedef greg_t gregset_t[NGREG];
+
+/* Number of each register is the `gregset_t' array. */
+enum
+{
+ REG_GS = 0,
+#define REG_GS REG_GS
+ REG_FS,
+#define REG_FS REG_FS
+ REG_ES,
+#define REG_ES REG_ES
+ REG_DS,
+#define REG_DS REG_DS
+ REG_EDI,
+#define REG_EDI REG_EDI
+ REG_ESI,
+#define REG_ESI REG_ESI
+ REG_EBP,
+#define REG_EBP REG_EBP
+ REG_ESP,
+#define REG_ESP REG_ESP
+ REG_EBX,
+#define REG_EBX REG_EBX
+ REG_EDX,
+#define REG_EDX REG_EDX
+ REG_ECX,
+#define REG_ECX REG_ECX
+ REG_EAX,
+#define REG_EAX REG_EAX
+ REG_TRAPNO,
+#define REG_TRAPNO REG_TRAPNO
+ REG_ERR,
+#define REG_ERR REG_ERR
+ REG_EIP,
+#define REG_EIP REG_EIP
+ REG_CS,
+#define REG_CS REG_CS
+ REG_EFL,
+#define REG_EFL REG_EFL
+ REG_UESP,
+#define REG_UESP REG_UESP
+ REG_SS
+#define REG_SS REG_SS
+};
+
+/* Structure to describe FPU registers. */
+typedef struct fpregset
+ {
+ union
+ {
+ struct fpchip_state
+ {
+ int state[27];
+ int status;
+ } fpchip_state;
+
+ struct fp_emul_space
+ {
+ char fp_emul[246];
+ char fp_epad[2];
+ } fp_emul_space;
+
+ int f_fpregs[62];
+ } fp_reg_set;
+
+ long int f_wregs[33];
+ } fpregset_t;
+
+/* Context to describe whole processor state. */
+typedef struct
+ {
+ gregset_t gregs;
+ fpregset_t fpregs;
+ } mcontext_t;
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ __sigset_t uc_sigmask;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ long int uc_filler[5];
+ } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/i386/sysdep.h b/libc/sysdeps/i386/sysdep.h
new file mode 100644
index 000000000..2739cb00b
--- /dev/null
+++ b/libc/sysdeps/i386/sysdep.h
@@ -0,0 +1,175 @@
+/* Assembler macros for i386.
+ Copyright (C) 1991-93,95,96,98,2002,2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+/* Syntactic details of assembler. */
+
+#ifdef HAVE_ELF
+
+/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */
+#define ALIGNARG(log2) 1<<log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
+
+/* In ELF C symbols are asm symbols. */
+#undef NO_UNDERSCORES
+#define NO_UNDERSCORES
+
+#else
+
+#define ALIGNARG(log2) log2
+#define ASM_TYPE_DIRECTIVE(name,type) /* Nothing is specified. */
+#define ASM_SIZE_DIRECTIVE(name) /* Nothing is specified. */
+
+#endif
+
+
+/* Define an entry point visible from C.
+
+ There is currently a bug in gdb which prevents us from specifying
+ incomplete stabs information. Fake some entries here which specify
+ the current source file. */
+#define ENTRY(name) \
+ STABS_CURRENT_FILE1("") \
+ STABS_CURRENT_FILE(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(4); \
+ STABS_FUN(name) \
+ C_LABEL(name) \
+ cfi_startproc; \
+ CALL_MCOUNT
+
+#undef END
+#define END(name) \
+ cfi_endproc; \
+ ASM_SIZE_DIRECTIVE(name) \
+ STABS_FUN_END(name)
+
+#ifdef HAVE_CPP_ASM_DEBUGINFO
+/* Disable that goop, because we just pass -g through to the assembler
+ and it generates proper line number information directly. */
+# define STABS_CURRENT_FILE1(name)
+# define STABS_CURRENT_FILE(name)
+# define STABS_FUN(name)
+# define STABS_FUN_END(name)
+#else
+/* Remove the following two lines once the gdb bug is fixed. */
+#define STABS_CURRENT_FILE(name) \
+ STABS_CURRENT_FILE1 (#name)
+#define STABS_CURRENT_FILE1(name) \
+ 1: .stabs name,100,0,0,1b;
+/* Emit stabs definition lines. We use F(0,1) and define t(0,1) as `int',
+ the same way gcc does it. */
+#define STABS_FUN(name) STABS_FUN2(name, name##:F(0,1))
+#define STABS_FUN2(name, namestr) \
+ .stabs "int:t(0,1)=r(0,1);-2147483648;2147483647;",128,0,0,0; \
+ .stabs #namestr,36,0,0,name;
+#define STABS_FUN_END(name) \
+ 1: .stabs "",36,0,0,1b-name;
+#endif
+
+/* If compiled for profiling, call `mcount' at the start of each function. */
+#ifdef PROF
+/* The mcount code relies on a normal frame pointer being on the stack
+ to locate our caller, so push one just for its benefit. */
+#define CALL_MCOUNT \
+ pushl %ebp; cfi_adjust_cfa_offset (4); movl %esp, %ebp; \
+ cfi_def_cfa_register (ebp); call JUMPTARGET(mcount); \
+ popl %ebp; cfi_def_cfa (esp, 4);
+#else
+#define CALL_MCOUNT /* Do nothing. */
+#endif
+
+#ifdef NO_UNDERSCORES
+/* Since C identifiers are not normally prefixed with an underscore
+ on this system, the asm identifier `syscall_error' intrudes on the
+ C name space. Make sure we use an innocuous name. */
+#define syscall_error __syscall_error
+#define mcount _mcount
+#endif
+
+#define PSEUDO(name, syscall_name, args) \
+ .globl syscall_error; \
+lose: SYSCALL_PIC_SETUP \
+ jmp JUMPTARGET(syscall_error); \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ jb lose
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
+
+#undef JUMPTARGET
+#ifdef PIC
+#define JUMPTARGET(name) name##@PLT
+#define SYSCALL_PIC_SETUP \
+ pushl %ebx; \
+ cfi_adjust_cfa_offset (4); \
+ call 0f; \
+0: popl %ebx; \
+ cfi_adjust_cfa_offset (-4); \
+ addl $_GLOBAL_OFFSET_TABLE+[.-0b], %ebx;
+
+# ifndef HAVE_HIDDEN
+# define SETUP_PIC_REG(reg) \
+ call 1f; \
+ .subsection 1; \
+1:movl (%esp), %e##reg; \
+ ret; \
+ .previous
+# else
+# define SETUP_PIC_REG(reg) \
+ .ifndef __i686.get_pc_thunk.reg; \
+ .section .gnu.linkonce.t.__i686.get_pc_thunk.reg,"ax",@progbits; \
+ .globl __i686.get_pc_thunk.reg; \
+ .hidden __i686.get_pc_thunk.reg; \
+ .type __i686.get_pc_thunk.reg,@function; \
+__i686.get_pc_thunk.reg: \
+ movl (%esp), %e##reg; \
+ ret; \
+ .size __i686.get_pc_thunk.reg, . - __i686.get_pc_thunk.reg; \
+ .previous; \
+ .endif; \
+ call __i686.get_pc_thunk.reg
+# endif
+
+# define LOAD_PIC_REG(reg) \
+ SETUP_PIC_REG(reg); addl $_GLOBAL_OFFSET_TABLE_, %e##reg
+
+#else
+#define JUMPTARGET(name) name
+#define SYSCALL_PIC_SETUP /* Nothing. */
+#endif
+
+/* Local label name for asm code. */
+#ifndef L
+#ifdef HAVE_ELF
+#define L(name) .L##name
+#else
+#define L(name) name
+#endif
+#endif
+
+#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/i386/tst-stack-align.h b/libc/sysdeps/i386/tst-stack-align.h
new file mode 100644
index 000000000..6297d9faa
--- /dev/null
+++ b/libc/sysdeps/i386/tst-stack-align.h
@@ -0,0 +1,42 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <stdint.h>
+
+typedef struct { int i[4]; } int_al16 __attribute__((aligned (16)));
+
+#define TEST_STACK_ALIGN() \
+ ({ \
+ int_al16 _m; \
+ double _d = 12.0; \
+ long double _ld = 15.0; \
+ int _ret = 0; \
+ printf ("int_al16: %p %zu\n", &_m, __alignof (int_al16)); \
+ if ((((uintptr_t) &_m) & (__alignof (int_al16) - 1)) != 0) \
+ _ret = 1; \
+ \
+ printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
+ if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
+ _ret = 1; \
+ \
+ printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
+ if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
+ _ret = 1; \
+ _ret; \
+ })
diff --git a/libc/sysdeps/ia64/Implies b/libc/sysdeps/ia64/Implies
new file mode 100644
index 000000000..852425702
--- /dev/null
+++ b/libc/sysdeps/ia64/Implies
@@ -0,0 +1,5 @@
+wordsize-64
+# ia64 uses IEEE 754 floating point.
+ieee754/ldbl-96
+ieee754/dbl-64
+ieee754/flt-32
diff --git a/libc/sysdeps/ia64/Makefile b/libc/sysdeps/ia64/Makefile
new file mode 100644
index 000000000..2ea937ac9
--- /dev/null
+++ b/libc/sysdeps/ia64/Makefile
@@ -0,0 +1,24 @@
+# The ia64 `long double' is a distinct type we support.
+long-double-fcts = yes
+
+ifeq ($(subdir),gmon)
+sysdep_routines += _mcount
+endif
+
+ifeq ($(subdir), csu)
+CPPFLAGS-start.S = -D__ASSEMBLY__
+sysdep_routines += hp-timing
+elide-routines.os += hp-timing
+
+ifeq (yes,$(build-shared))
+# Compatibility
+sysdep_routines += ia64libgcc
+shared-only-routines += ia64libgcc
+endif
+endif
+
+ifeq ($(subdir),elf)
+sysdep-dl-routines += dl-symaddr dl-fptr
+sysdep_routines += $(sysdep-dl-routines)
+sysdep-rtld-routines += $(sysdep-dl-routines)
+endif
diff --git a/libc/sysdeps/ia64/Versions b/libc/sysdeps/ia64/Versions
new file mode 100644
index 000000000..56b417d61
--- /dev/null
+++ b/libc/sysdeps/ia64/Versions
@@ -0,0 +1,21 @@
+ld {
+ GLIBC_PRIVATE {
+ # ia64 specific functions in the dynamic linker, but used by libc.so.
+ _dl_symbol_address; _dl_unmap; _dl_lookup_address;
+ _dl_function_address;
+ }
+}
+libc {
+ GLIBC_2.2 {
+ # Functions from libgcc.
+ __divtf3; __divdf3; __divsf3; __divdi3; __moddi3; __udivdi3; __umoddi3;
+ __multi3;
+ }
+}
+libm {
+ GLIBC_2.1 {
+ # A generic bug got this omitted from other configurations' version
+ # sets, but we always had it.
+ exp2l;
+ }
+}
diff --git a/libc/sysdeps/ia64/_mcount.S b/libc/sysdeps/ia64/_mcount.S
new file mode 100644
index 000000000..8720a9c10
--- /dev/null
+++ b/libc/sysdeps/ia64/_mcount.S
@@ -0,0 +1,92 @@
+/* Machine-specific calling sequence for `mcount' profiling function. ia64
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by David Mosberger <davidm@hpl.hp.com>
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Assembly stub to invoke _mcount(). Compiler generated code calls
+ this stub before executing a function's prologue and without saving
+ any registers. It is therefore necessary to preserve the input
+ registers as they may contain function arguments. To work
+ correctly with frame-less functions, it is also necessary to
+ preserve the return pointer (b0 aka rp).
+
+ State upon entering _mcount:
+
+ r8 address of return value structure (used only when called
+ function returns a large structure)
+ r15 static link (used only for nested functions)
+ in0 ar.pfs to restore before returning to the function that
+ called _mcount
+ in1 gp value to restore before returning to the function that
+ called _mcount
+ in2 return address in the function that invoked the caller
+ of _mcount (frompc)
+ in3 address of the global-offset table entry that holds the
+ profile count dword allocated by the compiler; to get
+ the address of this dword, use "ld8 in2=[in2]; this
+ dword can be used in any way by _mcount (including
+ not at all, as is the case with the current implementation)
+ b0 address to return to after _mcount is done
+*/
+
+#include <sysdep.h>
+
+#undef ret
+
+LEAF(_mcount)
+ .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
+ alloc loc1 = ar.pfs, 4, 4, 3, 0
+ mov loc0 = rp
+ .body
+ mov loc2 = r8 // gcc uses r8 to pass pointer to return structure
+ ;;
+ mov loc3 = r15 // gcc uses r15 to pass the static link to nested functions
+ mov out0 = in2
+ mov out1 = rp
+ br.call.sptk.few rp = __mcount
+ ;;
+.here:
+{
+ .mii
+ mov gp = in1
+ mov r2 = ip
+ mov ar.pfs = loc1
+}
+ ;;
+ adds r2 = _mcount_ret_helper - .here, r2
+ mov b7 = loc0
+ mov rp = in2
+ ;;
+ mov r3 = in0
+ mov r8 = loc2
+ mov r15 = loc3
+ mov b6 = r2
+ br.ret.sptk.few b6
+END(_mcount)
+
+LOCAL_LEAF(_mcount_ret_helper)
+ .prologue
+ .altrp b7
+ .save ar.pfs, r3
+ .body
+ alloc r2 = ar.pfs, 0, 0, 8, 0
+ mov ar.pfs = r3
+ br b7
+END(_mcount_ret_helper)
+
+weak_alias (_mcount, mcount)
diff --git a/libc/sysdeps/ia64/abort-instr.h b/libc/sysdeps/ia64/abort-instr.h
new file mode 100644
index 000000000..8f26f0fc2
--- /dev/null
+++ b/libc/sysdeps/ia64/abort-instr.h
@@ -0,0 +1,3 @@
+/* An instruction which should crash any program is `break 0' which triggers
+ SIGILL. */
+#define ABORT_INSTRUCTION asm ("break 0")
diff --git a/libc/sysdeps/ia64/backtrace.c b/libc/sysdeps/ia64/backtrace.c
new file mode 100644
index 000000000..3f2b75ec0
--- /dev/null
+++ b/libc/sysdeps/ia64/backtrace.c
@@ -0,0 +1,93 @@
+/* Return backtrace of current program state.
+ Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <bits/libc-lock.h>
+#include <dlfcn.h>
+#include <execinfo.h>
+#include <stdlib.h>
+#include <unwind.h>
+
+struct trace_arg
+{
+ void **array;
+ int cnt, size;
+};
+
+#ifdef SHARED
+static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
+static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *);
+
+static void
+init (void)
+{
+ void *handle = __libc_dlopen ("libgcc_s.so.1");
+
+ if (handle == NULL)
+ return;
+
+ unwind_backtrace = __libc_dlsym (handle, "_Unwind_Backtrace");
+ unwind_getip = __libc_dlsym (handle, "_Unwind_GetIP");
+ if (unwind_getip == NULL)
+ unwind_backtrace = NULL;
+}
+#else
+# define unwind_backtrace _Unwind_Backtrace
+# define unwind_getip _Unwind_GetIP
+#endif
+
+static _Unwind_Reason_Code
+backtrace_helper (struct _Unwind_Context *ctx, void *a)
+{
+ struct trace_arg *arg = a;
+
+ /* We are first called with address in the __backtrace function.
+ Skip it. */
+ if (arg->cnt != -1)
+ arg->array[arg->cnt] = (void *) unwind_getip (ctx);
+ if (++arg->cnt == arg->size)
+ return _URC_END_OF_STACK;
+ return _URC_NO_REASON;
+}
+
+int
+__backtrace (array, size)
+ void **array;
+ int size;
+{
+ struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
+#ifdef SHARED
+ __libc_once_define (static, once);
+
+ __libc_once (once, init);
+ if (unwind_backtrace == NULL)
+ return 0;
+#endif
+
+ if (size >= 1)
+ unwind_backtrace (backtrace_helper, &arg);
+
+ /* _Unwind_Backtrace on IA-64 seems to put NULL address above
+ _start. Fix it up here. */
+ if (arg.cnt > 1 && arg.array[arg.cnt - 1] == NULL)
+ --arg.cnt;
+ return arg.cnt != -1 ? arg.cnt : 0;
+}
+weak_alias (__backtrace, backtrace)
+libc_hidden_def (__backtrace)
diff --git a/libc/sysdeps/ia64/bcopy.S b/libc/sysdeps/ia64/bcopy.S
new file mode 100644
index 000000000..bdabf5acd
--- /dev/null
+++ b/libc/sysdeps/ia64/bcopy.S
@@ -0,0 +1,10 @@
+#include <sysdep.h>
+
+ENTRY(bcopy)
+ .regstk 3, 0, 0, 0
+ mov r8 = in0
+ mov in0 = in1
+ ;;
+ mov in1 = r8
+ br.cond.sptk.many HIDDEN_BUILTIN_JUMPTARGET(memmove)
+END(bcopy)
diff --git a/libc/sysdeps/ia64/bits/atomic.h b/libc/sysdeps/ia64/bits/atomic.h
new file mode 100644
index 000000000..1020c2f22
--- /dev/null
+++ b/libc/sysdeps/ia64/bits/atomic.h
@@ -0,0 +1,119 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+#include <ia64intrin.h>
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+
+#define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \
+ (abort (), 0)
+
+#define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval) \
+ (abort (), 0)
+
+#define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \
+ (!__sync_bool_compare_and_swap ((mem), (int) (long) (oldval), \
+ (int) (long) (newval)))
+
+#define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \
+ (!__sync_bool_compare_and_swap ((mem), (long) (oldval), \
+ (long) (newval)))
+
+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+
+#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ __sync_val_compare_and_swap ((mem), (int) (long) (oldval), \
+ (int) (long) (newval))
+
+#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ __sync_val_compare_and_swap ((mem), (long) (oldval), (long) (newval))
+
+/* Atomically store newval and return the old value. */
+#define atomic_exchange_acq(mem, value) \
+ __sync_lock_test_and_set (mem, value)
+
+#define atomic_exchange_rel(mem, value) \
+ (__sync_synchronize (), __sync_lock_test_and_set (mem, value))
+
+#define atomic_exchange_and_add(mem, value) \
+ ({ __typeof (*mem) __result; \
+ __result = __sync_fetch_and_add ((mem), (int) (value)); \
+ __result; })
+
+#define atomic_decrement_if_positive(mem) \
+ ({ __typeof (*mem) __oldval, __val; \
+ __typeof (mem) __memp = (mem); \
+ \
+ __val = (*__memp); \
+ do \
+ { \
+ __oldval = __val; \
+ if (__builtin_expect (__val <= 0, 0)) \
+ break; \
+ __val = atomic_compare_and_exchange_val_acq (__memp, __oldval - 1, \
+ __oldval); \
+ } \
+ while (__builtin_expect (__val != __oldval, 0)); \
+ __oldval; })
+
+#define atomic_bit_test_set(mem, bit) \
+ ({ __typeof (*mem) __oldval, __val; \
+ __typeof (mem) __memp = (mem); \
+ __typeof (*mem) __mask = ((__typeof (*mem)) 1 << (bit)); \
+ \
+ __val = (*__memp); \
+ do \
+ { \
+ __oldval = __val; \
+ __val = atomic_compare_and_exchange_val_acq (__memp, \
+ __oldval | __mask, \
+ __oldval); \
+ } \
+ while (__builtin_expect (__val != __oldval, 0)); \
+ __oldval & __mask; })
+
+#define atomic_full_barrier() __sync_synchronize ()
diff --git a/libc/sysdeps/ia64/bits/byteswap.h b/libc/sysdeps/ia64/bits/byteswap.h
new file mode 100644
index 000000000..6862aa0b6
--- /dev/null
+++ b/libc/sysdeps/ia64/bits/byteswap.h
@@ -0,0 +1,110 @@
+/* Macros to swap the order of bytes in integer values.
+ Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
+# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
+#endif
+
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H 1
+
+/* Swap bytes in 16 bit value. */
+#define __bswap_constant_16(x) \
+ ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+# define __bswap_16(x) \
+ (__extension__ \
+ ({ register unsigned short int __v, __x = (x); \
+ if (__builtin_constant_p (x)) \
+ __v = __bswap_constant_16 (__x); \
+ else \
+ __asm__ __volatile__ ("shl %0 = %1, 48 ;;" \
+ "mux1 %0 = %0, @rev ;;" \
+ : "=r" (__v) \
+ : "r" ((unsigned short int) (__x))); \
+ __v; }))
+#else
+/* This is better than nothing. */
+static __inline unsigned short int
+__bswap_16 (unsigned short int __bsx)
+{
+ return __bswap_constant_16 (__bsx);
+}
+#endif
+
+
+/* Swap bytes in 32 bit value. */
+#define __bswap_constant_32(x) \
+ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
+ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+# define __bswap_32(x) \
+ (__extension__ \
+ ({ register unsigned int __v, __x = (x); \
+ if (__builtin_constant_p (x)) \
+ __v = __bswap_constant_32 (__x); \
+ else \
+ __asm__ __volatile__ ("shl %0 = %1, 32 ;;" \
+ "mux1 %0 = %0, @rev ;;" \
+ : "=r" (__v) \
+ : "r" ((unsigned int) (__x))); \
+ __v; }))
+#else
+static __inline unsigned int
+__bswap_32 (unsigned int __bsx)
+{
+ return __bswap_constant_32 (__bsx);
+}
+#endif
+
+
+/* Swap bytes in 64 bit value. */
+#define __bswap_constant_64(x) \
+ ((((x) & 0xff00000000000000ul) >> 56) \
+ | (((x) & 0x00ff000000000000ul) >> 40) \
+ | (((x) & 0x0000ff0000000000ul) >> 24) \
+ | (((x) & 0x000000ff00000000ul) >> 8) \
+ | (((x) & 0x00000000ff000000ul) << 8) \
+ | (((x) & 0x0000000000ff0000ul) << 24) \
+ | (((x) & 0x000000000000ff00ul) << 40) \
+ | (((x) & 0x00000000000000fful) << 56))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+# define __bswap_64(x) \
+ (__extension__ \
+ ({ register unsigned long int __v, __x = (x); \
+ if (__builtin_constant_p (x)) \
+ __v = __bswap_constant_64 (__x); \
+ else \
+ __asm__ __volatile__ ("mux1 %0 = %1, @rev ;;" \
+ : "=r" (__v) \
+ : "r" ((unsigned long int) (__x))); \
+ __v; }))
+
+#else
+static __inline unsigned long int
+__bswap_64 (unsigned long int __bsx)
+{
+ return __bswap_constant_64 (__bsx);
+}
+#endif
+
+#endif /* _BITS_BYTESWAP_H */
diff --git a/libc/sysdeps/ia64/bits/fenv.h b/libc/sysdeps/ia64/bits/fenv.h
new file mode 100644
index 000000000..32515f079
--- /dev/null
+++ b/libc/sysdeps/ia64/bits/fenv.h
@@ -0,0 +1,87 @@
+/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+
+/* Define bits representing the exception. We use the bit positions of
+ the appropriate bits in the FPSR... (Tahoe EAS 2.4 5-4)*/
+
+enum
+ {
+ FE_INEXACT = 1UL << 5,
+#define FE_INEXACT FE_INEXACT
+
+ FE_UNDERFLOW = 1UL << 4,
+#define FE_UNDERFLOW FE_UNDERFLOW
+
+ FE_OVERFLOW = 1UL << 3,
+#define FE_OVERFLOW FE_OVERFLOW
+
+ FE_DIVBYZERO = 1UL << 2,
+#define FE_DIVBYZERO FE_DIVBYZERO
+
+ FE_UNNORMAL = 1UL << 1,
+#define FE_UNNORMAL FE_UNNORMAL
+
+ FE_INVALID = 1UL << 0,
+#define FE_INVALID FE_INVALID
+
+ FE_ALL_EXCEPT =
+ (FE_INEXACT | FE_UNDERFLOW | FE_OVERFLOW | FE_DIVBYZERO | FE_UNNORMAL | FE_INVALID)
+#define FE_ALL_EXCEPT FE_ALL_EXCEPT
+ };
+
+
+enum
+ {
+ FE_TOWARDZERO = 3,
+#define FE_TOWARDZERO FE_TOWARDZERO
+
+ FE_UPWARD = 2,
+#define FE_UPWARD FE_UPWARD
+
+ FE_DOWNWARD = 1,
+#define FE_DOWNWARD FE_DOWNWARD
+
+ FE_TONEAREST = 0,
+#define FE_TONEAREST FE_TONEAREST
+ };
+
+
+/* Type representing exception flags. */
+typedef unsigned long int fexcept_t;
+
+/* Type representing floating-point environment. */
+typedef unsigned long int fenv_t;
+
+/* If the default argument is used we use this value. */
+#define FE_DFL_ENV ((__const fenv_t *) 0xc009804c0270033fUL)
+
+#ifdef __USE_GNU
+/* Floating-point environment where only FE_UNNORMAL is masked since this
+ exception is not generally supported by glibc. */
+# define FE_NOMASK_ENV ((__const fenv_t *) 0xc009804c02700302UL)
+
+/* Floating-point environment with (processor-dependent) non-IEEE
+ floating point. In this case, turning on flush-to-zero mode for
+ s0, s2, and s3. */
+# define FE_NONIEEE_ENV ((__const fenv_t *) 0xc009a04d0270037fUL)
+#endif
diff --git a/libc/sysdeps/ia64/bits/huge_vall.h b/libc/sysdeps/ia64/bits/huge_vall.h
new file mode 100644
index 000000000..a1f583b34
--- /dev/null
+++ b/libc/sysdeps/ia64/bits/huge_vall.h
@@ -0,0 +1,42 @@
+/* `HUGE_VALL' constant for ia64 (where it is infinity).
+ Used by <stdlib.h> and <math.h> functions for overflow.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/huge_vall.h> directly; include <math.h> instead."
+#endif
+
+#if __GNUC_PREREQ(3,3)
+# define HUGE_VALL (__builtin_huge_vall())
+#elif __GNUC_PREREQ(2,96)
+# define HUGE_VALL (__extension__ 0x1.0p32767L)
+#else
+
+# define __HUGE_VALL_bytes { 0,0,0,0,0,0,0, 0x80, 0xff, 0x7f, 0,0,0,0,0,0}
+
+# define __huge_vall_t union { unsigned char __c[16]; long double __ld; }
+# ifdef __GNUC__
+# define HUGE_VALL (__extension__ \
+ ((__huge_vall_t) { __c: __HUGE_VALL_bytes }).__ld)
+# else /* Not GCC. */
+static __huge_vall_t __huge_vall = { __HUGE_VALL_bytes };
+# define HUGE_VALL (__huge_vall.__ld)
+# endif /* GCC. */
+
+#endif /* GCC 2.95 */
diff --git a/libc/sysdeps/ia64/bits/link.h b/libc/sysdeps/ia64/bits/link.h
new file mode 100644
index 000000000..f751c23fd
--- /dev/null
+++ b/libc/sysdeps/ia64/bits/link.h
@@ -0,0 +1,63 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+/* Registers for entry into PLT on ia64. */
+typedef struct La_ia64_regs
+{
+ uint64_t lr_r8;
+ uint64_t lr_r9;
+ uint64_t lr_r10;
+ uint64_t lr_r11;
+ uint64_t lr_gr [8];
+ long double lr_fr [8];
+ uint64_t lr_unat;
+ uint64_t lr_sp;
+} La_ia64_regs;
+
+/* Return values for calls from PLT on ia64. */
+typedef struct La_ia64_retval
+{
+ uint64_t lrv_r8;
+ uint64_t lrv_r9;
+ uint64_t lrv_r10;
+ uint64_t lrv_r11;
+ long double lr_fr [8];
+} La_ia64_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf64_Addr la_ia64_gnu_pltenter (Elf64_Sym *__sym, unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_ia64_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_ia64_gnu_pltexit (Elf64_Sym *__sym, unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_ia64_regs *__inregs,
+ La_ia64_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
diff --git a/libc/sysdeps/ia64/bits/linkmap.h b/libc/sysdeps/ia64/bits/linkmap.h
new file mode 100644
index 000000000..7f8b0550d
--- /dev/null
+++ b/libc/sysdeps/ia64/bits/linkmap.h
@@ -0,0 +1,5 @@
+struct link_map_machine
+ {
+ size_t fptr_table_len;
+ Elf64_Addr *fptr_table;
+ };
diff --git a/libc/sysdeps/ia64/bits/mathdef.h b/libc/sysdeps/ia64/bits/mathdef.h
new file mode 100644
index 000000000..3dc286022
--- /dev/null
+++ b/libc/sysdeps/ia64/bits/mathdef.h
@@ -0,0 +1,37 @@
+/* Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
+/* The IA-64 architecture computes values with the precision of the
+ used type. */
+typedef float float_t; /* `float' expressions are evaluated as
+ `float'. */
+typedef double double_t; /* `double' expressions are evaluated as
+ `double'. */
+
+/* The values returned by `ilogb' for 0 and NaN respectively. */
+# define FP_ILOGB0 (-2147483647 - 1)
+# define FP_ILOGBNAN 2147483647
+
+#endif /* ISO C99 */
diff --git a/libc/sysdeps/ia64/bits/xtitypes.h b/libc/sysdeps/ia64/bits/xtitypes.h
new file mode 100644
index 000000000..54c85ba90
--- /dev/null
+++ b/libc/sysdeps/ia64/bits/xtitypes.h
@@ -0,0 +1,34 @@
+/* bits/xtitypes.h -- Define some types used by <bits/stropts.h>. IA64
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _STROPTS_H
+# error "Never include <bits/xtitypes.h> directly; use <stropts.h> instead."
+#endif
+
+#ifndef _BITS_XTITYPES_H
+#define _BITS_XTITYPES_H 1
+
+#include <bits/types.h>
+
+/* This type is used by some structs in <bits/stropts.h>. */
+typedef __S32_TYPE __t_scalar_t;
+typedef __U32_TYPE __t_uscalar_t;
+
+
+#endif /* bits/xtitypes.h */
diff --git a/libc/sysdeps/ia64/bzero.S b/libc/sysdeps/ia64/bzero.S
new file mode 100644
index 000000000..bcca41d5e
--- /dev/null
+++ b/libc/sysdeps/ia64/bzero.S
@@ -0,0 +1,315 @@
+/* Optimized version of the standard bzero() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Dan Pop for Itanium <Dan.Pop@cern.ch>.
+ Rewritten for McKinley by Sverre Jarp, HP Labs/CERN <Sverre.Jarp@cern.ch>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: dest
+
+ Inputs:
+ in0: dest
+ in1: count
+
+ The algorithm is fairly straightforward: set byte by byte until we
+ we get to a 16B-aligned address, then loop on 128 B chunks using an
+ early store as prefetching, then loop on 32B chucks, then clear remaining
+ words, finally clear remaining bytes.
+ Since a stf.spill f0 can store 16B in one go, we use this instruction
+ to get peak speed. */
+
+#include <sysdep.h>
+#undef ret
+
+#define dest in0
+#define cnt in1
+
+#define tmp r31
+#define save_lc r30
+#define ptr0 r29
+#define ptr1 r28
+#define ptr2 r27
+#define ptr3 r26
+#define ptr9 r24
+#define loopcnt r23
+#define linecnt r22
+#define bytecnt r21
+
+// This routine uses only scratch predicate registers (p6 - p15)
+#define p_scr p6 // default register for same-cycle branches
+#define p_unalgn p9
+#define p_y p11
+#define p_n p12
+#define p_yy p13
+#define p_nn p14
+
+#define movi0 mov
+
+#define MIN1 15
+#define MIN1P1HALF 8
+#define LINE_SIZE 128
+#define LSIZE_SH 7 // shift amount
+#define PREF_AHEAD 8
+
+#define USE_FLP
+#if defined(USE_INT)
+#define store st8
+#define myval r0
+#elif defined(USE_FLP)
+#define store stf8
+#define myval f0
+#endif
+
+.align 64
+ENTRY(bzero)
+{ .mmi
+ .prologue
+ alloc tmp = ar.pfs, 2, 0, 0, 0
+ lfetch.nt1 [dest]
+ .save ar.lc, save_lc
+ movi0 save_lc = ar.lc
+} { .mmi
+ .body
+ mov ret0 = dest // return value
+ nop.m 0
+ cmp.eq p_scr, p0 = cnt, r0
+;; }
+{ .mmi
+ and ptr2 = -(MIN1+1), dest // aligned address
+ and tmp = MIN1, dest // prepare to check for alignment
+ tbit.nz p_y, p_n = dest, 0 // Do we have an odd address? (M_B_U)
+} { .mib
+ mov ptr1 = dest
+ nop.i 0
+(p_scr) br.ret.dpnt.many rp // return immediately if count = 0
+;; }
+{ .mib
+ cmp.ne p_unalgn, p0 = tmp, r0
+} { .mib // NB: # of bytes to move is 1
+ sub bytecnt = (MIN1+1), tmp // higher than loopcnt
+ cmp.gt p_scr, p0 = 16, cnt // is it a minimalistic task?
+(p_scr) br.cond.dptk.many .move_bytes_unaligned // go move just a few (M_B_U)
+;; }
+{ .mmi
+(p_unalgn) add ptr1 = (MIN1+1), ptr2 // after alignment
+(p_unalgn) add ptr2 = MIN1P1HALF, ptr2 // after alignment
+(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 3 // should we do a st8 ?
+;; }
+{ .mib
+(p_y) add cnt = -8, cnt
+(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 2 // should we do a st4 ?
+} { .mib
+(p_y) st8 [ptr2] = r0,-4
+(p_n) add ptr2 = 4, ptr2
+;; }
+{ .mib
+(p_yy) add cnt = -4, cnt
+(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 1 // should we do a st2 ?
+} { .mib
+(p_yy) st4 [ptr2] = r0,-2
+(p_nn) add ptr2 = 2, ptr2
+;; }
+{ .mmi
+ mov tmp = LINE_SIZE+1 // for compare
+(p_y) add cnt = -2, cnt
+(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 0 // should we do a st1 ?
+} { .mmi
+ nop.m 0
+(p_y) st2 [ptr2] = r0,-1
+(p_n) add ptr2 = 1, ptr2
+;; }
+
+{ .mmi
+(p_yy) st1 [ptr2] = r0
+ cmp.gt p_scr, p0 = tmp, cnt // is it a minimalistic task?
+} { .mbb
+(p_yy) add cnt = -1, cnt
+(p_scr) br.cond.dpnt.many .fraction_of_line // go move just a few
+;; }
+{ .mib
+ nop.m 0
+ shr.u linecnt = cnt, LSIZE_SH
+ nop.b 0
+;; }
+
+ .align 32
+.l1b: // ------------------// L1B: store ahead into cache lines; fill later
+{ .mmi
+ and tmp = -(LINE_SIZE), cnt // compute end of range
+ mov ptr9 = ptr1 // used for prefetching
+ and cnt = (LINE_SIZE-1), cnt // remainder
+} { .mmi
+ mov loopcnt = PREF_AHEAD-1 // default prefetch loop
+ cmp.gt p_scr, p0 = PREF_AHEAD, linecnt // check against actual value
+;; }
+{ .mmi
+(p_scr) add loopcnt = -1, linecnt
+ add ptr2 = 16, ptr1 // start of stores (beyond prefetch stores)
+ add ptr1 = tmp, ptr1 // first address beyond total range
+;; }
+{ .mmi
+ add tmp = -1, linecnt // next loop count
+ movi0 ar.lc = loopcnt
+;; }
+.pref_l1b:
+{ .mib
+ stf.spill [ptr9] = f0, 128 // Do stores one cache line apart
+ nop.i 0
+ br.cloop.dptk.few .pref_l1b
+;; }
+{ .mmi
+ add ptr0 = 16, ptr2 // Two stores in parallel
+ movi0 ar.lc = tmp
+;; }
+.l1bx:
+ { .mmi
+ stf.spill [ptr2] = f0, 32
+ stf.spill [ptr0] = f0, 32
+ ;; }
+ { .mmi
+ stf.spill [ptr2] = f0, 32
+ stf.spill [ptr0] = f0, 32
+ ;; }
+ { .mmi
+ stf.spill [ptr2] = f0, 32
+ stf.spill [ptr0] = f0, 64
+ cmp.lt p_scr, p0 = ptr9, ptr1 // do we need more prefetching?
+ ;; }
+{ .mmb
+ stf.spill [ptr2] = f0, 32
+(p_scr) stf.spill [ptr9] = f0, 128
+ br.cloop.dptk.few .l1bx
+;; }
+{ .mib
+ cmp.gt p_scr, p0 = 8, cnt // just a few bytes left ?
+(p_scr) br.cond.dpnt.many .move_bytes_from_alignment
+;; }
+
+.fraction_of_line:
+{ .mib
+ add ptr2 = 16, ptr1
+ shr.u loopcnt = cnt, 5 // loopcnt = cnt / 32
+;; }
+{ .mib
+ cmp.eq p_scr, p0 = loopcnt, r0
+ add loopcnt = -1, loopcnt
+(p_scr) br.cond.dpnt.many .store_words
+;; }
+{ .mib
+ and cnt = 0x1f, cnt // compute the remaining cnt
+ movi0 ar.lc = loopcnt
+;; }
+ .align 32
+.l2: // -----------------------------// L2A: store 32B in 2 cycles
+{ .mmb
+ store [ptr1] = myval, 8
+ store [ptr2] = myval, 8
+;; } { .mmb
+ store [ptr1] = myval, 24
+ store [ptr2] = myval, 24
+ br.cloop.dptk.many .l2
+;; }
+.store_words:
+{ .mib
+ cmp.gt p_scr, p0 = 8, cnt // just a few bytes left ?
+(p_scr) br.cond.dpnt.many .move_bytes_from_alignment // Branch
+;; }
+
+{ .mmi
+ store [ptr1] = myval, 8 // store
+ cmp.le p_y, p_n = 16, cnt //
+ add cnt = -8, cnt // subtract
+;; }
+{ .mmi
+(p_y) store [ptr1] = myval, 8 // store
+(p_y) cmp.le.unc p_yy, p_nn = 16, cnt
+(p_y) add cnt = -8, cnt // subtract
+;; }
+{ .mmi // store
+(p_yy) store [ptr1] = myval, 8
+(p_yy) add cnt = -8, cnt // subtract
+;; }
+
+.move_bytes_from_alignment:
+{ .mib
+ cmp.eq p_scr, p0 = cnt, r0
+ tbit.nz.unc p_y, p0 = cnt, 2 // should we terminate with a st4 ?
+(p_scr) br.cond.dpnt.few .restore_and_exit
+;; }
+{ .mib
+(p_y) st4 [ptr1] = r0,4
+ tbit.nz.unc p_yy, p0 = cnt, 1 // should we terminate with a st2 ?
+;; }
+{ .mib
+(p_yy) st2 [ptr1] = r0,2
+ tbit.nz.unc p_y, p0 = cnt, 0 // should we terminate with a st1 ?
+;; }
+
+{ .mib
+(p_y) st1 [ptr1] = r0
+;; }
+.restore_and_exit:
+{ .mib
+ nop.m 0
+ movi0 ar.lc = save_lc
+ br.ret.sptk.many rp
+;; }
+
+.move_bytes_unaligned:
+{ .mmi
+ .pred.rel "mutex",p_y, p_n
+ .pred.rel "mutex",p_yy, p_nn
+(p_n) cmp.le p_yy, p_nn = 4, cnt
+(p_y) cmp.le p_yy, p_nn = 5, cnt
+(p_n) add ptr2 = 2, ptr1
+} { .mmi
+(p_y) add ptr2 = 3, ptr1
+(p_y) st1 [ptr1] = r0, 1 // fill 1 (odd-aligned) byte
+(p_y) add cnt = -1, cnt // [15, 14 (or less) left]
+;; }
+{ .mmi
+(p_yy) cmp.le.unc p_y, p0 = 8, cnt
+ add ptr3 = ptr1, cnt // prepare last store
+ movi0 ar.lc = save_lc
+} { .mmi
+(p_yy) st2 [ptr1] = r0, 4 // fill 2 (aligned) bytes
+(p_yy) st2 [ptr2] = r0, 4 // fill 2 (aligned) bytes
+(p_yy) add cnt = -4, cnt // [11, 10 (o less) left]
+;; }
+{ .mmi
+(p_y) cmp.le.unc p_yy, p0 = 8, cnt
+ add ptr3 = -1, ptr3 // last store
+ tbit.nz p_scr, p0 = cnt, 1 // will there be a st2 at the end ?
+} { .mmi
+(p_y) st2 [ptr1] = r0, 4 // fill 2 (aligned) bytes
+(p_y) st2 [ptr2] = r0, 4 // fill 2 (aligned) bytes
+(p_y) add cnt = -4, cnt // [7, 6 (or less) left]
+;; }
+{ .mmi
+(p_yy) st2 [ptr1] = r0, 4 // fill 2 (aligned) bytes
+(p_yy) st2 [ptr2] = r0, 4 // fill 2 (aligned) bytes
+ // [3, 2 (or less) left]
+ tbit.nz p_y, p0 = cnt, 0 // will there be a st1 at the end ?
+} { .mmi
+(p_yy) add cnt = -4, cnt
+;; }
+{ .mmb
+(p_scr) st2 [ptr1] = r0 // fill 2 (aligned) bytes
+(p_y) st1 [ptr3] = r0 // fill last byte (using ptr3)
+ br.ret.sptk.many rp
+;; }
+END(bzero)
diff --git a/libc/sysdeps/ia64/dl-dtprocnum.h b/libc/sysdeps/ia64/dl-dtprocnum.h
new file mode 100644
index 000000000..fc3158962
--- /dev/null
+++ b/libc/sysdeps/ia64/dl-dtprocnum.h
@@ -0,0 +1,22 @@
+/* Configuration of lookup functions. IA-64 version.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Number of extra dynamic section entries for this architecture. By
+ default there are none. */
+#define DT_THISPROCNUM DT_IA_64_NUM
diff --git a/libc/sysdeps/ia64/dl-fptr.h b/libc/sysdeps/ia64/dl-fptr.h
new file mode 100644
index 000000000..43907b9bf
--- /dev/null
+++ b/libc/sysdeps/ia64/dl-fptr.h
@@ -0,0 +1,36 @@
+/* Function descriptors. IA64 version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef dl_ia64_fptr_h
+#define dl_ia64_fptr_h 1
+
+#include <ia64intrin.h>
+#include <sysdeps/generic/dl-fptr.h>
+
+#define COMPARE_AND_SWAP(ptr, old, new) \
+ __sync_bool_compare_and_swap (ptr, old, new)
+
+/* There are currently 123 dynamic symbols in ld.so.
+ ELF_MACHINE_BOOT_FPTR_TABLE_LEN needs to be at least that big. */
+#define ELF_MACHINE_BOOT_FPTR_TABLE_LEN 200
+
+#define ELF_MACHINE_LOAD_ADDRESS(var, symbol) \
+ asm ("movl %0 = @gprel (" #symbol ");; add %0 = %0, gp" : "=&r" (var));
+
+#endif /* !dl_ia64_fptr_h */
diff --git a/libc/sysdeps/ia64/dl-lookupcfg.h b/libc/sysdeps/ia64/dl-lookupcfg.h
new file mode 100644
index 000000000..b50030ebd
--- /dev/null
+++ b/libc/sysdeps/ia64/dl-lookupcfg.h
@@ -0,0 +1,72 @@
+/* Configuration of lookup functions.
+ Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define ELF_FUNCTION_PTR_IS_SPECIAL
+#define DL_UNMAP_IS_SPECIAL
+
+#include <dl-fptr.h>
+
+/* We do not support copy relocations for IA-64. */
+#define DL_NO_COPY_RELOCS
+
+/* Forward declaration. */
+struct link_map;
+
+extern void *_dl_symbol_address (struct link_map *map, const Elf64_Sym *ref);
+
+#define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref)
+
+extern Elf64_Addr _dl_lookup_address (const void *address);
+
+#define DL_LOOKUP_ADDRESS(addr) _dl_lookup_address (addr)
+
+extern void _dl_unmap (struct link_map *map);
+
+#define DL_UNMAP(map) _dl_unmap (map)
+
+#define DL_AUTO_FUNCTION_ADDRESS(map, addr) \
+({ \
+ unsigned long int fptr[2]; \
+ fptr[0] = (unsigned long int) (addr); \
+ fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
+ (Elf64_Addr) fptr; \
+})
+
+#define DL_STATIC_FUNCTION_ADDRESS(map, addr) \
+({ \
+ static unsigned long int fptr[2]; \
+ fptr[0] = (unsigned long int) (addr); \
+ fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
+ (Elf64_Addr) fptr; \
+})
+
+#define DL_DT_INIT_ADDRESS(map, addr) DL_AUTO_FUNCTION_ADDRESS (map, addr)
+#define DL_DT_FINI_ADDRESS(map, addr) DL_AUTO_FUNCTION_ADDRESS (map, addr)
+/* The type of the return value of fixup/profile_fixup. */
+#define DL_FIXUP_VALUE_TYPE struct fdesc
+/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address
+ and a link map. */
+#define DL_FIXUP_MAKE_VALUE(map, addr) \
+ ((struct fdesc) { (addr), (map)->l_info[DT_PLTGOT]->d_un.d_ptr })
+/* Extract the code address from a value of type DL_FIXUP_MAKE_VALUE.
+ */
+#define DL_FIXUP_VALUE_CODE_ADDR(value) (value).ip
+
+#define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
+#define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
diff --git a/libc/sysdeps/ia64/dl-machine.h b/libc/sysdeps/ia64/dl-machine.h
new file mode 100644
index 000000000..55349690e
--- /dev/null
+++ b/libc/sysdeps/ia64/dl-machine.h
@@ -0,0 +1,512 @@
+/* Machine-dependent ELF dynamic relocation inline functions. IA-64 version.
+ Copyright (C) 1995-1997, 2000-2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef dl_machine_h
+#define dl_machine_h 1
+
+#define ELF_MACHINE_NAME "ia64"
+
+#include <assert.h>
+#include <string.h>
+#include <link.h>
+#include <errno.h>
+#include <dl-fptr.h>
+#include <tls.h>
+
+/* Translate a processor specific dynamic tag to the index
+ in l_info array. */
+#define DT_IA_64(x) (DT_IA_64_##x - DT_LOPROC + DT_NUM)
+
+static inline void __attribute__ ((always_inline))
+__ia64_init_bootstrap_fdesc_table (struct link_map *map)
+{
+ Elf64_Addr *boot_table;
+
+ /* careful: this will be called before got has been relocated... */
+ asm (";; addl %0 = @gprel (_dl_boot_fptr_table), gp" : "=r"(boot_table));
+
+ map->l_mach.fptr_table_len = ELF_MACHINE_BOOT_FPTR_TABLE_LEN;
+ map->l_mach.fptr_table = boot_table;
+}
+
+#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \
+ __ia64_init_bootstrap_fdesc_table (&bootstrap_map);
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int __attribute__ ((unused))
+elf_machine_matches_host (const Elf64_Ehdr *ehdr)
+{
+ return ehdr->e_machine == EM_IA_64;
+}
+
+
+/* Return the link-time address of _DYNAMIC. */
+static inline Elf64_Addr __attribute__ ((unused, const))
+elf_machine_dynamic (void)
+{
+ Elf64_Addr *p;
+
+ __asm__ (
+ ".section .sdata\n"
+ " .type __dynamic_ltv#, @object\n"
+ " .size __dynamic_ltv#, 8\n"
+ "__dynamic_ltv:\n"
+ " data8 @ltv(_DYNAMIC#)\n"
+ ".previous\n"
+ " addl %0 = @gprel(__dynamic_ltv#), gp ;;"
+ : "=r" (p));
+
+ return *p;
+}
+
+
+/* Return the run-time load address of the shared object. */
+static inline Elf64_Addr __attribute__ ((unused))
+elf_machine_load_address (void)
+{
+ Elf64_Addr ip;
+ int *p;
+
+ __asm__ (
+ "1: mov %0 = ip\n"
+ ".section .sdata\n"
+ "2: data4 @ltv(1b)\n"
+ " .align 8\n"
+ ".previous\n"
+ " addl %1 = @gprel(2b), gp ;;"
+ : "=r" (ip), "=r" (p));
+
+ return ip - (Elf64_Addr) *p;
+}
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int __attribute__ ((unused, always_inline))
+elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+{
+ extern void _dl_runtime_resolve (void);
+ extern void _dl_runtime_profile (void);
+
+ if (lazy)
+ {
+ register Elf64_Addr gp __asm__ ("gp");
+ Elf64_Addr *reserve, doit;
+
+ /*
+ * Careful with the typecast here or it will try to add l-l_addr
+ * pointer elements
+ */
+ reserve = ((Elf64_Addr *)
+ (l->l_info[DT_IA_64 (PLT_RESERVE)]->d_un.d_ptr + l->l_addr));
+ /* Identify this shared object. */
+ reserve[0] = (Elf64_Addr) l;
+
+ /* This function will be called to perform the relocation. */
+ if (!profile)
+ doit = (Elf64_Addr) ((struct fdesc *) &_dl_runtime_resolve)->ip;
+ else
+ {
+ if (GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), l))
+ {
+ /* This is the object we are looking for. Say that we really
+ want profiling and the timers are started. */
+ GL(dl_profile_map) = l;
+ }
+ doit = (Elf64_Addr) ((struct fdesc *) &_dl_runtime_profile)->ip;
+ }
+
+ reserve[1] = doit;
+ reserve[2] = gp;
+ }
+
+ return lazy;
+}
+
+/* Names of the architecture-specific auditing callback functions. */
+#define ARCH_LA_PLTENTER ia64_gnu_pltenter
+#define ARCH_LA_PLTEXIT ia64_gnu_pltexit
+
+/* Undo the adds out0 = 16, sp below to get at the value we want in
+ __libc_stack_end. */
+#define DL_STACK_END(cookie) \
+ ((void *) (((long) (cookie)) - 16))
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+
+#define RTLD_START asm ( \
+".text\n" \
+" .global _start#\n" \
+" .proc _start#\n" \
+"_start:\n" \
+"0: { .mii\n" \
+" .prologue\n" \
+" .save rp, r0\n" \
+" .body\n" \
+" .prologue\n" \
+" .save ar.pfs, r32\n" \
+" alloc loc0 = ar.pfs, 0, 3, 4, 0\n" \
+" .body\n" \
+" mov r2 = ip\n" \
+" addl r3 = @gprel(0b), r0\n" \
+" ;;\n" \
+" }\n" \
+" { .mlx\n" \
+" /* Calculate the GP, and save a copy in loc1. */\n" \
+" sub gp = r2, r3\n" \
+" movl r8 = 0x9804c0270033f\n" \
+" ;;\n" \
+" }\n" \
+" { .mii\n" \
+" mov ar.fpsr = r8\n" \
+" sub loc1 = r2, r3\n" \
+" /* _dl_start wants a pointer to the pointer to the arg block and\n" \
+" the arg block starts with an integer, thus the magic 16. */\n" \
+" adds out0 = 16, sp\n" \
+" }\n" \
+" { .bbb\n" \
+" br.call.sptk.many b0 = _dl_start#\n" \
+" ;;\n" \
+" }\n" \
+" .endp _start#\n" \
+" /* FALLTHRU */\n" \
+" .global _dl_start_user#\n" \
+" .proc _dl_start_user#\n" \
+"_dl_start_user:\n" \
+" .prologue\n" \
+" .save rp, r0\n" \
+" .body\n" \
+" .prologue\n" \
+" .save ar.pfs, r32\n" \
+" .body\n" \
+" { .mii\n" \
+" addl r3 = @gprel(_dl_skip_args), gp\n" \
+" adds r11 = 24, sp /* Load the address of argv. */\n" \
+" /* Save the pointer to the user entry point fptr in loc2. */\n" \
+" mov loc2 = ret0\n" \
+" ;;\n" \
+" }\n" \
+" { .mii\n" \
+" ld4 r3 = [r3]\n" \
+" adds r10 = 16, sp /* Load the address of argc. */\n" \
+" mov out2 = r11\n" \
+" ;;\n" \
+" /* See if we were run as a command with the executable file\n" \
+" name as an extra leading argument. If so, adjust the argv\n" \
+" pointer to skip _dl_skip_args words.\n" \
+" Note that _dl_skip_args is an integer, not a long - Jes\n" \
+"\n" \
+" The stack pointer has to be 16 byte aligned. We cannot simply\n" \
+" addjust the stack pointer. We have to move the whole argv and\n" \
+" envp and adjust _dl_argv by _dl_skip_args. H.J. */\n" \
+" }\n" \
+" { .mib\n" \
+" ld8 out1 = [r10] /* is argc actually stored as a long\n" \
+" or as an int? */\n" \
+" addl r2 = @ltoff(_dl_argv), gp\n" \
+" ;;\n" \
+" }\n" \
+" { .mmi\n" \
+" ld8 r2 = [r2] /* Get the address of _dl_argv. */\n" \
+" sub out1 = out1, r3 /* Get the new argc. */\n" \
+" shladd r3 = r3, 3, r0\n" \
+" ;;\n" \
+" }\n" \
+" {\n" \
+" .mib\n" \
+" ld8 r17 = [r2] /* Get _dl_argv. */\n" \
+" add r15 = r11, r3 /* The address of the argv we move */\n" \
+" ;;\n" \
+" }\n" \
+" /* ??? Could probably merge these two loops into 3 bundles.\n" \
+" using predication to control which set of copies we're on. */\n" \
+"1: /* Copy argv. */\n" \
+" { .mfi\n" \
+" ld8 r16 = [r15], 8 /* Load the value in the old argv. */\n" \
+" ;;\n" \
+" }\n" \
+" { .mib\n" \
+" st8 [r11] = r16, 8 /* Store it in the new argv. */\n" \
+" cmp.ne p6, p7 = 0, r16\n" \
+"(p6) br.cond.dptk.few 1b\n" \
+" ;;\n" \
+" }\n" \
+" { .mmi\n" \
+" mov out3 = r11\n" \
+" sub r17 = r17, r3 /* Substract _dl_skip_args. */\n" \
+" addl out0 = @gprel(_rtld_local), gp\n" \
+" }\n" \
+"1: /* Copy env. */\n" \
+" { .mfi\n" \
+" ld8 r16 = [r15], 8 /* Load the value in the old env. */\n" \
+" ;;\n" \
+" }\n" \
+" { .mib\n" \
+" st8 [r11] = r16, 8 /* Store it in the new env. */\n" \
+" cmp.ne p6, p7 = 0, r16\n" \
+"(p6) br.cond.dptk.few 1b\n" \
+" ;;\n" \
+" }\n" \
+" { .mmb\n" \
+" st8 [r10] = out1 /* Record the new argc. */\n" \
+" ld8 out0 = [out0] /* get the linkmap */\n" \
+" }\n" \
+" { .mmb\n" \
+" st8 [r2] = r17 /* Load the new _dl_argv. */\n" \
+" br.call.sptk.many b0 = _dl_init_internal#\n" \
+" ;;\n" \
+" }\n" \
+" /* Pass our finalizer function to the user,\n" \
+" and jump to the user's entry point. */\n" \
+" { .mmi\n" \
+" ld8 r3 = [loc2], 8\n" \
+" mov b0 = r0\n" \
+" }\n" \
+" { .mmi\n" \
+" addl ret0 = @ltoff(@fptr(_dl_fini#)), gp\n" \
+" ;;\n" \
+" mov b6 = r3\n" \
+" }\n" \
+" { .mmi\n" \
+" ld8 ret0 = [ret0]\n" \
+" ld8 gp = [loc2]\n" \
+" mov ar.pfs = loc0\n" \
+" ;;\n" \
+" }\n" \
+" { .mfb\n" \
+" br.sptk.many b6\n" \
+" ;;\n" \
+" }\n" \
+" .endp _dl_start_user#\n" \
+".previous\n");
+
+
+#ifndef RTLD_START_SPECIAL_INIT
+#define RTLD_START_SPECIAL_INIT /* nothing */
+#endif
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or TLS
+ variable, so undefined references should not be allowed to define the
+ value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc, which we don't
+ use. */
+/* ??? Ignore *MSB for now. */
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#define elf_machine_type_class(type) \
+ (((type) == R_IA64_IPLTLSB || (type) == R_IA64_DTPMOD64LSB \
+ || (type) == R_IA64_DTPREL64LSB || (type) == R_IA64_TPREL64LSB) \
+ * ELF_RTYPE_CLASS_PLT)
+#else
+#define elf_machine_type_class(type) \
+ (((type) == R_IA64_IPLTLSB) * ELF_RTYPE_CLASS_PLT)
+#endif
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_IA64_IPLTLSB
+
+/* According to the IA-64 specific documentation, Rela is always used. */
+#define ELF_MACHINE_NO_REL 1
+
+/* Return the address of the entry point. */
+#define ELF_MACHINE_START_ADDRESS(map, start) \
+ DL_STATIC_FUNCTION_ADDRESS (map, start)
+
+/* Fixup a PLT entry to bounce directly to the function at VALUE. */
+static inline struct fdesc __attribute__ ((always_inline))
+elf_machine_fixup_plt (struct link_map *l, lookup_t t,
+ const Elf64_Rela *reloc,
+ Elf64_Addr *reloc_addr, struct fdesc value)
+{
+ /* l is the link_map for the caller, t is the link_map for the object
+ * being called */
+ /* got has already been relocated in elf_get_dynamic_info() */
+ reloc_addr[1] = value.gp;
+ /* we need a "release" here to ensure that the gp is visible before
+ the code entry point is updated: */
+ ((volatile Elf64_Addr *) reloc_addr)[0] = value.ip;
+ return value;
+}
+
+/* Return the final value of a plt relocation. */
+static inline struct fdesc
+elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
+ struct fdesc value)
+{
+ /* No need to handle rel vs rela since IA64 is rela only */
+ return (struct fdesc) { value.ip + reloc->r_addend, value.gp };
+}
+
+#endif /* !dl_machine_h */
+
+#ifdef RESOLVE_MAP
+
+#define R_IA64_TYPE(R) ((R) & -8)
+#define R_IA64_FORMAT(R) ((R) & 7)
+
+#define R_IA64_FORMAT_32MSB 4
+#define R_IA64_FORMAT_32LSB 5
+#define R_IA64_FORMAT_64MSB 6
+#define R_IA64_FORMAT_64LSB 7
+
+
+/* Perform the relocation specified by RELOC and SYM (which is fully
+ resolved). MAP is the object containing the reloc. */
+auto inline void
+__attribute ((always_inline))
+elf_machine_rela (struct link_map *map,
+ const Elf64_Rela *reloc,
+ const Elf64_Sym *sym,
+ const struct r_found_version *version,
+ void *const reloc_addr_arg)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+ const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
+ Elf64_Addr value;
+
+#if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC && !defined SHARED
+ /* This is defined in rtld.c, but nowhere in the static libc.a; make the
+ reference weak so static programs can still link. This declaration
+ cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
+ because rtld.c contains the common defn for _dl_rtld_map, which is
+ incompatible with a weak decl in the same file. */
+ weak_extern (_dl_rtld_map);
+#endif
+
+ /* We cannot use a switch here because we cannot locate the switch
+ jump table until we've self-relocated. */
+
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+ if (__builtin_expect (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_REL64LSB),
+ 0))
+ {
+ assert (ELF64_R_TYPE (reloc->r_info) == R_IA64_REL64LSB);
+ value = *reloc_addr;
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ /* Already done in dynamic linker. */
+ if (map != &GL(dl_rtld_map))
+# endif
+ value += map->l_addr;
+ }
+ else
+#endif
+ if (__builtin_expect (r_type == R_IA64_NONE, 0))
+ return;
+ else
+ {
+ struct link_map *sym_map;
+
+ /* RESOLVE_MAP() will return NULL if it fail to locate the symbol. */
+ if ((sym_map = RESOLVE_MAP (&sym, version, r_type)))
+ {
+ value = sym_map->l_addr + sym->st_value + reloc->r_addend;
+
+ if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DIR64LSB))
+ ;/* No adjustment. */
+ else if (r_type == R_IA64_IPLTLSB)
+ {
+ elf_machine_fixup_plt (NULL, NULL, reloc, reloc_addr,
+ DL_FIXUP_MAKE_VALUE (sym_map, value));
+ return;
+ }
+ else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_FPTR64LSB))
+ value = _dl_make_fptr (sym_map, sym, value);
+ else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_PCREL64LSB))
+ value -= (Elf64_Addr) reloc_addr & -16;
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || defined USE___THREAD)
+ else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DTPMOD64LSB))
+# ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always index 1. */
+ value = 1;
+# else
+ /* Get the information from the link map returned by the
+ resolv function. */
+ value = sym_map->l_tls_modid;
+ else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DTPREL64LSB))
+ value -= sym_map->l_addr;
+# endif
+ else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_TPREL64LSB))
+ {
+# ifndef RTLD_BOOTSTRAP
+ CHECK_STATIC_TLS (map, sym_map);
+# endif
+ value += sym_map->l_tls_offset - sym_map->l_addr;
+ }
+#endif
+ else
+ _dl_reloc_bad_type (map, r_type, 0);
+ }
+ else
+ value = 0;
+ }
+
+ /* ??? Ignore MSB and Instruction format for now. */
+ if (R_IA64_FORMAT (r_type) == R_IA64_FORMAT_64LSB)
+ *reloc_addr = value;
+ else if (R_IA64_FORMAT (r_type) == R_IA64_FORMAT_32LSB)
+ *(int *) reloc_addr = value;
+ else if (r_type == R_IA64_IPLTLSB)
+ {
+ reloc_addr[0] = 0;
+ reloc_addr[1] = 0;
+ }
+ else
+ _dl_reloc_bad_type (map, r_type, 0);
+}
+
+/* Let do-rel.h know that on IA-64 if l_addr is 0, all RELATIVE relocs
+ can be skipped. */
+#define ELF_MACHINE_REL_RELATIVE 1
+
+auto inline void
+__attribute ((always_inline))
+elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+ /* ??? Ignore MSB and Instruction format for now. */
+ assert (ELF64_R_TYPE (reloc->r_info) == R_IA64_REL64LSB);
+
+ *reloc_addr += l_addr;
+}
+
+/* Perform a RELATIVE reloc on the .got entry that transfers to the .plt. */
+auto inline void
+__attribute ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf64_Addr l_addr, const Elf64_Rela *reloc)
+{
+ Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
+ const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
+
+ if (r_type == R_IA64_IPLTLSB)
+ {
+ reloc_addr[0] += l_addr;
+ reloc_addr[1] += l_addr;
+ }
+ else if (r_type == R_IA64_NONE)
+ return;
+ else
+ _dl_reloc_bad_type (map, r_type, 1);
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/libc/sysdeps/ia64/dl-sysdep.h b/libc/sysdeps/ia64/dl-sysdep.h
new file mode 100644
index 000000000..e4040efc4
--- /dev/null
+++ b/libc/sysdeps/ia64/dl-sysdep.h
@@ -0,0 +1,24 @@
+/* System-specific settings for dynamic linker code. IA-64 version.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include_next <dl-sysdep.h>
+
+/* _dl_argv cannot be attribute_relro, because _dl_start_user
+ might write into it after _dl_start returns. */
+#define DL_ARGV_NOT_RELRO 1
diff --git a/libc/sysdeps/ia64/dl-tls.h b/libc/sysdeps/ia64/dl-tls.h
new file mode 100644
index 000000000..26f3d2adf
--- /dev/null
+++ b/libc/sysdeps/ia64/dl-tls.h
@@ -0,0 +1,30 @@
+/* Thread-local storage handling in the ELF dynamic linker. IA-64 version.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* On IA-64 the __tls_get_addr function take the module ID and the
+ offset as parameters. */
+#define GET_ADDR_ARGS size_t m, size_t offset
+#define GET_ADDR_MODULE m
+#define GET_ADDR_OFFSET offset
+
+/* We have no tls_index type. */
+#define DONT_USE_TLS_INDEX 1
+
+extern void *__tls_get_addr (size_t m, size_t offset);
diff --git a/libc/sysdeps/ia64/dl-trampoline.S b/libc/sysdeps/ia64/dl-trampoline.S
new file mode 100644
index 000000000..1b31dc7c9
--- /dev/null
+++ b/libc/sysdeps/ia64/dl-trampoline.S
@@ -0,0 +1,539 @@
+/* PLT trampolines. ia64 version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#undef ret
+
+/*
+ This code is used in dl-runtime.c to call the `_dl_fixup' function
+ and then redirect to the address it returns. `_dl_fixup()' takes two
+ arguments, however _dl_profile_fixup() takes five.
+
+ The ABI specifies that we will never see more than 8 input
+ registers to a function call, thus it is safe to simply allocate
+ those, and simpler than playing stack games. */
+
+/* Used to save and restore 8 incoming fp registers */
+#define RESOLVE_FRAME_SIZE (16*8)
+
+ENTRY(_dl_runtime_resolve)
+ { .mmi
+ .prologue
+ .save ar.pfs, r40
+ alloc loc0 = ar.pfs, 8, 6, 2, 0
+ /* Use the 16 byte scratch area. r2 will start at f8 and
+ r3 will start at f9. */
+ adds r2 = -(RESOLVE_FRAME_SIZE - 16), r12
+ adds r3 = -(RESOLVE_FRAME_SIZE - 32), r12
+ }
+ { .mii
+ .fframe RESOLVE_FRAME_SIZE
+ adds r12 = -RESOLVE_FRAME_SIZE, r12
+ .save rp, loc1
+ mov loc1 = b0
+ .body
+ mov loc2 = r8 /* preserve struct value register */
+ ;;
+ }
+ { .mii
+ mov loc3 = r9 /* preserve language specific register */
+ mov loc4 = r10 /* preserve language specific register */
+ mov loc5 = r11 /* preserve language specific register */
+ }
+ { .mmi
+ stf.spill [r2] = f8, 32
+ stf.spill [r3] = f9, 32
+ mov out0 = r16
+ ;;
+ }
+ { .mmi
+ stf.spill [r2] = f10, 32
+ stf.spill [r3] = f11, 32
+ shl out1 = r15, 4
+ ;;
+ }
+ { .mmi
+ stf.spill [r2] = f12, 32
+ stf.spill [r3] = f13, 32
+ /* Relocation record is 24 byte. */
+ shladd out1 = r15, 3, out1
+ ;;
+ }
+ { .mmb
+ stf.spill [r2] = f14
+ stf.spill [r3] = f15
+ br.call.sptk.many b0 = _dl_fixup
+ }
+ { .mii
+ /* Skip the 16byte scratch area. */
+ adds r2 = 16, r12
+ adds r3 = 32, r12
+ mov b6 = ret0
+ ;;
+ }
+ { .mmi
+ ldf.fill f8 = [r2], 32
+ ldf.fill f9 = [r3], 32
+ mov b0 = loc1
+ ;;
+ }
+ { .mmi
+ ldf.fill f10 = [r2], 32
+ ldf.fill f11 = [r3], 32
+ mov gp = ret1
+ ;;
+ }
+ { .mmi
+ ldf.fill f12 = [r2], 32
+ ldf.fill f13 = [r3], 32
+ mov ar.pfs = loc0
+ ;;
+ }
+ { .mmi
+ ldf.fill f14 = [r2], 32
+ ldf.fill f15 = [r3], 32
+ .restore sp /* pop the unwind frame state */
+ adds r12 = RESOLVE_FRAME_SIZE, r12
+ ;;
+ }
+ { .mii
+ mov r9 = loc3 /* restore language specific register */
+ mov r10 = loc4 /* restore language specific register */
+ mov r11 = loc5 /* restore language specific register */
+ }
+ { .mii
+ mov r8 = loc2 /* restore struct value register */
+ ;;
+ }
+ /* An alloc is needed for the break system call to work.
+ We don't care about the old value of the pfs register. */
+ { .mmb
+ .prologue
+ .body
+ alloc r2 = ar.pfs, 0, 0, 8, 0
+ br.sptk.many b6
+ ;;
+ }
+END(_dl_runtime_resolve)
+
+
+/* The fourth argument to _dl_profile_fixup and the third one to
+ _dl_call_pltexit are a pointer to La_ia64_regs:
+
+ 8byte r8
+ 8byte r9
+ 8byte r10
+ 8byte r11
+ 8byte in0
+ 8byte in1
+ 8byte in2
+ 8byte in3
+ 8byte in4
+ 8byte in5
+ 8byte in6
+ 8byte in7
+ 16byte f8
+ 16byte f9
+ 16byte f10
+ 16byte f11
+ 16byte f12
+ 16byte f13
+ 16byte f14
+ 16byte f15
+ 8byte ar.unat
+ 8byte sp
+
+ The fifth argument to _dl_profile_fixup is a pointer to long int.
+ The fourth argument to _dl_call_pltexit is a pointer to
+ La_ia64_retval:
+
+ 8byte r8
+ 8byte r9
+ 8byte r10
+ 8byte r11
+ 16byte f8
+ 16byte f9
+ 16byte f10
+ 16byte f11
+ 16byte f12
+ 16byte f13
+ 16byte f14
+ 16byte f15
+
+ Since stack has to be 16 byte aligned, the stack allocation is in
+ 16byte increment. Before calling _dl_profile_fixup, the stack will
+ look like
+
+ psp new frame_size
+ +16 La_ia64_regs
+ sp scratch
+
+ */
+
+#define PLTENTER_FRAME_SIZE (4*8 + 8*8 + 8*16 + 2*8 + 16)
+#define PLTEXIT_FRAME_SIZE (PLTENTER_FRAME_SIZE + 4*8 + 8*16)
+
+#ifndef PROF
+ENTRY(_dl_runtime_profile)
+ { .mii
+ .prologue
+ .save ar.pfs, r40
+ alloc loc0 = ar.pfs, 8, 12, 8, 0
+ .vframe loc10
+ mov loc10 = r12
+ .save rp, loc1
+ mov loc1 = b0
+ }
+ { .mii
+ .save ar.unat, r17
+ mov r17 = ar.unat
+ .save ar.lc, loc6
+ mov loc6 = ar.lc
+ mov loc11 = gp
+ }
+ { .mii
+ .body
+ /* There is a 16 byte scratch area. r2 will start at r8 and
+ r3 will start at r9 for La_ia64_regs. */
+ adds r2 = -(PLTENTER_FRAME_SIZE - 16), r12
+ adds r3 = -(PLTENTER_FRAME_SIZE - 24), r12
+ adds r12 = -PLTENTER_FRAME_SIZE, r12
+ ;;
+ }
+ { .mmi
+ st8 [r2] = r8, 16;
+ st8 [r3] = r9, 16;
+ mov out2 = b0 /* needed by _dl_fixup_profile */
+ ;;
+ }
+ { .mmi
+ st8 [r2] = r10, 16;
+ st8 [r3] = r11, 16;
+ adds out3 = 16, r12 /* pointer to La_ia64_regs */
+ ;;
+ }
+ { .mmi
+ .mem.offset 0, 0
+ st8.spill [r2] = in0, 16
+ .mem.offset 8, 0
+ st8.spill [r3] = in1, 16
+ mov out4 = loc10 /* pointer to new frame size */
+ ;;
+ }
+ { .mmi
+ .mem.offset 0, 0
+ st8.spill [r2] = in2, 16
+ .mem.offset 8, 0
+ st8.spill [r3] = in3, 16
+ mov loc2 = r8 /* preserve struct value register */
+ ;;
+ }
+ { .mmi
+ .mem.offset 0, 0
+ st8.spill [r2] = in4, 16
+ .mem.offset 8, 0
+ st8.spill [r3] = in5, 16
+ mov loc3 = r9 /* preserve language specific register */
+ ;;
+ }
+ { .mmi
+ .mem.offset 0, 0
+ st8 [r2] = in6, 16
+ .mem.offset 8, 0
+ st8 [r3] = in7, 24 /* adjust for f9 */
+ mov loc4 = r10 /* preserve language specific register */
+ ;;
+ }
+ { .mii
+ mov r18 = ar.unat /* save it in La_ia64_regs */
+ mov loc7 = out3 /* save it for _dl_call_pltexit */
+ mov loc5 = r11 /* preserve language specific register */
+ }
+ { .mmi
+ stf.spill [r2] = f8, 32
+ stf.spill [r3] = f9, 32
+ mov out0 = r16 /* needed by _dl_fixup_profile */
+ ;;
+ }
+ { .mii
+ mov ar.unat = r17 /* restore it for function call */
+ mov loc8 = r16 /* save it for _dl_call_pltexit */
+ nop.i 0x0
+ }
+ { .mmi
+ stf.spill [r2] = f10, 32
+ stf.spill [r3] = f11, 32
+ shl out1 = r15, 4
+ ;;
+ }
+ { .mmi
+ stf.spill [r2] = f12, 32
+ stf.spill [r3] = f13, 32
+ /* Relocation record is 24 byte. */
+ shladd out1 = r15, 3, out1
+ ;;
+ }
+ { .mmi
+ stf.spill [r2] = f14, 32
+ stf.spill [r3] = f15, 24
+ mov loc9 = out1 /* save it for _dl_call_pltexit */
+ ;;
+ }
+ { .mmb
+ st8 [r2] = r18 /* store ar.unat */
+ st8 [r3] = loc10 /* store sp */
+ br.call.sptk.many b0 = _dl_profile_fixup
+ }
+ { .mii
+ /* Skip the 16byte scratch area, 4 language specific GRs and
+ 8 incoming GRs to restore incoming fp registers. */
+ adds r2 = (4*8 + 8*8 + 16), r12
+ adds r3 = (4*8 + 8*8 + 32), r12
+ mov b6 = ret0
+ ;;
+ }
+ { .mmi
+ ldf.fill f8 = [r2], 32
+ ldf.fill f9 = [r3], 32
+ mov gp = ret1
+ ;;
+ }
+ { .mmi
+ ldf.fill f10 = [r2], 32
+ ldf.fill f11 = [r3], 32
+ mov r8 = loc2 /* restore struct value register */
+ ;;
+ }
+ { .mmi
+ ldf.fill f12 = [r2], 32
+ ldf.fill f13 = [r3], 32
+ mov r9 = loc3 /* restore language specific register */
+ ;;
+ }
+ { .mmi
+ ldf.fill f14 = [r2], 32
+ ldf.fill f15 = [r3], 32
+ mov r10 = loc4 /* restore language specific register */
+ ;;
+ }
+ { .mii
+ ld8 r15 = [loc10] /* load the new frame size */
+ mov r11 = loc5 /* restore language specific register */
+ ;;
+ cmp.eq p6, p7 = -1, r15
+ ;;
+ }
+ { .mii
+(p7) cmp.eq p8, p9 = 0, r15
+(p6) mov b0 = loc1
+(p6) mov ar.lc = loc6
+ }
+ { .mib
+ nop.m 0x0
+(p6) mov ar.pfs = loc0
+(p6) br.cond.dptk.many .Lresolved
+ ;;
+ }
+
+ /* At this point, the stack looks like
+
+ +psp free
+ +16 La_ia64_regs
+ sp scratch
+
+ We need to keep the current stack and call the resolved
+ function by copying the r15 byte from sp + PLTENTER_FRAME_SIZE
+ + 16 (scratch area) to sp + 16 (scratch area). Since stack
+ has to be 16byte aligned, we around r15 up to 16byte. */
+
+ { .mbb
+(p9) adds r15 = 15, r15
+(p8) br.cond.dptk.many .Lno_new_frame
+ nop.b 0x0
+ ;;
+ }
+ { .mmi
+ and r15 = -16, r15
+ ;;
+ /* We don't copy the 16byte scatch area. Prepare r16/r17 as
+ destination. */
+ sub r16 = r12, r15
+ sub r17 = r12, r15
+ ;;
+ }
+ { .mii
+ adds r16 = 16, r16
+ adds r17 = 24, r17
+ sub r12 = r12, r15 /* Adjust stack */
+ ;;
+ }
+ { .mii
+ nop.m 0x0
+ shr r15 = r15, 4
+ ;;
+ adds r15 = -1, r15
+ ;;
+ }
+ { .mii
+ /* Skip the 16byte scatch area. Prepare r2/r3 as source. */
+ adds r2 = 16, loc10
+ adds r3 = 24, loc10
+ mov ar.lc = r15
+ ;;
+ }
+.Lcopy:
+ { .mmi
+ ld8 r18 = [r2], 16
+ ld8 r19 = [r3], 16
+ nop.i 0x0
+ ;;
+ }
+ { .mmb
+ st8 [r16] = r18, 16
+ st8 [r17] = r19, 16
+ br.cloop.sptk.few .Lcopy
+ }
+.Lno_new_frame:
+ { .mii
+ mov out0 = in0
+ mov out1 = in1
+ mov out2 = in2
+ }
+ { .mii
+ mov out3 = in3
+ mov out4 = in4
+ mov out5 = in5
+ }
+ { .mib
+ mov out6 = in6
+ mov out7 = in7
+ /* Call the resolved function */
+ br.call.sptk.many b0 = b6
+ }
+ { .mii
+ /* Prepare stack for _dl_call_pltexit. Loc10 has the original
+ stack pointer. */
+ adds r12 = -PLTEXIT_FRAME_SIZE, loc10
+ adds r2 = -(PLTEXIT_FRAME_SIZE - 16), loc10
+ adds r3 = -(PLTEXIT_FRAME_SIZE - 24), loc10
+ ;;
+ }
+ { .mmi
+ /* Load all possible return values into buffer. */
+ st8 [r2] = r8, 16
+ st8 [r3] = r9, 16
+ mov out0 = loc8
+ ;;
+ }
+ { .mmi
+ st8 [r2] = r10, 16
+ st8 [r3] = r11, 24
+ mov out1 = loc9
+ ;;
+ }
+ { .mmi
+ stf.spill [r2] = f8, 32
+ stf.spill [r3] = f9, 32
+ mov out2 = loc7 /* Pointer to La_ia64_regs */
+ ;;
+ }
+ { .mmi
+ stf.spill [r2] = f10, 32
+ stf.spill [r3] = f11, 32
+ adds out3 = 16, r12 /* Pointer to La_ia64_retval */
+ ;;
+ }
+ { .mmi
+ stf.spill [r2] = f12, 32
+ stf.spill [r3] = f13, 32
+ /* We need to restore gp for _dl_call_pltexit. */
+ mov gp = loc11
+ ;;
+ }
+ { .mmb
+ stf.spill [r2] = f14
+ stf.spill [r3] = f15
+ br.call.sptk.many b0 = _dl_call_pltexit
+ }
+ { .mmi
+ /* Load all the non-floating and floating return values. Skip
+ the 16byte scratch area. */
+ adds r2 = 16, r12
+ adds r3 = 24, r12
+ nop.i 0x0
+ ;;
+ }
+ { .mmi
+ ld8 r8 = [r2], 16
+ ld8 r9 = [r3], 16
+ nop.i 0x0
+ ;;
+ }
+ { .mmi
+ ld8 r10 = [r2], 16
+ ld8 r11 = [r3], 24
+ nop.i 0x0
+ ;;
+ }
+ { .mmi
+ ldf.fill f8 = [r2], 32
+ ldf.fill f9 = [r3], 32
+ mov ar.lc = loc6
+ ;;
+ }
+ { .mmi
+ ldf.fill f10 = [r2], 32
+ ldf.fill f11 = [r3], 32
+ mov ar.pfs = loc0
+ ;;
+ }
+ { .mmi
+ ldf.fill f12 = [r2], 32
+ ldf.fill f13 = [r3], 32
+ mov b0 = loc1
+ ;;
+ }
+ { .mmi
+ ldf.fill f14 = [r2]
+ ldf.fill f15 = [r3]
+ /* We know that the previous stack pointer, loc10, isn't 0.
+ We use it to reload p7. */
+ cmp.ne p7, p0 = 0, loc10
+ ;;
+ }
+.Lresolved:
+ { .mmb
+ .restore sp
+ mov r12 = loc10
+(p7) br.ret.sptk.many b0
+ ;;
+ }
+ /* An alloc is needed for the break system call to work. We
+ don't care about the old value of the pfs register. After
+ this alloc, we can't use any rotating registers. Otherwise
+ assembler won't be happy. This has to be at the end. */
+ { .mmb
+ .prologue
+ .body
+ alloc r2 = ar.pfs, 0, 0, 8, 0
+ br.sptk.many b6
+ ;;
+ }
+END(_dl_runtime_profile)
+#endif
diff --git a/libc/sysdeps/ia64/elf/configure b/libc/sysdeps/ia64/elf/configure
new file mode 100644
index 000000000..30f485067
--- /dev/null
+++ b/libc/sysdeps/ia64/elf/configure
@@ -0,0 +1,51 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/ia64/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+echo "$as_me:$LINENO: checking for ia64 TLS support" >&5
+echo $ECHO_N "checking for ia64 TLS support... $ECHO_C" >&6
+if test "${libc_cv_ia64_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<\EOF
+ .section ".tdata","awT",@progbits
+foo: data8 25
+ .text
+ addl r16 = @ltoff(@dtpmod(foo#)), gp
+ addl r17 = @ltoff(@dtprel(foo#)), gp
+ addl r18 = @ltoff(@tprel(foo#)), gp
+ addl r19 = @dtprel(foo#), gp
+ adds r21 = @dtprel(foo#), r13
+ movl r23 = @dtprel(foo#)
+ addl r20 = @tprel(foo#), gp
+ adds r22 = @tprel(foo#), r13
+ movl r24 = @tprel(foo#)
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_ia64_tls=yes
+else
+ libc_cv_ia64_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_ia64_tls" >&5
+echo "${ECHO_T}$libc_cv_ia64_tls" >&6
+if test $libc_cv_ia64_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+cat >>confdefs.h <<\_ACEOF
+#define PI_STATIC_AND_HIDDEN 1
+_ACEOF
+
diff --git a/libc/sysdeps/ia64/elf/configure.in b/libc/sysdeps/ia64/elf/configure.in
new file mode 100644
index 000000000..b113579ee
--- /dev/null
+++ b/libc/sysdeps/ia64/elf/configure.in
@@ -0,0 +1,36 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/ia64/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for ia64 TLS support, libc_cv_ia64_tls, [dnl
+cat > conftest.s <<\EOF
+ .section ".tdata","awT",@progbits
+foo: data8 25
+ .text
+ addl r16 = @ltoff(@dtpmod(foo#)), gp
+ addl r17 = @ltoff(@dtprel(foo#)), gp
+ addl r18 = @ltoff(@tprel(foo#)), gp
+ addl r19 = @dtprel(foo#), gp
+ adds r21 = @dtprel(foo#), r13
+ movl r23 = @dtprel(foo#)
+ addl r20 = @tprel(foo#), gp
+ adds r22 = @tprel(foo#), r13
+ movl r24 = @tprel(foo#)
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_ia64_tls=yes
+else
+ libc_cv_ia64_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_ia64_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
+dnl It is always possible to access static and hidden symbols in an
+dnl position independent way.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
diff --git a/libc/sysdeps/ia64/elf/entry.h b/libc/sysdeps/ia64/elf/entry.h
new file mode 100644
index 000000000..b93e1b6a5
--- /dev/null
+++ b/libc/sysdeps/ia64/elf/entry.h
@@ -0,0 +1,10 @@
+#ifndef __ASSEMBLY__
+extern void _start (void);
+#endif
+
+/* The function's entry point is stored in the first word of the
+ function descriptor (plabel) of _start(). */
+#define ENTRY_POINT (((long int *) _start)[0])
+
+/* We have to provide a special declaration. */
+#define ENTRY_POINT_DECL(class) class void _start (void);
diff --git a/libc/sysdeps/ia64/elf/initfini.c b/libc/sysdeps/ia64/elf/initfini.c
new file mode 100644
index 000000000..d0a65ece8
--- /dev/null
+++ b/libc/sysdeps/ia64/elf/initfini.c
@@ -0,0 +1,152 @@
+/* Special .init and .fini section support for ia64.
+ Copyright (C) 2000, 2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file is compiled into assembly code which is then munged by a sed
+ script into two files: crti.s and crtn.s.
+
+ * crti.s puts a function prologue at the beginning of the
+ .init and .fini sections and defines global symbols for
+ those addresses, so they can be called as functions.
+
+ * crtn.s puts the corresponding function epilogues
+ in the .init and .fini sections. */
+
+__asm__ ("\n\n"
+"#include \"defs.h\"\n"
+"\n"
+"/*@HEADER_ENDS*/\n"
+"\n"
+"/*@_init_PROLOG_BEGINS*/\n");
+
+
+/* If we have working .init_array support, we want to keep the .init
+ section empty (apart from the mandatory prologue/epilogue. This
+ ensures that the default unwind conventions (return-pointer in b0,
+ frame state in ar.pfs, etc.) will do the Right Thing. To ensure
+ an empty .init section, we register gmon_initializer() via the
+ .init_array.
+
+ --davidm 02/10/29 */
+
+static void
+__attribute__ ((used))
+gmon_initializer (void)
+{
+ extern void weak_function __gmon_start__ (void);
+
+ if (__gmon_start__)
+ (*__gmon_start__)();
+}
+
+__asm__ (".section .init_array, \"aw\"\n"
+ "\tdata8 @fptr(gmon_initializer)\n");
+
+
+__asm__ (".section .init\n"
+" .global _init#\n"
+" .proc _init#\n"
+"_init:\n"
+" .prologue\n"
+" .save ar.pfs, r34\n"
+" alloc r34 = ar.pfs, 0, 3, 0, 0\n"
+" .vframe r32\n"
+" mov r32 = r12\n"
+" .save rp, r33\n"
+" mov r33 = b0\n"
+" .body\n"
+" adds r12 = -16, r12\n"
+" ;;\n" /* see gmon_initializer() above */
+" .endp _init#\n"
+"\n"
+"/*@_init_PROLOG_ENDS*/\n"
+"\n"
+"/*@_init_EPILOG_BEGINS*/\n"
+" .section .init\n"
+" .proc _init#\n"
+"_init:\n"
+" .prologue\n"
+" .save ar.pfs, r34\n"
+" .vframe r32\n"
+" .save rp, r33\n"
+" .body\n"
+" .regstk 0,2,0,0\n"
+" mov r12 = r32\n"
+" mov ar.pfs = r34\n"
+" mov b0 = r33\n"
+" br.ret.sptk.many b0\n"
+" .endp _init#\n"
+"/*@_init_EPILOG_ENDS*/\n"
+"\n"
+"/*@_fini_PROLOG_BEGINS*/\n"
+" .section .fini\n"
+" .global _fini#\n"
+" .proc _fini#\n"
+"_fini:\n"
+" .prologue\n"
+" .save ar.pfs, r34\n"
+" alloc r34 = ar.pfs, 0, 3, 0, 0\n"
+" .vframe r32\n"
+" mov r32 = r12\n"
+" .save rp, r33\n"
+" mov r33 = b0\n"
+" .body\n"
+" adds r12 = -16, r12\n"
+" ;;\n"
+" .endp _fini#\n"
+"\n"
+"/*@_fini_PROLOG_ENDS*/\n"
+" br.call.sptk.many b0 = i_am_not_a_leaf# ;;\n"
+" ;;\n"
+"\n"
+"/*@_fini_EPILOG_BEGINS*/\n"
+" .section .fini\n"
+" .proc _fini#\n"
+"_fini:\n"
+" .prologue\n"
+" .save ar.pfs, r34\n"
+" .vframe r32\n"
+" .save rp, r33\n"
+" .body\n"
+" mov r12 = r32\n"
+" mov ar.pfs = r34\n"
+" mov b0 = r33\n"
+" br.ret.sptk.many b0\n"
+" .endp _fini#\n"
+"\n"
+"/*@_fini_EPILOG_ENDS*/\n"
+"\n"
+"/*@TRAILER_BEGINS*/\n"
+);
diff --git a/libc/sysdeps/ia64/elf/start.S b/libc/sysdeps/ia64/elf/start.S
new file mode 100644
index 000000000..1c41a6517
--- /dev/null
+++ b/libc/sysdeps/ia64/elf/start.S
@@ -0,0 +1,120 @@
+/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include <asm/unistd.h>
+#include <asm/fpu.h>
+
+/*
+ * Arguments for __libc_start_main:
+ * out0: main
+ * out1: argc
+ * out2: argv
+ * out3: init
+ * out4: fini
+ * out5: rtld_fini
+ * out6: stack_end
+ */
+
+ .align 32
+ .global _start
+
+ .proc _start
+ .type _start,@function
+_start:
+ .prologue
+ .save rp, r0
+ .body
+ .prologue
+ { .mlx
+ alloc r2 = ar.pfs,0,0,7,0
+ movl r3 = FPSR_DEFAULT
+ }
+ { .mlx
+ adds out2 = 16, sp /* get address of argc value */
+ movl gp = @gprel(0f)
+ ;;
+ }
+0: { .mmi
+ ld8 out1 = [out2], 8 /* load argc and move out2 to become argv */
+ mov.m r10 = ar.bsp /* fetch rbs base address */
+ mov r9 = ip
+ ;;
+ }
+ { .mii
+ mov ar.fpsr = r3
+ sub gp = r9, gp /* back-compute gp value */
+ adds out6 = 16, sp /* highest non-environment stack address */
+ ;;
+ }
+ {
+ addl r11 = @ltoff(__libc_ia64_register_backing_store_base), gp
+ addl out0 = @ltoff(@fptr(main)), gp
+ addl out3 = @ltoff(@fptr(__libc_csu_init)), gp
+ ;;
+ }
+ { .mmi
+ ld8 r3 = [r11] /* pointer to __libc_ia64_register_backing_store_base */
+ ld8 out0 = [out0] /* pointer to `main' function descriptor */
+ addl out4 = @ltoff(@fptr(__libc_csu_fini)), gp
+ ;;
+ }
+ { .mmi
+ ld8 out3 = [out3] /* pointer to `init' function descriptor */
+ ld8 out4 = [out4] /* pointer to `fini' function descriptor */
+ nop 0
+ }
+ .body
+ { .mib
+ st8 [r3] = r10
+ mov out5 = ret0 /* dynamic linker destructor */
+ br.call.sptk.few rp = __libc_start_main
+ }
+ { .mib
+ break 0 /* break miserably if we ever return */
+ }
+ .endp _start
+
+/* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+ .long 0
+ .weak data_start
+ data_start = __data_start
+
+ .common __libc_ia64_register_backing_store_base, 8, 8
diff --git a/libc/sysdeps/ia64/fpu/Makefile b/libc/sysdeps/ia64/fpu/Makefile
new file mode 100644
index 000000000..384fc836a
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/Makefile
@@ -0,0 +1,34 @@
+ifeq ($(subdir),math)
+#
+# Some files which need to go both into libc and libm have external
+# dependencies which need to be resolved differently for libc
+# vs. libm. For example, inside libc, __libm_error_support needs to
+# resolve to HIDDEN_JUMPTARGET(__libm_error_support) whereas within
+# libm it always resolves to __libm_error_support. Such files need to
+# be compiled twice. Fortunately, math/Makefile already has logic to
+# support this: if a file starts with "s_", make will automatically
+# generate a matching file whose name starts with "m_" which simply
+# includes the corresponding "s_" file.
+#
+duplicated-routines = s_libm_ldexp s_libm_ldexpf s_libm_ldexpl \
+ s_libm_scalbn s_libm_scalbnf s_libm_scalbnl
+
+libm-sysdep_routines += s_erfc s_erfcf s_erfcl \
+ s_matherrf s_matherrl libm_reduce \
+ libm_error \
+ libm_frexp libm_frexpf libm_frexpl \
+ libm_sincos libm_sincosf libm_sincosl \
+ libm_sincos_large \
+ libm_lgamma libm_lgammaf libm_lgammal \
+ libm_scalblnf \
+ $(duplicated-routines:s_%=m_%)
+
+sysdep_routines += libc_libm_error libm_frexp libm_frexpf libm_frexpl \
+ $(duplicated-routines)
+
+sysdep-CPPFLAGS += -include libm-symbols.h \
+ -D__POSIX__ -Dopensource \
+ -D_LIB_VERSIONIMF=_LIB_VERSION \
+ -DSIZE_INT_32 -DSIZE_LONG_INT_64 -DSIZE_LONG_LONG_INT_64 \
+ -DSIZE_LONG_64 -DIA64
+endif
diff --git a/libc/sysdeps/ia64/fpu/README b/libc/sysdeps/ia64/fpu/README
new file mode 100644
index 000000000..6f4af0678
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/README
@@ -0,0 +1,50 @@
+ ----------------------------------------------------------
+ Notes on how to update libm based on Intel's libm releases
+ ----------------------------------------------------------
+
+This source code in this directory is currently based on Intel libm
+v2.1 as available from:
+
+ http://www.intel.com/software/products/opensource/libraries/num.htm
+
+To ease importing, fix some bugs, and simplify integration into libc,
+it is also necessary to apply the patch at:
+
+ ftp://ftp.hpl.hp.com/pub/linux-ia64/intel-libm-041228.diff.gz
+
+The expectation is that Intel will integrate most if not all of these
+changes into future releases of libm, so this patching step can
+hopefully be omitted in the future.
+
+Once the patched libm sources are extracted in a directory $LIBM, they
+can be imported into the libc source tree at $LIBC with the following
+step:
+
+ $ cd $LIBC/src/sysdep/ia64/fpu
+ $ ./import_intel_libm $LIBM
+
+This should produce a number of "Importing..." messages, without
+showing any errors.
+
+At this point, you should be able to build glibc in the usual fashion.
+We assume you do this in directory $OBJ. Once the build has
+completed, run "make check" to verify that all (math) checks succeed.
+If these checks succeed, you should also run the following commands to
+verify that the new libm doesn't pollute the name-space and has proper
+size-info for the data objects:
+
+ $ cd $LIBC/src/sysdep/ia64/fpu
+ $ import_check $OBJ/math/
+
+There should be no (unexpected) errors reported by this script.
+
+As an optional step, you may also want to confirm that the new libm
+exports the exact same global symbols as the old one.
+
+If you want to see the changes introduced by the "import_intel_libm"
+script, you can run the commands:
+
+ $ cd $LIBC/src/sysdep/ia64/fpu
+ $ import_diffs
+
+That's it.
diff --git a/libc/sysdeps/ia64/fpu/Versions b/libc/sysdeps/ia64/fpu/Versions
new file mode 100644
index 000000000..1faea6458
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/Versions
@@ -0,0 +1,10 @@
+libc {
+ GLIBC_PRIVATE {
+ __libm_frexp_4; __libm_frexp_4f; __libm_frexp_4l; __libm_error_support;
+ }
+}
+libm {
+ GLIBC_2.2.3 {
+ matherrf; matherrl;
+ }
+}
diff --git a/libc/sysdeps/ia64/fpu/bits/mathinline.h b/libc/sysdeps/ia64/fpu/bits/mathinline.h
new file mode 100644
index 000000000..9bb5f1a71
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/bits/mathinline.h
@@ -0,0 +1,54 @@
+/* Inline math functions for ia64.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
+#endif
+
+#ifdef __cplusplus
+# define __MATH_INLINE __inline
+#else
+# define __MATH_INLINE extern __inline
+#endif
+
+#if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2
+/* The gcc, version 2.7 or below, has problems with all this inlining
+ code. So disable it for this version of the compiler. */
+# if __GNUC_PREREQ (2, 8)
+/* Test for negative number. Used in the signbit() macro. */
+__MATH_INLINE int
+__NTH (__signbitf (float __x))
+{
+ __extension__ union { float __f; int __i; } __u = { __f: __x };
+ return __u.__i < 0;
+}
+__MATH_INLINE int
+__NTH (__signbit (double __x))
+{
+ __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
+ return __u.__i[1] < 0;
+}
+__MATH_INLINE int
+__NTH (__signbitl (long double __x))
+{
+ __extension__ union { long double __l; int __i[3]; } __u = { __l: __x };
+ return (__u.__i[2] & 0x8000) != 0;
+}
+# endif
+#endif
diff --git a/libc/sysdeps/ia64/fpu/branred.c b/libc/sysdeps/ia64/fpu/branred.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/branred.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/doasin.c b/libc/sysdeps/ia64/fpu/doasin.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/doasin.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/dosincos.c b/libc/sysdeps/ia64/fpu/dosincos.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/dosincos.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/e_acos.S b/libc/sysdeps/ia64/fpu/e_acos.S
new file mode 100644
index 000000000..c2b31ab85
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_acos.S
@@ -0,0 +1,878 @@
+.file "acos.s"
+
+
+// Copyright (c) 2000 - 2003 Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 08/17/00 New and much faster algorithm.
+// 08/30/00 Avoided bank conflicts on loads, shortened |x|=1 and x=0 paths,
+// fixed mfb split issue stalls.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 08/02/02 New and much faster algorithm II
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+
+// Description
+//=========================================
+// The acos function computes the principal value of the arc cosine of x.
+// acos(0) returns Pi/2, acos(1) returns 0, acos(-1) returns Pi.
+// A doman error occurs for arguments not in the range [-1,+1].
+//
+// The acos function returns the arc cosine in the range [0, Pi] radians.
+//
+// There are 8 paths:
+// 1. x = +/-0.0
+// Return acos(x) = Pi/2 + x
+//
+// 2. 0.0 < |x| < 0.625
+// Return acos(x) = Pi/2 - x - x^3 *PolA(x^2)
+// where PolA(x^2) = A3 + A5*x^2 + A7*x^4 +...+ A35*x^32
+//
+// 3. 0.625 <=|x| < 1.0
+// Return acos(x) = Pi/2 - asin(x) =
+// = Pi/2 - sign(x) * ( Pi/2 - sqrt(R) * PolB(R))
+// Where R = 1 - |x|,
+// PolB(R) = B0 + B1*R + B2*R^2 +...+B12*R^12
+//
+// sqrt(R) is approximated using the following sequence:
+// y0 = (1 + eps)/sqrt(R) - initial approximation by frsqrta,
+// |eps| < 2^(-8)
+// Then 3 iterations are used to refine the result:
+// H0 = 0.5*y0
+// S0 = R*y0
+//
+// d0 = 0.5 - H0*S0
+// H1 = H0 + d0*H0
+// S1 = S0 + d0*S0
+//
+// d1 = 0.5 - H1*S1
+// H2 = H1 + d0*H1
+// S2 = S1 + d0*S1
+//
+// d2 = 0.5 - H2*S2
+// S3 = S3 + d2*S3
+//
+// S3 approximates sqrt(R) with enough accuracy for this algorithm
+//
+// So, the result should be reconstracted as follows:
+// acos(x) = Pi/2 - sign(x) * (Pi/2 - S3*PolB(R))
+//
+// But for optimization purposes the reconstruction step is slightly
+// changed:
+// acos(x) = Cpi + sign(x)*PolB(R)*S2 - sign(x)*d2*S2*PolB(R)
+// where Cpi = 0 if x > 0 and Cpi = Pi if x < 0
+//
+// 4. |x| = 1.0
+// Return acos(1.0) = 0.0, acos(-1.0) = Pi
+//
+// 5. 1.0 < |x| <= +INF
+// A doman error occurs for arguments not in the range [-1,+1]
+//
+// 6. x = [S,Q]NaN
+// Return acos(x) = QNaN
+//
+// 7. x is denormal
+// Return acos(x) = Pi/2 - x,
+//
+// 8. x is unnormal
+// Normalize input in f8 and return to the very beginning of the function
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input, output
+// f6, f7, f9 -> f15, f32 -> f64
+
+// General registers used:
+// r3, r21 -> r31, r32 -> r38
+
+// Predicate registers used:
+// p0, p6 -> p14
+
+//
+// Assembly macros
+//=========================================
+// integer registers used
+// scratch
+rTblAddr = r3
+
+rPiBy2Ptr = r21
+rTmpPtr3 = r22
+rDenoBound = r23
+rOne = r24
+rAbsXBits = r25
+rHalf = r26
+r0625 = r27
+rSign = r28
+rXBits = r29
+rTmpPtr2 = r30
+rTmpPtr1 = r31
+
+// stacked
+GR_SAVE_PFS = r32
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Parameter_TAG = r38
+
+// floating point registers used
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+
+// scratch
+fXSqr = f6
+fXCube = f7
+fXQuadr = f9
+f1pX = f10
+f1mX = f11
+f1pXRcp = f12
+f1mXRcp = f13
+fH = f14
+fS = f15
+// stacked
+fA3 = f32
+fB1 = f32
+fA5 = f33
+fB2 = f33
+fA7 = f34
+fPiBy2 = f34
+fA9 = f35
+fA11 = f36
+fB10 = f35
+fB11 = f36
+fA13 = f37
+fA15 = f38
+fB4 = f37
+fB5 = f38
+fA17 = f39
+fA19 = f40
+fB6 = f39
+fB7 = f40
+fA21 = f41
+fA23 = f42
+fB3 = f41
+fB8 = f42
+fA25 = f43
+fA27 = f44
+fB9 = f43
+fB12 = f44
+fA29 = f45
+fA31 = f46
+fA33 = f47
+fA35 = f48
+fBaseP = f49
+fB0 = f50
+fSignedS = f51
+fD = f52
+fHalf = f53
+fR = f54
+fCloseTo1Pol = f55
+fSignX = f56
+fDenoBound = f57
+fNormX = f58
+fX8 = f59
+fRSqr = f60
+fRQuadr = f61
+fR8 = f62
+fX16 = f63
+fCpi = f64
+
+// Data tables
+//==============================================================
+RODATA
+.align 16
+LOCAL_OBJECT_START(acos_base_range_table)
+// Ai: Polynomial coefficients for the acos(x), |x| < .625000
+// Bi: Polynomial coefficients for the acos(x), |x| > .625000
+data8 0xBFDAAB56C01AE468 //A29
+data8 0x3FE1C470B76A5B2B //A31
+data8 0xBFDC5FF82A0C4205 //A33
+data8 0x3FC71FD88BFE93F0 //A35
+data8 0xB504F333F9DE6487, 0x00003FFF //B0
+data8 0xAAAAAAAAAAAAFC18, 0x00003FFC //A3
+data8 0x3F9F1C71BC4A7823 //A9
+data8 0x3F96E8BBAAB216B2 //A11
+data8 0x3F91C4CA1F9F8A98 //A13
+data8 0x3F8C9DDCEDEBE7A6 //A15
+data8 0x3F877784442B1516 //A17
+data8 0x3F859C0491802BA2 //A19
+data8 0x9999999998C88B8F, 0x00003FFB //A5
+data8 0x3F6BD7A9A660BF5E //A21
+data8 0x3F9FC1659340419D //A23
+data8 0xB6DB6DB798149BDF, 0x00003FFA //A7
+data8 0xBFB3EF18964D3ED3 //A25
+data8 0x3FCD285315542CF2 //A27
+data8 0xF15BEEEFF7D2966A, 0x00003FFB //B1
+data8 0x3EF0DDA376D10FB3 //B10
+data8 0xBEB83CAFE05EBAC9 //B11
+data8 0x3F65FFB67B513644 //B4
+data8 0x3F5032FBB86A4501 //B5
+data8 0x3F392162276C7CBA //B6
+data8 0x3F2435949FD98BDF //B7
+data8 0xD93923D7FA08341C, 0x00003FF9 //B2
+data8 0x3F802995B6D90BDB //B3
+data8 0x3F10DF86B341A63F //B8
+data8 0xC90FDAA22168C235, 0x00003FFF // Pi/2
+data8 0x3EFA3EBD6B0ECB9D //B9
+data8 0x3EDE18BA080E9098 //B12
+LOCAL_OBJECT_END(acos_base_range_table)
+
+.section .text
+GLOBAL_LIBM_ENTRY(acos)
+acos_unnormal_back:
+{ .mfi
+ getf.d rXBits = f8 // grab bits of input value
+ // set p12 = 1 if x is a NaN, denormal, or zero
+ fclass.m p12, p0 = f8, 0xcf
+ adds rSign = 1, r0
+}
+{ .mfi
+ addl rTblAddr = @ltoff(acos_base_range_table),gp
+ // 1 - x = 1 - |x| for positive x
+ fms.s1 f1mX = f1, f1, f8
+ addl rHalf = 0xFFFE, r0 // exponent of 1/2
+}
+;;
+{ .mfi
+ addl r0625 = 0x3FE4, r0 // high 16 bits of 0.625
+ // set p8 = 1 if x < 0
+ fcmp.lt.s1 p8, p9 = f8, f0
+ shl rSign = rSign, 63 // sign bit
+}
+{ .mfi
+ // point to the beginning of the table
+ ld8 rTblAddr = [rTblAddr]
+ // 1 + x = 1 - |x| for negative x
+ fma.s1 f1pX = f1, f1, f8
+ adds rOne = 0x3FF, r0
+}
+;;
+{ .mfi
+ andcm rAbsXBits = rXBits, rSign // bits of |x|
+ fmerge.s fSignX = f8, f1 // signum(x)
+ shl r0625 = r0625, 48 // bits of DP representation of 0.625
+}
+{ .mfb
+ setf.exp fHalf = rHalf // load A2 to FP reg
+ fma.s1 fXSqr = f8, f8, f0 // x^2
+ // branch on special path if x is a NaN, denormal, or zero
+(p12) br.cond.spnt acos_special
+}
+;;
+{ .mfi
+ adds rPiBy2Ptr = 272, rTblAddr
+ nop.f 0
+ shl rOne = rOne, 52 // bits of 1.0
+}
+{ .mfi
+ adds rTmpPtr1 = 16, rTblAddr
+ nop.f 0
+ // set p6 = 1 if |x| < 0.625
+ cmp.lt p6, p7 = rAbsXBits, r0625
+}
+;;
+{ .mfi
+ ldfpd fA29, fA31 = [rTblAddr] // A29, fA31
+ // 1 - x = 1 - |x| for positive x
+(p9) fms.s1 fR = f1, f1, f8
+ // point to coefficient of "near 1" polynomial
+(p7) adds rTmpPtr2 = 176, rTblAddr
+}
+{ .mfi
+ ldfpd fA33, fA35 = [rTmpPtr1], 16 // A33, fA35
+ // 1 + x = 1 - |x| for negative x
+(p8) fma.s1 fR = f1, f1, f8
+(p6) adds rTmpPtr2 = 48, rTblAddr
+}
+;;
+{ .mfi
+ ldfe fB0 = [rTmpPtr1], 16 // B0
+ nop.f 0
+ nop.i 0
+}
+{ .mib
+ adds rTmpPtr3 = 16, rTmpPtr2
+ // set p10 = 1 if |x| = 1.0
+ cmp.eq p10, p0 = rAbsXBits, rOne
+ // branch on special path for |x| = 1.0
+(p10) br.cond.spnt acos_abs_1
+}
+;;
+{ .mfi
+ ldfe fA3 = [rTmpPtr2], 48 // A3 or B1
+ nop.f 0
+ adds rTmpPtr1 = 64, rTmpPtr3
+}
+{ .mib
+ ldfpd fA9, fA11 = [rTmpPtr3], 16 // A9, A11 or B10, B11
+ // set p11 = 1 if |x| > 1.0
+ cmp.gt p11, p0 = rAbsXBits, rOne
+ // branch on special path for |x| > 1.0
+(p11) br.cond.spnt acos_abs_gt_1
+}
+;;
+{ .mfi
+ ldfpd fA17, fA19 = [rTmpPtr2], 16 // A17, A19 or B6, B7
+ // initial approximation of 1 / sqrt(1 - x)
+ frsqrta.s1 f1mXRcp, p0 = f1mX
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA13, fA15 = [rTmpPtr3] // A13, A15 or B4, B5
+ fma.s1 fXCube = fXSqr, f8, f0 // x^3
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fA5 = [rTmpPtr2], 48 // A5 or B2
+ // initial approximation of 1 / sqrt(1 + x)
+ frsqrta.s1 f1pXRcp, p0 = f1pX
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA21, fA23 = [rTmpPtr1], 16 // A21, A23 or B3, B8
+ fma.s1 fXQuadr = fXSqr, fXSqr, f0 // x^4
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fA7 = [rTmpPtr1] // A7 or Pi/2
+ fma.s1 fRSqr = fR, fR, f0 // R^2
+ nop.i 0
+}
+{ .mfb
+ ldfpd fA25, fA27 = [rTmpPtr2] // A25, A27 or B9, B12
+ nop.f 0
+(p6) br.cond.spnt acos_base_range;
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fH = fHalf, f1mXRcp, f0 // H0 for x > 0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fS = f1mX, f1mXRcp, f0 // S0 for x > 0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fH = fHalf, f1pXRcp, f0 // H0 for x < 0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fS = f1pX, f1pXRcp, f0 // S0 for x > 0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRQuadr = fRSqr, fRSqr, f0 // R^4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fB11 = fB11, fR, fB10
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB1 = fB1, fR, fB0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fB5 = fB5, fR, fB4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB7 = fB7, fR, fB6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fB3 = fB3, fR, fB2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fnma.s1 fD = fH, fS, fHalf // d0 = 1/2 - H0*S0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fR8 = fRQuadr, fRQuadr, f0 // R^4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB9 = fB9, fR, fB8
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fB12 = fB12, fRSqr, fB11
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 fB7 = fB7, fRSqr, fB5
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fB3 = fB3, fRSqr, fB1
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fH = fH, fD, fH // H1 = H0 + H0*d0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS = fS, fD, fS // S1 = S0 + S0*d0
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+(p9) fma.s1 fCpi = f1, f0, f0 // Cpi = 0 if x > 0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fCpi = fPiBy2, f1, fPiBy2 // Cpi = Pi if x < 0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fB12 = fB12, fRSqr, fB9
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB7 = fB7, fRQuadr, fB3
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fnma.s1 fD = fH, fS, fHalf // d1 = 1/2 - H1*S1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 fSignedS = fSignX, fS, f0 // -signum(x)*S1
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fCloseTo1Pol = fB12, fR8, fB7
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fH = fH, fD, fH // H2 = H1 + H1*d1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS = fS, fD, fS // S2 = S1 + S1*d1
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // -signum(x)* S2 = -signum(x)*(S1 + S1*d1)
+ fma.s1 fSignedS = fSignedS, fD, fSignedS
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fnma.s1 fD = fH, fS, fHalf // d2 = 1/2 - H2*S2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // Cpi + signum(x)*PolB*S2
+ fnma.s1 fCpi = fSignedS, fCloseTo1Pol, fCpi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // signum(x)*PolB * S2
+ fnma.s1 fCloseTo1Pol = fSignedS, fCloseTo1Pol, f0
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ // final result for 0.625 <= |x| < 1
+ fma.d.s0 f8 = fCloseTo1Pol, fD, fCpi
+ // exit here for 0.625 <= |x| < 1
+ br.ret.sptk b0
+}
+;;
+
+
+// here if |x| < 0.625
+.align 32
+acos_base_range:
+{ .mfi
+ ldfe fCpi = [rPiBy2Ptr] // Pi/2
+ fma.s1 fA33 = fA33, fXSqr, fA31
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, fXSqr, fA13
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA29 = fA29, fXSqr, fA27
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA25 = fA25, fXSqr, fA23
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA21 = fA21, fXSqr, fA19
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, fXSqr, fA7
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA5 = fA5, fXSqr, fA3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA35 = fA35, fXQuadr, fA33
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, fXQuadr, fA15
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fX8 = fXQuadr, fXQuadr, f0 // x^8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA25 = fA25, fXQuadr, fA21
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, fXQuadr, fA5
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fCpi = fCpi, f1, f8 // Pi/2 - x
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA35 = fA35, fXQuadr, fA29
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, fXSqr, fA11
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fX16 = fX8, fX8, f0 // x^16
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA35 = fA35, fX8, fA25
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, fX8, fA9
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fBaseP = fA35, fX16, fA17
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ // final result for |x| < 0.625
+ fnma.d.s0 f8 = fBaseP, fXCube, fCpi
+ // exit here for |x| < 0.625 path
+ br.ret.sptk b0
+}
+;;
+
+// here if |x| = 1
+// acos(1) = 0
+// acos(-1) = Pi
+.align 32
+acos_abs_1:
+{ .mfi
+ ldfe fPiBy2 = [rPiBy2Ptr] // Pi/2
+ nop.f 0
+ nop.i 0
+}
+;;
+.pred.rel "mutex", p8, p9
+{ .mfi
+ nop.m 0
+ // result for x = 1.0
+(p9) fma.d.s0 f8 = f1, f0, f0 // 0.0
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ // result for x = -1.0
+(p8) fma.d.s0 f8 = fPiBy2, f1, fPiBy2 // Pi
+ // exit here for |x| = 1.0
+ br.ret.sptk b0
+}
+;;
+
+// here if x is a NaN, denormal, or zero
+.align 32
+acos_special:
+{ .mfi
+ // point to Pi/2
+ adds rPiBy2Ptr = 272, rTblAddr
+ // set p12 = 1 if x is a NaN
+ fclass.m p12, p0 = f8, 0xc3
+ nop.i 0
+}
+{ .mlx
+ nop.m 0
+ // smallest positive DP normalized number
+ movl rDenoBound = 0x0010000000000000
+}
+;;
+{ .mfi
+ ldfe fPiBy2 = [rPiBy2Ptr] // Pi/2
+ // set p13 = 1 if x = 0.0
+ fclass.m p13, p0 = f8, 0x07
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNormX = f8
+ nop.i 0
+}
+;;
+{ .mfb
+ // load smallest normal to FP reg
+ setf.d fDenoBound = rDenoBound
+ // answer if x is a NaN
+(p12) fma.d.s0 f8 = f8,f1,f0
+ // exit here if x is a NaN
+(p12) br.ret.spnt b0
+}
+;;
+{ .mfi
+ nop.m 0
+ // absolute value of normalized x
+ fmerge.s fNormX = f1, fNormX
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ // final result for x = 0
+(p13) fma.d.s0 f8 = fPiBy2, f1, f8
+ // exit here if x = 0.0
+(p13) br.ret.spnt b0
+}
+;;
+// if we still here then x is denormal or unnormal
+{ .mfi
+ nop.m 0
+ // set p14 = 1 if normalized x is greater than or
+ // equal to the smallest denormalized value
+ // So, if p14 is set to 1 it means that we deal with
+ // unnormal rather than with "true" denormal
+ fcmp.ge.s1 p14, p0 = fNormX, fDenoBound
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+(p14) fcmp.eq.s0 p6, p0 = f8, f0 // Set D flag if x unnormal
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ // normalize unnormal input
+(p14) fnorm.s1 f8 = f8
+ // return to the main path
+(p14) br.cond.sptk acos_unnormal_back
+}
+;;
+// if we still here it means that input is "true" denormal
+{ .mfb
+ nop.m 0
+ // final result if x is denormal
+ fms.d.s0 f8 = fPiBy2, f1, f8 // Pi/2 - x
+ // exit here if x is denormal
+ br.ret.sptk b0
+}
+;;
+
+// here if |x| > 1.0
+// error handler should be called
+.align 32
+acos_abs_gt_1:
+{ .mfi
+ alloc r32 = ar.pfs, 0, 3, 4, 0 // get some registers
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 58 // error code
+ frcpa.s0 FR_RESULT, p0 = f0,f0
+ // call error handler routine
+ br.cond.sptk __libm_error_region
+}
+;;
+GLOBAL_LIBM_END(acos)
+
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_acosf.S b/libc/sysdeps/ia64/fpu/e_acosf.S
new file mode 100644
index 000000000..68b0b2ee8
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_acosf.S
@@ -0,0 +1,694 @@
+.file "acosf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 06/28/00 Improved speed
+// 06/31/00 Changed register allocation because of some duplicate macros
+// moved nan exit bundle up to gain a cycle.
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 08/17/00 Changed predicate register macro-usage to direct predicate
+// names due to an assembler bug.
+// 10/17/00 Improved speed of x=0 and x=1 paths, set D flag if x denormal.
+// 03/13/01 Corrected sign of imm1 value in dep instruction.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 04/17/03 Moved mutex after label
+
+
+// Description
+//=========================================
+// The acosf function computes the principle value of the arc sine of x.
+// A doman error occurs for arguments not in the range [-1,+1].
+
+// The acosf function returns the arc cosine in the range [0, +pi] radians.
+// acos(1) returns +0
+// acos(x) returns a Nan and raises the invalid exception for |x| >1
+
+// |x| <= sqrt(2)/2. get Ax and Bx
+
+// poly_p1 = x p1
+// poly_p3 = x2 p4 + p3
+// poly_p1 = x2 (poly_p1) + x = x2(x p1) + x
+// poly_p2 = x2( poly_p3) + p2 = x2(x2 p4 + p3) + p2
+
+// poly_Ax = x5(x2( poly_p3) + p2) + x2(x p1) + x
+// = x5(x2(x2 p4 + p3) + p2) + x2(x p1) + x
+
+// poly_p7 = x2 p8 + p7
+// poly_p5 = x2 p6 + p5
+
+// poly_p7 = x4 p9 + (x2 p8 + p7)
+// poly_Bx = x4 (x4 p9 + (x2 p8 + p7)) + x2 p6 + p5
+
+// sinf1 = x11(x4 (x4 p9 + (x2 p8 + p7)) + x2 p6 + p5) + x5(x2(x2 p4 + p3) + p2) + x2(x p1) + x
+// = x19 p9 + x17 p8 + x15 p7 x13 p6 + x11 p5 + x9 p4 + x7 p3 + x5 p2 + x3 p1 + x
+// answer1 = pi/2 - sinf1
+
+
+
+// |x| > sqrt(2)/2
+
+// Get z = sqrt(1-x2)
+
+// Get polynomial in t = 1-x2
+
+// t2 = t t
+// t4 = t2 t2
+
+// poly_p4 = t p5 + p4
+// poly_p1 = t p1 + 1
+
+// poly_p6 = t p7 + p6
+// poly_p2 = t p3 + p2
+
+// poly_p8 = t p9 + p8
+
+// poly_p4 = t2 poly_p6 + poly_p4
+// = t2 (t p7 + p6) + (t p5 + p4)
+
+// poly_p2 = t2 poly_p2 + poly_p1
+// = t2 (t p3 + p2) + (t p1 + 1)
+
+// poly_p4 = t4 poly_p8 + poly_p4
+// = t4 (t p9 + p8) + (t2 (t p7 + p6) + (t p5 + p4))
+
+// P(t) = poly_p2 + t4 poly_p8
+// = t2 (t p3 + p2) + (t p1 + 1) + t4 (t4 (t p9 + p8) + (t2 (t p7 + p6) + (t p5 + p4)))
+// = t3 p3 + t2 p2 + t p1 + 1 + t9 p9 + t8 p8 + t7 p7 + t6 p6 + t5 p5 + t4 p4
+
+
+// answer2 = sign(x) z P(t) if x>0
+// = sign(x) z P(t) + pi if x<0
+
+
+//
+// Assembly macros
+//=========================================
+
+// predicate registers
+//acosf_pred_LEsqrt2by2 = p7
+//acosf_pred_GTsqrt2by2 = p8
+
+// integer registers
+ACOSF_Addr1 = r33
+ACOSF_Addr2 = r34
+ACOSF_GR_1by2 = r35
+
+ACOSF_GR_3by2 = r36
+ACOSF_GR_5by2 = r37
+
+GR_SAVE_B0 = r38
+GR_SAVE_PFS = r39
+GR_SAVE_GP = r40
+
+GR_Parameter_X = r41
+GR_Parameter_Y = r42
+GR_Parameter_RESULT = r43
+GR_Parameter_TAG = r44
+
+// floating point registers
+
+acosf_y = f32
+acosf_abs_x = f33
+acosf_x2 = f34
+acosf_sgn_x = f35
+
+acosf_1by2 = f36
+acosf_3by2 = f37
+acosf_5by2 = f38
+acosf_coeff_P3 = f39
+acosf_coeff_P8 = f40
+
+acosf_coeff_P1 = f41
+acosf_coeff_P4 = f42
+acosf_coeff_P5 = f43
+acosf_coeff_P2 = f44
+acosf_coeff_P7 = f45
+
+acosf_coeff_P6 = f46
+acosf_coeff_P9 = f47
+acosf_x2 = f48
+acosf_x3 = f49
+acosf_x4 = f50
+
+acosf_x8 = f51
+acosf_x5 = f52
+acosf_const_piby2 = f53
+acosf_const_sqrt2by2 = f54
+acosf_x11 = f55
+
+acosf_poly_p1 = f56
+acosf_poly_p3 = f57
+acosf_sinf1 = f58
+acosf_poly_p2 = f59
+acosf_poly_Ax = f60
+
+acosf_poly_p7 = f61
+acosf_poly_p5 = f62
+acosf_sgnx_t4 = f63
+acosf_poly_Bx = f64
+acosf_t = f65
+
+acosf_yby2 = f66
+acosf_B = f67
+acosf_B2 = f68
+acosf_Az = f69
+acosf_dz = f70
+
+acosf_Sz = f71
+acosf_d2z = f72
+acosf_Fz = f73
+acosf_z = f74
+acosf_sgnx_z = f75
+
+acosf_t2 = f76
+acosf_2poly_p4 = f77
+acosf_2poly_p6 = f78
+acosf_2poly_p1 = f79
+acosf_2poly_p2 = f80
+
+acosf_2poly_p8 = f81
+acosf_t4 = f82
+acosf_Pt = f83
+acosf_sgnx_2poly_p2 = f84
+acosf_sgn_x_piby2 = f85
+
+acosf_poly_p7a = f86
+acosf_2poly_p4a = f87
+acosf_2poly_p4b = f88
+acosf_2poly_p2a = f89
+acosf_poly_p1a = f90
+
+
+
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(acosf_coeff_1_table)
+data8 0x3FC5555607DCF816 // P1
+data8 0x3F9CF81AD9BAB2C6 // P4
+data8 0x3FC59E0975074DF3 // P7
+data8 0xBFA6F4CC2780AA1D // P6
+data8 0x3FC2DD45292E93CB // P9
+data8 0x3fe6a09e667f3bcd // sqrt(2)/2
+LOCAL_OBJECT_END(acosf_coeff_1_table)
+
+LOCAL_OBJECT_START(acosf_coeff_2_table)
+data8 0x3FA6F108E31EFBA6 // P3
+data8 0xBFCA31BF175D82A0 // P8
+data8 0x3FA30C0337F6418B // P5
+data8 0x3FB332C9266CB1F9 // P2
+data8 0x3ff921fb54442d18 // pi_by_2
+LOCAL_OBJECT_END(acosf_coeff_2_table)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(acosf)
+
+// Load the addresses of the two tables.
+// Then, load the coefficients and other constants.
+
+{ .mfi
+ alloc r32 = ar.pfs,1,8,4,0
+ fnma.s1 acosf_t = f8,f8,f1
+ dep.z ACOSF_GR_1by2 = 0x3f,24,8 // 0x3f000000
+}
+{ .mfi
+ addl ACOSF_Addr1 = @ltoff(acosf_coeff_1_table),gp
+ fma.s1 acosf_x2 = f8,f8,f0
+ addl ACOSF_Addr2 = @ltoff(acosf_coeff_2_table),gp ;;
+}
+
+
+{ .mfi
+ ld8 ACOSF_Addr1 = [ACOSF_Addr1]
+ fmerge.s acosf_abs_x = f1,f8
+ dep ACOSF_GR_3by2 = -1,r0,22,8 // 0x3fc00000
+}
+{ .mlx
+ nop.m 999
+ movl ACOSF_GR_5by2 = 0x40200000;;
+}
+
+
+
+{ .mfi
+ setf.s acosf_1by2 = ACOSF_GR_1by2
+ fmerge.s acosf_sgn_x = f8,f1
+ nop.i 999
+}
+{ .mfi
+ ld8 ACOSF_Addr2 = [ACOSF_Addr2]
+ nop.f 0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ setf.s acosf_5by2 = ACOSF_GR_5by2
+ fcmp.lt.s1 p11,p12 = f8,f0
+ nop.i 999;;
+}
+
+{ .mmf
+ ldfpd acosf_coeff_P1,acosf_coeff_P4 = [ACOSF_Addr1],16
+ setf.s acosf_3by2 = ACOSF_GR_3by2
+ fclass.m.unc p8,p0 = f8, 0xc3 ;; //@qnan | @snan
+}
+
+
+{ .mfi
+ ldfpd acosf_coeff_P7,acosf_coeff_P6 = [ACOSF_Addr1],16
+ fma.s1 acosf_t2 = acosf_t,acosf_t,f0
+ nop.i 999
+}
+{ .mfi
+ ldfpd acosf_coeff_P3,acosf_coeff_P8 = [ACOSF_Addr2],16
+ fma.s1 acosf_x4 = acosf_x2,acosf_x2,f0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ ldfpd acosf_coeff_P9,acosf_const_sqrt2by2 = [ACOSF_Addr1]
+ fclass.m.unc p10,p0 = f8, 0x07 //@zero
+ nop.i 999
+}
+{ .mfi
+ ldfpd acosf_coeff_P5,acosf_coeff_P2 = [ACOSF_Addr2],16
+ fma.s1 acosf_x3 = f8,acosf_x2,f0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ ldfd acosf_const_piby2 = [ACOSF_Addr2]
+ frsqrta.s1 acosf_B,p0 = acosf_t
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p8) fma.s.s0 f8 = f8,f1,f0
+(p8) br.ret.spnt b0 ;; // Exit if x=nan
+}
+
+
+{ .mfb
+ nop.m 999
+ fcmp.eq.s1 p6,p0 = acosf_abs_x,f1
+(p10) br.cond.spnt ACOSF_ZERO ;; // Branch if x=0
+}
+
+{ .mfi
+ nop.m 999
+ fcmp.gt.s1 p9,p0 = acosf_abs_x,f1
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_x8 = acosf_x4,acosf_x4,f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fma.s1 acosf_t4 = acosf_t2,acosf_t2,f0
+(p6) br.cond.spnt ACOSF_ABS_ONE ;; // Branch if |x|=1
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_x5 = acosf_x2,acosf_x3,f0
+ nop.i 999
+}
+{ .mfb
+(p9) mov GR_Parameter_TAG = 59
+ fma.s1 acosf_yby2 = acosf_t,acosf_1by2,f0
+(p9) br.cond.spnt __libm_error_region ;; // Branch if |x|>1
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_Az = acosf_t,acosf_B,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_B2 = acosf_B,acosf_B,f0
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_poly_p1 = f8,acosf_coeff_P1,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_2poly_p1 = acosf_coeff_P1,acosf_t,f1
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_poly_p3 = acosf_coeff_P4,acosf_x2,acosf_coeff_P3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_2poly_p6 = acosf_coeff_P7,acosf_t,acosf_coeff_P6
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_poly_p7 = acosf_x2,acosf_coeff_P8,acosf_coeff_P7
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_2poly_p2 = acosf_coeff_P3,acosf_t,acosf_coeff_P2
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_poly_p5 = acosf_x2,acosf_coeff_P6,acosf_coeff_P5
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_2poly_p4 = acosf_coeff_P5,acosf_t,acosf_coeff_P4
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_x11 = acosf_x8,acosf_x3,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnma.s1 acosf_dz = acosf_B2,acosf_yby2,acosf_1by2
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_poly_p1a = acosf_x2,acosf_poly_p1,f8
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_2poly_p8 = acosf_coeff_P9,acosf_t,acosf_coeff_P8
+ nop.i 999;;
+}
+
+
+// Get the absolute value of x and determine the region in which x lies
+
+{ .mfi
+ nop.m 999
+ fcmp.le.s1 p7,p8 = acosf_abs_x,acosf_const_sqrt2by2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_poly_p2 = acosf_x2,acosf_poly_p3,acosf_coeff_P2
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_poly_p7a = acosf_x4,acosf_coeff_P9,acosf_poly_p7
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 acosf_2poly_p2a = acosf_2poly_p2,acosf_t2,acosf_2poly_p1
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 acosf_sgnx_t4 = acosf_sgn_x,acosf_t4,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 acosf_2poly_p4a = acosf_2poly_p6,acosf_t2,acosf_2poly_p4
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 acosf_Sz = acosf_5by2,acosf_dz,acosf_3by2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 acosf_d2z = acosf_dz,acosf_dz,f0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fnma.d.s1 acosf_sgn_x_piby2 = acosf_sgn_x,acosf_const_piby2,acosf_const_piby2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fma.s1 acosf_poly_Ax = acosf_x5,acosf_poly_p2,acosf_poly_p1a
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+(p7) fma.s1 acosf_poly_Bx = acosf_x4,acosf_poly_p7a,acosf_poly_p5
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 acosf_sgnx_2poly_p2 = acosf_sgn_x,acosf_2poly_p2a,f0
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p6,p0 = f8,f0 // Only purpose is to set D if x denormal
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 acosf_2poly_p4b = acosf_2poly_p8,acosf_t4,acosf_2poly_p4a
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 acosf_Fz = acosf_d2z,acosf_Sz,acosf_dz
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.d.s1 acosf_Pt = acosf_2poly_p4b,acosf_sgnx_t4,acosf_sgnx_2poly_p2
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+(p8) fma.d.s1 acosf_z = acosf_Az,acosf_Fz,acosf_Az
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p7) fma.d.s1 acosf_sinf1 = acosf_x11,acosf_poly_Bx,acosf_poly_Ax
+ nop.i 999;;
+}
+
+.pred.rel "mutex",p8,p7 //acosf_pred_GTsqrt2by2,acosf_pred_LEsqrt2by2
+{ .mfi
+ nop.m 999
+(p8) fma.s.s0 f8 = acosf_z,acosf_Pt,acosf_sgn_x_piby2
+ nop.i 999
+}
+
+{ .mfb
+ nop.m 999
+(p7) fms.s.s0 f8 = acosf_const_piby2,f1,acosf_sinf1
+ br.ret.sptk b0 ;;
+}
+
+ACOSF_ZERO:
+// Here if x=0
+{ .mfb
+ nop.m 999
+ fma.s.s0 f8 = acosf_const_piby2,f1,f0 // acosf(0)=pi/2
+ br.ret.sptk b0 ;;
+}
+
+
+ACOSF_ABS_ONE:
+.pred.rel "mutex",p11,p12
+// Here if |x|=1
+{ .mfi
+ nop.m 999
+(p11) fma.s.s0 f8 = acosf_const_piby2,f1,acosf_const_piby2 // acosf(-1)=pi
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p12) fma.s.s0 f8 = f1,f0,f0 // acosf(1)=0
+ br.ret.sptk b0 ;;
+}
+
+GLOBAL_LIBM_END(acosf)
+
+
+// Stack operations when calling error support.
+// (1) (2)
+// sp -> + psp -> +
+// | |
+// | | <- GR_Y
+// | |
+// | <-GR_Y Y2->|
+// | |
+// | | <- GR_X
+// | |
+// sp-64 -> + sp -> +
+// save ar.pfs save b0
+// save gp
+
+
+// Stack operations when calling error support.
+// (3) (call) (4)
+// psp -> + sp -> +
+// | |
+// R3 ->| <- GR_RESULT | -> f8
+// | |
+// Y2 ->| <- GR_Y |
+// | |
+// X1 ->| |
+// | |
+// sp -> + +
+// restore gp
+// restore ar.pfs
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 999
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = f1,16 // Store Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mfi
+ nop.m 0
+ frcpa.s0 f9,p0 = f0,f0
+ nop.i 0
+};;
+
+{ .mib
+ stfs [GR_Parameter_X] = f8 // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfs [GR_Parameter_Y] = f9 // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_acosh.S b/libc/sysdeps/ia64/fpu/e_acosh.S
new file mode 100644
index 000000000..fb25fa005
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_acosh.S
@@ -0,0 +1,1202 @@
+.file "acosh.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// ==============================================================
+// History
+// ==============================================================
+// 03/23/01 Initial version
+// 04/19/01 Improved speed of the paths #1,2,3,4,5
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 05/14/03 Improved performance, set denormal flag for unorms >= 1.0
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+// ==============================================================
+// double acosh(double)
+//
+// Overview of operation
+// ==============================================================
+//
+// There are 7 paths:
+// 1. x = 1.0
+// Return acosh(x) = 0.0
+// 2. 1.0 < x < 1.000499725341796875(0x3FF0020C00000000)
+// Return acosh(x) = sqrt(x-1) * Pol4(x), where Pol4(x) =
+// (((x*C4 + C3)*(x-1) + C2)*(x-1) + C1)*(x-1) + C0
+
+// 3. 1.000499725341796875(0x3FF0020C00000000) <= x < 2^63
+// Return acosh(x) = log(x + sqrt(x^2 -1.0))
+// To compute x + sqrt(x^2 -1.0) modified Newton Raphson method is used
+// (3 iterations)
+// Algorithm description for log function see below.
+//
+// 4. 2^63 <= x < +INF
+// Return acosh(x) = log(2*x)
+// Algorithm description for log function see below.
+//
+// 5. x = +INF
+// Return acosh(x) = +INF
+//
+// 6. x = [S,Q]NaN
+// Return acosh(x) = QNaN
+//
+// 7. x < 1.0
+// It's domain error. Error handler with tag = 136 is called
+//
+//==============================================================
+// Algorithm Description for log(x) function
+// Below we are using the fact that inequality x - 1.0 > 2^(-6) is always
+// true for this acosh implementation
+//
+// Consider x = 2^N 1.f1 f2 f3 f4...f63
+// Log(x) = log(frcpa(x) x/frcpa(x))
+// = log(1/frcpa(x)) + log(frcpa(x) x)
+// = -log(frcpa(x)) + log(frcpa(x) x)
+//
+// frcpa(x) = 2^-N frcpa((1.f1 f2 ... f63)
+//
+// -log(frcpa(x)) = -log(C)
+// = -log(2^-N) - log(frcpa(1.f1 f2 ... f63))
+//
+// -log(frcpa(x)) = -log(C)
+// = +Nlog2 - log(frcpa(1.f1 f2 ... f63))
+//
+// -log(frcpa(x)) = -log(C)
+// = +Nlog2 + log(frcpa(1.f1 f2 ... f63))
+//
+// Log(x) = log(1/frcpa(x)) + log(frcpa(x) x)
+//
+// Log(x) = +Nlog2 + log(1./frcpa(1.f1 f2 ... f63)) + log(frcpa(x) x)
+// Log(x) = +Nlog2 - log(/frcpa(1.f1 f2 ... f63)) + log(frcpa(x) x)
+// Log(x) = +Nlog2 + T + log(frcpa(x) x)
+//
+// Log(x) = +Nlog2 + T + log(C x)
+//
+// Cx = 1 + r
+//
+// Log(x) = +Nlog2 + T + log(1+r)
+// Log(x) = +Nlog2 + T + Series( r - r^2/2 + r^3/3 - r^4/4 ....)
+//
+// 1.f1 f2 ... f8 has 256 entries.
+// They are 1 + k/2^8, k = 0 ... 255
+// These 256 values are the table entries.
+//
+// Implementation
+//==============================================================
+// C = frcpa(x)
+// r = C * x - 1
+//
+// Form rseries = r + P1*r^2 + P2*r^3 + P3*r^4 + P4*r^5 + P5*r^6
+//
+// x = f * 2*n where f is 1.f_1f_2f_3....f_63
+// Nfloat = float(n) where n is the true unbiased exponent
+// pre-index = f_1f_2....f_8
+// index = pre_index * 16
+// get the dxt table entry at index + offset = T
+//
+// result = (T + Nfloat * log(2)) + rseries
+//
+// The T table is calculated as follows
+// Form x_k = 1 + k/2^8 where k goes from 0... 255
+// y_k = frcpa(x_k)
+// log(1/y_k) in quad and round to double-extended
+//
+
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f9 -> f15, f32 -> f65
+
+// General registers used:
+// r14 -> r27, r32 -> r39
+
+// Predicate registers used:
+// p6 -> p15
+
+// p6 to filter out case when x = [Q,S]NaN
+// p7,p8 to filter out case when x < 1.0
+// p10 to select path #1
+// p11 to filter out case when x = +INF
+// p12 used in the frcpa
+// p13 to select path #4
+// p14,p15 to select path #2
+
+// Assembly macros
+//==============================================================
+log_GR_exp_17_ones = r14
+log_GR_signexp_f8 = r15
+log_table_address2 = r16
+log_GR_exp_16_ones = r17
+log_GR_exp_f8 = r18
+log_GR_true_exp_f8 = r19
+log_GR_significand_f8 = r20
+log_GR_index = r21
+log_GR_comp2 = r22
+acosh_GR_f8 = r23
+log_GR_comp = r24
+acosh_GR_f8_sig = r25
+log_table_address3 = r26
+NR_table_address = r27
+
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_SAVE_PFS = r35
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+acosh_GR_tag = r39
+
+//==============================================================
+log_y = f9
+NR1 = f10
+NR2 = f11
+log_y_rs = f12
+log_y_rs_iter = f13
+log_y_rs_iter1 = f14
+log_NORM_f8 = f15
+acosh_comp = f32
+log_w = f34
+log_P5 = f35
+log_P4 = f36
+log_P3 = f37
+log_P2 = f38
+log_P1 = f39
+log_C0 = f40
+log_C1 = f41
+log_C2 = f42
+log2 = f43
+acosh_w_rs = f44
+log_C = f45
+log_arg = f46
+acosh_w_iter1 = f47
+acosh_w_iter2 = f48
+log_int_Nfloat = f49
+log_r = f50
+log_rsq = f51
+log_rp_p4 = f52
+log_rp_p32 = f53
+log_rcube = f54
+log_rp_p10 = f55
+log_rp_p2 = f56
+log_Nfloat = f57
+log_T = f58
+log_r2P_r = f59
+log_T_plus_Nlog2 = f60
+acosh_w_sqrt = f61
+acosh_w_1 = f62
+log_C3 = f63
+log_C4 = f64
+log_arg_early = f65
+
+
+// Data tables
+//==============================================================
+
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(log_table_1)
+data8 0x3FF0020C49BA5E35 // 1.0005
+data8 0xBFC5555DA7212371 // P5
+data8 0x3FC999A19EEF5826 // P4
+data8 0xBFCFFFFFFFFEF009 // P3
+data8 0x3FD555555554ECB2 // P2
+data8 0xBFE0000000000000 // P1 = -0.5
+//
+data8 0xb17217f7d1cf79ac, 0x00003ffe // log2
+LOCAL_OBJECT_END(log_table_1)
+
+LOCAL_OBJECT_START(log_table_2)
+data8 0x3FE0000000000000 // 0.5
+data8 0x4008000000000000 // 3.0
+//
+data8 0xAFE8F9203939CCF8, 0x00003FF6 // C4 3FF6AFE8F9203939CCF8
+data8 0xAD46EB6AE752D809, 0x0000BFF8 // C3 BFF8AD46EB6AE752D809
+data8 0xD93923D7F53F3627, 0x00003FF9 // C2 3FF9D93923D7F53F3627
+data8 0xF15BEEEFF7D32D36, 0x0000BFFB // C1 BFFBF15BEEEFF7D32D36
+data8 0xB504F333F9DE6484, 0x00003FFF // C0 3FFFB504F333F9DE6484
+LOCAL_OBJECT_END(log_table_2)
+
+
+LOCAL_OBJECT_START(log_table_3)
+data8 0x80200aaeac44ef38 , 0x00003ff6 // log(1/frcpa(1+ 0/2^-8))
+//
+data8 0xc09090a2c35aa070 , 0x00003ff7 // log(1/frcpa(1+ 1/2^-8))
+data8 0xa0c94fcb41977c75 , 0x00003ff8 // log(1/frcpa(1+ 2/2^-8))
+data8 0xe18b9c263af83301 , 0x00003ff8 // log(1/frcpa(1+ 3/2^-8))
+data8 0x8d35c8d6399c30ea , 0x00003ff9 // log(1/frcpa(1+ 4/2^-8))
+data8 0xadd4d2ecd601cbb8 , 0x00003ff9 // log(1/frcpa(1+ 5/2^-8))
+//
+data8 0xce95403a192f9f01 , 0x00003ff9 // log(1/frcpa(1+ 6/2^-8))
+data8 0xeb59392cbcc01096 , 0x00003ff9 // log(1/frcpa(1+ 7/2^-8))
+data8 0x862c7d0cefd54c5d , 0x00003ffa // log(1/frcpa(1+ 8/2^-8))
+data8 0x94aa63c65e70d499 , 0x00003ffa // log(1/frcpa(1+ 9/2^-8))
+data8 0xa54a696d4b62b382 , 0x00003ffa // log(1/frcpa(1+ 10/2^-8))
+//
+data8 0xb3e4a796a5dac208 , 0x00003ffa // log(1/frcpa(1+ 11/2^-8))
+data8 0xc28c45b1878340a9 , 0x00003ffa // log(1/frcpa(1+ 12/2^-8))
+data8 0xd35c55f39d7a6235 , 0x00003ffa // log(1/frcpa(1+ 13/2^-8))
+data8 0xe220f037b954f1f5 , 0x00003ffa // log(1/frcpa(1+ 14/2^-8))
+data8 0xf0f3389b036834f3 , 0x00003ffa // log(1/frcpa(1+ 15/2^-8))
+//
+data8 0xffd3488d5c980465 , 0x00003ffa // log(1/frcpa(1+ 16/2^-8))
+data8 0x87609ce2ed300490 , 0x00003ffb // log(1/frcpa(1+ 17/2^-8))
+data8 0x8ede9321e8c85927 , 0x00003ffb // log(1/frcpa(1+ 18/2^-8))
+data8 0x96639427f2f8e2f4 , 0x00003ffb // log(1/frcpa(1+ 19/2^-8))
+data8 0x9defad3e8f73217b , 0x00003ffb // log(1/frcpa(1+ 20/2^-8))
+//
+data8 0xa582ebd50097029c , 0x00003ffb // log(1/frcpa(1+ 21/2^-8))
+data8 0xac06dbe75ab80fee , 0x00003ffb // log(1/frcpa(1+ 22/2^-8))
+data8 0xb3a78449b2d3ccca , 0x00003ffb // log(1/frcpa(1+ 23/2^-8))
+data8 0xbb4f79635ab46bb2 , 0x00003ffb // log(1/frcpa(1+ 24/2^-8))
+data8 0xc2fec93a83523f3f , 0x00003ffb // log(1/frcpa(1+ 25/2^-8))
+//
+data8 0xc99af2eaca4c4571 , 0x00003ffb // log(1/frcpa(1+ 26/2^-8))
+data8 0xd1581106472fa653 , 0x00003ffb // log(1/frcpa(1+ 27/2^-8))
+data8 0xd8002560d4355f2e , 0x00003ffb // log(1/frcpa(1+ 28/2^-8))
+data8 0xdfcb43b4fe508632 , 0x00003ffb // log(1/frcpa(1+ 29/2^-8))
+data8 0xe67f6dff709d4119 , 0x00003ffb // log(1/frcpa(1+ 30/2^-8))
+//
+data8 0xed393b1c22351280 , 0x00003ffb // log(1/frcpa(1+ 31/2^-8))
+data8 0xf5192bff087bcc35 , 0x00003ffb // log(1/frcpa(1+ 32/2^-8))
+data8 0xfbdf4ff6dfef2fa3 , 0x00003ffb // log(1/frcpa(1+ 33/2^-8))
+data8 0x81559a97f92f9cc7 , 0x00003ffc // log(1/frcpa(1+ 34/2^-8))
+data8 0x84be72bce90266e8 , 0x00003ffc // log(1/frcpa(1+ 35/2^-8))
+//
+data8 0x88bc74113f23def2 , 0x00003ffc // log(1/frcpa(1+ 36/2^-8))
+data8 0x8c2ba3edf6799d11 , 0x00003ffc // log(1/frcpa(1+ 37/2^-8))
+data8 0x8f9dc92f92ea08b1 , 0x00003ffc // log(1/frcpa(1+ 38/2^-8))
+data8 0x9312e8f36efab5a7 , 0x00003ffc // log(1/frcpa(1+ 39/2^-8))
+data8 0x968b08643409ceb6 , 0x00003ffc // log(1/frcpa(1+ 40/2^-8))
+//
+data8 0x9a062cba08a1708c , 0x00003ffc // log(1/frcpa(1+ 41/2^-8))
+data8 0x9d845b3abf95485c , 0x00003ffc // log(1/frcpa(1+ 42/2^-8))
+data8 0xa06fd841bc001bb4 , 0x00003ffc // log(1/frcpa(1+ 43/2^-8))
+data8 0xa3f3a74652fbe0db , 0x00003ffc // log(1/frcpa(1+ 44/2^-8))
+data8 0xa77a8fb2336f20f5 , 0x00003ffc // log(1/frcpa(1+ 45/2^-8))
+//
+data8 0xab0497015d28b0a0 , 0x00003ffc // log(1/frcpa(1+ 46/2^-8))
+data8 0xae91c2be6ba6a615 , 0x00003ffc // log(1/frcpa(1+ 47/2^-8))
+data8 0xb189d1b99aebb20b , 0x00003ffc // log(1/frcpa(1+ 48/2^-8))
+data8 0xb51cced5de9c1b2c , 0x00003ffc // log(1/frcpa(1+ 49/2^-8))
+data8 0xb819bee9e720d42f , 0x00003ffc // log(1/frcpa(1+ 50/2^-8))
+//
+data8 0xbbb2a0947b093a5d , 0x00003ffc // log(1/frcpa(1+ 51/2^-8))
+data8 0xbf4ec1505811684a , 0x00003ffc // log(1/frcpa(1+ 52/2^-8))
+data8 0xc2535bacfa8975ff , 0x00003ffc // log(1/frcpa(1+ 53/2^-8))
+data8 0xc55a3eafad187eb8 , 0x00003ffc // log(1/frcpa(1+ 54/2^-8))
+data8 0xc8ff2484b2c0da74 , 0x00003ffc // log(1/frcpa(1+ 55/2^-8))
+//
+data8 0xcc0b1a008d53ab76 , 0x00003ffc // log(1/frcpa(1+ 56/2^-8))
+data8 0xcfb6203844b3209b , 0x00003ffc // log(1/frcpa(1+ 57/2^-8))
+data8 0xd2c73949a47a19f5 , 0x00003ffc // log(1/frcpa(1+ 58/2^-8))
+data8 0xd5daae18b49d6695 , 0x00003ffc // log(1/frcpa(1+ 59/2^-8))
+data8 0xd8f08248cf7e8019 , 0x00003ffc // log(1/frcpa(1+ 60/2^-8))
+//
+data8 0xdca7749f1b3e540e , 0x00003ffc // log(1/frcpa(1+ 61/2^-8))
+data8 0xdfc28e033aaaf7c7 , 0x00003ffc // log(1/frcpa(1+ 62/2^-8))
+data8 0xe2e012a5f91d2f55 , 0x00003ffc // log(1/frcpa(1+ 63/2^-8))
+data8 0xe600064ed9e292a8 , 0x00003ffc // log(1/frcpa(1+ 64/2^-8))
+data8 0xe9226cce42b39f60 , 0x00003ffc // log(1/frcpa(1+ 65/2^-8))
+//
+data8 0xec4749fd97a28360 , 0x00003ffc // log(1/frcpa(1+ 66/2^-8))
+data8 0xef6ea1bf57780495 , 0x00003ffc // log(1/frcpa(1+ 67/2^-8))
+data8 0xf29877ff38809091 , 0x00003ffc // log(1/frcpa(1+ 68/2^-8))
+data8 0xf5c4d0b245cb89be , 0x00003ffc // log(1/frcpa(1+ 69/2^-8))
+data8 0xf8f3afd6fcdef3aa , 0x00003ffc // log(1/frcpa(1+ 70/2^-8))
+//
+data8 0xfc2519756be1abc7 , 0x00003ffc // log(1/frcpa(1+ 71/2^-8))
+data8 0xff59119f503e6832 , 0x00003ffc // log(1/frcpa(1+ 72/2^-8))
+data8 0x8147ce381ae0e146 , 0x00003ffd // log(1/frcpa(1+ 73/2^-8))
+data8 0x82e45f06cb1ad0f2 , 0x00003ffd // log(1/frcpa(1+ 74/2^-8))
+data8 0x842f5c7c573cbaa2 , 0x00003ffd // log(1/frcpa(1+ 75/2^-8))
+//
+data8 0x85ce471968c8893a , 0x00003ffd // log(1/frcpa(1+ 76/2^-8))
+data8 0x876e8305bc04066d , 0x00003ffd // log(1/frcpa(1+ 77/2^-8))
+data8 0x891012678031fbb3 , 0x00003ffd // log(1/frcpa(1+ 78/2^-8))
+data8 0x8a5f1493d766a05f , 0x00003ffd // log(1/frcpa(1+ 79/2^-8))
+data8 0x8c030c778c56fa00 , 0x00003ffd // log(1/frcpa(1+ 80/2^-8))
+//
+data8 0x8da85df17e31d9ae , 0x00003ffd // log(1/frcpa(1+ 81/2^-8))
+data8 0x8efa663e7921687e , 0x00003ffd // log(1/frcpa(1+ 82/2^-8))
+data8 0x90a22b6875c6a1f8 , 0x00003ffd // log(1/frcpa(1+ 83/2^-8))
+data8 0x91f62cc8f5d24837 , 0x00003ffd // log(1/frcpa(1+ 84/2^-8))
+data8 0x93a06cfc3857d980 , 0x00003ffd // log(1/frcpa(1+ 85/2^-8))
+//
+data8 0x94f66d5e6fd01ced , 0x00003ffd // log(1/frcpa(1+ 86/2^-8))
+data8 0x96a330156e6772f2 , 0x00003ffd // log(1/frcpa(1+ 87/2^-8))
+data8 0x97fb3582754ea25b , 0x00003ffd // log(1/frcpa(1+ 88/2^-8))
+data8 0x99aa8259aad1bbf2 , 0x00003ffd // log(1/frcpa(1+ 89/2^-8))
+data8 0x9b0492f6227ae4a8 , 0x00003ffd // log(1/frcpa(1+ 90/2^-8))
+//
+data8 0x9c5f8e199bf3a7a5 , 0x00003ffd // log(1/frcpa(1+ 91/2^-8))
+data8 0x9e1293b9998c1daa , 0x00003ffd // log(1/frcpa(1+ 92/2^-8))
+data8 0x9f6fa31e0b41f308 , 0x00003ffd // log(1/frcpa(1+ 93/2^-8))
+data8 0xa0cda11eaf46390e , 0x00003ffd // log(1/frcpa(1+ 94/2^-8))
+data8 0xa22c8f029cfa45aa , 0x00003ffd // log(1/frcpa(1+ 95/2^-8))
+//
+data8 0xa3e48badb7856b34 , 0x00003ffd // log(1/frcpa(1+ 96/2^-8))
+data8 0xa5459a0aa95849f9 , 0x00003ffd // log(1/frcpa(1+ 97/2^-8))
+data8 0xa6a79c84480cfebd , 0x00003ffd // log(1/frcpa(1+ 98/2^-8))
+data8 0xa80a946d0fcb3eb2 , 0x00003ffd // log(1/frcpa(1+ 99/2^-8))
+data8 0xa96e831a3ea7b314 , 0x00003ffd // log(1/frcpa(1+100/2^-8))
+//
+data8 0xaad369e3dc544e3b , 0x00003ffd // log(1/frcpa(1+101/2^-8))
+data8 0xac92e9588952c815 , 0x00003ffd // log(1/frcpa(1+102/2^-8))
+data8 0xadfa035aa1ed8fdc , 0x00003ffd // log(1/frcpa(1+103/2^-8))
+data8 0xaf6219eae1ad6e34 , 0x00003ffd // log(1/frcpa(1+104/2^-8))
+data8 0xb0cb2e6d8160f753 , 0x00003ffd // log(1/frcpa(1+105/2^-8))
+//
+data8 0xb2354249ad950f72 , 0x00003ffd // log(1/frcpa(1+106/2^-8))
+data8 0xb3a056e98ef4a3b4 , 0x00003ffd // log(1/frcpa(1+107/2^-8))
+data8 0xb50c6dba52c6292a , 0x00003ffd // log(1/frcpa(1+108/2^-8))
+data8 0xb679882c33876165 , 0x00003ffd // log(1/frcpa(1+109/2^-8))
+data8 0xb78c07429785cedc , 0x00003ffd // log(1/frcpa(1+110/2^-8))
+//
+data8 0xb8faeb8dc4a77d24 , 0x00003ffd // log(1/frcpa(1+111/2^-8))
+data8 0xba6ad77eb36ae0d6 , 0x00003ffd // log(1/frcpa(1+112/2^-8))
+data8 0xbbdbcc915e9bee50 , 0x00003ffd // log(1/frcpa(1+113/2^-8))
+data8 0xbd4dcc44f8cf12ef , 0x00003ffd // log(1/frcpa(1+114/2^-8))
+data8 0xbec0d81bf5b531fa , 0x00003ffd // log(1/frcpa(1+115/2^-8))
+//
+data8 0xc034f19c139186f4 , 0x00003ffd // log(1/frcpa(1+116/2^-8))
+data8 0xc14cb69f7c5e55ab , 0x00003ffd // log(1/frcpa(1+117/2^-8))
+data8 0xc2c2abbb6e5fd56f , 0x00003ffd // log(1/frcpa(1+118/2^-8))
+data8 0xc439b2c193e6771e , 0x00003ffd // log(1/frcpa(1+119/2^-8))
+data8 0xc553acb9d5c67733 , 0x00003ffd // log(1/frcpa(1+120/2^-8))
+//
+data8 0xc6cc96e441272441 , 0x00003ffd // log(1/frcpa(1+121/2^-8))
+data8 0xc8469753eca88c30 , 0x00003ffd // log(1/frcpa(1+122/2^-8))
+data8 0xc962cf3ce072b05c , 0x00003ffd // log(1/frcpa(1+123/2^-8))
+data8 0xcadeba8771f694aa , 0x00003ffd // log(1/frcpa(1+124/2^-8))
+data8 0xcc5bc08d1f72da94 , 0x00003ffd // log(1/frcpa(1+125/2^-8))
+//
+data8 0xcd7a3f99ea035c29 , 0x00003ffd // log(1/frcpa(1+126/2^-8))
+data8 0xcef93860c8a53c35 , 0x00003ffd // log(1/frcpa(1+127/2^-8))
+data8 0xd0192f68a7ed23df , 0x00003ffd // log(1/frcpa(1+128/2^-8))
+data8 0xd19a201127d3c645 , 0x00003ffd // log(1/frcpa(1+129/2^-8))
+data8 0xd2bb92f4061c172c , 0x00003ffd // log(1/frcpa(1+130/2^-8))
+//
+data8 0xd43e80b2ee8cc8fc , 0x00003ffd // log(1/frcpa(1+131/2^-8))
+data8 0xd56173601fc4ade4 , 0x00003ffd // log(1/frcpa(1+132/2^-8))
+data8 0xd6e6637efb54086f , 0x00003ffd // log(1/frcpa(1+133/2^-8))
+data8 0xd80ad9f58f3c8193 , 0x00003ffd // log(1/frcpa(1+134/2^-8))
+data8 0xd991d1d31aca41f8 , 0x00003ffd // log(1/frcpa(1+135/2^-8))
+//
+data8 0xdab7d02231484a93 , 0x00003ffd // log(1/frcpa(1+136/2^-8))
+data8 0xdc40d532cde49a54 , 0x00003ffd // log(1/frcpa(1+137/2^-8))
+data8 0xdd685f79ed8b265e , 0x00003ffd // log(1/frcpa(1+138/2^-8))
+data8 0xde9094bbc0e17b1d , 0x00003ffd // log(1/frcpa(1+139/2^-8))
+data8 0xe01c91b78440c425 , 0x00003ffd // log(1/frcpa(1+140/2^-8))
+//
+data8 0xe14658f26997e729 , 0x00003ffd // log(1/frcpa(1+141/2^-8))
+data8 0xe270cdc2391e0d23 , 0x00003ffd // log(1/frcpa(1+142/2^-8))
+data8 0xe3ffce3a2aa64922 , 0x00003ffd // log(1/frcpa(1+143/2^-8))
+data8 0xe52bdb274ed82887 , 0x00003ffd // log(1/frcpa(1+144/2^-8))
+data8 0xe6589852e75d7df6 , 0x00003ffd // log(1/frcpa(1+145/2^-8))
+//
+data8 0xe786068c79937a7d , 0x00003ffd // log(1/frcpa(1+146/2^-8))
+data8 0xe91903adad100911 , 0x00003ffd // log(1/frcpa(1+147/2^-8))
+data8 0xea481236f7d35bb0 , 0x00003ffd // log(1/frcpa(1+148/2^-8))
+data8 0xeb77d48c692e6b14 , 0x00003ffd // log(1/frcpa(1+149/2^-8))
+data8 0xeca84b83d7297b87 , 0x00003ffd // log(1/frcpa(1+150/2^-8))
+//
+data8 0xedd977f4962aa158 , 0x00003ffd // log(1/frcpa(1+151/2^-8))
+data8 0xef7179a22f257754 , 0x00003ffd // log(1/frcpa(1+152/2^-8))
+data8 0xf0a450d139366ca7 , 0x00003ffd // log(1/frcpa(1+153/2^-8))
+data8 0xf1d7e0524ff9ffdb , 0x00003ffd // log(1/frcpa(1+154/2^-8))
+data8 0xf30c29036a8b6cae , 0x00003ffd // log(1/frcpa(1+155/2^-8))
+//
+data8 0xf4412bc411ea8d92 , 0x00003ffd // log(1/frcpa(1+156/2^-8))
+data8 0xf576e97564c8619d , 0x00003ffd // log(1/frcpa(1+157/2^-8))
+data8 0xf6ad62fa1b5f172f , 0x00003ffd // log(1/frcpa(1+158/2^-8))
+data8 0xf7e499368b55c542 , 0x00003ffd // log(1/frcpa(1+159/2^-8))
+data8 0xf91c8d10abaffe22 , 0x00003ffd // log(1/frcpa(1+160/2^-8))
+//
+data8 0xfa553f7018c966f3 , 0x00003ffd // log(1/frcpa(1+161/2^-8))
+data8 0xfb8eb13e185d802c , 0x00003ffd // log(1/frcpa(1+162/2^-8))
+data8 0xfcc8e3659d9bcbed , 0x00003ffd // log(1/frcpa(1+163/2^-8))
+data8 0xfe03d6d34d487fd2 , 0x00003ffd // log(1/frcpa(1+164/2^-8))
+data8 0xff3f8c7581e9f0ae , 0x00003ffd // log(1/frcpa(1+165/2^-8))
+//
+data8 0x803e029e280173ae , 0x00003ffe // log(1/frcpa(1+166/2^-8))
+data8 0x80dca10cc52d0757 , 0x00003ffe // log(1/frcpa(1+167/2^-8))
+data8 0x817ba200632755a1 , 0x00003ffe // log(1/frcpa(1+168/2^-8))
+data8 0x821b05f3b01d6774 , 0x00003ffe // log(1/frcpa(1+169/2^-8))
+data8 0x82bacd623ff19d06 , 0x00003ffe // log(1/frcpa(1+170/2^-8))
+//
+data8 0x835af8c88e7a8f47 , 0x00003ffe // log(1/frcpa(1+171/2^-8))
+data8 0x83c5f8299e2b4091 , 0x00003ffe // log(1/frcpa(1+172/2^-8))
+data8 0x8466cb43f3d87300 , 0x00003ffe // log(1/frcpa(1+173/2^-8))
+data8 0x850803a67c80ca4b , 0x00003ffe // log(1/frcpa(1+174/2^-8))
+data8 0x85a9a1d11a23b461 , 0x00003ffe // log(1/frcpa(1+175/2^-8))
+//
+data8 0x864ba644a18e6e05 , 0x00003ffe // log(1/frcpa(1+176/2^-8))
+data8 0x86ee1182dcc432f7 , 0x00003ffe // log(1/frcpa(1+177/2^-8))
+data8 0x875a925d7e48c316 , 0x00003ffe // log(1/frcpa(1+178/2^-8))
+data8 0x87fdaa109d23aef7 , 0x00003ffe // log(1/frcpa(1+179/2^-8))
+data8 0x88a129ed4becfaf2 , 0x00003ffe // log(1/frcpa(1+180/2^-8))
+//
+data8 0x89451278ecd7f9cf , 0x00003ffe // log(1/frcpa(1+181/2^-8))
+data8 0x89b29295f8432617 , 0x00003ffe // log(1/frcpa(1+182/2^-8))
+data8 0x8a572ac5a5496882 , 0x00003ffe // log(1/frcpa(1+183/2^-8))
+data8 0x8afc2d0ce3b2dadf , 0x00003ffe // log(1/frcpa(1+184/2^-8))
+data8 0x8b6a69c608cfd3af , 0x00003ffe // log(1/frcpa(1+185/2^-8))
+//
+data8 0x8c101e106e899a83 , 0x00003ffe // log(1/frcpa(1+186/2^-8))
+data8 0x8cb63de258f9d626 , 0x00003ffe // log(1/frcpa(1+187/2^-8))
+data8 0x8d2539c5bd19e2b1 , 0x00003ffe // log(1/frcpa(1+188/2^-8))
+data8 0x8dcc0e064b29e6f1 , 0x00003ffe // log(1/frcpa(1+189/2^-8))
+data8 0x8e734f45d88357ae , 0x00003ffe // log(1/frcpa(1+190/2^-8))
+//
+data8 0x8ee30cef034a20db , 0x00003ffe // log(1/frcpa(1+191/2^-8))
+data8 0x8f8b0515686d1d06 , 0x00003ffe // log(1/frcpa(1+192/2^-8))
+data8 0x90336bba039bf32f , 0x00003ffe // log(1/frcpa(1+193/2^-8))
+data8 0x90a3edd23d1c9d58 , 0x00003ffe // log(1/frcpa(1+194/2^-8))
+data8 0x914d0de2f5d61b32 , 0x00003ffe // log(1/frcpa(1+195/2^-8))
+//
+data8 0x91be0c20d28173b5 , 0x00003ffe // log(1/frcpa(1+196/2^-8))
+data8 0x9267e737c06cd34a , 0x00003ffe // log(1/frcpa(1+197/2^-8))
+data8 0x92d962ae6abb1237 , 0x00003ffe // log(1/frcpa(1+198/2^-8))
+data8 0x9383fa6afbe2074c , 0x00003ffe // log(1/frcpa(1+199/2^-8))
+data8 0x942f0421651c1c4e , 0x00003ffe // log(1/frcpa(1+200/2^-8))
+//
+data8 0x94a14a3845bb985e , 0x00003ffe // log(1/frcpa(1+201/2^-8))
+data8 0x954d133857f861e7 , 0x00003ffe // log(1/frcpa(1+202/2^-8))
+data8 0x95bfd96468e604c4 , 0x00003ffe // log(1/frcpa(1+203/2^-8))
+data8 0x9632d31cafafa858 , 0x00003ffe // log(1/frcpa(1+204/2^-8))
+data8 0x96dfaabd86fa1647 , 0x00003ffe // log(1/frcpa(1+205/2^-8))
+//
+data8 0x9753261fcbb2a594 , 0x00003ffe // log(1/frcpa(1+206/2^-8))
+data8 0x9800c11b426b996d , 0x00003ffe // log(1/frcpa(1+207/2^-8))
+data8 0x9874bf4d45ae663c , 0x00003ffe // log(1/frcpa(1+208/2^-8))
+data8 0x99231f5ee9a74f79 , 0x00003ffe // log(1/frcpa(1+209/2^-8))
+data8 0x9997a18a56bcad28 , 0x00003ffe // log(1/frcpa(1+210/2^-8))
+//
+data8 0x9a46c873a3267e79 , 0x00003ffe // log(1/frcpa(1+211/2^-8))
+data8 0x9abbcfc621eb6cb6 , 0x00003ffe // log(1/frcpa(1+212/2^-8))
+data8 0x9b310cb0d354c990 , 0x00003ffe // log(1/frcpa(1+213/2^-8))
+data8 0x9be14cf9e1b3515c , 0x00003ffe // log(1/frcpa(1+214/2^-8))
+data8 0x9c5710b8cbb73a43 , 0x00003ffe // log(1/frcpa(1+215/2^-8))
+//
+data8 0x9ccd0abd301f399c , 0x00003ffe // log(1/frcpa(1+216/2^-8))
+data8 0x9d7e67f3bdce8888 , 0x00003ffe // log(1/frcpa(1+217/2^-8))
+data8 0x9df4ea81a99daa01 , 0x00003ffe // log(1/frcpa(1+218/2^-8))
+data8 0x9e6ba405a54514ba , 0x00003ffe // log(1/frcpa(1+219/2^-8))
+data8 0x9f1e21c8c7bb62b3 , 0x00003ffe // log(1/frcpa(1+220/2^-8))
+//
+data8 0x9f956593f6b6355c , 0x00003ffe // log(1/frcpa(1+221/2^-8))
+data8 0xa00ce1092e5498c3 , 0x00003ffe // log(1/frcpa(1+222/2^-8))
+data8 0xa0c08309c4b912c1 , 0x00003ffe // log(1/frcpa(1+223/2^-8))
+data8 0xa1388a8c6faa2afa , 0x00003ffe // log(1/frcpa(1+224/2^-8))
+data8 0xa1b0ca7095b5f985 , 0x00003ffe // log(1/frcpa(1+225/2^-8))
+//
+data8 0xa22942eb47534a00 , 0x00003ffe // log(1/frcpa(1+226/2^-8))
+data8 0xa2de62326449d0a3 , 0x00003ffe // log(1/frcpa(1+227/2^-8))
+data8 0xa357690f88bfe345 , 0x00003ffe // log(1/frcpa(1+228/2^-8))
+data8 0xa3d0a93f45169a4b , 0x00003ffe // log(1/frcpa(1+229/2^-8))
+data8 0xa44a22f7ffe65f30 , 0x00003ffe // log(1/frcpa(1+230/2^-8))
+//
+data8 0xa500c5e5b4c1aa36 , 0x00003ffe // log(1/frcpa(1+231/2^-8))
+data8 0xa57ad064eb2ebbc2 , 0x00003ffe // log(1/frcpa(1+232/2^-8))
+data8 0xa5f5152dedf4384e , 0x00003ffe // log(1/frcpa(1+233/2^-8))
+data8 0xa66f9478856233ec , 0x00003ffe // log(1/frcpa(1+234/2^-8))
+data8 0xa6ea4e7cca02c32e , 0x00003ffe // log(1/frcpa(1+235/2^-8))
+//
+data8 0xa765437325341ccf , 0x00003ffe // log(1/frcpa(1+236/2^-8))
+data8 0xa81e21e6c75b4020 , 0x00003ffe // log(1/frcpa(1+237/2^-8))
+data8 0xa899ab333fe2b9ca , 0x00003ffe // log(1/frcpa(1+238/2^-8))
+data8 0xa9157039c51ebe71 , 0x00003ffe // log(1/frcpa(1+239/2^-8))
+data8 0xa991713433c2b999 , 0x00003ffe // log(1/frcpa(1+240/2^-8))
+//
+data8 0xaa0dae5cbcc048b3 , 0x00003ffe // log(1/frcpa(1+241/2^-8))
+data8 0xaa8a27ede5eb13ad , 0x00003ffe // log(1/frcpa(1+242/2^-8))
+data8 0xab06de228a9e3499 , 0x00003ffe // log(1/frcpa(1+243/2^-8))
+data8 0xab83d135dc633301 , 0x00003ffe // log(1/frcpa(1+244/2^-8))
+data8 0xac3fb076adc7fe7a , 0x00003ffe // log(1/frcpa(1+245/2^-8))
+//
+data8 0xacbd3cbbe47988f1 , 0x00003ffe // log(1/frcpa(1+246/2^-8))
+data8 0xad3b06b1a5dc57c3 , 0x00003ffe // log(1/frcpa(1+247/2^-8))
+data8 0xadb90e94af887717 , 0x00003ffe // log(1/frcpa(1+248/2^-8))
+data8 0xae3754a218f7c816 , 0x00003ffe // log(1/frcpa(1+249/2^-8))
+data8 0xaeb5d9175437afa2 , 0x00003ffe // log(1/frcpa(1+250/2^-8))
+//
+data8 0xaf349c322e9c7cee , 0x00003ffe // log(1/frcpa(1+251/2^-8))
+data8 0xafb39e30d1768d1c , 0x00003ffe // log(1/frcpa(1+252/2^-8))
+data8 0xb032df51c2c93116 , 0x00003ffe // log(1/frcpa(1+253/2^-8))
+data8 0xb0b25fd3e6035ad9 , 0x00003ffe // log(1/frcpa(1+254/2^-8))
+data8 0xb1321ff67cba178c , 0x00003ffe // log(1/frcpa(1+255/2^-8))
+LOCAL_OBJECT_END(log_table_3)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(acosh)
+
+{ .mfi
+ getf.exp acosh_GR_f8 = f8
+ fclass.m p6,p0 = f8, 0xc3 // Test for x = NaN
+ mov log_GR_comp2 = 0x1003e
+}
+{ .mfi
+ addl NR_table_address = @ltoff(log_table_1), gp
+ fms.s1 log_y = f8, f8, f1 // y = x^2-1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.sig acosh_GR_f8_sig = f8
+ fclass.m p11,p0 = f8, 0x21 // Test for x=+inf
+ mov log_GR_exp_17_ones = 0x1ffff
+}
+{ .mfi
+ ld8 NR_table_address = [NR_table_address]
+ fms.s1 log_w = f8,f1,f1 // w = x - 1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.lt.s1 p7,p8 = f8, f1 // Test for x<1.0
+ addl log_GR_comp = 0x10020C,r0 // Upper 21 bits of signif of 1.0005
+}
+{ .mfb
+ mov log_GR_exp_16_ones = 0xffff //BIAS
+(p6) fma.d.s0 f8 = f8,f1,f0 // quietize nan result if x=nan
+(p6) br.ret.spnt b0 // Exit for x=nan
+}
+;;
+
+{ .mfb
+ //get second table address
+ adds log_table_address2 = 0x40, NR_table_address
+ fcmp.eq.s1 p10,p0 = f8, f1 // Test for x=+1.0
+(p11) br.ret.spnt b0 // Exit for x=+inf
+}
+;;
+
+{ .mfi
+ ldfpd NR1,NR2 = [log_table_address2],16
+ frsqrta.s1 log_y_rs,p0 = log_y // z=1/sqrt(y)
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s1 log_arg = f8,f1,f8
+(p7) br.cond.spnt ACOSH_LESS_ONE // Branch if path 7, x < 1.0
+}
+;;
+
+{ .mfi
+ ldfe log_C4 = [log_table_address2],16
+(p8) fcmp.eq.s0 p6,p0 = f8, f0 // Dummy op sets denorm flag if unorm>=1.0
+ nop.i 0
+}
+{ .mfb
+(p8) cmp.le.unc p13,p0 = log_GR_comp2,acosh_GR_f8
+ nop.f 0
+(p13) br.cond.spnt LOG_COMMON1 // Branch if path 4, x >= 2^63
+}
+;;
+
+{ .mfi
+ ldfe log_C3 = [log_table_address2],16
+(p10) fmerge.s f8 = f0, f0 // Return 0 if x=1.0
+ shr.u acosh_GR_f8_sig = acosh_GR_f8_sig,43
+}
+{ .mib
+ cmp.eq p14,p0 = log_GR_exp_16_ones,acosh_GR_f8
+ nop.i 0
+(p10) br.ret.spnt b0 // Exit for x=1.0
+}
+;;
+
+{ .mfi
+ ldfe log_C2 = [log_table_address2],16
+ frsqrta.s1 acosh_w_rs,p0 = log_w // t=1/sqrt(w)
+ nop.i 0
+}
+{ .mfb
+(p14) cmp.lt.unc p15,p0 = acosh_GR_f8_sig,log_GR_comp
+ nop.f 0
+(p15) br.cond.spnt ACOSH_NEAR_ONE // Branch if path 2, 1.0 < x < 1.0005
+}
+;;
+
+// Here is main path, 1.0005 <= x < 2^63
+/////////////// The first iteration //////////////////////////////////
+{ .mfi
+ ldfpd acosh_comp,log_P5 = [NR_table_address],16
+ fma.s1 log_y_rs_iter = log_y_rs,log_y,f0 // y*z
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfpd log_P4,log_P3 = [NR_table_address],16
+ fnma.s1 log_y_rs_iter = log_y_rs_iter,log_y_rs,NR2 // 3-(y*z)*z
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs,NR1,f0 // 0.5*z
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfpd log_P2,log_P1 = [NR_table_address],16
+ //(0.5*z)*(3-(y*z)*z)
+ fma.s1 log_y_rs_iter = log_y_rs_iter1,log_y_rs_iter,f0
+ nop.i 0
+}
+;;
+
+/////////////////////////// The second iteration /////////////////////////////
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs = log_y_rs_iter,log_y,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 log_y_rs = log_y_rs,log_y_rs_iter,NR2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs_iter,NR1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //(0.5*z)*(3-(y*z)*z)
+ fma.s1 log_y_rs_iter = log_y_rs_iter1,log_y_rs,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ //(0.5*z)*(3-(y*z)*z)
+ fma.s1 log_arg_early = log_y_rs_iter1,log_y_rs,f0
+ nop.i 0
+}
+;;
+
+//////////////////////////////////////// The third iteration /////////////////
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs = log_y_rs_iter,log_y,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs_iter,NR1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_arg_early = log_arg_early,log_y,f8
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 log_y_rs = log_y_rs,log_y_rs_iter,NR2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs_iter1,log_y,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ frcpa.s1 log_C,p0 = f1,log_arg_early
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.exp log_GR_signexp_f8 = log_arg_early
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.sig log_GR_significand_f8 = log_arg_early
+ fma.s1 log_arg = log_y_rs_iter1,log_y_rs,f8 // (0.5*z)*(3-(y*z)*z)
+ adds log_table_address3 = 0x70, NR_table_address
+}
+;;
+
+///////////////////////////////// The end NR iterations /////////////////////
+{ .mfi
+ ldfe log2 = [NR_table_address],16
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mmi
+ //significant bit destruction
+ and log_GR_exp_f8 = log_GR_signexp_f8, log_GR_exp_17_ones
+;;
+ //BIAS subtraction
+ sub log_GR_true_exp_f8 = log_GR_exp_f8, log_GR_exp_16_ones
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.sig log_int_Nfloat = log_GR_true_exp_f8
+ fms.s1 log_r = log_C,log_arg,f1 // C = frcpa(x); r = C * x - 1
+ extr.u log_GR_index = log_GR_significand_f8,55,8 //Extract 8 bits
+}
+;;
+
+{ .mmi
+ //pre-index*16 + index
+ shladd log_table_address3 = log_GR_index,4,log_table_address3
+;;
+ ldfe log_T = [log_table_address3]
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rsq = log_r, log_r, f0 //r^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p4 = log_P5, log_r, log_P4 //P5*r + P4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p32 = log_P3, log_r, log_P2 //P3*r + P2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //convert N to the floating-point format log_Nfloat
+ fcvt.xf log_Nfloat = log_int_Nfloat
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rcube = log_rsq, log_r, f0 //r^3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p10 = log_rsq, log_P1, log_r //P1*r^2 + r
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //(P5*r + P4)*r^2 + P3*r + P2
+ fma.s1 log_rp_p2 = log_rp_p4, log_rsq, log_rp_p32
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_T_plus_Nlog2 = log_Nfloat,log2,log_T //N*log2 + T
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ //((P5*r + P4)*r^2 + P3*r + P2)*r^3 + P1*r^2 + r
+ fma.s1 log_r2P_r = log_rp_p2, log_rcube, log_rp_p10
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ // N*log2 + T + ((P5*r + P4)*r^2 + P3*r + P2)*w^3 + P1*r^2 + r
+ fadd.d.s0 f8 = log_T_plus_Nlog2, log_r2P_r
+ br.ret.sptk b0 // Exit main path, path 3: 1.0005 <= x < 2^63
+}
+;;
+
+// Here if path 2, 1.0 < x < 1.0005
+ACOSH_NEAR_ONE:
+// The first NR iteration
+{ .mfi
+ ldfe log_C1 = [log_table_address2],16
+ fma.s1 acosh_w_iter1 = acosh_w_rs,log_w,f0 //t*w
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_1 = f8,log_C4,log_C3 //x*C4 + C3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe log_C0 = [log_table_address2],16
+ fma.s1 acosh_w_iter2 = acosh_w_rs,NR1,f0 //t*0.5
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 acosh_w_iter1 = acosh_w_iter1,acosh_w_rs,NR2 //3-t*t*w
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //(3-t*t*w)*t*0.5
+ fma.s1 acosh_w_iter2 = acosh_w_iter2,acosh_w_iter1,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_1 = acosh_w_1,log_w,log_C2 //(x*C4 + C3)*(x-1) + C2
+ nop.i 0
+}
+;;
+
+// The second NR iteration
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_rs = acosh_w_iter2,log_w,f0 //t*w
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ //((x*C4 + C3)*(x-1) + C2)*(x-1) + C1
+ fma.s1 acosh_w_1 = acosh_w_1,log_w,log_C1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 acosh_w_iter1 = acosh_w_iter2,acosh_w_rs,NR2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_iter2 = acosh_w_iter2,NR1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_iter2 = acosh_w_iter2,acosh_w_iter1,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ //(((x*C4 + C3)*(x-1) + C2)*(x-1) + C1)*(x-1) + C0
+ fma.s1 acosh_w_1 = acosh_w_1,log_w,log_C0
+ nop.i 0
+}
+;;
+
+//The third NR iteration
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_rs = acosh_w_iter2,log_w,f0 //t*w
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 acosh_w_iter1 = acosh_w_iter2,acosh_w_rs,NR2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_iter2 = acosh_w_iter2,NR1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_iter2 = acosh_w_iter2,acosh_w_iter1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_sqrt = acosh_w_iter2,log_w,f0
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = acosh_w_1,acosh_w_sqrt,f0
+ br.ret.sptk b0 // Exit path 2, 1.0 < x < 1.0005
+}
+;;
+
+// Here if path 4, x >= 2^63
+LOG_COMMON1:
+{ .mfi
+ ldfpd acosh_comp,log_P5 = [NR_table_address],16
+ frcpa.s1 log_C,p0 = f1,log_arg
+ nop.i 0
+}
+;;
+
+{ .mmi
+ getf.exp log_GR_signexp_f8 = log_arg
+ ldfpd log_P4,log_P3 = [NR_table_address],16
+ nop.i 0
+}
+;;
+
+{ .mmi
+ getf.sig log_GR_significand_f8 = log_arg
+ ldfpd log_P2,log_P1 = [NR_table_address],16
+ nop.i 0
+}
+;;
+
+{ .mfi
+ adds log_table_address3 = 0x70, NR_table_address
+ nop.f 0
+ //significant bit destruction
+ and log_GR_exp_f8 = log_GR_signexp_f8, log_GR_exp_17_ones
+}
+;;
+
+{ .mmf
+ ldfe log2 = [NR_table_address],16
+ //BIAS subtraction
+ sub log_GR_true_exp_f8 = log_GR_exp_f8, log_GR_exp_16_ones
+ fms.s1 log_r = log_C,log_arg,f1 // C = frcpa(x); r = C * x - 1
+}
+;;
+
+{ .mfi
+ setf.sig log_int_Nfloat = log_GR_true_exp_f8
+ nop.f 0
+ extr.u log_GR_index = log_GR_significand_f8,55,8 //Extract 8 bits
+}
+;;
+
+{ .mmi
+ //pre-index*16 + index
+ shladd log_table_address3 = log_GR_index,4,log_table_address3
+;;
+ ldfe log_T = [log_table_address3]
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rsq = log_r, log_r, f0 //r^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p4 = log_P5, log_r, log_P4 //P5*r + P4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p32 = log_P3, log_r, log_P2 //P3*r + P2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rcube = log_rsq, log_r, f0 //r^3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p10 = log_rsq, log_P1, log_r //P1*r^2 + r
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //convert N to the floating-point format log_Nfloat
+ fcvt.xf log_Nfloat = log_int_Nfloat
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ //(P5*r + P4)*r^2 + P3*r + P2
+ fma.s1 log_rp_p2 = log_rp_p4, log_rsq, log_rp_p32
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_T_plus_Nlog2 = log_Nfloat,log2,log_T //N*log2 + T
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ //((P5*r + P4)*r^2 + P3*r + P2)*w^3 + P1*r^2 + r
+ fma.s1 log_r2P_r = log_rp_p2, log_rcube, log_rp_p10
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ // N*log2 + T + ((P5*r + P4)*r^2 + P3*r + P2)*w^3 + P1*r^2 + r
+ fadd.d.s0 f8 = log_T_plus_Nlog2, log_r2P_r
+ br.ret.sptk b0 // Exit path 4, x >= 2^63
+}
+;;
+
+// Here if path 7, x < 1.0
+ACOSH_LESS_ONE:
+{ .mfi
+ alloc r32 = ar.pfs,1,3,4,0
+ fmerge.s f10 = f8,f8
+ nop.i 0
+}
+;;
+
+{ .mfb
+ mov acosh_GR_tag = 136
+ frcpa.s0 f8,p0 = f0,f0
+ br.cond.sptk __libm_error_region
+}
+;;
+
+GLOBAL_LIBM_END(acosh)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfd [GR_Parameter_Y] = f1,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfd [GR_Parameter_X] = f10 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_acoshf.S b/libc/sysdeps/ia64/fpu/e_acoshf.S
new file mode 100644
index 000000000..58ef5f2ad
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_acoshf.S
@@ -0,0 +1,1030 @@
+.file "acoshf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// ==============================================================
+// History
+// ==============================================================
+// 03/28/01 Initial version
+// 04/19/01 Improved speed of the paths #1,2,3,4,5
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 05/14/03 Improved performance, set denormal flag for unorms >= 1.0
+//
+// API
+// ==============================================================
+// float acoshf(float)
+//
+// Overview of operation
+// ==============================================================
+//
+// There are 7 paths:
+// 1. x = 1.0
+// Return acoshf(x) = 0.0
+// 2. 1.0 < x < 1.000499725341796875(0x3FF0020C00000000)
+// Return acoshf(x) = sqrt(x-1) * Pol4(x),
+// where Pol4(x) = (x*C2 + C1)*(x-1) + C0
+//
+// 3. 1.000499725341796875(0x3FF0020C00000000) <= x < 2^51
+// Return acoshf(x) = log(x + sqrt(x^2 -1.0))
+// To compute x + sqrt(x^2 -1.0) modified Newton Raphson method is used
+// (2 iterations)
+// Algorithm description for log function see below.
+//
+// 4. 2^51 <= x < +INF
+// Return acoshf(x) = log(2*x)
+// Algorithm description for log function see below.
+//
+// 5. x = +INF
+// Return acoshf(x) = +INF
+//
+// 6. x = [S,Q]NaN
+// Return acoshf(x) = QNaN
+//
+// 7. x < 1.0
+// It's domain error. Error handler with tag = 137 is called
+//
+//==============================================================
+// Algorithm Description for log(x) function
+// Below we are using the fact that inequality x - 1.0 > 2^(-6) is always
+// true for this acosh implementation
+//
+// Consider x = 2^N 1.f1 f2 f3 f4...f63
+// Log(x) = log(frcpa(x) x/frcpa(x))
+// = log(1/frcpa(x)) + log(frcpa(x) x)
+// = -log(frcpa(x)) + log(frcpa(x) x)
+//
+// frcpa(x) = 2^-N frcpa((1.f1 f2 ... f63)
+//
+// -log(frcpa(x)) = -log(C)
+// = -log(2^-N) - log(frcpa(1.f1 f2 ... f63))
+//
+// -log(frcpa(x)) = -log(C)
+// = +Nlog2 - log(frcpa(1.f1 f2 ... f63))
+//
+// -log(frcpa(x)) = -log(C)
+// = +Nlog2 + log(frcpa(1.f1 f2 ... f63))
+//
+// Log(x) = log(1/frcpa(x)) + log(frcpa(x) x)
+//
+// Log(x) = +Nlog2 + log(1./frcpa(1.f1 f2 ... f63)) + log(frcpa(x) x)
+// Log(x) = +Nlog2 - log(/frcpa(1.f1 f2 ... f63)) + log(frcpa(x) x)
+// Log(x) = +Nlog2 + T + log(frcpa(x) x)
+//
+// Log(x) = +Nlog2 + T + log(C x)
+//
+// Cx = 1 + r
+//
+// Log(x) = +Nlog2 + T + log(1+r)
+// Log(x) = +Nlog2 + T + Series( r - r^2/2 + r^3/3 - r^4/4 ....)
+//
+// 1.f1 f2 ... f8 has 256 entries.
+// They are 1 + k/2^8, k = 0 ... 255
+// These 256 values are the table entries.
+//
+// Implementation
+//==============================================================
+// C = frcpa(x)
+// r = C * x - 1
+//
+// Form rseries = r + P1*r^2 + P2*r^3 + P3*r^4
+//
+// x = f * 2*n where f is 1.f_1f_2f_3....f_63
+// Nfloat = float(n) where n is the true unbiased exponent
+// pre-index = f_1f_2....f_8
+// index = pre_index * 8
+// get the dxt table entry at index + offset = T
+//
+// result = (T + Nfloat * log(2)) + rseries
+//
+// The T table is calculated as follows
+// Form x_k = 1 + k/2^8 where k goes from 0... 255
+// y_k = frcpa(x_k)
+// log(1/y_k) in quad and round to double
+//
+
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f9 -> f15, f32 -> f62
+//
+// General registers used:
+// r14 -> r27, r32 -> r39
+//
+// Predicate registers used:
+// p6 -> p15
+//
+// p6 to filter out case when x = [Q,S]NaN
+// p7,p8 to filter out case when x < 1.0
+//
+// p10 to select path #1
+// p11 to filter out case when x = +INF
+// p12 used in the frcpa
+// p13 to select path #4
+// p14,p15 to select path #2
+
+// Assembly macros
+//==============================================================
+log_GR_exp_17_ones = r14
+log_GR_signexp_f8 = r15
+log_table_address2 = r16
+log_GR_exp_16_ones = r17
+log_GR_exp_f8 = r18
+log_GR_true_exp_f8 = r19
+log_GR_significand_f8 = r20
+log_GR_index = r21
+log_GR_comp2 = r22
+acosh_GR_f8 = r23
+log_GR_comp = r24
+acosh_GR_f8_sig = r25
+log_table_address3 = r26
+NR_table_address = r27
+
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_SAVE_PFS = r35
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+acosh_GR_tag = r39
+
+//==============================================================
+log_y = f9
+NR1 = f10
+NR2 = f11
+log_y_rs = f12
+log_y_rs_iter = f13
+log_y_rs_iter1 = f14
+log_NORM_f8 = f15
+log_w = f32
+acosh_comp = f34
+acosh_comp2 = f33
+log_P3 = f35
+log_P2 = f36
+log_P1 = f37
+log2 = f38
+log_C0 = f39
+log_C1 = f40
+log_C2 = f41
+acosh_w_rs = f42
+log_C = f43
+log_arg = f44
+acosh_w_iter1 = f45
+acosh_w_iter2 = f46
+log_int_Nfloat = f47
+log_r = f48
+log_rsq = f49
+log_rp_p4 = f50
+log_rp_p32 = f51
+log_rcube = f52
+log_rp_p10 = f53
+log_rp_p2 = f54
+log_Nfloat = f55
+log_T = f56
+log_r2P_r = f57
+log_T_plus_Nlog2 = f58
+acosh_w_sqrt = f59
+acosh_w_1 = f60
+log_arg_early = f61
+log_y_rs_iter2 = f62
+
+
+// Data tables
+//==============================================================
+
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(log_table_1)
+data8 0xbfd0001008f39d59 // p3
+data8 0x3fd5556073e0c45a // p2
+data8 0xbfdffffffffaea15 // p1
+data8 0x3FE62E42FEFA39EF // log2
+LOCAL_OBJECT_END(log_table_1)
+
+LOCAL_OBJECT_START(log_table_2)
+
+data8 0x3FE0000000000000 // 0.5
+data8 0x4008000000000000 // 3.0
+data8 0xD92CBAD213719F11, 0x00003FF9 // C2 3FF9D92CBAD213719F11
+data8 0x93D38EBF2EC9B073, 0x0000BFFC // C1 BFFC93D38EBF2EC9B073
+data8 0xB504F333F9DA0E32, 0x00003FFF // C0 3FFFB504F333F9DA0E32
+LOCAL_OBJECT_END(log_table_2)
+
+LOCAL_OBJECT_START(log_table_3)
+data8 0x3F60040155D5889E //log(1/frcpa(1+ 0/256)
+data8 0x3F78121214586B54 //log(1/frcpa(1+ 1/256)
+data8 0x3F841929F96832F0 //log(1/frcpa(1+ 2/256)
+data8 0x3F8C317384C75F06 //log(1/frcpa(1+ 3/256)
+data8 0x3F91A6B91AC73386 //log(1/frcpa(1+ 4/256)
+data8 0x3F95BA9A5D9AC039 //log(1/frcpa(1+ 5/256)
+data8 0x3F99D2A8074325F4 //log(1/frcpa(1+ 6/256)
+data8 0x3F9D6B2725979802 //log(1/frcpa(1+ 7/256)
+data8 0x3FA0C58FA19DFAAA //log(1/frcpa(1+ 8/256)
+data8 0x3FA2954C78CBCE1B //log(1/frcpa(1+ 9/256)
+data8 0x3FA4A94D2DA96C56 //log(1/frcpa(1+ 10/256)
+data8 0x3FA67C94F2D4BB58 //log(1/frcpa(1+ 11/256)
+data8 0x3FA85188B630F068 //log(1/frcpa(1+ 12/256)
+data8 0x3FAA6B8ABE73AF4C //log(1/frcpa(1+ 13/256)
+data8 0x3FAC441E06F72A9E //log(1/frcpa(1+ 14/256)
+data8 0x3FAE1E6713606D07 //log(1/frcpa(1+ 15/256)
+data8 0x3FAFFA6911AB9301 //log(1/frcpa(1+ 16/256)
+data8 0x3FB0EC139C5DA601 //log(1/frcpa(1+ 17/256)
+data8 0x3FB1DBD2643D190B //log(1/frcpa(1+ 18/256)
+data8 0x3FB2CC7284FE5F1C //log(1/frcpa(1+ 19/256)
+data8 0x3FB3BDF5A7D1EE64 //log(1/frcpa(1+ 20/256)
+data8 0x3FB4B05D7AA012E0 //log(1/frcpa(1+ 21/256)
+data8 0x3FB580DB7CEB5702 //log(1/frcpa(1+ 22/256)
+data8 0x3FB674F089365A7A //log(1/frcpa(1+ 23/256)
+data8 0x3FB769EF2C6B568D //log(1/frcpa(1+ 24/256)
+data8 0x3FB85FD927506A48 //log(1/frcpa(1+ 25/256)
+data8 0x3FB9335E5D594989 //log(1/frcpa(1+ 26/256)
+data8 0x3FBA2B0220C8E5F5 //log(1/frcpa(1+ 27/256)
+data8 0x3FBB0004AC1A86AC //log(1/frcpa(1+ 28/256)
+data8 0x3FBBF968769FCA11 //log(1/frcpa(1+ 29/256)
+data8 0x3FBCCFEDBFEE13A8 //log(1/frcpa(1+ 30/256)
+data8 0x3FBDA727638446A2 //log(1/frcpa(1+ 31/256)
+data8 0x3FBEA3257FE10F7A //log(1/frcpa(1+ 32/256)
+data8 0x3FBF7BE9FEDBFDE6 //log(1/frcpa(1+ 33/256)
+data8 0x3FC02AB352FF25F4 //log(1/frcpa(1+ 34/256)
+data8 0x3FC097CE579D204D //log(1/frcpa(1+ 35/256)
+data8 0x3FC1178E8227E47C //log(1/frcpa(1+ 36/256)
+data8 0x3FC185747DBECF34 //log(1/frcpa(1+ 37/256)
+data8 0x3FC1F3B925F25D41 //log(1/frcpa(1+ 38/256)
+data8 0x3FC2625D1E6DDF57 //log(1/frcpa(1+ 39/256)
+data8 0x3FC2D1610C86813A //log(1/frcpa(1+ 40/256)
+data8 0x3FC340C59741142E //log(1/frcpa(1+ 41/256)
+data8 0x3FC3B08B6757F2A9 //log(1/frcpa(1+ 42/256)
+data8 0x3FC40DFB08378003 //log(1/frcpa(1+ 43/256)
+data8 0x3FC47E74E8CA5F7C //log(1/frcpa(1+ 44/256)
+data8 0x3FC4EF51F6466DE4 //log(1/frcpa(1+ 45/256)
+data8 0x3FC56092E02BA516 //log(1/frcpa(1+ 46/256)
+data8 0x3FC5D23857CD74D5 //log(1/frcpa(1+ 47/256)
+data8 0x3FC6313A37335D76 //log(1/frcpa(1+ 48/256)
+data8 0x3FC6A399DABBD383 //log(1/frcpa(1+ 49/256)
+data8 0x3FC70337DD3CE41B //log(1/frcpa(1+ 50/256)
+data8 0x3FC77654128F6127 //log(1/frcpa(1+ 51/256)
+data8 0x3FC7E9D82A0B022D //log(1/frcpa(1+ 52/256)
+data8 0x3FC84A6B759F512F //log(1/frcpa(1+ 53/256)
+data8 0x3FC8AB47D5F5A310 //log(1/frcpa(1+ 54/256)
+data8 0x3FC91FE49096581B //log(1/frcpa(1+ 55/256)
+data8 0x3FC981634011AA75 //log(1/frcpa(1+ 56/256)
+data8 0x3FC9F6C407089664 //log(1/frcpa(1+ 57/256)
+data8 0x3FCA58E729348F43 //log(1/frcpa(1+ 58/256)
+data8 0x3FCABB55C31693AD //log(1/frcpa(1+ 59/256)
+data8 0x3FCB1E104919EFD0 //log(1/frcpa(1+ 60/256)
+data8 0x3FCB94EE93E367CB //log(1/frcpa(1+ 61/256)
+data8 0x3FCBF851C067555F //log(1/frcpa(1+ 62/256)
+data8 0x3FCC5C0254BF23A6 //log(1/frcpa(1+ 63/256)
+data8 0x3FCCC000C9DB3C52 //log(1/frcpa(1+ 64/256)
+data8 0x3FCD244D99C85674 //log(1/frcpa(1+ 65/256)
+data8 0x3FCD88E93FB2F450 //log(1/frcpa(1+ 66/256)
+data8 0x3FCDEDD437EAEF01 //log(1/frcpa(1+ 67/256)
+data8 0x3FCE530EFFE71012 //log(1/frcpa(1+ 68/256)
+data8 0x3FCEB89A1648B971 //log(1/frcpa(1+ 69/256)
+data8 0x3FCF1E75FADF9BDE //log(1/frcpa(1+ 70/256)
+data8 0x3FCF84A32EAD7C35 //log(1/frcpa(1+ 71/256)
+data8 0x3FCFEB2233EA07CD //log(1/frcpa(1+ 72/256)
+data8 0x3FD028F9C7035C1C //log(1/frcpa(1+ 73/256)
+data8 0x3FD05C8BE0D9635A //log(1/frcpa(1+ 74/256)
+data8 0x3FD085EB8F8AE797 //log(1/frcpa(1+ 75/256)
+data8 0x3FD0B9C8E32D1911 //log(1/frcpa(1+ 76/256)
+data8 0x3FD0EDD060B78081 //log(1/frcpa(1+ 77/256)
+data8 0x3FD122024CF0063F //log(1/frcpa(1+ 78/256)
+data8 0x3FD14BE2927AECD4 //log(1/frcpa(1+ 79/256)
+data8 0x3FD180618EF18ADF //log(1/frcpa(1+ 80/256)
+data8 0x3FD1B50BBE2FC63B //log(1/frcpa(1+ 81/256)
+data8 0x3FD1DF4CC7CF242D //log(1/frcpa(1+ 82/256)
+data8 0x3FD214456D0EB8D4 //log(1/frcpa(1+ 83/256)
+data8 0x3FD23EC5991EBA49 //log(1/frcpa(1+ 84/256)
+data8 0x3FD2740D9F870AFB //log(1/frcpa(1+ 85/256)
+data8 0x3FD29ECDABCDFA04 //log(1/frcpa(1+ 86/256)
+data8 0x3FD2D46602ADCCEE //log(1/frcpa(1+ 87/256)
+data8 0x3FD2FF66B04EA9D4 //log(1/frcpa(1+ 88/256)
+data8 0x3FD335504B355A37 //log(1/frcpa(1+ 89/256)
+data8 0x3FD360925EC44F5D //log(1/frcpa(1+ 90/256)
+data8 0x3FD38BF1C3337E75 //log(1/frcpa(1+ 91/256)
+data8 0x3FD3C25277333184 //log(1/frcpa(1+ 92/256)
+data8 0x3FD3EDF463C1683E //log(1/frcpa(1+ 93/256)
+data8 0x3FD419B423D5E8C7 //log(1/frcpa(1+ 94/256)
+data8 0x3FD44591E0539F49 //log(1/frcpa(1+ 95/256)
+data8 0x3FD47C9175B6F0AD //log(1/frcpa(1+ 96/256)
+data8 0x3FD4A8B341552B09 //log(1/frcpa(1+ 97/256)
+data8 0x3FD4D4F3908901A0 //log(1/frcpa(1+ 98/256)
+data8 0x3FD501528DA1F968 //log(1/frcpa(1+ 99/256)
+data8 0x3FD52DD06347D4F6 //log(1/frcpa(1+ 100/256)
+data8 0x3FD55A6D3C7B8A8A //log(1/frcpa(1+ 101/256)
+data8 0x3FD5925D2B112A59 //log(1/frcpa(1+ 102/256)
+data8 0x3FD5BF406B543DB2 //log(1/frcpa(1+ 103/256)
+data8 0x3FD5EC433D5C35AE //log(1/frcpa(1+ 104/256)
+data8 0x3FD61965CDB02C1F //log(1/frcpa(1+ 105/256)
+data8 0x3FD646A84935B2A2 //log(1/frcpa(1+ 106/256)
+data8 0x3FD6740ADD31DE94 //log(1/frcpa(1+ 107/256)
+data8 0x3FD6A18DB74A58C5 //log(1/frcpa(1+ 108/256)
+data8 0x3FD6CF31058670EC //log(1/frcpa(1+ 109/256)
+data8 0x3FD6F180E852F0BA //log(1/frcpa(1+ 110/256)
+data8 0x3FD71F5D71B894F0 //log(1/frcpa(1+ 111/256)
+data8 0x3FD74D5AEFD66D5C //log(1/frcpa(1+ 112/256)
+data8 0x3FD77B79922BD37E //log(1/frcpa(1+ 113/256)
+data8 0x3FD7A9B9889F19E2 //log(1/frcpa(1+ 114/256)
+data8 0x3FD7D81B037EB6A6 //log(1/frcpa(1+ 115/256)
+data8 0x3FD8069E33827231 //log(1/frcpa(1+ 116/256)
+data8 0x3FD82996D3EF8BCB //log(1/frcpa(1+ 117/256)
+data8 0x3FD85855776DCBFB //log(1/frcpa(1+ 118/256)
+data8 0x3FD8873658327CCF //log(1/frcpa(1+ 119/256)
+data8 0x3FD8AA75973AB8CF //log(1/frcpa(1+ 120/256)
+data8 0x3FD8D992DC8824E5 //log(1/frcpa(1+ 121/256)
+data8 0x3FD908D2EA7D9512 //log(1/frcpa(1+ 122/256)
+data8 0x3FD92C59E79C0E56 //log(1/frcpa(1+ 123/256)
+data8 0x3FD95BD750EE3ED3 //log(1/frcpa(1+ 124/256)
+data8 0x3FD98B7811A3EE5B //log(1/frcpa(1+ 125/256)
+data8 0x3FD9AF47F33D406C //log(1/frcpa(1+ 126/256)
+data8 0x3FD9DF270C1914A8 //log(1/frcpa(1+ 127/256)
+data8 0x3FDA0325ED14FDA4 //log(1/frcpa(1+ 128/256)
+data8 0x3FDA33440224FA79 //log(1/frcpa(1+ 129/256)
+data8 0x3FDA57725E80C383 //log(1/frcpa(1+ 130/256)
+data8 0x3FDA87D0165DD199 //log(1/frcpa(1+ 131/256)
+data8 0x3FDAAC2E6C03F896 //log(1/frcpa(1+ 132/256)
+data8 0x3FDADCCC6FDF6A81 //log(1/frcpa(1+ 133/256)
+data8 0x3FDB015B3EB1E790 //log(1/frcpa(1+ 134/256)
+data8 0x3FDB323A3A635948 //log(1/frcpa(1+ 135/256)
+data8 0x3FDB56FA04462909 //log(1/frcpa(1+ 136/256)
+data8 0x3FDB881AA659BC93 //log(1/frcpa(1+ 137/256)
+data8 0x3FDBAD0BEF3DB165 //log(1/frcpa(1+ 138/256)
+data8 0x3FDBD21297781C2F //log(1/frcpa(1+ 139/256)
+data8 0x3FDC039236F08819 //log(1/frcpa(1+ 140/256)
+data8 0x3FDC28CB1E4D32FD //log(1/frcpa(1+ 141/256)
+data8 0x3FDC4E19B84723C2 //log(1/frcpa(1+ 142/256)
+data8 0x3FDC7FF9C74554C9 //log(1/frcpa(1+ 143/256)
+data8 0x3FDCA57B64E9DB05 //log(1/frcpa(1+ 144/256)
+data8 0x3FDCCB130A5CEBB0 //log(1/frcpa(1+ 145/256)
+data8 0x3FDCF0C0D18F326F //log(1/frcpa(1+ 146/256)
+data8 0x3FDD232075B5A201 //log(1/frcpa(1+ 147/256)
+data8 0x3FDD490246DEFA6B //log(1/frcpa(1+ 148/256)
+data8 0x3FDD6EFA918D25CD //log(1/frcpa(1+ 149/256)
+data8 0x3FDD9509707AE52F //log(1/frcpa(1+ 150/256)
+data8 0x3FDDBB2EFE92C554 //log(1/frcpa(1+ 151/256)
+data8 0x3FDDEE2F3445E4AF //log(1/frcpa(1+ 152/256)
+data8 0x3FDE148A1A2726CE //log(1/frcpa(1+ 153/256)
+data8 0x3FDE3AFC0A49FF40 //log(1/frcpa(1+ 154/256)
+data8 0x3FDE6185206D516E //log(1/frcpa(1+ 155/256)
+data8 0x3FDE882578823D52 //log(1/frcpa(1+ 156/256)
+data8 0x3FDEAEDD2EAC990C //log(1/frcpa(1+ 157/256)
+data8 0x3FDED5AC5F436BE3 //log(1/frcpa(1+ 158/256)
+data8 0x3FDEFC9326D16AB9 //log(1/frcpa(1+ 159/256)
+data8 0x3FDF2391A2157600 //log(1/frcpa(1+ 160/256)
+data8 0x3FDF4AA7EE03192D //log(1/frcpa(1+ 161/256)
+data8 0x3FDF71D627C30BB0 //log(1/frcpa(1+ 162/256)
+data8 0x3FDF991C6CB3B379 //log(1/frcpa(1+ 163/256)
+data8 0x3FDFC07ADA69A910 //log(1/frcpa(1+ 164/256)
+data8 0x3FDFE7F18EB03D3E //log(1/frcpa(1+ 165/256)
+data8 0x3FE007C053C5002E //log(1/frcpa(1+ 166/256)
+data8 0x3FE01B942198A5A1 //log(1/frcpa(1+ 167/256)
+data8 0x3FE02F74400C64EB //log(1/frcpa(1+ 168/256)
+data8 0x3FE04360BE7603AD //log(1/frcpa(1+ 169/256)
+data8 0x3FE05759AC47FE34 //log(1/frcpa(1+ 170/256)
+data8 0x3FE06B5F1911CF52 //log(1/frcpa(1+ 171/256)
+data8 0x3FE078BF0533C568 //log(1/frcpa(1+ 172/256)
+data8 0x3FE08CD9687E7B0E //log(1/frcpa(1+ 173/256)
+data8 0x3FE0A10074CF9019 //log(1/frcpa(1+ 174/256)
+data8 0x3FE0B5343A234477 //log(1/frcpa(1+ 175/256)
+data8 0x3FE0C974C89431CE //log(1/frcpa(1+ 176/256)
+data8 0x3FE0DDC2305B9886 //log(1/frcpa(1+ 177/256)
+data8 0x3FE0EB524BAFC918 //log(1/frcpa(1+ 178/256)
+data8 0x3FE0FFB54213A476 //log(1/frcpa(1+ 179/256)
+data8 0x3FE114253DA97D9F //log(1/frcpa(1+ 180/256)
+data8 0x3FE128A24F1D9AFF //log(1/frcpa(1+ 181/256)
+data8 0x3FE1365252BF0865 //log(1/frcpa(1+ 182/256)
+data8 0x3FE14AE558B4A92D //log(1/frcpa(1+ 183/256)
+data8 0x3FE15F85A19C765B //log(1/frcpa(1+ 184/256)
+data8 0x3FE16D4D38C119FA //log(1/frcpa(1+ 185/256)
+data8 0x3FE18203C20DD133 //log(1/frcpa(1+ 186/256)
+data8 0x3FE196C7BC4B1F3B //log(1/frcpa(1+ 187/256)
+data8 0x3FE1A4A738B7A33C //log(1/frcpa(1+ 188/256)
+data8 0x3FE1B981C0C9653D //log(1/frcpa(1+ 189/256)
+data8 0x3FE1CE69E8BB106B //log(1/frcpa(1+ 190/256)
+data8 0x3FE1DC619DE06944 //log(1/frcpa(1+ 191/256)
+data8 0x3FE1F160A2AD0DA4 //log(1/frcpa(1+ 192/256)
+data8 0x3FE2066D7740737E //log(1/frcpa(1+ 193/256)
+data8 0x3FE2147DBA47A394 //log(1/frcpa(1+ 194/256)
+data8 0x3FE229A1BC5EBAC3 //log(1/frcpa(1+ 195/256)
+data8 0x3FE237C1841A502E //log(1/frcpa(1+ 196/256)
+data8 0x3FE24CFCE6F80D9A //log(1/frcpa(1+ 197/256)
+data8 0x3FE25B2C55CD5762 //log(1/frcpa(1+ 198/256)
+data8 0x3FE2707F4D5F7C41 //log(1/frcpa(1+ 199/256)
+data8 0x3FE285E0842CA384 //log(1/frcpa(1+ 200/256)
+data8 0x3FE294294708B773 //log(1/frcpa(1+ 201/256)
+data8 0x3FE2A9A2670AFF0C //log(1/frcpa(1+ 202/256)
+data8 0x3FE2B7FB2C8D1CC1 //log(1/frcpa(1+ 203/256)
+data8 0x3FE2C65A6395F5F5 //log(1/frcpa(1+ 204/256)
+data8 0x3FE2DBF557B0DF43 //log(1/frcpa(1+ 205/256)
+data8 0x3FE2EA64C3F97655 //log(1/frcpa(1+ 206/256)
+data8 0x3FE3001823684D73 //log(1/frcpa(1+ 207/256)
+data8 0x3FE30E97E9A8B5CD //log(1/frcpa(1+ 208/256)
+data8 0x3FE32463EBDD34EA //log(1/frcpa(1+ 209/256)
+data8 0x3FE332F4314AD796 //log(1/frcpa(1+ 210/256)
+data8 0x3FE348D90E7464D0 //log(1/frcpa(1+ 211/256)
+data8 0x3FE35779F8C43D6E //log(1/frcpa(1+ 212/256)
+data8 0x3FE36621961A6A99 //log(1/frcpa(1+ 213/256)
+data8 0x3FE37C299F3C366A //log(1/frcpa(1+ 214/256)
+data8 0x3FE38AE2171976E7 //log(1/frcpa(1+ 215/256)
+data8 0x3FE399A157A603E7 //log(1/frcpa(1+ 216/256)
+data8 0x3FE3AFCCFE77B9D1 //log(1/frcpa(1+ 217/256)
+data8 0x3FE3BE9D503533B5 //log(1/frcpa(1+ 218/256)
+data8 0x3FE3CD7480B4A8A3 //log(1/frcpa(1+ 219/256)
+data8 0x3FE3E3C43918F76C //log(1/frcpa(1+ 220/256)
+data8 0x3FE3F2ACB27ED6C7 //log(1/frcpa(1+ 221/256)
+data8 0x3FE4019C2125CA93 //log(1/frcpa(1+ 222/256)
+data8 0x3FE4181061389722 //log(1/frcpa(1+ 223/256)
+data8 0x3FE42711518DF545 //log(1/frcpa(1+ 224/256)
+data8 0x3FE436194E12B6BF //log(1/frcpa(1+ 225/256)
+data8 0x3FE445285D68EA69 //log(1/frcpa(1+ 226/256)
+data8 0x3FE45BCC464C893A //log(1/frcpa(1+ 227/256)
+data8 0x3FE46AED21F117FC //log(1/frcpa(1+ 228/256)
+data8 0x3FE47A1527E8A2D3 //log(1/frcpa(1+ 229/256)
+data8 0x3FE489445EFFFCCC //log(1/frcpa(1+ 230/256)
+data8 0x3FE4A018BCB69835 //log(1/frcpa(1+ 231/256)
+data8 0x3FE4AF5A0C9D65D7 //log(1/frcpa(1+ 232/256)
+data8 0x3FE4BEA2A5BDBE87 //log(1/frcpa(1+ 233/256)
+data8 0x3FE4CDF28F10AC46 //log(1/frcpa(1+ 234/256)
+data8 0x3FE4DD49CF994058 //log(1/frcpa(1+ 235/256)
+data8 0x3FE4ECA86E64A684 //log(1/frcpa(1+ 236/256)
+data8 0x3FE503C43CD8EB68 //log(1/frcpa(1+ 237/256)
+data8 0x3FE513356667FC57 //log(1/frcpa(1+ 238/256)
+data8 0x3FE522AE0738A3D8 //log(1/frcpa(1+ 239/256)
+data8 0x3FE5322E26867857 //log(1/frcpa(1+ 240/256)
+data8 0x3FE541B5CB979809 //log(1/frcpa(1+ 241/256)
+data8 0x3FE55144FDBCBD62 //log(1/frcpa(1+ 242/256)
+data8 0x3FE560DBC45153C7 //log(1/frcpa(1+ 243/256)
+data8 0x3FE5707A26BB8C66 //log(1/frcpa(1+ 244/256)
+data8 0x3FE587F60ED5B900 //log(1/frcpa(1+ 245/256)
+data8 0x3FE597A7977C8F31 //log(1/frcpa(1+ 246/256)
+data8 0x3FE5A760D634BB8B //log(1/frcpa(1+ 247/256)
+data8 0x3FE5B721D295F10F //log(1/frcpa(1+ 248/256)
+data8 0x3FE5C6EA94431EF9 //log(1/frcpa(1+ 249/256)
+data8 0x3FE5D6BB22EA86F6 //log(1/frcpa(1+ 250/256)
+data8 0x3FE5E6938645D390 //log(1/frcpa(1+ 251/256)
+data8 0x3FE5F673C61A2ED2 //log(1/frcpa(1+ 252/256)
+data8 0x3FE6065BEA385926 //log(1/frcpa(1+ 253/256)
+data8 0x3FE6164BFA7CC06B //log(1/frcpa(1+ 254/256)
+data8 0x3FE62643FECF9743 //log(1/frcpa(1+ 255/256)
+LOCAL_OBJECT_END(log_table_3)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(acoshf)
+
+{ .mfi
+ getf.exp acosh_GR_f8 = f8
+ fclass.m p6,p0 = f8, 0xc3 // Test for x = NaN
+ mov log_GR_comp2 = 0x10032
+}
+{ .mfi
+ addl NR_table_address = @ltoff(log_table_1), gp
+ fms.s1 log_y = f8, f8, f1 // y = x^2-1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.sig acosh_GR_f8_sig = f8
+ fclass.m p11,p0 = f8, 0x21 // Test for x=+inf
+ mov log_GR_exp_17_ones = 0x1ffff
+}
+{ .mfi
+ ld8 NR_table_address = [NR_table_address]
+ fms.s1 log_w = f8,f1,f1 // w = x - 1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.lt.s1 p7,p8 = f8, f1 // Test for x<1.0
+ addl log_GR_comp = 0x10020C,r0 // Upper 21 bits of signif of 1.0005
+}
+{ .mfb
+ mov log_GR_exp_16_ones = 0xffff //BIAS
+(p6) fma.s.s0 f8 = f8,f1,f0 // quietize nan result if x=nan
+(p6) br.ret.spnt b0 // Exit for x=nan
+}
+;;
+
+{ .mfb
+ //get second table address
+ adds log_table_address2 = 0x20, NR_table_address
+ fcmp.eq.s1 p10,p0 = f8, f1 // Test for x=+1.0
+(p11) br.ret.spnt b0 // Exit for x=+inf
+}
+;;
+
+{ .mfi
+ ldfpd NR1,NR2 = [log_table_address2],16
+ frsqrta.s1 log_y_rs,p0 = log_y // z=1/sqrt(y)
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s1 log_arg = f8,f1,f8
+(p7) br.cond.spnt ACOSH_LESS_ONE // Branch if path 7, x < 1.0
+}
+;;
+
+{ .mfi
+ ldfe log_C2 = [log_table_address2],16
+(p8) fcmp.eq.s0 p6,p0 = f8, f0 // Dummy op sets denorm flag if unorm>=1.0
+ nop.i 0
+}
+{ .mfb
+(p8) cmp.le.unc p13,p0 = log_GR_comp2,acosh_GR_f8
+ nop.f 0
+(p13) br.cond.spnt LOG_COMMON1 // Branch if path 4, x >= 2^51
+}
+;;
+
+{ .mfi
+ ldfe log_C1 = [log_table_address2],16
+(p10) fmerge.s f8 = f0, f0 // Return 0 if x=1.0
+ shr.u acosh_GR_f8_sig = acosh_GR_f8_sig,43
+}
+{ .mib
+ cmp.eq p14,p0 = log_GR_exp_16_ones,acosh_GR_f8
+ nop.i 0
+(p10) br.ret.spnt b0 // Exit for x=1.0
+}
+;;
+
+{ .mfi
+ ldfe log_C0 = [log_table_address2],16
+ frsqrta.s1 acosh_w_rs,p0 = log_w // t=1/sqrt(w)
+ nop.i 0
+}
+{ .mfb
+(p14) cmp.lt.unc p15,p0 = acosh_GR_f8_sig,log_GR_comp
+ nop.f 0
+(p15) br.cond.spnt ACOSH_NEAR_ONE // Branch if path 2, 1.0 < x < 1.0005
+}
+;;
+
+// Here is main path, 1.0005 <= x < 2^51
+/////////////// The first iteration //////////////////////////////////
+{ .mfi
+ ldfpd log_P3,log_P2 = [NR_table_address],16
+ fma.s1 log_y_rs_iter = log_y_rs,log_y,f0 // y*z
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfpd log_P1,log2 = [NR_table_address],16
+ fnma.s1 log_y_rs_iter2 = log_y_rs_iter,log_y_rs,NR2 // 3-(y*z)*z
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs,NR1,f0 // 0.5*z
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // (0.5*z)*(3-(y*z)*z)
+ fma.s1 log_y_rs_iter = log_y_rs_iter1,log_y_rs_iter2,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (0.5*z)*(3-(y*z)*z)
+ fma.s1 log_arg_early = log_y_rs_iter1,log_y_rs_iter2,f0
+ nop.i 0
+}
+;;
+
+/////////////////////////// The second iteration /////////////////////////////
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs = log_y_rs_iter,log_y,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs_iter,NR1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_arg_early = log_arg_early,log_y,f8
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 log_y_rs = log_y_rs,log_y_rs_iter,NR2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs_iter1,log_y,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ frcpa.s1 log_C,p0 = f1,log_arg_early
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.exp log_GR_signexp_f8 = log_arg_early
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.sig log_GR_significand_f8 = log_arg_early
+ fma.s1 log_arg = log_y_rs_iter1,log_y_rs,f8 // (0.5*z)*(3-(y*z)*z)
+ adds log_table_address3 = 0x40, NR_table_address
+}
+;;
+
+///////////////////////////////// The end NR iterations /////////////////////
+
+{ .mmi
+ //significant bit destruction
+ and log_GR_exp_f8 = log_GR_signexp_f8, log_GR_exp_17_ones
+;;
+ //BIAS subtraction
+ sub log_GR_true_exp_f8 = log_GR_exp_f8, log_GR_exp_16_ones
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.sig log_int_Nfloat = log_GR_true_exp_f8
+ fms.s1 log_r = log_C,log_arg,f1 // C = frcpa(x); r = C * x - 1
+ extr.u log_GR_index = log_GR_significand_f8,55,8 //Extract 8 bits
+}
+;;
+
+{ .mmi
+ //pre-index*8 + index
+ shladd log_table_address3 = log_GR_index,3,log_table_address3
+;;
+ ldfd log_T = [log_table_address3]
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rsq = log_r, log_r, f0 //r^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p32 = log_P3, log_r, log_P2 //P3*r + P2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p10 = log_P1, log_r, f1 //P1*r + 1.0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //convert N to the floating-point format log_Nfloat
+ fcvt.xf log_Nfloat = log_int_Nfloat
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //(P3*r + P2)*r^2 + P1*r + 1.0
+ fma.s1 log_rp_p2 = log_rp_p32, log_rsq, log_rp_p10
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_T_plus_Nlog2 = log_Nfloat,log2,log_T //N*log2 + T
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = log_rp_p2,log_r,log_T_plus_Nlog2
+ br.ret.sptk b0 // Exit main path, path 3: 1.0005 <= x < 2^51
+}
+;;
+
+// Here if path 2, 1.0 < x < 1.0005
+ACOSH_NEAR_ONE:
+// The first NR iteration
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_iter1 = acosh_w_rs,log_w,f0 //t*w
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_1 = f8,log_C2,log_C1 //x*C2 + C1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_iter2 = acosh_w_rs,NR1,f0 //t*0.5
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 acosh_w_iter1 = acosh_w_iter1,acosh_w_rs,NR2 //3-t*t*w
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //(3-t*t*w)*t*0.5
+ fma.s1 acosh_w_iter2 = acosh_w_iter2,acosh_w_iter1,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_1 = acosh_w_1,log_w,log_C0 //(x*C2 + C1)*(x-1) + C0
+ nop.i 0
+}
+;;
+
+// The second NR iteration
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_rs = acosh_w_iter2,log_w,f0 //t*w
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 acosh_w_iter1 = acosh_w_iter2,acosh_w_rs,NR2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_iter2 = acosh_w_iter2,NR1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_iter2 = acosh_w_iter2,acosh_w_iter1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 acosh_w_sqrt = acosh_w_iter2,log_w,f0
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = acosh_w_1,acosh_w_sqrt,f0
+ br.ret.sptk b0 // Exit path 2, 1.0 < x < 1.0005
+}
+;;
+
+// Here if path 4, x >= 2^51
+LOG_COMMON1:
+{ .mfi
+ ldfpd log_P3,log_P2 = [NR_table_address],16
+ frcpa.s1 log_C,p0 = f1,log_arg
+ nop.i 0
+}
+;;
+
+{ .mmi
+ getf.exp log_GR_signexp_f8 = log_arg
+ ldfpd log_P1,log2 = [NR_table_address],16
+ nop.i 0
+}
+;;
+
+{ .mmi
+ getf.sig log_GR_significand_f8 = log_arg
+ nop.m 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ adds log_table_address3 = 0x40, NR_table_address
+ nop.f 0
+ //significant bit destruction
+ and log_GR_exp_f8 = log_GR_signexp_f8, log_GR_exp_17_ones
+}
+;;
+
+{ .mmf
+ nop.m 0
+ //BIAS subtraction
+ sub log_GR_true_exp_f8 = log_GR_exp_f8, log_GR_exp_16_ones
+ fms.s1 log_r = log_C,log_arg,f1 // C = frcpa(x); r = C * x - 1
+}
+;;
+
+{ .mfi
+ setf.sig log_int_Nfloat = log_GR_true_exp_f8
+ nop.f 0
+ extr.u log_GR_index = log_GR_significand_f8,55,8 //Extract 8 bits
+}
+;;
+
+{ .mmi
+ //pre-index*8 + index
+ shladd log_table_address3 = log_GR_index,3,log_table_address3
+;;
+ ldfd log_T = [log_table_address3]
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rsq = log_r, log_r, f0 //r^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p32 = log_P3, log_r, log_P2 //P3*r + P2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p10 = log_P1, log_r, f1 //P1*r + 1.0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //convert N to the floating-point format log_Nfloat
+ fcvt.xf log_Nfloat = log_int_Nfloat
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p2 = log_rp_p32, log_rsq, log_rp_p10
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_T_plus_Nlog2 = log_Nfloat,log2,log_T //N*log2 + T
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = log_rp_p2,log_r,log_T_plus_Nlog2
+ br.ret.sptk b0 // Exit path 4, x >= 2^51
+}
+;;
+
+// Here if path 7, x < 1.0
+ACOSH_LESS_ONE:
+{ .mfi
+ alloc r32 = ar.pfs,1,3,4,0
+ fmerge.s f10 = f8,f8
+ nop.i 0
+}
+;;
+
+{ .mfb
+ mov acosh_GR_tag = 137
+ frcpa.s0 f8,p0 = f0,f0
+ br.cond.sptk __libm_error_region
+}
+;;
+
+GLOBAL_LIBM_END(acoshf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfs [GR_Parameter_Y] = f1,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfs [GR_Parameter_X] = f10 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_acoshl.S b/libc/sysdeps/ia64/fpu/e_acoshl.S
new file mode 100644
index 000000000..42e1f394e
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_acoshl.S
@@ -0,0 +1,1716 @@
+.file "acoshl.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 10/01/01 Initial version
+// 10/10/01 Performance inproved
+// 12/11/01 Changed huges_logp to not be global
+// 01/02/02 Corrected .restore syntax
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 08/14/02 Changed mli templates to mlx
+// 02/06/03 Reorganized data tables
+// 03/31/05 Reformatted delimiters between data tables
+//
+//*********************************************************************
+//
+// API
+//==============================================================
+// long double acoshl(long double);
+//
+// Overview of operation
+//==============================================================
+//
+// There are 6 paths:
+// 1. x = 1
+// Return acoshl(x) = 0;
+//
+// 2. x < 1
+// Return acoshl(x) = Nan (Domain error, error handler call with tag 135);
+//
+// 3. x = [S,Q]Nan or +INF
+// Return acoshl(x) = x + x;
+//
+// 4. 'Near 1': 1 < x < 1+1/8
+// Return acoshl(x) = sqrtl(2*y)*(1-P(y)/Q(y)),
+// where y = 1, P(y)/Q(y) - rational approximation
+//
+// 5. 'Huges': x > 0.5*2^64
+// Return acoshl(x) = (logl(2*x-1));
+//
+// 6. 'Main path': 1+1/8 < x < 0.5*2^64
+// b_hi + b_lo = x + sqrt(x^2 - 1);
+// acoshl(x) = logl_special(b_hi, b_lo);
+//
+// Algorithm description
+//==============================================================
+//
+// I. Near 1 path algorithm
+// **************************************************************
+// The formula is acoshl(x) = sqrtl(2*y)*(1-P(y)/Q(y)),
+// where y = 1, P(y)/Q(y) - rational approximation
+//
+// 1) y = x - 1, y2 = 2 * y
+//
+// 2) Compute in parallel sqrtl(2*y) and P(y)/Q(y)
+// a) sqrtl computation method described below (main path algorithm, item 2))
+// As result we obtain (gg+gl) - multiprecision result
+// as pair of double extended values
+// b) P(y) and Q(y) calculated without any extra precision manipulations
+// c) P/Q division:
+// y = frcpa(Q) initial approximation of 1/Q
+// z = P*y initial approximation of P/Q
+//
+// e = 1 - b*y
+// e2 = e + e^2
+// e1 = e^2
+// y1 = y + y*e2 = y + y*(e+e^2)
+//
+// e3 = e + e1^2
+// y2 = y + y1*e3 = y + y*(e+e^2+..+e^6)
+//
+// r = P - Q*z
+// e = 1 - Q*y2
+// xx = z + r*y2 high part of a/b
+//
+// y3 = y2 + y2*e4
+// r1 = P - Q*xx
+// xl = r1*y3 low part of a/b
+//
+// 3) res = sqrt(2*y) - sqrt(2*y)*(P(y)/Q(y)) =
+// = (gg+gl) - (gg + gl)*(xx+xl);
+//
+// a) hh = gg*xx; hl = gg*xl; lh = gl*xx; ll = gl*xl;
+// b) res = ((((gl + ll) + lh) + hl) + hh) + gg;
+// (exactly in this order)
+//
+// II. Main path algorithm
+// ( thanks to Peter Markstein for the idea of sqrt(x^2+1) computation! )
+// **********************************************************************
+//
+// There are 3 parts of x+sqrt(x^2-1) computation:
+//
+// 1) m2 = (m2_hi+m2_lo) = x^2-1 obtaining
+// ------------------------------------
+// m2_hi = x2_hi - 1, where x2_hi = x * x;
+// m2_lo = x2_lo + p1_lo, where
+// x2_lo = FMS(x*x-x2_hi),
+// p1_lo = (1 + m2_hi) - x2_hi;
+//
+// 2) g = (g_hi+g_lo) = sqrt(m2) = sqrt(m2_hi+m2_lo)
+// ----------------------------------------------
+// r = invsqrt(m2_hi) (8-bit reciprocal square root approximation);
+// g = m2_hi * r (first 8 bit-approximation of sqrt);
+//
+// h = 0.5 * r;
+// e = 0.5 - g * h;
+// g = g * e + g (second 16 bit-approximation of sqrt);
+//
+// h = h * e + h;
+// e = 0.5 - g * h;
+// g = g * e + g (third 32 bit-approximation of sqrt);
+//
+// h = h * e + h;
+// e = 0.5 - g * h;
+// g_hi = g * e + g (fourth 64 bit-approximation of sqrt);
+//
+// Remainder computation:
+// h = h * e + h;
+// d = (m2_hi - g_hi * g_hi) + m2_lo;
+// g_lo = d * h;
+//
+// 3) b = (b_hi + b_lo) = x + g, where g = (g_hi + g_lo) = sqrt(x^2-1)
+// -------------------------------------------------------------------
+// b_hi = (g_hi + x) + gl;
+// b_lo = (x - b_hi) + g_hi + gl;
+//
+// Now we pass b presented as sum b_hi + b_lo to special version
+// of logl function which accept a pair of arguments as
+// mutiprecision value.
+//
+// Special log algorithm overview
+// ================================
+// Here we use a table lookup method. The basic idea is that in
+// order to compute logl(Arg) for an argument Arg in [1,2),
+// we construct a value G such that G*Arg is close to 1 and that
+// logl(1/G) is obtainable easily from a table of values calculated
+// beforehand. Thus
+//
+// logl(Arg) = logl(1/G) + logl((G*Arg - 1))
+//
+// Because |G*Arg - 1| is small, the second term on the right hand
+// side can be approximated by a short polynomial. We elaborate
+// this method in four steps.
+//
+// Step 0: Initialization
+//
+// We need to calculate logl( X+1 ). Obtain N, S_hi such that
+//
+// X = 2^N * ( S_hi + S_lo ) exactly
+//
+// where S_hi in [1,2) and S_lo is a correction to S_hi in the sense
+// that |S_lo| <= ulp(S_hi).
+//
+// For the special version of logl: S_lo = b_lo
+// !-----------------------------------------------!
+//
+// Step 1: Argument Reduction
+//
+// Based on S_hi, obtain G_1, G_2, G_3 from a table and calculate
+//
+// G := G_1 * G_2 * G_3
+// r := (G * S_hi - 1) + G * S_lo
+//
+// These G_j's have the property that the product is exactly
+// representable and that |r| < 2^(-12) as a result.
+//
+// Step 2: Approximation
+//
+// logl(1 + r) is approximated by a short polynomial poly(r).
+//
+// Step 3: Reconstruction
+//
+// Finally, logl( X ) = logl( X+1 ) is given by
+//
+// logl( X ) = logl( 2^N * (S_hi + S_lo) )
+// ~=~ N*logl(2) + logl(1/G) + logl(1 + r)
+// ~=~ N*logl(2) + logl(1/G) + poly(r).
+//
+// For detailed description see logl or log1pl function, regular path.
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f32 -> f95 (64 registers)
+
+// General registers used:
+// r32 -> r67 (36 registers)
+
+// Predicate registers used:
+// p7 -> p11
+// p7 for 'NaNs, Inf' path
+// p8 for 'near 1' path
+// p9 for 'huges' path
+// p10 for x = 1
+// p11 for x < 1
+//
+//*********************************************************************
+// IEEE Special Conditions:
+//
+// acoshl(+inf) = +inf
+// acoshl(-inf) = QNaN
+// acoshl(1) = 0
+// acoshl(x<1) = QNaN
+// acoshl(SNaN) = QNaN
+// acoshl(QNaN) = QNaN
+//
+
+// Data tables
+//==============================================================
+
+RODATA
+.align 64
+
+// Near 1 path rational aproximation coefficients
+LOCAL_OBJECT_START(Poly_P)
+data8 0xB0978143F695D40F, 0x3FF1 // .84205539791447100108478906277453574946e-4
+data8 0xB9800D841A8CAD29, 0x3FF6 // .28305085180397409672905983082168721069e-2
+data8 0xC889F455758C1725, 0x3FF9 // .24479844297887530847660233111267222945e-1
+data8 0x9BE1DFF006F45F12, 0x3FFB // .76114415657565879842941751209926938306e-1
+data8 0x9E34AF4D372861E0, 0x3FFB // .77248925727776366270605984806795850504e-1
+data8 0xF3DC502AEE14C4AE, 0x3FA6 // .3077953476682583606615438814166025592e-26
+LOCAL_OBJECT_END(Poly_P)
+
+//
+LOCAL_OBJECT_START(Poly_Q)
+data8 0xF76E3FD3C7680357, 0x3FF1 // .11798413344703621030038719253730708525e-3
+data8 0xD107D2E7273263AE, 0x3FF7 // .63791065024872525660782716786703188820e-2
+data8 0xB609BE5CDE206AEF, 0x3FFB // .88885771950814004376363335821980079985e-1
+data8 0xF7DEACAC28067C8A, 0x3FFD // .48412074662702495416825113623936037072302
+data8 0x8F9BE5890CEC7E38, 0x3FFF // 1.1219450873557867470217771071068369729526
+data8 0xED4F06F3D2BC92D1, 0x3FFE // .92698710873331639524734537734804056798748
+LOCAL_OBJECT_END(Poly_Q)
+
+// Q coeffs
+LOCAL_OBJECT_START(Constants_Q)
+data4 0x00000000,0xB1721800,0x00003FFE,0x00000000
+data4 0x4361C4C6,0x82E30865,0x0000BFE2,0x00000000
+data4 0x328833CB,0xCCCCCAF2,0x00003FFC,0x00000000
+data4 0xA9D4BAFB,0x80000077,0x0000BFFD,0x00000000
+data4 0xAAABE3D2,0xAAAAAAAA,0x00003FFD,0x00000000
+data4 0xFFFFDAB7,0xFFFFFFFF,0x0000BFFD,0x00000000
+LOCAL_OBJECT_END(Constants_Q)
+
+// Z1 - 16 bit fixed
+LOCAL_OBJECT_START(Constants_Z_1)
+data4 0x00008000
+data4 0x00007879
+data4 0x000071C8
+data4 0x00006BCB
+data4 0x00006667
+data4 0x00006187
+data4 0x00005D18
+data4 0x0000590C
+data4 0x00005556
+data4 0x000051EC
+data4 0x00004EC5
+data4 0x00004BDB
+data4 0x00004925
+data4 0x0000469F
+data4 0x00004445
+data4 0x00004211
+LOCAL_OBJECT_END(Constants_Z_1)
+
+// G1 and H1 - IEEE single and h1 - IEEE double
+LOCAL_OBJECT_START(Constants_G_H_h1)
+data4 0x3F800000,0x00000000
+data8 0x0000000000000000
+data4 0x3F70F0F0,0x3D785196
+data8 0x3DA163A6617D741C
+data4 0x3F638E38,0x3DF13843
+data8 0x3E2C55E6CBD3D5BB
+data4 0x3F579430,0x3E2FF9A0
+data8 0xBE3EB0BFD86EA5E7
+data4 0x3F4CCCC8,0x3E647FD6
+data8 0x3E2E6A8C86B12760
+data4 0x3F430C30,0x3E8B3AE7
+data8 0x3E47574C5C0739BA
+data4 0x3F3A2E88,0x3EA30C68
+data8 0x3E20E30F13E8AF2F
+data4 0x3F321640,0x3EB9CEC8
+data8 0xBE42885BF2C630BD
+data4 0x3F2AAAA8,0x3ECF9927
+data8 0x3E497F3497E577C6
+data4 0x3F23D708,0x3EE47FC5
+data8 0x3E3E6A6EA6B0A5AB
+data4 0x3F1D89D8,0x3EF8947D
+data8 0xBDF43E3CD328D9BE
+data4 0x3F17B420,0x3F05F3A1
+data8 0x3E4094C30ADB090A
+data4 0x3F124920,0x3F0F4303
+data8 0xBE28FBB2FC1FE510
+data4 0x3F0D3DC8,0x3F183EBF
+data8 0x3E3A789510FDE3FA
+data4 0x3F088888,0x3F20EC80
+data8 0x3E508CE57CC8C98F
+data4 0x3F042108,0x3F29516A
+data8 0xBE534874A223106C
+LOCAL_OBJECT_END(Constants_G_H_h1)
+
+// Z2 - 16 bit fixed
+LOCAL_OBJECT_START(Constants_Z_2)
+data4 0x00008000
+data4 0x00007F81
+data4 0x00007F02
+data4 0x00007E85
+data4 0x00007E08
+data4 0x00007D8D
+data4 0x00007D12
+data4 0x00007C98
+data4 0x00007C20
+data4 0x00007BA8
+data4 0x00007B31
+data4 0x00007ABB
+data4 0x00007A45
+data4 0x000079D1
+data4 0x0000795D
+data4 0x000078EB
+LOCAL_OBJECT_END(Constants_Z_2)
+
+// G2 and H2 - IEEE single and h2 - IEEE double
+LOCAL_OBJECT_START(Constants_G_H_h2)
+data4 0x3F800000,0x00000000
+data8 0x0000000000000000
+data4 0x3F7F00F8,0x3B7F875D
+data8 0x3DB5A11622C42273
+data4 0x3F7E03F8,0x3BFF015B
+data8 0x3DE620CF21F86ED3
+data4 0x3F7D08E0,0x3C3EE393
+data8 0xBDAFA07E484F34ED
+data4 0x3F7C0FC0,0x3C7E0586
+data8 0xBDFE07F03860BCF6
+data4 0x3F7B1880,0x3C9E75D2
+data8 0x3DEA370FA78093D6
+data4 0x3F7A2328,0x3CBDC97A
+data8 0x3DFF579172A753D0
+data4 0x3F792FB0,0x3CDCFE47
+data8 0x3DFEBE6CA7EF896B
+data4 0x3F783E08,0x3CFC15D0
+data8 0x3E0CF156409ECB43
+data4 0x3F774E38,0x3D0D874D
+data8 0xBE0B6F97FFEF71DF
+data4 0x3F766038,0x3D1CF49B
+data8 0xBE0804835D59EEE8
+data4 0x3F757400,0x3D2C531D
+data8 0x3E1F91E9A9192A74
+data4 0x3F748988,0x3D3BA322
+data8 0xBE139A06BF72A8CD
+data4 0x3F73A0D0,0x3D4AE46F
+data8 0x3E1D9202F8FBA6CF
+data4 0x3F72B9D0,0x3D5A1756
+data8 0xBE1DCCC4BA796223
+data4 0x3F71D488,0x3D693B9D
+data8 0xBE049391B6B7C239
+LOCAL_OBJECT_END(Constants_G_H_h2)
+
+// G3 and H3 - IEEE single and h3 - IEEE double
+LOCAL_OBJECT_START(Constants_G_H_h3)
+data4 0x3F7FFC00,0x38800100
+data8 0x3D355595562224CD
+data4 0x3F7FF400,0x39400480
+data8 0x3D8200A206136FF6
+data4 0x3F7FEC00,0x39A00640
+data8 0x3DA4D68DE8DE9AF0
+data4 0x3F7FE400,0x39E00C41
+data8 0xBD8B4291B10238DC
+data4 0x3F7FDC00,0x3A100A21
+data8 0xBD89CCB83B1952CA
+data4 0x3F7FD400,0x3A300F22
+data8 0xBDB107071DC46826
+data4 0x3F7FCC08,0x3A4FF51C
+data8 0x3DB6FCB9F43307DB
+data4 0x3F7FC408,0x3A6FFC1D
+data8 0xBD9B7C4762DC7872
+data4 0x3F7FBC10,0x3A87F20B
+data8 0xBDC3725E3F89154A
+data4 0x3F7FB410,0x3A97F68B
+data8 0xBD93519D62B9D392
+data4 0x3F7FAC18,0x3AA7EB86
+data8 0x3DC184410F21BD9D
+data4 0x3F7FA420,0x3AB7E101
+data8 0xBDA64B952245E0A6
+data4 0x3F7F9C20,0x3AC7E701
+data8 0x3DB4B0ECAABB34B8
+data4 0x3F7F9428,0x3AD7DD7B
+data8 0x3D9923376DC40A7E
+data4 0x3F7F8C30,0x3AE7D474
+data8 0x3DC6E17B4F2083D3
+data4 0x3F7F8438,0x3AF7CBED
+data8 0x3DAE314B811D4394
+data4 0x3F7F7C40,0x3B03E1F3
+data8 0xBDD46F21B08F2DB1
+data4 0x3F7F7448,0x3B0BDE2F
+data8 0xBDDC30A46D34522B
+data4 0x3F7F6C50,0x3B13DAAA
+data8 0x3DCB0070B1F473DB
+data4 0x3F7F6458,0x3B1BD766
+data8 0xBDD65DDC6AD282FD
+data4 0x3F7F5C68,0x3B23CC5C
+data8 0xBDCDAB83F153761A
+data4 0x3F7F5470,0x3B2BC997
+data8 0xBDDADA40341D0F8F
+data4 0x3F7F4C78,0x3B33C711
+data8 0x3DCD1BD7EBC394E8
+data4 0x3F7F4488,0x3B3BBCC6
+data8 0xBDC3532B52E3E695
+data4 0x3F7F3C90,0x3B43BAC0
+data8 0xBDA3961EE846B3DE
+data4 0x3F7F34A0,0x3B4BB0F4
+data8 0xBDDADF06785778D4
+data4 0x3F7F2CA8,0x3B53AF6D
+data8 0x3DCC3ED1E55CE212
+data4 0x3F7F24B8,0x3B5BA620
+data8 0xBDBA31039E382C15
+data4 0x3F7F1CC8,0x3B639D12
+data8 0x3D635A0B5C5AF197
+data4 0x3F7F14D8,0x3B6B9444
+data8 0xBDDCCB1971D34EFC
+data4 0x3F7F0CE0,0x3B7393BC
+data8 0x3DC7450252CD7ADA
+data4 0x3F7F04F0,0x3B7B8B6D
+data8 0xBDB68F177D7F2A42
+LOCAL_OBJECT_END(Constants_G_H_h3)
+
+// Assembly macros
+//==============================================================
+
+// Floating Point Registers
+
+FR_Arg = f8
+FR_Res = f8
+
+
+FR_PP0 = f32
+FR_PP1 = f33
+FR_PP2 = f34
+FR_PP3 = f35
+FR_PP4 = f36
+FR_PP5 = f37
+FR_QQ0 = f38
+FR_QQ1 = f39
+FR_QQ2 = f40
+FR_QQ3 = f41
+FR_QQ4 = f42
+FR_QQ5 = f43
+
+FR_Q1 = f44
+FR_Q2 = f45
+FR_Q3 = f46
+FR_Q4 = f47
+
+FR_Half = f48
+FR_Two = f49
+
+FR_log2_hi = f50
+FR_log2_lo = f51
+
+
+FR_X2 = f52
+FR_M2 = f53
+FR_M2L = f54
+FR_Rcp = f55
+FR_GG = f56
+FR_HH = f57
+FR_EE = f58
+FR_DD = f59
+FR_GL = f60
+FR_Tmp = f61
+
+
+FR_XM1 = f62
+FR_2XM1 = f63
+FR_XM12 = f64
+
+
+
+ // Special logl registers
+FR_XLog_Hi = f65
+FR_XLog_Lo = f66
+
+FR_Y_hi = f67
+FR_Y_lo = f68
+
+FR_S_hi = f69
+FR_S_lo = f70
+
+FR_poly_lo = f71
+FR_poly_hi = f72
+
+FR_G = f73
+FR_H = f74
+FR_h = f75
+
+FR_G2 = f76
+FR_H2 = f77
+FR_h2 = f78
+
+FR_r = f79
+FR_rsq = f80
+FR_rcub = f81
+
+FR_float_N = f82
+
+FR_G3 = f83
+FR_H3 = f84
+FR_h3 = f85
+
+FR_2_to_minus_N = f86
+
+
+ // Near 1 registers
+FR_PP = f65
+FR_QQ = f66
+
+
+FR_PV6 = f69
+FR_PV4 = f70
+FR_PV3 = f71
+FR_PV2 = f72
+
+FR_QV6 = f73
+FR_QV4 = f74
+FR_QV3 = f75
+FR_QV2 = f76
+
+FR_Y0 = f77
+FR_Q0 = f78
+FR_E0 = f79
+FR_E2 = f80
+FR_E1 = f81
+FR_Y1 = f82
+FR_E3 = f83
+FR_Y2 = f84
+FR_R0 = f85
+FR_E4 = f86
+FR_Y3 = f87
+FR_R1 = f88
+FR_X_Hi = f89
+FR_X_lo = f90
+
+FR_HH = f91
+FR_LL = f92
+FR_HL = f93
+FR_LH = f94
+
+
+
+ // Error handler registers
+FR_Arg_X = f95
+FR_Arg_Y = f0
+
+
+// General Purpose Registers
+
+ // General prolog registers
+GR_PFS = r32
+GR_OneP125 = r33
+GR_TwoP63 = r34
+GR_Arg = r35
+GR_Half = r36
+
+ // Near 1 path registers
+GR_Poly_P = r37
+GR_Poly_Q = r38
+
+ // Special logl registers
+GR_Index1 = r39
+GR_Index2 = r40
+GR_signif = r41
+GR_X_0 = r42
+GR_X_1 = r43
+GR_X_2 = r44
+GR_minus_N = r45
+GR_Z_1 = r46
+GR_Z_2 = r47
+GR_N = r48
+GR_Bias = r49
+GR_M = r50
+GR_Index3 = r51
+GR_exp_2tom80 = r52
+GR_exp_mask = r53
+GR_exp_2tom7 = r54
+GR_ad_ln10 = r55
+GR_ad_tbl_1 = r56
+GR_ad_tbl_2 = r57
+GR_ad_tbl_3 = r58
+GR_ad_q = r59
+GR_ad_z_1 = r60
+GR_ad_z_2 = r61
+GR_ad_z_3 = r62
+
+//
+// Added for unwind support
+//
+GR_SAVE_PFS = r32
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+
+GR_Parameter_X = r64
+GR_Parameter_Y = r65
+GR_Parameter_RESULT = r66
+GR_Parameter_TAG = r67
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(acoshl)
+
+{ .mfi
+ alloc GR_PFS = ar.pfs,0,32,4,0 // Local frame allocation
+ fcmp.lt.s1 p11, p0 = FR_Arg, f1 // if arg is less than 1
+ mov GR_Half = 0xfffe // 0.5's exp
+}
+{ .mfi
+ addl GR_Poly_Q = @ltoff(Poly_Q), gp // Address of Q-coeff table
+ fma.s1 FR_X2 = FR_Arg, FR_Arg, f0 // Obtain x^2
+ addl GR_Poly_P = @ltoff(Poly_P), gp // Address of P-coeff table
+};;
+
+{ .mfi
+ getf.d GR_Arg = FR_Arg // get arument as double (int64)
+ fma.s0 FR_Two = f1, f1, f1 // construct 2.0
+ addl GR_ad_z_1 = @ltoff(Constants_Z_1#),gp // logl tables
+}
+{ .mlx
+ nop.m 0
+ movl GR_TwoP63 = 0x43E8000000000000 // 0.5*2^63 (huge arguments)
+};;
+
+{ .mfi
+ ld8 GR_Poly_P = [GR_Poly_P] // get actual P-coeff table address
+ fcmp.eq.s1 p10, p0 = FR_Arg, f1 // if arg == 1 (return 0)
+ nop.i 0
+}
+{ .mlx
+ ld8 GR_Poly_Q = [GR_Poly_Q] // get actual Q-coeff table address
+ movl GR_OneP125 = 0x3FF2000000000000 // 1.125 (near 1 path bound)
+};;
+
+{ .mfi
+ ld8 GR_ad_z_1 = [GR_ad_z_1] // Get pointer to Constants_Z_1
+ fclass.m p7,p0 = FR_Arg, 0xe3 // if arg NaN inf
+ cmp.le p9, p0 = GR_TwoP63, GR_Arg // if arg > 0.5*2^63 ('huges')
+}
+{ .mfb
+ cmp.ge p8, p0 = GR_OneP125, GR_Arg // if arg<1.125 -near 1 path
+ fms.s1 FR_XM1 = FR_Arg, f1, f1 // X0 = X-1 (for near 1 path)
+(p11) br.cond.spnt acoshl_lt_pone // error branch (less than 1)
+};;
+
+{ .mmi
+ setf.exp FR_Half = GR_Half // construct 0.5
+(p9) setf.s FR_XLog_Lo = r0 // Low of logl arg=0 (Huges path)
+ mov GR_exp_mask = 0x1FFFF // Create exponent mask
+};;
+
+{ .mmf
+(p8) ldfe FR_PP5 = [GR_Poly_P],16 // Load P5
+(p8) ldfe FR_QQ5 = [GR_Poly_Q],16 // Load Q5
+ fms.s1 FR_M2 = FR_X2, f1, f1 // m2 = x^2 - 1
+};;
+
+{ .mfi
+(p8) ldfe FR_QQ4 = [GR_Poly_Q],16 // Load Q4
+ fms.s1 FR_M2L = FR_Arg, FR_Arg, FR_X2 // low part of
+ // m2 = fma(X*X - m2)
+ add GR_ad_tbl_1 = 0x040, GR_ad_z_1 // Point to Constants_G_H_h1
+}
+{ .mfb
+(p8) ldfe FR_PP4 = [GR_Poly_P],16 // Load P4
+(p7) fma.s0 FR_Res = FR_Arg,f1,FR_Arg // r = a + a (Nan, Inf)
+(p7) br.ret.spnt b0 // return (Nan, Inf)
+};;
+
+{ .mfi
+(p8) ldfe FR_PP3 = [GR_Poly_P],16 // Load P3
+ nop.f 0
+ add GR_ad_q = -0x60, GR_ad_z_1 // Point to Constants_P
+}
+{ .mfb
+(p8) ldfe FR_QQ3 = [GR_Poly_Q],16 // Load Q3
+(p9) fms.s1 FR_XLog_Hi = FR_Two, FR_Arg, f1 // Hi of log arg = 2*X-1
+(p9) br.cond.spnt huges_logl // special version of log
+}
+;;
+
+{ .mfi
+(p8) ldfe FR_PP2 = [GR_Poly_P],16 // Load P2
+(p8) fma.s1 FR_2XM1 = FR_Two, FR_XM1, f0 // 2X0 = 2 * X0
+ add GR_ad_z_2 = 0x140, GR_ad_z_1 // Point to Constants_Z_2
+}
+{ .mfb
+(p8) ldfe FR_QQ2 = [GR_Poly_Q],16 // Load Q2
+(p10) fma.s0 FR_Res = f0,f1,f0 // r = 0 (arg = 1)
+(p10) br.ret.spnt b0 // return (arg = 1)
+};;
+
+{ .mmi
+(p8) ldfe FR_PP1 = [GR_Poly_P],16 // Load P1
+(p8) ldfe FR_QQ1 = [GR_Poly_Q],16 // Load Q1
+ add GR_ad_tbl_2 = 0x180, GR_ad_z_1 // Point to Constants_G_H_h2
+}
+;;
+
+{ .mfi
+(p8) ldfe FR_PP0 = [GR_Poly_P] // Load P0
+ fma.s1 FR_Tmp = f1, f1, FR_M2 // Tmp = 1 + m2
+ add GR_ad_tbl_3 = 0x280, GR_ad_z_1 // Point to Constants_G_H_h3
+}
+{ .mfb
+(p8) ldfe FR_QQ0 = [GR_Poly_Q]
+ nop.f 0
+(p8) br.cond.spnt near_1 // near 1 path
+};;
+{ .mfi
+ ldfe FR_log2_hi = [GR_ad_q],16 // Load log2_hi
+ nop.f 0
+ mov GR_Bias = 0x0FFFF // Create exponent bias
+};;
+{ .mfi
+ nop.m 0
+ frsqrta.s1 FR_Rcp, p0 = FR_M2 // Rcp = 1/m2 reciprocal appr.
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_log2_lo = [GR_ad_q],16 // Load log2_lo
+ fms.s1 FR_Tmp = FR_X2, f1, FR_Tmp // Tmp = x^2 - Tmp
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_Q4 = [GR_ad_q],16 // Load Q4
+ fma.s1 FR_GG = FR_Rcp, FR_M2, f0 // g = Rcp * m2
+ // 8 bit Newton Raphson iteration
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_Half, FR_Rcp, f0 // h = 0.5 * Rcp
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_Q3 = [GR_ad_q],16 // Load Q3
+ fnma.s1 FR_EE = FR_GG, FR_HH, FR_Half // e = 0.5 - g * h
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_M2L = FR_Tmp, f1, FR_M2L // low part of m2 = Tmp+m2l
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_Q2 = [GR_ad_q],16 // Load Q2
+ fma.s1 FR_GG = FR_GG, FR_EE, FR_GG // g = g * e + g
+ // 16 bit Newton Raphson iteration
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_HH, FR_EE, FR_HH // h = h * e + h
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_Q1 = [GR_ad_q] // Load Q1
+ fnma.s1 FR_EE = FR_GG, FR_HH, FR_Half // e = 0.5 - g * h
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_GG = FR_GG, FR_EE, FR_GG // g = g * e + g
+ // 32 bit Newton Raphson iteration
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_HH, FR_EE, FR_HH // h = h * e + h
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_EE = FR_GG, FR_HH, FR_Half // e = 0.5 - g * h
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_GG = FR_GG, FR_EE, FR_GG // g = g * e + g
+ // 64 bit Newton Raphson iteration
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_HH, FR_EE, FR_HH // h = h * e + h
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_DD = FR_GG, FR_GG, FR_M2 // Remainder d = g * g - p2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_XLog_Hi = FR_Arg, f1, FR_GG // bh = z + gh
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_DD = FR_DD, f1, FR_M2L // add p2l: d = d + p2l
+ nop.i 0
+};;
+
+{ .mfi
+ getf.sig GR_signif = FR_XLog_Hi // Get significand of x+1
+ nop.f 0
+ mov GR_exp_2tom7 = 0x0fff8 // Exponent of 2^-7
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_GL = FR_DD, FR_HH, f0 // gl = d * h
+ extr.u GR_Index1 = GR_signif, 59, 4 // Get high 4 bits of signif
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_XLog_Hi = FR_DD, FR_HH, FR_XLog_Hi // bh = bh + gl
+ nop.i 0
+};;
+
+
+
+{ .mmi
+ shladd GR_ad_z_1 = GR_Index1, 2, GR_ad_z_1 // Point to Z_1
+ shladd GR_ad_tbl_1 = GR_Index1, 4, GR_ad_tbl_1 // Point to G_1
+ extr.u GR_X_0 = GR_signif, 49, 15 // Get high 15 bits of signif.
+};;
+
+{ .mmi
+ ld4 GR_Z_1 = [GR_ad_z_1] // Load Z_1
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfps FR_G, FR_H = [GR_ad_tbl_1],8 // Load G_1, H_1
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_XLog_Lo = FR_Arg, f1, FR_XLog_Hi // bl = x - bh
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15 // Get bits 30-15 of X_0 * Z_1
+};;
+
+// WE CANNOT USE GR_X_1 IN NEXT 3 CYCLES BECAUSE OF POSSIBLE 10 CLOCKS STALL!
+// "DEAD" ZONE!
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmerge.se FR_S_hi = f1,FR_XLog_Hi // Form |x+1|
+ nop.i 0
+};;
+
+
+{ .mmi
+ getf.exp GR_N = FR_XLog_Hi // Get N = exponent of x+1
+ ldfd FR_h = [GR_ad_tbl_1] // Load h_1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract bits 6-9 of X_1
+};;
+
+{ .mfi
+ shladd GR_ad_tbl_2 = GR_Index2, 4, GR_ad_tbl_2 // Point to G_2
+ fma.s1 FR_XLog_Lo = FR_XLog_Lo, f1, FR_GG // bl = bl + gg
+ mov GR_exp_2tom80 = 0x0ffaf // Exponent of 2^-80
+}
+{ .mfi
+ shladd GR_ad_z_2 = GR_Index2, 2, GR_ad_z_2 // Point to Z_2
+ nop.f 0
+ sub GR_N = GR_N, GR_Bias // sub bias from exp
+};;
+
+{ .mmi
+ ldfps FR_G2, FR_H2 = [GR_ad_tbl_2],8 // Load G_2, H_2
+ ld4 GR_Z_2 = [GR_ad_z_2] // Load Z_2
+ sub GR_minus_N = GR_Bias, GR_N // Form exponent of 2^(-N)
+};;
+
+{ .mmi
+ ldfd FR_h2 = [GR_ad_tbl_2] // Load h_2
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ setf.sig FR_float_N = GR_N // Put integer N into rightmost sign
+ setf.exp FR_2_to_minus_N = GR_minus_N // Form 2^(-N)
+ pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15 // Get bits 30-15 of X_1 * Z_2
+};;
+
+// WE CANNOT USE GR_X_2 IN NEXT 3 CYCLES ("DEAD" ZONE!)
+// BECAUSE OF POSSIBLE 10 CLOCKS STALL!
+// (Just nops added - nothing to do here)
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_XLog_Lo = FR_XLog_Lo, f1, FR_GL // bl = bl + gl
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ extr.u GR_Index3 = GR_X_2, 1, 5 // Extract bits 1-5 of X_2
+};;
+
+{ .mfi
+ shladd GR_ad_tbl_3 = GR_Index3, 4, GR_ad_tbl_3 // Point to G_3
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfps FR_G3, FR_H3 = [GR_ad_tbl_3],8 // Load G_3, H_3
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfd FR_h3 = [GR_ad_tbl_3] // Load h_3
+ fcvt.xf FR_float_N = FR_float_N
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_G = FR_G, FR_G2 // G = G_1 * G_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H2 // H = H_1 + H_2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_h = FR_h, FR_h2 // h = h_1 + h_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S_lo = FR_XLog_Lo, FR_2_to_minus_N, f0 //S_lo=S_lo*2^(-N)
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_G = FR_G, FR_G3 // G = (G_1 * G_2) * G_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H3 // H = (H_1 + H_2) + H_3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_h = FR_h, FR_h3 // h = (h_1 + h_2) + h_3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r = FR_G, FR_S_hi, f1 // r = G * S_hi - 1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Y_hi = FR_float_N, FR_log2_hi, FR_H // Y_hi=N*log2_hi+H
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_h = FR_float_N, FR_log2_lo, FR_h // h=N*log2_lo+h
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r = FR_G, FR_S_lo, FR_r // r=G*S_lo+(G*S_hi-1)
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_lo = FR_r, FR_Q4, FR_Q3 // poly_lo = r * Q4 + Q3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_r, FR_Q2 // poly_lo=poly_lo*r+Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rcub = FR_rsq, FR_r, f0 // rcub = r^3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r // poly_hi = Q1*rsq + r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h//poly_lo=poly_lo*r^3+h
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fadd.s0 FR_Y_lo = FR_poly_hi, FR_poly_lo
+ // Y_lo=poly_hi+poly_lo
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ fadd.s0 FR_Res = FR_Y_lo,FR_Y_hi // Result=Y_lo+Y_hi
+ br.ret.sptk b0 // Common exit for 2^-7 < x < inf
+};;
+
+
+huges_logl:
+{ .mmi
+ getf.sig GR_signif = FR_XLog_Hi // Get significand of x+1
+ mov GR_exp_2tom7 = 0x0fff8 // Exponent of 2^-7
+ nop.i 0
+};;
+
+{ .mfi
+ add GR_ad_tbl_1 = 0x040, GR_ad_z_1 // Point to Constants_G_H_h1
+ nop.f 0
+ add GR_ad_q = -0x60, GR_ad_z_1 // Point to Constants_P
+}
+{ .mfi
+ add GR_ad_z_2 = 0x140, GR_ad_z_1 // Point to Constants_Z_2
+ nop.f 0
+ add GR_ad_tbl_2 = 0x180, GR_ad_z_1 // Point to Constants_G_H_h2
+};;
+
+{ .mfi
+ add GR_ad_tbl_3 = 0x280, GR_ad_z_1 // Point to Constants_G_H_h3
+ nop.f 0
+ extr.u GR_Index1 = GR_signif, 59, 4 // Get high 4 bits of signif
+};;
+
+{ .mfi
+ shladd GR_ad_z_1 = GR_Index1, 2, GR_ad_z_1 // Point to Z_1
+ nop.f 0
+ extr.u GR_X_0 = GR_signif, 49, 15 // Get high 15 bits of signif.
+};;
+
+{ .mfi
+ ld4 GR_Z_1 = [GR_ad_z_1] // Load Z_1
+ nop.f 0
+ mov GR_exp_mask = 0x1FFFF // Create exponent mask
+}
+{ .mfi
+ shladd GR_ad_tbl_1 = GR_Index1, 4, GR_ad_tbl_1 // Point to G_1
+ nop.f 0
+ mov GR_Bias = 0x0FFFF // Create exponent bias
+};;
+
+{ .mfi
+ ldfps FR_G, FR_H = [GR_ad_tbl_1],8 // Load G_1, H_1
+ fmerge.se FR_S_hi = f1,FR_XLog_Hi // Form |x|
+ nop.i 0
+};;
+
+{ .mmi
+ getf.exp GR_N = FR_XLog_Hi // Get N = exponent of x+1
+ ldfd FR_h = [GR_ad_tbl_1] // Load h_1
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_log2_hi = [GR_ad_q],16 // Load log2_hi
+ nop.f 0
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15 // Get bits 30-15 of X_0 * Z_1
+};;
+
+{ .mmi
+ ldfe FR_log2_lo = [GR_ad_q],16 // Load log2_lo
+ sub GR_N = GR_N, GR_Bias
+ mov GR_exp_2tom80 = 0x0ffaf // Exponent of 2^-80
+};;
+
+{ .mfi
+ ldfe FR_Q4 = [GR_ad_q],16 // Load Q4
+ nop.f 0
+ sub GR_minus_N = GR_Bias, GR_N // Form exponent of 2^(-N)
+};;
+
+{ .mmf
+ ldfe FR_Q3 = [GR_ad_q],16 // Load Q3
+ setf.sig FR_float_N = GR_N // Put integer N into rightmost sign
+ nop.f 0
+};;
+
+{ .mmi
+ ldfe FR_Q2 = [GR_ad_q],16 // Load Q2
+ nop.m 0
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract bits 6-9 of X_1
+};;
+
+{ .mmi
+ ldfe FR_Q1 = [GR_ad_q] // Load Q1
+ shladd GR_ad_z_2 = GR_Index2, 2, GR_ad_z_2 // Point to Z_2
+ nop.i 0
+};;
+
+{ .mmi
+ ld4 GR_Z_2 = [GR_ad_z_2] // Load Z_2
+ shladd GR_ad_tbl_2 = GR_Index2, 4, GR_ad_tbl_2 // Point to G_2
+ nop.i 0
+};;
+
+{ .mmi
+ ldfps FR_G2, FR_H2 = [GR_ad_tbl_2],8 // Load G_2, H_2
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmf
+ ldfd FR_h2 = [GR_ad_tbl_2] // Load h_2
+ setf.exp FR_2_to_minus_N = GR_minus_N // Form 2^(-N)
+ nop.f 0
+};;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15 // Get bits 30-15 of X_1*Z_2
+};;
+
+// WE CANNOT USE GR_X_2 IN NEXT 3 CYCLES ("DEAD" ZONE!)
+// BECAUSE OF POSSIBLE 10 CLOCKS STALL!
+// (Just nops added - nothing to do here)
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ extr.u GR_Index3 = GR_X_2, 1, 5 // Extract bits 1-5 of X_2
+};;
+
+{ .mfi
+ shladd GR_ad_tbl_3 = GR_Index3, 4, GR_ad_tbl_3 // Point to G_3
+ fcvt.xf FR_float_N = FR_float_N
+ nop.i 0
+};;
+
+{ .mfi
+ ldfps FR_G3, FR_H3 = [GR_ad_tbl_3],8 // Load G_3, H_3
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfd FR_h3 = [GR_ad_tbl_3] // Load h_3
+ fmpy.s1 FR_G = FR_G, FR_G2 // G = G_1 * G_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H2 // H = H_1 + H_2
+ nop.i 0
+};;
+
+{ .mmf
+ nop.m 0
+ nop.m 0
+ fadd.s1 FR_h = FR_h, FR_h2 // h = h_1 + h_2
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_G = FR_G, FR_G3 // G = (G_1 * G_2)*G_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H3 // H = (H_1 + H_2)+H_3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_h = FR_h, FR_h3 // h = (h_1 + h_2) + h_3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r = FR_G, FR_S_hi, f1 // r = G * S_hi - 1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Y_hi = FR_float_N, FR_log2_hi, FR_H // Y_hi=N*log2_hi+H
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_h = FR_float_N, FR_log2_lo, FR_h // h = N*log2_lo+h
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_lo = FR_r, FR_Q4, FR_Q3 // poly_lo = r * Q4 + Q3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_r, FR_Q2 // poly_lo=poly_lo*r+Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rcub = FR_rsq, FR_r, f0 // rcub = r^3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r // poly_hi = Q1*rsq + r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h//poly_lo=poly_lo*r^3+h
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fadd.s0 FR_Y_lo = FR_poly_hi, FR_poly_lo // Y_lo=poly_hi+poly_lo
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ fadd.s0 FR_Res = FR_Y_lo,FR_Y_hi // Result=Y_lo+Y_hi
+ br.ret.sptk b0 // Common exit
+};;
+
+
+// NEAR ONE INTERVAL
+near_1:
+{ .mfi
+ nop.m 0
+ frsqrta.s1 FR_Rcp, p0 = FR_2XM1 // Rcp = 1/x reciprocal appr. &SQRT&
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PV6 = FR_PP5, FR_XM1, FR_PP4 // pv6 = P5*xm1+P4 $POLY$
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_QV6 = FR_QQ5, FR_XM1, FR_QQ4 // qv6 = Q5*xm1+Q4 $POLY$
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PV4 = FR_PP3, FR_XM1, FR_PP2 // pv4 = P3*xm1+P2 $POLY$
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_QV4 = FR_QQ3, FR_XM1, FR_QQ2 // qv4 = Q3*xm1+Q2 $POLY$
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_XM12 = FR_XM1, FR_XM1, f0 // xm1^2 = xm1 * xm1 $POLY$
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PV2 = FR_PP1, FR_XM1, FR_PP0 // pv2 = P1*xm1+P0 $POLY$
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_QV2 = FR_QQ1, FR_XM1, FR_QQ0 // qv2 = Q1*xm1+Q0 $POLY$
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_GG = FR_Rcp, FR_2XM1, f0 // g = Rcp * x &SQRT&
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_Half, FR_Rcp, f0 // h = 0.5 * Rcp &SQRT&
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PV3 = FR_XM12, FR_PV6, FR_PV4//pv3=pv6*xm1^2+pv4 $POLY$
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_QV3 = FR_XM12, FR_QV6, FR_QV4//qv3=qv6*xm1^2+qv4 $POLY$
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_EE = FR_GG, FR_HH, FR_Half // e = 0.5 - g * h &SQRT&
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PP = FR_XM12, FR_PV3, FR_PV2 //pp=pv3*xm1^2+pv2 $POLY$
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_QQ = FR_XM12, FR_QV3, FR_QV2 //qq=qv3*xm1^2+qv2 $POLY$
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_GG = FR_GG, FR_EE, FR_GG // g = g * e + g &SQRT&
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_HH, FR_EE, FR_HH // h = h * e + h &SQRT&
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ frcpa.s1 FR_Y0,p0 = f1,FR_QQ // y = frcpa(b) #DIV#
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_EE = FR_GG, FR_HH, FR_Half // e = 0.5 - g*h &SQRT&
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Q0 = FR_PP,FR_Y0,f0 // q = a*y #DIV#
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_E0 = FR_Y0,FR_QQ,f1 // e = 1 - b*y #DIV#
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_GG = FR_GG, FR_EE, FR_GG // g = g * e + g &SQRT&
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_HH, FR_EE, FR_HH // h = h * e + h &SQRT&
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_E2 = FR_E0,FR_E0,FR_E0 // e2 = e+e^2 #DIV#
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_E1 = FR_E0,FR_E0,f0 // e1 = e^2 #DIV#
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_EE = FR_GG, FR_HH, FR_Half // e = 0.5 - g * h &SQRT&
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_DD = FR_GG, FR_GG, FR_2XM1 // d = x - g * g &SQRT&
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Y1 = FR_Y0,FR_E2,FR_Y0 // y1 = y+y*e2 #DIV#
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_E3 = FR_E1,FR_E1,FR_E0 // e3 = e+e1^2 #DIV#
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_GG = FR_DD, FR_HH, FR_GG // g = d * h + g &SQRT&
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_HH, FR_EE, FR_HH // h = h * e + h &SQRT&
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Y2 = FR_Y1,FR_E3,FR_Y0 // y2 = y+y1*e3 #DIV#
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_R0 = FR_QQ,FR_Q0,FR_PP // r = a-b*q #DIV#
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_DD = FR_GG, FR_GG, FR_2XM1 // d = x - g * g &SQRT&
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_E4 = FR_QQ,FR_Y2,f1 // e4 = 1-b*y2 #DIV#
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_X_Hi = FR_R0,FR_Y2,FR_Q0 // x = q+r*y2 #DIV#
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_GL = FR_DD, FR_HH, f0 // gl = d * h &SQRT&
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Y3 = FR_Y2,FR_E4,FR_Y2 // y3 = y2+y2*e4 #DIV#
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_R1 = FR_QQ,FR_X_Hi,FR_PP // r1 = a-b*x #DIV#
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_GG, FR_X_Hi, f0 // hh = gg * x_hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_LH = FR_GL, FR_X_Hi, f0 // lh = gl * x_hi
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_X_lo = FR_R1,FR_Y3,f0 // x_lo = r1*y3 #DIV#
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_LL = FR_GL, FR_X_lo, f0 // ll = gl*x_lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HL = FR_GG, FR_X_lo, f0 // hl = gg * x_lo
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_Res = FR_GL, f1, FR_LL // res = gl + ll
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_Res = FR_Res, f1, FR_LH // res = res + lh
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_Res = FR_Res, f1, FR_HL // res = res + hl
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_Res = FR_Res, f1, FR_HH // res = res + hh
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ fma.s0 FR_Res = FR_Res, f1, FR_GG // result = res + gg
+ br.ret.sptk b0 // Exit for near 1 path
+};;
+// NEAR ONE INTERVAL END
+
+
+
+
+acoshl_lt_pone:
+{ .mfi
+ nop.m 0
+ fmerge.s FR_Arg_X = FR_Arg, FR_Arg
+ nop.i 0
+};;
+{ .mfb
+ mov GR_Parameter_TAG = 135
+ frcpa.s0 FR_Res,p0 = f0,f0 // get QNaN,and raise invalid
+ br.cond.sptk __libm_error_region // exit if x < 1.0
+};;
+
+GLOBAL_LIBM_END(acoshl)
+
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y = -32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS = ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp = -64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP = gp // Save gp
+};;
+
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Arg_Y,16 // Parameter 2 to stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0,GR_SAVE_B0
+ mov GR_SAVE_B0 = b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_Arg_X // Parameter 1 to stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_Res // Parameter 3 to stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0 = __libm_error_support# // Error handling function
+};;
+
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return res
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region#)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_acosl.S b/libc/sysdeps/ia64/fpu/e_acosl.S
new file mode 100644
index 000000000..4fd345bed
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_acosl.S
@@ -0,0 +1,2552 @@
+.file "acosl.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/28/01 New version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// long double acosl(long double)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// For |s| in [2^{-4}, sqrt(2)/2]:
+// Let t= 2^k*1.b1 b2..b6 1, where s= 2^k*1.b1 b2.. b52
+// acos(s)= pi/2-asin(t)-asin(r), where r= s*sqrt(1-t^2)-t*sqrt(1-s^2), i.e.
+// r= (s-t)*sqrt(1-t^2)-t*sqrt(1-t^2)*(sqrt((1-s^2)/(1-t^2))-1)
+// asin(r)-r evaluated as 9-degree polynomial (c3*r^3+c5*r^5+c7*r^7+c9*r^9)
+// The 64-bit significands of sqrt(1-t^2), 1/(1-t^2) are read from the table,
+// along with the high and low parts of asin(t) (stored as two double precision
+// values)
+//
+// |s| in (sqrt(2)/2, sqrt(255/256)):
+// Let t= 2^k*1.b1 b2..b6 1, where (1-s^2)*frsqrta(1-s^2)= 2^k*1.b1 b2..b6..
+// acos(|s|)= asin(t)-asin(r)
+// acos(-|s|)=pi-asin(t)+asin(r), r= s*t-sqrt(1-s^2)*sqrt(1-t^2)
+// To minimize accumulated errors, r is computed as
+// r= (t*s)_s-t^2*y*z+z*y*(t^2-1+s^2)_s+z*y*(1-s^2)_s*x+z'*y*(1-s^2)*PS29+
+// +(t*s-(t*s)_s)+z*y*((t^2-1-(t^2-1+s^2)_s)+s^2)+z*y*(1-s^2-(1-s^2)_s)+
+// +ez*z'*y*(1-s^2)*(1-x),
+// where y= frsqrta(1-s^2), z= (sqrt(1-t^2))_s (rounded to 24 significant bits)
+// z'= sqrt(1-t^2), x= ((1-s^2)*y^2-1)/2
+//
+// |s|<2^{-4}: evaluate asin(s) as 17-degree polynomial, return pi/2-asin(s)
+// (or simply return pi/2-s, if|s|<2^{-64})
+//
+// |s| in [sqrt(255/256), 1): acos(|s|)= asin(sqrt(1-s^2))
+// acos(-|s|)= pi-asin(sqrt(1-s^2))
+// use 17-degree polynomial for asin(sqrt(1-s^2)),
+// 9-degree polynomial to evaluate sqrt(1-s^2)
+// High order term is (pi)_high-(y*(1-s^2))_high, for s<0,
+// or y*(1-s^2)_s, for s>0
+//
+
+
+
+// Registers used
+//==============================================================
+// f6-f15, f32-f36
+// r2-r3, r23-r23
+// p6, p7, p8, p12
+//
+
+
+ GR_SAVE_B0= r33
+ GR_SAVE_PFS= r34
+ GR_SAVE_GP= r35 // This reg. can safely be used
+ GR_SAVE_SP= r36
+
+ GR_Parameter_X= r37
+ GR_Parameter_Y= r38
+ GR_Parameter_RESULT= r39
+ GR_Parameter_TAG= r40
+
+ FR_X= f10
+ FR_Y= f1
+ FR_RESULT= f8
+
+
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(T_table)
+
+// stores 64-bit significand of 1/(1-t^2), 64-bit significand of sqrt(1-t^2),
+// asin(t)_high (double precision), asin(t)_low (double precision)
+
+data8 0x80828692b71c4391, 0xff7ddcec2d87e879
+data8 0x3fb022bc0ae531a0, 0x3c9f599c7bb42af6
+data8 0x80869f0163d0b082, 0xff79cad2247914d3
+data8 0x3fb062dd26afc320, 0x3ca4eff21bd49c5c
+data8 0x808ac7d5a8690705, 0xff75a89ed6b626b9
+data8 0x3fb0a2ff4a1821e0, 0x3cb7e33b58f164cc
+data8 0x808f0112ad8ad2e0, 0xff7176517c2cc0cb
+data8 0x3fb0e32279319d80, 0x3caee31546582c43
+data8 0x80934abba8a1da0a, 0xff6d33e949b1ed31
+data8 0x3fb12346b8101da0, 0x3cb8bfe463d087cd
+data8 0x8097a4d3dbe63d8f, 0xff68e16571015c63
+data8 0x3fb1636c0ac824e0, 0x3c8870a7c5a3556f
+data8 0x809c0f5e9662b3dd, 0xff647ec520bca0f0
+data8 0x3fb1a392756ed280, 0x3c964f1a927461ae
+data8 0x80a08a5f33fadc66, 0xff600c07846a6830
+data8 0x3fb1e3b9fc19e580, 0x3c69eb3576d56332
+data8 0x80a515d91d71acd4, 0xff5b892bc475affa
+data8 0x3fb223e2a2dfbe80, 0x3c6a4e19fd972fb6
+data8 0x80a9b1cfc86ff7cd, 0xff56f631062cf93d
+data8 0x3fb2640c6dd76260, 0x3c62041160e0849e
+data8 0x80ae5e46b78b0d68, 0xff5253166bc17794
+data8 0x3fb2a43761187c80, 0x3cac61651af678c0
+data8 0x80b31b417a4b756b, 0xff4d9fdb14463dc8
+data8 0x3fb2e46380bb6160, 0x3cb06ef23eeba7a1
+data8 0x80b7e8c3ad33c369, 0xff48dc7e1baf6738
+data8 0x3fb32490d0d910c0, 0x3caa05f480b300d5
+data8 0x80bcc6d0f9c784d6, 0xff4408fe9ad13e37
+data8 0x3fb364bf558b3820, 0x3cb01e7e403aaab9
+data8 0x80c1b56d1692492d, 0xff3f255ba75f5f4e
+data8 0x3fb3a4ef12ec3540, 0x3cb4fe8fcdf5f5f1
+data8 0x80c6b49bc72ec446, 0xff3a319453ebd961
+data8 0x3fb3e5200d171880, 0x3caf2dc089b2b7e2
+data8 0x80cbc460dc4e0ae8, 0xff352da7afe64ac6
+data8 0x3fb425524827a720, 0x3cb75a855e7c6053
+data8 0x80d0e4c033bee9c4, 0xff301994c79afb32
+data8 0x3fb46585c83a5e00, 0x3cb3264981c019ab
+data8 0x80d615bdb87556db, 0xff2af55aa431f291
+data8 0x3fb4a5ba916c73c0, 0x3c994251d94427b5
+data8 0x80db575d6291fd8a, 0xff25c0f84bae0cb9
+data8 0x3fb4e5f0a7dbdb20, 0x3cbee2fcc4c786cb
+data8 0x80e0a9a33769e535, 0xff207c6cc0ec09fd
+data8 0x3fb526280fa74620, 0x3c940656e5549b91
+data8 0x80e60c93498e32cd, 0xff1b27b703a19c98
+data8 0x3fb56660ccee2740, 0x3ca7082374d7b2cd
+data8 0x80eb8031b8d4052d, 0xff15c2d6105c72f8
+data8 0x3fb5a69ae3d0b520, 0x3c7c4d46e09ac68a
+data8 0x80f10482b25c6c8a, 0xff104dc8e0813ed4
+data8 0x3fb5e6d6586fec20, 0x3c9aa84ffd9b4958
+data8 0x80f6998a709c7cfb, 0xff0ac88e6a4ab926
+data8 0x3fb627132eed9140, 0x3cbced2cbbbe7d16
+data8 0x80fc3f4d3b657c44, 0xff053325a0c8a2ec
+data8 0x3fb667516b6c34c0, 0x3c6489c5fc68595a
+data8 0x8101f5cf67ed2af8, 0xfeff8d8d73dec2bb
+data8 0x3fb6a791120f33a0, 0x3cbe12acf159dfad
+data8 0x8107bd1558d6291f, 0xfef9d7c4d043df29
+data8 0x3fb6e7d226fabba0, 0x3ca386d099cd0dc7
+data8 0x810d95237e38766a, 0xfef411ca9f80b5f7
+data8 0x3fb72814ae53cc20, 0x3cb9f35731e71dd6
+data8 0x81137dfe55aa0e29, 0xfeee3b9dc7eef009
+data8 0x3fb76858ac403a00, 0x3c74df3dd959141a
+data8 0x811977aa6a479f0f, 0xfee8553d2cb8122c
+data8 0x3fb7a89e24e6b0e0, 0x3ca6034406ee42bc
+data8 0x811f822c54bd5ef8, 0xfee25ea7add46a91
+data8 0x3fb7e8e51c6eb6a0, 0x3cb82f8f78e68ed7
+data8 0x81259d88bb4ffac1, 0xfedc57dc2809fb1d
+data8 0x3fb8292d9700ad60, 0x3cbebb73c0e653f9
+data8 0x812bc9c451e5a257, 0xfed640d974eb6068
+data8 0x3fb8697798c5d620, 0x3ca2feee76a9701b
+data8 0x813206e3da0f3124, 0xfed0199e6ad6b585
+data8 0x3fb8a9c325e852e0, 0x3cb9e88f2f4d0efe
+data8 0x813854ec231172f9, 0xfec9e229dcf4747d
+data8 0x3fb8ea1042932a00, 0x3ca5ff40d81f66fd
+data8 0x813eb3e209ee858f, 0xfec39a7a9b36538b
+data8 0x3fb92a5ef2f247c0, 0x3cb5e3bece4d6b07
+data8 0x814523ca796f56ce, 0xfebd428f72561efe
+data8 0x3fb96aaf3b3281a0, 0x3cb7b9e499436d7c
+data8 0x814ba4aa6a2d3ff9, 0xfeb6da672bd48fe4
+data8 0x3fb9ab011f819860, 0x3cb9168143cc1a7f
+data8 0x81523686e29bbdd7, 0xfeb062008df81f50
+data8 0x3fb9eb54a40e3ac0, 0x3cb6e544197eb1e1
+data8 0x8158d964f7124614, 0xfea9d95a5bcbd65a
+data8 0x3fba2ba9cd080800, 0x3ca9a717be8f7446
+data8 0x815f8d49c9d639e4, 0xfea34073551e1ac8
+data8 0x3fba6c009e9f9260, 0x3c741e989a60938a
+data8 0x8166523a8b24f626, 0xfe9c974a367f785c
+data8 0x3fbaac591d0661a0, 0x3cb2c1290107e57d
+data8 0x816d283c793e0114, 0xfe95ddddb94166cb
+data8 0x3fbaecb34c6ef600, 0x3c9c7d5fbaec405d
+data8 0x81740f54e06d55bd, 0xfe8f142c93750c50
+data8 0x3fbb2d0f310cca00, 0x3cbc09479a9cbcfb
+data8 0x817b07891b15cd5e, 0xfe883a3577e9fceb
+data8 0x3fbb6d6ccf1455e0, 0x3cb9450bff4ee307
+data8 0x818210de91bba6c8, 0xfe814ff7162cf62f
+data8 0x3fbbadcc2abb1180, 0x3c9227fda12a8d24
+data8 0x81892b5abb0f2bf9, 0xfe7a55701a8697b1
+data8 0x3fbbee2d48377700, 0x3cb6fad72acfe356
+data8 0x819057031bf7760e, 0xfe734a9f2dfa1810
+data8 0x3fbc2e902bc10600, 0x3cb4465b588d16ad
+data8 0x819793dd479d4fbe, 0xfe6c2f82f643f68b
+data8 0x3fbc6ef4d9904580, 0x3c8b9ac54823960d
+data8 0x819ee1eedf76367a, 0xfe65041a15d8a92c
+data8 0x3fbcaf5b55dec6a0, 0x3ca2b8d28a954db2
+data8 0x81a6413d934f7a66, 0xfe5dc8632be3477f
+data8 0x3fbcefc3a4e727a0, 0x3c9380da83713ab4
+data8 0x81adb1cf21597d4b, 0xfe567c5cd44431d5
+data8 0x3fbd302dcae51600, 0x3ca995b83421756a
+data8 0x81b533a9563310b8, 0xfe4f2005a78fb50f
+data8 0x3fbd7099cc155180, 0x3caefa2f7a817d5f
+data8 0x81bcc6d20cf4f373, 0xfe47b35c3b0caaeb
+data8 0x3fbdb107acb5ae80, 0x3cb455fc372dd026
+data8 0x81c46b4f2f3d6e68, 0xfe40365f20b316d6
+data8 0x3fbdf177710518c0, 0x3cbee3dcc5b01434
+data8 0x81cc2126b53c1144, 0xfe38a90ce72abf36
+data8 0x3fbe31e91d439620, 0x3cb3e131c950aebd
+data8 0x81d3e85ea5bd8ee2, 0xfe310b6419c9c33a
+data8 0x3fbe725cb5b24900, 0x3c01d3fac6029027
+data8 0x81dbc0fd1637b9c1, 0xfe295d6340932d15
+data8 0x3fbeb2d23e937300, 0x3c6304cc44aeedd1
+data8 0x81e3ab082ad5a0a4, 0xfe219f08e03580b3
+data8 0x3fbef349bc2a77e0, 0x3cac1d2d6abe9c72
+data8 0x81eba6861683cb97, 0xfe19d0537a0946e2
+data8 0x3fbf33c332bbe020, 0x3ca0909dba4e96ca
+data8 0x81f3b37d1afc9979, 0xfe11f1418c0f94e2
+data8 0x3fbf743ea68d5b60, 0x3c937fc12a2a779a
+data8 0x81fbd1f388d4be45, 0xfe0a01d190f09063
+data8 0x3fbfb4bc1be5c340, 0x3cbf51a504b55813
+data8 0x820401efbf87e248, 0xfe020201fff9efea
+data8 0x3fbff53b970d1e80, 0x3ca625444b260078
+data8 0x82106ad2ffdca049, 0xfdf5e3940a49135e
+data8 0x3fc02aff52065460, 0x3c9125d113e22a57
+data8 0x8221343d6ea1d3e2, 0xfde581a45429b0a0
+data8 0x3fc06b84f8e03220, 0x3caccf362295894b
+data8 0x82324434adbf99c2, 0xfdd4de1a001fb775
+data8 0x3fc0ac0ed1fe7240, 0x3cc22f676096b0af
+data8 0x82439aee8d0c7747, 0xfdc3f8e8269d1f03
+data8 0x3fc0ec9cee9e4820, 0x3cca147e2886a628
+data8 0x825538a1d0fcb2f0, 0xfdb2d201a9b1ba66
+data8 0x3fc12d2f6006f0a0, 0x3cc72b36633bc2d4
+data8 0x82671d86345c5cee, 0xfda1695934d723e7
+data8 0x3fc16dc63789de60, 0x3cb11f9c47c7b83f
+data8 0x827949d46a121770, 0xfd8fbee13cbbb823
+data8 0x3fc1ae618682e620, 0x3cce1b59020cef8e
+data8 0x828bbdc61eeab9ba, 0xfd7dd28bff0c9f34
+data8 0x3fc1ef015e586c40, 0x3cafec043e0225ee
+data8 0x829e7995fb6de9e1, 0xfd6ba44b823ee1ca
+data8 0x3fc22fa5d07b90c0, 0x3cba905409caf8e3
+data8 0x82b17d7fa5bbc982, 0xfd5934119557883a
+data8 0x3fc2704eee685da0, 0x3cb5ef21838a823e
+data8 0x82c4c9bfc373d276, 0xfd4681cfcfb2c161
+data8 0x3fc2b0fcc9a5f3e0, 0x3ccc7952c5e0e312
+data8 0x82d85e93fba50136, 0xfd338d7790ca0f41
+data8 0x3fc2f1af73c6ba00, 0x3cbecf5f977d1ca9
+data8 0x82ec3c3af8c76b32, 0xfd2056f9fff97727
+data8 0x3fc33266fe6889a0, 0x3c9d329c022ebdb5
+data8 0x830062f46abf6022, 0xfd0cde480c43b327
+data8 0x3fc373237b34de60, 0x3cc95806d4928adb
+data8 0x8314d30108ea35f0, 0xfcf923526c1562b2
+data8 0x3fc3b3e4fbe10520, 0x3cbc299fe7223d54
+data8 0x83298ca29434df97, 0xfce526099d0737ed
+data8 0x3fc3f4ab922e4a60, 0x3cb59d8bb8fdbccc
+data8 0x833e901bd93c7009, 0xfcd0e65de39f1f7c
+data8 0x3fc435774fea2a60, 0x3c9ec18b43340914
+data8 0x8353ddb0b278aad8, 0xfcbc643f4b106055
+data8 0x3fc4764846ee80a0, 0x3cb90402efd87ed6
+data8 0x836975a60a70c52e, 0xfca79f9da4fab13a
+data8 0x3fc4b71e8921b860, 0xbc58f23449ed6365
+data8 0x837f5841ddfa7a46, 0xfc92986889284148
+data8 0x3fc4f7fa2876fca0, 0xbc6294812bf43acd
+data8 0x839585cb3e839773, 0xfc7d4e8f554ab12f
+data8 0x3fc538db36ee6960, 0x3cb910b773d4c578
+data8 0x83abfe8a5466246f, 0xfc67c2012cb6fa68
+data8 0x3fc579c1c6953cc0, 0x3cc5ede909fc47fc
+data8 0x83c2c2c861474d91, 0xfc51f2acf82041d5
+data8 0x3fc5baade9860880, 0x3cac63cdfc3588e5
+data8 0x83d9d2cfc2813637, 0xfc3be08165519325
+data8 0x3fc5fb9fb1e8e3a0, 0x3cbf7c8466578c29
+data8 0x83f12eebf397daac, 0xfc258b6ce6e6822f
+data8 0x3fc63c9731f39d40, 0x3cb6d2a7ffca3e9e
+data8 0x8408d76990b9296e, 0xfc0ef35db402af94
+data8 0x3fc67d947be9eec0, 0x3cb1980da09e6566
+data8 0x8420cc9659487cd7, 0xfbf81841c8082dc4
+data8 0x3fc6be97a21daf00, 0x3cc2ac8330e59aa5
+data8 0x84390ec132759ecb, 0xfbe0fa06e24cc390
+data8 0x3fc6ffa0b6ef05e0, 0x3ccc1a030fee56c4
+data8 0x84519e3a29df811a, 0xfbc9989a85ce0954
+data8 0x3fc740afcccca000, 0x3cc19692a5301ca6
+data8 0x846a7b527842d61b, 0xfbb1f3e9f8e45dc4
+data8 0x3fc781c4f633e2c0, 0x3cc0e98f3868a508
+data8 0x8483a65c8434b5f0, 0xfb9a0be244f4af45
+data8 0x3fc7c2e045b12140, 0x3cb2a8d309754420
+data8 0x849d1fabe4e97dd7, 0xfb81e070362116d1
+data8 0x3fc80401cddfd120, 0x3ca7a44544aa4ce6
+data8 0x84b6e795650817ea, 0xfb6971805af8411e
+data8 0x3fc84529a16ac020, 0x3c9e3b709c7d6f94
+data8 0x84d0fe6f0589da92, 0xfb50beff0423a2f5
+data8 0x3fc88657d30c49e0, 0x3cc60d65a7f0a278
+data8 0x84eb649000a73014, 0xfb37c8d84414755c
+data8 0x3fc8c78c758e8e80, 0x3cc94b2ee984c2b7
+data8 0x85061a50ccd13781, 0xfb1e8ef7eeaf764b
+data8 0x3fc908c79bcba900, 0x3cc8540ae794a2fe
+data8 0x8521200b1fb8916e, 0xfb05114998f76a83
+data8 0x3fc94a0958ade6c0, 0x3ca127f49839fa9c
+data8 0x853c7619f1618bf6, 0xfaeb4fb898b65d19
+data8 0x3fc98b51bf2ffee0, 0x3c8c9ba7a803909a
+data8 0x85581cd97f45e274, 0xfad14a3004259931
+data8 0x3fc9cca0e25d4ac0, 0x3cba458e91d3bf54
+data8 0x857414a74f8446b4, 0xfab7009ab1945a54
+data8 0x3fca0df6d551fe80, 0x3cc78ea1d329d2b2
+data8 0x85905de2341dea46, 0xfa9c72e3370d2fbc
+data8 0x3fca4f53ab3b6200, 0x3ccf60dca86d57ef
+data8 0x85acf8ea4e423ff8, 0xfa81a0f3e9fa0ee9
+data8 0x3fca90b777580aa0, 0x3ca4c4e2ec8a867e
+data8 0x85c9e62111a92e7d, 0xfa668ab6dec711b1
+data8 0x3fcad2224cf814e0, 0x3c303de5980d071c
+data8 0x85e725e947fbee97, 0xfa4b3015e883dbfe
+data8 0x3fcb13943f7d5f80, 0x3cc29d4eefa5cb1e
+data8 0x8604b8a7144cd054, 0xfa2f90fa9883a543
+data8 0x3fcb550d625bc6a0, 0x3c9e01a746152daf
+data8 0x86229ebff69e2415, 0xfa13ad4e3dfbe1c1
+data8 0x3fcb968dc9195ea0, 0x3ccc091bd73ae518
+data8 0x8640d89acf78858c, 0xf9f784f9e5a1877b
+data8 0x3fcbd815874eb160, 0x3cb5f4b89875e187
+data8 0x865f669fe390c7f5, 0xf9db17e65944eacf
+data8 0x3fcc19a4b0a6f9c0, 0x3cc5c0bc2b0bbf14
+data8 0x867e4938df7dc45f, 0xf9be65fc1f6c2e6e
+data8 0x3fcc5b3b58e061e0, 0x3cc1ca70df8f57e7
+data8 0x869d80d0db7e4c0c, 0xf9a16f237aec427a
+data8 0x3fcc9cd993cc4040, 0x3cbae93acc85eccf
+data8 0x86bd0dd45f4f8265, 0xf98433446a806e70
+data8 0x3fccde7f754f5660, 0x3cb22f70e64568d0
+data8 0x86dcf0b16613e37a, 0xf966b246a8606170
+data8 0x3fcd202d11620fa0, 0x3c962030e5d4c849
+data8 0x86fd29d7624b3d5d, 0xf948ec11a9d4c45b
+data8 0x3fcd61e27c10c0a0, 0x3cc7083c91d59217
+data8 0x871db9b741dbe44a, 0xf92ae08c9eca4941
+data8 0x3fcda39fc97be7c0, 0x3cc9258579e57211
+data8 0x873ea0c3722d6af2, 0xf90c8f9e71633363
+data8 0x3fcde5650dd86d60, 0x3ca4755a9ea582a9
+data8 0x875fdf6fe45529e8, 0xf8edf92dc5875319
+data8 0x3fce27325d6fe520, 0x3cbc1e2b6c1954f9
+data8 0x878176321154e2bc, 0xf8cf1d20f87270b8
+data8 0x3fce6907cca0d060, 0x3cb6ca4804750830
+data8 0x87a36580fe6bccf5, 0xf8affb5e20412199
+data8 0x3fceaae56fdee040, 0x3cad6b310d6fd46c
+data8 0x87c5add5417a5cb9, 0xf89093cb0b7c0233
+data8 0x3fceeccb5bb33900, 0x3cc16e99cedadb20
+data8 0x87e84fa9057914ca, 0xf870e64d40a15036
+data8 0x3fcf2eb9a4bcb600, 0x3cc75ee47c8b09e9
+data8 0x880b4b780f02b709, 0xf850f2c9fdacdf78
+data8 0x3fcf70b05fb02e20, 0x3cad6350d379f41a
+data8 0x882ea1bfc0f228ac, 0xf830b926379e6465
+data8 0x3fcfb2afa158b8a0, 0x3cce0ccd9f829985
+data8 0x885252ff21146108, 0xf810394699fe0e8e
+data8 0x3fcff4b77e97f3e0, 0x3c9b30faa7a4c703
+data8 0x88765fb6dceebbb3, 0xf7ef730f865f6df0
+data8 0x3fd01b6406332540, 0x3cdc5772c9e0b9bd
+data8 0x88ad1f69be2cc730, 0xf7bdc59bc9cfbd97
+data8 0x3fd04cf8ad203480, 0x3caeef44fe21a74a
+data8 0x88f763f70ae2245e, 0xf77a91c868a9c54e
+data8 0x3fd08f23ce0162a0, 0x3cd6290ab3fe5889
+data8 0x89431fc7bc0c2910, 0xf73642973c91298e
+data8 0x3fd0d1610f0c1ec0, 0x3cc67401a01f08cf
+data8 0x8990573407c7738e, 0xf6f0d71d1d7a2dd6
+data8 0x3fd113b0c65d88c0, 0x3cc7aa4020fe546f
+data8 0x89df0eb108594653, 0xf6aa4e6a05cfdef2
+data8 0x3fd156134ada6fe0, 0x3cc87369da09600c
+data8 0x8a2f4ad16e0ed78a, 0xf662a78900c35249
+data8 0x3fd19888f43427a0, 0x3cc62b220f38e49c
+data8 0x8a811046373e0819, 0xf619e180181d97cc
+data8 0x3fd1db121aed7720, 0x3ca3ede7490b52f4
+data8 0x8ad463df6ea0fa2c, 0xf5cffb504190f9a2
+data8 0x3fd21daf185fa360, 0x3caafad98c1d6c1b
+data8 0x8b294a8cf0488daf, 0xf584f3f54b8604e6
+data8 0x3fd2606046bf95a0, 0x3cdb2d704eeb08fa
+data8 0x8b7fc95f35647757, 0xf538ca65c960b582
+data8 0x3fd2a32601231ec0, 0x3cc661619fa2f126
+data8 0x8bd7e588272276f8, 0xf4eb7d92ff39fccb
+data8 0x3fd2e600a3865760, 0x3c8a2a36a99aca4a
+data8 0x8c31a45bf8e9255e, 0xf49d0c68cd09b689
+data8 0x3fd328f08ad12000, 0x3cb9efaf1d7ab552
+data8 0x8c8d0b520a35eb18, 0xf44d75cd993cfad2
+data8 0x3fd36bf614dcc040, 0x3ccacbb590bef70d
+data8 0x8cea2005d068f23d, 0xf3fcb8a23ab4942b
+data8 0x3fd3af11a079a6c0, 0x3cd9775872cf037d
+data8 0x8d48e837c8cd5027, 0xf3aad3c1e2273908
+data8 0x3fd3f2438d754b40, 0x3ca03304f667109a
+data8 0x8da969ce732f3ac7, 0xf357c60202e2fd7e
+data8 0x3fd4358c3ca032e0, 0x3caecf2504ff1a9d
+data8 0x8e0baad75555e361, 0xf3038e323ae9463a
+data8 0x3fd478ec0fd419c0, 0x3cc64bdc3d703971
+data8 0x8e6fb18807ba877e, 0xf2ae2b1c3a6057f7
+data8 0x3fd4bc6369fa40e0, 0x3cbb7122ec245cf2
+data8 0x8ed5843f4bda74d5, 0xf2579b83aa556f0c
+data8 0x3fd4fff2af11e2c0, 0x3c9cfa2dc792d394
+data8 0x8f3d29862c861fef, 0xf1ffde2612ca1909
+data8 0x3fd5439a4436d000, 0x3cc38d46d310526b
+data8 0x8fa6a81128940b2d, 0xf1a6f1bac0075669
+data8 0x3fd5875a8fa83520, 0x3cd8bf59b8153f8a
+data8 0x901206c1686317a6, 0xf14cd4f2a730d480
+data8 0x3fd5cb33f8cf8ac0, 0x3c9502b5c4d0e431
+data8 0x907f4ca5fe9cf739, 0xf0f186784a125726
+data8 0x3fd60f26e847b120, 0x3cc8a1a5e0acaa33
+data8 0x90ee80fd34aeda5e, 0xf09504ef9a212f18
+data8 0x3fd65333c7e43aa0, 0x3cae5b029cb1f26e
+data8 0x915fab35e37421c6, 0xf0374ef5daab5c45
+data8 0x3fd6975b02b8e360, 0x3cd5aa1c280c45e6
+data8 0x91d2d2f0d894d73c, 0xefd86321822dbb51
+data8 0x3fd6db9d05213b20, 0x3cbecf2c093ccd8b
+data8 0x9248000249200009, 0xef7840021aca5a72
+data8 0x3fd71ffa3cc87fc0, 0x3cb8d273f08d00d9
+data8 0x92bf3a7351f081d2, 0xef16e42021d7cbd5
+data8 0x3fd7647318b1ad20, 0x3cbce099d79cdc46
+data8 0x93388a8386725713, 0xeeb44dfce6820283
+data8 0x3fd7a908093fc1e0, 0x3ccb033ec17a30d9
+data8 0x93b3f8aa8e653812, 0xee507c126774fa45
+data8 0x3fd7edb9803e3c20, 0x3cc10aedb48671eb
+data8 0x94318d99d341ade4, 0xedeb6cd32f891afb
+data8 0x3fd83287f0e9cf80, 0x3c994c0c1505cd2a
+data8 0x94b1523e3dedc630, 0xed851eaa3168f43c
+data8 0x3fd87773cff956e0, 0x3cda3b7bce6a6b16
+data8 0x95334fc20577563f, 0xed1d8ffaa2279669
+data8 0x3fd8bc7d93a70440, 0x3cd4922edc792ce2
+data8 0x95b78f8e8f92f274, 0xecb4bf1fd2be72da
+data8 0x3fd901a5b3b9cf40, 0x3cd3fea1b00f9d0d
+data8 0x963e1b4e63a87c3f, 0xec4aaa6d08694cc1
+data8 0x3fd946eca98f2700, 0x3cdba4032d968ff1
+data8 0x96c6fcef314074fc, 0xebdf502d53d65fea
+data8 0x3fd98c52f024e800, 0x3cbe7be1ab8c95c9
+data8 0x97523ea3eab028b2, 0xeb72aea36720793e
+data8 0x3fd9d1d904239860, 0x3cd72d08a6a22b70
+data8 0x97dfeae6f4ee4a9a, 0xeb04c4096a884e94
+data8 0x3fda177f63e8ef00, 0x3cd818c3c1ebfac7
+data8 0x98700c7c6d85d119, 0xea958e90cfe1efd7
+data8 0x3fda5d468f92a540, 0x3cdf45fbfaa080fe
+data8 0x9902ae7487a9caa1, 0xea250c6224aab21a
+data8 0x3fdaa32f090998e0, 0x3cd715a9353cede4
+data8 0x9997dc2e017a9550, 0xe9b33b9ce2bb7638
+data8 0x3fdae939540d3f00, 0x3cc545c014943439
+data8 0x9a2fa158b29b649b, 0xe9401a573f8aa706
+data8 0x3fdb2f65f63f6c60, 0x3cd4a63c2f2ca8e2
+data8 0x9aca09f835466186, 0xe8cba69df9f0bf35
+data8 0x3fdb75b5773075e0, 0x3cda310ce1b217ec
+data8 0x9b672266ab1e0136, 0xe855de74266193d4
+data8 0x3fdbbc28606babc0, 0x3cdc84b75cca6c44
+data8 0x9c06f7579f0b7bd5, 0xe7debfd2f98c060b
+data8 0x3fdc02bf3d843420, 0x3cd225d967ffb922
+data8 0x9ca995db058cabdc, 0xe76648a991511c6e
+data8 0x3fdc497a9c224780, 0x3cde08101c5b825b
+data8 0x9d4f0b605ce71e88, 0xe6ec76dcbc02d9a7
+data8 0x3fdc905b0c10d420, 0x3cb1abbaa3edf120
+data8 0x9df765b9eecad5e6, 0xe6714846bdda7318
+data8 0x3fdcd7611f4b8a00, 0x3cbf6217ae80aadf
+data8 0x9ea2b320350540fe, 0xe5f4bab71494cd6b
+data8 0x3fdd1e8d6a0d56c0, 0x3cb726e048cc235c
+data8 0x9f51023562fc5676, 0xe576cbf239235ecb
+data8 0x3fdd65e082df5260, 0x3cd9e66872bd5250
+data8 0xa002620915c2a2f6, 0xe4f779b15f5ec5a7
+data8 0x3fddad5b02a82420, 0x3c89743b0b57534b
+data8 0xa0b6e21c2caf9992, 0xe476c1a233a7873e
+data8 0x3fddf4fd84bbe160, 0x3cbf7adea9ee3338
+data8 0xa16e9264cc83a6b2, 0xe3f4a16696608191
+data8 0x3fde3cc8a6ec6ee0, 0x3cce46f5a51f49c6
+data8 0xa22983528f3d8d49, 0xe3711694552da8a8
+data8 0x3fde84bd099a6600, 0x3cdc78f6490a2d31
+data8 0xa2e7c5d2e2e69460, 0xe2ec1eb4e1e0a5fb
+data8 0x3fdeccdb4fc685c0, 0x3cdd3aedb56a4825
+data8 0xa3a96b5599bd2532, 0xe265b74506fbe1c9
+data8 0x3fdf15241f23b3e0, 0x3cd440f3c6d65f65
+data8 0xa46e85d1ae49d7de, 0xe1ddddb499b3606f
+data8 0x3fdf5d98202994a0, 0x3cd6c44bd3fb745a
+data8 0xa53727ca3e11b99e, 0xe1548f662951b00d
+data8 0x3fdfa637fe27bf60, 0x3ca8ad1cd33054dd
+data8 0xa6036453bdc20186, 0xe0c9c9aeabe5e481
+data8 0x3fdfef0467599580, 0x3cc0f1ac0685d78a
+data8 0xa6d34f1969dda338, 0xe03d89d5281e4f81
+data8 0x3fe01bff067d6220, 0x3cc0731e8a9ef057
+data8 0xa7a6fc62f7246ff3, 0xdfafcd125c323f54
+data8 0x3fe04092d1ae3b40, 0x3ccabda24b59906d
+data8 0xa87e811a861df9b9, 0xdf20909061bb9760
+data8 0x3fe0653df0fd9fc0, 0x3ce94c8dcc722278
+data8 0xa959f2d2dd687200, 0xde8fd16a4e5f88bd
+data8 0x3fe08a00c1cae320, 0x3ce6b888bb60a274
+data8 0xaa3967cdeea58bda, 0xddfd8cabd1240d22
+data8 0x3fe0aedba3221c00, 0x3ced5941cd486e46
+data8 0xab904fd587263c84, 0xdd1f4472e1cf64ed
+data8 0x3fe0e651e85229c0, 0x3cdb6701042299b1
+data8 0xad686d44dd5a74bb, 0xdbf173e1f6b46e92
+data8 0x3fe1309cbf4cdb20, 0x3cbf1be7bb3f0ec5
+data8 0xaf524e15640ebee4, 0xdabd54896f1029f6
+data8 0x3fe17b4ee1641300, 0x3ce81dd055b792f1
+data8 0xb14eca24ef7db3fa, 0xd982cb9ae2f47e41
+data8 0x3fe1c66b9ffd6660, 0x3cd98ea31eb5ddc7
+data8 0xb35ec807669920ce, 0xd841bd1b8291d0b6
+data8 0x3fe211f66db3a5a0, 0x3ca480c35a27b4a2
+data8 0xb5833e4755e04dd1, 0xd6fa0bd3150b6930
+data8 0x3fe25df2e05b6c40, 0x3ca4bc324287a351
+data8 0xb7bd34c8000b7bd3, 0xd5ab9939a7d23aa1
+data8 0x3fe2aa64b32f7780, 0x3cba67314933077c
+data8 0xba0dc64d126cc135, 0xd4564563ce924481
+data8 0x3fe2f74fc9289ac0, 0x3cec1a1dc0efc5ec
+data8 0xbc76222cbbfa74a6, 0xd2f9eeed501125a8
+data8 0x3fe344b82f859ac0, 0x3ceeef218de413ac
+data8 0xbef78e31985291a9, 0xd19672e2182f78be
+data8 0x3fe392a22087b7e0, 0x3cd2619ba201204c
+data8 0xc19368b2b0629572, 0xd02baca5427e436a
+data8 0x3fe3e11206694520, 0x3cb5d0b3143fe689
+data8 0xc44b2ae8c6733e51, 0xceb975d60b6eae5d
+data8 0x3fe4300c7e945020, 0x3cbd367143da6582
+data8 0xc7206b894212dfef, 0xcd3fa6326ff0ac9a
+data8 0x3fe47f965d201d60, 0x3ce797c7a4ec1d63
+data8 0xca14e1b0622de526, 0xcbbe13773c3c5338
+data8 0x3fe4cfb4b09d1a20, 0x3cedfadb5347143c
+data8 0xcd2a6825eae65f82, 0xca34913d425a5ae9
+data8 0x3fe5206cc637e000, 0x3ce2798b38e54193
+data8 0xd06301095e1351ee, 0xc8a2f0d3679c08c0
+data8 0x3fe571c42e3d0be0, 0x3ccd7cb9c6c2ca68
+data8 0xd3c0d9f50057adda, 0xc70901152d59d16b
+data8 0x3fe5c3c0c108f940, 0x3ceb6c13563180ab
+data8 0xd74650a98cc14789, 0xc5668e3d4cbf8828
+data8 0x3fe61668a46ffa80, 0x3caa9092e9e3c0e5
+data8 0xdaf5f8579dcc8f8f, 0xc3bb61b3eed42d02
+data8 0x3fe669c251ad69e0, 0x3cccf896ef3b4fee
+data8 0xded29f9f9a6171b4, 0xc20741d7f8e8e8af
+data8 0x3fe6bdd49bea05c0, 0x3cdc6b29937c575d
+data8 0xe2df5765854ccdb0, 0xc049f1c2d1b8014b
+data8 0x3fe712a6b76c6e80, 0x3ce1ddc6f2922321
+data8 0xe71f7a9b94fcb4c3, 0xbe833105ec291e91
+data8 0x3fe76840418978a0, 0x3ccda46e85432c3d
+data8 0xeb96b72d3374b91e, 0xbcb2bb61493b28b3
+data8 0x3fe7bea9496d5a40, 0x3ce37b42ec6e17d3
+data8 0xf049183c3f53c39b, 0xbad848720223d3a8
+data8 0x3fe815ea59dab0a0, 0x3cb03ad41bfc415b
+data8 0xf53b11ec7f415f15, 0xb8f38b57c53c9c48
+data8 0x3fe86e0c84010760, 0x3cc03bfcfb17fe1f
+data8 0xfa718f05adbf2c33, 0xb70432500286b185
+data8 0x3fe8c7196b9225c0, 0x3ced99fcc6866ba9
+data8 0xfff200c3f5489608, 0xb509e6454dca33cc
+data8 0x3fe9211b54441080, 0x3cb789cb53515688
+// The following table entries are not used
+//data8 0x82e138a0fac48700, 0xb3044a513a8e6132
+//data8 0x3fe97c1d30f5b7c0, 0x3ce1eb765612d1d0
+//data8 0x85f4cc7fc670d021, 0xb0f2fb2ea6cbbc88
+//data8 0x3fe9d82ab4b5fde0, 0x3ced3fe6f27e8039
+//data8 0x89377c1387d5b908, 0xaed58e9a09014d5c
+//data8 0x3fea355065f87fa0, 0x3cbef481d25f5b58
+//data8 0x8cad7a2c98dec333, 0xacab929ce114d451
+//data8 0x3fea939bb451e2a0, 0x3c8e92b4fbf4560f
+//data8 0x905b7dfc99583025, 0xaa748cc0dbbbc0ec
+//data8 0x3feaf31b11270220, 0x3cdced8c61bd7bd5
+//data8 0x9446d8191f80dd42, 0xa82ff92687235baf
+//data8 0x3feb53de0bcffc20, 0x3cbe1722fb47509e
+//data8 0x98758ba086e4000a, 0xa5dd497a9c184f58
+//data8 0x3febb5f571cb0560, 0x3ce0c7774329a613
+//data8 0x9cee6c7bf18e4e24, 0xa37be3c3cd1de51b
+//data8 0x3fec197373bc7be0, 0x3ce08ebdb55c3177
+//data8 0xa1b944000a1b9440, 0xa10b2101b4f27e03
+//data8 0x3fec7e6bd023da60, 0x3ce5fc5fd4995959
+//data8 0xa6defd8ba04d3e38, 0x9e8a4b93cad088ec
+//data8 0x3fece4f404e29b20, 0x3cea3413401132b5
+//data8 0xac69dd408a10c62d, 0x9bf89d5d17ddae8c
+//data8 0x3fed4d2388f63600, 0x3cd5a7fb0d1d4276
+//data8 0xb265c39cbd80f97a, 0x99553d969fec7beb
+//data8 0x3fedb714101e0a00, 0x3cdbda21f01193f2
+//data8 0xb8e081a16ae4ae73, 0x969f3e3ed2a0516c
+//data8 0x3fee22e1da97bb00, 0x3ce7231177f85f71
+//data8 0xbfea427678945732, 0x93d5990f9ee787af
+//data8 0x3fee90ac13b18220, 0x3ce3c8a5453363a5
+//data8 0xc79611399b8c90c5, 0x90f72bde80febc31
+//data8 0x3fef009542b712e0, 0x3ce218fd79e8cb56
+//data8 0xcffa8425040624d7, 0x8e02b4418574ebed
+//data8 0x3fef72c3d2c57520, 0x3cd32a717f82203f
+//data8 0xd93299cddcf9cf23, 0x8af6ca48e9c44024
+//data8 0x3fefe762b77744c0, 0x3ce53478a6bbcf94
+//data8 0xe35eda760af69ad9, 0x87d1da0d7f45678b
+//data8 0x3ff02f511b223c00, 0x3ced6e11782c28fc
+//data8 0xeea6d733421da0a6, 0x84921bbe64ae029a
+//data8 0x3ff06c5c6f8ce9c0, 0x3ce71fc71c1ffc02
+//data8 0xfb3b2c73fc6195cc, 0x813589ba3a5651b6
+//data8 0x3ff0aaf2613700a0, 0x3cf2a72d2fd94ef3
+//data8 0x84ac1fcec4203245, 0xfb73a828893df19e
+//data8 0x3ff0eb367c3fd600, 0x3cf8054c158610de
+//data8 0x8ca50621110c60e6, 0xf438a14c158d867c
+//data8 0x3ff12d51caa6b580, 0x3ce6bce9748739b6
+//data8 0x95b8c2062d6f8161, 0xecb3ccdd37b369da
+//data8 0x3ff1717418520340, 0x3ca5c2732533177c
+//data8 0xa0262917caab4ad1, 0xe4dde4ddc81fd119
+//data8 0x3ff1b7d59dd40ba0, 0x3cc4c7c98e870ff5
+//data8 0xac402c688b72f3f4, 0xdcae469be46d4c8d
+//data8 0x3ff200b93cc5a540, 0x3c8dd6dc1bfe865a
+//data8 0xba76968b9eabd9ab, 0xd41a8f3df1115f7f
+//data8 0x3ff24c6f8f6affa0, 0x3cf1acb6d2a7eff7
+//data8 0xcb63c87c23a71dc5, 0xcb161074c17f54ec
+//data8 0x3ff29b5b338b7c80, 0x3ce9b5845f6ec746
+//data8 0xdfe323b8653af367, 0xc19107d99ab27e42
+//data8 0x3ff2edf6fac7f5a0, 0x3cf77f961925fa02
+//data8 0xf93746caaba3e1f1, 0xb777744a9df03bff
+//data8 0x3ff344df237486c0, 0x3cf6ddf5f6ddda43
+//data8 0x8ca77052f6c340f0, 0xacaf476f13806648
+//data8 0x3ff3a0dfa4bb4ae0, 0x3cfee01bbd761bff
+//data8 0xa1a48604a81d5c62, 0xa11575d30c0aae50
+//data8 0x3ff4030b73c55360, 0x3cf1cf0e0324d37c
+//data8 0xbe45074b05579024, 0x9478e362a07dd287
+//data8 0x3ff46ce4c738c4e0, 0x3ce3179555367d12
+//data8 0xe7a08b5693d214ec, 0x8690e3575b8a7c3b
+//data8 0x3ff4e0a887c40a80, 0x3cfbd5d46bfefe69
+//data8 0x94503d69396d91c7, 0xedd2ce885ff04028
+//data8 0x3ff561ebd9c18cc0, 0x3cf331bd176b233b
+//data8 0xced1d96c5bb209e6, 0xc965278083808702
+//data8 0x3ff5f71d7ff42c80, 0x3ce3301cc0b5a48c
+//data8 0xabac2cee0fc24e20, 0x9c4eb1136094cbbd
+//data8 0x3ff6ae4c63222720, 0x3cf5ff46874ee51e
+//data8 0x8040201008040201, 0xb4d7ac4d9acb1bf4
+//data8 0x3ff7b7d33b928c40, 0x3cfacdee584023bb
+LOCAL_OBJECT_END(T_table)
+
+
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+ // C_3
+data8 0xaaaaaaaaaaaaaaab, 0x0000000000003ffc
+ // C_5
+data8 0x999999999999999a, 0x0000000000003ffb
+ // C_7, C_9
+data8 0x3fa6db6db6db6db7, 0x3f9f1c71c71c71c8
+ // pi/2 (low, high)
+data8 0x3C91A62633145C07, 0x3FF921FB54442D18
+ // C_11, C_13
+data8 0x3f96e8ba2e8ba2e9, 0x3f91c4ec4ec4ec4e
+ // C_15, C_17
+data8 0x3f8c99999999999a, 0x3f87a87878787223
+ // pi (low, high)
+data8 0x3CA1A62633145C07, 0x400921FB54442D18
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+R_DBL_S = r21
+R_EXP0 = r22
+R_EXP = r15
+R_SGNMASK = r23
+R_TMP = r24
+R_TMP2 = r25
+R_INDEX = r26
+R_TMP3 = r27
+R_TMP03 = r27
+R_TMP4 = r28
+R_TMP5 = r23
+R_TMP6 = r22
+R_TMP7 = r21
+R_T = r29
+R_BIAS = r20
+
+F_T = f6
+F_1S2 = f7
+F_1S2_S = f9
+F_INV_1T2 = f10
+F_SQRT_1T2 = f11
+F_S2T2 = f12
+F_X = f13
+F_D = f14
+F_2M64 = f15
+
+F_CS2 = f32
+F_CS3 = f33
+F_CS4 = f34
+F_CS5 = f35
+F_CS6 = f36
+F_CS7 = f37
+F_CS8 = f38
+F_CS9 = f39
+F_S23 = f40
+F_S45 = f41
+F_S67 = f42
+F_S89 = f43
+F_S25 = f44
+F_S69 = f45
+F_S29 = f46
+F_X2 = f47
+F_X4 = f48
+F_TSQRT = f49
+F_DTX = f50
+F_R = f51
+F_R2 = f52
+F_R3 = f53
+F_R4 = f54
+
+F_C3 = f55
+F_C5 = f56
+F_C7 = f57
+F_C9 = f58
+F_P79 = f59
+F_P35 = f60
+F_P39 = f61
+
+F_ATHI = f62
+F_ATLO = f63
+
+F_T1 = f64
+F_Y = f65
+F_Y2 = f66
+F_ANDMASK = f67
+F_ORMASK = f68
+F_S = f69
+F_05 = f70
+F_SQRT_1S2 = f71
+F_DS = f72
+F_Z = f73
+F_1T2 = f74
+F_DZ = f75
+F_ZE = f76
+F_YZ = f77
+F_Y1S2 = f78
+F_Y1S2X = f79
+F_1X = f80
+F_ST = f81
+F_1T2_ST = f82
+F_TSS = f83
+F_Y1S2X2 = f84
+F_DZ_TERM = f85
+F_DTS = f86
+F_DS2X = f87
+F_T2 = f88
+F_ZY1S2S = f89
+F_Y1S2_1X = f90
+F_TS = f91
+F_PI2_LO = f92
+F_PI2_HI = f93
+F_S19 = f94
+F_INV1T2_2 = f95
+F_CORR = f96
+F_DZ0 = f97
+
+F_C11 = f98
+F_C13 = f99
+F_C15 = f100
+F_C17 = f101
+F_P1113 = f102
+F_P1517 = f103
+F_P1117 = f104
+F_P317 = f105
+F_R8 = f106
+F_HI = f107
+F_1S2_HI = f108
+F_DS2 = f109
+F_Y2_2 = f110
+//F_S2 = f111
+//F_S_DS2 = f112
+F_S_1S2S = f113
+F_XL = f114
+F_2M128 = f115
+F_1AS = f116
+F_AS = f117
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(acosl)
+
+{.mfi
+ // get exponent, mantissa (rounded to double precision) of s
+ getf.d R_DBL_S = f8
+ // 1-s^2
+ fnma.s1 F_1S2 = f8, f8, f1
+ // r2 = pointer to T_table
+ addl r2 = @ltoff(T_table), gp
+}
+
+{.mfi
+ // sign mask
+ mov R_SGNMASK = 0x20000
+ nop.f 0
+ // bias-63-1
+ mov R_TMP03 = 0xffff-64;;
+}
+
+
+{.mfi
+ // get exponent of s
+ getf.exp R_EXP = f8
+ nop.f 0
+ // R_TMP4 = 2^45
+ shl R_TMP4 = R_SGNMASK, 45-17
+}
+
+{.mlx
+ // load bias-4
+ mov R_TMP = 0xffff-4
+ // load RU(sqrt(2)/2) to integer register (in double format, shifted left by 1)
+ movl R_TMP2 = 0x7fcd413cccfe779a;;
+}
+
+
+{.mfi
+ // load 2^{-64} in FP register
+ setf.exp F_2M64 = R_TMP03
+ nop.f 0
+ // index = (0x7-exponent)|b1 b2.. b6
+ extr.u R_INDEX = R_DBL_S, 46, 9
+}
+
+{.mfi
+ // get t = sign|exponent|b1 b2.. b6 1 x.. x
+ or R_T = R_DBL_S, R_TMP4
+ nop.f 0
+ // R_TMP4 = 2^45-1
+ sub R_TMP4 = R_TMP4, r0, 1;;
+}
+
+
+{.mfi
+ // get t = sign|exponent|b1 b2.. b6 1 0.. 0
+ andcm R_T = R_T, R_TMP4
+ nop.f 0
+ // eliminate sign from R_DBL_S (shift left by 1)
+ shl R_TMP3 = R_DBL_S, 1
+}
+
+{.mfi
+ // R_BIAS = 3*2^6
+ mov R_BIAS = 0xc0
+ nop.f 0
+ // eliminate sign from R_EXP
+ andcm R_EXP0 = R_EXP, R_SGNMASK;;
+}
+
+
+
+{.mfi
+ // load start address for T_table
+ ld8 r2 = [r2]
+ nop.f 0
+ // p8 = 1 if |s|> = sqrt(2)/2
+ cmp.geu p8, p0 = R_TMP3, R_TMP2
+}
+
+{.mlx
+ // p7 = 1 if |s|<2^{-4} (exponent of s<bias-4)
+ cmp.lt p7, p0 = R_EXP0, R_TMP
+ // sqrt coefficient cs8 = -33*13/128
+ movl R_TMP2 = 0xc0568000;;
+}
+
+
+
+{.mbb
+ // load t in FP register
+ setf.d F_T = R_T
+ // if |s|<2^{-4}, take alternate path
+ (p7) br.cond.spnt SMALL_S
+ // if |s|> = sqrt(2)/2, take alternate path
+ (p8) br.cond.sptk LARGE_S
+}
+
+{.mlx
+ // index = (4-exponent)|b1 b2.. b6
+ sub R_INDEX = R_INDEX, R_BIAS
+ // sqrt coefficient cs9 = 55*13/128
+ movl R_TMP = 0x40b2c000;;
+}
+
+
+{.mfi
+ // sqrt coefficient cs8 = -33*13/128
+ setf.s F_CS8 = R_TMP2
+ nop.f 0
+ // shift R_INDEX by 5
+ shl R_INDEX = R_INDEX, 5
+}
+
+{.mfi
+ // sqrt coefficient cs3 = 0.5 (set exponent = bias-1)
+ mov R_TMP4 = 0xffff - 1
+ nop.f 0
+ // sqrt coefficient cs6 = -21/16
+ mov R_TMP6 = 0xbfa8;;
+}
+
+
+{.mlx
+ // table index
+ add r2 = r2, R_INDEX
+ // sqrt coefficient cs7 = 33/16
+ movl R_TMP2 = 0x40040000;;
+}
+
+
+{.mmi
+ // load cs9 = 55*13/128
+ setf.s F_CS9 = R_TMP
+ // sqrt coefficient cs5 = 7/8
+ mov R_TMP3 = 0x3f60
+ // sqrt coefficient cs6 = 21/16
+ shl R_TMP6 = R_TMP6, 16;;
+}
+
+
+{.mmi
+ // load significand of 1/(1-t^2)
+ ldf8 F_INV_1T2 = [r2], 8
+ // sqrt coefficient cs7 = 33/16
+ setf.s F_CS7 = R_TMP2
+ // sqrt coefficient cs4 = -5/8
+ mov R_TMP5 = 0xbf20;;
+}
+
+
+{.mmi
+ // load significand of sqrt(1-t^2)
+ ldf8 F_SQRT_1T2 = [r2], 8
+ // sqrt coefficient cs6 = 21/16
+ setf.s F_CS6 = R_TMP6
+ // sqrt coefficient cs5 = 7/8
+ shl R_TMP3 = R_TMP3, 16;;
+}
+
+
+{.mmi
+ // sqrt coefficient cs3 = 0.5 (set exponent = bias-1)
+ setf.exp F_CS3 = R_TMP4
+ // r3 = pointer to polynomial coefficients
+ addl r3 = @ltoff(poly_coeffs), gp
+ // sqrt coefficient cs4 = -5/8
+ shl R_TMP5 = R_TMP5, 16;;
+}
+
+
+{.mfi
+ // sqrt coefficient cs5 = 7/8
+ setf.s F_CS5 = R_TMP3
+ // d = s-t
+ fms.s1 F_D = f8, f1, F_T
+ // set p6 = 1 if s<0, p11 = 1 if s> = 0
+ cmp.ge p6, p11 = R_EXP, R_DBL_S
+}
+
+{.mfi
+ // r3 = load start address to polynomial coefficients
+ ld8 r3 = [r3]
+ // s+t
+ fma.s1 F_S2T2 = f8, f1, F_T
+ nop.i 0;;
+}
+
+
+{.mfi
+ // sqrt coefficient cs4 = -5/8
+ setf.s F_CS4 = R_TMP5
+ // s^2-t^2
+ fma.s1 F_S2T2 = F_S2T2, F_D, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ // load C3
+ ldfe F_C3 = [r3], 16
+ // 0.5/(1-t^2) = 2^{-64}*(2^63/(1-t^2))
+ fma.s1 F_INV_1T2 = F_INV_1T2, F_2M64, f0
+ nop.i 0;;
+}
+
+{.mfi
+ // load C_5
+ ldfe F_C5 = [r3], 16
+ // set correct exponent for sqrt(1-t^2)
+ fma.s1 F_SQRT_1T2 = F_SQRT_1T2, F_2M64, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ // load C_7, C_9
+ ldfpd F_C7, F_C9 = [r3], 16
+ // x = -(s^2-t^2)/(1-t^2)/2
+ fnma.s1 F_X = F_INV_1T2, F_S2T2, f0
+ nop.i 0;;
+}
+
+
+{.mmf
+ // load asin(t)_high, asin(t)_low
+ ldfpd F_ATHI, F_ATLO = [r2]
+ // load pi/2
+ ldfpd F_PI2_LO, F_PI2_HI = [r3]
+ // t*sqrt(1-t^2)
+ fma.s1 F_TSQRT = F_T, F_SQRT_1T2, f0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // cs9*x+cs8
+ fma.s1 F_S89 = F_CS9, F_X, F_CS8
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // cs7*x+cs6
+ fma.s1 F_S67 = F_CS7, F_X, F_CS6
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // cs5*x+cs4
+ fma.s1 F_S45 = F_CS5, F_X, F_CS4
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // x*x
+ fma.s1 F_X2 = F_X, F_X, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (s-t)-t*x
+ fnma.s1 F_DTX = F_T, F_X, F_D
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // cs3*x+cs2 (cs2 = -0.5 = -cs3)
+ fms.s1 F_S23 = F_CS3, F_X, F_CS3
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // if sign is negative, negate table values: asin(t)_low
+ (p6) fnma.s1 F_ATLO = F_ATLO, f1, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // if sign is negative, negate table values: asin(t)_high
+ (p6) fnma.s1 F_ATHI = F_ATHI, f1, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // cs9*x^3+cs8*x^2+cs7*x+cs6
+ fma.s1 F_S69 = F_S89, F_X2, F_S67
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // x^4
+ fma.s1 F_X4 = F_X2, F_X2, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // t*sqrt(1-t^2)*x^2
+ fma.s1 F_TSQRT = F_TSQRT, F_X2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // cs5*x^3+cs4*x^2+cs3*x+cs2
+ fma.s1 F_S25 = F_S45, F_X2, F_S23
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // ((s-t)-t*x)*sqrt(1-t^2)
+ fma.s1 F_DTX = F_DTX, F_SQRT_1T2, f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // (pi/2)_high - asin(t)_high
+ fnma.s1 F_ATHI = F_ATHI, f1, F_PI2_HI
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // asin(t)_low - (pi/2)_low
+ fnma.s1 F_ATLO = F_PI2_LO, f1, F_ATLO
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // PS29 = cs9*x^7+..+cs5*x^3+cs4*x^2+cs3*x+cs2
+ fma.s1 F_S29 = F_S69, F_X4, F_S25
+ nop.i 0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // R = ((s-t)-t*x)*sqrt(1-t^2)-t*sqrt(1-t^2)*x^2*PS29
+ fnma.s1 F_R = F_S29, F_TSQRT, F_DTX
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // R^2
+ fma.s1 F_R2 = F_R, F_R, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c7+c9*R^2
+ fma.s1 F_P79 = F_C9, F_R2, F_C7
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2
+ fma.s1 F_P35 = F_C5, F_R2, F_C3
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // R^3
+ fma.s1 F_R4 = F_R2, F_R2, f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // R^3
+ fma.s1 F_R3 = F_R2, F_R, f0
+ nop.i 0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2+c7*R^4+c9*R^6
+ fma.s1 F_P39 = F_P79, F_R4, F_P35
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6)
+ fma.s1 F_P39 = F_P39, F_R3, F_ATLO
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // R+asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6)
+ fma.s1 F_P39 = F_P39, f1, F_R
+ nop.i 0;;
+}
+
+
+{.mfb
+ nop.m 0
+ // result = (pi/2)-asin(t)_high+R+asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6)
+ fnma.s0 f8 = F_P39, f1, F_ATHI
+ // return
+ br.ret.sptk b0;;
+}
+
+
+
+
+LARGE_S:
+
+{.mfi
+ // bias-1
+ mov R_TMP3 = 0xffff - 1
+ // y ~ 1/sqrt(1-s^2)
+ frsqrta.s1 F_Y, p7 = F_1S2
+ // c9 = 55*13*17/128
+ mov R_TMP4 = 0x10af7b
+}
+
+{.mlx
+ // c8 = -33*13*15/128
+ mov R_TMP5 = 0x184923
+ movl R_TMP2 = 0xff00000000000000;;
+}
+
+{.mfi
+ // set p6 = 1 if s<0, p11 = 1 if s>0
+ cmp.ge p6, p11 = R_EXP, R_DBL_S
+ // 1-s^2
+ fnma.s1 F_1S2 = f8, f8, f1
+ // set p9 = 1
+ cmp.eq p9, p0 = r0, r0;;
+}
+
+
+{.mfi
+ // load 0.5
+ setf.exp F_05 = R_TMP3
+ // (1-s^2) rounded to single precision
+ fnma.s.s1 F_1S2_S = f8, f8, f1
+ // c9 = 55*13*17/128
+ shl R_TMP4 = R_TMP4, 10
+}
+
+{.mlx
+ // AND mask for getting t ~ sqrt(1-s^2)
+ setf.sig F_ANDMASK = R_TMP2
+ // OR mask
+ movl R_TMP2 = 0x0100000000000000;;
+}
+
+.pred.rel "mutex", p6, p11
+{.mfi
+ nop.m 0
+ // 1-|s|
+ (p6) fma.s1 F_1AS = f8, f1, f1
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // 1-|s|
+ (p11) fnma.s1 F_1AS = f8, f1, f1
+ nop.i 0;;
+}
+
+
+{.mfi
+ // c9 = 55*13*17/128
+ setf.s F_CS9 = R_TMP4
+ // |s|
+ (p6) fnma.s1 F_AS = f8, f1, f0
+ // c8 = -33*13*15/128
+ shl R_TMP5 = R_TMP5, 11
+}
+
+{.mfi
+ // c7 = 33*13/16
+ mov R_TMP4 = 0x41d68
+ // |s|
+ (p11) fma.s1 F_AS = f8, f1, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ setf.sig F_ORMASK = R_TMP2
+ // y^2
+ fma.s1 F_Y2 = F_Y, F_Y, f0
+ // c7 = 33*13/16
+ shl R_TMP4 = R_TMP4, 12
+}
+
+{.mfi
+ // c6 = -33*7/16
+ mov R_TMP6 = 0xc1670
+ // y' ~ sqrt(1-s^2)
+ fma.s1 F_T1 = F_Y, F_1S2, f0
+ // c5 = 63/8
+ mov R_TMP7 = 0x40fc;;
+}
+
+
+{.mlx
+ // load c8 = -33*13*15/128
+ setf.s F_CS8 = R_TMP5
+ // c4 = -35/8
+ movl R_TMP5 = 0xc08c0000;;
+}
+
+{.mfi
+ // r3 = pointer to polynomial coefficients
+ addl r3 = @ltoff(poly_coeffs), gp
+ // 1-s-(1-s^2)_s
+ fnma.s1 F_DS = F_1S2_S, f1, F_1AS
+ // p9 = 0 if p7 = 1 (p9 = 1 for special cases only)
+ (p7) cmp.ne p9, p0 = r0, r0
+}
+
+{.mlx
+ // load c7 = 33*13/16
+ setf.s F_CS7 = R_TMP4
+ // c3 = 5/2
+ movl R_TMP4 = 0x40200000;;
+}
+
+
+{.mlx
+ // load c4 = -35/8
+ setf.s F_CS4 = R_TMP5
+ // c2 = -3/2
+ movl R_TMP5 = 0xbfc00000;;
+}
+
+
+{.mfi
+ // load c3 = 5/2
+ setf.s F_CS3 = R_TMP4
+ // x = (1-s^2)_s*y^2-1
+ fms.s1 F_X = F_1S2_S, F_Y2, f1
+ // c6 = -33*7/16
+ shl R_TMP6 = R_TMP6, 12
+}
+
+{.mfi
+ nop.m 0
+ // y^2/2
+ fma.s1 F_Y2_2 = F_Y2, F_05, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ // load c6 = -33*7/16
+ setf.s F_CS6 = R_TMP6
+ // eliminate lower bits from y'
+ fand F_T = F_T1, F_ANDMASK
+ // c5 = 63/8
+ shl R_TMP7 = R_TMP7, 16
+}
+
+
+{.mfb
+ // r3 = load start address to polynomial coefficients
+ ld8 r3 = [r3]
+ // 1-(1-s^2)_s-s^2
+ fma.s1 F_DS = F_AS, F_1AS, F_DS
+ // p9 = 1 if s is a special input (NaN, or |s|> = 1)
+ (p9) br.cond.spnt acosl_SPECIAL_CASES;;
+}
+
+{.mmf
+ // get exponent, significand of y' (in single prec.)
+ getf.s R_TMP = F_T1
+ // load c3 = -3/2
+ setf.s F_CS2 = R_TMP5
+ // y*(1-s^2)
+ fma.s1 F_Y1S2 = F_Y, F_1S2, f0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // if s<0, set s = -s
+ (p6) fnma.s1 f8 = f8, f1, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ // load c5 = 63/8
+ setf.s F_CS5 = R_TMP7
+ // x = (1-s^2)_s*y^2-1+(1-(1-s^2)_s-s^2)*y^2
+ fma.s1 F_X = F_DS, F_Y2, F_X
+ // for t = 2^k*1.b1 b2.., get 7-k|b1.. b6
+ extr.u R_INDEX = R_TMP, 17, 9;;
+}
+
+
+{.mmi
+ // index = (4-exponent)|b1 b2.. b6
+ sub R_INDEX = R_INDEX, R_BIAS
+ nop.m 0
+ // get exponent of y
+ shr.u R_TMP2 = R_TMP, 23;;
+}
+
+{.mmi
+ // load C3
+ ldfe F_C3 = [r3], 16
+ // set p8 = 1 if y'<2^{-4}
+ cmp.gt p8, p0 = 0x7b, R_TMP2
+ // shift R_INDEX by 5
+ shl R_INDEX = R_INDEX, 5;;
+}
+
+
+{.mfb
+ // get table index for sqrt(1-t^2)
+ add r2 = r2, R_INDEX
+ // get t = 2^k*1.b1 b2.. b7 1
+ for F_T = F_T, F_ORMASK
+ (p8) br.cond.spnt VERY_LARGE_INPUT;;
+}
+
+
+
+{.mmf
+ // load C5
+ ldfe F_C5 = [r3], 16
+ // load 1/(1-t^2)
+ ldfp8 F_INV_1T2, F_SQRT_1T2 = [r2], 16
+ // x = ((1-s^2)*y^2-1)/2
+ fma.s1 F_X = F_X, F_05, f0;;
+}
+
+
+
+{.mmf
+ nop.m 0
+ // C7, C9
+ ldfpd F_C7, F_C9 = [r3], 16
+ // set correct exponent for t
+ fmerge.se F_T = F_T1, F_T;;
+}
+
+
+
+{.mfi
+ // get address for loading pi
+ add r3 = 48, r3
+ // c9*x+c8
+ fma.s1 F_S89 = F_X, F_CS9, F_CS8
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // x^2
+ fma.s1 F_X2 = F_X, F_X, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ // pi (low, high)
+ ldfpd F_PI2_LO, F_PI2_HI = [r3]
+ // y*(1-s^2)*x
+ fma.s1 F_Y1S2X = F_Y1S2, F_X, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c7*x+c6
+ fma.s1 F_S67 = F_X, F_CS7, F_CS6
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // 1-x
+ fnma.s1 F_1X = F_X, f1, f1
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c3*x+c2
+ fma.s1 F_S23 = F_X, F_CS3, F_CS2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // 1-t^2
+ fnma.s1 F_1T2 = F_T, F_T, f1
+ nop.i 0
+}
+
+{.mfi
+ // load asin(t)_high, asin(t)_low
+ ldfpd F_ATHI, F_ATLO = [r2]
+ // c5*x+c4
+ fma.s1 F_S45 = F_X, F_CS5, F_CS4
+ nop.i 0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // t*s
+ fma.s1 F_TS = F_T, f8, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // 0.5/(1-t^2)
+ fma.s1 F_INV_1T2 = F_INV_1T2, F_2M64, f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // z~sqrt(1-t^2), rounded to 24 significant bits
+ fma.s.s1 F_Z = F_SQRT_1T2, F_2M64, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // sqrt(1-t^2)
+ fma.s1 F_SQRT_1T2 = F_SQRT_1T2, F_2M64, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*(1-s^2)*x^2
+ fma.s1 F_Y1S2X2 = F_Y1S2, F_X2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // x^4
+ fma.s1 F_X4 = F_X2, F_X2, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // s*t rounded to 24 significant bits
+ fma.s.s1 F_TSS = F_T, f8, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c9*x^3+..+c6
+ fma.s1 F_S69 = F_X2, F_S89, F_S67
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // ST = (t^2-1+s^2) rounded to 24 significant bits
+ fms.s.s1 F_ST = f8, f8, F_1T2
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c5*x^3+..+c2
+ fma.s1 F_S25 = F_X2, F_S45, F_S23
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // 0.25/(1-t^2)
+ fma.s1 F_INV1T2_2 = F_05, F_INV_1T2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // t*s-sqrt(1-t^2)*(1-s^2)*y
+ fnma.s1 F_TS = F_Y1S2, F_SQRT_1T2, F_TS
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // z*0.5/(1-t^2)
+ fma.s1 F_ZE = F_INV_1T2, F_SQRT_1T2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // z^2+t^2-1
+ fms.s1 F_DZ0 = F_Z, F_Z, F_1T2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (1-s^2-(1-s^2)_s)*x
+ fma.s1 F_DS2X = F_X, F_DS, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // t*s-(t*s)_s
+ fms.s1 F_DTS = F_T, f8, F_TSS
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c9*x^7+..+c2
+ fma.s1 F_S29 = F_X4, F_S69, F_S25
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*z
+ fma.s1 F_YZ = F_Z, F_Y, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // t^2
+ fma.s1 F_T2 = F_T, F_T, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // 1-t^2+ST
+ fma.s1 F_1T2_ST = F_ST, f1, F_1T2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*(1-s^2)(1-x)
+ fma.s1 F_Y1S2_1X = F_Y1S2, F_1X, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // dz ~ sqrt(1-t^2)-z
+ fma.s1 F_DZ = F_DZ0, F_ZE, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // -1+correction for sqrt(1-t^2)-z
+ fnma.s1 F_CORR = F_INV1T2_2, F_DZ0, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (PS29*x^2+x)*y*(1-s^2)
+ fma.s1 F_S19 = F_Y1S2X2, F_S29, F_Y1S2X
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // z*y*(1-s^2)_s
+ fma.s1 F_ZY1S2S = F_YZ, F_1S2_S, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // s^2-(1-t^2+ST)
+ fms.s1 F_1T2_ST = f8, f8, F_1T2_ST
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (t*s-(t*s)_s)+z*y*(1-s^2-(1-s^2)_s)*x
+ fma.s1 F_DTS = F_YZ, F_DS2X, F_DTS
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // dz*y*(1-s^2)*(1-x)
+ fma.s1 F_DZ_TERM = F_DZ, F_Y1S2_1X, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // R = t*s-sqrt(1-t^2)*(1-s^2)*y+sqrt(1-t^2)*(1-s^2)*y*PS19
+ // (used for polynomial evaluation)
+ fma.s1 F_R = F_S19, F_SQRT_1T2, F_TS
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (PS29*x^2)*y*(1-s^2)
+ fma.s1 F_S29 = F_Y1S2X2, F_S29, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // apply correction to dz*y*(1-s^2)*(1-x)
+ fma.s1 F_DZ_TERM = F_DZ_TERM, F_CORR, F_DZ_TERM
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // R^2
+ fma.s1 F_R2 = F_R, F_R, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (t*s-(t*s)_s)+z*y*(1-s^2-(1-s^2)_s)*x+dz*y*(1-s^2)*(1-x)
+ fma.s1 F_DZ_TERM = F_DZ_TERM, f1, F_DTS
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c7+c9*R^2
+ fma.s1 F_P79 = F_C9, F_R2, F_C7
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2
+ fma.s1 F_P35 = F_C5, F_R2, F_C3
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // asin(t)_low-(pi)_low (if s<0)
+ (p6) fms.s1 F_ATLO = F_ATLO, f1, F_PI2_LO
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // R^4
+ fma.s1 F_R4 = F_R2, F_R2, f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // R^3
+ fma.s1 F_R3 = F_R2, F_R, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (t*s)_s-t^2*y*z
+ fnma.s1 F_TSS = F_T2, F_YZ, F_TSS
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // d(ts)+z*y*d(1-s^2)*x+dz*y*(1-s^2)*(1-x)+z*y*(s^2-1+t^2-ST)
+ fma.s1 F_DZ_TERM = F_YZ, F_1T2_ST, F_DZ_TERM
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (pi)_hi-asin(t)_hi (if s<0)
+ (p6) fms.s1 F_ATHI = F_PI2_HI, f1, F_ATHI
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2+c7*R^4+c9*R^6
+ fma.s1 F_P39 = F_P79, F_R4, F_P35
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // d(ts)+z*y*d(1-s^2)*x+dz*y*(1-s^2)*(1-x)+z*y*(s^2-1+t^2-ST)+
+ // + sqrt(1-t^2)*y*(1-s^2)*x^2*PS29
+ fma.s1 F_DZ_TERM = F_SQRT_1T2, F_S29, F_DZ_TERM
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (t*s)_s-t^2*y*z+z*y*ST
+ fma.s1 F_TSS = F_YZ, F_ST, F_TSS
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // -asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6)
+ fms.s1 F_P39 = F_P39, F_R3, F_ATLO
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // d(ts)+z*y*d(1-s^2)*x+dz*y*(1-s^2)*(1-x)+z*y*(s^2-1+t^2-ST) +
+ // + sqrt(1-t^2)*y*(1-s^2)*x^2*PS29 +
+ // - asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6)
+ fma.s1 F_DZ_TERM = F_P39, f1, F_DZ_TERM
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // d(ts)+z*y*d(1-s^2)*x+dz*y*(1-s^2)*(1-x)+z*y*(s^2-1+t^2-ST) +
+ // + sqrt(1-t^2)*y*(1-s^2)*x^2*PS29 + z*y*(1-s^2)_s*x +
+ // - asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6)
+ fma.s1 F_DZ_TERM = F_ZY1S2S, F_X, F_DZ_TERM
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // d(ts)+z*y*d(1-s^2)*x+dz*y*(1-s^2)*(1-x)+z*y*(s^2-1+t^2-ST) +
+ // + sqrt(1-t^2)*y*(1-s^2)*x^2*PS29 + z*y*(1-s^2)_s*x +
+ // - asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6) +
+ // + (t*s)_s-t^2*y*z+z*y*ST
+ fma.s1 F_DZ_TERM = F_TSS, f1, F_DZ_TERM
+ nop.i 0;;
+}
+
+
+.pred.rel "mutex", p6, p11
+{.mfi
+ nop.m 0
+ // result: add high part of table value
+ // s>0 in this case
+ (p11) fnma.s0 f8 = F_DZ_TERM, f1, F_ATHI
+ nop.i 0
+}
+
+{.mfb
+ nop.m 0
+ // result: add high part of pi-table value
+ // if s<0
+ (p6) fma.s0 f8 = F_DZ_TERM, f1, F_ATHI
+ br.ret.sptk b0;;
+}
+
+
+
+
+
+
+SMALL_S:
+
+ // use 15-term polynomial approximation
+
+{.mmi
+ // r3 = pointer to polynomial coefficients
+ addl r3 = @ltoff(poly_coeffs), gp;;
+ // load start address for coefficients
+ ld8 r3 = [r3]
+ mov R_TMP = 0x3fbf;;
+}
+
+
+{.mmi
+ add r2 = 64, r3
+ ldfe F_C3 = [r3], 16
+ // p7 = 1 if |s|<2^{-64} (exponent of s<bias-64)
+ cmp.lt p7, p0 = R_EXP0, R_TMP;;
+}
+
+{.mmf
+ ldfe F_C5 = [r3], 16
+ ldfpd F_C11, F_C13 = [r2], 16
+ nop.f 0;;
+}
+
+{.mmf
+ ldfpd F_C7, F_C9 = [r3], 16
+ ldfpd F_C15, F_C17 = [r2]
+ nop.f 0;;
+}
+
+
+
+{.mfb
+ // load pi/2
+ ldfpd F_PI2_LO, F_PI2_HI = [r3]
+ // s^2
+ fma.s1 F_R2 = f8, f8, f0
+ // |s|<2^{-64}
+ (p7) br.cond.spnt RETURN_PI2;;
+}
+
+
+{.mfi
+ nop.m 0
+ // s^3
+ fma.s1 F_R3 = f8, F_R2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // s^4
+ fma.s1 F_R4 = F_R2, F_R2, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c3+c5*s^2
+ fma.s1 F_P35 = F_C5, F_R2, F_C3
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c11+c13*s^2
+ fma.s1 F_P1113 = F_C13, F_R2, F_C11
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c7+c9*s^2
+ fma.s1 F_P79 = F_C9, F_R2, F_C7
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c15+c17*s^2
+ fma.s1 F_P1517 = F_C17, F_R2, F_C15
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // (pi/2)_high-s_high
+ fnma.s1 F_T = f8, f1, F_PI2_HI
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // s^8
+ fma.s1 F_R8 = F_R4, F_R4, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c3+c5*s^2+c7*s^4+c9*s^6
+ fma.s1 F_P39 = F_P79, F_R4, F_P35
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c11+c13*s^2+c15*s^4+c17*s^6
+ fma.s1 F_P1117 = F_P1517, F_R4, F_P1113
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // -s_high
+ fms.s1 F_S = F_T, f1, F_PI2_HI
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // c3+..+c17*s^14
+ fma.s1 F_P317 = F_R8, F_P1117, F_P39
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // s_low
+ fma.s1 F_DS = f8, f1, F_S
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // (pi/2)_low-s^3*(c3+..+c17*s^14)
+ fnma.s0 F_P317 = F_P317, F_R3, F_PI2_LO
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // (pi/2)_low-s_low-s^3*(c3+..+c17*s^14)
+ fms.s1 F_P317 = F_P317, f1, F_DS
+ nop.i 0;;
+}
+
+{.mfb
+ nop.m 0
+ // result: pi/2-s-c3*s^3-..-c17*s^17
+ fma.s0 f8 = F_T, f1, F_P317
+ br.ret.sptk b0;;
+}
+
+
+
+
+
+RETURN_PI2:
+
+{.mfi
+ nop.m 0
+ // (pi/2)_low-s
+ fms.s0 F_PI2_LO = F_PI2_LO, f1, f8
+ nop.i 0;;
+}
+
+{.mfb
+ nop.m 0
+ // (pi/2)-s
+ fma.s0 f8 = F_PI2_HI, f1, F_PI2_LO
+ br.ret.sptk b0;;
+}
+
+
+
+
+
+VERY_LARGE_INPUT:
+
+
+{.mmf
+ // pointer to pi_low, pi_high
+ add r2 = 80, r3
+ // load C5
+ ldfe F_C5 = [r3], 16
+ // x = ((1-(s^2)_s)*y^2-1)/2-(s^2-(s^2)_s)*y^2/2
+ fma.s1 F_X = F_X, F_05, f0;;
+}
+
+.pred.rel "mutex", p6, p11
+{.mmf
+ // load pi (low, high), if s<0
+ (p6) ldfpd F_PI2_LO, F_PI2_HI = [r2]
+ // C7, C9
+ ldfpd F_C7, F_C9 = [r3], 16
+ // if s>0, set F_PI2_LO=0
+ (p11) fma.s1 F_PI2_HI = f0, f0, f0;;
+}
+
+{.mfi
+ nop.m 0
+ (p11) fma.s1 F_PI2_LO = f0, f0, f0
+ nop.i 0;;
+}
+
+{.mfi
+ // adjust address for C_11
+ add r3 = 16, r3
+ // c9*x+c8
+ fma.s1 F_S89 = F_X, F_CS9, F_CS8
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // x^2
+ fma.s1 F_X2 = F_X, F_X, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*(1-s^2)*x
+ fma.s1 F_Y1S2X = F_Y1S2, F_X, f0
+ nop.i 0
+}
+
+{.mfi
+ // C11, C13
+ ldfpd F_C11, F_C13 = [r3], 16
+ // c7*x+c6
+ fma.s1 F_S67 = F_X, F_CS7, F_CS6
+ nop.i 0;;
+}
+
+
+{.mfi
+ // C15, C17
+ ldfpd F_C15, F_C17 = [r3], 16
+ // c3*x+c2
+ fma.s1 F_S23 = F_X, F_CS3, F_CS2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c5*x+c4
+ fma.s1 F_S45 = F_X, F_CS5, F_CS4
+ nop.i 0;;
+}
+
+
+
+
+{.mfi
+ nop.m 0
+ // y*(1-s^2)*x^2
+ fma.s1 F_Y1S2X2 = F_Y1S2, F_X2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // x^4
+ fma.s1 F_X4 = F_X2, F_X2, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c9*x^3+..+c6
+ fma.s1 F_S69 = F_X2, F_S89, F_S67
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c5*x^3+..+c2
+ fma.s1 F_S25 = F_X2, F_S45, F_S23
+ nop.i 0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // (pi)_high-y*(1-s^2)_s
+ fnma.s1 F_HI = F_Y, F_1S2_S, F_PI2_HI
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c9*x^7+..+c2
+ fma.s1 F_S29 = F_X4, F_S69, F_S25
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // -(y*(1-s^2)_s)_high
+ fms.s1 F_1S2_HI = F_HI, f1, F_PI2_HI
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (PS29*x^2+x)*y*(1-s^2)
+ fma.s1 F_S19 = F_Y1S2X2, F_S29, F_Y1S2X
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*(1-s^2)_s-(y*(1-s^2))_high
+ fma.s1 F_DS2 = F_Y, F_1S2_S, F_1S2_HI
+ nop.i 0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // R ~ sqrt(1-s^2)
+ // (used for polynomial evaluation)
+ fnma.s1 F_R = F_S19, f1, F_Y1S2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*(1-s^2)-(y*(1-s^2))_high
+ fma.s1 F_DS2 = F_Y, F_DS, F_DS2
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // (pi)_low+(PS29*x^2)*y*(1-s^2)
+ fma.s1 F_S29 = F_Y1S2X2, F_S29, F_PI2_LO
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // R^2
+ fma.s1 F_R2 = F_R, F_R, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // if s<0
+ // (pi)_low+(PS29*x^2)*y*(1-s^2)-(y*(1-s^2)-(y*(1-s^2))_high)
+ fms.s1 F_S29 = F_S29, f1, F_DS2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c7+c9*R^2
+ fma.s1 F_P79 = F_C9, F_R2, F_C7
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2
+ fma.s1 F_P35 = F_C5, F_R2, F_C3
+ nop.i 0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // R^4
+ fma.s1 F_R4 = F_R2, F_R2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // R^3
+ fma.s1 F_R3 = F_R2, F_R, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c11+c13*R^2
+ fma.s1 F_P1113 = F_C13, F_R2, F_C11
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c15+c17*R^2
+ fma.s1 F_P1517 = F_C17, F_R2, F_C15
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (pi)_low+(PS29*x^2)*y*(1-s^2)-(y*(1-s^2)-(y*(1-s^2))_high)+y*(1-s^2)*x
+ fma.s1 F_S29 = F_Y1S2, F_X, F_S29
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c11+c13*R^2+c15*R^4+c17*R^6
+ fma.s1 F_P1117 = F_P1517, F_R4, F_P1113
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2+c7*R^4+c9*R^6
+ fma.s1 F_P39 = F_P79, F_R4, F_P35
+ nop.i 0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // R^8
+ fma.s1 F_R8 = F_R4, F_R4, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2+c7*R^4+c9*R^6+..+c17*R^14
+ fma.s1 F_P317 = F_P1117, F_R8, F_P39
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (pi)_low-(PS29*x^2)*y*(1-s^2)-(y*(1-s^2)-
+ // -(y*(1-s^2))_high)+y*(1-s^2)*x - P3, 17
+ fnma.s1 F_S29 = F_P317, F_R3, F_S29
+ nop.i 0;;
+}
+
+.pred.rel "mutex", p6, p11
+{.mfi
+ nop.m 0
+ // Result (if s<0):
+ // (pi)_low-(PS29*x^2)*y*(1-s^2)-(y*(1-s^2)-
+ // -(y*(1-s^2))_high)+y*(1-s^2)*x - P3, 17
+ // +(pi)_high-(y*(1-s^2))_high
+ (p6) fma.s0 f8 = F_S29, f1, F_HI
+ nop.i 0
+}
+
+{.mfb
+ nop.m 0
+ // Result (if s>0):
+ // (PS29*x^2)*y*(1-s^2)-
+ // -y*(1-s^2)*x + P3, 17
+ // +(y*(1-s^2))
+ (p11) fms.s0 f8 = F_Y, F_1S2_S, F_S29
+ br.ret.sptk b0;;
+}
+
+
+
+
+
+
+acosl_SPECIAL_CASES:
+
+{.mfi
+ alloc r32 = ar.pfs, 1, 4, 4, 0
+ // check if the input is a NaN, or unsupported format
+ // (i.e. not infinity or normal/denormal)
+ fclass.nm p7, p8 = f8, 0x3f
+ // pointer to pi/2
+ add r3 = 96, r3;;
+}
+
+
+{.mfi
+ // load pi/2
+ ldfpd F_PI2_HI, F_PI2_LO = [r3]
+ // get |s|
+ fmerge.s F_S = f0, f8
+ nop.i 0
+}
+
+{.mfb
+ nop.m 0
+ // if NaN, quietize it, and return
+ (p7) fma.s0 f8 = f8, f1, f0
+ (p7) br.ret.spnt b0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // |s| = 1 ?
+ fcmp.eq.s0 p9, p10 = F_S, f1
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // load FR_X
+ fma.s1 FR_X = f8, f1, f0
+ // load error tag
+ mov GR_Parameter_TAG = 57;;
+}
+
+
+{.mfi
+ nop.m 0
+ // if s = 1, result is 0
+ (p9) fma.s0 f8 = f0, f0, f0
+ // set p6=0 for |s|>1
+ (p10) cmp.ne p6, p0 = r0, r0;;
+}
+
+
+{.mfb
+ nop.m 0
+ // if s = -1, result is pi
+ (p6) fma.s0 f8 = F_PI2_HI, f1, F_PI2_LO
+ // return if |s| = 1
+ (p9) br.ret.sptk b0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // get Infinity
+ frcpa.s1 FR_RESULT, p0 = f1, f0
+ nop.i 0;;
+}
+
+
+{.mfb
+ nop.m 0
+ // return QNaN indefinite (0*Infinity)
+ fma.s0 FR_RESULT = f0, FR_RESULT, f0
+ nop.b 0;;
+}
+
+
+GLOBAL_LIBM_END(acosl)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+
+// (2)
+{ .mmi
+ stfe [GR_Parameter_Y] = f1,16 // Store Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+// (4)
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
+
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_asin.S b/libc/sysdeps/ia64/fpu/e_asin.S
new file mode 100644
index 000000000..f995c597f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_asin.S
@@ -0,0 +1,854 @@
+.file "asin.s"
+
+
+// Copyright (c) 2000 - 2003 Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 08/17/00 New and much faster algorithm.
+// 08/31/00 Avoided bank conflicts on loads, shortened |x|=1 path,
+// fixed mfb split issue stalls.
+// 12/19/00 Fixed small arg cases to force inexact, or inexact and underflow.
+// 08/02/02 New and much faster algorithm II
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+
+// Description
+//=========================================
+// The asin function computes the principal value of the arc sine of x.
+// asin(0) returns 0, asin(1) returns pi/2, asin(-1) returns -pi/2.
+// A doman error occurs for arguments not in the range [-1,+1].
+//
+// The asin function returns the arc sine in the range [-pi/2, +pi/2] radians.
+//
+// There are 8 paths:
+// 1. x = +/-0.0
+// Return asin(x) = +/-0.0
+//
+// 2. 0.0 < |x| < 0.625
+// Return asin(x) = x + x^3 *PolA(x^2)
+// where PolA(x^2) = A3 + A5*x^2 + A7*x^4 +...+ A35*x^32
+//
+// 3. 0.625 <=|x| < 1.0
+// Return asin(x) = sign(x) * ( Pi/2 - sqrt(R) * PolB(R))
+// Where R = 1 - |x|,
+// PolB(R) = B0 + B1*R + B2*R^2 +...+B12*R^12
+//
+// sqrt(R) is approximated using the following sequence:
+// y0 = (1 + eps)/sqrt(R) - initial approximation by frsqrta,
+// |eps| < 2^(-8)
+// Then 3 iterations are used to refine the result:
+// H0 = 0.5*y0
+// S0 = R*y0
+//
+// d0 = 0.5 - H0*S0
+// H1 = H0 + d0*H0
+// S1 = S0 + d0*S0
+//
+// d1 = 0.5 - H1*S1
+// H2 = H1 + d0*H1
+// S2 = S1 + d0*S1
+//
+// d2 = 0.5 - H2*S2
+// S3 = S3 + d2*S3
+//
+// S3 approximates sqrt(R) with enough accuracy for this algorithm
+//
+// So, the result should be reconstracted as follows:
+// asin(x) = sign(x) * (Pi/2 - S3*PolB(R))
+//
+// But for optimization perposes the reconstruction step is slightly
+// changed:
+// asin(x) = sign(x)*(Pi/2 - PolB(R)*S2) + sign(x)*d2*S2*PolB(R)
+//
+// 4. |x| = 1.0
+// Return asin(x) = sign(x)*Pi/2
+//
+// 5. 1.0 < |x| <= +INF
+// A doman error occurs for arguments not in the range [-1,+1]
+//
+// 6. x = [S,Q]NaN
+// Return asin(x) = QNaN
+//
+// 7. x is denormal
+// Return asin(x) = x + x^3,
+//
+// 8. x is unnormal
+// Normalize input in f8 and return to the very beginning of the function
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input, output
+// f6, f7, f9 -> f15, f32 -> f63
+
+// General registers used:
+// r3, r21 -> r31, r32 -> r38
+
+// Predicate registers used:
+// p0, p6 -> p14
+
+//
+// Assembly macros
+//=========================================
+// integer registers used
+// scratch
+rTblAddr = r3
+
+rPiBy2Ptr = r21
+rTmpPtr3 = r22
+rDenoBound = r23
+rOne = r24
+rAbsXBits = r25
+rHalf = r26
+r0625 = r27
+rSign = r28
+rXBits = r29
+rTmpPtr2 = r30
+rTmpPtr1 = r31
+
+// stacked
+GR_SAVE_PFS = r32
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Parameter_TAG = r38
+
+// floating point registers used
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+
+// scratch
+fXSqr = f6
+fXCube = f7
+fXQuadr = f9
+f1pX = f10
+f1mX = f11
+f1pXRcp = f12
+f1mXRcp = f13
+fH = f14
+fS = f15
+// stacked
+fA3 = f32
+fB1 = f32
+fA5 = f33
+fB2 = f33
+fA7 = f34
+fPiBy2 = f34
+fA9 = f35
+fA11 = f36
+fB10 = f35
+fB11 = f36
+fA13 = f37
+fA15 = f38
+fB4 = f37
+fB5 = f38
+fA17 = f39
+fA19 = f40
+fB6 = f39
+fB7 = f40
+fA21 = f41
+fA23 = f42
+fB3 = f41
+fB8 = f42
+fA25 = f43
+fA27 = f44
+fB9 = f43
+fB12 = f44
+fA29 = f45
+fA31 = f46
+fA33 = f47
+fA35 = f48
+fBaseP = f49
+fB0 = f50
+fSignedS = f51
+fD = f52
+fHalf = f53
+fR = f54
+fCloseTo1Pol = f55
+fSignX = f56
+fDenoBound = f57
+fNormX = f58
+fX8 = f59
+fRSqr = f60
+fRQuadr = f61
+fR8 = f62
+fX16 = f63
+// Data tables
+//==============================================================
+RODATA
+.align 16
+LOCAL_OBJECT_START(asin_base_range_table)
+// Ai: Polynomial coefficients for the asin(x), |x| < .625000
+// Bi: Polynomial coefficients for the asin(x), |x| > .625000
+data8 0xBFDAAB56C01AE468 //A29
+data8 0x3FE1C470B76A5B2B //A31
+data8 0xBFDC5FF82A0C4205 //A33
+data8 0x3FC71FD88BFE93F0 //A35
+data8 0xB504F333F9DE6487, 0x00003FFF //B0
+data8 0xAAAAAAAAAAAAFC18, 0x00003FFC //A3
+data8 0x3F9F1C71BC4A7823 //A9
+data8 0x3F96E8BBAAB216B2 //A11
+data8 0x3F91C4CA1F9F8A98 //A13
+data8 0x3F8C9DDCEDEBE7A6 //A15
+data8 0x3F877784442B1516 //A17
+data8 0x3F859C0491802BA2 //A19
+data8 0x9999999998C88B8F, 0x00003FFB //A5
+data8 0x3F6BD7A9A660BF5E //A21
+data8 0x3F9FC1659340419D //A23
+data8 0xB6DB6DB798149BDF, 0x00003FFA //A7
+data8 0xBFB3EF18964D3ED3 //A25
+data8 0x3FCD285315542CF2 //A27
+data8 0xF15BEEEFF7D2966A, 0x00003FFB //B1
+data8 0x3EF0DDA376D10FB3 //B10
+data8 0xBEB83CAFE05EBAC9 //B11
+data8 0x3F65FFB67B513644 //B4
+data8 0x3F5032FBB86A4501 //B5
+data8 0x3F392162276C7CBA //B6
+data8 0x3F2435949FD98BDF //B7
+data8 0xD93923D7FA08341C, 0x00003FF9 //B2
+data8 0x3F802995B6D90BDB //B3
+data8 0x3F10DF86B341A63F //B8
+data8 0xC90FDAA22168C235, 0x00003FFF // Pi/2
+data8 0x3EFA3EBD6B0ECB9D //B9
+data8 0x3EDE18BA080E9098 //B12
+LOCAL_OBJECT_END(asin_base_range_table)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(asin)
+asin_unnormal_back:
+{ .mfi
+ getf.d rXBits = f8 // grab bits of input value
+ // set p12 = 1 if x is a NaN, denormal, or zero
+ fclass.m p12, p0 = f8, 0xcf
+ adds rSign = 1, r0
+}
+{ .mfi
+ addl rTblAddr = @ltoff(asin_base_range_table),gp
+ // 1 - x = 1 - |x| for positive x
+ fms.s1 f1mX = f1, f1, f8
+ addl rHalf = 0xFFFE, r0 // exponent of 1/2
+}
+;;
+{ .mfi
+ addl r0625 = 0x3FE4, r0 // high 16 bits of 0.625
+ // set p8 = 1 if x < 0
+ fcmp.lt.s1 p8, p9 = f8, f0
+ shl rSign = rSign, 63 // sign bit
+}
+{ .mfi
+ // point to the beginning of the table
+ ld8 rTblAddr = [rTblAddr]
+ // 1 + x = 1 - |x| for negative x
+ fma.s1 f1pX = f1, f1, f8
+ adds rOne = 0x3FF, r0
+}
+;;
+{ .mfi
+ andcm rAbsXBits = rXBits, rSign // bits of |x|
+ fmerge.s fSignX = f8, f1 // signum(x)
+ shl r0625 = r0625, 48 // bits of DP representation of 0.625
+}
+{ .mfb
+ setf.exp fHalf = rHalf // load A2 to FP reg
+ fma.s1 fXSqr = f8, f8, f0 // x^2
+ // branch on special path if x is a NaN, denormal, or zero
+(p12) br.cond.spnt asin_special
+}
+;;
+{ .mfi
+ adds rPiBy2Ptr = 272, rTblAddr
+ nop.f 0
+ shl rOne = rOne, 52 // bits of 1.0
+}
+{ .mfi
+ adds rTmpPtr1 = 16, rTblAddr
+ nop.f 0
+ // set p6 = 1 if |x| < 0.625
+ cmp.lt p6, p7 = rAbsXBits, r0625
+}
+;;
+{ .mfi
+ ldfpd fA29, fA31 = [rTblAddr] // A29, fA31
+ // 1 - x = 1 - |x| for positive x
+(p9) fms.s1 fR = f1, f1, f8
+ // point to coefficient of "near 1" polynomial
+(p7) adds rTmpPtr2 = 176, rTblAddr
+}
+{ .mfi
+ ldfpd fA33, fA35 = [rTmpPtr1], 16 // A33, fA35
+ // 1 + x = 1 - |x| for negative x
+(p8) fma.s1 fR = f1, f1, f8
+(p6) adds rTmpPtr2 = 48, rTblAddr
+}
+;;
+{ .mfi
+ ldfe fB0 = [rTmpPtr1], 16 // B0
+ nop.f 0
+ nop.i 0
+}
+{ .mib
+ adds rTmpPtr3 = 16, rTmpPtr2
+ // set p10 = 1 if |x| = 1.0
+ cmp.eq p10, p0 = rAbsXBits, rOne
+ // branch on special path for |x| = 1.0
+(p10) br.cond.spnt asin_abs_1
+}
+;;
+{ .mfi
+ ldfe fA3 = [rTmpPtr2], 48 // A3 or B1
+ nop.f 0
+ adds rTmpPtr1 = 64, rTmpPtr3
+}
+{ .mib
+ ldfpd fA9, fA11 = [rTmpPtr3], 16 // A9, A11 or B10, B11
+ // set p11 = 1 if |x| > 1.0
+ cmp.gt p11, p0 = rAbsXBits, rOne
+ // branch on special path for |x| > 1.0
+(p11) br.cond.spnt asin_abs_gt_1
+}
+;;
+{ .mfi
+ ldfpd fA17, fA19 = [rTmpPtr2], 16 // A17, A19 or B6, B7
+ // initial approximation of 1 / sqrt(1 - x)
+ frsqrta.s1 f1mXRcp, p0 = f1mX
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA13, fA15 = [rTmpPtr3] // A13, A15 or B4, B5
+ fma.s1 fXCube = fXSqr, f8, f0 // x^3
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fA5 = [rTmpPtr2], 48 // A5 or B2
+ // initial approximation of 1 / sqrt(1 + x)
+ frsqrta.s1 f1pXRcp, p0 = f1pX
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA21, fA23 = [rTmpPtr1], 16 // A21, A23 or B3, B8
+ fma.s1 fXQuadr = fXSqr, fXSqr, f0 // x^4
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fA7 = [rTmpPtr1] // A7 or Pi/2
+ fma.s1 fRSqr = fR, fR, f0 // R^2
+ nop.i 0
+}
+{ .mfb
+ ldfpd fA25, fA27 = [rTmpPtr2] // A25, A27 or B9, B12
+ nop.f 0
+(p6) br.cond.spnt asin_base_range;
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fH = fHalf, f1mXRcp, f0 // H0 for x > 0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fS = f1mX, f1mXRcp, f0 // S0 for x > 0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fH = fHalf, f1pXRcp, f0 // H0 for x < 0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fS = f1pX, f1pXRcp, f0 // S0 for x > 0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRQuadr = fRSqr, fRSqr, f0 // R^4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fB11 = fB11, fR, fB10
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB1 = fB1, fR, fB0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fB5 = fB5, fR, fB4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB7 = fB7, fR, fB6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fB3 = fB3, fR, fB2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fnma.s1 fD = fH, fS, fHalf // d0 = 1/2 - H0*S0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fR8 = fRQuadr, fRQuadr, f0 // R^4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB9 = fB9, fR, fB8
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fB12 = fB12, fRSqr, fB11
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 fB7 = fB7, fRSqr, fB5
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fB3 = fB3, fRSqr, fB1
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fH = fH, fD, fH // H1 = H0 + H0*d0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS = fS, fD, fS // S1 = S0 + S0*d0
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fPiBy2 = fPiBy2, fSignX, f0 // signum(x)*Pi/2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fB12 = fB12, fRSqr, fB9
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB7 = fB7, fRQuadr, fB3
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fnma.s1 fD = fH, fS, fHalf // d1 = 1/2 - H1*S1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 fSignedS = fSignX, fS, f0 // -signum(x)*S1
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fCloseTo1Pol = fB12, fR8, fB7
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fH = fH, fD, fH // H2 = H1 + H1*d1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS = fS, fD, fS // S2 = S1 + S1*d1
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // -signum(x)* S2 = -signum(x)*(S1 + S1*d1)
+ fma.s1 fSignedS = fSignedS, fD, fSignedS
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fnma.s1 fD = fH, fS, fHalf // d2 = 1/2 - H2*S2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // signum(x)*(Pi/2 - PolB*S2)
+ fma.s1 fPiBy2 = fSignedS, fCloseTo1Pol, fPiBy2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // -signum(x)*PolB * S2
+ fma.s1 fCloseTo1Pol = fSignedS, fCloseTo1Pol, f0
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ // final result for 0.625 <= |x| < 1
+ fma.d.s0 f8 = fCloseTo1Pol, fD, fPiBy2
+ // exit here for 0.625 <= |x| < 1
+ br.ret.sptk b0
+}
+;;
+
+
+// here if |x| < 0.625
+.align 32
+asin_base_range:
+{ .mfi
+ nop.m 0
+ fma.s1 fA33 = fA33, fXSqr, fA31
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, fXSqr, fA13
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA29 = fA29, fXSqr, fA27
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA25 = fA25, fXSqr, fA23
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA21 = fA21, fXSqr, fA19
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, fXSqr, fA7
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA5 = fA5, fXSqr, fA3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA35 = fA35, fXQuadr, fA33
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, fXQuadr, fA15
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fX8 = fXQuadr, fXQuadr, f0 // x^8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA25 = fA25, fXQuadr, fA21
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, fXQuadr, fA5
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA35 = fA35, fXQuadr, fA29
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, fXSqr, fA11
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fX16 = fX8, fX8, f0 // x^16
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA35 = fA35, fX8, fA25
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, fX8, fA9
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fBaseP = fA35, fX16, fA17
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ // final result for |x| < 0.625
+ fma.d.s0 f8 = fBaseP, fXCube, f8
+ // exit here for |x| < 0.625 path
+ br.ret.sptk b0
+}
+;;
+
+// here if |x| = 1
+// asin(x) = sign(x) * Pi/2
+.align 32
+asin_abs_1:
+{ .mfi
+ ldfe fPiBy2 = [rPiBy2Ptr] // Pi/2
+ nop.f 0
+ nop.i 0
+}
+;;
+{.mfb
+ nop.m 0
+ // result for |x| = 1.0
+ fma.d.s0 f8 = fPiBy2, fSignX, f0
+ // exit here for |x| = 1.0
+ br.ret.sptk b0
+}
+;;
+
+// here if x is a NaN, denormal, or zero
+.align 32
+asin_special:
+{ .mfi
+ nop.m 0
+ // set p12 = 1 if x is a NaN
+ fclass.m p12, p0 = f8, 0xc3
+ nop.i 0
+}
+{ .mlx
+ nop.m 0
+ // smallest positive DP normalized number
+ movl rDenoBound = 0x0010000000000000
+}
+;;
+{ .mfi
+ nop.m 0
+ // set p13 = 1 if x = 0.0
+ fclass.m p13, p0 = f8, 0x07
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNormX = f8
+ nop.i 0
+}
+;;
+{ .mfb
+ // load smallest normal to FP reg
+ setf.d fDenoBound = rDenoBound
+ // answer if x is a NaN
+(p12) fma.d.s0 f8 = f8,f1,f0
+ // exit here if x is a NaN
+(p12) br.ret.spnt b0
+}
+;;
+{ .mfb
+ nop.m 0
+ nop.f 0
+ // exit here if x = 0.0
+(p13) br.ret.spnt b0
+}
+;;
+// if we still here then x is denormal or unnormal
+{ .mfi
+ nop.m 0
+ // absolute value of normalized x
+ fmerge.s fNormX = f1, fNormX
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // set p14 = 1 if normalized x is greater than or
+ // equal to the smallest denormalized value
+ // So, if p14 is set to 1 it means that we deal with
+ // unnormal rather than with "true" denormal
+ fcmp.ge.s1 p14, p0 = fNormX, fDenoBound
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+(p14) fcmp.eq.s0 p6, p0 = f8, f0 // Set D flag if x unnormal
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ // normalize unnormal input
+(p14) fnorm.s1 f8 = f8
+ // return to the main path
+(p14) br.cond.sptk asin_unnormal_back
+}
+;;
+// if we still here it means that input is "true" denormal
+{ .mfb
+ nop.m 0
+ // final result if x is denormal
+ fma.d.s0 f8 = f8, fXSqr, f8
+ // exit here if x is denormal
+ br.ret.sptk b0
+}
+;;
+
+// here if |x| > 1.0
+// error handler should be called
+.align 32
+asin_abs_gt_1:
+{ .mfi
+ alloc r32 = ar.pfs, 0, 3, 4, 0 // get some registers
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 61 // error code
+ frcpa.s0 FR_RESULT, p0 = f0,f0
+ // call error handler routine
+ br.cond.sptk __libm_error_region
+}
+;;
+GLOBAL_LIBM_END(asin)
+
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_asinf.S b/libc/sysdeps/ia64/fpu/e_asinf.S
new file mode 100644
index 000000000..af24165d8
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_asinf.S
@@ -0,0 +1,675 @@
+.file "asinf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 06/28/00 Improved speed
+// 06/31/00 Changed register allocation because of some duplicate macros
+// moved nan exit bundle up to gain a cycle.
+// 08/08/00 Improved speed by avoiding SIR flush.
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 08/17/00 Changed predicate register macro-usage to direct predicate
+// names due to an assembler bug.
+// 10/17/00 Improved speed of x=0 and x=1 paths, set D flag if x denormal.
+// 03/13/01 Corrected sign of imm1 value in dep instruction.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+
+
+// Description
+//=========================================
+// The asinf function computes the arc sine of x in the range [-pi,+pi].
+// A doman error occurs for arguments not in the range [-1,+1].
+// asinf(+-0) returns +-0
+// asinf(x) returns a Nan and raises the invalid exception for |x| >1
+
+// The acosf function returns the arc cosine in the range [0, +pi] radians.
+// A doman error occurs for arguments not in the range [-1,+1].
+// acosf(1) returns +0
+// acosf(x) returns a Nan and raises the invalid exception for |x| >1
+
+
+// |x| <= sqrt(2)/2. get Ax and Bx
+
+// poly_p1 = x p1
+// poly_p3 = x2 p4 + p3
+// poly_p1 = x2 (poly_p1) + x = x2(x p1) + x
+// poly_p2 = x2( poly_p3) + p2 = x2(x2 p4 + p3) + p2
+
+// poly_Ax = x5(x2( poly_p3) + p2) + x2(x p1) + x
+// = x5(x2(x2 p4 + p3) + p2) + x2(x p1) + x
+
+// poly_p7 = x2 p8 + p7
+// poly_p5 = x2 p6 + p5
+
+// poly_p7 = x4 p9 + (poly_p7)
+// poly_p7 = x4 p9 + (x2 p8 + p7)
+// poly_Bx = x4 (x4 p9 + (x2 p8 + p7)) + x2 p6 + p5
+
+// answer1 = x11(x4 (x4 p9 + (x2 p8 + p7)) + x2 p6 + p5) + x5(x2(x2 p4 + p3) + p2) + x2(x p1) + x
+// = x19 p9 + x17 p8 + x15 p7 x13 p6 + x11 p5 + x9 p4 + x7 p3 + x5 p2 + x3 p1 + x
+
+
+
+// |x| > sqrt(2)/2
+
+// Get z = sqrt(1-x2)
+
+// Get polynomial in t = 1-x2
+
+// t2 = t t
+// t4 = t2 t2
+
+// poly_p4 = t p5 + p4
+// poly_p1 = t p1 + 1
+
+// poly_p6 = t p7 + p6
+// poly_p2 = t p3 + p2
+
+// poly_p8 = t p9 + p8
+
+// poly_p4 = t2 poly_p6 + poly_p4
+// = t2 (t p7 + p6) + (t p5 + p4)
+
+// poly_p2 = t2 poly_p2 + poly_p1
+// = t2 (t p3 + p2) + (t p1 + 1)
+
+// poly_p4 = t4 poly_p8 + poly_p4
+// = t4 (t p9 + p8) + (t2 (t p7 + p6) + (t p5 + p4))
+
+// P(t) = poly_p2 + t4 poly_p8
+// = t2 (t p3 + p2) + (t p1 + 1) + t4 (t4 (t p9 + p8) + (t2 (t p7 + p6) + (t p5 + p4)))
+// = t3 p3 + t2 p2 + t p1 + 1 + t9 p9 + t8 p8 + t7 p7 + t6 p6 + t5 p5 + t4 p4
+
+
+// answer2 = - sign(x) z P(t) + (sign(x) pi/2)
+//
+
+
+// Assembly macros
+//=========================================
+
+// predicate registers
+//asinf_pred_LEsqrt2by2 = p7
+//asinf_pred_GTsqrt2by2 = p8
+
+// integer registers
+ASINF_Addr1 = r33
+ASINF_Addr2 = r34
+ASINF_GR_1by2 = r35
+
+ASINF_GR_3by2 = r36
+ASINF_GR_5by2 = r37
+
+GR_SAVE_B0 = r38
+GR_SAVE_PFS = r39
+GR_SAVE_GP = r40
+
+GR_Parameter_X = r41
+GR_Parameter_Y = r42
+GR_Parameter_RESULT = r43
+GR_Parameter_TAG = r44
+
+// floating point registers
+
+asinf_y = f32
+asinf_abs_x = f33
+asinf_x2 = f34
+asinf_sgn_x = f35
+
+asinf_1by2 = f36
+asinf_3by2 = f37
+asinf_5by2 = f38
+asinf_coeff_P3 = f39
+asinf_coeff_P8 = f40
+
+asinf_coeff_P1 = f41
+asinf_coeff_P4 = f42
+asinf_coeff_P5 = f43
+asinf_coeff_P2 = f44
+asinf_coeff_P7 = f45
+
+asinf_coeff_P6 = f46
+asinf_coeff_P9 = f47
+asinf_x2 = f48
+asinf_x3 = f49
+asinf_x4 = f50
+
+asinf_x8 = f51
+asinf_x5 = f52
+asinf_const_piby2 = f53
+asinf_const_sqrt2by2 = f54
+asinf_x11 = f55
+
+asinf_poly_p1 = f56
+asinf_poly_p3 = f57
+asinf_sinf1 = f58
+asinf_poly_p2 = f59
+asinf_poly_Ax = f60
+
+asinf_poly_p7 = f61
+asinf_poly_p5 = f62
+asinf_sgnx_t4 = f63
+asinf_poly_Bx = f64
+asinf_t = f65
+
+asinf_yby2 = f66
+asinf_B = f67
+asinf_B2 = f68
+asinf_Az = f69
+asinf_dz = f70
+
+asinf_Sz = f71
+asinf_d2z = f72
+asinf_Fz = f73
+asinf_z = f74
+asinf_sgnx_z = f75
+
+asinf_t2 = f76
+asinf_2poly_p4 = f77
+asinf_2poly_p6 = f78
+asinf_2poly_p1 = f79
+asinf_2poly_p2 = f80
+
+asinf_2poly_p8 = f81
+asinf_t4 = f82
+asinf_Pt = f83
+asinf_sgnx_2poly_p2 = f84
+asinf_sgn_x_piby2 = f85
+
+asinf_poly_p7a = f86
+asinf_2poly_p4a = f87
+asinf_2poly_p4b = f88
+asinf_2poly_p2a = f89
+asinf_poly_p1a = f90
+
+
+
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(asinf_coeff_1_table)
+data8 0x3FC5555607DCF816 // P1
+data8 0x3F9CF81AD9BAB2C6 // P4
+data8 0x3FC59E0975074DF3 // P7
+data8 0xBFA6F4CC2780AA1D // P6
+data8 0x3FC2DD45292E93CB // P9
+data8 0x3fe6a09e667f3bcd // sqrt(2)/2
+LOCAL_OBJECT_END(asinf_coeff_1_table)
+
+LOCAL_OBJECT_START(asinf_coeff_2_table)
+data8 0x3FA6F108E31EFBA6 // P3
+data8 0xBFCA31BF175D82A0 // P8
+data8 0x3FA30C0337F6418B // P5
+data8 0x3FB332C9266CB1F9 // P2
+data8 0x3ff921fb54442d18 // pi_by_2
+LOCAL_OBJECT_END(asinf_coeff_2_table)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(asinf)
+
+// Load the addresses of the two tables.
+// Then, load the coefficients and other constants.
+
+{ .mfi
+ alloc r32 = ar.pfs,1,8,4,0
+ fnma.s1 asinf_t = f8,f8,f1
+ dep.z ASINF_GR_1by2 = 0x3f,24,8 // 0x3f000000
+}
+{ .mfi
+ addl ASINF_Addr1 = @ltoff(asinf_coeff_1_table),gp
+ fma.s1 asinf_x2 = f8,f8,f0
+ addl ASINF_Addr2 = @ltoff(asinf_coeff_2_table),gp ;;
+}
+
+
+{ .mfi
+ ld8 ASINF_Addr1 = [ASINF_Addr1]
+ fmerge.s asinf_abs_x = f1,f8
+ dep ASINF_GR_3by2 = -1,r0,22,8 // 0x3fc00000
+}
+{ .mlx
+ nop.m 999
+ movl ASINF_GR_5by2 = 0x40200000;;
+}
+
+
+
+{ .mfi
+ setf.s asinf_1by2 = ASINF_GR_1by2
+ fmerge.s asinf_sgn_x = f8,f1
+ nop.i 999
+}
+{ .mfi
+ ld8 ASINF_Addr2 = [ASINF_Addr2]
+ nop.f 0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ setf.s asinf_5by2 = ASINF_GR_5by2
+ fcmp.lt.s1 p11,p12 = f8,f0
+ nop.i 999;;
+}
+
+{ .mmf
+ ldfpd asinf_coeff_P1,asinf_coeff_P4 = [ASINF_Addr1],16
+ setf.s asinf_3by2 = ASINF_GR_3by2
+ fclass.m.unc p8,p0 = f8, 0xc3 ;; //@qnan | @snan
+}
+
+
+{ .mfi
+ ldfpd asinf_coeff_P7,asinf_coeff_P6 = [ASINF_Addr1],16
+ fma.s1 asinf_t2 = asinf_t,asinf_t,f0
+ nop.i 999
+}
+{ .mfi
+ ldfpd asinf_coeff_P3,asinf_coeff_P8 = [ASINF_Addr2],16
+ fma.s1 asinf_x4 = asinf_x2,asinf_x2,f0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ ldfpd asinf_coeff_P9,asinf_const_sqrt2by2 = [ASINF_Addr1]
+ fclass.m.unc p10,p0 = f8, 0x07 //@zero
+ nop.i 999
+}
+{ .mfi
+ ldfpd asinf_coeff_P5,asinf_coeff_P2 = [ASINF_Addr2],16
+ fma.s1 asinf_x3 = f8,asinf_x2,f0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ ldfd asinf_const_piby2 = [ASINF_Addr2]
+ frsqrta.s1 asinf_B,p0 = asinf_t
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p8) fma.s.s0 f8 = f8,f1,f0
+(p8) br.ret.spnt b0 ;; // Exit if x=nan
+}
+
+
+{ .mfb
+ nop.m 999
+ fcmp.eq.s1 p6,p0 = asinf_abs_x,f1
+(p10) br.ret.spnt b0 ;; // Exit if x=0
+}
+
+{ .mfi
+ nop.m 999
+ fcmp.gt.s1 p9,p0 = asinf_abs_x,f1
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_x8 = asinf_x4,asinf_x4,f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fma.s1 asinf_t4 = asinf_t2,asinf_t2,f0
+(p6) br.cond.spnt ASINF_ABS_ONE ;; // Branch if |x|=1
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_x5 = asinf_x2,asinf_x3,f0
+ nop.i 999
+}
+{ .mfb
+(p9) mov GR_Parameter_TAG = 62
+ fma.s1 asinf_yby2 = asinf_t,asinf_1by2,f0
+(p9) br.cond.spnt __libm_error_region ;; // Branch if |x|>1
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_Az = asinf_t,asinf_B,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_B2 = asinf_B,asinf_B,f0
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_poly_p1 = f8,asinf_coeff_P1,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_2poly_p1 = asinf_coeff_P1,asinf_t,f1
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_poly_p3 = asinf_coeff_P4,asinf_x2,asinf_coeff_P3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_2poly_p6 = asinf_coeff_P7,asinf_t,asinf_coeff_P6
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_poly_p7 = asinf_x2,asinf_coeff_P8,asinf_coeff_P7
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_2poly_p2 = asinf_coeff_P3,asinf_t,asinf_coeff_P2
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_poly_p5 = asinf_x2,asinf_coeff_P6,asinf_coeff_P5
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_2poly_p4 = asinf_coeff_P5,asinf_t,asinf_coeff_P4
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.d.s1 asinf_x11 = asinf_x8,asinf_x3,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnma.s1 asinf_dz = asinf_B2,asinf_yby2,asinf_1by2
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_poly_p1a = asinf_x2,asinf_poly_p1,f8
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_2poly_p8 = asinf_coeff_P9,asinf_t,asinf_coeff_P8
+ nop.i 999;;
+}
+
+
+// Get the absolute value of x and determine the region in which x lies
+
+{ .mfi
+ nop.m 999
+ fcmp.le.s1 p7,p8 = asinf_abs_x,asinf_const_sqrt2by2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_poly_p2 = asinf_x2,asinf_poly_p3,asinf_coeff_P2
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_poly_p7a = asinf_x4,asinf_coeff_P9,asinf_poly_p7
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 asinf_2poly_p2a = asinf_2poly_p2,asinf_t2,asinf_2poly_p1
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 asinf_sgnx_t4 = asinf_sgn_x,asinf_t4,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 asinf_2poly_p4a = asinf_2poly_p6,asinf_t2,asinf_2poly_p4
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 asinf_Sz = asinf_5by2,asinf_dz,asinf_3by2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 asinf_d2z = asinf_dz,asinf_dz,f0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 asinf_sgn_x_piby2 = asinf_sgn_x,asinf_const_piby2,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fma.d.s1 asinf_poly_Ax = asinf_x5,asinf_poly_p2,asinf_poly_p1a
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+(p7) fma.d.s1 asinf_poly_Bx = asinf_x4,asinf_poly_p7a,asinf_poly_p5
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 asinf_sgnx_2poly_p2 = asinf_sgn_x,asinf_2poly_p2a,f0
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p6,p0 = f8,f0 // Only purpose is to set D if x denormal
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 asinf_2poly_p4b = asinf_2poly_p8,asinf_t4,asinf_2poly_p4a
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 asinf_Fz = asinf_d2z,asinf_Sz,asinf_dz
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.d.s1 asinf_Pt = asinf_2poly_p4b,asinf_sgnx_t4,asinf_sgnx_2poly_p2
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+(p8) fma.d.s1 asinf_z = asinf_Az,asinf_Fz,asinf_Az
+ nop.i 999;;
+}
+
+.pred.rel "mutex",p8,p7 //asinf_pred_GTsqrt2by2,asinf_pred_LEsqrt2by2
+{ .mfi
+ nop.m 999
+(p8) fnma.s.s0 f8 = asinf_z,asinf_Pt,asinf_sgn_x_piby2
+ nop.i 999
+}
+
+{ .mfb
+ nop.m 999
+(p7) fma.s.s0 f8 = asinf_x11,asinf_poly_Bx,asinf_poly_Ax
+ br.ret.sptk b0 ;;
+}
+
+ASINF_ABS_ONE:
+// Here for short exit if |x|=1
+{ .mfb
+ nop.m 999
+ fma.s.s0 f8 = asinf_sgn_x,asinf_const_piby2,f0
+ br.ret.sptk b0
+}
+;;
+
+GLOBAL_LIBM_END(asinf)
+
+// Stack operations when calling error support.
+// (1) (2)
+// sp -> + psp -> +
+// | |
+// | | <- GR_Y
+// | |
+// | <-GR_Y Y2->|
+// | |
+// | | <- GR_X
+// | |
+// sp-64 -> + sp -> +
+// save ar.pfs save b0
+// save gp
+
+
+// Stack operations when calling error support.
+// (3) (call) (4)
+// psp -> + sp -> +
+// | |
+// R3 ->| <- GR_RESULT | -> f8
+// | |
+// Y2 ->| <- GR_Y |
+// | |
+// X1 ->| |
+// | |
+// sp -> + +
+// restore gp
+// restore ar.pfs
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 999
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = f1,16 // Store Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mfi
+ nop.m 0
+ frcpa.s0 f9,p0 = f0,f0
+ nop.i 0
+};;
+
+{ .mib
+ stfs [GR_Parameter_X] = f8 // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfs [GR_Parameter_Y] = f9 // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_asinl.S b/libc/sysdeps/ia64/fpu/e_asinl.S
new file mode 100644
index 000000000..ad65a731f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_asinl.S
@@ -0,0 +1,2528 @@
+.file "asinl.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/28/01 New version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// long double asinl(long double)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// For |s| in [2^{-4}, sqrt(2)/2]:
+// Let t= 2^k*1.b1 b2..b6 1, where s= 2^k*1.b1 b2.. b52
+// asin(s)= asin(t)+asin(r), where r= s*sqrt(1-t^2)-t*sqrt(1-s^2), i.e.
+// r= (s-t)*sqrt(1-t^2)-t*sqrt(1-t^2)*(sqrt((1-s^2)/(1-t^2))-1)
+// asin(r)-r evaluated as 9-degree polynomial (c3*r^3+c5*r^5+c7*r^7+c9*r^9)
+// The 64-bit significands of sqrt(1-t^2), 1/(1-t^2) are read from the table,
+// along with the high and low parts of asin(t) (stored as two double precision
+// values)
+//
+// |s| in (sqrt(2)/2, sqrt(255/256)):
+// Let t= 2^k*1.b1 b2..b6 1, where (1-s^2)*frsqrta(1-s^2)= 2^k*1.b1 b2..b6..
+// asin(|s|)= pi/2-asin(t)+asin(r), r= s*t-sqrt(1-s^2)*sqrt(1-t^2)
+// To minimize accumulated errors, r is computed as
+// r= (t*s)_s-t^2*y*z+z*y*(t^2-1+s^2)_s+z*y*(1-s^2)_s*x+z'*y*(1-s^2)*PS29+
+// +(t*s-(t*s)_s)+z*y*((t^2-1-(t^2-1+s^2)_s)+s^2)+z*y*(1-s^2-(1-s^2)_s)+
+// +ez*z'*y*(1-s^2)*(1-x),
+// where y= frsqrta(1-s^2), z= (sqrt(1-t^2))_s (rounded to 24 significant bits)
+// z'= sqrt(1-t^2), x= ((1-s^2)*y^2-1)/2
+//
+// |s|<2^{-4}: evaluate as 17-degree polynomial
+// (or simply return s, if|s|<2^{-64})
+//
+// |s| in [sqrt(255/256), 1): asin(|s|)= pi/2-asin(sqrt(1-s^2))
+// use 17-degree polynomial for asin(sqrt(1-s^2)),
+// 9-degree polynomial to evaluate sqrt(1-s^2)
+// High order term is (pi/2)_high-(y*(1-s^2))_high
+//
+
+
+
+// Registers used
+//==============================================================
+// f6-f15, f32-f36
+// r2-r3, r23-r23
+// p6, p7, p8, p12
+//
+
+
+ GR_SAVE_B0= r33
+ GR_SAVE_PFS= r34
+ GR_SAVE_GP= r35 // This reg. can safely be used
+ GR_SAVE_SP= r36
+
+ GR_Parameter_X= r37
+ GR_Parameter_Y= r38
+ GR_Parameter_RESULT= r39
+ GR_Parameter_TAG= r40
+
+ FR_X= f10
+ FR_Y= f1
+ FR_RESULT= f8
+
+
+
+RODATA
+
+.align 16
+
+
+
+LOCAL_OBJECT_START(T_table)
+
+// stores 64-bit significand of 1/(1-t^2), 64-bit significand of sqrt(1-t^2),
+// asin(t)_high (double precision), asin(t)_low (double precision)
+
+data8 0x80828692b71c4391, 0xff7ddcec2d87e879
+data8 0x3fb022bc0ae531a0, 0x3c9f599c7bb42af6
+data8 0x80869f0163d0b082, 0xff79cad2247914d3
+data8 0x3fb062dd26afc320, 0x3ca4eff21bd49c5c
+data8 0x808ac7d5a8690705, 0xff75a89ed6b626b9
+data8 0x3fb0a2ff4a1821e0, 0x3cb7e33b58f164cc
+data8 0x808f0112ad8ad2e0, 0xff7176517c2cc0cb
+data8 0x3fb0e32279319d80, 0x3caee31546582c43
+data8 0x80934abba8a1da0a, 0xff6d33e949b1ed31
+data8 0x3fb12346b8101da0, 0x3cb8bfe463d087cd
+data8 0x8097a4d3dbe63d8f, 0xff68e16571015c63
+data8 0x3fb1636c0ac824e0, 0x3c8870a7c5a3556f
+data8 0x809c0f5e9662b3dd, 0xff647ec520bca0f0
+data8 0x3fb1a392756ed280, 0x3c964f1a927461ae
+data8 0x80a08a5f33fadc66, 0xff600c07846a6830
+data8 0x3fb1e3b9fc19e580, 0x3c69eb3576d56332
+data8 0x80a515d91d71acd4, 0xff5b892bc475affa
+data8 0x3fb223e2a2dfbe80, 0x3c6a4e19fd972fb6
+data8 0x80a9b1cfc86ff7cd, 0xff56f631062cf93d
+data8 0x3fb2640c6dd76260, 0x3c62041160e0849e
+data8 0x80ae5e46b78b0d68, 0xff5253166bc17794
+data8 0x3fb2a43761187c80, 0x3cac61651af678c0
+data8 0x80b31b417a4b756b, 0xff4d9fdb14463dc8
+data8 0x3fb2e46380bb6160, 0x3cb06ef23eeba7a1
+data8 0x80b7e8c3ad33c369, 0xff48dc7e1baf6738
+data8 0x3fb32490d0d910c0, 0x3caa05f480b300d5
+data8 0x80bcc6d0f9c784d6, 0xff4408fe9ad13e37
+data8 0x3fb364bf558b3820, 0x3cb01e7e403aaab9
+data8 0x80c1b56d1692492d, 0xff3f255ba75f5f4e
+data8 0x3fb3a4ef12ec3540, 0x3cb4fe8fcdf5f5f1
+data8 0x80c6b49bc72ec446, 0xff3a319453ebd961
+data8 0x3fb3e5200d171880, 0x3caf2dc089b2b7e2
+data8 0x80cbc460dc4e0ae8, 0xff352da7afe64ac6
+data8 0x3fb425524827a720, 0x3cb75a855e7c6053
+data8 0x80d0e4c033bee9c4, 0xff301994c79afb32
+data8 0x3fb46585c83a5e00, 0x3cb3264981c019ab
+data8 0x80d615bdb87556db, 0xff2af55aa431f291
+data8 0x3fb4a5ba916c73c0, 0x3c994251d94427b5
+data8 0x80db575d6291fd8a, 0xff25c0f84bae0cb9
+data8 0x3fb4e5f0a7dbdb20, 0x3cbee2fcc4c786cb
+data8 0x80e0a9a33769e535, 0xff207c6cc0ec09fd
+data8 0x3fb526280fa74620, 0x3c940656e5549b91
+data8 0x80e60c93498e32cd, 0xff1b27b703a19c98
+data8 0x3fb56660ccee2740, 0x3ca7082374d7b2cd
+data8 0x80eb8031b8d4052d, 0xff15c2d6105c72f8
+data8 0x3fb5a69ae3d0b520, 0x3c7c4d46e09ac68a
+data8 0x80f10482b25c6c8a, 0xff104dc8e0813ed4
+data8 0x3fb5e6d6586fec20, 0x3c9aa84ffd9b4958
+data8 0x80f6998a709c7cfb, 0xff0ac88e6a4ab926
+data8 0x3fb627132eed9140, 0x3cbced2cbbbe7d16
+data8 0x80fc3f4d3b657c44, 0xff053325a0c8a2ec
+data8 0x3fb667516b6c34c0, 0x3c6489c5fc68595a
+data8 0x8101f5cf67ed2af8, 0xfeff8d8d73dec2bb
+data8 0x3fb6a791120f33a0, 0x3cbe12acf159dfad
+data8 0x8107bd1558d6291f, 0xfef9d7c4d043df29
+data8 0x3fb6e7d226fabba0, 0x3ca386d099cd0dc7
+data8 0x810d95237e38766a, 0xfef411ca9f80b5f7
+data8 0x3fb72814ae53cc20, 0x3cb9f35731e71dd6
+data8 0x81137dfe55aa0e29, 0xfeee3b9dc7eef009
+data8 0x3fb76858ac403a00, 0x3c74df3dd959141a
+data8 0x811977aa6a479f0f, 0xfee8553d2cb8122c
+data8 0x3fb7a89e24e6b0e0, 0x3ca6034406ee42bc
+data8 0x811f822c54bd5ef8, 0xfee25ea7add46a91
+data8 0x3fb7e8e51c6eb6a0, 0x3cb82f8f78e68ed7
+data8 0x81259d88bb4ffac1, 0xfedc57dc2809fb1d
+data8 0x3fb8292d9700ad60, 0x3cbebb73c0e653f9
+data8 0x812bc9c451e5a257, 0xfed640d974eb6068
+data8 0x3fb8697798c5d620, 0x3ca2feee76a9701b
+data8 0x813206e3da0f3124, 0xfed0199e6ad6b585
+data8 0x3fb8a9c325e852e0, 0x3cb9e88f2f4d0efe
+data8 0x813854ec231172f9, 0xfec9e229dcf4747d
+data8 0x3fb8ea1042932a00, 0x3ca5ff40d81f66fd
+data8 0x813eb3e209ee858f, 0xfec39a7a9b36538b
+data8 0x3fb92a5ef2f247c0, 0x3cb5e3bece4d6b07
+data8 0x814523ca796f56ce, 0xfebd428f72561efe
+data8 0x3fb96aaf3b3281a0, 0x3cb7b9e499436d7c
+data8 0x814ba4aa6a2d3ff9, 0xfeb6da672bd48fe4
+data8 0x3fb9ab011f819860, 0x3cb9168143cc1a7f
+data8 0x81523686e29bbdd7, 0xfeb062008df81f50
+data8 0x3fb9eb54a40e3ac0, 0x3cb6e544197eb1e1
+data8 0x8158d964f7124614, 0xfea9d95a5bcbd65a
+data8 0x3fba2ba9cd080800, 0x3ca9a717be8f7446
+data8 0x815f8d49c9d639e4, 0xfea34073551e1ac8
+data8 0x3fba6c009e9f9260, 0x3c741e989a60938a
+data8 0x8166523a8b24f626, 0xfe9c974a367f785c
+data8 0x3fbaac591d0661a0, 0x3cb2c1290107e57d
+data8 0x816d283c793e0114, 0xfe95ddddb94166cb
+data8 0x3fbaecb34c6ef600, 0x3c9c7d5fbaec405d
+data8 0x81740f54e06d55bd, 0xfe8f142c93750c50
+data8 0x3fbb2d0f310cca00, 0x3cbc09479a9cbcfb
+data8 0x817b07891b15cd5e, 0xfe883a3577e9fceb
+data8 0x3fbb6d6ccf1455e0, 0x3cb9450bff4ee307
+data8 0x818210de91bba6c8, 0xfe814ff7162cf62f
+data8 0x3fbbadcc2abb1180, 0x3c9227fda12a8d24
+data8 0x81892b5abb0f2bf9, 0xfe7a55701a8697b1
+data8 0x3fbbee2d48377700, 0x3cb6fad72acfe356
+data8 0x819057031bf7760e, 0xfe734a9f2dfa1810
+data8 0x3fbc2e902bc10600, 0x3cb4465b588d16ad
+data8 0x819793dd479d4fbe, 0xfe6c2f82f643f68b
+data8 0x3fbc6ef4d9904580, 0x3c8b9ac54823960d
+data8 0x819ee1eedf76367a, 0xfe65041a15d8a92c
+data8 0x3fbcaf5b55dec6a0, 0x3ca2b8d28a954db2
+data8 0x81a6413d934f7a66, 0xfe5dc8632be3477f
+data8 0x3fbcefc3a4e727a0, 0x3c9380da83713ab4
+data8 0x81adb1cf21597d4b, 0xfe567c5cd44431d5
+data8 0x3fbd302dcae51600, 0x3ca995b83421756a
+data8 0x81b533a9563310b8, 0xfe4f2005a78fb50f
+data8 0x3fbd7099cc155180, 0x3caefa2f7a817d5f
+data8 0x81bcc6d20cf4f373, 0xfe47b35c3b0caaeb
+data8 0x3fbdb107acb5ae80, 0x3cb455fc372dd026
+data8 0x81c46b4f2f3d6e68, 0xfe40365f20b316d6
+data8 0x3fbdf177710518c0, 0x3cbee3dcc5b01434
+data8 0x81cc2126b53c1144, 0xfe38a90ce72abf36
+data8 0x3fbe31e91d439620, 0x3cb3e131c950aebd
+data8 0x81d3e85ea5bd8ee2, 0xfe310b6419c9c33a
+data8 0x3fbe725cb5b24900, 0x3c01d3fac6029027
+data8 0x81dbc0fd1637b9c1, 0xfe295d6340932d15
+data8 0x3fbeb2d23e937300, 0x3c6304cc44aeedd1
+data8 0x81e3ab082ad5a0a4, 0xfe219f08e03580b3
+data8 0x3fbef349bc2a77e0, 0x3cac1d2d6abe9c72
+data8 0x81eba6861683cb97, 0xfe19d0537a0946e2
+data8 0x3fbf33c332bbe020, 0x3ca0909dba4e96ca
+data8 0x81f3b37d1afc9979, 0xfe11f1418c0f94e2
+data8 0x3fbf743ea68d5b60, 0x3c937fc12a2a779a
+data8 0x81fbd1f388d4be45, 0xfe0a01d190f09063
+data8 0x3fbfb4bc1be5c340, 0x3cbf51a504b55813
+data8 0x820401efbf87e248, 0xfe020201fff9efea
+data8 0x3fbff53b970d1e80, 0x3ca625444b260078
+data8 0x82106ad2ffdca049, 0xfdf5e3940a49135e
+data8 0x3fc02aff52065460, 0x3c9125d113e22a57
+data8 0x8221343d6ea1d3e2, 0xfde581a45429b0a0
+data8 0x3fc06b84f8e03220, 0x3caccf362295894b
+data8 0x82324434adbf99c2, 0xfdd4de1a001fb775
+data8 0x3fc0ac0ed1fe7240, 0x3cc22f676096b0af
+data8 0x82439aee8d0c7747, 0xfdc3f8e8269d1f03
+data8 0x3fc0ec9cee9e4820, 0x3cca147e2886a628
+data8 0x825538a1d0fcb2f0, 0xfdb2d201a9b1ba66
+data8 0x3fc12d2f6006f0a0, 0x3cc72b36633bc2d4
+data8 0x82671d86345c5cee, 0xfda1695934d723e7
+data8 0x3fc16dc63789de60, 0x3cb11f9c47c7b83f
+data8 0x827949d46a121770, 0xfd8fbee13cbbb823
+data8 0x3fc1ae618682e620, 0x3cce1b59020cef8e
+data8 0x828bbdc61eeab9ba, 0xfd7dd28bff0c9f34
+data8 0x3fc1ef015e586c40, 0x3cafec043e0225ee
+data8 0x829e7995fb6de9e1, 0xfd6ba44b823ee1ca
+data8 0x3fc22fa5d07b90c0, 0x3cba905409caf8e3
+data8 0x82b17d7fa5bbc982, 0xfd5934119557883a
+data8 0x3fc2704eee685da0, 0x3cb5ef21838a823e
+data8 0x82c4c9bfc373d276, 0xfd4681cfcfb2c161
+data8 0x3fc2b0fcc9a5f3e0, 0x3ccc7952c5e0e312
+data8 0x82d85e93fba50136, 0xfd338d7790ca0f41
+data8 0x3fc2f1af73c6ba00, 0x3cbecf5f977d1ca9
+data8 0x82ec3c3af8c76b32, 0xfd2056f9fff97727
+data8 0x3fc33266fe6889a0, 0x3c9d329c022ebdb5
+data8 0x830062f46abf6022, 0xfd0cde480c43b327
+data8 0x3fc373237b34de60, 0x3cc95806d4928adb
+data8 0x8314d30108ea35f0, 0xfcf923526c1562b2
+data8 0x3fc3b3e4fbe10520, 0x3cbc299fe7223d54
+data8 0x83298ca29434df97, 0xfce526099d0737ed
+data8 0x3fc3f4ab922e4a60, 0x3cb59d8bb8fdbccc
+data8 0x833e901bd93c7009, 0xfcd0e65de39f1f7c
+data8 0x3fc435774fea2a60, 0x3c9ec18b43340914
+data8 0x8353ddb0b278aad8, 0xfcbc643f4b106055
+data8 0x3fc4764846ee80a0, 0x3cb90402efd87ed6
+data8 0x836975a60a70c52e, 0xfca79f9da4fab13a
+data8 0x3fc4b71e8921b860, 0xbc58f23449ed6365
+data8 0x837f5841ddfa7a46, 0xfc92986889284148
+data8 0x3fc4f7fa2876fca0, 0xbc6294812bf43acd
+data8 0x839585cb3e839773, 0xfc7d4e8f554ab12f
+data8 0x3fc538db36ee6960, 0x3cb910b773d4c578
+data8 0x83abfe8a5466246f, 0xfc67c2012cb6fa68
+data8 0x3fc579c1c6953cc0, 0x3cc5ede909fc47fc
+data8 0x83c2c2c861474d91, 0xfc51f2acf82041d5
+data8 0x3fc5baade9860880, 0x3cac63cdfc3588e5
+data8 0x83d9d2cfc2813637, 0xfc3be08165519325
+data8 0x3fc5fb9fb1e8e3a0, 0x3cbf7c8466578c29
+data8 0x83f12eebf397daac, 0xfc258b6ce6e6822f
+data8 0x3fc63c9731f39d40, 0x3cb6d2a7ffca3e9e
+data8 0x8408d76990b9296e, 0xfc0ef35db402af94
+data8 0x3fc67d947be9eec0, 0x3cb1980da09e6566
+data8 0x8420cc9659487cd7, 0xfbf81841c8082dc4
+data8 0x3fc6be97a21daf00, 0x3cc2ac8330e59aa5
+data8 0x84390ec132759ecb, 0xfbe0fa06e24cc390
+data8 0x3fc6ffa0b6ef05e0, 0x3ccc1a030fee56c4
+data8 0x84519e3a29df811a, 0xfbc9989a85ce0954
+data8 0x3fc740afcccca000, 0x3cc19692a5301ca6
+data8 0x846a7b527842d61b, 0xfbb1f3e9f8e45dc4
+data8 0x3fc781c4f633e2c0, 0x3cc0e98f3868a508
+data8 0x8483a65c8434b5f0, 0xfb9a0be244f4af45
+data8 0x3fc7c2e045b12140, 0x3cb2a8d309754420
+data8 0x849d1fabe4e97dd7, 0xfb81e070362116d1
+data8 0x3fc80401cddfd120, 0x3ca7a44544aa4ce6
+data8 0x84b6e795650817ea, 0xfb6971805af8411e
+data8 0x3fc84529a16ac020, 0x3c9e3b709c7d6f94
+data8 0x84d0fe6f0589da92, 0xfb50beff0423a2f5
+data8 0x3fc88657d30c49e0, 0x3cc60d65a7f0a278
+data8 0x84eb649000a73014, 0xfb37c8d84414755c
+data8 0x3fc8c78c758e8e80, 0x3cc94b2ee984c2b7
+data8 0x85061a50ccd13781, 0xfb1e8ef7eeaf764b
+data8 0x3fc908c79bcba900, 0x3cc8540ae794a2fe
+data8 0x8521200b1fb8916e, 0xfb05114998f76a83
+data8 0x3fc94a0958ade6c0, 0x3ca127f49839fa9c
+data8 0x853c7619f1618bf6, 0xfaeb4fb898b65d19
+data8 0x3fc98b51bf2ffee0, 0x3c8c9ba7a803909a
+data8 0x85581cd97f45e274, 0xfad14a3004259931
+data8 0x3fc9cca0e25d4ac0, 0x3cba458e91d3bf54
+data8 0x857414a74f8446b4, 0xfab7009ab1945a54
+data8 0x3fca0df6d551fe80, 0x3cc78ea1d329d2b2
+data8 0x85905de2341dea46, 0xfa9c72e3370d2fbc
+data8 0x3fca4f53ab3b6200, 0x3ccf60dca86d57ef
+data8 0x85acf8ea4e423ff8, 0xfa81a0f3e9fa0ee9
+data8 0x3fca90b777580aa0, 0x3ca4c4e2ec8a867e
+data8 0x85c9e62111a92e7d, 0xfa668ab6dec711b1
+data8 0x3fcad2224cf814e0, 0x3c303de5980d071c
+data8 0x85e725e947fbee97, 0xfa4b3015e883dbfe
+data8 0x3fcb13943f7d5f80, 0x3cc29d4eefa5cb1e
+data8 0x8604b8a7144cd054, 0xfa2f90fa9883a543
+data8 0x3fcb550d625bc6a0, 0x3c9e01a746152daf
+data8 0x86229ebff69e2415, 0xfa13ad4e3dfbe1c1
+data8 0x3fcb968dc9195ea0, 0x3ccc091bd73ae518
+data8 0x8640d89acf78858c, 0xf9f784f9e5a1877b
+data8 0x3fcbd815874eb160, 0x3cb5f4b89875e187
+data8 0x865f669fe390c7f5, 0xf9db17e65944eacf
+data8 0x3fcc19a4b0a6f9c0, 0x3cc5c0bc2b0bbf14
+data8 0x867e4938df7dc45f, 0xf9be65fc1f6c2e6e
+data8 0x3fcc5b3b58e061e0, 0x3cc1ca70df8f57e7
+data8 0x869d80d0db7e4c0c, 0xf9a16f237aec427a
+data8 0x3fcc9cd993cc4040, 0x3cbae93acc85eccf
+data8 0x86bd0dd45f4f8265, 0xf98433446a806e70
+data8 0x3fccde7f754f5660, 0x3cb22f70e64568d0
+data8 0x86dcf0b16613e37a, 0xf966b246a8606170
+data8 0x3fcd202d11620fa0, 0x3c962030e5d4c849
+data8 0x86fd29d7624b3d5d, 0xf948ec11a9d4c45b
+data8 0x3fcd61e27c10c0a0, 0x3cc7083c91d59217
+data8 0x871db9b741dbe44a, 0xf92ae08c9eca4941
+data8 0x3fcda39fc97be7c0, 0x3cc9258579e57211
+data8 0x873ea0c3722d6af2, 0xf90c8f9e71633363
+data8 0x3fcde5650dd86d60, 0x3ca4755a9ea582a9
+data8 0x875fdf6fe45529e8, 0xf8edf92dc5875319
+data8 0x3fce27325d6fe520, 0x3cbc1e2b6c1954f9
+data8 0x878176321154e2bc, 0xf8cf1d20f87270b8
+data8 0x3fce6907cca0d060, 0x3cb6ca4804750830
+data8 0x87a36580fe6bccf5, 0xf8affb5e20412199
+data8 0x3fceaae56fdee040, 0x3cad6b310d6fd46c
+data8 0x87c5add5417a5cb9, 0xf89093cb0b7c0233
+data8 0x3fceeccb5bb33900, 0x3cc16e99cedadb20
+data8 0x87e84fa9057914ca, 0xf870e64d40a15036
+data8 0x3fcf2eb9a4bcb600, 0x3cc75ee47c8b09e9
+data8 0x880b4b780f02b709, 0xf850f2c9fdacdf78
+data8 0x3fcf70b05fb02e20, 0x3cad6350d379f41a
+data8 0x882ea1bfc0f228ac, 0xf830b926379e6465
+data8 0x3fcfb2afa158b8a0, 0x3cce0ccd9f829985
+data8 0x885252ff21146108, 0xf810394699fe0e8e
+data8 0x3fcff4b77e97f3e0, 0x3c9b30faa7a4c703
+data8 0x88765fb6dceebbb3, 0xf7ef730f865f6df0
+data8 0x3fd01b6406332540, 0x3cdc5772c9e0b9bd
+data8 0x88ad1f69be2cc730, 0xf7bdc59bc9cfbd97
+data8 0x3fd04cf8ad203480, 0x3caeef44fe21a74a
+data8 0x88f763f70ae2245e, 0xf77a91c868a9c54e
+data8 0x3fd08f23ce0162a0, 0x3cd6290ab3fe5889
+data8 0x89431fc7bc0c2910, 0xf73642973c91298e
+data8 0x3fd0d1610f0c1ec0, 0x3cc67401a01f08cf
+data8 0x8990573407c7738e, 0xf6f0d71d1d7a2dd6
+data8 0x3fd113b0c65d88c0, 0x3cc7aa4020fe546f
+data8 0x89df0eb108594653, 0xf6aa4e6a05cfdef2
+data8 0x3fd156134ada6fe0, 0x3cc87369da09600c
+data8 0x8a2f4ad16e0ed78a, 0xf662a78900c35249
+data8 0x3fd19888f43427a0, 0x3cc62b220f38e49c
+data8 0x8a811046373e0819, 0xf619e180181d97cc
+data8 0x3fd1db121aed7720, 0x3ca3ede7490b52f4
+data8 0x8ad463df6ea0fa2c, 0xf5cffb504190f9a2
+data8 0x3fd21daf185fa360, 0x3caafad98c1d6c1b
+data8 0x8b294a8cf0488daf, 0xf584f3f54b8604e6
+data8 0x3fd2606046bf95a0, 0x3cdb2d704eeb08fa
+data8 0x8b7fc95f35647757, 0xf538ca65c960b582
+data8 0x3fd2a32601231ec0, 0x3cc661619fa2f126
+data8 0x8bd7e588272276f8, 0xf4eb7d92ff39fccb
+data8 0x3fd2e600a3865760, 0x3c8a2a36a99aca4a
+data8 0x8c31a45bf8e9255e, 0xf49d0c68cd09b689
+data8 0x3fd328f08ad12000, 0x3cb9efaf1d7ab552
+data8 0x8c8d0b520a35eb18, 0xf44d75cd993cfad2
+data8 0x3fd36bf614dcc040, 0x3ccacbb590bef70d
+data8 0x8cea2005d068f23d, 0xf3fcb8a23ab4942b
+data8 0x3fd3af11a079a6c0, 0x3cd9775872cf037d
+data8 0x8d48e837c8cd5027, 0xf3aad3c1e2273908
+data8 0x3fd3f2438d754b40, 0x3ca03304f667109a
+data8 0x8da969ce732f3ac7, 0xf357c60202e2fd7e
+data8 0x3fd4358c3ca032e0, 0x3caecf2504ff1a9d
+data8 0x8e0baad75555e361, 0xf3038e323ae9463a
+data8 0x3fd478ec0fd419c0, 0x3cc64bdc3d703971
+data8 0x8e6fb18807ba877e, 0xf2ae2b1c3a6057f7
+data8 0x3fd4bc6369fa40e0, 0x3cbb7122ec245cf2
+data8 0x8ed5843f4bda74d5, 0xf2579b83aa556f0c
+data8 0x3fd4fff2af11e2c0, 0x3c9cfa2dc792d394
+data8 0x8f3d29862c861fef, 0xf1ffde2612ca1909
+data8 0x3fd5439a4436d000, 0x3cc38d46d310526b
+data8 0x8fa6a81128940b2d, 0xf1a6f1bac0075669
+data8 0x3fd5875a8fa83520, 0x3cd8bf59b8153f8a
+data8 0x901206c1686317a6, 0xf14cd4f2a730d480
+data8 0x3fd5cb33f8cf8ac0, 0x3c9502b5c4d0e431
+data8 0x907f4ca5fe9cf739, 0xf0f186784a125726
+data8 0x3fd60f26e847b120, 0x3cc8a1a5e0acaa33
+data8 0x90ee80fd34aeda5e, 0xf09504ef9a212f18
+data8 0x3fd65333c7e43aa0, 0x3cae5b029cb1f26e
+data8 0x915fab35e37421c6, 0xf0374ef5daab5c45
+data8 0x3fd6975b02b8e360, 0x3cd5aa1c280c45e6
+data8 0x91d2d2f0d894d73c, 0xefd86321822dbb51
+data8 0x3fd6db9d05213b20, 0x3cbecf2c093ccd8b
+data8 0x9248000249200009, 0xef7840021aca5a72
+data8 0x3fd71ffa3cc87fc0, 0x3cb8d273f08d00d9
+data8 0x92bf3a7351f081d2, 0xef16e42021d7cbd5
+data8 0x3fd7647318b1ad20, 0x3cbce099d79cdc46
+data8 0x93388a8386725713, 0xeeb44dfce6820283
+data8 0x3fd7a908093fc1e0, 0x3ccb033ec17a30d9
+data8 0x93b3f8aa8e653812, 0xee507c126774fa45
+data8 0x3fd7edb9803e3c20, 0x3cc10aedb48671eb
+data8 0x94318d99d341ade4, 0xedeb6cd32f891afb
+data8 0x3fd83287f0e9cf80, 0x3c994c0c1505cd2a
+data8 0x94b1523e3dedc630, 0xed851eaa3168f43c
+data8 0x3fd87773cff956e0, 0x3cda3b7bce6a6b16
+data8 0x95334fc20577563f, 0xed1d8ffaa2279669
+data8 0x3fd8bc7d93a70440, 0x3cd4922edc792ce2
+data8 0x95b78f8e8f92f274, 0xecb4bf1fd2be72da
+data8 0x3fd901a5b3b9cf40, 0x3cd3fea1b00f9d0d
+data8 0x963e1b4e63a87c3f, 0xec4aaa6d08694cc1
+data8 0x3fd946eca98f2700, 0x3cdba4032d968ff1
+data8 0x96c6fcef314074fc, 0xebdf502d53d65fea
+data8 0x3fd98c52f024e800, 0x3cbe7be1ab8c95c9
+data8 0x97523ea3eab028b2, 0xeb72aea36720793e
+data8 0x3fd9d1d904239860, 0x3cd72d08a6a22b70
+data8 0x97dfeae6f4ee4a9a, 0xeb04c4096a884e94
+data8 0x3fda177f63e8ef00, 0x3cd818c3c1ebfac7
+data8 0x98700c7c6d85d119, 0xea958e90cfe1efd7
+data8 0x3fda5d468f92a540, 0x3cdf45fbfaa080fe
+data8 0x9902ae7487a9caa1, 0xea250c6224aab21a
+data8 0x3fdaa32f090998e0, 0x3cd715a9353cede4
+data8 0x9997dc2e017a9550, 0xe9b33b9ce2bb7638
+data8 0x3fdae939540d3f00, 0x3cc545c014943439
+data8 0x9a2fa158b29b649b, 0xe9401a573f8aa706
+data8 0x3fdb2f65f63f6c60, 0x3cd4a63c2f2ca8e2
+data8 0x9aca09f835466186, 0xe8cba69df9f0bf35
+data8 0x3fdb75b5773075e0, 0x3cda310ce1b217ec
+data8 0x9b672266ab1e0136, 0xe855de74266193d4
+data8 0x3fdbbc28606babc0, 0x3cdc84b75cca6c44
+data8 0x9c06f7579f0b7bd5, 0xe7debfd2f98c060b
+data8 0x3fdc02bf3d843420, 0x3cd225d967ffb922
+data8 0x9ca995db058cabdc, 0xe76648a991511c6e
+data8 0x3fdc497a9c224780, 0x3cde08101c5b825b
+data8 0x9d4f0b605ce71e88, 0xe6ec76dcbc02d9a7
+data8 0x3fdc905b0c10d420, 0x3cb1abbaa3edf120
+data8 0x9df765b9eecad5e6, 0xe6714846bdda7318
+data8 0x3fdcd7611f4b8a00, 0x3cbf6217ae80aadf
+data8 0x9ea2b320350540fe, 0xe5f4bab71494cd6b
+data8 0x3fdd1e8d6a0d56c0, 0x3cb726e048cc235c
+data8 0x9f51023562fc5676, 0xe576cbf239235ecb
+data8 0x3fdd65e082df5260, 0x3cd9e66872bd5250
+data8 0xa002620915c2a2f6, 0xe4f779b15f5ec5a7
+data8 0x3fddad5b02a82420, 0x3c89743b0b57534b
+data8 0xa0b6e21c2caf9992, 0xe476c1a233a7873e
+data8 0x3fddf4fd84bbe160, 0x3cbf7adea9ee3338
+data8 0xa16e9264cc83a6b2, 0xe3f4a16696608191
+data8 0x3fde3cc8a6ec6ee0, 0x3cce46f5a51f49c6
+data8 0xa22983528f3d8d49, 0xe3711694552da8a8
+data8 0x3fde84bd099a6600, 0x3cdc78f6490a2d31
+data8 0xa2e7c5d2e2e69460, 0xe2ec1eb4e1e0a5fb
+data8 0x3fdeccdb4fc685c0, 0x3cdd3aedb56a4825
+data8 0xa3a96b5599bd2532, 0xe265b74506fbe1c9
+data8 0x3fdf15241f23b3e0, 0x3cd440f3c6d65f65
+data8 0xa46e85d1ae49d7de, 0xe1ddddb499b3606f
+data8 0x3fdf5d98202994a0, 0x3cd6c44bd3fb745a
+data8 0xa53727ca3e11b99e, 0xe1548f662951b00d
+data8 0x3fdfa637fe27bf60, 0x3ca8ad1cd33054dd
+data8 0xa6036453bdc20186, 0xe0c9c9aeabe5e481
+data8 0x3fdfef0467599580, 0x3cc0f1ac0685d78a
+data8 0xa6d34f1969dda338, 0xe03d89d5281e4f81
+data8 0x3fe01bff067d6220, 0x3cc0731e8a9ef057
+data8 0xa7a6fc62f7246ff3, 0xdfafcd125c323f54
+data8 0x3fe04092d1ae3b40, 0x3ccabda24b59906d
+data8 0xa87e811a861df9b9, 0xdf20909061bb9760
+data8 0x3fe0653df0fd9fc0, 0x3ce94c8dcc722278
+data8 0xa959f2d2dd687200, 0xde8fd16a4e5f88bd
+data8 0x3fe08a00c1cae320, 0x3ce6b888bb60a274
+data8 0xaa3967cdeea58bda, 0xddfd8cabd1240d22
+data8 0x3fe0aedba3221c00, 0x3ced5941cd486e46
+data8 0xab904fd587263c84, 0xdd1f4472e1cf64ed
+data8 0x3fe0e651e85229c0, 0x3cdb6701042299b1
+data8 0xad686d44dd5a74bb, 0xdbf173e1f6b46e92
+data8 0x3fe1309cbf4cdb20, 0x3cbf1be7bb3f0ec5
+data8 0xaf524e15640ebee4, 0xdabd54896f1029f6
+data8 0x3fe17b4ee1641300, 0x3ce81dd055b792f1
+data8 0xb14eca24ef7db3fa, 0xd982cb9ae2f47e41
+data8 0x3fe1c66b9ffd6660, 0x3cd98ea31eb5ddc7
+data8 0xb35ec807669920ce, 0xd841bd1b8291d0b6
+data8 0x3fe211f66db3a5a0, 0x3ca480c35a27b4a2
+data8 0xb5833e4755e04dd1, 0xd6fa0bd3150b6930
+data8 0x3fe25df2e05b6c40, 0x3ca4bc324287a351
+data8 0xb7bd34c8000b7bd3, 0xd5ab9939a7d23aa1
+data8 0x3fe2aa64b32f7780, 0x3cba67314933077c
+data8 0xba0dc64d126cc135, 0xd4564563ce924481
+data8 0x3fe2f74fc9289ac0, 0x3cec1a1dc0efc5ec
+data8 0xbc76222cbbfa74a6, 0xd2f9eeed501125a8
+data8 0x3fe344b82f859ac0, 0x3ceeef218de413ac
+data8 0xbef78e31985291a9, 0xd19672e2182f78be
+data8 0x3fe392a22087b7e0, 0x3cd2619ba201204c
+data8 0xc19368b2b0629572, 0xd02baca5427e436a
+data8 0x3fe3e11206694520, 0x3cb5d0b3143fe689
+data8 0xc44b2ae8c6733e51, 0xceb975d60b6eae5d
+data8 0x3fe4300c7e945020, 0x3cbd367143da6582
+data8 0xc7206b894212dfef, 0xcd3fa6326ff0ac9a
+data8 0x3fe47f965d201d60, 0x3ce797c7a4ec1d63
+data8 0xca14e1b0622de526, 0xcbbe13773c3c5338
+data8 0x3fe4cfb4b09d1a20, 0x3cedfadb5347143c
+data8 0xcd2a6825eae65f82, 0xca34913d425a5ae9
+data8 0x3fe5206cc637e000, 0x3ce2798b38e54193
+data8 0xd06301095e1351ee, 0xc8a2f0d3679c08c0
+data8 0x3fe571c42e3d0be0, 0x3ccd7cb9c6c2ca68
+data8 0xd3c0d9f50057adda, 0xc70901152d59d16b
+data8 0x3fe5c3c0c108f940, 0x3ceb6c13563180ab
+data8 0xd74650a98cc14789, 0xc5668e3d4cbf8828
+data8 0x3fe61668a46ffa80, 0x3caa9092e9e3c0e5
+data8 0xdaf5f8579dcc8f8f, 0xc3bb61b3eed42d02
+data8 0x3fe669c251ad69e0, 0x3cccf896ef3b4fee
+data8 0xded29f9f9a6171b4, 0xc20741d7f8e8e8af
+data8 0x3fe6bdd49bea05c0, 0x3cdc6b29937c575d
+data8 0xe2df5765854ccdb0, 0xc049f1c2d1b8014b
+data8 0x3fe712a6b76c6e80, 0x3ce1ddc6f2922321
+data8 0xe71f7a9b94fcb4c3, 0xbe833105ec291e91
+data8 0x3fe76840418978a0, 0x3ccda46e85432c3d
+data8 0xeb96b72d3374b91e, 0xbcb2bb61493b28b3
+data8 0x3fe7bea9496d5a40, 0x3ce37b42ec6e17d3
+data8 0xf049183c3f53c39b, 0xbad848720223d3a8
+data8 0x3fe815ea59dab0a0, 0x3cb03ad41bfc415b
+data8 0xf53b11ec7f415f15, 0xb8f38b57c53c9c48
+data8 0x3fe86e0c84010760, 0x3cc03bfcfb17fe1f
+data8 0xfa718f05adbf2c33, 0xb70432500286b185
+data8 0x3fe8c7196b9225c0, 0x3ced99fcc6866ba9
+data8 0xfff200c3f5489608, 0xb509e6454dca33cc
+data8 0x3fe9211b54441080, 0x3cb789cb53515688
+// The following table entries are not used
+//data8 0x82e138a0fac48700, 0xb3044a513a8e6132
+//data8 0x3fe97c1d30f5b7c0, 0x3ce1eb765612d1d0
+//data8 0x85f4cc7fc670d021, 0xb0f2fb2ea6cbbc88
+//data8 0x3fe9d82ab4b5fde0, 0x3ced3fe6f27e8039
+//data8 0x89377c1387d5b908, 0xaed58e9a09014d5c
+//data8 0x3fea355065f87fa0, 0x3cbef481d25f5b58
+//data8 0x8cad7a2c98dec333, 0xacab929ce114d451
+//data8 0x3fea939bb451e2a0, 0x3c8e92b4fbf4560f
+//data8 0x905b7dfc99583025, 0xaa748cc0dbbbc0ec
+//data8 0x3feaf31b11270220, 0x3cdced8c61bd7bd5
+//data8 0x9446d8191f80dd42, 0xa82ff92687235baf
+//data8 0x3feb53de0bcffc20, 0x3cbe1722fb47509e
+//data8 0x98758ba086e4000a, 0xa5dd497a9c184f58
+//data8 0x3febb5f571cb0560, 0x3ce0c7774329a613
+//data8 0x9cee6c7bf18e4e24, 0xa37be3c3cd1de51b
+//data8 0x3fec197373bc7be0, 0x3ce08ebdb55c3177
+//data8 0xa1b944000a1b9440, 0xa10b2101b4f27e03
+//data8 0x3fec7e6bd023da60, 0x3ce5fc5fd4995959
+//data8 0xa6defd8ba04d3e38, 0x9e8a4b93cad088ec
+//data8 0x3fece4f404e29b20, 0x3cea3413401132b5
+//data8 0xac69dd408a10c62d, 0x9bf89d5d17ddae8c
+//data8 0x3fed4d2388f63600, 0x3cd5a7fb0d1d4276
+//data8 0xb265c39cbd80f97a, 0x99553d969fec7beb
+//data8 0x3fedb714101e0a00, 0x3cdbda21f01193f2
+//data8 0xb8e081a16ae4ae73, 0x969f3e3ed2a0516c
+//data8 0x3fee22e1da97bb00, 0x3ce7231177f85f71
+//data8 0xbfea427678945732, 0x93d5990f9ee787af
+//data8 0x3fee90ac13b18220, 0x3ce3c8a5453363a5
+//data8 0xc79611399b8c90c5, 0x90f72bde80febc31
+//data8 0x3fef009542b712e0, 0x3ce218fd79e8cb56
+//data8 0xcffa8425040624d7, 0x8e02b4418574ebed
+//data8 0x3fef72c3d2c57520, 0x3cd32a717f82203f
+//data8 0xd93299cddcf9cf23, 0x8af6ca48e9c44024
+//data8 0x3fefe762b77744c0, 0x3ce53478a6bbcf94
+//data8 0xe35eda760af69ad9, 0x87d1da0d7f45678b
+//data8 0x3ff02f511b223c00, 0x3ced6e11782c28fc
+//data8 0xeea6d733421da0a6, 0x84921bbe64ae029a
+//data8 0x3ff06c5c6f8ce9c0, 0x3ce71fc71c1ffc02
+//data8 0xfb3b2c73fc6195cc, 0x813589ba3a5651b6
+//data8 0x3ff0aaf2613700a0, 0x3cf2a72d2fd94ef3
+//data8 0x84ac1fcec4203245, 0xfb73a828893df19e
+//data8 0x3ff0eb367c3fd600, 0x3cf8054c158610de
+//data8 0x8ca50621110c60e6, 0xf438a14c158d867c
+//data8 0x3ff12d51caa6b580, 0x3ce6bce9748739b6
+//data8 0x95b8c2062d6f8161, 0xecb3ccdd37b369da
+//data8 0x3ff1717418520340, 0x3ca5c2732533177c
+//data8 0xa0262917caab4ad1, 0xe4dde4ddc81fd119
+//data8 0x3ff1b7d59dd40ba0, 0x3cc4c7c98e870ff5
+//data8 0xac402c688b72f3f4, 0xdcae469be46d4c8d
+//data8 0x3ff200b93cc5a540, 0x3c8dd6dc1bfe865a
+//data8 0xba76968b9eabd9ab, 0xd41a8f3df1115f7f
+//data8 0x3ff24c6f8f6affa0, 0x3cf1acb6d2a7eff7
+//data8 0xcb63c87c23a71dc5, 0xcb161074c17f54ec
+//data8 0x3ff29b5b338b7c80, 0x3ce9b5845f6ec746
+//data8 0xdfe323b8653af367, 0xc19107d99ab27e42
+//data8 0x3ff2edf6fac7f5a0, 0x3cf77f961925fa02
+//data8 0xf93746caaba3e1f1, 0xb777744a9df03bff
+//data8 0x3ff344df237486c0, 0x3cf6ddf5f6ddda43
+//data8 0x8ca77052f6c340f0, 0xacaf476f13806648
+//data8 0x3ff3a0dfa4bb4ae0, 0x3cfee01bbd761bff
+//data8 0xa1a48604a81d5c62, 0xa11575d30c0aae50
+//data8 0x3ff4030b73c55360, 0x3cf1cf0e0324d37c
+//data8 0xbe45074b05579024, 0x9478e362a07dd287
+//data8 0x3ff46ce4c738c4e0, 0x3ce3179555367d12
+//data8 0xe7a08b5693d214ec, 0x8690e3575b8a7c3b
+//data8 0x3ff4e0a887c40a80, 0x3cfbd5d46bfefe69
+//data8 0x94503d69396d91c7, 0xedd2ce885ff04028
+//data8 0x3ff561ebd9c18cc0, 0x3cf331bd176b233b
+//data8 0xced1d96c5bb209e6, 0xc965278083808702
+//data8 0x3ff5f71d7ff42c80, 0x3ce3301cc0b5a48c
+//data8 0xabac2cee0fc24e20, 0x9c4eb1136094cbbd
+//data8 0x3ff6ae4c63222720, 0x3cf5ff46874ee51e
+//data8 0x8040201008040201, 0xb4d7ac4d9acb1bf4
+//data8 0x3ff7b7d33b928c40, 0x3cfacdee584023bb
+LOCAL_OBJECT_END(T_table)
+
+
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+ // C_3
+data8 0xaaaaaaaaaaaaaaab, 0x0000000000003ffc
+ // C_5
+data8 0x999999999999999a, 0x0000000000003ffb
+ // C_7, C_9
+data8 0x3fa6db6db6db6db7, 0x3f9f1c71c71c71c8
+ // pi/2 (low, high)
+data8 0x3C91A62633145C07, 0x3FF921FB54442D18
+ // C_11, C_13
+data8 0x3f96e8ba2e8ba2e9, 0x3f91c4ec4ec4ec4e
+ // C_15, C_17
+data8 0x3f8c99999999999a, 0x3f87a87878787223
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+R_DBL_S = r21
+R_EXP0 = r22
+R_EXP = r15
+R_SGNMASK = r23
+R_TMP = r24
+R_TMP2 = r25
+R_INDEX = r26
+R_TMP3 = r27
+R_TMP03 = r27
+R_TMP4 = r28
+R_TMP5 = r23
+R_TMP6 = r22
+R_TMP7 = r21
+R_T = r29
+R_BIAS = r20
+
+F_T = f6
+F_1S2 = f7
+F_1S2_S = f9
+F_INV_1T2 = f10
+F_SQRT_1T2 = f11
+F_S2T2 = f12
+F_X = f13
+F_D = f14
+F_2M64 = f15
+
+F_CS2 = f32
+F_CS3 = f33
+F_CS4 = f34
+F_CS5 = f35
+F_CS6 = f36
+F_CS7 = f37
+F_CS8 = f38
+F_CS9 = f39
+F_S23 = f40
+F_S45 = f41
+F_S67 = f42
+F_S89 = f43
+F_S25 = f44
+F_S69 = f45
+F_S29 = f46
+F_X2 = f47
+F_X4 = f48
+F_TSQRT = f49
+F_DTX = f50
+F_R = f51
+F_R2 = f52
+F_R3 = f53
+F_R4 = f54
+
+F_C3 = f55
+F_C5 = f56
+F_C7 = f57
+F_C9 = f58
+F_P79 = f59
+F_P35 = f60
+F_P39 = f61
+
+F_ATHI = f62
+F_ATLO = f63
+
+F_T1 = f64
+F_Y = f65
+F_Y2 = f66
+F_ANDMASK = f67
+F_ORMASK = f68
+F_S = f69
+F_05 = f70
+F_SQRT_1S2 = f71
+F_DS = f72
+F_Z = f73
+F_1T2 = f74
+F_DZ = f75
+F_ZE = f76
+F_YZ = f77
+F_Y1S2 = f78
+F_Y1S2X = f79
+F_1X = f80
+F_ST = f81
+F_1T2_ST = f82
+F_TSS = f83
+F_Y1S2X2 = f84
+F_DZ_TERM = f85
+F_DTS = f86
+F_DS2X = f87
+F_T2 = f88
+F_ZY1S2S = f89
+F_Y1S2_1X = f90
+F_TS = f91
+F_PI2_LO = f92
+F_PI2_HI = f93
+F_S19 = f94
+F_INV1T2_2 = f95
+F_CORR = f96
+F_DZ0 = f97
+
+F_C11 = f98
+F_C13 = f99
+F_C15 = f100
+F_C17 = f101
+F_P1113 = f102
+F_P1517 = f103
+F_P1117 = f104
+F_P317 = f105
+F_R8 = f106
+F_HI = f107
+F_1S2_HI = f108
+F_DS2 = f109
+F_Y2_2 = f110
+F_S2 = f111
+F_S_DS2 = f112
+F_S_1S2S = f113
+F_XL = f114
+F_2M128 = f115
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(asinl)
+
+{.mfi
+ // get exponent, mantissa (rounded to double precision) of s
+ getf.d R_DBL_S = f8
+ // 1-s^2
+ fnma.s1 F_1S2 = f8, f8, f1
+ // r2 = pointer to T_table
+ addl r2 = @ltoff(T_table), gp
+}
+
+{.mfi
+ // sign mask
+ mov R_SGNMASK = 0x20000
+ nop.f 0
+ // bias-63-1
+ mov R_TMP03 = 0xffff-64;;
+}
+
+
+{.mfi
+ // get exponent of s
+ getf.exp R_EXP = f8
+ nop.f 0
+ // R_TMP4 = 2^45
+ shl R_TMP4 = R_SGNMASK, 45-17
+}
+
+{.mlx
+ // load bias-4
+ mov R_TMP = 0xffff-4
+ // load RU(sqrt(2)/2) to integer register (in double format, shifted left by 1)
+ movl R_TMP2 = 0x7fcd413cccfe779a;;
+}
+
+
+{.mfi
+ // load 2^{-64} in FP register
+ setf.exp F_2M64 = R_TMP03
+ nop.f 0
+ // index = (0x7-exponent)|b1 b2.. b6
+ extr.u R_INDEX = R_DBL_S, 46, 9
+}
+
+{.mfi
+ // get t = sign|exponent|b1 b2.. b6 1 x.. x
+ or R_T = R_DBL_S, R_TMP4
+ nop.f 0
+ // R_TMP4 = 2^45-1
+ sub R_TMP4 = R_TMP4, r0, 1;;
+}
+
+
+{.mfi
+ // get t = sign|exponent|b1 b2.. b6 1 0.. 0
+ andcm R_T = R_T, R_TMP4
+ nop.f 0
+ // eliminate sign from R_DBL_S (shift left by 1)
+ shl R_TMP3 = R_DBL_S, 1
+}
+
+{.mfi
+ // R_BIAS = 3*2^6
+ mov R_BIAS = 0xc0
+ nop.f 0
+ // eliminate sign from R_EXP
+ andcm R_EXP0 = R_EXP, R_SGNMASK;;
+}
+
+
+
+{.mfi
+ // load start address for T_table
+ ld8 r2 = [r2]
+ nop.f 0
+ // p8 = 1 if |s|> = sqrt(2)/2
+ cmp.geu p8, p0 = R_TMP3, R_TMP2
+}
+
+{.mlx
+ // p7 = 1 if |s|<2^{-4} (exponent of s<bias-4)
+ cmp.lt p7, p0 = R_EXP0, R_TMP
+ // sqrt coefficient cs8 = -33*13/128
+ movl R_TMP2 = 0xc0568000;;
+}
+
+
+
+{.mbb
+ // load t in FP register
+ setf.d F_T = R_T
+ // if |s|<2^{-4}, take alternate path
+ (p7) br.cond.spnt SMALL_S
+ // if |s|> = sqrt(2)/2, take alternate path
+ (p8) br.cond.sptk LARGE_S
+}
+
+{.mlx
+ // index = (4-exponent)|b1 b2.. b6
+ sub R_INDEX = R_INDEX, R_BIAS
+ // sqrt coefficient cs9 = 55*13/128
+ movl R_TMP = 0x40b2c000;;
+}
+
+
+{.mfi
+ // sqrt coefficient cs8 = -33*13/128
+ setf.s F_CS8 = R_TMP2
+ nop.f 0
+ // shift R_INDEX by 5
+ shl R_INDEX = R_INDEX, 5
+}
+
+{.mfi
+ // sqrt coefficient cs3 = 0.5 (set exponent = bias-1)
+ mov R_TMP4 = 0xffff - 1
+ nop.f 0
+ // sqrt coefficient cs6 = -21/16
+ mov R_TMP6 = 0xbfa8;;
+}
+
+
+{.mlx
+ // table index
+ add r2 = r2, R_INDEX
+ // sqrt coefficient cs7 = 33/16
+ movl R_TMP2 = 0x40040000;;
+}
+
+
+{.mmi
+ // load cs9 = 55*13/128
+ setf.s F_CS9 = R_TMP
+ // sqrt coefficient cs5 = 7/8
+ mov R_TMP3 = 0x3f60
+ // sqrt coefficient cs6 = 21/16
+ shl R_TMP6 = R_TMP6, 16;;
+}
+
+
+{.mmi
+ // load significand of 1/(1-t^2)
+ ldf8 F_INV_1T2 = [r2], 8
+ // sqrt coefficient cs7 = 33/16
+ setf.s F_CS7 = R_TMP2
+ // sqrt coefficient cs4 = -5/8
+ mov R_TMP5 = 0xbf20;;
+}
+
+
+{.mmi
+ // load significand of sqrt(1-t^2)
+ ldf8 F_SQRT_1T2 = [r2], 8
+ // sqrt coefficient cs6 = 21/16
+ setf.s F_CS6 = R_TMP6
+ // sqrt coefficient cs5 = 7/8
+ shl R_TMP3 = R_TMP3, 16;;
+}
+
+
+{.mmi
+ // sqrt coefficient cs3 = 0.5 (set exponent = bias-1)
+ setf.exp F_CS3 = R_TMP4
+ // r3 = pointer to polynomial coefficients
+ addl r3 = @ltoff(poly_coeffs), gp
+ // sqrt coefficient cs4 = -5/8
+ shl R_TMP5 = R_TMP5, 16;;
+}
+
+
+{.mfi
+ // sqrt coefficient cs5 = 7/8
+ setf.s F_CS5 = R_TMP3
+ // d = s-t
+ fms.s1 F_D = f8, f1, F_T
+ // set p6 = 1 if s<0, p11 = 1 if s> = 0
+ cmp.ge p6, p11 = R_EXP, R_DBL_S
+}
+
+{.mfi
+ // r3 = load start address to polynomial coefficients
+ ld8 r3 = [r3]
+ // s+t
+ fma.s1 F_S2T2 = f8, f1, F_T
+ nop.i 0;;
+}
+
+
+{.mfi
+ // sqrt coefficient cs4 = -5/8
+ setf.s F_CS4 = R_TMP5
+ // s^2-t^2
+ fma.s1 F_S2T2 = F_S2T2, F_D, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ // load C3
+ ldfe F_C3 = [r3], 16
+ // 0.5/(1-t^2) = 2^{-64}*(2^63/(1-t^2))
+ fma.s1 F_INV_1T2 = F_INV_1T2, F_2M64, f0
+ nop.i 0;;
+}
+
+{.mfi
+ // load C_5
+ ldfe F_C5 = [r3], 16
+ // set correct exponent for sqrt(1-t^2)
+ fma.s1 F_SQRT_1T2 = F_SQRT_1T2, F_2M64, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ // load C_7, C_9
+ ldfpd F_C7, F_C9 = [r3]
+ // x = -(s^2-t^2)/(1-t^2)/2
+ fnma.s1 F_X = F_INV_1T2, F_S2T2, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ // load asin(t)_high, asin(t)_low
+ ldfpd F_ATHI, F_ATLO = [r2]
+ // t*sqrt(1-t^2)
+ fma.s1 F_TSQRT = F_T, F_SQRT_1T2, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // cs9*x+cs8
+ fma.s1 F_S89 = F_CS9, F_X, F_CS8
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // cs7*x+cs6
+ fma.s1 F_S67 = F_CS7, F_X, F_CS6
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // cs5*x+cs4
+ fma.s1 F_S45 = F_CS5, F_X, F_CS4
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // x*x
+ fma.s1 F_X2 = F_X, F_X, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (s-t)-t*x
+ fnma.s1 F_DTX = F_T, F_X, F_D
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // cs3*x+cs2 (cs2 = -0.5 = -cs3)
+ fms.s1 F_S23 = F_CS3, F_X, F_CS3
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // cs9*x^3+cs8*x^2+cs7*x+cs6
+ fma.s1 F_S69 = F_S89, F_X2, F_S67
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // x^4
+ fma.s1 F_X4 = F_X2, F_X2, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // t*sqrt(1-t^2)*x^2
+ fma.s1 F_TSQRT = F_TSQRT, F_X2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // cs5*x^3+cs4*x^2+cs3*x+cs2
+ fma.s1 F_S25 = F_S45, F_X2, F_S23
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // ((s-t)-t*x)*sqrt(1-t^2)
+ fma.s1 F_DTX = F_DTX, F_SQRT_1T2, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // if sign is negative, negate table values: asin(t)_low
+ (p6) fnma.s1 F_ATLO = F_ATLO, f1, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // PS29 = cs9*x^7+..+cs5*x^3+cs4*x^2+cs3*x+cs2
+ fma.s1 F_S29 = F_S69, F_X4, F_S25
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // if sign is negative, negate table values: asin(t)_high
+ (p6) fnma.s1 F_ATHI = F_ATHI, f1, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // R = ((s-t)-t*x)*sqrt(1-t^2)-t*sqrt(1-t^2)*x^2*PS29
+ fnma.s1 F_R = F_S29, F_TSQRT, F_DTX
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // R^2
+ fma.s1 F_R2 = F_R, F_R, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c7+c9*R^2
+ fma.s1 F_P79 = F_C9, F_R2, F_C7
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2
+ fma.s1 F_P35 = F_C5, F_R2, F_C3
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // R^3
+ fma.s1 F_R4 = F_R2, F_R2, f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // R^3
+ fma.s1 F_R3 = F_R2, F_R, f0
+ nop.i 0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2+c7*R^4+c9*R^6
+ fma.s1 F_P39 = F_P79, F_R4, F_P35
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6)
+ fma.s1 F_P39 = F_P39, F_R3, F_ATLO
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // R+asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6)
+ fma.s1 F_P39 = F_P39, f1, F_R
+ nop.i 0;;
+}
+
+
+{.mfb
+ nop.m 0
+ // result = asin(t)_high+R+asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6)
+ fma.s0 f8 = F_ATHI, f1, F_P39
+ // return
+ br.ret.sptk b0;;
+}
+
+
+
+
+LARGE_S:
+
+{.mfi
+ // bias-1
+ mov R_TMP3 = 0xffff - 1
+ // y ~ 1/sqrt(1-s^2)
+ frsqrta.s1 F_Y, p7 = F_1S2
+ // c9 = 55*13*17/128
+ mov R_TMP4 = 0x10af7b
+}
+
+{.mlx
+ // c8 = -33*13*15/128
+ mov R_TMP5 = 0x184923
+ movl R_TMP2 = 0xff00000000000000;;
+}
+
+{.mfi
+ // set p6 = 1 if s<0, p11 = 1 if s>0
+ cmp.ge p6, p11 = R_EXP, R_DBL_S
+ // 1-s^2
+ fnma.s1 F_1S2 = f8, f8, f1
+ // set p9 = 1
+ cmp.eq p9, p0 = r0, r0;;
+}
+
+
+{.mfi
+ // load 0.5
+ setf.exp F_05 = R_TMP3
+ // (1-s^2) rounded to single precision
+ fnma.s.s1 F_1S2_S = f8, f8, f1
+ // c9 = 55*13*17/128
+ shl R_TMP4 = R_TMP4, 10
+}
+
+{.mlx
+ // AND mask for getting t ~ sqrt(1-s^2)
+ setf.sig F_ANDMASK = R_TMP2
+ // OR mask
+ movl R_TMP2 = 0x0100000000000000;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (s^2)_s
+ fma.s.s1 F_S2 = f8, f8, f0
+ nop.i 0;;
+}
+
+
+{.mmi
+ // c9 = 55*13*17/128
+ setf.s F_CS9 = R_TMP4
+ // c7 = 33*13/16
+ mov R_TMP4 = 0x41d68
+ // c8 = -33*13*15/128
+ shl R_TMP5 = R_TMP5, 11;;
+}
+
+
+{.mfi
+ setf.sig F_ORMASK = R_TMP2
+ // y^2
+ fma.s1 F_Y2 = F_Y, F_Y, f0
+ // c7 = 33*13/16
+ shl R_TMP4 = R_TMP4, 12
+}
+
+{.mfi
+ // c6 = -33*7/16
+ mov R_TMP6 = 0xc1670
+ // y' ~ sqrt(1-s^2)
+ fma.s1 F_T1 = F_Y, F_1S2, f0
+ // c5 = 63/8
+ mov R_TMP7 = 0x40fc;;
+}
+
+
+{.mlx
+ // load c8 = -33*13*15/128
+ setf.s F_CS8 = R_TMP5
+ // c4 = -35/8
+ movl R_TMP5 = 0xc08c0000;;
+}
+
+{.mfi
+ // r3 = pointer to polynomial coefficients
+ addl r3 = @ltoff(poly_coeffs), gp
+ // 1-(1-s^2)_s
+ fnma.s1 F_DS = F_1S2_S, f1, f1
+ // p9 = 0 if p7 = 1 (p9 = 1 for special cases only)
+ (p7) cmp.ne p9, p0 = r0, r0
+}
+
+{.mlx
+ // load c7 = 33*13/16
+ setf.s F_CS7 = R_TMP4
+ // c3 = 5/2
+ movl R_TMP4 = 0x40200000;;
+}
+
+
+{.mfi
+ nop.m 0
+ // 1-(s^2)_s
+ fnma.s1 F_S_1S2S = F_S2, f1, f1
+ nop.i 0
+}
+
+{.mlx
+ // load c4 = -35/8
+ setf.s F_CS4 = R_TMP5
+ // c2 = -3/2
+ movl R_TMP5 = 0xbfc00000;;
+}
+
+
+{.mfi
+ // load c3 = 5/2
+ setf.s F_CS3 = R_TMP4
+ // x = (1-s^2)_s*y^2-1
+ fms.s1 F_X = F_1S2_S, F_Y2, f1
+ // c6 = -33*7/16
+ shl R_TMP6 = R_TMP6, 12
+}
+
+{.mfi
+ nop.m 0
+ // y^2/2
+ fma.s1 F_Y2_2 = F_Y2, F_05, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ // load c6 = -33*7/16
+ setf.s F_CS6 = R_TMP6
+ // eliminate lower bits from y'
+ fand F_T = F_T1, F_ANDMASK
+ // c5 = 63/8
+ shl R_TMP7 = R_TMP7, 16
+}
+
+{.mfb
+ // r3 = load start address to polynomial coefficients
+ ld8 r3 = [r3]
+ // 1-(1-s^2)_s-s^2
+ fnma.s1 F_DS = f8, f8, F_DS
+ // p9 = 1 if s is a special input (NaN, or |s|> = 1)
+ (p9) br.cond.spnt ASINL_SPECIAL_CASES;;
+}
+
+{.mmf
+ // get exponent, significand of y' (in single prec.)
+ getf.s R_TMP = F_T1
+ // load c3 = -3/2
+ setf.s F_CS2 = R_TMP5
+ // y*(1-s^2)
+ fma.s1 F_Y1S2 = F_Y, F_1S2, f0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // x' = (y^2/2)*(1-(s^2)_s)-0.5
+ fms.s1 F_XL = F_Y2_2, F_S_1S2S, F_05
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // s^2-(s^2)_s
+ fms.s1 F_S_DS2 = f8, f8, F_S2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // if s<0, set s = -s
+ (p6) fnma.s1 f8 = f8, f1, f0
+ nop.i 0;;
+}
+
+{.mfi
+ // load c5 = 63/8
+ setf.s F_CS5 = R_TMP7
+ // x = (1-s^2)_s*y^2-1+(1-(1-s^2)_s-s^2)*y^2
+ fma.s1 F_X = F_DS, F_Y2, F_X
+ // for t = 2^k*1.b1 b2.., get 7-k|b1.. b6
+ extr.u R_INDEX = R_TMP, 17, 9;;
+}
+
+
+{.mmi
+ // index = (4-exponent)|b1 b2.. b6
+ sub R_INDEX = R_INDEX, R_BIAS
+ nop.m 0
+ // get exponent of y
+ shr.u R_TMP2 = R_TMP, 23;;
+}
+
+{.mmi
+ // load C3
+ ldfe F_C3 = [r3], 16
+ // set p8 = 1 if y'<2^{-4}
+ cmp.gt p8, p0 = 0x7b, R_TMP2
+ // shift R_INDEX by 5
+ shl R_INDEX = R_INDEX, 5;;
+}
+
+
+{.mfb
+ // get table index for sqrt(1-t^2)
+ add r2 = r2, R_INDEX
+ // get t = 2^k*1.b1 b2.. b7 1
+ for F_T = F_T, F_ORMASK
+ (p8) br.cond.spnt VERY_LARGE_INPUT;;
+}
+
+
+
+{.mmf
+ // load C5
+ ldfe F_C5 = [r3], 16
+ // load 1/(1-t^2)
+ ldfp8 F_INV_1T2, F_SQRT_1T2 = [r2], 16
+ // x = ((1-s^2)*y^2-1)/2
+ fma.s1 F_X = F_X, F_05, f0;;
+}
+
+
+
+{.mmf
+ nop.m 0
+ // C7, C9
+ ldfpd F_C7, F_C9 = [r3], 16
+ // set correct exponent for t
+ fmerge.se F_T = F_T1, F_T;;
+}
+
+
+
+{.mfi
+ // pi/2 (low, high)
+ ldfpd F_PI2_LO, F_PI2_HI = [r3]
+ // c9*x+c8
+ fma.s1 F_S89 = F_X, F_CS9, F_CS8
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // x^2
+ fma.s1 F_X2 = F_X, F_X, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*(1-s^2)*x
+ fma.s1 F_Y1S2X = F_Y1S2, F_X, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c7*x+c6
+ fma.s1 F_S67 = F_X, F_CS7, F_CS6
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // 1-x
+ fnma.s1 F_1X = F_X, f1, f1
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c3*x+c2
+ fma.s1 F_S23 = F_X, F_CS3, F_CS2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // 1-t^2
+ fnma.s1 F_1T2 = F_T, F_T, f1
+ nop.i 0
+}
+
+{.mfi
+ // load asin(t)_high, asin(t)_low
+ ldfpd F_ATHI, F_ATLO = [r2]
+ // c5*x+c4
+ fma.s1 F_S45 = F_X, F_CS5, F_CS4
+ nop.i 0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // t*s
+ fma.s1 F_TS = F_T, f8, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // 0.5/(1-t^2)
+ fma.s1 F_INV_1T2 = F_INV_1T2, F_2M64, f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // z~sqrt(1-t^2), rounded to 24 significant bits
+ fma.s.s1 F_Z = F_SQRT_1T2, F_2M64, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // sqrt(1-t^2)
+ fma.s1 F_SQRT_1T2 = F_SQRT_1T2, F_2M64, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*(1-s^2)*x^2
+ fma.s1 F_Y1S2X2 = F_Y1S2, F_X2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // x^4
+ fma.s1 F_X4 = F_X2, F_X2, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // s*t rounded to 24 significant bits
+ fma.s.s1 F_TSS = F_T, f8, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c9*x^3+..+c6
+ fma.s1 F_S69 = F_X2, F_S89, F_S67
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // ST = (t^2-1+s^2) rounded to 24 significant bits
+ fms.s.s1 F_ST = f8, f8, F_1T2
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c5*x^3+..+c2
+ fma.s1 F_S25 = F_X2, F_S45, F_S23
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // 0.25/(1-t^2)
+ fma.s1 F_INV1T2_2 = F_05, F_INV_1T2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // t*s-sqrt(1-t^2)*(1-s^2)*y
+ fnma.s1 F_TS = F_Y1S2, F_SQRT_1T2, F_TS
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // z*0.5/(1-t^2)
+ fma.s1 F_ZE = F_INV_1T2, F_SQRT_1T2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // z^2+t^2-1
+ fms.s1 F_DZ0 = F_Z, F_Z, F_1T2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (1-s^2-(1-s^2)_s)*x
+ fma.s1 F_DS2X = F_X, F_DS, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // t*s-(t*s)_s
+ fms.s1 F_DTS = F_T, f8, F_TSS
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c9*x^7+..+c2
+ fma.s1 F_S29 = F_X4, F_S69, F_S25
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*z
+ fma.s1 F_YZ = F_Z, F_Y, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // t^2
+ fma.s1 F_T2 = F_T, F_T, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // 1-t^2+ST
+ fma.s1 F_1T2_ST = F_ST, f1, F_1T2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*(1-s^2)(1-x)
+ fma.s1 F_Y1S2_1X = F_Y1S2, F_1X, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // dz ~ sqrt(1-t^2)-z
+ fma.s1 F_DZ = F_DZ0, F_ZE, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // -1+correction for sqrt(1-t^2)-z
+ fnma.s1 F_CORR = F_INV1T2_2, F_DZ0, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (PS29*x^2+x)*y*(1-s^2)
+ fma.s1 F_S19 = F_Y1S2X2, F_S29, F_Y1S2X
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // z*y*(1-s^2)_s
+ fma.s1 F_ZY1S2S = F_YZ, F_1S2_S, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // s^2-(1-t^2+ST)
+ fms.s1 F_1T2_ST = f8, f8, F_1T2_ST
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (t*s-(t*s)_s)+z*y*(1-s^2-(1-s^2)_s)*x
+ fma.s1 F_DTS = F_YZ, F_DS2X, F_DTS
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // dz*y*(1-s^2)*(1-x)
+ fma.s1 F_DZ_TERM = F_DZ, F_Y1S2_1X, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // R = t*s-sqrt(1-t^2)*(1-s^2)*y+sqrt(1-t^2)*(1-s^2)*y*PS19
+ // (used for polynomial evaluation)
+ fma.s1 F_R = F_S19, F_SQRT_1T2, F_TS
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (PS29*x^2)*y*(1-s^2)
+ fma.s1 F_S29 = F_Y1S2X2, F_S29, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // apply correction to dz*y*(1-s^2)*(1-x)
+ fma.s1 F_DZ_TERM = F_DZ_TERM, F_CORR, F_DZ_TERM
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // R^2
+ fma.s1 F_R2 = F_R, F_R, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (t*s-(t*s)_s)+z*y*(1-s^2-(1-s^2)_s)*x+dz*y*(1-s^2)*(1-x)
+ fma.s1 F_DZ_TERM = F_DZ_TERM, f1, F_DTS
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c7+c9*R^2
+ fma.s1 F_P79 = F_C9, F_R2, F_C7
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2
+ fma.s1 F_P35 = F_C5, F_R2, F_C3
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // asin(t)_low-(pi/2)_low
+ fms.s1 F_ATLO = F_ATLO, f1, F_PI2_LO
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // R^4
+ fma.s1 F_R4 = F_R2, F_R2, f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // R^3
+ fma.s1 F_R3 = F_R2, F_R, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (t*s)_s-t^2*y*z
+ fnma.s1 F_TSS = F_T2, F_YZ, F_TSS
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // d(ts)+z*y*d(1-s^2)*x+dz*y*(1-s^2)*(1-x)+z*y*(s^2-1+t^2-ST)
+ fma.s1 F_DZ_TERM = F_YZ, F_1T2_ST, F_DZ_TERM
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (pi/2)_hi-asin(t)_hi
+ fms.s1 F_ATHI = F_PI2_HI, f1, F_ATHI
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2+c7*R^4+c9*R^6
+ fma.s1 F_P39 = F_P79, F_R4, F_P35
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // d(ts)+z*y*d(1-s^2)*x+dz*y*(1-s^2)*(1-x)+z*y*(s^2-1+t^2-ST)+
+ // + sqrt(1-t^2)*y*(1-s^2)*x^2*PS29
+ fma.s1 F_DZ_TERM = F_SQRT_1T2, F_S29, F_DZ_TERM
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (t*s)_s-t^2*y*z+z*y*ST
+ fma.s1 F_TSS = F_YZ, F_ST, F_TSS
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // -asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6)
+ fms.s1 F_P39 = F_P39, F_R3, F_ATLO
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // if s<0, change sign of F_ATHI
+ (p6) fnma.s1 F_ATHI = F_ATHI, f1, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // d(ts)+z*y*d(1-s^2)*x+dz*y*(1-s^2)*(1-x)+z*y*(s^2-1+t^2-ST) +
+ // + sqrt(1-t^2)*y*(1-s^2)*x^2*PS29 +
+ // - asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6)
+ fma.s1 F_DZ_TERM = F_P39, f1, F_DZ_TERM
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // d(ts)+z*y*d(1-s^2)*x+dz*y*(1-s^2)*(1-x)+z*y*(s^2-1+t^2-ST) +
+ // + sqrt(1-t^2)*y*(1-s^2)*x^2*PS29 + z*y*(1-s^2)_s*x +
+ // - asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6)
+ fma.s1 F_DZ_TERM = F_ZY1S2S, F_X, F_DZ_TERM
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // d(ts)+z*y*d(1-s^2)*x+dz*y*(1-s^2)*(1-x)+z*y*(s^2-1+t^2-ST) +
+ // + sqrt(1-t^2)*y*(1-s^2)*x^2*PS29 + z*y*(1-s^2)_s*x +
+ // - asin(t)_low+R^3*(c3+c5*R^2+c7*R^4+c9*R^6) +
+ // + (t*s)_s-t^2*y*z+z*y*ST
+ fma.s1 F_DZ_TERM = F_TSS, f1, F_DZ_TERM
+ nop.i 0;;
+}
+
+
+.pred.rel "mutex", p6, p11
+{.mfi
+ nop.m 0
+ // result: add high part of pi/2-table value
+ // s>0 in this case
+ (p11) fma.s0 f8 = F_DZ_TERM, f1, F_ATHI
+ nop.i 0
+}
+
+{.mfb
+ nop.m 0
+ // result: add high part of pi/2-table value
+ // if s<0
+ (p6) fnma.s0 f8 = F_DZ_TERM, f1, F_ATHI
+ br.ret.sptk b0;;
+}
+
+
+
+
+
+
+SMALL_S:
+
+ // use 15-term polynomial approximation
+
+{.mmi
+ // r3 = pointer to polynomial coefficients
+ addl r3 = @ltoff(poly_coeffs), gp;;
+ // load start address for coefficients
+ ld8 r3 = [r3]
+ mov R_TMP = 0x3fbf;;
+}
+
+
+{.mmi
+ add r2 = 64, r3
+ ldfe F_C3 = [r3], 16
+ // p7 = 1 if |s|<2^{-64} (exponent of s<bias-64)
+ cmp.lt p7, p0 = R_EXP0, R_TMP;;
+}
+
+{.mmf
+ ldfe F_C5 = [r3], 16
+ ldfpd F_C11, F_C13 = [r2], 16
+ // 2^{-128}
+ fma.s1 F_2M128 = F_2M64, F_2M64, f0;;
+}
+
+{.mmf
+ ldfpd F_C7, F_C9 = [r3]
+ ldfpd F_C15, F_C17 = [r2]
+ // if |s|<2^{-64}, return s+2^{-128}*s
+ (p7) fma.s0 f8 = f8, F_2M128, f8;;
+}
+
+
+
+{.mfb
+ nop.m 0
+ // s^2
+ fma.s1 F_R2 = f8, f8, f0
+ // if |s|<2^{-64}, return s
+ (p7) br.ret.spnt b0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // s^3
+ fma.s1 F_R3 = f8, F_R2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // s^4
+ fma.s1 F_R4 = F_R2, F_R2, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c3+c5*s^2
+ fma.s1 F_P35 = F_C5, F_R2, F_C3
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c11+c13*s^2
+ fma.s1 F_P1113 = F_C13, F_R2, F_C11
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c7+c9*s^2
+ fma.s1 F_P79 = F_C9, F_R2, F_C7
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c15+c17*s^2
+ fma.s1 F_P1517 = F_C17, F_R2, F_C15
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // s^8
+ fma.s1 F_R8 = F_R4, F_R4, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c3+c5*s^2+c7*s^4+c9*s^6
+ fma.s1 F_P39 = F_P79, F_R4, F_P35
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c11+c13*s^2+c15*s^4+c17*s^6
+ fma.s1 F_P1117 = F_P1517, F_R4, F_P1113
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c3+..+c17*s^14
+ fma.s1 F_P317 = F_R8, F_P1117, F_P39
+ nop.i 0;;
+}
+
+
+{.mfb
+ nop.m 0
+ // result
+ fma.s0 f8 = F_P317, F_R3, f8
+ br.ret.sptk b0;;
+}
+
+
+{.mfb
+ nop.m 0
+ fma.s0 f8 = F_P317, F_R3, f0//F_P317, F_R3, F_S29
+ // nop.f 0//fma.s0 f8 = f13, f6, f0
+ br.ret.sptk b0;;
+}
+
+
+
+
+
+ VERY_LARGE_INPUT:
+
+{.mfi
+ nop.m 0
+ // s rounded to 24 significant bits
+ fma.s.s1 F_S = f8, f1, f0
+ nop.i 0
+}
+
+{.mfi
+ // load C5
+ ldfe F_C5 = [r3], 16
+ // x = ((1-(s^2)_s)*y^2-1)/2-(s^2-(s^2)_s)*y^2/2
+ fnma.s1 F_X = F_S_DS2, F_Y2_2, F_XL
+ nop.i 0;;
+}
+
+
+
+{.mmf
+ nop.m 0
+ // C7, C9
+ ldfpd F_C7, F_C9 = [r3], 16
+ nop.f 0;;
+}
+
+
+
+{.mfi
+ // pi/2 (low, high)
+ ldfpd F_PI2_LO, F_PI2_HI = [r3], 16
+ // c9*x+c8
+ fma.s1 F_S89 = F_X, F_CS9, F_CS8
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // x^2
+ fma.s1 F_X2 = F_X, F_X, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*(1-s^2)*x
+ fma.s1 F_Y1S2X = F_Y1S2, F_X, f0
+ nop.i 0
+}
+
+{.mfi
+ // C11, C13
+ ldfpd F_C11, F_C13 = [r3], 16
+ // c7*x+c6
+ fma.s1 F_S67 = F_X, F_CS7, F_CS6
+ nop.i 0;;
+}
+
+
+{.mfi
+ // C15, C17
+ ldfpd F_C15, F_C17 = [r3], 16
+ // c3*x+c2
+ fma.s1 F_S23 = F_X, F_CS3, F_CS2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c5*x+c4
+ fma.s1 F_S45 = F_X, F_CS5, F_CS4
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (s_s)^2
+ fma.s1 F_DS = F_S, F_S, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // 1-(s_s)^2
+ fnma.s1 F_1S2_S = F_S, F_S, f1
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*(1-s^2)*x^2
+ fma.s1 F_Y1S2X2 = F_Y1S2, F_X2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // x^4
+ fma.s1 F_X4 = F_X2, F_X2, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c9*x^3+..+c6
+ fma.s1 F_S69 = F_X2, F_S89, F_S67
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c5*x^3+..+c2
+ fma.s1 F_S25 = F_X2, F_S45, F_S23
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // ((s_s)^2-s^2)
+ fnma.s1 F_DS = f8, f8, F_DS
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // (pi/2)_high-y*(1-(s_s)^2)
+ fnma.s1 F_HI = F_Y, F_1S2_S, F_PI2_HI
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c9*x^7+..+c2
+ fma.s1 F_S29 = F_X4, F_S69, F_S25
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // -(y*(1-(s_s)^2))_high
+ fms.s1 F_1S2_HI = F_HI, f1, F_PI2_HI
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (PS29*x^2+x)*y*(1-s^2)
+ fma.s1 F_S19 = F_Y1S2X2, F_S29, F_Y1S2X
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*(1-(s_s)^2)-(y*(1-s^2))_high
+ fma.s1 F_DS2 = F_Y, F_1S2_S, F_1S2_HI
+ nop.i 0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // R ~ sqrt(1-s^2)
+ // (used for polynomial evaluation)
+ fnma.s1 F_R = F_S19, f1, F_Y1S2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // y*(1-s^2)-(y*(1-s^2))_high
+ fma.s1 F_DS2 = F_Y, F_DS, F_DS2
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // (pi/2)_low+(PS29*x^2)*y*(1-s^2)
+ fma.s1 F_S29 = F_Y1S2X2, F_S29, F_PI2_LO
+ nop.i 0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // R^2
+ fma.s1 F_R2 = F_R, F_R, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (pi/2)_low+(PS29*x^2)*y*(1-s^2)-(y*(1-s^2)-(y*(1-s^2))_high)
+ fms.s1 F_S29 = F_S29, f1, F_DS2
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c7+c9*R^2
+ fma.s1 F_P79 = F_C9, F_R2, F_C7
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2
+ fma.s1 F_P35 = F_C5, F_R2, F_C3
+ nop.i 0;;
+}
+
+
+
+{.mfi
+ nop.m 0
+ // R^4
+ fma.s1 F_R4 = F_R2, F_R2, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // R^3
+ fma.s1 F_R3 = F_R2, F_R, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c11+c13*R^2
+ fma.s1 F_P1113 = F_C13, F_R2, F_C11
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c15+c17*R^2
+ fma.s1 F_P1517 = F_C17, F_R2, F_C15
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (pi/2)_low+(PS29*x^2)*y*(1-s^2)-(y*(1-s^2)-(y*(1-s^2))_high)+y*(1-s^2)*x
+ fma.s1 F_S29 = F_Y1S2, F_X, F_S29
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c11+c13*R^2+c15*R^4+c17*R^6
+ fma.s1 F_P1117 = F_P1517, F_R4, F_P1113
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2+c7*R^4+c9*R^6
+ fma.s1 F_P39 = F_P79, F_R4, F_P35
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // R^8
+ fma.s1 F_R8 = F_R4, F_R4, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // c3+c5*R^2+c7*R^4+c9*R^6+..+c17*R^14
+ fma.s1 F_P317 = F_P1117, F_R8, F_P39
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (pi/2)_low-(PS29*x^2)*y*(1-s^2)-(y*(1-s^2)-
+ // -(y*(1-s^2))_high)+y*(1-s^2)*x - P3, 17
+ fnma.s1 F_S29 = F_P317, F_R3, F_S29
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // set sign
+ (p6) fnma.s1 F_S29 = F_S29, f1, f0
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ (p6) fnma.s1 F_HI = F_HI, f1, f0
+ nop.i 0;;
+}
+
+
+{.mfb
+ nop.m 0
+ // Result:
+ // (pi/2)_low-(PS29*x^2)*y*(1-s^2)-(y*(1-s^2)-
+ // -(y*(1-s^2))_high)+y*(1-s^2)*x - P3, 17
+ // +(pi/2)_high-(y*(1-s^2))_high
+ fma.s0 f8 = F_S29, f1, F_HI
+ br.ret.sptk b0;;
+}
+
+
+
+
+
+
+
+
+
+ ASINL_SPECIAL_CASES:
+
+{.mfi
+ alloc r32 = ar.pfs, 1, 4, 4, 0
+ // check if the input is a NaN, or unsupported format
+ // (i.e. not infinity or normal/denormal)
+ fclass.nm p7, p8 = f8, 0x3f
+ // pointer to pi/2
+ add r3 = 48, r3;;
+}
+
+
+{.mfi
+ // load pi/2
+ ldfpd F_PI2_HI, F_PI2_LO = [r3]
+ // get |s|
+ fmerge.s F_S = f0, f8
+ nop.i 0
+}
+
+{.mfb
+ nop.m 0
+ // if NaN, quietize it, and return
+ (p7) fma.s0 f8 = f8, f1, f0
+ (p7) br.ret.spnt b0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // |s| = 1 ?
+ fcmp.eq.s0 p9, p0 = F_S, f1
+ nop.i 0
+}
+
+{.mfi
+ nop.m 0
+ // load FR_X
+ fma.s1 FR_X = f8, f1, f0
+ // load error tag
+ mov GR_Parameter_TAG = 60;;
+}
+
+
+{.mfb
+ nop.m 0
+ // change sign if s = -1
+ (p6) fnma.s1 F_PI2_HI = F_PI2_HI, f1, f0
+ nop.b 0
+}
+
+{.mfb
+ nop.m 0
+ // change sign if s = -1
+ (p6) fnma.s1 F_PI2_LO = F_PI2_LO, f1, f0
+ nop.b 0;;
+}
+
+{.mfb
+ nop.m 0
+ // if s = 1, result is pi/2
+ (p9) fma.s0 f8 = F_PI2_HI, f1, F_PI2_LO
+ // return if |s| = 1
+ (p9) br.ret.sptk b0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // get Infinity
+ frcpa.s1 FR_RESULT, p0 = f1, f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // return QNaN indefinite (0*Infinity)
+ fma.s0 FR_RESULT = f0, FR_RESULT, f0
+ nop.i 0;;
+}
+
+
+GLOBAL_LIBM_END(asinl)
+
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+
+// (2)
+{ .mmi
+ stfe [GR_Parameter_Y] = f1,16 // Store Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+// (4)
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_atan2.S b/libc/sysdeps/ia64/fpu/e_atan2.S
new file mode 100644
index 000000000..7a17fbfed
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_atan2.S
@@ -0,0 +1,1049 @@
+.file "atan2.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 08/17/00 Changed predicate register macro-usage to direct predicate
+// names due to an assembler bug.
+// 09/28/00 Updated to set invalid on SNaN inputs
+// 01/19/01 Fixed flags for small results
+// 04/13/01 Rescheduled to make all paths faster
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 08/20/02 Corrected inexact flag and directed rounding symmetry bugs
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 04/17/03 Added missing mutex directive
+// 12/23/03 atan2(NaN1,NaN2) now QNaN1, for consistency with atan2f, atan2l
+//
+// API
+//==============================================================
+// double atan2(double Y, double X)
+//
+// Overview of operation
+//==============================================================
+//
+// The atan2 function returns values in the interval [-pi,+pi].
+//
+// There are two basic paths: swap true and swap false.
+// atan2(Y,X) ==> atan2(V/U) where U >= V. If Y > X, we must swap.
+//
+// p6 swap True |Y| > |X|
+// p7 swap False |Y| <= |X|
+// p8 X+ (If swap=True p8=p9=0)
+// p9 X-
+//
+// all the other predicates p10 thru p15 are false for the main path
+//
+// Simple trigonometric identities show
+// Region 1 (-45 to +45 degrees):
+// X>0, |Y|<=X, V=Y, U=X atan2(Y,X) = sgnY * (0 + atan(V/U))
+//
+// Region 2 (-90 to -45 degrees, and +45 to +90 degrees):
+// X>0, |Y|>X, V=X, U=Y atan2(Y,X) = sgnY * (pi/2 - atan(V/U))
+//
+// Region 3 (-135 to -90 degrees, and +90 to +135 degrees):
+// X<0, |Y|>X, V=X, U=Y atan2(Y,X) = sgnY * (pi/2 + atan(V/U))
+//
+// Region 4 (-180 to -135 degrees, and +135 to +180 degrees):
+// X<0, |Y|<=X, V=Y, U=X atan2(Y,X) = sgnY * (pi - atan(V/U))
+//
+// So the result is always of the form atan2(Y,X) = P + sgnXY * atan(V/U)
+//
+// We compute atan(V/U) from the identity
+// atan(z) + atan([(V/U)-z] / [1+(V/U)z])
+// where z is a limited precision approximation (16 bits) to V/U
+//
+// z is calculated with the assistance of the frcpa instruction.
+//
+// atan(z) is calculated by a polynomial z + z^3 * p(w), w=z^2
+// where p(w) = P0+P1*w+...+P22*w^22
+//
+// Let d = [(V/U)-z] / [1+(V/U)z]) = (V-U*z)/(U+V*z)
+//
+// Approximate atan(d) by d + P0*d^3
+// Let F = 1/(U+V*z) * (1-a), where |a|< 2^-8.8.
+// Compute q(a) = 1 + a + ... + a^5.
+// Then F*q(a) approximates the reciprocal to more than 50 bits.
+
+// Special values
+//==============================================================
+// Y x Result
+// +number +inf +0
+// -number +inf -0
+// +number -inf +pi
+// -number -inf -pi
+//
+// +inf +number +pi/2
+// -inf +number -pi/2
+// +inf -number +pi/2
+// -inf -number -pi/2
+//
+// +inf +inf +pi/4
+// -inf +inf -pi/4
+// +inf -inf +3pi/4
+// -inf -inf -3pi/4
+//
+// +1 +1 +pi/4
+// -1 +1 -pi/4
+// +1 -1 +3pi/4
+// -1 -1 -3pi/4
+//
+// +number +0 +pi/2
+// -number +0 -pi/2
+// +number -0 +pi/2
+// -number -0 -pi/2
+//
+// +0 +number +0
+// -0 +number -0
+// +0 -number +pi
+// -0 -number -pi
+//
+// +0 +0 +0
+// -0 +0 -0
+// +0 -0 +pi
+// -0 -0 -pi
+//
+// Nan anything quiet Y
+// Not NaN NaN quiet X
+
+// atan2(+-0/+-0) sets double error tag to 37
+
+// Registers used
+//==============================================================
+
+// predicate registers used:
+// p6 -> p15
+
+// floating-point registers used:
+// f8, f9 input
+// f32 -> f119
+
+// general registers used
+// r32 -> r41
+
+// Assembly macros
+//==============================================================
+
+EXP_AD_P1 = r33
+EXP_AD_P2 = r34
+rsig_near_one = r35
+
+
+GR_SAVE_B0 = r35
+GR_SAVE_GP = r36
+GR_SAVE_PFS = r37
+
+GR_Parameter_X = r38
+GR_Parameter_Y = r39
+GR_Parameter_RESULT = r40
+atan2_GR_tag = r41
+
+atan2_Y = f8
+atan2_X = f9
+
+atan2_u1_X = f32
+atan2_u1_Y = f33
+atan2_z2_X = f34
+atan2_z2_Y = f35
+
+atan2_two = f36
+atan2_B1sq_Y = f37
+atan2_z1_X = f38
+atan2_z1_Y = f39
+atan2_B1X = f40
+
+atan2_B1Y = f41
+atan2_wp_X = f42
+atan2_B1sq_X = f43
+atan2_z = f44
+atan2_w = f45
+
+atan2_P0 = f46
+atan2_P1 = f47
+atan2_P2 = f48
+atan2_P3 = f49
+atan2_P4 = f50
+
+atan2_P5 = f51
+atan2_P6 = f52
+atan2_P7 = f53
+atan2_P8 = f54
+atan2_P9 = f55
+
+atan2_P10 = f56
+atan2_P11 = f57
+atan2_P12 = f58
+atan2_P13 = f59
+atan2_P14 = f60
+
+atan2_P15 = f61
+atan2_P16 = f62
+atan2_P17 = f63
+atan2_P18 = f64
+atan2_P19 = f65
+
+atan2_P20 = f66
+atan2_P21 = f67
+atan2_P22 = f68
+atan2_tmp = f68
+atan2_pi_by_2 = f69
+atan2_sgn_pi_by_2 = f69
+atan2_V13 = f70
+
+atan2_W11 = f71
+atan2_E = f72
+atan2_wp_Y = f73
+atan2_V11 = f74
+atan2_V12 = f75
+
+atan2_V7 = f76
+atan2_V8 = f77
+atan2_W7 = f78
+atan2_W8 = f79
+atan2_W3 = f80
+
+atan2_W4 = f81
+atan2_V3 = f82
+atan2_V4 = f83
+atan2_F = f84
+atan2_gV = f85
+
+atan2_V10 = f86
+atan2_zcub = f87
+atan2_V6 = f88
+atan2_V9 = f89
+atan2_W10 = f90
+
+atan2_W6 = f91
+atan2_W2 = f92
+atan2_V2 = f93
+atan2_alpha = f94
+atan2_alpha_1 = f95
+
+atan2_gVF = f96
+atan2_V5 = f97
+atan2_W12 = f98
+atan2_W5 = f99
+atan2_alpha_sq = f100
+
+atan2_Cp = f101
+atan2_V1 = f102
+atan2_ysq = f103
+atan2_W1 = f104
+atan2_alpha_cub = f105
+
+atan2_C = f106
+atan2_xsq = f107
+atan2_d = f108
+atan2_A_hi = f109
+atan2_dsq = f110
+
+atan2_pd = f111
+atan2_A_lo = f112
+atan2_A = f113
+atan2_Pp = f114
+atan2_sgnY = f115
+
+atan2_sig_near_one = f116
+atan2_near_one = f116
+atan2_pi = f117
+atan2_sgn_pi = f117
+atan2_3pi_by_4 = f118
+atan2_pi_by_4 = f119
+
+
+/////////////////////////////////////////////////////////////
+
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(atan2_tb1)
+data8 0xA21922DC45605EA1 , 0x00003FFA // P11
+data8 0xB199DD6D2675C40F , 0x0000BFFA // P10
+data8 0xC2F01E5DDD100DBE , 0x00003FFA // P9
+data8 0xD78F28FC2A592781 , 0x0000BFFA // P8
+data8 0xF0F03ADB3FC930D3 , 0x00003FFA // P7
+data8 0x88887EBB209E3543 , 0x0000BFFB // P6
+data8 0x9D89D7D55C3287A5 , 0x00003FFB // P5
+data8 0xBA2E8B9793955C77 , 0x0000BFFB // P4
+data8 0xE38E38E320A8A098 , 0x00003FFB // P3
+data8 0x9249249247E37913 , 0x0000BFFC // P2
+data8 0xCCCCCCCCCCC906CD , 0x00003FFC // P1
+data8 0xAAAAAAAAAAAAA8A9 , 0x0000BFFD // P0
+data8 0xC90FDAA22168C235 , 0x00004000 // pi
+LOCAL_OBJECT_END(atan2_tb1)
+
+LOCAL_OBJECT_START(atan2_tb2)
+data8 0xCE585A259BD8374C , 0x00003FF0 // P21
+data8 0x9F90FB984D8E39D0 , 0x0000BFF3 // P20
+data8 0x9D3436AABE218776 , 0x00003FF5 // P19
+data8 0xDEC343E068A6D2A8 , 0x0000BFF6 // P18
+data8 0xF396268151CFB11C , 0x00003FF7 // P17
+data8 0xD818B4BB43D84BF2 , 0x0000BFF8 // P16
+data8 0xA2270D30A90AA220 , 0x00003FF9 // P15
+data8 0xD5F4F2182E7A8725 , 0x0000BFF9 // P14
+data8 0x80D601879218B53A , 0x00003FFA // P13
+data8 0x9297B23CCFFB291F , 0x0000BFFA // P12
+data8 0xFE7E52D2A89995B3 , 0x0000BFEC // P22
+data8 0xC90FDAA22168C235 , 0x00003FFF // pi/2
+data8 0xC90FDAA22168C235 , 0x00003FFE // pi/4
+data8 0x96cbe3f9990e91a8 , 0x00004000 // 3pi/4
+LOCAL_OBJECT_END(atan2_tb2)
+
+
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(atan2)
+
+{ .mfi
+ alloc r32 = ar.pfs,1,5,4,0
+ frcpa.s1 atan2_u1_X,p6 = f1,atan2_X
+ nop.i 999
+}
+{ .mfi
+ addl EXP_AD_P1 = @ltoff(atan2_tb1), gp
+ fma.s1 atan2_two = f1,f1,f1
+ nop.i 999
+;;
+}
+
+{ .mfi
+ ld8 EXP_AD_P1 = [EXP_AD_P1]
+ frcpa.s1 atan2_u1_Y,p7 = f1,atan2_Y
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_xsq = atan2_X,atan2_X,f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fclass.m p10,p0 = atan2_Y, 0xc3 // Test for y=nan
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_ysq = atan2_Y,atan2_Y,f0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ add EXP_AD_P2 = 0xd0,EXP_AD_P1
+ fclass.m p12,p0 = atan2_X, 0xc3 // Test for x nan
+ nop.i 999
+}
+;;
+
+
+// p10 Y NAN, quiet and return
+{ .mfi
+ ldfe atan2_P11 = [EXP_AD_P1],16
+ fmerge.s atan2_sgnY = atan2_Y,f1
+ nop.i 999
+}
+{ .mfb
+ ldfe atan2_P21 = [EXP_AD_P2],16
+(p10) fma.d.s0 f8 = atan2_X,atan2_Y,f0 // If y=nan, result quietized y
+(p10) br.ret.spnt b0 // Exit if y=nan
+;;
+}
+
+
+{ .mfi
+ ldfe atan2_P10 = [EXP_AD_P1],16
+ fma.s1 atan2_z1_X = atan2_u1_X, atan2_Y, f0
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P20 = [EXP_AD_P2],16
+ fnma.s1 atan2_B1X = atan2_u1_X, atan2_X, atan2_two
+ nop.i 999
+;;
+}
+
+{ .mfi
+ ldfe atan2_P9 = [EXP_AD_P1],16
+ fma.s1 atan2_z1_Y = atan2_u1_Y, atan2_X, f0
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P19 = [EXP_AD_P2],16
+ fnma.s1 atan2_B1Y = atan2_u1_Y, atan2_Y, atan2_two
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe atan2_P8 = [EXP_AD_P1],16
+ fma.s1 atan2_z2_X = atan2_u1_X, atan2_ysq, f0
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P18 = [EXP_AD_P2],16
+ fma.s1 atan2_z2_Y = atan2_u1_Y, atan2_xsq, f0
+ nop.i 999
+}
+;;
+
+// p10 ==> x inf y ?
+// p11 ==> x !inf y ?
+{ .mfi
+ ldfe atan2_P7 = [EXP_AD_P1],16
+ fclass.m p10,p11 = atan2_X, 0x23 // test for x inf
+ nop.i 999
+}
+{ .mfb
+ ldfe atan2_P17 = [EXP_AD_P2],16
+(p12) fma.d.s0 f8 = atan2_X,atan2_Y,f0 // If x nan, result quiet x
+(p12) br.ret.spnt b0 // Exit for x nan
+;;
+}
+
+// p6 true if swap, means |y| > |x| or ysq > xsq
+// p7 true if no swap, means |x| >= |y| or xsq >= ysq
+{ .mmf
+ ldfe atan2_P6 = [EXP_AD_P1],16
+ ldfe atan2_P16 = [EXP_AD_P2],16
+ fcmp.ge.s1 p7,p6 = atan2_xsq, atan2_ysq
+;;
+}
+
+{ .mfi
+ ldfe atan2_P5 = [EXP_AD_P1],16
+ fma.s1 atan2_wp_X = atan2_z1_X, atan2_z1_X, f0
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P15 = [EXP_AD_P2],16
+ fma.s1 atan2_B1sq_X = atan2_B1X, atan2_B1X, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ ldfe atan2_P4 = [EXP_AD_P1],16
+(p6) fma.s1 atan2_wp_Y = atan2_z1_Y, atan2_z1_Y, f0
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P14 = [EXP_AD_P2],16
+(p6) fma.s1 atan2_B1sq_Y = atan2_B1Y, atan2_B1Y, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ ldfe atan2_P3 = [EXP_AD_P1],16
+(p6) fma.s1 atan2_E = atan2_z2_Y, atan2_B1Y, atan2_Y
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P13 = [EXP_AD_P2],16
+(p7) fma.s1 atan2_E = atan2_z2_X, atan2_B1X, atan2_X
+ nop.i 999
+;;
+}
+
+
+{ .mfi
+ ldfe atan2_P2 = [EXP_AD_P1],16
+(p6) fma.s1 atan2_z = atan2_z1_Y, atan2_B1Y, f0
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P12 = [EXP_AD_P2],16
+(p7) fma.s1 atan2_z = atan2_z1_X, atan2_B1X, f0
+ nop.i 999
+;;
+}
+
+
+{ .mfi
+ ldfe atan2_P1 = [EXP_AD_P1],16
+ fcmp.eq.s0 p14,p15=atan2_X,atan2_Y // Dummy for denorm and invalid
+ nop.i 999
+}
+{ .mlx
+ ldfe atan2_P22 = [EXP_AD_P2],16
+ movl rsig_near_one = 0x8000000000000001 // signif near 1.0
+;;
+}
+
+
+// p12 ==> x inf y inf
+// p13 ==> x inf y !inf
+{ .mmf
+ ldfe atan2_P0 = [EXP_AD_P1],16
+ ldfe atan2_pi_by_2 = [EXP_AD_P2],16
+(p10) fclass.m.unc p12,p13 = atan2_Y, 0x23 // x inf, test if y inf
+;;
+}
+
+{ .mfi
+ ldfe atan2_pi = [EXP_AD_P1],16
+(p6) fma.s1 atan2_w = atan2_wp_Y, atan2_B1sq_Y,f0
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_pi_by_4 = [EXP_AD_P2],16
+(p7) fma.s1 atan2_w = atan2_wp_X, atan2_B1sq_X,f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ ldfe atan2_3pi_by_4 = [EXP_AD_P2],16
+(p11) fclass.m.unc p9,p0 = atan2_Y, 0x23 // x not inf, test if y inf
+ nop.i 999
+;;
+}
+
+{ .mfi
+ setf.sig atan2_sig_near_one = rsig_near_one
+(p12) fcmp.gt.unc.s1 p10,p11 = atan2_X,f0 // x inf, y inf, test if x +inf
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p6) fnma.s1 atan2_gV = atan2_Y, atan2_z, atan2_X
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ frcpa.s1 atan2_F,p0 = f1, atan2_E
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fnma.s1 atan2_gV = atan2_X, atan2_z, atan2_Y
+ nop.i 999
+;;
+}
+
+// p13 ==> x inf y !inf
+{ .mfi
+ nop.m 999
+(p13) fcmp.gt.unc.s1 p14,p15 = atan2_X,f0 // x inf, y !inf, test if x +inf
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p9) fma.d.s0 f8 = atan2_sgnY, atan2_pi_by_2, f0 // +-pi/2 if x !inf, y inf
+(p9) br.ret.spnt b0 // exit if x not inf, y inf, result is +-pi/2
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V13 = atan2_w, atan2_P11, atan2_P10
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W11 = atan2_w, atan2_P21, atan2_P20
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V11 = atan2_w, atan2_P9, atan2_P8
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V12 = atan2_w, atan2_w, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V8 = atan2_w, atan2_P7 , atan2_P6
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W8 = atan2_w, atan2_P19, atan2_P18
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fnma.s1 atan2_alpha = atan2_E, atan2_F, f1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnma.s1 atan2_alpha_1 = atan2_E, atan2_F, atan2_two
+ nop.i 999
+;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V7 = atan2_w, atan2_P5 , atan2_P4
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W7 = atan2_w, atan2_P17, atan2_P16
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V4 = atan2_w, atan2_P3 , atan2_P2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W4 = atan2_w, atan2_P15, atan2_P14
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V3 = atan2_w, atan2_P1 , atan2_P0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W3 = atan2_w, atan2_P13, atan2_P12
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V10 = atan2_V12, atan2_V13, atan2_V11
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_gVF = atan2_gV, atan2_F, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_alpha_sq = atan2_alpha, atan2_alpha, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_Cp = atan2_alpha, atan2_alpha_1, f1
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V9 = atan2_V12, atan2_V12, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W10 = atan2_V12, atan2_P22 , atan2_W11
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V6 = atan2_V12, atan2_V8 , atan2_V7
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W6 = atan2_V12, atan2_W8 , atan2_W7
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V2 = atan2_V12, atan2_V4 , atan2_V3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W2 = atan2_V12, atan2_W4 , atan2_W3
+ nop.i 999
+;;
+}
+
+// p8 ==> y 0 x?
+// p9 ==> y !0 x?
+{ .mfi
+ nop.m 999
+ fclass.m p8,p9 = atan2_Y, 0x07 // Test for y=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_zcub = atan2_z, atan2_w, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_alpha_cub = atan2_alpha, atan2_alpha_sq, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_C = atan2_gVF, atan2_Cp, f0
+ nop.i 999
+;;
+}
+
+// p12 ==> y0 x0
+// p13 ==> y0 x!0
+{ .mfi
+ nop.m 999
+(p8) fclass.m.unc p12,p13 = atan2_X, 0x07 // y=0, test if x is 0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W12 = atan2_V9, atan2_V9, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V5 = atan2_V9, atan2_V10, atan2_V6
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W5 = atan2_V9, atan2_W10, atan2_W6
+ nop.i 999
+;;
+}
+
+
+// p9 ==> y!0 x0
+{ .mfi
+ nop.m 999
+(p9) fclass.m.unc p9,p0 = atan2_X, 0x07 // y not 0, test if x is 0
+ nop.i 999
+}
+// p10 ==> X +INF, Y +-INF
+{ .mfb
+ nop.m 999
+(p10) fma.d.s0 f8 = atan2_sgnY, atan2_pi_by_4, f0 // x=+inf, y=inf
+(p10) br.ret.spnt b0 // Exit for x=+inf, y=inf, result is +-pi/4
+;;
+}
+
+.pred.rel "mutex",p11,p14
+{ .mfi
+ nop.m 999
+(p14) fmerge.s f8 = atan2_sgnY, f0 // x=+inf, y !inf, result +-0
+ nop.i 999
+}
+// p11 ==> X -INF, Y +-INF
+{ .mfb
+ nop.m 999
+(p11) fma.d.s0 f8 = atan2_sgnY, atan2_3pi_by_4, f0 // x=-inf, y=inf
+(p11) br.ret.spnt b0 // Exit for x=-inf, y=inf, result is +-3pi/4
+;;
+}
+
+{ .mfi
+ nop.m 999
+(p13) fcmp.gt.unc.s1 p10,p11 = atan2_X,f0 // x not 0, y=0, test if x>0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fma.s1 atan2_d = atan2_alpha_cub, atan2_C, atan2_C
+(p14) br.ret.spnt b0 // Exit if x=+inf, y !inf, result +-0
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W12 = atan2_V9, atan2_W12, f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p9) fma.d.s0 f8 = atan2_sgnY, atan2_pi_by_2, f0 // x=0, y not 0
+(p9) br.ret.spnt b0 // Exit if x=0 and y not 0, result is +-pi/2
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V1 = atan2_V9, atan2_V5, atan2_V2
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fma.s1 atan2_W1 = atan2_V9, atan2_W5, atan2_W2
+(p12) br.spnt ATAN2_ERROR // Branch if x=0 and y=0
+;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) fmerge.s f8 = atan2_sgnY, f0 // +-0 if x>0, y=0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p11) fma.d.s0 f8 = atan2_sgnY, atan2_pi, f0 // +-pi if x<0, y=0
+(p13) br.ret.spnt b0 // Exit if x!0 and y=0
+;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_pd = atan2_P0, atan2_d, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_dsq = atan2_d, atan2_d, f0
+ nop.i 999
+;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fmerge.se atan2_near_one = f1, atan2_sig_near_one // Const ~1.0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_Pp = atan2_W12, atan2_W1, atan2_V1
+ nop.i 999
+;;
+}
+
+// p8 true if no swap and X positive
+// p9 true if no swap and X negative
+// both are false is swap is true
+{ .mfi
+ nop.m 999
+(p7) fcmp.ge.unc.s1 p8,p9 = atan2_X,f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p15) fma.d.s0 f8 = atan2_sgnY, atan2_pi, f0
+(p15) br.ret.spnt b0 // Exit if x=-inf, y !inf, result +-pi
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_sgn_pi_by_2 = atan2_pi_by_2, atan2_sgnY, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_A_lo = atan2_pd, atan2_dsq, atan2_d
+ nop.i 999
+;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_sgn_pi = atan2_pi, atan2_sgnY, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_A_hi = atan2_zcub, atan2_Pp, atan2_z
+ nop.i 999
+;;
+}
+
+
+// For |Y| <= |X| and X > 0, force inexact in case A_lo is zero
+{ .mfi
+ nop.m 999
+(p8) fmpy.s0 atan2_tmp = atan2_P22, atan2_P22
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_A = atan2_A_hi, f1, atan2_A_lo
+ nop.i 999
+}
+// For |Y| <= |X| and X > 0, result is A_hi + A_lo
+{ .mfi
+ nop.m 999
+(p8) fma.d.s0 f8 = atan2_A_hi, f1, atan2_A_lo
+ nop.i 999
+;;
+}
+
+.pred.rel "mutex",p6,p9
+// We perturb A by multiplying by 1.0+1ulp as we produce the result
+// in order to get symmetrically rounded results in directed rounding modes.
+// If we don't do this, there are a few cases where the trailing 11 bits of
+// the significand of the result, before converting to double, are zero. These
+// cases do not round symmetrically in round to +infinity or round to -infinity.
+// The perturbation also insures that the inexact flag is set.
+// For |Y| > |X|, result is +- pi/2 - (A_hi + A_lo)
+{ .mfi
+ nop.m 999
+(p6) fnma.d.s0 f8 = atan2_A, atan2_near_one, atan2_sgn_pi_by_2
+ nop.i 999
+}
+// For |Y| <= |X|, and X < 0, result is +- pi + (A_hi + A_lo)
+{ .mfb
+ nop.m 999
+(p9) fma.d.s0 f8 = atan2_A, atan2_near_one, atan2_sgn_pi
+ br.ret.sptk b0
+;;
+}
+
+ATAN2_ERROR:
+// Here if x=0 and y=0
+{ .mfi
+ nop.m 999
+ fclass.m p10,p11 = atan2_X,0x05 // Test if x=+0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ mov atan2_GR_tag = 37
+(p10) fmerge.s f10 = atan2_sgnY, f0 // x=+0, y=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fma.d.s0 f10 = atan2_sgnY, atan2_pi, f0 // x=-0, y=0
+ nop.i 999
+;;
+}
+GLOBAL_IEEE754_END(atan2)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 999
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+
+// (2)
+{ .mmi
+ stfd [GR_Parameter_Y] = f8,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfd [GR_Parameter_X] = f9 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = f10 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+// (4)
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_atan2f.S b/libc/sysdeps/ia64/fpu/e_atan2f.S
new file mode 100644
index 000000000..67618f043
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_atan2f.S
@@ -0,0 +1,900 @@
+.file "atan2f.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+
+// History
+//==============================================================
+// 06/01/00 Initial version
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 08/17/00 Changed predicate register macro-usage to direct predicate
+// names due to an assembler bug.
+// 01/05/01 Fixed flag settings for denormal input.
+// 01/19/01 Added documentation
+// 01/30/01 Improved speed
+// 02/06/02 Corrected .section statement
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+
+// Description
+//=========================================
+// The atan2 function computes the principle value of the arc tangent of y/x using
+// the signs of both arguments to determine the quadrant of the return value.
+// A domain error may occur if both arguments are zero.
+
+// The atan2 function returns the arc tangent of y/x in the range [-pi,+pi] radians.
+
+//..
+//..Let (v,u) = (y,x) if |y| <= |x|, and (v,u) = (x,y) otherwise. Note that
+//..v and u can be negative. We state the relationship between atan2(y,x) and
+//..atan(v/u).
+//..
+//..Let swap = false if v = y, and swap = true if v = x.
+//..Define C according to the matrix
+//..
+//.. TABLE FOR C
+//.. x +ve x -ve
+//.. no swap (swap = false) sgn(y)*0 sgn(y)*pi
+//.. swap (swap = true ) sgn(y)*pi/2 sgn(y)*pi/2
+//..
+//.. atan2(y,x) = C + atan(v/u) if no swap
+//.. atan2(y,x) = C - atan(v/u) if swap
+//..
+//..These relationship is more efficient to compute as we accommodate signs in v and u
+//..saving the need to obtain the absolute value before computation can proceed.
+//..
+//..Suppose (v,u) = (y,x), we calculate atan(v/u) as follows:
+//..A = y * frcpa(x) (so A = (y/x)(1 - beta))
+//..atan(y/x) = atan(A) + atan( ((y/x)-A))/(1 + (y/x)A) ), the second term is
+//..a correction.
+//..atan(A) is approximated by a polynomial
+//..A + p1 A^3 + p2 A^5 + ... + p10 A^21,
+//..atan(G) is approximated as follows:
+//..Let G = (y - Ax)/(x + Ay), atan(G) can be approximated by G + g * p1
+//..where g is a limited precision approximation to G via g = (y - Ax)*frcpa(x + Ay).
+//..
+//..Suppose (v,u) = (x,y), we calculate atan(v/u) as follows:
+//..Z = x * frcpa(y) (so Z = (x/y)(1 - beta))
+//..atan(x/y) = atan(Z) + atan( ((x/y)-Z))/(1 + (x/y)Z) ), the second term is
+//..a correction.
+//..atan(Z) is approximated by a polynomial
+//..Z + p1 Z^3 + p2 Z^5 + ... + p10 Z^21,
+//..atan(T) is approximated as follows:
+//..Let T = (x - Ay)/(y + Ax), atan(T) can be approximated by T + t * p1
+//..where t is a limited precision approximation to T via t = (x - Ay)*frcpa(y + Ax).
+//..
+//..
+//..A = y * frcpa(x)
+//..atan(A) ~=~ A + p1 A^3 + ... + P10 A^21
+//..
+//..This polynomial is computed as follows:
+//..Asq = A*A; Acub = A*Asq, A4 = Asq*Asq
+//..A5 = Asq*Acub, A6 = Asq*A4; A11 = A5 * A6
+//..
+//..poly_A1 = p9 + Asq*p10, poly_A2 = p7 + Asq*p8, poly_A3 = p5 + Asq*p6
+//..poly_A1 = poly_A2 + A4 * poly_A1
+//..poly_A1 = poly_A3 + A4 * poly_A1
+//..
+//..poly_A4 = p1 * A
+//,,poly_A5 = p3 + Asq * p4, poly_A4 = A + Asq*poly_A4
+//..poly_A5 = p2 + Asq * poly_A5
+//..poly_A4 = poly_A4 + A5 * poly_A5
+//..
+//..atan_A = poly_A4 + A11 * poly_A1
+//..
+//..atan(G) is approximated as follows:
+//..G_numer = y - A*x, G_denom = x + A*y
+//..H1 = frcpa(G_denom)
+//..H_beta = 1 - H1 * G_denom
+//..H2 = H1 + H1 * H_beta
+//..H_beta2 = H_beta*H_beta
+//..H3 = H2 + H2*H_beta2
+//..g = H1 * G_numer; gsq = g*g; atan_G = g*p1, atan_G = atan_G*gsq
+//..atan_G = G_numer*H3 + atan_G
+//..
+//..
+//..A = y * frcpa(x)
+//..atan(A) ~=~ A + p1 A^3 + ... + P10 A^21
+//..
+//..This polynomial is computed as follows:
+//..Asq = A*A; Acub = A*Asq, A4 = Asq*Asq
+//..A5 = Asq*Acub, A6 = Asq*A4; A11 = A5 * A6
+//..
+//..poly_A1 = p9 + Asq*p10, poly_A2 = p7 + Asq*p8, poly_A3 = p5 + Asq*p6
+//..poly_A1 = poly_A2 + A4 * poly_A1
+//..poly_A1 = poly_A3 + A4 * poly_A1
+//..
+//..poly_A4 = p1 * A
+//,,poly_A5 = p3 + Asq * p4, poly_A4 = A + Asq*poly_A4
+//..poly_A5 = p2 + Asq * poly_A5
+//..poly_A4 = poly_A4 + A5 * poly_A5
+//..
+//..atan_A = poly_A4 + A11 * poly_A1
+//..
+//..
+//..====================================================================
+//.. COEFFICIENTS USED IN THE COMPUTATION
+//..====================================================================
+
+//coef_pj, j = 1,2,...,10; atan(A) ~=~ A + p1 A^3 + p2 A^5 + ... + p10 A^21
+//
+// coef_p1 = -.3333332707155439167401311806315789E+00
+// coef_p1 in dbl = BFD5 5555 1219 1621
+//
+// coef_p2 = .1999967670926658391827857030875748E+00
+// coef_p2 in dbl = 3FC9 997E 7AFB FF4E
+//
+// coef_p3 = -.1427989384500152360161563301087296E+00
+// coef_p3 in dbl = BFC2 473C 5145 EE38
+//
+// coef_p4 = .1105852823460720770079031213661163E+00
+// coef_p4 in dbl = 3FBC 4F51 2B18 65F5
+//
+// coef_p5 = -.8811839915595312348625710228448363E-01
+// coef_p5 in dbl = BFB6 8EED 6A8C FA32
+//
+// coef_p6 = .6742329836955067042153645159059714E-01
+// coef_p6 in dbl = 3FB1 42A7 3D7C 54E3
+//
+// coef_p7 = -.4468571068774672908561591262231909E-01
+// coef_p7 in dbl = BFA6 E10B A401 393F
+//
+// coef_p8 = .2252333246746511135532726960586493E-01
+// coef_p8 in dbl = 3F97 105B 4160 F86B
+//
+// coef_p9 = -.7303884867007574742501716845542314E-02
+// coef_p9 in dbl = BF7D EAAD AA33 6451
+//
+// coef_p10 = .1109686868355312093949039454619058E-02
+// coef_p10 in dbl = 3F52 2E5D 33BC 9BAA
+//
+
+// Special values
+//==============================================================
+// Y x Result
+// +number +inf +0
+// -number +inf -0
+// +number -inf +pi
+// -number -inf -pi
+//
+// +inf +number +pi/2
+// -inf +number -pi/2
+// +inf -number +pi/2
+// -inf -number -pi/2
+//
+// +inf +inf +pi/4
+// -inf +inf -pi/4
+// +inf -inf +3pi/4
+// -inf -inf -3pi/4
+//
+// +1 +1 +pi/4
+// -1 +1 -pi/4
+// +1 -1 +3pi/4
+// -1 -1 -3pi/4
+//
+// +number +0 +pi/2 // does not raise DBZ
+// -number +0 -pi/2 // does not raise DBZ
+// +number -0 +pi/2 // does not raise DBZ
+// -number -0 -pi/2 // does not raise DBZ
+//
+// +0 +number +0
+// -0 +number -0
+// +0 -number +pi
+// -0 -number -pi
+//
+// +0 +0 +0 // does not raise invalid
+// -0 +0 -0 // does not raise invalid
+// +0 -0 +pi // does not raise invalid
+// -0 -0 -pi // does not raise invalid
+//
+// Nan anything quiet Y
+// anything NaN quiet X
+
+// atan2(+-0/+-0) sets double error tag to 37
+// atan2f(+-0/+-0) sets single error tag to 38
+// These are domain errors.
+
+
+//
+// Assembly macros
+//=========================================
+
+
+// integer registers
+atan2f_GR_Addr_1 = r33
+atan2f_GR_Addr_2 = r34
+GR_SAVE_B0 = r35
+
+GR_SAVE_PFS = r36
+GR_SAVE_GP = r37
+
+GR_Parameter_X = r38
+GR_Parameter_Y = r39
+GR_Parameter_RESULT = r40
+GR_Parameter_TAG = r41
+
+// floating point registers
+atan2f_coef_p1 = f32
+atan2f_coef_p10 = f33
+atan2f_coef_p7 = f34
+atan2f_coef_p6 = f35
+
+atan2f_coef_p3 = f36
+atan2f_coef_p2 = f37
+atan2f_coef_p9 = f38
+atan2f_coef_p8 = f39
+atan2f_coef_p5 = f40
+
+atan2f_coef_p4 = f41
+atan2f_const_piby2 = f42
+atan2f_const_pi = f43
+atan2f_const_piby4 = f44
+atan2f_const_3piby4 = f45
+
+atan2f_xsq = f46
+atan2f_ysq = f47
+atan2f_xy = f48
+atan2f_const_1 = f49
+atan2f_sgn_Y = f50
+
+atan2f_Z0 = f51
+atan2f_A0 = f52
+atan2f_Z = f53
+atan2f_A = f54
+atan2f_C = f55
+
+atan2f_U = f56
+atan2f_Usq = f57
+atan2f_U4 = f58
+atan2f_U6 = f59
+atan2f_U8 = f60
+
+atan2f_poly_u109 = f61
+atan2f_poly_u87 = f62
+atan2f_poly_u65 = f63
+atan2f_poly_u43 = f64
+atan2f_poly_u21 = f65
+
+atan2f_poly_u10to7 = f66
+atan2f_poly_u6to3 = f67
+atan2f_poly_u10to3 = f68
+atan2f_poly_u10to0 = f69
+atan2f_poly_u210 = f70
+
+atan2f_T_numer = f71
+atan2f_T_denom = f72
+atan2f_G_numer = f73
+atan2f_G_denom = f74
+atan2f_p1rnum = f75
+
+atan2f_R_denom = f76
+atan2f_R_numer = f77
+atan2f_pR = f78
+atan2f_pRC = f79
+atan2f_pQRC = f80
+
+atan2f_Q1 = f81
+atan2f_Q_beta = f82
+atan2f_Q2 = f83
+atan2f_Q_beta2 = f84
+atan2f_Q3 = f85
+
+atan2f_r = f86
+atan2f_rsq = f87
+atan2f_poly_atan_U = f88
+
+
+// predicate registers
+//atan2f_Pred_Swap = p6 // |y| > |x|
+//atan2f_Pred_noSwap = p7 // |y| <= |x|
+//atan2f_Pred_Xpos = p8 // x >= 0
+//atan2f_Pred_Xneg = p9 // x < 0
+
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(atan2f_coef_table1)
+data8 0xBFD5555512191621 // p1
+data8 0x3F522E5D33BC9BAA // p10
+data8 0xBFA6E10BA401393F // p7
+data8 0x3FB142A73D7C54E3 // p6
+data8 0xBFC2473C5145EE38 // p3
+data8 0x3FC9997E7AFBFF4E // p2
+LOCAL_OBJECT_END(atan2f_coef_table1)
+
+LOCAL_OBJECT_START(atan2f_coef_table2)
+data8 0xBF7DEAADAA336451 // p9
+data8 0x3F97105B4160F86B // p8
+data8 0xBFB68EED6A8CFA32 // p5
+data8 0x3FBC4F512B1865F5 // p4
+data8 0x3ff921fb54442d18 // pi/2
+data8 0x400921fb54442d18 // pi
+data8 0x3fe921fb54442d18 // pi/4
+data8 0x4002d97c7f3321d2 // 3pi/4
+LOCAL_OBJECT_END(atan2f_coef_table2)
+
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(atan2f)
+
+{ .mfi
+ alloc r32 = ar.pfs,1,5,4,0
+ frcpa.s1 atan2f_Z0,p0 = f1,f8 // Approx to 1/y
+ nop.i 999
+}
+{ .mfi
+ addl atan2f_GR_Addr_1 = @ltoff(atan2f_coef_table1),gp
+ fma.s1 atan2f_xsq = f9,f9,f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ ld8 atan2f_GR_Addr_1 = [atan2f_GR_Addr_1]
+ frcpa.s1 atan2f_A0,p0 = f1,f9 // Approx to 1/x
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_ysq = f8,f8,f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fcmp.ge.s1 p8,p9 = f9,f0 // Set p8 if x>=0, p9 if x<0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_xy = f9,f8,f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ add atan2f_GR_Addr_2 = 0x30, atan2f_GR_Addr_1
+ fmerge.s atan2f_sgn_Y = f8,f1
+ nop.i 999 ;;
+}
+
+{ .mmf
+ ldfpd atan2f_coef_p1,atan2f_coef_p10 = [atan2f_GR_Addr_1],16
+ ldfpd atan2f_coef_p9,atan2f_coef_p8 = [atan2f_GR_Addr_2],16
+ fclass.m p10,p0 = f9,0xe7 // Test x @inf|@snan|@qnan|@zero
+}
+;;
+
+{ .mfi
+ ldfpd atan2f_coef_p7,atan2f_coef_p6 = [atan2f_GR_Addr_1],16
+ fma.s1 atan2f_T_denom = atan2f_Z0,atan2f_xsq,f8
+ nop.i 999
+}
+{ .mfi
+ ldfpd atan2f_coef_p5,atan2f_coef_p4 = [atan2f_GR_Addr_2],16
+ fma.s1 atan2f_Z = atan2f_Z0,f9,f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ ldfpd atan2f_coef_p3,atan2f_coef_p2 = [atan2f_GR_Addr_1],16
+ fma.s1 atan2f_G_denom = atan2f_A0,atan2f_ysq,f9
+ nop.i 999
+}
+{ .mfi
+ ldfpd atan2f_const_piby2,atan2f_const_pi = [atan2f_GR_Addr_2],16
+ fma.s1 atan2f_A = atan2f_A0,f8,f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ ldfpd atan2f_const_piby4,atan2f_const_3piby4 = [atan2f_GR_Addr_2]
+ fclass.m p11,p0 = f8,0xe7 // Test y @inf|@snan|@qnan|@zero
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fnma.s1 atan2f_T_numer = atan2f_Z0,atan2f_xy,f9
+(p10) br.cond.spnt ATAN2F_XY_INF_NAN_ZERO ;; // Branch on x nan,inf,zero
+}
+
+
+// p6 if |y|>|x|, p7 if |x|>=|y| , use xsq and ysq for test
+{ .mfi
+ nop.m 999
+ fcmp.gt.s1 p6,p7 = atan2f_ysq,atan2f_xsq
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fnma.s1 atan2f_G_numer = atan2f_A0,atan2f_xy,f8
+(p11) br.cond.spnt ATAN2F_XY_INF_NAN_ZERO ;; // Branch on y nan,inf,zero
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 atan2f_const_1 = atan2f_sgn_Y,f0,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 atan2f_const_1 = atan2f_sgn_Y,f1,f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p6) fnma.s1 atan2f_U = atan2f_Z,f1,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p6) fma.s1 atan2f_Usq = atan2f_Z,atan2f_Z,f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p7) fma.s1 atan2f_U = atan2f_A,f1,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fma.s1 atan2f_Usq = atan2f_A,atan2f_A,f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p6) frcpa.s1 atan2f_Q1,p0 = f1,atan2f_T_denom
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p6) fma.s1 atan2f_R_denom = atan2f_T_denom,f1,f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p7) frcpa.s1 atan2f_Q1,p0 = f1,atan2f_G_denom
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fma.s1 atan2f_R_denom = atan2f_G_denom,f1,f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p6) fnma.s1 atan2f_R_numer = atan2f_T_numer,f1,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fma.s1 atan2f_R_numer = atan2f_G_numer,f1,f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p6) fnma.s1 atan2f_p1rnum = atan2f_T_numer,atan2f_coef_p1,f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p7) fma.s1 atan2f_p1rnum = atan2f_G_numer,atan2f_coef_p1,f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_U4 = atan2f_Usq,atan2f_Usq,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_poly_u109 = atan2f_Usq,atan2f_coef_p10,atan2f_coef_p9
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_poly_u87 = atan2f_Usq,atan2f_coef_p8,atan2f_coef_p7
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_poly_u65 = atan2f_Usq,atan2f_coef_p6,atan2f_coef_p5
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_poly_u43 = atan2f_Usq,atan2f_coef_p4,atan2f_coef_p3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnma.s1 atan2f_Q_beta = atan2f_Q1,atan2f_R_denom,f1
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_poly_u21 = atan2f_Usq,atan2f_coef_p2,atan2f_coef_p1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_r = atan2f_Q1,atan2f_R_numer,f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p6) fma.s1 atan2f_C = atan2f_sgn_Y,atan2f_const_piby2,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fma.s1 atan2f_C = atan2f_const_1,atan2f_const_pi,f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_U6 = atan2f_U4,atan2f_Usq,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_U8 = atan2f_U4,atan2f_U4,f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_poly_u10to7 = atan2f_U4,atan2f_poly_u109,atan2f_poly_u87
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_pR = atan2f_p1rnum,atan2f_Q1,f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_poly_u6to3 = atan2f_U4,atan2f_poly_u65,atan2f_poly_u43
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_Q2 = atan2f_Q1,atan2f_Q_beta,atan2f_Q1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_Q_beta2 = atan2f_Q_beta,atan2f_Q_beta,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_rsq = atan2f_r,atan2f_r,f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_poly_u210 = atan2f_Usq,atan2f_poly_u21,f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p8,p0 = f8,f9 // Dummy op to set flag on denormal inputs
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_poly_u10to3 = atan2f_U8,atan2f_poly_u10to7,atan2f_poly_u6to3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_Q3 = atan2f_Q2,atan2f_Q_beta2,atan2f_Q2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_pRC = atan2f_rsq,atan2f_pR,atan2f_C
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_poly_u10to0 = atan2f_U6,atan2f_poly_u10to3,atan2f_poly_u210
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2f_pQRC = atan2f_R_numer,atan2f_Q3,atan2f_pRC
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fma.s.s0 f8 = atan2f_U,atan2f_poly_u10to0,atan2f_pQRC
+ br.ret.sptk b0 ;;
+}
+
+
+
+ATAN2F_XY_INF_NAN_ZERO:
+
+{ .mfi
+ nop.m 999
+ fclass.m p10,p0 = f8,0xc3 // Is y nan
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p12,p0 = f9,0xc3 // Is x nan
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p6,p0 = f9,0x21 // Is x +inf
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p10) fma.s.s0 f8 = f9,f8,f0 // Result quietized y if y is nan
+(p10) br.ret.spnt b0 // Exit if y is nan
+}
+;;
+
+
+{ .mfi
+ nop.m 999
+(p6) fclass.m.unc p7,p8 = f8,0x23 // x +inf, is y inf
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p12) fnorm.s.s0 f8 = f9 // Result quietized x if x is nan, y not nan
+(p12) br.ret.spnt b0 // Exit if x is nan, y not nan
+}
+;;
+
+// Here if x or y inf, or x or y zero
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p15,p0 = f8,f9 // Dummy op to set flag on denormal inputs
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p11,p12 = f9,0x22 // Is x -inf
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p7) fma.s.s0 f8 = atan2f_sgn_Y, atan2f_const_piby4,f0 // Result +-pi/4
+(p7) br.ret.spnt b0 // Exit if x +inf and y inf
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p8) fmerge.s f8 = f8,f0 // If x +inf and y not inf, result +-0
+(p8) br.ret.spnt b0 // Exit if x +inf and y not inf
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p12) fclass.m.unc p13,p0 = f8,0x23 // x not -inf, is y inf
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p11) fclass.m.unc p14,p15 = f8,0x23 // x -inf, is y inf
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p6,p7 = f9,0x7 // Is x zero
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p13) fma.s.s0 f8 = atan2f_sgn_Y, atan2f_const_piby2,f0 // Result +-pi/2
+(p13) br.ret.spnt b0 // Exit if x not -inf and y inf
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p14) fma.s.s0 f8 = atan2f_sgn_Y, atan2f_const_3piby4,f0 // Result +-3pi/4
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p15) fma.s.s0 f8 = atan2f_sgn_Y, atan2f_const_pi,f0 // Result +-pi
+(p11) br.ret.spnt b0 // Exit if x -inf
+}
+;;
+
+// Here if x or y zero
+{ .mfi
+ nop.m 999
+(p7) fclass.m.unc p8,p9 = f9,0x19 // x not zero, y zero, is x > zero
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fclass.m.unc p10,p11 = f8,0x7 // x zero, is y zero
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fmerge.s f8 = f8, f0 // x > zero and y zero, result is +-zero
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p9) fma.s.s0 f8 = atan2f_sgn_Y, atan2f_const_pi,f0 // x < 0, y 0, result +-pi
+(p10) br.cond.spnt __libm_error_region // Branch if x zero and y zero
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p11) fma.s.s0 f8 = atan2f_sgn_Y, atan2f_const_piby2,f0 // x zero, y not zero
+ br.ret.sptk b0 // Final special case exit
+}
+;;
+
+
+GLOBAL_IEEE754_END(atan2f)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+ mov GR_Parameter_TAG = 38
+ fclass.m p10,p11 = f9,0x5 // @zero | @pos
+;;
+(p10) fmerge.s f10 = f8, f0
+(p11) fma.s.s0 f10 = atan2f_sgn_Y, atan2f_const_pi,f0
+;;
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 999
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+}
+;;
+
+{ .mmi
+ stfs [GR_Parameter_Y] = f9,16 // Store Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+}
+;;
+
+
+.body
+{ .mib
+ stfs [GR_Parameter_X] = f8 // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfs [GR_Parameter_Y] = f10 // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+}
+;;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+}
+;;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+}
+;;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_atan2l.c b/libc/sysdeps/ia64/fpu/e_atan2l.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_atan2l.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/e_atanh.S b/libc/sysdeps/ia64/fpu/e_atanh.S
new file mode 100644
index 000000000..4ae5ee692
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_atanh.S
@@ -0,0 +1,1071 @@
+.file "atanh.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// ==============================================================
+// History
+// ==============================================================
+// 05/03/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 05/26/03 Improved performance, fixed to handle unorms
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+// ==============================================================
+// double atanh(double)
+//
+// Overview of operation
+// ==============================================================
+//
+// There are 7 paths:
+// 1. x = +/-0.0
+// Return atanh(x) = +/-0.0
+//
+// 2. 0.0 < |x| < 1/4
+// Return atanh(x) = Po2l(x),
+// where Po2l(x) = (((((((((C9*x^2 + C8)*x^2 + C7)*x^2 + C6)*x^2 +
+// C5)*x^2 + C4)*x^2 + C3)*x^2 + C2)*x^2 + C1)* x^2 + C0)*x^3 + x
+// 3. 1/4 <= |x| < 1
+// Return atanh(x) = sign(x) * log((1 + |x|)/(1 - |x|))
+// To compute (1 + |x|)/(1 - |x|) modified Newton Raphson method is used
+// (3 iterations)
+// Algorithm description for log function see below.
+//
+// 4. |x| = 1
+// Return atanh(x) = sign(x) * +INF
+//
+// 5. 1 < |x| <= +INF
+// Return atanh(x) = QNaN
+//
+// 6. x = [S,Q]NaN
+// Return atanh(x) = QNaN
+//
+// 7. x = denormal
+// Return atanh(x) = x
+//
+//==============================================================
+// Algorithm Description for log(x) function
+// Below we are using the fact that inequality x - 1.0 > 2^(-6) is always true
+// for this atanh implementation
+//
+// Consider x = 2^N 1.f1 f2 f3 f4...f63
+// Log(x) = log(x * frcpa(x) / frcpa(x))
+// = log(x * frcpa(x)) + log(1/frcpa(x))
+// = log(x * frcpa(x)) - log(frcpa(x))
+//
+// frcpa(x) = 2^-N * frcpa(1.f1 f2 ... f63)
+//
+// -log(frcpa(x)) = -log(C)
+// = -log(2^-N) - log(frcpa(1.f1 f2 ... f63))
+//
+// -log(frcpa(x)) = -log(C)
+// = N*log2 - log(frcpa(1.f1 f2 ... f63))
+//
+//
+// Log(x) = log(1/frcpa(x)) + log(frcpa(x) x)
+//
+// Log(x) = N*log2 + log(1./frcpa(1.f1 f2 ... f63)) + log(x * frcpa(x))
+// Log(x) = N*log2 + T + log(frcpa(x) x)
+//
+// Log(x) = N*log2 + T + log(C * x)
+//
+// C * x = 1 + r
+//
+// Log(x) = N*log2 + T + log(1 + r)
+// Log(x) = N*log2 + T + Series(r - r^2/2 + r^3/3 - r^4/4 + ...)
+//
+// 1.f1 f2 ... f8 has 256 entries.
+// They are 1 + k/2^8, k = 0 ... 255
+// These 256 values are the table entries.
+//
+// Implementation
+//==============================================================
+// C = frcpa(x)
+// r = C * x - 1
+//
+// Form rseries = r + P1*r^2 + P2*r^3 + P3*r^4 + P4*r^5 + P5*r^6
+//
+// x = f * 2*N where f is 1.f_1f_2f_3...f_63
+// Nfloat = float(n) where n is the true unbiased exponent
+// pre-index = f_1f_2....f_8
+// index = pre_index * 16
+// get the dxt table entry at index + offset = T
+//
+// result = (T + Nfloat * log(2)) + rseries
+//
+// The T table is calculated as follows
+// Form x_k = 1 + k/2^8 where k goes from 0... 255
+// y_k = frcpa(x_k)
+// log(1/y_k) in quad and round to double-extended
+//
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f32 -> f77
+
+// General registers used:
+// r14 -> r27, r33 -> r39
+
+// Predicate registers used:
+// p6 -> p14
+
+// p10, p11 to indicate is argument positive or negative
+// p12 to filter out case when x = [Q,S]NaN or +/-0
+// p13 to filter out case when x = denormal
+// p6, p7 to filter out case when |x| >= 1
+// p8 to filter out case when |x| < 1/4
+
+// Assembly macros
+//==============================================================
+Data2Ptr = r14
+Data3Ptr = r15
+RcpTablePtr = r16
+rExpbMask = r17
+rBias = r18
+rNearZeroBound = r19
+rArgSExpb = r20
+rArgExpb = r21
+rSExpb = r22
+rExpb = r23
+rSig = r24
+rN = r25
+rInd = r26
+DataPtr = r27
+
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_SAVE_PFS = r35
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+atanh_GR_tag = r39
+
+//==============================================================
+fAbsX = f32
+fOneMx = f33
+fOnePx = f34
+fY = f35
+fR = f36
+fR2 = f37
+fR3 = f38
+fRcp = f39
+fY4Rcp = f40
+fRcp0 = f41
+fRcp0n = f42
+fRcp1 = f43
+fRcp2 = f44
+fRcp3 = f45
+fN4Cvt = f46
+fN = f47
+fY2 = f48
+fLog2 = f49
+fLogT = f50
+fLogT_N = f51
+fX2 = f52
+fX3 = f53
+fX4 = f54
+fX8 = f55
+fP0 = f56
+fP5 = f57
+fP4 = f58
+fP3 = f59
+fP2 = f60
+fP1 = f61
+fNormX = f62
+fC9 = f63
+fC8 = f64
+fC7 = f65
+fC6 = f66
+fC5 = f67
+fC4 = f68
+fC3 = f69
+fC2 = f70
+fC1 = f71
+fC0 = f72
+fP98 = f73
+fP76 = f74
+fP54 = f75
+fP32 = f76
+fP10 = f77
+
+// Data tables
+//==============================================================
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(atanh_data)
+data8 0xBFC5555DA7212371 // P5
+data8 0x3FC999A19EEF5826 // P4
+data8 0xBFCFFFFFFFFEF009 // P3
+data8 0x3FD555555554ECB2 // P2
+data8 0xBFE0000000000000 // P1 = -0.5
+data8 0x0000000000000000 // pad
+data8 0xb17217f7d1cf79ac , 0x00003ffd // 0.5*log(2)
+data8 0x0000000000000000 , 0x00000000 // pad to eliminate bank conflicts
+LOCAL_OBJECT_END(atanh_data)
+
+LOCAL_OBJECT_START(atanh_data_2)
+data8 0x8649FB89D3AD51FB , 0x00003FFB // C9
+data8 0xCC10AABEF160077A , 0x00003FFA // C8
+data8 0xF1EDB99AC0819CE2 , 0x00003FFA // C7
+data8 0x8881E53A809AD24D , 0x00003FFB // C6
+data8 0x9D8A116EF212F271 , 0x00003FFB // C5
+data8 0xBA2E8A6D1D756453 , 0x00003FFB // C4
+data8 0xE38E38E7A0945692 , 0x00003FFB // C3
+data8 0x924924924536891A , 0x00003FFC // C2
+data8 0xCCCCCCCCCCD08D51 , 0x00003FFC // C1
+data8 0xAAAAAAAAAAAAAA0C , 0x00003FFD // C0
+LOCAL_OBJECT_END(atanh_data_2)
+
+
+LOCAL_OBJECT_START(atanh_data_3)
+data8 0x80200aaeac44ef38 , 0x00003ff5 // log(1/frcpa(1+0/2^-8))/2
+//
+data8 0xc09090a2c35aa070 , 0x00003ff6 // log(1/frcpa(1+1/2^-8))/2
+data8 0xa0c94fcb41977c75 , 0x00003ff7 // log(1/frcpa(1+2/2^-8))/2
+data8 0xe18b9c263af83301 , 0x00003ff7 // log(1/frcpa(1+3/2^-8))/2
+data8 0x8d35c8d6399c30ea , 0x00003ff8 // log(1/frcpa(1+4/2^-8))/2
+data8 0xadd4d2ecd601cbb8 , 0x00003ff8 // log(1/frcpa(1+5/2^-8))/2
+//
+data8 0xce95403a192f9f01 , 0x00003ff8 // log(1/frcpa(1+6/2^-8))/2
+data8 0xeb59392cbcc01096 , 0x00003ff8 // log(1/frcpa(1+7/2^-8))/2
+data8 0x862c7d0cefd54c5d , 0x00003ff9 // log(1/frcpa(1+8/2^-8))/2
+data8 0x94aa63c65e70d499 , 0x00003ff9 // log(1/frcpa(1+9/2^-8))/2
+data8 0xa54a696d4b62b382 , 0x00003ff9 // log(1/frcpa(1+10/2^-8))/2
+//
+data8 0xb3e4a796a5dac208 , 0x00003ff9 // log(1/frcpa(1+11/2^-8))/2
+data8 0xc28c45b1878340a9 , 0x00003ff9 // log(1/frcpa(1+12/2^-8))/2
+data8 0xd35c55f39d7a6235 , 0x00003ff9 // log(1/frcpa(1+13/2^-8))/2
+data8 0xe220f037b954f1f5 , 0x00003ff9 // log(1/frcpa(1+14/2^-8))/2
+data8 0xf0f3389b036834f3 , 0x00003ff9 // log(1/frcpa(1+15/2^-8))/2
+//
+data8 0xffd3488d5c980465 , 0x00003ff9 // log(1/frcpa(1+16/2^-8))/2
+data8 0x87609ce2ed300490 , 0x00003ffa // log(1/frcpa(1+17/2^-8))/2
+data8 0x8ede9321e8c85927 , 0x00003ffa // log(1/frcpa(1+18/2^-8))/2
+data8 0x96639427f2f8e2f4 , 0x00003ffa // log(1/frcpa(1+19/2^-8))/2
+data8 0x9defad3e8f73217b , 0x00003ffa // log(1/frcpa(1+20/2^-8))/2
+//
+data8 0xa582ebd50097029c , 0x00003ffa // log(1/frcpa(1+21/2^-8))/2
+data8 0xac06dbe75ab80fee , 0x00003ffa // log(1/frcpa(1+22/2^-8))/2
+data8 0xb3a78449b2d3ccca , 0x00003ffa // log(1/frcpa(1+23/2^-8))/2
+data8 0xbb4f79635ab46bb2 , 0x00003ffa // log(1/frcpa(1+24/2^-8))/2
+data8 0xc2fec93a83523f3f , 0x00003ffa // log(1/frcpa(1+25/2^-8))/2
+//
+data8 0xc99af2eaca4c4571 , 0x00003ffa // log(1/frcpa(1+26/2^-8))/2
+data8 0xd1581106472fa653 , 0x00003ffa // log(1/frcpa(1+27/2^-8))/2
+data8 0xd8002560d4355f2e , 0x00003ffa // log(1/frcpa(1+28/2^-8))/2
+data8 0xdfcb43b4fe508632 , 0x00003ffa // log(1/frcpa(1+29/2^-8))/2
+data8 0xe67f6dff709d4119 , 0x00003ffa // log(1/frcpa(1+30/2^-8))/2
+//
+data8 0xed393b1c22351280 , 0x00003ffa // log(1/frcpa(1+31/2^-8))/2
+data8 0xf5192bff087bcc35 , 0x00003ffa // log(1/frcpa(1+32/2^-8))/2
+data8 0xfbdf4ff6dfef2fa3 , 0x00003ffa // log(1/frcpa(1+33/2^-8))/2
+data8 0x81559a97f92f9cc7 , 0x00003ffb // log(1/frcpa(1+34/2^-8))/2
+data8 0x84be72bce90266e8 , 0x00003ffb // log(1/frcpa(1+35/2^-8))/2
+//
+data8 0x88bc74113f23def2 , 0x00003ffb // log(1/frcpa(1+36/2^-8))/2
+data8 0x8c2ba3edf6799d11 , 0x00003ffb // log(1/frcpa(1+37/2^-8))/2
+data8 0x8f9dc92f92ea08b1 , 0x00003ffb // log(1/frcpa(1+38/2^-8))/2
+data8 0x9312e8f36efab5a7 , 0x00003ffb // log(1/frcpa(1+39/2^-8))/2
+data8 0x968b08643409ceb6 , 0x00003ffb // log(1/frcpa(1+40/2^-8))/2
+//
+data8 0x9a062cba08a1708c , 0x00003ffb // log(1/frcpa(1+41/2^-8))/2
+data8 0x9d845b3abf95485c , 0x00003ffb // log(1/frcpa(1+42/2^-8))/2
+data8 0xa06fd841bc001bb4 , 0x00003ffb // log(1/frcpa(1+43/2^-8))/2
+data8 0xa3f3a74652fbe0db , 0x00003ffb // log(1/frcpa(1+44/2^-8))/2
+data8 0xa77a8fb2336f20f5 , 0x00003ffb // log(1/frcpa(1+45/2^-8))/2
+//
+data8 0xab0497015d28b0a0 , 0x00003ffb // log(1/frcpa(1+46/2^-8))/2
+data8 0xae91c2be6ba6a615 , 0x00003ffb // log(1/frcpa(1+47/2^-8))/2
+data8 0xb189d1b99aebb20b , 0x00003ffb // log(1/frcpa(1+48/2^-8))/2
+data8 0xb51cced5de9c1b2c , 0x00003ffb // log(1/frcpa(1+49/2^-8))/2
+data8 0xb819bee9e720d42f , 0x00003ffb // log(1/frcpa(1+50/2^-8))/2
+//
+data8 0xbbb2a0947b093a5d , 0x00003ffb // log(1/frcpa(1+51/2^-8))/2
+data8 0xbf4ec1505811684a , 0x00003ffb // log(1/frcpa(1+52/2^-8))/2
+data8 0xc2535bacfa8975ff , 0x00003ffb // log(1/frcpa(1+53/2^-8))/2
+data8 0xc55a3eafad187eb8 , 0x00003ffb // log(1/frcpa(1+54/2^-8))/2
+data8 0xc8ff2484b2c0da74 , 0x00003ffb // log(1/frcpa(1+55/2^-8))/2
+//
+data8 0xcc0b1a008d53ab76 , 0x00003ffb // log(1/frcpa(1+56/2^-8))/2
+data8 0xcfb6203844b3209b , 0x00003ffb // log(1/frcpa(1+57/2^-8))/2
+data8 0xd2c73949a47a19f5 , 0x00003ffb // log(1/frcpa(1+58/2^-8))/2
+data8 0xd5daae18b49d6695 , 0x00003ffb // log(1/frcpa(1+59/2^-8))/2
+data8 0xd8f08248cf7e8019 , 0x00003ffb // log(1/frcpa(1+60/2^-8))/2
+//
+data8 0xdca7749f1b3e540e , 0x00003ffb // log(1/frcpa(1+61/2^-8))/2
+data8 0xdfc28e033aaaf7c7 , 0x00003ffb // log(1/frcpa(1+62/2^-8))/2
+data8 0xe2e012a5f91d2f55 , 0x00003ffb // log(1/frcpa(1+63/2^-8))/2
+data8 0xe600064ed9e292a8 , 0x00003ffb // log(1/frcpa(1+64/2^-8))/2
+data8 0xe9226cce42b39f60 , 0x00003ffb // log(1/frcpa(1+65/2^-8))/2
+//
+data8 0xec4749fd97a28360 , 0x00003ffb // log(1/frcpa(1+66/2^-8))/2
+data8 0xef6ea1bf57780495 , 0x00003ffb // log(1/frcpa(1+67/2^-8))/2
+data8 0xf29877ff38809091 , 0x00003ffb // log(1/frcpa(1+68/2^-8))/2
+data8 0xf5c4d0b245cb89be , 0x00003ffb // log(1/frcpa(1+69/2^-8))/2
+data8 0xf8f3afd6fcdef3aa , 0x00003ffb // log(1/frcpa(1+70/2^-8))/2
+//
+data8 0xfc2519756be1abc7 , 0x00003ffb // log(1/frcpa(1+71/2^-8))/2
+data8 0xff59119f503e6832 , 0x00003ffb // log(1/frcpa(1+72/2^-8))/2
+data8 0x8147ce381ae0e146 , 0x00003ffc // log(1/frcpa(1+73/2^-8))/2
+data8 0x82e45f06cb1ad0f2 , 0x00003ffc // log(1/frcpa(1+74/2^-8))/2
+data8 0x842f5c7c573cbaa2 , 0x00003ffc // log(1/frcpa(1+75/2^-8))/2
+//
+data8 0x85ce471968c8893a , 0x00003ffc // log(1/frcpa(1+76/2^-8))/2
+data8 0x876e8305bc04066d , 0x00003ffc // log(1/frcpa(1+77/2^-8))/2
+data8 0x891012678031fbb3 , 0x00003ffc // log(1/frcpa(1+78/2^-8))/2
+data8 0x8a5f1493d766a05f , 0x00003ffc // log(1/frcpa(1+79/2^-8))/2
+data8 0x8c030c778c56fa00 , 0x00003ffc // log(1/frcpa(1+80/2^-8))/2
+//
+data8 0x8da85df17e31d9ae , 0x00003ffc // log(1/frcpa(1+81/2^-8))/2
+data8 0x8efa663e7921687e , 0x00003ffc // log(1/frcpa(1+82/2^-8))/2
+data8 0x90a22b6875c6a1f8 , 0x00003ffc // log(1/frcpa(1+83/2^-8))/2
+data8 0x91f62cc8f5d24837 , 0x00003ffc // log(1/frcpa(1+84/2^-8))/2
+data8 0x93a06cfc3857d980 , 0x00003ffc // log(1/frcpa(1+85/2^-8))/2
+//
+data8 0x94f66d5e6fd01ced , 0x00003ffc // log(1/frcpa(1+86/2^-8))/2
+data8 0x96a330156e6772f2 , 0x00003ffc // log(1/frcpa(1+87/2^-8))/2
+data8 0x97fb3582754ea25b , 0x00003ffc // log(1/frcpa(1+88/2^-8))/2
+data8 0x99aa8259aad1bbf2 , 0x00003ffc // log(1/frcpa(1+89/2^-8))/2
+data8 0x9b0492f6227ae4a8 , 0x00003ffc // log(1/frcpa(1+90/2^-8))/2
+//
+data8 0x9c5f8e199bf3a7a5 , 0x00003ffc // log(1/frcpa(1+91/2^-8))/2
+data8 0x9e1293b9998c1daa , 0x00003ffc // log(1/frcpa(1+92/2^-8))/2
+data8 0x9f6fa31e0b41f308 , 0x00003ffc // log(1/frcpa(1+93/2^-8))/2
+data8 0xa0cda11eaf46390e , 0x00003ffc // log(1/frcpa(1+94/2^-8))/2
+data8 0xa22c8f029cfa45aa , 0x00003ffc // log(1/frcpa(1+95/2^-8))/2
+//
+data8 0xa3e48badb7856b34 , 0x00003ffc // log(1/frcpa(1+96/2^-8))/2
+data8 0xa5459a0aa95849f9 , 0x00003ffc // log(1/frcpa(1+97/2^-8))/2
+data8 0xa6a79c84480cfebd , 0x00003ffc // log(1/frcpa(1+98/2^-8))/2
+data8 0xa80a946d0fcb3eb2 , 0x00003ffc // log(1/frcpa(1+99/2^-8))/2
+data8 0xa96e831a3ea7b314 , 0x00003ffc // log(1/frcpa(1+100/2^-8))/2
+//
+data8 0xaad369e3dc544e3b , 0x00003ffc // log(1/frcpa(1+101/2^-8))/2
+data8 0xac92e9588952c815 , 0x00003ffc // log(1/frcpa(1+102/2^-8))/2
+data8 0xadfa035aa1ed8fdc , 0x00003ffc // log(1/frcpa(1+103/2^-8))/2
+data8 0xaf6219eae1ad6e34 , 0x00003ffc // log(1/frcpa(1+104/2^-8))/2
+data8 0xb0cb2e6d8160f753 , 0x00003ffc // log(1/frcpa(1+105/2^-8))/2
+//
+data8 0xb2354249ad950f72 , 0x00003ffc // log(1/frcpa(1+106/2^-8))/2
+data8 0xb3a056e98ef4a3b4 , 0x00003ffc // log(1/frcpa(1+107/2^-8))/2
+data8 0xb50c6dba52c6292a , 0x00003ffc // log(1/frcpa(1+108/2^-8))/2
+data8 0xb679882c33876165 , 0x00003ffc // log(1/frcpa(1+109/2^-8))/2
+data8 0xb78c07429785cedc , 0x00003ffc // log(1/frcpa(1+110/2^-8))/2
+//
+data8 0xb8faeb8dc4a77d24 , 0x00003ffc // log(1/frcpa(1+111/2^-8))/2
+data8 0xba6ad77eb36ae0d6 , 0x00003ffc // log(1/frcpa(1+112/2^-8))/2
+data8 0xbbdbcc915e9bee50 , 0x00003ffc // log(1/frcpa(1+113/2^-8))/2
+data8 0xbd4dcc44f8cf12ef , 0x00003ffc // log(1/frcpa(1+114/2^-8))/2
+data8 0xbec0d81bf5b531fa , 0x00003ffc // log(1/frcpa(1+115/2^-8))/2
+//
+data8 0xc034f19c139186f4 , 0x00003ffc // log(1/frcpa(1+116/2^-8))/2
+data8 0xc14cb69f7c5e55ab , 0x00003ffc // log(1/frcpa(1+117/2^-8))/2
+data8 0xc2c2abbb6e5fd56f , 0x00003ffc // log(1/frcpa(1+118/2^-8))/2
+data8 0xc439b2c193e6771e , 0x00003ffc // log(1/frcpa(1+119/2^-8))/2
+data8 0xc553acb9d5c67733 , 0x00003ffc // log(1/frcpa(1+120/2^-8))/2
+//
+data8 0xc6cc96e441272441 , 0x00003ffc // log(1/frcpa(1+121/2^-8))/2
+data8 0xc8469753eca88c30 , 0x00003ffc // log(1/frcpa(1+122/2^-8))/2
+data8 0xc962cf3ce072b05c , 0x00003ffc // log(1/frcpa(1+123/2^-8))/2
+data8 0xcadeba8771f694aa , 0x00003ffc // log(1/frcpa(1+124/2^-8))/2
+data8 0xcc5bc08d1f72da94 , 0x00003ffc // log(1/frcpa(1+125/2^-8))/2
+//
+data8 0xcd7a3f99ea035c29 , 0x00003ffc // log(1/frcpa(1+126/2^-8))/2
+data8 0xcef93860c8a53c35 , 0x00003ffc // log(1/frcpa(1+127/2^-8))/2
+data8 0xd0192f68a7ed23df , 0x00003ffc // log(1/frcpa(1+128/2^-8))/2
+data8 0xd19a201127d3c645 , 0x00003ffc // log(1/frcpa(1+129/2^-8))/2
+data8 0xd2bb92f4061c172c , 0x00003ffc // log(1/frcpa(1+130/2^-8))/2
+//
+data8 0xd43e80b2ee8cc8fc , 0x00003ffc // log(1/frcpa(1+131/2^-8))/2
+data8 0xd56173601fc4ade4 , 0x00003ffc // log(1/frcpa(1+132/2^-8))/2
+data8 0xd6e6637efb54086f , 0x00003ffc // log(1/frcpa(1+133/2^-8))/2
+data8 0xd80ad9f58f3c8193 , 0x00003ffc // log(1/frcpa(1+134/2^-8))/2
+data8 0xd991d1d31aca41f8 , 0x00003ffc // log(1/frcpa(1+135/2^-8))/2
+//
+data8 0xdab7d02231484a93 , 0x00003ffc // log(1/frcpa(1+136/2^-8))/2
+data8 0xdc40d532cde49a54 , 0x00003ffc // log(1/frcpa(1+137/2^-8))/2
+data8 0xdd685f79ed8b265e , 0x00003ffc // log(1/frcpa(1+138/2^-8))/2
+data8 0xde9094bbc0e17b1d , 0x00003ffc // log(1/frcpa(1+139/2^-8))/2
+data8 0xe01c91b78440c425 , 0x00003ffc // log(1/frcpa(1+140/2^-8))/2
+//
+data8 0xe14658f26997e729 , 0x00003ffc // log(1/frcpa(1+141/2^-8))/2
+data8 0xe270cdc2391e0d23 , 0x00003ffc // log(1/frcpa(1+142/2^-8))/2
+data8 0xe3ffce3a2aa64922 , 0x00003ffc // log(1/frcpa(1+143/2^-8))/2
+data8 0xe52bdb274ed82887 , 0x00003ffc // log(1/frcpa(1+144/2^-8))/2
+data8 0xe6589852e75d7df6 , 0x00003ffc // log(1/frcpa(1+145/2^-8))/2
+//
+data8 0xe786068c79937a7d , 0x00003ffc // log(1/frcpa(1+146/2^-8))/2
+data8 0xe91903adad100911 , 0x00003ffc // log(1/frcpa(1+147/2^-8))/2
+data8 0xea481236f7d35bb0 , 0x00003ffc // log(1/frcpa(1+148/2^-8))/2
+data8 0xeb77d48c692e6b14 , 0x00003ffc // log(1/frcpa(1+149/2^-8))/2
+data8 0xeca84b83d7297b87 , 0x00003ffc // log(1/frcpa(1+150/2^-8))/2
+//
+data8 0xedd977f4962aa158 , 0x00003ffc // log(1/frcpa(1+151/2^-8))/2
+data8 0xef7179a22f257754 , 0x00003ffc // log(1/frcpa(1+152/2^-8))/2
+data8 0xf0a450d139366ca7 , 0x00003ffc // log(1/frcpa(1+153/2^-8))/2
+data8 0xf1d7e0524ff9ffdb , 0x00003ffc // log(1/frcpa(1+154/2^-8))/2
+data8 0xf30c29036a8b6cae , 0x00003ffc // log(1/frcpa(1+155/2^-8))/2
+//
+data8 0xf4412bc411ea8d92 , 0x00003ffc // log(1/frcpa(1+156/2^-8))/2
+data8 0xf576e97564c8619d , 0x00003ffc // log(1/frcpa(1+157/2^-8))/2
+data8 0xf6ad62fa1b5f172f , 0x00003ffc // log(1/frcpa(1+158/2^-8))/2
+data8 0xf7e499368b55c542 , 0x00003ffc // log(1/frcpa(1+159/2^-8))/2
+data8 0xf91c8d10abaffe22 , 0x00003ffc // log(1/frcpa(1+160/2^-8))/2
+//
+data8 0xfa553f7018c966f3 , 0x00003ffc // log(1/frcpa(1+161/2^-8))/2
+data8 0xfb8eb13e185d802c , 0x00003ffc // log(1/frcpa(1+162/2^-8))/2
+data8 0xfcc8e3659d9bcbed , 0x00003ffc // log(1/frcpa(1+163/2^-8))/2
+data8 0xfe03d6d34d487fd2 , 0x00003ffc // log(1/frcpa(1+164/2^-8))/2
+data8 0xff3f8c7581e9f0ae , 0x00003ffc // log(1/frcpa(1+165/2^-8))/2
+//
+data8 0x803e029e280173ae , 0x00003ffd // log(1/frcpa(1+166/2^-8))/2
+data8 0x80dca10cc52d0757 , 0x00003ffd // log(1/frcpa(1+167/2^-8))/2
+data8 0x817ba200632755a1 , 0x00003ffd // log(1/frcpa(1+168/2^-8))/2
+data8 0x821b05f3b01d6774 , 0x00003ffd // log(1/frcpa(1+169/2^-8))/2
+data8 0x82bacd623ff19d06 , 0x00003ffd // log(1/frcpa(1+170/2^-8))/2
+//
+data8 0x835af8c88e7a8f47 , 0x00003ffd // log(1/frcpa(1+171/2^-8))/2
+data8 0x83c5f8299e2b4091 , 0x00003ffd // log(1/frcpa(1+172/2^-8))/2
+data8 0x8466cb43f3d87300 , 0x00003ffd // log(1/frcpa(1+173/2^-8))/2
+data8 0x850803a67c80ca4b , 0x00003ffd // log(1/frcpa(1+174/2^-8))/2
+data8 0x85a9a1d11a23b461 , 0x00003ffd // log(1/frcpa(1+175/2^-8))/2
+//
+data8 0x864ba644a18e6e05 , 0x00003ffd // log(1/frcpa(1+176/2^-8))/2
+data8 0x86ee1182dcc432f7 , 0x00003ffd // log(1/frcpa(1+177/2^-8))/2
+data8 0x875a925d7e48c316 , 0x00003ffd // log(1/frcpa(1+178/2^-8))/2
+data8 0x87fdaa109d23aef7 , 0x00003ffd // log(1/frcpa(1+179/2^-8))/2
+data8 0x88a129ed4becfaf2 , 0x00003ffd // log(1/frcpa(1+180/2^-8))/2
+//
+data8 0x89451278ecd7f9cf , 0x00003ffd // log(1/frcpa(1+181/2^-8))/2
+data8 0x89b29295f8432617 , 0x00003ffd // log(1/frcpa(1+182/2^-8))/2
+data8 0x8a572ac5a5496882 , 0x00003ffd // log(1/frcpa(1+183/2^-8))/2
+data8 0x8afc2d0ce3b2dadf , 0x00003ffd // log(1/frcpa(1+184/2^-8))/2
+data8 0x8b6a69c608cfd3af , 0x00003ffd // log(1/frcpa(1+185/2^-8))/2
+//
+data8 0x8c101e106e899a83 , 0x00003ffd // log(1/frcpa(1+186/2^-8))/2
+data8 0x8cb63de258f9d626 , 0x00003ffd // log(1/frcpa(1+187/2^-8))/2
+data8 0x8d2539c5bd19e2b1 , 0x00003ffd // log(1/frcpa(1+188/2^-8))/2
+data8 0x8dcc0e064b29e6f1 , 0x00003ffd // log(1/frcpa(1+189/2^-8))/2
+data8 0x8e734f45d88357ae , 0x00003ffd // log(1/frcpa(1+190/2^-8))/2
+//
+data8 0x8ee30cef034a20db , 0x00003ffd // log(1/frcpa(1+191/2^-8))/2
+data8 0x8f8b0515686d1d06 , 0x00003ffd // log(1/frcpa(1+192/2^-8))/2
+data8 0x90336bba039bf32f , 0x00003ffd // log(1/frcpa(1+193/2^-8))/2
+data8 0x90a3edd23d1c9d58 , 0x00003ffd // log(1/frcpa(1+194/2^-8))/2
+data8 0x914d0de2f5d61b32 , 0x00003ffd // log(1/frcpa(1+195/2^-8))/2
+//
+data8 0x91be0c20d28173b5 , 0x00003ffd // log(1/frcpa(1+196/2^-8))/2
+data8 0x9267e737c06cd34a , 0x00003ffd // log(1/frcpa(1+197/2^-8))/2
+data8 0x92d962ae6abb1237 , 0x00003ffd // log(1/frcpa(1+198/2^-8))/2
+data8 0x9383fa6afbe2074c , 0x00003ffd // log(1/frcpa(1+199/2^-8))/2
+data8 0x942f0421651c1c4e , 0x00003ffd // log(1/frcpa(1+200/2^-8))/2
+//
+data8 0x94a14a3845bb985e , 0x00003ffd // log(1/frcpa(1+201/2^-8))/2
+data8 0x954d133857f861e7 , 0x00003ffd // log(1/frcpa(1+202/2^-8))/2
+data8 0x95bfd96468e604c4 , 0x00003ffd // log(1/frcpa(1+203/2^-8))/2
+data8 0x9632d31cafafa858 , 0x00003ffd // log(1/frcpa(1+204/2^-8))/2
+data8 0x96dfaabd86fa1647 , 0x00003ffd // log(1/frcpa(1+205/2^-8))/2
+//
+data8 0x9753261fcbb2a594 , 0x00003ffd // log(1/frcpa(1+206/2^-8))/2
+data8 0x9800c11b426b996d , 0x00003ffd // log(1/frcpa(1+207/2^-8))/2
+data8 0x9874bf4d45ae663c , 0x00003ffd // log(1/frcpa(1+208/2^-8))/2
+data8 0x99231f5ee9a74f79 , 0x00003ffd // log(1/frcpa(1+209/2^-8))/2
+data8 0x9997a18a56bcad28 , 0x00003ffd // log(1/frcpa(1+210/2^-8))/2
+//
+data8 0x9a46c873a3267e79 , 0x00003ffd // log(1/frcpa(1+211/2^-8))/2
+data8 0x9abbcfc621eb6cb6 , 0x00003ffd // log(1/frcpa(1+212/2^-8))/2
+data8 0x9b310cb0d354c990 , 0x00003ffd // log(1/frcpa(1+213/2^-8))/2
+data8 0x9be14cf9e1b3515c , 0x00003ffd // log(1/frcpa(1+214/2^-8))/2
+data8 0x9c5710b8cbb73a43 , 0x00003ffd // log(1/frcpa(1+215/2^-8))/2
+//
+data8 0x9ccd0abd301f399c , 0x00003ffd // log(1/frcpa(1+216/2^-8))/2
+data8 0x9d7e67f3bdce8888 , 0x00003ffd // log(1/frcpa(1+217/2^-8))/2
+data8 0x9df4ea81a99daa01 , 0x00003ffd // log(1/frcpa(1+218/2^-8))/2
+data8 0x9e6ba405a54514ba , 0x00003ffd // log(1/frcpa(1+219/2^-8))/2
+data8 0x9f1e21c8c7bb62b3 , 0x00003ffd // log(1/frcpa(1+220/2^-8))/2
+//
+data8 0x9f956593f6b6355c , 0x00003ffd // log(1/frcpa(1+221/2^-8))/2
+data8 0xa00ce1092e5498c3 , 0x00003ffd // log(1/frcpa(1+222/2^-8))/2
+data8 0xa0c08309c4b912c1 , 0x00003ffd // log(1/frcpa(1+223/2^-8))/2
+data8 0xa1388a8c6faa2afa , 0x00003ffd // log(1/frcpa(1+224/2^-8))/2
+data8 0xa1b0ca7095b5f985 , 0x00003ffd // log(1/frcpa(1+225/2^-8))/2
+//
+data8 0xa22942eb47534a00 , 0x00003ffd // log(1/frcpa(1+226/2^-8))/2
+data8 0xa2de62326449d0a3 , 0x00003ffd // log(1/frcpa(1+227/2^-8))/2
+data8 0xa357690f88bfe345 , 0x00003ffd // log(1/frcpa(1+228/2^-8))/2
+data8 0xa3d0a93f45169a4b , 0x00003ffd // log(1/frcpa(1+229/2^-8))/2
+data8 0xa44a22f7ffe65f30 , 0x00003ffd // log(1/frcpa(1+230/2^-8))/2
+//
+data8 0xa500c5e5b4c1aa36 , 0x00003ffd // log(1/frcpa(1+231/2^-8))/2
+data8 0xa57ad064eb2ebbc2 , 0x00003ffd // log(1/frcpa(1+232/2^-8))/2
+data8 0xa5f5152dedf4384e , 0x00003ffd // log(1/frcpa(1+233/2^-8))/2
+data8 0xa66f9478856233ec , 0x00003ffd // log(1/frcpa(1+234/2^-8))/2
+data8 0xa6ea4e7cca02c32e , 0x00003ffd // log(1/frcpa(1+235/2^-8))/2
+//
+data8 0xa765437325341ccf , 0x00003ffd // log(1/frcpa(1+236/2^-8))/2
+data8 0xa81e21e6c75b4020 , 0x00003ffd // log(1/frcpa(1+237/2^-8))/2
+data8 0xa899ab333fe2b9ca , 0x00003ffd // log(1/frcpa(1+238/2^-8))/2
+data8 0xa9157039c51ebe71 , 0x00003ffd // log(1/frcpa(1+239/2^-8))/2
+data8 0xa991713433c2b999 , 0x00003ffd // log(1/frcpa(1+240/2^-8))/2
+//
+data8 0xaa0dae5cbcc048b3 , 0x00003ffd // log(1/frcpa(1+241/2^-8))/2
+data8 0xaa8a27ede5eb13ad , 0x00003ffd // log(1/frcpa(1+242/2^-8))/2
+data8 0xab06de228a9e3499 , 0x00003ffd // log(1/frcpa(1+243/2^-8))/2
+data8 0xab83d135dc633301 , 0x00003ffd // log(1/frcpa(1+244/2^-8))/2
+data8 0xac3fb076adc7fe7a , 0x00003ffd // log(1/frcpa(1+245/2^-8))/2
+//
+data8 0xacbd3cbbe47988f1 , 0x00003ffd // log(1/frcpa(1+246/2^-8))/2
+data8 0xad3b06b1a5dc57c3 , 0x00003ffd // log(1/frcpa(1+247/2^-8))/2
+data8 0xadb90e94af887717 , 0x00003ffd // log(1/frcpa(1+248/2^-8))/2
+data8 0xae3754a218f7c816 , 0x00003ffd // log(1/frcpa(1+249/2^-8))/2
+data8 0xaeb5d9175437afa2 , 0x00003ffd // log(1/frcpa(1+250/2^-8))/2
+//
+data8 0xaf349c322e9c7cee , 0x00003ffd // log(1/frcpa(1+251/2^-8))/2
+data8 0xafb39e30d1768d1c , 0x00003ffd // log(1/frcpa(1+252/2^-8))/2
+data8 0xb032df51c2c93116 , 0x00003ffd // log(1/frcpa(1+253/2^-8))/2
+data8 0xb0b25fd3e6035ad9 , 0x00003ffd // log(1/frcpa(1+254/2^-8))/2
+data8 0xb1321ff67cba178c , 0x00003ffd // log(1/frcpa(1+255/2^-8))/2
+LOCAL_OBJECT_END(atanh_data_3)
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(atanh)
+
+{ .mfi
+ getf.exp rArgSExpb = f8 // Must recompute if x unorm
+ fclass.m p13,p0 = f8, 0x0b // is arg denormal ?
+ mov rExpbMask = 0x1ffff
+}
+{ .mfi
+ addl DataPtr = @ltoff(atanh_data), gp
+ fnma.s1 fOneMx = f8, f1, f1 // fOneMx = 1 - x
+ mov rBias = 0xffff
+}
+;;
+
+{ .mfi
+ mov rNearZeroBound = 0xfffd // biased exp of 1/4
+ fclass.m p12,p0 = f8, 0xc7 // is arg NaN or +/-0 ?
+ nop.i 0
+}
+{ .mfi
+ ld8 DataPtr = [DataPtr]
+ fma.s1 fOnePx = f8, f1, f1 // fOnePx = 1 + x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.lt.s1 p10,p11 = f8,f0 // is x < 0 ?
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fnorm.s1 fNormX = f8 // Normalize x
+(p13) br.cond.spnt ATANH_UNORM // Branch if x=unorm
+}
+;;
+
+ATANH_COMMON:
+// Return here if x=unorm and not denorm
+{ .mfi
+ adds Data2Ptr = 0x50, DataPtr
+ fma.s1 fX2 = f8, f8, f0 // x^2
+ nop.i 0
+}
+{ .mfb
+ adds Data3Ptr = 0xC0, DataPtr
+(p12) fma.d.s0 f8 = f8,f1,f8 // NaN or +/-0
+(p12) br.ret.spnt b0 // Exit for x Nan or zero
+}
+;;
+
+{ .mfi
+ ldfe fC9 = [Data2Ptr], 16
+(p11) frcpa.s1 fRcp0, p0 = f1, fOneMx
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe fC8 = [Data2Ptr], 16
+(p10) frcpa.s1 fRcp0n, p0 = f1, fOnePx
+ and rArgExpb = rArgSExpb, rExpbMask // biased exponent
+}
+{ .mfi
+ nop.m 0
+(p10) fma.s1 fOneMx = fOnePx, f1, f0 // fOnePx = 1 - |x|
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe fC7 = [Data2Ptr], 16
+(p10) fnma.s1 fOnePx = fNormX, f1, f1 // fOnePx = 1 + |x|
+ cmp.ge p6,p0 = rArgExpb, rBias // is Expb(Arg) >= Expb(1) ?
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p6) br.cond.spnt atanh_ge_one // Branch if |x| >=1.0
+}
+;;
+
+{ .mfi
+ ldfe fC6 = [Data2Ptr], 16
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe fC5 = [Data2Ptr], 16
+ fma.s1 fX4 = fX2, fX2, f0 // x^4
+ cmp.gt p8,p0 = rNearZeroBound, rArgExpb
+}
+{ .mfb
+ ldfe fC2 = [Data3Ptr], 16
+ fma.s1 fX3 = fX2, fNormX, f0 // x^3
+(p8) br.cond.spnt atanh_near_zero // Exit if 0 < |x| < 0.25
+}
+;;
+
+// Main path: 0.25 <= |x| < 1.0
+// NR method: iteration #1
+.pred.rel "mutex",p11,p10
+{ .mfi
+ ldfpd fP5, fP4 = [DataPtr], 16
+(p11) fnma.s1 fRcp1 = fRcp0, fOneMx, f1 // t = 1 - r0*x
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fnma.s1 fRcp1 = fRcp0n, fOneMx, f1 // t = 1 - r0*x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfpd fP3, fP2 = [DataPtr], 16
+ // r1 = r0 + r0*t = r0 + r0*(1 - r0*x)
+(p11) fma.s1 fRcp1 = fRcp0, fRcp1, fRcp0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // r1 = r0 + r0*t = r0 + r0*(1 - r0*x)
+(p10) fma.s1 fRcp1 = fRcp0n, fRcp1, fRcp0n
+ nop.i 0
+}
+;;
+
+// NR method: iteration #2
+{ .mfi
+ ldfd fP1 = [DataPtr], 16
+ fnma.s1 fRcp2 = fRcp1, fOneMx, f1 // t = 1 - r1*x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe fLog2 = [DataPtr], 16
+ // r2 = r1 + r1*t = r1 + r1*(1 - r1*x)
+ fma.s1 fRcp2 = fRcp1, fRcp2, fRcp1
+ nop.i 0
+}
+;;
+
+// NR method: iteration #3
+{ .mfi
+ adds RcpTablePtr = 0xB0, DataPtr
+ fnma.s1 fRcp3 = fRcp2, fOneMx, f1 // t = 1 - r2*x
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fY4Rcp = fRcp2, fOnePx, f0 // fY4Rcp = r2*(1 + x)
+ nop.i 0
+}
+;;
+
+// polynomial approximation & final reconstruction
+{ .mfi
+ nop.m 0
+ frcpa.s1 fRcp, p0 = f1, fY4Rcp
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // y = r2 * (1 + x) + r2 * (1 + x) * t = (1 + x) * (r2 + r2*(1 - r2*x))
+ fma.s1 fY = fY4Rcp, fRcp3, fY4Rcp
+ nop.i 0
+}
+;;
+
+{ .mmi
+ getf.exp rSExpb = fY4Rcp // biased exponent and sign
+;;
+ getf.sig rSig = fY4Rcp // significand
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fR = fY, fRcp, f1 // fR = fY * fRcp - 1
+ nop.i 0
+}
+;;
+
+{ .mmi
+ and rExpb = rSExpb, rExpbMask
+;;
+ sub rN = rExpb, rBias // exponent
+ extr.u rInd = rSig,55,8 // Extract 8 bits
+}
+;;
+
+{ .mmi
+ setf.sig fN4Cvt = rN
+ shladd RcpTablePtr = rInd, 4, RcpTablePtr
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe fLogT = [RcpTablePtr]
+ fma.s1 fR2 = fR, fR, f0 // r^2
+ nop.i 0
+}
+{
+ nop.m 0
+ fma.s1 fP54 = fP5, fR, fP4 // P5*r + P4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP32 = fP3, fR, fP2 // P3*r + P2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fR3 = fR2, fR, f0 // r^3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fP10 = fP1, fR2, fR // P1*r^2 + r
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf fN = fN4Cvt
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fP54 = fP54, fR2, fP32 // (P5*r + P4)*r^2 + P3*r + P2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fLogT_N = fN, fLog2, fLogT // N*Log2 + LogT
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // ((P5*r + P4)*r^2 + P3*r + P2)*r^3 + P1*r^2 + r
+ fma.s1 fP54 = fP54, fR3, fP10
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p11,p10
+{ .mfi
+ nop.m 0
+ // 0.5*(((P5*r + P4)*r^2 + P3*r + P2)*r^3 + P1*r^2 + r) + 0.5*(N*Log2 + T)
+(p11) fnma.d.s0 f8 = fP54, fP1, fLogT_N
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ // -0.5*(((P5*r + P4)*r^2 + P3*r + P2)*r^3 + P1*r^2 + r) - 0.5*(N*Log2 + T)
+(p10) fms.d.s0 f8 = fP54, fP1, fLogT_N
+ br.ret.sptk b0 // Exit for 0.25 <= |x| < 1.0
+}
+;;
+
+// Here if 0 < |x| < 0.25
+atanh_near_zero:
+{ .mfi
+ ldfe fC4 = [Data2Ptr], 16
+ fma.s1 fP98 = fC9, fX2, fC8 // C9*x^2 + C8
+ nop.i 0
+}
+{ .mfi
+ ldfe fC1 = [Data3Ptr], 16
+ fma.s1 fP76 = fC7, fX2, fC6 // C7*x^2 + C6
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe fC3 = [Data2Ptr], 16
+ fma.s1 fX8 = fX4, fX4, f0 // x^8
+ nop.i 0
+}
+{ .mfi
+ ldfe fC0 = [Data3Ptr], 16
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP98 = fP98, fX4, fP76 // C9*x^6 + C8*x^4 + C7*x^2 + C6
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP54 = fC5, fX2, fC4 // C5*x^2 + C4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP32 = fC3, fX2, fC2 // C3*x^2 + C2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP10 = fC1, fX2, fC0 // C1*x^2 + C0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP54 = fP54, fX4, fP32 // C5*x^6 + C4*x^4 + C3*x^2 + C2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // C9*x^14 + C8*x^12 + C7*x^10 + C6*x^8 + C5*x^6 + C4*x^4 + C3*x^2 + C2
+ fma.s1 fP98 = fP98, fX8, fP54
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // C9*x^18 + C8*x^16 + C7*x^14 + C6*x^12 + C5*x^10 + C4*x^8 + C3*x^6 +
+ // C2*x^4 + C1*x^2 + C0
+ fma.s1 fP98 = fP98, fX4, fP10
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ // C9*x^21 + C8*x^19 + C7*x^17 + C6*x^15 + C5*x^13 + C4*x^11 + C3*x^9 +
+ // C2*x^7 + C1*x^5 + C0*x^3 + x
+ fma.d.s0 f8 = fP98, fX3, fNormX
+ br.ret.sptk b0 // Exit for 0 < |x| < 0.25
+}
+;;
+
+ATANH_UNORM:
+// Here if x=unorm
+{ .mfi
+ getf.exp rArgSExpb = fNormX // Recompute if x unorm
+ fclass.m p0,p13 = fNormX, 0x0b // Test x denorm
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy to set denormal flag
+(p13) br.cond.sptk ATANH_COMMON // Continue if x unorm and not denorm
+}
+;;
+
+.pred.rel "mutex",p10,p11
+{ .mfi
+ nop.m 0
+(p10) fnma.d.s0 f8 = f8,f8,f8 // Result x-x^2 if x=-denorm
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p11) fma.d.s0 f8 = f8,f8,f8 // Result x+x^2 if x=+denorm
+ br.ret.spnt b0 // Exit if denorm
+}
+;;
+
+// Here if |x| >= 1.0
+atanh_ge_one:
+{ .mfi
+ alloc r32 = ar.pfs,1,3,4,0
+ fmerge.s fAbsX = f0, f8 // Form |x|
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fmerge.s f10 = f8, f8 // Save input for error call
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s1 p6,p7 = fAbsX, f1 // Test for |x| = 1.0
+ nop.i 0
+}
+;;
+
+// Set error tag and result, and raise invalid flag if |x| > 1.0
+{ .mfi
+(p7) mov atanh_GR_tag = 131
+(p7) frcpa.s0 f8, p0 = f0, f0 // Get QNaN, and raise invalid
+ nop.i 0
+}
+;;
+
+// Set error tag and result, and raise Z flag if |x| = 1.0
+{ .mfi
+ nop.m 0
+(p6) frcpa.s0 fRcp, p0 = f1, f0 // Get inf, and raise Z flag
+ nop.i 0
+}
+;;
+
+{ .mfb
+(p6) mov atanh_GR_tag = 132
+(p6) fmerge.s f8 = f8, fRcp // result is +-inf
+ br.cond.sptk __libm_error_region // Exit if |x| >= 1.0
+}
+;;
+
+GLOBAL_LIBM_END(atanh)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfd [GR_Parameter_Y] = f1,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfd [GR_Parameter_X] = f10 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_atanhf.S b/libc/sysdeps/ia64/fpu/e_atanhf.S
new file mode 100644
index 000000000..1ec1408e3
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_atanhf.S
@@ -0,0 +1,845 @@
+.file "atanhf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 05/22/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 08/06/02 Improved Itanium 2 performance
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 05/26/03 Improved performance, fixed to handle unorms
+//
+// API
+//==============================================================
+// float atanhf(float)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+//
+// There are 7 paths:
+// 1. x = +/-0.0
+// Return atanhf(x) = +/-0.0
+//
+// 2. 0.0 < |x| <= MAX_DENORMAL_ABS
+// Return atanhf(x) = x + sign(x)*x^2
+//
+// 3. MAX_DENORMAL_ABS < |x| < 2^(-20)
+// Return atanhf(x) = Pol3(x), where Pol3(x) = x + x^3
+//
+// 4. 2^(-20) <= |x| < 1
+// Return atanhf(x) = 0.5 * (log(1 + x) - log(1 - x))
+// Algorithm description for log function see below.
+//
+// 5. |x| = 1
+// Return atanhf(x) = sign(x) * +INF
+//
+// 6. 1 < |x| <= +INF
+// Return atanhf(x) = QNaN
+//
+// 7. x = [S,Q]NaN
+// Return atanhf(x) = QNaN
+//
+//==============================================================
+// Algorithm Description for log(x) function
+//
+// Consider x = 2^N * 1.f1 f2 f3 f4...f63
+// log(x) = log(x * frcpa(x) / frcpa(x))
+// = log(x * frcpa(x)) + log(1/frcpa(x))
+// = log(x * frcpa(x)) - log(frcpa(x))
+//
+// frcpa(x) = 2^(-N) * frcpa(1.f1 f2 ... f63)
+//
+// -log(frcpa(x)) = -log(C)
+// = -log(2^(-N)) - log(frcpa(1.f1 f2 ... f63))
+//
+// -log(frcpa(x)) = -log(C)
+// = N*log2 - log(frcpa(1.f1 f2 ... f63))
+//
+//
+// log(x) = log(1/frcpa(x)) + log(frcpa(x) x)
+//
+// log(x) = N*log2 + log(1./frcpa(1.f1 f2 ... f63)) + log(x * frcpa(x))
+// log(x) = N*log2 + T + log(frcpa(x) x)
+//
+// Log(x) = N*log2 + T + log(C * x)
+//
+// C * x = 1 + r
+//
+// log(x) = N*log2 + T + log(1 + r)
+// log(x) = N*log2 + T + Series(r)
+//
+// 1.f1 f2 ... f8 has 256 entries.
+// They are 1 + k/2^8, k = 0 ... 255
+// These 256 values are the table entries.
+//
+// Implementation
+//==============================================================
+// C = frcpa(x)
+// r = C * x - 1
+//
+// Form rseries = r + P1*r^2 + P2*r^3 + P3*r^4
+//
+// x = f * 2*N where f is 1.f_1f_2f_3...f_63
+// Nfloat = float(n) where n is the true unbiased exponent
+// pre-index = f_1f_2....f_8
+// index = pre_index * 16
+// get the dxt table entry at index + offset = T
+//
+// result = (T + Nfloat * log(2)) + rseries
+//
+// The T table is calculated as follows
+// Form x_k = 1 + k/2^8 where k goes from 0... 255
+// y_k = frcpa(x_k)
+// log(1/y_k) in quad and round to double-extended
+
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f32 -> f59
+
+// General registers used:
+// r14 -> r29, r32 -> r39
+
+// Predicate registers used:
+// p6 -> p9
+
+// p6 to filter out case when |x| >= 1
+// p7 to filter out case when x = [Q,S]NaN or +/-0
+// p8 to filter out case when |x| < 2^(-20)
+// p9 to filter out case when x = denormal
+
+
+// Assembly macros
+//==============================================================
+DataPtr = r14
+RcpTablePtrM = r15
+RcpTablePtrP = r16
+rExpbMask = r17
+rBias = r18
+rNearZeroBound = r19
+rArgSExpb = r20
+rArgExpb = r21
+rExpbm = r22
+rExpbp = r23
+rSigm = r24
+rSigp = r25
+rNm = r26
+rNp = r27
+rIndm = r28
+rIndp = r29
+
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_SAVE_PFS = r35
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+atanh_GR_tag = r39
+
+//==============================================================
+fOneMx = f33
+fOnePx = f34
+fRm2 = f35
+fRm3 = f36
+fRp2 = f37
+fRp3 = f38
+fRcpM = f39
+fRcpP = f40
+fRp = f41
+fRm = f42
+fN4CvtM = f43
+fN4CvtP = f44
+fNm = f45
+fNp = f46
+fLogTm = f47
+fLogTp = f48
+fLog2 = f49
+fArgAbs = f50
+fNormX = f50
+fP32m = f51
+fP32p = f52
+fP10m = f53
+fP10p = f54
+fX2 = f55
+fP3 = f56
+fP2 = f57
+fP1 = f58
+fHalf = f59
+
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(atanhf_data)
+data8 0xbfc0001008f39d59 // P3*0.5
+data8 0x3fc5556073e0c45a // P2*0.5
+data8 0xbfcffffffffaea15 // P1*0.5
+data8 0x3fe0000000000000 // 0.5
+data8 0x3fd62e42fefa39ef // 0.5*ln(2)
+data8 0x0000000000000000 // pad
+LOCAL_OBJECT_END(atanhf_data)
+
+LOCAL_OBJECT_START(atanhf_data2)
+data8 0x3f50040155d5889e //log(1/frcpa(1+0/256))/2
+data8 0x3f68121214586b54 //log(1/frcpa(1+1/256))/2
+data8 0x3f741929f96832f0 //log(1/frcpa(1+2/256))/2
+data8 0x3f7c317384c75f06 //log(1/frcpa(1+3/256))/2
+data8 0x3f81a6b91ac73386 //log(1/frcpa(1+4/256))/2
+data8 0x3f85ba9a5d9ac039 //log(1/frcpa(1+5/256))/2
+data8 0x3f89d2a8074325f4 //log(1/frcpa(1+6/256))/2
+data8 0x3f8d6b2725979802 //log(1/frcpa(1+7/256))/2
+data8 0x3f90c58fa19dfaaa //log(1/frcpa(1+8/256))/2
+data8 0x3f92954c78cbce1b //log(1/frcpa(1+9/256))/2
+data8 0x3f94a94d2da96c56 //log(1/frcpa(1+10/256))/2
+data8 0x3f967c94f2d4bb58 //log(1/frcpa(1+11/256))/2
+data8 0x3f985188b630f068 //log(1/frcpa(1+12/256))/2
+data8 0x3f9a6b8abe73af4c //log(1/frcpa(1+13/256))/2
+data8 0x3f9c441e06f72a9e //log(1/frcpa(1+14/256))/2
+data8 0x3f9e1e6713606d07 //log(1/frcpa(1+15/256))/2
+data8 0x3f9ffa6911ab9301 //log(1/frcpa(1+16/256))/2
+data8 0x3fa0ec139c5da601 //log(1/frcpa(1+17/256))/2
+data8 0x3fa1dbd2643d190b //log(1/frcpa(1+18/256))/2
+data8 0x3fa2cc7284fe5f1c //log(1/frcpa(1+19/256))/2
+data8 0x3fa3bdf5a7d1ee64 //log(1/frcpa(1+20/256))/2
+data8 0x3fa4b05d7aa012e0 //log(1/frcpa(1+21/256))/2
+data8 0x3fa580db7ceb5702 //log(1/frcpa(1+22/256))/2
+data8 0x3fa674f089365a7a //log(1/frcpa(1+23/256))/2
+data8 0x3fa769ef2c6b568d //log(1/frcpa(1+24/256))/2
+data8 0x3fa85fd927506a48 //log(1/frcpa(1+25/256))/2
+data8 0x3fa9335e5d594989 //log(1/frcpa(1+26/256))/2
+data8 0x3faa2b0220c8e5f5 //log(1/frcpa(1+27/256))/2
+data8 0x3fab0004ac1a86ac //log(1/frcpa(1+28/256))/2
+data8 0x3fabf968769fca11 //log(1/frcpa(1+29/256))/2
+data8 0x3faccfedbfee13a8 //log(1/frcpa(1+30/256))/2
+data8 0x3fada727638446a2 //log(1/frcpa(1+31/256))/2
+data8 0x3faea3257fe10f7a //log(1/frcpa(1+32/256))/2
+data8 0x3faf7be9fedbfde6 //log(1/frcpa(1+33/256))/2
+data8 0x3fb02ab352ff25f4 //log(1/frcpa(1+34/256))/2
+data8 0x3fb097ce579d204d //log(1/frcpa(1+35/256))/2
+data8 0x3fb1178e8227e47c //log(1/frcpa(1+36/256))/2
+data8 0x3fb185747dbecf34 //log(1/frcpa(1+37/256))/2
+data8 0x3fb1f3b925f25d41 //log(1/frcpa(1+38/256))/2
+data8 0x3fb2625d1e6ddf57 //log(1/frcpa(1+39/256))/2
+data8 0x3fb2d1610c86813a //log(1/frcpa(1+40/256))/2
+data8 0x3fb340c59741142e //log(1/frcpa(1+41/256))/2
+data8 0x3fb3b08b6757f2a9 //log(1/frcpa(1+42/256))/2
+data8 0x3fb40dfb08378003 //log(1/frcpa(1+43/256))/2
+data8 0x3fb47e74e8ca5f7c //log(1/frcpa(1+44/256))/2
+data8 0x3fb4ef51f6466de4 //log(1/frcpa(1+45/256))/2
+data8 0x3fb56092e02ba516 //log(1/frcpa(1+46/256))/2
+data8 0x3fb5d23857cd74d5 //log(1/frcpa(1+47/256))/2
+data8 0x3fb6313a37335d76 //log(1/frcpa(1+48/256))/2
+data8 0x3fb6a399dabbd383 //log(1/frcpa(1+49/256))/2
+data8 0x3fb70337dd3ce41b //log(1/frcpa(1+50/256))/2
+data8 0x3fb77654128f6127 //log(1/frcpa(1+51/256))/2
+data8 0x3fb7e9d82a0b022d //log(1/frcpa(1+52/256))/2
+data8 0x3fb84a6b759f512f //log(1/frcpa(1+53/256))/2
+data8 0x3fb8ab47d5f5a310 //log(1/frcpa(1+54/256))/2
+data8 0x3fb91fe49096581b //log(1/frcpa(1+55/256))/2
+data8 0x3fb981634011aa75 //log(1/frcpa(1+56/256))/2
+data8 0x3fb9f6c407089664 //log(1/frcpa(1+57/256))/2
+data8 0x3fba58e729348f43 //log(1/frcpa(1+58/256))/2
+data8 0x3fbabb55c31693ad //log(1/frcpa(1+59/256))/2
+data8 0x3fbb1e104919efd0 //log(1/frcpa(1+60/256))/2
+data8 0x3fbb94ee93e367cb //log(1/frcpa(1+61/256))/2
+data8 0x3fbbf851c067555f //log(1/frcpa(1+62/256))/2
+data8 0x3fbc5c0254bf23a6 //log(1/frcpa(1+63/256))/2
+data8 0x3fbcc000c9db3c52 //log(1/frcpa(1+64/256))/2
+data8 0x3fbd244d99c85674 //log(1/frcpa(1+65/256))/2
+data8 0x3fbd88e93fb2f450 //log(1/frcpa(1+66/256))/2
+data8 0x3fbdedd437eaef01 //log(1/frcpa(1+67/256))/2
+data8 0x3fbe530effe71012 //log(1/frcpa(1+68/256))/2
+data8 0x3fbeb89a1648b971 //log(1/frcpa(1+69/256))/2
+data8 0x3fbf1e75fadf9bde //log(1/frcpa(1+70/256))/2
+data8 0x3fbf84a32ead7c35 //log(1/frcpa(1+71/256))/2
+data8 0x3fbfeb2233ea07cd //log(1/frcpa(1+72/256))/2
+data8 0x3fc028f9c7035c1c //log(1/frcpa(1+73/256))/2
+data8 0x3fc05c8be0d9635a //log(1/frcpa(1+74/256))/2
+data8 0x3fc085eb8f8ae797 //log(1/frcpa(1+75/256))/2
+data8 0x3fc0b9c8e32d1911 //log(1/frcpa(1+76/256))/2
+data8 0x3fc0edd060b78081 //log(1/frcpa(1+77/256))/2
+data8 0x3fc122024cf0063f //log(1/frcpa(1+78/256))/2
+data8 0x3fc14be2927aecd4 //log(1/frcpa(1+79/256))/2
+data8 0x3fc180618ef18adf //log(1/frcpa(1+80/256))/2
+data8 0x3fc1b50bbe2fc63b //log(1/frcpa(1+81/256))/2
+data8 0x3fc1df4cc7cf242d //log(1/frcpa(1+82/256))/2
+data8 0x3fc214456d0eb8d4 //log(1/frcpa(1+83/256))/2
+data8 0x3fc23ec5991eba49 //log(1/frcpa(1+84/256))/2
+data8 0x3fc2740d9f870afb //log(1/frcpa(1+85/256))/2
+data8 0x3fc29ecdabcdfa04 //log(1/frcpa(1+86/256))/2
+data8 0x3fc2d46602adccee //log(1/frcpa(1+87/256))/2
+data8 0x3fc2ff66b04ea9d4 //log(1/frcpa(1+88/256))/2
+data8 0x3fc335504b355a37 //log(1/frcpa(1+89/256))/2
+data8 0x3fc360925ec44f5d //log(1/frcpa(1+90/256))/2
+data8 0x3fc38bf1c3337e75 //log(1/frcpa(1+91/256))/2
+data8 0x3fc3c25277333184 //log(1/frcpa(1+92/256))/2
+data8 0x3fc3edf463c1683e //log(1/frcpa(1+93/256))/2
+data8 0x3fc419b423d5e8c7 //log(1/frcpa(1+94/256))/2
+data8 0x3fc44591e0539f49 //log(1/frcpa(1+95/256))/2
+data8 0x3fc47c9175b6f0ad //log(1/frcpa(1+96/256))/2
+data8 0x3fc4a8b341552b09 //log(1/frcpa(1+97/256))/2
+data8 0x3fc4d4f3908901a0 //log(1/frcpa(1+98/256))/2
+data8 0x3fc501528da1f968 //log(1/frcpa(1+99/256))/2
+data8 0x3fc52dd06347d4f6 //log(1/frcpa(1+100/256))/2
+data8 0x3fc55a6d3c7b8a8a //log(1/frcpa(1+101/256))/2
+data8 0x3fc5925d2b112a59 //log(1/frcpa(1+102/256))/2
+data8 0x3fc5bf406b543db2 //log(1/frcpa(1+103/256))/2
+data8 0x3fc5ec433d5c35ae //log(1/frcpa(1+104/256))/2
+data8 0x3fc61965cdb02c1f //log(1/frcpa(1+105/256))/2
+data8 0x3fc646a84935b2a2 //log(1/frcpa(1+106/256))/2
+data8 0x3fc6740add31de94 //log(1/frcpa(1+107/256))/2
+data8 0x3fc6a18db74a58c5 //log(1/frcpa(1+108/256))/2
+data8 0x3fc6cf31058670ec //log(1/frcpa(1+109/256))/2
+data8 0x3fc6f180e852f0ba //log(1/frcpa(1+110/256))/2
+data8 0x3fc71f5d71b894f0 //log(1/frcpa(1+111/256))/2
+data8 0x3fc74d5aefd66d5c //log(1/frcpa(1+112/256))/2
+data8 0x3fc77b79922bd37e //log(1/frcpa(1+113/256))/2
+data8 0x3fc7a9b9889f19e2 //log(1/frcpa(1+114/256))/2
+data8 0x3fc7d81b037eb6a6 //log(1/frcpa(1+115/256))/2
+data8 0x3fc8069e33827231 //log(1/frcpa(1+116/256))/2
+data8 0x3fc82996d3ef8bcb //log(1/frcpa(1+117/256))/2
+data8 0x3fc85855776dcbfb //log(1/frcpa(1+118/256))/2
+data8 0x3fc8873658327ccf //log(1/frcpa(1+119/256))/2
+data8 0x3fc8aa75973ab8cf //log(1/frcpa(1+120/256))/2
+data8 0x3fc8d992dc8824e5 //log(1/frcpa(1+121/256))/2
+data8 0x3fc908d2ea7d9512 //log(1/frcpa(1+122/256))/2
+data8 0x3fc92c59e79c0e56 //log(1/frcpa(1+123/256))/2
+data8 0x3fc95bd750ee3ed3 //log(1/frcpa(1+124/256))/2
+data8 0x3fc98b7811a3ee5b //log(1/frcpa(1+125/256))/2
+data8 0x3fc9af47f33d406c //log(1/frcpa(1+126/256))/2
+data8 0x3fc9df270c1914a8 //log(1/frcpa(1+127/256))/2
+data8 0x3fca0325ed14fda4 //log(1/frcpa(1+128/256))/2
+data8 0x3fca33440224fa79 //log(1/frcpa(1+129/256))/2
+data8 0x3fca57725e80c383 //log(1/frcpa(1+130/256))/2
+data8 0x3fca87d0165dd199 //log(1/frcpa(1+131/256))/2
+data8 0x3fcaac2e6c03f896 //log(1/frcpa(1+132/256))/2
+data8 0x3fcadccc6fdf6a81 //log(1/frcpa(1+133/256))/2
+data8 0x3fcb015b3eb1e790 //log(1/frcpa(1+134/256))/2
+data8 0x3fcb323a3a635948 //log(1/frcpa(1+135/256))/2
+data8 0x3fcb56fa04462909 //log(1/frcpa(1+136/256))/2
+data8 0x3fcb881aa659bc93 //log(1/frcpa(1+137/256))/2
+data8 0x3fcbad0bef3db165 //log(1/frcpa(1+138/256))/2
+data8 0x3fcbd21297781c2f //log(1/frcpa(1+139/256))/2
+data8 0x3fcc039236f08819 //log(1/frcpa(1+140/256))/2
+data8 0x3fcc28cb1e4d32fd //log(1/frcpa(1+141/256))/2
+data8 0x3fcc4e19b84723c2 //log(1/frcpa(1+142/256))/2
+data8 0x3fcc7ff9c74554c9 //log(1/frcpa(1+143/256))/2
+data8 0x3fcca57b64e9db05 //log(1/frcpa(1+144/256))/2
+data8 0x3fcccb130a5cebb0 //log(1/frcpa(1+145/256))/2
+data8 0x3fccf0c0d18f326f //log(1/frcpa(1+146/256))/2
+data8 0x3fcd232075b5a201 //log(1/frcpa(1+147/256))/2
+data8 0x3fcd490246defa6b //log(1/frcpa(1+148/256))/2
+data8 0x3fcd6efa918d25cd //log(1/frcpa(1+149/256))/2
+data8 0x3fcd9509707ae52f //log(1/frcpa(1+150/256))/2
+data8 0x3fcdbb2efe92c554 //log(1/frcpa(1+151/256))/2
+data8 0x3fcdee2f3445e4af //log(1/frcpa(1+152/256))/2
+data8 0x3fce148a1a2726ce //log(1/frcpa(1+153/256))/2
+data8 0x3fce3afc0a49ff40 //log(1/frcpa(1+154/256))/2
+data8 0x3fce6185206d516e //log(1/frcpa(1+155/256))/2
+data8 0x3fce882578823d52 //log(1/frcpa(1+156/256))/2
+data8 0x3fceaedd2eac990c //log(1/frcpa(1+157/256))/2
+data8 0x3fced5ac5f436be3 //log(1/frcpa(1+158/256))/2
+data8 0x3fcefc9326d16ab9 //log(1/frcpa(1+159/256))/2
+data8 0x3fcf2391a2157600 //log(1/frcpa(1+160/256))/2
+data8 0x3fcf4aa7ee03192d //log(1/frcpa(1+161/256))/2
+data8 0x3fcf71d627c30bb0 //log(1/frcpa(1+162/256))/2
+data8 0x3fcf991c6cb3b379 //log(1/frcpa(1+163/256))/2
+data8 0x3fcfc07ada69a910 //log(1/frcpa(1+164/256))/2
+data8 0x3fcfe7f18eb03d3e //log(1/frcpa(1+165/256))/2
+data8 0x3fd007c053c5002e //log(1/frcpa(1+166/256))/2
+data8 0x3fd01b942198a5a1 //log(1/frcpa(1+167/256))/2
+data8 0x3fd02f74400c64eb //log(1/frcpa(1+168/256))/2
+data8 0x3fd04360be7603ad //log(1/frcpa(1+169/256))/2
+data8 0x3fd05759ac47fe34 //log(1/frcpa(1+170/256))/2
+data8 0x3fd06b5f1911cf52 //log(1/frcpa(1+171/256))/2
+data8 0x3fd078bf0533c568 //log(1/frcpa(1+172/256))/2
+data8 0x3fd08cd9687e7b0e //log(1/frcpa(1+173/256))/2
+data8 0x3fd0a10074cf9019 //log(1/frcpa(1+174/256))/2
+data8 0x3fd0b5343a234477 //log(1/frcpa(1+175/256))/2
+data8 0x3fd0c974c89431ce //log(1/frcpa(1+176/256))/2
+data8 0x3fd0ddc2305b9886 //log(1/frcpa(1+177/256))/2
+data8 0x3fd0eb524bafc918 //log(1/frcpa(1+178/256))/2
+data8 0x3fd0ffb54213a476 //log(1/frcpa(1+179/256))/2
+data8 0x3fd114253da97d9f //log(1/frcpa(1+180/256))/2
+data8 0x3fd128a24f1d9aff //log(1/frcpa(1+181/256))/2
+data8 0x3fd1365252bf0865 //log(1/frcpa(1+182/256))/2
+data8 0x3fd14ae558b4a92d //log(1/frcpa(1+183/256))/2
+data8 0x3fd15f85a19c765b //log(1/frcpa(1+184/256))/2
+data8 0x3fd16d4d38c119fa //log(1/frcpa(1+185/256))/2
+data8 0x3fd18203c20dd133 //log(1/frcpa(1+186/256))/2
+data8 0x3fd196c7bc4b1f3b //log(1/frcpa(1+187/256))/2
+data8 0x3fd1a4a738b7a33c //log(1/frcpa(1+188/256))/2
+data8 0x3fd1b981c0c9653d //log(1/frcpa(1+189/256))/2
+data8 0x3fd1ce69e8bb106b //log(1/frcpa(1+190/256))/2
+data8 0x3fd1dc619de06944 //log(1/frcpa(1+191/256))/2
+data8 0x3fd1f160a2ad0da4 //log(1/frcpa(1+192/256))/2
+data8 0x3fd2066d7740737e //log(1/frcpa(1+193/256))/2
+data8 0x3fd2147dba47a394 //log(1/frcpa(1+194/256))/2
+data8 0x3fd229a1bc5ebac3 //log(1/frcpa(1+195/256))/2
+data8 0x3fd237c1841a502e //log(1/frcpa(1+196/256))/2
+data8 0x3fd24cfce6f80d9a //log(1/frcpa(1+197/256))/2
+data8 0x3fd25b2c55cd5762 //log(1/frcpa(1+198/256))/2
+data8 0x3fd2707f4d5f7c41 //log(1/frcpa(1+199/256))/2
+data8 0x3fd285e0842ca384 //log(1/frcpa(1+200/256))/2
+data8 0x3fd294294708b773 //log(1/frcpa(1+201/256))/2
+data8 0x3fd2a9a2670aff0c //log(1/frcpa(1+202/256))/2
+data8 0x3fd2b7fb2c8d1cc1 //log(1/frcpa(1+203/256))/2
+data8 0x3fd2c65a6395f5f5 //log(1/frcpa(1+204/256))/2
+data8 0x3fd2dbf557b0df43 //log(1/frcpa(1+205/256))/2
+data8 0x3fd2ea64c3f97655 //log(1/frcpa(1+206/256))/2
+data8 0x3fd3001823684d73 //log(1/frcpa(1+207/256))/2
+data8 0x3fd30e97e9a8b5cd //log(1/frcpa(1+208/256))/2
+data8 0x3fd32463ebdd34ea //log(1/frcpa(1+209/256))/2
+data8 0x3fd332f4314ad796 //log(1/frcpa(1+210/256))/2
+data8 0x3fd348d90e7464d0 //log(1/frcpa(1+211/256))/2
+data8 0x3fd35779f8c43d6e //log(1/frcpa(1+212/256))/2
+data8 0x3fd36621961a6a99 //log(1/frcpa(1+213/256))/2
+data8 0x3fd37c299f3c366a //log(1/frcpa(1+214/256))/2
+data8 0x3fd38ae2171976e7 //log(1/frcpa(1+215/256))/2
+data8 0x3fd399a157a603e7 //log(1/frcpa(1+216/256))/2
+data8 0x3fd3afccfe77b9d1 //log(1/frcpa(1+217/256))/2
+data8 0x3fd3be9d503533b5 //log(1/frcpa(1+218/256))/2
+data8 0x3fd3cd7480b4a8a3 //log(1/frcpa(1+219/256))/2
+data8 0x3fd3e3c43918f76c //log(1/frcpa(1+220/256))/2
+data8 0x3fd3f2acb27ed6c7 //log(1/frcpa(1+221/256))/2
+data8 0x3fd4019c2125ca93 //log(1/frcpa(1+222/256))/2
+data8 0x3fd4181061389722 //log(1/frcpa(1+223/256))/2
+data8 0x3fd42711518df545 //log(1/frcpa(1+224/256))/2
+data8 0x3fd436194e12b6bf //log(1/frcpa(1+225/256))/2
+data8 0x3fd445285d68ea69 //log(1/frcpa(1+226/256))/2
+data8 0x3fd45bcc464c893a //log(1/frcpa(1+227/256))/2
+data8 0x3fd46aed21f117fc //log(1/frcpa(1+228/256))/2
+data8 0x3fd47a1527e8a2d3 //log(1/frcpa(1+229/256))/2
+data8 0x3fd489445efffccc //log(1/frcpa(1+230/256))/2
+data8 0x3fd4a018bcb69835 //log(1/frcpa(1+231/256))/2
+data8 0x3fd4af5a0c9d65d7 //log(1/frcpa(1+232/256))/2
+data8 0x3fd4bea2a5bdbe87 //log(1/frcpa(1+233/256))/2
+data8 0x3fd4cdf28f10ac46 //log(1/frcpa(1+234/256))/2
+data8 0x3fd4dd49cf994058 //log(1/frcpa(1+235/256))/2
+data8 0x3fd4eca86e64a684 //log(1/frcpa(1+236/256))/2
+data8 0x3fd503c43cd8eb68 //log(1/frcpa(1+237/256))/2
+data8 0x3fd513356667fc57 //log(1/frcpa(1+238/256))/2
+data8 0x3fd522ae0738a3d8 //log(1/frcpa(1+239/256))/2
+data8 0x3fd5322e26867857 //log(1/frcpa(1+240/256))/2
+data8 0x3fd541b5cb979809 //log(1/frcpa(1+241/256))/2
+data8 0x3fd55144fdbcbd62 //log(1/frcpa(1+242/256))/2
+data8 0x3fd560dbc45153c7 //log(1/frcpa(1+243/256))/2
+data8 0x3fd5707a26bb8c66 //log(1/frcpa(1+244/256))/2
+data8 0x3fd587f60ed5b900 //log(1/frcpa(1+245/256))/2
+data8 0x3fd597a7977c8f31 //log(1/frcpa(1+246/256))/2
+data8 0x3fd5a760d634bb8b //log(1/frcpa(1+247/256))/2
+data8 0x3fd5b721d295f10f //log(1/frcpa(1+248/256))/2
+data8 0x3fd5c6ea94431ef9 //log(1/frcpa(1+249/256))/2
+data8 0x3fd5d6bb22ea86f6 //log(1/frcpa(1+250/256))/2
+data8 0x3fd5e6938645d390 //log(1/frcpa(1+251/256))/2
+data8 0x3fd5f673c61a2ed2 //log(1/frcpa(1+252/256))/2
+data8 0x3fd6065bea385926 //log(1/frcpa(1+253/256))/2
+data8 0x3fd6164bfa7cc06b //log(1/frcpa(1+254/256))/2
+data8 0x3fd62643fecf9743 //log(1/frcpa(1+255/256))/2
+LOCAL_OBJECT_END(atanhf_data2)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(atanhf)
+
+{ .mfi
+ getf.exp rArgSExpb = f8
+ fclass.m p9,p0 = f8, 0x0b // is arg denormal ?
+ mov rExpbMask = 0x1ffff
+}
+{ .mfi
+ addl DataPtr = @ltoff(atanhf_data), gp
+ fnma.s1 fOneMx = f8, f1, f1 // 1 - x
+ mov rBias = 0xffff
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p7,p0 = f8, 0xc7 // is arg NaN or +/-0 ?
+ mov rNearZeroBound = 0xffeb // 2^(-20)
+}
+{ .mfi
+ ld8 DataPtr = [DataPtr]
+ fma.s1 fOnePx = f8, f1, f1 // 1 + x
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fnorm.s1 fNormX = f8 // Normalize x
+(p9) br.cond.spnt ATANH_UNORM // Branch if x=unorm
+}
+;;
+
+ATANH_COMMON:
+// Return here if x=unorm and not denorm
+{ .mfi
+ ldfpd fP3, fP2 = [DataPtr], 16
+ fma.s1 fX2 = f8, f8, f0 // x^2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.s.s0 f8 = f8,f1,f8 // NaN or +/-0
+(p7) br.ret.spnt b0
+}
+;;
+
+{ .mfi
+ ldfpd fP1, fHalf = [DataPtr], 16
+ frcpa.s1 fRcpM, p9 = f1, fOneMx // rcpm = frcpa(1 - x)
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.exp rExpbm = fOneMx
+ frcpa.s1 fRcpP, p0 = f1, fOnePx // rcpp = frcpa(1 + x)
+ // biased exponent
+ and rArgExpb = rArgSExpb, rExpbMask
+}
+;;
+
+{ .mmi
+ getf.exp rExpbp = fOnePx
+ // is |x| < 2^(-20) ?
+ cmp.gt p8,p0 = rNearZeroBound, rArgExpb
+ cmp.ge p6,p0 = rArgExpb, rBias // is |x| >= 1 ?
+}
+;;
+
+{ .mmb
+ getf.sig rSigm = fOneMx
+ nop.m 0
+(p6) br.cond.spnt atanhf_ge_one
+}
+;;
+
+{ .mfb
+ getf.sig rSigp = fOnePx
+(p8) fma.s.s0 f8 = fX2, f8, f8 // x + x^3
+(p8) br.ret.spnt b0 // Exit for MAX_DENORM_ABS < |x| < 2^-20
+}
+;;
+
+{ .mfi
+ ldfd fLog2 = [DataPtr], 16
+ fms.s1 fRm = fRcpM, fOneMx, f1 // rm = rcpm * (1 - x) - 1
+ nop.i 0
+}
+;;
+
+{ .mmf
+ // (1 - x) is always positive here and we need not mask sign bit
+ sub rNm = rExpbm, rBias
+ // (1 + x) is always positive here and we need not mask sign bit
+ sub rNp = rExpbp, rBias
+ fms.s1 fRp = fRcpP, fOnePx, f1 // rp = rcpp * (1 + x) - 1
+}
+;;
+
+{ .mmi
+ setf.sig fN4CvtM = rNm
+ setf.sig fN4CvtP = rNp
+ extr.u rIndm = rSigm,55,8 // Extract 8 bits
+}
+;;
+
+{ .mmi
+ shladd RcpTablePtrM = rIndm, 3, DataPtr
+ nop.m 0
+ extr.u rIndp = rSigp,55,8 // Extract 8 bits
+}
+;;
+
+{ .mmi
+ ldfd fLogTm = [RcpTablePtrM]
+ shladd RcpTablePtrP = rIndp, 3, DataPtr
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfd fLogTp = [RcpTablePtrP]
+ fma.s1 fRm2 = fRm, fRm, f0 // rm^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fP32m = fP3, fRm, fP2 // P3*rm + P2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRp2 = fRp, fRp, f0 // rp^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fP10m = fP1, fRm, fHalf // P1*rm + 1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP32p = fP3, fRp, fP2 // P3*rp + P2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fP10p = fP1, fRp, fHalf // P1*rp + 1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf fNm = fN4CvtM
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcvt.xf fNp = fN4CvtP
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // (P3*rm + P2)*rm^2 + (P1*rm + 1)
+ fma.s1 fP32m = fP32m, fRm2, fP10m
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (P3*rp + P2)*rp^2 + (P1*rp + 1)
+ fma.s1 fP32p = fP32p, fRp2, fP10p
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // Nm*ln(2)/2 + Tm/2
+ fma.s1 fLogTm = fNm, fLog2, fLogTm
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // Np*ln(2)/2 + Tp/2
+ fma.s1 fLogTp = fNp, fLog2, fLogTp
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // ((P3*rm + P2)*rm^2 + (P3*rm + 1))*0.5*rm + (Nm*ln(2)/2 + Tm/2)
+ fma.d.s1 fP32m = fP32m, fRm, fLogTm
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // ((P3*rp + P2)*rp^2 + (P3*rp + 1))*0.5*rp + (Np*ln(2)/2 + Tp/2)
+ fma.d.s1 fP32p = fP32p, fRp, fLogTp
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ // atanhf(x) = 0.5 * (log(1 + x) - log(1 - x))
+ fnma.s.s0 f8 = fP32m, f1, fP32p
+ br.ret.sptk b0 // Exit for 2^(-20) <= |x| < 1.0
+}
+;;
+
+
+ATANH_UNORM:
+// Here if x=unorm
+{ .mfi
+ getf.exp rArgSExpb = fNormX // Recompute if x unorm
+ fclass.m p0,p9 = fNormX, 0x0b // Test x denorm
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fcmp.lt.s0 p10,p11 = f8, f0 // Set denormal flag
+(p9) br.cond.sptk ATANH_COMMON // Continue if x unorm and not denorm
+}
+;;
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fnma.s.s0 f8 = f8,f8,f8 // Result x-x^2 if x=-denorm
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.s.s0 f8 = f8,f8,f8 // Result x+x^2 if x=+denorm
+ br.ret.spnt b0 // Exit if denorm
+}
+;;
+
+// Here if |x| >= 1.0
+atanhf_ge_one:
+{ .mfi
+ alloc r32 = ar.pfs,1,3,4,0
+ fmerge.s fArgAbs = f0, f8 // Form |x|
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fmerge.s f10 = f8, f8 // Save input for error call
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s1 p6,p7 = fArgAbs, f1 // Test for |x| = 1.0
+ nop.i 0
+}
+;;
+
+// Set error tag and result, and raise invalid flag if |x| > 1.0
+{ .mfi
+(p7) mov atanh_GR_tag = 133
+(p7) frcpa.s0 f8, p0 = f0, f0 // Get QNaN, and raise invalid
+ nop.i 0
+}
+;;
+
+// Set error tag and result, and raise Z flag if |x| = 1.0
+{ .mfi
+ nop.m 0
+(p6) frcpa.s0 fRm, p0 = f1, f0 // Get inf, and raise Z flag
+ nop.i 0
+}
+;;
+
+{ .mfb
+(p6) mov atanh_GR_tag = 134
+(p6) fmerge.s f8 = f8, fRm // result is +-inf
+ br.cond.sptk __libm_error_region // Exit if |x| >= 1.0
+}
+;;
+
+GLOBAL_LIBM_END(atanhf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfs [GR_Parameter_Y] = f1,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfs [GR_Parameter_X] = f10 // STORE Parameter 1 on stack
+ // Parameter 3 address
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_atanhl.S b/libc/sysdeps/ia64/fpu/e_atanhl.S
new file mode 100644
index 000000000..cee1ba17b
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_atanhl.S
@@ -0,0 +1,1156 @@
+.file "atanhl.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING,BUT NOT
+// LIMITED TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code,and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 09/10/01 Initial version
+// 12/11/01 Corrected .restore syntax
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+//
+//*********************************************************************
+//
+//*********************************************************************
+//
+// Function: atanhl(x) computes the principle value of the inverse
+// hyperbolic tangent of x.
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f33-f73
+//
+// General Purpose Registers:
+// r32-r52
+// r49-r52 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6-p15
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// atanhl(inf) = QNaN
+// atanhl(-inf) = QNaN
+// atanhl(+/-0) = +/-0
+// atanhl(1) = +inf
+// atanhl(-1) = -inf
+// atanhl(|x|>1) = QNaN
+// atanhl(SNaN) = QNaN
+// atanhl(QNaN) = QNaN
+//
+//*********************************************************************
+//
+// Overview
+//
+// The method consists of two cases.
+//
+// If |x| < 1/32 use case atanhl_near_zero;
+// else use case atanhl_regular;
+//
+// Case atanhl_near_zero:
+//
+// atanhl(x) can be approximated by the Taylor series expansion
+// up to order 17.
+//
+// Case atanhl_regular:
+//
+// Here we use formula atanhl(x) = sign(x)*log1pl(2*|x|/(1-|x|))/2 and
+// calculation is subdivided into two stages. The first stage is
+// calculating of X = 2*|x|/(1-|x|). The second one is calculating of
+// sign(x)*log1pl(X)/2. To obtain required accuracy we use precise division
+// algorythm output of which is a pair of two extended precision values those
+// approximate result of division with accuracy higher than working
+// precision. This pair is passed to modified log1pl function.
+//
+//
+// 1. calculating of X = 2*|x|/(1-|x|)
+// ( based on Peter Markstein's "IA-64 and Elementary Functions" book )
+// ********************************************************************
+//
+// a = 2*|x|
+// b = 1 - |x|
+// b_lo = |x| - (1 - b)
+//
+// y = frcpa(b) initial approximation of 1/b
+// q = a*y initial approximation of a/b
+//
+// e = 1 - b*y
+// e2 = e + e^2
+// e1 = e^2
+// y1 = y + y*e2 = y + y*(e+e^2)
+//
+// e3 = e + e1^2
+// y2 = y + y1*e3 = y + y*(e+e^2+..+e^6)
+//
+// r = a - b*q
+// e = 1 - b*y2
+// X = q + r*y2 high part of a/b
+//
+// y3 = y2 + y2*e4
+// r1 = a - b*X
+// r1 = r1 - b_lo*X
+// X_lo = r1*y3 low part of a/b
+//
+// 2. special log1p algorithm overview
+// ***********************************
+//
+// Here we use a table lookup method. The basic idea is that in
+// order to compute logl(Arg) = log1pl (Arg-1) for an argument Arg in [1,2),
+// we construct a value G such that G*Arg is close to 1 and that
+// logl(1/G) is obtainable easily from a table of values calculated
+// beforehand. Thus
+//
+// logl(Arg) = logl(1/G) + logl(G*Arg)
+// = logl(1/G) + logl(1 + (G*Arg - 1))
+//
+// Because |G*Arg - 1| is small, the second term on the right hand
+// side can be approximated by a short polynomial. We elaborate
+// this method in several steps.
+//
+// Step 0: Initialization
+// ------
+// We need to calculate logl(X + X_lo + 1). Obtain N, S_hi such that
+//
+// X + X_lo + 1 = 2^N * ( S_hi + S_lo ) exactly
+//
+// where S_hi in [1,2) and S_lo is a correction to S_hi in the sense
+// that |S_lo| <= ulp(S_hi).
+//
+// For the special version of log1p we add X_lo to S_lo (S_lo = S_lo + X_lo)
+// !-----------------------------------------------------------------------!
+//
+// Step 1: Argument Reduction
+// ------
+// Based on S_hi, obtain G_1, G_2, G_3 from a table and calculate
+//
+// G := G_1 * G_2 * G_3
+// r := (G * S_hi - 1) + G * S_lo
+//
+// These G_j's have the property that the product is exactly
+// representable and that |r| < 2^(-12) as a result.
+//
+// Step 2: Approximation
+// ------
+// logl(1 + r) is approximated by a short polynomial poly(r).
+//
+// Step 3: Reconstruction
+// ------
+// Finally, log1pl(X + X_lo) = logl(X + X_lo + 1) is given by
+//
+// logl(X + X_lo + 1) = logl(2^N * (S_hi + S_lo))
+// ~=~ N*logl(2) + logl(1/G) + logl(1 + r)
+// ~=~ N*logl(2) + logl(1/G) + poly(r).
+//
+// For detailed description see log1p1 function, regular path.
+//
+//*********************************************************************
+
+RODATA
+.align 64
+
+// ************* DO NOT CHANGE THE ORDER OF THESE TABLES *************
+
+LOCAL_OBJECT_START(Constants_TaylorSeries)
+data8 0xF0F0F0F0F0F0F0F1,0x00003FFA // C17
+data8 0x8888888888888889,0x00003FFB // C15
+data8 0x9D89D89D89D89D8A,0x00003FFB // C13
+data8 0xBA2E8BA2E8BA2E8C,0x00003FFB // C11
+data8 0xE38E38E38E38E38E,0x00003FFB // C9
+data8 0x9249249249249249,0x00003FFC // C7
+data8 0xCCCCCCCCCCCCCCCD,0x00003FFC // C5
+data8 0xAAAAAAAAAAAAAAAA,0x00003FFD // C3
+data4 0x3f000000 // 1/2
+data4 0x00000000 // pad
+data4 0x00000000
+data4 0x00000000
+LOCAL_OBJECT_END(Constants_TaylorSeries)
+
+LOCAL_OBJECT_START(Constants_Q)
+data4 0x00000000,0xB1721800,0x00003FFE,0x00000000 // log2_hi
+data4 0x4361C4C6,0x82E30865,0x0000BFE2,0x00000000 // log2_lo
+data4 0x328833CB,0xCCCCCAF2,0x00003FFC,0x00000000 // Q4
+data4 0xA9D4BAFB,0x80000077,0x0000BFFD,0x00000000 // Q3
+data4 0xAAABE3D2,0xAAAAAAAA,0x00003FFD,0x00000000 // Q2
+data4 0xFFFFDAB7,0xFFFFFFFF,0x0000BFFD,0x00000000 // Q1
+LOCAL_OBJECT_END(Constants_Q)
+
+
+// Z1 - 16 bit fixed
+LOCAL_OBJECT_START(Constants_Z_1)
+data4 0x00008000
+data4 0x00007879
+data4 0x000071C8
+data4 0x00006BCB
+data4 0x00006667
+data4 0x00006187
+data4 0x00005D18
+data4 0x0000590C
+data4 0x00005556
+data4 0x000051EC
+data4 0x00004EC5
+data4 0x00004BDB
+data4 0x00004925
+data4 0x0000469F
+data4 0x00004445
+data4 0x00004211
+LOCAL_OBJECT_END(Constants_Z_1)
+
+// G1 and H1 - IEEE single and h1 - IEEE double
+LOCAL_OBJECT_START(Constants_G_H_h1)
+data4 0x3F800000,0x00000000
+data8 0x0000000000000000
+data4 0x3F70F0F0,0x3D785196
+data8 0x3DA163A6617D741C
+data4 0x3F638E38,0x3DF13843
+data8 0x3E2C55E6CBD3D5BB
+data4 0x3F579430,0x3E2FF9A0
+data8 0xBE3EB0BFD86EA5E7
+data4 0x3F4CCCC8,0x3E647FD6
+data8 0x3E2E6A8C86B12760
+data4 0x3F430C30,0x3E8B3AE7
+data8 0x3E47574C5C0739BA
+data4 0x3F3A2E88,0x3EA30C68
+data8 0x3E20E30F13E8AF2F
+data4 0x3F321640,0x3EB9CEC8
+data8 0xBE42885BF2C630BD
+data4 0x3F2AAAA8,0x3ECF9927
+data8 0x3E497F3497E577C6
+data4 0x3F23D708,0x3EE47FC5
+data8 0x3E3E6A6EA6B0A5AB
+data4 0x3F1D89D8,0x3EF8947D
+data8 0xBDF43E3CD328D9BE
+data4 0x3F17B420,0x3F05F3A1
+data8 0x3E4094C30ADB090A
+data4 0x3F124920,0x3F0F4303
+data8 0xBE28FBB2FC1FE510
+data4 0x3F0D3DC8,0x3F183EBF
+data8 0x3E3A789510FDE3FA
+data4 0x3F088888,0x3F20EC80
+data8 0x3E508CE57CC8C98F
+data4 0x3F042108,0x3F29516A
+data8 0xBE534874A223106C
+LOCAL_OBJECT_END(Constants_G_H_h1)
+
+// Z2 - 16 bit fixed
+LOCAL_OBJECT_START(Constants_Z_2)
+data4 0x00008000
+data4 0x00007F81
+data4 0x00007F02
+data4 0x00007E85
+data4 0x00007E08
+data4 0x00007D8D
+data4 0x00007D12
+data4 0x00007C98
+data4 0x00007C20
+data4 0x00007BA8
+data4 0x00007B31
+data4 0x00007ABB
+data4 0x00007A45
+data4 0x000079D1
+data4 0x0000795D
+data4 0x000078EB
+LOCAL_OBJECT_END(Constants_Z_2)
+
+// G2 and H2 - IEEE single and h2 - IEEE double
+LOCAL_OBJECT_START(Constants_G_H_h2)
+data4 0x3F800000,0x00000000
+data8 0x0000000000000000
+data4 0x3F7F00F8,0x3B7F875D
+data8 0x3DB5A11622C42273
+data4 0x3F7E03F8,0x3BFF015B
+data8 0x3DE620CF21F86ED3
+data4 0x3F7D08E0,0x3C3EE393
+data8 0xBDAFA07E484F34ED
+data4 0x3F7C0FC0,0x3C7E0586
+data8 0xBDFE07F03860BCF6
+data4 0x3F7B1880,0x3C9E75D2
+data8 0x3DEA370FA78093D6
+data4 0x3F7A2328,0x3CBDC97A
+data8 0x3DFF579172A753D0
+data4 0x3F792FB0,0x3CDCFE47
+data8 0x3DFEBE6CA7EF896B
+data4 0x3F783E08,0x3CFC15D0
+data8 0x3E0CF156409ECB43
+data4 0x3F774E38,0x3D0D874D
+data8 0xBE0B6F97FFEF71DF
+data4 0x3F766038,0x3D1CF49B
+data8 0xBE0804835D59EEE8
+data4 0x3F757400,0x3D2C531D
+data8 0x3E1F91E9A9192A74
+data4 0x3F748988,0x3D3BA322
+data8 0xBE139A06BF72A8CD
+data4 0x3F73A0D0,0x3D4AE46F
+data8 0x3E1D9202F8FBA6CF
+data4 0x3F72B9D0,0x3D5A1756
+data8 0xBE1DCCC4BA796223
+data4 0x3F71D488,0x3D693B9D
+data8 0xBE049391B6B7C239
+LOCAL_OBJECT_END(Constants_G_H_h2)
+
+// G3 and H3 - IEEE single and h3 - IEEE double
+LOCAL_OBJECT_START(Constants_G_H_h3)
+data4 0x3F7FFC00,0x38800100
+data8 0x3D355595562224CD
+data4 0x3F7FF400,0x39400480
+data8 0x3D8200A206136FF6
+data4 0x3F7FEC00,0x39A00640
+data8 0x3DA4D68DE8DE9AF0
+data4 0x3F7FE400,0x39E00C41
+data8 0xBD8B4291B10238DC
+data4 0x3F7FDC00,0x3A100A21
+data8 0xBD89CCB83B1952CA
+data4 0x3F7FD400,0x3A300F22
+data8 0xBDB107071DC46826
+data4 0x3F7FCC08,0x3A4FF51C
+data8 0x3DB6FCB9F43307DB
+data4 0x3F7FC408,0x3A6FFC1D
+data8 0xBD9B7C4762DC7872
+data4 0x3F7FBC10,0x3A87F20B
+data8 0xBDC3725E3F89154A
+data4 0x3F7FB410,0x3A97F68B
+data8 0xBD93519D62B9D392
+data4 0x3F7FAC18,0x3AA7EB86
+data8 0x3DC184410F21BD9D
+data4 0x3F7FA420,0x3AB7E101
+data8 0xBDA64B952245E0A6
+data4 0x3F7F9C20,0x3AC7E701
+data8 0x3DB4B0ECAABB34B8
+data4 0x3F7F9428,0x3AD7DD7B
+data8 0x3D9923376DC40A7E
+data4 0x3F7F8C30,0x3AE7D474
+data8 0x3DC6E17B4F2083D3
+data4 0x3F7F8438,0x3AF7CBED
+data8 0x3DAE314B811D4394
+data4 0x3F7F7C40,0x3B03E1F3
+data8 0xBDD46F21B08F2DB1
+data4 0x3F7F7448,0x3B0BDE2F
+data8 0xBDDC30A46D34522B
+data4 0x3F7F6C50,0x3B13DAAA
+data8 0x3DCB0070B1F473DB
+data4 0x3F7F6458,0x3B1BD766
+data8 0xBDD65DDC6AD282FD
+data4 0x3F7F5C68,0x3B23CC5C
+data8 0xBDCDAB83F153761A
+data4 0x3F7F5470,0x3B2BC997
+data8 0xBDDADA40341D0F8F
+data4 0x3F7F4C78,0x3B33C711
+data8 0x3DCD1BD7EBC394E8
+data4 0x3F7F4488,0x3B3BBCC6
+data8 0xBDC3532B52E3E695
+data4 0x3F7F3C90,0x3B43BAC0
+data8 0xBDA3961EE846B3DE
+data4 0x3F7F34A0,0x3B4BB0F4
+data8 0xBDDADF06785778D4
+data4 0x3F7F2CA8,0x3B53AF6D
+data8 0x3DCC3ED1E55CE212
+data4 0x3F7F24B8,0x3B5BA620
+data8 0xBDBA31039E382C15
+data4 0x3F7F1CC8,0x3B639D12
+data8 0x3D635A0B5C5AF197
+data4 0x3F7F14D8,0x3B6B9444
+data8 0xBDDCCB1971D34EFC
+data4 0x3F7F0CE0,0x3B7393BC
+data8 0x3DC7450252CD7ADA
+data4 0x3F7F04F0,0x3B7B8B6D
+data8 0xBDB68F177D7F2A42
+LOCAL_OBJECT_END(Constants_G_H_h3)
+
+
+
+// Floating Point Registers
+
+FR_C17 = f50
+FR_C15 = f51
+FR_C13 = f52
+FR_C11 = f53
+FR_C9 = f54
+FR_C7 = f55
+FR_C5 = f56
+FR_C3 = f57
+FR_x2 = f58
+FR_x3 = f59
+FR_x4 = f60
+FR_x8 = f61
+
+FR_Rcp = f61
+
+FR_A = f33
+FR_R1 = f33
+
+FR_E1 = f34
+FR_E3 = f34
+FR_Y2 = f34
+FR_Y3 = f34
+
+FR_E2 = f35
+FR_Y1 = f35
+
+FR_B = f36
+FR_Y0 = f37
+FR_E0 = f38
+FR_E4 = f39
+FR_Q0 = f40
+FR_R0 = f41
+FR_B_lo = f42
+
+FR_abs_x = f43
+FR_Bp = f44
+FR_Bn = f45
+FR_Yp = f46
+FR_Yn = f47
+
+FR_X = f48
+FR_BB = f48
+FR_X_lo = f49
+
+FR_G = f50
+FR_Y_hi = f51
+FR_H = f51
+FR_h = f52
+FR_G2 = f53
+FR_H2 = f54
+FR_h2 = f55
+FR_G3 = f56
+FR_H3 = f57
+FR_h3 = f58
+
+FR_Q4 = f59
+FR_poly_lo = f59
+FR_Y_lo = f59
+
+FR_Q3 = f60
+FR_Q2 = f61
+
+FR_Q1 = f62
+FR_poly_hi = f62
+
+FR_float_N = f63
+
+FR_AA = f64
+FR_S_lo = f64
+
+FR_S_hi = f65
+FR_r = f65
+
+FR_log2_hi = f66
+FR_log2_lo = f67
+FR_Z = f68
+FR_2_to_minus_N = f69
+FR_rcub = f70
+FR_rsq = f71
+FR_05r = f72
+FR_Half = f73
+
+FR_Arg_X = f50
+FR_Arg_Y = f0
+FR_RESULT = f8
+
+
+
+// General Purpose Registers
+
+GR_ad_05 = r33
+GR_Index1 = r34
+GR_ArgExp = r34
+GR_Index2 = r35
+GR_ExpMask = r35
+GR_NearZeroBound = r36
+GR_signif = r36
+GR_X_0 = r37
+GR_X_1 = r37
+GR_X_2 = r38
+GR_Index3 = r38
+GR_minus_N = r39
+GR_Z_1 = r40
+GR_Z_2 = r40
+GR_N = r41
+GR_Bias = r42
+GR_M = r43
+GR_ad_taylor = r44
+GR_ad_taylor_2 = r45
+GR_ad2_tbl_3 = r45
+GR_ad_tbl_1 = r46
+GR_ad_tbl_2 = r47
+GR_ad_tbl_3 = r48
+GR_ad_q = r49
+GR_ad_z_1 = r50
+GR_ad_z_2 = r51
+GR_ad_z_3 = r52
+
+//
+// Added for unwind support
+//
+GR_SAVE_PFS = r46
+GR_SAVE_B0 = r47
+GR_SAVE_GP = r48
+GR_Parameter_X = r49
+GR_Parameter_Y = r50
+GR_Parameter_RESULT = r51
+GR_Parameter_TAG = r52
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(atanhl)
+
+{ .mfi
+ alloc r32 = ar.pfs,0,17,4,0
+ fnma.s1 FR_Bp = f8,f1,f1 // b = 1 - |arg| (for x>0)
+ mov GR_ExpMask = 0x1ffff
+}
+{ .mfi
+ addl GR_ad_taylor = @ltoff(Constants_TaylorSeries),gp
+ fma.s1 FR_Bn = f8,f1,f1 // b = 1 - |arg| (for x<0)
+ mov GR_NearZeroBound = 0xfffa // biased exp of 1/32
+};;
+{ .mfi
+ getf.exp GR_ArgExp = f8
+ fcmp.lt.s1 p6,p7 = f8,f0 // is negative?
+ nop.i 0
+}
+{ .mfi
+ ld8 GR_ad_taylor = [GR_ad_taylor]
+ fmerge.s FR_abs_x = f1,f8
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fclass.m p8,p0 = f8,0x1C7 // is arg NaT,Q/SNaN or +/-0 ?
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_x2 = f8,f8,f0
+ nop.i 0
+};;
+{ .mfi
+ add GR_ad_z_1 = 0x0F0,GR_ad_taylor
+ fclass.m p9,p0 = f8,0x0a // is arg -denormal ?
+ add GR_ad_taylor_2 = 0x010,GR_ad_taylor
+}
+{ .mfi
+ add GR_ad_05 = 0x080,GR_ad_taylor
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_C17 = [GR_ad_taylor],32
+ fclass.m p10,p0 = f8,0x09 // is arg +denormal ?
+ add GR_ad_tbl_1 = 0x040,GR_ad_z_1 // point to Constants_G_H_h1
+}
+{ .mfb
+ add GR_ad_z_2 = 0x140,GR_ad_z_1 // point to Constants_Z_2
+ (p8) fma.s0 f8 = f8,f1,f0 // NaN or +/-0
+ (p8) br.ret.spnt b0 // exit for Nan or +/-0
+};;
+{ .mfi
+ ldfe FR_C15 = [GR_ad_taylor_2],32
+ fclass.m p15,p0 = f8,0x23 // is +/-INF ?
+ add GR_ad_tbl_2 = 0x180,GR_ad_z_1 // point to Constants_G_H_h2
+}
+{ .mfb
+ ldfe FR_C13 = [GR_ad_taylor],32
+ (p9) fnma.s0 f8 = f8,f8,f8 // -denormal
+ (p9) br.ret.spnt b0 // exit for -denormal
+};;
+{ .mfi
+ ldfe FR_C11 = [GR_ad_taylor_2],32
+ fcmp.eq.s0 p13,p0 = FR_abs_x,f1 // is |arg| = 1?
+ nop.i 0
+}
+{ .mfb
+ ldfe FR_C9 = [GR_ad_taylor],32
+(p10) fma.s0 f8 = f8,f8,f8 // +denormal
+(p10) br.ret.spnt b0 // exit for +denormal
+};;
+{ .mfi
+ ldfe FR_C7 = [GR_ad_taylor_2],32
+ (p6) frcpa.s1 FR_Yn,p11 = f1,FR_Bn // y = frcpa(b)
+ and GR_ArgExp = GR_ArgExp,GR_ExpMask // biased exponent
+}
+{ .mfb
+ ldfe FR_C5 = [GR_ad_taylor],32
+ fnma.s1 FR_B = FR_abs_x,f1,f1 // b = 1 - |arg|
+(p15) br.cond.spnt atanhl_gt_one // |arg| > 1
+};;
+{ .mfb
+ cmp.gt p14,p0 = GR_NearZeroBound,GR_ArgExp
+ (p7) frcpa.s1 FR_Yp,p12 = f1,FR_Bp // y = frcpa(b)
+(p13) br.cond.spnt atanhl_eq_one // |arg| = 1/32
+}
+{ .mfb
+ ldfe FR_C3 = [GR_ad_taylor_2],32
+ fma.s1 FR_A = FR_abs_x,f1,FR_abs_x // a = 2 * |arg|
+(p14) br.cond.spnt atanhl_near_zero // |arg| < 1/32
+};;
+{ .mfi
+ nop.m 0
+ fcmp.gt.s0 p8,p0 = FR_abs_x,f1 // is |arg| > 1 ?
+ nop.i 0
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+ (p6) fnma.s1 FR_B_lo = FR_Bn,f1,f1 // argt = 1 - (1 - |arg|)
+ nop.i 0
+}
+{ .mfi
+ ldfs FR_Half = [GR_ad_05]
+ (p7) fnma.s1 FR_B_lo = FR_Bp,f1,f1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ (p6) fnma.s1 FR_E0 = FR_Yn,FR_Bn,f1 // e = 1-b*y
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ (p6) fma.s1 FR_Y0 = FR_Yn,f1,f0
+ (p8) br.cond.spnt atanhl_gt_one // |arg| > 1
+};;
+{ .mfi
+ nop.m 0
+ (p7) fnma.s1 FR_E0 = FR_Yp,FR_Bp,f1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ (p6) fma.s1 FR_Q0 = FR_A,FR_Yn,f0 // q = a*y
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ (p7) fma.s1 FR_Q0 = FR_A,FR_Yp,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ (p7) fma.s1 FR_Y0 = FR_Yp,f1,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fclass.nm p10,p0 = f8,0x1FF // test for unsupported
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_E2 = FR_E0,FR_E0,FR_E0 // e2 = e+e^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_E1 = FR_E0,FR_E0,f0 // e1 = e^2
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+// Return generated NaN or other value for unsupported values.
+(p10) fma.s0 f8 = f8, f0, f0
+(p10) br.ret.spnt b0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Y1 = FR_Y0,FR_E2,FR_Y0 // y1 = y+y*e2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_E3 = FR_E1,FR_E1,FR_E0 // e3 = e+e1^2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_B_lo = FR_abs_x,f1,FR_B_lo // b_lo = argt-|arg|
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Y2 = FR_Y1,FR_E3,FR_Y0 // y2 = y+y1*e3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_R0 = FR_B,FR_Q0,FR_A // r = a-b*q
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_E4 = FR_B,FR_Y2,f1 // e4 = 1-b*y2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_X = FR_R0,FR_Y2,FR_Q0 // x = q+r*y2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Z = FR_X,f1,f1 // x+1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ (p6) fnma.s1 FR_Half = FR_Half,f1,f0 // sign(arg)/2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Y3 = FR_Y2,FR_E4,FR_Y2 // y3 = y2+y2*e4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_R1 = FR_B,FR_X,FR_A // r1 = a-b*x
+ nop.i 0
+};;
+{ .mfi
+ getf.sig GR_signif = FR_Z // get significand of x+1
+ nop.f 0
+ nop.i 0
+};;
+
+
+{ .mfi
+ add GR_ad_q = -0x060,GR_ad_z_1
+ nop.f 0
+ extr.u GR_Index1 = GR_signif,59,4 // get high 4 bits of signif
+}
+{ .mfi
+ add GR_ad_tbl_3 = 0x280,GR_ad_z_1 // point to Constants_G_H_h3
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ shladd GR_ad_z_1 = GR_Index1,2,GR_ad_z_1 // point to Z_1
+ nop.f 0
+ extr.u GR_X_0 = GR_signif,49,15 // get high 15 bits of significand
+};;
+{ .mfi
+ ld4 GR_Z_1 = [GR_ad_z_1] // load Z_1
+ fmax.s1 FR_AA = FR_X,f1 // for S_lo,form AA = max(X,1.0)
+ nop.i 0
+}
+{ .mfi
+ shladd GR_ad_tbl_1 = GR_Index1,4,GR_ad_tbl_1 // point to G_1
+ nop.f 0
+ mov GR_Bias = 0x0FFFF // exponent bias
+};;
+{ .mfi
+ ldfps FR_G,FR_H = [GR_ad_tbl_1],8 // load G_1,H_1
+ fmerge.se FR_S_hi = f1,FR_Z // form |x+1|
+ nop.i 0
+};;
+{ .mfi
+ getf.exp GR_N = FR_Z // get N = exponent of x+1
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfd FR_h = [GR_ad_tbl_1] // load h_1
+ fnma.s1 FR_R1 = FR_B_lo,FR_X,FR_R1 // r1 = r1-b_lo*x
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_log2_hi = [GR_ad_q],16 // load log2_hi
+ nop.f 0
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15 // get bits 30-15 of X_0 * Z_1
+};;
+//
+// For performance,don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mfi
+ ldfe FR_log2_lo = [GR_ad_q],16 // load log2_lo
+ nop.f 0
+ sub GR_N = GR_N,GR_Bias
+};;
+{ .mfi
+ ldfe FR_Q4 = [GR_ad_q],16 // load Q4
+ fms.s1 FR_S_lo = FR_AA,f1,FR_Z // form S_lo = AA - Z
+ sub GR_minus_N = GR_Bias,GR_N // form exponent of 2^(-N)
+};;
+{ .mmf
+ ldfe FR_Q3 = [GR_ad_q],16 // load Q3
+ // put integer N into rightmost significand
+ setf.sig FR_float_N = GR_N
+ fmin.s1 FR_BB = FR_X,f1 // for S_lo,form BB = min(X,1.0)
+};;
+{ .mfi
+ ldfe FR_Q2 = [GR_ad_q],16 // load Q2
+ nop.f 0
+ extr.u GR_Index2 = GR_X_1,6,4 // extract bits 6-9 of X_1
+};;
+{ .mmi
+ ldfe FR_Q1 = [GR_ad_q] // load Q1
+ shladd GR_ad_z_2 = GR_Index2,2,GR_ad_z_2 // point to Z_2
+ nop.i 0
+};;
+{ .mmi
+ ld4 GR_Z_2 = [GR_ad_z_2] // load Z_2
+ shladd GR_ad_tbl_2 = GR_Index2,4,GR_ad_tbl_2 // point to G_2
+ nop.i 0
+};;
+{ .mfi
+ ldfps FR_G2,FR_H2 = [GR_ad_tbl_2],8 // load G_2,H_2
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ ldfd FR_h2 = [GR_ad_tbl_2] // load h_2
+ fma.s1 FR_S_lo = FR_S_lo,f1,FR_BB // S_lo = S_lo + BB
+ nop.i 0
+}
+{ .mfi
+ setf.exp FR_2_to_minus_N = GR_minus_N // form 2^(-N)
+ fma.s1 FR_X_lo = FR_R1,FR_Y3,f0 // x_lo = r1*y3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ nop.f 0
+ pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15 // get bits 30-15 of X_1 * Z_2
+};;
+//
+// For performance,don't use result of pmpyshr2.u for 4 cycles
+//
+{ .mfi
+ add GR_ad2_tbl_3 = 8,GR_ad_tbl_3
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+
+//
+// Now GR_X_2 can be used
+//
+{ .mfi
+ nop.m 0
+ nop.f 0
+ extr.u GR_Index3 = GR_X_2,1,5 // extract bits 1-5 of X_2
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S_lo = FR_S_lo,f1,FR_X_lo // S_lo = S_lo + Arg_lo
+ nop.i 0
+};;
+
+{ .mfi
+ shladd GR_ad_tbl_3 = GR_Index3,4,GR_ad_tbl_3 // point to G_3
+ fcvt.xf FR_float_N = FR_float_N
+ nop.i 0
+}
+{ .mfi
+ shladd GR_ad2_tbl_3 = GR_Index3,4,GR_ad2_tbl_3 // point to h_3
+ fma.s1 FR_Q1 = FR_Q1,FR_Half,f0 // sign(arg)*Q1/2
+ nop.i 0
+};;
+{ .mmi
+ ldfps FR_G3,FR_H3 = [GR_ad_tbl_3],8 // load G_3,H_3
+ ldfd FR_h3 = [GR_ad2_tbl_3] // load h_3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_G = FR_G,FR_G2 // G = G_1 * G_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H,FR_H2 // H = H_1 + H_2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_h = FR_h,FR_h2 // h = h_1 + h_2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ // S_lo = S_lo * 2^(-N)
+ fma.s1 FR_S_lo = FR_S_lo,FR_2_to_minus_N,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_G = FR_G,FR_G3 // G = (G_1 * G_2) * G_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H,FR_H3 // H = (H_1 + H_2) + H_3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_h = FR_h,FR_h3 // h = (h_1 + h_2) + h_3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r = FR_G,FR_S_hi,f1 // r = G * S_hi - 1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // Y_hi = N * log2_hi + H
+ fma.s1 FR_Y_hi = FR_float_N,FR_log2_hi,FR_H
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_h = FR_float_N,FR_log2_lo,FR_h // h = N * log2_lo + h
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r = FR_G,FR_S_lo,FR_r // r = G * S_lo + (G * S_hi - 1)
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_lo = FR_r,FR_Q4,FR_Q3 // poly_lo = r * Q4 + Q3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_rsq = FR_r,FR_r // rsq = r * r
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_05r = FR_r,FR_Half,f0 // sign(arg)*r/2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo * r + Q2
+ fma.s1 FR_poly_lo = FR_poly_lo,FR_r,FR_Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rcub = FR_rsq,FR_r,f0 // rcub = r^3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ // poly_hi = sing(arg)*(Q1*r^2 + r)/2
+ fma.s1 FR_poly_hi = FR_Q1,FR_rsq,FR_05r
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo*r^3 + h
+ fma.s1 FR_poly_lo = FR_poly_lo,FR_rcub,FR_h
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ // Y_lo = poly_hi + poly_lo/2
+ fma.s0 FR_Y_lo = FR_poly_lo,FR_Half,FR_poly_hi
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ // Result = arctanh(x) = Y_hi/2 + Y_lo
+ fma.s0 f8 = FR_Y_hi,FR_Half,FR_Y_lo
+ br.ret.sptk b0
+};;
+
+// Taylor's series
+atanhl_near_zero:
+{ .mfi
+ nop.m 0
+ fma.s1 FR_x3 = FR_x2,f8,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_x4 = FR_x2,FR_x2,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C17 = FR_C17,FR_x2,FR_C15
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C13 = FR_C13,FR_x2,FR_C11
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C9 = FR_C9,FR_x2,FR_C7
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C5 = FR_C5,FR_x2,FR_C3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_x8 = FR_x4,FR_x4,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C17 = FR_C17,FR_x4,FR_C13
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C9 = FR_C9,FR_x4,FR_C5
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C17 = FR_C17,FR_x8,FR_C9
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ fma.s0 f8 = FR_C17,FR_x3,f8
+ br.ret.sptk b0
+};;
+
+atanhl_eq_one:
+{ .mfi
+ nop.m 0
+ frcpa.s0 FR_Rcp,p0 = f1,f0 // get inf,and raise Z flag
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmerge.s FR_Arg_X = f8, f8
+ nop.i 0
+};;
+{ .mfb
+ mov GR_Parameter_TAG = 130
+ fmerge.s FR_RESULT = f8,FR_Rcp // result is +-inf
+ br.cond.sptk __libm_error_region // exit if |x| = 1.0
+};;
+
+atanhl_gt_one:
+{ .mfi
+ nop.m 0
+ fmerge.s FR_Arg_X = f8, f8
+ nop.i 0
+};;
+{ .mfb
+ mov GR_Parameter_TAG = 129
+ frcpa.s0 FR_RESULT,p0 = f0,f0 // get QNaN,and raise invalid
+ br.cond.sptk __libm_error_region // exit if |x| > 1.0
+};;
+
+GLOBAL_LIBM_END(atanhl)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Arg_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0,GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_Arg_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region#)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_cosh.S b/libc/sysdeps/ia64/fpu/e_cosh.S
new file mode 100644
index 000000000..885456b38
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_cosh.S
@@ -0,0 +1,866 @@
+.file "cosh.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 05/07/01 Reworked to improve speed of all paths
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 11/15/02 Improved speed with new algorithm
+// 03/31/05 Reformatted delimiters between data tables
+
+// API
+//==============================================================
+// double cosh(double)
+
+// Overview of operation
+//==============================================================
+// Case 1: 0 < |x| < 0.25
+// Evaluate cosh(x) by a 12th order polynomial
+// Care is take for the order of multiplication; and A2 is not exactly 1/4!,
+// A3 is not exactly 1/6!, etc.
+// cosh(x) = 1 + (A1*x^2 + A2*x^4 + A3*x^6 + A4*x^8 + A5*x^10 + A6*x^12)
+//
+// Case 2: 0.25 < |x| < 710.47586
+// Algorithm is based on the identity cosh(x) = ( exp(x) + exp(-x) ) / 2.
+// The algorithm for exp is described as below. There are a number of
+// economies from evaluating both exp(x) and exp(-x). Although we
+// are evaluating both quantities, only where the quantities diverge do we
+// duplicate the computations. The basic algorithm for exp(x) is described
+// below.
+//
+// Take the input x. w is "how many log2/128 in x?"
+// w = x * 128/log2
+// n = int(w)
+// x = n log2/128 + r + delta
+
+// n = 128M + index_1 + 2^4 index_2
+// x = M log2 + (log2/128) index_1 + (log2/8) index_2 + r + delta
+
+// exp(x) = 2^M 2^(index_1/128) 2^(index_2/8) exp(r) exp(delta)
+// Construct 2^M
+// Get 2^(index_1/128) from table_1;
+// Get 2^(index_2/8) from table_2;
+// Calculate exp(r) by 5th order polynomial
+// r = x - n (log2/128)_high
+// delta = - n (log2/128)_low
+// Calculate exp(delta) as 1 + delta
+
+
+// Special values
+//==============================================================
+// cosh(+0) = 1.0
+// cosh(-0) = 1.0
+
+// cosh(+qnan) = +qnan
+// cosh(-qnan) = -qnan
+// cosh(+snan) = +qnan
+// cosh(-snan) = -qnan
+
+// cosh(-inf) = +inf
+// cosh(+inf) = +inf
+
+// Overflow and Underflow
+//=======================
+// cosh(x) = largest double normal when
+// x = 710.47586 = 0x408633ce8fb9f87d
+//
+// There is no underflow.
+
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input, output
+// f6 -> f15, f32 -> f61
+
+// General registers used:
+// r14 -> r40
+
+// Predicate registers used:
+// p6 -> p15
+
+// Assembly macros
+//==============================================================
+
+rRshf = r14
+rN_neg = r14
+rAD_TB1 = r15
+rAD_TB2 = r16
+rAD_P = r17
+rN = r18
+rIndex_1 = r19
+rIndex_2_16 = r20
+rM = r21
+rBiased_M = r21
+rSig_inv_ln2 = r22
+rIndex_1_neg = r22
+rExp_bias = r23
+rExp_bias_minus_1 = r23
+rExp_mask = r24
+rTmp = r24
+rGt_ln = r24
+rIndex_2_16_neg = r24
+rM_neg = r25
+rBiased_M_neg = r25
+rRshf_2to56 = r26
+rAD_T1_neg = r26
+rExp_2tom56 = r28
+rAD_T2_neg = r28
+rAD_T1 = r29
+rAD_T2 = r30
+rSignexp_x = r31
+rExp_x = r31
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+fRSHF_2TO56 = f6
+fINV_LN2_2TO63 = f7
+fW_2TO56_RSH = f9
+f2TOM56 = f11
+fP5 = f12
+fP4 = f13
+fP3 = f14
+fP2 = f15
+
+fLn2_by_128_hi = f33
+fLn2_by_128_lo = f34
+
+fRSHF = f35
+fNfloat = f36
+fNormX = f37
+fR = f38
+fF = f39
+
+fRsq = f40
+f2M = f41
+fS1 = f42
+fT1 = f42
+fS2 = f43
+fT2 = f43
+fS = f43
+fWre_urm_f8 = f44
+fAbsX = f44
+
+fMIN_DBL_OFLOW_ARG = f45
+fMAX_DBL_NORM_ARG = f46
+fXsq = f47
+fX4 = f48
+fGt_pln = f49
+fTmp = f49
+
+fP54 = f50
+fP5432 = f50
+fP32 = f51
+fP = f52
+fP54_neg = f53
+fP5432_neg = f53
+fP32_neg = f54
+fP_neg = f55
+fF_neg = f56
+
+f2M_neg = f57
+fS1_neg = f58
+fT1_neg = f58
+fS2_neg = f59
+fT2_neg = f59
+fS_neg = f59
+fExp = f60
+fExp_neg = f61
+
+fA6 = f50
+fA65 = f50
+fA6543 = f50
+fA654321 = f50
+fA5 = f51
+fA4 = f52
+fA43 = f52
+fA3 = f53
+fA2 = f54
+fA21 = f54
+fA1 = f55
+
+// Data tables
+//==============================================================
+
+RODATA
+.align 16
+
+// ************* DO NOT CHANGE ORDER OF THESE TABLES ********************
+
+// double-extended 1/ln(2)
+// 3fff b8aa 3b29 5c17 f0bb be87fed0691d3e88
+// 3fff b8aa 3b29 5c17 f0bc
+// For speed the significand will be loaded directly with a movl and setf.sig
+// and the exponent will be bias+63 instead of bias+0. Thus subsequent
+// computations need to scale appropriately.
+// The constant 128/ln(2) is needed for the computation of w. This is also
+// obtained by scaling the computations.
+//
+// Two shifting constants are loaded directly with movl and setf.d.
+// 1. fRSHF_2TO56 = 1.1000..00 * 2^(63-7)
+// This constant is added to x*1/ln2 to shift the integer part of
+// x*128/ln2 into the rightmost bits of the significand.
+// The result of this fma is fW_2TO56_RSH.
+// 2. fRSHF = 1.1000..00 * 2^(63)
+// This constant is subtracted from fW_2TO56_RSH * 2^(-56) to give
+// the integer part of w, n, as a floating-point number.
+// The result of this fms is fNfloat.
+
+
+LOCAL_OBJECT_START(exp_table_1)
+data8 0x408633ce8fb9f87e // smallest dbl overflow arg
+data8 0x408633ce8fb9f87d // largest dbl arg to give normal dbl result
+data8 0xb17217f7d1cf79ab , 0x00003ff7 // ln2/128 hi
+data8 0xc9e3b39803f2f6af , 0x00003fb7 // ln2/128 lo
+//
+// Table 1 is 2^(index_1/128) where
+// index_1 goes from 0 to 15
+//
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x80B1ED4FD999AB6C , 0x00003FFF
+data8 0x8164D1F3BC030773 , 0x00003FFF
+data8 0x8218AF4373FC25EC , 0x00003FFF
+data8 0x82CD8698AC2BA1D7 , 0x00003FFF
+data8 0x8383594EEFB6EE37 , 0x00003FFF
+data8 0x843A28C3ACDE4046 , 0x00003FFF
+data8 0x84F1F656379C1A29 , 0x00003FFF
+data8 0x85AAC367CC487B15 , 0x00003FFF
+data8 0x8664915B923FBA04 , 0x00003FFF
+data8 0x871F61969E8D1010 , 0x00003FFF
+data8 0x87DB357FF698D792 , 0x00003FFF
+data8 0x88980E8092DA8527 , 0x00003FFF
+data8 0x8955EE03618E5FDD , 0x00003FFF
+data8 0x8A14D575496EFD9A , 0x00003FFF
+data8 0x8AD4C6452C728924 , 0x00003FFF
+LOCAL_OBJECT_END(exp_table_1)
+
+// Table 2 is 2^(index_1/8) where
+// index_2 goes from 0 to 7
+LOCAL_OBJECT_START(exp_table_2)
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x8B95C1E3EA8BD6E7 , 0x00003FFF
+data8 0x9837F0518DB8A96F , 0x00003FFF
+data8 0xA5FED6A9B15138EA , 0x00003FFF
+data8 0xB504F333F9DE6484 , 0x00003FFF
+data8 0xC5672A115506DADD , 0x00003FFF
+data8 0xD744FCCAD69D6AF4 , 0x00003FFF
+data8 0xEAC0C6E7DD24392F , 0x00003FFF
+LOCAL_OBJECT_END(exp_table_2)
+
+LOCAL_OBJECT_START(exp_p_table)
+data8 0x3f8111116da21757 //P5
+data8 0x3fa55555d787761c //P4
+data8 0x3fc5555555555414 //P3
+data8 0x3fdffffffffffd6a //P2
+LOCAL_OBJECT_END(exp_p_table)
+
+LOCAL_OBJECT_START(cosh_p_table)
+data8 0x8FA02AC65BCBD5BC, 0x00003FE2 // A6
+data8 0xD00D00D1021D7370, 0x00003FEF // A4
+data8 0xAAAAAAAAAAAAAB80, 0x00003FFA // A2
+data8 0x93F27740C0C2F1CC, 0x00003FE9 // A5
+data8 0xB60B60B60B4FE884, 0x00003FF5 // A3
+data8 0x8000000000000000, 0x00003FFE // A1
+LOCAL_OBJECT_END(cosh_p_table)
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(cosh)
+
+{ .mlx
+ getf.exp rSignexp_x = f8 // Must recompute if x unorm
+ movl rSig_inv_ln2 = 0xb8aa3b295c17f0bc // significand of 1/ln2
+}
+{ .mlx
+ addl rAD_TB1 = @ltoff(exp_table_1), gp
+ movl rRshf_2to56 = 0x4768000000000000 // 1.10000 2^(63+56)
+}
+;;
+
+{ .mfi
+ ld8 rAD_TB1 = [rAD_TB1]
+ fclass.m p6,p0 = f8,0x0b // Test for x=unorm
+ mov rExp_mask = 0x1ffff
+}
+{ .mfi
+ mov rExp_bias = 0xffff
+ fnorm.s1 fNormX = f8
+ mov rExp_2tom56 = 0xffff-56
+}
+;;
+
+// Form two constants we need
+// 1/ln2 * 2^63 to compute w = x * 1/ln2 * 128
+// 1.1000..000 * 2^(63+63-7) to right shift int(w) into the significand
+
+{ .mfi
+ setf.sig fINV_LN2_2TO63 = rSig_inv_ln2 // form 1/ln2 * 2^63
+ fclass.m p8,p0 = f8,0x07 // Test for x=0
+ nop.i 999
+}
+{ .mlx
+ setf.d fRSHF_2TO56 = rRshf_2to56 // Form const 1.100 * 2^(63+56)
+ movl rRshf = 0x43e8000000000000 // 1.10000 2^63 for right shift
+}
+;;
+
+{ .mfi
+ ldfpd fMIN_DBL_OFLOW_ARG, fMAX_DBL_NORM_ARG = [rAD_TB1],16
+ fclass.m p10,p0 = f8,0x1e3 // Test for x=inf, nan, NaT
+ nop.i 0
+}
+{ .mfb
+ setf.exp f2TOM56 = rExp_2tom56 // form 2^-56 for scaling Nfloat
+ nop.f 0
+(p6) br.cond.spnt COSH_UNORM // Branch if x=unorm
+}
+;;
+
+COSH_COMMON:
+{ .mfi
+ ldfe fLn2_by_128_hi = [rAD_TB1],16
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+ setf.d fRSHF = rRshf // Form right shift const 1.100 * 2^63
+(p8) fma.d.s0 f8 = f1,f1,f0 // quick exit for x=0
+(p8) br.ret.spnt b0
+}
+;;
+
+{ .mfi
+ ldfe fLn2_by_128_lo = [rAD_TB1],16
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+ and rExp_x = rExp_mask, rSignexp_x // Biased exponent of x
+(p10) fma.d.s0 f8 = f8,f8,f0 // Result if x=inf, nan, NaT
+(p10) br.ret.spnt b0 // quick exit for x=inf, nan, NaT
+}
+;;
+
+// After that last load rAD_TB1 points to the beginning of table 1
+{ .mfi
+ nop.m 0
+ fcmp.eq.s0 p6,p0 = f8, f0 // Dummy to set D
+ sub rExp_x = rExp_x, rExp_bias // True exponent of x
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fmerge.s fAbsX = f0, fNormX // Form |x|
+ nop.i 0
+}
+{ .mfb
+ cmp.gt p7, p0 = -2, rExp_x // Test |x| < 2^(-2)
+ fma.s1 fXsq = fNormX, fNormX, f0 // x*x for small path
+(p7) br.cond.spnt COSH_SMALL // Branch if 0 < |x| < 2^-2
+}
+;;
+
+// W = X * Inv_log2_by_128
+// By adding 1.10...0*2^63 we shift and get round_int(W) in significand.
+// We actually add 1.10...0*2^56 to X * Inv_log2 to do the same thing.
+
+{ .mfi
+ add rAD_P = 0x180, rAD_TB1
+ fma.s1 fW_2TO56_RSH = fNormX, fINV_LN2_2TO63, fRSHF_2TO56
+ add rAD_TB2 = 0x100, rAD_TB1
+}
+;;
+
+// Divide arguments into the following categories:
+// Certain Safe - 0.25 <= |x| <= MAX_DBL_NORM_ARG
+// Possible Overflow p14 - MAX_DBL_NORM_ARG < |x| < MIN_DBL_OFLOW_ARG
+// Certain Overflow p15 - MIN_DBL_OFLOW_ARG <= |x| < +inf
+//
+// If the input is really a double arg, then there will never be
+// "Possible Overflow" arguments.
+//
+
+{ .mfi
+ ldfpd fP5, fP4 = [rAD_P] ,16
+ fcmp.ge.s1 p15,p14 = fAbsX,fMIN_DBL_OFLOW_ARG
+ nop.i 0
+}
+;;
+
+// Nfloat = round_int(W)
+// The signficand of fW_2TO56_RSH contains the rounded integer part of W,
+// as a twos complement number in the lower bits (that is, it may be negative).
+// That twos complement number (called N) is put into rN.
+
+// Since fW_2TO56_RSH is scaled by 2^56, it must be multiplied by 2^-56
+// before the shift constant 1.10000 * 2^63 is subtracted to yield fNfloat.
+// Thus, fNfloat contains the floating point version of N
+
+{ .mfi
+ ldfpd fP3, fP2 = [rAD_P]
+(p14) fcmp.gt.unc.s1 p14,p0 = fAbsX,fMAX_DBL_NORM_ARG
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fms.s1 fNfloat = fW_2TO56_RSH, f2TOM56, fRSHF
+(p15) br.cond.spnt COSH_CERTAIN_OVERFLOW
+}
+;;
+
+{ .mfi
+ getf.sig rN = fW_2TO56_RSH
+ nop.f 0
+ mov rExp_bias_minus_1 = 0xfffe
+}
+;;
+
+// rIndex_1 has index_1
+// rIndex_2_16 has index_2 * 16
+// rBiased_M has M
+
+// rM has true M
+// r = x - Nfloat * ln2_by_128_hi
+// f = 1 - Nfloat * ln2_by_128_lo
+{ .mfi
+ and rIndex_1 = 0x0f, rN
+ fnma.s1 fR = fNfloat, fLn2_by_128_hi, fNormX
+ shr rM = rN, 0x7
+}
+{ .mfi
+ and rIndex_2_16 = 0x70, rN
+ fnma.s1 fF = fNfloat, fLn2_by_128_lo, f1
+ sub rN_neg = r0, rN
+}
+;;
+
+{ .mmi
+ and rIndex_1_neg = 0x0f, rN_neg
+ add rBiased_M = rExp_bias_minus_1, rM
+ shr rM_neg = rN_neg, 0x7
+}
+{ .mmi
+ and rIndex_2_16_neg = 0x70, rN_neg
+ add rAD_T2 = rAD_TB2, rIndex_2_16
+ shladd rAD_T1 = rIndex_1, 4, rAD_TB1
+}
+;;
+
+// rAD_T1 has address of T1
+// rAD_T2 has address if T2
+
+{ .mmi
+ setf.exp f2M = rBiased_M
+ ldfe fT2 = [rAD_T2]
+ nop.i 0
+}
+{ .mmi
+ add rBiased_M_neg = rExp_bias_minus_1, rM_neg
+ add rAD_T2_neg = rAD_TB2, rIndex_2_16_neg
+ shladd rAD_T1_neg = rIndex_1_neg, 4, rAD_TB1
+}
+;;
+
+// Create Scale = 2^M
+// Load T1 and T2
+{ .mmi
+ ldfe fT1 = [rAD_T1]
+ nop.m 0
+ nop.i 0
+}
+{ .mmf
+ setf.exp f2M_neg = rBiased_M_neg
+ ldfe fT2_neg = [rAD_T2_neg]
+ fma.s1 fF_neg = fNfloat, fLn2_by_128_lo, f1
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRsq = fR, fR, f0
+ nop.i 0
+}
+{ .mfi
+ ldfe fT1_neg = [rAD_T1_neg]
+ fma.s1 fP54 = fR, fP5, fP4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP32 = fR, fP3, fP2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 fP54_neg = fR, fP5, fP4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 fP32_neg = fR, fP3, fP2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP5432 = fRsq, fP54, fP32
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS2 = fF,fT2,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fS1 = f2M,fT1,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fP5432_neg = fRsq, fP54_neg, fP32_neg
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fS1_neg = f2M_neg,fT1_neg,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS2_neg = fF_neg,fT2_neg,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP = fRsq, fP5432, fR
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS = fS1,fS2,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fP_neg = fRsq, fP5432_neg, fR
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS_neg = fS1_neg,fS2_neg,f0
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fmpy.s0 fTmp = fLn2_by_128_lo, fLn2_by_128_lo // Force inexact
+(p14) br.cond.spnt COSH_POSSIBLE_OVERFLOW
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fExp = fS, fP, fS
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fExp_neg = fS_neg, fP_neg, fS_neg
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fExp, f1, fExp_neg
+ br.ret.sptk b0 // Normal path exit
+}
+;;
+
+// Here if 0 < |x| < 0.25
+COSH_SMALL:
+{ .mmf
+ add rAD_T1 = 0x1a0, rAD_TB1
+ add rAD_T2 = 0x1d0, rAD_TB1
+}
+;;
+
+{ .mmf
+ ldfe fA6 = [rAD_T1],16
+ ldfe fA5 = [rAD_T2],16
+ nop.f 0
+}
+;;
+
+{ .mmi
+ ldfe fA4 = [rAD_T1],16
+ ldfe fA3 = [rAD_T2],16
+ nop.i 0
+}
+;;
+
+{ .mmi
+ ldfe fA2 = [rAD_T1],16
+ ldfe fA1 = [rAD_T2],16
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fX4 = fXsq, fXsq, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA65 = fXsq, fA6, fA5
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA43 = fXsq, fA4, fA3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA21 = fXsq, fA2, fA1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA6543 = fX4, fA65, fA43
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA654321 = fX4, fA6543, fA21
+ nop.i 0
+}
+;;
+
+// Dummy multiply to generate inexact
+{ .mfi
+ nop.m 0
+ fmpy.s0 fTmp = fA6, fA6
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fA654321, fXsq, f1
+ br.ret.sptk b0 // Exit if 0 < |x| < 0.25
+}
+;;
+
+
+COSH_POSSIBLE_OVERFLOW:
+
+// Here if fMAX_DBL_NORM_ARG < |x| < fMIN_DBL_OFLOW_ARG
+// This cannot happen if input is a double, only if input higher precision.
+// Overflow is a possibility, not a certainty.
+
+// Recompute result using status field 2 with user's rounding mode,
+// and wre set. If result is larger than largest double, then we have
+// overflow
+
+{ .mfi
+ mov rGt_ln = 0x103ff // Exponent for largest dbl + 1 ulp
+ fsetc.s2 0x7F,0x42 // Get user's round mode, set wre
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp fGt_pln = rGt_ln // Create largest double + 1 ulp
+ fma.d.s2 fWre_urm_f8 = fS, fP, fS // Result with wre set
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40 // Turn off wre in sf2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p6, p0 = fWre_urm_f8, fGt_pln // Test for overflow
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p6) br.cond.spnt COSH_CERTAIN_OVERFLOW // Branch if overflow
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fS, fP, fS
+ br.ret.sptk b0 // Exit if really no overflow
+}
+;;
+
+COSH_CERTAIN_OVERFLOW:
+{ .mmi
+ sub rTmp = rExp_mask, r0, 1
+;;
+ setf.exp fTmp = rTmp
+ nop.i 0
+}
+;;
+
+{ .mfi
+ alloc r32=ar.pfs,1,4,4,0
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 64
+ fma.d.s0 FR_RESULT = fTmp, fTmp, f0 // Set I,O and +INF result
+ br.cond.sptk __libm_error_region
+}
+;;
+
+// Here if x unorm
+COSH_UNORM:
+{ .mfb
+ getf.exp rSignexp_x = fNormX // Must recompute if x unorm
+ fcmp.eq.s0 p6, p0 = f8, f0 // Set D flag
+ br.cond.sptk COSH_COMMON
+}
+;;
+
+GLOBAL_IEEE754_END(cosh)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_coshf.S b/libc/sysdeps/ia64/fpu/e_coshf.S
new file mode 100644
index 000000000..97cb4e177
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_coshf.S
@@ -0,0 +1,711 @@
+.file "coshf.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+
+// History
+//*********************************************************************
+// 02/02/00 Initial version
+// 02/16/00 The error tag for coshf overflow changed to 65 (from 64).
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 05/07/01 Reworked to improve speed of all paths
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 11/15/02 Improved algorithm based on expf
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//*********************************************************************
+// float coshf(float)
+//
+// Overview of operation
+//*********************************************************************
+// Case 1: 0 < |x| < 0.25
+// Evaluate cosh(x) by a 8th order polynomial
+// Care is take for the order of multiplication; and A2 is not exactly 1/4!,
+// A3 is not exactly 1/6!, etc.
+// cosh(x) = 1 + (A1*x^2 + A2*x^4 + A3*x^6 + A4*x^8)
+//
+// Case 2: 0.25 < |x| < 89.41598
+// Algorithm is based on the identity cosh(x) = ( exp(x) + exp(-x) ) / 2.
+// The algorithm for exp is described as below. There are a number of
+// economies from evaluating both exp(x) and exp(-x). Although we
+// are evaluating both quantities, only where the quantities diverge do we
+// duplicate the computations. The basic algorithm for exp(x) is described
+// below.
+//
+// Take the input x. w is "how many log2/128 in x?"
+// w = x * 64/log2
+// NJ = int(w)
+// x = NJ*log2/64 + R
+
+// NJ = 64*n + j
+// x = n*log2 + (log2/64)*j + R
+//
+// So, exp(x) = 2^n * 2^(j/64)* exp(R)
+//
+// T = 2^n * 2^(j/64)
+// Construct 2^n
+// Get 2^(j/64) table
+// actually all the entries of 2^(j/64) table are stored in DP and
+// with exponent bits set to 0 -> multiplication on 2^n can be
+// performed by doing logical "or" operation with bits presenting 2^n
+
+// exp(R) = 1 + (exp(R) - 1)
+// P = exp(R) - 1 approximated by Taylor series of 3rd degree
+// P = A3*R^3 + A2*R^2 + R, A3 = 1/6, A2 = 1/2
+//
+
+// The final result is reconstructed as follows
+// exp(x) = T + T*P
+
+// Special values
+//*********************************************************************
+// coshf(+0) = 1.0
+// coshf(-0) = 1.0
+
+// coshf(+qnan) = +qnan
+// coshf(-qnan) = -qnan
+// coshf(+snan) = +qnan
+// coshf(-snan) = -qnan
+
+// coshf(-inf) = +inf
+// coshf(+inf) = +inf
+
+// Overflow and Underflow
+//*********************************************************************
+// coshf(x) = largest single normal when
+// x = 89.41598 = 0x42b2d4fc
+//
+// There is no underflow.
+
+// Registers used
+//*********************************************************************
+// Floating Point registers used:
+// f8 input, output
+// f6,f7, f9 -> f15, f32 -> f45
+
+// General registers used:
+// r2, r3, r16 -> r38
+
+// Predicate registers used:
+// p6 -> p15
+
+// Assembly macros
+//*********************************************************************
+// integer registers used
+// scratch
+rNJ = r2
+rNJ_neg = r3
+
+rJ_neg = r16
+rN_neg = r17
+rSignexp_x = r18
+rExp_x = r18
+rExp_mask = r19
+rExp_bias = r20
+rAd1 = r21
+rAd2 = r22
+rJ = r23
+rN = r24
+rTblAddr = r25
+rA3 = r26
+rExpHalf = r27
+rLn2Div64 = r28
+rGt_ln = r29
+r17ones_m1 = r29
+rRightShifter = r30
+rJ_mask = r30
+r64DivLn2 = r31
+rN_mask = r31
+// stacked
+GR_SAVE_PFS = r32
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Parameter_TAG = r38
+
+// floating point registers used
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+// scratch
+fRightShifter = f6
+f64DivLn2 = f7
+fNormX = f9
+fNint = f10
+fN = f11
+fR = f12
+fLn2Div64 = f13
+fA2 = f14
+fA3 = f15
+// stacked
+fP = f32
+fT = f33
+fMIN_SGL_OFLOW_ARG = f34
+fMAX_SGL_NORM_ARG = f35
+fRSqr = f36
+fA1 = f37
+fA21 = f37
+fA4 = f38
+fA43 = f38
+fA4321 = f38
+fX4 = f39
+fTmp = f39
+fGt_pln = f39
+fWre_urm_f8 = f40
+fXsq = f40
+fP_neg = f41
+fT_neg = f42
+fExp = f43
+fExp_neg = f44
+fAbsX = f45
+
+
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(_coshf_table)
+data4 0x42b2d4fd // Smallest single arg to overflow single result
+data4 0x42b2d4fc // Largest single arg to give normal single result
+data4 0x00000000 // pad
+data4 0x00000000 // pad
+//
+// 2^(j/64) table, j goes from 0 to 63
+data8 0x0000000000000000 // 2^(0/64)
+data8 0x00002C9A3E778061 // 2^(1/64)
+data8 0x000059B0D3158574 // 2^(2/64)
+data8 0x0000874518759BC8 // 2^(3/64)
+data8 0x0000B5586CF9890F // 2^(4/64)
+data8 0x0000E3EC32D3D1A2 // 2^(5/64)
+data8 0x00011301D0125B51 // 2^(6/64)
+data8 0x0001429AAEA92DE0 // 2^(7/64)
+data8 0x000172B83C7D517B // 2^(8/64)
+data8 0x0001A35BEB6FCB75 // 2^(9/64)
+data8 0x0001D4873168B9AA // 2^(10/64)
+data8 0x0002063B88628CD6 // 2^(11/64)
+data8 0x0002387A6E756238 // 2^(12/64)
+data8 0x00026B4565E27CDD // 2^(13/64)
+data8 0x00029E9DF51FDEE1 // 2^(14/64)
+data8 0x0002D285A6E4030B // 2^(15/64)
+data8 0x000306FE0A31B715 // 2^(16/64)
+data8 0x00033C08B26416FF // 2^(17/64)
+data8 0x000371A7373AA9CB // 2^(18/64)
+data8 0x0003A7DB34E59FF7 // 2^(19/64)
+data8 0x0003DEA64C123422 // 2^(20/64)
+data8 0x0004160A21F72E2A // 2^(21/64)
+data8 0x00044E086061892D // 2^(22/64)
+data8 0x000486A2B5C13CD0 // 2^(23/64)
+data8 0x0004BFDAD5362A27 // 2^(24/64)
+data8 0x0004F9B2769D2CA7 // 2^(25/64)
+data8 0x0005342B569D4F82 // 2^(26/64)
+data8 0x00056F4736B527DA // 2^(27/64)
+data8 0x0005AB07DD485429 // 2^(28/64)
+data8 0x0005E76F15AD2148 // 2^(29/64)
+data8 0x0006247EB03A5585 // 2^(30/64)
+data8 0x0006623882552225 // 2^(31/64)
+data8 0x0006A09E667F3BCD // 2^(32/64)
+data8 0x0006DFB23C651A2F // 2^(33/64)
+data8 0x00071F75E8EC5F74 // 2^(34/64)
+data8 0x00075FEB564267C9 // 2^(35/64)
+data8 0x0007A11473EB0187 // 2^(36/64)
+data8 0x0007E2F336CF4E62 // 2^(37/64)
+data8 0x00082589994CCE13 // 2^(38/64)
+data8 0x000868D99B4492ED // 2^(39/64)
+data8 0x0008ACE5422AA0DB // 2^(40/64)
+data8 0x0008F1AE99157736 // 2^(41/64)
+data8 0x00093737B0CDC5E5 // 2^(42/64)
+data8 0x00097D829FDE4E50 // 2^(43/64)
+data8 0x0009C49182A3F090 // 2^(44/64)
+data8 0x000A0C667B5DE565 // 2^(45/64)
+data8 0x000A5503B23E255D // 2^(46/64)
+data8 0x000A9E6B5579FDBF // 2^(47/64)
+data8 0x000AE89F995AD3AD // 2^(48/64)
+data8 0x000B33A2B84F15FB // 2^(49/64)
+data8 0x000B7F76F2FB5E47 // 2^(50/64)
+data8 0x000BCC1E904BC1D2 // 2^(51/64)
+data8 0x000C199BDD85529C // 2^(52/64)
+data8 0x000C67F12E57D14B // 2^(53/64)
+data8 0x000CB720DCEF9069 // 2^(54/64)
+data8 0x000D072D4A07897C // 2^(55/64)
+data8 0x000D5818DCFBA487 // 2^(56/64)
+data8 0x000DA9E603DB3285 // 2^(57/64)
+data8 0x000DFC97337B9B5F // 2^(58/64)
+data8 0x000E502EE78B3FF6 // 2^(59/64)
+data8 0x000EA4AFA2A490DA // 2^(60/64)
+data8 0x000EFA1BEE615A27 // 2^(61/64)
+data8 0x000F50765B6E4540 // 2^(62/64)
+data8 0x000FA7C1819E90D8 // 2^(63/64)
+LOCAL_OBJECT_END(_coshf_table)
+
+LOCAL_OBJECT_START(cosh_p_table)
+data8 0x3efa3001dcf5905b // A4
+data8 0x3f56c1437543543e // A3
+data8 0x3fa5555572601504 // A2
+data8 0x3fdfffffffe2f097 // A1
+LOCAL_OBJECT_END(cosh_p_table)
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(coshf)
+
+{ .mlx
+ getf.exp rSignexp_x = f8 // Must recompute if x unorm
+ movl r64DivLn2 = 0x40571547652B82FE // 64/ln(2)
+}
+{ .mlx
+ addl rTblAddr = @ltoff(_coshf_table),gp
+ movl rRightShifter = 0x43E8000000000000 // DP Right Shifter
+}
+;;
+
+{ .mfi
+ // point to the beginning of the table
+ ld8 rTblAddr = [rTblAddr]
+ fclass.m p6, p0 = f8, 0x0b // Test for x=unorm
+ addl rA3 = 0x3E2AA, r0 // high bits of 1.0/6.0 rounded to SP
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNormX = f8 // normalized x
+ addl rExpHalf = 0xFFFE, r0 // exponent of 1/2
+}
+;;
+
+{ .mfi
+ setf.d f64DivLn2 = r64DivLn2 // load 64/ln(2) to FP reg
+ fclass.m p15, p0 = f8, 0x1e3 // test for NaT,NaN,Inf
+ nop.i 0
+}
+{ .mlx
+ // load Right Shifter to FP reg
+ setf.d fRightShifter = rRightShifter
+ movl rLn2Div64 = 0x3F862E42FEFA39EF // DP ln(2)/64 in GR
+}
+;;
+
+{ .mfi
+ mov rExp_mask = 0x1ffff
+ fcmp.eq.s1 p13, p0 = f0, f8 // test for x = 0.0
+ shl rA3 = rA3, 12 // 0x3E2AA000, approx to 1.0/6.0 in SP
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p6) br.cond.spnt COSH_UNORM // Branch if x=unorm
+}
+;;
+
+COSH_COMMON:
+{ .mfi
+ setf.exp fA2 = rExpHalf // load A2 to FP reg
+ nop.f 0
+ mov rExp_bias = 0xffff
+}
+{ .mfb
+ setf.d fLn2Div64 = rLn2Div64 // load ln(2)/64 to FP reg
+(p15) fma.s.s0 f8 = f8, f8, f0 // result if x = NaT,NaN,Inf
+(p15) br.ret.spnt b0 // exit here if x = NaT,NaN,Inf
+}
+;;
+
+{ .mfi
+ // min overflow and max normal threshold
+ ldfps fMIN_SGL_OFLOW_ARG, fMAX_SGL_NORM_ARG = [rTblAddr], 8
+ nop.f 0
+ and rExp_x = rExp_mask, rSignexp_x // Biased exponent of x
+}
+{ .mfb
+ setf.s fA3 = rA3 // load A3 to FP reg
+(p13) fma.s.s0 f8 = f1, f1, f0 // result if x = 0.0
+(p13) br.ret.spnt b0 // exit here if x =0.0
+}
+;;
+
+{ .mfi
+ sub rExp_x = rExp_x, rExp_bias // True exponent of x
+ fmerge.s fAbsX = f0, fNormX // Form |x|
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // x*(64/ln(2)) + Right Shifter
+ fma.s1 fNint = fNormX, f64DivLn2, fRightShifter
+ add rTblAddr = 8, rTblAddr
+}
+{ .mfb
+ cmp.gt p7, p0 = -2, rExp_x // Test |x| < 2^(-2)
+ fma.s1 fXsq = fNormX, fNormX, f0 // x*x for small path
+(p7) br.cond.spnt COSH_SMALL // Branch if 0 < |x| < 2^-2
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // check for overflow
+ fcmp.ge.s1 p12, p13 = fAbsX, fMIN_SGL_OFLOW_ARG
+ mov rJ_mask = 0x3f // 6-bit mask for J
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fms.s1 fN = fNint, f1, fRightShifter // n in FP register
+ // branch out if overflow
+(p12) br.cond.spnt COSH_CERTAIN_OVERFLOW
+}
+;;
+
+{ .mfi
+ getf.sig rNJ = fNint // bits of n, j
+ // check for possible overflow
+ fcmp.gt.s1 p13, p0 = fAbsX, fMAX_SGL_NORM_ARG
+ nop.i 0
+}
+;;
+
+{ .mfi
+ addl rN = 0xFFBF - 63, rNJ // biased and shifted n-1,j
+ fnma.s1 fR = fLn2Div64, fN, fNormX // R = x - N*ln(2)/64
+ and rJ = rJ_mask, rNJ // bits of j
+}
+{ .mfi
+ sub rNJ_neg = r0, rNJ // bits of n, j for -x
+ nop.f 0
+ andcm rN_mask = -1, rJ_mask // 0xff...fc0 to mask N
+}
+;;
+
+{ .mfi
+ shladd rJ = rJ, 3, rTblAddr // address in the 2^(j/64) table
+ nop.f 0
+ and rN = rN_mask, rN // biased, shifted n-1
+}
+{ .mfi
+ addl rN_neg = 0xFFBF - 63, rNJ_neg // -x biased, shifted n-1,j
+ nop.f 0
+ and rJ_neg = rJ_mask, rNJ_neg // bits of j for -x
+}
+;;
+
+{ .mfi
+ ld8 rJ = [rJ] // Table value
+ nop.f 0
+ shl rN = rN, 46 // 2^(n-1) bits in DP format
+}
+{ .mfi
+ shladd rJ_neg = rJ_neg, 3, rTblAddr // addr in 2^(j/64) table -x
+ nop.f 0
+ and rN_neg = rN_mask, rN_neg // biased, shifted n-1 for -x
+}
+;;
+
+{ .mfi
+ ld8 rJ_neg = [rJ_neg] // Table value for -x
+ nop.f 0
+ shl rN_neg = rN_neg, 46 // 2^(n-1) bits in DP format for -x
+}
+;;
+
+{ .mfi
+ or rN = rN, rJ // bits of 2^n * 2^(j/64) in DP format
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mmf
+ setf.d fT = rN // 2^(n-1) * 2^(j/64)
+ or rN_neg = rN_neg, rJ_neg // -x bits of 2^n * 2^(j/64) in DP
+ fma.s1 fRSqr = fR, fR, f0 // R^2
+}
+;;
+
+{ .mfi
+ setf.d fT_neg = rN_neg // 2^(n-1) * 2^(j/64) for -x
+ fma.s1 fP = fA3, fR, fA2 // A3*R + A2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 fP_neg = fA3, fR, fA2 // A3*R + A2 for -x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP = fP, fRSqr, fR // P = (A3*R + A2)*R^2 + R
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fP_neg = fP_neg, fRSqr, fR // P = (A3*R + A2)*R^2 + R, -x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fmpy.s0 fTmp = fLn2Div64, fLn2Div64 // Force inexact
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fExp = fP, fT, fT // exp(x)/2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s1 fExp_neg = fP_neg, fT_neg, fT_neg // exp(-x)/2
+ // branch out if possible overflow result
+(p13) br.cond.spnt COSH_POSSIBLE_OVERFLOW
+}
+;;
+
+{ .mfb
+ nop.m 0
+ // final result in the absence of overflow
+ fma.s.s0 f8 = fExp, f1, fExp_neg // result = (exp(x)+exp(-x))/2
+ // exit here in the absence of overflow
+ br.ret.sptk b0 // Exit main path, 0.25 <= |x| < 89.41598
+}
+;;
+
+// Here if 0 < |x| < 0.25. Evaluate 8th order polynomial.
+COSH_SMALL:
+{ .mmi
+ add rAd1 = 0x200, rTblAddr
+ add rAd2 = 0x210, rTblAddr
+ nop.i 0
+}
+;;
+
+{ .mmi
+ ldfpd fA4, fA3 = [rAd1]
+ ldfpd fA2, fA1 = [rAd2]
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fX4 = fXsq, fXsq, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA43 = fXsq, fA4, fA3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA21 = fXsq, fA2, fA1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA4321 = fX4, fA43, fA21
+ nop.i 0
+}
+;;
+
+// Dummy multiply to generate inexact
+{ .mfi
+ nop.m 0
+ fmpy.s0 fTmp = fA4, fA4
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = fA4321, fXsq, f1
+ br.ret.sptk b0 // Exit if 0 < |x| < 0.25
+}
+;;
+
+COSH_POSSIBLE_OVERFLOW:
+
+// Here if fMAX_SGL_NORM_ARG < x < fMIN_SGL_OFLOW_ARG
+// This cannot happen if input is a single, only if input higher precision.
+// Overflow is a possibility, not a certainty.
+
+// Recompute result using status field 2 with user's rounding mode,
+// and wre set. If result is larger than largest single, then we have
+// overflow
+
+{ .mfi
+ mov rGt_ln = 0x1007f // Exponent for largest single + 1 ulp
+ fsetc.s2 0x7F,0x42 // Get user's round mode, set wre
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp fGt_pln = rGt_ln // Create largest single + 1 ulp
+ fma.s.s2 fWre_urm_f8 = fP, fT, fT // Result with wre set
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40 // Turn off wre in sf2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p6, p0 = fWre_urm_f8, fGt_pln // Test for overflow
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p6) br.cond.spnt COSH_CERTAIN_OVERFLOW // Branch if overflow
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = fP, fT, fT
+ br.ret.sptk b0 // Exit if really no overflow
+}
+;;
+
+// here if overflow
+COSH_CERTAIN_OVERFLOW:
+{ .mmi
+ addl r17ones_m1 = 0x1FFFE, r0
+;;
+ setf.exp fTmp = r17ones_m1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ alloc r32 = ar.pfs, 0, 3, 4, 0 // get some registers
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 65
+ fma.s.s0 FR_RESULT = fTmp, fTmp, f0 // Set I,O and +INF result
+ br.cond.sptk __libm_error_region
+}
+;;
+
+// Here if x unorm
+COSH_UNORM:
+{ .mfb
+ getf.exp rSignexp_x = fNormX // Must recompute if x unorm
+ fcmp.eq.s0 p6, p0 = f8, f0 // Set D flag
+ br.cond.sptk COSH_COMMON // Return to main path
+}
+;;
+
+GLOBAL_IEEE754_END(coshf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // Store Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mfi
+ stfs [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ nop.f 0
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_coshl.S b/libc/sysdeps/ia64/fpu/e_coshl.S
new file mode 100644
index 000000000..b5872d0b2
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_coshl.S
@@ -0,0 +1,1095 @@
+.file "coshl.s"
+
+
+// Copyright (c) 2000 - 2002, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 01/23/01 Set inexact flag for large args.
+// 05/07/01 Reworked to improve speed of all paths
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 12/06/02 Improved performance
+//
+// API
+//==============================================================
+// long double = coshl(long double)
+// input floating point f8
+// output floating point f8
+//
+// Registers used
+//==============================================================
+// general registers:
+// r14 -> r40
+// predicate registers used:
+// p6 -> p11
+// floating-point registers used:
+// f9 -> f15; f32 -> f90;
+// f8 has input, then output
+//
+// Overview of operation
+//==============================================================
+// There are seven paths
+// 1. 0 < |x| < 0.25 COSH_BY_POLY
+// 2. 0.25 <=|x| < 32 COSH_BY_TBL
+// 3. 32 <= |x| < 11357.21655 COSH_BY_EXP (merged path with COSH_BY_TBL)
+// 4. |x| >= 11357.21655 COSH_HUGE
+// 5. x=0 Done with early exit
+// 6. x=inf,nan Done with early exit
+// 7. x=denormal COSH_DENORM
+//
+// For double extended we get overflow for x >= 400c b174 ddc0 31ae c0ea
+// >= 11357.21655
+//
+//
+// 1. COSH_BY_POLY 0 < |x| < 0.25
+// ===============
+// Evaluate cosh(x) by a 12th order polynomial
+// Care is take for the order of multiplication; and P2 is not exactly 1/4!,
+// P3 is not exactly 1/6!, etc.
+// cosh(x) = 1 + (P1*x^2 + P2*x^4 + P3*x^6 + P4*x^8 + P5*x^10 + P6*x^12)
+//
+// 2. COSH_BY_TBL 0.25 <= |x| < 32.0
+// =============
+// cosh(x) = cosh(B+R)
+// = cosh(B)cosh(R) + sinh(B)sinh(R)
+//
+// ax = |x| = M*log2/64 + R
+// B = M*log2/64
+// M = 64*N + j
+// We will calculate M and get N as (M-j)/64
+// The division is a shift.
+// exp(B) = exp(N*log2 + j*log2/64)
+// = 2^N * 2^(j*log2/64)
+// cosh(B) = 1/2(e^B + e^-B)
+// = 1/2(2^N * 2^(j*log2/64) + 2^-N * 2^(-j*log2/64))
+// cosh(B) = (2^(N-1) * 2^(j*log2/64) + 2^(-N-1) * 2^(-j*log2/64))
+// sinh(B) = (2^(N-1) * 2^(j*log2/64) - 2^(-N-1) * 2^(-j*log2/64))
+// 2^(j*log2/64) is stored as Tjhi + Tjlo , j= -32,....,32
+// Tjhi is double-extended (80-bit) and Tjlo is single(32-bit)
+//
+// R = ax - M*log2/64
+// R = ax - M*log2_by_64_hi - M*log2_by_64_lo
+// exp(R) = 1 + R +R^2(1/2! + R(1/3! + R(1/4! + ... + R(1/n!)...)
+// = 1 + p_odd + p_even
+// where the p_even uses the A coefficients and the p_even uses
+// the B coefficients
+//
+// So sinh(R) = 1 + p_odd + p_even -(1 -p_odd -p_even)/2 = p_odd
+// cosh(R) = 1 + p_even
+// cosh(B) = C_hi + C_lo
+// sinh(B) = S_hi
+// cosh(x) = cosh(B)cosh(R) + sinh(B)sinh(R)
+//
+// 3. COSH_BY_EXP 32.0 <= |x| < 11357.21655 ( 400c b174 ddc0 31ae c0ea )
+// ==============
+// Can approximate result by exp(x)/2 in this region.
+// Y_hi = Tjhi
+// Y_lo = Tjhi * (p_odd + p_even) + Tjlo
+// cosh(x) = Y_hi + Y_lo
+//
+// 4. COSH_HUGE |x| >= 11357.21655 ( 400c b174 ddc0 31ae c0ea )
+// ============
+// Set error tag and call error support
+//
+//
+// Assembly macros
+//==============================================================
+r_ad5 = r14
+r_rshf_2to57 = r15
+r_exp_denorm = r15
+r_ad_mJ_lo = r15
+r_ad_J_lo = r16
+r_2Nm1 = r17
+r_2mNm1 = r18
+r_exp_x = r18
+r_ad_J_hi = r19
+r_ad2o = r19
+r_ad_mJ_hi = r20
+r_mj = r21
+r_ad2e = r22
+r_ad3 = r23
+r_ad1 = r24
+r_Mmj = r24
+r_rshf = r25
+r_M = r25
+r_N = r25
+r_jshf = r26
+r_exp_2tom57 = r26
+r_j = r26
+r_exp_mask = r27
+r_signexp_x = r28
+r_signexp_0_5 = r28
+r_exp_0_25 = r29
+r_sig_inv_ln2 = r30
+r_exp_32 = r30
+r_exp_huge = r30
+r_ad4 = r31
+
+GR_SAVE_PFS = r34
+GR_SAVE_B0 = r35
+GR_SAVE_GP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+f_ABS_X = f9
+f_X2 = f10
+f_X4 = f11
+f_tmp = f14
+f_RSHF = f15
+
+f_Inv_log2by64 = f32
+f_log2by64_lo = f33
+f_log2by64_hi = f34
+f_A1 = f35
+
+f_A2 = f36
+f_A3 = f37
+f_Rcub = f38
+f_M_temp = f39
+f_R_temp = f40
+
+f_Rsq = f41
+f_R = f42
+f_M = f43
+f_B1 = f44
+f_B2 = f45
+
+f_B3 = f46
+f_peven_temp1 = f47
+f_peven_temp2 = f48
+f_peven = f49
+f_podd_temp1 = f50
+
+f_podd_temp2 = f51
+f_podd = f52
+f_poly65 = f53
+f_poly6543 = f53
+f_poly6to1 = f53
+f_poly43 = f54
+f_poly21 = f55
+
+f_X3 = f56
+f_INV_LN2_2TO63 = f57
+f_RSHF_2TO57 = f58
+f_2TOM57 = f59
+f_smlst_oflow_input = f60
+
+f_pre_result = f61
+f_huge = f62
+f_spos = f63
+f_sneg = f64
+f_Tjhi = f65
+
+f_Tjlo = f66
+f_Tmjhi = f67
+f_Tmjlo = f68
+f_S_hi = f69
+f_SC_hi_temp = f70
+
+f_C_lo_temp1 = f71
+f_C_lo_temp2 = f72
+f_C_lo_temp3 = f73
+f_C_lo_temp4 = f73
+f_C_lo = f74
+f_C_hi = f75
+
+f_Y_hi = f77
+f_Y_lo_temp = f78
+f_Y_lo = f79
+f_NORM_X = f80
+
+f_P1 = f81
+f_P2 = f82
+f_P3 = f83
+f_P4 = f84
+f_P5 = f85
+
+f_P6 = f86
+f_Tjhi_spos = f87
+f_Tjlo_spos = f88
+f_huge = f89
+f_signed_hi_lo = f90
+
+
+// Data tables
+//==============================================================
+
+// DO NOT CHANGE ORDER OF THESE TABLES
+RODATA
+
+.align 16
+LOCAL_OBJECT_START(cosh_arg_reduction)
+// data8 0xB8AA3B295C17F0BC, 0x00004005 // 64/log2 -- signif loaded with setf
+ data8 0xB17217F7D1000000, 0x00003FF8 // log2/64 high part
+ data8 0xCF79ABC9E3B39804, 0x00003FD0 // log2/64 low part
+ data8 0xb174ddc031aec0ea, 0x0000400c // Smallest x to overflow (11357.21655)
+LOCAL_OBJECT_END(cosh_arg_reduction)
+
+LOCAL_OBJECT_START(cosh_p_table)
+ data8 0x8FA02AC65BCBD5BC, 0x00003FE2 // P6
+ data8 0xD00D00D1021D7370, 0x00003FEF // P4
+ data8 0xAAAAAAAAAAAAAB80, 0x00003FFA // P2
+ data8 0x93F27740C0C2F1CC, 0x00003FE9 // P5
+ data8 0xB60B60B60B4FE884, 0x00003FF5 // P3
+ data8 0x8000000000000000, 0x00003FFE // P1
+LOCAL_OBJECT_END(cosh_p_table)
+
+LOCAL_OBJECT_START(cosh_ab_table)
+ data8 0xAAAAAAAAAAAAAAAC, 0x00003FFC // A1
+ data8 0x88888888884ECDD5, 0x00003FF8 // A2
+ data8 0xD00D0C6DCC26A86B, 0x00003FF2 // A3
+ data8 0x8000000000000002, 0x00003FFE // B1
+ data8 0xAAAAAAAAAA402C77, 0x00003FFA // B2
+ data8 0xB60B6CC96BDB144D, 0x00003FF5 // B3
+LOCAL_OBJECT_END(cosh_ab_table)
+
+LOCAL_OBJECT_START(cosh_j_hi_table)
+ data8 0xB504F333F9DE6484, 0x00003FFE
+ data8 0xB6FD91E328D17791, 0x00003FFE
+ data8 0xB8FBAF4762FB9EE9, 0x00003FFE
+ data8 0xBAFF5AB2133E45FB, 0x00003FFE
+ data8 0xBD08A39F580C36BF, 0x00003FFE
+ data8 0xBF1799B67A731083, 0x00003FFE
+ data8 0xC12C4CCA66709456, 0x00003FFE
+ data8 0xC346CCDA24976407, 0x00003FFE
+ data8 0xC5672A115506DADD, 0x00003FFE
+ data8 0xC78D74C8ABB9B15D, 0x00003FFE
+ data8 0xC9B9BD866E2F27A3, 0x00003FFE
+ data8 0xCBEC14FEF2727C5D, 0x00003FFE
+ data8 0xCE248C151F8480E4, 0x00003FFE
+ data8 0xD06333DAEF2B2595, 0x00003FFE
+ data8 0xD2A81D91F12AE45A, 0x00003FFE
+ data8 0xD4F35AABCFEDFA1F, 0x00003FFE
+ data8 0xD744FCCAD69D6AF4, 0x00003FFE
+ data8 0xD99D15C278AFD7B6, 0x00003FFE
+ data8 0xDBFBB797DAF23755, 0x00003FFE
+ data8 0xDE60F4825E0E9124, 0x00003FFE
+ data8 0xE0CCDEEC2A94E111, 0x00003FFE
+ data8 0xE33F8972BE8A5A51, 0x00003FFE
+ data8 0xE5B906E77C8348A8, 0x00003FFE
+ data8 0xE8396A503C4BDC68, 0x00003FFE
+ data8 0xEAC0C6E7DD24392F, 0x00003FFE
+ data8 0xED4F301ED9942B84, 0x00003FFE
+ data8 0xEFE4B99BDCDAF5CB, 0x00003FFE
+ data8 0xF281773C59FFB13A, 0x00003FFE
+ data8 0xF5257D152486CC2C, 0x00003FFE
+ data8 0xF7D0DF730AD13BB9, 0x00003FFE
+ data8 0xFA83B2DB722A033A, 0x00003FFE
+ data8 0xFD3E0C0CF486C175, 0x00003FFE
+ data8 0x8000000000000000, 0x00003FFF // Center of table
+ data8 0x8164D1F3BC030773, 0x00003FFF
+ data8 0x82CD8698AC2BA1D7, 0x00003FFF
+ data8 0x843A28C3ACDE4046, 0x00003FFF
+ data8 0x85AAC367CC487B15, 0x00003FFF
+ data8 0x871F61969E8D1010, 0x00003FFF
+ data8 0x88980E8092DA8527, 0x00003FFF
+ data8 0x8A14D575496EFD9A, 0x00003FFF
+ data8 0x8B95C1E3EA8BD6E7, 0x00003FFF
+ data8 0x8D1ADF5B7E5BA9E6, 0x00003FFF
+ data8 0x8EA4398B45CD53C0, 0x00003FFF
+ data8 0x9031DC431466B1DC, 0x00003FFF
+ data8 0x91C3D373AB11C336, 0x00003FFF
+ data8 0x935A2B2F13E6E92C, 0x00003FFF
+ data8 0x94F4EFA8FEF70961, 0x00003FFF
+ data8 0x96942D3720185A00, 0x00003FFF
+ data8 0x9837F0518DB8A96F, 0x00003FFF
+ data8 0x99E0459320B7FA65, 0x00003FFF
+ data8 0x9B8D39B9D54E5539, 0x00003FFF
+ data8 0x9D3ED9A72CFFB751, 0x00003FFF
+ data8 0x9EF5326091A111AE, 0x00003FFF
+ data8 0xA0B0510FB9714FC2, 0x00003FFF
+ data8 0xA27043030C496819, 0x00003FFF
+ data8 0xA43515AE09E6809E, 0x00003FFF
+ data8 0xA5FED6A9B15138EA, 0x00003FFF
+ data8 0xA7CD93B4E965356A, 0x00003FFF
+ data8 0xA9A15AB4EA7C0EF8, 0x00003FFF
+ data8 0xAB7A39B5A93ED337, 0x00003FFF
+ data8 0xAD583EEA42A14AC6, 0x00003FFF
+ data8 0xAF3B78AD690A4375, 0x00003FFF
+ data8 0xB123F581D2AC2590, 0x00003FFF
+ data8 0xB311C412A9112489, 0x00003FFF
+ data8 0xB504F333F9DE6484, 0x00003FFF
+LOCAL_OBJECT_END(cosh_j_hi_table)
+
+LOCAL_OBJECT_START(cosh_j_lo_table)
+ data4 0x1EB2FB13
+ data4 0x1CE2CBE2
+ data4 0x1DDC3CBC
+ data4 0x1EE9AA34
+ data4 0x9EAEFDC1
+ data4 0x9DBF517B
+ data4 0x1EF88AFB
+ data4 0x1E03B216
+ data4 0x1E78AB43
+ data4 0x9E7B1747
+ data4 0x9EFE3C0E
+ data4 0x9D36F837
+ data4 0x9DEE53E4
+ data4 0x9E24AE8E
+ data4 0x1D912473
+ data4 0x1EB243BE
+ data4 0x1E669A2F
+ data4 0x9BBC610A
+ data4 0x1E761035
+ data4 0x9E0BE175
+ data4 0x1CCB12A1
+ data4 0x1D1BFE90
+ data4 0x1DF2F47A
+ data4 0x1EF22F22
+ data4 0x9E3F4A29
+ data4 0x1EC01A5B
+ data4 0x1E8CAC3A
+ data4 0x9DBB3FAB
+ data4 0x1EF73A19
+ data4 0x9BB795B5
+ data4 0x1EF84B76
+ data4 0x9EF5818B
+ data4 0x00000000 // Center of table
+ data4 0x1F77CACA
+ data4 0x1EF8A91D
+ data4 0x1E57C976
+ data4 0x9EE8DA92
+ data4 0x1EE85C9F
+ data4 0x1F3BF1AF
+ data4 0x1D80CA1E
+ data4 0x9D0373AF
+ data4 0x9F167097
+ data4 0x1EB70051
+ data4 0x1F6EB029
+ data4 0x1DFD6D8E
+ data4 0x9EB319B0
+ data4 0x1EBA2BEB
+ data4 0x1F11D537
+ data4 0x1F0D5A46
+ data4 0x9E5E7BCA
+ data4 0x9F3AAFD1
+ data4 0x9E86DACC
+ data4 0x9F3EDDC2
+ data4 0x1E496E3D
+ data4 0x9F490BF6
+ data4 0x1DD1DB48
+ data4 0x1E65EBFB
+ data4 0x9F427496
+ data4 0x1F283C4A
+ data4 0x1F4B0047
+ data4 0x1F130152
+ data4 0x9E8367C0
+ data4 0x9F705F90
+ data4 0x1EFB3C53
+ data4 0x1F32FB13
+LOCAL_OBJECT_END(cosh_j_lo_table)
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(coshl)
+
+{ .mlx
+ getf.exp r_signexp_x = f8 // Get signexp of x, must redo if unorm
+ movl r_sig_inv_ln2 = 0xb8aa3b295c17f0bc // significand of 1/ln2
+}
+{ .mlx
+ addl r_ad1 = @ltoff(cosh_arg_reduction), gp
+ movl r_rshf_2to57 = 0x4778000000000000 // 1.10000 2^(63+57)
+}
+;;
+
+{ .mfi
+ ld8 r_ad1 = [r_ad1]
+ fmerge.s f_ABS_X = f0,f8
+ mov r_exp_0_25 = 0x0fffd // Form exponent for 0.25
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 f_NORM_X = f8
+ mov r_exp_2tom57 = 0xffff-57
+}
+;;
+
+{ .mfi
+ setf.d f_RSHF_2TO57 = r_rshf_2to57 // Form const 1.100 * 2^120
+ fclass.m p10,p0 = f8, 0x0b // Test for denorm
+ mov r_exp_mask = 0x1ffff
+}
+{ .mlx
+ setf.sig f_INV_LN2_2TO63 = r_sig_inv_ln2 // Form 1/ln2 * 2^63
+ movl r_rshf = 0x43e8000000000000 // 1.1000 2^63 for right shift
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p7,p0 = f8, 0x07 // Test if x=0
+ nop.i 0
+}
+{ .mfi
+ setf.exp f_2TOM57 = r_exp_2tom57 // Form 2^-57 for scaling
+ nop.f 0
+ add r_ad3 = 0x90, r_ad1 // Point to ab_table
+}
+;;
+
+{ .mfi
+ setf.d f_RSHF = r_rshf // Form right shift const 1.100 * 2^63
+ fclass.m p6,p0 = f8, 0xe3 // Test if x nan, inf
+ add r_ad4 = 0x2f0, r_ad1 // Point to j_hi_table midpoint
+}
+{ .mib
+ add r_ad2e = 0x20, r_ad1 // Point to p_table
+ nop.i 0
+(p10) br.cond.spnt COSH_DENORM // Branch if x denorm
+}
+;;
+
+// Common path -- return here from COSH_DENORM if x is unnorm
+COSH_COMMON:
+{ .mfi
+ ldfe f_smlst_oflow_input = [r_ad2e],16
+(p7) fma.s0 f8 = f1, f1, f0 // Result = 1.0 if x=0
+ add r_ad5 = 0x580, r_ad1 // Point to j_lo_table midpoint
+}
+{ .mib
+ ldfe f_log2by64_hi = [r_ad1],16
+ and r_exp_x = r_exp_mask, r_signexp_x
+(p7) br.ret.spnt b0 // Exit if x=0
+}
+;;
+
+// Get the A coefficients for COSH_BY_TBL
+{ .mfi
+ ldfe f_A1 = [r_ad3],16
+ fcmp.lt.s1 p8,p9 = f8,f0 // Test for x<0
+ cmp.lt p7,p0 = r_exp_x, r_exp_0_25 // Test x < 0.25
+}
+{ .mfb
+ add r_ad2o = 0x30, r_ad2e // Point to p_table odd coeffs
+(p6) fma.s0 f8 = f8,f8,f0 // Result for x nan, inf
+(p6) br.ret.spnt b0 // Exit for x nan, inf
+}
+;;
+
+// Calculate X2 = ax*ax for COSH_BY_POLY
+{ .mfi
+ ldfe f_log2by64_lo = [r_ad1],16
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+ ldfe f_A2 = [r_ad3],16
+ fma.s1 f_X2 = f_NORM_X, f_NORM_X, f0
+(p7) br.cond.spnt COSH_BY_POLY
+}
+;;
+
+// Here if |x| >= 0.25
+COSH_BY_TBL:
+// ******************************************************
+// STEP 1 (TBL and EXP) - Argument reduction
+// ******************************************************
+// Get the following constants.
+// Inv_log2by64
+// log2by64_hi
+// log2by64_lo
+
+
+// We want 2^(N-1) and 2^(-N-1). So bias N-1 and -N-1 and
+// put them in an exponent.
+// f_spos = 2^(N-1) and f_sneg = 2^(-N-1)
+// 0xffff + (N-1) = 0xffff +N -1
+// 0xffff - (N +1) = 0xffff -N -1
+
+
+// Calculate M and keep it as integer and floating point.
+// M = round-to-integer(x*Inv_log2by64)
+// f_M = M = truncate(ax/(log2/64))
+// Put the integer representation of M in r_M
+// and the floating point representation of M in f_M
+
+// Get the remaining A,B coefficients
+{ .mmi
+ ldfe f_A3 = [r_ad3],16
+ nop.m 0
+ nop.i 0
+}
+;;
+
+// Use constant (1.100*2^(63-6)) to get rounded M into rightmost significand
+// |x| * 64 * 1/ln2 * 2^(63-6) + 1.1000 * 2^(63+(63-6))
+{ .mfi
+ nop.m 0
+ fma.s1 f_M_temp = f_ABS_X, f_INV_LN2_2TO63, f_RSHF_2TO57
+ mov r_signexp_0_5 = 0x0fffe // signexp of +0.5
+}
+;;
+
+// Test for |x| >= overflow limit
+{ .mfi
+ ldfe f_B1 = [r_ad3],16
+ fcmp.ge.s1 p6,p0 = f_ABS_X, f_smlst_oflow_input
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe f_B2 = [r_ad3],16
+ nop.f 0
+ mov r_exp_32 = 0x10004
+}
+;;
+
+// Subtract RSHF constant to get rounded M as a floating point value
+// M_temp * 2^(63-6) - 2^63
+{ .mfb
+ ldfe f_B3 = [r_ad3],16
+ fms.s1 f_M = f_M_temp, f_2TOM57, f_RSHF
+(p6) br.cond.spnt COSH_HUGE // Branch if result will overflow
+}
+;;
+
+{ .mfi
+ getf.sig r_M = f_M_temp
+ nop.f 0
+ cmp.ge p7,p6 = r_exp_x, r_exp_32 // Test if x >= 32
+}
+;;
+
+// Calculate j. j is the signed extension of the six lsb of M. It
+// has a range of -32 thru 31.
+
+// Calculate R
+// ax - M*log2by64_hi
+// R = (ax - M*log2by64_hi) - M*log2by64_lo
+
+{ .mfi
+ nop.m 0
+ fnma.s1 f_R_temp = f_M, f_log2by64_hi, f_ABS_X
+ and r_j = 0x3f, r_M
+}
+;;
+
+{ .mii
+ nop.m 0
+ shl r_jshf = r_j, 0x2 // Shift j so can sign extend it
+;;
+ sxt1 r_jshf = r_jshf
+}
+;;
+
+{ .mii
+ nop.m 0
+ shr r_j = r_jshf, 0x2 // Now j has range -32 to 31
+ nop.i 0
+}
+;;
+
+{ .mmi
+ shladd r_ad_J_hi = r_j, 4, r_ad4 // pointer to Tjhi
+ sub r_Mmj = r_M, r_j // M-j
+ sub r_mj = r0, r_j // Form -j
+}
+;;
+
+// The TBL and EXP branches are merged and predicated
+// If TBL, p6 true, 0.25 <= |x| < 32
+// If EXP, p7 true, 32 <= |x| < overflow_limit
+//
+// N = (M-j)/64
+{ .mfi
+ ldfe f_Tjhi = [r_ad_J_hi]
+ fnma.s1 f_R = f_M, f_log2by64_lo, f_R_temp
+ shr r_N = r_Mmj, 0x6 // N = (M-j)/64
+}
+{ .mfi
+ shladd r_ad_mJ_hi = r_mj, 4, r_ad4 // pointer to Tmjhi
+ nop.f 0
+ shladd r_ad_mJ_lo = r_mj, 2, r_ad5 // pointer to Tmjlo
+}
+;;
+
+{ .mfi
+ sub r_2mNm1 = r_signexp_0_5, r_N // signexp 2^(-N-1)
+ nop.f 0
+ shladd r_ad_J_lo = r_j, 2, r_ad5 // pointer to Tjlo
+}
+{ .mfi
+ ldfe f_Tmjhi = [r_ad_mJ_hi]
+ nop.f 0
+ add r_2Nm1 = r_signexp_0_5, r_N // signexp 2^(N-1)
+}
+;;
+
+{ .mmf
+ ldfs f_Tmjlo = [r_ad_mJ_lo]
+ setf.exp f_sneg = r_2mNm1 // Form 2^(-N-1)
+ nop.f 0
+}
+;;
+
+{ .mmf
+ ldfs f_Tjlo = [r_ad_J_lo]
+ setf.exp f_spos = r_2Nm1 // Form 2^(N-1)
+ nop.f 0
+}
+;;
+
+// ******************************************************
+// STEP 2 (TBL and EXP)
+// ******************************************************
+// Calculate Rsquared and Rcubed in preparation for p_even and p_odd
+
+{ .mmf
+ nop.m 0
+ nop.m 0
+ fma.s1 f_Rsq = f_R, f_R, f0
+}
+;;
+
+
+// Calculate p_even
+// B_2 + Rsq *B_3
+// B_1 + Rsq * (B_2 + Rsq *B_3)
+// p_even = Rsq * (B_1 + Rsq * (B_2 + Rsq *B_3))
+{ .mfi
+ nop.m 0
+ fma.s1 f_peven_temp1 = f_Rsq, f_B3, f_B2
+ nop.i 0
+}
+// Calculate p_odd
+// A_2 + Rsq *A_3
+// A_1 + Rsq * (A_2 + Rsq *A_3)
+// podd = R + Rcub * (A_1 + Rsq * (A_2 + Rsq *A_3))
+{ .mfi
+ nop.m 0
+ fma.s1 f_podd_temp1 = f_Rsq, f_A3, f_A2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_Rcub = f_Rsq, f_R, f0
+ nop.i 0
+}
+;;
+
+//
+// If TBL,
+// Calculate S_hi and S_lo, and C_hi
+// SC_hi_temp = sneg * Tmjhi
+// S_hi = spos * Tjhi - SC_hi_temp
+// S_hi = spos * Tjhi - (sneg * Tmjhi)
+// C_hi = spos * Tjhi + SC_hi_temp
+// C_hi = spos * Tjhi + (sneg * Tmjhi)
+
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_SC_hi_temp = f_sneg, f_Tmjhi, f0
+ nop.i 0
+}
+;;
+
+// If TBL,
+// C_lo_temp3 = sneg * Tmjlo
+// C_lo_temp4 = spos * Tjlo + C_lo_temp3
+// C_lo_temp4 = spos * Tjlo + (sneg * Tmjlo)
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_C_lo_temp3 = f_sneg, f_Tmjlo, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_peven_temp2 = f_Rsq, f_peven_temp1, f_B1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 f_podd_temp2 = f_Rsq, f_podd_temp1, f_A1
+ nop.i 0
+}
+;;
+
+// If EXP,
+// Compute 2^(N-1) * Tjhi and 2^(N-1) * Tjlo
+{ .mfi
+ nop.m 0
+(p7) fma.s1 f_Tjhi_spos = f_Tjhi, f_spos, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s1 f_Tjlo_spos = f_Tjlo, f_spos, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_C_hi = f_spos, f_Tjhi, f_SC_hi_temp
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fms.s1 f_S_hi = f_spos, f_Tjhi, f_SC_hi_temp
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_C_lo_temp4 = f_spos, f_Tjlo, f_C_lo_temp3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_peven = f_Rsq, f_peven_temp2, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 f_podd = f_podd_temp2, f_Rcub, f_R
+ nop.i 0
+}
+;;
+
+// If TBL,
+// C_lo_temp1 = spos * Tjhi - C_hi
+// C_lo_temp2 = sneg * Tmjlo + C_lo_temp1
+// C_lo_temp2 = sneg * Tmjlo + (spos * Tjhi - C_hi)
+
+{ .mfi
+ nop.m 0
+(p6) fms.s1 f_C_lo_temp1 = f_spos, f_Tjhi, f_C_hi
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_C_lo_temp2 = f_sneg, f_Tmjhi, f_C_lo_temp1
+ nop.i 0
+}
+;;
+
+// If EXP,
+// Y_hi = 2^(N-1) * Tjhi
+// Y_lo = 2^(N-1) * Tjhi * (p_odd + p_even) + 2^(N-1) * Tjlo
+{ .mfi
+ nop.m 0
+(p7) fma.s1 f_Y_lo_temp = f_peven, f1, f_podd
+ nop.i 0
+}
+;;
+
+// If TBL,
+// C_lo = C_lo_temp4 + C_lo_temp2
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_C_lo = f_C_lo_temp4, f1, f_C_lo_temp2
+ nop.i 0
+}
+;;
+
+// If TBL,
+// Y_hi = C_hi
+// Y_lo = S_hi*p_odd + (C_hi*p_even + C_lo)
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_Y_lo_temp = f_C_hi, f_peven, f_C_lo
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p7) fma.s1 f_Y_lo = f_Tjhi_spos, f_Y_lo_temp, f_Tjlo_spos
+ nop.i 0
+}
+;;
+
+// Dummy multiply to generate inexact
+{ .mfi
+ nop.m 0
+ fmpy.s0 f_tmp = f_B2, f_B2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_Y_lo = f_S_hi, f_podd, f_Y_lo_temp
+ nop.i 0
+}
+;;
+
+// f8 = answer = Y_hi + Y_lo
+{ .mfi
+ nop.m 0
+(p7) fma.s0 f8 = f_Y_lo, f1, f_Tjhi_spos
+ nop.i 0
+}
+;;
+
+// f8 = answer = Y_hi + Y_lo
+{ .mfb
+ nop.m 0
+(p6) fma.s0 f8 = f_Y_lo, f1, f_C_hi
+ br.ret.sptk b0 // Exit for COSH_BY_TBL and COSH_BY_EXP
+}
+;;
+
+
+// Here if 0 < |x| < 0.25
+COSH_BY_POLY:
+{ .mmf
+ ldfe f_P6 = [r_ad2e],16
+ ldfe f_P5 = [r_ad2o],16
+ nop.f 0
+}
+;;
+
+{ .mmi
+ ldfe f_P4 = [r_ad2e],16
+ ldfe f_P3 = [r_ad2o],16
+ nop.i 0
+}
+;;
+
+{ .mmi
+ ldfe f_P2 = [r_ad2e],16
+ ldfe f_P1 = [r_ad2o],16
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_X3 = f_NORM_X, f_X2, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 f_X4 = f_X2, f_X2, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_poly65 = f_X2, f_P6, f_P5
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 f_poly43 = f_X2, f_P4, f_P3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_poly21 = f_X2, f_P2, f_P1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_poly6543 = f_X4, f_poly65, f_poly43
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_poly6to1 = f_X4, f_poly6543, f_poly21
+ nop.i 0
+}
+;;
+
+// Dummy multiply to generate inexact
+{ .mfi
+ nop.m 0
+ fmpy.s0 f_tmp = f_P6, f_P6
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s0 f8 = f_poly6to1, f_X2, f1
+ br.ret.sptk b0 // Exit COSH_BY_POLY
+}
+;;
+
+
+// Here if x denorm or unorm
+COSH_DENORM:
+// Determine if x really a denorm and not a unorm
+{ .mmf
+ getf.exp r_signexp_x = f_NORM_X
+ mov r_exp_denorm = 0x0c001 // Real denorms have exp < this
+ fmerge.s f_ABS_X = f0, f_NORM_X
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s0 p10,p0 = f8, f0 // Set denorm flag
+ nop.i 0
+}
+;;
+
+// Set p8 if really a denorm
+{ .mmi
+ and r_exp_x = r_exp_mask, r_signexp_x
+;;
+ cmp.lt p8,p9 = r_exp_x, r_exp_denorm
+ nop.i 0
+}
+;;
+
+// Identify denormal operands.
+{ .mfb
+ nop.m 0
+(p8) fma.s0 f8 = f8,f8,f1 // If x denorm, result=1+x^2
+(p9) br.cond.sptk COSH_COMMON // Return to main path if x unorm
+}
+;;
+
+{ .mfb
+ nop.m 0
+ nop.f 0
+ br.ret.sptk b0 // Exit if x denorm
+}
+;;
+
+
+// Here if |x| >= overflow limit
+COSH_HUGE:
+// for COSH_HUGE, put 24000 in exponent; take sign from input
+{ .mmi
+ mov r_exp_huge = 0x15dbf
+;;
+ setf.exp f_huge = r_exp_huge
+ nop.i 0
+}
+;;
+
+{ .mfi
+ alloc r32 = ar.pfs,0,5,4,0
+ fma.s1 f_signed_hi_lo = f_huge, f1, f1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s0 f_pre_result = f_signed_hi_lo, f_huge, f0
+ mov GR_Parameter_TAG = 63
+}
+;;
+
+GLOBAL_IEEE754_END(coshl)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfe [GR_Parameter_Y] = f0,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfe [GR_Parameter_X] = f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = f_pre_result // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_exp.S b/libc/sysdeps/ia64/fpu/e_exp.S
new file mode 100644
index 000000000..fcc247fb1
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_exp.S
@@ -0,0 +1,793 @@
+.file "exp.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 2/02/00 Initial version
+// 3/07/00 exp(inf) = inf but now does NOT call error support
+// exp(-inf) = 0 but now does NOT call error support
+// 4/04/00 Unwind support added
+// 8/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 11/30/00 Reworked to shorten main path, widen main path to include all
+// args in normal range, and add quick exit for 0, nan, inf.
+// 12/05/00 Loaded constants earlier with setf to save 2 cycles.
+// 02/05/02 Corrected uninitialize predicate in POSSIBLE_UNDERFLOW path
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 09/07/02 Force inexact flag
+// 11/15/02 Split underflow path into zero/nonzero; eliminated fma in main path
+// 05/30/03 Set inexact flag on unmasked overflow/underflow
+// 03/31/05 Reformatted delimiters between data tables
+
+// API
+//==============================================================
+// double exp(double)
+
+// Overview of operation
+//==============================================================
+// Take the input x. w is "how many log2/128 in x?"
+// w = x * 128/log2
+// n = int(w)
+// x = n log2/128 + r + delta
+
+// n = 128M + index_1 + 2^4 index_2
+// x = M log2 + (log2/128) index_1 + (log2/8) index_2 + r + delta
+
+// exp(x) = 2^M 2^(index_1/128) 2^(index_2/8) exp(r) exp(delta)
+// Construct 2^M
+// Get 2^(index_1/128) from table_1;
+// Get 2^(index_2/8) from table_2;
+// Calculate exp(r) by 5th order polynomial
+// r = x - n (log2/128)_high
+// delta = - n (log2/128)_low
+// Calculate exp(delta) as 1 + delta
+
+
+// Special values
+//==============================================================
+// exp(+0) = 1.0
+// exp(-0) = 1.0
+
+// exp(+qnan) = +qnan
+// exp(-qnan) = -qnan
+// exp(+snan) = +qnan
+// exp(-snan) = -qnan
+
+// exp(-inf) = +0
+// exp(+inf) = +inf
+
+// Overflow and Underflow
+//=======================
+// exp(x) = largest double normal when
+// x = 709.7827 = 0x40862e42fefa39ef
+
+// exp(x) = smallest double normal when
+// x = -708.396 = 0xc086232bdd7abcd2
+
+// exp(x) = largest round-to-nearest single zero when
+// x = -745.1332 = 0xc0874910d52d3052
+
+
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input, output
+// f6 -> f15, f32 -> f49
+
+// General registers used:
+// r14 -> r40
+
+// Predicate registers used:
+// p6 -> p15
+
+// Assembly macros
+//==============================================================
+
+rRshf = r14
+rAD_TB1 = r15
+rAD_T1 = r15
+rAD_TB2 = r16
+rAD_T2 = r16
+rAD_P = r17
+rN = r18
+rIndex_1 = r19
+rIndex_2_16 = r20
+rM = r21
+rBiased_M = r21
+rIndex_1_16 = r21
+rSig_inv_ln2 = r22
+rExp_bias = r23
+rExp_mask = r24
+rTmp = r25
+rRshf_2to56 = r26
+rGt_ln = r27
+rExp_2tom56 = r28
+
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+fRSHF_2TO56 = f6
+fINV_LN2_2TO63 = f7
+fW_2TO56_RSH = f9
+f2TOM56 = f11
+fP5 = f12
+fP54 = f12
+fP5432 = f12
+fP4 = f13
+fP3 = f14
+fP32 = f14
+fP2 = f15
+fP = f15
+
+fLn2_by_128_hi = f33
+fLn2_by_128_lo = f34
+
+fRSHF = f35
+fNfloat = f36
+fNormX = f37
+fR = f38
+fF = f39
+
+fRsq = f40
+f2M = f41
+fS1 = f42
+fT1 = f42
+fS2 = f43
+fT2 = f43
+fS = f43
+fWre_urm_f8 = f44
+fFtz_urm_f8 = f44
+
+fMIN_DBL_OFLOW_ARG = f45
+fMAX_DBL_ZERO_ARG = f46
+fMAX_DBL_NORM_ARG = f47
+fMIN_DBL_NORM_ARG = f48
+fGt_pln = f49
+fTmp = f49
+
+
+// Data tables
+//==============================================================
+
+RODATA
+.align 16
+
+// ************* DO NOT CHANGE ORDER OF THESE TABLES ********************
+
+// double-extended 1/ln(2)
+// 3fff b8aa 3b29 5c17 f0bb be87fed0691d3e88
+// 3fff b8aa 3b29 5c17 f0bc
+// For speed the significand will be loaded directly with a movl and setf.sig
+// and the exponent will be bias+63 instead of bias+0. Thus subsequent
+// computations need to scale appropriately.
+// The constant 128/ln(2) is needed for the computation of w. This is also
+// obtained by scaling the computations.
+//
+// Two shifting constants are loaded directly with movl and setf.d.
+// 1. fRSHF_2TO56 = 1.1000..00 * 2^(63-7)
+// This constant is added to x*1/ln2 to shift the integer part of
+// x*128/ln2 into the rightmost bits of the significand.
+// The result of this fma is fW_2TO56_RSH.
+// 2. fRSHF = 1.1000..00 * 2^(63)
+// This constant is subtracted from fW_2TO56_RSH * 2^(-56) to give
+// the integer part of w, n, as a floating-point number.
+// The result of this fms is fNfloat.
+
+
+LOCAL_OBJECT_START(exp_table_1)
+data8 0x40862e42fefa39f0 // smallest dbl overflow arg, +709.7827
+data8 0xc0874910d52d3052 // largest arg for rnd-to-nearest 0 result, -745.133
+data8 0x40862e42fefa39ef // largest dbl arg to give normal dbl result, +709.7827
+data8 0xc086232bdd7abcd2 // smallest dbl arg to give normal dbl result, -708.396
+data8 0xb17217f7d1cf79ab , 0x00003ff7 // ln2/128 hi
+data8 0xc9e3b39803f2f6af , 0x00003fb7 // ln2/128 lo
+//
+// Table 1 is 2^(index_1/128) where
+// index_1 goes from 0 to 15
+//
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x80B1ED4FD999AB6C , 0x00003FFF
+data8 0x8164D1F3BC030773 , 0x00003FFF
+data8 0x8218AF4373FC25EC , 0x00003FFF
+data8 0x82CD8698AC2BA1D7 , 0x00003FFF
+data8 0x8383594EEFB6EE37 , 0x00003FFF
+data8 0x843A28C3ACDE4046 , 0x00003FFF
+data8 0x84F1F656379C1A29 , 0x00003FFF
+data8 0x85AAC367CC487B15 , 0x00003FFF
+data8 0x8664915B923FBA04 , 0x00003FFF
+data8 0x871F61969E8D1010 , 0x00003FFF
+data8 0x87DB357FF698D792 , 0x00003FFF
+data8 0x88980E8092DA8527 , 0x00003FFF
+data8 0x8955EE03618E5FDD , 0x00003FFF
+data8 0x8A14D575496EFD9A , 0x00003FFF
+data8 0x8AD4C6452C728924 , 0x00003FFF
+LOCAL_OBJECT_END(exp_table_1)
+
+// Table 2 is 2^(index_1/8) where
+// index_2 goes from 0 to 7
+LOCAL_OBJECT_START(exp_table_2)
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x8B95C1E3EA8BD6E7 , 0x00003FFF
+data8 0x9837F0518DB8A96F , 0x00003FFF
+data8 0xA5FED6A9B15138EA , 0x00003FFF
+data8 0xB504F333F9DE6484 , 0x00003FFF
+data8 0xC5672A115506DADD , 0x00003FFF
+data8 0xD744FCCAD69D6AF4 , 0x00003FFF
+data8 0xEAC0C6E7DD24392F , 0x00003FFF
+LOCAL_OBJECT_END(exp_table_2)
+
+
+LOCAL_OBJECT_START(exp_p_table)
+data8 0x3f8111116da21757 //P5
+data8 0x3fa55555d787761c //P4
+data8 0x3fc5555555555414 //P3
+data8 0x3fdffffffffffd6a //P2
+LOCAL_OBJECT_END(exp_p_table)
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(exp)
+
+{ .mlx
+ nop.m 0
+ movl rSig_inv_ln2 = 0xb8aa3b295c17f0bc // significand of 1/ln2
+}
+{ .mlx
+ addl rAD_TB1 = @ltoff(exp_table_1), gp
+ movl rRshf_2to56 = 0x4768000000000000 // 1.10000 2^(63+56)
+}
+;;
+
+{ .mfi
+ ld8 rAD_TB1 = [rAD_TB1]
+ fclass.m p8,p0 = f8,0x07 // Test for x=0
+ mov rExp_mask = 0x1ffff
+}
+{ .mfi
+ mov rExp_bias = 0xffff
+ fnorm.s1 fNormX = f8
+ mov rExp_2tom56 = 0xffff-56
+}
+;;
+
+// Form two constants we need
+// 1/ln2 * 2^63 to compute w = x * 1/ln2 * 128
+// 1.1000..000 * 2^(63+63-7) to right shift int(w) into the significand
+
+{ .mfi
+ setf.sig fINV_LN2_2TO63 = rSig_inv_ln2 // form 1/ln2 * 2^63
+ fclass.m p9,p0 = f8,0x22 // Test for x=-inf
+ nop.i 0
+}
+{ .mlx
+ setf.d fRSHF_2TO56 = rRshf_2to56 // Form const 1.100 * 2^(63+56)
+ movl rRshf = 0x43e8000000000000 // 1.10000 2^63 for right shift
+}
+;;
+
+{ .mfi
+ ldfpd fMIN_DBL_OFLOW_ARG, fMAX_DBL_ZERO_ARG = [rAD_TB1],16
+ fclass.m p10,p0 = f8,0x1e1 // Test for x=+inf, nan, NaT
+ nop.i 0
+}
+{ .mfb
+ setf.exp f2TOM56 = rExp_2tom56 // form 2^-56 for scaling Nfloat
+(p9) fma.d.s0 f8 = f0,f0,f0 // quick exit for x=-inf
+(p9) br.ret.spnt b0
+}
+;;
+
+{ .mfi
+ ldfpd fMAX_DBL_NORM_ARG, fMIN_DBL_NORM_ARG = [rAD_TB1],16
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+ setf.d fRSHF = rRshf // Form right shift const 1.100 * 2^63
+(p8) fma.d.s0 f8 = f1,f1,f0 // quick exit for x=0
+(p8) br.ret.spnt b0
+}
+;;
+
+{ .mfb
+ ldfe fLn2_by_128_hi = [rAD_TB1],16
+(p10) fma.d.s0 f8 = f8,f8,f0 // Result if x=+inf, nan, NaT
+(p10) br.ret.spnt b0 // quick exit for x=+inf, nan, NaT
+}
+;;
+
+{ .mfi
+ ldfe fLn2_by_128_lo = [rAD_TB1],16
+ fcmp.eq.s0 p6,p0 = f8, f0 // Dummy to set D
+ nop.i 0
+}
+;;
+
+// After that last load, rAD_TB1 points to the beginning of table 1
+
+// W = X * Inv_log2_by_128
+// By adding 1.10...0*2^63 we shift and get round_int(W) in significand.
+// We actually add 1.10...0*2^56 to X * Inv_log2 to do the same thing.
+
+{ .mfi
+ nop.m 0
+ fma.s1 fW_2TO56_RSH = fNormX, fINV_LN2_2TO63, fRSHF_2TO56
+ nop.i 0
+}
+;;
+
+// Divide arguments into the following categories:
+// Certain Underflow p11 - -inf < x <= MAX_DBL_ZERO_ARG
+// Possible Underflow p13 - MAX_DBL_ZERO_ARG < x < MIN_DBL_NORM_ARG
+// Certain Safe - MIN_DBL_NORM_ARG <= x <= MAX_DBL_NORM_ARG
+// Possible Overflow p14 - MAX_DBL_NORM_ARG < x < MIN_DBL_OFLOW_ARG
+// Certain Overflow p15 - MIN_DBL_OFLOW_ARG <= x < +inf
+//
+// If the input is really a double arg, then there will never be
+// "Possible Overflow" arguments.
+//
+
+{ .mfi
+ add rAD_TB2 = 0x100, rAD_TB1
+ fcmp.ge.s1 p15,p0 = fNormX,fMIN_DBL_OFLOW_ARG
+ nop.i 0
+}
+;;
+
+{ .mfi
+ add rAD_P = 0x80, rAD_TB2
+ fcmp.le.s1 p11,p0 = fNormX,fMAX_DBL_ZERO_ARG
+ nop.i 0
+}
+;;
+
+{ .mfb
+ ldfpd fP5, fP4 = [rAD_P] ,16
+ fcmp.gt.s1 p14,p0 = fNormX,fMAX_DBL_NORM_ARG
+(p15) br.cond.spnt EXP_CERTAIN_OVERFLOW
+}
+;;
+
+// Nfloat = round_int(W)
+// The signficand of fW_2TO56_RSH contains the rounded integer part of W,
+// as a twos complement number in the lower bits (that is, it may be negative).
+// That twos complement number (called N) is put into rN.
+
+// Since fW_2TO56_RSH is scaled by 2^56, it must be multiplied by 2^-56
+// before the shift constant 1.10000 * 2^63 is subtracted to yield fNfloat.
+// Thus, fNfloat contains the floating point version of N
+
+{ .mfb
+ ldfpd fP3, fP2 = [rAD_P]
+ fms.s1 fNfloat = fW_2TO56_RSH, f2TOM56, fRSHF
+(p11) br.cond.spnt EXP_CERTAIN_UNDERFLOW
+}
+;;
+
+{ .mfi
+ getf.sig rN = fW_2TO56_RSH
+ nop.f 0
+ nop.i 0
+}
+;;
+
+// rIndex_1 has index_1
+// rIndex_2_16 has index_2 * 16
+// rBiased_M has M
+// rIndex_1_16 has index_1 * 16
+
+// rM has true M
+// r = x - Nfloat * ln2_by_128_hi
+// f = 1 - Nfloat * ln2_by_128_lo
+{ .mfi
+ and rIndex_1 = 0x0f, rN
+ fnma.s1 fR = fNfloat, fLn2_by_128_hi, fNormX
+ shr rM = rN, 0x7
+}
+{ .mfi
+ and rIndex_2_16 = 0x70, rN
+ fnma.s1 fF = fNfloat, fLn2_by_128_lo, f1
+ nop.i 0
+}
+;;
+
+// rAD_T1 has address of T1
+// rAD_T2 has address if T2
+
+{ .mmi
+ add rBiased_M = rExp_bias, rM
+ add rAD_T2 = rAD_TB2, rIndex_2_16
+ shladd rAD_T1 = rIndex_1, 4, rAD_TB1
+}
+;;
+
+// Create Scale = 2^M
+{ .mmi
+ setf.exp f2M = rBiased_M
+ ldfe fT2 = [rAD_T2]
+ nop.i 0
+}
+;;
+
+// Load T1 and T2
+{ .mfi
+ ldfe fT1 = [rAD_T1]
+ fmpy.s0 fTmp = fLn2_by_128_lo, fLn2_by_128_lo // Force inexact
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRsq = fR, fR, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fP54 = fR, fP5, fP4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.lt.s1 p13,p0 = fNormX,fMIN_DBL_NORM_ARG
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fP32 = fR, fP3, fP2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP5432 = fRsq, fP54, fP32
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fS1 = f2M,fT1,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS2 = fF,fT2,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP = fRsq, fP5432, fR
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS = fS1,fS2,f0
+ nop.i 0
+}
+;;
+
+{ .mbb
+ nop.m 0
+(p13) br.cond.spnt EXP_POSSIBLE_UNDERFLOW
+(p14) br.cond.spnt EXP_POSSIBLE_OVERFLOW
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fS, fP, fS
+ br.ret.sptk b0 // Normal path exit
+}
+;;
+
+
+EXP_POSSIBLE_OVERFLOW:
+
+// Here if fMAX_DBL_NORM_ARG < x < fMIN_DBL_OFLOW_ARG
+// This cannot happen if input is a double, only if input higher precision.
+// Overflow is a possibility, not a certainty.
+
+// Recompute result using status field 2 with user's rounding mode,
+// and wre set. If result is larger than largest double, then we have
+// overflow
+
+{ .mfi
+ mov rGt_ln = 0x103ff // Exponent for largest dbl + 1 ulp
+ fsetc.s2 0x7F,0x42 // Get user's round mode, set wre
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp fGt_pln = rGt_ln // Create largest double + 1 ulp
+ fma.d.s2 fWre_urm_f8 = fS, fP, fS // Result with wre set
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40 // Turn off wre in sf2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p6, p0 = fWre_urm_f8, fGt_pln // Test for overflow
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p6) br.cond.spnt EXP_CERTAIN_OVERFLOW // Branch if overflow
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fS, fP, fS
+ br.ret.sptk b0 // Exit if really no overflow
+}
+;;
+
+EXP_CERTAIN_OVERFLOW:
+{ .mmi
+ sub rTmp = rExp_mask, r0, 1
+;;
+ setf.exp fTmp = rTmp
+ nop.i 0
+}
+;;
+
+{ .mfi
+ alloc r32=ar.pfs,1,4,4,0
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 14
+ fma.d.s0 FR_RESULT = fTmp, fTmp, fTmp // Set I,O and +INF result
+ br.cond.sptk __libm_error_region
+}
+;;
+
+EXP_POSSIBLE_UNDERFLOW:
+
+// Here if fMAX_DBL_ZERO_ARG < x < fMIN_DBL_NORM_ARG
+// Underflow is a possibility, not a certainty
+
+// We define an underflow when the answer with
+// ftz set
+// is zero (tiny numbers become zero)
+
+// Notice (from below) that if we have an unlimited exponent range,
+// then there is an extra machine number E between the largest denormal and
+// the smallest normal.
+
+// So if with unbounded exponent we round to E or below, then we are
+// tiny and underflow has occurred.
+
+// But notice that you can be in a situation where we are tiny, namely
+// rounded to E, but when the exponent is bounded we round to smallest
+// normal. So the answer can be the smallest normal with underflow.
+
+// E
+// -----+--------------------+--------------------+-----
+// | | |
+// 1.1...10 2^-3fff 1.1...11 2^-3fff 1.0...00 2^-3ffe
+// 0.1...11 2^-3ffe (biased, 1)
+// largest dn smallest normal
+
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x41 // Get user's round mode, set ftz
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.d.s2 fFtz_urm_f8 = fS, fP, fS // Result with ftz set
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40 // Turn off ftz in sf2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s1 p6, p7 = fFtz_urm_f8, f0 // Test for underflow
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.d.s0 f8 = fS, fP, fS // Compute result, set I, maybe U
+ nop.i 0
+}
+;;
+
+{ .mbb
+ nop.m 0
+(p6) br.cond.spnt EXP_UNDERFLOW_COMMON // Branch if really underflow
+(p7) br.ret.sptk b0 // Exit if really no underflow
+}
+;;
+
+EXP_CERTAIN_UNDERFLOW:
+// Here if x < fMAX_DBL_ZERO_ARG
+// Result will be zero (or smallest denorm if round to +inf) with I, U set
+{ .mmi
+ mov rTmp = 1
+;;
+ setf.exp fTmp = rTmp // Form small normal
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fmerge.se fTmp = fTmp, fLn2_by_128_lo // Small with signif lsb 1
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fTmp, fTmp, f0 // Set I,U, tiny (+0.0) result
+ br.cond.sptk EXP_UNDERFLOW_COMMON
+}
+;;
+
+EXP_UNDERFLOW_COMMON:
+// Determine if underflow result is zero or nonzero
+{ .mfi
+ alloc r32=ar.pfs,1,4,4,0
+ fcmp.eq.s1 p6, p0 = f8, f0
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fmerge.s FR_X = fNormX,fNormX
+(p6) br.cond.spnt EXP_UNDERFLOW_ZERO
+}
+;;
+
+EXP_UNDERFLOW_NONZERO:
+// Here if x < fMIN_DBL_NORM_ARG and result nonzero;
+// I, U are set
+{ .mfb
+ mov GR_Parameter_TAG = 15
+ nop.f 0 // FR_RESULT already set
+ br.cond.sptk __libm_error_region
+}
+;;
+
+EXP_UNDERFLOW_ZERO:
+// Here if x < fMIN_DBL_NORM_ARG and result zero;
+// I, U are set
+{ .mfb
+ mov GR_Parameter_TAG = 15
+ nop.f 0 // FR_RESULT already set
+ br.cond.sptk __libm_error_region
+}
+;;
+
+GLOBAL_IEEE754_END(exp)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_exp10.S b/libc/sysdeps/ia64/fpu/e_exp10.S
new file mode 100644
index 000000000..eafa59dd7
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_exp10.S
@@ -0,0 +1,605 @@
+.file "exp10.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/25/00 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 09/06/02 Improved performance; no inexact flags on exact cases
+// 01/29/03 Added missing } to bundle templates
+// 12/16/04 Call error handling on underflow.
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// double exp10(double)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// Let x= (K + fh + fl + r)/log2(10), where
+// K is an integer, fh= 0.b1 b2 b3 b4 b5,
+// fl= 2^{-5}* 0.b6 b7 b8 b8 b10 (fh, fl >= 0),
+// and |r|<2^{-11}
+// Th is a table that stores 2^fh (32 entries) rounded to
+// double extended precision (only mantissa is stored)
+// Tl is a table that stores 2^fl (32 entries) rounded to
+// double extended precision (only mantissa is stored)
+//
+// 10^x is approximated as
+// 2^K * Th [ f ] * Tl [ f ] * (1+c1*e+c1*r+c2*r^2+c3*r^3+c4*r^4),
+// where e= (x*log2(10)_hi-RN(x*log2(10)_hi))+log2(10)_lo*x
+
+// Note there are only 22 non-zero values that produce an exact result:
+// 1.0, 2.0, ... 22.0.
+// We test for these cases and use s1 to avoid setting the inexact flag.
+
+// Special values
+//==============================================================
+// exp10(0)= 1
+// exp10(+inf)= inf
+// exp10(-inf)= 0
+//
+
+// Registers used
+//==============================================================
+// r2-r3, r14-r40
+// f6-f15, f32-f52
+// p6-p12
+//
+
+
+GR_TBL_START = r2
+GR_LOG_TBL = r3
+
+GR_OF_LIMIT = r14
+GR_UF_LIMIT = r15
+GR_EXP_CORR = r16
+GR_F_low = r17
+GR_F_high = r18
+GR_K = r19
+GR_Flow_ADDR = r20
+
+GR_BIAS = r21
+GR_Fh = r22
+GR_Fh_ADDR = r23
+GR_EXPMAX = r24
+GR_BIAS53 = r25
+
+GR_ROUNDVAL = r26
+GR_SNORM_LIMIT = r26
+GR_MASK = r27
+GR_KF0 = r28
+GR_MASK_low = r29
+GR_COEFF_START = r30
+GR_exact_limit = r31
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+
+FR_COEFF1 = f6
+FR_COEFF2 = f7
+FR_R = f9
+FR_LOG2_10 = f10
+
+FR_2P53 = f11
+FR_KF0 = f12
+FR_COEFF3 = f13
+FR_COEFF4 = f14
+FR_UF_LIMIT = f15
+
+FR_OF_LIMIT = f32
+FR_DX_L210 = f33
+FR_ROUNDVAL = f34
+FR_KF = f35
+
+FR_2_TO_K = f36
+FR_T_low = f37
+FR_T_high = f38
+FR_P34 = f39
+FR_R2 = f40
+
+FR_P12 = f41
+FR_T_low_K = f42
+FR_P14 = f43
+FR_T = f44
+FR_P = f45
+
+FR_L2_10_low = f46
+FR_L2_10_high = f47
+FR_E0 = f48
+FR_E = f49
+FR_exact_limit = f50
+
+FR_int_x = f51
+FR_SNORM_LIMIT = f52
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+
+data8 0xd49a784bcd1b8afe, 0x00003fcb // log2(10)*2^(10-63)
+data8 0x9257edfe9b5fb698, 0x3fbf // log2(10)_low (bits 64...127)
+data8 0x3fac6b08d704a0c0, 0x3f83b2ab6fba4e77 // C_3 and C_4
+data8 0xb17217f7d1cf79ab, 0x00003ffe // C_1
+data8 0xf5fdeffc162c7541, 0x00003ffc // C_2
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+LOCAL_OBJECT_START(T_table)
+
+// 2^{0.00000 b6 b7 b8 b9 b10}
+data8 0x8000000000000000, 0x8016302f17467628
+data8 0x802c6436d0e04f50, 0x80429c17d77c18ed
+data8 0x8058d7d2d5e5f6b0, 0x806f17687707a7af
+data8 0x80855ad965e88b83, 0x809ba2264dada76a
+data8 0x80b1ed4fd999ab6c, 0x80c83c56b50cf77f
+data8 0x80de8f3b8b85a0af, 0x80f4e5ff089f763e
+data8 0x810b40a1d81406d4, 0x81219f24a5baa59d
+data8 0x813801881d886f7b, 0x814e67cceb90502c
+data8 0x8164d1f3bc030773, 0x817b3ffd3b2f2e47
+data8 0x8191b1ea15813bfd, 0x81a827baf7838b78
+data8 0x81bea1708dde6055, 0x81d51f0b8557ec1c
+data8 0x81eba08c8ad4536f, 0x820225f44b55b33b
+data8 0x8218af4373fc25eb, 0x822f3c7ab205c89a
+data8 0x8245cd9ab2cec048, 0x825c62a423d13f0c
+data8 0x8272fb97b2a5894c, 0x828998760d01faf3
+data8 0x82a0393fe0bb0ca8, 0x82b6ddf5dbc35906
+//
+// 2^{0.b1 b2 b3 b4 b5}
+data8 0x8000000000000000, 0x82cd8698ac2ba1d7
+data8 0x85aac367cc487b14, 0x88980e8092da8527
+data8 0x8b95c1e3ea8bd6e6, 0x8ea4398b45cd53c0
+data8 0x91c3d373ab11c336, 0x94f4efa8fef70961
+data8 0x9837f0518db8a96f, 0x9b8d39b9d54e5538
+data8 0x9ef5326091a111ad, 0xa27043030c496818
+data8 0xa5fed6a9b15138ea, 0xa9a15ab4ea7c0ef8
+data8 0xad583eea42a14ac6, 0xb123f581d2ac258f
+data8 0xb504f333f9de6484, 0xb8fbaf4762fb9ee9
+data8 0xbd08a39f580c36be, 0xc12c4cca66709456
+data8 0xc5672a115506dadd, 0xc9b9bd866e2f27a2
+data8 0xce248c151f8480e3, 0xd2a81d91f12ae45a
+data8 0xd744fccad69d6af4, 0xdbfbb797daf23755
+data8 0xe0ccdeec2a94e111, 0xe5b906e77c8348a8
+data8 0xeac0c6e7dd24392e, 0xefe4b99bdcdaf5cb
+data8 0xf5257d152486cc2c, 0xfa83b2db722a033a
+LOCAL_OBJECT_END(T_table)
+
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(exp10)
+
+
+{.mfi
+ alloc r32= ar.pfs, 1, 4, 4, 0
+ // will continue only for non-zero normal/denormal numbers
+ fclass.nm.unc p12, p7= f8, 0x1b
+ mov GR_BIAS53= 0xffff+63-10
+}
+{.mlx
+ // GR_TBL_START= pointer to log2(10), C_1...C_4 followed by T_table
+ addl GR_TBL_START= @ltoff(poly_coeffs), gp
+ movl GR_ROUNDVAL= 0x3fc00000 // 1.5 (SP)
+}
+;;
+
+{.mfi
+ ld8 GR_COEFF_START= [ GR_TBL_START ] // Load pointer to coeff table
+ fcmp.lt.s1 p6, p8= f8, f0 // X<0 ?
+ nop.i 0
+}
+;;
+
+{.mlx
+ setf.exp FR_2P53= GR_BIAS53 // 2^{63-10}
+ movl GR_UF_LIMIT= 0xc07439b746e36b52 // (-2^10-51) / log2(10)
+}
+{.mlx
+ setf.s FR_ROUNDVAL= GR_ROUNDVAL
+ movl GR_OF_LIMIT= 0x40734413509f79fe // Overflow threshold
+}
+;;
+
+{.mlx
+ ldfe FR_LOG2_10= [ GR_COEFF_START ], 16 // load log2(10)*2^(10-63)
+ movl GR_SNORM_LIMIT= 0xc0733a7146f72a41 // Smallest normal threshold
+}
+{.mib
+ nop.m 0
+ nop.i 0
+ (p12) br.cond.spnt SPECIAL_exp10 // Branch if nan, inf, zero
+}
+;;
+
+{.mmf
+ ldfe FR_L2_10_low= [ GR_COEFF_START ], 16 // load log2(10)_low
+ setf.d FR_OF_LIMIT= GR_OF_LIMIT // Set overflow limit
+ fma.s0 f8= f8, f1, f0 // normalize x
+}
+;;
+
+{.mfi
+ ldfpd FR_COEFF3, FR_COEFF4= [ GR_COEFF_START ], 16 // load C_3, C_4
+ (p8) fcvt.fx.s1 FR_int_x = f8 // Convert x to integer
+ nop.i 0
+}
+{.mfi
+ setf.d FR_UF_LIMIT= GR_UF_LIMIT // Set underflow limit
+ fma.s1 FR_KF0= f8, FR_LOG2_10, FR_ROUNDVAL // y= (x*log2(10)*2^10 +
+ // 1.5*2^63) * 2^(-63)
+ mov GR_EXP_CORR= 0xffff-126
+}
+;;
+
+{.mfi
+ setf.d FR_SNORM_LIMIT= GR_SNORM_LIMIT // Set smallest normal limit
+ fma.s1 FR_L2_10_high= FR_LOG2_10, FR_2P53, f0 // FR_LOG2_10= log2(10)_hi
+ nop.i 0
+}
+;;
+
+{.mfi
+ ldfe FR_COEFF1= [ GR_COEFF_START ], 16 // load C_1
+ fms.s1 FR_KF= FR_KF0, f1, FR_ROUNDVAL // (K+f)*2^(10-63)
+ mov GR_MASK= 1023
+}
+;;
+
+{.mfi
+ ldfe FR_COEFF2= [ GR_COEFF_START ], 16 // load C_2
+ fma.s1 FR_LOG2_10= f8, FR_L2_10_high, f0 // y0= x*log2(10)_hi
+ mov GR_MASK_low= 31
+}
+;;
+
+{.mlx
+ getf.sig GR_KF0= FR_KF0 // (K+f)*2^10= round_to_int(y)
+ (p8) movl GR_exact_limit= 0x41b00000 // Largest x for exact result,
+ // +22.0
+}
+;;
+
+{.mfi
+ add GR_LOG_TBL= 256, GR_COEFF_START // Pointer to high T_table
+ fcmp.gt.s1 p12, p7= f8, FR_OF_LIMIT // x>overflow threshold ?
+ nop.i 0
+}
+;;
+
+{.mfi
+ (p8) setf.s FR_exact_limit = GR_exact_limit // Largest x for exact result
+ (p8) fcvt.xf FR_int_x = FR_int_x // Integral part of x
+ shr GR_K= GR_KF0, 10 // K
+}
+{.mfi
+ and GR_F_high= GR_MASK, GR_KF0 // f_high*32
+ fnma.s1 FR_R= FR_KF, FR_2P53, FR_LOG2_10 // r= x*log2(10)-2^{63-10}*
+ // [ (K+f)*2^{10-63} ]
+ and GR_F_low= GR_KF0, GR_MASK_low // f_low
+}
+;;
+
+{.mmi
+ shladd GR_Flow_ADDR= GR_F_low, 3, GR_COEFF_START // address of 2^{f_low}
+ add GR_BIAS= GR_K, GR_EXP_CORR // K= bias-2*63
+ shr GR_Fh= GR_F_high, 5 // f_high
+}
+;;
+
+{.mfi
+ setf.exp FR_2_TO_K= GR_BIAS // 2^{K-126}
+ (p7) fcmp.lt.s1 p12, p7= f8, FR_UF_LIMIT // x<underflow threshold ?
+ shladd GR_Fh_ADDR= GR_Fh, 3, GR_LOG_TBL // address of 2^{f_high}
+}
+{.mfi
+ ldf8 FR_T_low= [ GR_Flow_ADDR ] // load T_low= 2^{f_low}
+ fms.s1 FR_DX_L210= f8, FR_L2_10_high, FR_LOG2_10 // x*log2(10)_hi-
+ // RN(x*log2(10)_hi)
+ nop.i 0
+}
+;;
+
+{.mfi
+ ldf8 FR_T_high= [ GR_Fh_ADDR ] // load T_high= 2^{f_high}
+ fma.s1 FR_P34= FR_COEFF4, FR_R, FR_COEFF3 // P34= C_3+C_4*r
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ fma.s1 FR_R2= FR_R, FR_R, f0 // r*r
+ (p12) br.cond.spnt OUT_RANGE_exp10
+}
+;;
+
+{.mfi
+ nop.m 0
+ // e= (x*log2(10)_hi-RN(x*log2(10)_hi))+log2(10)_lo*x
+ fma.s1 FR_E0= f8, FR_L2_10_low, FR_DX_L210
+ cmp.eq p7,p9= r0,r0 // Assume inexact result
+}
+{.mfi
+ nop.m 0
+ fma.s1 FR_P12= FR_COEFF2, FR_R, FR_COEFF1 // P12= C_1+C_2*r
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ (p8) fcmp.eq.s1 p9,p7= FR_int_x, f8 // Test x positive integer
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 FR_T_low_K= FR_T_low, FR_2_TO_K, f0 // T= 2^{K-126}*T_low
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fcmp.ge.s1 p11,p0= f8, FR_SNORM_LIMIT // Test x for normal range
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_E= FR_E0, FR_COEFF1, f0 // E= C_1*e
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 FR_P14= FR_R2, FR_P34, FR_P12 // P14= P12+r2*P34
+ nop.i 0
+}
+;;
+
+// If x a positive integer, will it produce an exact result?
+// p7 result will be inexact
+// p9 result will be exact
+{.mfi
+ nop.m 0
+ (p9) fcmp.le.s1 p9,p7= f8, FR_exact_limit // Test x gives exact result
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 FR_T= FR_T_low_K, FR_T_high, f0 // T= T*T_high
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_P= FR_P14, FR_R, FR_E // P= P14*r+E
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p7,p9
+{.mfi
+ nop.m 0
+ (p7) fma.d.s0 f8= FR_P, FR_T, FR_T // result= T+T*P, inexact set
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ (p9) fma.d.s1 f8= FR_P, FR_T, FR_T // result= T+T*P, exact use s1
+ (p11) br.ret.sptk b0 // return, if result normal
+}
+;;
+
+// Here if result in denormal range (and not zero)
+{.mib
+ nop.m 0
+ mov GR_Parameter_TAG= 265
+ br.cond.sptk __libm_error_region // Branch to error handling
+}
+;;
+
+SPECIAL_exp10:
+{.mfi
+ nop.m 0
+ fclass.m p6, p0= f8, 0x22 // x= -Infinity ?
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fclass.m p7, p0= f8, 0x21 // x= +Infinity ?
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fclass.m p8, p0= f8, 0x7 // x= +/-Zero ?
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ (p6) mov f8= f0 // exp10(-Infinity)= 0
+ (p6) br.ret.spnt b0
+}
+;;
+
+{.mfb
+ nop.m 0
+ nop.f 0
+ (p7) br.ret.spnt b0 // exp10(+Infinity)= +Infinity
+}
+;;
+
+{.mfb
+ nop.m 0
+ (p8) mov f8= f1 // exp10(+/-0)= 1
+ (p8) br.ret.spnt b0
+}
+;;
+
+{.mfb
+ nop.m 0
+ fma.d.s0 f8= f8, f1, f0 // Remaining cases: NaNs
+ br.ret.sptk b0
+}
+;;
+
+
+OUT_RANGE_exp10:
+
+// underflow: p6= 1
+// overflow: p8= 1
+
+.pred.rel "mutex",p6,p8
+{.mmi
+ (p8) mov GR_EXPMAX= 0x1fffe
+ (p6) mov GR_EXPMAX= 1
+ nop.i 0
+}
+;;
+
+{.mii
+ setf.exp FR_R= GR_EXPMAX
+ (p8) mov GR_Parameter_TAG= 166
+ (p6) mov GR_Parameter_TAG= 265
+}
+;;
+
+{.mfb
+ nop.m 0
+ fma.d.s0 f8= FR_R, FR_R, f0 // Create overflow/underflow
+ br.cond.sptk __libm_error_region // Branch to error handling
+}
+;;
+
+GLOBAL_IEEE754_END(exp10)
+weak_alias (exp10, pow10)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+.prologue
+{.mfi
+ add GR_Parameter_Y= -32, sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs, GR_SAVE_PFS
+ mov GR_SAVE_PFS= ar.pfs // Save ar.pfs
+}
+
+{.mfi
+.fframe 64
+ add sp= -64, sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP= gp // Save gp
+}
+;;
+
+{.mmi
+ stfd [ GR_Parameter_Y ]= FR_Y, 16 // STORE Parameter 2 on stack
+ add GR_Parameter_X= 16, sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0= b0 // Save b0
+}
+;;
+
+.body
+{.mib
+ stfd [ GR_Parameter_X ]= FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT= 0, GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{.mib
+ stfd [ GR_Parameter_Y ]= FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y= -16, GR_Parameter_Y
+ br.call.sptk b0= __libm_error_support# // Call error handling function
+}
+;;
+
+{.mmi
+ add GR_Parameter_RESULT= 48, sp
+ nop.m 0
+ nop.i 0
+}
+;;
+
+{.mmi
+ ldfd f8= [ GR_Parameter_RESULT ] // Get return result off stack
+.restore sp
+ add sp= 64, sp // Restore stack pointer
+ mov b0= GR_SAVE_B0 // Restore return address
+}
+;;
+
+{.mib
+ mov gp= GR_SAVE_GP // Restore gp
+ mov ar.pfs= GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+}
+;;
+
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#, @function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_exp10f.S b/libc/sysdeps/ia64/fpu/e_exp10f.S
new file mode 100644
index 000000000..fa54e9039
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_exp10f.S
@@ -0,0 +1,557 @@
+.file "exp10f.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/25/00 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 09/06/02 Improved performance and accuracy; no inexact flags on exact cases
+// 01/29/03 Added missing } to bundle templates
+// 12/16/04 Call error handling on underflow.
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// float exp10f(float)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// Let x= (K + fh + fl + r)/log2(10), where
+// K is an integer, fh= 0.b1 b2 b3 b4 b5,
+// fl= 2^{-5}* 0.b6 b7 b8 b8 b10 (fh, fl >= 0),
+// and |r|<2^{-11}
+// Th is a table that stores 2^fh (32 entries) rounded to
+// double extended precision (only mantissa is stored)
+// Tl is a table that stores 2^fl (32 entries) rounded to
+// double extended precision (only mantissa is stored)
+//
+// 10^x is approximated as
+// 2^K * Th [ f ] * Tl [ f ] * (1+c1*r+c2*r^2)
+
+// Note there are only 10 non-zero values that produce an exact result:
+// 1.0, 2.0, ... 10.0.
+// We test for these cases and use s1 to avoid setting the inexact flag.
+
+// Special values
+//==============================================================
+// exp10(0)= 1
+// exp10(+inf)= inf
+// exp10(-inf)= 0
+//
+
+// Registers used
+//==============================================================
+// r2-r3, r14-r40
+// f6-f15, f32-f52
+// p6-p12
+//
+
+
+GR_TBL_START = r2
+GR_LOG_TBL = r3
+
+GR_OF_LIMIT = r14
+GR_UF_LIMIT = r15
+GR_EXP_CORR = r16
+GR_F_low = r17
+GR_F_high = r18
+GR_K = r19
+GR_Flow_ADDR = r20
+
+GR_BIAS = r21
+GR_Fh = r22
+GR_Fh_ADDR = r23
+GR_EXPMAX = r24
+
+GR_ROUNDVAL = r26
+GR_SNORM_LIMIT = r26
+GR_MASK = r27
+GR_KF0 = r28
+GR_MASK_low = r29
+GR_COEFF_START = r30
+GR_exact_limit = r31
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+
+FR_COEFF1 = f6
+FR_COEFF2 = f7
+FR_R = f9
+FR_LOG2_10 = f10
+
+FR_2P53 = f11
+FR_KF0 = f12
+FR_COEFF3 = f13
+FR_COEFF4 = f14
+FR_UF_LIMIT = f15
+
+FR_OF_LIMIT = f32
+FR_DX_L210 = f33
+FR_ROUNDVAL = f34
+FR_KF = f35
+
+FR_2_TO_K = f36
+FR_T_low = f37
+FR_T_high = f38
+
+FR_P12 = f41
+FR_T_low_K = f42
+FR_T = f44
+FR_P = f45
+
+FR_E = f49
+FR_exact_limit = f50
+
+FR_int_x = f51
+FR_SNORM_LIMIT = f52
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+
+data8 0xd49a784bcd1b8afe, 0x00003fcb // log2(10)*2^(10-63)
+data8 0xb17217f7d1cf79ab, 0x00004033 // C_1 * 2^53
+data8 0xf5fdeffc162c7541, 0x00004066 // C_2 * 2^106
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+LOCAL_OBJECT_START(T_table)
+
+// 2^{0.00000 b6 b7 b8 b9 b10}
+data8 0x8000000000000000, 0x8016302f17467628
+data8 0x802c6436d0e04f50, 0x80429c17d77c18ed
+data8 0x8058d7d2d5e5f6b0, 0x806f17687707a7af
+data8 0x80855ad965e88b83, 0x809ba2264dada76a
+data8 0x80b1ed4fd999ab6c, 0x80c83c56b50cf77f
+data8 0x80de8f3b8b85a0af, 0x80f4e5ff089f763e
+data8 0x810b40a1d81406d4, 0x81219f24a5baa59d
+data8 0x813801881d886f7b, 0x814e67cceb90502c
+data8 0x8164d1f3bc030773, 0x817b3ffd3b2f2e47
+data8 0x8191b1ea15813bfd, 0x81a827baf7838b78
+data8 0x81bea1708dde6055, 0x81d51f0b8557ec1c
+data8 0x81eba08c8ad4536f, 0x820225f44b55b33b
+data8 0x8218af4373fc25eb, 0x822f3c7ab205c89a
+data8 0x8245cd9ab2cec048, 0x825c62a423d13f0c
+data8 0x8272fb97b2a5894c, 0x828998760d01faf3
+data8 0x82a0393fe0bb0ca8, 0x82b6ddf5dbc35906
+//
+// 2^{0.b1 b2 b3 b4 b5}
+data8 0x8000000000000000, 0x82cd8698ac2ba1d7
+data8 0x85aac367cc487b14, 0x88980e8092da8527
+data8 0x8b95c1e3ea8bd6e6, 0x8ea4398b45cd53c0
+data8 0x91c3d373ab11c336, 0x94f4efa8fef70961
+data8 0x9837f0518db8a96f, 0x9b8d39b9d54e5538
+data8 0x9ef5326091a111ad, 0xa27043030c496818
+data8 0xa5fed6a9b15138ea, 0xa9a15ab4ea7c0ef8
+data8 0xad583eea42a14ac6, 0xb123f581d2ac258f
+data8 0xb504f333f9de6484, 0xb8fbaf4762fb9ee9
+data8 0xbd08a39f580c36be, 0xc12c4cca66709456
+data8 0xc5672a115506dadd, 0xc9b9bd866e2f27a2
+data8 0xce248c151f8480e3, 0xd2a81d91f12ae45a
+data8 0xd744fccad69d6af4, 0xdbfbb797daf23755
+data8 0xe0ccdeec2a94e111, 0xe5b906e77c8348a8
+data8 0xeac0c6e7dd24392e, 0xefe4b99bdcdaf5cb
+data8 0xf5257d152486cc2c, 0xfa83b2db722a033a
+LOCAL_OBJECT_END(T_table)
+
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(exp10f)
+
+
+{.mfi
+ alloc r32= ar.pfs, 1, 4, 4, 0
+ // will continue only for non-zero normal/denormal numbers
+ fclass.nm.unc p12, p7= f8, 0x1b
+ nop.i 0
+}
+{.mlx
+ // GR_TBL_START= pointer to log2(10), C_1...C_4 followed by T_table
+ addl GR_TBL_START= @ltoff(poly_coeffs), gp
+ movl GR_ROUNDVAL= 0x3fc00000 // 1.5 (SP)
+}
+;;
+
+{.mfi
+ ld8 GR_COEFF_START= [ GR_TBL_START ] // Load pointer to coeff table
+ fcmp.lt.s1 p6, p8= f8, f0 // X<0 ?
+ nop.i 0
+}
+;;
+
+{.mlx
+ nop.m 0
+ movl GR_UF_LIMIT= 0xc2349e35 // (-2^7-22) / log2(10)
+}
+{.mlx
+ setf.s FR_ROUNDVAL= GR_ROUNDVAL
+ movl GR_OF_LIMIT= 0x421a209a // Overflow threshold
+}
+;;
+
+{.mlx
+ ldfe FR_LOG2_10= [ GR_COEFF_START ], 16 // load log2(10)*2^(10-63)
+ movl GR_SNORM_LIMIT= 0xc217b818 // Smallest normal threshold
+}
+{.mib
+ nop.m 0
+ nop.i 0
+ (p12) br.cond.spnt SPECIAL_exp10 // Branch if nan, inf, zero
+}
+;;
+
+{.mfi
+ setf.s FR_OF_LIMIT= GR_OF_LIMIT // Set overflow limit
+ fma.s0 f8= f8, f1, f0 // normalize x
+ nop.i 0
+}
+;;
+
+{.mfi
+ setf.s FR_SNORM_LIMIT= GR_SNORM_LIMIT // Set smallest normal limit
+ (p8) fcvt.fx.s1 FR_int_x = f8 // Convert x to integer
+ nop.i 0
+}
+{.mfi
+ setf.s FR_UF_LIMIT= GR_UF_LIMIT // Set underflow limit
+ fma.s1 FR_KF0= f8, FR_LOG2_10, FR_ROUNDVAL // y= (x*log2(10)*2^10 +
+ // 1.5*2^63) * 2^(-63)
+ mov GR_EXP_CORR= 0xffff-126
+}
+;;
+
+{.mfi
+ ldfe FR_COEFF1= [ GR_COEFF_START ], 16 // load C_1
+ fms.s1 FR_KF= FR_KF0, f1, FR_ROUNDVAL // (K+f)*2^(10-63)
+ mov GR_MASK= 1023
+}
+;;
+
+{.mfi
+ ldfe FR_COEFF2= [ GR_COEFF_START ], 16 // load C_2
+ nop.f 0
+ mov GR_MASK_low= 31
+}
+;;
+
+{.mlx
+ getf.sig GR_KF0= FR_KF0 // (K+f)*2^10= round_to_int(y)
+ (p8) movl GR_exact_limit= 0x41200000 // Largest x for exact result,
+ // +10.0
+}
+;;
+
+{.mfi
+ add GR_LOG_TBL= 256, GR_COEFF_START // Pointer to high T_table
+ fcmp.gt.s1 p12, p7= f8, FR_OF_LIMIT // x>overflow threshold ?
+ nop.i 0
+}
+;;
+
+{.mfi
+ (p8) setf.s FR_exact_limit = GR_exact_limit // Largest x for exact result
+ (p8) fcvt.xf FR_int_x = FR_int_x // Integral part of x
+ shr GR_K= GR_KF0, 10 // K
+}
+{.mfi
+ and GR_F_high= GR_MASK, GR_KF0 // f_high*32
+ fms.s1 FR_R= f8, FR_LOG2_10, FR_KF // r*2^(-53)= [ x*log2(10)-
+ // (K+f) ] *2^{10-63}
+ and GR_F_low= GR_KF0, GR_MASK_low // f_low
+}
+;;
+
+{.mmi
+ shladd GR_Flow_ADDR= GR_F_low, 3, GR_COEFF_START // address of 2^{f_low}
+ add GR_BIAS= GR_K, GR_EXP_CORR // K= bias-2*63
+ shr GR_Fh= GR_F_high, 5 // f_high
+}
+;;
+
+{.mfi
+ setf.exp FR_2_TO_K= GR_BIAS // 2^{K-126}
+ (p7) fcmp.lt.s1 p12, p7= f8, FR_UF_LIMIT // x<underflow threshold ?
+ shladd GR_Fh_ADDR= GR_Fh, 3, GR_LOG_TBL // address of 2^{f_high}
+}
+{.mfi
+ ldf8 FR_T_low= [ GR_Flow_ADDR ] // load T_low= 2^{f_low}
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{.mfb
+ ldf8 FR_T_high= [ GR_Fh_ADDR ] // load T_high= 2^{f_high}
+ fcmp.ge.s1 p11, p0= f8, FR_SNORM_LIMIT // Test x for normal range
+ (p12) br.cond.spnt OUT_RANGE_exp10
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_P12= FR_COEFF2, FR_R, FR_COEFF1 // P12= C_1+C_2*r
+ cmp.eq p7,p9= r0,r0 // Assume inexact result
+}
+;;
+
+{.mfi
+ nop.m 0
+ (p8) fcmp.eq.s1 p9,p7= FR_int_x, f8 // Test x positive integer
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 FR_T_low_K= FR_T_low, FR_2_TO_K, f0 // T= 2^{K-126}*T_low
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_P= FR_P12, FR_R, f0 // P= P12*r
+ nop.i 0
+}
+;;
+
+// If x a positive integer, will it produce an exact result?
+// p7 result will be inexact
+// p9 result will be exact
+{.mfi
+ nop.m 0
+ (p9) fcmp.le.s1 p9,p7= f8, FR_exact_limit // Test x gives exact result
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 FR_T= FR_T_low_K, FR_T_high, f0 // T= T*T_high
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p7,p9
+{.mfi
+ nop.m 0
+ (p7) fma.s.s0 f8= FR_P, FR_T, FR_T // result= T+T*P, inexact set
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ (p9) fma.s.s1 f8= FR_P, FR_T, FR_T // result= T+T*P, exact use s1
+ (p11) br.ret.sptk b0 // return, if result normal
+}
+;;
+
+// Here if result in denormal range (and not zero)
+{.mib
+ nop.m 0
+ mov GR_Parameter_TAG= 266
+ br.cond.sptk __libm_error_region // Branch to error handling
+}
+;;
+
+SPECIAL_exp10:
+{.mfi
+ nop.m 0
+ fclass.m p6, p0= f8, 0x22 // x= -Infinity ?
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fclass.m p7, p0= f8, 0x21 // x= +Infinity ?
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fclass.m p8, p0= f8, 0x7 // x= +/-Zero ?
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ (p6) mov f8= f0 // exp10(-Infinity)= 0
+ (p6) br.ret.spnt b0
+}
+;;
+
+{.mfb
+ nop.m 0
+ nop.f 0
+ (p7) br.ret.spnt b0 // exp10(+Infinity)= +Infinity
+}
+;;
+
+{.mfb
+ nop.m 0
+ (p8) mov f8= f1 // exp10(+/-0)= 1
+ (p8) br.ret.spnt b0
+}
+;;
+
+{.mfb
+ nop.m 0
+ fma.s.s0 f8= f8, f1, f0 // Remaining cases: NaNs
+ br.ret.sptk b0
+}
+;;
+
+
+OUT_RANGE_exp10:
+
+// underflow: p6= 1
+// overflow: p8= 1
+
+.pred.rel "mutex",p6,p8
+{.mmi
+ (p8) mov GR_EXPMAX= 0x1fffe
+ (p6) mov GR_EXPMAX= 1
+ nop.i 0
+}
+;;
+
+{.mii
+ setf.exp FR_R= GR_EXPMAX
+ (p8) mov GR_Parameter_TAG= 167
+ (p6) mov GR_Parameter_TAG= 266
+}
+;;
+
+{.mfb
+ nop.m 0
+ fma.s.s0 f8= FR_R, FR_R, f0 // Create overflow/underflow
+ br.cond.sptk __libm_error_region // Branch to error handling
+}
+;;
+
+GLOBAL_IEEE754_END(exp10f)
+weak_alias (exp10f, pow10f)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+.prologue
+{.mfi
+ add GR_Parameter_Y= -32, sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs, GR_SAVE_PFS
+ mov GR_SAVE_PFS= ar.pfs // Save ar.pfs
+}
+
+{.mfi
+.fframe 64
+ add sp= -64, sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP= gp // Save gp
+}
+;;
+
+{.mmi
+ stfs [ GR_Parameter_Y ]= FR_Y, 16 // STORE Parameter 2 on stack
+ add GR_Parameter_X= 16, sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0= b0 // Save b0
+}
+;;
+
+.body
+{.mib
+ stfs [ GR_Parameter_X ]= FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT= 0, GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{.mib
+ stfs [ GR_Parameter_Y ]= FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y= -16, GR_Parameter_Y
+ br.call.sptk b0= __libm_error_support# // Call error handling function
+}
+;;
+
+{.mmi
+ add GR_Parameter_RESULT= 48, sp
+ nop.m 0
+ nop.i 0
+}
+;;
+
+{.mmi
+ ldfs f8= [ GR_Parameter_RESULT ] // Get return result off stack
+.restore sp
+ add sp= 64, sp // Restore stack pointer
+ mov b0= GR_SAVE_B0 // Restore return address
+}
+;;
+
+{.mib
+ mov gp= GR_SAVE_GP // Restore gp
+ mov ar.pfs= GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+}
+;;
+
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#, @function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_exp10l.S b/libc/sysdeps/ia64/fpu/e_exp10l.S
new file mode 100644
index 000000000..a2e84b377
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_exp10l.S
@@ -0,0 +1,811 @@
+.file "exp10l.s"
+
+
+// Copyright (c) 2000 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/25/00 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 05/08/03 Reformatted assembly source; corrected overflow result for round to
+// -inf and round to zero; exact results now don't set inexact flag
+// 12/16/04 Call error handling on underflow.
+//
+// API
+//==============================================================
+// long double exp10l(long double)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// Let x= (K + f + r)/log2(10), where
+// K is an integer, f= 0.b1 b2... b8 (f>= 0),
+// and |r|<2^{-9}
+// T is a table that stores 2^f (256 entries) rounded to
+// double extended precision (only mantissa is stored)
+// D stores (2^f/T [ f ] - 1), rounded to single precision
+//
+// 10^x is approximated as
+// 2^K * T [ f ] * ((1+c1*r+c2*r^2+...+c6*r^6)*(1+c1*e)+D [ f ] ),
+// where e= log2(10)_lo*x+(log2(10)_hi*x-RN(log2(10)_hi*x))
+//
+
+
+
+// Special values
+//==============================================================
+// exp10(0)= 1
+// exp10(+inf)= inf
+// exp10(-inf)= 0
+//
+
+
+// Registers used
+//==============================================================
+// f6-f15, f32-f63
+// r14-r30, r32-r40
+// p6-p8, p11-p14
+//
+
+
+ FR_X = f10
+ FR_Y = f1
+ FR_RESULT = f8
+
+ FR_COEFF1 = f6
+ FR_COEFF2 = f7
+ FR_KF0 = f9
+ FR_LOG10 = f10
+ FR_CONST1 = f11
+ FR_XL10 = f12
+ FR_COEFF3 = f13
+ FR_COEFF4 = f14
+ FR_UF_TEST = f15
+ FR_OF_TEST = f32
+ FR_L10_LOW = f33
+ FR_COEFF5 = f34
+ FR_COEFF6 = f35
+ FR_L10 = f36
+ FR_C_L10 = f37
+ FR_XL10_H = f38
+ FR_XL10_L = f39
+ FR_KF = f40
+ FR_E = f41
+ FR_T = f42
+ FR_D = f43
+ FR_EXP_M_63 = f44
+ FR_R = f45
+ FR_E1 = f46
+ FR_COEFF2 = f47
+ FR_P34 = f48
+ FR_P56 = f49
+ FR_R2 = f50
+ FR_RE = f51
+ FR_D1 = f52
+ FR_P36 = f53
+ FR_R3E = f54
+ FR_P1 = f55
+ FR_P = f56
+ FR_T1 = f57
+ FR_XINT = f58
+ FR_XINTF = f59
+ FR_4 = f60
+ FR_28 = f61
+ FR_32 = f62
+ FR_SNORM_LIMIT = f63
+
+
+ GR_ADDR0 = r14
+ GR_D_ADDR = r15
+ GR_ADDR = r16
+ GR_B63 = r17
+ GR_KBITS = r18
+ GR_F = r19
+ GR_K = r20
+ GR_D = r21
+ GR_BM63 = r22
+ GR_T = r23
+ GR_CONST1 = r24
+ GR_EMIN = r25
+ GR_CONST2 = r26
+ GR_BM8 = r27
+ GR_SREG = r28
+ GR_4_BIAS = r29
+ GR_32_BIAS = r30
+
+ GR_SAVE_B0 = r33
+ GR_SAVE_PFS = r34
+ GR_SAVE_GP = r35
+ GR_SAVE_SP = r36
+
+ GR_Parameter_X = r37
+ GR_Parameter_Y = r38
+ GR_Parameter_RESULT= r39
+ GR_Parameter_TAG = r40
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+
+ data8 0xd49a784bcd1b8afe, 0x00004008 // log2(10)*2^8
+ data8 0x9a209a84fbcff798, 0x0000400b // overflow threshold
+ data8 0xb17217f7d1cf79ab, 0x00003ffe // C_1
+ data8 0xf5fdeffc162c7541, 0x00003ffc // C_2
+ data8 0x3fac6b08d704a0c0 // C_3
+ data8 0x3f83b2ab6fba4e77 // C_4
+ data8 0x3f55d87fe78a6731 // C_5
+ data8 0x3f2430912f86c787 // C_6
+ data8 0x9257edfe9b5fb698, 0x00003fbf // log2(10)_low (bits 64...127)
+ data8 0x9a1bc98027a81918, 0x0000c00b // Smallest normal threshold
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+LOCAL_OBJECT_START(T_table)
+
+ // 2^{0.b1 b2 b3 b4 b5 b6 b7 b8}
+ data8 0x8000000000000000, 0x8058d7d2d5e5f6b1
+ data8 0x80b1ed4fd999ab6c, 0x810b40a1d81406d4
+ data8 0x8164d1f3bc030773, 0x81bea1708dde6056
+ data8 0x8218af4373fc25ec, 0x8272fb97b2a5894c
+ data8 0x82cd8698ac2ba1d7, 0x83285071e0fc4547
+ data8 0x8383594eefb6ee37, 0x83dea15b9541b132
+ data8 0x843a28c3acde4046, 0x8495efb3303efd30
+ data8 0x84f1f656379c1a29, 0x854e3cd8f9c8c95d
+ data8 0x85aac367cc487b15, 0x86078a2f23642a9f
+ data8 0x8664915b923fba04, 0x86c1d919caef5c88
+ data8 0x871f61969e8d1010, 0x877d2afefd4e256c
+ data8 0x87db357ff698d792, 0x88398146b919f1d4
+ data8 0x88980e8092da8527, 0x88f6dd5af155ac6b
+ data8 0x8955ee03618e5fdd, 0x89b540a7902557a4
+ data8 0x8a14d575496efd9a, 0x8a74ac9a79896e47
+ data8 0x8ad4c6452c728924, 0x8b3522a38e1e1032
+ data8 0x8b95c1e3ea8bd6e7, 0x8bf6a434adde0085
+ data8 0x8c57c9c4646f4dde, 0x8cb932c1bae97a95
+ data8 0x8d1adf5b7e5ba9e6, 0x8d7ccfc09c50e2f8
+ data8 0x8ddf042022e69cd6, 0x8e417ca940e35a01
+ data8 0x8ea4398b45cd53c0, 0x8f073af5a2013520
+ data8 0x8f6a8117e6c8e5c4, 0x8fce0c21c6726481
+ data8 0x9031dc431466b1dc, 0x9095f1abc540ca6b
+ data8 0x90fa4c8beee4b12b, 0x915eed13c89689d3
+ data8 0x91c3d373ab11c336, 0x9228ffdc10a051ad
+ data8 0x928e727d9531f9ac, 0x92f42b88f673aa7c
+ data8 0x935a2b2f13e6e92c, 0x93c071a0eef94bc1
+ data8 0x9426ff0fab1c04b6, 0x948dd3ac8ddb7ed3
+ data8 0x94f4efa8fef70961, 0x955c5336887894d5
+ data8 0x95c3fe86d6cc7fef, 0x962bf1cbb8d97560
+ data8 0x96942d3720185a00, 0x96fcb0fb20ac4ba3
+ data8 0x97657d49f17ab08e, 0x97ce9255ec4357ab
+ data8 0x9837f0518db8a96f, 0x98a1976f7597e996
+ data8 0x990b87e266c189aa, 0x9975c1dd47518c77
+ data8 0x99e0459320b7fa65, 0x9a4b13371fd166ca
+ data8 0x9ab62afc94ff864a, 0x9b218d16f441d63d
+ data8 0x9b8d39b9d54e5539, 0x9bf93118f3aa4cc1
+ data8 0x9c6573682ec32c2d, 0x9cd200db8a0774cb
+ data8 0x9d3ed9a72cffb751, 0x9dabfdff6367a2aa
+ data8 0x9e196e189d472420, 0x9e872a276f0b98ff
+ data8 0x9ef5326091a111ae, 0x9f6386f8e28ba651
+ data8 0x9fd228256400dd06, 0xa041161b3d0121be
+ data8 0xa0b0510fb9714fc2, 0xa11fd9384a344cf7
+ data8 0xa18faeca8544b6e4, 0xa1ffd1fc25cea188
+ data8 0xa27043030c496819, 0xa2e102153e918f9e
+ data8 0xa3520f68e802bb93, 0xa3c36b345991b47c
+ data8 0xa43515ae09e6809e, 0xa4a70f0c95768ec5
+ data8 0xa5195786be9ef339, 0xa58bef536dbeb6ee
+ data8 0xa5fed6a9b15138ea, 0xa6720dc0be08a20c
+ data8 0xa6e594cfeee86b1e, 0xa7596c0ec55ff55b
+ data8 0xa7cd93b4e965356a, 0xa8420bfa298f70d1
+ data8 0xa8b6d5167b320e09, 0xa92bef41fa77771b
+ data8 0xa9a15ab4ea7c0ef8, 0xaa1717a7b5693979
+ data8 0xaa8d2652ec907629, 0xab0386ef48868de1
+ data8 0xab7a39b5a93ed337, 0xabf13edf162675e9
+ data8 0xac6896a4be3fe929, 0xace0413ff83e5d04
+ data8 0xad583eea42a14ac6, 0xadd08fdd43d01491
+ data8 0xae493452ca35b80e, 0xaec22c84cc5c9465
+ data8 0xaf3b78ad690a4375, 0xafb51906e75b8661
+ data8 0xb02f0dcbb6e04584, 0xb0a957366fb7a3c9
+ data8 0xb123f581d2ac2590, 0xb19ee8e8c94feb09
+ data8 0xb21a31a66618fe3b, 0xb295cff5e47db4a4
+ data8 0xb311c412a9112489, 0xb38e0e38419fae18
+ data8 0xb40aaea2654b9841, 0xb487a58cf4a9c180
+ data8 0xb504f333f9de6484, 0xb58297d3a8b9f0d2
+ data8 0xb60093a85ed5f76c, 0xb67ee6eea3b22b8f
+ data8 0xb6fd91e328d17791, 0xb77c94c2c9d725e9
+ data8 0xb7fbefca8ca41e7c, 0xb87ba337a1743834
+ data8 0xb8fbaf4762fb9ee9, 0xb97c143756844dbf
+ data8 0xb9fcd2452c0b9deb, 0xba7de9aebe5fea09
+ data8 0xbaff5ab2133e45fb, 0xbb81258d5b704b6f
+ data8 0xbc034a7ef2e9fb0d, 0xbc85c9c560e7b269
+ data8 0xbd08a39f580c36bf, 0xbd8bd84bb67ed483
+ data8 0xbe0f6809860993e2, 0xbe935317fc378238
+ data8 0xbf1799b67a731083, 0xbf9c3c248e2486f8
+ data8 0xc0213aa1f0d08db0, 0xc0a6956e8836ca8d
+ data8 0xc12c4cca66709456, 0xc1b260f5ca0fbb33
+ data8 0xc238d2311e3d6673, 0xc2bfa0bcfad907c9
+ data8 0xc346ccda24976407, 0xc3ce56c98d21b15d
+ data8 0xc4563ecc5334cb33, 0xc4de8523c2c07baa
+ data8 0xc5672a115506dadd, 0xc5f02dd6b0bbc3d9
+ data8 0xc67990b5aa245f79, 0xc70352f04336c51e
+ data8 0xc78d74c8abb9b15d, 0xc817f681416452b2
+ data8 0xc8a2d85c8ffe2c45, 0xc92e1a9d517f0ecc
+ data8 0xc9b9bd866e2f27a3, 0xca45c15afcc72624
+ data8 0xcad2265e4290774e, 0xcb5eecd3b38597c9
+ data8 0xcbec14fef2727c5d, 0xcc799f23d11510e5
+ data8 0xcd078b86503dcdd2, 0xcd95da6a9ff06445
+ data8 0xce248c151f8480e4, 0xceb3a0ca5dc6a55d
+ data8 0xcf4318cf191918c1, 0xcfd2f4683f94eeb5
+ data8 0xd06333daef2b2595, 0xd0f3d76c75c5db8d
+ data8 0xd184df6251699ac6, 0xd2164c023056bcab
+ data8 0xd2a81d91f12ae45a, 0xd33a5457a3029054
+ data8 0xd3ccf099859ac379, 0xd45ff29e0972c561
+ data8 0xd4f35aabcfedfa1f, 0xd5872909ab75d18a
+ data8 0xd61b5dfe9f9bce07, 0xd6aff9d1e13ba2fe
+ data8 0xd744fccad69d6af4, 0xd7da67311797f56a
+ data8 0xd870394c6db32c84, 0xd9067364d44a929c
+ data8 0xd99d15c278afd7b6, 0xda3420adba4d8704
+ data8 0xdacb946f2ac9cc72, 0xdb63714f8e295255
+ data8 0xdbfbb797daf23755, 0xdc9467913a4f1c92
+ data8 0xdd2d818508324c20, 0xddc705bcd378f7f0
+ data8 0xde60f4825e0e9124, 0xdefb4e1f9d1037f2
+ data8 0xdf9612deb8f04420, 0xe031430a0d99e627
+ data8 0xe0ccdeec2a94e111, 0xe168e6cfd3295d23
+ data8 0xe2055afffe83d369, 0xe2a23bc7d7d91226
+ data8 0xe33f8972be8a5a51, 0xe3dd444c46499619
+ data8 0xe47b6ca0373da88d, 0xe51a02ba8e26d681
+ data8 0xe5b906e77c8348a8, 0xe658797368b3a717
+ data8 0xe6f85aaaee1fce22, 0xe798aadadd5b9cbf
+ data8 0xe8396a503c4bdc68, 0xe8da9958464b42ab
+ data8 0xe97c38406c4f8c57, 0xea1e4756550eb27b
+ data8 0xeac0c6e7dd24392f, 0xeb63b74317369840
+ data8 0xec0718b64c1cbddc, 0xecaaeb8ffb03ab41
+ data8 0xed4f301ed9942b84, 0xedf3e6b1d418a491
+ data8 0xee990f980da3025b, 0xef3eab20e032bc6b
+ data8 0xefe4b99bdcdaf5cb, 0xf08b3b58cbe8b76a
+ data8 0xf13230a7ad094509, 0xf1d999d8b7708cc1
+ data8 0xf281773c59ffb13a, 0xf329c9233b6bae9c
+ data8 0xf3d28fde3a641a5b, 0xf47bcbbe6db9fddf
+ data8 0xf5257d152486cc2c, 0xf5cfa433e6537290
+ data8 0xf67a416c733f846e, 0xf7255510c4288239
+ data8 0xf7d0df730ad13bb9, 0xf87ce0e5b2094d9c
+ data8 0xf92959bb5dd4ba74, 0xf9d64a46eb939f35
+ data8 0xfa83b2db722a033a, 0xfb3193cc4227c3f4
+ data8 0xfbdfed6ce5f09c49, 0xfc8ec01121e447bb
+ data8 0xfd3e0c0cf486c175, 0xfdedd1b496a89f35
+ data8 0xfe9e115c7b8f884c, 0xff4ecb59511ec8a5
+LOCAL_OBJECT_END(T_table)
+
+
+LOCAL_OBJECT_START(D_table)
+ data4 0x00000000, 0x9f55c08f, 0x1e93ffa3, 0x1dcd43a8
+ data4 0x1f751f79, 0x9f3cdd88, 0x9f43d155, 0x1eda222c
+ data4 0x1ef35513, 0x9f597895, 0x9e698881, 0x1ec71073
+ data4 0x1e50e371, 0x9dc01e19, 0x1de74133, 0x1e2f028c
+ data4 0x9edefb47, 0x1ebbac48, 0x9e8b0330, 0x9e9e9314
+ data4 0x1edc1d11, 0x1f098529, 0x9f52827c, 0x1f50050d
+ data4 0x1f301e8e, 0x1f5b64d1, 0x9f45e3ee, 0x9ef64d6d
+ data4 0x1d6ec5e8, 0x9e61ad9a, 0x1d44ccbb, 0x9e4a8bbb
+ data4 0x9cf11576, 0x9dcce7e7, 0x9d02ac90, 0x1f26ccf0
+ data4 0x9f0877c6, 0x9ddd62ae, 0x9f4b7fc3, 0x1ea8ef6b
+ data4 0x1ea4378d, 0x1ef6fc38, 0x1db99fd9, 0x1f22bf6f
+ data4 0x1f53e172, 0x1e85504a, 0x9f37cc75, 0x1f0c5e17
+ data4 0x1dde8aac, 0x9cb42bb2, 0x1e153cd7, 0x1eb62bba
+ data4 0x9e9b941b, 0x9ea80e3c, 0x1f508823, 0x1ec3fd36
+ data4 0x1e9ffaa1, 0x1e21e2eb, 0x9d948b1d, 0x9e8ac93a
+ data4 0x1ef7ee6f, 0x9e80dda3, 0x1f0814be, 0x1dc5ddfe
+ data4 0x1eedb9d1, 0x9f2aaa26, 0x9ea5b0fc, 0x1edf702e
+ data4 0x9e391201, 0x1f1316bb, 0x1ea27fb7, 0x9e05ed18
+ data4 0x9f199ed2, 0x1ee7fd7c, 0x1f003db6, 0x9eac3793
+ data4 0x9e5b8c10, 0x9f3af17c, 0x1bc9a8be, 0x1ee3c004
+ data4 0x9f19b1b2, 0x9f242ce9, 0x9ce67dd1, 0x9e4f6275
+ data4 0x1e20742c, 0x1eb9328a, 0x9f477153, 0x1d969718
+ data4 0x9f1e6c43, 0x1f2f67f4, 0x9f39c7e4, 0x9e3c4feb
+ data4 0x1da3956b, 0x9e7c685d, 0x1f280911, 0x9f0d8afb
+ data4 0x1e314b40, 0x9eb4f250, 0x9f1a34ad, 0x1ef5d5e7
+ data4 0x9f145496, 0x1e604827, 0x9f1e5195, 0x1e9c1fc0
+ data4 0x1efde521, 0x1e69b385, 0x1f316830, 0x9f244eae
+ data4 0x1f1787ec, 0x9e939971, 0x1f0bb393, 0x9f0511d6
+ data4 0x1ed919de, 0x1d8b7b28, 0x1e5ca4a9, 0x1e7c357b
+ data4 0x9e3ff8e8, 0x1eef53b5, 0x9ed22ed7, 0x1f16659b
+ data4 0x9f2db102, 0x9e2c6a78, 0x1f328d7d, 0x9f2fec3c
+ data4 0x1eb395bd, 0x9f242b84, 0x9e2683e6, 0x1ed71e68
+ data4 0x1efd1df5, 0x9e9eeafd, 0x9ed2249c, 0x1eef129a
+ data4 0x1d1ea44c, 0x9e81f7ff, 0x1eaf77c9, 0x9ee7a285
+ data4 0x1e1864ed, 0x9ee7edbb, 0x9e15a27d, 0x9ae61655
+ data4 0x1f1ff1a2, 0x1da29755, 0x9e5f46fb, 0x1e901236
+ data4 0x9eecfb9b, 0x9f204d2f, 0x1ec64685, 0x9eb809bd
+ data4 0x9e0026c5, 0x1d9f1da1, 0x1f142b49, 0x9f20f22e
+ data4 0x1f24b067, 0x1f185a4c, 0x9f09765c, 0x9ece902f
+ data4 0x1e2ca5db, 0x1e6de464, 0x9f071f67, 0x1f1518c3
+ data4 0x1ea13ded, 0x1f0b8414, 0x1edb6ad4, 0x9e548740
+ data4 0x9ea10efb, 0x1ee48a60, 0x1e7954c5, 0x9edad013
+ data4 0x9f21517d, 0x9e9b6e0c, 0x9ee7f9a6, 0x9ebd4298
+ data4 0x9d65b24e, 0x1eed751f, 0x9f1573ea, 0x9d430377
+ data4 0x9e13fc0c, 0x1e47008a, 0x1e3d5c1d, 0x1ef41a91
+ data4 0x9e4a4ef7, 0x9e952f18, 0x1d620566, 0x1d9b8d33
+ data4 0x1db06247, 0x1e94b31e, 0x1f0730ad, 0x9d79ffb4
+ data4 0x1ed64d51, 0x9e91fd11, 0x9e28d35a, 0x9dea0ed9
+ data4 0x1e891def, 0x9ee28ac0, 0x1e1db99b, 0x9ee1ce38
+ data4 0x9bdd9bca, 0x1eb72cb9, 0x9e8c53c6, 0x1e0df6ca
+ data4 0x1e8f2ccd, 0x9e9b0886, 0x1eeb3bc7, 0x1ec7e772
+ data4 0x9e210776, 0x9daf246c, 0x1ea1f151, 0x1ece4dc6
+ data4 0x1ce741c8, 0x1ed3c88f, 0x9ec9a4fd, 0x9e0c8d30
+ data4 0x1d2fbb26, 0x9ef212a7, 0x1ee44f1c, 0x9e445550
+ data4 0x1e075f77, 0x9d9291a3, 0x1f09c2ee, 0x9e012c88
+ data4 0x1f057d62, 0x9e7bb0dc, 0x9d8758ee, 0x1ee8d6c1
+ data4 0x9e509a57, 0x9e4ca7b7, 0x1e2cb341, 0x9ec35106
+ data4 0x1ecf3baf, 0x1e11781c, 0x1ea0cc78, 0x1eb75ca6
+ data4 0x1e961e1a, 0x1eb88853, 0x1e7abf50, 0x1ee38704
+ data4 0x9dc5ab0f, 0x1afe197b, 0x9ec07523, 0x9d9b7f78
+ data4 0x1f011618, 0x1ed43b0b, 0x9f035945, 0x9e3fd014
+ data4 0x9bbda5cd, 0x9e83f8ab, 0x1e58a928, 0x1e392d61
+ data4 0x1efdbb52, 0x1ee310a8, 0x9ec7ecc1, 0x1e8c9ed6
+ data4 0x9ef82dee, 0x9e70545b, 0x9ea53fc4, 0x1e40f419
+LOCAL_OBJECT_END(D_table)
+
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(exp10l)
+
+{.mfi
+ alloc GR_SREG = ar.pfs, 1, 4, 4, 0
+ // will continue only for normal/denormal numbers
+ fclass.nm.unc p12, p7 = f8, 0x1b
+ // GR_ADDR0 = pointer to log2(10), C_1...C_6 followed by T_table
+ addl GR_ADDR0 = @ltoff(poly_coeffs), gp ;;
+}
+
+{.mfi
+ // load start address for C_1...C_6 followed by T_table
+ ld8 GR_ADDR0 = [ GR_ADDR0 ]
+ // X<0 ?
+ fcmp.lt.s1 p6, p8 = f8, f0
+ // GR_BM8 = bias-8
+ mov GR_BM8 = 0xffff-8
+}
+{.mlx
+ nop.m 0
+ // GR_EMIN = (-2^14-62)*2^{8}
+ movl GR_EMIN = 0xca807c00 ;;
+}
+
+{.mmb
+ // FR_CONST1 = 2^{-8}
+ setf.exp FR_CONST1 = GR_BM8
+ // load log2(10)*2^8
+ ldfe FR_LOG10 = [ GR_ADDR0 ], 16
+ (p12) br.cond.spnt SPECIAL_EXP10 ;;
+}
+
+{.mmf
+ setf.s FR_UF_TEST = GR_EMIN
+ // load overflow threshold
+ ldfe FR_OF_TEST = [ GR_ADDR0 ], 16
+ // normalize x
+ fma.s0 f8 = f8, f1, f0 ;;
+}
+
+{.mmi
+ // load C_1
+ ldfe FR_COEFF1 = [ GR_ADDR0 ], 16 ;;
+ // load C_2
+ ldfe FR_COEFF2 = [ GR_ADDR0 ], 16
+ nop.i 0 ;;
+}
+
+{.mmf
+ // GR_D_ADDR = pointer to D table
+ add GR_D_ADDR = 2048-64+96+32, GR_ADDR0
+ // load C_3, C_4
+ ldfpd FR_COEFF3, FR_COEFF4 = [ GR_ADDR0 ], 16
+ // y = x*log2(10)*2^8
+ fma.s1 FR_XL10 = f8, FR_LOG10, f0 ;;
+}
+
+{.mfi
+ // load C_5, C_6
+ ldfpd FR_COEFF5, FR_COEFF6 = [ GR_ADDR0 ], 16
+ // get int(x)
+ fcvt.fx.trunc.s1 FR_XINT = f8
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // FR_LOG10 = log2(10)
+ fma.s1 FR_L10 = FR_LOG10, FR_CONST1, f0
+ nop.i 0 ;;
+}
+
+{.mfi
+ // load log2(10)_low
+ ldfe FR_L10_LOW = [ GR_ADDR0 ], 16
+ // y0 = x*log2(10) = x*log2(10)_hi
+ fma.s1 FR_LOG10 = f8, FR_L10, f0
+ mov GR_EMIN = 0xffff-63
+}
+{.mfi
+ mov GR_32_BIAS = 0xffff + 5
+ // (K+f)*2^8 = round_to_int(y)
+ fcvt.fx.s1 FR_KF0 = FR_XL10
+ mov GR_4_BIAS = 0xffff + 2;;
+}
+
+{.mfi
+ // load smallest normal limit
+ ldfe FR_SNORM_LIMIT = [ GR_ADDR0 ], 16
+ // x>overflow threshold ?
+ fcmp.gt.s1 p12, p7 = f8, FR_OF_TEST
+ nop.i 0 ;;
+}
+
+{.mfi
+ setf.exp FR_32 = GR_32_BIAS
+ // x<underflow threshold ?
+ (p7) fcmp.lt.s1 p12, p7 = FR_XL10, FR_UF_TEST
+ nop.i 0 ;;
+}
+
+{.mfi
+ setf.exp FR_4 = GR_4_BIAS
+ fcvt.xf FR_XINTF = FR_XINT
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // FR_L10 = log2(10)_h*x-RN(log2(10)_h*x)
+ fms.s1 FR_L10 = f8, FR_L10, FR_LOG10
+ nop.i 0 ;;
+}
+
+{.mfi
+ getf.sig GR_BM8 = FR_KF0
+ fcvt.xf FR_KF0 = FR_KF0
+ mov GR_CONST2 = 255 ;;
+}
+
+{.mfi
+ // GR_CONST2 = f
+ and GR_CONST2 = GR_CONST2, GR_BM8
+ // FR_L10_LOW = e = log2(10)_l*x+(log2(10)_h*x-RN(log2(10)_h*x))
+ fma.s1 FR_L10_LOW = FR_L10_LOW, f8, FR_L10
+ // GR_BM8 = K
+ shr GR_BM8 = GR_BM8, 8 ;;
+}
+
+{.mmi
+ // address of D
+ shladd GR_D_ADDR = GR_CONST2, 2, GR_D_ADDR
+ // K+ = bias-63
+ add GR_BM8 = GR_BM8, GR_EMIN
+ // address of T
+ shladd GR_ADDR0 = GR_CONST2, 3, GR_ADDR0 ;;
+}
+
+{.mfb
+ // load D
+ ldfs FR_OF_TEST = [ GR_D_ADDR ]
+ // is input an integer ?
+ fcmp.eq.s1 p13, p14 = f8, FR_XINTF
+ (p12) br.cond.spnt OUT_RANGE_EXP10 ;;
+}
+
+{.mmf
+ // load T
+ ldf8 FR_UF_TEST = [ GR_ADDR0 ]
+ // FR_XL10 = 2^{K-63}
+ setf.exp FR_XL10 = GR_BM8
+ // r = x*log2(10)_hi-2^{-10}* [ (K+f)*2^{10} ]
+ fnma.s1 FR_KF0 = FR_KF0, FR_CONST1, FR_LOG10 ;;
+}
+
+{.mfi
+ nop.m 0
+ // get 28.0
+ fms.s1 FR_28 = FR_32, f1, FR_4
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // E = 1+C_1*e
+ fma.s1 FR_L10 = FR_L10_LOW, FR_COEFF1, f1
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // P12 = C_1+C_2*r
+ fma.s1 FR_COEFF2 = FR_COEFF2, FR_KF0, FR_COEFF1
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P34 = C_3+C_4*r
+ fma.s1 FR_COEFF4 = FR_COEFF4, FR_KF0, FR_COEFF3
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // P56 = C_5+C_6*r
+ fma.s1 FR_COEFF5 = FR_COEFF6, FR_KF0, FR_COEFF5
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // GR_ADDR0 = r*r
+ fma.s1 FR_COEFF3 = FR_KF0, FR_KF0, f0
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // if input is integer, is it positive ?
+ (p13) fcmp.ge.s1 p13, p14 = f8, f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // r' = r*E
+ fma.s1 FR_KF0 = FR_KF0, FR_L10, f0
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // D' = D+C_1*e
+ fma.s1 FR_OF_TEST = FR_L10_LOW, FR_COEFF1, FR_OF_TEST
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // test if x >= smallest normal limit
+ fcmp.ge.s1 p11, p0 = f8, FR_SNORM_LIMIT
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // P36 = P34+r2*P56
+ fma.s1 FR_COEFF4 = FR_COEFF5, FR_COEFF3, FR_COEFF4
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // GR_D_ADDR = r'*r2
+ fma.s1 FR_COEFF3 = FR_COEFF3, FR_KF0, f0
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // is input below 28.0 ?
+ (p13) fcmp.lt.s1 p13, p14 = f8, FR_28
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P' = P12*r'+D'
+ fma.s1 FR_COEFF2 = FR_COEFF2, FR_KF0, FR_OF_TEST
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // P = P'+r3*P36
+ fma.s1 FR_COEFF3 = FR_COEFF3, FR_COEFF4, FR_COEFF2
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // T = 2^{K-63}*T
+ fma.s1 FR_UF_TEST = FR_UF_TEST, FR_XL10, f0
+ nop.i 0 ;;
+}
+
+.pred.rel "mutex",p13,p14
+{.mfi
+ nop.m 0
+ (p13) fma.s1 f8 = FR_COEFF3, FR_UF_TEST, FR_UF_TEST
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ // result = T+T*P
+ (p14) fma.s0 f8 = FR_COEFF3, FR_UF_TEST, FR_UF_TEST
+ // return
+ (p11) br.ret.sptk b0 ;; // return, if result normal
+}
+
+// Here if result in denormal range (and not zero)
+{.mib
+ nop.m 0
+ mov GR_Parameter_TAG= 264
+ br.cond.sptk __libm_error_region // Branch to error handling
+}
+;;
+
+SPECIAL_EXP10:
+
+{.mfi
+ nop.m 0
+ // x = -Infinity ?
+ fclass.m p6, p0 = f8, 0x22
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // x = +Infinity ?
+ fclass.m p7, p0 = f8, 0x21
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // x = +/-Zero ?
+ fclass.m p8, p0 = f8, 0x7
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ // exp10(-Infinity) = 0
+ (p6) mov f8 = f0
+ (p6) br.ret.spnt b0 ;;
+}
+
+{.mfb
+ nop.m 0
+ // exp10(+Infinity) = +Infinity
+ nop.f 0
+ (p7) br.ret.spnt b0 ;;
+}
+
+{.mfb
+ nop.m 0
+ // exp10(+/-0) = 1
+ (p8) mov f8 = f1
+ (p8) br.ret.spnt b0 ;;
+}
+
+{.mfb
+ nop.m 0
+ // Remaining cases: NaNs
+ fma.s0 f8 = f8, f1, f0
+ br.ret.sptk b0 ;;
+}
+
+
+OUT_RANGE_EXP10:
+
+// underflow: p6 = 1
+// overflow: p8 = 1
+
+.pred.rel "mutex",p6,p8
+{.mmi
+ (p8) mov GR_CONST1 = 0x1fffe
+ (p6) mov GR_CONST1 = 1
+ nop.i 0
+}
+;;
+
+{.mii
+ setf.exp FR_KF0 = GR_CONST1
+ (p8) mov GR_Parameter_TAG = 165
+ (p6) mov GR_Parameter_TAG = 264
+}
+;;
+
+{.mfb
+ nop.m 999
+ fma.s0 f8 = FR_KF0, FR_KF0, f0 // Create overflow/underflow
+ br.cond.sptk __libm_error_region // Branch to error handling
+}
+;;
+
+GLOBAL_IEEE754_END(exp10l)
+weak_alias (exp10l, pow10l)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{.mfi
+ add GR_Parameter_Y = -32, sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs, GR_SAVE_PFS
+ mov GR_SAVE_PFS = ar.pfs // Save ar.pfs
+}
+
+{.mfi
+.fframe 64
+ add sp = -64, sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP = gp ;; // Save gp
+}
+
+{.mmi
+ stfe [ GR_Parameter_Y ] = FR_Y, 16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16, sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0 = b0 ;; // Save b0
+}
+
+.body
+{.mib
+ stfe [ GR_Parameter_X ] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0, GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{.mib
+ stfe [ GR_Parameter_Y ] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16, GR_Parameter_Y
+ br.call.sptk b0 = __libm_error_support# ;; // Call error handling function
+}
+
+{.mmi
+ add GR_Parameter_RESULT = 48, sp
+ nop.m 0
+ nop.i 0 ;;
+}
+
+{.mmi
+ ldfe f8 = [ GR_Parameter_RESULT ] // Get return result off stack
+.restore sp
+ add sp = 64, sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 ;; // Restore return address
+}
+
+{.mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 ;; // Return
+}
+
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#, @function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/e_exp2.S b/libc/sysdeps/ia64/fpu/e_exp2.S
new file mode 100644
index 000000000..54f652e38
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_exp2.S
@@ -0,0 +1,564 @@
+.file "exp2.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/25/00 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 09/05/02 Improved performance
+// 01/17/03 Fixed to call error support when x=1024.0
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// double exp2(double)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// Let x= (K + fh + fl + r), where
+// K is an integer, fh= 0.b1 b2 b3 b4 b5,
+// fl= 2^{-5}* 0.b6 b7 b8 b8 b10 (fh, fl >= 0),
+// and |r|<2^{-11}
+// Th is a table that stores 2^fh (32 entries) rounded to
+// double extended precision (only mantissa is stored)
+// Tl is a table that stores 2^fl (32 entries) rounded to
+// double extended precision (only mantissa is stored)
+//
+// 2^x is approximated as
+// 2^K * Th [ f ] * Tl [ f ] * (1+c1*r+c2*r^2+c3*r^3+c4*r^4)
+
+// Note: We use the following trick to speed up conversion from FP to integer:
+//
+// Let x = K + r, where K is an integer, and |r| <= 0.5
+// Let N be the number of significand bits for the FP format used
+// ( N=64 for double-extended, N=53 for double)
+//
+// Then let y = 1.5 * 2^(N-1) + x for RN mode
+// K = y - 1.5 * 2^(N-1)
+// r = x - K
+//
+// If we want to obtain the integer part and the first m fractional bits of x,
+// we can use the same trick, but with a constant of 1.5 * 2^(N-1-m):
+//
+// Let x = K + f + r
+// f = 0.b_1 b_2 ... b_m
+// |r| <= 2^(-m-1)
+//
+// Then let y = 1.5 * 2^(N-1-m) + x for RN mode
+// (K+f) = y - 1.5 * 2^(N-1-m)
+// r = x - K
+
+
+// Special values
+//==============================================================
+// exp2(0)= 1
+// exp2(+inf)= inf
+// exp2(-inf)= 0
+//
+
+// Registers used
+//==============================================================
+// r2-r3, r14-r40
+// f6-f15, f32-f45
+// p6-p8, p12
+//
+
+
+GR_TBL_START = r2
+GR_LOG_TBL = r3
+
+GR_OF_LIMIT = r14
+GR_UF_LIMIT = r15
+GR_EXP_CORR = r16
+GR_F_low = r17
+GR_F_high = r18
+GR_K = r19
+GR_Flow_ADDR = r20
+
+GR_BIAS = r21
+GR_Fh = r22
+GR_Fh_ADDR = r23
+GR_EXPMAX = r24
+GR_EMIN = r25
+
+GR_ROUNDVAL = r26
+GR_MASK = r27
+GR_KF0 = r28
+GR_MASK_low = r29
+GR_COEFF_START = r30
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+
+FR_COEFF1 = f6
+FR_COEFF2 = f7
+FR_R = f9
+
+FR_KF0 = f12
+FR_COEFF3 = f13
+FR_COEFF4 = f14
+FR_UF_LIMIT = f15
+
+FR_OF_LIMIT = f32
+FR_EXPMIN = f33
+FR_ROUNDVAL = f34
+FR_KF = f35
+
+FR_2_TO_K = f36
+FR_T_low = f37
+FR_T_high = f38
+FR_P34 = f39
+FR_R2 = f40
+
+FR_P12 = f41
+FR_T_low_K = f42
+FR_P14 = f43
+FR_T = f44
+FR_P = f45
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+
+data8 0x3fac6b08d704a0c0, 0x3f83b2ab6fba4e77 // C_3 and C_4
+data8 0xb17217f7d1cf79ab, 0x00003ffe // C_1
+data8 0xf5fdeffc162c7541, 0x00003ffc // C_2
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+LOCAL_OBJECT_START(T_table)
+
+// 2^{0.00000 b6 b7 b8 b9 b10}
+data8 0x8000000000000000, 0x8016302f17467628
+data8 0x802c6436d0e04f50, 0x80429c17d77c18ed
+data8 0x8058d7d2d5e5f6b0, 0x806f17687707a7af
+data8 0x80855ad965e88b83, 0x809ba2264dada76a
+data8 0x80b1ed4fd999ab6c, 0x80c83c56b50cf77f
+data8 0x80de8f3b8b85a0af, 0x80f4e5ff089f763e
+data8 0x810b40a1d81406d4, 0x81219f24a5baa59d
+data8 0x813801881d886f7b, 0x814e67cceb90502c
+data8 0x8164d1f3bc030773, 0x817b3ffd3b2f2e47
+data8 0x8191b1ea15813bfd, 0x81a827baf7838b78
+data8 0x81bea1708dde6055, 0x81d51f0b8557ec1c
+data8 0x81eba08c8ad4536f, 0x820225f44b55b33b
+data8 0x8218af4373fc25eb, 0x822f3c7ab205c89a
+data8 0x8245cd9ab2cec048, 0x825c62a423d13f0c
+data8 0x8272fb97b2a5894c, 0x828998760d01faf3
+data8 0x82a0393fe0bb0ca8, 0x82b6ddf5dbc35906
+//
+// 2^{0.b1 b2 b3 b4 b5}
+data8 0x8000000000000000, 0x82cd8698ac2ba1d7
+data8 0x85aac367cc487b14, 0x88980e8092da8527
+data8 0x8b95c1e3ea8bd6e6, 0x8ea4398b45cd53c0
+data8 0x91c3d373ab11c336, 0x94f4efa8fef70961
+data8 0x9837f0518db8a96f, 0x9b8d39b9d54e5538
+data8 0x9ef5326091a111ad, 0xa27043030c496818
+data8 0xa5fed6a9b15138ea, 0xa9a15ab4ea7c0ef8
+data8 0xad583eea42a14ac6, 0xb123f581d2ac258f
+data8 0xb504f333f9de6484, 0xb8fbaf4762fb9ee9
+data8 0xbd08a39f580c36be, 0xc12c4cca66709456
+data8 0xc5672a115506dadd, 0xc9b9bd866e2f27a2
+data8 0xce248c151f8480e3, 0xd2a81d91f12ae45a
+data8 0xd744fccad69d6af4, 0xdbfbb797daf23755
+data8 0xe0ccdeec2a94e111, 0xe5b906e77c8348a8
+data8 0xeac0c6e7dd24392e, 0xefe4b99bdcdaf5cb
+data8 0xf5257d152486cc2c, 0xfa83b2db722a033a
+LOCAL_OBJECT_END(T_table)
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(exp2)
+
+
+{.mfi
+ alloc r32= ar.pfs, 1, 4, 4, 0
+ // will continue only for non-zero normal/denormal numbers
+ fclass.nm p12, p0= f8, 0x1b
+ // GR_TBL_START= pointer to C_1...C_4 followed by T_table
+ addl GR_TBL_START= @ltoff(poly_coeffs), gp
+}
+{.mlx
+ mov GR_OF_LIMIT= 0xffff + 10 // Exponent of overflow limit
+ movl GR_ROUNDVAL= 0x5a400000 // 1.5*2^(63-10) (SP)
+}
+;;
+
+// Form special constant 1.5*2^(63-10) to give integer part and first 10
+// fractional bits of x
+{.mfi
+ setf.s FR_ROUNDVAL= GR_ROUNDVAL // Form special constant
+ fcmp.lt.s1 p6, p8= f8, f0 // X<0 ?
+ nop.i 0
+}
+{.mfb
+ ld8 GR_COEFF_START= [ GR_TBL_START ] // Load pointer to coeff table
+ nop.f 0
+ (p12) br.cond.spnt SPECIAL_exp2 // Branch if nan, inf, zero
+}
+;;
+
+{.mlx
+ setf.exp FR_OF_LIMIT= GR_OF_LIMIT // Set overflow limit
+ movl GR_UF_LIMIT= 0xc4866000 // (-2^10-51) = -1075
+}
+;;
+
+{.mfi
+ ldfpd FR_COEFF3, FR_COEFF4= [ GR_COEFF_START ], 16 // load C_3, C_4
+ fma.s0 f8= f8, f1, f0 // normalize x
+ nop.i 0
+}
+;;
+
+{.mmi
+ setf.s FR_UF_LIMIT= GR_UF_LIMIT // Set underflow limit
+ ldfe FR_COEFF1= [ GR_COEFF_START ], 16 // load C_1
+ mov GR_EXP_CORR= 0xffff-126
+}
+;;
+
+{.mfi
+ ldfe FR_COEFF2= [ GR_COEFF_START ], 16 // load C_2
+ fma.s1 FR_KF0= f8, f1, FR_ROUNDVAL // y= x + 1.5*2^(63-10)
+ nop.i 0
+}
+;;
+
+{.mfi
+ mov GR_MASK= 1023
+ fms.s1 FR_KF= FR_KF0, f1, FR_ROUNDVAL // (K+f)
+ mov GR_MASK_low= 31
+}
+;;
+
+{.mfi
+ getf.sig GR_KF0= FR_KF0 // (K+f)*2^10= round_to_int(y)
+ fcmp.ge.s1 p12, p7= f8, FR_OF_LIMIT // x >= overflow threshold ?
+ add GR_LOG_TBL= 256, GR_COEFF_START // Pointer to high T_table
+}
+;;
+
+{.mmi
+ and GR_F_low= GR_KF0, GR_MASK_low // f_low
+ and GR_F_high= GR_MASK, GR_KF0 // f_high*32
+ shr GR_K= GR_KF0, 10 // K
+}
+;;
+
+{.mmi
+ shladd GR_Flow_ADDR= GR_F_low, 3, GR_COEFF_START // address of 2^{f_low}
+ add GR_BIAS= GR_K, GR_EXP_CORR // K= bias-2*63
+ shr GR_Fh= GR_F_high, 5 // f_high
+}
+;;
+
+{.mfi
+ setf.exp FR_2_TO_K= GR_BIAS // 2^{K-126}
+ fnma.s1 FR_R= FR_KF, f1, f8 // r= x - (K+f)
+ shladd GR_Fh_ADDR= GR_Fh, 3, GR_LOG_TBL // address of 2^{f_high}
+}
+{.mlx
+ ldf8 FR_T_low= [ GR_Flow_ADDR ] // load T_low= 2^{f_low}
+ movl GR_EMIN= 0xc47f8000 // EMIN= -1022
+}
+;;
+
+{.mfi
+ ldf8 FR_T_high= [ GR_Fh_ADDR ] // load T_high= 2^{f_high}
+ (p7) fcmp.lt.s1 p12, p7= f8, FR_UF_LIMIT // x<underflow threshold ?
+ nop.i 0
+}
+;;
+
+{.mfi
+ setf.s FR_EXPMIN= GR_EMIN // FR_EXPMIN= EMIN
+ fma.s1 FR_P34= FR_COEFF4, FR_R, FR_COEFF3 // P34= C_3+C_4*r
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ fma.s1 FR_R2= FR_R, FR_R, f0 // r*r
+ (p12) br.cond.spnt OUT_RANGE_exp2
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_P12= FR_COEFF2, FR_R, FR_COEFF1 // P12= C_1+C_2*r
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_T_low_K= FR_T_low, FR_2_TO_K, f0 // T= 2^{K-126}*T_low
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_P14= FR_R2, FR_P34, FR_P12 // P14= P12+r2*P34
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_T= FR_T_low_K, FR_T_high, f0 // T= T*T_high
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fcmp.lt.s0 p6, p8= f8, FR_EXPMIN // underflow (x<EMIN) ?
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_P= FR_P14, FR_R, f0 // P= P14*r
+ nop.i 0
+}
+;;
+
+{.mfb
+ nop.m 0
+ fma.d.s0 f8= FR_P, FR_T, FR_T // result= T+T*P
+ (p8) br.ret.sptk b0 // return
+}
+;;
+
+{.mfb
+ (p6) mov GR_Parameter_TAG= 162
+ nop.f 0
+ (p6) br.cond.sptk __libm_error_region
+}
+;;
+
+
+SPECIAL_exp2:
+{.mfi
+ nop.m 0
+ fclass.m p6, p0= f8, 0x22 // x= -Infinity ?
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fclass.m p7, p0= f8, 0x21 // x= +Infinity ?
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fclass.m p8, p0= f8, 0x7 // x= +/-Zero ?
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ (p6) mov f8= f0 // exp2(-Infinity)= 0
+ (p6) br.ret.spnt b0
+}
+;;
+
+{.mfb
+ nop.m 0
+ nop.f 0
+ (p7) br.ret.spnt b0 // exp2(+Infinity)= +Infinity
+}
+;;
+
+{.mfb
+ nop.m 0
+ (p8) mov f8= f1 // exp2(+/-0)= 1
+ (p8) br.ret.spnt b0
+}
+;;
+
+{.mfb
+ nop.m 0
+ fma.d.s0 f8= f8, f1, f0 // Remaining cases: NaNs
+ br.ret.sptk b0
+}
+;;
+
+
+OUT_RANGE_exp2:
+
+// overflow: p8= 1
+
+{.mii
+ (p8) mov GR_EXPMAX= 0x1fffe
+ nop.i 0
+ nop.i 0
+}
+;;
+
+{.mmb
+ (p8) mov GR_Parameter_TAG= 161
+ (p8) setf.exp FR_R= GR_EXPMAX
+ nop.b 999
+}
+;;
+
+{.mfi
+ nop.m 999
+ (p8) fma.d.s0 f8= FR_R, FR_R, f0 // Create overflow
+ nop.i 999
+}
+// underflow: p6= 1
+{.mii
+ (p6) mov GR_Parameter_TAG= 162
+ (p6) mov GR_EXPMAX= 1
+ nop.i 0
+}
+;;
+
+{.mmb
+ nop.m 0
+ (p6) setf.exp FR_R= GR_EXPMAX
+ nop.b 999
+}
+;;
+
+{.mfb
+ nop.m 999
+ (p6) fma.d.s0 f8= FR_R, FR_R, f0 // Create underflow
+ nop.b 0
+}
+;;
+
+GLOBAL_LIBM_END(exp2)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+.prologue
+{.mfi
+ add GR_Parameter_Y= -32, sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs, GR_SAVE_PFS
+ mov GR_SAVE_PFS= ar.pfs // Save ar.pfs
+}
+
+{.mfi
+.fframe 64
+ add sp= -64, sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP= gp // Save gp
+}
+;;
+
+{.mmi
+ stfd [ GR_Parameter_Y ]= FR_Y, 16 // STORE Parameter 2 on stack
+ add GR_Parameter_X= 16, sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0= b0 // Save b0
+}
+;;
+
+.body
+{.mib
+ stfd [ GR_Parameter_X ]= FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT= 0, GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{.mib
+ stfd [ GR_Parameter_Y ]= FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y= -16, GR_Parameter_Y
+ br.call.sptk b0= __libm_error_support# // Call error handling function
+}
+;;
+
+{.mmi
+ add GR_Parameter_RESULT= 48, sp
+ nop.m 0
+ nop.i 0
+}
+;;
+
+{.mmi
+ ldfd f8= [ GR_Parameter_RESULT ] // Get return result off stack
+.restore sp
+ add sp= 64, sp // Restore stack pointer
+ mov b0= GR_SAVE_B0 // Restore return address
+}
+;;
+
+{.mib
+ mov gp= GR_SAVE_GP // Restore gp
+ mov ar.pfs= GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+}
+;;
+
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#, @function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_exp2f.S b/libc/sysdeps/ia64/fpu/e_exp2f.S
new file mode 100644
index 000000000..36354ae3b
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_exp2f.S
@@ -0,0 +1,539 @@
+.file "exp2f.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/25/00 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 09/05/02 Improved performance and accuracy
+// 01/17/03 Fixed to call error support when x=128.0
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// float exp2f(float)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// Let x= (K + fh + fl + r), where
+// K is an integer, fh= 0.b1 b2 b3 b4 b5,
+// fl= 2^{-5}* 0.b6 b7 b8 b8 b10 (fh, fl >= 0),
+// and |r|<2^{-11}
+// Th is a table that stores 2^fh (32 entries) rounded to
+// double extended precision (only mantissa is stored)
+// Tl is a table that stores 2^fl (32 entries) rounded to
+// double extended precision (only mantissa is stored)
+//
+// 2^x is approximated as
+// 2^K * Th [ f ] * Tl [ f ] * (1+c1*r+c2*r^2)
+
+// Note: We use the following trick to speed up conversion from FP to integer:
+//
+// Let x = K + r, where K is an integer, and |r| <= 0.5
+// Let N be the number of significand bits for the FP format used
+// ( N=64 for double-extended, N=53 for double)
+//
+// Then let y = 1.5 * 2^(N-1) + x for RN mode
+// K = y - 1.5 * 2^(N-1)
+// r = x - K
+//
+// If we want to obtain the integer part and the first m fractional bits of x,
+// we can use the same trick, but with a constant of 1.5 * 2^(N-1-m):
+//
+// Let x = K + f + r
+// f = 0.b_1 b_2 ... b_m
+// |r| <= 2^(-m-1)
+//
+// Then let y = 1.5 * 2^(N-1-m) + x for RN mode
+// (K+f) = y - 1.5 * 2^(N-1-m)
+// r = x - K
+
+
+// Special values
+//==============================================================
+// exp2(0)= 1
+// exp2(+inf)= inf
+// exp2(-inf)= 0
+//
+
+// Registers used
+//==============================================================
+// r2-r3, r14-r40
+// f6-f15, f32-f45
+// p6-p8, p12
+//
+
+
+GR_TBL_START = r2
+GR_LOG_TBL = r3
+
+GR_OF_LIMIT = r14
+GR_UF_LIMIT = r15
+GR_EXP_CORR = r16
+GR_F_low = r17
+GR_F_high = r18
+GR_K = r19
+GR_Flow_ADDR = r20
+
+GR_BIAS = r21
+GR_Fh = r22
+GR_Fh_ADDR = r23
+GR_EXPMAX = r24
+GR_EMIN = r25
+
+GR_ROUNDVAL = r26
+GR_MASK = r27
+GR_KF0 = r28
+GR_MASK_low = r29
+GR_COEFF_START = r30
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+
+FR_COEFF1 = f6
+FR_COEFF2 = f7
+FR_R = f9
+
+FR_KF0 = f12
+FR_UF_LIMIT = f15
+
+FR_OF_LIMIT = f32
+FR_EXPMIN = f33
+FR_ROUNDVAL = f34
+FR_KF = f35
+
+FR_2_TO_K = f36
+FR_T_low = f37
+FR_T_high = f38
+
+FR_P12 = f41
+FR_T_low_K = f42
+FR_T = f44
+FR_P = f45
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+
+data8 0xb17217f7d1cf79ab, 0x00003ffe // C_1
+data8 0xf5fdeffc162c7541, 0x00003ffc // C_2
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+LOCAL_OBJECT_START(T_table)
+
+// 2^{0.00000 b6 b7 b8 b9 b10}
+data8 0x8000000000000000, 0x8016302f17467628
+data8 0x802c6436d0e04f50, 0x80429c17d77c18ed
+data8 0x8058d7d2d5e5f6b0, 0x806f17687707a7af
+data8 0x80855ad965e88b83, 0x809ba2264dada76a
+data8 0x80b1ed4fd999ab6c, 0x80c83c56b50cf77f
+data8 0x80de8f3b8b85a0af, 0x80f4e5ff089f763e
+data8 0x810b40a1d81406d4, 0x81219f24a5baa59d
+data8 0x813801881d886f7b, 0x814e67cceb90502c
+data8 0x8164d1f3bc030773, 0x817b3ffd3b2f2e47
+data8 0x8191b1ea15813bfd, 0x81a827baf7838b78
+data8 0x81bea1708dde6055, 0x81d51f0b8557ec1c
+data8 0x81eba08c8ad4536f, 0x820225f44b55b33b
+data8 0x8218af4373fc25eb, 0x822f3c7ab205c89a
+data8 0x8245cd9ab2cec048, 0x825c62a423d13f0c
+data8 0x8272fb97b2a5894c, 0x828998760d01faf3
+data8 0x82a0393fe0bb0ca8, 0x82b6ddf5dbc35906
+//
+// 2^{0.b1 b2 b3 b4 b5}
+data8 0x8000000000000000, 0x82cd8698ac2ba1d7
+data8 0x85aac367cc487b14, 0x88980e8092da8527
+data8 0x8b95c1e3ea8bd6e6, 0x8ea4398b45cd53c0
+data8 0x91c3d373ab11c336, 0x94f4efa8fef70961
+data8 0x9837f0518db8a96f, 0x9b8d39b9d54e5538
+data8 0x9ef5326091a111ad, 0xa27043030c496818
+data8 0xa5fed6a9b15138ea, 0xa9a15ab4ea7c0ef8
+data8 0xad583eea42a14ac6, 0xb123f581d2ac258f
+data8 0xb504f333f9de6484, 0xb8fbaf4762fb9ee9
+data8 0xbd08a39f580c36be, 0xc12c4cca66709456
+data8 0xc5672a115506dadd, 0xc9b9bd866e2f27a2
+data8 0xce248c151f8480e3, 0xd2a81d91f12ae45a
+data8 0xd744fccad69d6af4, 0xdbfbb797daf23755
+data8 0xe0ccdeec2a94e111, 0xe5b906e77c8348a8
+data8 0xeac0c6e7dd24392e, 0xefe4b99bdcdaf5cb
+data8 0xf5257d152486cc2c, 0xfa83b2db722a033a
+LOCAL_OBJECT_END(T_table)
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(exp2f)
+
+
+{.mfi
+ alloc r32= ar.pfs, 1, 4, 4, 0
+ // will continue only for non-zero normal/denormal numbers
+ fclass.nm p12, p0= f8, 0x1b
+ // GR_TBL_START= pointer to C_1...C_2 followed by T_table
+ addl GR_TBL_START= @ltoff(poly_coeffs), gp
+}
+{.mlx
+ mov GR_OF_LIMIT= 0xffff + 7 // Exponent of overflow limit
+ movl GR_ROUNDVAL= 0x5a400000 // 1.5*2^(63-10) (SP)
+}
+;;
+
+// Form special constant 1.5*2^(63-10) to give integer part and first 10
+// fractional bits of x
+{.mfi
+ setf.s FR_ROUNDVAL= GR_ROUNDVAL // Form special constant
+ fcmp.lt.s1 p6, p8= f8, f0 // X<0 ?
+ nop.i 0
+}
+{.mfb
+ ld8 GR_COEFF_START= [ GR_TBL_START ] // Load pointer to coeff table
+ nop.f 0
+ (p12) br.cond.spnt SPECIAL_exp2 // Branch if nan, inf, zero
+}
+;;
+
+{.mlx
+ setf.exp FR_OF_LIMIT= GR_OF_LIMIT // Set overflow limit
+ movl GR_UF_LIMIT= 0xc3160000 // (-2^7-22) = -150
+}
+;;
+
+{.mfi
+ ldfe FR_COEFF1= [ GR_COEFF_START ], 16 // load C_1
+ fma.s0 f8= f8, f1, f0 // normalize x
+ nop.i 0
+}
+;;
+
+{.mmi
+ ldfe FR_COEFF2= [ GR_COEFF_START ], 16 // load C_2
+ setf.s FR_UF_LIMIT= GR_UF_LIMIT // Set underflow limit
+ mov GR_EXP_CORR= 0xffff-126
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_KF0= f8, f1, FR_ROUNDVAL // y= x + 1.5*2^(63-10)
+ nop.i 0
+}
+;;
+
+{.mfi
+ mov GR_MASK= 1023
+ fms.s1 FR_KF= FR_KF0, f1, FR_ROUNDVAL // (K+f)
+ mov GR_MASK_low= 31
+}
+;;
+
+{.mfi
+ getf.sig GR_KF0= FR_KF0 // (K+f)*2^10= round_to_int(y)
+ fcmp.ge.s1 p12, p7= f8, FR_OF_LIMIT // x >= overflow threshold ?
+ add GR_LOG_TBL= 256, GR_COEFF_START // Pointer to high T_table
+}
+;;
+
+{.mmi
+ and GR_F_low= GR_KF0, GR_MASK_low // f_low
+ and GR_F_high= GR_MASK, GR_KF0 // f_high*32
+ shr GR_K= GR_KF0, 10 // K
+}
+;;
+
+{.mmi
+ shladd GR_Flow_ADDR= GR_F_low, 3, GR_COEFF_START // address of 2^{f_low}
+ add GR_BIAS= GR_K, GR_EXP_CORR // K= bias-2*63
+ shr GR_Fh= GR_F_high, 5 // f_high
+}
+;;
+
+{.mfi
+ setf.exp FR_2_TO_K= GR_BIAS // 2^{K-126}
+ fnma.s1 FR_R= FR_KF, f1, f8 // r= x - (K+f)
+ shladd GR_Fh_ADDR= GR_Fh, 3, GR_LOG_TBL // address of 2^{f_high}
+}
+{.mlx
+ ldf8 FR_T_low= [ GR_Flow_ADDR ] // load T_low= 2^{f_low}
+ movl GR_EMIN= 0xc2fc0000 // EMIN= -126
+}
+;;
+
+{.mfi
+ ldf8 FR_T_high= [ GR_Fh_ADDR ] // load T_high= 2^{f_high}
+ (p7) fcmp.lt.s1 p12, p7= f8, FR_UF_LIMIT // x<underflow threshold ?
+ nop.i 0
+}
+;;
+
+{.mfb
+ setf.s FR_EXPMIN= GR_EMIN // FR_EXPMIN= EMIN
+ fma.s1 FR_P12= FR_COEFF2, FR_R, FR_COEFF1 // P12= C_1+C_2*r
+ (p12) br.cond.spnt OUT_RANGE_exp2
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_T_low_K= FR_T_low, FR_2_TO_K, f0 // T= 2^{K-126}*T_low
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_P= FR_R, FR_P12, f0 // P= P12+r
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fma.s1 FR_T= FR_T_low_K, FR_T_high, f0 // T= T*T_high
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fcmp.lt.s0 p6, p8= f8, FR_EXPMIN // underflow (x<EMIN) ?
+ nop.i 0
+}
+;;
+
+{.mfb
+ nop.m 0
+ fma.s.s0 f8= FR_P, FR_T, FR_T // result= T+T*P
+ (p8) br.ret.sptk b0 // return
+}
+;;
+
+{.mfb
+ (p6) mov GR_Parameter_TAG= 164
+ nop.f 0
+ (p6) br.cond.sptk __libm_error_region
+}
+;;
+
+
+SPECIAL_exp2:
+{.mfi
+ nop.m 0
+ fclass.m p6, p0= f8, 0x22 // x= -Infinity ?
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fclass.m p7, p0= f8, 0x21 // x= +Infinity ?
+ nop.i 0
+}
+;;
+
+{.mfi
+ nop.m 0
+ fclass.m p8, p0= f8, 0x7 // x= +/-Zero ?
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ (p6) mov f8= f0 // exp2(-Infinity)= 0
+ (p6) br.ret.spnt b0
+}
+;;
+
+{.mfb
+ nop.m 0
+ nop.f 0
+ (p7) br.ret.spnt b0 // exp2(+Infinity)= +Infinity
+}
+;;
+
+{.mfb
+ nop.m 0
+ (p8) mov f8= f1 // exp2(+/-0)= 1
+ (p8) br.ret.spnt b0
+}
+;;
+
+{.mfb
+ nop.m 0
+ fma.s.s0 f8= f8, f1, f0 // Remaining cases: NaNs
+ br.ret.sptk b0
+}
+;;
+
+
+OUT_RANGE_exp2:
+
+// overflow: p8= 1
+
+{.mii
+ (p8) mov GR_EXPMAX= 0x1fffe
+ nop.i 0
+ nop.i 0
+}
+;;
+
+{.mmb
+ (p8) mov GR_Parameter_TAG= 163
+ (p8) setf.exp FR_R= GR_EXPMAX
+ nop.b 999
+}
+;;
+
+{.mfi
+ nop.m 999
+ (p8) fma.s.s0 f8= FR_R, FR_R, f0 // Create overflow
+ nop.i 999
+}
+// underflow: p6= 1
+{.mii
+ (p6) mov GR_Parameter_TAG= 164
+ (p6) mov GR_EXPMAX= 1
+ nop.i 0
+}
+;;
+
+{.mmb
+ nop.m 0
+ (p6) setf.exp FR_R= GR_EXPMAX
+ nop.b 999
+}
+;;
+
+{.mfb
+ nop.m 999
+ (p6) fma.s.s0 f8= FR_R, FR_R, f0 // Create underflow
+ nop.b 0
+}
+;;
+
+GLOBAL_LIBM_END(exp2f)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+.prologue
+{.mfi
+ add GR_Parameter_Y= -32, sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs, GR_SAVE_PFS
+ mov GR_SAVE_PFS= ar.pfs // Save ar.pfs
+}
+
+{.mfi
+.fframe 64
+ add sp= -64, sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP= gp // Save gp
+}
+;;
+
+{.mmi
+ stfs [ GR_Parameter_Y ]= FR_Y, 16 // STORE Parameter 2 on stack
+ add GR_Parameter_X= 16, sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0= b0 // Save b0
+}
+;;
+
+.body
+{.mib
+ stfs [ GR_Parameter_X ]= FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT= 0, GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{.mib
+ stfs [ GR_Parameter_Y ]= FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y= -16, GR_Parameter_Y
+ br.call.sptk b0= __libm_error_support# // Call error handling function
+}
+;;
+
+{.mmi
+ add GR_Parameter_RESULT= 48, sp
+ nop.m 0
+ nop.i 0
+}
+;;
+
+{.mmi
+ ldfs f8= [ GR_Parameter_RESULT ] // Get return result off stack
+.restore sp
+ add sp= 64, sp // Restore stack pointer
+ mov b0= GR_SAVE_B0 // Restore return address
+}
+;;
+
+{.mib
+ mov gp= GR_SAVE_GP // Restore gp
+ mov ar.pfs= GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+}
+;;
+
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#, @function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_exp2l.S b/libc/sysdeps/ia64/fpu/e_exp2l.S
new file mode 100644
index 000000000..743ed3558
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_exp2l.S
@@ -0,0 +1,807 @@
+.file "exp2l.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 07/27/00 Initial version
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [ the previously overwritten ] GR_Parameter_RESULT.
+// 02/02/01 Added libm_error_support calls for underflow
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 05/07/03 Reformatted assembly source
+//
+// API
+//==============================================================
+// long double exp2l(long double)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// Let x= K + f + r, where
+// K is an integer, f= 0.b1 b2... b8 (f>= 0),
+// and |r|<2^{-8}
+// T is a table that stores 2^f (256 entries) rounded to
+// double extended precision (only mantissa is stored)
+// D stores (2^f/T [ f ] - 1), rounded to single precision
+//
+// 2^x is approximated as
+// 2^K * T [ f ] * (1+D [ f ] +c1*r+c2*r^2+...+c6*r^6)
+//
+
+
+
+// Special values
+//==============================================================
+// exp2(0)= 1
+// exp2(+inf)= inf
+// exp2(-inf)= 0
+//
+
+
+// Registers used
+//==============================================================
+// f6-f15, f32-f46
+// r2-r3, r8-r11, r14-r40
+// p6, p7, p8, p12
+
+ FR_X = f10
+ FR_Y = f1
+ FR_RESULT = f8
+
+ FR_KF0 = f6
+ FR_EXP63 = f7
+ FR_T = f9
+ FR_COEFF3 = f10
+ FR_COEFF4 = f11
+ FR_COEFF5 = f12
+ FR_COEFF6 = f13
+ FR_COEFF1 = f14
+ FR_COEFF2 = f15
+ FR_2P14 = f32
+ FR_UF_TEST = f33
+ FR_D = f34
+ FR_R = f35
+ FR_2EXP = f36
+ FR_EMIN = f37
+ FR_P34 = f38
+ FR_P56 = f39
+ FR_R2 = f40
+ FR_P12 = f41
+ FR_TS = f42
+ FR_P36 = f43
+ FR_P02 = f44
+ FR_R3 = f45
+ FR_P06 = f46
+
+
+ GR_ADDR0 = r2
+ GR_ADDR = r2
+ GR_D_ADDR0 = r3
+ GR_D_ADDR = r3
+ GR_LEADBITS = r8
+ GR_256 = r9
+ GR_EM63 = r10
+ GR_255 = r11
+ GR_EXPON = r14
+ GR_BM63 = r15
+ GR_UF_TEST = r16
+ GR_INDEX = r17
+ GR_K = r18
+ GR_KF = r19
+ GR_2P14 = r19
+ GR_EMIN = r20
+ GR_IT = r21
+ GR_ID = r22
+ GR_63 = r23
+ GR_CONST1 = r24
+ GR_EBIAS = r25
+ GR_CONST2 = r26
+ GR_CONST3 = r27
+ GR_SIGNIF = r28
+ GR_ARGEXP = r29
+ GR_SGN = r30
+ GR_EMIN1 = r31
+ GR_SREG = r32
+
+ GR_SAVE_B0 = r33
+ GR_SAVE_PFS = r34
+ GR_SAVE_GP = r35
+ GR_SAVE_SP = r36
+
+ GR_Parameter_X = r37
+ GR_Parameter_Y = r38
+ GR_Parameter_RESULT= r39
+ GR_Parameter_TAG = r40
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+
+ data8 0x3fac6b08d704a0c0 // C_3
+ data8 0x3f83b2ab6fba4e77 // C_4
+ data8 0x3f55d87fe78a6731 // C_5
+ data8 0x3f2430912f86c787 // C_6
+ data8 0xb17217f7d1cf79ab, 0x00003ffe // C_1
+ data8 0xf5fdeffc162c7541, 0x00003ffc // C_2
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+LOCAL_OBJECT_START(T_table)
+
+ data8 0x8000000000000000, 0x8058d7d2d5e5f6b1
+ data8 0x80b1ed4fd999ab6c, 0x810b40a1d81406d4
+ data8 0x8164d1f3bc030773, 0x81bea1708dde6056
+ data8 0x8218af4373fc25ec, 0x8272fb97b2a5894c
+ data8 0x82cd8698ac2ba1d7, 0x83285071e0fc4547
+ data8 0x8383594eefb6ee37, 0x83dea15b9541b132
+ data8 0x843a28c3acde4046, 0x8495efb3303efd30
+ data8 0x84f1f656379c1a29, 0x854e3cd8f9c8c95d
+ data8 0x85aac367cc487b15, 0x86078a2f23642a9f
+ data8 0x8664915b923fba04, 0x86c1d919caef5c88
+ data8 0x871f61969e8d1010, 0x877d2afefd4e256c
+ data8 0x87db357ff698d792, 0x88398146b919f1d4
+ data8 0x88980e8092da8527, 0x88f6dd5af155ac6b
+ data8 0x8955ee03618e5fdd, 0x89b540a7902557a4
+ data8 0x8a14d575496efd9a, 0x8a74ac9a79896e47
+ data8 0x8ad4c6452c728924, 0x8b3522a38e1e1032
+ data8 0x8b95c1e3ea8bd6e7, 0x8bf6a434adde0085
+ data8 0x8c57c9c4646f4dde, 0x8cb932c1bae97a95
+ data8 0x8d1adf5b7e5ba9e6, 0x8d7ccfc09c50e2f8
+ data8 0x8ddf042022e69cd6, 0x8e417ca940e35a01
+ data8 0x8ea4398b45cd53c0, 0x8f073af5a2013520
+ data8 0x8f6a8117e6c8e5c4, 0x8fce0c21c6726481
+ data8 0x9031dc431466b1dc, 0x9095f1abc540ca6b
+ data8 0x90fa4c8beee4b12b, 0x915eed13c89689d3
+ data8 0x91c3d373ab11c336, 0x9228ffdc10a051ad
+ data8 0x928e727d9531f9ac, 0x92f42b88f673aa7c
+ data8 0x935a2b2f13e6e92c, 0x93c071a0eef94bc1
+ data8 0x9426ff0fab1c04b6, 0x948dd3ac8ddb7ed3
+ data8 0x94f4efa8fef70961, 0x955c5336887894d5
+ data8 0x95c3fe86d6cc7fef, 0x962bf1cbb8d97560
+ data8 0x96942d3720185a00, 0x96fcb0fb20ac4ba3
+ data8 0x97657d49f17ab08e, 0x97ce9255ec4357ab
+ data8 0x9837f0518db8a96f, 0x98a1976f7597e996
+ data8 0x990b87e266c189aa, 0x9975c1dd47518c77
+ data8 0x99e0459320b7fa65, 0x9a4b13371fd166ca
+ data8 0x9ab62afc94ff864a, 0x9b218d16f441d63d
+ data8 0x9b8d39b9d54e5539, 0x9bf93118f3aa4cc1
+ data8 0x9c6573682ec32c2d, 0x9cd200db8a0774cb
+ data8 0x9d3ed9a72cffb751, 0x9dabfdff6367a2aa
+ data8 0x9e196e189d472420, 0x9e872a276f0b98ff
+ data8 0x9ef5326091a111ae, 0x9f6386f8e28ba651
+ data8 0x9fd228256400dd06, 0xa041161b3d0121be
+ data8 0xa0b0510fb9714fc2, 0xa11fd9384a344cf7
+ data8 0xa18faeca8544b6e4, 0xa1ffd1fc25cea188
+ data8 0xa27043030c496819, 0xa2e102153e918f9e
+ data8 0xa3520f68e802bb93, 0xa3c36b345991b47c
+ data8 0xa43515ae09e6809e, 0xa4a70f0c95768ec5
+ data8 0xa5195786be9ef339, 0xa58bef536dbeb6ee
+ data8 0xa5fed6a9b15138ea, 0xa6720dc0be08a20c
+ data8 0xa6e594cfeee86b1e, 0xa7596c0ec55ff55b
+ data8 0xa7cd93b4e965356a, 0xa8420bfa298f70d1
+ data8 0xa8b6d5167b320e09, 0xa92bef41fa77771b
+ data8 0xa9a15ab4ea7c0ef8, 0xaa1717a7b5693979
+ data8 0xaa8d2652ec907629, 0xab0386ef48868de1
+ data8 0xab7a39b5a93ed337, 0xabf13edf162675e9
+ data8 0xac6896a4be3fe929, 0xace0413ff83e5d04
+ data8 0xad583eea42a14ac6, 0xadd08fdd43d01491
+ data8 0xae493452ca35b80e, 0xaec22c84cc5c9465
+ data8 0xaf3b78ad690a4375, 0xafb51906e75b8661
+ data8 0xb02f0dcbb6e04584, 0xb0a957366fb7a3c9
+ data8 0xb123f581d2ac2590, 0xb19ee8e8c94feb09
+ data8 0xb21a31a66618fe3b, 0xb295cff5e47db4a4
+ data8 0xb311c412a9112489, 0xb38e0e38419fae18
+ data8 0xb40aaea2654b9841, 0xb487a58cf4a9c180
+ data8 0xb504f333f9de6484, 0xb58297d3a8b9f0d2
+ data8 0xb60093a85ed5f76c, 0xb67ee6eea3b22b8f
+ data8 0xb6fd91e328d17791, 0xb77c94c2c9d725e9
+ data8 0xb7fbefca8ca41e7c, 0xb87ba337a1743834
+ data8 0xb8fbaf4762fb9ee9, 0xb97c143756844dbf
+ data8 0xb9fcd2452c0b9deb, 0xba7de9aebe5fea09
+ data8 0xbaff5ab2133e45fb, 0xbb81258d5b704b6f
+ data8 0xbc034a7ef2e9fb0d, 0xbc85c9c560e7b269
+ data8 0xbd08a39f580c36bf, 0xbd8bd84bb67ed483
+ data8 0xbe0f6809860993e2, 0xbe935317fc378238
+ data8 0xbf1799b67a731083, 0xbf9c3c248e2486f8
+ data8 0xc0213aa1f0d08db0, 0xc0a6956e8836ca8d
+ data8 0xc12c4cca66709456, 0xc1b260f5ca0fbb33
+ data8 0xc238d2311e3d6673, 0xc2bfa0bcfad907c9
+ data8 0xc346ccda24976407, 0xc3ce56c98d21b15d
+ data8 0xc4563ecc5334cb33, 0xc4de8523c2c07baa
+ data8 0xc5672a115506dadd, 0xc5f02dd6b0bbc3d9
+ data8 0xc67990b5aa245f79, 0xc70352f04336c51e
+ data8 0xc78d74c8abb9b15d, 0xc817f681416452b2
+ data8 0xc8a2d85c8ffe2c45, 0xc92e1a9d517f0ecc
+ data8 0xc9b9bd866e2f27a3, 0xca45c15afcc72624
+ data8 0xcad2265e4290774e, 0xcb5eecd3b38597c9
+ data8 0xcbec14fef2727c5d, 0xcc799f23d11510e5
+ data8 0xcd078b86503dcdd2, 0xcd95da6a9ff06445
+ data8 0xce248c151f8480e4, 0xceb3a0ca5dc6a55d
+ data8 0xcf4318cf191918c1, 0xcfd2f4683f94eeb5
+ data8 0xd06333daef2b2595, 0xd0f3d76c75c5db8d
+ data8 0xd184df6251699ac6, 0xd2164c023056bcab
+ data8 0xd2a81d91f12ae45a, 0xd33a5457a3029054
+ data8 0xd3ccf099859ac379, 0xd45ff29e0972c561
+ data8 0xd4f35aabcfedfa1f, 0xd5872909ab75d18a
+ data8 0xd61b5dfe9f9bce07, 0xd6aff9d1e13ba2fe
+ data8 0xd744fccad69d6af4, 0xd7da67311797f56a
+ data8 0xd870394c6db32c84, 0xd9067364d44a929c
+ data8 0xd99d15c278afd7b6, 0xda3420adba4d8704
+ data8 0xdacb946f2ac9cc72, 0xdb63714f8e295255
+ data8 0xdbfbb797daf23755, 0xdc9467913a4f1c92
+ data8 0xdd2d818508324c20, 0xddc705bcd378f7f0
+ data8 0xde60f4825e0e9124, 0xdefb4e1f9d1037f2
+ data8 0xdf9612deb8f04420, 0xe031430a0d99e627
+ data8 0xe0ccdeec2a94e111, 0xe168e6cfd3295d23
+ data8 0xe2055afffe83d369, 0xe2a23bc7d7d91226
+ data8 0xe33f8972be8a5a51, 0xe3dd444c46499619
+ data8 0xe47b6ca0373da88d, 0xe51a02ba8e26d681
+ data8 0xe5b906e77c8348a8, 0xe658797368b3a717
+ data8 0xe6f85aaaee1fce22, 0xe798aadadd5b9cbf
+ data8 0xe8396a503c4bdc68, 0xe8da9958464b42ab
+ data8 0xe97c38406c4f8c57, 0xea1e4756550eb27b
+ data8 0xeac0c6e7dd24392f, 0xeb63b74317369840
+ data8 0xec0718b64c1cbddc, 0xecaaeb8ffb03ab41
+ data8 0xed4f301ed9942b84, 0xedf3e6b1d418a491
+ data8 0xee990f980da3025b, 0xef3eab20e032bc6b
+ data8 0xefe4b99bdcdaf5cb, 0xf08b3b58cbe8b76a
+ data8 0xf13230a7ad094509, 0xf1d999d8b7708cc1
+ data8 0xf281773c59ffb13a, 0xf329c9233b6bae9c
+ data8 0xf3d28fde3a641a5b, 0xf47bcbbe6db9fddf
+ data8 0xf5257d152486cc2c, 0xf5cfa433e6537290
+ data8 0xf67a416c733f846e, 0xf7255510c4288239
+ data8 0xf7d0df730ad13bb9, 0xf87ce0e5b2094d9c
+ data8 0xf92959bb5dd4ba74, 0xf9d64a46eb939f35
+ data8 0xfa83b2db722a033a, 0xfb3193cc4227c3f4
+ data8 0xfbdfed6ce5f09c49, 0xfc8ec01121e447bb
+ data8 0xfd3e0c0cf486c175, 0xfdedd1b496a89f35
+ data8 0xfe9e115c7b8f884c, 0xff4ecb59511ec8a5
+LOCAL_OBJECT_END(T_table)
+
+
+LOCAL_OBJECT_START(D_table)
+
+ data4 0x00000000, 0x9f55c08f, 0x1e93ffa3, 0x1dcd43a8
+ data4 0x1f751f79, 0x9f3cdd88, 0x9f43d155, 0x1eda222c
+ data4 0x1ef35513, 0x9f597895, 0x9e698881, 0x1ec71073
+ data4 0x1e50e371, 0x9dc01e19, 0x1de74133, 0x1e2f028c
+ data4 0x9edefb47, 0x1ebbac48, 0x9e8b0330, 0x9e9e9314
+ data4 0x1edc1d11, 0x1f098529, 0x9f52827c, 0x1f50050d
+ data4 0x1f301e8e, 0x1f5b64d1, 0x9f45e3ee, 0x9ef64d6d
+ data4 0x1d6ec5e8, 0x9e61ad9a, 0x1d44ccbb, 0x9e4a8bbb
+ data4 0x9cf11576, 0x9dcce7e7, 0x9d02ac90, 0x1f26ccf0
+ data4 0x9f0877c6, 0x9ddd62ae, 0x9f4b7fc3, 0x1ea8ef6b
+ data4 0x1ea4378d, 0x1ef6fc38, 0x1db99fd9, 0x1f22bf6f
+ data4 0x1f53e172, 0x1e85504a, 0x9f37cc75, 0x1f0c5e17
+ data4 0x1dde8aac, 0x9cb42bb2, 0x1e153cd7, 0x1eb62bba
+ data4 0x9e9b941b, 0x9ea80e3c, 0x1f508823, 0x1ec3fd36
+ data4 0x1e9ffaa1, 0x1e21e2eb, 0x9d948b1d, 0x9e8ac93a
+ data4 0x1ef7ee6f, 0x9e80dda3, 0x1f0814be, 0x1dc5ddfe
+ data4 0x1eedb9d1, 0x9f2aaa26, 0x9ea5b0fc, 0x1edf702e
+ data4 0x9e391201, 0x1f1316bb, 0x1ea27fb7, 0x9e05ed18
+ data4 0x9f199ed2, 0x1ee7fd7c, 0x1f003db6, 0x9eac3793
+ data4 0x9e5b8c10, 0x9f3af17c, 0x1bc9a8be, 0x1ee3c004
+ data4 0x9f19b1b2, 0x9f242ce9, 0x9ce67dd1, 0x9e4f6275
+ data4 0x1e20742c, 0x1eb9328a, 0x9f477153, 0x1d969718
+ data4 0x9f1e6c43, 0x1f2f67f4, 0x9f39c7e4, 0x9e3c4feb
+ data4 0x1da3956b, 0x9e7c685d, 0x1f280911, 0x9f0d8afb
+ data4 0x1e314b40, 0x9eb4f250, 0x9f1a34ad, 0x1ef5d5e7
+ data4 0x9f145496, 0x1e604827, 0x9f1e5195, 0x1e9c1fc0
+ data4 0x1efde521, 0x1e69b385, 0x1f316830, 0x9f244eae
+ data4 0x1f1787ec, 0x9e939971, 0x1f0bb393, 0x9f0511d6
+ data4 0x1ed919de, 0x1d8b7b28, 0x1e5ca4a9, 0x1e7c357b
+ data4 0x9e3ff8e8, 0x1eef53b5, 0x9ed22ed7, 0x1f16659b
+ data4 0x9f2db102, 0x9e2c6a78, 0x1f328d7d, 0x9f2fec3c
+ data4 0x1eb395bd, 0x9f242b84, 0x9e2683e6, 0x1ed71e68
+ data4 0x1efd1df5, 0x9e9eeafd, 0x9ed2249c, 0x1eef129a
+ data4 0x1d1ea44c, 0x9e81f7ff, 0x1eaf77c9, 0x9ee7a285
+ data4 0x1e1864ed, 0x9ee7edbb, 0x9e15a27d, 0x9ae61655
+ data4 0x1f1ff1a2, 0x1da29755, 0x9e5f46fb, 0x1e901236
+ data4 0x9eecfb9b, 0x9f204d2f, 0x1ec64685, 0x9eb809bd
+ data4 0x9e0026c5, 0x1d9f1da1, 0x1f142b49, 0x9f20f22e
+ data4 0x1f24b067, 0x1f185a4c, 0x9f09765c, 0x9ece902f
+ data4 0x1e2ca5db, 0x1e6de464, 0x9f071f67, 0x1f1518c3
+ data4 0x1ea13ded, 0x1f0b8414, 0x1edb6ad4, 0x9e548740
+ data4 0x9ea10efb, 0x1ee48a60, 0x1e7954c5, 0x9edad013
+ data4 0x9f21517d, 0x9e9b6e0c, 0x9ee7f9a6, 0x9ebd4298
+ data4 0x9d65b24e, 0x1eed751f, 0x9f1573ea, 0x9d430377
+ data4 0x9e13fc0c, 0x1e47008a, 0x1e3d5c1d, 0x1ef41a91
+ data4 0x9e4a4ef7, 0x9e952f18, 0x1d620566, 0x1d9b8d33
+ data4 0x1db06247, 0x1e94b31e, 0x1f0730ad, 0x9d79ffb4
+ data4 0x1ed64d51, 0x9e91fd11, 0x9e28d35a, 0x9dea0ed9
+ data4 0x1e891def, 0x9ee28ac0, 0x1e1db99b, 0x9ee1ce38
+ data4 0x9bdd9bca, 0x1eb72cb9, 0x9e8c53c6, 0x1e0df6ca
+ data4 0x1e8f2ccd, 0x9e9b0886, 0x1eeb3bc7, 0x1ec7e772
+ data4 0x9e210776, 0x9daf246c, 0x1ea1f151, 0x1ece4dc6
+ data4 0x1ce741c8, 0x1ed3c88f, 0x9ec9a4fd, 0x9e0c8d30
+ data4 0x1d2fbb26, 0x9ef212a7, 0x1ee44f1c, 0x9e445550
+ data4 0x1e075f77, 0x9d9291a3, 0x1f09c2ee, 0x9e012c88
+ data4 0x1f057d62, 0x9e7bb0dc, 0x9d8758ee, 0x1ee8d6c1
+ data4 0x9e509a57, 0x9e4ca7b7, 0x1e2cb341, 0x9ec35106
+ data4 0x1ecf3baf, 0x1e11781c, 0x1ea0cc78, 0x1eb75ca6
+ data4 0x1e961e1a, 0x1eb88853, 0x1e7abf50, 0x1ee38704
+ data4 0x9dc5ab0f, 0x1afe197b, 0x9ec07523, 0x9d9b7f78
+ data4 0x1f011618, 0x1ed43b0b, 0x9f035945, 0x9e3fd014
+ data4 0x9bbda5cd, 0x9e83f8ab, 0x1e58a928, 0x1e392d61
+ data4 0x1efdbb52, 0x1ee310a8, 0x9ec7ecc1, 0x1e8c9ed6
+ data4 0x9ef82dee, 0x9e70545b, 0x9ea53fc4, 0x1e40f419
+LOCAL_OBJECT_END(D_table)
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(exp2l)
+
+{.mii
+ // get exponent
+ getf.exp GR_EBIAS = f8
+ // GR_D_ADDR0 = pointer to D_table
+ addl GR_D_ADDR0 = @ltoff(D_table), gp
+ // GR_ADDR0 = pointer to C_1...C_6 followed by T_table
+ addl GR_ADDR0 = @ltoff(poly_coeffs), gp ;;
+}
+
+{.mfi
+ // get significand
+ getf.sig GR_SIGNIF = f8
+ // will continue only for normal/denormal numbers
+ fclass.nm.unc p12, p7 = f8, 0x1b
+ mov GR_63 = 63 ;;
+}
+
+{.mfi
+ nop.m 0
+ nop.f 0
+ // GR_CONST2 = bias+63-8
+ mov GR_CONST2 = 0xffff+55
+}
+{.mfi
+ // GR_CONST1 = bias+15
+ mov GR_CONST1 = 0xffff+15
+ nop.f 0
+ mov GR_CONST3 = 0x1ffff ;;
+}
+
+{.mfi
+ // load start address for C_1...C_6 followed by T_table
+ ld8 GR_ADDR = [ GR_ADDR0 ]
+ nop.f 0
+ // get sign of argument
+ andcm GR_SGN = GR_EBIAS, GR_CONST3
+}
+{.mfi
+ // GR_D_ADDR = pointer to D_table
+ ld8 GR_D_ADDR = [ GR_D_ADDR0 ]
+ nop.f 0
+ // get argument exponent
+ and GR_ARGEXP = GR_CONST3, GR_EBIAS ;;
+}
+
+{.mfi
+ alloc GR_SREG = ar.pfs, 1, 4, 4, 0
+ nop.f 0
+ // p6 = 1 if sign = 1
+ cmp.ne p6, p8 = GR_SGN, r0
+}
+{.mfi
+ // p7 = 1 if exponent> = 15 (argument out of range)
+ cmp.ge p7, p0 = GR_ARGEXP, GR_CONST1
+ nop.f 0
+ sub GR_EXPON = GR_CONST2, GR_ARGEXP ;;
+}
+
+{.mib
+ // load C_3, C_4
+ ldfpd FR_COEFF3, FR_COEFF4 = [ GR_ADDR ], 16
+ // get first exponent+8 bits
+ shr.u GR_LEADBITS = GR_SIGNIF, GR_EXPON
+ (p12) br.cond.spnt SPECIAL_exp2l
+}
+{.mib
+ mov GR_256 = 256
+ // exponent- = 63
+ sub GR_EM63 = GR_EBIAS, GR_63
+ (p7) br.cond.spnt OUT_RANGE_exp2l ;;
+}
+
+{.mlx
+ // load C_5, C_6
+ ldfpd FR_COEFF5, FR_COEFF6 = [ GR_ADDR ], 16
+ // GR_2P14 = 2^14
+ movl GR_2P14 = 0x46800000 ;;
+}
+
+{.mfi
+ // load C_1
+ ldfe FR_COEFF1 = [ GR_ADDR ], 16
+ fma.s0 f8 = f8, f1, f0
+ // GR_BM63 = bias-63
+ mov GR_BM63 = 0xffff-63 ;;
+}
+
+{.mlx
+ setf.s FR_2P14 = GR_2P14
+ // GR_UF_TEST = -2^14-62
+ movl GR_UF_TEST = 0xc6807c00
+}
+{.mfi
+ // load C_2
+ ldfe FR_COEFF2 = [ GR_ADDR ], 16
+ nop.f 0
+ mov GR_255 = 255 ;;
+}
+
+{.mib
+ // get 8-bit index
+ and GR_INDEX = GR_255, GR_LEADBITS
+ // get K = integer part
+ shr.u GR_K = GR_LEADBITS, 8
+ nop.b 0 ;;
+}
+
+{.mmi
+ // if sign = 1 && f>0, set p7 = 1
+ (p6) cmp.gt.unc p7, p0 = GR_INDEX, r0
+ setf.s FR_UF_TEST = GR_UF_TEST
+ shl GR_KF = GR_LEADBITS, GR_EXPON ;;
+}
+
+{.mfi
+ // if sign = 1 && f>0, set f = 1-f
+ (p7) sub GR_INDEX = GR_256, GR_INDEX
+ nop.f 0
+ // if sign = 1 && f>0, set K = K+1
+ (p7) add GR_K = GR_K, r0, 1 ;;
+}
+
+{.mfi
+ // FR_EXP63 = 2^{expon-63}
+ setf.exp FR_EXP63 = GR_EM63
+ nop.f 0
+ nop.i 0 ;;
+}
+
+.pred.rel "mutex", p6, p8
+{.mfi
+ // if sign = 0, set scale factor exponent S = K+bias-63
+ (p8) add GR_K = GR_K, GR_BM63
+ nop.f 0
+ // if sign = 1, set scale factor exponent S = -K+bias-63
+ (p6) sub GR_K = GR_BM63, GR_K ;;
+}
+
+{.mmi
+ // FR_KF0 = 2^{63-expon}*(K+f)
+ setf.sig FR_KF0 = GR_KF
+ nop.m 0
+ // GR_EMIN = EMIN = 2-2^14
+ mov GR_EMIN = 0x18cfff ;;
+}
+
+{.mfi
+ // get T_table index
+ shladd GR_IT = GR_INDEX, 3, GR_ADDR
+ // p7 = 1 if x> = 2^10
+ fcmp.ge.s1 p7, p12 = f8, FR_2P14
+ // get D_table index
+ shladd GR_ID = GR_INDEX, 2, GR_D_ADDR ;;
+}
+
+{.mfi
+ // load T_table value
+ ldf8 FR_T = [ GR_IT ]
+ // p7 = 1 if x<-2^10-50
+ (p12) fcmp.lt.s1 p7, p0 = f8, FR_UF_TEST
+ // GR_EMIN1 = EMIN = 2-2^14
+ shl GR_EMIN1 = GR_EMIN, 11 ;;
+}
+
+{.mmb
+ // f50 = scale factor = 2^{K-63}
+ setf.exp FR_2EXP = GR_K
+ // load D_table value
+ ldfs FR_D = [ GR_ID ]
+ (p7) br.cond.spnt OUT_RANGE_exp2l ;;
+}
+
+{.mfi
+ nop.m 0
+ // get r = x-(K+f)
+ fnma.s1 FR_R = FR_KF0, FR_EXP63, f8
+ nop.i 0 ;;
+}
+
+{.mfi
+ // FR_EMIN = EMIN
+ setf.s FR_EMIN = GR_EMIN1
+ // P34 = C_4*r+C_3
+ fma.s1 FR_P34 = FR_COEFF4, FR_R, FR_COEFF3
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P56 = C_6*r+C_5
+ fma.s1 FR_P56 = FR_COEFF6, FR_R, FR_COEFF5
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // r*r
+ fma.s1 FR_R2 = FR_R, FR_R, f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P12 = C_2*r+C_1
+ fma.s1 FR_P12 = FR_COEFF2, FR_R, FR_COEFF1
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // T* = scaling factor
+ fma.s1 FR_TS = FR_T, FR_2EXP, f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P36 = P34+r2*P56
+ fma.s1 FR_P36 = FR_P56, FR_R2, FR_P34
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // P02 = D+r*P12
+ fma.s1 FR_P02 = FR_P12, FR_R, FR_D
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // GR_ID = r*r2
+ fma.s1 FR_R3 = FR_R2, FR_R, f0
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // P06 = P02+r3*P36
+ fma.s1 FR_P06 = FR_P36, FR_R3, FR_P02
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // underflow (x<EMIN) ?
+ fcmp.lt.s0 p6, p8 = f8, FR_EMIN
+ nop.i 0 ;;
+}
+
+{.mfb
+ nop.m 0
+ // result = T+T*P06
+ fma.s0 f8 = FR_TS, FR_P06, FR_TS
+ // return
+ (p8) br.ret.sptk b0
+}
+{.mfb
+ (p6) mov GR_Parameter_TAG = 160
+ nop.f 0
+ (p6) br.cond.sptk __libm_error_region ;;
+}
+
+
+SPECIAL_exp2l:
+
+{.mfi
+ nop.m 0
+ // x = -Infinity ?
+ fclass.m p6, p0 = f8, 0x22
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // x = +Infinity ?
+ fclass.m p7, p0 = f8, 0x21
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // x = +/-Zero ?
+ fclass.m p8, p0 = f8, 0x7
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ // exp2l(-Infinity) = 0
+ (p6) mov f8 = f0
+ (p6) br.ret.spnt b0 ;;
+}
+
+{.mfb
+ nop.m 0
+ // exp2l(+Infinity) = +Infinity
+ nop.f 0
+ (p7) br.ret.spnt b0 ;;
+}
+
+{.mfb
+ nop.m 0
+ // exp2l(+/-0) = 1
+ (p8) mov f8 = f1
+ (p8) br.ret.spnt b0 ;;
+}
+
+{.mfb
+ nop.m 0
+ // Remaining cases: NaNs
+ fma.s0 f8 = f8, f1, f0
+ br.ret.sptk b0 ;;
+}
+
+
+OUT_RANGE_exp2l:
+
+
+{.mfi
+ // overflow: p8 = 1
+ (p8) mov GR_EM63 = 0x1fffe
+ // normalize input, to detect pseudo-zeroes
+ fma.s0 f8 = f8, f1, f0
+ nop.i 0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // f8 = 0?
+ fcmp.eq.s1 p7, p0 = f8, f0
+ nop.i 0 ;;
+}
+
+{.mmb
+ (p8) mov GR_Parameter_TAG = 159
+ (p8) setf.exp FR_TS = GR_EM63
+ nop.b 999 ;;
+}
+
+{.mfb
+ nop.m 0
+ // pseudo-zero
+ (p7) mov f8 = f1
+ (p7) br.ret.sptk b0 ;;
+}
+
+{.mfi
+ nop.m 999
+ (p8) fma.s0 f8 = FR_TS, FR_TS, f0
+ nop.i 999
+}
+{.mii
+ nop.m 0
+ // underflow: p6 = 1
+ (p6) mov GR_EM63 = 1
+ nop.i 0 ;;
+}
+
+{.mmb
+ (p6) mov GR_Parameter_TAG = 160
+ (p6) setf.exp FR_TS = GR_EM63
+ nop.b 999 ;;
+}
+
+{.mfb
+ nop.m 999
+ (p6) fma.s0 f8 = FR_TS, FR_TS, f0
+ nop.b 0 ;;
+}
+
+
+GLOBAL_LIBM_END(exp2l)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{.mfi
+ add GR_Parameter_Y = -32, sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs, GR_SAVE_PFS
+ mov GR_SAVE_PFS = ar.pfs // Save ar.pfs
+}
+{.mfi
+.fframe 64
+ add sp = -64, sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP = gp ;; // Save gp
+}
+
+{.mmi
+ stfe [ GR_Parameter_Y ] = FR_Y, 16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16, sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0 = b0 ;; // Save b0
+}
+
+.body
+{.mib
+ stfe [ GR_Parameter_X ] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0, GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{.mib
+ stfe [ GR_Parameter_Y ] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16, GR_Parameter_Y
+ br.call.sptk b0 = __libm_error_support# ;; // Call error handling function
+}
+
+{.mmi
+ add GR_Parameter_RESULT = 48, sp
+ nop.m 0
+ nop.i 0 ;;
+}
+
+{.mmi
+ ldfe f8 = [ GR_Parameter_RESULT ] // Get return result off stack
+.restore sp
+ add sp = 64, sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 ;; // Restore return address
+}
+
+{.mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 ;; // Return
+}
+
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#, @function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_expf.S b/libc/sysdeps/ia64/fpu/e_expf.S
new file mode 100644
index 000000000..6fe0a833e
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_expf.S
@@ -0,0 +1,716 @@
+.file "expf.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+
+// History
+//*********************************************************************
+// 02/02/00 Original version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 08/21/00 Improvements to save 2 cycles on main path, and shorten x=0 case
+// 12/07/00 Widen main path, shorten x=inf, nan paths
+// 03/15/01 Fix monotonicity problem around x=0 for round to +inf
+// 02/05/02 Corrected uninitialize predicate in POSSIBLE_UNDERFLOW path
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 07/26/02 Algorithm changed, accuracy improved
+// 09/26/02 support of higher precision inputs added, underflow threshold
+// corrected
+// 11/15/02 Improved performance on Itanium 2, added possible over/under paths
+// 05/30/03 Set inexact flag on unmasked overflow/underflow
+// 03/31/05 Reformatted delimiters between data tables
+//
+//
+// API
+//*********************************************************************
+// float expf(float)
+//
+// Overview of operation
+//*********************************************************************
+// Take the input x. w is "how many log2/128 in x?"
+// w = x * 64/log2
+// NJ = int(w)
+// x = NJ*log2/64 + R
+
+// NJ = 64*n + j
+// x = n*log2 + (log2/64)*j + R
+//
+// So, exp(x) = 2^n * 2^(j/64)* exp(R)
+//
+// T = 2^n * 2^(j/64)
+// Construct 2^n
+// Get 2^(j/64) table
+// actually all the entries of 2^(j/64) table are stored in DP and
+// with exponent bits set to 0 -> multiplication on 2^n can be
+// performed by doing logical "or" operation with bits presenting 2^n
+
+// exp(R) = 1 + (exp(R) - 1)
+// P = exp(R) - 1 approximated by Taylor series of 3rd degree
+// P = A3*R^3 + A2*R^2 + R, A3 = 1/6, A2 = 1/2
+//
+
+// The final result is reconstructed as follows
+// exp(x) = T + T*P
+
+// Special values
+//*********************************************************************
+// expf(+0) = 1.0
+// expf(-0) = 1.0
+
+// expf(+qnan) = +qnan
+// expf(-qnan) = -qnan
+// expf(+snan) = +qnan
+// expf(-snan) = -qnan
+
+// expf(-inf) = +0
+// expf(+inf) = +inf
+
+// Overflow and Underflow
+//*********************************************************************
+// expf(x) = largest single normal when
+// x = 88.72283 = 0x42b17217
+
+// expf(x) = smallest single normal when
+// x = -87.33654 = 0xc2aeac4f
+
+// expf(x) = largest round-to-nearest single zero when
+// x = -103.97208 = 0xc2cff1b5
+
+
+// Registers used
+//*********************************************************************
+// Floating Point registers used:
+// f8, input
+// f6,f7, f9 -> f15, f32 -> f40
+
+// General registers used:
+// r3, r23 -> r38
+
+// Predicate registers used:
+// p10 -> p15
+
+// Assembly macros
+//*********************************************************************
+// integer registers used
+// scratch
+rNJ = r3
+
+rTmp = r23
+rJ = r23
+rN = r24
+rTblAddr = r25
+rA3 = r26
+rExpHalf = r27
+rLn2Div64 = r28
+r17ones_m1 = r29
+rGt_ln = r29
+rRightShifter = r30
+r64DivLn2 = r31
+// stacked
+GR_SAVE_PFS = r32
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Parameter_TAG = r38
+
+// floating point registers used
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+// scratch
+fRightShifter = f6
+f64DivLn2 = f7
+fNormX = f9
+fNint = f10
+fN = f11
+fR = f12
+fLn2Div64 = f13
+fA2 = f14
+fA3 = f15
+// stacked
+fP = f32
+fT = f33
+fMIN_SGL_OFLOW_ARG = f34
+fMAX_SGL_ZERO_ARG = f35
+fMAX_SGL_NORM_ARG = f36
+fMIN_SGL_NORM_ARG = f37
+fRSqr = f38
+fTmp = f39
+fGt_pln = f39
+fWre_urm_f8 = f40
+fFtz_urm_f8 = f40
+
+
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(_expf_table)
+data4 0x42b17218 // Smallest sgl arg to overflow sgl result, +88.7228
+data4 0xc2cff1b5 // Largest sgl for rnd-to-nearest 0 result, -103.9720
+data4 0x42b17217 // Largest sgl arg to give normal sgl result, +88.7228
+data4 0xc2aeac4f // Smallest sgl arg to give normal sgl result, -87.3365
+//
+// 2^(j/64) table, j goes from 0 to 63
+data8 0x0000000000000000 // 2^(0/64)
+data8 0x00002C9A3E778061 // 2^(1/64)
+data8 0x000059B0D3158574 // 2^(2/64)
+data8 0x0000874518759BC8 // 2^(3/64)
+data8 0x0000B5586CF9890F // 2^(4/64)
+data8 0x0000E3EC32D3D1A2 // 2^(5/64)
+data8 0x00011301D0125B51 // 2^(6/64)
+data8 0x0001429AAEA92DE0 // 2^(7/64)
+data8 0x000172B83C7D517B // 2^(8/64)
+data8 0x0001A35BEB6FCB75 // 2^(9/64)
+data8 0x0001D4873168B9AA // 2^(10/64)
+data8 0x0002063B88628CD6 // 2^(11/64)
+data8 0x0002387A6E756238 // 2^(12/64)
+data8 0x00026B4565E27CDD // 2^(13/64)
+data8 0x00029E9DF51FDEE1 // 2^(14/64)
+data8 0x0002D285A6E4030B // 2^(15/64)
+data8 0x000306FE0A31B715 // 2^(16/64)
+data8 0x00033C08B26416FF // 2^(17/64)
+data8 0x000371A7373AA9CB // 2^(18/64)
+data8 0x0003A7DB34E59FF7 // 2^(19/64)
+data8 0x0003DEA64C123422 // 2^(20/64)
+data8 0x0004160A21F72E2A // 2^(21/64)
+data8 0x00044E086061892D // 2^(22/64)
+data8 0x000486A2B5C13CD0 // 2^(23/64)
+data8 0x0004BFDAD5362A27 // 2^(24/64)
+data8 0x0004F9B2769D2CA7 // 2^(25/64)
+data8 0x0005342B569D4F82 // 2^(26/64)
+data8 0x00056F4736B527DA // 2^(27/64)
+data8 0x0005AB07DD485429 // 2^(28/64)
+data8 0x0005E76F15AD2148 // 2^(29/64)
+data8 0x0006247EB03A5585 // 2^(30/64)
+data8 0x0006623882552225 // 2^(31/64)
+data8 0x0006A09E667F3BCD // 2^(32/64)
+data8 0x0006DFB23C651A2F // 2^(33/64)
+data8 0x00071F75E8EC5F74 // 2^(34/64)
+data8 0x00075FEB564267C9 // 2^(35/64)
+data8 0x0007A11473EB0187 // 2^(36/64)
+data8 0x0007E2F336CF4E62 // 2^(37/64)
+data8 0x00082589994CCE13 // 2^(38/64)
+data8 0x000868D99B4492ED // 2^(39/64)
+data8 0x0008ACE5422AA0DB // 2^(40/64)
+data8 0x0008F1AE99157736 // 2^(41/64)
+data8 0x00093737B0CDC5E5 // 2^(42/64)
+data8 0x00097D829FDE4E50 // 2^(43/64)
+data8 0x0009C49182A3F090 // 2^(44/64)
+data8 0x000A0C667B5DE565 // 2^(45/64)
+data8 0x000A5503B23E255D // 2^(46/64)
+data8 0x000A9E6B5579FDBF // 2^(47/64)
+data8 0x000AE89F995AD3AD // 2^(48/64)
+data8 0x000B33A2B84F15FB // 2^(49/64)
+data8 0x000B7F76F2FB5E47 // 2^(50/64)
+data8 0x000BCC1E904BC1D2 // 2^(51/64)
+data8 0x000C199BDD85529C // 2^(52/64)
+data8 0x000C67F12E57D14B // 2^(53/64)
+data8 0x000CB720DCEF9069 // 2^(54/64)
+data8 0x000D072D4A07897C // 2^(55/64)
+data8 0x000D5818DCFBA487 // 2^(56/64)
+data8 0x000DA9E603DB3285 // 2^(57/64)
+data8 0x000DFC97337B9B5F // 2^(58/64)
+data8 0x000E502EE78B3FF6 // 2^(59/64)
+data8 0x000EA4AFA2A490DA // 2^(60/64)
+data8 0x000EFA1BEE615A27 // 2^(61/64)
+data8 0x000F50765B6E4540 // 2^(62/64)
+data8 0x000FA7C1819E90D8 // 2^(63/64)
+LOCAL_OBJECT_END(_expf_table)
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(expf)
+
+{ .mlx
+ addl rTblAddr = @ltoff(_expf_table),gp
+ movl r64DivLn2 = 0x40571547652B82FE // 64/ln(2)
+}
+{ .mlx
+ addl rA3 = 0x3E2AA, r0 // high bits of 1.0/6.0 rounded to SP
+ movl rRightShifter = 0x43E8000000000000 // DP Right Shifter
+}
+;;
+
+{ .mfi
+ // point to the beginning of the table
+ ld8 rTblAddr = [rTblAddr]
+ fclass.m p14, p0 = f8, 0x22 // test for -INF
+ shl rA3 = rA3, 12 // 0x3E2AA000, approx to 1.0/6.0 in SP
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNormX = f8 // normalized x
+ addl rExpHalf = 0xFFFE, r0 // exponent of 1/2
+}
+;;
+
+{ .mfi
+ setf.d f64DivLn2 = r64DivLn2 // load 64/ln(2) to FP reg
+ fclass.m p15, p0 = f8, 0x1e1 // test for NaT,NaN,+Inf
+ nop.i 0
+}
+{ .mlx
+ // load Right Shifter to FP reg
+ setf.d fRightShifter = rRightShifter
+ movl rLn2Div64 = 0x3F862E42FEFA39EF // DP ln(2)/64 in GR
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s1 p13, p0 = f0, f8 // test for x = 0.0
+ nop.i 0
+}
+{ .mfb
+ setf.s fA3 = rA3 // load A3 to FP reg
+(p14) fma.s.s0 f8 = f0, f1, f0 // result if x = -inf
+(p14) br.ret.spnt b0 // exit here if x = -inf
+}
+;;
+
+{ .mfi
+ setf.exp fA2 = rExpHalf // load A2 to FP reg
+ fcmp.eq.s0 p6, p0 = f8, f0 // Dummy to flag denorm
+ nop.i 0
+}
+{ .mfb
+ setf.d fLn2Div64 = rLn2Div64 // load ln(2)/64 to FP reg
+(p15) fma.s.s0 f8 = f8, f1, f0 // result if x = NaT,NaN,+Inf
+(p15) br.ret.spnt b0 // exit here if x = NaT,NaN,+Inf
+}
+;;
+
+{ .mfb
+ // overflow and underflow_zero threshold
+ ldfps fMIN_SGL_OFLOW_ARG, fMAX_SGL_ZERO_ARG = [rTblAddr], 8
+(p13) fma.s.s0 f8 = f1, f1, f0 // result if x = 0.0
+(p13) br.ret.spnt b0 // exit here if x =0.0
+}
+;;
+
+ // max normal and underflow_denorm threshold
+{ .mfi
+ ldfps fMAX_SGL_NORM_ARG, fMIN_SGL_NORM_ARG = [rTblAddr], 8
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // x*(64/ln(2)) + Right Shifter
+ fma.s1 fNint = fNormX, f64DivLn2, fRightShifter
+ nop.i 0
+}
+;;
+
+// Divide arguments into the following categories:
+// Certain Underflow p11 - -inf < x <= MAX_SGL_ZERO_ARG
+// Possible Underflow p13 - MAX_SGL_ZERO_ARG < x < MIN_SGL_NORM_ARG
+// Certain Safe - MIN_SGL_NORM_ARG <= x <= MAX_SGL_NORM_ARG
+// Possible Overflow p14 - MAX_SGL_NORM_ARG < x < MIN_SGL_OFLOW_ARG
+// Certain Overflow p15 - MIN_SGL_OFLOW_ARG <= x < +inf
+//
+// If the input is really a single arg, then there will never be
+// "Possible Overflow" arguments.
+//
+
+{ .mfi
+ nop.m 0
+ // check for overflow
+ fcmp.ge.s1 p15, p0 = fNormX, fMIN_SGL_OFLOW_ARG
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // check for underflow and tiny (+0) result
+ fcmp.le.s1 p11, p0 = fNormX, fMAX_SGL_ZERO_ARG
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fms.s1 fN = fNint, f1, fRightShifter // n in FP register
+ // branch out if overflow
+(p15) br.cond.spnt EXP_CERTAIN_OVERFLOW
+}
+;;
+
+{ .mfb
+ getf.sig rNJ = fNint // bits of n, j
+ // check for underflow and deno result
+ fcmp.lt.s1 p13, p0 = fNormX, fMIN_SGL_NORM_ARG
+ // branch out if underflow and tiny (+0) result
+(p11) br.cond.spnt EXP_CERTAIN_UNDERFLOW
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // check for possible overflow
+ fcmp.gt.s1 p14, p0 = fNormX, fMAX_SGL_NORM_ARG
+ extr.u rJ = rNJ, 0, 6 // bits of j
+}
+{ .mfi
+ addl rN = 0xFFFF - 63, rNJ // biased and shifted n
+ fnma.s1 fR = fLn2Div64, fN, fNormX // R = x - N*ln(2)/64
+ nop.i 0
+}
+;;
+
+{ .mfi
+ shladd rJ = rJ, 3, rTblAddr // address in the 2^(j/64) table
+ nop.f 0
+ shr rN = rN, 6 // biased n
+}
+;;
+
+{ .mfi
+ ld8 rJ = [rJ]
+ nop.f 0
+ shl rN = rN, 52 // 2^n bits in DP format
+}
+;;
+
+{ .mfi
+ or rN = rN, rJ // bits of 2^n * 2^(j/64) in DP format
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.d fT = rN // 2^n * 2^(j/64)
+ fma.s1 fP = fA3, fR, fA2 // A3*R + A2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fRSqr = fR, fR, f0 // R^2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP = fP, fRSqr, fR // P = (A3*R + A2)*R^2 + R
+ nop.i 0
+}
+;;
+
+{ .mbb
+ nop.m 0
+ // branch out if possible underflow
+(p13) br.cond.spnt EXP_POSSIBLE_UNDERFLOW
+ // branch out if possible overflow result
+(p14) br.cond.spnt EXP_POSSIBLE_OVERFLOW
+}
+;;
+
+{ .mfb
+ nop.m 0
+ // final result in the absence of over- and underflow
+ fma.s.s0 f8 = fP, fT, fT
+ // exit here in the absence of over- and underflow
+ br.ret.sptk b0
+}
+;;
+
+EXP_POSSIBLE_OVERFLOW:
+
+// Here if fMAX_SGL_NORM_ARG < x < fMIN_SGL_OFLOW_ARG
+// This cannot happen if input is a single, only if input higher precision.
+// Overflow is a possibility, not a certainty.
+
+// Recompute result using status field 2 with user's rounding mode,
+// and wre set. If result is larger than largest single, then we have
+// overflow
+
+{ .mfi
+ mov rGt_ln = 0x1007f // Exponent for largest single + 1 ulp
+ fsetc.s2 0x7F,0x42 // Get user's round mode, set wre
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp fGt_pln = rGt_ln // Create largest single + 1 ulp
+ fma.s.s2 fWre_urm_f8 = fP, fT, fT // Result with wre set
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40 // Turn off wre in sf2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p6, p0 = fWre_urm_f8, fGt_pln // Test for overflow
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p6) br.cond.spnt EXP_CERTAIN_OVERFLOW // Branch if overflow
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = fP, fT, fT
+ br.ret.sptk b0 // Exit if really no overflow
+}
+;;
+
+// here if overflow
+EXP_CERTAIN_OVERFLOW:
+{ .mmi
+ addl r17ones_m1 = 0x1FFFE, r0
+;;
+ setf.exp fTmp = r17ones_m1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ alloc r32=ar.pfs,0,3,4,0
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 16
+ fma.s.s0 FR_RESULT = fTmp, fTmp, fTmp // Set I,O and +INF result
+ br.cond.sptk __libm_error_region
+}
+;;
+
+EXP_POSSIBLE_UNDERFLOW:
+
+// Here if fMAX_SGL_ZERO_ARG < x < fMIN_SGL_NORM_ARG
+// Underflow is a possibility, not a certainty
+
+// We define an underflow when the answer with
+// ftz set
+// is zero (tiny numbers become zero)
+
+// Notice (from below) that if we have an unlimited exponent range,
+// then there is an extra machine number E between the largest denormal and
+// the smallest normal.
+
+// So if with unbounded exponent we round to E or below, then we are
+// tiny and underflow has occurred.
+
+// But notice that you can be in a situation where we are tiny, namely
+// rounded to E, but when the exponent is bounded we round to smallest
+// normal. So the answer can be the smallest normal with underflow.
+
+// E
+// -----+--------------------+--------------------+-----
+// | | |
+// 1.1...10 2^-3fff 1.1...11 2^-3fff 1.0...00 2^-3ffe
+// 0.1...11 2^-3ffe (biased, 1)
+// largest dn smallest normal
+
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x41 // Get user's round mode, set ftz
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s.s2 fFtz_urm_f8 = fP, fT, fT // Result with ftz set
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40 // Turn off ftz in sf2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s1 p6, p7 = fFtz_urm_f8, f0 // Test for underflow
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s.s0 f8 = fP, fT, fT // Compute result, set I, maybe U
+ nop.i 0
+}
+;;
+
+{ .mbb
+ nop.m 0
+(p6) br.cond.spnt EXP_UNDERFLOW_COMMON // Branch if really underflow
+(p7) br.ret.sptk b0 // Exit if really no underflow
+}
+;;
+
+EXP_CERTAIN_UNDERFLOW:
+// Here if x < fMAX_SGL_ZERO_ARG
+// Result will be zero (or smallest denorm if round to +inf) with I, U set
+{ .mmi
+ mov rTmp = 1
+;;
+ setf.exp fTmp = rTmp // Form small normal
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fmerge.se fTmp = fTmp, f64DivLn2 // Small with non-trial signif
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = fTmp, fTmp, f0 // Set I,U, tiny (+0.0) result
+ br.cond.sptk EXP_UNDERFLOW_COMMON
+}
+;;
+
+EXP_UNDERFLOW_COMMON:
+// Determine if underflow result is zero or nonzero
+{ .mfi
+ alloc r32=ar.pfs,0,3,4,0
+ fcmp.eq.s1 p6, p0 = f8, f0
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fmerge.s FR_X = fNormX,fNormX
+(p6) br.cond.spnt EXP_UNDERFLOW_ZERO
+}
+;;
+
+EXP_UNDERFLOW_NONZERO:
+// Here if x < fMIN_SGL_NORM_ARG and result nonzero;
+// I, U are set
+{ .mfb
+ mov GR_Parameter_TAG = 17
+ nop.f 0 // FR_RESULT already set
+ br.cond.sptk __libm_error_region
+}
+;;
+
+EXP_UNDERFLOW_ZERO:
+// Here if x < fMIN_SGL_NORM_ARG and result zero;
+// I, U are set
+{ .mfb
+ mov GR_Parameter_TAG = 17
+ nop.f 0 // FR_RESULT already set
+ br.cond.sptk __libm_error_region
+}
+;;
+
+GLOBAL_IEEE754_END(expf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // Store Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mfi
+ stfs [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ nop.f 0
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_expl.c b/libc/sysdeps/ia64/fpu/e_expl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_expl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/e_fmod.S b/libc/sysdeps/ia64/fpu/e_fmod.S
new file mode 100644
index 000000000..dbd0a2969
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_fmod.S
@@ -0,0 +1,559 @@
+.file "fmod.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//====================================================================
+// 02/02/00 Initial version
+// 03/02/00 New Algorithm
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 11/28/00 Set FR_Y to f9
+// 03/11/02 Fixed flags for fmod(qnan,zero)
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 04/28/03 Fix: fmod(sNaN,0) no longer sets errno
+//
+// API
+//====================================================================
+// double fmod(double,double);
+//
+// Overview of operation
+//====================================================================
+// fmod(a,b)=a-i*b,
+// where i is an integer such that, if b!=0,
+// |i|<|a/b| and |a/b-i|<1
+//
+// Algorithm
+//====================================================================
+// a). if |a|<|b|, return a
+// b). get quotient and reciprocal overestimates accurate to
+// 33 bits (q2,y2)
+// c). if the exponent difference (exponent(a)-exponent(b))
+// is less than 32, truncate quotient to integer and
+// finish in one iteration
+// d). if exponent(a)-exponent(b)>=32 (q2>=2^32)
+// round quotient estimate to single precision (k=RN(q2)),
+// calculate partial remainder (a'=a-k*b),
+// get quotient estimate (a'*y2), and repeat from c).
+//
+// Special cases
+//====================================================================
+// b=+/-0: return NaN, call libm_error_support
+// a=+/-Inf, a=NaN or b=NaN: return NaN
+//
+// Registers used
+//====================================================================
+// Predicate registers: p6-p11
+// General registers: r2,r29,r32 (ar.pfs), r33-r39
+// Floating point registers: f6-f15
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+FR_X = f10
+FR_Y = f9
+FR_RESULT = f8
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(fmod)
+
+// inputs in f8, f9
+// result in f8
+
+{ .mfi
+ alloc r32=ar.pfs,1,4,4,0
+ // f6=|a|
+ fmerge.s f6=f0,f8
+ mov r2 = 0x0ffdd
+}
+ {.mfi
+ nop.m 0
+ // f7=|b|
+ fmerge.s f7=f0,f9
+ nop.i 0;;
+}
+
+{ .mfi
+ setf.exp f11 = r2
+ // (1) y0
+ frcpa.s1 f10,p6=f6,f7
+ nop.i 0
+}
+
+// Y +-NAN, +-inf, +-0? p7
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f9, 0xe7
+ nop.i 999;;
+}
+
+// qnan snan inf norm unorm 0 -+
+// 1 1 1 0 0 0 11
+// e 3
+// X +-NAN, +-inf, ? p9
+
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p0 = f8, 0xe3
+ nop.i 999
+}
+
+// |x| < |y|? Return x p8
+{ .mfi
+ nop.m 999
+ fcmp.lt.unc.s1 p8,p0 = f6,f7
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 0
+ // normalize y (if |x|<|y|)
+ (p8) fma.s0 f9=f9,f1,f0
+ nop.i 0;;
+}
+
+ { .mfi
+ mov r2=0x1001f
+ // (2) q0=a*y0
+ (p6) fma.s1 f13=f6,f10,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (3) e0 = 1 - b * y0
+ (p6) fnma.s1 f12=f7,f10,f1
+ nop.i 0;;
+}
+
+ {.mfi
+ nop.m 0
+ // normalize x (if |x|<|y|)
+ (p8) fma.d.s0 f8=f8,f1,f0
+ nop.i 0
+}
+{.bbb
+ (p9) br.cond.spnt FMOD_X_NAN_INF
+ (p7) br.cond.spnt FMOD_Y_NAN_INF_ZERO
+ // if |x|<|y|, return
+ (p8) br.ret.spnt b0;;
+}
+
+ {.mfi
+ nop.m 0
+ // normalize x
+ fma.s0 f6=f6,f1,f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // normalize y
+ fma.s0 f7=f7,f1,f0
+ nop.i 0;;
+}
+
+ {.mfi
+ // f15=2^32
+ setf.exp f15=r2
+ // (4) q1=q0+e0*q0
+ (p6) fma.s1 f13=f12,f13,f13
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (5) e1 = e0 * e0 + 2^-34
+ (p6) fma.s1 f14=f12,f12,f11
+ nop.i 0;;
+}
+{.mlx
+ nop.m 0
+ movl r2=0x33a00000;;
+}
+{ .mfi
+ nop.m 0
+ // (6) y1 = y0 + e0 * y0
+ (p6) fma.s1 f10=f12,f10,f10
+ nop.i 0;;
+}
+{.mfi
+ // set f12=1.25*2^{-24}
+ setf.s f12=r2
+ // (7) q2=q1+e1*q1
+ (p6) fma.s1 f13=f13,f14,f13
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ fmerge.s f9=f8,f9
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (8) y2 = y1 + e1 * y1
+ (p6) fma.s1 f10=f14,f10,f10
+ // set p6=0, p10=0
+ cmp.ne.and p6,p10=r0,r0;;
+}
+
+.align 32
+loop53:
+ {.mfi
+ nop.m 0
+ // compare q2, 2^32
+ fcmp.lt.unc.s1 p8,p7=f13,f15
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // will truncate quotient to integer, if exponent<32 (in advance)
+ fcvt.fx.trunc.s1 f11=f13
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // if exponent>32, round quotient to single precision (perform in advance)
+ fma.s.s1 f13=f13,f1,f0
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // set f12=sgn(a)
+ (p8) fmerge.s f12=f8,f1
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // normalize truncated quotient
+ (p8) fcvt.xf f13=f11
+ nop.i 0;;
+}
+ { .mfi
+ nop.m 0
+ // calculate remainder (assuming f13=RZ(Q))
+ (p7) fnma.s1 f14=f13,f7,f6
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // also if exponent>32, round quotient to single precision
+ // and subtract 1 ulp: q=q-q*(1.25*2^{-24})
+ (p7) fnma.s.s1 f11=f13,f12,f13
+ nop.i 0;;
+}
+
+ {.mfi
+ nop.m 0
+ // (p8) calculate remainder (82-bit format)
+ (p8) fnma.s1 f11=f13,f7,f6
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // (p7) calculate remainder (assuming f11=RZ(Q))
+ (p7) fnma.s1 f6=f11,f7,f6
+ nop.i 0;;
+}
+
+
+ {.mfi
+ nop.m 0
+ // Final iteration (p8): is f6 the correct remainder (quotient was not overestimated) ?
+ (p8) fcmp.lt.unc.s1 p6,p10=f11,f0
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // get new quotient estimation: a'*y2
+ (p7) fma.s1 f13=f14,f10,f0
+ nop.i 0
+}
+ {.mfb
+ nop.m 0
+ // was f14=RZ(Q) ? (then new remainder f14>=0)
+ (p7) fcmp.lt.unc.s1 p7,p9=f14,f0
+ nop.b 0;;
+}
+
+
+.pred.rel "mutex",p6,p10
+ {.mfb
+ nop.m 0
+ // add b to estimated remainder (to cover the case when the quotient was overestimated)
+ // also set correct sign by using f9=|b|*sgn(a), f12=sgn(a)
+ (p6) fma.d.s0 f8=f11,f12,f9
+ nop.b 0
+}
+ {.mfb
+ nop.m 0
+ // calculate remainder (single precision)
+ // set correct sign of result before returning
+ (p10) fma.d.s0 f8=f11,f12,f0
+ (p8) br.ret.sptk b0;;
+}
+ {.mfi
+ nop.m 0
+ // if f13!=RZ(Q), get alternative quotient estimation: a''*y2
+ (p7) fma.s1 f13=f6,f10,f0
+ nop.i 0
+}
+ {.mfb
+ nop.m 0
+ // if f14 was RZ(Q), set remainder to f14
+ (p9) mov f6=f14
+ br.cond.sptk loop53;;
+}
+
+
+
+FMOD_X_NAN_INF:
+
+// Y zero ?
+{.mfi
+ nop.m 0
+ fclass.m p10,p0=f8,0xc3 // Test x=nan
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 f10=f9,f1,f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ fma.s0 f8=f8,f1,f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+(p10) fclass.m p10,p0=f9,0x07 // Test x=nan, and y=zero
+ nop.i 0;;
+}
+
+{.mfb
+ nop.m 0
+ fcmp.eq.unc.s1 p11,p0=f10,f0
+(p10) br.ret.spnt b0;; // Exit with result=x if x=nan and y=zero
+}
+{.mib
+ nop.m 0
+ nop.i 0
+ // if Y zero
+ (p11) br.cond.spnt FMOD_Y_ZERO;;
+}
+
+// X infinity? Return QNAN indefinite
+{ .mfi
+ nop.m 999
+ fclass.m.unc p8,p9 = f8, 0x23
+ nop.i 999;;
+}
+// Y NaN ?
+{.mfi
+ nop.m 999
+(p8) fclass.m p9,p8=f9,0xc3
+ nop.i 0;;
+}
+{.mfi
+ nop.m 999
+(p8) frcpa.s0 f8,p0 = f8,f8
+ nop.i 0
+}
+{ .mfi
+ nop.m 999
+ // also set Denormal flag if necessary
+(p8) fma.s0 f9=f9,f1,f0
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p8) fma.d.s0 f8=f8,f1,f0
+ nop.b 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p9) frcpa.s0 f8,p7=f8,f9
+ br.ret.sptk b0 ;;
+}
+
+
+FMOD_Y_NAN_INF_ZERO:
+
+// Y INF
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f9, 0x23
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p7) fma.d.s0 f8=f8,f1,f0
+(p7) br.ret.spnt b0 ;;
+}
+
+// Y NAN?
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p0 = f9, 0xc3
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p9) fma.d.s0 f8=f9,f1,f0
+(p9) br.ret.spnt b0 ;;
+}
+
+FMOD_Y_ZERO:
+// Y zero? Must be zero at this point
+// because it is the only choice left.
+// Return QNAN indefinite
+
+{.mfi
+ nop.m 0
+ // set Invalid
+ frcpa.s0 f12,p0=f0,f0
+ nop.i 0
+}
+// X NAN?
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p10 = f8, 0xc3
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fclass.nm p9,p10 = f8, 0xff
+ nop.i 999 ;;
+}
+
+{.mfi
+ nop.m 999
+ (p9) frcpa.s0 f11,p7=f8,f0
+ nop.i 0;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) frcpa.s0 f11,p7 = f9,f9
+ mov GR_Parameter_TAG = 121 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fmerge.s f10 = f8, f8
+ nop.i 999
+}
+
+{ .mfb
+ nop.m 999
+ fma.d.s0 f8=f11,f1,f0
+ br.sptk __libm_error_region;;
+}
+
+GLOBAL_IEEE754_END(fmod)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_fmodf.S b/libc/sysdeps/ia64/fpu/e_fmodf.S
new file mode 100644
index 000000000..36e580729
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_fmodf.S
@@ -0,0 +1,571 @@
+.file "fmodf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//====================================================================
+// 02/02/00 Initial version
+// 03/02/00 New Algorithm
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 11/28/00 Set FR_Y to f9
+// 03/11/02 Fixed flags for fmodf(qnan,zero)
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 04/28/03 Fix: fmod(sNaN,0) no longer sets errno
+//
+// API
+//====================================================================
+// float fmodf(float,float);
+//
+// Overview of operation
+//====================================================================
+// fmod(a,b)=a-i*b,
+// where i is an integer such that, if b!=0,
+// |i|<|a/b| and |a/b-i|<1
+
+// Algorithm
+//====================================================================
+// a). if |a|<|b|, return a
+// b). get quotient and reciprocal overestimates accurate to
+// 33 bits (q2,y2)
+// c). if the exponent difference (exponent(a)-exponent(b))
+// is less than 32, truncate quotient to integer and
+// finish in one iteration
+// d). if exponent(a)-exponent(b)>=32 (q2>=2^32)
+// round quotient estimate to single precision (k=RN(q2)),
+// calculate partial remainder (a'=a-k*b),
+// get quotient estimate (a'*y2), and repeat from c).
+
+// Special cases
+//====================================================================
+// b=+/-0: return NaN, call libm_error_support
+// a=+/-Inf, a=NaN or b=NaN: return NaN
+
+// Registers used
+//====================================================================
+// Predicate registers: p6-p11
+// General registers: r2,r29,r32 (ar.pfs), r33-r39
+// Floating point registers: f6-f15
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+FR_X = f10
+FR_Y = f9
+FR_RESULT = f8
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(fmodf)
+
+// inputs in f8, f9
+// result in f8
+
+{ .mfi
+ alloc r32=ar.pfs,1,4,4,0
+ // f6=|a|
+ fmerge.s f6=f0,f8
+ mov r2 = 0x0ffdd
+}
+ {.mfi
+ nop.m 0
+ // f7=|b|
+ fmerge.s f7=f0,f9
+ nop.i 0;;
+}
+
+{ .mfi
+ setf.exp f11 = r2
+ // (1) y0
+ frcpa.s1 f10,p6=f6,f7
+ nop.i 0
+}
+
+// eliminate special cases
+// Y +-NAN, +-inf, +-0? p7
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f9, 0xe7
+ nop.i 999;;
+}
+
+// qnan snan inf norm unorm 0 -+
+// 1 1 1 0 0 0 11
+// e 3
+// X +-NAN, +-inf, ? p9
+
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p0 = f8, 0xe3
+ nop.i 999
+}
+
+// |x| < |y|? Return x p8
+{ .mfi
+ nop.m 999
+ fcmp.lt.unc.s1 p8,p0 = f6,f7
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 0
+ // normalize y (if |x|<|y|)
+ (p8) fma.s0 f9=f9,f1,f0
+ nop.i 0;;
+}
+
+ { .mfi
+ mov r2=0x1001f
+ // (2) q0=a*y0
+ (p6) fma.s1 f13=f6,f10,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (3) e0 = 1 - b * y0
+ (p6) fnma.s1 f12=f7,f10,f1
+ nop.i 0;;
+}
+
+ {.mfi
+ nop.m 0
+ // normalize x (if |x|<|y|)
+ (p8) fma.s.s0 f8=f8,f1,f0
+ nop.i 0
+}
+{.bbb
+ (p9) br.cond.spnt FMOD_X_NAN_INF
+ (p7) br.cond.spnt FMOD_Y_NAN_INF_ZERO
+ // if |x|<|y|, return
+ (p8) br.ret.spnt b0;;
+}
+
+ {.mfi
+ nop.m 0
+ // normalize x
+ fma.s0 f6=f6,f1,f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // normalize y
+ fma.s0 f7=f7,f1,f0
+ nop.i 0;;
+}
+
+
+ {.mfi
+ // f15=2^32
+ setf.exp f15=r2
+ // (4) q1=q0+e0*q0
+ (p6) fma.s1 f13=f12,f13,f13
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (5) e1 = e0 * e0 + 2^-34
+ (p6) fma.s1 f14=f12,f12,f11
+ nop.i 0;;
+}
+{.mlx
+ nop.m 0
+ movl r2=0x33a00000;;
+}
+{ .mfi
+ nop.m 0
+ // (6) y1 = y0 + e0 * y0
+ (p6) fma.s1 f10=f12,f10,f10
+ nop.i 0;;
+}
+{.mfi
+ // set f12=1.25*2^{-24}
+ setf.s f12=r2
+ // (7) q2=q1+e1*q1
+ (p6) fma.s1 f13=f13,f14,f13
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ fmerge.s f9=f8,f9
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (8) y2 = y1 + e1 * y1
+ (p6) fma.s1 f10=f14,f10,f10
+ // set p6=0, p10=0
+ cmp.ne.and p6,p10=r0,r0;;
+}
+
+.align 32
+loop24:
+ {.mfi
+ nop.m 0
+ // compare q2, 2^32
+ fcmp.lt.unc.s1 p8,p7=f13,f15
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // will truncate quotient to integer, if exponent<32 (in advance)
+ fcvt.fx.trunc.s1 f11=f13
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // if exponent>32, round quotient to single precision (perform in advance)
+ fma.s.s1 f13=f13,f1,f0
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // set f12=sgn(a)
+ (p8) fmerge.s f12=f8,f1
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // normalize truncated quotient
+ (p8) fcvt.xf f13=f11
+ nop.i 0;;
+}
+ { .mfi
+ nop.m 0
+ // calculate remainder (assuming f13=RZ(Q))
+ (p7) fnma.s1 f14=f13,f7,f6
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // also if exponent>32, round quotient to single precision
+ // and subtract 1 ulp: q=q-q*(1.25*2^{-24})
+ (p7) fnma.s.s1 f11=f13,f12,f13
+ nop.i 0;;
+}
+
+ {.mfi
+ nop.m 0
+ // (p8) calculate remainder (82-bit format)
+ (p8) fnma.s1 f11=f13,f7,f6
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // (p7) calculate remainder (assuming f11=RZ(Q))
+ (p7) fnma.s1 f6=f11,f7,f6
+ nop.i 0;;
+}
+
+
+ {.mfi
+ nop.m 0
+ // Final iteration (p8): is f6 the correct remainder (quotient was not overestimated) ?
+ (p8) fcmp.lt.unc.s1 p6,p10=f11,f0
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // get new quotient estimation: a'*y2
+ (p7) fma.s1 f13=f14,f10,f0
+ nop.i 0
+}
+ {.mfb
+ nop.m 0
+ // was f14=RZ(Q) ? (then new remainder f14>=0)
+ (p7) fcmp.lt.unc.s1 p7,p9=f14,f0
+ nop.b 0;;
+}
+
+
+.pred.rel "mutex",p6,p10
+ {.mfb
+ nop.m 0
+ // add b to estimated remainder (to cover the case when the quotient was overestimated)
+ // also set correct sign by using f9=|b|*sgn(a), f12=sgn(a)
+ (p6) fma.s.s0 f8=f11,f12,f9
+ nop.b 0
+}
+ {.mfb
+ nop.m 0
+ // calculate remainder (single precision)
+ // set correct sign of result before returning
+ (p10) fma.s.s0 f8=f11,f12,f0
+ (p8) br.ret.sptk b0;;
+}
+ {.mfi
+ nop.m 0
+ // if f13!=RZ(Q), get alternative quotient estimation: a''*y2
+ (p7) fma.s1 f13=f6,f10,f0
+ nop.i 0
+}
+ {.mfb
+ nop.m 0
+ // if f14 was RZ(Q), set remainder to f14
+ (p9) mov f6=f14
+ br.cond.sptk loop24;;
+}
+
+ { .mmb
+ nop.m 0
+ nop.m 0
+ br.ret.sptk b0;;
+ }
+
+FMOD_X_NAN_INF:
+
+
+// Y zero ?
+{.mfi
+ nop.m 0
+ fclass.m p10,p0=f8,0xc3 // Test x=nan
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 f10=f9,f1,f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ fma.s0 f8=f8,f1,f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+(p10) fclass.m p10,p0=f9,0x07 // Test x=nan, and y=zero
+ nop.i 0;;
+}
+{.mfb
+ nop.m 0
+ fcmp.eq.unc.s1 p11,p0=f10,f0
+(p10) br.ret.spnt b0;; // Exit with result=x if x=nan and y=zero
+}
+{.mib
+ nop.m 0
+ nop.i 0
+ // if Y zero
+ (p11) br.cond.spnt FMOD_Y_ZERO;;
+}
+
+// X infinity? Return QNAN indefinite
+{ .mfi
+ nop.m 999
+ fclass.m.unc p8,p9 = f8, 0x23
+ nop.i 999;;
+}
+// Y NaN ?
+{.mfi
+ nop.m 999
+(p8) fclass.m p9,p8=f9,0xc3
+ nop.i 0;;
+}
+{.mfi
+ nop.m 999
+(p8) frcpa.s0 f8,p0 = f8,f8
+ nop.i 0
+}
+{ .mfi
+ nop.m 999
+ // also set Denormal flag if necessary
+(p8) fma.s0 f9=f9,f1,f0
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p8) fma.s.s0 f8=f8,f1,f0
+ nop.b 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p9) frcpa.s0 f8,p7=f8,f9
+ br.ret.sptk b0 ;;
+}
+
+
+FMOD_Y_NAN_INF_ZERO:
+
+// Y INF
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f9, 0x23
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p7) fma.s.s0 f8=f8,f1,f0
+(p7) br.ret.spnt b0 ;;
+}
+
+// Y NAN?
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p0 = f9, 0xc3
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p9) fma.s.s0 f8=f9,f1,f0
+(p9) br.ret.spnt b0 ;;
+}
+
+FMOD_Y_ZERO:
+// Y zero? Must be zero at this point
+// because it is the only choice left.
+// Return QNAN indefinite
+
+{.mfi
+ nop.m 0
+ // set Invalid
+ frcpa.s0 f12,p0=f0,f0
+ nop.i 999
+}
+// X NAN?
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p10 = f8, 0xc3
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fclass.nm p9,p10 = f8, 0xff
+ nop.i 999 ;;
+}
+
+{.mfi
+ nop.m 999
+ (p9) frcpa.s0 f11,p7=f8,f0
+ nop.i 0;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) frcpa.s0 f11,p7 = f0,f0
+nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fmerge.s f10 = f8, f8
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+ fma.s.s0 f8=f11,f1,f0
+ nop.i 999;;
+}
+
+EXP_ERROR_RETURN:
+
+
+{ .mib
+ nop.m 0
+ mov GR_Parameter_TAG=122
+ br.sptk __libm_error_region;;
+}
+
+GLOBAL_IEEE754_END(fmodf)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support#;; // Call error handling function
+}
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_fmodl.S b/libc/sysdeps/ia64/fpu/e_fmodl.S
new file mode 100644
index 000000000..3e87eb090
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_fmodl.S
@@ -0,0 +1,672 @@
+.file "fmodl.s"
+
+
+// Copyright (c) 2000 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//====================================================================
+// 02/02/00 Initial version
+// 03/02/00 New Algorithm
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [ the previously overwritten ] GR_Parameter_RESULT.
+// 11/28/00 Set FR_Y to f9
+// 03/11/02 Fixed flags for fmodl(qnan, zero)
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header:.section,.global,.proc,.align
+// 04/28/03 Fix: fmod(sNaN, 0) no longer sets errno
+// 11/23/04 Reformatted routine and improved speed
+//
+// API
+//====================================================================
+// long double fmodl(long double, long double);
+//
+// Overview of operation
+//====================================================================
+// fmod(a, b)= a-i*b,
+// where i is an integer such that, if b!= 0,
+// |i|<|a/b| and |a/b-i|<1
+//
+// Algorithm
+//====================================================================
+// a). if |a|<|b|, return a
+// b). get quotient and reciprocal overestimates accurate to
+// 33 bits (q2, y2)
+// c). if the exponent difference (exponent(a)-exponent(b))
+// is less than 32, truncate quotient to integer and
+// finish in one iteration
+// d). if exponent(a)-exponent(b)>= 32 (q2>= 2^32)
+// round quotient estimate to single precision (k= RN(q2)),
+// calculate partial remainder (a'= a-k*b),
+// get quotient estimate (a'*y2), and repeat from c).
+//
+// Registers used
+//====================================================================
+
+GR_SMALLBIASEXP = r2
+GR_2P32 = r3
+GR_SMALLBIASEXP = r20
+GR_ROUNDCONST = r21
+GR_SIG_B = r22
+GR_ARPFS = r23
+GR_TMP1 = r24
+GR_TMP2 = r25
+GR_TMP3 = r26
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+FR_X = f10
+FR_Y = f9
+FR_RESULT = f8
+
+FR_ABS_A = f6
+FR_ABS_B = f7
+FR_Y_INV = f10
+FR_SMALLBIAS = f11
+FR_E0 = f12
+FR_Q = f13
+FR_E1 = f14
+FR_2P32 = f15
+FR_TMPX = f32
+FR_TMPY = f33
+FR_ROUNDCONST = f34
+FR_QINT = f35
+FR_QRND24 = f36
+FR_NORM_B = f37
+FR_TMP = f38
+FR_TMP2 = f39
+FR_DFLAG = f40
+FR_Y_INV0 = f41
+FR_Y_INV1 = f42
+FR_Q0 = f43
+FR_Q1 = f44
+FR_QINT_Z = f45
+FR_QREM = f46
+FR_B_SGN_A = f47
+
+.section .text
+GLOBAL_IEEE754_ENTRY(fmodl)
+
+// inputs in f8, f9
+// result in f8
+
+{ .mfi
+ getf.sig GR_SIG_B = f9
+ // FR_ABS_A = |a|
+ fmerge.s FR_ABS_A = f0, f8
+ mov GR_SMALLBIASEXP = 0x0ffdd
+}
+{ .mfi
+ nop.m 0
+ // FR_ABS_B = |b|
+ fmerge.s FR_ABS_B = f0, f9
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp FR_SMALLBIAS = GR_SMALLBIASEXP
+ // (1) y0
+ frcpa.s1 FR_Y_INV0, p6 = FR_ABS_A, FR_ABS_B
+ nop.i 0
+}
+;;
+
+{ .mlx
+ nop.m 0
+ movl GR_ROUNDCONST = 0x33a00000
+}
+;;
+
+// eliminate special cases
+{ .mmi
+ nop.m 0
+ nop.m 0
+ // y pseudo-zero ?
+ cmp.eq p7, p10 = GR_SIG_B, r0
+}
+;;
+
+// set p7 if b +/-NAN, +/-inf, +/-0
+{ .mfi
+ nop.m 0
+ (p10) fclass.m p7, p10 = f9, 0xe7
+ nop.i 0
+}
+;;
+
+{ .mfi
+ mov GR_2P32 = 0x1001f
+ // (2) q0 = a*y0
+ (p6) fma.s1 FR_Q0 = FR_ABS_A, FR_Y_INV0, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (3) e0 = 1 - b * y0
+ (p6) fnma.s1 FR_E0 = FR_ABS_B, FR_Y_INV0, f1
+ nop.i 0
+}
+;;
+
+// set p9 if a +/-NAN, +/-inf
+{ .mfi
+ nop.m 0
+ fclass.m.unc p9, p11 = f8, 0xe3
+ nop.i 0
+}
+ // |a| < |b|? Return a, p8=1
+{ .mfi
+ nop.m 0
+ (p10) fcmp.lt.unc.s1 p8, p0 = FR_ABS_A, FR_ABS_B
+ nop.i 0
+}
+;;
+
+// set p7 if b +/-NAN, +/-inf, +/-0
+{ .mfi
+ nop.m 0
+ // pseudo-NaN ?
+ (p10) fclass.nm p7, p0 = f9, 0xff
+ nop.i 0
+}
+;;
+
+// set p9 if a is +/-NaN, +/-Inf
+{ .mfi
+ nop.m 0
+ (p11) fclass.nm p9, p0 = f8, 0xff
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // b denormal ? set D flag (if |a|<|b|)
+ (p8) fnma.s0 FR_DFLAG = f9, f1, f9
+ nop.i 0
+}
+;;
+
+{ .mfi
+ // FR_2P32 = 2^32
+ setf.exp FR_2P32 = GR_2P32
+ // (4) q1 = q0+e0*q0
+ (p6) fma.s1 FR_Q1 = FR_E0, FR_Q0, FR_Q0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (5) e1 = e0 * e0 + 2^-34
+ (p6) fma.s1 FR_E1 = FR_E0, FR_E0, FR_SMALLBIAS
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // normalize a (if |a|<|b|)
+ (p8) fma.s0 f8 = f8, f1, f0
+ nop.i 0
+}
+{ .bbb
+ (p9) br.cond.spnt FMOD_A_NAN_INF
+ (p7) br.cond.spnt FMOD_B_NAN_INF_ZERO
+ // if |a|<|b|, return
+ (p8) br.ret.spnt b0
+}
+;;
+
+
+{ .mfi
+ nop.m 0
+ // (6) y1 = y0 + e0 * y0
+ (p6) fma.s1 FR_Y_INV1 = FR_E0, FR_Y_INV0, FR_Y_INV0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // a denormal ? set D flag
+ // b denormal ? set D flag
+ fcmp.eq.s0 p12,p0 = FR_ABS_A, FR_ABS_B
+ nop.i 0
+}
+{ .mfi
+ // set FR_ROUNDCONST = 1.25*2^{-24}
+ setf.s FR_ROUNDCONST = GR_ROUNDCONST
+ // (7) q2 = q1+e1*q1
+ (p6) fma.s1 FR_Q = FR_Q1, FR_E1, FR_Q1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fmerge.s FR_B_SGN_A = f8, f9
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (8) y2 = y1 + e1 * y1
+ (p6) fma.s1 FR_Y_INV = FR_E1, FR_Y_INV1, FR_Y_INV1
+ // set p6 = 0, p10 = 0
+ cmp.ne.and p6, p10 = r0, r0
+}
+;;
+
+// will compute integer quotient bits (24 bits per iteration)
+.align 32
+loop64:
+{ .mfi
+ nop.m 0
+ // compare q2, 2^32
+ fcmp.lt.unc.s1 p8, p7 = FR_Q, FR_2P32
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // will truncate quotient to integer, if exponent<32 (in advance)
+ fcvt.fx.trunc.s1 FR_QINT = FR_Q
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // if exponent>32 round quotient to single precision (perform in advance)
+ fma.s.s1 FR_QRND24 = FR_Q, f1, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // set FR_ROUNDCONST = sgn(a)
+ (p8) fmerge.s FR_ROUNDCONST = f8, f1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // normalize truncated quotient
+ (p8) fcvt.xf FR_QRND24 = FR_QINT
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // calculate remainder (assuming FR_QRND24 = RZ(Q))
+ (p7) fnma.s1 FR_E1 = FR_QRND24, FR_ABS_B, FR_ABS_A
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // also if exponent>32, round quotient to single precision
+ // and subtract 1 ulp: q = q-q*(1.25*2^{-24})
+ (p7) fnma.s.s1 FR_QINT_Z = FR_QRND24, FR_ROUNDCONST, FR_QRND24
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // (p8) calculate remainder (82-bit format)
+ (p8) fnma.s1 FR_QREM = FR_QRND24, FR_ABS_B, FR_ABS_A
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (p7) calculate remainder (assuming FR_QINT_Z = RZ(Q))
+ (p7) fnma.s1 FR_ABS_A = FR_QINT_Z, FR_ABS_B, FR_ABS_A
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // Final iteration (p8): is FR_ABS_A the correct remainder
+ // (quotient was not overestimated) ?
+ (p8) fcmp.lt.unc.s1 p6, p10 = FR_QREM, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // get new quotient estimation: a'*y2
+ (p7) fma.s1 FR_Q = FR_E1, FR_Y_INV, f0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ // was FR_Q = RZ(Q) ? (then new remainder FR_E1> = 0)
+ (p7) fcmp.lt.unc.s1 p7, p9 = FR_E1, f0
+ nop.b 0
+}
+;;
+
+.pred.rel "mutex", p6, p10
+{ .mfb
+ nop.m 0
+ // add b to estimated remainder (to cover the case when the quotient was
+ // overestimated)
+ // also set correct sign by using
+ // FR_B_SGN_A = |b|*sgn(a), FR_ROUNDCONST = sgn(a)
+ (p6) fma.s0 f8 = FR_QREM, FR_ROUNDCONST, FR_B_SGN_A
+ nop.b 0
+}
+{ .mfb
+ nop.m 0
+ // set correct sign of result before returning: FR_ROUNDCONST = sgn(a)
+ (p10) fma.s0 f8 = FR_QREM, FR_ROUNDCONST, f0
+ (p8) br.ret.sptk b0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // if f13! = RZ(Q), get alternative quotient estimation: a''*y2
+ (p7) fma.s1 FR_Q = FR_ABS_A, FR_Y_INV, f0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ // if FR_E1 was RZ(Q), set remainder to FR_E1
+ (p9) fma.s1 FR_ABS_A = FR_E1, f1, f0
+ br.cond.sptk loop64
+}
+;;
+
+FMOD_A_NAN_INF:
+
+// b zero ?
+{ .mfi
+ nop.m 0
+ fclass.m p10, p0 = f8, 0xc3 // Test a = nan
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_NORM_B = f9, f1, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s0 f8 = f8, f1, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ (p10) fclass.m p10, p0 = f9, 0x07 // Test x = nan, and y = zero
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fcmp.eq.unc.s1 p11, p0 = FR_NORM_B, f0
+ (p10) br.ret.spnt b0 // Exit with result = a if a = nan and b = zero
+}
+;;
+
+{ .mib
+ nop.m 0
+ nop.i 0
+ // if Y zero
+ (p11) br.cond.spnt FMOD_B_ZERO
+}
+;;
+
+// a= infinity? Return QNAN indefinite
+{ .mfi
+ // set p7 t0 0
+ cmp.ne p7, p0 = r0, r0
+ fclass.m.unc p8, p9 = f8, 0x23
+ nop.i 0
+}
+;;
+
+// b NaN ?
+{ .mfi
+ nop.m 0
+ (p8) fclass.m p9, p8 = f9, 0xc3
+ nop.i 0
+}
+;;
+
+// b not pseudo-zero ? (GR_SIG_B holds significand)
+{ .mii
+ nop.m 0
+ (p8) cmp.ne p7, p0 = GR_SIG_B, r0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ (p8) frcpa.s0 f8, p0 = f8, f8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // also set Denormal flag if necessary
+ (p7) fnma.s0 f9 = f9, f1, f9
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ (p8) fma.s0 f8 = f8, f1, f0
+ nop.b 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ (p9) frcpa.s0 f8, p7 = f8, f9
+ br.ret.sptk b0
+}
+;;
+
+FMOD_B_NAN_INF_ZERO:
+// b INF
+{ .mfi
+ nop.m 0
+ fclass.m.unc p7, p0 = f9, 0x23
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ (p7) fma.s0 f8 = f8, f1, f0
+ (p7) br.ret.spnt b0
+}
+;;
+
+// b NAN?
+{ .mfi
+ nop.m 0
+ fclass.m.unc p9, p10 = f9, 0xc3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ (p10) fclass.nm p9, p0 = f9, 0xff
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ (p9) fma.s0 f8 = f9, f1, f0
+ (p9) br.ret.spnt b0
+}
+;;
+
+FMOD_B_ZERO:
+// Y zero? Must be zero at this point
+// because it is the only choice left.
+// Return QNAN indefinite
+
+{ .mfi
+ nop.m 0
+ // set Invalid
+ frcpa.s0 FR_TMP, p0 = f0, f0
+ nop.i 0
+}
+;;
+
+// a NAN?
+{ .mfi
+ nop.m 0
+ fclass.m.unc p9, p10 = f8, 0xc3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ alloc GR_ARPFS = ar.pfs, 1, 4, 4, 0
+ (p10) fclass.nm p9, p10 = f8, 0xff
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ (p9) frcpa.s0 FR_TMP2, p7 = f8, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ (p10) frcpa.s0 FR_TMP2, p7 = f9, f9
+ mov GR_Parameter_TAG = 120
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8, f8
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s0 f8 = FR_TMP2, f1, f0
+ br.sptk __libm_error_region
+}
+;;
+
+GLOBAL_IEEE754_END(fmodl)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y = -32, sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs, GR_SAVE_PFS
+ mov GR_SAVE_PFS = ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp = -64, sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP = gp // Save gp
+}
+;;
+
+{ .mmi
+ stfe [ GR_Parameter_Y ] = FR_Y, 16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16, sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0 = b0 // Save b0
+}
+;;
+
+.body
+{ .mib
+ stfe [ GR_Parameter_X ] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0, GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [ GR_Parameter_Y ] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16, GR_Parameter_Y
+ br.call.sptk b0 = __libm_error_support# // Call error handling function
+}
+;;
+
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48, sp
+}
+;;
+
+{ .mmi
+ ldfe f8 = [ GR_Parameter_RESULT ] // Get return result off stack
+.restore sp
+ add sp = 64, sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+}
+;;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+}
+;;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#, @function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_gamma_r.c b/libc/sysdeps/ia64/fpu/e_gamma_r.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_gamma_r.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/e_gammaf_r.c b/libc/sysdeps/ia64/fpu/e_gammaf_r.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_gammaf_r.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/e_gammal_r.c b/libc/sysdeps/ia64/fpu/e_gammal_r.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_gammal_r.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/e_hypot.S b/libc/sysdeps/ia64/fpu/e_hypot.S
new file mode 100644
index 000000000..36cfd1e66
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_hypot.S
@@ -0,0 +1,440 @@
+.file "hypot.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 02/02/00 hand-optimized
+// 04/04/00 Unwind support added
+// 06/20/00 new version
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 04/17/03 Added missing mutex directive
+//
+//*********************************************************************
+// ___________
+// Function: hypot(x,y) = |(x^2 + y^2) = for double precision values
+// x and y
+// Also provides cabs functionality.
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f9 (Input)
+// f6 -f15, f32-f34
+//
+// General Purpose Registers:
+// r2,r3,r29 (Scratch)
+// r32-r36 (Locals)
+// r37-r40 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6 - p10
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// All faults and exceptions should be raised correctly.
+// Overflow can occur.
+// hypot(Infinity and anything) = +Infinity
+// hypot(QNaN and anything) = QNaN
+// hypot(SNaN and anything ) = QNaN
+//
+//*********************************************************************
+//
+// Implementation:
+// x2 = x * x in double-extended
+// y2 = y * y in double-extended
+// temp = x2 + y2 in double-extended
+// sqrt(temp) rounded to double
+//
+//*********************************************************************
+
+GR_SAVE_PFS = r33
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+FR_X = f32
+FR_Y = f33
+FR_RESULT = f8
+
+.section .text
+
+LOCAL_LIBM_ENTRY(cabs)
+LOCAL_LIBM_END(cabs)
+
+GLOBAL_IEEE754_ENTRY(hypot)
+
+{.mfi
+ alloc r32= ar.pfs,0,4,4,0
+ // Compute x*x
+ fma.s1 f10=f8,f8,f0
+ // r2=bias-1
+ mov r2=0xfffe
+}
+{.mfi
+ // 63/8
+ mov r3=0x40fc //0000
+ // y*y
+ fma.s1 f11=f9,f9,f0
+ // r29=429/16
+ mov r29=0x41d68;; //000
+}
+
+{ .mfi
+ nop.m 0
+// Check if x is an Inf - if so return Inf even
+// if y is a NaN (C9X)
+ fclass.m.unc p7, p6 = f8, 0x023
+ shl r3=r3,16
+}
+{.mfi
+ nop.m 0
+ // if possible overflow, copy f8 to f32
+ // set Denormal, if necessary
+ // (p8)
+ fma.d.s0 f32=f8,f1,f0
+ nop.i 0;;
+}
+{ .mfi
+ nop.m 0
+// Check if y is an Inf - if so return Inf even
+// if x is a NaN (C9X)
+ fclass.m.unc p8, p9 = f9, 0x023
+ shl r29=r29,12
+}
+{ .mfb
+ // f7=0.5
+ setf.exp f7=r2
+// For x=inf, multiply y by 1 to raise invalid on y an SNaN
+// (p7) fma.s0 f9=f9,f1,f0
+ // copy f9 to f33; set Denormal, if necessary
+ fma.d.s0 f33=f9,f1,f0
+ nop.b 0;;
+}
+{.mfb
+ // f13=63/8
+ setf.s f13=r3
+ // is y Zero ?
+ (p6) fclass.m p6,p0=f9,0x7
+ nop.b 0
+}
+{.mlx
+ nop.m 0
+ movl r2=0x408c0000;;
+}
+
+{.mfi
+ // f34=429/16
+ setf.s f34=r29
+ // is x Zero ?
+ (p9) fclass.m p9,p0=f8,0x7
+ // 231/16
+ mov r3=0x4167;; //0000
+}
+{.mfi
+ nop.m 0
+ // a=x2+y2
+ fma.s1 f12=f10,f1,f11
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // y not NaN ?
+ (p9) fclass.m p8,p0=f9,0x3f
+ shl r3=r3,16
+}
+{.mfi
+ nop.m 0
+ // f6=2
+ fma.s1 f6=f1,f1,f1
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // x not NaN ?
+ (p6) fclass.m p7,p0=f8,0x3f
+ nop.i 0;;
+}
+{.mfi
+ // f9=35/8
+ setf.s f9=r2
+ nop.f 0
+ // 2*emax-2
+ mov r2=0x107fb;;
+}
+
+.pred.rel "mutex",p7,p8
+{.mfb
+ nop.m 0
+ // if f8=Infinity or f9=Zero, return |f8|
+ (p7) fmerge.s f8=f0,f32
+ (p7) br.ret.spnt b0
+}
+{.mfb
+ nop.m 0
+ // if f9=Infinity or f8=Zero, return |f9|
+ (p8) fmerge.s f8=f0,f33
+ (p8) br.ret.spnt b0;;
+}
+
+
+{.mfi
+ // f10 =231/16
+ setf.s f10=r3
+ // z0=frsqrta(a)
+ frsqrta.s1 f8,p6=f12
+ nop.i 0;;
+}
+
+{ .mfi
+ nop.m 0
+// Identify Natvals, Infs, NaNs, and Zeros
+// and return result
+ fclass.m.unc p7, p0 = f12, 0x1E7
+ nop.i 0;;
+}
+{.mfb
+ // get exponent of x^2+y^2
+ getf.exp r3=f12
+ // if special case, set f8
+ (p7) mov f8=f12
+ (p7) br.ret.spnt b0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // S0=a*z0
+ (p6) fma.s1 f14=f12,f8,f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // H0=0.5*z0
+ (p6) fma.s1 f15=f8,f7,f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // f6=5/2
+ fma.s1 f6=f7,f1,f6
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // f11=3/2
+ fma.s1 f11=f7,f1,f1
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // d=0.5-S0*H0
+ (p6) fnma.s1 f7=f14,f15,f7
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // P67=231/16+429/16*d
+ (p6) fma.s1 f10=f34,f7,f10
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P45=63/8*d+35/8
+ (p6) fma.s1 f9=f13,f7,f9
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // P23=5/2*d+3/2
+ (p6) fma.s1 f11=f6,f7,f11
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // d2=d*d
+ (p6) fma.s1 f13=f7,f7,f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // P47=d2*P67+P45
+ (p6) fma.s1 f10=f10,f13,f9
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P13=d*P23+1
+ (p6) fma.s1 f11=f11,f7,f1
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // d3=d2*d
+ (p6) fma.s1 f13=f13,f7,f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // T0=d*S0
+ (p6) fma.s1 f15=f7,f14,f0
+ nop.i 0
+}
+{.mfi
+ // Is x^2 + y^2 well less than the overflow
+ // threshold?
+ (p6) cmp.lt.unc p7, p8 = r3,r2
+ // P=P13+d3*P47
+ (p6) fma.s1 f10=f13,f10,f11
+ nop.i 0;;
+}
+
+{.mfb
+ nop.m 0
+ // S=P*T0+S0
+ fma.d.s0 f8=f10,f15,f14
+ // No overflow in this case
+ (p7) br.ret.sptk b0;;
+}
+
+{ .mfi
+ nop.m 0
+(p8) fsetc.s2 0x7F,0x42
+ // Possible overflow path, must detect by
+ // Setting widest range exponent with prevailing
+ // rounding mode.
+ nop.i 0 ;;
+}
+
+
+{ .mfi
+ // bias+0x400 (bias+EMAX+1)
+ (p8) mov r2=0x103ff
+ // S=P*T0+S0
+ (p8) fma.d.s2 f12=f10,f15,f14
+ nop.i 0 ;;
+}
+{ .mfi
+(p8) setf.exp f11 = r2
+(p8) fsetc.s2 0x7F,0x40
+// Restore Original Mode in S2
+ nop.i 0 ;;
+}
+{ .mfi
+ nop.m 0
+(p8) fcmp.lt.unc.s1 p9, p10 = f12, f11
+ nop.i 0 ;;
+}
+{ .mib
+ nop.m 0
+ mov GR_Parameter_TAG = 46
+ // No overflow
+(p9) br.ret.sptk b0;;
+}
+GLOBAL_IEEE754_END(hypot)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+LOCAL_LIBM_END(__libm_error_region#)
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_hypotf.S b/libc/sysdeps/ia64/fpu/e_hypotf.S
new file mode 100644
index 000000000..d6fcbd1a0
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_hypotf.S
@@ -0,0 +1,395 @@
+.file "hypotf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 02/02/00 hand-optimized
+// 04/04/00 Unwind support added
+// 06/26/00 new version
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 04/17/03 Added missing mutex directive
+//
+//*********************************************************************
+// ___________
+// Function: hypotf(x,y) = |(x^2 + y^2) = for single precision values
+// x and y
+// Also provides cabsf functionality.
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f9 (Input)
+// f6 -f15
+//
+// General Purpose Registers:
+// r2-r3 (Scratch)
+// r32-r36 (Locals)
+// r37-r40 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6 - p10
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// All faults and exceptions should be raised correctly.
+// Overflow can occur.
+// hypotf(Infinity and anything) = +Infinity
+// hypotf(QNaN and anything) = QNaN
+// hypotf(SNaN and anything ) = QNaN
+//
+//*********************************************************************
+//
+// Implementation:
+// x2 = x * x in double-extended
+// y2 = y * y in double-extended
+// temp = x2 + y2 in double-extended
+// sqrt(temp) rounded to single precision
+//
+//*********************************************************************
+
+GR_SAVE_PFS = r33
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+FR_X = f14
+FR_Y = f15
+FR_RESULT = f8
+
+.section .text
+
+LOCAL_LIBM_ENTRY(cabsf)
+LOCAL_LIBM_END(cabsf)
+
+GLOBAL_IEEE754_ENTRY(hypotf)
+{.mfi
+ alloc r32= ar.pfs,0,4,4,0
+ // Compute x*x
+ fma.s1 f10=f8,f8,f0
+ // r2=bias-1
+ mov r2=0xfffe
+}
+{.mfi
+ nop.m 0
+ // y*y
+ fma.s1 f11=f9,f9,f0
+ nop.i 0;;
+}
+
+{ .mfi
+ nop.m 0
+// Check if x is an Inf - if so return Inf even
+// if y is a NaN (C9X)
+ fclass.m.unc p7, p6 = f8, 0x023
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // if possible overflow, copy f8 to f14
+ // set Denormal, if necessary
+ // (p8)
+ fma.s.s0 f14=f8,f1,f0
+ nop.i 0;;
+}
+
+{ .mfi
+ nop.m 0
+// Check if y is an Inf - if so return Inf even
+// if x is a NaN (C9X)
+ fclass.m.unc p8, p9 = f9, 0x023
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+// For x=inf, multiply y by 1 to raise invalid on y an SNaN
+// (p7) fma.s0 f9=f9,f1,f0
+ // copy f9 to f15; set Denormal, if necessary
+ fma.s.s0 f15=f9,f1,f0
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // is y Zero ?
+ (p6) fclass.m p6,p0=f9,0x7
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // is x Zero ?
+ (p9) fclass.m p9,p0=f8,0x7
+ nop.i 0;;
+}
+
+{.mfi
+ // f7=0.5
+ setf.exp f7=r2
+ // a=x2+y2
+ fma.s1 f12=f10,f1,f11
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // x not NaN ?
+ (p6) fclass.m p7,p0=f8,0x3f
+ nop.i 0
+}
+{.mfi
+ // 2*emax-2
+ mov r2=0x100fb
+ // f6=2
+ fma.s1 f6=f1,f1,f1
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // y not NaN ?
+ (p9) fclass.m p8,p0=f9,0x3f
+ nop.i 0;;
+}
+
+.pred.rel "mutex",p7,p8
+{.mfb
+ nop.m 0
+ // if f8=Infinity or f9=Zero, return |f8|
+ (p7) fmerge.s f8=f0,f14
+ (p7) br.ret.spnt b0
+}
+{.mfb
+ nop.m 0
+ // if f9=Infinity or f8=Zero, return |f9|
+ (p8) fmerge.s f8=f0,f15
+ (p8) br.ret.spnt b0;;
+}
+
+{ .mfi
+ nop.m 0
+// Identify Natvals, Infs, NaNs, and Zeros
+// and return result
+ fclass.m.unc p7, p0 = f12, 0x1E7
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // z0=frsqrta(a)
+ frsqrta.s1 f8,p6=f12
+ nop.i 0;;
+}
+
+{.mfb
+ // get exponent of x^2+y^2
+ getf.exp r3=f12
+ // if special case, set f8
+ (p7) mov f8=f12
+ (p7) br.ret.spnt b0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // S0=a*z0
+ (p6) fma.s1 f12=f12,f8,f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // H0=0.5*z0
+ (p6) fma.s1 f10=f8,f7,f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // f6=5/2
+ fma.s1 f6=f7,f1,f6
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // f11=3/2
+ fma.s1 f11=f7,f1,f1
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // d=0.5-S0*H0
+ (p6) fnma.s1 f7=f12,f10,f7
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // P01=d+1
+ (p6) fma.s1 f10=f1,f7,f1
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P23=5/2*d+3/2
+ (p6) fma.s1 f11=f6,f7,f11
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // d2=d*d
+ (p6) fma.s1 f7=f7,f7,f0
+ nop.i 0;;
+}
+
+
+{.mfi
+ // Is x^2 + y^2 well less than the overflow
+ // threshold?
+ (p6) cmp.lt.unc p7, p8 = r3,r2
+ // P=P01+d2*P23
+ (p6) fma.s1 f10=f7,f11,f10
+ nop.i 0;;
+}
+
+{.mfb
+ nop.m 0
+ // S=P*S0
+ fma.s.s0 f8=f10,f12,f0
+ // No overflow in this case
+ (p7) br.ret.sptk b0;;
+}
+
+{ .mfi
+ nop.m 0
+(p8) fsetc.s2 0x7F,0x42
+ // Possible overflow path, must detect by
+ // Setting widest range exponent with prevailing
+ // rounding mode.
+ nop.i 0 ;;
+}
+
+
+{ .mfi
+ // bias+0x400 (bias+EMAX+1)
+ (p8) mov r2=0x1007f
+ // S=P*S0
+ (p8) fma.s.s2 f12=f10,f12,f0
+ nop.i 0 ;;
+}
+{ .mfi
+(p8) setf.exp f11 = r2
+(p8) fsetc.s2 0x7F,0x40
+// Restore Original Mode in S2
+ nop.i 0 ;;
+}
+{ .mfi
+ nop.m 0
+(p8) fcmp.lt.unc.s1 p9, p10 = f12, f11
+ nop.i 0 ;;
+}
+{ .mib
+ nop.m 0
+ mov GR_Parameter_TAG = 47
+ // No overflow
+(p9) br.ret.sptk b0;;
+}
+GLOBAL_IEEE754_END(hypotf)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mii
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ mov GR_Parameter_TAG = 47
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // Store Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/e_hypotl.S b/libc/sysdeps/ia64/fpu/e_hypotl.S
new file mode 100644
index 000000000..988b86e76
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_hypotl.S
@@ -0,0 +1,478 @@
+.file "hypotl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 02/02/00 hand-optimized
+// 04/04/00 Unwind support added
+// 06/20/00 new version
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+//*********************************************************************
+// ___________
+// Function: hypotl(x,y) = |(x^2 + y^2) = for double extended values
+// x and y
+// Also provides cabsl functionality.
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f9 (Input)
+// f6 -f15, f32-f34
+//
+// General Purpose Registers:
+// r2-r3 (Scratch)
+// r32-r36 (Locals)
+// r37-r40 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6 - p10
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// All faults and exceptions should be raised correctly.
+// Overflow can occur.
+// hypotl(Infinity and anything) = +Infinity
+// hypotl(QNaN and anything) = QNaN
+// hypotl(SNaN and anything ) = QNaN
+//
+//*********************************************************************
+//
+// Implementation:
+// x2 = x * x in double-extended
+// y2 = y * y in double-extended
+// temp = x2 + y2 in double-extended
+// sqrt(temp) rounded to double extended
+//
+//*********************************************************************
+
+GR_SAVE_PFS = r33
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+FR_X = f32
+FR_Y = f33
+FR_RESULT = f8
+
+.section .text
+
+LOCAL_LIBM_ENTRY(cabsl)
+LOCAL_LIBM_END(cabsl)
+
+GLOBAL_IEEE754_ENTRY(hypotl)
+{.mfi
+ alloc r32= ar.pfs,0,4,4,0
+ // Compute x*x
+ fma.s1 f10=f8,f8,f0
+ // r2=bias-1
+ mov r2=0xfffe
+}
+{.mfi
+ nop.m 0
+ // y*y
+ fma.s1 f11=f9,f9,f0
+ nop.i 0;;
+}
+
+{ .mfi
+ nop.m 0
+// Check if x is an Inf - if so return Inf even
+// if y is a NaN (C9X)
+ fclass.m.unc p7, p6 = f8, 0x023
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // if possible overflow, copy f8 to f32
+ // set Denormal, if necessary
+ // (p8)
+ fma.s0 f32=f8,f1,f0
+ nop.i 0;;
+}
+{ .mfi
+ nop.m 0
+// Check if y is an Inf - if so return Inf even
+// if x is a NaN (C9X)
+ fclass.m.unc p8, p9 = f9, 0x023
+ nop.i 0
+}
+{ .mfi
+ nop.m 999
+// For x=inf, multiply y by 1 to raise invalid on y an SNaN
+// (p7) fma.s0 f9=f9,f1,f0
+ // copy f9 to f33; set Denormal, if necessary
+ fma.s0 f33=f9,f1,f0
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // is y Zero ?
+ (p6) fclass.m p6,p0=f9,0x7
+ nop.i 0;;
+}
+
+{.mfi
+ // f7=0.5
+ setf.exp f7=r2
+ // a=x2+y2
+ fma.s1 f12=f10,f1,f11
+ nop.i 0
+}
+{.mfi
+ mov r2=0x408c //0000
+ // dx=x*x-x2
+ fms.s1 f13=f8,f8,f10
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // is x Zero ?
+ (p9) fclass.m p9,p0=f8,0x7
+ shl r2=r2,16
+}
+{.mfi
+ nop.m 0
+ // dy=y*y-y2
+ fms.s1 f14=f9,f9,f11
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // x not NaN ?
+ (p6) fclass.m p7,p0=f8,0x3f
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // f6=2
+ fma.s1 f6=f1,f1,f1
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // f34=min(x2,y2)
+ famin.s1 f34=f10,f11
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ // f10=max(x2,y2)
+ famax.s1 f10=f11,f10
+ nop.b 0;; //
+}
+
+{.mfi
+ nop.m 0
+ // y not NaN ?
+ (p9) fclass.m p8,p0=f9,0x3f
+ nop.i 0;;
+}
+{.mfb
+ // f9=35/8
+ setf.s f9=r2
+ // if f8=Infinity or f9=Zero, return |f8|
+ (p7) fmerge.s f8=f0,f32
+ (p7) br.ret.spnt b0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // z0=frsqrta(a)
+ frsqrta.s1 f8,p6=f12
+ nop.i 0;;
+}
+{ .mfi
+ nop.m 0
+// Identify Natvals, Infs, NaNs, and Zeros
+// and return result
+ fclass.m.unc p7, p0 = f12, 0x1E7
+ nop.i 0
+}
+{.mfi
+ // get exponent of x^2+y^2
+ getf.exp r3=f12
+ // dxy=dx+dy
+ fma.s1 f13=f13,f1,f14
+ nop.i 0;;
+}
+
+{.mfb
+ // 2*emax-2
+ mov r2=0x17ffb
+ // if f9=Infinity or f8=Zero, return |f9|
+ (p8) fmerge.s f8=f0,f33
+ (p8) br.ret.spnt b0
+}
+{.mfi
+ nop.m 0
+ // dd=a-max(x2,y2)
+ fnma.s1 f10=f10,f1,f12
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // S0=a*z0
+ (p6) fma.s1 f14=f12,f8,f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // H0=0.5*z0
+ (p6) fma.s1 f15=f8,f7,f0
+ nop.i 0;;
+}
+
+{.mfb
+ nop.m 0
+ // if special case, set f8
+ (p7) mov f8=f12
+ (p7) br.ret.spnt b0
+}
+{.mfi
+ nop.m 0
+ // da=min(x2,y2)-dd
+ fnma.s1 f10=f10,f1,f34
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // f6=5/2
+ fma.s1 f6=f7,f1,f6
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // f11=3/2
+ fma.s1 f11=f7,f1,f1
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // d=0.5-S0*H0
+ (p6) fnma.s1 f7=f14,f15,f7
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // P1=3/2*d+1
+ (p6) fma.s1 f11=f11,f7,f1
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P2=35/8*d+5/2
+ (p6) fma.s1 f9=f9,f7,f6
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // d2=d*d
+ (p6) fma.s1 f34=f7,f7,f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // T0=d*S0
+ (p6) fma.s1 f6=f7,f14,f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // G0=d*H0
+ (p6) fma.s1 f7=f7,f15,f0
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // P=d2*P2+P1
+ (p6) fma.s1 f11=f34,f9,f11
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // S1=p*T0+S0
+ (p6) fma.s1 f14=f11,f6,f14
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // H1=p*G0+H0
+ (p6) fma.s1 f15=f11,f7,f15
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // e1=a-S1*S1
+ (p6) fnma.s1 f7=f14,f14,f12
+ nop.i 0
+}
+{.mfi
+ // Is x^2 + y^2 well less than the overflow
+ // threshold?
+ (p6) cmp.lt.unc p7, p8 = r3,r2
+ // c=dxy+da
+ (p6) fma.s1 f13=f13,f1,f10
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // e=e1+c
+ (p6) fma.s1 f13=f7,f1,f13
+ nop.i 0;;
+}
+
+{.mfb
+ nop.m 0
+ // S=e*H1+S1
+ fma.s0 f8=f13,f15,f14
+ // No overflow in this case
+ (p7) br.ret.sptk b0;;
+}
+
+{ .mfi
+ nop.m 0
+(p8) fsetc.s2 0x7F,0x42
+ // Possible overflow path, must detect by
+ // Setting widest range exponent with prevailing
+ // rounding mode.
+ nop.i 0 ;;
+}
+
+
+{ .mfi
+ // bias+0x4000 (bias+EMAX+1)
+ (p8) mov r2=0x13fff
+ // S=e*H1+S1
+ (p8) fma.s2 f12=f13,f15,f14
+ nop.i 0 ;;
+}
+{ .mfi
+(p8) setf.exp f11 = r2
+(p8) fsetc.s2 0x7F,0x40
+// Restore Original Mode in S2
+ nop.i 0 ;;
+}
+{ .mfi
+ nop.m 0
+(p8) fcmp.lt.unc.s1 p9, p10 = f12, f11
+ nop.i 0 ;;
+}
+{ .mib
+ nop.m 0
+ mov GR_Parameter_TAG = 45;
+ // No overflow
+(p9) br.ret.sptk b0;;
+}
+GLOBAL_IEEE754_END(hypotl)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+LOCAL_LIBM_END(__libm_error_region#)
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_lgamma_r.c b/libc/sysdeps/ia64/fpu/e_lgamma_r.c
new file mode 100644
index 000000000..cb9efbfe0
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_lgamma_r.c
@@ -0,0 +1,71 @@
+/* file: lgamma_r.c */
+
+
+// Copyright (c) 2002 Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+// History
+//==============================================================
+// 02/04/02: Initial version
+// 02/22/02: Removed lgammaf_r, gammaf_r
+/*
+// FUNCTIONS: double lgamma_r(double x, int* signgam)
+// double gamma_r(double x, int* signgam)
+// Natural logarithm of GAMMA function
+*/
+
+#include "libm_support.h"
+
+
+extern double __libm_lgamma(double /*x*/, int* /*signgam*/, int /*signgamsz*/);
+
+
+double __ieee754_lgamma_r(double x, int* signgam)
+{
+ return __libm_lgamma(x, signgam, sizeof(*signgam));
+}
+weak_alias (__ieee754_lgamma_r, lgamma_r)
+
+#ifndef _LIBC
+double __ieee754_gamma_r(double x, int* signgam)
+{
+ return __libm_lgamma(x, signgam, sizeof(*signgam));
+}
+weak_alias (__ieee754_gamma_r, gamma_r)
+#endif
diff --git a/libc/sysdeps/ia64/fpu/e_lgammaf_r.c b/libc/sysdeps/ia64/fpu/e_lgammaf_r.c
new file mode 100644
index 000000000..44911aeab
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_lgammaf_r.c
@@ -0,0 +1,71 @@
+/* file: lgammaf_r.c */
+
+
+// Copyright (c) 2002 Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+// History
+//==============================================================
+// 02/04/02: Initial version
+// 02/22/02: Removed lgamma_r, gamma_r
+/*
+// FUNCTIONS: float lgammaf_r(float x, int* signgam)
+// float gammaf_r(float x, int* signgam)
+// Natural logarithm of GAMMA function
+*/
+
+#include "libm_support.h"
+
+
+extern float __libm_lgammaf(float /*x*/, int* /*signgam*/, int /*signgamsz*/);
+
+
+float __ieee754_lgammaf_r(float x, int* signgam)
+{
+ return __libm_lgammaf(x, signgam, sizeof(*signgam));
+}
+weak_alias (__ieee754_lgammaf_r, lgammaf_r)
+
+#ifndef _LIBC
+float __ieee754_gammaf_r(float x, int* signgam)
+{
+ return __libm_lgammaf(x, signgam, sizeof(*signgam));
+}
+weak_alias (__ieee754_gammaf_r, gammaf_r)
+#endif
diff --git a/libc/sysdeps/ia64/fpu/e_lgammal_r.c b/libc/sysdeps/ia64/fpu/e_lgammal_r.c
new file mode 100644
index 000000000..4451201b7
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_lgammal_r.c
@@ -0,0 +1,70 @@
+/* file: lgammal_r.c */
+
+
+// Copyright (c) 2002 Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+// History
+//==============================================================
+// 08/15/02: Initial version
+/*
+// FUNCTIONS: long double lgammal_r(long double x, int* signgam)
+// long double gammal_r(long double x, int* signgam)
+// Natural logarithm of GAMMA function
+*/
+
+#include "libm_support.h"
+
+
+extern double __libm_lgammal(long double /*x*/, int* /*signgam*/, int /*signgamsz*/);
+
+
+long double __ieee754_lgammal_r(long double x, int* signgam)
+{
+ return __libm_lgammal(x, signgam, sizeof(*signgam));
+}
+weak_alias (__ieee754_lgammal_r, lgammal_r)
+
+#ifndef _LIBC
+long double __ieee754_gammal_r(long double x, int* signgam)
+{
+ return __libm_lgammal(x, signgam, sizeof(*signgam));
+}
+weak_alias (__ieee754_gammal_r, gammal_r)
+#endif
diff --git a/libc/sysdeps/ia64/fpu/e_log.S b/libc/sysdeps/ia64/fpu/e_log.S
new file mode 100644
index 000000000..c644c6f8f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_log.S
@@ -0,0 +1,1729 @@
+.file "log.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 06/16/00 Updated table to be rounded correctly
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 08/17/00 Improved speed of main path by 5 cycles
+// Shortened path for x=1.0
+// 01/09/01 Improved speed, fixed flags for neg denormals
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 05/23/02 Modified algorithm. Now only one polynomial is used
+// for |x-1| >= 1/256 and for |x-1| < 1/256
+// 12/11/02 Improved performance for Itanium 2
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// double log(double)
+// double log10(double)
+//
+//
+// Overview of operation
+//==============================================================
+// Background
+// ----------
+//
+// This algorithm is based on fact that
+// log(a b) = log(a) + log(b).
+// In our case we have x = 2^N f, where 1 <= f < 2.
+// So
+// log(x) = log(2^N f) = log(2^N) + log(f) = n*log(2) + log(f)
+//
+// To calculate log(f) we do following
+// log(f) = log(f * frcpa(f) / frcpa(f)) =
+// = log(f * frcpa(f)) + log(1/frcpa(f))
+//
+// According to definition of IA-64's frcpa instruction it's a
+// floating point that approximates 1/f using a lookup on the
+// top of 8 bits of the input number's significand with relative
+// error < 2^(-8.886). So we have following
+//
+// |(1/f - frcpa(f)) / (1/f))| = |1 - f*frcpa(f)| < 1/256
+//
+// and
+//
+// log(f) = log(f * frcpa(f)) + log(1/frcpa(f)) =
+// = log(1 + r) + T
+//
+// The first value can be computed by polynomial P(r) approximating
+// log(1 + r) on |r| < 1/256 and the second is precomputed tabular
+// value defined by top 8 bit of f.
+//
+// Finally we have that log(x) ~ (N*log(2) + T) + P(r)
+//
+// Note that if input argument is close to 1.0 (in our case it means
+// that |1 - x| < 1/256) we can use just polynomial approximation
+// because x = 2^0 * f = f = 1 + r and
+// log(x) = log(1 + r) ~ P(r)
+//
+//
+// To compute log10(x) we use the simple identity
+//
+// log10(x) = log(x)/log(10)
+//
+// so we have that
+//
+// log10(x) = (N*log(2) + T + log(1+r)) / log(10) =
+// = N*(log(2)/log(10)) + (T/log(10)) + log(1 + r)/log(10)
+//
+//
+// Implementation
+// --------------
+// It can be seen that formulas for log and log10 differ from one another
+// only by coefficients and tabular values. Namely as log as log10 are
+// calculated as (N*L1 + T) + L2*Series(r) where in case of log
+// L1 = log(2)
+// T = log(1/frcpa(x))
+// L2 = 1.0
+// and in case of log10
+// L1 = log(2)/log(10)
+// T = log(1/frcpa(x))/log(10)
+// L2 = 1.0/log(10)
+//
+// So common code with two different entry points those set pointers
+// to the base address of coresponding data sets containing values
+// of L2,T and prepare integer representation of L1 needed for following
+// setf instruction.
+//
+// Note that both log and log10 use common approximation polynomial
+// it means we need only one set of coefficients of approximation.
+//
+//
+// 1. |x-1| >= 1/256
+// InvX = frcpa(x)
+// r = InvX*x - 1
+// P(r) = r*((r*A3 - A2) + r^4*((A4 + r*A5) + r^2*(A6 + r*A7)),
+// all coefficients are calcutated in quad and rounded to double
+// precision. A7,A6,A5,A4 are stored in memory whereas A3 and A2
+// created with setf.
+//
+// N = float(n) where n is true unbiased exponent of x
+//
+// T is tabular value of log(1/frcpa(x)) calculated in quad precision
+// and represented by two floating-point numbers 64-bit Thi and 32-bit Tlo.
+// To load Thi,Tlo we get bits from 55 to 62 of register format significand
+// as index and calculate two addresses
+// ad_Thi = Thi_table_base_addr + 8 * index
+// ad_Tlo = Tlo_table_base_addr + 4 * index
+//
+// L2 (1.0 or 1.0/log(10) depending on function) is calculated in quad
+// precision and rounded to double extended; it's loaded from memory.
+//
+// L1 (log(2) or log10(2) depending on function) is calculated in quad
+// precision and represented by two floating-point 64-bit numbers L1hi,L1lo
+// stored in memory.
+//
+// And final result = ((L1hi*N + Thi) + (N*L1lo + Tlo)) + L2*P(r)
+//
+//
+// 2. |x-1| < 1/256
+// r = x - 1
+// P(r) = r*((r*A3 - A2) + r^4*((A4 + r*A5) + r^2*(A6 + r*A7)),
+// A7,A6,A5A4,A3,A2 are the same as in case |x-1| >= 1/256
+//
+// And final results
+// log(x) = P(r)
+// log10(x) = L2*P(r)
+//
+// 3. How we define is input argument such that |x-1| < 1/256 or not.
+//
+// To do it we analyze biased exponent and integer representation of
+// input argument
+//
+// a) First we test is biased exponent equal to 0xFFFE or 0xFFFF (i.e.
+// we test is 0.5 <= x < 2). This comparison can be performed using
+// unsigned version of cmp instruction in such a way
+// biased_exponent_of_x - 0xFFFE < 2
+//
+//
+// b) Second (in case when result of a) is true) we need to compare x
+// with 1-1/256 and 1+1/256 or in double precision memory representation
+// with 0x3FEFE00000000000 and 0x3FF0100000000000 correspondingly.
+// This comparison can be made like in a), using unsigned
+// version of cmp i.e. ix - 0x3FEFE00000000000 < 0x0000300000000000.
+// 0x0000300000000000 is difference between 0x3FF0100000000000 and
+// 0x3FEFE00000000000
+//
+// Note: NaT, any NaNs, +/-INF, +/-0, negatives and unnormalized numbers are
+// filtered and processed on special branches.
+//
+
+//
+// Special values
+//==============================================================
+//
+// log(+0) = -inf
+// log(-0) = -inf
+//
+// log(+qnan) = +qnan
+// log(-qnan) = -qnan
+// log(+snan) = +qnan
+// log(-snan) = -qnan
+//
+// log(-n) = QNAN Indefinite
+// log(-inf) = QNAN Indefinite
+//
+// log(+inf) = +inf
+//
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f7 -> f15, f32 -> f42
+//
+// General registers used:
+// r8 -> r11
+// r14 -> r23
+//
+// Predicate registers used:
+// p6 -> p15
+
+// Assembly macros
+//==============================================================
+GR_TAG = r8
+GR_ad_1 = r8
+GR_ad_2 = r9
+GR_Exp = r10
+GR_N = r11
+
+GR_x = r14
+GR_dx = r15
+GR_NearOne = r15
+GR_xorg = r16
+GR_mask = r16
+GR_05 = r17
+GR_A3 = r18
+GR_Sig = r19
+GR_Ind = r19
+GR_Nm1 = r20
+GR_bias = r21
+GR_ad_3 = r22
+GR_rexp = r23
+
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+
+FR_NormX = f7
+FR_RcpX = f9
+FR_tmp = f9
+FR_r = f10
+FR_r2 = f11
+FR_r4 = f12
+FR_N = f13
+FR_Ln2hi = f14
+FR_Ln2lo = f15
+
+FR_A7 = f32
+FR_A6 = f33
+FR_A5 = f34
+FR_A4 = f35
+FR_A3 = f36
+FR_A2 = f37
+
+FR_Thi = f38
+FR_NxLn2hipThi = f38
+FR_NxLn2pT = f38
+FR_Tlo = f39
+FR_NxLn2lopTlo = f39
+
+FR_InvLn10 = f40
+FR_A32 = f41
+FR_A321 = f42
+
+
+FR_Y = f1
+FR_X = f10
+FR_RESULT = f8
+
+
+// Data
+//==============================================================
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(log_data)
+// coefficients of polynomial approximation
+data8 0x3FC2494104381A8E // A7
+data8 0xBFC5556D556BBB69 // A6
+//
+// two parts of ln(2)
+data8 0x3FE62E42FEF00000,0x3DD473DE6AF278ED
+//
+data8 0x8000000000000000,0x3FFF // 1.0
+//
+data8 0x3FC999999988B5E9 // A5
+data8 0xBFCFFFFFFFF6FFF5 // A4
+//
+// hi parts of ln(1/frcpa(1+i/256)), i=0...255
+data8 0x3F60040155D5889D // 0
+data8 0x3F78121214586B54 // 1
+data8 0x3F841929F96832EF // 2
+data8 0x3F8C317384C75F06 // 3
+data8 0x3F91A6B91AC73386 // 4
+data8 0x3F95BA9A5D9AC039 // 5
+data8 0x3F99D2A8074325F3 // 6
+data8 0x3F9D6B2725979802 // 7
+data8 0x3FA0C58FA19DFAA9 // 8
+data8 0x3FA2954C78CBCE1A // 9
+data8 0x3FA4A94D2DA96C56 // 10
+data8 0x3FA67C94F2D4BB58 // 11
+data8 0x3FA85188B630F068 // 12
+data8 0x3FAA6B8ABE73AF4C // 13
+data8 0x3FAC441E06F72A9E // 14
+data8 0x3FAE1E6713606D06 // 15
+data8 0x3FAFFA6911AB9300 // 16
+data8 0x3FB0EC139C5DA600 // 17
+data8 0x3FB1DBD2643D190B // 18
+data8 0x3FB2CC7284FE5F1C // 19
+data8 0x3FB3BDF5A7D1EE64 // 20
+data8 0x3FB4B05D7AA012E0 // 21
+data8 0x3FB580DB7CEB5701 // 22
+data8 0x3FB674F089365A79 // 23
+data8 0x3FB769EF2C6B568D // 24
+data8 0x3FB85FD927506A47 // 25
+data8 0x3FB9335E5D594988 // 26
+data8 0x3FBA2B0220C8E5F4 // 27
+data8 0x3FBB0004AC1A86AB // 28
+data8 0x3FBBF968769FCA10 // 29
+data8 0x3FBCCFEDBFEE13A8 // 30
+data8 0x3FBDA727638446A2 // 31
+data8 0x3FBEA3257FE10F79 // 32
+data8 0x3FBF7BE9FEDBFDE5 // 33
+data8 0x3FC02AB352FF25F3 // 34
+data8 0x3FC097CE579D204C // 35
+data8 0x3FC1178E8227E47B // 36
+data8 0x3FC185747DBECF33 // 37
+data8 0x3FC1F3B925F25D41 // 38
+data8 0x3FC2625D1E6DDF56 // 39
+data8 0x3FC2D1610C868139 // 40
+data8 0x3FC340C59741142E // 41
+data8 0x3FC3B08B6757F2A9 // 42
+data8 0x3FC40DFB08378003 // 43
+data8 0x3FC47E74E8CA5F7C // 44
+data8 0x3FC4EF51F6466DE4 // 45
+data8 0x3FC56092E02BA516 // 46
+data8 0x3FC5D23857CD74D4 // 47
+data8 0x3FC6313A37335D76 // 48
+data8 0x3FC6A399DABBD383 // 49
+data8 0x3FC70337DD3CE41A // 50
+data8 0x3FC77654128F6127 // 51
+data8 0x3FC7E9D82A0B022D // 52
+data8 0x3FC84A6B759F512E // 53
+data8 0x3FC8AB47D5F5A30F // 54
+data8 0x3FC91FE49096581B // 55
+data8 0x3FC981634011AA75 // 56
+data8 0x3FC9F6C407089664 // 57
+data8 0x3FCA58E729348F43 // 58
+data8 0x3FCABB55C31693AC // 59
+data8 0x3FCB1E104919EFD0 // 60
+data8 0x3FCB94EE93E367CA // 61
+data8 0x3FCBF851C067555E // 62
+data8 0x3FCC5C0254BF23A5 // 63
+data8 0x3FCCC000C9DB3C52 // 64
+data8 0x3FCD244D99C85673 // 65
+data8 0x3FCD88E93FB2F450 // 66
+data8 0x3FCDEDD437EAEF00 // 67
+data8 0x3FCE530EFFE71012 // 68
+data8 0x3FCEB89A1648B971 // 69
+data8 0x3FCF1E75FADF9BDE // 70
+data8 0x3FCF84A32EAD7C35 // 71
+data8 0x3FCFEB2233EA07CD // 72
+data8 0x3FD028F9C7035C1C // 73
+data8 0x3FD05C8BE0D9635A // 74
+data8 0x3FD085EB8F8AE797 // 75
+data8 0x3FD0B9C8E32D1911 // 76
+data8 0x3FD0EDD060B78080 // 77
+data8 0x3FD122024CF0063F // 78
+data8 0x3FD14BE2927AECD4 // 79
+data8 0x3FD180618EF18ADF // 80
+data8 0x3FD1B50BBE2FC63B // 81
+data8 0x3FD1DF4CC7CF242D // 82
+data8 0x3FD214456D0EB8D4 // 83
+data8 0x3FD23EC5991EBA49 // 84
+data8 0x3FD2740D9F870AFB // 85
+data8 0x3FD29ECDABCDFA03 // 86
+data8 0x3FD2D46602ADCCEE // 87
+data8 0x3FD2FF66B04EA9D4 // 88
+data8 0x3FD335504B355A37 // 89
+data8 0x3FD360925EC44F5C // 90
+data8 0x3FD38BF1C3337E74 // 91
+data8 0x3FD3C25277333183 // 92
+data8 0x3FD3EDF463C1683E // 93
+data8 0x3FD419B423D5E8C7 // 94
+data8 0x3FD44591E0539F48 // 95
+data8 0x3FD47C9175B6F0AD // 96
+data8 0x3FD4A8B341552B09 // 97
+data8 0x3FD4D4F39089019F // 98
+data8 0x3FD501528DA1F967 // 99
+data8 0x3FD52DD06347D4F6 // 100
+data8 0x3FD55A6D3C7B8A89 // 101
+data8 0x3FD5925D2B112A59 // 102
+data8 0x3FD5BF406B543DB1 // 103
+data8 0x3FD5EC433D5C35AD // 104
+data8 0x3FD61965CDB02C1E // 105
+data8 0x3FD646A84935B2A1 // 106
+data8 0x3FD6740ADD31DE94 // 107
+data8 0x3FD6A18DB74A58C5 // 108
+data8 0x3FD6CF31058670EC // 109
+data8 0x3FD6F180E852F0B9 // 110
+data8 0x3FD71F5D71B894EF // 111
+data8 0x3FD74D5AEFD66D5C // 112
+data8 0x3FD77B79922BD37D // 113
+data8 0x3FD7A9B9889F19E2 // 114
+data8 0x3FD7D81B037EB6A6 // 115
+data8 0x3FD8069E33827230 // 116
+data8 0x3FD82996D3EF8BCA // 117
+data8 0x3FD85855776DCBFA // 118
+data8 0x3FD8873658327CCE // 119
+data8 0x3FD8AA75973AB8CE // 120
+data8 0x3FD8D992DC8824E4 // 121
+data8 0x3FD908D2EA7D9511 // 122
+data8 0x3FD92C59E79C0E56 // 123
+data8 0x3FD95BD750EE3ED2 // 124
+data8 0x3FD98B7811A3EE5B // 125
+data8 0x3FD9AF47F33D406B // 126
+data8 0x3FD9DF270C1914A7 // 127
+data8 0x3FDA0325ED14FDA4 // 128
+data8 0x3FDA33440224FA78 // 129
+data8 0x3FDA57725E80C382 // 130
+data8 0x3FDA87D0165DD199 // 131
+data8 0x3FDAAC2E6C03F895 // 132
+data8 0x3FDADCCC6FDF6A81 // 133
+data8 0x3FDB015B3EB1E790 // 134
+data8 0x3FDB323A3A635948 // 135
+data8 0x3FDB56FA04462909 // 136
+data8 0x3FDB881AA659BC93 // 137
+data8 0x3FDBAD0BEF3DB164 // 138
+data8 0x3FDBD21297781C2F // 139
+data8 0x3FDC039236F08818 // 140
+data8 0x3FDC28CB1E4D32FC // 141
+data8 0x3FDC4E19B84723C1 // 142
+data8 0x3FDC7FF9C74554C9 // 143
+data8 0x3FDCA57B64E9DB05 // 144
+data8 0x3FDCCB130A5CEBAF // 145
+data8 0x3FDCF0C0D18F326F // 146
+data8 0x3FDD232075B5A201 // 147
+data8 0x3FDD490246DEFA6B // 148
+data8 0x3FDD6EFA918D25CD // 149
+data8 0x3FDD9509707AE52F // 150
+data8 0x3FDDBB2EFE92C554 // 151
+data8 0x3FDDEE2F3445E4AE // 152
+data8 0x3FDE148A1A2726CD // 153
+data8 0x3FDE3AFC0A49FF3F // 154
+data8 0x3FDE6185206D516D // 155
+data8 0x3FDE882578823D51 // 156
+data8 0x3FDEAEDD2EAC990C // 157
+data8 0x3FDED5AC5F436BE2 // 158
+data8 0x3FDEFC9326D16AB8 // 159
+data8 0x3FDF2391A21575FF // 160
+data8 0x3FDF4AA7EE03192C // 161
+data8 0x3FDF71D627C30BB0 // 162
+data8 0x3FDF991C6CB3B379 // 163
+data8 0x3FDFC07ADA69A90F // 164
+data8 0x3FDFE7F18EB03D3E // 165
+data8 0x3FE007C053C5002E // 166
+data8 0x3FE01B942198A5A0 // 167
+data8 0x3FE02F74400C64EA // 168
+data8 0x3FE04360BE7603AC // 169
+data8 0x3FE05759AC47FE33 // 170
+data8 0x3FE06B5F1911CF51 // 171
+data8 0x3FE078BF0533C568 // 172
+data8 0x3FE08CD9687E7B0E // 173
+data8 0x3FE0A10074CF9019 // 174
+data8 0x3FE0B5343A234476 // 175
+data8 0x3FE0C974C89431CD // 176
+data8 0x3FE0DDC2305B9886 // 177
+data8 0x3FE0EB524BAFC918 // 178
+data8 0x3FE0FFB54213A475 // 179
+data8 0x3FE114253DA97D9F // 180
+data8 0x3FE128A24F1D9AFF // 181
+data8 0x3FE1365252BF0864 // 182
+data8 0x3FE14AE558B4A92D // 183
+data8 0x3FE15F85A19C765B // 184
+data8 0x3FE16D4D38C119FA // 185
+data8 0x3FE18203C20DD133 // 186
+data8 0x3FE196C7BC4B1F3A // 187
+data8 0x3FE1A4A738B7A33C // 188
+data8 0x3FE1B981C0C9653C // 189
+data8 0x3FE1CE69E8BB106A // 190
+data8 0x3FE1DC619DE06944 // 191
+data8 0x3FE1F160A2AD0DA3 // 192
+data8 0x3FE2066D7740737E // 193
+data8 0x3FE2147DBA47A393 // 194
+data8 0x3FE229A1BC5EBAC3 // 195
+data8 0x3FE237C1841A502E // 196
+data8 0x3FE24CFCE6F80D9A // 197
+data8 0x3FE25B2C55CD5762 // 198
+data8 0x3FE2707F4D5F7C40 // 199
+data8 0x3FE285E0842CA383 // 200
+data8 0x3FE294294708B773 // 201
+data8 0x3FE2A9A2670AFF0C // 202
+data8 0x3FE2B7FB2C8D1CC0 // 203
+data8 0x3FE2C65A6395F5F5 // 204
+data8 0x3FE2DBF557B0DF42 // 205
+data8 0x3FE2EA64C3F97654 // 206
+data8 0x3FE3001823684D73 // 207
+data8 0x3FE30E97E9A8B5CC // 208
+data8 0x3FE32463EBDD34E9 // 209
+data8 0x3FE332F4314AD795 // 210
+data8 0x3FE348D90E7464CF // 211
+data8 0x3FE35779F8C43D6D // 212
+data8 0x3FE36621961A6A99 // 213
+data8 0x3FE37C299F3C366A // 214
+data8 0x3FE38AE2171976E7 // 215
+data8 0x3FE399A157A603E7 // 216
+data8 0x3FE3AFCCFE77B9D1 // 217
+data8 0x3FE3BE9D503533B5 // 218
+data8 0x3FE3CD7480B4A8A2 // 219
+data8 0x3FE3E3C43918F76C // 220
+data8 0x3FE3F2ACB27ED6C6 // 221
+data8 0x3FE4019C2125CA93 // 222
+data8 0x3FE4181061389722 // 223
+data8 0x3FE42711518DF545 // 224
+data8 0x3FE436194E12B6BF // 225
+data8 0x3FE445285D68EA69 // 226
+data8 0x3FE45BCC464C893A // 227
+data8 0x3FE46AED21F117FC // 228
+data8 0x3FE47A1527E8A2D3 // 229
+data8 0x3FE489445EFFFCCB // 230
+data8 0x3FE4A018BCB69835 // 231
+data8 0x3FE4AF5A0C9D65D7 // 232
+data8 0x3FE4BEA2A5BDBE87 // 233
+data8 0x3FE4CDF28F10AC46 // 234
+data8 0x3FE4DD49CF994058 // 235
+data8 0x3FE4ECA86E64A683 // 236
+data8 0x3FE503C43CD8EB68 // 237
+data8 0x3FE513356667FC57 // 238
+data8 0x3FE522AE0738A3D7 // 239
+data8 0x3FE5322E26867857 // 240
+data8 0x3FE541B5CB979809 // 241
+data8 0x3FE55144FDBCBD62 // 242
+data8 0x3FE560DBC45153C6 // 243
+data8 0x3FE5707A26BB8C66 // 244
+data8 0x3FE587F60ED5B8FF // 245
+data8 0x3FE597A7977C8F31 // 246
+data8 0x3FE5A760D634BB8A // 247
+data8 0x3FE5B721D295F10E // 248
+data8 0x3FE5C6EA94431EF9 // 249
+data8 0x3FE5D6BB22EA86F5 // 250
+data8 0x3FE5E6938645D38F // 251
+data8 0x3FE5F673C61A2ED1 // 252
+data8 0x3FE6065BEA385926 // 253
+data8 0x3FE6164BFA7CC06B // 254
+data8 0x3FE62643FECF9742 // 255
+//
+// lo parts of ln(1/frcpa(1+i/256)), i=0...255
+data4 0x20E70672 // 0
+data4 0x1F60A5D0 // 1
+data4 0x218EABA0 // 2
+data4 0x21403104 // 3
+data4 0x20E9B54E // 4
+data4 0x21EE1382 // 5
+data4 0x226014E3 // 6
+data4 0x2095E5C9 // 7
+data4 0x228BA9D4 // 8
+data4 0x22932B86 // 9
+data4 0x22608A57 // 10
+data4 0x220209F3 // 11
+data4 0x212882CC // 12
+data4 0x220D46E2 // 13
+data4 0x21FA4C28 // 14
+data4 0x229E5BD9 // 15
+data4 0x228C9838 // 16
+data4 0x2311F954 // 17
+data4 0x221365DF // 18
+data4 0x22BD0CB3 // 19
+data4 0x223D4BB7 // 20
+data4 0x22A71BBE // 21
+data4 0x237DB2FA // 22
+data4 0x23194C9D // 23
+data4 0x22EC639E // 24
+data4 0x2367E669 // 25
+data4 0x232E1D5F // 26
+data4 0x234A639B // 27
+data4 0x2365C0E0 // 28
+data4 0x234646C1 // 29
+data4 0x220CBF9C // 30
+data4 0x22A00FD4 // 31
+data4 0x2306A3F2 // 32
+data4 0x23745A9B // 33
+data4 0x2398D756 // 34
+data4 0x23DD0B6A // 35
+data4 0x23DE338B // 36
+data4 0x23A222DF // 37
+data4 0x223164F8 // 38
+data4 0x23B4E87B // 39
+data4 0x23D6CCB8 // 40
+data4 0x220C2099 // 41
+data4 0x21B86B67 // 42
+data4 0x236D14F1 // 43
+data4 0x225A923F // 44
+data4 0x22748723 // 45
+data4 0x22200D13 // 46
+data4 0x23C296EA // 47
+data4 0x2302AC38 // 48
+data4 0x234B1996 // 49
+data4 0x2385E298 // 50
+data4 0x23175BE5 // 51
+data4 0x2193F482 // 52
+data4 0x23BFEA90 // 53
+data4 0x23D70A0C // 54
+data4 0x231CF30A // 55
+data4 0x235D9E90 // 56
+data4 0x221AD0CB // 57
+data4 0x22FAA08B // 58
+data4 0x23D29A87 // 59
+data4 0x20C4B2FE // 60
+data4 0x2381B8B7 // 61
+data4 0x23F8D9FC // 62
+data4 0x23EAAE7B // 63
+data4 0x2329E8AA // 64
+data4 0x23EC0322 // 65
+data4 0x2357FDCB // 66
+data4 0x2392A9AD // 67
+data4 0x22113B02 // 68
+data4 0x22DEE901 // 69
+data4 0x236A6D14 // 70
+data4 0x2371D33E // 71
+data4 0x2146F005 // 72
+data4 0x23230B06 // 73
+data4 0x22F1C77D // 74
+data4 0x23A89FA3 // 75
+data4 0x231D1241 // 76
+data4 0x244DA96C // 77
+data4 0x23ECBB7D // 78
+data4 0x223E42B4 // 79
+data4 0x23801BC9 // 80
+data4 0x23573263 // 81
+data4 0x227C1158 // 82
+data4 0x237BD749 // 83
+data4 0x21DDBAE9 // 84
+data4 0x23401735 // 85
+data4 0x241D9DEE // 86
+data4 0x23BC88CB // 87
+data4 0x2396D5F1 // 88
+data4 0x23FC89CF // 89
+data4 0x2414F9A2 // 90
+data4 0x2474A0F5 // 91
+data4 0x24354B60 // 92
+data4 0x23C1EB40 // 93
+data4 0x2306DD92 // 94
+data4 0x24353B6B // 95
+data4 0x23CD1701 // 96
+data4 0x237C7A1C // 97
+data4 0x245793AA // 98
+data4 0x24563695 // 99
+data4 0x23C51467 // 100
+data4 0x24476B68 // 101
+data4 0x212585A9 // 102
+data4 0x247B8293 // 103
+data4 0x2446848A // 104
+data4 0x246A53F8 // 105
+data4 0x246E496D // 106
+data4 0x23ED1D36 // 107
+data4 0x2314C258 // 108
+data4 0x233244A7 // 109
+data4 0x245B7AF0 // 110
+data4 0x24247130 // 111
+data4 0x22D67B38 // 112
+data4 0x2449F620 // 113
+data4 0x23BBC8B8 // 114
+data4 0x237D3BA0 // 115
+data4 0x245E8F13 // 116
+data4 0x2435573F // 117
+data4 0x242DE666 // 118
+data4 0x2463BC10 // 119
+data4 0x2466587D // 120
+data4 0x2408144B // 121
+data4 0x2405F0E5 // 122
+data4 0x22381CFF // 123
+data4 0x24154F9B // 124
+data4 0x23A4E96E // 125
+data4 0x24052967 // 126
+data4 0x2406963F // 127
+data4 0x23F7D3CB // 128
+data4 0x2448AFF4 // 129
+data4 0x24657A21 // 130
+data4 0x22FBC230 // 131
+data4 0x243C8DEA // 132
+data4 0x225DC4B7 // 133
+data4 0x23496EBF // 134
+data4 0x237C2B2B // 135
+data4 0x23A4A5B1 // 136
+data4 0x2394E9D1 // 137
+data4 0x244BC950 // 138
+data4 0x23C7448F // 139
+data4 0x2404A1AD // 140
+data4 0x246511D5 // 141
+data4 0x24246526 // 142
+data4 0x23111F57 // 143
+data4 0x22868951 // 144
+data4 0x243EB77F // 145
+data4 0x239F3DFF // 146
+data4 0x23089666 // 147
+data4 0x23EBFA6A // 148
+data4 0x23C51312 // 149
+data4 0x23E1DD5E // 150
+data4 0x232C0944 // 151
+data4 0x246A741F // 152
+data4 0x2414DF8D // 153
+data4 0x247B5546 // 154
+data4 0x2415C980 // 155
+data4 0x24324ABD // 156
+data4 0x234EB5E5 // 157
+data4 0x2465E43E // 158
+data4 0x242840D1 // 159
+data4 0x24444057 // 160
+data4 0x245E56F0 // 161
+data4 0x21AE30F8 // 162
+data4 0x23FB3283 // 163
+data4 0x247A4D07 // 164
+data4 0x22AE314D // 165
+data4 0x246B7727 // 166
+data4 0x24EAD526 // 167
+data4 0x24B41DC9 // 168
+data4 0x24EE8062 // 169
+data4 0x24A0C7C4 // 170
+data4 0x24E8DA67 // 171
+data4 0x231120F7 // 172
+data4 0x24401FFB // 173
+data4 0x2412DD09 // 174
+data4 0x248C131A // 175
+data4 0x24C0A7CE // 176
+data4 0x243DD4C8 // 177
+data4 0x24457FEB // 178
+data4 0x24DEEFBB // 179
+data4 0x243C70AE // 180
+data4 0x23E7A6FA // 181
+data4 0x24C2D311 // 182
+data4 0x23026255 // 183
+data4 0x2437C9B9 // 184
+data4 0x246BA847 // 185
+data4 0x2420B448 // 186
+data4 0x24C4CF5A // 187
+data4 0x242C4981 // 188
+data4 0x24DE1525 // 189
+data4 0x24F5CC33 // 190
+data4 0x235A85DA // 191
+data4 0x24A0B64F // 192
+data4 0x244BA0A4 // 193
+data4 0x24AAF30A // 194
+data4 0x244C86F9 // 195
+data4 0x246D5B82 // 196
+data4 0x24529347 // 197
+data4 0x240DD008 // 198
+data4 0x24E98790 // 199
+data4 0x2489B0CE // 200
+data4 0x22BC29AC // 201
+data4 0x23F37C7A // 202
+data4 0x24987FE8 // 203
+data4 0x22AFE20B // 204
+data4 0x24C8D7C2 // 205
+data4 0x24B28B7D // 206
+data4 0x23B6B271 // 207
+data4 0x24C77CB6 // 208
+data4 0x24EF1DCA // 209
+data4 0x24A4F0AC // 210
+data4 0x24CF113E // 211
+data4 0x2496BBAB // 212
+data4 0x23C7CC8A // 213
+data4 0x23AE3961 // 214
+data4 0x2410A895 // 215
+data4 0x23CE3114 // 216
+data4 0x2308247D // 217
+data4 0x240045E9 // 218
+data4 0x24974F60 // 219
+data4 0x242CB39F // 220
+data4 0x24AB8D69 // 221
+data4 0x23436788 // 222
+data4 0x24305E9E // 223
+data4 0x243E71A9 // 224
+data4 0x23C2A6B3 // 225
+data4 0x23FFE6CF // 226
+data4 0x2322D801 // 227
+data4 0x24515F21 // 228
+data4 0x2412A0D6 // 229
+data4 0x24E60D44 // 230
+data4 0x240D9251 // 231
+data4 0x247076E2 // 232
+data4 0x229B101B // 233
+data4 0x247B12DE // 234
+data4 0x244B9127 // 235
+data4 0x2499EC42 // 236
+data4 0x21FC3963 // 237
+data4 0x23E53266 // 238
+data4 0x24CE102D // 239
+data4 0x23CC45D2 // 240
+data4 0x2333171D // 241
+data4 0x246B3533 // 242
+data4 0x24931129 // 243
+data4 0x24405FFA // 244
+data4 0x24CF464D // 245
+data4 0x237095CD // 246
+data4 0x24F86CBD // 247
+data4 0x24E2D84B // 248
+data4 0x21ACBB44 // 249
+data4 0x24F43A8C // 250
+data4 0x249DB931 // 251
+data4 0x24A385EF // 252
+data4 0x238B1279 // 253
+data4 0x2436213E // 254
+data4 0x24F18A3B // 255
+LOCAL_OBJECT_END(log_data)
+
+
+LOCAL_OBJECT_START(log10_data)
+// coefficients of polynoimal approximation
+data8 0x3FC2494104381A8E // A7
+data8 0xBFC5556D556BBB69 // A6
+//
+// two parts of ln(2)/ln(10)
+data8 0x3FD3441350900000, 0x3DCEF3FDE623E256
+//
+data8 0xDE5BD8A937287195,0x3FFD // 1/ln(10)
+//
+data8 0x3FC999999988B5E9 // A5
+data8 0xBFCFFFFFFFF6FFF5 // A4
+//
+// Hi parts of ln(1/frcpa(1+i/256))/ln(10), i=0...255
+data8 0x3F4BD27045BFD024 // 0
+data8 0x3F64E84E793A474A // 1
+data8 0x3F7175085AB85FF0 // 2
+data8 0x3F787CFF9D9147A5 // 3
+data8 0x3F7EA9D372B89FC8 // 4
+data8 0x3F82DF9D95DA961C // 5
+data8 0x3F866DF172D6372B // 6
+data8 0x3F898D79EF5EEDEF // 7
+data8 0x3F8D22ADF3F9579C // 8
+data8 0x3F9024231D30C398 // 9
+data8 0x3F91F23A98897D49 // 10
+data8 0x3F93881A7B818F9E // 11
+data8 0x3F951F6E1E759E35 // 12
+data8 0x3F96F2BCE7ADC5B4 // 13
+data8 0x3F988D362CDF359E // 14
+data8 0x3F9A292BAF010981 // 15
+data8 0x3F9BC6A03117EB97 // 16
+data8 0x3F9D65967DE3AB08 // 17
+data8 0x3F9F061167FC31E7 // 18
+data8 0x3FA05409E4F7819B // 19
+data8 0x3FA125D0432EA20D // 20
+data8 0x3FA1F85D440D299B // 21
+data8 0x3FA2AD755749617C // 22
+data8 0x3FA381772A00E603 // 23
+data8 0x3FA45643E165A70A // 24
+data8 0x3FA52BDD034475B8 // 25
+data8 0x3FA5E3966B7E9295 // 26
+data8 0x3FA6BAAF47C5B244 // 27
+data8 0x3FA773B3E8C4F3C7 // 28
+data8 0x3FA84C51EBEE8D15 // 29
+data8 0x3FA906A6786FC1CA // 30
+data8 0x3FA9C197ABF00DD6 // 31
+data8 0x3FAA9C78712191F7 // 32
+data8 0x3FAB58C09C8D637C // 33
+data8 0x3FAC15A8BCDD7B7E // 34
+data8 0x3FACD331E2C2967B // 35
+data8 0x3FADB11ED766ABF4 // 36
+data8 0x3FAE70089346A9E6 // 37
+data8 0x3FAF2F96C6754AED // 38
+data8 0x3FAFEFCA8D451FD5 // 39
+data8 0x3FB0585283764177 // 40
+data8 0x3FB0B913AAC7D3A6 // 41
+data8 0x3FB11A294F2569F5 // 42
+data8 0x3FB16B51A2696890 // 43
+data8 0x3FB1CD03ADACC8BD // 44
+data8 0x3FB22F0BDD7745F5 // 45
+data8 0x3FB2916ACA38D1E7 // 46
+data8 0x3FB2F4210DF7663C // 47
+data8 0x3FB346A6C3C49065 // 48
+data8 0x3FB3A9FEBC605409 // 49
+data8 0x3FB3FD0C10A3AA54 // 50
+data8 0x3FB46107D3540A81 // 51
+data8 0x3FB4C55DD16967FE // 52
+data8 0x3FB51940330C000A // 53
+data8 0x3FB56D620EE7115E // 54
+data8 0x3FB5D2ABCF26178D // 55
+data8 0x3FB6275AA5DEBF81 // 56
+data8 0x3FB68D4EAF26D7EE // 57
+data8 0x3FB6E28C5C54A28D // 58
+data8 0x3FB7380B9665B7C7 // 59
+data8 0x3FB78DCCC278E85B // 60
+data8 0x3FB7F50C2CF25579 // 61
+data8 0x3FB84B5FD5EAEFD7 // 62
+data8 0x3FB8A1F6BAB2B226 // 63
+data8 0x3FB8F8D144557BDF // 64
+data8 0x3FB94FEFDCD61D92 // 65
+data8 0x3FB9A752EF316149 // 66
+data8 0x3FB9FEFAE7611EDF // 67
+data8 0x3FBA56E8325F5C86 // 68
+data8 0x3FBAAF1B3E297BB3 // 69
+data8 0x3FBB079479C372AC // 70
+data8 0x3FBB6054553B12F7 // 71
+data8 0x3FBBB95B41AB5CE5 // 72
+data8 0x3FBC12A9B13FE079 // 73
+data8 0x3FBC6C4017382BEA // 74
+data8 0x3FBCB41FBA42686C // 75
+data8 0x3FBD0E38CE73393E // 76
+data8 0x3FBD689B2193F132 // 77
+data8 0x3FBDC3472B1D285F // 78
+data8 0x3FBE0C06300D528B // 79
+data8 0x3FBE6738190E394B // 80
+data8 0x3FBEC2B50D208D9A // 81
+data8 0x3FBF0C1C2B936827 // 82
+data8 0x3FBF68216C9CC726 // 83
+data8 0x3FBFB1F6381856F3 // 84
+data8 0x3FC00742AF4CE5F8 // 85
+data8 0x3FC02C64906512D2 // 86
+data8 0x3FC05AF1E63E03B4 // 87
+data8 0x3FC0804BEA723AA8 // 88
+data8 0x3FC0AF1FD6711526 // 89
+data8 0x3FC0D4B2A88059FF // 90
+data8 0x3FC0FA5EF136A06C // 91
+data8 0x3FC1299A4FB3E305 // 92
+data8 0x3FC14F806253C3EC // 93
+data8 0x3FC175805D1587C1 // 94
+data8 0x3FC19B9A637CA294 // 95
+data8 0x3FC1CB5FC26EDE16 // 96
+data8 0x3FC1F1B4E65F2590 // 97
+data8 0x3FC218248B5DC3E5 // 98
+data8 0x3FC23EAED62ADC76 // 99
+data8 0x3FC26553EBD337BC // 100
+data8 0x3FC28C13F1B118FF // 101
+data8 0x3FC2BCAA14381385 // 102
+data8 0x3FC2E3A740B7800E // 103
+data8 0x3FC30ABFD8F333B6 // 104
+data8 0x3FC331F403985096 // 105
+data8 0x3FC35943E7A6068F // 106
+data8 0x3FC380AFAC6E7C07 // 107
+data8 0x3FC3A8377997B9E5 // 108
+data8 0x3FC3CFDB771C9ADB // 109
+data8 0x3FC3EDA90D39A5DE // 110
+data8 0x3FC4157EC09505CC // 111
+data8 0x3FC43D7113FB04C0 // 112
+data8 0x3FC4658030AD1CCE // 113
+data8 0x3FC48DAC404638F5 // 114
+data8 0x3FC4B5F56CBBB869 // 115
+data8 0x3FC4DE5BE05E7582 // 116
+data8 0x3FC4FCBC0776FD85 // 117
+data8 0x3FC525561E9256EE // 118
+data8 0x3FC54E0DF3198865 // 119
+data8 0x3FC56CAB7112BDE2 // 120
+data8 0x3FC59597BA735B15 // 121
+data8 0x3FC5BEA23A506FD9 // 122
+data8 0x3FC5DD7E08DE382E // 123
+data8 0x3FC606BDD3F92355 // 124
+data8 0x3FC6301C518A501E // 125
+data8 0x3FC64F3770618915 // 126
+data8 0x3FC678CC14C1E2D7 // 127
+data8 0x3FC6981005ED2947 // 128
+data8 0x3FC6C1DB5F9BB335 // 129
+data8 0x3FC6E1488ECD2880 // 130
+data8 0x3FC70B4B2E7E41B8 // 131
+data8 0x3FC72AE209146BF8 // 132
+data8 0x3FC7551C81BD8DCF // 133
+data8 0x3FC774DD76CC43BD // 134
+data8 0x3FC79F505DB00E88 // 135
+data8 0x3FC7BF3BDE099F30 // 136
+data8 0x3FC7E9E7CAC437F8 // 137
+data8 0x3FC809FE4902D00D // 138
+data8 0x3FC82A2757995CBD // 139
+data8 0x3FC85525C625E098 // 140
+data8 0x3FC8757A79831887 // 141
+data8 0x3FC895E2058D8E02 // 142
+data8 0x3FC8C13437695531 // 143
+data8 0x3FC8E1C812EF32BE // 144
+data8 0x3FC9026F112197E8 // 145
+data8 0x3FC923294888880A // 146
+data8 0x3FC94EEA4B8334F2 // 147
+data8 0x3FC96FD1B639FC09 // 148
+data8 0x3FC990CCA66229AB // 149
+data8 0x3FC9B1DB33334842 // 150
+data8 0x3FC9D2FD740E6606 // 151
+data8 0x3FC9FF49EEDCB553 // 152
+data8 0x3FCA209A84FBCFF7 // 153
+data8 0x3FCA41FF1E43F02B // 154
+data8 0x3FCA6377D2CE9377 // 155
+data8 0x3FCA8504BAE0D9F5 // 156
+data8 0x3FCAA6A5EEEBEFE2 // 157
+data8 0x3FCAC85B878D7878 // 158
+data8 0x3FCAEA259D8FFA0B // 159
+data8 0x3FCB0C0449EB4B6A // 160
+data8 0x3FCB2DF7A5C50299 // 161
+data8 0x3FCB4FFFCA70E4D1 // 162
+data8 0x3FCB721CD17157E2 // 163
+data8 0x3FCB944ED477D4EC // 164
+data8 0x3FCBB695ED655C7C // 165
+data8 0x3FCBD8F2364AEC0F // 166
+data8 0x3FCBFB63C969F4FF // 167
+data8 0x3FCC1DEAC134D4E9 // 168
+data8 0x3FCC4087384F4F80 // 169
+data8 0x3FCC6339498F09E1 // 170
+data8 0x3FCC86010FFC076B // 171
+data8 0x3FCC9D3D065C5B41 // 172
+data8 0x3FCCC029375BA079 // 173
+data8 0x3FCCE32B66978BA4 // 174
+data8 0x3FCD0643AFD51404 // 175
+data8 0x3FCD29722F0DEA45 // 176
+data8 0x3FCD4CB70070FE43 // 177
+data8 0x3FCD6446AB3F8C95 // 178
+data8 0x3FCD87B0EF71DB44 // 179
+data8 0x3FCDAB31D1FE99A6 // 180
+data8 0x3FCDCEC96FDC888E // 181
+data8 0x3FCDE69088763579 // 182
+data8 0x3FCE0A4E4A25C1FF // 183
+data8 0x3FCE2E2315755E32 // 184
+data8 0x3FCE461322D1648A // 185
+data8 0x3FCE6A0E95C7787B // 186
+data8 0x3FCE8E216243DD60 // 187
+data8 0x3FCEA63AF26E007C // 188
+data8 0x3FCECA74ED15E0B7 // 189
+data8 0x3FCEEEC692CCD259 // 190
+data8 0x3FCF070A36B8D9C0 // 191
+data8 0x3FCF2B8393E34A2D // 192
+data8 0x3FCF5014EF538A5A // 193
+data8 0x3FCF68833AF1B17F // 194
+data8 0x3FCF8D3CD9F3F04E // 195
+data8 0x3FCFA5C61ADD93E9 // 196
+data8 0x3FCFCAA8567EBA79 // 197
+data8 0x3FCFE34CC8743DD8 // 198
+data8 0x3FD0042BFD74F519 // 199
+data8 0x3FD016BDF6A18017 // 200
+data8 0x3FD023262F907322 // 201
+data8 0x3FD035CCED8D32A1 // 202
+data8 0x3FD042430E869FFB // 203
+data8 0x3FD04EBEC842B2DF // 204
+data8 0x3FD06182E84FD4AB // 205
+data8 0x3FD06E0CB609D383 // 206
+data8 0x3FD080E60BEC8F12 // 207
+data8 0x3FD08D7E0D894735 // 208
+data8 0x3FD0A06CC96A2055 // 209
+data8 0x3FD0AD131F3B3C55 // 210
+data8 0x3FD0C01771E775FB // 211
+data8 0x3FD0CCCC3CAD6F4B // 212
+data8 0x3FD0D986D91A34A8 // 213
+data8 0x3FD0ECA9B8861A2D // 214
+data8 0x3FD0F972F87FF3D5 // 215
+data8 0x3FD106421CF0E5F7 // 216
+data8 0x3FD11983EBE28A9C // 217
+data8 0x3FD12661E35B7859 // 218
+data8 0x3FD13345D2779D3B // 219
+data8 0x3FD146A6F597283A // 220
+data8 0x3FD15399E81EA83D // 221
+data8 0x3FD16092E5D3A9A6 // 222
+data8 0x3FD17413C3B7AB5D // 223
+data8 0x3FD1811BF629D6FA // 224
+data8 0x3FD18E2A47B46685 // 225
+data8 0x3FD19B3EBE1A4418 // 226
+data8 0x3FD1AEE9017CB450 // 227
+data8 0x3FD1BC0CED7134E1 // 228
+data8 0x3FD1C93712ABC7FF // 229
+data8 0x3FD1D66777147D3E // 230
+data8 0x3FD1EA3BD1286E1C // 231
+data8 0x3FD1F77BED932C4C // 232
+data8 0x3FD204C25E1B031F // 233
+data8 0x3FD2120F28CE69B1 // 234
+data8 0x3FD21F6253C48D00 // 235
+data8 0x3FD22CBBE51D60A9 // 236
+data8 0x3FD240CE4C975444 // 237
+data8 0x3FD24E37F8ECDAE7 // 238
+data8 0x3FD25BA8215AF7FC // 239
+data8 0x3FD2691ECC29F042 // 240
+data8 0x3FD2769BFFAB2DFF // 241
+data8 0x3FD2841FC23952C9 // 242
+data8 0x3FD291AA1A384978 // 243
+data8 0x3FD29F3B0E15584A // 244
+data8 0x3FD2B3A0EE479DF7 // 245
+data8 0x3FD2C142842C09E5 // 246
+data8 0x3FD2CEEACCB7BD6C // 247
+data8 0x3FD2DC99CE82FF20 // 248
+data8 0x3FD2EA4F902FD7D9 // 249
+data8 0x3FD2F80C186A25FC // 250
+data8 0x3FD305CF6DE7B0F6 // 251
+data8 0x3FD3139997683CE7 // 252
+data8 0x3FD3216A9BB59E7C // 253
+data8 0x3FD32F4281A3CEFE // 254
+data8 0x3FD33D2150110091 // 255
+//
+// Lo parts of ln(1/frcpa(1+i/256))/ln(10), i=0...255
+data4 0x1FB0EB5A // 0
+data4 0x206E5EE3 // 1
+data4 0x208F3609 // 2
+data4 0x2070EB03 // 3
+data4 0x1F314BAE // 4
+data4 0x217A889D // 5
+data4 0x21E63650 // 6
+data4 0x21C2F4A3 // 7
+data4 0x2192A10C // 8
+data4 0x1F84B73E // 9
+data4 0x2243FBCA // 10
+data4 0x21BD9C51 // 11
+data4 0x213C542B // 12
+data4 0x21047386 // 13
+data4 0x21217D8F // 14
+data4 0x226791B7 // 15
+data4 0x204CCE66 // 16
+data4 0x2234CE9F // 17
+data4 0x220675E2 // 18
+data4 0x22B8E5BA // 19
+data4 0x22C12D14 // 20
+data4 0x211D41F0 // 21
+data4 0x228507F3 // 22
+data4 0x22F7274B // 23
+data4 0x22A7FDD1 // 24
+data4 0x2244A06E // 25
+data4 0x215DCE69 // 26
+data4 0x22F5C961 // 27
+data4 0x22EBEF29 // 28
+data4 0x222A2CB6 // 29
+data4 0x22B9FE00 // 30
+data4 0x22E79EB7 // 31
+data4 0x222F9607 // 32
+data4 0x2189D87F // 33
+data4 0x2236DB45 // 34
+data4 0x22ED77FB // 35
+data4 0x21CB70F0 // 36
+data4 0x21B8ACE8 // 37
+data4 0x22EC58C1 // 38
+data4 0x22CFCC1C // 39
+data4 0x2343E77A // 40
+data4 0x237FBC7F // 41
+data4 0x230D472E // 42
+data4 0x234686FB // 43
+data4 0x23770425 // 44
+data4 0x223977EC // 45
+data4 0x2345800A // 46
+data4 0x237BC351 // 47
+data4 0x23191502 // 48
+data4 0x232BAC12 // 49
+data4 0x22692421 // 50
+data4 0x234D409D // 51
+data4 0x22EC3214 // 52
+data4 0x2376C916 // 53
+data4 0x22B00DD1 // 54
+data4 0x2309D910 // 55
+data4 0x22F925FD // 56
+data4 0x22A63A7B // 57
+data4 0x2106264A // 58
+data4 0x234227F9 // 59
+data4 0x1ECB1978 // 60
+data4 0x23460A62 // 61
+data4 0x232ED4B1 // 62
+data4 0x226DDC38 // 63
+data4 0x1F101A73 // 64
+data4 0x21B1F82B // 65
+data4 0x22752F19 // 66
+data4 0x2320BC15 // 67
+data4 0x236EEC5E // 68
+data4 0x23404D3E // 69
+data4 0x2304C517 // 70
+data4 0x22F7441A // 71
+data4 0x230D3D7A // 72
+data4 0x2264A9DF // 73
+data4 0x22410CC8 // 74
+data4 0x2342CCCB // 75
+data4 0x23560BD4 // 76
+data4 0x237BBFFE // 77
+data4 0x2373A206 // 78
+data4 0x22C871B9 // 79
+data4 0x2354B70C // 80
+data4 0x232EDB33 // 81
+data4 0x235DB680 // 82
+data4 0x230EF422 // 83
+data4 0x235316CA // 84
+data4 0x22EEEE8B // 85
+data4 0x2375C88C // 86
+data4 0x235ABD21 // 87
+data4 0x23A0D232 // 88
+data4 0x23F5FFB5 // 89
+data4 0x23D3CEC8 // 90
+data4 0x22A92204 // 91
+data4 0x238C64DF // 92
+data4 0x23B82896 // 93
+data4 0x22D633B8 // 94
+data4 0x23861E93 // 95
+data4 0x23CB594B // 96
+data4 0x2330387E // 97
+data4 0x21CD4702 // 98
+data4 0x2284C505 // 99
+data4 0x23D6995C // 100
+data4 0x23F6C807 // 101
+data4 0x239CEF5C // 102
+data4 0x239442B0 // 103
+data4 0x22B35EE5 // 104
+data4 0x2391E9A4 // 105
+data4 0x23A390F5 // 106
+data4 0x2349AC9C // 107
+data4 0x23FA5535 // 108
+data4 0x21E3A46A // 109
+data4 0x23B44ABA // 110
+data4 0x23CEA8E0 // 111
+data4 0x23F647DC // 112
+data4 0x2390D1A8 // 113
+data4 0x23D0CFA2 // 114
+data4 0x236E0872 // 115
+data4 0x23B88B91 // 116
+data4 0x2283C359 // 117
+data4 0x232F647F // 118
+data4 0x23122CD7 // 119
+data4 0x232CF564 // 120
+data4 0x232630FD // 121
+data4 0x23BEE1C8 // 122
+data4 0x23B2BD30 // 123
+data4 0x2301F1C0 // 124
+data4 0x23CE4D67 // 125
+data4 0x23A353C9 // 126
+data4 0x238086E8 // 127
+data4 0x22D0D29E // 128
+data4 0x23A3B3C8 // 129
+data4 0x23F69F4B // 130
+data4 0x23EA3C21 // 131
+data4 0x23951C88 // 132
+data4 0x2372AFFC // 133
+data4 0x23A6D1A8 // 134
+data4 0x22BBBAF4 // 135
+data4 0x227FA3DD // 136
+data4 0x23804D9B // 137
+data4 0x232D771F // 138
+data4 0x239CB57B // 139
+data4 0x2303CF34 // 140
+data4 0x22218C2A // 141
+data4 0x23991BEE // 142
+data4 0x23EB3596 // 143
+data4 0x230487FA // 144
+data4 0x2135DF4C // 145
+data4 0x2380FD2D // 146
+data4 0x23EB75E9 // 147
+data4 0x211C62C8 // 148
+data4 0x23F518F1 // 149
+data4 0x23FEF882 // 150
+data4 0x239097C7 // 151
+data4 0x223E2BDA // 152
+data4 0x23988F89 // 153
+data4 0x22E4A4AD // 154
+data4 0x23F03D9C // 155
+data4 0x23F5018F // 156
+data4 0x23E1E250 // 157
+data4 0x23FD3D90 // 158
+data4 0x22DEE2FF // 159
+data4 0x238342AB // 160
+data4 0x22E6736F // 161
+data4 0x233AFC28 // 162
+data4 0x2395F661 // 163
+data4 0x23D8B991 // 164
+data4 0x23CD58D5 // 165
+data4 0x21941FD6 // 166
+data4 0x23352915 // 167
+data4 0x235D09EE // 168
+data4 0x22DC7EF9 // 169
+data4 0x238BC9F3 // 170
+data4 0x2397DF8F // 171
+data4 0x2380A7BB // 172
+data4 0x23EFF48C // 173
+data4 0x21E67408 // 174
+data4 0x236420F7 // 175
+data4 0x22C8DFB5 // 176
+data4 0x239B5D35 // 177
+data4 0x23BDC09D // 178
+data4 0x239E822C // 179
+data4 0x23984F0A // 180
+data4 0x23EF2119 // 181
+data4 0x23F738B8 // 182
+data4 0x23B66187 // 183
+data4 0x23B06AD7 // 184
+data4 0x2369140F // 185
+data4 0x218DACE6 // 186
+data4 0x21DF23F1 // 187
+data4 0x235D8B34 // 188
+data4 0x23460333 // 189
+data4 0x23F11D62 // 190
+data4 0x23C37147 // 191
+data4 0x22B2AE2A // 192
+data4 0x23949211 // 193
+data4 0x23B69799 // 194
+data4 0x23DBEC75 // 195
+data4 0x229A6FB3 // 196
+data4 0x23FC6C60 // 197
+data4 0x22D01FFC // 198
+data4 0x235985F0 // 199
+data4 0x23F7ECA5 // 200
+data4 0x23F924D3 // 201
+data4 0x2381B92F // 202
+data4 0x243A0FBE // 203
+data4 0x24712D72 // 204
+data4 0x24594E2F // 205
+data4 0x220CD12A // 206
+data4 0x23D87FB0 // 207
+data4 0x2338288A // 208
+data4 0x242BB2CC // 209
+data4 0x220F6265 // 210
+data4 0x23BB7FE3 // 211
+data4 0x2301C0A2 // 212
+data4 0x246709AB // 213
+data4 0x23A619E2 // 214
+data4 0x24030E3B // 215
+data4 0x233C36CC // 216
+data4 0x241AAB77 // 217
+data4 0x243D41A3 // 218
+data4 0x23834A60 // 219
+data4 0x236AC7BF // 220
+data4 0x23B6D597 // 221
+data4 0x210E9474 // 222
+data4 0x242156E6 // 223
+data4 0x243A1D68 // 224
+data4 0x2472187C // 225
+data4 0x23834E86 // 226
+data4 0x23CA0807 // 227
+data4 0x24745887 // 228
+data4 0x23E2B0E1 // 229
+data4 0x2421EB67 // 230
+data4 0x23DCC64E // 231
+data4 0x22DF71D1 // 232
+data4 0x238D5ECA // 233
+data4 0x23CDE86F // 234
+data4 0x24131F45 // 235
+data4 0x240FE4E2 // 236
+data4 0x2317731A // 237
+data4 0x24015C76 // 238
+data4 0x2301A4E8 // 239
+data4 0x23E52A6D // 240
+data4 0x247D8A0D // 241
+data4 0x23DFEEBA // 242
+data4 0x22139FEC // 243
+data4 0x2454A112 // 244
+data4 0x23C21E28 // 245
+data4 0x2460D813 // 246
+data4 0x24258924 // 247
+data4 0x2425680F // 248
+data4 0x24194D1E // 249
+data4 0x24242C2F // 250
+data4 0x243DDE5E // 251
+data4 0x23DEB388 // 252
+data4 0x23E0E6EB // 253
+data4 0x24393E74 // 254
+data4 0x241B1863 // 255
+LOCAL_OBJECT_END(log10_data)
+
+
+
+// Code
+//==============================================================
+
+// log has p13 true, p14 false
+// log10 has p14 true, p13 false
+
+.section .text
+GLOBAL_IEEE754_ENTRY(log10)
+{ .mfi
+ getf.exp GR_Exp = f8 // if x is unorm then must recompute
+ frcpa.s1 FR_RcpX,p0 = f1,f8
+ mov GR_05 = 0xFFFE // biased exponent of A2=0.5
+}
+{ .mlx
+ addl GR_ad_1 = @ltoff(log10_data),gp
+ movl GR_A3 = 0x3fd5555555555557 // double precision memory
+ // representation of A3
+};;
+
+{ .mfi
+ getf.sig GR_Sig = f8 // get significand to calculate index
+ fclass.m p8,p0 = f8,9 // is x positive unorm?
+ mov GR_xorg = 0x3fefe // double precision memory msb of 255/256
+}
+{ .mib
+ ld8 GR_ad_1 = [GR_ad_1]
+ cmp.eq p14,p13 = r0,r0 // set p14 to 1 for log10
+ br.cond.sptk log_log10_common
+};;
+GLOBAL_IEEE754_END(log10)
+
+
+GLOBAL_IEEE754_ENTRY(log)
+{ .mfi
+ getf.exp GR_Exp = f8 // if x is unorm then must recompute
+ frcpa.s1 FR_RcpX,p0 = f1,f8
+ mov GR_05 = 0xfffe
+}
+{ .mlx
+ addl GR_ad_1 = @ltoff(log_data),gp
+ movl GR_A3 = 0x3fd5555555555557 // double precision memory
+ // representation of A3
+};;
+
+{ .mfi
+ getf.sig GR_Sig = f8 // get significand to calculate index
+ fclass.m p8,p0 = f8,9 // is x positive unorm?
+ mov GR_xorg = 0x3fefe // double precision memory msb of 255/256
+}
+{ .mfi
+ ld8 GR_ad_1 = [GR_ad_1]
+ nop.f 0
+ cmp.eq p13,p14 = r0,r0 // set p13 to 1 for log
+};;
+
+log_log10_common:
+{ .mfi
+ getf.d GR_x = f8 // double precision memory representation of x
+ fclass.m p9,p0 = f8,0x1E1 // is x NaN, NaT or +Inf?
+ dep.z GR_dx = 3, 44, 2 // Create 0x0000300000000000
+ // Difference between double precision
+ // memory representations of 257/256 and
+ // 255/256
+}
+{ .mfi
+ setf.exp FR_A2 = GR_05 // create A2
+ fnorm.s1 FR_NormX = f8
+ mov GR_bias = 0xffff
+};;
+
+{ .mfi
+ setf.d FR_A3 = GR_A3 // create A3
+ fcmp.eq.s1 p12,p0 = f1,f8 // is x equal to 1.0?
+ dep.z GR_xorg = GR_xorg, 44, 19 // 0x3fefe00000000000
+ // double precision memory
+ // representation of 255/256
+}
+{ .mib
+ add GR_ad_2 = 0x30,GR_ad_1 // address of A5,A4
+ add GR_ad_3 = 0x840,GR_ad_1 // address of ln(1/frcpa) lo parts
+(p8) br.cond.spnt log_positive_unorms
+};;
+
+log_core:
+{ .mfi
+ ldfpd FR_A7,FR_A6 = [GR_ad_1],16
+ fclass.m p10,p0 = f8,0x3A // is x < 0?
+ sub GR_Nm1 = GR_Exp,GR_05 // unbiased_exponent_of_x - 1
+}
+{ .mfi
+ ldfpd FR_A5,FR_A4 = [GR_ad_2],16
+(p9) fma.d.s0 f8 = f8,f1,f0 // set V-flag
+ sub GR_N = GR_Exp,GR_bias // unbiased_exponent_of_x
+};;
+
+{ .mfi
+ setf.sig FR_N = GR_N // copy unbiased exponent of x to significand
+ fms.s1 FR_r = FR_RcpX,f8,f1 // range reduction for |x-1|>=1/256
+ extr.u GR_Ind = GR_Sig,55,8 // get bits from 55 to 62 as index
+}
+{ .mib
+ sub GR_x = GR_x, GR_xorg // get diff between x and 255/256
+ cmp.gtu p6, p7 = 2, GR_Nm1 // p6 true if 0.5 <= x < 2
+(p9) br.ret.spnt b0 // exit for NaN, NaT and +Inf
+};;
+
+{ .mfi
+ ldfpd FR_Ln2hi,FR_Ln2lo = [GR_ad_1],16
+ fclass.m p11,p0 = f8,0x07 // is x = 0?
+ shladd GR_ad_3 = GR_Ind,2,GR_ad_3 // address of Tlo
+}
+{ .mib
+ shladd GR_ad_2 = GR_Ind,3,GR_ad_2 // address of Thi
+(p6) cmp.leu p6, p7 = GR_x, GR_dx // 255/256 <= x <= 257/256
+(p10) br.cond.spnt log_negatives // jump if x is negative
+};;
+
+// p6 is true if |x-1| < 1/256
+// p7 is true if |x-1| >= 1/256
+{ .mfi
+ ldfd FR_Thi = [GR_ad_2]
+(p6) fms.s1 FR_r = f8,f1,f1 // range reduction for |x-1|<1/256
+ nop.i 0
+};;
+
+{ .mmi
+(p7) ldfs FR_Tlo = [GR_ad_3]
+ nop.m 0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p12) fma.d.s0 f8 = f0,f0,f0
+(p12) br.ret.spnt b0 // exit for +1.0
+};;
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+(p6) mov GR_NearOne = 1
+ fms.s1 FR_A32 = FR_A3,FR_r,FR_A2 // A3*r-A2
+(p7) mov GR_NearOne = 0
+}
+{ .mfb
+ ldfe FR_InvLn10 = [GR_ad_1],16
+ fma.s1 FR_r2 = FR_r,FR_r,f0 // r^2
+(p11) br.cond.spnt log_zeroes // jump if x is zero
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A6 = FR_A7,FR_r,FR_A6 // A7*r+A6
+ nop.i 0
+}
+{ .mfi
+(p7) cmp.eq.unc p9,p0 = r0,r0 // set p9 if |x-1| > 1/256
+ fma.s1 FR_A4 = FR_A5,FR_r,FR_A4 // A5*r+A4
+(p14) cmp.eq.unc p8,p0 = 1,GR_NearOne // set p8 to 1 if it's log10
+ // and argument near 1.0
+};;
+
+{ .mfi
+(p6) getf.exp GR_rexp = FR_r // Get signexp of x-1
+(p7) fcvt.xf FR_N = FR_N
+(p8) cmp.eq p9,p6 = r0,r0 // Also set p9 and clear p6 if log10
+ // and arg near 1
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r4 = FR_r2,FR_r2,f0 // r^4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.s1 FR_NxLn2pT = f0,f0,f0 // Clear NxLn2pT if log10 near 1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ // (A3*r+A2)*r^2+r
+ fma.s1 FR_A321 = FR_A32,FR_r2,FR_r
+ mov GR_mask = 0x1ffff
+}
+{ .mfi
+ nop.m 0
+ // (A7*r+A6)*r^2+(A5*r+A4)
+ fma.s1 FR_A4 = FR_A6,FR_r2,FR_A4
+ nop.i 0
+};;
+
+{ .mfi
+(p6) and GR_rexp = GR_rexp, GR_mask
+ // N*Ln2hi+Thi
+(p7) fma.s1 FR_NxLn2hipThi = FR_N,FR_Ln2hi,FR_Thi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // N*Ln2lo+Tlo
+(p7) fma.s1 FR_NxLn2lopTlo = FR_N,FR_Ln2lo,FR_Tlo
+ nop.i 0
+};;
+
+{ .mfi
+(p6) sub GR_rexp = GR_rexp, GR_bias // unbiased exponent of x-1
+(p9) fma.s1 f8 = FR_A4,FR_r4,FR_A321 // P(r) if |x-1| >= 1/256 or
+ // log10 and |x-1| < 1/256
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (N*Ln2hi+Thi) + (N*Ln2lo+Tlo)
+(p7) fma.s1 FR_NxLn2pT = FR_NxLn2hipThi,f1,FR_NxLn2lopTlo
+ nop.i 0
+};;
+
+{ .mfi
+(p6) cmp.gt.unc p10, p6 = -40, GR_rexp // Test |x-1| < 2^-40
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p10) fma.d.s0 f8 = FR_A32,FR_r2,FR_r // log(x) if |x-1| < 2^-40
+ nop.i 0
+};;
+
+.pred.rel "mutex",p6,p9
+{ .mfi
+ nop.m 0
+(p6) fma.d.s0 f8 = FR_A4,FR_r4,FR_A321 // log(x) if 2^-40 <= |x-1| < 1/256
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p9) fma.d.s0 f8 = f8,FR_InvLn10,FR_NxLn2pT // result if |x-1| >= 1/256
+ // or log10 and |x-1| < 1/256
+ br.ret.sptk b0
+};;
+
+.align 32
+log_positive_unorms:
+{ .mmf
+ getf.exp GR_Exp = FR_NormX // recompute biased exponent
+ getf.d GR_x = FR_NormX // recompute double precision x
+ fcmp.eq.s1 p12,p0 = f1,FR_NormX // is x equal to 1.0?
+};;
+
+{ .mfb
+ getf.sig GR_Sig = FR_NormX // recompute significand
+ fcmp.eq.s0 p15, p0 = f8, f0 // set denormal flag
+ br.cond.sptk log_core
+};;
+
+.align 32
+log_zeroes:
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8,f8 // keep input argument for subsequent
+ // call of __libm_error_support#
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_tmp = f0,f0,f1 // -1.0
+ nop.i 0
+};;
+
+.pred.rel "mutex",p13,p14
+{ .mfi
+(p13) mov GR_TAG = 2 // set libm error in case of log
+ frcpa.s0 f8,p0 = FR_tmp,f0 // log(+/-0) should be equal to -INF.
+ // We can get it using frcpa because it
+ // sets result to the IEEE-754 mandated
+ // quotient of FR_tmp/f0.
+ // As far as FR_tmp is -1 it'll be -INF
+ nop.i 0
+}
+{ .mib
+(p14) mov GR_TAG = 8 // set libm error in case of log10
+ nop.i 0
+ br.cond.sptk log_libm_err
+};;
+
+.align 32
+log_negatives:
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+};;
+
+.pred.rel "mutex",p13,p14
+{ .mfi
+(p13) mov GR_TAG = 3 // set libm error in case of log
+ frcpa.s0 f8,p0 = f0,f0 // log(negatives) should be equal to NaN.
+ // We can get it using frcpa because it
+ // sets result to the IEEE-754 mandated
+ // quotient of f0/f0 i.e. NaN.
+(p14) mov GR_TAG = 9 // set libm error in case of log10
+};;
+
+.align 32
+log_libm_err:
+{ .mmi
+ alloc r32 = ar.pfs,1,4,4,0
+ mov GR_Parameter_TAG = GR_TAG
+ nop.i 0
+};;
+GLOBAL_IEEE754_END(log)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y = -32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS = ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp = -64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP = gp // Save gp
+};;
+
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0 = b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/e_log10.c b/libc/sysdeps/ia64/fpu/e_log10.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_log10.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/e_log10f.c b/libc/sysdeps/ia64/fpu/e_log10f.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_log10f.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/e_log10l.c b/libc/sysdeps/ia64/fpu/e_log10l.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_log10l.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/e_log2.S b/libc/sysdeps/ia64/fpu/e_log2.S
new file mode 100644
index 000000000..660a9526b
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_log2.S
@@ -0,0 +1,711 @@
+.file "log2.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//=================================================================
+// 09/11/00 Initial version
+// 03/19/01 Added one polynomial coefficient, to improve accuracy
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 04/18/03 Reformatted T[255]
+//
+// API
+//=================================================================
+// double log2(double)
+//
+// Overview of operation
+//=================================================================
+// Background
+//
+// Implementation
+//
+// Let x = 2^l * m, where m=1.b1 b2 ... b8 b9 ... b52
+// y=frcpa(m), r=m*y-1, f=b1 b2 .. b8 (table index)
+// j=0 if f<128; j=1 if f>=128
+// T is a table that stores log2(1/y) (in entries 1..255) rounded to
+// double extended precision; f is used as an index; T[255]=0
+//
+// If f=0 and b9=0, r is set to 2^{-8}* 0.b9 b10 ... b52 = m-1 (fractional part of m),
+// and 0 is used instead of T[0]
+// (polynomial evaluation only, for m=1+r, 0<=r<2^{-9})
+// If f=255, r is set to (m-2)/2 (T[255]=0, and only polynomial evaluation is used
+// for m=2(1-r'), 0<=r'<2^{-9})
+//
+// log2(x) is approximated as
+// (l-j) + T[f] + (c1*r+c2*r^2+...+c7*r^7), if f>0
+//
+
+
+// Special values
+//=================================================================
+// log2(0)=-inf, raises Divide by Zero
+// log2(+inf)=inf
+// log2(x)=NaN, raises Invalid if x<0
+//
+
+
+// Registers used
+//==============================================================
+// f6-f15, f32-f33
+// r2-r3, r23-r30
+// p6,p7,p8,p12
+//
+
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35 // This reg. can safely be used
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+
+data8 0xbfd0000000000000, 0x3fc999999999999a //C_4, C_5
+data8 0xbfc5555555555555, 0x3fc2492492492492 //C_6, C_7
+data8 0xb8aa3b295c17f0bc, 0x00003fff // C_1
+data8 0xaaaaaaaaaaaaaaab, 0x00003ffd // C_3=1/3
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+LOCAL_OBJECT_START(T_table)
+
+data8 0xb8d8752172fed131, 0x00003ff6
+data8 0x8ae7f475764180a3, 0x00003ff8
+data8 0xe7f73862e72ee35d, 0x00003ff8
+data8 0xa2b25310c941a2f2, 0x00003ff9
+data8 0xcbb91d671abb2e85, 0x00003ff9
+data8 0xfac91e34daa50483, 0x00003ff9
+data8 0x9504a5042eb495c5, 0x00003ffa
+data8 0xa9c4a0bbb580ee02, 0x00003ffa
+data8 0xc19264dc8a5e3bf9, 0x00003ffa
+data8 0xd67aa6703ebf4a77, 0x00003ffa
+data8 0xee76cac6d6e08ce7, 0x00003ffa
+data8 0x81c3f7de5434ed04, 0x00003ffb
+data8 0x8c563033a3ce01e4, 0x00003ffb
+data8 0x9876e9f09a98661c, 0x00003ffb
+data8 0xa31e0ac9b2326ce2, 0x00003ffb
+data8 0xadcf09e1fd10e4a5, 0x00003ffb
+data8 0xb889f992cf03cdb6, 0x00003ffb
+data8 0xc34eec68d901a714, 0x00003ffb
+data8 0xce1df524e9909ed9, 0x00003ffb
+data8 0xd8f726bcb0b80ad0, 0x00003ffb
+data8 0xe3da945b878e27d1, 0x00003ffb
+data8 0xeec851633b76a320, 0x00003ffb
+data8 0xf82ea4bb6101421a, 0x00003ffb
+data8 0x8197ddd7736b2864, 0x00003ffc
+data8 0x871dad4f994253f0, 0x00003ffc
+data8 0x8ca8cae3e892d549, 0x00003ffc
+data8 0x916d6e1559a4b697, 0x00003ffc
+data8 0x97028118efabeb7d, 0x00003ffc
+data8 0x9bcfbce1592ad5d5, 0x00003ffc
+data8 0xa16ee95d0da54a91, 0x00003ffc
+data8 0xa644dcf3403fa5d0, 0x00003ffc
+data8 0xab1ee14ffd659064, 0x00003ffc
+data8 0xb0cd12faebcc6757, 0x00003ffc
+data8 0xb5affdf9b3b221e0, 0x00003ffc
+data8 0xba970fb307c6ade1, 0x00003ffc
+data8 0xbf824f3a9f3e7561, 0x00003ffc
+data8 0xc544c055fde99333, 0x00003ffc
+data8 0xca39266532bdf26c, 0x00003ffc
+data8 0xcf31d124b8fa2f56, 0x00003ffc
+data8 0xd42ec7f59017b6ab, 0x00003ffc
+data8 0xd930124bea9a2c67, 0x00003ffc
+data8 0xde35b7af70e4dab3, 0x00003ffc
+data8 0xe33fbfbb8533ef03, 0x00003ffc
+data8 0xe77625911a7dcef3, 0x00003ffc
+data8 0xec884bd689cc12e3, 0x00003ffc
+data8 0xf19eeabf9e99a40a, 0x00003ffc
+data8 0xf6ba0a35e3d88051, 0x00003ffc
+data8 0xfbd9b237f7b4192b, 0x00003ffc
+data8 0x80111d4a1ee0c79e, 0x00003ffd
+data8 0x82a523a5f875bbfc, 0x00003ffd
+data8 0x84ccecdc92cd0815, 0x00003ffd
+data8 0x87653369d92c057a, 0x00003ffd
+data8 0x89ffd1742da3aa21, 0x00003ffd
+data8 0x8c2d2227d053d9b6, 0x00003ffd
+data8 0x8e5c189793f7f798, 0x00003ffd
+data8 0x90fd0a20e72f3c96, 0x00003ffd
+data8 0x932fa937301e59ae, 0x00003ffd
+data8 0x95d5061a5f0f5f7f, 0x00003ffd
+data8 0x980b5a2ef10e7023, 0x00003ffd
+data8 0x9a4361c5514d3c27, 0x00003ffd
+data8 0x9c7d1f7d541313fd, 0x00003ffd
+data8 0x9f2b16040b500d04, 0x00003ffd
+data8 0xa168a0fa9db22c98, 0x00003ffd
+data8 0xa3a7eaa1f9116293, 0x00003ffd
+data8 0xa5e8f5b4072a3d44, 0x00003ffd
+data8 0xa82bc4f11a5e88aa, 0x00003ffd
+data8 0xaa705b2001db8317, 0x00003ffd
+data8 0xacb6bb0e1e0f8005, 0x00003ffd
+data8 0xaefee78f75707221, 0x00003ffd
+data8 0xb148e37ec994dd99, 0x00003ffd
+data8 0xb394b1bdaca0bc17, 0x00003ffd
+data8 0xb5e255349707e496, 0x00003ffd
+data8 0xb831d0d2fda791cc, 0x00003ffd
+data8 0xba83278f6838ab20, 0x00003ffd
+data8 0xbcd65c67881c7d47, 0x00003ffd
+data8 0xbeb3e0f21d72dc92, 0x00003ffd
+data8 0xc10a7a03457d35dc, 0x00003ffd
+data8 0xc362f9b6f51eddd3, 0x00003ffd
+data8 0xc5bd6326ebfce656, 0x00003ffd
+data8 0xc7a0b3d0637c8f97, 0x00003ffd
+data8 0xc9fe96af0df8e4b5, 0x00003ffd
+data8 0xcc5e6c214b4a2cd7, 0x00003ffd
+data8 0xce46199f374d29cf, 0x00003ffd
+data8 0xd0a978a14c0d9ebe, 0x00003ffd
+data8 0xd293fecafec7f9b5, 0x00003ffd
+data8 0xd4faf1f6f5cf32e6, 0x00003ffd
+data8 0xd6e8595abaad34d1, 0x00003ffd
+data8 0xd952eb7a8ffc1593, 0x00003ffd
+data8 0xdb433ccd805f171e, 0x00003ffd
+data8 0xddb178dc43e6bd84, 0x00003ffd
+data8 0xdfa4bcfb333342a4, 0x00003ffd
+data8 0xe19953741ccea015, 0x00003ffd
+data8 0xe40cee16a2ff21c5, 0x00003ffd
+data8 0xe6048470cdbde8ea, 0x00003ffd
+data8 0xe7fd7308d6895b14, 0x00003ffd
+data8 0xe9f7bbb6a1ff9f87, 0x00003ffd
+data8 0xec7280138809433d, 0x00003ffd
+data8 0xee6fda4365cd051f, 0x00003ffd
+data8 0xf06e94a122ff1f12, 0x00003ffd
+data8 0xf26eb1151441fce5, 0x00003ffd
+data8 0xf470318b88a77e2f, 0x00003ffd
+data8 0xf67317f4d4c8aa58, 0x00003ffd
+data8 0xf8f8b250a9c4cde6, 0x00003ffd
+data8 0xfafec54831f1a484, 0x00003ffd
+data8 0xfd06449bf3eaea1e, 0x00003ffd
+data8 0xff0f324ddb19ab67, 0x00003ffd
+data8 0x808cc8320a9acf15, 0x00003ffe
+data8 0x8192b0748f2cef06, 0x00003ffe
+data8 0x829952f5e6a24ee5, 0x00003ffe
+data8 0x83a0b0bfafe1424e, 0x00003ffe
+data8 0x8466b29f9c41caea, 0x00003ffe
+data8 0x856f5aae0881d857, 0x00003ffe
+data8 0x8678c0eae8ee8190, 0x00003ffe
+data8 0x8782e6685676b9d7, 0x00003ffe
+data8 0x888dcc3abc4554ec, 0x00003ffe
+data8 0x89997378de7b98b8, 0x00003ffe
+data8 0x8aa5dd3be1044279, 0x00003ffe
+data8 0x8b6facdfd0360ab8, 0x00003ffe
+data8 0x8c7d6db7169e0cdb, 0x00003ffe
+data8 0x8d8bf424d6e130b2, 0x00003ffe
+data8 0x8e575b506f409fa6, 0x00003ffe
+data8 0x8f673e418776492c, 0x00003ffe
+data8 0x9077e9ed700ef9ba, 0x00003ffe
+data8 0x9144ef1baec80b20, 0x00003ffe
+data8 0x9256fcdb537f035f, 0x00003ffe
+data8 0x9369d68d75e7e1d6, 0x00003ffe
+data8 0x943880613b8f9f1e, 0x00003ffe
+data8 0x954cc1d9e0d94206, 0x00003ffe
+data8 0xd3c70a37bdf7a294, 0x0000bffd
+data8 0xd19bb053fb0284ec, 0x0000bffd
+data8 0xcffa1a3b7dafb8bf, 0x0000bffd
+data8 0xcdcbe1e2776479ee, 0x0000bffd
+data8 0xcc282218b8bfdda2, 0x0000bffd
+data8 0xc9f703a9afcb38ac, 0x0000bffd
+data8 0xc851146ab89593c6, 0x0000bffd
+data8 0xc61d08265927a860, 0x0000bffd
+data8 0xc474e39705912d26, 0x0000bffd
+data8 0xc23de19ec30c6e3e, 0x0000bffd
+data8 0xc09381cc45db45b4, 0x0000bffd
+data8 0xbee82b4e025ff90c, 0x0000bffd
+data8 0xbcace101149788ec, 0x0000bffd
+data8 0xbaff46962ea47964, 0x0000bffd
+data8 0xb950b1be5e0c14a2, 0x0000bffd
+data8 0xb7110e6ce866f2bc, 0x0000bffd
+data8 0xb5602ccc2a81db52, 0x0000bffd
+data8 0xb3ae4ce740fc8ef1, 0x0000bffd
+data8 0xb1fb6d92c8240ccc, 0x0000bffd
+data8 0xafb609c09b244abc, 0x0000bffd
+data8 0xae00d1cfdeb43cfd, 0x0000bffd
+data8 0xac4a967a8c8c9bd0, 0x0000bffd
+data8 0xaa93568c249e6c52, 0x0000bffd
+data8 0xa8db10cdff375343, 0x0000bffd
+data8 0xa68e6fc5a42376e3, 0x0000bffd
+data8 0xa4d3c25e68dc57f2, 0x0000bffd
+data8 0xa3180b0c192a3816, 0x0000bffd
+data8 0xa15b488e7aa329a0, 0x0000bffd
+data8 0x9f9d79a30f0e1d5f, 0x0000bffd
+data8 0x9dde9d050ee7d4ac, 0x0000bffd
+data8 0x9c1eb16d63d7356c, 0x0000bffd
+data8 0x9a5db592a310c36a, 0x0000bffd
+data8 0x989ba82907a9016f, 0x0000bffd
+data8 0x96d887e26cd57b79, 0x0000bffd
+data8 0x9514536e481c3a4f, 0x0000bffd
+data8 0x934f0979a3715fc9, 0x0000bffd
+data8 0x9188a8af1742a9d5, 0x0000bffd
+data8 0x8fc12fb6c470995f, 0x0000bffd
+data8 0x8df89d364e34f8f1, 0x0000bffd
+data8 0x8c2eefd0d3f67dd6, 0x0000bffd
+data8 0x8a642626eb093d54, 0x0000bffd
+data8 0x88983ed6985bae58, 0x0000bffd
+data8 0x86cb387b4a0feec6, 0x0000bffd
+data8 0x84fd11add101024b, 0x0000bffd
+data8 0x83c856dd81804b78, 0x0000bffd
+data8 0x81f84c2c62afd6f1, 0x0000bffd
+data8 0x80271d3e4be5ea5a, 0x0000bffd
+data8 0xfca991447e7b485d, 0x0000bffc
+data8 0xf90299c904793a3c, 0x0000bffc
+data8 0xf559511d2dc1ed69, 0x0000bffc
+data8 0xf2e72afee9bd2aee, 0x0000bffc
+data8 0xef39ff1d8a40770e, 0x0000bffc
+data8 0xeb8a7a2311c935dc, 0x0000bffc
+data8 0xe7d8990dc620012f, 0x0000bffc
+data8 0xe560b1e3b86e44b6, 0x0000bffc
+data8 0xe1aadb38caee80c4, 0x0000bffc
+data8 0xddf2a051f81b76a4, 0x0000bffc
+data8 0xdb7678bafcaf4b5f, 0x0000bffc
+data8 0xd7ba3a8f0df19bfc, 0x0000bffc
+data8 0xd3fb8fdbdd5cebdb, 0x0000bffc
+data8 0xd17b191905c35652, 0x0000bffc
+data8 0xcdb85d29cefd7121, 0x0000bffc
+data8 0xc9f32c3c88221ef6, 0x0000bffc
+data8 0xc76e5741a95b5dae, 0x0000bffc
+data8 0xc3a506d80d38c718, 0x0000bffc
+data8 0xbfd938ccef8b68c1, 0x0000bffc
+data8 0xbd4ff63e82eef78c, 0x0000bffc
+data8 0xb97ffa2b563865bd, 0x0000bffc
+data8 0xb6f3eb3011eddcea, 0x0000bffc
+data8 0xb31fb7d64898b3e6, 0x0000bffc
+data8 0xb090d63a409e7880, 0x0000bffc
+data8 0xacb8623c7ffa4f39, 0x0000bffc
+data8 0xa8dd5c83d2e45246, 0x0000bffc
+data8 0xa649e998a8d91f2e, 0x0000bffc
+data8 0xa26a93fed6faa94f, 0x0000bffc
+data8 0x9fd43df079d0db1f, 0x0000bffc
+data8 0x9d3cbe69aecac4c2, 0x0000bffc
+data8 0x99574f13c570d0fb, 0x0000bffc
+data8 0x96bce349bf7ee6c7, 0x0000bffc
+data8 0x92d30c9b86cee18e, 0x0000bffc
+data8 0x9035adef17c5bd5c, 0x0000bffc
+data8 0x8c4765e8e8b5f251, 0x0000bffc
+data8 0x89a70da448316ffa, 0x0000bffc
+data8 0x85b44a24474af78a, 0x0000bffc
+data8 0x8310f17aab5adf70, 0x0000bffc
+data8 0x806c6388d0965f29, 0x0000bffc
+data8 0xf8e69092bf0c5ead, 0x0000bffb
+data8 0xf397608bfd2d90e6, 0x0000bffb
+data8 0xee45be24d0eedbc4, 0x0000bffb
+data8 0xe646af233db881e9, 0x0000bffb
+data8 0xe0eee4e1ce3d06fb, 0x0000bffb
+data8 0xdb94a049e6e87a4f, 0x0000bffb
+data8 0xd3888ef9a4249f5a, 0x0000bffb
+data8 0xce280e6fbac39194, 0x0000bffb
+data8 0xc8c50b72319ad574, 0x0000bffb
+data8 0xc0abcd39f41e329b, 0x0000bffb
+data8 0xbb4279cfa7f9667b, 0x0000bffb
+data8 0xb5d69bac77ec398a, 0x0000bffb
+data8 0xb068306bf20d6233, 0x0000bffb
+data8 0xa83dc1b019ddb6a8, 0x0000bffb
+data8 0xa2c8eb1886c2d024, 0x0000bffb
+data8 0x9d517ee93f8e16c0, 0x0000bffb
+data8 0x97d77aae659b92fb, 0x0000bffb
+data8 0x8f9b91da5736d415, 0x0000bffb
+data8 0x8a1b06b09b7fd1d1, 0x0000bffb
+data8 0x8497daca0a2e077a, 0x0000bffb
+data8 0xfe241745a453f10c, 0x0000bffa
+data8 0xf3132d6708d723c5, 0x0000bffa
+data8 0xe7fcf2e21a0e7d77, 0x0000bffa
+data8 0xd75198b04afb8da9, 0x0000bffa
+data8 0xcc2dfe1a4a8ca305, 0x0000bffa
+data8 0xc10500d63aa65882, 0x0000bffa
+data8 0xb5d69bac77ec398a, 0x0000bffa
+data8 0xaaa2c95dc66abcde, 0x0000bffa
+data8 0x9f6984a342d13101, 0x0000bffa
+data8 0x942ac82e5387ac51, 0x0000bffa
+data8 0x88e68ea899a0976c, 0x0000bffa
+data8 0xefebc4409ccf872e, 0x0000bff9
+data8 0xd947b0c6642ef69e, 0x0000bff9
+data8 0xc2987d51e043d407, 0x0000bff9
+data8 0xabde1eeee6bfd257, 0x0000bff9
+data8 0x95188a9917cf2e01, 0x0000bff9
+data8 0xfc8f6a777c1b7f1e, 0x0000bff8
+data8 0xced727635c59725c, 0x0000bff8
+data8 0xa108358a4c904615, 0x0000bff8
+data8 0xe644fcbeb3ac9c90, 0x0000bff7
+data8 0x8a4bd667bf08e7de, 0x0000bff7
+data8 0x0000000000000000 // T[255] Low
+data8 0x0000000000000000 // T[255] High
+LOCAL_OBJECT_END(T_table)
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(log2)
+
+{ .mfi
+ alloc r32=ar.pfs,1,4,4,0
+ // y=frcpa(x)
+ frcpa.s1 f6,p0=f1,f8
+ // will form significand of 1.5 (to test whether the index is 128 or above)
+ mov r24=0xc
+}
+{.mfi
+ nop.m 0
+ // normalize x
+ fma.s1 f7=f8,f1,f0
+ // r2 = pointer to C_1...C_6 followed by T_table
+ addl r2 = @ltoff(poly_coeffs), gp;;
+}
+{.mfi
+ // get significand
+ getf.sig r25=f8
+ // f8 denormal ?
+ fclass.m p8,p10=f8,0x9
+ // will form significand of 1.5 (to test whether the index is 128 or above)
+ shl r24=r24,60
+}
+{.mfi
+ mov r26=0x804
+ nop.f 0
+ // r23=bias-1
+ mov r23=0xfffe;;
+}
+
+{.mmf
+ getf.exp r29=f8
+ // load start address for C_1...C_6 followed by T_table
+ ld8 r2=[r2]
+ // will continue only for positive normal/denormal numbers
+ fclass.nm.unc p12,p7 = f8, 0x19 ;;
+}
+
+.pred.rel "mutex",p8,p10
+{.mfi
+ // denormal input, repeat get significand (after normalization)
+ (p8) getf.sig r25=f7
+ // x=1 ?
+ fcmp.eq.s0 p6,p0=f8,f1
+ // get T_index
+ (p10) shr.u r28=r25,63-8
+}
+{.mfi
+ // f32=0.5
+ setf.exp f32=r23
+ nop.f 0
+ // r27=bias
+ mov r27=0xffff;;
+}
+
+{.mmi
+ // denormal input, repeat get exponent (after normalization)
+ (p8) getf.exp r29=f7
+ mov r23=0xff
+ // r26=0x80400...0 (threshold for using polynomial approximation)
+ shl r26=r26,64-12;;
+}
+
+{.mfb
+ add r3=48,r2
+ // r=1-x*y
+ fms.s1 f6=f6,f8,f1
+ (p12) br.cond.spnt SPECIAL_LOG2
+}
+{.mfi
+ // load C_4, C_5
+ ldfpd f10,f11=[r2],16
+ nop.f 0
+ cmp.geu p12,p0=r25,r24;;
+}
+
+{.mmi
+ // load C_6, C_7
+ ldfpd f12,f13=[r2],16
+ // r27=bias-1 (if index >=128, will add exponent+1)
+ (p12) mov r27=0xfffe
+ (p8) shr.u r28=r25,63-8;;
+}
+
+
+{.mfi
+ // load C_1
+ ldfe f14=[r2],32
+ fmerge.se f7=f1,f7
+ // if first 9 bits after leading 1 are all zero, then p8=1
+ cmp.ltu p8,p12=r25,r26
+}
+{.mfi
+ // load C_3
+ ldfe f15=[r3]
+ nop.f 0
+ // get T_index
+ and r28=r28,r23;;
+}
+{.mfi
+ // r29=exponent-bias
+ sub r29=r29,r27
+ // x=1, return 0
+ (p6) fma.d.s0 f8=f0,f0,f0
+ // get T address
+ shladd r2=r28,4,r2
+}
+{.mfb
+ // first 8 bits after leading 1 are all ones ?
+ cmp.eq p10,p0=r23,r28
+ // if first 8 bits after leading bit are 0, use polynomial approx. only
+ (p8) fms.s1 f6=f7,f1,f1
+ // x=1, return
+ (p6) br.ret.spnt b0;;
+}
+{.mfi
+ // r26=1
+ mov r26=1
+ // if first 8 bits after leading 1 are all ones, use polynomial approx. only
+ (p10) fms.s1 f6=f7,f32,f1
+ nop.i 0;;
+}
+
+.pred.rel "mutex",p8,p12
+{.mmf
+ // load T (unless first 9 bits after leading 1 are 0)
+ (p12) ldfe f33=[r2]
+ // f8=expon - bias
+ setf.sig f8=r29
+ // set T=0 (if first 9 bits after leading 1 are 0)
+ (p8) fma.s1 f33=f0,f0,f0;;
+}
+
+{.mfi
+ nop.m 0
+ // P12=1-0.5*r
+ fnma.s1 f32=f32,f6,f1
+ // r26=2^{63}
+ shl r26=r26,63
+}
+{.mfi
+ nop.m 0
+ // r2=r*r
+ fma.s1 f7=f6,f6,f0
+ nop.i 0;;
+}
+{.mfi
+ // significand(x)=1 ?
+ cmp.eq p0,p6=r26,r25
+ // P67=C_6+C_7*r
+ fma.s1 f13=f13,f6,f12
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P45=C_4+C_5*r
+ fma.s1 f10=f11,f6,f10
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // C_1*r
+ (p6) fma.s1 f14=f14,f6,f0
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // normalize additive term (l=exponent of x)
+ fcvt.xf f8=f8
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P13=1-0.5*r+C_3*r^2
+ (p6) fma.s1 f15=f15,f7,f32
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // P47=P45+r2*P67
+ (p6) fma.s1 f13=f13,f7,f10
+ // if significand(x)=1, return exponent (l)
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // r3=r^3
+ (p6) fma.s1 f7=f7,f6,f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // add T+l
+ (p6) fma.s1 f8=f8,f1,f33
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P17=P13+r3*P47
+ (p6) fma.s1 f13=f13,f7,f15
+ nop.i 0;;
+}
+
+{.mfb
+ nop.m 0
+ // result=T+l+(C_1*r)*P16
+ (p6) fma.d.s0 f8=f13,f14,f8
+ // return
+ br.ret.sptk b0;;
+}
+
+
+SPECIAL_LOG2:
+{.mfi
+ nop.m 0
+ // x=+Infinity ?
+ fclass.m p7,p0=f8,0x21
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // x=+/-Zero ?
+ fclass.m p8,p0=f8,0x7
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // x=-Infinity, -normal, -denormal ?
+ fclass.m p6,p0=f8,0x3a
+ nop.i 0;;
+}
+{.mfb
+ nop.m 0
+ // log2(+Infinity)=+Infinity
+ nop.f 0
+ (p7) br.ret.spnt b0;;
+}
+{.mfi
+ (p8) mov GR_Parameter_TAG = 170
+ // log2(+/-0)=-infinity, raises Divide by Zero
+ // set f8=-0
+ (p8) fmerge.ns f8=f0,f8
+ nop.i 0;;
+}
+{.mfb
+ nop.m 0
+ (p8) frcpa.s0 f8,p0=f1,f8
+ (p8) br.cond.sptk __libm_error_region;;
+}
+{.mfb
+ (p6) mov GR_Parameter_TAG = 171
+ // x<0: return NaN, raise Invalid
+ (p6) frcpa.s0 f8,p0=f0,f0
+ (p6) br.cond.sptk __libm_error_region;;
+}
+
+
+{.mfb
+ nop.m 0
+ // Remaining cases: NaNs
+ fma.d.s0 f8=f8,f1,f0
+ br.ret.sptk b0;;
+}
+
+GLOBAL_LIBM_END(log2)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_log2f.S b/libc/sysdeps/ia64/fpu/e_log2f.S
new file mode 100644
index 000000000..17d710a95
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_log2f.S
@@ -0,0 +1,551 @@
+.file "log2f.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 09/11/00 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// float log2f(float)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// Let x = 2^l * m, where m=1.b1 b2 ... b8 b9 ... b52
+// y=frcpa(m), r=m*y-1, f=b1 b2 .. b8 (table index)
+// j=0 if f<128; j=1 if f>=128
+// T is a table that stores log2(1/y) (in entries 1..255) rounded to
+// double extended precision; f is used as an index; T[255]=0
+//
+// If f=0 and b9=0, r is set to 2^{-8}* 0.b9 b10 ... b52 = m-1 (fractional part of m),
+// and 0 is used instead of T[0]
+// (polynomial evaluation only, for m=1+r, 0<=r<2^{-9})
+// If f=255, r is set to (m-2)/2 (T[255]=0, and only polynomial evaluation is used
+// for m=2(1-r'), 0<=r'<2^{-9})
+//
+// log2f(x) is approximated as
+// (l-j) + T[f] + (c1*r+c2*r^2+...+c6*r^6), if f>0
+//
+
+
+// Special values
+//==============================================================
+// log2f(0)=-inf, raises Divide by Zero
+// log2f(+inf)=inf
+// log2f(x)=NaN, raises Invalid if x<0
+//
+
+
+// Registers used
+//==============================================================
+// f6-f14
+// r2-r3, r23-r30
+// p6,p7,p8,p12
+//
+
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35 // This reg. can safely be used
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+
+data8 0x3fdec709dc3a03fd, 0xbfd71547652b82fe //C_3 and C_4
+data8 0xb8aa3b295c17f0bc, 0x00003fff // C_1
+data8 0xb8aa3b295c17f0bc, 0x0000bffe // C_2
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+LOCAL_OBJECT_START(T_table)
+
+data8 0x3f671b0ea42e5fda, 0x3f815cfe8eaec830
+data8 0x3f8cfee70c5ce5dc, 0x3f94564a62192834
+data8 0x3f997723ace35766, 0x3f9f5923c69b54a1
+data8 0x3fa2a094a085d693, 0x3fa538941776b01e
+data8 0x3fa8324c9b914bc7, 0x3faacf54ce07d7e9
+data8 0x3fadced958dadc12, 0x3fb0387efbca869e
+data8 0x3fb18ac6067479c0, 0x3fb30edd3e13530d
+data8 0x3fb463c15936464e, 0x3fb5b9e13c3fa21d
+data8 0x3fb7113f3259e07a, 0x3fb869dd8d1b2035
+data8 0x3fb9c3bea49d3214, 0x3fbb1ee4d7961701
+data8 0x3fbc7b528b70f1c5, 0x3fbdd90a2c676ed4
+data8 0x3fbf05d4976c2028, 0x3fc032fbbaee6d65
+data8 0x3fc0e3b5a9f3284a, 0x3fc195195c7d125b
+data8 0x3fc22dadc2ab3497, 0x3fc2e050231df57d
+data8 0x3fc379f79c2b255b, 0x3fc42ddd2ba1b4a9
+data8 0x3fc4c89b9e6807f5, 0x3fc563dc29ffacb2
+data8 0x3fc619a25f5d798d, 0x3fc6b5ffbf367644
+data8 0x3fc752e1f660f8d6, 0x3fc7f049e753e7cf
+data8 0x3fc8a8980abfbd32, 0x3fc94724cca657be
+data8 0x3fc9e63a24971f46, 0x3fca85d8feb202f7
+data8 0x3fcb2602497d5346, 0x3fcbc6b6f5ee1c9b
+data8 0x3fcc67f7f770a67e, 0x3fcceec4b2234fba
+data8 0x3fcd91097ad13982, 0x3fce33dd57f3d335
+data8 0x3fced74146bc7b10, 0x3fcf7b3646fef683
+data8 0x3fd00223a943dc19, 0x3fd054a474bf0eb7
+data8 0x3fd0999d9b9259a1, 0x3fd0eca66d3b2581
+data8 0x3fd13ffa2e85b475, 0x3fd185a444fa0a7b
+data8 0x3fd1cb8312f27eff, 0x3fd21fa1441ce5e8
+data8 0x3fd265f526e603cb, 0x3fd2baa0c34be1ec
+data8 0x3fd3016b45de21ce, 0x3fd3486c38aa29a8
+data8 0x3fd38fa3efaa8262, 0x3fd3e562c0816a02
+data8 0x3fd42d141f53b646, 0x3fd474fd543f222c
+data8 0x3fd4bd1eb680e548, 0x3fd505789e234bd1
+data8 0x3fd54e0b64003b70, 0x3fd596d761c3c1f0
+data8 0x3fd5dfdcf1eeae0e, 0x3fd6291c6fd9329c
+data8 0x3fd6729637b59418, 0x3fd6bc4aa692e0fd
+data8 0x3fd7063a1a5fb4f2, 0x3fd75064f1ed0715
+data8 0x3fd79acb8cf10390, 0x3fd7d67c1e43ae5c
+data8 0x3fd8214f4068afa7, 0x3fd86c5f36dea3dc
+data8 0x3fd8b7ac64dd7f9d, 0x3fd8f4167a0c6f92
+data8 0x3fd93fd2d5e1bf1d, 0x3fd98bcd84296946
+data8 0x3fd9c8c333e6e9a5, 0x3fda152f142981b4
+data8 0x3fda527fd95fd8ff, 0x3fda9f5e3edeb9e6
+data8 0x3fdadd0b2b5755a7, 0x3fdb2a5d6f51ff83
+data8 0x3fdb686799b00be3, 0x3fdbb62f1b887cd8
+data8 0x3fdbf4979f666668, 0x3fdc332a6e8399d4
+data8 0x3fdc819dc2d45fe4, 0x3fdcc0908e19b7bd
+data8 0x3fdcffae611ad12b, 0x3fdd3ef776d43ff4
+data8 0x3fdd8e5002710128, 0x3fddcdfb486cb9a1
+data8 0x3fde0dd294245fe4, 0x3fde4dd622a28840
+data8 0x3fde8e06317114f0, 0x3fdece62fe9a9915
+data8 0x3fdf1f164a15389a, 0x3fdf5fd8a9063e35
+data8 0x3fdfa0c8937e7d5d, 0x3fdfe1e649bb6335
+data8 0x3fe011990641535a, 0x3fe032560e91e59e
+data8 0x3fe0532a5ebcd44a, 0x3fe0741617f5fc28
+data8 0x3fe08cd653f38839, 0x3fe0adeb55c1103b
+data8 0x3fe0cf181d5d1dd0, 0x3fe0f05ccd0aced7
+data8 0x3fe111b9875788ab, 0x3fe1332e6f1bcf73
+data8 0x3fe154bba77c2088, 0x3fe16df59bfa06c1
+data8 0x3fe18fadb6e2d3c2, 0x3fe1b17e849adc26
+data8 0x3fe1caeb6a0de814, 0x3fe1ece7c830eec9
+data8 0x3fe20efd3dae01df, 0x3fe2289de375d901
+data8 0x3fe24adf9b6a6fe0, 0x3fe26d3ad1aebcfc
+data8 0x3fe287100c2771f4, 0x3fe2a9983b3c1b28
+data8 0xbfda78e146f7bef4, 0xbfda33760a7f6051
+data8 0xbfd9ff43476fb5f7, 0xbfd9b97c3c4eec8f
+data8 0xbfd98504431717fc, 0xbfd93ee07535f967
+data8 0xbfd90a228d5712b2, 0xbfd8c3a104cb24f5
+data8 0xbfd88e9c72e0b226, 0xbfd847bc33d8618e
+data8 0xbfd812703988bb69, 0xbfd7dd0569c04bff
+data8 0xbfd7959c202292f1, 0xbfd75fe8d2c5d48f
+data8 0xbfd72a1637cbc183, 0xbfd6e221cd9d0cde
+data8 0xbfd6ac059985503b, 0xbfd675c99ce81f92
+data8 0xbfd63f6db2590482, 0xbfd5f6c138136489
+data8 0xbfd5c01a39fbd688, 0xbfd58952cf519193
+data8 0xbfd5526ad18493ce, 0xbfd51b6219bfe6ea
+data8 0xbfd4d1cdf8b4846f, 0xbfd49a784bcd1b8b
+data8 0xbfd4630161832547, 0xbfd42b6911cf5465
+data8 0xbfd3f3af3461e1c4, 0xbfd3bbd3a0a1dcfb
+data8 0xbfd383d62dac7ae7, 0xbfd34bb6b2546218
+data8 0xbfd313750520f520, 0xbfd2db10fc4d9aaf
+data8 0xbfd2a28a6dc90387, 0xbfd269e12f346e2c
+data8 0xbfd2311515e2e855, 0xbfd1f825f6d88e13
+data8 0xbfd1bf13a6c9c69f, 0xbfd185ddfa1a7ed0
+data8 0xbfd14c84c4dd6128, 0xbfd11307dad30b76
+data8 0xbfd0d9670f6941fe, 0xbfd09fa235ba2020
+data8 0xbfd0790adbb03009, 0xbfd03f09858c55fb
+data8 0xbfd004e3a7c97cbd, 0xbfcf9532288fcf69
+data8 0xbfcf205339208f27, 0xbfceab2a23a5b83e
+data8 0xbfce5ce55fdd37a5, 0xbfcde73fe3b1480f
+data8 0xbfcd714f44623927, 0xbfccfb1321b8c400
+data8 0xbfccac163c770dc9, 0xbfcc355b67195dd0
+data8 0xbfcbbe540a3f036f, 0xbfcb6ecf175f95e9
+data8 0xbfcaf74751e1be33, 0xbfca7f71fb7bab9d
+data8 0xbfca2f632320b86b, 0xbfc9b70ba539dfae
+data8 0xbfc93e6587910444, 0xbfc8edcae8352b6c
+data8 0xbfc874a0db01a719, 0xbfc7fb27199df16d
+data8 0xbfc7a9fec7d05ddf, 0xbfc72fff456ac70d
+data8 0xbfc6de7d66023dbc, 0xbfc663f6fac91316
+data8 0xbfc6121ac74813cf, 0xbfc5970c478fff4a
+data8 0xbfc51bab907a5c8a, 0xbfc4c93d33151b24
+data8 0xbfc44d527fdadf55, 0xbfc3fa87be0f3a1b
+data8 0xbfc3a797cd35d959, 0xbfc32ae9e278ae1a
+data8 0xbfc2d79c6937efdd, 0xbfc25a619370d9dc
+data8 0xbfc206b5bde2f8b8, 0xbfc188ecbd1d16be
+data8 0xbfc134e1b489062e, 0xbfc0b6894488e95f
+data8 0xbfc0621e2f556b5c, 0xbfc00d8c711a12cc
+data8 0xbfbf1cd21257e18c, 0xbfbe72ec117fa5b2
+data8 0xbfbdc8b7c49a1ddb, 0xbfbcc8d5e467b710
+data8 0xbfbc1ddc9c39c7a1, 0xbfbb7294093cdd0f
+data8 0xbfba7111df348494, 0xbfb9c501cdf75872
+data8 0xbfb918a16e46335b, 0xbfb81579a73e83c6
+data8 0xbfb7684f39f4ff2d, 0xbfb6bad3758efd87
+data8 0xbfb60d060d7e41ac, 0xbfb507b836033bb7
+data8 0xbfb4591d6310d85a, 0xbfb3aa2fdd27f1c3
+data8 0xbfb2faef55ccb372, 0xbfb1f3723b4ae6db
+data8 0xbfb14360d6136ffa, 0xbfb092fb594145c1
+data8 0xbfafc482e8b48a7e, 0xbfae6265ace11ae4
+data8 0xbfacff9e5c4341d0, 0xbfaaea3316095f72
+data8 0xbfa985bfc3495194, 0xbfa820a01ac754cb
+data8 0xbfa6bad3758efd87, 0xbfa554592bb8cd58
+data8 0xbfa3ed3094685a26, 0xbfa2855905ca70f6
+data8 0xbfa11cd1d5133413, 0xbf9dfd78881399f1
+data8 0xbf9b28f618cc85df, 0xbf98530faa3c087b
+data8 0xbf957bc3dddcd7fa, 0xbf92a3115322f9e6
+data8 0xbf8f91ed4eef8370, 0xbf89dae4ec6b8b2e
+data8 0xbf842106b1499209, 0xbf7cc89f97d67594
+data8 0xbf71497accf7e11d, 0x0000000000000000
+LOCAL_OBJECT_END(T_table)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(log2f)
+
+{ .mfi
+ alloc r32=ar.pfs,1,4,4,0
+ // y=frcpa(x)
+ frcpa.s1 f6,p0=f1,f8
+ // will form significand of 1.5 (to test whether the index is 128 or above)
+ mov r24=0xc
+}
+{.mfi
+ nop.m 0
+ // normalize x
+ fma.s1 f7=f8,f1,f0
+ // r2 = pointer to C_1...C_6 followed by T_table
+ addl r2 = @ltoff(poly_coeffs), gp;;
+}
+{.mfi
+ // get significand
+ getf.sig r25=f8
+ // f8 denormal ?
+ fclass.m p8,p10=f8,0x9
+ // will form significand of 1.5 (to test whether the index is 128 or above)
+ shl r24=r24,60
+}
+{.mfi
+ mov r26=0x804
+ nop.f 0
+ // r23=bias-1
+ mov r23=0xfffe;;
+}
+
+{.mmf
+ getf.exp r29=f8
+ // load start address for C_1...C_6 followed by T_table
+ ld8 r2=[r2]
+ // will continue only for positive normal/denormal numbers
+ fclass.nm.unc p12,p7 = f8, 0x19 ;;
+}
+
+.pred.rel "mutex",p8,p10
+{.mfi
+ // denormal input, repeat get significand (after normalization)
+ (p8) getf.sig r25=f7
+ // x=1 ?
+ fcmp.eq.s0 p6,p0=f8,f1
+ // get T_index
+ (p10) shr.u r28=r25,63-8
+}
+{.mfi
+ // f12=0.5
+ setf.exp f12=r23
+ nop.f 0
+ // r27=bias
+ mov r27=0xffff;;
+}
+
+{.mfb
+ // denormal input, repeat get exponent (after normalization)
+ (p8) getf.exp r29=f7
+ nop.f 0
+ (p12) br.cond.spnt SPECIAL_log2f
+}
+{.mfi
+ cmp.geu p12,p0=r25,r24
+ nop.f 0
+ mov r23=0xff;;
+}
+
+{.mfi
+ add r3=32,r2
+ // r=1-x*y
+ fms.s1 f6=f6,f8,f1
+ // r26=0x80400...0 (threshold for using polynomial approximation)
+ shl r26=r26,64-12
+}
+{.mfi
+ // load C_3, C_4
+ ldfpd f10,f11=[r2],16
+ nop.f 0
+ // r27=bias-1 (if index >=128, will add exponent+1)
+ (p12) mov r27=0xfffe;;
+}
+
+{.mfi
+ // load C_1
+ ldfe f14=[r2],32
+ // x=1, return 0
+ (p6) fma.s.s0 f8=f0,f0,f0
+ (p8) shr.u r28=r25,63-8
+}
+{.mib
+ // load C_2
+ ldfe f13=[r3]
+ // r29=exponent-bias
+ sub r29=r29,r27
+ // x=1, return
+ (p6) br.ret.spnt b0;;
+}
+
+
+{.mfi
+ // get T_index
+ and r28=r28,r23
+ fmerge.se f7=f1,f7
+ // if first 9 bits after leading 1 are all zero, then p8=1
+ cmp.ltu p8,p12=r25,r26;;
+}
+{.mfi
+ // f8=expon - bias
+ setf.sig f8=r29
+ nop.f 0
+ // get T address
+ shladd r2=r28,3,r2
+}
+{.mfi
+ // first 8 bits after leading 1 are all ones ?
+ cmp.eq p10,p0=r23,r28
+ // if first 8 bits after leading bit are 0, use polynomial approx. only
+ (p8) fms.s1 f6=f7,f1,f1
+ nop.i 0;;
+}
+{.mfi
+ //r26=1
+ mov r26=1
+ // if first 8 bits after leading 1 are all ones, use polynomial approx. only
+ (p10) fms.s1 f6=f7,f12,f1
+ nop.i 0;;
+}
+
+.pred.rel "mutex",p8,p12
+{.mmf
+ // load T (unless first 9 bits after leading 1 are 0)
+ (p12) ldfd f12=[r2]
+ nop.m 0
+ // set T=0 (if first 9 bits after leading 1 are 0)
+ (p8) fma.s1 f12=f0,f0,f0;;
+}
+
+{.mfi
+ nop.m 0
+ // P34=C_3+C_4*r
+ fma.s1 f10=f11,f6,f10
+ // r26=2^{63}
+ shl r26=r26,63
+}
+{.mfi
+ nop.m 0
+ // r2=r*r
+ fma.s1 f11=f6,f6,f0
+ nop.i 0;;
+}
+{.mfi
+ // significand of x is 1 ?
+ cmp.eq p0,p6=r25,r26
+ // P12=C_1+C_2*r
+ fma.s1 f14=f13,f6,f14
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // normalize additive term (l=exponent of x)
+ fcvt.xf f8=f8
+ // if significand(x)=1, return exponent (l)
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // add T+l
+ (p6) fma.s1 f8=f8,f1,f12
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P14=P12+r2*P34
+ (p6) fma.s1 f13=f10,f11,f14
+ nop.i 0;;
+}
+
+{.mfb
+ nop.m 0
+ // result=T+l+r*P14
+ (p6) fma.s.s0 f8=f13,f6,f8
+ // return
+ br.ret.sptk b0;;
+}
+
+
+SPECIAL_log2f:
+{.mfi
+ nop.m 0
+ // x=+Infinity ?
+ fclass.m p7,p0=f8,0x21
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // x=+/-Zero ?
+ fclass.m p8,p0=f8,0x7
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // x=-Infinity, -normal, -denormal ?
+ fclass.m p6,p0=f8,0x3a
+ nop.i 0;;
+}
+{.mfb
+ nop.m 0
+ // log2f(+Infinity)=+Infinity
+ nop.f 0
+ (p7) br.ret.spnt b0;;
+}
+{.mfi
+ (p8) mov GR_Parameter_TAG = 172
+ // log2f(+/-0)=-infinity, raises Divide by Zero
+ // set f8=-0
+ (p8) fmerge.ns f8=f0,f8
+ nop.i 0;;
+}
+{.mfb
+ nop.m 0
+ (p8) frcpa.s0 f8,p0=f1,f8
+ (p8) br.cond.sptk __libm_error_region;;
+}
+{.mfb
+ (p6) mov GR_Parameter_TAG = 173
+ // x<0: return NaN, raise Invalid
+ (p6) frcpa.s0 f8,p0=f0,f0
+ (p6) br.cond.sptk __libm_error_region;;
+}
+
+
+{.mfb
+ nop.m 0
+ // Remaining cases: NaNs
+ fma.s.s0 f8=f8,f1,f0
+ br.ret.sptk b0;;
+}
+
+GLOBAL_LIBM_END(log2f)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_log2l.S b/libc/sysdeps/ia64/fpu/e_log2l.S
new file mode 100644
index 000000000..b3fe63f18
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_log2l.S
@@ -0,0 +1,817 @@
+.file "log2l.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 09/25/00 Initial version
+// 11/22/00 Fixed accuracy bug (for mantissas near 1, 2)
+// 12/07/00 Fixed C_1l constant, eliminated rounding errors in
+// reduced argument (x*frcpa(x)-1)
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// long double log2l(long double)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// Let x = 2^l * m, where m=1.b1 b2 ... b8 b9 ... b52
+// y=frcpa(m), r=m*y-1, f=b1 b2 .. b8
+// T_hi is a table that stores the 24 most significant bits of log2(1/y)
+// (in entries 1..255) in single precision format
+// T_low is a table that stores (log2(1/y)-T_high), rounded to double
+// precision
+//
+// f is used as an index; T_high[255]=T_low[255]=0
+//
+// If f=0 and b9=0, r is set to 2^{-8}* 0.b9 b10 ... b52 = m-1 (fractional part of m),
+// and 0 is used instead of T_high[0], T_low[0]
+// (polynomial evaluation only, for m=1+r, 0<=r<2^{-9})
+// If f=255, r is set to (m-2)/2 (T[255]=0, and only polynomial evaluation is used
+// for m=2(1-r'), 0<=r'<2^{-9})
+//
+// If 2^{-9}<=m<2-2^{-8} or (input not near 1), let C1r=(2^{16}+C1*r)-2^{16}
+// and let E=((RN(m*y)-1)-r)+(m*y-RN(m*y))
+// Else let C1r=C1*r (rounded to 64 significant bits) and let E=0
+//
+// Let D=C1*r-C1r
+//
+//
+// log2l(x) is approximated as
+// (l+T_high[f]+C1r) + (D+r*(c1+c2*r+c3*r^2...+c8*r^7)+(T_low[f]+C_1*E))
+//
+
+
+// Special values
+//==============================================================
+// log2l(0)=-inf, raises Divide by Zero
+// log2l(+inf)=inf
+// log2l(x)=NaN, raises Invalid if x<0
+//
+
+
+// Registers used
+//==============================================================
+// f6-f15, f32-f36
+// r2-r3, r23-r23
+// p6,p7,p8,p12
+//
+
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35 // This reg. can safely be used
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+
+data8 0xb8aa3b295c17f0bc, 0x00003fff // C_1
+data8 0x3fca61762a7aded9, 0xbfc71547652b82fe // C_7, C_8
+data8 0x3fd2776c50ef9bfe, 0xbfcec709dc3a03fd // C_5, C_6
+data8 0x3fdec709dc3a03fd, 0xbfd71547652b82fe // C_3, C_4
+//data8 0xd871319ff0342580, 0x0000bfbd // C_1l (low part of C1)
+data8 0x82f0025f2dc582ee, 0x0000bfbe // C_1l (low part of C1)
+data8 0xb8aa3b295c17f0bc, 0x0000bffe // C_2
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+
+
+LOCAL_OBJECT_START(T_table)
+
+data4 0x3b38d875, 0x3c0ae7f4, 0x3c67f738, 0x3ca2b253
+data4 0x3ccbb91d, 0x3cfac91e, 0x3d1504a5, 0x3d29c4a0
+data4 0x3d419264, 0x3d567aa6, 0x3d6e76ca, 0x3d81c3f7
+data4 0x3d8c5630, 0x3d9876e9, 0x3da31e0a, 0x3dadcf09
+data4 0x3db889f9, 0x3dc34eec, 0x3dce1df5, 0x3dd8f726
+data4 0x3de3da94, 0x3deec851, 0x3df82ea4, 0x3e0197dd
+data4 0x3e071dad, 0x3e0ca8ca, 0x3e116d6e, 0x3e170281
+data4 0x3e1bcfbc, 0x3e216ee9, 0x3e2644dc, 0x3e2b1ee1
+data4 0x3e30cd12, 0x3e35affd, 0x3e3a970f, 0x3e3f824f
+data4 0x3e4544c0, 0x3e4a3926, 0x3e4f31d1, 0x3e542ec7
+data4 0x3e593012, 0x3e5e35b7, 0x3e633fbf, 0x3e677625
+data4 0x3e6c884b, 0x3e719eea, 0x3e76ba0a, 0x3e7bd9b2
+data4 0x3e80111d, 0x3e82a523, 0x3e84ccec, 0x3e876533
+data4 0x3e89ffd1, 0x3e8c2d22, 0x3e8e5c18, 0x3e90fd0a
+data4 0x3e932fa9, 0x3e95d506, 0x3e980b5a, 0x3e9a4361
+data4 0x3e9c7d1f, 0x3e9f2b16, 0x3ea168a0, 0x3ea3a7ea
+data4 0x3ea5e8f5, 0x3ea82bc4, 0x3eaa705b, 0x3eacb6bb
+data4 0x3eaefee7, 0x3eb148e3, 0x3eb394b1, 0x3eb5e255
+data4 0x3eb831d0, 0x3eba8327, 0x3ebcd65c, 0x3ebeb3e0
+data4 0x3ec10a7a, 0x3ec362f9, 0x3ec5bd63, 0x3ec7a0b3
+data4 0x3ec9fe96, 0x3ecc5e6c, 0x3ece4619, 0x3ed0a978
+data4 0x3ed293fe, 0x3ed4faf1, 0x3ed6e859, 0x3ed952eb
+data4 0x3edb433c, 0x3eddb178, 0x3edfa4bc, 0x3ee19953
+data4 0x3ee40cee, 0x3ee60484, 0x3ee7fd73, 0x3ee9f7bb
+data4 0x3eec7280, 0x3eee6fda, 0x3ef06e94, 0x3ef26eb1
+data4 0x3ef47031, 0x3ef67317, 0x3ef8f8b2, 0x3efafec5
+data4 0x3efd0644, 0x3eff0f32, 0x3f008cc8, 0x3f0192b0
+data4 0x3f029952, 0x3f03a0b0, 0x3f0466b2, 0x3f056f5a
+data4 0x3f0678c0, 0x3f0782e6, 0x3f088dcc, 0x3f099973
+data4 0x3f0aa5dd, 0x3f0b6fac, 0x3f0c7d6d, 0x3f0d8bf4
+data4 0x3f0e575b, 0x3f0f673e, 0x3f1077e9, 0x3f1144ef
+data4 0x3f1256fc, 0x3f1369d6, 0x3f143880, 0x3f154cc1
+data4 0x3f161c7a, 0x3f173227, 0x3f1802f2, 0x3f191a0f
+data4 0x3f19ebee, 0x3f1b047e, 0x3f1bd775, 0x3f1cf17b
+data4 0x3f1dc58e, 0x3f1ee10f, 0x3f1fb63f, 0x3f208bea
+data4 0x3f21a98f, 0x3f22805c, 0x3f2357a7, 0x3f247778
+data4 0x3f254fe9, 0x3f2628d9, 0x3f270249, 0x3f2824fb
+data4 0x3f28ff97, 0x3f29dab4, 0x3f2ab654, 0x3f2b9277
+data4 0x3f2cb8c8, 0x3f2d961e, 0x3f2e73fa, 0x3f2f525b
+data4 0x3f303143, 0x3f3110b1, 0x3f31f0a7, 0x3f32d125
+data4 0x3f33b22b, 0x3f3493bc, 0x3f3575d6, 0x3f36587b
+data4 0x3f373bab, 0x3f381f68, 0x3f3903b1, 0x3f39e888
+data4 0x3f3acdec, 0x3f3bb3e0, 0x3f3c9a63, 0x3f3d8177
+data4 0x3f3e1bd4, 0x3f3f03d9, 0x3f3fec71, 0x3f40d59b
+data4 0x3f41bf59, 0x3f42a9ab, 0x3f434635, 0x3f443180
+data4 0x3f451d61, 0x3f4609d9, 0x3f46a7d3, 0x3f479549
+data4 0x3f488357, 0x3f492261, 0x3f4a1171, 0x3f4b011c
+data4 0x3f4ba139, 0x3f4c91e8, 0x3f4d8334, 0x3f4e246a
+data4 0x3f4f16be, 0x3f5009b1, 0x3f50ac02, 0x3f51a001
+data4 0x3f524305, 0x3f533812, 0x3f53dbca, 0x3f54d1e7
+data4 0x3f55c8a8, 0x3f566d85, 0x3f57655b, 0x3f580af0
+data4 0x3f58b0d0, 0x3f59aa2c, 0x3f5a50c7, 0x3f5b4b3c
+data4 0x3f5bf294, 0x3f5cee26, 0x3f5d963c, 0x3f5e92ed
+data4 0x3f5f3bc3, 0x3f5fe4e7, 0x3f60e32d, 0x3f618d13
+data4 0x3f623748, 0x3f63372a, 0x3f63e223, 0x3f648d6b
+data4 0x3f658eee, 0x3f663afe, 0x3f66e75e, 0x3f67ea86
+data4 0x3f6897b0, 0x3f69452c, 0x3f69f2f9, 0x3f6af847
+data4 0x3f6ba6e2, 0x3f6c55d0, 0x3f6d0510, 0x3f6e0c8d
+data4 0x3f6ebc9f, 0x3f6f6d04, 0x3f701dbe, 0x3f70cecd
+data4 0x3f718030, 0x3f728ae6, 0x3f733d20, 0x3f73efaf
+data4 0x3f74a296, 0x3f7555d3, 0x3f760967, 0x3f76bd53
+data4 0x3f777197, 0x3f7880a1, 0x3f7935c2, 0x3f79eb3c
+data4 0x3f7aa10f, 0x3f7b573b, 0x3f7c0dc2, 0x3f7cc4a3
+data4 0x3f7d7bdf, 0x3f7e3376, 0x3f7eeb68, 0x00000000
+LOCAL_OBJECT_END(T_table)
+
+
+
+LOCAL_OBJECT_START(T_low)
+
+
+data8 0x3dc0b97f689876ef, 0x3dfd5d906028ac01
+data8 0x3df8b9cbb8d7240b, 0x3de0c941a2f220cd
+data8 0x3e09c6aecba15936, 0x3dfa6d528241827c
+data8 0x3dd0bad25714903c, 0x3e2776b01dc036a2
+data8 0x3e2b914bc77f158b, 0x3e1c0fafd29dc74a
+data8 0x3e28dadc119cd3de, 0x3e3bca869da085be
+data8 0x3e19d1e700f2200a, 0x3e3e13530cc37504
+data8 0x3e3936464d9c41ee, 0x3e3c3fa21c9499d0
+data8 0x3e3259e079b6c6e8, 0x3e2a364069c4f7f3
+data8 0x3e1274c84f6c6364, 0x3e3796170159f454
+data8 0x3e26e1e389f4364e, 0x3e28cedda8c7f658
+data8 0x3e376c2028433268, 0x3e4aee6d650c82e1
+data8 0x3e33e65094fbeeb4, 0x3e4c7d125aa92c5d
+data8 0x3e1559a4b69691d8, 0x3e18efabeb7d7221
+data8 0x3e4c2b255abaa8de, 0x3e37436952a4538b
+data8 0x3e4e6807f4ba00b8, 0x3e33ff5964190e42
+data8 0x3e4f5d798cead43c, 0x3e4f3676443bf453
+data8 0x3e4660f8d5bc1bf5, 0x3e2d4f9f3ab04f36
+data8 0x3e357f7a64ccd537, 0x3e394caf7c9b05af
+data8 0x3e225c7d17ab29b0, 0x3e4eb202f6d55a12
+data8 0x3e32faa68b19bcd2, 0x3e45ee1c9b566a8b
+data8 0x3e4770a67de054ff, 0x3e42234fb9de6d6b
+data8 0x3e4ad139825c6e19, 0x3e47f3d334814a93
+data8 0x3e2af1ec402867b6, 0x3e2bfbda0c956e3d
+data8 0x3e4287b831e77ff2, 0x3e54bf0eb77f7b89
+data8 0x3e5b9259a1029607, 0x3e4a764b015e699d
+data8 0x3e4d0b68ea883ab5, 0x3e33e829ecdadf46
+data8 0x3e52f27efef3031b, 0x3e3073979e4af89e
+data8 0x3e3b980f2cd6c253, 0x3e2a5f0f5f7f66a9
+data8 0x3e37788738117b02, 0x3e58aa29a784d52f
+data8 0x3e4f5504c4ff2466, 0x3e002d40340fa647
+data8 0x3e5f53b64592f4c3, 0x3e543f222c526802
+data8 0x3e5680e547a872fa, 0x3e5e234bd1154450
+data8 0x3e3000edc18b6d21, 0x3e1c3c1f000942a8
+data8 0x3e51eeae0e442d6e, 0x3e4fb265376623f2
+data8 0x3e57b5941782d830, 0x3e3a4b83f24ae52c
+data8 0x3e5a5fb4f23978de, 0x3e51ed071563fb02
+data8 0x3e49e2071f51a7a8, 0x3e5e43ae5b924234
+data8 0x3dfa2be9aedf374a, 0x3e56dea3dbba67d5
+data8 0x3e3375fe732b3c3e, 0x3e5a0c6f91f2e77e
+data8 0x3e55e1bf1c969e41, 0x3e30a5a5166b8eee
+data8 0x3e53e6e9a539d46c, 0x3e542981b3d7b0e6
+data8 0x3e595fd8ff36ad64, 0x3e5edeb9e65cbbb4
+data8 0x3e46aeab4d3434c1, 0x3e4ea3ff0564b010
+data8 0x3e59b00be2e3c25a, 0x3e5b887cd7b0821f
+data8 0x3e5f666668547b4d, 0x3e4d0733a805273f
+data8 0x3e26a2ff21c4aec5, 0x3e4c336f7a3a78f3
+data8 0x3e11ad12b628e2d0, 0x3e56d43ff3f0ea64
+data8 0x3e238809433cccd2, 0x3e40d9734147d40f
+data8 0x3e54245fe3e24e06, 0x3e251441fce4d48c
+data8 0x3e517114efc5d1f9, 0x3e5e9a99154b0d82
+data8 0x3e442a71337970f8, 0x3e420c7c69211fdf
+data8 0x3e537e7d5d43c6a7, 0x3e4376c66ad9ad8b
+data8 0x3e49054d678a4f1c, 0x3e5d23cb3bc19f18
+data8 0x3e6ebcd449dcab2b, 0x3e67f5fc2849c88a
+data8 0x3e63f388395d3e84, 0x3e65c1103b0ad7e9
+data8 0x3e6d5d1dd031f353, 0x3e5a159dae75c4d0
+data8 0x3e4d5e22aa75f71d, 0x3e5e379ee62e1e35
+data8 0x3e4df082213cb2dc, 0x3e6bfa06c156f521
+data8 0x3e66e2d3c19b517b, 0x3e426b7098590071
+data8 0x3e541bd027e9854e, 0x3e5061dd924b0ac0
+data8 0x3e6dae01df373a03, 0x3e3baec80b207b0b
+data8 0x3e6b6a6fe06bebac, 0x3e61aebcfc3ab5d1
+data8 0x3e584ee3e7c79d83, 0x3e6b3c1b2840cb40
+data8 0x3e6c842085d6befd, 0x3e6ac04fd7b141e0
+data8 0x3e6c48250474141d, 0x3e2d889b86125f69
+data8 0x3e6e74740225dad0, 0x3e45940d31d50a7c
+data8 0x3e695476a6c39ddc, 0x3e6d9a6d857a060a
+data8 0x3e4a3e9bb4b69337, 0x3e484f3ce4707ed6
+data8 0x3e39dd125d25fc27, 0x3e563fb400de8732
+data8 0x3e5fdd6d0ee28b48, 0x3e669d15b869bb07
+data8 0x3e40687cfad7964d, 0x3e69317990d43957
+data8 0x3e633d57e24ae1bd, 0x3e618bf03710eabb
+data8 0x3e4b4df6fccd1160, 0x3e3fb26ddaa1ec45
+data8 0x3e3810a5e1817fd4, 0x3e6857373642fa5c
+data8 0x3e673db6193add31, 0x3e63200c8acbc9c3
+data8 0x3e3d2dee448ebb62, 0x3e6a19723a80db6a
+data8 0x3e5e7cdab8fd3e6a, 0x3e671855cd660672
+data8 0x3e473c3c78a85ecd, 0x3e5f5e23056a7cf2
+data8 0x3e52538519527367, 0x3e4b573bcf2580e9
+data8 0x3e6d6f856fe90c60, 0x3e2d932a8487642e
+data8 0x3e5236fc78b6174c, 0x3e50cb91d406db50
+data8 0x3e650e8bd562aa57, 0x3e424ee3d9a82f2e
+data8 0x3e59363960e1e3d9, 0x3e379604c1150a3e
+data8 0x3e6d914f6c2ac258, 0x3e62967a451a7b48
+data8 0x3e684b5f01139cb2, 0x3e448bbfbf6d292c
+data8 0x3e6227e7fb487e73, 0x3e6d39d50290f458
+data8 0x3e58368342b4b668, 0x3e65dc0c25bd1763
+data8 0x3e61b7dc362e22b5, 0x3e671691f094bb80
+data8 0x3e5011642d5123f2, 0x3e4c4eb7f11e41be
+data8 0x3e5dcee36ca242cf, 0x3e6791cefff688f1
+data8 0x3e60e23c8dda4ecd, 0x3e48e6a22fe78cfe
+data8 0x3e6d703f244adc86, 0x3e6a281a85a5049d
+data8 0x3e570f20e6403d9e, 0x3e2211518a12956f
+data8 0x3e6737d1e54d71df, 0x3e66b1881476f5e9
+data8 0x3e6e1bbeef085376, 0x3e47cad4944a32be
+data8 0x3e527f2c738e7ee9, 0x3e699883a4b9fb29
+data8 0x3e5c17d1108740d9, 0x3e5d4a9c79a43389
+data8 0x3e49fdc24462ba3b, 0x3e24dbb3a60cceb2
+data8 0x3e5c5bf618780748, 0x3e5c38005b0c778c
+data8 0x3e6be168dd6dd3fe, 0x3e633ab9370693b0
+data8 0x3dd290556b0ae339, 0x3e607c317927096a
+data8 0x3e59651353b3d90e, 0x3e4d8751e5e0ae0d
+data8 0x3e46c81023272a85, 0x3e6b23c988f391b2
+data8 0x3e608741d215209c, 0x3e60b8ba506d758f
+data8 0x3e62ddbe74803297, 0x3e5dbb8b5087587d
+data8 0x3e642aa529048131, 0x3e3dcbda6835dcf4
+data8 0x3e6db503ce854d2a, 0x3e6dd00b49bc6849
+data8 0x3e4db2f11243bc84, 0x3e3b9848efc2ea97
+data8 0x3e58f18e17c82609, 0x3e6ed8645e16c312
+data8 0x3e4065bdb60a5dd4, 0x3e490453c6e6c30a
+data8 0x3e62373994aa31ba, 0x3e56305f0e6b2a95
+data8 0x3e68c1601a6614ee, 0x3e614e204f19d93f
+data8 0x3e6e5037ca773299, 0x3e693f98892561a6
+data8 0x3e639de4f4bf700d, 0x3e416c071e93fd97
+data8 0x3e65466991b415ef, 0x3e6896a324afac9d
+data8 0x3e44f64802e2f11c, 0x3e64d7d747e2191a
+data8 0x3e6174b7581de84c, 0x3e44c7b946e1d43c
+data8 0x3e6a3bcbe30512ec, 0x3e5d3ed411c95ce4
+data8 0x3e3e5b5735cfaf8e, 0x3e6e538ab34efb51
+data8 0x3e514e204f19d93f, 0x3e5a88e6550c89a4
+data8 0x3e66b97a5d9dfd8b, 0x3e5f46b1e14ebaf3
+data8 0x3e357665f6893f5d, 0x3e6bbf633078d1d5
+data8 0x3e5e7337a212c417, 0x3e3570fde15fc8cc
+data8 0x3e21119402da92b4, 0x3e6566e830d1ff3b
+data8 0x3e558883e480e220, 0x3e589ca3a68da411
+data8 0x3e44eb66df73d648, 0x3e1a0a629b1b7e68
+data8 0x3e54cc207b8c1116, 0x0000000000000000
+LOCAL_OBJECT_END(T_low)
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(log2l)
+
+{ .mfi
+ alloc r32=ar.pfs,1,4,4,0
+ // normalize x
+ // y=frcpa(x)
+ frcpa.s1 f41,p0=f1,f8
+ // r26=bias-1
+ mov r26=0xfffe
+}
+{.mfi
+ // r23=bias+16
+ mov r23=0xffff+16
+ fma.s1 f7=f8,f1,f0
+ // r2 = pointer to C_1...C_6 followed by T_table
+ addl r2 = @ltoff(poly_coeffs), gp;;
+}
+{.mfi
+ // get significand
+ getf.sig r25=f8
+ // f8 denormal ?
+ fclass.m p8,p10=f8,0x9
+ // r24=bias-8
+ mov r24=0xffff-8;;
+}
+{.mfi
+ setf.exp f36=r26
+ nop.f 0
+ // r27=bias
+ mov r27=0xffff;;
+}
+
+{.mmf
+ getf.exp r29=f8
+ // load start address for C_1...C_7 followed by T_table
+ ld8 r2=[r2]
+ // will continue only for positive normal/unnormal numbers
+ fclass.m.unc p0,p12 = f8, 0x19;;
+}
+
+
+.pred.rel "mutex",p8,p10
+{.mfi
+ // denormal input, repeat get significand (after normalization)
+ (p8) getf.sig r25=f7
+ // x=1 ?
+ fcmp.eq.s0 p6,p0=f8,f1
+ // get T_index
+ (p10) shr.u r28=r25,63-8
+}
+{.mfi
+ // f32=2^16
+ setf.exp f32=r23
+ nop.f 0
+ mov r26=0x804;;
+}
+
+{.mfi
+ // denormal input, repeat get exponent (after normalization)
+ (p8) getf.exp r29=f7
+ // f33=0
+ mov f33=f0
+ // r26=0x80400...0 (threshold for using polynomial approximation)
+ shl r26=r26,64-12;;
+}
+
+{.mfb
+ add r3=16,r2
+ // r=x*y-1
+ fms.s1 f6=f41,f8,f1
+ (p12) br.cond.spnt SPECIAL_log2l
+}
+{.mfi
+ // load C_1
+ ldfe f14=[r2],48
+ // RN(x*y)
+ fma.s1 f43=f41,f8,f0
+ mov r23=0xff;;
+}
+
+{.mmi
+ // load C_7, C_8
+ ldfpd f10,f11=[r3],16
+ // load C_3,C_4
+ ldfpd f15,f42=[r2],16
+ (p8) shr.u r28=r25,63-8;;
+}
+
+
+{.mfi
+ // load C_5, C_6
+ ldfpd f12,f13=[r3]
+ // pseudo-zero ?
+ fcmp.eq.s0 p7,p0=f7,f0
+ // if first 9 bits after leading 1 are all zero, then p8=1
+ cmp.ltu p8,p12=r25,r26
+}
+{.mfi
+ // load C1l
+ ldfe f34=[r2],16
+ fmerge.se f7=f1,f7
+ // get T_index
+ and r28=r28,r23;;
+}
+{.mfi
+ // r29=exponent-bias
+ sub r29=r29,r27
+ // if first 8 bits after leading bit are 0, use polynomial approx. only
+ (p8) fms.s1 f6=f7,f1,f1
+ // start address of T_low
+ add r3=1024+16,r2
+}
+{.mfi
+ // load C_2
+ ldfe f35=[r2],16
+ // x=1, return 0
+ (p6) fma.s0 f8=f0,f0,f0
+ // first 8 bits after leading 1 are all ones ?
+ cmp.eq p10,p0=r23,r28;;
+}
+
+{.mfb
+ // if first 8 bits after leading 1 are all ones, use polynomial approx. only
+ // add 1 to the exponent additive term, and estimate log2(1-r)
+ (p10) add r29=1,r29
+ nop.f 0
+ (p7) br.cond.spnt LOG2_PSEUDO_ZERO
+}
+{.mfi
+ // get T_low adress
+ shladd r3=r28,3,r3
+ // if first 8 bits after leading 1 are all ones, use polynomial approx. only
+ (p10) fms.s1 f6=f7,f36,f1
+ // p10 --> p8=1, p12=0
+ (p10) cmp.eq p8,p12=r0,r0;;
+}
+
+{.mfi
+ // get T_high address
+ shladd r2=r28,2,r2
+ // L(x*y)=x*y-RN(x*y)
+ fms.s1 f41=f41,f8,f43
+ nop.i 0
+}
+{.mfi
+ // p13=p12
+ (p12) cmp.eq.unc p13,p0=r0,r0
+ // RtH=RN(x*y)-1 (will eliminate rounding errors in r)
+ fms.s1 f43=f43,f1,f1
+ nop.i 0;;
+}
+
+.pred.rel "mutex",p8,p12
+{.mfb
+ // load T_high (unless first 9 bits after leading 1 are 0)
+ (p12) ldfs f7=[r2]
+ // set T_high=0 (if first 9 bits after leading 1 are 0)
+ (p8) fma.s1 f7=f0,f0,f0
+ // x=1, return
+ (p6) br.ret.spnt b0
+}
+.pred.rel "mutex",p8,p12
+{.mfi
+ // p12: load T_low
+ (p12) ldfd f36=[r3]
+ // p8: set T_low=0
+ (p8) fma.s1 f36=f0,f0,f0
+ (p8) cmp.eq p8,p12=r29,r0;; //nop.i 0;;
+}
+
+.pred.rel "mutex",p8,p12
+{.mfi
+ // f8=expon - bias
+ setf.sig f8=r29
+ // general case: 2^{16}+C1*r
+ (p12) fma.s1 f33=f6,f14,f32
+ nop.i 0
+}
+{.mfi
+ // r26=1
+ mov r26=1
+ // p8 (mantissa is close to 1, or close to 2): 2^{-8}+C1*r
+ (p8) fma.s1 f32=f6,f14,f33
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // P78=C_7+C_8*r
+ fma.s1 f10=f11,f6,f10
+ // r26=2^{63}
+ shl r26=r26,63
+}
+{.mfi
+ nop.m 0
+ // P34=C_3+r*C_4
+ fma.s1 f15=f42,f6,f15
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // r2=r*r
+ fma.s1 f11=f6,f6,f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P56=C_5+C_6*r
+ fma.s1 f13=f13,f6,f12
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // Rth-r
+ (p13) fms.s1 f43=f43,f1,f6
+ nop.i 0
+}
+{.mfi
+ // significand(x)=1 ?
+ cmp.eq p0,p6=r25,r26
+ // P12=C1l+C_2*r
+ fma.s1 f34=f35,f6,f34
+ nop.i 0;;
+}
+
+.pred.rel "mutex",p8,p12
+{.mfi
+ nop.m 0
+ // p12: C1r=(2^{16}+C1*r)-2^{16}
+ (p12) fms.s1 f32=f33,f1,f32
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // p8: C1r=C1*r (double extended)
+ (p8) fms.s1 f32=f32,f1,f33
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // L(x*y)*C_1+T_low
+ (p13) fma.s1 f36=f41,f14,f36
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // P58=P56+r2*P78
+ fma.s1 f13=f11,f10,f13
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // P14=P12+r2*P34
+ fma.s1 f15=f15,f11,f34
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // r4=r2*r2
+ fma.s1 f11=f11,f11,f0
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // normalize additive term (l=exponent of x)
+ fcvt.xf f8=f8
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // D=C1*r-C1r
+ (p6) fms.s1 f12=f14,f6,f32
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // T_low'=(Rth-r)*C1+(L(x*y)*C1+T_low)
+ (p13) fma.s1 f36=f43,f14,f36
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // P18=P14+r4*P58
+ (p6) fma.s1 f13=f11,f13,f15
+ nop.i 0;;
+}
+
+{.mfi
+ nop.m 0
+ // add T_high+l
+ (p6) fma.s1 f8=f8,f1,f7
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // D+T_low
+ (p6) fma.s1 f12=f12,f1,f36
+ nop.i 0;;
+}
+
+
+{.mfi
+ nop.m 0
+ // (T_high+l)+C1r
+ (p6) fma.s1 f8=f8,f1,f32
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // (D+T_low)+r*P18
+ (p6) fma.s1 f13=f13,f6,f12
+ nop.i 0;;
+}
+
+//{.mfb
+//nop.m 0
+//mov f8=f36
+//fma.s0 f8=f13,f6,f0
+//br.ret.sptk b0;;
+//}
+
+
+{.mfb
+ nop.m 0
+ // result=((T_high+l)+C1r)+((D+T_low)+r*P18)
+ (p6) fma.s0 f8=f13,f1,f8
+ // return
+ br.ret.sptk b0;;
+}
+
+
+SPECIAL_log2l:
+{.mfi
+ nop.m 0
+ mov FR_X=f8
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // x=+Infinity ?
+ fclass.m p7,p0=f8,0x21
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // x=+/-Zero ?
+ fclass.m p8,p0=f7,0x7
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ // x=-Infinity, -normal, -denormal ?
+ fclass.m p6,p0=f8,0x3a
+ nop.i 0;;
+}
+{.mfb
+ nop.m 0
+ // log2l(+Infinity)=+Infinity
+ nop.f 0
+ (p7) br.ret.spnt b0;;
+}
+{.mfi
+ (p8) mov GR_Parameter_TAG = 168
+ // log2l(+/-0)=-infinity, raises Divide by Zero
+ // set f8=-0
+ (p8) fmerge.ns f8=f0,f8
+ nop.i 0;;
+}
+{.mfb
+ nop.m 0
+ (p8) frcpa.s0 f8,p0=f1,f8
+ (p8) br.cond.sptk __libm_error_region;;
+}
+{.mfb
+ (p6) mov GR_Parameter_TAG = 169
+ // x<0: return NaN, raise Invalid
+ (p6) frcpa.s0 f8,p0=f0,f0
+ (p6) br.cond.sptk __libm_error_region;;
+}
+
+
+{.mfb
+ nop.m 0
+ // Remaining cases: NaNs
+ fma.s0 f8=f8,f1,f0
+ br.ret.sptk b0;;
+}
+
+LOG2_PSEUDO_ZERO:
+
+{.mfi
+ nop.m 0
+ mov FR_X=f8
+ nop.i 0
+}
+{.mfi
+ mov GR_Parameter_TAG = 168
+ // log2l(+/-0)=-infinity, raises Divide by Zero
+ // set f8=-0
+ fmerge.ns f8=f0,f8
+ nop.i 0;;
+}
+{.mfb
+ nop.m 0
+ frcpa.s0 f8,p0=f1,f8
+ br.cond.sptk __libm_error_region;;
+}
+
+
+GLOBAL_IEEE754_END(log2l)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_logf.S b/libc/sysdeps/ia64/fpu/e_logf.S
new file mode 100644
index 000000000..3d11a296c
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_logf.S
@@ -0,0 +1,1159 @@
+.file "logf.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 03/01/00 Initial version
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 01/10/01 Improved speed, fixed flags for neg denormals
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 05/23/02 Modified algorithm. Now only one polynomial is used
+// for |x-1| >= 1/256 and for |x-1| < 1/256
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// float logf(float)
+// float log10f(float)
+//
+//
+// Overview of operation
+//==============================================================
+// Background
+// ----------
+//
+// This algorithm is based on fact that
+// log(a b) = log(a) + log(b).
+//
+// In our case we have x = 2^N f, where 1 <= f < 2.
+// So
+// log(x) = log(2^N f) = log(2^N) + log(f) = n*log(2) + log(f)
+//
+// To calculate log(f) we do following
+// log(f) = log(f * frcpa(f) / frcpa(f)) =
+// = log(f * frcpa(f)) + log(1/frcpa(f))
+//
+// According to definition of IA-64's frcpa instruction it's a
+// floating point that approximates 1/f using a lookup on the
+// top of 8 bits of the input number's significand with relative
+// error < 2^(-8.886). So we have following
+//
+// |(1/f - frcpa(f)) / (1/f))| = |1 - f*frcpa(f)| < 1/256
+//
+// and
+//
+// log(f) = log(f * frcpa(f)) + log(1/frcpa(f)) =
+// = log(1 + r) + T
+//
+// The first value can be computed by polynomial P(r) approximating
+// log(1 + r) on |r| < 1/256 and the second is precomputed tabular
+// value defined by top 8 bit of f.
+//
+// Finally we have that log(x) ~ (N*log(2) + T) + P(r)
+//
+// Note that if input argument is close to 1.0 (in our case it means
+// that |1 - x| < 1/256) we can use just polynomial approximation
+// because x = 2^0 * f = f = 1 + r and
+// log(x) = log(1 + r) ~ P(r)
+//
+//
+// To compute log10(x) we just use identity:
+//
+// log10(x) = log(x)/log(10)
+//
+// so we have that
+//
+// log10(x) = (N*log(2) + T + log(1+r)) / log(10) =
+// = N*(log(2)/log(10)) + (T/log(10)) + log(1 + r)/log(10)
+//
+//
+// Implementation
+// --------------
+// It can be seen that formulas for log and log10 differ from one another
+// only by coefficients and tabular values. Namely as log as log10 are
+// calculated as (N*L1 + T) + L2*Series(r) where in case of log
+// L1 = log(2)
+// T = log(1/frcpa(x))
+// L2 = 1.0
+// and in case of log10
+// L1 = log(2)/log(10)
+// T = log(1/frcpa(x))/log(10)
+// L2 = 1.0/log(10)
+//
+// So common code with two different entry points those set pointers
+// to the base address of coresponding data sets containing values
+// of L2,T and prepare integer representation of L1 needed for following
+// setf instruction can be used.
+//
+// Note that both log and log10 use common approximation polynomial
+// it means we need only one set of coefficients of approximation.
+//
+// 1. Computation of log(x) for |x-1| >= 1/256
+// InvX = frcpa(x)
+// r = InvX*x - 1
+// P(r) = r*((1 - A2*r) + r^2*(A3 - A4*r)) = r*P2(r),
+// A4,A3,A2 are created with setf inctruction.
+// We use Taylor series and so A4 = 1/4, A3 = 1/3,
+// A2 = 1/2 rounded to double.
+//
+// N = float(n) where n is true unbiased exponent of x
+//
+// T is tabular value of log(1/frcpa(x)) calculated in quad precision
+// and rounded to double. To T we get bits from 55 to 62 of register
+// format significand of x and calculate address
+// ad_T = table_base_addr + 8 * index
+//
+// L2 (1.0 or 1.0/log(10) depending on function) is calculated in quad
+// precision and rounded to double; it's loaded from memory
+//
+// L1 (log(2) or log10(2) depending on function) is calculated in quad
+// precision and rounded to double; it's created with setf.
+//
+// And final result = P2(r)*(r*L2) + (T + N*L1)
+//
+//
+// 2. Computation of log(x) for |x-1| < 1/256
+// r = x - 1
+// P(r) = r*((1 - A2*r) + r^2*(A3 - A4*r)) = r*P2(r),
+// A4,A3,A2 are the same as in case |x-1| >= 1/256
+//
+// And final result = P2(r)*(r*L2)
+//
+// 3. How we define is input argument such that |x-1| < 1/256 or not.
+//
+// To do it we analyze biased exponent and significand of input argment.
+//
+// a) First we test is biased exponent equal to 0xFFFE or 0xFFFF (i.e.
+// we test is 0.5 <= x < 2). This comparison can be performed using
+// unsigned version of cmp instruction in such a way
+// biased_exponent_of_x - 0xFFFE < 2
+//
+//
+// b) Second (in case when result of a) is true) we need to compare x
+// with 1-1/256 and 1+1/256 or in register format representation with
+// 0xFFFEFF00000000000000 and 0xFFFF8080000000000000 correspondingly.
+// As far as biased exponent of x here can be equal only to 0xFFFE or
+// 0xFFFF we need to test only last bit of it. Also signifigand always
+// has implicit bit set to 1 that can be exluded from comparison.
+// Thus it's quite enough to generate 64-bit integer bits of that are
+// ix[63] = biased_exponent_of_x[0] and ix[62-0] = significand_of_x[62-0]
+// and compare it with 0x7F00000000000000 and 0x80800000000000000 (those
+// obtained like ix from register representatinos of 255/256 and
+// 257/256). This comparison can be made like in a), using unsigned
+// version of cmp i.e. ix - 0x7F00000000000000 < 0x0180000000000000.
+// 0x0180000000000000 is difference between 0x80800000000000000 and
+// 0x7F00000000000000.
+//
+// Note: NaT, any NaNs, +/-INF, +/-0, negatives and unnormalized numbers are
+// filtered and processed on special branches.
+//
+//
+// Special values
+//==============================================================
+//
+// logf(+0) = -inf
+// logf(-0) = -inf
+//
+// logf(+qnan) = +qnan
+// logf(-qnan) = -qnan
+// logf(+snan) = +qnan
+// logf(-snan) = -qnan
+//
+// logf(-n) = QNAN Indefinite
+// logf(-inf) = QNAN Indefinite
+//
+// logf(+inf) = +inf
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f12 -> f14, f33 -> f39
+//
+// General registers used:
+// r8 -> r11
+// r14 -> r19
+//
+// Predicate registers used:
+// p6 -> p12
+
+
+// Assembly macros
+//==============================================================
+
+GR_TAG = r8
+GR_ad_T = r8
+GR_N = r9
+GR_Exp = r10
+GR_Sig = r11
+
+GR_025 = r14
+GR_05 = r15
+GR_A3 = r16
+GR_Ind = r17
+GR_dx = r15
+GR_Ln2 = r19
+GR_de = r20
+GR_x = r21
+GR_xorg = r22
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+FR_A2 = f12
+FR_A3 = f13
+FR_A4 = f14
+
+FR_RcpX = f33
+FR_r = f34
+FR_r2 = f35
+FR_tmp = f35
+FR_Ln2 = f36
+FR_T = f37
+FR_N = f38
+FR_NxLn2pT = f38
+FR_NormX = f39
+FR_InvLn10 = f40
+
+
+FR_Y = f1
+FR_X = f10
+FR_RESULT = f8
+
+
+// Data tables
+//==============================================================
+RODATA
+.align 16
+LOCAL_OBJECT_START(logf_data)
+data8 0x3FF0000000000000 // 1.0
+//
+// ln(1/frcpa(1+i/256)), i=0...255
+data8 0x3F60040155D5889E // 0
+data8 0x3F78121214586B54 // 1
+data8 0x3F841929F96832F0 // 2
+data8 0x3F8C317384C75F06 // 3
+data8 0x3F91A6B91AC73386 // 4
+data8 0x3F95BA9A5D9AC039 // 5
+data8 0x3F99D2A8074325F4 // 6
+data8 0x3F9D6B2725979802 // 7
+data8 0x3FA0C58FA19DFAAA // 8
+data8 0x3FA2954C78CBCE1B // 9
+data8 0x3FA4A94D2DA96C56 // 10
+data8 0x3FA67C94F2D4BB58 // 11
+data8 0x3FA85188B630F068 // 12
+data8 0x3FAA6B8ABE73AF4C // 13
+data8 0x3FAC441E06F72A9E // 14
+data8 0x3FAE1E6713606D07 // 15
+data8 0x3FAFFA6911AB9301 // 16
+data8 0x3FB0EC139C5DA601 // 17
+data8 0x3FB1DBD2643D190B // 18
+data8 0x3FB2CC7284FE5F1C // 19
+data8 0x3FB3BDF5A7D1EE64 // 20
+data8 0x3FB4B05D7AA012E0 // 21
+data8 0x3FB580DB7CEB5702 // 22
+data8 0x3FB674F089365A7A // 23
+data8 0x3FB769EF2C6B568D // 24
+data8 0x3FB85FD927506A48 // 25
+data8 0x3FB9335E5D594989 // 26
+data8 0x3FBA2B0220C8E5F5 // 27
+data8 0x3FBB0004AC1A86AC // 28
+data8 0x3FBBF968769FCA11 // 29
+data8 0x3FBCCFEDBFEE13A8 // 30
+data8 0x3FBDA727638446A2 // 31
+data8 0x3FBEA3257FE10F7A // 32
+data8 0x3FBF7BE9FEDBFDE6 // 33
+data8 0x3FC02AB352FF25F4 // 34
+data8 0x3FC097CE579D204D // 35
+data8 0x3FC1178E8227E47C // 36
+data8 0x3FC185747DBECF34 // 37
+data8 0x3FC1F3B925F25D41 // 38
+data8 0x3FC2625D1E6DDF57 // 39
+data8 0x3FC2D1610C86813A // 40
+data8 0x3FC340C59741142E // 41
+data8 0x3FC3B08B6757F2A9 // 42
+data8 0x3FC40DFB08378003 // 43
+data8 0x3FC47E74E8CA5F7C // 44
+data8 0x3FC4EF51F6466DE4 // 45
+data8 0x3FC56092E02BA516 // 46
+data8 0x3FC5D23857CD74D5 // 47
+data8 0x3FC6313A37335D76 // 48
+data8 0x3FC6A399DABBD383 // 49
+data8 0x3FC70337DD3CE41B // 50
+data8 0x3FC77654128F6127 // 51
+data8 0x3FC7E9D82A0B022D // 52
+data8 0x3FC84A6B759F512F // 53
+data8 0x3FC8AB47D5F5A310 // 54
+data8 0x3FC91FE49096581B // 55
+data8 0x3FC981634011AA75 // 56
+data8 0x3FC9F6C407089664 // 57
+data8 0x3FCA58E729348F43 // 58
+data8 0x3FCABB55C31693AD // 59
+data8 0x3FCB1E104919EFD0 // 60
+data8 0x3FCB94EE93E367CB // 61
+data8 0x3FCBF851C067555F // 62
+data8 0x3FCC5C0254BF23A6 // 63
+data8 0x3FCCC000C9DB3C52 // 64
+data8 0x3FCD244D99C85674 // 65
+data8 0x3FCD88E93FB2F450 // 66
+data8 0x3FCDEDD437EAEF01 // 67
+data8 0x3FCE530EFFE71012 // 68
+data8 0x3FCEB89A1648B971 // 69
+data8 0x3FCF1E75FADF9BDE // 70
+data8 0x3FCF84A32EAD7C35 // 71
+data8 0x3FCFEB2233EA07CD // 72
+data8 0x3FD028F9C7035C1C // 73
+data8 0x3FD05C8BE0D9635A // 74
+data8 0x3FD085EB8F8AE797 // 75
+data8 0x3FD0B9C8E32D1911 // 76
+data8 0x3FD0EDD060B78081 // 77
+data8 0x3FD122024CF0063F // 78
+data8 0x3FD14BE2927AECD4 // 79
+data8 0x3FD180618EF18ADF // 80
+data8 0x3FD1B50BBE2FC63B // 81
+data8 0x3FD1DF4CC7CF242D // 82
+data8 0x3FD214456D0EB8D4 // 83
+data8 0x3FD23EC5991EBA49 // 84
+data8 0x3FD2740D9F870AFB // 85
+data8 0x3FD29ECDABCDFA04 // 86
+data8 0x3FD2D46602ADCCEE // 87
+data8 0x3FD2FF66B04EA9D4 // 88
+data8 0x3FD335504B355A37 // 89
+data8 0x3FD360925EC44F5D // 90
+data8 0x3FD38BF1C3337E75 // 91
+data8 0x3FD3C25277333184 // 92
+data8 0x3FD3EDF463C1683E // 93
+data8 0x3FD419B423D5E8C7 // 94
+data8 0x3FD44591E0539F49 // 95
+data8 0x3FD47C9175B6F0AD // 96
+data8 0x3FD4A8B341552B09 // 97
+data8 0x3FD4D4F3908901A0 // 98
+data8 0x3FD501528DA1F968 // 99
+data8 0x3FD52DD06347D4F6 // 100
+data8 0x3FD55A6D3C7B8A8A // 101
+data8 0x3FD5925D2B112A59 // 102
+data8 0x3FD5BF406B543DB2 // 103
+data8 0x3FD5EC433D5C35AE // 104
+data8 0x3FD61965CDB02C1F // 105
+data8 0x3FD646A84935B2A2 // 106
+data8 0x3FD6740ADD31DE94 // 107
+data8 0x3FD6A18DB74A58C5 // 108
+data8 0x3FD6CF31058670EC // 109
+data8 0x3FD6F180E852F0BA // 110
+data8 0x3FD71F5D71B894F0 // 111
+data8 0x3FD74D5AEFD66D5C // 112
+data8 0x3FD77B79922BD37E // 113
+data8 0x3FD7A9B9889F19E2 // 114
+data8 0x3FD7D81B037EB6A6 // 115
+data8 0x3FD8069E33827231 // 116
+data8 0x3FD82996D3EF8BCB // 117
+data8 0x3FD85855776DCBFB // 118
+data8 0x3FD8873658327CCF // 119
+data8 0x3FD8AA75973AB8CF // 120
+data8 0x3FD8D992DC8824E5 // 121
+data8 0x3FD908D2EA7D9512 // 122
+data8 0x3FD92C59E79C0E56 // 123
+data8 0x3FD95BD750EE3ED3 // 124
+data8 0x3FD98B7811A3EE5B // 125
+data8 0x3FD9AF47F33D406C // 126
+data8 0x3FD9DF270C1914A8 // 127
+data8 0x3FDA0325ED14FDA4 // 128
+data8 0x3FDA33440224FA79 // 129
+data8 0x3FDA57725E80C383 // 130
+data8 0x3FDA87D0165DD199 // 131
+data8 0x3FDAAC2E6C03F896 // 132
+data8 0x3FDADCCC6FDF6A81 // 133
+data8 0x3FDB015B3EB1E790 // 134
+data8 0x3FDB323A3A635948 // 135
+data8 0x3FDB56FA04462909 // 136
+data8 0x3FDB881AA659BC93 // 137
+data8 0x3FDBAD0BEF3DB165 // 138
+data8 0x3FDBD21297781C2F // 139
+data8 0x3FDC039236F08819 // 140
+data8 0x3FDC28CB1E4D32FD // 141
+data8 0x3FDC4E19B84723C2 // 142
+data8 0x3FDC7FF9C74554C9 // 143
+data8 0x3FDCA57B64E9DB05 // 144
+data8 0x3FDCCB130A5CEBB0 // 145
+data8 0x3FDCF0C0D18F326F // 146
+data8 0x3FDD232075B5A201 // 147
+data8 0x3FDD490246DEFA6B // 148
+data8 0x3FDD6EFA918D25CD // 149
+data8 0x3FDD9509707AE52F // 150
+data8 0x3FDDBB2EFE92C554 // 151
+data8 0x3FDDEE2F3445E4AF // 152
+data8 0x3FDE148A1A2726CE // 153
+data8 0x3FDE3AFC0A49FF40 // 154
+data8 0x3FDE6185206D516E // 155
+data8 0x3FDE882578823D52 // 156
+data8 0x3FDEAEDD2EAC990C // 157
+data8 0x3FDED5AC5F436BE3 // 158
+data8 0x3FDEFC9326D16AB9 // 159
+data8 0x3FDF2391A2157600 // 160
+data8 0x3FDF4AA7EE03192D // 161
+data8 0x3FDF71D627C30BB0 // 162
+data8 0x3FDF991C6CB3B379 // 163
+data8 0x3FDFC07ADA69A910 // 164
+data8 0x3FDFE7F18EB03D3E // 165
+data8 0x3FE007C053C5002E // 166
+data8 0x3FE01B942198A5A1 // 167
+data8 0x3FE02F74400C64EB // 168
+data8 0x3FE04360BE7603AD // 169
+data8 0x3FE05759AC47FE34 // 170
+data8 0x3FE06B5F1911CF52 // 171
+data8 0x3FE078BF0533C568 // 172
+data8 0x3FE08CD9687E7B0E // 173
+data8 0x3FE0A10074CF9019 // 174
+data8 0x3FE0B5343A234477 // 175
+data8 0x3FE0C974C89431CE // 176
+data8 0x3FE0DDC2305B9886 // 177
+data8 0x3FE0EB524BAFC918 // 178
+data8 0x3FE0FFB54213A476 // 179
+data8 0x3FE114253DA97D9F // 180
+data8 0x3FE128A24F1D9AFF // 181
+data8 0x3FE1365252BF0865 // 182
+data8 0x3FE14AE558B4A92D // 183
+data8 0x3FE15F85A19C765B // 184
+data8 0x3FE16D4D38C119FA // 185
+data8 0x3FE18203C20DD133 // 186
+data8 0x3FE196C7BC4B1F3B // 187
+data8 0x3FE1A4A738B7A33C // 188
+data8 0x3FE1B981C0C9653D // 189
+data8 0x3FE1CE69E8BB106B // 190
+data8 0x3FE1DC619DE06944 // 191
+data8 0x3FE1F160A2AD0DA4 // 192
+data8 0x3FE2066D7740737E // 193
+data8 0x3FE2147DBA47A394 // 194
+data8 0x3FE229A1BC5EBAC3 // 195
+data8 0x3FE237C1841A502E // 196
+data8 0x3FE24CFCE6F80D9A // 197
+data8 0x3FE25B2C55CD5762 // 198
+data8 0x3FE2707F4D5F7C41 // 199
+data8 0x3FE285E0842CA384 // 200
+data8 0x3FE294294708B773 // 201
+data8 0x3FE2A9A2670AFF0C // 202
+data8 0x3FE2B7FB2C8D1CC1 // 203
+data8 0x3FE2C65A6395F5F5 // 204
+data8 0x3FE2DBF557B0DF43 // 205
+data8 0x3FE2EA64C3F97655 // 206
+data8 0x3FE3001823684D73 // 207
+data8 0x3FE30E97E9A8B5CD // 208
+data8 0x3FE32463EBDD34EA // 209
+data8 0x3FE332F4314AD796 // 210
+data8 0x3FE348D90E7464D0 // 211
+data8 0x3FE35779F8C43D6E // 212
+data8 0x3FE36621961A6A99 // 213
+data8 0x3FE37C299F3C366A // 214
+data8 0x3FE38AE2171976E7 // 215
+data8 0x3FE399A157A603E7 // 216
+data8 0x3FE3AFCCFE77B9D1 // 217
+data8 0x3FE3BE9D503533B5 // 218
+data8 0x3FE3CD7480B4A8A3 // 219
+data8 0x3FE3E3C43918F76C // 220
+data8 0x3FE3F2ACB27ED6C7 // 221
+data8 0x3FE4019C2125CA93 // 222
+data8 0x3FE4181061389722 // 223
+data8 0x3FE42711518DF545 // 224
+data8 0x3FE436194E12B6BF // 225
+data8 0x3FE445285D68EA69 // 226
+data8 0x3FE45BCC464C893A // 227
+data8 0x3FE46AED21F117FC // 228
+data8 0x3FE47A1527E8A2D3 // 229
+data8 0x3FE489445EFFFCCC // 230
+data8 0x3FE4A018BCB69835 // 231
+data8 0x3FE4AF5A0C9D65D7 // 232
+data8 0x3FE4BEA2A5BDBE87 // 233
+data8 0x3FE4CDF28F10AC46 // 234
+data8 0x3FE4DD49CF994058 // 235
+data8 0x3FE4ECA86E64A684 // 236
+data8 0x3FE503C43CD8EB68 // 237
+data8 0x3FE513356667FC57 // 238
+data8 0x3FE522AE0738A3D8 // 239
+data8 0x3FE5322E26867857 // 240
+data8 0x3FE541B5CB979809 // 241
+data8 0x3FE55144FDBCBD62 // 242
+data8 0x3FE560DBC45153C7 // 243
+data8 0x3FE5707A26BB8C66 // 244
+data8 0x3FE587F60ED5B900 // 245
+data8 0x3FE597A7977C8F31 // 246
+data8 0x3FE5A760D634BB8B // 247
+data8 0x3FE5B721D295F10F // 248
+data8 0x3FE5C6EA94431EF9 // 249
+data8 0x3FE5D6BB22EA86F6 // 250
+data8 0x3FE5E6938645D390 // 251
+data8 0x3FE5F673C61A2ED2 // 252
+data8 0x3FE6065BEA385926 // 253
+data8 0x3FE6164BFA7CC06B // 254
+data8 0x3FE62643FECF9743 // 255
+LOCAL_OBJECT_END(logf_data)
+
+LOCAL_OBJECT_START(log10f_data)
+data8 0x3FDBCB7B1526E50E // 1/ln(10)
+//
+// ln(1/frcpa(1+i/256))/ln(10), i=0...255
+data8 0x3F4BD27045BFD025 // 0
+data8 0x3F64E84E793A474A // 1
+data8 0x3F7175085AB85FF0 // 2
+data8 0x3F787CFF9D9147A5 // 3
+data8 0x3F7EA9D372B89FC8 // 4
+data8 0x3F82DF9D95DA961C // 5
+data8 0x3F866DF172D6372C // 6
+data8 0x3F898D79EF5EEDF0 // 7
+data8 0x3F8D22ADF3F9579D // 8
+data8 0x3F9024231D30C398 // 9
+data8 0x3F91F23A98897D4A // 10
+data8 0x3F93881A7B818F9E // 11
+data8 0x3F951F6E1E759E35 // 12
+data8 0x3F96F2BCE7ADC5B4 // 13
+data8 0x3F988D362CDF359E // 14
+data8 0x3F9A292BAF010982 // 15
+data8 0x3F9BC6A03117EB97 // 16
+data8 0x3F9D65967DE3AB09 // 17
+data8 0x3F9F061167FC31E8 // 18
+data8 0x3FA05409E4F7819C // 19
+data8 0x3FA125D0432EA20E // 20
+data8 0x3FA1F85D440D299B // 21
+data8 0x3FA2AD755749617D // 22
+data8 0x3FA381772A00E604 // 23
+data8 0x3FA45643E165A70B // 24
+data8 0x3FA52BDD034475B8 // 25
+data8 0x3FA5E3966B7E9295 // 26
+data8 0x3FA6BAAF47C5B245 // 27
+data8 0x3FA773B3E8C4F3C8 // 28
+data8 0x3FA84C51EBEE8D15 // 29
+data8 0x3FA906A6786FC1CB // 30
+data8 0x3FA9C197ABF00DD7 // 31
+data8 0x3FAA9C78712191F7 // 32
+data8 0x3FAB58C09C8D637C // 33
+data8 0x3FAC15A8BCDD7B7E // 34
+data8 0x3FACD331E2C2967C // 35
+data8 0x3FADB11ED766ABF4 // 36
+data8 0x3FAE70089346A9E6 // 37
+data8 0x3FAF2F96C6754AEE // 38
+data8 0x3FAFEFCA8D451FD6 // 39
+data8 0x3FB0585283764178 // 40
+data8 0x3FB0B913AAC7D3A7 // 41
+data8 0x3FB11A294F2569F6 // 42
+data8 0x3FB16B51A2696891 // 43
+data8 0x3FB1CD03ADACC8BE // 44
+data8 0x3FB22F0BDD7745F5 // 45
+data8 0x3FB2916ACA38D1E8 // 46
+data8 0x3FB2F4210DF7663D // 47
+data8 0x3FB346A6C3C49066 // 48
+data8 0x3FB3A9FEBC60540A // 49
+data8 0x3FB3FD0C10A3AA54 // 50
+data8 0x3FB46107D3540A82 // 51
+data8 0x3FB4C55DD16967FE // 52
+data8 0x3FB51940330C000B // 53
+data8 0x3FB56D620EE7115E // 54
+data8 0x3FB5D2ABCF26178E // 55
+data8 0x3FB6275AA5DEBF81 // 56
+data8 0x3FB68D4EAF26D7EE // 57
+data8 0x3FB6E28C5C54A28D // 58
+data8 0x3FB7380B9665B7C8 // 59
+data8 0x3FB78DCCC278E85B // 60
+data8 0x3FB7F50C2CF2557A // 61
+data8 0x3FB84B5FD5EAEFD8 // 62
+data8 0x3FB8A1F6BAB2B226 // 63
+data8 0x3FB8F8D144557BDF // 64
+data8 0x3FB94FEFDCD61D92 // 65
+data8 0x3FB9A752EF316149 // 66
+data8 0x3FB9FEFAE7611EE0 // 67
+data8 0x3FBA56E8325F5C87 // 68
+data8 0x3FBAAF1B3E297BB4 // 69
+data8 0x3FBB079479C372AD // 70
+data8 0x3FBB6054553B12F7 // 71
+data8 0x3FBBB95B41AB5CE6 // 72
+data8 0x3FBC12A9B13FE079 // 73
+data8 0x3FBC6C4017382BEA // 74
+data8 0x3FBCB41FBA42686D // 75
+data8 0x3FBD0E38CE73393F // 76
+data8 0x3FBD689B2193F133 // 77
+data8 0x3FBDC3472B1D2860 // 78
+data8 0x3FBE0C06300D528B // 79
+data8 0x3FBE6738190E394C // 80
+data8 0x3FBEC2B50D208D9B // 81
+data8 0x3FBF0C1C2B936828 // 82
+data8 0x3FBF68216C9CC727 // 83
+data8 0x3FBFB1F6381856F4 // 84
+data8 0x3FC00742AF4CE5F8 // 85
+data8 0x3FC02C64906512D2 // 86
+data8 0x3FC05AF1E63E03B4 // 87
+data8 0x3FC0804BEA723AA9 // 88
+data8 0x3FC0AF1FD6711527 // 89
+data8 0x3FC0D4B2A8805A00 // 90
+data8 0x3FC0FA5EF136A06C // 91
+data8 0x3FC1299A4FB3E306 // 92
+data8 0x3FC14F806253C3ED // 93
+data8 0x3FC175805D1587C1 // 94
+data8 0x3FC19B9A637CA295 // 95
+data8 0x3FC1CB5FC26EDE17 // 96
+data8 0x3FC1F1B4E65F2590 // 97
+data8 0x3FC218248B5DC3E5 // 98
+data8 0x3FC23EAED62ADC76 // 99
+data8 0x3FC26553EBD337BD // 100
+data8 0x3FC28C13F1B11900 // 101
+data8 0x3FC2BCAA14381386 // 102
+data8 0x3FC2E3A740B7800F // 103
+data8 0x3FC30ABFD8F333B6 // 104
+data8 0x3FC331F403985097 // 105
+data8 0x3FC35943E7A60690 // 106
+data8 0x3FC380AFAC6E7C07 // 107
+data8 0x3FC3A8377997B9E6 // 108
+data8 0x3FC3CFDB771C9ADB // 109
+data8 0x3FC3EDA90D39A5DF // 110
+data8 0x3FC4157EC09505CD // 111
+data8 0x3FC43D7113FB04C1 // 112
+data8 0x3FC4658030AD1CCF // 113
+data8 0x3FC48DAC404638F6 // 114
+data8 0x3FC4B5F56CBBB869 // 115
+data8 0x3FC4DE5BE05E7583 // 116
+data8 0x3FC4FCBC0776FD85 // 117
+data8 0x3FC525561E9256EE // 118
+data8 0x3FC54E0DF3198865 // 119
+data8 0x3FC56CAB7112BDE2 // 120
+data8 0x3FC59597BA735B15 // 121
+data8 0x3FC5BEA23A506FDA // 122
+data8 0x3FC5DD7E08DE382F // 123
+data8 0x3FC606BDD3F92355 // 124
+data8 0x3FC6301C518A501F // 125
+data8 0x3FC64F3770618916 // 126
+data8 0x3FC678CC14C1E2D8 // 127
+data8 0x3FC6981005ED2947 // 128
+data8 0x3FC6C1DB5F9BB336 // 129
+data8 0x3FC6E1488ECD2881 // 130
+data8 0x3FC70B4B2E7E41B9 // 131
+data8 0x3FC72AE209146BF9 // 132
+data8 0x3FC7551C81BD8DCF // 133
+data8 0x3FC774DD76CC43BE // 134
+data8 0x3FC79F505DB00E88 // 135
+data8 0x3FC7BF3BDE099F30 // 136
+data8 0x3FC7E9E7CAC437F9 // 137
+data8 0x3FC809FE4902D00D // 138
+data8 0x3FC82A2757995CBE // 139
+data8 0x3FC85525C625E098 // 140
+data8 0x3FC8757A79831887 // 141
+data8 0x3FC895E2058D8E03 // 142
+data8 0x3FC8C13437695532 // 143
+data8 0x3FC8E1C812EF32BE // 144
+data8 0x3FC9026F112197E8 // 145
+data8 0x3FC923294888880B // 146
+data8 0x3FC94EEA4B8334F3 // 147
+data8 0x3FC96FD1B639FC09 // 148
+data8 0x3FC990CCA66229AC // 149
+data8 0x3FC9B1DB33334843 // 150
+data8 0x3FC9D2FD740E6607 // 151
+data8 0x3FC9FF49EEDCB553 // 152
+data8 0x3FCA209A84FBCFF8 // 153
+data8 0x3FCA41FF1E43F02B // 154
+data8 0x3FCA6377D2CE9378 // 155
+data8 0x3FCA8504BAE0D9F6 // 156
+data8 0x3FCAA6A5EEEBEFE3 // 157
+data8 0x3FCAC85B878D7879 // 158
+data8 0x3FCAEA259D8FFA0B // 159
+data8 0x3FCB0C0449EB4B6B // 160
+data8 0x3FCB2DF7A5C50299 // 161
+data8 0x3FCB4FFFCA70E4D1 // 162
+data8 0x3FCB721CD17157E3 // 163
+data8 0x3FCB944ED477D4ED // 164
+data8 0x3FCBB695ED655C7D // 165
+data8 0x3FCBD8F2364AEC0F // 166
+data8 0x3FCBFB63C969F4FF // 167
+data8 0x3FCC1DEAC134D4E9 // 168
+data8 0x3FCC4087384F4F80 // 169
+data8 0x3FCC6339498F09E2 // 170
+data8 0x3FCC86010FFC076C // 171
+data8 0x3FCC9D3D065C5B42 // 172
+data8 0x3FCCC029375BA07A // 173
+data8 0x3FCCE32B66978BA4 // 174
+data8 0x3FCD0643AFD51404 // 175
+data8 0x3FCD29722F0DEA45 // 176
+data8 0x3FCD4CB70070FE44 // 177
+data8 0x3FCD6446AB3F8C96 // 178
+data8 0x3FCD87B0EF71DB45 // 179
+data8 0x3FCDAB31D1FE99A7 // 180
+data8 0x3FCDCEC96FDC888F // 181
+data8 0x3FCDE6908876357A // 182
+data8 0x3FCE0A4E4A25C200 // 183
+data8 0x3FCE2E2315755E33 // 184
+data8 0x3FCE461322D1648A // 185
+data8 0x3FCE6A0E95C7787B // 186
+data8 0x3FCE8E216243DD60 // 187
+data8 0x3FCEA63AF26E007C // 188
+data8 0x3FCECA74ED15E0B7 // 189
+data8 0x3FCEEEC692CCD25A // 190
+data8 0x3FCF070A36B8D9C1 // 191
+data8 0x3FCF2B8393E34A2D // 192
+data8 0x3FCF5014EF538A5B // 193
+data8 0x3FCF68833AF1B180 // 194
+data8 0x3FCF8D3CD9F3F04F // 195
+data8 0x3FCFA5C61ADD93E9 // 196
+data8 0x3FCFCAA8567EBA7A // 197
+data8 0x3FCFE34CC8743DD8 // 198
+data8 0x3FD0042BFD74F519 // 199
+data8 0x3FD016BDF6A18017 // 200
+data8 0x3FD023262F907322 // 201
+data8 0x3FD035CCED8D32A1 // 202
+data8 0x3FD042430E869FFC // 203
+data8 0x3FD04EBEC842B2E0 // 204
+data8 0x3FD06182E84FD4AC // 205
+data8 0x3FD06E0CB609D383 // 206
+data8 0x3FD080E60BEC8F12 // 207
+data8 0x3FD08D7E0D894735 // 208
+data8 0x3FD0A06CC96A2056 // 209
+data8 0x3FD0AD131F3B3C55 // 210
+data8 0x3FD0C01771E775FB // 211
+data8 0x3FD0CCCC3CAD6F4B // 212
+data8 0x3FD0D986D91A34A9 // 213
+data8 0x3FD0ECA9B8861A2D // 214
+data8 0x3FD0F972F87FF3D6 // 215
+data8 0x3FD106421CF0E5F7 // 216
+data8 0x3FD11983EBE28A9D // 217
+data8 0x3FD12661E35B785A // 218
+data8 0x3FD13345D2779D3B // 219
+data8 0x3FD146A6F597283A // 220
+data8 0x3FD15399E81EA83D // 221
+data8 0x3FD16092E5D3A9A6 // 222
+data8 0x3FD17413C3B7AB5E // 223
+data8 0x3FD1811BF629D6FB // 224
+data8 0x3FD18E2A47B46686 // 225
+data8 0x3FD19B3EBE1A4418 // 226
+data8 0x3FD1AEE9017CB450 // 227
+data8 0x3FD1BC0CED7134E2 // 228
+data8 0x3FD1C93712ABC7FF // 229
+data8 0x3FD1D66777147D3F // 230
+data8 0x3FD1EA3BD1286E1C // 231
+data8 0x3FD1F77BED932C4C // 232
+data8 0x3FD204C25E1B031F // 233
+data8 0x3FD2120F28CE69B1 // 234
+data8 0x3FD21F6253C48D01 // 235
+data8 0x3FD22CBBE51D60AA // 236
+data8 0x3FD240CE4C975444 // 237
+data8 0x3FD24E37F8ECDAE8 // 238
+data8 0x3FD25BA8215AF7FC // 239
+data8 0x3FD2691ECC29F042 // 240
+data8 0x3FD2769BFFAB2E00 // 241
+data8 0x3FD2841FC23952C9 // 242
+data8 0x3FD291AA1A384978 // 243
+data8 0x3FD29F3B0E15584B // 244
+data8 0x3FD2B3A0EE479DF7 // 245
+data8 0x3FD2C142842C09E6 // 246
+data8 0x3FD2CEEACCB7BD6D // 247
+data8 0x3FD2DC99CE82FF21 // 248
+data8 0x3FD2EA4F902FD7DA // 249
+data8 0x3FD2F80C186A25FD // 250
+data8 0x3FD305CF6DE7B0F7 // 251
+data8 0x3FD3139997683CE7 // 252
+data8 0x3FD3216A9BB59E7C // 253
+data8 0x3FD32F4281A3CEFF // 254
+data8 0x3FD33D2150110092 // 255
+LOCAL_OBJECT_END(log10f_data)
+
+
+// Code
+//==============================================================
+.section .text
+
+// logf has p13 true, p14 false
+// log10f has p14 true, p13 false
+
+GLOBAL_IEEE754_ENTRY(log10f)
+{ .mfi
+ getf.exp GR_Exp = f8 // if x is unorm then must recompute
+ frcpa.s1 FR_RcpX,p0 = f1,f8
+ mov GR_05 = 0xFFFE // biased exponent of A2=0.5
+}
+{ .mlx
+ addl GR_ad_T = @ltoff(log10f_data),gp
+ movl GR_A3 = 0x3FD5555555555555 // double precision memory
+ // representation of A3
+};;
+{ .mfi
+ getf.sig GR_Sig = f8 // if x is unorm then must recompute
+ fclass.m p8,p0 = f8,9 // is x positive unorm?
+ sub GR_025 = GR_05,r0,1 // biased exponent of A4=0.25
+}
+{ .mlx
+ ld8 GR_ad_T = [GR_ad_T]
+ movl GR_Ln2 = 0x3FD34413509F79FF // double precision memory
+ // representation of
+ // log(2)/ln(10)
+};;
+{ .mfi
+ setf.d FR_A3 = GR_A3 // create A3
+ fcmp.eq.s1 p14,p13 = f0,f0 // set p14 to 1 for log10f
+ dep.z GR_xorg = GR_05,55,8 // 0x7F00000000000000 integer number
+ // bits of that are
+ // GR_xorg[63] = last bit of biased
+ // exponent of 255/256
+ // GR_xorg[62-0] = bits from 62 to 0
+ // of significand of 255/256
+}
+{ .mib
+ setf.exp FR_A2 = GR_05 // create A2
+ sub GR_de = GR_Exp,GR_05 // biased_exponent_of_x - 0xFFFE
+ // needed to comparion with 0.5 and 2.0
+ br.cond.sptk logf_log10f_common
+};;
+GLOBAL_IEEE754_END(log10f)
+
+GLOBAL_IEEE754_ENTRY(logf)
+{ .mfi
+ getf.exp GR_Exp = f8 // if x is unorm then must recompute
+ frcpa.s1 FR_RcpX,p0 = f1,f8
+ mov GR_05 = 0xFFFE // biased exponent of A2=-0.5
+}
+{ .mlx
+ addl GR_ad_T = @ltoff(logf_data),gp
+ movl GR_A3 = 0x3FD5555555555555 // double precision memory
+ // representation of A3
+};;
+{ .mfi
+ getf.sig GR_Sig = f8 // if x is unorm then must recompute
+ fclass.m p8,p0 = f8,9 // is x positive unorm?
+ dep.z GR_xorg = GR_05,55,8 // 0x7F00000000000000 integer number
+ // bits of that are
+ // GR_xorg[63] = last bit of biased
+ // exponent of 255/256
+ // GR_xorg[62-0] = bits from 62 to 0
+ // of significand of 255/256
+}
+{ .mfi
+ ld8 GR_ad_T = [GR_ad_T]
+ nop.f 0
+ sub GR_025 = GR_05,r0,1 // biased exponent of A4=0.25
+};;
+{ .mfi
+ setf.d FR_A3 = GR_A3 // create A3
+ fcmp.eq.s1 p13,p14 = f0,f0 // p13 - true for logf
+ sub GR_de = GR_Exp,GR_05 // biased_exponent_of_x - 0xFFFE
+ // needed to comparion with 0.5 and 2.0
+}
+{ .mlx
+ setf.exp FR_A2 = GR_05 // create A2
+ movl GR_Ln2 = 0x3FE62E42FEFA39EF // double precision memory
+ // representation of log(2)
+};;
+logf_log10f_common:
+{ .mfi
+ setf.exp FR_A4 = GR_025 // create A4=0.25
+ fclass.m p9,p0 = f8,0x3A // is x < 0 (including negateve unnormals)?
+ dep GR_x = GR_Exp,GR_Sig,63,1 // produce integer that bits are
+ // GR_x[63] = GR_Exp[0]
+ // GR_x[62-0] = GR_Sig[62-0]
+}
+{ .mib
+ sub GR_N = GR_Exp,GR_05,1 // unbiased exponent of x
+ cmp.gtu p6,p7 = 2,GR_de // is 0.5 <= x < 2.0?
+(p8) br.cond.spnt logf_positive_unorm
+};;
+logf_core:
+{ .mfi
+ setf.sig FR_N = GR_N // copy unbiased exponent of x to the
+ // significand field of FR_N
+ fclass.m p10,p0 = f8,0x1E1 // is x NaN, NaT or +Inf?
+ dep.z GR_dx = GR_05,54,3 // 0x0180000000000000 - difference
+ // between our integer representations
+ // of 257/256 and 255/256
+}
+{ .mfi
+ nop.m 0
+ nop.f 0
+ sub GR_x = GR_x,GR_xorg // difference between representations
+ // of x and 255/256
+};;
+{ .mfi
+ ldfd FR_InvLn10 = [GR_ad_T],8
+ fcmp.eq.s1 p11,p0 = f8,f1 // is x equal to 1.0?
+ extr.u GR_Ind = GR_Sig,55,8 // get bits from 55 to 62 as index
+}
+{ .mib
+ setf.d FR_Ln2 = GR_Ln2 // create log(2) or log10(2)
+(p6) cmp.gtu p6,p7 = GR_dx,GR_x // set p6 if 255/256 <= x < 257/256
+(p9) br.cond.spnt logf_negatives // jump if input argument is negative number
+};;
+// p6 is true if |x-1| < 1/256
+// p7 is true if |x-1| >= 1/256
+.pred.rel "mutex",p6,p7
+{ .mfi
+ shladd GR_ad_T = GR_Ind,3,GR_ad_T // calculate address of T
+(p7) fms.s1 FR_r = FR_RcpX,f8,f1 // range reduction for |x-1|>=1/256
+ extr.u GR_Exp = GR_Exp,0,17 // exponent without sign
+}
+{ .mfb
+ nop.m 0
+(p6) fms.s1 FR_r = f8,f1,f1 // range reduction for |x-1|<1/256
+(p10) br.cond.spnt logf_nan_nat_pinf // exit for NaN, NaT or +Inf
+};;
+{ .mfb
+ ldfd FR_T = [GR_ad_T] // load T
+(p11) fma.s.s0 f8 = f0,f0,f0
+(p11) br.ret.spnt b0 // exit for x = 1.0
+};;
+{ .mib
+ nop.m 0
+ cmp.eq p12,p0 = r0,GR_Exp // is x +/-0? (here it's quite enough
+ // only to compare exponent with 0
+ // because all unnormals already
+ // have been filtered)
+(p12) br.cond.spnt logf_zeroes // Branch if input argument is +/-0
+};;
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_A2 = FR_A2,FR_r,f1 // A2*r+1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r2 = FR_r,FR_r,f0 // r^2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_N = FR_N // convert integer N in significand of FR_N
+ // to floating-point representation
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_A3 = FR_A4,FR_r,FR_A3 // A4*r+A3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r = FR_r,FR_InvLn10,f0 // For log10f we have r/log(10)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A2 = FR_A3,FR_r2,FR_A2 // (A4*r+A3)*r^2+(A2*r+1)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_NxLn2pT = FR_N,FR_Ln2,FR_T // N*Ln2+T
+ nop.i 0
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p7) fma.s.s0 f8 = FR_A2,FR_r,FR_NxLn2pT // result for |x-1|>=1/256
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p6) fma.s.s0 f8 = FR_A2,FR_r,f0 // result for |x-1|<1/256
+ br.ret.sptk b0
+};;
+
+.align 32
+logf_positive_unorm:
+{ .mfi
+ nop.m 0
+(p8) fma.s0 f8 = f8,f1,f0 // Normalize & set D-flag
+ nop.i 0
+};;
+{ .mfi
+ getf.exp GR_Exp = f8 // recompute biased exponent
+ nop.f 0
+ cmp.ne p6,p7 = r0,r0 // p6 <- 0, p7 <- 1 because
+ // in case of unorm we are out
+ // interval [255/256; 257/256]
+};;
+{ .mfi
+ getf.sig GR_Sig = f8 // recompute significand
+ nop.f 0
+ nop.i 0
+};;
+{ .mib
+ sub GR_N = GR_Exp,GR_05,1 // unbiased exponent N
+ nop.i 0
+ br.cond.sptk logf_core // return into main path
+};;
+
+.align 32
+logf_nan_nat_pinf:
+{ .mfi
+ nop.m 0
+ fma.s.s0 f8 = f8,f1,f0 // set V-flag
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+ br.ret.sptk b0 // exit for NaN, NaT or +Inf
+};;
+
+.align 32
+logf_zeroes:
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8,f8 // keep input argument for subsequent
+ // call of __libm_error_support#
+ nop.i 0
+}
+{ .mfi
+(p13) mov GR_TAG = 4 // set libm error in case of logf
+ fms.s1 FR_tmp = f0,f0,f1 // -1.0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ frcpa.s0 f8,p0 = FR_tmp,f0 // log(+/-0) should be equal to -INF.
+ // We can get it using frcpa because it
+ // sets result to the IEEE-754 mandated
+ // quotient of FR_tmp/f0.
+ // As far as FR_tmp is -1 it'll be -INF
+ nop.i 0
+}
+{ .mib
+(p14) mov GR_TAG = 10 // set libm error in case of log10f
+ nop.i 0
+ br.cond.sptk logf_libm_err
+};;
+
+.align 32
+logf_negatives:
+{ .mfi
+(p13) mov GR_TAG = 5 // set libm error in case of logf
+ fmerge.s FR_X = f8,f8 // keep input argument for subsequent
+ // call of __libm_error_support#
+ nop.i 0
+};;
+{ .mfi
+(p14) mov GR_TAG = 11 // set libm error in case of log10f
+ frcpa.s0 f8,p0 = f0,f0 // log(negatives) should be equal to NaN.
+ // We can get it using frcpa because it
+ // sets result to the IEEE-754 mandated
+ // quotient of f0/f0 i.e. NaN.
+ nop.i 0
+};;
+
+.align 32
+logf_libm_err:
+{ .mmi
+ alloc r32 = ar.pfs,1,4,4,0
+ mov GR_Parameter_TAG = GR_TAG
+ nop.i 0
+};;
+GLOBAL_IEEE754_END(logf)
+
+
+// Stack operations when calling error support.
+// (1) (2) (3) (call) (4)
+// sp -> + psp -> + psp -> + sp -> +
+// | | | |
+// | | <- GR_Y R3 ->| <- GR_RESULT | -> f8
+// | | | |
+// | <-GR_Y Y2->| Y2 ->| <- GR_Y |
+// | | | |
+// | | <- GR_X X1 ->| |
+// | | | |
+// sp-64 -> + sp -> + sp -> + +
+// save ar.pfs save b0 restore gp
+// save gp restore ar.pfs
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/e_logl.S b/libc/sysdeps/ia64/fpu/e_logl.S
new file mode 100644
index 000000000..3ebb20a63
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_logl.S
@@ -0,0 +1,1200 @@
+.file "logl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 05/21/01 Extracted logl and log10l from log1pl.s file, and optimized
+// all paths.
+// 06/20/01 Fixed error tag for x=-inf.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+//
+//*********************************************************************
+//
+//*********************************************************************
+//
+// Function: Combined logl(x) and log10l(x) where
+// logl(x) = ln(x), for double-extended precision x values
+// log10l(x) = log (x), for double-extended precision x values
+// 10
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f34-f76
+//
+// General Purpose Registers:
+// r32-r56
+// r53-r56 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6-p14
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// Denormal fault raised on denormal inputs
+// Overflow exceptions cannot occur
+// Underflow exceptions raised when appropriate for log1p
+// (Error Handling Routine called for underflow)
+// Inexact raised when appropriate by algorithm
+//
+// logl(inf) = inf
+// logl(-inf) = QNaN
+// logl(+/-0) = -inf
+// logl(SNaN) = QNaN
+// logl(QNaN) = QNaN
+// logl(EM_special Values) = QNaN
+// log10l(inf) = inf
+// log10l(-inf) = QNaN
+// log10l(+/-0) = -inf
+// log10l(SNaN) = QNaN
+// log10l(QNaN) = QNaN
+// log10l(EM_special Values) = QNaN
+//
+//*********************************************************************
+//
+// Overview
+//
+// The method consists of two cases.
+//
+// If |X-1| < 2^(-7) use case log_near1;
+// else use case log_regular;
+//
+// Case log_near1:
+//
+// logl( 1 + X ) can be approximated by a simple polynomial
+// in W = X-1. This polynomial resembles the truncated Taylor
+// series W - W^/2 + W^3/3 - ...
+//
+// Case log_regular:
+//
+// Here we use a table lookup method. The basic idea is that in
+// order to compute logl(Arg) for an argument Arg in [1,2), we
+// construct a value G such that G*Arg is close to 1 and that
+// logl(1/G) is obtainable easily from a table of values calculated
+// beforehand. Thus
+//
+// logl(Arg) = logl(1/G) + logl(G*Arg)
+// = logl(1/G) + logl(1 + (G*Arg - 1))
+//
+// Because |G*Arg - 1| is small, the second term on the right hand
+// side can be approximated by a short polynomial. We elaborate
+// this method in four steps.
+//
+// Step 0: Initialization
+//
+// We need to calculate logl( X ). Obtain N, S_hi such that
+//
+// X = 2^N * S_hi exactly
+//
+// where S_hi in [1,2)
+//
+// Step 1: Argument Reduction
+//
+// Based on S_hi, obtain G_1, G_2, G_3 from a table and calculate
+//
+// G := G_1 * G_2 * G_3
+// r := (G * S_hi - 1)
+//
+// These G_j's have the property that the product is exactly
+// representable and that |r| < 2^(-12) as a result.
+//
+// Step 2: Approximation
+//
+//
+// logl(1 + r) is approximated by a short polynomial poly(r).
+//
+// Step 3: Reconstruction
+//
+//
+// Finally, logl( X ) is given by
+//
+// logl( X ) = logl( 2^N * S_hi )
+// ~=~ N*logl(2) + logl(1/G) + logl(1 + r)
+// ~=~ N*logl(2) + logl(1/G) + poly(r).
+//
+// **** Algorithm ****
+//
+// Case log_near1:
+//
+// Here we compute a simple polynomial. To exploit parallelism, we split
+// the polynomial into two portions.
+//
+// W := X - 1
+// Wsq := W * W
+// W4 := Wsq*Wsq
+// W6 := W4*Wsq
+// Y_hi := W + Wsq*(P_1 + W*(P_2 + W*(P_3 + W*P_4))
+// Y_lo := W6*(P_5 + W*(P_6 + W*(P_7 + W*P_8)))
+//
+// Case log_regular:
+//
+// We present the algorithm in four steps.
+//
+// Step 0. Initialization
+// ----------------------
+//
+// Z := X
+// N := unbaised exponent of Z
+// S_hi := 2^(-N) * Z
+//
+// Step 1. Argument Reduction
+// --------------------------
+//
+// Let
+//
+// Z = 2^N * S_hi = 2^N * 1.d_1 d_2 d_3 ... d_63
+//
+// We obtain G_1, G_2, G_3 by the following steps.
+//
+//
+// Define X_0 := 1.d_1 d_2 ... d_14. This is extracted
+// from S_hi.
+//
+// Define A_1 := 1.d_1 d_2 d_3 d_4. This is X_0 truncated
+// to lsb = 2^(-4).
+//
+// Define index_1 := [ d_1 d_2 d_3 d_4 ].
+//
+// Fetch Z_1 := (1/A_1) rounded UP in fixed point with
+// fixed point lsb = 2^(-15).
+// Z_1 looks like z_0.z_1 z_2 ... z_15
+// Note that the fetching is done using index_1.
+// A_1 is actually not needed in the implementation
+// and is used here only to explain how is the value
+// Z_1 defined.
+//
+// Fetch G_1 := (1/A_1) truncated to 21 sig. bits.
+// floating pt. Again, fetching is done using index_1. A_1
+// explains how G_1 is defined.
+//
+// Calculate X_1 := X_0 * Z_1 truncated to lsb = 2^(-14)
+// = 1.0 0 0 0 d_5 ... d_14
+// This is accomplised by integer multiplication.
+// It is proved that X_1 indeed always begin
+// with 1.0000 in fixed point.
+//
+//
+// Define A_2 := 1.0 0 0 0 d_5 d_6 d_7 d_8. This is X_1
+// truncated to lsb = 2^(-8). Similar to A_1,
+// A_2 is not needed in actual implementation. It
+// helps explain how some of the values are defined.
+//
+// Define index_2 := [ d_5 d_6 d_7 d_8 ].
+//
+// Fetch Z_2 := (1/A_2) rounded UP in fixed point with
+// fixed point lsb = 2^(-15). Fetch done using index_2.
+// Z_2 looks like z_0.z_1 z_2 ... z_15
+//
+// Fetch G_2 := (1/A_2) truncated to 21 sig. bits.
+// floating pt.
+//
+// Calculate X_2 := X_1 * Z_2 truncated to lsb = 2^(-14)
+// = 1.0 0 0 0 0 0 0 0 d_9 d_10 ... d_14
+// This is accomplised by integer multiplication.
+// It is proved that X_2 indeed always begin
+// with 1.00000000 in fixed point.
+//
+//
+// Define A_3 := 1.0 0 0 0 0 0 0 0 d_9 d_10 d_11 d_12 d_13 1.
+// This is 2^(-14) + X_2 truncated to lsb = 2^(-13).
+//
+// Define index_3 := [ d_9 d_10 d_11 d_12 d_13 ].
+//
+// Fetch G_3 := (1/A_3) truncated to 21 sig. bits.
+// floating pt. Fetch is done using index_3.
+//
+// Compute G := G_1 * G_2 * G_3.
+//
+// This is done exactly since each of G_j only has 21 sig. bits.
+//
+// Compute
+//
+// r := (G*S_hi - 1)
+//
+//
+// Step 2. Approximation
+// ---------------------
+//
+// This step computes an approximation to logl( 1 + r ) where r is the
+// reduced argument just obtained. It is proved that |r| <= 1.9*2^(-13);
+// thus logl(1+r) can be approximated by a short polynomial:
+//
+// logl(1+r) ~=~ poly = r + Q1 r^2 + ... + Q4 r^5
+//
+//
+// Step 3. Reconstruction
+// ----------------------
+//
+// This step computes the desired result of logl(X):
+//
+// logl(X) = logl( 2^N * S_hi )
+// = N*logl(2) + logl( S_hi )
+// = N*logl(2) + logl(1/G) +
+// logl(1 + G*S_hi - 1 )
+//
+// logl(2), logl(1/G_j) are stored as pairs of (single,double) numbers:
+// log2_hi, log2_lo, log1byGj_hi, log1byGj_lo. The high parts are
+// single-precision numbers and the low parts are double precision
+// numbers. These have the property that
+//
+// N*log2_hi + SUM ( log1byGj_hi )
+//
+// is computable exactly in double-extended precision (64 sig. bits).
+// Finally
+//
+// Y_hi := N*log2_hi + SUM ( log1byGj_hi )
+// Y_lo := poly_hi + [ poly_lo +
+// ( SUM ( log1byGj_lo ) + N*log2_lo ) ]
+//
+
+RODATA
+.align 64
+
+// ************* DO NOT CHANGE THE ORDER OF THESE TABLES *************
+
+// P_8, P_7, P_6, P_5, P_4, P_3, P_2, and P_1
+
+LOCAL_OBJECT_START(Constants_P)
+data8 0xE3936754EFD62B15,0x00003FFB
+data8 0x8003B271A5E56381,0x0000BFFC
+data8 0x9249248C73282DB0,0x00003FFC
+data8 0xAAAAAA9F47305052,0x0000BFFC
+data8 0xCCCCCCCCCCD17FC9,0x00003FFC
+data8 0x8000000000067ED5,0x0000BFFD
+data8 0xAAAAAAAAAAAAAAAA,0x00003FFD
+data8 0xFFFFFFFFFFFFFFFE,0x0000BFFD
+LOCAL_OBJECT_END(Constants_P)
+
+// log2_hi, log2_lo, Q_4, Q_3, Q_2, and Q_1
+
+LOCAL_OBJECT_START(Constants_Q)
+data8 0xB172180000000000,0x00003FFE
+data8 0x82E308654361C4C6,0x0000BFE2
+data8 0xCCCCCAF2328833CB,0x00003FFC
+data8 0x80000077A9D4BAFB,0x0000BFFD
+data8 0xAAAAAAAAAAABE3D2,0x00003FFD
+data8 0xFFFFFFFFFFFFDAB7,0x0000BFFD
+LOCAL_OBJECT_END(Constants_Q)
+
+// 1/ln10_hi, 1/ln10_lo
+
+LOCAL_OBJECT_START(Constants_1_by_LN10)
+data8 0xDE5BD8A937287195,0x00003FFD
+data8 0xD56EAABEACCF70C8,0x00003FBB
+LOCAL_OBJECT_END(Constants_1_by_LN10)
+
+
+// Z1 - 16 bit fixed
+
+LOCAL_OBJECT_START(Constants_Z_1)
+data4 0x00008000
+data4 0x00007879
+data4 0x000071C8
+data4 0x00006BCB
+data4 0x00006667
+data4 0x00006187
+data4 0x00005D18
+data4 0x0000590C
+data4 0x00005556
+data4 0x000051EC
+data4 0x00004EC5
+data4 0x00004BDB
+data4 0x00004925
+data4 0x0000469F
+data4 0x00004445
+data4 0x00004211
+LOCAL_OBJECT_END(Constants_Z_1)
+
+// G1 and H1 - IEEE single and h1 - IEEE double
+
+LOCAL_OBJECT_START(Constants_G_H_h1)
+data4 0x3F800000,0x00000000
+data8 0x0000000000000000
+data4 0x3F70F0F0,0x3D785196
+data8 0x3DA163A6617D741C
+data4 0x3F638E38,0x3DF13843
+data8 0x3E2C55E6CBD3D5BB
+data4 0x3F579430,0x3E2FF9A0
+data8 0xBE3EB0BFD86EA5E7
+data4 0x3F4CCCC8,0x3E647FD6
+data8 0x3E2E6A8C86B12760
+data4 0x3F430C30,0x3E8B3AE7
+data8 0x3E47574C5C0739BA
+data4 0x3F3A2E88,0x3EA30C68
+data8 0x3E20E30F13E8AF2F
+data4 0x3F321640,0x3EB9CEC8
+data8 0xBE42885BF2C630BD
+data4 0x3F2AAAA8,0x3ECF9927
+data8 0x3E497F3497E577C6
+data4 0x3F23D708,0x3EE47FC5
+data8 0x3E3E6A6EA6B0A5AB
+data4 0x3F1D89D8,0x3EF8947D
+data8 0xBDF43E3CD328D9BE
+data4 0x3F17B420,0x3F05F3A1
+data8 0x3E4094C30ADB090A
+data4 0x3F124920,0x3F0F4303
+data8 0xBE28FBB2FC1FE510
+data4 0x3F0D3DC8,0x3F183EBF
+data8 0x3E3A789510FDE3FA
+data4 0x3F088888,0x3F20EC80
+data8 0x3E508CE57CC8C98F
+data4 0x3F042108,0x3F29516A
+data8 0xBE534874A223106C
+LOCAL_OBJECT_END(Constants_G_H_h1)
+
+// Z2 - 16 bit fixed
+
+LOCAL_OBJECT_START(Constants_Z_2)
+data4 0x00008000
+data4 0x00007F81
+data4 0x00007F02
+data4 0x00007E85
+data4 0x00007E08
+data4 0x00007D8D
+data4 0x00007D12
+data4 0x00007C98
+data4 0x00007C20
+data4 0x00007BA8
+data4 0x00007B31
+data4 0x00007ABB
+data4 0x00007A45
+data4 0x000079D1
+data4 0x0000795D
+data4 0x000078EB
+LOCAL_OBJECT_END(Constants_Z_2)
+
+// G2 and H2 - IEEE single and h2 - IEEE double
+
+LOCAL_OBJECT_START(Constants_G_H_h2)
+data4 0x3F800000,0x00000000
+data8 0x0000000000000000
+data4 0x3F7F00F8,0x3B7F875D
+data8 0x3DB5A11622C42273
+data4 0x3F7E03F8,0x3BFF015B
+data8 0x3DE620CF21F86ED3
+data4 0x3F7D08E0,0x3C3EE393
+data8 0xBDAFA07E484F34ED
+data4 0x3F7C0FC0,0x3C7E0586
+data8 0xBDFE07F03860BCF6
+data4 0x3F7B1880,0x3C9E75D2
+data8 0x3DEA370FA78093D6
+data4 0x3F7A2328,0x3CBDC97A
+data8 0x3DFF579172A753D0
+data4 0x3F792FB0,0x3CDCFE47
+data8 0x3DFEBE6CA7EF896B
+data4 0x3F783E08,0x3CFC15D0
+data8 0x3E0CF156409ECB43
+data4 0x3F774E38,0x3D0D874D
+data8 0xBE0B6F97FFEF71DF
+data4 0x3F766038,0x3D1CF49B
+data8 0xBE0804835D59EEE8
+data4 0x3F757400,0x3D2C531D
+data8 0x3E1F91E9A9192A74
+data4 0x3F748988,0x3D3BA322
+data8 0xBE139A06BF72A8CD
+data4 0x3F73A0D0,0x3D4AE46F
+data8 0x3E1D9202F8FBA6CF
+data4 0x3F72B9D0,0x3D5A1756
+data8 0xBE1DCCC4BA796223
+data4 0x3F71D488,0x3D693B9D
+data8 0xBE049391B6B7C239
+LOCAL_OBJECT_END(Constants_G_H_h2)
+
+// G3 and H3 - IEEE single and h3 - IEEE double
+
+LOCAL_OBJECT_START(Constants_G_H_h3)
+data4 0x3F7FFC00,0x38800100
+data8 0x3D355595562224CD
+data4 0x3F7FF400,0x39400480
+data8 0x3D8200A206136FF6
+data4 0x3F7FEC00,0x39A00640
+data8 0x3DA4D68DE8DE9AF0
+data4 0x3F7FE400,0x39E00C41
+data8 0xBD8B4291B10238DC
+data4 0x3F7FDC00,0x3A100A21
+data8 0xBD89CCB83B1952CA
+data4 0x3F7FD400,0x3A300F22
+data8 0xBDB107071DC46826
+data4 0x3F7FCC08,0x3A4FF51C
+data8 0x3DB6FCB9F43307DB
+data4 0x3F7FC408,0x3A6FFC1D
+data8 0xBD9B7C4762DC7872
+data4 0x3F7FBC10,0x3A87F20B
+data8 0xBDC3725E3F89154A
+data4 0x3F7FB410,0x3A97F68B
+data8 0xBD93519D62B9D392
+data4 0x3F7FAC18,0x3AA7EB86
+data8 0x3DC184410F21BD9D
+data4 0x3F7FA420,0x3AB7E101
+data8 0xBDA64B952245E0A6
+data4 0x3F7F9C20,0x3AC7E701
+data8 0x3DB4B0ECAABB34B8
+data4 0x3F7F9428,0x3AD7DD7B
+data8 0x3D9923376DC40A7E
+data4 0x3F7F8C30,0x3AE7D474
+data8 0x3DC6E17B4F2083D3
+data4 0x3F7F8438,0x3AF7CBED
+data8 0x3DAE314B811D4394
+data4 0x3F7F7C40,0x3B03E1F3
+data8 0xBDD46F21B08F2DB1
+data4 0x3F7F7448,0x3B0BDE2F
+data8 0xBDDC30A46D34522B
+data4 0x3F7F6C50,0x3B13DAAA
+data8 0x3DCB0070B1F473DB
+data4 0x3F7F6458,0x3B1BD766
+data8 0xBDD65DDC6AD282FD
+data4 0x3F7F5C68,0x3B23CC5C
+data8 0xBDCDAB83F153761A
+data4 0x3F7F5470,0x3B2BC997
+data8 0xBDDADA40341D0F8F
+data4 0x3F7F4C78,0x3B33C711
+data8 0x3DCD1BD7EBC394E8
+data4 0x3F7F4488,0x3B3BBCC6
+data8 0xBDC3532B52E3E695
+data4 0x3F7F3C90,0x3B43BAC0
+data8 0xBDA3961EE846B3DE
+data4 0x3F7F34A0,0x3B4BB0F4
+data8 0xBDDADF06785778D4
+data4 0x3F7F2CA8,0x3B53AF6D
+data8 0x3DCC3ED1E55CE212
+data4 0x3F7F24B8,0x3B5BA620
+data8 0xBDBA31039E382C15
+data4 0x3F7F1CC8,0x3B639D12
+data8 0x3D635A0B5C5AF197
+data4 0x3F7F14D8,0x3B6B9444
+data8 0xBDDCCB1971D34EFC
+data4 0x3F7F0CE0,0x3B7393BC
+data8 0x3DC7450252CD7ADA
+data4 0x3F7F04F0,0x3B7B8B6D
+data8 0xBDB68F177D7F2A42
+LOCAL_OBJECT_END(Constants_G_H_h3)
+
+
+// Floating Point Registers
+
+FR_Input_X = f8
+
+FR_Y_hi = f34
+FR_Y_lo = f35
+
+FR_Scale = f36
+FR_X_Prime = f37
+FR_S_hi = f38
+FR_W = f39
+FR_G = f40
+
+FR_H = f41
+FR_wsq = f42
+FR_w4 = f43
+FR_h = f44
+FR_w6 = f45
+
+FR_G2 = f46
+FR_H2 = f47
+FR_poly_lo = f48
+FR_P8 = f49
+FR_poly_hi = f50
+
+FR_P7 = f51
+FR_h2 = f52
+FR_rsq = f53
+FR_P6 = f54
+FR_r = f55
+
+FR_log2_hi = f56
+FR_log2_lo = f57
+FR_p87 = f58
+FR_p876 = f58
+FR_p8765 = f58
+FR_float_N = f59
+FR_Q4 = f60
+
+FR_p43 = f61
+FR_p432 = f61
+FR_p4321 = f61
+FR_P4 = f62
+FR_G3 = f63
+FR_H3 = f64
+FR_h3 = f65
+
+FR_Q3 = f66
+FR_P3 = f67
+FR_Q2 = f68
+FR_P2 = f69
+FR_1LN10_hi = f70
+
+FR_Q1 = f71
+FR_P1 = f72
+FR_1LN10_lo = f73
+FR_P5 = f74
+FR_rcub = f75
+
+FR_Output_X_tmp = f76
+
+FR_X = f8
+FR_Y = f0
+FR_RESULT = f76
+
+
+// General Purpose Registers
+
+GR_ad_p = r33
+GR_Index1 = r34
+GR_Index2 = r35
+GR_signif = r36
+GR_X_0 = r37
+GR_X_1 = r38
+GR_X_2 = r39
+GR_Z_1 = r40
+GR_Z_2 = r41
+GR_N = r42
+GR_Bias = r43
+GR_M = r44
+GR_Index3 = r45
+GR_ad_p2 = r46
+GR_exp_mask = r47
+GR_exp_2tom7 = r48
+GR_ad_ln10 = r49
+GR_ad_tbl_1 = r50
+GR_ad_tbl_2 = r51
+GR_ad_tbl_3 = r52
+GR_ad_q = r53
+GR_ad_z_1 = r54
+GR_ad_z_2 = r55
+GR_ad_z_3 = r56
+
+//
+// Added for unwind support
+//
+
+GR_SAVE_PFS = r50
+GR_SAVE_B0 = r51
+GR_SAVE_GP = r52
+GR_Parameter_X = r53
+GR_Parameter_Y = r54
+GR_Parameter_RESULT = r55
+GR_Parameter_TAG = r56
+
+.section .text
+
+GLOBAL_IEEE754_ENTRY(logl)
+{ .mfi
+ alloc r32 = ar.pfs,0,21,4,0
+ fclass.m p6, p0 = FR_Input_X, 0x1E3 // Test for natval, nan, inf
+ cmp.eq p7, p14 = r0, r0 // Set p7 if logl
+}
+{ .mfb
+ addl GR_ad_z_1 = @ltoff(Constants_Z_1#),gp
+ fnorm.s1 FR_X_Prime = FR_Input_X // Normalize x
+ br.cond.sptk LOGL_BEGIN
+}
+;;
+
+GLOBAL_IEEE754_END(logl)
+
+
+GLOBAL_IEEE754_ENTRY(log10l)
+{ .mfi
+ alloc r32 = ar.pfs,0,21,4,0
+ fclass.m p6, p0 = FR_Input_X, 0x1E3 // Test for natval, nan, inf
+ cmp.ne p7, p14 = r0, r0 // Set p14 if log10l
+}
+{ .mfb
+ addl GR_ad_z_1 = @ltoff(Constants_Z_1#),gp
+ fnorm.s1 FR_X_Prime = FR_Input_X // Normalize x
+ nop.b 999
+}
+;;
+
+
+// Common code for logl and log10
+LOGL_BEGIN:
+{ .mfi
+ ld8 GR_ad_z_1 = [GR_ad_z_1] // Get pointer to Constants_Z_1
+ fclass.m p10, p0 = FR_Input_X, 0x0b // Test for denormal
+ mov GR_exp_2tom7 = 0x0fff8 // Exponent of 2^-7
+}
+;;
+
+{ .mfb
+ getf.sig GR_signif = FR_Input_X // Get significand of x
+ fcmp.eq.s1 p9, p0 = FR_Input_X, f1 // Test for x=1.0
+(p6) br.cond.spnt LOGL_64_special // Branch for nan, inf, natval
+}
+;;
+
+{ .mfi
+ add GR_ad_tbl_1 = 0x040, GR_ad_z_1 // Point to Constants_G_H_h1
+ fcmp.lt.s1 p13, p0 = FR_Input_X, f0 // Test for x<0
+ add GR_ad_p = -0x100, GR_ad_z_1 // Point to Constants_P
+}
+{ .mib
+ add GR_ad_z_2 = 0x140, GR_ad_z_1 // Point to Constants_Z_2
+ add GR_ad_tbl_2 = 0x180, GR_ad_z_1 // Point to Constants_G_H_h2
+(p10) br.cond.spnt LOGL_64_denormal // Branch for denormal
+}
+;;
+
+LOGL_64_COMMON:
+{ .mfi
+ add GR_ad_q = 0x080, GR_ad_p // Point to Constants_Q
+ fcmp.eq.s1 p8, p0 = FR_Input_X, f0 // Test for x=0
+ extr.u GR_Index1 = GR_signif, 59, 4 // Get high 4 bits of signif
+}
+{ .mfb
+ add GR_ad_tbl_3 = 0x280, GR_ad_z_1 // Point to Constants_G_H_h3
+(p9) fma.s0 f8 = FR_Input_X, f0, f0 // If x=1, return +0.0
+(p9) br.ret.spnt b0 // Exit if x=1
+}
+;;
+
+{ .mfi
+ shladd GR_ad_z_1 = GR_Index1, 2, GR_ad_z_1 // Point to Z_1
+ fclass.nm p10, p0 = FR_Input_X, 0x1FF // Test for unsupported
+ extr.u GR_X_0 = GR_signif, 49, 15 // Get high 15 bits of significand
+}
+{ .mfi
+ ldfe FR_P8 = [GR_ad_p],16 // Load P_8 for near1 path
+ fsub.s1 FR_W = FR_X_Prime, f1 // W = x - 1
+ add GR_ad_ln10 = 0x060, GR_ad_q // Point to Constants_1_by_LN10
+}
+;;
+
+{ .mfi
+ ld4 GR_Z_1 = [GR_ad_z_1] // Load Z_1
+ nop.f 999
+ mov GR_exp_mask = 0x1FFFF // Create exponent mask
+}
+{ .mib
+ shladd GR_ad_tbl_1 = GR_Index1, 4, GR_ad_tbl_1 // Point to G_1
+ mov GR_Bias = 0x0FFFF // Create exponent bias
+(p13) br.cond.spnt LOGL_64_negative // Branch if x<0
+}
+;;
+
+{ .mfb
+ ldfps FR_G, FR_H = [GR_ad_tbl_1],8 // Load G_1, H_1
+ fmerge.se FR_S_hi = f1,FR_X_Prime // Form |x|
+(p8) br.cond.spnt LOGL_64_zero // Branch if x=0
+}
+;;
+
+{ .mmb
+ getf.exp GR_N = FR_X_Prime // Get N = exponent of x
+ ldfd FR_h = [GR_ad_tbl_1] // Load h_1
+(p10) br.cond.spnt LOGL_64_unsupported // Branch for unsupported type
+}
+;;
+
+{ .mfi
+ ldfe FR_log2_hi = [GR_ad_q],16 // Load log2_hi
+ fcmp.eq.s0 p8, p0 = FR_Input_X, f0 // Dummy op to flag denormals
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15 // Get bits 30-15 of X_0 * Z_1
+}
+;;
+
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mmi
+ ldfe FR_log2_lo = [GR_ad_q],16 // Load log2_lo
+(p14) ldfe FR_1LN10_hi = [GR_ad_ln10],16 // If log10l, load 1/ln10_hi
+ sub GR_N = GR_N, GR_Bias
+}
+;;
+
+{ .mmi
+ ldfe FR_Q4 = [GR_ad_q],16 // Load Q4
+(p14) ldfe FR_1LN10_lo = [GR_ad_ln10] // If log10l, load 1/ln10_lo
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ldfe FR_Q3 = [GR_ad_q],16 // Load Q3
+ setf.sig FR_float_N = GR_N // Put integer N into rightmost significand
+ nop.i 999
+}
+;;
+
+{ .mmi
+ getf.exp GR_M = FR_W // Get signexp of w = x - 1
+ ldfe FR_Q2 = [GR_ad_q],16 // Load Q2
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract bits 6-9 of X_1
+}
+;;
+
+{ .mmi
+ ldfe FR_Q1 = [GR_ad_q] // Load Q1
+ shladd GR_ad_z_2 = GR_Index2, 2, GR_ad_z_2 // Point to Z_2
+ add GR_ad_p2 = 0x30,GR_ad_p // Point to P_4
+}
+;;
+
+{ .mmi
+ ld4 GR_Z_2 = [GR_ad_z_2] // Load Z_2
+ shladd GR_ad_tbl_2 = GR_Index2, 4, GR_ad_tbl_2 // Point to G_2
+ and GR_M = GR_exp_mask, GR_M // Get exponent of w = x - 1
+}
+;;
+
+{ .mmi
+ ldfps FR_G2, FR_H2 = [GR_ad_tbl_2],8 // Load G_2, H_2
+ cmp.lt p8, p9 = GR_M, GR_exp_2tom7 // Test |x-1| < 2^-7
+ nop.i 999
+}
+;;
+
+// Paths are merged.
+// p8 is for the near1 path: |x-1| < 2^-7
+// p9 is for regular path: |x-1| >= 2^-7
+
+{ .mmi
+ ldfd FR_h2 = [GR_ad_tbl_2] // Load h_2
+ nop.m 999
+ nop.i 999
+}
+;;
+
+{ .mmi
+(p8) ldfe FR_P7 = [GR_ad_p],16 // Load P_7 for near1 path
+(p8) ldfe FR_P4 = [GR_ad_p2],16 // Load P_4 for near1 path
+(p9) pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15 // Get bits 30-15 of X_1 * Z_2
+}
+;;
+
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mmi
+(p8) ldfe FR_P6 = [GR_ad_p],16 // Load P_6 for near1 path
+(p8) ldfe FR_P3 = [GR_ad_p2],16 // Load P_3 for near1 path
+ nop.i 999
+}
+;;
+
+{ .mmf
+(p8) ldfe FR_P5 = [GR_ad_p],16 // Load P_5 for near1 path
+(p8) ldfe FR_P2 = [GR_ad_p2],16 // Load P_2 for near1 path
+(p8) fmpy.s1 FR_wsq = FR_W, FR_W // wsq = w * w for near1 path
+}
+;;
+
+{ .mmi
+(p8) ldfe FR_P1 = [GR_ad_p2],16 ;; // Load P_1 for near1 path
+ nop.m 999
+(p9) extr.u GR_Index3 = GR_X_2, 1, 5 // Extract bits 1-5 of X_2
+}
+;;
+
+{ .mfi
+(p9) shladd GR_ad_tbl_3 = GR_Index3, 4, GR_ad_tbl_3 // Point to G_3
+(p9) fcvt.xf FR_float_N = FR_float_N
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p9) ldfps FR_G3, FR_H3 = [GR_ad_tbl_3],8 // Load G_3, H_3
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p9) ldfd FR_h3 = [GR_ad_tbl_3] // Load h_3
+(p9) fmpy.s1 FR_G = FR_G, FR_G2 // G = G_1 * G_2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fadd.s1 FR_H = FR_H, FR_H2 // H = H_1 + H_2
+ nop.i 999
+}
+;;
+
+{ .mmf
+ nop.m 999
+ nop.m 999
+(p9) fadd.s1 FR_h = FR_h, FR_h2 // h = h_1 + h_2
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fmpy.s1 FR_w4 = FR_wsq, FR_wsq // w4 = w^4 for near1 path
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_p87 = FR_W, FR_P8, FR_P7 // p87 = w * P8 + P7
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_p43 = FR_W, FR_P4, FR_P3 // p43 = w * P4 + P3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fmpy.s1 FR_G = FR_G, FR_G3 // G = (G_1 * G_2) * G_3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fadd.s1 FR_H = FR_H, FR_H3 // H = (H_1 + H_2) + H_3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fadd.s1 FR_h = FR_h, FR_h3 // h = (h_1 + h_2) + h_3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fmpy.s1 FR_w6 = FR_w4, FR_wsq // w6 = w^6 for near1 path
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_p432 = FR_W, FR_p43, FR_P2 // p432 = w * p43 + P2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_p876 = FR_W, FR_p87, FR_P6 // p876 = w * p87 + P6
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fms.s1 FR_r = FR_G, FR_S_hi, f1 // r = G * S_hi - 1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_Y_hi = FR_float_N, FR_log2_hi, FR_H // Y_hi = N * log2_hi + H
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_h = FR_float_N, FR_log2_lo, FR_h // h = N * log2_lo + h
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_p4321 = FR_W, FR_p432, FR_P1 // p4321 = w * p432 + P1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_p8765 = FR_W, FR_p876, FR_P5 // p8765 = w * p876 + P5
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_lo = FR_r, FR_Q4, FR_Q3 // poly_lo = r * Q4 + Q3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_Y_lo = FR_wsq, FR_p4321, f0 // Y_lo = wsq * p4321
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_Y_hi = FR_W, f1, f0 // Y_hi = w for near1 path
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_lo = FR_poly_lo, FR_r, FR_Q2 // poly_lo = poly_lo * r + Q2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_rcub = FR_rsq, FR_r, f0 // rcub = r^3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_Y_lo = FR_w6, FR_p8765,FR_Y_lo // Y_lo = w6 * p8765 + w2 * p4321
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r // poly_hi = Q1 * rsq + r
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h // poly_lo = poly_lo*r^3 + h
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fadd.s1 FR_Y_lo = FR_poly_hi, FR_poly_lo // Y_lo = poly_hi + poly_lo
+ nop.i 999
+}
+;;
+
+// Remainder of code is common for near1 and regular paths
+{ .mfi
+ nop.m 999
+(p7) fadd.s0 f8 = FR_Y_lo,FR_Y_hi // If logl, result=Y_lo+Y_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p14) fmpy.s1 FR_Output_X_tmp = FR_Y_lo,FR_1LN10_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p14) fma.s1 FR_Output_X_tmp = FR_Y_hi,FR_1LN10_lo,FR_Output_X_tmp
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p14) fma.s0 f8 = FR_Y_hi,FR_1LN10_hi,FR_Output_X_tmp
+ br.ret.sptk b0 // Common exit for 0 < x < inf
+}
+;;
+
+
+// Here if x=+-0
+LOGL_64_zero:
+//
+// If x=+-0 raise divide by zero and return -inf
+//
+{ .mfi
+(p7) mov GR_Parameter_TAG = 0
+ fsub.s1 FR_Output_X_tmp = f0, f1
+ nop.i 999
+}
+;;
+
+{ .mfb
+(p14) mov GR_Parameter_TAG = 6
+ frcpa.s0 FR_Output_X_tmp, p8 = FR_Output_X_tmp, f0
+ br.cond.sptk __libm_error_region
+}
+;;
+
+LOGL_64_special:
+{ .mfi
+ nop.m 999
+ fclass.m.unc p8, p0 = FR_Input_X, 0x1E1 // Test for natval, nan, +inf
+ nop.i 999
+}
+;;
+
+//
+// For SNaN raise invalid and return QNaN.
+// For QNaN raise invalid and return QNaN.
+// For +Inf return +Inf.
+//
+{ .mfb
+ nop.m 999
+(p8) fmpy.s0 f8 = FR_Input_X, f1
+(p8) br.ret.sptk b0 // Return for natval, nan, +inf
+}
+;;
+
+//
+// For -Inf raise invalid and return QNaN.
+//
+{ .mmi
+(p7) mov GR_Parameter_TAG = 1
+ nop.m 999
+ nop.i 999
+}
+;;
+
+{ .mfb
+(p14) mov GR_Parameter_TAG = 7
+ fmpy.s0 FR_Output_X_tmp = FR_Input_X, f0
+ br.cond.sptk __libm_error_region
+}
+;;
+
+// Here if x denormal or unnormal
+LOGL_64_denormal:
+{ .mmi
+ getf.sig GR_signif = FR_X_Prime // Get significand of normalized input
+ nop.m 999
+ nop.i 999
+}
+;;
+
+{ .mmb
+ getf.exp GR_N = FR_X_Prime // Get exponent of normalized input
+ nop.m 999
+ br.cond.sptk LOGL_64_COMMON // Branch back to common code
+}
+;;
+
+LOGL_64_unsupported:
+//
+// Return generated NaN or other value.
+//
+{ .mfb
+ nop.m 999
+ fmpy.s0 f8 = FR_Input_X, f0
+ br.ret.sptk b0
+}
+;;
+
+// Here if -inf < x < 0
+LOGL_64_negative:
+//
+// Deal with x < 0 in a special way - raise
+// invalid and produce QNaN indefinite.
+//
+{ .mfi
+(p7) mov GR_Parameter_TAG = 1
+ frcpa.s0 FR_Output_X_tmp, p8 = f0, f0
+ nop.i 999
+}
+;;
+
+{ .mib
+(p14) mov GR_Parameter_TAG = 7
+ nop.i 999
+ br.cond.sptk __libm_error_region
+}
+;;
+
+
+GLOBAL_IEEE754_END(log10l)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 999
+ nop.m 999
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region#)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_pow.S b/libc/sysdeps/ia64/fpu/e_pow.S
new file mode 100644
index 000000000..89449c79e
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_pow.S
@@ -0,0 +1,2297 @@
+.file "pow.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/03/00 Added p12 to definite over/under path. With odd power we did not
+// maintain the sign of x in this path.
+// 04/04/00 Unwind support added
+// 04/19/00 pow(+-1,inf) now returns NaN
+// pow(+-val, +-inf) returns 0 or inf, but now does not call error
+// support
+// Added s1 to fcvt.fx because invalid flag was incorrectly set.
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 09/07/00 Improved performance by eliminating bank conflicts and other stalls,
+// and tweaking the critical path
+// 09/08/00 Per c99, pow(+-1,inf) now returns 1, and pow(+1,nan) returns 1
+// 09/28/00 Updated NaN**0 path
+// 01/20/01 Fixed denormal flag settings.
+// 02/13/01 Improved speed.
+// 03/19/01 Reordered exp polynomial to improve speed and eliminate monotonicity
+// problem in round up, down, and to zero modes. Also corrected
+// overflow result when x negative, y odd in round up, down, zero.
+// 06/14/01 Added brace missing from bundle
+// 12/10/01 Corrected case where x negative, 2^52 <= |y| < 2^53, y odd integer.
+// 12/20/01 Fixed monotonity problem in round to nearest.
+// 02/08/02 Fixed overflow/underflow cases that were not calling error support.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 08/29/02 Improved Itanium 2 performance
+// 09/21/02 Added branch for |y*log(x)|<2^-11 to fix monotonicity problems.
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// double pow(double x, double y)
+//
+// Overview of operation
+//==============================================================
+//
+// Three steps...
+// 1. Log(x)
+// 2. y Log(x)
+// 3. exp(y log(x))
+//
+// This means we work with the absolute value of x and merge in the sign later.
+// Log(x) = G + delta + r -rsq/2 + p
+// G,delta depend on the exponent of x and table entries. The table entries are
+// indexed by the exponent of x, called K.
+//
+// The G and delta come out of the reduction; r is the reduced x.
+//
+// B = frcpa(x)
+// xB-1 is small means that B is the approximate inverse of x.
+//
+// Log(x) = Log( (1/B)(Bx) )
+// = Log(1/B) + Log(Bx)
+// = Log(1/B) + Log( 1 + (Bx-1))
+//
+// x = 2^K 1.x_1x_2.....x_52
+// B= frcpa(x) = 2^-k Cm
+// Log(1/B) = Log(1/(2^-K Cm))
+// Log(1/B) = Log((2^K/ Cm))
+// Log(1/B) = K Log(2) + Log(1/Cm)
+//
+// Log(x) = K Log(2) + Log(1/Cm) + Log( 1 + (Bx-1))
+//
+// If you take the significand of x, set the exponent to true 0, then Cm is
+// the frcpa. We tabulate the Log(1/Cm) values. There are 256 of them.
+// The frcpa table is indexed by 8 bits, the x_1 thru x_8.
+// m = x_1x_2...x_8 is an 8-bit index.
+//
+// Log(1/Cm) = log(1/frcpa(1+m/256)) where m goes from 0 to 255.
+//
+// We tabluate as two doubles, T and t, where T +t is the value itself.
+//
+// Log(x) = (K Log(2)_hi + T) + (Log(2)_hi + t) + Log( 1 + (Bx-1))
+// Log(x) = G + delta + Log( 1 + (Bx-1))
+//
+// The Log( 1 + (Bx-1)) can be calculated as a series in r = Bx-1.
+//
+// Log( 1 + (Bx-1)) = r - rsq/2 + p
+//
+// Then,
+//
+// yLog(x) = yG + y delta + y(r-rsq/2) + yp
+// yLog(x) = Z1 + e3 + Z2 + Z3 + (e2 + e3)
+//
+//
+// exp(yLog(x)) = exp(Z1 + Z2 + Z3) exp(e1 + e2 + e3)
+//
+//
+// exp(Z3) is another series.
+// exp(e1 + e2 + e3) is approximated as f3 = 1 + (e1 + e2 + e3)
+//
+// Z1 (128/log2) = number of log2/128 in Z1 is N1
+// Z2 (128/log2) = number of log2/128 in Z2 is N2
+//
+// s1 = Z1 - N1 log2/128
+// s2 = Z2 - N2 log2/128
+//
+// s = s1 + s2
+// N = N1 + N2
+//
+// exp(Z1 + Z2) = exp(Z)
+// exp(Z) = exp(s) exp(N log2/128)
+//
+// exp(r) = exp(Z - N log2/128)
+//
+// r = s + d = (Z - N (log2/128)_hi) -N (log2/128)_lo
+// = Z - N (log2/128)
+//
+// Z = s+d +N (log2/128)
+//
+// exp(Z) = exp(s) (1+d) exp(N log2/128)
+//
+// N = M 128 + n
+//
+// N log2/128 = M log2 + n log2/128
+//
+// n is 8 binary digits = n_7n_6...n_1
+//
+// n log2/128 = n_7n_6n_5 16 log2/128 + n_4n_3n_2n_1 log2/128
+// n log2/128 = n_7n_6n_5 log2/8 + n_4n_3n_2n_1 log2/128
+// n log2/128 = I2 log2/8 + I1 log2/128
+//
+// N log2/128 = M log2 + I2 log2/8 + I1 log2/128
+//
+// exp(Z) = exp(s) (1+d) exp(log(2^M) + log(2^I2/8) + log(2^I1/128))
+// exp(Z) = exp(s) (1+d1) (1+d2)(2^M) 2^I2/8 2^I1/128
+// exp(Z) = exp(s) f1 f2 (2^M) 2^I2/8 2^I1/128
+//
+// I1, I2 are table indices. Use a series for exp(s).
+// Then get exp(Z)
+//
+// exp(yLog(x)) = exp(Z1 + Z2 + Z3) exp(e1 + e2 + e3)
+// exp(yLog(x)) = exp(Z) exp(Z3) f3
+// exp(yLog(x)) = exp(Z)f3 exp(Z3)
+// exp(yLog(x)) = A exp(Z3)
+//
+// We actually calculate exp(Z3) -1.
+// Then,
+// exp(yLog(x)) = A + A( exp(Z3) -1)
+//
+
+// Table Generation
+//==============================================================
+
+// The log values
+// ==============
+// The operation (K*log2_hi) must be exact. K is the true exponent of x.
+// If we allow gradual underflow (denormals), K can be represented in 12 bits
+// (as a two's complement number). We assume 13 bits as an engineering
+// precaution.
+//
+// +------------+----------------+-+
+// | 13 bits | 50 bits | |
+// +------------+----------------+-+
+// 0 1 66
+// 2 34
+//
+// So we want the lsb(log2_hi) to be 2^-50
+// We get log2 as a quad-extended (15-bit exponent, 128-bit significand)
+//
+// 0 fffe b17217f7d1cf79ab c9e3b39803f2f6af (4...)
+//
+// Consider numbering the bits left to right, starting at 0 thru 127.
+// Bit 0 is the 2^-1 bit; bit 49 is the 2^-50 bit.
+//
+// ...79ab
+// 0111 1001 1010 1011
+// 44
+// 89
+//
+// So if we shift off the rightmost 14 bits, then (shift back only
+// the top half) we get
+//
+// 0 fffe b17217f7d1cf4000 e6af278ece600fcb dabc000000000000
+//
+// Put the right 64-bit signficand in an FR register, convert to double;
+// it is exact. Put the next 128 bits into a quad register and round to double.
+// The true exponent of the low part is -51.
+//
+// hi is 0 fffe b17217f7d1cf4000
+// lo is 0 ffcc e6af278ece601000
+//
+// Convert to double memory format and get
+//
+// hi is 0x3fe62e42fefa39e8
+// lo is 0x3cccd5e4f1d9cc02
+//
+// log2_hi + log2_lo is an accurate value for log2.
+//
+//
+// The T and t values
+// ==================
+// A similar method is used to generate the T and t values.
+//
+// K * log2_hi + T must be exact.
+//
+// Smallest T,t
+// ----------
+// The smallest T,t is
+// T t
+// 0x3f60040155d58800, 0x3c93bce0ce3ddd81 log(1/frcpa(1+0/256))= +1.95503e-003
+//
+// The exponent is 0x3f6 (biased) or -9 (true).
+// For the smallest T value, what we want is to clip the significand such that
+// when it is shifted right by 9, its lsb is in the bit for 2^-51. The 9 is the
+// specific for the first entry. In general, it is 0xffff - (biased 15-bit
+// exponent).
+
+// Independently, what we have calculated is the table value as a quad
+// precision number.
+// Table entry 1 is
+// 0 fff6 80200aaeac44ef38 338f77605fdf8000
+//
+// We store this quad precision number in a data structure that is
+// sign: 1
+// exponent: 15
+// signficand_hi: 64 (includes explicit bit)
+// signficand_lo: 49
+// Because the explicit bit is included, the significand is 113 bits.
+//
+// Consider significand_hi for table entry 1.
+//
+//
+// +-+--- ... -------+--------------------+
+// | |
+// +-+--- ... -------+--------------------+
+// 0 1 4444444455555555556666
+// 2345678901234567890123
+//
+// Labeled as above, bit 0 is 2^0, bit 1 is 2^-1, etc.
+// Bit 42 is 2^-42. If we shift to the right by 9, the bit in
+// bit 42 goes in 51.
+//
+// So what we want to do is shift bits 43 thru 63 into significand_lo.
+// This is shifting bit 42 into bit 63, taking care to retain shifted-off bits.
+// Then shifting (just with signficaand_hi) back into bit 42.
+//
+// The shift_value is 63-42 = 21. In general, this is
+// 63 - (51 -(0xffff - 0xfff6))
+// For this example, it is
+// 63 - (51 - 9) = 63 - 42 = 21
+//
+// This means we are shifting 21 bits into significand_lo. We must maintain more
+// that a 128-bit signficand not to lose bits. So before the shift we put the
+// 128-bit significand into a 256-bit signficand and then shift.
+// The 256-bit significand has four parts: hh, hl, lh, and ll.
+//
+// Start off with
+// hh hl lh ll
+// <64> <49><15_0> <64_0> <64_0>
+//
+// After shift by 21 (then return for significand_hi),
+// <43><21_0> <21><43> <6><58_0> <64_0>
+//
+// Take the hh part and convert to a double. There is no rounding here.
+// The conversion is exact. The true exponent of the high part is the same as
+// the true exponent of the input quad.
+//
+// We have some 64 plus significand bits for the low part. In this example, we
+// have 70 bits. We want to round this to a double. Put them in a quad and then
+// do a quad fnorm.
+// For this example the true exponent of the low part is
+// true_exponent_of_high - 43 = true_exponent_of_high - (64-21)
+// In general, this is
+// true_exponent_of_high - (64 - shift_value)
+//
+//
+// Largest T,t
+// ----------
+// The largest T,t is
+// 0x3fe62643fecf9742, 0x3c9e3147684bd37d log(1/frcpa(1+255/256))=+6.92171e-001
+//
+// Table entry 256 is
+// 0 fffe b1321ff67cba178c 51da12f4df5a0000
+//
+// The shift value is
+// 63 - (51 -(0xffff - 0xfffe)) = 13
+//
+// The true exponent of the low part is
+// true_exponent_of_high - (64 - shift_value)
+// -1 - (64-13) = -52
+// Biased as a double, this is 0x3cb
+//
+//
+//
+// So then lsb(T) must be >= 2^-51
+// msb(Klog2_hi) <= 2^12
+//
+// +--------+---------+
+// | 51 bits | <== largest T
+// +--------+---------+
+// | 9 bits | 42 bits | <== smallest T
+// +------------+----------------+-+
+// | 13 bits | 50 bits | |
+// +------------+----------------+-+
+
+
+// Special Cases
+//==============================================================
+
+// double float
+// overflow error 24 30
+
+// underflow error 25 31
+
+// X zero Y zero
+// +0 +0 +1 error 26 32
+// -0 +0 +1 error 26 32
+// +0 -0 +1 error 26 32
+// -0 -0 +1 error 26 32
+
+// X zero Y negative
+// +0 -odd integer +inf error 27 33 divide-by-zero
+// -0 -odd integer -inf error 27 33 divide-by-zero
+// +0 !-odd integer +inf error 27 33 divide-by-zero
+// -0 !-odd integer +inf error 27 33 divide-by-zero
+// +0 -inf +inf error 27 33 divide-by-zero
+// -0 -inf +inf error 27 33 divide-by-zero
+
+// X zero Y positve
+// +0 +odd integer +0
+// -0 +odd integer -0
+// +0 !+odd integer +0
+// -0 !+odd integer +0
+// +0 +inf +0
+// -0 +inf +0
+// +0 Y NaN quiet Y invalid if Y SNaN
+// -0 Y NaN quiet Y invalid if Y SNaN
+
+// X one
+// -1 Y inf +1
+// -1 Y NaN quiet Y invalid if Y SNaN
+// +1 Y NaN +1 invalid if Y SNaN
+// +1 Y any else +1
+
+// X - Y not integer QNAN error 28 34 invalid
+
+// X NaN Y 0 +1 error 29 35
+// X NaN Y NaN quiet X invalid if X or Y SNaN
+// X NaN Y any else quiet X invalid if X SNaN
+// X !+1 Y NaN quiet Y invalid if Y SNaN
+
+
+// X +inf Y >0 +inf
+// X -inf Y >0, !odd integer +inf
+// X -inf Y >0, odd integer -inf
+
+// X +inf Y <0 +0
+// X -inf Y <0, !odd integer +0
+// X -inf Y <0, odd integer -0
+
+// X +inf Y =0 +1
+// X -inf Y =0 +1
+
+// |X|<1 Y +inf +0
+// |X|<1 Y -inf +inf
+// |X|>1 Y +inf +inf
+// |X|>1 Y -inf +0
+
+// X any Y =0 +1
+
+// Assembly macros
+//==============================================================
+
+// integer registers used
+
+pow_GR_signexp_X = r14
+pow_GR_17ones = r15
+pow_AD_P = r16
+pow_GR_exp_2tom8 = r17
+pow_GR_sig_X = r18
+pow_GR_10033 = r19
+pow_GR_16ones = r20
+
+pow_AD_Tt = r21
+pow_GR_exp_X = r22
+pow_AD_Q = r23
+pow_GR_true_exp_X = r24
+pow_GR_y_zero = r25
+
+pow_GR_exp_Y = r26
+pow_AD_tbl1 = r27
+pow_AD_tbl2 = r28
+pow_GR_offset = r29
+pow_GR_exp_Xm1 = r30
+pow_GR_xneg_yodd = r31
+
+pow_GR_signexp_Xm1 = r35
+pow_GR_int_W1 = r36
+pow_GR_int_W2 = r37
+pow_GR_int_N = r38
+pow_GR_index1 = r39
+pow_GR_index2 = r40
+
+pow_AD_T1 = r41
+pow_AD_T2 = r42
+pow_int_GR_M = r43
+pow_GR_sig_int_Y = r44
+pow_GR_sign_Y_Gpr = r45
+
+pow_GR_17ones_m1 = r46
+pow_GR_one = r47
+pow_GR_sign_Y = r48
+pow_GR_signexp_Y_Gpr = r49
+pow_GR_exp_Y_Gpr = r50
+
+pow_GR_true_exp_Y_Gpr = r51
+pow_GR_signexp_Y = r52
+pow_GR_x_one = r53
+pow_GR_exp_2toM63 = r54
+pow_GR_big_pos = r55
+
+pow_GR_big_neg = r56
+
+GR_SAVE_B0 = r50
+GR_SAVE_GP = r51
+GR_SAVE_PFS = r52
+
+GR_Parameter_X = r53
+GR_Parameter_Y = r54
+GR_Parameter_RESULT = r55
+pow_GR_tag = r56
+
+
+// floating point registers used
+
+POW_B = f32
+POW_NORM_X = f33
+POW_Xm1 = f34
+POW_r1 = f34
+POW_P4 = f35
+
+POW_P5 = f36
+POW_NORM_Y = f37
+POW_Q2 = f38
+POW_Q3 = f39
+POW_P2 = f40
+
+POW_P3 = f41
+POW_P0 = f42
+POW_log2_lo = f43
+POW_r = f44
+POW_Q0_half = f45
+
+POW_Q1 = f46
+POW_tmp = f47
+POW_log2_hi = f48
+POW_Q4 = f49
+POW_P1 = f50
+
+POW_log2_by_128_hi = f51
+POW_inv_log2_by_128 = f52
+POW_rsq = f53
+POW_Yrcub = f54
+POW_log2_by_128_lo = f55
+
+POW_v6 = f56
+POW_xsq = f57
+POW_v4 = f58
+POW_v2 = f59
+POW_T = f60
+
+POW_Tt = f61
+POW_RSHF = f62
+POW_v21ps = f63
+POW_s4 = f64
+POW_twoV = f65
+
+POW_U = f66
+POW_G = f67
+POW_delta = f68
+POW_v3 = f69
+POW_V = f70
+
+POW_p = f71
+POW_Z1 = f72
+POW_e3 = f73
+POW_e2 = f74
+POW_Z2 = f75
+
+POW_e1 = f76
+POW_W1 = f77
+POW_UmZ2 = f78
+POW_W2 = f79
+POW_Z3 = f80
+
+POW_int_W1 = f81
+POW_e12 = f82
+POW_int_W2 = f83
+POW_UmZ2pV = f84
+POW_Z3sq = f85
+
+POW_e123 = f86
+POW_N1float = f87
+POW_N2float = f88
+POW_f3 = f89
+POW_q = f90
+
+POW_s1 = f91
+POW_Nfloat = f92
+POW_s2 = f93
+POW_f2 = f94
+POW_f1 = f95
+
+POW_T1 = f96
+POW_T2 = f97
+POW_2M = f98
+POW_s = f99
+POW_f12 = f100
+
+POW_ssq = f101
+POW_T1T2 = f102
+POW_1ps = f103
+POW_A = f104
+POW_es = f105
+
+POW_Xp1 = f106
+POW_int_K = f107
+POW_K = f108
+POW_f123 = f109
+POW_Gpr = f110
+
+POW_Y_Gpr = f111
+POW_int_Y = f112
+POW_abs_q = f114
+POW_2toM63 = f115
+
+POW_float_int_Y = f116
+POW_ftz_urm_f8 = f117
+POW_wre_urm_f8 = f118
+POW_big_neg = f119
+POW_big_pos = f120
+
+POW_GY_Z2 = f121
+POW_pYrcub_e3 = f122
+POW_d = f123
+POW_d2 = f124
+POW_poly_d_hi = f121
+POW_poly_d_lo = f122
+POW_poly_d = f121
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(pow_table_P)
+data8 0x8000F7B249FF332D, 0x0000BFFC // P_5
+data8 0xAAAAAAA9E7902C7F, 0x0000BFFC // P_3
+data8 0x80000000000018E5, 0x0000BFFD // P_1
+data8 0xb8aa3b295c17f0bc, 0x00004006 // inv_ln2_by_128
+//
+//
+data8 0x3FA5555555554A9E // Q_2
+data8 0x3F8111124F4DD9F9 // Q_3
+data8 0x3FE0000000000000 // Q_0
+data8 0x3FC5555555554733 // Q_1
+data8 0x3F56C16D9360FFA0 // Q_4
+data8 0x43e8000000000000 // Right shift constant for exp
+data8 0xc9e3b39803f2f6af, 0x00003fb7 // ln2_by_128_lo
+data8 0x0000000000000000 // pad to eliminate bank conflicts with pow_table_Q
+data8 0x0000000000000000 // pad to eliminate bank conflicts with pow_table_Q
+LOCAL_OBJECT_END(pow_table_P)
+
+LOCAL_OBJECT_START(pow_table_Q)
+data8 0x9249FE7F0DC423CF, 0x00003FFC // P_4
+data8 0xCCCCCCCC4ED2BA7F, 0x00003FFC // P_2
+data8 0xAAAAAAAAAAAAB505, 0x00003FFD // P_0
+data8 0x3fe62e42fefa39e8, 0x3cccd5e4f1d9cc02 // log2 hi lo = +6.93147e-001
+data8 0xb17217f7d1cf79ab, 0x00003ff7 // ln2_by_128_hi
+LOCAL_OBJECT_END(pow_table_Q)
+
+
+LOCAL_OBJECT_START(pow_Tt)
+data8 0x3f60040155d58800, 0x3c93bce0ce3ddd81 // log(1/frcpa(1+0/256))= +1.95503e-003
+data8 0x3f78121214586a00, 0x3cb540e0a5cfc9bc // log(1/frcpa(1+1/256))= +5.87661e-003
+data8 0x3f841929f9683200, 0x3cbdf1d57404da1f // log(1/frcpa(1+2/256))= +9.81362e-003
+data8 0x3f8c317384c75f00, 0x3c69806208c04c22 // log(1/frcpa(1+3/256))= +1.37662e-002
+data8 0x3f91a6b91ac73380, 0x3c7874daa716eb32 // log(1/frcpa(1+4/256))= +1.72376e-002
+data8 0x3f95ba9a5d9ac000, 0x3cacbb84e08d78ac // log(1/frcpa(1+5/256))= +2.12196e-002
+data8 0x3f99d2a807432580, 0x3cbcf80538b441e1 // log(1/frcpa(1+6/256))= +2.52177e-002
+data8 0x3f9d6b2725979800, 0x3c6095e5c8f8f359 // log(1/frcpa(1+7/256))= +2.87291e-002
+data8 0x3fa0c58fa19dfa80, 0x3cb4c5d4e9d0dda2 // log(1/frcpa(1+8/256))= +3.27573e-002
+data8 0x3fa2954c78cbce00, 0x3caa932b860ab8d6 // log(1/frcpa(1+9/256))= +3.62953e-002
+data8 0x3fa4a94d2da96c40, 0x3ca670452b76bbd5 // log(1/frcpa(1+10/256))= +4.03542e-002
+data8 0x3fa67c94f2d4bb40, 0x3ca84104f9941798 // log(1/frcpa(1+11/256))= +4.39192e-002
+data8 0x3fa85188b630f040, 0x3cb40a882cbf0153 // log(1/frcpa(1+12/256))= +4.74971e-002
+data8 0x3faa6b8abe73af40, 0x3c988d46e25c9059 // log(1/frcpa(1+13/256))= +5.16017e-002
+data8 0x3fac441e06f72a80, 0x3cae3e930a1a2a96 // log(1/frcpa(1+14/256))= +5.52072e-002
+data8 0x3fae1e6713606d00, 0x3c8a796f6283b580 // log(1/frcpa(1+15/256))= +5.88257e-002
+data8 0x3faffa6911ab9300, 0x3c5193070351e88a // log(1/frcpa(1+16/256))= +6.24574e-002
+data8 0x3fb0ec139c5da600, 0x3c623f2a75eb992d // log(1/frcpa(1+17/256))= +6.61022e-002
+data8 0x3fb1dbd2643d1900, 0x3ca649b2ef8927f0 // log(1/frcpa(1+18/256))= +6.97605e-002
+data8 0x3fb2cc7284fe5f00, 0x3cbc5e86599513e2 // log(1/frcpa(1+19/256))= +7.34321e-002
+data8 0x3fb3bdf5a7d1ee60, 0x3c90bd4bb69dada3 // log(1/frcpa(1+20/256))= +7.71173e-002
+data8 0x3fb4b05d7aa012e0, 0x3c54e377c9b8a54f // log(1/frcpa(1+21/256))= +8.08161e-002
+data8 0x3fb580db7ceb5700, 0x3c7fdb2f98354cde // log(1/frcpa(1+22/256))= +8.39975e-002
+data8 0x3fb674f089365a60, 0x3cb9994c9d3301c1 // log(1/frcpa(1+23/256))= +8.77219e-002
+data8 0x3fb769ef2c6b5680, 0x3caaec639db52a79 // log(1/frcpa(1+24/256))= +9.14602e-002
+data8 0x3fb85fd927506a40, 0x3c9f9f99a3cf8e25 // log(1/frcpa(1+25/256))= +9.52125e-002
+data8 0x3fb9335e5d594980, 0x3ca15c3abd47d99a // log(1/frcpa(1+26/256))= +9.84401e-002
+data8 0x3fba2b0220c8e5e0, 0x3cb4ca639adf6fc3 // log(1/frcpa(1+27/256))= +1.02219e-001
+data8 0x3fbb0004ac1a86a0, 0x3ca7cb81bf959a59 // log(1/frcpa(1+28/256))= +1.05469e-001
+data8 0x3fbbf968769fca00, 0x3cb0c646c121418e // log(1/frcpa(1+29/256))= +1.09274e-001
+data8 0x3fbccfedbfee13a0, 0x3ca0465fce24ab4b // log(1/frcpa(1+30/256))= +1.12548e-001
+data8 0x3fbda727638446a0, 0x3c82803f4e2e6603 // log(1/frcpa(1+31/256))= +1.15832e-001
+data8 0x3fbea3257fe10f60, 0x3cb986a3f2313d1a // log(1/frcpa(1+32/256))= +1.19677e-001
+data8 0x3fbf7be9fedbfde0, 0x3c97d16a6a621cf4 // log(1/frcpa(1+33/256))= +1.22985e-001
+data8 0x3fc02ab352ff25f0, 0x3c9cc6baad365600 // log(1/frcpa(1+34/256))= +1.26303e-001
+data8 0x3fc097ce579d2040, 0x3cb9ba16d329440b // log(1/frcpa(1+35/256))= +1.29633e-001
+data8 0x3fc1178e8227e470, 0x3cb7bc671683f8e6 // log(1/frcpa(1+36/256))= +1.33531e-001
+data8 0x3fc185747dbecf30, 0x3c9d1116f66d2345 // log(1/frcpa(1+37/256))= +1.36885e-001
+data8 0x3fc1f3b925f25d40, 0x3c8162c9ef939ac6 // log(1/frcpa(1+38/256))= +1.40250e-001
+data8 0x3fc2625d1e6ddf50, 0x3caad3a1ec384fc3 // log(1/frcpa(1+39/256))= +1.43627e-001
+data8 0x3fc2d1610c868130, 0x3cb3ad997036941b // log(1/frcpa(1+40/256))= +1.47015e-001
+data8 0x3fc340c597411420, 0x3cbc2308262c7998 // log(1/frcpa(1+41/256))= +1.50414e-001
+data8 0x3fc3b08b6757f2a0, 0x3cb2170d6cdf0526 // log(1/frcpa(1+42/256))= +1.53825e-001
+data8 0x3fc40dfb08378000, 0x3c9bb453c4f7b685 // log(1/frcpa(1+43/256))= +1.56677e-001
+data8 0x3fc47e74e8ca5f70, 0x3cb836a48fdfce9d // log(1/frcpa(1+44/256))= +1.60109e-001
+data8 0x3fc4ef51f6466de0, 0x3ca07a43919aa64b // log(1/frcpa(1+45/256))= +1.63553e-001
+data8 0x3fc56092e02ba510, 0x3ca85006899d97b0 // log(1/frcpa(1+46/256))= +1.67010e-001
+data8 0x3fc5d23857cd74d0, 0x3ca30a5ba6e7abbe // log(1/frcpa(1+47/256))= +1.70478e-001
+data8 0x3fc6313a37335d70, 0x3ca905586f0ac97e // log(1/frcpa(1+48/256))= +1.73377e-001
+data8 0x3fc6a399dabbd380, 0x3c9b2c6657a96684 // log(1/frcpa(1+49/256))= +1.76868e-001
+data8 0x3fc70337dd3ce410, 0x3cb50bc52f55cdd8 // log(1/frcpa(1+50/256))= +1.79786e-001
+data8 0x3fc77654128f6120, 0x3cad2eb7c9a39efe // log(1/frcpa(1+51/256))= +1.83299e-001
+data8 0x3fc7e9d82a0b0220, 0x3cba127e90393c01 // log(1/frcpa(1+52/256))= +1.86824e-001
+data8 0x3fc84a6b759f5120, 0x3cbd7fd52079f706 // log(1/frcpa(1+53/256))= +1.89771e-001
+data8 0x3fc8ab47d5f5a300, 0x3cbfae141751a3de // log(1/frcpa(1+54/256))= +1.92727e-001
+data8 0x3fc91fe490965810, 0x3cb69cf30a1c319e // log(1/frcpa(1+55/256))= +1.96286e-001
+data8 0x3fc981634011aa70, 0x3ca5bb3d208bc42a // log(1/frcpa(1+56/256))= +1.99261e-001
+data8 0x3fc9f6c407089660, 0x3ca04d68658179a0 // log(1/frcpa(1+57/256))= +2.02843e-001
+data8 0x3fca58e729348f40, 0x3c99f5411546c286 // log(1/frcpa(1+58/256))= +2.05838e-001
+data8 0x3fcabb55c31693a0, 0x3cb9a5350eb327d5 // log(1/frcpa(1+59/256))= +2.08842e-001
+data8 0x3fcb1e104919efd0, 0x3c18965fcce7c406 // log(1/frcpa(1+60/256))= +2.11855e-001
+data8 0x3fcb94ee93e367c0, 0x3cb503716da45184 // log(1/frcpa(1+61/256))= +2.15483e-001
+data8 0x3fcbf851c0675550, 0x3cbdf1b3f7ab5378 // log(1/frcpa(1+62/256))= +2.18516e-001
+data8 0x3fcc5c0254bf23a0, 0x3ca7aab9ed0b1d7b // log(1/frcpa(1+63/256))= +2.21558e-001
+data8 0x3fccc000c9db3c50, 0x3c92a7a2a850072a // log(1/frcpa(1+64/256))= +2.24609e-001
+data8 0x3fcd244d99c85670, 0x3c9f6019120edf4c // log(1/frcpa(1+65/256))= +2.27670e-001
+data8 0x3fcd88e93fb2f450, 0x3c6affb96815e081 // log(1/frcpa(1+66/256))= +2.30741e-001
+data8 0x3fcdedd437eaef00, 0x3c72553595897976 // log(1/frcpa(1+67/256))= +2.33820e-001
+data8 0x3fce530effe71010, 0x3c90913b020fa182 // log(1/frcpa(1+68/256))= +2.36910e-001
+data8 0x3fceb89a1648b970, 0x3c837ba4045bfd25 // log(1/frcpa(1+69/256))= +2.40009e-001
+data8 0x3fcf1e75fadf9bd0, 0x3cbcea6d13e0498d // log(1/frcpa(1+70/256))= +2.43117e-001
+data8 0x3fcf84a32ead7c30, 0x3ca5e3a67b3c6d77 // log(1/frcpa(1+71/256))= +2.46235e-001
+data8 0x3fcfeb2233ea07c0, 0x3cba0c6f0049c5a6 // log(1/frcpa(1+72/256))= +2.49363e-001
+data8 0x3fd028f9c7035c18, 0x3cb0a30b06677ff6 // log(1/frcpa(1+73/256))= +2.52501e-001
+data8 0x3fd05c8be0d96358, 0x3ca0f1c77ccb5865 // log(1/frcpa(1+74/256))= +2.55649e-001
+data8 0x3fd085eb8f8ae790, 0x3cbd513f45fe7a97 // log(1/frcpa(1+75/256))= +2.58174e-001
+data8 0x3fd0b9c8e32d1910, 0x3c927449047ca006 // log(1/frcpa(1+76/256))= +2.61339e-001
+data8 0x3fd0edd060b78080, 0x3c89b52d8435f53e // log(1/frcpa(1+77/256))= +2.64515e-001
+data8 0x3fd122024cf00638, 0x3cbdd976fabda4bd // log(1/frcpa(1+78/256))= +2.67701e-001
+data8 0x3fd14be2927aecd0, 0x3cb02f90ad0bc471 // log(1/frcpa(1+79/256))= +2.70257e-001
+data8 0x3fd180618ef18ad8, 0x3cbd003792c71a98 // log(1/frcpa(1+80/256))= +2.73461e-001
+data8 0x3fd1b50bbe2fc638, 0x3ca9ae64c6403ead // log(1/frcpa(1+81/256))= +2.76675e-001
+data8 0x3fd1df4cc7cf2428, 0x3cb43f0455f7e395 // log(1/frcpa(1+82/256))= +2.79254e-001
+data8 0x3fd214456d0eb8d0, 0x3cb0fbd748d75d30 // log(1/frcpa(1+83/256))= +2.82487e-001
+data8 0x3fd23ec5991eba48, 0x3c906edd746b77e2 // log(1/frcpa(1+84/256))= +2.85081e-001
+data8 0x3fd2740d9f870af8, 0x3ca9802e6a00a670 // log(1/frcpa(1+85/256))= +2.88333e-001
+data8 0x3fd29ecdabcdfa00, 0x3cacecef70890cfa // log(1/frcpa(1+86/256))= +2.90943e-001
+data8 0x3fd2d46602adcce8, 0x3cb97911955f3521 // log(1/frcpa(1+87/256))= +2.94214e-001
+data8 0x3fd2ff66b04ea9d0, 0x3cb12dabe191d1c9 // log(1/frcpa(1+88/256))= +2.96838e-001
+data8 0x3fd335504b355a30, 0x3cbdf9139df924ec // log(1/frcpa(1+89/256))= +3.00129e-001
+data8 0x3fd360925ec44f58, 0x3cb253e68977a1e3 // log(1/frcpa(1+90/256))= +3.02769e-001
+data8 0x3fd38bf1c3337e70, 0x3cb3d283d2a2da21 // log(1/frcpa(1+91/256))= +3.05417e-001
+data8 0x3fd3c25277333180, 0x3cadaa5b035eae27 // log(1/frcpa(1+92/256))= +3.08735e-001
+data8 0x3fd3edf463c16838, 0x3cb983d680d3c108 // log(1/frcpa(1+93/256))= +3.11399e-001
+data8 0x3fd419b423d5e8c0, 0x3cbc86dd921c139d // log(1/frcpa(1+94/256))= +3.14069e-001
+data8 0x3fd44591e0539f48, 0x3c86a76d6dc2782e // log(1/frcpa(1+95/256))= +3.16746e-001
+data8 0x3fd47c9175b6f0a8, 0x3cb59a2e013c6b5f // log(1/frcpa(1+96/256))= +3.20103e-001
+data8 0x3fd4a8b341552b08, 0x3c93f1e86e468694 // log(1/frcpa(1+97/256))= +3.22797e-001
+data8 0x3fd4d4f390890198, 0x3cbf5e4ea7c5105a // log(1/frcpa(1+98/256))= +3.25498e-001
+data8 0x3fd501528da1f960, 0x3cbf58da53e9ad10 // log(1/frcpa(1+99/256))= +3.28206e-001
+data8 0x3fd52dd06347d4f0, 0x3cb98a28cebf6eef // log(1/frcpa(1+100/256))= +3.30921e-001
+data8 0x3fd55a6d3c7b8a88, 0x3c9c76b67c2d1fd4 // log(1/frcpa(1+101/256))= +3.33644e-001
+data8 0x3fd5925d2b112a58, 0x3c9029616a4331b8 // log(1/frcpa(1+102/256))= +3.37058e-001
+data8 0x3fd5bf406b543db0, 0x3c9fb8292ecfc820 // log(1/frcpa(1+103/256))= +3.39798e-001
+data8 0x3fd5ec433d5c35a8, 0x3cb71a1229d17eec // log(1/frcpa(1+104/256))= +3.42545e-001
+data8 0x3fd61965cdb02c18, 0x3cbba94fe1dbb8d2 // log(1/frcpa(1+105/256))= +3.45300e-001
+data8 0x3fd646a84935b2a0, 0x3c9ee496d2c9ae57 // log(1/frcpa(1+106/256))= +3.48063e-001
+data8 0x3fd6740add31de90, 0x3cb1da3a6c7a9dfd // log(1/frcpa(1+107/256))= +3.50833e-001
+data8 0x3fd6a18db74a58c0, 0x3cb494c257add8dc // log(1/frcpa(1+108/256))= +3.53610e-001
+data8 0x3fd6cf31058670e8, 0x3cb0b244a70a8da9 // log(1/frcpa(1+109/256))= +3.56396e-001
+data8 0x3fd6f180e852f0b8, 0x3c9db7aefa866720 // log(1/frcpa(1+110/256))= +3.58490e-001
+data8 0x3fd71f5d71b894e8, 0x3cbe91c4bf324957 // log(1/frcpa(1+111/256))= +3.61289e-001
+data8 0x3fd74d5aefd66d58, 0x3cb06b3d9bfac023 // log(1/frcpa(1+112/256))= +3.64096e-001
+data8 0x3fd77b79922bd378, 0x3cb727d8804491f4 // log(1/frcpa(1+113/256))= +3.66911e-001
+data8 0x3fd7a9b9889f19e0, 0x3ca2ef22df5bc543 // log(1/frcpa(1+114/256))= +3.69734e-001
+data8 0x3fd7d81b037eb6a0, 0x3cb8fd3ba07a7ece // log(1/frcpa(1+115/256))= +3.72565e-001
+data8 0x3fd8069e33827230, 0x3c8bd1e25866e61a // log(1/frcpa(1+116/256))= +3.75404e-001
+data8 0x3fd82996d3ef8bc8, 0x3ca5aab9f5928928 // log(1/frcpa(1+117/256))= +3.77538e-001
+data8 0x3fd85855776dcbf8, 0x3ca56f33337789d6 // log(1/frcpa(1+118/256))= +3.80391e-001
+data8 0x3fd8873658327cc8, 0x3cbb8ef0401db49d // log(1/frcpa(1+119/256))= +3.83253e-001
+data8 0x3fd8aa75973ab8c8, 0x3cbb9961f509a680 // log(1/frcpa(1+120/256))= +3.85404e-001
+data8 0x3fd8d992dc8824e0, 0x3cb220512a53732d // log(1/frcpa(1+121/256))= +3.88280e-001
+data8 0x3fd908d2ea7d9510, 0x3c985f0e513bfb5c // log(1/frcpa(1+122/256))= +3.91164e-001
+data8 0x3fd92c59e79c0e50, 0x3cb82e073fd30d63 // log(1/frcpa(1+123/256))= +3.93332e-001
+data8 0x3fd95bd750ee3ed0, 0x3ca4aa7cdb6dd8a8 // log(1/frcpa(1+124/256))= +3.96231e-001
+data8 0x3fd98b7811a3ee58, 0x3caa93a5b660893e // log(1/frcpa(1+125/256))= +3.99138e-001
+data8 0x3fd9af47f33d4068, 0x3cac294b3b3190ba // log(1/frcpa(1+126/256))= +4.01323e-001
+data8 0x3fd9df270c1914a0, 0x3cbe1a58fd0cd67e // log(1/frcpa(1+127/256))= +4.04245e-001
+data8 0x3fda0325ed14fda0, 0x3cb1efa7950fb57e // log(1/frcpa(1+128/256))= +4.06442e-001
+data8 0x3fda33440224fa78, 0x3c8915fe75e7d477 // log(1/frcpa(1+129/256))= +4.09379e-001
+data8 0x3fda57725e80c380, 0x3ca72bd1062b1b7f // log(1/frcpa(1+130/256))= +4.11587e-001
+data8 0x3fda87d0165dd198, 0x3c91f7845f58dbad // log(1/frcpa(1+131/256))= +4.14539e-001
+data8 0x3fdaac2e6c03f890, 0x3cb6f237a911c509 // log(1/frcpa(1+132/256))= +4.16759e-001
+data8 0x3fdadccc6fdf6a80, 0x3c90ddc4b7687169 // log(1/frcpa(1+133/256))= +4.19726e-001
+data8 0x3fdb015b3eb1e790, 0x3c692dd7d90e1e8e // log(1/frcpa(1+134/256))= +4.21958e-001
+data8 0x3fdb323a3a635948, 0x3c6f85655cbe14de // log(1/frcpa(1+135/256))= +4.24941e-001
+data8 0x3fdb56fa04462908, 0x3c95252d841994de // log(1/frcpa(1+136/256))= +4.27184e-001
+data8 0x3fdb881aa659bc90, 0x3caa53a745a3642f // log(1/frcpa(1+137/256))= +4.30182e-001
+data8 0x3fdbad0bef3db160, 0x3cb32f2540dcc16a // log(1/frcpa(1+138/256))= +4.32437e-001
+data8 0x3fdbd21297781c28, 0x3cbd8e891e106f1d // log(1/frcpa(1+139/256))= +4.34697e-001
+data8 0x3fdc039236f08818, 0x3c809435af522ba7 // log(1/frcpa(1+140/256))= +4.37718e-001
+data8 0x3fdc28cb1e4d32f8, 0x3cb3944752fbd81e // log(1/frcpa(1+141/256))= +4.39990e-001
+data8 0x3fdc4e19b84723c0, 0x3c9a465260cd3fe5 // log(1/frcpa(1+142/256))= +4.42267e-001
+data8 0x3fdc7ff9c74554c8, 0x3c92447d5b6ca369 // log(1/frcpa(1+143/256))= +4.45311e-001
+data8 0x3fdca57b64e9db00, 0x3cb44344a8a00c82 // log(1/frcpa(1+144/256))= +4.47600e-001
+data8 0x3fdccb130a5ceba8, 0x3cbefaddfb97b73f // log(1/frcpa(1+145/256))= +4.49895e-001
+data8 0x3fdcf0c0d18f3268, 0x3cbd3e7bfee57898 // log(1/frcpa(1+146/256))= +4.52194e-001
+data8 0x3fdd232075b5a200, 0x3c9222599987447c // log(1/frcpa(1+147/256))= +4.55269e-001
+data8 0x3fdd490246defa68, 0x3cabafe9a767a80d // log(1/frcpa(1+148/256))= +4.57581e-001
+data8 0x3fdd6efa918d25c8, 0x3cb58a2624e1c6fd // log(1/frcpa(1+149/256))= +4.59899e-001
+data8 0x3fdd9509707ae528, 0x3cbdc3babce578e7 // log(1/frcpa(1+150/256))= +4.62221e-001
+data8 0x3fddbb2efe92c550, 0x3cb0ac0943c434a4 // log(1/frcpa(1+151/256))= +4.64550e-001
+data8 0x3fddee2f3445e4a8, 0x3cbba9d07ce820e8 // log(1/frcpa(1+152/256))= +4.67663e-001
+data8 0x3fde148a1a2726c8, 0x3cb6537e3375b205 // log(1/frcpa(1+153/256))= +4.70004e-001
+data8 0x3fde3afc0a49ff38, 0x3cbfed5518dbc20e // log(1/frcpa(1+154/256))= +4.72350e-001
+data8 0x3fde6185206d5168, 0x3cb6572601f73d5c // log(1/frcpa(1+155/256))= +4.74702e-001
+data8 0x3fde882578823d50, 0x3c9b24abd4584d1a // log(1/frcpa(1+156/256))= +4.77060e-001
+data8 0x3fdeaedd2eac9908, 0x3cb0ceb5e4d2c8f7 // log(1/frcpa(1+157/256))= +4.79423e-001
+data8 0x3fded5ac5f436be0, 0x3ca72f21f1f5238e // log(1/frcpa(1+158/256))= +4.81792e-001
+data8 0x3fdefc9326d16ab8, 0x3c85081a1639a45c // log(1/frcpa(1+159/256))= +4.84166e-001
+data8 0x3fdf2391a21575f8, 0x3cbf11015bdd297a // log(1/frcpa(1+160/256))= +4.86546e-001
+data8 0x3fdf4aa7ee031928, 0x3cb3795bc052a2d1 // log(1/frcpa(1+161/256))= +4.88932e-001
+data8 0x3fdf71d627c30bb0, 0x3c35c61f0f5a88f3 // log(1/frcpa(1+162/256))= +4.91323e-001
+data8 0x3fdf991c6cb3b378, 0x3c97d99419be6028 // log(1/frcpa(1+163/256))= +4.93720e-001
+data8 0x3fdfc07ada69a908, 0x3cbfe9341ded70b1 // log(1/frcpa(1+164/256))= +4.96123e-001
+data8 0x3fdfe7f18eb03d38, 0x3cb85718a640c33f // log(1/frcpa(1+165/256))= +4.98532e-001
+data8 0x3fe007c053c5002c, 0x3cb3addc9c065f09 // log(1/frcpa(1+166/256))= +5.00946e-001
+data8 0x3fe01b942198a5a0, 0x3c9d5aa4c77da6ac // log(1/frcpa(1+167/256))= +5.03367e-001
+data8 0x3fe02f74400c64e8, 0x3cb5a0ee4450ef52 // log(1/frcpa(1+168/256))= +5.05793e-001
+data8 0x3fe04360be7603ac, 0x3c9dd00c35630fe0 // log(1/frcpa(1+169/256))= +5.08225e-001
+data8 0x3fe05759ac47fe30, 0x3cbd063e1f0bd82c // log(1/frcpa(1+170/256))= +5.10663e-001
+data8 0x3fe06b5f1911cf50, 0x3cae8da674af5289 // log(1/frcpa(1+171/256))= +5.13107e-001
+data8 0x3fe078bf0533c568, 0x3c62241edf5fd1f7 // log(1/frcpa(1+172/256))= +5.14740e-001
+data8 0x3fe08cd9687e7b0c, 0x3cb3007febcca227 // log(1/frcpa(1+173/256))= +5.17194e-001
+data8 0x3fe0a10074cf9018, 0x3ca496e84603816b // log(1/frcpa(1+174/256))= +5.19654e-001
+data8 0x3fe0b5343a234474, 0x3cb46098d14fc90a // log(1/frcpa(1+175/256))= +5.22120e-001
+data8 0x3fe0c974c89431cc, 0x3cac0a7cdcbb86c6 // log(1/frcpa(1+176/256))= +5.24592e-001
+data8 0x3fe0ddc2305b9884, 0x3cb2f753210410ff // log(1/frcpa(1+177/256))= +5.27070e-001
+data8 0x3fe0eb524bafc918, 0x3c88affd6682229e // log(1/frcpa(1+178/256))= +5.28726e-001
+data8 0x3fe0ffb54213a474, 0x3cadeefbab9af993 // log(1/frcpa(1+179/256))= +5.31214e-001
+data8 0x3fe114253da97d9c, 0x3cbaf1c2b8bc160a // log(1/frcpa(1+180/256))= +5.33709e-001
+data8 0x3fe128a24f1d9afc, 0x3cb9cf4df375e650 // log(1/frcpa(1+181/256))= +5.36210e-001
+data8 0x3fe1365252bf0864, 0x3c985a621d4be111 // log(1/frcpa(1+182/256))= +5.37881e-001
+data8 0x3fe14ae558b4a92c, 0x3ca104c4aa8977d1 // log(1/frcpa(1+183/256))= +5.40393e-001
+data8 0x3fe15f85a19c7658, 0x3cbadf26e540f375 // log(1/frcpa(1+184/256))= +5.42910e-001
+data8 0x3fe16d4d38c119f8, 0x3cb3aea11caec416 // log(1/frcpa(1+185/256))= +5.44592e-001
+data8 0x3fe18203c20dd130, 0x3cba82d1211d1d6d // log(1/frcpa(1+186/256))= +5.47121e-001
+data8 0x3fe196c7bc4b1f38, 0x3cb6267acc4f4f4a // log(1/frcpa(1+187/256))= +5.49656e-001
+data8 0x3fe1a4a738b7a33c, 0x3c858930213c987d // log(1/frcpa(1+188/256))= +5.51349e-001
+data8 0x3fe1b981c0c9653c, 0x3c9bc2a4a30f697b // log(1/frcpa(1+189/256))= +5.53895e-001
+data8 0x3fe1ce69e8bb1068, 0x3cb7ae6199cf2a00 // log(1/frcpa(1+190/256))= +5.56447e-001
+data8 0x3fe1dc619de06944, 0x3c6b50bb38388177 // log(1/frcpa(1+191/256))= +5.58152e-001
+data8 0x3fe1f160a2ad0da0, 0x3cbd05b2778a5e1d // log(1/frcpa(1+192/256))= +5.60715e-001
+data8 0x3fe2066d7740737c, 0x3cb32e828f9c6bd6 // log(1/frcpa(1+193/256))= +5.63285e-001
+data8 0x3fe2147dba47a390, 0x3cbd579851b8b672 // log(1/frcpa(1+194/256))= +5.65001e-001
+data8 0x3fe229a1bc5ebac0, 0x3cbb321be5237ce8 // log(1/frcpa(1+195/256))= +5.67582e-001
+data8 0x3fe237c1841a502c, 0x3cb3b56e0915ea64 // log(1/frcpa(1+196/256))= +5.69306e-001
+data8 0x3fe24cfce6f80d98, 0x3cb34a4d1a422919 // log(1/frcpa(1+197/256))= +5.71898e-001
+data8 0x3fe25b2c55cd5760, 0x3cb237401ea5015e // log(1/frcpa(1+198/256))= +5.73630e-001
+data8 0x3fe2707f4d5f7c40, 0x3c9d30f20acc8341 // log(1/frcpa(1+199/256))= +5.76233e-001
+data8 0x3fe285e0842ca380, 0x3cbc4d866d5f21c0 // log(1/frcpa(1+200/256))= +5.78842e-001
+data8 0x3fe294294708b770, 0x3cb85e14d5dc54fa // log(1/frcpa(1+201/256))= +5.80586e-001
+data8 0x3fe2a9a2670aff0c, 0x3c7e6f8f468bbf91 // log(1/frcpa(1+202/256))= +5.83207e-001
+data8 0x3fe2b7fb2c8d1cc0, 0x3c930ffcf63c8b65 // log(1/frcpa(1+203/256))= +5.84959e-001
+data8 0x3fe2c65a6395f5f4, 0x3ca0afe20b53d2d2 // log(1/frcpa(1+204/256))= +5.86713e-001
+data8 0x3fe2dbf557b0df40, 0x3cb646be1188fbc9 // log(1/frcpa(1+205/256))= +5.89350e-001
+data8 0x3fe2ea64c3f97654, 0x3c96516fa8df33b2 // log(1/frcpa(1+206/256))= +5.91113e-001
+data8 0x3fe3001823684d70, 0x3cb96d64e16d1360 // log(1/frcpa(1+207/256))= +5.93762e-001
+data8 0x3fe30e97e9a8b5cc, 0x3c98ef96bc97cca0 // log(1/frcpa(1+208/256))= +5.95531e-001
+data8 0x3fe32463ebdd34e8, 0x3caef1dc9a56c1bf // log(1/frcpa(1+209/256))= +5.98192e-001
+data8 0x3fe332f4314ad794, 0x3caa4f0ac5d5fa11 // log(1/frcpa(1+210/256))= +5.99970e-001
+data8 0x3fe348d90e7464cc, 0x3cbe7889f0516acd // log(1/frcpa(1+211/256))= +6.02643e-001
+data8 0x3fe35779f8c43d6c, 0x3ca96bbab7245411 // log(1/frcpa(1+212/256))= +6.04428e-001
+data8 0x3fe36621961a6a98, 0x3ca31f32262db9fb // log(1/frcpa(1+213/256))= +6.06217e-001
+data8 0x3fe37c299f3c3668, 0x3cb15c72c107ee29 // log(1/frcpa(1+214/256))= +6.08907e-001
+data8 0x3fe38ae2171976e4, 0x3cba42a2554b2dd4 // log(1/frcpa(1+215/256))= +6.10704e-001
+data8 0x3fe399a157a603e4, 0x3cb99c62286d8919 // log(1/frcpa(1+216/256))= +6.12504e-001
+data8 0x3fe3afccfe77b9d0, 0x3ca11048f96a43bd // log(1/frcpa(1+217/256))= +6.15210e-001
+data8 0x3fe3be9d503533b4, 0x3ca4022f47588c3e // log(1/frcpa(1+218/256))= +6.17018e-001
+data8 0x3fe3cd7480b4a8a0, 0x3cb4ba7afc2dc56a // log(1/frcpa(1+219/256))= +6.18830e-001
+data8 0x3fe3e3c43918f76c, 0x3c859673d064b8ba // log(1/frcpa(1+220/256))= +6.21554e-001
+data8 0x3fe3f2acb27ed6c4, 0x3cb55c6b452a16a8 // log(1/frcpa(1+221/256))= +6.23373e-001
+data8 0x3fe4019c2125ca90, 0x3cb8c367879c5a31 // log(1/frcpa(1+222/256))= +6.25197e-001
+data8 0x3fe4181061389720, 0x3cb2c17a79c5cc6c // log(1/frcpa(1+223/256))= +6.27937e-001
+data8 0x3fe42711518df544, 0x3ca5f38d47012fc5 // log(1/frcpa(1+224/256))= +6.29769e-001
+data8 0x3fe436194e12b6bc, 0x3cb9854d65a9b426 // log(1/frcpa(1+225/256))= +6.31604e-001
+data8 0x3fe445285d68ea68, 0x3ca3ff9b3a81cd81 // log(1/frcpa(1+226/256))= +6.33442e-001
+data8 0x3fe45bcc464c8938, 0x3cb0a2d8011a6c05 // log(1/frcpa(1+227/256))= +6.36206e-001
+data8 0x3fe46aed21f117fc, 0x3c8a2be41f8e9f3d // log(1/frcpa(1+228/256))= +6.38053e-001
+data8 0x3fe47a1527e8a2d0, 0x3cba4a83594fab09 // log(1/frcpa(1+229/256))= +6.39903e-001
+data8 0x3fe489445efffcc8, 0x3cbf306a23dcbcde // log(1/frcpa(1+230/256))= +6.41756e-001
+data8 0x3fe4a018bcb69834, 0x3ca46c9285029fd1 // log(1/frcpa(1+231/256))= +6.44543e-001
+data8 0x3fe4af5a0c9d65d4, 0x3cbbc1db897580e3 // log(1/frcpa(1+232/256))= +6.46405e-001
+data8 0x3fe4bea2a5bdbe84, 0x3cb84d880d7ef775 // log(1/frcpa(1+233/256))= +6.48271e-001
+data8 0x3fe4cdf28f10ac44, 0x3cb3ec4b7893ce1f // log(1/frcpa(1+234/256))= +6.50140e-001
+data8 0x3fe4dd49cf994058, 0x3c897224d59d3408 // log(1/frcpa(1+235/256))= +6.52013e-001
+data8 0x3fe4eca86e64a680, 0x3cbccf620f24f0cd // log(1/frcpa(1+236/256))= +6.53889e-001
+data8 0x3fe503c43cd8eb68, 0x3c3f872c65971084 // log(1/frcpa(1+237/256))= +6.56710e-001
+data8 0x3fe513356667fc54, 0x3cb9ca64cc3d52c8 // log(1/frcpa(1+238/256))= +6.58595e-001
+data8 0x3fe522ae0738a3d4, 0x3cbe708164c75968 // log(1/frcpa(1+239/256))= +6.60483e-001
+data8 0x3fe5322e26867854, 0x3cb9988ba4aea615 // log(1/frcpa(1+240/256))= +6.62376e-001
+data8 0x3fe541b5cb979808, 0x3ca1662e3a6b95f5 // log(1/frcpa(1+241/256))= +6.64271e-001
+data8 0x3fe55144fdbcbd60, 0x3cb3acd4ca45c1e0 // log(1/frcpa(1+242/256))= +6.66171e-001
+data8 0x3fe560dbc45153c4, 0x3cb4988947959fed // log(1/frcpa(1+243/256))= +6.68074e-001
+data8 0x3fe5707a26bb8c64, 0x3cb3017fe6607ba9 // log(1/frcpa(1+244/256))= +6.69980e-001
+data8 0x3fe587f60ed5b8fc, 0x3cbe7a3266366ed4 // log(1/frcpa(1+245/256))= +6.72847e-001
+data8 0x3fe597a7977c8f30, 0x3ca1e12b9959a90e // log(1/frcpa(1+246/256))= +6.74763e-001
+data8 0x3fe5a760d634bb88, 0x3cb7c365e53d9602 // log(1/frcpa(1+247/256))= +6.76682e-001
+data8 0x3fe5b721d295f10c, 0x3cb716c2551ccbf0 // log(1/frcpa(1+248/256))= +6.78605e-001
+data8 0x3fe5c6ea94431ef8, 0x3ca02b2ed0e28261 // log(1/frcpa(1+249/256))= +6.80532e-001
+data8 0x3fe5d6bb22ea86f4, 0x3caf43a8bbb2f974 // log(1/frcpa(1+250/256))= +6.82462e-001
+data8 0x3fe5e6938645d38c, 0x3cbcedc98821b333 // log(1/frcpa(1+251/256))= +6.84397e-001
+data8 0x3fe5f673c61a2ed0, 0x3caa385eef5f2789 // log(1/frcpa(1+252/256))= +6.86335e-001
+data8 0x3fe6065bea385924, 0x3cb11624f165c5b4 // log(1/frcpa(1+253/256))= +6.88276e-001
+data8 0x3fe6164bfa7cc068, 0x3cbad884f87073fa // log(1/frcpa(1+254/256))= +6.90222e-001
+data8 0x3fe62643fecf9740, 0x3cb78c51da12f4df // log(1/frcpa(1+255/256))= +6.92171e-001
+LOCAL_OBJECT_END(pow_Tt)
+
+
+// Table 1 is 2^(index_1/128) where
+// index_1 goes from 0 to 15
+LOCAL_OBJECT_START(pow_tbl1)
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x80B1ED4FD999AB6C , 0x00003FFF
+data8 0x8164D1F3BC030773 , 0x00003FFF
+data8 0x8218AF4373FC25EC , 0x00003FFF
+data8 0x82CD8698AC2BA1D7 , 0x00003FFF
+data8 0x8383594EEFB6EE37 , 0x00003FFF
+data8 0x843A28C3ACDE4046 , 0x00003FFF
+data8 0x84F1F656379C1A29 , 0x00003FFF
+data8 0x85AAC367CC487B15 , 0x00003FFF
+data8 0x8664915B923FBA04 , 0x00003FFF
+data8 0x871F61969E8D1010 , 0x00003FFF
+data8 0x87DB357FF698D792 , 0x00003FFF
+data8 0x88980E8092DA8527 , 0x00003FFF
+data8 0x8955EE03618E5FDD , 0x00003FFF
+data8 0x8A14D575496EFD9A , 0x00003FFF
+data8 0x8AD4C6452C728924 , 0x00003FFF
+LOCAL_OBJECT_END(pow_tbl1)
+
+
+// Table 2 is 2^(index_1/8) where
+// index_2 goes from 0 to 7
+LOCAL_OBJECT_START(pow_tbl2)
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x8B95C1E3EA8BD6E7 , 0x00003FFF
+data8 0x9837F0518DB8A96F , 0x00003FFF
+data8 0xA5FED6A9B15138EA , 0x00003FFF
+data8 0xB504F333F9DE6484 , 0x00003FFF
+data8 0xC5672A115506DADD , 0x00003FFF
+data8 0xD744FCCAD69D6AF4 , 0x00003FFF
+data8 0xEAC0C6E7DD24392F , 0x00003FFF
+LOCAL_OBJECT_END(pow_tbl2)
+
+.section .text
+GLOBAL_LIBM_ENTRY(pow)
+
+// Get exponent of x. Will be used to calculate K.
+{ .mfi
+ getf.exp pow_GR_signexp_X = f8
+ fms.s1 POW_Xm1 = f8,f1,f1 // Will be used for r1 if x>0
+ mov pow_GR_17ones = 0x1FFFF
+}
+{ .mfi
+ addl pow_AD_P = @ltoff(pow_table_P), gp
+ fma.s1 POW_Xp1 = f8,f1,f1 // Will be used for r1 if x<0
+ nop.i 999
+;;
+}
+
+// Get significand of x. Will be used to get index to fetch T, Tt.
+{ .mfi
+ getf.sig pow_GR_sig_X = f8
+ frcpa.s1 POW_B, p6 = f1,f8
+ nop.i 999
+}
+{ .mfi
+ ld8 pow_AD_P = [pow_AD_P]
+ fma.s1 POW_NORM_X = f8,f1,f0
+ mov pow_GR_exp_2tom8 = 0xFFF7
+}
+;;
+
+// p13 = TRUE ==> X is unorm
+// DOUBLE 0x10033 exponent limit at which y is an integer
+{ .mfi
+ nop.m 999
+ fclass.m p13,p0 = f8, 0x0b // Test for x unorm
+ addl pow_GR_10033 = 0x10033, r0
+}
+{ .mfi
+ mov pow_GR_16ones = 0xFFFF
+ fma.s1 POW_NORM_Y = f9,f1,f0
+ nop.i 999
+}
+;;
+
+// p14 = TRUE ==> X is ZERO
+{ .mfi
+ adds pow_AD_Tt = pow_Tt - pow_table_P, pow_AD_P
+ fclass.m p14,p0 = f8, 0x07
+ and pow_GR_exp_X = pow_GR_signexp_X, pow_GR_17ones
+}
+{ .mfi
+ adds pow_AD_Q = pow_table_Q - pow_table_P, pow_AD_P
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe POW_P5 = [pow_AD_P], 16
+ fcmp.lt.s1 p8,p9 = f8, f0 // Test for x<0
+ nop.i 999
+}
+{ .mib
+ ldfe POW_P4 = [pow_AD_Q], 16
+ sub pow_GR_true_exp_X = pow_GR_exp_X, pow_GR_16ones
+(p13) br.cond.spnt POW_X_DENORM
+}
+;;
+
+// Continue normal and denormal paths here
+POW_COMMON:
+// p11 = TRUE ==> Y is a NAN
+{ .mfi
+ ldfe POW_P3 = [pow_AD_P], 16
+ fclass.m p11,p0 = f9, 0xc3
+ nop.i 999
+}
+{ .mfi
+ ldfe POW_P2 = [pow_AD_Q], 16
+ nop.f 999
+ mov pow_GR_y_zero = 0
+}
+;;
+
+// Note POW_Xm1 and POW_r1 are used interchangably
+{ .mfi
+ alloc r32=ar.pfs,2,19,4,0
+ fms.s1 POW_r = POW_B, POW_NORM_X,f1
+ nop.i 999
+}
+{ .mfi
+ setf.sig POW_int_K = pow_GR_true_exp_X
+(p8) fnma.s1 POW_Xm1 = POW_Xp1,f1,f0
+ nop.i 999
+}
+;;
+
+// p12 = TRUE if Y is ZERO
+// Compute xsq to decide later if |x|=1
+{ .mfi
+ ldfe POW_P1 = [pow_AD_P], 16
+ fclass.m p12,p0 = f9, 0x07
+ shl pow_GR_offset = pow_GR_sig_X, 1
+}
+{ .mfb
+ ldfe POW_P0 = [pow_AD_Q], 16
+ fma.s1 POW_xsq = POW_NORM_X, POW_NORM_X, f0
+(p11) br.cond.spnt POW_Y_NAN // Branch if y=nan
+}
+;;
+
+// Get exponent of |x|-1 to use in comparison to 2^-8
+{ .mfi
+ getf.exp pow_GR_signexp_Xm1 = POW_Xm1
+ fcvt.fx.s1 POW_int_Y = POW_NORM_Y
+ shr.u pow_GR_offset = pow_GR_offset,56
+}
+;;
+
+// p11 = TRUE ==> X is a NAN
+{ .mfi
+ ldfpd POW_log2_hi, POW_log2_lo = [pow_AD_Q], 16
+ fclass.m p11,p0 = f8, 0xc3
+ shladd pow_AD_Tt = pow_GR_offset, 4, pow_AD_Tt
+}
+{ .mfi
+ ldfe POW_inv_log2_by_128 = [pow_AD_P], 16
+ fma.s1 POW_delta = f0,f0,f0 // delta=0 in case |x| near 1
+(p12) mov pow_GR_y_zero = 1
+}
+;;
+
+{ .mfi
+ ldfpd POW_Q2, POW_Q3 = [pow_AD_P], 16
+ fma.s1 POW_G = f0,f0,f0 // G=0 in case |x| near 1
+ and pow_GR_exp_Xm1 = pow_GR_signexp_Xm1, pow_GR_17ones
+}
+;;
+
+// Determine if we will use the |x| near 1 path (p6) or normal path (p7)
+{ .mfi
+ getf.exp pow_GR_signexp_Y = POW_NORM_Y
+ nop.f 999
+ cmp.lt p6,p7 = pow_GR_exp_Xm1, pow_GR_exp_2tom8
+}
+{ .mfb
+ ldfpd POW_T, POW_Tt = [pow_AD_Tt], 16
+ fma.s1 POW_rsq = POW_r, POW_r,f0
+(p11) br.cond.spnt POW_X_NAN // Branch if x=nan and y not nan
+}
+;;
+
+// If on the x near 1 path, assign r1 to r and r1*r1 to rsq
+{ .mfi
+ ldfpd POW_Q0_half, POW_Q1 = [pow_AD_P], 16
+(p6) fma.s1 POW_r = POW_r1, f1, f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p6) fma.s1 POW_rsq = POW_r1, POW_r1, f0
+(p14) br.cond.spnt POW_X_0 // Branch if x zero and y not nan
+}
+;;
+
+{ .mfi
+ ldfpd POW_Q4, POW_RSHF = [pow_AD_P], 16
+(p7) fma.s1 POW_v6 = POW_r, POW_P5, POW_P4
+ nop.i 999
+}
+{ .mfi
+ mov pow_GR_exp_2toM63 = 0xffc0 // Exponent of 2^-63
+(p6) fma.s1 POW_v6 = POW_r1, POW_P5, POW_P4
+ nop.i 999
+}
+;;
+
+{ .mfi
+ setf.exp POW_2toM63 = pow_GR_exp_2toM63 // Form 2^-63 for test of q
+(p7) fma.s1 POW_v4 = POW_P3, POW_r, POW_P2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p6) fma.s1 POW_v4 = POW_P3, POW_r1, POW_P2
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcvt.xf POW_K = POW_int_K
+ nop.i 999
+}
+;;
+
+{ .mfi
+ getf.sig pow_GR_sig_int_Y = POW_int_Y
+ fnma.s1 POW_twoV = POW_NORM_Y, POW_rsq,f0
+ and pow_GR_exp_Y = pow_GR_signexp_Y, pow_GR_17ones
+}
+{ .mfb
+ andcm pow_GR_sign_Y = pow_GR_signexp_Y, pow_GR_17ones
+ fma.s1 POW_U = POW_NORM_Y,POW_r,f0
+(p12) br.cond.spnt POW_Y_0 // Branch if y=zero, x not zero or nan
+}
+;;
+
+// p11 = TRUE ==> X is NEGATIVE but not inf
+{ .mfi
+ ldfe POW_log2_by_128_lo = [pow_AD_P], 16
+ fclass.m p11,p0 = f8, 0x1a
+ nop.i 999
+}
+{ .mfi
+ ldfe POW_log2_by_128_hi = [pow_AD_Q], 16
+ fma.s1 POW_v2 = POW_P1, POW_r, POW_P0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcvt.xf POW_float_int_Y = POW_int_Y
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_v3 = POW_v6, POW_rsq, POW_v4
+ adds pow_AD_tbl1 = pow_tbl1 - pow_Tt, pow_AD_Q
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fma.s1 POW_delta = POW_K, POW_log2_lo, POW_Tt
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fma.s1 POW_G = POW_K, POW_log2_hi, POW_T
+ adds pow_AD_tbl2 = pow_tbl2 - pow_tbl1, pow_AD_tbl1
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fms.s1 POW_e2 = POW_NORM_Y, POW_r, POW_U
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_Z2 = POW_twoV, POW_Q0_half, POW_U
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_Yrcub = POW_rsq, POW_U, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_p = POW_rsq, POW_v3, POW_v2
+ nop.i 999
+}
+;;
+
+// p11 = TRUE ==> X is NEGATIVE but not inf
+// p12 = TRUE ==> X is NEGATIVE AND Y already even int
+// p13 = TRUE ==> X is NEGATIVE AND Y possible int
+{ .mfi
+ nop.m 999
+ fma.s1 POW_Z1 = POW_NORM_Y, POW_G, f0
+(p11) cmp.gt.unc p12,p13 = pow_GR_exp_Y, pow_GR_10033
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_Gpr = POW_G, f1, POW_r
+ nop.i 999
+}
+;;
+
+// By adding RSHF (1.1000...*2^63) we put integer part in rightmost significand
+{ .mfi
+ nop.m 999
+ fma.s1 POW_W2 = POW_Z2, POW_inv_log2_by_128, POW_RSHF
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fms.s1 POW_UmZ2 = POW_U, f1, POW_Z2
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_e3 = POW_NORM_Y, POW_delta, f0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_Z3 = POW_p, POW_Yrcub, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_GY_Z2 = POW_G, POW_NORM_Y, POW_Z2
+ nop.i 999
+}
+;;
+
+// By adding RSHF (1.1000...*2^63) we put integer part in rightmost significand
+{ .mfi
+ nop.m 999
+ fms.s1 POW_e1 = POW_NORM_Y, POW_G, POW_Z1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_W1 = POW_Z1, POW_inv_log2_by_128, POW_RSHF
+ nop.i 999
+}
+;;
+
+// p13 = TRUE ==> X is NEGATIVE AND Y possible int
+// p10 = TRUE ==> X is NEG and Y is an int
+// p12 = TRUE ==> X is NEG and Y is not an int
+{ .mfi
+ nop.m 999
+(p13) fcmp.eq.unc.s1 p10,p12 = POW_float_int_Y, POW_NORM_Y
+ mov pow_GR_xneg_yodd = 0
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_Y_Gpr = POW_NORM_Y, POW_Gpr, f0
+ nop.i 999
+}
+;;
+
+// By subtracting RSHF we get rounded integer POW_N2float
+{ .mfi
+ nop.m 999
+ fms.s1 POW_N2float = POW_W2, f1, POW_RSHF
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_UmZ2pV = POW_twoV,POW_Q0_half,POW_UmZ2
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_Z3sq = POW_Z3, POW_Z3, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_v4 = POW_Z3, POW_Q3, POW_Q2
+ nop.i 999
+}
+;;
+
+// Extract rounded integer from rightmost significand of POW_W2
+// By subtracting RSHF we get rounded integer POW_N1float
+{ .mfi
+ getf.sig pow_GR_int_W2 = POW_W2
+ fms.s1 POW_N1float = POW_W1, f1, POW_RSHF
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_v2 = POW_Z3, POW_Q1, POW_Q0_half
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fnma.s1 POW_s2 = POW_N2float, POW_log2_by_128_hi, POW_Z2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_e2 = POW_e2,f1,POW_UmZ2pV
+ nop.i 999
+}
+;;
+
+// Extract rounded integer from rightmost significand of POW_W1
+// Test if x inf
+{ .mfi
+ getf.sig pow_GR_int_W1 = POW_W1
+ fclass.m p15,p0 = POW_NORM_X, 0x23
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fnma.s1 POW_f2 = POW_N2float, POW_log2_by_128_lo, f1
+(p12) br.cond.spnt POW_X_NEG_Y_NONINT // Branch if x neg, y not integer
+}
+;;
+
+// p11 = TRUE ==> X is +1.0
+// p12 = TRUE ==> X is NEGATIVE AND Y is an odd integer
+{ .mfi
+ getf.exp pow_GR_signexp_Y_Gpr = POW_Y_Gpr
+ fcmp.eq.s1 p11,p0 = POW_NORM_X, f1
+(p10) tbit.nz.unc p12,p0 = pow_GR_sig_int_Y,0
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_v3 = POW_Z3sq, POW_Q4, POW_v4
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fnma.s1 POW_f1 = POW_N1float, POW_log2_by_128_lo, f1
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fnma.s1 POW_s1 = POW_N1float, POW_log2_by_128_hi, POW_Z1
+(p15) br.cond.spnt POW_X_INF
+}
+;;
+
+// Test x and y and flag denormal
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p15,p0 = f8,f9
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_pYrcub_e3 = POW_p, POW_Yrcub, POW_e3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.s1 p7,p0 = POW_NORM_Y, f1 // Test for y=1.0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_e12 = POW_e1,f1,POW_e2
+ nop.i 999
+}
+;;
+
+{ .mfi
+ add pow_GR_int_N = pow_GR_int_W1, pow_GR_int_W2
+(p11) fma.d.s0 f8 = f1,f1,f0 // If x=1, result is +1
+ nop.i 999
+}
+{ .mib
+(p12) mov pow_GR_xneg_yodd = 1
+ nop.i 999
+(p11) br.ret.spnt b0 // Early exit if x=1.0, result is +1
+}
+;;
+
+{ .mfi
+ and pow_GR_index1 = 0x0f, pow_GR_int_N
+ fma.s1 POW_q = POW_Z3sq, POW_v3, POW_v2
+ shr pow_int_GR_M = pow_GR_int_N, 7 // M = N/128
+}
+{ .mib
+ and pow_GR_index2 = 0x70, pow_GR_int_N
+ cmp.eq p6, p0 = pow_GR_xneg_yodd, r0
+(p7) br.ret.spnt b0 // Early exit if y=1.0, result is x
+}
+;;
+
+{ .mfi
+ shladd pow_AD_T1 = pow_GR_index1, 4, pow_AD_tbl1
+ fma.s1 POW_s = POW_s1, f1, POW_s2
+ add pow_int_GR_M = pow_GR_16ones, pow_int_GR_M
+}
+{ .mfi
+ add pow_AD_T2 = pow_AD_tbl2, pow_GR_index2
+ fma.s1 POW_f12 = POW_f1, POW_f2,f0
+ and pow_GR_exp_Y_Gpr = pow_GR_signexp_Y_Gpr, pow_GR_17ones
+}
+;;
+
+{ .mmi
+ ldfe POW_T1 = [pow_AD_T1]
+ ldfe POW_T2 = [pow_AD_T2]
+ sub pow_GR_true_exp_Y_Gpr = pow_GR_exp_Y_Gpr, pow_GR_16ones
+}
+;;
+
+{ .mfi
+ setf.exp POW_2M = pow_int_GR_M
+ fma.s1 POW_e123 = POW_e12, f1, POW_e3
+ nop.i 999
+}
+{ .mfb
+(p6) cmp.gt p6, p0 = -11, pow_GR_true_exp_Y_Gpr
+ fma.s1 POW_d = POW_GY_Z2, f1, POW_pYrcub_e3
+(p6) br.cond.spnt POW_NEAR_ONE // branch if |y*log(x)| < 2^(-11)
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_q = POW_Z3sq, POW_q, POW_Z3
+ nop.i 999
+}
+;;
+
+// p8 TRUE ==> |Y(G + r)| >= 10
+
+// double
+// -2^10 -2^9 2^9 2^10
+// -----+-----+----+ ... +-----+-----+-----
+// p8 | p9 | p8
+// | | p10 | |
+
+// Form signexp of constants to indicate overflow
+{ .mfi
+ mov pow_GR_big_pos = 0x103ff
+ fma.s1 POW_ssq = POW_s, POW_s, f0
+ cmp.le p8,p9 = 10, pow_GR_true_exp_Y_Gpr
+}
+{ .mfi
+ mov pow_GR_big_neg = 0x303ff
+ fma.s1 POW_v4 = POW_s, POW_Q3, POW_Q2
+ andcm pow_GR_sign_Y_Gpr = pow_GR_signexp_Y_Gpr, pow_GR_17ones
+}
+;;
+
+// Form big positive and negative constants to test for possible overflow
+{ .mfi
+ setf.exp POW_big_pos = pow_GR_big_pos
+ fma.s1 POW_v2 = POW_s, POW_Q1, POW_Q0_half
+(p9) cmp.le.unc p0,p10 = 9, pow_GR_true_exp_Y_Gpr
+}
+{ .mfb
+ setf.exp POW_big_neg = pow_GR_big_neg
+ fma.s1 POW_1ps = f1,f1,POW_s
+(p8) br.cond.spnt POW_OVER_UNDER_X_NOT_INF
+}
+;;
+
+// f123 = f12*(e123+1) = f12*e123+f12
+{ .mfi
+ nop.m 999
+ fma.s1 POW_f123 = POW_e123,POW_f12,POW_f12
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_T1T2 = POW_T1, POW_T2, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_v3 = POW_ssq, POW_Q4, POW_v4
+ cmp.ne p12,p13 = pow_GR_xneg_yodd, r0
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_v21ps = POW_ssq, POW_v2, POW_1ps
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_s4 = POW_ssq, POW_ssq, f0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p12) fnma.s1 POW_A = POW_2M, POW_f123, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p13) fma.s1 POW_A = POW_2M, POW_f123, f0
+ cmp.eq p14,p11 = r0,r0 // Initialize p14 on, p11 off
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmerge.s POW_abs_q = f0, POW_q // Form |q| so can test its size
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p10) cmp.eq p0,p14 = r0,r0 // Turn off p14 if no overflow
+ fma.s1 POW_es = POW_s4, POW_v3, POW_v21ps
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_A = POW_A, POW_T1T2, f0
+ nop.i 999
+}
+;;
+
+{ .mfi
+// Test for |q| < 2^-63. If so then reverse last two steps of the result
+// to avoid monotonicity problems for results near 1.0 in round up/down/zero.
+// p11 will be set if need to reverse the order, p14 if not.
+ nop.m 999
+(p10) fcmp.lt.s0 p11,p14 = POW_abs_q, POW_2toM63 // Test |q| <2^-63
+ nop.i 999
+}
+;;
+
+.pred.rel "mutex",p11,p14
+{ .mfi
+ nop.m 999
+(p14) fma.s1 POW_A = POW_A, POW_es, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fma.s1 POW_A = POW_A, POW_q, POW_A
+ nop.i 999
+}
+;;
+
+// Dummy op to set inexact if |q| < 2^-63
+{ .mfi
+ nop.m 999
+(p11) fma.d.s0 POW_tmp = POW_A, POW_q, POW_A
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p14) fma.d.s0 f8 = POW_A, POW_q, POW_A
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p11) fma.d.s0 f8 = POW_A, POW_es, f0
+(p10) br.ret.sptk b0 // Exit main branch if no over/underflow
+}
+;;
+
+// POSSIBLE_OVER_UNDER
+// p6 = TRUE ==> Y_Gpr negative
+// Result is already computed. We just need to know if over/underflow occurred.
+
+{ .mfb
+ cmp.eq p0,p6 = pow_GR_sign_Y_Gpr, r0
+ nop.f 999
+(p6) br.cond.spnt POW_POSSIBLE_UNDER
+}
+;;
+
+// POSSIBLE_OVER
+// We got an answer.
+// overflow is a possibility, not a certainty
+
+
+// We define an overflow when the answer with
+// WRE set
+// user-defined rounding mode
+
+// double
+// Largest double is 7FE (biased double)
+// 7FE - 3FF + FFFF = 103FE
+// Create + largest_double_plus_ulp
+// Create - largest_double_plus_ulp
+// Calculate answer with WRE set.
+
+// single
+// Largest single is FE (biased double)
+// FE - 7F + FFFF = 1007E
+// Create + largest_single_plus_ulp
+// Create - largest_single_plus_ulp
+// Calculate answer with WRE set.
+
+// Cases when answer is ldn+1 are as follows:
+// ldn ldn+1
+// --+----------|----------+------------
+// |
+// +inf +inf -inf
+// RN RN
+// RZ
+
+// Put in s2 (td set, wre set)
+{ .mfi
+ nop.m 999
+ fsetc.s2 0x7F,0x42
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.d.s2 POW_wre_urm_f8 = POW_A, POW_q, POW_A
+ nop.i 999
+}
+;;
+
+// Return s2 to default
+{ .mfi
+ nop.m 999
+ fsetc.s2 0x7F,0x40
+ nop.i 999
+}
+;;
+
+// p7 = TRUE ==> yes, we have an overflow
+{ .mfi
+ nop.m 999
+ fcmp.ge.s1 p7, p8 = POW_wre_urm_f8, POW_big_pos
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fcmp.le.s1 p7, p0 = POW_wre_urm_f8, POW_big_neg
+ nop.i 999
+}
+;;
+
+{ .mbb
+(p7) mov pow_GR_tag = 24
+(p7) br.cond.spnt __libm_error_region // Branch if overflow
+ br.ret.sptk b0 // Exit if did not overflow
+}
+;;
+
+// Here if |y*log(x)| < 2^(-11)
+// pow(x,y) ~ exp(d) ~ 1 + d + 0.5*d^2 + Q1*d^3 + Q2*d^4, where d = y*log(x)
+.align 32
+POW_NEAR_ONE:
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_d2 = POW_d, POW_d, f0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_poly_d_hi = POW_d, POW_Q0_half, f1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_poly_d_lo = POW_d, POW_Q2, POW_Q1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_poly_d = POW_d2, POW_poly_d_lo, POW_poly_d_hi
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+ fma.d.s0 f8 = POW_d, POW_poly_d, f1
+ br.ret.sptk b0 // exit function for arguments |y*log(x)| < 2^(-11)
+}
+;;
+
+POW_POSSIBLE_UNDER:
+// We got an answer. input was < -2^9 but > -2^10 (double)
+// We got an answer. input was < -2^6 but > -2^7 (float)
+// underflow is a possibility, not a certainty
+
+// We define an underflow when the answer with
+// ftz set
+// is zero (tiny numbers become zero)
+// Notice (from below) that if we have an unlimited exponent range,
+// then there is an extra machine number E between the largest denormal and
+// the smallest normal.
+// So if with unbounded exponent we round to E or below, then we are
+// tiny and underflow has occurred.
+// But notice that you can be in a situation where we are tiny, namely
+// rounded to E, but when the exponent is bounded we round to smallest
+// normal. So the answer can be the smallest normal with underflow.
+// E
+// -----+--------------------+--------------------+-----
+// | | |
+// 1.1...10 2^-3fff 1.1...11 2^-3fff 1.0...00 2^-3ffe
+// 0.1...11 2^-3ffe (biased, 1)
+// largest dn smallest normal
+
+// Put in s2 (td set, ftz set)
+{ .mfi
+ nop.m 999
+ fsetc.s2 0x7F,0x41
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.d.s2 POW_ftz_urm_f8 = POW_A, POW_q, POW_A
+ nop.i 999
+}
+;;
+
+// Return s2 to default
+{ .mfi
+ nop.m 999
+ fsetc.s2 0x7F,0x40
+ nop.i 999
+}
+;;
+
+// p7 = TRUE ==> yes, we have an underflow
+{ .mfi
+ nop.m 999
+ fcmp.eq.s1 p7, p0 = POW_ftz_urm_f8, f0
+ nop.i 999
+}
+;;
+
+{ .mbb
+(p7) mov pow_GR_tag = 25
+(p7) br.cond.spnt __libm_error_region // Branch if underflow
+ br.ret.sptk b0 // Exit if did not underflow
+}
+;;
+
+POW_X_DENORM:
+// Here if x unorm. Use the NORM_X for getf instructions, and then back
+// to normal path
+{ .mfi
+ getf.exp pow_GR_signexp_X = POW_NORM_X
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mmi
+ getf.sig pow_GR_sig_X = POW_NORM_X
+;;
+ and pow_GR_exp_X = pow_GR_signexp_X, pow_GR_17ones
+ nop.i 999
+}
+;;
+
+{ .mib
+ sub pow_GR_true_exp_X = pow_GR_exp_X, pow_GR_16ones
+ nop.i 999
+ br.cond.sptk POW_COMMON
+}
+;;
+
+POW_X_0:
+// Here if x=0 and y not nan
+//
+// We have the following cases:
+// p6 x=0 and y>0 and is an integer (may be even or odd)
+// p7 x=0 and y>0 and is NOT an integer, return +0
+// p8 x=0 and y>0 and so big as to always be an even integer, return +0
+// p9 x=0 and y>0 and may not be integer
+// p10 x=0 and y>0 and is an odd integer, return x
+// p11 x=0 and y>0 and is an even integer, return +0
+// p12 used in dummy fcmp to set denormal flag if y=unorm
+// p13 x=0 and y>0
+// p14 x=0 and y=0, branch to code for calling error handling
+// p15 x=0 and y<0, branch to code for calling error handling
+//
+{ .mfi
+ getf.sig pow_GR_sig_int_Y = POW_int_Y // Get signif of int_Y
+ fcmp.lt.s1 p15,p13 = f9, f0 // Test for y<0
+ and pow_GR_exp_Y = pow_GR_signexp_Y, pow_GR_17ones
+}
+{ .mfb
+ cmp.ne p14,p0 = pow_GR_y_zero,r0 // Test for y=0
+ fcvt.xf POW_float_int_Y = POW_int_Y
+(p14) br.cond.spnt POW_X_0_Y_0 // Branch if x=0 and y=0
+}
+;;
+
+// If x=0 and y>0, test y and flag denormal
+{ .mfb
+(p13) cmp.gt.unc p8,p9 = pow_GR_exp_Y, pow_GR_10033 // Test y +big = even int
+(p13) fcmp.eq.s0 p12,p0 = f9,f0 // If x=0, y>0 dummy op to flag denormal
+(p15) br.cond.spnt POW_X_0_Y_NEG // Branch if x=0 and y<0
+}
+;;
+
+// Here if x=0 and y>0
+{ .mfi
+ nop.m 999
+(p9) fcmp.eq.unc.s1 p6,p7 = POW_float_int_Y, POW_NORM_Y // Test y=int
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.d.s0 f8 = f0,f0,f0 // If x=0, y>0 and large even int, return +0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fma.d.s0 f8 = f0,f0,f0 // Result +0 if x=0 and y>0 and not integer
+(p6) tbit.nz.unc p10,p11 = pow_GR_sig_int_Y,0 // If y>0 int, test y even/odd
+}
+;;
+
+// Note if x=0, y>0 and odd integer, just return x
+{ .mfb
+ nop.m 999
+(p11) fma.d.s0 f8 = f0,f0,f0 // Result +0 if x=0 and y even integer
+ br.ret.sptk b0 // Exit if x=0 and y>0
+}
+;;
+
+POW_X_0_Y_0:
+// When X is +-0 and Y is +-0, IEEE returns 1.0
+// We call error support with this value
+
+{ .mfb
+ mov pow_GR_tag = 26
+ fma.d.s0 f8 = f1,f1,f0
+ br.cond.sptk __libm_error_region
+}
+;;
+
+POW_X_0_Y_NEG:
+// When X is +-0 and Y is negative, IEEE returns
+// X Y answer
+// +0 -odd int +inf
+// -0 -odd int -inf
+
+// +0 !-odd int +inf
+// -0 !-odd int +inf
+
+// p6 == Y is a floating point number outside the integer.
+// Hence it is an integer and is even.
+// return +inf
+
+// p7 == Y is a floating point number within the integer range.
+// p9 == (int_Y = NORM_Y), Y is an integer, which may be odd or even.
+// p11 odd
+// return (sign_of_x)inf
+// p12 even
+// return +inf
+// p10 == Y is not an integer
+// return +inf
+//
+
+{ .mfi
+ nop.m 999
+ nop.f 999
+ cmp.gt p6,p7 = pow_GR_exp_Y, pow_GR_10033
+}
+;;
+
+{ .mfi
+ mov pow_GR_tag = 27
+(p7) fcmp.eq.unc.s1 p9,p10 = POW_float_int_Y, POW_NORM_Y
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p6) frcpa.s0 f8,p13 = f1, f0
+(p6) br.cond.sptk __libm_error_region // x=0, y<0, y large neg int
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p10) frcpa.s0 f8,p13 = f1, f0
+(p10) br.cond.sptk __libm_error_region // x=0, y<0, y not int
+}
+;;
+
+// x=0, y<0, y an int
+{ .mib
+ nop.m 999
+(p9) tbit.nz.unc p11,p12 = pow_GR_sig_int_Y,0
+ nop.b 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p12) frcpa.s0 f8,p13 = f1,f0
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p11) frcpa.s0 f8,p13 = f1,f8
+ br.cond.sptk __libm_error_region
+}
+;;
+
+
+POW_Y_0:
+// Here for y zero, x anything but zero and nan
+// Set flag if x denormal
+// Result is +1.0
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p6,p0 = f8,f0 // Sets flag if x denormal
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fma.d.s0 f8 = f1,f1,f0
+ br.ret.sptk b0
+}
+;;
+
+
+POW_X_INF:
+// Here when X is +-inf
+
+// X +inf Y +inf +inf
+// X -inf Y +inf +inf
+
+// X +inf Y >0 +inf
+// X -inf Y >0, !odd integer +inf <== (-inf)^0.5 = +inf !!
+// X -inf Y >0, odd integer -inf
+
+// X +inf Y -inf +0
+// X -inf Y -inf +0
+
+// X +inf Y <0 +0
+// X -inf Y <0, !odd integer +0
+// X -inf Y <0, odd integer -0
+
+// X + inf Y=+0 +1
+// X + inf Y=-0 +1
+// X - inf Y=+0 +1
+// X - inf Y=-0 +1
+
+// p13 == Y negative
+// p14 == Y positive
+
+// p6 == Y is a floating point number outside the integer.
+// Hence it is an integer and is even.
+// p13 == (Y negative)
+// return +inf
+// p14 == (Y positive)
+// return +0
+
+// p7 == Y is a floating point number within the integer range.
+// p9 == (int_Y = NORM_Y), Y is an integer, which may be odd or even.
+// p11 odd
+// p13 == (Y negative)
+// return (sign_of_x)inf
+// p14 == (Y positive)
+// return (sign_of_x)0
+// pxx even
+// p13 == (Y negative)
+// return +inf
+// p14 == (Y positive)
+// return +0
+
+// pxx == Y is not an integer
+// p13 == (Y negative)
+// return +inf
+// p14 == (Y positive)
+// return +0
+//
+
+// If x=inf, test y and flag denormal
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p10,p11 = f9,f0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcmp.lt.s0 p13,p14 = POW_NORM_Y,f0
+ cmp.gt p6,p7 = pow_GR_exp_Y, pow_GR_10033
+}
+{ .mfi
+ nop.m 999
+ fclass.m p12,p0 = f9, 0x23 //@inf
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p15,p0 = f9, 0x07 //@zero
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p15) fmerge.s f8 = f1,f1 // Return +1.0 if x=inf, y=0
+(p15) br.ret.spnt b0 // Exit if x=inf, y=0
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p14) frcpa.s1 f8,p10 = f1,f0 // If x=inf, y>0, assume result +inf
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p13) fma.d.s0 f8 = f0,f0,f0 // If x=inf, y<0, assume result +0.0
+(p12) br.ret.spnt b0 // Exit if x=inf, y=inf
+}
+;;
+
+// Here if x=inf, and 0 < |y| < inf. Need to correct results if y odd integer.
+{ .mfi
+ nop.m 999
+(p7) fcmp.eq.unc.s1 p9,p0 = POW_float_int_Y, POW_NORM_Y // Is y integer?
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ nop.f 999
+(p9) tbit.nz.unc p11,p0 = pow_GR_sig_int_Y,0 // Test for y odd integer
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p11) fmerge.s f8 = POW_NORM_X,f8 // If y odd integer use sign of x
+ br.ret.sptk b0 // Exit for x=inf, 0 < |y| < inf
+}
+;;
+
+
+POW_X_NEG_Y_NONINT:
+// When X is negative and Y is a non-integer, IEEE
+// returns a qnan indefinite.
+// We call error support with this value
+
+{ .mfb
+ mov pow_GR_tag = 28
+ frcpa.s0 f8,p6 = f0,f0
+ br.cond.sptk __libm_error_region
+}
+;;
+
+POW_X_NAN:
+// Here if x=nan, y not nan
+{ .mfi
+ nop.m 999
+ fclass.m p9,p13 = f9, 0x07 // Test y=zero
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p13) fma.d.s0 f8 = f8,f1,f0
+(p13) br.ret.sptk b0 // Exit if x nan, y anything but zero or nan
+}
+;;
+
+POW_X_NAN_Y_0:
+// When X is a NAN and Y is zero, IEEE returns 1.
+// We call error support with this value.
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p6,p0 = f8,f0 // Dummy op to set invalid on snan
+ nop.i 999
+}
+{ .mfb
+ mov pow_GR_tag = 29
+ fma.d.s0 f8 = f0,f0,f1
+ br.cond.sptk __libm_error_region
+}
+;;
+
+
+POW_OVER_UNDER_X_NOT_INF:
+
+// p8 is TRUE for overflow
+// p9 is TRUE for underflow
+
+// if y is infinity, we should not over/underflow
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.s1 p14, p13 = POW_xsq,f1 // Test |x|=1
+ cmp.eq p8,p9 = pow_GR_sign_Y_Gpr, r0
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p14) fclass.m.unc p15, p0 = f9, 0x23 // If |x|=1, test y=inf
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p13) fclass.m.unc p11,p0 = f9, 0x23 // If |x| not 1, test y=inf
+ nop.i 999
+}
+;;
+
+// p15 = TRUE if |x|=1, y=inf, return +1
+{ .mfb
+ nop.m 999
+(p15) fma.d.s0 f8 = f1,f1,f0 // If |x|=1, y=inf, result +1
+(p15) br.ret.spnt b0 // Exit if |x|=1, y=inf
+}
+;;
+
+.pred.rel "mutex",p8,p9
+{ .mfb
+(p8) setf.exp f8 = pow_GR_17ones // If exp(+big), result inf
+(p9) fmerge.s f8 = f0,f0 // If exp(-big), result 0
+(p11) br.ret.sptk b0 // Exit if |x| not 1, y=inf
+}
+;;
+
+{ .mfb
+ nop.m 999
+ nop.f 999
+ br.cond.sptk POW_OVER_UNDER_ERROR // Branch if y not inf
+}
+;;
+
+
+POW_Y_NAN:
+// Here if y=nan, x anything
+// If x = +1 then result is +1, else result is quiet Y
+{ .mfi
+ nop.m 999
+ fcmp.eq.s1 p10,p9 = POW_NORM_X, f1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p10) fcmp.eq.s0 p6,p0 = f9,f1 // Set invalid, even if x=+1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p10) fma.d.s0 f8 = f1,f1,f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p9) fma.d.s0 f8 = f9,f8,f0
+ br.ret.sptk b0 // Exit y=nan
+}
+;;
+
+
+POW_OVER_UNDER_ERROR:
+// Here if we have overflow or underflow.
+// Enter with p12 true if x negative and y odd int to force -0 or -inf
+
+{ .mfi
+ sub pow_GR_17ones_m1 = pow_GR_17ones, r0, 1
+ nop.f 999
+ mov pow_GR_one = 0x1
+}
+;;
+
+// overflow, force inf with O flag
+{ .mmb
+(p8) mov pow_GR_tag = 24
+(p8) setf.exp POW_tmp = pow_GR_17ones_m1
+ nop.b 999
+}
+;;
+
+// underflow, force zero with I, U flags
+{ .mmi
+(p9) mov pow_GR_tag = 25
+(p9) setf.exp POW_tmp = pow_GR_one
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.d.s0 f8 = POW_tmp, POW_tmp, f0
+ nop.i 999
+}
+;;
+
+// p12 x is negative and y is an odd integer, change sign of result
+{ .mfi
+ nop.m 999
+(p12) fnma.d.s0 f8 = POW_tmp, POW_tmp, f0
+ nop.i 999
+}
+;;
+
+GLOBAL_LIBM_END(pow)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfd [GR_Parameter_Y] = POW_NORM_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfd [GR_Parameter_X] = POW_NORM_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/e_powf.S b/libc/sysdeps/ia64/fpu/e_powf.S
new file mode 100644
index 000000000..1406a94b6
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_powf.S
@@ -0,0 +1,2066 @@
+.file "powf.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/03/00 Added p12 to definite over/under path. With odd power we did not
+// maintain the sign of x in this path.
+// 04/04/00 Unwind support added
+// 04/19/00 pow(+-1,inf) now returns NaN
+// pow(+-val, +-inf) returns 0 or inf, but now does not call error
+// support
+// Added s1 to fcvt.fx because invalid flag was incorrectly set.
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 09/07/00 Improved performance by eliminating bank conflicts and other stalls,
+// and tweaking the critical path
+// 09/08/00 Per c99, pow(+-1,inf) now returns 1, and pow(+1,nan) returns 1
+// 09/28/00 Updated NaN**0 path
+// 01/20/01 Fixed denormal flag settings.
+// 02/13/01 Improved speed.
+// 03/19/01 Reordered exp polynomial to improve speed and eliminate monotonicity
+// problem in round up, down, and to zero modes. Also corrected
+// overflow result when x negative, y odd in round up, down, zero.
+// 06/14/01 Added brace missing from bundle
+// 12/10/01 Corrected case where x negative, 2^23 <= |y| < 2^24, y odd integer.
+// 02/08/02 Fixed overflow/underflow cases that were not calling error support.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 08/29/02 Improved Itanium 2 performance
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 10/09/03 Modified algorithm to improve performance, reduce table size, and
+// fix boundary case powf(2.0,-150.0)
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// float powf(float x, float y)
+//
+// Overview of operation
+//==============================================================
+//
+// Three steps...
+// 1. Log(x)
+// 2. y Log(x)
+// 3. exp(y log(x))
+//
+// This means we work with the absolute value of x and merge in the sign later.
+// Log(x) = G + delta + r -rsq/2 + p
+// G,delta depend on the exponent of x and table entries. The table entries are
+// indexed by the exponent of x, called K.
+//
+// The G and delta come out of the reduction; r is the reduced x.
+//
+// B = frcpa(x)
+// xB-1 is small means that B is the approximate inverse of x.
+//
+// Log(x) = Log( (1/B)(Bx) )
+// = Log(1/B) + Log(Bx)
+// = Log(1/B) + Log( 1 + (Bx-1))
+//
+// x = 2^K 1.x_1x_2.....x_52
+// B= frcpa(x) = 2^-k Cm
+// Log(1/B) = Log(1/(2^-K Cm))
+// Log(1/B) = Log((2^K/ Cm))
+// Log(1/B) = K Log(2) + Log(1/Cm)
+//
+// Log(x) = K Log(2) + Log(1/Cm) + Log( 1 + (Bx-1))
+//
+// If you take the significand of x, set the exponent to true 0, then Cm is
+// the frcpa. We tabulate the Log(1/Cm) values. There are 256 of them.
+// The frcpa table is indexed by 8 bits, the x_1 thru x_8.
+// m = x_1x_2...x_8 is an 8-bit index.
+//
+// Log(1/Cm) = log(1/frcpa(1+m/256)) where m goes from 0 to 255.
+//
+// We tabluate as one double, T for single precision power
+//
+// Log(x) = (K Log(2)_hi + T) + (K Log(2)_lo) + Log( 1 + (Bx-1))
+// Log(x) = G + delta + Log( 1 + (Bx-1))
+//
+// The Log( 1 + (Bx-1)) can be calculated as a series in r = Bx-1.
+//
+// Log( 1 + (Bx-1)) = r - rsq/2 + p
+// where p = r^3(P0 + P1*r + P2*r^2)
+//
+// Then,
+//
+// yLog(x) = yG + y delta + y(r-rsq/2) + yp
+// yLog(x) = Z1 + e3 + Z2 + Z3
+//
+//
+// exp(yLog(x)) = exp(Z1 + Z2) exp(Z3) exp(e3)
+//
+//
+// exp(Z3) is another series.
+// exp(e3) is approximated as f3 = 1 + e3
+//
+// exp(Z1 + Z2) = exp(Z)
+// Z (128/log2) = number of log2/128 in Z is N
+//
+// s = Z - N log2/128
+//
+// exp(Z) = exp(s) exp(N log2/128)
+//
+// exp(r) = exp(Z - N log2/128)
+//
+// r = s + d = (Z - N (log2/128)_hi) -N (log2/128)_lo
+// = Z - N (log2/128)
+//
+// Z = s+d +N (log2/128)
+//
+// exp(Z) = exp(s) (1+d) exp(N log2/128)
+//
+// N = M 128 + n
+//
+// N log2/128 = M log2 + n log2/128
+//
+// n is 8 binary digits = n_7n_6...n_1
+//
+// n log2/128 = n_7n_6n_5 16 log2/128 + n_4n_3n_2n_1 log2/128
+// n log2/128 = n_7n_6n_5 log2/8 + n_4n_3n_2n_1 log2/128
+// n log2/128 = I2 log2/8 + I1 log2/128
+//
+// N log2/128 = M log2 + I2 log2/8 + I1 log2/128
+//
+// exp(Z) = exp(s) (1+d) exp(log(2^M) + log(2^I2/8) + log(2^I1/128))
+// exp(Z) = exp(s) f12 (2^M) 2^I2/8 2^I1/128
+//
+// I1, I2 are table indices. Use a series for exp(s).
+// Then get exp(Z)
+//
+// exp(yLog(x)) = exp(Z) exp(Z3) f3
+// exp(yLog(x)) = exp(Z)f3 exp(Z3)
+// exp(yLog(x)) = A exp(Z3)
+//
+// We actually calculate exp(Z3) -1.
+// Then,
+// exp(yLog(x)) = A + A( exp(Z3) -1)
+//
+
+// Table Generation
+//==============================================================
+
+// The log values
+// ==============
+// The operation (K*log2_hi) must be exact. K is the true exponent of x.
+// If we allow gradual underflow (denormals), K can be represented in 12 bits
+// (as a two's complement number). We assume 13 bits as an engineering
+// precaution.
+//
+// +------------+----------------+-+
+// | 13 bits | 50 bits | |
+// +------------+----------------+-+
+// 0 1 66
+// 2 34
+//
+// So we want the lsb(log2_hi) to be 2^-50
+// We get log2 as a quad-extended (15-bit exponent, 128-bit significand)
+//
+// 0 fffe b17217f7d1cf79ab c9e3b39803f2f6af (4...)
+//
+// Consider numbering the bits left to right, starting at 0 thru 127.
+// Bit 0 is the 2^-1 bit; bit 49 is the 2^-50 bit.
+//
+// ...79ab
+// 0111 1001 1010 1011
+// 44
+// 89
+//
+// So if we shift off the rightmost 14 bits, then (shift back only
+// the top half) we get
+//
+// 0 fffe b17217f7d1cf4000 e6af278ece600fcb dabc000000000000
+//
+// Put the right 64-bit signficand in an FR register, convert to double;
+// it is exact. Put the next 128 bits into a quad register and round to double.
+// The true exponent of the low part is -51.
+//
+// hi is 0 fffe b17217f7d1cf4000
+// lo is 0 ffcc e6af278ece601000
+//
+// Convert to double memory format and get
+//
+// hi is 0x3fe62e42fefa39e8
+// lo is 0x3cccd5e4f1d9cc02
+//
+// log2_hi + log2_lo is an accurate value for log2.
+//
+//
+// The T and t values
+// ==================
+// A similar method is used to generate the T and t values.
+//
+// K * log2_hi + T must be exact.
+//
+// Smallest T,t
+// ----------
+// The smallest T,t is
+// T t
+// 0x3f60040155d58800, 0x3c93bce0ce3ddd81 log(1/frcpa(1+0/256))= +1.95503e-003
+//
+// The exponent is 0x3f6 (biased) or -9 (true).
+// For the smallest T value, what we want is to clip the significand such that
+// when it is shifted right by 9, its lsb is in the bit for 2^-51. The 9 is the
+// specific for the first entry. In general, it is 0xffff - (biased 15-bit
+// exponent).
+
+// Independently, what we have calculated is the table value as a quad
+// precision number.
+// Table entry 1 is
+// 0 fff6 80200aaeac44ef38 338f77605fdf8000
+//
+// We store this quad precision number in a data structure that is
+// sign: 1
+// exponent: 15
+// signficand_hi: 64 (includes explicit bit)
+// signficand_lo: 49
+// Because the explicit bit is included, the significand is 113 bits.
+//
+// Consider significand_hi for table entry 1.
+//
+//
+// +-+--- ... -------+--------------------+
+// | |
+// +-+--- ... -------+--------------------+
+// 0 1 4444444455555555556666
+// 2345678901234567890123
+//
+// Labeled as above, bit 0 is 2^0, bit 1 is 2^-1, etc.
+// Bit 42 is 2^-42. If we shift to the right by 9, the bit in
+// bit 42 goes in 51.
+//
+// So what we want to do is shift bits 43 thru 63 into significand_lo.
+// This is shifting bit 42 into bit 63, taking care to retain shifted-off bits.
+// Then shifting (just with signficaand_hi) back into bit 42.
+//
+// The shift_value is 63-42 = 21. In general, this is
+// 63 - (51 -(0xffff - 0xfff6))
+// For this example, it is
+// 63 - (51 - 9) = 63 - 42 = 21
+//
+// This means we are shifting 21 bits into significand_lo. We must maintain more
+// that a 128-bit signficand not to lose bits. So before the shift we put the
+// 128-bit significand into a 256-bit signficand and then shift.
+// The 256-bit significand has four parts: hh, hl, lh, and ll.
+//
+// Start off with
+// hh hl lh ll
+// <64> <49><15_0> <64_0> <64_0>
+//
+// After shift by 21 (then return for significand_hi),
+// <43><21_0> <21><43> <6><58_0> <64_0>
+//
+// Take the hh part and convert to a double. There is no rounding here.
+// The conversion is exact. The true exponent of the high part is the same as
+// the true exponent of the input quad.
+//
+// We have some 64 plus significand bits for the low part. In this example, we
+// have 70 bits. We want to round this to a double. Put them in a quad and then
+// do a quad fnorm.
+// For this example the true exponent of the low part is
+// true_exponent_of_high - 43 = true_exponent_of_high - (64-21)
+// In general, this is
+// true_exponent_of_high - (64 - shift_value)
+//
+//
+// Largest T,t
+// ----------
+// The largest T,t is
+// 0x3fe62643fecf9742, 0x3c9e3147684bd37d log(1/frcpa(1+255/256))=+6.92171e-001
+//
+// Table entry 256 is
+// 0 fffe b1321ff67cba178c 51da12f4df5a0000
+//
+// The shift value is
+// 63 - (51 -(0xffff - 0xfffe)) = 13
+//
+// The true exponent of the low part is
+// true_exponent_of_high - (64 - shift_value)
+// -1 - (64-13) = -52
+// Biased as a double, this is 0x3cb
+//
+//
+//
+// So then lsb(T) must be >= 2^-51
+// msb(Klog2_hi) <= 2^12
+//
+// +--------+---------+
+// | 51 bits | <== largest T
+// +--------+---------+
+// | 9 bits | 42 bits | <== smallest T
+// +------------+----------------+-+
+// | 13 bits | 50 bits | |
+// +------------+----------------+-+
+//
+// Note: For powf only the table of T is needed
+
+
+// Special Cases
+//==============================================================
+
+// double float
+// overflow error 24 30
+
+// underflow error 25 31
+
+// X zero Y zero
+// +0 +0 +1 error 26 32
+// -0 +0 +1 error 26 32
+// +0 -0 +1 error 26 32
+// -0 -0 +1 error 26 32
+
+// X zero Y negative
+// +0 -odd integer +inf error 27 33 divide-by-zero
+// -0 -odd integer -inf error 27 33 divide-by-zero
+// +0 !-odd integer +inf error 27 33 divide-by-zero
+// -0 !-odd integer +inf error 27 33 divide-by-zero
+// +0 -inf +inf error 27 33 divide-by-zero
+// -0 -inf +inf error 27 33 divide-by-zero
+
+// X zero Y positve
+// +0 +odd integer +0
+// -0 +odd integer -0
+// +0 !+odd integer +0
+// -0 !+odd integer +0
+// +0 +inf +0
+// -0 +inf +0
+// +0 Y NaN quiet Y invalid if Y SNaN
+// -0 Y NaN quiet Y invalid if Y SNaN
+
+// X one
+// -1 Y inf +1
+// -1 Y NaN quiet Y invalid if Y SNaN
+// +1 Y NaN +1 invalid if Y SNaN
+// +1 Y any else +1
+
+// X - Y not integer QNAN error 28 34 invalid
+
+// X NaN Y 0 +1 error 29 35
+// X NaN Y NaN quiet X invalid if X or Y SNaN
+// X NaN Y any else quiet X invalid if X SNaN
+// X !+1 Y NaN quiet Y invalid if Y SNaN
+
+
+// X +inf Y >0 +inf
+// X -inf Y >0, !odd integer +inf
+// X -inf Y >0, odd integer -inf
+
+// X +inf Y <0 +0
+// X -inf Y <0, !odd integer +0
+// X -inf Y <0, odd integer -0
+
+// X +inf Y =0 +1
+// X -inf Y =0 +1
+
+// |X|<1 Y +inf +0
+// |X|<1 Y -inf +inf
+// |X|>1 Y +inf +inf
+// |X|>1 Y -inf +0
+
+// X any Y =0 +1
+
+// Assembly macros
+//==============================================================
+
+// integer registers used
+
+pow_GR_exp_half = r10
+pow_GR_signexp_Xm1 = r11
+pow_GR_tmp = r11
+
+pow_GR_signexp_X = r14
+pow_GR_17ones = r15
+pow_GR_Fpsr = r15
+pow_AD_P = r16
+pow_GR_rcs0_mask = r16
+pow_GR_exp_2tom8 = r17
+pow_GR_rcs0 = r17
+pow_GR_sig_X = r18
+pow_GR_10033 = r19
+pow_GR_16ones = r20
+
+pow_AD_Tt = r21
+pow_GR_exp_X = r22
+pow_AD_Q = r23
+pow_GR_true_exp_X = r24
+pow_GR_y_zero = r25
+
+pow_GR_exp_Y = r26
+pow_AD_tbl1 = r27
+pow_AD_tbl2 = r28
+pow_GR_offset = r29
+pow_GR_exp_Xm1 = r30
+pow_GR_xneg_yodd = r31
+
+pow_GR_int_N = r38
+pow_GR_index1 = r39
+pow_GR_index2 = r40
+
+pow_AD_T1 = r41
+pow_AD_T2 = r42
+pow_int_GR_M = r43
+pow_GR_sig_int_Y = r44
+pow_GR_sign_Y_Gpr = r45
+
+pow_GR_17ones_m1 = r46
+pow_GR_one = r47
+pow_GR_sign_Y = r48
+pow_GR_signexp_Y_Gpr = r49
+pow_GR_exp_Y_Gpr = r50
+
+pow_GR_true_exp_Y_Gpr = r51
+pow_GR_signexp_Y = r52
+pow_GR_x_one = r53
+pow_GR_big_pos = r55
+
+pow_GR_big_neg = r56
+
+GR_SAVE_B0 = r50
+GR_SAVE_GP = r51
+GR_SAVE_PFS = r52
+
+GR_Parameter_X = r53
+GR_Parameter_Y = r54
+GR_Parameter_RESULT = r55
+pow_GR_tag = r56
+
+
+// floating point registers used
+
+POW_B = f32
+POW_NORM_X = f33
+POW_Xm1 = f34
+POW_r1 = f34
+
+POW_NORM_Y = f37
+POW_Q2 = f38
+POW_eps = f39
+POW_P2 = f40
+
+POW_P0 = f42
+POW_log2_lo = f43
+POW_r = f44
+POW_Q0_half = f45
+
+POW_tmp = f47
+POW_log2_hi = f48
+POW_Q1 = f49
+POW_P1 = f50
+
+POW_log2_by_128_hi = f51
+POW_inv_log2_by_128 = f52
+POW_rsq = f53
+POW_Yrcub = f54
+POW_log2_by_128_lo = f55
+
+POW_xsq = f57
+POW_v2 = f59
+POW_T = f60
+
+POW_RSHF = f62
+POW_v210 = f63
+POW_twoV = f65
+
+POW_U = f66
+POW_G = f67
+POW_delta = f68
+POW_V = f70
+
+POW_p = f71
+POW_Z = f72
+POW_e3 = f73
+POW_Z2 = f75
+
+POW_W1 = f77
+POW_Z3 = f80
+
+POW_Z3sq = f85
+
+POW_Nfloat = f87
+POW_f3 = f89
+POW_q = f90
+
+POW_T1 = f96
+POW_T2 = f97
+POW_2M = f98
+POW_s = f99
+POW_f12 = f100
+
+POW_ssq = f101
+POW_T1T2 = f102
+POW_1ps = f103
+POW_A = f104
+POW_es = f105
+
+POW_Xp1 = f106
+POW_int_K = f107
+POW_K = f108
+POW_f123 = f109
+POW_Gpr = f110
+
+POW_Y_Gpr = f111
+POW_int_Y = f112
+POW_2Mqp1 = f113
+
+POW_float_int_Y = f116
+POW_ftz_urm_f8 = f117
+POW_wre_urm_f8 = f118
+POW_big_neg = f119
+POW_big_pos = f120
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(pow_table_P)
+data8 0x80000000000018E5, 0x0000BFFD // P_1
+data8 0xb8aa3b295c17f0bc, 0x00004006 // inv_ln2_by_128
+//
+//
+data8 0x3FA5555555554A9E // Q_2
+data8 0x0000000000000000 // Pad
+data8 0x3FC5555555554733 // Q_1
+data8 0x43e8000000000000 // Right shift constant for exp
+data8 0xc9e3b39803f2f6af, 0x00003fb7 // ln2_by_128_lo
+LOCAL_OBJECT_END(pow_table_P)
+
+LOCAL_OBJECT_START(pow_table_Q)
+data8 0xCCCCCCCC4ED2BA7F, 0x00003FFC // P_2
+data8 0xAAAAAAAAAAAAB505, 0x00003FFD // P_0
+data8 0x3fe62e42fefa39e8, 0x3cccd5e4f1d9cc02 // log2 hi lo = +6.93147e-001
+data8 0xb17217f7d1cf79ab, 0x00003ff7 // ln2_by_128_hi
+LOCAL_OBJECT_END(pow_table_Q)
+
+
+LOCAL_OBJECT_START(pow_Tt)
+data8 0x3f60040155d58800 // log(1/frcpa(1+0/256))= +1.95503e-003
+data8 0x3f78121214586a00 // log(1/frcpa(1+1/256))= +5.87661e-003
+data8 0x3f841929f9683200 // log(1/frcpa(1+2/256))= +9.81362e-003
+data8 0x3f8c317384c75f00 // log(1/frcpa(1+3/256))= +1.37662e-002
+data8 0x3f91a6b91ac73380 // log(1/frcpa(1+4/256))= +1.72376e-002
+data8 0x3f95ba9a5d9ac000 // log(1/frcpa(1+5/256))= +2.12196e-002
+data8 0x3f99d2a807432580 // log(1/frcpa(1+6/256))= +2.52177e-002
+data8 0x3f9d6b2725979800 // log(1/frcpa(1+7/256))= +2.87291e-002
+data8 0x3fa0c58fa19dfa80 // log(1/frcpa(1+8/256))= +3.27573e-002
+data8 0x3fa2954c78cbce00 // log(1/frcpa(1+9/256))= +3.62953e-002
+data8 0x3fa4a94d2da96c40 // log(1/frcpa(1+10/256))= +4.03542e-002
+data8 0x3fa67c94f2d4bb40 // log(1/frcpa(1+11/256))= +4.39192e-002
+data8 0x3fa85188b630f040 // log(1/frcpa(1+12/256))= +4.74971e-002
+data8 0x3faa6b8abe73af40 // log(1/frcpa(1+13/256))= +5.16017e-002
+data8 0x3fac441e06f72a80 // log(1/frcpa(1+14/256))= +5.52072e-002
+data8 0x3fae1e6713606d00 // log(1/frcpa(1+15/256))= +5.88257e-002
+data8 0x3faffa6911ab9300 // log(1/frcpa(1+16/256))= +6.24574e-002
+data8 0x3fb0ec139c5da600 // log(1/frcpa(1+17/256))= +6.61022e-002
+data8 0x3fb1dbd2643d1900 // log(1/frcpa(1+18/256))= +6.97605e-002
+data8 0x3fb2cc7284fe5f00 // log(1/frcpa(1+19/256))= +7.34321e-002
+data8 0x3fb3bdf5a7d1ee60 // log(1/frcpa(1+20/256))= +7.71173e-002
+data8 0x3fb4b05d7aa012e0 // log(1/frcpa(1+21/256))= +8.08161e-002
+data8 0x3fb580db7ceb5700 // log(1/frcpa(1+22/256))= +8.39975e-002
+data8 0x3fb674f089365a60 // log(1/frcpa(1+23/256))= +8.77219e-002
+data8 0x3fb769ef2c6b5680 // log(1/frcpa(1+24/256))= +9.14602e-002
+data8 0x3fb85fd927506a40 // log(1/frcpa(1+25/256))= +9.52125e-002
+data8 0x3fb9335e5d594980 // log(1/frcpa(1+26/256))= +9.84401e-002
+data8 0x3fba2b0220c8e5e0 // log(1/frcpa(1+27/256))= +1.02219e-001
+data8 0x3fbb0004ac1a86a0 // log(1/frcpa(1+28/256))= +1.05469e-001
+data8 0x3fbbf968769fca00 // log(1/frcpa(1+29/256))= +1.09274e-001
+data8 0x3fbccfedbfee13a0 // log(1/frcpa(1+30/256))= +1.12548e-001
+data8 0x3fbda727638446a0 // log(1/frcpa(1+31/256))= +1.15832e-001
+data8 0x3fbea3257fe10f60 // log(1/frcpa(1+32/256))= +1.19677e-001
+data8 0x3fbf7be9fedbfde0 // log(1/frcpa(1+33/256))= +1.22985e-001
+data8 0x3fc02ab352ff25f0 // log(1/frcpa(1+34/256))= +1.26303e-001
+data8 0x3fc097ce579d2040 // log(1/frcpa(1+35/256))= +1.29633e-001
+data8 0x3fc1178e8227e470 // log(1/frcpa(1+36/256))= +1.33531e-001
+data8 0x3fc185747dbecf30 // log(1/frcpa(1+37/256))= +1.36885e-001
+data8 0x3fc1f3b925f25d40 // log(1/frcpa(1+38/256))= +1.40250e-001
+data8 0x3fc2625d1e6ddf50 // log(1/frcpa(1+39/256))= +1.43627e-001
+data8 0x3fc2d1610c868130 // log(1/frcpa(1+40/256))= +1.47015e-001
+data8 0x3fc340c597411420 // log(1/frcpa(1+41/256))= +1.50414e-001
+data8 0x3fc3b08b6757f2a0 // log(1/frcpa(1+42/256))= +1.53825e-001
+data8 0x3fc40dfb08378000 // log(1/frcpa(1+43/256))= +1.56677e-001
+data8 0x3fc47e74e8ca5f70 // log(1/frcpa(1+44/256))= +1.60109e-001
+data8 0x3fc4ef51f6466de0 // log(1/frcpa(1+45/256))= +1.63553e-001
+data8 0x3fc56092e02ba510 // log(1/frcpa(1+46/256))= +1.67010e-001
+data8 0x3fc5d23857cd74d0 // log(1/frcpa(1+47/256))= +1.70478e-001
+data8 0x3fc6313a37335d70 // log(1/frcpa(1+48/256))= +1.73377e-001
+data8 0x3fc6a399dabbd380 // log(1/frcpa(1+49/256))= +1.76868e-001
+data8 0x3fc70337dd3ce410 // log(1/frcpa(1+50/256))= +1.79786e-001
+data8 0x3fc77654128f6120 // log(1/frcpa(1+51/256))= +1.83299e-001
+data8 0x3fc7e9d82a0b0220 // log(1/frcpa(1+52/256))= +1.86824e-001
+data8 0x3fc84a6b759f5120 // log(1/frcpa(1+53/256))= +1.89771e-001
+data8 0x3fc8ab47d5f5a300 // log(1/frcpa(1+54/256))= +1.92727e-001
+data8 0x3fc91fe490965810 // log(1/frcpa(1+55/256))= +1.96286e-001
+data8 0x3fc981634011aa70 // log(1/frcpa(1+56/256))= +1.99261e-001
+data8 0x3fc9f6c407089660 // log(1/frcpa(1+57/256))= +2.02843e-001
+data8 0x3fca58e729348f40 // log(1/frcpa(1+58/256))= +2.05838e-001
+data8 0x3fcabb55c31693a0 // log(1/frcpa(1+59/256))= +2.08842e-001
+data8 0x3fcb1e104919efd0 // log(1/frcpa(1+60/256))= +2.11855e-001
+data8 0x3fcb94ee93e367c0 // log(1/frcpa(1+61/256))= +2.15483e-001
+data8 0x3fcbf851c0675550 // log(1/frcpa(1+62/256))= +2.18516e-001
+data8 0x3fcc5c0254bf23a0 // log(1/frcpa(1+63/256))= +2.21558e-001
+data8 0x3fccc000c9db3c50 // log(1/frcpa(1+64/256))= +2.24609e-001
+data8 0x3fcd244d99c85670 // log(1/frcpa(1+65/256))= +2.27670e-001
+data8 0x3fcd88e93fb2f450 // log(1/frcpa(1+66/256))= +2.30741e-001
+data8 0x3fcdedd437eaef00 // log(1/frcpa(1+67/256))= +2.33820e-001
+data8 0x3fce530effe71010 // log(1/frcpa(1+68/256))= +2.36910e-001
+data8 0x3fceb89a1648b970 // log(1/frcpa(1+69/256))= +2.40009e-001
+data8 0x3fcf1e75fadf9bd0 // log(1/frcpa(1+70/256))= +2.43117e-001
+data8 0x3fcf84a32ead7c30 // log(1/frcpa(1+71/256))= +2.46235e-001
+data8 0x3fcfeb2233ea07c0 // log(1/frcpa(1+72/256))= +2.49363e-001
+data8 0x3fd028f9c7035c18 // log(1/frcpa(1+73/256))= +2.52501e-001
+data8 0x3fd05c8be0d96358 // log(1/frcpa(1+74/256))= +2.55649e-001
+data8 0x3fd085eb8f8ae790 // log(1/frcpa(1+75/256))= +2.58174e-001
+data8 0x3fd0b9c8e32d1910 // log(1/frcpa(1+76/256))= +2.61339e-001
+data8 0x3fd0edd060b78080 // log(1/frcpa(1+77/256))= +2.64515e-001
+data8 0x3fd122024cf00638 // log(1/frcpa(1+78/256))= +2.67701e-001
+data8 0x3fd14be2927aecd0 // log(1/frcpa(1+79/256))= +2.70257e-001
+data8 0x3fd180618ef18ad8 // log(1/frcpa(1+80/256))= +2.73461e-001
+data8 0x3fd1b50bbe2fc638 // log(1/frcpa(1+81/256))= +2.76675e-001
+data8 0x3fd1df4cc7cf2428 // log(1/frcpa(1+82/256))= +2.79254e-001
+data8 0x3fd214456d0eb8d0 // log(1/frcpa(1+83/256))= +2.82487e-001
+data8 0x3fd23ec5991eba48 // log(1/frcpa(1+84/256))= +2.85081e-001
+data8 0x3fd2740d9f870af8 // log(1/frcpa(1+85/256))= +2.88333e-001
+data8 0x3fd29ecdabcdfa00 // log(1/frcpa(1+86/256))= +2.90943e-001
+data8 0x3fd2d46602adcce8 // log(1/frcpa(1+87/256))= +2.94214e-001
+data8 0x3fd2ff66b04ea9d0 // log(1/frcpa(1+88/256))= +2.96838e-001
+data8 0x3fd335504b355a30 // log(1/frcpa(1+89/256))= +3.00129e-001
+data8 0x3fd360925ec44f58 // log(1/frcpa(1+90/256))= +3.02769e-001
+data8 0x3fd38bf1c3337e70 // log(1/frcpa(1+91/256))= +3.05417e-001
+data8 0x3fd3c25277333180 // log(1/frcpa(1+92/256))= +3.08735e-001
+data8 0x3fd3edf463c16838 // log(1/frcpa(1+93/256))= +3.11399e-001
+data8 0x3fd419b423d5e8c0 // log(1/frcpa(1+94/256))= +3.14069e-001
+data8 0x3fd44591e0539f48 // log(1/frcpa(1+95/256))= +3.16746e-001
+data8 0x3fd47c9175b6f0a8 // log(1/frcpa(1+96/256))= +3.20103e-001
+data8 0x3fd4a8b341552b08 // log(1/frcpa(1+97/256))= +3.22797e-001
+data8 0x3fd4d4f390890198 // log(1/frcpa(1+98/256))= +3.25498e-001
+data8 0x3fd501528da1f960 // log(1/frcpa(1+99/256))= +3.28206e-001
+data8 0x3fd52dd06347d4f0 // log(1/frcpa(1+100/256))= +3.30921e-001
+data8 0x3fd55a6d3c7b8a88 // log(1/frcpa(1+101/256))= +3.33644e-001
+data8 0x3fd5925d2b112a58 // log(1/frcpa(1+102/256))= +3.37058e-001
+data8 0x3fd5bf406b543db0 // log(1/frcpa(1+103/256))= +3.39798e-001
+data8 0x3fd5ec433d5c35a8 // log(1/frcpa(1+104/256))= +3.42545e-001
+data8 0x3fd61965cdb02c18 // log(1/frcpa(1+105/256))= +3.45300e-001
+data8 0x3fd646a84935b2a0 // log(1/frcpa(1+106/256))= +3.48063e-001
+data8 0x3fd6740add31de90 // log(1/frcpa(1+107/256))= +3.50833e-001
+data8 0x3fd6a18db74a58c0 // log(1/frcpa(1+108/256))= +3.53610e-001
+data8 0x3fd6cf31058670e8 // log(1/frcpa(1+109/256))= +3.56396e-001
+data8 0x3fd6f180e852f0b8 // log(1/frcpa(1+110/256))= +3.58490e-001
+data8 0x3fd71f5d71b894e8 // log(1/frcpa(1+111/256))= +3.61289e-001
+data8 0x3fd74d5aefd66d58 // log(1/frcpa(1+112/256))= +3.64096e-001
+data8 0x3fd77b79922bd378 // log(1/frcpa(1+113/256))= +3.66911e-001
+data8 0x3fd7a9b9889f19e0 // log(1/frcpa(1+114/256))= +3.69734e-001
+data8 0x3fd7d81b037eb6a0 // log(1/frcpa(1+115/256))= +3.72565e-001
+data8 0x3fd8069e33827230 // log(1/frcpa(1+116/256))= +3.75404e-001
+data8 0x3fd82996d3ef8bc8 // log(1/frcpa(1+117/256))= +3.77538e-001
+data8 0x3fd85855776dcbf8 // log(1/frcpa(1+118/256))= +3.80391e-001
+data8 0x3fd8873658327cc8 // log(1/frcpa(1+119/256))= +3.83253e-001
+data8 0x3fd8aa75973ab8c8 // log(1/frcpa(1+120/256))= +3.85404e-001
+data8 0x3fd8d992dc8824e0 // log(1/frcpa(1+121/256))= +3.88280e-001
+data8 0x3fd908d2ea7d9510 // log(1/frcpa(1+122/256))= +3.91164e-001
+data8 0x3fd92c59e79c0e50 // log(1/frcpa(1+123/256))= +3.93332e-001
+data8 0x3fd95bd750ee3ed0 // log(1/frcpa(1+124/256))= +3.96231e-001
+data8 0x3fd98b7811a3ee58 // log(1/frcpa(1+125/256))= +3.99138e-001
+data8 0x3fd9af47f33d4068 // log(1/frcpa(1+126/256))= +4.01323e-001
+data8 0x3fd9df270c1914a0 // log(1/frcpa(1+127/256))= +4.04245e-001
+data8 0x3fda0325ed14fda0 // log(1/frcpa(1+128/256))= +4.06442e-001
+data8 0x3fda33440224fa78 // log(1/frcpa(1+129/256))= +4.09379e-001
+data8 0x3fda57725e80c380 // log(1/frcpa(1+130/256))= +4.11587e-001
+data8 0x3fda87d0165dd198 // log(1/frcpa(1+131/256))= +4.14539e-001
+data8 0x3fdaac2e6c03f890 // log(1/frcpa(1+132/256))= +4.16759e-001
+data8 0x3fdadccc6fdf6a80 // log(1/frcpa(1+133/256))= +4.19726e-001
+data8 0x3fdb015b3eb1e790 // log(1/frcpa(1+134/256))= +4.21958e-001
+data8 0x3fdb323a3a635948 // log(1/frcpa(1+135/256))= +4.24941e-001
+data8 0x3fdb56fa04462908 // log(1/frcpa(1+136/256))= +4.27184e-001
+data8 0x3fdb881aa659bc90 // log(1/frcpa(1+137/256))= +4.30182e-001
+data8 0x3fdbad0bef3db160 // log(1/frcpa(1+138/256))= +4.32437e-001
+data8 0x3fdbd21297781c28 // log(1/frcpa(1+139/256))= +4.34697e-001
+data8 0x3fdc039236f08818 // log(1/frcpa(1+140/256))= +4.37718e-001
+data8 0x3fdc28cb1e4d32f8 // log(1/frcpa(1+141/256))= +4.39990e-001
+data8 0x3fdc4e19b84723c0 // log(1/frcpa(1+142/256))= +4.42267e-001
+data8 0x3fdc7ff9c74554c8 // log(1/frcpa(1+143/256))= +4.45311e-001
+data8 0x3fdca57b64e9db00 // log(1/frcpa(1+144/256))= +4.47600e-001
+data8 0x3fdccb130a5ceba8 // log(1/frcpa(1+145/256))= +4.49895e-001
+data8 0x3fdcf0c0d18f3268 // log(1/frcpa(1+146/256))= +4.52194e-001
+data8 0x3fdd232075b5a200 // log(1/frcpa(1+147/256))= +4.55269e-001
+data8 0x3fdd490246defa68 // log(1/frcpa(1+148/256))= +4.57581e-001
+data8 0x3fdd6efa918d25c8 // log(1/frcpa(1+149/256))= +4.59899e-001
+data8 0x3fdd9509707ae528 // log(1/frcpa(1+150/256))= +4.62221e-001
+data8 0x3fddbb2efe92c550 // log(1/frcpa(1+151/256))= +4.64550e-001
+data8 0x3fddee2f3445e4a8 // log(1/frcpa(1+152/256))= +4.67663e-001
+data8 0x3fde148a1a2726c8 // log(1/frcpa(1+153/256))= +4.70004e-001
+data8 0x3fde3afc0a49ff38 // log(1/frcpa(1+154/256))= +4.72350e-001
+data8 0x3fde6185206d5168 // log(1/frcpa(1+155/256))= +4.74702e-001
+data8 0x3fde882578823d50 // log(1/frcpa(1+156/256))= +4.77060e-001
+data8 0x3fdeaedd2eac9908 // log(1/frcpa(1+157/256))= +4.79423e-001
+data8 0x3fded5ac5f436be0 // log(1/frcpa(1+158/256))= +4.81792e-001
+data8 0x3fdefc9326d16ab8 // log(1/frcpa(1+159/256))= +4.84166e-001
+data8 0x3fdf2391a21575f8 // log(1/frcpa(1+160/256))= +4.86546e-001
+data8 0x3fdf4aa7ee031928 // log(1/frcpa(1+161/256))= +4.88932e-001
+data8 0x3fdf71d627c30bb0 // log(1/frcpa(1+162/256))= +4.91323e-001
+data8 0x3fdf991c6cb3b378 // log(1/frcpa(1+163/256))= +4.93720e-001
+data8 0x3fdfc07ada69a908 // log(1/frcpa(1+164/256))= +4.96123e-001
+data8 0x3fdfe7f18eb03d38 // log(1/frcpa(1+165/256))= +4.98532e-001
+data8 0x3fe007c053c5002c // log(1/frcpa(1+166/256))= +5.00946e-001
+data8 0x3fe01b942198a5a0 // log(1/frcpa(1+167/256))= +5.03367e-001
+data8 0x3fe02f74400c64e8 // log(1/frcpa(1+168/256))= +5.05793e-001
+data8 0x3fe04360be7603ac // log(1/frcpa(1+169/256))= +5.08225e-001
+data8 0x3fe05759ac47fe30 // log(1/frcpa(1+170/256))= +5.10663e-001
+data8 0x3fe06b5f1911cf50 // log(1/frcpa(1+171/256))= +5.13107e-001
+data8 0x3fe078bf0533c568 // log(1/frcpa(1+172/256))= +5.14740e-001
+data8 0x3fe08cd9687e7b0c // log(1/frcpa(1+173/256))= +5.17194e-001
+data8 0x3fe0a10074cf9018 // log(1/frcpa(1+174/256))= +5.19654e-001
+data8 0x3fe0b5343a234474 // log(1/frcpa(1+175/256))= +5.22120e-001
+data8 0x3fe0c974c89431cc // log(1/frcpa(1+176/256))= +5.24592e-001
+data8 0x3fe0ddc2305b9884 // log(1/frcpa(1+177/256))= +5.27070e-001
+data8 0x3fe0eb524bafc918 // log(1/frcpa(1+178/256))= +5.28726e-001
+data8 0x3fe0ffb54213a474 // log(1/frcpa(1+179/256))= +5.31214e-001
+data8 0x3fe114253da97d9c // log(1/frcpa(1+180/256))= +5.33709e-001
+data8 0x3fe128a24f1d9afc // log(1/frcpa(1+181/256))= +5.36210e-001
+data8 0x3fe1365252bf0864 // log(1/frcpa(1+182/256))= +5.37881e-001
+data8 0x3fe14ae558b4a92c // log(1/frcpa(1+183/256))= +5.40393e-001
+data8 0x3fe15f85a19c7658 // log(1/frcpa(1+184/256))= +5.42910e-001
+data8 0x3fe16d4d38c119f8 // log(1/frcpa(1+185/256))= +5.44592e-001
+data8 0x3fe18203c20dd130 // log(1/frcpa(1+186/256))= +5.47121e-001
+data8 0x3fe196c7bc4b1f38 // log(1/frcpa(1+187/256))= +5.49656e-001
+data8 0x3fe1a4a738b7a33c // log(1/frcpa(1+188/256))= +5.51349e-001
+data8 0x3fe1b981c0c9653c // log(1/frcpa(1+189/256))= +5.53895e-001
+data8 0x3fe1ce69e8bb1068 // log(1/frcpa(1+190/256))= +5.56447e-001
+data8 0x3fe1dc619de06944 // log(1/frcpa(1+191/256))= +5.58152e-001
+data8 0x3fe1f160a2ad0da0 // log(1/frcpa(1+192/256))= +5.60715e-001
+data8 0x3fe2066d7740737c // log(1/frcpa(1+193/256))= +5.63285e-001
+data8 0x3fe2147dba47a390 // log(1/frcpa(1+194/256))= +5.65001e-001
+data8 0x3fe229a1bc5ebac0 // log(1/frcpa(1+195/256))= +5.67582e-001
+data8 0x3fe237c1841a502c // log(1/frcpa(1+196/256))= +5.69306e-001
+data8 0x3fe24cfce6f80d98 // log(1/frcpa(1+197/256))= +5.71898e-001
+data8 0x3fe25b2c55cd5760 // log(1/frcpa(1+198/256))= +5.73630e-001
+data8 0x3fe2707f4d5f7c40 // log(1/frcpa(1+199/256))= +5.76233e-001
+data8 0x3fe285e0842ca380 // log(1/frcpa(1+200/256))= +5.78842e-001
+data8 0x3fe294294708b770 // log(1/frcpa(1+201/256))= +5.80586e-001
+data8 0x3fe2a9a2670aff0c // log(1/frcpa(1+202/256))= +5.83207e-001
+data8 0x3fe2b7fb2c8d1cc0 // log(1/frcpa(1+203/256))= +5.84959e-001
+data8 0x3fe2c65a6395f5f4 // log(1/frcpa(1+204/256))= +5.86713e-001
+data8 0x3fe2dbf557b0df40 // log(1/frcpa(1+205/256))= +5.89350e-001
+data8 0x3fe2ea64c3f97654 // log(1/frcpa(1+206/256))= +5.91113e-001
+data8 0x3fe3001823684d70 // log(1/frcpa(1+207/256))= +5.93762e-001
+data8 0x3fe30e97e9a8b5cc // log(1/frcpa(1+208/256))= +5.95531e-001
+data8 0x3fe32463ebdd34e8 // log(1/frcpa(1+209/256))= +5.98192e-001
+data8 0x3fe332f4314ad794 // log(1/frcpa(1+210/256))= +5.99970e-001
+data8 0x3fe348d90e7464cc // log(1/frcpa(1+211/256))= +6.02643e-001
+data8 0x3fe35779f8c43d6c // log(1/frcpa(1+212/256))= +6.04428e-001
+data8 0x3fe36621961a6a98 // log(1/frcpa(1+213/256))= +6.06217e-001
+data8 0x3fe37c299f3c3668 // log(1/frcpa(1+214/256))= +6.08907e-001
+data8 0x3fe38ae2171976e4 // log(1/frcpa(1+215/256))= +6.10704e-001
+data8 0x3fe399a157a603e4 // log(1/frcpa(1+216/256))= +6.12504e-001
+data8 0x3fe3afccfe77b9d0 // log(1/frcpa(1+217/256))= +6.15210e-001
+data8 0x3fe3be9d503533b4 // log(1/frcpa(1+218/256))= +6.17018e-001
+data8 0x3fe3cd7480b4a8a0 // log(1/frcpa(1+219/256))= +6.18830e-001
+data8 0x3fe3e3c43918f76c // log(1/frcpa(1+220/256))= +6.21554e-001
+data8 0x3fe3f2acb27ed6c4 // log(1/frcpa(1+221/256))= +6.23373e-001
+data8 0x3fe4019c2125ca90 // log(1/frcpa(1+222/256))= +6.25197e-001
+data8 0x3fe4181061389720 // log(1/frcpa(1+223/256))= +6.27937e-001
+data8 0x3fe42711518df544 // log(1/frcpa(1+224/256))= +6.29769e-001
+data8 0x3fe436194e12b6bc // log(1/frcpa(1+225/256))= +6.31604e-001
+data8 0x3fe445285d68ea68 // log(1/frcpa(1+226/256))= +6.33442e-001
+data8 0x3fe45bcc464c8938 // log(1/frcpa(1+227/256))= +6.36206e-001
+data8 0x3fe46aed21f117fc // log(1/frcpa(1+228/256))= +6.38053e-001
+data8 0x3fe47a1527e8a2d0 // log(1/frcpa(1+229/256))= +6.39903e-001
+data8 0x3fe489445efffcc8 // log(1/frcpa(1+230/256))= +6.41756e-001
+data8 0x3fe4a018bcb69834 // log(1/frcpa(1+231/256))= +6.44543e-001
+data8 0x3fe4af5a0c9d65d4 // log(1/frcpa(1+232/256))= +6.46405e-001
+data8 0x3fe4bea2a5bdbe84 // log(1/frcpa(1+233/256))= +6.48271e-001
+data8 0x3fe4cdf28f10ac44 // log(1/frcpa(1+234/256))= +6.50140e-001
+data8 0x3fe4dd49cf994058 // log(1/frcpa(1+235/256))= +6.52013e-001
+data8 0x3fe4eca86e64a680 // log(1/frcpa(1+236/256))= +6.53889e-001
+data8 0x3fe503c43cd8eb68 // log(1/frcpa(1+237/256))= +6.56710e-001
+data8 0x3fe513356667fc54 // log(1/frcpa(1+238/256))= +6.58595e-001
+data8 0x3fe522ae0738a3d4 // log(1/frcpa(1+239/256))= +6.60483e-001
+data8 0x3fe5322e26867854 // log(1/frcpa(1+240/256))= +6.62376e-001
+data8 0x3fe541b5cb979808 // log(1/frcpa(1+241/256))= +6.64271e-001
+data8 0x3fe55144fdbcbd60 // log(1/frcpa(1+242/256))= +6.66171e-001
+data8 0x3fe560dbc45153c4 // log(1/frcpa(1+243/256))= +6.68074e-001
+data8 0x3fe5707a26bb8c64 // log(1/frcpa(1+244/256))= +6.69980e-001
+data8 0x3fe587f60ed5b8fc // log(1/frcpa(1+245/256))= +6.72847e-001
+data8 0x3fe597a7977c8f30 // log(1/frcpa(1+246/256))= +6.74763e-001
+data8 0x3fe5a760d634bb88 // log(1/frcpa(1+247/256))= +6.76682e-001
+data8 0x3fe5b721d295f10c // log(1/frcpa(1+248/256))= +6.78605e-001
+data8 0x3fe5c6ea94431ef8 // log(1/frcpa(1+249/256))= +6.80532e-001
+data8 0x3fe5d6bb22ea86f4 // log(1/frcpa(1+250/256))= +6.82462e-001
+data8 0x3fe5e6938645d38c // log(1/frcpa(1+251/256))= +6.84397e-001
+data8 0x3fe5f673c61a2ed0 // log(1/frcpa(1+252/256))= +6.86335e-001
+data8 0x3fe6065bea385924 // log(1/frcpa(1+253/256))= +6.88276e-001
+data8 0x3fe6164bfa7cc068 // log(1/frcpa(1+254/256))= +6.90222e-001
+data8 0x3fe62643fecf9740 // log(1/frcpa(1+255/256))= +6.92171e-001
+LOCAL_OBJECT_END(pow_Tt)
+
+
+// Table 1 is 2^(index_1/128) where
+// index_1 goes from 0 to 15
+LOCAL_OBJECT_START(pow_tbl1)
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x80B1ED4FD999AB6C , 0x00003FFF
+data8 0x8164D1F3BC030773 , 0x00003FFF
+data8 0x8218AF4373FC25EC , 0x00003FFF
+data8 0x82CD8698AC2BA1D7 , 0x00003FFF
+data8 0x8383594EEFB6EE37 , 0x00003FFF
+data8 0x843A28C3ACDE4046 , 0x00003FFF
+data8 0x84F1F656379C1A29 , 0x00003FFF
+data8 0x85AAC367CC487B15 , 0x00003FFF
+data8 0x8664915B923FBA04 , 0x00003FFF
+data8 0x871F61969E8D1010 , 0x00003FFF
+data8 0x87DB357FF698D792 , 0x00003FFF
+data8 0x88980E8092DA8527 , 0x00003FFF
+data8 0x8955EE03618E5FDD , 0x00003FFF
+data8 0x8A14D575496EFD9A , 0x00003FFF
+data8 0x8AD4C6452C728924 , 0x00003FFF
+LOCAL_OBJECT_END(pow_tbl1)
+
+
+// Table 2 is 2^(index_1/8) where
+// index_2 goes from 0 to 7
+LOCAL_OBJECT_START(pow_tbl2)
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x8B95C1E3EA8BD6E7 , 0x00003FFF
+data8 0x9837F0518DB8A96F , 0x00003FFF
+data8 0xA5FED6A9B15138EA , 0x00003FFF
+data8 0xB504F333F9DE6484 , 0x00003FFF
+data8 0xC5672A115506DADD , 0x00003FFF
+data8 0xD744FCCAD69D6AF4 , 0x00003FFF
+data8 0xEAC0C6E7DD24392F , 0x00003FFF
+LOCAL_OBJECT_END(pow_tbl2)
+
+.section .text
+GLOBAL_LIBM_ENTRY(powf)
+
+// Get exponent of x. Will be used to calculate K.
+{ .mfi
+ getf.exp pow_GR_signexp_X = f8
+ fms.s1 POW_Xm1 = f8,f1,f1 // Will be used for r1 if x>0
+ mov pow_GR_17ones = 0x1FFFF
+}
+{ .mfi
+ addl pow_AD_P = @ltoff(pow_table_P), gp
+ fma.s1 POW_Xp1 = f8,f1,f1 // Will be used for r1 if x<0
+ nop.i 999
+}
+;;
+
+// Get significand of x. Will be used to get index to fetch T, Tt.
+{ .mfi
+ getf.sig pow_GR_sig_X = f8
+ frcpa.s1 POW_B, p6 = f1,f8
+ mov pow_GR_exp_half = 0xFFFE // Exponent for 0.5
+}
+{ .mfi
+ ld8 pow_AD_P = [pow_AD_P]
+ fma.s1 POW_NORM_X = f8,f1,f0
+ mov pow_GR_exp_2tom8 = 0xFFF7
+}
+;;
+
+// DOUBLE 0x10033 exponent limit at which y is an integer
+{ .mfi
+ nop.m 999
+ fcmp.lt.s1 p8,p9 = f8, f0 // Test for x<0
+ addl pow_GR_10033 = 0x10033, r0
+}
+{ .mfi
+ mov pow_GR_16ones = 0xFFFF
+ fma.s1 POW_NORM_Y = f9,f1,f0
+ nop.i 999
+}
+;;
+
+// p13 = TRUE ==> X is unorm
+{ .mfi
+ setf.exp POW_Q0_half = pow_GR_exp_half // Form 0.5
+ fclass.m p13,p0 = f8, 0x0b // Test for x unorm
+ adds pow_AD_Tt = pow_Tt - pow_table_P, pow_AD_P
+}
+{ .mfi
+ adds pow_AD_Q = pow_table_Q - pow_table_P, pow_AD_P
+ nop.f 999
+ nop.i 999
+}
+;;
+
+// p14 = TRUE ==> X is ZERO
+{ .mfi
+ ldfe POW_P2 = [pow_AD_Q], 16
+ fclass.m p14,p0 = f8, 0x07
+ nop.i 999
+}
+// Note POW_Xm1 and POW_r1 are used interchangably
+{ .mfb
+ nop.m 999
+(p8) fnma.s1 POW_Xm1 = POW_Xp1,f1,f0
+(p13) br.cond.spnt POW_X_DENORM
+}
+;;
+
+// Continue normal and denormal paths here
+POW_COMMON:
+// p11 = TRUE ==> Y is a NAN
+{ .mfi
+ and pow_GR_exp_X = pow_GR_signexp_X, pow_GR_17ones
+ fclass.m p11,p0 = f9, 0xc3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fms.s1 POW_r = POW_B, POW_NORM_X,f1
+ mov pow_GR_y_zero = 0
+}
+;;
+
+// Get exponent of |x|-1 to use in comparison to 2^-8
+{ .mmi
+ getf.exp pow_GR_signexp_Xm1 = POW_Xm1
+ sub pow_GR_true_exp_X = pow_GR_exp_X, pow_GR_16ones
+ extr.u pow_GR_offset = pow_GR_sig_X, 55, 8
+}
+;;
+
+{ .mfi
+ alloc r32=ar.pfs,2,19,4,0
+ fcvt.fx.s1 POW_int_Y = POW_NORM_Y
+ shladd pow_AD_Tt = pow_GR_offset, 3, pow_AD_Tt
+}
+{ .mfi
+ setf.sig POW_int_K = pow_GR_true_exp_X
+ nop.f 999
+ nop.i 999
+}
+;;
+
+// p12 = TRUE if Y is ZERO
+// Compute xsq to decide later if |x|=1
+{ .mfi
+ ldfe POW_P1 = [pow_AD_P], 16
+ fclass.m p12,p0 = f9, 0x07
+ nop.i 999
+}
+{ .mfb
+ ldfe POW_P0 = [pow_AD_Q], 16
+ fma.s1 POW_xsq = POW_NORM_X, POW_NORM_X, f0
+(p11) br.cond.spnt POW_Y_NAN // Branch if y=nan
+}
+;;
+
+{ .mmf
+ getf.exp pow_GR_signexp_Y = POW_NORM_Y
+ ldfd POW_T = [pow_AD_Tt]
+ fma.s1 POW_rsq = POW_r, POW_r,f0
+}
+;;
+
+// p11 = TRUE ==> X is a NAN
+{ .mfi
+ ldfpd POW_log2_hi, POW_log2_lo = [pow_AD_Q], 16
+ fclass.m p11,p0 = POW_NORM_X, 0xc3
+ nop.i 999
+}
+{ .mfi
+ ldfe POW_inv_log2_by_128 = [pow_AD_P], 16
+ fma.s1 POW_delta = f0,f0,f0 // delta=0 in case |x| near 1
+(p12) mov pow_GR_y_zero = 1
+}
+;;
+
+{ .mfi
+ ldfd POW_Q2 = [pow_AD_P], 16
+ fnma.s1 POW_twoV = POW_r, POW_Q0_half,f1
+ and pow_GR_exp_Xm1 = pow_GR_signexp_Xm1, pow_GR_17ones
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_U = POW_NORM_Y,POW_r,f0
+ nop.i 999
+}
+;;
+
+// Determine if we will use the |x| near 1 path (p6) or normal path (p7)
+{ .mfi
+ nop.m 999
+ fcvt.xf POW_K = POW_int_K
+ cmp.lt p6,p7 = pow_GR_exp_Xm1, pow_GR_exp_2tom8
+}
+{ .mfb
+ nop.m 999
+ fma.s1 POW_G = f0,f0,f0 // G=0 in case |x| near 1
+(p11) br.cond.spnt POW_X_NAN // Branch if x=nan and y not nan
+}
+;;
+
+// If on the x near 1 path, assign r1 to r
+{ .mfi
+ ldfpd POW_Q1, POW_RSHF = [pow_AD_P], 16
+(p6) fma.s1 POW_r = POW_r1, f1, f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p6) fma.s1 POW_rsq = POW_r1, POW_r1, f0
+(p14) br.cond.spnt POW_X_0 // Branch if x zero and y not nan
+}
+;;
+
+{ .mfi
+ getf.sig pow_GR_sig_int_Y = POW_int_Y
+(p6) fnma.s1 POW_twoV = POW_r1, POW_Q0_half,f1
+ and pow_GR_exp_Y = pow_GR_signexp_Y, pow_GR_17ones
+}
+{ .mfb
+ andcm pow_GR_sign_Y = pow_GR_signexp_Y, pow_GR_17ones
+(p6) fma.s1 POW_U = POW_NORM_Y,POW_r1,f0
+(p12) br.cond.spnt POW_Y_0 // Branch if y=zero, x not zero or nan
+}
+;;
+
+{ .mfi
+ ldfe POW_log2_by_128_lo = [pow_AD_P], 16
+(p7) fma.s1 POW_Z2 = POW_twoV, POW_U, f0
+ nop.i 999
+}
+{ .mfi
+ ldfe POW_log2_by_128_hi = [pow_AD_Q], 16
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcvt.xf POW_float_int_Y = POW_int_Y
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fma.s1 POW_G = POW_K, POW_log2_hi, POW_T
+ adds pow_AD_tbl1 = pow_tbl1 - pow_Tt, pow_AD_Q
+}
+;;
+
+// p11 = TRUE ==> X is NEGATIVE but not inf
+{ .mfi
+ nop.m 999
+ fclass.m p11,p0 = POW_NORM_X, 0x1a
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fma.s1 POW_delta = POW_K, POW_log2_lo, f0
+ adds pow_AD_tbl2 = pow_tbl2 - pow_tbl1, pow_AD_tbl1
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fma.s1 POW_Z = POW_twoV, POW_U, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_v2 = POW_P1, POW_r, POW_P0
+ nop.i 999
+}
+;;
+
+// p11 = TRUE ==> X is NEGATIVE but not inf
+// p12 = TRUE ==> X is NEGATIVE AND Y already even int
+// p13 = TRUE ==> X is NEGATIVE AND Y possible int
+{ .mfi
+ nop.m 999
+(p7) fma.s1 POW_Z = POW_NORM_Y, POW_G, POW_Z2
+(p11) cmp.gt.unc p12,p13 = pow_GR_exp_Y, pow_GR_10033
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_Gpr = POW_G, f1, POW_r
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_Yrcub = POW_rsq, POW_U, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_p = POW_rsq, POW_P2, POW_v2
+ nop.i 999
+}
+;;
+
+// Test if x inf
+{ .mfi
+ nop.m 999
+ fclass.m p15,p0 = POW_NORM_X, 0x23
+ nop.i 999
+}
+// By adding RSHF (1.1000...*2^63) we put integer part in rightmost significand
+{ .mfi
+ nop.m 999
+ fma.s1 POW_W1 = POW_Z, POW_inv_log2_by_128, POW_RSHF
+ nop.i 999
+}
+;;
+
+// p13 = TRUE ==> X is NEGATIVE AND Y possible int
+// p10 = TRUE ==> X is NEG and Y is an int
+// p12 = TRUE ==> X is NEG and Y is not an int
+{ .mfi
+ nop.m 999
+(p13) fcmp.eq.unc.s1 p10,p12 = POW_float_int_Y, POW_NORM_Y
+ mov pow_GR_xneg_yodd = 0
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_Y_Gpr = POW_NORM_Y, POW_Gpr, f0
+ nop.i 999
+}
+;;
+
+// p11 = TRUE ==> X is +1.0
+{ .mfi
+ nop.m 999
+ fcmp.eq.s1 p11,p0 = POW_NORM_X, f1
+ nop.i 999
+}
+;;
+
+// Extract rounded integer from rightmost significand of POW_W1
+// By subtracting RSHF we get rounded integer POW_Nfloat
+{ .mfi
+ getf.sig pow_GR_int_N = POW_W1
+ fms.s1 POW_Nfloat = POW_W1, f1, POW_RSHF
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fma.s1 POW_Z3 = POW_p, POW_Yrcub, f0
+(p12) br.cond.spnt POW_X_NEG_Y_NONINT // Branch if x neg, y not integer
+}
+;;
+
+// p7 = TRUE ==> Y is +1.0
+// p12 = TRUE ==> X is NEGATIVE AND Y is an odd integer
+{ .mfi
+ getf.exp pow_GR_signexp_Y_Gpr = POW_Y_Gpr
+ fcmp.eq.s1 p7,p0 = POW_NORM_Y, f1 // Test for y=1.0
+(p10) tbit.nz.unc p12,p0 = pow_GR_sig_int_Y,0
+}
+{ .mfb
+ nop.m 999
+(p11) fma.s.s0 f8 = f1,f1,f0 // If x=1, result is +1
+(p15) br.cond.spnt POW_X_INF
+}
+;;
+
+// Test x and y and flag denormal
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p15,p0 = f8,f9
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fma.s1 POW_e3 = POW_NORM_Y, POW_delta, f0
+(p11) br.ret.spnt b0 // Early exit if x=1.0, result is +1
+}
+;;
+
+{ .mfi
+(p12) mov pow_GR_xneg_yodd = 1
+ fnma.s1 POW_f12 = POW_Nfloat, POW_log2_by_128_lo, f1
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fnma.s1 POW_s = POW_Nfloat, POW_log2_by_128_hi, POW_Z
+(p7) br.ret.spnt b0 // Early exit if y=1.0, result is x
+}
+;;
+
+{ .mmi
+ and pow_GR_index1 = 0x0f, pow_GR_int_N
+ and pow_GR_index2 = 0x70, pow_GR_int_N
+ shr pow_int_GR_M = pow_GR_int_N, 7 // M = N/128
+}
+;;
+
+{ .mfi
+ shladd pow_AD_T1 = pow_GR_index1, 4, pow_AD_tbl1
+ fma.s1 POW_q = POW_Z3, POW_Q1, POW_Q0_half
+ add pow_int_GR_M = pow_GR_16ones, pow_int_GR_M
+}
+{ .mfi
+ add pow_AD_T2 = pow_AD_tbl2, pow_GR_index2
+ fma.s1 POW_Z3sq = POW_Z3, POW_Z3, f0
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ldfe POW_T1 = [pow_AD_T1]
+ ldfe POW_T2 = [pow_AD_T2]
+ nop.i 999
+}
+;;
+
+// f123 = f12*(e3+1) = f12*e3+f12
+{ .mfi
+ setf.exp POW_2M = pow_int_GR_M
+ fma.s1 POW_f123 = POW_e3,POW_f12,POW_f12
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_ssq = POW_s, POW_s, f0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_v2 = POW_s, POW_Q2, POW_Q1
+ and pow_GR_exp_Y_Gpr = pow_GR_signexp_Y_Gpr, pow_GR_17ones
+}
+;;
+
+{ .mfi
+ cmp.ne p12,p13 = pow_GR_xneg_yodd, r0
+ fma.s1 POW_q = POW_Z3sq, POW_q, POW_Z3
+ sub pow_GR_true_exp_Y_Gpr = pow_GR_exp_Y_Gpr, pow_GR_16ones
+}
+;;
+
+// p8 TRUE ==> |Y(G + r)| >= 7
+
+// single
+// -2^7 -2^6 2^6 2^7
+// -----+-----+----+ ... +-----+-----+-----
+// p8 | p9 | p8
+// | | p10 | |
+
+// Form signexp of constants to indicate overflow
+{ .mfi
+ mov pow_GR_big_pos = 0x1007f
+ nop.f 999
+ cmp.le p8,p9 = 7, pow_GR_true_exp_Y_Gpr
+}
+{ .mfi
+ mov pow_GR_big_neg = 0x3007f
+ nop.f 999
+ andcm pow_GR_sign_Y_Gpr = pow_GR_signexp_Y_Gpr, pow_GR_17ones
+}
+;;
+
+// Form big positive and negative constants to test for possible overflow
+// Scale both terms of the polynomial by POW_f123
+{ .mfi
+ setf.exp POW_big_pos = pow_GR_big_pos
+ fma.s1 POW_ssq = POW_ssq, POW_f123, f0
+(p9) cmp.le.unc p0,p10 = 6, pow_GR_true_exp_Y_Gpr
+}
+{ .mfb
+ setf.exp POW_big_neg = pow_GR_big_neg
+ fma.s1 POW_1ps = POW_s, POW_f123, POW_f123
+(p8) br.cond.spnt POW_OVER_UNDER_X_NOT_INF
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p12) fnma.s1 POW_T1T2 = POW_T1, POW_T2, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p13) fma.s1 POW_T1T2 = POW_T1, POW_T2, f0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_v210 = POW_s, POW_v2, POW_Q0_half
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_2Mqp1 = POW_2M, POW_q, POW_2M
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 POW_es = POW_ssq, POW_v210, POW_1ps
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 POW_A = POW_T1T2, POW_2Mqp1, f0
+ nop.i 999
+}
+;;
+
+// Dummy op to set inexact
+{ .mfi
+ nop.m 999
+ fma.s0 POW_tmp = POW_2M, POW_q, POW_2M
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+ fma.s.s0 f8 = POW_A, POW_es, f0
+(p10) br.ret.sptk b0 // Exit main branch if no over/underflow
+}
+;;
+
+// POSSIBLE_OVER_UNDER
+// p6 = TRUE ==> Y_Gpr negative
+// Result is already computed. We just need to know if over/underflow occurred.
+
+{ .mfb
+ cmp.eq p0,p6 = pow_GR_sign_Y_Gpr, r0
+ nop.f 999
+(p6) br.cond.spnt POW_POSSIBLE_UNDER
+}
+;;
+
+// POSSIBLE_OVER
+// We got an answer.
+// overflow is a possibility, not a certainty
+
+
+// We define an overflow when the answer with
+// WRE set
+// user-defined rounding mode
+
+// double
+// Largest double is 7FE (biased double)
+// 7FE - 3FF + FFFF = 103FE
+// Create + largest_double_plus_ulp
+// Create - largest_double_plus_ulp
+// Calculate answer with WRE set.
+
+// single
+// Largest single is FE (biased double)
+// FE - 7F + FFFF = 1007E
+// Create + largest_single_plus_ulp
+// Create - largest_single_plus_ulp
+// Calculate answer with WRE set.
+
+// Cases when answer is ldn+1 are as follows:
+// ldn ldn+1
+// --+----------|----------+------------
+// |
+// +inf +inf -inf
+// RN RN
+// RZ
+
+// Put in s2 (td set, wre set)
+{ .mfi
+ nop.m 999
+ fsetc.s2 0x7F,0x42
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s.s2 POW_wre_urm_f8 = POW_A, POW_es, f0
+ nop.i 999
+}
+;;
+
+// Return s2 to default
+{ .mfi
+ nop.m 999
+ fsetc.s2 0x7F,0x40
+ nop.i 999
+}
+;;
+
+// p7 = TRUE ==> yes, we have an overflow
+{ .mfi
+ nop.m 999
+ fcmp.ge.s1 p7, p8 = POW_wre_urm_f8, POW_big_pos
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fcmp.le.s1 p7, p0 = POW_wre_urm_f8, POW_big_neg
+ nop.i 999
+}
+;;
+
+{ .mbb
+(p7) mov pow_GR_tag = 30
+(p7) br.cond.spnt __libm_error_region // Branch if overflow
+ br.ret.sptk b0 // Exit if did not overflow
+}
+;;
+
+
+POW_POSSIBLE_UNDER:
+// We got an answer. input was < -2^9 but > -2^10 (double)
+// We got an answer. input was < -2^6 but > -2^7 (float)
+// underflow is a possibility, not a certainty
+
+// We define an underflow when the answer with
+// ftz set
+// is zero (tiny numbers become zero)
+// Notice (from below) that if we have an unlimited exponent range,
+// then there is an extra machine number E between the largest denormal and
+// the smallest normal.
+// So if with unbounded exponent we round to E or below, then we are
+// tiny and underflow has occurred.
+// But notice that you can be in a situation where we are tiny, namely
+// rounded to E, but when the exponent is bounded we round to smallest
+// normal. So the answer can be the smallest normal with underflow.
+// E
+// -----+--------------------+--------------------+-----
+// | | |
+// 1.1...10 2^-3fff 1.1...11 2^-3fff 1.0...00 2^-3ffe
+// 0.1...11 2^-3ffe (biased, 1)
+// largest dn smallest normal
+
+// Form small constant (2^-170) to correct underflow result near region of
+// smallest denormal in round-nearest.
+
+// Put in s2 (td set, ftz set)
+.pred.rel "mutex",p12,p13
+{ .mfi
+ mov pow_GR_Fpsr = ar40 // Read the fpsr--need to check rc.s0
+ fsetc.s2 0x7F,0x41
+ mov pow_GR_rcs0_mask = 0x0c00 // Set mask for rc.s0
+}
+{ .mfi
+(p12) mov pow_GR_tmp = 0x2ffff - 170
+ nop.f 999
+(p13) mov pow_GR_tmp = 0x0ffff - 170
+}
+;;
+
+{ .mfi
+ setf.exp POW_eps = pow_GR_tmp // Form 2^-170
+ fma.s.s2 POW_ftz_urm_f8 = POW_A, POW_es, f0
+ nop.i 999
+}
+;;
+
+// Return s2 to default
+{ .mfi
+ nop.m 999
+ fsetc.s2 0x7F,0x40
+ nop.i 999
+}
+;;
+
+// p7 = TRUE ==> yes, we have an underflow
+{ .mfi
+ nop.m 999
+ fcmp.eq.s1 p7, p0 = POW_ftz_urm_f8, f0
+ nop.i 999
+}
+;;
+
+{ .mmi
+(p7) and pow_GR_rcs0 = pow_GR_rcs0_mask, pow_GR_Fpsr // Isolate rc.s0
+;;
+(p7) cmp.eq.unc p6,p0 = pow_GR_rcs0, r0 // Test for round to nearest
+ nop.i 999
+}
+;;
+
+// Tweak result slightly if underflow to get correct rounding near smallest
+// denormal if round-nearest
+{ .mfi
+ nop.m 999
+(p6) fms.s.s0 f8 = POW_A, POW_es, POW_eps
+ nop.i 999
+}
+{ .mbb
+(p7) mov pow_GR_tag = 31
+(p7) br.cond.spnt __libm_error_region // Branch if underflow
+ br.ret.sptk b0 // Exit if did not underflow
+}
+;;
+
+POW_X_DENORM:
+// Here if x unorm. Use the NORM_X for getf instructions, and then back
+// to normal path
+{ .mfi
+ getf.exp pow_GR_signexp_X = POW_NORM_X
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mib
+ getf.sig pow_GR_sig_X = POW_NORM_X
+ nop.i 999
+ br.cond.sptk POW_COMMON
+}
+;;
+
+POW_X_0:
+// Here if x=0 and y not nan
+//
+// We have the following cases:
+// p6 x=0 and y>0 and is an integer (may be even or odd)
+// p7 x=0 and y>0 and is NOT an integer, return +0
+// p8 x=0 and y>0 and so big as to always be an even integer, return +0
+// p9 x=0 and y>0 and may not be integer
+// p10 x=0 and y>0 and is an odd integer, return x
+// p11 x=0 and y>0 and is an even integer, return +0
+// p12 used in dummy fcmp to set denormal flag if y=unorm
+// p13 x=0 and y>0
+// p14 x=0 and y=0, branch to code for calling error handling
+// p15 x=0 and y<0, branch to code for calling error handling
+//
+{ .mfi
+ getf.sig pow_GR_sig_int_Y = POW_int_Y // Get signif of int_Y
+ fcmp.lt.s1 p15,p13 = f9, f0 // Test for y<0
+ and pow_GR_exp_Y = pow_GR_signexp_Y, pow_GR_17ones
+}
+{ .mfb
+ cmp.ne p14,p0 = pow_GR_y_zero,r0 // Test for y=0
+ fcvt.xf POW_float_int_Y = POW_int_Y
+(p14) br.cond.spnt POW_X_0_Y_0 // Branch if x=0 and y=0
+}
+;;
+
+// If x=0 and y>0, test y and flag denormal
+{ .mfb
+(p13) cmp.gt.unc p8,p9 = pow_GR_exp_Y, pow_GR_10033 // Test y +big = even int
+(p13) fcmp.eq.s0 p12,p0 = f9,f0 // If x=0, y>0 dummy op to flag denormal
+(p15) br.cond.spnt POW_X_0_Y_NEG // Branch if x=0 and y<0
+}
+;;
+
+// Here if x=0 and y>0
+{ .mfi
+ nop.m 999
+(p9) fcmp.eq.unc.s1 p6,p7 = POW_float_int_Y, POW_NORM_Y // Test y=int
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s.s0 f8 = f0,f0,f0 // If x=0, y>0 and large even int, return +0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fma.s.s0 f8 = f0,f0,f0 // Result +0 if x=0 and y>0 and not integer
+(p6) tbit.nz.unc p10,p11 = pow_GR_sig_int_Y,0 // If y>0 int, test y even/odd
+}
+;;
+
+// Note if x=0, y>0 and odd integer, just return x
+{ .mfb
+ nop.m 999
+(p11) fma.s.s0 f8 = f0,f0,f0 // Result +0 if x=0 and y even integer
+ br.ret.sptk b0 // Exit if x=0 and y>0
+}
+;;
+
+POW_X_0_Y_0:
+// When X is +-0 and Y is +-0, IEEE returns 1.0
+// We call error support with this value
+
+{ .mfb
+ mov pow_GR_tag = 32
+ fma.s.s0 f8 = f1,f1,f0
+ br.cond.sptk __libm_error_region
+}
+;;
+
+POW_X_0_Y_NEG:
+// When X is +-0 and Y is negative, IEEE returns
+// X Y answer
+// +0 -odd int +inf
+// -0 -odd int -inf
+
+// +0 !-odd int +inf
+// -0 !-odd int +inf
+
+// p6 == Y is a floating point number outside the integer.
+// Hence it is an integer and is even.
+// return +inf
+
+// p7 == Y is a floating point number within the integer range.
+// p9 == (int_Y = NORM_Y), Y is an integer, which may be odd or even.
+// p11 odd
+// return (sign_of_x)inf
+// p12 even
+// return +inf
+// p10 == Y is not an integer
+// return +inf
+//
+
+{ .mfi
+ nop.m 999
+ nop.f 999
+ cmp.gt p6,p7 = pow_GR_exp_Y, pow_GR_10033
+}
+;;
+
+{ .mfi
+ mov pow_GR_tag = 33
+(p7) fcmp.eq.unc.s1 p9,p10 = POW_float_int_Y, POW_NORM_Y
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p6) frcpa.s0 f8,p13 = f1, f0
+(p6) br.cond.sptk __libm_error_region // x=0, y<0, y large neg int
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p10) frcpa.s0 f8,p13 = f1, f0
+(p10) br.cond.sptk __libm_error_region // x=0, y<0, y not int
+}
+;;
+
+// x=0, y<0, y an int
+{ .mib
+ nop.m 999
+(p9) tbit.nz.unc p11,p12 = pow_GR_sig_int_Y,0
+ nop.b 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p12) frcpa.s0 f8,p13 = f1,f0
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p11) frcpa.s0 f8,p13 = f1,f8
+ br.cond.sptk __libm_error_region
+}
+;;
+
+
+POW_Y_0:
+// Here for y zero, x anything but zero and nan
+// Set flag if x denormal
+// Result is +1.0
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p6,p0 = f8,f0 // Sets flag if x denormal
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fma.s.s0 f8 = f1,f1,f0
+ br.ret.sptk b0
+}
+;;
+
+
+POW_X_INF:
+// Here when X is +-inf
+
+// X +inf Y +inf +inf
+// X -inf Y +inf +inf
+
+// X +inf Y >0 +inf
+// X -inf Y >0, !odd integer +inf <== (-inf)^0.5 = +inf !!
+// X -inf Y >0, odd integer -inf
+
+// X +inf Y -inf +0
+// X -inf Y -inf +0
+
+// X +inf Y <0 +0
+// X -inf Y <0, !odd integer +0
+// X -inf Y <0, odd integer -0
+
+// X + inf Y=+0 +1
+// X + inf Y=-0 +1
+// X - inf Y=+0 +1
+// X - inf Y=-0 +1
+
+// p13 == Y negative
+// p14 == Y positive
+
+// p6 == Y is a floating point number outside the integer.
+// Hence it is an integer and is even.
+// p13 == (Y negative)
+// return +inf
+// p14 == (Y positive)
+// return +0
+
+// p7 == Y is a floating point number within the integer range.
+// p9 == (int_Y = NORM_Y), Y is an integer, which may be odd or even.
+// p11 odd
+// p13 == (Y negative)
+// return (sign_of_x)inf
+// p14 == (Y positive)
+// return (sign_of_x)0
+// pxx even
+// p13 == (Y negative)
+// return +inf
+// p14 == (Y positive)
+// return +0
+
+// pxx == Y is not an integer
+// p13 == (Y negative)
+// return +inf
+// p14 == (Y positive)
+// return +0
+//
+
+// If x=inf, test y and flag denormal
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p10,p11 = f9,f0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcmp.lt.s0 p13,p14 = POW_NORM_Y,f0
+ cmp.gt p6,p7 = pow_GR_exp_Y, pow_GR_10033
+}
+{ .mfi
+ nop.m 999
+ fclass.m p12,p0 = f9, 0x23 //@inf
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p15,p0 = f9, 0x07 //@zero
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p15) fmerge.s f8 = f1,f1 // Return +1.0 if x=inf, y=0
+(p15) br.ret.spnt b0 // Exit if x=inf, y=0
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p14) frcpa.s1 f8,p10 = f1,f0 // If x=inf, y>0, assume result +inf
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p13) fma.s.s0 f8 = f0,f0,f0 // If x=inf, y<0, assume result +0.0
+(p12) br.ret.spnt b0 // Exit if x=inf, y=inf
+}
+;;
+
+// Here if x=inf, and 0 < |y| < inf. Need to correct results if y odd integer.
+{ .mfi
+ nop.m 999
+(p7) fcmp.eq.unc.s1 p9,p0 = POW_float_int_Y, POW_NORM_Y // Is y integer?
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ nop.f 999
+(p9) tbit.nz.unc p11,p0 = pow_GR_sig_int_Y,0 // Test for y odd integer
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p11) fmerge.s f8 = POW_NORM_X,f8 // If y odd integer use sign of x
+ br.ret.sptk b0 // Exit for x=inf, 0 < |y| < inf
+}
+;;
+
+
+POW_X_NEG_Y_NONINT:
+// When X is negative and Y is a non-integer, IEEE
+// returns a qnan indefinite.
+// We call error support with this value
+
+{ .mfb
+ mov pow_GR_tag = 34
+ frcpa.s0 f8,p6 = f0,f0
+ br.cond.sptk __libm_error_region
+}
+;;
+
+POW_X_NAN:
+// Here if x=nan, y not nan
+{ .mfi
+ nop.m 999
+ fclass.m p9,p13 = f9, 0x07 // Test y=zero
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p13) fma.s.s0 f8 = f8,f1,f0
+(p13) br.ret.sptk b0 // Exit if x nan, y anything but zero or nan
+}
+;;
+
+POW_X_NAN_Y_0:
+// When X is a NAN and Y is zero, IEEE returns 1.
+// We call error support with this value.
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p6,p0 = f8,f0 // Dummy op to set invalid on snan
+ nop.i 999
+}
+{ .mfb
+ mov pow_GR_tag = 35
+ fma.s.s0 f8 = f0,f0,f1
+ br.cond.sptk __libm_error_region
+}
+;;
+
+
+POW_OVER_UNDER_X_NOT_INF:
+
+// p8 is TRUE for overflow
+// p9 is TRUE for underflow
+
+// if y is infinity, we should not over/underflow
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.s1 p14, p13 = POW_xsq,f1 // Test |x|=1
+ cmp.eq p8,p9 = pow_GR_sign_Y_Gpr, r0
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p14) fclass.m.unc p15, p0 = f9, 0x23 // If |x|=1, test y=inf
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p13) fclass.m.unc p11,p0 = f9, 0x23 // If |x| not 1, test y=inf
+ nop.i 999
+}
+;;
+
+// p15 = TRUE if |x|=1, y=inf, return +1
+{ .mfb
+ nop.m 999
+(p15) fma.s.s0 f8 = f1,f1,f0 // If |x|=1, y=inf, result +1
+(p15) br.ret.spnt b0 // Exit if |x|=1, y=inf
+}
+;;
+
+.pred.rel "mutex",p8,p9
+{ .mfb
+(p8) setf.exp f8 = pow_GR_17ones // If exp(+big), result inf
+(p9) fmerge.s f8 = f0,f0 // If exp(-big), result 0
+(p11) br.ret.sptk b0 // Exit if |x| not 1, y=inf
+}
+;;
+
+{ .mfb
+ nop.m 999
+ nop.f 999
+ br.cond.sptk POW_OVER_UNDER_ERROR // Branch if y not inf
+}
+;;
+
+
+POW_Y_NAN:
+// Here if y=nan, x anything
+// If x = +1 then result is +1, else result is quiet Y
+{ .mfi
+ nop.m 999
+ fcmp.eq.s1 p10,p9 = POW_NORM_X, f1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p10) fcmp.eq.s0 p6,p0 = f9,f1 // Set invalid, even if x=+1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p10) fma.s.s0 f8 = f1,f1,f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p9) fma.s.s0 f8 = f9,f8,f0
+ br.ret.sptk b0 // Exit y=nan
+}
+;;
+
+
+POW_OVER_UNDER_ERROR:
+// Here if we have overflow or underflow.
+// Enter with p12 true if x negative and y odd int to force -0 or -inf
+
+{ .mfi
+ sub pow_GR_17ones_m1 = pow_GR_17ones, r0, 1
+ nop.f 999
+ mov pow_GR_one = 0x1
+}
+;;
+
+// overflow, force inf with O flag
+{ .mmb
+(p8) mov pow_GR_tag = 30
+(p8) setf.exp POW_tmp = pow_GR_17ones_m1
+ nop.b 999
+}
+;;
+
+// underflow, force zero with I, U flags
+{ .mmi
+(p9) mov pow_GR_tag = 31
+(p9) setf.exp POW_tmp = pow_GR_one
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s.s0 f8 = POW_tmp, POW_tmp, f0
+ nop.i 999
+}
+;;
+
+// p12 x is negative and y is an odd integer, change sign of result
+{ .mfi
+ nop.m 999
+(p12) fnma.s.s0 f8 = POW_tmp, POW_tmp, f0
+ nop.i 999
+}
+;;
+
+GLOBAL_LIBM_END(powf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfs [GR_Parameter_Y] = POW_NORM_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfs [GR_Parameter_X] = POW_NORM_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/e_powl.S b/libc/sysdeps/ia64/fpu/e_powl.S
new file mode 100644
index 000000000..3f93f6090
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_powl.S
@@ -0,0 +1,2810 @@
+.file "powl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// Function: powl(x,y), where
+// y
+// powl(x,y) = x , for double extended precision x and y values
+//
+//*********************************************************************
+//
+// History:
+// 02/02/00 (Hand Optimized)
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 01/22/01 Corrected results for powl(1,inf), powl(1,nan), and
+// powl(snan,0) to be 1 per C99, not nan. Fixed many flag settings.
+// 02/06/01 Call __libm_error support if over/underflow when y=2.
+// 04/17/01 Support added for y close to 1 and x a non-special value.
+// Shared software under/overflow detection for all paths
+// 02/07/02 Corrected sf3 setting to disable traps
+// 05/13/02 Improved performance of all paths
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+// 04/17/03 Added missing mutex directive
+// 10/13/03 Corrected .endp names to match .proc names
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers:
+// f8 (Input x and Return Value)
+// f9 (Input y)
+// f10-f15,f32-f79
+//
+// General Purpose Registers:
+// Locals r14-24,r32-r65
+// Parameters to __libm_error_support r62,r63,r64,r65
+//
+// Predicate Registers: p6-p15
+//
+//*********************************************************************
+//
+// Special Cases and IEEE special conditions:
+//
+// Denormal fault raised on denormal inputs
+// Overflow exceptions raised when appropriate for pow
+// Underflow exceptions raised when appropriate for pow
+// (Error Handling Routine called for overflow and Underflow)
+// Inexact raised when appropriate by algorithm
+//
+// 1. (anything) ** NatVal or (NatVal) ** anything is NatVal
+// 2. X or Y unsupported or sNaN is qNaN/Invalid
+// 3. (anything) ** 0 is 1
+// 4. (anything) ** 1 is itself
+// 5. (anything except 1) ** qNAN is qNAN
+// 6. qNAN ** (anything except 0) is qNAN
+// 7. +-(|x| > 1) ** +INF is +INF
+// 8. +-(|x| > 1) ** -INF is +0
+// 9. +-(|x| < 1) ** +INF is +0
+// 10. +-(|x| < 1) ** -INF is +INF
+// 11. +-1 ** +-INF is +1
+// 12. +0 ** (+anything except 0, NAN) is +0
+// 13. -0 ** (+anything except 0, NAN, odd integer) is +0
+// 14. +0 ** (-anything except 0, NAN) is +INF/div_0
+// 15. -0 ** (-anything except 0, NAN, odd integer) is +INF/div_0
+// 16. -0 ** (odd integer) = -( +0 ** (odd integer) )
+// 17. +INF ** (+anything except 0,NAN) is +INF
+// 18. +INF ** (-anything except 0,NAN) is +0
+// 19. -INF ** (anything except NAN) = -0 ** (-anything)
+// 20. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
+// 21. (-anything except 0 and inf) ** (non-integer) is qNAN/Invalid
+// 22. X or Y denorm/unorm and denorm/unorm operand trap is enabled,
+// generate denorm/unorm fault except if invalid or div_0 raised.
+//
+//*********************************************************************
+//
+// Algorithm
+// =========
+//
+// Special Cases
+//
+// If Y = 2, return X*X.
+// If Y = 0.5, return sqrt(X).
+//
+// Compute log(X) to extra precision.
+//
+// ker_log_80( X, logX_hi, logX_lo, Safe );
+//
+// ...logX_hi + logX_lo approximates log(X) to roughly 80
+// ...significant bits of accuracy.
+//
+// Compute Y*log(X) to extra precision.
+//
+// P_hi := Y * logX_hi
+// P_lo := Y * logX_hi - P_hi ...using FMA
+// P_lo := Y * logX_lo + P_lo ...using FMA
+//
+// Compute exp(P_hi + P_lo)
+//
+// Flag := 2;
+// Expo_Range := 2; (assuming double-extended power function)
+// ker_exp_64( P_hi, P_lo, Flag, Expo_Range,
+// Z_hi, Z_lo, scale, Safe )
+//
+// scale := sgn * scale
+//
+// If (Safe) then ...result will not over/underflow
+// return scale*Z_hi + (scale*Z_lo)
+// quickly
+// Else
+// take necessary precaution in computing
+// scale*Z_hi + (scale*Z_lo)
+// to set possible exceptions correctly.
+// End If
+//
+// Case_Y_Special
+//
+// ...Follow the order of the case checks
+//
+// If Y is +-0, return +1 without raising any exception.
+// If Y is +1, return X without raising any exception.
+// If Y is qNaN, return Y without exception.
+// If X is qNaN, return X without exception.
+//
+// At this point, X is real and Y is +-inf.
+// Thus |X| can only be 1, strictly bigger than 1, or
+// strictly less than 1.
+//
+// If |X| < 1, then
+// return ( Y == +inf? +0 : +inf )
+// elseif |X| > 1, then
+// return ( Y == +inf? +0 : +inf )
+// else
+// goto Case_Invalid
+//
+// Case_X_Special
+//
+// ...Follow the order of the case checks
+// ...Note that Y is real, finite, non-zero, and not +1.
+//
+// If X is qNaN, return X without exception.
+//
+// If X is +-0,
+// return ( Y > 0 ? +0 : +inf )
+//
+// If X is +inf
+// return ( Y > 0 ? +inf : +0 )
+//
+// If X is -inf
+// return -0 ** -Y
+// return ( Y > 0 ? +inf : +0 )
+//
+// Case_Invalid
+//
+// Return 0 * inf to generate a quiet NaN together
+// with an invalid exception.
+//
+// Implementation
+// ==============
+//
+// We describe the quick branch since this part is important
+// in reaching the normal case efficiently.
+//
+// STAGE 1
+// -------
+// This stage contains two threads.
+//
+// Stage1.Thread1
+//
+// fclass.m X_excep, X_ok = X, (NatVal or s/qNaN) or
+// +-0, +-infinity
+//
+// fclass.nm X_unsupp, X_supp = X, (NatVal or s/qNaN) or
+// +-(0, unnorm, norm, infinity)
+//
+// X_norm := fnorm( X ) with traps disabled
+//
+// If (X_excep) goto Filtering (Step 2)
+// If (X_unsupp) goto Filtering (Step 2)
+//
+// Stage1.Thread2
+// ..............
+//
+// fclass.m Y_excep, Y_ok = Y, (NatVal or s/qNaN) or
+// +-0, +-infinity
+//
+// fclass.nm Y_unsupp, Y_supp = Y, (NatVal or s/qNaN) or
+// +-(0, unnorm, norm, infinity)
+//
+// Y_norm := fnorm( Y ) with traps disabled
+//
+// If (Y_excep) goto Filtering (Step 2)
+// If (Y_unsupp) goto Filtering (Step 2)
+//
+//
+// STAGE 2
+// -------
+// This stage contains two threads.
+//
+// Stage2.Thread1
+// ..............
+//
+// Set X_lt_0 if X < 0 (using fcmp)
+// sgn := +1.0
+// If (X_lt_0) goto Filtering (Step 2)
+//
+// Stage2.Thread2
+// ..............
+//
+// Set Y_is_1 if Y = +1 (using fcmp)
+// If (Y_is_1) goto Filtering (Step 2)
+//
+// STAGE 3
+// -------
+// This stage contains two threads.
+//
+//
+// Stage3.Thread1
+// ..............
+//
+// X := fnorm(X) in prevailing traps
+//
+//
+// Stage3.Thread2
+// ..............
+//
+// Y := fnorm(Y) in prevailing traps
+//
+// STAGE 4
+// -------
+//
+// Go to Case_Normal.
+//
+
+
+// ************* DO NOT CHANGE ORDER OF THESE TABLES ********************
+
+// double-extended 1/ln(2)
+// 3fff b8aa 3b29 5c17 f0bb be87fed0691d3e88
+// 3fff b8aa 3b29 5c17 f0bc
+// For speed the significand will be loaded directly with a movl and setf.sig
+// and the exponent will be bias+63 instead of bias+0. Thus subsequent
+// computations need to scale appropriately.
+// The constant 2^12/ln(2) is needed for the computation of N. This is also
+// obtained by scaling the computations.
+//
+// Two shifting constants are loaded directly with movl and setf.d.
+// 1. RSHF_2TO51 = 1.1000..00 * 2^(63-12)
+// This constant is added to x*1/ln2 to shift the integer part of
+// x*2^12/ln2 into the rightmost bits of the significand.
+// The result of this fma is N_signif.
+// 2. RSHF = 1.1000..00 * 2^(63)
+// This constant is subtracted from N_signif * 2^(-51) to give
+// the integer part of N, N_fix, as a floating-point number.
+// The result of this fms is float_N.
+RODATA
+
+.align 16
+// L_hi, L_lo
+LOCAL_OBJECT_START(Constants_exp_64_Arg)
+data8 0xB17217F400000000,0x00003FF2 // L_hi = hi part log(2)/2^12
+data8 0xF473DE6AF278ECE6,0x00003FD4 // L_lo = lo part log(2)/2^12
+LOCAL_OBJECT_END(Constants_exp_64_Arg)
+
+LOCAL_OBJECT_START(Constants_exp_64_A)
+// Reversed
+data8 0xAAAAAAABB1B736A0,0x00003FFA
+data8 0xAAAAAAAB90CD6327,0x00003FFC
+data8 0xFFFFFFFFFFFFFFFF,0x00003FFD
+LOCAL_OBJECT_END(Constants_exp_64_A)
+
+LOCAL_OBJECT_START(Constants_exp_64_P)
+// Reversed
+data8 0xD00D6C8143914A8A,0x00003FF2
+data8 0xB60BC4AC30304B30,0x00003FF5
+data8 0x888888887474C518,0x00003FF8
+data8 0xAAAAAAAA8DAE729D,0x00003FFA
+data8 0xAAAAAAAAAAAAAF61,0x00003FFC
+data8 0x80000000000004C7,0x00003FFE
+LOCAL_OBJECT_END(Constants_exp_64_P)
+
+LOCAL_OBJECT_START(Constants_exp_64_T1)
+data4 0x3F800000,0x3F8164D2,0x3F82CD87,0x3F843A29
+data4 0x3F85AAC3,0x3F871F62,0x3F88980F,0x3F8A14D5
+data4 0x3F8B95C2,0x3F8D1ADF,0x3F8EA43A,0x3F9031DC
+data4 0x3F91C3D3,0x3F935A2B,0x3F94F4F0,0x3F96942D
+data4 0x3F9837F0,0x3F99E046,0x3F9B8D3A,0x3F9D3EDA
+data4 0x3F9EF532,0x3FA0B051,0x3FA27043,0x3FA43516
+data4 0x3FA5FED7,0x3FA7CD94,0x3FA9A15B,0x3FAB7A3A
+data4 0x3FAD583F,0x3FAF3B79,0x3FB123F6,0x3FB311C4
+data4 0x3FB504F3,0x3FB6FD92,0x3FB8FBAF,0x3FBAFF5B
+data4 0x3FBD08A4,0x3FBF179A,0x3FC12C4D,0x3FC346CD
+data4 0x3FC5672A,0x3FC78D75,0x3FC9B9BE,0x3FCBEC15
+data4 0x3FCE248C,0x3FD06334,0x3FD2A81E,0x3FD4F35B
+data4 0x3FD744FD,0x3FD99D16,0x3FDBFBB8,0x3FDE60F5
+data4 0x3FE0CCDF,0x3FE33F89,0x3FE5B907,0x3FE8396A
+data4 0x3FEAC0C7,0x3FED4F30,0x3FEFE4BA,0x3FF28177
+data4 0x3FF5257D,0x3FF7D0DF,0x3FFA83B3,0x3FFD3E0C
+LOCAL_OBJECT_END(Constants_exp_64_T1)
+
+LOCAL_OBJECT_START(Constants_exp_64_T2)
+data4 0x3F800000,0x3F80058C,0x3F800B18,0x3F8010A4
+data4 0x3F801630,0x3F801BBD,0x3F80214A,0x3F8026D7
+data4 0x3F802C64,0x3F8031F2,0x3F803780,0x3F803D0E
+data4 0x3F80429C,0x3F80482B,0x3F804DB9,0x3F805349
+data4 0x3F8058D8,0x3F805E67,0x3F8063F7,0x3F806987
+data4 0x3F806F17,0x3F8074A8,0x3F807A39,0x3F807FCA
+data4 0x3F80855B,0x3F808AEC,0x3F80907E,0x3F809610
+data4 0x3F809BA2,0x3F80A135,0x3F80A6C7,0x3F80AC5A
+data4 0x3F80B1ED,0x3F80B781,0x3F80BD14,0x3F80C2A8
+data4 0x3F80C83C,0x3F80CDD1,0x3F80D365,0x3F80D8FA
+data4 0x3F80DE8F,0x3F80E425,0x3F80E9BA,0x3F80EF50
+data4 0x3F80F4E6,0x3F80FA7C,0x3F810013,0x3F8105AA
+data4 0x3F810B41,0x3F8110D8,0x3F81166F,0x3F811C07
+data4 0x3F81219F,0x3F812737,0x3F812CD0,0x3F813269
+data4 0x3F813802,0x3F813D9B,0x3F814334,0x3F8148CE
+data4 0x3F814E68,0x3F815402,0x3F81599C,0x3F815F37
+LOCAL_OBJECT_END(Constants_exp_64_T2)
+
+LOCAL_OBJECT_START(Constants_exp_64_W1)
+data8 0x0000000000000000, 0xBE384454171EC4B4
+data8 0xBE6947414AA72766, 0xBE5D32B6D42518F8
+data8 0x3E68D96D3A319149, 0xBE68F4DA62415F36
+data8 0xBE6DDA2FC9C86A3B, 0x3E6B2E50F49228FE
+data8 0xBE49C0C21188B886, 0x3E64BFC21A4C2F1F
+data8 0xBE6A2FBB2CB98B54, 0x3E5DC5DE9A55D329
+data8 0x3E69649039A7AACE, 0x3E54728B5C66DBA5
+data8 0xBE62B0DBBA1C7D7D, 0x3E576E0409F1AF5F
+data8 0x3E6125001A0DD6A1, 0xBE66A419795FBDEF
+data8 0xBE5CDE8CE1BD41FC, 0xBE621376EA54964F
+data8 0x3E6370BE476E76EE, 0x3E390D1A3427EB92
+data8 0x3E1336DE2BF82BF8, 0xBE5FF1CBD0F7BD9E
+data8 0xBE60A3550CEB09DD, 0xBE5CA37E0980F30D
+data8 0xBE5C541B4C082D25, 0xBE5BBECA3B467D29
+data8 0xBE400D8AB9D946C5, 0xBE5E2A0807ED374A
+data8 0xBE66CB28365C8B0A, 0x3E3AAD5BD3403BCA
+data8 0x3E526055C7EA21E0, 0xBE442C75E72880D6
+data8 0x3E58B2BB85222A43, 0xBE5AAB79522C42BF
+data8 0xBE605CB4469DC2BC, 0xBE589FA7A48C40DC
+data8 0xBE51C2141AA42614, 0xBE48D087C37293F4
+data8 0x3E367A1CA2D673E0, 0xBE51BEBB114F7A38
+data8 0xBE6348E5661A4B48, 0xBDF526431D3B9962
+data8 0x3E3A3B5E35A78A53, 0xBE46C46C1CECD788
+data8 0xBE60B7EC7857D689, 0xBE594D3DD14F1AD7
+data8 0xBE4F9C304C9A8F60, 0xBE52187302DFF9D2
+data8 0xBE5E4C8855E6D68F, 0xBE62140F667F3DC4
+data8 0xBE36961B3BF88747, 0x3E602861C96EC6AA
+data8 0xBE3B5151D57FD718, 0x3E561CD0FC4A627B
+data8 0xBE3A5217CA913FEA, 0x3E40A3CC9A5D193A
+data8 0xBE5AB71310A9C312, 0x3E4FDADBC5F57719
+data8 0x3E361428DBDF59D5, 0x3E5DB5DB61B4180D
+data8 0xBE42AD5F7408D856, 0x3E2A314831B2B707
+LOCAL_OBJECT_END(Constants_exp_64_W1)
+
+LOCAL_OBJECT_START(Constants_exp_64_W2)
+data8 0x0000000000000000, 0xBE641F2537A3D7A2
+data8 0xBE68DD57AD028C40, 0xBE5C77D8F212B1B6
+data8 0x3E57878F1BA5B070, 0xBE55A36A2ECAE6FE
+data8 0xBE620608569DFA3B, 0xBE53B50EA6D300A3
+data8 0x3E5B5EF2223F8F2C, 0xBE56A0D9D6DE0DF4
+data8 0xBE64EEF3EAE28F51, 0xBE5E5AE2367EA80B
+data8 0x3E47CB1A5FCBC02D, 0xBE656BA09BDAFEB7
+data8 0x3E6E70C6805AFEE7, 0xBE6E0509A3415EBA
+data8 0xBE56856B49BFF529, 0x3E66DD3300508651
+data8 0x3E51165FC114BC13, 0x3E53333DC453290F
+data8 0x3E6A072B05539FDA, 0xBE47CD877C0A7696
+data8 0xBE668BF4EB05C6D9, 0xBE67C3E36AE86C93
+data8 0xBE533904D0B3E84B, 0x3E63E8D9556B53CE
+data8 0x3E212C8963A98DC8, 0xBE33138F032A7A22
+data8 0x3E530FA9BC584008, 0xBE6ADF82CCB93C97
+data8 0x3E5F91138370EA39, 0x3E5443A4FB6A05D8
+data8 0x3E63DACD181FEE7A, 0xBE62B29DF0F67DEC
+data8 0x3E65C4833DDE6307, 0x3E5BF030D40A24C1
+data8 0x3E658B8F14E437BE, 0xBE631C29ED98B6C7
+data8 0x3E6335D204CF7C71, 0x3E529EEDE954A79D
+data8 0x3E5D9257F64A2FB8, 0xBE6BED1B854ED06C
+data8 0x3E5096F6D71405CB, 0xBE3D4893ACB9FDF5
+data8 0xBDFEB15801B68349, 0x3E628D35C6A463B9
+data8 0xBE559725ADE45917, 0xBE68C29C042FC476
+data8 0xBE67593B01E511FA, 0xBE4A4313398801ED
+data8 0x3E699571DA7C3300, 0x3E5349BE08062A9E
+data8 0x3E5229C4755BB28E, 0x3E67E42677A1F80D
+data8 0xBE52B33F6B69C352, 0xBE6B3550084DA57F
+data8 0xBE6DB03FD1D09A20, 0xBE60CBC42161B2C1
+data8 0x3E56ED9C78A2B771, 0xBE508E319D0FA795
+data8 0xBE59482AFD1A54E9, 0xBE2A17CEB07FD23E
+data8 0x3E68BF5C17365712, 0x3E3956F9B3785569
+LOCAL_OBJECT_END(Constants_exp_64_W2)
+
+LOCAL_OBJECT_START(Constants_log_80_P)
+// P_8, P_7, ..., P_1
+data8 0xCCCE8B883B1042BC, 0x0000BFFB // P_8
+data8 0xE38997B7CADC2149, 0x00003FFB // P_7
+data8 0xFFFFFFFEB1ACB090, 0x0000BFFB // P_6
+data8 0x9249249806481C81, 0x00003FFC // P_5
+data8 0x0000000000000000, 0x00000000 // Pad for bank conflicts
+data8 0xAAAAAAAAAAAAB0EF, 0x0000BFFC // P_4
+data8 0xCCCCCCCCCCC91416, 0x00003FFC // P_3
+data8 0x8000000000000000, 0x0000BFFD // P_2
+data8 0xAAAAAAAAAAAAAAAB, 0x00003FFD // P_1
+LOCAL_OBJECT_END(Constants_log_80_P)
+
+LOCAL_OBJECT_START(Constants_log_80_Q)
+// log2_hi, log2_lo, Q_6, Q_5, Q_4, Q_3, Q_2, Q_1
+data8 0xB172180000000000,0x00003FFE
+data8 0x82E308654361C4C6,0x0000BFE2
+data8 0x92492453A51BE0AF,0x00003FFC
+data8 0xAAAAAB73A0CFD29F,0x0000BFFC
+data8 0xCCCCCCCCCCCE3872,0x00003FFC
+data8 0xFFFFFFFFFFFFB4FB,0x0000BFFC
+data8 0xAAAAAAAAAAAAAAAB,0x00003FFD
+data8 0x8000000000000000,0x0000BFFE
+LOCAL_OBJECT_END(Constants_log_80_Q)
+
+LOCAL_OBJECT_START(Constants_log_80_Z_G_H_h1)
+// Z1 - 16 bit fixed, G1 and H1 IEEE single, h1 IEEE double
+data4 0x00008000,0x3F800000,0x00000000,0x00000000
+data4 0x00000000,0x00000000,0x00000000,0x00000000
+data4 0x00007879,0x3F70F0F0,0x3D785196,0x00000000
+data4 0xEBA0E0D1,0x8B1D330B,0x00003FDA,0x00000000
+data4 0x000071C8,0x3F638E38,0x3DF13843,0x00000000
+data4 0x9EADD553,0xE2AF365E,0x00003FE2,0x00000000
+data4 0x00006BCB,0x3F579430,0x3E2FF9A0,0x00000000
+data4 0x752F34A2,0xF585FEC3,0x0000BFE3,0x00000000
+data4 0x00006667,0x3F4CCCC8,0x3E647FD6,0x00000000
+data4 0x893B03F3,0xF3546435,0x00003FE2,0x00000000
+data4 0x00006187,0x3F430C30,0x3E8B3AE7,0x00000000
+data4 0x39CDD2AC,0xBABA62E0,0x00003FE4,0x00000000
+data4 0x00005D18,0x3F3A2E88,0x3EA30C68,0x00000000
+data4 0x457978A1,0x8718789F,0x00003FE2,0x00000000
+data4 0x0000590C,0x3F321640,0x3EB9CEC8,0x00000000
+data4 0x3185E56A,0x9442DF96,0x0000BFE4,0x00000000
+data4 0x00005556,0x3F2AAAA8,0x3ECF9927,0x00000000
+data4 0x2BBE2CBD,0xCBF9A4BF,0x00003FE4,0x00000000
+data4 0x000051EC,0x3F23D708,0x3EE47FC5,0x00000000
+data4 0x852D5935,0xF3537535,0x00003FE3,0x00000000
+data4 0x00004EC5,0x3F1D89D8,0x3EF8947D,0x00000000
+data4 0x46CDF32F,0xA1F1E699,0x0000BFDF,0x00000000
+data4 0x00004BDB,0x3F17B420,0x3F05F3A1,0x00000000
+data4 0xD8484CE3,0x84A61856,0x00003FE4,0x00000000
+data4 0x00004925,0x3F124920,0x3F0F4303,0x00000000
+data4 0xFF28821B,0xC7DD97E0,0x0000BFE2,0x00000000
+data4 0x0000469F,0x3F0D3DC8,0x3F183EBF,0x00000000
+data4 0xEF1FD32F,0xD3C4A887,0x00003FE3,0x00000000
+data4 0x00004445,0x3F088888,0x3F20EC80,0x00000000
+data4 0x464C76DA,0x84672BE6,0x00003FE5,0x00000000
+data4 0x00004211,0x3F042108,0x3F29516A,0x00000000
+data4 0x18835FB9,0x9A43A511,0x0000BFE5,0x00000000
+LOCAL_OBJECT_END(Constants_log_80_Z_G_H_h1)
+
+LOCAL_OBJECT_START(Constants_log_80_Z_G_H_h2)
+// Z2 - 16 bit fixed, G2 and H2 IEEE single, h2 IEEE double
+data4 0x00008000,0x3F800000,0x00000000,0x00000000
+data4 0x00000000,0x00000000,0x00000000,0x00000000
+data4 0x00007F81,0x3F7F00F8,0x3B7F875D,0x00000000
+data4 0x211398BF,0xAD08B116,0x00003FDB,0x00000000
+data4 0x00007F02,0x3F7E03F8,0x3BFF015B,0x00000000
+data4 0xC376958E,0xB106790F,0x00003FDE,0x00000000
+data4 0x00007E85,0x3F7D08E0,0x3C3EE393,0x00000000
+data4 0x79A7679A,0xFD03F242,0x0000BFDA,0x00000000
+data4 0x00007E08,0x3F7C0FC0,0x3C7E0586,0x00000000
+data4 0x05E7AE08,0xF03F81C3,0x0000BFDF,0x00000000
+data4 0x00007D8D,0x3F7B1880,0x3C9E75D2,0x00000000
+data4 0x049EB22F,0xD1B87D3C,0x00003FDE,0x00000000
+data4 0x00007D12,0x3F7A2328,0x3CBDC97A,0x00000000
+data4 0x3A9E81E0,0xFABC8B95,0x00003FDF,0x00000000
+data4 0x00007C98,0x3F792FB0,0x3CDCFE47,0x00000000
+data4 0x7C4B5443,0xF5F3653F,0x00003FDF,0x00000000
+data4 0x00007C20,0x3F783E08,0x3CFC15D0,0x00000000
+data4 0xF65A1773,0xE78AB204,0x00003FE0,0x00000000
+data4 0x00007BA8,0x3F774E38,0x3D0D874D,0x00000000
+data4 0x7B8EF695,0xDB7CBFFF,0x0000BFE0,0x00000000
+data4 0x00007B31,0x3F766038,0x3D1CF49B,0x00000000
+data4 0xCF773FB3,0xC0241AEA,0x0000BFE0,0x00000000
+data4 0x00007ABB,0x3F757400,0x3D2C531D,0x00000000
+data4 0xC9539FDF,0xFC8F4D48,0x00003FE1,0x00000000
+data4 0x00007A45,0x3F748988,0x3D3BA322,0x00000000
+data4 0x954665C2,0x9CD035FB,0x0000BFE1,0x00000000
+data4 0x000079D1,0x3F73A0D0,0x3D4AE46F,0x00000000
+data4 0xDD367A30,0xEC9017C7,0x00003FE1,0x00000000
+data4 0x0000795D,0x3F72B9D0,0x3D5A1756,0x00000000
+data4 0xCB11189C,0xEE6625D3,0x0000BFE1,0x00000000
+data4 0x000078EB,0x3F71D488,0x3D693B9D,0x00000000
+data4 0xBE11C424,0xA49C8DB5,0x0000BFE0,0x00000000
+LOCAL_OBJECT_END(Constants_log_80_Z_G_H_h2)
+
+LOCAL_OBJECT_START(Constants_log_80_h3_G_H)
+// h3 IEEE double extended, H3 and G3 IEEE single
+data4 0x112666B0,0xAAACAAB1,0x00003FD3,0x3F7FFC00
+data4 0x9B7FAD21,0x90051030,0x00003FD8,0x3F7FF400
+data4 0xF4D783C4,0xA6B46F46,0x00003FDA,0x3F7FEC00
+data4 0x11C6DDCA,0xDA148D88,0x0000BFD8,0x3F7FE400
+data4 0xCA964D95,0xCE65C1D8,0x0000BFD8,0x3F7FDC00
+data4 0x23412D13,0x883838EE,0x0000BFDB,0x3F7FD400
+data4 0x983ED687,0xB7E5CFA1,0x00003FDB,0x3F7FCC08
+data4 0xE3C3930B,0xDBE23B16,0x0000BFD9,0x3F7FC408
+data4 0x48AA4DFC,0x9B92F1FC,0x0000BFDC,0x3F7FBC10
+data4 0xCE9C8F7E,0x9A8CEB15,0x0000BFD9,0x3F7FB410
+data4 0x0DECE74A,0x8C220879,0x00003FDC,0x3F7FAC18
+data4 0x2F053150,0xB25CA912,0x0000BFDA,0x3F7FA420
+data4 0xD9A5BE20,0xA5876555,0x00003FDB,0x3F7F9C20
+data4 0x2053F087,0xC919BB6E,0x00003FD9,0x3F7F9428
+data4 0x041E9A77,0xB70BDA79,0x00003FDC,0x3F7F8C30
+data4 0xEA1C9C30,0xF18A5C08,0x00003FDA,0x3F7F8438
+data4 0x796D89E5,0xA3790D84,0x0000BFDD,0x3F7F7C40
+data4 0xA2915A3A,0xE1852369,0x0000BFDD,0x3F7F7448
+data4 0xA39ED868,0xD803858F,0x00003FDC,0x3F7F6C50
+data4 0x9417EBB7,0xB2EEE356,0x0000BFDD,0x3F7F6458
+data4 0x9BB0D07F,0xED5C1F8A,0x0000BFDC,0x3F7F5C68
+data4 0xE87C740A,0xD6D201A0,0x0000BFDD,0x3F7F5470
+data4 0x1CA74025,0xE8DEBF5E,0x00003FDC,0x3F7F4C78
+data4 0x1F34A7EB,0x9A995A97,0x0000BFDC,0x3F7F4488
+data4 0x359EED97,0x9CB0F742,0x0000BFDA,0x3F7F3C90
+data4 0xBBC6A1C8,0xD6F833C2,0x0000BFDD,0x3F7F34A0
+data4 0xE71090EC,0xE1F68F2A,0x00003FDC,0x3F7F2CA8
+data4 0xC160A74F,0xD1881CF1,0x0000BFDB,0x3F7F24B8
+data4 0xD78CB5A4,0x9AD05AE2,0x00003FD6,0x3F7F1CC8
+data4 0x9A77DC4B,0xE658CB8E,0x0000BFDD,0x3F7F14D8
+data4 0x6BD6D312,0xBA281296,0x00003FDC,0x3F7F0CE0
+data4 0xF95210D0,0xB478BBEB,0x0000BFDB,0x3F7F04F0
+data4 0x38800100,0x39400480,0x39A00640,0x39E00C41 // H's start here
+data4 0x3A100A21,0x3A300F22,0x3A4FF51C,0x3A6FFC1D
+data4 0x3A87F20B,0x3A97F68B,0x3AA7EB86,0x3AB7E101
+data4 0x3AC7E701,0x3AD7DD7B,0x3AE7D474,0x3AF7CBED
+data4 0x3B03E1F3,0x3B0BDE2F,0x3B13DAAA,0x3B1BD766
+data4 0x3B23CC5C,0x3B2BC997,0x3B33C711,0x3B3BBCC6
+data4 0x3B43BAC0,0x3B4BB0F4,0x3B53AF6D,0x3B5BA620
+data4 0x3B639D12,0x3B6B9444,0x3B7393BC,0x3B7B8B6D
+LOCAL_OBJECT_END(Constants_log_80_h3_G_H)
+
+GR_sig_inv_ln2 = r14
+GR_rshf_2to51 = r15
+GR_exp_2tom51 = r16
+GR_rshf = r17
+GR_exp_half = r18
+GR_sign_mask = r19
+GR_exp_square_oflow = r20
+GR_exp_square_uflow = r21
+GR_exp_ynear1_oflow = r22
+GR_exp_ynear1_uflow = r23
+GR_signif_Z = r24
+
+GR_signexp_x = r32
+
+GR_exp_x = r33
+
+GR_Table_Ptr = r34
+
+GR_Table_Ptr1 = r35
+
+GR_Index1 = r36
+
+GR_Index2 = r37
+GR_Expo_X = r37
+
+GR_M = r38
+
+GR_X_0 = r39
+GR_Mask = r39
+
+GR_X_1 = r40
+GR_W1_ptr = r40
+
+GR_W2_ptr = r41
+GR_X_2 = r41
+
+GR_Z_1 = r42
+GR_M2 = r42
+
+GR_M1 = r43
+GR_Z_2 = r43
+
+GR_N = r44
+GR_k = r44
+
+GR_Big_Pos_Exp = r45
+
+GR_exp_pos_max = r46
+
+GR_exp_bias_p_k = r47
+
+GR_Index3 = r48
+GR_temp = r48
+
+GR_vsm_expo = r49
+
+GR_T1_ptr = r50
+GR_P_ptr1 = r50
+GR_T2_ptr = r51
+GR_P_ptr2 = r51
+GR_N_fix = r52
+GR_exp_y = r53
+GR_signif_y = r54
+GR_signexp_y = r55
+GR_fraction_y = r55
+GR_low_order_bit = r56
+GR_exp_mask = r57
+GR_exp_bias = r58
+GR_y_sign = r59
+GR_table_base = r60
+GR_ptr_exp_Arg = r61
+GR_Delta_Exp = r62
+GR_Special_Exp = r63
+GR_exp_neg_max = r64
+GR_Big_Neg_Exp = r65
+
+//** Registers for unwind support
+
+GR_SAVE_PFS = r59
+GR_SAVE_B0 = r60
+GR_SAVE_GP = r61
+GR_Parameter_X = r62
+GR_Parameter_Y = r63
+GR_Parameter_RESULT = r64
+GR_Parameter_TAG = r65
+
+//**
+
+FR_Input_X = f8
+FR_Result = f8
+FR_Input_Y = f9
+
+FR_Neg = f10
+FR_P_hi = f10
+FR_X = f10
+
+FR_Half = f11
+FR_h_3 = f11
+FR_poly_hi = f11
+
+FR_Sgn = f12
+
+FR_half_W = f13
+
+FR_X_cor = f14
+FR_P_lo = f14
+
+FR_W = f15
+
+FR_X_lo = f32
+
+FR_S = f33
+FR_W3 = f33
+
+FR_Y_hi = f34
+FR_logx_hi = f34
+
+FR_Z = f35
+FR_logx_lo = f35
+FR_GS_hi = f35
+FR_Y_lo = f35
+
+FR_r_cor = f36
+FR_Scale = f36
+
+FR_G_1 = f37
+FR_G = f37
+FR_Wsq = f37
+FR_temp = f37
+
+FR_H_1 = f38
+FR_H = f38
+FR_W4 = f38
+
+FR_h = f39
+FR_h_1 = f39
+FR_N = f39
+FR_P_7 = f39
+
+FR_G_2 = f40
+FR_P_8 = f40
+FR_L_hi = f40
+
+FR_H_2 = f41
+FR_L_lo = f41
+FR_A_1 = f41
+
+FR_h_2 = f42
+
+FR_W1 = f43
+
+FR_G_3 = f44
+FR_P_8 = f44
+FR_T1 = f44
+
+FR_log2_hi = f45
+FR_W2 = f45
+
+FR_GS_lo = f46
+FR_T2 = f46
+
+FR_W_1_p1 = f47
+FR_H_3 = f47
+
+FR_float_N = f48
+
+FR_A_2 = f49
+
+FR_Q_4 = f50
+FR_r4 = f50
+
+FR_Q_3 = f51
+FR_A_3 = f51
+
+FR_Q_2 = f52
+FR_P_2 = f52
+
+FR_Q_1 = f53
+FR_P_1 = f53
+FR_T = f53
+
+FR_Wp1 = f54
+FR_Q_5 = f54
+FR_P_3 = f54
+
+FR_Q_6 = f55
+
+FR_log2_lo = f56
+FR_Two = f56
+
+FR_Big = f57
+
+FR_neg_2_mK = f58
+
+FR_r = f59
+
+FR_poly_lo = f60
+
+FR_poly = f61
+
+FR_P_5 = f62
+FR_Result_small = f62
+
+FR_rsq = f63
+
+FR_Delta = f64
+
+FR_save_Input_X = f65
+FR_norm_X = f66
+FR_norm_Y = f67
+FR_Y_lo_2 = f68
+
+FR_P_6 = f69
+FR_Result_big = f69
+
+FR_RSHF_2TO51 = f70
+FR_INV_LN2_2TO63 = f71
+FR_2TOM51 = f72
+FR_RSHF = f73
+FR_TMP1 = f74
+FR_TMP2 = f75
+FR_TMP3 = f76
+FR_Tscale = f77
+FR_P_4 = f78
+FR_NBig = f79
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(powl)
+//
+// Get significand of x. It is the critical path.
+//
+{ .mfi
+ getf.sig GR_signif_Z = FR_Input_X // Get significand of x
+ fclass.m p11, p12 = FR_Input_X, 0x0b // Test x unorm
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnorm.s1 FR_norm_X = FR_Input_X // Normalize x
+ mov GR_exp_half = 0xffff - 1 // Exponent for 0.5
+}
+;;
+
+{ .mfi
+ alloc r32 = ar.pfs,0,30,4,0
+ fclass.m p7, p0 = FR_Input_Y, 0x1E7 // Test y natval, nan, inf, zero
+ mov GR_exp_pos_max = 0x13fff // Max exponent for pos oflow test
+}
+{ .mfi
+ addl GR_table_base = @ltoff(Constants_exp_64_Arg#), gp // Ptr to tables
+ fnorm.s1 FR_norm_Y = FR_Input_Y // Normalize y
+ mov GR_exp_neg_max = 0x33fff // Max exponent for neg oflow test
+}
+;;
+
+{ .mfi
+ getf.exp GR_signexp_y = FR_Input_Y // Get sign and exp of y
+(p12) fclass.m p11, p0 = FR_Input_Y, 0x0b // Test y unorm
+ mov GR_sign_mask = 0x20000 // Sign mask
+}
+{ .mfi
+ ld8 GR_table_base = [GR_table_base] // Get base address for tables
+ fadd.s1 FR_Two = f1, f1 // Form 2.0 for square test
+ mov GR_exp_mask = 0x1FFFF // Exponent mask
+}
+;;
+
+{ .mfi
+ getf.sig GR_signif_y = FR_Input_Y // Get significand of y
+ fclass.m p6, p0 = FR_Input_X, 0x1E7 // Test x natval, nan, inf, zero
+ nop.i 999
+}
+;;
+
+{ .mfi
+ getf.exp GR_signexp_x = FR_Input_X // Get signexp of x
+ fmerge.s FR_save_Input_X = FR_Input_X, FR_Input_X
+ extr.u GR_Index1 = GR_signif_Z, 59, 4 // Extract upper 4 signif bits of x
+}
+{ .mfb
+ setf.exp FR_Half = GR_exp_half // Load half
+ nop.f 999
+(p11) br.cond.spnt POWL_DENORM // Branch if x or y denorm/unorm
+}
+;;
+
+// Return here from POWL_DENORM
+POWL_COMMON:
+{ .mfi
+ setf.exp FR_Big = GR_exp_pos_max // Form big pos value for oflow test
+ fclass.nm p11, p0 = FR_Input_Y, 0x1FF // Test Y unsupported
+ shl GR_Index1 = GR_Index1,5 // Adjust index1 pointer x 32
+}
+{ .mfi
+ add GR_Table_Ptr = 0x7c0, GR_table_base // Constants_log_80_Z_G_H_h1
+ fma.s1 FR_Sgn = f1,f1,f0 // Assume result positive
+ mov GR_exp_bias = 0xFFFF // Form exponent bias
+}
+;;
+
+//
+// Identify NatVals, NaNs, Infs, and Zeros.
+//
+//
+// Remove sign bit from exponent of y.
+// Check for x = 1
+// Branch on Infs, Nans, Zeros, and Natvals
+// Check to see that exponent < 0
+//
+{ .mfi
+ setf.exp FR_NBig = GR_exp_neg_max // Form big neg value for oflow test
+ fclass.nm p8, p0 = FR_Input_X, 0x1FF // Test X unsupported
+ and GR_exp_y = GR_exp_mask,GR_signexp_y // Get biased exponent of y
+}
+{ .mfb
+ add GR_Index1 = GR_Index1,GR_Table_Ptr
+ nop.f 999
+(p6) br.cond.spnt POWL_64_SPECIAL // Branch if x natval, nan, inf, zero
+}
+;;
+
+// load Z_1 from Index1
+
+// There is logic starting here to determine if y is an integer when x < 0.
+// If 0 < |y| < 1 then clearly y is not an integer.
+// If |y| > 1, then the significand of y is shifted left by the size of
+// the exponent of y. This preserves the lsb of the integer part + the
+// fractional bits. The lsb of the integer can be tested to determine if
+// the integer is even or odd. The fractional bits can be tested. If zero,
+// then y is an integer.
+//
+{ .mfi
+ ld2 GR_Z_1 =[GR_Index1],4 // Load Z_1
+ fmerge.s FR_Z = f0, FR_norm_X // Z = |x|
+ extr.u GR_X_0 = GR_signif_Z, 49, 15 // Extract X_0 from significand
+}
+{ .mfb
+ cmp.lt p9, p0 = GR_exp_y,GR_exp_bias // Test 0 < |y| < 1
+ nop.f 999
+(p7) br.cond.spnt POWL_64_SPECIAL // Branch if y natval, nan, inf, zero
+}
+;;
+
+{ .mfb
+ ldfs FR_G_1 = [GR_Index1],4 // Load G_1
+ fcmp.eq.s1 p10, p0 = FR_Input_Y, f1 // Test Y = +1.0
+(p8) br.cond.spnt POWL_64_UNSUPPORT // Branch if x unsupported
+}
+;;
+
+//
+// X_0 = High order 15 bit of Z
+//
+{ .mfb
+ ldfs FR_H_1 = [GR_Index1],8 // Load H_1
+(p9) fcmp.lt.unc.s1 p9, p0 = FR_Input_X, f0 // Test x<0, 0 <|y|<1
+(p11) br.cond.spnt POWL_64_UNSUPPORT // Branch if y unsupported
+}
+;;
+
+{ .mfi
+ ldfe FR_h_1 = [GR_Index1] // Load h_1
+ fcmp.eq.s1 p7, p0 = FR_Input_Y, FR_Two // Test y = 2.0
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15 // X_1 = X_0 * Z_1 (bits 15-30)
+ // Wait 4 cycles to use result
+}
+{ .mfi
+ add GR_Table_Ptr = 0x9c0, GR_table_base // Constants_log_80_Z_G_H_h2
+ nop.f 999
+ sub GR_exp_y = GR_exp_y,GR_exp_bias // Get true exponent of y
+}
+;;
+
+//
+// Branch for (x < 0) and Y not an integer.
+//
+{ .mfb
+ nop.m 999
+ fcmp.lt.s1 p6, p0 = FR_Input_X, f0 // Test x < 0
+(p9) br.cond.spnt POWL_64_XNEG // Branch if x < 0, 0 < |y| < 1
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.s1 p12, p0 = FR_Input_X, f1 // Test x=+1.0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fsub.s1 FR_W = FR_Z, f1 // W = Z - 1
+(p7) br.cond.spnt POWL_64_SQUARE // Branch if y=2
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p10) fmpy.s0 FR_Result = FR_Input_X, f1 // If y=+1.0, result=x
+(p6) shl GR_fraction_y= GR_signif_y,GR_exp_y // Get lsb of int + fraction
+ // Wait 4 cycles to use result
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p12) fma.s0 FR_Result = FR_Input_Y, f0, f1 // If x=1.0, result=1, chk denorm
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract index2
+}
+;;
+
+//
+// N = exponent of Z
+//
+{ .mib
+ getf.exp GR_N = FR_Z // Get exponent of Z (also x)
+ shl GR_Index2=GR_Index2,5 // Index2 x 32 bytes
+(p10) br.ret.spnt b0 // Exit if y=+1.0
+}
+;;
+
+{ .mib
+ add GR_Index2 = GR_Index2, GR_Table_Ptr // Pointer to table 2
+ nop.i 999
+(p12) br.ret.spnt b0 // Exit if x=+1.0
+}
+;;
+
+{ .mmi
+ ld2 GR_Z_2 =[GR_Index2],4 // Load Z_2
+;;
+ ldfs FR_G_2 = [GR_Index2],4 // Load G_2
+ nop.i 999
+}
+;;
+
+{ .mii
+ ldfs FR_H_2 = [GR_Index2],8 // Load H_2
+(p6) tbit.nz.unc p9, p0 = GR_fraction_y, 63 // Test x<0 and y odd integer
+ add GR_Table_Ptr = 0xbcc, GR_table_base // Constants_log_80_h3_G_H, G_3
+}
+;;
+
+//
+// For x < 0 and y odd integer,, set sign = -1.
+//
+{ .mfi
+ getf.exp GR_M = FR_W // Get signexp of W
+ nop.f 999
+ pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15 // X_2 = X_1 * Z_2 (bits 15-30)
+}
+{ .mfi
+ ldfe FR_h_2 = [GR_Index2] // Load h_2
+(p9) fnma.s1 FR_Sgn = f1, f1, f0 // If x<0, y odd int, result negative
+ sub GR_N = GR_N, GR_exp_bias // Get true exponent of x = N
+}
+;;
+
+{ .mfi
+ add GR_Table_Ptr1 = 0xdc0, GR_table_base // Ptr to H_3
+ fcmp.eq.s0 p11, p0 = FR_Input_Y, FR_Half // Test y=0.5, also set denorm
+(p6) shl GR_fraction_y= GR_fraction_y, 1 // Shift left 1 to get fraction
+}
+;;
+
+{ .mmb
+ setf.sig FR_float_N = GR_N
+(p6) cmp.ne.unc p8, p0 = GR_fraction_y, r0 // Test x<0 and y not integer
+(p8) br.cond.spnt POWL_64_XNEG // Branch if x<0 and y not int
+}
+;;
+
+//
+// Raise possible denormal operand exception for both X and Y.
+// Set pointers in case |x| near 1
+// Branch to embedded sqrt(x) if y=0.5
+//
+{ .mfi
+ add GR_P_ptr1 = 0x6b0, GR_table_base // Constants_log_80_P, P8, NEAR path
+ fcmp.eq.s0 p12, p0 = FR_Input_X, FR_Input_Y // Dummy to set denormal
+ add GR_P_ptr2 = 0x700, GR_table_base // Constants_log_80_P, P4, NEAR path
+}
+{ .mfb
+ cmp.eq p15, p14 = r0, r0 // Assume result safe (no over/under)
+ fsub.s1 FR_Delta = FR_Input_Y,f1 // Delta = y - 1.0
+(p11) br.cond.spnt POWL_64_SQRT // Branch if y=0.5
+}
+;;
+
+//
+// Computes ln( x ) to extra precision
+// Input FR 1: FR_X
+// Output FR 2: FR_Y_hi
+// Output FR 3: FR_Y_lo
+// Output PR 1: PR_Safe
+//
+{ .mfi
+ and GR_M = GR_exp_mask, GR_M // Mask to get exponent of W
+ nop.f 999
+ extr.u GR_Index3 = GR_X_2, 1, 5 // Get index3
+}
+;;
+
+{ .mmi
+ shladd GR_Table_Ptr1 = GR_Index3,2,GR_Table_Ptr1 // Ptr to H_3
+ shladd GR_Index3 = GR_Index3,4,GR_Table_Ptr // Ptr to G_3
+ sub GR_M = GR_M, GR_exp_bias // Get true exponent of W
+}
+;;
+
+{ .mib
+ ldfs FR_G_3 = [GR_Index3],-12 // Load G_3
+ cmp.gt p7, p14 = -8, GR_M // Test if |x-1| < 2^-8
+(p7) br.cond.spnt LOGL80_NEAR // Branch if |x-1| < 2^-8
+}
+;;
+
+// Here if |x-1| >= 2^-8
+{ .mmf
+ ldfs FR_H_3 = [GR_Table_Ptr1] // Load H_3
+ nop.m 999
+ nop.f 999
+}
+;;
+
+{ .mfi
+ ldfe FR_h_3 = [GR_Index3] // Load h_3
+ fmerge.se FR_S = f1,FR_Z // S = merge of 1.0 and signif(Z)
+ nop.i 999
+}
+{ .mfi
+ add GR_Table_Ptr = 0x740, GR_table_base // Constants_log_80_Q
+ fmpy.s1 FR_G = FR_G_1, FR_G_2 // G = G_1 * G_2
+ nop.i 999
+}
+;;
+
+//
+// Begin Loading Q's - load log2_hi part
+//
+{ .mfi
+ ldfe FR_log2_hi = [GR_Table_Ptr],16 // Load log2_hi
+ fadd.s1 FR_H = FR_H_1, FR_H_2 // H = H_1 + H_2
+ nop.i 999
+};;
+
+//
+// h = h_1 + h_2
+//
+{ .mfi
+ ldfe FR_log2_lo = [GR_Table_Ptr],16 // Load log2_lo
+ fadd.s1 FR_h = FR_h_1, FR_h_2 // h = h_1 + h_2
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe FR_Q_6 = [GR_Table_Ptr],16 // Load Q_6
+ fcvt.xf FR_float_N = FR_float_N
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe FR_Q_5 = [GR_Table_Ptr],16 // Load Q_5
+ nop.f 999
+ nop.i 999
+}
+;;
+
+//
+// G = G_1 * G_2 * G_3
+//
+{ .mfi
+ ldfe FR_Q_4 = [GR_Table_Ptr],16 // Load Q_4
+ fmpy.s1 FR_G = FR_G, FR_G_3
+ nop.i 999
+}
+;;
+
+//
+// H = H_1 + H_2 + H_3
+//
+{ .mfi
+ ldfe FR_Q_3 = [GR_Table_Ptr],16 // Load Q_3
+ fadd.s1 FR_H = FR_H, FR_H_3
+ nop.i 999
+}
+;;
+
+//
+// Y_lo = poly + Y_lo
+//
+// h = h_1 + h_2 + h_3
+//
+{ .mfi
+ ldfe FR_Q_2 = [GR_Table_Ptr],16 // Load Q_2
+ fadd.s1 FR_h = FR_h, FR_h_3
+ nop.i 999
+}
+;;
+
+//
+// GS_hi = G*S
+// r = G*S -1
+//
+{ .mfi
+ ldfe FR_Q_1 = [GR_Table_Ptr],16 // Load Q_1
+ fmpy.s1 FR_GS_hi = FR_G, FR_S
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fms.s1 FR_r = FR_G, FR_S, f1
+ nop.i 999
+}
+;;
+
+//
+// poly_lo = Q_5 + r * Q_6
+//
+{ .mfi
+ getf.exp GR_Delta_Exp = FR_Delta // Get signexp of y-1 for exp calc
+ fma.s1 FR_poly_lo = FR_r, FR_Q_6, FR_Q_5
+ nop.i 999
+}
+//
+// r_cor = GS_hi -1
+//
+{ .mfi
+ nop.m 999
+ fsub.s1 FR_r_cor = FR_GS_hi, f1
+ nop.i 999
+}
+;;
+
+//
+// GS_lo = G*S - GS_hi
+//
+{ .mfi
+ nop.m 999
+ fms.s1 FR_GS_lo = FR_G, FR_S, FR_GS_hi
+ nop.i 999
+}
+;;
+
+//
+// rsq = r * r
+//
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_rsq = FR_r, FR_r
+ nop.i 999
+}
+//
+// G = float_N*log2_hi + H
+//
+{ .mfi
+ nop.m 999
+ fma.s1 FR_G = FR_float_N, FR_log2_hi, FR_H
+ nop.i 999
+}
+;;
+
+//
+// Y_lo = float_N*log2_lo + h
+//
+{ .mfi
+ nop.m 999
+ fma.s1 FR_Y_lo = FR_float_N, FR_log2_lo, FR_h
+ nop.i 999
+}
+;;
+
+//
+// poly_lo = Q_4 + r * poly_lo
+// r_cor = r_cor - r
+//
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly_lo = FR_r, FR_poly_lo, FR_Q_4
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fsub.s1 FR_r_cor = FR_r_cor, FR_r
+ nop.i 999
+}
+;;
+
+//
+// poly_hi = r * Q_2 + Q_1
+// Y_hi = G + r
+//
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_r, FR_Q_2, FR_Q_1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_Y_hi = FR_G, FR_r
+ nop.i 999
+}
+;;
+
+//
+// poly_lo = Q_3 + r * poly_lo
+// r_cor = r_cor + GS_lo
+//
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly_lo = FR_r, FR_poly_lo, FR_Q_3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_r_cor = FR_r_cor, FR_GS_lo
+ nop.i 999
+}
+;;
+
+//
+// Y_lo = G - Y_hi
+//
+{ .mfi
+ nop.m 999
+ fsub.s1 FR_Y_lo_2 = FR_G, FR_Y_hi
+ nop.i 999
+}
+;;
+
+//
+// r_cor = r_cor + Y_lo
+// poly = poly_hi + rsq * poly_lo
+//
+{ .mfi
+ add GR_Table_Ptr = 0x0, GR_table_base // Constants_exp_64_Arg
+ fadd.s1 FR_r_cor = FR_r_cor, FR_Y_lo
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_rsq, FR_poly_lo, FR_poly
+ nop.i 999
+}
+;;
+
+//
+// Load L_hi
+// Load L_lo
+// all long before they are needed.
+// They are used in LOGL_RETURN PATH
+//
+// Y_lo = Y_lo + r
+// poly = rsq * poly + r_cor
+//
+{ .mfi
+ ldfe FR_L_hi = [GR_Table_Ptr],16 // Load L_hi
+ fadd.s1 FR_Y_lo = FR_Y_lo_2, FR_r
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_rsq, FR_poly, FR_r_cor
+ nop.i 999
+}
+;;
+
+{ .mfb
+ ldfe FR_L_lo = [GR_Table_Ptr],16 // Load L_lo
+ fadd.s1 FR_Y_lo = FR_Y_lo, FR_poly
+ br.cond.sptk LOGL_RETURN // Branch to common code
+}
+;;
+
+
+LOGL80_NEAR:
+// Here if |x-1| < 2^-8
+//
+// Branch LOGL80_NEAR
+//
+
+{ .mmf
+ ldfe FR_P_8 = [GR_P_ptr1],16 // Load P_8
+ ldfe FR_P_4 = [GR_P_ptr2],16 // Load P_4
+ fmpy.s1 FR_Wsq = FR_W, FR_W
+}
+;;
+
+{ .mmi
+ ldfe FR_P_7 = [GR_P_ptr1],16 // Load P_7
+ ldfe FR_P_3 = [GR_P_ptr2],16 // Load P_3
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ldfe FR_P_6 = [GR_P_ptr1],16 // Load P_6
+ ldfe FR_P_2 = [GR_P_ptr2],16 // Load P_2
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ldfe FR_P_5 = [GR_P_ptr1],16 // Load P_5
+ ldfe FR_P_1 = [GR_P_ptr2],16 // Load P_1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ getf.exp GR_Delta_Exp = FR_Delta // Get signexp of y-1 for exp calc
+ fmpy.s1 FR_W4 = FR_Wsq, FR_Wsq
+ nop.i 999
+}
+{ .mfi
+ add GR_Table_Ptr = 0x0, GR_table_base // Constants_exp_64_Arg
+ fmpy.s1 FR_W3 = FR_Wsq, FR_W
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_half_W = FR_Half, FR_W
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe FR_L_hi = [GR_Table_Ptr],16
+ fma.s1 FR_poly_lo = FR_W, FR_P_8,FR_P_7
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_W, FR_P_4, FR_P_3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe FR_L_lo = [GR_Table_Ptr],16
+ fnma.s1 FR_Y_hi = FR_W, FR_half_W, FR_W
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly_lo = FR_W, FR_poly_lo, FR_P_6
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_W, FR_poly, FR_P_2
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fsub.s1 FR_Y_lo = FR_W, FR_Y_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly_lo = FR_W, FR_poly_lo, FR_P_5
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_W, FR_poly, FR_P_1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fnma.s1 FR_Y_lo = FR_W, FR_half_W, FR_Y_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_poly_lo, FR_W4, FR_poly
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_Y_lo = FR_poly, FR_W3, FR_Y_lo
+ nop.i 999
+}
+;;
+
+
+LOGL_RETURN:
+// Common code for completion of both logx paths
+
+//
+// L_hi, L_lo already loaded.
+//
+//
+// kernel_log_80 computed ln(X)
+// and return logX_hi and logX_lo as results.
+// PR_pow_Safe set as well.
+//
+//
+// Compute Y * (logX_hi + logX_lo)
+// P_hi -> X
+// P_lo -> X_cor
+// (Manipulate names so that inputs are in
+// the place kernel_exp expects them)
+//
+// This function computes exp( x + x_cor)
+// Input FR 1: FR_X
+// Input FR 2: FR_X_cor
+// Output FR 3: FR_Y_hi
+// Output FR 4: FR_Y_lo
+// Output FR 5: FR_Scale
+// Output PR 1: PR_Safe
+//
+// P15 is True
+//
+// Load constants used in computing N using right-shift technique
+{ .mlx
+ mov GR_exp_2tom51 = 0xffff-51
+ movl GR_sig_inv_ln2 = 0xb8aa3b295c17f0bc // significand of 1/ln2
+}
+{ .mlx
+ add GR_Special_Exp = -50,GR_exp_bias
+ movl GR_rshf_2to51 = 0x4718000000000000 // 1.10000 2^(63+51)
+}
+;;
+
+//
+// Point to Table of W1s
+// Point to Table of W2s
+//
+{ .mmi
+ add GR_W1_ptr = 0x2b0, GR_table_base // Constants_exp_64_W1
+ add GR_W2_ptr = 0x4b0, GR_table_base // Constants_exp_64_W2
+ cmp.le p6,p0= GR_Delta_Exp,GR_Special_Exp
+};;
+
+// Form two constants we need
+// 1/ln2 * 2^63 to compute w = x * 1/ln2 * 128
+// 1.1000..000 * 2^(63+63-12) to right shift int(N) into the significand
+
+{ .mfi
+ setf.sig FR_INV_LN2_2TO63 = GR_sig_inv_ln2 // form 1/ln2 * 2^63
+ nop.f 999
+ and GR_Delta_Exp=GR_Delta_Exp,GR_exp_mask // Get exponent of y-1
+}
+{ .mlx
+ setf.d FR_RSHF_2TO51 = GR_rshf_2to51 // Form const 1.1000 * 2^(63+51)
+ movl GR_rshf = 0x43e8000000000000 // 1.10000 2^63 for right shift
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_X_lo = FR_Input_Y, FR_logx_lo // logx_lo is Y_lo
+ cmp.eq p15, p0= r0, r0 // Set p15, assume safe
+};;
+
+{ .mmi
+ setf.exp FR_2TOM51 = GR_exp_2tom51 // Form 2^-51 for scaling float_N
+ setf.d FR_RSHF = GR_rshf // Form right shift const 1.1000 * 2^63
+ add GR_Table_Ptr1 = 0x50, GR_table_base // Constants_exp_64_P for
+ // EXPL_SMALL path
+}
+;;
+
+{ .mmi
+ ldfe FR_P_6 = [GR_Table_Ptr1],16 // Load P_6 for EXPL_SMALL path
+;;
+ ldfe FR_P_5 = [GR_Table_Ptr1],16 // Load P_5 for EXPL_SMALL path
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe FR_P_4 = [GR_Table_Ptr1],16 // Load P_4 for EXPL_SMALL path
+ fma.s1 FR_P_hi = FR_Input_Y, FR_logx_hi,FR_X_lo // logx_hi ix Y_hi
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ldfe FR_P_3 = [GR_Table_Ptr1],16 // Load P_3 for EXPL_SMALL path
+;;
+ ldfe FR_P_2 = [GR_Table_Ptr1],16 // Load P_2 for EXPL_SMALL path
+ nop.i 999
+}
+;;
+
+// N = X * Inv_log2_by_2^12
+// By adding 1.10...0*2^63 we shift and get round_int(N_signif) in significand.
+// We actually add 1.10...0*2^51 to X * Inv_log2 to do the same thing.
+{ .mfi
+ ldfe FR_P_1 = [GR_Table_Ptr1] // Load P_1 for EXPL_SMALL path
+ fma.s1 FR_N = FR_X, FR_INV_LN2_2TO63, FR_RSHF_2TO51
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fms.s1 FR_P_lo= FR_Input_Y, FR_logx_hi, FR_P_hi // P_hi is X
+(p6) br.cond.spnt POWL_Y_ALMOST_1 // Branch if |y-1| < 2^-50
+}
+;;
+
+{ .mmi
+ getf.exp GR_Expo_X = FR_X
+ add GR_T1_ptr = 0x0b0, GR_table_base // Constants_exp_64_T1
+ add GR_T2_ptr = 0x1b0, GR_table_base // Constants_exp_64_T2
+}
+;;
+
+// float_N = round_int(N)
+// The signficand of N contains the rounded integer part of X * 2^12/ln2,
+// as a twos complement number in the lower bits (that is, it may be negative).
+// That twos complement number (called N) is put into GR_N_fix.
+
+// Since N is scaled by 2^51, it must be multiplied by 2^-51
+// before the shift constant 1.10000 * 2^63 is subtracted to yield float_N.
+// Thus, float_N contains the floating point version of N
+
+
+{ .mfi
+ add GR_Table_Ptr = 0x20, GR_table_base // Constants_exp_64_A
+ fms.s1 FR_float_N = FR_N, FR_2TOM51, FR_RSHF // Form float_N
+ nop.i 999
+}
+// Create low part of Y(ln(x)_hi + ln(x)_lo) as P_lo
+{ .mfi
+ mov GR_Big_Pos_Exp = 0x3ffe // 16382, largest safe exponent
+ fadd.s1 FR_P_lo = FR_P_lo, FR_X_lo
+ mov GR_Big_Neg_Exp = -0x3ffd // -16381 smallest safe exponent
+};;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_rsq = FR_X, FR_X // rsq = X*X for EXPL_SMALL path
+ mov GR_vsm_expo = -70 // Exponent for very small path
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly_lo = FR_P_6, FR_X, FR_P_5 // poly_lo for EXPL_SMALL path
+ add GR_temp = 0x1,r0 // For tiny signif if small path
+}
+;;
+
+//
+// If expo_X < -6 goto exp_small
+//
+{ .mmi
+ getf.sig GR_N_fix = FR_N
+ ldfe FR_A_3 = [GR_Table_Ptr],16 // Load A_3
+ and GR_Expo_X = GR_Expo_X, GR_exp_mask // Get exponent of X
+}
+;;
+
+{ .mfi
+ ldfe FR_A_2 = [GR_Table_Ptr],16 // Load A_2
+ nop.f 999
+ sub GR_Expo_X = GR_Expo_X, GR_exp_bias // Get true exponent of X
+}
+;;
+
+//
+// If -6 > Expo_X, set P9 and branch
+//
+{ .mfb
+ cmp.gt p9, p0 = -6, GR_Expo_X
+ fnma.s1 FR_r = FR_L_hi, FR_float_N, FR_X // r = X - L_hi * float_N
+(p9) br.cond.spnt EXPL_SMALL // Branch if |X| < 2^-6
+}
+;;
+
+//
+// If 14 <= Expo_X, set P10
+//
+{ .mib
+ cmp.le p10, p0 = 14, GR_Expo_X
+ nop.i 999
+(p10) br.cond.spnt EXPL_HUGE // Branch if |X| >= 2^14
+}
+;;
+
+//
+// Load single T1
+// Load single T2
+// W_1_p1 = W_1 + 1
+//
+{ .mmi
+ nop.m 999
+ nop.m 999
+ extr.u GR_M1 = GR_N_fix, 6, 6 // Extract index M_1
+}
+;;
+
+//
+// k = extr.u(N_fix,0,6)
+//
+{ .mmi
+ shladd GR_W1_ptr = GR_M1,3,GR_W1_ptr // Point to W1
+ shladd GR_T1_ptr = GR_M1,2,GR_T1_ptr // Point to T1
+ extr.u GR_M2 = GR_N_fix, 0, 6 // Extract index M_2
+}
+;;
+
+// N_fix is only correct up to 50 bits because of our right shift technique.
+// Actually in the normal path we will have restricted K to about 14 bits.
+// Somewhat arbitrarily we extract 32 bits.
+{ .mmi
+ ldfd FR_W1 = [GR_W1_ptr]
+ shladd GR_W2_ptr = GR_M2,3,GR_W2_ptr // Point to W2
+ extr GR_k = GR_N_fix, 12, 32 // Extract k
+}
+;;
+
+{ .mfi
+ ldfs FR_T1 = [GR_T1_ptr]
+ fnma.s1 FR_r = FR_L_lo, FR_float_N, FR_r
+ shladd GR_T2_ptr = GR_M2,2,GR_T2_ptr // Point to T2
+}
+{ .mfi
+ add GR_exp_bias_p_k = GR_exp_bias, GR_k
+ nop.f 999
+ cmp.gt p14,p15 = GR_k,GR_Big_Pos_Exp
+}
+;;
+
+//
+// if k < big_neg_exp, set p14 and Safe=False
+//
+{ .mmi
+ ldfs FR_T2 = [GR_T2_ptr]
+(p15) cmp.lt p14,p15 = GR_k,GR_Big_Neg_Exp
+ nop.i 999
+}
+;;
+
+{ .mmi
+ setf.exp FR_Scale = GR_exp_bias_p_k
+ ldfd FR_W2 = [GR_W2_ptr]
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe FR_A_1 = [GR_Table_Ptr],16
+ fadd.s1 FR_r = FR_r, FR_X_cor
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_W_1_p1 = FR_W1, f1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_r, FR_A_3, FR_A_2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_rsq = FR_r, FR_r
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_T = FR_T1, FR_T2
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_W = FR_W2, FR_W_1_p1, FR_W1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_TMP1 = FR_Scale, FR_Sgn, f0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_r, FR_poly, FR_A_1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_TMP2 = FR_T, f1, f0 // TMP2 = Y_hi = T
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_Wp1 = FR_W, f1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_rsq, FR_poly,FR_r
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_Tscale = FR_T, FR_TMP1, f0 // Scale * Sgn * T
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_Y_lo = FR_Wp1, FR_poly, FR_W
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+ fmpy.s1 FR_TMP3 = FR_Y_lo, FR_Tscale
+ br.cond.sptk POWL_64_SHARED
+}
+;;
+
+
+EXPL_SMALL:
+// Here if |ylogx| < 2^-6
+//
+// Begin creating lsb to perturb final result
+//
+{ .mfi
+ setf.sig FR_temp = GR_temp
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_X, FR_P_4
+ cmp.lt p12, p0 = GR_Expo_X, GR_vsm_expo // Test |ylogx| < 2^-70
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly_hi = FR_P_2, FR_X, FR_P_1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_TMP2 = f1, f1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_TMP1 = FR_Sgn, f1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_r4 = FR_rsq, FR_rsq
+(p12) cmp.eq p15, p0 = r0, r0 // Set safe if |ylogx| < 2^-70
+}
+{ .mfb
+ nop.m 999
+(p12) fmpy.s1 FR_TMP3 = FR_Sgn, FR_X
+(p12) br.cond.spnt POWL_64_SHARED // Branch if |ylogx| < 2^-70
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_X, FR_P_3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly_hi = FR_poly_hi, FR_rsq, FR_X
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_Y_lo = FR_poly_lo, FR_r4, FR_poly_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_TMP3 = FR_Y_lo, FR_TMP1 // Add sign info
+ nop.i 999
+}
+;;
+
+//
+// Toggle on last bit of Y_lo
+// Set lsb of Y_lo to 1
+//
+{ .mfi
+ nop.m 999
+ for FR_temp = FR_Y_lo,FR_temp
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+ fmerge.se FR_TMP3 = FR_TMP3,FR_temp
+ br.cond.sptk POWL_64_SHARED
+}
+;;
+
+
+EXPL_HUGE:
+// Here if |ylogx| >= 2^14
+{ .mfi
+ mov GR_temp = 0x0A1DC // If X < 0, exponent -24100
+ fcmp.gt.s1 p12, p13 = FR_X, f0 // Test X > 0
+ cmp.eq p14, p15 = r0, r0 // Set Safe to false
+}
+;;
+
+{ .mmi
+(p12) mov GR_Mask = 0x15DC0 // If X > 0, exponent +24000
+(p13) mov GR_Mask = 0x0A240 // If X < 0, exponent -24000
+ nop.i 999
+}
+;;
+
+{ .mmf
+ setf.exp FR_TMP2 = GR_Mask // Form Y_hi = TMP2
+(p13) setf.exp FR_Y_lo = GR_temp // If X < 0, Y_lo = 2^-24100
+(p12) mov FR_Y_lo = f1 // IF X > 0, Y_lo = 1.0
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_TMP1 = FR_TMP2, FR_Sgn // TMP1 = Y_hi * Sgn
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+ fmpy.s1 FR_TMP3 = FR_Y_lo,FR_TMP1 // TMP3 = Y_lo * (Y_hi * Sgn)
+ br.cond.sptk POWL_64_SHARED
+}
+;;
+
+POWL_Y_ALMOST_1:
+// Here if delta = |y-1| < 2^-50
+//
+// x**(1 + delta) = x * e (ln(x)*delta) = x ( 1 + ln(x) * delta)
+//
+// Computation will be safe for 2^-16381 <= x < 2^16383
+
+{ .mfi
+ mov GR_exp_ynear1_oflow = 0xffff + 16383
+ fma.s1 FR_TMP1 = FR_Input_X,FR_Delta,f0
+ and GR_exp_x = GR_exp_mask, GR_signexp_x
+}
+;;
+
+{ .mfi
+ cmp.lt p15, p14 = GR_exp_x, GR_exp_ynear1_oflow
+ fma.s1 FR_TMP2 = FR_logx_hi,f1,FR_X_lo
+ mov GR_exp_ynear1_uflow = 0xffff - 16381
+}
+;;
+
+{ .mfb
+(p15) cmp.ge p15, p14 = GR_exp_x, GR_exp_ynear1_uflow
+ fma.s1 FR_TMP3 = FR_Input_X,f1,f0
+ br.cond.sptk POWL_64_SHARED
+};;
+
+POWL_64_SQUARE:
+//
+// Here if x not zero and y=2.
+//
+// Setup for multipath code
+//
+{ .mfi
+ mov GR_exp_square_oflow = 0xffff + 8192 // Exponent where x*x overflows
+ fmerge.se FR_TMP1 = FR_Input_X, FR_Input_X
+ and GR_exp_x = GR_exp_mask, GR_signexp_x // Get exponent of x
+}
+;;
+
+{ .mfi
+ cmp.lt p15, p14 = GR_exp_x, GR_exp_square_oflow // Decide safe/unsafe
+ fmerge.se FR_TMP2 = FR_Input_X, FR_Input_X
+ mov GR_exp_square_uflow = 0xffff - 8191 // Exponent where x*x underflows
+}
+;;
+
+{ .mfi
+(p15) cmp.ge p15, p14 = GR_exp_x, GR_exp_square_uflow // Decide safe/unsafe
+ fma.s1 FR_TMP3 = f0,f0,f0
+ nop.i 999
+}
+;;
+
+//
+// This is the shared path that will set overflow and underflow.
+//
+POWL_64_SHARED:
+
+//
+// Return if no danger of over or underflow.
+//
+{ .mfb
+ nop.m 999
+ fma.s0 FR_Result = FR_TMP1, FR_TMP2, FR_TMP3
+(p15) br.ret.sptk b0 // Main path return if certain no over/underflow
+}
+;;
+
+//
+// S0 user supplied status
+// S2 user supplied status + WRE + TD (Overflows)
+// S2 user supplied status + FZ + TD (Underflows)
+//
+//
+// If (Safe) is true, then
+// Compute result using user supplied status field.
+// No overflow or underflow here, but perhaps inexact.
+// Return
+// Else
+// Determine if overflow or underflow was raised.
+// Fetch +/- overflow threshold for IEEE double extended
+
+{ .mfi
+ nop.m 999
+ fsetc.s2 0x7F,0x41 // For underflow test, set S2=User+TD+FTZ
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s2 FR_Result_small = FR_TMP1, FR_TMP2, FR_TMP3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fsetc.s2 0x7F,0x42 // For overflow test, set S2=User+TD+WRE
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s2 FR_Result_big = FR_TMP1, FR_TMP2,FR_TMP3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fsetc.s2 0x7F,0x40 // Reset S2=User
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p11, p0 = FR_Result_small, 0x00F // Test small result unorm/zero
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcmp.ge.s1 p8, p0 = FR_Result_big , FR_Big // Test >= + oflow threshold
+ nop.i 999
+}
+;;
+
+{ .mfb
+(p11) mov GR_Parameter_TAG = 19 // Set tag for underflow
+ fcmp.le.s1 p9, p0 = FR_Result_big, FR_NBig // Test <= - oflow threshold
+(p11) br.cond.spnt __libm_error_region // Branch if pow underflowed
+}
+;;
+
+{ .mfb
+(p8) mov GR_Parameter_TAG = 18 // Set tag for overflow
+ nop.f 999
+(p8) br.cond.spnt __libm_error_region // Branch if pow +overflow
+}
+;;
+
+{ .mbb
+(p9) mov GR_Parameter_TAG = 18 // Set tag for overflow
+(p9) br.cond.spnt __libm_error_region // Branch if pow -overflow
+ br.ret.sptk b0 // Branch if result really ok
+}
+;;
+
+
+POWL_64_SPECIAL:
+// Here if x or y is NatVal, nan, inf, or zero
+{ .mfi
+ nop.m 999
+ fcmp.eq.s1 p15, p0 = FR_Input_X, f1 // Test x=+1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p8, p0 = FR_Input_X, 0x143 // Test x natval, snan
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p15) fcmp.eq.unc.s0 p6,p0 = FR_Input_Y, f0 // If x=1, flag invalid if y=SNaN
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p15) fmpy.s0 FR_Result = f1,f1 // If x=1, result=1
+(p15) br.ret.spnt b0 // Exit if x=1
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p6, p0 = FR_Input_Y, 0x007 // Test y zero
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p9, p0 = FR_Input_Y, 0x143 // Test y natval, snan
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p10, p0 = FR_Input_X, 0x083 // Test x qnan
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fmpy.s0 FR_Result = FR_Input_Y, FR_Input_X // If x=snan, result=qnan
+(p6) cmp.ne p8,p0 = r0,r0 // Don't exit if x=snan, y=0 ==> result=+1
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fclass.m.unc p15, p0 = FR_Input_X,0x007 // Test x=0, y=0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p9) fmpy.s0 FR_Result = FR_Input_Y, FR_Input_X // If y=snan, result=qnan
+(p8) br.ret.spnt b0 // Exit if x=snan, y not 0,
+ // result=qnan
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.s1 p7, p0 = FR_Input_Y, f1 // Test y +1.0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p10) fmpy.s0 FR_Result = FR_Input_X, f0 // If x=qnan, result=qnan
+(p9) br.ret.spnt b0 // Exit if y=snan, result=qnan
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fclass.m.unc p8, p0 = FR_Input_X,0x0C3 // Test x=nan, y=0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fcmp.eq.s0 p9,p0 = FR_Input_X, f0 // If y=0, flag if x denormal
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p6) fadd.s0 FR_Result = f1, f0 // If y=0, result=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p11, p0 = FR_Input_Y, 0x083 // Test y qnan
+ nop.i 999
+}
+{ .mfb
+(p15) mov GR_Parameter_TAG = 20 // Error tag for x=0, y=0
+(p7) fmpy.s0 FR_Result = FR_Input_X,f1 // If y=1, result=x
+(p15) br.cond.spnt __libm_error_region // Branch if x=0, y=0, result=1
+}
+;;
+
+{ .mfb
+(p8) mov GR_Parameter_TAG = 23 // Error tag for x=nan, y=0
+ fclass.m p14, p0 = FR_Input_Y, 0x023 // Test y inf
+(p8) br.cond.spnt __libm_error_region // Branch if x=snan, y=0,
+ // result=1
+}
+;;
+
+{ .mfb
+ nop.m 999
+ fclass.m p13, p0 = FR_Input_X, 0x023 // Test x inf
+(p6) br.ret.spnt b0 // Exit y=0, x not nan or 0,
+ // result=1
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p14) fcmp.eq.unc.s1 p0,p14 = FR_Input_X,f0 // Test x not 0, y=inf
+(p7) br.ret.spnt b0 // Exit y=1, x not snan,
+ // result=x
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p10) fmpy.s0 FR_Result = FR_Input_Y,FR_Input_X // If x=qnan, y not snan,
+ // result=qnan
+(p10) br.ret.spnt b0 // Exit x=qnan, y not snan,
+ // result=qnan
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p11) fmpy.s0 FR_Result = FR_Input_Y,FR_Input_X // If y=qnan, x not nan or 1,
+ // result=qnan
+(p11) br.ret.spnt b0 // Exit y=qnan, x not nan or 1,
+ // result=qnan
+}
+;;
+
+{ .mbb
+ nop.m 999
+(p14) br.cond.spnt POWL_64_Y_IS_INF // Branch if y=inf, x not 1 or nan
+(p13) br.cond.spnt POWL_64_X_IS_INF // Branch if x=inf, y not 1 or nan
+}
+;;
+
+
+POWL_64_X_IS_ZERO:
+// Here if x=0, y not nan or 1 or inf or 0
+
+// There is logic starting here to determine if y is an integer when x = 0.
+// If 0 < |y| < 1 then clearly y is not an integer.
+// If |y| > 1, then the significand of y is shifted left by the size of
+// the exponent of y. This preserves the lsb of the integer part + the
+// fractional bits. The lsb of the integer can be tested to determine if
+// the integer is even or odd. The fractional bits can be tested. If zero,
+// then y is an integer.
+//
+{ .mfi
+ and GR_exp_y = GR_exp_mask,GR_signexp_y // Get biased exponent of y
+ nop.f 999
+ and GR_y_sign = GR_sign_mask,GR_signexp_y // Get sign of y
+}
+;;
+
+//
+// Maybe y is < 1 already, so
+// can never be an integer.
+//
+{ .mfi
+ cmp.lt p9, p8 = GR_exp_y,GR_exp_bias // Test 0 < |y| < 1
+ nop.f 999
+ sub GR_exp_y = GR_exp_y,GR_exp_bias // Get true exponent of y
+}
+;;
+
+//
+// Shift significand of y looking for nonzero bits
+// For y > 1, shift signif_y exp_y bits to the left
+// For y < 1, turn on 4 low order bits of significand of y
+// so that the fraction will always be non-zero
+//
+{ .mmi
+(p9) or GR_exp_y= 0xF,GR_signif_y // Force nonzero fraction if y<1
+;;
+ nop.m 999
+(p8) shl GR_exp_y= GR_signif_y,GR_exp_y // Get lsb of int + fraction
+ // Wait 4 cycles to use result
+}
+;;
+
+{ .mmi
+ nop.m 999
+;;
+ nop.m 999
+ nop.i 999
+}
+;;
+
+{ .mmi
+ nop.m 999
+;;
+ nop.m 999
+ shl GR_fraction_y= GR_exp_y,1 // Shift left 1 to get fraction
+}
+;;
+
+//
+// Integer part of y shifted off.
+// Get y's low even or odd bit - y might not be an int.
+//
+{ .mii
+ cmp.eq p13,p0 = GR_fraction_y, r0 // Test for y integer
+ cmp.eq p8,p0 = GR_y_sign, r0 // Test for y > 0
+;;
+(p13) tbit.nz.unc p13,p0 = GR_exp_y, 63 // Test if y an odd integer
+}
+;;
+
+{ .mfi
+(p13) cmp.eq.unc p13,p14 = GR_y_sign, r0 // Test y pos odd integer
+(p8) fcmp.eq.s0 p12,p0 = FR_Input_Y, f0 // If x=0 and y>0 flag if y denormal
+ nop.i 999
+}
+;;
+
+//
+// Return +/-0 when x=+/-0 and y is positive odd integer
+//
+{ .mfb
+ nop.m 999
+(p13) mov FR_Result = FR_Input_X // If x=0, y pos odd int, result=x
+(p13) br.ret.spnt b0 // Exit x=0, y pos odd int, result=x
+}
+;;
+
+//
+// Return +/-inf when x=+/-0 and y is negative odd int
+//
+{ .mfb
+(p14) mov GR_Parameter_TAG = 21
+(p14) frcpa.s0 FR_Result, p0 = f1, FR_Input_X // Result +-inf, set Z flag
+(p14) br.cond.spnt __libm_error_region
+}
+;;
+
+//
+// Return +0 when x=+/-0 and y positive and not an odd integer
+//
+{ .mfb
+ nop.m 999
+(p8) mov FR_Result = f0 // If x=0, y>0 and not odd integer, result=+0
+(p8) br.ret.sptk b0 // Exit x=0, y>0 and not odd integer, result=+0
+}
+;;
+
+//
+// Return +inf when x=+/-0 and y is negative and not odd int
+//
+{ .mfb
+ mov GR_Parameter_TAG = 21
+ frcpa.s0 FR_Result, p10 = f1,f0 // Result +inf, raise Z flag
+ br.cond.sptk __libm_error_region
+}
+;;
+
+
+POWL_64_X_IS_INF:
+//
+// Here if x=inf, y not 1 or nan
+//
+{ .mfi
+ and GR_exp_y = GR_exp_mask,GR_signexp_y // Get biased exponent y
+ fclass.m p13, p0 = FR_Input_X,0x022 // Test x=-inf
+ nop.i 999
+}
+;;
+
+{ .mfi
+ and GR_y_sign = GR_sign_mask,GR_signexp_y // Get sign of y
+ fcmp.eq.s0 p9,p0 = FR_Input_Y, f0 // Dummy to set flag if y denorm
+ nop.i 999
+}
+;;
+
+//
+// Maybe y is < 1 already, so
+// isn't an int.
+//
+{ .mfi
+(p13) cmp.lt.unc p9, p8 = GR_exp_y,GR_exp_bias // Test 0 < |y| < 1 if x=-inf
+ fclass.m p11, p0 = FR_Input_X,0x021 // Test x=+inf
+ sub GR_exp_y = GR_exp_y,GR_exp_bias // Get true exponent y
+}
+;;
+
+//
+// Shift significand of y looking for nonzero bits
+// For y > 1, shift signif_y exp_y bits to the left
+// For y < 1, turn on 4 low order bits of significand of y
+// so that the fraction will always be non-zero
+//
+{ .mmi
+(p9) or GR_exp_y= 0xF,GR_signif_y // Force nonzero fraction if y<1
+;;
+(p11) cmp.eq.unc p14,p12 = GR_y_sign, r0 // Test x=+inf, y>0
+(p8) shl GR_exp_y= GR_signif_y,GR_exp_y // Get lsb of int + fraction
+ // Wait 4 cycles to use result
+}
+;;
+
+//
+// Return +inf for x=+inf, y > 0
+// Return +0 for x=+inf, y < 0
+//
+{ .mfi
+ nop.m 999
+(p12) mov FR_Result = f0 // If x=+inf, y<0, result=+0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p14) fma.s0 FR_Result = FR_Input_X,f1,f0 // If x=+inf, y>0, result=+inf
+(p11) br.ret.sptk b0 // Exit x=+inf
+}
+;;
+
+//
+// Here only if x=-inf. Wait until can use result of shl...
+//
+{ .mmi
+ nop.m 999
+;;
+ nop.m 999
+ nop.i 999
+}
+;;
+
+{ .mfi
+ cmp.eq p8,p9 = GR_y_sign, r0 // Test y pos
+ nop.f 999
+ shl GR_fraction_y = GR_exp_y,1 // Shift left 1 to get fraction
+}
+;;
+
+{ .mmi
+ cmp.eq p13,p0 = GR_fraction_y, r0 // Test y integer
+;;
+ nop.m 999
+(p13) tbit.nz.unc p13,p0 = GR_exp_y, 63 // Test y odd integer
+}
+;;
+
+//
+// Is y even or odd?
+//
+{ .mii
+(p13) cmp.eq.unc p14,p10 = GR_y_sign, r0 // Test x=-inf, y pos odd int
+(p13) cmp.ne.and p8,p9 = r0,r0 // If y odd int, turn off p8,p9
+ nop.i 999
+}
+;;
+
+//
+// Return -0 for x = -inf and y < 0 and odd int.
+// Return -Inf for x = -inf and y > 0 and odd int.
+//
+{ .mfi
+ nop.m 999
+(p10) fmerge.ns FR_Result = f0, f0 // If x=-inf, y neg odd int, result=-0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p14) fmpy.s0 FR_Result = FR_Input_X,f1 // If x=-inf, y pos odd int, result=-inf
+ nop.i 999
+}
+;;
+
+//
+// Return Inf for x = -inf and y > 0 not an odd int.
+// Return +0 for x = -inf and y < 0 not an odd int.
+//
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 999
+(p8) fmerge.ns FR_Result = FR_Input_X, FR_Input_X // If x=-inf, y>0 not odd int
+ // result=+inf
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p9) fmpy.s0 FR_Result = f0,f0 // If x=-inf, y<0 not odd int
+ // result=+0
+ br.ret.sptk b0 // Exit for x=-inf
+}
+;;
+
+
+POWL_64_Y_IS_INF:
+// Here if y=inf, x not 1 or nan
+//
+// For y = +Inf and |x| < 1 returns 0
+// For y = +Inf and |x| > 1 returns Inf
+// For y = -Inf and |x| < 1 returns Inf
+// For y = -Inf and |x| > 1 returns 0
+// For y = Inf and |x| = 1 returns 1
+//
+{ .mfi
+ nop.m 999
+ fclass.m p8, p0 = FR_Input_Y, 0x021 // Test y=+inf
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p9, p0 = FR_Input_Y, 0x022 // Test y=-inf
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fabs FR_X = FR_Input_X // Form |x|
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p10,p0 = FR_Input_X, f0 // flag if x denormal
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fcmp.lt.unc.s1 p6, p0 = FR_X, f1 // Test y=+inf, |x|<1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fcmp.gt.unc.s1 p7, p0 = FR_X, f1 // Test y=+inf, |x|>1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fcmp.lt.unc.s1 p12, p0 = FR_X, f1 // Test y=-inf, |x|<1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p6) fmpy.s0 FR_Result = f0,f0 // If y=+inf, |x|<1, result=+0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fcmp.gt.unc.s1 p13, p0 = FR_X, f1 // Test y=-inf, |x|>1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fmpy.s0 FR_Result = FR_Input_Y, f1 // If y=+inf, |x|>1, result=+inf
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.s1 p14, p0 = FR_X, f1 // Test y=inf, |x|=1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fnma.s0 FR_Result = FR_Input_Y, f1, f0 // If y=-inf, |x|<1, result=+inf
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p13) mov FR_Result = f0 // If y=-inf, |x|>1, result=+0
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p14) fmpy.s0 FR_Result = f1,f1 // If y=inf, |x|=1, result=+1
+ br.ret.sptk b0 // Common return for y=inf
+}
+;;
+
+
+// Here if x or y denorm/unorm
+POWL_DENORM:
+{ .mmi
+ getf.sig GR_signif_Z = FR_norm_X // Get significand of x
+;;
+ getf.exp GR_signexp_y = FR_norm_Y // Get sign and exp of y
+ nop.i 999
+}
+;;
+
+{ .mfi
+ getf.sig GR_signif_y = FR_norm_Y // Get significand of y
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mib
+ getf.exp GR_signexp_x = FR_norm_X // Get sign and exp of x
+ extr.u GR_Index1 = GR_signif_Z, 59, 4 // Extract upper 4 signif bits of x
+ br.cond.sptk POWL_COMMON // Branch back to main path
+}
+;;
+
+
+POWL_64_UNSUPPORT:
+//
+// Raise exceptions for specific
+// values - pseudo NaN and
+// infinities.
+// Return NaN and raise invalid
+//
+{ .mfb
+ nop.m 999
+ fmpy.s0 FR_Result = FR_Input_X,f0
+ br.ret.sptk b0
+}
+;;
+
+POWL_64_XNEG:
+//
+// Raise invalid for x < 0 and
+// y not an integer
+//
+{ .mfi
+ nop.m 999
+ frcpa.s0 FR_Result, p8 = f0, f0
+ mov GR_Parameter_TAG = 22
+}
+{ .mib
+ nop.m 999
+ nop.i 999
+ br.cond.sptk __libm_error_region
+}
+;;
+
+POWL_64_SQRT:
+{ .mfi
+ nop.m 999
+ frsqrta.s0 FR_Result,p10 = FR_save_Input_X
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 f62=FR_Half,FR_save_Input_X,f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 f63=FR_Result,FR_Result,f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fnma.s1 f32=f63,f62,FR_Half
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 f33=f32,FR_Result,FR_Result
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 f34=f33,f62,f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fnma.s1 f35=f34,f33,FR_Half
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 f63=f35,f33,f33
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 f32=FR_save_Input_X,f63,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_Result=f63,f62,f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 f33=f11,f63,f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fnma.s1 f34=f32,f32,FR_save_Input_X
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fnma.s1 f35=FR_Result,f63,FR_Half
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 f62=f33,f34,f32
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 f63=f33,f35,f33
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fnma.s1 f32=f62,f62,FR_save_Input_X
+ nop.i 999 ;;
+}
+{ .mfb
+ nop.m 999
+(p10) fma.s0 FR_Result=f32,f63,f62
+ br.ret.sptk b0 // Exit for x > 0, y = 0.5
+}
+;;
+
+GLOBAL_LIBM_END(powl)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Input_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_save_Input_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_Result // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region#)
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_rem_pio2.c b/libc/sysdeps/ia64/fpu/e_rem_pio2.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_rem_pio2.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/e_rem_pio2f.c b/libc/sysdeps/ia64/fpu/e_rem_pio2f.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_rem_pio2f.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/e_remainder.S b/libc/sysdeps/ia64/fpu/e_remainder.S
new file mode 100644
index 000000000..f655567f5
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_remainder.S
@@ -0,0 +1,590 @@
+.file "remainder.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//====================================================================
+// 02/02/00 Initial version
+// 03/02/00 New Algorithm
+// 04/04/00 Unwind support added
+// 07/21/00 Fixed quotient=2^{24*m+23}*1.q1...q23 1 bug
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 11/29/00 Set FR_Y to f9
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//====================================================================
+// double remainder(double,double);
+//
+// Overview of operation
+//====================================================================
+// remainder(a,b)=a-i*b,
+// where i is an integer such that, if b!=0 and a is finite,
+// |a/b-i|<=1/2. If |a/b-i|=1/2, i is even.
+//
+// Algorithm
+//====================================================================
+// a). eliminate special cases
+// b). if |a/b|<0.25 (first quotient estimate), return a
+// c). use single precision divide algorithm to get quotient q
+// rounded to 24 bits of precision
+// d). calculate partial remainders (using both q and q-ulp);
+// select one and RZ(a/b) based on the sign of |a|-|b|*q
+// e). if the exponent difference (exponent(a)-exponent(b))
+// is less than 24 (quotient estimate<2^{24}-2), use RZ(a/b)
+// and sticky bits to round to integer; exit loop and
+// calculate final remainder
+// f). if exponent(a)-exponent(b)>=24, select new value of a as
+// the partial remainder calculated using RZ(a/b);
+// repeat from c).
+//
+// Special cases
+//====================================================================
+// a=+/- Inf, or b=+/-0: return NaN, call libm_error_support
+// a=NaN or b=NaN: return NaN
+
+// Registers used
+//====================================================================
+// Predicate registers: p6-p14
+// General registers: r2,r3,r28,r29,r32 (ar.pfs), r33-r39
+// Floating point registers: f6-f15,f32
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+FR_X = f10
+FR_Y = f9
+FR_RESULT = f8
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(remainder)
+
+// inputs in f8, f9
+// result in f8
+
+{ .mfi
+ alloc r32=ar.pfs,1,4,4,0
+ // f13=|a|
+ fmerge.s f13=f0,f8
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // f14=|b|
+ fmerge.s f14=f0,f9
+ nop.i 0;;
+}
+ {.mlx
+ mov r28=0x2ffdd
+ // r2=2^{23}
+ movl r3=0x4b000000;;
+}
+
+// Y +-NAN, +-inf, +-0? p11
+{ .mfi
+ setf.exp f32=r28
+ fclass.m.unc p11,p0 = f9, 0xe7
+ nop.i 999
+}
+// qnan snan inf norm unorm 0 -+
+// 1 1 1 0 0 0 11
+// e 3
+// X +-NAN, +-inf, ? p9
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p0 = f8, 0xe3
+ nop.i 999;;
+}
+
+{.mfi
+ nop.m 0
+ mov f12=f0
+ nop.i 0
+}
+{ .mfi
+ // set p7=1
+ cmp.eq.unc p7,p0=r0,r0
+ // Step (1)
+ // y0 = 1 / b in f10
+ frcpa.s1 f10,p6=f13,f14
+ nop.i 0;;
+}
+
+{.bbb
+ (p9) br.cond.spnt FREM_X_NAN_INF
+ (p11) br.cond.spnt FREM_Y_NAN_INF_ZERO
+ nop.b 0
+} {.mfi
+ nop.m 0
+ // set D flag if a (f8) is denormal
+ fnma.s0 f6=f8,f1,f8
+ nop.i 0;;
+}
+
+
+remloop24:
+ { .mfi
+ nop.m 0
+ // Step (2)
+ // q0 = a * y0 in f12
+ (p6) fma.s1 f12=f13,f10,f0
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (3)
+ // e0 = 1 - b * y0 in f7
+ (p6) fnma.s1 f7=f14,f10,f1
+ nop.i 0;;
+} {.mlx
+ nop.m 0
+ // r2=1.25*2^{-24}
+ movl r2=0x33a00000;;
+}
+
+{.mfi
+ nop.m 0
+ // q1=q0*(1+e0)
+ (p6) fma.s1 f15=f12,f7,f12
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // Step (4)
+ // e1 = e0 * e0 + E in f7
+ (p6) fma.s1 f7=f7,f7,f32
+ nop.i 0;;
+}
+ {.mii
+ (p7) getf.exp r29=f12
+ (p7) mov r28=0xfffd
+ nop.i 0;;
+}
+ { .mfi
+ // f12=2^{23}
+ setf.s f12=r3
+ // Step (5)
+ // q2 = q1 + e1 * q1 in f11
+ (p6) fma.s.s1 f11=f7,f15,f15
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (6)
+ // q2 = q1 + e1 * q1 in f6
+ (p6) fma.s1 f6=f7,f15,f15
+ nop.i 0;;
+}
+
+ {.mmi
+ // f15=1.25*2^{-24}
+ setf.s f15=r2
+ // q<1/4 ? (i.e. expon< -2)
+ (p7) cmp.gt p7,p0=r28,r29
+ nop.i 0;;
+}
+
+{.mfb
+ // r29= -32+bias
+ mov r29=0xffdf
+ // if |a/b|<1/4, set D flag before returning
+ (p7) fma.d.s0 f9=f9,f0,f8
+ nop.b 0;;
+}
+ {.mfb
+ nop.m 0
+ // can be combined with bundle above if sign of 0 or
+ // FTZ enabled are not important
+ (p7) fmerge.s f8=f8,f9
+ // return if |a|<4*|b| (estimated quotient < 1/4)
+ (p7) br.ret.spnt b0;;
+}
+ {.mfi
+ // f7=2^{-32}
+ setf.exp f7=r29
+ // set f8 to current a value | sign
+ fmerge.s f8=f8,f13
+ nop.i 0;;
+}
+
+
+ {.mfi
+ getf.exp r28=f6
+ // last step ? (q<2^{23})
+ fcmp.lt.unc.s1 p0,p12=f6,f12
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // r=a-b*q
+ fnma.s1 f6=f14,f11,f13
+ nop.i 0
+} {.mfi
+ // r2=23+bias
+ mov r2=0xffff+23
+ // q'=q-q*(1.25*2^{-24}) (q'=q-ulp)
+ fnma.s.s1 f15=f11,f15,f11
+ nop.i 0;;
+}
+ {.mmi
+ nop.m 0
+ cmp.eq p11,p14=r2,r28
+ nop.i 0;;
+}
+
+.pred.rel "mutex",p11,p14
+ {.mfi
+ nop.m 0
+ // if exp_q=2^23, then r=a-b*2^{23}
+ (p11) fnma.s1 f13=f12,f14,f13
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // r2=a-b*q'
+ (p14) fnma.s1 f13=f14,f15,f13
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // r>0 iff q=RZ(a/b) and inexact
+ fcmp.gt.unc.s1 p8,p0=f6,f0
+ nop.i 0
+} {.mfi
+ nop.m 0
+ // r<0 iff q'=RZ(a/b) and inexact
+ (p14) fcmp.lt.unc.s1 p9,p10=f6,f0
+ nop.i 0;;
+}
+
+.pred.rel "mutex",p8,p9
+ {.mfi
+ nop.m 0
+ // (p8) Q=q+(last iteration ? sticky bits:0)
+ // i.e. Q=q+q*x (x=2^{-32} or 0)
+ (p8) fma.s1 f11=f11,f7,f11
+ nop.i 0
+} {.mfi
+ nop.m 0
+ // (p9) Q=q'+(last iteration ? sticky bits:0)
+ // i.e. Q=q'+q'*x (x=2^{-32} or 0)
+ (p9) fma.s1 f11=f15,f7,f15
+ nop.i 0;;
+}
+
+ {.mfb
+ nop.m 0
+ // (p9) set r=r2 (new a, if not last iteration)
+ // (p10) new a =r
+ (p10) mov f13=f6
+ (p12) br.cond.sptk remloop24;;
+}
+
+// last iteration
+ {.mfi
+ nop.m 0
+ // set f9=|b|*sgn(a)
+ fmerge.s f9=f8,f9
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // round to integer
+ fcvt.fx.s1 f11=f11
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // save sign of a
+ fmerge.s f7=f8,f8
+ nop.i 0
+} {.mfi
+ nop.m 0
+ // normalize
+ fcvt.xf f11=f11
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // This can be removed if sign of 0 is not important
+ // get remainder using sf1
+ fnma.d.s1 f12=f9,f11,f8
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // get remainder
+ fnma.d.s0 f8=f9,f11,f8
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // f12=0?
+ // This can be removed if sign of 0 is not important
+ fcmp.eq.unc.s1 p8,p0=f12,f0
+ nop.i 0;;
+}
+ {.mfb
+ nop.m 0
+ // if f8=0, set sign correctly
+ // This can be removed if sign of 0 is not important
+ (p8) fmerge.s f8=f7,f8
+ // return
+ br.ret.sptk b0;;
+}
+
+
+FREM_X_NAN_INF:
+
+// Y zero ?
+{.mfi
+ nop.m 0
+ fma.s1 f10=f9,f1,f0
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ fcmp.eq.unc.s1 p11,p0=f10,f0
+ nop.i 0;;
+}
+{.mib
+ nop.m 0
+ nop.i 0
+ // if Y zero
+ (p11) br.cond.spnt FREM_Y_ZERO;;
+}
+
+// X infinity? Return QNAN indefinite
+{ .mfi
+ nop.m 999
+ fclass.m.unc p8,p0 = f8, 0x23
+ nop.i 999
+}
+// X infinity? Return QNAN indefinite
+{ .mfi
+ nop.m 999
+ fclass.m.unc p11,p0 = f8, 0x23
+ nop.i 999;;
+}
+// Y NaN ?
+{.mfi
+ nop.m 999
+(p8) fclass.m.unc p0,p8=f9,0xc3
+ nop.i 0;;
+}
+{.mfi
+ nop.m 999
+ // also set Denormal flag if necessary
+(p8) fma.s0 f9=f9,f1,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 999
+(p8) frcpa.s0 f8,p7 = f8,f8
+ nop.i 999 ;;
+}
+
+{.mfi
+ nop.m 999
+(p11) mov f10=f8
+ nop.i 0
+}
+{ .mfi
+ nop.m 999
+(p8) fma.d.s0 f8=f8,f1,f0
+ nop.i 0 ;;
+}
+
+{ .mfb
+ nop.m 999
+ frcpa.s0 f8,p7=f8,f9
+ (p11) br.cond.spnt EXP_ERROR_RETURN;;
+}
+{ .mib
+ nop.m 0
+ nop.i 0
+ br.ret.spnt b0 ;;
+}
+
+
+FREM_Y_NAN_INF_ZERO:
+
+// Y INF
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f9, 0x23
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p7) fma.d.s0 f8=f8,f1,f0
+(p7) br.ret.spnt b0 ;;
+}
+
+// Y NAN?
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p0 = f9, 0xc3
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p9) fma.d.s0 f8=f9,f1,f0
+(p9) br.ret.spnt b0 ;;
+}
+
+FREM_Y_ZERO:
+// Y zero? Must be zero at this point
+// because it is the only choice left.
+// Return QNAN indefinite
+
+// X NAN?
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p10 = f8, 0xc3
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fclass.nm p9,p10 = f8, 0xff
+ nop.i 999 ;;
+}
+
+{.mfi
+ nop.m 999
+ (p9) frcpa.s0 f11,p7=f8,f0
+ nop.i 0;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) frcpa.s0 f11,p7 = f0,f0
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fmerge.s f10 = f8, f8
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+ fma.d.s0 f8=f11,f1,f0
+ nop.i 999
+}
+
+
+EXP_ERROR_RETURN:
+
+{ .mib
+ mov GR_Parameter_TAG = 124
+ nop.i 999
+ br.sptk __libm_error_region;;
+}
+
+GLOBAL_IEEE754_END(remainder)
+
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_remainderf.S b/libc/sysdeps/ia64/fpu/e_remainderf.S
new file mode 100644
index 000000000..0e9bedd65
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_remainderf.S
@@ -0,0 +1,609 @@
+.file "remainderf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//====================================================================
+// 02/02/00 Initial version
+// 03/02/00 New algorithm
+// 04/04/00 Unwind support added
+// 07/21/00 Fixed quotient=2^{24*m+23} bug
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 11/29/00 Set FR_Y to f9
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//====================================================================
+// float remainderf(float,float);
+//
+// Overview of operation
+//====================================================================
+// remainder(a,b)=a-i*b,
+// where i is an integer such that, if b!=0 and a is finite,
+// |a/b-i|<=1/2. If |a/b-i|=1/2, i is even.
+//
+// Algorithm
+//====================================================================
+// a). eliminate special cases
+// b). if |a/b|<0.25 (first quotient estimate), return a
+// c). use single precision divide algorithm to get quotient q
+// rounded to 24 bits of precision
+// d). calculate partial remainders (using both q and q-ulp);
+// select one and RZ(a/b) based on the sign of |a|-|b|*q
+// e). if the exponent difference (exponent(a)-exponent(b))
+// is less than 24 (quotient estimate<2^{24}-2), use RZ(a/b)
+// and sticky bits to round to integer; exit loop and
+// calculate final remainder
+// f). if exponent(a)-exponent(b)>=24, select new value of a as
+// the partial remainder calculated using RZ(a/b);
+// repeat from c).
+//
+// Special cases
+//====================================================================
+// a=+/- Inf, or b=+/-0: return NaN, call libm_error_support
+// a=NaN or b=NaN: return NaN
+//
+// Registers used
+//====================================================================
+// Predicate registers: p6-p12
+// General registers: r2,r3,r28,r29,r32 (ar.pfs), r33-r39
+// Floating point registers: f6-f15
+//
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+FR_X = f10
+FR_Y = f9
+FR_RESULT = f8
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(remainderf)
+
+// inputs in f8, f9
+// result in f8
+
+{ .mfi
+ alloc r32=ar.pfs,1,4,4,0
+ // f13=|a|
+ fmerge.s f13=f0,f8
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // f14=|b|
+ fmerge.s f14=f0,f9
+ nop.i 0;;
+}
+ {.mlx
+ nop.m 0
+ // r2=2^{24}-2
+ movl r3=0x4b7ffffe;;
+}
+
+// Y +-NAN, +-inf, +-0? p11
+{ .mfi
+ nop.m 999
+ fclass.m.unc p11,p0 = f9, 0xe7
+ nop.i 999
+}
+// qnan snan inf norm unorm 0 -+
+// 1 1 1 0 0 0 11
+// e 3
+// X +-NAN, +-inf, ? p9
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p0 = f8, 0xe3
+ nop.i 999;;
+}
+
+{.mfi
+ nop.m 0
+ mov f15=f0
+ nop.i 0
+}
+{ .mfi
+ // set p7=1
+ cmp.eq.unc p7,p0=r0,r0
+ // Step (1)
+ // y0 = 1 / b in f10
+ frcpa.s1 f10,p6=f13,f14
+ nop.i 0;;
+}
+{.bbb
+ (p9) br.cond.spnt FREM_X_NAN_INF
+ (p11) br.cond.spnt FREM_Y_NAN_INF_ZERO
+ nop.b 0
+} {.mfi
+ nop.m 0
+ // set D flag if a (f8) is denormal
+ fnma.s0 f6=f8,f1,f8
+ nop.i 0;;
+}
+
+.align 32
+remloop24:
+ { .mfi
+ // f12=2^{24}-2
+ setf.s f12=r3
+ // Step (2)
+ // q0 = a * y0 in f15
+ (p6) fma.s1 f15=f13,f10,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // Step (3)
+ // e0 = 1 - b * y0 in f7
+ (p6) fnma.s1 f7=f14,f10,f1
+ nop.i 0;;
+}
+{.mlx
+ nop.m 0
+ // r2=1.25*2^{-24}
+ movl r2=0x33a00000;;
+}
+ { .mfi
+ nop.m 0
+ // Step (4)
+ // q1 = q0 + e0 * q0 in f6
+ (p6) fma.s1 f6=f7,f15,f15
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // Step (5)
+ // e1 = e0 * e0 in f7
+ (p6) fma.s1 f7=f7,f7,f0
+ nop.i 0;;
+}
+ {.mii
+ (p7) getf.exp r29=f15
+ (p7) mov r28=0xfffd
+ nop.i 0;;
+}
+
+ { .mfi
+ // f15=1.25*2^{-24}
+ setf.s f15=r2
+ // Step (6)
+ // q2 = q1 + e1 * q1 in f6
+ (p6) fma.s1 f6=f7,f6,f6
+ nop.i 0
+}
+{ .mfi
+ mov r2=0x3e7
+ // Step (7)
+ // e2 = e1 * e1 in f7
+ (p6) fma.s1 f7=f7,f7,f0
+ nop.i 0;;
+}
+
+ {.mmi
+ // q<1/4 ? (i.e. expon< -2)
+ (p7) cmp.gt.unc p7,p0=r28,r29
+ nop.m 0
+ // r2=0x3e7000000
+ shl r2=r2,24;;
+}
+
+{.mfb
+ // r2=0x3e7000001
+ add r2=1,r2
+ // if |a/b|<1/4, set D flag before returning
+ (p7) fma.s.s0 f9=f9,f0,f8
+ nop.b 0;;
+}
+ {.mfb
+ nop.m 0
+ // can be combined with bundle above if sign of 0 or
+ // FTZ enabled are not important
+ (p7) fmerge.s f8=f8,f9
+ // return if |a|<4*|b| (estimated quotient < 1/4)
+ (p7) br.ret.spnt b0;;
+}
+ {.mfi
+ nop.m 0
+ // set f8 to current a value | sign
+ fmerge.s f8=f8,f13
+ // r2=2^{-24}+2^{-48} (double prec.)
+ shl r2=r2,28;;
+}
+
+
+{ .mfi
+ // r29= -32+bias
+ mov r29=0xffdf
+ // Step (8)
+ // q3 = q2 + e2 * q2 in f6
+ (p6) fma.d.s1 f6=f7,f6,f6
+ nop.i 0;;
+}
+{ .mfi
+ nop.m 0
+ // Step (9)
+ // q = q3 in f11
+ (p6) fma.s.s1 f11=f6,f1,f0
+ nop.i 0;;
+}
+ {.mfi
+ // f7=2^{-24}
+ setf.d f7=r2
+ // last step ? (q3<2^{24}-2 --> q<2^{24})
+ fcmp.lt.unc.s1 p0,p12=f6,f12
+ nop.i 0
+} {.mfi
+ // f12=2^{-32}
+ setf.exp f12=r29
+ nop.f 0
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // r=a-b*q
+ fnma.s1 f6=f14,f11,f13
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // q'=q-q*(1.25*2^{-24}) (q'=q-ulp)
+ fnma.s.s1 f15=f11,f15,f11
+ nop.i 0;;
+}
+
+ {.mfi
+ nop.m 0
+ // r2=a-b*q'
+ fnma.s1 f13=f14,f15,f13
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // r>0 iff q=RZ(a/b) and inexact
+ fcmp.gt.unc.s1 p8,p0=f6,f0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // r<0 iff q'=RZ(a/b) and inexact
+ fcmp.lt.unc.s1 p9,p10=f6,f0
+ nop.i 0;;
+}
+.pred.rel "mutex",p8,p9
+ {.mfi
+ nop.m 0
+ // (p8) Q=q+(last iteration ? sticky bits:0)
+ // i.e. Q=q+q*x (x=2^{-32} or 0)
+ (p8) fma.s1 f11=f11,f12,f11
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // (p9) Q=q'+(last iteration ? sticky bits:0)
+ // i.e. Q=q'+q'*x (x=2^{-24} or 0: if expon. difference=23, want to round back to q)
+ (p9) fma.s1 f11=f15,f7,f15
+ nop.i 0;;
+}
+
+ {.mfb
+ nop.m 0
+ // (p9) set r=r2 (new a, if not last iteration)
+ // (p10) new a =r
+ (p10) mov f13=f6
+ (p12) br.cond.sptk remloop24;;
+}
+
+// last iteration
+ {.mfi
+ nop.m 0
+ // set f9=|b|*sgn(a)
+ fmerge.s f9=f8,f9
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // round to integer
+ fcvt.fx.s1 f11=f11
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // save sign of a
+ fmerge.s f7=f8,f8
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // normalize
+ fcvt.xf f11=f11
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // This can be removed if sign of 0 is not important
+ // get remainder using sf1
+ fnma.s.s1 f12=f9,f11,f8
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // get remainder
+ fnma.s.s0 f8=f9,f11,f8
+ nop.i 0;;
+}
+
+
+
+ {.mfi
+ nop.m 0
+ // f12=0?
+ // This can be removed if sign of 0 is not important
+ fcmp.eq.unc.s1 p8,p0=f12,f0
+ nop.i 0;;
+}
+ {.mfb
+ nop.m 0
+ // if f8=0, set sign correctly
+ // This can be removed if sign of 0 is not important
+ (p8) fmerge.s f8=f7,f8
+ // return
+ br.ret.sptk b0;;
+}
+
+
+FREM_X_NAN_INF:
+
+// Y zero ?
+{.mfi
+ nop.m 0
+ fma.s1 f10=f9,f1,f0
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ fcmp.eq.unc.s1 p11,p0=f10,f0
+ nop.i 0;;
+}
+{.mib
+ nop.m 0
+ nop.i 0
+ // if Y zero
+ (p11) br.cond.spnt FREM_Y_ZERO;;
+}
+
+// X infinity? Return QNAN indefinite
+{ .mfi
+ nop.m 999
+ fclass.m.unc p8,p0 = f8, 0x23
+ nop.i 999
+}
+// X infinity? Return QNAN indefinite
+{ .mfi
+ nop.m 999
+ fclass.m.unc p11,p0 = f8, 0x23
+ nop.i 999;;
+}
+// Y NaN ?
+{.mfi
+ nop.m 999
+(p8) fclass.m.unc p0,p8=f9,0xc3
+ nop.i 0;;
+}
+{.mfi
+ nop.m 999
+ // also set Denormal flag if necessary
+(p8) fma.s0 f9=f9,f1,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 999
+(p8) frcpa.s0 f8,p7 = f8,f8
+ nop.i 999 ;;
+}
+
+{.mfi
+ nop.m 999
+(p11) mov f10=f8
+ nop.i 0
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s.s0 f8=f8,f1,f0
+ nop.i 0 ;;
+}
+
+{ .mfb
+ nop.m 999
+ frcpa.s0 f8,p7=f8,f9
+ (p11) br.cond.spnt EXP_ERROR_RETURN;;
+}
+{ .mib
+ nop.m 0
+ nop.i 0
+ br.ret.spnt b0 ;;
+}
+
+
+FREM_Y_NAN_INF_ZERO:
+
+// Y INF
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f9, 0x23
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p7) fma.s.s0 f8=f8,f1,f0
+(p7) br.ret.spnt b0 ;;
+}
+
+// Y NAN?
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p0 = f9, 0xc3
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p9) fma.s.s0 f8=f9,f1,f0
+(p9) br.ret.spnt b0 ;;
+}
+
+FREM_Y_ZERO:
+// Y zero? Must be zero at this point
+// because it is the only choice left.
+// Return QNAN indefinite
+
+// X NAN?
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p10 = f8, 0xc3
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fclass.nm p9,p10 = f8, 0xff
+ nop.i 999 ;;
+}
+
+{.mfi
+ nop.m 999
+ (p9) frcpa.s0 f11,p7=f8,f0
+ nop.i 0;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) frcpa.s0 f11,p7 = f0,f0
+nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fmerge.s f10 = f8, f8
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+ fma.s.s0 f8=f11,f1,f0
+ nop.i 999
+}
+
+
+EXP_ERROR_RETURN:
+
+{ .mib
+ mov GR_Parameter_TAG = 125
+ nop.i 999
+ br.sptk __libm_error_region;;
+}
+
+GLOBAL_IEEE754_END(remainderf)
+
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support#;; // Call error handling function
+}
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_remainderl.S b/libc/sysdeps/ia64/fpu/e_remainderl.S
new file mode 100644
index 000000000..8c1630e3a
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_remainderl.S
@@ -0,0 +1,617 @@
+.file "remainderl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//====================================================================
+// 02/02/00 Initial version
+// 03/02/00 New algorithm
+// 04/04/00 Unwind support added
+// 07/21/00 Fixed quotient=2^{24*m+23}*1.q1...q23 1 bug
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 11/29/00 Set FR_Y to f9
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//====================================================================
+// long double remainderl(long double,long double);
+//
+// Overview of operation
+//====================================================================
+// remainder(a,b)=a-i*b,
+// where i is an integer such that, if b!=0 and a is finite,
+// |a/b-i|<=1/2. If |a/b-i|=1/2, i is even.
+//
+// Algorithm
+//====================================================================
+// a). eliminate special cases
+// b). if |a/b|<0.25 (first quotient estimate), return a
+// c). use single precision divide algorithm to get quotient q
+// rounded to 24 bits of precision
+// d). calculate partial remainders (using both q and q-ulp);
+// select one and RZ(a/b) based on the sign of |a|-|b|*q
+// e). if the exponent difference (exponent(a)-exponent(b))
+// is less than 24 (quotient estimate<2^{24}-2), use RZ(a/b)
+// and sticky bits to round to integer; exit loop and
+// calculate final remainder
+// f). if exponent(a)-exponent(b)>=24, select new value of a as
+// the partial remainder calculated using RZ(a/b);
+// repeat from c).
+//
+// Special cases
+//====================================================================
+// a=+/- Inf, or b=+/-0: return NaN, call libm_error_support
+// a=NaN or b=NaN: return NaN
+//
+// Registers used
+//====================================================================
+// Predicate registers: p6-p14
+// General registers: r2,r3,r28,r29,r32 (ar.pfs), r33-r39
+// Floating point registers: f6-f15,f32
+//
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+FR_X = f10
+FR_Y = f9
+FR_RESULT = f8
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(remainderl)
+
+// inputs in f8, f9
+// result in f8
+
+{ .mfi
+ alloc r32=ar.pfs,1,4,4,0
+ // f13=|a|
+ fmerge.s f13=f0,f8
+ nop.i 0
+}
+ {.mfi
+ getf.sig r29=f9
+ // f14=|b|
+ fmerge.s f14=f0,f9
+ nop.i 0;;
+}
+ {.mlx
+ mov r28=0x2ffdd
+ // r2=2^{23}
+ movl r3=0x4b000000;;
+}
+
+
+{.mmi
+setf.exp f32=r28
+nop.m 0
+// y pseudo-zero ?
+cmp.eq p11,p10=r29,r0;;
+}
+
+// Y +-NAN, +-inf, +-0? p11
+{ .mfi
+ nop.m 999
+(p10) fclass.m p11,p10 = f9, 0xe7
+ nop.i 999
+}
+// qnan snan inf norm unorm 0 -+
+// 1 1 1 0 0 0 11
+// e 3
+// X +-NAN, +-inf, ? p9
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p8 = f8, 0xe3
+ nop.i 999;;
+}
+
+{.mfi
+ nop.m 0
+ mov f12=f0
+ nop.i 0
+}
+{ .mfi
+ // set p7=1
+ cmp.eq.unc p7,p0=r0,r0
+ // Step (1)
+ // y0 = 1 / b in f10
+ frcpa.s1 f10,p6=f13,f14
+ nop.i 0;;
+}
+// Y +-NAN, +-inf, +-0? p11
+{ .mfi
+ nop.m 999
+ // pseudo-NaN ?
+(p10) fclass.nm p11,p0 = f9, 0xff
+ nop.i 999
+}
+
+// qnan snan inf norm unorm 0 -+
+// 1 1 1 0 0 0 11
+// e 3
+// X +-NAN, +-inf, ? p9
+
+{ .mfi
+ nop.m 999
+(p8) fclass.nm p9,p0 = f8, 0xff
+ nop.i 999;;
+}
+
+{.bbb
+ (p9) br.cond.spnt FREM_X_NAN_INF
+ (p11) br.cond.spnt FREM_Y_NAN_INF_ZERO
+ nop.b 0
+} {.mfi
+ nop.m 0
+ // set D flag if a (f8) is denormal
+ fnma.s0 f6=f8,f1,f8
+ nop.i 0;;
+}
+
+remloop24:
+ { .mfi
+ nop.m 0
+ // Step (2)
+ // q0 = a * y0 in f15
+ (p6) fma.s1 f12=f13,f10,f0
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (3)
+ // e0 = 1 - b * y0 in f7
+ (p6) fnma.s1 f7=f14,f10,f1
+ nop.i 0;;
+} {.mlx
+ nop.m 0
+ // r2=1.25*2^{-24}
+ movl r2=0x33a00000;;
+}
+
+{.mfi
+ nop.m 0
+ // q1=q0*(1+e0)
+ (p6) fma.s1 f15=f12,f7,f12
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // Step (4)
+ // e1 = e0 * e0 + E in f7
+ (p6) fma.s1 f7=f7,f7,f32
+ nop.i 0;;
+}
+ {.mii
+ (p7) getf.exp r29=f12
+ (p7) mov r28=0xfffd
+ nop.i 0;;
+}
+
+ { .mfi
+ // f12=2^{23}
+ setf.s f12=r3
+ // Step (5)
+ // q2 = q1 + e1 * q1 in f11
+ (p6) fma.s.s1 f11=f7,f15,f15
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (6)
+ // q2 = q1 + e1 * q1 in f6
+ (p6) fma.s1 f6=f7,f15,f15
+ nop.i 0;;
+}
+
+ {.mmi
+ // f15=1.25*2^{-24}
+ setf.s f15=r2
+ // q<1/4 ? (i.e. expon< -2)
+ (p7) cmp.gt p7,p0=r28,r29
+ nop.i 0;;
+}
+
+{.mfb
+ // r29= -32+bias
+ mov r29=0xffdf
+ // if |a/b|<1/4, set D flag before returning
+ (p7) fma.s0 f9=f9,f0,f8
+ nop.b 0;;
+}
+ {.mfb
+ nop.m 0
+ // can be combined with bundle above if sign of 0 or
+ // FTZ enabled are not important
+ (p7) fmerge.s f8=f8,f9
+ // return if |a|<4*|b| (estimated quotient < 1/4)
+ (p7) br.ret.spnt b0;;
+}
+ {.mfi
+ // f7=2^{-32}
+ setf.exp f7=r29
+ // set f8 to current a value | sign
+ fmerge.s f8=f8,f13
+ nop.i 0;;
+}
+ {.mfi
+ getf.exp r28=f6
+ // last step ? (q<2^{23})
+ fcmp.lt.unc.s1 p0,p12=f6,f12
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // r=a-b*q
+ fnma.s1 f6=f14,f11,f13
+ nop.i 0
+} {.mfi
+ // r2=23+bias
+ mov r2=0xffff+23
+ // q'=q-q*(1.25*2^{-24}) (q'=q-ulp)
+ fnma.s.s1 f15=f11,f15,f11
+ nop.i 0;;
+}
+ {.mmi
+ nop.m 0
+ cmp.eq p11,p14=r2,r28
+ nop.i 0;;
+}
+
+.pred.rel "mutex",p11,p14
+ {.mfi
+ nop.m 0
+ // if exp_q=2^23, then r=a-b*2^{23}
+ (p11) fnma.s1 f13=f12,f14,f13
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // r2=a-b*q'
+ (p14) fnma.s1 f13=f14,f15,f13
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // r>0 iff q=RZ(a/b) and inexact
+ fcmp.gt.unc.s1 p8,p0=f6,f0
+ nop.i 0
+} {.mfi
+ nop.m 0
+ // r<0 iff q'=RZ(a/b) and inexact
+ (p14) fcmp.lt.unc.s1 p9,p10=f6,f0
+ nop.i 0;;
+}
+
+.pred.rel "mutex",p8,p9
+ {.mfi
+ nop.m 0
+ // (p8) Q=q+(last iteration ? sticky bits:0)
+ // i.e. Q=q+q*x (x=2^{-32} or 0)
+ (p8) fma.s1 f11=f11,f7,f11
+ nop.i 0
+} {.mfi
+ nop.m 0
+ // (p9) Q=q'+(last iteration ? sticky bits:0)
+ // i.e. Q=q'+q'*x (x=2^{-32} or 0)
+ (p9) fma.s1 f11=f15,f7,f15
+ nop.i 0;;
+}
+
+ {.mfb
+ nop.m 0
+ // (p9) set r=r2 (new a, if not last iteration)
+ // (p10) new a =r
+ (p10) mov f13=f6
+ (p12) br.cond.sptk remloop24;;
+}
+
+// last iteration
+ {.mfi
+ nop.m 0
+ // set f9=|b|*sgn(a)
+ fmerge.s f9=f8,f9
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // round to integer
+ fcvt.fx.s1 f11=f11
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // save sign of a
+ fmerge.s f7=f8,f8
+ nop.i 0
+} {.mfi
+ nop.m 0
+ // normalize
+ fcvt.xf f11=f11
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // This can be removed if sign of 0 is not important
+ // get remainder using sf1
+ fnma.s1 f12=f9,f11,f8
+ nop.i 0
+}
+ {.mfi
+ nop.m 0
+ // get remainder
+ fnma.s0 f8=f9,f11,f8
+ nop.i 0;;
+}
+ {.mfi
+ nop.m 0
+ // f12=0?
+ // This can be removed if sign of 0 is not important
+ fcmp.eq.unc.s1 p8,p0=f12,f0
+ nop.i 0;;
+}
+ {.mfb
+ nop.m 0
+ // if f8=0, set sign correctly
+ // This can be removed if sign of 0 is not important
+ (p8) fmerge.s f8=f7,f8
+ // return
+ br.ret.sptk b0;;
+}
+
+
+
+FREM_X_NAN_INF:
+
+// Y zero ?
+{.mfi
+ nop.m 0
+ fma.s1 f10=f9,f1,f0
+ nop.i 0;;
+}
+{.mfi
+ nop.m 0
+ fcmp.eq.unc.s1 p11,p0=f10,f0
+ nop.i 0;;
+}
+{.mib
+ nop.m 0
+ nop.i 0
+ // if Y zero
+ (p11) br.cond.spnt FREM_Y_ZERO;;
+}
+
+// X infinity? Return QNAN indefinite
+{ .mfi
+ nop.m 999
+ fclass.m.unc p8,p0 = f8, 0x23
+ nop.i 999
+}
+// X infinity? Return QNAN indefinite
+{ .mfi
+ nop.m 999
+ fclass.m.unc p11,p0 = f8, 0x23
+ nop.i 999;;
+}
+// Y NaN ?
+{.mfi
+ nop.m 999
+(p8) fclass.m.unc p0,p8=f9,0xc3
+ nop.i 0;;
+}
+{.mfi
+ nop.m 999
+ // also set Denormal flag if necessary
+(p8) fnma.s0 f9=f9,f1,f9
+ nop.i 0
+}
+{ .mfi
+ nop.m 999
+(p8) frcpa.s0 f8,p7 = f8,f8
+ nop.i 999 ;;
+}
+
+{.mfi
+ nop.m 999
+(p11) mov f10=f8
+ nop.i 0
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s0 f8=f8,f1,f0
+ nop.i 0 ;;
+}
+
+{ .mfb
+ nop.m 999
+ frcpa.s0 f8,p7=f8,f9
+ (p11) br.cond.spnt EXP_ERROR_RETURN;;
+}
+{ .mib
+ nop.m 0
+ nop.i 0
+ br.ret.spnt b0 ;;
+}
+
+
+FREM_Y_NAN_INF_ZERO:
+// Y INF
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f9, 0x23
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p7) fma.s0 f8=f8,f1,f0
+(p7) br.ret.spnt b0 ;;
+}
+
+// Y NAN?
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p10 = f9, 0xc3
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fclass.nm p9,p0 = f9, 0xff
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p9) fma.s0 f8=f9,f1,f0
+(p9) br.ret.spnt b0 ;;
+}
+
+FREM_Y_ZERO:
+// Y zero? Must be zero at this point
+// because it is the only choice left.
+// Return QNAN indefinite
+
+// X NAN?
+{ .mfi
+ nop.m 999
+ fclass.m.unc p9,p10 = f8, 0xc3
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fclass.nm p9,p10 = f8, 0xff
+ nop.i 999 ;;
+}
+
+{.mfi
+ nop.m 999
+ (p9) frcpa.s0 f11,p7=f8,f0
+ nop.i 0;;
+}
+{ .mfi
+ nop.m 999
+(p10) frcpa.s0 f11,p7 = f0,f0
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fmerge.s f10 = f8, f8
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+ fma.s0 f8=f11,f1,f0
+ nop.i 999;;
+}
+
+EXP_ERROR_RETURN:
+
+{ .mib
+ mov GR_Parameter_TAG = 123
+ nop.i 999
+ br.sptk __libm_error_region;;
+}
+
+GLOBAL_IEEE754_END(remainderl)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/e_scalb.S b/libc/sysdeps/ia64/fpu/e_scalb.S
new file mode 100644
index 000000000..3d48aab18
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_scalb.S
@@ -0,0 +1,599 @@
+.file "scalb.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 01/26/01 Scalb completely reworked and now standalone version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 08/06/03 Improved performance
+//
+// API
+//==============================================================
+// double = scalb (double x, double n)
+// input floating point f8 and floating point f9
+// output floating point f8
+//
+// int_type = 0 if int is 32 bits
+// int_type = 1 if int is 64 bits
+//
+// Returns x* 2**n using an fma and detects overflow
+// and underflow.
+//
+//
+// Strategy:
+// Compute biased exponent of result exp_Result = N + exp_X
+// Break into ranges:
+// exp_Result > 0x103fe -> Certain overflow
+// exp_Result = 0x103fe -> Possible overflow
+// 0x0fc01 <= exp_Result < 0x103fe -> No over/underflow (main path)
+// 0x0fc01 - 52 <= exp_Result < 0x0fc01 -> Possible underflow
+// exp_Result < 0x0fc01 - 52 -> Certain underflow
+
+FR_Big = f6
+FR_NBig = f7
+FR_Floating_X = f8
+FR_Result = f8
+FR_Floating_N = f9
+FR_Result2 = f9
+FR_Result3 = f10
+FR_Norm_X = f11
+FR_Two_N = f12
+FR_N_float_int = f13
+FR_Norm_N = f14
+
+GR_neg_ov_limit= r14
+GR_big_exp = r14
+GR_N_Biased = r15
+GR_Big = r16
+GR_exp_Result = r18
+GR_pos_ov_limit= r19
+GR_exp_sure_ou = r19
+GR_Bias = r20
+GR_N_as_int = r21
+GR_signexp_X = r22
+GR_exp_X = r23
+GR_exp_mask = r24
+GR_max_exp = r25
+GR_min_exp = r26
+GR_min_den_exp = r27
+GR_Scratch = r28
+GR_signexp_N = r29
+GR_exp_N = r30
+
+GR_SAVE_B0 = r32
+GR_SAVE_GP = r33
+GR_SAVE_PFS = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Tag = r38
+
+.section .text
+GLOBAL_IEEE754_ENTRY(scalb)
+
+//
+// Is x NAN, INF, ZERO, +-?
+// Build the exponent Bias
+//
+{ .mfi
+ getf.exp GR_signexp_N = FR_Floating_N // Get signexp of n
+ fclass.m p6,p0 = FR_Floating_X, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_Bias = 0x0ffff
+}
+{ .mfi
+ mov GR_Big = 35000 // If N this big then certain overflow
+ fcvt.fx.trunc.s1 FR_N_float_int = FR_Floating_N // Get N in significand
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.exp GR_signexp_X = FR_Floating_X // Get signexp of x
+ fclass.m p7,p0 = FR_Floating_N, 0x0b // Test for n=unorm
+ nop.i 0
+}
+//
+// Normalize n
+//
+{ .mfi
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+ fnorm.s1 FR_Norm_N = FR_Floating_N
+ nop.i 0
+}
+;;
+
+//
+// Is n NAN, INF, ZERO, +-?
+//
+{ .mfi
+ mov GR_big_exp = 0x1003e // Exponent at which n is integer
+ fclass.m p9,p0 = FR_Floating_N, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_max_exp = 0x103fe // Exponent of maximum double
+}
+//
+// Normalize x
+//
+{ .mfb
+ nop.m 0
+ fnorm.s1 FR_Norm_X = FR_Floating_X
+(p7) br.cond.spnt SCALB_N_UNORM // Branch if n=unorm
+}
+;;
+
+SCALB_COMMON1:
+// Main path continues. Also return here from u=unorm path.
+// Handle special cases if x = Nan, Inf, Zero
+{ .mfb
+ nop.m 0
+ fcmp.lt.s1 p7,p0 = FR_Floating_N, f0 // Test N negative
+(p6) br.cond.spnt SCALB_NAN_INF_ZERO
+}
+;;
+
+// Handle special cases if n = Nan, Inf, Zero
+{ .mfi
+ getf.sig GR_N_as_int = FR_N_float_int // Get n from significand
+ fclass.m p8,p0 = FR_Floating_X, 0x0b // Test for x=unorm
+ mov GR_exp_sure_ou = 0x1000e // Exp_N where x*2^N sure over/under
+}
+{ .mfb
+ mov GR_min_exp = 0x0fc01 // Exponent of minimum double
+ fcvt.xf FR_N_float_int = FR_N_float_int // Convert N to FP integer
+(p9) br.cond.spnt SCALB_NAN_INF_ZERO
+}
+;;
+
+{ .mmi
+ and GR_exp_N = GR_exp_mask, GR_signexp_N // Get exponent of N
+(p7) sub GR_Big = r0, GR_Big // Limit for N
+ nop.i 0
+}
+;;
+
+{ .mib
+ cmp.lt p9,p0 = GR_exp_N, GR_big_exp // N possible non-integer?
+ cmp.ge p6,p0 = GR_exp_N, GR_exp_sure_ou // N certain over/under?
+(p8) br.cond.spnt SCALB_X_UNORM // Branch if x=unorm
+}
+;;
+
+SCALB_COMMON2:
+// Main path continues. Also return here from x=unorm path.
+// Create biased exponent for 2**N
+{ .mmi
+(p6) mov GR_N_as_int = GR_Big // Limit N
+;;
+ add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp FR_Two_N = GR_N_Biased // Form 2**N
+(p9) fcmp.neq.unc.s1 p9,p0 = FR_Norm_N, FR_N_float_int // Test if N an integer
+ and GR_exp_X = GR_exp_mask, GR_signexp_X // Get exponent of X
+}
+;;
+
+//
+// Compute biased result exponent
+// Branch if N is not an integer
+//
+{ .mib
+ add GR_exp_Result = GR_exp_X, GR_N_as_int
+ mov GR_min_den_exp = 0x0fc01 - 52 // Exponent of min denorm dble
+(p9) br.cond.spnt SCALB_N_NOT_INT
+}
+;;
+
+//
+// Raise Denormal operand flag with compare
+// Do final operation
+//
+{ .mfi
+ cmp.lt p7,p6 = GR_exp_Result, GR_max_exp // Test no overflow
+ fcmp.ge.s0 p0,p11 = FR_Floating_X,FR_Floating_N // Dummy to set denorm
+ cmp.lt p9,p0 = GR_exp_Result, GR_min_den_exp // Test sure underflow
+}
+{ .mfb
+ nop.m 0
+ fma.d.s0 FR_Result = FR_Two_N,FR_Norm_X,f0
+(p9) br.cond.spnt SCALB_UNDERFLOW // Branch if certain underflow
+}
+;;
+
+{ .mib
+(p6) cmp.gt.unc p6,p8 = GR_exp_Result, GR_max_exp // Test sure overflow
+(p7) cmp.ge.unc p7,p9 = GR_exp_Result, GR_min_exp // Test no over/underflow
+(p7) br.ret.sptk b0 // Return from main path
+}
+;;
+
+{ .bbb
+(p6) br.cond.spnt SCALB_OVERFLOW // Branch if certain overflow
+(p8) br.cond.spnt SCALB_POSSIBLE_OVERFLOW // Branch if possible overflow
+(p9) br.cond.spnt SCALB_POSSIBLE_UNDERFLOW // Branch if possible underflow
+}
+;;
+
+// Here if possible underflow.
+// Resulting exponent: 0x0fc01-52 <= exp_Result < 0x0fc01
+SCALB_POSSIBLE_UNDERFLOW:
+//
+// Here if possible overflow.
+// Resulting exponent: 0x103fe = exp_Result
+SCALB_POSSIBLE_OVERFLOW:
+
+// Set up necessary status fields
+//
+// S0 user supplied status
+// S2 user supplied status + WRE + TD (Overflows)
+// S3 user supplied status + FZ + TD (Underflows)
+//
+{ .mfi
+ mov GR_pos_ov_limit = 0x103ff // Exponent for positive overflow
+ fsetc.s3 0x7F,0x41
+ nop.i 0
+}
+{ .mfi
+ mov GR_neg_ov_limit = 0x303ff // Exponent for negative overflow
+ fsetc.s2 0x7F,0x42
+ nop.i 0
+}
+;;
+
+//
+// Do final operation with s2 and s3
+//
+{ .mfi
+ setf.exp FR_NBig = GR_neg_ov_limit
+ fma.d.s3 FR_Result3 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+{ .mfi
+ setf.exp FR_Big = GR_pos_ov_limit
+ fma.d.s2 FR_Result2 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+;;
+
+// Check for overflow or underflow.
+// Restore s3
+// Restore s2
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x40
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40
+ nop.i 0
+}
+;;
+
+//
+// Is the result zero?
+//
+{ .mfi
+ nop.m 0
+ fclass.m p6, p0 = FR_Result3, 0x007
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p7, p8 = FR_Result2 , FR_Big
+ nop.i 0
+}
+;;
+
+//
+// Detect masked underflow - Tiny + Inexact Only
+//
+{ .mfi
+ nop.m 0
+(p6) fcmp.neq.unc.s1 p6, p0 = FR_Result , FR_Result2
+ nop.i 0
+}
+;;
+
+//
+// Is result bigger the allowed range?
+// Branch out for underflow
+//
+{ .mfb
+ nop.m 0
+(p8) fcmp.le.unc.s1 p9, p10 = FR_Result2 , FR_NBig
+(p6) br.cond.spnt SCALB_UNDERFLOW
+}
+;;
+
+//
+// Branch out for overflow
+//
+{ .bbb
+(p7) br.cond.spnt SCALB_OVERFLOW
+(p9) br.cond.spnt SCALB_OVERFLOW
+ br.ret.sptk b0 // Return from main path.
+}
+;;
+
+// Here if result overflows
+SCALB_OVERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 53, r0 // Set error tag for overflow
+ br.cond.sptk __libm_error_region // Call error support for overflow
+}
+;;
+
+// Here if result underflows
+SCALB_UNDERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 54, r0 // Set error tag for underflow
+ br.cond.sptk __libm_error_region // Call error support for underflow
+}
+;;
+
+SCALB_NAN_INF_ZERO:
+
+//
+// Before entry, N has been converted to a fp integer in significand of
+// FR_N_float_int
+//
+// Convert N_float_int to floating point value
+//
+{ .mfi
+ getf.sig GR_N_as_int = FR_N_float_int
+ fclass.m p6,p0 = FR_Floating_N, 0xc3 //@snan | @qnan
+ nop.i 0
+}
+{ .mfi
+ addl GR_Scratch = 1,r0
+ fcvt.xf FR_N_float_int = FR_N_float_int
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p7,p0 = FR_Floating_X, 0xc3 //@snan | @qnan
+ shl GR_Scratch = GR_Scratch,63
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p8,p0 = FR_Floating_N, 0x21 // @inf
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fclass.m p9,p0 = FR_Floating_N, 0x22 // @-inf
+ nop.i 0
+}
+;;
+
+//
+// Either X or N is a Nan, return result and possible raise invalid.
+//
+{ .mfb
+ nop.m 0
+(p6) fma.d.s0 FR_Result = FR_Floating_N,FR_Floating_X,f0
+(p6) br.ret.spnt b0
+}
+;;
+
+{ .mfb
+ nop.m 0
+(p7) fma.d.s0 FR_Result = FR_Floating_N,FR_Floating_X,f0
+(p7) br.ret.spnt b0
+}
+;;
+
+//
+// If N + Inf do something special
+// For N = -Inf, create Int
+//
+{ .mfb
+ nop.m 0
+(p8) fma.d.s0 FR_Result = FR_Floating_X, FR_Floating_N,f0
+(p8) br.ret.spnt b0
+}
+{ .mfi
+ nop.m 0
+(p9) fnma.d.s0 FR_Floating_N = FR_Floating_N, f1, f0
+ nop.i 0
+}
+;;
+
+//
+// If N==-Inf,return x/(-N)
+//
+{ .mfb
+ cmp.ne p7,p0 = GR_N_as_int,GR_Scratch
+(p9) frcpa.s0 FR_Result,p0 = FR_Floating_X,FR_Floating_N
+(p9) br.ret.spnt b0
+}
+;;
+
+//
+// Is N an integer.
+//
+{ .mfi
+ nop.m 0
+(p7) fcmp.neq.unc.s1 p7,p0 = FR_Norm_N, FR_N_float_int
+ nop.i 0
+}
+;;
+
+//
+// If N not an int, return NaN and raise invalid.
+//
+{ .mfb
+ nop.m 0
+(p7) frcpa.s0 FR_Result,p0 = f0,f0
+(p7) br.ret.spnt b0
+}
+;;
+
+//
+// Always return x in other path.
+//
+{ .mfb
+ nop.m 0
+ fma.d.s0 FR_Result = FR_Floating_X,f1,f0
+ br.ret.sptk b0
+}
+;;
+
+// Here if n not int
+// Return NaN and raise invalid.
+SCALB_N_NOT_INT:
+{ .mfb
+ nop.m 0
+ frcpa.s0 FR_Result,p0 = f0,f0
+ br.ret.sptk b0
+}
+;;
+
+// Here if n=unorm
+SCALB_N_UNORM:
+{ .mfb
+ getf.exp GR_signexp_N = FR_Norm_N // Get signexp of normalized n
+ fcvt.fx.trunc.s1 FR_N_float_int = FR_Norm_N // Get N in significand
+ br.cond.sptk SCALB_COMMON1 // Return to main path
+}
+;;
+
+// Here if x=unorm
+SCALB_X_UNORM:
+{ .mib
+ getf.exp GR_signexp_X = FR_Norm_X // Get signexp of normalized x
+ nop.i 0
+ br.cond.sptk SCALB_COMMON2 // Return to main path
+}
+;;
+
+GLOBAL_IEEE754_END(scalb)
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+//
+// Get stack address of N
+//
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs
+}
+//
+// Adjust sp
+//
+{ .mfi
+.fframe 64
+ add sp=-64,sp
+ nop.f 0
+ mov GR_SAVE_GP=gp
+};;
+
+//
+// Store N on stack in correct position
+// Locate the address of x on stack
+//
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Norm_N,16
+ add GR_Parameter_X = 16,sp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0
+};;
+
+//
+// Store x on the stack.
+// Get address for result on stack.
+//
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_Norm_X
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_Result
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support#
+};;
+
+//
+// Get location of result on stack
+//
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+//
+// Get the new result
+//
+{ .mmi
+ ldfd FR_Result = [GR_Parameter_RESULT]
+.restore sp
+ add sp = 64,sp
+ mov b0 = GR_SAVE_B0
+};;
+
+//
+// Restore gp, ar.pfs and return
+//
+{ .mib
+ mov gp = GR_SAVE_GP
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_scalbf.S b/libc/sysdeps/ia64/fpu/e_scalbf.S
new file mode 100644
index 000000000..e965667d7
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_scalbf.S
@@ -0,0 +1,599 @@
+.file "scalbf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 01/26/01 Scalb completely reworked and now standalone version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 08/06/03 Improved performance
+//
+// API
+//==============================================================
+// float = scalbf (float x, float n)
+// input floating point f8 and floating point f9
+// output floating point f8
+//
+// int_type = 0 if int is 32 bits
+// int_type = 1 if int is 64 bits
+//
+// Returns x* 2**n using an fma and detects overflow
+// and underflow.
+//
+//
+// Strategy:
+// Compute biased exponent of result exp_Result = N + exp_X
+// Break into ranges:
+// exp_Result > 0x1007e -> Certain overflow
+// exp_Result = 0x1007e -> Possible overflow
+// 0x0ff81 <= exp_Result < 0x1007e -> No over/underflow (main path)
+// 0x0ff81 - 23 <= exp_Result < 0x0ff81 -> Possible underflow
+// exp_Result < 0x0ff81 - 23 -> Certain underflow
+
+FR_Big = f6
+FR_NBig = f7
+FR_Floating_X = f8
+FR_Result = f8
+FR_Floating_N = f9
+FR_Result2 = f9
+FR_Result3 = f10
+FR_Norm_X = f11
+FR_Two_N = f12
+FR_N_float_int = f13
+FR_Norm_N = f14
+
+GR_neg_ov_limit= r14
+GR_big_exp = r14
+GR_N_Biased = r15
+GR_Big = r16
+GR_exp_Result = r18
+GR_pos_ov_limit= r19
+GR_exp_sure_ou = r19
+GR_Bias = r20
+GR_N_as_int = r21
+GR_signexp_X = r22
+GR_exp_X = r23
+GR_exp_mask = r24
+GR_max_exp = r25
+GR_min_exp = r26
+GR_min_den_exp = r27
+GR_Scratch = r28
+GR_signexp_N = r29
+GR_exp_N = r30
+
+GR_SAVE_B0 = r32
+GR_SAVE_GP = r33
+GR_SAVE_PFS = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Tag = r38
+
+.section .text
+GLOBAL_IEEE754_ENTRY(scalbf)
+
+//
+// Is x NAN, INF, ZERO, +-?
+// Build the exponent Bias
+//
+{ .mfi
+ getf.exp GR_signexp_N = FR_Floating_N // Get signexp of n
+ fclass.m p6,p0 = FR_Floating_X, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_Bias = 0x0ffff
+}
+{ .mfi
+ mov GR_Big = 35000 // If N this big then certain overflow
+ fcvt.fx.trunc.s1 FR_N_float_int = FR_Floating_N // Get N in significand
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.exp GR_signexp_X = FR_Floating_X // Get signexp of x
+ fclass.m p7,p0 = FR_Floating_N, 0x0b // Test for n=unorm
+ nop.i 0
+}
+//
+// Normalize n
+//
+{ .mfi
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+ fnorm.s1 FR_Norm_N = FR_Floating_N
+ nop.i 0
+}
+;;
+
+//
+// Is n NAN, INF, ZERO, +-?
+//
+{ .mfi
+ mov GR_big_exp = 0x1003e // Exponent at which n is integer
+ fclass.m p9,p0 = FR_Floating_N, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_max_exp = 0x1007e // Exponent of maximum float
+}
+//
+// Normalize x
+//
+{ .mfb
+ nop.m 0
+ fnorm.s1 FR_Norm_X = FR_Floating_X
+(p7) br.cond.spnt SCALBF_N_UNORM // Branch if n=unorm
+}
+;;
+
+SCALBF_COMMON1:
+// Main path continues. Also return here from u=unorm path.
+// Handle special cases if x = Nan, Inf, Zero
+{ .mfb
+ nop.m 0
+ fcmp.lt.s1 p7,p0 = FR_Floating_N, f0 // Test N negative
+(p6) br.cond.spnt SCALBF_NAN_INF_ZERO
+}
+;;
+
+// Handle special cases if n = Nan, Inf, Zero
+{ .mfi
+ getf.sig GR_N_as_int = FR_N_float_int // Get n from significand
+ fclass.m p8,p0 = FR_Floating_X, 0x0b // Test for x=unorm
+ mov GR_exp_sure_ou = 0x1000e // Exp_N where x*2^N sure over/under
+}
+{ .mfb
+ mov GR_min_exp = 0x0ff81 // Exponent of minimum float
+ fcvt.xf FR_N_float_int = FR_N_float_int // Convert N to FP integer
+(p9) br.cond.spnt SCALBF_NAN_INF_ZERO
+}
+;;
+
+{ .mmi
+ and GR_exp_N = GR_exp_mask, GR_signexp_N // Get exponent of N
+(p7) sub GR_Big = r0, GR_Big // Limit for N
+ nop.i 0
+}
+;;
+
+{ .mib
+ cmp.lt p9,p0 = GR_exp_N, GR_big_exp // N possible non-integer?
+ cmp.ge p6,p0 = GR_exp_N, GR_exp_sure_ou // N certain over/under?
+(p8) br.cond.spnt SCALBF_X_UNORM // Branch if x=unorm
+}
+;;
+
+SCALBF_COMMON2:
+// Main path continues. Also return here from x=unorm path.
+// Create biased exponent for 2**N
+{ .mmi
+(p6) mov GR_N_as_int = GR_Big // Limit N
+;;
+ add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp FR_Two_N = GR_N_Biased // Form 2**N
+(p9) fcmp.neq.unc.s1 p9,p0 = FR_Norm_N, FR_N_float_int // Test if N an integer
+ and GR_exp_X = GR_exp_mask, GR_signexp_X // Get exponent of X
+}
+;;
+
+//
+// Compute biased result exponent
+// Branch if N is not an integer
+//
+{ .mib
+ add GR_exp_Result = GR_exp_X, GR_N_as_int
+ mov GR_min_den_exp = 0x0ff81 - 23 // Exponent of min denorm float
+(p9) br.cond.spnt SCALBF_N_NOT_INT
+}
+;;
+
+//
+// Raise Denormal operand flag with compare
+// Do final operation
+//
+{ .mfi
+ cmp.lt p7,p6 = GR_exp_Result, GR_max_exp // Test no overflow
+ fcmp.ge.s0 p0,p11 = FR_Floating_X,FR_Floating_N // Dummy to set denorm
+ cmp.lt p9,p0 = GR_exp_Result, GR_min_den_exp // Test sure underflow
+}
+{ .mfb
+ nop.m 0
+ fma.s.s0 FR_Result = FR_Two_N,FR_Norm_X,f0
+(p9) br.cond.spnt SCALBF_UNDERFLOW // Branch if certain underflow
+}
+;;
+
+{ .mib
+(p6) cmp.gt.unc p6,p8 = GR_exp_Result, GR_max_exp // Test sure overflow
+(p7) cmp.ge.unc p7,p9 = GR_exp_Result, GR_min_exp // Test no over/underflow
+(p7) br.ret.sptk b0 // Return from main path
+}
+;;
+
+{ .bbb
+(p6) br.cond.spnt SCALBF_OVERFLOW // Branch if certain overflow
+(p8) br.cond.spnt SCALBF_POSSIBLE_OVERFLOW // Branch if possible overflow
+(p9) br.cond.spnt SCALBF_POSSIBLE_UNDERFLOW // Branch if possible underflow
+}
+;;
+
+// Here if possible underflow.
+// Resulting exponent: 0x0ff81-23 <= exp_Result < 0x0ff81
+SCALBF_POSSIBLE_UNDERFLOW:
+//
+// Here if possible overflow.
+// Resulting exponent: 0x1007e = exp_Result
+SCALBF_POSSIBLE_OVERFLOW:
+
+// Set up necessary status fields
+//
+// S0 user supplied status
+// S2 user supplied status + WRE + TD (Overflows)
+// S3 user supplied status + FZ + TD (Underflows)
+//
+{ .mfi
+ mov GR_pos_ov_limit = 0x1007f // Exponent for positive overflow
+ fsetc.s3 0x7F,0x41
+ nop.i 0
+}
+{ .mfi
+ mov GR_neg_ov_limit = 0x3007f // Exponent for negative overflow
+ fsetc.s2 0x7F,0x42
+ nop.i 0
+}
+;;
+
+//
+// Do final operation with s2 and s3
+//
+{ .mfi
+ setf.exp FR_NBig = GR_neg_ov_limit
+ fma.s.s3 FR_Result3 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+{ .mfi
+ setf.exp FR_Big = GR_pos_ov_limit
+ fma.s.s2 FR_Result2 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+;;
+
+// Check for overflow or underflow.
+// Restore s3
+// Restore s2
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x40
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40
+ nop.i 0
+}
+;;
+
+//
+// Is the result zero?
+//
+{ .mfi
+ nop.m 0
+ fclass.m p6, p0 = FR_Result3, 0x007
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p7, p8 = FR_Result2 , FR_Big
+ nop.i 0
+}
+;;
+
+//
+// Detect masked underflow - Tiny + Inexact Only
+//
+{ .mfi
+ nop.m 0
+(p6) fcmp.neq.unc.s1 p6, p0 = FR_Result , FR_Result2
+ nop.i 0
+}
+;;
+
+//
+// Is result bigger the allowed range?
+// Branch out for underflow
+//
+{ .mfb
+ nop.m 0
+(p8) fcmp.le.unc.s1 p9, p10 = FR_Result2 , FR_NBig
+(p6) br.cond.spnt SCALBF_UNDERFLOW
+}
+;;
+
+//
+// Branch out for overflow
+//
+{ .bbb
+(p7) br.cond.spnt SCALBF_OVERFLOW
+(p9) br.cond.spnt SCALBF_OVERFLOW
+ br.ret.sptk b0 // Return from main path.
+}
+;;
+
+// Here if result overflows
+SCALBF_OVERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 55, r0 // Set error tag for overflow
+ br.cond.sptk __libm_error_region // Call error support for overflow
+}
+;;
+
+// Here if result underflows
+SCALBF_UNDERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 56, r0 // Set error tag for underflow
+ br.cond.sptk __libm_error_region // Call error support for underflow
+}
+;;
+
+SCALBF_NAN_INF_ZERO:
+
+//
+// Before entry, N has been converted to a fp integer in significand of
+// FR_N_float_int
+//
+// Convert N_float_int to floating point value
+//
+{ .mfi
+ getf.sig GR_N_as_int = FR_N_float_int
+ fclass.m p6,p0 = FR_Floating_N, 0xc3 //@snan | @qnan
+ nop.i 0
+}
+{ .mfi
+ addl GR_Scratch = 1,r0
+ fcvt.xf FR_N_float_int = FR_N_float_int
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p7,p0 = FR_Floating_X, 0xc3 //@snan | @qnan
+ shl GR_Scratch = GR_Scratch,63
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p8,p0 = FR_Floating_N, 0x21 // @inf
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fclass.m p9,p0 = FR_Floating_N, 0x22 // @-inf
+ nop.i 0
+}
+;;
+
+//
+// Either X or N is a Nan, return result and possible raise invalid.
+//
+{ .mfb
+ nop.m 0
+(p6) fma.s.s0 FR_Result = FR_Floating_N,FR_Floating_X,f0
+(p6) br.ret.spnt b0
+}
+;;
+
+{ .mfb
+ nop.m 0
+(p7) fma.s.s0 FR_Result = FR_Floating_N,FR_Floating_X,f0
+(p7) br.ret.spnt b0
+}
+;;
+
+//
+// If N + Inf do something special
+// For N = -Inf, create Int
+//
+{ .mfb
+ nop.m 0
+(p8) fma.s.s0 FR_Result = FR_Floating_X, FR_Floating_N,f0
+(p8) br.ret.spnt b0
+}
+{ .mfi
+ nop.m 0
+(p9) fnma.s.s0 FR_Floating_N = FR_Floating_N, f1, f0
+ nop.i 0
+}
+;;
+
+//
+// If N==-Inf,return x/(-N)
+//
+{ .mfb
+ cmp.ne p7,p0 = GR_N_as_int,GR_Scratch
+(p9) frcpa.s0 FR_Result,p0 = FR_Floating_X,FR_Floating_N
+(p9) br.ret.spnt b0
+}
+;;
+
+//
+// Is N an integer.
+//
+{ .mfi
+ nop.m 0
+(p7) fcmp.neq.unc.s1 p7,p0 = FR_Norm_N, FR_N_float_int
+ nop.i 0
+}
+;;
+
+//
+// If N not an int, return NaN and raise invalid.
+//
+{ .mfb
+ nop.m 0
+(p7) frcpa.s0 FR_Result,p0 = f0,f0
+(p7) br.ret.spnt b0
+}
+;;
+
+//
+// Always return x in other path.
+//
+{ .mfb
+ nop.m 0
+ fma.s.s0 FR_Result = FR_Floating_X,f1,f0
+ br.ret.sptk b0
+}
+;;
+
+// Here if n not int
+// Return NaN and raise invalid.
+SCALBF_N_NOT_INT:
+{ .mfb
+ nop.m 0
+ frcpa.s0 FR_Result,p0 = f0,f0
+ br.ret.sptk b0
+}
+;;
+
+// Here if n=unorm
+SCALBF_N_UNORM:
+{ .mfb
+ getf.exp GR_signexp_N = FR_Norm_N // Get signexp of normalized n
+ fcvt.fx.trunc.s1 FR_N_float_int = FR_Norm_N // Get N in significand
+ br.cond.sptk SCALBF_COMMON1 // Return to main path
+}
+;;
+
+// Here if x=unorm
+SCALBF_X_UNORM:
+{ .mib
+ getf.exp GR_signexp_X = FR_Norm_X // Get signexp of normalized x
+ nop.i 0
+ br.cond.sptk SCALBF_COMMON2 // Return to main path
+}
+;;
+
+GLOBAL_IEEE754_END(scalbf)
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+//
+// Get stack address of N
+//
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs
+}
+//
+// Adjust sp
+//
+{ .mfi
+.fframe 64
+ add sp=-64,sp
+ nop.f 0
+ mov GR_SAVE_GP=gp
+};;
+
+//
+// Store N on stack in correct position
+// Locate the address of x on stack
+//
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Norm_N,16
+ add GR_Parameter_X = 16,sp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0
+};;
+
+//
+// Store x on the stack.
+// Get address for result on stack.
+//
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_Norm_X
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_Result
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support#
+};;
+
+//
+// Get location of result on stack
+//
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+//
+// Get the new result
+//
+{ .mmi
+ ldfs FR_Result = [GR_Parameter_RESULT]
+.restore sp
+ add sp = 64,sp
+ mov b0 = GR_SAVE_B0
+};;
+
+//
+// Restore gp, ar.pfs and return
+//
+{ .mib
+ mov gp = GR_SAVE_GP
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_scalbl.S b/libc/sysdeps/ia64/fpu/e_scalbl.S
new file mode 100644
index 000000000..9b6467ff2
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_scalbl.S
@@ -0,0 +1,599 @@
+.file "scalbl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 01/26/01 Scalb completely reworked and now standalone version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 08/06/03 Improved performance
+//
+// API
+//==============================================================
+// long double = scalbl (long double x, long double n)
+// input floating point f8 and floating point f9
+// output floating point f8
+//
+// int_type = 0 if int is 32 bits
+// int_type = 1 if int is 64 bits
+//
+// Returns x* 2**n using an fma and detects overflow
+// and underflow.
+//
+//
+// Strategy:
+// Compute biased exponent of result exp_Result = N + exp_X
+// Break into ranges:
+// exp_Result > 0x13ffe -> Certain overflow
+// exp_Result = 0x13ffe -> Possible overflow
+// 0x0c001 <= exp_Result < 0x13ffe -> No over/underflow (main path)
+// 0x0c001 - 63 <= exp_Result < 0x0c001 -> Possible underflow
+// exp_Result < 0x0c001 - 63 -> Certain underflow
+
+FR_Big = f6
+FR_NBig = f7
+FR_Floating_X = f8
+FR_Result = f8
+FR_Floating_N = f9
+FR_Result2 = f9
+FR_Result3 = f10
+FR_Norm_X = f11
+FR_Two_N = f12
+FR_N_float_int = f13
+FR_Norm_N = f14
+
+GR_neg_ov_limit= r14
+GR_big_exp = r14
+GR_N_Biased = r15
+GR_Big = r16
+GR_exp_Result = r18
+GR_pos_ov_limit= r19
+GR_exp_sure_ou = r19
+GR_Bias = r20
+GR_N_as_int = r21
+GR_signexp_X = r22
+GR_exp_X = r23
+GR_exp_mask = r24
+GR_max_exp = r25
+GR_min_exp = r26
+GR_min_den_exp = r27
+GR_Scratch = r28
+GR_signexp_N = r29
+GR_exp_N = r30
+
+GR_SAVE_B0 = r32
+GR_SAVE_GP = r33
+GR_SAVE_PFS = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Tag = r38
+
+.section .text
+GLOBAL_IEEE754_ENTRY(scalbl)
+
+//
+// Is x NAN, INF, ZERO, +-?
+// Build the exponent Bias
+//
+{ .mfi
+ getf.exp GR_signexp_N = FR_Floating_N // Get signexp of n
+ fclass.m p6,p0 = FR_Floating_X, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_Bias = 0x0ffff
+}
+{ .mfi
+ mov GR_Big = 35000 // If N this big then certain overflow
+ fcvt.fx.trunc.s1 FR_N_float_int = FR_Floating_N // Get N in significand
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.exp GR_signexp_X = FR_Floating_X // Get signexp of x
+ fclass.m p7,p0 = FR_Floating_N, 0x0b // Test for n=unorm
+ nop.i 0
+}
+//
+// Normalize n
+//
+{ .mfi
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+ fnorm.s1 FR_Norm_N = FR_Floating_N
+ nop.i 0
+}
+;;
+
+//
+// Is n NAN, INF, ZERO, +-?
+//
+{ .mfi
+ mov GR_big_exp = 0x1003e // Exponent at which n is integer
+ fclass.m p9,p0 = FR_Floating_N, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_max_exp = 0x13ffe // Exponent of maximum long double
+}
+//
+// Normalize x
+//
+{ .mfb
+ nop.m 0
+ fnorm.s1 FR_Norm_X = FR_Floating_X
+(p7) br.cond.spnt SCALBL_N_UNORM // Branch if n=unorm
+}
+;;
+
+SCALBL_COMMON1:
+// Main path continues. Also return here from u=unorm path.
+// Handle special cases if x = Nan, Inf, Zero
+{ .mfb
+ nop.m 0
+ fcmp.lt.s1 p7,p0 = FR_Floating_N, f0 // Test N negative
+(p6) br.cond.spnt SCALBL_NAN_INF_ZERO
+}
+;;
+
+// Handle special cases if n = Nan, Inf, Zero
+{ .mfi
+ getf.sig GR_N_as_int = FR_N_float_int // Get n from significand
+ fclass.m p8,p0 = FR_Floating_X, 0x0b // Test for x=unorm
+ mov GR_exp_sure_ou = 0x1000e // Exp_N where x*2^N sure over/under
+}
+{ .mfb
+ mov GR_min_exp = 0x0c001 // Exponent of minimum long double
+ fcvt.xf FR_N_float_int = FR_N_float_int // Convert N to FP integer
+(p9) br.cond.spnt SCALBL_NAN_INF_ZERO
+}
+;;
+
+{ .mmi
+ and GR_exp_N = GR_exp_mask, GR_signexp_N // Get exponent of N
+(p7) sub GR_Big = r0, GR_Big // Limit for N
+ nop.i 0
+}
+;;
+
+{ .mib
+ cmp.lt p9,p0 = GR_exp_N, GR_big_exp // N possible non-integer?
+ cmp.ge p6,p0 = GR_exp_N, GR_exp_sure_ou // N certain over/under?
+(p8) br.cond.spnt SCALBL_X_UNORM // Branch if x=unorm
+}
+;;
+
+SCALBL_COMMON2:
+// Main path continues. Also return here from x=unorm path.
+// Create biased exponent for 2**N
+{ .mmi
+(p6) mov GR_N_as_int = GR_Big // Limit N
+;;
+ add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp FR_Two_N = GR_N_Biased // Form 2**N
+(p9) fcmp.neq.unc.s1 p9,p0 = FR_Norm_N, FR_N_float_int // Test if N an integer
+ and GR_exp_X = GR_exp_mask, GR_signexp_X // Get exponent of X
+}
+;;
+
+//
+// Compute biased result exponent
+// Branch if N is not an integer
+//
+{ .mib
+ add GR_exp_Result = GR_exp_X, GR_N_as_int
+ mov GR_min_den_exp = 0x0c001 - 63 // Exp of min denorm long dble
+(p9) br.cond.spnt SCALBL_N_NOT_INT
+}
+;;
+
+//
+// Raise Denormal operand flag with compare
+// Do final operation
+//
+{ .mfi
+ cmp.lt p7,p6 = GR_exp_Result, GR_max_exp // Test no overflow
+ fcmp.ge.s0 p0,p11 = FR_Floating_X,FR_Floating_N // Dummy to set denorm
+ cmp.lt p9,p0 = GR_exp_Result, GR_min_den_exp // Test sure underflow
+}
+{ .mfb
+ nop.m 0
+ fma.s0 FR_Result = FR_Two_N,FR_Norm_X,f0
+(p9) br.cond.spnt SCALBL_UNDERFLOW // Branch if certain underflow
+}
+;;
+
+{ .mib
+(p6) cmp.gt.unc p6,p8 = GR_exp_Result, GR_max_exp // Test sure overflow
+(p7) cmp.ge.unc p7,p9 = GR_exp_Result, GR_min_exp // Test no over/underflow
+(p7) br.ret.sptk b0 // Return from main path
+}
+;;
+
+{ .bbb
+(p6) br.cond.spnt SCALBL_OVERFLOW // Branch if certain overflow
+(p8) br.cond.spnt SCALBL_POSSIBLE_OVERFLOW // Branch if possible overflow
+(p9) br.cond.spnt SCALBL_POSSIBLE_UNDERFLOW // Branch if possible underflow
+}
+;;
+
+// Here if possible underflow.
+// Resulting exponent: 0x0c001-63 <= exp_Result < 0x0c001
+SCALBL_POSSIBLE_UNDERFLOW:
+//
+// Here if possible overflow.
+// Resulting exponent: 0x13ffe = exp_Result
+SCALBL_POSSIBLE_OVERFLOW:
+
+// Set up necessary status fields
+//
+// S0 user supplied status
+// S2 user supplied status + WRE + TD (Overflows)
+// S3 user supplied status + FZ + TD (Underflows)
+//
+{ .mfi
+ mov GR_pos_ov_limit = 0x13fff // Exponent for positive overflow
+ fsetc.s3 0x7F,0x41
+ nop.i 0
+}
+{ .mfi
+ mov GR_neg_ov_limit = 0x33fff // Exponent for negative overflow
+ fsetc.s2 0x7F,0x42
+ nop.i 0
+}
+;;
+
+//
+// Do final operation with s2 and s3
+//
+{ .mfi
+ setf.exp FR_NBig = GR_neg_ov_limit
+ fma.s3 FR_Result3 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+{ .mfi
+ setf.exp FR_Big = GR_pos_ov_limit
+ fma.s2 FR_Result2 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+;;
+
+// Check for overflow or underflow.
+// Restore s3
+// Restore s2
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x40
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40
+ nop.i 0
+}
+;;
+
+//
+// Is the result zero?
+//
+{ .mfi
+ nop.m 0
+ fclass.m p6, p0 = FR_Result3, 0x007
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p7, p8 = FR_Result2 , FR_Big
+ nop.i 0
+}
+;;
+
+//
+// Detect masked underflow - Tiny + Inexact Only
+//
+{ .mfi
+ nop.m 0
+(p6) fcmp.neq.unc.s1 p6, p0 = FR_Result , FR_Result2
+ nop.i 0
+}
+;;
+
+//
+// Is result bigger the allowed range?
+// Branch out for underflow
+//
+{ .mfb
+ nop.m 0
+(p8) fcmp.le.unc.s1 p9, p10 = FR_Result2 , FR_NBig
+(p6) br.cond.spnt SCALBL_UNDERFLOW
+}
+;;
+
+//
+// Branch out for overflow
+//
+{ .bbb
+(p7) br.cond.spnt SCALBL_OVERFLOW
+(p9) br.cond.spnt SCALBL_OVERFLOW
+ br.ret.sptk b0 // Return from main path.
+}
+;;
+
+// Here if result overflows
+SCALBL_OVERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 51, r0 // Set error tag for overflow
+ br.cond.sptk __libm_error_region // Call error support for overflow
+}
+;;
+
+// Here if result underflows
+SCALBL_UNDERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 52, r0 // Set error tag for underflow
+ br.cond.sptk __libm_error_region // Call error support for underflow
+}
+;;
+
+SCALBL_NAN_INF_ZERO:
+
+//
+// Before entry, N has been converted to a fp integer in significand of
+// FR_N_float_int
+//
+// Convert N_float_int to floating point value
+//
+{ .mfi
+ getf.sig GR_N_as_int = FR_N_float_int
+ fclass.m p6,p0 = FR_Floating_N, 0xc3 //@snan | @qnan
+ nop.i 0
+}
+{ .mfi
+ addl GR_Scratch = 1,r0
+ fcvt.xf FR_N_float_int = FR_N_float_int
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p7,p0 = FR_Floating_X, 0xc3 //@snan | @qnan
+ shl GR_Scratch = GR_Scratch,63
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p8,p0 = FR_Floating_N, 0x21 // @inf
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fclass.m p9,p0 = FR_Floating_N, 0x22 // @-inf
+ nop.i 0
+}
+;;
+
+//
+// Either X or N is a Nan, return result and possible raise invalid.
+//
+{ .mfb
+ nop.m 0
+(p6) fma.s0 FR_Result = FR_Floating_N,FR_Floating_X,f0
+(p6) br.ret.spnt b0
+}
+;;
+
+{ .mfb
+ nop.m 0
+(p7) fma.s0 FR_Result = FR_Floating_N,FR_Floating_X,f0
+(p7) br.ret.spnt b0
+}
+;;
+
+//
+// If N + Inf do something special
+// For N = -Inf, create Int
+//
+{ .mfb
+ nop.m 0
+(p8) fma.s0 FR_Result = FR_Floating_X, FR_Floating_N,f0
+(p8) br.ret.spnt b0
+}
+{ .mfi
+ nop.m 0
+(p9) fnma.s0 FR_Floating_N = FR_Floating_N, f1, f0
+ nop.i 0
+}
+;;
+
+//
+// If N==-Inf,return x/(-N)
+//
+{ .mfb
+ cmp.ne p7,p0 = GR_N_as_int,GR_Scratch
+(p9) frcpa.s0 FR_Result,p0 = FR_Floating_X,FR_Floating_N
+(p9) br.ret.spnt b0
+}
+;;
+
+//
+// Is N an integer.
+//
+{ .mfi
+ nop.m 0
+(p7) fcmp.neq.unc.s1 p7,p0 = FR_Norm_N, FR_N_float_int
+ nop.i 0
+}
+;;
+
+//
+// If N not an int, return NaN and raise invalid.
+//
+{ .mfb
+ nop.m 0
+(p7) frcpa.s0 FR_Result,p0 = f0,f0
+(p7) br.ret.spnt b0
+}
+;;
+
+//
+// Always return x in other path.
+//
+{ .mfb
+ nop.m 0
+ fma.s0 FR_Result = FR_Floating_X,f1,f0
+ br.ret.sptk b0
+}
+;;
+
+// Here if n not int
+// Return NaN and raise invalid.
+SCALBL_N_NOT_INT:
+{ .mfb
+ nop.m 0
+ frcpa.s0 FR_Result,p0 = f0,f0
+ br.ret.sptk b0
+}
+;;
+
+// Here if n=unorm
+SCALBL_N_UNORM:
+{ .mfb
+ getf.exp GR_signexp_N = FR_Norm_N // Get signexp of normalized n
+ fcvt.fx.trunc.s1 FR_N_float_int = FR_Norm_N // Get N in significand
+ br.cond.sptk SCALBL_COMMON1 // Return to main path
+}
+;;
+
+// Here if x=unorm
+SCALBL_X_UNORM:
+{ .mib
+ getf.exp GR_signexp_X = FR_Norm_X // Get signexp of normalized x
+ nop.i 0
+ br.cond.sptk SCALBL_COMMON2 // Return to main path
+}
+;;
+
+GLOBAL_IEEE754_END(scalbl)
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+//
+// Get stack address of N
+//
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs
+}
+//
+// Adjust sp
+//
+{ .mfi
+.fframe 64
+ add sp=-64,sp
+ nop.f 0
+ mov GR_SAVE_GP=gp
+};;
+
+//
+// Store N on stack in correct position
+// Locate the address of x on stack
+//
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Norm_N,16
+ add GR_Parameter_X = 16,sp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0
+};;
+
+//
+// Store x on the stack.
+// Get address for result on stack.
+//
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_Norm_X
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_Result
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support#
+};;
+
+//
+// Get location of result on stack
+//
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+//
+// Get the new result
+//
+{ .mmi
+ ldfe FR_Result = [GR_Parameter_RESULT]
+.restore sp
+ add sp = 64,sp
+ mov b0 = GR_SAVE_B0
+};;
+
+//
+// Restore gp, ar.pfs and return
+//
+{ .mib
+ mov gp = GR_SAVE_GP
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_sinh.S b/libc/sysdeps/ia64/fpu/e_sinh.S
new file mode 100644
index 000000000..f60907b72
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_sinh.S
@@ -0,0 +1,905 @@
+.file "sinh.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 10/12/00 Update to set denormal operand and underflow flags
+// 01/22/01 Fixed to set inexact flag for small args.
+// 05/02/01 Reworked to improve speed of all paths
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 11/20/02 Improved speed with new algorithm
+// 03/31/05 Reformatted delimiters between data tables
+
+// API
+//==============================================================
+// double sinh(double)
+
+// Overview of operation
+//==============================================================
+// Case 1: 0 < |x| < 2^-60
+// Result = x, computed by x+sgn(x)*x^2) to handle flags and rounding
+//
+// Case 2: 2^-60 < |x| < 0.25
+// Evaluate sinh(x) by a 13th order polynomial
+// Care is take for the order of multiplication; and A1 is not exactly 1/3!,
+// A2 is not exactly 1/5!, etc.
+// sinh(x) = x + (A1*x^3 + A2*x^5 + A3*x^7 + A4*x^9 + A5*x^11 + A6*x^13)
+//
+// Case 3: 0.25 < |x| < 710.47586
+// Algorithm is based on the identity sinh(x) = ( exp(x) - exp(-x) ) / 2.
+// The algorithm for exp is described as below. There are a number of
+// economies from evaluating both exp(x) and exp(-x). Although we
+// are evaluating both quantities, only where the quantities diverge do we
+// duplicate the computations. The basic algorithm for exp(x) is described
+// below.
+//
+// Take the input x. w is "how many log2/128 in x?"
+// w = x * 128/log2
+// n = int(w)
+// x = n log2/128 + r + delta
+
+// n = 128M + index_1 + 2^4 index_2
+// x = M log2 + (log2/128) index_1 + (log2/8) index_2 + r + delta
+
+// exp(x) = 2^M 2^(index_1/128) 2^(index_2/8) exp(r) exp(delta)
+// Construct 2^M
+// Get 2^(index_1/128) from table_1;
+// Get 2^(index_2/8) from table_2;
+// Calculate exp(r) by 5th order polynomial
+// r = x - n (log2/128)_high
+// delta = - n (log2/128)_low
+// Calculate exp(delta) as 1 + delta
+
+
+// Special values
+//==============================================================
+// sinh(+0) = +0
+// sinh(-0) = -0
+
+// sinh(+qnan) = +qnan
+// sinh(-qnan) = -qnan
+// sinh(+snan) = +qnan
+// sinh(-snan) = -qnan
+
+// sinh(-inf) = -inf
+// sinh(+inf) = +inf
+
+// Overflow and Underflow
+//=======================
+// sinh(x) = largest double normal when
+// |x| = 710.47586 = 0x408633ce8fb9f87d
+//
+// Underflow is handled as described in case 1 above
+
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input, output
+// f6 -> f15, f32 -> f61
+
+// General registers used:
+// r14 -> r40
+
+// Predicate registers used:
+// p6 -> p15
+
+// Assembly macros
+//==============================================================
+
+rRshf = r14
+rN_neg = r14
+rAD_TB1 = r15
+rAD_TB2 = r16
+rAD_P = r17
+rN = r18
+rIndex_1 = r19
+rIndex_2_16 = r20
+rM = r21
+rBiased_M = r21
+rSig_inv_ln2 = r22
+rIndex_1_neg = r22
+rExp_bias = r23
+rExp_bias_minus_1 = r23
+rExp_mask = r24
+rTmp = r24
+rGt_ln = r24
+rIndex_2_16_neg = r24
+rM_neg = r25
+rBiased_M_neg = r25
+rRshf_2to56 = r26
+rAD_T1_neg = r26
+rExp_2tom56 = r28
+rAD_T2_neg = r28
+rAD_T1 = r29
+rAD_T2 = r30
+rSignexp_x = r31
+rExp_x = r31
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+fRSHF_2TO56 = f6
+fINV_LN2_2TO63 = f7
+fW_2TO56_RSH = f9
+f2TOM56 = f11
+fP5 = f12
+fP4 = f13
+fP3 = f14
+fP2 = f15
+
+fLn2_by_128_hi = f33
+fLn2_by_128_lo = f34
+
+fRSHF = f35
+fNfloat = f36
+fNormX = f37
+fR = f38
+fF = f39
+
+fRsq = f40
+f2M = f41
+fS1 = f42
+fT1 = f42
+fS2 = f43
+fT2 = f43
+fS = f43
+fWre_urm_f8 = f44
+fAbsX = f44
+
+fMIN_DBL_OFLOW_ARG = f45
+fMAX_DBL_NORM_ARG = f46
+fXsq = f47
+fX4 = f48
+fGt_pln = f49
+fTmp = f49
+
+fP54 = f50
+fP5432 = f50
+fP32 = f51
+fP = f52
+fP54_neg = f53
+fP5432_neg = f53
+fP32_neg = f54
+fP_neg = f55
+fF_neg = f56
+
+f2M_neg = f57
+fS1_neg = f58
+fT1_neg = f58
+fS2_neg = f59
+fT2_neg = f59
+fS_neg = f59
+fExp = f60
+fExp_neg = f61
+
+fA6 = f50
+fA65 = f50
+fA6543 = f50
+fA654321 = f50
+fA5 = f51
+fA4 = f52
+fA43 = f52
+fA3 = f53
+fA2 = f54
+fA21 = f54
+fA1 = f55
+fX3 = f56
+
+// Data tables
+//==============================================================
+
+RODATA
+.align 16
+
+// ************* DO NOT CHANGE ORDER OF THESE TABLES ********************
+
+// double-extended 1/ln(2)
+// 3fff b8aa 3b29 5c17 f0bb be87fed0691d3e88
+// 3fff b8aa 3b29 5c17 f0bc
+// For speed the significand will be loaded directly with a movl and setf.sig
+// and the exponent will be bias+63 instead of bias+0. Thus subsequent
+// computations need to scale appropriately.
+// The constant 128/ln(2) is needed for the computation of w. This is also
+// obtained by scaling the computations.
+//
+// Two shifting constants are loaded directly with movl and setf.d.
+// 1. fRSHF_2TO56 = 1.1000..00 * 2^(63-7)
+// This constant is added to x*1/ln2 to shift the integer part of
+// x*128/ln2 into the rightmost bits of the significand.
+// The result of this fma is fW_2TO56_RSH.
+// 2. fRSHF = 1.1000..00 * 2^(63)
+// This constant is subtracted from fW_2TO56_RSH * 2^(-56) to give
+// the integer part of w, n, as a floating-point number.
+// The result of this fms is fNfloat.
+
+
+LOCAL_OBJECT_START(exp_table_1)
+data8 0x408633ce8fb9f87e // smallest dbl overflow arg
+data8 0x408633ce8fb9f87d // largest dbl arg to give normal dbl result
+data8 0xb17217f7d1cf79ab , 0x00003ff7 // ln2/128 hi
+data8 0xc9e3b39803f2f6af , 0x00003fb7 // ln2/128 lo
+//
+// Table 1 is 2^(index_1/128) where
+// index_1 goes from 0 to 15
+//
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x80B1ED4FD999AB6C , 0x00003FFF
+data8 0x8164D1F3BC030773 , 0x00003FFF
+data8 0x8218AF4373FC25EC , 0x00003FFF
+data8 0x82CD8698AC2BA1D7 , 0x00003FFF
+data8 0x8383594EEFB6EE37 , 0x00003FFF
+data8 0x843A28C3ACDE4046 , 0x00003FFF
+data8 0x84F1F656379C1A29 , 0x00003FFF
+data8 0x85AAC367CC487B15 , 0x00003FFF
+data8 0x8664915B923FBA04 , 0x00003FFF
+data8 0x871F61969E8D1010 , 0x00003FFF
+data8 0x87DB357FF698D792 , 0x00003FFF
+data8 0x88980E8092DA8527 , 0x00003FFF
+data8 0x8955EE03618E5FDD , 0x00003FFF
+data8 0x8A14D575496EFD9A , 0x00003FFF
+data8 0x8AD4C6452C728924 , 0x00003FFF
+LOCAL_OBJECT_END(exp_table_1)
+
+// Table 2 is 2^(index_1/8) where
+// index_2 goes from 0 to 7
+LOCAL_OBJECT_START(exp_table_2)
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x8B95C1E3EA8BD6E7 , 0x00003FFF
+data8 0x9837F0518DB8A96F , 0x00003FFF
+data8 0xA5FED6A9B15138EA , 0x00003FFF
+data8 0xB504F333F9DE6484 , 0x00003FFF
+data8 0xC5672A115506DADD , 0x00003FFF
+data8 0xD744FCCAD69D6AF4 , 0x00003FFF
+data8 0xEAC0C6E7DD24392F , 0x00003FFF
+LOCAL_OBJECT_END(exp_table_2)
+
+
+LOCAL_OBJECT_START(exp_p_table)
+data8 0x3f8111116da21757 //P5
+data8 0x3fa55555d787761c //P4
+data8 0x3fc5555555555414 //P3
+data8 0x3fdffffffffffd6a //P2
+LOCAL_OBJECT_END(exp_p_table)
+
+LOCAL_OBJECT_START(sinh_p_table)
+data8 0xB08AF9AE78C1239F, 0x00003FDE // A6
+data8 0xB8EF1D28926D8891, 0x00003FEC // A4
+data8 0x8888888888888412, 0x00003FF8 // A2
+data8 0xD732377688025BE9, 0x00003FE5 // A5
+data8 0xD00D00D00D4D39F2, 0x00003FF2 // A3
+data8 0xAAAAAAAAAAAAAAAB, 0x00003FFC // A1
+LOCAL_OBJECT_END(sinh_p_table)
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(sinh)
+
+{ .mlx
+ getf.exp rSignexp_x = f8 // Must recompute if x unorm
+ movl rSig_inv_ln2 = 0xb8aa3b295c17f0bc // significand of 1/ln2
+}
+{ .mlx
+ addl rAD_TB1 = @ltoff(exp_table_1), gp
+ movl rRshf_2to56 = 0x4768000000000000 // 1.10000 2^(63+56)
+}
+;;
+
+{ .mfi
+ ld8 rAD_TB1 = [rAD_TB1]
+ fclass.m p6,p0 = f8,0x0b // Test for x=unorm
+ mov rExp_mask = 0x1ffff
+}
+{ .mfi
+ mov rExp_bias = 0xffff
+ fnorm.s1 fNormX = f8
+ mov rExp_2tom56 = 0xffff-56
+}
+;;
+
+// Form two constants we need
+// 1/ln2 * 2^63 to compute w = x * 1/ln2 * 128
+// 1.1000..000 * 2^(63+63-7) to right shift int(w) into the significand
+
+{ .mfi
+ setf.sig fINV_LN2_2TO63 = rSig_inv_ln2 // form 1/ln2 * 2^63
+ fclass.m p8,p0 = f8,0x07 // Test for x=0
+ nop.i 999
+}
+{ .mlx
+ setf.d fRSHF_2TO56 = rRshf_2to56 // Form const 1.100 * 2^(63+56)
+ movl rRshf = 0x43e8000000000000 // 1.10000 2^63 for right shift
+}
+;;
+
+{ .mfi
+ ldfpd fMIN_DBL_OFLOW_ARG, fMAX_DBL_NORM_ARG = [rAD_TB1],16
+ fclass.m p10,p0 = f8,0x1e3 // Test for x=inf, nan, NaT
+ nop.i 0
+}
+{ .mfb
+ setf.exp f2TOM56 = rExp_2tom56 // form 2^-56 for scaling Nfloat
+ nop.f 0
+(p6) br.cond.spnt SINH_UNORM // Branch if x=unorm
+}
+;;
+
+SINH_COMMON:
+{ .mfi
+ ldfe fLn2_by_128_hi = [rAD_TB1],16
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+ setf.d fRSHF = rRshf // Form right shift const 1.100 * 2^63
+ nop.f 0
+(p8) br.ret.spnt b0 // Exit for x=0, result=x
+}
+;;
+
+{ .mfi
+ ldfe fLn2_by_128_lo = [rAD_TB1],16
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+ and rExp_x = rExp_mask, rSignexp_x // Biased exponent of x
+(p10) fma.d.s0 f8 = f8,f1,f0 // Result if x=inf, nan, NaT
+(p10) br.ret.spnt b0 // quick exit for x=inf, nan, NaT
+}
+;;
+
+// After that last load rAD_TB1 points to the beginning of table 1
+{ .mfi
+ nop.m 0
+ fcmp.eq.s0 p6,p0 = f8, f0 // Dummy to set D
+ sub rExp_x = rExp_x, rExp_bias // True exponent of x
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fmerge.s fAbsX = f0, fNormX // Form |x|
+ nop.i 0
+}
+{ .mfb
+ cmp.gt p7, p0 = -2, rExp_x // Test |x| < 2^(-2)
+ fma.s1 fXsq = fNormX, fNormX, f0 // x*x for small path
+(p7) br.cond.spnt SINH_SMALL // Branch if 0 < |x| < 2^-2
+}
+;;
+
+// W = X * Inv_log2_by_128
+// By adding 1.10...0*2^63 we shift and get round_int(W) in significand.
+// We actually add 1.10...0*2^56 to X * Inv_log2 to do the same thing.
+
+{ .mfi
+ add rAD_P = 0x180, rAD_TB1
+ fma.s1 fW_2TO56_RSH = fNormX, fINV_LN2_2TO63, fRSHF_2TO56
+ add rAD_TB2 = 0x100, rAD_TB1
+}
+;;
+
+// Divide arguments into the following categories:
+// Certain Safe - 0.25 <= |x| <= MAX_DBL_NORM_ARG
+// Possible Overflow p14 - MAX_DBL_NORM_ARG < |x| < MIN_DBL_OFLOW_ARG
+// Certain Overflow p15 - MIN_DBL_OFLOW_ARG <= |x| < +inf
+//
+// If the input is really a double arg, then there will never be
+// "Possible Overflow" arguments.
+//
+
+{ .mfi
+ ldfpd fP5, fP4 = [rAD_P] ,16
+ fcmp.ge.s1 p15,p14 = fAbsX,fMIN_DBL_OFLOW_ARG
+ nop.i 0
+}
+;;
+
+// Nfloat = round_int(W)
+// The signficand of fW_2TO56_RSH contains the rounded integer part of W,
+// as a twos complement number in the lower bits (that is, it may be negative).
+// That twos complement number (called N) is put into rN.
+
+// Since fW_2TO56_RSH is scaled by 2^56, it must be multiplied by 2^-56
+// before the shift constant 1.10000 * 2^63 is subtracted to yield fNfloat.
+// Thus, fNfloat contains the floating point version of N
+
+{ .mfi
+ ldfpd fP3, fP2 = [rAD_P]
+(p14) fcmp.gt.unc.s1 p14,p0 = fAbsX,fMAX_DBL_NORM_ARG
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fms.s1 fNfloat = fW_2TO56_RSH, f2TOM56, fRSHF
+(p15) br.cond.spnt SINH_CERTAIN_OVERFLOW
+}
+;;
+
+{ .mfi
+ getf.sig rN = fW_2TO56_RSH
+ nop.f 0
+ mov rExp_bias_minus_1 = 0xfffe
+}
+;;
+
+// rIndex_1 has index_1
+// rIndex_2_16 has index_2 * 16
+// rBiased_M has M
+
+// rM has true M
+// r = x - Nfloat * ln2_by_128_hi
+// f = 1 - Nfloat * ln2_by_128_lo
+{ .mfi
+ and rIndex_1 = 0x0f, rN
+ fnma.s1 fR = fNfloat, fLn2_by_128_hi, fNormX
+ shr rM = rN, 0x7
+}
+{ .mfi
+ and rIndex_2_16 = 0x70, rN
+ fnma.s1 fF = fNfloat, fLn2_by_128_lo, f1
+ sub rN_neg = r0, rN
+}
+;;
+
+{ .mmi
+ and rIndex_1_neg = 0x0f, rN_neg
+ add rBiased_M = rExp_bias_minus_1, rM
+ shr rM_neg = rN_neg, 0x7
+}
+{ .mmi
+ and rIndex_2_16_neg = 0x70, rN_neg
+ add rAD_T2 = rAD_TB2, rIndex_2_16
+ shladd rAD_T1 = rIndex_1, 4, rAD_TB1
+}
+;;
+
+// rAD_T1 has address of T1
+// rAD_T2 has address if T2
+
+{ .mmi
+ setf.exp f2M = rBiased_M
+ ldfe fT2 = [rAD_T2]
+ nop.i 0
+}
+{ .mmi
+ add rBiased_M_neg = rExp_bias_minus_1, rM_neg
+ add rAD_T2_neg = rAD_TB2, rIndex_2_16_neg
+ shladd rAD_T1_neg = rIndex_1_neg, 4, rAD_TB1
+}
+;;
+
+// Create Scale = 2^M
+// Load T1 and T2
+{ .mmi
+ ldfe fT1 = [rAD_T1]
+ nop.m 0
+ nop.i 0
+}
+{ .mmf
+ setf.exp f2M_neg = rBiased_M_neg
+ ldfe fT2_neg = [rAD_T2_neg]
+ fma.s1 fF_neg = fNfloat, fLn2_by_128_lo, f1
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRsq = fR, fR, f0
+ nop.i 0
+}
+{ .mfi
+ ldfe fT1_neg = [rAD_T1_neg]
+ fma.s1 fP54 = fR, fP5, fP4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP32 = fR, fP3, fP2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 fP54_neg = fR, fP5, fP4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 fP32_neg = fR, fP3, fP2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP5432 = fRsq, fP54, fP32
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS2 = fF,fT2,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fS1 = f2M,fT1,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fP5432_neg = fRsq, fP54_neg, fP32_neg
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fS1_neg = f2M_neg,fT1_neg,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS2_neg = fF_neg,fT2_neg,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP = fRsq, fP5432, fR
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS = fS1,fS2,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fP_neg = fRsq, fP5432_neg, fR
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS_neg = fS1_neg,fS2_neg,f0
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fmpy.s0 fTmp = fLn2_by_128_lo, fLn2_by_128_lo // Force inexact
+(p14) br.cond.spnt SINH_POSSIBLE_OVERFLOW
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fExp = fS, fP, fS
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fExp_neg = fS_neg, fP_neg, fS_neg
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fms.d.s0 f8 = fExp, f1, fExp_neg
+ br.ret.sptk b0 // Normal path exit
+}
+;;
+
+// Here if 0 < |x| < 0.25
+SINH_SMALL:
+{ .mfi
+ add rAD_T1 = 0x1a0, rAD_TB1
+ fcmp.lt.s1 p7, p8 = fNormX, f0 // Test sign of x
+ cmp.gt p6, p0 = -60, rExp_x // Test |x| < 2^(-60)
+}
+{ .mfi
+ add rAD_T2 = 0x1d0, rAD_TB1
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mmb
+ ldfe fA6 = [rAD_T1],16
+ ldfe fA5 = [rAD_T2],16
+(p6) br.cond.spnt SINH_VERY_SMALL // Branch if |x| < 2^(-60)
+}
+;;
+
+{ .mmi
+ ldfe fA4 = [rAD_T1],16
+ ldfe fA3 = [rAD_T2],16
+ nop.i 0
+}
+;;
+
+{ .mmi
+ ldfe fA2 = [rAD_T1]
+ ldfe fA1 = [rAD_T2]
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fX3 = fNormX, fXsq, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fX4 = fXsq, fXsq, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA65 = fXsq, fA6, fA5
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA43 = fXsq, fA4, fA3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA21 = fXsq, fA2, fA1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA6543 = fX4, fA65, fA43
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA654321 = fX4, fA6543, fA21
+ nop.i 0
+}
+;;
+
+// Dummy multiply to generate inexact
+{ .mfi
+ nop.m 0
+ fmpy.s0 fTmp = fA6, fA6
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fA654321, fX3, fNormX
+ br.ret.sptk b0 // Exit if 2^-60 < |x| < 0.25
+}
+;;
+
+SINH_VERY_SMALL:
+// Here if 0 < |x| < 2^-60
+// Compute result by x + sgn(x)*x^2 to get properly rounded result
+.pred.rel "mutex",p7,p8
+{ .mfi
+ nop.m 0
+(p7) fnma.d.s0 f8 = fNormX, fNormX, fNormX // If x<0 result ~ x-x^2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fma.d.s0 f8 = fNormX, fNormX, fNormX // If x>0 result ~ x+x^2
+ br.ret.sptk b0 // Exit if |x| < 2^-60
+}
+;;
+
+
+SINH_POSSIBLE_OVERFLOW:
+
+// Here if fMAX_DBL_NORM_ARG < |x| < fMIN_DBL_OFLOW_ARG
+// This cannot happen if input is a double, only if input higher precision.
+// Overflow is a possibility, not a certainty.
+
+// Recompute result using status field 2 with user's rounding mode,
+// and wre set. If result is larger than largest double, then we have
+// overflow
+
+{ .mfi
+ mov rGt_ln = 0x103ff // Exponent for largest dbl + 1 ulp
+ fsetc.s2 0x7F,0x42 // Get user's round mode, set wre
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp fGt_pln = rGt_ln // Create largest double + 1 ulp
+ fma.d.s2 fWre_urm_f8 = fS, fP, fS // Result with wre set
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40 // Turn off wre in sf2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p6, p0 = fWre_urm_f8, fGt_pln // Test for overflow
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p6) br.cond.spnt SINH_CERTAIN_OVERFLOW // Branch if overflow
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fS, fP, fS
+ br.ret.sptk b0 // Exit if really no overflow
+}
+;;
+
+SINH_CERTAIN_OVERFLOW:
+{ .mfi
+ sub rTmp = rExp_mask, r0, 1
+ fcmp.lt.s1 p6, p7 = fNormX, f0 // Test for x < 0
+ nop.i 0
+}
+;;
+
+{ .mmf
+ alloc r32=ar.pfs,1,4,4,0
+ setf.exp fTmp = rTmp
+ fmerge.s FR_X = f8,f8
+}
+;;
+
+{ .mfi
+ mov GR_Parameter_TAG = 127
+(p6) fnma.d.s0 FR_RESULT = fTmp, fTmp, f0 // Set I,O and -INF result
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.d.s0 FR_RESULT = fTmp, fTmp, f0 // Set I,O and +INF result
+ br.cond.sptk __libm_error_region
+}
+;;
+
+// Here if x unorm
+SINH_UNORM:
+{ .mfb
+ getf.exp rSignexp_x = fNormX // Must recompute if x unorm
+ fcmp.eq.s0 p6, p0 = f8, f0 // Set D flag
+ br.cond.sptk SINH_COMMON
+}
+;;
+
+GLOBAL_IEEE754_END(sinh)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_sinhf.S b/libc/sysdeps/ia64/fpu/e_sinhf.S
new file mode 100644
index 000000000..6d808cb47
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_sinhf.S
@@ -0,0 +1,748 @@
+.file "sinhf.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+
+// History
+//*********************************************************************
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 10/12/00 Update to set denormal operand and underflow flags
+// 01/22/01 Fixed to set inexact flag for small args.
+// 05/02/01 Reworked to improve speed of all paths
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 11/20/02 Improved algorithm based on expf
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//*********************************************************************
+// float sinhf(float)
+//
+// Overview of operation
+//*********************************************************************
+// Case 1: 0 < |x| < 2^-60
+// Result = x, computed by x+sgn(x)*x^2) to handle flags and rounding
+//
+// Case 2: 2^-60 < |x| < 0.25
+// Evaluate sinh(x) by a 9th order polynomial
+// Care is take for the order of multiplication; and A2 is not exactly 1/5!,
+// A3 is not exactly 1/7!, etc.
+// sinh(x) = x + (A1*x^3 + A2*x^5 + A3*x^7 + A4*x^9)
+//
+// Case 3: 0.25 < |x| < 89.41598
+// Algorithm is based on the identity sinh(x) = ( exp(x) - exp(-x) ) / 2.
+// The algorithm for exp is described as below. There are a number of
+// economies from evaluating both exp(x) and exp(-x). Although we
+// are evaluating both quantities, only where the quantities diverge do we
+// duplicate the computations. The basic algorithm for exp(x) is described
+// below.
+//
+// Take the input x. w is "how many log2/128 in x?"
+// w = x * 64/log2
+// NJ = int(w)
+// x = NJ*log2/64 + R
+
+// NJ = 64*n + j
+// x = n*log2 + (log2/64)*j + R
+//
+// So, exp(x) = 2^n * 2^(j/64)* exp(R)
+//
+// T = 2^n * 2^(j/64)
+// Construct 2^n
+// Get 2^(j/64) table
+// actually all the entries of 2^(j/64) table are stored in DP and
+// with exponent bits set to 0 -> multiplication on 2^n can be
+// performed by doing logical "or" operation with bits presenting 2^n
+
+// exp(R) = 1 + (exp(R) - 1)
+// P = exp(R) - 1 approximated by Taylor series of 3rd degree
+// P = A3*R^3 + A2*R^2 + R, A3 = 1/6, A2 = 1/2
+//
+
+// The final result is reconstructed as follows
+// exp(x) = T + T*P
+
+// Special values
+//*********************************************************************
+// sinhf(+0) = +0
+// sinhf(-0) = -0
+
+// sinhf(+qnan) = +qnan
+// sinhf(-qnan) = -qnan
+// sinhf(+snan) = +qnan
+// sinhf(-snan) = -qnan
+
+// sinhf(-inf) = -inf
+// sinhf(+inf) = +inf
+
+// Overflow and Underflow
+//*********************************************************************
+// sinhf(x) = largest single normal when
+// x = 89.41598 = 0x42b2d4fc
+//
+// Underflow is handled as described in case 1 above
+
+// Registers used
+//*********************************************************************
+// Floating Point registers used:
+// f8 input, output
+// f6,f7, f9 -> f15, f32 -> f45
+
+// General registers used:
+// r2, r3, r16 -> r38
+
+// Predicate registers used:
+// p6 -> p15
+
+// Assembly macros
+//*********************************************************************
+// integer registers used
+// scratch
+rNJ = r2
+rNJ_neg = r3
+
+rJ_neg = r16
+rN_neg = r17
+rSignexp_x = r18
+rExp_x = r18
+rExp_mask = r19
+rExp_bias = r20
+rAd1 = r21
+rAd2 = r22
+rJ = r23
+rN = r24
+rTblAddr = r25
+rA3 = r26
+rExpHalf = r27
+rLn2Div64 = r28
+rGt_ln = r29
+r17ones_m1 = r29
+rRightShifter = r30
+rJ_mask = r30
+r64DivLn2 = r31
+rN_mask = r31
+// stacked
+GR_SAVE_PFS = r32
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Parameter_TAG = r38
+
+// floating point registers used
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+// scratch
+fRightShifter = f6
+f64DivLn2 = f7
+fNormX = f9
+fNint = f10
+fN = f11
+fR = f12
+fLn2Div64 = f13
+fA2 = f14
+fA3 = f15
+// stacked
+fP = f32
+fT = f33
+fMIN_SGL_OFLOW_ARG = f34
+fMAX_SGL_NORM_ARG = f35
+fRSqr = f36
+fA1 = f37
+fA21 = f37
+fA4 = f38
+fA43 = f38
+fA4321 = f38
+fX4 = f39
+fTmp = f39
+fGt_pln = f39
+fWre_urm_f8 = f40
+fXsq = f40
+fP_neg = f41
+fX3 = f41
+fT_neg = f42
+fExp = f43
+fExp_neg = f44
+fAbsX = f45
+
+
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(_sinhf_table)
+data4 0x42b2d4fd // Smallest single arg to overflow single result
+data4 0x42b2d4fc // Largest single arg to give normal single result
+data4 0x00000000 // pad
+data4 0x00000000 // pad
+//
+// 2^(j/64) table, j goes from 0 to 63
+data8 0x0000000000000000 // 2^(0/64)
+data8 0x00002C9A3E778061 // 2^(1/64)
+data8 0x000059B0D3158574 // 2^(2/64)
+data8 0x0000874518759BC8 // 2^(3/64)
+data8 0x0000B5586CF9890F // 2^(4/64)
+data8 0x0000E3EC32D3D1A2 // 2^(5/64)
+data8 0x00011301D0125B51 // 2^(6/64)
+data8 0x0001429AAEA92DE0 // 2^(7/64)
+data8 0x000172B83C7D517B // 2^(8/64)
+data8 0x0001A35BEB6FCB75 // 2^(9/64)
+data8 0x0001D4873168B9AA // 2^(10/64)
+data8 0x0002063B88628CD6 // 2^(11/64)
+data8 0x0002387A6E756238 // 2^(12/64)
+data8 0x00026B4565E27CDD // 2^(13/64)
+data8 0x00029E9DF51FDEE1 // 2^(14/64)
+data8 0x0002D285A6E4030B // 2^(15/64)
+data8 0x000306FE0A31B715 // 2^(16/64)
+data8 0x00033C08B26416FF // 2^(17/64)
+data8 0x000371A7373AA9CB // 2^(18/64)
+data8 0x0003A7DB34E59FF7 // 2^(19/64)
+data8 0x0003DEA64C123422 // 2^(20/64)
+data8 0x0004160A21F72E2A // 2^(21/64)
+data8 0x00044E086061892D // 2^(22/64)
+data8 0x000486A2B5C13CD0 // 2^(23/64)
+data8 0x0004BFDAD5362A27 // 2^(24/64)
+data8 0x0004F9B2769D2CA7 // 2^(25/64)
+data8 0x0005342B569D4F82 // 2^(26/64)
+data8 0x00056F4736B527DA // 2^(27/64)
+data8 0x0005AB07DD485429 // 2^(28/64)
+data8 0x0005E76F15AD2148 // 2^(29/64)
+data8 0x0006247EB03A5585 // 2^(30/64)
+data8 0x0006623882552225 // 2^(31/64)
+data8 0x0006A09E667F3BCD // 2^(32/64)
+data8 0x0006DFB23C651A2F // 2^(33/64)
+data8 0x00071F75E8EC5F74 // 2^(34/64)
+data8 0x00075FEB564267C9 // 2^(35/64)
+data8 0x0007A11473EB0187 // 2^(36/64)
+data8 0x0007E2F336CF4E62 // 2^(37/64)
+data8 0x00082589994CCE13 // 2^(38/64)
+data8 0x000868D99B4492ED // 2^(39/64)
+data8 0x0008ACE5422AA0DB // 2^(40/64)
+data8 0x0008F1AE99157736 // 2^(41/64)
+data8 0x00093737B0CDC5E5 // 2^(42/64)
+data8 0x00097D829FDE4E50 // 2^(43/64)
+data8 0x0009C49182A3F090 // 2^(44/64)
+data8 0x000A0C667B5DE565 // 2^(45/64)
+data8 0x000A5503B23E255D // 2^(46/64)
+data8 0x000A9E6B5579FDBF // 2^(47/64)
+data8 0x000AE89F995AD3AD // 2^(48/64)
+data8 0x000B33A2B84F15FB // 2^(49/64)
+data8 0x000B7F76F2FB5E47 // 2^(50/64)
+data8 0x000BCC1E904BC1D2 // 2^(51/64)
+data8 0x000C199BDD85529C // 2^(52/64)
+data8 0x000C67F12E57D14B // 2^(53/64)
+data8 0x000CB720DCEF9069 // 2^(54/64)
+data8 0x000D072D4A07897C // 2^(55/64)
+data8 0x000D5818DCFBA487 // 2^(56/64)
+data8 0x000DA9E603DB3285 // 2^(57/64)
+data8 0x000DFC97337B9B5F // 2^(58/64)
+data8 0x000E502EE78B3FF6 // 2^(59/64)
+data8 0x000EA4AFA2A490DA // 2^(60/64)
+data8 0x000EFA1BEE615A27 // 2^(61/64)
+data8 0x000F50765B6E4540 // 2^(62/64)
+data8 0x000FA7C1819E90D8 // 2^(63/64)
+LOCAL_OBJECT_END(_sinhf_table)
+
+LOCAL_OBJECT_START(sinh_p_table)
+data8 0x3ec749d84bc96d7d // A4
+data8 0x3f2a0168d09557cf // A3
+data8 0x3f811111326ed15a // A2
+data8 0x3fc55555552ed1e2 // A1
+LOCAL_OBJECT_END(sinh_p_table)
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(sinhf)
+
+{ .mlx
+ getf.exp rSignexp_x = f8 // Must recompute if x unorm
+ movl r64DivLn2 = 0x40571547652B82FE // 64/ln(2)
+}
+{ .mlx
+ addl rTblAddr = @ltoff(_sinhf_table),gp
+ movl rRightShifter = 0x43E8000000000000 // DP Right Shifter
+}
+;;
+
+{ .mfi
+ // point to the beginning of the table
+ ld8 rTblAddr = [rTblAddr]
+ fclass.m p6, p0 = f8, 0x0b // Test for x=unorm
+ addl rA3 = 0x3E2AA, r0 // high bits of 1.0/6.0 rounded to SP
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNormX = f8 // normalized x
+ addl rExpHalf = 0xFFFE, r0 // exponent of 1/2
+}
+;;
+
+{ .mfi
+ setf.d f64DivLn2 = r64DivLn2 // load 64/ln(2) to FP reg
+ fclass.m p15, p0 = f8, 0x1e3 // test for NaT,NaN,Inf
+ nop.i 0
+}
+{ .mlx
+ // load Right Shifter to FP reg
+ setf.d fRightShifter = rRightShifter
+ movl rLn2Div64 = 0x3F862E42FEFA39EF // DP ln(2)/64 in GR
+}
+;;
+
+{ .mfi
+ mov rExp_mask = 0x1ffff
+ fcmp.eq.s1 p13, p0 = f0, f8 // test for x = 0.0
+ shl rA3 = rA3, 12 // 0x3E2AA000, approx to 1.0/6.0 in SP
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p6) br.cond.spnt SINH_UNORM // Branch if x=unorm
+}
+;;
+
+SINH_COMMON:
+{ .mfi
+ setf.exp fA2 = rExpHalf // load A2 to FP reg
+ nop.f 0
+ mov rExp_bias = 0xffff
+}
+{ .mfb
+ setf.d fLn2Div64 = rLn2Div64 // load ln(2)/64 to FP reg
+(p15) fma.s.s0 f8 = f8, f1, f0 // result if x = NaT,NaN,Inf
+(p15) br.ret.spnt b0 // exit here if x = NaT,NaN,Inf
+}
+;;
+
+{ .mfi
+ // min overflow and max normal threshold
+ ldfps fMIN_SGL_OFLOW_ARG, fMAX_SGL_NORM_ARG = [rTblAddr], 8
+ nop.f 0
+ and rExp_x = rExp_mask, rSignexp_x // Biased exponent of x
+}
+{ .mfb
+ setf.s fA3 = rA3 // load A3 to FP reg
+ nop.f 0
+(p13) br.ret.spnt b0 // exit here if x=0.0, return x
+}
+;;
+
+{ .mfi
+ sub rExp_x = rExp_x, rExp_bias // True exponent of x
+ fmerge.s fAbsX = f0, fNormX // Form |x|
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // x*(64/ln(2)) + Right Shifter
+ fma.s1 fNint = fNormX, f64DivLn2, fRightShifter
+ add rTblAddr = 8, rTblAddr
+}
+{ .mfb
+ cmp.gt p7, p0 = -2, rExp_x // Test |x| < 2^(-2)
+ fma.s1 fXsq = fNormX, fNormX, f0 // x*x for small path
+(p7) br.cond.spnt SINH_SMALL // Branch if 0 < |x| < 2^-2
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // check for overflow
+ fcmp.ge.s1 p12, p13 = fAbsX, fMIN_SGL_OFLOW_ARG
+ mov rJ_mask = 0x3f // 6-bit mask for J
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fms.s1 fN = fNint, f1, fRightShifter // n in FP register
+ // branch out if overflow
+(p12) br.cond.spnt SINH_CERTAIN_OVERFLOW
+}
+;;
+
+{ .mfi
+ getf.sig rNJ = fNint // bits of n, j
+ // check for possible overflow
+ fcmp.gt.s1 p13, p0 = fAbsX, fMAX_SGL_NORM_ARG
+ nop.i 0
+}
+;;
+
+{ .mfi
+ addl rN = 0xFFBF - 63, rNJ // biased and shifted n-1,j
+ fnma.s1 fR = fLn2Div64, fN, fNormX // R = x - N*ln(2)/64
+ and rJ = rJ_mask, rNJ // bits of j
+}
+{ .mfi
+ sub rNJ_neg = r0, rNJ // bits of n, j for -x
+ nop.f 0
+ andcm rN_mask = -1, rJ_mask // 0xff...fc0 to mask N
+}
+;;
+
+{ .mfi
+ shladd rJ = rJ, 3, rTblAddr // address in the 2^(j/64) table
+ nop.f 0
+ and rN = rN_mask, rN // biased, shifted n-1
+}
+{ .mfi
+ addl rN_neg = 0xFFBF - 63, rNJ_neg // -x biased, shifted n-1,j
+ nop.f 0
+ and rJ_neg = rJ_mask, rNJ_neg // bits of j for -x
+}
+;;
+
+{ .mfi
+ ld8 rJ = [rJ] // Table value
+ nop.f 0
+ shl rN = rN, 46 // 2^(n-1) bits in DP format
+}
+{ .mfi
+ shladd rJ_neg = rJ_neg, 3, rTblAddr // addr in 2^(j/64) table -x
+ nop.f 0
+ and rN_neg = rN_mask, rN_neg // biased, shifted n-1 for -x
+}
+;;
+
+{ .mfi
+ ld8 rJ_neg = [rJ_neg] // Table value for -x
+ nop.f 0
+ shl rN_neg = rN_neg, 46 // 2^(n-1) bits in DP format for -x
+}
+;;
+
+{ .mfi
+ or rN = rN, rJ // bits of 2^n * 2^(j/64) in DP format
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mmf
+ setf.d fT = rN // 2^(n-1) * 2^(j/64)
+ or rN_neg = rN_neg, rJ_neg // -x bits of 2^n * 2^(j/64) in DP
+ fma.s1 fRSqr = fR, fR, f0 // R^2
+}
+;;
+
+{ .mfi
+ setf.d fT_neg = rN_neg // 2^(n-1) * 2^(j/64) for -x
+ fma.s1 fP = fA3, fR, fA2 // A3*R + A2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 fP_neg = fA3, fR, fA2 // A3*R + A2 for -x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP = fP, fRSqr, fR // P = (A3*R + A2)*R^2 + R
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fP_neg = fP_neg, fRSqr, fR // P = (A3*R + A2)*R^2 + R, -x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fmpy.s0 fTmp = fLn2Div64, fLn2Div64 // Force inexact
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fExp = fP, fT, fT // exp(x)/2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s1 fExp_neg = fP_neg, fT_neg, fT_neg // exp(-x)/2
+ // branch out if possible overflow result
+(p13) br.cond.spnt SINH_POSSIBLE_OVERFLOW
+}
+;;
+
+{ .mfb
+ nop.m 0
+ // final result in the absence of overflow
+ fms.s.s0 f8 = fExp, f1, fExp_neg // result = (exp(x)-exp(-x))/2
+ // exit here in the absence of overflow
+ br.ret.sptk b0 // Exit main path, 0.25 <= |x| < 89.41598
+}
+;;
+
+// Here if 0 < |x| < 0.25. Evaluate 9th order polynomial.
+SINH_SMALL:
+{ .mfi
+ add rAd1 = 0x200, rTblAddr
+ fcmp.lt.s1 p7, p8 = fNormX, f0 // Test sign of x
+ cmp.gt p6, p0 = -60, rExp_x // Test |x| < 2^(-60)
+}
+{ .mfi
+ add rAd2 = 0x210, rTblAddr
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mmb
+ ldfpd fA4, fA3 = [rAd1]
+ ldfpd fA2, fA1 = [rAd2]
+(p6) br.cond.spnt SINH_VERY_SMALL // Branch if |x| < 2^(-60)
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fX3 = fXsq, fNormX, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fX4 = fXsq, fXsq, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA43 = fXsq, fA4, fA3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA21 = fXsq, fA2, fA1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA4321 = fX4, fA43, fA21
+ nop.i 0
+}
+;;
+
+// Dummy multiply to generate inexact
+{ .mfi
+ nop.m 0
+ fmpy.s0 fTmp = fA4, fA4
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = fA4321, fX3, fNormX
+ br.ret.sptk b0 // Exit if 2^-60 < |x| < 0.25
+}
+;;
+
+SINH_VERY_SMALL:
+// Here if 0 < |x| < 2^-60
+// Compute result by x + sgn(x)*x^2 to get properly rounded result
+.pred.rel "mutex",p7,p8
+{ .mfi
+ nop.m 0
+(p7) fnma.s.s0 f8 = fNormX, fNormX, fNormX // If x<0 result ~ x-x^2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fma.s.s0 f8 = fNormX, fNormX, fNormX // If x>0 result ~ x+x^2
+ br.ret.sptk b0 // Exit if |x| < 2^-60
+}
+;;
+
+SINH_POSSIBLE_OVERFLOW:
+
+// Here if fMAX_SGL_NORM_ARG < x < fMIN_SGL_OFLOW_ARG
+// This cannot happen if input is a single, only if input higher precision.
+// Overflow is a possibility, not a certainty.
+
+// Recompute result using status field 2 with user's rounding mode,
+// and wre set. If result is larger than largest single, then we have
+// overflow
+
+{ .mfi
+ mov rGt_ln = 0x1007f // Exponent for largest single + 1 ulp
+ fsetc.s2 0x7F,0x42 // Get user's round mode, set wre
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp fGt_pln = rGt_ln // Create largest single + 1 ulp
+ fma.s.s2 fWre_urm_f8 = fP, fT, fT // Result with wre set
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40 // Turn off wre in sf2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p6, p0 = fWre_urm_f8, fGt_pln // Test for overflow
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p6) br.cond.spnt SINH_CERTAIN_OVERFLOW // Branch if overflow
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = fP, fT, fT
+ br.ret.sptk b0 // Exit if really no overflow
+}
+;;
+
+// here if overflow
+SINH_CERTAIN_OVERFLOW:
+{ .mfi
+ addl r17ones_m1 = 0x1FFFE, r0
+ fcmp.lt.s1 p6, p7 = fNormX, f0 // Test for x < 0
+ nop.i 0
+}
+;;
+
+{ .mmf
+ alloc r32 = ar.pfs, 0, 3, 4, 0 // get some registers
+ setf.exp fTmp = r17ones_m1
+ fmerge.s FR_X = f8,f8
+}
+;;
+
+{ .mfi
+ mov GR_Parameter_TAG = 128
+(p6) fnma.s.s0 FR_RESULT = fTmp, fTmp, f0 // Set I,O and -INF result
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.s.s0 FR_RESULT = fTmp, fTmp, f0 // Set I,O and +INF result
+ br.cond.sptk __libm_error_region
+}
+;;
+
+// Here if x unorm
+SINH_UNORM:
+{ .mfb
+ getf.exp rSignexp_x = fNormX // Must recompute if x unorm
+ fcmp.eq.s0 p6, p0 = f8, f0 // Set D flag
+ br.cond.sptk SINH_COMMON // Return to main path
+}
+;;
+
+GLOBAL_IEEE754_END(sinhf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // Store Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mfi
+ stfs [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ nop.f 0
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_sinhl.S b/libc/sysdeps/ia64/fpu/e_sinhl.S
new file mode 100644
index 000000000..5b4a4addc
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_sinhl.S
@@ -0,0 +1,1117 @@
+.file "sinhl.s"
+
+
+// Copyright (c) 2000 - 2002, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 10/12/00 Update to set denormal operand and underflow flags
+// 01/22/01 Fixed to set inexact flag for small args. Fixed incorrect
+// call to __libm_error_support for 710.476 < x < 11357.2166.
+// 05/02/01 Reworked to improve speed of all paths
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 12/04/02 Improved performance
+//
+// API
+//==============================================================
+// long double = sinhl(long double)
+// input floating point f8
+// output floating point f8
+//
+// Registers used
+//==============================================================
+// general registers:
+// r14 -> r40
+// predicate registers used:
+// p6 -> p11
+// floating-point registers used:
+// f9 -> f15; f32 -> f90;
+// f8 has input, then output
+//
+// Overview of operation
+//==============================================================
+// There are seven paths
+// 1. 0 < |x| < 0.25 SINH_BY_POLY
+// 2. 0.25 <=|x| < 32 SINH_BY_TBL
+// 3. 32 <= |x| < 11357.21655 SINH_BY_EXP (merged path with SINH_BY_TBL)
+// 4. |x| >= 11357.21655 SINH_HUGE
+// 5. x=0 Done with early exit
+// 6. x=inf,nan Done with early exit
+// 7. x=denormal SINH_DENORM
+//
+// For double extended we get overflow for x >= 400c b174 ddc0 31ae c0ea
+// >= 11357.21655
+//
+//
+// 1. SINH_BY_POLY 0 < |x| < 0.25
+// ===============
+// Evaluate sinh(x) by a 13th order polynomial
+// Care is take for the order of multiplication; and P_1 is not exactly 1/3!,
+// P_2 is not exactly 1/5!, etc.
+// sinh(x) = sign * (series(e^x) - series(e^-x))/2
+// = sign * (ax + ax^3/3! + ax^5/5! + ax^7/7! + ax^9/9! + ax^11/11!
+// + ax^13/13!)
+// = sign * (ax + ax * ( ax^2 * (1/3! + ax^4 * (1/7! + ax^4*1/11!)) )
+// + ax * ( ax^4 * (1/5! + ax^4 * (1/9! + ax^4*1/13!)) ))
+// = sign * (ax + ax*p_odd + (ax*p_even))
+// = sign * (ax + Y_lo)
+// sinh(x) = sign * (Y_hi + Y_lo)
+// Note that ax = |x|
+//
+// 2. SINH_BY_TBL 0.25 <= |x| < 32.0
+// =============
+// sinh(x) = sinh(B+R)
+// = sinh(B)cosh(R) + cosh(B)sinh(R)
+//
+// ax = |x| = M*log2/64 + R
+// B = M*log2/64
+// M = 64*N + j
+// We will calculate M and get N as (M-j)/64
+// The division is a shift.
+// exp(B) = exp(N*log2 + j*log2/64)
+// = 2^N * 2^(j*log2/64)
+// sinh(B) = 1/2(e^B -e^-B)
+// = 1/2(2^N * 2^(j*log2/64) - 2^-N * 2^(-j*log2/64))
+// sinh(B) = (2^(N-1) * 2^(j*log2/64) - 2^(-N-1) * 2^(-j*log2/64))
+// cosh(B) = (2^(N-1) * 2^(j*log2/64) + 2^(-N-1) * 2^(-j*log2/64))
+// 2^(j*log2/64) is stored as Tjhi + Tjlo , j= -32,....,32
+// Tjhi is double-extended (80-bit) and Tjlo is single(32-bit)
+//
+// R = ax - M*log2/64
+// R = ax - M*log2_by_64_hi - M*log2_by_64_lo
+// exp(R) = 1 + R +R^2(1/2! + R(1/3! + R(1/4! + ... + R(1/n!)...)
+// = 1 + p_odd + p_even
+// where the p_even uses the A coefficients and the p_even uses
+// the B coefficients
+//
+// So sinh(R) = 1 + p_odd + p_even -(1 -p_odd -p_even)/2 = p_odd
+// cosh(R) = 1 + p_even
+// sinh(B) = S_hi + S_lo
+// cosh(B) = C_hi
+// sinh(x) = sinh(B)cosh(R) + cosh(B)sinh(R)
+//
+// 3. SINH_BY_EXP 32.0 <= |x| < 11357.21655 ( 400c b174 ddc0 31ae c0ea )
+// ==============
+// Can approximate result by exp(x)/2 in this region.
+// Y_hi = Tjhi
+// Y_lo = Tjhi * (p_odd + p_even) + Tjlo
+// sinh(x) = Y_hi + Y_lo
+//
+// 4. SINH_HUGE |x| >= 11357.21655 ( 400c b174 ddc0 31ae c0ea )
+// ============
+// Set error tag and call error support
+//
+//
+// Assembly macros
+//==============================================================
+r_ad5 = r14
+r_rshf_2to57 = r15
+r_exp_denorm = r15
+r_ad_mJ_lo = r15
+r_ad_J_lo = r16
+r_2Nm1 = r17
+r_2mNm1 = r18
+r_exp_x = r18
+r_ad_J_hi = r19
+r_ad2o = r19
+r_ad_mJ_hi = r20
+r_mj = r21
+r_ad2e = r22
+r_ad3 = r23
+r_ad1 = r24
+r_Mmj = r24
+r_rshf = r25
+r_M = r25
+r_N = r25
+r_jshf = r26
+r_exp_2tom57 = r26
+r_j = r26
+r_exp_mask = r27
+r_signexp_x = r28
+r_signexp_sgnx_0_5 = r28
+r_exp_0_25 = r29
+r_sig_inv_ln2 = r30
+r_exp_32 = r30
+r_exp_huge = r30
+r_ad4 = r31
+
+GR_SAVE_PFS = r34
+GR_SAVE_B0 = r35
+GR_SAVE_GP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+f_ABS_X = f9
+f_X2 = f10
+f_X4 = f11
+f_tmp = f14
+f_RSHF = f15
+
+f_Inv_log2by64 = f32
+f_log2by64_lo = f33
+f_log2by64_hi = f34
+f_A1 = f35
+
+f_A2 = f36
+f_A3 = f37
+f_Rcub = f38
+f_M_temp = f39
+f_R_temp = f40
+
+f_Rsq = f41
+f_R = f42
+f_M = f43
+f_B1 = f44
+f_B2 = f45
+
+f_B3 = f46
+f_peven_temp1 = f47
+f_peven_temp2 = f48
+f_peven = f49
+f_podd_temp1 = f50
+
+f_podd_temp2 = f51
+f_podd = f52
+f_poly65 = f53
+f_poly6543 = f53
+f_poly6to1 = f53
+f_poly43 = f54
+f_poly21 = f55
+
+f_X3 = f56
+f_INV_LN2_2TO63 = f57
+f_RSHF_2TO57 = f58
+f_2TOM57 = f59
+f_smlst_oflow_input = f60
+
+f_pre_result = f61
+f_huge = f62
+f_spos = f63
+f_sneg = f64
+f_Tjhi = f65
+
+f_Tjlo = f66
+f_Tmjhi = f67
+f_Tmjlo = f68
+f_S_hi = f69
+f_SC_hi_temp = f70
+
+f_S_lo_temp1 = f71
+f_S_lo_temp2 = f72
+f_S_lo_temp3 = f73
+f_S_lo_temp4 = f73
+f_S_lo = f74
+f_C_hi = f75
+
+f_Y_hi = f77
+f_Y_lo_temp = f78
+f_Y_lo = f79
+f_NORM_X = f80
+
+f_P1 = f81
+f_P2 = f82
+f_P3 = f83
+f_P4 = f84
+f_P5 = f85
+
+f_P6 = f86
+f_Tjhi_spos = f87
+f_Tjlo_spos = f88
+f_huge = f89
+f_signed_hi_lo = f90
+
+
+// Data tables
+//==============================================================
+
+// DO NOT CHANGE ORDER OF THESE TABLES
+RODATA
+
+.align 16
+LOCAL_OBJECT_START(sinh_arg_reduction)
+// data8 0xB8AA3B295C17F0BC, 0x00004005 // 64/log2 -- signif loaded with setf
+ data8 0xB17217F7D1000000, 0x00003FF8 // log2/64 high part
+ data8 0xCF79ABC9E3B39804, 0x00003FD0 // log2/64 low part
+ data8 0xb174ddc031aec0ea, 0x0000400c // Smallest x to overflow (11357.21655)
+LOCAL_OBJECT_END(sinh_arg_reduction)
+
+LOCAL_OBJECT_START(sinh_p_table)
+ data8 0xB08AF9AE78C1239F, 0x00003FDE // P6
+ data8 0xB8EF1D28926D8891, 0x00003FEC // P4
+ data8 0x8888888888888412, 0x00003FF8 // P2
+ data8 0xD732377688025BE9, 0x00003FE5 // P5
+ data8 0xD00D00D00D4D39F2, 0x00003FF2 // P3
+ data8 0xAAAAAAAAAAAAAAAB, 0x00003FFC // P1
+LOCAL_OBJECT_END(sinh_p_table)
+
+LOCAL_OBJECT_START(sinh_ab_table)
+ data8 0xAAAAAAAAAAAAAAAC, 0x00003FFC // A1
+ data8 0x88888888884ECDD5, 0x00003FF8 // A2
+ data8 0xD00D0C6DCC26A86B, 0x00003FF2 // A3
+ data8 0x8000000000000002, 0x00003FFE // B1
+ data8 0xAAAAAAAAAA402C77, 0x00003FFA // B2
+ data8 0xB60B6CC96BDB144D, 0x00003FF5 // B3
+LOCAL_OBJECT_END(sinh_ab_table)
+
+LOCAL_OBJECT_START(sinh_j_hi_table)
+ data8 0xB504F333F9DE6484, 0x00003FFE
+ data8 0xB6FD91E328D17791, 0x00003FFE
+ data8 0xB8FBAF4762FB9EE9, 0x00003FFE
+ data8 0xBAFF5AB2133E45FB, 0x00003FFE
+ data8 0xBD08A39F580C36BF, 0x00003FFE
+ data8 0xBF1799B67A731083, 0x00003FFE
+ data8 0xC12C4CCA66709456, 0x00003FFE
+ data8 0xC346CCDA24976407, 0x00003FFE
+ data8 0xC5672A115506DADD, 0x00003FFE
+ data8 0xC78D74C8ABB9B15D, 0x00003FFE
+ data8 0xC9B9BD866E2F27A3, 0x00003FFE
+ data8 0xCBEC14FEF2727C5D, 0x00003FFE
+ data8 0xCE248C151F8480E4, 0x00003FFE
+ data8 0xD06333DAEF2B2595, 0x00003FFE
+ data8 0xD2A81D91F12AE45A, 0x00003FFE
+ data8 0xD4F35AABCFEDFA1F, 0x00003FFE
+ data8 0xD744FCCAD69D6AF4, 0x00003FFE
+ data8 0xD99D15C278AFD7B6, 0x00003FFE
+ data8 0xDBFBB797DAF23755, 0x00003FFE
+ data8 0xDE60F4825E0E9124, 0x00003FFE
+ data8 0xE0CCDEEC2A94E111, 0x00003FFE
+ data8 0xE33F8972BE8A5A51, 0x00003FFE
+ data8 0xE5B906E77C8348A8, 0x00003FFE
+ data8 0xE8396A503C4BDC68, 0x00003FFE
+ data8 0xEAC0C6E7DD24392F, 0x00003FFE
+ data8 0xED4F301ED9942B84, 0x00003FFE
+ data8 0xEFE4B99BDCDAF5CB, 0x00003FFE
+ data8 0xF281773C59FFB13A, 0x00003FFE
+ data8 0xF5257D152486CC2C, 0x00003FFE
+ data8 0xF7D0DF730AD13BB9, 0x00003FFE
+ data8 0xFA83B2DB722A033A, 0x00003FFE
+ data8 0xFD3E0C0CF486C175, 0x00003FFE
+ data8 0x8000000000000000, 0x00003FFF // Center of table
+ data8 0x8164D1F3BC030773, 0x00003FFF
+ data8 0x82CD8698AC2BA1D7, 0x00003FFF
+ data8 0x843A28C3ACDE4046, 0x00003FFF
+ data8 0x85AAC367CC487B15, 0x00003FFF
+ data8 0x871F61969E8D1010, 0x00003FFF
+ data8 0x88980E8092DA8527, 0x00003FFF
+ data8 0x8A14D575496EFD9A, 0x00003FFF
+ data8 0x8B95C1E3EA8BD6E7, 0x00003FFF
+ data8 0x8D1ADF5B7E5BA9E6, 0x00003FFF
+ data8 0x8EA4398B45CD53C0, 0x00003FFF
+ data8 0x9031DC431466B1DC, 0x00003FFF
+ data8 0x91C3D373AB11C336, 0x00003FFF
+ data8 0x935A2B2F13E6E92C, 0x00003FFF
+ data8 0x94F4EFA8FEF70961, 0x00003FFF
+ data8 0x96942D3720185A00, 0x00003FFF
+ data8 0x9837F0518DB8A96F, 0x00003FFF
+ data8 0x99E0459320B7FA65, 0x00003FFF
+ data8 0x9B8D39B9D54E5539, 0x00003FFF
+ data8 0x9D3ED9A72CFFB751, 0x00003FFF
+ data8 0x9EF5326091A111AE, 0x00003FFF
+ data8 0xA0B0510FB9714FC2, 0x00003FFF
+ data8 0xA27043030C496819, 0x00003FFF
+ data8 0xA43515AE09E6809E, 0x00003FFF
+ data8 0xA5FED6A9B15138EA, 0x00003FFF
+ data8 0xA7CD93B4E965356A, 0x00003FFF
+ data8 0xA9A15AB4EA7C0EF8, 0x00003FFF
+ data8 0xAB7A39B5A93ED337, 0x00003FFF
+ data8 0xAD583EEA42A14AC6, 0x00003FFF
+ data8 0xAF3B78AD690A4375, 0x00003FFF
+ data8 0xB123F581D2AC2590, 0x00003FFF
+ data8 0xB311C412A9112489, 0x00003FFF
+ data8 0xB504F333F9DE6484, 0x00003FFF
+LOCAL_OBJECT_END(sinh_j_hi_table)
+
+LOCAL_OBJECT_START(sinh_j_lo_table)
+ data4 0x1EB2FB13
+ data4 0x1CE2CBE2
+ data4 0x1DDC3CBC
+ data4 0x1EE9AA34
+ data4 0x9EAEFDC1
+ data4 0x9DBF517B
+ data4 0x1EF88AFB
+ data4 0x1E03B216
+ data4 0x1E78AB43
+ data4 0x9E7B1747
+ data4 0x9EFE3C0E
+ data4 0x9D36F837
+ data4 0x9DEE53E4
+ data4 0x9E24AE8E
+ data4 0x1D912473
+ data4 0x1EB243BE
+ data4 0x1E669A2F
+ data4 0x9BBC610A
+ data4 0x1E761035
+ data4 0x9E0BE175
+ data4 0x1CCB12A1
+ data4 0x1D1BFE90
+ data4 0x1DF2F47A
+ data4 0x1EF22F22
+ data4 0x9E3F4A29
+ data4 0x1EC01A5B
+ data4 0x1E8CAC3A
+ data4 0x9DBB3FAB
+ data4 0x1EF73A19
+ data4 0x9BB795B5
+ data4 0x1EF84B76
+ data4 0x9EF5818B
+ data4 0x00000000 // Center of table
+ data4 0x1F77CACA
+ data4 0x1EF8A91D
+ data4 0x1E57C976
+ data4 0x9EE8DA92
+ data4 0x1EE85C9F
+ data4 0x1F3BF1AF
+ data4 0x1D80CA1E
+ data4 0x9D0373AF
+ data4 0x9F167097
+ data4 0x1EB70051
+ data4 0x1F6EB029
+ data4 0x1DFD6D8E
+ data4 0x9EB319B0
+ data4 0x1EBA2BEB
+ data4 0x1F11D537
+ data4 0x1F0D5A46
+ data4 0x9E5E7BCA
+ data4 0x9F3AAFD1
+ data4 0x9E86DACC
+ data4 0x9F3EDDC2
+ data4 0x1E496E3D
+ data4 0x9F490BF6
+ data4 0x1DD1DB48
+ data4 0x1E65EBFB
+ data4 0x9F427496
+ data4 0x1F283C4A
+ data4 0x1F4B0047
+ data4 0x1F130152
+ data4 0x9E8367C0
+ data4 0x9F705F90
+ data4 0x1EFB3C53
+ data4 0x1F32FB13
+LOCAL_OBJECT_END(sinh_j_lo_table)
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(sinhl)
+
+{ .mlx
+ getf.exp r_signexp_x = f8 // Get signexp of x, must redo if unorm
+ movl r_sig_inv_ln2 = 0xb8aa3b295c17f0bc // significand of 1/ln2
+}
+{ .mlx
+ addl r_ad1 = @ltoff(sinh_arg_reduction), gp
+ movl r_rshf_2to57 = 0x4778000000000000 // 1.10000 2^(63+57)
+}
+;;
+
+{ .mfi
+ ld8 r_ad1 = [r_ad1]
+ fmerge.s f_ABS_X = f0,f8
+ mov r_exp_0_25 = 0x0fffd // Form exponent for 0.25
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 f_NORM_X = f8
+ mov r_exp_2tom57 = 0xffff-57
+}
+;;
+
+{ .mfi
+ setf.d f_RSHF_2TO57 = r_rshf_2to57 // Form const 1.100 * 2^120
+ fclass.m p10,p0 = f8, 0x0b // Test for denorm
+ mov r_exp_mask = 0x1ffff
+}
+{ .mlx
+ setf.sig f_INV_LN2_2TO63 = r_sig_inv_ln2 // Form 1/ln2 * 2^63
+ movl r_rshf = 0x43e8000000000000 // 1.1000 2^63 for right shift
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p7,p0 = f8, 0x07 // Test if x=0
+ nop.i 0
+}
+{ .mfi
+ setf.exp f_2TOM57 = r_exp_2tom57 // Form 2^-57 for scaling
+ nop.f 0
+ add r_ad3 = 0x90, r_ad1 // Point to ab_table
+}
+;;
+
+{ .mfi
+ setf.d f_RSHF = r_rshf // Form right shift const 1.100 * 2^63
+ fclass.m p6,p0 = f8, 0xe3 // Test if x nan, inf
+ add r_ad4 = 0x2f0, r_ad1 // Point to j_hi_table midpoint
+}
+{ .mib
+ add r_ad2e = 0x20, r_ad1 // Point to p_table
+ nop.i 0
+(p10) br.cond.spnt SINH_DENORM // Branch if x denorm
+}
+;;
+
+// Common path -- return here from SINH_DENORM if x is unnorm
+SINH_COMMON:
+{ .mfi
+ ldfe f_smlst_oflow_input = [r_ad2e],16
+ nop.f 0
+ add r_ad5 = 0x580, r_ad1 // Point to j_lo_table midpoint
+}
+{ .mib
+ ldfe f_log2by64_hi = [r_ad1],16
+ and r_exp_x = r_exp_mask, r_signexp_x
+(p7) br.ret.spnt b0 // Exit if x=0
+}
+;;
+
+// Get the A coefficients for SINH_BY_TBL
+{ .mfi
+ ldfe f_A1 = [r_ad3],16
+ fcmp.lt.s1 p8,p9 = f8,f0 // Test for x<0
+ cmp.lt p7,p0 = r_exp_x, r_exp_0_25 // Test x < 0.25
+}
+{ .mfb
+ add r_ad2o = 0x30, r_ad2e // Point to p_table odd coeffs
+(p6) fma.s0 f8 = f8,f1,f0 // Result for x nan, inf
+(p6) br.ret.spnt b0 // Exit for x nan, inf
+}
+;;
+
+// Calculate X2 = ax*ax for SINH_BY_POLY
+{ .mfi
+ ldfe f_log2by64_lo = [r_ad1],16
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+ ldfe f_A2 = [r_ad3],16
+ fma.s1 f_X2 = f_NORM_X, f_NORM_X, f0
+(p7) br.cond.spnt SINH_BY_POLY
+}
+;;
+
+// Here if |x| >= 0.25
+SINH_BY_TBL:
+// ******************************************************
+// STEP 1 (TBL and EXP) - Argument reduction
+// ******************************************************
+// Get the following constants.
+// Inv_log2by64
+// log2by64_hi
+// log2by64_lo
+
+
+// We want 2^(N-1) and 2^(-N-1). So bias N-1 and -N-1 and
+// put them in an exponent.
+// f_spos = 2^(N-1) and f_sneg = 2^(-N-1)
+// 0xffff + (N-1) = 0xffff +N -1
+// 0xffff - (N +1) = 0xffff -N -1
+
+
+// Calculate M and keep it as integer and floating point.
+// M = round-to-integer(x*Inv_log2by64)
+// f_M = M = truncate(ax/(log2/64))
+// Put the integer representation of M in r_M
+// and the floating point representation of M in f_M
+
+// Get the remaining A,B coefficients
+{ .mmi
+ ldfe f_A3 = [r_ad3],16
+ nop.m 0
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p8,p9
+// Use constant (1.100*2^(63-6)) to get rounded M into rightmost significand
+// |x| * 64 * 1/ln2 * 2^(63-6) + 1.1000 * 2^(63+(63-6))
+{ .mfi
+(p8) mov r_signexp_sgnx_0_5 = 0x2fffe // signexp of -0.5
+ fma.s1 f_M_temp = f_ABS_X, f_INV_LN2_2TO63, f_RSHF_2TO57
+(p9) mov r_signexp_sgnx_0_5 = 0x0fffe // signexp of +0.5
+}
+;;
+
+// Test for |x| >= overflow limit
+{ .mfi
+ ldfe f_B1 = [r_ad3],16
+ fcmp.ge.s1 p6,p0 = f_ABS_X, f_smlst_oflow_input
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe f_B2 = [r_ad3],16
+ nop.f 0
+ mov r_exp_32 = 0x10004
+}
+;;
+
+// Subtract RSHF constant to get rounded M as a floating point value
+// M_temp * 2^(63-6) - 2^63
+{ .mfb
+ ldfe f_B3 = [r_ad3],16
+ fms.s1 f_M = f_M_temp, f_2TOM57, f_RSHF
+(p6) br.cond.spnt SINH_HUGE // Branch if result will overflow
+}
+;;
+
+{ .mfi
+ getf.sig r_M = f_M_temp
+ nop.f 0
+ cmp.ge p7,p6 = r_exp_x, r_exp_32 // Test if x >= 32
+}
+;;
+
+// Calculate j. j is the signed extension of the six lsb of M. It
+// has a range of -32 thru 31.
+
+// Calculate R
+// ax - M*log2by64_hi
+// R = (ax - M*log2by64_hi) - M*log2by64_lo
+
+{ .mfi
+ nop.m 0
+ fnma.s1 f_R_temp = f_M, f_log2by64_hi, f_ABS_X
+ and r_j = 0x3f, r_M
+}
+;;
+
+{ .mii
+ nop.m 0
+ shl r_jshf = r_j, 0x2 // Shift j so can sign extend it
+;;
+ sxt1 r_jshf = r_jshf
+}
+;;
+
+{ .mii
+ nop.m 0
+ shr r_j = r_jshf, 0x2 // Now j has range -32 to 31
+ nop.i 0
+}
+;;
+
+{ .mmi
+ shladd r_ad_J_hi = r_j, 4, r_ad4 // pointer to Tjhi
+ sub r_Mmj = r_M, r_j // M-j
+ sub r_mj = r0, r_j // Form -j
+}
+;;
+
+// The TBL and EXP branches are merged and predicated
+// If TBL, p6 true, 0.25 <= |x| < 32
+// If EXP, p7 true, 32 <= |x| < overflow_limit
+//
+// N = (M-j)/64
+{ .mfi
+ ldfe f_Tjhi = [r_ad_J_hi]
+ fnma.s1 f_R = f_M, f_log2by64_lo, f_R_temp
+ shr r_N = r_Mmj, 0x6 // N = (M-j)/64
+}
+{ .mfi
+ shladd r_ad_mJ_hi = r_mj, 4, r_ad4 // pointer to Tmjhi
+ nop.f 0
+ shladd r_ad_mJ_lo = r_mj, 2, r_ad5 // pointer to Tmjlo
+}
+;;
+
+{ .mfi
+ sub r_2mNm1 = r_signexp_sgnx_0_5, r_N // signexp sgnx*2^(-N-1)
+ nop.f 0
+ shladd r_ad_J_lo = r_j, 2, r_ad5 // pointer to Tjlo
+}
+{ .mfi
+ ldfe f_Tmjhi = [r_ad_mJ_hi]
+ nop.f 0
+ add r_2Nm1 = r_signexp_sgnx_0_5, r_N // signexp sgnx*2^(N-1)
+}
+;;
+
+{ .mmf
+ ldfs f_Tmjlo = [r_ad_mJ_lo]
+ setf.exp f_sneg = r_2mNm1 // Form sgnx * 2^(-N-1)
+ nop.f 0
+}
+;;
+
+{ .mmf
+ ldfs f_Tjlo = [r_ad_J_lo]
+ setf.exp f_spos = r_2Nm1 // Form sgnx * 2^(N-1)
+ nop.f 0
+}
+;;
+
+// ******************************************************
+// STEP 2 (TBL and EXP)
+// ******************************************************
+// Calculate Rsquared and Rcubed in preparation for p_even and p_odd
+
+{ .mmf
+ nop.m 0
+ nop.m 0
+ fma.s1 f_Rsq = f_R, f_R, f0
+}
+;;
+
+
+// Calculate p_even
+// B_2 + Rsq *B_3
+// B_1 + Rsq * (B_2 + Rsq *B_3)
+// p_even = Rsq * (B_1 + Rsq * (B_2 + Rsq *B_3))
+{ .mfi
+ nop.m 0
+ fma.s1 f_peven_temp1 = f_Rsq, f_B3, f_B2
+ nop.i 0
+}
+// Calculate p_odd
+// A_2 + Rsq *A_3
+// A_1 + Rsq * (A_2 + Rsq *A_3)
+// podd = R + Rcub * (A_1 + Rsq * (A_2 + Rsq *A_3))
+{ .mfi
+ nop.m 0
+ fma.s1 f_podd_temp1 = f_Rsq, f_A3, f_A2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_Rcub = f_Rsq, f_R, f0
+ nop.i 0
+}
+;;
+
+//
+// If TBL,
+// Calculate S_hi and S_lo, and C_hi
+// SC_hi_temp = sneg * Tmjhi
+// S_hi = spos * Tjhi - SC_hi_temp
+// S_hi = spos * Tjhi - (sneg * Tmjhi)
+// C_hi = spos * Tjhi + SC_hi_temp
+// C_hi = spos * Tjhi + (sneg * Tmjhi)
+
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_SC_hi_temp = f_sneg, f_Tmjhi, f0
+ nop.i 0
+}
+;;
+
+// If TBL,
+// S_lo_temp3 = sneg * Tmjlo
+// S_lo_temp4 = spos * Tjlo - S_lo_temp3
+// S_lo_temp4 = spos * Tjlo -(sneg * Tmjlo)
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_S_lo_temp3 = f_sneg, f_Tmjlo, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_peven_temp2 = f_Rsq, f_peven_temp1, f_B1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 f_podd_temp2 = f_Rsq, f_podd_temp1, f_A1
+ nop.i 0
+}
+;;
+
+// If EXP,
+// Compute sgnx * 2^(N-1) * Tjhi and sgnx * 2^(N-1) * Tjlo
+{ .mfi
+ nop.m 0
+(p7) fma.s1 f_Tjhi_spos = f_Tjhi, f_spos, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s1 f_Tjlo_spos = f_Tjlo, f_spos, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fms.s1 f_S_hi = f_spos, f_Tjhi, f_SC_hi_temp
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_C_hi = f_spos, f_Tjhi, f_SC_hi_temp
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p6) fms.s1 f_S_lo_temp4 = f_spos, f_Tjlo, f_S_lo_temp3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_peven = f_Rsq, f_peven_temp2, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 f_podd = f_podd_temp2, f_Rcub, f_R
+ nop.i 0
+}
+;;
+
+// If TBL,
+// S_lo_temp1 = spos * Tjhi - S_hi
+// S_lo_temp2 = -sneg * Tmjlo + S_lo_temp1
+// S_lo_temp2 = -sneg * Tmjlo + (spos * Tjhi - S_hi)
+
+{ .mfi
+ nop.m 0
+(p6) fms.s1 f_S_lo_temp1 = f_spos, f_Tjhi, f_S_hi
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fnma.s1 f_S_lo_temp2 = f_sneg, f_Tmjhi, f_S_lo_temp1
+ nop.i 0
+}
+;;
+
+// If EXP,
+// Y_hi = sgnx * 2^(N-1) * Tjhi
+// Y_lo = sgnx * 2^(N-1) * Tjhi * (p_odd + p_even) + sgnx * 2^(N-1) * Tjlo
+{ .mfi
+ nop.m 0
+(p7) fma.s1 f_Y_lo_temp = f_peven, f1, f_podd
+ nop.i 0
+}
+;;
+
+// If TBL,
+// S_lo = S_lo_temp4 + S_lo_temp2
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_S_lo = f_S_lo_temp4, f1, f_S_lo_temp2
+ nop.i 0
+}
+;;
+
+// If TBL,
+// Y_hi = S_hi
+// Y_lo = C_hi*p_odd + (S_hi*p_even + S_lo)
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_Y_lo_temp = f_S_hi, f_peven, f_S_lo
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p7) fma.s1 f_Y_lo = f_Tjhi_spos, f_Y_lo_temp, f_Tjlo_spos
+ nop.i 0
+}
+;;
+
+// Dummy multiply to generate inexact
+{ .mfi
+ nop.m 0
+ fmpy.s0 f_tmp = f_B2, f_B2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p6) fma.s1 f_Y_lo = f_C_hi, f_podd, f_Y_lo_temp
+ nop.i 0
+}
+;;
+
+// f8 = answer = Y_hi + Y_lo
+{ .mfi
+ nop.m 0
+(p7) fma.s0 f8 = f_Y_lo, f1, f_Tjhi_spos
+ nop.i 0
+}
+;;
+
+// f8 = answer = Y_hi + Y_lo
+{ .mfb
+ nop.m 0
+(p6) fma.s0 f8 = f_Y_lo, f1, f_S_hi
+ br.ret.sptk b0 // Exit for SINH_BY_TBL and SINH_BY_EXP
+}
+;;
+
+
+// Here if 0 < |x| < 0.25
+SINH_BY_POLY:
+{ .mmf
+ ldfe f_P6 = [r_ad2e],16
+ ldfe f_P5 = [r_ad2o],16
+ nop.f 0
+}
+;;
+
+{ .mmi
+ ldfe f_P4 = [r_ad2e],16
+ ldfe f_P3 = [r_ad2o],16
+ nop.i 0
+}
+;;
+
+{ .mmi
+ ldfe f_P2 = [r_ad2e],16
+ ldfe f_P1 = [r_ad2o],16
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_X3 = f_NORM_X, f_X2, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 f_X4 = f_X2, f_X2, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_poly65 = f_X2, f_P6, f_P5
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 f_poly43 = f_X2, f_P4, f_P3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_poly21 = f_X2, f_P2, f_P1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_poly6543 = f_X4, f_poly65, f_poly43
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f_poly6to1 = f_X4, f_poly6543, f_poly21
+ nop.i 0
+}
+;;
+
+// Dummy multiply to generate inexact
+{ .mfi
+ nop.m 0
+ fmpy.s0 f_tmp = f_P6, f_P6
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s0 f8 = f_poly6to1, f_X3, f_NORM_X
+ br.ret.sptk b0 // Exit SINH_BY_POLY
+}
+;;
+
+
+// Here if x denorm or unorm
+SINH_DENORM:
+// Determine if x really a denorm and not a unorm
+{ .mmf
+ getf.exp r_signexp_x = f_NORM_X
+ mov r_exp_denorm = 0x0c001 // Real denorms have exp < this
+ fmerge.s f_ABS_X = f0, f_NORM_X
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s0 p10,p0 = f8, f0 // Set denorm flag
+ nop.i 0
+}
+;;
+
+// Set p8 if really a denorm
+{ .mmi
+ and r_exp_x = r_exp_mask, r_signexp_x
+;;
+ cmp.lt p8,p9 = r_exp_x, r_exp_denorm
+ nop.i 0
+}
+;;
+
+// Identify denormal operands.
+{ .mfb
+ nop.m 0
+(p8) fcmp.ge.unc.s1 p6,p7 = f8, f0 // Test sign of denorm
+(p9) br.cond.sptk SINH_COMMON // Return to main path if x unorm
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fma.s0 f8 = f8,f8,f8 // If x +denorm, result=x+x^2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fnma.s0 f8 = f8,f8,f8 // If x -denorm, result=x-x^2
+ br.ret.sptk b0 // Exit if x denorm
+}
+;;
+
+
+// Here if |x| >= overflow limit
+SINH_HUGE:
+// for SINH_HUGE, put 24000 in exponent; take sign from input
+{ .mmi
+ mov r_exp_huge = 0x15dbf
+;;
+ setf.exp f_huge = r_exp_huge
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p8,p9
+{ .mfi
+ alloc r32 = ar.pfs,0,5,4,0
+(p8) fnma.s1 f_signed_hi_lo = f_huge, f1, f1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 f_signed_hi_lo = f_huge, f1, f1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s0 f_pre_result = f_signed_hi_lo, f_huge, f0
+ mov GR_Parameter_TAG = 126
+}
+;;
+
+GLOBAL_IEEE754_END(sinhl)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfe [GR_Parameter_Y] = f0,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfe [GR_Parameter_X] = f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = f_pre_result // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_sqrt.S b/libc/sysdeps/ia64/fpu/e_sqrt.S
new file mode 100644
index 000000000..53e60ef23
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_sqrt.S
@@ -0,0 +1,342 @@
+.file "sqrt.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//********************************************************************
+// History
+//********************************************************************
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+//********************************************************************
+//
+// Function: Combined sqrt(x), where
+// _
+// sqrt(x) = |x, for double precision x values
+//
+//********************************************************************
+//
+// Accuracy: Correctly Rounded
+//
+//********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f7 -f14
+//
+// General Purpose Registers:
+// r32-r36 (Locals)
+// r37-r40 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6, p7, p8
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// All faults and exceptions should be raised correctly.
+// sqrt(QNaN) = QNaN
+// sqrt(SNaN) = QNaN
+// sqrt(+/-0) = +/-0
+// sqrt(negative) = QNaN and error handling is called
+//
+//*********************************************************************
+//
+// Implementation:
+//
+// Modified Newton-Raphson Algorithm
+//
+//*********************************************************************
+
+GR_SAVE_PFS = r33
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(sqrt)
+{ .mfi
+ alloc r32= ar.pfs,0,5,4,0
+ frsqrta.s0 f7,p6=f8
+ nop.i 0
+} { .mlx
+ // BEGIN DOUBLE PRECISION MINIMUM LATENCY SQUARE ROOT ALGORITHM
+ nop.m 0
+ // exponent of +1/2 in r2
+ movl r2 = 0x0fffe;;
+} { .mmi
+ // +1/2 in f9
+ setf.exp f9 = r2
+ nop.m 0
+ nop.i 0
+} { .mlx
+ nop.m 0
+ // 3/2 in r3
+ movl r3=0x3fc00000;;
+} { .mfi
+ setf.s f10=r3
+ // Step (1)
+ // y0 = 1/sqrt(a) in f7
+ fclass.m.unc p7,p8 = f8,0x3A
+ nop.i 0;;
+} { .mlx
+ nop.m 0
+ // 5/2 in r2
+ movl r2 = 0x40200000
+} { .mlx
+ nop.m 0
+ // 63/8 in r3
+ movl r3 = 0x40fc0000;;
+} { .mfi
+ setf.s f11=r2
+ // Step (2)
+ // h = +1/2 * y0 in f6
+ (p6) fma.s1 f6=f9,f7,f0
+ nop.i 0
+} { .mfi
+ setf.s f12=r3
+ // Step (3)
+ // g = a * y0 in f7
+ (p6) fma.s1 f7=f8,f7,f0
+ nop.i 0
+} { .mfi
+ nop.m 0
+ mov f15 = f8
+ nop.i 0;;
+} { .mlx
+ nop.m 0
+ // 231/16 in r2
+ movl r2 = 0x41670000;;
+} { .mfi
+ setf.s f13=r2
+ // Step (4)
+ // e = 1/2 - g * h in f9
+ (p6) fnma.s1 f9=f7,f6,f9
+ nop.i 0
+} { .mlx
+ nop.m 0
+ // 35/8 in r3
+ movl r3 = 0x408c0000;;
+} { .mfi
+ setf.s f14=r3
+ // Step (5)
+ // S = 3/2 + 5/2 * e in f10
+ (p6) fma.s1 f10=f11,f9,f10
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (6)
+ // e2 = e * e in f11
+ (p6) fma.s1 f11=f9,f9,f0
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (7)
+ // t = 63/8 + 231/16 * e in f12
+ (p6) fma.s1 f12=f13,f9,f12
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (8)
+ // S1 = e + e2 * S in f10
+ (p6) fma.s1 f10=f11,f10,f9
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (9)
+ // e4 = e2 * e2 in f11
+ (p6) fma.s1 f11=f11,f11,f0
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (10)
+ // t1 = 35/8 + e * t in f9
+ (p6) fma.s1 f9=f9,f12,f14
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (11)
+ // G = g + S1 * g in f12
+ (p6) fma.s1 f12=f10,f7,f7
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (12)
+ // E = g * e4 in f7
+ (p6) fma.s1 f7=f7,f11,f0
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (13)
+ // u = S1 + e4 * t1 in f10
+ (p6) fma.s1 f10=f11,f9,f10
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (14)
+ // g1 = G + t1 * E in f7
+ (p6) fma.d.s1 f7=f9,f7,f12
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (15)
+ // h1 = h + u * h in f6
+ (p6) fma.s1 f6=f10,f6,f6
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (16)
+ // d = a - g1 * g1 in f9
+ (p6) fnma.s1 f9=f7,f7,f8
+ nop.i 0;;
+} { .mfb
+ nop.m 0
+ // Step (17)
+ // g2 = g1 + d * h1 in f7
+ (p6) fma.d.s0 f8=f9,f6,f7
+ (p6) br.ret.sptk b0 ;;
+}
+
+{ .mfb
+ nop.m 0
+ mov f8 = f7
+ (p8) br.ret.sptk b0 ;;
+}
+{ .mfb
+ (p7) mov r40 = 49
+ nop.f 0
+ (p7) br.cond.sptk __libm_error_region ;;
+}
+// END DOUBLE PRECISION MINIMUM LATENCY SQUARE ROOT ALGORITHM
+GLOBAL_IEEE754_END(sqrt)
+
+// Stack operations when calling error support.
+// (1) (2) (3) (call) (4)
+// sp -> + psp -> + psp -> + sp -> +
+// | | | |
+// | | <- GR_Y R3 ->| <- GR_RESULT | -> f8
+// | | | |
+// | <-GR_Y Y2->| Y2 ->| <- GR_Y |
+// | | | |
+// | | <- GR_X X1 ->| |
+// | | | |
+// sp-64 -> + sp -> + sp -> + +
+// save ar.pfs save b0 restore gp
+// save gp restore ar.pfs
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+//
+// This branch includes all those special values that are not negative,
+// with the result equal to frcpa(x)
+//
+
+.prologue
+// We are distinguishing between over(under)flow and letting
+// __libm_error_support set ERANGE or do anything else needed.
+
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+
+// (2)
+{ .mmi
+ stfd [GR_Parameter_Y] = f0,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfd [GR_Parameter_X] = f15 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+// (4)
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_sqrtf.S b/libc/sysdeps/ia64/fpu/e_sqrtf.S
new file mode 100644
index 000000000..daa20454d
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_sqrtf.S
@@ -0,0 +1,260 @@
+.file "sqrtf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+// History:
+//
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+//*********************************************************************
+//
+// Function: Combined sqrtf(x), where
+// _
+// sqrtf(x) = |x, for single precision x values
+//
+//********************************************************************
+//
+// Accuracy: Correctly Rounded
+//
+//********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f7 -f14
+//
+// General Purpose Registers:
+// r32-r36 (Locals)
+// r37-r40 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6, p7, p8
+//
+//********************************************************************
+//
+// IEEE Special Conditions:
+//
+// All faults and exceptions should be raised correctly.
+// sqrtf(QNaN) = QNaN
+// sqrtf(SNaN) = QNaN
+// sqrtf(+/-0) = +/-0
+// sqrtf(negative) = QNaN and error handling is called
+//
+//********************************************************************
+//
+// Implementation:
+//
+// Modified Newton-Raphson Algorithm
+//
+//********************************************************************
+
+
+GR_SAVE_B0 = r34
+GR_SAVE_PFS = r33
+GR_SAVE_GP = r35
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+FR_X = f13
+FR_Y = f0
+FR_RESULT = f8
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(sqrtf)
+{ .mlx
+ // BEGIN SINGLE PRECISION MINIMUM LATENCY SQUARE ROOT ALGORITHM
+ alloc r32= ar.pfs,0,5,4,0
+ // exponent of +1/2 in r2
+ movl r2 = 0x0fffe
+} { .mfi
+ // +1/2 in f12
+ nop.m 0
+ frsqrta.s0 f7,p6=f8
+ nop.i 0;;
+} { .mfi
+ setf.exp f12 = r2
+ // Step (1)
+ // y0 = 1/sqrt(a) in f7
+ fclass.m.unc p7,p8 = f8,0x3A
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Make a copy of x just in case
+ mov f13 = f8
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (2)
+ // H0 = 1/2 * y0 in f9
+ (p6) fma.s1 f9=f12,f7,f0
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (3)
+ // S0 = a * y0 in f7
+ (p6) fma.s1 f7=f8,f7,f0
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (4)
+ // d = 1/2 - S0 * H0 in f10
+ (p6) fnma.s1 f10=f7,f9,f12
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (0'')
+ // 3/2 = 1 + 1/2 in f12
+ (p6) fma.s1 f12=f12,f1,f1
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (5)
+ // e = 1 + 3/2 * d in f12
+ (p6) fma.s1 f12=f12,f10,f1
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (6)
+ // T0 = d * S0 in f11
+ (p6) fma.s1 f11=f10,f7,f0
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (7)
+ // G0 = d * H0 in f10
+ (p6) fma.s1 f10=f10,f9,f0
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (8)
+ // S1 = S0 + e * T0 in f7
+ (p6) fma.s.s1 f7=f12,f11,f7
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (9)
+ // H1 = H0 + e * G0 in f12
+ (p6) fma.s1 f12=f12,f10,f9
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (10)
+ // d1 = a - S1 * S1 in f9
+ (p6) fnma.s1 f9=f7,f7,f8
+ nop.i 0;;
+} { .mfb
+ nop.m 0
+ // Step (11)
+ // S = S1 + d1 * H1 in f7
+ (p6) fma.s.s0 f8=f9,f12,f7
+ (p6) br.ret.sptk b0 ;;
+// END SINGLE PRECISION MINIMUM LATENCY SQUARE ROOT ALGORITHM
+} { .mfb
+ nop.m 0
+ mov f8 = f7
+ (p8) br.ret.sptk b0 ;;
+}
+//
+// This branch includes all those special values that are not negative,
+// with the result equal to frcpa(x)
+//
+GLOBAL_IEEE754_END(sqrtf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mii
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ mov GR_Parameter_TAG = 50
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // Store Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/e_sqrtl.S b/libc/sysdeps/ia64/fpu/e_sqrtl.S
new file mode 100644
index 000000000..6a5735d45
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/e_sqrtl.S
@@ -0,0 +1,275 @@
+.file "sqrtl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//********************************************************************
+//
+// History:
+// 02/02/00 (hand-optimized)
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+//********************************************************************
+//
+// Function: Combined sqrtl(x), where
+// _
+// sqrtl(x) = |x, for double-extended precision x values
+//
+//********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f7 -f14
+//
+// General Purpose Registers:
+// r32-r36 (Locals)
+// r37-r40 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6, p7, p8
+//
+//********************************************************************
+//
+// IEEE Special Conditions:
+//
+// All faults and exceptions should be raised correctly.
+// sqrtl(QNaN) = QNaN
+// sqrtl(SNaN) = QNaN
+// sqrtl(+/-0) = +/-0
+// sqrtl(negative) = QNaN and error handling is called
+//
+//********************************************************************
+//
+// Implementation:
+//
+// Modified Newton-Raphson Algorithm
+//
+//********************************************************************
+
+GR_SAVE_PFS = r33
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+FR_X = f15
+FR_Y = f0
+FR_RESULT = f8
+
+.section .text
+GLOBAL_IEEE754_ENTRY(sqrtl)
+{ .mlx
+alloc r32= ar.pfs,0,5,4,0
+ // exponent of +1/2 in r2
+ movl r2 = 0x0fffe;;
+} { .mfi
+ // +1/2 in f10
+ setf.exp f12 = r2
+ // Step (1)
+ // y0 = 1/sqrt(a) in f7
+ frsqrta.s0 f7,p6=f8
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (2)
+ // H0 = +1/2 * y0 in f9
+ (p6) fma.s1 f9=f12,f7,f0
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (3)
+ // S0 = a * y0 in f7
+ (p6) fma.s1 f7=f8,f7,f0
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Make copy input x
+ mov f13=f8
+ nop.i 0
+} { .mfi
+ nop.m 0
+ fclass.m.unc p7,p8 = f8,0x3A
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (4)
+ // d0 = 1/2 - S0 * H0 in f10
+ (p6) fnma.s1 f10=f7,f9,f12
+ nop.i 0;;
+}
+{ .mfi
+ nop.m 0
+ mov f15=f8
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (5)
+ // H1 = H0 + d0 * H0 in f9
+ (p6) fma.s1 f9=f10,f9,f9
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (6)
+ // S1 = S0 + d0 * S0 in f7
+ (p6) fma.s1 f7=f10,f7,f7
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (7)
+ // d1 = 1/2 - S1 * H1 in f10
+ (p6) fnma.s1 f10=f7,f9,f12
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (8)
+ // H2 = H1 + d1 * H1 in f9
+ (p6) fma.s1 f9=f10,f9,f9
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (9)
+ // S2 = S1 + d1 * S1 in f7
+ (p6) fma.s1 f7=f10,f7,f7
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (10)
+ // d2 = 1/2 - S2 * H2 in f10
+ (p6) fnma.s1 f10=f7,f9,f12
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (11)
+ // e2 = a - S2 * S2 in f12
+ (p6) fnma.s1 f12=f7,f7,f8
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (12)
+ // S3 = S2 + d2 * S2 in f7
+ (p6) fma.s1 f7=f12,f9,f7
+ nop.i 0
+} { .mfi
+ nop.m 0
+ // Step (13)
+ // H3 = H2 + d2 * H2 in f9
+ (p6) fma.s1 f9=f10,f9,f9
+ nop.i 0;;
+} { .mfi
+ nop.m 0
+ // Step (14)
+ // e3 = a - S3 * S3 in f12
+ (p6) fnma.s1 f12=f7,f7,f8
+ nop.i 0;;
+} { .mfb
+ nop.m 0
+ // Step (15)
+ // S = S3 + e3 * H3 in f7
+ (p6) fma.s0 f8=f12,f9,f7
+ (p6) br.ret.sptk b0 ;;
+}
+{ .mfb
+ mov GR_Parameter_TAG = 48
+ mov f8 = f7
+ (p8) br.ret.sptk b0 ;;
+}
+//
+// This branch includes all those special values that are not negative,
+// with the result equal to frcpa(x)
+//
+
+
+// END DOUBLE EXTENDED PRECISION MINIMUM LATENCY SQUARE ROOT ALGORITHM
+GLOBAL_IEEE754_END(sqrtl)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region#)
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/fclrexcpt.c b/libc/sysdeps/ia64/fpu/fclrexcpt.c
new file mode 100644
index 000000000..aa815fc78
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/fclrexcpt.c
@@ -0,0 +1,39 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999 and
+ Jes Sorensen <Jes.Sorensen@cern.ch>, 2000
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+feclearexcept (int excepts)
+{
+ fenv_t fpsr;
+
+ /* Get the current state. */
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
+
+ /* Clear the relevant bits. */
+ fpsr &= ~(((fenv_t) ((excepts & FE_ALL_EXCEPT) << 13)));
+ /* Put the new state in effect. */
+ __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (fpsr) : "memory");
+
+ /* success */
+ return 0;
+}
diff --git a/libc/sysdeps/ia64/fpu/fedisblxcpt.c b/libc/sysdeps/ia64/fpu/fedisblxcpt.c
new file mode 100644
index 000000000..9e809a67d
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/fedisblxcpt.c
@@ -0,0 +1,37 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jes Sorensen <Jes.Sorensen@cern.ch>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fedisableexcept (int excepts)
+{
+ fenv_t old_fpsr;
+ fenv_t new_fpsr;
+
+ /* Get the current fpsr. */
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (old_fpsr));
+
+ new_fpsr = old_fpsr | ((fenv_t) excepts & FE_ALL_EXCEPT);
+
+ __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (new_fpsr) : "memory");
+
+ return (old_fpsr ^ FE_ALL_EXCEPT) & FE_ALL_EXCEPT;
+}
diff --git a/libc/sysdeps/ia64/fpu/feenablxcpt.c b/libc/sysdeps/ia64/fpu/feenablxcpt.c
new file mode 100644
index 000000000..4775395c7
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/feenablxcpt.c
@@ -0,0 +1,37 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jes Sorensen <Jes.Sorensen@cern.ch>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+feenableexcept (int excepts)
+{
+ fenv_t old_fpsr;
+ fenv_t new_fpsr;
+
+ /* Get the current fpsr. */
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (old_fpsr));
+
+ new_fpsr = old_fpsr & ~((fenv_t) excepts & FE_ALL_EXCEPT);
+
+ __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (new_fpsr) : "memory");
+
+ return (old_fpsr ^ FE_ALL_EXCEPT) & FE_ALL_EXCEPT;
+}
diff --git a/libc/sysdeps/ia64/fpu/fegetenv.c b/libc/sysdeps/ia64/fpu/fegetenv.c
new file mode 100644
index 000000000..5446b1649
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/fegetenv.c
@@ -0,0 +1,29 @@
+/* Store current floating-point environment.
+ Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetenv (fenv_t *envp)
+{
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (*envp));
+
+ return 0;
+}
diff --git a/libc/sysdeps/ia64/fpu/fegetexcept.c b/libc/sysdeps/ia64/fpu/fegetexcept.c
new file mode 100644
index 000000000..243dc535f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/fegetexcept.c
@@ -0,0 +1,31 @@
+/* Get enabled floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jes Sorensen <Jes.Sorensen@cern.ch>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetexcept (void)
+{
+ fenv_t fpsr;
+
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
+
+ return (fpsr ^ FE_ALL_EXCEPT) & FE_ALL_EXCEPT;
+}
diff --git a/libc/sysdeps/ia64/fpu/fegetround.c b/libc/sysdeps/ia64/fpu/fegetround.c
new file mode 100644
index 000000000..dca98e7b7
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/fegetround.c
@@ -0,0 +1,31 @@
+/* Return current rounding direction.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetround (void)
+{
+ fenv_t fpsr;
+
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
+
+ return (fpsr >> 10) & 3;
+}
diff --git a/libc/sysdeps/ia64/fpu/feholdexcpt.c b/libc/sysdeps/ia64/fpu/feholdexcpt.c
new file mode 100644
index 000000000..27c9a1109
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/feholdexcpt.c
@@ -0,0 +1,34 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 1997, 1999, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ /* Save the current state. */
+ fegetenv (envp);
+
+ /* set the trap disable bit */
+ __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (*envp | FE_ALL_EXCEPT));
+
+ return 1;
+}
+libm_hidden_def (feholdexcept)
diff --git a/libc/sysdeps/ia64/fpu/fesetenv.c b/libc/sysdeps/ia64/fpu/fesetenv.c
new file mode 100644
index 000000000..4c5c2edbb
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/fesetenv.c
@@ -0,0 +1,42 @@
+/* Install given floating-point environment.
+ Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jes Sorensen <Jes.Sorensen@cern.ch>, 2000
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fesetenv (const fenv_t *envp)
+{
+ fenv_t env;
+
+ /*
+ This stinks!
+ Magic encoding of default values: bit 62+63 set (which will never
+ happen for a user-space address) means it's not indirect.
+ */
+ if (((fenv_t) envp >> 62) == 0x03)
+ env = (fenv_t) envp & 0x3fffffffffffffff;
+ else
+ env = *envp;
+
+ __asm__ __volatile__ ("mov.m ar.fpsr=%0;;" :: "r" (env));
+
+ return 0;
+}
+libm_hidden_def (fesetenv)
diff --git a/libc/sysdeps/ia64/fpu/fesetround.c b/libc/sysdeps/ia64/fpu/fesetround.c
new file mode 100644
index 000000000..351bcc2f1
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/fesetround.c
@@ -0,0 +1,42 @@
+/* Set current rounding direction.
+ Copyright (C) 1999, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fesetround (int round)
+{
+ fenv_t fpsr;
+
+ if (round & ~3)
+ return 0;
+
+ /* Get the current state. */
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
+
+ /* Set the relevant bits. */
+ fpsr = (fpsr & ~(3UL << 10)) | ((fenv_t) round << 10);
+
+ /* Put the new state in effect. */
+ __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (fpsr) : "memory");
+
+ return 1;
+}
+libm_hidden_def (fesetround)
diff --git a/libc/sysdeps/ia64/fpu/feupdateenv.c b/libc/sysdeps/ia64/fpu/feupdateenv.c
new file mode 100644
index 000000000..544c38485
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/feupdateenv.c
@@ -0,0 +1,42 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+feupdateenv (const fenv_t *envp)
+{
+ fenv_t fpsr;
+
+
+ /* Get the current exception state. */
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
+
+ /* Install new environment. */
+ fesetenv (envp);
+
+ /* Raise the safed exception. Incidently for us the implementation
+ defined format of the values in objects of type fexcept_t is the
+ same as the ones specified using the FE_* constants. */
+ feraiseexcept ((int) fpsr & FE_ALL_EXCEPT);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libc/sysdeps/ia64/fpu/fgetexcptflg.c b/libc/sysdeps/ia64/fpu/fgetexcptflg.c
new file mode 100644
index 000000000..13c84ed25
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/fgetexcptflg.c
@@ -0,0 +1,35 @@
+/* Store current representation for exceptions.
+ Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ fenv_t fpsr;
+
+ /* Get the current exceptions. */
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
+
+ *flagp = (fexcept_t) ((fpsr >> 13) & excepts & FE_ALL_EXCEPT);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libc/sysdeps/ia64/fpu/fraiseexcpt.c b/libc/sysdeps/ia64/fpu/fraiseexcpt.c
new file mode 100644
index 000000000..3086ded81
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/fraiseexcpt.c
@@ -0,0 +1,79 @@
+/* Raise given exceptions.
+ Copyright (C) 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jes Sorensen <Jes.Sorensen@cern.ch>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <float.h>
+#include <math.h>
+#include <signal.h>
+#include <unistd.h>
+
+int
+feraiseexcept (int excepts)
+{
+ double tmp;
+ double dummy;
+
+ /* Raise exceptions represented by EXPECTS. But we must raise only
+ one signal at a time. It is important the if the overflow/underflow
+ exception and the inexact exception are given at the same time,
+ the overflow/underflow exception precedes the inexact exception. */
+
+ /* We do these bits in assembly to be certain GCC doesn't optimize
+ away something important. */
+
+ /* First: invalid exception. */
+ if (FE_INVALID & excepts)
+ {
+ /* One example of a invalid operation is 0 * Infinity. */
+ tmp = 0;
+ __asm__ __volatile__ ("frcpa.s0 %0,p1=f0,f0" : "=f" (tmp) : : "p1" );
+ }
+
+ /* Next: division by zero. */
+ if (FE_DIVBYZERO & excepts)
+ __asm__ __volatile__ ("frcpa.s0 %0,p1=f1,f0" : "=f" (tmp) : : "p1" );
+
+ /* Next: overflow. */
+ if (FE_OVERFLOW & excepts)
+ {
+ dummy = DBL_MAX;
+
+ __asm__ __volatile__ ("fadd.d.s0 %0=%1,%1" : "=f" (dummy) : "0" (dummy));
+ }
+
+ /* Next: underflow. */
+ if (FE_UNDERFLOW & excepts)
+ {
+ dummy = DBL_MIN;
+
+ __asm__ __volatile__ ("fnma.d.s0 %0=%1,%1,f0" : "=f" (tmp) : "f" (dummy));
+ }
+
+ /* Last: inexact. */
+ if (FE_INEXACT & excepts)
+ {
+ dummy = DBL_MAX;
+ __asm__ __volatile__ ("fadd.d.s0 %0=%1,f1" : "=f" (dummy) : "0" (dummy));
+ }
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (feraiseexcept)
diff --git a/libc/sysdeps/ia64/fpu/fsetexcptflg.c b/libc/sysdeps/ia64/fpu/fsetexcptflg.c
new file mode 100644
index 000000000..b3994827f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/fsetexcptflg.c
@@ -0,0 +1,41 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fenv_t fpsr;
+
+ /* Get the current exception state. */
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
+
+ fpsr &= ~(((fenv_t) excepts & FE_ALL_EXCEPT) << 13);
+
+ /* Set all the bits that were called for. */
+ fpsr |= ((*flagp & excepts & FE_ALL_EXCEPT) << 13);
+
+ /* And store it back. */
+ __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (fpsr) : "memory");
+
+ /* Success. */
+ return 0;
+}
diff --git a/libc/sysdeps/ia64/fpu/ftestexcept.c b/libc/sysdeps/ia64/fpu/ftestexcept.c
new file mode 100644
index 000000000..64c37d8c8
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/ftestexcept.c
@@ -0,0 +1,32 @@
+/* Test exception in current environment.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fetestexcept (int excepts)
+{
+ fenv_t fpsr;
+
+ /* Get current exceptions. */
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
+
+ return (fpsr >> 13) & excepts & FE_ALL_EXCEPT;
+}
diff --git a/libc/sysdeps/ia64/fpu/gen_import_file_list b/libc/sysdeps/ia64/fpu/gen_import_file_list
new file mode 100644
index 000000000..b8bd6a54f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/gen_import_file_list
@@ -0,0 +1,90 @@
+#!/bin/sh
+
+libm_dir=$1
+
+import() {
+ # $1 = name
+ # $2 = source file-name
+ # $3 = destination file-name
+ echo "$1 $libm_dir/$2 $3"
+}
+
+import_c() {
+ # $1 = name
+ # $2 = source file-name
+ # $3 = destination file-name
+ echo "$1 $libm_dir/$2 $3"
+}
+
+dummy_files="
+libm_cpu_defs.h
+libm_error_codes.h
+libm_support.h
+libm_error.c
+"
+
+for f in $dummy_files
+do
+ import_c DUMMY $f $f
+done
+
+import_c scalblnf scalblnf.c s_scalblnf.c
+
+for f in acos acosh asin atanh cosh exp2 exp10 fmod log2 pow remainder \
+ scalb sinh sqrt; do
+ for t in "" f l; do
+ import $f$t $f$t.s e_$f$t.S
+ done
+done
+
+for f in atan2 exp; do
+ for t in "" f; do
+ import $f$t $f$t.s e_$f$t.S
+ done
+done
+import "atan" atan.s s_atan.S
+import "atanf" atanf.s s_atanf.S
+import "atan(2)?l" atanl.s s_atanl.S
+import "exp(m1)?l" expl_m1.s s_expm1l.S
+
+for t in "" f l; do
+ import "log(10)?$t" log$t.s e_log$t.S
+ import tgamma$t tgamma$t.s w_tgamma$t.S
+ import "(hypot|cabs)$t" hypot$t.s e_hypot$t.S
+done
+
+for f in asinh cbrt ceil erf erfc fabs floor \
+ ilogb log1p logb modf nearbyint nextafter nexttoward \
+ rint round significand fdim fma fmax tanh trunc; do
+ for t in "" f l; do
+ import $f$t $f$t.s s_$f$t.S
+ done
+done
+
+for t in "" f l; do
+ import "(tan|cot)$t" tancot$t.s s_tan$t.S
+done
+
+for t in "" f l; do
+ import "(sin|cos)$t" sincos$t.s s_cos$t.S
+ import_c frexp$t frexp$t.c s_frexp$t.c
+ import_c ldexp$t ldexp$t.c s_ldexp$t.c
+ import_c scalbn$t scalbn$t.c s_scalbn$t.c
+done
+
+import expm1 exp_m1.s s_expm1.S
+import expm1f expf_m1.s s_expm1f.S
+
+for f in frexp frexpf frexpl reduce; do
+ import __libm_$f libm_$f.s libm_$f.S
+done
+
+for t in "" f l; do
+ import __libm_ldexp$t libm_ldexp$t.s s_libm_ldexp$t.S
+ import "(__libm_)?(sincos|cis)$t" libm_sincos$t.s libm_sincos$t.S
+ import __libm_lgamma$t libm_lgamma$t.s libm_lgamma$t.S
+ import __libm_scalbn$t libm_scalbn$t.s s_libm_scalbn$t.S
+done
+import __libm_scalblnf libm_scalblnf.s libm_scalblnf.S
+import "__libm_(sin|cos|sincos)_large" libm_sincos_large.s \
+ libm_sincos_large.S
diff --git a/libc/sysdeps/ia64/fpu/halfulp.c b/libc/sysdeps/ia64/fpu/halfulp.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/halfulp.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/import_check b/libc/sysdeps/ia64/fpu/import_check
new file mode 100644
index 000000000..21176f578
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/import_check
@@ -0,0 +1,81 @@
+#!/bin/sh
+
+objdir="$1"
+
+num_errors=0
+
+check_syms() {
+ global_count=0
+ entry_count=0
+ while read value type name; do
+ if [ $value = "U" ]; then
+ name=$type
+ # undefined symbols must start with double-underscore
+ if [ $(expr $name : '\(..\)') != "__" ]; then
+ echo -e "$(basename $file):\tError: undefined reference $name doesn't start with \"__\"."
+ num_errors=$(($num_errors + 1))
+ fi
+ continue
+ fi
+
+ case "$type" in
+ W)
+ entry_count=$(($entry_count + 1))
+ ;;
+ *)
+ entry_count=$(($entry_count + 1))
+ if [ "$(expr $name : '\(..\)')" != "__" ]; then
+ global_count=$(($global_count + 1))
+ fi
+ ;;
+ esac
+ done
+ if [ $entry_count -gt 1 -a $global_count -gt 0 ]; then
+ echo -e "$(basename $file):\tError: detected $global_count strong " \
+ "global and $entry_count entry-points."
+ num_errors=$(($num_errors + 1))
+ fi
+}
+
+check_file() {
+ file=$1
+ size=$(readelf -S $file | \
+ (sz=0; while read line; do
+ if echo $line | fgrep -q " .rodata"; then
+ read sz rest
+ break
+ fi
+ done;
+ printf "%d" 0x$sz))
+
+ summands=$(readelf -s $file | fgrep " OBJECT " | tr -s ' ' |
+ cut -f4 -d' ' | sed 's,$,+,')0
+ sum=$(($summands))
+ if [ $sum != $size ]; then
+ echo -e "$(basename $file):\tError: sum of objects=$sum bytes, .rodata size=$size bytes"
+ num_errors=$(($num_errors + 1))
+ fi
+
+ tmp=$(tempfile -p syms)
+ nm -g $file > $tmp
+ check_syms < $tmp
+}
+
+do_checks() {
+ echo "Note: 1 error expected in w_tgammal.o due to 64-byte alignment-padding."
+ while read func_pattern src_file dst_file; do
+ if [ "$(expr $dst_file : '.*\(S\)$')" = "S" ]; then
+ objfile=$(expr $dst_file : '\(.*\)[.]S$')
+ check_file $objdir/$objfile.o
+ fi
+ done
+}
+
+do_checks < import_file_list
+
+if [ $num_errors -gt 0 ]; then
+ echo "FAILURE: Detected $num_errors error(s)."
+ exit 1
+fi
+echo SUCCESS
+exit 0
diff --git a/libc/sysdeps/ia64/fpu/import_diffs b/libc/sysdeps/ia64/fpu/import_diffs
new file mode 100644
index 000000000..147280d5f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/import_diffs
@@ -0,0 +1,7 @@
+#!/bin/sh
+do_diffs() {
+ while read func_pattern src_file dst_file; do
+ diff -up $src_file $dst_file
+ done
+}
+do_diffs < import_file_list
diff --git a/libc/sysdeps/ia64/fpu/import_file.awk b/libc/sysdeps/ia64/fpu/import_file.awk
new file mode 100644
index 000000000..97fe77e18
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/import_file.awk
@@ -0,0 +1,151 @@
+BEGIN {
+ getline;
+ while (!match($0, "^/[/*] static char cvs_id")) {
+ print;
+ getline;
+ }
+ getline;
+ while (!match($0, "^// WARRANTY DISCLAIMER")) {
+ print;
+ if (!getline) {
+ break;
+ }
+ }
+ if (getline)
+ {
+ printf \
+"// Redistribution and use in source and binary forms, with or without\n" \
+"// modification, are permitted provided that the following conditions are\n" \
+"// met:\n" \
+"//\n" \
+"// * Redistributions of source code must retain the above copyright\n" \
+"// notice, this list of conditions and the following disclaimer.\n" \
+"//\n" \
+"// * Redistributions in binary form must reproduce the above copyright\n" \
+"// notice, this list of conditions and the following disclaimer in the\n" \
+"// documentation and/or other materials provided with the distribution.\n" \
+"//\n" \
+"// * The name of Intel Corporation may not be used to endorse or promote\n" \
+"// products derived from this software without specific prior written\n" \
+"// permission.\n\n";
+ if (LICENSE_ONLY == "y") {
+ do {
+ print;
+ } while (getline);
+ }
+ }
+}
+
+/^[.]data/ {
+ print "RODATA";
+ next;
+}
+/^([a-zA-Z_0-9]*_(tb[l0-9]|Tt|[tT]able|data|low|coeffs|constants|CONSTANTS|reduction|Stirling)(_?([1-9cdimpqstPQT]+|tail))?|(Constants|Poly|coeff)_.+|(double_sin_?cos|double_cis)[fl]?_.+):/ {
+ table_name=substr($1,1,length($1)-1);
+ printf "LOCAL_OBJECT_START(%s)\n", table_name;
+ getline;
+ while (!match($0, "^[ \t]*data")) {
+ print;
+ getline;
+ }
+ while (match($0, "(//|^[ \t]*data)")) {
+ print;
+ getline;
+ }
+ printf "LOCAL_OBJECT_END(%s)\n\n", table_name;
+ next;
+}
+/^[.]proc[ \t]+__libm_(error_region|callout)/ {
+ printf "LOCAL_LIBM_ENTRY(%s)\n", $2;
+ getline;
+ next;
+}
+/^[.]endp[ \t]+__libm_(error_region|callout)/ {
+ printf "LOCAL_LIBM_END(%s)\n", $2;
+ next;
+}
+/^[.]global/ {
+ split($2, part, "#");
+ name=part[1];
+ if (match(name, "^"FUNC"$")) {
+ next;
+ }
+}
+/^[.]proc/ {
+ split($2, part, "#");
+ name=part[1];
+ if (match(name, "^"FUNC"$")) {
+ local_funcs=("^(" \
+ "cis|cisf|cisl" \
+ "|cabs|cabsf|cabsl" \
+ "|cot|cotf|cotl" \
+ ")$");
+ ieee754_funcs=("^(" \
+ "atan2|atan2f|atan2l|atanl" \
+ "|cos|cosf|cosl" \
+ "|cosh|coshf|coshl" \
+ "|exp|expf|expl" \
+ "|exp10|exp10f|exp10l" \
+ "|expm1|expm1f|expm1l" \
+ "|fmod|fmodf|fmodl" \
+ "|hypot|hypotf|hypotl" \
+ "|fabs|fabsf|fabsl" \
+ "|floor|floorf|floorl" \
+ "|log1p|log1pf|log1pl" \
+ "|log|log10|log10f|log10l|log2l|logf|logl" \
+ "|remainder|remainderf|remainderl|" \
+ "|rint|rintf|rintl|" \
+ "|scalb|scalbf|scalbl" \
+ "|sin|sinf|sinl" \
+ "|sincos|sincosf|sincosl" \
+ "|sinh|sinhf|sinhl" \
+ "|sqrt|sqrtf|sqrtl" \
+ "|tan|tanf|tanl" \
+ ")$");
+ if (match(name, ieee754_funcs)) {
+ type="GLOBAL_IEEE754";
+ } else if (match (name, local_funcs)) {
+ type="LOCAL_LIBM";
+ } else {
+ type="GLOBAL_LIBM";
+ }
+ printf "%s_ENTRY(%s)\n", type, name;
+ getline;
+ while (!match($0, "^"name"#?:")) {
+ getline;
+ }
+ getline;
+ while (!match($0, "^.endp")) {
+ print
+ getline;
+ }
+ printf "%s_END(%s)\n", type, name;
+ if (match(name, "^exp10[fl]?$")) {
+ t=substr(name,6)
+ printf "weak_alias (exp10%s, pow10%s)\n", t, t
+ }
+ next;
+ }
+}
+/^[a-zA-Z_]+:/ {
+ split($1, part, ":");
+ name=part[1];
+ if (match(name, "^"FUNC"$")) {
+ printf "GLOBAL_LIBM_ENTRY(%s)\n", name;
+ getline;
+ while (!match($0, "^"name"#?:")) {
+ getline;
+ }
+ getline;
+ while (!match($0, "^.endp")) {
+ print
+ getline;
+ }
+ getline;
+ printf "GLOBAL_LIBM_END(%s)\n", name;
+ next;
+ }
+}
+
+{ print }
+
diff --git a/libc/sysdeps/ia64/fpu/import_intel_libm b/libc/sysdeps/ia64/fpu/import_intel_libm
new file mode 100644
index 000000000..1aaa646a9
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/import_intel_libm
@@ -0,0 +1,106 @@
+#!/bin/sh
+
+# Notes:
+
+# We don't import copysign finite, fpclassify, isinf, isnan, and signbit
+# since our own versions are nicer and just as correct and fast (except
+# perhaps that they don't handle non-finite arguments well?).
+#
+# Also, leave out cabs for now since it doesn't seem overridable in
+# glibc.
+
+libm_dir=$1
+
+import_s() {
+ # $1 = name
+ # $2 = source file-name
+ # $3 = destination file-name
+ echo "Importing $1 from $2 -> $3"
+ rm -f $3
+ awk -f import_file.awk FUNC=$1 $2 > $3
+}
+
+import_c() {
+ # $1 = name
+ # $2 = source file-name
+ # $3 = destination file-name
+ echo "Importing $1 from $2 -> $3"
+ rm -f $3
+ awk -f import_file.awk LICENSE_ONLY=y $2 > $3
+}
+
+do_imports() {
+ while read func_pattern src_file dst_file; do
+ case $src_file in
+ *.[ch])
+ import_c "$func_pattern" "$src_file" "$dst_file"
+ ;;
+ *)
+ import_s "$func_pattern" "$src_file" "$dst_file"
+ ;;
+ esac
+ done
+}
+
+./gen_import_file_list $libm_dir > import_file_list
+
+do_imports < import_file_list
+
+emptyfiles="
+e_gamma_r.c
+e_gammaf_r.c
+e_gammal_r.c
+s_sincos.c
+s_sincosf.c
+s_sincosl.c
+t_exp.c
+w_acosh.c
+w_acoshf.c
+w_acoshl.c
+w_atanh.c
+w_atanhf.c
+w_atanhl.c
+w_exp10.c
+w_exp10f.c
+w_exp10l.c
+w_exp2.c
+w_exp2f.c
+w_exp2l.c
+w_expl.c
+w_lgamma_r.c
+w_lgammaf_r.c
+w_lgammal_r.c
+w_log2.c
+w_log2f.c
+w_log2l.c
+w_sinh.c
+w_sinhf.c
+w_sinhl.c
+"
+for f in $emptyfiles
+do
+ rm -f $f
+ echo "/* Not needed. */" > $f
+done
+
+removedfiles="
+libm_atan2_reg.S
+s_ldexp.S
+s_ldexpf.S
+s_ldexpl.S
+s_scalbn.S
+s_scalbnf.S
+s_scalbnl.S
+"
+
+rm -f $removedfiles
+
+for f in lgammaf_r.c lgammal_r.c lgamma_r.c
+do
+ import_c $f $libm_dir/$f e_$f
+done
+
+for f in lgamma.c lgammaf.c lgammal.c
+do
+ import_c $f $libm_dir/$f w_$f
+done
diff --git a/libc/sysdeps/ia64/fpu/k_rem_pio2.c b/libc/sysdeps/ia64/fpu/k_rem_pio2.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/k_rem_pio2.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/k_rem_pio2f.c b/libc/sysdeps/ia64/fpu/k_rem_pio2f.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/k_rem_pio2f.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/k_rem_pio2l.c b/libc/sysdeps/ia64/fpu/k_rem_pio2l.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/k_rem_pio2l.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/libc_libm_error.c b/libc/sysdeps/ia64/fpu/libc_libm_error.c
new file mode 100644
index 000000000..5a34878d7
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libc_libm_error.c
@@ -0,0 +1,14 @@
+/* Error handling in libm-style for libc. */
+
+#include <errno.h>
+
+#include "libm_support.h"
+
+
+void
+__libm_error_support (void *arg1, void *arg2, void *retval,
+ error_types input_tag)
+{
+ __set_errno (ERANGE);
+}
+libc_hidden_def (__libm_error_support)
diff --git a/libc/sysdeps/ia64/fpu/libm-symbols.h b/libc/sysdeps/ia64/fpu/libm-symbols.h
new file mode 100644
index 000000000..5b5e4b7d7
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm-symbols.h
@@ -0,0 +1,64 @@
+#include <sysdep.h>
+#undef ret /* get rid of the stupid "ret" macro; it breaks br.ret */
+
+/* Support for compatible assembler handling. */
+
+#ifdef __ELF__
+# define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+# define ASM_TYPE_DIRECTIVE(name,T) .type name,T
+#else
+# define ASM_SIZE_DIRECTIVE(name)
+# define ASM_TYPE_DIRECTIVE(name,T)
+#endif
+
+#define LOCAL_LIBM_ENTRY(name) \
+ .proc name; \
+ name:
+
+#define LOCAL_LIBM_END(name) \
+ .endp name; \
+ ASM_SIZE_DIRECTIVE(name)
+
+
+#define RODATA .rodata
+#define LOCAL_OBJECT_START(name) \
+ name:; \
+ ASM_TYPE_DIRECTIVE(name, @object)
+#define LOCAL_OBJECT_END(name) \
+ ASM_SIZE_DIRECTIVE(name)
+
+#define GLOBAL_LIBM_ENTRY(name) \
+ LOCAL_LIBM_ENTRY(name); \
+ .global name
+#define GLOBAL_LIBM_END(name) LOCAL_LIBM_END(name)
+
+#define INTERNAL_LIBM_ENTRY(name) \
+ GLOBAL_LIBM_ENTRY(__libm_##name); \
+ .global __libm_##name
+#define INTERNAL_LIBM_END(name) GLOBAL_LIBM_END(__libm_##name)
+
+#define WEAK_LIBM_ENTRY(name) \
+ .align 32; \
+ LOCAL_LIBM_ENTRY(__##name); \
+ .global __##name; \
+ __##name:
+#define WEAK_LIBM_END(name) \
+ weak_alias (__##name, name); \
+ .hidden __##name; \
+ LOCAL_LIBM_END(__##name); \
+ ASM_SIZE_DIRECTIVE(__##name); \
+ ASM_TYPE_DIRECTIVE(__##name, @function)
+
+#define GLOBAL_IEEE754_ENTRY(name) \
+ WEAK_LIBM_ENTRY(name); \
+ .global __ieee754_##name; \
+ .hidden __ieee754_##name; \
+ __ieee754_##name:
+#define GLOBAL_IEEE754_END(name) \
+ WEAK_LIBM_END(name); \
+ ASM_SIZE_DIRECTIVE(__ieee754_##name); \
+ ASM_TYPE_DIRECTIVE(__ieee754_##name, @function)
+
+#if defined ASSEMBLER && !defined NOT_IN_libc
+# define __libm_error_support HIDDEN_JUMPTARGET(__libm_error_support)
+#endif
diff --git a/libc/sysdeps/ia64/fpu/libm-test-ulps b/libc/sysdeps/ia64/fpu/libm-test-ulps
new file mode 100644
index 000000000..c5a2a0854
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm-test-ulps
@@ -0,0 +1,1146 @@
+# Begin of automatic generation
+
+# cacos
+Test "Imaginary part of: cacos (0.75 + 1.25 i) == 1.11752014915610270578240049553777969 - 1.13239363160530819522266333696834467 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+# cacosh
+Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+ildouble: 7
+ldouble: 7
+Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# casin
+Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+# casinh
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 5
+ldouble: 5
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 5
+ldouble: 5
+Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# catan
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 4
+idouble: 4
+ildouble: 1
+ldouble: 1
+Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+double: 1
+idouble: 1
+
+# ccos
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+ildouble: 1
+ldouble: 1
+
+# ccosh
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+float: 1
+ifloat: 1
+
+# cexp
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+float: 1
+ifloat: 1
+Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+ildouble: 1
+ldouble: 1
+
+# clog
+Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# cos
+Test "cos (0.80190127184058835) == 0.69534156199418473":
+double: 1
+idouble: 1
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "cos (pi/2) == 0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# cpow
+Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+ildouble: 6
+ldouble: 6
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 3
+ldouble: 3
+Test "Real part of: cpow (2 + 0 i, 10 + 0 i) == 1024.0 + 0.0 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 2
+ifloat: 2
+ildouble: 4
+ldouble: 4
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+# csin
+Test "Real part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
+float: 1
+ifloat: 1
+
+# csinh
+Test "Real part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+
+# csqrt
+Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+
+# ctan
+Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+float: 1
+ifloat: 1
+ildouble: 24
+ldouble: 24
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+ifloat: 1
+Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# erf
+Test "erf (1.25) == 0.922900128256458230136523481197281140":
+double: 1
+idouble: 1
+
+# erfc
+Test "erfc (0.75) == 0.288844366346484868401062165408589223":
+float: 1
+ifloat: 1
+Test "erfc (1.25) == 0.0770998717435417698634765188027188596":
+ildouble: 1
+ldouble: 1
+Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
+double: 1
+idouble: 1
+Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# exp10
+Test "exp10 (-1) == 0.1":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "exp10 (3) == 1000":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+# expm1
+Test "expm1 (1) == M_El - 1.0":
+ildouble: 1
+ldouble: 1
+
+# gamma
+Test "gamma (-0.5) == log(2*sqrt(pi))":
+ildouble: 1
+ldouble: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+
+# j0
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+
+# j1
+Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+
+# jn
+Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+Test "jn (10, -1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "jn (10, 1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+float: 4
+ifloat: 4
+ildouble: 1
+ldouble: 1
+Test "jn (3, -1.0) == -0.0195633539826684059189053216217515083":
+ildouble: 1
+ldouble: 1
+Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+double: 1
+idouble: 1
+Test "jn (3, 1.0) == 0.0195633539826684059189053216217515083":
+ildouble: 1
+ldouble: 1
+Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# lgamma
+Test "lgamma (-0.5) == log(2*sqrt(pi))":
+ildouble: 1
+ldouble: 1
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# log
+Test "log (e) == 1":
+float: 1
+ifloat: 1
+
+# log10
+Test "log10 (e) == log10(e)":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# sincos
+Test "sincos (0.80190127184058835, &sin_res, &cos_res) puts 0.69534156199418473 in cos_res":
+double: 1
+idouble: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# tan
+Test "tan (pi/4) == 1":
+double: 1
+idouble: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+ifloat: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# y0
+Test "y0 (0.125) == -1.38968062514384052915582277745018693":
+ildouble: 1
+ldouble: 1
+Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "y0 (2.0) == 0.510375672649745119596606592727157873":
+double: 1
+idouble: 1
+Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# y1
+Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "y1 (1.5) == -0.412308626973911295952829820633445323";
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# yn
+Test "yn (0, 0.125) == -1.38968062514384052915582277745018693":
+ildouble: 1
+ldouble: 1
+Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (0, 2.0) == 0.510375672649745119596606592727157873":
+double: 1
+idouble: 1
+Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "yn (1, 1.5) == -0.412308626973911295952829820633445323";
+float: 1
+ifloat: 1
+ldouble: 1
+ildouble: 1
+Test "yn (1, 2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+float: 2
+ifloat: 2
+Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+double: 1
+idouble: 1
+
+# Maximal error of functions:
+Function: Imaginary part of "cacos":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cacosh":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+ildouble: 7
+ldouble: 7
+
+Function: Imaginary part of "cacosh":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "casin":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "catanh":
+double: 4
+idouble: 4
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccos":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccos":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cexp":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "cexp":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cpow":
+double: 2
+float: 5
+idouble: 2
+ifloat: 5
+ildouble: 6
+ldouble: 6
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: Real part of "csin":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csin":
+float: 1
+ifloat: 1
+
+Function: Real part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csqrt":
+float: 1
+ifloat: 1
+
+Function: Real part of "ctan":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "ctan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ctanh":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ctanh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 24
+ldouble: 24
+
+Function: "erf":
+double: 1
+idouble: 1
+
+Function: "erfc":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "exp10":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: "expm1":
+ildouble: 1
+ldouble: 1
+
+Function: "gamma":
+ildouble: 1
+ldouble: 1
+
+Function: "hypot":
+float: 1
+ifloat: 1
+
+Function: "j0":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "jn":
+double: 3
+float: 4
+idouble: 3
+ifloat: 4
+ildouble: 2
+ldouble: 2
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log":
+float: 1
+ifloat: 1
+
+Function: "log10":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "tan":
+double: 1
+idouble: 1
+
+Function: "tgamma":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+# end of automatic generation
diff --git a/libc/sysdeps/ia64/fpu/libm_cpu_defs.h b/libc/sysdeps/ia64/fpu/libm_cpu_defs.h
new file mode 100644
index 000000000..516128c40
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_cpu_defs.h
@@ -0,0 +1,156 @@
+/* file: libm_cpu_defs.h */
+
+
+// Copyright (c) 2000 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+
+#ifndef __LIBM_CPU_DEFS__H_INCLUDED__
+#define __LIBM_CPU_DEFS__H_INCLUDED__
+
+void __libm_sincos_pi4(double,double*,double*,int);
+void __libm_y0y1(double , double *, double *);
+void __libm_j0j1(double , double *, double *);
+double __libm_j0(double);
+double __libm_j1(double);
+double __libm_jn(int,double);
+double __libm_y0(double);
+double __libm_y1(double);
+double __libm_yn(int,double);
+
+double __libm_copysign (double, double);
+float __libm_copysignf (float, float);
+long double __libm_copysignl (long double, long double);
+
+extern double sqrt(double);
+extern double fabs(double);
+extern double log(double);
+extern double log1p(double);
+extern double sqrt(double);
+extern double sin(double);
+extern double exp(double);
+extern double modf(double, double *);
+extern double asinh(double);
+extern double acosh(double);
+extern double atanh(double);
+extern double tanh(double);
+extern double erf(double);
+extern double erfc(double);
+extern double j0(double);
+extern double j1(double);
+extern double jn(int, double);
+extern double y0(double);
+extern double y1(double);
+extern double yn(int, double);
+
+extern float fabsf(float);
+extern float asinhf(float);
+extern float acoshf(float);
+extern float atanhf(float);
+extern float tanhf(float);
+extern float erff(float);
+extern float erfcf(float);
+extern float j0f(float);
+extern float j1f(float);
+extern float jnf(int, float);
+extern float y0f(float);
+extern float y1f(float);
+extern float ynf(int, float);
+
+extern long double log1pl(long double);
+extern long double logl(long double);
+extern long double sqrtl(long double);
+extern long double expl(long double);
+extern long double fabsl(long double);
+
+#if !(defined(SIZE_LONG_INT_32) || defined(SIZE_LONG_INT_64))
+#error long int size not established; define SIZE_LONG_INT_32 or SIZE_LONG_INT_64
+#endif
+
+#if (defined(SIZE_LONG_INT_32) && defined(SIZE_LONG_INT_64))
+#error multiple long int size definitions; define SIZE_LONG_INT_32 or SIZE_LONG_INT_64
+#endif
+
+#if !(defined(SIZE_LONG_LONG_INT_32) || defined(SIZE_LONG_LONG_INT_64))
+#error long long int size not established; define SIZE_LONG_LONG_INT_32 or SIZE_LONG_LONG_INT_64
+#endif
+
+#if (defined(SIZE_LONG_LONG_INT_32) && defined(SIZE_LONG_LONG_INT_64))
+#error multiple long long int size definitions; define SIZE_LONG_LONG_INT_32 or SIZE_LONG_LONG_INT_64
+#endif
+
+#define HI_SIGNIFICAND_LESS(X, HI) ((X)->hi_significand < 0x ## HI)
+#define f64abs(x) ((x) < 0.0 ? -(x) : (x))
+
+#define FP80_DECLARE()
+#define FP80_SET()
+#define FP80_RESET()
+
+#ifdef _LIBC
+# include <math.h>
+#else
+
+static const unsigned INF[] = {
+ DOUBLE_HEX(7ff00000, 00000000),
+ DOUBLE_HEX(fff00000, 00000000)
+};
+
+static const double _zeroo = 0.0;
+static const double _bigg = 1.0e300;
+static const double _ponee = 1.0;
+static const double _nonee = -1.0;
+
+#define INVALID (_zeroo * *((double*)&INF[0]))
+#define PINF *((double*)&INF[0])
+#define NINF -PINF
+#define PINF_DZ (_ponee/_zeroo)
+#define X_TLOSS 1.41484755040568800000e+16
+#endif
+
+/* Set these appropriately to make thread Safe */
+#define ERRNO_RANGE errno = ERANGE
+#define ERRNO_DOMAIN errno = EDOM
+
+#ifndef _LIBC
+#if defined(__ICC) || defined(__ICL) || defined(__ECC) || defined(__ECL)
+# pragma warning( disable : 68 ) /* #68: integer conversion resulted in a change of sign */
+# pragma warning( disable : 186 ) /* #186: pointless comparison of unsigned integer with zero */
+# pragma warning( disable : 1572 ) /* #1572: floating-point equality and inequality comparisons are unreliable */
+#endif
+#endif
+
+#endif /*__LIBM_CPU_DEFS__H_INCLUDED__*/
diff --git a/libc/sysdeps/ia64/fpu/libm_error.c b/libc/sysdeps/ia64/fpu/libm_error.c
new file mode 100644
index 000000000..8ef4bb5a7
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_error.c
@@ -0,0 +1,4295 @@
+/* file: libm_error.c */
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 2/02/00: Initial version
+// 3/22/00: Updated to support flexible and dynamic error handling.
+// 8/16/00: Changed all matherr function-calls to use the pmatherr
+// function-pointers.
+// 10/03/00: Corrected a scalb type.
+// 11/28/00: Changed INPUT_XL to INPUT_XD for scalb_underflow case.
+// 12/07/00: Added code to make scalbn error support equivalent to ldexp.
+// 2/07/01: Added __declspec(align(16)) to long double constants to correct
+// alignment problem.
+// 4/23/01: Added code for remquo
+// 6/07/01: Added code for fdim, lrint, lround, llrint, llround
+// Deleted code for remquo
+// 8/15/01: Added code for scalbln, nexttoward
+// 12/10/01: Added code for erfc
+// 12/27/01: Added code for degree argument functions
+// 01/02/02: Added code for tand, cotd
+// 01/15/02: Corrected SVID/XOPEN code for log1p, pow, and acosh
+// 01/25/02: Corrected ISOC for lgamma and gamma to return EDOM for neg ints
+// 01/28/02: Corrected SVID/XOPEN stderr message for log2
+// 05/20/02: Added code for cot
+// 07/01/02: Added code for sinhcosh
+// 10/04/02: Underflow detection in ISOC path redefined to
+// be zero rather than tiny and inexact
+// 12/06/02: Added code for annuity and compound
+// 01/30/03: Corrected test for underflow in ISOC path to not set denormal
+// 04/10/03: Corrected ISOC branch for gamma/lgamma to return ERANGE for neg ints.
+// Added code for tgamma
+// 04/11/03: Corrected POSIX/SVID/XOPEN branches for gamma/lgamma
+// to return EDOM for neg ints.
+// 09/08/03: Corrected XOPEN/SVID result for pow overflow with neg x, pos y.
+// 10/14/03: Added ILP32 ifdef
+// 12/12/03: Corrected XOPEN/SVID results for powf_zero_to_negative,
+// powl_neg_to_non_integer, atan2f_zero, atan2df_zero,
+// acoshf_lt_one, acosh_lt_one.
+// 12/07/04: Cast name strings as char *.
+// 12/08/04: Corrected POSIX behavior for atan2_zero, acos_gt_one, asin_gt_one,
+// log_negative, log10_negative, log1p_negative, and log2_negative.
+// Added SVID and XOPEN case log2l_zero.
+// 12/13/04: Corrected POSIX behavior for exp2_overflow, exp2_underflow,
+// exp10_overflow, exp10_underflow. Added ISOC to set errno for
+// exp10_underflow.
+// 12/14/04: Corrected POSIX behavior for nextafter_overflow,
+// nextafter_underflow, nexttoward_overflow, nexttoward_underflow.
+// Added ISOC to set errno for nextafter and nexttoward underflow.
+// 12/15/04: Corrected POSIX behavior for exp, exp2, and exp10 underflow.
+// 03/31/05: Added missing ALIGNIT statement to 6 float constants.
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "libm_support.h"
+
+#ifdef _LIBC
+# define pmatherr matherr
+# define pmatherrf matherrf
+# define pmatherrl matherrl
+#else
+_LIB_VERSION_TYPE
+#if defined( __POSIX__ )
+_LIB_VERSIONIMF = _POSIX_;
+#elif defined( __XOPEN__ )
+_LIB_VERSIONIMF = _XOPEN_;
+#elif defined( __SVID__ )
+_LIB_VERSIONIMF = _SVID_;
+#elif defined( __IEEE__ )
+_LIB_VERSIONIMF = _IEEE_;
+#else
+_LIB_VERSIONIMF = _ISOC_;
+#endif
+
+/************************************************************/
+/* matherrX function pointers and setusermatherrX functions */
+/************************************************************/
+int (*pmatherrf)(struct exceptionf*) = MATHERR_F;
+int (*pmatherr)(struct EXC_DECL_D*) = MATHERR_D;
+int (*pmatherrl)(struct exceptionl*) = matherrl;
+
+void __libm_setusermatherrf( int(*user_merrf)(struct exceptionf*) )
+{ pmatherrf = ( (user_merrf==NULL)? (MATHERR_F) : (user_merrf) ); }
+
+void __libm_setusermatherr( int(*user_merr)(struct EXC_DECL_D*) )
+{ pmatherr = ( (user_merr==NULL)? (MATHERR_D) : (user_merr) ); }
+
+void __libm_setusermatherrl( int(*user_merrl)(struct exceptionl*) )
+{ pmatherrl = ( (user_merrl==NULL)? (matherrl) : (user_merrl) ); }
+
+#endif /* !_LIBC */
+
+/***********************************************/
+/* error-handling function, libm_error_support */
+/***********************************************/
+void __libm_error_support(void *arg1,void *arg2,void *retval,error_types input_tag)
+{
+
+# ifdef __cplusplus
+struct __exception exc;
+# else
+struct exception exc;
+# endif
+
+struct exceptionf excf;
+struct exceptionl excl;
+
+# ifdef __GNUC__
+#define ALIGNIT __attribute__ ((__aligned__ (16)))
+# elif defined opensource
+#define ALIGNIT
+# else
+#define ALIGNIT __declspec(align(16))
+# endif
+
+# ifdef SIZE_LONG_INT_64
+#define __INT_64__ signed long
+# else
+# if ILP32
+#define __INT_64__ signed long long
+# else
+#define __INT_64__ __int64
+# endif
+# endif
+
+
+#define STATIC static
+
+ALIGNIT
+STATIC const char float_inf[4] = {0x00,0x00,0x80,0x7F};
+ALIGNIT
+STATIC const char float_huge[4] = {0xFF,0xFF,0x7F,0x7F};
+ALIGNIT
+STATIC const char float_zero[4] = {0x00,0x00,0x00,0x00};
+ALIGNIT
+STATIC const char float_neg_inf[4] = {0x00,0x00,0x80,0xFF};
+ALIGNIT
+STATIC const char float_neg_huge[4] = {0xFF,0xFF,0x7F,0xFF};
+ALIGNIT
+STATIC const char float_neg_zero[4] = {0x00,0x00,0x00,0x80};
+ALIGNIT
+STATIC const char double_inf[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x7F};
+#ifndef _LIBC
+ALIGNIT
+STATIC const char double_huge[8] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x7F};
+#endif
+ALIGNIT
+STATIC const char double_zero[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ALIGNIT
+STATIC const char double_neg_inf[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF};
+#ifndef _LIBC
+ALIGNIT
+STATIC const char double_neg_huge[8] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF};
+#endif
+ALIGNIT
+STATIC const char double_neg_zero[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80};
+ALIGNIT
+STATIC const char long_double_inf[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00};
+ALIGNIT
+#ifndef _LIBC
+STATIC const char long_double_huge[16] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00};
+#endif
+ALIGNIT
+STATIC const char long_double_zero[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ALIGNIT
+STATIC const char long_double_neg_inf[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00};
+ALIGNIT
+#ifndef _LIBC
+STATIC const char long_double_neg_huge[16] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x00,0x00,0x00,0x00,0x00,0x00};
+#endif
+ALIGNIT
+STATIC const char long_double_neg_zero[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00};
+
+
+#define RETVAL_HUGE_VALL *(long double *)retval = *(long double *)long_double_inf
+#define RETVAL_NEG_HUGE_VALL *(long double *)retval = *(long double *)long_double_neg_inf
+#define RETVAL_HUGEL *(long double *)retval = (long double)*(float *)float_huge
+#define RETVAL_NEG_HUGEL *(long double *)retval =(long double)*(float*)float_neg_huge
+
+#define RETVAL_HUGE_VALD *(double *)retval = *(double *) double_inf
+#define RETVAL_NEG_HUGE_VALD *(double *)retval = *(double *) double_neg_inf
+#define RETVAL_HUGED *(double *)retval = (double) *(float *)float_huge
+#define RETVAL_NEG_HUGED *(double *)retval = (double) *(float *) float_neg_huge
+
+#define RETVAL_HUGE_VALF *(float *)retval = *(float *) float_inf
+#define RETVAL_NEG_HUGE_VALF *(float *)retval = *(float *) float_neg_inf
+#define RETVAL_HUGEF *(float *)retval = *(float *) float_huge
+#define RETVAL_NEG_HUGEF *(float *)retval = *(float *) float_neg_huge
+
+#define ZEROL_VALUE *(long double *)long_double_zero
+#define ZEROD_VALUE *(double *)double_zero
+#define ZEROF_VALUE *(float *)float_zero
+
+#define RETVAL_ZEROL *(long double *)retval = *(long double *)long_double_zero
+#define RETVAL_ZEROD *(double *)retval = *(double *)double_zero
+#define RETVAL_ZEROF *(float *)retval = *(float *)float_zero
+
+#define RETVAL_NEG_ZEROL *(long double *)retval = *(long double *)long_double_neg_zero
+#define RETVAL_NEG_ZEROD *(double *)retval = *(double *)double_neg_zero
+#define RETVAL_NEG_ZEROF *(float *)retval = *(float *)float_neg_zero
+
+#define RETVAL_ONEL *(long double *)retval = (long double) 1.0
+#define RETVAL_ONED *(double *)retval = 1.0
+#define RETVAL_ONEF *(float *)retval = 1.0f
+
+#define NOT_MATHERRL excl.arg1=*(long double *)arg1;excl.arg2=*(long double *)arg2;excl.retval=*(long double *)retval;if(!pmatherrl(&excl))
+#define NOT_MATHERRD exc.arg1=*(double *)arg1;exc.arg2=*(double *)arg2;exc.retval=*(double *)retval;if(!pmatherr(&exc))
+#define NOT_MATHERRF excf.arg1=*(float *)arg1;excf.arg2=*(float *)arg2;excf.retval=*(float *)retval;if(!pmatherrf(&excf))
+
+#define ifSVID if(_LIB_VERSIONIMF==_SVID_)
+
+#define NAMEL excl.name
+#define NAMED exc.name
+#define NAMEF excf.name
+
+//
+// These should work OK for MS because they are ints -
+// leading underbars are not necessary.
+//
+
+#define DOMAIN 1
+#define SING 2
+#define OVERFLOW 3
+#define UNDERFLOW 4
+#define TLOSS 5
+#define PLOSS 6
+
+#define SINGL excl.type = SING
+#define DOMAINL excl.type = DOMAIN
+#define OVERFLOWL excl.type = OVERFLOW
+#define UNDERFLOWL excl.type = UNDERFLOW
+#define TLOSSL excl.type = TLOSS
+#define SINGD exc.type = SING
+#define DOMAIND exc.type = DOMAIN
+#define OVERFLOWD exc.type = OVERFLOW
+#define UNDERFLOWD exc.type = UNDERFLOW
+#define TLOSSD exc.type = TLOSS
+#define SINGF excf.type = SING
+#define DOMAINF excf.type = DOMAIN
+#define OVERFLOWF excf.type = OVERFLOW
+#define UNDERFLOWF excf.type = UNDERFLOW
+#define TLOSSF excf.type = TLOSS
+
+#define INPUT_XL (excl.arg1=*(long double*)arg1)
+#define INPUT_XD (exc.arg1=*(double*)arg1)
+#define INPUT_XF (excf.arg1=*(float*)arg1)
+#define INPUT_YL (excl.arg2=*(long double*)arg2)
+#define INPUT_YD (exc.arg2=*(double*)arg2)
+#define INPUT_YF (excf.arg2=*(float*)arg2)
+#define INPUT_RESL (*(long double *)retval)
+#define INPUT_RESD (*(double *)retval)
+#define INPUT_RESF (*(float *)retval)
+#define INPUT_RESI64 (*(__INT_64__ *)retval)
+
+#define WRITEL_LOG_ZERO fputs("logl: SING error\n",stderr)
+#define WRITED_LOG_ZERO fputs("log: SING error\n",stderr)
+#define WRITEF_LOG_ZERO fputs("logf: SING error\n",stderr)
+#define WRITEL_LOG_NEGATIVE fputs("logl: DOMAIN error\n",stderr)
+#define WRITED_LOG_NEGATIVE fputs("log: DOMAIN error\n",stderr)
+#define WRITEF_LOG_NEGATIVE fputs("logf: DOMAIN error\n",stderr)
+#define WRITEL_Y0_ZERO fputs("y0l: DOMAIN error\n",stderr)
+#define WRITED_Y0_ZERO fputs("y0: DOMAIN error\n",stderr)
+#define WRITEF_Y0_ZERO fputs("y0f: DOMAIN error\n",stderr)
+#define WRITEL_Y0_NEGATIVE fputs("y0l: DOMAIN error\n",stderr)
+#define WRITED_Y0_NEGATIVE fputs("y0: DOMAIN error\n",stderr)
+#define WRITEF_Y0_NEGATIVE fputs("y0f: DOMAIN error\n",stderr)
+#define WRITEL_Y1_ZERO fputs("y1l: DOMAIN error\n",stderr)
+#define WRITED_Y1_ZERO fputs("y1: DOMAIN error\n",stderr)
+#define WRITEF_Y1_ZERO fputs("y1f: DOMAIN error\n",stderr)
+#define WRITEL_Y1_NEGATIVE fputs("y1l: DOMAIN error\n",stderr)
+#define WRITED_Y1_NEGATIVE fputs("y1: DOMAIN error\n",stderr)
+#define WRITEF_Y1_NEGATIVE fputs("y1f: DOMAIN error\n",stderr)
+#define WRITEL_YN_ZERO fputs("ynl: DOMAIN error\n",stderr)
+#define WRITED_YN_ZERO fputs("yn: DOMAIN error\n",stderr)
+#define WRITEF_YN_ZERO fputs("ynf: DOMAIN error\n",stderr)
+#define WRITEL_YN_NEGATIVE fputs("ynl: DOMAIN error\n",stderr)
+#define WRITED_YN_NEGATIVE fputs("yn: DOMAIN error\n",stderr)
+#define WRITEF_YN_NEGATIVE fputs("ynf: DOMAIN error\n",stderr)
+#define WRITEL_LOG1P_ZERO fputs("log1pl: SING error\n",stderr)
+#define WRITED_LOG1P_ZERO fputs("log1p: SING error\n",stderr)
+#define WRITEF_LOG1P_ZERO fputs("log1pf: SING error\n",stderr)
+#define WRITEL_LOG1P_NEGATIVE fputs("log1pl: DOMAIN error\n",stderr)
+#define WRITED_LOG1P_NEGATIVE fputs("log1p: DOMAIN error\n",stderr)
+#define WRITEF_LOG1P_NEGATIVE fputs("log1pf: DOMAIN error\n",stderr)
+#define WRITEL_LOG10_ZERO fputs("log10l: SING error\n",stderr)
+#define WRITED_LOG10_ZERO fputs("log10: SING error\n",stderr)
+#define WRITEF_LOG10_ZERO fputs("log10f: SING error\n",stderr)
+#define WRITEL_LOG10_NEGATIVE fputs("log10l: DOMAIN error\n",stderr)
+#define WRITED_LOG10_NEGATIVE fputs("log10: DOMAIN error\n",stderr)
+#define WRITEF_LOG10_NEGATIVE fputs("log10f: DOMAIN error\n",stderr)
+#define WRITEL_LOG2_ZERO fputs("log2l: SING error\n",stderr)
+#define WRITED_LOG2_ZERO fputs("log2: SING error\n",stderr)
+#define WRITEF_LOG2_ZERO fputs("log2f: SING error\n",stderr)
+#define WRITEL_LOG2_NEGATIVE fputs("log2l: DOMAIN error\n",stderr)
+#define WRITED_LOG2_NEGATIVE fputs("log2: DOMAIN error\n",stderr)
+#define WRITEF_LOG2_NEGATIVE fputs("log2f: DOMAIN error\n",stderr)
+#define WRITEL_POW_ZERO_TO_ZERO fputs("powl(0,0): DOMAIN error\n",stderr)
+#define WRITED_POW_ZERO_TO_ZERO fputs("pow(0,0): DOMAIN error\n",stderr)
+#define WRITEF_POW_ZERO_TO_ZERO fputs("powf(0,0): DOMAIN error\n",stderr)
+#define WRITEL_POW_ZERO_TO_NEGATIVE fputs("powl(0,negative): DOMAIN error\n",stderr)
+#define WRITED_POW_ZERO_TO_NEGATIVE fputs("pow(0,negative): DOMAIN error\n",stderr)
+#define WRITEF_POW_ZERO_TO_NEGATIVE fputs("powf(0,negative): DOMAIN error\n",stderr)
+#define WRITEL_POW_NEG_TO_NON_INTEGER fputs("powl(negative,non-integer): DOMAIN error\n",stderr)
+#define WRITED_POW_NEG_TO_NON_INTEGER fputs("pow(negative,non-integer): DOMAIN error\n",stderr)
+#define WRITEF_POW_NEG_TO_NON_INTEGER fputs("powf(negative,non-integer): DOMAIN error\n",stderr)
+#define WRITEL_ATAN2_ZERO_BY_ZERO fputs("atan2l: DOMAIN error\n",stderr)
+#define WRITED_ATAN2_ZERO_BY_ZERO fputs("atan2: DOMAIN error\n",stderr)
+#define WRITEF_ATAN2_ZERO_BY_ZERO fputs("atan2f: DOMAIN error\n",stderr)
+#define WRITEL_SQRT fputs("sqrtl: DOMAIN error\n",stderr)
+#define WRITED_SQRT fputs("sqrt: DOMAIN error\n",stderr)
+#define WRITEF_SQRT fputs("sqrtf: DOMAIN error\n",stderr)
+#define WRITEL_FMOD fputs("fmodl: DOMAIN error\n",stderr)
+#define WRITED_FMOD fputs("fmod: DOMAIN error\n",stderr)
+#define WRITEF_FMOD fputs("fmodf: DOMAIN error\n",stderr)
+#define WRITEL_REM fputs("remainderl: DOMAIN error\n",stderr)
+#define WRITED_REM fputs("remainder: DOMAIN error\n",stderr)
+#define WRITEF_REM fputs("remainderf: DOMAIN error\n",stderr)
+#define WRITEL_ACOS fputs("acosl: DOMAIN error\n",stderr)
+#define WRITED_ACOS fputs("acos: DOMAIN error\n",stderr)
+#define WRITEF_ACOS fputs("acosf: DOMAIN error\n",stderr)
+#define WRITEL_ASIN fputs("asinl: DOMAIN error\n",stderr)
+#define WRITED_ASIN fputs("asin: DOMAIN error\n",stderr)
+#define WRITEF_ASIN fputs("asinf: DOMAIN error\n",stderr)
+#define WRITEL_ACOSH fputs("acoshl: DOMAIN error\n",stderr)
+#define WRITED_ACOSH fputs("acosh: DOMAIN error\n",stderr)
+#define WRITEF_ACOSH fputs("acoshf: DOMAIN error\n",stderr)
+#define WRITEL_ATANH_GT_ONE fputs("atanhl: DOMAIN error\n",stderr)
+#define WRITED_ATANH_GT_ONE fputs("atanh: DOMAIN error\n",stderr)
+#define WRITEF_ATANH_GT_ONE fputs("atanhf: DOMAIN error\n",stderr)
+#define WRITEL_ATANH_EQ_ONE fputs("atanhl: SING error\n",stderr)
+#define WRITED_ATANH_EQ_ONE fputs("atanh: SING error\n",stderr)
+#define WRITEF_ATANH_EQ_ONE fputs("atanhf: SING error\n",stderr)
+#define WRITEL_LGAMMA_NEGATIVE fputs("lgammal: SING error\n",stderr)
+#define WRITED_LGAMMA_NEGATIVE fputs("lgamma: SING error\n",stderr)
+#define WRITEF_LGAMMA_NEGATIVE fputs("lgammaf: SING error\n",stderr)
+#define WRITEL_GAMMA_NEGATIVE fputs("gammal: SING error\n",stderr)
+#define WRITED_GAMMA_NEGATIVE fputs("gamma: SING error\n",stderr)
+#define WRITEF_GAMMA_NEGATIVE fputs("gammaf: SING error\n",stderr)
+#define WRITEL_TGAMMA_NEGATIVE fputs("tgammal: SING error\n",stderr)
+#define WRITED_TGAMMA_NEGATIVE fputs("tgamma: SING error\n",stderr)
+#define WRITEF_TGAMMA_NEGATIVE fputs("tgammaf: SING error\n",stderr)
+#define WRITEL_J0_TLOSS fputs("j0l: TLOSS error\n",stderr)
+#define WRITEL_Y0_TLOSS fputs("y0l: TLOSS error\n",stderr)
+#define WRITEL_J1_TLOSS fputs("j1l: TLOSS error\n",stderr)
+#define WRITEL_Y1_TLOSS fputs("y1l: TLOSS error\n",stderr)
+#define WRITEL_JN_TLOSS fputs("jnl: TLOSS error\n",stderr)
+#define WRITEL_YN_TLOSS fputs("ynl: TLOSS error\n",stderr)
+#define WRITED_J0_TLOSS fputs("j0: TLOSS error\n",stderr)
+#define WRITED_Y0_TLOSS fputs("y0: TLOSS error\n",stderr)
+#define WRITED_J1_TLOSS fputs("j1: TLOSS error\n",stderr)
+#define WRITED_Y1_TLOSS fputs("y1: TLOSS error\n",stderr)
+#define WRITED_JN_TLOSS fputs("jn: TLOSS error\n",stderr)
+#define WRITED_YN_TLOSS fputs("yn: TLOSS error\n",stderr)
+#define WRITEF_J0_TLOSS fputs("j0f: TLOSS error\n",stderr)
+#define WRITEF_Y0_TLOSS fputs("y0f: TLOSS error\n",stderr)
+#define WRITEF_J1_TLOSS fputs("j1f: TLOSS error\n",stderr)
+#define WRITEF_Y1_TLOSS fputs("y1f: TLOSS error\n",stderr)
+#define WRITEF_JN_TLOSS fputs("jnf: TLOSS error\n",stderr)
+#define WRITEF_YN_TLOSS fputs("ynf: TLOSS error\n",stderr)
+#define WRITEL_ACOSD fputs("acosdl: DOMAIN error\n",stderr)
+#define WRITED_ACOSD fputs("acosd: DOMAIN error\n",stderr)
+#define WRITEF_ACOSD fputs("acosdf: DOMAIN error\n",stderr)
+#define WRITEL_ASIND fputs("asindl: DOMAIN error\n",stderr)
+#define WRITED_ASIND fputs("asind: DOMAIN error\n",stderr)
+#define WRITEF_ASIND fputs("asindf: DOMAIN error\n",stderr)
+#define WRITEL_ATAN2D_ZERO_BY_ZERO fputs("atan2dl: DOMAIN error\n",stderr)
+#define WRITED_ATAN2D_ZERO_BY_ZERO fputs("atan2d: DOMAIN error\n",stderr)
+#define WRITEF_ATAN2D_ZERO_BY_ZERO fputs("atan2df: DOMAIN error\n",stderr)
+
+
+/***********************/
+/* IEEE Path */
+/***********************/
+if(_LIB_VERSIONIMF==_IEEE_) return;
+
+/***********************/
+/* C9X Path */
+/***********************/
+else if(_LIB_VERSIONIMF==_ISOC_)
+{
+ switch(input_tag)
+ {
+ case logl_zero:
+ case log_zero:
+ case logf_zero:
+ case log10l_zero:
+ case log10_zero:
+ case log10f_zero:
+ case log2l_zero:
+ case log2_zero:
+ case log2f_zero:
+ case log1pl_zero:
+ case log1p_zero:
+ case log1pf_zero:
+ case powl_overflow:
+ case pow_overflow:
+ case powf_overflow:
+ case expl_overflow:
+ case exp_overflow:
+ case expf_overflow:
+ case exp2l_overflow:
+ case exp2_overflow:
+ case exp2f_overflow:
+ case exp10l_overflow:
+ case exp10_overflow:
+ case exp10f_overflow:
+ case expm1l_overflow:
+ case expm1_overflow:
+ case expm1f_overflow:
+ case hypotl_overflow:
+ case hypot_overflow:
+ case hypotf_overflow:
+ case sinhl_overflow:
+ case sinh_overflow:
+ case sinhf_overflow:
+ case atanhl_eq_one:
+ case atanh_eq_one:
+ case atanhf_eq_one:
+ case scalbl_overflow:
+ case scalb_overflow:
+ case scalbf_overflow:
+ case coshl_overflow:
+ case cosh_overflow:
+ case coshf_overflow:
+ case nextafterl_overflow:
+ case nextafter_overflow:
+ case nextafterf_overflow:
+ case nextafterl_underflow:
+ case nextafter_underflow:
+ case nextafterf_underflow:
+ case nexttowardl_overflow:
+ case nexttoward_overflow:
+ case nexttowardf_overflow:
+ case nexttowardl_underflow:
+ case nexttoward_underflow:
+ case nexttowardf_underflow:
+ case scalbnl_overflow:
+ case scalbn_overflow:
+ case scalbnf_overflow:
+ case scalblnl_overflow:
+ case scalbln_overflow:
+ case scalblnf_overflow:
+ case ldexpl_overflow:
+ case ldexp_overflow:
+ case ldexpf_overflow:
+ case lgammal_overflow:
+ case lgamma_overflow:
+ case lgammaf_overflow:
+ case gammal_overflow:
+ case gamma_overflow:
+ case gammaf_overflow:
+ case lgammal_negative:
+ case lgamma_negative:
+ case lgammaf_negative:
+ case gammal_negative:
+ case gamma_negative:
+ case gammaf_negative:
+ case ilogbl_zero:
+ case ilogb_zero:
+ case ilogbf_zero:
+ case fdiml_overflow:
+ case fdim_overflow:
+ case fdimf_overflow:
+ case llrintl_large:
+ case llrint_large:
+ case llrintf_large:
+ case llroundl_large:
+ case llround_large:
+ case llroundf_large:
+ case lrintl_large:
+ case lrint_large:
+ case lrintf_large:
+ case lroundl_large:
+ case lround_large:
+ case lroundf_large:
+ case tandl_overflow:
+ case tand_overflow:
+ case tandf_overflow:
+ case cotdl_overflow:
+ case cotd_overflow:
+ case cotdf_overflow:
+ case cotl_overflow:
+ case cot_overflow:
+ case cotf_overflow:
+ case sinhcoshl_overflow:
+ case sinhcosh_overflow:
+ case sinhcoshf_overflow:
+ case annuityl_overflow:
+ case annuity_overflow:
+ case annuityf_overflow:
+ case compoundl_overflow:
+ case compound_overflow:
+ case compoundf_overflow:
+ case tgammal_overflow:
+ case tgamma_overflow:
+ case tgammaf_overflow:
+ {
+ ERRNO_RANGE; break;
+ }
+ case powl_underflow:
+ case expl_underflow:
+ case exp10l_underflow:
+ case exp2l_underflow:
+ case scalbl_underflow:
+ case scalbnl_underflow:
+ case scalblnl_underflow:
+ case ldexpl_underflow:
+ case erfcl_underflow:
+ case annuityl_underflow:
+ case compoundl_underflow:
+ {
+ /* Test for zero by testing 64 significand bits for zero. An integer
+ test is needed so denormal flag is not set by a floating-point test */
+ if ( INPUT_RESI64 == 0 ) ERRNO_RANGE;
+ break;
+ }
+ case pow_underflow:
+ case exp_underflow:
+ case exp10_underflow:
+ case exp2_underflow:
+ case scalb_underflow:
+ case scalbn_underflow:
+ case scalbln_underflow:
+ case ldexp_underflow:
+ case erfc_underflow:
+ case annuity_underflow:
+ case compound_underflow:
+ {
+ /* Test for zero by testing exp and significand bits for zero. An integer
+ test is needed so denormal flag is not set by a floating-point test */
+ if ( (INPUT_RESI64 << 1) == 0 ) ERRNO_RANGE;
+ break;
+ }
+ case powf_underflow:
+ case expf_underflow:
+ case exp10f_underflow:
+ case exp2f_underflow:
+ case scalbf_underflow:
+ case scalbnf_underflow:
+ case scalblnf_underflow:
+ case ldexpf_underflow:
+ case erfcf_underflow:
+ case annuityf_underflow:
+ case compoundf_underflow:
+ {
+ /* Test for zero by testing exp and significand bits for zero. An integer
+ test is needed so denormal flag is not set by a floating-point test */
+ if ( (INPUT_RESI64 << 33) == 0 ) ERRNO_RANGE;
+ break;
+ }
+ case logl_negative:
+ case log_negative:
+ case logf_negative:
+ case log10l_negative:
+ case log10_negative:
+ case log10f_negative:
+ case log2l_negative:
+ case log2_negative:
+ case log2f_negative:
+ case log1pl_negative:
+ case log1p_negative:
+ case log1pf_negative:
+ case sqrtl_negative:
+ case sqrt_negative:
+ case sqrtf_negative:
+ case atan2l_zero:
+ case atan2_zero:
+ case atan2f_zero:
+ case powl_zero_to_negative:
+ case powl_neg_to_non_integer:
+ case pow_zero_to_negative:
+ case pow_neg_to_non_integer:
+ case powf_zero_to_negative:
+ case powf_neg_to_non_integer:
+ case fmodl_by_zero:
+ case fmod_by_zero:
+ case fmodf_by_zero:
+ case atanhl_gt_one:
+ case atanh_gt_one:
+ case atanhf_gt_one:
+ case acosl_gt_one:
+ case acos_gt_one:
+ case acosf_gt_one:
+ case asinl_gt_one:
+ case asin_gt_one:
+ case asinf_gt_one:
+ case logbl_zero:
+ case logb_zero:
+ case logbf_zero:
+ case acoshl_lt_one:
+ case acosh_lt_one:
+ case acoshf_lt_one:
+ case y0l_zero:
+ case y0_zero:
+ case y0f_zero:
+ case y1l_zero:
+ case y1_zero:
+ case y1f_zero:
+ case ynl_zero:
+ case yn_zero:
+ case ynf_zero:
+ case y0l_negative:
+ case y0_negative:
+ case y0f_negative:
+ case y1l_negative:
+ case y1_negative:
+ case y1f_negative:
+ case ynl_negative:
+ case yn_negative:
+ case ynf_negative:
+ case acosdl_gt_one:
+ case acosd_gt_one:
+ case acosdf_gt_one:
+ case asindl_gt_one:
+ case asind_gt_one:
+ case asindf_gt_one:
+ case atan2dl_zero:
+ case atan2d_zero:
+ case atan2df_zero:
+ case annuityl_by_zero:
+ case annuity_by_zero:
+ case annuityf_by_zero:
+ case annuityl_less_m1:
+ case annuity_less_m1:
+ case annuityf_less_m1:
+ case compoundl_by_zero:
+ case compound_by_zero:
+ case compoundf_by_zero:
+ case compoundl_less_m1:
+ case compound_less_m1:
+ case compoundf_less_m1:
+ case tgammal_negative:
+ case tgamma_negative:
+ case tgammaf_negative:
+ {
+ ERRNO_DOMAIN; break;
+ }
+ default:
+ break;
+ }
+ return;
+}
+
+/***********************/
+/* _POSIX_ Path */
+/***********************/
+
+else if(_LIB_VERSIONIMF==_POSIX_)
+{
+switch(input_tag)
+ {
+ case gammal_overflow:
+ case lgammal_overflow:
+ case tgammal_overflow:
+ {
+ RETVAL_HUGE_VALL; ERRNO_RANGE; break;
+ }
+ case gamma_overflow:
+ case lgamma_overflow:
+ case tgamma_overflow:
+ {
+ RETVAL_HUGE_VALD; ERRNO_RANGE; break;
+ }
+ case gammaf_overflow:
+ case lgammaf_overflow:
+ case tgammaf_overflow:
+ {
+ RETVAL_HUGE_VALF; ERRNO_RANGE; break;
+ }
+ case gammal_negative:
+ case gamma_negative:
+ case gammaf_negative:
+ case lgammal_negative:
+ case lgamma_negative:
+ case lgammaf_negative:
+ case tgammal_negative:
+ case tgamma_negative:
+ case tgammaf_negative:
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case ldexpl_overflow:
+ case ldexpl_underflow:
+ case ldexp_overflow:
+ case ldexp_underflow:
+ case ldexpf_overflow:
+ case ldexpf_underflow:
+ case scalbnl_overflow:
+ case scalbnl_underflow:
+ case scalbn_overflow:
+ case scalbn_underflow:
+ case scalbnf_overflow:
+ case scalbnf_underflow:
+ case scalblnl_overflow:
+ case scalblnl_underflow:
+ case scalbln_overflow:
+ case scalbln_underflow:
+ case scalblnf_overflow:
+ case scalblnf_underflow:
+ case tandl_overflow:
+ case tand_overflow:
+ case tandf_overflow:
+ case cotdl_overflow:
+ case cotd_overflow:
+ case cotdf_overflow:
+ case cotl_overflow:
+ case cot_overflow:
+ case cotf_overflow:
+ case sinhcoshl_overflow:
+ case sinhcosh_overflow:
+ case sinhcoshf_overflow:
+ case nextafterl_overflow:
+ case nextafter_overflow:
+ case nextafterf_overflow:
+ case nextafterl_underflow:
+ case nextafter_underflow:
+ case nextafterf_underflow:
+ case nexttowardl_overflow:
+ case nexttoward_overflow:
+ case nexttowardf_overflow:
+ case nexttowardl_underflow:
+ case nexttoward_underflow:
+ case nexttowardf_underflow:
+ {
+ ERRNO_RANGE; break;
+ }
+ case atanhl_gt_one:
+ case atanhl_eq_one:
+ /* atanhl(|x| >= 1) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case atanh_gt_one:
+ case atanh_eq_one:
+ /* atanh(|x| >= 1) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case atanhf_gt_one:
+ case atanhf_eq_one:
+ /* atanhf(|x| >= 1) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case sqrtl_negative:
+ /* sqrtl(x < 0) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case sqrt_negative:
+ /* sqrt(x < 0) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case sqrtf_negative:
+ /* sqrtf(x < 0) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case y0l_zero:
+ case y1l_zero:
+ case ynl_zero:
+ /* y0l(0) */
+ /* y1l(0) */
+ /* ynl(0) */
+ {
+ RETVAL_NEG_HUGE_VALL; ERRNO_DOMAIN; break;
+ }
+ case y0_zero:
+ case y1_zero:
+ case yn_zero:
+ /* y0(0) */
+ /* y1(0) */
+ /* yn(0) */
+ {
+ RETVAL_NEG_HUGE_VALD; ERRNO_DOMAIN; break;
+ }
+ case y0f_zero:
+ case y1f_zero:
+ case ynf_zero:
+ /* y0f(0) */
+ /* y1f(0) */
+ /* ynf(0) */
+ {
+ RETVAL_NEG_HUGE_VALF; ERRNO_DOMAIN; break;
+ }
+ case y0l_negative:
+ case y1l_negative:
+ case ynl_negative:
+ /* y0l(x < 0) */
+ /* y1l(x < 0) */
+ /* ynl(x < 0) */
+ {
+#ifndef _LIBC
+ RETVAL_NEG_HUGE_VALL;
+#endif
+ ERRNO_DOMAIN; break;
+ }
+ case y0_negative:
+ case y1_negative:
+ case yn_negative:
+ /* y0(x < 0) */
+ /* y1(x < 0) */
+ /* yn(x < 0) */
+ {
+ RETVAL_NEG_HUGE_VALD; ERRNO_DOMAIN; break;
+ }
+ case y0f_negative:
+ case y1f_negative:
+ case ynf_negative:
+ /* y0f(x < 0) */
+ /* y1f(x < 0) */
+ /* ynf(x < 0) */
+ {
+ RETVAL_NEG_HUGE_VALF; ERRNO_DOMAIN; break;
+ }
+ case logl_zero:
+ case log1pl_zero:
+ case log10l_zero:
+ case log2l_zero:
+ /* logl(0) */
+ /* log1pl(-1) */
+ /* log10l(0) */
+ /* log2l(0) */
+ {
+ RETVAL_NEG_HUGE_VALL; ERRNO_RANGE; break;
+ }
+ case log_zero:
+ case log1p_zero:
+ case log10_zero:
+ case log2_zero:
+ /* log(0) */
+ /* log1p(-1) */
+ /* log10(0) */
+ /* log2(0) */
+ {
+ RETVAL_NEG_HUGE_VALD; ERRNO_RANGE; break;
+ }
+ case logf_zero:
+ case log1pf_zero:
+ case log10f_zero:
+ case log2f_zero:
+ /* logf(0) */
+ /* log1pf(-1) */
+ /* log10f(0) */
+ /* log2f(0) */
+ {
+ RETVAL_NEG_HUGE_VALF; ERRNO_RANGE; break;
+ }
+ case logl_negative:
+ case log1pl_negative:
+ case log10l_negative:
+ case log2l_negative:
+ /* logl(x < 0) */
+ /* log1pl(x < -1) */
+ /* log10l(x < 0) */
+ /* log2l(x < 0) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case log_negative:
+ case log1p_negative:
+ case log10_negative:
+ case log2_negative:
+ /* log(x < 0) */
+ /* log1p(x < -1) */
+ /* log10(x < 0) */
+ /* log2(x < 0) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case logf_negative:
+ case log1pf_negative:
+ case log10f_negative:
+ case log2f_negative:
+ /* logf(x < 0) */
+ /* log1pf(x < -1) */
+ /* log10f(x < 0) */
+ /* log2f(x < 0) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case expl_overflow:
+ case exp10l_overflow:
+ case exp2l_overflow:
+ /* expl overflow */
+ /* exp10l overflow */
+ /* exp2l overflow */
+ {
+ RETVAL_HUGE_VALL; ERRNO_RANGE; break;
+ }
+ case exp_overflow:
+ case exp10_overflow:
+ case exp2_overflow:
+ /* exp overflow */
+ /* exp10 overflow */
+ /* exp2 overflow */
+ {
+ RETVAL_HUGE_VALD; ERRNO_RANGE; break;
+ }
+ case expf_overflow:
+ case exp10f_overflow:
+ case exp2f_overflow:
+ /* expf overflow */
+ {
+ RETVAL_HUGE_VALF; ERRNO_RANGE; break;
+ }
+ case expl_underflow:
+ case exp10l_underflow:
+ case exp2l_underflow:
+ /* expl underflow */
+ /* exp10l underflow */
+ /* exp2l underflow */
+ {
+ ERRNO_RANGE; break;
+ }
+ case exp_underflow:
+ case exp10_underflow:
+ case exp2_underflow:
+ /* exp underflow */
+ /* exp10 underflow */
+ /* exp2 underflow */
+ {
+ ERRNO_RANGE; break;
+ }
+ case expf_underflow:
+ case exp10f_underflow:
+ case exp2f_underflow:
+ /* expf underflow */
+ /* exp10f underflow */
+ /* exp2f underflow */
+ {
+ ERRNO_RANGE; break;
+ }
+ case j0l_gt_loss:
+ case y0l_gt_loss:
+ case j1l_gt_loss:
+ case y1l_gt_loss:
+ case jnl_gt_loss:
+ case ynl_gt_loss:
+ /* jn and yn doubl-extended> XLOSS */
+ {
+ RETVAL_ZEROL; ERRNO_RANGE; break;
+ }
+ case j0_gt_loss:
+ case y0_gt_loss:
+ case j1_gt_loss:
+ case y1_gt_loss:
+ case jn_gt_loss:
+ case yn_gt_loss:
+ /* jn and yn double > XLOSS */
+ {
+ RETVAL_ZEROD; ERRNO_RANGE; break;
+ }
+ case j0f_gt_loss:
+ case y0f_gt_loss:
+ case j1f_gt_loss:
+ case y1f_gt_loss:
+ case jnf_gt_loss:
+ case ynf_gt_loss:
+ /* j0n and y0n > XLOSS */
+ {
+ RETVAL_ZEROF; ERRNO_RANGE; break;
+ }
+ case powl_zero_to_zero:
+ /* powl 0**0 */
+ {
+ break;
+ }
+ case pow_zero_to_zero:
+ /* pow 0**0 */
+ {
+ break;
+ }
+ case powf_zero_to_zero:
+ /* powf 0**0 */
+ {
+ break;
+ }
+ case powl_overflow:
+ case annuityl_overflow:
+ case compoundl_overflow:
+ /* powl(x,y) overflow */
+ {
+ if (INPUT_RESL < ZEROL_VALUE /*0*/) RETVAL_NEG_HUGE_VALL;
+ else RETVAL_HUGE_VALL;
+ ERRNO_RANGE; break;
+ }
+ case pow_overflow:
+ case annuity_overflow:
+ case compound_overflow:
+ /* pow(x,y) overflow */
+ {
+ if (INPUT_RESD < ZEROD_VALUE /*0*/) RETVAL_NEG_HUGE_VALD;
+ else RETVAL_HUGE_VALD;
+ ERRNO_RANGE; break;
+ }
+ case powf_overflow:
+ case annuityf_overflow:
+ case compoundf_overflow:
+ /* powf(x,y) overflow */
+ {
+ if (INPUT_RESF < ZEROF_VALUE /*0*/) RETVAL_NEG_HUGE_VALF;
+ else RETVAL_HUGE_VALF;
+ ERRNO_RANGE; break;
+ }
+ case powl_underflow:
+ case annuityl_underflow:
+ case compoundl_underflow:
+ /* powl(x,y) underflow */
+ {
+ RETVAL_ZEROL; ERRNO_RANGE; break;
+ }
+ case pow_underflow:
+ case annuity_underflow:
+ case compound_underflow:
+ /* pow(x,y) underflow */
+ {
+ RETVAL_ZEROD; ERRNO_RANGE; break;
+ }
+ case powf_underflow:
+ case annuityf_underflow:
+ case compoundf_underflow:
+ /* powf(x,y) underflow */
+ {
+ RETVAL_ZEROF; ERRNO_RANGE; break;
+ }
+ case annuityl_by_zero:
+ case annuityl_less_m1:
+ case compoundl_by_zero:
+ case compoundl_less_m1:
+ case annuity_by_zero:
+ case annuity_less_m1:
+ case compound_by_zero:
+ case compound_less_m1:
+ case annuityf_by_zero:
+ case annuityf_less_m1:
+ case compoundf_by_zero:
+ case compoundf_less_m1:
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case powl_zero_to_negative:
+ /* 0**neg */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case pow_zero_to_negative:
+ /* 0**neg */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case powf_zero_to_negative:
+ /* 0**neg */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case powl_neg_to_non_integer:
+ /* neg**non_integral */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case pow_neg_to_non_integer:
+ /* neg**non_integral */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case powf_neg_to_non_integer:
+ /* neg**non-integral */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case powl_nan_to_zero:
+ /* powl(NaN,0.0) */
+ /* Special Error */
+ {
+ break;
+ }
+ case pow_nan_to_zero:
+ /* pow(NaN,0.0) */
+ {
+ break;
+ }
+ case powf_nan_to_zero:
+ /* powf(NaN,0.0) */
+ {
+ break;
+ }
+ case atan2l_zero:
+ case atan2dl_zero:
+ /* atan2l(0,0) */
+ /* atan2dl(0,0) */
+ {
+ break;
+ }
+ case atan2_zero:
+ case atan2d_zero:
+ /* atan2(0,0) */
+ /* atan2d(0,0) */
+ {
+ break;
+ }
+ case atan2f_zero:
+ case atan2df_zero:
+ /* atan2f(0,0) */
+ /* atan2df(0,0) */
+ {
+ break;
+ }
+ case expm1l_overflow:
+ /* expm1 overflow */
+ {
+ ERRNO_RANGE; break;
+ }
+ case expm1_overflow:
+ /* expm1 overflow */
+ {
+ ERRNO_RANGE; break;
+ }
+ case expm1f_overflow:
+ /* expm1f overflow */
+ {
+ ERRNO_RANGE; break;
+ }
+ case expm1l_underflow:
+ /* expm1 underflow */
+ {
+ ERRNO_RANGE; break;
+ }
+ case expm1_underflow:
+ /* expm1 underflow */
+ {
+ ERRNO_RANGE; break;
+ }
+ case expm1f_underflow:
+ /* expm1f underflow */
+ {
+ ERRNO_RANGE; break;
+ }
+ case hypotl_overflow:
+ /* hypotl overflow */
+ {
+ RETVAL_HUGE_VALL; ERRNO_RANGE; break;
+ }
+ case hypot_overflow:
+ /* hypot overflow */
+ {
+ RETVAL_HUGE_VALD; ERRNO_RANGE; break;
+ }
+ case hypotf_overflow:
+ /* hypotf overflow */
+ {
+ RETVAL_HUGE_VALF; ERRNO_RANGE; break;
+ }
+ case scalbl_underflow:
+ /* scalbl underflow */
+ {
+ if (INPUT_XL < ZEROL_VALUE /*0*/) RETVAL_NEG_ZEROL;
+ else RETVAL_ZEROL;
+ ERRNO_RANGE; break;
+ }
+ case scalb_underflow:
+ /* scalb underflow */
+ {
+ if (INPUT_XD < ZEROD_VALUE /*0*/) RETVAL_NEG_ZEROD;
+ else RETVAL_ZEROD;
+ ERRNO_RANGE; break;
+ }
+ case scalbf_underflow:
+ /* scalbf underflow */
+ {
+ if (INPUT_XF < ZEROF_VALUE /*0*/) RETVAL_NEG_ZEROF;
+ else RETVAL_ZEROF;
+ ERRNO_RANGE; break;
+ }
+ case scalbl_overflow:
+ /* scalbl overflow */
+ {
+ if (INPUT_XL < ZEROL_VALUE /*0*/) RETVAL_NEG_HUGE_VALL;
+ else RETVAL_HUGE_VALL;
+ ERRNO_RANGE; break;
+ }
+ case scalb_overflow:
+ /* scalb overflow */
+ {
+ if (INPUT_XD < ZEROD_VALUE /*0*/) RETVAL_NEG_HUGE_VALD;
+ else RETVAL_HUGE_VALD;
+ ERRNO_RANGE; break;
+ }
+ case scalbf_overflow:
+ /* scalbf overflow */
+ {
+ if (INPUT_XF < ZEROF_VALUE /*0*/) RETVAL_NEG_HUGE_VALF;
+ else RETVAL_HUGE_VALF;
+ ERRNO_RANGE; break;
+ }
+ case acoshl_lt_one:
+ /* acoshl(x < 1) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case acosh_lt_one:
+ /* acosh(x < 1) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case acoshf_lt_one:
+ /* acoshf(x < 1) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case acosl_gt_one:
+ case acosdl_gt_one:
+ /* acosl(x > 1) */
+ /* acosdl(x > 1) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case acos_gt_one:
+ case acosd_gt_one:
+ /* acos(x > 1) */
+ /* acosd(x > 1) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case acosf_gt_one:
+ case acosdf_gt_one:
+ /* acosf(x > 1) */
+ /* acosdf(x > 1) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case asinl_gt_one:
+ case asindl_gt_one:
+ /* asinl(x > 1) */
+ /* asindl(x > 1) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case asin_gt_one:
+ case asind_gt_one:
+ /* asin(x > 1) */
+ /* asind(x > 1) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case asinf_gt_one:
+ case asindf_gt_one:
+ /* asinf(x > 1) */
+ /* asindf(x > 1) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case remainderl_by_zero:
+ case fmodl_by_zero:
+ /* fmodl(x,0) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case remainder_by_zero:
+ case fmod_by_zero:
+ /* fmod(x,0) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case remainderf_by_zero:
+ case fmodf_by_zero:
+ /* fmodf(x,0) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case coshl_overflow:
+ /* coshl overflows */
+ {
+ RETVAL_HUGE_VALL; ERRNO_RANGE; break;
+ }
+ case cosh_overflow:
+ /* cosh overflows */
+ {
+ RETVAL_HUGE_VALD; ERRNO_RANGE; break;
+ }
+ case coshf_overflow:
+ /* coshf overflows */
+ {
+ RETVAL_HUGE_VALF; ERRNO_RANGE; break;
+ }
+ case sinhl_overflow:
+ /* sinhl overflows */
+ {
+ if (INPUT_XL > ZEROL_VALUE /*0*/) RETVAL_HUGE_VALL;
+ else RETVAL_NEG_HUGE_VALL;
+ ERRNO_RANGE; break;
+ }
+ case sinh_overflow:
+ /* sinh overflows */
+ {
+ if (INPUT_XD > ZEROD_VALUE /*0*/) RETVAL_HUGE_VALD;
+ else RETVAL_NEG_HUGE_VALD;
+ ERRNO_RANGE; break;
+ }
+ case sinhf_overflow:
+ /* sinhf overflows */
+ {
+ if (INPUT_XF > ZEROF_VALUE /*0*/) RETVAL_HUGE_VALF;
+ else RETVAL_NEG_HUGE_VALF;
+ ERRNO_RANGE; break;
+ }
+ case logbl_zero:
+ /* logbl(0) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case logb_zero:
+ /* logb(0) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case logbf_zero:
+ /* logbf(0) */
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case ilogbl_zero:
+ /* ilogbl(0) */
+ {
+ ERRNO_RANGE; break;
+ }
+ case ilogb_zero:
+ /* ilogb(0) */
+ {
+ ERRNO_RANGE; break;
+ }
+ case ilogbf_zero:
+ /* ilogbf(0) */
+ {
+ ERRNO_RANGE; break;
+ }
+ default:
+ break;
+}
+return;
+/* _POSIX_ */
+}
+
+/*******************************/
+/* __SVID__ and __XOPEN__ Path */
+/*******************************/
+else
+{
+ switch(input_tag)
+ {
+ case ldexpl_overflow:
+ case ldexpl_underflow:
+ case ldexp_overflow:
+ case ldexp_underflow:
+ case ldexpf_overflow:
+ case ldexpf_underflow:
+ case scalbnl_overflow:
+ case scalbnl_underflow:
+ case scalbn_overflow:
+ case scalbn_underflow:
+ case scalbnf_overflow:
+ case scalbnf_underflow:
+ case scalblnl_overflow:
+ case scalblnl_underflow:
+ case scalbln_overflow:
+ case scalbln_underflow:
+ case scalblnf_overflow:
+ case scalblnf_underflow:
+ case tandl_overflow:
+ case tand_overflow:
+ case tandf_overflow:
+ case cotdl_overflow:
+ case cotd_overflow:
+ case cotdf_overflow:
+ case cotl_overflow:
+ case cot_overflow:
+ case cotf_overflow:
+ case annuityl_overflow:
+ case annuityl_underflow:
+ case annuity_overflow:
+ case annuity_underflow:
+ case annuityf_overflow:
+ case annuityf_underflow:
+ case compoundl_overflow:
+ case compoundl_underflow:
+ case compound_overflow:
+ case compound_underflow:
+ case compoundf_overflow:
+ case compoundf_underflow:
+ {
+ ERRNO_RANGE; break;
+ }
+ case annuityl_by_zero:
+ case annuityl_less_m1:
+ case annuity_by_zero:
+ case annuity_less_m1:
+ case annuityf_by_zero:
+ case annuityf_less_m1:
+ case compoundl_by_zero:
+ case compoundl_less_m1:
+ case compound_by_zero:
+ case compound_less_m1:
+ case compoundf_by_zero:
+ case compoundf_less_m1:
+ {
+ ERRNO_DOMAIN; break;
+ }
+ case sqrtl_negative:
+ /* sqrtl(x < 0) */
+ {
+ DOMAINL; NAMEL = (char *) "sqrtl";
+ ifSVID
+ {
+ RETVAL_ZEROL;
+ NOT_MATHERRL
+ {
+ WRITEL_SQRT;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ { /* NaN already computed */
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case sqrt_negative:
+ /* sqrt(x < 0) */
+ {
+ DOMAIND; NAMED = (char *) "sqrt";
+ ifSVID
+ {
+
+ RETVAL_ZEROD;
+ NOT_MATHERRD
+ {
+ WRITED_SQRT;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ { /* NaN already computed */
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case sqrtf_negative:
+ /* sqrtf(x < 0) */
+ {
+ DOMAINF; NAMEF = (char *) "sqrtf";
+ ifSVID
+ {
+ RETVAL_ZEROF;
+ NOT_MATHERRF
+ {
+ WRITEF_SQRT;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case logl_zero:
+ /* logl(0) */
+ {
+ SINGL; NAMEL = (char *) "logl";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_LOG_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case log_zero:
+ /* log(0) */
+ {
+ SINGD; NAMED = (char *) "log";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_LOG_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case logf_zero:
+ /* logf(0) */
+ {
+ SINGF; NAMEF = (char *) "logf";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_LOG_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+
+ case logl_negative:
+ /* logl(x < 0) */
+ {
+ DOMAINL; NAMEL = (char *) "logl";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_LOG_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case log_negative:
+ /* log(x < 0) */
+ {
+ DOMAIND; NAMED = (char *) "log";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_LOG_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case logf_negative:
+ /* logf(x < 0) */
+ {
+ DOMAINF; NAMEF = (char *) "logf";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_LOG_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF{ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case log1pl_zero:
+ /* log1pl(-1) */
+ {
+ SINGL; NAMEL = (char *) "log1pl";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_LOG1P_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case log1p_zero:
+ /* log1p(-1) */
+ {
+ SINGD; NAMED = (char *) "log1p";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_LOG1P_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case log1pf_zero:
+ /* log1pf(-1) */
+ {
+ SINGF; NAMEF = (char *) "log1pf";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_LOG1P_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case log1pl_negative:
+ /* log1pl(x < -1) */
+ {
+ DOMAINL; NAMEL = (char *) "log1pl";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_LOG1P_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case log1p_negative:
+ /* log1p(x < -1) */
+ {
+ DOMAIND; NAMED = (char *) "log1p";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_LOG1P_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case log1pf_negative:
+ /* log1pf(x < -1) */
+ {
+ DOMAINF; NAMEF = (char *) "log1pf";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_LOG1P_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case log10l_zero:
+ /* log10l(0) */
+ {
+ SINGL; NAMEL = (char *) "log10l";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_LOG10_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case log10_zero:
+ /* log10(0) */
+ {
+ SINGD; NAMED = (char *) "log10";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_LOG10_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case log10f_zero:
+ /* log10f(0) */
+ {
+ SINGF; NAMEF = (char *) "log10f";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_LOG10_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case log10l_negative:
+ /* log10l(x < 0) */
+ {
+ DOMAINL; NAMEL = (char *) "log10l";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_LOG10_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case log10_negative:
+ /* log10(x < 0) */
+ {
+ DOMAIND; NAMED = (char *) "log10";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_LOG10_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case log10f_negative:
+ /* log10f(x < 0) */
+ {
+ DOMAINF; NAMEF = (char *) "log10f";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_LOG10_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case log2l_zero:
+ /* log2l(0) */
+ {
+ SINGL; NAMEL = (char *) "log2l";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_LOG2_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case log2_zero:
+ /* log2(0) */
+ {
+ SINGD; NAMED = (char *) "log2";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_LOG2_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case log2f_zero:
+ /* log2f(0) */
+ {
+ SINGF; NAMEF = (char *) "log2f";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_LOG2_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case log2l_negative:
+ /* log2l(x < 0) */
+ {
+ DOMAINL; NAMEL = (char *) "log2l";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_LOG2_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case log2_negative:
+ /* log2(x < 0) */
+ {
+ DOMAIND; NAMED = (char *) "log2";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_LOG2_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case log2f_negative:
+ /* log2f(x < 0) */
+ {
+ DOMAINF; NAMEF = (char *) "log2f";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_LOG2_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case expl_overflow:
+ /* expl overflow */
+ {
+ OVERFLOWL; NAMEL = (char *) "expl";
+ ifSVID
+ {
+ RETVAL_HUGEL;
+ }
+ else
+ {
+ RETVAL_HUGE_VALL;
+ }
+ NOT_MATHERRL {ERRNO_RANGE;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case exp_overflow:
+ /* exp overflow */
+ {
+ OVERFLOWD; NAMED = (char *) "exp";
+ ifSVID
+ {
+ RETVAL_HUGED;
+ }
+ else
+ {
+ RETVAL_HUGE_VALD;
+ }
+ NOT_MATHERRD {ERRNO_RANGE;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case expf_overflow:
+ /* expf overflow */
+ {
+ OVERFLOWF; NAMEF = (char *) "expf";
+ ifSVID
+ {
+ RETVAL_HUGEF;
+ }
+ else
+ {
+ RETVAL_HUGE_VALF;
+ }
+ NOT_MATHERRF {ERRNO_RANGE;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case expl_underflow:
+ /* expl underflow */
+ {
+ UNDERFLOWL; NAMEL = (char *) "expl"; RETVAL_ZEROL;
+ NOT_MATHERRL {ERRNO_RANGE;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case exp_underflow:
+ /* exp underflow */
+ {
+ UNDERFLOWD; NAMED = (char *) "exp"; RETVAL_ZEROD;
+ NOT_MATHERRD {ERRNO_RANGE;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case expf_underflow:
+ /* expf underflow */
+ {
+ UNDERFLOWF; NAMEF = (char *) "expf"; RETVAL_ZEROF;
+ NOT_MATHERRF {ERRNO_RANGE;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case powl_zero_to_zero:
+ /* powl 0**0 */
+ {
+ DOMAINL; NAMEL = (char *) "powl";
+ ifSVID
+ {
+ RETVAL_ZEROL;
+ NOT_MATHERRL
+ {
+ WRITEL_POW_ZERO_TO_ZERO;
+ ERRNO_DOMAIN;
+ }
+ *(long double *)retval = excl.retval;
+ }
+ else RETVAL_ONEL;
+ break;
+ }
+ case pow_zero_to_zero:
+ /* pow 0**0 */
+ {
+ DOMAIND; NAMED = (char *) "pow";
+ ifSVID
+ {
+ RETVAL_ZEROD;
+ NOT_MATHERRD
+ {
+ WRITED_POW_ZERO_TO_ZERO;
+ ERRNO_DOMAIN;
+ }
+ *(double *)retval = exc.retval;
+ }
+ else RETVAL_ONED;
+ break;
+ }
+ case powf_zero_to_zero:
+ /* powf 0**0 */
+ {
+ DOMAINF; NAMEF = (char *) "powf";
+ ifSVID
+ {
+ RETVAL_ZEROF;
+ NOT_MATHERRF
+ {
+ WRITEF_POW_ZERO_TO_ZERO;
+ ERRNO_DOMAIN;
+ }
+ *(float *)retval = excf.retval;
+ }
+ else RETVAL_ONEF;
+ break;
+ }
+ case powl_overflow:
+ /* powl(x,y) overflow */
+ {
+ OVERFLOWL; NAMEL = (char *) "powl";
+ ifSVID
+ {
+ if (INPUT_RESL < ZEROL_VALUE /*0*/) RETVAL_NEG_HUGEL;
+ else RETVAL_HUGEL;
+ }
+ else
+ {
+ if (INPUT_RESL < ZEROL_VALUE /*0*/) RETVAL_NEG_HUGE_VALL;
+ else RETVAL_HUGE_VALL;
+ }
+ NOT_MATHERRL {ERRNO_RANGE;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case pow_overflow:
+ /* pow(x,y) overflow */
+ {
+ OVERFLOWD; NAMED = (char *) "pow";
+ ifSVID
+ {
+ if (INPUT_RESD < ZEROD_VALUE /*0*/) RETVAL_NEG_HUGED;
+ else RETVAL_HUGED;
+ }
+ else
+ {
+ if (INPUT_RESD < ZEROD_VALUE /*0*/) RETVAL_NEG_HUGE_VALD;
+ else RETVAL_HUGE_VALD;
+ }
+ NOT_MATHERRD {ERRNO_RANGE;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case powf_overflow:
+ /* powf(x,y) overflow */
+ {
+ OVERFLOWF; NAMEF = (char *) "powf";
+ ifSVID
+ {
+ if (INPUT_RESF < ZEROF_VALUE /*0*/) RETVAL_NEG_HUGEF;
+ else RETVAL_HUGEF;
+ }
+ else
+ {
+ if (INPUT_RESF < ZEROF_VALUE /*0*/) RETVAL_NEG_HUGE_VALF;
+ else RETVAL_HUGE_VALF;
+ }
+ NOT_MATHERRF {ERRNO_RANGE;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case powl_underflow:
+ /* powl(x,y) underflow */
+ {
+ UNDERFLOWL; NAMEL = (char *) "powl"; RETVAL_ZEROL;
+ NOT_MATHERRL {ERRNO_RANGE;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case pow_underflow:
+ /* pow(x,y) underflow */
+ {
+ UNDERFLOWD; NAMED = (char *) "pow"; RETVAL_ZEROD;
+ NOT_MATHERRD {ERRNO_RANGE;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case powf_underflow:
+ /* powf(x,y) underflow */
+ {
+ UNDERFLOWF; NAMEF = (char *) "powf"; RETVAL_ZEROF;
+ NOT_MATHERRF {ERRNO_RANGE;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case powl_zero_to_negative:
+ /* 0 to neg */
+ {
+ DOMAINL; NAMEL = (char *) "powl";
+ ifSVID
+ {
+ RETVAL_ZEROL;
+ NOT_MATHERRL
+ {
+ WRITEL_POW_ZERO_TO_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case pow_zero_to_negative:
+ /* 0**neg */
+ {
+ DOMAIND; NAMED = (char *) "pow";
+ ifSVID
+ {
+ RETVAL_ZEROD;
+ NOT_MATHERRD
+ {
+ WRITED_POW_ZERO_TO_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case powf_zero_to_negative:
+ /* 0**neg */
+ {
+ DOMAINF; NAMEF = (char *) "powf";
+ ifSVID
+ {
+ RETVAL_ZEROF;
+ NOT_MATHERRF
+ {
+ WRITEF_POW_ZERO_TO_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case powl_neg_to_non_integer:
+ /* neg**non_integral */
+ {
+ DOMAINL; NAMEL = (char *) "powl";
+ ifSVID
+ {
+ RETVAL_ZEROL;
+ NOT_MATHERRL
+ {
+ WRITEL_POW_NEG_TO_NON_INTEGER;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case pow_neg_to_non_integer:
+ /* neg**non_integral */
+ {
+ DOMAIND; NAMED = (char *) "pow";
+ ifSVID
+ {
+ RETVAL_ZEROD;
+ NOT_MATHERRD
+ {
+ WRITED_POW_NEG_TO_NON_INTEGER;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case powf_neg_to_non_integer:
+ /* neg**non-integral */
+ {
+ DOMAINF; NAMEF = (char *) "powf";
+ ifSVID
+ {
+ RETVAL_ZEROF;
+ NOT_MATHERRF
+ {
+ WRITEF_POW_NEG_TO_NON_INTEGER;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case powl_nan_to_zero:
+ /* pow(NaN,0.0) */
+ /* Special Error */
+ {
+ DOMAINL; NAMEL = (char *) "powl";
+ *(long double *)retval = *(long double *)arg1;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case pow_nan_to_zero:
+ /* pow(NaN,0.0) */
+ /* Special Error */
+ {
+ DOMAIND; NAMED = (char *) "pow";
+ *(double *)retval = *(double *)arg1;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case powf_nan_to_zero:
+ /* powf(NaN,0.0) */
+ /* Special Error */
+ {
+ DOMAINF; NAMEF = (char *) "powf";
+ *(float *)retval = *(float *)arg1;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case atan2l_zero:
+ /* atan2l(0.0,0.0) */
+ {
+ DOMAINL; NAMEL = (char *) "atan2l";
+ RETVAL_ZEROL;
+ NOT_MATHERRL
+ {
+ ifSVID
+ {
+ WRITEL_ATAN2_ZERO_BY_ZERO;
+ }
+ ERRNO_DOMAIN;
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case atan2_zero:
+ /* atan2(0.0,0.0) */
+ {
+ DOMAIND; NAMED = (char *) "atan2";
+ RETVAL_ZEROD;
+ NOT_MATHERRD
+ {
+ ifSVID
+ {
+ WRITED_ATAN2_ZERO_BY_ZERO;
+ }
+ ERRNO_DOMAIN;
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case atan2f_zero:
+ /* atan2f(0.0,0.0) */
+ {
+ DOMAINF; NAMEF = (char *) "atan2f";
+ RETVAL_ZEROF;
+ NOT_MATHERRF
+ {
+ ifSVID
+ {
+ WRITEF_ATAN2_ZERO_BY_ZERO;
+ }
+ ERRNO_DOMAIN;
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case atan2dl_zero:
+ /* atan2dl(0.0,0.0) */
+ {
+ DOMAINL; NAMEL = (char *) "atan2dl";
+ RETVAL_ZEROL;
+ NOT_MATHERRL
+ {
+ ifSVID
+ {
+ WRITEL_ATAN2D_ZERO_BY_ZERO;
+ }
+ ERRNO_DOMAIN;
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case atan2d_zero:
+ /* atan2d(0.0,0.0) */
+ {
+ DOMAIND; NAMED = (char *) "atan2d";
+ RETVAL_ZEROD;
+ NOT_MATHERRD
+ {
+ ifSVID
+ {
+ WRITED_ATAN2D_ZERO_BY_ZERO;
+ }
+ ERRNO_DOMAIN;
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case atan2df_zero:
+ /* atan2df(0.0,0.0) */
+ {
+ DOMAINF; NAMEF = (char *) "atan2df";
+ RETVAL_ZEROF;
+ NOT_MATHERRF
+ {
+ ifSVID
+ {
+ WRITEF_ATAN2D_ZERO_BY_ZERO;
+ }
+ ERRNO_DOMAIN;
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case expm1_overflow:
+ /* expm1(finite) overflow */
+ /* Overflow is the only documented */
+ /* special value. */
+ {
+ ERRNO_RANGE;
+ break;
+ }
+ case expm1f_overflow:
+ /* expm1f(finite) overflow */
+ {
+ ERRNO_RANGE;
+ break;
+ }
+ case expm1_underflow:
+ /* expm1(finite) underflow */
+ /* Underflow is not documented */
+ /* special value. */
+ {
+ ERRNO_RANGE;
+ break;
+ }
+ case expm1f_underflow:
+ /* expm1f(finite) underflow */
+ {
+ ERRNO_RANGE;
+ break;
+ }
+ case scalbl_underflow:
+ /* scalbl underflow */
+ {
+ UNDERFLOWL; NAMEL = (char *) "scalbl";
+ if (INPUT_XL < ZEROL_VALUE /*0.0L*/) RETVAL_NEG_ZEROL;
+ else RETVAL_ZEROL;
+ NOT_MATHERRL {ERRNO_RANGE;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case scalb_underflow:
+ /* scalb underflow */
+ {
+ UNDERFLOWD; NAMED = (char *) "scalb";
+ if (INPUT_XD < ZEROD_VALUE /*0.0*/) RETVAL_NEG_ZEROD;
+ else RETVAL_ZEROD;
+ NOT_MATHERRD {ERRNO_RANGE;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case scalbf_underflow:
+ /* scalbf underflow */
+ {
+ UNDERFLOWF; NAMEF = (char *) "scalbf";
+ if (INPUT_XF < ZEROF_VALUE /*0.0*/) RETVAL_NEG_ZEROF;
+ else RETVAL_ZEROF;
+ NOT_MATHERRF {ERRNO_RANGE;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case scalbl_overflow:
+ /* scalbl overflow */
+ {
+ OVERFLOWL; NAMEL = (char *) "scalbl";
+ if (INPUT_XL < ZEROL_VALUE /*0*/) RETVAL_NEG_HUGE_VALL;
+ else RETVAL_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_RANGE;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case scalb_overflow:
+ /* scalb overflow */
+ {
+ OVERFLOWD; NAMED = (char *) "scalb";
+ if (INPUT_XD < ZEROD_VALUE /*0*/) RETVAL_NEG_HUGE_VALD;
+ else RETVAL_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_RANGE;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case scalbf_overflow:
+ /* scalbf overflow */
+ {
+ OVERFLOWF; NAMEF = (char *) "scalbf";
+ if (INPUT_XF < ZEROF_VALUE /*0*/) RETVAL_NEG_HUGE_VALF;
+ else RETVAL_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_RANGE;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case hypotl_overflow:
+ /* hypotl overflow */
+ {
+ OVERFLOWL; NAMEL = (char *) "hypotl";
+ ifSVID
+ {
+ RETVAL_HUGEL;
+ }
+ else
+ {
+ RETVAL_HUGE_VALL;
+ }
+ NOT_MATHERRL {ERRNO_RANGE;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case hypot_overflow:
+ /* hypot overflow */
+ {
+ OVERFLOWD; NAMED = (char *) "hypot";
+ ifSVID
+ {
+ RETVAL_HUGED;
+ }
+ else
+ {
+ RETVAL_HUGE_VALD;
+ }
+ NOT_MATHERRD {ERRNO_RANGE;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case hypotf_overflow:
+ /* hypotf overflow */
+ {
+ OVERFLOWF; NAMEF = (char *) "hypotf";
+ ifSVID
+ {
+ RETVAL_HUGEF;
+ }
+ else
+ {
+ RETVAL_HUGE_VALF;
+ }
+ NOT_MATHERRF {ERRNO_RANGE;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case acosl_gt_one:
+ /* acosl(x > 1) */
+ {
+ DOMAINL; NAMEL = (char *) "acosl";
+ RETVAL_ZEROL;
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_ACOS;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case acos_gt_one:
+ /* acos(x > 1) */
+ {
+ DOMAIND; NAMED = (char *) "acos";
+ RETVAL_ZEROD;
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_ACOS;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case acosf_gt_one:
+ /* acosf(x > 1) */
+ {
+ DOMAINF; NAMEF = (char *) "acosf";
+ RETVAL_ZEROF;
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_ACOS;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case asinl_gt_one:
+ /* asinl(x > 1) */
+ {
+ DOMAINL; NAMEL = (char *) "asinl";
+ RETVAL_ZEROL;
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_ASIN;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case asin_gt_one:
+ /* asin(x > 1) */
+ {
+ DOMAIND; NAMED = (char *) "asin";
+ RETVAL_ZEROD;
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_ASIN;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case asinf_gt_one:
+ /* asinf(x > 1) */
+ {
+ DOMAINF; NAMEF = (char *) "asinf";
+ RETVAL_ZEROF;
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_ASIN;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case acosdl_gt_one:
+ /* acosdl(x > 1) */
+ {
+ DOMAINL; NAMEL = (char *) "acosdl";
+ RETVAL_ZEROL;
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_ACOSD;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case acosd_gt_one:
+ /* acosd(x > 1) */
+ {
+ DOMAIND; NAMED = (char *) "acosd";
+ RETVAL_ZEROD;
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_ACOSD;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case acosdf_gt_one:
+ /* acosdf(x > 1) */
+ {
+ DOMAINF; NAMEF = (char *) "acosdf";
+ RETVAL_ZEROF;
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_ACOSD;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case asindl_gt_one:
+ /* asindl(x > 1) */
+ {
+ DOMAINL; NAMEL = (char *) "asindl";
+ RETVAL_ZEROL;
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_ASIND;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case asind_gt_one:
+ /* asind(x > 1) */
+ {
+ DOMAIND; NAMED = (char *) "asind";
+ RETVAL_ZEROD;
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_ASIND;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case asindf_gt_one:
+ /* asindf(x > 1) */
+ {
+ DOMAINF; NAMEF = (char *) "asindf";
+ RETVAL_ZEROF;
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_ASIND;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case coshl_overflow:
+ /* coshl overflow */
+ {
+ OVERFLOWL; NAMEL = (char *) "coshl";
+ ifSVID
+ {
+ RETVAL_HUGEL;
+ }
+ else
+ {
+ RETVAL_HUGE_VALL;
+ }
+ NOT_MATHERRL {ERRNO_RANGE;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case cosh_overflow:
+ /* cosh overflow */
+ {
+ OVERFLOWD; NAMED = (char *) "cosh";
+ ifSVID
+ {
+ RETVAL_HUGED;
+ }
+ else
+ {
+ RETVAL_HUGE_VALD;
+ }
+ NOT_MATHERRD {ERRNO_RANGE;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case coshf_overflow:
+ /* coshf overflow */
+ {
+ OVERFLOWF; NAMEF = (char *) "coshf";
+ ifSVID
+ {
+ RETVAL_HUGEF;
+ }
+ else
+ {
+ RETVAL_HUGE_VALF;
+ }
+ NOT_MATHERRF {ERRNO_RANGE;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case sinhl_overflow:
+ /* sinhl overflow */
+ {
+ OVERFLOWL; NAMEL = (char *) "sinhl";
+ ifSVID
+ {
+ if (INPUT_XL > ZEROL_VALUE /*0.0*/) RETVAL_HUGEL;
+ else RETVAL_NEG_HUGEL;
+ }
+ else
+ {
+ if (INPUT_XL > ZEROL_VALUE /*0.0*/) RETVAL_HUGE_VALL;
+ else RETVAL_NEG_HUGE_VALL;
+ }
+ NOT_MATHERRL {ERRNO_RANGE;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case sinh_overflow:
+ /* sinh overflow */
+ {
+ OVERFLOWD; NAMED = (char *) "sinh";
+ ifSVID
+ {
+ if (INPUT_XD > ZEROD_VALUE /*0.0*/) RETVAL_HUGED;
+ else RETVAL_NEG_HUGED;
+ }
+ else
+ {
+ if (INPUT_XD > ZEROD_VALUE /*0.0*/) RETVAL_HUGE_VALD;
+ else RETVAL_NEG_HUGE_VALD;
+ }
+ NOT_MATHERRD {ERRNO_RANGE;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case sinhf_overflow:
+ /* sinhf overflow */
+ {
+ OVERFLOWF; NAMEF = (char *) "sinhf";
+ ifSVID
+ {
+ if (INPUT_XF > ZEROF_VALUE /*0.0*/) RETVAL_HUGEF;
+ else RETVAL_NEG_HUGEF;
+ }
+ else
+ {
+ if (INPUT_XF > ZEROF_VALUE /*0.0*/) RETVAL_HUGE_VALF;
+ else RETVAL_NEG_HUGE_VALF;
+ }
+ NOT_MATHERRF {ERRNO_RANGE;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case acoshl_lt_one:
+ /* acoshl(x < 1) */
+ {
+ DOMAINL; NAMEL = (char *) "acoshl";
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_ACOSH;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case acosh_lt_one:
+ /* acosh(x < 1) */
+ {
+ DOMAIND; NAMED = (char *) "acosh";
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_ACOSH;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case acoshf_lt_one:
+ /* acoshf(x < 1) */
+ {
+ DOMAINF; NAMEF = (char *) "acoshf";
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_ACOSH;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case atanhl_gt_one:
+ /* atanhl(|x| > 1) */
+ {
+ DOMAINL; NAMEL = (char *) "atanhl";
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_ATANH_GT_ONE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ break;
+ }
+ case atanh_gt_one:
+ /* atanh(|x| > 1) */
+ {
+ DOMAIND; NAMED = (char *) "atanh";
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_ATANH_GT_ONE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ break;
+ }
+ case atanhf_gt_one:
+ /* atanhf(|x| > 1) */
+ {
+ DOMAINF; NAMEF = (char *) "atanhf";
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_ATANH_GT_ONE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ break;
+ }
+ case atanhl_eq_one:
+ /* atanhl(|x| == 1) */
+ {
+ SINGL; NAMEL = (char *) "atanhl";
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_ATANH_EQ_ONE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ break;
+ }
+ case atanh_eq_one:
+ /* atanh(|x| == 1) */
+ {
+ SINGD; NAMED = (char *) "atanh";
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_ATANH_EQ_ONE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ break;
+ }
+ case atanhf_eq_one:
+ /* atanhf(|x| == 1) */
+ {
+ SINGF; NAMEF = (char *) "atanhf";
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_ATANH_EQ_ONE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ break;
+ }
+ case gammal_overflow:
+ /* gammal overflow */
+ {
+ OVERFLOWL; NAMEL = (char *) "gammal";
+ ifSVID
+ {
+ RETVAL_HUGEL;
+ }
+ else
+ {
+ RETVAL_HUGE_VALL;
+ }
+ NOT_MATHERRL {ERRNO_RANGE;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case gamma_overflow:
+ /* gamma overflow */
+ {
+ OVERFLOWD; NAMED = (char *) "gamma";
+ ifSVID
+ {
+ RETVAL_HUGED;
+ }
+ else
+ {
+ RETVAL_HUGE_VALD;
+ }
+ NOT_MATHERRD {ERRNO_RANGE;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case gammaf_overflow:
+ /* gammaf overflow */
+ {
+ OVERFLOWF; NAMEF = (char *) "gammaf";
+ ifSVID
+ {
+ RETVAL_HUGEF;
+ }
+ else
+ {
+ RETVAL_HUGE_VALF;
+ }
+ NOT_MATHERRF {ERRNO_RANGE;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case gammal_negative:
+ /* gammal -int or 0 */
+ {
+ SINGL; NAMEL = (char *) "gammal";
+ ifSVID
+ {
+ RETVAL_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_GAMMA_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case gamma_negative:
+ /* gamma -int or 0 */
+ {
+ SINGD; NAMED = (char *) "gamma";
+ ifSVID
+ {
+ RETVAL_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_GAMMA_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case gammaf_negative:
+ /* gammaf -int or 0 */
+ {
+ SINGF; NAMEF = (char *) "gammaf";
+ ifSVID
+ {
+ RETVAL_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_GAMMA_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case lgammal_overflow:
+ /* lgammal overflow */
+ {
+ OVERFLOWL; NAMEL = (char *) "lgammal";
+ ifSVID
+ {
+ RETVAL_HUGEL;
+ }
+ else
+ {
+ RETVAL_HUGE_VALL;
+ }
+ NOT_MATHERRL {ERRNO_RANGE;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case lgamma_overflow:
+ /* lgamma overflow */
+ {
+ OVERFLOWD; NAMED = (char *) "lgamma";
+ ifSVID
+ {
+ RETVAL_HUGED;
+ }
+ else
+ {
+ RETVAL_HUGE_VALD;
+ }
+ NOT_MATHERRD {ERRNO_RANGE;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case lgammaf_overflow:
+ /* lgammaf overflow */
+ {
+ OVERFLOWF; NAMEF = (char *) "lgammaf";
+ ifSVID
+ {
+ RETVAL_HUGEF;
+ }
+ else
+ {
+ RETVAL_HUGE_VALF;
+ }
+ NOT_MATHERRF {ERRNO_RANGE;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case lgammal_negative:
+ /* lgammal -int or 0 */
+ {
+ SINGL; NAMEL = (char *) "lgammal";
+ ifSVID
+ {
+ RETVAL_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_LGAMMA_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case lgamma_negative:
+ /* lgamma -int or 0 */
+ {
+ SINGD; NAMED = (char *) "lgamma";
+ ifSVID
+ {
+ RETVAL_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_LGAMMA_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case lgammaf_negative:
+ /* lgammaf -int or 0 */
+ {
+ SINGF; NAMEF = (char *) "lgammaf";
+ ifSVID
+ {
+ RETVAL_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_LGAMMA_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case tgammal_overflow:
+ /* tgammal overflow */
+ {
+ OVERFLOWL; NAMEL = (char *) "tgammal";
+ ifSVID
+ {
+ RETVAL_HUGEL;
+ }
+ else
+ {
+ RETVAL_HUGE_VALL;
+ }
+ NOT_MATHERRL {ERRNO_RANGE;}
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case tgamma_overflow:
+ /* tgamma overflow */
+ {
+ OVERFLOWD; NAMED = (char *) "tgamma";
+ ifSVID
+ {
+ RETVAL_HUGED;
+ }
+ else
+ {
+ RETVAL_HUGE_VALD;
+ }
+ NOT_MATHERRD {ERRNO_RANGE;}
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case tgammaf_overflow:
+ /* tgammaf overflow */
+ {
+ OVERFLOWF; NAMEF = (char *) "tgammaf";
+ ifSVID
+ {
+ RETVAL_HUGEF;
+ }
+ else
+ {
+ RETVAL_HUGE_VALF;
+ }
+ NOT_MATHERRF {ERRNO_RANGE;}
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case tgammal_negative:
+ /* tgammal -int or 0 */
+ {
+ SINGL; NAMEL = (char *) "tgammal";
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_TGAMMA_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case tgamma_negative:
+ /* tgamma -int or 0 */
+ {
+ SINGD; NAMED = (char *) "tgamma";
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_TGAMMA_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case tgammaf_negative:
+ /* tgammaf -int or 0 */
+ {
+ SINGF; NAMEF = (char *) "tgammaf";
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_TGAMMA_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case j0l_gt_loss:
+ /* j0l > loss */
+ {
+ TLOSSL; NAMEL = (char *) "j0l";
+ RETVAL_ZEROL;
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_J0_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_RANGE;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case j0_gt_loss:
+ /* j0 > loss */
+ {
+ TLOSSD; NAMED = (char *) "j0";
+ RETVAL_ZEROD;
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_J0_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_RANGE;}
+ }
+ *(double*)retval = exc.retval;
+ break;
+ }
+ case j0f_gt_loss:
+ /* j0f > loss */
+ {
+ TLOSSF; NAMEF = (char *) "j0f";
+ RETVAL_ZEROF;
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_J0_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_RANGE;}
+ }
+ *(float*)retval = excf.retval;
+ break;
+ }
+ case j1l_gt_loss:
+ /* j1l > loss */
+ {
+ TLOSSL; NAMEL = (char *) "j1l";
+ RETVAL_ZEROL;
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_J1_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_RANGE;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case j1_gt_loss:
+ /* j1 > loss */
+ {
+ TLOSSD; NAMED = (char *) "j1";
+ RETVAL_ZEROD;
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_J1_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_RANGE;}
+ }
+ *(double*)retval = exc.retval;
+ break;
+ }
+ case j1f_gt_loss:
+ /* j1f > loss */
+ {
+ TLOSSF; NAMEF = (char *) "j1f";
+ RETVAL_ZEROF;
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_J1_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_RANGE;}
+ }
+ *(float*)retval = excf.retval;
+ break;
+ }
+ case jnl_gt_loss:
+ /* jnl > loss */
+ {
+ TLOSSL; NAMEL = (char *) "jnl";
+ RETVAL_ZEROL;
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_JN_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_RANGE;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case jn_gt_loss:
+ /* jn > loss */
+ {
+ TLOSSD; NAMED = (char *) "jn";
+ RETVAL_ZEROD;
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_JN_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_RANGE;}
+ }
+ *(double*)retval = exc.retval;
+ break;
+ }
+ case jnf_gt_loss:
+ /* jnf > loss */
+ {
+ TLOSSF; NAMEF = (char *) "jnf";
+ RETVAL_ZEROF;
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_JN_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_RANGE;}
+ }
+ *(float*)retval = excf.retval;
+ break;
+ }
+ case y0l_gt_loss:
+ /* y0l > loss */
+ {
+ TLOSSL; NAMEL = (char *) "y0l";
+ RETVAL_ZEROL;
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_Y0_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_RANGE;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case y0_gt_loss:
+ /* y0 > loss */
+ {
+ TLOSSD; NAMED = (char *) "y0";
+ RETVAL_ZEROD;
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_Y0_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_RANGE;}
+ }
+ *(double*)retval = exc.retval;
+ break;
+ }
+ case y0f_gt_loss:
+ /* y0f > loss */
+ {
+ TLOSSF; NAMEF = (char *) "y0f";
+ RETVAL_ZEROF;
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_Y0_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_RANGE;}
+ }
+ *(float*)retval = excf.retval;
+ break;
+ }
+ case y0l_zero:
+ /* y0l(0) */
+ {
+ DOMAINL; NAMEL = (char *) "y0l";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_Y0_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case y0_zero:
+ /* y0(0) */
+ {
+ DOMAIND; NAMED = (char *) "y0";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_Y0_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case y0f_zero:
+ /* y0f(0) */
+ {
+ DOMAINF; NAMEF = (char *) "y0f";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_Y0_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case y1l_gt_loss:
+ /* y1l > loss */
+ {
+ TLOSSL; NAMEL = (char *) "y1l";
+ RETVAL_ZEROL;
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_Y1_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_RANGE;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case y1_gt_loss:
+ /* y1 > loss */
+ {
+ TLOSSD; NAMED = (char *) "y1";
+ RETVAL_ZEROD;
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_Y1_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_RANGE;}
+ }
+ *(double*)retval = exc.retval;
+ break;
+ }
+ case y1f_gt_loss:
+ /* y1f > loss */
+ {
+ TLOSSF; NAMEF = (char *) "y1f";
+ RETVAL_ZEROF;
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_Y1_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_RANGE;}
+ }
+ *(float*)retval = excf.retval;
+ break;
+ }
+ case y1l_zero:
+ /* y1l(0) */
+ {
+ DOMAINL; NAMEL = (char *) "y1l";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_Y1_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case y1_zero:
+ /* y1(0) */
+ {
+ DOMAIND; NAMED = (char *) "y1";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_Y1_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case y1f_zero:
+ /* y1f(0) */
+ {
+ DOMAINF; NAMEF = (char *) "y1f";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_Y1_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case ynl_gt_loss:
+ /* ynl > loss */
+ {
+ TLOSSL; NAMEL = (char *) "ynl";
+ RETVAL_ZEROL;
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_YN_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRL {ERRNO_RANGE;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case yn_gt_loss:
+ /* yn > loss */
+ {
+ TLOSSD; NAMED = (char *) "yn";
+ RETVAL_ZEROD;
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_YN_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRD {ERRNO_RANGE;}
+ }
+ *(double*)retval = exc.retval;
+ break;
+ }
+ case ynf_gt_loss:
+ /* ynf > loss */
+ {
+ TLOSSF; NAMEF = (char *) "ynf";
+ RETVAL_ZEROF;
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_YN_TLOSS;
+ ERRNO_RANGE;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_RANGE;}
+ }
+ *(float*)retval = excf.retval;
+ break;
+ }
+ case ynl_zero:
+ /* ynl(0) */
+ {
+ DOMAINL; NAMEL = (char *) "ynl";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_YN_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case yn_zero:
+ /* yn(0) */
+ {
+ DOMAIND; NAMED = (char *) "yn";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_YN_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case ynf_zero:
+ /* ynf(0) */
+ {
+ DOMAINF; NAMEF = (char *) "ynf";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_YN_ZERO;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case y0l_negative:
+ /* y0l(x<0) */
+ {
+ DOMAINL; NAMEL = (char *) "y0l";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_Y0_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case y0_negative:
+ /* y0(x<0) */
+ {
+ DOMAIND; NAMED = (char *) "y0";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_Y0_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case y0f_negative:
+ /* y0f(x<0) */
+ {
+ DOMAINF; NAMEF = (char *) "y0f";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_Y0_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case y1l_negative:
+ /* y1l(x<0) */
+ {
+ DOMAINL; NAMEL = (char *) "y1l";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_Y1_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case y1_negative:
+ /* y1(x<0) */
+ {
+ DOMAIND; NAMED = (char *) "y1";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_Y1_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case y1f_negative:
+ /* y1f(x<0) */
+ {
+ DOMAINF; NAMEF = (char *) "y1f";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_Y1_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case ynl_negative:
+ /* ynl(x<0) */
+ {
+ DOMAINL; NAMEL = (char *) "ynl";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEL;
+ NOT_MATHERRL
+ {
+ WRITEL_YN_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALL;
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case yn_negative:
+ /* yn(x<0) */
+ {
+ DOMAIND; NAMED = (char *) "yn";
+ ifSVID
+ {
+ RETVAL_NEG_HUGED;
+ NOT_MATHERRD
+ {
+ WRITED_YN_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALD;
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case ynf_negative:
+ /* ynf(x<0) */
+ {
+ DOMAINF; NAMEF = (char *) "ynf";
+ ifSVID
+ {
+ RETVAL_NEG_HUGEF;
+ NOT_MATHERRF
+ {
+ WRITEF_YN_NEGATIVE;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ RETVAL_NEG_HUGE_VALF;
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case fmodl_by_zero:
+ /* fmodl(x,0) */
+ {
+ DOMAINL; NAMEL = (char *) "fmodl";
+ ifSVID
+ {
+ *(long double *)retval = *(long double *)arg1;
+ NOT_MATHERRL
+ {
+ WRITEL_FMOD;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ { /* NaN already computed */
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case fmod_by_zero:
+ /* fmod(x,0) */
+ {
+ DOMAIND; NAMED = (char *) "fmod";
+ ifSVID
+ {
+ *(double *)retval = *(double *)arg1;
+ NOT_MATHERRD
+ {
+ WRITED_FMOD;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ { /* NaN already computed */
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case fmodf_by_zero:
+ /* fmodf(x,0) */
+ {
+ DOMAINF; NAMEF = (char *) "fmodf";
+ ifSVID
+ {
+ *(float *)retval = *(float *)arg1;
+ NOT_MATHERRF
+ {
+ WRITEF_FMOD;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ case remainderl_by_zero:
+ /* remainderl(x,0) */
+ {
+ DOMAINL; NAMEL = (char *) "remainderl";
+ ifSVID
+ {
+ NOT_MATHERRL
+ {
+ WRITEL_REM;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ { /* NaN already computed */
+ NOT_MATHERRL {ERRNO_DOMAIN;}
+ }
+ *(long double *)retval = excl.retval;
+ break;
+ }
+ case remainder_by_zero:
+ /* remainder(x,0) */
+ {
+ DOMAIND; NAMED = (char *) "remainder";
+ ifSVID
+ {
+ NOT_MATHERRD
+ {
+ WRITED_REM;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ { /* NaN already computed */
+ NOT_MATHERRD {ERRNO_DOMAIN;}
+ }
+ *(double *)retval = exc.retval;
+ break;
+ }
+ case remainderf_by_zero:
+ /* remainderf(x,0) */
+ {
+ DOMAINF; NAMEF = (char *) "remainderf";
+ ifSVID
+ {
+ NOT_MATHERRF
+ {
+ WRITEF_REM;
+ ERRNO_DOMAIN;
+ }
+ }
+ else
+ {
+ NOT_MATHERRF {ERRNO_DOMAIN;}
+ }
+ *(float *)retval = excf.retval;
+ break;
+ }
+ default:
+ /* We don't want to abort () since SVID doesn't cover all math
+ library functions. */
+ break;
+ }
+ return;
+ }
+}
diff --git a/libc/sysdeps/ia64/fpu/libm_error_codes.h b/libc/sysdeps/ia64/fpu/libm_error_codes.h
new file mode 100644
index 000000000..4f0945ea1
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_error_codes.h
@@ -0,0 +1,211 @@
+/* file: libm_error_codes.h */
+
+
+/*
+// Copyright (c) 2000 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+
+// Abstract:
+// ========================================================================
+// This file contains the interface to the Intel exception dispatcher.
+//
+//
+// History:
+// ========================================================================
+// 12/15/2004 Initial version - extracted from libm_support.h
+//
+*/
+
+#if !defined(__LIBM_ERROR_CODES_H__)
+#define __LIBM_ERROR_CODES_H__
+
+typedef enum
+{
+ logl_zero=0, logl_negative, /* 0, 1 */
+ log_zero, log_negative, /* 2, 3 */
+ logf_zero, logf_negative, /* 4, 5 */
+ log10l_zero, log10l_negative, /* 6, 7 */
+ log10_zero, log10_negative, /* 8, 9 */
+ log10f_zero, log10f_negative, /* 10, 11 */
+ expl_overflow, expl_underflow, /* 12, 13 */
+ exp_overflow, exp_underflow, /* 14, 15 */
+ expf_overflow, expf_underflow, /* 16, 17 */
+ powl_overflow, powl_underflow, /* 18, 19 */
+ powl_zero_to_zero, /* 20 */
+ powl_zero_to_negative, /* 21 */
+ powl_neg_to_non_integer, /* 22 */
+ powl_nan_to_zero, /* 23 */
+ pow_overflow, pow_underflow, /* 24, 25 */
+ pow_zero_to_zero, /* 26 */
+ pow_zero_to_negative, /* 27 */
+ pow_neg_to_non_integer, /* 28 */
+ pow_nan_to_zero, /* 29 */
+ powf_overflow, powf_underflow, /* 30, 31 */
+ powf_zero_to_zero, /* 32 */
+ powf_zero_to_negative, /* 33 */
+ powf_neg_to_non_integer, /* 34 */
+ powf_nan_to_zero, /* 35 */
+ atan2l_zero, /* 36 */
+ atan2_zero, /* 37 */
+ atan2f_zero, /* 38 */
+ expm1l_overflow, /* 39 */
+ expm1l_underflow, /* 40 */
+ expm1_overflow, /* 41 */
+ expm1_underflow, /* 42 */
+ expm1f_overflow, /* 43 */
+ expm1f_underflow, /* 44 */
+ hypotl_overflow, /* 45 */
+ hypot_overflow, /* 46 */
+ hypotf_overflow, /* 47 */
+ sqrtl_negative, /* 48 */
+ sqrt_negative, /* 49 */
+ sqrtf_negative, /* 50 */
+ scalbl_overflow, scalbl_underflow, /* 51, 52 */
+ scalb_overflow, scalb_underflow, /* 53, 54 */
+ scalbf_overflow, scalbf_underflow, /* 55, 56 */
+ acosl_gt_one, acos_gt_one, acosf_gt_one, /* 57, 58, 59 */
+ asinl_gt_one, asin_gt_one, asinf_gt_one, /* 60, 61, 62 */
+ coshl_overflow, cosh_overflow, coshf_overflow, /* 63, 64, 65 */
+ y0l_zero, y0l_negative,y0l_gt_loss, /* 66, 67, 68 */
+ y0_zero, y0_negative,y0_gt_loss, /* 69, 70, 71 */
+ y0f_zero, y0f_negative,y0f_gt_loss, /* 72, 73, 74 */
+ y1l_zero, y1l_negative,y1l_gt_loss, /* 75, 76, 77 */
+ y1_zero, y1_negative,y1_gt_loss, /* 78, 79, 80 */
+ y1f_zero, y1f_negative,y1f_gt_loss, /* 81, 82, 83 */
+ ynl_zero, ynl_negative,ynl_gt_loss, /* 84, 85, 86 */
+ yn_zero, yn_negative,yn_gt_loss, /* 87, 88, 89 */
+ ynf_zero, ynf_negative,ynf_gt_loss, /* 90, 91, 92 */
+ j0l_gt_loss, /* 93 */
+ j0_gt_loss, /* 94 */
+ j0f_gt_loss, /* 95 */
+ j1l_gt_loss, /* 96 */
+ j1_gt_loss, /* 97 */
+ j1f_gt_loss, /* 98 */
+ jnl_gt_loss, /* 99 */
+ jn_gt_loss, /* 100 */
+ jnf_gt_loss, /* 101 */
+ lgammal_overflow, lgammal_negative,lgammal_reserve, /* 102, 103, 104 */
+ lgamma_overflow, lgamma_negative,lgamma_reserve, /* 105, 106, 107 */
+ lgammaf_overflow, lgammaf_negative, lgammaf_reserve,/* 108, 109, 110 */
+ gammal_overflow,gammal_negative, gammal_reserve, /* 111, 112, 113 */
+ gamma_overflow, gamma_negative, gamma_reserve, /* 114, 115, 116 */
+ gammaf_overflow,gammaf_negative,gammaf_reserve, /* 117, 118, 119 */
+ fmodl_by_zero, /* 120 */
+ fmod_by_zero, /* 121 */
+ fmodf_by_zero, /* 122 */
+ remainderl_by_zero, /* 123 */
+ remainder_by_zero, /* 124 */
+ remainderf_by_zero, /* 125 */
+ sinhl_overflow, sinh_overflow, sinhf_overflow, /* 126, 127, 128 */
+ atanhl_gt_one, atanhl_eq_one, /* 129, 130 */
+ atanh_gt_one, atanh_eq_one, /* 131, 132 */
+ atanhf_gt_one, atanhf_eq_one, /* 133, 134 */
+ acoshl_lt_one, /* 135 */
+ acosh_lt_one, /* 136 */
+ acoshf_lt_one, /* 137 */
+ log1pl_zero, log1pl_negative, /* 138, 139 */
+ log1p_zero, log1p_negative, /* 140, 141 */
+ log1pf_zero, log1pf_negative, /* 142, 143 */
+ ldexpl_overflow, ldexpl_underflow, /* 144, 145 */
+ ldexp_overflow, ldexp_underflow, /* 146, 147 */
+ ldexpf_overflow, ldexpf_underflow, /* 148, 149 */
+ logbl_zero, logb_zero, logbf_zero, /* 150, 151, 152 */
+ nextafterl_overflow, nextafter_overflow,
+ nextafterf_overflow, /* 153, 154, 155 */
+ ilogbl_zero, ilogb_zero, ilogbf_zero, /* 156, 157, 158 */
+ exp2l_overflow, exp2l_underflow, /* 159, 160 */
+ exp2_overflow, exp2_underflow, /* 161, 162 */
+ exp2f_overflow, exp2f_underflow, /* 163, 164 */
+ exp10l_overflow, exp10_overflow,
+ exp10f_overflow, /* 165, 166, 167 */
+ log2l_zero, log2l_negative, /* 168, 169 */
+ log2_zero, log2_negative, /* 170, 171 */
+ log2f_zero, log2f_negative, /* 172, 173 */
+ scalbnl_overflow, scalbnl_underflow, /* 174, 175 */
+ scalbn_overflow, scalbn_underflow, /* 176, 177 */
+ scalbnf_overflow, scalbnf_underflow, /* 178, 179 */
+ remquol_by_zero, /* 180 */
+ remquo_by_zero, /* 181 */
+ remquof_by_zero, /* 182 */
+ lrintl_large, lrint_large, lrintf_large, /* 183, 184, 185 */
+ llrintl_large, llrint_large, llrintf_large, /* 186, 187, 188 */
+ lroundl_large, lround_large, lroundf_large, /* 189, 190, 191 */
+ llroundl_large, llround_large, llroundf_large, /* 192, 193, 194 */
+ fdiml_overflow, fdim_overflow, fdimf_overflow, /* 195, 196, 197 */
+ nexttowardl_overflow, nexttoward_overflow,
+ nexttowardf_overflow, /* 198, 199, 200 */
+ scalblnl_overflow, scalblnl_underflow, /* 201, 202 */
+ scalbln_overflow, scalbln_underflow, /* 203, 204 */
+ scalblnf_overflow, scalblnf_underflow, /* 205, 206 */
+ erfcl_underflow, erfc_underflow, erfcf_underflow, /* 207, 208, 209 */
+ acosdl_gt_one, acosd_gt_one, acosdf_gt_one, /* 210, 211, 212 */
+ asindl_gt_one, asind_gt_one, asindf_gt_one, /* 213, 214, 215 */
+ atan2dl_zero, atan2d_zero, atan2df_zero, /* 216, 217, 218 */
+ tandl_overflow, tand_overflow, tandf_overflow, /* 219, 220, 221 */
+ cotdl_overflow, cotd_overflow, cotdf_overflow, /* 222, 223, 224 */
+ cotl_overflow, cot_overflow, cotf_overflow, /* 225, 226, 227 */
+ sinhcoshl_overflow, sinhcosh_overflow, sinhcoshf_overflow, /* 228, 229, 230 */
+ annuityl_by_zero, annuity_by_zero, annuityf_by_zero, /* 231, 232, 233 */
+ annuityl_less_m1, annuity_less_m1, annuityf_less_m1, /* 234, 235, 236 */
+ annuityl_overflow, annuity_overflow, annuityf_overflow, /* 237, 238, 239 */
+ annuityl_underflow, annuity_underflow, annuityf_underflow, /* 240, 241, 242 */
+ compoundl_by_zero, compound_by_zero, compoundf_by_zero, /* 243, 244, 245 */
+ compoundl_less_m1, compound_less_m1, compoundf_less_m1, /* 246, 247, 248 */
+ compoundl_overflow, compound_overflow, compoundf_overflow, /* 249, 250, 251 */
+ compoundl_underflow, compound_underflow, compoundf_underflow, /* 252, 253, 254 */
+ tgammal_overflow, tgammal_negative, tgammal_reserve, /* 255, 256, 257 */
+ tgamma_overflow, tgamma_negative, tgamma_reserve, /* 258, 259, 260 */
+ tgammaf_overflow, tgammaf_negative, tgammaf_reserve, /* 261, 262, 263 */
+ exp10l_underflow, exp10_underflow, exp10f_underflow, /* 264, 265, 266 */
+ nextafterl_underflow, nextafter_underflow,
+ nextafterf_underflow, /* 267, 268, 269 */
+ nexttowardl_underflow, nexttoward_underflow,
+ nexttowardf_underflow /* 270, 271, 272 */
+} error_types;
+
+#define LIBM_ERROR __libm_error_support
+
+extern void LIBM_ERROR(void*,void*,void*,error_types);
+#ifdef _LIBC
+libc_hidden_proto(LIBM_ERROR)
+#endif
+
+#define LIBM_ERROR1(x,r,e) LIBM_ERROR(&(x), (void *)0, &(r), e)
+#define LIBM_ERROR2(x,y,r,e) LIBM_ERROR(&(x), &(y), &(r), e)
+
+#endif // !defined(__LIBM_ERROR_CODES_H__)
diff --git a/libc/sysdeps/ia64/fpu/libm_frexp.S b/libc/sysdeps/ia64/fpu/libm_frexp.S
new file mode 100644
index 000000000..c6bd676a4
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_frexp.S
@@ -0,0 +1,209 @@
+.file "libm_frexp.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 03/20/00 Improved speed
+// 06/01/00 Fixed bug when x a double-extended denormal
+// 12/08/00 Corrected label on .endp
+// 01/23/02 Added handling for int 32 or 64 bits
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// double __libm_frexp(double x, int* y, int int_type)
+// input floating point f8, pointer to y (r33), int int_type (r34)
+// output floating point f8, returns the fraction of x, 0.5 <= fraction < 1.0
+// output int* y, returns the true exponent of x
+//
+// int_type = 0 if int is 32 bits
+// int_type = 1 if int is 64 bits
+//
+// int* y is returned as a 32 bit integer if int_type = 0
+// int* y is returned as a 64 bit integer if int_type = 1
+//
+// Overview of operation
+//==============================================================
+// break a floating point x number into fraction and an exponent
+// The fraction is returned as a double
+// The exponent is returned as an integer pointed to by y
+// This is a true (not a biased exponent) but 0fffe is subtracted
+// as a bias instead of 0xffff. This is because the fraction returned
+// is between 0.5 and 1.0, not the expected IEEE range.
+//
+// The fraction is 0.5 <= fraction < 1.0
+//
+// Registers used
+//==============================================================
+//
+// general registers:
+// r14 exponent bias for x negative
+// r15 exponent bias for x positive
+// r16 signexp of x
+// r17 exponent mask
+// r18 exponent of x
+// r19 exponent result
+// r20 signexp of 2^64
+// r32 on input contains the 64-bit IEEE double that is in f8
+// r33 on input pointer to 32-bit or 64-bit integer for exponent
+// r34 on input contains 0 if output int is 32 bits, else output int is 64 bits
+//
+// predicate registers:
+// p6 set if x is Nan, zero, or infinity
+// p7 set if x negative
+// p8 set if x positive
+// p9 set if x double-extended denormal
+// p10 set if int_type = 0, 32-bit integer
+// p11 set if int_type = 1, 64-bit integer
+//
+// floating-point registers:
+// f8 input, output
+// f9 normalized x
+// f10 signexp for significand result for x positive
+// f11 signexp for significand result for x negative
+// f12 2^64
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_frexp)
+
+// Set signexp for significand result for x>0
+// If x is a NaN, zero, or infinity, return it.
+// Put 0 in the int pointer.
+// x NAN, ZERO, INFINITY?
+// Set signexp for significand result for x<0
+{ .mfi
+ mov r15 = 0x0fffe
+ fclass.m p6,p7 = f8, 0xe7
+ mov r14 = 0x2fffe
+}
+// Form signexp of 2^64 in case x double-extended denormal
+// Save the normalized value of input in f9
+// The normalization also sets fault flags and takes faults if necessary
+{ .mfi
+ mov r20 = 0x1003f
+ fnorm.s0 f9 = f8
+ nop.i 999 ;;
+}
+
+// Move signexp for significand result for x>0 to FP reg
+// Form 2^64 in case x double-extended denormal
+{ .mmi
+ setf.exp f10 = r15
+ setf.exp f12 = r20
+ nop.i 999 ;;
+}
+
+// Move signexp for significand result for x<0 to FP reg
+// p7 if x<0, else p8
+// If x=0,nan,inf, set p10 if output int to be 32 bits, or set p11 if 64 bits
+{ .mfi
+ setf.exp f11 = r14
+(p7) fcmp.lt.s0 p7,p8 = f8,f0
+(p6) cmp.eq.unc p10,p11 = r34, r0 ;;
+}
+
+// If x NAN, ZERO, INFINITY, set *y=0 and exit
+{ .mmb
+(p10) st4 [r33] = r0 // Store *y=0 as 32-bit integer
+(p11) st8 [r33] = r0 // Store *y=0 as 64-bit integer
+(p6) br.ret.spnt b0 ;;
+}
+
+// Form exponent mask
+// Test for fnorm(x) denormal, means x double-extended denormal
+{ .mfi
+ mov r17 = 0x1ffff
+ fclass.m p9,p0 = f9, 0x0b
+ nop.i 999 ;;
+}
+
+// If x double-extended denormal add 64 to exponent bias for scaling
+// If x double-extended denormal multiply x * 2^64 which is normal
+// Set p10 if output int to be 32 bits, or set p11 if 64 bits
+{ .mfi
+(p9) add r15 = 64, r15
+(p9) fmpy.s0 f9 = f9, f12
+ cmp.eq p10,p11 = r34, r0 ;;
+}
+
+// true exponent stored to int pointer
+// the bias is treated as 0xfffe instead of
+// normal 0xffff because we want the significand
+// to be in the range <=0.5 sig < 1.0
+// Store the value of the exponent at the pointer in r33
+
+// If x>0 form significand result
+{ .mfi
+ nop.m 999
+(p8) fmerge.se f8 = f10,f9
+ nop.i 999 ;;
+}
+
+// Get signexp of normalized x
+// If x<0 form significand result
+{ .mfi
+ getf.exp r16 = f9
+(p7) fmerge.se f8 = f11,f9
+ nop.i 999 ;;
+}
+
+// Get exp of normalized x
+// Subtract off bias to get true exponent of x
+{ .mmi
+ and r18 = r17,r16 ;;
+ sub r19 = r18,r15
+ nop.i 999 ;;
+}
+
+// Store int *y as a 32-bit integer
+// Make the value a double
+{ .mfi
+(p10) st4 [r33] = r19 // Store *y as 32-bit integer
+ fnorm.d.s0 f8 = f8
+ nop.i 999
+}
+{ .mfb
+(p11) st8 [r33] = r19 // Store *y as 64-bit integer
+ nop.f 999
+ br.ret.sptk b0 ;;
+}
+
+GLOBAL_LIBM_END(__libm_frexp)
diff --git a/libc/sysdeps/ia64/fpu/libm_frexp4.S b/libc/sysdeps/ia64/fpu/libm_frexp4.S
new file mode 100644
index 000000000..08c2de676
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_frexp4.S
@@ -0,0 +1,199 @@
+.file "libm_frexp_4.s"
+
+// Copyright (C) 2000, 2001, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2/2/2000 by John Harrison, Ted Kubaska, Bob Norin, Shane Story,
+// and Ping Tak Peter Tang of the Computational Software Lab, Intel Corporation.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://developer.intel.com/opensource.
+//
+// History
+//==============================================================
+// 2/02/00: Initial version
+// 3/20/00: Improved speed
+// 6/01/00: Fixed bug when x a double-extended denormal
+// 12/08/00 Corrected label on .endp
+//
+// API
+//==============================================================
+// double frexp(double x, int* y)
+// double __libm_frexp_4(double x, int* y)
+// where int* y is a 32-bit integer
+//
+// Overview of operation
+//==============================================================
+// break a floating point x number into fraction and an exponent
+// The fraction is returned as a double
+// The exponent is returned as an integer pointed to by y
+// This is a true (not a biased exponent) but 0fffe is subtracted
+// as a bias instead of 0xffff. This is because the fraction returned
+// is between 0.5 and 1.0, not the expected IEEE range.
+//
+// The fraction is 0.5 <= fraction < 1.0
+//
+// Registers used
+//==============================================================
+//
+// general registers:
+// r14 exponent bias for x negative
+// r15 exponent bias for x positive
+// r16 signexp of x
+// r17 exponent mask
+// r18 exponent of x
+// r19 exponent result
+// r20 signexp of 2^64
+// r32 on input contains the 64-bit IEEE double that is in f8
+// r33 on input pointer to 32-bit integer for exponent
+//
+// predicate registers:
+// p6 set if x is Nan, zero, or infinity
+// p7 set if x negative
+// p8 set if x positive
+// p9 set if x double-extended denormal
+//
+// floating-point registers:
+// f8 input, output
+// f9 normalized x
+// f10 signexp for significand result for x positive
+// f11 signexp for significand result for x negative
+// f12 2^64
+
+#include "libm_support.h"
+
+.align 32
+.global __libm_frexp_4#
+
+.section .text
+.proc __libm_frexp_4#
+.align 32
+
+__libm_frexp_4:
+
+// Set signexp for significand result for x>0
+// If x is a NaN, zero, or infinity, return it.
+// Put 0 in the int pointer.
+// x NAN, ZERO, INFINITY?
+// Set signexp for significand result for x<0
+{ .mfi
+(p0) mov r15 = 0x0fffe
+(p0) fclass.m.unc p6,p0 = f8, 0xe7
+(p0) mov r14 = 0x2fffe
+}
+// Form signexp of 2^64 in case x double-extended denormal
+// Save the normalized value of input in f9
+// The normalization also sets fault flags and takes faults if necessary
+{ .mfi
+(p0) mov r20 = 0x1003f
+(p0) fnorm f9 = f8
+ nop.i 999 ;;
+}
+
+// Move signexp for significand result for x>0 to FP reg
+// Form 2^64 in case x double-extended denormal
+{ .mmi
+(p0) setf.exp f10 = r15
+(p0) setf.exp f12 = r20
+ nop.i 999 ;;
+}
+
+// Move signexp for significand result for x<0 to FP reg
+// If x NAN, ZERO, INFINITY, set *y=0 as a 32-bit integer, and exit
+{ .mmb
+(p0) setf.exp f11 = r14
+(p6) st4 [r33] = r0
+(p6) br.ret.spnt b0 ;;
+}
+
+// Form exponent mask
+// p7 if x<0, else p8
+{ .mfi
+(p0) mov r17 = 0x1ffff
+(p0) fcmp.lt.unc p7,p8 = f8,f0
+ nop.i 999 ;;
+}
+
+// Test for fnorm(x) denormal, means x double-extended denormal
+{ .mfi
+ nop.m 999
+(p0) fclass.m.unc p9,p0 = f9, 0x0b
+ nop.i 999 ;;
+}
+
+// If x double-extended denormal add 64 to exponent bias for scaling
+// If x double-extended denormal multiply x * 2^64 which is normal
+{ .mfi
+(p9) add r15 = 64, r15
+(p9) fmpy f9 = f9, f12
+ nop.i 999 ;;
+}
+
+// true exponent stored to int pointer
+// the bias is treated as 0xfffe instead of
+// normal 0xffff because we want the significand
+// to be in the range <=0.5 sig < 1.0
+// Store the value of the exponent at the pointer in r33
+
+// If x>0 form significand result
+{ .mfi
+ nop.m 999
+(p8) fmerge.se f8 = f10,f9
+ nop.i 999 ;;
+}
+
+// Get signexp of normalized x
+// If x<0 form significand result
+{ .mfi
+(p0) getf.exp r16 = f9
+(p7) fmerge.se f8 = f11,f9
+ nop.i 999 ;;
+}
+
+// Get exp of normalized x
+// Subtract off bias to get true exponent of x
+{ .mmi
+(p0) and r18 = r17,r16 ;;
+(p0) sub r19 = r18,r15
+ nop.i 999 ;;
+}
+
+// Store int y as a 32-bit integer
+// Make the value a double
+{ .mfb
+(p0) st4 [r33] = r19
+(p0) fnorm.d f8 = f8
+(p0) br.ret.sptk b0 ;;
+}
+
+.endp __libm_frexp_4
+ASM_SIZE_DIRECTIVE(__libm_frexp_4)
+strong_alias(__libm_frexp_4, _GI___libm_frexp_4)
diff --git a/libc/sysdeps/ia64/fpu/libm_frexp4f.S b/libc/sysdeps/ia64/fpu/libm_frexp4f.S
new file mode 100644
index 000000000..596dea671
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_frexp4f.S
@@ -0,0 +1,199 @@
+.file "libm_frexp_4f.s"
+
+// Copyright (C) 2000, 2001, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2/2/2000 by John Harrison, Ted Kubaska, Bob Norin, Shane Story,
+// and Ping Tak Peter Tang of the Computational Software Lab, Intel Corporation.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://developer.intel.com/opensource.
+//
+// History
+//==============================================================
+// 2/02/00: Initial version
+// 3/20/00: Improved speed
+// 6/01/00: Fixed bug when x a double-extended denormal
+// 12/08/00 Corrected label on .endp
+//
+// API
+//==============================================================
+// float frexp(float x, int* y)
+// float __libm_frexp_4f(float x, int* y)
+// where int* y is a 32-bit integer
+//
+// Overview of operation
+//==============================================================
+// break a floating point x number into fraction and an exponent
+// The fraction is returned as a float
+// The exponent is returned as an integer pointed to by y
+// This is a true (not a biased exponent) but 0fffe is subtracted
+// as a bias instead of 0xffff. This is because the fraction returned
+// is between 0.5 and 1.0, not the expected IEEE range.
+//
+// The fraction is 0.5 <= fraction < 1.0
+//
+// Registers used
+//==============================================================
+
+// general registers:
+// r14 exponent bias for x negative
+// r15 exponent bias for x positive
+// r16 signexp of x
+// r17 exponent mask
+// r18 exponent of x
+// r19 exponent result
+// r20 signexp of 2^64
+// r32 on input contains the 32-bit IEEE float that is in f8
+// r33 on input pointer to 32-bit integer for exponent
+
+// predicate registers:
+// p6 set if x is Nan, zero, or infinity
+// p7 set if x negative
+// p8 set if x positive
+// p9 set if x double-extended denormal
+
+// floating-point registers:
+// f8 input, output
+// f9 normalized x
+// f10 signexp for significand result for x positive
+// f11 signexp for significand result for x negative
+// f12 2^64
+
+#include "libm_support.h"
+
+.align 32
+.global __libm_frexp_4f#
+
+.section .text
+.proc __libm_frexp_4f#
+.align 32
+
+__libm_frexp_4f:
+
+// Set signexp for significand result for x>0
+// If x is a NaN, zero, or infinity, return it.
+// Put 0 in the int pointer.
+// x NAN, ZERO, INFINITY?
+// Set signexp for significand result for x<0
+{ .mfi
+(p0) mov r15 = 0x0fffe
+(p0) fclass.m.unc p6,p0 = f8, 0xe7
+(p0) mov r14 = 0x2fffe
+}
+// Form signexp of 2^64 in case x double-extended denormal
+// Save the normalized value of input in f9
+// The normalization also sets fault flags and takes faults if necessary
+{ .mfi
+(p0) mov r20 = 0x1003f
+(p0) fnorm f9 = f8
+ nop.i 999 ;;
+}
+
+// Move signexp for significand result for x>0 to FP reg
+// Form 2^64 in case x double-extended denormal
+{ .mmi
+(p0) setf.exp f10 = r15
+(p0) setf.exp f12 = r20
+ nop.i 999 ;;
+}
+
+// Move signexp for significand result for x<0 to FP reg
+// If x NAN, ZERO, INFINITY, set *y=0 as a 32-bit integer, and exit
+{ .mmb
+(p0) setf.exp f11 = r14
+(p6) st4 [r33] = r0
+(p6) br.ret.spnt b0 ;;
+}
+
+// Form exponent mask
+// p7 if x<0, else p8
+{ .mfi
+(p0) mov r17 = 0x1ffff
+(p0) fcmp.lt.unc p7,p8 = f8,f0
+ nop.i 999 ;;
+}
+
+// Test for fnorm(x) denormal, means x double-extended denormal
+{ .mfi
+ nop.m 999
+(p0) fclass.m.unc p9,p0 = f9, 0x0b
+ nop.i 999 ;;
+}
+
+// If x double-extended denormal add 64 to exponent bias for scaling
+// If x double-extended denormal multiply x * 2^64 which is normal
+{ .mfi
+(p9) add r15 = 64, r15
+(p9) fmpy f9 = f9, f12
+ nop.i 999 ;;
+}
+
+// true exponent stored to int pointer
+// the bias is treated as 0xfffe instead of
+// normal 0xffff because we want the significand
+// to be in the range <=0.5 sig < 1.0
+// Store the value of the exponent at the pointer in r33
+
+// If x>0 form significand result
+{ .mfi
+ nop.m 999
+(p8) fmerge.se f8 = f10,f9
+ nop.i 999 ;;
+}
+
+// Get signexp of normalized x
+// If x<0 form significand result
+{ .mfi
+(p0) getf.exp r16 = f9
+(p7) fmerge.se f8 = f11,f9
+ nop.i 999 ;;
+}
+
+// Get exp of normalized x
+// Subtract off bias to get true exponent of x
+{ .mmi
+(p0) and r18 = r17,r16 ;;
+(p0) sub r19 = r18,r15
+ nop.i 999 ;;
+}
+
+// Store int y as a 32-bit integer
+// Make the value a float
+{ .mfb
+(p0) st4 [r33] = r19
+(p0) fnorm.s f8 = f8
+(p0) br.ret.sptk b0 ;;
+}
+
+.endp __libm_frexp_4f
+ASM_SIZE_DIRECTIVE(__libm_frexp_4f)
+strong_alias(__libm_frexp_4f, _GI___libm_frexp_4f)
diff --git a/libc/sysdeps/ia64/fpu/libm_frexp4l.S b/libc/sysdeps/ia64/fpu/libm_frexp4l.S
new file mode 100644
index 000000000..447c574bf
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_frexp4l.S
@@ -0,0 +1,198 @@
+.file "libm_frexp_4l.s"
+
+// Copyright (C) 2000, 2001, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2/2/2000 by John Harrison, Ted Kubaska, Bob Norin, Shane Story,
+// and Ping Tak Peter Tang of the Computational Software Lab, Intel Corporation.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://developer.intel.com/opensource.
+//
+// History
+//==============================================================
+// 3/20/00: Initial version
+// 6/01/00: Fixed bug when x a double-extended denormal
+// 12/08/00 Corrected label on .endp
+//
+// API
+//==============================================================
+// long double frexpl(long double x, int* y)
+// long double __libm_frexp_4l(long double x, int* y)
+// where int* y is a 32-bit integer
+//
+// Overview of operation
+//==============================================================
+// break a floating point x number into fraction and an exponent
+// The fraction is returned as a long double
+// The exponent is returned as an integer pointed to by y
+// This is a true (not a biased exponent) but 0fffe is subtracted
+// as a bias instead of 0xffff. This is because the fraction returned
+// is between 0.5 and 1.0, not the expected IEEE range.
+//
+// The fraction is 0.5 <= fraction < 1.0
+//
+// Registers used
+//==============================================================
+//
+// general registers:
+// r14 exponent bias for x negative
+// r15 exponent bias for x positive
+// r16 signexp of x
+// r17 exponent mask
+// r18 exponent of x
+// r19 exponent result
+// r20 signexp of 2^64
+// r32-33 on input contains the 80-bit IEEE long double that is in f8
+// r34 on input pointer to 32-bit integer for exponent
+//
+// predicate registers:
+// p6 set if x is Nan, zero, or infinity
+// p7 set if x negative
+// p8 set if x positive
+// p9 set if x double-extended denormal
+//
+// floating-point registers:
+// f8 input, output
+// f9 normalized x
+// f10 signexp for significand result for x positive
+// f11 signexp for significand result for x negative
+// f12 2^64
+
+#include "libm_support.h"
+
+.align 32
+.global __libm_frexp_4l#
+
+.section .text
+.proc __libm_frexp_4l#
+.align 32
+
+__libm_frexp_4l:
+
+// Set signexp for significand result for x>0
+// If x is a NaN, zero, or infinity, return it.
+// Put 0 in the int pointer.
+// x NAN, ZERO, INFINITY?
+// Set signexp for significand result for x<0
+{ .mfi
+(p0) mov r15 = 0x0fffe
+(p0) fclass.m.unc p6,p0 = f8, 0xe7
+(p0) mov r14 = 0x2fffe
+}
+// Form signexp of 2^64 in case x double-extended denormal
+// Save the normalized value of input in f9
+// The normalization also sets fault flags and takes faults if necessary
+{ .mfi
+(p0) mov r20 = 0x1003f
+(p0) fnorm f9 = f8
+ nop.i 999 ;;
+}
+
+// Move signexp for significand result for x>0 to FP reg
+// Form 2^64 in case x double-extended denormal
+{ .mmi
+(p0) setf.exp f10 = r15
+(p0) setf.exp f12 = r20
+ nop.i 999 ;;
+}
+
+// Move signexp for significand result for x<0 to FP reg
+// If x NAN, ZERO, INFINITY, set *y=0 as a 32-bit integer, and exit
+{ .mmb
+(p0) setf.exp f11 = r14
+(p6) st4 [r34] = r0
+(p6) br.ret.spnt b0 ;;
+}
+
+// Form exponent mask
+// p7 if x<0, else p8
+{ .mfi
+(p0) mov r17 = 0x1ffff
+(p0) fcmp.lt.unc p7,p8 = f8,f0
+ nop.i 999 ;;
+}
+
+// Test for fnorm(x) denormal, means x double-extended denormal
+{ .mfi
+ nop.m 999
+(p0) fclass.m.unc p9,p0 = f9, 0x0b
+ nop.i 999 ;;
+}
+
+// If x double-extended denormal add 64 to exponent bias for scaling
+// If x double-extended denormal multiply x * 2^64 which is normal
+{ .mfi
+(p9) add r15 = 64, r15
+(p9) fmpy f9 = f9, f12
+ nop.i 999 ;;
+}
+
+// true exponent stored to int pointer
+// the bias is treated as 0xfffe instead of
+// normal 0xffff because we want the significand
+// to be in the range <=0.5 sig < 1.0
+// Store the value of the exponent at the pointer in r34
+
+// If x>0 form significand result
+{ .mfi
+ nop.m 999
+(p8) fmerge.se f8 = f10,f9
+ nop.i 999 ;;
+}
+
+// Get signexp of normalized x
+// If x<0 form significand result
+{ .mfi
+(p0) getf.exp r16 = f9
+(p7) fmerge.se f8 = f11,f9
+ nop.i 999 ;;
+}
+
+// Get exp of normalized x
+// Subtract off bias to get true exponent of x
+{ .mmi
+(p0) and r18 = r17,r16 ;;
+(p0) sub r19 = r18,r15
+ nop.i 999 ;;
+}
+
+// Store int y as a 32-bit integer
+// Make the value a long double
+{ .mfb
+(p0) st4 [r34] = r19
+(p0) fnorm f8 = f8
+(p0) br.ret.sptk b0 ;;
+}
+
+.endp __libm_frexp_4l
+ASM_SIZE_DIRECTIVE(__libm_frexp_4l)
+strong_alias(__libm_frexp_4l, _GI___libm_frexp_4l)
diff --git a/libc/sysdeps/ia64/fpu/libm_frexpf.S b/libc/sysdeps/ia64/fpu/libm_frexpf.S
new file mode 100644
index 000000000..dde2d09b4
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_frexpf.S
@@ -0,0 +1,209 @@
+.file "libm_frexpf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 03/20/00 Improved speed
+// 06/01/00 Fixed bug when x a double-extended denormal
+// 12/08/00 Corrected label on .endp
+// 01/23/02 Added handling for int 32 or 64 bits
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// float __libm_frexpf(float x, int* y, int int_type)
+// input floating point f8, pointer to y (r33), int int_type (r34)
+// output floating point f8, returns the fraction of x, 0.5 <= fraction < 1.0
+// output int* y, returns the true exponent of x
+//
+// int_type = 0 if int is 32 bits
+// int_type = 1 if int is 64 bits
+//
+// int* y is returned as a 32 bit integer if int_type = 0
+// int* y is returned as a 64 bit integer if int_type = 1
+//
+// Overview of operation
+//==============================================================
+// break a floating point x number into fraction and an exponent
+// The fraction is returned as a float
+// The exponent is returned as an integer pointed to by y
+// This is a true (not a biased exponent) but 0fffe is subtracted
+// as a bias instead of 0xffff. This is because the fraction returned
+// is between 0.5 and 1.0, not the expected IEEE range.
+//
+// The fraction is 0.5 <= fraction < 1.0
+//
+// Registers used
+//==============================================================
+//
+// general registers:
+// r14 exponent bias for x negative
+// r15 exponent bias for x positive
+// r16 signexp of x
+// r17 exponent mask
+// r18 exponent of x
+// r19 exponent result
+// r20 signexp of 2^64
+// r32 on input contains the 32-bit IEEE float that is in f8
+// r33 on input pointer to 32-bit or 64-bit integer for exponent
+// r34 on input contains 0 if output int is 32 bits, else output int is 64 bits
+//
+// predicate registers:
+// p6 set if x is Nan, zero, or infinity
+// p7 set if x negative
+// p8 set if x positive
+// p9 set if x double-extended denormal
+// p10 set if int_type = 0, 32-bit integer
+// p11 set if int_type = 1, 64-bit integer
+//
+// floating-point registers:
+// f8 input, output
+// f9 normalized x
+// f10 signexp for significand result for x positive
+// f11 signexp for significand result for x negative
+// f12 2^64
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_frexpf)
+
+// Set signexp for significand result for x>0
+// If x is a NaN, zero, or infinity, return it.
+// Put 0 in the int pointer.
+// x NAN, ZERO, INFINITY?
+// Set signexp for significand result for x<0
+{ .mfi
+ mov r15 = 0x0fffe
+ fclass.m p6,p7 = f8, 0xe7
+ mov r14 = 0x2fffe
+}
+// Form signexp of 2^64 in case x double-extended denormal
+// Save the normalized value of input in f9
+// The normalization also sets fault flags and takes faults if necessary
+{ .mfi
+ mov r20 = 0x1003f
+ fnorm.s0 f9 = f8
+ nop.i 999 ;;
+}
+
+// Move signexp for significand result for x>0 to FP reg
+// Form 2^64 in case x double-extended denormal
+{ .mmi
+ setf.exp f10 = r15
+ setf.exp f12 = r20
+ nop.i 999 ;;
+}
+
+// Move signexp for significand result for x<0 to FP reg
+// p7 if x<0, else p8
+// If x=0,nan,inf, set p10 if output int to be 32 bits, or set p11 if 64 bits
+{ .mfi
+ setf.exp f11 = r14
+(p7) fcmp.lt.s0 p7,p8 = f8,f0
+(p6) cmp.eq.unc p10,p11 = r34, r0 ;;
+}
+
+// If x NAN, ZERO, INFINITY, set *y=0 and exit
+{ .mmb
+(p10) st4 [r33] = r0 // Store *y=0 as 32-bit integer
+(p11) st8 [r33] = r0 // Store *y=0 as 64-bit integer
+(p6) br.ret.spnt b0 ;;
+}
+
+// Form exponent mask
+// Test for fnorm(x) denormal, means x double-extended denormal
+{ .mfi
+ mov r17 = 0x1ffff
+ fclass.m p9,p0 = f9, 0x0b
+ nop.i 999 ;;
+}
+
+// If x double-extended denormal add 64 to exponent bias for scaling
+// If x double-extended denormal multiply x * 2^64 which is normal
+// Set p10 if output int to be 32 bits, or set p11 if 64 bits
+{ .mfi
+(p9) add r15 = 64, r15
+(p9) fmpy.s0 f9 = f9, f12
+ cmp.eq p10,p11 = r34, r0 ;;
+}
+
+// true exponent stored to int pointer
+// the bias is treated as 0xfffe instead of
+// normal 0xffff because we want the significand
+// to be in the range <=0.5 sig < 1.0
+// Store the value of the exponent at the pointer in r33
+
+// If x>0 form significand result
+{ .mfi
+ nop.m 999
+(p8) fmerge.se f8 = f10,f9
+ nop.i 999 ;;
+}
+
+// Get signexp of normalized x
+// If x<0 form significand result
+{ .mfi
+ getf.exp r16 = f9
+(p7) fmerge.se f8 = f11,f9
+ nop.i 999 ;;
+}
+
+// Get exp of normalized x
+// Subtract off bias to get true exponent of x
+{ .mmi
+ and r18 = r17,r16 ;;
+ sub r19 = r18,r15
+ nop.i 999 ;;
+}
+
+// Store int *y as a 32-bit integer
+// Make the value a float
+{ .mfi
+(p10) st4 [r33] = r19 // Store *y as 32-bit integer
+ fnorm.s.s0 f8 = f8
+ nop.i 999
+}
+{ .mfb
+(p11) st8 [r33] = r19 // Store *y as 64-bit integer
+ nop.f 999
+ br.ret.sptk b0 ;;
+}
+
+GLOBAL_LIBM_END(__libm_frexpf)
diff --git a/libc/sysdeps/ia64/fpu/libm_frexpl.S b/libc/sysdeps/ia64/fpu/libm_frexpl.S
new file mode 100644
index 000000000..64f30b636
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_frexpl.S
@@ -0,0 +1,209 @@
+.file "libm_frexpl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 03/20/00 Improved speed
+// 06/01/00 Fixed bug when x a double-extended denormal
+// 12/08/00 Corrected label on .endp
+// 01/23/02 Added handling for int 32 or 64 bits
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// long double __libm_frexpl(long double x, int* y, int int_type)
+// input floating point f8, pointer to y (r34), int int_type (r35)
+// output floating point f8, returns the fraction of x, 0.5 <= fraction < 1.0
+// output int* y, returns the true exponent of x
+//
+// int_type = 0 if int is 32 bits
+// int_type = 1 if int is 64 bits
+//
+// int* y is returned as a 32 bit integer if int_type = 0
+// int* y is returned as a 64 bit integer if int_type = 1
+//
+// Overview of operation
+//==============================================================
+// break a floating point x number into fraction and an exponent
+// The fraction is returned as a long double
+// The exponent is returned as an integer pointed to by y
+// This is a true (not a biased exponent) but 0fffe is subtracted
+// as a bias instead of 0xffff. This is because the fraction returned
+// is between 0.5 and 1.0, not the expected IEEE range.
+//
+// The fraction is 0.5 <= fraction < 1.0
+//
+// Registers used
+//==============================================================
+//
+// general registers:
+// r14 exponent bias for x negative
+// r15 exponent bias for x positive
+// r16 signexp of x
+// r17 exponent mask
+// r18 exponent of x
+// r19 exponent result
+// r20 signexp of 2^64
+// r32-33 on input contains the 80-bit IEEE long double that is in f8
+// r34 on input pointer to 32-bit or 64-bit integer for exponent
+// r35 on input contains 0 if output int is 32 bits, else output int is 64 bits
+//
+// predicate registers:
+// p6 set if x is Nan, zero, or infinity
+// p7 set if x negative
+// p8 set if x positive
+// p9 set if x double-extended denormal
+// p10 set if int_type = 0, 32-bit integer
+// p11 set if int_type = 1, 64-bit integer
+//
+// floating-point registers:
+// f8 input, output
+// f9 normalized x
+// f10 signexp for significand result for x positive
+// f11 signexp for significand result for x negative
+// f12 2^64
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_frexpl)
+
+// Set signexp for significand result for x>0
+// If x is a NaN, zero, or infinity, return it.
+// Put 0 in the int pointer.
+// x NAN, ZERO, INFINITY?
+// Set signexp for significand result for x<0
+{ .mfi
+ mov r15 = 0x0fffe
+ fclass.m p6,p7 = f8, 0xe7
+ mov r14 = 0x2fffe
+}
+// Form signexp of 2^64 in case x double-extended denormal
+// Save the normalized value of input in f9
+// The normalization also sets fault flags and takes faults if necessary
+{ .mfi
+ mov r20 = 0x1003f
+ fnorm.s0 f9 = f8
+ nop.i 999 ;;
+}
+
+// Move signexp for significand result for x>0 to FP reg
+// Form 2^64 in case x double-extended denormal
+{ .mmi
+ setf.exp f10 = r15
+ setf.exp f12 = r20
+ nop.i 999 ;;
+}
+
+// Move signexp for significand result for x<0 to FP reg
+// p7 if x<0, else p8
+// If x=0,nan,inf, set p10 if output int to be 32 bits, or set p11 if 64 bits
+{ .mfi
+ setf.exp f11 = r14
+(p7) fcmp.lt.s0 p7,p8 = f8,f0
+(p6) cmp.eq.unc p10,p11 = r35, r0 ;;
+}
+
+// If x NAN, ZERO, INFINITY, set *y=0 and exit
+{ .mmb
+(p10) st4 [r34] = r0 // Store *y=0 as 32-bit integer
+(p11) st8 [r34] = r0 // Store *y=0 as 64-bit integer
+(p6) br.ret.spnt b0 ;;
+}
+
+// Form exponent mask
+// Test for fnorm(x) denormal, means x double-extended denormal
+{ .mfi
+ mov r17 = 0x1ffff
+ fclass.m p9,p0 = f9, 0x0b
+ nop.i 999 ;;
+}
+
+// If x double-extended denormal add 64 to exponent bias for scaling
+// If x double-extended denormal multiply x * 2^64 which is normal
+// Set p10 if output int to be 32 bits, or set p11 if 64 bits
+{ .mfi
+(p9) add r15 = 64, r15
+(p9) fmpy.s0 f9 = f9, f12
+ cmp.eq p10,p11 = r35, r0 ;;
+}
+
+// true exponent stored to int pointer
+// the bias is treated as 0xfffe instead of
+// normal 0xffff because we want the significand
+// to be in the range <=0.5 sig < 1.0
+// Store the value of the exponent at the pointer in r34
+
+// If x>0 form significand result
+{ .mfi
+ nop.m 999
+(p8) fmerge.se f8 = f10,f9
+ nop.i 999 ;;
+}
+
+// Get signexp of normalized x
+// If x<0 form significand result
+{ .mfi
+ getf.exp r16 = f9
+(p7) fmerge.se f8 = f11,f9
+ nop.i 999 ;;
+}
+
+// Get exp of normalized x
+// Subtract off bias to get true exponent of x
+{ .mmi
+ and r18 = r17,r16 ;;
+ sub r19 = r18,r15
+ nop.i 999 ;;
+}
+
+// Store int *y as a 32-bit integer
+// Make the value a long double
+{ .mfi
+(p10) st4 [r34] = r19 // Store *y as 32-bit integer
+ fnorm.s0 f8 = f8
+ nop.i 999
+}
+{ .mfb
+(p11) st8 [r34] = r19 // Store *y as 64-bit integer
+ nop.f 999
+ br.ret.sptk b0 ;;
+}
+
+GLOBAL_LIBM_END(__libm_frexpl)
diff --git a/libc/sysdeps/ia64/fpu/libm_lgamma.S b/libc/sysdeps/ia64/fpu/libm_lgamma.S
new file mode 100644
index 000000000..6096319ba
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_lgamma.S
@@ -0,0 +1,3623 @@
+.file "libm_lgamma.s"
+
+
+// Copyright (c) 2002 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING,BUT NOT
+// LIMITED TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code,and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 01/10/02 Initial version
+// 01/25/02 Corrected error tag numbers
+// 02/04/02 Added support of SIGN(GAMMA(x)) calculation
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 09/15/02 Fixed bug on the branch lgamma_negrecursion
+// 10/21/02 Now it returns SIGN(GAMMA(x))=-1 for negative zero
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 07/22/03 Reformatted some data tables
+// 03/31/05 Reformatted delimiters between data tables
+//
+//*********************************************************************
+//
+//*********************************************************************
+//
+// Function: __libm_lgamma(double x, int* signgam, int szsigngam)
+// computes the principle value of the logarithm of the GAMMA function
+// of x. Signum of GAMMA(x) is stored to memory starting at the address
+// specified by the signgam.
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f6-f15
+// f32-f122
+//
+// General Purpose Registers:
+// r8-r11
+// r14-r31
+// r32-r36
+// r37-r40 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6-p15
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// __libm_lgamma(+inf) = +inf
+// __libm_lgamma(-inf) = QNaN
+// __libm_lgamma(+/-0) = +inf
+// __libm_lgamma(x<0, x - integer) = +inf
+// __libm_lgamma(SNaN) = QNaN
+// __libm_lgamma(QNaN) = QNaN
+//
+//*********************************************************************
+//
+// Overview
+//
+// The method consists of three cases.
+//
+// If 512 <= x < OVERFLOW_BOUNDARY use case lgamma_pstirling;
+// else if 1 < x < 512 use case lgamma_regular;
+// else if -17 < x < 1 use case lgamma_negrecursion;
+// else if -512 < x < -17 use case lgamma_negpoly;
+// else if x < -512 use case lgamma_negstirling;
+// else if x is close to negative
+// roots of ln(GAMMA(x)) use case lgamma_negroots;
+//
+//
+// Case 512 <= x < OVERFLOW_BOUNDARY
+// ---------------------------------
+// Here we use algorithm based on the Stirling formula:
+// ln(GAMMA(x)) = ln(sqrt(2*Pi)) + (x-0.5)ln(x) - x + (W2 + W4/x^2)/x
+//
+// Case 1 < x < 512
+// ----------------
+// To calculate GAMMA(x) on this interval we use polynomial approximation
+// on following intervals [0.875; 1.25), [1.25; 1.75), [1.75, 2.25),
+// [2.25; 4), [2^i; 2^(i+1)), i=2..8
+//
+// Following variants of approximation and argument reduction are used:
+// 1. [0.875; 1.25)
+// ln(GAMMA(x)) ~ (x-1.0)*P17(x-1.0)
+//
+// 2. [1.25; 1.75)
+// ln(GAMMA(x)) ~ (x-LocalMinimun)*P17(x-LocalMinimun)
+//
+// 3. [1.75, 2.25)
+// ln(GAMMA(x)) ~ (x-2.0)*P17(x-2.0)
+//
+// 4. [2.25; 4)
+// ln(GAMMA(x)) ~ P22(x)
+//
+// 5. [2^i; 2^(i+1)), i=2..8
+// ln(GAMMA(x)) ~ P22((x-2^i)/2^i)
+//
+// Case -17 < x < 1
+// ----------------
+// Here we use the recursive formula:
+// ln(GAMMA(x)) = ln(GAMMA(x+1)) - ln(x)
+//
+// Using this formula we reduce argument to base interval [1.0; 2.0]
+//
+// Case -512 < x < -17
+// --------------------
+// Here we use the formula:
+// ln(GAMMA(-x)) = ln(Pi/(x*GAMMA(x)*sin(Pi*x))) =
+// = -ln(x) - ln((GAMMA(x)) - ln(sin(Pi*r)/(Pi*r)) - ln(|r|)
+// where r = x - rounded_to_nearest(x), i.e |r| <= 0.5 and
+// ln(sin(Pi*r)/(Pi*r)) is approximated by 14-degree polynomial of r^2
+//
+//
+// Case x < -512
+// -------------
+// Here we use algorithm based on the Stirling formula:
+// ln(GAMMA(-x)) = -ln(sqrt(2*Pi)) + (-x-0.5)ln(x) + x - (W2 + W4/x^2)/x -
+// - ln(sin(Pi*r)/(Pi*r)) - ln(|r|)
+// where r = x - rounded_to_nearest(x).
+//
+// Neighbourhoods of negative roots
+// --------------------------------
+// Here we use polynomial approximation
+// ln(GAMMA(x-x0)) = ln(GAMMA(x0)) + (x-x0)*P14(x-x0),
+// where x0 is a root of ln(GAMMA(x)) rounded to nearest double
+// precision number.
+//
+
+//*********************************************************************
+
+FR_X = f10
+FR_Y = f1 // __libm_lgamma is single argument function
+FR_RESULT = f8
+
+FR_B11 = f6
+FR_B10 = f7
+
+FR_int_N = f9
+FR_N = f10
+FR_P5 = f11
+FR_P4 = f12
+FR_P3 = f13
+FR_P2 = f14
+FR_NormX = f15
+
+FR_Ln2 = f32
+FR_C01 = f33
+FR_A17 = f33
+FR_C00 = f34
+FR_Xp2 = f34
+FR_A00 = f34
+FR_A16 = f34
+FR_C11 = f35
+FR_A15 = f35
+FR_C10 = f36
+FR_Xp3 = f36
+FR_A14 = f36
+FR_B1 = f36
+FR_C21 = f37
+FR_A13 = f37
+FR_PR01 = f37
+FR_C20 = f38
+FR_Xp6 = f38
+FR_A12 = f38
+FR_C31 = f39
+FR_Xp7 = f39
+FR_B0 = f39
+FR_A11 = f39
+FR_C30 = f40
+FR_Xp8 = f40
+FR_A10 = f40
+FR_PR00 = f40
+FR_C41 = f41
+FR_Xp9 = f41
+FR_A9 = f41
+FR_PR11 = f41
+FR_C40 = f42
+FR_A8 = f42
+FR_C51 = f43
+FR_Xp11 = f43
+FR_A7 = f43
+FR_C50 = f44
+FR_C = f44
+FR_Xp12 = f44
+FR_A6 = f44
+FR_Xm2 = f45
+FR_Xp13 = f45
+FR_A5 = f45
+FR_PR10 = f45
+FR_C61 = f46
+FR_Xp14 = f46
+FR_A4 = f46
+FR_PR21 = f46
+FR_C60 = f47
+FR_Xp15 = f47
+FR_A3 = f47
+FR_PR20 = f47
+FR_C71 = f48
+FR_Xp16 = f48
+FR_A2 = f48
+FR_PR31 = f48
+FR_C70 = f49
+FR_Xp17 = f49
+FR_A1 = f49
+FR_PR30 = f49
+FR_C81 = f50
+FR_B17 = f50
+FR_A0 = f50
+FR_C80 = f51
+FR_B16 = f51
+FR_C91 = f52
+FR_B15 = f52
+FR_C90 = f53
+FR_B14 = f53
+FR_CA1 = f54
+FR_B13 = f54
+FR_CA0 = f55
+FR_B12 = f55
+FR_CN = f56
+FR_Qlo = f56
+FR_PRN = f56
+FR_B7 = f57
+FR_B6 = f58
+FR_Qhi = f59
+FR_x = f60
+FR_x2 = f61
+FR_TpNxLn2 = f62
+FR_W2 = f63
+FR_x4 = f64
+FR_r4 = f64
+FR_x8 = f65
+FR_r8 = f65
+FR_r05 = f66
+FR_Xm05 = f66
+FR_B5 = f66
+FR_LnSqrt2Pi = f67
+FR_B4 = f67
+FR_InvX = f68
+FR_B3 = f68
+FR_InvX2 = f69
+FR_B2 = f69
+FR_W4 = f70
+FR_OvfBound = f71
+FR_05 = f72
+FR_LocalMin = f73
+FR_tmp = f73
+FR_LnX = f74
+FR_Xf = f75
+FR_InvXf = f76
+FR_rf = f77
+FR_rf2 = f78
+FR_P54f = f79
+FR_P32f = f80
+FR_rf3 = f81
+FR_P10f = f82
+FR_TpNxLn2f = f83
+FR_Nf = f84
+FR_LnXf = f85
+FR_int_Nf = f86
+FR_Tf = f87
+FR_Xf2 = f88
+FR_Xp10 = f89
+FR_w3 = f90
+FR_S28 = f90
+FR_w2 = f91
+FR_S26 = f91
+FR_w6 = f92
+FR_S24 = f92
+FR_w4 = f93
+FR_S22 = f93
+FR_w = f94
+FR_S20 = f94
+FR_Q8 = f95
+FR_S18 = f95
+FR_Q7 = f96
+FR_S16 = f96
+FR_Q4 = f97
+FR_S14 = f97
+FR_Q3 = f98
+FR_S12 = f98
+FR_Q6 = f99
+FR_S10 = f99
+FR_Q5 = f100
+FR_S8 = f100
+FR_Q2 = f101
+FR_S6 = f101
+FR_Root = f101
+FR_S4 = f102
+FR_Q1 = f102
+FR_S2 = f103
+FR_Xp1 = f104
+FR_Xf4 = f105
+FR_Xf8 = f106
+FR_Xfr = f107
+FR_Xf6 = f108
+FR_Ntrunc = f109
+FR_B9 = f110
+FR_2 = f110
+FR_B8 = f111
+FR_3 = f111
+FR_5 = f112
+FR_Xp4 = f113
+FR_Xp5 = f114
+FR_P54 = f115
+FR_P32 = f116
+FR_P10 = f117
+FR_r = f118
+FR_r2 = f119
+FR_r3 = f120
+FR_T = f121
+FR_int_Ntrunc = f122
+
+//===================================
+
+GR_TAG = r8
+GR_ExpMask = r8
+GR_ExpBias = r9
+GR_ad_Roots = r9
+GR_Expf = r10
+GR_Arg = r10
+GR_SignExp = r11
+GR_ArgXfr = r11
+
+GR_Exp = r14
+GR_Arg125 = r14
+GR_RootInd = r14
+GR_ArgAsIs = r15
+GR_Arg175 = r15
+GR_Sig = r16
+GR_Ind = r17
+GR_ad_Dx = r17
+GR_ad_1 = r18
+GR_SignExp_w = r19
+GR_2_25 = r19
+GR_Arg025 = r19
+GR_Arg15 = r19
+GR_Arg17 = r19
+GR_Exp_w = r19//21
+GR_ad_2 = r20
+GR_2xDx = r21
+GR_SignOfGamma = r21
+GR_fff9 = r22
+GR_Offs = r22
+GR_ad_Co7 = r23
+GR_Arg075 = r23
+GR_Arg0875 = r23
+GR_ad_T = r24
+GR_ad_Root = r24
+GR_Ind = r24
+GR_ad_Co = r25
+GR_ad_Ce = r26
+GR_ad_Ce7 = r27
+GR_Arg05 = r27
+GR_Offs7 = r28
+GR_ArgXfrAsIs = r28
+GR_ExpOf2 = r29
+GR_ad_LnT = r29
+GR_Dx = r29
+GR_ExpOf256 = r30
+GR_0x30033 = r30
+GR_Root = r30
+GR_PseudoRoot = r30
+GR_ad_Data = r31
+GR_ad_SignGam = r31
+
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+
+// Data tables
+//==============================================================
+
+RODATA
+.align 16
+LOCAL_OBJECT_START(lgamma_data)
+// polynomial approximation of ln(GAMMA(x)), 2.25 <= x < 512
+// [2.25; 4)
+data8 0xF888E8D7892718A2,0xC001 // C01
+data8 0xF62F273BA12A4639,0x3FFD // C11
+data8 0xA93AC50A37EC8D38,0xBFFC // C21
+data8 0xB4CC43D2C161E057,0xBFFF // C31
+data8 0xC6AC672F0C1392C7,0xC000 // C41
+data8 0xA292B9AE3276942E,0xC001 // C51
+data8 0xE554E4CCCA6C7B7B,0xC001 // C61
+data8 0x92F0F55FBC87F860,0xC002 // C71
+data8 0xAF60D0112843F6C1,0xC002 // C81
+data8 0xC5956500FA3D92E7,0xC002 // C91
+data8 0xD3B22CCBD8587750,0xC002 // CA1
+data8 0xD888B6CF34159B54,0x4001 // C00
+data8 0xBCB79C8329FD9F44,0x3FFE // C10
+data8 0xCB8896FAD69C455D,0x4000 // C20
+data8 0xE510A424639EBF5E,0x4001 // C30
+data8 0xC65ED41B097486B3,0x4002 // C40
+// [4; 8)
+data8 0x9F1F3C822D03080E,0xC001 // C01
+data8 0x941CACFA9C0FA8A6,0xC001 // C11
+data8 0xFE34336391D99CB7,0xC000 // C21
+data8 0xC40BAEAA165F81A1,0xC000 // C31
+data8 0xFE3AE166E9B4DE8F,0xBFFF // C41
+data8 0xD744F91AF7DAF873,0xBFFE // C51
+data8 0x87871851E9C32D02,0x3FFD // C61
+data8 0x9C93C03C502E808F,0x3FFF // C71
+data8 0xF78BED07501D6A8E,0x3FFF // C81
+data8 0x92FE41BA8BEADF70,0x4000 // C91
+data8 0xA021878E1903A2C6,0x3FFF // CA1
+data8 0xC85EFAC379FAFEE2,0x4001 // C00
+data8 0xC10D7AAB7CEC7FF2,0x4001 // C10
+data8 0xB3537BDF603E454C,0x4001 // C20
+data8 0xA0D44E3D5BBE44C4,0x4001 // C30
+data8 0x8B9C229B6241E7B3,0x4001 // C40
+// [8; 16)
+data8 0xD16AB33AEC220DF6,0x3FFF // C01
+data8 0x987483646E150BCD,0x4000 // C11
+data8 0x80C10A24C863999B,0x4000 // C21
+data8 0xA39A8EB6F8AACE75,0x3FFF // C31
+data8 0x93E04A1379BEC764,0x3FFD // C41
+data8 0xD9F59C4BD3A69BD1,0xBFFE // C51
+data8 0x82094EC891179B1A,0xC000 // C61
+data8 0xC90CFE3A24F70659,0xC000 // C71
+data8 0x827984EA7C155184,0xC001 // C81
+data8 0x981BFDF79D1E0D80,0xC001 // C91
+data8 0xA37209A8B97D230D,0xC001 // CA1
+data8 0xAA1989737D6BA66D,0x3FFE // C00
+data8 0xDBC013A351630AF8,0x3FFF // C10
+data8 0x8B8D47698299389D,0x4000 // C20
+data8 0xACCDD1315DE06EB0,0x4000 // C30
+data8 0xD3414A5AC81BBB2D,0x4000 // C40
+// [16; 32)
+data8 0xECB2B0BE75C5F995,0x3FFF // C01
+data8 0x9DD28BD6DBC96500,0x4000 // C11
+data8 0x8521431B99C6244F,0x4000 // C21
+data8 0xA95F92612B8413C3,0x3FFF // C31
+data8 0x9C76E643B22D9544,0x3FFD // C41
+data8 0xDD90EA99417C8038,0xBFFE // C51
+data8 0x84EA6B6D32E5F906,0xC000 // C61
+data8 0xCDBFE499E05AA622,0xC000 // C71
+data8 0x8594A7DE35427100,0xC001 // C81
+data8 0x9BC1CB2C10DC702F,0xC001 // C91
+data8 0xA7602268762666B0,0xC001 // CA1
+data8 0xDA082BCC6BDB8F7B,0x3FFE // C00
+data8 0xEEBFE1C99322B85E,0x3FFF // C10
+data8 0x96FED4C785361946,0x4000 // C20
+data8 0xB9E3A7207C16B2FE,0x4000 // C30
+data8 0xE1E8170CED48E2C7,0x4000 // C40
+// [32; 64)
+data8 0xFD481EB9AEDD53E7,0x3FFF // C01
+data8 0xA216FB66AC8C53E1,0x4000 // C11
+data8 0x885FF935787553BA,0x4000 // C21
+data8 0xAD471CD89A313327,0x3FFF // C31
+data8 0x9FF13FBA139D21E0,0x3FFD // C41
+data8 0xE25E1663A6EE0266,0xBFFE // C51
+data8 0x87BE51DD5D262FA2,0xC000 // C61
+data8 0xD211A9D4CCE55696,0xC000 // C71
+data8 0x885BEFC29FDED3C9,0xC001 // C81
+data8 0x9EFA48E6367A67F6,0xC001 // C91
+data8 0xAAD3978FC0791297,0xC001 // CA1
+data8 0xF96D210DF37A0AEA,0x3FFE // C00
+data8 0xFE11DC6783917C82,0x3FFF // C10
+data8 0x9FFCD928291B7DDE,0x4000 // C20
+data8 0xC4518F4A80E09AE1,0x4000 // C30
+data8 0xEDDFE9E0FD297C63,0x4000 // C40
+// [64; 128)
+data8 0x840E2E62609B0AD3,0x4000 // C01
+data8 0xA5275A0DD0D3DDF8,0x4000 // C11
+data8 0x8AADC6ABFC441731,0x4000 // C21
+data8 0xB041C6696BE90E50,0x3FFF // C31
+data8 0xA4A8C9153F4B037E,0x3FFD // C41
+data8 0xE3C6A461A7B86736,0xBFFE // C51
+data8 0x89047681C6DE7673,0xC000 // C61
+data8 0xD42DF77A480092DF,0xC000 // C71
+data8 0x89C25D17F086FB20,0xC001 // C81
+data8 0xA09F907D02E34EC7,0xC001 // C91
+data8 0xAC998A9CB79805B7,0xC001 // CA1
+data8 0x875CC9B69AE964CC,0x3FFF // C00
+data8 0x847836BA85DD4C12,0x4000 // C10
+data8 0xA5F3CB2B32E74936,0x4000 // C20
+data8 0xCAE2197C96CB5A0F,0x4000 // C30
+data8 0xF50F7EB60DE5CD09,0x4000 // C40
+// [128; 256)
+data8 0x87D9065DD1876926,0x4000 // C01
+data8 0xA781C28FDAD7CC25,0x4000 // C11
+data8 0x8C6A4FCE35A7EC8D,0x4000 // C21
+data8 0xB27BA081728354F9,0x3FFF // C31
+data8 0xA82FEA7124B0EB2B,0x3FFD // C41
+data8 0xE4C996E42ECBF77A,0xBFFE // C51
+data8 0x89F1A92C84FA538F,0xC000 // C61
+data8 0xD5B6CFF7DB7F6070,0xC000 // C71
+data8 0x8AC6B561FAE38B66,0xC001 // C81
+data8 0xA1D1505C438D8F46,0xC001 // C91
+data8 0xADE2DC1C924FEC81,0xC001 // CA1
+data8 0x8EF6CC62A7E0EB5A,0x3FFF // C00
+data8 0x88A2FFC0ABCB00C0,0x4000 // C10
+data8 0xAA6EA8FCB75B065B,0x4000 // C20
+data8 0xCFC4B82B3D5C9363,0x4000 // C30
+data8 0xFA60FD85DE861771,0x4000 // C40
+// [256; 512)
+data8 0x8AAA7CE4ED5C1EFD,0x4000 // C01
+data8 0xA9679234FB56F1E1,0x4000 // C11
+data8 0x8DCE02287789D841,0x4000 // C21
+data8 0xB44328EF30A8DE7E,0x3FFF // C31
+data8 0xAB0DC564BFA1AB12,0x3FFD // C41
+data8 0xE5882B16FCF2D3CB,0xBFFE // C51
+data8 0x8AA7F48993006A86,0xC000 // C61
+data8 0xD6E63752D192750D,0xC000 // C71
+data8 0x8B90080B17853295,0xC001 // C81
+data8 0xA2BDD4253128D1AB,0xC001 // C91
+data8 0xAEE1A042F96B8121,0xC001 // CA1
+data8 0x94A9C37A42E43BA7,0x3FFF // C00
+data8 0x8BFA54E703878F5A,0x4000 // C10
+data8 0xADFA426DDF14647B,0x4000 // C20
+data8 0xD39C7F7B3958EAF0,0x4000 // C30
+data8 0xFE8C3987853C01E3,0x4000 // C40
+//
+// [2.25; 4)
+data8 0x943AF77763601441,0x4003 // C50
+data8 0xC8A93F9ECB06E891,0x4003 // C60
+data8 0xFC2E5A4AD33DE19D,0x4003 // C70
+data8 0x9526B75B38670119,0x4004 // C80
+data8 0xA7675879D68B587E,0x4004 // C90
+data8 0xB31DFA672D7FB8C0,0x4004 // CA0
+data8 0x83A27775D86F9A81,0xBFD7 // CN
+// [4; 8)
+data8 0xEB8049BA5E79ADA3,0x4000 // C50
+data8 0xC20C95EA99037228,0x4000 // C60
+data8 0x9D4A8C864053CEB8,0x4000 // C70
+data8 0xFC7716544AB0C5C9,0x3FFF // C80
+data8 0xC7EB985259EABA5F,0x3FFF // C90
+data8 0xC042FB3B4C95096D,0x3FFD // CA0
+data8 0xCC2A7F930856177B,0x3FEE // CN
+// [8; 16)
+data8 0xFE1903679D078C7A,0x4000 // C50
+data8 0x957C221AB90171F1,0x4001 // C60
+data8 0xAB2C53B2A78F4031,0x4001 // C70
+data8 0xBE080AE6063AE387,0x4001 // C80
+data8 0xCC019A0311605CB9,0x4001 // C90
+data8 0xD3739D85A12C8ADF,0x4001 // CA0
+data8 0x81FA4D2B7BD7A82D,0x3FEF // CN
+// [16; 32)
+data8 0x871F69E2DD221F02,0x4001 // C50
+data8 0x9E3EF2D477442A9C,0x4001 // C60
+data8 0xB48733582B3C82C5,0x4001 // C70
+data8 0xC7DB9B3C25854A2A,0x4001 // C80
+data8 0xD628B87975BE898F,0x4001 // C90
+data8 0xDDC569C321FF119C,0x4001 // CA0
+data8 0xB27B65560DF7ADA7,0x3FEF // CN
+// [32; 64)
+data8 0x8DE4127349719B22,0x4001 // C50
+data8 0xA5C30A7760F5FBB2,0x4001 // C60
+data8 0xBCB4096055AA2A4E,0x4001 // C70
+data8 0xD08F5F2FB4E7B899,0x4001 // C80
+data8 0xDF39ED39DC91F9CF,0x4001 // C90
+data8 0xE7063E45322F072E,0x4001 // CA0
+data8 0x85A9E11DDDDE67C8,0x3FF0 // CN
+// [64; 128)
+data8 0x91CA191EB80E8893,0x4001 // C50
+data8 0xA9F1D5A55397334A,0x4001 // C60
+data8 0xC1222710295094E3,0x4001 // C70
+data8 0xD52FFABBA6CBE5C6,0x4001 // C80
+data8 0xE3FD9D5282052E1D,0x4001 // C90
+data8 0xEBDBE47BB662F3EF,0x4001 // CA0
+data8 0xEF889F489D88FD31,0x3FF0 // CN
+// [128; 256)
+data8 0x94AA029C2286F8D2,0x4001 // C50
+data8 0xAD0549E55A72389F,0x4001 // C60
+data8 0xC4628899DAF94BA4,0x4001 // C70
+data8 0xD89432A4161C72CB,0x4001 // C80
+data8 0xE77ABA75E9C38F3A,0x4001 // C90
+data8 0xEF65BFFFF71347FF,0x4001 // CA0
+data8 0xE2627460064D918D,0x3FF1 // CN
+// [256; 512)
+data8 0x96E9890D722C2FC1,0x4001 // C50
+data8 0xAF6C2236F6A1CEC4,0x4001 // C60
+data8 0xC6EBB8C9F987D20D,0x4001 // C70
+data8 0xDB38CEFD5EF328CC,0x4001 // C80
+data8 0xEA3265DC66C9A0B4,0x4001 // C90
+data8 0xF2272D6B368C70B1,0x4001 // CA0
+data8 0xDBFF93ECEBCEF1F3,0x3FF2 // CN
+//
+data8 0x3FDD8B618D5AF8FE // point of local minimum on [1;2]
+data8 0x3FE0000000000000 // 0.5
+data8 0xBFC5555DA7212371 // P5
+data8 0x3FC999A19EEF5826 // P4
+data8 0xb17217f7d1cf79ac,0x3ffe // ln(2)
+data8 0xEB3F8E4325F5A535,0x3FFE // ln(sqrt(4*arcsin(1)))
+//
+data8 0xBFCFFFFFFFFEF009 // P3
+data8 0x3FD555555554ECB2 // P2
+data8 0xBF66C16C16C16C17 // W4=B4/12=-1/360
+data8 0x7F5754D9278B51A8 // overflow boundary (first inf result)
+data8 0xAAAAAAAAAAAAAAAB,0x3FFB // W2=B2/2=1/12
+//
+data8 0x3FBC756AC654273B // Q8
+data8 0xBFC001A42489AB4D // Q7
+data8 0x3FC99999999A169B // Q4
+data8 0xBFD00000000019AC // Q3
+data8 0x3FC2492479AA0DF8 // Q6
+data8 0xBFC5555544986F52 // Q5
+data8 0x3FD5555555555555 // Q2
+data8 0xBFE0000000000000 // Q1, P1 = -0.5
+//
+data8 0x80200aaeac44ef38,0x3ff6 // ln(1/frcpa(1+ 0/2^-8))
+data8 0xc09090a2c35aa070,0x3ff7 // ln(1/frcpa(1+ 1/2^-8))
+data8 0xa0c94fcb41977c75,0x3ff8 // ln(1/frcpa(1+ 2/2^-8))
+data8 0xe18b9c263af83301,0x3ff8 // ln(1/frcpa(1+ 3/2^-8))
+data8 0x8d35c8d6399c30ea,0x3ff9 // ln(1/frcpa(1+ 4/2^-8))
+data8 0xadd4d2ecd601cbb8,0x3ff9 // ln(1/frcpa(1+ 5/2^-8))
+data8 0xce95403a192f9f01,0x3ff9 // ln(1/frcpa(1+ 6/2^-8))
+data8 0xeb59392cbcc01096,0x3ff9 // ln(1/frcpa(1+ 7/2^-8))
+data8 0x862c7d0cefd54c5d,0x3ffa // ln(1/frcpa(1+ 8/2^-8))
+data8 0x94aa63c65e70d499,0x3ffa // ln(1/frcpa(1+ 9/2^-8))
+data8 0xa54a696d4b62b382,0x3ffa // ln(1/frcpa(1+ 10/2^-8))
+data8 0xb3e4a796a5dac208,0x3ffa // ln(1/frcpa(1+ 11/2^-8))
+data8 0xc28c45b1878340a9,0x3ffa // ln(1/frcpa(1+ 12/2^-8))
+data8 0xd35c55f39d7a6235,0x3ffa // ln(1/frcpa(1+ 13/2^-8))
+data8 0xe220f037b954f1f5,0x3ffa // ln(1/frcpa(1+ 14/2^-8))
+data8 0xf0f3389b036834f3,0x3ffa // ln(1/frcpa(1+ 15/2^-8))
+data8 0xffd3488d5c980465,0x3ffa // ln(1/frcpa(1+ 16/2^-8))
+data8 0x87609ce2ed300490,0x3ffb // ln(1/frcpa(1+ 17/2^-8))
+data8 0x8ede9321e8c85927,0x3ffb // ln(1/frcpa(1+ 18/2^-8))
+data8 0x96639427f2f8e2f4,0x3ffb // ln(1/frcpa(1+ 19/2^-8))
+data8 0x9defad3e8f73217b,0x3ffb // ln(1/frcpa(1+ 20/2^-8))
+data8 0xa582ebd50097029c,0x3ffb // ln(1/frcpa(1+ 21/2^-8))
+data8 0xac06dbe75ab80fee,0x3ffb // ln(1/frcpa(1+ 22/2^-8))
+data8 0xb3a78449b2d3ccca,0x3ffb // ln(1/frcpa(1+ 23/2^-8))
+data8 0xbb4f79635ab46bb2,0x3ffb // ln(1/frcpa(1+ 24/2^-8))
+data8 0xc2fec93a83523f3f,0x3ffb // ln(1/frcpa(1+ 25/2^-8))
+data8 0xc99af2eaca4c4571,0x3ffb // ln(1/frcpa(1+ 26/2^-8))
+data8 0xd1581106472fa653,0x3ffb // ln(1/frcpa(1+ 27/2^-8))
+data8 0xd8002560d4355f2e,0x3ffb // ln(1/frcpa(1+ 28/2^-8))
+data8 0xdfcb43b4fe508632,0x3ffb // ln(1/frcpa(1+ 29/2^-8))
+data8 0xe67f6dff709d4119,0x3ffb // ln(1/frcpa(1+ 30/2^-8))
+data8 0xed393b1c22351280,0x3ffb // ln(1/frcpa(1+ 31/2^-8))
+data8 0xf5192bff087bcc35,0x3ffb // ln(1/frcpa(1+ 32/2^-8))
+data8 0xfbdf4ff6dfef2fa3,0x3ffb // ln(1/frcpa(1+ 33/2^-8))
+data8 0x81559a97f92f9cc7,0x3ffc // ln(1/frcpa(1+ 34/2^-8))
+data8 0x84be72bce90266e8,0x3ffc // ln(1/frcpa(1+ 35/2^-8))
+data8 0x88bc74113f23def2,0x3ffc // ln(1/frcpa(1+ 36/2^-8))
+data8 0x8c2ba3edf6799d11,0x3ffc // ln(1/frcpa(1+ 37/2^-8))
+data8 0x8f9dc92f92ea08b1,0x3ffc // ln(1/frcpa(1+ 38/2^-8))
+data8 0x9312e8f36efab5a7,0x3ffc // ln(1/frcpa(1+ 39/2^-8))
+data8 0x968b08643409ceb6,0x3ffc // ln(1/frcpa(1+ 40/2^-8))
+data8 0x9a062cba08a1708c,0x3ffc // ln(1/frcpa(1+ 41/2^-8))
+data8 0x9d845b3abf95485c,0x3ffc // ln(1/frcpa(1+ 42/2^-8))
+data8 0xa06fd841bc001bb4,0x3ffc // ln(1/frcpa(1+ 43/2^-8))
+data8 0xa3f3a74652fbe0db,0x3ffc // ln(1/frcpa(1+ 44/2^-8))
+data8 0xa77a8fb2336f20f5,0x3ffc // ln(1/frcpa(1+ 45/2^-8))
+data8 0xab0497015d28b0a0,0x3ffc // ln(1/frcpa(1+ 46/2^-8))
+data8 0xae91c2be6ba6a615,0x3ffc // ln(1/frcpa(1+ 47/2^-8))
+data8 0xb189d1b99aebb20b,0x3ffc // ln(1/frcpa(1+ 48/2^-8))
+data8 0xb51cced5de9c1b2c,0x3ffc // ln(1/frcpa(1+ 49/2^-8))
+data8 0xb819bee9e720d42f,0x3ffc // ln(1/frcpa(1+ 50/2^-8))
+data8 0xbbb2a0947b093a5d,0x3ffc // ln(1/frcpa(1+ 51/2^-8))
+data8 0xbf4ec1505811684a,0x3ffc // ln(1/frcpa(1+ 52/2^-8))
+data8 0xc2535bacfa8975ff,0x3ffc // ln(1/frcpa(1+ 53/2^-8))
+data8 0xc55a3eafad187eb8,0x3ffc // ln(1/frcpa(1+ 54/2^-8))
+data8 0xc8ff2484b2c0da74,0x3ffc // ln(1/frcpa(1+ 55/2^-8))
+data8 0xcc0b1a008d53ab76,0x3ffc // ln(1/frcpa(1+ 56/2^-8))
+data8 0xcfb6203844b3209b,0x3ffc // ln(1/frcpa(1+ 57/2^-8))
+data8 0xd2c73949a47a19f5,0x3ffc // ln(1/frcpa(1+ 58/2^-8))
+data8 0xd5daae18b49d6695,0x3ffc // ln(1/frcpa(1+ 59/2^-8))
+data8 0xd8f08248cf7e8019,0x3ffc // ln(1/frcpa(1+ 60/2^-8))
+data8 0xdca7749f1b3e540e,0x3ffc // ln(1/frcpa(1+ 61/2^-8))
+data8 0xdfc28e033aaaf7c7,0x3ffc // ln(1/frcpa(1+ 62/2^-8))
+data8 0xe2e012a5f91d2f55,0x3ffc // ln(1/frcpa(1+ 63/2^-8))
+data8 0xe600064ed9e292a8,0x3ffc // ln(1/frcpa(1+ 64/2^-8))
+data8 0xe9226cce42b39f60,0x3ffc // ln(1/frcpa(1+ 65/2^-8))
+data8 0xec4749fd97a28360,0x3ffc // ln(1/frcpa(1+ 66/2^-8))
+data8 0xef6ea1bf57780495,0x3ffc // ln(1/frcpa(1+ 67/2^-8))
+data8 0xf29877ff38809091,0x3ffc // ln(1/frcpa(1+ 68/2^-8))
+data8 0xf5c4d0b245cb89be,0x3ffc // ln(1/frcpa(1+ 69/2^-8))
+data8 0xf8f3afd6fcdef3aa,0x3ffc // ln(1/frcpa(1+ 70/2^-8))
+data8 0xfc2519756be1abc7,0x3ffc // ln(1/frcpa(1+ 71/2^-8))
+data8 0xff59119f503e6832,0x3ffc // ln(1/frcpa(1+ 72/2^-8))
+data8 0x8147ce381ae0e146,0x3ffd // ln(1/frcpa(1+ 73/2^-8))
+data8 0x82e45f06cb1ad0f2,0x3ffd // ln(1/frcpa(1+ 74/2^-8))
+data8 0x842f5c7c573cbaa2,0x3ffd // ln(1/frcpa(1+ 75/2^-8))
+data8 0x85ce471968c8893a,0x3ffd // ln(1/frcpa(1+ 76/2^-8))
+data8 0x876e8305bc04066d,0x3ffd // ln(1/frcpa(1+ 77/2^-8))
+data8 0x891012678031fbb3,0x3ffd // ln(1/frcpa(1+ 78/2^-8))
+data8 0x8a5f1493d766a05f,0x3ffd // ln(1/frcpa(1+ 79/2^-8))
+data8 0x8c030c778c56fa00,0x3ffd // ln(1/frcpa(1+ 80/2^-8))
+data8 0x8da85df17e31d9ae,0x3ffd // ln(1/frcpa(1+ 81/2^-8))
+data8 0x8efa663e7921687e,0x3ffd // ln(1/frcpa(1+ 82/2^-8))
+data8 0x90a22b6875c6a1f8,0x3ffd // ln(1/frcpa(1+ 83/2^-8))
+data8 0x91f62cc8f5d24837,0x3ffd // ln(1/frcpa(1+ 84/2^-8))
+data8 0x93a06cfc3857d980,0x3ffd // ln(1/frcpa(1+ 85/2^-8))
+data8 0x94f66d5e6fd01ced,0x3ffd // ln(1/frcpa(1+ 86/2^-8))
+data8 0x96a330156e6772f2,0x3ffd // ln(1/frcpa(1+ 87/2^-8))
+data8 0x97fb3582754ea25b,0x3ffd // ln(1/frcpa(1+ 88/2^-8))
+data8 0x99aa8259aad1bbf2,0x3ffd // ln(1/frcpa(1+ 89/2^-8))
+data8 0x9b0492f6227ae4a8,0x3ffd // ln(1/frcpa(1+ 90/2^-8))
+data8 0x9c5f8e199bf3a7a5,0x3ffd // ln(1/frcpa(1+ 91/2^-8))
+data8 0x9e1293b9998c1daa,0x3ffd // ln(1/frcpa(1+ 92/2^-8))
+data8 0x9f6fa31e0b41f308,0x3ffd // ln(1/frcpa(1+ 93/2^-8))
+data8 0xa0cda11eaf46390e,0x3ffd // ln(1/frcpa(1+ 94/2^-8))
+data8 0xa22c8f029cfa45aa,0x3ffd // ln(1/frcpa(1+ 95/2^-8))
+data8 0xa3e48badb7856b34,0x3ffd // ln(1/frcpa(1+ 96/2^-8))
+data8 0xa5459a0aa95849f9,0x3ffd // ln(1/frcpa(1+ 97/2^-8))
+data8 0xa6a79c84480cfebd,0x3ffd // ln(1/frcpa(1+ 98/2^-8))
+data8 0xa80a946d0fcb3eb2,0x3ffd // ln(1/frcpa(1+ 99/2^-8))
+data8 0xa96e831a3ea7b314,0x3ffd // ln(1/frcpa(1+100/2^-8))
+data8 0xaad369e3dc544e3b,0x3ffd // ln(1/frcpa(1+101/2^-8))
+data8 0xac92e9588952c815,0x3ffd // ln(1/frcpa(1+102/2^-8))
+data8 0xadfa035aa1ed8fdc,0x3ffd // ln(1/frcpa(1+103/2^-8))
+data8 0xaf6219eae1ad6e34,0x3ffd // ln(1/frcpa(1+104/2^-8))
+data8 0xb0cb2e6d8160f753,0x3ffd // ln(1/frcpa(1+105/2^-8))
+data8 0xb2354249ad950f72,0x3ffd // ln(1/frcpa(1+106/2^-8))
+data8 0xb3a056e98ef4a3b4,0x3ffd // ln(1/frcpa(1+107/2^-8))
+data8 0xb50c6dba52c6292a,0x3ffd // ln(1/frcpa(1+108/2^-8))
+data8 0xb679882c33876165,0x3ffd // ln(1/frcpa(1+109/2^-8))
+data8 0xb78c07429785cedc,0x3ffd // ln(1/frcpa(1+110/2^-8))
+data8 0xb8faeb8dc4a77d24,0x3ffd // ln(1/frcpa(1+111/2^-8))
+data8 0xba6ad77eb36ae0d6,0x3ffd // ln(1/frcpa(1+112/2^-8))
+data8 0xbbdbcc915e9bee50,0x3ffd // ln(1/frcpa(1+113/2^-8))
+data8 0xbd4dcc44f8cf12ef,0x3ffd // ln(1/frcpa(1+114/2^-8))
+data8 0xbec0d81bf5b531fa,0x3ffd // ln(1/frcpa(1+115/2^-8))
+data8 0xc034f19c139186f4,0x3ffd // ln(1/frcpa(1+116/2^-8))
+data8 0xc14cb69f7c5e55ab,0x3ffd // ln(1/frcpa(1+117/2^-8))
+data8 0xc2c2abbb6e5fd56f,0x3ffd // ln(1/frcpa(1+118/2^-8))
+data8 0xc439b2c193e6771e,0x3ffd // ln(1/frcpa(1+119/2^-8))
+data8 0xc553acb9d5c67733,0x3ffd // ln(1/frcpa(1+120/2^-8))
+data8 0xc6cc96e441272441,0x3ffd // ln(1/frcpa(1+121/2^-8))
+data8 0xc8469753eca88c30,0x3ffd // ln(1/frcpa(1+122/2^-8))
+data8 0xc962cf3ce072b05c,0x3ffd // ln(1/frcpa(1+123/2^-8))
+data8 0xcadeba8771f694aa,0x3ffd // ln(1/frcpa(1+124/2^-8))
+data8 0xcc5bc08d1f72da94,0x3ffd // ln(1/frcpa(1+125/2^-8))
+data8 0xcd7a3f99ea035c29,0x3ffd // ln(1/frcpa(1+126/2^-8))
+data8 0xcef93860c8a53c35,0x3ffd // ln(1/frcpa(1+127/2^-8))
+data8 0xd0192f68a7ed23df,0x3ffd // ln(1/frcpa(1+128/2^-8))
+data8 0xd19a201127d3c645,0x3ffd // ln(1/frcpa(1+129/2^-8))
+data8 0xd2bb92f4061c172c,0x3ffd // ln(1/frcpa(1+130/2^-8))
+data8 0xd43e80b2ee8cc8fc,0x3ffd // ln(1/frcpa(1+131/2^-8))
+data8 0xd56173601fc4ade4,0x3ffd // ln(1/frcpa(1+132/2^-8))
+data8 0xd6e6637efb54086f,0x3ffd // ln(1/frcpa(1+133/2^-8))
+data8 0xd80ad9f58f3c8193,0x3ffd // ln(1/frcpa(1+134/2^-8))
+data8 0xd991d1d31aca41f8,0x3ffd // ln(1/frcpa(1+135/2^-8))
+data8 0xdab7d02231484a93,0x3ffd // ln(1/frcpa(1+136/2^-8))
+data8 0xdc40d532cde49a54,0x3ffd // ln(1/frcpa(1+137/2^-8))
+data8 0xdd685f79ed8b265e,0x3ffd // ln(1/frcpa(1+138/2^-8))
+data8 0xde9094bbc0e17b1d,0x3ffd // ln(1/frcpa(1+139/2^-8))
+data8 0xe01c91b78440c425,0x3ffd // ln(1/frcpa(1+140/2^-8))
+data8 0xe14658f26997e729,0x3ffd // ln(1/frcpa(1+141/2^-8))
+data8 0xe270cdc2391e0d23,0x3ffd // ln(1/frcpa(1+142/2^-8))
+data8 0xe3ffce3a2aa64922,0x3ffd // ln(1/frcpa(1+143/2^-8))
+data8 0xe52bdb274ed82887,0x3ffd // ln(1/frcpa(1+144/2^-8))
+data8 0xe6589852e75d7df6,0x3ffd // ln(1/frcpa(1+145/2^-8))
+data8 0xe786068c79937a7d,0x3ffd // ln(1/frcpa(1+146/2^-8))
+data8 0xe91903adad100911,0x3ffd // ln(1/frcpa(1+147/2^-8))
+data8 0xea481236f7d35bb0,0x3ffd // ln(1/frcpa(1+148/2^-8))
+data8 0xeb77d48c692e6b14,0x3ffd // ln(1/frcpa(1+149/2^-8))
+data8 0xeca84b83d7297b87,0x3ffd // ln(1/frcpa(1+150/2^-8))
+data8 0xedd977f4962aa158,0x3ffd // ln(1/frcpa(1+151/2^-8))
+data8 0xef7179a22f257754,0x3ffd // ln(1/frcpa(1+152/2^-8))
+data8 0xf0a450d139366ca7,0x3ffd // ln(1/frcpa(1+153/2^-8))
+data8 0xf1d7e0524ff9ffdb,0x3ffd // ln(1/frcpa(1+154/2^-8))
+data8 0xf30c29036a8b6cae,0x3ffd // ln(1/frcpa(1+155/2^-8))
+data8 0xf4412bc411ea8d92,0x3ffd // ln(1/frcpa(1+156/2^-8))
+data8 0xf576e97564c8619d,0x3ffd // ln(1/frcpa(1+157/2^-8))
+data8 0xf6ad62fa1b5f172f,0x3ffd // ln(1/frcpa(1+158/2^-8))
+data8 0xf7e499368b55c542,0x3ffd // ln(1/frcpa(1+159/2^-8))
+data8 0xf91c8d10abaffe22,0x3ffd // ln(1/frcpa(1+160/2^-8))
+data8 0xfa553f7018c966f3,0x3ffd // ln(1/frcpa(1+161/2^-8))
+data8 0xfb8eb13e185d802c,0x3ffd // ln(1/frcpa(1+162/2^-8))
+data8 0xfcc8e3659d9bcbed,0x3ffd // ln(1/frcpa(1+163/2^-8))
+data8 0xfe03d6d34d487fd2,0x3ffd // ln(1/frcpa(1+164/2^-8))
+data8 0xff3f8c7581e9f0ae,0x3ffd // ln(1/frcpa(1+165/2^-8))
+data8 0x803e029e280173ae,0x3ffe // ln(1/frcpa(1+166/2^-8))
+data8 0x80dca10cc52d0757,0x3ffe // ln(1/frcpa(1+167/2^-8))
+data8 0x817ba200632755a1,0x3ffe // ln(1/frcpa(1+168/2^-8))
+data8 0x821b05f3b01d6774,0x3ffe // ln(1/frcpa(1+169/2^-8))
+data8 0x82bacd623ff19d06,0x3ffe // ln(1/frcpa(1+170/2^-8))
+data8 0x835af8c88e7a8f47,0x3ffe // ln(1/frcpa(1+171/2^-8))
+data8 0x83c5f8299e2b4091,0x3ffe // ln(1/frcpa(1+172/2^-8))
+data8 0x8466cb43f3d87300,0x3ffe // ln(1/frcpa(1+173/2^-8))
+data8 0x850803a67c80ca4b,0x3ffe // ln(1/frcpa(1+174/2^-8))
+data8 0x85a9a1d11a23b461,0x3ffe // ln(1/frcpa(1+175/2^-8))
+data8 0x864ba644a18e6e05,0x3ffe // ln(1/frcpa(1+176/2^-8))
+data8 0x86ee1182dcc432f7,0x3ffe // ln(1/frcpa(1+177/2^-8))
+data8 0x875a925d7e48c316,0x3ffe // ln(1/frcpa(1+178/2^-8))
+data8 0x87fdaa109d23aef7,0x3ffe // ln(1/frcpa(1+179/2^-8))
+data8 0x88a129ed4becfaf2,0x3ffe // ln(1/frcpa(1+180/2^-8))
+data8 0x89451278ecd7f9cf,0x3ffe // ln(1/frcpa(1+181/2^-8))
+data8 0x89b29295f8432617,0x3ffe // ln(1/frcpa(1+182/2^-8))
+data8 0x8a572ac5a5496882,0x3ffe // ln(1/frcpa(1+183/2^-8))
+data8 0x8afc2d0ce3b2dadf,0x3ffe // ln(1/frcpa(1+184/2^-8))
+data8 0x8b6a69c608cfd3af,0x3ffe // ln(1/frcpa(1+185/2^-8))
+data8 0x8c101e106e899a83,0x3ffe // ln(1/frcpa(1+186/2^-8))
+data8 0x8cb63de258f9d626,0x3ffe // ln(1/frcpa(1+187/2^-8))
+data8 0x8d2539c5bd19e2b1,0x3ffe // ln(1/frcpa(1+188/2^-8))
+data8 0x8dcc0e064b29e6f1,0x3ffe // ln(1/frcpa(1+189/2^-8))
+data8 0x8e734f45d88357ae,0x3ffe // ln(1/frcpa(1+190/2^-8))
+data8 0x8ee30cef034a20db,0x3ffe // ln(1/frcpa(1+191/2^-8))
+data8 0x8f8b0515686d1d06,0x3ffe // ln(1/frcpa(1+192/2^-8))
+data8 0x90336bba039bf32f,0x3ffe // ln(1/frcpa(1+193/2^-8))
+data8 0x90a3edd23d1c9d58,0x3ffe // ln(1/frcpa(1+194/2^-8))
+data8 0x914d0de2f5d61b32,0x3ffe // ln(1/frcpa(1+195/2^-8))
+data8 0x91be0c20d28173b5,0x3ffe // ln(1/frcpa(1+196/2^-8))
+data8 0x9267e737c06cd34a,0x3ffe // ln(1/frcpa(1+197/2^-8))
+data8 0x92d962ae6abb1237,0x3ffe // ln(1/frcpa(1+198/2^-8))
+data8 0x9383fa6afbe2074c,0x3ffe // ln(1/frcpa(1+199/2^-8))
+data8 0x942f0421651c1c4e,0x3ffe // ln(1/frcpa(1+200/2^-8))
+data8 0x94a14a3845bb985e,0x3ffe // ln(1/frcpa(1+201/2^-8))
+data8 0x954d133857f861e7,0x3ffe // ln(1/frcpa(1+202/2^-8))
+data8 0x95bfd96468e604c4,0x3ffe // ln(1/frcpa(1+203/2^-8))
+data8 0x9632d31cafafa858,0x3ffe // ln(1/frcpa(1+204/2^-8))
+data8 0x96dfaabd86fa1647,0x3ffe // ln(1/frcpa(1+205/2^-8))
+data8 0x9753261fcbb2a594,0x3ffe // ln(1/frcpa(1+206/2^-8))
+data8 0x9800c11b426b996d,0x3ffe // ln(1/frcpa(1+207/2^-8))
+data8 0x9874bf4d45ae663c,0x3ffe // ln(1/frcpa(1+208/2^-8))
+data8 0x99231f5ee9a74f79,0x3ffe // ln(1/frcpa(1+209/2^-8))
+data8 0x9997a18a56bcad28,0x3ffe // ln(1/frcpa(1+210/2^-8))
+data8 0x9a46c873a3267e79,0x3ffe // ln(1/frcpa(1+211/2^-8))
+data8 0x9abbcfc621eb6cb6,0x3ffe // ln(1/frcpa(1+212/2^-8))
+data8 0x9b310cb0d354c990,0x3ffe // ln(1/frcpa(1+213/2^-8))
+data8 0x9be14cf9e1b3515c,0x3ffe // ln(1/frcpa(1+214/2^-8))
+data8 0x9c5710b8cbb73a43,0x3ffe // ln(1/frcpa(1+215/2^-8))
+data8 0x9ccd0abd301f399c,0x3ffe // ln(1/frcpa(1+216/2^-8))
+data8 0x9d7e67f3bdce8888,0x3ffe // ln(1/frcpa(1+217/2^-8))
+data8 0x9df4ea81a99daa01,0x3ffe // ln(1/frcpa(1+218/2^-8))
+data8 0x9e6ba405a54514ba,0x3ffe // ln(1/frcpa(1+219/2^-8))
+data8 0x9f1e21c8c7bb62b3,0x3ffe // ln(1/frcpa(1+220/2^-8))
+data8 0x9f956593f6b6355c,0x3ffe // ln(1/frcpa(1+221/2^-8))
+data8 0xa00ce1092e5498c3,0x3ffe // ln(1/frcpa(1+222/2^-8))
+data8 0xa0c08309c4b912c1,0x3ffe // ln(1/frcpa(1+223/2^-8))
+data8 0xa1388a8c6faa2afa,0x3ffe // ln(1/frcpa(1+224/2^-8))
+data8 0xa1b0ca7095b5f985,0x3ffe // ln(1/frcpa(1+225/2^-8))
+data8 0xa22942eb47534a00,0x3ffe // ln(1/frcpa(1+226/2^-8))
+data8 0xa2de62326449d0a3,0x3ffe // ln(1/frcpa(1+227/2^-8))
+data8 0xa357690f88bfe345,0x3ffe // ln(1/frcpa(1+228/2^-8))
+data8 0xa3d0a93f45169a4b,0x3ffe // ln(1/frcpa(1+229/2^-8))
+data8 0xa44a22f7ffe65f30,0x3ffe // ln(1/frcpa(1+230/2^-8))
+data8 0xa500c5e5b4c1aa36,0x3ffe // ln(1/frcpa(1+231/2^-8))
+data8 0xa57ad064eb2ebbc2,0x3ffe // ln(1/frcpa(1+232/2^-8))
+data8 0xa5f5152dedf4384e,0x3ffe // ln(1/frcpa(1+233/2^-8))
+data8 0xa66f9478856233ec,0x3ffe // ln(1/frcpa(1+234/2^-8))
+data8 0xa6ea4e7cca02c32e,0x3ffe // ln(1/frcpa(1+235/2^-8))
+data8 0xa765437325341ccf,0x3ffe // ln(1/frcpa(1+236/2^-8))
+data8 0xa81e21e6c75b4020,0x3ffe // ln(1/frcpa(1+237/2^-8))
+data8 0xa899ab333fe2b9ca,0x3ffe // ln(1/frcpa(1+238/2^-8))
+data8 0xa9157039c51ebe71,0x3ffe // ln(1/frcpa(1+239/2^-8))
+data8 0xa991713433c2b999,0x3ffe // ln(1/frcpa(1+240/2^-8))
+data8 0xaa0dae5cbcc048b3,0x3ffe // ln(1/frcpa(1+241/2^-8))
+data8 0xaa8a27ede5eb13ad,0x3ffe // ln(1/frcpa(1+242/2^-8))
+data8 0xab06de228a9e3499,0x3ffe // ln(1/frcpa(1+243/2^-8))
+data8 0xab83d135dc633301,0x3ffe // ln(1/frcpa(1+244/2^-8))
+data8 0xac3fb076adc7fe7a,0x3ffe // ln(1/frcpa(1+245/2^-8))
+data8 0xacbd3cbbe47988f1,0x3ffe // ln(1/frcpa(1+246/2^-8))
+data8 0xad3b06b1a5dc57c3,0x3ffe // ln(1/frcpa(1+247/2^-8))
+data8 0xadb90e94af887717,0x3ffe // ln(1/frcpa(1+248/2^-8))
+data8 0xae3754a218f7c816,0x3ffe // ln(1/frcpa(1+249/2^-8))
+data8 0xaeb5d9175437afa2,0x3ffe // ln(1/frcpa(1+250/2^-8))
+data8 0xaf349c322e9c7cee,0x3ffe // ln(1/frcpa(1+251/2^-8))
+data8 0xafb39e30d1768d1c,0x3ffe // ln(1/frcpa(1+252/2^-8))
+data8 0xb032df51c2c93116,0x3ffe // ln(1/frcpa(1+253/2^-8))
+data8 0xb0b25fd3e6035ad9,0x3ffe // ln(1/frcpa(1+254/2^-8))
+data8 0xb1321ff67cba178c,0x3ffe // ln(1/frcpa(1+255/2^-8))
+//
+data8 0xC7DC2985D3B44557,0x3FCA // A00
+//
+// polynomial approximation of ln(GAMMA(x)), 1 <= x < 2.25
+// [0.875,1.25)
+data8 0xBF9A04F7E40C8498,0x3FAB79D8D9380F03 // C17,C16
+data8 0xBFB3B63609CA0CBD,0x3FB5564EA1675539 // C13,C12
+data8 0xBFBC806766F48C41,0x3FC010B36CDA773A // C9,C8
+data8 0xD45CE0BD54BE3D67,0xBFFC // C5
+data8 0xCD26AADF559676D0,0xBFFD // C3
+data8 0x93C467E37DB0C7A7,0xBFFE // C1
+data8 0xBFB10C251723B123,0x3FB2669DAD69A12D // C15,C14
+data8 0xBFB748A3CFCE4717,0x3FB9A01DEE29966A // C11,C10
+data8 0xBFC2703A1D85497E,0x3FC5B40CB0FD353C // C7,C6
+data8 0x8A8991563ECBBA5D,0x3FFD // C4
+data8 0xD28D3312983E9844,0x3FFE // C2
+data8 0,0 // C0
+// [1.25,1.75)
+data8 0xBF12680486396DE6,0x3F23C51FC332CD9D // C17,C16
+data8 0xBF422633DA3A1496,0x3F4CC70680768857 // C13,C12
+data8 0xBF6E2F1A1F804B5D,0x3F78FCE02A032428 // C9,C8
+data8 0x864D46FA895985C1,0xBFFA // C5
+data8 0x97213C6E35E12043,0xBFFC // C3
+data8 0x8A8A42A401D979B7,0x3FC7 // C1
+data8 0xBF2E098A8A2332A8,0x3F370E61B73B205C // C15,C14
+data8 0xBF56F9849D3BC6CC,0x3F6283126F58D7F4 // C11,C10
+data8 0xBF851F9F9516A98F,0x3F9266E797A1433F // C7,C6
+data8 0x845A14A6A81B0638,0x3FFB // C4
+data8 0xF7B95E4771C55C99,0x3FFD // C2
+data8 0xF8CDCDE61C520E0F,0xBFFB // C0
+// [1.75,2.25)
+data8 0xBEA01D7AFA5D8F52,0x3EB1010986E60253 // C17,C16
+data8 0xBEE3CBEDB4C918AA,0x3EF580F6D9D0F72D // C13,C12
+data8 0xBF2D3FD4C7F68563,0x3F40B36AF884AE9A // C9,C8
+data8 0xF2027E10C7B051EC,0xBFF7 // C5
+data8 0x89F000D2ABB03401,0xBFFB // C3
+data8 0xD8773039049E70B6,0x3FFD // C1
+data8 0xBEC112CD07CFC31A,0x3ED2528A428D30E1 // C15,C14
+data8 0xBF078DE5618D8C9F,0x3F1A127AD811A53D // C11,C10
+data8 0xBF538AC5C2BF540D,0x3F67ADD6EADB5718 // C7,C6
+data8 0xA8991563EC243383,0x3FF9 // C4
+data8 0xA51A6625307D3230,0x3FFD // C2
+data8 0,0 // C0
+//
+// polynomial approximation of ln(sin(Pi*x)/(Pi*x)), 9 <= x <= 0.5
+data8 0xBFDC1BF0931AE591,0x3FD36D6D6CE263D7 //S28,S26
+data8 0xBFBD516F4FD9FB18,0xBFBBE1703F315086 //S20,S18
+data8 0xAAB5A3CCEFCD3628,0xBFFC //S12
+data8 0x80859B5C318E19A5,0xBFFD //S8
+data8 0x8A8991563EC7EB33,0xBFFE //S4
+data8 0xBFD23AB9E6CC88AC,0xBF9957F5146FC7AF //S24,S22
+data8 0xBFC007B324E23040,0xBFC248DEC29CAC4A //S16,S14
+data8 0xCD00EFF2F8F86899,0xBFFC //S10
+data8 0xADA06587FACD668B,0xBFFD //S6
+data8 0xD28D3312983E98A0,0xBFFF //S2
+//
+data8 0x8090F777D7942F73,0x4001 // PR01
+data8 0xE5B521193CF61E63,0x4000 // PR11
+data8 0xC02C000000001939 // (-15;-14)
+data8 0x0000000000000233 // (-15;-14)
+data8 0xC02A000000016124 // (-14;-13)
+data8 0x0000000000002BFB // (-14;-13)
+data8 0xC02800000011EED9 // (-13;-12)
+data8 0x0000000000025CBB // (-13;-12)
+data8 0xC026000000D7322A // (-12;-11)
+data8 0x00000000001E1095 // (-12;-11)
+data8 0xC0240000093F2777 // (-11;-10)
+data8 0x00000000013DD3DC // (-11;-10)
+data8 0xC02200005C7768FB // (-10;-9)
+data8 0x000000000C9539B9 // (-10;-9)
+data8 0xC02000034028B3F9 // (-9;-8)
+data8 0x000000007570C565 // (-9;-8)
+data8 0xC01C0033FDEDFE1F // (-8;-7)
+data8 0x00000007357E670E // (-8;-7)
+data8 0xC018016B25897C8D // (-7;-6)
+data8 0x000000346DC5D639 // (-7;-6)
+data8 0xC014086A57F0B6D9 // (-6;-5)
+data8 0x0000010624DD2F1B // (-6;-5)
+data8 0xC010284E78599581 // (-5;-4)
+data8 0x0000051EB851EB85 // (-5;-4)
+data8 0xC009260DBC9E59AF // (-4;-3)
+data8 0x000028F5C28F5C29 // (-4;-3)
+data8 0xC003A7FC9600F86C // (-3;-2)
+data8 0x0000666666666666 // (-3;-2)
+data8 0xCC15879606130890,0x4000 // PR21
+data8 0xB42FE3281465E1CC,0x4000 // PR31
+//
+data8 0x828185F0B95C9916,0x4001 // PR00
+//
+data8 0xD4D3C819E4E5654B,0x4000 // PR10
+data8 0xA82FBBA4FCC75298,0x4000 // PR20
+data8 0xC02DFFFFFFFFFE52 // (-15;-14)
+data8 0x000000000000001C // (-15;-14)
+data8 0xC02BFFFFFFFFE6C7 // (-14;-13)
+data8 0x00000000000001A6 // (-14;-13)
+data8 0xC029FFFFFFFE9EDC // (-13;-12)
+data8 0x0000000000002BFB // (-13;-12)
+data8 0xC027FFFFFFEE1127 // (-12;-11)
+data8 0x000000000001EEC8 // (-12;-11)
+data8 0xC025FFFFFF28CDD4 // (-11;-10)
+data8 0x00000000001E1095 // (-11;-10)
+data8 0xC023FFFFF6C0D7C0 // (-10;-9)
+data8 0x000000000101B2B3 // (-10;-9)
+data8 0xC021FFFFA3884BD0 // (-9;-8)
+data8 0x000000000D6BF94D // (-9;-8)
+data8 0xC01FFFF97F8159CF // (-8;-7)
+data8 0x00000000C9539B89 // (-8;-7)
+data8 0xC01BFFCBF76B86F0 // (-7;-6)
+data8 0x00000007357E670E // (-7;-6)
+data8 0xC017FE92F591F40D // (-6;-5)
+data8 0x000000346DC5D639 // (-6;-5)
+data8 0xC013F7577A6EEAFD // (-5;-4)
+data8 0x00000147AE147AE1 // (-5;-4)
+data8 0xC00FA471547C2FE5 // (-4;-3)
+data8 0x00000C49BA5E353F // (-4;-3)
+data8 0xC005FB410A1BD901 // (-3;-2)
+data8 0x000053F7CED91687 // (-3;-2)
+data8 0x80151BB918A293AA,0x4000 // PR30
+data8 0xB3C9F8F47422A314,0x400B // PRN
+//
+// right negative roots
+//(-3;-2)
+data8 0x40BFCF8B90BE7F6B,0x40B237623345EFC3 // A15,A14
+data8 0x407A92EFB03B281E,0x40728700C7819759 // A11,A10
+data8 0x403809F04EF4D0F2,0x4038D32F682D9593 // A7,A6
+data8 0xB4A5302C53C2F2D8,0x3FFF // A3
+data8 0xC1FF4B357A9B0383,0x3FFF // A1
+data8 0x409C46632EB4B2D3,0x4091A72AFA2148F5 // A13,A12
+data8 0x4059297AC79A88DB,0x40548EAA7BE7FA6B // A9,A8
+data8 0x4017339FE04B227F,0x4021718D7CA09E02 // A5,A4
+data8 0x9B775D8017AAE668,0x4001 // A2
+data8 0x8191DB68FF4366A1,0x3FC9 // A0
+//(-4;-3)
+data8 0x425260910D35307B,0x422668F5BE7983BB // A15,A14
+data8 0x41A4454DBE4BEE43,0x41799CA93F6EA817 // A11,A10
+data8 0x40FBB97AA1400F31,0x40D293C3F7ADAB15 // A7,A6
+data8 0xE089B8926AE4517B,0x4005 // A3
+data8 0xF90532F97D630C69,0x4001 // A1
+data8 0x41F9F0CF98C5F2EA,0x41D026336C6BF394 // A13,A12
+data8 0x415057F61156D5B8,0x41251EA3055CB754 // A9,A8
+data8 0x40A99A6337D9FC2B,0x408267203D776151 // A5,A4
+data8 0xCEA694BB8A8827A9,0x4003 // A2
+data8 0xF4B02F1D73D30EED,0x3FCD // A0
+//(-5;-4)
+data8 0x4412365489340979,0x43C86441BAFDEE39 // A15,A14
+data8 0x42ED68FCB19352DD,0x42A45FCE3905CD6F // A11,A10
+data8 0x41CD14FE49FD4FCA,0x41855E3DBFA89744 // A7,A6
+data8 0xAACD88D954E0EC16,0x400B // A3
+data8 0xD652E7A490B0DCDF,0x4003 // A1
+data8 0x437F52608E0E752A,0x433560E0633E33D5 // A13,A12
+data8 0x425C83998976DE3D,0x421433DCCD3B473B // A9,A8
+data8 0x4140261EB5732106,0x40F96D18E21AE6CC // A5,A4
+data8 0xA220AE6C09FA8A0E,0x4007 // A2
+data8 0xCC1682D17A2B5A58,0xBFCF // A0
+//(-6;-5)
+data8 0x4630E41D6386CF5A,0x45C2E7992C628C8C // A15,A14
+data8 0x447AABEC714F913A,0x440EDCAB45339F3A // A11,A10
+data8 0x42C9A8D00C97E3CE,0x425F7D8D5BEAB44D // A7,A6
+data8 0x929EC2B1FB95BB5B,0x4012 // A3
+data8 0xF6B970414D717D38,0x4005 // A1
+data8 0x45545E578976F6A2,0x44E738288DD52686 // A13,A12
+data8 0x43A20921FEC49492,0x433557FD7C6A41B3 // A9,A8
+data8 0x41F3E01773761DB4,0x418A225DF2DA6C47 // A5,A4
+data8 0xE7661976117F9312,0x400B // A2
+data8 0xC33C13FEE07494DE,0x3FCF // A0
+//(-7;-6)
+data8 0x4898F1E6133305AD,0x4802C5306FE4A850 // A15,A14
+data8 0x463FD37946B44094,0x45A8D489B784C2DD // A11,A10
+data8 0x43E9500995815F06,0x4354F21E2FEE6DF5 // A7,A6
+data8 0xEF281D1E1BBE10BD,0x4019 // A3
+data8 0xB4EF24F1D78C2029,0x4008 // A1
+data8 0x476AB1D5930011E5,0x46D4867E77BFB622 // A13,A12
+data8 0x45139151ECDEF7C5,0x447F3A2BC6BF466F // A9,A8
+data8 0x42C1D3D50713FA40,0x422F9C7B52556A1B // A5,A4
+data8 0xFE711A4267CEA83A,0x4010 // A2
+data8 0xD11E91B3FF8F4B94,0xBFD2 // A0
+//(-8;-7)
+data8 0x4B39E57569811B6E,0x4A7656073EB1FA21 // A15,A14
+data8 0x482C9B24A516B0BB,0x47698FF55139C62B // A11,A10
+data8 0x452393E2BC8E8D04,0x44628E1C710DA478 // A7,A6
+data8 0x9F2A95AF1B7A773F,0x4022 // A3
+data8 0x9DA03D51C303C918,0x400B // A1
+data8 0x49B24C241A3D5BCB,0x48F01CB936ECDA67 // A13,A12
+data8 0x46A712B3425C6797,0x45E5164114BD6DA1 // A9,A8
+data8 0x43A216A356069D01,0x42E25E42A45E2108 // A5,A4
+data8 0xC1F42ED57BBC2529,0x4016 // A2
+data8 0xB1C7B615A7DCA8A9,0xBFD7 // A0
+//(-9;-8)
+data8 0x4E09D478E5EE857D,0x4D1647782106E9AB // A15,A14
+data8 0x4A3C7F4D51927548,0x49497954796D743A // A11,A10
+data8 0x467387BD6AF0CBDF,0x4582843E134111D2 // A7,A6
+data8 0x9F003C6DE9666513,0x402B // A3
+data8 0x9D8447F6BF99950A,0x400E // A1
+data8 0x4C22364D238C61A9,0x4B300B18050AB940 // A13,A12
+data8 0x4857004D64215772,0x4765074E448C3C9A // A9,A8
+data8 0x44920E9EA07BF624,0x43A257BEC94BBF48 // A5,A4
+data8 0xC1D1C49AC5B2A4B4,0x401C // A2
+data8 0x9A749AF9F2D2E688,0x3FDB // A0
+//(-10;-9)
+data8 0x5102C7C43EA26C83,0x4FDCD174DEB0426B // A15,A14
+data8 0x4C6A036195CD5BAD,0x4B44ABB52B65628A // A11,A10
+data8 0x47D6439374B98FED,0x46B2C3903EF44D7D // A7,A6
+data8 0xE25BAF73AB8A7DB3,0x4034 // A3
+data8 0xB130901CA6D81B61,0x4011 // A1
+data8 0x4EB50BB0726AE206,0x4D907A96E6D2B6E2 // A13,A12
+data8 0x4A20975D78EAF01A,0x48FAF79C9C3E7908 // A9,A8
+data8 0x459044144129A247,0x446D6043FA3150A3 // A5,A4
+data8 0xF547997E083D9BA7,0x4022 // A2
+data8 0x977AF525A6ECA1BC,0x3FDC // A0
+//(-11;-10)
+data8 0x5420A5D5E90C6D73,0x52C4710A503DC67A // A15,A14
+data8 0x4EB2ED07BA88D2A8,0x4D581001ED9A5ECE // A11,A10
+data8 0x494A8A28E9E3DFEF,0x47F1E4E1E476793E // A7,A6
+data8 0xDD0C97E12D4A3378,0x403E // A3
+data8 0xDD7C12D5182FD543,0x4014 // A1
+data8 0x5167ED536877A072,0x500DF9AF21DDC0B6 // A13,A12
+data8 0x4BFEE6F04BC34FF8,0x4AA4175CEF736A5E // A9,A8
+data8 0x4698D1B4388FEC78,0x4541EDE7607A600D // A5,A4
+data8 0xBF9F645F282AC552,0x4029 // A2
+data8 0xAE1BBE4D3CDACCF4,0x3FE1 // A0
+//(-12;-11)
+data8 0x575F0EEF5FB7D4C0,0x55CBB7302B211A7C // A15,A14
+data8 0x5113A4F1825C7CB2,0x4F822A0D46E0605A // A11,A10
+data8 0x4ACED38FC8BE069A,0x493E3B56D2649F18 // A7,A6
+data8 0x8FA8FF5DF8B72D5E,0x4049 // A3
+data8 0x9845417E8598D642,0x4018 // A1
+data8 0x5437780541C3F2D3,0x52A56279B563C1B2 // A13,A12
+data8 0x4DF0F71A48C50188,0x4C600B358988DEBF // A9,A8
+data8 0x47AE7EE95BDA3DE9,0x46200599DC16B18F // A5,A4
+data8 0xB5249F914932E55D,0x4030 // A2
+data8 0xEAE760CD2C086094,0x3FE5 // A0
+//(-13;-12)
+data8 0x5ABA5848651F6D18,0x58EF60D8A817650B // A15,A14
+data8 0x538A8CA86E13EFB1,0x51C05DBD4D01076D // A11,A10
+data8 0x4C607594C339D259,0x4A9585BD5BF932BB // A7,A6
+data8 0xF26D282C36EC3611,0x4053 // A3
+data8 0xE467DF4810EE7EEE,0x401B // A1
+data8 0x5721D9BA485E8CC3,0x5555AF2CCFB2104D // A13,A12
+data8 0x4FF4619A17B14EA6,0x4E29B2F29EB9F8C4 // A9,A8
+data8 0x48CCF27629D46E79,0x47044715F991A63D // A5,A4
+data8 0xCBC92FB9BDAA95A9,0x4037 // A2
+data8 0xFB743A426163665B,0xBFE6 // A0
+//(-14;-13)
+data8 0x5E3295B24B353EAA,0x5C2B447E29796F20 // A15,A14
+data8 0x5615A35CB5EAFAE5,0x54106AB089C95CAF // A11,A10
+data8 0x4DFEC7D93501900A,0x4BF8C4C685F01B83 // A7,A6
+data8 0x820899603D9A74D5,0x405F // A3
+data8 0xB9949919933821CB,0x401F // A1
+data8 0x5A23373DB9A995AC,0x581CBA0AF7F53009 // A13,A12
+data8 0x520929836BB304CD,0x500386409A7076DA // A9,A8
+data8 0x49F480173FEAF90B,0x47F1ACB14B810793 // A5,A4
+data8 0x86881B8674DBF205,0x403F // A2
+data8 0x8CF3CC35AA2C5F90,0x3FED // A0
+//(-15;-14)
+data8 0x61C37D53BE0029D6,0x5F80667CD9D68354 // A15,A14
+data8 0x58B3F01898E6605B,0x567149652116DB6A // A11,A10
+data8 0x4FA82FA4F5D35B00,0x4D663DB00832DF8F // A7,A6
+data8 0xAE426731C9B94996,0x406A // A3
+data8 0xA264C84BE3708F3F,0x4023 // A1
+data8 0x5D3B254BC1C806A8,0x5AF72E736048B553 // A13,A12
+data8 0x542E476505104BB0,0x51EAD96CDC4FB48F // A9,A8
+data8 0x4B25095F498DB134,0x48E4B9FDEBFE24AB // A5,A4
+data8 0xCE076A5A116C1D34,0x4046 // A2
+data8 0x940013871A15050B,0x3FF1 // A0
+//
+// left negative roots
+//(-3;-2)
+data8 0x41AEB7998DBE2B2C,0xC19053D8FAC05DF7 // A16,A15
+data8 0x4133197BF1ADEAF9,0xC1150728B9B82072 // A12,A11
+data8 0x40BDBA65E74F4526,0xC0A12239BEEF8F72 // A8,A7
+data8 0xFA8256664F99E2AA,0x4004 // A4
+data8 0x9933F9E132D2A5DB,0x4002 // A2
+data8 0x416FFB167B85F77C,0xC15166AE0ACCF87C // A14,A13
+data8 0x40F75815106322C0,0xC0DA2D23C59C348D // A10,A9
+data8 0x4084373F7CC42043,0xC0685884581F8C61 // A6,A5
+data8 0xA0C2D6186460FF9D,0xC003 // A3
+data8 0xF5096D48258CA0AD,0xBFFF // A1
+//(-4;-3)
+data8 0xC3E5BD233016D4B9,0x43A084DAD2D94AB1 // A15,A14
+data8 0xC2CCFFF5E5AED722,0x4286D143AC7D29A6 // A11,A10
+data8 0xC1B7DBBE0680D07B,0x4173E8F3ABB79CED // A7,A6
+data8 0xE929ACEA59799BAF,0xC00A // A3
+data8 0xA5CCECB362B21E1C,0xC003 // A1
+data8 0xC357EED873871B81,0x43128E0B873204FC // A13,A12
+data8 0xC242225FA76E8450,0x41FD2F76AE7386CE // A9,A8
+data8 0xC13116F7806D0C7A,0x40EE8F829F141025 // A5,A4
+data8 0xFBB6F57021B5B397,0x4006 // A2
+data8 0xEEE019B4C05AC269,0xBFCB // A0
+//(-5;-4)
+data8 0xC626A52FE8AAA100,0x45B9FD1F4DDFE31E // A15,A14
+data8 0xC473812A5675F08B,0x440738530AECC254 // A11,A10
+data8 0xC2C5068B3F94AC27,0x425A8C5C539A500B // A7,A6
+data8 0x869FBFF732F20C3A,0xC012 // A3
+data8 0xE91251F7CF25A655,0xC005 // A1
+data8 0xC54C18CB48E5DA0F,0x44E07BD36FF561DF // A13,A12
+data8 0xC39BEC120D2FEBEA,0x4330FFA5388435BE // A9,A8
+data8 0xC1F13D5D163B7FB5,0x418752A6F5AC0F39 // A5,A4
+data8 0xDA99E33C51D360F0,0x400B // A2
+data8 0x9F47A66A2F53D9B9,0x3FD1 // A0
+//(-6;-5)
+data8 0xC8970DAC16B6D59E,0x480170728306FD76 // A15,A14
+data8 0xC63E0E5030604CF3,0x45A7924D74D57C65 // A11,A10
+data8 0xC3E8684E41730FC6,0x43544D54EA2E5B9A // A7,A6
+data8 0xEB7404450C47C5F4,0xC019 // A3
+data8 0xB30FB521D2C19F8B,0xC008 // A1
+data8 0xC768F34D35DF6320,0x46D348B3BB2E68B8 // A13,A12
+data8 0xC512AC2FE5EA638E,0x447DF44BC7FC5E17 // A9,A8
+data8 0xC2C15EA6B0AAFEF9,0x422EF5D308DBC420 // A5,A4
+data8 0xFBCEE5BCA70FD3A3,0x4010 // A2
+data8 0x8589A7CFFE0A3E86,0xBFD5 // A0
+//(-7;-6)
+data8 0xCB3995A0CC961E5A,0x4A7615C6C7116ADD // A15,A14
+data8 0xC82C5AFE0BF9C427,0x47695BD2F367668B // A11,A10
+data8 0xC52377E70BA14CF5,0x4462775E859E4392 // A7,A6
+data8 0x9EC8ED6E4C3D4DBE,0xC022 // A3
+data8 0x9D5FBD2E75520E65,0xC00B // A1
+data8 0xC9B21BB881A4DDF8,0x48EFEAB06FBA0207 // A13,A12
+data8 0xC6A6E8550CBC188F,0x45E4F3D26238B099 // A9,A8
+data8 0xC3A20427DF1B110A,0x42E24F3D636F2E4E // A5,A4
+data8 0xC1A4D12A82280CFB,0x4016 // A2
+data8 0xEF46D8DCCA9E8197,0x3FD2 // A0
+//(-8;-7)
+data8 0xCE0946982B27DE5B,0x4D15DBC6664E2DD2 // A15,A14
+data8 0xCA3C769F6B3B2B93,0x49497251CD0C4363 // A11,A10
+data8 0xC67384066C47F489,0x458281393433AB28 // A7,A6
+data8 0x9EF3459926D0F14F,0xC02B // A3
+data8 0x9D7BB7F2600DFF0B,0xC00E // A1
+data8 0xCC22351326C939A7,0x4B3009431C4F1D3F // A13,A12
+data8 0xC856FAADDD48815D,0x476502BC3ECA040C // A9,A8
+data8 0xC4920C2A84173810,0x43A255C052525F99 // A5,A4
+data8 0xC1C73B6554011EFA,0x401C // A2
+data8 0x954612700ADF8317,0xBFD8 // A0
+//(-9;-8)
+data8 0xD102F5CC7B590D3A,0x4FDD0F1C30E4EB22 // A15,A14
+data8 0xCC6A02912B0DF650,0x4B44AB18E4FCC159 // A11,A10
+data8 0xC7D64314B4A2FAAB,0x46B2C334AE5E2D34 // A7,A6
+data8 0xE2598724F7E28E99,0xC034 // A3
+data8 0xB12F6FE2E195452C,0xC011 // A1
+data8 0xCEB507747AF9356A,0x4D907802C08BA48F // A13,A12
+data8 0xCA2096E3DC29516F,0x48FAF6ED046A1DB7 // A9,A8
+data8 0xC59043D21BA5EE56,0x446D5FE468B30450 // A5,A4
+data8 0xF5460A8196B59C83,0x4022 // A2
+data8 0xB108F35A8EDA92D5,0xBFDD // A0
+//(-10;-9)
+data8 0xD420430D91F8265B,0x52C406CAAAC9E0EE // A15,A14
+data8 0xCEB2ECDDDAA3DAD1,0x4D580FDA97F92E3A // A11,A10
+data8 0xC94A8A192341B5D4,0x47F1E4D8C690D07B // A7,A6
+data8 0xDD0C5F920C2F0D2B,0xC03E // A3
+data8 0xDD7BED3631657B48,0xC014 // A1
+data8 0xD167F410E64E90A4,0x500DFFED20F714A7 // A13,A12
+data8 0xCBFEE6D9043169E9,0x4AA4174F64B40AA7 // A9,A8
+data8 0xC698D1A9AF0AB9C2,0x4541EDE14987A887 // A5,A4
+data8 0xBF9F43D461B3DE6E,0x4029 // A2
+data8 0xF3891A50642FAF26,0x3FE1 // A0
+//(-11;-10)
+data8 0xD75F0EEAF769D42A,0x55CBB72C8869183A // A15,A14
+data8 0xD113A4EF80394F77,0x4F822A0B96B3ECA9 // A11,A10
+data8 0xCACED38DC75763CB,0x493E3B5522D2D028 // A7,A6
+data8 0x8FA8FB5C92533701,0xC049 // A3
+data8 0x98453EDB9339C24E,0xC018 // A1
+data8 0xD43778026CCD4B20,0x52A5627753273B9B // A13,A12
+data8 0xCDF0F718DD7E1214,0x4C600B34582911EB // A9,A8
+data8 0xC7AE7EE7F112362C,0x46200599439C264F // A5,A4
+data8 0xB5249C335342B5BC,0x4030 // A2
+data8 0x881550711D143475,0x3FE4 // A0
+//(-12;-11)
+data8 0xDAB9C724EEEE2BBB,0x58EEC971340EDDBA // A15,A14
+data8 0xD38A8C8AE63BD8BF,0x51C05DB21CEE00D3 // A11,A10
+data8 0xCC607594C311C12D,0x4A9585BD5BE6AB57 // A7,A6
+data8 0xF26D282C36EC0E66,0xC053 // A3
+data8 0xE467DF1FA674BFAE,0xC01B // A1
+data8 0xD721DE506999AA9C,0x5555B34F71B45132 // A13,A12
+data8 0xCFF4619A476BF76F,0x4E29B2F2BBE7A67E // A9,A8
+data8 0xC8CCF27629D48EDC,0x47044715F991AB46 // A5,A4
+data8 0xCBC92FB9BDAA928D,0x4037 // A2
+data8 0xCE27C4F01CF53284,0xBFE6 // A0
+//(-13;-12)
+data8 0xDE3295B24355C5A1,0x5C2B447E298B562D // A15,A14
+data8 0xD615A35CB5E92103,0x54106AB089C95E8C // A11,A10
+data8 0xCDFEC7D935019005,0x4BF8C4C685F01B83 // A7,A6
+data8 0x820899603D9A74D5,0xC05F // A3
+data8 0xB9949916F8DF4AC4,0xC01F // A1
+data8 0xDA23373DBA0B7548,0x581CBA0AF7F45C01 // A13,A12
+data8 0xD20929836BB30934,0x500386409A7076D6 // A9,A8
+data8 0xC9F480173FEAF90B,0x47F1ACB14B810793 // A5,A4
+data8 0x86881B8674DBF205,0x403F // A2
+data8 0x8CFAFA9A142C1FF0,0x3FED // A0
+//(-14;-13)
+data8 0xE1C33F356FA2C630,0x5F8038B8AA919DD7 // A15,A14
+data8 0xD8B3F0167E14982D,0x5671496400BAE0DB // A11,A10
+data8 0xCFA82FA4F5D25C3E,0x4D663DB008328C58 // A7,A6
+data8 0xAE426731C9B94980,0xC06A // A3
+data8 0xA264C84BB8A66F86,0xC023 // A1
+data8 0xDD3B26E34762ED1E,0x5AF72F76E3C1B793 // A13,A12
+data8 0xD42E476507E3D06E,0x51EAD96CDD881DFA // A9,A8
+data8 0xCB25095F498DB15F,0x48E4B9FDEBFE24B5 // A5,A4
+data8 0xCE076A5A116C1D32,0x4046 // A2
+data8 0x94001BF5A24966F5,0x3FF1 // A0
+//(-15;-14)
+data8 0xE56DB8B72D7156FF,0x62EAB0CDB22539BE // A15,A14
+data8 0xDB63D76B0D3457E7,0x58E254823D0AE4FF // A11,A10
+data8 0xD15F060BF548404A,0x4EDE65C20CD4E961 // A7,A6
+data8 0x900DA565ED76C19D,0xC076 // A3
+data8 0x9868C809852DA712,0xC027 // A1
+data8 0xE067CCDA0408AAF0,0x5DE5A79C5C5C54AF // A13,A12
+data8 0xD6611ADBF5958ED0,0x53E0294092BE9677 // A9,A8
+data8 0xCC5EA28D90EE8C5D,0x49E014930EF336EE // A5,A4
+data8 0xB57930DCE7A61AE8,0x404E // A2
+data8 0x976BEC1F30DF151C,0x3FF5 // A0
+LOCAL_OBJECT_END(lgamma_data)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_lgamma)
+
+{ .mfi
+ getf.exp GR_SignExp = f8
+ frcpa.s1 FR_C,p9 = f1,f8
+ mov GR_ExpMask = 0x1ffff
+}
+{ .mfi
+ addl GR_ad_Data = @ltoff(lgamma_data),gp
+ fcvt.fx.s1 FR_int_N = f8
+ mov GR_2_25 = 0x4002 // 2.25
+};;
+{ .mfi
+ getf.d GR_ArgAsIs = f8
+ fclass.m p13,p0 = f8,0x1EF // is x NaTVal, NaN,
+ // +/-0, +/-INF or +/-deno?
+ mov GR_ExpBias = 0xFFFF
+}
+{ .mfi
+ ld8 GR_ad_Data = [GR_ad_Data]
+ fcvt.fx.trunc.s1 FR_int_Ntrunc = f8
+ mov GR_ExpOf256 = 0x10007
+};;
+{ .mfi
+ mov GR_ExpOf2 = 0x10000
+ fcmp.lt.s1 p14,p15 = f8,f0 // p14 if x<0
+ dep.z GR_Ind = GR_SignExp,8,4
+}
+{ .mfi
+ and GR_Exp = GR_SignExp,GR_ExpMask
+ fma.s1 FR_2 = f1,f1,f1
+ cmp.lt p10,p0 = GR_SignExp,GR_ExpBias
+};;
+{ .mfi
+ add GR_ad_1 = 0xB80,GR_ad_Data
+ fnorm.s1 FR_NormX = f8
+ shr.u GR_Arg = GR_ArgAsIs,48
+}
+{ .mib
+ add GR_ad_Co = GR_Ind,GR_ad_Data
+ add GR_ad_Ce = 0x10,GR_ad_Data
+ // jump if the input argument is NaTVal, NaN, +/-0, +/-INF or +/-deno
+(p13) br.cond.spnt lgamma_spec
+};;
+lgamma_common:
+{ .mfi
+ ldfpd FR_LocalMin,FR_05 = [GR_ad_1],16
+ fmerge.se FR_x = f1,f8
+ add GR_ad_2 = 0xBC0,GR_ad_Data
+}
+{ .mfb
+ add GR_ad_Ce = GR_Ind,GR_ad_Ce
+ fms.s1 FR_w = f8,f1,f1 // x-1
+ // jump if the input argument is positive and less than 1.0
+(p10) br.cond.spnt lgamma_0_1
+};;
+{ .mfi
+ ldfe FR_C01 = [GR_ad_Co],32
+ fnma.s1 FR_InvX = FR_C,f8,f1 // NR iteration #1
+(p15) cmp.lt.unc p8,p0 = GR_ExpOf256,GR_SignExp
+}
+{ .mib
+ ldfe FR_C11 = [GR_ad_Ce],32
+(p15) cmp.lt.unc p11,p0 = GR_Arg,GR_2_25
+ // jump if the input argument isn't less than 512.0
+(p8) br.cond.spnt lgamma_pstirling
+};;
+{ .mfi
+ ldfe FR_C21 = [GR_ad_Co],32
+(p14) fms.s1 FR_r = FR_C,f8,f1 // reduced arg for log(x)
+(p14) cmp.lt.unc p0,p9 = GR_Exp,GR_ExpOf256
+}
+{ .mib
+ ldfe FR_C31 = [GR_ad_Ce],32
+ add GR_ad_Co7 = 0x12C0,GR_ad_2
+ // jump if the input argument is from range [1.0; 2.25)
+(p11) br.cond.spnt lgamma_1_2
+};;
+{ .mfi
+ ldfe FR_C41 = [GR_ad_Co],32
+ fcvt.xf FR_N = FR_int_N
+ add GR_ad_Ce7 = 0x1310,GR_ad_2
+}
+{ .mfb
+ ldfe FR_C51 = [GR_ad_Ce],32
+(p14) fma.s1 FR_5 = FR_2,FR_2,f1
+ // jump if the input argument is less or equal to -512.0
+(p9) br.cond.spnt lgamma_negstirling
+};;
+{ .mfi
+ ldfe FR_C61 = [GR_ad_Co],32
+(p14) fcvt.xf FR_Ntrunc = FR_int_Ntrunc
+ shr GR_Ind = GR_Ind,4
+}
+{ .mfi
+ ldfe FR_C71 = [GR_ad_Ce],32
+(p14) fma.s1 FR_Xp1 = f1,f1,FR_NormX // x+1
+ cmp.eq p6,p7 = GR_ExpOf2,GR_SignExp
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+ ldfe FR_C81 = [GR_ad_Co],32
+(p6) fma.s1 FR_x = f0,f0,FR_NormX
+ shladd GR_Offs7 = GR_Ind,2,GR_Ind // (ind*16)*5
+}
+{ .mfi
+ ldfe FR_C91 = [GR_ad_Ce],32
+(p7) fms.s1 FR_x = FR_x,f1,f1
+ add GR_ad_Co7 = 0x800,GR_ad_Data
+};;
+{ .mfi
+ ldfe FR_CA1 = [GR_ad_Co],32
+(p14) fma.s1 FR_3 = f1,f1,FR_2
+ shladd GR_Offs7 = GR_Ind,1,GR_Offs7 // (ind*16)*7
+}
+{ .mfi
+ ldfe FR_C00 = [GR_ad_Ce],32
+(p14) fma.s1 FR_Xp4 = FR_2,FR_2,FR_NormX
+ add GR_ad_Ce7 = 0x810,GR_ad_Data
+};;
+{ .mfi
+ ldfe FR_C10 = [GR_ad_Co],32
+(p6) fms.s1 FR_Xm2 = FR_w,f1,f1
+ add GR_ad_Co7 = GR_ad_Co7,GR_Offs7
+}
+{ .mfi
+ ldfe FR_C20 = [GR_ad_Ce],32
+(p14) fma.s1 FR_r2 = FR_r,FR_r,f0 // log(x)
+ add GR_ad_Ce7 = GR_ad_Ce7,GR_Offs7
+};;
+{ .mfi
+ ldfe FR_C30 = [GR_ad_Co],32
+(p14) fms.s1 FR_Xf = FR_NormX,f1,FR_N // xf = x - [x]
+(p14) mov GR_Arg17 = 0xC031 // -17
+}
+{ .mfi
+ ldfe FR_C40 = [GR_ad_Ce],32
+(p14) fma.s1 FR_Xp5 = FR_5,f1,FR_NormX
+(p14) sub GR_Exp = GR_Exp,GR_ExpBias
+};;
+{ .mfi
+ ldfe FR_C50 = [GR_ad_Co7],32
+(p14) fms.s1 FR_Xfr = FR_Xp1,f1,FR_Ntrunc // xfr = (x+1) - [x]
+(p14) cmp.lt.unc p13,p0 = GR_Arg,GR_Arg17
+}
+{ .mfb
+ ldfe FR_C60 = [GR_ad_Ce7],32
+(p14) fma.s1 FR_Xp10 = FR_5,FR_2,FR_NormX
+ // jump if the input argument is negative and great than -17.0
+(p13) br.cond.spnt lgamma_negrecursion
+};;
+{ .mfi
+ ldfe FR_C70 = [GR_ad_Co7],32
+ fma.s1 FR_C01 = FR_x,f1,FR_C01
+(p14) add GR_ad_Ce = 0x1310,GR_ad_2
+}
+{ .mfi
+ ldfe FR_C80 = [GR_ad_Ce7],32
+ fma.s1 FR_C11 = FR_x,f1,FR_C11
+(p14) add GR_ad_Co = 0x12C0,GR_ad_2
+};;
+{ .mfi
+ ldfe FR_C90 = [GR_ad_Co7],32
+ fma.s1 FR_C21 = FR_x,f1,FR_C21
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_CA0 = [GR_ad_Ce7],32
+ fma.s1 FR_C31 = FR_x,f1,FR_C31
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_CN = [GR_ad_Co7],32
+ fma.s1 FR_C41 = FR_x,f1,FR_C41
+ nop.i 0
+}
+{ .mfi
+(p14) ldfpd FR_P5,FR_P4 = [GR_ad_1],16
+ fma.s1 FR_C51 = FR_x,f1,FR_C51
+ nop.i 0
+};;
+{ .mfi
+(p14) ldfpd FR_P3,FR_P2 = [GR_ad_2],16
+ fma.s1 FR_C61 = FR_x,f1,FR_C61
+ nop.i 0
+}
+{ .mfi
+(p14) ldfe FR_Ln2 = [GR_ad_1]
+ fma.s1 FR_C71 = FR_x,f1,FR_C71
+ nop.i 0
+};;
+{ .mfi
+(p14) ldfpd FR_S28,FR_S26 = [GR_ad_Co],16
+ fma.s1 FR_C81 = FR_x,f1,FR_C81
+ add GR_ad_2 = 0x60,GR_ad_2
+}
+{ .mfi
+(p14) ldfpd FR_S24,FR_S22 = [GR_ad_Ce],16
+ fma.s1 FR_C91 = FR_x,f1,FR_C91
+ nop.i 0
+};;
+{ .mfi
+(p14) ldfpd FR_S20,FR_S18 = [GR_ad_Co],16
+ fma.s1 FR_CA1 = FR_x,f1,FR_CA1
+ nop.i 0
+}
+{ .mfi
+(p14) ldfpd FR_S16,FR_S14 = [GR_ad_Ce],16
+ fma.s1 FR_C01 = FR_C01,FR_x,FR_C00
+ nop.i 0
+};;
+{ .mfi
+(p14) getf.exp GR_SignExp = FR_Xf
+ fma.s1 FR_C11 = FR_C11,FR_x,FR_C10
+ nop.i 0
+}
+{ .mfi
+(p14) ldfe FR_S12 = [GR_ad_Co],16
+ fma.s1 FR_C21 = FR_C21,FR_x,FR_C20
+ nop.i 0
+};;
+{ .mfi
+(p14) getf.sig GR_Sig = FR_Xf
+(p14) frcpa.s1 FR_InvXf,p0 = f1,FR_Xf
+ nop.i 0
+}
+{ .mfi
+(p14) ldfe FR_S10 = [GR_ad_Ce],16
+ fma.s1 FR_C41 = FR_C41,FR_x,FR_C40
+ nop.i 0
+};;
+{ .mfi
+(p14) ldfe FR_S8 = [GR_ad_Co],16
+ fma.s1 FR_C51 = FR_C51,FR_x,FR_C50
+ nop.i 0
+}
+{ .mfi
+(p14) ldfe FR_S6 = [GR_ad_Ce],16
+ fma.s1 FR_C61 = FR_C61,FR_x,FR_C60
+(p14) and GR_Expf = GR_SignExp,GR_ExpMask
+};;
+{ .mfi
+(p14) sub GR_Expf = GR_Expf,GR_ExpBias
+ fma.s1 FR_C71 = FR_C71,FR_x,FR_C70
+(p14) shl GR_Ind = GR_Sig,1
+}
+{ .mfi
+(p14) ldfe FR_S4 = [GR_ad_Co],16
+ fma.s1 FR_C81 = FR_C81,FR_x,FR_C80
+(p14) cmp.eq.unc p8,p0 = 0,GR_Sig
+};;
+{ .mfi
+(p14) setf.sig FR_int_Nf = GR_Expf
+ fma.s1 FR_C91 = FR_C91,FR_x,FR_C90
+(p14) shr.u GR_Ind = GR_Ind,56
+}
+{ .mfb
+(p14) ldfe FR_S2 = [GR_ad_Ce],16
+ fma.s1 FR_CA1 = FR_CA1,FR_x,FR_CA0
+ // jump if the input argument is integer number from range (-512.0;-17.0]
+(p8) br.cond.spnt lgamma_singularity
+};;
+{ .mfi
+(p14) getf.sig GR_Sig = FR_int_Ntrunc
+ fma.s1 FR_C01 = FR_C01,FR_C11,f0
+ nop.i 0
+}
+{ .mfi
+(p14) shladd GR_ad_T = GR_Ind,4,GR_ad_2
+ fma.s1 FR_C31 = FR_C31,FR_x,FR_C30
+ nop.i 0
+};;
+{ .mfi
+(p14) ldfe FR_Tf = [GR_ad_T]
+(p14) fms.s1 FR_rf = FR_InvXf,FR_Xf,f1 // reduced arg for log({x})
+(p14) extr.u GR_Ind = GR_ArgAsIs,44,8
+}
+{ .mfi
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+ fma.s1 FR_C21 = FR_C21,FR_C41,f0
+ mov GR_SignOfGamma = 1
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C51 = FR_C51,FR_C61,f0
+(p14) tbit.z.unc p8,p0 = GR_Sig,0
+}
+{ .mfi
+(p14) shladd GR_ad_T = GR_Ind,4,GR_ad_2
+(p6) fma.s1 FR_CN = FR_CN,FR_Xm2,f0
+ nop.i 0
+};;
+{ .mfi
+(p14) setf.sig FR_int_N = GR_Exp
+ fma.s1 FR_C71 = FR_C71,FR_C81,f0
+(p8) sub GR_SignOfGamma = r0,GR_SignOfGamma
+}
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_Xf2 = FR_Xf,FR_Xf,f0
+ nop.i 0
+};;
+{ .mfi
+(p14) ldfe FR_T = [GR_ad_T]
+ fma.s1 FR_C91 = FR_C91,FR_CA1,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_r2 = FR_r,FR_r,f0
+ nop.i 0
+};;
+.pred.rel "mutex",p9,p10
+{ .mfi
+ // store sign of gamma(x) as 32-bit int
+(p9) st4 [r33] = GR_SignOfGamma
+ fma.s1 FR_C01 = FR_C01,FR_C31,f0
+ nop.i 0
+}
+{ .mfi
+ // store sign of gamma(x) as 64-bit int
+(p10) st8 [r33] = GR_SignOfGamma
+(p14) fma.s1 FR_P54 = FR_P5,FR_r,FR_P4
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_P32 = FR_P3,FR_r,FR_P2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p14) fma.s1 FR_P54f = FR_P5,FR_rf,FR_P4
+ // jump if the input argument is non-integer from range (-512.0;-17.0]
+(p14) br.cond.spnt lgamma_negpoly
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C21 = FR_C21,FR_C51,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C71 = FR_C71,FR_C91,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_CN = FR_C01,FR_CN,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C21 = FR_C21,FR_C71,f0
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = FR_C21,FR_CN,f0
+ br.ret.sptk b0 // exit for arguments from range [2.25; 512.0)
+};;
+// branch for calculating of ln(GAMMA(x)) for -512 < x < -17
+//---------------------------------------------------------------------
+.align 32
+lgamma_negpoly:
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Xf4 = FR_Xf2,FR_Xf2,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S28 = FR_S28,FR_Xf2,FR_S26
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S24 = FR_S24,FR_Xf2,FR_S22
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S20 = FR_S20,FR_Xf2,FR_S18
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S16 = FR_S16,FR_Xf2,FR_S14
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S12 = FR_S12,FR_Xf2,FR_S10
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S8 = FR_S8,FR_Xf2,FR_S6
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S4 = FR_S4,FR_Xf2,FR_S2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rf2 = FR_rf,FR_rf,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P32f = FR_P3,FR_rf,FR_P2 // log(x)
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r3 = FR_r2,FR_r,f0 // log(x)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_Nf = FR_int_Nf // log({x})
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S28 = FR_S28,FR_Xf4,FR_S24
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Xf8 = FR_Xf4,FR_Xf4,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S20 = FR_S20,FR_Xf4,FR_S16
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C21 = FR_C21,FR_C51,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S12 = FR_S12,FR_Xf4,FR_S8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C71 = FR_C71,FR_C91,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_P10 = FR_r2,FR_05,FR_r // log(x)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P54 = FR_P54,FR_r2,FR_P32 // log(x)
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_P10f = FR_rf2,FR_05,FR_rf // log({x})
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_N = FR_int_N // log(x)
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rf3 = FR_rf2,FR_rf,f0 // log({x})
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P54f = FR_P54f,FR_rf2,FR_P32f // log({x})
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S28 = FR_S28,FR_Xf8,FR_S20
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_TpNxLn2f = FR_Nf,FR_Ln2,FR_Tf // log({x})
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_CN = FR_C01,FR_CN,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C21 = FR_C21,FR_C71,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P54 = FR_P54,FR_r3,FR_P10 // log(x)
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_TpNxLn2 = FR_N,FR_Ln2,FR_T // log(x)
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P54f = FR_P54f,FR_rf3,FR_P10f // log({x})
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S28 = FR_S28,FR_Xf8,FR_S12
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_C21 = FR_C21,FR_CN,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_LnX = FR_TpNxLn2,f1,FR_P54 // log(x)
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_LnXf = FR_TpNxLn2f,f1,FR_P54f // log({x})
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S28 = FR_S28,FR_Xf4,FR_S4
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_LnX = FR_LnX,f1,FR_LnXf
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_S28 = FR_S28,FR_Xf2,FR_C21
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ fms.d.s0 f8 = FR_S28,f1,FR_LnX
+ br.ret.sptk b0
+};;
+// branch for calculating of ln(GAMMA(x)) for x >= 512
+//---------------------------------------------------------------------
+.align 32
+lgamma_pstirling:
+{ .mfi
+ ldfpd FR_P5,FR_P4 = [GR_ad_1],16
+ nop.f 0
+ and GR_Exp = GR_SignExp,GR_ExpMask
+}
+{ .mfi
+ ldfpd FR_P3,FR_P2 = [GR_ad_2],16
+ fma.s1 FR_InvX = FR_C,FR_InvX,FR_C // NR iteration #1
+ mov GR_ExpBias = 0xffff
+};;
+{ .mfi
+ ldfe FR_Ln2 = [GR_ad_1],16
+ nop.f 0
+ sub GR_Exp = GR_Exp,GR_ExpBias
+};;
+{ .mfi
+ ldfpd FR_W4,FR_OvfBound = [GR_ad_2],16
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ setf.sig FR_int_N = GR_Exp
+ fms.s1 FR_r = FR_C,f8,f1
+ nop.i 0
+};;
+{ .mmf
+ getf.sig GR_Sig = FR_NormX
+ ldfe FR_LnSqrt2Pi = [GR_ad_1],16
+ nop.f 0
+};;
+{ .mmf
+ ldfe FR_W2 = [GR_ad_2],16
+ nop.m 0
+ fnma.s1 FR_InvX2 = FR_InvX,FR_NormX,f1 // NR iteration #2
+};;
+{ .mfi
+ add GR_ad_2 = 0x40,GR_ad_2
+ nop.f 0
+ shl GR_Ind = GR_Sig,1
+};;
+{ .mfi
+ mov GR_SignOfGamma = 1
+ nop.f 0
+ shr.u GR_Ind = GR_Ind,56
+};;
+{ .mfi
+ shladd GR_ad_2 = GR_Ind,4,GR_ad_2
+ fma.s1 FR_r2 = FR_r,FR_r,f0
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+};;
+{ .mfi
+ ldfe FR_T = [GR_ad_2]
+ fma.s1 FR_P54 = FR_P5,FR_r,FR_P4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P32 = FR_P3,FR_r,FR_P2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fcmp.le.s1 p6,p0 = FR_OvfBound,FR_NormX
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_InvX2 = FR_InvX,FR_InvX2,FR_InvX // NR iteration #2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_N = FR_int_N
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+ // jump if x is great than OVERFLOW_BOUNDARY
+(p6) br.cond.spnt lgamma_overflow
+};;
+.pred.rel "mutex",p9,p10
+{ .mfi
+ // store sign of gamma(x) as 32-bit int
+(p9) st4 [r33] = GR_SignOfGamma
+ fma.s1 FR_r3 = FR_r2,FR_r,f0
+ nop.i 0
+}
+{ .mfi
+ // store sign of gamma(x) as 64-bit int
+(p10) st8 [r33] = GR_SignOfGamma
+ fnma.s1 FR_P10 = FR_r2,FR_05,FR_r
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P54 = FR_P54,FR_r2,FR_P32
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_InvX = FR_InvX2,FR_NormX,f1 // NR iteration #3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_Xm05 = FR_NormX,f1,FR_05 // (x-1/2)
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_TpNxLn2 = FR_N,FR_Ln2,FR_T
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P54 = FR_P54,FR_r3,FR_P10
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_InvX = FR_InvX2,FR_InvX,FR_InvX2 // NR iteration #3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_LnSqrt2Pi = FR_LnSqrt2Pi,f1,FR_NormX // ln(sqrt(2*Pi))-x
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_LnX = FR_TpNxLn2,f1,FR_P54
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_InvX2 = FR_InvX,FR_InvX,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ // (x-1/2)*ln(x)+ln(sqrt(2*Pi))-x
+ fma.s1 FR_LnX = FR_LnX,FR_Xm05,FR_LnSqrt2Pi
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_W2 = FR_W4,FR_InvX2,FR_W2 // W2 + W4/x^2
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = FR_InvX,FR_W2,FR_LnX
+ br.ret.sptk b0
+};;
+// branch for calculating of ln(GAMMA(x)) for x < -512
+//---------------------------------------------------------------------
+.align 32
+lgamma_negstirling:
+{ .mfi
+ ldfpd FR_P5,FR_P4 = [GR_ad_1],16
+ fms.s1 FR_Xf = FR_NormX,f1,FR_N // xf = x - [x]
+ and GR_Exp = GR_SignExp,GR_ExpMask
+}
+{ .mfi
+ ldfpd FR_P3,FR_P2 = [GR_ad_2],16
+ fma.s1 FR_InvX = FR_C,FR_InvX,FR_C // NR iteration #1
+ mov GR_0x30033 = 0x30033
+};;
+{ .mfi
+ ldfe FR_Ln2 = [GR_ad_1],16
+ nop.f 0
+ extr.u GR_Ind = GR_ArgAsIs,44,8
+}
+{ .mib
+ ldfd FR_W4 = [GR_ad_2],16
+ // jump if x is less or equal to -2^52, i.e. x is big negative integer
+ cmp.leu.unc p7,p0 = GR_0x30033,GR_SignExp
+(p7) br.cond.spnt lgamma_singularity
+};;
+{ .mfi
+ ldfpd FR_S28,FR_S26 = [GR_ad_Co7],16
+ nop.f 0
+ add GR_ad_LnT = 0x50,GR_ad_2
+}
+{ .mfi
+ ldfpd FR_S24,FR_S22 = [GR_ad_Ce7],16
+ nop.f 0
+ mov GR_ExpBias = 0xffff
+};;
+{ .mfi
+ ldfpd FR_S20,FR_S18 = [GR_ad_Co7],16
+ nop.f 0
+ shladd GR_ad_T = GR_Ind,4,GR_ad_LnT
+}
+{ .mfi
+ ldfpd FR_S16,FR_S14 = [GR_ad_Ce7],16
+ nop.f 0
+ sub GR_Exp = GR_Exp,GR_ExpBias
+};;
+{ .mfi
+ ldfe FR_S12 = [GR_ad_Co7],16
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_S10 = [GR_ad_Ce7],16
+ fms.s1 FR_r = FR_C,f8,f1
+ nop.i 0
+};;
+{ .mmf
+ ldfe FR_S8 = [GR_ad_Co7],16
+ ldfe FR_S6 = [GR_ad_Ce7],16
+ nop.f 0
+};;
+{ .mfi
+ ldfe FR_S4 = [GR_ad_Co7],16
+ fma.s1 FR_Xf2 = FR_Xf,FR_Xf,f0
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_S2 = [GR_ad_Ce7],16
+ fnma.s1 FR_InvX2 = FR_InvX,FR_NormX,f1 // NR iteration #2
+ nop.i 0
+};;
+{ .mfi
+ setf.sig FR_int_N = GR_Exp
+ frcpa.s1 FR_InvXf,p9 = f1,FR_Xf // 1/xf
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_LnSqrt2Pi = [GR_ad_1],16
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ getf.exp GR_SignExp = FR_Xf
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_W2 = [GR_ad_2],16
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ getf.sig GR_Sig = FR_Xf
+ fma.s1 FR_P54 = FR_P5,FR_r,FR_P4
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_T = [GR_ad_T]
+ fma.s1 FR_P32 = FR_P3,FR_r,FR_P2
+ nop.i 0
+};;
+{ .mfi
+ and GR_Exp = GR_SignExp,GR_ExpMask
+ fma.s1 FR_r2 = FR_r,FR_r,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_Xm05 = FR_NormX,f1,FR_05 // (x-1/2)
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_InvX2 = FR_InvX,FR_InvX2,FR_InvX // NR iteration #2
+ extr.u GR_Ind = GR_Sig,55,8
+}
+{ .mfi
+ sub GR_Exp = GR_Exp,GR_ExpBias
+ fma.s1 FR_Xf4 = FR_Xf2,FR_Xf2,f0
+ cmp.eq p6,p0 = 0,GR_Sig
+};;
+{ .mfi
+ setf.sig FR_int_Nf = GR_Exp
+ fma.s1 FR_S28 = FR_S28,FR_Xf2,FR_S26
+ shladd GR_ad_T = GR_Ind,4,GR_ad_LnT
+}
+{ .mfb
+ nop.m 0
+ fma.s1 FR_S24 = FR_S24,FR_Xf2,FR_S22
+ // jump if the input argument is integer number from range (-512.0;-17.0]
+(p6) br.cond.spnt lgamma_singularity
+};;
+{ .mfi
+ getf.sig GR_Sig = FR_int_Ntrunc
+ fma.s1 FR_S20 = FR_S20,FR_Xf2,FR_S18
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S16 = FR_S16,FR_Xf2,FR_S14
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_Tf = [GR_ad_T]
+ fma.s1 FR_S12 = FR_S12,FR_Xf2,FR_S10
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S8 = FR_S8,FR_Xf2,FR_S6
+ mov GR_SignOfGamma = 1
+};;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_rf = FR_InvXf,FR_Xf,f1 // reduced arg rf
+ tbit.z p8,p0 = GR_Sig,0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r3 = FR_r2,FR_r,f0
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+};;
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_N = FR_int_N
+(p8) sub GR_SignOfGamma = r0,GR_SignOfGamma
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_InvX = FR_InvX2,FR_NormX,f1 // NR iteration #3
+ nop.i 0
+};;
+.pred.rel "mutex",p9,p10
+{ .mfi
+ // store sign of gamma(x) as 32-bit int
+(p9) st4 [r33] = GR_SignOfGamma
+ fma.s1 FR_P54 = FR_P54,FR_r2,FR_P32
+ nop.i 0
+}
+{ .mfi
+ // store sign of gamma(x) as 64-bit int
+(p10) st8 [r33] = GR_SignOfGamma
+ fnma.s1 FR_P10 = FR_r2,FR_05,FR_r
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Xf8 = FR_Xf4,FR_Xf4,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S28 = FR_S28,FR_Xf4,FR_S24
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S20 = FR_S20,FR_Xf4,FR_S16
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S12 = FR_S12,FR_Xf4,FR_S8
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rf2 = FR_rf,FR_rf,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P54f = FR_P5,FR_rf,FR_P4
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P32f = FR_P3,FR_rf,FR_P2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_InvX = FR_InvX2,FR_InvX,FR_InvX2 // NR iteration #3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_Nf = FR_int_Nf
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_LnSqrt2Pi = FR_NormX,f1,FR_LnSqrt2Pi // x+ln(sqrt(2*Pi))
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P54 = FR_P54,FR_r3,FR_P10
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S28 = FR_S28,FR_Xf8,FR_S20
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rf3 = FR_rf2,FR_rf,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_P10f = FR_rf2,FR_05,FR_rf
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_TpNxLn2 = FR_N,FR_Ln2,FR_T
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P54f = FR_P54f,FR_rf2,FR_P32f
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_InvX2 = FR_InvX,FR_InvX,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S28 = FR_S28,FR_Xf8,FR_S12
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S4 = FR_S4,FR_Xf2,FR_S2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P54f = FR_P54f,FR_rf3,FR_P10f
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_TpNxLn2f = FR_Nf,FR_Ln2,FR_Tf
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_LnX = FR_TpNxLn2,f1,FR_P54
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_W2 = FR_W4,FR_InvX2,FR_W2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S28 = FR_S28,FR_Xf4,FR_S4
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_LnXf = FR_TpNxLn2f,f1,FR_P54f
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_LnX = FR_LnX,FR_Xm05,FR_LnSqrt2Pi
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_LnX = FR_InvX,FR_W2,FR_LnX
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_LnX = FR_S28,FR_Xf2,FR_LnX
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ fms.d.s0 f8 = FR_LnX,f1,FR_LnXf
+ br.ret.sptk b0
+};;
+// branch for calculating of ln(GAMMA(x)) for 0 <= x < 1
+//---------------------------------------------------------------------
+.align 32
+lgamma_0_1:
+{ .mfi
+ ldfpd FR_P5,FR_P4 = [GR_ad_1],16
+ fms.s1 FR_x = FR_NormX,f1,f0 // x
+ mov GR_Arg025 = 0x3FD0
+}
+{ .mfi
+ ldfpd FR_P3,FR_P2 = [GR_ad_2],16
+ nop.f 0
+ add GR_ad_Co = 0x1C40,GR_ad_Data
+};;
+{ .mfi
+ ldfe FR_Ln2 = [GR_ad_1],0x50
+ nop.f 0
+ // p6 if arg < 0.25
+ cmp.lt p6,p9 = GR_Arg,GR_Arg025
+}
+{ .mfi
+ add GR_ad_2 = 0x40,GR_ad_2
+ nop.f 0
+ mov GR_Arg075 = 0x3FE8
+};;
+{ .mfi
+ ldfpd FR_Q8,FR_Q7 = [GR_ad_1],16
+ fma.s1 FR_w2 = FR_w,FR_w,f0
+ // p7 if 0.25 <= arg < 0.75
+ // p8 if 0.75 <= arg < 1.0
+(p9) cmp.lt.unc p7,p8 = GR_Arg,GR_Arg075
+}
+{ .mfi
+ mov GR_Arg0875 = 0x3FEC
+ nop.f 0
+ sub GR_Exp = GR_Exp,GR_ExpBias
+};;
+{ .mfi
+ ldfpd FR_Q6,FR_Q5 = [GR_ad_2],16
+ nop.f 0
+(p8) cmp.lt p9,p0 = GR_Arg,GR_Arg0875
+}
+{ .mfi
+ ldfpd FR_Q4,FR_Q3 = [GR_ad_1],16
+ nop.f 0
+ add GR_ad_Ce = 0x60,GR_ad_Co
+};;
+.pred.rel "mutex",p7,p8
+{ .mfi
+ ldfd FR_Q2 = [GR_ad_2],16
+ fms.s1 FR_r = FR_C,f8,f1
+(p7) mov GR_Offs = 0xC0
+}
+{ .mfi
+ setf.sig FR_int_N = GR_Exp
+ nop.f 0
+(p8) mov GR_Offs = 0x180
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+(p9) add GR_ad_Co = GR_Offs,GR_ad_Co
+(p8) fms.s1 FR_x = FR_NormX,f1,f1 // x-1
+ nop.i 0
+}
+{ .mfi
+(p9) add GR_ad_Ce = GR_Offs,GR_ad_Ce
+(p7) fms.s1 FR_x = FR_NormX,f1,FR_LocalMin // x-LocalMin
+ cmp.lt p10,p0 = GR_Arg,GR_Arg0875
+};;
+lgamma_common_0_2:
+{ .mfi
+ ldfpd FR_A17,FR_A16 = [GR_ad_Co],16
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd FR_A15,FR_A14 = [GR_ad_Ce],16
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ ldfpd FR_A13,FR_A12 = [GR_ad_Co],16
+ nop.f 0
+(p10) extr.u GR_Ind = GR_ArgAsIs,44,8
+}
+{ .mfi
+ ldfpd FR_A11,FR_A10 = [GR_ad_Ce],16
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ ldfpd FR_A9,FR_A8 = [GR_ad_Co],16
+(p10) fnma.s1 FR_Q1 = FR_05,FR_w2,FR_w
+ nop.i 0
+}
+{ .mfi
+ ldfpd FR_A7,FR_A6 = [GR_ad_Ce],16
+(p10) fma.s1 FR_w3 = FR_w2,FR_w,f0
+ nop.i 0
+};;
+{ .mfi
+(p10) getf.exp GR_SignExp_w = FR_w
+(p10) fma.s1 FR_w4 = FR_w2,FR_w2,f0
+ nop.i 0
+}
+{ .mfi
+(p10) shladd GR_ad_2 = GR_Ind,4,GR_ad_2
+(p10) fma.s1 FR_r2 = FR_r,FR_r,f0
+ nop.i 0
+};;
+{ .mfi
+(p10) ldfe FR_T = [GR_ad_2]
+(p10) fma.s1 FR_P54 = FR_P5,FR_r,FR_P4
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A5 = [GR_ad_Co],16
+(p10) fma.s1 FR_P32 = FR_P3,FR_r,FR_P2
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_A4 = [GR_ad_Ce],16
+ fma.s1 FR_x2 = FR_x,FR_x,f0
+(p10) and GR_Exp_w = GR_ExpMask, GR_SignExp_w
+}
+{ .mfi
+ ldfe FR_A3 = [GR_ad_Co],16
+ nop.f 0
+(p10) mov GR_fff9 = 0xfff9
+};;
+// p13 <== large w __libm_lgamma
+// p14 <== small w __libm_lgamma
+{ .mfi
+ ldfe FR_A2 = [GR_ad_Ce],16
+(p10) fma.s1 FR_Q8 = FR_Q8,FR_w,FR_Q7
+(p10) cmp.ge.unc p13,p14 = GR_Exp_w,GR_fff9
+}
+{ .mfi
+ ldfe FR_A1 = [GR_ad_Co],16
+(p10) fma.s1 FR_Q6 = FR_Q6,FR_w,FR_Q5
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_A0 = [GR_ad_Ce],16
+(p10) fma.s1 FR_Q4 = FR_Q4,FR_w,FR_Q3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_Q2 = FR_Q2,FR_w3,FR_Q1
+ nop.i 0
+};;
+{ .mfi
+ // set p11 if signgum is 32-bit int
+ // set p12 if signgum is 64-bit int
+ cmp.eq p12,p11 = 8,r34
+(p10) fma.s1 FR_r3 = FR_r2,FR_r,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fnma.s1 FR_P10 = FR_r2,FR_05,FR_r
+ mov GR_SignOfGamma = 1
+};;
+.pred.rel "mutex",p11,p12
+{ .mfi
+ // store sign of gamma(x) as 32-bit int
+(p11) st4 [r33] = GR_SignOfGamma
+ fma.s1 FR_A17 = FR_A17,FR_x,FR_A16
+ nop.i 0
+}
+{ .mfi
+ // store sign of gamma(x) as 64-bit int
+(p12) st8 [r33] = GR_SignOfGamma
+ fma.s1 FR_A15 = FR_A15,FR_x,FR_A14
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p10) fcvt.xf FR_N = FR_int_N
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_P54 = FR_P54,FR_r2,FR_P32
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A13 = FR_A13,FR_x,FR_A12
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A11 = FR_A11,FR_x,FR_A10
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A9 = FR_A9,FR_x,FR_A8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A7 = FR_A7,FR_x,FR_A6
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_Qlo = FR_Q8,FR_w2,FR_Q6
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_w6 = FR_w3,FR_w3,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_Qhi = FR_Q4,FR_w4,FR_Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A5 = FR_A5,FR_x,FR_A4
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_TpNxLn2 = FR_N,FR_Ln2,FR_T
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A3 = FR_A3,FR_x,FR_A2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_P54 = FR_P54,FR_r3,FR_P10
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A1 = FR_A1,FR_x,FR_A0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A17 = FR_A17,FR_x2,FR_A15
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A13 = FR_A13,FR_x2,FR_A11
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A9 = FR_A9,FR_x2,FR_A7
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_x4 = FR_x2,FR_x2,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_LnX = FR_Qlo,FR_w6,FR_Qhi
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A5 = FR_A5,FR_x2,FR_A3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_LnX = FR_TpNxLn2,f1,FR_P54
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A17 = FR_A17,FR_x4,FR_A13
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_x8 = FR_x4,FR_x4,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A9 = FR_A9,FR_x4,FR_A5
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A17 = FR_A17,FR_x8,FR_A9
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p10) fms.s1 FR_A1 = FR_A1,f1,FR_LnX
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = FR_A17,FR_x2,FR_A1
+ br.ret.sptk b0
+};;
+// branch for calculating of ln(GAMMA(x)) for 1.0 <= x < 2.25
+//---------------------------------------------------------------------
+.align 32
+lgamma_1_2:
+{ .mfi
+ add GR_ad_Co = 0x10B0,GR_ad_1
+ fcmp.eq.s1 p12,p0 = f1,FR_w
+ mov GR_Arg125 = 0x3FF4
+}
+{ .mfi
+ add GR_ad_Ce = 0x1110,GR_ad_1
+ nop.f 0
+ mov GR_Arg175 = 0x3FFC
+};;
+{ .mfi
+ mov GR_SignOfGamma = 1
+ fcmp.eq.s1 p13,p0 = f1,FR_NormX
+ cmp.lt p6,p9 = GR_Arg,GR_Arg125 // 1.0 <= x < 1.25
+}
+{ .mfi
+ // set p10 if signgum is 32-bit int
+ // set p11 if signgum is 64-bit int
+ cmp.eq p11,p10 = 8,r34
+ nop.f 0
+ cmp.ge p8,p0 = GR_Arg,GR_Arg175 // x >= 1.75
+};;
+.pred.rel "mutex",p10,p11
+{ .mfi
+ // store sign of gamma(x) as 32-bit int
+(p10) st4 [r33] = GR_SignOfGamma
+(p12) fma.d.s0 f8 = f0,f0,f0
+(p9) cmp.lt.unc p7,p0 = GR_Arg,GR_Arg175 // 1.25 <= x < 1.75
+}
+{ .mib
+ // store sign of gamma(x) as 64-bit int
+(p11) st8 [r33] = GR_SignOfGamma
+ mov GR_Offs = 0
+(p12) br.ret.spnt b0 // fast exit for 2.0
+};;
+.pred.rel "mutex",p7,p8
+{ .mfi
+(p7) mov GR_Offs = 0xC0
+(p7) fms.s1 FR_x = FR_w,f1,FR_LocalMin
+ nop.i 0
+}
+{ .mfb
+(p8) mov GR_Offs = 0x180
+(p13) fma.d.s0 f8 = f0,f0,f0
+(p13) br.ret.spnt b0 // fast exit for 1.0
+};;
+.pred.rel "mutex",p6,p8
+{ .mfi
+ add GR_ad_Co = GR_ad_Co,GR_Offs
+(p8) fms.s1 FR_x = FR_w,f1,f1
+ cmp.eq p0,p10 = r0,r0
+}
+{ .mfb
+ add GR_ad_Ce = GR_ad_Ce,GR_Offs
+(p6) fma.s1 FR_x = f0,f0,FR_w
+ br.cond.sptk lgamma_common_0_2
+};;
+// branch for calculating of ln(GAMMA(x)) for -17 < x < 0
+//---------------------------------------------------------------------
+.align 32
+lgamma_negrecursion:
+{ .mfi
+ getf.d GR_ArgXfrAsIs = FR_Xfr
+ fma.s1 FR_Xp2 = FR_2,f1,FR_NormX
+ mov GR_Arg05 = 0x3FE
+}
+{ .mfi
+ add GR_ad_Roots = 0x1390,GR_ad_1
+ fma.s1 FR_NormX = FR_NormX,FR_Xfr,f0
+ mov GR_Arg075 = 0x3FE8
+};;
+{ .mfi
+ getf.sig GR_Sig = FR_int_Ntrunc
+ fma.s1 FR_Xp3 = FR_2,f1,FR_Xp1
+ shl GR_Arg05 = GR_Arg05,52
+}
+{ .mfi
+ mov GR_Arg025 = 0x3FD0
+ fma.s1 FR_Xp6 = FR_5,f1,FR_Xp1
+ add GR_ad_Co = 0x1C40,GR_ad_Data
+};;
+{ .mfi
+ add GR_ad_Dx = 8,GR_ad_Roots
+ fma.s1 FR_Xp7 = FR_2,f1,FR_Xp5
+ shr.u GR_ArgXfr = GR_ArgXfrAsIs,48
+}
+{ .mfi
+ add GR_ad_Ce = 0x60,GR_ad_Co
+ fma.s1 FR_Xp8 = FR_3,f1,FR_Xp5
+ cmp.lt p6,p0 = GR_ArgXfrAsIs,GR_Arg05
+};;
+{ .mfi
+ and GR_RootInd = 0xF,GR_Sig
+ fma.s1 FR_Xp9 = FR_2,FR_2,FR_Xp5
+ // p10 if arg < 0.25
+ cmp.lt p10,p14 = GR_ArgXfr,GR_Arg025
+}
+{ .mfi
+(p6) add GR_ad_Roots = 0x120,GR_ad_Roots
+ fma.s1 FR_Xp11 = f1,f1,FR_Xp10
+(p6) add GR_ad_Dx = 0x120,GR_ad_Dx
+};;
+{ .mfi
+ shladd GR_ad_Root = GR_RootInd,4,GR_ad_Roots
+ fma.s1 FR_Xp12 = FR_2,f1,FR_Xp10
+ // p11 if 0.25 <= arg < 0.75
+ // p12 if 0.75 <= arg < 1.0
+(p14) cmp.lt.unc p11,p12 = GR_ArgXfr,GR_Arg075
+}
+{ .mfi
+ shladd GR_ad_Dx = GR_RootInd,4,GR_ad_Dx
+ fma.s1 FR_Xp13 = FR_3,f1,FR_Xp10
+ cmp.eq p0,p13 = 0,GR_Sig
+};;
+{ .mfi
+ ld8 GR_Root = [GR_ad_Root]
+ fma.s1 FR_Xp14 = FR_2,FR_2,FR_Xp10
+(p12) mov GR_Offs = 0x180
+}
+{ .mfi
+ ldfd FR_Root = [GR_ad_Root]
+ fma.s1 FR_Xp15 = FR_5,f1,FR_Xp10
+ and GR_Sig = 0xF,GR_Sig
+};;
+{ .mfi
+ ld8 GR_Dx = [GR_ad_Dx]
+ fma.s1 FR_Xp16 = FR_3,FR_2,FR_Xp10
+(p13) cmp.ge.unc p6,p0 = 0xD,GR_Sig
+}
+{ .mfi
+(p11) mov GR_Offs = 0xC0
+(p13) fma.s1 FR_NormX = FR_NormX,FR_Xp1,f0
+(p13) cmp.ge.unc p7,p0 = 0xB,GR_Sig
+};;
+{ .mfi
+(p14) add GR_ad_Co = GR_Offs,GR_ad_Co
+(p6) fma.s1 FR_Xp2 = FR_Xp2,FR_Xp3,f0
+(p13) cmp.ge.unc p8,p0 = 0x9,GR_Sig
+}
+{ .mfi
+(p14) add GR_ad_Ce = GR_Offs,GR_ad_Ce
+(p7) fma.s1 FR_Xp4 = FR_Xp4,FR_Xp5,f0
+(p13) cmp.ge.unc p9,p0 = 0x7,GR_Sig
+};;
+{ .mfi
+ ldfpd FR_B17,FR_B16 = [GR_ad_Co],16
+(p8) fma.s1 FR_Xp6 = FR_Xp6,FR_Xp7,f0
+(p13) cmp.ge.unc p6,p0 = 0x5,GR_Sig
+}
+{ .mfi
+ ldfpd FR_B15,FR_B14 = [GR_ad_Ce],16
+(p9) fma.s1 FR_Xp8 = FR_Xp8,FR_Xp9,f0
+(p13) cmp.ge.unc p7,p0 = 0x3,GR_Sig
+};;
+{ .mfi
+ ldfpd FR_B13,FR_B12 = [GR_ad_Co],16
+(p6) fma.s1 FR_Xp10 = FR_Xp10,FR_Xp11,f0
+(p13) cmp.ge.unc p8,p0 = 0x1,GR_Sig
+}
+{ .mfi
+ ldfpd FR_B11,FR_B10 = [GR_ad_Ce],16
+(p7) fma.s1 FR_Xp12 = FR_Xp12,FR_Xp13,f0
+(p13) cmp.eq.unc p9,p0 = 0,GR_Sig
+};;
+{ .mfi
+ ldfpd FR_B9,FR_B8 = [GR_ad_Co],16
+(p8) fma.s1 FR_Xp14 = FR_Xp14,FR_Xp15,f0
+ mov GR_Arg15 = 0xC02E // -15
+}
+{ .mfi
+ ldfpd FR_B7,FR_B6 = [GR_ad_Ce],16
+ fcmp.eq.s1 p15,p0 = f0,FR_Xf
+(p13) cmp.ge.unc p6,p0 = 0xC,GR_Sig
+};;
+{ .mfi
+ ldfe FR_B5 = [GR_ad_Co],16
+(p9) fma.s1 FR_NormX = FR_NormX,FR_Xp16,f0
+ sub GR_Root = GR_ArgAsIs,GR_Root
+}
+{ .mfi
+ sub GR_RootInd = 0xE,GR_RootInd
+(p11) fms.s1 FR_x = FR_Xfr,f1,FR_LocalMin // x-LocalMin
+(p13) cmp.ge.unc p7,p0 = 0x8,GR_Sig
+};;
+.pred.rel "mutex",p10,p12
+{ .mfi
+ ldfe FR_B4 = [GR_ad_Ce],16
+(p10) fms.s1 FR_x = FR_Xfr,f1,f0 // x
+ add GR_Root = GR_Root,GR_Dx
+}
+{ .mfb
+ cmp.gtu p14,p0 = 0xE,GR_RootInd
+(p12) fms.s1 FR_x = FR_Xfr,f1,f1 // x-1
+(p15) br.cond.spnt lgamma_singularity
+};;
+{ .mfi
+ ldfe FR_B3 = [GR_ad_Co],16
+(p6) fma.s1 FR_Xp2 = FR_Xp2,FR_Xp4,f0
+(p14) cmp.lt.unc p11,p0 = GR_Arg,GR_Arg15
+}
+{ .mfi
+ ldfe FR_B2 = [GR_ad_Ce],16
+(p7) fma.s1 FR_Xp6 = FR_Xp6,FR_Xp8,f0
+ add GR_2xDx = GR_Dx,GR_Dx
+};;
+{ .mfi
+ ldfe FR_B1 = [GR_ad_Co],16
+ fms.s1 FR_r = f8,f1,FR_Root
+(p13) cmp.ge.unc p6,p0 = 0x4,GR_Sig
+}
+{ .mib
+ ldfe FR_B0 = [GR_ad_Ce],16
+(p11) cmp.leu.unc p10,p0 = GR_Root,GR_2xDx
+(p10) br.cond.spnt lgamma_negroots
+};;
+{ .mfi
+ ldfpd FR_P5,FR_P4 = [GR_ad_1],16
+(p6) fma.s1 FR_Xp10 = FR_Xp10,FR_Xp12,f0
+ tbit.z p14,p15 = GR_Sig,0
+}
+{ .mfi
+ ldfpd FR_P3,FR_P2 = [GR_ad_2],16
+ fnma.d.s0 FR_T = f1,f1,f8 // nop.f 0
+
+(p13) cmp.ge.unc p7,p0 = 0x2,GR_Sig
+};;
+{ .mfi
+ ldfe FR_Ln2 = [GR_ad_1],0x50
+(p7) fma.s1 FR_NormX = FR_NormX,FR_Xp14,f0
+ mov GR_PseudoRoot = 0xBFFBC
+}
+{ .mlx
+ add GR_ad_2 = 0x40,GR_ad_2
+ movl GR_2xDx = 0x00002346DC5D6389
+};;
+{ .mfi
+ ldfpd FR_Q8,FR_Q7 = [GR_ad_1],16
+ fma.s1 FR_x2 = FR_x,FR_x,f0
+ shl GR_PseudoRoot = GR_PseudoRoot,44
+}
+{ .mfi
+ ldfpd FR_Q6,FR_Q5 = [GR_ad_2],16
+ fma.s1 FR_B17 = FR_B17,FR_x,FR_B16
+(p13) cmp.ge.unc p6,p0 = 0xA,GR_Sig
+};;
+{ .mfi
+ ldfpd FR_Q4,FR_Q3 = [GR_ad_1],16
+(p6) fma.s1 FR_Xp2 = FR_Xp2,FR_Xp6,f0
+ sub GR_PseudoRoot = GR_ArgAsIs,GR_PseudoRoot
+}
+{ .mfi
+ ldfpd FR_Q2,FR_Q1 = [GR_ad_2],16
+ fma.s1 FR_B15 = FR_B15,FR_x,FR_B14
+(p13) cmp.ge.unc p7,p0 = 0x6,GR_Sig
+};;
+{ .mfi
+ add GR_ad_Co = 0x12F0,GR_ad_2
+ fma.s1 FR_B13 = FR_B13,FR_x,FR_B12
+ cmp.leu.unc p10,p0 = GR_PseudoRoot,GR_2xDx
+}
+{ .mfi
+ add GR_ad_Ce = 0x1300,GR_ad_2
+ fma.s1 FR_B11 = FR_B11,FR_x,FR_B10
+ mov GR_ExpMask = 0x1ffff
+};;
+{ .mfi
+(p10) ldfe FR_PR01 = [GR_ad_Co],0xF0
+ fma.s1 FR_B9 = FR_B9,FR_x,FR_B8
+ mov GR_ExpBias = 0xFFFF
+}
+{ .mfb
+(p10) ldfe FR_PR11 = [GR_ad_Ce],0xF0
+ fma.s1 FR_B7 = FR_B7,FR_x,FR_B6
+(p10) br.cond.spnt lgamma_pseudoroot
+};;
+{ .mfi
+(p13) cmp.ge.unc p6,p0 = 0xE,GR_Sig
+(p7) fma.s1 FR_NormX = FR_NormX,FR_Xp10,f0
+ tbit.z.unc p8,p0 = GR_Sig,0
+}
+{ .mfi
+ mov GR_SignOfGamma = 1
+ fma.s1 FR_B5 = FR_B5,FR_x,FR_B4
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_B3 = FR_B3,FR_x,FR_B2
+(p8) sub GR_SignOfGamma = r0,GR_SignOfGamma
+}
+{ .mfi
+ nop.m 0
+(p14) fms.s1 FR_w = f0,f0,f1
+ nop.i 0
+};;
+.pred.rel "mutex",p9,p10
+{ .mfi
+ // store sign of gamma(x) as 32-bit int
+(p9) st4 [r33] = GR_SignOfGamma
+ fma.s1 FR_B1 = FR_B1,FR_x,FR_B0
+ nop.i 0
+}
+{ .mfi
+ // store sign of gamma(x) as 64-bit int
+(p10) st8 [r33] = GR_SignOfGamma
+ fma.s1 FR_B17 = FR_B17,FR_x2,FR_B15
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_B13 = FR_B13,FR_x2,FR_B11
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_B9 = FR_B9,FR_x2,FR_B7
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_x4 = FR_x2,FR_x2,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p6) fma.s1 FR_NormX = FR_NormX,FR_Xp2,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_B5 = FR_B5,FR_x2,FR_B3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_B17 = FR_B17,FR_x4,FR_B13
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_x8 = FR_x4,FR_x4,f0
+ nop.i 0
+};;
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p15) fms.s1 FR_w = FR_NormX,f1,f1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p14) fnma.s1 FR_w = FR_NormX,f1,FR_w
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_B9 = FR_B9,FR_x4,FR_B5
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ frcpa.s1 FR_C,p0 = f1,FR_NormX
+ nop.i 0
+};;
+{ .mfi
+ getf.exp GR_Exp = FR_NormX
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ getf.d GR_ArgAsIs = FR_NormX
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_w2 = FR_w,FR_w,f0
+ nop.i 0
+}
+{ .mfi
+ and GR_Exp = GR_Exp,GR_ExpMask
+ fma.s1 FR_Q8 = FR_Q8,FR_w,FR_Q7
+ nop.i 0
+};;
+{ .mfi
+ sub GR_Exp = GR_Exp,GR_ExpBias
+ fma.s1 FR_B17 = FR_B17,FR_x8,FR_B9
+ extr.u GR_Ind = GR_ArgAsIs,44,8
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Q6 = FR_Q6,FR_w,FR_Q5
+ nop.i 0
+};;
+{ .mfi
+ setf.sig FR_int_N = GR_Exp
+ fms.s1 FR_r = FR_C,FR_NormX,f1
+ nop.i 0
+}
+{ .mfi
+ shladd GR_ad_2 = GR_Ind,4,GR_ad_2
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ getf.exp GR_SignExp_w = FR_w
+ fma.s1 FR_Q4 = FR_Q4,FR_w,FR_Q3
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_T = [GR_ad_2]
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ and GR_Exp_w = GR_ExpMask, GR_SignExp_w
+ fnma.s1 FR_Q1 = FR_05,FR_w2,FR_w
+ mov GR_fff9 = 0xfff9
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_w3 = FR_w2,FR_w,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_w4 = FR_w2,FR_w2,f0
+// p13 <== large w __libm_lgamma
+// p14 <== small w __libm_lgamma
+ cmp.ge p13,p14 = GR_Exp_w,GR_fff9
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Qlo = FR_Q8,FR_w2,FR_Q6
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_r2 = FR_r,FR_r,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_B17 = FR_B17,FR_x2,FR_B1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_P32 = FR_P3,FR_r,FR_P2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_P54 = FR_P5,FR_r,FR_P4
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_Q2 = FR_Q2,FR_w3,FR_Q1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_w6 = FR_w3,FR_w3,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fcvt.xf FR_N = FR_int_N
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_r3 = FR_r2,FR_r,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fnma.s1 FR_P10 = FR_r2,FR_05,FR_r
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_P54 = FR_P54,FR_r2,FR_P32
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_Qhi = FR_Q4,FR_w4,FR_Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p14) fnma.s1 FR_Qlo = FR_Qlo,FR_w6,FR_B17
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_TpNxLn2 = FR_N,FR_Ln2,FR_T
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_P54 = FR_P54,FR_r3,FR_P10
+ nop.i 0
+};;
+.pred.rel "mutex",p13,p14
+{ .mfi
+ nop.m 0
+(p14) fms.d.s0 f8 = FR_Qlo,f1,FR_Qhi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_LnX = FR_TpNxLn2,f1,FR_P54
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+(p13) fms.d.s0 f8 = FR_B17,f1,FR_LnX
+ br.ret.sptk b0
+};;
+// branch for calculating of ln(GAMMA(x)) near negative roots
+//---------------------------------------------------------------------
+.align 32
+lgamma_negroots:
+{ .mfi
+ shladd GR_Offs = GR_RootInd,3,r0 //GR_RootInd*8
+ fma.s1 FR_r2 = FR_r,FR_r,f0
+ add GR_ad_Co = 0x15C0,GR_ad_1//0x1590,GR_ad_1
+}
+{ .mfi
+ add GR_ad_Ce = 0x1610,GR_ad_1//0x15E0,GR_ad_1
+ nop.f 0
+ cmp.lt p6,p0 = GR_ArgXfrAsIs,GR_Arg05
+};;
+{ .mfi
+ add GR_ad_Roots = 0x10A0,GR_ad_1
+ nop.f 0
+(p6) add GR_ad_Co = 0x820,GR_ad_Co
+}
+{ .mfi
+(p6) add GR_ad_Ce = 0x820,GR_ad_Ce
+ nop.f 0
+ shladd GR_Offs = GR_RootInd,1,GR_Offs //GR_RootInd*10
+};;
+{ .mmi
+ shladd GR_ad_Co = GR_Offs,4,GR_ad_Co
+ shladd GR_ad_Ce = GR_Offs,4,GR_ad_Ce
+ cmp.eq p8,p7 = r0,r0
+};;
+{ .mmi
+ ldfpd FR_A15,FR_A14 = [GR_ad_Co],16
+ ldfpd FR_A13,FR_A12 = [GR_ad_Ce],16
+ mov GR_SignOfGamma = 1
+};;
+{ .mmi
+ ldfpd FR_A11,FR_A10 = [GR_ad_Co],16
+ ldfpd FR_A9,FR_A8 = [GR_ad_Ce],16
+(p6) cmp.eq p7,p8 = r0,GR_RootInd
+};;
+{ .mmi
+ ldfpd FR_A7,FR_A6 = [GR_ad_Co],16
+ ldfpd FR_A5,FR_A4 = [GR_ad_Ce],16
+ tbit.z p11,p0 = GR_Sig,0
+};;
+{ .mmi
+ ldfe FR_A3 = [GR_ad_Co],16
+ ldfe FR_A2 = [GR_ad_Ce],16
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+};;
+{ .mmi
+ ldfe FR_A1 = [GR_ad_Co],16
+ ldfe FR_A0 = [GR_ad_Ce],16
+(p11) sub GR_SignOfGamma = r0,GR_SignOfGamma
+};;
+{ .mfi
+ ldfe FR_A00 = [GR_ad_Roots]
+ fma.s1 FR_r4 = FR_r2,FR_r2,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A15 = FR_A15,FR_r,FR_A14
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A13 = FR_A13,FR_r,FR_A12
+ nop.i 0
+};;
+.pred.rel "mutex",p9,p10
+{ .mfi
+ // store sign of gamma(x) as 32-bit int
+(p9) st4 [r33] = GR_SignOfGamma
+ fma.s1 FR_A11 = FR_A11,FR_r,FR_A10
+ nop.i 0
+}
+{ .mfi
+ // store sign of gamma(x) as 64-bit int
+(p10) st8 [r33] = GR_SignOfGamma
+ fma.s1 FR_A9 = FR_A9,FR_r,FR_A8
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A7 = FR_A7,FR_r,FR_A6
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A5 = FR_A5,FR_r,FR_A4
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A3 = FR_A3,FR_r,FR_A2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r8 = FR_r4,FR_r4,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A1 = FR_A1,FR_r,FR_A0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A15 = FR_A15,FR_r2,FR_A13
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A11 = FR_A11,FR_r2,FR_A9
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A7 = FR_A7,FR_r2,FR_A5
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A3 = FR_A3,FR_r2,FR_A1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A15 = FR_A15,FR_r4,FR_A11
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A7 = FR_A7,FR_r4,FR_A3
+ nop.i 0
+};;
+.pred.rel "mutex",p7,p8
+{ .mfi
+ nop.m 0
+(p7) fma.s1 FR_A1 = FR_A15,FR_r8,FR_A7
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.d.s0 f8 = FR_A15,FR_r8,FR_A7
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+(p7) fma.d.s0 f8 = FR_A1,FR_r,FR_A00
+ br.ret.sptk b0
+};;
+// branch for handling pseudo root on (-2;-1)
+//---------------------------------------------------------------------
+.align 32
+lgamma_pseudoroot:
+{ .mmi
+ ldfe FR_PR21 = [GR_ad_Co],32
+ ldfe FR_PR31 = [GR_ad_Ce],32
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+};;
+{ .mmi
+ ldfe FR_PR00 = [GR_ad_Co],32
+ ldfe FR_PR10 = [GR_ad_Ce],0xF0
+ mov GR_SignOfGamma = 1
+};;
+{ .mmi
+ ldfe FR_PR20 = [GR_ad_Co],0xF0
+ ldfe FR_PR30 = [GR_ad_Ce]
+ tbit.z p8,p0 = GR_Sig,0
+};;
+{ .mfi
+ ldfe FR_PRN = [GR_ad_Co]
+ fma.s1 FR_PR01 = f8,f1,FR_PR01
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PR11 = f8,f1,FR_PR11
+(p8) sub GR_SignOfGamma = r0,GR_SignOfGamma
+};;
+.pred.rel "mutex",p9,p10
+{ .mfi
+ // store sign of gamma(x) as 32-bit int
+(p9) st4 [r33] = GR_SignOfGamma
+ fma.s1 FR_PR21 = f8,f1,FR_PR21
+ nop.i 0
+}
+{ .mfi
+ // store sign of gamma(x) as 64-bit int
+(p10) st8 [r33] = GR_SignOfGamma
+ fma.s1 FR_PR31 = f8,f1,FR_PR31
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PR01 = f8,FR_PR01,FR_PR00
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PR11 = f8,FR_PR11,FR_PR10
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PR21 = f8,FR_PR21,FR_PR20
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PR31 = f8,FR_PR31,FR_PR30
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PR01 = FR_PR11,FR_PR01,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PR21 = FR_PR31,FR_PR21,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_PR01 = FR_PR21,FR_PR01,f0
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = FR_PR01,FR_PRN,f0
+ br.ret.sptk b0
+};;
+// branch for handling +/-0, NaT, QNaN, +/-INF and denormalised numbers
+//---------------------------------------------------------------------
+.align 32
+lgamma_spec:
+{ .mfi
+ getf.exp GR_SignExp = FR_NormX
+ fclass.m p6,p0 = f8,0x21 // is arg +INF?
+ mov GR_SignOfGamma = 1
+};;
+{ .mfi
+ getf.sig GR_ArgAsIs = FR_NormX
+ fclass.m p7,p0 = f8,0xB // is x deno?
+ // set p11 if signgum is 32-bit int
+ // set p12 if signgum is 64-bit int
+ cmp.eq p12,p11 = 8,r34
+};;
+.pred.rel "mutex",p11,p12
+{ .mfi
+ // store sign of gamma(x) as 32-bit int
+(p11) st4 [r33] = GR_SignOfGamma
+ fclass.m p8,p0 = f8,0x1C0 // is arg NaT or NaN?
+ dep.z GR_Ind = GR_SignExp,8,4
+}
+{ .mib
+ // store sign of gamma(x) as 64-bit int
+(p12) st8 [r33] = GR_SignOfGamma
+ cmp.lt p10,p0 = GR_SignExp,GR_ExpBias
+(p6) br.ret.spnt b0 // exit for +INF
+};;
+{ .mfi
+ and GR_Exp = GR_SignExp,GR_ExpMask
+ fclass.m p9,p0 = f8,0x22 // is arg -INF?
+ nop.i 0
+};;
+{ .mfi
+ add GR_ad_Co = GR_Ind,GR_ad_Data
+(p7) fma.s0 FR_tmp = f8,f8,f8
+ extr.u GR_ArgAsIs = GR_ArgAsIs,11,52
+}
+{ .mfb
+ nop.m 0
+(p8) fms.d.s0 f8 = f8,f1,f8
+(p8) br.ret.spnt b0 // exit for NaT and NaN
+};;
+{ .mib
+ nop.m 0
+ shr.u GR_Arg = GR_ArgAsIs,48
+(p7) br.cond.sptk lgamma_common
+};;
+{ .mfb
+ nop.m 0
+(p9) fmerge.s f8 = f1,f8
+(p9) br.ret.spnt b0 // exit -INF
+};;
+// branch for handling negative integers and +/-0
+//---------------------------------------------------------------------
+.align 32
+lgamma_singularity:
+{ .mfi
+ mov GR_ad_SignGam = r33
+ fclass.m p6,p0 = f8, 0x6 // is x -0?
+ mov GR_SignOfGamma = 1
+}
+{ .mfi
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+ fma.s1 FR_X = f0,f0,f8
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ frcpa.s0 f8,p0 = f1,f0
+ mov GR_TAG = 106 // negative
+}
+{ .mib
+ nop.m 0
+(p6) sub GR_SignOfGamma = r0,GR_SignOfGamma
+ br.cond.sptk lgamma_libm_err
+};;
+// overflow (x > OVERFLOV_BOUNDARY)
+//---------------------------------------------------------------------
+.align 32
+lgamma_overflow:
+{ .mfi
+ mov GR_SignOfGamma = 1
+ nop.f 0
+ mov r8 = 0x1FFFE
+};;
+{ .mfi
+ setf.exp f9 = r8
+ fmerge.s FR_X = f8,f8
+ mov GR_TAG = 105 // overflow
+};;
+{ .mfi
+ mov GR_ad_SignGam = r33
+ nop.f 0
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+}
+{ .mfi
+ nop.m 0
+ fma.d.s0 f8 = f9,f9,f0 // Set I,O and +INF result
+ nop.i 0
+};;
+//
+//---------------------------------------------------------------------
+.align 32
+lgamma_libm_err:
+{ .mmi
+ alloc r32 = ar.pfs,1,4,4,0
+ mov GR_Parameter_TAG = GR_TAG
+ nop.i 0
+};;
+.pred.rel "mutex",p9,p10
+{ .mmi
+ // store sign of gamma(x) as 32-bit int
+(p9) st4 [GR_ad_SignGam] = GR_SignOfGamma
+ // store sign of gamma(x) as 64-bit int
+(p10) st8 [GR_ad_SignGam] = GR_SignOfGamma
+ nop.i 0
+};;
+GLOBAL_LIBM_END(__libm_lgamma)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // STORE Parameter 1
+ // on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3
+ // on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling
+ // function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/libm_lgammaf.S b/libc/sysdeps/ia64/fpu/libm_lgammaf.S
new file mode 100644
index 000000000..4bd92c3b2
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_lgammaf.S
@@ -0,0 +1,2199 @@
+.file "libm_lgammaf.s"
+
+
+// Copyright (c) 2002 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING,BUT NOT
+// LIMITED TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code,and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 01/10/02 Initial version
+// 01/25/02 Corrected parameter store, load, and tag for __libm_error_support
+// 02/01/02 Added support of SIGN(GAMMA(x)) calculation
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 09/16/02 Improved accuracy on intervals reduced to [1;1.25]
+// 10/21/02 Now it returns SIGN(GAMMA(x))=-1 for negative zero
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 07/22/03 Reformatted some data tables
+// 03/31/05 Reformatted delimiters between data tables
+//
+//*********************************************************************
+//
+//*********************************************************************
+//
+// Function: __libm_lgammaf(float x, int* signgam, int szsigngam)
+// computes the principle value of the logarithm of the GAMMA function
+// of x. Signum of GAMMA(x) is stored to memory starting at the address
+// specified by the signgam.
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f6-f15
+// f32-f97
+//
+// General Purpose Registers:
+// r8-r11
+// r14-r30
+// r32-r36
+// r37-r40 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6-p15
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// lgamma(+inf) = +inf
+// lgamma(-inf) = +inf
+// lgamma(+/-0) = +inf
+// lgamma(x<0, x - integer) = +inf
+// lgamma(SNaN) = QNaN
+// lgamma(QNaN) = QNaN
+//
+//*********************************************************************
+//
+// Overview
+//
+// The method consists of three cases.
+//
+// If 2^13 <= x < OVERFLOW_BOUNDARY use case lgammaf_pstirling;
+// else if 1 < x < 2^13 use case lgammaf_regular;
+// else if -9 < x < 1 use case lgammaf_negrecursion;
+// else if -2^13 < x < -9 use case lgammaf_negpoly;
+// else if x < -2^13 use case lgammaf_negstirling;
+// else if x is close to negative
+// roots of ln(GAMMA(x)) use case lgammaf_negroots;
+//
+//
+// Case 2^13 <= x < OVERFLOW_BOUNDARY
+// ----------------------------------
+// Here we use algorithm based on the Stirling formula:
+// ln(GAMMA(x)) = ln(sqrt(2*Pi)) + (x-0.5)*ln(x) - x
+//
+// Case 1 < x < 2^13
+// -----------------
+// To calculate ln(GAMMA(x)) for such arguments we use polynomial
+// approximation on following intervals: [1.0; 1.25), [1.25; 1.5),
+// [1.5, 1.75), [1.75; 2), [2; 4), [2^i; 2^(i+1)), i=1..8
+//
+// Following variants of approximation and argument reduction are used:
+// 1. [1.0; 1.25)
+// ln(GAMMA(x)) ~ (x-1.0)*P7(x)
+//
+// 2. [1.25; 1.5)
+// ln(GAMMA(x)) ~ ln(GAMMA(x0))+(x-x0)*P8(x-x0),
+// where x0 - point of local minimum on [1;2] rounded to nearest double
+// precision number.
+//
+// 3. [1.5; 1.75)
+// ln(GAMMA(x)) ~ P8(x)
+//
+// 4. [1.75; 2.0)
+// ln(GAMMA(x)) ~ (x-2)*P7(x)
+//
+// 5. [2; 4)
+// ln(GAMMA(x)) ~ (x-2)*P10(x)
+//
+// 6. [2^i; 2^(i+1)), i=2..8
+// ln(GAMMA(x)) ~ P10((x-2^i)/2^i)
+//
+// Case -9 < x < 1
+// ---------------
+// Here we use the recursive formula:
+// ln(GAMMA(x)) = ln(GAMMA(x+1)) - ln(x)
+//
+// Using this formula we reduce argument to base interval [1.0; 2.0]
+//
+// Case -2^13 < x < -9
+// --------------------
+// Here we use the formula:
+// ln(GAMMA(x)) = ln(Pi/(|x|*GAMMA(|x|)*sin(Pi*|x|))) =
+// = -ln(|x|) - ln((GAMMA(|x|)) - ln(sin(Pi*r)/(Pi*r)) - ln(|r|)
+// where r = x - rounded_to_nearest(x), i.e |r| <= 0.5 and
+// ln(sin(Pi*r)/(Pi*r)) is approximated by 8-degree polynomial of r^2
+//
+// Case x < -2^13
+// --------------
+// Here we use algorithm based on the Stirling formula:
+// ln(GAMMA(x)) = -ln(sqrt(2*Pi)) + (|x|-0.5)ln(x) - |x| -
+// - ln(sin(Pi*r)/(Pi*r)) - ln(|r|)
+// where r = x - rounded_to_nearest(x).
+//
+// Neighbourhoods of negative roots
+// --------------------------------
+// Here we use polynomial approximation
+// ln(GAMMA(x-x0)) = ln(GAMMA(x0)) + (x-x0)*P14(x-x0),
+// where x0 is a root of ln(GAMMA(x)) rounded to nearest double
+// precision number.
+//
+//
+// Claculation of logarithm
+// ------------------------
+// Consider x = 2^N * xf so
+// ln(x) = ln(frcpa(x)*x/frcpa(x))
+// = ln(1/frcpa(x)) + ln(frcpa(x)*x)
+//
+// frcpa(x) = 2^(-N) * frcpa(xf)
+//
+// ln(1/frcpa(x)) = -ln(2^(-N)) - ln(frcpa(xf))
+// = N*ln(2) - ln(frcpa(xf))
+// = N*ln(2) + ln(1/frcpa(xf))
+//
+// ln(x) = ln(1/frcpa(x)) + ln(frcpa(x)*x) =
+// = N*ln(2) + ln(1/frcpa(xf)) + ln(frcpa(x)*x)
+// = N*ln(2) + T + ln(frcpa(x)*x)
+//
+// Let r = 1 - frcpa(x)*x, note that r is quite small by
+// absolute value so
+//
+// ln(x) = N*ln(2) + T + ln(1+r) ~ N*ln(2) + T + Series(r),
+// where T - is precomputed tabular value,
+// Series(r) = (P3*r + P2)*r^2 + (P1*r + 1)
+//
+//*********************************************************************
+
+GR_TAG = r8
+GR_ad_Data = r8
+GR_ad_Co = r9
+GR_ad_SignGam = r10
+GR_ad_Ce = r10
+GR_SignExp = r11
+
+GR_ad_C650 = r14
+GR_ad_RootCo = r14
+GR_ad_C0 = r15
+GR_Dx = r15
+GR_Ind = r16
+GR_Offs = r17
+GR_IntNum = r17
+GR_ExpBias = r18
+GR_ExpMask = r19
+GR_Ind4T = r20
+GR_RootInd = r20
+GR_Sig = r21
+GR_Exp = r22
+GR_PureExp = r23
+GR_ad_C43 = r24
+GR_StirlBound = r25
+GR_ad_T = r25
+GR_IndX8 = r25
+GR_Neg2 = r25
+GR_2xDx = r25
+GR_SingBound = r26
+GR_IndX2 = r26
+GR_Neg4 = r26
+GR_ad_RootCe = r26
+GR_Arg = r27
+GR_ExpOf2 = r28
+GR_fff7 = r28
+GR_Root = r28
+GR_ReqBound = r28
+GR_N = r29
+GR_ad_Root = r30
+GR_ad_OvfBound = r30
+GR_SignOfGamma = r31
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+//*********************************************************************
+
+FR_X = f10
+FR_Y = f1 // lgammaf is single argument function
+FR_RESULT = f8
+
+FR_x = f6
+FR_x2 = f7
+
+FR_x3 = f9
+FR_x4 = f10
+FR_xm2 = f11
+FR_w = f11
+FR_w2 = f12
+FR_Q32 = f13
+FR_Q10 = f14
+FR_InvX = f15
+
+FR_NormX = f32
+
+FR_A0 = f33
+FR_A1 = f34
+FR_A2 = f35
+FR_A3 = f36
+FR_A4 = f37
+FR_A5 = f38
+FR_A6 = f39
+FR_A7 = f40
+FR_A8 = f41
+FR_A9 = f42
+FR_A10 = f43
+
+FR_int_N = f44
+FR_P3 = f45
+FR_P2 = f46
+FR_P1 = f47
+FR_LocalMin = f48
+FR_Ln2 = f49
+FR_05 = f50
+FR_LnSqrt2Pi = f51
+FR_3 = f52
+FR_r = f53
+FR_r2 = f54
+FR_T = f55
+FR_N = f56
+FR_xm05 = f57
+FR_int_Ln = f58
+FR_P32 = f59
+FR_P10 = f60
+
+FR_Xf = f61
+FR_InvXf = f62
+FR_rf = f63
+FR_rf2 = f64
+FR_Tf = f65
+FR_Nf = f66
+FR_xm05f = f67
+FR_P32f = f68
+FR_P10f = f69
+FR_Lnf = f70
+FR_Xf2 = f71
+FR_Xf4 = f72
+FR_Xf8 = f73
+FR_Ln = f74
+FR_xx = f75
+FR_Root = f75
+FR_Req = f76
+FR_1pXf = f77
+
+FR_S16 = f78
+FR_R3 = f78
+FR_S14 = f79
+FR_R2 = f79
+FR_S12 = f80
+FR_R1 = f80
+FR_S10 = f81
+FR_R0 = f81
+FR_S8 = f82
+FR_rx = f82
+FR_S6 = f83
+FR_rx2 = f84
+FR_S4 = f84
+FR_S2 = f85
+
+FR_Xp1 = f86
+FR_Xp2 = f87
+FR_Xp3 = f88
+FR_Xp4 = f89
+FR_Xp5 = f90
+FR_Xp6 = f91
+FR_Xp7 = f92
+FR_Xp8 = f93
+FR_OverflowBound = f93
+
+FR_2 = f94
+FR_tmp = f95
+FR_int_Ntrunc = f96
+FR_Ntrunc = f97
+
+//*********************************************************************
+
+RODATA
+.align 32
+LOCAL_OBJECT_START(lgammaf_data)
+log_table_1:
+data8 0xbfd0001008f39d59 // P3
+data8 0x3fd5556073e0c45a // P2
+data8 0x3fe62e42fefa39ef // ln(2)
+data8 0x3fe0000000000000 // 0.5
+//
+data8 0x3F60040155D5889E //ln(1/frcpa(1+ 0/256)
+data8 0x3F78121214586B54 //ln(1/frcpa(1+ 1/256)
+data8 0x3F841929F96832F0 //ln(1/frcpa(1+ 2/256)
+data8 0x3F8C317384C75F06 //ln(1/frcpa(1+ 3/256)
+data8 0x3F91A6B91AC73386 //ln(1/frcpa(1+ 4/256)
+data8 0x3F95BA9A5D9AC039 //ln(1/frcpa(1+ 5/256)
+data8 0x3F99D2A8074325F4 //ln(1/frcpa(1+ 6/256)
+data8 0x3F9D6B2725979802 //ln(1/frcpa(1+ 7/256)
+data8 0x3FA0C58FA19DFAAA //ln(1/frcpa(1+ 8/256)
+data8 0x3FA2954C78CBCE1B //ln(1/frcpa(1+ 9/256)
+data8 0x3FA4A94D2DA96C56 //ln(1/frcpa(1+ 10/256)
+data8 0x3FA67C94F2D4BB58 //ln(1/frcpa(1+ 11/256)
+data8 0x3FA85188B630F068 //ln(1/frcpa(1+ 12/256)
+data8 0x3FAA6B8ABE73AF4C //ln(1/frcpa(1+ 13/256)
+data8 0x3FAC441E06F72A9E //ln(1/frcpa(1+ 14/256)
+data8 0x3FAE1E6713606D07 //ln(1/frcpa(1+ 15/256)
+data8 0x3FAFFA6911AB9301 //ln(1/frcpa(1+ 16/256)
+data8 0x3FB0EC139C5DA601 //ln(1/frcpa(1+ 17/256)
+data8 0x3FB1DBD2643D190B //ln(1/frcpa(1+ 18/256)
+data8 0x3FB2CC7284FE5F1C //ln(1/frcpa(1+ 19/256)
+data8 0x3FB3BDF5A7D1EE64 //ln(1/frcpa(1+ 20/256)
+data8 0x3FB4B05D7AA012E0 //ln(1/frcpa(1+ 21/256)
+data8 0x3FB580DB7CEB5702 //ln(1/frcpa(1+ 22/256)
+data8 0x3FB674F089365A7A //ln(1/frcpa(1+ 23/256)
+data8 0x3FB769EF2C6B568D //ln(1/frcpa(1+ 24/256)
+data8 0x3FB85FD927506A48 //ln(1/frcpa(1+ 25/256)
+data8 0x3FB9335E5D594989 //ln(1/frcpa(1+ 26/256)
+data8 0x3FBA2B0220C8E5F5 //ln(1/frcpa(1+ 27/256)
+data8 0x3FBB0004AC1A86AC //ln(1/frcpa(1+ 28/256)
+data8 0x3FBBF968769FCA11 //ln(1/frcpa(1+ 29/256)
+data8 0x3FBCCFEDBFEE13A8 //ln(1/frcpa(1+ 30/256)
+data8 0x3FBDA727638446A2 //ln(1/frcpa(1+ 31/256)
+data8 0x3FBEA3257FE10F7A //ln(1/frcpa(1+ 32/256)
+data8 0x3FBF7BE9FEDBFDE6 //ln(1/frcpa(1+ 33/256)
+data8 0x3FC02AB352FF25F4 //ln(1/frcpa(1+ 34/256)
+data8 0x3FC097CE579D204D //ln(1/frcpa(1+ 35/256)
+data8 0x3FC1178E8227E47C //ln(1/frcpa(1+ 36/256)
+data8 0x3FC185747DBECF34 //ln(1/frcpa(1+ 37/256)
+data8 0x3FC1F3B925F25D41 //ln(1/frcpa(1+ 38/256)
+data8 0x3FC2625D1E6DDF57 //ln(1/frcpa(1+ 39/256)
+data8 0x3FC2D1610C86813A //ln(1/frcpa(1+ 40/256)
+data8 0x3FC340C59741142E //ln(1/frcpa(1+ 41/256)
+data8 0x3FC3B08B6757F2A9 //ln(1/frcpa(1+ 42/256)
+data8 0x3FC40DFB08378003 //ln(1/frcpa(1+ 43/256)
+data8 0x3FC47E74E8CA5F7C //ln(1/frcpa(1+ 44/256)
+data8 0x3FC4EF51F6466DE4 //ln(1/frcpa(1+ 45/256)
+data8 0x3FC56092E02BA516 //ln(1/frcpa(1+ 46/256)
+data8 0x3FC5D23857CD74D5 //ln(1/frcpa(1+ 47/256)
+data8 0x3FC6313A37335D76 //ln(1/frcpa(1+ 48/256)
+data8 0x3FC6A399DABBD383 //ln(1/frcpa(1+ 49/256)
+data8 0x3FC70337DD3CE41B //ln(1/frcpa(1+ 50/256)
+data8 0x3FC77654128F6127 //ln(1/frcpa(1+ 51/256)
+data8 0x3FC7E9D82A0B022D //ln(1/frcpa(1+ 52/256)
+data8 0x3FC84A6B759F512F //ln(1/frcpa(1+ 53/256)
+data8 0x3FC8AB47D5F5A310 //ln(1/frcpa(1+ 54/256)
+data8 0x3FC91FE49096581B //ln(1/frcpa(1+ 55/256)
+data8 0x3FC981634011AA75 //ln(1/frcpa(1+ 56/256)
+data8 0x3FC9F6C407089664 //ln(1/frcpa(1+ 57/256)
+data8 0x3FCA58E729348F43 //ln(1/frcpa(1+ 58/256)
+data8 0x3FCABB55C31693AD //ln(1/frcpa(1+ 59/256)
+data8 0x3FCB1E104919EFD0 //ln(1/frcpa(1+ 60/256)
+data8 0x3FCB94EE93E367CB //ln(1/frcpa(1+ 61/256)
+data8 0x3FCBF851C067555F //ln(1/frcpa(1+ 62/256)
+data8 0x3FCC5C0254BF23A6 //ln(1/frcpa(1+ 63/256)
+data8 0x3FCCC000C9DB3C52 //ln(1/frcpa(1+ 64/256)
+data8 0x3FCD244D99C85674 //ln(1/frcpa(1+ 65/256)
+data8 0x3FCD88E93FB2F450 //ln(1/frcpa(1+ 66/256)
+data8 0x3FCDEDD437EAEF01 //ln(1/frcpa(1+ 67/256)
+data8 0x3FCE530EFFE71012 //ln(1/frcpa(1+ 68/256)
+data8 0x3FCEB89A1648B971 //ln(1/frcpa(1+ 69/256)
+data8 0x3FCF1E75FADF9BDE //ln(1/frcpa(1+ 70/256)
+data8 0x3FCF84A32EAD7C35 //ln(1/frcpa(1+ 71/256)
+data8 0x3FCFEB2233EA07CD //ln(1/frcpa(1+ 72/256)
+data8 0x3FD028F9C7035C1C //ln(1/frcpa(1+ 73/256)
+data8 0x3FD05C8BE0D9635A //ln(1/frcpa(1+ 74/256)
+data8 0x3FD085EB8F8AE797 //ln(1/frcpa(1+ 75/256)
+data8 0x3FD0B9C8E32D1911 //ln(1/frcpa(1+ 76/256)
+data8 0x3FD0EDD060B78081 //ln(1/frcpa(1+ 77/256)
+data8 0x3FD122024CF0063F //ln(1/frcpa(1+ 78/256)
+data8 0x3FD14BE2927AECD4 //ln(1/frcpa(1+ 79/256)
+data8 0x3FD180618EF18ADF //ln(1/frcpa(1+ 80/256)
+data8 0x3FD1B50BBE2FC63B //ln(1/frcpa(1+ 81/256)
+data8 0x3FD1DF4CC7CF242D //ln(1/frcpa(1+ 82/256)
+data8 0x3FD214456D0EB8D4 //ln(1/frcpa(1+ 83/256)
+data8 0x3FD23EC5991EBA49 //ln(1/frcpa(1+ 84/256)
+data8 0x3FD2740D9F870AFB //ln(1/frcpa(1+ 85/256)
+data8 0x3FD29ECDABCDFA04 //ln(1/frcpa(1+ 86/256)
+data8 0x3FD2D46602ADCCEE //ln(1/frcpa(1+ 87/256)
+data8 0x3FD2FF66B04EA9D4 //ln(1/frcpa(1+ 88/256)
+data8 0x3FD335504B355A37 //ln(1/frcpa(1+ 89/256)
+data8 0x3FD360925EC44F5D //ln(1/frcpa(1+ 90/256)
+data8 0x3FD38BF1C3337E75 //ln(1/frcpa(1+ 91/256)
+data8 0x3FD3C25277333184 //ln(1/frcpa(1+ 92/256)
+data8 0x3FD3EDF463C1683E //ln(1/frcpa(1+ 93/256)
+data8 0x3FD419B423D5E8C7 //ln(1/frcpa(1+ 94/256)
+data8 0x3FD44591E0539F49 //ln(1/frcpa(1+ 95/256)
+data8 0x3FD47C9175B6F0AD //ln(1/frcpa(1+ 96/256)
+data8 0x3FD4A8B341552B09 //ln(1/frcpa(1+ 97/256)
+data8 0x3FD4D4F3908901A0 //ln(1/frcpa(1+ 98/256)
+data8 0x3FD501528DA1F968 //ln(1/frcpa(1+ 99/256)
+data8 0x3FD52DD06347D4F6 //ln(1/frcpa(1+ 100/256)
+data8 0x3FD55A6D3C7B8A8A //ln(1/frcpa(1+ 101/256)
+data8 0x3FD5925D2B112A59 //ln(1/frcpa(1+ 102/256)
+data8 0x3FD5BF406B543DB2 //ln(1/frcpa(1+ 103/256)
+data8 0x3FD5EC433D5C35AE //ln(1/frcpa(1+ 104/256)
+data8 0x3FD61965CDB02C1F //ln(1/frcpa(1+ 105/256)
+data8 0x3FD646A84935B2A2 //ln(1/frcpa(1+ 106/256)
+data8 0x3FD6740ADD31DE94 //ln(1/frcpa(1+ 107/256)
+data8 0x3FD6A18DB74A58C5 //ln(1/frcpa(1+ 108/256)
+data8 0x3FD6CF31058670EC //ln(1/frcpa(1+ 109/256)
+data8 0x3FD6F180E852F0BA //ln(1/frcpa(1+ 110/256)
+data8 0x3FD71F5D71B894F0 //ln(1/frcpa(1+ 111/256)
+data8 0x3FD74D5AEFD66D5C //ln(1/frcpa(1+ 112/256)
+data8 0x3FD77B79922BD37E //ln(1/frcpa(1+ 113/256)
+data8 0x3FD7A9B9889F19E2 //ln(1/frcpa(1+ 114/256)
+data8 0x3FD7D81B037EB6A6 //ln(1/frcpa(1+ 115/256)
+data8 0x3FD8069E33827231 //ln(1/frcpa(1+ 116/256)
+data8 0x3FD82996D3EF8BCB //ln(1/frcpa(1+ 117/256)
+data8 0x3FD85855776DCBFB //ln(1/frcpa(1+ 118/256)
+data8 0x3FD8873658327CCF //ln(1/frcpa(1+ 119/256)
+data8 0x3FD8AA75973AB8CF //ln(1/frcpa(1+ 120/256)
+data8 0x3FD8D992DC8824E5 //ln(1/frcpa(1+ 121/256)
+data8 0x3FD908D2EA7D9512 //ln(1/frcpa(1+ 122/256)
+data8 0x3FD92C59E79C0E56 //ln(1/frcpa(1+ 123/256)
+data8 0x3FD95BD750EE3ED3 //ln(1/frcpa(1+ 124/256)
+data8 0x3FD98B7811A3EE5B //ln(1/frcpa(1+ 125/256)
+data8 0x3FD9AF47F33D406C //ln(1/frcpa(1+ 126/256)
+data8 0x3FD9DF270C1914A8 //ln(1/frcpa(1+ 127/256)
+data8 0x3FDA0325ED14FDA4 //ln(1/frcpa(1+ 128/256)
+data8 0x3FDA33440224FA79 //ln(1/frcpa(1+ 129/256)
+data8 0x3FDA57725E80C383 //ln(1/frcpa(1+ 130/256)
+data8 0x3FDA87D0165DD199 //ln(1/frcpa(1+ 131/256)
+data8 0x3FDAAC2E6C03F896 //ln(1/frcpa(1+ 132/256)
+data8 0x3FDADCCC6FDF6A81 //ln(1/frcpa(1+ 133/256)
+data8 0x3FDB015B3EB1E790 //ln(1/frcpa(1+ 134/256)
+data8 0x3FDB323A3A635948 //ln(1/frcpa(1+ 135/256)
+data8 0x3FDB56FA04462909 //ln(1/frcpa(1+ 136/256)
+data8 0x3FDB881AA659BC93 //ln(1/frcpa(1+ 137/256)
+data8 0x3FDBAD0BEF3DB165 //ln(1/frcpa(1+ 138/256)
+data8 0x3FDBD21297781C2F //ln(1/frcpa(1+ 139/256)
+data8 0x3FDC039236F08819 //ln(1/frcpa(1+ 140/256)
+data8 0x3FDC28CB1E4D32FD //ln(1/frcpa(1+ 141/256)
+data8 0x3FDC4E19B84723C2 //ln(1/frcpa(1+ 142/256)
+data8 0x3FDC7FF9C74554C9 //ln(1/frcpa(1+ 143/256)
+data8 0x3FDCA57B64E9DB05 //ln(1/frcpa(1+ 144/256)
+data8 0x3FDCCB130A5CEBB0 //ln(1/frcpa(1+ 145/256)
+data8 0x3FDCF0C0D18F326F //ln(1/frcpa(1+ 146/256)
+data8 0x3FDD232075B5A201 //ln(1/frcpa(1+ 147/256)
+data8 0x3FDD490246DEFA6B //ln(1/frcpa(1+ 148/256)
+data8 0x3FDD6EFA918D25CD //ln(1/frcpa(1+ 149/256)
+data8 0x3FDD9509707AE52F //ln(1/frcpa(1+ 150/256)
+data8 0x3FDDBB2EFE92C554 //ln(1/frcpa(1+ 151/256)
+data8 0x3FDDEE2F3445E4AF //ln(1/frcpa(1+ 152/256)
+data8 0x3FDE148A1A2726CE //ln(1/frcpa(1+ 153/256)
+data8 0x3FDE3AFC0A49FF40 //ln(1/frcpa(1+ 154/256)
+data8 0x3FDE6185206D516E //ln(1/frcpa(1+ 155/256)
+data8 0x3FDE882578823D52 //ln(1/frcpa(1+ 156/256)
+data8 0x3FDEAEDD2EAC990C //ln(1/frcpa(1+ 157/256)
+data8 0x3FDED5AC5F436BE3 //ln(1/frcpa(1+ 158/256)
+data8 0x3FDEFC9326D16AB9 //ln(1/frcpa(1+ 159/256)
+data8 0x3FDF2391A2157600 //ln(1/frcpa(1+ 160/256)
+data8 0x3FDF4AA7EE03192D //ln(1/frcpa(1+ 161/256)
+data8 0x3FDF71D627C30BB0 //ln(1/frcpa(1+ 162/256)
+data8 0x3FDF991C6CB3B379 //ln(1/frcpa(1+ 163/256)
+data8 0x3FDFC07ADA69A910 //ln(1/frcpa(1+ 164/256)
+data8 0x3FDFE7F18EB03D3E //ln(1/frcpa(1+ 165/256)
+data8 0x3FE007C053C5002E //ln(1/frcpa(1+ 166/256)
+data8 0x3FE01B942198A5A1 //ln(1/frcpa(1+ 167/256)
+data8 0x3FE02F74400C64EB //ln(1/frcpa(1+ 168/256)
+data8 0x3FE04360BE7603AD //ln(1/frcpa(1+ 169/256)
+data8 0x3FE05759AC47FE34 //ln(1/frcpa(1+ 170/256)
+data8 0x3FE06B5F1911CF52 //ln(1/frcpa(1+ 171/256)
+data8 0x3FE078BF0533C568 //ln(1/frcpa(1+ 172/256)
+data8 0x3FE08CD9687E7B0E //ln(1/frcpa(1+ 173/256)
+data8 0x3FE0A10074CF9019 //ln(1/frcpa(1+ 174/256)
+data8 0x3FE0B5343A234477 //ln(1/frcpa(1+ 175/256)
+data8 0x3FE0C974C89431CE //ln(1/frcpa(1+ 176/256)
+data8 0x3FE0DDC2305B9886 //ln(1/frcpa(1+ 177/256)
+data8 0x3FE0EB524BAFC918 //ln(1/frcpa(1+ 178/256)
+data8 0x3FE0FFB54213A476 //ln(1/frcpa(1+ 179/256)
+data8 0x3FE114253DA97D9F //ln(1/frcpa(1+ 180/256)
+data8 0x3FE128A24F1D9AFF //ln(1/frcpa(1+ 181/256)
+data8 0x3FE1365252BF0865 //ln(1/frcpa(1+ 182/256)
+data8 0x3FE14AE558B4A92D //ln(1/frcpa(1+ 183/256)
+data8 0x3FE15F85A19C765B //ln(1/frcpa(1+ 184/256)
+data8 0x3FE16D4D38C119FA //ln(1/frcpa(1+ 185/256)
+data8 0x3FE18203C20DD133 //ln(1/frcpa(1+ 186/256)
+data8 0x3FE196C7BC4B1F3B //ln(1/frcpa(1+ 187/256)
+data8 0x3FE1A4A738B7A33C //ln(1/frcpa(1+ 188/256)
+data8 0x3FE1B981C0C9653D //ln(1/frcpa(1+ 189/256)
+data8 0x3FE1CE69E8BB106B //ln(1/frcpa(1+ 190/256)
+data8 0x3FE1DC619DE06944 //ln(1/frcpa(1+ 191/256)
+data8 0x3FE1F160A2AD0DA4 //ln(1/frcpa(1+ 192/256)
+data8 0x3FE2066D7740737E //ln(1/frcpa(1+ 193/256)
+data8 0x3FE2147DBA47A394 //ln(1/frcpa(1+ 194/256)
+data8 0x3FE229A1BC5EBAC3 //ln(1/frcpa(1+ 195/256)
+data8 0x3FE237C1841A502E //ln(1/frcpa(1+ 196/256)
+data8 0x3FE24CFCE6F80D9A //ln(1/frcpa(1+ 197/256)
+data8 0x3FE25B2C55CD5762 //ln(1/frcpa(1+ 198/256)
+data8 0x3FE2707F4D5F7C41 //ln(1/frcpa(1+ 199/256)
+data8 0x3FE285E0842CA384 //ln(1/frcpa(1+ 200/256)
+data8 0x3FE294294708B773 //ln(1/frcpa(1+ 201/256)
+data8 0x3FE2A9A2670AFF0C //ln(1/frcpa(1+ 202/256)
+data8 0x3FE2B7FB2C8D1CC1 //ln(1/frcpa(1+ 203/256)
+data8 0x3FE2C65A6395F5F5 //ln(1/frcpa(1+ 204/256)
+data8 0x3FE2DBF557B0DF43 //ln(1/frcpa(1+ 205/256)
+data8 0x3FE2EA64C3F97655 //ln(1/frcpa(1+ 206/256)
+data8 0x3FE3001823684D73 //ln(1/frcpa(1+ 207/256)
+data8 0x3FE30E97E9A8B5CD //ln(1/frcpa(1+ 208/256)
+data8 0x3FE32463EBDD34EA //ln(1/frcpa(1+ 209/256)
+data8 0x3FE332F4314AD796 //ln(1/frcpa(1+ 210/256)
+data8 0x3FE348D90E7464D0 //ln(1/frcpa(1+ 211/256)
+data8 0x3FE35779F8C43D6E //ln(1/frcpa(1+ 212/256)
+data8 0x3FE36621961A6A99 //ln(1/frcpa(1+ 213/256)
+data8 0x3FE37C299F3C366A //ln(1/frcpa(1+ 214/256)
+data8 0x3FE38AE2171976E7 //ln(1/frcpa(1+ 215/256)
+data8 0x3FE399A157A603E7 //ln(1/frcpa(1+ 216/256)
+data8 0x3FE3AFCCFE77B9D1 //ln(1/frcpa(1+ 217/256)
+data8 0x3FE3BE9D503533B5 //ln(1/frcpa(1+ 218/256)
+data8 0x3FE3CD7480B4A8A3 //ln(1/frcpa(1+ 219/256)
+data8 0x3FE3E3C43918F76C //ln(1/frcpa(1+ 220/256)
+data8 0x3FE3F2ACB27ED6C7 //ln(1/frcpa(1+ 221/256)
+data8 0x3FE4019C2125CA93 //ln(1/frcpa(1+ 222/256)
+data8 0x3FE4181061389722 //ln(1/frcpa(1+ 223/256)
+data8 0x3FE42711518DF545 //ln(1/frcpa(1+ 224/256)
+data8 0x3FE436194E12B6BF //ln(1/frcpa(1+ 225/256)
+data8 0x3FE445285D68EA69 //ln(1/frcpa(1+ 226/256)
+data8 0x3FE45BCC464C893A //ln(1/frcpa(1+ 227/256)
+data8 0x3FE46AED21F117FC //ln(1/frcpa(1+ 228/256)
+data8 0x3FE47A1527E8A2D3 //ln(1/frcpa(1+ 229/256)
+data8 0x3FE489445EFFFCCC //ln(1/frcpa(1+ 230/256)
+data8 0x3FE4A018BCB69835 //ln(1/frcpa(1+ 231/256)
+data8 0x3FE4AF5A0C9D65D7 //ln(1/frcpa(1+ 232/256)
+data8 0x3FE4BEA2A5BDBE87 //ln(1/frcpa(1+ 233/256)
+data8 0x3FE4CDF28F10AC46 //ln(1/frcpa(1+ 234/256)
+data8 0x3FE4DD49CF994058 //ln(1/frcpa(1+ 235/256)
+data8 0x3FE4ECA86E64A684 //ln(1/frcpa(1+ 236/256)
+data8 0x3FE503C43CD8EB68 //ln(1/frcpa(1+ 237/256)
+data8 0x3FE513356667FC57 //ln(1/frcpa(1+ 238/256)
+data8 0x3FE522AE0738A3D8 //ln(1/frcpa(1+ 239/256)
+data8 0x3FE5322E26867857 //ln(1/frcpa(1+ 240/256)
+data8 0x3FE541B5CB979809 //ln(1/frcpa(1+ 241/256)
+data8 0x3FE55144FDBCBD62 //ln(1/frcpa(1+ 242/256)
+data8 0x3FE560DBC45153C7 //ln(1/frcpa(1+ 243/256)
+data8 0x3FE5707A26BB8C66 //ln(1/frcpa(1+ 244/256)
+data8 0x3FE587F60ED5B900 //ln(1/frcpa(1+ 245/256)
+data8 0x3FE597A7977C8F31 //ln(1/frcpa(1+ 246/256)
+data8 0x3FE5A760D634BB8B //ln(1/frcpa(1+ 247/256)
+data8 0x3FE5B721D295F10F //ln(1/frcpa(1+ 248/256)
+data8 0x3FE5C6EA94431EF9 //ln(1/frcpa(1+ 249/256)
+data8 0x3FE5D6BB22EA86F6 //ln(1/frcpa(1+ 250/256)
+data8 0x3FE5E6938645D390 //ln(1/frcpa(1+ 251/256)
+data8 0x3FE5F673C61A2ED2 //ln(1/frcpa(1+ 252/256)
+data8 0x3FE6065BEA385926 //ln(1/frcpa(1+ 253/256)
+data8 0x3FE6164BFA7CC06B //ln(1/frcpa(1+ 254/256)
+data8 0x3FE62643FECF9743 //ln(1/frcpa(1+ 255/256)
+//
+// [2;4)
+data8 0xBEB2CC7A38B9355F,0x3F035F2D1833BF4C // A10,A9
+data8 0xBFF51BAA7FD27785,0x3FFC9D5D5B6CDEFF // A2,A1
+data8 0xBF421676F9CB46C7,0x3F7437F2FA1436C6 // A8,A7
+data8 0xBFD7A7041DE592FE,0x3FE9F107FEE8BD29 // A4,A3
+// [4;8)
+data8 0x3F6BBBD68451C0CD,0xBF966EC3272A16F7 // A10,A9
+data8 0x40022A24A39AD769,0x4014190EDF49C8C5 // A2,A1
+data8 0x3FB130FD016EE241,0xBFC151B46E635248 // A8,A7
+data8 0x3FDE8F611965B5FE,0xBFEB5110EB265E3D // A4,A3
+// [8;16)
+data8 0x3F736EF93508626A,0xBF9FE5DBADF58AF1 // A10,A9
+data8 0x40110A9FC5192058,0x40302008A6F96B29 // A2,A1
+data8 0x3FB8E74E0CE1E4B5,0xBFC9B5DA78873656 // A8,A7
+data8 0x3FE99D0DF10022DC,0xBFF829C0388F9484 // A4,A3
+// [16;32)
+data8 0x3F7FFF9D6D7E9269,0xBFAA780A249AEDB1 // A10,A9
+data8 0x402082A807AEA080,0x4045ED9868408013 // A2,A1
+data8 0x3FC4E1E54C2F99B7,0xBFD5DE2D6FFF1490 // A8,A7
+data8 0x3FF75FC89584AE87,0xC006B4BADD886CAE // A4,A3
+// [32;64)
+data8 0x3F8CE54375841A5F,0xBFB801ABCFFA1BE2 // A10,A9
+data8 0x403040A8B1815BDA,0x405B99A917D24B7A // A2,A1
+data8 0x3FD30CAB81BFFA03,0xBFE41AEF61ECF48B // A8,A7
+data8 0x400650CC136BEC43,0xC016022046E8292B // A4,A3
+// [64;128)
+data8 0x3F9B69BD22CAA8B8,0xBFC6D48875B7A213 // A10,A9
+data8 0x40402028CCAA2F6D,0x40709AACEB3CBE0F // A2,A1
+data8 0x3FE22C6A5924761E,0xBFF342F5F224523D // A8,A7
+data8 0x4015CD405CCA331F,0xC025AAD10482C769 // A4,A3
+// [128;256)
+data8 0x3FAAAD9CD0E40D06,0xBFD63FC8505D80CB // A10,A9
+data8 0x40501008D56C2648,0x408364794B0F4376 // A2,A1
+data8 0x3FF1BE0126E00284,0xC002D8E3F6F7F7CA // A8,A7
+data8 0x40258C757E95D860,0xC0357FA8FD398011 // A4,A3
+// [256;512)
+data8 0x3FBA4DAC59D49FEB,0xBFE5F476D1C43A77 // A10,A9
+data8 0x40600800D890C7C6,0x40962C42AAEC8EF0 // A2,A1
+data8 0x40018680ECF19B89,0xC012A3EB96FB7BA4 // A8,A7
+data8 0x40356C4CDD3B60F9,0xC0456A34BF18F440 // A4,A3
+// [512;1024)
+data8 0x3FCA1B54F6225A5A,0xBFF5CD67BA10E048 // A10,A9
+data8 0x407003FED94C58C2,0x40A8F30B4ACBCD22 // A2,A1
+data8 0x40116A135EB66D8C,0xC022891B1CED527E // A8,A7
+data8 0x40455C4617FDD8BC,0xC0555F82729E59C4 // A4,A3
+// [1024;2048)
+data8 0x3FD9FFF9095C6EC9,0xC005B88CB25D76C9 // A10,A9
+data8 0x408001FE58FA734D,0x40BBB953BAABB0F3 // A2,A1
+data8 0x40215B2F9FEB5D87,0xC0327B539DEA5058 // A8,A7
+data8 0x40555444B3E8D64D,0xC0655A2B26F9FC8A // A4,A3
+// [2048;4096)
+data8 0x3FE9F065A1C3D6B1,0xC015ACF6FAE8D78D // A10,A9
+data8 0x409000FE383DD2B7,0x40CE7F5C1E8BCB8B // A2,A1
+data8 0x40315324E5DB2EBE,0xC04274194EF70D18 // A8,A7
+data8 0x4065504353FF2207,0xC075577FE1BFE7B6 // A4,A3
+// [4096;8192)
+data8 0x3FF9E6FBC6B1C70D,0xC025A62DAF76F85D // A10,A9
+data8 0x40A0007E2F61EBE8,0x40E0A2A23FB5F6C3 // A2,A1
+data8 0x40414E9BC0A0141A,0xC0527030F2B69D43 // A8,A7
+data8 0x40754E417717B45B,0xC085562A447258E5 // A4,A3
+//
+data8 0xbfdffffffffaea15 // P1
+data8 0x3FDD8B618D5AF8FE // point of local minimum on [1;2]
+data8 0x3FED67F1C864BEB5 // ln(sqrt(2*Pi))
+data8 0x4008000000000000 // 3.0
+//
+data8 0xBF9E1C289FB224AB,0x3FBF7422445C9460 // A6,A5
+data8 0xBFF01E76D66F8D8A // A0
+data8 0xBFE2788CFC6F91DA // A1 [1.0;1.25)
+data8 0x3FCB8CC69000EB5C,0xBFD41997A0C2C641 // A6,A5
+data8 0x3FFCAB0BFA0EA462 // A0
+data8 0xBFBF19B9BCC38A42 // A0 [1.25;1.5)
+data8 0x3FD51EE4DE0A364C,0xBFE00D7F98A16E4B // A6,A5
+data8 0x40210CE1F327E9E4 // A0
+data8 0x4001DB08F9DFA0CC // A0 [1.5;1.75)
+data8 0x3FE24F606742D252,0xBFEC81D7D12574EC // A6,A5
+data8 0x403BE636A63A9C27 // A0
+data8 0x4000A0CB38D6CF0A // A0 [1.75;2.0)
+data8 0x3FF1029A9DD542B4,0xBFFAD37C209D3B25 // A6,A5
+data8 0x405385E6FD9BE7EA // A0
+data8 0x478895F1C0000000 // Overflow boundary
+data8 0x400062D97D26B523,0xC00A03E1529FF023 // A6,A5
+data8 0x4069204C51E566CE // A0
+data8 0x0000000000000000 // pad
+data8 0x40101476B38FD501,0xC0199DE7B387C0FC // A6,A5
+data8 0x407EB8DAEC83D759 // A0
+data8 0x0000000000000000 // pad
+data8 0x401FDB008D65125A,0xC0296B506E665581 // A6,A5
+data8 0x409226D93107EF66 // A0
+data8 0x0000000000000000 // pad
+data8 0x402FB3EAAF3E7B2D,0xC039521142AD8E0D // A6,A5
+data8 0x40A4EFA4F072792E // A0
+data8 0x0000000000000000 // pad
+data8 0x403FA024C66B2563,0xC0494569F250E691 // A6,A5
+data8 0x40B7B747C9235BB8 // A0
+data8 0x0000000000000000 // pad
+data8 0x404F9607D6DA512C,0xC0593F0B2EDDB4BC // A6,A5
+data8 0x40CA7E29C5F16DE2 // A0
+data8 0x0000000000000000 // pad
+data8 0x405F90C5F613D98D,0xC0693BD130E50AAF // A6,A5
+data8 0x40DD4495238B190C // A0
+data8 0x0000000000000000 // pad
+//
+// polynomial approximation of ln(sin(Pi*x)/(Pi*x)), |x| <= 0.5
+data8 0xBFD58731A486E820,0xBFA4452CC28E15A9 // S16,S14
+data8 0xBFD013F6E1B86C4F,0xBFD5B3F19F7A341F // S8,S6
+data8 0xBFC86A0D5252E778,0xBFC93E08C9EE284B // S12,S10
+data8 0xBFE15132555C9EDD,0xBFFA51A662480E35 // S4,S2
+//
+// [1.0;1.25)
+data8 0xBFA697D6775F48EA,0x3FB9894B682A98E7 // A9,A8
+data8 0xBFCA8969253CFF55,0x3FD15124EFB35D9D // A5,A4
+data8 0xBFC1B00158AB719D,0x3FC5997D04E7F1C1 // A7,A6
+data8 0xBFD9A4D50BAFF989,0x3FEA51A661F5176A // A3,A2
+// [1.25;1.5)
+data8 0x3F838E0D35A6171A,0xBF831BBBD61313B7 // A8,A7
+data8 0x3FB08B40196425D0,0xBFC2E427A53EB830 // A4,A3
+data8 0x3F9285DDDC20D6C3,0xBFA0C90C9C223044 // A6,A5
+data8 0x3FDEF72BC8F5287C,0x3D890B3DAEBC1DFC // A2,A1
+// [1.5;1.75)
+data8 0x3F65D5A7EB31047F,0xBFA44EAC9BFA7FDE // A8,A7
+data8 0x40051FEFE7A663D8,0xC012A5CFE00A2522 // A4,A3
+data8 0x3FD0E1583AB00E08,0xBFF084AF95883BA5 // A6,A5
+data8 0x40185982877AE0A2,0xC015F83DB73B57B7 // A2,A1
+// [1.75;2.0)
+data8 0x3F4A9222032EB39A,0xBF8CBC9587EEA5A3 // A8,A7
+data8 0x3FF795400783BE49,0xC00851BC418B8A25 // A4,A3
+data8 0x3FBBC992783E8C5B,0xBFDFA67E65E89B29 // A6,A5
+data8 0x4012B408F02FAF88,0xC013284CE7CB0C39 // A2,A1
+//
+// roots
+data8 0xC003A7FC9600F86C // -2.4570247382208005860
+data8 0xC009260DBC9E59AF // -3.1435808883499798405
+data8 0xC005FB410A1BD901 // -2.7476826467274126919
+data8 0xC00FA471547C2FE5 // -3.9552942848585979085
+//
+// polynomial approximation of ln(GAMMA(x)) near roots
+// near -2.4570247382208005860
+data8 0x3FF694A6058D9592,0x40136EEBB003A92B // R3,R2
+data8 0x3FF83FE966AF5360,0x3C90323B6D1FE86D // R1,R0
+// near -3.1435808883499798405
+data8 0x405C11371268DA38,0x4039D4D2977D2C23 // R3,R2
+data8 0x401F20A65F2FAC62,0x3CDE9605E3AE7A62 // R1,R0
+// near -2.7476826467274126919
+data8 0xC034185AC31314FF,0x4023267F3C28DFE3 // R3,R2
+data8 0xBFFEA12DA904B194,0x3CA8FB8530BA7689 // R1,R0
+// near -2.7476826467274126919
+data8 0xC0AD25359E70C888,0x406F76DEAEA1B8C6 // R3,R2
+data8 0xC034B99D966C5644,0xBCBDDC0336980B58 // R1,R0
+LOCAL_OBJECT_END(lgammaf_data)
+
+//*********************************************************************
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_lgammaf)
+{ .mfi
+ getf.exp GR_SignExp = f8
+ frcpa.s1 FR_InvX,p0 = f1,f8
+ mov GR_ExpOf2 = 0x10000
+}
+{ .mfi
+ addl GR_ad_Data = @ltoff(lgammaf_data),gp
+ fcvt.fx.s1 FR_int_N = f8
+ mov GR_ExpMask = 0x1ffff
+};;
+{ .mfi
+ getf.sig GR_Sig = f8
+ fclass.m p13,p0 = f8,0x1EF // is x NaTVal, NaN,
+ // +/-0, +/-INF or +/-deno?
+ mov GR_ExpBias = 0xffff
+}
+{ .mfi
+ ld8 GR_ad_Data = [GR_ad_Data]
+ fma.s1 FR_Xp1 = f8,f1,f1
+ mov GR_StirlBound = 0x1000C
+};;
+{ .mfi
+ setf.exp FR_2 = GR_ExpOf2
+ fmerge.se FR_x = f1,f8
+ dep.z GR_Ind = GR_SignExp,3,4
+}
+{ .mfi
+ cmp.eq p8,p0 = GR_SignExp,GR_ExpBias
+ fcvt.fx.trunc.s1 FR_int_Ntrunc = f8
+ and GR_Exp = GR_ExpMask,GR_SignExp
+};;
+{ .mfi
+ add GR_ad_C650 = 0xB20,GR_ad_Data
+ fcmp.lt.s1 p14,p15 = f8,f0
+ extr.u GR_Ind4T = GR_Sig,55,8
+}
+{ .mfb
+ sub GR_PureExp = GR_Exp,GR_ExpBias
+ fnorm.s1 FR_NormX = f8
+ // jump if x is NaTVal, NaN, +/-0, +/-INF or +/-deno
+(p13) br.cond.spnt lgammaf_spec
+};;
+lgammaf_core:
+{ .mfi
+ ldfpd FR_P1,FR_LocalMin = [GR_ad_C650],16
+ fms.s1 FR_xm2 = f8,f1,f1
+ add GR_ad_Co = 0x820,GR_ad_Data
+}
+{ .mib
+ ldfpd FR_P3,FR_P2 = [GR_ad_Data],16
+ cmp.ltu p9,p0 = GR_SignExp,GR_ExpBias
+ // jump if x is from the interval [1; 2)
+(p8) br.cond.spnt lgammaf_1_2
+};;
+{ .mfi
+ setf.sig FR_int_Ln = GR_PureExp
+ fms.s1 FR_r = FR_InvX,f8,f1
+ shladd GR_ad_Co = GR_Ind,3,GR_ad_Co
+}
+{ .mib
+ ldfpd FR_LnSqrt2Pi,FR_3 = [GR_ad_C650],16
+ cmp.lt p13,p12 = GR_Exp,GR_StirlBound
+ // jump if x is from the interval (0; 1)
+(p9) br.cond.spnt lgammaf_0_1
+};;
+{ .mfi
+ ldfpd FR_Ln2,FR_05 = [GR_ad_Data],16
+ fma.s1 FR_Xp2 = f1,f1,FR_Xp1 // (x+2)
+ shladd GR_ad_C650 = GR_Ind,2,GR_ad_C650
+}
+{ .mfi
+ add GR_ad_Ce = 0x20,GR_ad_Co
+ nop.f 0
+ add GR_ad_C43 = 0x30,GR_ad_Co
+};;
+{ .mfi
+ // load coefficients of polynomial approximation
+ // of ln(GAMMA(x)), 2 <= x < 2^13
+(p13) ldfpd FR_A10,FR_A9 = [GR_ad_Co],16
+ fcvt.xf FR_N = FR_int_N
+ cmp.eq.unc p6,p7 = GR_ExpOf2,GR_SignExp
+}
+{ .mib
+(p13) ldfpd FR_A8,FR_A7 = [GR_ad_Ce]
+(p14) cmp.le.unc p9,p0 = GR_StirlBound,GR_Exp
+ // jump if x is less or equal to -2^13
+(p9) br.cond.spnt lgammaf_negstirling
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+(p13) ldfpd FR_A6,FR_A5 = [GR_ad_C650],16
+(p6) fma.s1 FR_x = f0,f0,FR_NormX
+ shladd GR_ad_T = GR_Ind4T,3,GR_ad_Data
+}
+{ .mfi
+(p13) ldfpd FR_A4,FR_A3 = [GR_ad_C43]
+(p7) fms.s1 FR_x = FR_x,f1,f1
+(p14) mov GR_ReqBound = 0x20005
+};;
+{ .mfi
+(p13) ldfpd FR_A2,FR_A1 = [GR_ad_Co],16
+ fms.s1 FR_xm2 = FR_xm2,f1,f1
+(p14) extr.u GR_Arg = GR_Sig,60,4
+}
+{ .mfi
+ mov GR_SignOfGamma = 1 // set sign of gamma(x) to 1
+ fcvt.xf FR_Ntrunc = FR_int_Ntrunc
+ nop.i 0
+};;
+{ .mfi
+ ldfd FR_T = [GR_ad_T]
+ fma.s1 FR_r2 = FR_r,FR_r,f0
+ shl GR_ReqBound = GR_ReqBound,3
+}
+{ .mfi
+ add GR_ad_Co = 0xCA0,GR_ad_Data
+ fnma.s1 FR_Req = FR_Xp1,FR_NormX,f0 // -x*(x+1)
+(p14) shladd GR_Arg = GR_Exp,4,GR_Arg
+};;
+{ .mfi
+(p13) ldfd FR_A0 = [GR_ad_C650]
+ fma.s1 FR_Xp3 = FR_2,f1,FR_Xp1 // (x+3)
+(p14) cmp.le.unc p9,p0 = GR_Arg,GR_ReqBound
+}
+{ .mfi
+(p14) add GR_ad_Ce = 0x20,GR_ad_Co
+ fma.s1 FR_Xp4 = FR_2,FR_2,FR_NormX // (x+4)
+(p15) add GR_ad_OvfBound = 0xBB8,GR_ad_Data
+};;
+{ .mfi
+ // load coefficients of polynomial approximation
+ // of ln(sin(Pi*xf)/(Pi*xf)), |xf| <= 0.5
+(p14) ldfpd FR_S16,FR_S14 = [GR_ad_Co],16
+(p14) fms.s1 FR_Xf = FR_NormX,f1,FR_N // xf = x - [x]
+(p14) sub GR_SignOfGamma = r0,GR_SignOfGamma // set sign of
+ // gamma(x) to -1
+}
+{ .mfb
+(p14) ldfpd FR_S12,FR_S10 = [GR_ad_Ce],16
+ fma.s1 FR_Xp5 = FR_2,FR_2,FR_Xp1 // (x+5)
+ // jump if x is from the interval (-9; 0)
+(p9) br.cond.spnt lgammaf_negrecursion
+};;
+{ .mfi
+(p14) ldfpd FR_S8,FR_S6 = [GR_ad_Co],16
+ fma.s1 FR_P32 = FR_P3,FR_r,FR_P2
+ nop.i 0
+}
+{ .mfb
+(p14) ldfpd FR_S4,FR_S2 = [GR_ad_Ce],16
+ fma.s1 FR_x2 = FR_x,FR_x,f0
+ // jump if x is from the interval (-2^13; -9)
+(p14) br.cond.spnt lgammaf_negpoly
+};;
+{ .mfi
+ ldfd FR_OverflowBound = [GR_ad_OvfBound]
+(p12) fcvt.xf FR_N = FR_int_Ln
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+}
+{ .mfi
+ nop.m 0
+(p12) fma.s1 FR_P10 = FR_P1,FR_r,f1
+ nop.i 0
+};;
+.pred.rel "mutex",p6,p7
+.pred.rel "mutex",p9,p10
+{ .mfi
+ // store sign of gamma(x) as 32-bit int
+(p9) st4 [r33] = GR_SignOfGamma
+(p6) fma.s1 FR_xx = FR_x,FR_xm2,f0
+ nop.i 0
+}
+{ .mfi
+ // store sign of gamma(x) as 64-bit int
+(p10) st8 [r33] = GR_SignOfGamma
+(p7) fma.s1 FR_xx = f0,f0,FR_x
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_A9 = FR_A10,FR_x,FR_A9
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_A7 = FR_A8,FR_x,FR_A7
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_A5 = FR_A6,FR_x,FR_A5
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_A3 = FR_A4,FR_x,FR_A3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p15) fcmp.eq.unc.s1 p8,p0 = FR_NormX,FR_2 // is input argument 2.0?
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_A1 = FR_A2,FR_x,FR_A1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p12) fma.s1 FR_T = FR_N,FR_Ln2,FR_T
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p12) fma.s1 FR_P32 = FR_P32,FR_r2,FR_P10
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_x4 = FR_x2,FR_x2,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_x3 = FR_x2,FR_xx,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_A7 = FR_A9,FR_x2,FR_A7
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fma.s.s0 f8 = f0,f0,f0
+(p8) br.ret.spnt b0 // fast exit for 2.0
+};;
+{ .mfi
+ nop.m 0
+(p6) fma.s1 FR_A0 = FR_A0,FR_xm2,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_A3 = FR_A5,FR_x2,FR_A3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p15) fcmp.le.unc.s1 p8,p0 = FR_OverflowBound,FR_NormX // overflow test
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p12) fms.s1 FR_xm05 = FR_NormX,f1,FR_05
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p12) fma.s1 FR_Ln = FR_P32,FR_r,FR_T
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p12) fms.s1 FR_LnSqrt2Pi = FR_LnSqrt2Pi,f1,FR_NormX
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_A0 = FR_A1,FR_xx,FR_A0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p13) fma.s1 FR_A3 = FR_A7,FR_x4,FR_A3
+ // jump if result overflows
+(p8) br.cond.spnt lgammaf_overflow
+};;
+.pred.rel "mutex",p12,p13
+{ .mfi
+ nop.m 0
+(p12) fma.s.s0 f8 = FR_Ln,FR_xm05,FR_LnSqrt2Pi
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p13) fma.s.s0 f8 = FR_A3,FR_x3,FR_A0
+ br.ret.sptk b0
+};;
+// branch for calculating of ln(GAMMA(x)) for 0 < x < 1
+//---------------------------------------------------------------------
+.align 32
+lgammaf_0_1:
+{ .mfi
+ getf.sig GR_Ind = FR_Xp1
+ fma.s1 FR_r2 = FR_r,FR_r,f0
+ mov GR_fff7 = 0xFFF7
+}
+{ .mfi
+ ldfpd FR_Ln2,FR_05 = [GR_ad_Data],16
+ fma.s1 FR_P32 = FR_P3,FR_r,FR_P2
+ // input argument cann't be equal to 1.0
+ cmp.eq p0,p14 = r0,r0
+};;
+{ .mfi
+ getf.exp GR_Exp = FR_w
+ fcvt.xf FR_N = FR_int_Ln
+ add GR_ad_Co = 0xCE0,GR_ad_Data
+}
+{ .mfi
+ shladd GR_ad_T = GR_Ind4T,3,GR_ad_Data
+ fma.s1 FR_P10 = FR_P1,FR_r,f1
+ add GR_ad_Ce = 0xD00,GR_ad_Data
+};;
+{ .mfi
+ ldfd FR_T = [GR_ad_T]
+ fma.s1 FR_w2 = FR_w,FR_w,f0
+ extr.u GR_Ind = GR_Ind,61,2
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Q32 = FR_P3,FR_w,FR_P2
+//// add GR_ad_C0 = 0xB30,GR_ad_Data
+ add GR_ad_C0 = 0xB38,GR_ad_Data
+};;
+{ .mfi
+ and GR_Exp = GR_Exp,GR_ExpMask
+ nop.f 0
+ shladd GR_IndX8 = GR_Ind,3,r0
+}
+{ .mfi
+ shladd GR_IndX2 = GR_Ind,1,r0
+ fma.s1 FR_Q10 = FR_P1,FR_w,f1
+ cmp.eq p6,p15 = 0,GR_Ind
+};;
+{ .mfi
+ shladd GR_ad_Co = GR_IndX8,3,GR_ad_Co
+(p6) fma.s1 FR_x = f0,f0,FR_NormX
+ shladd GR_ad_C0 = GR_IndX2,4,GR_ad_C0
+}
+{ .mfi
+ shladd GR_ad_Ce = GR_IndX8,3,GR_ad_Ce
+ nop.f 0
+(p15) cmp.eq.unc p7,p8 = 1,GR_Ind
+};;
+.pred.rel "mutex",p7,p8
+{ .mfi
+ ldfpd FR_A8,FR_A7 = [GR_ad_Co],16
+(p7) fms.s1 FR_x = FR_NormX,f1,FR_LocalMin
+ cmp.ge p10,p11 = GR_Exp,GR_fff7
+}
+{ .mfb
+ ldfpd FR_A6,FR_A5 = [GR_ad_Ce],16
+(p8) fma.s1 FR_x = f1,f1,FR_NormX
+ br.cond.sptk lgamma_0_2_core
+};;
+// branch for calculating of ln(GAMMA(x)) for 1 <= x < 2
+//---------------------------------------------------------------------
+.align 32
+lgammaf_1_2:
+{ .mfi
+ add GR_ad_Co = 0xCF0,GR_ad_Data
+ fcmp.eq.s1 p14,p0 = f1,FR_NormX // is input argument 1.0?
+ extr.u GR_Ind = GR_Sig,61,2
+}
+{ .mfi
+ add GR_ad_Ce = 0xD10,GR_ad_Data
+ nop.f 0
+//// add GR_ad_C0 = 0xB40,GR_ad_Data
+ add GR_ad_C0 = 0xB48,GR_ad_Data
+};;
+{ .mfi
+ shladd GR_IndX8 = GR_Ind,3,r0
+ nop.f 0
+ shladd GR_IndX2 = GR_Ind,1,r0
+}
+{ .mfi
+ cmp.eq p6,p15 = 0,GR_Ind // p6 <- x from [1;1.25)
+ nop.f 0
+ cmp.ne p9,p0 = r0,r0
+};;
+{ .mfi
+ shladd GR_ad_Co = GR_IndX8,3,GR_ad_Co
+(p6) fms.s1 FR_x = FR_NormX,f1,f1 // reduced x for [1;1.25)
+ shladd GR_ad_C0 = GR_IndX2,4,GR_ad_C0
+}
+{ .mfi
+ shladd GR_ad_Ce = GR_IndX8,3,GR_ad_Ce
+(p14) fma.s.s0 f8 = f0,f0,f0
+(p15) cmp.eq.unc p7,p8 = 1,GR_Ind // p7 <- x from [1.25;1.5)
+};;
+.pred.rel "mutex",p7,p8
+{ .mfi
+ ldfpd FR_A8,FR_A7 = [GR_ad_Co],16
+(p7) fms.s1 FR_x = FR_xm2,f1,FR_LocalMin
+ nop.i 0
+}
+{ .mfi
+ ldfpd FR_A6,FR_A5 = [GR_ad_Ce],16
+(p8) fma.s1 FR_x = f0,f0,FR_NormX
+(p9) cmp.eq.unc p10,p11 = r0,r0
+};;
+lgamma_0_2_core:
+{ .mmi
+ ldfpd FR_A4,FR_A3 = [GR_ad_Co],16
+ ldfpd FR_A2,FR_A1 = [GR_ad_Ce],16
+ mov GR_SignOfGamma = 1 // set sign of gamma(x) to 1
+};;
+{ .mfi
+// add GR_ad_C0 = 8,GR_ad_C0
+ ldfd FR_A0 = [GR_ad_C0]
+ nop.f 0
+ // set p13 if signgum is 32-bit int
+ // set p15 if signgum is 64-bit int
+ cmp.eq p15,p13 = 8,r34
+};;
+.pred.rel "mutex",p13,p15
+{ .mmf
+ // store sign of gamma(x)
+(p13) st4 [r33] = GR_SignOfGamma // as 32-bit int
+(p15) st8 [r33] = GR_SignOfGamma // as 64-bit int
+(p11) fma.s1 FR_Q32 = FR_Q32,FR_w2,FR_Q10
+};;
+{ .mfb
+ nop.m 0
+(p10) fma.s1 FR_P32 = FR_P32,FR_r2,FR_P10
+(p14) br.ret.spnt b0 // fast exit for 1.0
+};;
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_T = FR_N,FR_Ln2,FR_T
+ cmp.eq p6,p7 = 0,GR_Ind // p6 <- x from [1;1.25)
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_x2 = FR_x,FR_x,f0
+ cmp.eq p8,p0 = r0,r0 // set p8 to 1 that means we on [1;2]
+};;
+{ .mfi
+ nop.m 0
+(p11) fma.s1 FR_Ln = FR_Q32,FR_w,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fma.s1 FR_xx = f0,f0,FR_x
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s1 FR_xx = f0,f0,f1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A7 = FR_A8,FR_x,FR_A7
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A5 = FR_A6,FR_x,FR_A5
+(p9) cmp.ne p8,p0 = r0,r0 // set p8 to 0 that means we on [0;1]
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A3 = FR_A4,FR_x,FR_A3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A1 = FR_A2,FR_x,FR_A1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_x4 = FR_x2,FR_x2,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_Ln = FR_P32,FR_r,FR_T
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A5 = FR_A7,FR_x2,FR_A5
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A1 = FR_A3,FR_x2,FR_A1
+ nop.i 0
+};;
+.pred.rel "mutex",p9,p8
+{ .mfi
+ nop.m 0
+(p9) fms.d.s1 FR_A0 = FR_A0,FR_xx,FR_Ln
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fms.s1 FR_A0 = FR_A0,FR_xx,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.d.s1 FR_A1 = FR_A5,FR_x4,FR_A1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fma.s.s0 f8 = FR_A1,FR_x2,FR_A0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.s.s0 f8 = FR_A1,FR_x,FR_A0
+ br.ret.sptk b0
+};;
+// branch for calculating of ln(GAMMA(x)) for -9 < x < 1
+//---------------------------------------------------------------------
+.align 32
+lgammaf_negrecursion:
+{ .mfi
+ getf.sig GR_N = FR_int_Ntrunc
+ fms.s1 FR_1pXf = FR_Xp2,f1,FR_Ntrunc // 1 + (x+1) - [x]
+ mov GR_Neg2 = 2
+}
+{ .mfi
+ add GR_ad_Co = 0xCE0,GR_ad_Data
+ fms.s1 FR_Xf = FR_Xp1,f1,FR_Ntrunc // (x+1) - [x]
+ mov GR_Neg4 = 4
+};;
+{ .mfi
+ add GR_ad_Ce = 0xD00,GR_ad_Data
+ fma.s1 FR_Xp6 = FR_2,FR_2,FR_Xp2 // (x+6)
+ add GR_ad_C0 = 0xB30,GR_ad_Data
+}
+{ .mfi
+ sub GR_Neg2 = r0,GR_Neg2
+ fma.s1 FR_Xp7 = FR_2,FR_3,FR_Xp1 // (x+7)
+ sub GR_Neg4 = r0,GR_Neg4
+};;
+{ .mfi
+ cmp.ne p8,p0 = r0,GR_N
+ fcmp.eq.s1 p13,p0 = FR_NormX,FR_Ntrunc
+ and GR_IntNum = 0xF,GR_N
+}
+{ .mfi
+ cmp.lt p6,p0 = GR_N,GR_Neg2
+ fma.s1 FR_Xp8 = FR_2,FR_3,FR_Xp2 // (x+8)
+ cmp.lt p7,p0 = GR_N,GR_Neg4
+};;
+{ .mfi
+ getf.d GR_Arg = FR_NormX
+(p6) fma.s1 FR_Xp2 = FR_Xp2,FR_Xp3,f0
+(p8) tbit.z.unc p14,p15 = GR_IntNum,0
+}
+{ .mfi
+ sub GR_RootInd = 0xE,GR_IntNum
+(p7) fma.s1 FR_Xp4 = FR_Xp4,FR_Xp5,f0
+ add GR_ad_Root = 0xDE0,GR_ad_Data
+};;
+{ .mfi
+ shladd GR_ad_Root = GR_RootInd,3,GR_ad_Root
+ fms.s1 FR_x = FR_Xp1,f1,FR_Ntrunc // (x+1) - [x]
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p13) br.cond.spnt lgammaf_singularity
+};;
+.pred.rel "mutex",p14,p15
+{ .mfi
+ cmp.gt p6,p0 = 0xA,GR_IntNum
+(p14) fma.s1 FR_Req = FR_Req,FR_Xf,f0
+ cmp.gt p7,p0 = 0xD,GR_IntNum
+}
+{ .mfi
+(p15) mov GR_SignOfGamma = 1 // set sign of gamma(x) to 1
+(p15) fnma.s1 FR_Req = FR_Req,FR_Xf,f0
+ cmp.leu p0,p13 = 2,GR_RootInd
+};;
+{ .mfi
+ nop.m 0
+(p6) fma.s1 FR_Xp6 = FR_Xp6,FR_Xp7,f0
+(p13) add GR_ad_RootCo = 0xE00,GR_ad_Data
+};;
+{ .mfi
+ nop.m 0
+ fcmp.eq.s1 p12,p11 = FR_1pXf,FR_2
+ nop.i 0
+};;
+{ .mfi
+ getf.sig GR_Sig = FR_1pXf
+ fcmp.le.s1 p9,p0 = FR_05,FR_Xf
+ nop.i 0
+}
+{ .mfi
+(p13) shladd GR_RootInd = GR_RootInd,4,r0
+(p7) fma.s1 FR_Xp2 = FR_Xp2,FR_Xp4,f0
+(p8) cmp.gt.unc p10,p0 = 0x9,GR_IntNum
+};;
+.pred.rel "mutex",p11,p12
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_Req = FR_Req,FR_Xp8,f0
+(p11) extr.u GR_Ind = GR_Sig,61,2
+}
+{ .mfi
+(p13) add GR_RootInd = GR_RootInd,GR_RootInd
+ nop.f 0
+(p12) mov GR_Ind = 3
+};;
+{ .mfi
+ shladd GR_IndX2 = GR_Ind,1,r0
+ nop.f 0
+ cmp.gt p14,p0 = 2,GR_Ind
+}
+{ .mfi
+ shladd GR_IndX8 = GR_Ind,3,r0
+ nop.f 0
+ cmp.eq p6,p0 = 1,GR_Ind
+};;
+.pred.rel "mutex",p6,p9
+{ .mfi
+ shladd GR_ad_Co = GR_IndX8,3,GR_ad_Co
+(p6) fms.s1 FR_x = FR_Xf,f1,FR_LocalMin
+ cmp.gt p10,p0 = 0xB,GR_IntNum
+}
+{ .mfi
+ shladd GR_ad_Ce = GR_IndX8,3,GR_ad_Ce
+(p9) fma.s1 FR_x = f0,f0,FR_1pXf
+ shladd GR_ad_C0 = GR_IndX2,4,GR_ad_C0
+};;
+{ .mfi
+ // load coefficients of polynomial approximation
+ // of ln(GAMMA(x)), 1 <= x < 2
+ ldfpd FR_A8,FR_A7 = [GR_ad_Co],16
+(p10) fma.s1 FR_Xp2 = FR_Xp2,FR_Xp6,f0
+ add GR_ad_C0 = 8,GR_ad_C0
+}
+{ .mfi
+ ldfpd FR_A6,FR_A5 = [GR_ad_Ce],16
+ nop.f 0
+(p14) add GR_ad_Root = 0x10,GR_ad_Root
+};;
+{ .mfi
+ ldfpd FR_A4,FR_A3 = [GR_ad_Co],16
+ nop.f 0
+ add GR_ad_RootCe = 0xE10,GR_ad_Data
+}
+{ .mfi
+ ldfpd FR_A2,FR_A1 = [GR_ad_Ce],16
+ nop.f 0
+(p14) add GR_RootInd = 0x40,GR_RootInd
+};;
+{ .mmi
+ ldfd FR_A0 = [GR_ad_C0]
+(p13) add GR_ad_RootCo = GR_ad_RootCo,GR_RootInd
+(p13) add GR_ad_RootCe = GR_ad_RootCe,GR_RootInd
+};;
+{ .mmi
+(p13) ld8 GR_Root = [GR_ad_Root]
+(p13) ldfd FR_Root = [GR_ad_Root]
+ mov GR_ExpBias = 0xffff
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_x2 = FR_x,FR_x,f0
+ nop.i 0
+}
+{ .mlx
+(p8) cmp.gt.unc p10,p0 = 0xF,GR_IntNum
+ movl GR_Dx = 0x000000014F8B588E
+};;
+{ .mfi
+ // load coefficients of polynomial approximation
+ // of ln(GAMMA(x)), x is close to one of negative roots
+(p13) ldfpd FR_R3,FR_R2 = [GR_ad_RootCo]
+ // argumenth for logarithm
+(p10) fma.s1 FR_Req = FR_Req,FR_Xp2,f0
+ mov GR_ExpMask = 0x1ffff
+}
+{ .mfi
+(p13) ldfpd FR_R1,FR_R0 = [GR_ad_RootCe]
+ nop.f 0
+ // set p9 if signgum is 32-bit int
+ // set p8 if signgum is 64-bit int
+ cmp.eq p8,p9 = 8,r34
+};;
+.pred.rel "mutex",p9,p8
+{ .mfi
+(p9) st4 [r33] = GR_SignOfGamma // as 32-bit int
+ fma.s1 FR_A7 = FR_A8,FR_x,FR_A7
+(p13) sub GR_Root = GR_Arg,GR_Root
+}
+{ .mfi
+(p8) st8 [r33] = GR_SignOfGamma // as 64-bit int
+ fma.s1 FR_A5 = FR_A6,FR_x,FR_A5
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_w = FR_Req,f1,f1
+(p13) add GR_Root = GR_Root,GR_Dx
+}
+{ .mfi
+ nop.m 0
+ nop.f 0
+(p13) add GR_2xDx = GR_Dx,GR_Dx
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A3 = FR_A4,FR_x,FR_A3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A1 = FR_A2,FR_x,FR_A1
+(p13) cmp.leu.unc p10,p0 = GR_Root,GR_2xDx
+};;
+{ .mfi
+ nop.m 0
+ frcpa.s1 FR_InvX,p0 = f1,FR_Req
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fms.s1 FR_rx = FR_NormX,f1,FR_Root
+ nop.i 0
+};;
+{ .mfi
+ getf.exp GR_SignExp = FR_Req
+ fma.s1 FR_x4 = FR_x2,FR_x2,f0
+ nop.i 0
+};;
+{ .mfi
+ getf.sig GR_Sig = FR_Req
+ fma.s1 FR_A5 = FR_A7,FR_x2,FR_A5
+ nop.i 0
+};;
+{ .mfi
+ sub GR_PureExp = GR_SignExp,GR_ExpBias
+ fma.s1 FR_w2 = FR_w,FR_w,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Q32 = FR_P3,FR_w,FR_P2
+ nop.i 0
+};;
+{ .mfi
+ setf.sig FR_int_Ln = GR_PureExp
+ fma.s1 FR_A1 = FR_A3,FR_x2,FR_A1
+ extr.u GR_Ind4T = GR_Sig,55,8
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Q10 = FR_P1,FR_w,f1
+ nop.i 0
+};;
+{ .mfi
+ shladd GR_ad_T = GR_Ind4T,3,GR_ad_Data
+ fms.s1 FR_r = FR_InvX,FR_Req,f1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fms.s1 FR_rx2 = FR_rx,FR_rx,f0
+ nop.i 0
+};;
+{ .mfi
+ ldfd FR_T = [GR_ad_T]
+(p10) fma.s1 FR_R2 = FR_R3,FR_rx,FR_R2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_R0 = FR_R1,FR_rx,FR_R0
+ nop.i 0
+};;
+{ .mfi
+ getf.exp GR_Exp = FR_w
+ fma.s1 FR_A1 = FR_A5,FR_x4,FR_A1
+ mov GR_ExpMask = 0x1ffff
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Q32 = FR_Q32, FR_w2,FR_Q10
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r2 = FR_r,FR_r,f0
+ mov GR_fff7 = 0xFFF7
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P32 = FR_P3,FR_r,FR_P2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P10 = FR_P1,FR_r,f1
+ and GR_Exp = GR_ExpMask,GR_Exp
+}
+{ .mfb
+ nop.m 0
+(p10) fma.s.s0 f8 = FR_R2,FR_rx2,FR_R0
+(p10) br.ret.spnt b0 // exit for arguments close to negative roots
+};;
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_N = FR_int_Ln
+ nop.i 0
+}
+{ .mfi
+ cmp.ge p14,p15 = GR_Exp,GR_fff7
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A0 = FR_A1,FR_x,FR_A0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_Ln = FR_Q32,FR_w,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_P32 = FR_P32,FR_r2,FR_P10
+ cmp.eq p6,p7 = 0,GR_Ind
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_T = FR_N,FR_Ln2,FR_T
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_Ln = FR_P32,FR_r,FR_T
+ nop.i 0
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fms.s.s0 f8 = FR_A0,FR_x,FR_Ln
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fms.s.s0 f8 = FR_A0,f1,FR_Ln
+ br.ret.sptk b0
+};;
+
+// branch for calculating of ln(GAMMA(x)) for x < -2^13
+//---------------------------------------------------------------------
+.align 32
+lgammaf_negstirling:
+{ .mfi
+ shladd GR_ad_T = GR_Ind4T,3,GR_ad_Data
+ fms.s1 FR_Xf = FR_NormX,f1,FR_N // xf = x - [x]
+ mov GR_SingBound = 0x10016
+}
+{ .mfi
+ add GR_ad_Co = 0xCA0,GR_ad_Data
+ fma.s1 FR_P32 = FR_P3,FR_r,FR_P2
+ nop.i 0
+};;
+{ .mfi
+ ldfd FR_T = [GR_ad_T]
+ fcvt.xf FR_int_Ln = FR_int_Ln
+ cmp.le p6,p0 = GR_SingBound,GR_Exp
+}
+{ .mfb
+ add GR_ad_Ce = 0x20,GR_ad_Co
+ fma.s1 FR_r2 = FR_r,FR_r,f0
+(p6) br.cond.spnt lgammaf_singularity
+};;
+{ .mfi
+ // load coefficients of polynomial approximation
+ // of ln(sin(Pi*xf)/(Pi*xf)), |xf| <= 0.5
+ ldfpd FR_S16,FR_S14 = [GR_ad_Co],16
+ fma.s1 FR_P10 = FR_P1,FR_r,f1
+ nop.i 0
+}
+{ .mfi
+ ldfpd FR_S12,FR_S10 = [GR_ad_Ce],16
+ fms.s1 FR_xm05 = FR_NormX,f1,FR_05
+ nop.i 0
+};;
+{ .mmi
+ ldfpd FR_S8,FR_S6 = [GR_ad_Co],16
+ ldfpd FR_S4,FR_S2 = [GR_ad_Ce],16
+ nop.i 0
+};;
+{ .mfi
+ getf.sig GR_N = FR_int_Ntrunc // signgam calculation
+ fma.s1 FR_Xf2 = FR_Xf,FR_Xf,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ frcpa.s1 FR_InvXf,p0 = f1,FR_Xf
+ nop.i 0
+};;
+{ .mfi
+ getf.d GR_Arg = FR_Xf
+ fcmp.eq.s1 p6,p0 = FR_NormX,FR_N
+ mov GR_ExpBias = 0x3FF
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_T = FR_int_Ln,FR_Ln2,FR_T
+ extr.u GR_Exp = GR_Arg,52,11
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P32 = FR_P32,FR_r2,FR_P10
+ nop.i 0
+};;
+{ .mfi
+ sub GR_PureExp = GR_Exp,GR_ExpBias
+ fma.s1 FR_S14 = FR_S16,FR_Xf2,FR_S14
+ extr.u GR_Ind4T = GR_Arg,44,8
+}
+{ .mfb
+ mov GR_SignOfGamma = 1 // set signgam to -1
+ fma.s1 FR_S10 = FR_S12,FR_Xf2,FR_S10
+(p6) br.cond.spnt lgammaf_singularity
+};;
+{ .mfi
+ setf.sig FR_int_Ln = GR_PureExp
+ fms.s1 FR_rf = FR_InvXf,FR_Xf,f1
+ // set p14 if GR_N is even
+ tbit.z p14,p0 = GR_N,0
+}
+{ .mfi
+ shladd GR_ad_T = GR_Ind4T,3,GR_ad_Data
+ fma.s1 FR_Xf4 = FR_Xf2,FR_Xf2,f0
+ nop.i 0
+};;
+{ .mfi
+(p14) sub GR_SignOfGamma = r0,GR_SignOfGamma // set signgam to -1
+ fma.s1 FR_S6 = FR_S8,FR_Xf2,FR_S6
+ nop.i 0
+}
+{ .mfi
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+ fma.s1 FR_S2 = FR_S4,FR_Xf2,FR_S2
+ nop.i 0
+};;
+{ .mfi
+ ldfd FR_Tf = [GR_ad_T]
+ fma.s1 FR_Ln = FR_P32,FR_r,FR_T
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_LnSqrt2Pi = FR_LnSqrt2Pi,f1,FR_NormX
+ nop.i 0
+};;
+.pred.rel "mutex",p9,p10
+{ .mfi
+(p9) st4 [r33] = GR_SignOfGamma // as 32-bit int
+ fma.s1 FR_rf2 = FR_rf,FR_rf,f0
+ nop.i 0
+}
+{ .mfi
+(p10) st8 [r33] = GR_SignOfGamma // as 64-bit int
+ fma.s1 FR_S10 = FR_S14,FR_Xf4,FR_S10
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P32f = FR_P3,FR_rf,FR_P2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Xf8 = FR_Xf4,FR_Xf4,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P10f = FR_P1,FR_rf,f1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S2 = FR_S6,FR_Xf4,FR_S2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_Ln = FR_Ln,FR_xm05,FR_LnSqrt2Pi
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_Nf = FR_int_Ln
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S2 = FR_S10,FR_Xf8,FR_S2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Tf = FR_Nf,FR_Ln2,FR_Tf
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P32f = FR_P32f,FR_rf2,FR_P10f // ??????
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_Ln = FR_S2,FR_Xf2,FR_Ln
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Lnf = FR_P32f,FR_rf,FR_Tf
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ fms.s.s0 f8 = FR_Ln,f1,FR_Lnf
+ br.ret.sptk b0
+};;
+// branch for calculating of ln(GAMMA(x)) for -2^13 < x < -9
+//---------------------------------------------------------------------
+.align 32
+lgammaf_negpoly:
+{ .mfi
+ getf.d GR_Arg = FR_Xf
+ frcpa.s1 FR_InvXf,p0 = f1,FR_Xf
+ mov GR_ExpBias = 0x3FF
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Xf2 = FR_Xf,FR_Xf,f0
+ nop.i 0
+};;
+{ .mfi
+ getf.sig GR_N = FR_int_Ntrunc
+ fcvt.xf FR_N = FR_int_Ln
+ mov GR_SignOfGamma = 1
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A9 = FR_A10,FR_x,FR_A9
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P10 = FR_P1,FR_r,f1
+ extr.u GR_Exp = GR_Arg,52,11
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_x4 = FR_x2,FR_x2,f0
+ nop.i 0
+};;
+{ .mfi
+ sub GR_PureExp = GR_Exp,GR_ExpBias
+ fma.s1 FR_A7 = FR_A8,FR_x,FR_A7
+ tbit.z p14,p0 = GR_N,0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A5 = FR_A6,FR_x,FR_A5
+ nop.i 0
+};;
+{ .mfi
+ setf.sig FR_int_Ln = GR_PureExp
+ fma.s1 FR_A3 = FR_A4,FR_x,FR_A3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A1 = FR_A2,FR_x,FR_A1
+(p14) sub GR_SignOfGamma = r0,GR_SignOfGamma
+};;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_rf = FR_InvXf,FR_Xf,f1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Xf4 = FR_Xf2,FR_Xf2,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S14 = FR_S16,FR_Xf2,FR_S14
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S10 = FR_S12,FR_Xf2,FR_S10
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_T = FR_N,FR_Ln2,FR_T
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P32 = FR_P32,FR_r2,FR_P10
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S6 = FR_S8,FR_Xf2,FR_S6
+ extr.u GR_Ind4T = GR_Arg,44,8
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S2 = FR_S4,FR_Xf2,FR_S2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A7 = FR_A9,FR_x2,FR_A7
+ nop.i 0
+}
+{ .mfi
+ shladd GR_ad_T = GR_Ind4T,3,GR_ad_Data
+ fma.s1 FR_A3 = FR_A5,FR_x2,FR_A3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Xf8 = FR_Xf4,FR_Xf4,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rf2 = FR_rf,FR_rf,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P32f = FR_P3,FR_rf,FR_P2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P10f = FR_P1,FR_rf,f1
+ nop.i 0
+};;
+{ .mfi
+ ldfd FR_Tf = [GR_ad_T]
+ fma.s1 FR_Ln = FR_P32,FR_r,FR_T
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A0 = FR_A1,FR_x,FR_A0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S10 = FR_S14,FR_Xf4,FR_S10
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S2 = FR_S6,FR_Xf4,FR_S2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_Nf = FR_int_Ln
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A3 = FR_A7,FR_x4,FR_A3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fcmp.eq.s1 p13,p0 = FR_NormX,FR_Ntrunc
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_x3 = FR_x2,FR_x,f0 // -x^3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P32f = FR_P32f,FR_rf2,FR_P10f
+ nop.i 0
+};;
+{ .mfb
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+ fma.s1 FR_S2 = FR_S10,FR_Xf8,FR_S2
+(p13) br.cond.spnt lgammaf_singularity
+};;
+.pred.rel "mutex",p9,p10
+{ .mmf
+(p9) st4 [r33] = GR_SignOfGamma // as 32-bit int
+(p10) st8 [r33] = GR_SignOfGamma // as 64-bit int
+ fms.s1 FR_A0 = FR_A3,FR_x3,FR_A0 // -A3*x^3-A0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Tf = FR_Nf,FR_Ln2,FR_Tf
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Ln = FR_S2,FR_Xf2,FR_Ln // S2*Xf^2+Ln
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Lnf = FR_P32f,FR_rf,FR_Tf
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_Ln = FR_A0,f1,FR_Ln
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ fms.s.s0 f8 = FR_Ln,f1,FR_Lnf
+ br.ret.sptk b0
+};;
+// branch for handling +/-0, NaT, QNaN, +/-INF and denormalised numbers
+//---------------------------------------------------------------------
+.align 32
+lgammaf_spec:
+{ .mfi
+ getf.exp GR_SignExp = FR_NormX
+ fclass.m p6,p0 = f8,0x21 // is arg +INF?
+ mov GR_SignOfGamma = 1 // set signgam to 1
+};;
+{ .mfi
+ getf.sig GR_Sig = FR_NormX
+ fclass.m p7,p0 = f8,0xB // is x deno?
+ // set p11 if signgum is 32-bit int
+ // set p12 if signgum is 64-bit int
+ cmp.eq p12,p11 = 8,r34
+};;
+.pred.rel "mutex",p11,p12
+{ .mfi
+ // store sign of gamma(x) as 32-bit int
+(p11) st4 [r33] = GR_SignOfGamma
+ fclass.m p8,p0 = f8,0x1C0 // is arg NaT or NaN?
+ dep.z GR_Ind = GR_SignExp,3,4
+}
+{ .mib
+ // store sign of gamma(x) as 64-bit int
+(p12) st8 [r33] = GR_SignOfGamma
+ and GR_Exp = GR_ExpMask,GR_SignExp
+(p6) br.ret.spnt b0 // exit for +INF
+};;
+{ .mfi
+ sub GR_PureExp = GR_Exp,GR_ExpBias
+ fclass.m p9,p0 = f8,0x22 // is arg -INF?
+ extr.u GR_Ind4T = GR_Sig,55,8
+}
+{ .mfb
+ nop.m 0
+(p7) fma.s0 FR_tmp = f1,f1,f8
+(p7) br.cond.sptk lgammaf_core
+};;
+{ .mfb
+ nop.m 0
+(p8) fms.s.s0 f8 = f8,f1,f8
+(p8) br.ret.spnt b0 // exit for NaT and NaN
+};;
+{ .mfb
+ nop.m 0
+(p9) fmerge.s f8 = f1,f8
+(p9) br.ret.spnt b0 // exit -INF
+};;
+// branch for handling negative integers and +/-0
+//---------------------------------------------------------------------
+.align 32
+lgammaf_singularity:
+{ .mfi
+ mov GR_SignOfGamma = 1 // set signgam to 1
+ fclass.m p6,p0 = f8,0x6 // is x -0?
+ mov GR_TAG = 109 // negative
+}
+{ .mfi
+ mov GR_ad_SignGam = r33
+ fma.s1 FR_X = f0,f0,f8
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ frcpa.s0 f8,p0 = f1,f0
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+}
+{ .mib
+ nop.m 0
+(p6) sub GR_SignOfGamma = r0,GR_SignOfGamma
+ br.cond.sptk lgammaf_libm_err
+};;
+// overflow (x > OVERFLOV_BOUNDARY)
+//---------------------------------------------------------------------
+.align 32
+lgammaf_overflow:
+{ .mfi
+ nop.m 0
+ nop.f 0
+ mov r8 = 0x1FFFE
+};;
+{ .mfi
+ setf.exp f9 = r8
+ fmerge.s FR_X = f8,f8
+ mov GR_TAG = 108 // overflow
+};;
+{ .mfi
+ mov GR_ad_SignGam = r33
+ nop.f 0
+ // set p9 if signgum is 32-bit int
+ // set p10 if signgum is 64-bit int
+ cmp.eq p10,p9 = 8,r34
+}
+{ .mfi
+ nop.m 0
+ fma.s.s0 f8 = f9,f9,f0 // Set I,O and +INF result
+ nop.i 0
+};;
+// gate to __libm_error_support#
+//---------------------------------------------------------------------
+.align 32
+lgammaf_libm_err:
+{ .mmi
+ alloc r32 = ar.pfs,1,4,4,0
+ mov GR_Parameter_TAG = GR_TAG
+ nop.i 0
+};;
+.pred.rel "mutex",p9,p10
+{ .mmi
+ // store sign of gamma(x) as 32-bit int
+(p9) st4 [GR_ad_SignGam] = GR_SignOfGamma
+ // store sign of gamma(x) as 64-bit int
+(p10) st8 [GR_ad_SignGam] = GR_SignOfGamma
+ nop.i 0
+};;
+GLOBAL_LIBM_END(__libm_lgammaf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_X // STORE Parameter 1
+ // on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3
+ // on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling
+ // function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/libm_lgammal.S b/libc/sysdeps/ia64/fpu/libm_lgammal.S
new file mode 100644
index 000000000..407b3452c
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_lgammal.S
@@ -0,0 +1,7678 @@
+.file "libm_lgammal.s"
+
+
+// Copyright (c) 2002 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING,BUT NOT
+// LIMITED TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code,and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 03/28/02 Original version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 08/21/02 Added support of SIGN(GAMMA(x)) calculation
+// 09/26/02 Algorithm description improved
+// 10/21/02 Now it returns SIGN(GAMMA(x))=-1 for negative zero
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 03/31/05 Reformatted delimiters between data tables
+//
+//*********************************************************************
+//
+// Function: __libm_lgammal(long double x, int* signgam, int szsigngam)
+// computes the principal value of the logarithm of the GAMMA function
+// of x. Signum of GAMMA(x) is stored to memory starting at the address
+// specified by the signgam.
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f9-f15
+// f32-f127
+//
+// General Purpose Registers:
+// r2, r3, r8-r11, r14-r31
+// r32-r65
+// r66-r69 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6-p15
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// __libm_lgammal(+inf) = +inf
+// __libm_lgammal(-inf) = QNaN
+// __libm_lgammal(+/-0) = +inf
+// __libm_lgammal(x<0, x - integer) = QNaN
+// __libm_lgammal(SNaN) = QNaN
+// __libm_lgammal(QNaN) = QNaN
+//
+//*********************************************************************
+//
+// ALGORITHM DESCRIPTION
+//
+// Below we suppose that there is log(z) function which takes an long
+// double argument and returns result as a pair of long double numbers
+// lnHi and lnLo (such that sum lnHi + lnLo provides ~80 correct bits
+// of significand). Algorithm description for such log(z) function
+// see below.
+// Also, it this algorithm description we use the following notational
+// conventions:
+// a) pair A = (Ahi, Alo) means number A represented as sum of Ahi and Alo
+// b) C = A + B = (Ahi, Alo) + (Bhi, Blo) means multi-precision addition.
+// The result would be C = (Chi, Clo). Notice, that Clo shouldn't be
+// equal to Alo + Blo
+// c) D = A*B = (Ahi, Alo)*(Bhi, Blo) = (Dhi, Dlo) multi-precisiion
+// multiplication.
+//
+// So, lgammal has the following computational paths:
+// 1) |x| < 0.5
+// P = A1*|x| + A2*|x|^2 + ... + A22*|x|^22
+// A1, A2, A3 represented as a sum of two double precision
+// numbers and multi-precision computations are used for 3 higher
+// terms of the polynomial. We get polynomial as a sum of two
+// double extended numbers: P = (Phi, Plo)
+// 1.1) x > 0
+// lgammal(x) = P - log(|x|) = (Phi, Plo) - (lnHi(|x|), lnLo(|x|))
+// 1.2) x < 0
+// lgammal(x) = -P - log(|x|) - log(sin(Pi*x)/(Pi*x))
+// P and log(|x|) are computed by the same way as in 1.1;
+// - log(sin(Pi*x)/(Pi*x)) is approximated by a polynomial Plnsin.
+// Plnsin:= fLnSin2*|x|^2 + fLnSin4*|x|^4 + ... + fLnSin36*|x|^36
+// The first coefficient of Plnsin is represented as sum of two
+// double precision numbers (fLnSin2, fLnSin2L). Multi-precision
+// computations for higher two terms of Plnsin are used.
+// So, the final result is reconstructed by the following formula
+// lgammal(x) = (-(Phi, Plo) - (lnHi(|x|), lnLo(|x|))) -
+// - (PlnsinHi,PlnsinLo)
+//
+// 2) 0.5 <= x < 0.75 -> t = x - 0.625
+// -0.75 < x <= -0.5 -> t = x + 0.625
+// 2.25 <= x < 4.0 -> t = x/2 - 1.5
+// 4.0 <= x < 8.0 -> t = x/4 - 1.5
+// -0.5 < x <= -0.40625 -> t = x + 0.5
+// -2.6005859375 < x <= -2.5 -> t = x + 2.5
+// 1.3125 <= x < 1.5625 -> t = x - LOC_MIN, where LOC_MIN is point in
+// which lgammal has local minimum. Exact
+// value can be found in the table below,
+// approximate value is ~1.46
+//
+// lgammal(x) is approximated by the polynomial of 25th degree: P25(t)
+// P25(t) = A0 + A1*t + ... + A25*t^25 = (Phi, Plo) + t^4*P21(t),
+// where
+// (Phi, Plo) is sum of four highest terms of the polynomial P25(t):
+// (Phi, Plo) = ((A0, A0L) + (A1, A1L)*t) + t^2 *((A2, A2L) + (A3, A3L)*t),
+// (Ai, AiL) - coefficients represented as pairs of DP numbers.
+//
+// P21(t) = (PolC(t)*t^8 + PolD(t))*t^8 + PolE(t),
+// where
+// PolC(t) = C21*t^5 + C20*t^4 + ... + C16,
+// C21 = A25, C20 = A24, ..., C16 = A20
+//
+// PolD(t) = D7*t^7 + D6*t^6 + ... + D0,
+// D7 = A19, D6 = A18, ..., D0 = A12
+//
+// PolE(t) = E7*t^7 + E6*t^6 + ... + E0,
+// E7 = A11, E6 = A10, ..., E0 = A4
+//
+// Cis and Dis are represented as double precision numbers,
+// Eis are represented as double extended numbers.
+//
+// 3) 0.75 <= x < 1.3125 -> t = x - 1.0
+// 1.5625 <= x < 2.25 -> t = x - 2.0
+// lgammal(x) is approximated by the polynomial of 25th degree: P25(t)
+// P25(t) = A1*t + ... + A25*t^25, and computations are carried out
+// by similar way as in the previous case
+//
+// 4) 10.0 < x <= Overflow Bound ("positive Sterling" range)
+// lgammal(x) is approximated using Sterling's formula:
+// lgammal(x) ~ ((x*(lnHi(x) - 1, lnLo(x))) - 0.5*(lnHi(x), lnLo(x))) +
+// + ((Chi, Clo) + S(1/x))
+// where
+// C = (Chi, Clo) - pair of double precision numbers representing constant
+// 0.5*ln(2*Pi);
+// S(1/x) = 1/x * (B2 + B4*(1/x)^2 + ... + B20*(1/x)^18), B2, ..., B20 are
+// Bernulli numbers. S is computed in native precision and then added to
+// Clo;
+// lnHi(x) - 1 is computed in native precision and the multiprecision
+// multiplication (x, 0) *(lnHi(x) - 1, lnLo(x)) is used.
+//
+// 5) -INF < x <= -2^63, any negative integer < 0
+// All numbers in this range are integers -> error handler is called
+//
+// 6) -2^63 < x <= -0.75 ("negative Sterling" range), x is "far" from root,
+// lgammal(-t) for positive t is approximated using the following formula:
+// lgammal(-t) = -lgammal(t)-log(t)-log(|dT|)+log(sin(Pi*|dT|)/(Pi*|dT|))
+// where dT = -t -round_to_nearest_integer(-t)
+// Last item is approximated by the same polynomial as described in 1.2.
+// We split the whole range into three subranges due to different ways of
+// approximation of the first terms.
+// 6.1) -2^63 < x < -6.0 ("negative Sterling" range)
+// lgammal(t) is approximated exactly as in #4. The only difference that
+// for -13.0 < x < -6.0 subrange instead of Bernulli numbers we use their
+// minimax approximation on this range.
+// log(t), log(|dT|) are approximated by the log routine mentioned above.
+// 6.2) -6.0 < x <= -0.75, |x + 1|> 2^(-7)
+// log(t), log(|dT|) are approximated by the log routine mentioned above,
+// lgammal(t) is approximated by polynomials of the 25th degree similar
+// to ones from #2. Arguments z of the polynomials are as follows
+// a) 0.75 <= t < 1.0 - 2^(-7), z = 2*t - 1.5
+// b) 1.0 - 2^(-7) < t < 2.0, z = t - 1.5
+// c) 2.0 < t < 3.0, z = t/2 - 1.5
+// d) 3.0 < t < 4.0, z = t/2 - 1.5. Notice, that range reduction is
+// the same as in case c) but the set of coefficients is different
+// e) 4.0 < t < 6.0, z = t/4 - 1.5
+// 6.3) |x + 1| <= 2^(-7)
+// log(1 + (x-1)) is approximated by Taylor series,
+// log(sin(Pi*|dT|)/(Pi*|dT|)) is still approximated by polynomial but
+// it has just 4th degree.
+// log(|dT|) is approximated by the log routine mentioned above.
+// lgammal(-x) is approximated by polynomial of 8th degree from (-x + 1).
+//
+// 7) -20.0 < x < -2.0, x falls in root "neighbourhood".
+// "Neighbourhood" means that |lgammal(x)| < epsilon, where epsilon is
+// different for every root (and it is stored in the table), but typically
+// it is ~ 0.15. There are 35 roots significant from "double extended"
+// point of view. We split all the roots into two subsets: "left" and "right"
+// roots. Considering [-(N+1), -N] range we call root as "left" one if it
+// lies closer to -(N+1) and "right" otherwise. There is no "left" root in
+// the [-20, -19] range (it exists, but is insignificant for double extended
+// precision). To determine if x falls in root "neighbourhood" we store
+// significands of all the 35 roots as well as epsilon values (expressed
+// by the left and right bound).
+// In these ranges we approximate lgammal(x) by polynomial series of 19th
+// degree:
+// lgammal(x) = P19(t) = A0 + A1*t + ...+ A19*t^19, where t = x - EDP_Root,
+// EDP_Root is the exact value of the corresponding root rounded to double
+// extended precision. So, we have 35 different polynomials which make our
+// table rather big. We may hope that x falls in root "neighbourhood"
+// quite rarely -> ther might be no need in frequent use of different
+// polynomials.
+// A0, A1, A2, A3 are represented as pairs of double precision numbers,
+// A4, A5 are long doubles, and to decrease the size of the table we
+// keep the rest of coefficients in just double precision
+//
+//*********************************************************************
+// Algorithm for log(X) = (lnHi(X), lnLo(X))
+//
+// ALGORITHM
+//
+// Here we use a table lookup method. The basic idea is that in
+// order to compute logl(Arg) for an argument Arg in [1,2), we
+// construct a value G such that G*Arg is close to 1 and that
+// logl(1/G) is obtainable easily from a table of values calculated
+// beforehand. Thus
+//
+// logl(Arg) = logl(1/G) + logl(G*Arg)
+// = logl(1/G) + logl(1 + (G*Arg - 1))
+//
+// Because |G*Arg - 1| is small, the second term on the right hand
+// side can be approximated by a short polynomial. We elaborate
+// this method in four steps.
+//
+// Step 0: Initialization
+//
+// We need to calculate logl( X ). Obtain N, S_hi such that
+//
+// X = 2^N * S_hi exactly
+//
+// where S_hi in [1,2)
+//
+// Step 1: Argument Reduction
+//
+// Based on S_hi, obtain G_1, G_2, G_3 from a table and calculate
+//
+// G := G_1 * G_2 * G_3
+// r := (G * S_hi - 1)
+//
+// These G_j's have the property that the product is exactly
+// representable and that |r| < 2^(-12) as a result.
+//
+// Step 2: Approximation
+//
+//
+// logl(1 + r) is approximated by a short polynomial poly(r).
+//
+// Step 3: Reconstruction
+//
+//
+// Finally, logl( X ) is given by
+//
+// logl( X ) = logl( 2^N * S_hi )
+// ~=~ N*logl(2) + logl(1/G) + logl(1 + r)
+// ~=~ N*logl(2) + logl(1/G) + poly(r).
+//
+// IMPLEMENTATION
+//
+// Step 0. Initialization
+// ----------------------
+//
+// Z := X
+// N := unbaised exponent of Z
+// S_hi := 2^(-N) * Z
+//
+// Step 1. Argument Reduction
+// --------------------------
+//
+// Let
+//
+// Z = 2^N * S_hi = 2^N * 1.d_1 d_2 d_3 ... d_63
+//
+// We obtain G_1, G_2, G_3 by the following steps.
+//
+//
+// Define X_0 := 1.d_1 d_2 ... d_14. This is extracted
+// from S_hi.
+//
+// Define A_1 := 1.d_1 d_2 d_3 d_4. This is X_0 truncated
+// to lsb = 2^(-4).
+//
+// Define index_1 := [ d_1 d_2 d_3 d_4 ].
+//
+// Fetch Z_1 := (1/A_1) rounded UP in fixed point with
+// fixed point lsb = 2^(-15).
+// Z_1 looks like z_0.z_1 z_2 ... z_15
+// Note that the fetching is done using index_1.
+// A_1 is actually not needed in the implementation
+// and is used here only to explain how is the value
+// Z_1 defined.
+//
+// Fetch G_1 := (1/A_1) truncated to 21 sig. bits.
+// floating pt. Again, fetching is done using index_1. A_1
+// explains how G_1 is defined.
+//
+// Calculate X_1 := X_0 * Z_1 truncated to lsb = 2^(-14)
+// = 1.0 0 0 0 d_5 ... d_14
+// This is accomplised by integer multiplication.
+// It is proved that X_1 indeed always begin
+// with 1.0000 in fixed point.
+//
+//
+// Define A_2 := 1.0 0 0 0 d_5 d_6 d_7 d_8. This is X_1
+// truncated to lsb = 2^(-8). Similar to A_1,
+// A_2 is not needed in actual implementation. It
+// helps explain how some of the values are defined.
+//
+// Define index_2 := [ d_5 d_6 d_7 d_8 ].
+//
+// Fetch Z_2 := (1/A_2) rounded UP in fixed point with
+// fixed point lsb = 2^(-15). Fetch done using index_2.
+// Z_2 looks like z_0.z_1 z_2 ... z_15
+//
+// Fetch G_2 := (1/A_2) truncated to 21 sig. bits.
+// floating pt.
+//
+// Calculate X_2 := X_1 * Z_2 truncated to lsb = 2^(-14)
+// = 1.0 0 0 0 0 0 0 0 d_9 d_10 ... d_14
+// This is accomplised by integer multiplication.
+// It is proved that X_2 indeed always begin
+// with 1.00000000 in fixed point.
+//
+//
+// Define A_3 := 1.0 0 0 0 0 0 0 0 d_9 d_10 d_11 d_12 d_13 1.
+// This is 2^(-14) + X_2 truncated to lsb = 2^(-13).
+//
+// Define index_3 := [ d_9 d_10 d_11 d_12 d_13 ].
+//
+// Fetch G_3 := (1/A_3) truncated to 21 sig. bits.
+// floating pt. Fetch is done using index_3.
+//
+// Compute G := G_1 * G_2 * G_3.
+//
+// This is done exactly since each of G_j only has 21 sig. bits.
+//
+// Compute
+//
+// r := (G*S_hi - 1)
+//
+//
+// Step 2. Approximation
+// ---------------------
+//
+// This step computes an approximation to logl( 1 + r ) where r is the
+// reduced argument just obtained. It is proved that |r| <= 1.9*2^(-13);
+// thus logl(1+r) can be approximated by a short polynomial:
+//
+// logl(1+r) ~=~ poly = r + Q1 r^2 + ... + Q4 r^5
+//
+//
+// Step 3. Reconstruction
+// ----------------------
+//
+// This step computes the desired result of logl(X):
+//
+// logl(X) = logl( 2^N * S_hi )
+// = N*logl(2) + logl( S_hi )
+// = N*logl(2) + logl(1/G) +
+// logl(1 + G*S_hi - 1 )
+//
+// logl(2), logl(1/G_j) are stored as pairs of (single,double) numbers:
+// log2_hi, log2_lo, log1byGj_hi, log1byGj_lo. The high parts are
+// single-precision numbers and the low parts are double precision
+// numbers. These have the property that
+//
+// N*log2_hi + SUM ( log1byGj_hi )
+//
+// is computable exactly in double-extended precision (64 sig. bits).
+// Finally
+//
+// lnHi(X) := N*log2_hi + SUM ( log1byGj_hi )
+// lnLo(X) := poly_hi + [ poly_lo +
+// ( SUM ( log1byGj_lo ) + N*log2_lo ) ]
+//
+//
+//*********************************************************************
+// General Purpose Registers
+// scratch registers
+rPolDataPtr = r2
+rLnSinDataPtr = r3
+rExpX = r8
+rSignifX = r9
+rDelta = r10
+rSignExpX = r11
+GR_ad_z_1 = r14
+r17Ones = r15
+GR_Index1 = r16
+rSignif1andQ = r17
+GR_X_0 = r18
+GR_X_1 = r19
+GR_X_2 = r20
+GR_Z_1 = r21
+GR_Z_2 = r22
+GR_N = r23
+rExpHalf = r24
+rExp8 = r25
+rX0Dx = r25
+GR_ad_tbl_1 = r26
+GR_ad_tbl_2 = r27
+GR_ad_tbl_3 = r28
+GR_ad_q = r29
+GR_ad_z_1 = r30
+GR_ad_z_2 = r31
+// stacked registers
+rPFS_SAVED = r32
+GR_ad_z_3 = r33
+rSgnGamAddr = r34
+rSgnGamSize = r35
+rLogDataPtr = r36
+rZ1offsett = r37
+rTmpPtr = r38
+rTmpPtr2 = r39
+rTmpPtr3 = r40
+rExp2 = r41
+rExp2tom7 = r42
+rZ625 = r42
+rExpOne = r43
+rNegSingularity = r44
+rXint = r45
+rTbl1Addr = r46
+rTbl2Addr = r47
+rTbl3Addr = r48
+rZ2Addr = r49
+rRootsAddr = r50
+rRootsBndAddr = r51
+rRoot = r52
+rRightBound = r53
+rLeftBound = r54
+rSignifDx = r55
+rBernulliPtr = r56
+rLnSinTmpPtr = r56
+rIndex1Dx = r57
+rIndexPol = r58
+GR_Index3 = r59
+GR_Index2 = r60
+rSgnGam = r61
+rXRnd = r62
+
+GR_SAVE_B0 = r63
+GR_SAVE_GP = r64
+GR_SAVE_PFS = r65
+// output parameters when calling error handling routine
+GR_Parameter_X = r66
+GR_Parameter_Y = r67
+GR_Parameter_RESULT = r68
+GR_Parameter_TAG = r69
+
+//********************************************************************
+// Floating Point Registers
+// CAUTION: due to the lack of registers there exist (below in the code)
+// sometimes "unconventional" use of declared registers
+//
+fAbsX = f6
+fDelX4 = f6
+fSignifX = f7
+// macros for error handling routine
+FR_X = f10 // first argument
+FR_Y = f1 // second argument (lgammal has just one)
+FR_RESULT = f8 // result
+
+// First 7 Bernulli numbers
+fB2 = f9
+fLnDeltaL = f9
+fXSqr = f9
+fB4 = f10
+fX4 = f10
+fB6 = f11
+fX6 = f11
+fB8 = f12
+fXSqrL = f12
+fB10 = f13
+fRes7H = f13
+fB12 = f14
+fRes7L = f14
+fB14 = f15
+
+// stack registers
+// Polynomial coefficients: A0, ..., A25
+fA0 = f32
+fA0L = f33
+fInvXL = f33
+fA1 = f34
+fA1L = f35
+fA2 = f36
+fA2L = f37
+fA3 = f38
+fA3L = f39
+fA4 = f40
+fA4L = f41
+fRes6H = f41
+fA5 = f42
+fB2L = f42
+fA5L = f43
+fMinNegStir = f43
+fRes6L = f43
+fA6 = f44
+fMaxNegStir = f44
+fA7 = f45
+fLnDeltaH = f45
+fA8 = f46
+fBrnL = f46
+fA9 = f47
+fBrnH = f47
+fA10 = f48
+fRes5L = f48
+fA11 = f49
+fRes5H = f49
+fA12 = f50
+fDx6 = f50
+fA13 = f51
+fDx8 = f51
+fA14 = f52
+fDx4 = f52
+fA15 = f53
+fYL = f53
+fh3Dx = f53
+fA16 = f54
+fYH = f54
+fH3Dx = f54
+fA17 = f55
+fResLnDxL = f55
+fG3Dx = f55
+fA18 = f56
+fResLnDxH = f56
+fh2Dx = f56
+fA19 = f57
+fFloatNDx = f57
+fA20 = f58
+fPolyHiDx = f58
+fhDx = f58
+fA21 = f59
+fRDxCub = f59
+fHDx = f59
+fA22 = f60
+fRDxSq = f60
+fGDx = f60
+fA23 = f61
+fPolyLoDx = f61
+fInvX3 = f61
+fA24 = f62
+fRDx = f62
+fInvX8 = f62
+fA25 = f63
+fInvX4 = f63
+fPol = f64
+fPolL = f65
+// Coefficients of ln(sin(Pi*x)/Pi*x)
+fLnSin2 = f66
+fLnSin2L = f67
+fLnSin4 = f68
+fLnSin6 = f69
+fLnSin8 = f70
+fLnSin10 = f71
+fLnSin12 = f72
+fLnSin14 = f73
+fLnSin16 = f74
+fLnSin18 = f75
+fDelX8 = f75
+fLnSin20 = f76
+fLnSin22 = f77
+fDelX6 = f77
+fLnSin24 = f78
+fLnSin26 = f79
+fLnSin28 = f80
+fLnSin30 = f81
+fhDelX = f81
+fLnSin32 = f82
+fLnSin34 = f83
+fLnSin36 = f84
+fXint = f85
+fDxSqr = f85
+fRes3L = f86
+fRes3H = f87
+fRes4H = f88
+fRes4L = f89
+fResH = f90
+fResL = f91
+fDx = f92
+FR_MHalf = f93
+fRes1H = f94
+fRes1L = f95
+fRes2H = f96
+fRes2L = f97
+FR_FracX = f98
+fRcpX = f99
+fLnSinH = f99
+fTwo = f100
+fMOne = f100
+FR_G = f101
+FR_H = f102
+FR_h = f103
+FR_G2 = f104
+FR_H2 = f105
+FR_poly_lo = f106
+FR_poly_hi = f107
+FR_h2 = f108
+FR_rsq = f109
+FR_r = f110
+FR_log2_hi = f111
+FR_log2_lo = f112
+fFloatN = f113
+FR_Q4 = f114
+FR_G3 = f115
+FR_H3 = f116
+FR_h3 = f117
+FR_Q3 = f118
+FR_Q2 = f119
+FR_Q1 = f120
+fThirteen = f121
+fSix = f121
+FR_rcub = f121
+// Last three Bernulli numbers
+fB16 = f122
+fB18 = f123
+fB20 = f124
+fInvX = f125
+fLnSinL = f125
+fDxSqrL = f126
+fFltIntX = f126
+fRoot = f127
+fNormDx = f127
+
+// Data tables
+//==============================================================
+RODATA
+// ************* DO NOT CHANGE THE ORDER OF THESE TABLES *************
+.align 16
+LOCAL_OBJECT_START(lgammal_right_roots_data)
+// List of all right roots themselves
+data8 0x9D3FE4B007C360AB, 0x0000C000 // Range [-3, -2]
+data8 0xC9306DE4F2CD7BEE, 0x0000C000 // Range [-4, -3]
+data8 0x814273C2CCAC0618, 0x0000C001 // Range [-5, -4]
+data8 0xA04352BF85B6C865, 0x0000C001 // Range [-6, -5]
+data8 0xC00B592C4BE4676C, 0x0000C001 // Range [-7, -6]
+data8 0xE0019FEF6FF0F5BF, 0x0000C001 // Range [-8, -7]
+data8 0x80001A01459FC9F6, 0x0000C002 // Range [-9, -8]
+data8 0x900002E3BB47D86D, 0x0000C002 // Range [-10, -9]
+data8 0xA0000049F93BB992, 0x0000C002 // Range [-11, -10]
+data8 0xB0000006B9915316, 0x0000C002 // Range [-12, -11]
+data8 0xC00000008F76C773, 0x0000C002 // Range [-13, -12]
+data8 0xD00000000B09230A, 0x0000C002 // Range [-14, -13]
+data8 0xE000000000C9CBA5, 0x0000C002 // Range [-15, -14]
+data8 0xF0000000000D73FA, 0x0000C002 // Range [-16, -15]
+data8 0x8000000000006BA0, 0x0000C003 // Range [-17, -16]
+data8 0x8800000000000655, 0x0000C003 // Range [-18, -17]
+data8 0x900000000000005A, 0x0000C003 // Range [-19, -18]
+data8 0x9800000000000005, 0x0000C003 // Range [-20, -19]
+// List of bounds of ranges with special polynomial approximation near root
+// Only significands of bounds are actually stored
+data8 0xA000000000000000, 0x9800000000000000 // Bounds for root on [-3, -2]
+data8 0xCAB88035C5EFBB41, 0xC7E05E31F4B02115 // Bounds for root on [-4, -3]
+data8 0x817831B899735C72, 0x8114633941B8053A // Bounds for root on [-5, -4]
+data8 0xA04E8B34C6AA9476, 0xA039B4A42978197B // Bounds for root on [-6, -5]
+data8 0xC00D3D5E588A78A9, 0xC009BA25F7E858A6 // Bounds for root on [-7, -6]
+data8 0xE001E54202991EB4, 0xE001648416CE897F // Bounds for root on [-8, -7]
+data8 0x80001E56D13A6B9F, 0x8000164A3BAD888A // Bounds for root on [-9, -8]
+data8 0x9000035F0529272A, 0x9000027A0E3D94F0 // Bounds for root on [-10, -9]
+data8 0xA00000564D705880, 0xA000003F67EA0CC7 // Bounds for root on [-11, -10]
+data8 0xB0000007D87EE0EF, 0xB0000005C3A122A5 // Bounds for root on [-12, -11]
+data8 0xC0000000A75FE8B1, 0xC00000007AF818AC // Bounds for root on [-13, -12]
+data8 0xD00000000CDFFE36, 0xD000000009758BBF // Bounds for root on [-14, -13]
+data8 0xE000000000EB6D96, 0xE000000000ACF7B2 // Bounds for root on [-15, -14]
+data8 0xF0000000000FB1F9, 0xF0000000000B87FB // Bounds for root on [-16, -15]
+data8 0x8000000000007D90, 0x8000000000005C40 // Bounds for root on [-17, -16]
+data8 0x8800000000000763, 0x880000000000056D // Bounds for root on [-18, -17]
+data8 0x9000000000000069, 0x900000000000004D // Bounds for root on [-19, -18]
+data8 0x9800000000000006, 0x9800000000000005 // Bounds for root on [-20, -19]
+// List of all left roots themselves
+data8 0xAFDA0850DEC8065E, 0x0000C000 // Range [-3, -2]
+data8 0xFD238AA3E17F285C, 0x0000C000 // Range [-4, -3]
+data8 0x9FBABBD37757E6A2, 0x0000C001 // Range [-5, -4]
+data8 0xBFF497AC8FA06AFC, 0x0000C001 // Range [-6, -5]
+data8 0xDFFE5FBB5C377FE8, 0x0000C001 // Range [-7, -6]
+data8 0xFFFFCBFC0ACE7879, 0x0000C001 // Range [-8, -7]
+data8 0x8FFFFD1C425E8100, 0x0000C002 // Range [-9, -8]
+data8 0x9FFFFFB606BDFDCD, 0x0000C002 // Range [-10, -9]
+data8 0xAFFFFFF9466E9F1B, 0x0000C002 // Range [-11, -10]
+data8 0xBFFFFFFF70893874, 0x0000C002 // Range [-12, -11]
+data8 0xCFFFFFFFF4F6DCF6, 0x0000C002 // Range [-13, -12]
+data8 0xDFFFFFFFFF36345B, 0x0000C002 // Range [-14, -13]
+data8 0xEFFFFFFFFFF28C06, 0x0000C002 // Range [-15, -14]
+data8 0xFFFFFFFFFFFF28C0, 0x0000C002 // Range [-16, -15]
+data8 0x87FFFFFFFFFFF9AB, 0x0000C003 // Range [-17, -16]
+data8 0x8FFFFFFFFFFFFFA6, 0x0000C003 // Range [-18, -17]
+data8 0x97FFFFFFFFFFFFFB, 0x0000C003 // Range [-19, -18]
+data8 0x0000000000000000, 0x00000000 // pad to keep logic in the main path
+// List of bounds of ranges with special polynomial approximation near root
+// Only significands of bounds are actually stored
+data8 0xB235880944CC758E, 0xADD2F1A9FBE76C8B // Bounds for root on [-3, -2]
+data8 0xFD8E7844F307B07C, 0xFCA655C2152BDE4D // Bounds for root on [-4, -3]
+data8 0x9FC4D876EE546967, 0x9FAEE4AF68BC4292 // Bounds for root on [-5, -4]
+data8 0xBFF641FFBFCC44F1, 0xBFF2A47919F4BA89 // Bounds for root on [-6, -5]
+data8 0xDFFE9C803DEFDD59, 0xDFFE18932EB723FE // Bounds for root on [-7, -6]
+data8 0xFFFFD393FA47AFC3, 0xFFFFC317CF638AE1 // Bounds for root on [-8, -7]
+data8 0x8FFFFD8840279925, 0x8FFFFC9DCECEEE92 // Bounds for root on [-9, -8]
+data8 0x9FFFFFC0D34E2AF8, 0x9FFFFFA9619AA3B7 // Bounds for root on [-10, -9]
+data8 0xAFFFFFFA41C18246, 0xAFFFFFF82025A23C // Bounds for root on [-11, -10]
+data8 0xBFFFFFFF857ACB4E, 0xBFFFFFFF58032378 // Bounds for root on [-12, -11]
+data8 0xCFFFFFFFF6934AB8, 0xCFFFFFFFF313EF0A // Bounds for root on [-13, -12]
+data8 0xDFFFFFFFFF53A9E9, 0xDFFFFFFFFF13B5A5 // Bounds for root on [-14, -13]
+data8 0xEFFFFFFFFFF482CB, 0xEFFFFFFFFFF03F4F // Bounds for root on [-15, -14]
+data8 0xFFFFFFFFFFFF482D, 0xFFFFFFFFFFFF03F5 // Bounds for root on [-16, -15]
+data8 0x87FFFFFFFFFFFA98, 0x87FFFFFFFFFFF896 // Bounds for root on [-17, -16]
+data8 0x8FFFFFFFFFFFFFB3, 0x8FFFFFFFFFFFFF97 // Bounds for root on [-18, -17]
+data8 0x97FFFFFFFFFFFFFC, 0x97FFFFFFFFFFFFFB // Bounds for root on [-19, -18]
+LOCAL_OBJECT_END(lgammal_right_roots_data)
+
+LOCAL_OBJECT_START(lgammal_0_Half_data)
+// Polynomial coefficients for the lgammal(x), 0.0 < |x| < 0.5
+data8 0xBFD9A4D55BEAB2D6, 0xBC8AA3C097746D1F //A3
+data8 0x3FEA51A6625307D3, 0x3C7180E7BD2D0DCC //A2
+data8 0xBFE2788CFC6FB618, 0xBC9E9346C4692BCC //A1
+data8 0x8A8991563EC1BD13, 0x00003FFD //A4
+data8 0xD45CE0BD52C27EF2, 0x0000BFFC //A5
+data8 0xADA06587FA2BBD47, 0x00003FFC //A6
+data8 0x9381D0ED2194902A, 0x0000BFFC //A7
+data8 0x80859B3CF92D4192, 0x00003FFC //A8
+data8 0xE4033517C622A946, 0x0000BFFB //A9
+data8 0xCD00CE67A51FC82A, 0x00003FFB //A10
+data8 0xBA44E2A96C3B5700, 0x0000BFFB //A11
+data8 0xAAAD008FA46DBD99, 0x00003FFB //A12
+data8 0x9D604AC65A41153D, 0x0000BFFB //A13
+data8 0x917CECB864B5A861, 0x00003FFB //A14
+data8 0x85A4810EB730FDE4, 0x0000BFFB //A15
+data8 0xEF2761C38BD21F77, 0x00003FFA //A16
+data8 0xC913043A128367DA, 0x0000BFFA //A17
+data8 0x96A29B71FF7AFFAA, 0x00003FFA //A18
+data8 0xBB9FFA1A5FE649BB, 0x0000BFF9 //A19
+data8 0xB17982CD2DAA0EE3, 0x00003FF8 //A20
+data8 0xDE1DDCBFFB9453F0, 0x0000BFF6 //A21
+data8 0x87FBF5D7ACD9FA9D, 0x00003FF4 //A22
+LOCAL_OBJECT_END(lgammal_0_Half_data)
+
+LOCAL_OBJECT_START(Constants_Q)
+// log2_hi, log2_lo, Q_4, Q_3, Q_2, and Q_1
+data4 0x00000000,0xB1721800,0x00003FFE,0x00000000
+data4 0x4361C4C6,0x82E30865,0x0000BFE2,0x00000000
+data4 0x328833CB,0xCCCCCAF2,0x00003FFC,0x00000000
+data4 0xA9D4BAFB,0x80000077,0x0000BFFD,0x00000000
+data4 0xAAABE3D2,0xAAAAAAAA,0x00003FFD,0x00000000
+data4 0xFFFFDAB7,0xFFFFFFFF,0x0000BFFD,0x00000000
+LOCAL_OBJECT_END(Constants_Q)
+
+LOCAL_OBJECT_START(Constants_Z_1)
+// Z1 - 16 bit fixed
+data4 0x00008000
+data4 0x00007879
+data4 0x000071C8
+data4 0x00006BCB
+data4 0x00006667
+data4 0x00006187
+data4 0x00005D18
+data4 0x0000590C
+data4 0x00005556
+data4 0x000051EC
+data4 0x00004EC5
+data4 0x00004BDB
+data4 0x00004925
+data4 0x0000469F
+data4 0x00004445
+data4 0x00004211
+LOCAL_OBJECT_END(Constants_Z_1)
+
+LOCAL_OBJECT_START(Constants_G_H_h1)
+// G1 and H1 - IEEE single and h1 - IEEE double
+data4 0x3F800000,0x00000000,0x00000000,0x00000000
+data4 0x3F70F0F0,0x3D785196,0x617D741C,0x3DA163A6
+data4 0x3F638E38,0x3DF13843,0xCBD3D5BB,0x3E2C55E6
+data4 0x3F579430,0x3E2FF9A0,0xD86EA5E7,0xBE3EB0BF
+data4 0x3F4CCCC8,0x3E647FD6,0x86B12760,0x3E2E6A8C
+data4 0x3F430C30,0x3E8B3AE7,0x5C0739BA,0x3E47574C
+data4 0x3F3A2E88,0x3EA30C68,0x13E8AF2F,0x3E20E30F
+data4 0x3F321640,0x3EB9CEC8,0xF2C630BD,0xBE42885B
+data4 0x3F2AAAA8,0x3ECF9927,0x97E577C6,0x3E497F34
+data4 0x3F23D708,0x3EE47FC5,0xA6B0A5AB,0x3E3E6A6E
+data4 0x3F1D89D8,0x3EF8947D,0xD328D9BE,0xBDF43E3C
+data4 0x3F17B420,0x3F05F3A1,0x0ADB090A,0x3E4094C3
+data4 0x3F124920,0x3F0F4303,0xFC1FE510,0xBE28FBB2
+data4 0x3F0D3DC8,0x3F183EBF,0x10FDE3FA,0x3E3A7895
+data4 0x3F088888,0x3F20EC80,0x7CC8C98F,0x3E508CE5
+data4 0x3F042108,0x3F29516A,0xA223106C,0xBE534874
+LOCAL_OBJECT_END(Constants_G_H_h1)
+
+LOCAL_OBJECT_START(Constants_Z_2)
+// Z2 - 16 bit fixed
+data4 0x00008000
+data4 0x00007F81
+data4 0x00007F02
+data4 0x00007E85
+data4 0x00007E08
+data4 0x00007D8D
+data4 0x00007D12
+data4 0x00007C98
+data4 0x00007C20
+data4 0x00007BA8
+data4 0x00007B31
+data4 0x00007ABB
+data4 0x00007A45
+data4 0x000079D1
+data4 0x0000795D
+data4 0x000078EB
+LOCAL_OBJECT_END(Constants_Z_2)
+
+LOCAL_OBJECT_START(Constants_G_H_h2)
+// G2 and H2 - IEEE single and h2 - IEEE double
+data4 0x3F800000,0x00000000,0x00000000,0x00000000
+data4 0x3F7F00F8,0x3B7F875D,0x22C42273,0x3DB5A116
+data4 0x3F7E03F8,0x3BFF015B,0x21F86ED3,0x3DE620CF
+data4 0x3F7D08E0,0x3C3EE393,0x484F34ED,0xBDAFA07E
+data4 0x3F7C0FC0,0x3C7E0586,0x3860BCF6,0xBDFE07F0
+data4 0x3F7B1880,0x3C9E75D2,0xA78093D6,0x3DEA370F
+data4 0x3F7A2328,0x3CBDC97A,0x72A753D0,0x3DFF5791
+data4 0x3F792FB0,0x3CDCFE47,0xA7EF896B,0x3DFEBE6C
+data4 0x3F783E08,0x3CFC15D0,0x409ECB43,0x3E0CF156
+data4 0x3F774E38,0x3D0D874D,0xFFEF71DF,0xBE0B6F97
+data4 0x3F766038,0x3D1CF49B,0x5D59EEE8,0xBE080483
+data4 0x3F757400,0x3D2C531D,0xA9192A74,0x3E1F91E9
+data4 0x3F748988,0x3D3BA322,0xBF72A8CD,0xBE139A06
+data4 0x3F73A0D0,0x3D4AE46F,0xF8FBA6CF,0x3E1D9202
+data4 0x3F72B9D0,0x3D5A1756,0xBA796223,0xBE1DCCC4
+data4 0x3F71D488,0x3D693B9D,0xB6B7C239,0xBE049391
+LOCAL_OBJECT_END(Constants_G_H_h2)
+
+LOCAL_OBJECT_START(Constants_G_H_h3)
+// G3 and H3 - IEEE single and h3 - IEEE double
+data4 0x3F7FFC00,0x38800100,0x562224CD,0x3D355595
+data4 0x3F7FF400,0x39400480,0x06136FF6,0x3D8200A2
+data4 0x3F7FEC00,0x39A00640,0xE8DE9AF0,0x3DA4D68D
+data4 0x3F7FE400,0x39E00C41,0xB10238DC,0xBD8B4291
+data4 0x3F7FDC00,0x3A100A21,0x3B1952CA,0xBD89CCB8
+data4 0x3F7FD400,0x3A300F22,0x1DC46826,0xBDB10707
+data4 0x3F7FCC08,0x3A4FF51C,0xF43307DB,0x3DB6FCB9
+data4 0x3F7FC408,0x3A6FFC1D,0x62DC7872,0xBD9B7C47
+data4 0x3F7FBC10,0x3A87F20B,0x3F89154A,0xBDC3725E
+data4 0x3F7FB410,0x3A97F68B,0x62B9D392,0xBD93519D
+data4 0x3F7FAC18,0x3AA7EB86,0x0F21BD9D,0x3DC18441
+data4 0x3F7FA420,0x3AB7E101,0x2245E0A6,0xBDA64B95
+data4 0x3F7F9C20,0x3AC7E701,0xAABB34B8,0x3DB4B0EC
+data4 0x3F7F9428,0x3AD7DD7B,0x6DC40A7E,0x3D992337
+data4 0x3F7F8C30,0x3AE7D474,0x4F2083D3,0x3DC6E17B
+data4 0x3F7F8438,0x3AF7CBED,0x811D4394,0x3DAE314B
+data4 0x3F7F7C40,0x3B03E1F3,0xB08F2DB1,0xBDD46F21
+data4 0x3F7F7448,0x3B0BDE2F,0x6D34522B,0xBDDC30A4
+data4 0x3F7F6C50,0x3B13DAAA,0xB1F473DB,0x3DCB0070
+data4 0x3F7F6458,0x3B1BD766,0x6AD282FD,0xBDD65DDC
+data4 0x3F7F5C68,0x3B23CC5C,0xF153761A,0xBDCDAB83
+data4 0x3F7F5470,0x3B2BC997,0x341D0F8F,0xBDDADA40
+data4 0x3F7F4C78,0x3B33C711,0xEBC394E8,0x3DCD1BD7
+data4 0x3F7F4488,0x3B3BBCC6,0x52E3E695,0xBDC3532B
+data4 0x3F7F3C90,0x3B43BAC0,0xE846B3DE,0xBDA3961E
+data4 0x3F7F34A0,0x3B4BB0F4,0x785778D4,0xBDDADF06
+data4 0x3F7F2CA8,0x3B53AF6D,0xE55CE212,0x3DCC3ED1
+data4 0x3F7F24B8,0x3B5BA620,0x9E382C15,0xBDBA3103
+data4 0x3F7F1CC8,0x3B639D12,0x5C5AF197,0x3D635A0B
+data4 0x3F7F14D8,0x3B6B9444,0x71D34EFC,0xBDDCCB19
+data4 0x3F7F0CE0,0x3B7393BC,0x52CD7ADA,0x3DC74502
+data4 0x3F7F04F0,0x3B7B8B6D,0x7D7F2A42,0xBDB68F17
+LOCAL_OBJECT_END(Constants_G_H_h3)
+
+LOCAL_OBJECT_START(lgammal_data)
+// Positive overflow value
+data8 0xB8D54C8BFFFDEBF4, 0x00007FF1
+LOCAL_OBJECT_END(lgammal_data)
+
+LOCAL_OBJECT_START(lgammal_Stirling)
+// Coefficients needed for Strirling's formula
+data8 0x3FED67F1C864BEB4 // High part of 0.5*ln(2*Pi)
+data8 0x3C94D252F2400510 // Low part of 0.5*ln(2*Pi)
+//
+// Bernulli numbers used in Striling's formula for -2^63 < |x| < -13.0
+//(B1H, B1L) = 8.3333333333333333333262747254e-02
+data8 0x3FB5555555555555, 0x3C55555555555555
+data8 0xB60B60B60B60B60B, 0x0000BFF6 //B2 = -2.7777777777777777777777777778e-03
+data8 0xD00D00D00D00D00D, 0x00003FF4 //B3 = 7.9365079365079365079365079365e-04
+data8 0x9C09C09C09C09C0A, 0x0000BFF4 //B4 = -5.9523809523809523809523809524e-04
+data8 0xDCA8F158C7F91AB8, 0x00003FF4 //B5 = 8.4175084175084175084175084175e-04
+data8 0xFB5586CCC9E3E410, 0x0000BFF5 //B6 = -1.9175269175269175269175269175e-03
+data8 0xD20D20D20D20D20D, 0x00003FF7 //B7 = 6.4102564102564102564102564103e-03
+data8 0xF21436587A9CBEE1, 0x0000BFF9 //B8 = -2.9550653594771241830065359477e-02
+data8 0xB7F4B1C0F033FFD1, 0x00003FFC //B9 = 1.7964437236883057316493849002e-01
+data8 0xB23B3808C0F9CF6E, 0x0000BFFF //B10 = -1.3924322169059011164274322169e+00
+// Polynomial coefficients for Stirling's formula, -13.0 < x < -6.0
+data8 0x3FB5555555555555, 0x3C4D75060289C58B //A0
+data8 0xB60B60B60B0F0876, 0x0000BFF6 //A1
+data8 0xD00D00CE54B1256C, 0x00003FF4 //A2
+data8 0x9C09BF46B58F75E1, 0x0000BFF4 //A3
+data8 0xDCA8483BC91ACC6D, 0x00003FF4 //A4
+data8 0xFB3965C939CC9FEE, 0x0000BFF5 //A5
+data8 0xD0723ADE3F0BC401, 0x00003FF7 //A6
+data8 0xE1ED7434E81F0B73, 0x0000BFF9 //A7
+data8 0x8069C6982F993283, 0x00003FFC //A8
+data8 0xC271F65BFA5BEE3F, 0x0000BFFD //A9
+LOCAL_OBJECT_END(lgammal_Stirling)
+
+LOCAL_OBJECT_START(lgammal_lnsin_data)
+// polynomial approximation of -ln(sin(Pi*x)/(Pi*x)), 0 < x <= 0.5
+data8 0x3FFA51A6625307D3, 0x3C81873332FAF94C //A2
+data8 0x8A8991563EC241C3, 0x00003FFE //A4
+data8 0xADA06588061805DF, 0x00003FFD //A6
+data8 0x80859B57C338D0F7, 0x00003FFD //A8
+data8 0xCD00F1C2D78754BD, 0x00003FFC //A10
+data8 0xAAB56B1D3A1F4655, 0x00003FFC //A12
+data8 0x924B6F2FBBED12B1, 0x00003FFC //A14
+data8 0x80008E58765F43FC, 0x00003FFC //A16
+data8 0x3FBC718EC115E429//A18
+data8 0x3FB99CE544FE183E//A20
+data8 0x3FB7251C09EAAD89//A22
+data8 0x3FB64A970733628C//A24
+data8 0x3FAC92D6802A3498//A26
+data8 0x3FC47E1165261586//A28
+data8 0xBFCA1BAA434750D4//A30
+data8 0x3FE460001C4D5961//A32
+data8 0xBFE6F06A3E4908AD//A34
+data8 0x3FE300889EBB203A//A36
+LOCAL_OBJECT_END(lgammal_lnsin_data)
+
+LOCAL_OBJECT_START(lgammal_half_3Q_data)
+// Polynomial coefficients for the lgammal(x), 0.5 <= x < 0.75
+data8 0xBFF7A648EE90C62E, 0x3C713F326857E066 // A3, A0L
+data8 0xBFF73E4B8BA780AE, 0xBCA953BC788877EF // A1, A1L
+data8 0x403774DCD58D0291, 0xC0415254D5AE6623 // D0, D1
+data8 0x40B07213855CBFB0, 0xC0B8855E25D2D229 // C20, C21
+data8 0x3FFB359F85FF5000, 0x3C9BAECE6EF9EF3A // A2, A2L
+data8 0x3FD717D498A3A8CC, 0xBC9088E101CFEDFA // A0, A3L
+data8 0xAFEF36CC5AEC3FF0, 0x00004002 // E6
+data8 0xABE2054E1C34E791, 0x00004001 // E4
+data8 0xB39343637B2900D1, 0x00004000 // E2
+data8 0xD74FB710D53F58F6, 0x00003FFF // E0
+data8 0x4070655963BA4256, 0xC078DA9D263C4EA3 // D6, D7
+data8 0x405CD2B6A9B90978, 0xC065B3B9F4F4F171 // D4, D5
+data8 0x4049BC2204CF61FF, 0xC05337227E0BA152 // D2, D3
+data8 0x4095509A50C07A96, 0xC0A0747949D2FB45 // C18, C19
+data8 0x4082ECCBAD709414, 0xC08CD02FB088A702 // C16, C17
+data8 0xFFE4B2A61B508DD5, 0x0000C002 // E7
+data8 0xF461ADB8AE17E0A5, 0x0000C001 // E5
+data8 0xF5BE8B0B90325F20, 0x0000C000 // E3
+data8 0x877B275F3FB78DCA, 0x0000C000 // E1
+LOCAL_OBJECT_END(lgammal_half_3Q_data)
+
+LOCAL_OBJECT_START(lgammal_half_3Q_neg_data)
+// Polynomial coefficients for the lgammal(x), -0.75 < x <= -0.5
+data8 0xC014836EFD94899C, 0x3C9835679663B44F // A3, A0L
+data8 0xBFF276C7B4FB1875, 0xBC92D3D9FA29A1C0 // A1, A1L
+data8 0x40C5178F24E1A435, 0xC0D9DE84FBC5D76A // D0, D1
+data8 0x41D4D1B236BF6E93, 0xC1EBB0445CE58550 // C20, C21
+data8 0x4015718CD67F63D3, 0x3CC5354B6F04B59C // A2, A2L
+data8 0x3FF554493087E1ED, 0xBCB72715E37B02B9 // A0, A3L
+data8 0xE4AC7E915FA72229, 0x00004009 // E6
+data8 0xA28244206395FCC6, 0x00004007 // E4
+data8 0xFB045F19C07B2544, 0x00004004 // E2
+data8 0xE5C8A6E6A9BA7D7B, 0x00004002 // E0
+data8 0x4143943B55BF5118, 0xC158AC05EA675406 // D6, D7
+data8 0x4118F6833D19717C, 0xC12F51A6F375CC80 // D4, D5
+data8 0x40F00C209483481C, 0xC103F1DABF750259 // D2, D3
+data8 0x4191038F2D8F9E40, 0xC1A413066DA8AE4A // C18, C19
+data8 0x4170B537EDD833DE, 0xC1857E79424C61CE // C16, C17
+data8 0x8941D8AB4855DB73, 0x0000C00B // E7
+data8 0xBB822B131BD2E813, 0x0000C008 // E5
+data8 0x852B4C03B83D2D4F, 0x0000C006 // E3
+data8 0xC754CA7E2DDC0F1F, 0x0000C003 // E1
+LOCAL_OBJECT_END(lgammal_half_3Q_neg_data)
+
+LOCAL_OBJECT_START(lgammal_2Q_4_data)
+// Polynomial coefficients for the lgammal(x), 2.25 <= |x| < 4.0
+data8 0xBFCA4D55BEAB2D6F, 0x3C7ABC9DA14141F5 // A3, A0L
+data8 0x3FFD8773039049E7, 0x3C66CB7957A95BA4 // A1, A1L
+data8 0x3F45C3CC79E91E7D, 0xBF3A8E5005937E97 // D0, D1
+data8 0x3EC951E35E1C9203, 0xBEB030A90026C5DF // C20, C21
+data8 0x3FE94699894C1F4C, 0x3C91884D21D123F1 // A2, A2L
+data8 0x3FE62E42FEFA39EF, 0xBC66480CEB70870F // A0, A3L
+data8 0xF1C2EAFF0B3A7579, 0x00003FF5 // E6
+data8 0xB36AF863926B55A3, 0x00003FF7 // E4
+data8 0x9620656185BB44CA, 0x00003FF9 // E2
+data8 0xA264558FB0906AFF, 0x00003FFB // E0
+data8 0x3F03D59E9666C961, 0xBEF91115893D84A6 // D6, D7
+data8 0x3F19333611C46225, 0xBF0F89EB7D029870 // D4, D5
+data8 0x3F3055A96B347AFE, 0xBF243B5153E178A8 // D2, D3
+data8 0x3ED9A4AEF30C4BB2, 0xBED388138B1CEFF2 // C18, C19
+data8 0x3EEF7945A3C3A254, 0xBEE36F32A938EF11 // C16, C17
+data8 0x9028923F47C82118, 0x0000BFF5 // E7
+data8 0xCE0DAAFB6DC93B22, 0x0000BFF6 // E5
+data8 0xA0D0983B34AC4C8D, 0x0000BFF8 // E3
+data8 0x94D6C50FEB8B0CE7, 0x0000BFFA // E1
+LOCAL_OBJECT_END(lgammal_2Q_4_data)
+
+LOCAL_OBJECT_START(lgammal_4_8_data)
+// Polynomial coefficients for the lgammal(x), 4.0 <= |x| < 8.0
+data8 0xBFD6626BC9B31B54, 0x3CAA53C82493A92B // A3, A0L
+data8 0x401B4C420A50AD7C, 0x3C8C6E9929F789A3 // A1, A1L
+data8 0x3F49410427E928C2, 0xBF3E312678F8C146 // D0, D1
+data8 0x3ED51065F7CD5848, 0xBED052782A03312F // C20, C21
+data8 0x3FF735973273D5EC, 0x3C831DFC65BF8CCF // A2, A2L
+data8 0x401326643C4479C9, 0xBC6FA0498C5548A6 // A0, A3L
+data8 0x9382D8B3CD4EB7E3, 0x00003FF6 // E6
+data8 0xE9F92CAD8A85CBCD, 0x00003FF7 // E4
+data8 0xD58389FE38258CEC, 0x00003FF9 // E2
+data8 0x81310136363AE8AA, 0x00003FFC // E0
+data8 0x3F04F0AE38E78570, 0xBEF9E2144BB8F03C // D6, D7
+data8 0x3F1B5E992A6CBC2A, 0xBF10F3F400113911 // D4, D5
+data8 0x3F323EE00AAB7DEE, 0xBF2640FDFA9FB637 // D2, D3
+data8 0x3ED2143EBAFF067A, 0xBEBBDEB92D6FF35D // C18, C19
+data8 0x3EF173A42B69AAA4, 0xBEE78B9951A2EAA5 // C16, C17
+data8 0xAB3CCAC6344E52AA, 0x0000BFF5 // E7
+data8 0x81ACCB8915B16508, 0x0000BFF7 // E5
+data8 0xDA62C7221102C426, 0x0000BFF8 // E3
+data8 0xDF1BD44C4083580A, 0x0000BFFA // E1
+LOCAL_OBJECT_END(lgammal_4_8_data)
+
+LOCAL_OBJECT_START(lgammal_loc_min_data)
+// Polynomial coefficients for the lgammal(x), 1.3125 <= x < 1.5625
+data8 0xBB16C31AB5F1FB71, 0x00003FFF // xMin - point of local minimum
+data8 0xBFC2E4278DC6BC23, 0xBC683DA8DDCA9650 // A3, A0L
+data8 0x3BD4DB7D0CA61D5F, 0x386E719EDD01D801 // A1, A1L
+data8 0x3F4CC72638E1D93F, 0xBF4228EC9953CCB9 // D0, D1
+data8 0x3ED222F97A04613E,0xBED3DDD58095CB6C // C20, C21
+data8 0x3FDEF72BC8EE38AB, 0x3C863AFF3FC48940 // A2, A2L
+data8 0xBFBF19B9BCC38A41, 0xBC7425F1BFFC1442// A0, A3L
+data8 0x941890032BEB34C3, 0x00003FF6 // E6
+data8 0xC7E701591CE534BC, 0x00003FF7 // E4
+data8 0x93373CBD05138DD4, 0x00003FF9 // E2
+data8 0x845A14A6A81C05D6, 0x00003FFB // E0
+data8 0x3F0F6C4DF6D47A13, 0xBF045DCDB5B49E19 // D6, D7
+data8 0x3F22E23345DDE59C, 0xBF1851159AFB1735 // D4, D5
+data8 0x3F37101EA4022B78, 0xBF2D721E6323AF13 // D2, D3
+data8 0x3EE691EBE82DF09D, 0xBEDD42550961F730 // C18, C19
+data8 0x3EFA793EDE99AD85, 0xBEF14000108E70BE // C16, C17
+data8 0xB7CBC033ACE0C99C, 0x0000BFF5 // E7
+data8 0xF178D1F7B1A45E27, 0x0000BFF6 // E5
+data8 0xA8FCFCA8106F471C, 0x0000BFF8 // E3
+data8 0x864D46FA898A9AD2, 0x0000BFFA // E1
+LOCAL_OBJECT_END(lgammal_loc_min_data)
+
+LOCAL_OBJECT_START(lgammal_03Q_1Q_data)
+// Polynomial coefficients for the lgammal(x), 0.75 <= |x| < 1.3125
+data8 0x3FD151322AC7D848, 0x3C7184DE0DB7B4EE // A4, A2L
+data8 0x3FD9A4D55BEAB2D6, 0x3C9E934AAB10845F // A3, A1L
+data8 0x3FB111289C381259, 0x3FAFFFCFB32AE18D // D2, D3
+data8 0x3FB3B1D9E0E3E00D, 0x3FB2496F0D3768DF // D0, D1
+data8 0xBA461972C057D439, 0x00003FFB // E6
+data8 0x3FEA51A6625307D3, 0x3C76ABC886A72DA2 // A2, A4L
+data8 0x3FA8EFE46B32A70E, 0x3F8F31B3559576B6 // C17, C20
+data8 0xE403383700387D85, 0x00003FFB // E4
+data8 0x9381D0EE74BF7251, 0x00003FFC // E2
+data8 0x3FAA2177A6D28177, 0x3FA4895E65FBD995 // C18, C19
+data8 0x3FAAED2C77DBEE5D, 0x3FA94CA59385512C // D6, D7
+data8 0x3FAE1F522E8A5941, 0x3FAC785EF56DD87E // D4, D5
+data8 0x3FB556AD5FA56F0A, 0x3FA81F416E87C783 // E7, C16
+data8 0xCD00F1C2DC2C9F1E, 0x00003FFB // E5
+data8 0x3FE2788CFC6FB618, 0x3C8E52519B5B17CB // A1, A3L
+data8 0x80859B57C3E7F241, 0x00003FFC // E3
+data8 0xADA065880615F401, 0x00003FFC // E1
+data8 0xD45CE0BD530AB50E, 0x00003FFC // E0
+LOCAL_OBJECT_END(lgammal_03Q_1Q_data)
+
+LOCAL_OBJECT_START(lgammal_13Q_2Q_data)
+// Polynomial coefficients for the lgammal(x), 1.5625 <= |x| < 2.25
+data8 0x3F951322AC7D8483, 0x3C71873D88C6539D // A4, A2L
+data8 0xBFB13E001A557606, 0x3C56CB907018A101 // A3, A1L
+data8 0xBEC11B2EC1E7F6FC, 0x3EB0064ED9824CC7 // D2, D3
+data8 0xBEE3CBC963EC103A, 0x3ED2597A330C107D // D0, D1
+data8 0xBC6F2DEBDFE66F38, 0x0000BFF0 // E6
+data8 0x3FD4A34CC4A60FA6, 0x3C3AFC9BF775E8A0 // A2, A4L
+data8 0x3E48B0C542F85B32, 0xBE347F12EAF787AB // C17, C20
+data8 0xE9FEA63B6984FA1E, 0x0000BFF2 // E4
+data8 0x9C562E15FC703BBF, 0x0000BFF5 // E2
+data8 0xBE3C12A50AB0355E, 0xBE1C941626AE4717 // C18, C19
+data8 0xBE7AFA8714342BC4,0x3E69A12D2B7761CB // D6, D7
+data8 0xBE9E25EF1D526730, 0x3E8C762291889B99 // D4, D5
+data8 0x3EF580DCEE754733, 0xBE57C811D070549C // E7, C16
+data8 0xD093D878BE209C98, 0x00003FF1 // E5
+data8 0x3FDB0EE6072093CE, 0xBC6024B9E81281C4 // A1, A3L
+data8 0x859B57C31CB77D96, 0x00003FF4 // E3
+data8 0xBD6EB756DB617E8D, 0x00003FF6 // E1
+data8 0xF2027E10C7AF8C38, 0x0000BFF7 // E0
+LOCAL_OBJECT_END(lgammal_13Q_2Q_data)
+
+LOCAL_OBJECT_START(lgammal_8_10_data)
+// Polynomial coefficients for the lgammal(x), 8.0 <= |x| < 10.0
+// Multi Precision terms
+data8 0x40312008A3A23E5C, 0x3CE020B4F2E4083A //A1
+data8 0x4025358E82FCB70C, 0x3CD4A5A74AF7B99C //A0
+// Native precision terms
+data8 0xF0AA239FFBC616D2, 0x00004000 //A2
+data8 0x96A8EA798FE57D66, 0x0000BFFF //A3
+data8 0x8D501B7E3B9B9BDB, 0x00003FFE //A4
+data8 0x9EE062401F4B1DC2, 0x0000BFFD //A5
+data8 0xC63FD8CD31E93431, 0x00003FFC //A6
+data8 0x8461101709C23C30, 0x0000BFFC //A7
+data8 0xB96D7EA7EF3648B2, 0x00003FFB //A8
+data8 0x86886759D2ACC906, 0x0000BFFB //A9
+data8 0xC894B6E28265B183, 0x00003FFA //A10
+data8 0x98C4348CAD821662, 0x0000BFFA //A11
+data8 0xEC9B092226A94DF2, 0x00003FF9 //A12
+data8 0xB9F169FF9B98CDDC, 0x0000BFF9 //A13
+data8 0x9A3A32BB040894D3, 0x00003FF9 //A14
+data8 0xF9504CCC1003B3C3, 0x0000BFF8 //A15
+LOCAL_OBJECT_END(lgammal_8_10_data)
+
+LOCAL_OBJECT_START(lgammal_03Q_6_data)
+// Polynomial coefficients for the lgammal(x), 0.75 <= |x| < 1.0
+data8 0xBFBC47DCA479E295, 0xBC607E6C1A379D55 //A3
+data8 0x3FCA051C372609ED, 0x3C7B02D73EB7D831 //A0
+data8 0xBFE15FAFA86B04DB, 0xBC3F52EE4A8945B5 //A1
+data8 0x3FD455C4FF28F0BF, 0x3C75F8C6C99F30BB //A2
+data8 0xD2CF04CD934F03E1, 0x00003FFA //A4
+data8 0xDB4ED667E29256E1, 0x0000BFF9 //A5
+data8 0xF155A33A5B6021BF, 0x00003FF8 //A6
+data8 0x895E9B9D386E0338, 0x0000BFF8 //A7
+data8 0xA001BE94B937112E, 0x00003FF7 //A8
+data8 0xBD82846E490ED048, 0x0000BFF6 //A9
+data8 0xE358D24EC30DBB5D, 0x00003FF5 //A10
+data8 0x89C4F3652446B78B, 0x0000BFF5 //A11
+data8 0xA86043E10280193D, 0x00003FF4 //A12
+data8 0xCF3A2FBA61EB7682, 0x0000BFF3 //A13
+data8 0x3F300900CC9200EC //A14
+data8 0xBF23F42264B94AE8 //A15
+data8 0x3F18EEF29895FE73 //A16
+data8 0xBF0F3C4563E3EDFB //A17
+data8 0x3F0387DBBC385056 //A18
+data8 0xBEF81B4004F92900 //A19
+data8 0x3EECA6692A9A5B81 //A20
+data8 0xBEDF61A0059C15D3 //A21
+data8 0x3ECDA9F40DCA0111 //A22
+data8 0xBEB60FE788217BAF //A23
+data8 0x3E9661D795DFC8C6 //A24
+data8 0xBE66C7756A4EDEE5 //A25
+// Polynomial coefficients for the lgammal(x), 1.0 <= |x| < 2.0
+data8 0xBFC1AE55B180726B, 0xBC7DE1BC478453F5 //A3
+data8 0xBFBEEB95B094C191, 0xBC53456FF6F1C9D9 //A0
+data8 0x3FA2AED059BD608A, 0x3C0B65CC647D557F //A1
+data8 0x3FDDE9E64DF22EF2, 0x3C8993939A8BA8E4 //A2
+data8 0xF07C206D6B100CFF, 0x00003FFA //A4
+data8 0xED2CEA9BA52FE7FB, 0x0000BFF9 //A5
+data8 0xFCE51CED52DF3602, 0x00003FF8 //A6
+data8 0x8D45D27872326619, 0x0000BFF8 //A7
+data8 0xA2B78D6BCEBE27F7, 0x00003FF7 //A8
+data8 0xBF6DC0996A895B6F, 0x0000BFF6 //A9
+data8 0xE4B9AD335AF82D79, 0x00003FF5 //A10
+data8 0x8A451880195362A1, 0x0000BFF5 //A11
+data8 0xA8BE35E63089A7A9, 0x00003FF4 //A12
+data8 0xCF7FA175FA11C40C, 0x0000BFF3 //A13
+data8 0x3F300C282FAA3B02 //A14
+data8 0xBF23F6AEBDA68B80 //A15
+data8 0x3F18F6860E2224DD //A16
+data8 0xBF0F542B3CE32F28 //A17
+data8 0x3F039436218C9BF8 //A18
+data8 0xBEF8AE6307677AEC //A19
+data8 0x3EF0B55527B3A211 //A20
+data8 0xBEE576AC995E7605 //A21
+data8 0x3ED102DDC1365D2D //A22
+data8 0xBEC442184F97EA54 //A23
+data8 0x3ED4D2283DFE5FC6 //A24
+data8 0xBECB9219A9B46787 //A25
+// Polynomial coefficients for the lgammal(x), 2.0 <= |x| < 3.0
+data8 0xBFCA4D55BEAB2D6F, 0xBC66F80E5BFD5AF5 //A3
+data8 0x3FE62E42FEFA39EF, 0x3C7ABC9E3B347E3D //A0
+data8 0x3FFD8773039049E7, 0x3C66CB9007C426EA //A1
+data8 0x3FE94699894C1F4C, 0x3C918726EB111663 //A2
+data8 0xA264558FB0906209, 0x00003FFB //A4
+data8 0x94D6C50FEB902ADC, 0x0000BFFA //A5
+data8 0x9620656184243D17, 0x00003FF9 //A6
+data8 0xA0D0983B8BCA910B, 0x0000BFF8 //A7
+data8 0xB36AF8559B222BD3, 0x00003FF7 //A8
+data8 0xCE0DACB3260AE6E5, 0x0000BFF6 //A9
+data8 0xF1C2C0BF0437C7DB, 0x00003FF5 //A10
+data8 0x902A2F2F3AB74A92, 0x0000BFF5 //A11
+data8 0xAE05009B1B2C6E4C, 0x00003FF4 //A12
+data8 0xD5B71F6456D7D4CB, 0x0000BFF3 //A13
+data8 0x3F2F0351D71BC9C6 //A14
+data8 0xBF2B53BC56A3B793 //A15
+data8 0xBF18B12DC6F6B861 //A16
+data8 0xBF43EE6EB5215C2F //A17
+data8 0xBF5474787CDD455E //A18
+data8 0xBF642B503C9C060A //A19
+data8 0xBF6E07D1AA254AA3 //A20
+data8 0xBF71C785443AAEE8 //A21
+data8 0xBF6F67BF81B71052 //A22
+data8 0xBF63E4BCCF4FFABF //A23
+data8 0xBF50067F8C671D5A //A24
+data8 0xBF29C770D680A5AC //A25
+// Polynomial coefficients for the lgammal(x), 4.0 <= |x| < 6.0
+data8 0xBFD6626BC9B31B54, 0xBC85AABE08680902 //A3
+data8 0x401326643C4479C9, 0x3CAA53C26F31E364 //A0
+data8 0x401B4C420A50AD7C, 0x3C8C76D55E57DD8D //A1
+data8 0x3FF735973273D5EC, 0x3C83A0B78E09188A //A2
+data8 0x81310136363AAB6D, 0x00003FFC //A4
+data8 0xDF1BD44C4075C0E6, 0x0000BFFA //A5
+data8 0xD58389FE38D8D664, 0x00003FF9 //A6
+data8 0xDA62C7221D5B5F87, 0x0000BFF8 //A7
+data8 0xE9F92CAD0263E157, 0x00003FF7 //A8
+data8 0x81ACCB8606C165FE, 0x0000BFF7 //A9
+data8 0x9382D8D263D1C2A3, 0x00003FF6 //A10
+data8 0xAB3CCBA4C853B12C, 0x0000BFF5 //A11
+data8 0xCA0818BBCCC59296, 0x00003FF4 //A12
+data8 0xF18912691CBB5BD0, 0x0000BFF3 //A13
+data8 0x3F323EF5D8330339 //A14
+data8 0xBF2641132EA571F7 //A15
+data8 0x3F1B5D9576175CA9 //A16
+data8 0xBF10F56A689C623D //A17
+data8 0x3F04CACA9141A18D //A18
+data8 0xBEFA307AC9B4E85D //A19
+data8 0x3EF4B625939FBE32 //A20
+data8 0xBECEE6AC1420F86F //A21
+data8 0xBE9A95AE2E485964 //A22
+data8 0xBF039EF47F8C09BB //A23
+data8 0xBF05345957F7B7A9 //A24
+data8 0xBEF85AE6385D4CCC //A25
+// Polynomial coefficients for the lgammal(x), 3.0 <= |x| < 4.0
+data8 0xBFCA4D55BEAB2D6F, 0xBC667B20FF46C6A8 //A3
+data8 0x3FE62E42FEFA39EF, 0x3C7ABC9E3B398012 //A0
+data8 0x3FFD8773039049E7, 0x3C66CB9070238D77 //A1
+data8 0x3FE94699894C1F4C, 0x3C91873D8839B1CD //A2
+data8 0xA264558FB0906D7E, 0x00003FFB //A4
+data8 0x94D6C50FEB8AFD72, 0x0000BFFA //A5
+data8 0x9620656185B68F14, 0x00003FF9 //A6
+data8 0xA0D0983B34B7088A, 0x0000BFF8 //A7
+data8 0xB36AF863964AA440, 0x00003FF7 //A8
+data8 0xCE0DAAFB5497AFB8, 0x0000BFF6 //A9
+data8 0xF1C2EAFA79CC2864, 0x00003FF5 //A10
+data8 0x9028922A839572B8, 0x0000BFF5 //A11
+data8 0xAE1E62F870BA0278, 0x00003FF4 //A12
+data8 0xD4726F681E2ABA29, 0x0000BFF3 //A13
+data8 0x3F30559B9A02FADF //A14
+data8 0xBF243ADEB1266CAE //A15
+data8 0x3F19303B6F552603 //A16
+data8 0xBF0F768C288EC643 //A17
+data8 0x3F039D5356C21DE1 //A18
+data8 0xBEF81BCA8168E6BE //A19
+data8 0x3EEC74A53A06AD54 //A20
+data8 0xBEDED52D1A5DACDF //A21
+data8 0x3ECCB4C2C7087342 //A22
+data8 0xBEB4F1FAFDFF5C2F //A23
+data8 0x3E94C80B52D58904 //A24
+data8 0xBE64A328CBE92A27 //A25
+LOCAL_OBJECT_END(lgammal_03Q_6_data)
+
+LOCAL_OBJECT_START(lgammal_1pEps_data)
+// Polynomial coefficients for the lgammal(x), 1 - 2^(-7) <= |x| < 1 + 2^(-7)
+data8 0x93C467E37DB0C7A5, 0x00003FFE //A1
+data8 0xD28D3312983E9919, 0x00003FFE //A2
+data8 0xCD26AADF559A47E3, 0x00003FFD //A3
+data8 0x8A8991563EC22E81, 0x00003FFD //A4
+data8 0x3FCA8B9C168D52FE //A5
+data8 0x3FC5B40CB0696370 //A6
+data8 0x3FC270AC2229A65D //A7
+data8 0x3FC0110AF10FCBFC //A8
+// Polynomial coefficients for the log1p(x), - 2^(-7) <= |x| < 2^(-7)
+data8 0x3FBC71C71C71C71C //P8
+data8 0xBFC0000000000000 //P7
+data8 0x3FC2492492492492 //P6
+data8 0xBFC5555555555555 //P5
+data8 0x3FC999999999999A //P4
+data8 0xBFD0000000000000 //P3
+data8 0x3FD5555555555555 //P2
+data8 0xBFE0000000000000 //P1
+// short version of "lnsin" polynomial
+data8 0xD28D3312983E9918, 0x00003FFF //A2
+data8 0x8A8991563EC241B6, 0x00003FFE //A4
+data8 0xADA06588061830A5, 0x00003FFD //A6
+data8 0x80859B57C31CB746, 0x00003FFD //A8
+LOCAL_OBJECT_END(lgammal_1pEps_data)
+
+LOCAL_OBJECT_START(lgammal_neg2andHalf_data)
+// Polynomial coefficients for the lgammal(x), -2.005859375 <= x < -2.5
+data8 0xBF927781D4BB093A, 0xBC511D86D85B7045 // A3, A0L
+data8 0x3FF1A68793DEFC15, 0x3C9852AE2DA7DEEF // A1, A1L
+data8 0x408555562D45FAFD, 0xBF972CDAFE5FEFAD // D0, D1
+data8 0xC18682331EF492A5, 0xC1845E3E0D29606B // C20, C21
+data8 0x4013141822E16979, 0x3CCF8718B6E75F6C // A2, A2L
+data8 0xBFACCBF9F5ED0F15, 0xBBDD1AEB73297401 // A0, A3L
+data8 0xCCCDB17423046445, 0x00004006 // E6
+data8 0x800514E230A3A452, 0x00004005 // E4
+data8 0xAAE9A48EC162E76F, 0x00004003 // E2
+data8 0x81D4F88B3F3EA0FC, 0x00004002 // E0
+data8 0x40CF3F3E35238DA0, 0xC0F8B340945F1A7E // D6, D7
+data8 0x40BF89EC0BD609C6, 0xC095897242AEFEE2 // D4, D5
+data8 0x40A2482FF01DBC5C, 0xC02095E275FDCF62 // D2, D3
+data8 0xC1641354F2312A6A, 0xC17B3657F85258E9 // C18, C19
+data8 0xC11F964E9ECBE2C9, 0xC146D7A90F70696C // C16, C17
+data8 0xE7AECDE6AF8EA816, 0x0000BFEF // E7
+data8 0xD711252FEBBE1091, 0x0000BFEB // E5
+data8 0xE648BD10F8C43391, 0x0000BFEF // E3
+data8 0x948A1E78AA00A98D, 0x0000BFF4 // E1
+LOCAL_OBJECT_END(lgammal_neg2andHalf_data)
+
+LOCAL_OBJECT_START(lgammal_near_neg_half_data)
+// Polynomial coefficients for the lgammal(x), -0.5 < x < -0.40625
+data8 0xBFC1AE55B180726C, 0x3C8053CD734E6A1D // A3, A0L
+data8 0x3FA2AED059BD608A, 0x3C0CD3D2CDBA17F4 // A1, A1L
+data8 0x40855554DBCD1E1E, 0x3F96C51AC2BEE9E1 // D0, D1
+data8 0xC18682331EF4927D, 0x41845E3E0D295DFC // C20, C21
+data8 0x4011DE9E64DF22EF, 0x3CA692B70DAD6B7B // A2, A2L
+data8 0x3FF43F89A3F0EDD6, 0xBC4955AED0FA087D // A0, A3L
+data8 0xCCCD3F1DF4A2C1DD, 0x00004006 // E6
+data8 0x80028ADE33C7FCD9, 0x00004005 // E4
+data8 0xAACA474E485507EF, 0x00004003 // E2
+data8 0x80F07C206D6B0ECD, 0x00004002 // E0
+data8 0x40CF3F3E33E83056, 0x40F8B340944633D9 // D6, D7
+data8 0x40BF89EC059931F0, 0x409589723307AD20 // D4, D5
+data8 0x40A2482FD0054824, 0x402095CE7F19D011 // D2, D3
+data8 0xC1641354F2313614, 0x417B3657F8525354 // C18, C19
+data8 0xC11F964E9ECFD21C, 0x4146D7A90F701836 // C16, C17
+data8 0x86A9C01F0EA11E5A, 0x0000BFF5 // E7
+data8 0xBF6D8469142881C0, 0x0000BFF6 // E5
+data8 0x8D45D277BA8255F1, 0x0000BFF8 // E3
+data8 0xED2CEA9BA528BCC3, 0x0000BFF9 // E1
+LOCAL_OBJECT_END(lgammal_near_neg_half_data)
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+////////////// POLYNOMIAL COEFFICIENTS FOR "NEAR ROOTS" RANGES /////////////
+////////////// THIS PART OF TABLE SHOULD BE ADDRESSED REALLY RARE /////////////
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+LOCAL_OBJECT_START(lgammal_right_roots_polynomial_data)
+// Polynomial coefficients for right root on [-3, -2]
+// Lgammal is aproximated by polynomial within [-.056244 ; .158208 ] range
+data8 0xBBBD5E9DCD11030B, 0xB867411D9FF87DD4 //A0
+data8 0x3FF83FE966AF535E, 0x3CAA21235B8A769A //A1
+data8 0x40136EEBB002F55C, 0x3CC3959A6029838E //A2
+data8 0xB4A5302C53C2BEDD, 0x00003FFF //A3
+data8 0x8B8C6BE504F2DA1C, 0x00004002 //A4
+data8 0xB99CFF02593B4D98, 0x00004001 //A5
+data8 0x4038D32F682AA1CF //A6
+data8 0x403809F04EE6C5B5 //A7
+data8 0x40548EAA81634CEE //A8
+data8 0x4059297ADB6BC03D //A9
+data8 0x407286FB8EC5C9DA //A10
+data8 0x407A92E05B744CFB //A11
+data8 0x4091A9D4144258CD //A12
+data8 0x409C4D01D24F367E //A13
+data8 0x40B1871B9A426A83 //A14
+data8 0x40BE51C48BD9A583 //A15
+data8 0x40D2140D0C6153E7 //A16
+data8 0x40E0FB2C989CE4A3 //A17
+data8 0x40E52739AB005641 //A18
+data8 0x41161E3E6DDF503A //A19
+// Polynomial coefficients for right root on [-4, -3]
+// Lgammal is aproximated by polynomial within [-.172797 ; .171573 ] range
+data8 0x3C172712B248E42E, 0x38CB8D17801A5D67 //A0
+data8 0x401F20A65F2FAC54, 0x3CCB9EA1817A824E //A1
+data8 0x4039D4D2977150EF, 0x3CDA42E149B6276A //A2
+data8 0xE089B8926AE2D9CB, 0x00004005 //A3
+data8 0x933901EBBB586C37, 0x00004008 //A4
+data8 0xCCD319BED1CFA1CD, 0x0000400A //A5
+data8 0x40D293C3F78D3C37 //A6
+data8 0x40FBB97AA0B6DD02 //A7
+data8 0x41251EA3345E5EB9 //A8
+data8 0x415057F65C92E7B0 //A9
+data8 0x41799C865241B505 //A10
+data8 0x41A445209EFE896B //A11
+data8 0x41D02D21880C953B //A12
+data8 0x41F9FFDE8C63E16D //A13
+data8 0x422504DC8302D2BE //A14
+data8 0x425111BF18C95414 //A15
+data8 0x427BCBE74A2B8EF7 //A16
+data8 0x42A7256F59B286F7 //A17
+data8 0x42D462D1586DE61F //A18
+data8 0x42FBB1228D6C5118 //A19
+// Polynomial coefficients for right root on [-5, -4]
+// Lgammal is aproximated by polynomial within [-.163171 ; .161988 ] range
+data8 0x3C5840FBAFDEE5BB, 0x38CAC0336E8C490A //A0
+data8 0x403ACA5CF4921642, 0x3CCEDCDDA5491E56 //A1
+data8 0x40744415CD813F8E, 0x3CFBFEBC17E39146 //A2
+data8 0xAACD88D954E3E1BD, 0x0000400B //A3
+data8 0xCB68C710D75ED802, 0x0000400F //A4
+data8 0x8130F5AB997277AC, 0x00004014 //A5
+data8 0x41855E3DBF99EBA7 //A6
+data8 0x41CD14FE49C49FC2 //A7
+data8 0x421433DCE281F07D //A8
+data8 0x425C8399C7A92B6F //A9
+data8 0x42A45FBE67840F1A //A10
+data8 0x42ED68D75F9E6C98 //A11
+data8 0x433567291C27E5BE //A12
+data8 0x437F5ED7A9D9FD28 //A13
+data8 0x43C720A65C8AB711 //A14
+data8 0x441120A6C1D40B9B //A15
+data8 0x44596F561F2D1CBE //A16
+data8 0x44A3507DA81D5C01 //A17
+data8 0x44EF06A31E39EEDF //A18
+data8 0x45333774C99F523F //A19
+// Polynomial coefficients for right root on [-6, -5]
+// Lgammal is aproximated by polynomial within [-.156450 ; .156126 ] range
+data8 0x3C71B82D6B2B3304, 0x3917186E3C0DC231 //A0
+data8 0x405ED72E0829AE02, 0x3C960C25157980EB //A1
+data8 0x40BCECC32EC22F9B, 0x3D5D8335A32F019C //A2
+data8 0x929EC2B1FB931F17, 0x00004012 //A3
+data8 0xD112EF96D37316DE, 0x00004018 //A4
+data8 0x9F00BB9BB13416AB, 0x0000401F //A5
+data8 0x425F7D8D5BDCB223 //A6
+data8 0x42C9A8D00C776CC6 //A7
+data8 0x433557FD8C481424 //A8
+data8 0x43A209221A953EF0 //A9
+data8 0x440EDC98D5618AB7 //A10
+data8 0x447AABD25E367378 //A11
+data8 0x44E73DE20CC3B288 //A12
+data8 0x455465257B4E0BD8 //A13
+data8 0x45C2011532085353 //A14
+data8 0x462FEE4CC191945B //A15
+data8 0x469C63AEEFEF0A7F //A16
+data8 0x4709D045390A3810 //A17
+data8 0x4778D360873C9F64 //A18
+data8 0x47E26965BE9A682A //A19
+// Polynomial coefficients for right root on [-7, -6]
+// Lgammal is aproximated by polynomial within [-.154582 ; .154521 ] range
+data8 0x3C75F103A1B00A48, 0x391C041C190C726D //A0
+data8 0x40869DE49E3AF2AA, 0x3D1C17E1F813063B //A1
+data8 0x410FCE23484CFD10, 0x3DB6F38C2F11DAB9 //A2
+data8 0xEF281D1E1BE2055A, 0x00004019 //A3
+data8 0xFCE3DA92AC55DFF8, 0x00004022 //A4
+data8 0x8E9EA838A20BD58E, 0x0000402C //A5
+data8 0x4354F21E2FB9E0C9 //A6
+data8 0x43E9500994CD4F09 //A7
+data8 0x447F3A2C23C033DF //A8
+data8 0x45139152656606D8 //A9
+data8 0x45A8D45F8D3BF2E8 //A10
+data8 0x463FD32110E5BFE5 //A11
+data8 0x46D490B3BDBAE0BE //A12
+data8 0x476AC3CAD905DD23 //A13
+data8 0x48018558217AD473 //A14
+data8 0x48970AF371D30585 //A15
+data8 0x492E6273A8BEFFE3 //A16
+data8 0x49C47CC9AE3F1073 //A17
+data8 0x4A5D38E8C35EFF45 //A18
+data8 0x4AF0123E89694CD8 //A19
+// Polynomial coefficients for right root on [-8, -7]
+// Lgammal is aproximated by polynomial within [-.154217 ; .154208 ] range
+data8 0xBCD2507D818DDD68, 0xB97F6940EA2871A0 //A0
+data8 0x40B3B407AA387BCB, 0x3D6320238F2C43D1 //A1
+data8 0x41683E85DAAFBAC7, 0x3E148D085958EA3A //A2
+data8 0x9F2A95AF1E10A548, 0x00004022 //A3
+data8 0x92F21522F482300E, 0x0000402E //A4
+data8 0x90B51AB03A1F244D, 0x0000403A //A5
+data8 0x44628E1C70EF534F //A6
+data8 0x452393E2BC32D244 //A7
+data8 0x45E5164141F4BA0B //A8
+data8 0x46A712B3A8AF5808 //A9
+data8 0x47698FD36CEDD0F2 //A10
+data8 0x482C9AE6BBAA3637 //A11
+data8 0x48F023821857C8E9 //A12
+data8 0x49B2569053FC106F //A13
+data8 0x4A74F646D5C1604B //A14
+data8 0x4B3811CF5ABA4934 //A15
+data8 0x4BFBB5DD6C84E233 //A16
+data8 0x4CC05021086F637B //A17
+data8 0x4D8450A345B0FB49 //A18
+data8 0x4E43825848865DB2 //A19
+// Polynomial coefficients for right root on [-9, -8]
+// Lgammal is aproximated by polynomial within [-.154160 ; .154158 ] range
+data8 0x3CDF4358564F2B46, 0x397969BEE6042F81 //A0
+data8 0x40E3B088FED67721, 0x3D82787BA937EE85 //A1
+data8 0x41C83A3893550EF4, 0x3E542ED57E244DA8 //A2
+data8 0x9F003C6DC56E0B8E, 0x0000402B //A3
+data8 0x92BDF64A3213A699, 0x0000403A //A4
+data8 0x9074F503AAD417AF, 0x00004049 //A5
+data8 0x4582843E1313C8CD //A6
+data8 0x467387BD6A7826C1 //A7
+data8 0x4765074E788CF440 //A8
+data8 0x4857004DD9D1E09D //A9
+data8 0x4949792ED7530EAF //A10
+data8 0x4A3C7F089A292ED3 //A11
+data8 0x4B30125BF0AABB86 //A12
+data8 0x4C224175195E307E //A13
+data8 0x4D14DC4C8B32C08D //A14
+data8 0x4E07F1DB2786197E //A15
+data8 0x4EFB8EA1C336DACB //A16
+data8 0x4FF03797EACD0F23 //A17
+data8 0x50E4304A8E68A730 //A18
+data8 0x51D3618FB2EC9F93 //A19
+// Polynomial coefficients for right root on [-10, -9]
+// Lgammal is aproximated by polynomial within [-.154152 ; .154152 ] range
+data8 0x3D42F34DA97ECF0C, 0x39FD1256F345B0D0 //A0
+data8 0x4116261203919787, 0x3DC12D44055588EB //A1
+data8 0x422EA8F32FB7FE99, 0x3ED849CE4E7B2D77 //A2
+data8 0xE25BAF73477A57B5, 0x00004034 //A3
+data8 0xEB021FD10060504A, 0x00004046 //A4
+data8 0x8220A208EE206C5F, 0x00004059 //A5
+data8 0x46B2C3903EC9DA14 //A6
+data8 0x47D64393744B9C67 //A7
+data8 0x48FAF79CCDC604DD //A8
+data8 0x4A20975DB8061EBA //A9
+data8 0x4B44AB9CBB38DB21 //A10
+data8 0x4C6A032F60094FE9 //A11
+data8 0x4D908103927634B4 //A12
+data8 0x4EB516CA21D30861 //A13
+data8 0x4FDB1BF12C58D318 //A14
+data8 0x510180AAE094A553 //A15
+data8 0x5226A8F2A2D45D57 //A16
+data8 0x534E00B6B0C8B809 //A17
+data8 0x5475022FE21215B2 //A18
+data8 0x5596B02BF6C5E19B //A19
+// Polynomial coefficients for right root on [-11, -10]
+// Lgammal is aproximated by polynomial within [-.154151 ; .154151 ] range
+data8 0x3D7AA9C2E2B1029C, 0x3A15FB37578544DB //A0
+data8 0x414BAF825A0C91D4, 0x3DFB9DA2CE398747 //A1
+data8 0x4297F3EC8AE0AF03, 0x3F34208B55FB8781 //A2
+data8 0xDD0C97D3197F56DE, 0x0000403E //A3
+data8 0x8F6F3AF7A5499674, 0x00004054 //A4
+data8 0xC68DA1AF6D878EEB, 0x00004069 //A5
+data8 0x47F1E4E1E2197CE0 //A6
+data8 0x494A8A28E597C3EB //A7
+data8 0x4AA4175D0D35D705 //A8
+data8 0x4BFEE6F0AF69E814 //A9
+data8 0x4D580FE7B3DBB3C6 //A10
+data8 0x4EB2ECE60E4608AF //A11
+data8 0x500E04BE3E2B4F24 //A12
+data8 0x5167F9450F0FB8FD //A13
+data8 0x52C342BDE747603F //A14
+data8 0x541F1699D557268C //A15
+data8 0x557927C5F079864E //A16
+data8 0x56D4D10FEEDB030C //A17
+data8 0x5832385DF86AD28A //A18
+data8 0x598898914B4D6523 //A19
+// Polynomial coefficients for right root on [-12, -11]
+// Lgammal is aproximated by polynomial within [-.154151 ; .154151 ] range
+data8 0xBD96F61647C58B03, 0xBA3ABB0C2A6C755B //A0
+data8 0x418308A82714B70D, 0x3E1088FC6A104C39 //A1
+data8 0x4306A493DD613C39, 0x3FB2341ECBF85741 //A2
+data8 0x8FA8FE98339474AB, 0x00004049 //A3
+data8 0x802CCDF570BA7942, 0x00004062 //A4
+data8 0xF3F748AF11A32890, 0x0000407A //A5
+data8 0x493E3B567EF178CF //A6
+data8 0x4ACED38F651BA362 //A7
+data8 0x4C600B357337F946 //A8
+data8 0x4DF0F71A52B54CCF //A9
+data8 0x4F8229F3B9FA2C70 //A10
+data8 0x5113A4C4979B770E //A11
+data8 0x52A56BC367F298D5 //A12
+data8 0x543785CF31842DC0 //A13
+data8 0x55C9FC37E3E40896 //A14
+data8 0x575CD5D1BA556C82 //A15
+data8 0x58F00A7AD99A9E08 //A16
+data8 0x5A824088688B008D //A17
+data8 0x5C15F75EF7E08EBD //A18
+data8 0x5DA462EA902F0C90 //A19
+// Polynomial coefficients for right root on [-13, -12]
+// Lgammal is aproximated by polynomial within [-.154151 ; .154151 ] range
+data8 0x3DC3191752ACFC9D, 0x3A26CB6629532DBF //A0
+data8 0x41BC8CFC051191BD, 0x3E68A84DA4E62AF2 //A1
+data8 0x43797926294A0148, 0x400F345FF3723CFF //A2
+data8 0xF26D2AF700B82625, 0x00004053 //A3
+data8 0xA238B24A4B1F7B15, 0x00004070 //A4
+data8 0xE793B5C0A41A264F, 0x0000408C //A5
+data8 0x4A9585BDDACE863D //A6
+data8 0x4C6075953448088A //A7
+data8 0x4E29B2F38D1FC670 //A8
+data8 0x4FF4619B079C440F //A9
+data8 0x51C05DAE118D8AD9 //A10
+data8 0x538A8C7F87326AD4 //A11
+data8 0x5555B6937588DAB3 //A12
+data8 0x5721E1F8B6E6A7DB //A13
+data8 0x58EDA1D7A77DD6E5 //A14
+data8 0x5AB8A9616B7DC9ED //A15
+data8 0x5C84942AA209ED17 //A16
+data8 0x5E518FC34C6F54EF //A17
+data8 0x601FB3F17BCCD9A0 //A18
+data8 0x61E61128D512FE97 //A1
+// Polynomial coefficients for right root on [-14, -13]
+// Lgammal is aproximated by polynomial within [-.154151 ; .154151 ] range
+data8 0xBE170D646421B3F5, 0xBAAD95F79FCB5097 //A0
+data8 0x41F7328CBFCD9AC7, 0x3E743B8B1E8AEDB1 //A1
+data8 0x43F0D0FA2DBDA237, 0x40A0422D6A227B55 //A2
+data8 0x82082DF2D32686CC, 0x0000405F //A3
+data8 0x8D64EE9B42E68B43, 0x0000407F //A4
+data8 0xA3FFD82E08C5F1F1, 0x0000409F //A5
+data8 0x4BF8C49D99123454 //A6
+data8 0x4DFEC79DDF11342F //A7
+data8 0x50038615A892F6BD //A8
+data8 0x520929453DB32EF1 //A9
+data8 0x54106A7808189A7F //A10
+data8 0x5615A302D03C207B //A11
+data8 0x581CC175AA736F5E //A12
+data8 0x5A233E071147C017 //A13
+data8 0x5C29E81917243F22 //A14
+data8 0x5E3184B0B5AC4707 //A15
+data8 0x6037C11DE62D8388 //A16
+data8 0x6240787C4B1C9D6C //A17
+data8 0x6448289235E80977 //A18
+data8 0x664B5352C6C3449E //A19
+// Polynomial coefficients for right root on [-15, -14]
+// Lgammal is aproximated by polynomial within [-.154151 ; .154151 ] range
+data8 0x3E562C2E34A9207D, 0x3ADC00DA3DFF7A83 //A0
+data8 0x42344C3B2F0D90AB, 0x3EB8A2E979F24536 //A1
+data8 0x4469BFFF28B50D07, 0x41181E3D05C1C294 //A2
+data8 0xAE38F64DCB24D9F8, 0x0000406A //A3
+data8 0xA5C3F52C1B350702, 0x0000408E //A4
+data8 0xA83BC857BCD67A1B, 0x000040B2 //A5
+data8 0x4D663B4727B4D80A //A6
+data8 0x4FA82C965B0F7788 //A7
+data8 0x51EAD58C02908D95 //A8
+data8 0x542E427970E073D8 //A9
+data8 0x56714644C558A818 //A10
+data8 0x58B3EC2040C77BAE //A11
+data8 0x5AF72AE6A83D45B1 //A12
+data8 0x5D3B214F611F5D12 //A13
+data8 0x5F7FF5E49C54E92A //A14
+data8 0x61C2E917AB765FB2 //A15
+data8 0x64066FD70907B4C1 //A16
+data8 0x664B3998D60D0F9B //A17
+data8 0x689178710782FA8B //A18
+data8 0x6AD14A66C1C7BEC3 //A19
+// Polynomial coefficients for right root on [-16, -15]
+// Lgammal is aproximated by polynomial within [-.154151 ; .154151 ] range
+data8 0xBE6D7E7192615BAE, 0xBB0137677D7CC719 //A0
+data8 0x4273077763F6628C, 0x3F09250FB8FC8EC9 //A1
+data8 0x44E6A1BF095B1AB3, 0x4178D5A74F6CB3B3 //A2
+data8 0x8F8E0D5060FCC76E, 0x00004076 //A3
+data8 0x800CC1DCFF092A63, 0x0000409E //A4
+data8 0xF3AB0BA9D14CDA72, 0x000040C5 //A5
+data8 0x4EDE3000A2F6D54F //A6
+data8 0x515EC613B9C8E241 //A7
+data8 0x53E003309FEEEA96 //A8
+data8 0x5660ED908D7C9A90 //A9
+data8 0x58E21E9B517B1A50 //A10
+data8 0x5B639745E4374EE2 //A11
+data8 0x5DE55BB626B2075D //A12
+data8 0x606772B7506BA747 //A13
+data8 0x62E9E581AB2E057B //A14
+data8 0x656CBAD1CF85D396 //A15
+data8 0x67EFF4EBD7989872 //A16
+data8 0x6A722D2B19B7E2F9 //A17
+data8 0x6CF5DEB3073B0743 //A18
+data8 0x6F744AC11550B93A //A19
+// Polynomial coefficients for right root on [-17, -16]
+// Lgammal is aproximated by polynomial within [-.154151 ; .154151 ] range
+data8 0xBEDCC6291188207E, 0xBB872E3FDD48F5B7 //A0
+data8 0x42B3076EE7525EF9, 0x3F6687A5038CA81C //A1
+data8 0x4566A1AAD96EBCB5, 0x421F0FEDFBF548D2 //A2
+data8 0x8F8D4D3DE9850DBA, 0x00004082 //A3
+data8 0x800BDD6DA2CE1859, 0x000040AE //A4
+data8 0xF3A8EC4C9CDC1CE5, 0x000040D9 //A5
+data8 0x505E2FAFDB812628 //A6
+data8 0x531EC5B3A7508719 //A7
+data8 0x55E002F77E99B628 //A8
+data8 0x58A0ED4C9B4DAE54 //A9
+data8 0x5B621E4A8240F90C //A10
+data8 0x5E2396E5C8849814 //A11
+data8 0x60E55B43D8C5CE71 //A12
+data8 0x63A7722F5D45D01D //A13
+data8 0x6669E4E010DCE45A //A14
+data8 0x692CBA120D5E78F6 //A15
+data8 0x6BEFF4045350B22E //A16
+data8 0x6EB22C9807C21819 //A17
+data8 0x7175DE20D04617C4 //A18
+data8 0x74344AB87C6D655F //A19
+// Polynomial coefficients for right root on [-18, -17]
+// Lgammal is aproximated by polynomial within [-.154151 ; .154151 ] range
+data8 0xBF28AEEE7B61D77C, 0xBBDBBB5FC57ABF79 //A0
+data8 0x42F436F56B3B8A0C, 0x3FA43EE3C5C576E9 //A1
+data8 0x45E98A22535D115D, 0x42984678BE78CC48 //A2
+data8 0xAC176F3775E6FCFC, 0x0000408E //A3
+data8 0xA3114F53A9FEB922, 0x000040BE //A4
+data8 0xA4D168A8334ABF41, 0x000040EE //A5
+data8 0x51E5B0E7EC7182BB //A6
+data8 0x54E77D67B876EAB6 //A7
+data8 0x57E9F7C30C09C4B6 //A8
+data8 0x5AED29B0488614CA //A9
+data8 0x5DF09486F87E79F9 //A10
+data8 0x60F30B199979654E //A11
+data8 0x63F60E02C7DCCC5F //A12
+data8 0x66F9B8A00EB01684 //A13
+data8 0x69FE2D3ED0700044 //A14
+data8 0x6D01C8363C7DCC84 //A15
+data8 0x700502B29C2F06E3 //A16
+data8 0x730962B4500F4A61 //A17
+data8 0x76103C6ED099192A //A18
+data8 0x79100C7132CFD6E3 //A19
+// Polynomial coefficients for right root on [-19, -18]
+// Lgammal is aproximated by polynomial within [-.154151 ; .154151 ] range
+data8 0x3F3C19A53328A0C3, 0x3BE04ADC3FBE1458 //A0
+data8 0x4336C16C16C16C19, 0x3FE58CE3AC4A7C28 //A1
+data8 0x46702E85C0898B70, 0x432C922E412CEC6E //A2
+data8 0xF57B99A1C034335D, 0x0000409A //A3
+data8 0x82EC9634223DF909, 0x000040CF //A4
+data8 0x94F66D7557E2EA60, 0x00004103 //A5
+data8 0x5376118B79AE34D0 //A6
+data8 0x56BAE7106D52E548 //A7
+data8 0x5A00BD48CC8E25AB //A8
+data8 0x5D4529722821B493 //A9
+data8 0x608B1654AF31BBC1 //A10
+data8 0x63D182CC98AEA859 //A11
+data8 0x6716D43D5EEB05E8 //A12
+data8 0x6A5DF884FC172E1C //A13
+data8 0x6DA3CA7EBB97976B //A14
+data8 0x70EA416D0BE6D2EF //A15
+data8 0x743176C31EBB65F2 //A16
+data8 0x7777C401A8715CF9 //A17
+data8 0x7AC1110C6D350440 //A18
+data8 0x7E02D0971CF84865 //A19
+// Polynomial coefficients for right root on [-20, -19]
+// Lgammal is aproximated by polynomial within [-.154151 ; .154151 ] range
+data8 0xBFAB767F9BE21803, 0xBC5ACEF5BB1BD8B5 //A0
+data8 0x4379999999999999, 0x4029241C7F5914C8 //A1
+data8 0x46F47AE147AE147A, 0x43AC2979B64B9D7E //A2
+data8 0xAEC33E1F67152993, 0x000040A7 //A3
+data8 0xD1B71758E219616F, 0x000040DF //A4
+data8 0x8637BD05AF6CF468, 0x00004118 //A5
+data8 0x55065E9F80F293DE //A6
+data8 0x588EADA78C44EE66 //A7
+data8 0x5C15798EE22DEF09 //A8
+data8 0x5F9E8ABFD644FA63 //A9
+data8 0x6325FD7FE29BD7CD //A10
+data8 0x66AFFC5C57E1F802 //A11
+data8 0x6A3774CD7D5C0181 //A12
+data8 0x6DC152724DE2A6FE //A13
+data8 0x7149BB138EB3D0C2 //A14
+data8 0x74D32FF8A70896C2 //A15
+data8 0x785D3749F9C72BD7 //A16
+data8 0x7BE5CCF65EBC4E40 //A17
+data8 0x7F641A891B5FC652 //A18
+data8 0x7FEFFFFFFFFFFFFF //A19
+LOCAL_OBJECT_END(lgammal_right_roots_polynomial_data)
+
+LOCAL_OBJECT_START(lgammal_left_roots_polynomial_data)
+// Polynomial coefficients for left root on [-3, -2]
+// Lgammal is aproximated by polynomial within [.084641 ; -.059553 ] range
+data8 0xBC0844590979B82E, 0xB8BC7CE8CE2ECC3B //A0
+data8 0xBFFEA12DA904B18C, 0xBC91A6B2BAD5EF6E //A1
+data8 0x4023267F3C265A51, 0x3CD7055481D03AED //A2
+data8 0xA0C2D618645F8E00, 0x0000C003 //A3
+data8 0xFA8256664F8CD2BE, 0x00004004 //A4
+data8 0xC2C422C103F57158, 0x0000C006 //A5
+data8 0x4084373F7CC70AF5 //A6
+data8 0xC0A12239BDD6BB95 //A7
+data8 0x40BDBA65E2709397 //A8
+data8 0xC0DA2D2504DFB085 //A9
+data8 0x40F758173CA5BF3C //A10
+data8 0xC11506C65C267E72 //A11
+data8 0x413318EE3A6B05FC //A12
+data8 0xC1517767F247DA98 //A13
+data8 0x41701237B4754D73 //A14
+data8 0xC18DB8A03BC5C3D8 //A15
+data8 0x41AB80953AC14A07 //A16
+data8 0xC1C9B7B76638D0A4 //A17
+data8 0x41EA727E3033E2D9 //A18
+data8 0xC20812C297729142 //A19
+//
+// Polynomial coefficients for left root on [-4, -3]
+// Lgammal is aproximated by polynomial within [.147147 ; -.145158 ] range
+data8 0xBC3130AE5C4F54DB, 0xB8ED23294C13398A //A0
+data8 0xC034B99D966C5646, 0xBCE2E5FE3BC3DBB9 //A1
+data8 0x406F76DEAE0436BD, 0x3D14974DDEC057BD //A2
+data8 0xE929ACEA5979BE96, 0x0000C00A //A3
+data8 0xF47C14F8A0D52771, 0x0000400E //A4
+data8 0x88B7BC036937481C, 0x0000C013 //A5
+data8 0x4173E8F3AB9FC266 //A6
+data8 0xC1B7DBBE062FB11B //A7
+data8 0x41FD2F76DE7A47A7 //A8
+data8 0xC242225FE53B124D //A9
+data8 0x4286D12AE2FBFA30 //A10
+data8 0xC2CCFFC267A3C4C0 //A11
+data8 0x431294E10008E014 //A12
+data8 0xC357FAC8C9A2DF6A //A13
+data8 0x439F2190AB9FAE01 //A14
+data8 0xC3E44C1D8E8C67C3 //A15
+data8 0x442A8901105D5A38 //A16
+data8 0xC471C4421E908C3A //A17
+data8 0x44B92CD4D59D6D17 //A18
+data8 0xC4FB3A078B5247FA //A19
+// Polynomial coefficients for left root on [-5, -4]
+// Lgammal is aproximated by polynomial within [.155671 ; -.155300 ] range
+data8 0xBC57BF3C6E8A94C1, 0xB902FB666934AC9E //A0
+data8 0xC05D224A3EF9E41F, 0xBCF6F5713913E440 //A1
+data8 0x40BB533C678A3955, 0x3D688E53E3C72538 //A2
+data8 0x869FBFF732E99B84, 0x0000C012 //A3
+data8 0xBA9537AD61392DEC, 0x00004018 //A4
+data8 0x89EAE8B1DEA06B05, 0x0000C01F //A5
+data8 0x425A8C5C53458D3C //A6
+data8 0xC2C5068B3ED6509B //A7
+data8 0x4330FFA575E99B4E //A8
+data8 0xC39BEC12DDDF7669 //A9
+data8 0x44073825725F74F9 //A10
+data8 0xC47380EBCA299047 //A11
+data8 0x44E084DD9B666437 //A12
+data8 0xC54C2DA6BF787ACF //A13
+data8 0x45B82D65C8D6FA42 //A14
+data8 0xC624D62113FE950A //A15
+data8 0x469200CC19B45016 //A16
+data8 0xC6FFDDC6DD938E2E //A17
+data8 0x476DD7C07184B9F9 //A18
+data8 0xC7D554A30085C052 //A19
+// Polynomial coefficients for left root on [-6, -5]
+// Lgammal is aproximated by polynomial within [.157425 ; -.157360 ] range
+data8 0x3C9E20A87C8B79F1, 0x39488BE34B2427DB //A0
+data8 0xC08661F6A43A5E12, 0xBD3D912526D759CC //A1
+data8 0x410F79DCB794F270, 0x3DB9BEE7CD3C1BF5 //A2
+data8 0xEB7404450D0005DB, 0x0000C019 //A3
+data8 0xF7AE9846DFE4D4AB, 0x00004022 //A4
+data8 0x8AF535855A95B6DA, 0x0000C02C //A5
+data8 0x43544D54E9FE240E //A6
+data8 0xC3E8684E40CE6CFC //A7
+data8 0x447DF44C1D803454 //A8
+data8 0xC512AC305439B2BA //A9
+data8 0x45A79226AF79211A //A10
+data8 0xC63E0DFF7244893A //A11
+data8 0x46D35216C3A83AF3 //A12
+data8 0xC76903BE0C390E28 //A13
+data8 0x48004A4DECFA4FD5 //A14
+data8 0xC8954FBD243DB8BE //A15
+data8 0x492BF3A31EB18DDA //A16
+data8 0xC9C2C6A864521F3A //A17
+data8 0x4A5AB127C62E8DA1 //A18
+data8 0xCAECF60EF3183C57 //A19
+// Polynomial coefficients for left root on [-7, -6]
+// Lgammal is aproximated by polynomial within [.157749 ; -.157739 ] range
+data8 0x3CC9B9E8B8D551D6, 0x3961813C8E1E10DB //A0
+data8 0xC0B3ABF7A5CEA91F, 0xBD55638D4BCB4CC4 //A1
+data8 0x4168349A25504236, 0x3E0287ECE50CCF76 //A2
+data8 0x9EC8ED6E4C219E67, 0x0000C022 //A3
+data8 0x9279EB1B799A3FF3, 0x0000402E //A4
+data8 0x90213EF8D9A5DBCF, 0x0000C03A //A5
+data8 0x4462775E857FB71C //A6
+data8 0xC52377E70B45FDBF //A7
+data8 0x45E4F3D28EDA8C28 //A8
+data8 0xC6A6E85571BD2D0B //A9
+data8 0x47695BB17E74DF74 //A10
+data8 0xC82C5AC0ED6A662F //A11
+data8 0x48EFF8159441C2E3 //A12
+data8 0xC9B22602C1B68AE5 //A13
+data8 0x4A74BA8CE7B34100 //A14
+data8 0xCB37C7E208482E4B //A15
+data8 0x4BFB5A1D57352265 //A16
+data8 0xCCC01CB3021212FF //A17
+data8 0x4D841613AC3431D1 //A18
+data8 0xCE431C9E9EE43AD9 //A19
+// Polynomial coefficients for left root on [-8, -7]
+// Lgammal is aproximated by polynomial within [.157799 ; -.157798 ] range
+data8 0xBCF9C7A33AD9478C, 0xB995B0470F11E5ED //A0
+data8 0xC0E3AF76FE4C2F8B, 0xBD8DBCD503250511 //A1
+data8 0x41C838E76CAAF0D5, 0x3E5D79F5E2E069C3 //A2
+data8 0x9EF345992B262CE0, 0x0000C02B //A3
+data8 0x92AE0292985FD559, 0x0000403A //A4
+data8 0x90615420C08F7D8C, 0x0000C049 //A5
+data8 0x45828139342CEEB7 //A6
+data8 0xC67384066C31E2D3 //A7
+data8 0x476502BC4DAC2C35 //A8
+data8 0xC856FAADFF22ADC6 //A9
+data8 0x49497243255AB3CE //A10
+data8 0xCA3C768489520F6B //A11
+data8 0x4B300D1EA47AF838 //A12
+data8 0xCC223B0508AC620E //A13
+data8 0x4D14D46583338CD8 //A14
+data8 0xCE07E7A87AA068E4 //A15
+data8 0x4EFB811AD2F8BEAB //A16
+data8 0xCFF0351B51508523 //A17
+data8 0x50E4364CCBF53100 //A18
+data8 0xD1D33CFD0BF96FA6 //A19
+// Polynomial coefficients for left root on [-9, -8]
+// Lgammal is aproximated by polynomial within [.157806 ; -.157806 ] range
+data8 0x3D333E4438B1B9D4, 0x39E7B956B83964C1 //A0
+data8 0xC11625EDFC63DCD8, 0xBDCF39625709EFAC //A1
+data8 0x422EA8C150480F16, 0x3EC16ED908AB7EDD //A2
+data8 0xE2598725E2E11646, 0x0000C034 //A3
+data8 0xEAFF2346DE3EBC98, 0x00004046 //A4
+data8 0x821E90DE12A0F05F, 0x0000C059 //A5
+data8 0x46B2C334AE5366FE //A6
+data8 0xC7D64314B43191B6 //A7
+data8 0x48FAF6ED5899E01B //A8
+data8 0xCA2096E4472AF37D //A9
+data8 0x4B44AAF49FB7E4C8 //A10
+data8 0xCC6A02469F2BD920 //A11
+data8 0x4D9080626D2EFC07 //A12
+data8 0xCEB515EDCF0695F7 //A13
+data8 0x4FDB1AC69BF36960 //A14
+data8 0xD1017F8274339270 //A15
+data8 0x5226A684961BAE2F //A16
+data8 0xD34E085C088404A5 //A17
+data8 0x547511892FF8960E //A18
+data8 0xD5968FA3B1ED67A9 //A19
+// Polynomial coefficients for left root on [-10, -9]
+// Lgammal is aproximated by polynomial within [.157807 ; -.157807 ] range
+data8 0xBD355818A2B42BA2, 0xB9B7320B6A0D61EA //A0
+data8 0xC14BAF7DA5F3770E, 0xBDE64AF9A868F719 //A1
+data8 0x4297F3E8791F9CD3, 0x3F2A553E59B4835E //A2
+data8 0xDD0C5F7E551BD13C, 0x0000C03E //A3
+data8 0x8F6F0A3B2EB08BBB, 0x00004054 //A4
+data8 0xC68D4D5AD230BA08, 0x0000C069 //A5
+data8 0x47F1E4D8C35D1A3E //A6
+data8 0xC94A8A191DB0A466 //A7
+data8 0x4AA4174F65FE6AE8 //A8
+data8 0xCBFEE6D90F94E9DD //A9
+data8 0x4D580FD3438BE16C //A10
+data8 0xCEB2ECD456D50224 //A11
+data8 0x500E049F7FE64546 //A12
+data8 0xD167F92D9600F378 //A13
+data8 0x52C342AE2B43261A //A14
+data8 0xD41F15DEEDA4B67E //A15
+data8 0x55792638748AFB7D //A16
+data8 0xD6D4D760074F6E6B //A17
+data8 0x5832469D58ED3FA9 //A18
+data8 0xD988769F3DC76642 //A19
+// Polynomial coefficients for left root on [-11, -10]
+// Lgammal is aproximated by polynomial within [.157807 ; -.157807 ] range
+data8 0xBDA050601F39778A, 0xBA0D4D1CE53E8241 //A0
+data8 0xC18308A7D8EA4039, 0xBE370C379D3EAD41 //A1
+data8 0x4306A49380644E6C, 0x3FBBB143C0E7B5C8 //A2
+data8 0x8FA8FB233E4AA6D2, 0x0000C049 //A3
+data8 0x802CC9D8AEAC207D, 0x00004062 //A4
+data8 0xF3F73EE651A37A13, 0x0000C07A //A5
+data8 0x493E3B550A7B9568 //A6
+data8 0xCACED38DAA060929 //A7
+data8 0x4C600B346BAB3BC6 //A8
+data8 0xCDF0F719193E3D26 //A9
+data8 0x4F8229F24528B151 //A10
+data8 0xD113A4C2D32FBBE2 //A11
+data8 0x52A56BC13DC4474D //A12
+data8 0xD43785CFAF5E3CE3 //A13
+data8 0x55C9FC3EA5941202 //A14
+data8 0xD75CD545A3341AF5 //A15
+data8 0x58F009911F77C282 //A16
+data8 0xDA8246294D210BEC //A17
+data8 0x5C1608AAC32C3A8E //A18
+data8 0xDDA446E570A397D5 //A19
+// Polynomial coefficients for left root on [-12, -11]
+// Lgammal is aproximated by polynomial within [.157807 ; -.157807 ] range
+data8 0x3DEACBB3081C502E, 0x3A8AA6F01DEDF745 //A0
+data8 0xC1BC8CFBFB0A9912, 0xBE6556B6504A2AE6 //A1
+data8 0x43797926206941D7, 0x40289A9644C2A216 //A2
+data8 0xF26D2A78446D0839, 0x0000C053 //A3
+data8 0xA238B1D937FFED38, 0x00004070 //A4
+data8 0xE793B4F6DE470538, 0x0000C08C //A5
+data8 0x4A9585BDC44DC45D //A6
+data8 0xCC60759520342C47 //A7
+data8 0x4E29B2F3694C0404 //A8
+data8 0xCFF4619AE7B6BBAB //A9
+data8 0x51C05DADF52B89E8 //A10
+data8 0xD38A8C7F48819A4A //A11
+data8 0x5555B6932D687860 //A12
+data8 0xD721E1FACB6C1B5B //A13
+data8 0x58EDA1E2677C8F91 //A14
+data8 0xDAB8A8EC523C1F71 //A15
+data8 0x5C84930133F30411 //A16
+data8 0xDE51952FDFD1EC49 //A17
+data8 0x601FCCEC1BBD25F1 //A18
+data8 0xE1E5F2D76B610920 //A19
+// Polynomial coefficients for left root on [-13, -12]
+// Lgammal is aproximated by polynomial within [.157807 ; -.157807 ] range
+data8 0xBE01612F373268ED, 0xBA97B7A18CDF103B //A0
+data8 0xC1F7328CBF7A4FAC, 0xBE89A25A6952F481 //A1
+data8 0x43F0D0FA2DBDA237, 0x40A0422EC1CE6084 //A2
+data8 0x82082DF2D32686C5, 0x0000C05F //A3
+data8 0x8D64EE9B42E68B36, 0x0000407F //A4
+data8 0xA3FFD82E08C630C9, 0x0000C09F //A5
+data8 0x4BF8C49D99123466 //A6
+data8 0xCDFEC79DDF1119ED //A7
+data8 0x50038615A892D242 //A8
+data8 0xD20929453DC8B537 //A9
+data8 0x54106A78083BA1EE //A10
+data8 0xD615A302C69E27B2 //A11
+data8 0x581CC175870FF16F //A12
+data8 0xDA233E0979E12B74 //A13
+data8 0x5C29E822BC568C80 //A14
+data8 0xDE31845DB5340FBC //A15
+data8 0x6037BFC6D498D5F9 //A16
+data8 0xE2407D92CD613E82 //A17
+data8 0x64483B9B62367EB7 //A18
+data8 0xE64B2DC830E8A799 //A1
+// Polynomial coefficients for left root on [-14, -13]
+// Lgammal is aproximated by polynomial within [.157807 ; -.157807 ] range
+data8 0x3E563D0B930B371F, 0x3AE779957E14F012 //A0
+data8 0xC2344C3B2F083767, 0xBEC0B7769AA3DD66 //A1
+data8 0x4469BFFF28B50D07, 0x41181E3F13ED2401 //A2
+data8 0xAE38F64DCB24D9EE, 0x0000C06A //A3
+data8 0xA5C3F52C1B3506F2, 0x0000408E //A4
+data8 0xA83BC857BCD6BA92, 0x0000C0B2 //A5
+data8 0x4D663B4727B4D81A //A6
+data8 0xCFA82C965B0F62E9 //A7
+data8 0x51EAD58C02905B71 //A8
+data8 0xD42E427970FA56AD //A9
+data8 0x56714644C57D8476 //A10
+data8 0xD8B3EC2037EC95F2 //A11
+data8 0x5AF72AE68BBA5B3D //A12
+data8 0xDD3B2152C67AA6B7 //A13
+data8 0x5F7FF5F082861B8B //A14
+data8 0xE1C2E8BE125A5B7A //A15
+data8 0x64066E92FE9EBE7D //A16
+data8 0xE64B4201CDF9F138 //A17
+data8 0x689186351E58AA88 //A18
+data8 0xEAD132A585DFC60A //A19
+// Polynomial coefficients for left root on [-15, -14]
+// Lgammal is aproximated by polynomial within [.157807 ; -.157807 ] range
+data8 0xBE6D7DDE12700AC1, 0xBB1E025BF1667FB5 //A0
+data8 0xC273077763F60AD5, 0xBF2A1698184C7A9A //A1
+data8 0x44E6A1BF095B1AB3, 0x4178D5AE8A4A2874 //A2
+data8 0x8F8E0D5060FCC767, 0x0000C076 //A3
+data8 0x800CC1DCFF092A57, 0x0000409E //A4
+data8 0xF3AB0BA9D14D37D1, 0x0000C0C5 //A5
+data8 0x4EDE3000A2F6D565 //A6
+data8 0xD15EC613B9C8C800 //A7
+data8 0x53E003309FEECCAA //A8
+data8 0xD660ED908D8B15C4 //A9
+data8 0x58E21E9B51A1C4AE //A10
+data8 0xDB639745DB82210D //A11
+data8 0x5DE55BB60C68FCF6 //A12
+data8 0xE06772BA3FCA23C6 //A13
+data8 0x62E9E58B4F702C31 //A14
+data8 0xE56CBA49B071ABE2 //A15
+data8 0x67EFF31E4F2BA36A //A16
+data8 0xEA7232C8804F32C3 //A17
+data8 0x6CF5EFEE929A0928 //A18
+data8 0xEF742EE03EC3E8FF //A19
+// Polynomial coefficients for left root on [-16, -15]
+// Lgammal is aproximated by polynomial within [.157807 ; -.157807 ] range
+data8 0xBEDCC628FEAC7A1B, 0xBB80582C8BEBB198 //A0
+data8 0xC2B3076EE752595E, 0xBF5388F55AFAE53E //A1
+data8 0x4566A1AAD96EBCB5, 0x421F0FEFE2444293 //A2
+data8 0x8F8D4D3DE9850DB2, 0x0000C082 //A3
+data8 0x800BDD6DA2CE184C, 0x000040AE //A4
+data8 0xF3A8EC4C9CDC7A43, 0x0000C0D9 //A5
+data8 0x505E2FAFDB81263F //A6
+data8 0xD31EC5B3A7506CD9 //A7
+data8 0x55E002F77E999810 //A8
+data8 0xD8A0ED4C9B5C2900 //A9
+data8 0x5B621E4A8267C401 //A10
+data8 0xDE2396E5BFCFDA7A //A11
+data8 0x60E55B43BE6F9A79 //A12
+data8 0xE3A772324C7405FA //A13
+data8 0x6669E4E9B7E57A2D //A14
+data8 0xE92CB989F8A8FB37 //A15
+data8 0x6BEFF2368849A36E //A16
+data8 0xEEB23234FE191D55 //A17
+data8 0x7175EF5D1080B105 //A18
+data8 0xF4342ED7B1B7BE31 //A19
+// Polynomial coefficients for left root on [-17, -16]
+// Lgammal is aproximated by polynomial within [.157807 ; -.157807 ] range
+data8 0xBF28AEEE7B58C790, 0xBBC4448DE371FA0A //A0
+data8 0xC2F436F56B3B89B1, 0xBF636755245AC63A //A1
+data8 0x45E98A22535D115D, 0x4298467DA93DB784 //A2
+data8 0xAC176F3775E6FCF2, 0x0000C08E //A3
+data8 0xA3114F53A9FEB908, 0x000040BE //A4
+data8 0xA4D168A8334AFE5A, 0x0000C0EE //A5
+data8 0x51E5B0E7EC7182CF //A6
+data8 0xD4E77D67B876D6B4 //A7
+data8 0x57E9F7C30C098C83 //A8
+data8 0xDAED29B0489EF7A7 //A9
+data8 0x5DF09486F8A524B8 //A10
+data8 0xE0F30B19910A2393 //A11
+data8 0x63F60E02AB3109F4 //A12
+data8 0xE6F9B8A3431854D5 //A13
+data8 0x69FE2D4A6D94218E //A14
+data8 0xED01C7E272A73560 //A15
+data8 0x7005017D82B186B6 //A16
+data8 0xF3096A81A69BD8AE //A17
+data8 0x76104951BAD67D5C //A18
+data8 0xF90FECC99786FD5B //A19
+// Polynomial coefficients for left root on [-18, -17]
+// Lgammal is aproximated by polynomial within [.157807 ; -.157807 ] range
+data8 0x3F3C19A53328E26A, 0x3BE238D7BA036B3B //A0
+data8 0xC336C16C16C16C13, 0xBFEACE245DEC56F3 //A1
+data8 0x46702E85C0898B70, 0x432C922B64FD1DA4 //A2
+data8 0xF57B99A1C0343350, 0x0000C09A //A3
+data8 0x82EC9634223DF90D, 0x000040CF //A4
+data8 0x94F66D7557E3237D, 0x0000C103 //A5
+data8 0x5376118B79AE34D6 //A6
+data8 0xD6BAE7106D52CE49 //A7
+data8 0x5A00BD48CC8E11AB //A8
+data8 0xDD4529722833E2DF //A9
+data8 0x608B1654AF5F46AF //A10
+data8 0xE3D182CC90D8723F //A11
+data8 0x6716D43D46706AA0 //A12
+data8 0xEA5DF888C5B428D3 //A13
+data8 0x6DA3CA85888931A6 //A14
+data8 0xF0EA40EF2AC7E070 //A15
+data8 0x743175D1A251AFCD //A16
+data8 0xF777CB6E2B550D73 //A17
+data8 0x7AC11E468A134A51 //A18
+data8 0xFE02B6BDD0FC40AA //A19
+// Polynomial coefficients for left root on [-19, -18]
+// Lgammal is aproximated by polynomial within [.157807 ; -.157807 ] range
+data8 0xBFAB767F9BE217FC, 0xBC4A5541CE0D8D0D //A0
+data8 0xC379999999999999, 0xC01A84981B490BE8 //A1
+data8 0x46F47AE147AE147A, 0x43AC2987BBC466EB //A2
+data8 0xAEC33E1F67152987, 0x0000C0A7 //A3
+data8 0xD1B71758E2196153, 0x000040DF //A4
+data8 0x8637BD05AF6D420E, 0x0000C118 //A5
+data8 0x55065E9F80F293B2 //A6
+data8 0xD88EADA78C44BFA7 //A7
+data8 0x5C15798EE22EC6CD //A8
+data8 0xDF9E8ABFD67895CF //A9
+data8 0x6325FD7FE13B0DE0 //A10
+data8 0xE6AFFC5C3DE70858 //A11
+data8 0x6A3774CE81C70D43 //A12
+data8 0xEDC1527412D8129F //A13
+data8 0x7149BABCDA8B7A72 //A14
+data8 0xF4D330AD49071BB5 //A15
+data8 0x785D4046F4C5F1FD //A16
+data8 0xFBE59BFEDBA73FAF //A17
+data8 0x7F64BEF2B2EC8DA1 //A18
+data8 0xFFEFFFFFFFFFFFFF //A19
+LOCAL_OBJECT_END(lgammal_left_roots_polynomial_data)
+
+
+//==============================================================
+// Code
+//==============================================================
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_lgammal)
+{ .mfi
+ getf.exp rSignExpX = f8
+ // Test x for NaTVal, NaN, +/-0, +/-INF, denormals
+ fclass.m p6,p0 = f8,0x1EF
+ addl r17Ones = 0x1FFFF, r0 // exponent mask
+}
+{ .mfi
+ addl GR_ad_z_1 = @ltoff(Constants_Z_1#),gp
+ fcvt.fx.s1 fXint = f8 // Convert arg to int (int repres. in FR)
+ adds rDelta = 0x3FC, r0
+}
+;;
+{ .mfi
+ getf.sig rSignifX = f8
+ fcmp.lt.s1 p15, p14 = f8, f0
+ shl rDelta = rDelta, 20 // single precision 1.5
+}
+{ .mfi
+ ld8 GR_ad_z_1 = [GR_ad_z_1]// get pointer to Constants_Z_1
+ fma.s1 fTwo = f1, f1, f1 // 2.0
+ addl rExp8 = 0x10002, r0 // exponent of 8.0
+}
+;;
+{ .mfi
+ alloc rPFS_SAVED = ar.pfs, 0, 34, 4, 0 // get some registers
+ fmerge.s fAbsX = f1, f8 // |x|
+ and rExpX = rSignExpX, r17Ones // mask sign bit
+}
+{ .mib
+ addl rExpHalf = 0xFFFE, r0 // exponent of 0.5
+ addl rExp2 = 0x10000, r0 // exponent of 2.0
+ // branch out if x is NaTVal, NaN, +/-0, +/-INF, or denormalized number
+(p6) br.cond.spnt lgammal_spec
+}
+;;
+_deno_back_to_main_path:
+{ .mfi
+ // Point to Constants_G_H_h1
+ add rTbl1Addr = 0x040, GR_ad_z_1
+ frcpa.s1 fRcpX, p0 = f1, f8 // initial approximation of 1/x
+ extr.u GR_Index1 = rSignifX, 59, 4
+}
+{ .mib
+(p14) cmp.ge.unc p8, p0 = rExpX, rExp8 // p8 = 1 if x >= 8.0
+ adds rZ625 = 0x3F2, r0
+(p8) br.cond.spnt lgammal_big_positive // branch out if x >= 8.0
+}
+;;
+{ .mfi
+ shladd rZ1offsett = GR_Index1, 2, GR_ad_z_1 // Point to Z_1
+ fmerge.se fSignifX = f1, f8 // sifnificand of x
+ // Get high 15 bits of significand
+ extr.u GR_X_0 = rSignifX, 49, 15
+}
+{ .mib
+ cmp.lt.unc p9, p0 = rExpX, rExpHalf // p9 = 1 if |x| < 0.5
+ // set p11 if 2 <= x < 4
+(p14) cmp.eq.unc p11, p0 = rExpX, rExp2
+(p9) br.cond.spnt lgammal_0_half // branch out if |x| < 0.5
+}
+;;
+{ .mfi
+ ld4 GR_Z_1 = [rZ1offsett] // Load Z_1
+ fms.s1 fA5L = f1, f1, f8 // for 0.75 <= x < 1.3125 path
+ shl rZ625 = rZ625, 20 // sinfle precision 0.625
+}
+{ .mib
+ setf.s FR_MHalf = rDelta
+ // set p10 if x >= 4.0
+(p14) cmp.gt.unc p10, p0 = rExpX, rExp2
+ // branch to special path for 4.0 <= x < 8
+(p10) br.cond.spnt lgammal_4_8
+}
+;;
+{ .mfi
+ // for 1.3125 <= x < 1.5625 path
+ addl rPolDataPtr= @ltoff(lgammal_loc_min_data),gp
+ // argument of polynomial approximation for 1.5625 <= x < 2.25
+ fms.s1 fB4 = f8, f1, fTwo
+ cmp.eq p12, p0 = rExpX, rExpHalf
+}
+{ .mib
+ addl rExpOne = 0xFFFF, r0 // exponent of 1.0
+ // set p10 if significand of x >= 1.125
+(p11) cmp.le p11, p0 = 2, GR_Index1
+(p11) br.cond.spnt lgammal_2Q_4
+}
+;;
+{ .mfi
+ // point to xMin for 1.3125 <= x < 1.5625 path
+ ld8 rPolDataPtr = [rPolDataPtr]
+ fcvt.xf fFltIntX = fXint // RTN(x)
+(p14) cmp.eq.unc p13, p7 = rExpX, rExpOne // p13 set if 1.0 <= x < 2.0
+}
+{ .mib
+ setf.s FR_FracX = rZ625
+ // set p12 if |x| < 0.75
+(p12) cmp.gt.unc p12, p0 = 8, GR_Index1
+ // branch out to special path for |x| < 0.75
+(p12) br.cond.spnt lgammal_half_3Q
+}
+;;
+.pred.rel "mutex", p7, p13
+{ .mfi
+ getf.sig rXRnd = fXint // integer part of the input value
+ fnma.s1 fInvX = f8, fRcpX, f1 // start of 1st NR iteration
+ // Get bits 30-15 of X_0 * Z_1
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15
+}
+{ .mib
+(p7) cmp.eq p6, p0 = rExpX, rExp2 // p6 set if 2.0 <= x < 2.25
+(p13) cmp.le p6, p0 = 9, GR_Index1
+ // branch to special path 1.5625 <= x < 2.25
+(p6) br.cond.spnt lgammal_13Q_2Q
+}
+;;
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mfi
+ shladd GR_ad_tbl_1 = GR_Index1, 4, rTbl1Addr // Point to G_1
+ fma.s1 fSix = fTwo, fTwo, fTwo // 6.0
+ add GR_ad_q = -0x60, GR_ad_z_1 // Point to Constants_Q
+}
+{ .mib
+ add rTmpPtr3 = -0x50, GR_ad_z_1
+(p13) cmp.gt p7, p0 = 5, GR_Index1
+ // branch to special path 0.75 <= x < 1.3125
+(p7) br.cond.spnt lgammal_03Q_1Q
+}
+;;
+{ .mfi
+ add rTmpPtr = 8, GR_ad_tbl_1
+ fma.s1 fRoot = f8, f1, f1 // x + 1
+ // Absolute value of int arg. Will be used as index in table with roots
+ sub rXRnd = r0, rXRnd
+}
+{ .mib
+ ldfe fA5L = [rPolDataPtr], 16 // xMin
+ addl rNegSingularity = 0x3003E, r0
+(p14) br.cond.spnt lgammal_loc_min
+}
+;;
+{ .mfi
+ ldfps FR_G, FR_H = [GR_ad_tbl_1], 8 // Load G_1, H_1
+ nop.f 0
+ add rZ2Addr = 0x140, GR_ad_z_1 // Point to Constants_Z_2
+}
+{ .mib
+ ldfd FR_h = [rTmpPtr] // Load h_1
+ // If arg is less or equal to -2^63
+ cmp.geu.unc p8,p0 = rSignExpX, rNegSingularity
+ // Singularity for x < -2^63 since all such arguments are integers
+ // branch to special code which deals with singularity
+(p8) br.cond.spnt lgammal_singularity
+}
+;;
+{ .mfi
+ ldfe FR_log2_hi = [GR_ad_q], 32 // Load log2_hi
+ nop.f 0
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract bits 6-9 of X_1
+}
+{ .mfi
+ ldfe FR_log2_lo = [rTmpPtr3], 32 // Load log2_lo
+ fms.s1 fDx = f8, f1, fFltIntX // x - RTN(x)
+ // index in table with roots and bounds
+ adds rXint = -2, rXRnd
+}
+;;
+{ .mfi
+ ldfe FR_Q4 = [GR_ad_q], 32 // Load Q4
+ nop.f 0
+ // set p12 if x may be close to negative root: -19.5 < x < -2.0
+ cmp.gtu p12, p0 = 18, rXint
+}
+{ .mfi
+ shladd GR_ad_z_2 = GR_Index2, 2, rZ2Addr // Point to Z_2
+ fma.s1 fRcpX = fInvX, fRcpX, fRcpX // end of 1st NR iteration
+ // Point to Constants_G_H_h2
+ add rTbl2Addr = 0x180, GR_ad_z_1
+}
+;;
+{ .mfi
+ shladd GR_ad_tbl_2 = GR_Index2, 4, rTbl2Addr // Point to G_2
+ // set p9 if x is integer and negative
+ fcmp.eq.s1 p9, p0 = f8,fFltIntX
+ // Point to Constants_G_H_h3
+ add rTbl3Addr = 0x280, GR_ad_z_1
+}
+{ .mfi
+ ld4 GR_Z_2 = [GR_ad_z_2] // Load Z_2
+ nop.f 0
+ sub GR_N = rExpX, rExpHalf, 1
+}
+;;
+{ .mfi
+ ldfe FR_Q3 = [rTmpPtr3], 32 // Load Q3
+ nop.f 0
+ // Point to lnsin polynomial coefficients
+ adds rLnSinDataPtr = 864, rTbl3Addr
+}
+{ .mfi
+ ldfe FR_Q2 = [GR_ad_q],32 // Load Q2
+ nop.f 0
+ add rTmpPtr = 8, GR_ad_tbl_2
+}
+;;
+{ .mfi
+ ldfe FR_Q1 = [rTmpPtr3] // Load Q1
+ fcmp.lt.s1 p0, p15 = fAbsX, fSix // p15 is set when x < -6.0
+ // point to table with roots and bounds
+ adds rRootsBndAddr = -1296, GR_ad_z_1
+}
+{ .mfb
+ // Put integer N into rightmost significand
+ setf.sig fFloatN = GR_N
+ fma.s1 fThirteen = fSix, fTwo, f1 // 13.0
+ // Singularity if -2^63 < x < 0 and x is integer
+ // branch to special code which deals with singularity
+(p9) br.cond.spnt lgammal_singularity
+}
+;;
+{ .mfi
+ ldfps FR_G2, FR_H2 = [GR_ad_tbl_2] // Load G_2, H_2
+ // y = |x|/2^(exponent(x)) - 1.5
+ fms.s1 FR_FracX = fSignifX, f1, FR_MHalf
+ // Get bits 30-15 of X_1 * Z_2
+ pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15
+}
+{ .mfi
+ ldfd FR_h2 = [rTmpPtr] // Load h_2
+ fma.s1 fDxSqr = fDx, fDx, f0 // deltaX^2
+ adds rTmpPtr3 = 128, rLnSinDataPtr
+}
+;;
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mfi
+ getf.exp rRoot = fRoot // sign and biased exponent of (x + 1)
+ nop.f 0
+ // set p6 if -4 < x <= -2
+ cmp.eq p6, p0 = rExpX, rExp2
+}
+{ .mfi
+ ldfpd fLnSin2, fLnSin2L = [rLnSinDataPtr], 16
+ fnma.s1 fInvX = f8, fRcpX, f1 // start of 2nd NR iteration
+ sub rIndexPol = rExpX, rExpHalf // index of polynom
+}
+;;
+{ .mfi
+ ldfe fLnSin4 = [rLnSinDataPtr], 96
+ // p10 is set if x is potential "right" root
+ // p11 set for possible "left" root
+ fcmp.lt.s1 p10, p11 = fDx, f0
+ shl rIndexPol = rIndexPol, 6 // (i*16)*4
+}
+{ .mfi
+ ldfpd fLnSin18, fLnSin20 = [rTmpPtr3], 16
+ nop.f 0
+ mov rExp2tom7 = 0x0fff8 // Exponent of 2^-7
+}
+;;
+{ .mfi
+ getf.sig rSignifDx = fDx // Get significand of RTN(x)
+ nop.f 0
+ // set p6 if -4 < x <= -3.0
+(p6) cmp.le.unc p6, p0 = 0x8, GR_Index1
+}
+{ .mfi
+ ldfpd fLnSin22, fLnSin24 = [rTmpPtr3], 16
+ nop.f 0
+ // mask sign bit in the exponent of (x + 1)
+ and rRoot = rRoot, r17Ones
+}
+;;
+{ .mfi
+ ldfe fLnSin16 = [rLnSinDataPtr], -80
+ nop.f 0
+ extr.u GR_Index3 = GR_X_2, 1, 5 // Extract bits 1-5 of X_2
+}
+{ .mfi
+ ldfpd fLnSin26, fLnSin28 = [rTmpPtr3], 16
+ nop.f 0
+ and rXRnd = 1, rXRnd
+}
+;;
+{ .mfi
+ shladd GR_ad_tbl_3 = GR_Index3, 4, rTbl3Addr // Point to G_3
+ fms.s1 fDxSqrL = fDx, fDx, fDxSqr // low part of deltaX^2
+ // potential "left" root
+(p11) adds rRootsBndAddr = 560, rRootsBndAddr
+}
+{ .mib
+ ldfpd fLnSin30, fLnSin32 = [rTmpPtr3], 16
+ // set p7 if |x+1| < 2^-7
+ cmp.lt p7, p0 = rRoot, rExp2tom7
+ // branch to special path for |x+1| < 2^-7
+(p7) br.cond.spnt _closeToNegOne
+}
+;;
+{ .mfi
+ ldfps FR_G3, FR_H3 = [GR_ad_tbl_3], 8 // Load G_3, H_3
+ fcmp.lt.s1 p14, p0 = fAbsX, fThirteen // set p14 if x > -13.0
+ // base address of polynomial on range [-6.0, -0.75]
+ adds rPolDataPtr = 3440, rTbl3Addr
+}
+{ .mfi
+ // (i*16)*4 + (i*16)*8 - offsett of polynomial on range [-6.0, -0.75]
+ shladd rTmpPtr = rIndexPol, 2, rIndexPol
+ fma.s1 fXSqr = FR_FracX, FR_FracX, f0 // y^2
+ // point to left "near root" bound
+(p12) shladd rRootsBndAddr = rXint, 4, rRootsBndAddr
+}
+;;
+{ .mfi
+ ldfpd fLnSin34, fLnSin36 = [rTmpPtr3], 16
+ fma.s1 fRcpX = fInvX, fRcpX, fRcpX // end of 2nd NR iteration
+ // add special offsett if -4 < x <= -3.0
+(p6) adds rPolDataPtr = 640, rPolDataPtr
+}
+{ .mfi
+ // point to right "near root" bound
+ adds rTmpPtr2 = 8, rRootsBndAddr
+ fnma.s1 fMOne = f1, f1, f0 // -1.0
+ // Point to Bernulli numbers
+ adds rBernulliPtr = 544, rTbl3Addr
+}
+;;
+{ .mfi
+ // left bound of "near root" range
+(p12) ld8 rLeftBound = [rRootsBndAddr]
+ fmerge.se fNormDx = f1, fDx // significand of DeltaX
+ // base address + offsett for polynomial coeff. on range [-6.0, -0.75]
+ add rPolDataPtr = rPolDataPtr, rTmpPtr
+}
+{ .mfi
+ // right bound of "near root" range
+(p12) ld8 rRightBound = [rTmpPtr2]
+ fcvt.xf fFloatN = fFloatN
+ // special "Bernulli" numbers for Stirling's formula for -13 < x < -6
+(p14) adds rBernulliPtr = 160, rBernulliPtr
+}
+;;
+{ .mfi
+ ldfd FR_h3 = [GR_ad_tbl_3] // Load h_3
+ fmpy.s1 FR_G = FR_G, FR_G2 // G = G_1 * G_2
+ adds rTmpPtr3 = -160, rTmpPtr3
+}
+{ .mfb
+ adds rTmpPtr = 80, rPolDataPtr
+ fadd.s1 FR_H = FR_H, FR_H2 // H = H_1 + H_2
+ // p15 is set if -2^63 < x < 6.0 and x is not an integer
+ // branch to path with implementation using Stirling's formula for neg. x
+(p15) br.cond.spnt _negStirling
+}
+;;
+{ .mfi
+ ldfpd fA3, fA3L = [rPolDataPtr], 16 // A3
+ fma.s1 fDelX4 = fDxSqr, fDxSqr, f0 // deltaX^4
+ // Get high 4 bits of signif
+ extr.u rIndex1Dx = rSignifDx, 59, 4
+}
+{ .mfi
+ ldfe fA5 = [rTmpPtr], -16 // A5
+ fadd.s1 FR_h = FR_h, FR_h2 // h = h_1 + h_2
+ adds rLnSinTmpPtr = 16, rLnSinDataPtr
+}
+;;
+{ .mfi
+ ldfpd fA0, fA0L = [rPolDataPtr], 16 // A0
+ fma.s1 fLnSin20 = fLnSin20, fDxSqr, fLnSin18
+ // Get high 15 bits of significand
+ extr.u rX0Dx = rSignifDx, 49, 15
+}
+{ .mfi
+ ldfe fA4 = [rTmpPtr], 192 // A4
+ fms.s1 fXSqrL = FR_FracX, FR_FracX, fXSqr // low part of y^2
+ shladd GR_ad_z_1 = rIndex1Dx, 2, GR_ad_z_1 // Point to Z_1
+}
+;;
+{ .mfi
+ ldfpd fA1, fA1L = [rPolDataPtr], 16 // A1
+ fma.s1 fX4 = fXSqr, fXSqr, f0 // y^4
+ adds rTmpPtr2 = 32, rTmpPtr
+}
+{ .mfi
+ ldfpd fA18, fA19 = [rTmpPtr], 16 // A18, A19
+ fma.s1 fLnSin24 = fLnSin24, fDxSqr, fLnSin22
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fLnSin6 = [rLnSinDataPtr], 32
+ fma.s1 fLnSin28 = fLnSin28, fDxSqr, fLnSin26
+ nop.i 0
+}
+{ .mfi
+ ldfe fLnSin8 = [rLnSinTmpPtr], 32
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA20, fA21 = [rTmpPtr], 16 // A20, A21
+ fma.s1 fLnSin32 = fLnSin32, fDxSqr, fLnSin30
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA22, fA23 = [rTmpPtr2], 16 // A22, A23
+ fma.s1 fB20 = f1, f1, FR_MHalf // 2.5
+(p12) cmp.ltu.unc p6, p0 = rSignifX, rLeftBound
+}
+;;
+{ .mfi
+ ldfpd fA2, fA2L = [rPolDataPtr], 16 // A2
+ fmpy.s1 FR_G = FR_G, FR_G3 // G = (G_1 * G_2) * G_3
+ // set p6 if x falls in "near root" range
+(p6) cmp.geu.unc p6, p0 = rSignifX, rRightBound
+}
+{ .mfb
+ adds rTmpPtr3 = -64, rTmpPtr
+ fadd.s1 FR_H = FR_H, FR_H3 // H = (H_1 + H_2) + H_3
+ // branch to special path if x falls in "near root" range
+(p6) br.cond.spnt _negRoots
+}
+;;
+{ .mfi
+ ldfpd fA24, fA25 = [rTmpPtr2], 16 // A24, A25
+ fma.s1 fLnSin36 = fLnSin36, fDxSqr, fLnSin34
+(p11) cmp.eq.unc p7, p0 = 1,rXint // p7 set if -3.0 < x < -2.5
+}
+{ .mfi
+ adds rTmpPtr = -48, rTmpPtr
+ fma.s1 fLnSin20 = fLnSin20, fDxSqr, fLnSin16
+ addl rDelta = 0x5338, r0 // significand of -2.605859375
+}
+;;
+{ .mfi
+ getf.exp GR_N = fDx // Get N = exponent of DeltaX
+ fma.s1 fX6 = fX4, fXSqr, f0 // y^6
+ // p7 set if -2.605859375 <= x < -2.5
+(p7) cmp.gt.unc p7, p0 = rDelta, GR_X_0
+}
+{ .mfb
+ ld4 GR_Z_1 = [GR_ad_z_1] // Load Z_1
+ fma.s1 fDelX8 = fDelX4, fDelX4, f0 // deltaX^8
+ // branch to special path for -2.605859375 <= x < -2.5
+(p7) br.cond.spnt _neg2andHalf
+}
+;;
+{ .mfi
+ ldfpd fA14, fA15 = [rTmpPtr3], 16 // A14, A15
+ fadd.s1 FR_h = FR_h, FR_h3 // h = (h_1 + h_2) + h_3
+ adds rTmpPtr2 = 128 , rPolDataPtr
+}
+{ .mfi
+ ldfpd fA16, fA17 = [rTmpPtr], 16 // A16, A17
+ fma.s1 fLnSin28 = fLnSin28, fDelX4, fLnSin24
+ adds rPolDataPtr = 144 , rPolDataPtr
+}
+;;
+{ .mfi
+ ldfe fLnSin10 = [rLnSinDataPtr], 32
+ fma.s1 fRes1H = fA3, FR_FracX, f0 // (A3*y)hi
+ and GR_N = GR_N, r17Ones // mask sign bit
+}
+{ .mfi
+ ldfe fLnSin12 = [rLnSinTmpPtr]
+ fma.s1 fDelX6 = fDxSqr, fDelX4, f0 // DeltaX^6
+ shladd GR_ad_tbl_1 = rIndex1Dx, 4, rTbl1Addr // Point to G_1
+}
+;;
+{ .mfi
+ ldfe fA13 = [rPolDataPtr], -32 // A13
+ fma.s1 fA4 = fA5, FR_FracX, fA4 // A5*y + A4
+ // Get bits 30-15 of X_0 * Z_1
+ pmpyshr2.u GR_X_1 = rX0Dx, GR_Z_1, 15
+}
+{ .mfi
+ ldfe fA12 = [rTmpPtr2], -32 // A12
+ fms.s1 FR_r = FR_G, fSignifX, f1 // r = G * S_hi - 1
+ sub GR_N = GR_N, rExpHalf, 1 // unbisaed exponent of DeltaX
+}
+;;
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+.pred.rel "mutex",p10,p11
+{ .mfi
+ ldfe fA11 = [rPolDataPtr], -32 // A11
+ // High part of log(|x|) = Y_hi = N * log2_hi + H
+ fma.s1 fResH = fFloatN, FR_log2_hi, FR_H
+(p10) cmp.eq p8, p9 = rXRnd, r0
+}
+{ .mfi
+ ldfe fA10 = [rTmpPtr2], -32 // A10
+ fma.s1 fRes6H = fA1, FR_FracX, f0 // (A1*y)hi
+(p11) cmp.eq p9, p8 = rXRnd, r0
+}
+;;
+{ .mfi
+ ldfe fA9 = [rPolDataPtr], -32 // A9
+ fma.s1 fB14 = fLnSin6, fDxSqr, f0 // (LnSin6*deltaX^2)hi
+ cmp.eq p6, p7 = 4, rSgnGamSize
+}
+{ .mfi
+ ldfe fA8 = [rTmpPtr2], -32 // A8
+ fma.s1 fA18 = fA19, FR_FracX, fA18
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fA7 = [rPolDataPtr] // A7
+ fma.s1 fA23 = fA23, FR_FracX, fA22
+ nop.i 0
+}
+{ .mfi
+ ldfe fA6 = [rTmpPtr2] // A6
+ fma.s1 fA21 = fA21, FR_FracX, fA20
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fLnSin14 = [rLnSinDataPtr]
+ fms.s1 fRes1L = fA3, FR_FracX, fRes1H // delta((A3*y)hi)
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract bits 6-9 of X_1
+}
+{ .mfi
+ setf.sig fFloatNDx = GR_N
+ fadd.s1 fPol = fRes1H, fA2 // (A3*y + A2)hi
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfps FR_G, FR_H = [GR_ad_tbl_1], 8 // Load G_1, H_1
+ fma.s1 fRes2H = fA4, fXSqr, f0 // ((A5 + A4*y)*y^2)hi
+ nop.i 0
+}
+{ .mfi
+ shladd GR_ad_z_2 = GR_Index2, 2, rZ2Addr // Point to Z_2
+ fma.s1 fA25 = fA25, FR_FracX, fA24
+ shladd GR_ad_tbl_2 = GR_Index2, 4, rTbl2Addr // Point to G_2
+}
+;;
+.pred.rel "mutex",p8,p9
+{ .mfi
+ ld4 GR_Z_2 = [GR_ad_z_2] // Load Z_2
+ fms.s1 fRes6L = fA1, FR_FracX, fRes6H // delta((A1*y)hi)
+ // sign of GAMMA(x) is negative
+(p8) adds rSgnGam = -1, r0
+}
+{ .mfi
+ adds rTmpPtr = 8, GR_ad_tbl_2
+ fadd.s1 fRes3H = fRes6H, fA0 // (A1*y + A0)hi
+ // sign of GAMMA(x) is positive
+(p9) adds rSgnGam = 1, r0
+}
+;;
+{ .mfi
+ ldfps FR_G2, FR_H2 = [GR_ad_tbl_2] // Load G_2, H_2
+ // (LnSin6*deltaX^2 + LnSin4)hi
+ fadd.s1 fLnSinH = fB14, fLnSin4
+ nop.i 0
+}
+{ .mfi
+ ldfd FR_h2 = [rTmpPtr] // Load h_2
+ fms.s1 fB16 = fLnSin6, fDxSqr, fB14 // delta(LnSin6*deltaX^2)
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfd fhDelX = [GR_ad_tbl_1] // Load h_1
+ fma.s1 fA21 = fA21, fXSqr, fA18
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin36 = fLnSin36, fDelX4, fLnSin32
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1L = fA3L, FR_FracX, fRes1L // (A3*y)lo
+ // Get bits 30-15 of X_1 * Z_
+ pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 fPolL = fA2, fPol
+ nop.i 0
+}
+;;
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mfi
+ nop.m 0
+ // delta(((A5 + A4*y)*y^2)hi)
+ fms.s1 fRes2L = fA4, fXSqr, fRes2H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (((A5 + A4*y)*y^2) + A3*y + A2)hi
+ fadd.s1 fRes4H = fRes2H, fPol
+ nop.i 0
+}
+;;
+{ .mfi
+ // store signgam if size of variable is 4 bytes
+(p6) st4 [rSgnGamAddr] = rSgnGam
+ fma.s1 fRes6L = fA1L, FR_FracX, fRes6L // (A1*y)lo
+ nop.i 0
+}
+{ .mfi
+ // store signgam if size of variable is 8 bytes
+(p7) st8 [rSgnGamAddr] = rSgnGam
+ fsub.s1 fRes3L = fA0, fRes3H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fLnSinL = fLnSin4, fLnSinH
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // ((LnSin6*deltaX^2 + LnSin4)*deltaX^2)hi
+ fma.s1 fB18 = fLnSinH, fDxSqr, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ adds rTmpPtr = 8, rTbl3Addr
+ fma.s1 fB16 = fLnSin6, fDxSqrL, fB16 // (LnSin6*deltaX^2)lo
+ extr.u GR_Index3 = GR_X_2, 1, 5 // Extract bits 1-5 of X_2
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA25 = fA25, fXSqr, fA23
+ nop.i 0
+}
+;;
+{ .mfi
+ shladd GR_ad_tbl_3 = GR_Index3, 4, rTbl3Addr // Point to G_3
+ fadd.s1 fPolL = fPolL, fRes1H
+ nop.i 0
+}
+{ .mfi
+ shladd rTmpPtr = GR_Index3, 4, rTmpPtr // Point to G_3
+ fadd.s1 fRes1L = fRes1L, fA2L // (A3*y)lo + A2lo
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfps FR_G3, FR_H3 = [GR_ad_tbl_3] // Load G_3, H_3
+ fma.s1 fRes2L = fA4, fXSqrL, fRes2L // ((A5 + A4*y)*y^2)lo
+ nop.i 0
+}
+{ .mfi
+ ldfd FR_h3 = [rTmpPtr] // Load h_3
+ fsub.s1 fRes4L = fPol, fRes4H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // ((((A5 + A4*y)*y^2) + A3*y + A2)*y^2)hi
+ fma.s1 fRes7H = fRes4H, fXSqr, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, FR_FracX, fA14
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes3L = fRes3L, fRes6H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes6L = fRes6L, fA0L // (A1*y)lo + A0lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fLnSinL = fLnSinL, fB14
+
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // delta((LnSin6*deltaX^2 + LnSin4)*deltaX^2)
+ fms.s1 fB20 = fLnSinH, fDxSqr, fB18
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fPolL = fPolL, fRes1L // (A3*y + A2)lo
+
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // ((LnSin6*deltaX^2 + LnSin4)*deltaX^2 + LnSin2)hi
+ fadd.s1 fLnSin6 = fB18, fLnSin2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes4L = fRes4L, fRes2H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, FR_FracX, fA16
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // delta(((((A5 + A4*y)*y^2) + A3*y + A2)*y^2)
+ fms.s1 fRes7L = fRes4H, fXSqr, fRes7H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fPol = fRes7H, fRes3H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes3L = fRes3L, fRes6L // (A1*y + A0)lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA25 = fA25, fX4, fA21
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // (LnSin6*deltaX^2 + LnSin4)lo
+ fadd.s1 fLnSinL = fLnSinL, fB16
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB20 = fLnSinH, fDxSqrL, fB20
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fLnSin4 = fLnSin2, fLnSin6
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (((LnSin6*deltaX^2 + LnSin4)*deltaX^2 + LnSin2)*DeltaX^2)hi
+ fma.s1 fLnSinH = fLnSin6, fDxSqr, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // ((A5 + A4*y)*y^2)lo + (A3*y + A2)lo
+ fadd.s1 fRes2L = fRes2L, fPolL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, fXSqr, fA15
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // ((((A5 + A4*y)*y^2) + A3*y + A2)*y^2)lo
+ fma.s1 fRes7L = fRes4H, fXSqrL, fRes7L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 fPolL = fRes3H, fPol
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA13 = fA13, FR_FracX, fA12
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, FR_FracX, fA10
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // ((LnSin6*deltaX^2 + LnSin4)*deltaX^2)lo
+ fma.s1 fB20 = fLnSinL, fDxSqr, fB20
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_G = FR_G, FR_G2 // G = G_1 * G_2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fLnSin4 = fLnSin4, fB18
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fLnSinL = fLnSin6, fDxSqr, fLnSinH
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // (((A5 + A4*y)*y^2) + A3*y + A2)lo
+ fadd.s1 fRes4L = fRes4L, fRes2L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fhDelX = fhDelX, FR_h2 // h = h_1 + h_2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes7L = fRes7L, fRes3L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fPolL = fPolL, fRes7H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fcvt.xf fFloatNDx = fFloatNDx
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H2 // H = H_1 + H_2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_G = FR_G, FR_G3 // G = (G_1 * G_2) * G_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // ((LnSin6*deltaX^2 + LnSin4)*deltaX^2)lo + (LnSin2)lo
+ fadd.s1 fLnSin2L = fLnSin2L, fB20
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA25 = fA25, fX4, fA17
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA13 = fA13, fXSqr, fA11
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, FR_FracX, fA8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fA7, FR_FracX, fA6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin36 = fLnSin36, fDelX8, fLnSin28
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin14 = fLnSin14, fDxSqr, fLnSin12
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin10 = fLnSin10, fDxSqr, fLnSin8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H3 // H = (H_1 + H_2) + H_3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fRDx = FR_G, fNormDx, f1 // r = G * S_hi - 1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // poly_lo = r * Q4 + Q3
+ fma.s1 FR_poly_lo = FR_r, FR_Q4, FR_Q3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // ((((A5 + A4*y)*y^2) + A3*y + A2)*y^2)lo + (A1*y + A0)lo
+ fma.s1 fRes7L = fRes4L, fXSqr, fRes7L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA25 = fA25, fX4, fA13
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, fXSqr, fA7
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // h = N * log2_lo + h
+ fma.s1 FR_h = fFloatN, FR_log2_lo, FR_h
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fhDelX = fhDelX, FR_h3 // h = (h_1 + h_2) + h_3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin36 = fLnSin36, fDelX6, fLnSin20
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin14 = fLnSin14, fDelX4, fLnSin10
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_lo = r * Q4 + Q3
+ fma.s1 fPolyLoDx = fRDx, FR_Q4, FR_Q3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 fRDxSq = fRDx, fRDx // rsq = r * r
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // Y_hi = N * log2_hi + H
+ fma.s1 fResLnDxH = fFloatNDx, FR_log2_hi, FR_H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rcub = FR_rsq, FR_r, f0 // rcub = r^3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA25, fX4, fA9
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fPolL = fPolL, fRes7L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fLnSin4 = fLnSin4, fLnSin2L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // h = N * log2_lo + h
+ fma.s1 fhDelX = fFloatNDx, FR_log2_lo, fhDelX
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin36 = fLnSin36, fDelX8, fLnSin14
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // ((LnSin6*deltaX^2 + LnSin4)*deltaX^2 + LnSin2)lo
+ fma.s1 fLnSinL = fLnSin6, fDxSqrL, fLnSinL
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo * r + Q2
+ fma.s1 fPolyLoDx = fPolyLoDx, fRDx, FR_Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fRDxCub = fRDxSq, fRDx, f0 // rcub = r^3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ famax.s0 fRes5H = fPol, fResH
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // High part of (lgammal(|x|) + log(|x|))
+ fadd.s1 fRes1H = fPol, fResH
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo * r + Q2
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_r, FR_Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPolL = fA9, fX6, fPolL // P25lo
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ famin.s0 fRes5L = fPol, fResH
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // High part of -(LnSin + log(|DeltaX|))
+ fnma.s1 fRes2H = fResLnDxH, f1, fLnSinH
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // (((LnSin6*deltaX^2 + LnSin4)*deltaX^2 + LnSin2)*DeltaX^2)lo
+ fma.s1 fLnSinL = fLnSin4, fDxSqr, fLnSinL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin36 = fLnSin36, fDelX6, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_hi = Q1 * rsq + r
+ fma.s1 fPolyHiDx = FR_Q1, fRDxSq, fRDx
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo*r^3 + h
+ fma.s1 fPolyLoDx = fPolyLoDx, fRDxCub, fhDelX
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes1L = fRes5H, fRes1H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // -(lgammal(|x|) + log(|x|))hi
+ fnma.s1 fRes1H = fRes1H, f1, f0
+
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_hi = Q1 * rsq + r
+ fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo*r^3 + h
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fRes2L = fResLnDxH, fMOne, fRes2H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSinL = fLnSin36, fDxSqr, fLnSinL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // Y_lo = poly_hi + poly_lo
+ fadd.s1 fResLnDxL = fPolyHiDx, fPolyLoDx
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1L = fRes1L, fRes5L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // high part of the final result
+ fadd.s1 fYH = fRes2H, fRes1H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // Y_lo = poly_hi + poly_lo
+ fadd.s1 fResL = FR_poly_hi, FR_poly_lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ famax.s0 fRes4H = fRes2H, fRes1H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ famin.s0 fRes4L = fRes2H, fRes1H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // (LnSin)lo + (log(|DeltaX|))lo
+ fsub.s1 fLnSinL = fLnSinL, fResLnDxL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2L = fRes2L, fLnSinH
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ //(lgammal(|x|))lo + (log(|x|))lo
+ fadd.s1 fPolL = fResL, fPolL
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fYL = fRes4H, fYH
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // Low part of -(LnSin + log(|DeltaX|))
+ fadd.s1 fRes2L = fRes2L, fLnSinL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // High part of (lgammal(|x|) + log(|x|))
+ fadd.s1 fRes1L = fRes1L, fPolL
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fYL = fYL, fRes4L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes2L = fRes2L, fRes1L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // low part of the final result
+ fadd.s1 fYL = fYL, fRes2L
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ // final result for -6.0 < x <= -0.75, non-integer, "far" from roots
+ fma.s0 f8 = fYH, f1, fYL
+ // exit here for -6.0 < x <= -0.75, non-integer, "far" from roots
+ br.ret.sptk b0
+}
+;;
+
+// here if |x+1| < 2^(-7)
+.align 32
+_closeToNegOne:
+{ .mfi
+ getf.exp GR_N = fDx // Get N = exponent of x
+ fmerge.se fAbsX = f1, fDx // Form |deltaX|
+ // Get high 4 bits of significand of deltaX
+ extr.u rIndex1Dx = rSignifDx, 59, 4
+}
+{ .mfi
+ addl rPolDataPtr= @ltoff(lgammal_1pEps_data),gp
+ fma.s1 fA0L = fDxSqr, fDxSqr, f0 // deltaX^4
+ // sign of GAMMA is positive if p10 is set to 1
+(p10) adds rSgnGam = 1, r0
+}
+;;
+{ .mfi
+ shladd GR_ad_z_1 = rIndex1Dx, 2, GR_ad_z_1 // Point to Z_1
+ fnma.s1 fResL = fDx, f1, f0 // -(x+1)
+ // Get high 15 bits of significand
+ extr.u GR_X_0 = rSignifDx, 49, 15
+}
+{ .mfi
+ ld8 rPolDataPtr = [rPolDataPtr]
+ nop.f 0
+ shladd GR_ad_tbl_1 = rIndex1Dx, 4, rTbl1Addr // Point to G_1
+}
+;;
+{ .mfi
+ ld4 GR_Z_1 = [GR_ad_z_1] // Load Z_1
+ nop.f 0
+ and GR_N = GR_N, r17Ones // mask sign bit
+}
+{ .mfi
+ adds rTmpPtr = 8, GR_ad_tbl_1
+ nop.f 0
+ cmp.eq p6, p7 = 4, rSgnGamSize
+}
+;;
+{ .mfi
+ ldfps FR_G, FR_H = [GR_ad_tbl_1],8 // Load G_1, H_1
+ nop.f 0
+ adds rTmpPtr2 = 96, rPolDataPtr
+}
+{ .mfi
+ ldfd FR_h = [rTmpPtr] // Load h_1
+ nop.f 0
+ // unbiased exponent of deltaX
+ sub GR_N = GR_N, rExpHalf, 1
+}
+;;
+{ .mfi
+ adds rTmpPtr3 = 192, rPolDataPtr
+ nop.f 0
+ // sign of GAMMA is negative if p11 is set to 1
+(p11) adds rSgnGam = -1, r0
+}
+{ .mfi
+ ldfe fA1 = [rPolDataPtr], 16 // A1
+ nop.f 0
+ nop.i 0
+}
+;;
+{.mfi
+ ldfe fA2 = [rPolDataPtr], 16 // A2
+ nop.f 0
+ // Get bits 30-15 of X_0 * Z_1
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15
+}
+{ .mfi
+ ldfpd fA20, fA19 = [rTmpPtr2], 16 // P8, P7
+ nop.f 0
+ nop.i 0
+}
+;;
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mfi
+ ldfe fA3 = [rPolDataPtr], 16 // A3
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA18, fA17 = [rTmpPtr2], 16 // P6, P5
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fA4 = [rPolDataPtr], 16 // A4
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA16, fA15 = [rTmpPtr2], 16 // P4, p3
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA5L, fA6 = [rPolDataPtr], 16 // A5, A6
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA14, fA13 = [rTmpPtr2], 16 // P2, P1
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA7, fA8 = [rPolDataPtr], 16 // A7, A8
+ nop.f 0
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract bits 6-9 of X_1
+}
+{ .mfi
+ ldfe fLnSin2 = [rTmpPtr2], 16
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ shladd GR_ad_z_2 = GR_Index2, 2, rZ2Addr // Point to Z_2
+ nop.f 0
+ shladd GR_ad_tbl_2 = GR_Index2, 4, rTbl2Addr // Point to G_2
+}
+{ .mfi
+ ldfe fLnSin4 = [rTmpPtr2], 32
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ld4 GR_Z_2 = [GR_ad_z_2] // Load Z_2
+ nop.f 0
+ adds rTmpPtr = 8, GR_ad_tbl_2
+}
+{ .mfi
+ // Put integer N into rightmost significand
+ setf.sig fFloatN = GR_N
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fLnSin6 = [rTmpPtr3]
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe fLnSin8 = [rTmpPtr2]
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfps FR_G2, FR_H2 = [GR_ad_tbl_2],8 // Load G_2, H_2
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfd FR_h2 = [rTmpPtr] // Load h_2
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ // store signgam if size of variable is 4 bytes
+(p6) st4 [rSgnGamAddr] = rSgnGam
+ fma.s1 fResH = fA20, fResL, fA19 //polynomial for log(|x|)
+ // Get bits 30-15 of X_1 * Z_2
+ pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15
+}
+{ .mfi
+ // store signgam if size of variable is 8 bytes
+(p7) st8 [rSgnGamAddr] = rSgnGam
+ fma.s1 fA2 = fA2, fDx, fA1 // polynomial for lgammal(|x|)
+ nop.i 0
+}
+;;
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mfi
+ nop.m 0
+ fma.s1 fA18 = fA18, fResL, fA17 //polynomial for log(|x|)
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA16 = fA16, fResL, fA15 //polynomial for log(|x|)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA4, fDx, fA3 // polynomial for lgammal(|x|)
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA14 = fA14, fResL, fA13 //polynomial for log(|x|)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA6 = fA6, fDx, fA5L // polynomial for lgammal(|x|)
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fA8, fDx, fA7 // polynomial for lgammal(|x|)
+ extr.u GR_Index3 = GR_X_2, 1, 5 // Extract bits 1-5 of X_2
+}
+;;
+{ .mfi
+ shladd GR_ad_tbl_3 = GR_Index3, 4, rTbl3Addr // Point to G_3
+ // loqw part of lnsin polynomial
+ fma.s1 fRes3L = fLnSin4, fDxSqr, fLnSin2
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfps FR_G3, FR_H3 = [GR_ad_tbl_3], 8 // Load G_3, H_3
+ fcvt.xf fFloatN = fFloatN // N as FP number
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fResH = fResH, fDxSqr, fA18 // High part of log(|x|)
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfd FR_h3 = [GR_ad_tbl_3] // Load h_3
+ fma.s1 fA4 = fA4, fDxSqr, fA2 // Low part of lgammal(|x|)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // high part of lnsin polynomial
+ fma.s1 fRes3H = fLnSin8, fDxSqr, fLnSin6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_G = FR_G, FR_G2 // G = G_1 * G_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H2 // H = H_1 + H_2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_h = FR_h, FR_h2 // h = h_1 + h_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA16 = fA16, fDxSqr, fA14 // Low part of log(|x|)
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fPol, fDxSqr, fA6 // High part of lgammal(|x|)
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fResH = fResH, fA0L, fA16 // log(|x|)/deltaX^2 - deltaX
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_G = FR_G, FR_G3 // G = (G_1 * G_2) * G_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H3 // H = (H_1 + H_2) + H_3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_h = FR_h, FR_h3 // h = (h_1 + h_2) + h_3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fResH = fResH, fDxSqr, fResL // log(|x|)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fPol, fA0L, fA4 // lgammal(|x|)/|x|
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r = FR_G, fAbsX, f1 // r = G * S_hi - 1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // high part of log(deltaX)= Y_hi = N * log2_hi + H
+ fma.s1 fRes4H = fFloatN, FR_log2_hi, FR_H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // h = N * log2_lo + h
+ fma.s1 FR_h = fFloatN, FR_log2_lo, FR_h
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fResH = fPol, fDx, fResH // lgammal(|x|) + log(|x|)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // lnsin/deltaX^2
+ fma.s1 fRes3H = fRes3H, fA0L, fRes3L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_lo = r * Q4 + Q3
+ fma.s1 FR_poly_lo = FR_r, FR_Q4, FR_Q3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // lnSin - log(|x|) - lgammal(|x|)
+ fms.s1 fResH = fRes3H, fDxSqr, fResH
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo * r + Q2
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_r, FR_Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rcub = FR_rsq, FR_r, f0 // rcub = r^3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // poly_hi = Q1 * rsq + r
+ fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo*r^3 + h
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // low part of log(|deltaX|) = Y_lo = poly_hi + poly_lo
+ fadd.s1 fRes4L = FR_poly_hi, FR_poly_lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fResH = fResH, fRes4L
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ // final result for |x+1|< 2^(-7) path
+ fsub.s0 f8 = fResH, fRes4H
+ // exit for |x+1|< 2^(-7) path
+ br.ret.sptk b0
+}
+;;
+
+
+// here if -2^63 < x < -6.0 and x is not an integer
+// Also we are going to filter out cases when x falls in
+// range which is "close enough" to negative root. Rhis case
+// may occur only for -19.5 < x since other roots of lgamma are
+// insignificant from double extended point of view (they are closer
+// to RTN(x) than one ulp(x).
+.align 32
+_negStirling:
+{ .mfi
+ ldfe fLnSin6 = [rLnSinDataPtr], 32
+ fnma.s1 fInvX = f8, fRcpX, f1 // start of 3rd NR iteration
+ // Get high 4 bits of significand of deltaX
+ extr.u rIndex1Dx = rSignifDx, 59, 4
+}
+{ .mfi
+ ldfe fLnSin8 = [rTmpPtr3], 32
+ fadd.s1 FR_h = FR_h, FR_h2 // h = h_1 + h_2
+(p12) cmp.ltu.unc p6, p0 = rSignifX, rLeftBound
+}
+;;
+{ .mfi
+ ldfe fLnSin10 = [rLnSinDataPtr], 32
+ fmpy.s1 FR_G = FR_G, FR_G3 // G = (G_1 * G_2) * G_3
+ // Get high 15 bits of significand
+ extr.u GR_X_0 = rSignifDx, 49, 15
+}
+{ .mfi
+ shladd GR_ad_z_1 = rIndex1Dx, 2, GR_ad_z_1 // Point to Z_1
+ fadd.s1 FR_H = FR_H, FR_H3 // H = (H_1 + H_2) + H_3
+ // set p6 if x falls in "near root" range
+(p6) cmp.geu.unc p6, p0 = rSignifX, rRightBound
+}
+;;
+{ .mfi
+ getf.exp GR_N = fDx // Get N = exponent of x
+ fma.s1 fDx4 = fDxSqr, fDxSqr, f0 // deltaX^4
+ adds rTmpPtr = 96, rBernulliPtr
+}
+{ .mfb
+ ld4 GR_Z_1 = [GR_ad_z_1] // Load Z_1
+ fma.s1 fLnSin34 = fLnSin34, fDxSqr, fLnSin32
+ // branch to special path if x falls in "near root" range
+(p6) br.cond.spnt _negRoots
+}
+;;
+.pred.rel "mutex",p10,p11
+{ .mfi
+ ldfe fLnSin12 = [rTmpPtr3]
+ fma.s1 fLnSin26 = fLnSin26, fDxSqr, fLnSin24
+(p10) cmp.eq p8, p9 = rXRnd, r0
+}
+{ .mfi
+ ldfe fLnSin14 = [rLnSinDataPtr]
+ fma.s1 fLnSin30 = fLnSin30, fDxSqr, fLnSin28
+(p11) cmp.eq p9, p8 = rXRnd, r0
+}
+;;
+{ .mfi
+ ldfpd fB2, fB2L = [rBernulliPtr], 16
+ fma.s1 fLnSin18 = fLnSin18, fDxSqr, fLnSin16
+ shladd GR_ad_tbl_1 = rIndex1Dx, 4, rTbl1Addr // Point to G_1
+
+}
+{ .mfi
+ ldfe fB14 = [rTmpPtr], 16
+ fma.s1 fLnSin22 = fLnSin22, fDxSqr, fLnSin20
+ and GR_N = GR_N, r17Ones // mask sign bit
+}
+;;
+{ .mfi
+ ldfe fB4 = [rBernulliPtr], 16
+ fma.s1 fInvX = fInvX, fRcpX, fRcpX // end of 3rd NR iteration
+ // Get bits 30-15 of X_0 * Z_1
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15
+}
+{ .mfi
+ ldfe fB16 = [rTmpPtr], 16
+ fadd.s1 FR_h = FR_h, FR_h3 // h = (h_1 + h_2) + h_3
+ adds rTmpPtr2 = 8, GR_ad_tbl_1
+}
+;;
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mfi
+ ldfe fB6 = [rBernulliPtr], 16
+ fms.s1 FR_r = FR_G, fSignifX, f1 // r = G * S_hi - 1
+ adds rTmpPtr3 = -48, rTmpPtr
+}
+{ .mfi
+ ldfe fB18 = [rTmpPtr], 16
+ // High part of the log(|x|) = Y_hi = N * log2_hi + H
+ fma.s1 fResH = fFloatN, FR_log2_hi, FR_H
+ sub GR_N = GR_N, rExpHalf, 1 // unbiased exponent of deltaX
+}
+;;
+.pred.rel "mutex",p8,p9
+{ .mfi
+ ldfe fB8 = [rBernulliPtr], 16
+ fma.s1 fLnSin36 = fLnSin36, fDx4, fLnSin34
+ // sign of GAMMA(x) is negative
+(p8) adds rSgnGam = -1, r0
+}
+{ .mfi
+ ldfe fB20 = [rTmpPtr], -160
+ fma.s1 fRes5H = fLnSin4, fDxSqr, f0
+ // sign of GAMMA(x) is positive
+(p9) adds rSgnGam = 1, r0
+
+}
+;;
+{ .mfi
+ ldfe fB10 = [rBernulliPtr], 16
+ fma.s1 fLnSin30 = fLnSin30, fDx4, fLnSin26
+(p14) adds rTmpPtr = -160, rTmpPtr
+}
+{ .mfi
+ ldfe fB12 = [rTmpPtr3], 16
+ fma.s1 fDx8 = fDx4, fDx4, f0 // deltaX^8
+ cmp.eq p6, p7 = 4, rSgnGamSize
+}
+;;
+{ .mfi
+ ldfps fGDx, fHDx = [GR_ad_tbl_1], 8 // Load G_1, H_1
+ fma.s1 fDx6 = fDx4, fDxSqr, f0 // deltaX^6
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract bits 6-9 of X_1
+}
+{ .mfi
+ ldfd fhDx = [rTmpPtr2] // Load h_1
+ fma.s1 fLnSin22 = fLnSin22, fDx4, fLnSin18
+ nop.i 0
+}
+;;
+{ .mfi
+ // Load two parts of C
+ ldfpd fRes1H, fRes1L = [rTmpPtr], 16
+ fma.s1 fRcpX = fInvX, fInvX, f0 // (1/x)^2
+ shladd GR_ad_tbl_2 = GR_Index2, 4, rTbl2Addr // Point to G_2
+}
+{ .mfi
+ shladd GR_ad_z_2 = GR_Index2, 2, rZ2Addr // Point to Z_2
+ fma.s1 FR_h = fFloatN, FR_log2_lo, FR_h// h = N * log2_lo + h
+ nop.i 0
+}
+;;
+{ .mfi
+ ld4 GR_Z_2 = [GR_ad_z_2] // Load Z_2
+ fnma.s1 fInvXL = f8, fInvX, f1 // relative error of 1/x
+ nop.i 0
+}
+{ .mfi
+ adds rTmpPtr2 = 8, GR_ad_tbl_2
+ fma.s1 fLnSin8 = fLnSin8, fDxSqr, fLnSin6
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfps FR_G2, FR_H2 = [GR_ad_tbl_2],8 // Load G_2, H_2
+ // poly_lo = r * Q4 + Q3
+ fma.s1 FR_poly_lo = FR_r, FR_Q4, FR_Q3
+ nop.i 0
+}
+{ .mfi
+ ldfd fh2Dx = [rTmpPtr2] // Load h_2
+ fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA1L = fB2, fInvX, f0 // (B2*(1/x))hi
+ nop.i 0
+}
+{ .mfi
+ // Put integer N into rightmost significand
+ setf.sig fFloatNDx = GR_N
+ fms.s1 fRes4H = fResH, f1, f1 // ln(|x|)hi - 1
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2H = fRes5H, fLnSin2//(lnSin4*DeltaX^2 + lnSin2)hi
+ // Get bits 30-15 of X_1 * Z_2
+ pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fRes5L = fLnSin4, fDxSqr, fRes5H
+ nop.i 0
+}
+;;
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mfi
+ nop.m 0
+ fma.s1 fInvX4 = fRcpX, fRcpX, f0 // (1/x)^4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB6 = fB6, fRcpX, fB4
+ nop.i 0
+}
+;;
+{ .mfi
+ // store signgam if size of variable is 4 bytes
+(p6) st4 [rSgnGamAddr] = rSgnGam
+ fma.s1 fB18 = fB18, fRcpX, fB16
+ nop.i 0
+}
+{ .mfi
+ // store signgam if size of variable is 8 bytes
+(p7) st8 [rSgnGamAddr] = rSgnGam
+ fma.s1 fInvXL = fInvXL, fInvX, f0 // low part of 1/x
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo * r + Q2
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_r, FR_Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rcub = FR_rsq, FR_r, f0 // rcub = r^3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes3H = fRes4H, f8, f0 // (-|x|*(ln(|x|)-1))hi
+ extr.u GR_Index3 = GR_X_2, 1, 5 // Extract bits 1-5 of X_2
+}
+{ .mfi
+ nop.m 0
+ // poly_hi = Q1 * rsq + r
+ fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r
+ nop.i 0
+}
+;;
+{ .mfi
+ shladd GR_ad_tbl_3 = GR_Index3, 4, rTbl3Addr // Point to G_3
+ fms.s1 fA2L = fB2, fInvX, fA1L // delta(B2*(1/x))
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 fBrnH = fRes1H, f1, fA1L // (-C - S(1/x))hi
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfps fG3Dx, fH3Dx = [GR_ad_tbl_3],8 // Load G_3, H_3
+ fma.s1 fInvX8 = fInvX4, fInvX4, f0 // (1/x)^8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB10 = fB10, fRcpX, fB8
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfd fh3Dx = [GR_ad_tbl_3] // Load h_3
+ fma.s1 fB20 = fB20, fInvX4, fB18
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB14 = fB14, fRcpX, fB12
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin36 = fLnSin36, fDx8, fLnSin30
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin12 = fLnSin12, fDxSqr, fLnSin10
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes2L = fLnSin2, fRes2H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fRes2H, fDxSqr, f0 // high part of LnSin
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fnma.s1 fResH = fResH, FR_MHalf, fResH // -0.5*ln(|x|)hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 fGDx = fGDx, FR_G2 // G = G_1 * G_2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo*r^3 + h
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // B2lo*(1/x)hi+ delta(B2*(1/x))
+ fma.s1 fA2L = fB2L, fInvX, fA2L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fB20 = fB20, fInvX4, fB14
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB10 = fB10, fInvX4, fB6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fcvt.xf fFloatNDx = fFloatNDx
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin14 = fLnSin14, fDx4, fLnSin12
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin36 = fLnSin36, fDx8, fLnSin22
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fRes3L = fRes4H, f8, fRes3H // delta(-|x|*(ln(|x|)-1))
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fmpy.s1 fGDx = fGDx, fG3Dx // G = (G_1 * G_2) * G_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (-|x|*(ln(|x|)-1) - 0.5ln(|x|))hi
+ fadd.s1 fRes4H = fRes3H, fResH
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA2L = fInvXL, fB2, fA2L //(B2*(1/x))lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // low part of log(|x|) = Y_lo = poly_hi + poly_lo
+ fadd.s1 fResL = FR_poly_hi, FR_poly_lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fB20 = fB20, fInvX8, fB10
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fInvX3 = fInvX, fRcpX, f0 // (1/x)^3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fHDx = fHDx, FR_H2 // H = H_1 + H_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes5L = fRes5L, fLnSin2L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2L = fRes2L, fRes5H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fhDx = fhDx, fh2Dx // h = h_1 + h_2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fBrnL = fRes1H, fMOne, fBrnH
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r = fGDx, fNormDx, f1 // r = G * S_hi - 1
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes3L = fResL, f8 , fRes3L // (-|x|*(ln(|x|)-1))lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes4L = fRes3H, fRes4H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // low part of "Bernulli" polynomial
+ fma.s1 fB20 = fB20, fInvX3, fA2L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 fResL = fResL, FR_MHalf, fResL // -0.5*ln(|x|)lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fHDx = fHDx, fH3Dx // H = (H_1 + H_2) + H_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fPolL = fRes2H, fDxSqr, fPol
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fhDx = fhDx, fh3Dx // h = (h_1 + h_2) + h_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (-|x|*(ln(|x|)-1) - 0.5ln(|x|) - C - S(1/x))hi
+ fadd.s1 fB14 = fRes4H, fBrnH
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_lo = r * Q4 + Q3
+ fma.s1 FR_poly_lo = FR_r, FR_Q4, FR_Q3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes4L = fRes4L, fResH
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fBrnL = fBrnL, fA1L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // (-|x|*(ln(|x|)-1))lo + (-0.5ln(|x|))lo
+ fadd.s1 fRes3L = fRes3L, fResL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 fB20 = fRes1L, f1, fB20 // -Clo - S(1/x)lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2L = fRes2L, fRes5L // (lnSin4*DeltaX^2 + lnSin2)lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPolL = fDxSqrL, fRes2H, fPolL
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin14 = fLnSin14, fDx4, fLnSin8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin36 = fLnSin36, fDx8, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo * r + Q2
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_r, FR_Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rcub = FR_rsq, FR_r, f0 // rcub = r^3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_hi = Q1 * rsq + r
+ fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 fB12 = fRes4H, fB14
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // (-|x|*(ln(|x|)-1) - 0.5ln(|x|))lo
+ fadd.s1 fRes4L = fRes4L, fRes3L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fBrnL = fBrnL, fB20 // (-C - S(1/x))lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // high part of log(|DeltaX|) = Y_hi = N * log2_hi + H
+ fma.s1 fLnDeltaH = fFloatNDx, FR_log2_hi, fHDx
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // h = N * log2_lo + h
+ fma.s1 fhDx = fFloatNDx, FR_log2_lo, fhDx
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fPolL = fRes2L, fDxSqr, fPolL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin14 = fLnSin36, fDxSqr, fLnSin14
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // (-|x|*(ln(|x|)-1) - 0.5ln(|x|))lo + (- C - S(1/x))lo
+ fadd.s1 fBrnL = fBrnL, fRes4L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fB12 = fB12, fBrnH
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo*r^3 + h
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_rcub, fhDx
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 fRes1H = fLnDeltaH, f1, fPol//(-ln(|DeltaX|) + LnSin)hi
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fPolL = fDxSqrL, fRes2L, fPolL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin36 = fLnSin14, fDx6, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // (-|x|*(ln(|x|)-1) - 0.5ln(|x|) - C - S(1/x))lo
+ fadd.s1 fB12 = fB12, fBrnL
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // low part of log(|DeltaX|) = Y_lo = poly_hi + poly_lo
+ fadd.s1 fLnDeltaL= FR_poly_hi, FR_poly_lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fRes1L = fLnDeltaH, fMOne, fRes1H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fPolL = fPolL, fLnSin36
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ //(-|x|*(ln(|x|)-1)-0.5ln(|x|) - C - S(1/x))hi + (-ln(|DeltaX|) + LnSin)hi
+ fadd.s1 f8 = fRes1H, fB14
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ //max((-|x|*(ln(|x|)-1)-0.5ln(|x|) - C - S(1/x))hi,
+ // (-ln(|DeltaX|) + LnSin)hi)
+ famax.s1 fMaxNegStir = fRes1H, fB14
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ //min((-|x|*(ln(|x|)-1)-0.5ln(|x|) - C - S(1/x))hi,
+ // (-ln(|DeltaX|) + LnSin)hi)
+ famin.s1 fMinNegStir = fRes1H, fB14
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1L = fRes1L, fPol
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (-ln(|DeltaX|))lo + (LnSin)lo
+ fnma.s1 fPolL = fLnDeltaL, f1, fPolL
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 f9 = fMaxNegStir, f8 // delta1
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1L = fRes1L, fPolL // (-ln(|DeltaX|) + LnSin)lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 f9 = f9, fMinNegStir
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1L = fRes1L, fB12
+ nop.i 0
+}
+;;
+{ .mfi
+ // low part of the result
+ fadd.s1 f9 = f9, fRes1L
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ // final result for -2^63 < x < -6.0 path
+ fma.s0 f8 = f8, f1, f9
+ // exit here for -2^63 < x < -6.0 path
+ br.ret.sptk b0
+}
+;;
+
+// here if x falls in neighbourhood of any negative root
+// "neighbourhood" typically means that |lgammal(x)| < 0.17
+// on the [-3.0,-2.0] range |lgammal(x)| has even less
+// magnitude
+// rXint contains index of the root
+// p10 is set if root belongs to "right" ones
+// p11 is set if root belongs to "left" ones
+// lgammal(x) is approximated by polynomial of
+// 19th degree from (x - root) argument
+.align 32
+_negRoots:
+{ .mfi
+ addl rPolDataPtr= @ltoff(lgammal_right_roots_polynomial_data),gp
+ nop.f 0
+ shl rTmpPtr2 = rXint, 7 // (i*16)*8
+}
+{ .mfi
+ adds rRootsAddr = -288, rRootsBndAddr
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fRoot = [rRootsAddr] // FP representation of root
+ nop.f 0
+ shl rTmpPtr = rXint, 6 // (i*16)*4
+}
+{ .mfi
+(p11) adds rTmpPtr2 = 3536, rTmpPtr2
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ld8 rPolDataPtr = [rPolDataPtr]
+ nop.f 0
+ shladd rTmpPtr = rXint, 4, rTmpPtr // (i*16) + (i*16)*4
+}
+{ .mfi
+ adds rTmpPtr3 = 32, rTmpPtr2
+ nop.f 0
+ nop.i 0
+}
+;;
+.pred.rel "mutex",p10,p11
+{ .mfi
+ add rTmpPtr3 = rTmpPtr, rTmpPtr3
+ nop.f 0
+(p10) cmp.eq p8, p9 = rXRnd, r0
+}
+{ .mfi
+ // (i*16) + (i*16)*4 + (i*16)*8
+ add rTmpPtr = rTmpPtr, rTmpPtr2
+ nop.f 0
+(p11) cmp.eq p9, p8 = rXRnd, r0
+}
+;;
+{ .mfi
+ add rTmpPtr2 = rPolDataPtr, rTmpPtr3
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ add rPolDataPtr = rPolDataPtr, rTmpPtr // begin + offsett
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA0, fA0L = [rPolDataPtr], 16 // A0
+ nop.f 0
+ adds rTmpPtr = 112, rTmpPtr2
+}
+{ .mfi
+ ldfpd fA2, fA2L = [rTmpPtr2], 16 // A2
+ nop.f 0
+ cmp.eq p12, p13 = 4, rSgnGamSize
+}
+;;
+{ .mfi
+ ldfpd fA1, fA1L = [rPolDataPtr], 16 // A1
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe fA3 = [rTmpPtr2], 128 // A4
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA12, fA13 = [rTmpPtr], 16 // A12, A13
+ nop.f 0
+ adds rTmpPtr3 = 64, rPolDataPtr
+}
+{ .mfi
+ ldfpd fA16, fA17 = [rTmpPtr2], 16 // A16, A17
+ nop.f 0
+ adds rPolDataPtr = 32, rPolDataPtr
+}
+;;
+.pred.rel "mutex",p8,p9
+{ .mfi
+ ldfpd fA14, fA15 = [rTmpPtr], 16 // A14, A15
+ nop.f 0
+ // sign of GAMMA(x) is negative
+(p8) adds rSgnGam = -1, r0
+}
+{ .mfi
+ ldfpd fA18, fA19 = [rTmpPtr2], 16 // A18, A19
+ nop.f 0
+ // sign of GAMMA(x) is positive
+(p9) adds rSgnGam = 1, r0
+}
+;;
+{ .mfi
+ ldfe fA4 = [rPolDataPtr], 16 // A4
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA6, fA7 = [rTmpPtr3], 16 // A6, A7
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fA5 = [rPolDataPtr], 16 // A5
+ // if x equals to (rounded) root exactly
+ fcmp.eq.s1 p6, p0 = f8, fRoot
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA8, fA9 = [rTmpPtr3], 16 // A8, A9
+ fms.s1 FR_FracX = f8, f1, fRoot
+ nop.i 0
+}
+;;
+{ .mfi
+ // store signgam if size of variable is 4 bytes
+(p12) st4 [rSgnGamAddr] = rSgnGam
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+ // store signgam if size of variable is 8 bytes
+(p13) st8 [rSgnGamAddr] = rSgnGam
+ // answer if x equals to (rounded) root exactly
+(p6) fadd.s0 f8 = fA0, fA0L
+ // exit if x equals to (rounded) root exactly
+(p6) br.ret.spnt b0
+}
+;;
+{ .mmf
+ ldfpd fA10, fA11 = [rTmpPtr3], 16 // A10, A11
+ nop.m 0
+ nop.f 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fResH = fA2, FR_FracX, f0 // (A2*x)hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA4L = FR_FracX, FR_FracX, f0 // x^2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, FR_FracX, fA16
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 fA13 = fA13, FR_FracX, fA12
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA19 = fA19, FR_FracX, fA18
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, FR_FracX, fA14
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fPol = fA7, FR_FracX, fA6
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, FR_FracX, fA8
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fResL = fA2, FR_FracX, fResH // delta(A2*x)
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fadd.s1 fRes1H = fResH, fA1 // (A2*x + A1)hi
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, FR_FracX, fA10
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 fA5L = fA4L, fA4L, f0 // x^4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA19 = fA19, fA4L, fA17
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, fA4L, fA13
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fPol, FR_FracX, fA5
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 fA3L = fA4L, FR_FracX, f0 // x^3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // delta(A2*x) + A2L*x = (A2*x)lo
+ fma.s1 fResL = fA2L, FR_FracX, fResL
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fsub.s1 fRes1L = fA1, fRes1H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, fA4L, fA9
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fma.s1 fA19 = fA19, fA5L, fA15
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fPol = fPol, FR_FracX, fA4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fResL = fResL, fA1L // (A2*x)lo + A1
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fadd.s1 fRes1L = fRes1L, fResH
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes2H = fRes1H, FR_FracX, f0 // ((A2*x + A1)*x)hi
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fA19 = fA19, fA5L, fA11
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fPol = fPol, FR_FracX, fA3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1L = fRes1L, fResL // (A2*x + A1)lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // delta((A2*x + A1)*x)
+ fms.s1 fRes2L = fRes1H, FR_FracX, fRes2H
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fadd.s1 fRes3H = fRes2H, fA0 // ((A2*x + A1)*x + A0)hi
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA19 = fA19, fA5L, f0
+ nop.i 0
+}
+
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes2L = fRes1L, FR_FracX, fRes2L // ((A2*x + A1)*x)lo
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fsub.s1 fRes3L = fRes2H, fRes3H
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fPol = fA19, FR_FracX, fPol
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes3L = fRes3L, fA0
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ fadd.s1 fRes2L = fRes2L, fA0L // ((A2*x + A1)*x)lo + A0L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes3L = fRes3L, fRes2L // (((A2*x + A1)*x) + A0)lo
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fRes3L = fPol, fA3L, fRes3L
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ // final result for arguments which are close to negative roots
+ fma.s0 f8 = fRes3H, f1, fRes3L
+ // exit here for arguments which are close to negative roots
+ br.ret.sptk b0
+}
+;;
+
+// here if |x| < 0.5
+.align 32
+lgammal_0_half:
+{ .mfi
+ ld4 GR_Z_1 = [rZ1offsett] // Load Z_1
+ fma.s1 fA4L = f8, f8, f0 // x^2
+ addl rPolDataPtr = @ltoff(lgammal_0_Half_data), gp
+}
+{ .mfi
+ shladd GR_ad_tbl_1 = GR_Index1, 4, rTbl1Addr// Point to G_1
+ nop.f 0
+ addl rLnSinDataPtr = @ltoff(lgammal_lnsin_data), gp
+}
+;;
+{ .mfi
+ ldfps FR_G, FR_H = [GR_ad_tbl_1],8 // Load G_1, H_1
+ nop.f 0
+ // Point to Constants_Z_2
+ add GR_ad_z_2 = 0x140, GR_ad_z_1
+}
+{ .mfi
+ add GR_ad_q = -0x60, GR_ad_z_1 // Point to Constants_Q
+ nop.f 0
+ // Point to Constants_G_H_h2
+ add GR_ad_tbl_2 = 0x180, GR_ad_z_1
+}
+;;
+{ .mfi
+ ld8 rPolDataPtr = [rPolDataPtr]
+ nop.f 0
+ // Point to Constants_G_H_h3
+ add GR_ad_tbl_3 = 0x280, GR_ad_z_1
+}
+{ .mfi
+ ldfd FR_h = [GR_ad_tbl_1] // Load h_1
+ nop.f 0
+ sub GR_N = rExpX, rExpHalf, 1
+}
+;;
+{ .mfi
+ ld8 rLnSinDataPtr = [rLnSinDataPtr]
+ nop.f 0
+ // Get bits 30-15 of X_0 * Z_1
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15
+}
+{ .mfi
+ ldfe FR_log2_hi = [GR_ad_q],16 // Load log2_hi
+ nop.f 0
+ sub GR_N = r0, GR_N
+}
+;;
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mfi
+ ldfe FR_log2_lo = [GR_ad_q], 16 // Load log2_lo
+ nop.f 0
+ add rTmpPtr2 = 320, rPolDataPtr
+}
+{ .mfi
+ add rTmpPtr = 32, rPolDataPtr
+ nop.f 0
+ // exponent of 0.25
+ adds rExp2 = -1, rExpHalf
+}
+;;
+{ .mfi
+ ldfpd fA3, fA3L = [rPolDataPtr], 16 // A3
+ fma.s1 fA5L = fA4L, fA4L, f0 // x^4
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA1, fA1L = [rTmpPtr], 16 // A1
+ fms.s1 fB8 = f8, f8, fA4L // x^2 - <x^2>
+ // set p6 if -0.5 < x <= -0.25
+(p15) cmp.eq.unc p6, p0 = rExpX, rExp2
+}
+;;
+{ .mfi
+ ldfpd fA2, fA2L = [rPolDataPtr], 16 // A2
+ nop.f 0
+ // set p6 if -0.5 < x <= -0.40625
+(p6) cmp.le.unc p6, p0 = 10, GR_Index1
+}
+{ .mfi
+ ldfe fA21 = [rTmpPtr2], -16 // A21
+ // Put integer N into rightmost significand
+ nop.f 0
+ adds rTmpPtr = 240, rTmpPtr
+}
+;;
+{ .mfi
+ setf.sig fFloatN = GR_N
+ nop.f 0
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract bits 6-9 of X_1
+}
+{ .mfi
+ ldfe FR_Q4 = [GR_ad_q], 16 // Load Q4
+ nop.f 0
+ adds rPolDataPtr = 304, rPolDataPtr
+}
+;;
+{ .mfi
+ ldfe fA20 = [rTmpPtr2], -32 // A20
+ nop.f 0
+ shladd GR_ad_z_2 = GR_Index2, 2, GR_ad_z_2 // Point to Z_2
+}
+{ .mfi
+ ldfe fA19 = [rTmpPtr], -32 // A19
+ nop.f 0
+ shladd GR_ad_tbl_2 = GR_Index2, 4, GR_ad_tbl_2// Point to G_2
+}
+;;
+{ .mfi
+ ldfe fA17 = [rTmpPtr], -32 // A17
+ nop.f 0
+ adds rTmpPtr3 = 8, GR_ad_tbl_2
+}
+{ .mfb
+ ldfe fA18 = [rTmpPtr2], -32 // A18
+ nop.f 0
+ // branch to special path for -0.5 < x <= 0.40625
+(p6) br.cond.spnt lgammal_near_neg_half
+}
+;;
+{ .mmf
+ ld4 GR_Z_2 = [GR_ad_z_2] // Load Z_2
+ ldfe fA15 = [rTmpPtr], -32 // A15
+ fma.s1 fB20 = fA5L, fA5L, f0 // x^8
+}
+;;
+{ .mmf
+ ldfe fA16 = [rTmpPtr2], -32 // A16
+ ldfe fA13 = [rTmpPtr], -32 // A13
+ fms.s1 fB16 = fA4L, fA4L, fA5L
+}
+;;
+{ .mmf
+ ldfps FR_G2, FR_H2 = [GR_ad_tbl_2], 8 // Load G_2, H_2
+ ldfd FR_h2 = [rTmpPtr3] // Load h_2
+ fmerge.s fB10 = f8, fA5L // sign(x) * x^4
+}
+;;
+{ .mmi
+ ldfe fA14 = [rTmpPtr2], -32 // A14
+ ldfe fA11 = [rTmpPtr], -32 // A11
+ // Get bits 30-15 of X_1 * Z_2
+ pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15
+}
+;;
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mfi
+ ldfe fA12 = [rTmpPtr2], -32 // A12
+ fma.s1 fRes4H = fA3, fAbsX, f0
+ adds rTmpPtr3 = 16, GR_ad_q
+}
+{ .mfi
+ ldfe fA9 = [rTmpPtr], -32 // A9
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mmf
+ ldfe fA10 = [rTmpPtr2], -32 // A10
+ ldfe fA7 = [rTmpPtr], -32 // A7
+ fma.s1 fB18 = fB20, fB20, f0 // x^16
+}
+;;
+{ .mmf
+ ldfe fA8 = [rTmpPtr2], -32 // A8
+ ldfe fA22 = [rPolDataPtr], 16 // A22
+ fcvt.xf fFloatN = fFloatN
+}
+;;
+{ .mfi
+ ldfe fA5 = [rTmpPtr], -32 // A5
+ fma.s1 fA21 = fA21, fAbsX, fA20 // v16
+ extr.u GR_Index3 = GR_X_2, 1, 5 // Extract bits 1-5 of X_2
+}
+{ .mfi
+ ldfe fA6 = [rTmpPtr2], -32 // A6
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mmf
+ // Point to G_3
+ shladd GR_ad_tbl_3 = GR_Index3, 4, GR_ad_tbl_3
+ ldfe fA4 = [rTmpPtr2], -32 // A4
+ fma.s1 fA19 = fA19, fAbsX, fA18 // v13
+}
+;;
+.pred.rel "mutex",p14,p15
+{ .mfi
+ ldfps FR_G3, FR_H3 = [GR_ad_tbl_3],8 // Load G_3, H_3
+ fms.s1 fRes4L = fA3, fAbsX, fRes4H
+(p14) adds rSgnGam = 1, r0
+}
+{ .mfi
+ cmp.eq p6, p7 = 4, rSgnGamSize
+ fadd.s1 fRes2H = fRes4H, fA2
+(p15) adds rSgnGam = -1, r0
+}
+;;
+
+{ .mfi
+ ldfd FR_h3 = [GR_ad_tbl_3] // Load h_3
+ fma.s1 fA17 = fA17, fAbsX, fA16 // v12
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe FR_Q3 = [GR_ad_q], 32 // Load Q3
+ fmpy.s1 FR_G = FR_G, FR_G2 // G = G_1 * G_2
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_Q2 = [rTmpPtr3], 16 // Load Q2
+ fadd.s1 FR_H = FR_H, FR_H2 // H = H_1 + H_2
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe FR_Q1 = [GR_ad_q] // Load Q1
+ fma.s1 fA15 = fA15, fAbsX, fA14 // v8
+ nop.i 0
+}
+{ .mfi
+ adds rTmpPtr3 = 32, rLnSinDataPtr
+ fadd.s1 FR_h = FR_h, FR_h2 // h = h_1 + h_2
+ nop.i 0
+}
+;;
+{ .mmf
+ ldfpd fLnSin2, fLnSin2L = [rLnSinDataPtr], 16
+ ldfe fLnSin6 = [rTmpPtr3], 32
+ fma.s1 fA13 = fA13, fAbsX, fA12 // v7
+
+}
+;;
+{ .mfi
+ ldfe fLnSin4 = [rLnSinDataPtr], 32
+ fma.s1 fRes4L = fA3L, fAbsX, fRes4L
+ nop.i 0
+}
+{ .mfi
+ ldfe fLnSin10 = [rTmpPtr3], 32
+ fsub.s1 fRes2L = fA2, fRes2H
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fLnSin8 = [rLnSinDataPtr], 32
+ fma.s1 fResH = fRes2H, fAbsX, f0
+ nop.i 0
+}
+{ .mfi
+ ldfe fLnSin14 = [rTmpPtr3], 32
+ fma.s1 fA22 = fA22, fA4L, fA21 // v15
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fLnSin12 = [rLnSinDataPtr], 32
+ fma.s1 fA9 = fA9, fAbsX, fA8 // v4
+ nop.i 0
+}
+{ .mfi
+ ldfd fLnSin18 = [rTmpPtr3], 16
+ fma.s1 fA11 = fA11, fAbsX, fA10 // v5
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fLnSin16 = [rLnSinDataPtr], 24
+ fma.s1 fA19 = fA19, fA4L, fA17 // v11
+ nop.i 0
+}
+{ .mfi
+ ldfd fLnSin22 = [rTmpPtr3], 16
+ fma.s1 fPolL = fA7, fAbsX, fA6
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfd fLnSin20 = [rLnSinDataPtr], 16
+ fmpy.s1 FR_G = FR_G, FR_G3 // G = (G_1 * G_2) * G_3
+ nop.i 0
+}
+{ .mfi
+ ldfd fLnSin26 = [rTmpPtr3], 16
+ fadd.s1 FR_H = FR_H, FR_H3 // H = (H_1 + H_2) + H_3
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfd fLnSin24 = [rLnSinDataPtr], 16
+ fadd.s1 fRes2L = fRes2L, fRes4H
+ nop.i 0
+}
+{ .mfi
+ ldfd fLnSin30 = [rTmpPtr3], 16
+ fadd.s1 fA2L = fA2L, fRes4L
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfd fLnSin28 = [rLnSinDataPtr], 16
+ fms.s1 fResL = fRes2H, fAbsX, fResH
+ nop.i 0
+}
+{ .mfi
+ ldfd fLnSin34 = [rTmpPtr3], 8
+ fadd.s1 fRes2H = fResH, fA1
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfd fLnSin32 = [rLnSinDataPtr]
+ fma.s1 fA11 = fA11, fA4L, fA9 // v3
+ nop.i 0
+}
+{ .mfi
+ ldfd fLnSin36 = [rTmpPtr3]
+ fma.s1 fA15 = fA15, fA4L, fA13 // v6
+ nop.i 0
+}
+;;
+
+{ .mfi
+ // store signgam if size of variable is 4 bytes
+(p6) st4 [rSgnGamAddr] = rSgnGam
+ fadd.s1 FR_h = FR_h, FR_h3 // h = (h_1 + h_2) + h_3
+ nop.i 0
+}
+{ .mfi
+ // store signgam if size of variable is 8 bytes
+(p7) st8 [rSgnGamAddr] = rSgnGam
+ fma.s1 fA5 = fA5, fAbsX, fA4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r = FR_G, fSignifX, f1 // r = G * S_hi - 1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // High part of the log(|x|): Y_hi = N * log2_hi + H
+ fms.s1 FR_log2_hi = fFloatN, FR_log2_hi, FR_H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fA3L = fRes2L, fA2L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA22 = fA22, fA5L, fA19
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes2L = fA1, fRes2H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fRes3H = fRes2H, f8, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, fA5L, fA11 // v2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin18 = fLnSin18, fA4L, fLnSin16
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // h = N * log2_lo + h
+ fms.s1 FR_h = fFloatN, FR_log2_lo, FR_h
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPolL = fPolL, fA4L, fA5
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_lo = r * Q4 + Q3
+ fma.s1 FR_poly_lo = FR_r, FR_Q4, FR_Q3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fResL = fA3L, fAbsX, fResL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin30 = fLnSin30, fA4L, fLnSin28
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2L = fRes2L, fResH
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fRes3L = fRes2H, f8, fRes3H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1H = fRes3H, FR_log2_hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fB20, fA22, fA15
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin34 = fLnSin34, fA4L, fLnSin32
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin14 = fLnSin14, fA4L, fLnSin12
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo * r + Q2
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_r, FR_Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_rcub = FR_rsq, FR_r, f0 // rcub = r^3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_hi = Q1 * rsq + r
+ fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fA1L = fA1L, fResL
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin22 = fLnSin22, fA4L, fLnSin20
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin26 = fLnSin26, fA4L, fLnSin24
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes1L = FR_log2_hi, fRes1H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fPol, fA5L, fPolL
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin34 = fLnSin36, fA5L, fLnSin34
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin18 = fLnSin18, fA5L, fLnSin14
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin6 = fLnSin6, fA4L, fLnSin4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin10 = fLnSin10, fA4L, fLnSin8
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_hi = Q1 * rsq + r
+ fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2L = fRes2L, fA1L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo*r^3 + h
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB2 = fLnSin2, fA4L, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1L = fRes1L, fRes3H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fPol, fB10, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin26 = fLnSin26, fA5L, fLnSin22
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin34 = fLnSin34, fA5L, fLnSin30
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin10 = fLnSin10, fA5L, fLnSin6
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin2L = fLnSin2L, fA4L, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes3L = fRes2L, f8, fRes3L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // Y_lo = poly_hi + poly_lo
+ fsub.s1 FR_log2_lo = FR_poly_lo, FR_poly_hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fB4 = fLnSin2, fA4L, fB2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2H = fRes1H, fPol
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin34 = fLnSin34, fB20, fLnSin26
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin18 = fLnSin18, fB20, fLnSin10
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fLnSin2L = fB8, fLnSin2, fLnSin2L
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_log2_lo = FR_log2_lo, fRes3L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes2L = fRes1H, fRes2H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fB6 = fLnSin34, fB18, fLnSin18
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fB4 = fLnSin2L, fB4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1L = fRes1L, FR_log2_lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2L = fRes2L, fPol
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fB12 = fB6, fA5L, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2L = fRes2L, fRes1L
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fB14 = fB6, fA5L, fB12
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fadd.s1 fLnSin30 = fB2, fB12
+ // branch out if x is negative
+(p15) br.cond.spnt _O_Half_neg
+}
+;;
+{ .mfb
+ nop.m 0
+ // sign(x)*Pol(|x|) - log(|x|)
+ fma.s0 f8 = fRes2H, f1, fRes2L
+ // it's an answer already for positive x
+ // exit if 0 < x < 0.5
+ br.ret.sptk b0
+}
+;;
+
+// here if x is negative and |x| < 0.5
+.align 32
+_O_Half_neg:
+{ .mfi
+ nop.m 0
+ fma.s1 fB14 = fB16, fB6, fB14
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 fLnSin16 = fB2, fLnSin30
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fResH = fLnSin30, fRes2H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fLnSin16 = fLnSin16, fB12
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fB4 = fB14, fB4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fLnSin16 = fB4, fLnSin16
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 fResL = fRes2H, fResH
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fResL = fResL, fLnSin30
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fLnSin16 = fLnSin16, fRes2L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fResL = fResL, fLnSin16
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ // final result for -0.5 < x < 0
+ fma.s0 f8 = fResH, f1, fResL
+ // exit for -0.5 < x < 0
+ br.ret.sptk b0
+}
+;;
+
+// here if x >= 8.0
+// there are two computational paths:
+// 1) For x >10.0 Stirling's formula is used
+// 2) Polynomial approximation for 8.0 <= x <= 10.0
+.align 32
+lgammal_big_positive:
+{ .mfi
+ addl rPolDataPtr = @ltoff(lgammal_data), gp
+ fmerge.se fSignifX = f1, f8
+ // Get high 15 bits of significand
+ extr.u GR_X_0 = rSignifX, 49, 15
+}
+{.mfi
+ shladd rZ1offsett = GR_Index1, 2, GR_ad_z_1 // Point to Z_1
+ fnma.s1 fInvX = f8, fRcpX, f1 // start of 1st NR iteration
+ adds rSignif1andQ = 0x5, r0
+}
+;;
+{.mfi
+ ld4 GR_Z_1 = [rZ1offsett] // Load Z_1
+ nop.f 0
+ shl rSignif1andQ = rSignif1andQ, 61 // significand of 1.25
+}
+{ .mfi
+ cmp.eq p8, p0 = rExpX, rExp8 // p8 = 1 if 8.0 <= x < 16
+ nop.f 0
+ adds rSgnGam = 1, r0 // gamma is positive at this range
+}
+;;
+{ .mfi
+ shladd GR_ad_tbl_1 = GR_Index1, 4, rTbl1Addr// Point to G_1
+ nop.f 0
+ add GR_ad_q = -0x60, GR_ad_z_1 // Point to Constants_Q
+}
+{ .mlx
+ ld8 rPolDataPtr = [rPolDataPtr]
+ movl rDelta = 0x3FF2000000000000
+}
+;;
+{ .mfi
+ ldfps FR_G, FR_H = [GR_ad_tbl_1],8 // Load G_1, H_1
+ nop.f 0
+ add GR_ad_z_2 = 0x140, GR_ad_z_1 // Point to Constants_Z_2
+}
+{ .mfi
+ // Point to Constants_G_H_h2
+ add GR_ad_tbl_2 = 0x180, GR_ad_z_1
+ nop.f 0
+ // p8 = 1 if 8.0 <= x <= 10.0
+(p8) cmp.leu.unc p8, p0 = rSignifX, rSignif1andQ
+}
+;;
+{ .mfi
+ ldfd FR_h = [GR_ad_tbl_1] // Load h_1
+ nop.f 0
+ // Get bits 30-15 of X_0 * Z_1
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15
+}
+{ .mfb
+(p8) setf.d FR_MHalf = rDelta
+ nop.f 0
+(p8) br.cond.spnt lgammal_8_10 // branch out if 8.0 <= x <= 10.0
+}
+;;
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mfi
+ ldfe fA1 = [rPolDataPtr], 16 // Load overflow threshold
+ fma.s1 fRcpX = fInvX, fRcpX, fRcpX // end of 1st NR iteration
+ // Point to Constants_G_H_h3
+ add GR_ad_tbl_3 = 0x280, GR_ad_z_1
+}
+{ .mlx
+ nop.m 0
+ movl rDelta = 0xBFE0000000000000 // -0.5 in DP
+}
+;;
+{ .mfi
+ ldfe FR_log2_hi = [GR_ad_q],16 // Load log2_hi
+ nop.f 0
+ sub GR_N = rExpX, rExpHalf, 1 // unbiased exponent of x
+}
+;;
+{ .mfi
+ ldfe FR_log2_lo = [GR_ad_q],16 // Load log2_lo
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ setf.d FR_MHalf = rDelta
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ // Put integer N into rightmost significand
+ setf.sig fFloatN = GR_N
+ nop.f 0
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract bits 6-9 of X_1
+}
+{ .mfi
+ ldfe FR_Q4 = [GR_ad_q], 16 // Load Q4
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ shladd GR_ad_z_2 = GR_Index2, 2, GR_ad_z_2 // Point to Z_2
+ nop.f 0
+ shladd GR_ad_tbl_2 = GR_Index2, 4, GR_ad_tbl_2// Point to G_2
+}
+{ .mfi
+ ldfe FR_Q3 = [GR_ad_q], 16 // Load Q3
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ld4 GR_Z_2 = [GR_ad_z_2] // Load Z_2
+ fnma.s1 fInvX = f8, fRcpX, f1 // start of 2nd NR iteration
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfps FR_G2, FR_H2 = [GR_ad_tbl_2], 8 // Load G_2, H_2
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfd FR_h2 = [GR_ad_tbl_2] // Load h_2
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe FR_Q2 = [GR_ad_q],16 // Load Q2
+ nop.f 0
+ // Get bits 30-15 of X_1 * Z_2
+ pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15
+}
+;;
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mfi
+ ldfe FR_Q1 = [GR_ad_q] // Load Q1
+ fcmp.gt.s1 p7,p0 = f8, fA1 // check if x > overflow threshold
+ nop.i 0
+}
+;;
+{.mfi
+ ldfpd fA0, fA0L = [rPolDataPtr], 16 // Load two parts of C
+ fma.s1 fRcpX = fInvX, fRcpX, fRcpX // end of 2nd NR iteration
+ nop.i 0
+}
+;;
+{ .mfb
+ ldfpd fB2, fA1 = [rPolDataPtr], 16
+ nop.f 0
+(p7) br.cond.spnt lgammal_overflow // branch if x > overflow threshold
+}
+;;
+{.mfi
+ ldfe fB4 = [rPolDataPtr], 16
+ fcvt.xf fFloatN = fFloatN
+ extr.u GR_Index3 = GR_X_2, 1, 5 // Extract bits 1-5 of X_2
+}
+;;
+{ .mfi
+ shladd GR_ad_tbl_3 = GR_Index3, 4, GR_ad_tbl_3// Point to G_3
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe fB6 = [rPolDataPtr], 16
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfps FR_G3, FR_H3 = [GR_ad_tbl_3], 8 // Load G_3, H_3
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfd FR_h3 = [GR_ad_tbl_3] // Load h_3
+ fmpy.s1 FR_G = FR_G, FR_G2 // G = G_1 * G_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H2 // H = H_1 + H_2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe fB8 = [rPolDataPtr], 16
+ fadd.s1 FR_h = FR_h, FR_h2 // h = h_1 + h_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 fInvX = f8, fRcpX, f1 // start of 3rd NR iteration
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fB10 = [rPolDataPtr], 16
+ nop.f 0
+ cmp.eq p6, p7 = 4, rSgnGamSize
+}
+;;
+{ .mfi
+ ldfe fB12 = [rPolDataPtr], 16
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fB14 = [rPolDataPtr], 16
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe fB16 = [rPolDataPtr], 16
+ // get double extended coefficients from two doubles
+ // two doubles are needed in Stitling's formula for negative x
+ fadd.s1 fB2 = fB2, fA1
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fB18 = [rPolDataPtr], 16
+ fma.s1 fInvX = fInvX, fRcpX, fRcpX // end of 3rd NR iteration
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fB20 = [rPolDataPtr], 16
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ // store signgam if size of variable is 4 bytes
+(p6) st4 [rSgnGamAddr] = rSgnGam
+ fmpy.s1 FR_G = FR_G, FR_G3 // G = (G_1 * G_2) * G_3
+ nop.i 0
+}
+{ .mfi
+ // store signgam if size of variable is 8 bytes
+(p7) st8 [rSgnGamAddr] = rSgnGam
+ fadd.s1 FR_H = FR_H, FR_H3 // H = (H_1 + H_2) + H_3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_h = FR_h, FR_h3 // h = (h_1 + h_2) + h_3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRcpX = fInvX, fInvX, f0 // 1/x^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA0L = fB2, fInvX, fA0L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r = fSignifX, FR_G, f1 // r = G * S_hi - 1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // High part of the log(x): Y_hi = N * log2_hi + H
+ fma.s1 fRes2H = fFloatN, FR_log2_hi, FR_H
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // h = N * log2_lo + h
+ fma.s1 FR_h = fFloatN, FR_log2_lo, FR_h
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // High part of the log(x): Y_hi = N * log2_hi + H
+ fma.s1 fRes1H = fFloatN, FR_log2_hi, FR_H
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fPol = fB18, fRcpX, fB16 // v9
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA2L = fRcpX, fRcpX, f0 // v10
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fA3 = fB6, fRcpX, fB4 // v3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fB10, fRcpX, fB8 // v4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fRes2H =fRes2H, f1, f1 // log_Hi(x) -1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // poly_lo = r * Q4 + Q3
+ fma.s1 FR_poly_lo = FR_r, FR_Q4, FR_Q3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1H = fRes1H, FR_MHalf, f0 // -0.5*log_Hi(x)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fB14, fRcpX, fB12 // v7
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA8 = fA2L, fB20, fPol // v8
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA2 = fA4, fA2L, fA3 // v2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA4L = fA2L, fA2L, f0 // v5
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fResH = fRes2H, f8, f0 // (x*(ln(x)-1))hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo * r + Q2
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_r, FR_Q2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rcub = FR_rsq, FR_r, f0 // rcub = r^3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // poly_hi = Q1 * rsq + r
+ fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fRcpX, fInvX, f0 // 1/x^3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA6 = fA8, fA2L, fA7 // v6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fResL = fRes2H, f8, fResH // d(x*(ln(x)-1))
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes3H = fResH, fRes1H // (x*(ln(x)-1) -0.5ln(x))hi
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // poly_lo = poly_lo*r^3 + h
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fA4L, fA6, fA2 // v1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // raise inexact exception
+ fma.s0 FR_log2_lo = FR_log2_lo, FR_log2_lo, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes4H = fRes3H, fA0 // (x*(ln(x)-1) -0.5ln(x))hi + Chi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes3L = fResH, fRes3H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // Y_lo = poly_hi + poly_lo
+ fadd.s1 fRes2L = FR_poly_hi, FR_poly_lo
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA0L = fPol, fA11, fA0L // S(1/x) + Clo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes3L = fRes3L, fRes1H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes4L = fRes3H, fRes4H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fResL = fRes2L, f8 , fResL // lo part of x*(ln(x)-1)
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // Clo + S(1/x) - 0.5*logLo(x)
+ fma.s1 fA0L = fRes2L, FR_MHalf, fA0L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes4L = fRes4L, fA0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // Clo + S(1/x) - 0.5*logLo(x) + (x*(ln(x)-1))lo
+ fadd.s1 fA0L = fA0L, fResL
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes4L = fRes4L, fRes3L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes4L = fRes4L, fA0L
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ fma.s0 f8 = fRes4H, f1, fRes4L
+ // exit for x > 10.0
+ br.ret.sptk b0
+}
+;;
+// here if 8.0 <= x <= 10.0
+// Result = P15(y), where y = x/8.0 - 1.5
+.align 32
+lgammal_8_10:
+{ .mfi
+ addl rPolDataPtr = @ltoff(lgammal_8_10_data), gp
+ fms.s1 FR_FracX = fSignifX, f1, FR_MHalf // y = x/8.0 - 1.5
+ cmp.eq p6, p7 = 4, rSgnGamSize
+}
+;;
+{ .mfi
+ ld8 rLnSinDataPtr = [rPolDataPtr]
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ld8 rPolDataPtr = [rPolDataPtr]
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ adds rZ1offsett = 32, rLnSinDataPtr
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ adds rLnSinDataPtr = 48, rLnSinDataPtr
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA1, fA1L = [rPolDataPtr], 16 // A1
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe fA2 = [rZ1offsett], 32 // A5
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA0, fA0L = [rPolDataPtr], 16 // A0
+ fma.s1 FR_rsq = FR_FracX, FR_FracX, f0 // y^2
+ nop.i 0
+}
+{ .mfi
+ ldfe fA3 = [rLnSinDataPtr],32 // A5
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mmf
+ ldfe fA4 = [rZ1offsett], 32 // A4
+ ldfe fA5 = [rLnSinDataPtr], 32 // A5
+ nop.f 0
+}
+;;
+{ .mmf
+ ldfe fA6 = [rZ1offsett], 32 // A6
+ ldfe fA7 = [rLnSinDataPtr], 32 // A7
+ nop.f 0
+}
+;;
+{ .mmf
+ ldfe fA8 = [rZ1offsett], 32 // A8
+ ldfe fA9 = [rLnSinDataPtr], 32 // A9
+ nop.f 0
+}
+;;
+{ .mmf
+ ldfe fA10 = [rZ1offsett], 32 // A10
+ ldfe fA11 = [rLnSinDataPtr], 32 // A11
+ nop.f 0
+}
+;;
+{ .mmf
+ ldfe fA12 = [rZ1offsett], 32 // A12
+ ldfe fA13 = [rLnSinDataPtr], 32 // A13
+ fma.s1 FR_Q4 = FR_rsq, FR_rsq, f0 // y^4
+}
+;;
+{ .mmf
+ ldfe fA14 = [rZ1offsett], 32 // A14
+ ldfe fA15 = [rLnSinDataPtr], 32 // A15
+ nop.f 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1H = FR_FracX, fA1, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA3 = fA3, FR_FracX, fA2 // v4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA5 = fA5, FR_FracX, fA4 // v5
+ nop.i 0
+}
+;;
+{ .mfi
+ // store sign of GAMMA(x) if size of variable is 4 bytes
+(p6) st4 [rSgnGamAddr] = rSgnGam
+ fma.s1 fA3L = FR_Q4, FR_Q4, f0 // v9 = y^8
+ nop.i 0
+}
+{ .mfi
+ // store sign of GAMMA(x) if size of variable is 8 bytes
+(p7) st8 [rSgnGamAddr] = rSgnGam
+ fma.s1 fA7 = fA7, FR_FracX, fA6 // v7
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, FR_FracX, fA8 // v8
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fRes1L = FR_FracX, fA1, fRes1H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, FR_FracX, fA10 // v12
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA13 = fA13, FR_FracX, fA12 // v13
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fRes2H = fRes1H, f1, fA0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, FR_FracX, fA14 // v16
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA5 = fA5, FR_rsq, fA3 // v3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, FR_rsq, fA7 // v6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1L = FR_FracX, fA1L, fRes1L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fRes2L = fA0, f1, fRes2H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA13 = fA13, FR_rsq, fA11 // v11
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, FR_Q4, fA5 // v2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1L = fRes1L, f1, fA0L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes2L = fRes2L, f1, fRes1H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, FR_Q4, fA13 // v10
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes2L = fRes1L, f1, fRes2L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fA3L, fA15, fA9
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 f8 = FR_rsq , fPol, fRes2H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fPol, FR_rsq, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fRes1L = fRes2H, f1, f8
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1L = fRes1L, f1, fPol
+ nop.i 0
+}
+;;
+{.mfi
+ nop.m 0
+ fma.s1 fRes1L = fRes1L, f1, fRes2L
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ fma.s0 f8 = f8, f1, fRes1L
+ // exit for 8.0 <= x <= 10.0
+ br.ret.sptk b0
+}
+;;
+
+// here if 4.0 <=x < 8.0
+.align 32
+lgammal_4_8:
+{ .mfi
+ addl rPolDataPtr= @ltoff(lgammal_4_8_data),gp
+ fms.s1 FR_FracX = fSignifX, f1, FR_MHalf
+ adds rSgnGam = 1, r0
+}
+;;
+{ .mfi
+ ld8 rPolDataPtr = [rPolDataPtr]
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfb
+ adds rTmpPtr = 160, rPolDataPtr
+ nop.f 0
+ // branch to special path which computes polynomial of 25th degree
+ br.sptk lgamma_polynom25
+}
+;;
+
+// here if 2.25 <=x < 4.0
+.align 32
+lgammal_2Q_4:
+{ .mfi
+ addl rPolDataPtr= @ltoff(lgammal_2Q_4_data),gp
+ fms.s1 FR_FracX = fSignifX, f1, FR_MHalf
+ adds rSgnGam = 1, r0
+}
+;;
+{ .mfi
+ ld8 rPolDataPtr = [rPolDataPtr]
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfb
+ adds rTmpPtr = 160, rPolDataPtr
+ nop.f 0
+ // branch to special path which computes polynomial of 25th degree
+ br.sptk lgamma_polynom25
+}
+;;
+
+// here if 0.5 <= |x| < 0.75
+.align 32
+lgammal_half_3Q:
+.pred.rel "mutex", p14, p15
+{ .mfi
+(p14) addl rPolDataPtr= @ltoff(lgammal_half_3Q_data),gp
+ // FR_FracX = x - 0.625 for positive x
+(p14) fms.s1 FR_FracX = f8, f1, FR_FracX
+(p14) adds rSgnGam = 1, r0
+}
+{ .mfi
+(p15) addl rPolDataPtr= @ltoff(lgammal_half_3Q_neg_data),gp
+ // FR_FracX = x + 0.625 for negative x
+(p15) fma.s1 FR_FracX = f8, f1, FR_FracX
+(p15) adds rSgnGam = -1, r0
+}
+;;
+{ .mfi
+ ld8 rPolDataPtr = [rPolDataPtr]
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfb
+ adds rTmpPtr = 160, rPolDataPtr
+ nop.f 0
+ // branch to special path which computes polynomial of 25th degree
+ br.sptk lgamma_polynom25
+}
+;;
+// here if 1.3125 <= x < 1.5625
+.align 32
+lgammal_loc_min:
+{ .mfi
+ adds rSgnGam = 1, r0
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+ adds rTmpPtr = 160, rPolDataPtr
+ fms.s1 FR_FracX = f8, f1, fA5L
+ br.sptk lgamma_polynom25
+}
+;;
+// here if -2.605859375 <= x < -2.5
+// special polynomial approximation used since neither "near root"
+// approximation nor reflection formula give satisfactory accuracy on
+// this range
+.align 32
+_neg2andHalf:
+{ .mfi
+ addl rPolDataPtr= @ltoff(lgammal_neg2andHalf_data),gp
+ fma.s1 FR_FracX = fB20, f1, f8 // 2.5 + x
+ adds rSgnGam = -1, r0
+}
+;;
+{.mfi
+ ld8 rPolDataPtr = [rPolDataPtr]
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfb
+ adds rTmpPtr = 160, rPolDataPtr
+ nop.f 0
+ // branch to special path which computes polynomial of 25th degree
+ br.sptk lgamma_polynom25
+}
+;;
+
+// here if -0.5 < x <= -0.40625
+.align 32
+lgammal_near_neg_half:
+{ .mmf
+ addl rPolDataPtr= @ltoff(lgammal_near_neg_half_data),gp
+ setf.exp FR_FracX = rExpHalf
+ nop.f 0
+}
+;;
+{ .mfi
+ ld8 rPolDataPtr = [rPolDataPtr]
+ nop.f 0
+ adds rSgnGam = -1, r0
+}
+;;
+{ .mfb
+ adds rTmpPtr = 160, rPolDataPtr
+ fma.s1 FR_FracX = FR_FracX, f1, f8
+ // branch to special path which computes polynomial of 25th degree
+ br.sptk lgamma_polynom25
+}
+;;
+
+// here if there an answer is P25(x)
+// rPolDataPtr, rTmpPtr point to coefficients
+// x is in FR_FracX register
+.align 32
+lgamma_polynom25:
+{ .mfi
+ ldfpd fA3, fA0L = [rPolDataPtr], 16 // A3
+ nop.f 0
+ cmp.eq p6, p7 = 4, rSgnGamSize
+}
+{ .mfi
+ ldfpd fA18, fA19 = [rTmpPtr], 16 // D7, D6
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA1, fA1L = [rPolDataPtr], 16 // A1
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA16, fA17 = [rTmpPtr], 16 // D4, D5
+ nop.f 0
+}
+;;
+{ .mfi
+ ldfpd fA12, fA13 = [rPolDataPtr], 16 // D0, D1
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA14, fA15 = [rTmpPtr], 16 // D2, D3
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA24, fA25 = [rPolDataPtr], 16 // C21, C20
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA22, fA23 = [rTmpPtr], 16 // C19, C18
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA2, fA2L = [rPolDataPtr], 16 // A2
+ fma.s1 fA4L = FR_FracX, FR_FracX, f0 // x^2
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA20, fA21 = [rTmpPtr], 16 // C17, C16
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fA11 = [rTmpPtr], 16 // E7
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA0, fA3L = [rPolDataPtr], 16 // A0
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ ldfe fA10 = [rPolDataPtr], 16 // E6
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe fA9 = [rTmpPtr], 16 // E5
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mmf
+ ldfe fA8 = [rPolDataPtr], 16 // E4
+ ldfe fA7 = [rTmpPtr], 16 // E3
+ nop.f 0
+}
+;;
+{ .mmf
+ ldfe fA6 = [rPolDataPtr], 16 // E2
+ ldfe fA5 = [rTmpPtr], 16 // E1
+ nop.f 0
+}
+;;
+{ .mfi
+ ldfe fA4 = [rPolDataPtr], 16 // E0
+ fma.s1 fA5L = fA4L, fA4L, f0 // x^4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fB2 = FR_FracX, FR_FracX, fA4L // x^2 - <x^2>
+ nop.i 0
+}
+;;
+{ .mfi
+ // store signgam if size of variable is 4 bytes
+(p6) st4 [rSgnGamAddr] = rSgnGam
+ fma.s1 fRes4H = fA3, FR_FracX, f0 // (A3*x)hi
+ nop.i 0
+}
+{ .mfi
+ // store signgam if size of variable is 8 bytes
+(p7) st8 [rSgnGamAddr] = rSgnGam
+ fma.s1 fA19 = fA19, FR_FracX, fA18 // D7*x + D6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fResH = fA1, FR_FracX, f0 // (A1*x)hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB6 = fA1L, FR_FracX, fA0L // A1L*x + A0L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, FR_FracX, fA16 // D5*x + D4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, FR_FracX, fA14 // D3*x + D2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA25 = fA25, FR_FracX, fA24 // C21*x + C20
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA13 = fA13, FR_FracX, fA12 // D1*x + D0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA23 = fA23, FR_FracX, fA22 // C19*x + C18
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA21 = fA21, FR_FracX, fA20 // C17*x + C16
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fRes4L = fA3, FR_FracX, fRes4H // delta((A3*x)hi)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2H = fRes4H, fA2 // (A3*x + A2)hi
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fResL = fA1, FR_FracX, fResH // d(A1*x)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1H = fResH, fA0 // (A1*x + A0)hi
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA19 = fA19, fA4L, fA17 // Dhi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, FR_FracX, fA10 // E7*x + E6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // Doing this to raise inexact flag
+ fma.s0 fA10 = fA0, fA0, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, fA4L, fA13 // Dlo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (C21*x + C20)*x^2 + C19*x + C18
+ fma.s1 fA25 = fA25, fA4L, fA23
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, FR_FracX, fA8 // E5*x + E4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fA7, FR_FracX, fA6 // E3*x + E2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes4L = fA3L, FR_FracX, fRes4L // (A3*x)lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes2L = fA2, fRes2H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fResL = fResL, fB6 // (A1L*x + A0L) + d(A1*x)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes1L = fA0, fRes1H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA5 = fA5, FR_FracX, fA4 // E1*x + E0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB8 = fA5L, fA5L, f0 // x^8
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // ((C21*x + C20)*x^2 + C19*x + C18)*x^2 + C17*x + C16
+ fma.s1 fA25 = fA25, fA4L, fA21
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA19 = fA19, fA5L, fA15 // D
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, fA4L, fA9 // Ehi
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2L = fRes2L, fRes4H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes4L = fRes4L, fA2L // (A3*x)lo + A2L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes3H = fRes2H, fA4L, f0 // ((A3*x + A2)*x^2)hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1L = fRes1L, fResH
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes3L = fRes2H, fB2, f0 // (A3*x + A2)hi*d(x^2)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fA7, fA4L, fA5 // Elo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA25 = fA25, fB8, fA19 // C*x^8 + D
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2L = fRes2L, fRes4L // (A3*x + A2)lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fB4 = fRes2H, fA4L, fRes3H // d((A3*x + A2)*x^2))
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1L = fRes1L, fResL // (A1*x + A0)lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fB20 = fRes3H, fRes1H // Phi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, fA5L, fA7 // E
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // ( (A3*x + A2)lo*<x^2> + (A3*x + A2)hi*d(x^2))
+ fma.s1 fRes3L = fRes2L, fA4L, fRes3L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // d((A3*x + A2)*x^2)) + (A1*x + A0)lo
+ fadd.s1 fRes1L = fRes1L, fB4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fB18 = fRes1H, fB20
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fA25, fB8, fA11
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1L = fRes1L, fRes3L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fB18 = fB18, fRes3H
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fRes4H = fPol, fA5L, fB20
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fPolL = fPol, fA5L, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fB18 = fB18, fRes1L // Plo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes4L = fB20, fRes4H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fB18 = fB18, fPolL
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes4L = fRes4L, fB18
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ fma.s0 f8 = fRes4H, f1, fRes4L
+ // P25(x) computed, exit here
+ br.ret.sptk b0
+}
+;;
+
+
+// here if 0.75 <= x < 1.3125
+.align 32
+lgammal_03Q_1Q:
+{ .mfi
+ addl rPolDataPtr= @ltoff(lgammal_03Q_1Q_data),gp
+ fma.s1 FR_FracX = fA5L, f1, f0 // x
+ adds rSgnGam = 1, r0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB4 = fA5L, fA5L, f0 // x^2
+ nop.i 0
+}
+;;
+{ .mfi
+ ld8 rPolDataPtr = [rPolDataPtr]
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfb
+ adds rTmpPtr = 144, rPolDataPtr
+ nop.f 0
+ br.sptk lgamma_polynom24x
+}
+;;
+
+// here if 1.5625 <= x < 2.25
+.align 32
+lgammal_13Q_2Q:
+{ .mfi
+ addl rPolDataPtr= @ltoff(lgammal_13Q_2Q_data),gp
+ fma.s1 FR_FracX = fB4, f1, f0 // x
+ adds rSgnGam = 1, r0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB4 = fB4, fB4, f0 // x^2
+ nop.i 0
+}
+;;
+{ .mfi
+ ld8 rPolDataPtr = [rPolDataPtr]
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfb
+ adds rTmpPtr = 144, rPolDataPtr
+ nop.f 0
+ br.sptk lgamma_polynom24x
+}
+;;
+
+// here if result is Pol24(x)
+// x is in FR_FracX,
+// rPolDataPtr, rTmpPtr point to coefficients
+.align 32
+lgamma_polynom24x:
+{ .mfi
+ ldfpd fA4, fA2L = [rPolDataPtr], 16
+ nop.f 0
+ cmp.eq p6, p7 = 4, rSgnGamSize
+}
+{ .mfi
+ ldfpd fA23, fA24 = [rTmpPtr], 16 // C18, C19
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA3, fA1L = [rPolDataPtr], 16
+ fma.s1 fA5L = fB4, fB4, f0 // x^4
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA19, fA20 = [rTmpPtr], 16 // D6, D7
+ fms.s1 fB2 = FR_FracX, FR_FracX, fB4 // x^2 - <x^2>
+ nop.i 0
+}
+;;
+{ .mmf
+ ldfpd fA15, fA16 = [rPolDataPtr], 16 // D2, D3
+ ldfpd fA17, fA18 = [rTmpPtr], 16 // D4, D5
+ nop.f 0
+}
+;;
+{ .mmf
+ ldfpd fA13, fA14 = [rPolDataPtr], 16 // D0, D1
+ ldfpd fA12, fA21 = [rTmpPtr], 16 // E7, C16
+ nop.f 0
+}
+;;
+{ .mfi
+ ldfe fA11 = [rPolDataPtr], 16 // E6
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe fA10 = [rTmpPtr], 16 // E5
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA2, fA4L = [rPolDataPtr], 16
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA1, fA3L = [rTmpPtr], 16
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA22, fA25 = [rPolDataPtr], 16 // C17, C20
+ fma.s1 fA0 = fA5L, fA5L, f0 // x^8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA0L = fA5L, FR_FracX, f0 // x^5
+ nop.i 0
+}
+;;
+{ .mmf
+ ldfe fA9 = [rPolDataPtr], 16 // E4
+ ldfe fA8 = [rTmpPtr], 16 // E3
+ nop.f 0
+}
+;;
+{ .mmf
+ ldfe fA7 = [rPolDataPtr], 16 // E2
+ ldfe fA6 = [rTmpPtr], 16 // E1
+ nop.f 0
+}
+;;
+{ .mfi
+ ldfe fA5 = [rTmpPtr], 16 // E0
+ fma.s1 fRes4H = fA4, fB4, f0 // A4*<x^2>
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fA24, FR_FracX, fA23 // C19*x + C18
+ nop.i 0
+}
+;;
+{ .mfi
+ // store signgam if size of variable is 4 bytes
+(p6) st4 [rSgnGamAddr] = rSgnGam
+ fma.s1 fRes1H = fA3, fB4, f0 // A3*<x^2>
+ nop.i 0
+}
+{ .mfi
+ // store signgam if size of variable is 8 bytes
+(p7) st8 [rSgnGamAddr] = rSgnGam
+ fma.s1 fA1L = fA3, fB2,fA1L // A3*d(x^2) + A1L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA20 = fA20, FR_FracX, fA19 // D7*x + D6
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA18 = fA18, FR_FracX, fA17 // D5*x + D4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA16 = fA16, FR_FracX, fA15 // D3*x + D2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA14 = fA14, FR_FracX, fA13 // D1*x + D0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA2L = fA4, fB2,fA2L // A4*d(x^2) + A2L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA12 = fA12, FR_FracX, fA11 // E7*x + E6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fRes2L = fA4, fB4, fRes4H // delta(A4*<x^2>)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2H = fRes4H, fA2 // A4*<x^2> + A2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fms.s1 fRes3L = fA3, fB4, fRes1H // delta(A3*<x^2>)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes3H = fRes1H, fA1 // A3*<x^2> + A1
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA20 = fA20, fB4, fA18 // (D7*x + D6)*x^2 + D5*x + D4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA22 = fA22, FR_FracX, fA21 // C17*x + C16
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA16 = fA16, fB4, fA14 // (D3*x + D2)*x^2 + D1*x + D0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fA25, fB4, fPol // C20*x^2 + C19*x + C18
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA2L = fA4L, fB4, fA2L // A4L*<x^2> + A4*d(x^2) + A2L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA1L = fA3L, fB4, fA1L // A3L*<x^2> + A3*d(x^2) + A1L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes4L = fA2, fRes2H // d1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fResH = fRes2H, fB4, f0 // (A4*<x^2> + A2)*x^2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes1L = fA1, fRes3H // d1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB6 = fRes3H, FR_FracX, f0 // (A3*<x^2> + A1)*x
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA10 = fA10, FR_FracX, fA9 // E5*x + E4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA8 = fA8, FR_FracX, fA7 // E3*x + E2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // (C20*x^2 + C19*x + C18)*x^2 + C17*x + C16
+ fma.s1 fPol = fPol, fB4, fA22
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA6 = fA6, FR_FracX, fA5 // E1*x + E0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // A4L*<x^2> + A4*d(x^2) + A2L + delta(A4*<x^2>)
+ fadd.s1 fRes2L = fA2L, fRes2L
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // A3L*<x^2> + A3*d(x^2) + A1L + delta(A3*<x^2>)
+ fadd.s1 fRes3L = fA1L, fRes3L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes4L = fRes4L, fRes4H // d2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fResL = fRes2H, fB4, fResH // d(A4*<x^2> + A2)*x^2)
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes1L = fRes1L, fRes1H // d2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fB8 = fRes3H, FR_FracX, fB6 // d((A3*<x^2> + A1)*x)
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fB10 = fResH, fB6 // (A4*x^4 + .. + A1*x)hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA12 = fA12, fB4, fA10 // Ehi
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // ((D7*x + D6)*x^2 + D5*x + D4)*x^4 + (D3*x + D2)*x^2 + D1*x + D0
+ fma.s1 fA20 = fA20, fA5L, fA16
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA8 = fA8, fB4, fA6 // Elo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes2L = fRes2L, fRes4L // (A4*<x^2> + A2)lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // d(A4*<x^2> + A2)*x^2) + A4*<x^2> + A2)*d(x^2)
+ fma.s1 fResL = fRes2H, fB2, fResL
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes3L = fRes3L, fRes1L // (A4*<x^2> + A2)lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fB12 = fB6, fB10
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fPol, fA0, fA20 // PolC*x^8 + PolD
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPolL = fA12, fA5L, fA8 // E
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fResL = fB4, fRes2L, fResL // ((A4*<x^2> + A2)*x^2)lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes3L = fRes3L, FR_FracX, fB8 // ((A3*<x^2> + A1)*x)lo
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fB12 = fB12, fResH
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fPol = fPol, fA0, fPolL
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes3L = fRes3L, fResL
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes2H = fPol, fA0L, fB10
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes3L = fB12, fRes3L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fsub.s1 fRes4L = fB10, fRes2H
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes4L = fPol, fA0L, fRes4L
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fadd.s1 fRes4L = fRes4L, fRes3L
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ // final result for all paths for which the result is Pol24(x)
+ fma.s0 f8 = fRes2H, f1, fRes4L
+ // here is the exit for all paths for which the result is Pol24(x)
+ br.ret.sptk b0
+}
+;;
+
+
+// here if x is natval, nan, +/-inf, +/-0, or denormal
+.align 32
+lgammal_spec:
+{ .mfi
+ nop.m 0
+ fclass.m p9, p0 = f8, 0xB // +/-denormals
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fclass.m p6, p0 = f8, 0x1E1 // Test x for natval, nan, +inf
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ fclass.m p7, p0 = f8, 0x7 // +/-0
+(p9) br.cond.sptk lgammal_denormal_input
+};;
+{ .mfb
+ nop.m 0
+ nop.f 0
+ // branch out if if x is natval, nan, +inf
+(p6) br.cond.spnt lgammal_nan_pinf
+};;
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p7) br.cond.spnt lgammal_singularity
+};;
+// if we are still here then x = -inf
+{ .mfi
+ cmp.eq p6, p7 = 4, rSgnGamSize
+ nop.f 0
+ adds rSgnGam = 1, r0
+};;
+{ .mfi
+ // store signgam if size of variable is 4 bytes
+(p6) st4 [rSgnGamAddr] = rSgnGam
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+ // store signgam if size of variable is 8 bytes
+(p7) st8 [rSgnGamAddr] = rSgnGam
+ fma.s0 f8 = f8,f8,f0 // return +inf, no call to error support
+ br.ret.spnt b0
+};;
+
+// here if x is NaN, NatVal or +INF
+.align 32
+lgammal_nan_pinf:
+{ .mfi
+ cmp.eq p6, p7 = 4, rSgnGamSize
+ nop.f 0
+ adds rSgnGam = 1, r0
+}
+;;
+{ .mfi
+ // store signgam if size of variable is 4 bytes
+(p6) st4 [rSgnGamAddr] = rSgnGam
+ fma.s0 f8 = f8,f1,f8 // return x+x if x is natval, nan, +inf
+ nop.i 0
+}
+{ .mfb
+ // store signgam if size of variable is 8 bytes
+(p7) st8 [rSgnGamAddr] = rSgnGam
+ nop.f 0
+ br.ret.sptk b0
+}
+;;
+
+// here if x denormal or unnormal
+.align 32
+lgammal_denormal_input:
+{ .mfi
+ nop.m 0
+ fma.s0 fResH = f1, f1, f8 // raise denormal exception
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 f8 = f8 // normalize input value
+ nop.i 0
+}
+;;
+{ .mfi
+ getf.sig rSignifX = f8
+ fmerge.se fSignifX = f1, f8
+ nop.i 0
+}
+{ .mfi
+ getf.exp rSignExpX = f8
+ fcvt.fx.s1 fXint = f8 // Convert arg to int (int repres. in FR)
+ nop.i 0
+}
+;;
+{ .mfi
+ getf.exp rSignExpX = f8
+ fcmp.lt.s1 p15, p14 = f8, f0
+ nop.i 0
+}
+;;
+{ .mfb
+ and rExpX = rSignExpX, r17Ones
+ fmerge.s fAbsX = f1, f8 // |x|
+ br.cond.sptk _deno_back_to_main_path
+}
+;;
+
+
+// here if overflow (x > overflow_bound)
+.align 32
+lgammal_overflow:
+{ .mfi
+ addl r8 = 0x1FFFE, r0
+ nop.f 0
+ cmp.eq p6, p7 = 4, rSgnGamSize
+}
+{ .mfi
+ adds rSgnGam = 1, r0
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ setf.exp f9 = r8
+ fmerge.s FR_X = f8,f8
+ mov GR_Parameter_TAG = 102 // overflow
+};;
+{ .mfi
+ // store signgam if size of variable is 4 bytes
+(p6) st4 [rSgnGamAddr] = rSgnGam
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+ // store signgam if size of variable is 8 bytes
+(p7) st8 [rSgnGamAddr] = rSgnGam
+ fma.s0 FR_RESULT = f9,f9,f0 // Set I,O and +INF result
+ br.cond.sptk __libm_error_region
+};;
+
+// here if x is negative integer or +/-0 (SINGULARITY)
+.align 32
+lgammal_singularity:
+{ .mfi
+ adds rSgnGam = 1, r0
+ fclass.m p8,p0 = f8,0x6 // is x -0?
+ mov GR_Parameter_TAG = 103 // negative
+}
+{ .mfi
+ cmp.eq p6, p7 = 4, rSgnGamSize
+ fma.s1 FR_X = f0,f0,f8
+ nop.i 0
+};;
+{ .mfi
+(p8) sub rSgnGam = r0, rSgnGam
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ // store signgam if size of variable is 4 bytes
+(p6) st4 [rSgnGamAddr] = rSgnGam
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+ // store signgam if size of variable is 8 bytes
+(p7) st8 [rSgnGamAddr] = rSgnGam
+ frcpa.s0 FR_RESULT, p0 = f1, f0
+ br.cond.sptk __libm_error_region
+};;
+
+GLOBAL_LIBM_END(__libm_lgammal)
+
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 999
+ nop.i 999
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region#)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/libm_reduce.S b/libc/sysdeps/ia64/fpu/libm_reduce.S
new file mode 100644
index 000000000..8bdf91d6d
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_reduce.S
@@ -0,0 +1,1578 @@
+.file "libm_reduce.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History:
+// 02/02/00 Initial Version
+// 05/13/02 Rescheduled for speed, changed interface to pass
+// parameters in fp registers
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double data storage
+//
+//*********************************************************************
+//*********************************************************************
+//
+// Function: __libm_pi_by_two_reduce(x) return r, c, and N where
+// x = N * pi/4 + (r+c) , where |r+c| <= pi/4.
+// This function is not designed to be used by the
+// general user.
+//
+//*********************************************************************
+//
+// Accuracy: Returns double-precision values
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers:
+// f8 = Input x, return value r
+// f9 = return value c
+// f32-f70
+//
+// General Purpose Registers:
+// r8 = return value N
+// r34-r64
+//
+// Predicate Registers: p6-p14
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// No condions should be raised.
+//
+//*********************************************************************
+//
+// I. Introduction
+// ===============
+//
+// For the forward trigonometric functions sin, cos, sincos, and
+// tan, the original algorithms for IA 64 handle arguments up to
+// 1 ulp less than 2^63 in magnitude. For double-extended arguments x,
+// |x| >= 2^63, this routine returns N and r_hi, r_lo where
+//
+// x is accurately approximated by
+// 2*K*pi + N * pi/2 + r_hi + r_lo, |r_hi+r_lo| <= pi/4.
+// CASE = 1 or 2.
+// CASE is 1 unless |r_hi + r_lo| < 2^(-33).
+//
+// The exact value of K is not determined, but that information is
+// not required in trigonometric function computations.
+//
+// We first assume the argument x in question satisfies x >= 2^(63).
+// In particular, it is positive. Negative x can be handled by symmetry:
+//
+// -x is accurately approximated by
+// -2*K*pi + (-N) * pi/2 - (r_hi + r_lo), |r_hi+r_lo| <= pi/4.
+//
+// The idea of the reduction is that
+//
+// x * 2/pi = N_big + N + f, |f| <= 1/2
+//
+// Moreover, for double extended x, |f| >= 2^(-75). (This is an
+// non-obvious fact found by enumeration using a special algorithm
+// involving continued fraction.) The algorithm described below
+// calculates N and an accurate approximation of f.
+//
+// Roughly speaking, an appropriate 256-bit (4 X 64) portion of
+// 2/pi is multiplied with x to give the desired information.
+//
+// II. Representation of 2/PI
+// ==========================
+//
+// The value of 2/pi in binary fixed-point is
+//
+// .101000101111100110......
+//
+// We store 2/pi in a table, starting at the position corresponding
+// to bit position 63
+//
+// bit position 63 62 ... 0 -1 -2 -3 -4 -5 -6 -7 .... -16576
+//
+// 0 0 ... 0 . 1 0 1 0 1 0 1 .... X
+//
+// ^
+// |__ implied binary pt
+//
+// III. Algorithm
+// ==============
+//
+// This describes the algorithm in the most natural way using
+// unsigned interger multiplication. The implementation section
+// describes how the integer arithmetic is simulated.
+//
+// STEP 0. Initialization
+// ----------------------
+//
+// Let the input argument x be
+//
+// x = 2^m * ( 1. b_1 b_2 b_3 ... b_63 ), 63 <= m <= 16383.
+//
+// The first crucial step is to fetch four 64-bit portions of 2/pi.
+// To fulfill this goal, we calculate the bit position L of the
+// beginning of these 256-bit quantity by
+//
+// L := 62 - m.
+//
+// Note that -16321 <= L <= -1 because 63 <= m <= 16383; and that
+// the storage of 2/pi is adequate.
+//
+// Fetch P_1, P_2, P_3, P_4 beginning at bit position L thus:
+//
+// bit position L L-1 L-2 ... L-63
+//
+// P_1 = b b b ... b
+//
+// each b can be 0 or 1. Also, let P_0 be the two bits correspoding to
+// bit positions L+2 and L+1. So, when each of the P_j is interpreted
+// with appropriate scaling, we have
+//
+// 2/pi = P_big + P_0 + (P_1 + P_2 + P_3 + P_4) + P_small
+//
+// Note that P_big and P_small can be ignored. The reasons are as follow.
+// First, consider P_big. If P_big = 0, we can certainly ignore it.
+// Otherwise, P_big >= 2^(L+3). Now,
+//
+// P_big * ulp(x) >= 2^(L+3) * 2^(m-63)
+// >= 2^(65-m + m-63 )
+// >= 2^2
+//
+// Thus, P_big * x is an integer of the form 4*K. So
+//
+// x = 4*K * (pi/2) + x*(P_0 + P_1 + P_2 + P_3 + P_4)*(pi/2)
+// + x*P_small*(pi/2).
+//
+// Hence, P_big*x corresponds to information that can be ignored for
+// trigonometic function evaluation.
+//
+// Next, we must estimate the effect of ignoring P_small. The absolute
+// error made by ignoring P_small is bounded by
+//
+// |P_small * x| <= ulp(P_4) * x
+// <= 2^(L-255) * 2^(m+1)
+// <= 2^(62-m-255 + m + 1)
+// <= 2^(-192)
+//
+// Since for double-extended precision, x * 2/pi = integer + f,
+// 0.5 >= |f| >= 2^(-75), the relative error introduced by ignoring
+// P_small is bounded by 2^(-192+75) <= 2^(-117), which is acceptable.
+//
+// Further note that if x is split into x_hi + x_lo where x_lo is the
+// two bits corresponding to bit positions 2^(m-62) and 2^(m-63); then
+//
+// P_0 * x_hi
+//
+// is also an integer of the form 4*K; and thus can also be ignored.
+// Let M := P_0 * x_lo which is a small integer. The main part of the
+// calculation is really the multiplication of x with the four pieces
+// P_1, P_2, P_3, and P_4.
+//
+// Unless the reduced argument is extremely small in magnitude, it
+// suffices to carry out the multiplication of x with P_1, P_2, and
+// P_3. x*P_4 will be carried out and added on as a correction only
+// when it is found to be needed. Note also that x*P_4 need not be
+// computed exactly. A straightforward multiplication suffices since
+// the rounding error thus produced would be bounded by 2^(-3*64),
+// that is 2^(-192) which is small enough as the reduced argument
+// is bounded from below by 2^(-75).
+//
+// Now that we have four 64-bit data representing 2/pi and a
+// 64-bit x. We first need to calculate a highly accurate product
+// of x and P_1, P_2, P_3. This is best understood as integer
+// multiplication.
+//
+//
+// STEP 1. Multiplication
+// ----------------------
+//
+//
+// --------- --------- ---------
+// | P_1 | | P_2 | | P_3 |
+// --------- --------- ---------
+//
+// ---------
+// X | X |
+// ---------
+// ----------------------------------------------------
+//
+// --------- ---------
+// | A_hi | | A_lo |
+// --------- ---------
+//
+//
+// --------- ---------
+// | B_hi | | B_lo |
+// --------- ---------
+//
+//
+// --------- ---------
+// | C_hi | | C_lo |
+// --------- ---------
+//
+// ====================================================
+// --------- --------- --------- ---------
+// | S_0 | | S_1 | | S_2 | | S_3 |
+// --------- --------- --------- ---------
+//
+//
+//
+// STEP 2. Get N and f
+// -------------------
+//
+// Conceptually, after the individual pieces S_0, S_1, ..., are obtained,
+// we have to sum them and obtain an integer part, N, and a fraction, f.
+// Here, |f| <= 1/2, and N is an integer. Note also that N need only to
+// be known to module 2^k, k >= 2. In the case when |f| is small enough,
+// we would need to add in the value x*P_4.
+//
+//
+// STEP 3. Get reduced argument
+// ----------------------------
+//
+// The value f is not yet the reduced argument that we seek. The
+// equation
+//
+// x * 2/pi = 4K + N + f
+//
+// says that
+//
+// x = 2*K*pi + N * pi/2 + f * (pi/2).
+//
+// Thus, the reduced argument is given by
+//
+// reduced argument = f * pi/2.
+//
+// This multiplication must be performed to extra precision.
+//
+// IV. Implementation
+// ==================
+//
+// Step 0. Initialization
+// ----------------------
+//
+// Set sgn_x := sign(x); x := |x|; x_lo := 2 lsb of x.
+//
+// In memory, 2/pi is stored contigously as
+//
+// 0x00000000 0x00000000 0xA2F....
+// ^
+// |__ implied binary bit
+//
+// Given x = 2^m * 1.xxxx...xxx; we calculate L := 62 - m. Thus
+// -1 <= L <= -16321. We fetch from memory 5 integer pieces of data.
+//
+// P_0 is the two bits corresponding to bit positions L+2 and L+1
+// P_1 is the 64-bit starting at bit position L
+// P_2 is the 64-bit starting at bit position L-64
+// P_3 is the 64-bit starting at bit position L-128
+// P_4 is the 64-bit starting at bit position L-192
+//
+// For example, if m = 63, P_0 would be 0 and P_1 would look like
+// 0xA2F...
+//
+// If m = 65, P_0 would be the two msb of 0xA, thus, P_0 is 10 in binary.
+// P_1 in binary would be 1 0 0 0 1 0 1 1 1 1 ....
+//
+// Step 1. Multiplication
+// ----------------------
+//
+// At this point, P_1, P_2, P_3, P_4 are integers. They are
+// supposed to be interpreted as
+//
+// 2^(L-63) * P_1;
+// 2^(L-63-64) * P_2;
+// 2^(L-63-128) * P_3;
+// 2^(L-63-192) * P_4;
+//
+// Since each of them need to be multiplied to x, we would scale
+// both x and the P_j's by some convenient factors: scale each
+// of P_j's up by 2^(63-L), and scale x down by 2^(L-63).
+//
+// p_1 := fcvt.xf ( P_1 )
+// p_2 := fcvt.xf ( P_2 ) * 2^(-64)
+// p_3 := fcvt.xf ( P_3 ) * 2^(-128)
+// p_4 := fcvt.xf ( P_4 ) * 2^(-192)
+// x := replace exponent of x by -1
+// because 2^m * 1.xxxx...xxx * 2^(L-63)
+// is 2^(-1) * 1.xxxx...xxx
+//
+// We are now faced with the task of computing the following
+//
+// --------- --------- ---------
+// | P_1 | | P_2 | | P_3 |
+// --------- --------- ---------
+//
+// ---------
+// X | X |
+// ---------
+// ----------------------------------------------------
+//
+// --------- ---------
+// | A_hi | | A_lo |
+// --------- ---------
+//
+// --------- ---------
+// | B_hi | | B_lo |
+// --------- ---------
+//
+// --------- ---------
+// | C_hi | | C_lo |
+// --------- ---------
+//
+// ====================================================
+// ----------- --------- --------- ---------
+// | S_0 | | S_1 | | S_2 | | S_3 |
+// ----------- --------- --------- ---------
+// ^ ^
+// | |___ binary point
+// |
+// |___ possibly one more bit
+//
+// Let FPSR3 be set to round towards zero with widest precision
+// and exponent range. Unless an explicit FPSR is given,
+// round-to-nearest with widest precision and exponent range is
+// used.
+//
+// Define sigma_C := 2^63; sigma_B := 2^(-1); sigma_C := 2^(-65).
+//
+// Tmp_C := fmpy.fpsr3( x, p_1 );
+// If Tmp_C >= sigma_C then
+// C_hi := Tmp_C;
+// C_lo := x*p_1 - C_hi ...fma, exact
+// Else
+// C_hi := fadd.fpsr3(sigma_C, Tmp_C) - sigma_C
+// ...subtraction is exact, regardless
+// ...of rounding direction
+// C_lo := x*p_1 - C_hi ...fma, exact
+// End If
+//
+// Tmp_B := fmpy.fpsr3( x, p_2 );
+// If Tmp_B >= sigma_B then
+// B_hi := Tmp_B;
+// B_lo := x*p_2 - B_hi ...fma, exact
+// Else
+// B_hi := fadd.fpsr3(sigma_B, Tmp_B) - sigma_B
+// ...subtraction is exact, regardless
+// ...of rounding direction
+// B_lo := x*p_2 - B_hi ...fma, exact
+// End If
+//
+// Tmp_A := fmpy.fpsr3( x, p_3 );
+// If Tmp_A >= sigma_A then
+// A_hi := Tmp_A;
+// A_lo := x*p_3 - A_hi ...fma, exact
+// Else
+// A_hi := fadd.fpsr3(sigma_A, Tmp_A) - sigma_A
+// ...subtraction is exact, regardless
+// ...of rounding direction
+// A_lo := x*p_3 - A_hi ...fma, exact
+// End If
+//
+// ...Note that C_hi is of integer value. We need only the
+// ...last few bits. Thus we can ensure C_hi is never a big
+// ...integer, freeing us from overflow worry.
+//
+// Tmp_C := fadd.fpsr3( C_hi, 2^(70) ) - 2^(70);
+// ...Tmp_C is the upper portion of C_hi
+// C_hi := C_hi - Tmp_C
+// ...0 <= C_hi < 2^7
+//
+// Step 2. Get N and f
+// -------------------
+//
+// At this point, we have all the components to obtain
+// S_0, S_1, S_2, S_3 and thus N and f. We start by adding
+// C_lo and B_hi. This sum together with C_hi gives a good
+// estimation of N and f.
+//
+// A := fadd.fpsr3( B_hi, C_lo )
+// B := max( B_hi, C_lo )
+// b := min( B_hi, C_lo )
+//
+// a := (B - A) + b ...exact. Note that a is either 0
+// ...or 2^(-64).
+//
+// N := round_to_nearest_integer_value( A );
+// f := A - N; ...exact because lsb(A) >= 2^(-64)
+// ...and |f| <= 1/2.
+//
+// f := f + a ...exact because a is 0 or 2^(-64);
+// ...the msb of the sum is <= 1/2
+// ...lsb >= 2^(-64).
+//
+// N := convert to integer format( C_hi + N );
+// M := P_0 * x_lo;
+// N := N + M;
+//
+// If sgn_x == 1 (that is original x was negative)
+// N := 2^10 - N
+// ...this maintains N to be non-negative, but still
+// ...equivalent to the (negated N) mod 4.
+// End If
+//
+// If |f| >= 2^(-33)
+//
+// ...Case 1
+// CASE := 1
+// g := A_hi + B_lo;
+// s_hi := f + g;
+// s_lo := (f - s_hi) + g;
+//
+// Else
+//
+// ...Case 2
+// CASE := 2
+// A := fadd.fpsr3( A_hi, B_lo )
+// B := max( A_hi, B_lo )
+// b := min( A_hi, B_lo )
+//
+// a := (B - A) + b ...exact. Note that a is either 0
+// ...or 2^(-128).
+//
+// f_hi := A + f;
+// f_lo := (f - f_hi) + A;
+// ...this is exact.
+// ...f-f_hi is exact because either |f| >= |A|, in which
+// ...case f-f_hi is clearly exact; or otherwise, 0<|f|<|A|
+// ...means msb(f) <= msb(A) = 2^(-64) => |f| = 2^(-64).
+// ...If f = 2^(-64), f-f_hi involves cancellation and is
+// ...exact. If f = -2^(-64), then A + f is exact. Hence
+// ...f-f_hi is -A exactly, giving f_lo = 0.
+//
+// f_lo := f_lo + a;
+//
+// If |f| >= 2^(-50) then
+// s_hi := f_hi;
+// s_lo := f_lo;
+// Else
+// f_lo := (f_lo + A_lo) + x*p_4
+// s_hi := f_hi + f_lo
+// s_lo := (f_hi - s_hi) + f_lo
+// End If
+//
+// End If
+//
+// Step 3. Get reduced argument
+// ----------------------------
+//
+// If sgn_x == 0 (that is original x is positive)
+//
+// D_hi := Pi_by_2_hi
+// D_lo := Pi_by_2_lo
+// ...load from table
+//
+// Else
+//
+// D_hi := neg_Pi_by_2_hi
+// D_lo := neg_Pi_by_2_lo
+// ...load from table
+// End If
+//
+// r_hi := s_hi*D_hi
+// r_lo := s_hi*D_hi - r_hi ...fma
+// r_lo := (s_hi*D_lo + r_lo) + s_lo*D_hi
+//
+// Return N, r_hi, r_lo
+//
+FR_input_X = f8
+FR_r_hi = f8
+FR_r_lo = f9
+
+FR_X = f32
+FR_N = f33
+FR_p_1 = f34
+FR_TWOM33 = f35
+FR_TWOM50 = f36
+FR_g = f37
+FR_p_2 = f38
+FR_f = f39
+FR_s_lo = f40
+FR_p_3 = f41
+FR_f_abs = f42
+FR_D_lo = f43
+FR_p_4 = f44
+FR_D_hi = f45
+FR_Tmp2_C = f46
+FR_s_hi = f47
+FR_sigma_A = f48
+FR_A = f49
+FR_sigma_B = f50
+FR_B = f51
+FR_sigma_C = f52
+FR_b = f53
+FR_ScaleP2 = f54
+FR_ScaleP3 = f55
+FR_ScaleP4 = f56
+FR_Tmp_A = f57
+FR_Tmp_B = f58
+FR_Tmp_C = f59
+FR_A_hi = f60
+FR_f_hi = f61
+FR_RSHF = f62
+FR_A_lo = f63
+FR_B_hi = f64
+FR_a = f65
+FR_B_lo = f66
+FR_f_lo = f67
+FR_N_fix = f68
+FR_C_hi = f69
+FR_C_lo = f70
+
+GR_N = r8
+GR_Exp_x = r36
+GR_Temp = r37
+GR_BIASL63 = r38
+GR_CASE = r39
+GR_x_lo = r40
+GR_sgn_x = r41
+GR_M = r42
+GR_BASE = r43
+GR_LENGTH1 = r44
+GR_LENGTH2 = r45
+GR_ASUB = r46
+GR_P_0 = r47
+GR_P_1 = r48
+GR_P_2 = r49
+GR_P_3 = r50
+GR_P_4 = r51
+GR_START = r52
+GR_SEGMENT = r53
+GR_A = r54
+GR_B = r55
+GR_C = r56
+GR_D = r57
+GR_E = r58
+GR_TEMP1 = r59
+GR_TEMP2 = r60
+GR_TEMP3 = r61
+GR_TEMP4 = r62
+GR_TEMP5 = r63
+GR_TEMP6 = r64
+GR_rshf = r64
+
+RODATA
+.align 64
+
+LOCAL_OBJECT_START(Constants_Bits_of_2_by_pi)
+data8 0x0000000000000000,0xA2F9836E4E441529
+data8 0xFC2757D1F534DDC0,0xDB6295993C439041
+data8 0xFE5163ABDEBBC561,0xB7246E3A424DD2E0
+data8 0x06492EEA09D1921C,0xFE1DEB1CB129A73E
+data8 0xE88235F52EBB4484,0xE99C7026B45F7E41
+data8 0x3991D639835339F4,0x9C845F8BBDF9283B
+data8 0x1FF897FFDE05980F,0xEF2F118B5A0A6D1F
+data8 0x6D367ECF27CB09B7,0x4F463F669E5FEA2D
+data8 0x7527BAC7EBE5F17B,0x3D0739F78A5292EA
+data8 0x6BFB5FB11F8D5D08,0x56033046FC7B6BAB
+data8 0xF0CFBC209AF4361D,0xA9E391615EE61B08
+data8 0x6599855F14A06840,0x8DFFD8804D732731
+data8 0x06061556CA73A8C9,0x60E27BC08C6B47C4
+data8 0x19C367CDDCE8092A,0x8359C4768B961CA6
+data8 0xDDAF44D15719053E,0xA5FF07053F7E33E8
+data8 0x32C2DE4F98327DBB,0xC33D26EF6B1E5EF8
+data8 0x9F3A1F35CAF27F1D,0x87F121907C7C246A
+data8 0xFA6ED5772D30433B,0x15C614B59D19C3C2
+data8 0xC4AD414D2C5D000C,0x467D862D71E39AC6
+data8 0x9B0062337CD2B497,0xA7B4D55537F63ED7
+data8 0x1810A3FC764D2A9D,0x64ABD770F87C6357
+data8 0xB07AE715175649C0,0xD9D63B3884A7CB23
+data8 0x24778AD623545AB9,0x1F001B0AF1DFCE19
+data8 0xFF319F6A1E666157,0x9947FBACD87F7EB7
+data8 0x652289E83260BFE6,0xCDC4EF09366CD43F
+data8 0x5DD7DE16DE3B5892,0x9BDE2822D2E88628
+data8 0x4D58E232CAC616E3,0x08CB7DE050C017A7
+data8 0x1DF35BE01834132E,0x6212830148835B8E
+data8 0xF57FB0ADF2E91E43,0x4A48D36710D8DDAA
+data8 0x425FAECE616AA428,0x0AB499D3F2A6067F
+data8 0x775C83C2A3883C61,0x78738A5A8CAFBDD7
+data8 0x6F63A62DCBBFF4EF,0x818D67C12645CA55
+data8 0x36D9CAD2A8288D61,0xC277C9121426049B
+data8 0x4612C459C444C5C8,0x91B24DF31700AD43
+data8 0xD4E5492910D5FDFC,0xBE00CC941EEECE70
+data8 0xF53E1380F1ECC3E7,0xB328F8C79405933E
+data8 0x71C1B3092EF3450B,0x9C12887B20AB9FB5
+data8 0x2EC292472F327B6D,0x550C90A7721FE76B
+data8 0x96CB314A1679E279,0x4189DFF49794E884
+data8 0xE6E29731996BED88,0x365F5F0EFDBBB49A
+data8 0x486CA46742727132,0x5D8DB8159F09E5BC
+data8 0x25318D3974F71C05,0x30010C0D68084B58
+data8 0xEE2C90AA4702E774,0x24D6BDA67DF77248
+data8 0x6EEF169FA6948EF6,0x91B45153D1F20ACF
+data8 0x3398207E4BF56863,0xB25F3EDD035D407F
+data8 0x8985295255C06437,0x10D86D324832754C
+data8 0x5BD4714E6E5445C1,0x090B69F52AD56614
+data8 0x9D072750045DDB3B,0xB4C576EA17F9877D
+data8 0x6B49BA271D296996,0xACCCC65414AD6AE2
+data8 0x9089D98850722CBE,0xA4049407777030F3
+data8 0x27FC00A871EA49C2,0x663DE06483DD9797
+data8 0x3FA3FD94438C860D,0xDE41319D39928C70
+data8 0xDDE7B7173BDF082B,0x3715A0805C93805A
+data8 0x921110D8E80FAF80,0x6C4BFFDB0F903876
+data8 0x185915A562BBCB61,0xB989C7BD401004F2
+data8 0xD2277549F6B6EBBB,0x22DBAA140A2F2689
+data8 0x768364333B091A94,0x0EAA3A51C2A31DAE
+data8 0xEDAF12265C4DC26D,0x9C7A2D9756C0833F
+data8 0x03F6F0098C402B99,0x316D07B43915200C
+data8 0x5BC3D8C492F54BAD,0xC6A5CA4ECD37A736
+data8 0xA9E69492AB6842DD,0xDE6319EF8C76528B
+data8 0x6837DBFCABA1AE31,0x15DFA1AE00DAFB0C
+data8 0x664D64B705ED3065,0x29BF56573AFF47B9
+data8 0xF96AF3BE75DF9328,0x3080ABF68C6615CB
+data8 0x040622FA1DE4D9A4,0xB33D8F1B5709CD36
+data8 0xE9424EA4BE13B523,0x331AAAF0A8654FA5
+data8 0xC1D20F3F0BCD785B,0x76F923048B7B7217
+data8 0x8953A6C6E26E6F00,0xEBEF584A9BB7DAC4
+data8 0xBA66AACFCF761D02,0xD12DF1B1C1998C77
+data8 0xADC3DA4886A05DF7,0xF480C62FF0AC9AEC
+data8 0xDDBC5C3F6DDED01F,0xC790B6DB2A3A25A3
+data8 0x9AAF009353AD0457,0xB6B42D297E804BA7
+data8 0x07DA0EAA76A1597B,0x2A12162DB7DCFDE5
+data8 0xFAFEDB89FDBE896C,0x76E4FCA90670803E
+data8 0x156E85FF87FD073E,0x2833676186182AEA
+data8 0xBD4DAFE7B36E6D8F,0x3967955BBF3148D7
+data8 0x8416DF30432DC735,0x6125CE70C9B8CB30
+data8 0xFD6CBFA200A4E46C,0x05A0DD5A476F21D2
+data8 0x1262845CB9496170,0xE0566B0152993755
+data8 0x50B7D51EC4F1335F,0x6E13E4305DA92E85
+data8 0xC3B21D3632A1A4B7,0x08D4B1EA21F716E4
+data8 0x698F77FF2780030C,0x2D408DA0CD4F99A5
+data8 0x20D3A2B30A5D2F42,0xF9B4CBDA11D0BE7D
+data8 0xC1DB9BBD17AB81A2,0xCA5C6A0817552E55
+data8 0x0027F0147F8607E1,0x640B148D4196DEBE
+data8 0x872AFDDAB6256B34,0x897BFEF3059EBFB9
+data8 0x4F6A68A82A4A5AC4,0x4FBCF82D985AD795
+data8 0xC7F48D4D0DA63A20,0x5F57A4B13F149538
+data8 0x800120CC86DD71B6,0xDEC9F560BF11654D
+data8 0x6B0701ACB08CD0C0,0xB24855510EFB1EC3
+data8 0x72953B06A33540C0,0x7BDC06CC45E0FA29
+data8 0x4EC8CAD641F3E8DE,0x647CD8649B31BED9
+data8 0xC397A4D45877C5E3,0x6913DAF03C3ABA46
+data8 0x18465F7555F5BDD2,0xC6926E5D2EACED44
+data8 0x0E423E1C87C461E9,0xFD29F3D6E7CA7C22
+data8 0x35916FC5E0088DD7,0xFFE26A6EC6FDB0C1
+data8 0x0893745D7CB2AD6B,0x9D6ECD7B723E6A11
+data8 0xC6A9CFF7DF7329BA,0xC9B55100B70DB2E2
+data8 0x24BA74607DE58AD8,0x742C150D0C188194
+data8 0x667E162901767A9F,0xBEFDFDEF4556367E
+data8 0xD913D9ECB9BA8BFC,0x97C427A831C36EF1
+data8 0x36C59456A8D8B5A8,0xB40ECCCF2D891234
+data8 0x576F89562CE3CE99,0xB920D6AA5E6B9C2A
+data8 0x3ECC5F114A0BFDFB,0xF4E16D3B8E2C86E2
+data8 0x84D4E9A9B4FCD1EE,0xEFC9352E61392F44
+data8 0x2138C8D91B0AFC81,0x6A4AFBD81C2F84B4
+data8 0x538C994ECC2254DC,0x552AD6C6C096190B
+data8 0xB8701A649569605A,0x26EE523F0F117F11
+data8 0xB5F4F5CBFC2DBC34,0xEEBC34CC5DE8605E
+data8 0xDD9B8E67EF3392B8,0x17C99B5861BC57E1
+data8 0xC68351103ED84871,0xDDDD1C2DA118AF46
+data8 0x2C21D7F359987AD9,0xC0549EFA864FFC06
+data8 0x56AE79E536228922,0xAD38DC9367AAE855
+data8 0x3826829BE7CAA40D,0x51B133990ED7A948
+data8 0x0569F0B265A7887F,0x974C8836D1F9B392
+data8 0x214A827B21CF98DC,0x9F405547DC3A74E1
+data8 0x42EB67DF9DFE5FD4,0x5EA4677B7AACBAA2
+data8 0xF65523882B55BA41,0x086E59862A218347
+data8 0x39E6E389D49EE540,0xFB49E956FFCA0F1C
+data8 0x8A59C52BFA94C5C1,0xD3CFC50FAE5ADB86
+data8 0xC5476243853B8621,0x94792C8761107B4C
+data8 0x2A1A2C8012BF4390,0x2688893C78E4C4A8
+data8 0x7BDBE5C23AC4EAF4,0x268A67F7BF920D2B
+data8 0xA365B1933D0B7CBD,0xDC51A463DD27DDE1
+data8 0x6919949A9529A828,0xCE68B4ED09209F44
+data8 0xCA984E638270237C,0x7E32B90F8EF5A7E7
+data8 0x561408F1212A9DB5,0x4D7E6F5119A5ABF9
+data8 0xB5D6DF8261DD9602,0x36169F3AC4A1A283
+data8 0x6DED727A8D39A9B8,0x825C326B5B2746ED
+data8 0x34007700D255F4FC,0x4D59018071E0E13F
+data8 0x89B295F364A8F1AE,0xA74B38FC4CEAB2BB
+LOCAL_OBJECT_END(Constants_Bits_of_2_by_pi)
+
+LOCAL_OBJECT_START(Constants_Bits_of_pi_by_2)
+data8 0xC90FDAA22168C234,0x00003FFF
+data8 0xC4C6628B80DC1CD1,0x00003FBF
+LOCAL_OBJECT_END(Constants_Bits_of_pi_by_2)
+
+.section .text
+.global __libm_pi_by_2_reduce#
+.proc __libm_pi_by_2_reduce#
+.align 32
+
+__libm_pi_by_2_reduce:
+
+// X is in f8
+// Place the two-piece result r (r_hi) in f8 and c (r_lo) in f9
+// N is returned in r8
+
+{ .mfi
+ alloc r34 = ar.pfs,2,34,0,0
+ fsetc.s3 0x00,0x7F // Set sf3 to round to zero, 82-bit prec, td, ftz
+ nop.i 999
+}
+{ .mfi
+ addl GR_BASE = @ltoff(Constants_Bits_of_2_by_pi#), gp
+ nop.f 999
+ mov GR_BIASL63 = 0x1003E
+}
+;;
+
+
+// L -1-2-3-4
+// 0 0 0 0 0. 1 0 1 0
+// M 0 1 2 .... 63, 64 65 ... 127, 128
+// ---------------------------------------------
+// Segment 0. 1 , 2 , 3
+// START = M - 63 M = 128 becomes 65
+// LENGTH1 = START & 0x3F 65 become position 1
+// SEGMENT = shr(START,6) + 1 0 maps to 1, 64 maps to 2,
+// LENGTH2 = 64 - LENGTH1
+// Address_BASE = shladd(SEGMENT,3) + BASE
+
+
+{ .mmi
+ getf.exp GR_Exp_x = FR_input_X
+ ld8 GR_BASE = [GR_BASE]
+ mov GR_TEMP5 = 0x0FFFE
+}
+;;
+
+// Define sigma_C := 2^63; sigma_B := 2^(-1); sigma_A := 2^(-65).
+{ .mmi
+ getf.sig GR_x_lo = FR_input_X
+ mov GR_TEMP6 = 0x0FFBE
+ nop.i 999
+}
+;;
+
+// Special Code for testing DE arguments
+// movl GR_BIASL63 = 0x0000000000013FFE
+// movl GR_x_lo = 0xFFFFFFFFFFFFFFFF
+// setf.exp FR_X = GR_BIASL63
+// setf.sig FR_ScaleP3 = GR_x_lo
+// fmerge.se FR_X = FR_X,FR_ScaleP3
+// Set sgn_x := sign(x); x := |x|; x_lo := 2 lsb of x.
+// 2/pi is stored contigously as
+// 0x00000000 0x00000000.0xA2F....
+// M = EXP - BIAS ( M >= 63)
+// Given x = 2^m * 1.xxxx...xxx; we calculate L := 62 - m.
+// Thus -1 <= L <= -16321.
+{ .mmi
+ setf.exp FR_sigma_B = GR_TEMP5
+ setf.exp FR_sigma_A = GR_TEMP6
+ extr.u GR_M = GR_Exp_x,0,17
+}
+;;
+
+{ .mii
+ and GR_x_lo = 0x03,GR_x_lo
+ sub GR_START = GR_M,GR_BIASL63
+ add GR_BASE = 8,GR_BASE // To effectively add 1 to SEGMENT
+}
+;;
+
+{ .mii
+ and GR_LENGTH1 = 0x3F,GR_START
+ shr.u GR_SEGMENT = GR_START,6
+ nop.i 999
+}
+;;
+
+{ .mmi
+ shladd GR_BASE = GR_SEGMENT,3,GR_BASE
+ sub GR_LENGTH2 = 0x40,GR_LENGTH1
+ cmp.le p6,p7 = 0x2,GR_LENGTH1
+}
+;;
+
+// P_0 is the two bits corresponding to bit positions L+2 and L+1
+// P_1 is the 64-bit starting at bit position L
+// P_2 is the 64-bit starting at bit position L-64
+// P_3 is the 64-bit starting at bit position L-128
+// P_4 is the 64-bit starting at bit position L-192
+// P_1 is made up of Alo and Bhi
+// P_1 = deposit Alo, position 0, length2 into P_1,position length1
+// deposit Bhi, position length2, length1 into P_1, position 0
+// P_2 is made up of Blo and Chi
+// P_2 = deposit Blo, position 0, length2 into P_2, position length1
+// deposit Chi, position length2, length1 into P_2, position 0
+// P_3 is made up of Clo and Dhi
+// P_3 = deposit Clo, position 0, length2 into P_3, position length1
+// deposit Dhi, position length2, length1 into P_3, position 0
+// P_4 is made up of Clo and Dhi
+// P_4 = deposit Dlo, position 0, length2 into P_4, position length1
+// deposit Ehi, position length2, length1 into P_4, position 0
+{ .mfi
+ ld8 GR_A = [GR_BASE],8
+ fabs FR_X = FR_input_X
+(p7) cmp.eq.unc p8,p9 = 0x1,GR_LENGTH1
+}
+;;
+
+// ld_64 A at Base and increment Base by 8
+// ld_64 B at Base and increment Base by 8
+// ld_64 C at Base and increment Base by 8
+// ld_64 D at Base and increment Base by 8
+// ld_64 E at Base and increment Base by 8
+// A/B/C/D
+// ---------------------
+// A, B, C, D, and E look like | length1 | length2 |
+// ---------------------
+// hi lo
+{ .mlx
+ ld8 GR_B = [GR_BASE],8
+ movl GR_rshf = 0x43e8000000000000 // 1.10000 2^63 for right shift N_fix
+}
+;;
+
+{ .mmi
+ ld8 GR_C = [GR_BASE],8
+ nop.m 999
+(p8) extr.u GR_Temp = GR_A,63,1
+}
+;;
+
+// If length1 >= 2,
+// P_0 = deposit Ahi, position length2, 2 bit into P_0 at position 0.
+{ .mii
+ ld8 GR_D = [GR_BASE],8
+ shl GR_TEMP1 = GR_A,GR_LENGTH1 // MM instruction
+(p6) shr.u GR_P_0 = GR_A,GR_LENGTH2 // MM instruction
+}
+;;
+
+{ .mii
+ ld8 GR_E = [GR_BASE],-40
+ shl GR_TEMP2 = GR_B,GR_LENGTH1 // MM instruction
+ shr.u GR_P_1 = GR_B,GR_LENGTH2 // MM instruction
+}
+;;
+
+// Else
+// Load 16 bit of ASUB from (Base_Address_of_A - 2)
+// P_0 = ASUB & 0x3
+// If length1 == 0,
+// P_0 complete
+// Else
+// Deposit element 63 from Ahi and place in element 0 of P_0.
+// Endif
+// Endif
+
+{ .mii
+(p7) ld2 GR_ASUB = [GR_BASE],8
+ shl GR_TEMP3 = GR_C,GR_LENGTH1 // MM instruction
+ shr.u GR_P_2 = GR_C,GR_LENGTH2 // MM instruction
+}
+;;
+
+{ .mii
+ setf.d FR_RSHF = GR_rshf // Form right shift const 1.100 * 2^63
+ shl GR_TEMP4 = GR_D,GR_LENGTH1 // MM instruction
+ shr.u GR_P_3 = GR_D,GR_LENGTH2 // MM instruction
+}
+;;
+
+{ .mmi
+(p7) and GR_P_0 = 0x03,GR_ASUB
+(p6) and GR_P_0 = 0x03,GR_P_0
+ shr.u GR_P_4 = GR_E,GR_LENGTH2 // MM instruction
+}
+;;
+
+{ .mmi
+ nop.m 999
+ or GR_P_1 = GR_P_1,GR_TEMP1
+(p8) and GR_P_0 = 0x1,GR_P_0
+}
+;;
+
+{ .mmi
+ setf.sig FR_p_1 = GR_P_1
+ or GR_P_2 = GR_P_2,GR_TEMP2
+(p8) shladd GR_P_0 = GR_P_0,1,GR_Temp
+}
+;;
+
+{ .mmf
+ setf.sig FR_p_2 = GR_P_2
+ or GR_P_3 = GR_P_3,GR_TEMP3
+ fmerge.se FR_X = FR_sigma_B,FR_X
+}
+;;
+
+{ .mmi
+ setf.sig FR_p_3 = GR_P_3
+ or GR_P_4 = GR_P_4,GR_TEMP4
+ pmpy2.r GR_M = GR_P_0,GR_x_lo
+}
+;;
+
+// P_1, P_2, P_3, P_4 are integers. They should be
+// 2^(L-63) * P_1;
+// 2^(L-63-64) * P_2;
+// 2^(L-63-128) * P_3;
+// 2^(L-63-192) * P_4;
+// Since each of them need to be multiplied to x, we would scale
+// both x and the P_j's by some convenient factors: scale each
+// of P_j's up by 2^(63-L), and scale x down by 2^(L-63).
+// p_1 := fcvt.xf ( P_1 )
+// p_2 := fcvt.xf ( P_2 ) * 2^(-64)
+// p_3 := fcvt.xf ( P_3 ) * 2^(-128)
+// p_4 := fcvt.xf ( P_4 ) * 2^(-192)
+// x= Set x's exp to -1 because 2^m*1.x...x *2^(L-63)=2^(-1)*1.x...xxx
+// --------- --------- ---------
+// | P_1 | | P_2 | | P_3 |
+// --------- --------- ---------
+// ---------
+// X | X |
+// ---------
+// ----------------------------------------------------
+// --------- ---------
+// | A_hi | | A_lo |
+// --------- ---------
+// --------- ---------
+// | B_hi | | B_lo |
+// --------- ---------
+// --------- ---------
+// | C_hi | | C_lo |
+// --------- ---------
+// ====================================================
+// ----------- --------- --------- ---------
+// | S_0 | | S_1 | | S_2 | | S_3 |
+// ----------- --------- --------- ---------
+// | |___ binary point
+// |___ possibly one more bit
+//
+// Let FPSR3 be set to round towards zero with widest precision
+// and exponent range. Unless an explicit FPSR is given,
+// round-to-nearest with widest precision and exponent range is
+// used.
+{ .mmi
+ setf.sig FR_p_4 = GR_P_4
+ mov GR_TEMP1 = 0x0FFBF
+ nop.i 999
+}
+;;
+
+{ .mmi
+ setf.exp FR_ScaleP2 = GR_TEMP1
+ mov GR_TEMP2 = 0x0FF7F
+ nop.i 999
+}
+;;
+
+{ .mmi
+ setf.exp FR_ScaleP3 = GR_TEMP2
+ mov GR_TEMP4 = 0x1003E
+ nop.i 999
+}
+;;
+
+{ .mmf
+ setf.exp FR_sigma_C = GR_TEMP4
+ mov GR_Temp = 0x0FFDE
+ fcvt.xuf.s1 FR_p_1 = FR_p_1
+}
+;;
+
+{ .mfi
+ setf.exp FR_TWOM33 = GR_Temp
+ fcvt.xuf.s1 FR_p_2 = FR_p_2
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcvt.xuf.s1 FR_p_3 = FR_p_3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcvt.xuf.s1 FR_p_4 = FR_p_4
+ nop.i 999
+}
+;;
+
+// Tmp_C := fmpy.fpsr3( x, p_1 );
+// Tmp_B := fmpy.fpsr3( x, p_2 );
+// Tmp_A := fmpy.fpsr3( x, p_3 );
+// If Tmp_C >= sigma_C then
+// C_hi := Tmp_C;
+// C_lo := x*p_1 - C_hi ...fma, exact
+// Else
+// C_hi := fadd.fpsr3(sigma_C, Tmp_C) - sigma_C
+// C_lo := x*p_1 - C_hi ...fma, exact
+// End If
+// If Tmp_B >= sigma_B then
+// B_hi := Tmp_B;
+// B_lo := x*p_2 - B_hi ...fma, exact
+// Else
+// B_hi := fadd.fpsr3(sigma_B, Tmp_B) - sigma_B
+// B_lo := x*p_2 - B_hi ...fma, exact
+// End If
+// If Tmp_A >= sigma_A then
+// A_hi := Tmp_A;
+// A_lo := x*p_3 - A_hi ...fma, exact
+// Else
+// A_hi := fadd.fpsr3(sigma_A, Tmp_A) - sigma_A
+// Exact, regardless ...of rounding direction
+// A_lo := x*p_3 - A_hi ...fma, exact
+// Endif
+{ .mfi
+ nop.m 999
+ fmpy.s3 FR_Tmp_C = FR_X,FR_p_1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ mov GR_TEMP3 = 0x0FF3F
+ fmpy.s1 FR_p_2 = FR_p_2,FR_ScaleP2
+ nop.i 999
+}
+;;
+
+{ .mmf
+ setf.exp FR_ScaleP4 = GR_TEMP3
+ mov GR_TEMP4 = 0x10045
+ fmpy.s1 FR_p_3 = FR_p_3,FR_ScaleP3
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fadd.s3 FR_C_hi = FR_sigma_C,FR_Tmp_C // For Tmp_C < sigma_C case
+ nop.i 999
+}
+;;
+
+{ .mmf
+ setf.exp FR_Tmp2_C = GR_TEMP4
+ nop.m 999
+ fmpy.s3 FR_Tmp_B = FR_X,FR_p_2
+}
+;;
+
+{ .mfi
+ addl GR_BASE = @ltoff(Constants_Bits_of_pi_by_2#), gp
+ fcmp.ge.s1 p12, p9 = FR_Tmp_C,FR_sigma_C
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s3 FR_Tmp_A = FR_X,FR_p_3
+ nop.i 99
+}
+;;
+
+{ .mfi
+ ld8 GR_BASE = [GR_BASE]
+(p12) mov FR_C_hi = FR_Tmp_C
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fsub.s1 FR_C_hi = FR_C_hi,FR_sigma_C
+ nop.i 999
+}
+;;
+
+
+
+// End If
+// Step 3. Get reduced argument
+// If sgn_x == 0 (that is original x is positive)
+// D_hi := Pi_by_2_hi
+// D_lo := Pi_by_2_lo
+// Load from table
+// Else
+// D_hi := neg_Pi_by_2_hi
+// D_lo := neg_Pi_by_2_lo
+// Load from table
+// End If
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_p_4 = FR_p_4,FR_ScaleP4
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s3 FR_B_hi = FR_sigma_B,FR_Tmp_B // For Tmp_B < sigma_B case
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fadd.s3 FR_A_hi = FR_sigma_A,FR_Tmp_A // For Tmp_A < sigma_A case
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcmp.ge.s1 p13, p10 = FR_Tmp_B,FR_sigma_B
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fms.s1 FR_C_lo = FR_X,FR_p_1,FR_C_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe FR_D_hi = [GR_BASE],16
+ fcmp.ge.s1 p14, p11 = FR_Tmp_A,FR_sigma_A
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe FR_D_lo = [GR_BASE]
+(p13) mov FR_B_hi = FR_Tmp_B
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fsub.s1 FR_B_hi = FR_B_hi,FR_sigma_B
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p14) mov FR_A_hi = FR_Tmp_A
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fsub.s1 FR_A_hi = FR_A_hi,FR_sigma_A
+ nop.i 999
+}
+;;
+
+// Note that C_hi is of integer value. We need only the
+// last few bits. Thus we can ensure C_hi is never a big
+// integer, freeing us from overflow worry.
+// Tmp_C := fadd.fpsr3( C_hi, 2^(70) ) - 2^(70);
+// Tmp_C is the upper portion of C_hi
+{ .mfi
+ nop.m 999
+ fadd.s3 FR_Tmp_C = FR_C_hi,FR_Tmp2_C
+ tbit.z p12,p9 = GR_Exp_x, 17
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fms.s1 FR_B_lo = FR_X,FR_p_2,FR_B_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s3 FR_A = FR_B_hi,FR_C_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fms.s1 FR_A_lo = FR_X,FR_p_3,FR_A_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fsub.s1 FR_Tmp_C = FR_Tmp_C,FR_Tmp2_C
+ nop.i 999
+}
+;;
+
+// *******************
+// Step 2. Get N and f
+// *******************
+// We have all the components to obtain
+// S_0, S_1, S_2, S_3 and thus N and f. We start by adding
+// C_lo and B_hi. This sum together with C_hi estimates
+// N and f well.
+// A := fadd.fpsr3( B_hi, C_lo )
+// B := max( B_hi, C_lo )
+// b := min( B_hi, C_lo )
+{ .mfi
+ nop.m 999
+ fmax.s1 FR_B = FR_B_hi,FR_C_lo
+ nop.i 999
+}
+;;
+
+// We use a right-shift trick to get the integer part of A into the rightmost
+// bits of the significand by adding 1.1000..00 * 2^63. This operation is good
+// if |A| < 2^61, which it is in this case. We are doing this to save a few
+// cycles over using fcvt.fx followed by fnorm. The second step of the trick
+// is to subtract the same constant to float the rounded integer into a fp reg.
+
+{ .mfi
+ nop.m 999
+// N := round_to_nearest_integer_value( A );
+ fma.s1 FR_N_fix = FR_A, f1, FR_RSHF
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmin.s1 FR_b = FR_B_hi,FR_C_lo
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+// C_hi := C_hi - Tmp_C ...0 <= C_hi < 2^7
+ fsub.s1 FR_C_hi = FR_C_hi,FR_Tmp_C
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+// a := (B - A) + b: Exact - note that a is either 0 or 2^(-64).
+ fsub.s1 FR_a = FR_B,FR_A
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fms.s1 FR_N = FR_N_fix, f1, FR_RSHF
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_a = FR_a,FR_b
+ nop.i 999
+}
+;;
+
+// f := A - N; Exact because lsb(A) >= 2^(-64) and |f| <= 1/2.
+// N := convert to integer format( C_hi + N );
+// M := P_0 * x_lo;
+// N := N + M;
+{ .mfi
+ nop.m 999
+ fsub.s1 FR_f = FR_A,FR_N
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_N = FR_N,FR_C_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fsub.s1 FR_D_hi = f0, FR_D_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fsub.s1 FR_D_lo = f0, FR_D_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_g = FR_A_hi,FR_B_lo // For Case 1, g=A_hi+B_lo
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s3 FR_A = FR_A_hi,FR_B_lo // For Case 2, A=A_hi+B_lo w/ sf3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ mov GR_Temp = 0x0FFCD // For Case 2, exponent of 2^-50
+ fmax.s1 FR_B = FR_A_hi,FR_B_lo // For Case 2, B=max(A_hi,B_lo)
+ nop.i 999
+}
+;;
+
+// f = f + a Exact because a is 0 or 2^(-64);
+// the msb of the sum is <= 1/2 and lsb >= 2^(-64).
+{ .mfi
+ setf.exp FR_TWOM50 = GR_Temp // For Case 2, form 2^-50
+ fcvt.fx.s1 FR_N = FR_N
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_f = FR_f,FR_a
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmin.s1 FR_b = FR_A_hi,FR_B_lo // For Case 2, b=min(A_hi,B_lo)
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fsub.s1 FR_a = FR_B,FR_A // For Case 2, a=B-A
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_s_hi = FR_f,FR_g // For Case 1, s_hi=f+g
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_f_hi = FR_A,FR_f // For Case 2, f_hi=A+f
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fabs FR_f_abs = FR_f
+ nop.i 999
+}
+;;
+
+{ .mfi
+ getf.sig GR_N = FR_N
+ fsetc.s3 0x7F,0x40 // Reset sf3 to user settings + td
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fsub.s1 FR_s_lo = FR_f,FR_s_hi // For Case 1, s_lo=f-s_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fsub.s1 FR_f_lo = FR_f,FR_f_hi // For Case 2, f_lo=f-f_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_r_hi = FR_s_hi,FR_D_hi // For Case 1, r_hi=s_hi*D_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_a = FR_a,FR_b // For Case 2, a=a+b
+ nop.i 999
+}
+;;
+
+
+// If sgn_x == 1 (that is original x was negative)
+// N := 2^10 - N
+// this maintains N to be non-negative, but still
+// equivalent to the (negated N) mod 4.
+// End If
+{ .mfi
+ add GR_N = GR_N,GR_M
+ fcmp.ge.s1 p13, p10 = FR_f_abs,FR_TWOM33
+ mov GR_Temp = 0x00400
+}
+;;
+
+{ .mfi
+(p9) sub GR_N = GR_Temp,GR_N
+ fadd.s1 FR_s_lo = FR_s_lo,FR_g // For Case 1, s_lo=s_lo+g
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_f_lo = FR_f_lo,FR_A // For Case 2, f_lo=f_lo+A
+ nop.i 999
+}
+;;
+
+// a := (B - A) + b Exact.
+// Note that a is either 0 or 2^(-128).
+// f_hi := A + f;
+// f_lo := (f - f_hi) + A
+// f_lo=f-f_hi is exact because either |f| >= |A|, in which
+// case f-f_hi is clearly exact; or otherwise, 0<|f|<|A|
+// means msb(f) <= msb(A) = 2^(-64) => |f| = 2^(-64).
+// If f = 2^(-64), f-f_hi involves cancellation and is
+// exact. If f = -2^(-64), then A + f is exact. Hence
+// f-f_hi is -A exactly, giving f_lo = 0.
+// f_lo := f_lo + a;
+
+// If |f| >= 2^(-33)
+// Case 1
+// CASE := 1
+// g := A_hi + B_lo;
+// s_hi := f + g;
+// s_lo := (f - s_hi) + g;
+// Else
+// Case 2
+// CASE := 2
+// A := fadd.fpsr3( A_hi, B_lo )
+// B := max( A_hi, B_lo )
+// b := min( A_hi, B_lo )
+
+{ .mfi
+ nop.m 999
+(p10) fcmp.ge.unc.s1 p14, p11 = FR_f_abs,FR_TWOM50
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p13) fms.s1 FR_r_lo = FR_s_hi,FR_D_hi,FR_r_hi //For Case 1, r_lo=s_hi*D_hi+r_hi
+ nop.i 999
+}
+;;
+
+// If |f| >= 2^(-50) then
+// s_hi := f_hi;
+// s_lo := f_lo;
+// Else
+// f_lo := (f_lo + A_lo) + x*p_4
+// s_hi := f_hi + f_lo
+// s_lo := (f_hi - s_hi) + f_lo
+// End If
+{ .mfi
+ nop.m 999
+(p14) mov FR_s_hi = FR_f_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fadd.s1 FR_f_lo = FR_f_lo,FR_a
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p14) mov FR_s_lo = FR_f_lo
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fadd.s1 FR_f_lo = FR_f_lo,FR_A_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p11) fma.s1 FR_f_lo = FR_X,FR_p_4,FR_f_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p13) fma.s1 FR_r_lo = FR_s_hi,FR_D_lo,FR_r_lo //For Case 1, r_lo=s_hi*D_lo+r_lo
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fadd.s1 FR_s_hi = FR_f_hi,FR_f_lo
+ nop.i 999
+}
+;;
+
+// r_hi := s_hi*D_hi
+// r_lo := s_hi*D_hi - r_hi with fma
+// r_lo := (s_hi*D_lo + r_lo) + s_lo*D_hi
+{ .mfi
+ nop.m 999
+(p10) fmpy.s1 FR_r_hi = FR_s_hi,FR_D_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fsub.s1 FR_s_lo = FR_f_hi,FR_s_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p10) fms.s1 FR_r_lo = FR_s_hi,FR_D_hi,FR_r_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fadd.s1 FR_s_lo = FR_s_lo,FR_f_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_r_lo = FR_s_hi,FR_D_lo,FR_r_lo
+ nop.i 999
+}
+;;
+
+// Return N, r_hi, r_lo
+// We do not return CASE
+{ .mfb
+ nop.m 999
+ fma.s1 FR_r_lo = FR_s_lo,FR_D_hi,FR_r_lo
+ br.ret.sptk b0
+}
+;;
+
+.endp __libm_pi_by_2_reduce#
diff --git a/libc/sysdeps/ia64/fpu/libm_scalblnf.S b/libc/sysdeps/ia64/fpu/libm_scalblnf.S
new file mode 100644
index 000000000..af620d45f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_scalblnf.S
@@ -0,0 +1,450 @@
+.file "libm_scalblnf.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/03/01 Initial version
+// 08/23/01 Corrected error tag number
+// 02/06/02 Corrected to handle 32- or 64-bit integers
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 08/25/03 Improved performance
+//
+// API
+//==============================================================
+// float __libm_scalblnf (float x, long int n, int long_int_type)
+// input floating point f8 and long int n (r33)
+// input long_int_type = 0 if long int defined as 32 bits, = 1 if 64 bits
+// output floating point f8
+//
+// Returns x* 2**n using an fma and detects overflow
+// and underflow.
+//
+//
+// Strategy:
+// Compute biased exponent of result exp_Result = N + exp_X
+// Break into ranges:
+// exp_Result > 0x1007e -> Certain overflow
+// exp_Result = 0x1007e -> Possible overflow
+// 0x0ff81 <= exp_Result < 0x1007e -> No over/underflow (main path)
+// 0x0ff81 - 23 <= exp_Result < 0x0ff81 -> Possible underflow
+// exp_Result < 0x0ff81 - 23 -> Certain underflow
+
+FR_Big = f6
+FR_NBig = f7
+FR_Floating_X = f8
+FR_Result = f8
+FR_Result2 = f9
+FR_Result3 = f10
+FR_Norm_X = f11
+FR_Two_N = f12
+
+GR_neg_ov_limit= r14
+GR_N_Biased = r15
+GR_Big = r16
+GR_NBig = r17
+GR_exp_Result = r18
+GR_pos_ov_limit= r19
+GR_Bias = r20
+GR_N_as_int = r21
+GR_signexp_X = r22
+GR_exp_X = r23
+GR_exp_mask = r24
+GR_max_exp = r25
+GR_min_exp = r26
+GR_min_den_exp = r27
+
+GR_SAVE_B0 = r32
+GR_SAVE_GP = r33
+GR_SAVE_PFS = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Tag = r38
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_scalblnf)
+
+//
+// Is x NAN, INF, ZERO, +-?
+// Build the exponent Bias
+//
+{ .mfi
+ getf.exp GR_signexp_X = FR_Floating_X // Get signexp of x
+ fclass.m p6,p0 = FR_Floating_X, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_Bias = 0x0ffff
+}
+//
+// Normalize x
+// Is long integer type 32 bits?
+//
+{ .mfi
+ mov GR_Big = 35000 // If N this big then certain overflow
+ fnorm.s1 FR_Norm_X = FR_Floating_X
+ cmp.eq p8,p9 = r34,r0
+}
+;;
+
+// Sign extend N if long int is 32 bits
+{ .mfi
+(p9) mov GR_N_as_int = r33 // Copy N if long int is 64 bits
+ fclass.m p9,p0 = FR_Floating_X, 0x0b // Test for x=unorm
+(p8) sxt4 GR_N_as_int = r33 // Sign extend N if long int is 32 bits
+}
+{ .mfi
+ mov GR_NBig = -35000 // If N this small then certain underflow
+ nop.f 0
+ mov GR_max_exp = 0x1007e // Exponent of maximum float
+}
+;;
+
+// Create biased exponent for 2**N
+{ .mfi
+ add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.ge p7, p0 = GR_N_as_int, GR_Big // Certain overflow?
+}
+{ .mib
+ cmp.le p8, p0 = GR_N_as_int, GR_NBig // Certain underflow?
+ mov GR_min_exp = 0x0ff81 // Exponent of minimum float
+(p9) br.cond.spnt SCALBNF_UNORM // Branch if x=unorm
+}
+;;
+
+SCALBNF_COMMON:
+// Main path continues. Also return here from x=unorm path.
+// Create 2**N
+.pred.rel "mutex",p7,p8
+{ .mfi
+ setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+(p7) mov GR_N_as_int = GR_Big // Limit max N
+}
+{ .mfi
+(p8) mov GR_N_as_int = GR_NBig // Limit min N
+ nop.f 0
+(p8) cmp.eq p7,p0 = r0,r0 // Set p7 if |N| big
+}
+;;
+
+//
+// Create biased exponent for 2**N for N big
+// Is N zero?
+//
+{ .mfi
+(p7) add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.eq.or p6,p0 = r33,r0
+}
+{ .mfi
+ mov GR_pos_ov_limit = 0x1007f // Exponent for positive overflow
+ nop.f 0
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+}
+;;
+
+//
+// Create 2**N for N big
+// Return x when N = 0 or X = Nan, Inf, Zero
+//
+{ .mfi
+(p7) setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+ mov GR_min_den_exp = 0x0ff81 - 23 // Exponent of min denorm float
+}
+{ .mfb
+ and GR_exp_X = GR_exp_mask, GR_signexp_X
+(p6) fma.s.s0 FR_Result = FR_Floating_X, f1, f0
+(p6) br.ret.spnt b0
+}
+;;
+
+//
+// Raise Denormal operand flag with compare
+// Compute biased result exponent
+//
+{ .mfi
+ add GR_exp_Result = GR_exp_X, GR_N_as_int
+ fcmp.ge.s0 p0,p11 = FR_Floating_X,f0
+ mov GR_neg_ov_limit = 0x3007f // Exponent for negative overflow
+}
+;;
+
+//
+// Do final operation
+//
+{ .mfi
+ cmp.lt p7,p6 = GR_exp_Result, GR_max_exp // Test no overflow
+ fma.s.s0 FR_Result = FR_Two_N,FR_Norm_X,f0
+ cmp.lt p9,p0 = GR_exp_Result, GR_min_den_exp // Test sure underflow
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p9) br.cond.spnt SCALBNF_UNDERFLOW // Branch if certain underflow
+}
+;;
+
+{ .mib
+(p6) cmp.gt.unc p6,p8 = GR_exp_Result, GR_max_exp // Test sure overflow
+(p7) cmp.ge.unc p7,p9 = GR_exp_Result, GR_min_exp // Test no over/underflow
+(p7) br.ret.sptk b0 // Return from main path
+}
+;;
+
+{ .bbb
+(p6) br.cond.spnt SCALBNF_OVERFLOW // Branch if certain overflow
+(p8) br.cond.spnt SCALBNF_POSSIBLE_OVERFLOW // Branch if possible overflow
+(p9) br.cond.spnt SCALBNF_POSSIBLE_UNDERFLOW // Branch if possible underflow
+}
+;;
+
+// Here if possible underflow.
+// Resulting exponent: 0x0ff81-23 <= exp_Result < 0x0ff81
+SCALBNF_POSSIBLE_UNDERFLOW:
+//
+// Here if possible overflow.
+// Resulting exponent: 0x1007e = exp_Result
+SCALBNF_POSSIBLE_OVERFLOW:
+
+// Set up necessary status fields
+//
+// S0 user supplied status
+// S2 user supplied status + WRE + TD (Overflows)
+// S3 user supplied status + FZ + TD (Underflows)
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x41
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x42
+ nop.i 0
+}
+;;
+
+//
+// Do final operation with s2 and s3
+//
+{ .mfi
+ setf.exp FR_NBig = GR_neg_ov_limit
+ fma.s.s3 FR_Result3 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+{ .mfi
+ setf.exp FR_Big = GR_pos_ov_limit
+ fma.s.s2 FR_Result2 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+;;
+
+// Check for overflow or underflow.
+// Restore s3
+// Restore s2
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x40
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40
+ nop.i 0
+}
+;;
+
+//
+// Is the result zero?
+//
+{ .mfi
+ nop.m 0
+ fclass.m p6, p0 = FR_Result3, 0x007
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p7, p8 = FR_Result2 , FR_Big
+ nop.i 0
+}
+;;
+
+//
+// Detect masked underflow - Tiny + Inexact Only
+//
+{ .mfi
+ nop.m 0
+(p6) fcmp.neq.unc.s1 p6, p0 = FR_Result , FR_Result2
+ nop.i 0
+}
+;;
+
+//
+// Is result bigger the allowed range?
+// Branch out for underflow
+//
+{ .mfb
+ nop.m 0
+(p8) fcmp.le.unc.s1 p9, p10 = FR_Result2 , FR_NBig
+(p6) br.cond.spnt SCALBNF_UNDERFLOW
+}
+;;
+
+//
+// Branch out for overflow
+//
+{ .bbb
+(p7) br.cond.spnt SCALBNF_OVERFLOW
+(p9) br.cond.spnt SCALBNF_OVERFLOW
+ br.ret.sptk b0 // Return from main path.
+}
+;;
+
+// Here if result overflows
+SCALBNF_OVERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 205, r0 // Set error tag for overflow
+ br.cond.sptk __libm_error_region // Call error support for overflow
+}
+;;
+
+// Here if result underflows
+SCALBNF_UNDERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 206, r0 // Set error tag for underflow
+ br.cond.sptk __libm_error_region // Call error support for underflow
+}
+;;
+
+// Here if x=unorm
+SCALBNF_UNORM:
+{ .mib
+ getf.exp GR_signexp_X = FR_Norm_X // Get signexp of normalized x
+ nop.i 0
+ br.cond.sptk SCALBNF_COMMON // Return to main path
+}
+;;
+
+
+GLOBAL_LIBM_END(__libm_scalblnf)
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+//
+// Get stack address of N
+//
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs
+}
+//
+// Adjust sp
+//
+{ .mfi
+.fframe 64
+ add sp=-64,sp
+ nop.f 0
+ mov GR_SAVE_GP=gp
+};;
+
+//
+// Store N on stack in correct position
+// Locate the address of x on stack
+//
+{ .mmi
+ st8 [GR_Parameter_Y] = GR_N_as_int,16
+ add GR_Parameter_X = 16,sp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0
+};;
+
+//
+// Store x on the stack.
+// Get address for result on stack.
+//
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_Norm_X
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_Result
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support#
+};;
+
+//
+// Get location of result on stack
+//
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+//
+// Get the new result
+//
+{ .mmi
+ ldfs FR_Result = [GR_Parameter_RESULT]
+.restore sp
+ add sp = 64,sp
+ mov b0 = GR_SAVE_B0
+};;
+
+//
+// Restore gp, ar.pfs and return
+//
+{ .mib
+ mov gp = GR_SAVE_GP
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/libm_sincos.S b/libc/sysdeps/ia64/fpu/libm_sincos.S
new file mode 100644
index 000000000..7fda2afac
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_sincos.S
@@ -0,0 +1,783 @@
+.file "libm_sincos.s"
+
+
+// Copyright (c) 2002 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/01/02 Initial version
+// 02/18/02 Large arguments processing routine is excluded.
+// External interface entry points are added
+// 03/13/02 Corrected restore of predicate registers
+// 03/19/02 Added stack unwind around call to __libm_cis_large
+// 09/05/02 Work range is widened by reduction strengthen (3 parts of Pi/16)
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 08/08/03 Improved performance
+// 02/11/04 cis is moved to the separate file.
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// 1) void sincos(double, double*s, double*c)
+// 2) __libm_sincos - internal LIBM function, that accepts
+// argument in f8 and returns cosine through f8, sine through f9
+//
+// Overview of operation
+//==============================================================
+//
+// Step 1
+// ======
+// Reduce x to region -1/2*pi/2^k ===== 0 ===== +1/2*pi/2^k where k=4
+// divide x by pi/2^k.
+// Multiply by 2^k/pi.
+// nfloat = Round result to integer (round-to-nearest)
+//
+// r = x - nfloat * pi/2^k
+// Do this as ((((x - nfloat * HIGH(pi/2^k))) -
+// nfloat * LOW(pi/2^k)) -
+// nfloat * LOWEST(pi/2^k) for increased accuracy.
+// pi/2^k is stored as two numbers that when added make pi/2^k.
+// pi/2^k = HIGH(pi/2^k) + LOW(pi/2^k)
+// HIGH and LOW parts are rounded to zero values,
+// and LOWEST is rounded to nearest one.
+//
+// x = (nfloat * pi/2^k) + r
+// r is small enough that we can use a polynomial approximation
+// and is referred to as the reduced argument.
+//
+// Step 3
+// ======
+// Take the unreduced part and remove the multiples of 2pi.
+// So nfloat = nfloat (with lower k+1 bits cleared) + lower k+1 bits
+//
+// nfloat (with lower k+1 bits cleared) is a multiple of 2^(k+1)
+// N * 2^(k+1)
+// nfloat * pi/2^k = N * 2^(k+1) * pi/2^k + (lower k+1 bits) * pi/2^k
+// nfloat * pi/2^k = N * 2 * pi + (lower k+1 bits) * pi/2^k
+// nfloat * pi/2^k = N2pi + M * pi/2^k
+//
+//
+// Sin(x) = Sin((nfloat * pi/2^k) + r)
+// = Sin(nfloat * pi/2^k) * Cos(r) + Cos(nfloat * pi/2^k) * Sin(r)
+//
+// Sin(nfloat * pi/2^k) = Sin(N2pi + Mpi/2^k)
+// = Sin(N2pi)Cos(Mpi/2^k) + Cos(N2pi)Sin(Mpi/2^k)
+// = Sin(Mpi/2^k)
+//
+// Cos(nfloat * pi/2^k) = Cos(N2pi + Mpi/2^k)
+// = Cos(N2pi)Cos(Mpi/2^k) + Sin(N2pi)Sin(Mpi/2^k)
+// = Cos(Mpi/2^k)
+//
+// Sin(x) = Sin(Mpi/2^k) Cos(r) + Cos(Mpi/2^k) Sin(r)
+//
+//
+// Step 4
+// ======
+// 0 <= M < 2^(k+1)
+// There are 2^(k+1) Sin entries in a table.
+// There are 2^(k+1) Cos entries in a table.
+//
+// Get Sin(Mpi/2^k) and Cos(Mpi/2^k) by table lookup.
+//
+//
+// Step 5
+// ======
+// Calculate Cos(r) and Sin(r) by polynomial approximation.
+//
+// Cos(r) = 1 + r^2 q1 + r^4 q2 + r^6 q3 + ... = Series for Cos
+// Sin(r) = r + r^3 p1 + r^5 p2 + r^7 p3 + ... = Series for Sin
+//
+// and the coefficients q1, q2, ... and p1, p2, ... are stored in a table
+//
+//
+// Calculate
+// Sin(x) = Sin(Mpi/2^k) Cos(r) + Cos(Mpi/2^k) Sin(r)
+//
+// as follows
+//
+// S[m] = Sin(Mpi/2^k) and C[m] = Cos(Mpi/2^k)
+// rsq = r*r
+//
+//
+// P = p1 + r^2p2 + r^4p3 + r^6p4
+// Q = q1 + r^2q2 + r^4q3 + r^6q4
+//
+// rcub = r * rsq
+// Sin(r) = r + rcub * P
+// = r + r^3p1 + r^5p2 + r^7p3 + r^9p4 + ... = Sin(r)
+//
+// The coefficients are not exactly these values, but almost.
+//
+// p1 = -1/6 = -1/3!
+// p2 = 1/120 = 1/5!
+// p3 = -1/5040 = -1/7!
+// p4 = 1/362889 = 1/9!
+//
+// P = r + rcub * P
+//
+// Answer = S[m] Cos(r) + C[m] P
+//
+// Cos(r) = 1 + rsq Q
+// Cos(r) = 1 + r^2 Q
+// Cos(r) = 1 + r^2 (q1 + r^2q2 + r^4q3 + r^6q4)
+// Cos(r) = 1 + r^2q1 + r^4q2 + r^6q3 + r^8q4 + ...
+//
+// S[m] Cos(r) = S[m](1 + rsq Q)
+// S[m] Cos(r) = S[m] + S[m] rsq Q
+// S[m] Cos(r) = S[m] + s_rsq Q
+// Q = S[m] + s_rsq Q
+//
+// Then,
+//
+// Answer = Q + C[m] P
+
+// Registers used
+//==============================================================
+// general input registers:
+// r14 -> r39
+
+// predicate registers used:
+// p6 -> p14
+//
+// floating-point registers used
+// f9 -> f15
+// f32 -> f67
+
+// Assembly macros
+//==============================================================
+
+cis_Arg = f8
+
+cis_Sin_res = f9
+cis_Cos_res = f8
+
+cis_NORM_f8 = f10
+cis_W = f11
+cis_int_Nfloat = f12
+cis_Nfloat = f13
+
+cis_r = f14
+cis_rsq = f15
+cis_rcub = f32
+
+cis_Inv_Pi_by_16 = f33
+cis_Pi_by_16_hi = f34
+cis_Pi_by_16_lo = f35
+
+cis_Inv_Pi_by_64 = f36
+cis_Pi_by_16_lowest = f37
+cis_r_exact = f38
+
+
+cis_P1 = f39
+cis_Q1 = f40
+cis_P2 = f41
+cis_Q2 = f42
+cis_P3 = f43
+cis_Q3 = f44
+cis_P4 = f45
+cis_Q4 = f46
+
+cis_P_temp1 = f47
+cis_P_temp2 = f48
+
+cis_Q_temp1 = f49
+cis_Q_temp2 = f50
+
+cis_P = f51
+
+cis_SIG_INV_PI_BY_16_2TO61 = f52
+cis_RSHF_2TO61 = f53
+cis_RSHF = f54
+cis_2TOM61 = f55
+cis_NFLOAT = f56
+cis_W_2TO61_RSH = f57
+
+cis_tmp = f58
+
+cis_Sm_sin = f59
+cis_Cm_sin = f60
+
+cis_Sm_cos = f61
+cis_Cm_cos = f62
+
+cis_srsq_sin = f63
+cis_srsq_cos = f64
+
+cis_Q_sin = f65
+cis_Q_cos = f66
+cis_Q = f67
+
+/////////////////////////////////////////////////////////////
+
+cis_pResSin = r33
+cis_pResCos = r34
+
+cis_GR_sig_inv_pi_by_16 = r14
+cis_GR_rshf_2to61 = r15
+cis_GR_rshf = r16
+cis_GR_exp_2tom61 = r17
+cis_GR_n = r18
+cis_GR_n_sin = r19
+cis_exp_limit = r20
+cis_r_signexp = r21
+cis_AD_1 = r22
+cis_r_sincos = r23
+cis_r_exp = r24
+cis_r_17_ones = r25
+cis_GR_m_sin = r26
+cis_GR_32m_sin = r26
+cis_GR_n_cos = r27
+cis_GR_m_cos = r28
+cis_GR_32m_cos = r28
+cis_AD_2_sin = r29
+cis_AD_2_cos = r30
+cis_gr_tmp = r31
+
+GR_SAVE_B0 = r35
+GR_SAVE_GP = r36
+rB0_SAVED = r37
+GR_SAVE_PFS = r38
+GR_SAVE_PR = r39
+
+RODATA
+
+.align 16
+// Pi/16 parts
+LOCAL_OBJECT_START(double_cis_pi)
+ data8 0xC90FDAA22168C234, 0x00003FFC // pi/16 1st part
+ data8 0xC4C6628B80DC1CD1, 0x00003FBC // pi/16 2nd part
+ data8 0xA4093822299F31D0, 0x00003F7A // pi/16 3rd part
+LOCAL_OBJECT_END(double_cis_pi)
+
+// Coefficients for polynomials
+LOCAL_OBJECT_START(double_cis_pq_k4)
+ data8 0x3EC71C963717C63A // P4
+ data8 0x3EF9FFBA8F191AE6 // Q4
+ data8 0xBF2A01A00F4E11A8 // P3
+ data8 0xBF56C16C05AC77BF // Q3
+ data8 0x3F8111111110F167 // P2
+ data8 0x3FA555555554DD45 // Q2
+ data8 0xBFC5555555555555 // P1
+ data8 0xBFDFFFFFFFFFFFFC // Q1
+LOCAL_OBJECT_END(double_cis_pq_k4)
+
+// Sincos table (S[m], C[m])
+LOCAL_OBJECT_START(double_sin_cos_beta_k4)
+data8 0x0000000000000000 , 0x00000000 // sin( 0 pi/16) S0
+data8 0x8000000000000000 , 0x00003fff // cos( 0 pi/16) C0
+//
+data8 0xc7c5c1e34d3055b3 , 0x00003ffc // sin( 1 pi/16) S1
+data8 0xfb14be7fbae58157 , 0x00003ffe // cos( 1 pi/16) C1
+//
+data8 0xc3ef1535754b168e , 0x00003ffd // sin( 2 pi/16) S2
+data8 0xec835e79946a3146 , 0x00003ffe // cos( 2 pi/16) C2
+//
+data8 0x8e39d9cd73464364 , 0x00003ffe // sin( 3 pi/16) S3
+data8 0xd4db3148750d181a , 0x00003ffe // cos( 3 pi/16) C3
+//
+data8 0xb504f333f9de6484 , 0x00003ffe // sin( 4 pi/16) S4
+data8 0xb504f333f9de6484 , 0x00003ffe // cos( 4 pi/16) C4
+//
+data8 0xd4db3148750d181a , 0x00003ffe // sin( 5 pi/16) C3
+data8 0x8e39d9cd73464364 , 0x00003ffe // cos( 5 pi/16) S3
+//
+data8 0xec835e79946a3146 , 0x00003ffe // sin( 6 pi/16) C2
+data8 0xc3ef1535754b168e , 0x00003ffd // cos( 6 pi/16) S2
+//
+data8 0xfb14be7fbae58157 , 0x00003ffe // sin( 7 pi/16) C1
+data8 0xc7c5c1e34d3055b3 , 0x00003ffc // cos( 7 pi/16) S1
+//
+data8 0x8000000000000000 , 0x00003fff // sin( 8 pi/16) C0
+data8 0x0000000000000000 , 0x00000000 // cos( 8 pi/16) S0
+//
+data8 0xfb14be7fbae58157 , 0x00003ffe // sin( 9 pi/16) C1
+data8 0xc7c5c1e34d3055b3 , 0x0000bffc // cos( 9 pi/16) -S1
+//
+data8 0xec835e79946a3146 , 0x00003ffe // sin(10 pi/16) C2
+data8 0xc3ef1535754b168e , 0x0000bffd // cos(10 pi/16) -S2
+//
+data8 0xd4db3148750d181a , 0x00003ffe // sin(11 pi/16) C3
+data8 0x8e39d9cd73464364 , 0x0000bffe // cos(11 pi/16) -S3
+//
+data8 0xb504f333f9de6484 , 0x00003ffe // sin(12 pi/16) S4
+data8 0xb504f333f9de6484 , 0x0000bffe // cos(12 pi/16) -S4
+//
+data8 0x8e39d9cd73464364 , 0x00003ffe // sin(13 pi/16) S3
+data8 0xd4db3148750d181a , 0x0000bffe // cos(13 pi/16) -C3
+//
+data8 0xc3ef1535754b168e , 0x00003ffd // sin(14 pi/16) S2
+data8 0xec835e79946a3146 , 0x0000bffe // cos(14 pi/16) -C2
+//
+data8 0xc7c5c1e34d3055b3 , 0x00003ffc // sin(15 pi/16) S1
+data8 0xfb14be7fbae58157 , 0x0000bffe // cos(15 pi/16) -C1
+//
+data8 0x0000000000000000 , 0x00000000 // sin(16 pi/16) S0
+data8 0x8000000000000000 , 0x0000bfff // cos(16 pi/16) -C0
+//
+data8 0xc7c5c1e34d3055b3 , 0x0000bffc // sin(17 pi/16) -S1
+data8 0xfb14be7fbae58157 , 0x0000bffe // cos(17 pi/16) -C1
+//
+data8 0xc3ef1535754b168e , 0x0000bffd // sin(18 pi/16) -S2
+data8 0xec835e79946a3146 , 0x0000bffe // cos(18 pi/16) -C2
+//
+data8 0x8e39d9cd73464364 , 0x0000bffe // sin(19 pi/16) -S3
+data8 0xd4db3148750d181a , 0x0000bffe // cos(19 pi/16) -C3
+//
+data8 0xb504f333f9de6484 , 0x0000bffe // sin(20 pi/16) -S4
+data8 0xb504f333f9de6484 , 0x0000bffe // cos(20 pi/16) -S4
+//
+data8 0xd4db3148750d181a , 0x0000bffe // sin(21 pi/16) -C3
+data8 0x8e39d9cd73464364 , 0x0000bffe // cos(21 pi/16) -S3
+//
+data8 0xec835e79946a3146 , 0x0000bffe // sin(22 pi/16) -C2
+data8 0xc3ef1535754b168e , 0x0000bffd // cos(22 pi/16) -S2
+//
+data8 0xfb14be7fbae58157 , 0x0000bffe // sin(23 pi/16) -C1
+data8 0xc7c5c1e34d3055b3 , 0x0000bffc // cos(23 pi/16) -S1
+//
+data8 0x8000000000000000 , 0x0000bfff // sin(24 pi/16) -C0
+data8 0x0000000000000000 , 0x00000000 // cos(24 pi/16) S0
+//
+data8 0xfb14be7fbae58157 , 0x0000bffe // sin(25 pi/16) -C1
+data8 0xc7c5c1e34d3055b3 , 0x00003ffc // cos(25 pi/16) S1
+//
+data8 0xec835e79946a3146 , 0x0000bffe // sin(26 pi/16) -C2
+data8 0xc3ef1535754b168e , 0x00003ffd // cos(26 pi/16) S2
+//
+data8 0xd4db3148750d181a , 0x0000bffe // sin(27 pi/16) -C3
+data8 0x8e39d9cd73464364 , 0x00003ffe // cos(27 pi/16) S3
+//
+data8 0xb504f333f9de6484 , 0x0000bffe // sin(28 pi/16) -S4
+data8 0xb504f333f9de6484 , 0x00003ffe // cos(28 pi/16) S4
+//
+data8 0x8e39d9cd73464364 , 0x0000bffe // sin(29 pi/16) -S3
+data8 0xd4db3148750d181a , 0x00003ffe // cos(29 pi/16) C3
+//
+data8 0xc3ef1535754b168e , 0x0000bffd // sin(30 pi/16) -S2
+data8 0xec835e79946a3146 , 0x00003ffe // cos(30 pi/16) C2
+//
+data8 0xc7c5c1e34d3055b3 , 0x0000bffc // sin(31 pi/16) -S1
+data8 0xfb14be7fbae58157 , 0x00003ffe // cos(31 pi/16) C1
+//
+data8 0x0000000000000000 , 0x00000000 // sin(32 pi/16) S0
+data8 0x8000000000000000 , 0x00003fff // cos(32 pi/16) C0
+LOCAL_OBJECT_END(double_sin_cos_beta_k4)
+
+.section .text
+
+GLOBAL_IEEE754_ENTRY(sincos)
+// cis_GR_sig_inv_pi_by_16 = significand of 16/pi
+{ .mlx
+ getf.exp cis_r_signexp = cis_Arg
+ movl cis_GR_sig_inv_pi_by_16 = 0xA2F9836E4E44152A
+
+}
+// cis_GR_rshf_2to61 = 1.1000 2^(63+63-2)
+{ .mlx
+ addl cis_AD_1 = @ltoff(double_cis_pi), gp
+ movl cis_GR_rshf_2to61 = 0x47b8000000000000
+};;
+
+{ .mfi
+ ld8 cis_AD_1 = [cis_AD_1]
+ fnorm.s1 cis_NORM_f8 = cis_Arg
+ cmp.eq p13, p14 = r0, r0 // p13 set for sincos
+}
+// cis_GR_exp_2tom61 = exponent of scaling factor 2^-61
+{ .mib
+ mov cis_GR_exp_2tom61 = 0xffff-61
+ nop.i 0
+ br.cond.sptk _CIS_COMMON
+};;
+GLOBAL_IEEE754_END(sincos)
+
+GLOBAL_LIBM_ENTRY(__libm_sincos)
+// cis_GR_sig_inv_pi_by_16 = significand of 16/pi
+{ .mlx
+ getf.exp cis_r_signexp = cis_Arg
+ movl cis_GR_sig_inv_pi_by_16 = 0xA2F9836E4E44152A
+}
+// cis_GR_rshf_2to61 = 1.1000 2^(63+63-2)
+{ .mlx
+ addl cis_AD_1 = @ltoff(double_cis_pi), gp
+ movl cis_GR_rshf_2to61 = 0x47b8000000000000
+};;
+
+// p14 set for __libm_sincos and cis
+{ .mfi
+ ld8 cis_AD_1 = [cis_AD_1]
+ fnorm.s1 cis_NORM_f8 = cis_Arg
+ cmp.eq p14, p13 = r0, r0
+}
+// cis_GR_exp_2tom61 = exponent of scaling factor 2^-61
+{ .mib
+ mov cis_GR_exp_2tom61 = 0xffff-61
+ nop.i 0
+ nop.b 0
+};;
+
+_CIS_COMMON:
+// Form two constants we need
+// 16/pi * 2^-2 * 2^63, scaled by 2^61 since we just loaded the significand
+// 1.1000...000 * 2^(63+63-2) to right shift int(W) into the low significand
+// fcmp used to set denormal, and invalid on snans
+{ .mfi
+ setf.sig cis_SIG_INV_PI_BY_16_2TO61 = cis_GR_sig_inv_pi_by_16
+ fclass.m p6,p0 = cis_Arg, 0xe7 // if x=0,inf,nan
+ addl cis_gr_tmp = -1, r0
+}
+// 1.1000 2^63 for right shift
+{ .mlx
+ setf.d cis_RSHF_2TO61 = cis_GR_rshf_2to61
+ movl cis_GR_rshf = 0x43e8000000000000
+};;
+
+// Form another constant
+// 2^-61 for scaling Nfloat
+// 0x1001a is register_bias + 27.
+// So if f8 >= 2^27, go to large arguments routine
+{ .mfi
+ alloc GR_SAVE_PFS = ar.pfs, 3, 5, 0, 0
+ fclass.m p11,p0 = cis_Arg, 0x0b // Test for x=unorm
+ mov cis_exp_limit = 0x1001a
+}
+{ .mib
+ setf.exp cis_2TOM61 = cis_GR_exp_2tom61
+ nop.i 0
+(p6) br.cond.spnt _CIS_SPECIAL_ARGS
+};;
+
+// Load the two pieces of pi/16
+// Form another constant
+// 1.1000...000 * 2^63, the right shift constant
+{ .mmb
+ ldfe cis_Pi_by_16_hi = [cis_AD_1],16
+ setf.d cis_RSHF = cis_GR_rshf
+(p11) br.cond.spnt _CIS_UNORM // Branch if x=unorm
+};;
+
+_CIS_COMMON2:
+// Return here if x=unorm
+// Create constant inexact set
+{ .mmi
+ ldfe cis_Pi_by_16_lo = [cis_AD_1],16
+ setf.sig cis_tmp = cis_gr_tmp
+ nop.i 0
+};;
+
+// Select exponent (17 lsb)
+{ .mfi
+ ldfe cis_Pi_by_16_lowest = [cis_AD_1],16
+ nop.f 0
+ dep.z cis_r_exp = cis_r_signexp, 0, 17
+};;
+
+// Start loading P, Q coefficients
+// p10 is true if we must call routines to handle larger arguments
+// p10 is true if f8 exp is > 0x1001a
+{ .mmb
+ ldfpd cis_P4,cis_Q4 = [cis_AD_1],16
+ cmp.ge p10, p0 = cis_r_exp, cis_exp_limit
+(p10) br.cond.spnt _CIS_LARGE_ARGS // go to |x| >= 2^27 path
+};;
+
+// cis_W = x * cis_Inv_Pi_by_16
+// Multiply x by scaled 16/pi and add large const to shift integer part of W to
+// rightmost bits of significand
+{ .mfi
+ ldfpd cis_P3,cis_Q3 = [cis_AD_1],16
+ fma.s1 cis_W_2TO61_RSH = cis_NORM_f8,cis_SIG_INV_PI_BY_16_2TO61,cis_RSHF_2TO61
+ nop.i 0
+};;
+
+// get N = (int)cis_int_Nfloat
+// cis_NFLOAT = Round_Int_Nearest(cis_W)
+{ .mmf
+ getf.sig cis_GR_n = cis_W_2TO61_RSH
+ ldfpd cis_P2,cis_Q2 = [cis_AD_1],16
+ fms.s1 cis_NFLOAT = cis_W_2TO61_RSH,cis_2TOM61,cis_RSHF
+};;
+
+// cis_r = -cis_Nfloat * cis_Pi_by_16_hi + x
+{ .mfi
+ ldfpd cis_P1,cis_Q1 = [cis_AD_1], 16
+ fnma.s1 cis_r = cis_NFLOAT,cis_Pi_by_16_hi,cis_NORM_f8
+ nop.i 0
+};;
+
+// Add 2^(k-1) (which is in cis_r_sincos) to N
+{ .mmi
+ add cis_GR_n_cos = 0x8, cis_GR_n
+;;
+//Get M (least k+1 bits of N)
+ and cis_GR_m_sin = 0x1f,cis_GR_n
+ and cis_GR_m_cos = 0x1f,cis_GR_n_cos
+};;
+
+{ .mmi
+ nop.m 0
+ nop.m 0
+ shl cis_GR_32m_sin = cis_GR_m_sin,5
+};;
+
+// Add 32*M to address of sin_cos_beta table
+// cis_r = cis_r -cis_Nfloat * cis_Pi_by_16_lo
+{ .mfi
+ add cis_AD_2_sin = cis_GR_32m_sin, cis_AD_1
+ fnma.s1 cis_r = cis_NFLOAT, cis_Pi_by_16_lo, cis_r
+ shl cis_GR_32m_cos = cis_GR_m_cos,5
+};;
+
+// Add 32*M to address of sin_cos_beta table
+{ .mmf
+ ldfe cis_Sm_sin = [cis_AD_2_sin],16
+ add cis_AD_2_cos = cis_GR_32m_cos, cis_AD_1
+ fclass.m.unc p10,p0 = cis_Arg,0x0b // den. input - uflow
+};;
+
+{ .mfi
+ ldfe cis_Sm_cos = [cis_AD_2_cos], 16
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe cis_Cm_sin = [cis_AD_2_sin]
+ fma.s1 cis_rsq = cis_r, cis_r, f0 // get r^2
+ nop.i 0
+}
+// fmpy forces inexact flag
+{ .mfi
+ nop.m 0
+ fmpy.s0 cis_tmp = cis_tmp,cis_tmp
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 cis_r_exact = cis_NFLOAT, cis_Pi_by_16_lowest, cis_r
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe cis_Cm_cos = [cis_AD_2_cos]
+ fma.s1 cis_P_temp1 = cis_rsq, cis_P4, cis_P3
+ nop.i 0
+}
+
+{ .mfi
+ nop.m 0
+ fma.s1 cis_Q_temp1 = cis_rsq, cis_Q4, cis_Q3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 cis_srsq_sin = cis_Sm_sin, cis_rsq
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 cis_srsq_cos = cis_Sm_cos,cis_rsq
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 cis_Q_temp2 = cis_rsq, cis_Q_temp1, cis_Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 cis_P_temp2 = cis_rsq, cis_P_temp1, cis_P2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 cis_rcub = cis_r_exact, cis_rsq // get r^3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 cis_Q = cis_rsq, cis_Q_temp2, cis_Q1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 cis_P = cis_rsq, cis_P_temp2, cis_P1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 cis_Q_sin = cis_srsq_sin,cis_Q, cis_Sm_sin
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 cis_Q_cos = cis_srsq_cos,cis_Q, cis_Sm_cos
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 cis_P = cis_rcub,cis_P, cis_r_exact // final P
+ nop.i 0
+};;
+
+// If den. arg, force underflow to be set
+{ .mfi
+ nop.m 0
+(p10) fmpy.d.s0 cis_tmp = cis_Arg,cis_Arg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.d.s0 cis_Sin_res = cis_Cm_sin,cis_P,cis_Q_sin//Final sin
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.d.s0 cis_Cos_res = cis_Cm_cos,cis_P,cis_Q_cos//Final cos
+(p14) br.ret.sptk b0 // common exit for __libm_sincos and cis main path
+};;
+
+{ .mmb
+ stfd [cis_pResSin] = cis_Sin_res
+ stfd [cis_pResCos] = cis_Cos_res
+ br.ret.sptk b0 // common exit for sincos main path
+};;
+
+_CIS_SPECIAL_ARGS:
+// sin(+/-0) = +/-0
+// sin(Inf) = NaN
+// sin(NaN) = NaN
+{ .mfi
+ nop.m 999
+ fma.d.s0 cis_Sin_res = cis_Arg, f0, f0 // sinf(+/-0,NaN,Inf)
+ nop.i 999
+};;
+// cos(+/-0) = 1.0
+// cos(Inf) = NaN
+// cos(NaN) = NaN
+{ .mfb
+ nop.m 999
+ fma.d.s0 cis_Cos_res = cis_Arg, f0, f1 // cosf(+/-0,NaN,Inf)
+(p14) br.ret.sptk b0 //spec exit for __libm_sincos and cis main path
+};;
+
+{ .mmb
+ stfd [cis_pResSin] = cis_Sin_res
+ stfd [cis_pResCos] = cis_Cos_res
+ br.ret.sptk b0 // common exit for sincos main path
+};;
+
+_CIS_UNORM:
+// Here if x=unorm
+{ .mfb
+ getf.exp cis_r_signexp = cis_NORM_f8 // Get signexp of x
+ fcmp.eq.s0 p11,p0 = cis_Arg, f0 // Dummy op to set denorm
+ br.cond.sptk _CIS_COMMON2 // Return to main path
+};;
+
+GLOBAL_LIBM_END(__libm_sincos)
+
+//// |x| > 2^27 path ///////
+.proc _CIS_LARGE_ARGS
+_CIS_LARGE_ARGS:
+.prologue
+{ .mfi
+ nop.m 0
+ nop.f 0
+.save ar.pfs, GR_SAVE_PFS
+ mov GR_SAVE_PFS = ar.pfs
+}
+;;
+
+{ .mfi
+ mov GR_SAVE_GP = gp
+ nop.f 0
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0 = b0
+};;
+
+.body
+// Call of huge arguments sincos
+{ .mib
+ nop.m 0
+ mov GR_SAVE_PR = pr
+ br.call.sptk b0 = __libm_sincos_large
+};;
+
+{ .mfi
+ mov gp = GR_SAVE_GP
+ nop.f 0
+ mov pr = GR_SAVE_PR, 0x1fffe
+}
+;;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ mov b0 = GR_SAVE_B0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.d.s0 cis_Cos_res = cis_Cos_res, f1, f0
+ mov ar.pfs = GR_SAVE_PFS
+}
+{ .mfb
+ nop.m 0
+ fma.d.s0 cis_Sin_res = cis_Sin_res, f1, f0
+(p14) br.ret.sptk b0 // exit for |x| > 2^27 path (__libm_sincos and cis)
+};;
+
+{ .mmb
+ stfd [cis_pResSin] = cis_Sin_res
+ stfd [cis_pResCos] = cis_Cos_res
+ br.ret.sptk b0 // exit for sincos |x| > 2^27 path
+};;
+.endp _CIS_LARGE_ARGS
+
+.type __libm_sincos_large#,@function
+.global __libm_sincos_large#
+
diff --git a/libc/sysdeps/ia64/fpu/libm_sincos_large.S b/libc/sysdeps/ia64/fpu/libm_sincos_large.S
new file mode 100644
index 000000000..b09d3693a
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_sincos_large.S
@@ -0,0 +1,2757 @@
+.file "libm_sincos_large.s"
+
+
+// Copyright (c) 2002 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/15/02 Initial version
+// 05/13/02 Changed interface to __libm_pi_by_2_reduce
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+// 05/15/03 Reformatted data tables
+//
+//
+// Overview of operation
+//==============================================================
+//
+// These functions calculate the sin and cos for inputs
+// greater than 2^10
+//
+// __libm_sin_large#
+// __libm_cos_large#
+// They accept argument in f8
+// and return result in f8 without final rounding
+//
+// __libm_sincos_large#
+// It accepts argument in f8
+// and returns cos in f8 and sin in f9 without final rounding
+//
+//
+//*********************************************************************
+//
+// Accuracy: Within .7 ulps for 80-bit floating point values
+// Very accurate for double precision values
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 as Input Value, f8 and f9 as Return Values
+// f32-f103
+//
+// General Purpose Registers:
+// r32-r43
+// r44-r45 (Used to pass arguments to pi_by_2 reduce routine)
+//
+// Predicate Registers: p6-p13
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// Denormal fault raised on denormal inputs
+// Overflow exceptions do not occur
+// Underflow exceptions raised when appropriate for sin
+// (No specialized error handling for this routine)
+// Inexact raised when appropriate by algorithm
+//
+// sin(SNaN) = QNaN
+// sin(QNaN) = QNaN
+// sin(inf) = QNaN
+// sin(+/-0) = +/-0
+// cos(inf) = QNaN
+// cos(SNaN) = QNaN
+// cos(QNaN) = QNaN
+// cos(0) = 1
+//
+//*********************************************************************
+//
+// Mathematical Description
+// ========================
+//
+// The computation of FSIN and FCOS is best handled in one piece of
+// code. The main reason is that given any argument Arg, computation
+// of trigonometric functions first calculate N and an approximation
+// to alpha where
+//
+// Arg = N pi/2 + alpha, |alpha| <= pi/4.
+//
+// Since
+//
+// cos( Arg ) = sin( (N+1) pi/2 + alpha ),
+//
+// therefore, the code for computing sine will produce cosine as long
+// as 1 is added to N immediately after the argument reduction
+// process.
+//
+// Let M = N if sine
+// N+1 if cosine.
+//
+// Now, given
+//
+// Arg = M pi/2 + alpha, |alpha| <= pi/4,
+//
+// let I = M mod 4, or I be the two lsb of M when M is represented
+// as 2's complement. I = [i_0 i_1]. Then
+//
+// sin( Arg ) = (-1)^i_0 sin( alpha ) if i_1 = 0,
+// = (-1)^i_0 cos( alpha ) if i_1 = 1.
+//
+// For example:
+// if M = -1, I = 11
+// sin ((-pi/2 + alpha) = (-1) cos (alpha)
+// if M = 0, I = 00
+// sin (alpha) = sin (alpha)
+// if M = 1, I = 01
+// sin (pi/2 + alpha) = cos (alpha)
+// if M = 2, I = 10
+// sin (pi + alpha) = (-1) sin (alpha)
+// if M = 3, I = 11
+// sin ((3/2)pi + alpha) = (-1) cos (alpha)
+//
+// The value of alpha is obtained by argument reduction and
+// represented by two working precision numbers r and c where
+//
+// alpha = r + c accurately.
+//
+// The reduction method is described in a previous write up.
+// The argument reduction scheme identifies 4 cases. For Cases 2
+// and 4, because |alpha| is small, sin(r+c) and cos(r+c) can be
+// computed very easily by 2 or 3 terms of the Taylor series
+// expansion as follows:
+//
+// Case 2:
+// -------
+//
+// sin(r + c) = r + c - r^3/6 accurately
+// cos(r + c) = 1 - 2^(-67) accurately
+//
+// Case 4:
+// -------
+//
+// sin(r + c) = r + c - r^3/6 + r^5/120 accurately
+// cos(r + c) = 1 - r^2/2 + r^4/24 accurately
+//
+// The only cases left are Cases 1 and 3 of the argument reduction
+// procedure. These two cases will be merged since after the
+// argument is reduced in either cases, we have the reduced argument
+// represented as r + c and that the magnitude |r + c| is not small
+// enough to allow the usage of a very short approximation.
+//
+// The required calculation is either
+//
+// sin(r + c) = sin(r) + correction, or
+// cos(r + c) = cos(r) + correction.
+//
+// Specifically,
+//
+// sin(r + c) = sin(r) + c sin'(r) + O(c^2)
+// = sin(r) + c cos (r) + O(c^2)
+// = sin(r) + c(1 - r^2/2) accurately.
+// Similarly,
+//
+// cos(r + c) = cos(r) - c sin(r) + O(c^2)
+// = cos(r) - c(r - r^3/6) accurately.
+//
+// We therefore concentrate on accurately calculating sin(r) and
+// cos(r) for a working-precision number r, |r| <= pi/4 to within
+// 0.1% or so.
+//
+// The greatest challenge of this task is that the second terms of
+// the Taylor series
+//
+// r - r^3/3! + r^r/5! - ...
+//
+// and
+//
+// 1 - r^2/2! + r^4/4! - ...
+//
+// are not very small when |r| is close to pi/4 and the rounding
+// errors will be a concern if simple polynomial accumulation is
+// used. When |r| < 2^-3, however, the second terms will be small
+// enough (6 bits or so of right shift) that a normal Horner
+// recurrence suffices. Hence there are two cases that we consider
+// in the accurate computation of sin(r) and cos(r), |r| <= pi/4.
+//
+// Case small_r: |r| < 2^(-3)
+// --------------------------
+//
+// Since Arg = M pi/4 + r + c accurately, and M mod 4 is [i_0 i_1],
+// we have
+//
+// sin(Arg) = (-1)^i_0 * sin(r + c) if i_1 = 0
+// = (-1)^i_0 * cos(r + c) if i_1 = 1
+//
+// can be accurately approximated by
+//
+// sin(Arg) = (-1)^i_0 * [sin(r) + c] if i_1 = 0
+// = (-1)^i_0 * [cos(r) - c*r] if i_1 = 1
+//
+// because |r| is small and thus the second terms in the correction
+// are unneccessary.
+//
+// Finally, sin(r) and cos(r) are approximated by polynomials of
+// moderate lengths.
+//
+// sin(r) = r + S_1 r^3 + S_2 r^5 + ... + S_5 r^11
+// cos(r) = 1 + C_1 r^2 + C_2 r^4 + ... + C_5 r^10
+//
+// We can make use of predicates to selectively calculate
+// sin(r) or cos(r) based on i_1.
+//
+// Case normal_r: 2^(-3) <= |r| <= pi/4
+// ------------------------------------
+//
+// This case is more likely than the previous one if one considers
+// r to be uniformly distributed in [-pi/4 pi/4]. Again,
+//
+// sin(Arg) = (-1)^i_0 * sin(r + c) if i_1 = 0
+// = (-1)^i_0 * cos(r + c) if i_1 = 1.
+//
+// Because |r| is now larger, we need one extra term in the
+// correction. sin(Arg) can be accurately approximated by
+//
+// sin(Arg) = (-1)^i_0 * [sin(r) + c(1-r^2/2)] if i_1 = 0
+// = (-1)^i_0 * [cos(r) - c*r*(1 - r^2/6)] i_1 = 1.
+//
+// Finally, sin(r) and cos(r) are approximated by polynomials of
+// moderate lengths.
+//
+// sin(r) = r + PP_1_hi r^3 + PP_1_lo r^3 +
+// PP_2 r^5 + ... + PP_8 r^17
+//
+// cos(r) = 1 + QQ_1 r^2 + QQ_2 r^4 + ... + QQ_8 r^16
+//
+// where PP_1_hi is only about 16 bits long and QQ_1 is -1/2.
+// The crux in accurate computation is to calculate
+//
+// r + PP_1_hi r^3 or 1 + QQ_1 r^2
+//
+// accurately as two pieces: U_hi and U_lo. The way to achieve this
+// is to obtain r_hi as a 10 sig. bit number that approximates r to
+// roughly 8 bits or so of accuracy. (One convenient way is
+//
+// r_hi := frcpa( frcpa( r ) ).)
+//
+// This way,
+//
+// r + PP_1_hi r^3 = r + PP_1_hi r_hi^3 +
+// PP_1_hi (r^3 - r_hi^3)
+// = [r + PP_1_hi r_hi^3] +
+// [PP_1_hi (r - r_hi)
+// (r^2 + r_hi r + r_hi^2) ]
+// = U_hi + U_lo
+//
+// Since r_hi is only 10 bit long and PP_1_hi is only 16 bit long,
+// PP_1_hi * r_hi^3 is only at most 46 bit long and thus computed
+// exactly. Furthermore, r and PP_1_hi r_hi^3 are of opposite sign
+// and that there is no more than 8 bit shift off between r and
+// PP_1_hi * r_hi^3. Hence the sum, U_hi, is representable and thus
+// calculated without any error. Finally, the fact that
+//
+// |U_lo| <= 2^(-8) |U_hi|
+//
+// says that U_hi + U_lo is approximating r + PP_1_hi r^3 to roughly
+// 8 extra bits of accuracy.
+//
+// Similarly,
+//
+// 1 + QQ_1 r^2 = [1 + QQ_1 r_hi^2] +
+// [QQ_1 (r - r_hi)(r + r_hi)]
+// = U_hi + U_lo.
+//
+// Summarizing, we calculate r_hi = frcpa( frcpa( r ) ).
+//
+// If i_1 = 0, then
+//
+// U_hi := r + PP_1_hi * r_hi^3
+// U_lo := PP_1_hi * (r - r_hi) * (r^2 + r*r_hi + r_hi^2)
+// poly := PP_1_lo r^3 + PP_2 r^5 + ... + PP_8 r^17
+// correction := c * ( 1 + C_1 r^2 )
+//
+// Else ...i_1 = 1
+//
+// U_hi := 1 + QQ_1 * r_hi * r_hi
+// U_lo := QQ_1 * (r - r_hi) * (r + r_hi)
+// poly := QQ_2 * r^4 + QQ_3 * r^6 + ... + QQ_8 r^16
+// correction := -c * r * (1 + S_1 * r^2)
+//
+// End
+//
+// Finally,
+//
+// V := poly + ( U_lo + correction )
+//
+// / U_hi + V if i_0 = 0
+// result := |
+// \ (-U_hi) - V if i_0 = 1
+//
+// It is important that in the last step, negation of U_hi is
+// performed prior to the subtraction which is to be performed in
+// the user-set rounding mode.
+//
+//
+// Algorithmic Description
+// =======================
+//
+// The argument reduction algorithm is tightly integrated into FSIN
+// and FCOS which share the same code. The following is complete and
+// self-contained. The argument reduction description given
+// previously is repeated below.
+//
+//
+// Step 0. Initialization.
+//
+// If FSIN is invoked, set N_inc := 0; else if FCOS is invoked,
+// set N_inc := 1.
+//
+// Step 1. Check for exceptional and special cases.
+//
+// * If Arg is +-0, +-inf, NaN, NaT, go to Step 10 for special
+// handling.
+// * If |Arg| < 2^24, go to Step 2 for reduction of moderate
+// arguments. This is the most likely case.
+// * If |Arg| < 2^63, go to Step 8 for pre-reduction of large
+// arguments.
+// * If |Arg| >= 2^63, go to Step 10 for special handling.
+//
+// Step 2. Reduction of moderate arguments.
+//
+// If |Arg| < pi/4 ...quick branch
+// N_fix := N_inc (integer)
+// r := Arg
+// c := 0.0
+// Branch to Step 4, Case_1_complete
+// Else ...cf. argument reduction
+// N := Arg * two_by_PI (fp)
+// N_fix := fcvt.fx( N ) (int)
+// N := fcvt.xf( N_fix )
+// N_fix := N_fix + N_inc
+// s := Arg - N * P_1 (first piece of pi/2)
+// w := -N * P_2 (second piece of pi/2)
+//
+// If |s| >= 2^(-33)
+// go to Step 3, Case_1_reduce
+// Else
+// go to Step 7, Case_2_reduce
+// Endif
+// Endif
+//
+// Step 3. Case_1_reduce.
+//
+// r := s + w
+// c := (s - r) + w ...observe order
+//
+// Step 4. Case_1_complete
+//
+// ...At this point, the reduced argument alpha is
+// ...accurately represented as r + c.
+// If |r| < 2^(-3), go to Step 6, small_r.
+//
+// Step 5. Normal_r.
+//
+// Let [i_0 i_1] by the 2 lsb of N_fix.
+// FR_rsq := r * r
+// r_hi := frcpa( frcpa( r ) )
+// r_lo := r - r_hi
+//
+// If i_1 = 0, then
+// poly := r*FR_rsq*(PP_1_lo + FR_rsq*(PP_2 + ... FR_rsq*PP_8))
+// U_hi := r + PP_1_hi*r_hi*r_hi*r_hi ...any order
+// U_lo := PP_1_hi*r_lo*(r*r + r*r_hi + r_hi*r_hi)
+// correction := c + c*C_1*FR_rsq ...any order
+// Else
+// poly := FR_rsq*FR_rsq*(QQ_2 + FR_rsq*(QQ_3 + ... + FR_rsq*QQ_8))
+// U_hi := 1 + QQ_1 * r_hi * r_hi ...any order
+// U_lo := QQ_1 * r_lo * (r + r_hi)
+// correction := -c*(r + S_1*FR_rsq*r) ...any order
+// Endif
+//
+// V := poly + (U_lo + correction) ...observe order
+//
+// result := (i_0 == 0? 1.0 : -1.0)
+//
+// Last instruction in user-set rounding mode
+//
+// result := (i_0 == 0? result*U_hi + V :
+// result*U_hi - V)
+//
+// Return
+//
+// Step 6. Small_r.
+//
+// ...Use flush to zero mode without causing exception
+// Let [i_0 i_1] be the two lsb of N_fix.
+//
+// FR_rsq := r * r
+//
+// If i_1 = 0 then
+// z := FR_rsq*FR_rsq; z := FR_rsq*z *r
+// poly_lo := S_3 + FR_rsq*(S_4 + FR_rsq*S_5)
+// poly_hi := r*FR_rsq*(S_1 + FR_rsq*S_2)
+// correction := c
+// result := r
+// Else
+// z := FR_rsq*FR_rsq; z := FR_rsq*z
+// poly_lo := C_3 + FR_rsq*(C_4 + FR_rsq*C_5)
+// poly_hi := FR_rsq*(C_1 + FR_rsq*C_2)
+// correction := -c*r
+// result := 1
+// Endif
+//
+// poly := poly_hi + (z * poly_lo + correction)
+//
+// If i_0 = 1, result := -result
+//
+// Last operation. Perform in user-set rounding mode
+//
+// result := (i_0 == 0? result + poly :
+// result - poly )
+// Return
+//
+// Step 7. Case_2_reduce.
+//
+// ...Refer to the write up for argument reduction for
+// ...rationale. The reduction algorithm below is taken from
+// ...argument reduction description and integrated this.
+//
+// w := N*P_3
+// U_1 := N*P_2 + w ...FMA
+// U_2 := (N*P_2 - U_1) + w ...2 FMA
+// ...U_1 + U_2 is N*(P_2+P_3) accurately
+//
+// r := s - U_1
+// c := ( (s - r) - U_1 ) - U_2
+//
+// ...The mathematical sum r + c approximates the reduced
+// ...argument accurately. Note that although compared to
+// ...Case 1, this case requires much more work to reduce
+// ...the argument, the subsequent calculation needed for
+// ...any of the trigonometric function is very little because
+// ...|alpha| < 1.01*2^(-33) and thus two terms of the
+// ...Taylor series expansion suffices.
+//
+// If i_1 = 0 then
+// poly := c + S_1 * r * r * r ...any order
+// result := r
+// Else
+// poly := -2^(-67)
+// result := 1.0
+// Endif
+//
+// If i_0 = 1, result := -result
+//
+// Last operation. Perform in user-set rounding mode
+//
+// result := (i_0 == 0? result + poly :
+// result - poly )
+//
+// Return
+//
+//
+// Step 8. Pre-reduction of large arguments.
+//
+// ...Again, the following reduction procedure was described
+// ...in the separate write up for argument reduction, which
+// ...is tightly integrated here.
+
+// N_0 := Arg * Inv_P_0
+// N_0_fix := fcvt.fx( N_0 )
+// N_0 := fcvt.xf( N_0_fix)
+
+// Arg' := Arg - N_0 * P_0
+// w := N_0 * d_1
+// N := Arg' * two_by_PI
+// N_fix := fcvt.fx( N )
+// N := fcvt.xf( N_fix )
+// N_fix := N_fix + N_inc
+//
+// s := Arg' - N * P_1
+// w := w - N * P_2
+//
+// If |s| >= 2^(-14)
+// go to Step 3
+// Else
+// go to Step 9
+// Endif
+//
+// Step 9. Case_4_reduce.
+//
+// ...first obtain N_0*d_1 and -N*P_2 accurately
+// U_hi := N_0 * d_1 V_hi := -N*P_2
+// U_lo := N_0 * d_1 - U_hi V_lo := -N*P_2 - U_hi ...FMAs
+//
+// ...compute the contribution from N_0*d_1 and -N*P_3
+// w := -N*P_3
+// w := w + N_0*d_2
+// t := U_lo + V_lo + w ...any order
+//
+// ...at this point, the mathematical value
+// ...s + U_hi + V_hi + t approximates the true reduced argument
+// ...accurately. Just need to compute this accurately.
+//
+// ...Calculate U_hi + V_hi accurately:
+// A := U_hi + V_hi
+// if |U_hi| >= |V_hi| then
+// a := (U_hi - A) + V_hi
+// else
+// a := (V_hi - A) + U_hi
+// endif
+// ...order in computing "a" must be observed. This branch is
+// ...best implemented by predicates.
+// ...A + a is U_hi + V_hi accurately. Moreover, "a" is
+// ...much smaller than A: |a| <= (1/2)ulp(A).
+//
+// ...Just need to calculate s + A + a + t
+// C_hi := s + A t := t + a
+// C_lo := (s - C_hi) + A
+// C_lo := C_lo + t
+//
+// ...Final steps for reduction
+// r := C_hi + C_lo
+// c := (C_hi - r) + C_lo
+//
+// ...At this point, we have r and c
+// ...And all we need is a couple of terms of the corresponding
+// ...Taylor series.
+//
+// If i_1 = 0
+// poly := c + r*FR_rsq*(S_1 + FR_rsq*S_2)
+// result := r
+// Else
+// poly := FR_rsq*(C_1 + FR_rsq*C_2)
+// result := 1
+// Endif
+//
+// If i_0 = 1, result := -result
+//
+// Last operation. Perform in user-set rounding mode
+//
+// result := (i_0 == 0? result + poly :
+// result - poly )
+// Return
+//
+// Large Arguments: For arguments above 2**63, a Payne-Hanek
+// style argument reduction is used and pi_by_2 reduce is called.
+//
+
+
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(FSINCOS_CONSTANTS)
+
+data4 0x4B800000 // two**24
+data4 0xCB800000 // -two**24
+data4 0x00000000 // pad
+data4 0x00000000 // pad
+data8 0xA2F9836E4E44152A, 0x00003FFE // Inv_pi_by_2
+data8 0xC84D32B0CE81B9F1, 0x00004016 // P_0
+data8 0xC90FDAA22168C235, 0x00003FFF // P_1
+data8 0xECE675D1FC8F8CBB, 0x0000BFBD // P_2
+data8 0xB7ED8FBBACC19C60, 0x0000BF7C // P_3
+data4 0x5F000000 // two**63
+data4 0xDF000000 // -two**63
+data4 0x00000000 // pad
+data4 0x00000000 // pad
+data8 0xA397E5046EC6B45A, 0x00003FE7 // Inv_P_0
+data8 0x8D848E89DBD171A1, 0x0000BFBF // d_1
+data8 0xD5394C3618A66F8E, 0x0000BF7C // d_2
+data8 0xC90FDAA22168C234, 0x00003FFE // pi_by_4
+data8 0xC90FDAA22168C234, 0x0000BFFE // neg_pi_by_4
+data4 0x3E000000 // two**-3
+data4 0xBE000000 // -two**-3
+data4 0x00000000 // pad
+data4 0x00000000 // pad
+data4 0x2F000000 // two**-33
+data4 0xAF000000 // -two**-33
+data4 0x9E000000 // -two**-67
+data4 0x00000000 // pad
+data8 0xCC8ABEBCA21C0BC9, 0x00003FCE // PP_8
+data8 0xD7468A05720221DA, 0x0000BFD6 // PP_7
+data8 0xB092382F640AD517, 0x00003FDE // PP_6
+data8 0xD7322B47D1EB75A4, 0x0000BFE5 // PP_5
+data8 0xFFFFFFFFFFFFFFFE, 0x0000BFFD // C_1
+data8 0xAAAA000000000000, 0x0000BFFC // PP_1_hi
+data8 0xB8EF1D2ABAF69EEA, 0x00003FEC // PP_4
+data8 0xD00D00D00D03BB69, 0x0000BFF2 // PP_3
+data8 0x8888888888888962, 0x00003FF8 // PP_2
+data8 0xAAAAAAAAAAAB0000, 0x0000BFEC // PP_1_lo
+data8 0xD56232EFC2B0FE52, 0x00003FD2 // QQ_8
+data8 0xC9C99ABA2B48DCA6, 0x0000BFDA // QQ_7
+data8 0x8F76C6509C716658, 0x00003FE2 // QQ_6
+data8 0x93F27DBAFDA8D0FC, 0x0000BFE9 // QQ_5
+data8 0xAAAAAAAAAAAAAAAA, 0x0000BFFC // S_1
+data8 0x8000000000000000, 0x0000BFFE // QQ_1
+data8 0xD00D00D00C6E5041, 0x00003FEF // QQ_4
+data8 0xB60B60B60B607F60, 0x0000BFF5 // QQ_3
+data8 0xAAAAAAAAAAAAAA9B, 0x00003FFA // QQ_2
+data8 0xFFFFFFFFFFFFFFFE, 0x0000BFFD // C_1
+data8 0xAAAAAAAAAAAA719F, 0x00003FFA // C_2
+data8 0xB60B60B60356F994, 0x0000BFF5 // C_3
+data8 0xD00CFFD5B2385EA9, 0x00003FEF // C_4
+data8 0x93E4BD18292A14CD, 0x0000BFE9 // C_5
+data8 0xAAAAAAAAAAAAAAAA, 0x0000BFFC // S_1
+data8 0x88888888888868DB, 0x00003FF8 // S_2
+data8 0xD00D00D0055EFD4B, 0x0000BFF2 // S_3
+data8 0xB8EF1C5D839730B9, 0x00003FEC // S_4
+data8 0xD71EA3A4E5B3F492, 0x0000BFE5 // S_5
+data4 0x38800000 // two**-14
+data4 0xB8800000 // -two**-14
+LOCAL_OBJECT_END(FSINCOS_CONSTANTS)
+
+// sin and cos registers
+
+// FR
+FR_Input_X = f8
+
+FR_r = f8
+FR_c = f9
+
+FR_Two_to_63 = f32
+FR_Two_to_24 = f33
+FR_Pi_by_4 = f33
+FR_Two_to_M14 = f34
+FR_Two_to_M33 = f35
+FR_Neg_Two_to_24 = f36
+FR_Neg_Pi_by_4 = f36
+FR_Neg_Two_to_M14 = f37
+FR_Neg_Two_to_M33 = f38
+FR_Neg_Two_to_M67 = f39
+FR_Inv_pi_by_2 = f40
+FR_N_float = f41
+FR_N_fix = f42
+FR_P_1 = f43
+FR_P_2 = f44
+FR_P_3 = f45
+FR_s = f46
+FR_w = f47
+FR_d_2 = f48
+FR_prelim = f49
+FR_Z = f50
+FR_A = f51
+FR_a = f52
+FR_t = f53
+FR_U_1 = f54
+FR_U_2 = f55
+FR_C_1 = f56
+FR_C_2 = f57
+FR_C_3 = f58
+FR_C_4 = f59
+FR_C_5 = f60
+FR_S_1 = f61
+FR_S_2 = f62
+FR_S_3 = f63
+FR_S_4 = f64
+FR_S_5 = f65
+FR_poly_hi = f66
+FR_poly_lo = f67
+FR_r_hi = f68
+FR_r_lo = f69
+FR_rsq = f70
+FR_r_cubed = f71
+FR_C_hi = f72
+FR_N_0 = f73
+FR_d_1 = f74
+FR_V = f75
+FR_V_hi = f75
+FR_V_lo = f76
+FR_U_hi = f77
+FR_U_lo = f78
+FR_U_hiabs = f79
+FR_V_hiabs = f80
+FR_PP_8 = f81
+FR_QQ_8 = f81
+FR_PP_7 = f82
+FR_QQ_7 = f82
+FR_PP_6 = f83
+FR_QQ_6 = f83
+FR_PP_5 = f84
+FR_QQ_5 = f84
+FR_PP_4 = f85
+FR_QQ_4 = f85
+FR_PP_3 = f86
+FR_QQ_3 = f86
+FR_PP_2 = f87
+FR_QQ_2 = f87
+FR_QQ_1 = f88
+FR_N_0_fix = f89
+FR_Inv_P_0 = f90
+FR_corr = f91
+FR_poly = f92
+FR_Neg_Two_to_M3 = f93
+FR_Two_to_M3 = f94
+FR_Neg_Two_to_63 = f94
+FR_P_0 = f95
+FR_C_lo = f96
+FR_PP_1 = f97
+FR_PP_1_lo = f98
+FR_ArgPrime = f99
+
+// GR
+GR_Table_Base = r32
+GR_Table_Base1 = r33
+GR_i_0 = r34
+GR_i_1 = r35
+GR_N_Inc = r36
+GR_Sin_or_Cos = r37
+
+GR_SAVE_B0 = r39
+GR_SAVE_GP = r40
+GR_SAVE_PFS = r41
+
+// sincos combined routine registers
+
+// GR
+GR_SINCOS_SAVE_PFS = r32
+GR_SINCOS_SAVE_B0 = r33
+GR_SINCOS_SAVE_GP = r34
+
+// FR
+FR_SINCOS_ARG = f100
+FR_SINCOS_RES_SIN = f101
+
+
+.section .text
+
+
+GLOBAL_LIBM_ENTRY(__libm_sincos_large)
+
+{ .mfi
+ alloc GR_SINCOS_SAVE_PFS = ar.pfs,0,3,0,0
+ fma.s1 FR_SINCOS_ARG = f8, f1, f0 // Save argument for sin and cos
+ mov GR_SINCOS_SAVE_B0 = b0
+};;
+
+{ .mfb
+ mov GR_SINCOS_SAVE_GP = gp
+ nop.f 0
+ br.call.sptk b0 = __libm_sin_large // Call sin
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_SINCOS_RES_SIN = f8, f1, f0 // Save sin result
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ fma.s1 f8 = FR_SINCOS_ARG, f1, f0 // Arg for cos
+ br.call.sptk b0 = __libm_cos_large // Call cos
+};;
+
+{ .mfi
+ mov gp = GR_SINCOS_SAVE_GP
+ fma.s1 f9 = FR_SINCOS_RES_SIN, f1, f0 // Out sin result
+ mov b0 = GR_SINCOS_SAVE_B0
+};;
+
+{ .mib
+ nop.m 0
+ mov ar.pfs = GR_SINCOS_SAVE_PFS
+ br.ret.sptk b0 // sincos_large exit
+};;
+
+GLOBAL_LIBM_END(__libm_sincos_large)
+
+
+
+
+GLOBAL_LIBM_ENTRY(__libm_sin_large)
+
+{ .mlx
+alloc GR_Table_Base = ar.pfs,0,12,2,0
+ movl GR_Sin_or_Cos = 0x0 ;;
+}
+
+{ .mmi
+ nop.m 999
+ addl GR_Table_Base = @ltoff(FSINCOS_CONSTANTS#), gp
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ld8 GR_Table_Base = [GR_Table_Base]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+
+{ .mib
+ nop.m 999
+ nop.i 999
+ br.cond.sptk SINCOS_CONTINUE ;;
+}
+
+GLOBAL_LIBM_END(__libm_sin_large)
+
+GLOBAL_LIBM_ENTRY(__libm_cos_large)
+
+{ .mlx
+alloc GR_Table_Base= ar.pfs,0,12,2,0
+ movl GR_Sin_or_Cos = 0x1 ;;
+}
+
+{ .mmi
+ nop.m 999
+ addl GR_Table_Base = @ltoff(FSINCOS_CONSTANTS#), gp
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ld8 GR_Table_Base = [GR_Table_Base]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+//
+// Load Table Address
+//
+SINCOS_CONTINUE:
+
+{ .mmi
+ add GR_Table_Base1 = 96, GR_Table_Base
+ ldfs FR_Two_to_24 = [GR_Table_Base], 4
+ nop.i 999
+}
+;;
+
+{ .mmi
+ nop.m 999
+//
+// Load 2**24, load 2**63.
+//
+ ldfs FR_Neg_Two_to_24 = [GR_Table_Base], 12
+ mov r41 = ar.pfs ;;
+}
+
+{ .mfi
+ ldfs FR_Two_to_63 = [GR_Table_Base1], 4
+//
+// Check for unnormals - unsupported operands. We do not want
+// to generate denormal exception
+// Check for NatVals, QNaNs, SNaNs, +/-Infs
+// Check for EM unsupporteds
+// Check for Zero
+//
+ fclass.m.unc p6, p8 = FR_Input_X, 0x1E3
+ mov r40 = gp ;;
+}
+
+{ .mfi
+ nop.m 999
+ fclass.nm.unc p8, p0 = FR_Input_X, 0x1FF
+// GR_Sin_or_Cos denotes
+ mov r39 = b0
+}
+
+{ .mfb
+ ldfs FR_Neg_Two_to_63 = [GR_Table_Base1], 12
+ fclass.m.unc p10, p0 = FR_Input_X, 0x007
+(p6) br.cond.spnt SINCOS_SPECIAL ;;
+}
+
+{ .mib
+ nop.m 999
+ nop.i 999
+(p8) br.cond.spnt SINCOS_SPECIAL ;;
+}
+
+{ .mib
+ nop.m 999
+ nop.i 999
+//
+// Branch if +/- NaN, Inf.
+// Load -2**24, load -2**63.
+//
+(p10) br.cond.spnt SINCOS_ZERO ;;
+}
+
+{ .mmb
+ ldfe FR_Inv_pi_by_2 = [GR_Table_Base], 16
+ ldfe FR_Inv_P_0 = [GR_Table_Base1], 16
+ nop.b 999 ;;
+}
+
+{ .mmb
+ nop.m 999
+ ldfe FR_d_1 = [GR_Table_Base1], 16
+ nop.b 999 ;;
+}
+//
+// Raise possible denormal operand flag with useful fcmp
+// Is x <= -2**63
+// Load Inv_P_0 for pre-reduction
+// Load Inv_pi_by_2
+//
+
+{ .mmb
+ ldfe FR_P_0 = [GR_Table_Base], 16
+ ldfe FR_d_2 = [GR_Table_Base1], 16
+ nop.b 999 ;;
+}
+//
+// Load P_0
+// Load d_1
+// Is x >= 2**63
+// Is x <= -2**24?
+//
+
+{ .mmi
+ ldfe FR_P_1 = [GR_Table_Base], 16 ;;
+//
+// Load P_1
+// Load d_2
+// Is x >= 2**24?
+//
+ ldfe FR_P_2 = [GR_Table_Base], 16
+ nop.i 999 ;;
+}
+
+{ .mmf
+ nop.m 999
+ ldfe FR_P_3 = [GR_Table_Base], 16
+ fcmp.le.unc.s1 p7, p8 = FR_Input_X, FR_Neg_Two_to_24
+}
+
+{ .mfi
+ nop.m 999
+//
+// Branch if +/- zero.
+// Decide about the paths to take:
+// If -2**24 < FR_Input_X < 2**24 - CASE 1 OR 2
+// OTHERWISE - CASE 3 OR 4
+//
+ fcmp.le.unc.s1 p10, p11 = FR_Input_X, FR_Neg_Two_to_63
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p8) fcmp.ge.s1 p7, p0 = FR_Input_X, FR_Two_to_24
+ nop.i 999
+}
+
+{ .mfi
+ ldfe FR_Pi_by_4 = [GR_Table_Base1], 16
+(p11) fcmp.ge.s1 p10, p0 = FR_Input_X, FR_Two_to_63
+ nop.i 999 ;;
+}
+
+{ .mmi
+ ldfe FR_Neg_Pi_by_4 = [GR_Table_Base1], 16 ;;
+ ldfs FR_Two_to_M3 = [GR_Table_Base1], 4
+ nop.i 999 ;;
+}
+
+{ .mib
+ ldfs FR_Neg_Two_to_M3 = [GR_Table_Base1], 12
+ nop.i 999
+//
+// Load P_2
+// Load P_3
+// Load pi_by_4
+// Load neg_pi_by_4
+// Load 2**(-3)
+// Load -2**(-3).
+//
+(p10) br.cond.spnt SINCOS_ARG_TOO_LARGE ;;
+}
+
+{ .mib
+ nop.m 999
+ nop.i 999
+//
+// Branch out if x >= 2**63. Use Payne-Hanek Reduction
+//
+(p7) br.cond.spnt SINCOS_LARGER_ARG ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Branch if Arg <= -2**24 or Arg >= 2**24 and use pre-reduction.
+//
+ fma.s1 FR_N_float = FR_Input_X, FR_Inv_pi_by_2, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fcmp.lt.unc.s1 p6, p7 = FR_Input_X, FR_Pi_by_4
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Select the case when |Arg| < pi/4
+// Else Select the case when |Arg| >= pi/4
+//
+ fcvt.fx.s1 FR_N_fix = FR_N_float
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N = Arg * 2/pi
+// Check if Arg < pi/4
+//
+(p6) fcmp.gt.s1 p6, p7 = FR_Input_X, FR_Neg_Pi_by_4
+ nop.i 999 ;;
+}
+//
+// Case 2: Convert integer N_fix back to normalized floating-point value.
+// Case 1: p8 is only affected when p6 is set
+//
+
+{ .mfi
+(p7) ldfs FR_Two_to_M33 = [GR_Table_Base1], 4
+//
+// Grab the integer part of N and call it N_fix
+//
+(p6) fmerge.se FR_r = FR_Input_X, FR_Input_X
+// If |x| < pi/4, r = x and c = 0
+// lf |x| < pi/4, is x < 2**(-3).
+// r = Arg
+// c = 0
+(p6) mov GR_N_Inc = GR_Sin_or_Cos ;;
+}
+
+{ .mmf
+ nop.m 999
+(p7) ldfs FR_Neg_Two_to_M33 = [GR_Table_Base1], 4
+(p6) fmerge.se FR_c = f0, f0
+}
+
+{ .mfi
+ nop.m 999
+(p6) fcmp.lt.unc.s1 p8, p9 = FR_Input_X, FR_Two_to_M3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// lf |x| < pi/4, is -2**(-3)< x < 2**(-3) - set p8.
+// If |x| >= pi/4,
+// Create the right N for |x| < pi/4 and otherwise
+// Case 2: Place integer part of N in GP register
+//
+(p7) fcvt.xf FR_N_float = FR_N_fix
+ nop.i 999 ;;
+}
+
+{ .mmf
+ nop.m 999
+(p7) getf.sig GR_N_Inc = FR_N_fix
+(p8) fcmp.gt.s1 p8, p0 = FR_Input_X, FR_Neg_Two_to_M3 ;;
+}
+
+{ .mib
+ nop.m 999
+ nop.i 999
+//
+// Load 2**(-33), -2**(-33)
+//
+(p8) br.cond.spnt SINCOS_SMALL_R ;;
+}
+
+{ .mib
+ nop.m 999
+ nop.i 999
+(p6) br.cond.sptk SINCOS_NORMAL_R ;;
+}
+//
+// if |x| < pi/4, branch based on |x| < 2**(-3) or otherwise.
+//
+//
+// In this branch, |x| >= pi/4.
+//
+
+{ .mfi
+ ldfs FR_Neg_Two_to_M67 = [GR_Table_Base1], 8
+//
+// Load -2**(-67)
+//
+ fnma.s1 FR_s = FR_N_float, FR_P_1, FR_Input_X
+//
+// w = N * P_2
+// s = -N * P_1 + Arg
+//
+ add GR_N_Inc = GR_N_Inc, GR_Sin_or_Cos
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_w = FR_N_float, FR_P_2, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Adjust N_fix by N_inc to determine whether sine or
+// cosine is being calculated
+//
+ fcmp.lt.unc.s1 p7, p6 = FR_s, FR_Two_to_M33
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p7) fcmp.gt.s1 p7, p6 = FR_s, FR_Neg_Two_to_M33
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+// Remember x >= pi/4.
+// Is s <= -2**(-33) or s >= 2**(-33) (p6)
+// or -2**(-33) < s < 2**(-33) (p7)
+(p6) fms.s1 FR_r = FR_s, f1, FR_w
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p7) fma.s1 FR_w = FR_N_float, FR_P_3, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p7) fma.s1 FR_U_1 = FR_N_float, FR_P_2, FR_w
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p6) fms.s1 FR_c = FR_s, f1, FR_r
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// For big s: r = s - w: No futher reduction is necessary
+// For small s: w = N * P_3 (change sign) More reduction
+//
+(p6) fcmp.lt.unc.s1 p8, p9 = FR_r, FR_Two_to_M3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p8) fcmp.gt.s1 p8, p9 = FR_r, FR_Neg_Two_to_M3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p7) fms.s1 FR_r = FR_s, f1, FR_U_1
+ nop.i 999
+}
+
+{ .mfb
+ nop.m 999
+//
+// For big s: Is |r| < 2**(-3)?
+// For big s: c = S - r
+// For small s: U_1 = N * P_2 + w
+//
+// If p8 is set, prepare to branch to Small_R.
+// If p9 is set, prepare to branch to Normal_R.
+// For big s, r is complete here.
+//
+(p6) fms.s1 FR_c = FR_c, f1, FR_w
+//
+// For big s: c = c + w (w has not been negated.)
+// For small s: r = S - U_1
+//
+(p8) br.cond.spnt SINCOS_SMALL_R ;;
+}
+
+{ .mib
+ nop.m 999
+ nop.i 999
+(p9) br.cond.sptk SINCOS_NORMAL_R ;;
+}
+
+{ .mfi
+(p7) add GR_Table_Base1 = 224, GR_Table_Base1
+//
+// Branch to SINCOS_SMALL_R or SINCOS_NORMAL_R
+//
+(p7) fms.s1 FR_U_2 = FR_N_float, FR_P_2, FR_U_1
+//
+// c = S - U_1
+// r = S_1 * r
+//
+//
+(p7) extr.u GR_i_1 = GR_N_Inc, 0, 1
+}
+
+{ .mmi
+ nop.m 999 ;;
+//
+// Get [i_0,i_1] - two lsb of N_fix_gr.
+// Do dummy fmpy so inexact is always set.
+//
+(p7) cmp.eq.unc p9, p10 = 0x0, GR_i_1
+(p7) extr.u GR_i_0 = GR_N_Inc, 1, 1 ;;
+}
+//
+// For small s: U_2 = N * P_2 - U_1
+// S_1 stored constant - grab the one stored with the
+// coefficients.
+//
+
+{ .mfi
+(p7) ldfe FR_S_1 = [GR_Table_Base1], 16
+//
+// Check if i_1 and i_0 != 0
+//
+(p10) fma.s1 FR_poly = f0, f1, FR_Neg_Two_to_M67
+(p7) cmp.eq.unc p11, p12 = 0x0, GR_i_0 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p7) fms.s1 FR_s = FR_s, f1, FR_r
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// S = S - r
+// U_2 = U_2 + w
+// load S_1
+//
+(p7) fma.s1 FR_rsq = FR_r, FR_r, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p7) fma.s1 FR_U_2 = FR_U_2, f1, FR_w
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//(p7) fmerge.se FR_Input_X = FR_r, FR_r
+(p7) fmerge.se FR_prelim = FR_r, FR_r
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//(p10) fma.s1 FR_Input_X = f0, f1, f1
+(p10) fma.s1 FR_prelim = f0, f1, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// FR_rsq = r * r
+// Save r as the result.
+//
+(p7) fms.s1 FR_c = FR_s, f1, FR_U_1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if ( i_1 ==0) poly = c + S_1*r*r*r
+// else Result = 1
+//
+//(p12) fnma.s1 FR_Input_X = FR_Input_X, f1, f0
+(p12) fnma.s1 FR_prelim = FR_prelim, f1, f0
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p7) fma.s1 FR_r = FR_S_1, FR_r, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p7) fma.d.s1 FR_S_1 = FR_S_1, FR_S_1, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// If i_1 != 0, poly = 2**(-67)
+//
+(p7) fms.s1 FR_c = FR_c, f1, FR_U_2
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// c = c - U_2
+//
+(p9) fma.s1 FR_poly = FR_r, FR_rsq, FR_c
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// i_0 != 0, so Result = -Result
+//
+(p11) fma.s1 FR_Input_X = FR_prelim, f1, FR_poly
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p12) fms.s1 FR_Input_X = FR_prelim, f1, FR_poly
+//
+// if (i_0 == 0), Result = Result + poly
+// else Result = Result - poly
+//
+ br.ret.sptk b0 ;;
+}
+SINCOS_LARGER_ARG:
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_N_0 = FR_Input_X, FR_Inv_P_0, f0
+ nop.i 999
+}
+;;
+
+// This path for argument > 2*24
+// Adjust table_ptr1 to beginning of table.
+//
+
+{ .mmi
+ nop.m 999
+ addl GR_Table_Base = @ltoff(FSINCOS_CONSTANTS#), gp
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ld8 GR_Table_Base = [GR_Table_Base]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+
+//
+// Point to 2*-14
+// N_0 = Arg * Inv_P_0
+//
+
+{ .mmi
+ add GR_Table_Base = 688, GR_Table_Base ;;
+ ldfs FR_Two_to_M14 = [GR_Table_Base], 4
+ nop.i 999 ;;
+}
+
+{ .mfi
+ ldfs FR_Neg_Two_to_M14 = [GR_Table_Base], 0
+ nop.f 999
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Load values 2**(-14) and -2**(-14)
+//
+ fcvt.fx.s1 FR_N_0_fix = FR_N_0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N_0_fix = integer part of N_0
+//
+ fcvt.xf FR_N_0 = FR_N_0_fix
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Make N_0 the integer part
+//
+ fnma.s1 FR_ArgPrime = FR_N_0, FR_P_0, FR_Input_X
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_w = FR_N_0, FR_d_1, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Arg' = -N_0 * P_0 + Arg
+// w = N_0 * d_1
+//
+ fma.s1 FR_N_float = FR_ArgPrime, FR_Inv_pi_by_2, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N = A' * 2/pi
+//
+ fcvt.fx.s1 FR_N_fix = FR_N_float
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N_fix is the integer part
+//
+ fcvt.xf FR_N_float = FR_N_fix
+ nop.i 999 ;;
+}
+
+{ .mfi
+ getf.sig GR_N_Inc = FR_N_fix
+ nop.f 999
+ nop.i 999 ;;
+}
+
+{ .mii
+ nop.m 999
+ nop.i 999 ;;
+ add GR_N_Inc = GR_N_Inc, GR_Sin_or_Cos ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N is the integer part of the reduced-reduced argument.
+// Put the integer in a GP register
+//
+ fnma.s1 FR_s = FR_N_float, FR_P_1, FR_ArgPrime
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+ fnma.s1 FR_w = FR_N_float, FR_P_2, FR_w
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// s = -N*P_1 + Arg'
+// w = -N*P_2 + w
+// N_fix_gr = N_fix_gr + N_inc
+//
+ fcmp.lt.unc.s1 p9, p8 = FR_s, FR_Two_to_M14
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fcmp.gt.s1 p9, p8 = FR_s, FR_Neg_Two_to_M14
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// For |s| > 2**(-14) r = S + w (r complete)
+// Else U_hi = N_0 * d_1
+//
+(p9) fma.s1 FR_V_hi = FR_N_float, FR_P_2, f0
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_U_hi = FR_N_0, FR_d_1, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Either S <= -2**(-14) or S >= 2**(-14)
+// or -2**(-14) < s < 2**(-14)
+//
+(p8) fma.s1 FR_r = FR_s, f1, FR_w
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_w = FR_N_float, FR_P_3, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// We need abs of both U_hi and V_hi - don't
+// worry about switched sign of V_hi.
+//
+(p9) fms.s1 FR_A = FR_U_hi, f1, FR_V_hi
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// Big s: finish up c = (S - r) + w (c complete)
+// Case 4: A = U_hi + V_hi
+// Note: Worry about switched sign of V_hi, so subtract instead of add.
+//
+(p9) fnma.s1 FR_V_lo = FR_N_float, FR_P_2, FR_V_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fms.s1 FR_U_lo = FR_N_0, FR_d_1, FR_U_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fmerge.s FR_V_hiabs = f0, FR_V_hi
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+// For big s: c = S - r
+// For small s do more work: U_lo = N_0 * d_1 - U_hi
+//
+(p9) fmerge.s FR_U_hiabs = f0, FR_U_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// For big s: Is |r| < 2**(-3)
+// For big s: if p12 set, prepare to branch to Small_R.
+// For big s: If p13 set, prepare to branch to Normal_R.
+//
+(p8) fms.s1 FR_c = FR_s, f1, FR_r
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// For small S: V_hi = N * P_2
+// w = N * P_3
+// Note the product does not include the (-) as in the writeup
+// so (-) missing for V_hi and w.
+//
+(p8) fcmp.lt.unc.s1 p12, p13 = FR_r, FR_Two_to_M3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fcmp.gt.s1 p12, p13 = FR_r, FR_Neg_Two_to_M3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_c = FR_c, f1, FR_w
+ nop.i 999
+}
+
+{ .mfb
+ nop.m 999
+(p9) fms.s1 FR_w = FR_N_0, FR_d_2, FR_w
+(p12) br.cond.spnt SINCOS_SMALL_R ;;
+}
+
+{ .mib
+ nop.m 999
+ nop.i 999
+(p13) br.cond.sptk SINCOS_NORMAL_R ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Big s: Vector off when |r| < 2**(-3). Recall that p8 will be true.
+// The remaining stuff is for Case 4.
+// Small s: V_lo = N * P_2 + U_hi (U_hi is in place of V_hi in writeup)
+// Note: the (-) is still missing for V_lo.
+// Small s: w = w + N_0 * d_2
+// Note: the (-) is now incorporated in w.
+//
+(p9) fcmp.ge.unc.s1 p10, p11 = FR_U_hiabs, FR_V_hiabs
+ extr.u GR_i_1 = GR_N_Inc, 0, 1 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// C_hi = S + A
+//
+(p9) fma.s1 FR_t = FR_U_lo, f1, FR_V_lo
+ extr.u GR_i_0 = GR_N_Inc, 1, 1 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// t = U_lo + V_lo
+//
+//
+(p10) fms.s1 FR_a = FR_U_hi, f1, FR_A
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p11) fma.s1 FR_a = FR_V_hi, f1, FR_A
+ nop.i 999
+}
+;;
+
+{ .mmi
+ nop.m 999
+ addl GR_Table_Base = @ltoff(FSINCOS_CONSTANTS#), gp
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ld8 GR_Table_Base = [GR_Table_Base]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+
+{ .mfi
+ add GR_Table_Base = 528, GR_Table_Base
+//
+// Is U_hiabs >= V_hiabs?
+//
+(p9) fma.s1 FR_C_hi = FR_s, f1, FR_A
+ nop.i 999 ;;
+}
+
+{ .mmi
+ ldfe FR_C_1 = [GR_Table_Base], 16 ;;
+ ldfe FR_C_2 = [GR_Table_Base], 64
+ nop.i 999 ;;
+}
+
+{ .mmf
+ nop.m 999
+//
+// c = c + C_lo finished.
+// Load C_2
+//
+ ldfe FR_S_1 = [GR_Table_Base], 16
+//
+// C_lo = S - C_hi
+//
+ fma.s1 FR_t = FR_t, f1, FR_w ;;
+}
+//
+// r and c have been computed.
+// Make sure ftz mode is set - should be automatic when using wre
+// |r| < 2**(-3)
+// Get [i_0,i_1] - two lsb of N_fix.
+// Load S_1
+//
+
+{ .mfi
+ ldfe FR_S_2 = [GR_Table_Base], 64
+//
+// t = t + w
+//
+(p10) fms.s1 FR_a = FR_a, f1, FR_V_hi
+ cmp.eq.unc p9, p10 = 0x0, GR_i_0
+}
+
+{ .mfi
+ nop.m 999
+//
+// For larger u than v: a = U_hi - A
+// Else a = V_hi - A (do an add to account for missing (-) on V_hi
+//
+ fms.s1 FR_C_lo = FR_s, f1, FR_C_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p11) fms.s1 FR_a = FR_U_hi, f1, FR_a
+ cmp.eq.unc p11, p12 = 0x0, GR_i_1
+}
+
+{ .mfi
+ nop.m 999
+//
+// If u > v: a = (U_hi - A) + V_hi
+// Else a = (V_hi - A) + U_hi
+// In each case account for negative missing from V_hi.
+//
+ fma.s1 FR_C_lo = FR_C_lo, f1, FR_A
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// C_lo = (S - C_hi) + A
+//
+ fma.s1 FR_t = FR_t, f1, FR_a
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// t = t + a
+//
+ fma.s1 FR_C_lo = FR_C_lo, f1, FR_t
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// C_lo = C_lo + t
+// Adjust Table_Base to beginning of table
+//
+ fma.s1 FR_r = FR_C_hi, f1, FR_C_lo
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Load S_2
+//
+ fma.s1 FR_rsq = FR_r, FR_r, f0
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// Table_Base points to C_1
+// r = C_hi + C_lo
+//
+ fms.s1 FR_c = FR_C_hi, f1, FR_r
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if i_1 ==0: poly = S_2 * FR_rsq + S_1
+// else poly = C_2 * FR_rsq + C_1
+//
+//(p11) fma.s1 FR_Input_X = f0, f1, FR_r
+(p11) fma.s1 FR_prelim = f0, f1, FR_r
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//(p12) fma.s1 FR_Input_X = f0, f1, f1
+(p12) fma.s1 FR_prelim = f0, f1, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Compute r_cube = FR_rsq * r
+//
+(p11) fma.s1 FR_poly = FR_rsq, FR_S_2, FR_S_1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 FR_poly = FR_rsq, FR_C_2, FR_C_1
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// Compute FR_rsq = r * r
+// Is i_1 == 0 ?
+//
+ fma.s1 FR_r_cubed = FR_rsq, FR_r, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// c = C_hi - r
+// Load C_1
+//
+ fma.s1 FR_c = FR_c, f1, FR_C_lo
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// if i_1 ==0: poly = r_cube * poly + c
+// else poly = FR_rsq * poly
+//
+//(p10) fms.s1 FR_Input_X = f0, f1, FR_Input_X
+(p10) fms.s1 FR_prelim = f0, f1, FR_prelim
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if i_1 ==0: Result = r
+// else Result = 1.0
+//
+(p11) fma.s1 FR_poly = FR_r_cubed, FR_poly, FR_c
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 FR_poly = FR_rsq, FR_poly, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if i_0 !=0: Result = -Result
+//
+(p9) fma.s1 FR_Input_X = FR_prelim, f1, FR_poly
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+(p10) fms.s1 FR_Input_X = FR_prelim, f1, FR_poly
+//
+// if i_0 == 0: Result = Result + poly
+// else Result = Result - poly
+//
+ br.ret.sptk b0 ;;
+}
+SINCOS_SMALL_R:
+
+{ .mii
+ nop.m 999
+ extr.u GR_i_1 = GR_N_Inc, 0, 1 ;;
+//
+//
+// Compare both i_1 and i_0 with 0.
+// if i_1 == 0, set p9.
+// if i_0 == 0, set p11.
+//
+ cmp.eq.unc p9, p10 = 0x0, GR_i_1 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_rsq = FR_r, FR_r, f0
+ extr.u GR_i_0 = GR_N_Inc, 1, 1 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Z = Z * FR_rsq
+//
+(p10) fnma.s1 FR_c = FR_c, FR_r, f0
+ cmp.eq.unc p11, p12 = 0x0, GR_i_0
+}
+;;
+
+// ******************************************************************
+// ******************************************************************
+// ******************************************************************
+// r and c have been computed.
+// We know whether this is the sine or cosine routine.
+// Make sure ftz mode is set - should be automatic when using wre
+// |r| < 2**(-3)
+//
+// Set table_ptr1 to beginning of constant table.
+// Get [i_0,i_1] - two lsb of N_fix_gr.
+//
+
+{ .mmi
+ nop.m 999
+ addl GR_Table_Base = @ltoff(FSINCOS_CONSTANTS#), gp
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ld8 GR_Table_Base = [GR_Table_Base]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+
+//
+// Set table_ptr1 to point to S_5.
+// Set table_ptr1 to point to C_5.
+// Compute FR_rsq = r * r
+//
+
+{ .mfi
+(p9) add GR_Table_Base = 672, GR_Table_Base
+(p10) fmerge.s FR_r = f1, f1
+(p10) add GR_Table_Base = 592, GR_Table_Base ;;
+}
+//
+// Set table_ptr1 to point to S_5.
+// Set table_ptr1 to point to C_5.
+//
+
+{ .mmi
+(p9) ldfe FR_S_5 = [GR_Table_Base], -16 ;;
+//
+// if (i_1 == 0) load S_5
+// if (i_1 != 0) load C_5
+//
+(p9) ldfe FR_S_4 = [GR_Table_Base], -16
+ nop.i 999 ;;
+}
+
+{ .mmf
+(p10) ldfe FR_C_5 = [GR_Table_Base], -16
+//
+// Z = FR_rsq * FR_rsq
+//
+(p9) ldfe FR_S_3 = [GR_Table_Base], -16
+//
+// Compute FR_rsq = r * r
+// if (i_1 == 0) load S_4
+// if (i_1 != 0) load C_4
+//
+ fma.s1 FR_Z = FR_rsq, FR_rsq, f0 ;;
+}
+//
+// if (i_1 == 0) load S_3
+// if (i_1 != 0) load C_3
+//
+
+{ .mmi
+(p9) ldfe FR_S_2 = [GR_Table_Base], -16 ;;
+//
+// if (i_1 == 0) load S_2
+// if (i_1 != 0) load C_2
+//
+(p9) ldfe FR_S_1 = [GR_Table_Base], -16
+ nop.i 999
+}
+
+{ .mmi
+(p10) ldfe FR_C_4 = [GR_Table_Base], -16 ;;
+(p10) ldfe FR_C_3 = [GR_Table_Base], -16
+ nop.i 999 ;;
+}
+
+{ .mmi
+(p10) ldfe FR_C_2 = [GR_Table_Base], -16 ;;
+(p10) ldfe FR_C_1 = [GR_Table_Base], -16
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1 != 0):
+// poly_lo = FR_rsq * C_5 + C_4
+// poly_hi = FR_rsq * C_2 + C_1
+//
+(p9) fma.s1 FR_Z = FR_Z, FR_r, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1 == 0) load S_1
+// if (i_1 != 0) load C_1
+//
+(p9) fma.s1 FR_poly_lo = FR_rsq, FR_S_5, FR_S_4
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// c = -c * r
+// dummy fmpy's to flag inexact.
+//
+(p9) fma.d.s1 FR_S_4 = FR_S_4, FR_S_4, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// poly_lo = FR_rsq * poly_lo + C_3
+// poly_hi = FR_rsq * poly_hi
+//
+ fma.s1 FR_Z = FR_Z, FR_rsq, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_hi = FR_rsq, FR_S_2, FR_S_1
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1 == 0):
+// poly_lo = FR_rsq * S_5 + S_4
+// poly_hi = FR_rsq * S_2 + S_1
+//
+(p10) fma.s1 FR_poly_lo = FR_rsq, FR_C_5, FR_C_4
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1 == 0):
+// Z = Z * r for only one of the small r cases - not there
+// in original implementation notes.
+//
+(p9) fma.s1 FR_poly_lo = FR_rsq, FR_poly_lo, FR_S_3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly_hi = FR_rsq, FR_C_2, FR_C_1
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.d.s1 FR_C_1 = FR_C_1, FR_C_1, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_hi = FR_poly_hi, FR_rsq, f0
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// poly_lo = FR_rsq * poly_lo + S_3
+// poly_hi = FR_rsq * poly_hi
+//
+(p10) fma.s1 FR_poly_lo = FR_rsq, FR_poly_lo, FR_C_3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly_hi = FR_poly_hi, FR_rsq, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1 == 0): dummy fmpy's to flag inexact
+// r = 1
+//
+(p9) fma.s1 FR_poly_hi = FR_r, FR_poly_hi, f0
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// poly_hi = r * poly_hi
+//
+ fma.s1 FR_poly = FR_Z, FR_poly_lo, FR_c
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fms.s1 FR_r = f0, f1, FR_r
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// poly_hi = Z * poly_lo + c
+// if i_0 == 1: r = -r
+//
+ fma.s1 FR_poly = FR_poly, f1, FR_poly_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fms.s1 FR_Input_X = FR_r, f1, FR_poly
+ nop.i 999
+}
+
+{ .mfb
+ nop.m 999
+//
+// poly = poly + poly_hi
+//
+(p11) fma.s1 FR_Input_X = FR_r, f1, FR_poly
+//
+// if (i_0 == 0) Result = r + poly
+// if (i_0 != 0) Result = r - poly
+//
+ br.ret.sptk b0 ;;
+}
+SINCOS_NORMAL_R:
+
+{ .mii
+ nop.m 999
+ extr.u GR_i_1 = GR_N_Inc, 0, 1 ;;
+//
+// Set table_ptr1 and table_ptr2 to base address of
+// constant table.
+ cmp.eq.unc p9, p10 = 0x0, GR_i_1 ;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_rsq = FR_r, FR_r, f0
+ extr.u GR_i_0 = GR_N_Inc, 1, 1 ;;
+}
+
+{ .mfi
+ nop.m 999
+ frcpa.s1 FR_r_hi, p6 = f1, FR_r
+ cmp.eq.unc p11, p12 = 0x0, GR_i_0
+}
+;;
+
+// ******************************************************************
+// ******************************************************************
+// ******************************************************************
+//
+// r and c have been computed.
+// We known whether this is the sine or cosine routine.
+// Make sure ftz mode is set - should be automatic when using wre
+// Get [i_0,i_1] - two lsb of N_fix_gr alone.
+//
+
+{ .mmi
+ nop.m 999
+ addl GR_Table_Base = @ltoff(FSINCOS_CONSTANTS#), gp
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ld8 GR_Table_Base = [GR_Table_Base]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+
+{ .mfi
+(p10) add GR_Table_Base = 384, GR_Table_Base
+//(p12) fms.s1 FR_Input_X = f0, f1, f1
+(p12) fms.s1 FR_prelim = f0, f1, f1
+(p9) add GR_Table_Base = 224, GR_Table_Base ;;
+}
+
+{ .mmf
+ nop.m 999
+(p10) ldfe FR_QQ_8 = [GR_Table_Base], 16
+//
+// if (i_1==0) poly = poly * FR_rsq + PP_1_lo
+// else poly = FR_rsq * poly
+//
+//(p11) fma.s1 FR_Input_X = f0, f1, f1 ;;
+(p11) fma.s1 FR_prelim = f0, f1, f1 ;;
+}
+
+{ .mmf
+(p10) ldfe FR_QQ_7 = [GR_Table_Base], 16
+//
+// Adjust table pointers based on i_0
+// Compute rsq = r * r
+//
+(p9) ldfe FR_PP_8 = [GR_Table_Base], 16
+ fma.s1 FR_r_cubed = FR_r, FR_rsq, f0 ;;
+}
+
+{ .mmf
+(p9) ldfe FR_PP_7 = [GR_Table_Base], 16
+(p10) ldfe FR_QQ_6 = [GR_Table_Base], 16
+//
+// Load PP_8 and QQ_8; PP_7 and QQ_7
+//
+ frcpa.s1 FR_r_hi, p6 = f1, FR_r_hi ;;
+}
+//
+// if (i_1==0) poly = PP_7 + FR_rsq * PP_8.
+// else poly = QQ_7 + FR_rsq * QQ_8.
+//
+
+{ .mmb
+(p9) ldfe FR_PP_6 = [GR_Table_Base], 16
+(p10) ldfe FR_QQ_5 = [GR_Table_Base], 16
+ nop.b 999 ;;
+}
+
+{ .mmb
+(p9) ldfe FR_PP_5 = [GR_Table_Base], 16
+(p10) ldfe FR_S_1 = [GR_Table_Base], 16
+ nop.b 999 ;;
+}
+
+{ .mmb
+(p10) ldfe FR_QQ_1 = [GR_Table_Base], 16
+(p9) ldfe FR_C_1 = [GR_Table_Base], 16
+ nop.b 999 ;;
+}
+
+{ .mmi
+(p10) ldfe FR_QQ_4 = [GR_Table_Base], 16 ;;
+(p9) ldfe FR_PP_1 = [GR_Table_Base], 16
+ nop.i 999 ;;
+}
+
+{ .mmf
+(p10) ldfe FR_QQ_3 = [GR_Table_Base], 16
+//
+// if (i_1=0) corr = corr + c*c
+// else corr = corr * c
+//
+(p9) ldfe FR_PP_4 = [GR_Table_Base], 16
+(p10) fma.s1 FR_poly = FR_rsq, FR_QQ_8, FR_QQ_7 ;;
+}
+//
+// if (i_1=0) poly = rsq * poly + PP_5
+// else poly = rsq * poly + QQ_5
+// Load PP_4 or QQ_4
+//
+
+{ .mmf
+(p9) ldfe FR_PP_3 = [GR_Table_Base], 16
+(p10) ldfe FR_QQ_2 = [GR_Table_Base], 16
+//
+// r_hi = frcpa(frcpa(r)).
+// r_cube = r * FR_rsq.
+//
+(p9) fma.s1 FR_poly = FR_rsq, FR_PP_8, FR_PP_7 ;;
+}
+//
+// Do dummy multiplies so inexact is always set.
+//
+
+{ .mfi
+(p9) ldfe FR_PP_2 = [GR_Table_Base], 16
+//
+// r_lo = r - r_hi
+//
+(p9) fma.s1 FR_U_lo = FR_r_hi, FR_r_hi, f0
+ nop.i 999 ;;
+}
+
+{ .mmf
+ nop.m 999
+(p9) ldfe FR_PP_1_lo = [GR_Table_Base], 16
+(p10) fma.s1 FR_corr = FR_S_1, FR_r_cubed, FR_r
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, FR_QQ_6
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1=0) U_lo = r_hi * r_hi
+// else U_lo = r_hi + r
+//
+(p9) fma.s1 FR_corr = FR_C_1, FR_rsq, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1=0) corr = C_1 * rsq
+// else corr = S_1 * r_cubed + r
+//
+(p9) fma.s1 FR_poly = FR_rsq, FR_poly, FR_PP_6
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_U_lo = FR_r_hi, f1, FR_r
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1=0) U_hi = r_hi + U_hi
+// else U_hi = QQ_1 * U_hi + 1
+//
+(p9) fma.s1 FR_U_lo = FR_r, FR_r_hi, FR_U_lo
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// U_hi = r_hi * r_hi
+//
+ fms.s1 FR_r_lo = FR_r, f1, FR_r_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Load PP_1, PP_6, PP_5, and C_1
+// Load QQ_1, QQ_6, QQ_5, and S_1
+//
+ fma.s1 FR_U_hi = FR_r_hi, FR_r_hi, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, FR_QQ_5
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p10) fnma.s1 FR_corr = FR_corr, FR_c, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1=0) U_lo = r * r_hi + U_lo
+// else U_lo = r_lo * U_lo
+//
+(p9) fma.s1 FR_corr = FR_corr, FR_c, FR_c
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly = FR_rsq, FR_poly, FR_PP_5
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1 =0) U_hi = r + U_hi
+// if (i_1 =0) U_lo = r_lo * U_lo
+//
+//
+(p9) fma.d.s1 FR_PP_5 = FR_PP_5, FR_PP_4, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_U_lo = FR_r, FR_r, FR_U_lo
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_U_lo = FR_r_lo, FR_U_lo, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1=0) poly = poly * rsq + PP_6
+// else poly = poly * rsq + QQ_6
+//
+(p9) fma.s1 FR_U_hi = FR_r_hi, FR_U_hi, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, FR_QQ_4
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_U_hi = FR_QQ_1, FR_U_hi, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.d.s1 FR_QQ_5 = FR_QQ_5, FR_QQ_5, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1!=0) U_hi = PP_1 * U_hi
+// if (i_1!=0) U_lo = r * r + U_lo
+// Load PP_3 or QQ_3
+//
+(p9) fma.s1 FR_poly = FR_rsq, FR_poly, FR_PP_4
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_U_lo = FR_r_lo, FR_U_lo, f0
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_U_lo = FR_QQ_1,FR_U_lo, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_U_hi = FR_PP_1, FR_U_hi, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, FR_QQ_3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Load PP_2, QQ_2
+//
+(p9) fma.s1 FR_poly = FR_rsq, FR_poly, FR_PP_3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1==0) poly = FR_rsq * poly + PP_3
+// else poly = FR_rsq * poly + QQ_3
+// Load PP_1_lo
+//
+(p9) fma.s1 FR_U_lo = FR_PP_1, FR_U_lo, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1 =0) poly = poly * rsq + pp_r4
+// else poly = poly * rsq + qq_r4
+//
+(p9) fma.s1 FR_U_hi = FR_r, f1, FR_U_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, FR_QQ_2
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1==0) U_lo = PP_1_hi * U_lo
+// else U_lo = QQ_1 * U_lo
+//
+(p9) fma.s1 FR_poly = FR_rsq, FR_poly, FR_PP_2
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_0==0) Result = 1
+// else Result = -1
+//
+ fma.s1 FR_V = FR_U_lo, f1, FR_corr
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1==0) poly = FR_rsq * poly + PP_2
+// else poly = FR_rsq * poly + QQ_2
+//
+(p9) fma.s1 FR_poly = FR_rsq, FR_poly, FR_PP_1_lo
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// V = U_lo + corr
+//
+(p9) fma.s1 FR_poly = FR_r_cubed, FR_poly, f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if (i_1==0) poly = r_cube * poly
+// else poly = FR_rsq * poly
+//
+ fma.s1 FR_V = FR_poly, f1, FR_V
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//(p12) fms.s1 FR_Input_X = FR_Input_X, FR_U_hi, FR_V
+(p12) fms.s1 FR_Input_X = FR_prelim, FR_U_hi, FR_V
+ nop.i 999
+}
+
+{ .mfb
+ nop.m 999
+//
+// V = V + poly
+//
+//(p11) fma.s1 FR_Input_X = FR_Input_X, FR_U_hi, FR_V
+(p11) fma.s1 FR_Input_X = FR_prelim, FR_U_hi, FR_V
+//
+// if (i_0==0) Result = Result * U_hi + V
+// else Result = Result * U_hi - V
+//
+ br.ret.sptk b0 ;;
+}
+
+//
+// If cosine, FR_Input_X = 1
+// If sine, FR_Input_X = +/-Zero (Input FR_Input_X)
+// Results are exact, no exceptions
+//
+SINCOS_ZERO:
+
+{ .mmb
+ cmp.eq.unc p6, p7 = 0x1, GR_Sin_or_Cos
+ nop.m 999
+ nop.b 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p7) fmerge.s FR_Input_X = FR_Input_X, FR_Input_X
+ nop.i 999
+}
+
+{ .mfb
+ nop.m 999
+(p6) fmerge.s FR_Input_X = f1, f1
+ br.ret.sptk b0 ;;
+}
+
+SINCOS_SPECIAL:
+
+//
+// Path for Arg = +/- QNaN, SNaN, Inf
+// Invalid can be raised. SNaNs
+// become QNaNs
+//
+
+{ .mfb
+ nop.m 999
+ fmpy.s1 FR_Input_X = FR_Input_X, f0
+ br.ret.sptk b0 ;;
+}
+GLOBAL_LIBM_END(__libm_cos_large)
+
+
+// *******************************************************************
+// *******************************************************************
+// *******************************************************************
+//
+// Special Code to handle very large argument case.
+// Call int __libm_pi_by_2_reduce(x,r,c) for |arguments| >= 2**63
+// The interface is custom:
+// On input:
+// (Arg or x) is in f8
+// On output:
+// r is in f8
+// c is in f9
+// N is in r8
+// Be sure to allocate at least 2 GP registers as output registers for
+// __libm_pi_by_2_reduce. This routine uses r49-50. These are used as
+// scratch registers within the __libm_pi_by_2_reduce routine (for speed).
+//
+// We know also that __libm_pi_by_2_reduce preserves f10-15, f71-127. We
+// use this to eliminate save/restore of key fp registers in this calling
+// function.
+//
+// *******************************************************************
+// *******************************************************************
+// *******************************************************************
+
+LOCAL_LIBM_ENTRY(__libm_callout_2)
+SINCOS_ARG_TOO_LARGE:
+
+.prologue
+// Readjust Table ptr
+{ .mfi
+ adds GR_Table_Base1 = -16, GR_Table_Base1
+ nop.f 999
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+};;
+
+{ .mmi
+ ldfs FR_Two_to_M3 = [GR_Table_Base1],4
+ mov GR_SAVE_GP=gp // Save gp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+//
+// Call argument reduction with x in f8
+// Returns with N in r8, r in f8, c in f9
+// Assumes f71-127 are preserved across the call
+//
+{ .mib
+ ldfs FR_Neg_Two_to_M3 = [GR_Table_Base1],0
+ nop.i 0
+ br.call.sptk b0=__libm_pi_by_2_reduce#
+};;
+
+{ .mfi
+ add GR_N_Inc = GR_Sin_or_Cos,r8
+ fcmp.lt.unc.s1 p6, p0 = FR_r, FR_Two_to_M3
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mfi
+ mov gp = GR_SAVE_GP // Restore gp
+(p6) fcmp.gt.unc.s1 p6, p0 = FR_r, FR_Neg_Two_to_M3
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+};;
+
+{ .mbb
+ nop.m 999
+(p6) br.cond.spnt SINCOS_SMALL_R // Branch if |r| < 1/4
+ br.cond.sptk SINCOS_NORMAL_R ;; // Branch if 1/4 <= |r| < pi/4
+}
+
+LOCAL_LIBM_END(__libm_callout_2)
+
+.type __libm_pi_by_2_reduce#,@function
+.global __libm_pi_by_2_reduce#
+
diff --git a/libc/sysdeps/ia64/fpu/libm_sincosf.S b/libc/sysdeps/ia64/fpu/libm_sincosf.S
new file mode 100644
index 000000000..cf23356ef
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_sincosf.S
@@ -0,0 +1,745 @@
+.file "libm_sincosf.s"
+
+
+// Copyright (c) 2002 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/01/02 Initial version
+// 02/18/02 Large arguments processing routine is excluded.
+// External interface entry points are added
+// 02/26/02 Added temporary return of results in r8, r9
+// 03/13/02 Corrected restore of predicate registers
+// 03/19/02 Added stack unwind around call to __libm_cisf_large
+// 09/05/02 Work range is widened by reduction strengthen (2 parts of Pi/16)
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 02/11/04 cisf is moved to the separate file.
+// 03/31/05 Reformatted delimiters between data tables
+
+// API
+//==============================================================
+// 1) void sincosf(float, float*s, float*c)
+// 2) __libm_sincosf - internal LIBM function, that accepts
+// argument in f8 and returns cosine through f8, sine through f9
+
+//
+// Overview of operation
+//==============================================================
+//
+// Step 1
+// ======
+// Reduce x to region -1/2*pi/2^k ===== 0 ===== +1/2*pi/2^k where k=4
+// divide x by pi/2^k.
+// Multiply by 2^k/pi.
+// nfloat = Round result to integer (round-to-nearest)
+//
+// r = x - nfloat * pi/2^k
+// Do this as (x - nfloat * HIGH(pi/2^k)) - nfloat * LOW(pi/2^k) for increased accuracy.
+// pi/2^k is stored as two numbers that when added make pi/2^k.
+// pi/2^k = HIGH(pi/2^k) + LOW(pi/2^k)
+// HIGH part is rounded to zero, LOW - to nearest
+//
+// x = (nfloat * pi/2^k) + r
+// r is small enough that we can use a polynomial approximation
+// and is referred to as the reduced argument.
+//
+// Step 3
+// ======
+// Take the unreduced part and remove the multiples of 2pi.
+// So nfloat = nfloat (with lower k+1 bits cleared) + lower k+1 bits
+//
+// nfloat (with lower k+1 bits cleared) is a multiple of 2^(k+1)
+// N * 2^(k+1)
+// nfloat * pi/2^k = N * 2^(k+1) * pi/2^k + (lower k+1 bits) * pi/2^k
+// nfloat * pi/2^k = N * 2 * pi + (lower k+1 bits) * pi/2^k
+// nfloat * pi/2^k = N2pi + M * pi/2^k
+//
+//
+// Sin(x) = Sin((nfloat * pi/2^k) + r)
+// = Sin(nfloat * pi/2^k) * Cos(r) + Cos(nfloat * pi/2^k) * Sin(r)
+//
+// Sin(nfloat * pi/2^k) = Sin(N2pi + Mpi/2^k)
+// = Sin(N2pi)Cos(Mpi/2^k) + Cos(N2pi)Sin(Mpi/2^k)
+// = Sin(Mpi/2^k)
+//
+// Cos(nfloat * pi/2^k) = Cos(N2pi + Mpi/2^k)
+// = Cos(N2pi)Cos(Mpi/2^k) + Sin(N2pi)Sin(Mpi/2^k)
+// = Cos(Mpi/2^k)
+//
+// Sin(x) = Sin(Mpi/2^k) Cos(r) + Cos(Mpi/2^k) Sin(r)
+//
+//
+// Step 4
+// ======
+// 0 <= M < 2^(k+1)
+// There are 2^(k+1) Sin entries in a table.
+// There are 2^(k+1) Cos entries in a table.
+//
+// Get Sin(Mpi/2^k) and Cos(Mpi/2^k) by table lookup.
+//
+//
+// Step 5
+// ======
+// Calculate Cos(r) and Sin(r) by polynomial approximation.
+//
+// Cos(r) = 1 + r^2 q1 + r^4 q2 = Series for Cos
+// Sin(r) = r + r^3 p1 + r^5 p2 = Series for Sin
+//
+// and the coefficients q1, q2 and p1, p2 are stored in a table
+//
+//
+// Calculate
+// Sin(x) = Sin(Mpi/2^k) Cos(r) + Cos(Mpi/2^k) Sin(r)
+//
+// as follows
+//
+// S[m] = Sin(Mpi/2^k) and C[m] = Cos(Mpi/2^k)
+// rsq = r*r
+//
+//
+// P = p1 + r^2p2
+// Q = q1 + r^2q2
+//
+// rcub = r * rsq
+// Sin(r) = r + rcub * P
+// = r + r^3p1 + r^5p2 = Sin(r)
+//
+// P = r + rcub * P
+//
+// Answer = S[m] Cos(r) + C[m] P
+//
+// Cos(r) = 1 + rsq Q
+// Cos(r) = 1 + r^2 Q
+// Cos(r) = 1 + r^2 (q1 + r^2q2)
+// Cos(r) = 1 + r^2q1 + r^4q2
+//
+// S[m] Cos(r) = S[m](1 + rsq Q)
+// S[m] Cos(r) = S[m] + S[m] rsq Q
+// S[m] Cos(r) = S[m] + s_rsq Q
+// Q = S[m] + s_rsq Q
+//
+// Then,
+//
+// Answer = Q + C[m] P
+
+
+// Registers used
+//==============================================================
+// general input registers:
+// r14 -> r19
+// r32 -> r49
+
+// predicate registers used:
+// p6 -> p14
+
+// floating-point registers used
+// f9 -> f15
+// f32 -> f100
+
+// Assembly macros
+//==============================================================
+
+cisf_Arg = f8
+
+cisf_Sin_res = f9
+cisf_Cos_res = f8
+
+
+cisf_NORM_f8 = f10
+cisf_W = f11
+cisf_int_Nfloat = f12
+cisf_Nfloat = f13
+
+cisf_r = f14
+cisf_r_exact = f68
+cisf_rsq = f15
+cisf_rcub = f32
+
+cisf_Inv_Pi_by_16 = f33
+cisf_Pi_by_16_hi = f34
+cisf_Pi_by_16_lo = f35
+
+cisf_Inv_Pi_by_64 = f36
+cisf_Pi_by_64_hi = f37
+cisf_Pi_by_64_lo = f38
+
+
+cisf_P1 = f39
+cisf_Q1 = f40
+cisf_P2 = f41
+cisf_Q2 = f42
+cisf_P3 = f43
+cisf_Q3 = f44
+cisf_P4 = f45
+cisf_Q4 = f46
+
+cisf_P_temp1 = f47
+cisf_P_temp2 = f48
+
+cisf_Q_temp1 = f49
+cisf_Q_temp2 = f50
+
+cisf_P = f51
+
+cisf_SIG_INV_PI_BY_16_2TO61 = f52
+cisf_RSHF_2TO61 = f53
+cisf_RSHF = f54
+cisf_2TOM61 = f55
+cisf_NFLOAT = f56
+cisf_W_2TO61_RSH = f57
+
+cisf_tmp = f58
+
+cisf_Sm_sin = f59
+cisf_Cm_sin = f60
+
+cisf_Sm_cos = f61
+cisf_Cm_cos = f62
+
+cisf_srsq_sin = f63
+cisf_srsq_cos = f64
+
+cisf_Q_sin = f65
+cisf_Q_cos = f66
+cisf_Q = f67
+
+/////////////////////////////////////////////////////////////
+
+cisf_pResSin = r33
+cisf_pResCos = r34
+
+cisf_exp_limit = r35
+cisf_r_signexp = r36
+cisf_AD_beta_table = r37
+cisf_r_sincos = r38
+
+cisf_r_exp = r39
+cisf_r_17_ones = r40
+
+cisf_GR_sig_inv_pi_by_16 = r14
+cisf_GR_rshf_2to61 = r15
+cisf_GR_rshf = r16
+cisf_GR_exp_2tom61 = r17
+cisf_GR_n = r18
+
+cisf_GR_n_sin = r19
+cisf_GR_m_sin = r41
+cisf_GR_32m_sin = r41
+
+cisf_GR_n_cos = r42
+cisf_GR_m_cos = r43
+cisf_GR_32m_cos = r43
+
+cisf_AD_2_sin = r44
+cisf_AD_2_cos = r45
+
+cisf_gr_tmp = r46
+GR_SAVE_B0 = r47
+GR_SAVE_GP = r48
+rB0_SAVED = r49
+GR_SAVE_PFS = r50
+GR_SAVE_PR = r51
+cisf_AD_1 = r52
+
+RODATA
+
+.align 16
+// Pi/16 parts
+LOCAL_OBJECT_START(double_cisf_pi)
+ data8 0xC90FDAA22168C234, 0x00003FFC // pi/16 1st part
+ data8 0xC4C6628B80DC1CD1, 0x00003FBC // pi/16 2nd part
+LOCAL_OBJECT_END(double_cisf_pi)
+
+// Coefficients for polynomials
+LOCAL_OBJECT_START(double_cisf_pq_k4)
+ data8 0x3F810FABB668E9A2 // P2
+ data8 0x3FA552E3D6DE75C9 // Q2
+ data8 0xBFC555554447BC7F // P1
+ data8 0xBFDFFFFFC447610A // Q1
+LOCAL_OBJECT_END(double_cisf_pq_k4)
+
+// Sincos table (S[m], C[m])
+LOCAL_OBJECT_START(double_sin_cos_beta_k4)
+ data8 0x0000000000000000 // sin ( 0 Pi / 16 )
+ data8 0x3FF0000000000000 // cos ( 0 Pi / 16 )
+//
+ data8 0x3FC8F8B83C69A60B // sin ( 1 Pi / 16 )
+ data8 0x3FEF6297CFF75CB0 // cos ( 1 Pi / 16 )
+//
+ data8 0x3FD87DE2A6AEA963 // sin ( 2 Pi / 16 )
+ data8 0x3FED906BCF328D46 // cos ( 2 Pi / 16 )
+//
+ data8 0x3FE1C73B39AE68C8 // sin ( 3 Pi / 16 )
+ data8 0x3FEA9B66290EA1A3 // cos ( 3 Pi / 16 )
+//
+ data8 0x3FE6A09E667F3BCD // sin ( 4 Pi / 16 )
+ data8 0x3FE6A09E667F3BCD // cos ( 4 Pi / 16 )
+//
+ data8 0x3FEA9B66290EA1A3 // sin ( 5 Pi / 16 )
+ data8 0x3FE1C73B39AE68C8 // cos ( 5 Pi / 16 )
+//
+ data8 0x3FED906BCF328D46 // sin ( 6 Pi / 16 )
+ data8 0x3FD87DE2A6AEA963 // cos ( 6 Pi / 16 )
+//
+ data8 0x3FEF6297CFF75CB0 // sin ( 7 Pi / 16 )
+ data8 0x3FC8F8B83C69A60B // cos ( 7 Pi / 16 )
+//
+ data8 0x3FF0000000000000 // sin ( 8 Pi / 16 )
+ data8 0x0000000000000000 // cos ( 8 Pi / 16 )
+//
+ data8 0x3FEF6297CFF75CB0 // sin ( 9 Pi / 16 )
+ data8 0xBFC8F8B83C69A60B // cos ( 9 Pi / 16 )
+//
+ data8 0x3FED906BCF328D46 // sin ( 10 Pi / 16 )
+ data8 0xBFD87DE2A6AEA963 // cos ( 10 Pi / 16 )
+//
+ data8 0x3FEA9B66290EA1A3 // sin ( 11 Pi / 16 )
+ data8 0xBFE1C73B39AE68C8 // cos ( 11 Pi / 16 )
+//
+ data8 0x3FE6A09E667F3BCD // sin ( 12 Pi / 16 )
+ data8 0xBFE6A09E667F3BCD // cos ( 12 Pi / 16 )
+//
+ data8 0x3FE1C73B39AE68C8 // sin ( 13 Pi / 16 )
+ data8 0xBFEA9B66290EA1A3 // cos ( 13 Pi / 16 )
+//
+ data8 0x3FD87DE2A6AEA963 // sin ( 14 Pi / 16 )
+ data8 0xBFED906BCF328D46 // cos ( 14 Pi / 16 )
+//
+ data8 0x3FC8F8B83C69A60B // sin ( 15 Pi / 16 )
+ data8 0xBFEF6297CFF75CB0 // cos ( 15 Pi / 16 )
+//
+ data8 0x0000000000000000 // sin ( 16 Pi / 16 )
+ data8 0xBFF0000000000000 // cos ( 16 Pi / 16 )
+//
+ data8 0xBFC8F8B83C69A60B // sin ( 17 Pi / 16 )
+ data8 0xBFEF6297CFF75CB0 // cos ( 17 Pi / 16 )
+//
+ data8 0xBFD87DE2A6AEA963 // sin ( 18 Pi / 16 )
+ data8 0xBFED906BCF328D46 // cos ( 18 Pi / 16 )
+//
+ data8 0xBFE1C73B39AE68C8 // sin ( 19 Pi / 16 )
+ data8 0xBFEA9B66290EA1A3 // cos ( 19 Pi / 16 )
+//
+ data8 0xBFE6A09E667F3BCD // sin ( 20 Pi / 16 )
+ data8 0xBFE6A09E667F3BCD // cos ( 20 Pi / 16 )
+//
+ data8 0xBFEA9B66290EA1A3 // sin ( 21 Pi / 16 )
+ data8 0xBFE1C73B39AE68C8 // cos ( 21 Pi / 16 )
+//
+ data8 0xBFED906BCF328D46 // sin ( 22 Pi / 16 )
+ data8 0xBFD87DE2A6AEA963 // cos ( 22 Pi / 16 )
+//
+ data8 0xBFEF6297CFF75CB0 // sin ( 23 Pi / 16 )
+ data8 0xBFC8F8B83C69A60B // cos ( 23 Pi / 16 )
+//
+ data8 0xBFF0000000000000 // sin ( 24 Pi / 16 )
+ data8 0x0000000000000000 // cos ( 24 Pi / 16 )
+//
+ data8 0xBFEF6297CFF75CB0 // sin ( 25 Pi / 16 )
+ data8 0x3FC8F8B83C69A60B // cos ( 25 Pi / 16 )
+//
+ data8 0xBFED906BCF328D46 // sin ( 26 Pi / 16 )
+ data8 0x3FD87DE2A6AEA963 // cos ( 26 Pi / 16 )
+//
+ data8 0xBFEA9B66290EA1A3 // sin ( 27 Pi / 16 )
+ data8 0x3FE1C73B39AE68C8 // cos ( 27 Pi / 16 )
+//
+ data8 0xBFE6A09E667F3BCD // sin ( 28 Pi / 16 )
+ data8 0x3FE6A09E667F3BCD // cos ( 28 Pi / 16 )
+//
+ data8 0xBFE1C73B39AE68C8 // sin ( 29 Pi / 16 )
+ data8 0x3FEA9B66290EA1A3 // cos ( 29 Pi / 16 )
+//
+ data8 0xBFD87DE2A6AEA963 // sin ( 30 Pi / 16 )
+ data8 0x3FED906BCF328D46 // cos ( 30 Pi / 16 )
+//
+ data8 0xBFC8F8B83C69A60B // sin ( 31 Pi / 16 )
+ data8 0x3FEF6297CFF75CB0 // cos ( 31 Pi / 16 )
+//
+ data8 0x0000000000000000 // sin ( 32 Pi / 16 )
+ data8 0x3FF0000000000000 // cos ( 32 Pi / 16 )
+LOCAL_OBJECT_END(double_sin_cos_beta_k4)
+
+.section .text
+
+GLOBAL_IEEE754_ENTRY(sincosf)
+// cis_GR_sig_inv_pi_by_16 = significand of 16/pi
+{ .mlx
+ alloc GR_SAVE_PFS = ar.pfs, 0, 21, 0, 0
+ movl cisf_GR_sig_inv_pi_by_16 = 0xA2F9836E4E44152A // 16/pi signd
+
+}
+// cis_GR_rshf_2to61 = 1.1000 2^(63+63-2)
+{ .mlx
+ addl cisf_AD_1 = @ltoff(double_cisf_pi), gp
+ movl cisf_GR_rshf_2to61 = 0x47b8000000000000 // 1.1 2^(63+63-2)
+};;
+
+{ .mfi
+ ld8 cisf_AD_1 = [cisf_AD_1]
+ fnorm.s1 cisf_NORM_f8 = cisf_Arg
+ cmp.eq p13, p14 = r0, r0 // p13 set for sincos
+}
+// cis_GR_exp_2tom61 = exponent of scaling factor 2^-61
+{ .mib
+ mov cisf_GR_exp_2tom61 = 0xffff-61
+ nop.i 0
+ br.cond.sptk _CISF_COMMON
+};;
+GLOBAL_IEEE754_END(sincosf)
+
+GLOBAL_LIBM_ENTRY(__libm_sincosf)
+{ .mlx
+// cisf_GR_sig_inv_pi_by_16 = significand of 16/pi
+ alloc GR_SAVE_PFS = ar.pfs,0,21,0,0
+ movl cisf_GR_sig_inv_pi_by_16 = 0xA2F9836E4E44152A
+}
+// cisf_GR_rshf_2to61 = 1.1000 2^(63+63-2)
+{ .mlx
+ addl cisf_AD_1 = @ltoff(double_cisf_pi), gp
+ movl cisf_GR_rshf_2to61 = 0x47b8000000000000
+};;
+
+// p14 set for __libm_sincos and cis
+{ .mfi
+ ld8 cisf_AD_1 = [cisf_AD_1]
+ fnorm.s1 cisf_NORM_f8 = cisf_Arg
+ cmp.eq p14, p13 = r0, r0
+}
+// cisf_GR_exp_2tom61 = exponent of scaling factor 2^-61
+{ .mib
+ mov cisf_GR_exp_2tom61 = 0xffff-61
+ nop.i 0
+ nop.b 0
+};;
+
+_CISF_COMMON:
+// Form two constants we need
+// 16/pi * 2^-2 * 2^63, scaled by 2^61 since we just loaded the significand
+// 1.1000...000 * 2^(63+63-2) to right shift int(W) into the low significand
+// fcmp used to set denormal, and invalid on snans
+{ .mfi
+ setf.sig cisf_SIG_INV_PI_BY_16_2TO61 = cisf_GR_sig_inv_pi_by_16
+ fclass.m p6,p0 = cisf_Arg, 0xe7//if x=0,inf,nan
+ addl cisf_gr_tmp = -1, r0
+}
+// cisf_GR_rshf = 1.1000 2^63 for right shift
+{ .mlx
+ setf.d cisf_RSHF_2TO61 = cisf_GR_rshf_2to61
+ movl cisf_GR_rshf = 0x43e8000000000000
+};;
+
+// Form another constant
+// 2^-61 for scaling Nfloat
+// 0x10017 is register_bias + 24.
+// So if f8 >= 2^24, go to large args routine
+{ .mmi
+ getf.exp cisf_r_signexp = cisf_Arg
+ setf.exp cisf_2TOM61 = cisf_GR_exp_2tom61
+ mov cisf_exp_limit = 0x10017
+};;
+
+// Load the two pieces of pi/16
+// Form another constant
+// 1.1000...000 * 2^63, the right shift constant
+{ .mmb
+ ldfe cisf_Pi_by_16_hi = [cisf_AD_1],16
+ setf.d cisf_RSHF = cisf_GR_rshf
+(p6) br.cond.spnt _CISF_SPECIAL_ARGS
+};;
+
+{ .mmi
+ ldfe cisf_Pi_by_16_lo = [cisf_AD_1],16
+ setf.sig cisf_tmp = cisf_gr_tmp //constant for inexact set
+ nop.i 0
+};;
+
+// Start loading P, Q coefficients
+{ .mmi
+ ldfpd cisf_P2,cisf_Q2 = [cisf_AD_1],16
+ nop.m 0
+ dep.z cisf_r_exp = cisf_r_signexp, 0, 17
+};;
+
+// p10 is true if we must call routines to handle larger arguments
+// p10 is true if f8 exp is >= 0x10017
+{ .mmb
+ ldfpd cisf_P1,cisf_Q1 = [cisf_AD_1], 16
+ cmp.ge p10, p0 = cisf_r_exp, cisf_exp_limit
+(p10) br.cond.spnt _CISF_LARGE_ARGS // go to |x| >= 2^24 path
+};;
+
+// cisf_W = x * cisf_Inv_Pi_by_16
+// Multiply x by scaled 16/pi and add large const to shift integer part of W to
+// rightmost bits of significand
+{ .mfi
+ nop.m 0
+ fma.s1 cisf_W_2TO61_RSH = cisf_NORM_f8,cisf_SIG_INV_PI_BY_16_2TO61,cisf_RSHF_2TO61
+ nop.i 0
+};;
+
+// cisf_NFLOAT = Round_Int_Nearest(cisf_W)
+{ .mfi
+ nop.m 0
+ fms.s1 cisf_NFLOAT = cisf_W_2TO61_RSH,cisf_2TOM61,cisf_RSHF
+ nop.i 0
+};;
+
+// N = (int)cisf_int_Nfloat
+{ .mfi
+ getf.sig cisf_GR_n = cisf_W_2TO61_RSH
+ nop.f 0
+ nop.i 0
+};;
+
+// Add 2^(k-1) (which is in cisf_r_sincos) to N
+// cisf_r = -cisf_Nfloat * cisf_Pi_by_16_hi + x
+// cisf_r = cisf_r -cisf_Nfloat * cisf_Pi_by_16_lo
+{ .mfi
+ add cisf_GR_n_cos = 0x8, cisf_GR_n
+ fnma.s1 cisf_r = cisf_NFLOAT, cisf_Pi_by_16_hi, cisf_NORM_f8
+ nop.i 0
+};;
+
+//Get M (least k+1 bits of N)
+{ .mmi
+ and cisf_GR_m_sin = 0x1f,cisf_GR_n
+ and cisf_GR_m_cos = 0x1f,cisf_GR_n_cos
+ nop.i 0
+};;
+
+{ .mmi
+ shladd cisf_AD_2_cos = cisf_GR_m_cos,4, cisf_AD_1
+ shladd cisf_AD_2_sin = cisf_GR_m_sin,4, cisf_AD_1
+ nop.i 0
+};;
+
+// den. input to set uflow
+{ .mmf
+ ldfpd cisf_Sm_sin, cisf_Cm_sin = [cisf_AD_2_sin]
+ ldfpd cisf_Sm_cos, cisf_Cm_cos = [cisf_AD_2_cos]
+ fclass.m.unc p10,p0 = cisf_Arg,0x0b
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 cisf_rsq = cisf_r, cisf_r, f0 // get r^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s0 cisf_tmp = cisf_tmp,cisf_tmp // inexact flag
+ nop.i 0
+};;
+
+{ .mmf
+ nop.m 0
+ nop.m 0
+ fnma.s1 cisf_r_exact = cisf_NFLOAT, cisf_Pi_by_16_lo, cisf_r
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 cisf_P = cisf_rsq, cisf_P2, cisf_P1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 cisf_Q = cisf_rsq, cisf_Q2, cisf_Q1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 cisf_rcub = cisf_r_exact, cisf_rsq // get r^3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 cisf_srsq_sin = cisf_Sm_sin,cisf_rsq
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 cisf_srsq_cos = cisf_Sm_cos,cisf_rsq
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 cisf_P = cisf_rcub,cisf_P,cisf_r_exact
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 cisf_Q_sin = cisf_srsq_sin,cisf_Q, cisf_Sm_sin
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 cisf_Q_cos = cisf_srsq_cos,cisf_Q, cisf_Sm_cos
+ nop.i 0
+};;
+
+// If den. arg, force underflow to be set
+{ .mfi
+ nop.m 0
+(p10) fmpy.s.s0 cisf_tmp = cisf_Arg,cisf_Arg
+ nop.i 0
+};;
+
+//Final sin
+{ .mfi
+ nop.m 0
+ fma.s.s0 cisf_Sin_res = cisf_Cm_sin, cisf_P, cisf_Q_sin
+ nop.i 0
+}
+//Final cos
+{ .mfb
+ nop.m 0
+ fma.s.s0 cisf_Cos_res = cisf_Cm_cos, cisf_P, cisf_Q_cos
+(p14) br.cond.sptk _CISF_RETURN //com. exit for __libm_sincos and cis main path
+};;
+
+{ .mmb
+ stfs [cisf_pResSin] = cisf_Sin_res
+ stfs [cisf_pResCos] = cisf_Cos_res
+ br.ret.sptk b0 // common exit for sincos main path
+};;
+
+_CISF_SPECIAL_ARGS:
+// sinf(+/-0) = +/-0
+// sinf(Inf) = NaN
+// sinf(NaN) = NaN
+{ .mfi
+ nop.m 999
+ fma.s.s0 cisf_Sin_res = cisf_Arg, f0, f0 // sinf(+/-0,NaN,Inf)
+ nop.i 999
+};;
+
+// cosf(+/-0) = 1.0
+// cosf(Inf) = NaN
+// cosf(NaN) = NaN
+{ .mfb
+ nop.m 999
+ fma.s.s0 cisf_Cos_res = cisf_Arg, f0, f1 // cosf(+/-0,NaN,Inf)
+(p14) br.cond.sptk _CISF_RETURN //spec exit for __libm_sincos and cis main path
+};;
+
+{ .mmb
+ stfs [cisf_pResSin] = cisf_Sin_res
+ stfs [cisf_pResCos] = cisf_Cos_res
+ br.ret.sptk b0 // special exit for sincos main path
+};;
+
+ // exit for sincos
+ // NOTE! r8 and r9 used only because of compiler issue
+ // connected with float point complex function arguments pass
+ // After fix of this issue this operations can be deleted
+_CISF_RETURN:
+{ .mmb
+ getf.s r8 = cisf_Cos_res
+ getf.s r9 = cisf_Sin_res
+ br.ret.sptk b0 // exit for sincos
+};;
+GLOBAL_LIBM_END(__libm_sincosf)
+
+//// |x| > 2^24 path ///////
+.proc _CISF_LARGE_ARGS
+_CISF_LARGE_ARGS:
+.prologue
+{ .mfi
+ nop.m 0
+ nop.f 0
+.save ar.pfs, GR_SAVE_PFS
+ mov GR_SAVE_PFS = ar.pfs
+};;
+
+{ .mfi
+ mov GR_SAVE_GP = gp
+ nop.f 0
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0 = b0
+};;
+
+.body
+// Call of huge arguments sincos
+{ .mib
+ nop.m 0
+ mov GR_SAVE_PR = pr
+ br.call.sptk b0 = __libm_sincos_large
+};;
+
+{ .mfi
+ mov gp = GR_SAVE_GP
+ nop.f 0
+ mov pr = GR_SAVE_PR, 0x1fffe
+}
+;;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ mov b0 = GR_SAVE_B0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s.s0 cisf_Cos_res = cisf_Cos_res, f1, f0
+ mov ar.pfs = GR_SAVE_PFS
+}
+// exit for |x| > 2^24 path (__libm_sincos and cis)
+{ .mfb
+ nop.m 0
+ fma.s.s0 cisf_Sin_res = cisf_Sin_res, f1, f0
+(p14) br.cond.sptk _CISF_RETURN
+};;
+
+{ .mmb
+ stfs [cisf_pResSin] = cisf_Sin_res
+ stfs [cisf_pResCos] = cisf_Cos_res
+ br.ret.sptk b0 // exit for sincos |x| > 2^24 path
+};;
+
+.endp _CISF_LARGE_ARGS
+
+.type __libm_sincos_large#,@function
+.global __libm_sincos_large#
+
diff --git a/libc/sysdeps/ia64/fpu/libm_sincosl.S b/libc/sysdeps/ia64/fpu/libm_sincosl.S
new file mode 100644
index 000000000..1d89ff4bd
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_sincosl.S
@@ -0,0 +1,2528 @@
+.file "libm_sincosl.s"
+
+
+// Copyright (c) 2000 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 05/13/02 Initial version of sincosl (based on libm's sinl and cosl)
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+// 10/13/03 Corrected .file name
+// 02/11/04 cisl is moved to the separate file.
+// 10/26/04 Avoided using r14-31 as scratch so not clobbered by dynamic loader
+//
+//*********************************************************************
+//
+// Function: Combined sincosl routine with 3 different API's
+//
+// API's
+//==============================================================
+// 1) void sincosl(long double, long double*s, long double*c)
+// 2) __libm_sincosl - internal LIBM function, that accepts
+// argument in f8 and returns cosine through f8, sine through f9
+//
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input x and cosl return value),
+// f9 (sinl returned)
+// f32-f121
+//
+// General Purpose Registers:
+// r32-r61
+//
+// Predicate Registers: p6-p15
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// Denormal fault raised on denormal inputs
+// Overflow exceptions do not occur
+// Underflow exceptions raised when appropriate for sincosl
+// (No specialized error handling for this routine)
+// Inexact raised when appropriate by algorithm
+//
+// sincosl(SNaN) = QNaN, QNaN
+// sincosl(QNaN) = QNaN, QNaN
+// sincosl(inf) = QNaN, QNaN
+// sincosl(+/-0) = +/-0, 1
+//
+//*********************************************************************
+//
+// Mathematical Description
+// ========================
+//
+// The computation of FSIN and FCOS performed in parallel.
+//
+// Arg = N pi/2 + alpha, |alpha| <= pi/4.
+//
+// cosl( Arg ) = sinl( (N+1) pi/2 + alpha ),
+//
+// therefore, the code for computing sine will produce cosine as long
+// as 1 is added to N immediately after the argument reduction
+// process.
+//
+// Let M = N if sine
+// N+1 if cosine.
+//
+// Now, given
+//
+// Arg = M pi/2 + alpha, |alpha| <= pi/4,
+//
+// let I = M mod 4, or I be the two lsb of M when M is represented
+// as 2's complement. I = [i_0 i_1]. Then
+//
+// sinl( Arg ) = (-1)^i_0 sinl( alpha ) if i_1 = 0,
+// = (-1)^i_0 cosl( alpha ) if i_1 = 1.
+//
+// For example:
+// if M = -1, I = 11
+// sin ((-pi/2 + alpha) = (-1) cos (alpha)
+// if M = 0, I = 00
+// sin (alpha) = sin (alpha)
+// if M = 1, I = 01
+// sin (pi/2 + alpha) = cos (alpha)
+// if M = 2, I = 10
+// sin (pi + alpha) = (-1) sin (alpha)
+// if M = 3, I = 11
+// sin ((3/2)pi + alpha) = (-1) cos (alpha)
+//
+// The value of alpha is obtained by argument reduction and
+// represented by two working precision numbers r and c where
+//
+// alpha = r + c accurately.
+//
+// The reduction method is described in a previous write up.
+// The argument reduction scheme identifies 4 cases. For Cases 2
+// and 4, because |alpha| is small, sinl(r+c) and cosl(r+c) can be
+// computed very easily by 2 or 3 terms of the Taylor series
+// expansion as follows:
+//
+// Case 2:
+// -------
+//
+// sinl(r + c) = r + c - r^3/6 accurately
+// cosl(r + c) = 1 - 2^(-67) accurately
+//
+// Case 4:
+// -------
+//
+// sinl(r + c) = r + c - r^3/6 + r^5/120 accurately
+// cosl(r + c) = 1 - r^2/2 + r^4/24 accurately
+//
+// The only cases left are Cases 1 and 3 of the argument reduction
+// procedure. These two cases will be merged since after the
+// argument is reduced in either cases, we have the reduced argument
+// represented as r + c and that the magnitude |r + c| is not small
+// enough to allow the usage of a very short approximation.
+//
+// The required calculation is either
+//
+// sinl(r + c) = sinl(r) + correction, or
+// cosl(r + c) = cosl(r) + correction.
+//
+// Specifically,
+//
+// sinl(r + c) = sinl(r) + c sin'(r) + O(c^2)
+// = sinl(r) + c cos (r) + O(c^2)
+// = sinl(r) + c(1 - r^2/2) accurately.
+// Similarly,
+//
+// cosl(r + c) = cosl(r) - c sinl(r) + O(c^2)
+// = cosl(r) - c(r - r^3/6) accurately.
+//
+// We therefore concentrate on accurately calculating sinl(r) and
+// cosl(r) for a working-precision number r, |r| <= pi/4 to within
+// 0.1% or so.
+//
+// The greatest challenge of this task is that the second terms of
+// the Taylor series
+//
+// r - r^3/3! + r^r/5! - ...
+//
+// and
+//
+// 1 - r^2/2! + r^4/4! - ...
+//
+// are not very small when |r| is close to pi/4 and the rounding
+// errors will be a concern if simple polynomial accumulation is
+// used. When |r| < 2^-3, however, the second terms will be small
+// enough (6 bits or so of right shift) that a normal Horner
+// recurrence suffices. Hence there are two cases that we consider
+// in the accurate computation of sinl(r) and cosl(r), |r| <= pi/4.
+//
+// Case small_r: |r| < 2^(-3)
+// --------------------------
+//
+// Since Arg = M pi/4 + r + c accurately, and M mod 4 is [i_0 i_1],
+// we have
+//
+// sinl(Arg) = (-1)^i_0 * sinl(r + c) if i_1 = 0
+// = (-1)^i_0 * cosl(r + c) if i_1 = 1
+//
+// can be accurately approximated by
+//
+// sinl(Arg) = (-1)^i_0 * [sinl(r) + c] if i_1 = 0
+// = (-1)^i_0 * [cosl(r) - c*r] if i_1 = 1
+//
+// because |r| is small and thus the second terms in the correction
+// are unneccessary.
+//
+// Finally, sinl(r) and cosl(r) are approximated by polynomials of
+// moderate lengths.
+//
+// sinl(r) = r + S_1 r^3 + S_2 r^5 + ... + S_5 r^11
+// cosl(r) = 1 + C_1 r^2 + C_2 r^4 + ... + C_5 r^10
+//
+// We can make use of predicates to selectively calculate
+// sinl(r) or cosl(r) based on i_1.
+//
+// Case normal_r: 2^(-3) <= |r| <= pi/4
+// ------------------------------------
+//
+// This case is more likely than the previous one if one considers
+// r to be uniformly distributed in [-pi/4 pi/4]. Again,
+//
+// sinl(Arg) = (-1)^i_0 * sinl(r + c) if i_1 = 0
+// = (-1)^i_0 * cosl(r + c) if i_1 = 1.
+//
+// Because |r| is now larger, we need one extra term in the
+// correction. sinl(Arg) can be accurately approximated by
+//
+// sinl(Arg) = (-1)^i_0 * [sinl(r) + c(1-r^2/2)] if i_1 = 0
+// = (-1)^i_0 * [cosl(r) - c*r*(1 - r^2/6)] i_1 = 1.
+//
+// Finally, sinl(r) and cosl(r) are approximated by polynomials of
+// moderate lengths.
+//
+// sinl(r) = r + PP_1_hi r^3 + PP_1_lo r^3 +
+// PP_2 r^5 + ... + PP_8 r^17
+//
+// cosl(r) = 1 + QQ_1 r^2 + QQ_2 r^4 + ... + QQ_8 r^16
+//
+// where PP_1_hi is only about 16 bits long and QQ_1 is -1/2.
+// The crux in accurate computation is to calculate
+//
+// r + PP_1_hi r^3 or 1 + QQ_1 r^2
+//
+// accurately as two pieces: U_hi and U_lo. The way to achieve this
+// is to obtain r_hi as a 10 sig. bit number that approximates r to
+// roughly 8 bits or so of accuracy. (One convenient way is
+//
+// r_hi := frcpa( frcpa( r ) ).)
+//
+// This way,
+//
+// r + PP_1_hi r^3 = r + PP_1_hi r_hi^3 +
+// PP_1_hi (r^3 - r_hi^3)
+// = [r + PP_1_hi r_hi^3] +
+// [PP_1_hi (r - r_hi)
+// (r^2 + r_hi r + r_hi^2) ]
+// = U_hi + U_lo
+//
+// Since r_hi is only 10 bit long and PP_1_hi is only 16 bit long,
+// PP_1_hi * r_hi^3 is only at most 46 bit long and thus computed
+// exactly. Furthermore, r and PP_1_hi r_hi^3 are of opposite sign
+// and that there is no more than 8 bit shift off between r and
+// PP_1_hi * r_hi^3. Hence the sum, U_hi, is representable and thus
+// calculated without any error. Finally, the fact that
+//
+// |U_lo| <= 2^(-8) |U_hi|
+//
+// says that U_hi + U_lo is approximating r + PP_1_hi r^3 to roughly
+// 8 extra bits of accuracy.
+//
+// Similarly,
+//
+// 1 + QQ_1 r^2 = [1 + QQ_1 r_hi^2] +
+// [QQ_1 (r - r_hi)(r + r_hi)]
+// = U_hi + U_lo.
+//
+// Summarizing, we calculate r_hi = frcpa( frcpa( r ) ).
+//
+// If i_1 = 0, then
+//
+// U_hi := r + PP_1_hi * r_hi^3
+// U_lo := PP_1_hi * (r - r_hi) * (r^2 + r*r_hi + r_hi^2)
+// poly := PP_1_lo r^3 + PP_2 r^5 + ... + PP_8 r^17
+// correction := c * ( 1 + C_1 r^2 )
+//
+// Else ...i_1 = 1
+//
+// U_hi := 1 + QQ_1 * r_hi * r_hi
+// U_lo := QQ_1 * (r - r_hi) * (r + r_hi)
+// poly := QQ_2 * r^4 + QQ_3 * r^6 + ... + QQ_8 r^16
+// correction := -c * r * (1 + S_1 * r^2)
+//
+// End
+//
+// Finally,
+//
+// V := poly + ( U_lo + correction )
+//
+// / U_hi + V if i_0 = 0
+// result := |
+// \ (-U_hi) - V if i_0 = 1
+//
+// It is important that in the last step, negation of U_hi is
+// performed prior to the subtraction which is to be performed in
+// the user-set rounding mode.
+//
+//
+// Algorithmic Description
+// =======================
+//
+// The argument reduction algorithm shares the same code between FSIN and FCOS.
+// The argument reduction description given
+// previously is repeated below.
+//
+//
+// Step 0. Initialization.
+//
+// Step 1. Check for exceptional and special cases.
+//
+// * If Arg is +-0, +-inf, NaN, NaT, go to Step 10 for special
+// handling.
+// * If |Arg| < 2^24, go to Step 2 for reduction of moderate
+// arguments. This is the most likely case.
+// * If |Arg| < 2^63, go to Step 8 for pre-reduction of large
+// arguments.
+// * If |Arg| >= 2^63, go to Step 10 for special handling.
+//
+// Step 2. Reduction of moderate arguments.
+//
+// If |Arg| < pi/4 ...quick branch
+// N_fix := N_inc (integer)
+// r := Arg
+// c := 0.0
+// Branch to Step 4, Case_1_complete
+// Else ...cf. argument reduction
+// N := Arg * two_by_PI (fp)
+// N_fix := fcvt.fx( N ) (int)
+// N := fcvt.xf( N_fix )
+// N_fix := N_fix + N_inc
+// s := Arg - N * P_1 (first piece of pi/2)
+// w := -N * P_2 (second piece of pi/2)
+//
+// If |s| >= 2^(-33)
+// go to Step 3, Case_1_reduce
+// Else
+// go to Step 7, Case_2_reduce
+// Endif
+// Endif
+//
+// Step 3. Case_1_reduce.
+//
+// r := s + w
+// c := (s - r) + w ...observe order
+//
+// Step 4. Case_1_complete
+//
+// ...At this point, the reduced argument alpha is
+// ...accurately represented as r + c.
+// If |r| < 2^(-3), go to Step 6, small_r.
+//
+// Step 5. Normal_r.
+//
+// Let [i_0 i_1] by the 2 lsb of N_fix.
+// FR_rsq := r * r
+// r_hi := frcpa( frcpa( r ) )
+// r_lo := r - r_hi
+//
+// If i_1 = 0, then
+// poly := r*FR_rsq*(PP_1_lo + FR_rsq*(PP_2 + ... FR_rsq*PP_8))
+// U_hi := r + PP_1_hi*r_hi*r_hi*r_hi ...any order
+// U_lo := PP_1_hi*r_lo*(r*r + r*r_hi + r_hi*r_hi)
+// correction := c + c*C_1*FR_rsq ...any order
+// Else
+// poly := FR_rsq*FR_rsq*(QQ_2 + FR_rsq*(QQ_3 + ... + FR_rsq*QQ_8))
+// U_hi := 1 + QQ_1 * r_hi * r_hi ...any order
+// U_lo := QQ_1 * r_lo * (r + r_hi)
+// correction := -c*(r + S_1*FR_rsq*r) ...any order
+// Endif
+//
+// V := poly + (U_lo + correction) ...observe order
+//
+// result := (i_0 == 0? 1.0 : -1.0)
+//
+// Last instruction in user-set rounding mode
+//
+// result := (i_0 == 0? result*U_hi + V :
+// result*U_hi - V)
+//
+// Return
+//
+// Step 6. Small_r.
+//
+// ...Use flush to zero mode without causing exception
+// Let [i_0 i_1] be the two lsb of N_fix.
+//
+// FR_rsq := r * r
+//
+// If i_1 = 0 then
+// z := FR_rsq*FR_rsq; z := FR_rsq*z *r
+// poly_lo := S_3 + FR_rsq*(S_4 + FR_rsq*S_5)
+// poly_hi := r*FR_rsq*(S_1 + FR_rsq*S_2)
+// correction := c
+// result := r
+// Else
+// z := FR_rsq*FR_rsq; z := FR_rsq*z
+// poly_lo := C_3 + FR_rsq*(C_4 + FR_rsq*C_5)
+// poly_hi := FR_rsq*(C_1 + FR_rsq*C_2)
+// correction := -c*r
+// result := 1
+// Endif
+//
+// poly := poly_hi + (z * poly_lo + correction)
+//
+// If i_0 = 1, result := -result
+//
+// Last operation. Perform in user-set rounding mode
+//
+// result := (i_0 == 0? result + poly :
+// result - poly )
+// Return
+//
+// Step 7. Case_2_reduce.
+//
+// ...Refer to the write up for argument reduction for
+// ...rationale. The reduction algorithm below is taken from
+// ...argument reduction description and integrated this.
+//
+// w := N*P_3
+// U_1 := N*P_2 + w ...FMA
+// U_2 := (N*P_2 - U_1) + w ...2 FMA
+// ...U_1 + U_2 is N*(P_2+P_3) accurately
+//
+// r := s - U_1
+// c := ( (s - r) - U_1 ) - U_2
+//
+// ...The mathematical sum r + c approximates the reduced
+// ...argument accurately. Note that although compared to
+// ...Case 1, this case requires much more work to reduce
+// ...the argument, the subsequent calculation needed for
+// ...any of the trigonometric function is very little because
+// ...|alpha| < 1.01*2^(-33) and thus two terms of the
+// ...Taylor series expansion suffices.
+//
+// If i_1 = 0 then
+// poly := c + S_1 * r * r * r ...any order
+// result := r
+// Else
+// poly := -2^(-67)
+// result := 1.0
+// Endif
+//
+// If i_0 = 1, result := -result
+//
+// Last operation. Perform in user-set rounding mode
+//
+// result := (i_0 == 0? result + poly :
+// result - poly )
+//
+// Return
+//
+//
+// Step 8. Pre-reduction of large arguments.
+//
+// ...Again, the following reduction procedure was described
+// ...in the separate write up for argument reduction, which
+// ...is tightly integrated here.
+
+// N_0 := Arg * Inv_P_0
+// N_0_fix := fcvt.fx( N_0 )
+// N_0 := fcvt.xf( N_0_fix)
+
+// Arg' := Arg - N_0 * P_0
+// w := N_0 * d_1
+// N := Arg' * two_by_PI
+// N_fix := fcvt.fx( N )
+// N := fcvt.xf( N_fix )
+// N_fix := N_fix + N_inc
+//
+// s := Arg' - N * P_1
+// w := w - N * P_2
+//
+// If |s| >= 2^(-14)
+// go to Step 3
+// Else
+// go to Step 9
+// Endif
+//
+// Step 9. Case_4_reduce.
+//
+// ...first obtain N_0*d_1 and -N*P_2 accurately
+// U_hi := N_0 * d_1 V_hi := -N*P_2
+// U_lo := N_0 * d_1 - U_hi V_lo := -N*P_2 - U_hi ...FMAs
+//
+// ...compute the contribution from N_0*d_1 and -N*P_3
+// w := -N*P_3
+// w := w + N_0*d_2
+// t := U_lo + V_lo + w ...any order
+//
+// ...at this point, the mathematical value
+// ...s + U_hi + V_hi + t approximates the true reduced argument
+// ...accurately. Just need to compute this accurately.
+//
+// ...Calculate U_hi + V_hi accurately:
+// A := U_hi + V_hi
+// if |U_hi| >= |V_hi| then
+// a := (U_hi - A) + V_hi
+// else
+// a := (V_hi - A) + U_hi
+// endif
+// ...order in computing "a" must be observed. This branch is
+// ...best implemented by predicates.
+// ...A + a is U_hi + V_hi accurately. Moreover, "a" is
+// ...much smaller than A: |a| <= (1/2)ulp(A).
+//
+// ...Just need to calculate s + A + a + t
+// C_hi := s + A t := t + a
+// C_lo := (s - C_hi) + A
+// C_lo := C_lo + t
+//
+// ...Final steps for reduction
+// r := C_hi + C_lo
+// c := (C_hi - r) + C_lo
+//
+// ...At this point, we have r and c
+// ...And all we need is a couple of terms of the corresponding
+// ...Taylor series.
+//
+// If i_1 = 0
+// poly := c + r*FR_rsq*(S_1 + FR_rsq*S_2)
+// result := r
+// Else
+// poly := FR_rsq*(C_1 + FR_rsq*C_2)
+// result := 1
+// Endif
+//
+// If i_0 = 1, result := -result
+//
+// Last operation. Perform in user-set rounding mode
+//
+// result := (i_0 == 0? result + poly :
+// result - poly )
+// Return
+//
+// Large Arguments: For arguments above 2**63, a Payne-Hanek
+// style argument reduction is used and pi_by_2 reduce is called.
+//
+
+
+RODATA
+.align 64
+
+LOCAL_OBJECT_START(FSINCOSL_CONSTANTS)
+
+sincosl_table_p:
+//data4 0x4E44152A, 0xA2F9836E, 0x00003FFE,0x00000000 // Inv_pi_by_2
+//data4 0xCE81B9F1, 0xC84D32B0, 0x00004016,0x00000000 // P_0
+//data4 0x2168C235, 0xC90FDAA2, 0x00003FFF,0x00000000 // P_1
+//data4 0xFC8F8CBB, 0xECE675D1, 0x0000BFBD,0x00000000 // P_2
+//data4 0xACC19C60, 0xB7ED8FBB, 0x0000BF7C,0x00000000 // P_3
+//data4 0xDBD171A1, 0x8D848E89, 0x0000BFBF,0x00000000 // d_1
+//data4 0x18A66F8E, 0xD5394C36, 0x0000BF7C,0x00000000 // d_2
+data8 0xA2F9836E4E44152A, 0x00003FFE // Inv_pi_by_2
+data8 0xC84D32B0CE81B9F1, 0x00004016 // P_0
+data8 0xC90FDAA22168C235, 0x00003FFF // P_1
+data8 0xECE675D1FC8F8CBB, 0x0000BFBD // P_2
+data8 0xB7ED8FBBACC19C60, 0x0000BF7C // P_3
+data8 0x8D848E89DBD171A1, 0x0000BFBF // d_1
+data8 0xD5394C3618A66F8E, 0x0000BF7C // d_2
+LOCAL_OBJECT_END(FSINCOSL_CONSTANTS)
+
+LOCAL_OBJECT_START(sincosl_table_d)
+//data4 0x2168C234, 0xC90FDAA2, 0x00003FFE,0x00000000 // pi_by_4
+//data4 0x6EC6B45A, 0xA397E504, 0x00003FE7,0x00000000 // Inv_P_0
+data8 0xC90FDAA22168C234, 0x00003FFE // pi_by_4
+data8 0xA397E5046EC6B45A, 0x00003FE7 // Inv_P_0
+data4 0x3E000000, 0xBE000000 // 2^-3 and -2^-3
+data4 0x2F000000, 0xAF000000 // 2^-33 and -2^-33
+data4 0x9E000000, 0x00000000 // -2^-67
+data4 0x00000000, 0x00000000 // pad
+LOCAL_OBJECT_END(sincosl_table_d)
+
+LOCAL_OBJECT_START(sincosl_table_pp)
+//data4 0xA21C0BC9, 0xCC8ABEBC, 0x00003FCE,0x00000000 // PP_8
+//data4 0x720221DA, 0xD7468A05, 0x0000BFD6,0x00000000 // PP_7
+//data4 0x640AD517, 0xB092382F, 0x00003FDE,0x00000000 // PP_6
+//data4 0xD1EB75A4, 0xD7322B47, 0x0000BFE5,0x00000000 // PP_5
+//data4 0xFFFFFFFE, 0xFFFFFFFF, 0x0000BFFD,0x00000000 // C_1
+//data4 0x00000000, 0xAAAA0000, 0x0000BFFC,0x00000000 // PP_1_hi
+//data4 0xBAF69EEA, 0xB8EF1D2A, 0x00003FEC,0x00000000 // PP_4
+//data4 0x0D03BB69, 0xD00D00D0, 0x0000BFF2,0x00000000 // PP_3
+//data4 0x88888962, 0x88888888, 0x00003FF8,0x00000000 // PP_2
+//data4 0xAAAB0000, 0xAAAAAAAA, 0x0000BFEC,0x00000000 // PP_1_lo
+data8 0xCC8ABEBCA21C0BC9, 0x00003FCE // PP_8
+data8 0xD7468A05720221DA, 0x0000BFD6 // PP_7
+data8 0xB092382F640AD517, 0x00003FDE // PP_6
+data8 0xD7322B47D1EB75A4, 0x0000BFE5 // PP_5
+data8 0xFFFFFFFFFFFFFFFE, 0x0000BFFD // C_1
+data8 0xAAAA000000000000, 0x0000BFFC // PP_1_hi
+data8 0xB8EF1D2ABAF69EEA, 0x00003FEC // PP_4
+data8 0xD00D00D00D03BB69, 0x0000BFF2 // PP_3
+data8 0x8888888888888962, 0x00003FF8 // PP_2
+data8 0xAAAAAAAAAAAB0000, 0x0000BFEC // PP_1_lo
+LOCAL_OBJECT_END(sincosl_table_pp)
+
+LOCAL_OBJECT_START(sincosl_table_qq)
+//data4 0xC2B0FE52, 0xD56232EF, 0x00003FD2 // QQ_8
+//data4 0x2B48DCA6, 0xC9C99ABA, 0x0000BFDA // QQ_7
+//data4 0x9C716658, 0x8F76C650, 0x00003FE2 // QQ_6
+//data4 0xFDA8D0FC, 0x93F27DBA, 0x0000BFE9 // QQ_5
+//data4 0xAAAAAAAA, 0xAAAAAAAA, 0x0000BFFC // S_1
+//data4 0x00000000, 0x80000000, 0x0000BFFE,0x00000000 // QQ_1
+//data4 0x0C6E5041, 0xD00D00D0, 0x00003FEF,0x00000000 // QQ_4
+//data4 0x0B607F60, 0xB60B60B6, 0x0000BFF5,0x00000000 // QQ_3
+//data4 0xAAAAAA9B, 0xAAAAAAAA, 0x00003FFA,0x00000000 // QQ_2
+data8 0xD56232EFC2B0FE52, 0x00003FD2 // QQ_8
+data8 0xC9C99ABA2B48DCA6, 0x0000BFDA // QQ_7
+data8 0x8F76C6509C716658, 0x00003FE2 // QQ_6
+data8 0x93F27DBAFDA8D0FC, 0x0000BFE9 // QQ_5
+data8 0xAAAAAAAAAAAAAAAA, 0x0000BFFC // S_1
+data8 0x8000000000000000, 0x0000BFFE // QQ_1
+data8 0xD00D00D00C6E5041, 0x00003FEF // QQ_4
+data8 0xB60B60B60B607F60, 0x0000BFF5 // QQ_3
+data8 0xAAAAAAAAAAAAAA9B, 0x00003FFA // QQ_2
+LOCAL_OBJECT_END(sincosl_table_qq)
+
+LOCAL_OBJECT_START(sincosl_table_c)
+//data4 0xFFFFFFFE, 0xFFFFFFFF, 0x0000BFFD,0x00000000 // C_1
+//data4 0xAAAA719F, 0xAAAAAAAA, 0x00003FFA,0x00000000 // C_2
+//data4 0x0356F994, 0xB60B60B6, 0x0000BFF5,0x00000000 // C_3
+//data4 0xB2385EA9, 0xD00CFFD5, 0x00003FEF,0x00000000 // C_4
+//data4 0x292A14CD, 0x93E4BD18, 0x0000BFE9,0x00000000 // C_5
+data8 0xFFFFFFFFFFFFFFFE, 0x0000BFFD // C_1
+data8 0xAAAAAAAAAAAA719F, 0x00003FFA // C_2
+data8 0xB60B60B60356F994, 0x0000BFF5 // C_3
+data8 0xD00CFFD5B2385EA9, 0x00003FEF // C_4
+data8 0x93E4BD18292A14CD, 0x0000BFE9 // C_5
+LOCAL_OBJECT_END(sincosl_table_c)
+
+LOCAL_OBJECT_START(sincosl_table_s)
+//data4 0xAAAAAAAA, 0xAAAAAAAA, 0x0000BFFC,0x00000000 // S_1
+//data4 0x888868DB, 0x88888888, 0x00003FF8,0x00000000 // S_2
+//data4 0x055EFD4B, 0xD00D00D0, 0x0000BFF2,0x00000000 // S_3
+//data4 0x839730B9, 0xB8EF1C5D, 0x00003FEC,0x00000000 // S_4
+//data4 0xE5B3F492, 0xD71EA3A4, 0x0000BFE5,0x00000000 // S_5
+data8 0xAAAAAAAAAAAAAAAA, 0x0000BFFC // S_1
+data8 0x88888888888868DB, 0x00003FF8 // S_2
+data8 0xD00D00D0055EFD4B, 0x0000BFF2 // S_3
+data8 0xB8EF1C5D839730B9, 0x00003FEC // S_4
+data8 0xD71EA3A4E5B3F492, 0x0000BFE5 // S_5
+data4 0x38800000, 0xB8800000 // two**-14 and -two**-14
+LOCAL_OBJECT_END(sincosl_table_s)
+
+FR_Input_X = f8
+FR_Result = f8
+FR_ResultS = f9
+FR_ResultC = f8
+FR_r = f8
+FR_c = f9
+
+FR_norm_x = f9
+FR_inv_pi_2to63 = f10
+FR_rshf_2to64 = f11
+FR_2tom64 = f12
+FR_rshf = f13
+FR_N_float_signif = f14
+FR_abs_x = f15
+
+FR_r6 = f32
+FR_r7 = f33
+FR_Pi_by_4 = f34
+FR_Two_to_M14 = f35
+FR_Neg_Two_to_M14 = f36
+FR_Two_to_M33 = f37
+FR_Neg_Two_to_M33 = f38
+FR_Neg_Two_to_M67 = f39
+FR_Inv_pi_by_2 = f40
+FR_N_float = f41
+FR_N_fix = f42
+FR_P_1 = f43
+FR_P_2 = f44
+FR_P_3 = f45
+FR_s = f46
+FR_w = f47
+FR_Z = f50
+FR_A = f51
+FR_a = f52
+FR_t = f53
+FR_U_1 = f54
+FR_U_2 = f55
+FR_C_1 = f56
+FR_C_2 = f57
+FR_C_3 = f58
+FR_C_4 = f59
+FR_C_5 = f60
+FR_S_1 = f61
+FR_S_2 = f62
+FR_S_3 = f63
+FR_S_4 = f64
+FR_S_5 = f65
+FR_r_hi = f68
+FR_r_lo = f69
+FR_rsq = f70
+FR_r_cubed = f71
+FR_C_hi = f72
+FR_N_0 = f73
+FR_d_1 = f74
+FR_V_hi = f75
+FR_V_lo = f76
+FR_U_hi = f77
+FR_U_lo = f78
+FR_U_hiabs = f79
+FR_V_hiabs = f80
+FR_PP_8 = f81
+FR_QQ_8 = f101
+FR_PP_7 = f82
+FR_QQ_7 = f102
+FR_PP_6 = f83
+FR_QQ_6 = f103
+FR_PP_5 = f84
+FR_QQ_5 = f104
+FR_PP_4 = f85
+FR_QQ_4 = f105
+FR_PP_3 = f86
+FR_QQ_3 = f106
+FR_PP_2 = f87
+FR_QQ_2 = f107
+FR_QQ_1 = f108
+FR_r_hi_sq = f88
+FR_N_0_fix = f89
+FR_Inv_P_0 = f90
+FR_d_2 = f93
+FR_P_0 = f95
+FR_C_lo = f96
+FR_PP_1 = f97
+FR_PP_1_lo = f98
+FR_ArgPrime = f99
+FR_inexact = f100
+
+FR_Neg_Two_to_M3 = f109
+FR_Two_to_M3 = f110
+
+FR_poly_hiS = f66
+FR_poly_hiC = f112
+
+FR_poly_loS = f67
+FR_poly_loC = f113
+
+FR_polyS = f92
+FR_polyC = f114
+
+FR_cS = FR_c
+FR_cC = f115
+
+FR_corrS = f91
+FR_corrC = f116
+
+FR_U_hiC = f117
+FR_U_loC = f118
+
+FR_VS = f75
+FR_VC = f119
+
+FR_FirstS = f120
+FR_FirstC = f121
+
+FR_U_hiS = FR_U_hi
+FR_U_loS = FR_U_lo
+
+FR_Tmp = f94
+
+
+
+
+sincos_pResSin = r34
+sincos_pResCos = r35
+
+GR_exp_m2_to_m3= r36
+GR_N_Inc = r37
+GR_Cis = r38
+GR_signexp_x = r40
+GR_exp_x = r40
+GR_exp_mask = r41
+GR_exp_2_to_63 = r42
+GR_exp_2_to_m3 = r43
+GR_exp_2_to_24 = r44
+
+GR_N_SignS = r45
+GR_N_SignC = r46
+GR_N_SinCos = r47
+
+GR_sig_inv_pi = r48
+GR_rshf_2to64 = r49
+GR_exp_2tom64 = r50
+GR_rshf = r51
+GR_ad_p = r52
+GR_ad_d = r53
+GR_ad_pp = r54
+GR_ad_qq = r55
+GR_ad_c = r56
+GR_ad_s = r57
+GR_ad_ce = r58
+GR_ad_se = r59
+GR_ad_m14 = r60
+GR_ad_s1 = r61
+
+// For unwind support
+GR_SAVE_B0 = r39
+GR_SAVE_GP = r40
+GR_SAVE_PFS = r41
+
+
+.section .text
+
+GLOBAL_IEEE754_ENTRY(sincosl)
+{ .mlx ///////////////////////////// 1 /////////////////
+ alloc r32 = ar.pfs,3,27,2,0
+ movl GR_sig_inv_pi = 0xa2f9836e4e44152a // significand of 1/pi
+}
+{ .mlx
+ mov GR_N_Inc = 0x0
+ movl GR_rshf_2to64 = 0x47e8000000000000 // 1.1000 2^(63+64)
+};;
+
+{ .mfi ///////////////////////////// 2 /////////////////
+ addl GR_ad_p = @ltoff(FSINCOSL_CONSTANTS#), gp
+ fclass.m p6, p0 = FR_Input_X, 0x1E3 // Test x natval, nan, inf
+ mov GR_exp_2_to_m3 = 0xffff - 3 // Exponent of 2^-3
+}
+{ .mfb
+ mov GR_Cis = 0x0
+ fnorm.s1 FR_norm_x = FR_Input_X // Normalize x
+ br.cond.sptk _COMMON_SINCOSL
+};;
+GLOBAL_IEEE754_END(sincosl)
+
+GLOBAL_LIBM_ENTRY(__libm_sincosl)
+{ .mlx ///////////////////////////// 1 /////////////////
+ alloc r32 = ar.pfs,3,27,2,0
+ movl GR_sig_inv_pi = 0xa2f9836e4e44152a // significand of 1/pi
+}
+{ .mlx
+ mov GR_N_Inc = 0x0
+ movl GR_rshf_2to64 = 0x47e8000000000000 // 1.1000 2^(63+64)
+};;
+
+{ .mfi ///////////////////////////// 2 /////////////////
+ addl GR_ad_p = @ltoff(FSINCOSL_CONSTANTS#), gp
+ fclass.m p6, p0 = FR_Input_X, 0x1E3 // Test x natval, nan, inf
+ mov GR_exp_2_to_m3 = 0xffff - 3 // Exponent of 2^-3
+}
+{ .mfb
+ mov GR_Cis = 0x1
+ fnorm.s1 FR_norm_x = FR_Input_X // Normalize x
+ nop.b 0
+};;
+
+_COMMON_SINCOSL:
+{ .mfi ///////////////////////////// 3 /////////////////
+ setf.sig FR_inv_pi_2to63 = GR_sig_inv_pi // Form 1/pi * 2^63
+ nop.f 0
+ mov GR_exp_2tom64 = 0xffff - 64 // Scaling constant to compute N
+}
+{ .mlx
+ setf.d FR_rshf_2to64 = GR_rshf_2to64 // Form const 1.1000 * 2^(63+64)
+ movl GR_rshf = 0x43e8000000000000 // Form const 1.1000 * 2^63
+};;
+
+{ .mfi ///////////////////////////// 4 /////////////////
+ ld8 GR_ad_p = [GR_ad_p] // Point to Inv_pi_by_2
+ fclass.m p7, p0 = FR_Input_X, 0x0b // Test x denormal
+ nop.i 0
+};;
+
+{ .mfi ///////////////////////////// 5 /////////////////
+ getf.exp GR_signexp_x = FR_Input_X // Get sign and exponent of x
+ fclass.m p10, p0 = FR_Input_X, 0x007 // Test x zero
+ nop.i 0
+}
+{ .mib
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+ nop.i 0
+(p6) br.cond.spnt SINCOSL_SPECIAL // Branch if x natval, nan, inf
+};;
+
+{ .mfi ///////////////////////////// 6 /////////////////
+ setf.exp FR_2tom64 = GR_exp_2tom64 // Form 2^-64 for scaling N_float
+ nop.f 0
+ add GR_ad_d = 0x70, GR_ad_p // Point to constant table d
+}
+{ .mib
+ setf.d FR_rshf = GR_rshf // Form right shift const 1.1000 * 2^63
+ mov GR_exp_m2_to_m3 = 0x2fffc // Form -(2^-3)
+(p7) br.cond.spnt SINCOSL_DENORMAL // Branch if x denormal
+};;
+
+SINCOSL_COMMON2:
+{ .mfi ///////////////////////////// 7 /////////////////
+ and GR_exp_x = GR_exp_mask, GR_signexp_x // Get exponent of x
+ fclass.nm p8, p0 = FR_Input_X, 0x1FF // Test x unsupported type
+ mov GR_exp_2_to_63 = 0xffff + 63 // Exponent of 2^63
+}
+{ .mib
+ add GR_ad_pp = 0x40, GR_ad_d // Point to constant table pp
+ mov GR_exp_2_to_24 = 0xffff + 24 // Exponent of 2^24
+(p10) br.cond.spnt SINCOSL_ZERO // Branch if x zero
+};;
+
+{ .mfi ///////////////////////////// 8 /////////////////
+ ldfe FR_Inv_pi_by_2 = [GR_ad_p], 16 // Load 2/pi
+ fcmp.eq.s0 p15, p0 = FR_Input_X, f0 // Dummy to set denormal
+ add GR_ad_qq = 0xa0, GR_ad_pp // Point to constant table qq
+}
+{ .mfi
+ ldfe FR_Pi_by_4 = [GR_ad_d], 16 // Load pi/4 for range test
+ nop.f 0
+ cmp.ge p10,p0 = GR_exp_x, GR_exp_2_to_63 // Is |x| >= 2^63
+};;
+
+{ .mfi ///////////////////////////// 9 /////////////////
+ ldfe FR_P_0 = [GR_ad_p], 16 // Load P_0 for pi/4 <= |x| < 2^63
+ fmerge.s FR_abs_x = f1, FR_norm_x // |x|
+ add GR_ad_c = 0x90, GR_ad_qq // Point to constant table c
+}
+{ .mfi
+ ldfe FR_Inv_P_0 = [GR_ad_d], 16 // Load 1/P_0 for pi/4 <= |x| < 2^63
+ nop.f 0
+ cmp.ge p7,p0 = GR_exp_x, GR_exp_2_to_24 // Is |x| >= 2^24
+};;
+
+{ .mfi ///////////////////////////// 10 /////////////////
+ ldfe FR_P_1 = [GR_ad_p], 16 // Load P_1 for pi/4 <= |x| < 2^63
+ nop.f 0
+ add GR_ad_s = 0x50, GR_ad_c // Point to constant table s
+}
+{ .mfi
+ ldfe FR_PP_8 = [GR_ad_pp], 16 // Load PP_8 for 2^-3 < |r| < pi/4
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi ///////////////////////////// 11 /////////////////
+ ldfe FR_P_2 = [GR_ad_p], 16 // Load P_2 for pi/4 <= |x| < 2^63
+ nop.f 0
+ add GR_ad_ce = 0x40, GR_ad_c // Point to end of constant table c
+}
+{ .mfi
+ ldfe FR_QQ_8 = [GR_ad_qq], 16 // Load QQ_8 for 2^-3 < |r| < pi/4
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi ///////////////////////////// 12 /////////////////
+ ldfe FR_QQ_7 = [GR_ad_qq], 16 // Load QQ_7 for 2^-3 < |r| < pi/4
+ fma.s1 FR_N_float_signif = FR_Input_X, FR_inv_pi_2to63, FR_rshf_2to64
+ add GR_ad_se = 0x40, GR_ad_s // Point to end of constant table s
+}
+{ .mib
+ ldfe FR_PP_7 = [GR_ad_pp], 16 // Load PP_7 for 2^-3 < |r| < pi/4
+ mov GR_ad_s1 = GR_ad_s // Save pointer to S_1
+(p10) br.cond.spnt SINCOSL_ARG_TOO_LARGE // Branch if |x| >= 2^63
+ // Use Payne-Hanek Reduction
+};;
+
+{ .mfi ///////////////////////////// 13 /////////////////
+ ldfe FR_P_3 = [GR_ad_p], 16 // Load P_3 for pi/4 <= |x| < 2^63
+ fmerge.se FR_r = FR_norm_x, FR_norm_x // r = x, in case |x| < pi/4
+ add GR_ad_m14 = 0x50, GR_ad_s // Point to constant table m14
+}
+{ .mfb
+ ldfps FR_Two_to_M3, FR_Neg_Two_to_M3 = [GR_ad_d], 8
+ fma.s1 FR_rsq = FR_norm_x, FR_norm_x, f0 // rsq = x*x, in case |x| < pi/4
+(p7) br.cond.spnt SINCOSL_LARGER_ARG // Branch if 2^24 <= |x| < 2^63
+ // Use pre-reduction
+};;
+
+{ .mmf ///////////////////////////// 14 /////////////////
+ ldfe FR_PP_6 = [GR_ad_pp], 16 // Load PP_6 for normal path
+ ldfe FR_QQ_6 = [GR_ad_qq], 16 // Load QQ_6 for normal path
+ fmerge.se FR_c = f0, f0 // c = 0 in case |x| < pi/4
+};;
+
+{ .mmf ///////////////////////////// 15 /////////////////
+ ldfe FR_PP_5 = [GR_ad_pp], 16 // Load PP_5 for normal path
+ ldfe FR_QQ_5 = [GR_ad_qq], 16 // Load QQ_5 for normal path
+ nop.f 0
+};;
+
+// Here if 0 < |x| < 2^24
+{ .mfi ///////////////////////////// 17 /////////////////
+ ldfe FR_S_5 = [GR_ad_se], -16 // Load S_5 if i_1=0
+ fcmp.lt.s1 p6, p7 = FR_abs_x, FR_Pi_by_4 // Test |x| < pi/4
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_C_5 = [GR_ad_ce], -16 // Load C_5 if i_1=1
+ fms.s1 FR_N_float = FR_N_float_signif, FR_2tom64, FR_rshf
+ nop.i 0
+};;
+
+{ .mmi ///////////////////////////// 18 /////////////////
+ ldfe FR_S_4 = [GR_ad_se], -16 // Load S_4 if i_1=0
+ ldfe FR_C_4 = [GR_ad_ce], -16 // Load C_4 if i_1=1
+ nop.i 0
+};;
+
+//
+// N = Arg * 2/pi
+// Check if Arg < pi/4
+//
+//
+// Case 2: Convert integer N_fix back to normalized floating-point value.
+// Case 1: p8 is only affected when p6 is set
+//
+//
+// Grab the integer part of N and call it N_fix
+//
+{ .mfi ///////////////////////////// 19 /////////////////
+(p7) ldfps FR_Two_to_M33, FR_Neg_Two_to_M33 = [GR_ad_d], 8
+(p6) fma.s1 FR_r_cubed = FR_r, FR_rsq, f0 // r^3 if |x| < pi/4
+(p6) mov GR_N_Inc = 0x0 // N_IncS if |x| < pi/4
+};;
+
+// If |x| < pi/4, r = x and c = 0
+// lf |x| < pi/4, is x < 2**(-3).
+// r = Arg
+// c = 0
+{ .mmi ///////////////////////////// 20 /////////////////
+(p7) getf.sig GR_N_Inc = FR_N_float_signif
+ nop.m 0
+(p6) cmp.lt.unc p8,p0 = GR_exp_x, GR_exp_2_to_m3 // Is |x| < 2^-3
+};;
+
+//
+// lf |x| < pi/4, is -2**(-3)< x < 2**(-3) - set p8.
+// If |x| >= pi/4,
+// Create the right N for |x| < pi/4 and otherwise
+// Case 2: Place integer part of N in GP register
+//
+
+{ .mbb ///////////////////////////// 21 /////////////////
+ nop.m 0
+(p8) br.cond.spnt SINCOSL_SMALL_R_0 // Branch if 0 < |x| < 2^-3
+(p6) br.cond.spnt SINCOSL_NORMAL_R_0 // Branch if 2^-3 <= |x| < pi/4
+};;
+
+// Here if pi/4 <= |x| < 2^24
+{ .mfi
+ ldfs FR_Neg_Two_to_M67 = [GR_ad_d], 8 // Load -2^-67
+ fnma.s1 FR_s = FR_N_float, FR_P_1, FR_Input_X // s = -N * P_1 + Arg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_w = FR_N_float, FR_P_2, f0 // w = N * P_2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r = FR_s, f1, FR_w // r = s - w, assume |s| >= 2^-33
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fcmp.lt.s1 p7, p6 = FR_s, FR_Two_to_M33
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p7) fcmp.gt.s1 p7, p6 = FR_s, FR_Neg_Two_to_M33 // p6 if |s| >= 2^-33, else p7
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_c = FR_s, f1, FR_r // c = s - r, for |s| >= 2^-33
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rsq = FR_r, FR_r, f0 // rsq = r * r, for |s| >= 2^-33
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p7) fma.s1 FR_w = FR_N_float, FR_P_3, f0
+ nop.i 0
+};;
+
+{ .mmf
+ ldfe FR_C_1 = [GR_ad_pp], 16 // Load C_1 if i_1=0
+ ldfe FR_S_1 = [GR_ad_qq], 16 // Load S_1 if i_1=1
+ frcpa.s1 FR_r_hi, p15 = f1, FR_r // r_hi = frcpa(r)
+};;
+
+{ .mfi
+ nop.m 0
+(p6) fcmp.lt.unc.s1 p8, p13 = FR_r, FR_Two_to_M3 // If big s, test r with 2^-3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p7) fma.s1 FR_U_1 = FR_N_float, FR_P_2, FR_w
+ nop.i 0
+};;
+
+//
+// For big s: r = s - w: No futher reduction is necessary
+// For small s: w = N * P_3 (change sign) More reduction
+//
+{ .mfi
+ nop.m 0
+(p8) fcmp.gt.s1 p8, p13 = FR_r, FR_Neg_Two_to_M3 // If big s, p8 if |r| < 2^-3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyS = FR_rsq, FR_PP_8, FR_PP_7 // poly = rsq*PP_8+PP_7
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyC = FR_rsq, FR_QQ_8, FR_QQ_7 // poly = rsq*QQ_8+QQ_7
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p7) fms.s1 FR_r = FR_s, f1, FR_U_1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p6) fma.s1 FR_r_cubed = FR_r, FR_rsq, f0 // rcubed = r * rsq
+ nop.i 0
+};;
+
+{ .mfi
+//
+// For big s: Is |r| < 2**(-3)?
+// For big s: c = S - r
+// For small s: U_1 = N * P_2 + w
+//
+// If p8 is set, prepare to branch to Small_R.
+// If p9 is set, prepare to branch to Normal_R.
+// For big s, r is complete here.
+//
+//
+// For big s: c = c + w (w has not been negated.)
+// For small s: r = S - U_1
+//
+ nop.m 0
+(p6) fms.s1 FR_c = FR_c, f1, FR_w
+ nop.i 0
+}
+{ .mbb
+ nop.m 0
+(p8) br.cond.spnt SINCOSL_SMALL_R_1 // Branch if |s|>=2^-33, |r| < 2^-3,
+ // and pi/4 <= |x| < 2^24
+(p13) br.cond.sptk SINCOSL_NORMAL_R_1 // Branch if |s|>=2^-33, |r| >= 2^-3,
+ // and pi/4 <= |x| < 2^24
+};;
+
+SINCOSL_S_TINY:
+//
+// Here if |s| < 2^-33, and pi/4 <= |x| < 2^24
+//
+{ .mfi
+ and GR_N_SinCos = 0x1, GR_N_Inc
+ fms.s1 FR_U_2 = FR_N_float, FR_P_2, FR_U_1
+ tbit.z p8,p12 = GR_N_Inc, 0
+};;
+
+
+//
+// For small s: U_2 = N * P_2 - U_1
+// S_1 stored constant - grab the one stored with the
+// coefficients.
+//
+{ .mfi
+ ldfe FR_S_1 = [GR_ad_s1], 16
+ fma.s1 FR_polyC = f0, f1, FR_Neg_Two_to_M67
+ sub GR_N_SignS = GR_N_Inc, GR_N_SinCos
+}
+{ .mfi
+ add GR_N_SignC = GR_N_Inc, GR_N_SinCos
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_s = FR_s, f1, FR_r
+(p8) tbit.z.unc p10,p11 = GR_N_SignC, 1
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rsq = FR_r, FR_r, f0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U_2 = FR_U_2, f1, FR_w
+(p8) tbit.z.unc p8,p9 = GR_N_SignS, 1
+};;
+
+{ .mfi
+ nop.m 0
+ fmerge.se FR_FirstS = FR_r, FR_r
+(p12) tbit.z.unc p14,p15 = GR_N_SignC, 1
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_FirstC = f0, f1, f1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_c = FR_s, f1, FR_U_1
+(p12) tbit.z.unc p12,p13 = GR_N_SignS, 1
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r = FR_S_1, FR_r, f0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s0 FR_S_1 = FR_S_1, FR_S_1, f0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_c = FR_c, f1, FR_U_2
+ nop.i 0
+};;
+
+.pred.rel "mutex",p9,p15
+{ .mfi
+ nop.m 0
+(p9) fms.s0 FR_FirstS = f1, f0, FR_FirstS
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fms.s0 FR_FirstS = f1, f0, FR_FirstS
+ nop.i 0
+};;
+
+.pred.rel "mutex",p11,p13
+{ .mfi
+ nop.m 0
+(p11) fms.s0 FR_FirstC = f1, f0, FR_FirstC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fms.s0 FR_FirstC = f1, f0, FR_FirstC
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyS = FR_r, FR_rsq, FR_c
+ nop.i 0
+};;
+
+
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 0
+(p8) fma.s0 FR_ResultS = FR_FirstS, f1, FR_polyS
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fms.s0 FR_ResultS = FR_FirstS, f1, FR_polyS
+ nop.i 0
+};;
+
+.pred.rel "mutex",p10,p11
+{ .mfi
+ nop.m 0
+(p10) fma.s0 FR_ResultC = FR_FirstC, f1, FR_polyC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fms.s0 FR_ResultC = FR_FirstC, f1, FR_polyC
+ nop.i 0
+};;
+
+
+
+.pred.rel "mutex",p12,p13
+{ .mfi
+ nop.m 0
+(p12) fma.s0 FR_ResultS = FR_FirstC, f1, FR_polyC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fms.s0 FR_ResultS = FR_FirstC, f1, FR_polyC
+ nop.i 0
+};;
+
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p14) fma.s0 FR_ResultC = FR_FirstS, f1, FR_polyS
+ nop.i 0
+}
+{ .mfb
+ cmp.eq p10, p0 = 0x1, GR_Cis
+(p15) fms.s0 FR_ResultC = FR_FirstS, f1, FR_polyS
+(p10) br.ret.sptk b0
+};;
+
+{ .mmb // exit for sincosl
+ stfe [sincos_pResSin] = FR_ResultS
+ stfe [sincos_pResCos] = FR_ResultC
+ br.ret.sptk b0
+};;
+
+
+
+
+
+
+SINCOSL_LARGER_ARG:
+//
+// Here if 2^24 <= |x| < 2^63
+//
+{ .mfi
+ ldfe FR_d_1 = [GR_ad_p], 16 // Load d_1 for |x| >= 2^24 path
+ fma.s1 FR_N_0 = FR_Input_X, FR_Inv_P_0, f0 // N_0 = Arg * Inv_P_0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfps FR_Two_to_M14, FR_Neg_Two_to_M14 = [GR_ad_m14]
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_d_2 = [GR_ad_p], 16 // Load d_2 for |x| >= 2^24 path
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fcvt.fx.s1 FR_N_0_fix = FR_N_0 // N_0_fix = integer part of N_0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_N_0 = FR_N_0_fix // Make N_0 the integer part
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_ArgPrime = FR_N_0, FR_P_0, FR_Input_X // Arg'=-N_0*P_0+Arg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_w = FR_N_0, FR_d_1, f0 // w = N_0 * d_1
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_N_float = FR_ArgPrime, FR_Inv_pi_by_2, f0 // N = A' * 2/pi
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fcvt.fx.s1 FR_N_fix = FR_N_float // N_fix is the integer part
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_N_float = FR_N_fix
+ nop.i 0
+};;
+
+{ .mfi
+ getf.sig GR_N_Inc = FR_N_fix // N is the integer part of
+ // the reduced-reduced argument
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_s = FR_N_float, FR_P_1, FR_ArgPrime // s = -N*P_1 + Arg'
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_w = FR_N_float, FR_P_2, FR_w // w = -N*P_2 + w
+ nop.i 0
+};;
+
+//
+// For |s| > 2**(-14) r = S + w (r complete)
+// Else U_hi = N_0 * d_1
+//
+{ .mfi
+ nop.m 0
+ fcmp.lt.unc.s1 p9, p8 = FR_s, FR_Two_to_M14
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p9) fcmp.gt.s1 p9, p8 = FR_s, FR_Neg_Two_to_M14 // p9 if |s| < 2^-14
+ nop.i 0
+};;
+
+//
+// Either S <= -2**(-14) or S >= 2**(-14)
+// or -2**(-14) < s < 2**(-14)
+//
+{ .mfi
+ nop.m 0
+(p9) fma.s1 FR_V_hi = FR_N_float, FR_P_2, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 FR_U_hi = FR_N_0, FR_d_1, f0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p8) fma.s1 FR_r = FR_s, f1, FR_w
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 FR_w = FR_N_float, FR_P_3, f0
+ nop.i 0
+};;
+
+//
+// We need abs of both U_hi and V_hi - don't
+// worry about switched sign of V_hi.
+//
+// Big s: finish up c = (S - r) + w (c complete)
+// Case 4: A = U_hi + V_hi
+// Note: Worry about switched sign of V_hi, so subtract instead of add.
+//
+{ .mfi
+ nop.m 0
+(p9) fms.s1 FR_A = FR_U_hi, f1, FR_V_hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fnma.s1 FR_V_lo = FR_N_float, FR_P_2, FR_V_hi
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p9) fmerge.s FR_V_hiabs = f0, FR_V_hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fms.s1 FR_U_lo = FR_N_0, FR_d_1, FR_U_hi // For small s: U_lo=N_0*d_1-U_hi
+ nop.i 0
+};;
+
+//
+// For big s: Is |r| < 2**(-3)
+// For big s: if p12 set, prepare to branch to Small_R.
+// For big s: If p13 set, prepare to branch to Normal_R.
+//
+{ .mfi
+ nop.m 0
+(p9) fmerge.s FR_U_hiabs = f0, FR_U_hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fms.s1 FR_c = FR_s, f1, FR_r // For big s: c = S - r
+ nop.i 0
+};;
+
+//
+// For small S: V_hi = N * P_2
+// w = N * P_3
+// Note the product does not include the (-) as in the writeup
+// so (-) missing for V_hi and w.
+//
+{ .mfi
+ nop.m 0
+(p8) fcmp.lt.unc.s1 p12, p13 = FR_r, FR_Two_to_M3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p12) fcmp.gt.s1 p12, p13 = FR_r, FR_Neg_Two_to_M3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p8) fma.s1 FR_c = FR_c, f1, FR_w
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p9) fms.s1 FR_w = FR_N_0, FR_d_2, FR_w
+(p12) br.cond.spnt SINCOSL_SMALL_R // Branch if |r| < 2^-3
+ // and 2^24 <= |x| < 2^63
+};;
+
+{ .mib
+ nop.m 0
+ nop.i 0
+(p13) br.cond.sptk SINCOSL_NORMAL_R // Branch if |r| >= 2^-3
+ // and 2^24 <= |x| < 2^63
+};;
+
+SINCOSL_LARGER_S_TINY:
+// Here if |s| < 2^-14, and 2^24 <= |x| < 2^63
+//
+// Big s: Vector off when |r| < 2**(-3). Recall that p8 will be true.
+// The remaining stuff is for Case 4.
+// Small s: V_lo = N * P_2 + U_hi (U_hi is in place of V_hi in writeup)
+// Note: the (-) is still missing for V_lo.
+// Small s: w = w + N_0 * d_2
+// Note: the (-) is now incorporated in w.
+//
+{ .mfi
+ and GR_N_SinCos = 0x1, GR_N_Inc
+ fcmp.ge.unc.s1 p6, p7 = FR_U_hiabs, FR_V_hiabs
+ tbit.z p8,p12 = GR_N_Inc, 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_t = FR_U_lo, f1, FR_V_lo // C_hi = S + A
+ nop.i 0
+};;
+
+{ .mfi
+ sub GR_N_SignS = GR_N_Inc, GR_N_SinCos
+(p6) fms.s1 FR_a = FR_U_hi, f1, FR_A
+ add GR_N_SignC = GR_N_Inc, GR_N_SinCos
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s1 FR_a = FR_V_hi, f1, FR_A
+ nop.i 0
+};;
+
+{ .mmf
+ ldfe FR_C_1 = [GR_ad_c], 16
+ ldfe FR_S_1 = [GR_ad_s], 16
+ fma.s1 FR_C_hi = FR_s, f1, FR_A
+};;
+
+{ .mmi
+ ldfe FR_C_2 = [GR_ad_c], 64
+ ldfe FR_S_2 = [GR_ad_s], 64
+(p8) tbit.z.unc p10,p11 = GR_N_SignC, 1
+};;
+
+//
+// r and c have been computed.
+// Make sure ftz mode is set - should be automatic when using wre
+// |r| < 2**(-3)
+// Get [i_0,i_1] - two lsb of N_fix.
+//
+// For larger u than v: a = U_hi - A
+// Else a = V_hi - A (do an add to account for missing (-) on V_hi
+//
+{ .mfi
+ nop.m 0
+ fma.s1 FR_t = FR_t, f1, FR_w // t = t + w
+(p8) tbit.z.unc p8,p9 = GR_N_SignS, 1
+}
+{ .mfi
+ nop.m 0
+(p6) fms.s1 FR_a = FR_a, f1, FR_V_hi
+ nop.i 0
+};;
+
+//
+// If u > v: a = (U_hi - A) + V_hi
+// Else a = (V_hi - A) + U_hi
+// In each case account for negative missing from V_hi.
+//
+{ .mfi
+ nop.m 0
+ fms.s1 FR_C_lo = FR_s, f1, FR_C_hi
+(p12) tbit.z.unc p14,p15 = GR_N_SignC, 1
+}
+{ .mfi
+ nop.m 0
+(p7) fms.s1 FR_a = FR_U_hi, f1, FR_a
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C_lo = FR_C_lo, f1, FR_A // C_lo = (S - C_hi) + A
+(p12) tbit.z.unc p12,p13 = GR_N_SignS, 1
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_t = FR_t, f1, FR_a // t = t + a
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r = FR_C_hi, f1, FR_C_lo
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C_lo = FR_C_lo, f1, FR_t // C_lo = C_lo + t
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rsq = FR_r, FR_r, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_c = FR_C_hi, f1, FR_r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_FirstS = f0, f1, FR_r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_FirstC = f0, f1, f1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyS = FR_rsq, FR_S_2, FR_S_1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyC = FR_rsq, FR_C_2, FR_C_1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_cubed = FR_rsq, FR_r, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_c = FR_c, f1, FR_C_lo
+ nop.i 0
+};;
+
+.pred.rel "mutex",p9,p15
+{ .mfi
+ nop.m 0
+(p9) fms.s0 FR_FirstS = f1, f0, FR_FirstS
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fms.s0 FR_FirstS = f1, f0, FR_FirstS
+ nop.i 0
+};;
+
+.pred.rel "mutex",p11,p13
+{ .mfi
+ nop.m 0
+(p11) fms.s0 FR_FirstC = f1, f0, FR_FirstC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fms.s0 FR_FirstC = f1, f0, FR_FirstC
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyS = FR_r_cubed, FR_polyS, FR_c
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyC = FR_rsq, FR_polyC, f0
+ nop.i 0
+};;
+
+
+
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 0
+(p8) fma.s0 FR_ResultS = FR_FirstS, f1, FR_polyS
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fms.s0 FR_ResultS = FR_FirstS, f1, FR_polyS
+ nop.i 0
+};;
+
+.pred.rel "mutex",p10,p11
+{ .mfi
+ nop.m 0
+(p10) fma.s0 FR_ResultC = FR_FirstC, f1, FR_polyC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fms.s0 FR_ResultC = FR_FirstC, f1, FR_polyC
+ nop.i 0
+};;
+
+
+
+.pred.rel "mutex",p12,p13
+{ .mfi
+ nop.m 0
+(p12) fma.s0 FR_ResultS = FR_FirstC, f1, FR_polyC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fms.s0 FR_ResultS = FR_FirstC, f1, FR_polyC
+ nop.i 0
+};;
+
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p14) fma.s0 FR_ResultC = FR_FirstS, f1, FR_polyS
+ nop.i 0
+}
+{ .mfb
+ cmp.eq p10, p0 = 0x1, GR_Cis
+(p15) fms.s0 FR_ResultC = FR_FirstS, f1, FR_polyS
+(p10) br.ret.sptk b0
+};;
+
+
+{ .mmb // exit for sincosl
+ stfe [sincos_pResSin] = FR_ResultS
+ stfe [sincos_pResCos] = FR_ResultC
+ br.ret.sptk b0
+};;
+
+
+
+SINCOSL_SMALL_R:
+//
+// Here if |r| < 2^-3
+//
+// Enter with r, c, and N_Inc computed
+//
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rsq = FR_r, FR_r, f0 // rsq = r * r
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe FR_S_5 = [GR_ad_se], -16 // Load S_5
+ ldfe FR_C_5 = [GR_ad_ce], -16 // Load C_5
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe FR_S_4 = [GR_ad_se], -16 // Load S_4
+ ldfe FR_C_4 = [GR_ad_ce], -16 // Load C_4
+ nop.i 0
+};;
+
+SINCOSL_SMALL_R_0:
+// Entry point for 2^-3 < |x| < pi/4
+SINCOSL_SMALL_R_1:
+// Entry point for pi/4 < |x| < 2^24 and |r| < 2^-3
+{ .mfi
+ ldfe FR_S_3 = [GR_ad_se], -16 // Load S_3
+ fma.s1 FR_r6 = FR_rsq, FR_rsq, f0 // Z = rsq * rsq
+ tbit.z p7,p11 = GR_N_Inc, 0
+}
+{ .mfi
+ ldfe FR_C_3 = [GR_ad_ce], -16 // Load C_3
+ nop.f 0
+ and GR_N_SinCos = 0x1, GR_N_Inc
+};;
+
+{ .mfi
+ ldfe FR_S_2 = [GR_ad_se], -16 // Load S_2
+ fnma.s1 FR_cC = FR_c, FR_r, f0 // c = -c * r
+ sub GR_N_SignS = GR_N_Inc, GR_N_SinCos
+}
+{ .mfi
+ ldfe FR_C_2 = [GR_ad_ce], -16 // Load C_2
+ nop.f 0
+ add GR_N_SignC = GR_N_Inc, GR_N_SinCos
+};;
+
+{ .mmi
+ ldfe FR_S_1 = [GR_ad_se], -16 // Load S_1
+ ldfe FR_C_1 = [GR_ad_ce], -16 // Load C_1
+(p7) tbit.z.unc p9,p10 = GR_N_SignC, 1
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r7 = FR_r6, FR_r, f0 // Z = Z * r
+(p7) tbit.z.unc p7,p8 = GR_N_SignS, 1
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_loS = FR_rsq, FR_S_5, FR_S_4 // poly_lo=rsq*S_5+S_4
+(p11) tbit.z.unc p13,p14 = GR_N_SignC, 1
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_loC = FR_rsq, FR_C_5, FR_C_4 // poly_lo=rsq*C_5+C_4
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_hiS = FR_rsq, FR_S_2, FR_S_1 // poly_hi=rsq*S_2+S_1
+(p11) tbit.z.unc p11,p12 = GR_N_SignS, 1
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_hiC = FR_rsq, FR_C_2, FR_C_1 // poly_hi=rsq*C_2+C_1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s0 FR_FirstS = FR_r, f1, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s0 FR_FirstC = f1, f1, f0
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r6 = FR_r6, FR_rsq, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r7 = FR_r7, FR_rsq, f0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_loS = FR_rsq, FR_poly_loS, FR_S_3 // p_lo=p_lo*rsq+S_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_loC = FR_rsq, FR_poly_loC, FR_C_3 // p_lo=p_lo*rsq+C_3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s0 FR_inexact = FR_S_4, FR_S_4, f0 // Dummy op to set inexact
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_hiS = FR_poly_hiS, FR_rsq, f0 // p_hi=p_hi*rsq
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_hiC = FR_poly_hiC, FR_rsq, f0 // p_hi=p_hi*rsq
+ nop.i 0
+};;
+
+.pred.rel "mutex",p8,p14
+{ .mfi
+ nop.m 0
+(p8) fms.s0 FR_FirstS = f1, f0, FR_FirstS
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p14) fms.s0 FR_FirstS = f1, f0, FR_FirstS
+ nop.i 0
+};;
+
+.pred.rel "mutex",p10,p12
+{ .mfi
+ nop.m 0
+(p10) fms.s0 FR_FirstC = f1, f0, FR_FirstC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p12) fms.s0 FR_FirstC = f1, f0, FR_FirstC
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyS = FR_r7, FR_poly_loS, FR_cS // poly=Z*poly_lo+c
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyC = FR_r6, FR_poly_loC, FR_cC // poly=Z*poly_lo+c
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_hiS = FR_r, FR_poly_hiS, f0 // p_hi=r*p_hi
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyS = FR_polyS, f1, FR_poly_hiS
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyC = FR_polyC, f1, FR_poly_hiC
+ nop.i 0
+};;
+
+.pred.rel "mutex",p7,p8
+{ .mfi
+ nop.m 0
+(p7) fma.s0 FR_ResultS = FR_FirstS, f1, FR_polyS
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fms.s0 FR_ResultS = FR_FirstS, f1, FR_polyS
+ nop.i 0
+};;
+
+.pred.rel "mutex",p9,p10
+{ .mfi
+ nop.m 0
+(p9) fma.s0 FR_ResultC = FR_FirstC, f1, FR_polyC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fms.s0 FR_ResultC = FR_FirstC, f1, FR_polyC
+ nop.i 0
+};;
+
+.pred.rel "mutex",p11,p12
+{ .mfi
+ nop.m 0
+(p11) fma.s0 FR_ResultS = FR_FirstC, f1, FR_polyC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p12) fms.s0 FR_ResultS = FR_FirstC, f1, FR_polyC
+ nop.i 0
+};;
+
+.pred.rel "mutex",p13,p14
+{ .mfi
+ nop.m 0
+(p13) fma.s0 FR_ResultC = FR_FirstS, f1, FR_polyS
+ nop.i 0
+}
+{ .mfb
+ cmp.eq p15, p0 = 0x1, GR_Cis
+(p14) fms.s0 FR_ResultC = FR_FirstS, f1, FR_polyS
+(p15) br.ret.sptk b0
+};;
+
+
+{ .mmb // exit for sincosl
+ stfe [sincos_pResSin] = FR_ResultS
+ stfe [sincos_pResCos] = FR_ResultC
+ br.ret.sptk b0
+};;
+
+
+
+
+
+
+SINCOSL_NORMAL_R:
+//
+// Here if 2^-3 <= |r| < pi/4
+// THIS IS THE MAIN PATH
+//
+// Enter with r, c, and N_Inc having been computed
+//
+{ .mfi
+ ldfe FR_PP_6 = [GR_ad_pp], 16 // Load PP_6
+ fma.s1 FR_rsq = FR_r, FR_r, f0 // rsq = r * r
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_QQ_6 = [GR_ad_qq], 16 // Load QQ_6
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe FR_PP_5 = [GR_ad_pp], 16 // Load PP_5
+ ldfe FR_QQ_5 = [GR_ad_qq], 16 // Load QQ_5
+ nop.i 0
+};;
+
+
+
+SINCOSL_NORMAL_R_0:
+// Entry for 2^-3 < |x| < pi/4
+.pred.rel "mutex",p9,p10
+{ .mmf
+ ldfe FR_C_1 = [GR_ad_pp], 16 // Load C_1
+ ldfe FR_S_1 = [GR_ad_qq], 16 // Load S_1
+ frcpa.s1 FR_r_hi, p6 = f1, FR_r // r_hi = frcpa(r)
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyS = FR_rsq, FR_PP_8, FR_PP_7 // poly = rsq*PP_8+PP_7
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyC = FR_rsq, FR_QQ_8, FR_QQ_7 // poly = rsq*QQ_8+QQ_7
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_cubed = FR_r, FR_rsq, f0 // rcubed = r * rsq
+ nop.i 0
+};;
+
+
+SINCOSL_NORMAL_R_1:
+// Entry for pi/4 <= |x| < 2^24
+.pred.rel "mutex",p9,p10
+{ .mmf
+ ldfe FR_PP_1 = [GR_ad_pp], 16 // Load PP_1_hi
+ ldfe FR_QQ_1 = [GR_ad_qq], 16 // Load QQ_1
+ frcpa.s1 FR_r_hi, p6 = f1, FR_r_hi // r_hi = frpca(frcpa(r))
+};;
+
+{ .mfi
+ ldfe FR_PP_4 = [GR_ad_pp], 16 // Load PP_4
+ fma.s1 FR_polyS = FR_rsq, FR_polyS, FR_PP_6 // poly = rsq*poly+PP_6
+ and GR_N_SinCos = 0x1, GR_N_Inc
+}
+{ .mfi
+ ldfe FR_QQ_4 = [GR_ad_qq], 16 // Load QQ_4
+ fma.s1 FR_polyC = FR_rsq, FR_polyC, FR_QQ_6 // poly = rsq*poly+QQ_6
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_corrS = FR_C_1, FR_rsq, f0 // corr = C_1 * rsq
+ sub GR_N_SignS = GR_N_Inc, GR_N_SinCos
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_corrC = FR_S_1, FR_r_cubed, FR_r // corr = S_1 * r^3 + r
+ add GR_N_SignC = GR_N_Inc, GR_N_SinCos
+};;
+
+{ .mfi
+ ldfe FR_PP_3 = [GR_ad_pp], 16 // Load PP_3
+ fma.s1 FR_r_hi_sq = FR_r_hi, FR_r_hi, f0 // r_hi_sq = r_hi * r_hi
+ tbit.z p7,p11 = GR_N_Inc, 0
+}
+{ .mfi
+ ldfe FR_QQ_3 = [GR_ad_qq], 16 // Load QQ_3
+ fms.s1 FR_r_lo = FR_r, f1, FR_r_hi // r_lo = r - r_hi
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_PP_2 = [GR_ad_pp], 16 // Load PP_2
+ fma.s1 FR_polyS = FR_rsq, FR_polyS, FR_PP_5 // poly = rsq*poly+PP_5
+(p7) tbit.z.unc p9,p10 = GR_N_SignC, 1
+}
+{ .mfi
+ ldfe FR_QQ_2 = [GR_ad_qq], 16 // Load QQ_2
+ fma.s1 FR_polyC = FR_rsq, FR_polyC, FR_QQ_5 // poly = rsq*poly+QQ_5
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_PP_1_lo = [GR_ad_pp], 16 // Load PP_1_lo
+ fma.s1 FR_corrS = FR_corrS, FR_c, FR_c // corr = corr * c + c
+(p7) tbit.z.unc p7,p8 = GR_N_SignS, 1
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_corrC = FR_corrC, FR_c, f0 // corr = -corr * c
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U_loS = FR_r, FR_r_hi, FR_r_hi_sq // U_lo = r*r_hi+r_hi_sq
+(p11) tbit.z.unc p13,p14 = GR_N_SignC, 1
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U_loC = FR_r_hi, f1, FR_r // U_lo = r_hi + r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U_hiS = FR_r_hi, FR_r_hi_sq, f0 // U_hi = r_hi*r_hi_sq
+(p11) tbit.z.unc p11,p12 = GR_N_SignS, 1
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U_hiC = FR_QQ_1, FR_r_hi_sq, f1 // U_hi = QQ_1*r_hi_sq+1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyS = FR_rsq, FR_polyS, FR_PP_4 // poly = poly*rsq+PP_4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyC = FR_rsq, FR_polyC, FR_QQ_4 // poly = poly*rsq+QQ_4
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U_loS = FR_r, FR_r, FR_U_loS // U_lo = r * r + U_lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U_loC = FR_r_lo, FR_U_loC, f0 // U_lo = r_lo * U_lo
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U_hiS = FR_PP_1, FR_U_hiS, f0 // U_hi = PP_1 * U_hi
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyS = FR_rsq, FR_polyS, FR_PP_3 // poly = poly*rsq+PP_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyC = FR_rsq, FR_polyC, FR_QQ_3 // poly = poly*rsq+QQ_3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U_loS = FR_r_lo, FR_U_loS, f0 // U_lo = r_lo * U_lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U_loC = FR_QQ_1,FR_U_loC, f0 // U_lo = QQ_1 * U_lo
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U_hiS = FR_r, f1, FR_U_hiS // U_hi = r + U_hi
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyS = FR_rsq, FR_polyS, FR_PP_2 // poly = poly*rsq+PP_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyC = FR_rsq, FR_polyC, FR_QQ_2 // poly = poly*rsq+QQ_2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U_loS = FR_PP_1, FR_U_loS, f0 // U_lo = PP_1 * U_lo
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyS = FR_rsq, FR_polyS, FR_PP_1_lo // poly =poly*rsq+PP1lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyC = FR_rsq, FR_polyC, f0 // poly = poly*rsq
+ nop.i 0
+};;
+
+
+.pred.rel "mutex",p8,p14
+{ .mfi
+ nop.m 0
+(p8) fms.s0 FR_U_hiS = f1, f0, FR_U_hiS
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p14) fms.s0 FR_U_hiS = f1, f0, FR_U_hiS
+ nop.i 0
+};;
+
+.pred.rel "mutex",p10,p12
+{ .mfi
+ nop.m 0
+(p10) fms.s0 FR_U_hiC = f1, f0, FR_U_hiC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p12) fms.s0 FR_U_hiC = f1, f0, FR_U_hiC
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_VS = FR_U_loS, f1, FR_corrS // V = U_lo + corr
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_VC = FR_U_loC, f1, FR_corrC // V = U_lo + corr
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s0 FR_inexact = FR_PP_5, FR_PP_4, f0 // Dummy op to set inexact
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyS = FR_r_cubed, FR_polyS, f0 // poly = poly*r^3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_polyC = FR_rsq, FR_polyC, f0 // poly = poly*rsq
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_VS = FR_polyS, f1, FR_VS // V = poly + V
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_VC = FR_polyC, f1, FR_VC // V = poly + V
+ nop.i 0
+};;
+
+
+
+.pred.rel "mutex",p7,p8
+{ .mfi
+ nop.m 0
+(p7) fma.s0 FR_ResultS = FR_U_hiS, f1, FR_VS
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fms.s0 FR_ResultS = FR_U_hiS, f1, FR_VS
+ nop.i 0
+};;
+
+.pred.rel "mutex",p9,p10
+{ .mfi
+ nop.m 0
+(p9) fma.s0 FR_ResultC = FR_U_hiC, f1, FR_VC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fms.s0 FR_ResultC = FR_U_hiC, f1, FR_VC
+ nop.i 0
+};;
+
+
+
+.pred.rel "mutex",p11,p12
+{ .mfi
+ nop.m 0
+(p11) fma.s0 FR_ResultS = FR_U_hiC, f1, FR_VC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p12) fms.s0 FR_ResultS = FR_U_hiC, f1, FR_VC
+ nop.i 0
+};;
+
+.pred.rel "mutex",p13,p14
+{ .mfi
+ nop.m 0
+(p13) fma.s0 FR_ResultC = FR_U_hiS, f1, FR_VS
+ nop.i 0
+}
+{ .mfb
+ cmp.eq p15, p0 = 0x1, GR_Cis
+(p14) fms.s0 FR_ResultC = FR_U_hiS, f1, FR_VS
+(p15) br.ret.sptk b0
+};;
+
+{ .mmb // exit for sincosl
+ stfe [sincos_pResSin] = FR_ResultS
+ stfe [sincos_pResCos] = FR_ResultC
+ br.ret.sptk b0
+};;
+
+
+
+
+
+SINCOSL_ZERO:
+
+{ .mfi
+ nop.m 0
+ fmerge.s FR_ResultS = FR_Input_X, FR_Input_X // If sin, result = input
+ nop.i 0
+}
+{ .mfb
+ cmp.eq p15, p0 = 0x1, GR_Cis
+ fma.s0 FR_ResultC = f1, f1, f0 // If cos, result=1.0
+(p15) br.ret.sptk b0
+};;
+
+{ .mmb // exit for sincosl
+ stfe [sincos_pResSin] = FR_ResultS
+ stfe [sincos_pResCos] = FR_ResultC
+ br.ret.sptk b0
+};;
+
+
+SINCOSL_DENORMAL:
+{ .mmb
+ getf.exp GR_signexp_x = FR_norm_x // Get sign and exponent of x
+ nop.m 999
+ br.cond.sptk SINCOSL_COMMON2 // Return to common code
+}
+;;
+
+
+SINCOSL_SPECIAL:
+//
+// Path for Arg = +/- QNaN, SNaN, Inf
+// Invalid can be raised. SNaNs
+// become QNaNs
+//
+{ .mfi
+ cmp.eq p15, p0 = 0x1, GR_Cis
+ fmpy.s0 FR_ResultS = FR_Input_X, f0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fmpy.s0 FR_ResultC = FR_Input_X, f0
+(p15) br.ret.sptk b0
+};;
+
+{ .mmb // exit for sincosl
+ stfe [sincos_pResSin] = FR_ResultS
+ stfe [sincos_pResCos] = FR_ResultC
+ br.ret.sptk b0
+};;
+
+GLOBAL_LIBM_END(__libm_sincosl)
+
+
+// *******************************************************************
+// *******************************************************************
+// *******************************************************************
+//
+// Special Code to handle very large argument case.
+// Call int __libm_pi_by_2_reduce(x,r,c) for |arguments| >= 2**63
+// The interface is custom:
+// On input:
+// (Arg or x) is in f8
+// On output:
+// r is in f8
+// c is in f9
+// N is in r8
+// Be sure to allocate at least 2 GP registers as output registers for
+// __libm_pi_by_2_reduce. This routine uses r62-63. These are used as
+// scratch registers within the __libm_pi_by_2_reduce routine (for speed).
+//
+// We know also that __libm_pi_by_2_reduce preserves f10-15, f71-127. We
+// use this to eliminate save/restore of key fp registers in this calling
+// function.
+//
+// *******************************************************************
+// *******************************************************************
+// *******************************************************************
+
+LOCAL_LIBM_ENTRY(__libm_callout)
+SINCOSL_ARG_TOO_LARGE:
+.prologue
+{ .mfi
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+};;
+
+{ .mmi
+ setf.exp FR_Two_to_M3 = GR_exp_2_to_m3 // Form 2^-3
+ mov GR_SAVE_GP=gp // Save gp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+//
+// Call argument reduction with x in f8
+// Returns with N in r8, r in f8, c in f9
+// Assumes f71-127 are preserved across the call
+//
+{ .mib
+ setf.exp FR_Neg_Two_to_M3 = GR_exp_m2_to_m3 // Form -(2^-3)
+ nop.i 0
+ br.call.sptk b0=__libm_pi_by_2_reduce#
+};;
+
+{ .mfi
+ mov GR_N_Inc = r8
+ fcmp.lt.unc.s1 p6, p0 = FR_r, FR_Two_to_M3
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mfi
+ mov gp = GR_SAVE_GP // Restore gp
+(p6) fcmp.gt.unc.s1 p6, p0 = FR_r, FR_Neg_Two_to_M3
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+};;
+
+{ .mbb
+ nop.m 0
+(p6) br.cond.spnt SINCOSL_SMALL_R // Branch if |r|< 2^-3 for |x| >= 2^63
+ br.cond.sptk SINCOSL_NORMAL_R // Branch if |r|>=2^-3 for |x| >= 2^63
+};;
+
+LOCAL_LIBM_END(__libm_callout)
+
+.type __libm_pi_by_2_reduce#,@function
+.global __libm_pi_by_2_reduce#
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/libm_support.h b/libc/sysdeps/ia64/fpu/libm_support.h
new file mode 100644
index 000000000..dc9c0a264
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_support.h
@@ -0,0 +1,1051 @@
+/* file: libm_support.h */
+
+
+/*
+// Copyright (c) 2000 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+
+// History: 02/02/2000 Initial version
+// 2/28/2000 added tags for logb and nextafter
+// 3/22/2000 Changes to support _LIB_VERSIONIMF variable
+// and filled some enum gaps. Added support for C99.
+// 5/31/2000 added prototypes for __libm_frexp_4l/8l
+// 8/10/2000 Changed declaration of _LIB_VERSIONIMF to work for library
+// builds and other application builds (precompiler directives).
+// 8/11/2000 Added pointers-to-matherr-functions declarations to allow
+// for user-defined matherr functions in the dll build.
+// 12/07/2000 Added scalbn error_types values.
+// 5/01/2001 Added error_types values for C99 nearest integer
+// functions.
+// 6/07/2001 Added error_types values for fdim.
+// 6/18/2001 Added include of complex_support.h.
+// 8/03/2001 Added error_types values for nexttoward, scalbln.
+// 8/23/2001 Corrected tag numbers from 186 and higher.
+// 8/27/2001 Added check for long int and long long int definitions.
+// 12/10/2001 Added error_types for erfc.
+// 12/27/2001 Added error_types for degree argument functions.
+// 01/02/2002 Added error_types for tand, cotd.
+// 01/04/2002 Delete include of complex_support.h
+// 01/23/2002 Deleted prototypes for __libm_frexp*. Added check for
+// multiple int, long int, and long long int definitions.
+// 05/20/2002 Added error_types for cot.
+// 06/27/2002 Added error_types for sinhcosh.
+// 12/05/2002 Added error_types for annuity and compound
+// 04/10/2003 Added error_types for tgammal/tgamma/tgammaf
+// 05/16/2003 FP-treatment macros copied here from IA32 libm_support.h
+// 06/02/2003 Added pad into struct fp80 (12/16 bytes).
+// 08/01/2003 Added struct ker80 and macros for multiprecision addition,
+// subtraction, multiplication, division, square root.
+// 08/07/2003 History section updated.
+// 09/03/2003 ALIGN(n) macro added.
+// 10/01/2003 LDOUBLE_ALIGN and fp80 corrected on linux to 16 bytes.
+// 11/24/2004 Added ifdef around definitions of INT32/64
+// 12/15/2004 Added error_types for exp10, nextafter, nexttoward
+// underflow. Moved error codes into libm_error_codes.h.
+//
+*/
+
+#ifndef __LIBM_SUPPORT_H_INCLUDED__
+#define __LIBM_SUPPORT_H_INCLUDED__
+
+#ifndef _LIBC
+#if !(defined(_WIN32) || defined(_WIN64))
+# pragma const_seg(".rodata") /* place constant data in text (code) section */
+#endif
+
+#if defined(__ICC) || defined(__ICL) || defined(__ECC) || defined(__ECL)
+# pragma warning( disable : 1682 ) /* #1682: ixplicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem) */
+# pragma warning( disable : 1683 ) /* #1683: explicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem) */
+#endif
+#endif
+
+/* macros to form a double value in hex representation (unsigned int type) */
+
+#define DOUBLE_HEX(hi,lo) 0x##lo,0x##hi /*LITTLE_ENDIAN*/
+
+#include "libm_cpu_defs.h"
+
+#if !(defined (IA64))
+# include "libm_dll.h"
+# include "libm_dispatch.h"
+#endif
+
+#include "libm_error_codes.h"
+
+struct exceptionf
+{
+ int type;
+ char *name;
+ float arg1, arg2, retval;
+};
+
+# ifdef __cplusplus
+struct __exception
+{
+ int type;
+ char *name;
+ double arg1, arg2, retval;
+};
+# else
+
+# ifndef _LIBC
+struct exception
+{
+ int type;
+ char *name;
+ double arg1, arg2, retval;
+};
+# endif
+# endif
+
+struct exceptionl
+{
+ int type;
+ char *name;
+ long double arg1, arg2, retval;
+};
+
+#if (defined (_MS_) && defined (IA64))
+#define MATHERR_F _matherrf
+#define MATHERR_D _matherr
+#else
+#define MATHERR_F matherrf
+#define MATHERR_D matherr
+#endif
+
+# ifdef __cplusplus
+#define EXC_DECL_D __exception
+#else
+// exception is a reserved name in C++
+#define EXC_DECL_D exception
+#endif
+
+extern int MATHERR_F(struct exceptionf*);
+extern int MATHERR_D(struct EXC_DECL_D*);
+extern int matherrl(struct exceptionl*);
+
+#ifndef _LIBC
+// Add code to support _LIB_VERSIONIMF
+typedef enum
+{
+ _IEEE_ = -1, // IEEE-like behavior
+ _SVID_, // SysV, Rel. 4 behavior
+ _XOPEN_, // Unix98
+ _POSIX_, // Posix
+ _ISOC_ // ISO C9X
+} _LIB_VERSION_TYPE;
+#endif
+
+// This is a run-time variable and may affect
+// floating point behavior of the libm functions
+
+#if !defined( LIBM_BUILD )
+#if defined( _DLL )
+extern _LIB_VERSION_TYPE __declspec(dllimport) _LIB_VERSIONIMF;
+#else
+extern _LIB_VERSION_TYPE _LIB_VERSIONIMF;
+#endif /* _DLL */
+#else
+extern int (*pmatherrf)(struct exceptionf*);
+extern int (*pmatherr)(struct EXC_DECL_D*);
+extern int (*pmatherrl)(struct exceptionl*);
+#endif /* LIBM_BUILD */
+
+/* memory format definitions (LITTLE_ENDIAN only) */
+
+#if !(defined(SIZE_INT_32) || defined(SIZE_INT_64))
+# error "You need to define SIZE_INT_32 or SIZE_INT_64"
+#endif
+
+#if (defined(SIZE_INT_32) && defined(SIZE_INT_64))
+#error multiple integer size definitions; define SIZE_INT_32 or SIZE_INT_64
+#endif
+
+#if !(defined(SIZE_LONG_32) || defined(SIZE_LONG_64))
+# error "You need to define SIZE_LONG_32 or SIZE_LONG_64"
+#endif
+
+#if (defined(SIZE_LONG_32) && defined(SIZE_LONG_64))
+#error multiple integer size definitions; define SIZE_LONG_32 or SIZE_LONG_64
+#endif
+
+#if !defined(__USE_EXTERNAL_FPMEMTYP_H__)
+
+#define BIAS_32 0x007F
+#define BIAS_64 0x03FF
+#define BIAS_80 0x3FFF
+
+#define MAXEXP_32 0x00FE
+#define MAXEXP_64 0x07FE
+#define MAXEXP_80 0x7FFE
+
+#define EXPINF_32 0x00FF
+#define EXPINF_64 0x07FF
+#define EXPINF_80 0x7FFF
+
+struct fp32 { /*// sign:1 exponent:8 significand:23 (implied leading 1)*/
+#if defined(SIZE_INT_32)
+ unsigned significand:23;
+ unsigned exponent:8;
+ unsigned sign:1;
+#elif defined(SIZE_INT_64)
+ unsigned significand:23;
+ unsigned exponent:8;
+ unsigned sign:1;
+#endif
+};
+
+struct fp64 { /*/ sign:1 exponent:11 significand:52 (implied leading 1)*/
+#if defined(SIZE_INT_32)
+ unsigned lo_significand:32;
+ unsigned hi_significand:20;
+ unsigned exponent:11;
+ unsigned sign:1;
+#elif defined(SIZE_INT_64)
+ unsigned significand:52;
+ unsigned exponent:11;
+ unsigned sign:1;
+#endif
+};
+
+struct fp80 { /*/ sign:1 exponent:15 significand:64 (NO implied bits) */
+#if defined(SIZE_INT_32)
+ unsigned lo_significand;
+ unsigned hi_significand;
+ unsigned exponent:15;
+ unsigned sign:1;
+#elif defined(SIZE_INT_64)
+ unsigned significand;
+ unsigned exponent:15;
+ unsigned sign:1;
+#endif
+ unsigned pad:16;
+#if !(defined(__unix__) && defined(__i386__))
+ unsigned padwin:32;
+#endif
+};
+
+#endif /*__USE_EXTERNAL_FPMEMTYP_H__*/
+
+#if !(defined(opensource))
+typedef __int32 INT32;
+typedef signed __int32 SINT32;
+typedef unsigned __int32 UINT32;
+
+typedef __int64 INT64;
+typedef signed __int64 SINT64;
+typedef unsigned __int64 UINT64;
+#else
+typedef int INT32;
+typedef signed int SINT32;
+typedef unsigned int UINT32;
+
+typedef long long INT64;
+typedef signed long long SINT64;
+typedef unsigned long long UINT64;
+#endif
+
+#if (defined(_WIN32) || defined(_WIN64)) /* Windows */
+# define I64CONST(bits) 0x##bits##i64
+# define U64CONST(bits) 0x##bits##ui64
+#elif (defined(__linux__) && defined(_M_IA64)) /* Linux,64 */
+# define I64CONST(bits) 0x##bits##L
+# define U64CONST(bits) 0x##bits##uL
+#else /* Linux,32 */
+# define I64CONST(bits) 0x##bits##LL
+# define U64CONST(bits) 0x##bits##uLL
+#endif
+
+struct ker80 {
+ union {
+ long double ldhi;
+ struct fp80 fphi;
+ };
+ union {
+ long double ldlo;
+ struct fp80 fplo;
+ };
+ int ex;
+};
+
+/* Addition: x+y */
+/* The result is sum rhi+rlo */
+/* Temporary variables: t1 */
+/* All variables are in long double precision */
+/* Correct if no overflow (algorithm by D.Knuth) */
+#define __LIBM_ADDL1_K80( rhi,rlo,x,y, t1 ) \
+ rhi = x + y; \
+ rlo = rhi - x; \
+ t1 = rhi - rlo; \
+ rlo = y - rlo; \
+ t1 = x - t1; \
+ rlo = rlo + t1;
+
+/* Addition: (xhi+xlo) + (yhi+ylo) */
+/* The result is sum rhi+rlo */
+/* Temporary variables: t1 */
+/* All variables are in long double precision */
+/* Correct if no overflow (algorithm by T.J.Dekker) */
+#define __LIBM_ADDL2_K80( rhi,rlo,xhi,xlo,yhi,ylo, t1 ) \
+ rlo = xhi+yhi; \
+ if ( VALUE_GT_80(FP80(xhi),FP80(yhi)) ) { \
+ t1=xhi-rlo;t1=t1+yhi;t1=t1+ylo;t1=t1+xlo; \
+ } else { \
+ t1=yhi-rlo;t1=t1+xhi;t1=t1+xlo;t1=t1+ylo; \
+ } \
+ rhi=rlo+t1; \
+ rlo=rlo-rhi;rlo=rlo+t1;
+
+/* Addition: r=x+y */
+/* Variables r,x,y are pointers to struct ker80, */
+/* all other variables are in long double precision */
+/* Temporary variables: t1 */
+/* Correct if x and y belong to interval [2^-8000;2^8000], */
+/* or when one or both of them are zero */
+#if defined(SIZE_INT_32)
+#define __LIBM_ADDL_K80(r,x,y, t1) \
+ if ( ((y)->ex+(y)->fphi.exponent-134 < \
+ (x)->ex+(x)->fphi.exponent) && \
+ ((x)->ex+(x)->fphi.exponent < \
+ (y)->ex+(y)->fphi.exponent+134) && \
+ !SIGNIFICAND_ZERO_80(&((x)->fphi)) && \
+ !SIGNIFICAND_ZERO_80(&((y)->fphi)) ) \
+ { \
+ /* y/2^134 < x < y*2^134, */ \
+ /* and x,y are nonzero finite numbers */ \
+ if ( (x)->ex != (y)->ex ) { \
+ /* adjust x->ex to y->ex */ \
+ /* t1 = 2^(x->ex - y->ex) */ \
+ FP80(t1)->sign = 0; \
+ FP80(t1)->exponent = BIAS_80 + (x)->ex-(y)->ex; \
+ /* exponent is correct because */ \
+ /* |x->ex - y->ex| = */ \
+ /* = | (x->ex + x->fphi.exponent) - */ \
+ /* -(y->ex + y->fphi.exponent) + */ \
+ /* + y->fphi.exponent - */ \
+ /* - x->fphi.exponent | < */ \
+ /* < | (x->ex+x->fphi.exponent) - */ \
+ /* -(y->ex+y->fphi.exponent) | + */ \
+ /* +| y->fphi.exponent - */ \
+ /* -x->fphi.exponent | < */ \
+ /* < 134 + 16000 */ \
+ FP80(t1)->hi_significand = 0x80000000; \
+ FP80(t1)->lo_significand = 0x00000000; \
+ (x)->ex = (y)->ex; \
+ (x)->ldhi *= t1; \
+ (x)->ldlo *= t1; \
+ } \
+ /* r==x+y */ \
+ (r)->ex = (y)->ex; \
+ __LIBM_ADDL2_K80( (r)->ldhi,(r)->ldlo, \
+ (x)->ldhi,(x)->ldlo, (y)->ldhi,(y)->ldlo, t1 ); \
+ } else if ( SIGNIFICAND_ZERO_80(&((x)->fphi)) || \
+ ((y)->ex+(y)->fphi.exponent-BIAS_80 - 134 >= \
+ (x)->ex+(x)->fphi.exponent-BIAS_80) ) \
+ { \
+ /* |x|<<|y| */ \
+ *(r) = *(y); \
+ } else { \
+ /* |y|<<|x| */ \
+ *(r) = *(x); \
+ }
+#elif defined(SIZE_INT_64)
+#define __LIBM_ADDL_K80(r,x,y, t1) \
+ if ( ((y)->ex+(y)->fphi.exponent-134 < \
+ (x)->ex+(x)->fphi.exponent) && \
+ ((x)->ex+(x)->fphi.exponent < \
+ (y)->ex+(y)->fphi.exponent+134) && \
+ !SIGNIFICAND_ZERO_80(&((x)->fphi)) && \
+ !SIGNIFICAND_ZERO_80(&((y)->fphi)) ) \
+ { \
+ /* y/2^134 < x < y*2^134, */ \
+ /* and x,y are nonzero finite numbers */ \
+ if ( (x)->ex != (y)->ex ) { \
+ /* adjust x->ex to y->ex */ \
+ /* t1 = 2^(x->ex - y->ex) */ \
+ FP80(t1)->sign = 0; \
+ FP80(t1)->exponent = BIAS_80 + (x)->ex-(y)->ex; \
+ /* exponent is correct because */ \
+ /* |x->ex - y->ex| = */ \
+ /* = | (x->ex + x->fphi.exponent) - */ \
+ /* -(y->ex + y->fphi.exponent) + */ \
+ /* + y->fphi.exponent - */ \
+ /* - x->fphi.exponent | < */ \
+ /* < | (x->ex+x->fphi.exponent) - */ \
+ /* -(y->ex+y->fphi.exponent) | + */ \
+ /* +| y->fphi.exponent - */ \
+ /* -x->fphi.exponent | < */ \
+ /* < 134 + 16000 */ \
+ FP80(t1)->significand = 0x8000000000000000; \
+ (x)->ex = (y)->ex; \
+ (x)->ldhi *= t1; \
+ (x)->ldlo *= t1; \
+ } \
+ /* r==x+y */ \
+ (r)->ex = (y)->ex; \
+ __LIBM_ADDL2_K80( (r)->ldhi,(r)->ldlo, \
+ (x)->ldhi,(x)->ldlo, (y)->ldhi,(y)->ldlo, t1 ); \
+ } else if ( SIGNIFICAND_ZERO_80(&((x)->fphi)) || \
+ ((y)->ex+(y)->fphi.exponent-BIAS_80 - 134 >= \
+ (x)->ex+(x)->fphi.exponent-BIAS_80) ) \
+ { \
+ /* |x|<<|y| */ \
+ *(r) = *(y); \
+ } else { \
+ /* |y|<<|x| */ \
+ *(r) = *(x); \
+ }
+#endif
+
+/* Addition: r=x+y */
+/* Variables r,x,y are pointers to struct ker80, */
+/* all other variables are in long double precision */
+/* Temporary variables: t1 */
+/* Correct for any finite x and y */
+#define __LIBM_ADDL_NORM_K80(r,x,y, t1) \
+ if ( ((x)->fphi.exponent-BIAS_80<-8000) || \
+ ((x)->fphi.exponent-BIAS_80>+8000) || \
+ ((y)->fphi.exponent-BIAS_80<-8000) || \
+ ((y)->fphi.exponent-BIAS_80>+8000) ) \
+ { \
+ __libm_normalizel_k80(x); \
+ __libm_normalizel_k80(y); \
+ } \
+ __LIBM_ADDL_K80(r,x,y, t1)
+
+/* Subtraction: x-y */
+/* The result is sum rhi+rlo */
+/* Temporary variables: t1 */
+/* All variables are in long double precision */
+/* Correct if no overflow (algorithm by D.Knuth) */
+#define __LIBM_SUBL1_K80( rhi, rlo, x, y, t1 ) \
+ rhi = x - y; \
+ rlo = rhi - x; \
+ t1 = rhi - rlo; \
+ rlo = y + rlo; \
+ t1 = x - t1; \
+ rlo = t1 - rlo;
+
+/* Subtraction: (xhi+xlo) - (yhi+ylo) */
+/* The result is sum rhi+rlo */
+/* Temporary variables: t1 */
+/* All variables are in long double precision */
+/* Correct if no overflow (algorithm by T.J.Dekker) */
+#define __LIBM_SUBL2_K80( rhi,rlo,xhi,xlo,yhi,ylo, t1 ) \
+ rlo = xhi-yhi; \
+ if ( VALUE_GT_80(FP80(xhi),FP80(yhi)) ) { \
+ t1=xhi-rlo;t1=t1-yhi;t1=t1-ylo;t1=t1+xlo; \
+ } else { \
+ t1=yhi+rlo;t1=xhi-t1;t1=t1+xlo;t1=t1-ylo; \
+ } \
+ rhi=rlo+t1; \
+ rlo=rlo-rhi;rlo=rlo+t1;
+
+/* Subtraction: r=x-y */
+/* Variables r,x,y are pointers to struct ker80, */
+/* all other variables are in long double precision */
+/* Temporary variables: t1 */
+/* Correct if x and y belong to interval [2^-8000;2^8000], */
+/* or when one or both of them are zero */
+#if defined(SIZE_INT_32)
+#define __LIBM_SUBL_K80(r,x,y, t1) \
+ if ( ((y)->ex+(y)->fphi.exponent-134 < \
+ (x)->ex+(x)->fphi.exponent) && \
+ ((x)->ex+(x)->fphi.exponent < \
+ (y)->ex+(y)->fphi.exponent+134) && \
+ !SIGNIFICAND_ZERO_80(&((x)->fphi)) && \
+ !SIGNIFICAND_ZERO_80(&((y)->fphi)) ) \
+ { \
+ /* y/2^134 < x < y*2^134, */ \
+ /* and x,y are nonzero finite numbers */ \
+ if ( (x)->ex != (y)->ex ) { \
+ /* adjust x->ex to y->ex */ \
+ /* t1 = 2^(x->ex - y->ex) */ \
+ FP80(t1)->sign = 0; \
+ FP80(t1)->exponent = BIAS_80 + (x)->ex-(y)->ex; \
+ /* exponent is correct because */ \
+ /* |x->ex - y->ex| = */ \
+ /* = | (x->ex + x->fphi.exponent) - */ \
+ /* -(y->ex + y->fphi.exponent) + */ \
+ /* + y->fphi.exponent - */ \
+ /* - x->fphi.exponent | < */ \
+ /* < | (x->ex+x->fphi.exponent) - */ \
+ /* -(y->ex+y->fphi.exponent) | + */ \
+ /* +| y->fphi.exponent - */ \
+ /* -x->fphi.exponent | < */ \
+ /* < 134 + 16000 */ \
+ FP80(t1)->hi_significand = 0x80000000; \
+ FP80(t1)->lo_significand = 0x00000000; \
+ (x)->ex = (y)->ex; \
+ (x)->ldhi *= t1; \
+ (x)->ldlo *= t1; \
+ } \
+ /* r==x+y */ \
+ (r)->ex = (y)->ex; \
+ __LIBM_SUBL2_K80( (r)->ldhi,(r)->ldlo, \
+ (x)->ldhi,(x)->ldlo, (y)->ldhi,(y)->ldlo, t1 ); \
+ } else if ( SIGNIFICAND_ZERO_80(&((x)->fphi)) || \
+ ((y)->ex+(y)->fphi.exponent-BIAS_80 - 134 >= \
+ (x)->ex+(x)->fphi.exponent-BIAS_80) ) \
+ { \
+ /* |x|<<|y| */ \
+ (r)->ex = (y)->ex; \
+ (r)->ldhi = -((y)->ldhi); \
+ (r)->ldlo = -((y)->ldlo); \
+ } else { \
+ /* |y|<<|x| */ \
+ *(r) = *(x); \
+ }
+#elif defined(SIZE_INT_64)
+#define __LIBM_SUBL_K80(r,x,y, t1) \
+ if ( ((y)->ex+(y)->fphi.exponent-134 < \
+ (x)->ex+(x)->fphi.exponent) && \
+ ((x)->ex+(x)->fphi.exponent < \
+ (y)->ex+(y)->fphi.exponent+134) && \
+ !SIGNIFICAND_ZERO_80(&((x)->fphi)) && \
+ !SIGNIFICAND_ZERO_80(&((y)->fphi)) ) \
+ { \
+ /* y/2^134 < x < y*2^134, */ \
+ /* and x,y are nonzero finite numbers */ \
+ if ( (x)->ex != (y)->ex ) { \
+ /* adjust x->ex to y->ex */ \
+ /* t1 = 2^(x->ex - y->ex) */ \
+ FP80(t1)->sign = 0; \
+ FP80(t1)->exponent = BIAS_80 + (x)->ex-(y)->ex; \
+ /* exponent is correct because */ \
+ /* |x->ex - y->ex| = */ \
+ /* = | (x->ex + x->fphi.exponent) - */ \
+ /* -(y->ex + y->fphi.exponent) + */ \
+ /* + y->fphi.exponent - */ \
+ /* - x->fphi.exponent | < */ \
+ /* < | (x->ex+x->fphi.exponent) - */ \
+ /* -(y->ex+y->fphi.exponent) | + */ \
+ /* +| y->fphi.exponent - */ \
+ /* -x->fphi.exponent | < */ \
+ /* < 134 + 16000 */ \
+ FP80(t1)->significand = 0x8000000000000000; \
+ (x)->ex = (y)->ex; \
+ (x)->ldhi *= t1; \
+ (x)->ldlo *= t1; \
+ } \
+ /* r==x+y */ \
+ (r)->ex = (y)->ex; \
+ __LIBM_SUBL2_K80( (r)->ldhi,(r)->ldlo, \
+ (x)->ldhi,(x)->ldlo, (y)->ldhi,(y)->ldlo, t1 ); \
+ } else if ( SIGNIFICAND_ZERO_80(&((x)->fphi)) || \
+ ((y)->ex+(y)->fphi.exponent-BIAS_80 - 134 >= \
+ (x)->ex+(x)->fphi.exponent-BIAS_80) ) \
+ { \
+ /* |x|<<|y| */ \
+ (r)->ex = (y)->ex; \
+ (r)->ldhi = -((y)->ldhi); \
+ (r)->ldlo = -((y)->ldlo); \
+ } else { \
+ /* |y|<<|x| */ \
+ *(r) = *(x); \
+ }
+#endif
+
+/* Subtraction: r=x+y */
+/* Variables r,x,y are pointers to struct ker80, */
+/* all other variables are in long double precision */
+/* Temporary variables: t1 */
+/* Correct for any finite x and y */
+#define __LIBM_SUBL_NORM_K80(r,x,y, t1) \
+ if ( ((x)->fphi.exponent-BIAS_80<-8000) || \
+ ((x)->fphi.exponent-BIAS_80>+8000) || \
+ ((y)->fphi.exponent-BIAS_80<-8000) || \
+ ((y)->fphi.exponent-BIAS_80>+8000) ) \
+ { \
+ __libm_normalizel_k80(x); \
+ __libm_normalizel_k80(y); \
+ } \
+ __LIBM_SUBL_K80(r,x,y, t1)
+
+/* Multiplication: x*y */
+/* The result is sum rhi+rlo */
+/* Here t32 is the constant 2^32+1 */
+/* Temporary variables: t1,t2,t3,t4,t5,t6 */
+/* All variables are in long double precision */
+/* Correct if no over/underflow (algorithm by T.J.Dekker) */
+#define __LIBM_MULL1_K80(rhi,rlo,x,y, \
+ t32,t1,t2,t3,t4,t5,t6) \
+ t1=(x)*(t32); t3=x-t1; t3=t3+t1; t4=x-t3; \
+ t1=(y)*(t32); t5=y-t1; t5=t5+t1; t6=y-t5; \
+ t1=(t3)*(t5); \
+ t2=(t3)*(t6)+(t4)*(t5); \
+ rhi=t1+t2; \
+ rlo=t1-rhi; rlo=rlo+t2; rlo=rlo+(t4*t6);
+
+/* Multiplication: (xhi+xlo)*(yhi+ylo) */
+/* The result is sum rhi+rlo */
+/* Here t32 is the constant 2^32+1 */
+/* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8 */
+/* All variables are in long double precision */
+/* Correct if no over/underflow (algorithm by T.J.Dekker) */
+#define __LIBM_MULL2_K80(rhi,rlo,xhi,xlo,yhi,ylo, \
+ t32,t1,t2,t3,t4,t5,t6,t7,t8) \
+ __LIBM_MULL1_K80(t7,t8,xhi,yhi, t32,t1,t2,t3,t4,t5,t6) \
+ t1=(xhi)*(ylo)+(xlo)*(yhi); t1=t1+t8; \
+ rhi=t7+t1; \
+ rlo=t7-rhi; rlo=rlo+t1;
+
+/* Multiplication: r=x*y */
+/* Variables r,x,y are pointers to struct ker80, */
+/* all other variables are in long double precision */
+/* Here t32 is the constant 2^32+1 */
+/* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8 */
+/* Correct if x and y belong to interval [2^-8000;2^8000] */
+#define __LIBM_MULL_K80(r,x,y, t32,t1,t2,t3,t4,t5,t6,t7,t8) \
+ (r)->ex = (x)->ex + (y)->ex; \
+ __LIBM_MULL2_K80((r)->ldhi,(r)->ldlo, \
+ (x)->ldhi,(x)->ldlo,(y)->ldhi,(y)->ldlo, \
+ t32,t1,t2,t3,t4,t5,t6,t7,t8)
+
+/* Multiplication: r=x*y */
+/* Variables r,x,y are pointers to struct ker80, */
+/* all other variables are in long double precision */
+/* Here t32 is the constant 2^32+1 */
+/* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8 */
+/* Correct for any finite x and y */
+#define __LIBM_MULL_NORM_K80(r,x,y, \
+ t32,t1,t2,t3,t4,t5,t6,t7,t8) \
+ if ( ((x)->fphi.exponent-BIAS_80<-8000) || \
+ ((x)->fphi.exponent-BIAS_80>+8000) || \
+ ((y)->fphi.exponent-BIAS_80<-8000) || \
+ ((y)->fphi.exponent-BIAS_80>+8000) ) \
+ { \
+ __libm_normalizel_k80(x); \
+ __libm_normalizel_k80(y); \
+ } \
+ __LIBM_MULL_K80(r,x,y, t32,t1,t2,t3,t4,t5,t6,t7,t8)
+
+/* Division: (xhi+xlo)/(yhi+ylo) */
+/* The result is sum rhi+rlo */
+/* Here t32 is the constant 2^32+1 */
+/* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8,t9 */
+/* All variables are in long double precision */
+/* Correct if no over/underflow (algorithm by T.J.Dekker) */
+#define __LIBM_DIVL2_K80(rhi,rlo,xhi,xlo,yhi,ylo, \
+ t32,t1,t2,t3,t4,t5,t6,t7,t8,t9) \
+ t7=(xhi)/(yhi); \
+ __LIBM_MULL1_K80(t8,t9,t7,yhi, t32,t1,t2,t3,t4,t5,t6) \
+ t1=xhi-t8; t1=t1-t9; t1=t1+xlo; t1=t1-(t7)*(ylo); \
+ t1=(t1)/(yhi); \
+ rhi=t7+t1; \
+ rlo=t7-rhi; rlo=rlo+t1;
+
+/* Division: r=x/y */
+/* Variables r,x,y are pointers to struct ker80, */
+/* all other variables are in long double precision */
+/* Here t32 is the constant 2^32+1 */
+/* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8,t9 */
+/* Correct if x and y belong to interval [2^-8000;2^8000] */
+#define __LIBM_DIVL_K80(r,x,y, \
+ t32,t1,t2,t3,t4,t5,t6,t7,t8,t9) \
+ (r)->ex = (x)->ex - (y)->ex; \
+ __LIBM_DIVL2_K80( (r)->ldhi,(r)->ldlo, \
+ (x)->ldhi,(x)->ldlo,(y)->ldhi,(y)->ldlo, \
+ t32,t1,t2,t3,t4,t5,t6,t7,t8,t9)
+
+/* Division: r=x/y */
+/* Variables r,x,y are pointers to struct ker80, */
+/* all other variables are in long double precision */
+/* Here t32 is the constant 2^32+1 */
+/* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8 */
+/* Correct for any finite x and y */
+#define __LIBM_DIVL_NORM_K80(r,x,y, \
+ t32,t1,t2,t3,t4,t5,t6,t7,t8,t9) \
+ if ( ((x)->fphi.exponent-BIAS_80<-8000) || \
+ ((x)->fphi.exponent-BIAS_80>+8000) || \
+ ((y)->fphi.exponent-BIAS_80<-8000) || \
+ ((y)->fphi.exponent-BIAS_80>+8000) ) \
+ { \
+ __libm_normalizel_k80(x); \
+ __libm_normalizel_k80(y); \
+ } \
+ __LIBM_DIVL_K80(r,x,y, t32,t1,t2,t3,t4,t5,t6,t7,t8,t9)
+
+/* Square root: sqrt(xhi+xlo) */
+/* The result is sum rhi+rlo */
+/* Here t32 is the constant 2^32+1 */
+/* half is the constant 0.5 */
+/* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8,t9 */
+/* All variables are in long double precision */
+/* Correct for positive xhi+xlo (algorithm by T.J.Dekker) */
+#define __LIBM_SQRTL2_NORM_K80(rhi,rlo,xhi,xlo, \
+ t32,half,t1,t2,t3,t4,t5,t6,t7,t8,t9) \
+ t7=sqrtl(xhi); \
+ __LIBM_MULL1_K80(t8,t9,t7,t7, t32,t1,t2,t3,t4,t5,t6) \
+ t1=xhi-t8; t1=t1-t9; t1=t1+xlo; t1=(t1)*(half); \
+ t1=(t1)/(t7); \
+ rhi=t7+t1; \
+ rlo=t7-rhi; rlo=rlo+t1;
+
+/* Square root: r=sqrt(x) */
+/* Variables r,x,y are pointers to struct ker80, */
+/* all other variables are in long double precision */
+/* Here t32 is the constant 2^32+1 */
+/* half is the constant 0.5 */
+/* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8,t9 */
+/* Correct if x belongs to interval [2^-16000;2^16000] */
+#define __LIBM_SQRTL_K80(r,x, \
+ t32,half,t1,t2,t3,t4,t5,t6,t7,t8,t9) \
+ if ( ((x)->ex & 1) == 1 ) { \
+ (x)->ex = (x)->ex + 1; \
+ (x)->ldhi *= half; \
+ (x)->ldlo *= half; \
+ } \
+ (r)->ex = (x)->ex >> 1; \
+ __LIBM_SQRTL2_NORM_K80( (r)->ldhi,(r)->ldlo, \
+ (x)->ldhi,(x)->ldlo, \
+ t32,half,t1,t2,t3,t4,t5,t6,t7,t8,t9)
+
+/* Square root: r=sqrt(x) */
+/* Variables r,x,y are pointers to struct ker80, */
+/* all other variables are in long double precision */
+/* Here t32 is the constant 2^32+1 */
+/* half is the constant 0.5 */
+/* Temporary variables: t1,t2,t3,t4,t5,t6,t7,t8,t9 */
+/* Correct for any positive x */
+#define __LIBM_SQRTL_NORM_K80(r,x, \
+ t32,half,t1,t2,t3,t4,t5,t6,t7,t8,t9) \
+ if ( ((x)->fphi.exponent-BIAS_80<-16000) || \
+ ((x)->fphi.exponent-BIAS_80>+16000) ) \
+ { \
+ __libm_normalizel_k80(x); \
+ } \
+ __LIBM_SQRTL_K80(r,x, t32,half,t1,t2,t3,t4,t5,t6,t7,t8,t9)
+
+
+#ifdef __INTEL_COMPILER
+#define ALIGN(n) __declspec(align(n))
+#else /* __INTEL_COMPILER */
+#define ALIGN(n)
+#endif /* __INTEL_COMPILER */
+
+/* macros to form a long double value in hex representation (unsigned short type) */
+
+#if (defined(__unix__) && defined(__i386__))
+# define LDOUBLE_ALIGN 12 /* IA32 Linux: 12-byte alignment */
+#else /*__linux__ & IA32*/
+# define LDOUBLE_ALIGN 16 /* EFI2/IA32 Win or IPF Win/Linux: 16-byte alignment */
+#endif /*__linux__ & IA32*/
+
+#if (LDOUBLE_ALIGN == 16)
+#define _XPD_ ,0x0000,0x0000,0x0000
+#else /*12*/
+#define _XPD_ ,0x0000
+#endif
+
+#define LDOUBLE_HEX(w4,w3,w2,w1,w0) 0x##w0,0x##w1,0x##w2,0x##w3,0x##w4 _XPD_ /*LITTLE_ENDIAN*/
+
+/* macros to sign-expand low 'num' bits of 'val' to native integer */
+
+#if defined(SIZE_INT_32)
+# define SIGN_EXPAND(val,num) ((int)(val) << (32-(num))) >> (32-(num)) /* sign expand of 'num' LSBs */
+#elif defined(SIZE_INT_64)
+# define SIGN_EXPAND(val,num) ((int)(val) << (64-(num))) >> (64-(num)) /* sign expand of 'num' LSBs */
+#endif
+
+/* macros to form pointers to FP number on-the-fly */
+
+#define FP32(f) ((struct fp32 *)&f)
+#define FP64(d) ((struct fp64 *)&d)
+#define FP80(ld) ((struct fp80 *)&ld)
+
+/* macros to extract signed low and high doubleword of long double */
+
+#if defined(SIZE_INT_32)
+# define HI_DWORD_80(ld) ((((FP80(ld)->sign << 15) | FP80(ld)->exponent) << 16) | \
+ ((FP80(ld)->hi_significand >> 16) & 0xFFFF))
+# define LO_DWORD_80(ld) SIGN_EXPAND(FP80(ld)->lo_significand, 32)
+#elif defined(SIZE_INT_64)
+# define HI_DWORD_80(ld) ((((FP80(ld)->sign << 15) | FP80(ld)->exponent) << 16) | \
+ ((FP80(ld)->significand >> 48) & 0xFFFF))
+# define LO_DWORD_80(ld) SIGN_EXPAND(FP80(ld)->significand, 32)
+#endif
+
+/* macros to extract hi bits of significand.
+ * note that explicit high bit do not count (returns as is)
+ */
+
+#if defined(SIZE_INT_32)
+# define HI_SIGNIFICAND_80(X,NBITS) ((X)->hi_significand >> (31 - (NBITS)))
+#elif defined(SIZE_INT_64)
+# define HI_SIGNIFICAND_80(X,NBITS) ((X)->significand >> (63 - (NBITS)))
+#endif
+
+/* macros to check, whether a significand bits are all zero, or some of them are non-zero.
+ * note that SIGNIFICAND_ZERO_80 tests high bit also, but SIGNIFICAND_NONZERO_80 does not
+ */
+
+#define SIGNIFICAND_ZERO_32(X) ((X)->significand == 0)
+#define SIGNIFICAND_NONZERO_32(X) ((X)->significand != 0)
+
+#if defined(SIZE_INT_32)
+# define SIGNIFICAND_ZERO_64(X) (((X)->hi_significand == 0) && ((X)->lo_significand == 0))
+# define SIGNIFICAND_NONZERO_64(X) (((X)->hi_significand != 0) || ((X)->lo_significand != 0))
+#elif defined(SIZE_INT_64)
+# define SIGNIFICAND_ZERO_64(X) ((X)->significand == 0)
+# define SIGNIFICAND_NONZERO_64(X) ((X)->significand != 0)
+#endif
+
+#if defined(SIZE_INT_32)
+# define SIGNIFICAND_ZERO_80(X) (((X)->hi_significand == 0x00000000) && ((X)->lo_significand == 0))
+# define SIGNIFICAND_NONZERO_80(X) (((X)->hi_significand != 0x80000000) || ((X)->lo_significand != 0))
+#elif defined(SIZE_INT_64)
+# define SIGNIFICAND_ZERO_80(X) ((X)->significand == 0x0000000000000000)
+# define SIGNIFICAND_NONZERO_80(X) ((X)->significand != 0x8000000000000000)
+#endif
+
+/* macros to compare long double with constant value, represented as hex */
+
+#define SIGNIFICAND_EQ_HEX_32(X,BITS) ((X)->significand == 0x ## BITS)
+#define SIGNIFICAND_GT_HEX_32(X,BITS) ((X)->significand > 0x ## BITS)
+#define SIGNIFICAND_GE_HEX_32(X,BITS) ((X)->significand >= 0x ## BITS)
+#define SIGNIFICAND_LT_HEX_32(X,BITS) ((X)->significand < 0x ## BITS)
+#define SIGNIFICAND_LE_HEX_32(X,BITS) ((X)->significand <= 0x ## BITS)
+
+#if defined(SIZE_INT_32)
+# define SIGNIFICAND_EQ_HEX_64(X,HI,LO) \
+ (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand == 0x ## LO))
+# define SIGNIFICAND_GT_HEX_64(X,HI,LO) (((X)->hi_significand > 0x ## HI) || \
+ (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand > 0x ## LO)))
+# define SIGNIFICAND_GE_HEX_64(X,HI,LO) (((X)->hi_significand > 0x ## HI) || \
+ (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand >= 0x ## LO)))
+# define SIGNIFICAND_LT_HEX_64(X,HI,LO) (((X)->hi_significand < 0x ## HI) || \
+ (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand < 0x ## LO)))
+# define SIGNIFICAND_LE_HEX_64(X,HI,LO) (((X)->hi_significand < 0x ## HI) || \
+ (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand <= 0x ## LO)))
+#elif defined(SIZE_INT_64)
+# define SIGNIFICAND_EQ_HEX_64(X,HI,LO) ((X)->significand == 0x ## HI ## LO)
+# define SIGNIFICAND_GT_HEX_64(X,HI,LO) ((X)->significand > 0x ## HI ## LO)
+# define SIGNIFICAND_GE_HEX_64(X,HI,LO) ((X)->significand >= 0x ## HI ## LO)
+# define SIGNIFICAND_LT_HEX_64(X,HI,LO) ((X)->significand < 0x ## HI ## LO)
+# define SIGNIFICAND_LE_HEX_64(X,HI,LO) ((X)->significand <= 0x ## HI ## LO)
+#endif
+
+#if defined(SIZE_INT_32)
+# define SIGNIFICAND_EQ_HEX_80(X,HI,LO) \
+ (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand == 0x ## LO))
+# define SIGNIFICAND_GT_HEX_80(X,HI,LO) (((X)->hi_significand > 0x ## HI) || \
+ (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand > 0x ## LO)))
+# define SIGNIFICAND_GE_HEX_80(X,HI,LO) (((X)->hi_significand > 0x ## HI) || \
+ (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand >= 0x ## LO)))
+# define SIGNIFICAND_LT_HEX_80(X,HI,LO) (((X)->hi_significand < 0x ## HI) || \
+ (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand < 0x ## LO)))
+# define SIGNIFICAND_LE_HEX_80(X,HI,LO) (((X)->hi_significand < 0x ## HI) || \
+ (((X)->hi_significand == 0x ## HI) && ((X)->lo_significand <= 0x ## LO)))
+#elif defined(SIZE_INT_64)
+# define SIGNIFICAND_EQ_HEX_80(X,HI,LO) ((X)->significand == 0x ## HI ## LO)
+# define SIGNIFICAND_GT_HEX_80(X,HI,LO) ((X)->significand > 0x ## HI ## LO)
+# define SIGNIFICAND_GE_HEX_80(X,HI,LO) ((X)->significand >= 0x ## HI ## LO)
+# define SIGNIFICAND_LT_HEX_80(X,HI,LO) ((X)->significand < 0x ## HI ## LO)
+# define SIGNIFICAND_LE_HEX_80(X,HI,LO) ((X)->significand <= 0x ## HI ## LO)
+#endif
+
+#define VALUE_EQ_HEX_32(X,EXP,BITS) \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_EQ_HEX_32(X, BITS)))
+#define VALUE_GT_HEX_32(X,EXP,BITS) (((X)->exponent > (EXP)) || \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_GT_HEX_32(X, BITS))))
+#define VALUE_GE_HEX_32(X,EXP,BITS) (((X)->exponent > (EXP)) || \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_GE_HEX_32(X, BITS))))
+#define VALUE_LT_HEX_32(X,EXP,BITS) (((X)->exponent < (EXP)) || \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_LT_HEX_32(X, BITS))))
+#define VALUE_LE_HEX_32(X,EXP,BITS) (((X)->exponent < (EXP)) || \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_LE_HEX_32(X, BITS))))
+
+#define VALUE_EQ_HEX_64(X,EXP,HI,LO) \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_EQ_HEX_64(X, HI, LO)))
+#define VALUE_GT_HEX_64(X,EXP,HI,LO) (((X)->exponent > (EXP)) || \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_GT_HEX_64(X, HI, LO))))
+#define VALUE_GE_HEX_64(X,EXP,HI,LO) (((X)->exponent > (EXP)) || \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_GE_HEX_64(X, HI, LO))))
+#define VALUE_LT_HEX_64(X,EXP,HI,LO) (((X)->exponent < (EXP)) || \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_LT_HEX_64(X, HI, LO))))
+#define VALUE_LE_HEX_64(X,EXP,HI,LO) (((X)->exponent < (EXP)) || \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_LE_HEX_64(X, HI, LO))))
+
+#define VALUE_EQ_HEX_80(X,EXP,HI,LO) \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_EQ_HEX_80(X, HI, LO)))
+#define VALUE_GT_HEX_80(X,EXP,HI,LO) (((X)->exponent > (EXP)) || \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_GT_HEX_80(X, HI, LO))))
+#define VALUE_GE_HEX_80(X,EXP,HI,LO) (((X)->exponent > (EXP)) || \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_GE_HEX_80(X, HI, LO))))
+#define VALUE_LT_HEX_80(X,EXP,HI,LO) (((X)->exponent < (EXP)) || \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_LT_HEX_80(X, HI, LO))))
+#define VALUE_LE_HEX_80(X,EXP,HI,LO) (((X)->exponent < (EXP)) || \
+ (((X)->exponent == (EXP)) && (SIGNIFICAND_LE_HEX_80(X, HI, LO))))
+
+/* macros to compare two long doubles */
+
+#define SIGNIFICAND_EQ_32(X,Y) ((X)->significand == (Y)->significand)
+#define SIGNIFICAND_GT_32(X,Y) ((X)->significand > (Y)->significand)
+#define SIGNIFICAND_GE_32(X,Y) ((X)->significand >= (Y)->significand)
+#define SIGNIFICAND_LT_32(X,Y) ((X)->significand < (Y)->significand)
+#define SIGNIFICAND_LE_32(X,Y) ((X)->significand <= (Y)->significand)
+
+#if defined(SIZE_INT_32)
+# define SIGNIFICAND_EQ_64(X,Y) \
+ (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand == (Y)->lo_significand))
+# define SIGNIFICAND_GT_64(X,Y) (((X)->hi_significand > (Y)->hi_significand) || \
+ (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand > (Y)->lo_significand)))
+# define SIGNIFICAND_GE_64(X,Y) (((X)->hi_significand > (Y)->hi_significand) || \
+ (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand >= (Y)->lo_significand)))
+# define SIGNIFICAND_LT_64(X,Y) (((X)->hi_significand < (Y)->hi_significand) || \
+ (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand < (Y)->lo_significand)))
+# define SIGNIFICAND_LE_64(X,Y) (((X)->hi_significand < (Y)->hi_significand) || \
+ (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand <= (Y)->lo_significand)))
+#elif defined(SIZE_INT_64)
+# define SIGNIFICAND_EQ_64(X,Y) ((X)->significand == (Y)->significand)
+# define SIGNIFICAND_GT_64(X,Y) ((X)->significand > (Y)->significand)
+# define SIGNIFICAND_GE_64(X,Y) ((X)->significand >= (Y)->significand)
+# define SIGNIFICAND_LT_64(X,Y) ((X)->significand < (Y)->significand)
+# define SIGNIFICAND_LE_64(X,Y) ((X)->significand <= (Y)->significand)
+#endif
+
+#if defined(SIZE_INT_32)
+# define SIGNIFICAND_EQ_80(X,Y) \
+ (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand == (Y)->lo_significand))
+# define SIGNIFICAND_GT_80(X,Y) (((X)->hi_significand > (Y)->hi_significand) || \
+ (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand > (Y)->lo_significand)))
+# define SIGNIFICAND_GE_80(X,Y) (((X)->hi_significand > (Y)->hi_significand) || \
+ (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand >= (Y)->lo_significand)))
+# define SIGNIFICAND_LT_80(X,Y) (((X)->hi_significand < (Y)->hi_significand) || \
+ (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand < (Y)->lo_significand)))
+# define SIGNIFICAND_LE_80(X,Y) (((X)->hi_significand < (Y)->hi_significand) || \
+ (((X)->hi_significand == (Y)->hi_significand) && ((X)->lo_significand <= (Y)->lo_significand)))
+#elif defined(SIZE_INT_64)
+# define SIGNIFICAND_EQ_80(X,Y) ((X)->significand == (Y)->significand)
+# define SIGNIFICAND_GT_80(X,Y) ((X)->significand > (Y)->significand)
+# define SIGNIFICAND_GE_80(X,Y) ((X)->significand >= (Y)->significand)
+# define SIGNIFICAND_LT_80(X,Y) ((X)->significand < (Y)->significand)
+# define SIGNIFICAND_LE_80(X,Y) ((X)->significand <= (Y)->significand)
+#endif
+
+#define VALUE_EQ_32(X,Y) \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_EQ_32(X, Y)))
+#define VALUE_GT_32(X,Y) (((X)->exponent > (Y)->exponent) || \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GT_32(X, Y))))
+#define VALUE_GE_32(X,Y) (((X)->exponent > (Y)->exponent) || \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GE_32(X, Y))))
+#define VALUE_LT_32(X,Y) (((X)->exponent < (Y)->exponent) || \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LT_32(X, Y))))
+#define VALUE_LE_32(X,Y) (((X)->exponent < (Y)->exponent) || \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LE_32(X, Y))))
+
+#define VALUE_EQ_64(X,Y) \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_EQ_64(X, Y)))
+#define VALUE_GT_64(X,Y) (((X)->exponent > (Y)->exponent) || \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GT_64(X, Y))))
+#define VALUE_GE_64(X,Y) (((X)->exponent > (Y)->exponent) || \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GE_64(X, Y))))
+#define VALUE_LT_64(X,Y) (((X)->exponent < (Y)->exponent) || \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LT_64(X, Y))))
+#define VALUE_LE_64(X,Y) (((X)->exponent < (Y)->exponent) || \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LE_64(X, Y))))
+
+#define VALUE_EQ_80(X,Y) \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_EQ_80(X, Y)))
+#define VALUE_GT_80(X,Y) (((X)->exponent > (Y)->exponent) || \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GT_80(X, Y))))
+#define VALUE_GE_80(X,Y) (((X)->exponent > (Y)->exponent) || \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_GE_80(X, Y))))
+#define VALUE_LT_80(X,Y) (((X)->exponent < (Y)->exponent) || \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LT_80(X, Y))))
+#define VALUE_LE_80(X,Y) (((X)->exponent < (Y)->exponent) || \
+ (((X)->exponent == (Y)->exponent) && (SIGNIFICAND_LE_80(X, Y))))
+
+/* add/subtract 1 ulp macros */
+
+#if defined(SIZE_INT_32)
+# define ADD_ULP_80(X) \
+ if ((++(X)->lo_significand == 0) && \
+ (++(X)->hi_significand == (((X)->exponent == 0) ? 0x80000000 : 0))) \
+ { \
+ (X)->hi_significand |= 0x80000000; \
+ ++(X)->exponent; \
+ }
+# define SUB_ULP_80(X) \
+ if (--(X)->lo_significand == 0xFFFFFFFF) { \
+ --(X)->hi_significand; \
+ if (((X)->exponent != 0) && \
+ ((X)->hi_significand == 0x7FFFFFFF) && \
+ (--(X)->exponent != 0)) \
+ { \
+ (X)->hi_significand |= 0x80000000; \
+ } \
+ }
+#elif defined(SIZE_INT_64)
+# define ADD_ULP_80(X) \
+ if (++(X)->significand == (((X)->exponent == 0) ? 0x8000000000000000 : 0))) { \
+ (X)->significand |= 0x8000000000000000; \
+ ++(X)->exponent; \
+ }
+# define SUB_ULP_80(X) \
+ { \
+ --(X)->significand; \
+ if (((X)->exponent != 0) && \
+ ((X)->significand == 0x7FFFFFFFFFFFFFFF) && \
+ (--(X)->exponent != 0)) \
+ { \
+ (X)->significand |= 0x8000000000000000; \
+ } \
+ }
+#endif
+
+
+/* error codes */
+
+#define DOMAIN 1 /* argument domain error */
+#define SING 2 /* argument singularity */
+#define OVERFLOW 3 /* overflow range error */
+#define UNDERFLOW 4 /* underflow range error */
+#define TLOSS 5 /* total loss of precision */
+#define PLOSS 6 /* partial loss of precision */
+
+/* */
+
+#define VOLATILE_32 /*volatile*/
+#define VOLATILE_64 /*volatile*/
+#define VOLATILE_80 /*volatile*/
+
+#define QUAD_TYPE _Quad
+
+#endif /*__LIBM_SUPPORT_H_INCLUDED__*/
diff --git a/libc/sysdeps/ia64/fpu/libm_tan.S b/libc/sysdeps/ia64/fpu/libm_tan.S
new file mode 100644
index 000000000..179ea9c32
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/libm_tan.S
@@ -0,0 +1,3332 @@
+.file "libm_tan.s"
+
+// Copyright (C) 2000, 2001, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2/2/2000 by John Harrison, Ted Kubaska, Bob Norin, Shane Story,
+// and Ping Tak Peter Tang of the Computational Software Lab, Intel Corporation.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://developer.intel.com/opensource.
+//
+// *********************************************************************
+//
+// History:
+// 02/02/00 Initial Version
+// 4/04/00 Unwind support added
+// 12/28/00 Fixed false invalid flags
+//
+// *********************************************************************
+//
+// Function: tan(x) = tangent(x), for double precision x values
+//
+// *********************************************************************
+//
+// Accuracy: Very accurate for double-precision values
+//
+// *********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f9-f15
+// f32-f112
+//
+// General Purpose Registers:
+// r32-r48
+// r49-r50 (Used to pass arguments to pi_by_2 reduce routine)
+//
+// Predicate Registers: p6-p15
+//
+// *********************************************************************
+//
+// IEEE Special Conditions:
+//
+// Denormal fault raised on denormal inputs
+// Overflow exceptions do not occur
+// Underflow exceptions raised when appropriate for tan
+// (No specialized error handling for this routine)
+// Inexact raised when appropriate by algorithm
+//
+// tan(SNaN) = QNaN
+// tan(QNaN) = QNaN
+// tan(inf) = QNaN
+// tan(+/-0) = +/-0
+//
+// *********************************************************************
+//
+// Mathematical Description
+//
+// We consider the computation of FPTAN of Arg. Now, given
+//
+// Arg = N pi/2 + alpha, |alpha| <= pi/4,
+//
+// basic mathematical relationship shows that
+//
+// tan( Arg ) = tan( alpha ) if N is even;
+// = -cot( alpha ) otherwise.
+//
+// The value of alpha is obtained by argument reduction and
+// represented by two working precision numbers r and c where
+//
+// alpha = r + c accurately.
+//
+// The reduction method is described in a previous write up.
+// The argument reduction scheme identifies 4 cases. For Cases 2
+// and 4, because |alpha| is small, tan(r+c) and -cot(r+c) can be
+// computed very easily by 2 or 3 terms of the Taylor series
+// expansion as follows:
+//
+// Case 2:
+// -------
+//
+// tan(r + c) = r + c + r^3/3 ...accurately
+// -cot(r + c) = -1/(r+c) + r/3 ...accurately
+//
+// Case 4:
+// -------
+//
+// tan(r + c) = r + c + r^3/3 + 2r^5/15 ...accurately
+// -cot(r + c) = -1/(r+c) + r/3 + r^3/45 ...accurately
+//
+//
+// The only cases left are Cases 1 and 3 of the argument reduction
+// procedure. These two cases will be merged since after the
+// argument is reduced in either cases, we have the reduced argument
+// represented as r + c and that the magnitude |r + c| is not small
+// enough to allow the usage of a very short approximation.
+//
+// The greatest challenge of this task is that the second terms of
+// the Taylor series for tan(r) and -cot(r)
+//
+// r + r^3/3 + 2 r^5/15 + ...
+//
+// and
+//
+// -1/r + r/3 + r^3/45 + ...
+//
+// are not very small when |r| is close to pi/4 and the rounding
+// errors will be a concern if simple polynomial accumulation is
+// used. When |r| < 2^(-2), however, the second terms will be small
+// enough (5 bits or so of right shift) that a normal Horner
+// recurrence suffices. Hence there are two cases that we consider
+// in the accurate computation of tan(r) and cot(r), |r| <= pi/4.
+//
+// Case small_r: |r| < 2^(-2)
+// --------------------------
+//
+// Since Arg = N pi/4 + r + c accurately, we have
+//
+// tan(Arg) = tan(r+c) for N even,
+// = -cot(r+c) otherwise.
+//
+// Here for this case, both tan(r) and -cot(r) can be approximated
+// by simple polynomials:
+//
+// tan(r) = r + P1_1 r^3 + P1_2 r^5 + ... + P1_9 r^19
+// -cot(r) = -1/r + Q1_1 r + Q1_2 r^3 + ... + Q1_7 r^13
+//
+// accurately. Since |r| is relatively small, tan(r+c) and
+// -cot(r+c) can be accurately approximated by replacing r with
+// r+c only in the first two terms of the corresponding polynomials.
+//
+// Note that P1_1 (and Q1_1 for that matter) approximates 1/3 to
+// almost 64 sig. bits, thus
+//
+// P1_1 (r+c)^3 = P1_1 r^3 + c * r^2 accurately.
+//
+// Hence,
+//
+// tan(r+c) = r + P1_1 r^3 + P1_2 r^5 + ... + P1_9 r^19
+// + c*(1 + r^2)
+//
+// -cot(r+c) = -1/(r+c) + Q1_1 r + Q1_2 r^3 + ... + Q1_7 r^13
+// + Q1_1*c
+//
+//
+// Case normal_r: 2^(-2) <= |r| <= pi/4
+// ------------------------------------
+//
+// This case is more likely than the previous one if one considers
+// r to be uniformly distributed in [-pi/4 pi/4].
+//
+// The required calculation is either
+//
+// tan(r + c) = tan(r) + correction, or
+// -cot(r + c) = -cot(r) + correction.
+//
+// Specifically,
+//
+// tan(r + c) = tan(r) + c tan'(r) + O(c^2)
+// = tan(r) + c sec^2(r) + O(c^2)
+// = tan(r) + c SEC_sq ...accurately
+// as long as SEC_sq approximates sec^2(r)
+// to, say, 5 bits or so.
+//
+// Similarly,
+//
+// -cot(r + c) = -cot(r) - c cot'(r) + O(c^2)
+// = -cot(r) + c csc^2(r) + O(c^2)
+// = -cot(r) + c CSC_sq ...accurately
+// as long as CSC_sq approximates csc^2(r)
+// to, say, 5 bits or so.
+//
+// We therefore concentrate on accurately calculating tan(r) and
+// cot(r) for a working-precision number r, |r| <= pi/4 to within
+// 0.1% or so.
+//
+// We will employ a table-driven approach. Let
+//
+// r = sgn_r * 2^k * 1.b_1 b_2 ... b_5 ... b_63
+// = sgn_r * ( B + x )
+//
+// where
+//
+// B = 2^k * 1.b_1 b_2 ... b_5 1
+// x = |r| - B
+//
+// Now,
+// tan(B) + tan(x)
+// tan( B + x ) = ------------------------
+// 1 - tan(B)*tan(x)
+//
+// / \
+// | tan(B) + tan(x) |
+
+// = tan(B) + | ------------------------ - tan(B) |
+// | 1 - tan(B)*tan(x) |
+// \ /
+//
+// sec^2(B) * tan(x)
+// = tan(B) + ------------------------
+// 1 - tan(B)*tan(x)
+//
+// (1/[sin(B)*cos(B)]) * tan(x)
+// = tan(B) + --------------------------------
+// cot(B) - tan(x)
+//
+//
+// Clearly, the values of tan(B), cot(B) and 1/(sin(B)*cos(B)) are
+// calculated beforehand and stored in a table. Since
+//
+// |x| <= 2^k * 2^(-6) <= 2^(-7) (because k = -1, -2)
+//
+// a very short polynomial will be sufficient to approximate tan(x)
+// accurately. The details involved in computing the last expression
+// will be given in the next section on algorithm description.
+//
+//
+// Now, we turn to the case where cot( B + x ) is needed.
+//
+//
+// 1 - tan(B)*tan(x)
+// cot( B + x ) = ------------------------
+// tan(B) + tan(x)
+//
+// / \
+// | 1 - tan(B)*tan(x) |
+
+// = cot(B) + | ----------------------- - cot(B) |
+// | tan(B) + tan(x) |
+// \ /
+//
+// [tan(B) + cot(B)] * tan(x)
+// = cot(B) - ----------------------------
+// tan(B) + tan(x)
+//
+// (1/[sin(B)*cos(B)]) * tan(x)
+// = cot(B) - --------------------------------
+// tan(B) + tan(x)
+//
+//
+// Note that the values of tan(B), cot(B) and 1/(sin(B)*cos(B)) that
+// are needed are the same set of values needed in the previous
+// case.
+//
+// Finally, we can put all the ingredients together as follows:
+//
+// Arg = N * pi/2 + r + c ...accurately
+//
+// tan(Arg) = tan(r) + correction if N is even;
+// = -cot(r) + correction otherwise.
+//
+// For Cases 2 and 4,
+//
+// Case 2:
+// tan(Arg) = tan(r + c) = r + c + r^3/3 N even
+// = -cot(r + c) = -1/(r+c) + r/3 N odd
+// Case 4:
+// tan(Arg) = tan(r + c) = r + c + r^3/3 + 2r^5/15 N even
+// = -cot(r + c) = -1/(r+c) + r/3 + r^3/45 N odd
+//
+//
+// For Cases 1 and 3,
+//
+// Case small_r: |r| < 2^(-2)
+//
+// tan(Arg) = r + P1_1 r^3 + P1_2 r^5 + ... + P1_9 r^19
+// + c*(1 + r^2) N even
+//
+// = -1/(r+c) + Q1_1 r + Q1_2 r^3 + ... + Q1_7 r^13
+// + Q1_1*c N odd
+//
+// Case normal_r: 2^(-2) <= |r| <= pi/4
+//
+// tan(Arg) = tan(r) + c * sec^2(r) N even
+// = -cot(r) + c * csc^2(r) otherwise
+//
+// For N even,
+//
+// tan(Arg) = tan(r) + c*sec^2(r)
+// = tan( sgn_r * (B+x) ) + c * sec^2(|r|)
+// = sgn_r * ( tan(B+x) + sgn_r*c*sec^2(|r|) )
+// = sgn_r * ( tan(B+x) + sgn_r*c*sec^2(B) )
+//
+// since B approximates |r| to 2^(-6) in relative accuracy.
+//
+// / (1/[sin(B)*cos(B)]) * tan(x)
+// tan(Arg) = sgn_r * | tan(B) + --------------------------------
+// \ cot(B) - tan(x)
+// \
+// + CORR |
+
+// /
+// where
+//
+// CORR = sgn_r*c*tan(B)*SC_inv(B); SC_inv(B) = 1/(sin(B)*cos(B)).
+//
+// For N odd,
+//
+// tan(Arg) = -cot(r) + c*csc^2(r)
+// = -cot( sgn_r * (B+x) ) + c * csc^2(|r|)
+// = sgn_r * ( -cot(B+x) + sgn_r*c*csc^2(|r|) )
+// = sgn_r * ( -cot(B+x) + sgn_r*c*csc^2(B) )
+//
+// since B approximates |r| to 2^(-6) in relative accuracy.
+//
+// / (1/[sin(B)*cos(B)]) * tan(x)
+// tan(Arg) = sgn_r * | -cot(B) + --------------------------------
+// \ tan(B) + tan(x)
+// \
+// + CORR |
+
+// /
+// where
+//
+// CORR = sgn_r*c*cot(B)*SC_inv(B); SC_inv(B) = 1/(sin(B)*cos(B)).
+//
+//
+// The actual algorithm prescribes how all the mathematical formulas
+// are calculated.
+//
+//
+// 2. Algorithmic Description
+// ==========================
+//
+// 2.1 Computation for Cases 2 and 4.
+// ----------------------------------
+//
+// For Case 2, we use two-term polynomials.
+//
+// For N even,
+//
+// rsq := r * r
+// Result := c + r * rsq * P1_1
+// Result := r + Result ...in user-defined rounding
+//
+// For N odd,
+// S_hi := -frcpa(r) ...8 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...16 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...32 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...64 bits
+// S_lo := S_hi*( (1 + S_hi*r) + S_hi*c )
+// ...S_hi + S_lo is -1/(r+c) to extra precision
+// S_lo := S_lo + Q1_1*r
+//
+// Result := S_hi + S_lo ...in user-defined rounding
+//
+// For Case 4, we use three-term polynomials
+//
+// For N even,
+//
+// rsq := r * r
+// Result := c + r * rsq * (P1_1 + rsq * P1_2)
+// Result := r + Result ...in user-defined rounding
+//
+// For N odd,
+// S_hi := -frcpa(r) ...8 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...16 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...32 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...64 bits
+// S_lo := S_hi*( (1 + S_hi*r) + S_hi*c )
+// ...S_hi + S_lo is -1/(r+c) to extra precision
+// rsq := r * r
+// P := Q1_1 + rsq*Q1_2
+// S_lo := S_lo + r*P
+//
+// Result := S_hi + S_lo ...in user-defined rounding
+//
+//
+// Note that the coefficients P1_1, P1_2, Q1_1, and Q1_2 are
+// the same as those used in the small_r case of Cases 1 and 3
+// below.
+//
+//
+// 2.2 Computation for Cases 1 and 3.
+// ----------------------------------
+// This is further divided into the case of small_r,
+// where |r| < 2^(-2), and the case of normal_r, where |r| lies between
+// 2^(-2) and pi/4.
+//
+// Algorithm for the case of small_r
+// ---------------------------------
+//
+// For N even,
+// rsq := r * r
+// Poly1 := rsq*(P1_1 + rsq*(P1_2 + rsq*P1_3))
+// r_to_the_8 := rsq * rsq
+// r_to_the_8 := r_to_the_8 * r_to_the_8
+// Poly2 := P1_4 + rsq*(P1_5 + rsq*(P1_6 + ... rsq*P1_9))
+// CORR := c * ( 1 + rsq )
+// Poly := Poly1 + r_to_the_8*Poly2
+// Result := r*Poly + CORR
+// Result := r + Result ...in user-defined rounding
+// ...note that Poly1 and r_to_the_8 can be computed in parallel
+// ...with Poly2 (Poly1 is intentionally set to be much
+// ...shorter than Poly2 so that r_to_the_8 and CORR can be hidden)
+//
+// For N odd,
+// S_hi := -frcpa(r) ...8 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...16 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...32 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...64 bits
+// S_lo := S_hi*( (1 + S_hi*r) + S_hi*c )
+// ...S_hi + S_lo is -1/(r+c) to extra precision
+// S_lo := S_lo + Q1_1*c
+//
+// ...S_hi and S_lo are computed in parallel with
+// ...the following
+// rsq := r*r
+// P := Q1_1 + rsq*(Q1_2 + rsq*(Q1_3 + ... + rsq*Q1_7))
+//
+// Result := r*P + S_lo
+// Result := S_hi + Result ...in user-defined rounding
+//
+//
+// Algorithm for the case of normal_r
+// ----------------------------------
+//
+// Here, we first consider the computation of tan( r + c ). As
+// presented in the previous section,
+//
+// tan( r + c ) = tan(r) + c * sec^2(r)
+// = sgn_r * [ tan(B+x) + CORR ]
+// CORR = sgn_r * c * tan(B) * 1/[sin(B)*cos(B)]
+//
+// because sec^2(r) = sec^(|r|), and B approximate |r| to 6.5 bits.
+//
+// tan( r + c ) =
+// / (1/[sin(B)*cos(B)]) * tan(x)
+// sgn_r * | tan(B) + -------------------------------- +
+// \ cot(B) - tan(x)
+// \
+// CORR |
+
+// /
+//
+// The values of tan(B), cot(B) and 1/(sin(B)*cos(B)) are
+// calculated beforehand and stored in a table. Specifically,
+// the table values are
+//
+// tan(B) as T_hi + T_lo;
+// cot(B) as C_hi + C_lo;
+// 1/[sin(B)*cos(B)] as SC_inv
+//
+// T_hi, C_hi are in double-precision memory format;
+// T_lo, C_lo are in single-precision memory format;
+// SC_inv is in extended-precision memory format.
+//
+// The value of tan(x) will be approximated by a short polynomial of
+// the form
+//
+// tan(x) as x + x * P, where
+// P = x^2 * (P2_1 + x^2 * (P2_2 + x^2 * P2_3))
+//
+// Because |x| <= 2^(-7), cot(B) - x approximates cot(B) - tan(x)
+// to a relative accuracy better than 2^(-20). Thus, a good
+// initial guess of 1/( cot(B) - tan(x) ) to initiate the iterative
+// division is:
+//
+// 1/(cot(B) - tan(x)) is approximately
+// 1/(cot(B) - x) is
+// tan(B)/(1 - x*tan(B)) is approximately
+// T_hi / ( 1 - T_hi * x ) is approximately
+//
+// T_hi * [ 1 + (Thi * x) + (T_hi * x)^2 ]
+//
+// The calculation of tan(r+c) therefore proceed as follows:
+//
+// Tx := T_hi * x
+// xsq := x * x
+//
+// V_hi := T_hi*(1 + Tx*(1 + Tx))
+// P := xsq * (P1_1 + xsq*(P1_2 + xsq*P1_3))
+// ...V_hi serves as an initial guess of 1/(cot(B) - tan(x))
+// ...good to about 20 bits of accuracy
+//
+// tanx := x + x*P
+// D := C_hi - tanx
+// ...D is a double precision denominator: cot(B) - tan(x)
+//
+// V_hi := V_hi + V_hi*(1 - V_hi*D)
+// ....V_hi approximates 1/(cot(B)-tan(x)) to 40 bits
+//
+// V_lo := V_hi * ( [ (1 - V_hi*C_hi) + V_hi*tanx ]
+// - V_hi*C_lo ) ...observe all order
+// ...V_hi + V_lo approximates 1/(cot(B) - tan(x))
+// ...to extra accuracy
+//
+// ... SC_inv(B) * (x + x*P)
+// ... tan(B) + ------------------------- + CORR
+// ... cot(B) - (x + x*P)
+// ...
+// ... = tan(B) + SC_inv(B)*(x + x*P)*(V_hi + V_lo) + CORR
+// ...
+//
+// Sx := SC_inv * x
+// CORR := sgn_r * c * SC_inv * T_hi
+//
+// ...put the ingredients together to compute
+// ... SC_inv(B) * (x + x*P)
+// ... tan(B) + ------------------------- + CORR
+// ... cot(B) - (x + x*P)
+// ...
+// ... = tan(B) + SC_inv(B)*(x + x*P)*(V_hi + V_lo) + CORR
+// ...
+// ... = T_hi + T_lo + CORR +
+// ... Sx * V_hi + Sx * V_lo + Sx * P *(V_hi + V_lo)
+//
+// CORR := CORR + T_lo
+// tail := V_lo + P*(V_hi + V_lo)
+// tail := Sx * tail + CORR
+// tail := Sx * V_hi + tail
+// T_hi := sgn_r * T_hi
+//
+// ...T_hi + sgn_r*tail now approximate
+// ...sgn_r*(tan(B+x) + CORR) accurately
+//
+// Result := T_hi + sgn_r*tail ...in user-defined
+// ...rounding control
+// ...It is crucial that independent paths be fully
+// ...exploited for performance's sake.
+//
+//
+// Next, we consider the computation of -cot( r + c ). As
+// presented in the previous section,
+//
+// -cot( r + c ) = -cot(r) + c * csc^2(r)
+// = sgn_r * [ -cot(B+x) + CORR ]
+// CORR = sgn_r * c * cot(B) * 1/[sin(B)*cos(B)]
+//
+// because csc^2(r) = csc^(|r|), and B approximate |r| to 6.5 bits.
+//
+// -cot( r + c ) =
+// / (1/[sin(B)*cos(B)]) * tan(x)
+// sgn_r * | -cot(B) + -------------------------------- +
+// \ tan(B) + tan(x)
+// \
+// CORR |
+
+// /
+//
+// The values of tan(B), cot(B) and 1/(sin(B)*cos(B)) are
+// calculated beforehand and stored in a table. Specifically,
+// the table values are
+//
+// tan(B) as T_hi + T_lo;
+// cot(B) as C_hi + C_lo;
+// 1/[sin(B)*cos(B)] as SC_inv
+//
+// T_hi, C_hi are in double-precision memory format;
+// T_lo, C_lo are in single-precision memory format;
+// SC_inv is in extended-precision memory format.
+//
+// The value of tan(x) will be approximated by a short polynomial of
+// the form
+//
+// tan(x) as x + x * P, where
+// P = x^2 * (P2_1 + x^2 * (P2_2 + x^2 * P2_3))
+//
+// Because |x| <= 2^(-7), tan(B) + x approximates tan(B) + tan(x)
+// to a relative accuracy better than 2^(-18). Thus, a good
+// initial guess of 1/( tan(B) + tan(x) ) to initiate the iterative
+// division is:
+//
+// 1/(tan(B) + tan(x)) is approximately
+// 1/(tan(B) + x) is
+// cot(B)/(1 + x*cot(B)) is approximately
+// C_hi / ( 1 + C_hi * x ) is approximately
+//
+// C_hi * [ 1 - (C_hi * x) + (C_hi * x)^2 ]
+//
+// The calculation of -cot(r+c) therefore proceed as follows:
+//
+// Cx := C_hi * x
+// xsq := x * x
+//
+// V_hi := C_hi*(1 - Cx*(1 - Cx))
+// P := xsq * (P1_1 + xsq*(P1_2 + xsq*P1_3))
+// ...V_hi serves as an initial guess of 1/(tan(B) + tan(x))
+// ...good to about 18 bits of accuracy
+//
+// tanx := x + x*P
+// D := T_hi + tanx
+// ...D is a double precision denominator: tan(B) + tan(x)
+//
+// V_hi := V_hi + V_hi*(1 - V_hi*D)
+// ....V_hi approximates 1/(tan(B)+tan(x)) to 40 bits
+//
+// V_lo := V_hi * ( [ (1 - V_hi*T_hi) - V_hi*tanx ]
+// - V_hi*T_lo ) ...observe all order
+// ...V_hi + V_lo approximates 1/(tan(B) + tan(x))
+// ...to extra accuracy
+//
+// ... SC_inv(B) * (x + x*P)
+// ... -cot(B) + ------------------------- + CORR
+// ... tan(B) + (x + x*P)
+// ...
+// ... =-cot(B) + SC_inv(B)*(x + x*P)*(V_hi + V_lo) + CORR
+// ...
+//
+// Sx := SC_inv * x
+// CORR := sgn_r * c * SC_inv * C_hi
+//
+// ...put the ingredients together to compute
+// ... SC_inv(B) * (x + x*P)
+// ... -cot(B) + ------------------------- + CORR
+// ... tan(B) + (x + x*P)
+// ...
+// ... =-cot(B) + SC_inv(B)*(x + x*P)*(V_hi + V_lo) + CORR
+// ...
+// ... =-C_hi - C_lo + CORR +
+// ... Sx * V_hi + Sx * V_lo + Sx * P *(V_hi + V_lo)
+//
+// CORR := CORR - C_lo
+// tail := V_lo + P*(V_hi + V_lo)
+// tail := Sx * tail + CORR
+// tail := Sx * V_hi + tail
+// C_hi := -sgn_r * C_hi
+//
+// ...C_hi + sgn_r*tail now approximates
+// ...sgn_r*(-cot(B+x) + CORR) accurately
+//
+// Result := C_hi + sgn_r*tail in user-defined rounding control
+// ...It is crucial that independent paths be fully
+// ...exploited for performance's sake.
+//
+// 3. Implementation Notes
+// =======================
+//
+// Table entries T_hi, T_lo; C_hi, C_lo; SC_inv
+//
+// Recall that 2^(-2) <= |r| <= pi/4;
+//
+// r = sgn_r * 2^k * 1.b_1 b_2 ... b_63
+//
+// and
+//
+// B = 2^k * 1.b_1 b_2 b_3 b_4 b_5 1
+//
+// Thus, for k = -2, possible values of B are
+//
+// B = 2^(-2) * ( 1 + index/32 + 1/64 ),
+// index ranges from 0 to 31
+//
+// For k = -1, however, since |r| <= pi/4 = 0.78...
+// possible values of B are
+//
+// B = 2^(-1) * ( 1 + index/32 + 1/64 )
+// index ranges from 0 to 19.
+//
+//
+
+#include "libm_support.h"
+
+#ifdef _LIBC
+.rodata
+#else
+.data
+#endif
+
+.align 128
+
+TAN_BASE_CONSTANTS:
+ASM_TYPE_DIRECTIVE(TAN_BASE_CONSTANTS,@object)
+data4 0x4B800000, 0xCB800000, 0x38800000, 0xB8800000 // two**24, -two**24
+ // two**-14, -two**-14
+data4 0x4E44152A, 0xA2F9836E, 0x00003FFE, 0x00000000 // two_by_pi
+data4 0xCE81B9F1, 0xC84D32B0, 0x00004016, 0x00000000 // P_0
+data4 0x2168C235, 0xC90FDAA2, 0x00003FFF, 0x00000000 // P_1
+data4 0xFC8F8CBB, 0xECE675D1, 0x0000BFBD, 0x00000000 // P_2
+data4 0xACC19C60, 0xB7ED8FBB, 0x0000BF7C, 0x00000000 // P_3
+data4 0x5F000000, 0xDF000000, 0x00000000, 0x00000000 // two_to_63, -two_to_63
+data4 0x6EC6B45A, 0xA397E504, 0x00003FE7, 0x00000000 // Inv_P_0
+data4 0xDBD171A1, 0x8D848E89, 0x0000BFBF, 0x00000000 // d_1
+data4 0x18A66F8E, 0xD5394C36, 0x0000BF7C, 0x00000000 // d_2
+data4 0x2168C234, 0xC90FDAA2, 0x00003FFE, 0x00000000 // PI_BY_4
+data4 0x2168C234, 0xC90FDAA2, 0x0000BFFE, 0x00000000 // MPI_BY_4
+data4 0x3E800000, 0xBE800000, 0x00000000, 0x00000000 // two**-2, -two**-2
+data4 0x2F000000, 0xAF000000, 0x00000000, 0x00000000 // two**-33, -two**-33
+data4 0xAAAAAABD, 0xAAAAAAAA, 0x00003FFD, 0x00000000 // P1_1
+data4 0x88882E6A, 0x88888888, 0x00003FFC, 0x00000000 // P1_2
+data4 0x0F0177B6, 0xDD0DD0DD, 0x00003FFA, 0x00000000 // P1_3
+data4 0x646B8C6D, 0xB327A440, 0x00003FF9, 0x00000000 // P1_4
+data4 0x1D5F7D20, 0x91371B25, 0x00003FF8, 0x00000000 // P1_5
+data4 0x61C67914, 0xEB69A5F1, 0x00003FF6, 0x00000000 // P1_6
+data4 0x019318D2, 0xBEDD37BE, 0x00003FF5, 0x00000000 // P1_7
+data4 0x3C794015, 0x9979B146, 0x00003FF4, 0x00000000 // P1_8
+data4 0x8C6EB58A, 0x8EBD21A3, 0x00003FF3, 0x00000000 // P1_9
+data4 0xAAAAAAB4, 0xAAAAAAAA, 0x00003FFD, 0x00000000 // Q1_1
+data4 0x0B5FC93E, 0xB60B60B6, 0x00003FF9, 0x00000000 // Q1_2
+data4 0x0C9BBFBF, 0x8AB355E0, 0x00003FF6, 0x00000000 // Q1_3
+data4 0xCBEE3D4C, 0xDDEBBC89, 0x00003FF2, 0x00000000 // Q1_4
+data4 0x5F80BBB6, 0xB3548A68, 0x00003FEF, 0x00000000 // Q1_5
+data4 0x4CED5BF1, 0x91362560, 0x00003FEC, 0x00000000 // Q1_6
+data4 0x8EE92A83, 0xF189D95A, 0x00003FE8, 0x00000000 // Q1_7
+data4 0xAAAB362F, 0xAAAAAAAA, 0x00003FFD, 0x00000000 // P2_1
+data4 0xE97A6097, 0x88888886, 0x00003FFC, 0x00000000 // P2_2
+data4 0x25E716A1, 0xDD108EE0, 0x00003FFA, 0x00000000 // P2_3
+//
+// Entries T_hi double-precision memory format
+// Index = 0,1,...,31 B = 2^(-2)*(1+Index/32+1/64)
+// Entries T_lo single-precision memory format
+// Index = 0,1,...,31 B = 2^(-2)*(1+Index/32+1/64)
+//
+data4 0x62400794, 0x3FD09BC3, 0x23A05C32, 0x00000000
+data4 0xDFFBC074, 0x3FD124A9, 0x240078B2, 0x00000000
+data4 0x5BD4920F, 0x3FD1AE23, 0x23826B8E, 0x00000000
+data4 0x15E2701D, 0x3FD23835, 0x22D31154, 0x00000000
+data4 0x63739C2D, 0x3FD2C2E4, 0x2265C9E2, 0x00000000
+data4 0xAFEEA48B, 0x3FD34E36, 0x245C05EB, 0x00000000
+data4 0x7DBB35D1, 0x3FD3DA31, 0x24749F2D, 0x00000000
+data4 0x67321619, 0x3FD466DA, 0x2462CECE, 0x00000000
+data4 0x1F94A4D5, 0x3FD4F437, 0x246D0DF1, 0x00000000
+data4 0x740C3E6D, 0x3FD5824D, 0x240A85B5, 0x00000000
+data4 0x4CB1E73D, 0x3FD61123, 0x23F96E33, 0x00000000
+data4 0xAD9EA64B, 0x3FD6A0BE, 0x247C5393, 0x00000000
+data4 0xB804FD01, 0x3FD73125, 0x241F3B29, 0x00000000
+data4 0xAB53EE83, 0x3FD7C25E, 0x2479989B, 0x00000000
+data4 0xE6640EED, 0x3FD8546F, 0x23B343BC, 0x00000000
+data4 0xE8AF1892, 0x3FD8E75F, 0x241454D1, 0x00000000
+data4 0x53928BDA, 0x3FD97B35, 0x238613D9, 0x00000000
+data4 0xEB9DE4DE, 0x3FDA0FF6, 0x22859FA7, 0x00000000
+data4 0x99ECF92D, 0x3FDAA5AB, 0x237A6D06, 0x00000000
+data4 0x6D8F1796, 0x3FDB3C5A, 0x23952F6C, 0x00000000
+data4 0x9CFB8BE4, 0x3FDBD40A, 0x2280FC95, 0x00000000
+data4 0x87943100, 0x3FDC6CC3, 0x245D2EC0, 0x00000000
+data4 0xB736C500, 0x3FDD068C, 0x23C4AD7D, 0x00000000
+data4 0xE1DDBC31, 0x3FDDA16D, 0x23D076E6, 0x00000000
+data4 0xEB515A93, 0x3FDE3D6E, 0x244809A6, 0x00000000
+data4 0xE6E9E5F1, 0x3FDEDA97, 0x220856C8, 0x00000000
+data4 0x1963CE69, 0x3FDF78F1, 0x244BE993, 0x00000000
+data4 0x7D635BCE, 0x3FE00C41, 0x23D21799, 0x00000000
+data4 0x1C302CD3, 0x3FE05CAB, 0x248A1B1D, 0x00000000
+data4 0xDB6A1FA0, 0x3FE0ADB9, 0x23D53E33, 0x00000000
+data4 0x4A20BA81, 0x3FE0FF72, 0x24DB9ED5, 0x00000000
+data4 0x153FA6F5, 0x3FE151D9, 0x24E9E451, 0x00000000
+//
+// Entries T_hi double-precision memory format
+// Index = 0,1,...,19 B = 2^(-1)*(1+Index/32+1/64)
+// Entries T_lo single-precision memory format
+// Index = 0,1,...,19 B = 2^(-1)*(1+Index/32+1/64)
+//
+data4 0xBA1BE39E, 0x3FE1CEC4, 0x24B60F9E, 0x00000000
+data4 0x5ABD9B2D, 0x3FE277E4, 0x248C2474, 0x00000000
+data4 0x0272B110, 0x3FE32418, 0x247B8311, 0x00000000
+data4 0x890E2DF0, 0x3FE3D38B, 0x24C55751, 0x00000000
+data4 0x46236871, 0x3FE4866D, 0x24E5BC34, 0x00000000
+data4 0x45E044B0, 0x3FE53CEE, 0x24001BA4, 0x00000000
+data4 0x82EC06E4, 0x3FE5F742, 0x24B973DC, 0x00000000
+data4 0x25DF43F9, 0x3FE6B5A1, 0x24895440, 0x00000000
+data4 0xCAFD348C, 0x3FE77844, 0x240021CA, 0x00000000
+data4 0xCEED6B92, 0x3FE83F6B, 0x24C45372, 0x00000000
+data4 0xA34F3665, 0x3FE90B58, 0x240DAD33, 0x00000000
+data4 0x2C1E56B4, 0x3FE9DC52, 0x24F846CE, 0x00000000
+data4 0x27041578, 0x3FEAB2A4, 0x2323FB6E, 0x00000000
+data4 0x9DD8C373, 0x3FEB8E9F, 0x24B3090B, 0x00000000
+data4 0x65C9AA7B, 0x3FEC709B, 0x2449F611, 0x00000000
+data4 0xACCF8435, 0x3FED58F4, 0x23616A7E, 0x00000000
+data4 0x97635082, 0x3FEE480F, 0x24C2FEAE, 0x00000000
+data4 0xF0ACC544, 0x3FEF3E57, 0x242CE964, 0x00000000
+data4 0xF7E06E4B, 0x3FF01E20, 0x2480D3EE, 0x00000000
+data4 0x8A798A69, 0x3FF0A125, 0x24DB8967, 0x00000000
+//
+// Entries C_hi double-precision memory format
+// Index = 0,1,...,31 B = 2^(-2)*(1+Index/32+1/64)
+// Entries C_lo single-precision memory format
+// Index = 0,1,...,31 B = 2^(-2)*(1+Index/32+1/64)
+//
+data4 0xE63EFBD0, 0x400ED3E2, 0x259D94D4, 0x00000000
+data4 0xC515DAB5, 0x400DDDB4, 0x245F0537, 0x00000000
+data4 0xBE19A79F, 0x400CF57A, 0x25D4EA9F, 0x00000000
+data4 0xD15298ED, 0x400C1A06, 0x24AE40A0, 0x00000000
+data4 0x164B2708, 0x400B4A4C, 0x25A5AAB6, 0x00000000
+data4 0x5285B068, 0x400A855A, 0x25524F18, 0x00000000
+data4 0x3FFA549F, 0x4009CA5A, 0x24C999C0, 0x00000000
+data4 0x646AF623, 0x4009188A, 0x254FD801, 0x00000000
+data4 0x6084D0E7, 0x40086F3C, 0x2560F5FD, 0x00000000
+data4 0xA29A76EE, 0x4007CDD2, 0x255B9D19, 0x00000000
+data4 0x6C8ECA95, 0x400733BE, 0x25CB021B, 0x00000000
+data4 0x1F8DDC52, 0x4006A07E, 0x24AB4722, 0x00000000
+data4 0xC298AD58, 0x4006139B, 0x252764E2, 0x00000000
+data4 0xBAD7164B, 0x40058CAB, 0x24DAF5DB, 0x00000000
+data4 0xAE31A5D3, 0x40050B4B, 0x25EA20F4, 0x00000000
+data4 0x89F85A8A, 0x40048F21, 0x2583A3E8, 0x00000000
+data4 0xA862380D, 0x400417DA, 0x25DCC4CC, 0x00000000
+data4 0x1088FCFE, 0x4003A52B, 0x2430A492, 0x00000000
+data4 0xCD3527D5, 0x400336CC, 0x255F77CF, 0x00000000
+data4 0x5760766D, 0x4002CC7F, 0x25DA0BDA, 0x00000000
+data4 0x11CE02E3, 0x40026607, 0x256FF4A2, 0x00000000
+data4 0xD37BBE04, 0x4002032C, 0x25208AED, 0x00000000
+data4 0x7F050775, 0x4001A3BD, 0x24B72DD6, 0x00000000
+data4 0xA554848A, 0x40014789, 0x24AB4DAA, 0x00000000
+data4 0x323E81B7, 0x4000EE65, 0x2584C440, 0x00000000
+data4 0x21CF1293, 0x40009827, 0x25C9428D, 0x00000000
+data4 0x3D415EEB, 0x400044A9, 0x25DC8482, 0x00000000
+data4 0xBD72C577, 0x3FFFE78F, 0x257F5070, 0x00000000
+data4 0x75EFD28E, 0x3FFF4AC3, 0x23EBBF7A, 0x00000000
+data4 0x60B52DDE, 0x3FFEB2AF, 0x22EECA07, 0x00000000
+data4 0x35204180, 0x3FFE1F19, 0x24191079, 0x00000000
+data4 0x54F7E60A, 0x3FFD8FCA, 0x248D3058, 0x00000000
+//
+// Entries C_hi double-precision memory format
+// Index = 0,1,...,19 B = 2^(-1)*(1+Index/32+1/64)
+// Entries C_lo single-precision memory format
+// Index = 0,1,...,19 B = 2^(-1)*(1+Index/32+1/64)
+//
+data4 0x79F6FADE, 0x3FFCC06A, 0x239C7886, 0x00000000
+data4 0x891662A6, 0x3FFBB91F, 0x250BD191, 0x00000000
+data4 0x529F155D, 0x3FFABFB6, 0x256CC3E6, 0x00000000
+data4 0x2E964AE9, 0x3FF9D300, 0x250843E3, 0x00000000
+data4 0x89DCB383, 0x3FF8F1EF, 0x2277C87E, 0x00000000
+data4 0x7C87DBD6, 0x3FF81B93, 0x256DA6CF, 0x00000000
+data4 0x1042EDE4, 0x3FF74F14, 0x2573D28A, 0x00000000
+data4 0x1784B360, 0x3FF68BAF, 0x242E489A, 0x00000000
+data4 0x7C923C4C, 0x3FF5D0B5, 0x2532D940, 0x00000000
+data4 0xF418EF20, 0x3FF51D88, 0x253C7DD6, 0x00000000
+data4 0x02F88DAE, 0x3FF4719A, 0x23DB59BF, 0x00000000
+data4 0x49DA0788, 0x3FF3CC66, 0x252B4756, 0x00000000
+data4 0x0B980DB8, 0x3FF32D77, 0x23FE585F, 0x00000000
+data4 0xE56C987A, 0x3FF2945F, 0x25378A63, 0x00000000
+data4 0xB16523F6, 0x3FF200BD, 0x247BB2E0, 0x00000000
+data4 0x8CE27778, 0x3FF17235, 0x24446538, 0x00000000
+data4 0xFDEFE692, 0x3FF0E873, 0x2514638F, 0x00000000
+data4 0x33154062, 0x3FF0632C, 0x24A7FC27, 0x00000000
+data4 0xB3EF115F, 0x3FEFC42E, 0x248FD0FE, 0x00000000
+data4 0x135D26F6, 0x3FEEC9E8, 0x2385C719, 0x00000000
+//
+// Entries SC_inv in Swapped IEEE format (extended)
+// Index = 0,1,...,31 B = 2^(-2)*(1+Index/32+1/64)
+//
+data4 0x1BF30C9E, 0x839D6D4A, 0x00004001, 0x00000000
+data4 0x554B0EB0, 0x80092804, 0x00004001, 0x00000000
+data4 0xA1CF0DE9, 0xF959F94C, 0x00004000, 0x00000000
+data4 0x77378677, 0xF3086BA0, 0x00004000, 0x00000000
+data4 0xCCD4723C, 0xED154515, 0x00004000, 0x00000000
+data4 0x1C27CF25, 0xE7790944, 0x00004000, 0x00000000
+data4 0x8DDACB88, 0xE22D037D, 0x00004000, 0x00000000
+data4 0x89C73522, 0xDD2B2D8A, 0x00004000, 0x00000000
+data4 0xBB2C1171, 0xD86E1A23, 0x00004000, 0x00000000
+data4 0xDFF5E0F9, 0xD3F0E288, 0x00004000, 0x00000000
+data4 0x283BEBD5, 0xCFAF16B1, 0x00004000, 0x00000000
+data4 0x0D88DD53, 0xCBA4AFAA, 0x00004000, 0x00000000
+data4 0xCA67C43D, 0xC7CE03CC, 0x00004000, 0x00000000
+data4 0x0CA0DDB0, 0xC427BC82, 0x00004000, 0x00000000
+data4 0xF13D8CAB, 0xC0AECD57, 0x00004000, 0x00000000
+data4 0x71ECE6B1, 0xBD606C38, 0x00004000, 0x00000000
+data4 0xA44C4929, 0xBA3A0A96, 0x00004000, 0x00000000
+data4 0xE5CCCEC1, 0xB7394F6F, 0x00004000, 0x00000000
+data4 0x9637D8BC, 0xB45C1203, 0x00004000, 0x00000000
+data4 0x92CB051B, 0xB1A05528, 0x00004000, 0x00000000
+data4 0x6BA2FFD0, 0xAF04432B, 0x00004000, 0x00000000
+data4 0x7221235F, 0xAC862A23, 0x00004000, 0x00000000
+data4 0x5F00A9D1, 0xAA2478AF, 0x00004000, 0x00000000
+data4 0x81E082BF, 0xA7DDBB0C, 0x00004000, 0x00000000
+data4 0x45684FEE, 0xA5B0987D, 0x00004000, 0x00000000
+data4 0x627A8F53, 0xA39BD0F5, 0x00004000, 0x00000000
+data4 0x6EC5C8B0, 0xA19E3B03, 0x00004000, 0x00000000
+data4 0x91CD7C66, 0x9FB6C1F0, 0x00004000, 0x00000000
+data4 0x1FA3DF8A, 0x9DE46410, 0x00004000, 0x00000000
+data4 0xA8F6B888, 0x9C263139, 0x00004000, 0x00000000
+data4 0xC27B0450, 0x9A7B4968, 0x00004000, 0x00000000
+data4 0x5EE614EE, 0x98E2DB7E, 0x00004000, 0x00000000
+//
+// Entries SC_inv in Swapped IEEE format (extended)
+// Index = 0,1,...,19 B = 2^(-1)*(1+Index/32+1/64)
+//
+data4 0x13B2B5BA, 0x969F335C, 0x00004000, 0x00000000
+data4 0xD4C0F548, 0x93D446D9, 0x00004000, 0x00000000
+data4 0x61B798AF, 0x9147094F, 0x00004000, 0x00000000
+data4 0x758787AC, 0x8EF317CC, 0x00004000, 0x00000000
+data4 0xB99EEFDB, 0x8CD498B3, 0x00004000, 0x00000000
+data4 0xDFF8BC37, 0x8AE82A7D, 0x00004000, 0x00000000
+data4 0xE3C55D42, 0x892AD546, 0x00004000, 0x00000000
+data4 0xD15573C1, 0x8799FEA9, 0x00004000, 0x00000000
+data4 0x435A4B4C, 0x86335F88, 0x00004000, 0x00000000
+data4 0x3E93A87B, 0x84F4FB6E, 0x00004000, 0x00000000
+data4 0x80A382FB, 0x83DD1952, 0x00004000, 0x00000000
+data4 0xA4CB8C9E, 0x82EA3D7F, 0x00004000, 0x00000000
+data4 0x6861D0A8, 0x821B247C, 0x00004000, 0x00000000
+data4 0x63E8D244, 0x816EBED1, 0x00004000, 0x00000000
+data4 0x27E4CFC6, 0x80E42D91, 0x00004000, 0x00000000
+data4 0x28E64AFD, 0x807ABF8D, 0x00004000, 0x00000000
+data4 0x863B4FD8, 0x8031EF26, 0x00004000, 0x00000000
+data4 0xAE8C11FD, 0x800960AD, 0x00004000, 0x00000000
+data4 0x5FDBEC21, 0x8000E147, 0x00004000, 0x00000000
+data4 0xA07791FA, 0x80186650, 0x00004000, 0x00000000
+
+Arg = f8
+Result = f8
+fp_tmp = f9
+U_2 = f10
+rsq = f11
+C_hi = f12
+C_lo = f13
+T_hi = f14
+T_lo = f15
+
+N_0 = f32
+d_1 = f33
+MPI_BY_4 = f34
+tail = f35
+tanx = f36
+Cx = f37
+Sx = f38
+sgn_r = f39
+CORR = f40
+P = f41
+D = f42
+ArgPrime = f43
+P_0 = f44
+
+P2_1 = f45
+P2_2 = f46
+P2_3 = f47
+
+P1_1 = f45
+P1_2 = f46
+P1_3 = f47
+
+P1_4 = f48
+P1_5 = f49
+P1_6 = f50
+P1_7 = f51
+P1_8 = f52
+P1_9 = f53
+
+TWO_TO_63 = f54
+NEGTWO_TO_63 = f55
+x = f56
+xsq = f57
+Tx = f58
+Tx1 = f59
+Set = f60
+poly1 = f61
+poly2 = f62
+Poly = f63
+Poly1 = f64
+Poly2 = f65
+r_to_the_8 = f66
+B = f67
+SC_inv = f68
+Pos_r = f69
+N_0_fix = f70
+PI_BY_4 = f71
+NEGTWO_TO_NEG2 = f72
+TWO_TO_24 = f73
+TWO_TO_NEG14 = f74
+TWO_TO_NEG33 = f75
+NEGTWO_TO_24 = f76
+NEGTWO_TO_NEG14 = f76
+NEGTWO_TO_NEG33 = f77
+two_by_PI = f78
+N = f79
+N_fix = f80
+P_1 = f81
+P_2 = f82
+P_3 = f83
+s_val = f84
+w = f85
+c = f86
+r = f87
+Z = f88
+A = f89
+a = f90
+t = f91
+U_1 = f92
+d_2 = f93
+TWO_TO_NEG2 = f94
+Q1_1 = f95
+Q1_2 = f96
+Q1_3 = f97
+Q1_4 = f98
+Q1_5 = f99
+Q1_6 = f100
+Q1_7 = f101
+Q1_8 = f102
+S_hi = f103
+S_lo = f104
+V_hi = f105
+V_lo = f106
+U_hi = f107
+U_lo = f108
+U_hiabs = f109
+V_hiabs = f110
+V = f111
+Inv_P_0 = f112
+
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_SAVE_PFS = r35
+
+delta1 = r36
+table_ptr1 = r37
+table_ptr2 = r38
+i_0 = r39
+i_1 = r40
+N_fix_gr = r41
+N_inc = r42
+exp_Arg = r43
+exp_r = r44
+sig_r = r45
+lookup = r46
+table_offset = r47
+Create_B = r48
+gr_tmp = r49
+
+GR_Parameter_X = r49
+GR_Parameter_r = r50
+
+
+
+.global __libm_tan
+.section .text
+.proc __libm_tan
+
+
+__libm_tan:
+
+{ .mfi
+alloc r32 = ar.pfs, 0,17,2,0
+(p0) fclass.m.unc p6,p0 = Arg, 0x1E7
+ addl gr_tmp = -1,r0
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p0) fclass.nm.unc p7,p0 = Arg, 0x1FF
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p0) addl table_ptr1 = @ltoff(TAN_BASE_CONSTANTS), gp
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ld8 table_ptr1 = [table_ptr1]
+ setf.sig fp_tmp = gr_tmp // Make a constant so fmpy produces inexact
+ nop.i 999
+}
+;;
+
+//
+// Check for NatVals, Infs , NaNs, and Zeros
+// Check for everything - if false, then must be pseudo-zero
+// or pseudo-nan.
+// Local table pointer
+//
+
+{ .mbb
+(p0) add table_ptr2 = 96, table_ptr1
+(p6) br.cond.spnt __libm_TAN_SPECIAL
+(p7) br.cond.spnt __libm_TAN_SPECIAL ;;
+}
+//
+// Point to Inv_P_0
+// Branch out to deal with unsupporteds and special values.
+//
+
+{ .mmf
+(p0) ldfs TWO_TO_24 = [table_ptr1],4
+(p0) ldfs TWO_TO_63 = [table_ptr2],4
+//
+// Load -2**24, load -2**63.
+//
+(p0) fcmp.eq.s0 p0, p6 = Arg, f1 ;;
+}
+
+{ .mfi
+(p0) ldfs NEGTWO_TO_63 = [table_ptr2],12
+(p0) fnorm.s1 Arg = Arg
+ nop.i 999
+}
+//
+// Load 2**24, Load 2**63.
+//
+
+{ .mmi
+(p0) ldfs NEGTWO_TO_24 = [table_ptr1],12 ;;
+//
+// Do fcmp to generate Denormal exception
+// - can't do FNORM (will generate Underflow when U is unmasked!)
+// Normalize input argument.
+//
+(p0) ldfe two_by_PI = [table_ptr1],16
+ nop.i 999
+}
+
+{ .mmi
+(p0) ldfe Inv_P_0 = [table_ptr2],16 ;;
+(p0) ldfe d_1 = [table_ptr2],16
+ nop.i 999
+}
+//
+// Decide about the paths to take:
+// PR_1 and PR_3 set if -2**24 < Arg < 2**24 - CASE 1 OR 2
+// OTHERWISE - CASE 3 OR 4
+// Load inverse of P_0 .
+// Set PR_6 if Arg <= -2**63
+// Are there any Infs, NaNs, or zeros?
+//
+
+{ .mmi
+(p0) ldfe P_0 = [table_ptr1],16 ;;
+(p0) ldfe d_2 = [table_ptr2],16
+ nop.i 999
+}
+//
+// Set PR_8 if Arg <= -2**24
+// Set PR_6 if Arg >= 2**63
+//
+
+{ .mmi
+(p0) ldfe P_1 = [table_ptr1],16 ;;
+(p0) ldfe PI_BY_4 = [table_ptr2],16
+ nop.i 999
+}
+//
+// Set PR_8 if Arg >= 2**24
+//
+
+{ .mmi
+(p0) ldfe P_2 = [table_ptr1],16 ;;
+(p0) ldfe MPI_BY_4 = [table_ptr2],16
+ nop.i 999
+}
+//
+// Load P_2 and PI_BY_4
+//
+
+{ .mfi
+(p0) ldfe P_3 = [table_ptr1],16
+ nop.f 999
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p0) fcmp.le.unc.s1 p6,p7 = Arg,NEGTWO_TO_63
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p0) fcmp.le.unc.s1 p8,p9 = Arg,NEGTWO_TO_24
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p7) fcmp.ge.s1 p6,p0 = Arg,TWO_TO_63
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p9) fcmp.ge.s1 p8,p0 = Arg,TWO_TO_24
+ nop.i 999 ;;
+}
+
+{ .mib
+ nop.m 999
+ nop.i 999
+//
+// Load P_3 and -PI_BY_4
+//
+(p6) br.cond.spnt TAN_ARG_TOO_LARGE ;;
+}
+
+{ .mib
+ nop.m 999
+ nop.i 999
+//
+// Load 2**(-2).
+// Load -2**(-2).
+// Branch out if we have a special argument.
+// Branch out if the magnitude of the input argument is too large
+// - do this branch before the next.
+//
+(p8) br.cond.spnt TAN_LARGER_ARG ;;
+}
+//
+// Branch to Cases 3 or 4 if Arg <= -2**24 or Arg >= 2**24
+//
+
+{ .mfi
+(p0) ldfs TWO_TO_NEG2 = [table_ptr2],4
+// ARGUMENT REDUCTION CODE - CASE 1 and 2
+// Load 2**(-2).
+// Load -2**(-2).
+(p0) fmpy.s1 N = Arg,two_by_PI
+ nop.i 999 ;;
+}
+
+{ .mfi
+(p0) ldfs NEGTWO_TO_NEG2 = [table_ptr2],12
+//
+// N = Arg * 2/pi
+//
+(p0) fcmp.lt.unc.s1 p8,p9= Arg,PI_BY_4
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// if Arg < pi/4, set PR_8.
+//
+(p8) fcmp.gt.s1 p8,p9= Arg,MPI_BY_4
+ nop.i 999 ;;
+}
+//
+// Case 1: Is |r| < 2**(-2).
+// Arg is the same as r in this case.
+// r = Arg
+// c = 0
+//
+
+{ .mfi
+(p8) mov N_fix_gr = r0
+//
+// if Arg > -pi/4, reset PR_8.
+// Select the case when |Arg| < pi/4 - set PR[8] = true.
+// Else Select the case when |Arg| >= pi/4 - set PR[9] = true.
+//
+(p0) fcvt.fx.s1 N_fix = N
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Grab the integer part of N .
+//
+(p8) mov r = Arg
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p8) mov c = f0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p8) fcmp.lt.unc.s1 p10, p11 = Arg, TWO_TO_NEG2
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) fcmp.gt.s1 p10,p0 = Arg, NEGTWO_TO_NEG2
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 2: Place integer part of N in GP register.
+//
+(p9) fcvt.xf N = N_fix
+ nop.i 999 ;;
+}
+
+{ .mib
+(p9) getf.sig N_fix_gr = N_fix
+ nop.i 999
+//
+// Case 2: Convert integer N_fix back to normalized floating-point value.
+//
+(p10) br.cond.spnt TAN_SMALL_R ;;
+}
+
+{ .mib
+ nop.m 999
+ nop.i 999
+(p8) br.cond.sptk TAN_NORMAL_R ;;
+}
+//
+// Case 1: PR_3 is only affected when PR_1 is set.
+//
+
+{ .mmi
+(p9) ldfs TWO_TO_NEG33 = [table_ptr2], 4 ;;
+//
+// Case 2: Load 2**(-33).
+//
+(p9) ldfs NEGTWO_TO_NEG33 = [table_ptr2], 4
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 2: Load -2**(-33).
+//
+(p9) fnma.s1 s_val = N, P_1, Arg
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p9) fmpy.s1 w = N, P_2
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 2: w = N * P_2
+// Case 2: s_val = -N * P_1 + Arg
+//
+(p0) fcmp.lt.unc.s1 p9,p8 = s_val, TWO_TO_NEG33
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Decide between case_1 and case_2 reduce:
+//
+(p9) fcmp.gt.s1 p9, p8 = s_val, NEGTWO_TO_NEG33
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 1_reduce: s <= -2**(-33) or s >= 2**(-33)
+// Case 2_reduce: -2**(-33) < s < 2**(-33)
+//
+(p8) fsub.s1 r = s_val, w
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p9) fmpy.s1 w = N, P_3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 U_1 = N, P_2, w
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 1_reduce: Is |r| < 2**(-2), if so set PR_10
+// else set PR_11.
+//
+(p8) fsub.s1 c = s_val, r
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 1_reduce: r = s + w (change sign)
+// Case 2_reduce: w = N * P_3 (change sign)
+//
+(p8) fcmp.lt.unc.s1 p10, p11 = r, TWO_TO_NEG2
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p10) fcmp.gt.s1 p10, p11 = r, NEGTWO_TO_NEG2
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fsub.s1 r = s_val, U_1
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 1_reduce: c is complete here.
+// c = c + w (w has not been negated.)
+// Case 2_reduce: r is complete here - continue to calculate c .
+// r = s - U_1
+//
+(p9) fms.s1 U_2 = N, P_2, U_1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 1_reduce: c = s - r
+// Case 2_reduce: U_1 = N * P_2 + w
+//
+(p8) fsub.s1 c = c, w
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fsub.s1 s_val = s_val, r
+ nop.i 999
+}
+
+{ .mfb
+ nop.m 999
+//
+// Case 2_reduce:
+// U_2 = N * P_2 - U_1
+// Not needed until later.
+//
+(p9) fadd.s1 U_2 = U_2, w
+//
+// Case 2_reduce:
+// s = s - r
+// U_2 = U_2 + w
+//
+(p10) br.cond.spnt TAN_SMALL_R ;;
+}
+
+{ .mib
+ nop.m 999
+ nop.i 999
+(p11) br.cond.sptk TAN_NORMAL_R ;;
+}
+
+{ .mii
+ nop.m 999
+//
+// Case 2_reduce:
+// c = c - U_2
+// c is complete here
+// Argument reduction ends here.
+//
+(p9) extr.u i_1 = N_fix_gr, 0, 1 ;;
+(p9) cmp.eq.unc p11, p12 = 0x0000,i_1 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Is i_1 even or odd?
+// if i_1 == 0, set p11, else set p12.
+//
+(p11) fmpy.s1 rsq = r, Z
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) frcpa.s1 S_hi,p0 = f1, r
+ nop.i 999
+}
+
+//
+// Case 1: Branch to SMALL_R or NORMAL_R.
+// Case 1 is done now.
+//
+
+{ .mfi
+(p9) addl table_ptr1 = @ltoff(TAN_BASE_CONSTANTS), gp
+(p9) fsub.s1 c = s_val, U_1
+ nop.i 999 ;;
+}
+;;
+
+{ .mmi
+(p9) ld8 table_ptr1 = [table_ptr1]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+{ .mmi
+(p9) add table_ptr1 = 224, table_ptr1 ;;
+(p9) ldfe P1_1 = [table_ptr1],144
+ nop.i 999 ;;
+}
+//
+// Get [i_1] - lsb of N_fix_gr .
+// Load P1_1 and point to Q1_1 .
+//
+
+{ .mfi
+(p9) ldfe Q1_1 = [table_ptr1] , 0
+//
+// N even: rsq = r * Z
+// N odd: S_hi = frcpa(r)
+//
+(p12) fmerge.ns S_hi = S_hi, S_hi
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 2_reduce:
+// c = s - U_1
+//
+(p9) fsub.s1 c = c, U_2
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: Change sign of S_hi
+//
+(p11) fmpy.s1 rsq = rsq, P1_1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: rsq = rsq * P1_1
+// N odd: poly1 = 1.0 + S_hi * r 16 bits partial account for necessary
+//
+(p11) fma.s1 Result = r, rsq, c
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: Result = c + r * rsq
+// N odd: S_hi = S_hi + S_hi*poly1 16 bits account for necessary
+//
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: Result = Result + r
+// N odd: poly1 = 1.0 + S_hi * r 32 bits partial
+//
+(p11) fadd.s0 Result = r, Result
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: Result1 = Result + r
+// N odd: S_hi = S_hi * poly1 + S_hi 32 bits
+//
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * r + 1.0 64 bits partial
+//
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * poly + 1.0 64 bits
+//
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * r + 1.0
+//
+(p12) fma.s1 poly1 = S_hi, c, poly1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * c + poly1
+//
+(p12) fmpy.s1 S_lo = S_hi, poly1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: S_lo = S_hi * poly1
+//
+(p12) fma.s1 S_lo = Q1_1, r, S_lo
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: Result = S_hi + S_lo
+//
+(p0) fmpy.s0 fp_tmp = fp_tmp, fp_tmp // Dummy mult to set inexact
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+//
+// N odd: S_lo = S_lo + Q1_1 * r
+//
+(p12) fadd.s0 Result = S_hi, S_lo
+(p0) br.ret.sptk b0 ;;
+}
+
+
+TAN_LARGER_ARG:
+
+{ .mmf
+(p0) addl table_ptr1 = @ltoff(TAN_BASE_CONSTANTS), gp
+ nop.m 999
+(p0) fmpy.s1 N_0 = Arg, Inv_P_0
+}
+;;
+
+//
+// ARGUMENT REDUCTION CODE - CASE 3 and 4
+//
+//
+// Adjust table_ptr1 to beginning of table.
+// N_0 = Arg * Inv_P_0
+//
+
+
+{ .mmi
+(p0) ld8 table_ptr1 = [table_ptr1]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+
+{ .mmi
+(p0) add table_ptr1 = 8, table_ptr1 ;;
+//
+// Point to 2*-14
+//
+(p0) ldfs TWO_TO_NEG14 = [table_ptr1], 4
+ nop.i 999 ;;
+}
+//
+// Load 2**(-14).
+//
+
+{ .mmi
+(p0) ldfs NEGTWO_TO_NEG14 = [table_ptr1], 180 ;;
+//
+// N_0_fix = integer part of N_0 .
+// Adjust table_ptr1 to beginning of table.
+//
+(p0) ldfs TWO_TO_NEG2 = [table_ptr1], 4
+ nop.i 999 ;;
+}
+//
+// Make N_0 the integer part.
+//
+
+{ .mfi
+(p0) ldfs NEGTWO_TO_NEG2 = [table_ptr1]
+//
+// Load -2**(-14).
+//
+(p0) fcvt.fx.s1 N_0_fix = N_0
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p0) fcvt.xf N_0 = N_0_fix
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p0) fnma.s1 ArgPrime = N_0, P_0, Arg
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p0) fmpy.s1 w = N_0, d_1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// ArgPrime = -N_0 * P_0 + Arg
+// w = N_0 * d_1
+//
+(p0) fmpy.s1 N = ArgPrime, two_by_PI
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N = ArgPrime * 2/pi
+//
+(p0) fcvt.fx.s1 N_fix = N
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N_fix is the integer part.
+//
+(p0) fcvt.xf N = N_fix
+ nop.i 999 ;;
+}
+
+{ .mfi
+(p0) getf.sig N_fix_gr = N_fix
+ nop.f 999
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N is the integer part of the reduced-reduced argument.
+// Put the integer in a GP register.
+//
+(p0) fnma.s1 s_val = N, P_1, ArgPrime
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p0) fnma.s1 w = N, P_2, w
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// s_val = -N*P_1 + ArgPrime
+// w = -N*P_2 + w
+//
+(p0) fcmp.lt.unc.s1 p11, p10 = s_val, TWO_TO_NEG14
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p11) fcmp.gt.s1 p11, p10 = s_val, NEGTWO_TO_NEG14
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 3: r = s_val + w (Z complete)
+// Case 4: U_hi = N_0 * d_1
+//
+(p10) fmpy.s1 V_hi = N, P_2
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p11) fmpy.s1 U_hi = N_0, d_1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 3: r = s_val + w (Z complete)
+// Case 4: U_hi = N_0 * d_1
+//
+(p11) fmpy.s1 V_hi = N, P_2
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p11) fmpy.s1 U_hi = N_0, d_1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Decide between case 3 and 4:
+// Case 3: s <= -2**(-14) or s >= 2**(-14)
+// Case 4: -2**(-14) < s < 2**(-14)
+//
+(p10) fadd.s1 r = s_val, w
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p11) fmpy.s1 w = N, P_3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 4: We need abs of both U_hi and V_hi - dont
+// worry about switched sign of V_hi .
+//
+(p11) fsub.s1 A = U_hi, V_hi
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 4: A = U_hi + V_hi
+// Note: Worry about switched sign of V_hi, so subtract instead of add.
+//
+(p11) fnma.s1 V_lo = N, P_2, V_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p11) fms.s1 U_lo = N_0, d_1, U_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p11) fabs V_hiabs = V_hi
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 4: V_hi = N * P_2
+// w = N * P_3
+// Note the product does not include the (-) as in the writeup
+// so (-) missing for V_hi and w .
+(p10) fadd.s1 r = s_val, w
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 3: c = s_val - r
+// Case 4: U_lo = N_0 * d_1 - U_hi
+//
+(p11) fabs U_hiabs = U_hi
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p11) fmpy.s1 w = N, P_3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 4: Set P_12 if U_hiabs >= V_hiabs
+//
+(p11) fadd.s1 C_hi = s_val, A
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 4: C_hi = s_val + A
+//
+(p11) fadd.s1 t = U_lo, V_lo
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 3: Is |r| < 2**(-2), if so set PR_7
+// else set PR_8.
+// Case 3: If PR_7 is set, prepare to branch to Small_R.
+// Case 3: If PR_8 is set, prepare to branch to Normal_R.
+//
+(p10) fsub.s1 c = s_val, r
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 3: c = (s - r) + w (c complete)
+//
+(p11) fcmp.ge.unc.s1 p12, p13 = U_hiabs, V_hiabs
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p11) fms.s1 w = N_0, d_2, w
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 4: V_hi = N * P_2
+// w = N * P_3
+// Note the product does not include the (-) as in the writeup
+// so (-) missing for V_hi and w .
+//
+(p10) fcmp.lt.unc.s1 p14, p15 = r, TWO_TO_NEG2
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p14) fcmp.gt.s1 p14, p15 = r, NEGTWO_TO_NEG2
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+//
+// Case 4: V_lo = -N * P_2 - V_hi (U_hi is in place of V_hi in writeup)
+// Note: the (-) is still missing for V_hi .
+// Case 4: w = w + N_0 * d_2
+// Note: the (-) is now incorporated in w .
+//
+(p10) fadd.s1 c = c, w
+//
+// Case 4: t = U_lo + V_lo
+// Note: remember V_lo should be (-), subtract instead of add. NO
+//
+(p14) br.cond.spnt TAN_SMALL_R ;;
+}
+
+{ .mib
+ nop.m 999
+ nop.i 999
+(p15) br.cond.spnt TAN_NORMAL_R ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 3: Vector off when |r| < 2**(-2). Recall that PR_3 will be true.
+// The remaining stuff is for Case 4.
+//
+(p12) fsub.s1 a = U_hi, A
+(p11) extr.u i_1 = N_fix_gr, 0, 1 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 4: C_lo = s_val - C_hi
+//
+(p11) fadd.s1 t = t, w
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p13) fadd.s1 a = V_hi, A
+ nop.i 999 ;;
+}
+
+//
+// Case 4: a = U_hi - A
+// a = V_hi - A (do an add to account for missing (-) on V_hi
+//
+
+{ .mfi
+(p11) addl table_ptr1 = @ltoff(TAN_BASE_CONSTANTS), gp
+(p11) fsub.s1 C_lo = s_val, C_hi
+ nop.i 999
+}
+;;
+
+{ .mmi
+(p11) ld8 table_ptr1 = [table_ptr1]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+//
+// Case 4: a = (U_hi - A) + V_hi
+// a = (V_hi - A) + U_hi
+// In each case account for negative missing form V_hi .
+//
+//
+// Case 4: C_lo = (s_val - C_hi) + A
+//
+
+{ .mmi
+(p11) add table_ptr1 = 224, table_ptr1 ;;
+(p11) ldfe P1_1 = [table_ptr1], 16
+ nop.i 999 ;;
+}
+
+{ .mfi
+(p11) ldfe P1_2 = [table_ptr1], 128
+//
+// Case 4: w = U_lo + V_lo + w
+//
+(p12) fsub.s1 a = a, V_hi
+ nop.i 999 ;;
+}
+//
+// Case 4: r = C_hi + C_lo
+//
+
+{ .mfi
+(p11) ldfe Q1_1 = [table_ptr1], 16
+(p11) fadd.s1 C_lo = C_lo, A
+ nop.i 999 ;;
+}
+//
+// Case 4: c = C_hi - r
+// Get [i_1] - lsb of N_fix_gr.
+//
+
+{ .mfi
+(p11) ldfe Q1_2 = [table_ptr1], 16
+ nop.f 999
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p13) fsub.s1 a = U_hi, a
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p11) fadd.s1 t = t, a
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 4: t = t + a
+//
+(p11) fadd.s1 C_lo = C_lo, t
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 4: C_lo = C_lo + t
+//
+(p11) fadd.s1 r = C_hi, C_lo
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p11) fsub.s1 c = C_hi, r
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// Case 4: c = c + C_lo finished.
+// Is i_1 even or odd?
+// if i_1 == 0, set PR_4, else set PR_5.
+//
+// r and c have been computed.
+// We known whether this is the sine or cosine routine.
+// Make sure ftz mode is set - should be automatic when using wre
+(p0) fmpy.s1 rsq = r, r
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p11) fadd.s1 c = c , C_lo
+(p11) cmp.eq.unc p11, p12 = 0x0000, i_1 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) frcpa.s1 S_hi, p0 = f1, r
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: Change sign of S_hi
+//
+(p11) fma.s1 Result = rsq, P1_2, P1_1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 P = rsq, Q1_2, Q1_1
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: Result = S_hi + S_lo (User supplied rounding mode for C1)
+//
+(p0) fmpy.s0 fp_tmp = fp_tmp, fp_tmp // Dummy mult to set inexact
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: rsq = r * r
+// N odd: S_hi = frcpa(r)
+//
+(p12) fmerge.ns S_hi = S_hi, S_hi
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: rsq = rsq * P1_2 + P1_1
+// N odd: poly1 = 1.0 + S_hi * r 16 bits partial account for necessary
+//
+(p11) fmpy.s1 Result = rsq, Result
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, r,f1
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: Result = Result * rsq
+// N odd: S_hi = S_hi + S_hi*poly1 16 bits account for necessary
+//
+(p11) fma.s1 Result = r, Result, c
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: S_hi = S_hi * poly1 + S_hi 32 bits
+//
+(p11) fadd.s0 Result= r, Result
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: Result = Result * r + c
+// N odd: poly1 = 1.0 + S_hi * r 32 bits partial
+//
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: Result1 = Result + r (Rounding mode S0)
+// N odd: poly1 = S_hi * r + 1.0 64 bits partial
+//
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * poly + S_hi 64 bits
+//
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * r + 1.0
+//
+(p12) fma.s1 poly1 = S_hi, c, poly1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * c + poly1
+//
+(p12) fmpy.s1 S_lo = S_hi, poly1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: S_lo = S_hi * poly1
+//
+(p12) fma.s1 S_lo = P, r, S_lo
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+//
+// N odd: S_lo = S_lo + r * P
+//
+(p12) fadd.s0 Result = S_hi, S_lo
+(p0) br.ret.sptk b0 ;;
+}
+
+
+TAN_SMALL_R:
+
+{ .mii
+ nop.m 999
+(p0) extr.u i_1 = N_fix_gr, 0, 1 ;;
+(p0) cmp.eq.unc p11, p12 = 0x0000, i_1
+}
+
+{ .mfi
+ nop.m 999
+(p0) fmpy.s1 rsq = r, r
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) frcpa.s1 S_hi, p0 = f1, r
+ nop.i 999
+}
+
+{ .mfi
+(p0) addl table_ptr1 = @ltoff(TAN_BASE_CONSTANTS), gp
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mmi
+(p0) ld8 table_ptr1 = [table_ptr1]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+// *****************************************************************
+// *****************************************************************
+// *****************************************************************
+
+{ .mmi
+(p0) add table_ptr1 = 224, table_ptr1 ;;
+(p0) ldfe P1_1 = [table_ptr1], 16
+ nop.i 999 ;;
+}
+// r and c have been computed.
+// We known whether this is the sine or cosine routine.
+// Make sure ftz mode is set - should be automatic when using wre
+// |r| < 2**(-2)
+
+{ .mfi
+(p0) ldfe P1_2 = [table_ptr1], 16
+(p11) fmpy.s1 r_to_the_8 = rsq, rsq
+ nop.i 999 ;;
+}
+//
+// Set table_ptr1 to beginning of constant table.
+// Get [i_1] - lsb of N_fix_gr.
+//
+
+{ .mfi
+(p0) ldfe P1_3 = [table_ptr1], 96
+//
+// N even: rsq = r * r
+// N odd: S_hi = frcpa(r)
+//
+(p12) fmerge.ns S_hi = S_hi, S_hi
+ nop.i 999 ;;
+}
+//
+// Is i_1 even or odd?
+// if i_1 == 0, set PR_11.
+// if i_1 != 0, set PR_12.
+//
+
+{ .mfi
+(p11) ldfe P1_9 = [table_ptr1], -16
+//
+// N even: Poly2 = P1_7 + Poly2 * rsq
+// N odd: poly2 = Q1_5 + poly2 * rsq
+//
+(p11) fadd.s1 CORR = rsq, f1
+ nop.i 999 ;;
+}
+
+{ .mmi
+(p11) ldfe P1_8 = [table_ptr1], -16 ;;
+//
+// N even: Poly1 = P1_2 + P1_3 * rsq
+// N odd: poly1 = 1.0 + S_hi * r
+// 16 bits partial account for necessary (-1)
+//
+(p11) ldfe P1_7 = [table_ptr1], -16
+ nop.i 999 ;;
+}
+//
+// N even: Poly1 = P1_1 + Poly1 * rsq
+// N odd: S_hi = S_hi + S_hi * poly1) 16 bits account for necessary
+//
+
+{ .mfi
+(p11) ldfe P1_6 = [table_ptr1], -16
+//
+// N even: Poly2 = P1_5 + Poly2 * rsq
+// N odd: poly2 = Q1_3 + poly2 * rsq
+//
+(p11) fmpy.s1 r_to_the_8 = r_to_the_8, r_to_the_8
+ nop.i 999 ;;
+}
+//
+// N even: Poly1 = Poly1 * rsq
+// N odd: poly1 = 1.0 + S_hi * r 32 bits partial
+//
+
+{ .mfi
+(p11) ldfe P1_5 = [table_ptr1], -16
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+//
+// N even: CORR = CORR * c
+// N odd: S_hi = S_hi * poly1 + S_hi 32 bits
+//
+
+//
+// N even: Poly2 = P1_6 + Poly2 * rsq
+// N odd: poly2 = Q1_4 + poly2 * rsq
+//
+{ .mmf
+(p0) addl table_ptr2 = @ltoff(TAN_BASE_CONSTANTS), gp
+(p11) ldfe P1_4 = [table_ptr1], -16
+(p11) fmpy.s1 CORR = CORR, c
+}
+;;
+
+
+{ .mmi
+(p0) ld8 table_ptr2 = [table_ptr2]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+
+{ .mii
+(p0) add table_ptr2 = 464, table_ptr2
+ nop.i 999 ;;
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p11) fma.s1 Poly1 = P1_3, rsq, P1_2
+ nop.i 999 ;;
+}
+
+{ .mfi
+(p0) ldfe Q1_7 = [table_ptr2], -16
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+(p0) ldfe Q1_6 = [table_ptr2], -16
+(p11) fma.s1 Poly2 = P1_9, rsq, P1_8
+ nop.i 999 ;;
+}
+
+{ .mmi
+(p0) ldfe Q1_5 = [table_ptr2], -16 ;;
+(p12) ldfe Q1_4 = [table_ptr2], -16
+ nop.i 999 ;;
+}
+
+{ .mfi
+(p12) ldfe Q1_3 = [table_ptr2], -16
+//
+// N even: Poly2 = P1_8 + P1_9 * rsq
+// N odd: poly2 = Q1_6 + Q1_7 * rsq
+//
+(p11) fma.s1 Poly1 = Poly1, rsq, P1_1
+ nop.i 999 ;;
+}
+
+{ .mfi
+(p12) ldfe Q1_2 = [table_ptr2], -16
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+(p12) ldfe Q1_1 = [table_ptr2], -16
+(p11) fma.s1 Poly2 = Poly2, rsq, P1_7
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: CORR = rsq + 1
+// N even: r_to_the_8 = rsq * rsq
+//
+(p11) fmpy.s1 Poly1 = Poly1, rsq
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly2 = Q1_7, rsq, Q1_6
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p11) fma.s1 Poly2 = Poly2, rsq, P1_6
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly2 = poly2, rsq, Q1_5
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p11) fma.s1 Poly2= Poly2, rsq, P1_5
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly2 = poly2, rsq, Q1_4
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: r_to_the_8 = r_to_the_8 * r_to_the_8
+// N odd: poly1 = S_hi * r + 1.0 64 bits partial
+//
+(p11) fma.s1 Poly2 = Poly2, rsq, P1_4
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: Result = CORR + Poly * r
+// N odd: P = Q1_1 + poly2 * rsq
+//
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly2 = poly2, rsq, Q1_3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: Poly2 = P1_4 + Poly2 * rsq
+// N odd: poly2 = Q1_2 + poly2 * rsq
+//
+(p11) fma.s1 Poly = Poly2, r_to_the_8, Poly1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, c, poly1
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly2 = poly2, rsq, Q1_2
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: Poly = Poly1 + Poly2 * r_to_the_8
+// N odd: S_hi = S_hi * poly1 + S_hi 64 bits
+//
+(p11) fma.s1 Result = Poly, r, CORR
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: Result = r + Result (User supplied rounding mode)
+// N odd: poly1 = S_hi * c + poly1
+//
+(p12) fmpy.s1 S_lo = S_hi, poly1
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 P = poly2, rsq, Q1_1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * r + 1.0
+//
+(p11) fadd.s0 Result = Result, r
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: S_lo = S_hi * poly1
+//
+(p12) fma.s1 S_lo = Q1_1, c, S_lo
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: Result = Result + S_hi (user supplied rounding mode)
+//
+(p0) fmpy.s0 fp_tmp = fp_tmp, fp_tmp // Dummy mult to set inexact
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: S_lo = Q1_1 * c + S_lo
+//
+(p12) fma.s1 Result = P, r, S_lo
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+//
+// N odd: Result = S_lo + r * P
+//
+(p12) fadd.s0 Result = Result, S_hi
+(p0) br.ret.sptk b0 ;;
+}
+
+
+TAN_NORMAL_R:
+
+{ .mfi
+(p0) getf.sig sig_r = r
+// *******************************************************************
+// *******************************************************************
+// *******************************************************************
+//
+// r and c have been computed.
+// Make sure ftz mode is set - should be automatic when using wre
+//
+//
+// Get [i_1] - lsb of N_fix_gr alone.
+//
+(p0) fmerge.s Pos_r = f1, r
+(p0) extr.u i_1 = N_fix_gr, 0, 1 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p0) fmerge.s sgn_r = r, f1
+(p0) cmp.eq.unc p11, p12 = 0x0000, i_1 ;;
+}
+
+{ .mfi
+ nop.m 999
+ nop.f 999
+(p0) extr.u lookup = sig_r, 58, 5
+}
+
+{ .mlx
+ nop.m 999
+(p0) movl Create_B = 0x8200000000000000 ;;
+}
+
+{ .mfi
+(p0) addl table_ptr1 = @ltoff(TAN_BASE_CONSTANTS), gp
+ nop.f 999
+(p0) dep Create_B = lookup, Create_B, 58, 5
+}
+;;
+
+//
+// Get [i_1] - lsb of N_fix_gr alone.
+// Pos_r = abs (r)
+//
+
+
+{ .mmi
+ ld8 table_ptr1 = [table_ptr1]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+
+{ .mmi
+ nop.m 999
+(p0) setf.sig B = Create_B
+//
+// Set table_ptr1 and table_ptr2 to base address of
+// constant table.
+//
+(p0) add table_ptr1 = 480, table_ptr1 ;;
+}
+
+{ .mmb
+ nop.m 999
+//
+// Is i_1 or i_0 == 0 ?
+// Create the constant 1 00000 1000000000000000000000...
+//
+(p0) ldfe P2_1 = [table_ptr1], 16
+ nop.b 999
+}
+
+{ .mmi
+ nop.m 999 ;;
+(p0) getf.exp exp_r = Pos_r
+ nop.i 999
+}
+//
+// Get r's exponent
+// Get r's significand
+//
+
+{ .mmi
+(p0) ldfe P2_2 = [table_ptr1], 16 ;;
+//
+// Get the 5 bits or r for the lookup. 1.xxxxx ....
+// from sig_r.
+// Grab lsb of exp of B
+//
+(p0) ldfe P2_3 = [table_ptr1], 16
+ nop.i 999 ;;
+}
+
+{ .mii
+ nop.m 999
+(p0) andcm table_offset = 0x0001, exp_r ;;
+(p0) shl table_offset = table_offset, 9 ;;
+}
+
+{ .mii
+ nop.m 999
+//
+// Deposit 0 00000 1000000000000000000000... on
+// 1 xxxxx yyyyyyyyyyyyyyyyyyyyyy...,
+// getting rid of the ys.
+// Is B = 2** -2 or B= 2** -1? If 2**-1, then
+// we want an offset of 512 for table addressing.
+//
+(p0) shladd table_offset = lookup, 4, table_offset ;;
+//
+// B = ........ 1xxxxx 1000000000000000000...
+//
+(p0) add table_ptr1 = table_ptr1, table_offset ;;
+}
+
+{ .mmb
+ nop.m 999
+//
+// B = ........ 1xxxxx 1000000000000000000...
+// Convert B so it has the same exponent as Pos_r
+//
+(p0) ldfd T_hi = [table_ptr1], 8
+ nop.b 999 ;;
+}
+
+//
+// x = |r| - B
+// Load T_hi.
+// Load C_hi.
+//
+
+{ .mmf
+(p0) addl table_ptr2 = @ltoff(TAN_BASE_CONSTANTS), gp
+(p0) ldfs T_lo = [table_ptr1]
+(p0) fmerge.se B = Pos_r, B
+}
+;;
+
+{ .mmi
+ ld8 table_ptr2 = [table_ptr2]
+ nop.m 999
+ nop.i 999
+}
+;;
+
+{ .mii
+(p0) add table_ptr2 = 1360, table_ptr2
+ nop.i 999 ;;
+(p0) add table_ptr2 = table_ptr2, table_offset ;;
+}
+
+{ .mfi
+(p0) ldfd C_hi = [table_ptr2], 8
+(p0) fsub.s1 x = Pos_r, B
+ nop.i 999 ;;
+}
+
+{ .mii
+(p0) ldfs C_lo = [table_ptr2],255
+ nop.i 999 ;;
+//
+// xsq = x * x
+// N even: Tx = T_hi * x
+// Load T_lo.
+// Load C_lo - increment pointer to get SC_inv
+// - cant get all the way, do an add later.
+//
+(p0) add table_ptr2 = 569, table_ptr2 ;;
+}
+//
+// N even: Tx1 = Tx + 1
+// N odd: Cx1 = 1 - Cx
+//
+
+{ .mfi
+(p0) ldfe SC_inv = [table_ptr2], 0
+ nop.f 999
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p0) fmpy.s1 xsq = x, x
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p11) fmpy.s1 Tx = T_hi, x
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fmpy.s1 Cx = C_hi, x
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: Cx = C_hi * x
+//
+(p0) fma.s1 P = P2_3, xsq, P2_2
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even and odd: P = P2_3 + P2_2 * xsq
+//
+(p11) fadd.s1 Tx1 = Tx, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: D = C_hi - tanx
+// N odd: D = T_hi + tanx
+//
+(p11) fmpy.s1 CORR = SC_inv, T_hi
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p0) fmpy.s1 Sx = SC_inv, x
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fmpy.s1 CORR = SC_inv, C_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fsub.s1 V_hi = f1, Cx
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p0) fma.s1 P = P, xsq, P2_1
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even and odd: P = P2_1 + P * xsq
+//
+(p11) fma.s1 V_hi = Tx, Tx1, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: Result = sgn_r * tail + T_hi (user rounding mode for C1)
+// N odd: Result = sgn_r * tail + C_hi (user rounding mode for C1)
+//
+(p0) fmpy.s0 fp_tmp = fp_tmp, fp_tmp // Dummy mult to set inexact
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p0) fmpy.s1 CORR = CORR, c
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fnma.s1 V_hi = Cx,V_hi,f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: V_hi = Tx * Tx1 + 1
+// N odd: Cx1 = 1 - Cx * Cx1
+//
+(p0) fmpy.s1 P = P, xsq
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even and odd: P = P * xsq
+//
+(p11) fmpy.s1 V_hi = V_hi, T_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even and odd: tail = P * tail + V_lo
+//
+(p11) fmpy.s1 T_hi = sgn_r, T_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p0) fmpy.s1 CORR = CORR, sgn_r
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p12) fmpy.s1 V_hi = V_hi,C_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: V_hi = T_hi * V_hi
+// N odd: V_hi = C_hi * V_hi
+//
+(p0) fma.s1 tanx = P, x, x
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p12) fnmpy.s1 C_hi = sgn_r, C_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: V_lo = 1 - V_hi + C_hi
+// N odd: V_lo = 1 - V_hi + T_hi
+//
+(p11) fadd.s1 CORR = CORR, T_lo
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p12) fsub.s1 CORR = CORR, C_lo
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even and odd: tanx = x + x * P
+// N even and odd: Sx = SC_inv * x
+//
+(p11) fsub.s1 D = C_hi, tanx
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p12) fadd.s1 D = T_hi, tanx
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: CORR = SC_inv * C_hi
+// N even: CORR = SC_inv * T_hi
+//
+(p0) fnma.s1 D = V_hi, D, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even and odd: D = 1 - V_hi * D
+// N even and odd: CORR = CORR * c
+//
+(p0) fma.s1 V_hi = V_hi, D, V_hi
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even and odd: V_hi = V_hi + V_hi * D
+// N even and odd: CORR = sgn_r * CORR
+//
+(p11) fnma.s1 V_lo = V_hi, C_hi, f1
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p12) fnma.s1 V_lo = V_hi, T_hi, f1
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: CORR = COOR + T_lo
+// N odd: CORR = CORR - C_lo
+//
+(p11) fma.s1 V_lo = tanx, V_hi, V_lo
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p12) fnma.s1 V_lo = tanx, V_hi, V_lo
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: V_lo = V_lo + V_hi * tanx
+// N odd: V_lo = V_lo - V_hi * tanx
+//
+(p11) fnma.s1 V_lo = C_lo, V_hi, V_lo
+ nop.i 999
+}
+
+{ .mfi
+ nop.m 999
+(p12) fnma.s1 V_lo = T_lo, V_hi, V_lo
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: V_lo = V_lo - V_hi * C_lo
+// N odd: V_lo = V_lo - V_hi * T_lo
+//
+(p0) fmpy.s1 V_lo = V_hi, V_lo
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even and odd: V_lo = V_lo * V_hi
+//
+(p0) fadd.s1 tail = V_hi, V_lo
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even and odd: tail = V_hi + V_lo
+//
+(p0) fma.s1 tail = tail, P, V_lo
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: T_hi = sgn_r * T_hi
+// N odd : C_hi = -sgn_r * C_hi
+//
+(p0) fma.s1 tail = tail, Sx, CORR
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even and odd: tail = Sx * tail + CORR
+//
+(p0) fma.s1 tail = V_hi, Sx, tail
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even an odd: tail = Sx * V_hi + tail
+//
+(p11) fma.s0 Result = sgn_r, tail, T_hi
+ nop.i 999
+}
+
+{ .mfb
+ nop.m 999
+(p12) fma.s0 Result = sgn_r, tail, C_hi
+(p0) br.ret.sptk b0 ;;
+}
+
+.endp __libm_tan
+ASM_SIZE_DIRECTIVE(__libm_tan)
+
+
+
+// *******************************************************************
+// *******************************************************************
+// *******************************************************************
+//
+// Special Code to handle very large argument case.
+// Call int pi_by_2_reduce(&x,&r)
+// for |arguments| >= 2**63
+// (Arg or x) is in f8
+// Address to save r and c as double
+
+// (1) (2) (3) (call) (4)
+// sp -> + psp -> + psp -> + sp -> +
+// | | | |
+// | r50 ->| <- r50 f0 ->| r50 -> | -> c
+// | | | |
+// sp-32 -> | <- r50 f0 ->| f0 ->| <- r50 r49 -> | -> r
+// | | | |
+// | r49 ->| <- r49 Arg ->| <- r49 | -> x
+// | | | |
+// sp -64 ->| sp -64 ->| sp -64 ->| |
+//
+// save pfs save b0 restore gp
+// save gp restore b0
+// restore pfs
+
+
+
+.proc __libm_callout
+__libm_callout:
+TAN_ARG_TOO_LARGE:
+.prologue
+// (1)
+{ .mfi
+ add GR_Parameter_r =-32,sp // Parameter: r address
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+// (2)
+{ .mmi
+ stfe [GR_Parameter_r ] = f0,16 // Clear Parameter r on stack
+ add GR_Parameter_X = 16,sp // Parameter x address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+// (3)
+.body
+{ .mib
+ stfe [GR_Parameter_r ] = f0,-16 // Clear Parameter c on stack
+ nop.i 0
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_X] = Arg // Store Parameter x on stack
+ nop.i 0
+(p0) br.call.sptk b0=__libm_pi_by_2_reduce#
+}
+;;
+
+
+// (4)
+{ .mmi
+ mov gp = GR_SAVE_GP // Restore gp
+(p0) mov N_fix_gr = r8
+ nop.i 999
+}
+;;
+
+{ .mmi
+(p0) ldfe Arg =[GR_Parameter_X],16
+(p0) ldfs TWO_TO_NEG2 = [table_ptr2],4
+ nop.i 999
+}
+;;
+
+
+{ .mmb
+(p0) ldfe r =[GR_Parameter_r ],16
+(p0) ldfs NEGTWO_TO_NEG2 = [table_ptr2],4
+ nop.b 999 ;;
+}
+
+{ .mfi
+(p0) ldfe c =[GR_Parameter_r ]
+ nop.f 999
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// Is |r| < 2**(-2)
+//
+(p0) fcmp.lt.unc.s1 p6, p0 = r, TWO_TO_NEG2
+ mov b0 = GR_SAVE_B0 // Restore return address
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fcmp.gt.unc.s1 p6, p0 = r, NEGTWO_TO_NEG2
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+}
+;;
+
+{ .mbb
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+(p6) br.cond.spnt TAN_SMALL_R
+(p0) br.cond.sptk TAN_NORMAL_R
+}
+;;
+.endp __libm_callout
+ASM_SIZE_DIRECTIVE(__libm_callout)
+
+
+.proc __libm_TAN_SPECIAL
+__libm_TAN_SPECIAL:
+
+//
+// Code for NaNs, Unsupporteds, Infs, or +/- zero ?
+// Invalid raised for Infs and SNaNs.
+//
+
+{ .mfb
+ nop.m 999
+(p0) fmpy.s0 Arg = Arg, f0
+(p0) br.ret.sptk b0
+}
+.endp __libm_TAN_SPECIAL
+ASM_SIZE_DIRECTIVE(__libm_TAN_SPECIAL)
+
+
+.type __libm_pi_by_2_reduce#,@function
+.global __libm_pi_by_2_reduce#
diff --git a/libc/sysdeps/ia64/fpu/math_ldbl.h b/libc/sysdeps/ia64/fpu/math_ldbl.h
new file mode 100644
index 000000000..475ca795f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/math_ldbl.h
@@ -0,0 +1,100 @@
+#ifndef _MATH_PRIVATE_H_
+#error "Never use <math_ldbl.h> directly; include <math_private.h> instead."
+#endif
+
+/* A union which permits us to convert between a long double and
+ three 32 bit ints. */
+
+#if __FLOAT_WORD_ORDER == BIG_ENDIAN
+
+typedef union
+{
+ long double value;
+ struct
+ {
+ unsigned int empty0:32;
+ int sign_exponent:16;
+ unsigned int empty1:16;
+ u_int32_t msw;
+ u_int32_t lsw;
+ } parts;
+} ieee_long_double_shape_type;
+
+#endif
+
+#if __FLOAT_WORD_ORDER == LITTLE_ENDIAN
+
+typedef union
+{
+ long double value;
+ struct
+ {
+ u_int32_t lsw;
+ u_int32_t msw;
+ int sign_exponent:16;
+ unsigned int empty1:16;
+ unsigned int empty0:32;
+ } parts;
+} ieee_long_double_shape_type;
+
+#endif
+
+/* Get three 32 bit ints from a double. */
+
+#define GET_LDOUBLE_WORDS(exp,ix0,ix1,d) \
+do { \
+ ieee_long_double_shape_type ew_u; \
+ ew_u.value = (d); \
+ (exp) = ew_u.parts.sign_exponent; \
+ (ix0) = ew_u.parts.msw; \
+ (ix1) = ew_u.parts.lsw; \
+} while (0)
+
+/* Set a double from two 32 bit ints. */
+
+#define SET_LDOUBLE_WORDS(d,exp,ix0,ix1) \
+do { \
+ ieee_long_double_shape_type iw_u; \
+ iw_u.parts.sign_exponent = (exp); \
+ iw_u.parts.msw = (ix0); \
+ iw_u.parts.lsw = (ix1); \
+ (d) = iw_u.value; \
+} while (0)
+
+/* Get the more significant 32 bits of a long double mantissa. */
+
+#define GET_LDOUBLE_MSW(v,d) \
+do { \
+ ieee_long_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ (v) = sh_u.parts.msw; \
+} while (0)
+
+/* Set the more significant 32 bits of a long double mantissa from an int. */
+
+#define SET_LDOUBLE_MSW(d,v) \
+do { \
+ ieee_long_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ sh_u.parts.msw = (v); \
+ (d) = sh_u.value; \
+} while (0)
+
+/* Get int from the exponent of a long double. */
+
+#define GET_LDOUBLE_EXP(exp,d) \
+do { \
+ ieee_long_double_shape_type ge_u; \
+ ge_u.value = (d); \
+ (exp) = ge_u.parts.sign_exponent; \
+} while (0)
+
+/* Set exponent of a long double from an int. */
+
+#define SET_LDOUBLE_EXP(d,exp) \
+do { \
+ ieee_long_double_shape_type se_u; \
+ se_u.value = (d); \
+ se_u.parts.sign_exponent = (exp); \
+ (d) = se_u.value; \
+} while (0)
diff --git a/libc/sysdeps/ia64/fpu/mpa.c b/libc/sysdeps/ia64/fpu/mpa.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/mpa.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/mpatan.c b/libc/sysdeps/ia64/fpu/mpatan.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/mpatan.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/mpatan2.c b/libc/sysdeps/ia64/fpu/mpatan2.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/mpatan2.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/mpexp.c b/libc/sysdeps/ia64/fpu/mpexp.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/mpexp.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/mplog.c b/libc/sysdeps/ia64/fpu/mplog.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/mplog.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/mpsqrt.c b/libc/sysdeps/ia64/fpu/mpsqrt.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/mpsqrt.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/mptan.c b/libc/sysdeps/ia64/fpu/mptan.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/mptan.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/printf_fphex.c b/libc/sysdeps/ia64/fpu/printf_fphex.c
new file mode 100644
index 000000000..5def1905d
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/printf_fphex.c
@@ -0,0 +1,81 @@
+/* Print floating point number in hexadecimal notation according to ISO C99.
+ Copyright (C) 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef LONG_DOUBLE_DENORM_BIAS
+# define LONG_DOUBLE_DENORM_BIAS (IEEE854_LONG_DOUBLE_BIAS - 1)
+#endif
+
+#define PRINT_FPHEX_LONG_DOUBLE \
+do { \
+ /* The "strange" 80 bit format on ia64 has an explicit \
+ leading digit in the 64 bit mantissa. */ \
+ unsigned long long int num; \
+ \
+ num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \
+ | fpnum.ldbl.ieee.mantissa1); \
+ \
+ zero_mantissa = num == 0; \
+ \
+ numstr = _itoa_word (num, numbuf + sizeof numbuf, 16, \
+ info->spec == 'A'); \
+ wnumstr = _itowa_word (num, \
+ wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t), \
+ 16, info->spec == 'A'); \
+ \
+ /* Fill with zeroes. */ \
+ while (numstr > numbuf + (sizeof numbuf - 64 / 4)) \
+ { \
+ *--numstr = '0'; \
+ *--wnumstr = L'0'; \
+ } \
+ \
+ /* We use a full nibble for the leading digit. */ \
+ leading = *numstr++; \
+ \
+ /* We have 3 bits from the mantissa in the leading nibble. \
+ Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'. */ \
+ exponent = fpnum.ldbl.ieee.exponent; \
+ \
+ if (exponent == 0) \
+ { \
+ if (zero_mantissa) \
+ expnegative = 0; \
+ else \
+ { \
+ /* This is a denormalized number. */ \
+ expnegative = 1; \
+ /* This is a hook for the m68k long double format, where the \
+ exponent bias is the same for normalized and denormalized \
+ numbers. */ \
+ exponent = LONG_DOUBLE_DENORM_BIAS + 3; \
+ } \
+ } \
+ else if (exponent >= IEEE854_LONG_DOUBLE_BIAS + 3) \
+ { \
+ expnegative = 0; \
+ exponent -= IEEE854_LONG_DOUBLE_BIAS + 3; \
+ } \
+ else \
+ { \
+ expnegative = 1; \
+ exponent = -(exponent - (IEEE854_LONG_DOUBLE_BIAS + 3)); \
+ } \
+} while (0)
+
+#include <stdio-common/printf_fphex.c>
diff --git a/libc/sysdeps/ia64/fpu/s_asinh.S b/libc/sysdeps/ia64/fpu/s_asinh.S
new file mode 100644
index 000000000..7eba39eb4
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_asinh.S
@@ -0,0 +1,1138 @@
+.file "asinh.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// ==============================================================
+// History
+// ==============================================================
+// 04/02/01 Initial version
+// 04/19/01 Improved speed of the paths #1,2,3,4,5
+// 10/18/01 Improved accuracy
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 05/21/03 Improved performance, fixed to handle unorms
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+// ==============================================================
+// double asinh(double)
+//
+// Overview of operation
+// ==============================================================
+//
+// There are 7 paths:
+// 1. x = 0.0
+// Return asinh(x) = 0.0
+//
+// 2. 0.0 <|x| < 2^(-3)
+// Return asinh(x) = POL13(x),
+// where POL13(x) = (x^2*C13 + ...)*x^2 + C5)*x^2 + C3)*x^3 + x
+//
+// 3. 2^(-3) <= |x| < 2^63
+// Return asinh(x) = sign(x)*(log(|x| + sqrt(x^2 + 1.0)))
+// To compute x + sqrt(x^2 + 1.0) modified Newton Raphson method is used
+// (3 iterations)
+// Algorithm description for log function see below.
+//
+// 4. 2^63 <= |x| < +INF
+// Return asinh(x) = sign(x)*log(2*|x|)
+// Algorithm description for log function see below.
+//
+// 5. x = INF
+// Return asinh(x) = INF
+//
+// 6. x = [S,Q]NaN
+// Return asinh(x) = QNaN
+//
+// 7. x = denormal
+// Return asinh(x) = x correctly rounded
+//
+//==============================================================
+// Algorithm Description for log(x) function
+// Below we are using the fact that inequality x - 1.0 > 2^(-6) is always
+// true for this asinh implementation
+//
+// Consider x = 2^N 1.f1 f2 f3 f4...f63
+// Log(x) = log(frcpa(x) x/frcpa(x))
+// = log(1/frcpa(x)) + log(frcpa(x) x)
+// = -log(frcpa(x)) + log(frcpa(x) x)
+//
+// frcpa(x) = 2^-N frcpa((1.f1 f2 ... f63)
+//
+// -log(frcpa(x)) = -log(C)
+// = -log(2^-N) - log(frcpa(1.f1 f2 ... f63))
+//
+// -log(frcpa(x)) = -log(C)
+// = +Nlog2 - log(frcpa(1.f1 f2 ... f63))
+//
+// -log(frcpa(x)) = -log(C)
+// = +Nlog2 + log(frcpa(1.f1 f2 ... f63))
+//
+// Log(x) = log(1/frcpa(x)) + log(frcpa(x) x)
+//
+// Log(x) = +Nlog2 + log(1./frcpa(1.f1 f2 ... f63)) + log(frcpa(x) x)
+// Log(x) = +Nlog2 - log(/frcpa(1.f1 f2 ... f63)) + log(frcpa(x) x)
+// Log(x) = +Nlog2 + T + log(frcpa(x) x)
+//
+// Log(x) = +Nlog2 + T + log(C x)
+//
+// Cx = 1 + r
+//
+// Log(x) = +Nlog2 + T + log(1+r)
+// Log(x) = +Nlog2 + T + Series( r - r^2/2 + r^3/3 - r^4/4 ....)
+//
+// 1.f1 f2 ... f8 has 256 entries.
+// They are 1 + k/2^8, k = 0 ... 255
+// These 256 values are the table entries.
+//
+// Implementation
+//==============================================================
+// C = frcpa(x)
+// r = C * x - 1
+//
+// Form rseries = r + P1*r^2 + P2*r^3 + P3*r^4 + P4*r^5 + P5*r^6
+//
+// x = f * 2*n where f is 1.f_1f_2f_3....f_63
+// Nfloat = float(n) where n is the true unbiased exponent
+// pre-index = f_1f_2....f_8
+// index = pre_index * 16
+// get the dxt table entry at index + offset = T
+//
+// result = (T + Nfloat * log(2)) + rseries
+//
+// The T table is calculated as follows
+// Form x_k = 1 + k/2^8 where k goes from 0... 255
+// y_k = frcpa(x_k)
+// log(1/y_k) in quad and round to double-extended
+//
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f9 -> f15, f32 -> f68
+
+// General registers used:
+// r14 -> r27
+
+// Predicate registers used:
+// p6 -> p14
+
+// p6 to filter out case when x = [Q,S]NaN or INF or zero
+// p7 to filter out case when x < 0.0
+// p8 to select path #2
+// p9 used in the frcpa from path #3
+// p11 to filter out case when x >= 0
+// p12 to filter out case when x = unorm
+// p13 to select path #4
+// Assembly macros
+//==============================================================
+log_GR_exp_17_ones = r14
+log_GR_signexp_f8 = r15
+log_table_address2 = r16
+log_GR_exp_16_ones = r17
+log_GR_exp_f8 = r18
+log_GR_true_exp_f8 = r19
+log_GR_significand_f8 = r20
+log_GR_index = r21
+log_GR_comp2 = r22
+asinh_GR_f8 = r23
+asinh_GR_comp = r24
+asinh_GR_f8 = r25
+log_table_address3 = r26
+NR_table_address = r27
+
+//==============================================================
+log_y = f9
+NR1 = f10
+NR2 = f11
+log_y_rs = f12
+log_y_rs_iter = f13
+log_y_rs_iter1 = f14
+fNormX = f15
+asinh_w_sq = f32
+log_C13 = f33
+log_C11 = f34
+log_P3 = f35
+log_P2 = f36
+log_P1 = f37
+log_P5 = f38
+log_P4 = f39
+log_C3 = f40
+log_C5 = f41
+log_C7 = f42
+log2 = f43
+asinh_f8 = f44
+log_C = f45
+log_arg = f46
+log_C9 = f47
+asinh_w_four = f48
+log_int_Nfloat = f49
+log_r = f50
+log_rsq = f51
+log_rp_p4 = f52
+log_rp_p32 = f53
+log_rcube = f54
+log_rp_p10 = f55
+log_rp_p2 = f56
+log_Nfloat = f57
+log_T = f58
+log_r2P_r = f59
+log_T_plus_Nlog2 = f60
+asinh_w_3 = f61
+asinh_w_5 = f62
+asinh_w_cube = f63
+asinh_w_7 = f64
+log_arg_early = f65
+asinh_w_9 = f66
+asinh_w_13 = f67
+asinh_w_seven = f68
+
+// Data tables
+//==============================================================
+
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(log_table_1)
+data8 0xBFC5555DA7212371 // P5
+data8 0x3FC999A19EEF5826 // P4
+data8 0xBFCFFFFFFFFEF009 // P3
+data8 0x3FD555555554ECB2 // P2
+data8 0xBFE0000000000000 // P1 = -0.5
+data8 0x0000000000000000 // pad
+data8 0xb17217f7d1cf79ac, 0x00003ffe // log2
+LOCAL_OBJECT_END(log_table_1)
+
+LOCAL_OBJECT_START(log_table_2)
+data8 0x3FE0000000000000 // 0.5
+data8 0x4008000000000000 // 3.0
+//
+data8 0x8824BE4D74BC4F00, 0x00003FF9 // C13
+data8 0xB725A2CD9556CC57, 0x0000BFF9 // C11
+data8 0xF8E339127FBFF49D, 0x00003FF9 // C9
+data8 0xB6DB6D7DCE17CB78, 0x0000BFFA // C7
+data8 0x999999998802CCEF, 0x00003FFB // C5
+data8 0xAAAAAAAAAAA8DC40, 0x0000BFFC // C3
+LOCAL_OBJECT_END(log_table_2)
+
+
+LOCAL_OBJECT_START(log_table_3)
+data8 0x80200aaeac44ef38 , 0x00003ff6 // log(1/frcpa(1+ 0/2^-8))
+//
+data8 0xc09090a2c35aa070 , 0x00003ff7 // log(1/frcpa(1+ 1/2^-8))
+data8 0xa0c94fcb41977c75 , 0x00003ff8 // log(1/frcpa(1+ 2/2^-8))
+data8 0xe18b9c263af83301 , 0x00003ff8 // log(1/frcpa(1+ 3/2^-8))
+data8 0x8d35c8d6399c30ea , 0x00003ff9 // log(1/frcpa(1+ 4/2^-8))
+data8 0xadd4d2ecd601cbb8 , 0x00003ff9 // log(1/frcpa(1+ 5/2^-8))
+//
+data8 0xce95403a192f9f01 , 0x00003ff9 // log(1/frcpa(1+ 6/2^-8))
+data8 0xeb59392cbcc01096 , 0x00003ff9 // log(1/frcpa(1+ 7/2^-8))
+data8 0x862c7d0cefd54c5d , 0x00003ffa // log(1/frcpa(1+ 8/2^-8))
+data8 0x94aa63c65e70d499 , 0x00003ffa // log(1/frcpa(1+ 9/2^-8))
+data8 0xa54a696d4b62b382 , 0x00003ffa // log(1/frcpa(1+ 10/2^-8))
+//
+data8 0xb3e4a796a5dac208 , 0x00003ffa // log(1/frcpa(1+ 11/2^-8))
+data8 0xc28c45b1878340a9 , 0x00003ffa // log(1/frcpa(1+ 12/2^-8))
+data8 0xd35c55f39d7a6235 , 0x00003ffa // log(1/frcpa(1+ 13/2^-8))
+data8 0xe220f037b954f1f5 , 0x00003ffa // log(1/frcpa(1+ 14/2^-8))
+data8 0xf0f3389b036834f3 , 0x00003ffa // log(1/frcpa(1+ 15/2^-8))
+//
+data8 0xffd3488d5c980465 , 0x00003ffa // log(1/frcpa(1+ 16/2^-8))
+data8 0x87609ce2ed300490 , 0x00003ffb // log(1/frcpa(1+ 17/2^-8))
+data8 0x8ede9321e8c85927 , 0x00003ffb // log(1/frcpa(1+ 18/2^-8))
+data8 0x96639427f2f8e2f4 , 0x00003ffb // log(1/frcpa(1+ 19/2^-8))
+data8 0x9defad3e8f73217b , 0x00003ffb // log(1/frcpa(1+ 20/2^-8))
+//
+data8 0xa582ebd50097029c , 0x00003ffb // log(1/frcpa(1+ 21/2^-8))
+data8 0xac06dbe75ab80fee , 0x00003ffb // log(1/frcpa(1+ 22/2^-8))
+data8 0xb3a78449b2d3ccca , 0x00003ffb // log(1/frcpa(1+ 23/2^-8))
+data8 0xbb4f79635ab46bb2 , 0x00003ffb // log(1/frcpa(1+ 24/2^-8))
+data8 0xc2fec93a83523f3f , 0x00003ffb // log(1/frcpa(1+ 25/2^-8))
+//
+data8 0xc99af2eaca4c4571 , 0x00003ffb // log(1/frcpa(1+ 26/2^-8))
+data8 0xd1581106472fa653 , 0x00003ffb // log(1/frcpa(1+ 27/2^-8))
+data8 0xd8002560d4355f2e , 0x00003ffb // log(1/frcpa(1+ 28/2^-8))
+data8 0xdfcb43b4fe508632 , 0x00003ffb // log(1/frcpa(1+ 29/2^-8))
+data8 0xe67f6dff709d4119 , 0x00003ffb // log(1/frcpa(1+ 30/2^-8))
+//
+data8 0xed393b1c22351280 , 0x00003ffb // log(1/frcpa(1+ 31/2^-8))
+data8 0xf5192bff087bcc35 , 0x00003ffb // log(1/frcpa(1+ 32/2^-8))
+data8 0xfbdf4ff6dfef2fa3 , 0x00003ffb // log(1/frcpa(1+ 33/2^-8))
+data8 0x81559a97f92f9cc7 , 0x00003ffc // log(1/frcpa(1+ 34/2^-8))
+data8 0x84be72bce90266e8 , 0x00003ffc // log(1/frcpa(1+ 35/2^-8))
+//
+data8 0x88bc74113f23def2 , 0x00003ffc // log(1/frcpa(1+ 36/2^-8))
+data8 0x8c2ba3edf6799d11 , 0x00003ffc // log(1/frcpa(1+ 37/2^-8))
+data8 0x8f9dc92f92ea08b1 , 0x00003ffc // log(1/frcpa(1+ 38/2^-8))
+data8 0x9312e8f36efab5a7 , 0x00003ffc // log(1/frcpa(1+ 39/2^-8))
+data8 0x968b08643409ceb6 , 0x00003ffc // log(1/frcpa(1+ 40/2^-8))
+//
+data8 0x9a062cba08a1708c , 0x00003ffc // log(1/frcpa(1+ 41/2^-8))
+data8 0x9d845b3abf95485c , 0x00003ffc // log(1/frcpa(1+ 42/2^-8))
+data8 0xa06fd841bc001bb4 , 0x00003ffc // log(1/frcpa(1+ 43/2^-8))
+data8 0xa3f3a74652fbe0db , 0x00003ffc // log(1/frcpa(1+ 44/2^-8))
+data8 0xa77a8fb2336f20f5 , 0x00003ffc // log(1/frcpa(1+ 45/2^-8))
+//
+data8 0xab0497015d28b0a0 , 0x00003ffc // log(1/frcpa(1+ 46/2^-8))
+data8 0xae91c2be6ba6a615 , 0x00003ffc // log(1/frcpa(1+ 47/2^-8))
+data8 0xb189d1b99aebb20b , 0x00003ffc // log(1/frcpa(1+ 48/2^-8))
+data8 0xb51cced5de9c1b2c , 0x00003ffc // log(1/frcpa(1+ 49/2^-8))
+data8 0xb819bee9e720d42f , 0x00003ffc // log(1/frcpa(1+ 50/2^-8))
+//
+data8 0xbbb2a0947b093a5d , 0x00003ffc // log(1/frcpa(1+ 51/2^-8))
+data8 0xbf4ec1505811684a , 0x00003ffc // log(1/frcpa(1+ 52/2^-8))
+data8 0xc2535bacfa8975ff , 0x00003ffc // log(1/frcpa(1+ 53/2^-8))
+data8 0xc55a3eafad187eb8 , 0x00003ffc // log(1/frcpa(1+ 54/2^-8))
+data8 0xc8ff2484b2c0da74 , 0x00003ffc // log(1/frcpa(1+ 55/2^-8))
+//
+data8 0xcc0b1a008d53ab76 , 0x00003ffc // log(1/frcpa(1+ 56/2^-8))
+data8 0xcfb6203844b3209b , 0x00003ffc // log(1/frcpa(1+ 57/2^-8))
+data8 0xd2c73949a47a19f5 , 0x00003ffc // log(1/frcpa(1+ 58/2^-8))
+data8 0xd5daae18b49d6695 , 0x00003ffc // log(1/frcpa(1+ 59/2^-8))
+data8 0xd8f08248cf7e8019 , 0x00003ffc // log(1/frcpa(1+ 60/2^-8))
+//
+data8 0xdca7749f1b3e540e , 0x00003ffc // log(1/frcpa(1+ 61/2^-8))
+data8 0xdfc28e033aaaf7c7 , 0x00003ffc // log(1/frcpa(1+ 62/2^-8))
+data8 0xe2e012a5f91d2f55 , 0x00003ffc // log(1/frcpa(1+ 63/2^-8))
+data8 0xe600064ed9e292a8 , 0x00003ffc // log(1/frcpa(1+ 64/2^-8))
+data8 0xe9226cce42b39f60 , 0x00003ffc // log(1/frcpa(1+ 65/2^-8))
+//
+data8 0xec4749fd97a28360 , 0x00003ffc // log(1/frcpa(1+ 66/2^-8))
+data8 0xef6ea1bf57780495 , 0x00003ffc // log(1/frcpa(1+ 67/2^-8))
+data8 0xf29877ff38809091 , 0x00003ffc // log(1/frcpa(1+ 68/2^-8))
+data8 0xf5c4d0b245cb89be , 0x00003ffc // log(1/frcpa(1+ 69/2^-8))
+data8 0xf8f3afd6fcdef3aa , 0x00003ffc // log(1/frcpa(1+ 70/2^-8))
+//
+data8 0xfc2519756be1abc7 , 0x00003ffc // log(1/frcpa(1+ 71/2^-8))
+data8 0xff59119f503e6832 , 0x00003ffc // log(1/frcpa(1+ 72/2^-8))
+data8 0x8147ce381ae0e146 , 0x00003ffd // log(1/frcpa(1+ 73/2^-8))
+data8 0x82e45f06cb1ad0f2 , 0x00003ffd // log(1/frcpa(1+ 74/2^-8))
+data8 0x842f5c7c573cbaa2 , 0x00003ffd // log(1/frcpa(1+ 75/2^-8))
+//
+data8 0x85ce471968c8893a , 0x00003ffd // log(1/frcpa(1+ 76/2^-8))
+data8 0x876e8305bc04066d , 0x00003ffd // log(1/frcpa(1+ 77/2^-8))
+data8 0x891012678031fbb3 , 0x00003ffd // log(1/frcpa(1+ 78/2^-8))
+data8 0x8a5f1493d766a05f , 0x00003ffd // log(1/frcpa(1+ 79/2^-8))
+data8 0x8c030c778c56fa00 , 0x00003ffd // log(1/frcpa(1+ 80/2^-8))
+//
+data8 0x8da85df17e31d9ae , 0x00003ffd // log(1/frcpa(1+ 81/2^-8))
+data8 0x8efa663e7921687e , 0x00003ffd // log(1/frcpa(1+ 82/2^-8))
+data8 0x90a22b6875c6a1f8 , 0x00003ffd // log(1/frcpa(1+ 83/2^-8))
+data8 0x91f62cc8f5d24837 , 0x00003ffd // log(1/frcpa(1+ 84/2^-8))
+data8 0x93a06cfc3857d980 , 0x00003ffd // log(1/frcpa(1+ 85/2^-8))
+//
+data8 0x94f66d5e6fd01ced , 0x00003ffd // log(1/frcpa(1+ 86/2^-8))
+data8 0x96a330156e6772f2 , 0x00003ffd // log(1/frcpa(1+ 87/2^-8))
+data8 0x97fb3582754ea25b , 0x00003ffd // log(1/frcpa(1+ 88/2^-8))
+data8 0x99aa8259aad1bbf2 , 0x00003ffd // log(1/frcpa(1+ 89/2^-8))
+data8 0x9b0492f6227ae4a8 , 0x00003ffd // log(1/frcpa(1+ 90/2^-8))
+//
+data8 0x9c5f8e199bf3a7a5 , 0x00003ffd // log(1/frcpa(1+ 91/2^-8))
+data8 0x9e1293b9998c1daa , 0x00003ffd // log(1/frcpa(1+ 92/2^-8))
+data8 0x9f6fa31e0b41f308 , 0x00003ffd // log(1/frcpa(1+ 93/2^-8))
+data8 0xa0cda11eaf46390e , 0x00003ffd // log(1/frcpa(1+ 94/2^-8))
+data8 0xa22c8f029cfa45aa , 0x00003ffd // log(1/frcpa(1+ 95/2^-8))
+//
+data8 0xa3e48badb7856b34 , 0x00003ffd // log(1/frcpa(1+ 96/2^-8))
+data8 0xa5459a0aa95849f9 , 0x00003ffd // log(1/frcpa(1+ 97/2^-8))
+data8 0xa6a79c84480cfebd , 0x00003ffd // log(1/frcpa(1+ 98/2^-8))
+data8 0xa80a946d0fcb3eb2 , 0x00003ffd // log(1/frcpa(1+ 99/2^-8))
+data8 0xa96e831a3ea7b314 , 0x00003ffd // log(1/frcpa(1+100/2^-8))
+//
+data8 0xaad369e3dc544e3b , 0x00003ffd // log(1/frcpa(1+101/2^-8))
+data8 0xac92e9588952c815 , 0x00003ffd // log(1/frcpa(1+102/2^-8))
+data8 0xadfa035aa1ed8fdc , 0x00003ffd // log(1/frcpa(1+103/2^-8))
+data8 0xaf6219eae1ad6e34 , 0x00003ffd // log(1/frcpa(1+104/2^-8))
+data8 0xb0cb2e6d8160f753 , 0x00003ffd // log(1/frcpa(1+105/2^-8))
+//
+data8 0xb2354249ad950f72 , 0x00003ffd // log(1/frcpa(1+106/2^-8))
+data8 0xb3a056e98ef4a3b4 , 0x00003ffd // log(1/frcpa(1+107/2^-8))
+data8 0xb50c6dba52c6292a , 0x00003ffd // log(1/frcpa(1+108/2^-8))
+data8 0xb679882c33876165 , 0x00003ffd // log(1/frcpa(1+109/2^-8))
+data8 0xb78c07429785cedc , 0x00003ffd // log(1/frcpa(1+110/2^-8))
+//
+data8 0xb8faeb8dc4a77d24 , 0x00003ffd // log(1/frcpa(1+111/2^-8))
+data8 0xba6ad77eb36ae0d6 , 0x00003ffd // log(1/frcpa(1+112/2^-8))
+data8 0xbbdbcc915e9bee50 , 0x00003ffd // log(1/frcpa(1+113/2^-8))
+data8 0xbd4dcc44f8cf12ef , 0x00003ffd // log(1/frcpa(1+114/2^-8))
+data8 0xbec0d81bf5b531fa , 0x00003ffd // log(1/frcpa(1+115/2^-8))
+//
+data8 0xc034f19c139186f4 , 0x00003ffd // log(1/frcpa(1+116/2^-8))
+data8 0xc14cb69f7c5e55ab , 0x00003ffd // log(1/frcpa(1+117/2^-8))
+data8 0xc2c2abbb6e5fd56f , 0x00003ffd // log(1/frcpa(1+118/2^-8))
+data8 0xc439b2c193e6771e , 0x00003ffd // log(1/frcpa(1+119/2^-8))
+data8 0xc553acb9d5c67733 , 0x00003ffd // log(1/frcpa(1+120/2^-8))
+//
+data8 0xc6cc96e441272441 , 0x00003ffd // log(1/frcpa(1+121/2^-8))
+data8 0xc8469753eca88c30 , 0x00003ffd // log(1/frcpa(1+122/2^-8))
+data8 0xc962cf3ce072b05c , 0x00003ffd // log(1/frcpa(1+123/2^-8))
+data8 0xcadeba8771f694aa , 0x00003ffd // log(1/frcpa(1+124/2^-8))
+data8 0xcc5bc08d1f72da94 , 0x00003ffd // log(1/frcpa(1+125/2^-8))
+//
+data8 0xcd7a3f99ea035c29 , 0x00003ffd // log(1/frcpa(1+126/2^-8))
+data8 0xcef93860c8a53c35 , 0x00003ffd // log(1/frcpa(1+127/2^-8))
+data8 0xd0192f68a7ed23df , 0x00003ffd // log(1/frcpa(1+128/2^-8))
+data8 0xd19a201127d3c645 , 0x00003ffd // log(1/frcpa(1+129/2^-8))
+data8 0xd2bb92f4061c172c , 0x00003ffd // log(1/frcpa(1+130/2^-8))
+//
+data8 0xd43e80b2ee8cc8fc , 0x00003ffd // log(1/frcpa(1+131/2^-8))
+data8 0xd56173601fc4ade4 , 0x00003ffd // log(1/frcpa(1+132/2^-8))
+data8 0xd6e6637efb54086f , 0x00003ffd // log(1/frcpa(1+133/2^-8))
+data8 0xd80ad9f58f3c8193 , 0x00003ffd // log(1/frcpa(1+134/2^-8))
+data8 0xd991d1d31aca41f8 , 0x00003ffd // log(1/frcpa(1+135/2^-8))
+//
+data8 0xdab7d02231484a93 , 0x00003ffd // log(1/frcpa(1+136/2^-8))
+data8 0xdc40d532cde49a54 , 0x00003ffd // log(1/frcpa(1+137/2^-8))
+data8 0xdd685f79ed8b265e , 0x00003ffd // log(1/frcpa(1+138/2^-8))
+data8 0xde9094bbc0e17b1d , 0x00003ffd // log(1/frcpa(1+139/2^-8))
+data8 0xe01c91b78440c425 , 0x00003ffd // log(1/frcpa(1+140/2^-8))
+//
+data8 0xe14658f26997e729 , 0x00003ffd // log(1/frcpa(1+141/2^-8))
+data8 0xe270cdc2391e0d23 , 0x00003ffd // log(1/frcpa(1+142/2^-8))
+data8 0xe3ffce3a2aa64922 , 0x00003ffd // log(1/frcpa(1+143/2^-8))
+data8 0xe52bdb274ed82887 , 0x00003ffd // log(1/frcpa(1+144/2^-8))
+data8 0xe6589852e75d7df6 , 0x00003ffd // log(1/frcpa(1+145/2^-8))
+//
+data8 0xe786068c79937a7d , 0x00003ffd // log(1/frcpa(1+146/2^-8))
+data8 0xe91903adad100911 , 0x00003ffd // log(1/frcpa(1+147/2^-8))
+data8 0xea481236f7d35bb0 , 0x00003ffd // log(1/frcpa(1+148/2^-8))
+data8 0xeb77d48c692e6b14 , 0x00003ffd // log(1/frcpa(1+149/2^-8))
+data8 0xeca84b83d7297b87 , 0x00003ffd // log(1/frcpa(1+150/2^-8))
+//
+data8 0xedd977f4962aa158 , 0x00003ffd // log(1/frcpa(1+151/2^-8))
+data8 0xef7179a22f257754 , 0x00003ffd // log(1/frcpa(1+152/2^-8))
+data8 0xf0a450d139366ca7 , 0x00003ffd // log(1/frcpa(1+153/2^-8))
+data8 0xf1d7e0524ff9ffdb , 0x00003ffd // log(1/frcpa(1+154/2^-8))
+data8 0xf30c29036a8b6cae , 0x00003ffd // log(1/frcpa(1+155/2^-8))
+//
+data8 0xf4412bc411ea8d92 , 0x00003ffd // log(1/frcpa(1+156/2^-8))
+data8 0xf576e97564c8619d , 0x00003ffd // log(1/frcpa(1+157/2^-8))
+data8 0xf6ad62fa1b5f172f , 0x00003ffd // log(1/frcpa(1+158/2^-8))
+data8 0xf7e499368b55c542 , 0x00003ffd // log(1/frcpa(1+159/2^-8))
+data8 0xf91c8d10abaffe22 , 0x00003ffd // log(1/frcpa(1+160/2^-8))
+//
+data8 0xfa553f7018c966f3 , 0x00003ffd // log(1/frcpa(1+161/2^-8))
+data8 0xfb8eb13e185d802c , 0x00003ffd // log(1/frcpa(1+162/2^-8))
+data8 0xfcc8e3659d9bcbed , 0x00003ffd // log(1/frcpa(1+163/2^-8))
+data8 0xfe03d6d34d487fd2 , 0x00003ffd // log(1/frcpa(1+164/2^-8))
+data8 0xff3f8c7581e9f0ae , 0x00003ffd // log(1/frcpa(1+165/2^-8))
+//
+data8 0x803e029e280173ae , 0x00003ffe // log(1/frcpa(1+166/2^-8))
+data8 0x80dca10cc52d0757 , 0x00003ffe // log(1/frcpa(1+167/2^-8))
+data8 0x817ba200632755a1 , 0x00003ffe // log(1/frcpa(1+168/2^-8))
+data8 0x821b05f3b01d6774 , 0x00003ffe // log(1/frcpa(1+169/2^-8))
+data8 0x82bacd623ff19d06 , 0x00003ffe // log(1/frcpa(1+170/2^-8))
+//
+data8 0x835af8c88e7a8f47 , 0x00003ffe // log(1/frcpa(1+171/2^-8))
+data8 0x83c5f8299e2b4091 , 0x00003ffe // log(1/frcpa(1+172/2^-8))
+data8 0x8466cb43f3d87300 , 0x00003ffe // log(1/frcpa(1+173/2^-8))
+data8 0x850803a67c80ca4b , 0x00003ffe // log(1/frcpa(1+174/2^-8))
+data8 0x85a9a1d11a23b461 , 0x00003ffe // log(1/frcpa(1+175/2^-8))
+//
+data8 0x864ba644a18e6e05 , 0x00003ffe // log(1/frcpa(1+176/2^-8))
+data8 0x86ee1182dcc432f7 , 0x00003ffe // log(1/frcpa(1+177/2^-8))
+data8 0x875a925d7e48c316 , 0x00003ffe // log(1/frcpa(1+178/2^-8))
+data8 0x87fdaa109d23aef7 , 0x00003ffe // log(1/frcpa(1+179/2^-8))
+data8 0x88a129ed4becfaf2 , 0x00003ffe // log(1/frcpa(1+180/2^-8))
+//
+data8 0x89451278ecd7f9cf , 0x00003ffe // log(1/frcpa(1+181/2^-8))
+data8 0x89b29295f8432617 , 0x00003ffe // log(1/frcpa(1+182/2^-8))
+data8 0x8a572ac5a5496882 , 0x00003ffe // log(1/frcpa(1+183/2^-8))
+data8 0x8afc2d0ce3b2dadf , 0x00003ffe // log(1/frcpa(1+184/2^-8))
+data8 0x8b6a69c608cfd3af , 0x00003ffe // log(1/frcpa(1+185/2^-8))
+//
+data8 0x8c101e106e899a83 , 0x00003ffe // log(1/frcpa(1+186/2^-8))
+data8 0x8cb63de258f9d626 , 0x00003ffe // log(1/frcpa(1+187/2^-8))
+data8 0x8d2539c5bd19e2b1 , 0x00003ffe // log(1/frcpa(1+188/2^-8))
+data8 0x8dcc0e064b29e6f1 , 0x00003ffe // log(1/frcpa(1+189/2^-8))
+data8 0x8e734f45d88357ae , 0x00003ffe // log(1/frcpa(1+190/2^-8))
+//
+data8 0x8ee30cef034a20db , 0x00003ffe // log(1/frcpa(1+191/2^-8))
+data8 0x8f8b0515686d1d06 , 0x00003ffe // log(1/frcpa(1+192/2^-8))
+data8 0x90336bba039bf32f , 0x00003ffe // log(1/frcpa(1+193/2^-8))
+data8 0x90a3edd23d1c9d58 , 0x00003ffe // log(1/frcpa(1+194/2^-8))
+data8 0x914d0de2f5d61b32 , 0x00003ffe // log(1/frcpa(1+195/2^-8))
+//
+data8 0x91be0c20d28173b5 , 0x00003ffe // log(1/frcpa(1+196/2^-8))
+data8 0x9267e737c06cd34a , 0x00003ffe // log(1/frcpa(1+197/2^-8))
+data8 0x92d962ae6abb1237 , 0x00003ffe // log(1/frcpa(1+198/2^-8))
+data8 0x9383fa6afbe2074c , 0x00003ffe // log(1/frcpa(1+199/2^-8))
+data8 0x942f0421651c1c4e , 0x00003ffe // log(1/frcpa(1+200/2^-8))
+//
+data8 0x94a14a3845bb985e , 0x00003ffe // log(1/frcpa(1+201/2^-8))
+data8 0x954d133857f861e7 , 0x00003ffe // log(1/frcpa(1+202/2^-8))
+data8 0x95bfd96468e604c4 , 0x00003ffe // log(1/frcpa(1+203/2^-8))
+data8 0x9632d31cafafa858 , 0x00003ffe // log(1/frcpa(1+204/2^-8))
+data8 0x96dfaabd86fa1647 , 0x00003ffe // log(1/frcpa(1+205/2^-8))
+//
+data8 0x9753261fcbb2a594 , 0x00003ffe // log(1/frcpa(1+206/2^-8))
+data8 0x9800c11b426b996d , 0x00003ffe // log(1/frcpa(1+207/2^-8))
+data8 0x9874bf4d45ae663c , 0x00003ffe // log(1/frcpa(1+208/2^-8))
+data8 0x99231f5ee9a74f79 , 0x00003ffe // log(1/frcpa(1+209/2^-8))
+data8 0x9997a18a56bcad28 , 0x00003ffe // log(1/frcpa(1+210/2^-8))
+//
+data8 0x9a46c873a3267e79 , 0x00003ffe // log(1/frcpa(1+211/2^-8))
+data8 0x9abbcfc621eb6cb6 , 0x00003ffe // log(1/frcpa(1+212/2^-8))
+data8 0x9b310cb0d354c990 , 0x00003ffe // log(1/frcpa(1+213/2^-8))
+data8 0x9be14cf9e1b3515c , 0x00003ffe // log(1/frcpa(1+214/2^-8))
+data8 0x9c5710b8cbb73a43 , 0x00003ffe // log(1/frcpa(1+215/2^-8))
+//
+data8 0x9ccd0abd301f399c , 0x00003ffe // log(1/frcpa(1+216/2^-8))
+data8 0x9d7e67f3bdce8888 , 0x00003ffe // log(1/frcpa(1+217/2^-8))
+data8 0x9df4ea81a99daa01 , 0x00003ffe // log(1/frcpa(1+218/2^-8))
+data8 0x9e6ba405a54514ba , 0x00003ffe // log(1/frcpa(1+219/2^-8))
+data8 0x9f1e21c8c7bb62b3 , 0x00003ffe // log(1/frcpa(1+220/2^-8))
+//
+data8 0x9f956593f6b6355c , 0x00003ffe // log(1/frcpa(1+221/2^-8))
+data8 0xa00ce1092e5498c3 , 0x00003ffe // log(1/frcpa(1+222/2^-8))
+data8 0xa0c08309c4b912c1 , 0x00003ffe // log(1/frcpa(1+223/2^-8))
+data8 0xa1388a8c6faa2afa , 0x00003ffe // log(1/frcpa(1+224/2^-8))
+data8 0xa1b0ca7095b5f985 , 0x00003ffe // log(1/frcpa(1+225/2^-8))
+//
+data8 0xa22942eb47534a00 , 0x00003ffe // log(1/frcpa(1+226/2^-8))
+data8 0xa2de62326449d0a3 , 0x00003ffe // log(1/frcpa(1+227/2^-8))
+data8 0xa357690f88bfe345 , 0x00003ffe // log(1/frcpa(1+228/2^-8))
+data8 0xa3d0a93f45169a4b , 0x00003ffe // log(1/frcpa(1+229/2^-8))
+data8 0xa44a22f7ffe65f30 , 0x00003ffe // log(1/frcpa(1+230/2^-8))
+//
+data8 0xa500c5e5b4c1aa36 , 0x00003ffe // log(1/frcpa(1+231/2^-8))
+data8 0xa57ad064eb2ebbc2 , 0x00003ffe // log(1/frcpa(1+232/2^-8))
+data8 0xa5f5152dedf4384e , 0x00003ffe // log(1/frcpa(1+233/2^-8))
+data8 0xa66f9478856233ec , 0x00003ffe // log(1/frcpa(1+234/2^-8))
+data8 0xa6ea4e7cca02c32e , 0x00003ffe // log(1/frcpa(1+235/2^-8))
+//
+data8 0xa765437325341ccf , 0x00003ffe // log(1/frcpa(1+236/2^-8))
+data8 0xa81e21e6c75b4020 , 0x00003ffe // log(1/frcpa(1+237/2^-8))
+data8 0xa899ab333fe2b9ca , 0x00003ffe // log(1/frcpa(1+238/2^-8))
+data8 0xa9157039c51ebe71 , 0x00003ffe // log(1/frcpa(1+239/2^-8))
+data8 0xa991713433c2b999 , 0x00003ffe // log(1/frcpa(1+240/2^-8))
+//
+data8 0xaa0dae5cbcc048b3 , 0x00003ffe // log(1/frcpa(1+241/2^-8))
+data8 0xaa8a27ede5eb13ad , 0x00003ffe // log(1/frcpa(1+242/2^-8))
+data8 0xab06de228a9e3499 , 0x00003ffe // log(1/frcpa(1+243/2^-8))
+data8 0xab83d135dc633301 , 0x00003ffe // log(1/frcpa(1+244/2^-8))
+data8 0xac3fb076adc7fe7a , 0x00003ffe // log(1/frcpa(1+245/2^-8))
+//
+data8 0xacbd3cbbe47988f1 , 0x00003ffe // log(1/frcpa(1+246/2^-8))
+data8 0xad3b06b1a5dc57c3 , 0x00003ffe // log(1/frcpa(1+247/2^-8))
+data8 0xadb90e94af887717 , 0x00003ffe // log(1/frcpa(1+248/2^-8))
+data8 0xae3754a218f7c816 , 0x00003ffe // log(1/frcpa(1+249/2^-8))
+data8 0xaeb5d9175437afa2 , 0x00003ffe // log(1/frcpa(1+250/2^-8))
+//
+data8 0xaf349c322e9c7cee , 0x00003ffe // log(1/frcpa(1+251/2^-8))
+data8 0xafb39e30d1768d1c , 0x00003ffe // log(1/frcpa(1+252/2^-8))
+data8 0xb032df51c2c93116 , 0x00003ffe // log(1/frcpa(1+253/2^-8))
+data8 0xb0b25fd3e6035ad9 , 0x00003ffe // log(1/frcpa(1+254/2^-8))
+data8 0xb1321ff67cba178c , 0x00003ffe // log(1/frcpa(1+255/2^-8))
+LOCAL_OBJECT_END(log_table_3)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(asinh)
+
+{ .mfi
+ getf.exp asinh_GR_f8 = f8 // Must recompute later if x unorm
+ fclass.m p12,p0 = f8, 0x0b // Test x unorm
+ mov log_GR_exp_17_ones = 0x1ffff
+}
+{ .mfi
+ addl NR_table_address = @ltoff(log_table_1), gp
+ fma.s1 log_y = f8, f8, f1 // y = x^2 + 1
+ mov asinh_GR_comp = 0xfffc
+}
+;;
+
+{ .mfi
+ mov log_GR_exp_16_ones = 0xffff //BIAS
+ fclass.m p6,p0 = f8, 0xe7 // Test for x = NaN and inf and zero
+ mov log_GR_comp2 = 0x1003e
+}
+{ .mfi
+ ld8 NR_table_address = [NR_table_address]
+ fma.s1 asinh_w_sq = f8,f8,f0 // x^2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.lt.s1 p7,p11 = f8,f0 // if x<0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fnorm.s1 fNormX = f8 // Normalize x
+(p12) br.cond.spnt ASINH_UNORM // Branch if x=unorm
+}
+;;
+
+ASINH_COMMON:
+// Return here if x=unorm and not denorm
+{ .mfi
+ //to get second table address
+ adds log_table_address2 = 0x40, NR_table_address
+ fma.s1 log_arg = f8,f1,f8
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p6) fma.d.s0 f8 = f8,f1,f8 // quietize nan result if x=nan
+(p6) br.ret.spnt b0 // Exit for x=nan and inf and zero
+}
+;;
+
+{ .mfi
+ ldfpd NR1,NR2 = [log_table_address2],16
+ frsqrta.s1 log_y_rs,p0 = log_y // z=1/sqrt(y)
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe log_C13 = [log_table_address2],16
+ nop.f 0
+ and asinh_GR_f8 = asinh_GR_f8,log_GR_exp_17_ones
+}
+;;
+
+{ .mib
+ ldfe log_C11 = [log_table_address2],16
+ cmp.le p13,p0 = log_GR_comp2,asinh_GR_f8
+(p13) br.cond.spnt LOG_COMMON1 // Branch if path 4, |x| >= 2^63
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter = log_y_rs,log_y,f0 // y*z
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p7,p11
+{ .mfi
+ nop.m 0
+(p11) mov asinh_f8 = fNormX
+ nop.i 0
+}
+{ .mfb
+ cmp.gt p8,p0 = asinh_GR_comp,asinh_GR_f8
+(p7) fnma.s1 asinh_f8 = fNormX,f1,f0
+(p8) br.cond.spnt ASINH_NEAR_ZERO // Branch if path 2, 0 < |x| < 2^-3
+}
+;;
+
+// Here if main path, 2^-3 <= |x| < 2^63
+///////////////////////////////// The first iteration /////////////////////////
+{ .mfi
+ ldfpd log_P5,log_P4 = [NR_table_address],16
+ fnma.s1 log_y_rs_iter = log_y_rs_iter,log_y_rs,NR2 // 3-(y*z)*z
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs,NR1,f0 // 0.5*z
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfpd log_P3,log_P2 = [NR_table_address],16
+ // (0.5*z)*(3-(y*z)*z)
+ fma.s1 log_y_rs_iter = log_y_rs_iter1,log_y_rs_iter,f0
+ nop.i 0
+}
+;;
+
+/////////////////////////// The second iteration /////////////////////////////
+{ .mfi
+ ldfd log_P1 = [NR_table_address],16
+ fma.s1 log_y_rs = log_y_rs_iter,log_y,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 log_y_rs = log_y_rs,log_y_rs_iter,NR2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs_iter,NR1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe log2 = [NR_table_address],16
+ // (0.5*z)*(3-(y*z)*z)
+ fma.s1 log_y_rs_iter = log_y_rs_iter1,log_y_rs,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (0.5*z)*(3-(y*z)*z)
+ fma.s1 log_arg_early = log_y_rs_iter1,log_y_rs,f0
+ nop.i 0
+}
+;;
+
+////////////////////////////////// The third iteration ////////////////////////
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs = log_y_rs_iter,log_y,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs_iter,NR1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_arg_early = log_arg_early,log_y,asinh_f8
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 log_y_rs = log_y_rs,log_y_rs_iter,NR2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs_iter1,log_y,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ frcpa.s1 log_C,p0 = f1,log_arg_early
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.exp log_GR_signexp_f8 = log_arg_early
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.sig log_GR_significand_f8 = log_arg_early
+ // (0.5*z)*(3-(y*z)*z)*y + |x|
+ fma.s1 log_arg = log_y_rs_iter1,log_y_rs,asinh_f8
+ //to get third table address
+ adds log_table_address3 = 0x70, NR_table_address
+}
+;;
+
+///////////////////////////////// The end NR iterations /////////////////////
+{ .mfi
+ nop.m 0
+ nop.f 0
+ //significant bit destruction
+ and log_GR_exp_f8 = log_GR_signexp_f8, log_GR_exp_17_ones
+}
+;;
+
+{ .mfi
+ //BIAS subtraction
+ sub log_GR_true_exp_f8 = log_GR_exp_f8, log_GR_exp_16_ones
+(p7) fnma.s1 log2 = log2,f1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.sig log_int_Nfloat = log_GR_true_exp_f8
+ fms.s1 log_r = log_C,log_arg,f1 // C = frcpa(x); r = C * x - 1
+ extr.u log_GR_index = log_GR_significand_f8,55,8 //Extract 8 bits
+}
+;;
+
+{ .mmi
+ //pre-index*16 + index
+ shladd log_table_address3 = log_GR_index,4,log_table_address3
+;;
+ ldfe log_T = [log_table_address3]
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rsq = log_r, log_r, f0 //r^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p4 = log_P5, log_r, log_P4 //P5*r + P4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p32 = log_P3, log_r, log_P2 //P3*r + P2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //convert N to the floating-point format
+ fcvt.xf log_Nfloat = log_int_Nfloat
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rcube = log_rsq, log_r, f0 //r^3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p10 = log_rsq, log_P1, log_r //P1*r^2 + r
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //(P5*r + P4)*r^2 + P3*r + P2
+ fma.s1 log_rp_p2 = log_rp_p4, log_rsq, log_rp_p32
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p7,p11
+{ .mfi
+ nop.m 0
+(p11) fma.s1 log_T_plus_Nlog2 = log_Nfloat,log2,log_T //N*log2 + T if x>0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fms.s1 log_T_plus_Nlog2 = log_Nfloat,log2,log_T //N*log2 - T if x<0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //((P5*r + P4)*r^2 + P3*r + P2)*w^3 + P1*r^2 + r
+ fma.s1 log_r2P_r = log_rp_p2, log_rcube, log_rp_p10
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // N*log2 + T + ((P5*r + P4)*r^2 + P3*r + P2)*r^3 + P1*r^2 + r
+(p11) fadd.d.s0 f8 = log_T_plus_Nlog2,log_r2P_r
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ // -N*log2 - T - ((P5*r + P4)*r^2 + P3*r + P2)*r^3 + P1*r^2 + r
+(p7) fsub.d.s0 f8 = log_T_plus_Nlog2,log_r2P_r
+ br.ret.sptk b0 // Exit main path, path 3: 2^-3 <= |x| < 2^63
+}
+;;
+
+// Here if path 4, |x| >= 2^63
+LOG_COMMON1:
+{ .mfi
+ ldfpd log_P5,log_P4 = [NR_table_address],16
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfpd log_P3,log_P2 = [NR_table_address],16
+ frcpa.s1 log_C,p0 = f1,log_arg
+ nop.i 0
+}
+;;
+
+{ .mmi
+ getf.exp log_GR_signexp_f8 = log_arg
+ ldfd log_P1 = [NR_table_address],16
+ nop.i 0
+}
+;;
+
+{ .mmi
+ getf.sig log_GR_significand_f8 = log_arg
+ ldfe log2 = [NR_table_address],16
+ nop.i 0
+}
+;;
+
+{ .mfi
+ adds log_table_address3 = 0x70, NR_table_address
+ nop.f 0
+ //significant bit destruction
+ and log_GR_exp_f8 = log_GR_signexp_f8, log_GR_exp_17_ones
+}
+;;
+
+{ .mmf
+ nop.m 0
+ //BIAS subtraction
+ sub log_GR_true_exp_f8 = log_GR_exp_f8, log_GR_exp_16_ones
+ fms.s1 log_r = log_C,log_arg,f1 //C = frcpa(x); r = C * x - 1
+}
+;;
+
+{ .mfi
+ setf.sig log_int_Nfloat = log_GR_true_exp_f8
+ nop.f 0
+ extr.u log_GR_index = log_GR_significand_f8,55,8 //Extract 8 bits
+}
+;;
+
+{ .mmi
+ //pre-index*16 + index
+ shladd log_table_address3 = log_GR_index,4,log_table_address3
+;;
+ ldfe log_T = [log_table_address3]
+ nop.i 0
+
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rsq = log_r, log_r, f0 //r^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p4 = log_P5, log_r, log_P4 //P5*r + P4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p32 = log_P3, log_r, log_P2 //P3*r + P2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fnma.s1 log2 = log2,f1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rcube = log_rsq, log_r, f0 //r^3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p10 = log_rsq, log_P1, log_r //P1*r^2 + r
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //convert N to the floating-point format
+ fcvt.xf log_Nfloat = log_int_Nfloat
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ //(P5*r + P4)*r^2 + P3*r + P2
+ fma.s1 log_rp_p2 = log_rp_p4, log_rsq, log_rp_p32
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p7) fnma.s1 log_T = log_T,f1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_T_plus_Nlog2 = log_Nfloat,log2,log_T //N*log2 + T
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ //((P5*r + P4)*r^2 + P3*r + P2)*w^3 + P1*r^2 + r
+ fma.s1 log_r2P_r = log_rp_p2, log_rcube, log_rp_p10
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p7,p11
+{ .mfi
+ nop.m 0
+ // N*log2 + T + ((P5*r + P4)*r^2 + P3*r + P2)*r^3 + P1*r^2 + r
+(p11) fadd.d.s0 f8 = log_T_plus_Nlog2,log_r2P_r
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ // -N*log2 - T - ((P5*r + P4)*r^2 + P3*r + P2)*r^3 + P1*r^2 + r
+(p7) fsub.d.s0 f8 = log_T_plus_Nlog2,log_r2P_r
+ br.ret.sptk b0 // Exit path 4, |x| >= 2^63
+}
+;;
+
+// Here is path 2, 0 < |x| < 2^-3
+ASINH_NEAR_ZERO:
+{ .mfi
+ ldfe log_C9 = [log_table_address2],16
+ fma.s1 asinh_w_cube = asinh_w_sq,fNormX,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe log_C7 = [log_table_address2],16
+ fma.s1 asinh_w_four = asinh_w_sq,asinh_w_sq,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe log_C5 = [log_table_address2],16
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe log_C3 = [log_table_address2],16
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 asinh_w_13 = log_C13,asinh_w_sq,log_C11
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 asinh_w_9 = log_C9,asinh_w_sq,log_C7
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 asinh_w_3 = log_C5,asinh_w_sq,log_C3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 asinh_w_seven = asinh_w_four,asinh_w_cube,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 asinh_w_7 = asinh_w_13,asinh_w_four,asinh_w_9
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 asinh_w_5 = asinh_w_3,asinh_w_cube,fNormX
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = asinh_w_7,asinh_w_seven,asinh_w_5
+ br.ret.sptk b0 // Exit path 2 (0.0 <|x| < 2^(-3))
+}
+;;
+
+ASINH_UNORM:
+// Here if x=unorm
+{ .mfi
+ getf.exp asinh_GR_f8 = fNormX // Recompute if x unorm
+ fclass.m p0,p13 = fNormX, 0x0b // Test x denorm
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fcmp.eq.s0 p14,p0 = f8, f0 // Dummy to set denormal flag
+(p13) br.cond.sptk ASINH_COMMON // Continue if x unorm and not denorm
+}
+;;
+
+.pred.rel "mutex",p7,p11
+{ .mfi
+ nop.m 0
+(p7) fma.d.s0 f8 = f8,f8,f8 // Result x+x^2 if x=-denorm
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p11) fnma.d.s0 f8 = f8,f8,f8 // Result x-x^2 if x=+denorm
+ br.ret.spnt b0 // Exit if denorm
+}
+;;
+
+GLOBAL_LIBM_END(asinh)
+
diff --git a/libc/sysdeps/ia64/fpu/s_asinhf.S b/libc/sysdeps/ia64/fpu/s_asinhf.S
new file mode 100644
index 000000000..df616deae
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_asinhf.S
@@ -0,0 +1,937 @@
+.file "asinhf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// ==============================================================
+// History
+// ==============================================================
+// 04/02/01 Initial version
+// 04/19/01 Improved speed of the paths #1,2,3,4,5
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 05/21/03 Improved performance, fixed to handle unorms
+//
+// API
+// ==============================================================
+// float asinhf(float)
+//
+// Overview of operation
+// ==============================================================
+//
+// There are 7 paths:
+// 1. x = 0.0
+// Return asinhf(x) = 0.0
+// 2. 0.0 <|x| < 2^(-5)
+// Return asinhf(x) = Pol5(x), where Pol5(x) = ((x^2)*C1 + C0)*x^3 + x
+
+// 3. 2^(-5) <= |x| < 2^51
+// Return asinhf(x) = sign(x)*(log(|x| + sqrt(x^2 + 1.0)))
+// To compute x + sqrt(x^2 + 1.0) modified Newton Raphson method is used
+// (2 iterations)
+// Algorithm description for log function see below.
+//
+// 4. 2^51 <= |x| < +INF
+// Return asinhf(x) = sign(x)*log(2*|x|)
+// Algorithm description for log function see below.
+//
+// 5. x = INF
+// Return asinhf(x) = INF
+//
+// 6. x = [S,Q]NaN
+// Return asinhf(x) = QNaN
+//
+// 7. x = denormal
+// Return asinhf(x) = x
+//
+//==============================================================
+// Algorithm Description for log(x) function
+// Below we are using the fact that inequality x - 1.0 > 2^(-6) is always
+// true for this asinh implementation
+//
+// Consider x = 2^N 1.f1 f2 f3 f4...f63
+// Log(x) = log(frcpa(x) x/frcpa(x))
+// = log(1/frcpa(x)) + log(frcpa(x) x)
+// = -log(frcpa(x)) + log(frcpa(x) x)
+//
+// frcpa(x) = 2^-N frcpa((1.f1 f2 ... f63)
+//
+// -log(frcpa(x)) = -log(C)
+// = -log(2^-N) - log(frcpa(1.f1 f2 ... f63))
+//
+// -log(frcpa(x)) = -log(C)
+// = +Nlog2 - log(frcpa(1.f1 f2 ... f63))
+//
+// -log(frcpa(x)) = -log(C)
+// = +Nlog2 + log(frcpa(1.f1 f2 ... f63))
+//
+// Log(x) = log(1/frcpa(x)) + log(frcpa(x) x)
+//
+// Log(x) = +Nlog2 + log(1./frcpa(1.f1 f2 ... f63)) + log(frcpa(x) x)
+// Log(x) = +Nlog2 - log(/frcpa(1.f1 f2 ... f63)) + log(frcpa(x) x)
+// Log(x) = +Nlog2 + T + log(frcpa(x) x)
+//
+// Log(x) = +Nlog2 + T + log(C x)
+//
+// Cx = 1 + r
+//
+// Log(x) = +Nlog2 + T + log(1+r)
+// Log(x) = +Nlog2 + T + Series( r - r^2/2 + r^3/3 - r^4/4 ....)
+//
+// 1.f1 f2 ... f8 has 256 entries.
+// They are 1 + k/2^8, k = 0 ... 255
+// These 256 values are the table entries.
+//
+// Implementation
+//==============================================================
+// C = frcpa(x)
+// r = C * x - 1
+//
+// Form rseries = r + P1*r^2 + P2*r^3 + P3*r^4
+//
+// x = f * 2*n where f is 1.f_1f_2f_3....f_63
+// Nfloat = float(n) where n is the true unbiased exponent
+// pre-index = f_1f_2....f_8
+// index = pre_index * 8
+// get the dxt table entry at index + offset = T
+//
+// result = (T + Nfloat * log(2)) + rseries
+//
+// The T table is calculated as follows
+// Form x_k = 1 + k/2^8 where k goes from 0... 255
+// y_k = frcpa(x_k)
+// log(1/y_k) in quad and round to double-extended
+//
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f9 -> f15, f32 -> f55
+
+// General registers used:
+// r14 -> r27
+
+// Predicate registers used:
+// p6 -> p14
+
+// p6 to filter out case when x = [Q,S]NaN or INF or zero
+// p7 to filter out case when x < 0.0
+// p8 to select path #2
+
+// p11 to filter out case when x >= 0
+// p12 to filter out case when x = + denormal
+// p13 to select path #4
+// p14 to filtef out case when x = - denormal
+// Assembly macros
+//==============================================================
+log_GR_exp_17_ones = r14
+log_GR_signexp_f8 = r15
+log_table_address2 = r16
+log_GR_exp_16_ones = r17
+log_GR_exp_f8 = r18
+log_GR_true_exp_f8 = r19
+log_GR_significand_f8 = r20
+log_GR_index = r21
+log_GR_comp2 = r22
+asinh_GR_f8 = r23
+asinh_GR_comp = r24
+asinh_GR_f8 = r25
+log_table_address3 = r26
+NR_table_address = r27
+
+//==============================================================
+log_y = f9
+NR1 = f10
+NR2 = f11
+log_y_rs = f12
+log_y_rs_iter = f13
+log_y_rs_iter1 = f14
+fNormX = f15
+asinh_w_sq = f32
+log_arg_early = f33
+log_y_rs_iter2 = f34
+log_P3 = f35
+log_P2 = f36
+log_P1 = f37
+log2 = f38
+log_C0 = f39
+log_C1 = f40
+asinh_f8 = f41
+log_C = f42
+log_arg = f43
+asinh_w_cube = f44
+log_int_Nfloat = f45
+log_r = f46
+log_rsq = f47
+asinh_w_1 = f48
+log_rp_p32 = f49
+log_rcube = f50
+log_rp_p10 = f51
+log_rp_p2 = f52
+log_Nfloat = f53
+log_T = f54
+log_T_plus_Nlog2 = f55
+
+// Data tables
+//==============================================================
+
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(log_table_1)
+
+data8 0xbfd0001008f39d59 // p3
+data8 0x3fd5556073e0c45a // p2
+data8 0xbfdffffffffaea15 // p1
+data8 0x3fe62e42fefa39ef // log(2)
+LOCAL_OBJECT_END(log_table_1)
+
+LOCAL_OBJECT_START(log_table_2)
+data8 0x3FE0000000000000 // 0.5
+data8 0x4008000000000000 // 3.0
+data8 0x9979C79685A5EB16, 0x00003FFB // C1 3FFB9979C79685A5EB16
+data8 0xAAAAA96F80786D62, 0x0000BFFC // C0 BFFCAAAAA96F80786D62
+LOCAL_OBJECT_END(log_table_2)
+
+LOCAL_OBJECT_START(log_table_3)
+data8 0x3F60040155D5889E //log(1/frcpa(1+ 0/256)
+data8 0x3F78121214586B54 //log(1/frcpa(1+ 1/256)
+data8 0x3F841929F96832F0 //log(1/frcpa(1+ 2/256)
+data8 0x3F8C317384C75F06 //log(1/frcpa(1+ 3/256)
+data8 0x3F91A6B91AC73386 //log(1/frcpa(1+ 4/256)
+data8 0x3F95BA9A5D9AC039 //log(1/frcpa(1+ 5/256)
+data8 0x3F99D2A8074325F4 //log(1/frcpa(1+ 6/256)
+data8 0x3F9D6B2725979802 //log(1/frcpa(1+ 7/256)
+data8 0x3FA0C58FA19DFAAA //log(1/frcpa(1+ 8/256)
+data8 0x3FA2954C78CBCE1B //log(1/frcpa(1+ 9/256)
+data8 0x3FA4A94D2DA96C56 //log(1/frcpa(1+ 10/256)
+data8 0x3FA67C94F2D4BB58 //log(1/frcpa(1+ 11/256)
+data8 0x3FA85188B630F068 //log(1/frcpa(1+ 12/256)
+data8 0x3FAA6B8ABE73AF4C //log(1/frcpa(1+ 13/256)
+data8 0x3FAC441E06F72A9E //log(1/frcpa(1+ 14/256)
+data8 0x3FAE1E6713606D07 //log(1/frcpa(1+ 15/256)
+data8 0x3FAFFA6911AB9301 //log(1/frcpa(1+ 16/256)
+data8 0x3FB0EC139C5DA601 //log(1/frcpa(1+ 17/256)
+data8 0x3FB1DBD2643D190B //log(1/frcpa(1+ 18/256)
+data8 0x3FB2CC7284FE5F1C //log(1/frcpa(1+ 19/256)
+data8 0x3FB3BDF5A7D1EE64 //log(1/frcpa(1+ 20/256)
+data8 0x3FB4B05D7AA012E0 //log(1/frcpa(1+ 21/256)
+data8 0x3FB580DB7CEB5702 //log(1/frcpa(1+ 22/256)
+data8 0x3FB674F089365A7A //log(1/frcpa(1+ 23/256)
+data8 0x3FB769EF2C6B568D //log(1/frcpa(1+ 24/256)
+data8 0x3FB85FD927506A48 //log(1/frcpa(1+ 25/256)
+data8 0x3FB9335E5D594989 //log(1/frcpa(1+ 26/256)
+data8 0x3FBA2B0220C8E5F5 //log(1/frcpa(1+ 27/256)
+data8 0x3FBB0004AC1A86AC //log(1/frcpa(1+ 28/256)
+data8 0x3FBBF968769FCA11 //log(1/frcpa(1+ 29/256)
+data8 0x3FBCCFEDBFEE13A8 //log(1/frcpa(1+ 30/256)
+data8 0x3FBDA727638446A2 //log(1/frcpa(1+ 31/256)
+data8 0x3FBEA3257FE10F7A //log(1/frcpa(1+ 32/256)
+data8 0x3FBF7BE9FEDBFDE6 //log(1/frcpa(1+ 33/256)
+data8 0x3FC02AB352FF25F4 //log(1/frcpa(1+ 34/256)
+data8 0x3FC097CE579D204D //log(1/frcpa(1+ 35/256)
+data8 0x3FC1178E8227E47C //log(1/frcpa(1+ 36/256)
+data8 0x3FC185747DBECF34 //log(1/frcpa(1+ 37/256)
+data8 0x3FC1F3B925F25D41 //log(1/frcpa(1+ 38/256)
+data8 0x3FC2625D1E6DDF57 //log(1/frcpa(1+ 39/256)
+data8 0x3FC2D1610C86813A //log(1/frcpa(1+ 40/256)
+data8 0x3FC340C59741142E //log(1/frcpa(1+ 41/256)
+data8 0x3FC3B08B6757F2A9 //log(1/frcpa(1+ 42/256)
+data8 0x3FC40DFB08378003 //log(1/frcpa(1+ 43/256)
+data8 0x3FC47E74E8CA5F7C //log(1/frcpa(1+ 44/256)
+data8 0x3FC4EF51F6466DE4 //log(1/frcpa(1+ 45/256)
+data8 0x3FC56092E02BA516 //log(1/frcpa(1+ 46/256)
+data8 0x3FC5D23857CD74D5 //log(1/frcpa(1+ 47/256)
+data8 0x3FC6313A37335D76 //log(1/frcpa(1+ 48/256)
+data8 0x3FC6A399DABBD383 //log(1/frcpa(1+ 49/256)
+data8 0x3FC70337DD3CE41B //log(1/frcpa(1+ 50/256)
+data8 0x3FC77654128F6127 //log(1/frcpa(1+ 51/256)
+data8 0x3FC7E9D82A0B022D //log(1/frcpa(1+ 52/256)
+data8 0x3FC84A6B759F512F //log(1/frcpa(1+ 53/256)
+data8 0x3FC8AB47D5F5A310 //log(1/frcpa(1+ 54/256)
+data8 0x3FC91FE49096581B //log(1/frcpa(1+ 55/256)
+data8 0x3FC981634011AA75 //log(1/frcpa(1+ 56/256)
+data8 0x3FC9F6C407089664 //log(1/frcpa(1+ 57/256)
+data8 0x3FCA58E729348F43 //log(1/frcpa(1+ 58/256)
+data8 0x3FCABB55C31693AD //log(1/frcpa(1+ 59/256)
+data8 0x3FCB1E104919EFD0 //log(1/frcpa(1+ 60/256)
+data8 0x3FCB94EE93E367CB //log(1/frcpa(1+ 61/256)
+data8 0x3FCBF851C067555F //log(1/frcpa(1+ 62/256)
+data8 0x3FCC5C0254BF23A6 //log(1/frcpa(1+ 63/256)
+data8 0x3FCCC000C9DB3C52 //log(1/frcpa(1+ 64/256)
+data8 0x3FCD244D99C85674 //log(1/frcpa(1+ 65/256)
+data8 0x3FCD88E93FB2F450 //log(1/frcpa(1+ 66/256)
+data8 0x3FCDEDD437EAEF01 //log(1/frcpa(1+ 67/256)
+data8 0x3FCE530EFFE71012 //log(1/frcpa(1+ 68/256)
+data8 0x3FCEB89A1648B971 //log(1/frcpa(1+ 69/256)
+data8 0x3FCF1E75FADF9BDE //log(1/frcpa(1+ 70/256)
+data8 0x3FCF84A32EAD7C35 //log(1/frcpa(1+ 71/256)
+data8 0x3FCFEB2233EA07CD //log(1/frcpa(1+ 72/256)
+data8 0x3FD028F9C7035C1C //log(1/frcpa(1+ 73/256)
+data8 0x3FD05C8BE0D9635A //log(1/frcpa(1+ 74/256)
+data8 0x3FD085EB8F8AE797 //log(1/frcpa(1+ 75/256)
+data8 0x3FD0B9C8E32D1911 //log(1/frcpa(1+ 76/256)
+data8 0x3FD0EDD060B78081 //log(1/frcpa(1+ 77/256)
+data8 0x3FD122024CF0063F //log(1/frcpa(1+ 78/256)
+data8 0x3FD14BE2927AECD4 //log(1/frcpa(1+ 79/256)
+data8 0x3FD180618EF18ADF //log(1/frcpa(1+ 80/256)
+data8 0x3FD1B50BBE2FC63B //log(1/frcpa(1+ 81/256)
+data8 0x3FD1DF4CC7CF242D //log(1/frcpa(1+ 82/256)
+data8 0x3FD214456D0EB8D4 //log(1/frcpa(1+ 83/256)
+data8 0x3FD23EC5991EBA49 //log(1/frcpa(1+ 84/256)
+data8 0x3FD2740D9F870AFB //log(1/frcpa(1+ 85/256)
+data8 0x3FD29ECDABCDFA04 //log(1/frcpa(1+ 86/256)
+data8 0x3FD2D46602ADCCEE //log(1/frcpa(1+ 87/256)
+data8 0x3FD2FF66B04EA9D4 //log(1/frcpa(1+ 88/256)
+data8 0x3FD335504B355A37 //log(1/frcpa(1+ 89/256)
+data8 0x3FD360925EC44F5D //log(1/frcpa(1+ 90/256)
+data8 0x3FD38BF1C3337E75 //log(1/frcpa(1+ 91/256)
+data8 0x3FD3C25277333184 //log(1/frcpa(1+ 92/256)
+data8 0x3FD3EDF463C1683E //log(1/frcpa(1+ 93/256)
+data8 0x3FD419B423D5E8C7 //log(1/frcpa(1+ 94/256)
+data8 0x3FD44591E0539F49 //log(1/frcpa(1+ 95/256)
+data8 0x3FD47C9175B6F0AD //log(1/frcpa(1+ 96/256)
+data8 0x3FD4A8B341552B09 //log(1/frcpa(1+ 97/256)
+data8 0x3FD4D4F3908901A0 //log(1/frcpa(1+ 98/256)
+data8 0x3FD501528DA1F968 //log(1/frcpa(1+ 99/256)
+data8 0x3FD52DD06347D4F6 //log(1/frcpa(1+ 100/256)
+data8 0x3FD55A6D3C7B8A8A //log(1/frcpa(1+ 101/256)
+data8 0x3FD5925D2B112A59 //log(1/frcpa(1+ 102/256)
+data8 0x3FD5BF406B543DB2 //log(1/frcpa(1+ 103/256)
+data8 0x3FD5EC433D5C35AE //log(1/frcpa(1+ 104/256)
+data8 0x3FD61965CDB02C1F //log(1/frcpa(1+ 105/256)
+data8 0x3FD646A84935B2A2 //log(1/frcpa(1+ 106/256)
+data8 0x3FD6740ADD31DE94 //log(1/frcpa(1+ 107/256)
+data8 0x3FD6A18DB74A58C5 //log(1/frcpa(1+ 108/256)
+data8 0x3FD6CF31058670EC //log(1/frcpa(1+ 109/256)
+data8 0x3FD6F180E852F0BA //log(1/frcpa(1+ 110/256)
+data8 0x3FD71F5D71B894F0 //log(1/frcpa(1+ 111/256)
+data8 0x3FD74D5AEFD66D5C //log(1/frcpa(1+ 112/256)
+data8 0x3FD77B79922BD37E //log(1/frcpa(1+ 113/256)
+data8 0x3FD7A9B9889F19E2 //log(1/frcpa(1+ 114/256)
+data8 0x3FD7D81B037EB6A6 //log(1/frcpa(1+ 115/256)
+data8 0x3FD8069E33827231 //log(1/frcpa(1+ 116/256)
+data8 0x3FD82996D3EF8BCB //log(1/frcpa(1+ 117/256)
+data8 0x3FD85855776DCBFB //log(1/frcpa(1+ 118/256)
+data8 0x3FD8873658327CCF //log(1/frcpa(1+ 119/256)
+data8 0x3FD8AA75973AB8CF //log(1/frcpa(1+ 120/256)
+data8 0x3FD8D992DC8824E5 //log(1/frcpa(1+ 121/256)
+data8 0x3FD908D2EA7D9512 //log(1/frcpa(1+ 122/256)
+data8 0x3FD92C59E79C0E56 //log(1/frcpa(1+ 123/256)
+data8 0x3FD95BD750EE3ED3 //log(1/frcpa(1+ 124/256)
+data8 0x3FD98B7811A3EE5B //log(1/frcpa(1+ 125/256)
+data8 0x3FD9AF47F33D406C //log(1/frcpa(1+ 126/256)
+data8 0x3FD9DF270C1914A8 //log(1/frcpa(1+ 127/256)
+data8 0x3FDA0325ED14FDA4 //log(1/frcpa(1+ 128/256)
+data8 0x3FDA33440224FA79 //log(1/frcpa(1+ 129/256)
+data8 0x3FDA57725E80C383 //log(1/frcpa(1+ 130/256)
+data8 0x3FDA87D0165DD199 //log(1/frcpa(1+ 131/256)
+data8 0x3FDAAC2E6C03F896 //log(1/frcpa(1+ 132/256)
+data8 0x3FDADCCC6FDF6A81 //log(1/frcpa(1+ 133/256)
+data8 0x3FDB015B3EB1E790 //log(1/frcpa(1+ 134/256)
+data8 0x3FDB323A3A635948 //log(1/frcpa(1+ 135/256)
+data8 0x3FDB56FA04462909 //log(1/frcpa(1+ 136/256)
+data8 0x3FDB881AA659BC93 //log(1/frcpa(1+ 137/256)
+data8 0x3FDBAD0BEF3DB165 //log(1/frcpa(1+ 138/256)
+data8 0x3FDBD21297781C2F //log(1/frcpa(1+ 139/256)
+data8 0x3FDC039236F08819 //log(1/frcpa(1+ 140/256)
+data8 0x3FDC28CB1E4D32FD //log(1/frcpa(1+ 141/256)
+data8 0x3FDC4E19B84723C2 //log(1/frcpa(1+ 142/256)
+data8 0x3FDC7FF9C74554C9 //log(1/frcpa(1+ 143/256)
+data8 0x3FDCA57B64E9DB05 //log(1/frcpa(1+ 144/256)
+data8 0x3FDCCB130A5CEBB0 //log(1/frcpa(1+ 145/256)
+data8 0x3FDCF0C0D18F326F //log(1/frcpa(1+ 146/256)
+data8 0x3FDD232075B5A201 //log(1/frcpa(1+ 147/256)
+data8 0x3FDD490246DEFA6B //log(1/frcpa(1+ 148/256)
+data8 0x3FDD6EFA918D25CD //log(1/frcpa(1+ 149/256)
+data8 0x3FDD9509707AE52F //log(1/frcpa(1+ 150/256)
+data8 0x3FDDBB2EFE92C554 //log(1/frcpa(1+ 151/256)
+data8 0x3FDDEE2F3445E4AF //log(1/frcpa(1+ 152/256)
+data8 0x3FDE148A1A2726CE //log(1/frcpa(1+ 153/256)
+data8 0x3FDE3AFC0A49FF40 //log(1/frcpa(1+ 154/256)
+data8 0x3FDE6185206D516E //log(1/frcpa(1+ 155/256)
+data8 0x3FDE882578823D52 //log(1/frcpa(1+ 156/256)
+data8 0x3FDEAEDD2EAC990C //log(1/frcpa(1+ 157/256)
+data8 0x3FDED5AC5F436BE3 //log(1/frcpa(1+ 158/256)
+data8 0x3FDEFC9326D16AB9 //log(1/frcpa(1+ 159/256)
+data8 0x3FDF2391A2157600 //log(1/frcpa(1+ 160/256)
+data8 0x3FDF4AA7EE03192D //log(1/frcpa(1+ 161/256)
+data8 0x3FDF71D627C30BB0 //log(1/frcpa(1+ 162/256)
+data8 0x3FDF991C6CB3B379 //log(1/frcpa(1+ 163/256)
+data8 0x3FDFC07ADA69A910 //log(1/frcpa(1+ 164/256)
+data8 0x3FDFE7F18EB03D3E //log(1/frcpa(1+ 165/256)
+data8 0x3FE007C053C5002E //log(1/frcpa(1+ 166/256)
+data8 0x3FE01B942198A5A1 //log(1/frcpa(1+ 167/256)
+data8 0x3FE02F74400C64EB //log(1/frcpa(1+ 168/256)
+data8 0x3FE04360BE7603AD //log(1/frcpa(1+ 169/256)
+data8 0x3FE05759AC47FE34 //log(1/frcpa(1+ 170/256)
+data8 0x3FE06B5F1911CF52 //log(1/frcpa(1+ 171/256)
+data8 0x3FE078BF0533C568 //log(1/frcpa(1+ 172/256)
+data8 0x3FE08CD9687E7B0E //log(1/frcpa(1+ 173/256)
+data8 0x3FE0A10074CF9019 //log(1/frcpa(1+ 174/256)
+data8 0x3FE0B5343A234477 //log(1/frcpa(1+ 175/256)
+data8 0x3FE0C974C89431CE //log(1/frcpa(1+ 176/256)
+data8 0x3FE0DDC2305B9886 //log(1/frcpa(1+ 177/256)
+data8 0x3FE0EB524BAFC918 //log(1/frcpa(1+ 178/256)
+data8 0x3FE0FFB54213A476 //log(1/frcpa(1+ 179/256)
+data8 0x3FE114253DA97D9F //log(1/frcpa(1+ 180/256)
+data8 0x3FE128A24F1D9AFF //log(1/frcpa(1+ 181/256)
+data8 0x3FE1365252BF0865 //log(1/frcpa(1+ 182/256)
+data8 0x3FE14AE558B4A92D //log(1/frcpa(1+ 183/256)
+data8 0x3FE15F85A19C765B //log(1/frcpa(1+ 184/256)
+data8 0x3FE16D4D38C119FA //log(1/frcpa(1+ 185/256)
+data8 0x3FE18203C20DD133 //log(1/frcpa(1+ 186/256)
+data8 0x3FE196C7BC4B1F3B //log(1/frcpa(1+ 187/256)
+data8 0x3FE1A4A738B7A33C //log(1/frcpa(1+ 188/256)
+data8 0x3FE1B981C0C9653D //log(1/frcpa(1+ 189/256)
+data8 0x3FE1CE69E8BB106B //log(1/frcpa(1+ 190/256)
+data8 0x3FE1DC619DE06944 //log(1/frcpa(1+ 191/256)
+data8 0x3FE1F160A2AD0DA4 //log(1/frcpa(1+ 192/256)
+data8 0x3FE2066D7740737E //log(1/frcpa(1+ 193/256)
+data8 0x3FE2147DBA47A394 //log(1/frcpa(1+ 194/256)
+data8 0x3FE229A1BC5EBAC3 //log(1/frcpa(1+ 195/256)
+data8 0x3FE237C1841A502E //log(1/frcpa(1+ 196/256)
+data8 0x3FE24CFCE6F80D9A //log(1/frcpa(1+ 197/256)
+data8 0x3FE25B2C55CD5762 //log(1/frcpa(1+ 198/256)
+data8 0x3FE2707F4D5F7C41 //log(1/frcpa(1+ 199/256)
+data8 0x3FE285E0842CA384 //log(1/frcpa(1+ 200/256)
+data8 0x3FE294294708B773 //log(1/frcpa(1+ 201/256)
+data8 0x3FE2A9A2670AFF0C //log(1/frcpa(1+ 202/256)
+data8 0x3FE2B7FB2C8D1CC1 //log(1/frcpa(1+ 203/256)
+data8 0x3FE2C65A6395F5F5 //log(1/frcpa(1+ 204/256)
+data8 0x3FE2DBF557B0DF43 //log(1/frcpa(1+ 205/256)
+data8 0x3FE2EA64C3F97655 //log(1/frcpa(1+ 206/256)
+data8 0x3FE3001823684D73 //log(1/frcpa(1+ 207/256)
+data8 0x3FE30E97E9A8B5CD //log(1/frcpa(1+ 208/256)
+data8 0x3FE32463EBDD34EA //log(1/frcpa(1+ 209/256)
+data8 0x3FE332F4314AD796 //log(1/frcpa(1+ 210/256)
+data8 0x3FE348D90E7464D0 //log(1/frcpa(1+ 211/256)
+data8 0x3FE35779F8C43D6E //log(1/frcpa(1+ 212/256)
+data8 0x3FE36621961A6A99 //log(1/frcpa(1+ 213/256)
+data8 0x3FE37C299F3C366A //log(1/frcpa(1+ 214/256)
+data8 0x3FE38AE2171976E7 //log(1/frcpa(1+ 215/256)
+data8 0x3FE399A157A603E7 //log(1/frcpa(1+ 216/256)
+data8 0x3FE3AFCCFE77B9D1 //log(1/frcpa(1+ 217/256)
+data8 0x3FE3BE9D503533B5 //log(1/frcpa(1+ 218/256)
+data8 0x3FE3CD7480B4A8A3 //log(1/frcpa(1+ 219/256)
+data8 0x3FE3E3C43918F76C //log(1/frcpa(1+ 220/256)
+data8 0x3FE3F2ACB27ED6C7 //log(1/frcpa(1+ 221/256)
+data8 0x3FE4019C2125CA93 //log(1/frcpa(1+ 222/256)
+data8 0x3FE4181061389722 //log(1/frcpa(1+ 223/256)
+data8 0x3FE42711518DF545 //log(1/frcpa(1+ 224/256)
+data8 0x3FE436194E12B6BF //log(1/frcpa(1+ 225/256)
+data8 0x3FE445285D68EA69 //log(1/frcpa(1+ 226/256)
+data8 0x3FE45BCC464C893A //log(1/frcpa(1+ 227/256)
+data8 0x3FE46AED21F117FC //log(1/frcpa(1+ 228/256)
+data8 0x3FE47A1527E8A2D3 //log(1/frcpa(1+ 229/256)
+data8 0x3FE489445EFFFCCC //log(1/frcpa(1+ 230/256)
+data8 0x3FE4A018BCB69835 //log(1/frcpa(1+ 231/256)
+data8 0x3FE4AF5A0C9D65D7 //log(1/frcpa(1+ 232/256)
+data8 0x3FE4BEA2A5BDBE87 //log(1/frcpa(1+ 233/256)
+data8 0x3FE4CDF28F10AC46 //log(1/frcpa(1+ 234/256)
+data8 0x3FE4DD49CF994058 //log(1/frcpa(1+ 235/256)
+data8 0x3FE4ECA86E64A684 //log(1/frcpa(1+ 236/256)
+data8 0x3FE503C43CD8EB68 //log(1/frcpa(1+ 237/256)
+data8 0x3FE513356667FC57 //log(1/frcpa(1+ 238/256)
+data8 0x3FE522AE0738A3D8 //log(1/frcpa(1+ 239/256)
+data8 0x3FE5322E26867857 //log(1/frcpa(1+ 240/256)
+data8 0x3FE541B5CB979809 //log(1/frcpa(1+ 241/256)
+data8 0x3FE55144FDBCBD62 //log(1/frcpa(1+ 242/256)
+data8 0x3FE560DBC45153C7 //log(1/frcpa(1+ 243/256)
+data8 0x3FE5707A26BB8C66 //log(1/frcpa(1+ 244/256)
+data8 0x3FE587F60ED5B900 //log(1/frcpa(1+ 245/256)
+data8 0x3FE597A7977C8F31 //log(1/frcpa(1+ 246/256)
+data8 0x3FE5A760D634BB8B //log(1/frcpa(1+ 247/256)
+data8 0x3FE5B721D295F10F //log(1/frcpa(1+ 248/256)
+data8 0x3FE5C6EA94431EF9 //log(1/frcpa(1+ 249/256)
+data8 0x3FE5D6BB22EA86F6 //log(1/frcpa(1+ 250/256)
+data8 0x3FE5E6938645D390 //log(1/frcpa(1+ 251/256)
+data8 0x3FE5F673C61A2ED2 //log(1/frcpa(1+ 252/256)
+data8 0x3FE6065BEA385926 //log(1/frcpa(1+ 253/256)
+data8 0x3FE6164BFA7CC06B //log(1/frcpa(1+ 254/256)
+data8 0x3FE62643FECF9743 //log(1/frcpa(1+ 255/256)
+LOCAL_OBJECT_END(log_table_3)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(asinhf)
+
+{ .mfi
+ getf.exp asinh_GR_f8 = f8 // Must recompute later if x unorm
+ fclass.m p12,p0 = f8, 0x0b // Test x unorm
+ mov log_GR_exp_17_ones = 0x1ffff
+}
+{ .mfi
+ addl NR_table_address = @ltoff(log_table_1), gp
+ fma.s1 log_y = f8, f8, f1 // y = x^2 + 1
+ mov asinh_GR_comp = 0xfffa
+}
+;;
+
+{ .mfi
+ mov log_GR_exp_16_ones = 0xffff //BIAS
+ fclass.m p6,p0 = f8, 0xe7 // Test for x = NaN and inf and zero
+ mov log_GR_comp2 = 0x10032
+}
+{ .mfi
+ ld8 NR_table_address = [NR_table_address]
+ fma.s1 asinh_w_sq = f8,f8,f0 // x^2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.lt.s1 p7,p11 = f8,f0 // if x<0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fnorm.s1 fNormX = f8 // Normalize x
+(p12) br.cond.spnt ASINH_UNORM // Branch if x=unorm
+}
+;;
+
+ASINH_COMMON:
+// Return here if x=unorm and not denorm
+{ .mfi
+ //to get second table address
+ adds log_table_address2 = 0x20, NR_table_address
+ fma.s1 log_arg = f8,f1,f8
+}
+{ .mfb
+ nop.m 0
+(p6) fma.s.s0 f8 = f8,f1,f8 // quietize nan result if x=nan
+(p6) br.ret.spnt b0 // Exit for x=nan and inf and zero
+}
+;;
+
+{ .mfi
+ ldfpd NR1,NR2 = [log_table_address2],16
+ frsqrta.s1 log_y_rs,p0 = log_y // z=1/sqrt(y)
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe log_C1 = [log_table_address2],16
+ nop.f 0
+ and asinh_GR_f8 = asinh_GR_f8,log_GR_exp_17_ones
+}
+;;
+
+{ .mib
+ ldfe log_C0 = [log_table_address2],16
+ cmp.le p13,p0 = log_GR_comp2,asinh_GR_f8
+(p13) br.cond.spnt LOG_COMMON1 // Branch if path 4: |x| >= 2^51
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter = log_y_rs,log_y,f0 // y*z
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p7,p11
+{ .mfi
+ nop.m 0
+(p11) mov asinh_f8 = fNormX
+ nop.i 0
+}
+{ .mfb
+ cmp.gt p8,p0 = asinh_GR_comp,asinh_GR_f8
+(p7) fnma.s1 asinh_f8 = fNormX,f1,f0
+(p8) br.cond.spnt ASINH_NEAR_ZERO // Branch if path 2: 0 < |x| < 2^-5
+}
+;;
+
+// Here if main path, 2^-5 <= |x| < 2^51
+///////////////////////////////// The first iteration /////////////////////////
+{ .mfi
+ ldfpd log_P3,log_P2 = [NR_table_address],16
+ fnma.s1 log_y_rs_iter2 = log_y_rs_iter,log_y_rs,NR2 // 3-(y*z)*z
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs,NR1,f0 // 0.5*z
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfpd log_P1,log2 = [NR_table_address],16
+ // (0.5*z)*(3-(y*z)*z)
+ fma.s1 log_y_rs_iter = log_y_rs_iter1,log_y_rs_iter2,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (0.5*z)*(3-(y*z)*z)
+ fma.s1 log_arg_early = log_y_rs_iter1,log_y_rs_iter2,f0
+ nop.i 0
+}
+;;
+
+////////////////////////////////// The second iteration ////////////////////////
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs = log_y_rs_iter,log_y,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs_iter,NR1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_arg_early = log_arg_early,log_y,asinh_f8
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 log_y_rs = log_y_rs,log_y_rs_iter,NR2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_y_rs_iter1 = log_y_rs_iter1,log_y,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ frcpa.s1 log_C,p0 = f1,log_arg_early
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.exp log_GR_signexp_f8 = log_arg_early
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.sig log_GR_significand_f8 = log_arg_early
+ // (0.5*z)*(3-(y*z)*z)*y + |x|
+ fma.s1 log_arg = log_y_rs_iter1,log_y_rs,asinh_f8
+ //to get third table address
+ adds log_table_address3 = 0x30, NR_table_address
+}
+;;
+
+/////////////////////////////////////////// The end NR iterations /////////////
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ //significant bit destruction
+ and log_GR_exp_f8 = log_GR_signexp_f8, log_GR_exp_17_ones
+}
+;;
+
+{ .mfi
+ //BIAS subtraction
+ sub log_GR_true_exp_f8 = log_GR_exp_f8, log_GR_exp_16_ones
+(p7) fnma.s1 log2 = log2,f1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.sig log_int_Nfloat = log_GR_true_exp_f8
+ fms.s1 log_r = log_C,log_arg,f1 //C = frcpa(x); r = C * x - 1
+ extr.u log_GR_index = log_GR_significand_f8,55,8 //Extract 8 bits
+}
+;;
+
+{ .mmi
+ //pre-index*16 + index
+ shladd log_table_address3 = log_GR_index,3,log_table_address3
+;;
+ ldfd log_T = [log_table_address3]
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rsq = log_r, log_r, f0 //r^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p32 = log_P3, log_r, log_P2 //P3*r + P2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p10 = log_P1, log_r, f1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //convert N to the floating-point format
+ fcvt.xf log_Nfloat = log_int_Nfloat
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p2 = log_rp_p32, log_rsq, log_rp_p10
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p7,p11
+{ .mfi
+ nop.m 0
+(p11) fma.s1 log_T_plus_Nlog2 = log_Nfloat,log2,log_T //N*log2 + T if x>0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fms.s1 log_T_plus_Nlog2 = log_Nfloat,log2,log_T //N*log2 - T if x<0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p11) fma.s.s0 f8 = log_rp_p2,log_r,log_T_plus_Nlog2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fnma.s.s0 f8 = log_rp_p2,log_r,log_T_plus_Nlog2
+ br.ret.sptk b0 // Exit main path, path 3: 2^-5 <= |x| < 2^51
+}
+;;
+
+
+// Here if path 4, |x| >= 2^51
+LOG_COMMON1:
+{ .mfi
+ ldfpd log_P3,log_P2 = [NR_table_address],16
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfpd log_P1,log2 = [NR_table_address],16
+ frcpa.s1 log_C,p0 = f1,log_arg
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.exp log_GR_signexp_f8 = log_arg
+ nop.f 0
+ //to get third table address
+ adds log_table_address3 = 0x30, NR_table_address
+}
+;;
+
+{ .mfi
+ getf.sig log_GR_significand_f8 = log_arg
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ //to destroy the most bit in the significant area
+ and log_GR_exp_f8 = log_GR_signexp_f8, log_GR_exp_17_ones
+}
+;;
+
+{ .mmf
+ nop.m 0
+ //BIAS subtraction
+ sub log_GR_true_exp_f8 = log_GR_exp_f8, log_GR_exp_16_ones
+ fms.s1 log_r = log_C,log_arg,f1 //C = frcpa(x); r = C * x - 1
+}
+;;
+
+{ .mfi
+ setf.sig log_int_Nfloat = log_GR_true_exp_f8
+ nop.f 0
+ extr.u log_GR_index = log_GR_significand_f8,55,8 //Extract 8 bits
+}
+;;
+
+{ .mmi
+ //pre-index*16 + index
+ shladd log_table_address3 = log_GR_index,3,log_table_address3
+;;
+ ldfd log_T = [log_table_address3]
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rsq = log_r, log_r, f0 //r^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p32 = log_P3, log_r, log_P2 //P3*r + P2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p10 = log_P1, log_r, f1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fnma.s1 log2 = log2,f1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ //convert N to the floating-point format
+ fcvt.xf log_Nfloat = log_int_Nfloat
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 log_rp_p2 = log_rp_p32, log_rsq, log_rp_p10
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p7,p11
+{ .mfi
+ nop.m 0
+(p11) fma.s1 log_T_plus_Nlog2 = log_Nfloat,log2,log_T //N*log2 + T if x>0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fms.s1 log_T_plus_Nlog2 = log_Nfloat,log2,log_T //N*log2 - T if x<0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p11) fma.s.s0 f8 = log_rp_p2,log_r,log_T_plus_Nlog2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fnma.s.s0 f8 = log_rp_p2,log_r,log_T_plus_Nlog2
+ br.ret.sptk b0 // Exit path 4, |x| >= 2^51
+}
+;;
+
+// Here if path 2, 0 < |x| < 2^-5
+ASINH_NEAR_ZERO:
+{ .mfi
+ nop.m 0
+ fma.s1 asinh_w_1 = asinh_w_sq,log_C1,log_C0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 asinh_w_cube = asinh_w_sq,fNormX,f0
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = asinh_w_1,asinh_w_cube,fNormX
+ br.ret.sptk b0 // Exit path 2, 0 < |x| < 2^-5
+}
+;;
+
+ASINH_UNORM:
+// Here if x=unorm
+{ .mfi
+ getf.exp asinh_GR_f8 = fNormX // Recompute if x unorm
+ fclass.m p0,p13 = fNormX, 0x0b // Test x denorm
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fcmp.eq.s0 p14,p0 = f8, f0 // Dummy to set denormal flag
+(p13) br.cond.sptk ASINH_COMMON // Continue if x unorm and not denorm
+}
+;;
+
+.pred.rel "mutex",p7,p11
+{ .mfi
+ nop.m 0
+(p7) fma.s.s0 f8 = f8,f8,f8 // Result x+x^2 if x=-denorm
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p11) fnma.s.s0 f8 = f8,f8,f8 // Result x-x^2 if x=+denorm
+ br.ret.spnt b0 // Exit if denorm
+}
+;;
+
+GLOBAL_LIBM_END(asinhf)
diff --git a/libc/sysdeps/ia64/fpu/s_asinhl.S b/libc/sysdeps/ia64/fpu/s_asinhl.S
new file mode 100644
index 000000000..d3a5507a3
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_asinhl.S
@@ -0,0 +1,1347 @@
+.file "asinhl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 09/04/01 Initial version
+// 09/13/01 Performance improved, symmetry problems fixed
+// 10/10/01 Performance improved, split issues removed
+// 12/11/01 Changed huges_logp to not be global
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+//
+//*********************************************************************
+//
+// API
+//==============================================================
+// long double asinhl(long double);
+//
+// Overview of operation
+//==============================================================
+//
+// There are 6 paths:
+// 1. x = 0, [S,Q]Nan or +/-INF
+// Return asinhl(x) = x + x;
+//
+// 2. x = + denormal
+// Return asinhl(x) = x - x^2;
+//
+// 3. x = - denormal
+// Return asinhl(x) = x + x^2;
+//
+// 4. 'Near 0': max denormal < |x| < 1/128
+// Return asinhl(x) = sign(x)*(x+x^3*(c3+x^2*(c5+x^2*(c7+x^2*(c9)))));
+//
+// 5. 'Huges': |x| > 2^63
+// Return asinhl(x) = sign(x)*(logl(2*x));
+//
+// 6. 'Main path': 1/128 < |x| < 2^63
+// b_hi + b_lo = x + sqrt(x^2 + 1);
+// asinhl(x) = sign(x)*(log_special(b_hi, b_lo));
+//
+// Algorithm description
+//==============================================================
+//
+// Main path algorithm
+// ( thanks to Peter Markstein for the idea of sqrt(x^2+1) computation! )
+// *************************************************************************
+//
+// There are 3 parts of x+sqrt(x^2+1) computation:
+//
+// 1) p2 = (p2_hi+p2_lo) = x^2+1 obtaining
+// ------------------------------------
+// p2_hi = x2_hi + 1, where x2_hi = x * x;
+// p2_lo = x2_lo + p1_lo, where
+// x2_lo = FMS(x*x-x2_hi),
+// p1_lo = (1 - p2_hi) + x2_hi;
+//
+// 2) g = (g_hi+g_lo) = sqrt(p2) = sqrt(p2_hi+p2_lo)
+// ----------------------------------------------
+// r = invsqrt(p2_hi) (8-bit reciprocal square root approximation);
+// g = p2_hi * r (first 8 bit-approximation of sqrt);
+//
+// h = 0.5 * r;
+// e = 0.5 - g * h;
+// g = g * e + g (second 16 bit-approximation of sqrt);
+//
+// h = h * e + h;
+// e = 0.5 - g * h;
+// g = g * e + g (third 32 bit-approximation of sqrt);
+//
+// h = h * e + h;
+// e = 0.5 - g * h;
+// g_hi = g * e + g (fourth 64 bit-approximation of sqrt);
+//
+// Remainder computation:
+// h = h * e + h;
+// d = (p2_hi - g_hi * g_hi) + p2_lo;
+// g_lo = d * h;
+//
+// 3) b = (b_hi + b_lo) = x + g, where g = (g_hi + g_lo) = sqrt(x^2+1)
+// -------------------------------------------------------------------
+// b_hi = (g_hi + x) + gl;
+// b_lo = (g_hi - b_hi) + x + gl;
+//
+// Now we pass b presented as sum b_hi + b_lo to special version
+// of logl function which accept a pair of arguments as
+// 'mutiprecision' value.
+//
+// Special log algorithm overview
+// ================================
+// Here we use a table lookup method. The basic idea is that in
+// order to compute logl(Arg) = logl (Arg-1) for an argument Arg in [1,2),
+// we construct a value G such that G*Arg is close to 1 and that
+// logl(1/G) is obtainable easily from a table of values calculated
+// beforehand. Thus
+//
+// logl(Arg) = logl(1/G) + logl((G*Arg - 1))
+//
+// Because |G*Arg - 1| is small, the second term on the right hand
+// side can be approximated by a short polynomial. We elaborate
+// this method in four steps.
+//
+// Step 0: Initialization
+//
+// We need to calculate logl( X ). Obtain N, S_hi such that
+//
+// X = 2^N * ( S_hi + S_lo ) exactly
+//
+// where S_hi in [1,2) and S_lo is a correction to S_hi in the sense
+// that |S_lo| <= ulp(S_hi).
+//
+// For the special version of logl: S_lo = b_lo
+// !-----------------------------------------------!
+//
+// Step 1: Argument Reduction
+//
+// Based on S_hi, obtain G_1, G_2, G_3 from a table and calculate
+//
+// G := G_1 * G_2 * G_3
+// r := (G * S_hi - 1) + G * S_lo
+//
+// These G_j's have the property that the product is exactly
+// representable and that |r| < 2^(-12) as a result.
+//
+// Step 2: Approximation
+//
+// logl(1 + r) is approximated by a short polynomial poly(r).
+//
+// Step 3: Reconstruction
+//
+// Finally,
+//
+// logl( X ) = logl( 2^N * (S_hi + S_lo) )
+// ~=~ N*logl(2) + logl(1/G) + logl(1 + r)
+// ~=~ N*logl(2) + logl(1/G) + poly(r).
+//
+// For detailed description see logl or log1pl function, regular path.
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f32 -> f101 (70 registers)
+
+// General registers used:
+// r32 -> r57 (26 registers)
+
+// Predicate registers used:
+// p6 -> p11
+// p6 for '0, NaNs, Inf' path
+// p7 for '+ denormals' path
+// p8 for 'near 0' path
+// p9 for 'huges' path
+// p10 for '- denormals' path
+// p11 for negative values
+//
+// Data tables
+//==============================================================
+
+RODATA
+.align 64
+
+// C7, C9 'near 0' polynomial coefficients
+LOCAL_OBJECT_START(Poly_C_near_0_79)
+data8 0xF8DC939BBEDD5A54, 0x00003FF9
+data8 0xB6DB6DAB21565AC5, 0x0000BFFA
+LOCAL_OBJECT_END(Poly_C_near_0_79)
+
+// C3, C5 'near 0' polynomial coefficients
+LOCAL_OBJECT_START(Poly_C_near_0_35)
+data8 0x999999999991D582, 0x00003FFB
+data8 0xAAAAAAAAAAAAAAA9, 0x0000BFFC
+LOCAL_OBJECT_END(Poly_C_near_0_35)
+
+// Q coeffs
+LOCAL_OBJECT_START(Constants_Q)
+data4 0x00000000,0xB1721800,0x00003FFE,0x00000000
+data4 0x4361C4C6,0x82E30865,0x0000BFE2,0x00000000
+data4 0x328833CB,0xCCCCCAF2,0x00003FFC,0x00000000
+data4 0xA9D4BAFB,0x80000077,0x0000BFFD,0x00000000
+data4 0xAAABE3D2,0xAAAAAAAA,0x00003FFD,0x00000000
+data4 0xFFFFDAB7,0xFFFFFFFF,0x0000BFFD,0x00000000
+LOCAL_OBJECT_END(Constants_Q)
+
+// Z1 - 16 bit fixed
+LOCAL_OBJECT_START(Constants_Z_1)
+data4 0x00008000
+data4 0x00007879
+data4 0x000071C8
+data4 0x00006BCB
+data4 0x00006667
+data4 0x00006187
+data4 0x00005D18
+data4 0x0000590C
+data4 0x00005556
+data4 0x000051EC
+data4 0x00004EC5
+data4 0x00004BDB
+data4 0x00004925
+data4 0x0000469F
+data4 0x00004445
+data4 0x00004211
+LOCAL_OBJECT_END(Constants_Z_1)
+
+// G1 and H1 - IEEE single and h1 - IEEE double
+LOCAL_OBJECT_START(Constants_G_H_h1)
+data4 0x3F800000,0x00000000
+data8 0x0000000000000000
+data4 0x3F70F0F0,0x3D785196
+data8 0x3DA163A6617D741C
+data4 0x3F638E38,0x3DF13843
+data8 0x3E2C55E6CBD3D5BB
+data4 0x3F579430,0x3E2FF9A0
+data8 0xBE3EB0BFD86EA5E7
+data4 0x3F4CCCC8,0x3E647FD6
+data8 0x3E2E6A8C86B12760
+data4 0x3F430C30,0x3E8B3AE7
+data8 0x3E47574C5C0739BA
+data4 0x3F3A2E88,0x3EA30C68
+data8 0x3E20E30F13E8AF2F
+data4 0x3F321640,0x3EB9CEC8
+data8 0xBE42885BF2C630BD
+data4 0x3F2AAAA8,0x3ECF9927
+data8 0x3E497F3497E577C6
+data4 0x3F23D708,0x3EE47FC5
+data8 0x3E3E6A6EA6B0A5AB
+data4 0x3F1D89D8,0x3EF8947D
+data8 0xBDF43E3CD328D9BE
+data4 0x3F17B420,0x3F05F3A1
+data8 0x3E4094C30ADB090A
+data4 0x3F124920,0x3F0F4303
+data8 0xBE28FBB2FC1FE510
+data4 0x3F0D3DC8,0x3F183EBF
+data8 0x3E3A789510FDE3FA
+data4 0x3F088888,0x3F20EC80
+data8 0x3E508CE57CC8C98F
+data4 0x3F042108,0x3F29516A
+data8 0xBE534874A223106C
+LOCAL_OBJECT_END(Constants_G_H_h1)
+
+// Z2 - 16 bit fixed
+LOCAL_OBJECT_START(Constants_Z_2)
+data4 0x00008000
+data4 0x00007F81
+data4 0x00007F02
+data4 0x00007E85
+data4 0x00007E08
+data4 0x00007D8D
+data4 0x00007D12
+data4 0x00007C98
+data4 0x00007C20
+data4 0x00007BA8
+data4 0x00007B31
+data4 0x00007ABB
+data4 0x00007A45
+data4 0x000079D1
+data4 0x0000795D
+data4 0x000078EB
+LOCAL_OBJECT_END(Constants_Z_2)
+
+// G2 and H2 - IEEE single and h2 - IEEE double
+LOCAL_OBJECT_START(Constants_G_H_h2)
+data4 0x3F800000,0x00000000
+data8 0x0000000000000000
+data4 0x3F7F00F8,0x3B7F875D
+data8 0x3DB5A11622C42273
+data4 0x3F7E03F8,0x3BFF015B
+data8 0x3DE620CF21F86ED3
+data4 0x3F7D08E0,0x3C3EE393
+data8 0xBDAFA07E484F34ED
+data4 0x3F7C0FC0,0x3C7E0586
+data8 0xBDFE07F03860BCF6
+data4 0x3F7B1880,0x3C9E75D2
+data8 0x3DEA370FA78093D6
+data4 0x3F7A2328,0x3CBDC97A
+data8 0x3DFF579172A753D0
+data4 0x3F792FB0,0x3CDCFE47
+data8 0x3DFEBE6CA7EF896B
+data4 0x3F783E08,0x3CFC15D0
+data8 0x3E0CF156409ECB43
+data4 0x3F774E38,0x3D0D874D
+data8 0xBE0B6F97FFEF71DF
+data4 0x3F766038,0x3D1CF49B
+data8 0xBE0804835D59EEE8
+data4 0x3F757400,0x3D2C531D
+data8 0x3E1F91E9A9192A74
+data4 0x3F748988,0x3D3BA322
+data8 0xBE139A06BF72A8CD
+data4 0x3F73A0D0,0x3D4AE46F
+data8 0x3E1D9202F8FBA6CF
+data4 0x3F72B9D0,0x3D5A1756
+data8 0xBE1DCCC4BA796223
+data4 0x3F71D488,0x3D693B9D
+data8 0xBE049391B6B7C239
+LOCAL_OBJECT_END(Constants_G_H_h2)
+
+// G3 and H3 - IEEE single and h3 - IEEE double
+LOCAL_OBJECT_START(Constants_G_H_h3)
+data4 0x3F7FFC00,0x38800100
+data8 0x3D355595562224CD
+data4 0x3F7FF400,0x39400480
+data8 0x3D8200A206136FF6
+data4 0x3F7FEC00,0x39A00640
+data8 0x3DA4D68DE8DE9AF0
+data4 0x3F7FE400,0x39E00C41
+data8 0xBD8B4291B10238DC
+data4 0x3F7FDC00,0x3A100A21
+data8 0xBD89CCB83B1952CA
+data4 0x3F7FD400,0x3A300F22
+data8 0xBDB107071DC46826
+data4 0x3F7FCC08,0x3A4FF51C
+data8 0x3DB6FCB9F43307DB
+data4 0x3F7FC408,0x3A6FFC1D
+data8 0xBD9B7C4762DC7872
+data4 0x3F7FBC10,0x3A87F20B
+data8 0xBDC3725E3F89154A
+data4 0x3F7FB410,0x3A97F68B
+data8 0xBD93519D62B9D392
+data4 0x3F7FAC18,0x3AA7EB86
+data8 0x3DC184410F21BD9D
+data4 0x3F7FA420,0x3AB7E101
+data8 0xBDA64B952245E0A6
+data4 0x3F7F9C20,0x3AC7E701
+data8 0x3DB4B0ECAABB34B8
+data4 0x3F7F9428,0x3AD7DD7B
+data8 0x3D9923376DC40A7E
+data4 0x3F7F8C30,0x3AE7D474
+data8 0x3DC6E17B4F2083D3
+data4 0x3F7F8438,0x3AF7CBED
+data8 0x3DAE314B811D4394
+data4 0x3F7F7C40,0x3B03E1F3
+data8 0xBDD46F21B08F2DB1
+data4 0x3F7F7448,0x3B0BDE2F
+data8 0xBDDC30A46D34522B
+data4 0x3F7F6C50,0x3B13DAAA
+data8 0x3DCB0070B1F473DB
+data4 0x3F7F6458,0x3B1BD766
+data8 0xBDD65DDC6AD282FD
+data4 0x3F7F5C68,0x3B23CC5C
+data8 0xBDCDAB83F153761A
+data4 0x3F7F5470,0x3B2BC997
+data8 0xBDDADA40341D0F8F
+data4 0x3F7F4C78,0x3B33C711
+data8 0x3DCD1BD7EBC394E8
+data4 0x3F7F4488,0x3B3BBCC6
+data8 0xBDC3532B52E3E695
+data4 0x3F7F3C90,0x3B43BAC0
+data8 0xBDA3961EE846B3DE
+data4 0x3F7F34A0,0x3B4BB0F4
+data8 0xBDDADF06785778D4
+data4 0x3F7F2CA8,0x3B53AF6D
+data8 0x3DCC3ED1E55CE212
+data4 0x3F7F24B8,0x3B5BA620
+data8 0xBDBA31039E382C15
+data4 0x3F7F1CC8,0x3B639D12
+data8 0x3D635A0B5C5AF197
+data4 0x3F7F14D8,0x3B6B9444
+data8 0xBDDCCB1971D34EFC
+data4 0x3F7F0CE0,0x3B7393BC
+data8 0x3DC7450252CD7ADA
+data4 0x3F7F04F0,0x3B7B8B6D
+data8 0xBDB68F177D7F2A42
+LOCAL_OBJECT_END(Constants_G_H_h3)
+
+// Assembly macros
+//==============================================================
+
+// Floating Point Registers
+
+FR_Arg = f8
+FR_Res = f8
+FR_AX = f32
+FR_XLog_Hi = f33
+FR_XLog_Lo = f34
+
+ // Special logl registers
+FR_Y_hi = f35
+FR_Y_lo = f36
+
+FR_Scale = f37
+FR_X_Prime = f38
+FR_S_hi = f39
+FR_W = f40
+FR_G = f41
+
+FR_H = f42
+FR_wsq = f43
+FR_w4 = f44
+FR_h = f45
+FR_w6 = f46
+
+FR_G2 = f47
+FR_H2 = f48
+FR_poly_lo = f49
+FR_P8 = f50
+FR_poly_hi = f51
+
+FR_P7 = f52
+FR_h2 = f53
+FR_rsq = f54
+FR_P6 = f55
+FR_r = f56
+
+FR_log2_hi = f57
+FR_log2_lo = f58
+
+FR_float_N = f59
+FR_Q4 = f60
+
+FR_G3 = f61
+FR_H3 = f62
+FR_h3 = f63
+
+FR_Q3 = f64
+FR_Q2 = f65
+FR_1LN10_hi = f66
+
+FR_Q1 = f67
+FR_1LN10_lo = f68
+FR_P5 = f69
+FR_rcub = f70
+
+FR_Neg_One = f71
+FR_Z = f72
+FR_AA = f73
+FR_BB = f74
+FR_S_lo = f75
+FR_2_to_minus_N = f76
+
+
+ // Huge & Main path prolog registers
+FR_Half = f77
+FR_Two = f78
+FR_X2 = f79
+FR_P2 = f80
+FR_P2L = f81
+FR_Rcp = f82
+FR_GG = f83
+FR_HH = f84
+FR_EE = f85
+FR_DD = f86
+FR_GL = f87
+FR_A = f88
+FR_AL = f89
+FR_B = f90
+FR_BL = f91
+FR_Tmp = f92
+
+ // Near 0 & Huges path prolog registers
+FR_C3 = f93
+FR_C5 = f94
+FR_C7 = f95
+FR_C9 = f96
+
+FR_X3 = f97
+FR_X4 = f98
+FR_P9 = f99
+FR_P5 = f100
+FR_P3 = f101
+
+
+// General Purpose Registers
+
+ // General prolog registers
+GR_PFS = r32
+GR_TwoN7 = r40
+GR_TwoP63 = r41
+GR_ExpMask = r42
+GR_ArgExp = r43
+GR_Half = r44
+
+ // Near 0 path prolog registers
+GR_Poly_C_35 = r45
+GR_Poly_C_79 = r46
+
+ // Special logl registers
+GR_Index1 = r34
+GR_Index2 = r35
+GR_signif = r36
+GR_X_0 = r37
+GR_X_1 = r38
+GR_X_2 = r39
+GR_Z_1 = r40
+GR_Z_2 = r41
+GR_N = r42
+GR_Bias = r43
+GR_M = r44
+GR_Index3 = r45
+GR_exp_2tom80 = r45
+GR_exp_mask = r47
+GR_exp_2tom7 = r48
+GR_ad_ln10 = r49
+GR_ad_tbl_1 = r50
+GR_ad_tbl_2 = r51
+GR_ad_tbl_3 = r52
+GR_ad_q = r53
+GR_ad_z_1 = r54
+GR_ad_z_2 = r55
+GR_ad_z_3 = r56
+GR_minus_N = r57
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(asinhl)
+
+{ .mfi
+ alloc GR_PFS = ar.pfs,0,27,0,0
+ fma.s1 FR_P2 = FR_Arg, FR_Arg, f1 // p2 = x^2 + 1
+ mov GR_Half = 0xfffe // 0.5's exp
+}
+{ .mfi
+ addl GR_Poly_C_79 = @ltoff(Poly_C_near_0_79), gp // C7, C9 coeffs
+ fma.s1 FR_X2 = FR_Arg, FR_Arg, f0 // Obtain x^2
+ addl GR_Poly_C_35 = @ltoff(Poly_C_near_0_35), gp // C3, C5 coeffs
+};;
+
+{ .mfi
+ getf.exp GR_ArgExp = FR_Arg // get arument's exponent
+ fabs FR_AX = FR_Arg // absolute value of argument
+ mov GR_TwoN7 = 0xfff8 // 2^-7 exp
+}
+{ .mfi
+ ld8 GR_Poly_C_79 = [GR_Poly_C_79] // get actual coeff table address
+ fma.s0 FR_Two = f1, f1, f1 // construct 2.0
+ mov GR_ExpMask = 0x1ffff // mask for exp
+};;
+
+{ .mfi
+ ld8 GR_Poly_C_35 = [GR_Poly_C_35] // get actual coeff table address
+ fclass.m p6,p0 = FR_Arg, 0xe7 // if arg NaN inf zero
+ mov GR_TwoP63 = 0x1003e // 2^63 exp
+}
+{ .mfi
+ addl GR_ad_z_1 = @ltoff(Constants_Z_1#),gp
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ setf.exp FR_Half = GR_Half // construct 0.5
+ fclass.m p7,p0 = FR_Arg, 0x09 // if arg + denorm
+ and GR_ArgExp = GR_ExpMask, GR_ArgExp // select exp
+}
+{ .mfb
+ ld8 GR_ad_z_1 = [GR_ad_z_1] // Get pointer to Constants_Z_1
+ nop.f 0
+ nop.b 0
+};;
+{ .mfi
+ ldfe FR_C9 = [GR_Poly_C_79],16 // load C9
+ fclass.m p10,p0 = FR_Arg, 0x0a // if arg - denorm
+ cmp.gt p8, p0 = GR_TwoN7, GR_ArgExp // if arg < 2^-7 ('near 0')
+}
+{ .mfb
+ cmp.le p9, p0 = GR_TwoP63, GR_ArgExp // if arg > 2^63 ('huges')
+(p6) fma.s0 FR_Res = FR_Arg,f1,FR_Arg // r = a + a
+(p6) br.ret.spnt b0 // return
+};;
+// (X^2 + 1) computation
+{ .mfi
+(p8) ldfe FR_C5 = [GR_Poly_C_35],16 // load C5
+ fms.s1 FR_Tmp = f1, f1, FR_P2 // Tmp = 1 - p2
+ add GR_ad_tbl_1 = 0x040, GR_ad_z_1 // Point to Constants_G_H_h1
+}
+{ .mfb
+(p8) ldfe FR_C7 = [GR_Poly_C_79],16 // load C7
+(p7) fnma.s0 FR_Res = FR_Arg,FR_Arg,FR_Arg // r = a - a*a
+(p7) br.ret.spnt b0 // return
+};;
+
+{ .mfi
+(p8) ldfe FR_C3 = [GR_Poly_C_35],16 // load C3
+ fcmp.lt.s1 p11, p12 = FR_Arg, f0 // if arg is negative
+ add GR_ad_q = -0x60, GR_ad_z_1 // Point to Constants_P
+}
+{ .mfb
+ add GR_ad_z_2 = 0x140, GR_ad_z_1 // Point to Constants_Z_2
+(p10) fma.s0 FR_Res = FR_Arg,FR_Arg,FR_Arg // r = a + a*a
+(p10) br.ret.spnt b0 // return
+};;
+
+{ .mfi
+ add GR_ad_tbl_2 = 0x180, GR_ad_z_1 // Point to Constants_G_H_h2
+ frsqrta.s1 FR_Rcp, p0 = FR_P2 // Rcp = 1/p2 reciprocal appr.
+ add GR_ad_tbl_3 = 0x280, GR_ad_z_1 // Point to Constants_G_H_h3
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_P2L = FR_AX, FR_AX, FR_X2 //low part of p2=fma(X*X-p2)
+ mov GR_Bias = 0x0FFFF // Create exponent bias
+};;
+
+{ .mfb
+ nop.m 0
+(p9) fms.s1 FR_XLog_Hi = FR_Two, FR_AX, f0 // Hi of log1p arg = 2*X - 1
+(p9) br.cond.spnt huges_logl // special version of log1p
+};;
+
+{ .mfb
+ ldfe FR_log2_hi = [GR_ad_q],16 // Load log2_hi
+(p8) fma.s1 FR_X3 = FR_X2, FR_Arg, f0 // x^3 = x^2 * x
+(p8) br.cond.spnt near_0 // Go to near 0 branch
+};;
+
+{ .mfi
+ ldfe FR_log2_lo = [GR_ad_q],16 // Load log2_lo
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_Q4 = [GR_ad_q],16 // Load Q4
+ fma.s1 FR_Tmp = FR_Tmp, f1, FR_X2 // Tmp = Tmp + x^2
+ mov GR_exp_mask = 0x1FFFF // Create exponent mask
+};;
+
+{ .mfi
+ ldfe FR_Q3 = [GR_ad_q],16 // Load Q3
+ fma.s1 FR_GG = FR_Rcp, FR_P2, f0 // g = Rcp * p2
+ // 8 bit Newton Raphson iteration
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_Half, FR_Rcp, f0 // h = 0.5 * Rcp
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_Q2 = [GR_ad_q],16 // Load Q2
+ fnma.s1 FR_EE = FR_GG, FR_HH, FR_Half // e = 0.5 - g * h
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P2L = FR_Tmp, f1, FR_P2L // low part of p2 = Tmp + p2l
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_Q1 = [GR_ad_q] // Load Q1
+ fma.s1 FR_GG = FR_GG, FR_EE, FR_GG // g = g * e + g
+ // 16 bit Newton Raphson iteration
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_HH, FR_EE, FR_HH // h = h * e + h
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_EE = FR_GG, FR_HH, FR_Half // e = 0.5 - g * h
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_GG = FR_GG, FR_EE, FR_GG // g = g * e + g
+ // 32 bit Newton Raphson iteration
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_HH, FR_EE, FR_HH // h = h * e + h
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_EE = FR_GG, FR_HH, FR_Half // e = 0.5 - g * h
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_GG = FR_GG, FR_EE, FR_GG // g = g * e + g
+ // 64 bit Newton Raphson iteration
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_HH = FR_HH, FR_EE, FR_HH // h = h * e + h
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_DD = FR_GG, FR_GG, FR_P2 // Remainder d = g * g - p2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_XLog_Hi = FR_AX, f1, FR_GG // bh = z + gh
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_DD = FR_DD, f1, FR_P2L // add p2l: d = d + p2l
+ nop.i 0
+};;
+
+
+{ .mfi
+ getf.sig GR_signif = FR_XLog_Hi // Get significand of x+1
+ fmerge.ns FR_Neg_One = f1, f1 // Form -1.0
+ mov GR_exp_2tom7 = 0x0fff8 // Exponent of 2^-7
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_GL = FR_DD, FR_HH, f0 // gl = d * h
+ extr.u GR_Index1 = GR_signif, 59, 4 // Get high 4 bits of signif
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_XLog_Hi = FR_DD, FR_HH, FR_XLog_Hi // bh = bh + gl
+ nop.i 0
+};;
+
+{ .mmi
+ shladd GR_ad_z_1 = GR_Index1, 2, GR_ad_z_1 // Point to Z_1
+ shladd GR_ad_tbl_1 = GR_Index1, 4, GR_ad_tbl_1 // Point to G_1
+ extr.u GR_X_0 = GR_signif, 49, 15 // Get high 15 bits of signif.
+};;
+
+{ .mmi
+ ld4 GR_Z_1 = [GR_ad_z_1] // Load Z_1
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfps FR_G, FR_H = [GR_ad_tbl_1],8 // Load G_1, H_1
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_XLog_Lo = FR_GG, f1, FR_XLog_Hi // bl = gh - bh
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15 // Get bits 30-15 of X_0 * Z_1
+};;
+
+// WE CANNOT USE GR_X_1 IN NEXT 3 CYCLES BECAUSE OF POSSIBLE 10 CLOCKS STALL!
+// "DEAD" ZONE!
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmerge.se FR_S_hi = f1,FR_XLog_Hi // Form |x+1|
+ nop.i 0
+};;
+
+{ .mmi
+ getf.exp GR_N = FR_XLog_Hi // Get N = exponent of x+1
+ ldfd FR_h = [GR_ad_tbl_1] // Load h_1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract bits 6-9 of X_1
+};;
+
+
+{ .mfi
+ shladd GR_ad_tbl_2 = GR_Index2, 4, GR_ad_tbl_2 // Point to G_2
+ fma.s1 FR_XLog_Lo = FR_XLog_Lo, f1, FR_AX // bl = bl + x
+ mov GR_exp_2tom80 = 0x0ffaf // Exponent of 2^-80
+}
+{ .mfi
+ shladd GR_ad_z_2 = GR_Index2, 2, GR_ad_z_2 // Point to Z_2
+ nop.f 0
+ sub GR_N = GR_N, GR_Bias // sub bias from exp
+};;
+
+{ .mmi
+ ldfps FR_G2, FR_H2 = [GR_ad_tbl_2],8 // Load G_2, H_2
+ ld4 GR_Z_2 = [GR_ad_z_2] // Load Z_2
+ sub GR_minus_N = GR_Bias, GR_N // Form exponent of 2^(-N)
+};;
+
+{ .mmi
+ ldfd FR_h2 = [GR_ad_tbl_2] // Load h_2
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ setf.sig FR_float_N = GR_N // Put integer N into rightmost sign
+ setf.exp FR_2_to_minus_N = GR_minus_N // Form 2^(-N)
+ pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15 // Get bits 30-15 of X_1 * Z_2
+};;
+
+// WE CANNOT USE GR_X_2 IN NEXT 3 CYCLES ("DEAD" ZONE!)
+// BECAUSE OF POSSIBLE 10 CLOCKS STALL!
+// So we can negate Q coefficients there for negative values
+
+{ .mfi
+ nop.m 0
+(p11) fma.s1 FR_Q1 = FR_Q1, FR_Neg_One, f0 // Negate Q1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_XLog_Lo = FR_XLog_Lo, f1, FR_GL // bl = bl + gl
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p11) fma.s1 FR_Q2 = FR_Q2, FR_Neg_One, f0 // Negate Q2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p11) fma.s1 FR_Q3 = FR_Q3, FR_Neg_One, f0 // Negate Q3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p11) fma.s1 FR_Q4 = FR_Q4, FR_Neg_One, f0 // Negate Q4
+ extr.u GR_Index3 = GR_X_2, 1, 5 // Extract bits 1-5 of X_2
+};;
+
+{ .mfi
+ shladd GR_ad_tbl_3 = GR_Index3, 4, GR_ad_tbl_3 // Point to G_3
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfps FR_G3, FR_H3 = [GR_ad_tbl_3],8 // Load G_3, H_3
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfd FR_h3 = [GR_ad_tbl_3] // Load h_3
+ fcvt.xf FR_float_N = FR_float_N
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_G = FR_G, FR_G2 // G = G_1 * G_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H2 // H = H_1 + H_2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_h = FR_h, FR_h2 // h = h_1 + h_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S_lo = FR_XLog_Lo, FR_2_to_minus_N, f0 //S_lo=S_lo*2^-N
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_G = FR_G, FR_G3 // G = (G_1 * G_2) * G_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H3 // H = (H_1 + H_2) + H_3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_h = FR_h, FR_h3 // h = (h_1 + h_2) + h_3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r = FR_G, FR_S_hi, f1 // r = G * S_hi - 1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Y_hi = FR_float_N, FR_log2_hi, FR_H // Y_hi=N*log2_hi+H
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_h = FR_float_N, FR_log2_lo, FR_h // h=N*log2_lo+h
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r = FR_G, FR_S_lo, FR_r // r=G*S_lo+(G*S_hi-1)
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_lo = FR_r, FR_Q4, FR_Q3 // poly_lo = r * Q4 + Q3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_r, FR_Q2 // poly_lo=poly_lo*r+Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rcub = FR_rsq, FR_r, f0 // rcub = r^3
+ nop.i 0
+};;
+
+.pred.rel "mutex",p12,p11
+{ .mfi
+ nop.m 0
+(p12) fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r // poly_hi = Q1*rsq + r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fms.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r // poly_hi = Q1*rsq + r
+ nop.i 0
+};;
+
+
+.pred.rel "mutex",p12,p11
+{ .mfi
+ nop.m 0
+(p12) fma.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h//poly_lo=poly_lo*r^3+h
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fms.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h//poly_lo=poly_lo*r^3+h
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fadd.s0 FR_Y_lo = FR_poly_hi, FR_poly_lo
+ // Y_lo=poly_hi+poly_lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fma.s0 FR_Y_hi = FR_Y_hi, FR_Neg_One, f0 // FR_Y_hi sign for neg
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ fadd.s0 FR_Res = FR_Y_lo,FR_Y_hi // Result=Y_lo+Y_hi
+ br.ret.sptk b0 // Common exit for 2^-7 < x < inf
+};;
+
+// * SPECIAL VERSION OF LOGL FOR HUGE ARGUMENTS *
+
+huges_logl:
+{ .mfi
+ getf.sig GR_signif = FR_XLog_Hi // Get significand of x+1
+ fmerge.ns FR_Neg_One = f1, f1 // Form -1.0
+ mov GR_exp_2tom7 = 0x0fff8 // Exponent of 2^-7
+};;
+
+{ .mfi
+ add GR_ad_tbl_1 = 0x040, GR_ad_z_1 // Point to Constants_G_H_h1
+ nop.f 0
+ add GR_ad_q = -0x60, GR_ad_z_1 // Point to Constants_P
+}
+{ .mfi
+ add GR_ad_z_2 = 0x140, GR_ad_z_1 // Point to Constants_Z_2
+ nop.f 0
+ add GR_ad_tbl_2 = 0x180, GR_ad_z_1 // Point to Constants_G_H_h2
+};;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ extr.u GR_Index1 = GR_signif, 59, 4 // Get high 4 bits of signif
+}
+{ .mfi
+ add GR_ad_tbl_3 = 0x280, GR_ad_z_1 // Point to Constants_G_H_h3
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ shladd GR_ad_z_1 = GR_Index1, 2, GR_ad_z_1 // Point to Z_1
+ nop.f 0
+ extr.u GR_X_0 = GR_signif, 49, 15 // Get high 15 bits of signif.
+};;
+
+{ .mfi
+ ld4 GR_Z_1 = [GR_ad_z_1] // Load Z_1
+ nop.f 0
+ mov GR_exp_mask = 0x1FFFF // Create exponent mask
+}
+{ .mfi
+ shladd GR_ad_tbl_1 = GR_Index1, 4, GR_ad_tbl_1 // Point to G_1
+ nop.f 0
+ mov GR_Bias = 0x0FFFF // Create exponent bias
+};;
+
+{ .mfi
+ ldfps FR_G, FR_H = [GR_ad_tbl_1],8 // Load G_1, H_1
+ fmerge.se FR_S_hi = f1,FR_XLog_Hi // Form |x+1|
+ nop.i 0
+};;
+
+{ .mmi
+ getf.exp GR_N = FR_XLog_Hi // Get N = exponent of x+1
+ ldfd FR_h = [GR_ad_tbl_1] // Load h_1
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_log2_hi = [GR_ad_q],16 // Load log2_hi
+ nop.f 0
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15 // Get bits 30-15 of X_0 * Z_1
+};;
+
+// WE CANNOT USE GR_X_1 IN NEXT 3 CYCLES BECAUSE OF POSSIBLE 10 CLOCKS STALL!
+// "DEAD" ZONE!
+
+{ .mmi
+ ldfe FR_log2_lo = [GR_ad_q],16 // Load log2_lo
+ sub GR_N = GR_N, GR_Bias
+ mov GR_exp_2tom80 = 0x0ffaf // Exponent of 2^-80
+};;
+
+{ .mfi
+ ldfe FR_Q4 = [GR_ad_q],16 // Load Q4
+ nop.f 0
+ sub GR_minus_N = GR_Bias, GR_N // Form exponent of 2^(-N)
+};;
+
+{ .mmf
+ ldfe FR_Q3 = [GR_ad_q],16 // Load Q3
+ setf.sig FR_float_N = GR_N // Put integer N into rightmost sign
+ nop.f 0
+};;
+
+{ .mmi
+ nop.m 0
+ ldfe FR_Q2 = [GR_ad_q],16 // Load Q2
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract bits 6-9 of X_1
+};;
+
+{ .mmi
+ ldfe FR_Q1 = [GR_ad_q] // Load Q1
+ shladd GR_ad_z_2 = GR_Index2, 2, GR_ad_z_2 // Point to Z_2
+ nop.i 0
+};;
+
+{ .mmi
+ ld4 GR_Z_2 = [GR_ad_z_2] // Load Z_2
+ shladd GR_ad_tbl_2 = GR_Index2, 4, GR_ad_tbl_2 // Point to G_2
+ nop.i 0
+};;
+
+{ .mmi
+ ldfps FR_G2, FR_H2 = [GR_ad_tbl_2],8 // Load G_2, H_2
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfd FR_h2 = [GR_ad_tbl_2] // Load h_2
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ setf.exp FR_2_to_minus_N = GR_minus_N // Form 2^(-N)
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15 // Get bits 30-15 of X_1 * Z_2
+};;
+
+// WE CANNOT USE GR_X_2 IN NEXT 3 CYCLES BECAUSE OF POSSIBLE 10 CLOCKS STALL!
+// "DEAD" ZONE!
+// JUST HAVE TO INSERT 3 NOP CYCLES (nothing to do here)
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p11) fma.s1 FR_Q4 = FR_Q4, FR_Neg_One, f0 // Negate Q4
+ extr.u GR_Index3 = GR_X_2, 1, 5 // Extract bits 1-5 of X_2
+ };;
+
+{ .mfi
+ shladd GR_ad_tbl_3 = GR_Index3, 4, GR_ad_tbl_3 // Point to G_3
+ fcvt.xf FR_float_N = FR_float_N
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fma.s1 FR_Q3 = FR_Q3, FR_Neg_One, f0 // Negate Q3
+ nop.i 0
+};;
+
+{ .mfi
+ ldfps FR_G3, FR_H3 = [GR_ad_tbl_3],8 // Load G_3, H_3
+(p11) fma.s1 FR_Q2 = FR_Q2, FR_Neg_One, f0 // Negate Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fma.s1 FR_Q1 = FR_Q1, FR_Neg_One, f0 // Negate Q1
+ nop.i 0
+};;
+
+{ .mfi
+ ldfd FR_h3 = [GR_ad_tbl_3] // Load h_3
+ fmpy.s1 FR_G = FR_G, FR_G2 // G = G_1 * G_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H2 // H = H_1 + H_2
+ nop.i 0
+};;
+
+{ .mmf
+ nop.m 0
+ nop.m 0
+ fadd.s1 FR_h = FR_h, FR_h2 // h = h_1 + h_2
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_G = FR_G, FR_G3 // G = (G_1 * G_2) * G_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_H = FR_H, FR_H3 // H = (H_1 + H_2) + H_3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_h = FR_h, FR_h3 // h = (h_1 + h_2) + h_3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r = FR_G, FR_S_hi, f1 // r = G * S_hi - 1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Y_hi = FR_float_N, FR_log2_hi, FR_H // Y_hi=N*log2_hi+H
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_h = FR_float_N, FR_log2_lo, FR_h // h=N*log2_lo+h
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_lo = FR_r, FR_Q4, FR_Q3 // poly_lo = r * Q4 + Q3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly_lo = FR_poly_lo, FR_r, FR_Q2 // poly_lo=poly_lo*r+Q2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rcub = FR_rsq, FR_r, f0 // rcub = r^3
+ nop.i 0
+};;
+
+.pred.rel "mutex",p12,p11
+{ .mfi
+ nop.m 0
+(p12) fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r // poly_hi = Q1*rsq + r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fms.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r // poly_hi = Q1*rsq + r
+ nop.i 0
+};;
+
+
+.pred.rel "mutex",p12,p11
+{ .mfi
+ nop.m 0
+(p12) fma.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h//poly_lo=poly_lo*r^3+h
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fms.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h//poly_lo=poly_lo*r^3+h
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fadd.s0 FR_Y_lo = FR_poly_hi, FR_poly_lo // Y_lo=poly_hi+poly_lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fma.s0 FR_Y_hi = FR_Y_hi, FR_Neg_One, f0 // FR_Y_hi sign for neg
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ fadd.s0 FR_Res = FR_Y_lo,FR_Y_hi // Result=Y_lo+Y_hi
+ br.ret.sptk b0 // Common exit for 2^-7 < x < inf
+};;
+
+// NEAR ZERO POLYNOMIAL INTERVAL
+near_0:
+{ .mfi
+ nop.m 0
+ fma.s1 FR_X4 = FR_X2, FR_X2, f0 // x^4 = x^2 * x^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P9 = FR_C9,FR_X2,FR_C7 // p9 = C9*x^2 + C7
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P5 = FR_C5,FR_X2,FR_C3 // p5 = C5*x^2 + C3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P3 = FR_P9,FR_X4,FR_P5 // p3 = p9*x^4 + p5
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ fma.s0 FR_Res = FR_P3,FR_X3,FR_Arg // res = p3*C3 + x
+ br.ret.sptk b0 // Near 0 path return
+};;
+
+GLOBAL_LIBM_END(asinhl)
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/s_atan.S b/libc/sysdeps/ia64/fpu/s_atan.S
new file mode 100644
index 000000000..720ecad28
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_atan.S
@@ -0,0 +1,753 @@
+.file "atan.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/13/00 Improved speed
+// 04/19/00 Removed the qualifying predicate from the fmerge.s that
+// takes the absolute value.
+// 06/16/00 Reassigned FP registers to eliminate stalls on loads
+// 08/30/00 Saved 5 cycles in main path by rearranging large argument logic
+// and delaying use of result of fcmp in load by 1 group
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 08/20/02 Use atan2 algorithm with x=1 for better accuracy
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// double atan(double Y)
+//
+// Overview of operation
+//==============================================================
+//
+// The atan function returns values in the interval [-pi/2,+pi/2].
+//
+// The algorithm used is the atan2(Y,X) algorithm where we fix X=1.0.
+//
+// There are two basic paths: swap true and swap false.
+// atan2(Y,X) ==> atan2(V/U) where U >= V. If Y > X, we must swap.
+//
+// p6 swap True |Y| > |X|
+// p7 swap False |Y| <= |X|
+//
+//
+// Simple trigonometric identities show
+// Region 1
+// |Y|<=1.0, V=Y, U=1.0 atan2(Y,X) = sgnY * (0 + atan(V/U))
+//
+// Region 2
+// |Y|>1.0, V=1.0, U=Y atan2(Y,X) = sgnY * (pi/2 - atan(V/U))
+//
+//
+// We compute atan(V/U) from the identity
+// atan(z) + atan([(V/U)-z] / [1+(V/U)z])
+// where z is a limited precision approximation (16 bits) to V/U
+//
+// z is calculated with the assistance of the frcpa instruction.
+//
+// atan(z) is calculated by a polynomial z + z^3 * p(w), w=z^2
+// where p(w) = P0+P1*w+...+P22*w^22
+//
+// Let d = [(V/U)-z] / [1+(V/U)z]) = (V-U*z)/(U+V*z)
+//
+// Approximate atan(d) by d + P0*d^3
+// Let F = 1/(U+V*z) * (1-a), where |a|< 2^-8.8.
+// Compute q(a) = 1 + a + ... + a^5.
+// Then F*q(a) approximates the reciprocal to more than 50 bits.
+
+// Special values
+//==============================================================
+// atan(QNAN) = QNAN
+// atan(SNAN) = quieted SNAN
+// atan(+-inf) = +- pi/2
+// atan(+-0) = +-0
+
+// Registers used
+//==============================================================
+
+// predicate registers used:
+// p6 -> p15
+
+// floating-point registers used:
+// f8, input
+// f32 -> f116
+
+// general registers used
+// r14 -> r16
+
+// Assembly macros
+//==============================================================
+
+EXP_AD_P1 = r14
+EXP_AD_P2 = r15
+rsig_near_one = r16
+
+atan2_Y = f8
+atan2_X = f1
+
+atan2_u1_X = f32
+atan2_u1_Y = f33
+atan2_z2_X = f34
+
+atan2_two = f36
+atan2_B1sq_Y = f37
+atan2_z1_X = f38
+atan2_B1X = f40
+
+atan2_B1Y = f41
+atan2_wp_X = f42
+atan2_B1sq_X = f43
+atan2_z = f44
+atan2_w = f45
+
+atan2_P0 = f46
+atan2_P1 = f47
+atan2_P2 = f48
+atan2_P3 = f49
+atan2_P4 = f50
+
+atan2_P5 = f51
+atan2_P6 = f52
+atan2_P7 = f53
+atan2_P8 = f54
+atan2_P9 = f55
+
+atan2_P10 = f56
+atan2_P11 = f57
+atan2_P12 = f58
+atan2_P13 = f59
+atan2_P14 = f60
+
+atan2_P15 = f61
+atan2_P16 = f62
+atan2_P17 = f63
+atan2_P18 = f64
+atan2_P19 = f65
+
+atan2_P20 = f66
+atan2_P21 = f67
+atan2_P22 = f68
+atan2_pi_by_2 = f69
+atan2_sgn_pi_by_2 = f69
+atan2_V13 = f70
+
+atan2_W11 = f71
+atan2_E = f72
+atan2_wp_Y = f73
+atan2_V11 = f74
+atan2_V12 = f75
+
+atan2_V7 = f76
+atan2_V8 = f77
+atan2_W7 = f78
+atan2_W8 = f79
+atan2_W3 = f80
+
+atan2_W4 = f81
+atan2_V3 = f82
+atan2_V4 = f83
+atan2_F = f84
+atan2_gV = f85
+
+atan2_V10 = f86
+atan2_zcub = f87
+atan2_V6 = f88
+atan2_V9 = f89
+atan2_W10 = f90
+
+atan2_W6 = f91
+atan2_W2 = f92
+atan2_V2 = f93
+atan2_alpha = f94
+atan2_alpha_1 = f95
+
+atan2_gVF = f96
+atan2_V5 = f97
+atan2_W12 = f98
+atan2_W5 = f99
+atan2_alpha_sq = f100
+
+atan2_Cp = f101
+atan2_V1 = f102
+atan2_ysq = f103
+atan2_W1 = f104
+atan2_alpha_cub = f105
+
+atan2_C = f106
+atan2_d = f108
+atan2_A_hi = f109
+atan2_dsq = f110
+
+atan2_pd = f111
+atan2_A_lo = f112
+atan2_A = f113
+atan2_Pp = f114
+atan2_sgnY = f115
+
+atan2_sig_near_one = f116
+atan2_near_one = f116
+
+/////////////////////////////////////////////////////////////
+
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(atan2_tb1)
+data8 0xA21922DC45605EA1 , 0x00003FFA // P11
+data8 0xB199DD6D2675C40F , 0x0000BFFA // P10
+data8 0xC2F01E5DDD100DBE , 0x00003FFA // P9
+data8 0xD78F28FC2A592781 , 0x0000BFFA // P8
+data8 0xF0F03ADB3FC930D3 , 0x00003FFA // P7
+data8 0x88887EBB209E3543 , 0x0000BFFB // P6
+data8 0x9D89D7D55C3287A5 , 0x00003FFB // P5
+data8 0xBA2E8B9793955C77 , 0x0000BFFB // P4
+data8 0xE38E38E320A8A098 , 0x00003FFB // P3
+data8 0x9249249247E37913 , 0x0000BFFC // P2
+data8 0xCCCCCCCCCCC906CD , 0x00003FFC // P1
+data8 0xAAAAAAAAAAAAA8A9 , 0x0000BFFD // P0
+data8 0x0000000000000000 , 0x00000000 // pad to avoid bank conflict
+LOCAL_OBJECT_END(atan2_tb1)
+
+LOCAL_OBJECT_START(atan2_tb2)
+data8 0xCE585A259BD8374C , 0x00003FF0 // P21
+data8 0x9F90FB984D8E39D0 , 0x0000BFF3 // P20
+data8 0x9D3436AABE218776 , 0x00003FF5 // P19
+data8 0xDEC343E068A6D2A8 , 0x0000BFF6 // P18
+data8 0xF396268151CFB11C , 0x00003FF7 // P17
+data8 0xD818B4BB43D84BF2 , 0x0000BFF8 // P16
+data8 0xA2270D30A90AA220 , 0x00003FF9 // P15
+data8 0xD5F4F2182E7A8725 , 0x0000BFF9 // P14
+data8 0x80D601879218B53A , 0x00003FFA // P13
+data8 0x9297B23CCFFB291F , 0x0000BFFA // P12
+data8 0xFE7E52D2A89995B3 , 0x0000BFEC // P22
+data8 0xC90FDAA22168C235 , 0x00003FFF // pi/2
+LOCAL_OBJECT_END(atan2_tb2)
+
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(atan)
+
+{ .mfi
+ nop.m 999
+ frcpa.s1 atan2_u1_Y,p7 = f1,atan2_Y
+ nop.i 999
+}
+{ .mfi
+ addl EXP_AD_P1 = @ltoff(atan2_tb1), gp
+ fma.s1 atan2_two = f1,f1,f1
+ nop.i 999
+;;
+}
+
+{ .mfi
+ ld8 EXP_AD_P1 = [EXP_AD_P1]
+ frcpa.s1 atan2_u1_X,p6 = f1,atan2_X
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_ysq = atan2_Y,atan2_Y,f0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ add EXP_AD_P2 = 0xd0,EXP_AD_P1
+ fmerge.s atan2_sgnY = atan2_Y,f1
+ nop.i 999
+}
+;;
+
+
+{ .mfi
+ ldfe atan2_P11 = [EXP_AD_P1],16
+ fclass.m p10,p0 = atan2_Y, 0xc3 // Test for y=nan
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P21 = [EXP_AD_P2],16
+ nop.f 999
+ nop.i 999
+;;
+}
+
+
+{ .mfi
+ ldfe atan2_P10 = [EXP_AD_P1],16
+ fnma.s1 atan2_B1Y = atan2_u1_Y, atan2_Y, atan2_two
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P20 = [EXP_AD_P2],16
+ fma.s1 atan2_wp_Y = atan2_u1_Y, atan2_u1_Y, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ ldfe atan2_P9 = [EXP_AD_P1],16
+ fma.s1 atan2_z1_X = atan2_u1_X, atan2_Y, f0
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P19 = [EXP_AD_P2],16
+ fnma.s1 atan2_B1X = atan2_u1_X, atan2_X, atan2_two
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe atan2_P8 = [EXP_AD_P1],16
+ fma.s1 atan2_z2_X = atan2_u1_X, atan2_ysq, f0
+ nop.i 999
+}
+{ .mfb
+ ldfe atan2_P18 = [EXP_AD_P2],16
+(p10) fma.d.s0 f8 = atan2_Y,atan2_X,f0 // If y=nan, result quietized y
+(p10) br.ret.spnt b0 // Exit if y=nan
+}
+;;
+
+// p6 true if swap, means |y| > 1.0 or ysq > 1.0
+// p7 true if no swap, means 1.0 >= |y| or 1.0 >= ysq
+{ .mfi
+ ldfe atan2_P7 = [EXP_AD_P1],16
+ fcmp.ge.s1 p7,p6 = f1, atan2_ysq
+ nop.i 999
+}
+{ .mmf
+ ldfe atan2_P17 = [EXP_AD_P2],16
+ nop.m 999
+ nop.f 999
+}
+;;
+
+{ .mfi
+ ldfe atan2_P6 = [EXP_AD_P1],16
+ fma.s1 atan2_E = atan2_u1_Y, atan2_B1Y, atan2_Y
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P16 = [EXP_AD_P2],16
+ fma.s1 atan2_B1sq_Y = atan2_B1Y, atan2_B1Y, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ ldfe atan2_P5 = [EXP_AD_P1],16
+(p7) fma.s1 atan2_wp_X = atan2_z1_X, atan2_z1_X, f0
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P15 = [EXP_AD_P2],16
+(p7) fma.s1 atan2_B1sq_X = atan2_B1X, atan2_B1X, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ ldfe atan2_P4 = [EXP_AD_P1],16
+(p6) fma.s1 atan2_z = atan2_u1_Y, atan2_B1Y, f0
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P14 = [EXP_AD_P2],16
+(p7) fma.s1 atan2_E = atan2_z2_X, atan2_B1X, atan2_X
+ nop.i 999
+;;
+}
+
+
+{ .mfi
+ ldfe atan2_P3 = [EXP_AD_P1],16
+ fcmp.eq.s0 p14,p15=atan2_X,atan2_Y // Dummy for denorm and invalid
+ nop.i 999
+}
+{ .mmf
+ ldfe atan2_P13 = [EXP_AD_P2],16
+ nop.m 999
+(p7) fma.s1 atan2_z = atan2_z1_X, atan2_B1X, f0
+;;
+}
+
+{ .mfi
+ ldfe atan2_P2 = [EXP_AD_P1],16
+(p6) fma.s1 atan2_w = atan2_wp_Y, atan2_B1sq_Y,f0
+ nop.i 999
+}
+{ .mlx
+ ldfe atan2_P12 = [EXP_AD_P2],16
+ movl rsig_near_one = 0x8000000000000001 // signif near 1.0
+;;
+}
+
+{ .mfi
+ ldfe atan2_P1 = [EXP_AD_P1],16
+ fclass.m p9,p0 = atan2_Y, 0x23 // test if y inf
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_P22 = [EXP_AD_P2],16
+(p7) fma.s1 atan2_w = atan2_wp_X, atan2_B1sq_X,f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ ldfe atan2_P0 = [EXP_AD_P1],16
+ frcpa.s1 atan2_F,p0 = f1, atan2_E
+ nop.i 999
+}
+{ .mfi
+ ldfe atan2_pi_by_2 = [EXP_AD_P2],16
+(p6) fnma.s1 atan2_gV = atan2_Y, atan2_z, atan2_X
+ nop.i 999
+;;
+}
+
+{ .mfi
+ setf.sig atan2_sig_near_one = rsig_near_one
+(p7) fnma.s1 atan2_gV = atan2_X, atan2_z, atan2_Y
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p9) fma.d.s0 f8 = atan2_sgnY, atan2_pi_by_2, f0 // +-pi/2 if y inf
+(p9) br.ret.spnt b0 // exit if y inf, result is +-pi/2
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V13 = atan2_w, atan2_P11, atan2_P10
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W11 = atan2_w, atan2_P21, atan2_P20
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V11 = atan2_w, atan2_P9, atan2_P8
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V12 = atan2_w, atan2_w, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V8 = atan2_w, atan2_P7 , atan2_P6
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W8 = atan2_w, atan2_P19, atan2_P18
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fnma.s1 atan2_alpha = atan2_E, atan2_F, f1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnma.s1 atan2_alpha_1 = atan2_E, atan2_F, atan2_two
+ nop.i 999
+;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V7 = atan2_w, atan2_P5 , atan2_P4
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W7 = atan2_w, atan2_P17, atan2_P16
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V4 = atan2_w, atan2_P3 , atan2_P2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W4 = atan2_w, atan2_P15, atan2_P14
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V3 = atan2_w, atan2_P1 , atan2_P0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W3 = atan2_w, atan2_P13, atan2_P12
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V10 = atan2_V12, atan2_V13, atan2_V11
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_gVF = atan2_gV, atan2_F, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_alpha_sq = atan2_alpha, atan2_alpha, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_Cp = atan2_alpha, atan2_alpha_1, f1
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V9 = atan2_V12, atan2_V12, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W10 = atan2_V12, atan2_P22 , atan2_W11
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V6 = atan2_V12, atan2_V8 , atan2_V7
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W6 = atan2_V12, atan2_W8 , atan2_W7
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V2 = atan2_V12, atan2_V4 , atan2_V3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W2 = atan2_V12, atan2_W4 , atan2_W3
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_alpha_cub = atan2_alpha, atan2_alpha_sq, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_C = atan2_gVF, atan2_Cp, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W12 = atan2_V9, atan2_V9, f0
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V5 = atan2_V9, atan2_V10, atan2_V6
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W5 = atan2_V9, atan2_W10, atan2_W6
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fclass.m p8,p0 = atan2_Y, 0x07 // Test for y=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_d = atan2_alpha_cub, atan2_C, atan2_C
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W12 = atan2_V9, atan2_W12, f0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_V1 = atan2_V9, atan2_V5, atan2_V2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_W1 = atan2_V9, atan2_W5, atan2_W2
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+(p8) fmerge.s f8 = atan2_sgnY, f0 // +-0 if y=0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fma.s1 atan2_zcub = atan2_z, atan2_w, f0
+(p8) br.ret.spnt b0 // Exit if y=0
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_pd = atan2_P0, atan2_d, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_dsq = atan2_d, atan2_d, f0
+ nop.i 999
+;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fmerge.se atan2_near_one = f1, atan2_sig_near_one // Const ~1.0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_Pp = atan2_W12, atan2_W1, atan2_V1
+ nop.i 999
+;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_sgn_pi_by_2 = atan2_pi_by_2, atan2_sgnY, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_A_lo = atan2_pd, atan2_dsq, atan2_d
+ nop.i 999
+;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atan2_A_hi = atan2_zcub, atan2_Pp, atan2_z
+ nop.i 999
+;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p6) fma.s1 atan2_A = atan2_A_hi, f1, atan2_A_lo
+ nop.i 999
+}
+// For |Y| <= |X| and X > 0, result is A_hi + A_lo
+{ .mfi
+ nop.m 999
+(p7) fma.d.s0 f8 = atan2_A_hi, f1, atan2_A_lo
+ nop.i 999
+;;
+}
+
+// For |Y| > |X|, result is +- pi/2 - (A_hi + A_lo)
+// We perturb A by multiplying by 1.0+1ulp as we produce the result
+// in order to get symmetrically rounded results in directed rounding modes.
+// If we don't do this, there are a few cases where the trailing 11 bits of
+// the significand of the result, before converting to double, are zero. These
+// cases do not round symmetrically in round to +infinity or round to -infinity.
+{ .mfb
+ nop.m 999
+(p6) fnma.d.s0 f8 = atan2_A, atan2_near_one, atan2_sgn_pi_by_2
+ br.ret.sptk b0
+;;
+}
+
+GLOBAL_LIBM_END(atan)
diff --git a/libc/sysdeps/ia64/fpu/s_atanf.S b/libc/sysdeps/ia64/fpu/s_atanf.S
new file mode 100644
index 000000000..4da68c7f0
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_atanf.S
@@ -0,0 +1,556 @@
+.file "atanf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+
+
+// History
+//==============================================================
+// 02/20/00 Initial version
+// 08/17/00 Changed predicate register macro-usage to direct predicate
+// names due to an assembler bug.
+// 02/06/02 Corrected .section statement
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align;
+// added missing bundling
+
+//
+// Assembly macros
+//==============================================================
+
+// integer registers used
+EXP_Addr1 = r33
+EXP_Addr2 = r34
+
+// floating point registers used
+atanf_coeff_R4 = f32
+atanf_coeff_R5 = f33
+atanf_coeff_R1 = f34
+atanf_coeff_R2 = f35
+
+atanf_coeff_R3 = f36
+atanf_coeff_P1 = f37
+atanf_coeff_Q6 = f38
+atanf_coeff_Q7 = f39
+atanf_coeff_Q8 = f40
+
+atanf_coeff_Q9 = f41
+atanf_coeff_Q4 = f42
+atanf_coeff_Q5 = f43
+atanf_coeff_Q2 = f44
+atanf_coeff_Q3 = f45
+
+atanf_coeff_P5 = f46
+atanf_coeff_P6 = f47
+atanf_coeff_Q0 = f48
+atanf_coeff_Q1 = f49
+atanf_coeff_P7 = f50
+
+atanf_coeff_P8 = f51
+atanf_coeff_P3 = f52
+atanf_coeff_P4 = f53
+atanf_coeff_P9 = f54
+atanf_coeff_P10 = f55
+
+atanf_coeff_P2 = f56
+atanf_piby2 = f57
+atanf_z = f58
+atanf_b = f59
+atanf_zsq = f60
+
+atanf_sgn_x = f61
+atanf_sgnx_piby2 = f62
+atanf_abs_x = f63
+atanf_t = f64
+atanf_xcub = f65
+
+atanf_tsq = f66
+atanf_t4 = f67
+atanf_x5 = f68
+atanf_x6 = f69
+atanf_x11 = f70
+
+atanf_poly_p1 = f71
+atanf_poly_p2 = f72
+atanf_poly_p3 = f73
+atanf_poly_p4 = f74
+atanf_poly_p5 = f75
+
+atanf_poly_q1 = f76
+atanf_poly_q2 = f77
+atanf_poly_q3 = f78
+atanf_poly_q4 = f79
+atanf_poly_q5 = f80
+
+atanf_poly_q = f81
+atanf_poly_r1 = f81
+atanf_poly_r2 = f82
+atanf_poly_r3 = f83
+atanf_bsq = f84
+atanf_z4 = f85
+
+atanf_z5 = f86
+atanf_z8 = f87
+atanf_z13 = f88
+atanf_poly_r2 = f89
+atanf_poly_r1 = f90
+
+atanf_z8_bsq = f91
+atanf_poly_r = f92
+atanf_z21_poly_r = f93
+atanf_answer = f8
+
+
+// predicate registers used
+//atanf_pred_LE1 = p6
+//atanf_pred_GT1 = p7
+
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(atanf_coeff_1_table)
+data8 0x40c4c241be751ff2 // r4
+data8 0x40e9f300c2f3070b // r5
+data8 0x409babffef772075 // r3
+data8 0xbfd5555512191621 // p1
+data8 0x3fc9997e7afbff4e // p2 = q8
+data8 0xbfd5555512191621 // p1 = q9
+data8 0x3f97105b4160f86b // p8 = q2
+data8 0xbfa6e10ba401393f // p7 = q3
+data8 0x3f522e5d33bc9baa // p10 = q0
+data8 0xbf7deaadaa336451 // p9 = q1
+data8 0xbfc2473c5145ee38 // p3
+data8 0x3fbc4f512b1865f5 // p4
+data8 0x3fc9997e7afbff4e // p2
+data8 0x3ff921fb54442d18 // pi/2
+LOCAL_OBJECT_END(atanf_coeff_1_table)
+
+
+
+LOCAL_OBJECT_START(atanf_coeff_2_table)
+data8 0x4035000000004284 // r1
+data8 0x406cdffff336a59b // r2
+data8 0x3fbc4f512b1865f5 // p4 = q6
+data8 0xbfc2473c5145ee38 // p3 = q7
+data8 0x3fb142a73d7c54e3 // p6 = q4
+data8 0xbfb68eed6a8cfa32 // p5 = q5
+data8 0xbfb68eed6a8cfa32 // p5
+data8 0x3fb142a73d7c54e3 // p6
+data8 0xbfa6e10ba401393f // p7
+data8 0x3f97105b4160f86b // p8
+data8 0xbf7deaadaa336451 // p9
+data8 0x3f522e5d33bc9baa // p10
+LOCAL_OBJECT_END(atanf_coeff_2_table)
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(atanf)
+
+{ .mfi
+ alloc r32 = ar.pfs,1,2,0,0
+ frcpa.s1 atanf_z,p0 = f1,f8
+ addl EXP_Addr2 = @ltoff(atanf_coeff_2_table),gp
+}
+{ .mfi
+ addl EXP_Addr1 = @ltoff(atanf_coeff_1_table),gp
+ fma.s1 atanf_t = f8,f8,f0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fmerge.s atanf_sgn_x = f8,f1
+ nop.i 999;;
+}
+
+{ .mfi
+ ld8 EXP_Addr1 = [EXP_Addr1]
+ fmerge.s atanf_abs_x = f1,f8
+ nop.i 999
+}
+{ .mfi
+ ld8 EXP_Addr2 = [EXP_Addr2]
+ nop.f 999
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fclass.m p8,p0 = f8,0x7 // @zero
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.unc.s0 p9,p10 = f8,f1
+ nop.i 999;;
+}
+
+{ .mfi
+ ldfpd atanf_coeff_R4,atanf_coeff_R5 = [EXP_Addr1],16
+ fnma.s1 atanf_b = f8,atanf_z,f1
+ nop.i 999
+}
+{ .mfi
+ ldfpd atanf_coeff_R1,atanf_coeff_R2 = [EXP_Addr2],16
+ fma.s1 atanf_zsq = atanf_z,atanf_z,f0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ ldfpd atanf_coeff_R3,atanf_coeff_P1 = [EXP_Addr1],16
+ fma.s1 atanf_xcub = f8,atanf_t,f0
+ nop.i 999
+}
+{ .mfi
+ ldfpd atanf_coeff_Q6,atanf_coeff_Q7 = [EXP_Addr2],16
+ fma.s1 atanf_tsq = atanf_t,atanf_t,f0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ ldfpd atanf_coeff_Q8,atanf_coeff_Q9 = [EXP_Addr1],16
+// fcmp.le.s1 atanf_pred_LE1,atanf_pred_GT1 = atanf_abs_x,f1
+ fcmp.le.s1 p6,p7 = atanf_abs_x,f1
+ nop.i 999
+}
+{ .mfi
+ ldfpd atanf_coeff_Q4,atanf_coeff_Q5 = [EXP_Addr2],16
+ nop.f 999
+ nop.i 999;;
+}
+
+
+{ .mfi
+ ldfpd atanf_coeff_Q2,atanf_coeff_Q3 = [EXP_Addr1],16
+ fclass.m p8,p0 = f8,0xe7 // @inf|@qnan|@snan|@zero
+ nop.i 999
+}
+{ .mfi
+ ldfpd atanf_coeff_P5,atanf_coeff_P6 = [EXP_Addr2],16
+ nop.f 999
+ nop.i 999;;
+}
+
+
+{ .mfi
+ ldfpd atanf_coeff_Q0,atanf_coeff_Q1 = [EXP_Addr1],16
+ nop.f 999
+ nop.i 999
+}
+{ .mfi
+ ldfpd atanf_coeff_P7,atanf_coeff_P8 = [EXP_Addr2],16
+ nop.f 999
+ nop.i 999;;
+}
+
+
+{ .mfi
+ ldfpd atanf_coeff_P3,atanf_coeff_P4 = [EXP_Addr1],16
+ fma.s1 atanf_bsq = atanf_b,atanf_b,f0
+ nop.i 999
+}
+{ .mfi
+ ldfpd atanf_coeff_P9,atanf_coeff_P10 = [EXP_Addr2]
+ fma.s1 atanf_z4 = atanf_zsq,atanf_zsq,f0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ ldfpd atanf_coeff_P2,atanf_piby2 = [EXP_Addr1]
+ fma.s1 atanf_x6 = atanf_t,atanf_tsq,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_t4 = atanf_tsq,atanf_tsq,f0
+ nop.i 999;;
+}
+
+
+{ .mfb
+ nop.m 999
+ fma.s1 atanf_x5 = atanf_t,atanf_xcub,f0
+(p8) br.cond.spnt ATANF_X_INF_NAN_ZERO
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_r1 = atanf_b,atanf_coeff_R1,f1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_r3 = atanf_b,atanf_coeff_R5,atanf_coeff_R4
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_r2 = atanf_b,atanf_coeff_R3,atanf_coeff_R2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_z8 = atanf_z4,atanf_z4,f0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_q2 = atanf_t,atanf_coeff_Q5,atanf_coeff_Q4
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_q3 = atanf_t,atanf_coeff_Q7,atanf_coeff_Q6
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_z5 = atanf_z,atanf_z4,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_q1 = atanf_t,atanf_coeff_Q9,atanf_coeff_Q8
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_q4 = atanf_t,atanf_coeff_Q1,atanf_coeff_Q0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_q5 = atanf_t,atanf_coeff_Q3,atanf_coeff_Q2
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_p4 = f8,atanf_coeff_P1,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_p5 = atanf_t,atanf_coeff_P4,atanf_coeff_P3
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_r1 = atanf_z8,atanf_poly_r1,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_z8_bsq = atanf_z8,atanf_bsq,f0
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_q2 = atanf_tsq,atanf_poly_q3,atanf_poly_q2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_r2 = atanf_bsq,atanf_poly_r3,atanf_poly_r2
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_p2 = atanf_t,atanf_coeff_P8,atanf_coeff_P7
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_q1 = atanf_poly_q1,f1,atanf_tsq
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_z13 = atanf_z5,atanf_z8,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_p1 = atanf_t,atanf_coeff_P10,atanf_coeff_P9
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_p4 = atanf_t,atanf_poly_p4,f8
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_q4 = atanf_tsq,atanf_poly_q5,atanf_poly_q4
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_p3 = atanf_t,atanf_coeff_P6,atanf_coeff_P5
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_p5 = atanf_t,atanf_poly_p5,atanf_coeff_P2
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_x11 = atanf_x5,atanf_x6,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_r = atanf_z8_bsq,atanf_poly_r2,atanf_poly_r1
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s0 atanf_sgnx_piby2 = atanf_sgn_x,atanf_piby2,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_q2 = atanf_t4,atanf_poly_q1,atanf_poly_q2
+ nop.i 999;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_p1 = atanf_tsq,atanf_poly_p1,atanf_poly_p2
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_p4 = atanf_x5,atanf_poly_p5,atanf_poly_p4
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_z21_poly_r = atanf_z13,atanf_poly_r,f0
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_q = atanf_t4,atanf_poly_q2,atanf_poly_q4
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+ fma.s1 atanf_poly_p1 = atanf_tsq,atanf_poly_p1,atanf_poly_p3
+ nop.i 999;;
+}
+
+{ .mfi
+ nop.m 999
+//(atanf_pred_GT1) fnma.s atanf_answer = atanf_poly_q,atanf_z21_poly_r,atanf_sgnx_piby2
+(p7) fnma.s.s0 atanf_answer = atanf_poly_q,atanf_z21_poly_r,atanf_sgnx_piby2
+ nop.i 999;;
+}
+
+{ .mfb
+ nop.m 999
+//(atanf_pred_LE1) fma.s atanf_answer = atanf_x11,atanf_poly_p1,atanf_poly_p4
+(p6) fma.s.s0 atanf_answer = atanf_x11,atanf_poly_p1,atanf_poly_p4
+ br.ret.sptk b0
+}
+
+
+
+ATANF_X_INF_NAN_ZERO:
+
+{ .mfi
+ nop.m 0
+ fclass.m p8,p9 = f8,0x23 // @inf
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+(p8) fmerge.s f8 = f8, atanf_piby2
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ fnorm.s.s0 f8 = f8
+ br.ret.sptk b0
+}
+;;
+
+GLOBAL_LIBM_END(atanf)
+
diff --git a/libc/sysdeps/ia64/fpu/s_atanl.S b/libc/sysdeps/ia64/fpu/s_atanl.S
new file mode 100644
index 000000000..1a2361130
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_atanl.S
@@ -0,0 +1,2007 @@
+.file "atanl.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+//*********************************************************************
+//
+// History
+// 02/02/00 (hand-optimized)
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 03/13/01 Fixed flags when denormal raised on intermediate result
+// 01/08/02 Improved speed.
+// 02/06/02 Corrected .section statement
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+// 03/31/05 Reformatted delimiters between data tables
+//
+//*********************************************************************
+//
+// Function: atanl(x) = inverse tangent(x), for double extended x values
+// Function: atan2l(y,x) = atan(y/x), for double extended y, x values
+//
+// API
+//
+// long double atanl (long double x)
+// long double atan2l (long double y, long double x)
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f9 (Input for atan2l)
+// f10-f15, f32-f83
+//
+// General Purpose Registers:
+// r32-r51
+// r49-r52 (Arguments to error support for 0,0 case)
+//
+// Predicate Registers: p6-p15
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// Denormal fault raised on denormal inputs
+// Underflow exceptions may occur
+// Special error handling for the y=0 and x=0 case
+// Inexact raised when appropriate by algorithm
+//
+// atanl(SNaN) = QNaN
+// atanl(QNaN) = QNaN
+// atanl(+/-0) = +/- 0
+// atanl(+/-Inf) = +/-pi/2
+//
+// atan2l(Any NaN for x or y) = QNaN
+// atan2l(+/-0,x) = +/-0 for x > 0
+// atan2l(+/-0,x) = +/-pi for x < 0
+// atan2l(+/-0,+0) = +/-0
+// atan2l(+/-0,-0) = +/-pi
+// atan2l(y,+/-0) = pi/2 y > 0
+// atan2l(y,+/-0) = -pi/2 y < 0
+// atan2l(+/-y, Inf) = +/-0 for finite y > 0
+// atan2l(+/-Inf, x) = +/-pi/2 for finite x
+// atan2l(+/-y, -Inf) = +/-pi for finite y > 0
+// atan2l(+/-Inf, Inf) = +/-pi/4
+// atan2l(+/-Inf, -Inf) = +/-3pi/4
+//
+//*********************************************************************
+//
+// Mathematical Description
+// ---------------------------
+//
+// The function ATANL( Arg_Y, Arg_X ) returns the "argument"
+// or the "phase" of the complex number
+//
+// Arg_X + i Arg_Y
+//
+// or equivalently, the angle in radians from the positive
+// x-axis to the line joining the origin and the point
+// (Arg_X,Arg_Y)
+//
+//
+// (Arg_X, Arg_Y) x
+// \
+// \
+// \
+// \
+// \ angle between is ATANL(Arg_Y,Arg_X)
+
+
+
+
+// \
+// ------------------> X-axis
+
+// Origin
+//
+// Moreover, this angle is reported in the range [-pi,pi] thus
+//
+// -pi <= ATANL( Arg_Y, Arg_X ) <= pi.
+//
+// From the geometry, it is easy to define ATANL when one of
+// Arg_X or Arg_Y is +-0 or +-inf:
+//
+//
+// \ Y |
+// X \ | +0 | -0 | +inf | -inf | finite non-zero
+// \ | | | | |
+// ______________________________________________________
+// | | | |
+// +-0 | Invalid/ | pi/2 | -pi/2 | sign(Y)*pi/2
+// | qNaN | | |
+// --------------------------------------------------------
+// | | | | |
+// +inf | +0 | -0 | pi/4 | -pi/4 | sign(Y)*0
+// --------------------------------------------------------
+// | | | | |
+// -inf | +pi | -pi | 3pi/4 | -3pi/4 | sign(Y)*pi
+// --------------------------------------------------------
+// finite | X>0? | pi/2 | -pi/2 | normal case
+// non-zero| sign(Y)*0: | | |
+// | sign(Y)*pi | | |
+//
+//
+// One must take note that ATANL is NOT the arctangent of the
+// value Arg_Y/Arg_X; but rather ATANL and arctan are related
+// in a slightly more complicated way as follows:
+//
+// Let U := max(|Arg_X|, |Arg_Y|); V := min(|Arg_X|, |Arg_Y|);
+// sign_X be the sign bit of Arg_X, i.e., sign_X is 0 or 1;
+// s_X be the sign of Arg_X, i.e., s_X = (-1)^sign_X;
+//
+// sign_Y be the sign bit of Arg_Y, i.e., sign_Y is 0 or 1;
+// s_Y be the sign of Arg_Y, i.e., s_Y = (-1)^sign_Y;
+//
+// swap be 0 if |Arg_X| >= |Arg_Y| and 1 otherwise.
+//
+// Then, ATANL(Arg_Y, Arg_X) =
+//
+// / arctan(V/U) \ sign_X = 0 & swap = 0
+// | pi/2 - arctan(V/U) | sign_X = 0 & swap = 1
+// s_Y * | |
+// | pi - arctan(V/U) | sign_X = 1 & swap = 0
+// \ pi/2 + arctan(V/U) / sign_X = 1 & swap = 1
+//
+//
+// This relationship also suggest that the algorithm's major
+// task is to calculate arctan(V/U) for 0 < V <= U; and the
+// final Result is given by
+//
+// s_Y * { (P_hi + P_lo) + sigma * arctan(V/U) }
+//
+// where
+//
+// (P_hi,P_lo) represents M(sign_X,swap)*(pi/2) accurately
+//
+// M(sign_X,swap) = 0 for sign_X = 0 and swap = 0
+// 1 for swap = 1
+// 2 for sign_X = 1 and swap = 0
+//
+// and
+//
+// sigma = { (sign_X XOR swap) : -1.0 : 1.0 }
+//
+// = (-1) ^ ( sign_X XOR swap )
+//
+// Both (P_hi,P_lo) and sigma can be stored in a table and fetched
+// using (sign_X,swap) as an index. (P_hi, P_lo) can be stored as a
+// double-precision, and single-precision pair; and sigma can
+// obviously be just a single-precision number.
+//
+// In the algorithm we propose, arctan(V/U) is calculated to high accuracy
+// as A_hi + A_lo. Consequently, the Result ATANL( Arg_Y, Arg_X ) is
+// given by
+//
+// s_Y*P_hi + s_Y*sigma*A_hi + s_Y*(sigma*A_lo + P_lo)
+//
+// We now discuss the calculation of arctan(V/U) for 0 < V <= U.
+//
+// For (V/U) < 2^(-3), we use a simple polynomial of the form
+//
+// z + z^3*(P_1 + z^2*(P_2 + z^2*(P_3 + ... + P_8)))
+//
+// where z = V/U.
+//
+// For the sake of accuracy, the first term "z" must approximate V/U to
+// extra precision. For z^3 and higher power, a working precision
+// approximation to V/U suffices. Thus, we obtain:
+//
+// z_hi + z_lo = V/U to extra precision and
+// z = V/U to working precision
+//
+// The value arctan(V/U) is delivered as two pieces (A_hi, A_lo)
+//
+// (A_hi,A_lo) = (z_hi, z^3*(P_1 + ... + P_8) + z_lo).
+//
+//
+// For 2^(-3) <= (V/U) <= 1, we use a table-driven approach.
+// Consider
+//
+// (V/U) = 2^k * 1.b_1 b_2 .... b_63 b_64 b_65 ....
+//
+// Define
+//
+// z_hi = 2^k * 1.b_1 b_2 b_3 b_4 1
+//
+// then
+// / \
+// | (V/U) - z_hi |
+
+// arctan(V/U) = arctan(z_hi) + acrtan| -------------- |
+// | 1 + (V/U)*z_hi |
+// \ /
+//
+// / \
+// | V - z_hi*U |
+
+// = arctan(z_hi) + acrtan| -------------- |
+// | U + V*z_hi |
+// \ /
+//
+// = arctan(z_hi) + acrtan( V' / U' )
+//
+//
+// where
+//
+// V' = V - U*z_hi; U' = U + V*z_hi.
+//
+// Let
+//
+// w_hi + w_lo = V'/U' to extra precision and
+// w = V'/U' to working precision
+//
+// then we can approximate arctan(V'/U') by
+//
+// arctan(V'/U') = w_hi + w_lo
+// + w^3*(Q_1 + w^2*(Q_2 + w^2*(Q_3 + w^2*Q_4)))
+//
+// = w_hi + w_lo + poly
+//
+// Finally, arctan(z_hi) is calculated beforehand and stored in a table
+// as Tbl_hi, Tbl_lo. Thus,
+//
+// (A_hi, A_lo) = (Tbl_hi, w_hi+(poly+(w_lo+Tbl_lo)))
+//
+// This completes the mathematical description.
+//
+//
+// Algorithm
+// -------------
+//
+// Step 0. Check for unsupported format.
+//
+// If
+// ( expo(Arg_X) not zero AND msb(Arg_X) = 0 ) OR
+// ( expo(Arg_Y) not zero AND msb(Arg_Y) = 0 )
+//
+// then one of the arguments is unsupported. Generate an
+// invalid and return qNaN.
+//
+// Step 1. Initialize
+//
+// Normalize Arg_X and Arg_Y and set the following
+//
+// sign_X := sign_bit(Arg_X)
+// s_Y := (sign_bit(Arg_Y)==0? 1.0 : -1.0)
+// swap := (|Arg_X| >= |Arg_Y|? 0 : 1 )
+// U := max( |Arg_X|, |Arg_Y| )
+// V := min( |Arg_X|, |Arg_Y| )
+//
+// execute: frcpa E, pred, V, U
+// If pred is 0, go to Step 5 for special cases handling.
+//
+// Step 2. Decide on branch.
+//
+// Q := E * V
+// If Q < 2^(-3) go to Step 4 for simple polynomial case.
+//
+// Step 3. Table-driven algorithm.
+//
+// Q is represented as
+//
+// 2^(-k) * 1.b_1 b_2 b_3 ... b_63; k = 0,-1,-2,-3
+//
+// and that if k = 0, b_1 = b_2 = b_3 = b_4 = 0.
+//
+// Define
+//
+// z_hi := 2^(-k) * 1.b_1 b_2 b_3 b_4 1
+//
+// (note that there are 49 possible values of z_hi).
+//
+// ...We now calculate V' and U'. While V' is representable
+// ...as a 64-bit number because of cancellation, U' is
+// ...not in general a 64-bit number. Obtaining U' accurately
+// ...requires two working precision numbers
+//
+// U_prime_hi := U + V * z_hi ...WP approx. to U'
+// U_prime_lo := ( U - U_prime_hi ) + V*z_hi ...observe order
+// V_prime := V - U * z_hi ...this is exact
+//
+// C_hi := frcpa (1.0, U_prime_hi) ...C_hi approx 1/U'_hi
+//
+// loop 3 times
+// C_hi := C_hi + C_hi*(1.0 - C_hi*U_prime_hi)
+//
+// ...at this point C_hi is (1/U_prime_hi) to roughly 64 bits
+//
+// w_hi := V_prime * C_hi ...w_hi is V_prime/U_prime to
+// ...roughly working precision
+//
+// ...note that we want w_hi + w_lo to approximate
+// ...V_prime/(U_prime_hi + U_prime_lo) to extra precision
+// ...but for now, w_hi is good enough for the polynomial
+// ...calculation.
+//
+// wsq := w_hi*w_hi
+// poly := w_hi*wsq*(Q_1 + wsq*(Q_2 + wsq*(Q_3 + wsq*Q_4)))
+//
+// Fetch
+// (Tbl_hi, Tbl_lo) = atan(z_hi) indexed by (k,b_1,b_2,b_3,b_4)
+// ...Tbl_hi is a double-precision number
+// ...Tbl_lo is a single-precision number
+//
+// (P_hi, P_lo) := M(sign_X,swap)*(Pi_by_2_hi, Pi_by_2_lo)
+// ...as discussed previous. Again; the implementation can
+// ...chose to fetch P_hi and P_lo from a table indexed by
+// ...(sign_X, swap).
+// ...P_hi is a double-precision number;
+// ...P_lo is a single-precision number.
+//
+// ...calculate w_lo so that w_hi + w_lo is V'/U' accurately
+// w_lo := ((V_prime - w_hi*U_prime_hi) -
+// w_hi*U_prime_lo) * C_hi ...observe order
+//
+//
+// ...Ready to deliver arctan(V'/U') as A_hi, A_lo
+// A_hi := Tbl_hi
+// A_lo := w_hi + (poly + (Tbl_lo + w_lo)) ...observe order
+//
+// ...Deliver final Result
+// ...s_Y*P_hi + s_Y*sigma*A_hi + s_Y*(sigma*A_lo + P_lo)
+//
+// sigma := ( (sign_X XOR swap) ? -1.0 : 1.0 )
+// ...sigma can be obtained by a table lookup using
+// ...(sign_X,swap) as index and stored as single precision
+// ...sigma should be calculated earlier
+//
+// P_hi := s_Y*P_hi
+// A_hi := s_Y*A_hi
+//
+// Res_hi := P_hi + sigma*A_hi ...this is exact because
+// ...both P_hi and Tbl_hi
+// ...are double-precision
+// ...and |Tbl_hi| > 2^(-4)
+// ...P_hi is either 0 or
+// ...between (1,4)
+//
+// Res_lo := sigma*A_lo + P_lo
+//
+// Return Res_hi + s_Y*Res_lo in user-defined rounding control
+//
+// Step 4. Simple polynomial case.
+//
+// ...E and Q are inherited from Step 2.
+//
+// A_hi := Q ...Q is inherited from Step 2 Q approx V/U
+//
+// loop 3 times
+// E := E + E2(1.0 - E*U1
+// ...at this point E approximates 1/U to roughly working precision
+//
+// z := V * E ...z approximates V/U to roughly working precision
+// zsq := z * z
+// z4 := zsq * zsq; z8 := z4 * z4
+//
+// poly1 := P_4 + zsq*(P_5 + zsq*(P_6 + zsq*(P_7 + zsq*P_8)))
+// poly2 := zsq*(P_1 + zsq*(P_2 + zsq*P_3))
+//
+// poly := poly1 + z8*poly2
+//
+// z_lo := (V - A_hi*U)*E
+//
+// A_lo := z*poly + z_lo
+// ...A_hi, A_lo approximate arctan(V/U) accurately
+//
+// (P_hi, P_lo) := M(sign_X,swap)*(Pi_by_2_hi, Pi_by_2_lo)
+// ...one can store the M(sign_X,swap) as single precision
+// ...values
+//
+// ...Deliver final Result
+// ...s_Y*P_hi + s_Y*sigma*A_hi + s_Y*(sigma*A_lo + P_lo)
+//
+// sigma := ( (sign_X XOR swap) ? -1.0 : 1.0 )
+// ...sigma can be obtained by a table lookup using
+// ...(sign_X,swap) as index and stored as single precision
+// ...sigma should be calculated earlier
+//
+// P_hi := s_Y*P_hi
+// A_hi := s_Y*A_hi
+//
+// Res_hi := P_hi + sigma*A_hi ...need to compute
+// ...P_hi + sigma*A_hi
+// ...exactly
+//
+// tmp := (P_hi - Res_hi) + sigma*A_hi
+//
+// Res_lo := s_Y*(sigma*A_lo + P_lo) + tmp
+//
+// Return Res_hi + Res_lo in user-defined rounding control
+//
+// Step 5. Special Cases
+//
+// These are detected early in the function by fclass instructions.
+//
+// We are in one of those special cases when X or Y is 0,+-inf or NaN
+//
+// If one of X and Y is NaN, return X+Y (which will generate
+// invalid in case one is a signaling NaN). Otherwise,
+// return the Result as described in the table
+//
+//
+//
+// \ Y |
+// X \ | +0 | -0 | +inf | -inf | finite non-zero
+// \ | | | | |
+// ______________________________________________________
+// | | | |
+// +-0 | Invalid/ | pi/2 | -pi/2 | sign(Y)*pi/2
+// | qNaN | | |
+// --------------------------------------------------------
+// | | | | |
+// +inf | +0 | -0 | pi/4 | -pi/4 | sign(Y)*0
+// --------------------------------------------------------
+// | | | | |
+// -inf | +pi | -pi | 3pi/4 | -3pi/4 | sign(Y)*pi
+// --------------------------------------------------------
+// finite | X>0? | pi/2 | -pi/2 |
+// non-zero| sign(Y)*0: | | | N/A
+// | sign(Y)*pi | | |
+//
+//
+
+ArgY_orig = f8
+Result = f8
+FR_RESULT = f8
+ArgX_orig = f9
+ArgX = f10
+FR_X = f10
+ArgY = f11
+FR_Y = f11
+s_Y = f12
+U = f13
+V = f14
+E = f15
+Q = f32
+z_hi = f33
+U_prime_hi = f34
+U_prime_lo = f35
+V_prime = f36
+C_hi = f37
+w_hi = f38
+w_lo = f39
+wsq = f40
+poly = f41
+Tbl_hi = f42
+Tbl_lo = f43
+P_hi = f44
+P_lo = f45
+A_hi = f46
+A_lo = f47
+sigma = f48
+Res_hi = f49
+Res_lo = f50
+Z = f52
+zsq = f53
+z4 = f54
+z8 = f54
+poly1 = f55
+poly2 = f56
+z_lo = f57
+tmp = f58
+P_1 = f59
+Q_1 = f60
+P_2 = f61
+Q_2 = f62
+P_3 = f63
+Q_3 = f64
+P_4 = f65
+Q_4 = f66
+P_5 = f67
+P_6 = f68
+P_7 = f69
+P_8 = f70
+U_hold = f71
+TWO_TO_NEG3 = f72
+C_hi_hold = f73
+E_hold = f74
+M = f75
+ArgX_abs = f76
+ArgY_abs = f77
+Result_lo = f78
+A_temp = f79
+FR_temp = f80
+Xsq = f81
+Ysq = f82
+tmp_small = f83
+
+GR_SAVE_PFS = r33
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+sign_X = r36
+sign_Y = r37
+swap = r38
+table_ptr1 = r39
+table_ptr2 = r40
+k = r41
+lookup = r42
+exp_ArgX = r43
+exp_ArgY = r44
+exponent_Q = r45
+significand_Q = r46
+special = r47
+sp_exp_Q = r48
+sp_exp_4sig_Q = r49
+table_base = r50
+int_temp = r51
+
+GR_Parameter_X = r49
+GR_Parameter_Y = r50
+GR_Parameter_RESULT = r51
+GR_Parameter_TAG = r52
+GR_temp = r52
+
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(Constants_atan)
+// double pi/2
+data8 0x3FF921FB54442D18
+// single lo_pi/2, two**(-3)
+data4 0x248D3132, 0x3E000000
+data8 0xAAAAAAAAAAAAAAA3, 0xBFFD // P_1
+data8 0xCCCCCCCCCCCC54B2, 0x3FFC // P_2
+data8 0x9249249247E4D0C2, 0xBFFC // P_3
+data8 0xE38E38E058870889, 0x3FFB // P_4
+data8 0xBA2E895B290149F8, 0xBFFB // P_5
+data8 0x9D88E6D4250F733D, 0x3FFB // P_6
+data8 0x884E51FFFB8745A0, 0xBFFB // P_7
+data8 0xE1C7412B394396BD, 0x3FFA // P_8
+data8 0xAAAAAAAAAAAAA52F, 0xBFFD // Q_1
+data8 0xCCCCCCCCC75B60D3, 0x3FFC // Q_2
+data8 0x924923AD011F1940, 0xBFFC // Q_3
+data8 0xE36F716D2A5F89BD, 0x3FFB // Q_4
+//
+// Entries Tbl_hi (double precision)
+// B = 1+Index/16+1/32 Index = 0
+// Entries Tbl_lo (single precision)
+// B = 1+Index/16+1/32 Index = 0
+//
+data8 0x3FE9A000A935BD8E
+data4 0x23ACA08F, 0x00000000
+//
+// Entries Tbl_hi (double precision) Index = 0,1,...,15
+// B = 2^(-1)*(1+Index/16+1/32)
+// Entries Tbl_lo (single precision)
+// Index = 0,1,...,15 B = 2^(-1)*(1+Index/16+1/32)
+//
+data8 0x3FDE77EB7F175A34
+data4 0x238729EE, 0x00000000
+data8 0x3FE0039C73C1A40B
+data4 0x249334DB, 0x00000000
+data8 0x3FE0C6145B5B43DA
+data4 0x22CBA7D1, 0x00000000
+data8 0x3FE1835A88BE7C13
+data4 0x246310E7, 0x00000000
+data8 0x3FE23B71E2CC9E6A
+data4 0x236210E5, 0x00000000
+data8 0x3FE2EE628406CBCA
+data4 0x2462EAF5, 0x00000000
+data8 0x3FE39C391CD41719
+data4 0x24B73EF3, 0x00000000
+data8 0x3FE445065B795B55
+data4 0x24C11260, 0x00000000
+data8 0x3FE4E8DE5BB6EC04
+data4 0x242519EE, 0x00000000
+data8 0x3FE587D81F732FBA
+data4 0x24D4346C, 0x00000000
+data8 0x3FE6220D115D7B8D
+data4 0x24ED487B, 0x00000000
+data8 0x3FE6B798920B3D98
+data4 0x2495FF1E, 0x00000000
+data8 0x3FE748978FBA8E0F
+data4 0x223D9531, 0x00000000
+data8 0x3FE7D528289FA093
+data4 0x242B0411, 0x00000000
+data8 0x3FE85D69576CC2C5
+data4 0x2335B374, 0x00000000
+data8 0x3FE8E17AA99CC05D
+data4 0x24C27CFB, 0x00000000
+//
+// Entries Tbl_hi (double precision) Index = 0,1,...,15
+// B = 2^(-2)*(1+Index/16+1/32)
+// Entries Tbl_lo (single precision)
+// Index = 0,1,...,15 B = 2^(-2)*(1+Index/16+1/32)
+//
+data8 0x3FD025FA510665B5
+data4 0x24263482, 0x00000000
+data8 0x3FD1151A362431C9
+data4 0x242C8DC9, 0x00000000
+data8 0x3FD2025567E47C95
+data4 0x245CF9BA, 0x00000000
+data8 0x3FD2ED987A823CFE
+data4 0x235C892C, 0x00000000
+data8 0x3FD3D6D129271134
+data4 0x2389BE52, 0x00000000
+data8 0x3FD4BDEE586890E6
+data4 0x24436471, 0x00000000
+data8 0x3FD5A2E0175E0F4E
+data4 0x2389DBD4, 0x00000000
+data8 0x3FD685979F5FA6FD
+data4 0x2476D43F, 0x00000000
+data8 0x3FD7660752817501
+data4 0x24711774, 0x00000000
+data8 0x3FD84422B8DF95D7
+data4 0x23EBB501, 0x00000000
+data8 0x3FD91FDE7CD0C662
+data4 0x23883A0C, 0x00000000
+data8 0x3FD9F93066168001
+data4 0x240DF63F, 0x00000000
+data8 0x3FDAD00F5422058B
+data4 0x23FE261A, 0x00000000
+data8 0x3FDBA473378624A5
+data4 0x23A8CD0E, 0x00000000
+data8 0x3FDC76550AAD71F8
+data4 0x2422D1D0, 0x00000000
+data8 0x3FDD45AEC9EC862B
+data4 0x2344A109, 0x00000000
+//
+// Entries Tbl_hi (double precision) Index = 0,1,...,15
+// B = 2^(-3)*(1+Index/16+1/32)
+// Entries Tbl_lo (single precision)
+// Index = 0,1,...,15 B = 2^(-3)*(1+Index/16+1/32)
+//
+data8 0x3FC068D584212B3D
+data4 0x239874B6, 0x00000000
+data8 0x3FC1646541060850
+data4 0x2335E774, 0x00000000
+data8 0x3FC25F6E171A535C
+data4 0x233E36BE, 0x00000000
+data8 0x3FC359E8EDEB99A3
+data4 0x239680A3, 0x00000000
+data8 0x3FC453CEC6092A9E
+data4 0x230FB29E, 0x00000000
+data8 0x3FC54D18BA11570A
+data4 0x230C1418, 0x00000000
+data8 0x3FC645BFFFB3AA73
+data4 0x23F0564A, 0x00000000
+data8 0x3FC73DBDE8A7D201
+data4 0x23D4A5E1, 0x00000000
+data8 0x3FC8350BE398EBC7
+data4 0x23D4ADDA, 0x00000000
+data8 0x3FC92BA37D050271
+data4 0x23BCB085, 0x00000000
+data8 0x3FCA217E601081A5
+data4 0x23BC841D, 0x00000000
+data8 0x3FCB1696574D780B
+data4 0x23CF4A8E, 0x00000000
+data8 0x3FCC0AE54D768466
+data4 0x23BECC90, 0x00000000
+data8 0x3FCCFE654E1D5395
+data4 0x2323DCD2, 0x00000000
+data8 0x3FCDF110864C9D9D
+data4 0x23F53F3A, 0x00000000
+data8 0x3FCEE2E1451D980C
+data4 0x23CCB11F, 0x00000000
+//
+data8 0x400921FB54442D18, 0x3CA1A62633145C07 // PI two doubles
+data8 0x3FF921FB54442D18, 0x3C91A62633145C07 // PI_by_2 two dbles
+data8 0x3FE921FB54442D18, 0x3C81A62633145C07 // PI_by_4 two dbles
+data8 0x4002D97C7F3321D2, 0x3C9A79394C9E8A0A // 3PI_by_4 two dbles
+LOCAL_OBJECT_END(Constants_atan)
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(atanl)
+
+// Use common code with atan2l after setting x=1.0
+{ .mfi
+ alloc r32 = ar.pfs, 0, 17, 4, 0
+ fma.s1 Ysq = ArgY_orig, ArgY_orig, f0 // Form y*y
+ nop.i 999
+}
+{ .mfi
+ addl table_ptr1 = @ltoff(Constants_atan#), gp // Address of table pointer
+ fma.s1 Xsq = f1, f1, f0 // Form x*x
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ld8 table_ptr1 = [table_ptr1] // Get table pointer
+ fnorm.s1 ArgY = ArgY_orig
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnorm.s1 ArgX = f1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ getf.exp sign_X = f1 // Get signexp of x
+ fmerge.s ArgX_abs = f0, f1 // Form |x|
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnorm.s1 ArgX_orig = f1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ getf.exp sign_Y = ArgY_orig // Get signexp of y
+ fmerge.s ArgY_abs = f0, ArgY_orig // Form |y|
+ mov table_base = table_ptr1 // Save base pointer to tables
+}
+;;
+
+{ .mfi
+ ldfd P_hi = [table_ptr1],8 // Load double precision hi part of pi
+ fclass.m p8,p0 = ArgY_orig, 0x1e7 // Test y natval, nan, inf, zero
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfps P_lo, TWO_TO_NEG3 = [table_ptr1], 8 // Load P_lo and constant 2^-3
+ nop.f 999
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 M = f1, f1, f0 // Set M = 1.0
+ nop.i 999
+}
+;;
+
+//
+// Check for everything - if false, then must be pseudo-zero
+// or pseudo-nan (IA unsupporteds).
+//
+{ .mfb
+ nop.m 999
+ fclass.m p0,p12 = f1, 0x1FF // Test x unsupported
+(p8) br.cond.spnt ATANL_Y_SPECIAL // Branch if y natval, nan, inf, zero
+}
+;;
+
+// U = max(ArgX_abs,ArgY_abs)
+// V = min(ArgX_abs,ArgY_abs)
+{ .mfi
+ nop.m 999
+ fcmp.ge.s1 p6,p7 = Xsq, Ysq // Test for |x| >= |y| using squares
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fma.s1 V = ArgX_abs, f1, f0 // Set V assuming |x| < |y|
+ br.cond.sptk ATANL_COMMON // Branch to common code
+}
+;;
+
+GLOBAL_IEEE754_END(atanl)
+
+GLOBAL_IEEE754_ENTRY(atan2l)
+
+{ .mfi
+ alloc r32 = ar.pfs, 0, 17, 4, 0
+ fma.s1 Ysq = ArgY_orig, ArgY_orig, f0 // Form y*y
+ nop.i 999
+}
+{ .mfi
+ addl table_ptr1 = @ltoff(Constants_atan#), gp // Address of table pointer
+ fma.s1 Xsq = ArgX_orig, ArgX_orig, f0 // Form x*x
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ld8 table_ptr1 = [table_ptr1] // Get table pointer
+ fnorm.s1 ArgY = ArgY_orig
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnorm.s1 ArgX = ArgX_orig
+ nop.i 999
+}
+;;
+
+{ .mfi
+ getf.exp sign_X = ArgX_orig // Get signexp of x
+ fmerge.s ArgX_abs = f0, ArgX_orig // Form |x|
+ nop.i 999
+}
+;;
+
+{ .mfi
+ getf.exp sign_Y = ArgY_orig // Get signexp of y
+ fmerge.s ArgY_abs = f0, ArgY_orig // Form |y|
+ mov table_base = table_ptr1 // Save base pointer to tables
+}
+;;
+
+{ .mfi
+ ldfd P_hi = [table_ptr1],8 // Load double precision hi part of pi
+ fclass.m p8,p0 = ArgY_orig, 0x1e7 // Test y natval, nan, inf, zero
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfps P_lo, TWO_TO_NEG3 = [table_ptr1], 8 // Load P_lo and constant 2^-3
+ fclass.m p9,p0 = ArgX_orig, 0x1e7 // Test x natval, nan, inf, zero
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 M = f1, f1, f0 // Set M = 1.0
+ nop.i 999
+}
+;;
+
+//
+// Check for everything - if false, then must be pseudo-zero
+// or pseudo-nan (IA unsupporteds).
+//
+{ .mfb
+ nop.m 999
+ fclass.m p0,p12 = ArgX_orig, 0x1FF // Test x unsupported
+(p8) br.cond.spnt ATANL_Y_SPECIAL // Branch if y natval, nan, inf, zero
+}
+;;
+
+// U = max(ArgX_abs,ArgY_abs)
+// V = min(ArgX_abs,ArgY_abs)
+{ .mfi
+ nop.m 999
+ fcmp.ge.s1 p6,p7 = Xsq, Ysq // Test for |x| >= |y| using squares
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fma.s1 V = ArgX_abs, f1, f0 // Set V assuming |x| < |y|
+(p9) br.cond.spnt ATANL_X_SPECIAL // Branch if x natval, nan, inf, zero
+}
+;;
+
+// Now common code for atanl and atan2l
+ATANL_COMMON:
+{ .mfi
+ nop.m 999
+ fclass.m p0,p13 = ArgY_orig, 0x1FF // Test y unsupported
+ shr sign_X = sign_X, 17 // Get sign bit of x
+}
+{ .mfi
+ nop.m 999
+ fma.s1 U = ArgY_abs, f1, f0 // Set U assuming |x| < |y|
+ adds table_ptr1 = 176, table_ptr1 // Point to Q4
+}
+;;
+
+{ .mfi
+(p6) add swap = r0, r0 // Set swap=0 if |x| >= |y|
+(p6) frcpa.s1 E, p0 = ArgY_abs, ArgX_abs // Compute E if |x| >= |y|
+ shr sign_Y = sign_Y, 17 // Get sign bit of y
+}
+{ .mfb
+ nop.m 999
+(p6) fma.s1 V = ArgY_abs, f1, f0 // Set V if |x| >= |y|
+(p12) br.cond.spnt ATANL_UNSUPPORTED // Branch if x unsupported
+}
+;;
+
+// Set p8 if y >=0
+// Set p9 if y < 0
+// Set p10 if |x| >= |y| and x >=0
+// Set p11 if |x| >= |y| and x < 0
+{ .mfi
+ cmp.eq p8, p9 = 0, sign_Y // Test for y >= 0
+(p7) frcpa.s1 E, p0 = ArgX_abs, ArgY_abs // Compute E if |x| < |y|
+(p7) add swap = 1, r0 // Set swap=1 if |x| < |y|
+}
+{ .mfb
+(p6) cmp.eq.unc p10, p11 = 0, sign_X // If |x| >= |y|, test for x >= 0
+(p6) fma.s1 U = ArgX_abs, f1, f0 // Set U if |x| >= |y|
+(p13) br.cond.spnt ATANL_UNSUPPORTED // Branch if y unsupported
+}
+;;
+
+//
+// if p8, s_Y = 1.0
+// if p9, s_Y = -1.0
+//
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 999
+(p8) fadd.s1 s_Y = f0, f1 // If y >= 0 set s_Y = 1.0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fsub.s1 s_Y = f0, f1 // If y < 0 set s_Y = -1.0
+ nop.i 999
+}
+;;
+
+.pred.rel "mutex",p10,p11
+{ .mfi
+ nop.m 999
+(p10) fsub.s1 M = M, f1 // If |x| >= |y| and x >=0, set M=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fadd.s1 M = M, f1 // If |x| >= |y| and x < 0, set M=2.0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.s0 p0, p9 = ArgX_orig, ArgY_orig // Dummy to set denormal flag
+ nop.i 999
+}
+// *************************************************
+// ********************* STEP2 *********************
+// *************************************************
+//
+// Q = E * V
+//
+{ .mfi
+ nop.m 999
+ fmpy.s1 Q = E, V
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fnma.s1 E_hold = E, U, f1 // E_hold = 1.0 - E*U (1) if POLY path
+ nop.i 999
+}
+;;
+
+// Create a single precision representation of the signexp of Q with the
+// 4 most significant bits of the significand followed by a 1 and then 18 0's
+{ .mfi
+ nop.m 999
+ fmpy.s1 P_hi = M, P_hi
+ dep.z special = 0x1, 18, 1 // Form 0x0000000000040000
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 P_lo = M, P_lo
+ add table_ptr2 = 32, table_ptr1
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 A_temp = Q, f1, f0 // Set A_temp if POLY path
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 E = E, E_hold, E // E = E + E*E_hold (1) if POLY path
+ nop.i 999
+}
+;;
+
+//
+// Is Q < 2**(-3)?
+// swap = xor(swap,sign_X)
+//
+{ .mfi
+ nop.m 999
+ fcmp.lt.s1 p9, p0 = Q, TWO_TO_NEG3 // Test Q < 2^-3
+ xor swap = sign_X, swap
+}
+;;
+
+// P_hi = s_Y * P_hi
+{ .mmf
+ getf.exp exponent_Q = Q // Get signexp of Q
+ cmp.eq.unc p7, p6 = 0x00000, swap
+ fmpy.s1 P_hi = s_Y, P_hi
+}
+;;
+
+//
+// if (PR_1) sigma = -1.0
+// if (PR_2) sigma = 1.0
+//
+{ .mfi
+ getf.sig significand_Q = Q // Get significand of Q
+(p6) fsub.s1 sigma = f0, f1
+ nop.i 999
+}
+{ .mfb
+(p9) add table_ptr1 = 128, table_base // Point to P8 if POLY path
+(p7) fadd.s1 sigma = f0, f1
+(p9) br.cond.spnt ATANL_POLY // Branch to POLY if 0 < Q < 2^-3
+}
+;;
+
+//
+// *************************************************
+// ******************** STEP3 **********************
+// *************************************************
+//
+// lookup = b_1 b_2 b_3 B_4
+//
+{ .mmi
+ nop.m 999
+ nop.m 999
+ andcm k = 0x0003, exponent_Q // k=0,1,2,3 for exp_Q=0,-1,-2,-3
+}
+;;
+
+//
+// Generate sign_exp_Q b_1 b_2 b_3 b_4 1 0 0 0 ... 0 in single precision
+// representation. Note sign of Q is always 0.
+//
+{ .mfi
+ cmp.eq p8, p9 = 0x0000, k // Test k=0
+ nop.f 999
+ extr.u lookup = significand_Q, 59, 4 // Extract b_1 b_2 b_3 b_4 for index
+}
+{ .mfi
+ sub sp_exp_Q = 0x7f, k // Form single prec biased exp of Q
+ nop.f 999
+ sub k = k, r0, 1 // Decrement k
+}
+;;
+
+// Form pointer to B index table
+{ .mfi
+ ldfe Q_4 = [table_ptr1], -16 // Load Q_4
+ nop.f 999
+(p9) shl k = k, 8 // k = 0, 256, or 512
+}
+{ .mfi
+(p9) shladd table_ptr2 = lookup, 4, table_ptr2
+ nop.f 999
+ shladd sp_exp_4sig_Q = sp_exp_Q, 4, lookup // Shift and add in 4 high bits
+}
+;;
+
+{ .mmi
+(p8) add table_ptr2 = -16, table_ptr2 // Pointer if original k was 0
+(p9) add table_ptr2 = k, table_ptr2 // Pointer if k was 1, 2, 3
+ dep special = sp_exp_4sig_Q, special, 19, 13 // Form z_hi as single prec
+}
+;;
+
+// z_hi = s exp 1.b_1 b_2 b_3 b_4 1 0 0 0 ... 0
+{ .mmi
+ ldfd Tbl_hi = [table_ptr2], 8 // Load Tbl_hi from index table
+;;
+ setf.s z_hi = special // Form z_hi
+ nop.i 999
+}
+{ .mmi
+ ldfs Tbl_lo = [table_ptr2], 8 // Load Tbl_lo from index table
+;;
+ ldfe Q_3 = [table_ptr1], -16 // Load Q_3
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ldfe Q_2 = [table_ptr1], -16 // Load Q_2
+ nop.m 999
+ nop.i 999
+}
+;;
+
+{ .mmf
+ ldfe Q_1 = [table_ptr1], -16 // Load Q_1
+ nop.m 999
+ nop.f 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 U_prime_hi = V, z_hi, U // U_prime_hi = U + V * z_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnma.s1 V_prime = U, z_hi, V // V_prime = V - U * z_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ mov A_hi = Tbl_hi // Start with A_hi = Tbl_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fsub.s1 U_hold = U, U_prime_hi // U_hold = U - U_prime_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ frcpa.s1 C_hi, p0 = f1, U_prime_hi // C_hi = frcpa(1,U_prime_hi)
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 A_hi = s_Y, A_hi // A_hi = s_Y * A_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 U_prime_lo = z_hi, V, U_hold // U_prime_lo = U_hold + V * z_hi
+ nop.i 999
+}
+;;
+
+// C_hi_hold = 1 - C_hi * U_prime_hi (1)
+{ .mfi
+ nop.m 999
+ fnma.s1 C_hi_hold = C_hi, U_prime_hi, f1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 Res_hi = sigma, A_hi, P_hi // Res_hi = P_hi + sigma * A_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 C_hi = C_hi_hold, C_hi, C_hi // C_hi = C_hi + C_hi * C_hi_hold (1)
+ nop.i 999
+}
+;;
+
+// C_hi_hold = 1 - C_hi * U_prime_hi (2)
+{ .mfi
+ nop.m 999
+ fnma.s1 C_hi_hold = C_hi, U_prime_hi, f1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 C_hi = C_hi_hold, C_hi, C_hi // C_hi = C_hi + C_hi * C_hi_hold (2)
+ nop.i 999
+}
+;;
+
+// C_hi_hold = 1 - C_hi * U_prime_hi (3)
+{ .mfi
+ nop.m 999
+ fnma.s1 C_hi_hold = C_hi, U_prime_hi, f1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 C_hi = C_hi_hold, C_hi, C_hi // C_hi = C_hi + C_hi * C_hi_hold (3)
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 w_hi = V_prime, C_hi // w_hi = V_prime * C_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 wsq = w_hi, w_hi // wsq = w_hi * w_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnma.s1 w_lo = w_hi, U_prime_hi, V_prime // w_lo = V_prime-w_hi*U_prime_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 poly = wsq, Q_4, Q_3 // poly = Q_3 + wsq * Q_4
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnma.s1 w_lo = w_hi, U_prime_lo, w_lo // w_lo = w_lo - w_hi * U_prime_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 poly = wsq, poly, Q_2 // poly = Q_2 + wsq * poly
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 w_lo = C_hi, w_lo // w_lo = = w_lo * C_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 poly = wsq, poly, Q_1 // poly = Q_1 + wsq * poly
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s1 A_lo = Tbl_lo, w_lo // A_lo = Tbl_lo + w_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s0 Q_1 = Q_1, Q_1 // Dummy operation to raise inexact
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 poly = wsq, poly // poly = wsq * poly
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 poly = w_hi, poly // poly = w_hi * poly
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fadd.s1 A_lo = A_lo, poly // A_lo = A_lo + poly
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fadd.s1 A_lo = A_lo, w_hi // A_lo = A_lo + w_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 Res_lo = sigma, A_lo, P_lo // Res_lo = P_lo + sigma * A_lo
+ nop.i 999
+}
+;;
+
+//
+// Result = Res_hi + Res_lo * s_Y (User Supplied Rounding Mode)
+//
+{ .mfb
+ nop.m 999
+ fma.s0 Result = Res_lo, s_Y, Res_hi
+ br.ret.sptk b0 // Exit table path 2^-3 <= V/U < 1
+}
+;;
+
+
+ATANL_POLY:
+// Here if 0 < V/U < 2^-3
+//
+// ***********************************************
+// ******************** STEP4 ********************
+// ***********************************************
+
+//
+// Following:
+// Iterate 3 times E = E + E*(1.0 - E*U)
+// Also load P_8, P_7, P_6, P_5, P_4
+//
+{ .mfi
+ ldfe P_8 = [table_ptr1], -16 // Load P_8
+ fnma.s1 z_lo = A_temp, U, V // z_lo = V - A_temp * U
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnma.s1 E_hold = E, U, f1 // E_hold = 1.0 - E*U (2)
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ldfe P_7 = [table_ptr1], -16 // Load P_7
+;;
+ ldfe P_6 = [table_ptr1], -16 // Load P_6
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe P_5 = [table_ptr1], -16 // Load P_5
+ fma.s1 E = E, E_hold, E // E = E + E_hold*E (2)
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ldfe P_4 = [table_ptr1], -16 // Load P_4
+;;
+ ldfe P_3 = [table_ptr1], -16 // Load P_3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe P_2 = [table_ptr1], -16 // Load P_2
+ fnma.s1 E_hold = E, U, f1 // E_hold = 1.0 - E*U (3)
+ nop.i 999
+}
+{ .mlx
+ nop.m 999
+ movl int_temp = 0x24005 // Signexp for small neg number
+}
+;;
+
+{ .mmf
+ ldfe P_1 = [table_ptr1], -16 // Load P_1
+ setf.exp tmp_small = int_temp // Form small neg number
+ fma.s1 E = E, E_hold, E // E = E + E_hold*E (3)
+}
+;;
+
+//
+//
+// At this point E approximates 1/U to roughly working precision
+// Z = V*E approximates V/U
+//
+{ .mfi
+ nop.m 999
+ fmpy.s1 Z = V, E // Z = V * E
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 z_lo = z_lo, E // z_lo = z_lo * E
+ nop.i 999
+}
+;;
+
+//
+// Now what we want to do is
+// poly1 = P_4 + zsq*(P_5 + zsq*(P_6 + zsq*(P_7 + zsq*P_8)))
+// poly2 = zsq*(P_1 + zsq*(P_2 + zsq*P_3))
+//
+//
+// Fixup added to force inexact later -
+// A_hi = A_temp + z_lo
+// z_lo = (A_temp - A_hi) + z_lo
+//
+{ .mfi
+ nop.m 999
+ fmpy.s1 zsq = Z, Z // zsq = Z * Z
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s1 A_hi = A_temp, z_lo // A_hi = A_temp + z_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 poly1 = zsq, P_8, P_7 // poly1 = P_7 + zsq * P_8
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 poly2 = zsq, P_3, P_2 // poly2 = P_2 + zsq * P_3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 z4 = zsq, zsq // z4 = zsq * zsq
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fsub.s1 A_temp = A_temp, A_hi // A_temp = A_temp - A_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmerge.s tmp = A_hi, A_hi // Copy tmp = A_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 poly1 = zsq, poly1, P_6 // poly1 = P_6 + zsq * poly1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 poly2 = zsq, poly2, P_1 // poly2 = P_2 + zsq * poly2
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 z8 = z4, z4 // z8 = z4 * z4
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s1 z_lo = A_temp, z_lo // z_lo = (A_temp - A_hi) + z_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 poly1 = zsq, poly1, P_5 // poly1 = P_5 + zsq * poly1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 poly2 = poly2, zsq // poly2 = zsq * poly2
+ nop.i 999
+}
+;;
+
+// Create small GR double in case need to raise underflow
+{ .mfi
+ nop.m 999
+ fma.s1 poly1 = zsq, poly1, P_4 // poly1 = P_4 + zsq * poly1
+ dep GR_temp = -1,r0,0,53
+}
+;;
+
+// Create small double in case need to raise underflow
+{ .mfi
+ setf.d FR_temp = GR_temp
+ fma.s1 poly = z8, poly1, poly2 // poly = poly2 + z8 * poly1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 A_lo = Z, poly, z_lo // A_lo = z_lo + Z * poly
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fadd.s1 A_hi = tmp, A_lo // A_hi = tmp + A_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fsub.s1 tmp = tmp, A_hi // tmp = tmp - A_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 A_hi = s_Y, A_hi // A_hi = s_Y * A_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fadd.s1 A_lo = tmp, A_lo // A_lo = tmp + A_lo
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 Res_hi = sigma, A_hi, P_hi // Res_hi = P_hi + sigma * A_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fsub.s1 tmp = P_hi, Res_hi // tmp = P_hi - Res_hi
+ nop.i 999
+}
+;;
+
+//
+// Test if A_lo is zero
+//
+{ .mfi
+ nop.m 999
+ fclass.m p6,p0 = A_lo, 0x007 // Test A_lo = 0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) mov A_lo = tmp_small // If A_lo zero, make very small
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 tmp = A_hi, sigma, tmp // tmp = sigma * A_hi + tmp
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 sigma = A_lo, sigma, P_lo // sigma = A_lo * sigma + P_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 Res_lo = s_Y, sigma, tmp // Res_lo = s_Y * sigma + tmp
+ nop.i 999
+}
+;;
+
+//
+// Test if Res_lo is denormal
+//
+{ .mfi
+ nop.m 999
+ fclass.m p14, p15 = Res_lo, 0x0b
+ nop.i 999
+}
+;;
+
+//
+// Compute Result = Res_lo + Res_hi. Use s3 if Res_lo is denormal.
+//
+{ .mfi
+ nop.m 999
+(p14) fadd.s3 Result = Res_lo, Res_hi // Result for Res_lo denormal
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p15) fadd.s0 Result = Res_lo, Res_hi // Result for Res_lo normal
+ nop.i 999
+}
+;;
+
+//
+// If Res_lo is denormal test if Result equals zero
+//
+{ .mfi
+ nop.m 999
+(p14) fclass.m.unc p14, p0 = Result, 0x07
+ nop.i 999
+}
+;;
+
+//
+// If Res_lo is denormal and Result equals zero, raise inexact, underflow
+// by squaring small double
+//
+{ .mfb
+ nop.m 999
+(p14) fmpy.d.s0 FR_temp = FR_temp, FR_temp
+ br.ret.sptk b0 // Exit POLY path, 0 < Q < 2^-3
+}
+;;
+
+
+ATANL_UNSUPPORTED:
+{ .mfb
+ nop.m 999
+ fmpy.s0 Result = ArgX,ArgY
+ br.ret.sptk b0
+}
+;;
+
+// Here if y natval, nan, inf, zero
+ATANL_Y_SPECIAL:
+// Here if x natval, nan, inf, zero
+ATANL_X_SPECIAL:
+{ .mfi
+ nop.m 999
+ fclass.m p13,p12 = ArgY_orig, 0x0c3 // Test y nan
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p15,p14 = ArgY_orig, 0x103 // Test y natval
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p12) fclass.m p13,p0 = ArgX_orig, 0x0c3 // Test x nan
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p14) fclass.m p15,p0 = ArgX_orig, 0x103 // Test x natval
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p13) fmpy.s0 Result = ArgX_orig, ArgY_orig // Result nan if x or y nan
+(p13) br.ret.spnt b0 // Exit if x or y nan
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p15) fmpy.s0 Result = ArgX_orig, ArgY_orig // Result natval if x or y natval
+(p15) br.ret.spnt b0 // Exit if x or y natval
+}
+;;
+
+
+// Here if x or y inf or zero
+ATANL_SPECIAL_HANDLING:
+{ .mfi
+ nop.m 999
+ fclass.m p6, p7 = ArgY_orig, 0x007 // Test y zero
+ mov special = 992 // Offset to table
+}
+;;
+
+{ .mfb
+ add table_ptr1 = table_base, special // Point to 3pi/4
+ fcmp.eq.s0 p0, p9 = ArgX_orig, ArgY_orig // Dummy to set denormal flag
+(p7) br.cond.spnt ATANL_ArgY_Not_ZERO // Branch if y not zero
+}
+;;
+
+// Here if y zero
+{ .mmf
+ ldfd Result = [table_ptr1], 8 // Get pi high
+ nop.m 999
+ fclass.m p14, p0 = ArgX, 0x035 // Test for x>=+0
+}
+;;
+
+{ .mmf
+ nop.m 999
+ ldfd Result_lo = [table_ptr1], -8 // Get pi lo
+ fclass.m p15, p0 = ArgX, 0x036 // Test for x<=-0
+}
+;;
+
+//
+// Return sign_Y * 0 when ArgX > +0
+//
+{ .mfi
+ nop.m 999
+(p14) fmerge.s Result = ArgY, f0 // If x>=+0, y=0, hi sgn(y)*0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p13, p0 = ArgX, 0x007 // Test for x=0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p14) fmerge.s Result_lo = ArgY, f0 // If x>=+0, y=0, lo sgn(y)*0
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p13) mov GR_Parameter_TAG = 36 // Error tag for x=0, y=0
+ nop.f 999
+ nop.i 999
+}
+;;
+
+//
+// Return sign_Y * pi when ArgX < -0
+//
+{ .mfi
+ nop.m 999
+(p15) fmerge.s Result = ArgY, Result // If x<0, y=0, hi=sgn(y)*pi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p15) fmerge.s Result_lo = ArgY, Result_lo // If x<0, y=0, lo=sgn(y)*pi
+ nop.i 999
+}
+;;
+
+//
+// Call error support function for atan(0,0)
+//
+{ .mfb
+ nop.m 999
+ fadd.s0 Result = Result, Result_lo
+(p13) br.cond.spnt __libm_error_region // Branch if atan(0,0)
+}
+;;
+
+{ .mib
+ nop.m 999
+ nop.i 999
+ br.ret.sptk b0 // Exit for y=0, x not 0
+}
+;;
+
+// Here if y not zero
+ATANL_ArgY_Not_ZERO:
+{ .mfi
+ nop.m 999
+ fclass.m p0, p10 = ArgY, 0x023 // Test y inf
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+ fclass.m p6, p0 = ArgX, 0x017 // Test for 0 <= |x| < inf
+(p10) br.cond.spnt ATANL_ArgY_Not_INF // Branch if 0 < |y| < inf
+}
+;;
+
+// Here if y=inf
+//
+// Return +PI/2 when ArgY = +Inf and ArgX = +/-0 or normal
+// Return -PI/2 when ArgY = -Inf and ArgX = +/-0 or normal
+// Return +PI/4 when ArgY = +Inf and ArgX = +Inf
+// Return -PI/4 when ArgY = -Inf and ArgX = +Inf
+// Return +3PI/4 when ArgY = +Inf and ArgX = -Inf
+// Return -3PI/4 when ArgY = -Inf and ArgX = -Inf
+//
+{ .mfi
+ nop.m 999
+ fclass.m p7, p0 = ArgX, 0x021 // Test for x=+inf
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p6) add table_ptr1 = 16, table_ptr1 // Point to pi/2, if x finite
+ fclass.m p8, p0 = ArgX, 0x022 // Test for x=-inf
+ nop.i 999
+}
+;;
+
+{ .mmi
+(p7) add table_ptr1 = 32, table_ptr1 // Point to pi/4 if x=+inf
+;;
+(p8) add table_ptr1 = 48, table_ptr1 // Point to 3pi/4 if x=-inf
+
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ldfd Result = [table_ptr1], 8 // Load pi/2, pi/4, or 3pi/4 hi
+;;
+ ldfd Result_lo = [table_ptr1], -8 // Load pi/2, pi/4, or 3pi/4 lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmerge.s Result = ArgY, Result // Merge sgn(y) in hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmerge.s Result_lo = ArgY, Result_lo // Merge sgn(y) in lo
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+ fadd.s0 Result = Result, Result_lo // Compute complete result
+ br.ret.sptk b0 // Exit for y=inf
+}
+;;
+
+// Here if y not INF, and x=0 or INF
+ATANL_ArgY_Not_INF:
+//
+// Return +PI/2 when ArgY NOT Inf, ArgY > 0 and ArgX = +/-0
+// Return -PI/2 when ArgY NOT Inf, ArgY < 0 and ArgX = +/-0
+// Return +0 when ArgY NOT Inf, ArgY > 0 and ArgX = +Inf
+// Return -0 when ArgY NOT Inf, ArgY > 0 and ArgX = +Inf
+// Return +PI when ArgY NOT Inf, ArgY > 0 and ArgX = -Inf
+// Return -PI when ArgY NOT Inf, ArgY > 0 and ArgX = -Inf
+//
+{ .mfi
+ nop.m 999
+ fclass.m p7, p9 = ArgX, 0x021 // Test for x=+inf
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fclass.m p6, p0 = ArgX, 0x007 // Test for x=0
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p6) add table_ptr1 = 16, table_ptr1 // Point to pi/2
+ fclass.m p8, p0 = ArgX, 0x022 // Test for x=-inf
+ nop.i 999
+}
+;;
+
+.pred.rel "mutex",p7,p9
+{ .mfi
+(p9) ldfd Result = [table_ptr1], 8 // Load pi or pi/2 hi
+(p7) fmerge.s Result = ArgY, f0 // If y not inf, x=+inf, sgn(y)*0
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p9) ldfd Result_lo = [table_ptr1], -8 // Load pi or pi/2 lo
+(p7) fnorm.s0 Result = Result // If y not inf, x=+inf normalize
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fmerge.s Result = ArgY, Result // Merge sgn(y) in hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fmerge.s Result_lo = ArgY, Result_lo // Merge sgn(y) in lo
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p9) fadd.s0 Result = Result, Result_lo // Compute complete result
+ br.ret.spnt b0 // Exit for y not inf, x=0,inf
+}
+;;
+
+GLOBAL_IEEE754_END(atan2l)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region#)
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_cbrt.S b/libc/sysdeps/ia64/fpu/s_cbrt.S
new file mode 100644
index 000000000..7a74ac19b
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_cbrt.S
@@ -0,0 +1,767 @@
+.file "cbrt.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 05/19/00 New version (modified algorithm)
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/28/03 Updated polynomial coefficients (changed to Remez coefficients),
+// to slightly improve accuracy
+//
+// API
+//==============================================================
+// double cbrt(double)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// Let y= frcpa(a), where a is the argument
+//
+// cbrt(a)= cbrt(a*y)/cbrt(y) = cbrt(1 - (1-a*y)) * (1/cbrt(y))
+//
+// For all values of y, the 3 possible significands of 1/cbrt(y)
+// are stored in a table (T0) to 64 bits of accuracy. (There are
+// 3 possible significands because the exponent of y modulo 3
+// can be 0, 1, or 2.)
+//
+//
+// * cbrt(1 - (1-a*y)) is approximated by a degree-5 polynomial ~
+//
+// ~ 1 - (1/3)*r - (1/9)*r^2 - (5/81)*r^3 - (10/243)*r^4 - (22/729)*r^5
+//
+// in r = 1-a*y.
+//
+//
+// The table values are stored for three exponent values and are
+// then multiplied by e/3 where e is the exponent of the input number.
+// This computation is carried out in parallel with the polynomial
+// evaluation:
+//
+// T= 2^(e/3) * T0
+
+
+
+
+
+//===============
+// input= x
+// C= frcpa(x)
+// r= 1 - C * x
+//
+// Special values
+//==============================================================
+
+
+
+// Registers used
+//==============================================================
+// f6-f15
+// GR_GP, r23-r26, r28-r30
+// p6, p7, p8, p12
+
+ FR_R = f6
+ FR_COEFF1 = f7
+ FR_COEFF2 = f9
+ FR_COEFF3 = f10
+ FR_COEFF4 = f11
+ FR_COEFF5 = f12
+ FR_R2 = f13
+ FR_ARG = f14
+ FR_P23 = f15
+ FR_P25 = f32
+ FR_P15 = f33
+ FR_P1 = f34
+ FR_P45 = f35
+ FR_2EXP = f36
+ FR_TMP63 = f37
+
+ GR_GP = r2
+ GR_ADDR = r2
+ GR_CONST1 = r3
+ GR_I1 = r8
+ GR_EXP = r9
+ GR_ADDR2 = r10
+ GR_IT1 = r11
+ GR_TMP2 = r11
+ GR_EXPON = r15
+ GR_TMP1 = r16
+ GR_TMP6 = r16
+ GR_ITB1 = r17
+ GR_TMP3 = r18
+ GR_TMP4 = r19
+ GR_TMP63 = r19
+ GR_TMP5 = r20
+ GR_EXP_BY_3 = r20
+ GR_CONST4 = r21
+ GR_TMP6 = r22
+ GR_INDEX = r23
+ GR_EBIAS = r24
+ GR_SIGNIF = r25
+ GR_SIGNIF2 = r25
+ GR_TEST = r25
+ GR_ARGEXP = r26
+ GR_CONST2 = r27
+ GR_SIGN = r28
+ GR_REM = r29
+ GR_CONST3 = r30
+ GR_SEXP = r31
+
+
+
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+
+ data8 0xaaaaaaaaaaaaaab4, 0x0000bffd // ~ 1/3
+ data8 0xbfbc71c71c718e45, 0xbfaf9add3c0bbb43
+ data8 0xbfa511edb93dc98d, 0xbf9ee71c45f0dfbc
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+// For every entry B in the frcpa table, this table contains
+// the significands of cbrt(1/B), cbrt(2/B), cbrt(4/B).
+// The index to this table is the same as the frcpa index.
+
+LOCAL_OBJECT_START(T_table)
+
+
+ data8 0x80155c748c374836, 0xa160019ed37fb4ae
+ data8 0xcb51ddcb9e93095e, 0x8040404b0879f7f9
+ data8 0xa1960b5966da4608, 0xcb95f333968ad59b
+ data8 0x806b5dce4b405c10, 0xa1cc5dbe6dc2aab4
+ data8 0xcbda64292d3ffd97, 0x8096b586974669b1
+ data8 0xa202f97995b69c0d, 0xcc1f3184af961596
+ data8 0x80bcd273d952a028, 0xa232fe6eb0c0577d
+ data8 0xcc5bb1ac954d33e2, 0x80e898c52813f2f3
+ data8 0xa26a2582012f6e17, 0xcca12e9831fc6402
+ data8 0x81149add67c2d208, 0xa2a197e5d10465cb
+ data8 0xcce70a67b64f24ad, 0x813b4e2c856b6e9a
+ data8 0xa2d25a532efefbc8, 0xcd24794726477ea5
+ data8 0x8167c1dde03de7aa, 0xa30a5bd6e49e4ab8
+ data8 0xcd6b096a0b70ee87, 0x818ed973b811135e
+ data8 0xa33b9c9b59879e24, 0xcda9177738b15a90
+ data8 0x81bbc0c33e13ec98, 0xa3742fca6a3c1f21
+ data8 0xcdf05f2247dffab9, 0x81e33e69fbe7504a
+ data8 0xa3a5f1273887bf22, 0xce2f0f347f96f906
+ data8 0x820aec524e3c23e9, 0xa3d7ef508ff11574
+ data8 0xce6e0be0cd551a61, 0x823880f78e70b805
+ data8 0xa4115ce30548bc15, 0xceb666b2c347d1de
+ data8 0x826097a62a8e5200, 0xa443df0e53df577a
+ data8 0xcef609b0cb874f00, 0x8288dfe00e9b5eaf
+ data8 0xa4769fa5913c0ec3, 0xcf35fb5447e5c765
+ data8 0x82b15a10c5371624, 0xa4a99f303bc7def5
+ data8 0xcf763c47ee869f00, 0x82da06a527b18937
+ data8 0xa4dcde37779adf4b, 0xcfb6cd3888d71785
+ data8 0x8302e60b635ab394, 0xa5105d46152c938a
+ data8 0xcff7aed4fbfbb447, 0x832bf8b2feec2f0e
+ data8 0xa5441ce89825cb8d, 0xd038e1ce5167e3c6
+ data8 0x83553f0ce00e276b, 0xa5781dad3e54d899
+ data8 0xd07a66d7bfa0ebba, 0x837eb98b50f8322a
+ data8 0xa5ac602406c4e68c, 0xd0bc3ea6b32d1b21
+ data8 0x83a270f44c84f699, 0xa5d9601d95c2c0bc
+ data8 0xd0f4f0e8f36c1bf8, 0x83cc4d7cfcfac5ca
+ data8 0xa60e1e1a2de14745, 0xd1376458e34b037e
+ data8 0x83f65f78a8872b4c, 0xa6431f6e3fbd9658
+ data8 0xd17a2ca133f78572, 0x8420a75f2f7b53c8
+ data8 0xa67864b0d432fda4, 0xd1bd4a80301c5715
+ data8 0x844510461ff14209, 0xa6a6444aa0243c0b
+ data8 0xd1f71682b2fa4575, 0x846fbd91b930bed2
+ data8 0xa6dc094d10f25792, 0xd23ad555f773f059
+ data8 0x84947e18234f3294, 0xa70a574cc02bba69
+ data8 0xd2752c7039a5bf73, 0x84bf92755825045a
+ data8 0xa7409e2af9549084, 0xd2b98ee008c06b59
+ data8 0x84e4ac0ee112ba51, 0xa76f5c64ca2cf13b
+ data8 0xd2f4735ffd700280, 0x8509ef44b86f20be
+ data8 0xa79e4f0babab5dc0, 0xd32f99ed6d9ac0e1
+ data8 0x85359d5d91768427, 0xa7d5579ae5164b85
+ data8 0xd374f0666c75d51c, 0x855b3bd5b7384357
+ data8 0xa804bd3c6fe61cc8, 0xd3b0a7d13618e4a1
+ data8 0x858104f0c415f79a, 0xa8345895e5250a5a
+ data8 0xd3eca2ea53bcec0c, 0x85a6f90390d29864
+ data8 0xa8642a122b44ef0b, 0xd428e23874f13a17
+ data8 0x85d3772fcd56a1dd, 0xa89c38ca18f6108b
+ data8 0xd46f82fe293bc6d3, 0x85f9c982fcc002f3
+ data8 0xa8cc81063b6e87ca, 0xd4ac57e9b7186420
+ data8 0x862047e0e7ea554b, 0xa8fd00bfa409285e
+ data8 0xd4e972becb04e8b8, 0x8646f2a26f7f5852
+ data8 0xa92db8664d5516da, 0xd526d40a7a9b43a3
+ data8 0x866dca21754096b5, 0xa95ea86b75cc2c20
+ data8 0xd5647c5b73917370, 0x8694ceb8dfd17a37
+ data8 0xa98fd141a4992deb, 0xd5a26c4201bd6d13
+ data8 0x86bc00c49e9307e8, 0xa9c1335cae7446ba
+ data8 0xd5e0a45015350a7e, 0x86dccd74fce79610
+ data8 0xa9ea8686f556f645, 0xd614b539c6194104
+ data8 0x870453c845acf90f, 0xaa1c52d17906bb19
+ data8 0xd6537310e224283f, 0x872c089a1e90342c
+ data8 0xaa4e59b046dab887, 0xd6927ab62244c917
+ data8 0x8753ec4a92d16c5e, 0xaa809b9c60d1890b
+ data8 0xd6d1ccc1fc4ef4b7, 0x877bff3aca19f6b4
+ data8 0xaab319102f3f9b33, 0xd71169cea98fdded
+ data8 0x879d88b6fe1c324c, 0xaadd5a18c1e21274
+ data8 0xd746a66a5bc9f6d9, 0x87c5f346dbf98c3a
+ data8 0xab1045f2ac31bdf5, 0xd786ce8f0fae5317
+ data8 0x87e7c653efacef2c, 0xab3ae3ab2df7231e
+ data8 0xd7bc7ff214c4e75a, 0x881089d4e73ffefc
+ data8 0xab6e3f945d1e96fc, 0xd7fd35467a517ed1
+ data8 0x88397e6a366f2a8a, 0xaba1d953a08fa94e
+ data8 0xd83e38838648d815, 0x885bc559e5e1c081
+ data8 0xabcd090db7ef4c3f, 0xd874a1db598b8951
+ data8 0x887e2ee392bb7a93, 0xabf864602d7c323d
+ data8 0xd8ab42205b80edaf, 0x88a7a8587e404257
+ data8 0xac2ca5886ccf9b57, 0xd8ed1849d202f965
+ data8 0x88ca5eda67594784, 0xac5861d4aa441f0f
+ data8 0xd92432bd5a173685, 0x88f4356166bd590e
+ data8 0xac8d183fe3a2fbed, 0xd9669ca45b03c23e
+ data8 0x89173a0acf5ce026, 0xacb93703ff51571e
+ data8 0xd99e3327cf89574e, 0x893a62a098b6a57b
+ data8 0xace5830ad0c3f14b, 0xd9d602b19b100466
+ data8 0x895daf637236ae2c, 0xad11fca5d78b3ff2
+ data8 0xda0e0ba86c096841, 0x89883b9d1c2fa9c5
+ data8 0xad4797fddf91a798, 0xda5195fcdb1c3dce
+ data8 0x89abd8dd374a5d7b, 0xad747701e559ebcb
+ data8 0xda8a1eb87a491f6c, 0x89cf9b1dcd197fa0
+ data8 0xada184a47e9c7613, 0xdac2e230b91c3f84
+ data8 0x89f382a258ea79de, 0xadcec13ab0dda8ff
+ data8 0xdafbe0d0b66aea30, 0x8a178faf06648f29
+ data8 0xadfc2d1a5fd21ba8, 0xdb351b04a8fafced
+ data8 0x8a3bc288b3e1d18a, 0xae29c89a5053c33a
+ data8 0xdb6e9139e33cdd8e, 0x8a601b74f4d1f835
+ data8 0xae5794122b638df9, 0xdba843ded7151ea1
+ data8 0x8a849aba14274764, 0xae858fda8137ae0a
+ data8 0xdbe2336319b61fc8, 0x8aa9409f16cdbc9b
+ data8 0xaeb3bc4ccc56d3d1, 0xdc1c60376789fa68
+ data8 0x8ace0d6bbe2cb316, 0xaee219c374c09920
+ data8 0xdc56cacda82d0cd5, 0x8af301688ab33558
+ data8 0xaf10a899d3235fe7, 0xdc917398f2797814
+ data8 0x8b181cdebe6f3206, 0xaf3f692c341fe8b4
+ data8 0xdccc5b0d90a3e628, 0x8b3d60185fafcb7c
+ data8 0xaf6e5bd7db9ae6c2, 0xdd0781a10469f0f2
+ data8 0x8b62cb603bb2fad0, 0xaf9d80fb081cd91b
+ data8 0xdd42e7ca0b52838f, 0x8b80d7d6bc4104de
+ data8 0xafc35ce063eb3787, 0xdd729ad01c69114d
+ data8 0x8ba68bf73ac74f39, 0xaff2ddcb5f28f03d
+ data8 0xddae749c001fbf5e, 0x8bcc68fb9f9f7335
+ data8 0xb022923b148e05c5, 0xddea8f50a51c69b1
+ data8 0x8bf26f31c534fca2, 0xb0527a919adbf58b
+ data8 0xde26eb69a0f0f111, 0x8c10f86e13a1a1f9
+ data8 0xb078f3ab1d701c65, 0xde576480262399bc
+ data8 0x8c3749916cc6abb5, 0xb0a93a6870649f31
+ data8 0xde943789645933c8, 0x8c5dc4c4f7706032
+ data8 0xb0d9b624d62ec856, 0xded14d58139a28af
+ data8 0x8c7cac3a8c42e3e0, 0xb100a5f53fb3c8e1
+ data8 0xdf025c00bbf2b5c7, 0x8ca373f1b7bf2716
+ data8 0xb131821882f5540a, 0xdf3feb44d723a713
+ data8 0x8cc29907fb951294, 0xb158bf8e4cb04055
+ data8 0xdf715bc16c159be0, 0x8ce9ae4e9492aac8
+ data8 0xb189fd69d56b238f, 0xdfaf66240e29cda8
+ data8 0x8d0911dddbfdad0e, 0xb1b189958e8108e4
+ data8 0xdfe139cbf6e19bdc, 0x8d3075c4f20f04ee
+ data8 0xb1e32a8165b09832, 0xe01fc0fe94d9fc52
+ data8 0x8d5018a9d4de77d5, 0xb20b0678fc271eec
+ data8 0xe051f92ffcc0bd60, 0x8d77cc47dd143515
+ data8 0xb23d0bd3f7592b6e, 0xe090feec9c9a06ac
+ data8 0x8d97af6352739cb7, 0xb26538b2db8420dc
+ data8 0xe0c39d0c9ff862d6, 0x8db7af523167800f
+ data8 0xb28d89e339ceca14, 0xe0f668eeb99f188d
+ data8 0x8ddfd80bc68c32ff, 0xb2c022ca12e55a16
+ data8 0xe1362890eb663139, 0x8e00197e1e7c88fe
+ data8 0xb2e8c6852c6b03f1, 0xe1695c7212aecbaa
+ data8 0x8e207859f77e20e7, 0xb3118f4eda9fe40f
+ data8 0xe19cbf0391bbbbe9, 0x8e40f4ce60c9f8e2
+ data8 0xb33a7d6268109ebe, 0xe1d050901c531e85
+ data8 0x8e69ba46cf2fde4d, 0xb36ddbc5ea70ec55
+ data8 0xe2110903b4f4047a, 0x8e8a7a00bd7ae63e
+ data8 0xb3971e9b39264023, 0xe2450559b4d80b6d
+ data8 0x8eab57ef1cf2f529, 0xb3c0877ecc18e24a
+ data8 0xe27931a231554ef3, 0x8ecc5442cffb1dad
+ data8 0xb3ea16ae3a6c905f, 0xe2ad8e2ac3c5b04b
+ data8 0x8eed6f2d2a4acbfe, 0xb413cc67aa0e4d2d
+ data8 0xe2e21b41b9694cce, 0x8f0ea8dff24441ff
+ data8 0xb43da8e9d163e1af, 0xe316d93615862714
+ data8 0x8f385c95d696b817, 0xb47233773b84d425
+ data8 0xe3590bd86a0d30f9, 0x8f59dc43edd930f3
+ data8 0xb49c6825430fe730, 0xe38e38e38e38e38e
+ data8 0x8f7b7b5f5ffad1c4, 0xb4c6c46bcdb27dcf
+ data8 0xe3c397d1e6db7839, 0x8f9d3a1bea165f38
+ data8 0xb4f1488c0b35d26f, 0xe3f928f5953feb9e
+ data8 0x8fbf18adc34b66da, 0xb51bf4c7c51f0168
+ data8 0xe42eeca17c62886c, 0x8fe117499e356095
+ data8 0xb546c9616087ab9c, 0xe464e32943446305
+ data8 0x90033624aa685f8d, 0xb571c69bdffd9a70
+ data8 0xe49b0ce15747a8a2, 0x9025757495f36b86
+ data8 0xb59cecbae56984c3, 0xe4d16a1eee94e9d4
+ data8 0x903f3a5dcc091203, 0xb5bd64512bb14bb7
+ data8 0xe4fa52107353f67d, 0x9061b2fceb2bdbab
+ data8 0xb5e8d2a4bf5ba416, 0xe5310a471f4d2dc3
+ data8 0x90844ca7211032a7, 0xb6146a9a1bc47819
+ data8 0xe567f6f1c2b9c224, 0x90a7079403e6a15d
+ data8 0xb6402c7749d621c0, 0xe59f18689a9e4c9a
+ data8 0x90c9e3fbafd63799, 0xb66c1882fb435ea2
+ data8 0xe5d66f04b8a68ecf, 0x90ece216c8a16ee4
+ data8 0xb6982f048c999a56, 0xe60dfb2005c192e9
+ data8 0x9110021e7b516f0a, 0xb6c47044075b4142
+ data8 0xe645bd1544c7ea51, 0x912a708a39be9075
+ data8 0xb6e5bd6bfd02bafd, 0xe66fb21b505b20a0
+ data8 0x914dcc7b31146370, 0xb7124a2736ff8ef2
+ data8 0xe6a7d32af4a7c59a, 0x91714af8cfe984d5
+ data8 0xb73f026a01e94177, 0xe6e02b129c6a5ae4
+ data8 0x918c00a6f3795e97, 0xb760a959f1d0a7a7
+ data8 0xe70a9136a7403039, 0x91afbc299ed0295d
+ data8 0xb78dae7e06868ab0, 0xe74349fb2d92a589
+ data8 0x91d39add3e958db0, 0xb7badff8ad9e4e02
+ data8 0xe77c3a9c86ed7d42, 0x91ee9920a8974d92
+ data8 0xb7dce25b8e17ae9f, 0xe7a713f88151518a
+ data8 0x9212b5fcac537c19, 0xb80a6226904045e2
+ data8 0xe7e067453317ed2b, 0x9236f6b256923fcf
+ data8 0xb8380f1cafd73c1c, 0xe819f37a81871bb5
+ data8 0x92523ee6f90dcfc3, 0xb85a6ea8e321b4d8
+ data8 0xe8454236bfaeca14, 0x9276bef031e6eb79
+ data8 0xb8886b684ae7d2fa, 0xe87f32f24c3fc90e
+ data8 0x929236ec237a24ad, 0xb8ab0726fa00cf5d
+ data8 0xe8aacd8688892ba6, 0x92b6f70b7efe9dc3
+ data8 0xb8d954a4d13b7cb1, 0xe8e523fd32f606f7
+ data8 0x92d29f61eec7dc2b, 0xb8fc2d4f6cd9f04a
+ data8 0xe9110b5311407927, 0x92f7a05d5b8ba92f
+ data8 0xb92acc851476b1ab, 0xe94bc8bf0c108fa3
+ data8 0x931379a403be5c16, 0xb94de2d841a184c2
+ data8 0xe977fdc439c2ca3c, 0x9338bc44de2e3f34
+ data8 0xb97cd4c36c92693c, 0xe9b3236528fc349e
+ data8 0x9354c71412c69486, 0xb9a0297f172665e3
+ data8 0xe9dfa70b745ac1b4, 0x937a4c273907e262
+ data8 0xb9cf6f21e36c3924, 0xea1b36268d0eaa38
+ data8 0x93968919f6e7975d, 0xb9f3030951267208
+ data8 0xea480963fd394197, 0x93bc516fdd4680c9
+ data8 0xba229d6a618e7c59, 0xea84034425f27484
+ data8 0x93d8c123d9be59b2, 0xba467144459f9855
+ data8 0xeab12713138dd1cc, 0x93f546c955e60076
+ data8 0xba6a60c3c48f1a4b, 0xeade6db73a5e503b
+ data8 0x941b70a65879079f, 0xba9a76056b67ee7a
+ data8 0xeb1b0268343b121b, 0x943829f337410591
+ data8 0xbabea699563ada6e, 0xeb489b0b2bdb5f14
+ data8 0x9454f995765bc4d2, 0xbae2f350b262cc4b
+ data8 0xeb765721e85f03d0, 0x947b86b57f5842ed
+ data8 0xbb1385a23be24e57, 0xebb389645f222f62
+ data8 0x94988aeb23470f86, 0xbb3814975e17c680
+ data8 0xebe198f090607e0c, 0x94b5a5dc9695f42a
+ data8 0xbb5cc031009bf467, 0xec0fcc9321024509
+ data8 0x94d2d7a9170d8b42, 0xbb81889680024764
+ data8 0xec3e247da8b82f61, 0x94f9e87dd78bf019
+ data8 0xbbb2c0d8703ae95d, 0xec7c27d21321c9f7
+ data8 0x95175019a503d89e, 0xbbd7cd09ba3c5463
+ data8 0xecaad5278824e453, 0x9534cefa625fcb3a
+ data8 0xbbfcf68c4977718f, 0xecd9a76d097d4e77
+ data8 0x955265405c491a25, 0xbc223d88cfc88eee
+ data8 0xed089ed5dcd99446, 0x9570130c1f9bb857
+ data8 0xbc47a2284fee4ff8, 0xed37bb95add09a1c
+ data8 0x9597ca4119525184, 0xbc79ac0916ed7b8a
+ data8 0xed76c70508f904b6, 0x95b5af6fb5aa4d3c
+ data8 0xbc9f5670d1a13030, 0xeda63bb05e7f93c6
+ data8 0x95d3ac9273aafd7a, 0xbcc51f068cb95c1d
+ data8 0xedd5d661daed2dc4, 0x95f1c1cafdfd3684
+ data8 0xbceb05f4b30a9bc0, 0xee05974eef86b903
+ data8 0x960fef3b430b8d5f, 0xbd110b6604c7d306
+ data8 0xee357ead791fc670, 0x962e350575b409c5
+ data8 0xbd372f8598620f19, 0xee658cb3c134a463
+ data8 0x964c934c0dfc1708, 0xbd5d727edb6b3c7e
+ data8 0xee95c1987f080211, 0x966b0a31c9c6bc7d
+ data8 0xbd83d47d937bbc6d, 0xeec61d92d8c4314f
+ data8 0x968999d9ad8d264e, 0xbdaa55addf1ae47d
+ data8 0xeef6a0da64a014ac, 0x96a8426705198795
+ data8 0xbdd0f63c36aa73f0, 0xef274ba72a07c811
+ data8 0x96c703fd64445ee5, 0xbdf7b6556d550a15
+ data8 0xef581e31a2c91260, 0x96e5dec0a7b4268d
+ data8 0xbe1e9626b1ffa96b, 0xef8918b2bc43aec6
+ data8 0x9704d2d4f59f79f3, 0xbe4595dd903e5371
+ data8 0xefba3b63d89d7cbf, 0x9723e05ebe91b9b0
+ data8 0xbe6cb5a7f14bc935, 0xefeb867ecffaa607
+ data8 0x97430782be323831, 0xbe93f5b41d047cf7
+ data8 0xf01cfa3df1b9c9fa, 0x97624865fc0df8bf
+ data8 0xbebb5630bae4c15f, 0xf04e96dc05b43e2d
+ data8 0x9781a32dcc640b2a, 0xbee2d74cd30a430c
+ data8 0xf0805c944d827454, 0x97a117ffd0f48e46
+ data8 0xbf0a7937cf38d981, 0xf0b24ba285c495cb
+ data8 0x97c0a701f9d263c9, 0xbf323c217be2bc8c
+ data8 0xf0e46442e76f6569, 0x97e0505a8637a036
+ data8 0xbf5a203a09342bbb, 0xf116a6b2291d7896
+ data8 0x97f57a9fb0b08c6e, 0xbf74cad1c14ebfc4
+ data8 0xf1383fa9e9b5b381, 0x9815503365914a9d
+ data8 0xbf9ce6a497a89f78, 0xf16ac84f90083b9b
+ data8 0x98354085054fd204, 0xbfc52428bec6e72f
+ data8 0xf19d7b686dcb03d7, 0x98554bbbf8a77902
+ data8 0xbfed838fddab024b, 0xf1d0593311db1757
+ data8 0x987571fffb7f94f6, 0xc016050c0420981a
+ data8 0xf20361ee8f1c711e, 0x9895b3791dd03c23
+ data8 0xc03ea8cfabddc330, 0xf23695da7de51d3f
+ data8 0x98ab43a5fc65d0c8, 0xc059d3cbd65ddbce
+ data8 0xf258d095e465cc35, 0x98cbb2d196bd713d
+ data8 0xc082b122a3c78c9d, 0xf28c4d0bfc982b34
+ data8 0x98ec3d9ec7b6f21a, 0xc0abb1499ae736c4
+ data8 0xf2bff55eb3f0ea71, 0x990ce436db5e8344
+ data8 0xc0d4d474c3aedaaf, 0xf2f3c9cf9884636e
+ data8 0x9922b8218160967a, 0xc0f054ca33eb3437
+ data8 0xf31670135ab9cc0f, 0x99438d686f75779d
+ data8 0xc119b2c67e600ed0, 0xf34a8e9f0b54cdfb
+ data8 0x99647eea131fa20b, 0xc1433453de2033ff
+ data8 0xf37ed9fa6b8add3f, 0x997a85045a47c6d0
+ data8 0xc15ef3e44e10032d, 0xf3a1cfe884ef6bb6
+ data8 0x999ba5f14f8add02, 0xc188b130431d80e6
+ data8 0xf3d66689dcc8e8d3, 0x99bce38b5465ecae
+ data8 0xc1b2929d6067730e, 0xf40b2ab069d5c96a
+ data8 0x99d31ca0887f30f9, 0xc1ce9268f31cc734
+ data8 0xf42e718b90c8bc16, 0x99f48a669c74c09e
+ data8 0xc1f8b0877c1b0c08, 0xf463822a0a3b4b00
+ data8 0x9a16154eb445c873, 0xc222f35a87b415ba
+ data8 0xf498c1076015faf8, 0x9a2c822ec198d667
+ data8 0xc23f3467349e5c88, 0xf4bc5a19a33990b5
+ data8 0x9a4e3e080cd91b78, 0xc269b4e40e088c01
+ data8 0xf4f1e6a7d6f5425f, 0x9a70177afe52322e
+ data8 0xc2945aac24daaf6e, 0xf527a232cf6be334
+ data8 0x9a86b8fa94eebe10, 0xc2b0de05e43c1d66
+ data8 0xf54b8ecdcda90851, 0x9aa8c42866ae2958
+ data8 0xc2dbc275e1229d09, 0xf5819949c7ad87b4
+ data8 0x9abf86f9e12fc45e, 0xc2f86fca9d80eeff
+ data8 0xf5a5bac9213b48a9, 0x9ae1c462fc05f49d
+ data8 0xc323938449a2587e, 0xf5dc1501f324a812
+ data8 0x9af8a8dc936b84d0, 0xc3406b40a538ed20
+ data8 0xf6006bee86b5589e, 0x9b1b19033be35730
+ data8 0xc36bcee8211d15e0, 0xf63716b2fa067fa4
+ data8 0x9b3da7daf04c2892, 0xc397593adf2ba366
+ data8 0xf66df22fb6132b9c, 0x9b54c2e4c8a9012b
+ data8 0xc3b475b6206155d5, 0xf6929fb98225deb1
+ data8 0x9b77854e6c661200, 0xc3e0410243b97383
+ data8 0xf6c9cd13021e3fea, 0x9b8ec2e678d56d2f
+ data8 0xc3fd890709833d37, 0xf6eeb177472cedae
+ data8 0x9ba60e6a5ca133b6, 0xc41ae295f7e7fa06
+ data8 0xf713abf4cb0b3afb, 0x9bc919ea66a151a4
+ data8 0xc44709f7bb8a4dd2, 0xf74b4d5333684ef1
+ data8 0x9be0887c09ef82bb, 0xc4648fb0e0bec4c1
+ data8 0xf7707f75a72f8e94, 0x9c03c8d5fffc3503
+ data8 0xc490f9a94695ba14, 0xf7a874b97927af44
+ data8 0x9c1b5ad21a81cbb9, 0xc4aeac0173b7d390
+ data8 0xf7cddf140aedf1d8, 0x9c3ed09216e9ca02
+ data8 0xc4db5941007aa853, 0xf806291bacb7f7a9
+ data8 0x9c568656c0423def, 0xc4f938aec206291a
+ data8 0xf82bcc43b92eafef, 0x9c7a320af242ce60
+ data8 0xc52629e899dfd622, 0xf8646bf0defb759e
+ data8 0x9c920bf7a8c01dc2, 0xc54436e44043b965
+ data8 0xf88a487dfc3ff5f7, 0x9ca9f475d98b159c
+ data8 0xc562563abf9ea07f, 0xf8b03c2b46cdc17f
+ data8 0x9ccdeca60e80b5f8, 0xc58fa7d1dc42921c
+ data8 0xf8e95541c152ae7a, 0x9ce5f9d4653d4902
+ data8 0xc5adf561b91e110a, 0xf90f832c2700c160
+ data8 0x9cfe15cb38bfdd8e, 0xc5cc5591bdbd82fa
+ data8 0xf935c88e0c7f419b, 0x9d225b983f6c1f96
+ data8 0xc5fa08f1ff20593c, 0xf96f5cd84fd86873
+ data8 0x9d3a9cca32261ed7, 0xc618980a79ce6862
+ data8 0xf995dd53ebdd9d6d, 0x9d52ecfccebe1768
+ data8 0xc6373a09e34b50fa, 0xf9bc75a034436a41
+ data8 0x9d77818d95b82f86, 0xc66550a6e0baaf35
+ data8 0xf9f686f26d5518de, 0x9d8ff7893fa4706c
+ data8 0xc6842241926342c9, 0xfa1d5b39b910a8c5
+ data8 0x9da87cbef36f2a5e, 0xc6a3070b7c93bb9e
+ data8 0xfa4447acc4ecbfd2, 0x9dcd6140b4a35aeb
+ data8 0xc6d18260bb84081b, 0xfa7ed7e51e6fdfb4
+ data8 0x9de60cd06dc6e2d4, 0xc6f0977c9416828b
+ data8 0xfaa601394d49a1a0, 0x9dfec7d4cc43b76f
+ data8 0xc70fc0117c641630, 0xfacd431644ce0e40
+ data8 0x9e17925ec9fccc4a, 0xc72efc34d7e615be
+ data8 0xfaf49d96f7a75909, 0x9e3cdf6db57dc075
+ data8 0xc75dfb441594141e, 0xfb2fd3c65e562fd5
+ data8 0x9e55d110b63637a8, 0xc77d68aa019bda4c
+ data8 0xfb576c5762024805, 0x9e6ed27594550d2e
+ data8 0xc79ce9ea478dbc4f, 0xfb7f1debc22c4040
+ data8 0x9e87e3adc385d393, 0xc7bc7f1ae453219d
+ data8 0xfba6e89f32d0190a, 0x9ead9b54b37a1055
+ data8 0xc7ec0476e15e141a, 0xfbe2c803a0894893
+ data8 0x9ec6d46a3d7de215, 0xc80bcbe16f1d540f
+ data8 0xfc0ad1ff0ed9ecf0, 0x9ee01d9108be3154
+ data8 0xc82ba78a5d349735, 0xfc32f57bdfbcbe7f
+ data8 0x9ef976db07288d04, 0xc84b978847a06b87
+ data8 0xfc5b32968f99b21c, 0x9f12e05a4759ec25
+ data8 0xc86b9bf1ee817bc6, 0xfc83896bc861ab08
+ data8 0x9f2c5a20f4da6668, 0xc88bb4de3667cdf4
+ data8 0xfcabfa1861ed4815, 0x9f52af78ed1733ca
+ data8 0xc8bc00e7fe9e23a3, 0xfce8d3cea7d3163e
+ data8 0x9f6c52426a39d003, 0xc8dc4d7ff2d25232
+ data8 0xfd118595143ee273, 0x9f860593d42fd7f3
+ data8 0xc8fcaeebcb40eb47, 0xfd3a519943d4865a
+ data8 0x9f9fc97fdb96bd51, 0xc91d25431426a663
+ data8 0xfd6337f8e1ae5a4b, 0x9fb99e194f4a7037
+ data8 0xc93db09d7fdb2949, 0xfd8c38d1c8e927eb
+ data8 0x9fd383731ca51db9, 0xc95e5112e721582a
+ data8 0xfdb5544205095a53, 0x9fed79a04fbf9423
+ data8 0xc97f06bb49787677, 0xfdde8a67d2613531
+ data8 0xa00780b413b24ee8, 0xc99fd1aecd6e1b06
+ data8 0xfe07db619e781611, 0xa02eab2c4474b0cd
+ data8 0xc9d12a3e27bb1625, 0xfe460768d80bf758
+ data8 0xa048dcd51ccfd142, 0xc9f22ad82ba3d5f0
+ data8 0xfe6f9bfb06cd32f6, 0xa0631fa894b11b8d
+ data8 0xca134113105e67b2, 0xfe994bcd3d14fcc2
+ data8 0xa07d73ba65e680af, 0xca346d07b045a876
+ data8 0xfec316fecaf3f2ab, 0xa097d91e6aaf71b0
+ data8 0xca55aecf0e94bb88, 0xfeecfdaf33fadb80
+ data8 0xa0b24fe89e02602f, 0xca77068257be9bab
+ data8 0xff16fffe2fa8fad6, 0xa0ccd82d1bd2f68b
+ data8 0xca98743ae1c693a8, 0xff411e0ba9db886d
+ data8 0xa0e77200215909e6, 0xcab9f8122c99a101
+ data8 0xff6b57f7c33e4e9a, 0xa1021d760d584855
+ data8 0xcadb9221e268c3b5, 0xff95ade2d1bd7358
+ data8 0xa11cdaa36068a57d, 0xcafd4283d8043dfd
+ data8 0xffc01fed60f86fb5, 0xa137a99cbd3f880b
+ data8 0xcb1f09520d37c6fb, 0xffeaae3832b63956
+LOCAL_OBJECT_END(T_table)
+
+
+
+
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(cbrt)
+
+
+{.mfi
+ // get significand
+ getf.sig GR_SIGNIF = f8
+ // normalize a
+ fma.s1 FR_ARG = f8, f1, f0
+ // GR_GP = pointer to C_1,..., C_5 followed by T_table
+ addl GR_GP = @ltoff(poly_coeffs), gp ;;
+}
+
+{.mfi
+ // get exponent
+ getf.exp GR_ARGEXP = f8
+ // will continue only for normal/denormal numbers
+ fclass.m.unc p12, p13 = f8, 0x1e7
+ // GR_CONST4 = bias-((2^{12}-1)/3)-63 = 0xffff-0x555-0x3f = 0xfa6b
+ mov GR_CONST4 = 0xfa6b ;;
+}
+
+{.mlx
+ mov GR_CONST2 = 0x20000
+ // GR_CONST3 = 2^52
+ movl GR_CONST3 = 0x8000000000000000 ;;
+}
+
+.pred.rel "mutex", p12, p13
+{.mfi
+ // load start address for C_1,..., C_5 followed by T_table
+ ld8 GR_ADDR = [ GR_GP ]
+ // y = frcpa(a)
+ (p13) frcpa.s0 f8, p0 = f1, f8
+ // p7 = 1 if denormal input
+ cmp.gtu p7, p0 = GR_CONST3, GR_SIGNIF
+}
+{.mfb
+ nop.m 0
+ // if argument is 0, +/-Infinity, NaN, or NaTVal, then return
+ (p12) fma.d.s0 f8 = f8, f1, f0
+ (p12) br.ret.spnt b0 ;;
+}
+
+{.mmi
+ // get exponent (for denormal input)
+ (p7) getf.exp GR_ARGEXP = FR_ARG
+ // get normalized significand (for denormal input)
+ (p7) getf.sig GR_SIGNIF = FR_ARG
+ // GR_CONST1 = bias-(2^{12}-1)
+ mov GR_CONST1 = 0xf000 ;;
+}
+
+{.mii
+ // get GR_SIGN = sign
+ and GR_SIGN = GR_ARGEXP, GR_CONST2
+ // eliminate leading 1 from GR_I1 = 1st table index
+ shl GR_I1 = GR_SIGNIF, 1
+ // eliminate sign from exponent
+ andcm GR_EXP = GR_ARGEXP, GR_CONST2 ;;
+}
+
+{.mib
+ add GR_ADDR2 = 32, GR_ADDR
+ // GR_IT1 = 1st table index (y_index, 8 bits)
+ shr.u GR_IT1 = GR_I1, 56
+ nop.b 0
+}
+{.mib
+ // load C_1
+ ldfe FR_COEFF1 = [ GR_ADDR ], 16
+ // subtract bias from GR_EXPON = exponent
+ sub GR_EXPON = GR_EXP, GR_CONST1
+ nop.b 0 ;;
+}
+
+{.mib
+ // load C_2, C_3
+ ldfpd FR_COEFF2, FR_COEFF3 = [ GR_ADDR ]
+ // 1: exponent* = 5; // (2^{16}-1)/3 = 0x5555
+ shladd GR_TMP1 = GR_EXPON, 2, GR_EXPON
+ nop.b 0
+}
+{.mib
+ // load C_4, C_5
+ ldfpd FR_COEFF4, FR_COEFF5 = [ GR_ADDR2 ], 16
+ // GR_TMP2 = 3*y_index
+ shladd GR_TMP2 = GR_IT1, 1, GR_IT1
+ nop.b 0 ;;
+}
+
+{.mfi
+ // GR_TMP6 = (5*expon)*16+5*expon = (0x55)*expon
+ shladd GR_TMP6 = GR_TMP1, 4, GR_TMP1
+ // r = 1-a*y
+ fnma.s1 FR_R = f8, FR_ARG, f1
+ // adjust T_table pointer by 1st index
+ shladd GR_ITB1 = GR_TMP2, 3, GR_ADDR2 ;;
+}
+
+{.mii
+ // eliminate leading 1 from significand
+ add GR_SIGNIF2 = GR_SIGNIF, GR_SIGNIF
+ // GR_TMP3 = (0x5500)*expon
+ shl GR_TMP3 = GR_TMP6, 8 ;;
+ // GR_TMP4 = (0x5555)*expon
+ add GR_TMP4 = GR_TMP3, GR_TMP6 ;;
+}
+
+{.mii
+ // GR_TMP5 = (0x5556)*expon // 0x5556 = (2^{16}+2)/3
+ add GR_TMP5 = GR_TMP4, GR_EXPON
+ nop.i 0 ;;
+ // GR_EXP_BY_3 = floor(expon/3)
+ shr GR_EXP_BY_3 = GR_TMP5, 16 ;;
+}
+
+{.mfi
+ // GR_TMP6 = 3*exponent
+ shladd GR_TMP6 = GR_EXP_BY_3, 1, GR_EXP_BY_3
+ // r*r
+ fma.s1 FR_R2 = FR_R, FR_R, f0
+ // bias exponent
+ add GR_EBIAS = GR_CONST4, GR_EXP_BY_3 ;;
+}
+
+{.mfi
+ // get remainder of exponent/3
+ sub GR_REM = GR_EXPON, GR_TMP6
+ // c2+c3*r
+ fma.s1 FR_P23 = FR_COEFF3, FR_R, FR_COEFF2
+ nop.i 0
+}
+{.mfi
+ // add sign to exponent
+ or GR_SEXP = GR_EBIAS, GR_SIGN
+ // c4+c5*r
+ fma.s1 FR_P45 = FR_COEFF5, FR_R, FR_COEFF4
+ mov GR_TMP63 = 63+0xffff ;;
+}
+
+{.mmi
+ // FR_2EXP = sign*2^{exponent/3}
+ setf.exp FR_2EXP = GR_SEXP
+ // adjust T_table pointer by 2nd index
+ shladd GR_INDEX = GR_REM, 3, GR_ITB1
+ // is the argument of the form 2^(3*k) ?
+ // get (significand - leading 1) | (exponent mod 3)
+ or GR_TEST = GR_REM, GR_SIGNIF2 ;;
+}
+
+{.mmi
+ // 2^63
+ setf.exp FR_TMP63 = GR_TMP63
+ // load T
+ ldf8 f8 = [ GR_INDEX ]
+ // is the argument of the form 2^(3*k) ?
+ cmp.eq p14, p0 = GR_TEST, r0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // (c2+c3*r)+r^2*(c4+c5*r)
+ fma.s1 FR_P25 = FR_P45, FR_R2, FR_P23
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // c1*r
+ fma.s1 FR_P1 = FR_COEFF1, FR_R, f0
+ nop.i 0 ;;
+}
+
+{.mfb
+ nop.m 0
+ (p14) fma.d.s0 f8 = FR_2EXP, FR_TMP63, f0
+ (p14) br.ret.spnt b0 ;;
+}
+
+{.mfi
+ nop.m 0
+ // P = c1*r+r^2* [ (c2+c3*r)+r^2*(c4+c5*r) ]
+ fma.s1 FR_P15 = FR_P25, FR_R2, FR_P1
+ nop.i 0
+}
+{.mfi
+ nop.m 0
+ // T' = T*(2^exp)
+ fma.s1 f8 = f8, FR_2EXP, f0
+ nop.i 0 ;;
+}
+
+{.mfb
+ nop.m 0
+ // result = T'+T'*P
+ fma.d.s0 f8 = f8, FR_P15, f8
+ br.ret.sptk b0 ;;
+}
+
+
+GLOBAL_LIBM_END(cbrt)
diff --git a/libc/sysdeps/ia64/fpu/s_cbrtf.S b/libc/sysdeps/ia64/fpu/s_cbrtf.S
new file mode 100644
index 000000000..612fb85ea
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_cbrtf.S
@@ -0,0 +1,765 @@
+.file "cbrtf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 05/18/00 New version (modified algorithm)
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/28/03 Rescheduled some instructions for better performance
+// on Itanium 2, and reformatted
+//
+// API
+//==============================================================
+// float cbrtf(float)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// Let y= frcpa(a), where a is the argument
+//
+// cbrt(a)= cbrt(a*y)/cbrt(y) = cbrt(1 - (1-a*y)) * (1/cbrt(y))
+//
+// For all values of y, the 3 possible significands of 1/cbrt(y)
+// are stored in a table (T0) to 64 bits of accuracy. (There are
+// 3 possible significands because the exponent of y modulo 3
+// can be 0, 1, or 2.)
+//
+//
+// * cbrt(1 - (1-a*y)) is approximated by a degree-2 polynomial
+//
+// 1 - (1/3)*r - (1/9)*r^2
+//
+// in r = 1-a*y.
+//
+// The table values are stored for three exponent values and are
+// then multiplied by 2^(e/3) where e is the exponent of the input number.
+// This computation is carried out in parallel with the polynomial
+// evaluation:
+//
+// T= 2^(e/3) * T0
+
+
+
+
+
+//===============
+// input= x
+// C= frcpa(x)
+// r= 1 - C * x
+//
+// Special values
+//==============================================================
+
+
+
+// Registers used
+//==============================================================
+// p6, p7, p8, p12
+
+ FR_R = f6
+ FR_COEFF1 = f7
+ FR_COEFF2 = f9
+ FR_T0 = f10
+ FR_T1 = f11
+ FR_T2 = f12
+ FR_2M63 = f13
+ FR_ARG = f14
+ FR_Y = f15
+
+ GR_GP = r2
+ GR_ADDR = r2
+ GR_TMP5 = r3
+ GR_CONST = r8
+ GR_TMP63 = r8
+ GR_SIGN = r9
+ GR_CT2 = r10
+ GR_CT3 = r11
+ GR_TMP4 = r14
+ GR_EBIAS3 = r15
+ GR_REM = r16
+ GR_SEXP = r17
+ GR_2P63 = r18
+ GR_SIGNIF = r19
+ GR_I1 = r20
+ GR_EBIAS = r21
+ GR_EXP = r22
+ GR_IT1 = r23
+ GR_E5 = r24
+ GR_IT1_3 = r25
+ GR_TP1 = r26
+ GR_TMP = r27
+ GR_TMP2 = r28
+ GR_TMP3 = r29
+ GR_EXP3 = r30
+ GR_ARGEXP = r31
+
+
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+
+ data8 0xaaaab19b7e1f5ef9, 0x00003ffd // ~ 1/3
+ data8 0xe38e5192a5a8e56c, 0x00003ffb // ~ 1/9
+LOCAL_OBJECT_END(poly_coeffs)
+
+// For every entry B in the frcpa table, this table contains
+// the significands of cbrt(1/B), cbrt(2/B), cbrt(4/B).
+// The index to this table is the same as the frcpa index.
+
+LOCAL_OBJECT_START(T_table)
+
+ data8 0x80155c748c374836, 0xa160019ed37fb4ae
+ data8 0xcb51ddcb9e93095e, 0x8040404b0879f7f9
+ data8 0xa1960b5966da4608, 0xcb95f333968ad59b
+ data8 0x806b5dce4b405c10, 0xa1cc5dbe6dc2aab4
+ data8 0xcbda64292d3ffd97, 0x8096b586974669b1
+ data8 0xa202f97995b69c0d, 0xcc1f3184af961596
+ data8 0x80bcd273d952a028, 0xa232fe6eb0c0577d
+ data8 0xcc5bb1ac954d33e2, 0x80e898c52813f2f3
+ data8 0xa26a2582012f6e17, 0xcca12e9831fc6402
+ data8 0x81149add67c2d208, 0xa2a197e5d10465cb
+ data8 0xcce70a67b64f24ad, 0x813b4e2c856b6e9a
+ data8 0xa2d25a532efefbc8, 0xcd24794726477ea5
+ data8 0x8167c1dde03de7aa, 0xa30a5bd6e49e4ab8
+ data8 0xcd6b096a0b70ee87, 0x818ed973b811135e
+ data8 0xa33b9c9b59879e24, 0xcda9177738b15a90
+ data8 0x81bbc0c33e13ec98, 0xa3742fca6a3c1f21
+ data8 0xcdf05f2247dffab9, 0x81e33e69fbe7504a
+ data8 0xa3a5f1273887bf22, 0xce2f0f347f96f906
+ data8 0x820aec524e3c23e9, 0xa3d7ef508ff11574
+ data8 0xce6e0be0cd551a61, 0x823880f78e70b805
+ data8 0xa4115ce30548bc15, 0xceb666b2c347d1de
+ data8 0x826097a62a8e5200, 0xa443df0e53df577a
+ data8 0xcef609b0cb874f00, 0x8288dfe00e9b5eaf
+ data8 0xa4769fa5913c0ec3, 0xcf35fb5447e5c765
+ data8 0x82b15a10c5371624, 0xa4a99f303bc7def5
+ data8 0xcf763c47ee869f00, 0x82da06a527b18937
+ data8 0xa4dcde37779adf4b, 0xcfb6cd3888d71785
+ data8 0x8302e60b635ab394, 0xa5105d46152c938a
+ data8 0xcff7aed4fbfbb447, 0x832bf8b2feec2f0e
+ data8 0xa5441ce89825cb8d, 0xd038e1ce5167e3c6
+ data8 0x83553f0ce00e276b, 0xa5781dad3e54d899
+ data8 0xd07a66d7bfa0ebba, 0x837eb98b50f8322a
+ data8 0xa5ac602406c4e68c, 0xd0bc3ea6b32d1b21
+ data8 0x83a270f44c84f699, 0xa5d9601d95c2c0bc
+ data8 0xd0f4f0e8f36c1bf8, 0x83cc4d7cfcfac5ca
+ data8 0xa60e1e1a2de14745, 0xd1376458e34b037e
+ data8 0x83f65f78a8872b4c, 0xa6431f6e3fbd9658
+ data8 0xd17a2ca133f78572, 0x8420a75f2f7b53c8
+ data8 0xa67864b0d432fda4, 0xd1bd4a80301c5715
+ data8 0x844510461ff14209, 0xa6a6444aa0243c0b
+ data8 0xd1f71682b2fa4575, 0x846fbd91b930bed2
+ data8 0xa6dc094d10f25792, 0xd23ad555f773f059
+ data8 0x84947e18234f3294, 0xa70a574cc02bba69
+ data8 0xd2752c7039a5bf73, 0x84bf92755825045a
+ data8 0xa7409e2af9549084, 0xd2b98ee008c06b59
+ data8 0x84e4ac0ee112ba51, 0xa76f5c64ca2cf13b
+ data8 0xd2f4735ffd700280, 0x8509ef44b86f20be
+ data8 0xa79e4f0babab5dc0, 0xd32f99ed6d9ac0e1
+ data8 0x85359d5d91768427, 0xa7d5579ae5164b85
+ data8 0xd374f0666c75d51c, 0x855b3bd5b7384357
+ data8 0xa804bd3c6fe61cc8, 0xd3b0a7d13618e4a1
+ data8 0x858104f0c415f79a, 0xa8345895e5250a5a
+ data8 0xd3eca2ea53bcec0c, 0x85a6f90390d29864
+ data8 0xa8642a122b44ef0b, 0xd428e23874f13a17
+ data8 0x85d3772fcd56a1dd, 0xa89c38ca18f6108b
+ data8 0xd46f82fe293bc6d3, 0x85f9c982fcc002f3
+ data8 0xa8cc81063b6e87ca, 0xd4ac57e9b7186420
+ data8 0x862047e0e7ea554b, 0xa8fd00bfa409285e
+ data8 0xd4e972becb04e8b8, 0x8646f2a26f7f5852
+ data8 0xa92db8664d5516da, 0xd526d40a7a9b43a3
+ data8 0x866dca21754096b5, 0xa95ea86b75cc2c20
+ data8 0xd5647c5b73917370, 0x8694ceb8dfd17a37
+ data8 0xa98fd141a4992deb, 0xd5a26c4201bd6d13
+ data8 0x86bc00c49e9307e8, 0xa9c1335cae7446ba
+ data8 0xd5e0a45015350a7e, 0x86dccd74fce79610
+ data8 0xa9ea8686f556f645, 0xd614b539c6194104
+ data8 0x870453c845acf90f, 0xaa1c52d17906bb19
+ data8 0xd6537310e224283f, 0x872c089a1e90342c
+ data8 0xaa4e59b046dab887, 0xd6927ab62244c917
+ data8 0x8753ec4a92d16c5e, 0xaa809b9c60d1890b
+ data8 0xd6d1ccc1fc4ef4b7, 0x877bff3aca19f6b4
+ data8 0xaab319102f3f9b33, 0xd71169cea98fdded
+ data8 0x879d88b6fe1c324c, 0xaadd5a18c1e21274
+ data8 0xd746a66a5bc9f6d9, 0x87c5f346dbf98c3a
+ data8 0xab1045f2ac31bdf5, 0xd786ce8f0fae5317
+ data8 0x87e7c653efacef2c, 0xab3ae3ab2df7231e
+ data8 0xd7bc7ff214c4e75a, 0x881089d4e73ffefc
+ data8 0xab6e3f945d1e96fc, 0xd7fd35467a517ed1
+ data8 0x88397e6a366f2a8a, 0xaba1d953a08fa94e
+ data8 0xd83e38838648d815, 0x885bc559e5e1c081
+ data8 0xabcd090db7ef4c3f, 0xd874a1db598b8951
+ data8 0x887e2ee392bb7a93, 0xabf864602d7c323d
+ data8 0xd8ab42205b80edaf, 0x88a7a8587e404257
+ data8 0xac2ca5886ccf9b57, 0xd8ed1849d202f965
+ data8 0x88ca5eda67594784, 0xac5861d4aa441f0f
+ data8 0xd92432bd5a173685, 0x88f4356166bd590e
+ data8 0xac8d183fe3a2fbed, 0xd9669ca45b03c23e
+ data8 0x89173a0acf5ce026, 0xacb93703ff51571e
+ data8 0xd99e3327cf89574e, 0x893a62a098b6a57b
+ data8 0xace5830ad0c3f14b, 0xd9d602b19b100466
+ data8 0x895daf637236ae2c, 0xad11fca5d78b3ff2
+ data8 0xda0e0ba86c096841, 0x89883b9d1c2fa9c5
+ data8 0xad4797fddf91a798, 0xda5195fcdb1c3dce
+ data8 0x89abd8dd374a5d7b, 0xad747701e559ebcb
+ data8 0xda8a1eb87a491f6c, 0x89cf9b1dcd197fa0
+ data8 0xada184a47e9c7613, 0xdac2e230b91c3f84
+ data8 0x89f382a258ea79de, 0xadcec13ab0dda8ff
+ data8 0xdafbe0d0b66aea30, 0x8a178faf06648f29
+ data8 0xadfc2d1a5fd21ba8, 0xdb351b04a8fafced
+ data8 0x8a3bc288b3e1d18a, 0xae29c89a5053c33a
+ data8 0xdb6e9139e33cdd8e, 0x8a601b74f4d1f835
+ data8 0xae5794122b638df9, 0xdba843ded7151ea1
+ data8 0x8a849aba14274764, 0xae858fda8137ae0a
+ data8 0xdbe2336319b61fc8, 0x8aa9409f16cdbc9b
+ data8 0xaeb3bc4ccc56d3d1, 0xdc1c60376789fa68
+ data8 0x8ace0d6bbe2cb316, 0xaee219c374c09920
+ data8 0xdc56cacda82d0cd5, 0x8af301688ab33558
+ data8 0xaf10a899d3235fe7, 0xdc917398f2797814
+ data8 0x8b181cdebe6f3206, 0xaf3f692c341fe8b4
+ data8 0xdccc5b0d90a3e628, 0x8b3d60185fafcb7c
+ data8 0xaf6e5bd7db9ae6c2, 0xdd0781a10469f0f2
+ data8 0x8b62cb603bb2fad0, 0xaf9d80fb081cd91b
+ data8 0xdd42e7ca0b52838f, 0x8b80d7d6bc4104de
+ data8 0xafc35ce063eb3787, 0xdd729ad01c69114d
+ data8 0x8ba68bf73ac74f39, 0xaff2ddcb5f28f03d
+ data8 0xddae749c001fbf5e, 0x8bcc68fb9f9f7335
+ data8 0xb022923b148e05c5, 0xddea8f50a51c69b1
+ data8 0x8bf26f31c534fca2, 0xb0527a919adbf58b
+ data8 0xde26eb69a0f0f111, 0x8c10f86e13a1a1f9
+ data8 0xb078f3ab1d701c65, 0xde576480262399bc
+ data8 0x8c3749916cc6abb5, 0xb0a93a6870649f31
+ data8 0xde943789645933c8, 0x8c5dc4c4f7706032
+ data8 0xb0d9b624d62ec856, 0xded14d58139a28af
+ data8 0x8c7cac3a8c42e3e0, 0xb100a5f53fb3c8e1
+ data8 0xdf025c00bbf2b5c7, 0x8ca373f1b7bf2716
+ data8 0xb131821882f5540a, 0xdf3feb44d723a713
+ data8 0x8cc29907fb951294, 0xb158bf8e4cb04055
+ data8 0xdf715bc16c159be0, 0x8ce9ae4e9492aac8
+ data8 0xb189fd69d56b238f, 0xdfaf66240e29cda8
+ data8 0x8d0911dddbfdad0e, 0xb1b189958e8108e4
+ data8 0xdfe139cbf6e19bdc, 0x8d3075c4f20f04ee
+ data8 0xb1e32a8165b09832, 0xe01fc0fe94d9fc52
+ data8 0x8d5018a9d4de77d5, 0xb20b0678fc271eec
+ data8 0xe051f92ffcc0bd60, 0x8d77cc47dd143515
+ data8 0xb23d0bd3f7592b6e, 0xe090feec9c9a06ac
+ data8 0x8d97af6352739cb7, 0xb26538b2db8420dc
+ data8 0xe0c39d0c9ff862d6, 0x8db7af523167800f
+ data8 0xb28d89e339ceca14, 0xe0f668eeb99f188d
+ data8 0x8ddfd80bc68c32ff, 0xb2c022ca12e55a16
+ data8 0xe1362890eb663139, 0x8e00197e1e7c88fe
+ data8 0xb2e8c6852c6b03f1, 0xe1695c7212aecbaa
+ data8 0x8e207859f77e20e7, 0xb3118f4eda9fe40f
+ data8 0xe19cbf0391bbbbe9, 0x8e40f4ce60c9f8e2
+ data8 0xb33a7d6268109ebe, 0xe1d050901c531e85
+ data8 0x8e69ba46cf2fde4d, 0xb36ddbc5ea70ec55
+ data8 0xe2110903b4f4047a, 0x8e8a7a00bd7ae63e
+ data8 0xb3971e9b39264023, 0xe2450559b4d80b6d
+ data8 0x8eab57ef1cf2f529, 0xb3c0877ecc18e24a
+ data8 0xe27931a231554ef3, 0x8ecc5442cffb1dad
+ data8 0xb3ea16ae3a6c905f, 0xe2ad8e2ac3c5b04b
+ data8 0x8eed6f2d2a4acbfe, 0xb413cc67aa0e4d2d
+ data8 0xe2e21b41b9694cce, 0x8f0ea8dff24441ff
+ data8 0xb43da8e9d163e1af, 0xe316d93615862714
+ data8 0x8f385c95d696b817, 0xb47233773b84d425
+ data8 0xe3590bd86a0d30f9, 0x8f59dc43edd930f3
+ data8 0xb49c6825430fe730, 0xe38e38e38e38e38e
+ data8 0x8f7b7b5f5ffad1c4, 0xb4c6c46bcdb27dcf
+ data8 0xe3c397d1e6db7839, 0x8f9d3a1bea165f38
+ data8 0xb4f1488c0b35d26f, 0xe3f928f5953feb9e
+ data8 0x8fbf18adc34b66da, 0xb51bf4c7c51f0168
+ data8 0xe42eeca17c62886c, 0x8fe117499e356095
+ data8 0xb546c9616087ab9c, 0xe464e32943446305
+ data8 0x90033624aa685f8d, 0xb571c69bdffd9a70
+ data8 0xe49b0ce15747a8a2, 0x9025757495f36b86
+ data8 0xb59cecbae56984c3, 0xe4d16a1eee94e9d4
+ data8 0x903f3a5dcc091203, 0xb5bd64512bb14bb7
+ data8 0xe4fa52107353f67d, 0x9061b2fceb2bdbab
+ data8 0xb5e8d2a4bf5ba416, 0xe5310a471f4d2dc3
+ data8 0x90844ca7211032a7, 0xb6146a9a1bc47819
+ data8 0xe567f6f1c2b9c224, 0x90a7079403e6a15d
+ data8 0xb6402c7749d621c0, 0xe59f18689a9e4c9a
+ data8 0x90c9e3fbafd63799, 0xb66c1882fb435ea2
+ data8 0xe5d66f04b8a68ecf, 0x90ece216c8a16ee4
+ data8 0xb6982f048c999a56, 0xe60dfb2005c192e9
+ data8 0x9110021e7b516f0a, 0xb6c47044075b4142
+ data8 0xe645bd1544c7ea51, 0x912a708a39be9075
+ data8 0xb6e5bd6bfd02bafd, 0xe66fb21b505b20a0
+ data8 0x914dcc7b31146370, 0xb7124a2736ff8ef2
+ data8 0xe6a7d32af4a7c59a, 0x91714af8cfe984d5
+ data8 0xb73f026a01e94177, 0xe6e02b129c6a5ae4
+ data8 0x918c00a6f3795e97, 0xb760a959f1d0a7a7
+ data8 0xe70a9136a7403039, 0x91afbc299ed0295d
+ data8 0xb78dae7e06868ab0, 0xe74349fb2d92a589
+ data8 0x91d39add3e958db0, 0xb7badff8ad9e4e02
+ data8 0xe77c3a9c86ed7d42, 0x91ee9920a8974d92
+ data8 0xb7dce25b8e17ae9f, 0xe7a713f88151518a
+ data8 0x9212b5fcac537c19, 0xb80a6226904045e2
+ data8 0xe7e067453317ed2b, 0x9236f6b256923fcf
+ data8 0xb8380f1cafd73c1c, 0xe819f37a81871bb5
+ data8 0x92523ee6f90dcfc3, 0xb85a6ea8e321b4d8
+ data8 0xe8454236bfaeca14, 0x9276bef031e6eb79
+ data8 0xb8886b684ae7d2fa, 0xe87f32f24c3fc90e
+ data8 0x929236ec237a24ad, 0xb8ab0726fa00cf5d
+ data8 0xe8aacd8688892ba6, 0x92b6f70b7efe9dc3
+ data8 0xb8d954a4d13b7cb1, 0xe8e523fd32f606f7
+ data8 0x92d29f61eec7dc2b, 0xb8fc2d4f6cd9f04a
+ data8 0xe9110b5311407927, 0x92f7a05d5b8ba92f
+ data8 0xb92acc851476b1ab, 0xe94bc8bf0c108fa3
+ data8 0x931379a403be5c16, 0xb94de2d841a184c2
+ data8 0xe977fdc439c2ca3c, 0x9338bc44de2e3f34
+ data8 0xb97cd4c36c92693c, 0xe9b3236528fc349e
+ data8 0x9354c71412c69486, 0xb9a0297f172665e3
+ data8 0xe9dfa70b745ac1b4, 0x937a4c273907e262
+ data8 0xb9cf6f21e36c3924, 0xea1b36268d0eaa38
+ data8 0x93968919f6e7975d, 0xb9f3030951267208
+ data8 0xea480963fd394197, 0x93bc516fdd4680c9
+ data8 0xba229d6a618e7c59, 0xea84034425f27484
+ data8 0x93d8c123d9be59b2, 0xba467144459f9855
+ data8 0xeab12713138dd1cc, 0x93f546c955e60076
+ data8 0xba6a60c3c48f1a4b, 0xeade6db73a5e503b
+ data8 0x941b70a65879079f, 0xba9a76056b67ee7a
+ data8 0xeb1b0268343b121b, 0x943829f337410591
+ data8 0xbabea699563ada6e, 0xeb489b0b2bdb5f14
+ data8 0x9454f995765bc4d2, 0xbae2f350b262cc4b
+ data8 0xeb765721e85f03d0, 0x947b86b57f5842ed
+ data8 0xbb1385a23be24e57, 0xebb389645f222f62
+ data8 0x94988aeb23470f86, 0xbb3814975e17c680
+ data8 0xebe198f090607e0c, 0x94b5a5dc9695f42a
+ data8 0xbb5cc031009bf467, 0xec0fcc9321024509
+ data8 0x94d2d7a9170d8b42, 0xbb81889680024764
+ data8 0xec3e247da8b82f61, 0x94f9e87dd78bf019
+ data8 0xbbb2c0d8703ae95d, 0xec7c27d21321c9f7
+ data8 0x95175019a503d89e, 0xbbd7cd09ba3c5463
+ data8 0xecaad5278824e453, 0x9534cefa625fcb3a
+ data8 0xbbfcf68c4977718f, 0xecd9a76d097d4e77
+ data8 0x955265405c491a25, 0xbc223d88cfc88eee
+ data8 0xed089ed5dcd99446, 0x9570130c1f9bb857
+ data8 0xbc47a2284fee4ff8, 0xed37bb95add09a1c
+ data8 0x9597ca4119525184, 0xbc79ac0916ed7b8a
+ data8 0xed76c70508f904b6, 0x95b5af6fb5aa4d3c
+ data8 0xbc9f5670d1a13030, 0xeda63bb05e7f93c6
+ data8 0x95d3ac9273aafd7a, 0xbcc51f068cb95c1d
+ data8 0xedd5d661daed2dc4, 0x95f1c1cafdfd3684
+ data8 0xbceb05f4b30a9bc0, 0xee05974eef86b903
+ data8 0x960fef3b430b8d5f, 0xbd110b6604c7d306
+ data8 0xee357ead791fc670, 0x962e350575b409c5
+ data8 0xbd372f8598620f19, 0xee658cb3c134a463
+ data8 0x964c934c0dfc1708, 0xbd5d727edb6b3c7e
+ data8 0xee95c1987f080211, 0x966b0a31c9c6bc7d
+ data8 0xbd83d47d937bbc6d, 0xeec61d92d8c4314f
+ data8 0x968999d9ad8d264e, 0xbdaa55addf1ae47d
+ data8 0xeef6a0da64a014ac, 0x96a8426705198795
+ data8 0xbdd0f63c36aa73f0, 0xef274ba72a07c811
+ data8 0x96c703fd64445ee5, 0xbdf7b6556d550a15
+ data8 0xef581e31a2c91260, 0x96e5dec0a7b4268d
+ data8 0xbe1e9626b1ffa96b, 0xef8918b2bc43aec6
+ data8 0x9704d2d4f59f79f3, 0xbe4595dd903e5371
+ data8 0xefba3b63d89d7cbf, 0x9723e05ebe91b9b0
+ data8 0xbe6cb5a7f14bc935, 0xefeb867ecffaa607
+ data8 0x97430782be323831, 0xbe93f5b41d047cf7
+ data8 0xf01cfa3df1b9c9fa, 0x97624865fc0df8bf
+ data8 0xbebb5630bae4c15f, 0xf04e96dc05b43e2d
+ data8 0x9781a32dcc640b2a, 0xbee2d74cd30a430c
+ data8 0xf0805c944d827454, 0x97a117ffd0f48e46
+ data8 0xbf0a7937cf38d981, 0xf0b24ba285c495cb
+ data8 0x97c0a701f9d263c9, 0xbf323c217be2bc8c
+ data8 0xf0e46442e76f6569, 0x97e0505a8637a036
+ data8 0xbf5a203a09342bbb, 0xf116a6b2291d7896
+ data8 0x97f57a9fb0b08c6e, 0xbf74cad1c14ebfc4
+ data8 0xf1383fa9e9b5b381, 0x9815503365914a9d
+ data8 0xbf9ce6a497a89f78, 0xf16ac84f90083b9b
+ data8 0x98354085054fd204, 0xbfc52428bec6e72f
+ data8 0xf19d7b686dcb03d7, 0x98554bbbf8a77902
+ data8 0xbfed838fddab024b, 0xf1d0593311db1757
+ data8 0x987571fffb7f94f6, 0xc016050c0420981a
+ data8 0xf20361ee8f1c711e, 0x9895b3791dd03c23
+ data8 0xc03ea8cfabddc330, 0xf23695da7de51d3f
+ data8 0x98ab43a5fc65d0c8, 0xc059d3cbd65ddbce
+ data8 0xf258d095e465cc35, 0x98cbb2d196bd713d
+ data8 0xc082b122a3c78c9d, 0xf28c4d0bfc982b34
+ data8 0x98ec3d9ec7b6f21a, 0xc0abb1499ae736c4
+ data8 0xf2bff55eb3f0ea71, 0x990ce436db5e8344
+ data8 0xc0d4d474c3aedaaf, 0xf2f3c9cf9884636e
+ data8 0x9922b8218160967a, 0xc0f054ca33eb3437
+ data8 0xf31670135ab9cc0f, 0x99438d686f75779d
+ data8 0xc119b2c67e600ed0, 0xf34a8e9f0b54cdfb
+ data8 0x99647eea131fa20b, 0xc1433453de2033ff
+ data8 0xf37ed9fa6b8add3f, 0x997a85045a47c6d0
+ data8 0xc15ef3e44e10032d, 0xf3a1cfe884ef6bb6
+ data8 0x999ba5f14f8add02, 0xc188b130431d80e6
+ data8 0xf3d66689dcc8e8d3, 0x99bce38b5465ecae
+ data8 0xc1b2929d6067730e, 0xf40b2ab069d5c96a
+ data8 0x99d31ca0887f30f9, 0xc1ce9268f31cc734
+ data8 0xf42e718b90c8bc16, 0x99f48a669c74c09e
+ data8 0xc1f8b0877c1b0c08, 0xf463822a0a3b4b00
+ data8 0x9a16154eb445c873, 0xc222f35a87b415ba
+ data8 0xf498c1076015faf8, 0x9a2c822ec198d667
+ data8 0xc23f3467349e5c88, 0xf4bc5a19a33990b5
+ data8 0x9a4e3e080cd91b78, 0xc269b4e40e088c01
+ data8 0xf4f1e6a7d6f5425f, 0x9a70177afe52322e
+ data8 0xc2945aac24daaf6e, 0xf527a232cf6be334
+ data8 0x9a86b8fa94eebe10, 0xc2b0de05e43c1d66
+ data8 0xf54b8ecdcda90851, 0x9aa8c42866ae2958
+ data8 0xc2dbc275e1229d09, 0xf5819949c7ad87b4
+ data8 0x9abf86f9e12fc45e, 0xc2f86fca9d80eeff
+ data8 0xf5a5bac9213b48a9, 0x9ae1c462fc05f49d
+ data8 0xc323938449a2587e, 0xf5dc1501f324a812
+ data8 0x9af8a8dc936b84d0, 0xc3406b40a538ed20
+ data8 0xf6006bee86b5589e, 0x9b1b19033be35730
+ data8 0xc36bcee8211d15e0, 0xf63716b2fa067fa4
+ data8 0x9b3da7daf04c2892, 0xc397593adf2ba366
+ data8 0xf66df22fb6132b9c, 0x9b54c2e4c8a9012b
+ data8 0xc3b475b6206155d5, 0xf6929fb98225deb1
+ data8 0x9b77854e6c661200, 0xc3e0410243b97383
+ data8 0xf6c9cd13021e3fea, 0x9b8ec2e678d56d2f
+ data8 0xc3fd890709833d37, 0xf6eeb177472cedae
+ data8 0x9ba60e6a5ca133b6, 0xc41ae295f7e7fa06
+ data8 0xf713abf4cb0b3afb, 0x9bc919ea66a151a4
+ data8 0xc44709f7bb8a4dd2, 0xf74b4d5333684ef1
+ data8 0x9be0887c09ef82bb, 0xc4648fb0e0bec4c1
+ data8 0xf7707f75a72f8e94, 0x9c03c8d5fffc3503
+ data8 0xc490f9a94695ba14, 0xf7a874b97927af44
+ data8 0x9c1b5ad21a81cbb9, 0xc4aeac0173b7d390
+ data8 0xf7cddf140aedf1d8, 0x9c3ed09216e9ca02
+ data8 0xc4db5941007aa853, 0xf806291bacb7f7a9
+ data8 0x9c568656c0423def, 0xc4f938aec206291a
+ data8 0xf82bcc43b92eafef, 0x9c7a320af242ce60
+ data8 0xc52629e899dfd622, 0xf8646bf0defb759e
+ data8 0x9c920bf7a8c01dc2, 0xc54436e44043b965
+ data8 0xf88a487dfc3ff5f7, 0x9ca9f475d98b159c
+ data8 0xc562563abf9ea07f, 0xf8b03c2b46cdc17f
+ data8 0x9ccdeca60e80b5f8, 0xc58fa7d1dc42921c
+ data8 0xf8e95541c152ae7a, 0x9ce5f9d4653d4902
+ data8 0xc5adf561b91e110a, 0xf90f832c2700c160
+ data8 0x9cfe15cb38bfdd8e, 0xc5cc5591bdbd82fa
+ data8 0xf935c88e0c7f419b, 0x9d225b983f6c1f96
+ data8 0xc5fa08f1ff20593c, 0xf96f5cd84fd86873
+ data8 0x9d3a9cca32261ed7, 0xc618980a79ce6862
+ data8 0xf995dd53ebdd9d6d, 0x9d52ecfccebe1768
+ data8 0xc6373a09e34b50fa, 0xf9bc75a034436a41
+ data8 0x9d77818d95b82f86, 0xc66550a6e0baaf35
+ data8 0xf9f686f26d5518de, 0x9d8ff7893fa4706c
+ data8 0xc6842241926342c9, 0xfa1d5b39b910a8c5
+ data8 0x9da87cbef36f2a5e, 0xc6a3070b7c93bb9e
+ data8 0xfa4447acc4ecbfd2, 0x9dcd6140b4a35aeb
+ data8 0xc6d18260bb84081b, 0xfa7ed7e51e6fdfb4
+ data8 0x9de60cd06dc6e2d4, 0xc6f0977c9416828b
+ data8 0xfaa601394d49a1a0, 0x9dfec7d4cc43b76f
+ data8 0xc70fc0117c641630, 0xfacd431644ce0e40
+ data8 0x9e17925ec9fccc4a, 0xc72efc34d7e615be
+ data8 0xfaf49d96f7a75909, 0x9e3cdf6db57dc075
+ data8 0xc75dfb441594141e, 0xfb2fd3c65e562fd5
+ data8 0x9e55d110b63637a8, 0xc77d68aa019bda4c
+ data8 0xfb576c5762024805, 0x9e6ed27594550d2e
+ data8 0xc79ce9ea478dbc4f, 0xfb7f1debc22c4040
+ data8 0x9e87e3adc385d393, 0xc7bc7f1ae453219d
+ data8 0xfba6e89f32d0190a, 0x9ead9b54b37a1055
+ data8 0xc7ec0476e15e141a, 0xfbe2c803a0894893
+ data8 0x9ec6d46a3d7de215, 0xc80bcbe16f1d540f
+ data8 0xfc0ad1ff0ed9ecf0, 0x9ee01d9108be3154
+ data8 0xc82ba78a5d349735, 0xfc32f57bdfbcbe7f
+ data8 0x9ef976db07288d04, 0xc84b978847a06b87
+ data8 0xfc5b32968f99b21c, 0x9f12e05a4759ec25
+ data8 0xc86b9bf1ee817bc6, 0xfc83896bc861ab08
+ data8 0x9f2c5a20f4da6668, 0xc88bb4de3667cdf4
+ data8 0xfcabfa1861ed4815, 0x9f52af78ed1733ca
+ data8 0xc8bc00e7fe9e23a3, 0xfce8d3cea7d3163e
+ data8 0x9f6c52426a39d003, 0xc8dc4d7ff2d25232
+ data8 0xfd118595143ee273, 0x9f860593d42fd7f3
+ data8 0xc8fcaeebcb40eb47, 0xfd3a519943d4865a
+ data8 0x9f9fc97fdb96bd51, 0xc91d25431426a663
+ data8 0xfd6337f8e1ae5a4b, 0x9fb99e194f4a7037
+ data8 0xc93db09d7fdb2949, 0xfd8c38d1c8e927eb
+ data8 0x9fd383731ca51db9, 0xc95e5112e721582a
+ data8 0xfdb5544205095a53, 0x9fed79a04fbf9423
+ data8 0xc97f06bb49787677, 0xfdde8a67d2613531
+ data8 0xa00780b413b24ee8, 0xc99fd1aecd6e1b06
+ data8 0xfe07db619e781611, 0xa02eab2c4474b0cd
+ data8 0xc9d12a3e27bb1625, 0xfe460768d80bf758
+ data8 0xa048dcd51ccfd142, 0xc9f22ad82ba3d5f0
+ data8 0xfe6f9bfb06cd32f6, 0xa0631fa894b11b8d
+ data8 0xca134113105e67b2, 0xfe994bcd3d14fcc2
+ data8 0xa07d73ba65e680af, 0xca346d07b045a876
+ data8 0xfec316fecaf3f2ab, 0xa097d91e6aaf71b0
+ data8 0xca55aecf0e94bb88, 0xfeecfdaf33fadb80
+ data8 0xa0b24fe89e02602f, 0xca77068257be9bab
+ data8 0xff16fffe2fa8fad6, 0xa0ccd82d1bd2f68b
+ data8 0xca98743ae1c693a8, 0xff411e0ba9db886d
+ data8 0xa0e77200215909e6, 0xcab9f8122c99a101
+ data8 0xff6b57f7c33e4e9a, 0xa1021d760d584855
+ data8 0xcadb9221e268c3b5, 0xff95ade2d1bd7358
+ data8 0xa11cdaa36068a57d, 0xcafd4283d8043dfd
+ data8 0xffc01fed60f86fb5, 0xa137a99cbd3f880b
+ data8 0xcb1f09520d37c6fb, 0xffeaae3832b63956
+LOCAL_OBJECT_END(T_table)
+
+
+
+
+
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(cbrtf)
+
+
+{.mfi
+ getf.sig GR_SIGNIF = f8
+ // will continue only for normal/denormal numbers
+ fclass.nm.unc p12, p7 = f8, 0x1b
+ // GR_GP = pointer to C_1, C_2 followed by T_table
+ nop.i 0
+}
+{.mfi
+ addl GR_GP = @ltoff(poly_coeffs), gp
+ // normalize a
+ fma.s1 FR_ARG = f8, f1, f0
+ // GR_CT3 = bias-((2^8-1)/3) -63 = 0xffff-0x55-0x3f = 0xff6b
+ mov GR_CT3 = 0xff6b ;;
+}
+
+{.mmi
+ // get exponent
+ getf.exp GR_ARGEXP = f8
+ // load start address for C_1, C_2 followed by T_table
+ ld8 GR_ADDR = [ GR_GP ]
+ nop.i 0 ;;
+}
+
+{.mlx
+ // check if input significand is 0
+ (p7) cmp.eq p12, p7 = GR_SIGNIF, r0
+ // GR_2P63 = 2^63
+ movl GR_2P63 = 0x8000000000000000 ;;
+}
+
+{.mfi
+ nop.m 0
+ // y = frcpa(a)
+ // p7 = 1 for normal and denormal (but non-zero) arguments
+ (p7) frcpa.s0 FR_Y, p0 = f1, f8
+ // p9 = 1 if denormal input
+ cmp.gtu p9, p0 = GR_2P63, GR_SIGNIF
+}
+{.mfb
+ // load C_1
+ ldfe FR_COEFF1 = [ GR_ADDR ], 16
+ // if argument is 0, +/-Infinity, or NaN, return
+ (p12) fma.s.s0 f8 = f8, f1, f0
+ (p12) br.ret.spnt b0 ;;
+}
+
+{.mmi
+ // get normalized significand (for denormal inputs only)
+ (p9) getf.sig GR_SIGNIF = FR_ARG
+ // load C_2
+ ldfe FR_COEFF2 = [ GR_ADDR ], 16
+ // GR_CT2 = bias-(2^8-1)
+ mov GR_CT2 = 0xff00
+}
+
+{.mii
+ // get exponent (for denormal inputs only)
+ (p9) getf.exp GR_ARGEXP = FR_ARG
+ nop.i 0
+ mov GR_CONST = 0x20000 ;;
+}
+
+
+{.mii
+ // get GR_SIGN = sign
+ and GR_SIGN = GR_ARGEXP, GR_CONST
+ // eliminate leading 1 from GR_I1 = 1st table index
+ shl GR_I1 = GR_SIGNIF, 1
+ // eliminate sign from exponent
+ andcm GR_EBIAS = GR_ARGEXP, GR_CONST ;;
+}
+
+
+{.mfi
+ // subtract bias from GR_EXP = exponent
+ sub GR_EXP = GR_EBIAS, GR_CT2
+ // r = 1-a*y
+ fnma.s1 FR_R = FR_Y, FR_ARG, f1
+ // GR_IT1 = 1st table index (y_index8 bits)
+ shr.u GR_IT1 = GR_I1, 56 ;;
+}
+
+
+{.mii
+ // 1: exponent* = 5; // (2^{16}-1)/3 = 0x5555
+ shladd GR_E5 = GR_EXP, 2, GR_EXP
+ // GR_IT1_3 = 3*y_index
+ shladd GR_IT1_3 = GR_IT1, 1, GR_IT1
+ nop.i 0 ;;
+}
+
+
+{.mmi
+ // GR_TMP5 = (5*expon)*16+5*expon = (0x55)*expon
+ shladd GR_TMP5 = GR_E5, 4, GR_E5
+ // adjust T_table pointer by 1st index
+ shladd GR_TP1 = GR_IT1_3, 3, GR_ADDR
+ nop.i 0 ;;
+}
+
+
+{.mmi
+ // FR_T0 = T [ 0 ] [ y ]
+ ldf8 FR_T0 = [ GR_TP1 ], 8
+ // get 2^{-63}
+ mov GR_TMP63 = 0xffff + 63
+ // GR_TMP = (0x5500)*expon
+ shl GR_TMP = GR_TMP5, 8 ;;
+}
+
+
+{.mfi
+ // FR_T1 = T [ 1 ] [ y ]
+ ldf8 FR_T1 = [ GR_TP1 ], 8
+ // P_1 = C_1+C_2*r
+ fma.s1 FR_COEFF1 = FR_COEFF2, FR_R, FR_COEFF1
+ // GR_TMP2 = (0x5555)*expon
+ add GR_TMP2 = GR_TMP, GR_TMP5 ;;
+}
+
+
+{.mmi
+ // GR_TMP3 = (0x5556)*expon // 0x5556 = (2^{16}+2)/3
+ add GR_TMP3 = GR_TMP2, GR_EXP ;;
+ // FR_T2 = T [ 2 ] [ y ]
+ ldf8 FR_T2 = [ GR_TP1 ]
+ // GR_EXP3 = floor(expon/3)
+ shr GR_EXP3 = GR_TMP3, 16 ;;
+}
+
+
+{.mmi
+ setf.exp FR_2M63 = GR_TMP63
+ // GR_TMP4 = 3*exponent
+ shladd GR_TMP4 = GR_EXP3, 1, GR_EXP3
+ // bias exponent
+ add GR_EBIAS3 = GR_CT3, GR_EXP3 ;;
+}
+
+
+{.mmf
+ // get remainder of exponent/3
+ sub GR_REM = GR_EXP, GR_TMP4
+ // add sign to exponent
+ or GR_SEXP = GR_EBIAS3, GR_SIGN
+ // P_2 = -r*P_1
+ fnma.s1 FR_R = FR_COEFF1, FR_R, f0 ;;
+}
+
+
+
+{.mmi
+ // FR_ARG = sign*2^{exponent/3}
+ setf.exp FR_ARG = GR_SEXP
+ nop.m 0
+ // remainder = 0 ?
+ // p7=1 if input exponent is 3*j (remainder is 0)
+ cmp.eq.unc p7, p8 = r0, GR_REM ;;
+}
+
+
+{.mfi
+ // remainder = 1 ?
+ // p8=1 if input exponent is 3*j+1 (remainder is 1)
+ // p12=1 if input exponent is 3*j+2 (remainder is 2)
+ (p8) cmp.eq.unc p8, p12 = 1, GR_REM
+ // p7=1 -> remainder = 0 -> use T = FR_T0
+ (p7) fma.s1 f8 = FR_T0, FR_R, FR_T0
+ // argument is of the form 2^(3*k) ?
+ // ( GR_I1 holds significand bits, without the leading 1)
+ or GR_I1 = GR_I1, GR_REM ;;
+}
+
+
+.pred.rel "mutex", p12, p8
+{.mfi
+ nop.m 0
+ // p8=1 -> remainder = 1 -> use FR_T1
+ (p8) fma.s1 f8 = FR_T1, FR_R, FR_T1
+ // argument is of the form 2^(3*k) ?
+ cmp.eq p14, p7 = GR_I1, r0
+}
+
+
+{.mfi
+ nop.m 0
+ // p12=1 -> remainder=2 -> result = T+T*P_2
+ (p12) fma.s1 f8 = FR_T2, FR_R, FR_T2
+ nop.i 0 ;;
+}
+
+
+.pred.rel "mutex", p14, p7
+{.mfi
+ nop.m 0
+ // if argument is sgn*2^{3*(expon/3)}
+ (p14) fma.s.s0 f8 = FR_2M63, FR_ARG, f0
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ // T* = sgn*2^{expon/3}
+ (p7) fma.s.s0 f8 = f8, FR_ARG, f0
+ br.ret.sptk b0 ;;
+}
+
+
+GLOBAL_LIBM_END(cbrtf)
+
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/s_cbrtl.S b/libc/sysdeps/ia64/fpu/s_cbrtl.S
new file mode 100644
index 000000000..76ef12f33
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_cbrtl.S
@@ -0,0 +1,986 @@
+.file "cbrtl.s"
+
+
+// Copyright (c) 2000 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 04/28/00 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header:.section,.global,.proc,.align
+// 11/23/04 Reformatted routine and improved speed
+//
+// API
+//==============================================================
+// long double cbrtl(long double)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+// Implementation
+//
+// The result is computed as
+// cbrt(x)= cbrt(1 - (1 - x*y)) * (1/cbrt(y))
+// where y = frcpa(x) = (-1)^sgn_y * 2^(3*k+j) * m_y,
+// m_y in [1,2), j in {0,1,2}
+//
+// cbrt(1 - (1 - x*y)) is approximated by a degree-6 polynomial
+// in r= 1 - x*y :
+// P = 1 - c_1 r - c_2 * r^2 - c_3 * r^3 - c_4 * r^4 - c_5 * r^5 - c_6 * r^6
+//
+//
+// The values (1/cbrt(y)) are stored as two tables of constants T_hi
+// (double-extended precision) and D (single precision) as follows:
+// T_hi (1 + D)= 1/cbrt(y) to about 80 bits of accuracy
+//
+// The tables are only stored for three exponent values (i.e.
+// only for 2^j * m_y, where j in {0,1,2} and m_y covers the 256
+// possible mantissas for an frcpa result); the index is formed
+// by the 8 leading mantissa bits of x, which is the same index used
+// by the hardware to get frcpa(x).
+//
+// The table values are multiplied by 2^k where e is the exponent of
+// the input number. This multiplication is carried out in parallel with
+// the polynomial evaluation:
+// T= 2^(k) * T_hi
+//
+//=======================================================================
+
+//===============
+// Special values
+//==============================================================
+
+// Registers used
+//==============================================================
+// p6, p7, p12
+ FR_R = f6
+ FR_C1 = f7
+ FR_C2 = f9
+ FR_C3 = f10
+ FR_C4 = f11
+ FR_C5 = f12
+ FR_C6 = f13
+ FR_XNORM = f14
+ FR_D = f15
+ FR_SPECIAL = f32
+ FR_RCP = f33
+ FR_R2 = f34
+ FR_P1 = f35
+ FR_P2 = f36
+ FR_P3 = f37
+ FR_P4 = f38
+ FR_P5 = f39
+ FR_R3 = f40
+ FR_T = f41
+ FR_TF = f42
+ FR_P = f43
+ FR_SGNEXP = f44
+
+ GR_ADDR = r2
+ GR_C_START = r2
+ GR_ARGSIG = r3
+ GR_NORMSIG = r15
+ GR_D_ADDR = r16
+ GR_D_START = r16
+ GR_INDEX2 = r17
+ GR_IX2 = r17
+ GR_NORMEXP = r18
+ GR_EXP5 = r19
+ GR_EXP3 = r20
+ GR_EXP6 = r20
+ GR_EXP17 = r21
+ GR_TMP1 = r21
+ GR_SGNMASK = r22
+ GR_T_INDEX = r23
+ GR_IX_T = r23
+ GR_IX_D = r24
+ GR_D_INDEX = r24
+ GR_TMP2 = r25
+ GR_TMP3 = r25
+ GR_TMP4 = r25
+ GR_EXP_RES = r26
+ GR_BIAS23 = r27
+ GR_EXPBIAS = r27
+ GR_EXP_MOD_3 = r28
+ GR_SIGN = r29
+ GR_EXPSIGNRES = r29
+ GR_REMTMP = r30
+ GR_NORMEXPSGN = r31
+
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(poly_coeffs)
+
+ data8 0xaaaaaaaaaaaaaab1, 0x00003ffd // C_1
+ data8 0xe38e38e38e38e3e0, 0x00003ffb // C_2
+ data8 0x3faf9add3c0be9a6, 0x3fa511e8d2b1f749 // C_3, C_4
+ data8 0x3f9ee71b2c6ebe99, 0x3f9809180fd0340c // C_5, C_6
+LOCAL_OBJECT_END(poly_coeffs)
+
+
+LOCAL_OBJECT_START(T_table)
+
+ data8 0x80155c748c374836, 0x8040404b0879f7f9
+ data8 0x806b5dce4b405c10, 0x8096b586974669b1
+ data8 0x80bcd273d952a028, 0x80e898c52813f2f3
+ data8 0x81149add67c2d208, 0x813b4e2c856b6e9a
+ data8 0x8167c1dde03de7aa, 0x818ed973b811135e
+ data8 0x81bbc0c33e13ec98, 0x81e33e69fbe7504a
+ data8 0x820aec524e3c23e9, 0x823880f78e70b805
+ data8 0x826097a62a8e5200, 0x8288dfe00e9b5eaf
+ data8 0x82b15a10c5371624, 0x82da06a527b18937
+ data8 0x8302e60b635ab394, 0x832bf8b2feec2f0e
+ data8 0x83553f0ce00e276b, 0x837eb98b50f8322a
+ data8 0x83a270f44c84f699, 0x83cc4d7cfcfac5ca
+ data8 0x83f65f78a8872b4c, 0x8420a75f2f7b53c8
+ data8 0x844510461ff14209, 0x846fbd91b930bed2
+ data8 0x84947e18234f3294, 0x84bf92755825045a
+ data8 0x84e4ac0ee112ba51, 0x8509ef44b86f20be
+ data8 0x85359d5d91768427, 0x855b3bd5b7384357
+ data8 0x858104f0c415f79a, 0x85a6f90390d29864
+ data8 0x85d3772fcd56a1dd, 0x85f9c982fcc002f3
+ data8 0x862047e0e7ea554b, 0x8646f2a26f7f5852
+ data8 0x866dca21754096b5, 0x8694ceb8dfd17a37
+ data8 0x86bc00c49e9307e8, 0x86dccd74fce79610
+ data8 0x870453c845acf90f, 0x872c089a1e90342c
+ data8 0x8753ec4a92d16c5e, 0x877bff3aca19f6b4
+ data8 0x879d88b6fe1c324c, 0x87c5f346dbf98c3a
+ data8 0x87e7c653efacef2c, 0x881089d4e73ffefc
+ data8 0x88397e6a366f2a8a, 0x885bc559e5e1c081
+ data8 0x887e2ee392bb7a93, 0x88a7a8587e404257
+ data8 0x88ca5eda67594784, 0x88f4356166bd590e
+ data8 0x89173a0acf5ce026, 0x893a62a098b6a57b
+ data8 0x895daf637236ae2c, 0x89883b9d1c2fa9c5
+ data8 0x89abd8dd374a5d7b, 0x89cf9b1dcd197fa0
+ data8 0x89f382a258ea79de, 0x8a178faf06648f29
+ data8 0x8a3bc288b3e1d18a, 0x8a601b74f4d1f835
+ data8 0x8a849aba14274764, 0x8aa9409f16cdbc9b
+ data8 0x8ace0d6bbe2cb316, 0x8af301688ab33558
+ data8 0x8b181cdebe6f3206, 0x8b3d60185fafcb7c
+ data8 0x8b62cb603bb2fad0, 0x8b80d7d6bc4104de
+ data8 0x8ba68bf73ac74f39, 0x8bcc68fb9f9f7335
+ data8 0x8bf26f31c534fca2, 0x8c10f86e13a1a1f9
+ data8 0x8c3749916cc6abb5, 0x8c5dc4c4f7706032
+ data8 0x8c7cac3a8c42e3e0, 0x8ca373f1b7bf2716
+ data8 0x8cc29907fb951294, 0x8ce9ae4e9492aac8
+ data8 0x8d0911dddbfdad0e, 0x8d3075c4f20f04ee
+ data8 0x8d5018a9d4de77d5, 0x8d77cc47dd143515
+ data8 0x8d97af6352739cb7, 0x8db7af523167800f
+ data8 0x8ddfd80bc68c32ff, 0x8e00197e1e7c88fe
+ data8 0x8e207859f77e20e7, 0x8e40f4ce60c9f8e2
+ data8 0x8e69ba46cf2fde4d, 0x8e8a7a00bd7ae63e
+ data8 0x8eab57ef1cf2f529, 0x8ecc5442cffb1dad
+ data8 0x8eed6f2d2a4acbfe, 0x8f0ea8dff24441ff
+ data8 0x8f385c95d696b817, 0x8f59dc43edd930f3
+ data8 0x8f7b7b5f5ffad1c4, 0x8f9d3a1bea165f38
+ data8 0x8fbf18adc34b66da, 0x8fe117499e356095
+ data8 0x90033624aa685f8d, 0x9025757495f36b86
+ data8 0x903f3a5dcc091203, 0x9061b2fceb2bdbab
+ data8 0x90844ca7211032a7, 0x90a7079403e6a15d
+ data8 0x90c9e3fbafd63799, 0x90ece216c8a16ee4
+ data8 0x9110021e7b516f0a, 0x912a708a39be9075
+ data8 0x914dcc7b31146370, 0x91714af8cfe984d5
+ data8 0x918c00a6f3795e97, 0x91afbc299ed0295d
+ data8 0x91d39add3e958db0, 0x91ee9920a8974d92
+ data8 0x9212b5fcac537c19, 0x9236f6b256923fcf
+ data8 0x92523ee6f90dcfc3, 0x9276bef031e6eb79
+ data8 0x929236ec237a24ad, 0x92b6f70b7efe9dc3
+ data8 0x92d29f61eec7dc2b, 0x92f7a05d5b8ba92f
+ data8 0x931379a403be5c16, 0x9338bc44de2e3f34
+ data8 0x9354c71412c69486, 0x937a4c273907e262
+ data8 0x93968919f6e7975d, 0x93bc516fdd4680c9
+ data8 0x93d8c123d9be59b2, 0x93f546c955e60076
+ data8 0x941b70a65879079f, 0x943829f337410591
+ data8 0x9454f995765bc4d2, 0x947b86b57f5842ed
+ data8 0x94988aeb23470f86, 0x94b5a5dc9695f42a
+ data8 0x94d2d7a9170d8b42, 0x94f9e87dd78bf019
+ data8 0x95175019a503d89e, 0x9534cefa625fcb3a
+ data8 0x955265405c491a25, 0x9570130c1f9bb857
+ data8 0x9597ca4119525184, 0x95b5af6fb5aa4d3c
+ data8 0x95d3ac9273aafd7a, 0x95f1c1cafdfd3684
+ data8 0x960fef3b430b8d5f, 0x962e350575b409c5
+ data8 0x964c934c0dfc1708, 0x966b0a31c9c6bc7d
+ data8 0x968999d9ad8d264e, 0x96a8426705198795
+ data8 0x96c703fd64445ee5, 0x96e5dec0a7b4268d
+ data8 0x9704d2d4f59f79f3, 0x9723e05ebe91b9b0
+ data8 0x97430782be323831, 0x97624865fc0df8bf
+ data8 0x9781a32dcc640b2a, 0x97a117ffd0f48e46
+ data8 0x97c0a701f9d263c9, 0x97e0505a8637a036
+ data8 0x97f57a9fb0b08c6e, 0x9815503365914a9d
+ data8 0x98354085054fd204, 0x98554bbbf8a77902
+ data8 0x987571fffb7f94f6, 0x9895b3791dd03c23
+ data8 0x98ab43a5fc65d0c8, 0x98cbb2d196bd713d
+ data8 0x98ec3d9ec7b6f21a, 0x990ce436db5e8344
+ data8 0x9922b8218160967a, 0x99438d686f75779d
+ data8 0x99647eea131fa20b, 0x997a85045a47c6d0
+ data8 0x999ba5f14f8add02, 0x99bce38b5465ecae
+ data8 0x99d31ca0887f30f9, 0x99f48a669c74c09e
+ data8 0x9a16154eb445c873, 0x9a2c822ec198d667
+ data8 0x9a4e3e080cd91b78, 0x9a70177afe52322e
+ data8 0x9a86b8fa94eebe10, 0x9aa8c42866ae2958
+ data8 0x9abf86f9e12fc45e, 0x9ae1c462fc05f49d
+ data8 0x9af8a8dc936b84d0, 0x9b1b19033be35730
+ data8 0x9b3da7daf04c2892, 0x9b54c2e4c8a9012b
+ data8 0x9b77854e6c661200, 0x9b8ec2e678d56d2f
+ data8 0x9ba60e6a5ca133b6, 0x9bc919ea66a151a4
+ data8 0x9be0887c09ef82bb, 0x9c03c8d5fffc3503
+ data8 0x9c1b5ad21a81cbb9, 0x9c3ed09216e9ca02
+ data8 0x9c568656c0423def, 0x9c7a320af242ce60
+ data8 0x9c920bf7a8c01dc2, 0x9ca9f475d98b159c
+ data8 0x9ccdeca60e80b5f8, 0x9ce5f9d4653d4902
+ data8 0x9cfe15cb38bfdd8e, 0x9d225b983f6c1f96
+ data8 0x9d3a9cca32261ed7, 0x9d52ecfccebe1768
+ data8 0x9d77818d95b82f86, 0x9d8ff7893fa4706c
+ data8 0x9da87cbef36f2a5e, 0x9dcd6140b4a35aeb
+ data8 0x9de60cd06dc6e2d4, 0x9dfec7d4cc43b76f
+ data8 0x9e17925ec9fccc4a, 0x9e3cdf6db57dc075
+ data8 0x9e55d110b63637a8, 0x9e6ed27594550d2e
+ data8 0x9e87e3adc385d393, 0x9ead9b54b37a1055
+ data8 0x9ec6d46a3d7de215, 0x9ee01d9108be3154
+ data8 0x9ef976db07288d04, 0x9f12e05a4759ec25
+ data8 0x9f2c5a20f4da6668, 0x9f52af78ed1733ca
+ data8 0x9f6c52426a39d003, 0x9f860593d42fd7f3
+ data8 0x9f9fc97fdb96bd51, 0x9fb99e194f4a7037
+ data8 0x9fd383731ca51db9, 0x9fed79a04fbf9423
+ data8 0xa00780b413b24ee8, 0xa02eab2c4474b0cd
+ data8 0xa048dcd51ccfd142, 0xa0631fa894b11b8d
+ data8 0xa07d73ba65e680af, 0xa097d91e6aaf71b0
+ data8 0xa0b24fe89e02602f, 0xa0ccd82d1bd2f68b
+ data8 0xa0e77200215909e6, 0xa1021d760d584855
+ data8 0xa11cdaa36068a57d, 0xa137a99cbd3f880b
+ data8 0xa160019ed37fb4ae, 0xa1960b5966da4608
+ data8 0xa1cc5dbe6dc2aab4, 0xa202f97995b69c0d
+ data8 0xa232fe6eb0c0577d, 0xa26a2582012f6e17
+ data8 0xa2a197e5d10465cb, 0xa2d25a532efefbc8
+ data8 0xa30a5bd6e49e4ab8, 0xa33b9c9b59879e24
+ data8 0xa3742fca6a3c1f21, 0xa3a5f1273887bf22
+ data8 0xa3d7ef508ff11574, 0xa4115ce30548bc15
+ data8 0xa443df0e53df577a, 0xa4769fa5913c0ec3
+ data8 0xa4a99f303bc7def5, 0xa4dcde37779adf4b
+ data8 0xa5105d46152c938a, 0xa5441ce89825cb8d
+ data8 0xa5781dad3e54d899, 0xa5ac602406c4e68c
+ data8 0xa5d9601d95c2c0bc, 0xa60e1e1a2de14745
+ data8 0xa6431f6e3fbd9658, 0xa67864b0d432fda4
+ data8 0xa6a6444aa0243c0b, 0xa6dc094d10f25792
+ data8 0xa70a574cc02bba69, 0xa7409e2af9549084
+ data8 0xa76f5c64ca2cf13b, 0xa79e4f0babab5dc0
+ data8 0xa7d5579ae5164b85, 0xa804bd3c6fe61cc8
+ data8 0xa8345895e5250a5a, 0xa8642a122b44ef0b
+ data8 0xa89c38ca18f6108b, 0xa8cc81063b6e87ca
+ data8 0xa8fd00bfa409285e, 0xa92db8664d5516da
+ data8 0xa95ea86b75cc2c20, 0xa98fd141a4992deb
+ data8 0xa9c1335cae7446ba, 0xa9ea8686f556f645
+ data8 0xaa1c52d17906bb19, 0xaa4e59b046dab887
+ data8 0xaa809b9c60d1890b, 0xaab319102f3f9b33
+ data8 0xaadd5a18c1e21274, 0xab1045f2ac31bdf5
+ data8 0xab3ae3ab2df7231e, 0xab6e3f945d1e96fc
+ data8 0xaba1d953a08fa94e, 0xabcd090db7ef4c3f
+ data8 0xabf864602d7c323d, 0xac2ca5886ccf9b57
+ data8 0xac5861d4aa441f0f, 0xac8d183fe3a2fbed
+ data8 0xacb93703ff51571e, 0xace5830ad0c3f14b
+ data8 0xad11fca5d78b3ff2, 0xad4797fddf91a798
+ data8 0xad747701e559ebcb, 0xada184a47e9c7613
+ data8 0xadcec13ab0dda8ff, 0xadfc2d1a5fd21ba8
+ data8 0xae29c89a5053c33a, 0xae5794122b638df9
+ data8 0xae858fda8137ae0a, 0xaeb3bc4ccc56d3d1
+ data8 0xaee219c374c09920, 0xaf10a899d3235fe7
+ data8 0xaf3f692c341fe8b4, 0xaf6e5bd7db9ae6c2
+ data8 0xaf9d80fb081cd91b, 0xafc35ce063eb3787
+ data8 0xaff2ddcb5f28f03d, 0xb022923b148e05c5
+ data8 0xb0527a919adbf58b, 0xb078f3ab1d701c65
+ data8 0xb0a93a6870649f31, 0xb0d9b624d62ec856
+ data8 0xb100a5f53fb3c8e1, 0xb131821882f5540a
+ data8 0xb158bf8e4cb04055, 0xb189fd69d56b238f
+ data8 0xb1b189958e8108e4, 0xb1e32a8165b09832
+ data8 0xb20b0678fc271eec, 0xb23d0bd3f7592b6e
+ data8 0xb26538b2db8420dc, 0xb28d89e339ceca14
+ data8 0xb2c022ca12e55a16, 0xb2e8c6852c6b03f1
+ data8 0xb3118f4eda9fe40f, 0xb33a7d6268109ebe
+ data8 0xb36ddbc5ea70ec55, 0xb3971e9b39264023
+ data8 0xb3c0877ecc18e24a, 0xb3ea16ae3a6c905f
+ data8 0xb413cc67aa0e4d2d, 0xb43da8e9d163e1af
+ data8 0xb47233773b84d425, 0xb49c6825430fe730
+ data8 0xb4c6c46bcdb27dcf, 0xb4f1488c0b35d26f
+ data8 0xb51bf4c7c51f0168, 0xb546c9616087ab9c
+ data8 0xb571c69bdffd9a70, 0xb59cecbae56984c3
+ data8 0xb5bd64512bb14bb7, 0xb5e8d2a4bf5ba416
+ data8 0xb6146a9a1bc47819, 0xb6402c7749d621c0
+ data8 0xb66c1882fb435ea2, 0xb6982f048c999a56
+ data8 0xb6c47044075b4142, 0xb6e5bd6bfd02bafd
+ data8 0xb7124a2736ff8ef2, 0xb73f026a01e94177
+ data8 0xb760a959f1d0a7a7, 0xb78dae7e06868ab0
+ data8 0xb7badff8ad9e4e02, 0xb7dce25b8e17ae9f
+ data8 0xb80a6226904045e2, 0xb8380f1cafd73c1c
+ data8 0xb85a6ea8e321b4d8, 0xb8886b684ae7d2fa
+ data8 0xb8ab0726fa00cf5d, 0xb8d954a4d13b7cb1
+ data8 0xb8fc2d4f6cd9f04a, 0xb92acc851476b1ab
+ data8 0xb94de2d841a184c2, 0xb97cd4c36c92693c
+ data8 0xb9a0297f172665e3, 0xb9cf6f21e36c3924
+ data8 0xb9f3030951267208, 0xba229d6a618e7c59
+ data8 0xba467144459f9855, 0xba6a60c3c48f1a4b
+ data8 0xba9a76056b67ee7a, 0xbabea699563ada6e
+ data8 0xbae2f350b262cc4b, 0xbb1385a23be24e57
+ data8 0xbb3814975e17c680, 0xbb5cc031009bf467
+ data8 0xbb81889680024764, 0xbbb2c0d8703ae95d
+ data8 0xbbd7cd09ba3c5463, 0xbbfcf68c4977718f
+ data8 0xbc223d88cfc88eee, 0xbc47a2284fee4ff8
+ data8 0xbc79ac0916ed7b8a, 0xbc9f5670d1a13030
+ data8 0xbcc51f068cb95c1d, 0xbceb05f4b30a9bc0
+ data8 0xbd110b6604c7d306, 0xbd372f8598620f19
+ data8 0xbd5d727edb6b3c7e, 0xbd83d47d937bbc6d
+ data8 0xbdaa55addf1ae47d, 0xbdd0f63c36aa73f0
+ data8 0xbdf7b6556d550a15, 0xbe1e9626b1ffa96b
+ data8 0xbe4595dd903e5371, 0xbe6cb5a7f14bc935
+ data8 0xbe93f5b41d047cf7, 0xbebb5630bae4c15f
+ data8 0xbee2d74cd30a430c, 0xbf0a7937cf38d981
+ data8 0xbf323c217be2bc8c, 0xbf5a203a09342bbb
+ data8 0xbf74cad1c14ebfc4, 0xbf9ce6a497a89f78
+ data8 0xbfc52428bec6e72f, 0xbfed838fddab024b
+ data8 0xc016050c0420981a, 0xc03ea8cfabddc330
+ data8 0xc059d3cbd65ddbce, 0xc082b122a3c78c9d
+ data8 0xc0abb1499ae736c4, 0xc0d4d474c3aedaaf
+ data8 0xc0f054ca33eb3437, 0xc119b2c67e600ed0
+ data8 0xc1433453de2033ff, 0xc15ef3e44e10032d
+ data8 0xc188b130431d80e6, 0xc1b2929d6067730e
+ data8 0xc1ce9268f31cc734, 0xc1f8b0877c1b0c08
+ data8 0xc222f35a87b415ba, 0xc23f3467349e5c88
+ data8 0xc269b4e40e088c01, 0xc2945aac24daaf6e
+ data8 0xc2b0de05e43c1d66, 0xc2dbc275e1229d09
+ data8 0xc2f86fca9d80eeff, 0xc323938449a2587e
+ data8 0xc3406b40a538ed20, 0xc36bcee8211d15e0
+ data8 0xc397593adf2ba366, 0xc3b475b6206155d5
+ data8 0xc3e0410243b97383, 0xc3fd890709833d37
+ data8 0xc41ae295f7e7fa06, 0xc44709f7bb8a4dd2
+ data8 0xc4648fb0e0bec4c1, 0xc490f9a94695ba14
+ data8 0xc4aeac0173b7d390, 0xc4db5941007aa853
+ data8 0xc4f938aec206291a, 0xc52629e899dfd622
+ data8 0xc54436e44043b965, 0xc562563abf9ea07f
+ data8 0xc58fa7d1dc42921c, 0xc5adf561b91e110a
+ data8 0xc5cc5591bdbd82fa, 0xc5fa08f1ff20593c
+ data8 0xc618980a79ce6862, 0xc6373a09e34b50fa
+ data8 0xc66550a6e0baaf35, 0xc6842241926342c9
+ data8 0xc6a3070b7c93bb9e, 0xc6d18260bb84081b
+ data8 0xc6f0977c9416828b, 0xc70fc0117c641630
+ data8 0xc72efc34d7e615be, 0xc75dfb441594141e
+ data8 0xc77d68aa019bda4c, 0xc79ce9ea478dbc4f
+ data8 0xc7bc7f1ae453219d, 0xc7ec0476e15e141a
+ data8 0xc80bcbe16f1d540f, 0xc82ba78a5d349735
+ data8 0xc84b978847a06b87, 0xc86b9bf1ee817bc6
+ data8 0xc88bb4de3667cdf4, 0xc8bc00e7fe9e23a3
+ data8 0xc8dc4d7ff2d25232, 0xc8fcaeebcb40eb47
+ data8 0xc91d25431426a663, 0xc93db09d7fdb2949
+ data8 0xc95e5112e721582a, 0xc97f06bb49787677
+ data8 0xc99fd1aecd6e1b06, 0xc9d12a3e27bb1625
+ data8 0xc9f22ad82ba3d5f0, 0xca134113105e67b2
+ data8 0xca346d07b045a876, 0xca55aecf0e94bb88
+ data8 0xca77068257be9bab, 0xca98743ae1c693a8
+ data8 0xcab9f8122c99a101, 0xcadb9221e268c3b5
+ data8 0xcafd4283d8043dfd, 0xcb1f09520d37c6fb
+ data8 0xcb51ddcb9e93095e, 0xcb95f333968ad59b
+ data8 0xcbda64292d3ffd97, 0xcc1f3184af961596
+ data8 0xcc5bb1ac954d33e2, 0xcca12e9831fc6402
+ data8 0xcce70a67b64f24ad, 0xcd24794726477ea5
+ data8 0xcd6b096a0b70ee87, 0xcda9177738b15a90
+ data8 0xcdf05f2247dffab9, 0xce2f0f347f96f906
+ data8 0xce6e0be0cd551a61, 0xceb666b2c347d1de
+ data8 0xcef609b0cb874f00, 0xcf35fb5447e5c765
+ data8 0xcf763c47ee869f00, 0xcfb6cd3888d71785
+ data8 0xcff7aed4fbfbb447, 0xd038e1ce5167e3c6
+ data8 0xd07a66d7bfa0ebba, 0xd0bc3ea6b32d1b21
+ data8 0xd0f4f0e8f36c1bf8, 0xd1376458e34b037e
+ data8 0xd17a2ca133f78572, 0xd1bd4a80301c5715
+ data8 0xd1f71682b2fa4575, 0xd23ad555f773f059
+ data8 0xd2752c7039a5bf73, 0xd2b98ee008c06b59
+ data8 0xd2f4735ffd700280, 0xd32f99ed6d9ac0e1
+ data8 0xd374f0666c75d51c, 0xd3b0a7d13618e4a1
+ data8 0xd3eca2ea53bcec0c, 0xd428e23874f13a17
+ data8 0xd46f82fe293bc6d3, 0xd4ac57e9b7186420
+ data8 0xd4e972becb04e8b8, 0xd526d40a7a9b43a3
+ data8 0xd5647c5b73917370, 0xd5a26c4201bd6d13
+ data8 0xd5e0a45015350a7e, 0xd614b539c6194104
+ data8 0xd6537310e224283f, 0xd6927ab62244c917
+ data8 0xd6d1ccc1fc4ef4b7, 0xd71169cea98fdded
+ data8 0xd746a66a5bc9f6d9, 0xd786ce8f0fae5317
+ data8 0xd7bc7ff214c4e75a, 0xd7fd35467a517ed1
+ data8 0xd83e38838648d815, 0xd874a1db598b8951
+ data8 0xd8ab42205b80edaf, 0xd8ed1849d202f965
+ data8 0xd92432bd5a173685, 0xd9669ca45b03c23e
+ data8 0xd99e3327cf89574e, 0xd9d602b19b100466
+ data8 0xda0e0ba86c096841, 0xda5195fcdb1c3dce
+ data8 0xda8a1eb87a491f6c, 0xdac2e230b91c3f84
+ data8 0xdafbe0d0b66aea30, 0xdb351b04a8fafced
+ data8 0xdb6e9139e33cdd8e, 0xdba843ded7151ea1
+ data8 0xdbe2336319b61fc8, 0xdc1c60376789fa68
+ data8 0xdc56cacda82d0cd5, 0xdc917398f2797814
+ data8 0xdccc5b0d90a3e628, 0xdd0781a10469f0f2
+ data8 0xdd42e7ca0b52838f, 0xdd729ad01c69114d
+ data8 0xddae749c001fbf5e, 0xddea8f50a51c69b1
+ data8 0xde26eb69a0f0f111, 0xde576480262399bc
+ data8 0xde943789645933c8, 0xded14d58139a28af
+ data8 0xdf025c00bbf2b5c7, 0xdf3feb44d723a713
+ data8 0xdf715bc16c159be0, 0xdfaf66240e29cda8
+ data8 0xdfe139cbf6e19bdc, 0xe01fc0fe94d9fc52
+ data8 0xe051f92ffcc0bd60, 0xe090feec9c9a06ac
+ data8 0xe0c39d0c9ff862d6, 0xe0f668eeb99f188d
+ data8 0xe1362890eb663139, 0xe1695c7212aecbaa
+ data8 0xe19cbf0391bbbbe9, 0xe1d050901c531e85
+ data8 0xe2110903b4f4047a, 0xe2450559b4d80b6d
+ data8 0xe27931a231554ef3, 0xe2ad8e2ac3c5b04b
+ data8 0xe2e21b41b9694cce, 0xe316d93615862714
+ data8 0xe3590bd86a0d30f9, 0xe38e38e38e38e38e
+ data8 0xe3c397d1e6db7839, 0xe3f928f5953feb9e
+ data8 0xe42eeca17c62886c, 0xe464e32943446305
+ data8 0xe49b0ce15747a8a2, 0xe4d16a1eee94e9d4
+ data8 0xe4fa52107353f67d, 0xe5310a471f4d2dc3
+ data8 0xe567f6f1c2b9c224, 0xe59f18689a9e4c9a
+ data8 0xe5d66f04b8a68ecf, 0xe60dfb2005c192e9
+ data8 0xe645bd1544c7ea51, 0xe66fb21b505b20a0
+ data8 0xe6a7d32af4a7c59a, 0xe6e02b129c6a5ae4
+ data8 0xe70a9136a7403039, 0xe74349fb2d92a589
+ data8 0xe77c3a9c86ed7d42, 0xe7a713f88151518a
+ data8 0xe7e067453317ed2b, 0xe819f37a81871bb5
+ data8 0xe8454236bfaeca14, 0xe87f32f24c3fc90e
+ data8 0xe8aacd8688892ba6, 0xe8e523fd32f606f7
+ data8 0xe9110b5311407927, 0xe94bc8bf0c108fa3
+ data8 0xe977fdc439c2ca3c, 0xe9b3236528fc349e
+ data8 0xe9dfa70b745ac1b4, 0xea1b36268d0eaa38
+ data8 0xea480963fd394197, 0xea84034425f27484
+ data8 0xeab12713138dd1cc, 0xeade6db73a5e503b
+ data8 0xeb1b0268343b121b, 0xeb489b0b2bdb5f14
+ data8 0xeb765721e85f03d0, 0xebb389645f222f62
+ data8 0xebe198f090607e0c, 0xec0fcc9321024509
+ data8 0xec3e247da8b82f61, 0xec7c27d21321c9f7
+ data8 0xecaad5278824e453, 0xecd9a76d097d4e77
+ data8 0xed089ed5dcd99446, 0xed37bb95add09a1c
+ data8 0xed76c70508f904b6, 0xeda63bb05e7f93c6
+ data8 0xedd5d661daed2dc4, 0xee05974eef86b903
+ data8 0xee357ead791fc670, 0xee658cb3c134a463
+ data8 0xee95c1987f080211, 0xeec61d92d8c4314f
+ data8 0xeef6a0da64a014ac, 0xef274ba72a07c811
+ data8 0xef581e31a2c91260, 0xef8918b2bc43aec6
+ data8 0xefba3b63d89d7cbf, 0xefeb867ecffaa607
+ data8 0xf01cfa3df1b9c9fa, 0xf04e96dc05b43e2d
+ data8 0xf0805c944d827454, 0xf0b24ba285c495cb
+ data8 0xf0e46442e76f6569, 0xf116a6b2291d7896
+ data8 0xf1383fa9e9b5b381, 0xf16ac84f90083b9b
+ data8 0xf19d7b686dcb03d7, 0xf1d0593311db1757
+ data8 0xf20361ee8f1c711e, 0xf23695da7de51d3f
+ data8 0xf258d095e465cc35, 0xf28c4d0bfc982b34
+ data8 0xf2bff55eb3f0ea71, 0xf2f3c9cf9884636e
+ data8 0xf31670135ab9cc0f, 0xf34a8e9f0b54cdfb
+ data8 0xf37ed9fa6b8add3f, 0xf3a1cfe884ef6bb6
+ data8 0xf3d66689dcc8e8d3, 0xf40b2ab069d5c96a
+ data8 0xf42e718b90c8bc16, 0xf463822a0a3b4b00
+ data8 0xf498c1076015faf8, 0xf4bc5a19a33990b5
+ data8 0xf4f1e6a7d6f5425f, 0xf527a232cf6be334
+ data8 0xf54b8ecdcda90851, 0xf5819949c7ad87b4
+ data8 0xf5a5bac9213b48a9, 0xf5dc1501f324a812
+ data8 0xf6006bee86b5589e, 0xf63716b2fa067fa4
+ data8 0xf66df22fb6132b9c, 0xf6929fb98225deb1
+ data8 0xf6c9cd13021e3fea, 0xf6eeb177472cedae
+ data8 0xf713abf4cb0b3afb, 0xf74b4d5333684ef1
+ data8 0xf7707f75a72f8e94, 0xf7a874b97927af44
+ data8 0xf7cddf140aedf1d8, 0xf806291bacb7f7a9
+ data8 0xf82bcc43b92eafef, 0xf8646bf0defb759e
+ data8 0xf88a487dfc3ff5f7, 0xf8b03c2b46cdc17f
+ data8 0xf8e95541c152ae7a, 0xf90f832c2700c160
+ data8 0xf935c88e0c7f419b, 0xf96f5cd84fd86873
+ data8 0xf995dd53ebdd9d6d, 0xf9bc75a034436a41
+ data8 0xf9f686f26d5518de, 0xfa1d5b39b910a8c5
+ data8 0xfa4447acc4ecbfd2, 0xfa7ed7e51e6fdfb4
+ data8 0xfaa601394d49a1a0, 0xfacd431644ce0e40
+ data8 0xfaf49d96f7a75909, 0xfb2fd3c65e562fd5
+ data8 0xfb576c5762024805, 0xfb7f1debc22c4040
+ data8 0xfba6e89f32d0190a, 0xfbe2c803a0894893
+ data8 0xfc0ad1ff0ed9ecf0, 0xfc32f57bdfbcbe7f
+ data8 0xfc5b32968f99b21c, 0xfc83896bc861ab08
+ data8 0xfcabfa1861ed4815, 0xfce8d3cea7d3163e
+ data8 0xfd118595143ee273, 0xfd3a519943d4865a
+ data8 0xfd6337f8e1ae5a4b, 0xfd8c38d1c8e927eb
+ data8 0xfdb5544205095a53, 0xfdde8a67d2613531
+ data8 0xfe07db619e781611, 0xfe460768d80bf758
+ data8 0xfe6f9bfb06cd32f6, 0xfe994bcd3d14fcc2
+ data8 0xfec316fecaf3f2ab, 0xfeecfdaf33fadb80
+ data8 0xff16fffe2fa8fad6, 0xff411e0ba9db886d
+ data8 0xff6b57f7c33e4e9a, 0xff95ade2d1bd7358
+ data8 0xffc01fed60f86fb5, 0xffeaae3832b63956
+LOCAL_OBJECT_END(T_table)
+
+
+LOCAL_OBJECT_START(D_table)
+
+ data4 0x1e50f488, 0x1ebdc559, 0x1e649ec1, 0x9eed9b2c
+ data4 0x9e511c44, 0x9ec6d551, 0x9eefe248, 0x9e313854
+ data4 0x9f54ff18, 0x9d231411, 0x1ee5d63c, 0x9edf6b95
+ data4 0x9f332aaa, 0x1dc92a84, 0x1f73fb7b, 0x1e32f100
+ data4 0x9ea636f5, 0x9f6c3353, 0x9f405552, 0x1f33fd97
+ data4 0x1e975291, 0x9e59a11e, 0x1e47b0ba, 0x9d8ad33e
+ data4 0x1ea51bf6, 0x1f25d782, 0x9ecf534d, 0x1f55436f
+ data4 0x1d0975e4, 0x9f0633a1, 0x1f3e840a, 0x1f523a4c
+ data4 0x9f53cbbc, 0x9c8b5661, 0x9f6bc8eb, 0x1f4f6c7b
+ data4 0x9ed9b376, 0x9f5b30b6, 0x1f64fa5e, 0x1cbcc3e0
+ data4 0x1f343548, 0x1f62a6a2, 0x9f336abb, 0x9f1d15af
+ data4 0x1f476c83, 0x1ea86421, 0x1f33b2cf, 0x9e8f1348
+ data4 0x1f6fa829, 0x9f30ee3a, 0x9ebd6146, 0x1f2db598
+ data4 0x1ef9600d, 0x1f5b1427, 0x9edd741b, 0x1f51ef4e
+ data4 0x9f1aa57d, 0x9ee9b5e0, 0x9f17ecd7, 0x1ead71ff
+ data4 0x1f6c910e, 0x9e1837df, 0x9f0f17d9, 0x9e8350dd
+ data4 0x9d292f1b, 0x9e33b3ab, 0x9d6f0fe8, 0x9ed8c7cc
+ data4 0x9ec598c8, 0x9d56758c, 0x1e090c1e, 0x9ed4b941
+ data4 0x9f1fc4cf, 0x1f63513a, 0x9edd0abc, 0x1e3924dd
+ data4 0x1f60d56f, 0x1ea84424, 0x9e88f4fb, 0x1f205c09
+ data4 0x1ec9ae4e, 0x1d2d5738, 0x9f2c9f6d, 0x1e0765c2
+ data4 0x1e8bbdd7, 0x9f16d9f1, 0x9ea62627, 0x1f13904c
+ data4 0x1e566ab8, 0x9dca3d1a, 0x9e91f2a1, 0x9f14641c
+ data4 0x9f278946, 0x1f490c1e, 0x1f575eb6, 0x1f50b3fd
+ data4 0x9da32efb, 0x1ea95e59, 0x9e41e058, 0x9eada15f
+ data4 0x9e4fe66c, 0x1f3abc98, 0x1f1b8d1e, 0x9ece97e4
+ data4 0x1d188aed, 0x9e89b6ee, 0x1f287478, 0x9e8a161a
+ data4 0x1e4749f7, 0x9e68084a, 0x1e867f33, 0x9f462b63
+ data4 0x1db30792, 0x1f59a767, 0x9d1da4ae, 0x9f472a33
+ data4 0x1d1e91cd, 0x9f414824, 0x9f473d4f, 0x1f4b5783
+ data4 0x9f5b04b8, 0x9f5c205b, 0x1f309617, 0x9f0d6852
+ data4 0x9d96a609, 0x9f0965c2, 0x9e23f467, 0x9f089884
+ data4 0x9ec71458, 0x9ed6e955, 0x1e5e8691, 0x1f5b2bbc
+ data4 0x9f128268, 0x1ed40f5b, 0x1dc430ce, 0x1f345986
+ data4 0x1d778f72, 0x1e9b11d6, 0x9f5a40be, 0x9e07f61a
+ data4 0x9ed641a7, 0x9f334787, 0x1e952fd0, 0x1edeb5e2
+ data4 0x9e9f3eb1, 0x9e379fd9, 0x1f13102a, 0x9e5e80e1
+ data4 0x1c757944, 0x1dae2260, 0x1f183ab7, 0x1e55d576
+ data4 0x9e6bb99f, 0x9f52d7cb, 0x9e73a0f5, 0x1d4e1d14
+ data4 0x9dd05b53, 0x1f2261e4, 0x9d4ee73d, 0x1ede515e
+ data4 0x1f22a573, 0x9ecac348, 0x1e6a2ac0, 0x1e2787d2
+ data4 0x9eb64b87, 0x1f0c69c6, 0x9f470a01, 0x9d7c1686
+ data4 0x1e468ebe, 0x9f21ee2f, 0x9ee52116, 0x9e20f715
+ data4 0x1ed18533, 0x9f005b38, 0x9f20cb95, 0x1da72967
+ data4 0x1f1ba5d7, 0x1e2f8b16, 0x9c794f96, 0x9ca74ea3
+ data4 0x1f410555, 0x9eff2b96, 0x1ce8f0b1, 0x1f0cee77
+ data4 0x1f191edd, 0x9ed5fcbc, 0x1f30f242, 0x9e0ad369
+ data4 0x1ed8f3c8, 0x1f52bb0e, 0x9e9ce408, 0x1f18907f
+ data4 0x9ecdad40, 0x9e8af91d, 0x1d46698a, 0x9f4b93d6
+ data4 0x9f3f5d33, 0x1e2e52f7, 0x9f13aeec, 0x9f3b1969
+ data4 0x1f0996f4, 0x9f2a03df, 0x1e264767, 0x1f3ab1fb
+ data4 0x9f3193c9, 0x9f21ce22, 0x9eab624c, 0x9ecd8fb1
+ data4 0x1eaf9a85, 0x1f0c6a2c, 0x1eecbe61, 0x1f3fead9
+ data4 0x1f1d3a29, 0x1e9099ce, 0x1eadd875, 0x1e4dbfb8
+ data4 0x9dc640d2, 0x1f413680, 0x9f3f57b3, 0x1dfa1553
+ data4 0x1ec71c6b, 0x1e00cc00, 0x9f271e55, 0x1e5a88bb
+ data4 0x1f46cc2b, 0x1ee80ff9, 0x9e29c6f3, 0x1f15e229
+ data4 0x9ea83d66, 0x1f37408e, 0x9dacb66e, 0x1e6f6259
+ data4 0x9f106973, 0x1dd4e5ac, 0x1cbfdcc8, 0x9f231c9f
+ data4 0x9e8677e4, 0x9e9e695a, 0x1efd782b, 0x9dd26959
+ data4 0x9e80af69, 0x1f386fb3, 0x1f022e8c, 0x9e839967
+ data4 0x1ce6796f, 0x1e4c22c2, 0x1e57ef24, 0x1e919804
+ data4 0x9d7ea090, 0x1e40140a, 0x1f261b46, 0x1db75be2
+ data4 0x1f145019, 0x9e3102b9, 0x9e22507b, 0x1eae813c
+ data4 0x1f117e97, 0x1f282296, 0x1f3814b3, 0x1e17977b
+ data4 0x1f39d6ff, 0x9f1c81b9, 0x9eb5bcad, 0x1f0f596e
+ data4 0x1e757fd5, 0x9f090daa, 0x9f2532fc, 0x9eebafbb
+ data4 0x1f086556, 0x9eeedde8, 0x9f32e174, 0x1e33c030
+ data4 0x1f1f145a, 0x1e6e556c, 0x1e419ffb, 0x9eb6019a
+ data4 0x9e872a2e, 0x1e113136, 0x1e93096f, 0x1f39be40
+ data4 0x1f1665ad, 0x9db81d7d, 0x9cd29091, 0x1e3f4af7
+ data4 0x9f23176c, 0x9eccf9b3, 0x1f34fc6c, 0x9ed36894
+ data4 0x1ef08e06, 0x9f3b46bb, 0x9f2c850b, 0x1f1565a4
+ data4 0x1e887bc3, 0x1e92629c, 0x9f11ac9e, 0x9e5579f3
+ data4 0x1e4d5790, 0x9ee1c3d1, 0x9e916aec, 0x9eb8d9b8
+ data4 0x1db46105, 0x1e168663, 0x1f26a942, 0x9f0f0383
+ data4 0x9f079032, 0x9ecae1d8, 0x1ed3b34c, 0x9edc5ee6
+ data4 0x9e8a75a7, 0x1f3c3de2, 0x9ee5041e, 0x1f08c727
+ data4 0x1d02d7ae, 0x9f36adda, 0x9ef9a857, 0x9ef5cb3a
+ data4 0x9eee73da, 0x9da5d629, 0x1e0e99be, 0x1e5159b9
+ data4 0x1f2eac89, 0x9e8eedc5, 0x1dd0ec90, 0x1f229aff
+ data4 0x1ed9c3e6, 0x1e95c55a, 0x9f0c24e4, 0x1e8afed6
+ data4 0x1e599a96, 0x1e881b21, 0x1eab84b9, 0x9ba2bb0e
+ data4 0x9e33ab10, 0x1f1710b5, 0x1ebfa271, 0x9e90bbc5
+ data4 0x9f32515b, 0x9b32aae8, 0x1eda455c, 0x1da8186e
+ data4 0x9e8917ff, 0x1ec4d08e, 0x1c90069d, 0x9f2f1d29
+ data4 0x9ecee86d, 0x9f234d1f, 0x1f370724, 0x1da87496
+ data4 0x1e7959f0, 0x9e8ada34, 0x1f1c7f6f, 0x1edd576b
+ data4 0x9de91e8b, 0x1ec4ef89, 0x1f32078a, 0x1e9925e2
+ data4 0x9d8eeccb, 0x9ea3d011, 0x1f231fdf, 0x9f1dbdfa
+ data4 0x1e7507a3, 0x1ec42614, 0x9e8693cb, 0x9ec68398
+ data4 0x1d5b05fb, 0x1de32119, 0x9f003429, 0x9ec16d92
+ data4 0x9f095315, 0x9f119d2c, 0x9ed0c984, 0x9f090662
+ data4 0x9e59aa1f, 0x9ed4e64a, 0x9f2798a7, 0x9f23624d
+ data4 0x1e0467d9, 0x1f22e7e7, 0x1e915256, 0x9cb4df70
+ data4 0x9e6f687c, 0x9e3c35e5, 0x9e5757ab, 0x9f031fa1
+ data4 0x1f25bff7, 0x1f0e58c2, 0x1ef3ce04, 0x1f002ecb
+ data4 0x9ebdc836, 0x9ed657dd, 0x9f149441, 0x9e8544b2
+ data4 0x1cd8ff1e, 0x1e9bb463, 0x1eaa1c5c, 0x1f200c1a
+ data4 0x1edbfbaf, 0x1f18724d, 0x9ed63c22, 0x9f08e045
+ data4 0x1f13ad07, 0x9e949311, 0x9f0c50d4, 0x1e824516
+ data4 0x1d5e52ba, 0x1d583fbd, 0x1e3b60a9, 0x9effe6d3
+ data4 0x1f0d0508, 0x1f00be77, 0x9e404bfa, 0x9e1ca381
+ data4 0x9f084dd8, 0x9e6db85d, 0x1db698e4, 0x9ebd1871
+ data4 0x9ecc2679, 0x1ee68442, 0x1edb1050, 0x9dbc96a4
+ data4 0x9f27c1f4, 0x1c99b756, 0x1eb4400a, 0x9f24390a
+ data4 0x1d927875, 0x9f074faa, 0x1e9dc2c3, 0x1f13c0d2
+ data4 0x1e3c9685, 0x9e6b6f75, 0x9db9cb31, 0x1ea5f3aa
+ data4 0x9d992c61, 0x1f1015e4, 0x1f194f70, 0x9e19d2b3
+ data4 0x9d89116c, 0x1f23cd35, 0x1e33d3a2, 0x1ee331b8
+ data4 0x1d5ba7ec, 0x9f273788, 0x9e6907f4, 0x9ed5f912
+ data4 0x9edd458d, 0x1e2ca7b2, 0x1ef81fe4, 0x1dc7ade6
+ data4 0x1e876e51, 0x9f04ec89, 0x1f1da63a, 0x1ec02bd0
+ data4 0x9e71326f, 0x1e7847b4, 0x1f0de618, 0x9e036cb6
+ data4 0x1eec61e2, 0x1ef1758b, 0x9ee880a3, 0x1ed269d7
+ data4 0x1e27edd3, 0x9e8a81a1, 0x1eacb84d, 0x9e1aad37
+ data4 0x1f1aa8f7, 0x1e9bbd90, 0x1ea1b61f, 0x9ed41c2f
+ data4 0x1dbb5dd6, 0x1f0ec733, 0x9df06b1b, 0x1e06fef1
+ data4 0x9edede3a, 0x1edeb5e2, 0x1f0e63ee, 0x9db316bb
+ data4 0x9efc1ad3, 0x1f01fbb5, 0x9cc0d078, 0x1ea28b36
+ data4 0x9e9dd205, 0x9e791534, 0x1da1c8d5, 0x9e8195cc
+ data4 0x1f0681a4, 0x1eeaf1e2, 0x9ef83b37, 0x9f22a92b
+ data4 0x1eabc4ce, 0x1f10eefb, 0x1e06d9aa, 0x1e7cacd5
+ data4 0x1f1ea087, 0x1eb21983, 0x9f100c78, 0x1e840abe
+ data4 0x9efab66c, 0x1f183fa8, 0x9e84ee68, 0x9eea083d
+ data4 0x9ee23a74, 0x1f1351d7, 0x9ec5d42a, 0x9f071f57
+ data4 0x9ef578d9, 0x9f1aa7e7, 0x1eb02044, 0x1f151a2e
+ data4 0x9c0dc8b2, 0x9ef4087a, 0x1ec12b93, 0x1c1a946b
+ data4 0x1e89946f, 0x9dafe8c3, 0x1d295288, 0x9e8497ab
+ data4 0x1ec000c6, 0x1e102f29, 0x1e542256, 0x1e67d44d
+ data4 0x1ef688d8, 0x1f0e0f29, 0x1e67861f, 0x1e869748
+ data4 0x1ee6aa6e, 0x9e4d228b, 0x9e50be5b, 0x1e9fe225
+ data4 0x9ea34102, 0x9e628a3b, 0x9ed9fd83, 0x1ecd7109
+ data4 0x1f1864ff, 0x1ea19b76, 0x1db0d1c9, 0x9dff519b
+ data4 0x1e8fea71, 0x9ee82e9a, 0x9f08919b, 0x9ef5c8ae
+ data4 0x9ee446a4, 0x1ea59444, 0x1eb74230, 0x1ea13fbf
+ data4 0x9ea6a3ea, 0x1e5f2797, 0x9e0adb07, 0x9d3adadd
+ data4 0x1ebf2ee2, 0x1da19bfa, 0x1e8dea6d, 0x1ec4fea9
+ data4 0x1e669f22, 0x1dc5f919, 0x9ed25caa, 0x1ee475b1
+ data4 0x1ed0603e, 0x9eacb35c, 0x1dc00b27, 0x1e2f9991
+ data4 0x1e7b0406, 0x1eaa3387, 0x9d865bde, 0x1eb78a48
+ data4 0x1c40ae2e, 0x1ee9838b, 0x9f0f0d7f, 0x1e3e5d26
+ data4 0x1e99e7a6, 0x9e681ccf, 0x9e93ed65, 0x9eeb6a66
+ data4 0x1e29e9af, 0x9e96f923, 0x9e74f11d, 0x9f1474da
+ data4 0x1eec2ea7, 0x1ebf7aa3, 0x9c25dcca, 0x9f0553c2
+ data4 0x9e599efd, 0x1d2ab490, 0x1e95d7cd, 0x9ee4b20e
+ data4 0x9d988ce5, 0x9ef9787e, 0x9dbbba5b, 0x9f12c304
+ data4 0x1e3b9d70, 0x1e7bcae8, 0x9d98bb6e, 0x9e8e6b01
+ data4 0x9f07d03b, 0x9d67c822, 0x9f0ef69e, 0x1c7c0fe3
+ data4 0x9e9bfbb9, 0x9e83b84b, 0x1efbf15e, 0x9ecfa6a6
+ data4 0x9c91158e, 0x9ecf6770, 0x1ee1e3a8, 0x9dc95ec0
+ data4 0x1ef603f7, 0x1d5e52ba, 0x1c477d1b, 0x9e955cd8
+ data4 0x1ed665b0, 0x9e8376c4, 0x9c0ee88e, 0x1e8c989e
+ data4 0x1ea2df29, 0x9d961e5c, 0x1e101813, 0x1e7fffff
+ data4 0x9e5abff4, 0x1dbddd71, 0x1eb69100, 0x1e71f114
+ data4 0x1e9ca798, 0x1ef62c8d, 0x9db4e55a, 0x1dbe69ce
+ data4 0x9ef1c01f, 0x1f044a2a, 0x9eb9e0d7, 0x9ee59745
+ data4 0x9e874803, 0x1ea0b418, 0x9e13572a, 0x1ddbb3a2
+ data4 0x9ec0e391, 0x1e89fba1, 0x1ee8b261, 0x9e5d25f0
+ data4 0x9ef222cb, 0x9ef135ec, 0x1ea04b9a, 0x9f04291f
+ data4 0x9e969254, 0x9ee32f08, 0x9ed909d3, 0x9e362640
+ data4 0x9ec20735, 0x1e50131b, 0x9ed4e049, 0x1ee8e817
+ data4 0x1e1e09c0, 0x9ea643c5, 0x9e5a1ab6, 0x9e389059
+ data4 0x1e560947, 0x1d02b877, 0x1e4475ab, 0x9ea9aaf6
+ data4 0x1e95bc5e, 0x1eaf6afd, 0x1d43067d, 0x9d043821
+ data4 0x9e97baa9, 0x1de5c4f9, 0x9e9a0069, 0x9e1b9944
+ data4 0x1eb13686, 0x9eb907eb, 0x1e059589, 0x1cbd0f93
+ data4 0x9eb7e6ae, 0x1e9fa175, 0x1ee5bdf4, 0x1e8052f7
+ data4 0x9c80d1e3, 0x1bfbe28e, 0x9e672b3b, 0x9ecacf19
+ data4 0x9e3c04be, 0x1dfe8c5c, 0x1e1ba9cb, 0x1eb40b1e
+ data4 0x1ec7e7f6, 0x9d0d45b3, 0x1ef0113b, 0x9a155fa3
+ data4 0x1e28ec3b, 0x1e7ca8df, 0x9d2f91b4, 0x1eccd9ed
+ data4 0x9ed943bc, 0x9ccaab19, 0x9e8a5c58, 0x1ec3bca8
+ data4 0x1ed78dc7, 0x9ed391a8, 0x9e938f6e, 0x9ec4a030
+ data4 0x9e80346e, 0x1e7a4686, 0x9e284315, 0x9e39584c
+ data4 0x1ebdc9b4, 0x9e9cfce5, 0x9ef55c65, 0x1e2941e7
+ data4 0x9efbe59f, 0x1d87c41b, 0x1e40befc, 0x1e3d05b5
+ data4 0x1de9ea67, 0x1ec9a21c, 0x1decb69a, 0x1df6e75a
+ data4 0x9e8030ab, 0x9db20540, 0x9ef1e977, 0x1e3cdc43
+ data4 0x1e0492b0, 0x9e91d872, 0x1e775346, 0x9e939978
+ data4 0x1eb2714e, 0x1e49a203, 0x9e10195a, 0x1ef1ffc3
+ data4 0x9ea8b709, 0x9e832e27, 0x1ed5ac3b, 0x1edb20a6
+ data4 0x1e4dbd4e, 0x1efbb932, 0x1d8170ec, 0x1e6c4849
+ data4 0x1f008e17, 0x1e8000c4, 0x1d855ecf, 0x9e37cb85
+ data4 0x1ecffdf5, 0x1eba6519, 0x9edbe600, 0x1ea3e5e7
+ data4 0x1ed4fb39, 0x1f00be77, 0x1e6f4484, 0x9e9e7107
+ data4 0x9e30b29d, 0x9ee6e174, 0x1e3a2656, 0x9dd72f3f
+ data4 0x9ee12138, 0x1ed16fed, 0x9ece8a02, 0x9ca5b249
+ data4 0x9eafd508, 0x9ef0e9fc, 0x1d1307ac, 0x1eecee20
+ data4 0x1cf60c6f, 0x9d556216, 0x9eaed175, 0x9ec919f4
+ data4 0x1ec2c988, 0x1cd82772, 0x9dc99456, 0x1eab0467
+ data4 0x1e89b36f, 0x1c757944, 0x1eef9abd, 0x9e98664d
+LOCAL_OBJECT_END(D_table)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(cbrtl)
+
+{ .mfi
+ getf.sig GR_ARGSIG = f8
+ // will continue on main path only for normal/denormal numbers
+ // all other values will be filtered out and will exit early
+ fclass.nm.unc p12, p7 = f8, 0x1b
+ // GR_ADDR = pointer to C_1...C_6 followed by T_table
+ addl GR_ADDR = @ltoff(poly_coeffs), gp
+}
+{ .mfi
+ // GR_BIAS23 = 2/3*bias -63 = 0xaaaa-0x3f = 0xaa6b
+ mov GR_BIAS23 = 0xaa6b
+ // normalize a
+ fma.s1 FR_XNORM = f8, f1, f0
+ // GR_D_ADDR = pointer to D table
+ addl GR_D_ADDR = @ltoff(D_table), gp
+}
+;;
+
+{ .mmf
+ // load start address for C_1...C_6 followed by T_table
+ ld8 GR_C_START = [ GR_ADDR ]
+ // load start address of D table
+ ld8 GR_D_START = [ GR_D_ADDR ]
+ // y = frcpa(a)
+ frcpa.s1 FR_RCP, p6 = f1, f8
+}
+;;
+
+{ .mmi
+ // get normalized significand
+ getf.sig GR_NORMSIG = FR_XNORM
+ // get exponent
+ getf.exp GR_NORMEXPSGN = FR_XNORM
+ (p7) cmp.eq p12, p0 = GR_ARGSIG, r0
+}
+;;
+
+{ .mii
+ // load C_1
+ ldfe FR_C1 = [ GR_C_START ], 16
+ mov GR_SGNMASK = 0x20000
+ nop.i 0
+}
+;;
+
+{ .mfb
+ // load C_2
+ ldfe FR_C2 = [ GR_C_START ], 16
+ (p12) fma.s0 f8 = f8, f1, f0
+ // NaN/Infinities exit early
+ (p12) br.ret.spnt b0
+}
+;;
+
+{ .mfi
+ // load C_3, C_4
+ ldfpd FR_C3, FR_C4 = [ GR_C_START ], 16
+ // y = frcpa(a), set flags and result when argument is 0
+ // only used when p6=0
+ frcpa.s0 f8, p0 = f1, f8
+ nop.i 0
+}
+;;
+
+{ .mii
+ // get GR_SIGN = sign
+ and GR_SIGN = GR_NORMEXPSGN, GR_SGNMASK
+ // eliminate leading 1 from GR_NORMSIG = 2nd table index
+ shl GR_INDEX2 = GR_NORMSIG, 1
+ // eliminate sign from exponent
+ andcm GR_NORMEXP = GR_NORMEXPSGN, GR_SGNMASK
+}
+;;
+
+{ .mfi
+ // load C_5, C_6
+ (p6) ldfpd FR_C5, FR_C6 = [ GR_C_START ], 16
+ // r = 1-a*y
+ (p6) fnma.s1 FR_R = FR_RCP, FR_XNORM, f1
+ // Start computation of floor(exponent/3) by
+ // computing (2^20+2)/3*exponent = exponent*0x55556
+ // 1: exponent* = 5;
+ // (2^{16}-1)/3 = 0x5555:
+ // will form 0x5555*exponent by using shladd's
+ shladd GR_EXP5 = GR_NORMEXP, 2, GR_NORMEXP
+}
+;;
+
+{ .mib
+ // Next several integer steps compute floor(exponent/3)
+ // GR_TMP1 = (5*expon)*16
+ shladd GR_TMP1 = GR_EXP5, 4, r0
+ // GR_EXP3 = 3*exponent
+ shladd GR_EXP3 = GR_NORMEXP, 1, GR_NORMEXP
+ nop.b 0
+}
+;;
+
+{ .mmi
+ // GR_EXP6 = 6*exponent
+ shladd GR_EXP6 = GR_EXP3, 1, r0
+ // GR_EXP17 = 17*expon
+ add GR_EXP17 = GR_EXP5, GR_TMP1
+ // GR_IX2 = 2nd table index (8 bits)
+ shr.u GR_IX2 = GR_INDEX2, 56
+}
+;;
+
+{ .mmi
+ // adjust T_table pointer by 2nd index
+ shladd GR_T_INDEX = GR_IX2, 3, GR_C_START
+ // adjust D_table pointer by 2nd index
+ shladd GR_D_INDEX = GR_IX2, 2, GR_D_START
+ // GR_TMP2 = (17*expon)*16^2
+ shl GR_TMP2 = GR_EXP17, 8
+}
+;;
+
+{ .mmi
+ // GR_TMP3 = expon*(2^16-1)/3
+ add GR_TMP3 = GR_EXP17, GR_TMP2
+;;
+ // GR_TMP4 = expon*(2^20+2)/3 = expon*0x55556
+ shladd GR_TMP4 = GR_TMP3, 4, GR_EXP6
+ nop.i 0
+}
+;;
+
+{ .mii
+ nop.m 0
+ // GR_EXP_RES = floor(expon/3)
+ shr.u GR_EXP_RES = GR_TMP4, 20
+ nop.i 0
+}
+;;
+
+{ .mmi
+ nop.m 0
+ // r16 = 3*exponent
+ shladd r16 = GR_EXP_RES, 1, GR_EXP_RES
+ // bias exponent
+ add GR_EXPBIAS = GR_BIAS23, GR_EXP_RES
+}
+;;
+
+{ .mmi
+ // get remainder of exponent/3
+ sub GR_EXP_MOD_3 = GR_NORMEXP, r16
+;;
+ // add sign to exponent
+ or GR_EXPSIGNRES = GR_EXPBIAS, GR_SIGN
+ // remainder << = 8
+ shl GR_REMTMP = GR_EXP_MOD_3, 8
+}
+;;
+
+{ .mfi
+ // adjust D_table pointer by 1st index
+ shladd GR_IX_D = GR_REMTMP, 2, GR_D_INDEX
+ // P_1 = C_1+C_2*r
+ (p6) fma.s1 FR_P1 = FR_C2, FR_R, FR_C1
+ // adjust T_table pointer by 1st index
+ shladd GR_IX_T = GR_REMTMP, 3, GR_T_INDEX
+}
+{ .mfi
+ // FR_SGNEXP = sign*2^{exponent/3}
+ (p6) setf.exp FR_SGNEXP = GR_EXPSIGNRES
+ // r^2 = r*r
+ (p6) fma.s1 FR_R2 = FR_R, FR_R, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ // load D
+ (p6) ldfs FR_D = [ GR_IX_D ]
+ // P_2 = C_3+C_4*r
+ (p6) fma.s1 FR_P2 = FR_C4, FR_R, FR_C3
+ nop.i 0
+}
+{ .mfi
+ // load T
+ (p6) ldf8 FR_T = [ GR_IX_T ]
+ // P_3 = C_5+C_6*r
+ (p6) fma.s1 FR_P3 = FR_C6, FR_R, FR_C5
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // P_4 = D-r*P_1
+ (p6) fnma.s1 FR_P4 = FR_R, FR_P1, FR_D
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // r^3 = r*r^2
+ (p6) fma.s1 FR_R3 = FR_R, FR_R2, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // P_5 = P_2+r2*P_3
+ (p6) fma.s1 FR_P5 = FR_R2, FR_P3, FR_P2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // T = T*(sign*2^{exponent/3})
+ (p6) fma.s1 FR_TF = FR_T, FR_SGNEXP, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // P = P_4-r3*P_5
+ (p6) fnma.s1 FR_P = FR_R3, FR_P5, FR_P4
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ // result = T+T*p
+ (p6) fma.s0 f8 = FR_TF, FR_P, FR_TF
+ br.ret.sptk b0
+}
+;;
+
+GLOBAL_LIBM_END(cbrtl)
+
+
diff --git a/libc/sysdeps/ia64/fpu/s_ceil.S b/libc/sysdeps/ia64/fpu/s_ceil.S
new file mode 100644
index 000000000..d1d298061
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_ceil.S
@@ -0,0 +1,224 @@
+.file "ceil.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 06/13/00 Improved speed
+// 06/27/00 Eliminated incorrect invalid flag setting
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/28/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// double ceil(double x)
+//==============================================================
+
+// general input registers:
+// r14 - r19
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rM1 = r18
+rSignexpM1 = r19
+
+// floating-point registers:
+// f8 - f13
+
+fXInt = f9
+fNormX = f10
+fTmp = f11
+fAdj = f12
+fPreResult = f13
+
+// predicate registers used:
+// p6 - p10
+
+// Overview of operation
+//==============================================================
+// double ceil(double x)
+// Return an integer value (represented as a double) that is the smallest
+// value not less than x
+// This is x rounded toward +infinity to an integral value.
+// Inexact is set if x != ceil(x)
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(ceil)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ addl rBigexp = 0x10033, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rM1 = -1 // Set all ones
+ fcvt.fx.trunc.s1 fXInt = f8 // Convert to int in significand
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ mov rSignexpM1 = 0x2FFFF // Form signexp of -1
+ fcmp.lt.s1 p8,p9 = f8, f0 // Test x < 0
+ nop.i 0
+}
+{ .mfb
+ setf.sig fTmp = rM1 // Make const for setting inexact
+ fnorm.s1 fNormX = f8 // Normalize input
+(p7) br.cond.spnt CEIL_UNORM // Branch if x unorm
+}
+;;
+
+CEIL_COMMON:
+// Return here from CEIL_UNORM
+{ .mfi
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x1e7 // Test x natval, nan, inf, 0
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fAdj = f0, f0, f0 // If x < 0, adjustment is 0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fAdj = f1, f1, f0 // If x > 0, adjustment is +1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf fPreResult = fXInt // trunc(x)
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p6) fma.d.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf, 0
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf, 0
+}
+;;
+
+{ .mmi
+ and rExp = rSignexp, rExpMask // Get biased exponent
+;;
+ cmp.ge p7,p6 = rExp, rBigexp // Is |x| >= 2^52?
+(p8) cmp.lt.unc p10,p0 = rSignexp, rSignexpM1 // Is -1 < x < 0?
+}
+;;
+
+// If -1 < x < 0, we turn off p6 and compute result as -0
+{ .mfi
+(p10) cmp.ne p6,p0 = r0,r0
+(p10) fmerge.s f8 = fNormX, f0
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fma.d.s0 f8 = fPreResult, f1, fAdj // Result if !int, |x| < 2^52
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.d.s0 f8 = fNormX, f1, f0 // Result, if |x| >= 2^52
+(p10) cmp.eq p6,p0 = r0,r0 // If -1 < x < 0, turn on p6 again
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fcmp.eq.unc.s1 p8, p9 = fPreResult, fNormX // Is trunc(x) = x ?
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fmpy.s0 fTmp = fTmp, fTmp // Dummy to set inexact
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fma.d.s0 f8 = fNormX, f1, f0 // If x int, result normalized x
+ br.ret.sptk b0 // Exit main path, 0 < |x| < 2^52
+}
+;;
+
+
+CEIL_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk CEIL_COMMON // Return to main path
+}
+;;
+
+GLOBAL_LIBM_END(ceil)
diff --git a/libc/sysdeps/ia64/fpu/s_ceilf.S b/libc/sysdeps/ia64/fpu/s_ceilf.S
new file mode 100644
index 000000000..051534a20
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_ceilf.S
@@ -0,0 +1,224 @@
+.file "ceilf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 06/13/00 Improved speed
+// 06/27/00 Eliminated incorrect invalid flag setting
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/28/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// float ceilf(float x)
+//==============================================================
+
+// general input registers:
+// r14 - r19
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rM1 = r18
+rSignexpM1 = r19
+
+// floating-point registers:
+// f8 - f13
+
+fXInt = f9
+fNormX = f10
+fTmp = f11
+fAdj = f12
+fPreResult = f13
+
+// predicate registers used:
+// p6 - p10
+
+// Overview of operation
+//==============================================================
+// float ceilf(float x)
+// Return an integer value (represented as a float) that is the smallest
+// value not less than x
+// This is x rounded toward +infinity to an integral value.
+// Inexact is set if x != ceilf(x)
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(ceilf)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ addl rBigexp = 0x10016, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rM1 = -1 // Set all ones
+ fcvt.fx.trunc.s1 fXInt = f8 // Convert to int in significand
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ mov rSignexpM1 = 0x2FFFF // Form signexp of -1
+ fcmp.lt.s1 p8,p9 = f8, f0 // Test x < 0
+ nop.i 0
+}
+{ .mfb
+ setf.sig fTmp = rM1 // Make const for setting inexact
+ fnorm.s1 fNormX = f8 // Normalize input
+(p7) br.cond.spnt CEIL_UNORM // Branch if x unorm
+}
+;;
+
+CEIL_COMMON:
+// Return here from CEIL_UNORM
+{ .mfi
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x1e7 // Test x natval, nan, inf, 0
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fAdj = f0, f0, f0 // If x < 0, adjustment is 0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fAdj = f1, f1, f0 // If x > 0, adjustment is +1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf fPreResult = fXInt // trunc(x)
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p6) fma.s.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf, 0
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf, 0
+}
+;;
+
+{ .mmi
+ and rExp = rSignexp, rExpMask // Get biased exponent
+;;
+ cmp.ge p7,p6 = rExp, rBigexp // Is |x| >= 2^23?
+(p8) cmp.lt.unc p10,p0 = rSignexp, rSignexpM1 // Is -1 < x < 0?
+}
+;;
+
+// If -1 < x < 0, we turn off p6 and compute result as -0
+{ .mfi
+(p10) cmp.ne p6,p0 = r0,r0
+(p10) fmerge.s f8 = fNormX, f0
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fma.s.s0 f8 = fPreResult, f1, fAdj // Result if !int, |x| < 2^23
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s.s0 f8 = fNormX, f1, f0 // Result, if |x| >= 2^23
+(p10) cmp.eq p6,p0 = r0,r0 // If -1 < x < 0, turn on p6 again
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fcmp.eq.unc.s1 p8, p9 = fPreResult, fNormX // Is trunc(x) = x ?
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fmpy.s0 fTmp = fTmp, fTmp // Dummy to set inexact
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fma.s.s0 f8 = fNormX, f1, f0 // If x int, result normalized x
+ br.ret.sptk b0 // Exit main path, 0 < |x| < 2^23
+}
+;;
+
+
+CEIL_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk CEIL_COMMON // Return to main path
+}
+;;
+
+GLOBAL_LIBM_END(ceilf)
diff --git a/libc/sysdeps/ia64/fpu/s_ceill.S b/libc/sysdeps/ia64/fpu/s_ceill.S
new file mode 100644
index 000000000..71cb01d3f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_ceill.S
@@ -0,0 +1,224 @@
+.file "ceill.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 06/13/00 Improved speed
+// 06/27/00 Eliminated incorrect invalid flag setting
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/28/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// long double ceill(long double x)
+//==============================================================
+
+// general input registers:
+// r14 - r19
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rM1 = r18
+rSignexpM1 = r19
+
+// floating-point registers:
+// f8 - f13
+
+fXInt = f9
+fNormX = f10
+fTmp = f11
+fAdj = f12
+fPreResult = f13
+
+// predicate registers used:
+// p6 - p10
+
+// Overview of operation
+//==============================================================
+// long double ceill(long double x)
+// Return an integer value (represented as a long double) that is the smallest
+// value not less than x
+// This is x rounded toward +infinity to an integral value.
+// Inexact is set if x != ceill(x)
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(ceill)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ addl rBigexp = 0x1003e, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rM1 = -1 // Set all ones
+ fcvt.fx.trunc.s1 fXInt = f8 // Convert to int in significand
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ mov rSignexpM1 = 0x2FFFF // Form signexp of -1
+ fcmp.lt.s1 p8,p9 = f8, f0 // Test x < 0
+ nop.i 0
+}
+{ .mfb
+ setf.sig fTmp = rM1 // Make const for setting inexact
+ fnorm.s1 fNormX = f8 // Normalize input
+(p7) br.cond.spnt CEIL_UNORM // Branch if x unorm
+}
+;;
+
+CEIL_COMMON:
+// Return here from CEIL_UNORM
+{ .mfi
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x1e7 // Test x natval, nan, inf, 0
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fAdj = f0, f0, f0 // If x < 0, adjustment is 0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fAdj = f1, f1, f0 // If x > 0, adjustment is +1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf fPreResult = fXInt // trunc(x)
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p6) fma.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf, 0
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf, 0
+}
+;;
+
+{ .mmi
+ and rExp = rSignexp, rExpMask // Get biased exponent
+;;
+ cmp.ge p7,p6 = rExp, rBigexp // Is |x| >= 2^63?
+(p8) cmp.lt.unc p10,p0 = rSignexp, rSignexpM1 // Is -1 < x < 0?
+}
+;;
+
+// If -1 < x < 0, we turn off p6 and compute result as -0
+{ .mfi
+(p10) cmp.ne p6,p0 = r0,r0
+(p10) fmerge.s f8 = fNormX, f0
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fma.s0 f8 = fPreResult, f1, fAdj // Result if !int, |x| < 2^63
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s0 f8 = fNormX, f1, f0 // Result, if |x| >= 2^63
+(p10) cmp.eq p6,p0 = r0,r0 // If -1 < x < 0, turn on p6 again
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fcmp.eq.unc.s1 p8, p9 = fPreResult, fNormX // Is trunc(x) = x ?
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fmpy.s0 fTmp = fTmp, fTmp // Dummy to set inexact
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fma.s0 f8 = fNormX, f1, f0 // If x int, result normalized x
+ br.ret.sptk b0 // Exit main path, 0 < |x| < 2^63
+}
+;;
+
+
+CEIL_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk CEIL_COMMON // Return to main path
+}
+;;
+
+GLOBAL_LIBM_END(ceill)
diff --git a/libc/sysdeps/ia64/fpu/s_copysign.S b/libc/sysdeps/ia64/fpu/s_copysign.S
new file mode 100644
index 000000000..0903565ff
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_copysign.S
@@ -0,0 +1,38 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#undef ret
+
+ENTRY (__copysign)
+{
+ fmerge.s fret0 = farg1, farg0
+ br.ret.sptk.many rp
+}
+END (__copysign)
+
+strong_alias (__copysign, __copysignf)
+strong_alias (__copysign, __copysignl)
+
+strong_alias (__copysign, __libm_copysign)
+strong_alias (__copysign, __libm_copysignf)
+strong_alias (__copysign, __libm_copysignl)
+
+weak_alias (__copysign, copysign)
+weak_alias (__copysignf, copysignf)
+weak_alias (__copysignl, copysignl)
diff --git a/libc/sysdeps/ia64/fpu/s_copysignf.S b/libc/sysdeps/ia64/fpu/s_copysignf.S
new file mode 100644
index 000000000..055251d0d
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_copysignf.S
@@ -0,0 +1 @@
+/* __copysignf is in s_copysign.S. */
diff --git a/libc/sysdeps/ia64/fpu/s_copysignl.S b/libc/sysdeps/ia64/fpu/s_copysignl.S
new file mode 100644
index 000000000..e77237267
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_copysignl.S
@@ -0,0 +1 @@
+/* __copysignl is in s_copysign.S. */
diff --git a/libc/sysdeps/ia64/fpu/s_cos.S b/libc/sysdeps/ia64/fpu/s_cos.S
new file mode 100644
index 000000000..fc121fce1
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_cos.S
@@ -0,0 +1,768 @@
+.file "sincos.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/02/00 Unwind support added.
+// 06/16/00 Updated tables to enforce symmetry
+// 08/31/00 Saved 2 cycles in main path, and 9 in other paths.
+// 09/20/00 The updated tables regressed to an old version, so reinstated them
+// 10/18/00 Changed one table entry to ensure symmetry
+// 01/03/01 Improved speed, fixed flag settings for small arguments.
+// 02/18/02 Large arguments processing routine excluded
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 06/03/02 Insure inexact flag set for large arg result
+// 09/05/02 Work range is widened by reduction strengthen (3 parts of Pi/16)
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 08/08/03 Improved performance
+// 10/28/04 Saved sincos_r_sincos to avoid clobber by dynamic loader
+// 03/31/05 Reformatted delimiters between data tables
+
+// API
+//==============================================================
+// double sin( double x);
+// double cos( double x);
+//
+// Overview of operation
+//==============================================================
+//
+// Step 1
+// ======
+// Reduce x to region -1/2*pi/2^k ===== 0 ===== +1/2*pi/2^k where k=4
+// divide x by pi/2^k.
+// Multiply by 2^k/pi.
+// nfloat = Round result to integer (round-to-nearest)
+//
+// r = x - nfloat * pi/2^k
+// Do this as ((((x - nfloat * HIGH(pi/2^k))) -
+// nfloat * LOW(pi/2^k)) -
+// nfloat * LOWEST(pi/2^k) for increased accuracy.
+// pi/2^k is stored as two numbers that when added make pi/2^k.
+// pi/2^k = HIGH(pi/2^k) + LOW(pi/2^k)
+// HIGH and LOW parts are rounded to zero values,
+// and LOWEST is rounded to nearest one.
+//
+// x = (nfloat * pi/2^k) + r
+// r is small enough that we can use a polynomial approximation
+// and is referred to as the reduced argument.
+//
+// Step 3
+// ======
+// Take the unreduced part and remove the multiples of 2pi.
+// So nfloat = nfloat (with lower k+1 bits cleared) + lower k+1 bits
+//
+// nfloat (with lower k+1 bits cleared) is a multiple of 2^(k+1)
+// N * 2^(k+1)
+// nfloat * pi/2^k = N * 2^(k+1) * pi/2^k + (lower k+1 bits) * pi/2^k
+// nfloat * pi/2^k = N * 2 * pi + (lower k+1 bits) * pi/2^k
+// nfloat * pi/2^k = N2pi + M * pi/2^k
+//
+//
+// Sin(x) = Sin((nfloat * pi/2^k) + r)
+// = Sin(nfloat * pi/2^k) * Cos(r) + Cos(nfloat * pi/2^k) * Sin(r)
+//
+// Sin(nfloat * pi/2^k) = Sin(N2pi + Mpi/2^k)
+// = Sin(N2pi)Cos(Mpi/2^k) + Cos(N2pi)Sin(Mpi/2^k)
+// = Sin(Mpi/2^k)
+//
+// Cos(nfloat * pi/2^k) = Cos(N2pi + Mpi/2^k)
+// = Cos(N2pi)Cos(Mpi/2^k) + Sin(N2pi)Sin(Mpi/2^k)
+// = Cos(Mpi/2^k)
+//
+// Sin(x) = Sin(Mpi/2^k) Cos(r) + Cos(Mpi/2^k) Sin(r)
+//
+//
+// Step 4
+// ======
+// 0 <= M < 2^(k+1)
+// There are 2^(k+1) Sin entries in a table.
+// There are 2^(k+1) Cos entries in a table.
+//
+// Get Sin(Mpi/2^k) and Cos(Mpi/2^k) by table lookup.
+//
+//
+// Step 5
+// ======
+// Calculate Cos(r) and Sin(r) by polynomial approximation.
+//
+// Cos(r) = 1 + r^2 q1 + r^4 q2 + r^6 q3 + ... = Series for Cos
+// Sin(r) = r + r^3 p1 + r^5 p2 + r^7 p3 + ... = Series for Sin
+//
+// and the coefficients q1, q2, ... and p1, p2, ... are stored in a table
+//
+//
+// Calculate
+// Sin(x) = Sin(Mpi/2^k) Cos(r) + Cos(Mpi/2^k) Sin(r)
+//
+// as follows
+//
+// S[m] = Sin(Mpi/2^k) and C[m] = Cos(Mpi/2^k)
+// rsq = r*r
+//
+//
+// P = p1 + r^2p2 + r^4p3 + r^6p4
+// Q = q1 + r^2q2 + r^4q3 + r^6q4
+//
+// rcub = r * rsq
+// Sin(r) = r + rcub * P
+// = r + r^3p1 + r^5p2 + r^7p3 + r^9p4 + ... = Sin(r)
+//
+// The coefficients are not exactly these values, but almost.
+//
+// p1 = -1/6 = -1/3!
+// p2 = 1/120 = 1/5!
+// p3 = -1/5040 = -1/7!
+// p4 = 1/362889 = 1/9!
+//
+// P = r + rcub * P
+//
+// Answer = S[m] Cos(r) + [Cm] P
+//
+// Cos(r) = 1 + rsq Q
+// Cos(r) = 1 + r^2 Q
+// Cos(r) = 1 + r^2 (q1 + r^2q2 + r^4q3 + r^6q4)
+// Cos(r) = 1 + r^2q1 + r^4q2 + r^6q3 + r^8q4 + ...
+//
+// S[m] Cos(r) = S[m](1 + rsq Q)
+// S[m] Cos(r) = S[m] + Sm rsq Q
+// S[m] Cos(r) = S[m] + s_rsq Q
+// Q = S[m] + s_rsq Q
+//
+// Then,
+//
+// Answer = Q + C[m] P
+
+
+// Registers used
+//==============================================================
+// general input registers:
+// r14 -> r26
+// r32 -> r35
+
+// predicate registers used:
+// p6 -> p11
+
+// floating-point registers used
+// f9 -> f15
+// f32 -> f61
+
+// Assembly macros
+//==============================================================
+sincos_NORM_f8 = f9
+sincos_W = f10
+sincos_int_Nfloat = f11
+sincos_Nfloat = f12
+
+sincos_r = f13
+sincos_rsq = f14
+sincos_rcub = f15
+sincos_save_tmp = f15
+
+sincos_Inv_Pi_by_16 = f32
+sincos_Pi_by_16_1 = f33
+sincos_Pi_by_16_2 = f34
+
+sincos_Inv_Pi_by_64 = f35
+
+sincos_Pi_by_16_3 = f36
+
+sincos_r_exact = f37
+
+sincos_Sm = f38
+sincos_Cm = f39
+
+sincos_P1 = f40
+sincos_Q1 = f41
+sincos_P2 = f42
+sincos_Q2 = f43
+sincos_P3 = f44
+sincos_Q3 = f45
+sincos_P4 = f46
+sincos_Q4 = f47
+
+sincos_P_temp1 = f48
+sincos_P_temp2 = f49
+
+sincos_Q_temp1 = f50
+sincos_Q_temp2 = f51
+
+sincos_P = f52
+sincos_Q = f53
+
+sincos_srsq = f54
+
+sincos_SIG_INV_PI_BY_16_2TO61 = f55
+sincos_RSHF_2TO61 = f56
+sincos_RSHF = f57
+sincos_2TOM61 = f58
+sincos_NFLOAT = f59
+sincos_W_2TO61_RSH = f60
+
+fp_tmp = f61
+
+/////////////////////////////////////////////////////////////
+
+sincos_GR_sig_inv_pi_by_16 = r14
+sincos_GR_rshf_2to61 = r15
+sincos_GR_rshf = r16
+sincos_GR_exp_2tom61 = r17
+sincos_GR_n = r18
+sincos_GR_m = r19
+sincos_GR_32m = r19
+sincos_GR_all_ones = r19
+sincos_AD_1 = r20
+sincos_AD_2 = r21
+sincos_exp_limit = r22
+sincos_r_signexp = r23
+sincos_r_17_ones = r24
+sincos_r_sincos = r25
+sincos_r_exp = r26
+
+GR_SAVE_PFS = r33
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+GR_SAVE_r_sincos = r36
+
+
+RODATA
+
+// Pi/16 parts
+.align 16
+LOCAL_OBJECT_START(double_sincos_pi)
+ data8 0xC90FDAA22168C234, 0x00003FFC // pi/16 1st part
+ data8 0xC4C6628B80DC1CD1, 0x00003FBC // pi/16 2nd part
+ data8 0xA4093822299F31D0, 0x00003F7A // pi/16 3rd part
+LOCAL_OBJECT_END(double_sincos_pi)
+
+// Coefficients for polynomials
+LOCAL_OBJECT_START(double_sincos_pq_k4)
+ data8 0x3EC71C963717C63A // P4
+ data8 0x3EF9FFBA8F191AE6 // Q4
+ data8 0xBF2A01A00F4E11A8 // P3
+ data8 0xBF56C16C05AC77BF // Q3
+ data8 0x3F8111111110F167 // P2
+ data8 0x3FA555555554DD45 // Q2
+ data8 0xBFC5555555555555 // P1
+ data8 0xBFDFFFFFFFFFFFFC // Q1
+LOCAL_OBJECT_END(double_sincos_pq_k4)
+
+// Sincos table (S[m], C[m])
+LOCAL_OBJECT_START(double_sin_cos_beta_k4)
+
+data8 0x0000000000000000 , 0x00000000 // sin( 0 pi/16) S0
+data8 0x8000000000000000 , 0x00003fff // cos( 0 pi/16) C0
+//
+data8 0xc7c5c1e34d3055b3 , 0x00003ffc // sin( 1 pi/16) S1
+data8 0xfb14be7fbae58157 , 0x00003ffe // cos( 1 pi/16) C1
+//
+data8 0xc3ef1535754b168e , 0x00003ffd // sin( 2 pi/16) S2
+data8 0xec835e79946a3146 , 0x00003ffe // cos( 2 pi/16) C2
+//
+data8 0x8e39d9cd73464364 , 0x00003ffe // sin( 3 pi/16) S3
+data8 0xd4db3148750d181a , 0x00003ffe // cos( 3 pi/16) C3
+//
+data8 0xb504f333f9de6484 , 0x00003ffe // sin( 4 pi/16) S4
+data8 0xb504f333f9de6484 , 0x00003ffe // cos( 4 pi/16) C4
+//
+data8 0xd4db3148750d181a , 0x00003ffe // sin( 5 pi/16) C3
+data8 0x8e39d9cd73464364 , 0x00003ffe // cos( 5 pi/16) S3
+//
+data8 0xec835e79946a3146 , 0x00003ffe // sin( 6 pi/16) C2
+data8 0xc3ef1535754b168e , 0x00003ffd // cos( 6 pi/16) S2
+//
+data8 0xfb14be7fbae58157 , 0x00003ffe // sin( 7 pi/16) C1
+data8 0xc7c5c1e34d3055b3 , 0x00003ffc // cos( 7 pi/16) S1
+//
+data8 0x8000000000000000 , 0x00003fff // sin( 8 pi/16) C0
+data8 0x0000000000000000 , 0x00000000 // cos( 8 pi/16) S0
+//
+data8 0xfb14be7fbae58157 , 0x00003ffe // sin( 9 pi/16) C1
+data8 0xc7c5c1e34d3055b3 , 0x0000bffc // cos( 9 pi/16) -S1
+//
+data8 0xec835e79946a3146 , 0x00003ffe // sin(10 pi/16) C2
+data8 0xc3ef1535754b168e , 0x0000bffd // cos(10 pi/16) -S2
+//
+data8 0xd4db3148750d181a , 0x00003ffe // sin(11 pi/16) C3
+data8 0x8e39d9cd73464364 , 0x0000bffe // cos(11 pi/16) -S3
+//
+data8 0xb504f333f9de6484 , 0x00003ffe // sin(12 pi/16) S4
+data8 0xb504f333f9de6484 , 0x0000bffe // cos(12 pi/16) -S4
+//
+data8 0x8e39d9cd73464364 , 0x00003ffe // sin(13 pi/16) S3
+data8 0xd4db3148750d181a , 0x0000bffe // cos(13 pi/16) -C3
+//
+data8 0xc3ef1535754b168e , 0x00003ffd // sin(14 pi/16) S2
+data8 0xec835e79946a3146 , 0x0000bffe // cos(14 pi/16) -C2
+//
+data8 0xc7c5c1e34d3055b3 , 0x00003ffc // sin(15 pi/16) S1
+data8 0xfb14be7fbae58157 , 0x0000bffe // cos(15 pi/16) -C1
+//
+data8 0x0000000000000000 , 0x00000000 // sin(16 pi/16) S0
+data8 0x8000000000000000 , 0x0000bfff // cos(16 pi/16) -C0
+//
+data8 0xc7c5c1e34d3055b3 , 0x0000bffc // sin(17 pi/16) -S1
+data8 0xfb14be7fbae58157 , 0x0000bffe // cos(17 pi/16) -C1
+//
+data8 0xc3ef1535754b168e , 0x0000bffd // sin(18 pi/16) -S2
+data8 0xec835e79946a3146 , 0x0000bffe // cos(18 pi/16) -C2
+//
+data8 0x8e39d9cd73464364 , 0x0000bffe // sin(19 pi/16) -S3
+data8 0xd4db3148750d181a , 0x0000bffe // cos(19 pi/16) -C3
+//
+data8 0xb504f333f9de6484 , 0x0000bffe // sin(20 pi/16) -S4
+data8 0xb504f333f9de6484 , 0x0000bffe // cos(20 pi/16) -S4
+//
+data8 0xd4db3148750d181a , 0x0000bffe // sin(21 pi/16) -C3
+data8 0x8e39d9cd73464364 , 0x0000bffe // cos(21 pi/16) -S3
+//
+data8 0xec835e79946a3146 , 0x0000bffe // sin(22 pi/16) -C2
+data8 0xc3ef1535754b168e , 0x0000bffd // cos(22 pi/16) -S2
+//
+data8 0xfb14be7fbae58157 , 0x0000bffe // sin(23 pi/16) -C1
+data8 0xc7c5c1e34d3055b3 , 0x0000bffc // cos(23 pi/16) -S1
+//
+data8 0x8000000000000000 , 0x0000bfff // sin(24 pi/16) -C0
+data8 0x0000000000000000 , 0x00000000 // cos(24 pi/16) S0
+//
+data8 0xfb14be7fbae58157 , 0x0000bffe // sin(25 pi/16) -C1
+data8 0xc7c5c1e34d3055b3 , 0x00003ffc // cos(25 pi/16) S1
+//
+data8 0xec835e79946a3146 , 0x0000bffe // sin(26 pi/16) -C2
+data8 0xc3ef1535754b168e , 0x00003ffd // cos(26 pi/16) S2
+//
+data8 0xd4db3148750d181a , 0x0000bffe // sin(27 pi/16) -C3
+data8 0x8e39d9cd73464364 , 0x00003ffe // cos(27 pi/16) S3
+//
+data8 0xb504f333f9de6484 , 0x0000bffe // sin(28 pi/16) -S4
+data8 0xb504f333f9de6484 , 0x00003ffe // cos(28 pi/16) S4
+//
+data8 0x8e39d9cd73464364 , 0x0000bffe // sin(29 pi/16) -S3
+data8 0xd4db3148750d181a , 0x00003ffe // cos(29 pi/16) C3
+//
+data8 0xc3ef1535754b168e , 0x0000bffd // sin(30 pi/16) -S2
+data8 0xec835e79946a3146 , 0x00003ffe // cos(30 pi/16) C2
+//
+data8 0xc7c5c1e34d3055b3 , 0x0000bffc // sin(31 pi/16) -S1
+data8 0xfb14be7fbae58157 , 0x00003ffe // cos(31 pi/16) C1
+//
+data8 0x0000000000000000 , 0x00000000 // sin(32 pi/16) S0
+data8 0x8000000000000000 , 0x00003fff // cos(32 pi/16) C0
+LOCAL_OBJECT_END(double_sin_cos_beta_k4)
+
+.section .text
+
+////////////////////////////////////////////////////////
+// There are two entry points: sin and cos
+
+
+// If from sin, p8 is true
+// If from cos, p9 is true
+
+GLOBAL_IEEE754_ENTRY(sin)
+
+{ .mlx
+ getf.exp sincos_r_signexp = f8
+ movl sincos_GR_sig_inv_pi_by_16 = 0xA2F9836E4E44152A // signd of 16/pi
+}
+{ .mlx
+ addl sincos_AD_1 = @ltoff(double_sincos_pi), gp
+ movl sincos_GR_rshf_2to61 = 0x47b8000000000000 // 1.1 2^(63+63-2)
+}
+;;
+
+{ .mfi
+ ld8 sincos_AD_1 = [sincos_AD_1]
+ fnorm.s0 sincos_NORM_f8 = f8 // Normalize argument
+ cmp.eq p8,p9 = r0, r0 // set p8 (clear p9) for sin
+}
+{ .mib
+ mov sincos_GR_exp_2tom61 = 0xffff-61 // exponent of scale 2^-61
+ mov sincos_r_sincos = 0x0 // sincos_r_sincos = 0 for sin
+ br.cond.sptk _SINCOS_COMMON // go to common part
+}
+;;
+
+GLOBAL_IEEE754_END(sin)
+
+GLOBAL_IEEE754_ENTRY(cos)
+
+{ .mlx
+ getf.exp sincos_r_signexp = f8
+ movl sincos_GR_sig_inv_pi_by_16 = 0xA2F9836E4E44152A // signd of 16/pi
+}
+{ .mlx
+ addl sincos_AD_1 = @ltoff(double_sincos_pi), gp
+ movl sincos_GR_rshf_2to61 = 0x47b8000000000000 // 1.1 2^(63+63-2)
+}
+;;
+
+{ .mfi
+ ld8 sincos_AD_1 = [sincos_AD_1]
+ fnorm.s1 sincos_NORM_f8 = f8 // Normalize argument
+ cmp.eq p9,p8 = r0, r0 // set p9 (clear p8) for cos
+}
+{ .mib
+ mov sincos_GR_exp_2tom61 = 0xffff-61 // exp of scale 2^-61
+ mov sincos_r_sincos = 0x8 // sincos_r_sincos = 8 for cos
+ nop.b 999
+}
+;;
+
+////////////////////////////////////////////////////////
+// All entry points end up here.
+// If from sin, sincos_r_sincos is 0 and p8 is true
+// If from cos, sincos_r_sincos is 8 = 2^(k-1) and p9 is true
+// We add sincos_r_sincos to N
+
+///////////// Common sin and cos part //////////////////
+_SINCOS_COMMON:
+
+
+// Form two constants we need
+// 16/pi * 2^-2 * 2^63, scaled by 2^61 since we just loaded the significand
+// 1.1000...000 * 2^(63+63-2) to right shift int(W) into the low significand
+{ .mfi
+ setf.sig sincos_SIG_INV_PI_BY_16_2TO61 = sincos_GR_sig_inv_pi_by_16
+ fclass.m p6,p0 = f8, 0xe7 // if x = 0,inf,nan
+ mov sincos_exp_limit = 0x1001a
+}
+{ .mlx
+ setf.d sincos_RSHF_2TO61 = sincos_GR_rshf_2to61
+ movl sincos_GR_rshf = 0x43e8000000000000 // 1.1 2^63
+} // Right shift
+;;
+
+// Form another constant
+// 2^-61 for scaling Nfloat
+// 0x1001a is register_bias + 27.
+// So if f8 >= 2^27, go to large argument routines
+{ .mfi
+ alloc r32 = ar.pfs, 1, 4, 0, 0
+ fclass.m p11,p0 = f8, 0x0b // Test for x=unorm
+ mov sincos_GR_all_ones = -1 // For "inexect" constant create
+}
+{ .mib
+ setf.exp sincos_2TOM61 = sincos_GR_exp_2tom61
+ nop.i 999
+(p6) br.cond.spnt _SINCOS_SPECIAL_ARGS
+}
+;;
+
+// Load the two pieces of pi/16
+// Form another constant
+// 1.1000...000 * 2^63, the right shift constant
+{ .mmb
+ ldfe sincos_Pi_by_16_1 = [sincos_AD_1],16
+ setf.d sincos_RSHF = sincos_GR_rshf
+(p11) br.cond.spnt _SINCOS_UNORM // Branch if x=unorm
+}
+;;
+
+_SINCOS_COMMON2:
+// Return here if x=unorm
+// Create constant used to set inexact
+{ .mmi
+ ldfe sincos_Pi_by_16_2 = [sincos_AD_1],16
+ setf.sig fp_tmp = sincos_GR_all_ones
+ nop.i 999
+};;
+
+// Select exponent (17 lsb)
+{ .mfi
+ ldfe sincos_Pi_by_16_3 = [sincos_AD_1],16
+ nop.f 999
+ dep.z sincos_r_exp = sincos_r_signexp, 0, 17
+};;
+
+// Polynomial coefficients (Q4, P4, Q3, P3, Q2, Q1, P2, P1) loading
+// p10 is true if we must call routines to handle larger arguments
+// p10 is true if f8 exp is >= 0x1001a (2^27)
+{ .mmb
+ ldfpd sincos_P4,sincos_Q4 = [sincos_AD_1],16
+ cmp.ge p10,p0 = sincos_r_exp,sincos_exp_limit
+(p10) br.cond.spnt _SINCOS_LARGE_ARGS // Go to "large args" routine
+};;
+
+// sincos_W = x * sincos_Inv_Pi_by_16
+// Multiply x by scaled 16/pi and add large const to shift integer part of W to
+// rightmost bits of significand
+{ .mfi
+ ldfpd sincos_P3,sincos_Q3 = [sincos_AD_1],16
+ fma.s1 sincos_W_2TO61_RSH = sincos_NORM_f8,sincos_SIG_INV_PI_BY_16_2TO61,sincos_RSHF_2TO61
+ nop.i 999
+};;
+
+// get N = (int)sincos_int_Nfloat
+// sincos_NFLOAT = Round_Int_Nearest(sincos_W)
+// This is done by scaling back by 2^-61 and subtracting the shift constant
+{ .mmf
+ getf.sig sincos_GR_n = sincos_W_2TO61_RSH
+ ldfpd sincos_P2,sincos_Q2 = [sincos_AD_1],16
+ fms.s1 sincos_NFLOAT = sincos_W_2TO61_RSH,sincos_2TOM61,sincos_RSHF
+};;
+
+// sincos_r = -sincos_Nfloat * sincos_Pi_by_16_1 + x
+{ .mfi
+ ldfpd sincos_P1,sincos_Q1 = [sincos_AD_1],16
+ fnma.s1 sincos_r = sincos_NFLOAT, sincos_Pi_by_16_1, sincos_NORM_f8
+ nop.i 999
+};;
+
+// Add 2^(k-1) (which is in sincos_r_sincos) to N
+{ .mmi
+ add sincos_GR_n = sincos_GR_n, sincos_r_sincos
+;;
+// Get M (least k+1 bits of N)
+ and sincos_GR_m = 0x1f,sincos_GR_n
+ nop.i 999
+};;
+
+// sincos_r = sincos_r -sincos_Nfloat * sincos_Pi_by_16_2
+{ .mfi
+ nop.m 999
+ fnma.s1 sincos_r = sincos_NFLOAT, sincos_Pi_by_16_2, sincos_r
+ shl sincos_GR_32m = sincos_GR_m,5
+};;
+
+// Add 32*M to address of sin_cos_beta table
+// For sin denorm. - set uflow
+{ .mfi
+ add sincos_AD_2 = sincos_GR_32m, sincos_AD_1
+(p8) fclass.m.unc p10,p0 = f8,0x0b
+ nop.i 999
+};;
+
+// Load Sin and Cos table value using obtained index m (sincosf_AD_2)
+{ .mfi
+ ldfe sincos_Sm = [sincos_AD_2],16
+ nop.f 999
+ nop.i 999
+};;
+
+// get rsq = r*r
+{ .mfi
+ ldfe sincos_Cm = [sincos_AD_2]
+ fma.s1 sincos_rsq = sincos_r, sincos_r, f0 // r^2 = r*r
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s0 fp_tmp = fp_tmp,fp_tmp // forces inexact flag
+ nop.i 999
+};;
+
+// sincos_r_exact = sincos_r -sincos_Nfloat * sincos_Pi_by_16_3
+{ .mfi
+ nop.m 999
+ fnma.s1 sincos_r_exact = sincos_NFLOAT, sincos_Pi_by_16_3, sincos_r
+ nop.i 999
+};;
+
+// Polynomials calculation
+// P_1 = P4*r^2 + P3
+// Q_2 = Q4*r^2 + Q3
+{ .mfi
+ nop.m 999
+ fma.s1 sincos_P_temp1 = sincos_rsq, sincos_P4, sincos_P3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 sincos_Q_temp1 = sincos_rsq, sincos_Q4, sincos_Q3
+ nop.i 999
+};;
+
+// get rcube = r^3 and S[m]*r^2
+{ .mfi
+ nop.m 999
+ fmpy.s1 sincos_srsq = sincos_Sm,sincos_rsq
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 sincos_rcub = sincos_r_exact, sincos_rsq
+ nop.i 999
+};;
+
+// Polynomials calculation
+// Q_2 = Q_1*r^2 + Q2
+// P_1 = P_1*r^2 + P2
+{ .mfi
+ nop.m 999
+ fma.s1 sincos_Q_temp2 = sincos_rsq, sincos_Q_temp1, sincos_Q2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 sincos_P_temp2 = sincos_rsq, sincos_P_temp1, sincos_P2
+ nop.i 999
+};;
+
+// Polynomials calculation
+// Q = Q_2*r^2 + Q1
+// P = P_2*r^2 + P1
+{ .mfi
+ nop.m 999
+ fma.s1 sincos_Q = sincos_rsq, sincos_Q_temp2, sincos_Q1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 sincos_P = sincos_rsq, sincos_P_temp2, sincos_P1
+ nop.i 999
+};;
+
+// Get final P and Q
+// Q = Q*S[m]*r^2 + S[m]
+// P = P*r^3 + r
+{ .mfi
+ nop.m 999
+ fma.s1 sincos_Q = sincos_srsq,sincos_Q, sincos_Sm
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 sincos_P = sincos_rcub,sincos_P, sincos_r_exact
+ nop.i 999
+};;
+
+// If sin(denormal), force underflow to be set
+{ .mfi
+ nop.m 999
+(p10) fmpy.d.s0 fp_tmp = sincos_NORM_f8,sincos_NORM_f8
+ nop.i 999
+};;
+
+// Final calculation
+// result = C[m]*P + Q
+{ .mfb
+ nop.m 999
+ fma.d.s0 f8 = sincos_Cm, sincos_P, sincos_Q
+ br.ret.sptk b0 // Exit for common path
+};;
+
+////////// x = 0/Inf/NaN path //////////////////
+_SINCOS_SPECIAL_ARGS:
+.pred.rel "mutex",p8,p9
+// sin(+/-0) = +/-0
+// sin(Inf) = NaN
+// sin(NaN) = NaN
+{ .mfi
+ nop.m 999
+(p8) fma.d.s0 f8 = f8, f0, f0 // sin(+/-0,NaN,Inf)
+ nop.i 999
+}
+// cos(+/-0) = 1.0
+// cos(Inf) = NaN
+// cos(NaN) = NaN
+{ .mfb
+ nop.m 999
+(p9) fma.d.s0 f8 = f8, f0, f1 // cos(+/-0,NaN,Inf)
+ br.ret.sptk b0 // Exit for x = 0/Inf/NaN path
+};;
+
+_SINCOS_UNORM:
+// Here if x=unorm
+{ .mfb
+ getf.exp sincos_r_signexp = sincos_NORM_f8 // Get signexp of x
+ fcmp.eq.s0 p11,p0 = f8, f0 // Dummy op to set denorm flag
+ br.cond.sptk _SINCOS_COMMON2 // Return to main path
+};;
+
+GLOBAL_IEEE754_END(cos)
+
+//////////// x >= 2^27 - large arguments routine call ////////////
+LOCAL_LIBM_ENTRY(__libm_callout_sincos)
+_SINCOS_LARGE_ARGS:
+.prologue
+{ .mfi
+ mov GR_SAVE_r_sincos = sincos_r_sincos // Save sin or cos
+ nop.f 999
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS = ar.pfs
+}
+;;
+
+{ .mfi
+ mov GR_SAVE_GP = gp
+ nop.f 999
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0 = b0
+}
+
+.body
+{ .mbb
+ setf.sig sincos_save_tmp = sincos_GR_all_ones// inexact set
+ nop.b 999
+(p8) br.call.sptk.many b0 = __libm_sin_large# // sin(large_X)
+
+};;
+
+{ .mbb
+ cmp.ne p9,p0 = GR_SAVE_r_sincos, r0 // set p9 if cos
+ nop.b 999
+(p9) br.call.sptk.many b0 = __libm_cos_large# // cos(large_X)
+};;
+
+{ .mfi
+ mov gp = GR_SAVE_GP
+ fma.d.s0 f8 = f8, f1, f0 // Round result to double
+ mov b0 = GR_SAVE_B0
+}
+// Force inexact set
+{ .mfi
+ nop.m 999
+ fmpy.s0 sincos_save_tmp = sincos_save_tmp, sincos_save_tmp
+ nop.i 999
+};;
+
+{ .mib
+ nop.m 999
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0 // Exit for large arguments routine call
+};;
+
+LOCAL_LIBM_END(__libm_callout_sincos)
+
+.type __libm_sin_large#,@function
+.global __libm_sin_large#
+.type __libm_cos_large#,@function
+.global __libm_cos_large#
+
diff --git a/libc/sysdeps/ia64/fpu/s_cosf.S b/libc/sysdeps/ia64/fpu/s_cosf.S
new file mode 100644
index 000000000..bcdf1b0c0
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_cosf.S
@@ -0,0 +1,717 @@
+.file "sincosf.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/02/00 Unwind support added.
+// 06/16/00 Updated tables to enforce symmetry
+// 08/31/00 Saved 2 cycles in main path, and 9 in other paths.
+// 09/20/00 The updated tables regressed to an old version, so reinstated them
+// 10/18/00 Changed one table entry to ensure symmetry
+// 01/03/01 Improved speed, fixed flag settings for small arguments.
+// 02/18/02 Large arguments processing routine excluded
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 06/03/02 Insure inexact flag set for large arg result
+// 09/05/02 Single precision version is made using double precision one as base
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// float sinf( float x);
+// float cosf( float x);
+//
+// Overview of operation
+//==============================================================
+//
+// Step 1
+// ======
+// Reduce x to region -1/2*pi/2^k ===== 0 ===== +1/2*pi/2^k where k=4
+// divide x by pi/2^k.
+// Multiply by 2^k/pi.
+// nfloat = Round result to integer (round-to-nearest)
+//
+// r = x - nfloat * pi/2^k
+// Do this as (x - nfloat * HIGH(pi/2^k)) - nfloat * LOW(pi/2^k)
+
+// for increased accuracy.
+// pi/2^k is stored as two numbers that when added make pi/2^k.
+// pi/2^k = HIGH(pi/2^k) + LOW(pi/2^k)
+// HIGH part is rounded to zero, LOW - to nearest
+//
+// x = (nfloat * pi/2^k) + r
+// r is small enough that we can use a polynomial approximation
+// and is referred to as the reduced argument.
+//
+// Step 3
+// ======
+// Take the unreduced part and remove the multiples of 2pi.
+// So nfloat = nfloat (with lower k+1 bits cleared) + lower k+1 bits
+//
+// nfloat (with lower k+1 bits cleared) is a multiple of 2^(k+1)
+// N * 2^(k+1)
+// nfloat * pi/2^k = N * 2^(k+1) * pi/2^k + (lower k+1 bits) * pi/2^k
+// nfloat * pi/2^k = N * 2 * pi + (lower k+1 bits) * pi/2^k
+// nfloat * pi/2^k = N2pi + M * pi/2^k
+//
+//
+// Sin(x) = Sin((nfloat * pi/2^k) + r)
+// = Sin(nfloat * pi/2^k) * Cos(r) + Cos(nfloat * pi/2^k) * Sin(r)
+//
+// Sin(nfloat * pi/2^k) = Sin(N2pi + Mpi/2^k)
+// = Sin(N2pi)Cos(Mpi/2^k) + Cos(N2pi)Sin(Mpi/2^k)
+// = Sin(Mpi/2^k)
+//
+// Cos(nfloat * pi/2^k) = Cos(N2pi + Mpi/2^k)
+// = Cos(N2pi)Cos(Mpi/2^k) + Sin(N2pi)Sin(Mpi/2^k)
+// = Cos(Mpi/2^k)
+//
+// Sin(x) = Sin(Mpi/2^k) Cos(r) + Cos(Mpi/2^k) Sin(r)
+//
+//
+// Step 4
+// ======
+// 0 <= M < 2^(k+1)
+// There are 2^(k+1) Sin entries in a table.
+// There are 2^(k+1) Cos entries in a table.
+//
+// Get Sin(Mpi/2^k) and Cos(Mpi/2^k) by table lookup.
+//
+//
+// Step 5
+// ======
+// Calculate Cos(r) and Sin(r) by polynomial approximation.
+//
+// Cos(r) = 1 + r^2 q1 + r^4 q2 = Series for Cos
+// Sin(r) = r + r^3 p1 + r^5 p2 = Series for Sin
+//
+// and the coefficients q1, q2 and p1, p2 are stored in a table
+//
+//
+// Calculate
+// Sin(x) = Sin(Mpi/2^k) Cos(r) + Cos(Mpi/2^k) Sin(r)
+//
+// as follows
+//
+// S[m] = Sin(Mpi/2^k) and C[m] = Cos(Mpi/2^k)
+// rsq = r*r
+//
+//
+// P = P1 + r^2*P2
+// Q = Q1 + r^2*Q2
+//
+// rcub = r * rsq
+// Sin(r) = r + rcub * P
+// = r + r^3p1 + r^5p2 = Sin(r)
+//
+// The coefficients are not exactly these values, but almost.
+//
+// p1 = -1/6 = -1/3!
+// p2 = 1/120 = 1/5!
+// p3 = -1/5040 = -1/7!
+// p4 = 1/362889 = 1/9!
+//
+// P = r + r^3 * P
+//
+// Answer = S[m] Cos(r) + C[m] P
+//
+// Cos(r) = 1 + rsq Q
+// Cos(r) = 1 + r^2 Q
+// Cos(r) = 1 + r^2 (q1 + r^2q2)
+// Cos(r) = 1 + r^2q1 + r^4q2
+//
+// S[m] Cos(r) = S[m](1 + rsq Q)
+// S[m] Cos(r) = S[m] + S[m] rsq Q
+// S[m] Cos(r) = S[m] + s_rsq Q
+// Q = S[m] + s_rsq Q
+//
+// Then,
+//
+// Answer = Q + C[m] P
+
+
+// Registers used
+//==============================================================
+// general input registers:
+// r14 -> r19
+// r32 -> r45
+
+// predicate registers used:
+// p6 -> p14
+
+// floating-point registers used
+// f9 -> f15
+// f32 -> f61
+
+// Assembly macros
+//==============================================================
+sincosf_NORM_f8 = f9
+sincosf_W = f10
+sincosf_int_Nfloat = f11
+sincosf_Nfloat = f12
+
+sincosf_r = f13
+sincosf_rsq = f14
+sincosf_rcub = f15
+sincosf_save_tmp = f15
+
+sincosf_Inv_Pi_by_16 = f32
+sincosf_Pi_by_16_1 = f33
+sincosf_Pi_by_16_2 = f34
+
+sincosf_Inv_Pi_by_64 = f35
+
+sincosf_Pi_by_16_3 = f36
+
+sincosf_r_exact = f37
+
+sincosf_Sm = f38
+sincosf_Cm = f39
+
+sincosf_P1 = f40
+sincosf_Q1 = f41
+sincosf_P2 = f42
+sincosf_Q2 = f43
+sincosf_P3 = f44
+sincosf_Q3 = f45
+sincosf_P4 = f46
+sincosf_Q4 = f47
+
+sincosf_P_temp1 = f48
+sincosf_P_temp2 = f49
+
+sincosf_Q_temp1 = f50
+sincosf_Q_temp2 = f51
+
+sincosf_P = f52
+sincosf_Q = f53
+
+sincosf_srsq = f54
+
+sincosf_SIG_INV_PI_BY_16_2TO61 = f55
+sincosf_RSHF_2TO61 = f56
+sincosf_RSHF = f57
+sincosf_2TOM61 = f58
+sincosf_NFLOAT = f59
+sincosf_W_2TO61_RSH = f60
+
+fp_tmp = f61
+
+/////////////////////////////////////////////////////////////
+
+sincosf_AD_1 = r33
+sincosf_AD_2 = r34
+sincosf_exp_limit = r35
+sincosf_r_signexp = r36
+sincosf_AD_beta_table = r37
+sincosf_r_sincos = r38
+
+sincosf_r_exp = r39
+sincosf_r_17_ones = r40
+
+sincosf_GR_sig_inv_pi_by_16 = r14
+sincosf_GR_rshf_2to61 = r15
+sincosf_GR_rshf = r16
+sincosf_GR_exp_2tom61 = r17
+sincosf_GR_n = r18
+sincosf_GR_m = r19
+sincosf_GR_32m = r19
+sincosf_GR_all_ones = r19
+
+gr_tmp = r41
+GR_SAVE_PFS = r41
+GR_SAVE_B0 = r42
+GR_SAVE_GP = r43
+
+RODATA
+.align 16
+
+// Pi/16 parts
+LOCAL_OBJECT_START(double_sincosf_pi)
+ data8 0xC90FDAA22168C234, 0x00003FFC // pi/16 1st part
+ data8 0xC4C6628B80DC1CD1, 0x00003FBC // pi/16 2nd part
+LOCAL_OBJECT_END(double_sincosf_pi)
+
+// Coefficients for polynomials
+LOCAL_OBJECT_START(double_sincosf_pq_k4)
+ data8 0x3F810FABB668E9A2 // P2
+ data8 0x3FA552E3D6DE75C9 // Q2
+ data8 0xBFC555554447BC7F // P1
+ data8 0xBFDFFFFFC447610A // Q1
+LOCAL_OBJECT_END(double_sincosf_pq_k4)
+
+// Sincos table (S[m], C[m])
+LOCAL_OBJECT_START(double_sin_cos_beta_k4)
+ data8 0x0000000000000000 // sin ( 0 Pi / 16 )
+ data8 0x3FF0000000000000 // cos ( 0 Pi / 16 )
+//
+ data8 0x3FC8F8B83C69A60B // sin ( 1 Pi / 16 )
+ data8 0x3FEF6297CFF75CB0 // cos ( 1 Pi / 16 )
+//
+ data8 0x3FD87DE2A6AEA963 // sin ( 2 Pi / 16 )
+ data8 0x3FED906BCF328D46 // cos ( 2 Pi / 16 )
+//
+ data8 0x3FE1C73B39AE68C8 // sin ( 3 Pi / 16 )
+ data8 0x3FEA9B66290EA1A3 // cos ( 3 Pi / 16 )
+//
+ data8 0x3FE6A09E667F3BCD // sin ( 4 Pi / 16 )
+ data8 0x3FE6A09E667F3BCD // cos ( 4 Pi / 16 )
+//
+ data8 0x3FEA9B66290EA1A3 // sin ( 5 Pi / 16 )
+ data8 0x3FE1C73B39AE68C8 // cos ( 5 Pi / 16 )
+//
+ data8 0x3FED906BCF328D46 // sin ( 6 Pi / 16 )
+ data8 0x3FD87DE2A6AEA963 // cos ( 6 Pi / 16 )
+//
+ data8 0x3FEF6297CFF75CB0 // sin ( 7 Pi / 16 )
+ data8 0x3FC8F8B83C69A60B // cos ( 7 Pi / 16 )
+//
+ data8 0x3FF0000000000000 // sin ( 8 Pi / 16 )
+ data8 0x0000000000000000 // cos ( 8 Pi / 16 )
+//
+ data8 0x3FEF6297CFF75CB0 // sin ( 9 Pi / 16 )
+ data8 0xBFC8F8B83C69A60B // cos ( 9 Pi / 16 )
+//
+ data8 0x3FED906BCF328D46 // sin ( 10 Pi / 16 )
+ data8 0xBFD87DE2A6AEA963 // cos ( 10 Pi / 16 )
+//
+ data8 0x3FEA9B66290EA1A3 // sin ( 11 Pi / 16 )
+ data8 0xBFE1C73B39AE68C8 // cos ( 11 Pi / 16 )
+//
+ data8 0x3FE6A09E667F3BCD // sin ( 12 Pi / 16 )
+ data8 0xBFE6A09E667F3BCD // cos ( 12 Pi / 16 )
+//
+ data8 0x3FE1C73B39AE68C8 // sin ( 13 Pi / 16 )
+ data8 0xBFEA9B66290EA1A3 // cos ( 13 Pi / 16 )
+//
+ data8 0x3FD87DE2A6AEA963 // sin ( 14 Pi / 16 )
+ data8 0xBFED906BCF328D46 // cos ( 14 Pi / 16 )
+//
+ data8 0x3FC8F8B83C69A60B // sin ( 15 Pi / 16 )
+ data8 0xBFEF6297CFF75CB0 // cos ( 15 Pi / 16 )
+//
+ data8 0x0000000000000000 // sin ( 16 Pi / 16 )
+ data8 0xBFF0000000000000 // cos ( 16 Pi / 16 )
+//
+ data8 0xBFC8F8B83C69A60B // sin ( 17 Pi / 16 )
+ data8 0xBFEF6297CFF75CB0 // cos ( 17 Pi / 16 )
+//
+ data8 0xBFD87DE2A6AEA963 // sin ( 18 Pi / 16 )
+ data8 0xBFED906BCF328D46 // cos ( 18 Pi / 16 )
+//
+ data8 0xBFE1C73B39AE68C8 // sin ( 19 Pi / 16 )
+ data8 0xBFEA9B66290EA1A3 // cos ( 19 Pi / 16 )
+//
+ data8 0xBFE6A09E667F3BCD // sin ( 20 Pi / 16 )
+ data8 0xBFE6A09E667F3BCD // cos ( 20 Pi / 16 )
+//
+ data8 0xBFEA9B66290EA1A3 // sin ( 21 Pi / 16 )
+ data8 0xBFE1C73B39AE68C8 // cos ( 21 Pi / 16 )
+//
+ data8 0xBFED906BCF328D46 // sin ( 22 Pi / 16 )
+ data8 0xBFD87DE2A6AEA963 // cos ( 22 Pi / 16 )
+//
+ data8 0xBFEF6297CFF75CB0 // sin ( 23 Pi / 16 )
+ data8 0xBFC8F8B83C69A60B // cos ( 23 Pi / 16 )
+//
+ data8 0xBFF0000000000000 // sin ( 24 Pi / 16 )
+ data8 0x0000000000000000 // cos ( 24 Pi / 16 )
+//
+ data8 0xBFEF6297CFF75CB0 // sin ( 25 Pi / 16 )
+ data8 0x3FC8F8B83C69A60B // cos ( 25 Pi / 16 )
+//
+ data8 0xBFED906BCF328D46 // sin ( 26 Pi / 16 )
+ data8 0x3FD87DE2A6AEA963 // cos ( 26 Pi / 16 )
+//
+ data8 0xBFEA9B66290EA1A3 // sin ( 27 Pi / 16 )
+ data8 0x3FE1C73B39AE68C8 // cos ( 27 Pi / 16 )
+//
+ data8 0xBFE6A09E667F3BCD // sin ( 28 Pi / 16 )
+ data8 0x3FE6A09E667F3BCD // cos ( 28 Pi / 16 )
+//
+ data8 0xBFE1C73B39AE68C8 // sin ( 29 Pi / 16 )
+ data8 0x3FEA9B66290EA1A3 // cos ( 29 Pi / 16 )
+//
+ data8 0xBFD87DE2A6AEA963 // sin ( 30 Pi / 16 )
+ data8 0x3FED906BCF328D46 // cos ( 30 Pi / 16 )
+//
+ data8 0xBFC8F8B83C69A60B // sin ( 31 Pi / 16 )
+ data8 0x3FEF6297CFF75CB0 // cos ( 31 Pi / 16 )
+//
+ data8 0x0000000000000000 // sin ( 32 Pi / 16 )
+ data8 0x3FF0000000000000 // cos ( 32 Pi / 16 )
+LOCAL_OBJECT_END(double_sin_cos_beta_k4)
+
+.section .text
+
+////////////////////////////////////////////////////////
+// There are two entry points: sin and cos
+// If from sin, p8 is true
+// If from cos, p9 is true
+
+GLOBAL_IEEE754_ENTRY(sinf)
+
+{ .mlx
+ alloc r32 = ar.pfs,1,13,0,0
+ movl sincosf_GR_sig_inv_pi_by_16 = 0xA2F9836E4E44152A //signd of 16/pi
+}
+{ .mlx
+ addl sincosf_AD_1 = @ltoff(double_sincosf_pi), gp
+ movl sincosf_GR_rshf_2to61 = 0x47b8000000000000 // 1.1 2^(63+63-2)
+};;
+
+{ .mfi
+ ld8 sincosf_AD_1 = [sincosf_AD_1]
+ fnorm.s1 sincosf_NORM_f8 = f8 // Normalize argument
+ cmp.eq p8,p9 = r0, r0 // set p8 (clear p9) for sin
+}
+{ .mib
+ mov sincosf_GR_exp_2tom61 = 0xffff-61 // exponent of scale 2^-61
+ mov sincosf_r_sincos = 0x0 // 0 for sin
+ br.cond.sptk _SINCOSF_COMMON // go to common part
+};;
+
+GLOBAL_IEEE754_END(sinf)
+
+GLOBAL_IEEE754_ENTRY(cosf)
+
+{ .mlx
+ alloc r32 = ar.pfs,1,13,0,0
+ movl sincosf_GR_sig_inv_pi_by_16 = 0xA2F9836E4E44152A //signd of 16/pi
+}
+{ .mlx
+ addl sincosf_AD_1 = @ltoff(double_sincosf_pi), gp
+ movl sincosf_GR_rshf_2to61 = 0x47b8000000000000 // 1.1 2^(63+63-2)
+};;
+
+{ .mfi
+ ld8 sincosf_AD_1 = [sincosf_AD_1]
+ fnorm.s1 sincosf_NORM_f8 = f8 // Normalize argument
+ cmp.eq p9,p8 = r0, r0 // set p9 (clear p8) for cos
+}
+{ .mib
+ mov sincosf_GR_exp_2tom61 = 0xffff-61 // exponent of scale 2^-61
+ mov sincosf_r_sincos = 0x8 // 8 for cos
+ nop.b 999
+};;
+
+////////////////////////////////////////////////////////
+// All entry points end up here.
+// If from sin, sincosf_r_sincos is 0 and p8 is true
+// If from cos, sincosf_r_sincos is 8 = 2^(k-1) and p9 is true
+// We add sincosf_r_sincos to N
+
+///////////// Common sin and cos part //////////////////
+_SINCOSF_COMMON:
+
+// Form two constants we need
+// 16/pi * 2^-2 * 2^63, scaled by 2^61 since we just loaded the significand
+// 1.1000...000 * 2^(63+63-2) to right shift int(W) into the low significand
+// fcmp used to set denormal, and invalid on snans
+{ .mfi
+ setf.sig sincosf_SIG_INV_PI_BY_16_2TO61 = sincosf_GR_sig_inv_pi_by_16
+ fclass.m p6,p0 = f8, 0xe7 // if x=0,inf,nan
+ mov sincosf_exp_limit = 0x10017
+}
+{ .mlx
+ setf.d sincosf_RSHF_2TO61 = sincosf_GR_rshf_2to61
+ movl sincosf_GR_rshf = 0x43e8000000000000 // 1.1000 2^63
+};; // Right shift
+
+// Form another constant
+// 2^-61 for scaling Nfloat
+// 0x10017 is register_bias + 24.
+// So if f8 >= 2^24, go to large argument routines
+{ .mmi
+ getf.exp sincosf_r_signexp = f8
+ setf.exp sincosf_2TOM61 = sincosf_GR_exp_2tom61
+ addl gr_tmp = -1,r0 // For "inexect" constant create
+};;
+
+// Load the two pieces of pi/16
+// Form another constant
+// 1.1000...000 * 2^63, the right shift constant
+{ .mmb
+ ldfe sincosf_Pi_by_16_1 = [sincosf_AD_1],16
+ setf.d sincosf_RSHF = sincosf_GR_rshf
+(p6) br.cond.spnt _SINCOSF_SPECIAL_ARGS
+};;
+
+// Getting argument's exp for "large arguments" filtering
+{ .mmi
+ ldfe sincosf_Pi_by_16_2 = [sincosf_AD_1],16
+ setf.sig fp_tmp = gr_tmp // constant for inexact set
+ nop.i 999
+};;
+
+// Polynomial coefficients (Q2, Q1, P2, P1) loading
+{ .mmi
+ ldfpd sincosf_P2,sincosf_Q2 = [sincosf_AD_1],16
+ nop.m 999
+ nop.i 999
+};;
+
+// Select exponent (17 lsb)
+{ .mmi
+ ldfpd sincosf_P1,sincosf_Q1 = [sincosf_AD_1],16
+ nop.m 999
+ dep.z sincosf_r_exp = sincosf_r_signexp, 0, 17
+};;
+
+// p10 is true if we must call routines to handle larger arguments
+// p10 is true if f8 exp is >= 0x10017 (2^24)
+{ .mfb
+ cmp.ge p10,p0 = sincosf_r_exp,sincosf_exp_limit
+ nop.f 999
+(p10) br.cond.spnt _SINCOSF_LARGE_ARGS // Go to "large args" routine
+};;
+
+// sincosf_W = x * sincosf_Inv_Pi_by_16
+// Multiply x by scaled 16/pi and add large const to shift integer part of W to
+// rightmost bits of significand
+{ .mfi
+ nop.m 999
+ fma.s1 sincosf_W_2TO61_RSH = sincosf_NORM_f8, sincosf_SIG_INV_PI_BY_16_2TO61, sincosf_RSHF_2TO61
+ nop.i 999
+};;
+
+// sincosf_NFLOAT = Round_Int_Nearest(sincosf_W)
+// This is done by scaling back by 2^-61 and subtracting the shift constant
+{ .mfi
+ nop.m 999
+ fms.s1 sincosf_NFLOAT = sincosf_W_2TO61_RSH,sincosf_2TOM61,sincosf_RSHF
+ nop.i 999
+};;
+
+// get N = (int)sincosf_int_Nfloat
+{ .mfi
+ getf.sig sincosf_GR_n = sincosf_W_2TO61_RSH // integer N value
+ nop.f 999
+ nop.i 999
+};;
+
+// Add 2^(k-1) (which is in sincosf_r_sincos=8) to N
+// sincosf_r = -sincosf_Nfloat * sincosf_Pi_by_16_1 + x
+{ .mfi
+ add sincosf_GR_n = sincosf_GR_n, sincosf_r_sincos
+ fnma.s1 sincosf_r = sincosf_NFLOAT, sincosf_Pi_by_16_1, sincosf_NORM_f8
+ nop.i 999
+};;
+
+// Get M (least k+1 bits of N)
+{ .mmi
+ and sincosf_GR_m = 0x1f,sincosf_GR_n // Put mask 0x1F -
+ nop.m 999 // - select k+1 bits
+ nop.i 999
+};;
+
+// Add 16*M to address of sin_cos_beta table
+{ .mfi
+ shladd sincosf_AD_2 = sincosf_GR_32m, 4, sincosf_AD_1
+(p8) fclass.m.unc p10,p0 = f8,0x0b // If sin denormal input -
+ nop.i 999
+};;
+
+// Load Sin and Cos table value using obtained index m (sincosf_AD_2)
+{ .mfi
+ ldfd sincosf_Sm = [sincosf_AD_2],8 // Sin value S[m]
+(p9) fclass.m.unc p11,p0 = f8,0x0b // If cos denormal input -
+ nop.i 999 // - set denormal
+};;
+
+// sincosf_r = sincosf_r -sincosf_Nfloat * sincosf_Pi_by_16_2
+{ .mfi
+ ldfd sincosf_Cm = [sincosf_AD_2] // Cos table value C[m]
+ fnma.s1 sincosf_r_exact = sincosf_NFLOAT, sincosf_Pi_by_16_2, sincosf_r
+ nop.i 999
+}
+// get rsq = r*r
+{ .mfi
+ nop.m 999
+ fma.s1 sincosf_rsq = sincosf_r, sincosf_r, f0 // r^2 = r*r
+ nop.i 999
+};;
+
+{ .mfi
+ nop.m 999
+ fmpy.s0 fp_tmp = fp_tmp, fp_tmp // forces inexact flag
+ nop.i 999
+};;
+
+// Polynomials calculation
+// Q = Q2*r^2 + Q1
+// P = P2*r^2 + P1
+{ .mfi
+ nop.m 999
+ fma.s1 sincosf_Q = sincosf_rsq, sincosf_Q2, sincosf_Q1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 sincosf_P = sincosf_rsq, sincosf_P2, sincosf_P1
+ nop.i 999
+};;
+
+// get rcube and S[m]*r^2
+{ .mfi
+ nop.m 999
+ fmpy.s1 sincosf_srsq = sincosf_Sm,sincosf_rsq // r^2*S[m]
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 sincosf_rcub = sincosf_r_exact, sincosf_rsq
+ nop.i 999
+};;
+
+// Get final P and Q
+// Q = Q*S[m]*r^2 + S[m]
+// P = P*r^3 + r
+{ .mfi
+ nop.m 999
+ fma.s1 sincosf_Q = sincosf_srsq,sincosf_Q, sincosf_Sm
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 sincosf_P = sincosf_rcub,sincosf_P,sincosf_r_exact
+ nop.i 999
+};;
+
+// If sinf(denormal) - force underflow to be set
+.pred.rel "mutex",p10,p11
+{ .mfi
+ nop.m 999
+(p10) fmpy.s.s0 fp_tmp = f8,f8 // forces underflow flag
+ nop.i 999 // for denormal sine args
+}
+// If cosf(denormal) - force denormal to be set
+{ .mfi
+ nop.m 999
+(p11) fma.s.s0 fp_tmp = f8, f1, f8 // forces denormal flag
+ nop.i 999 // for denormal cosine args
+};;
+
+
+// Final calculation
+// result = C[m]*P + Q
+{ .mfb
+ nop.m 999
+ fma.s.s0 f8 = sincosf_Cm, sincosf_P, sincosf_Q
+ br.ret.sptk b0 // Exit for common path
+};;
+
+////////// x = 0/Inf/NaN path //////////////////
+_SINCOSF_SPECIAL_ARGS:
+.pred.rel "mutex",p8,p9
+// sinf(+/-0) = +/-0
+// sinf(Inf) = NaN
+// sinf(NaN) = NaN
+{ .mfi
+ nop.m 999
+(p8) fma.s.s0 f8 = f8, f0, f0 // sinf(+/-0,NaN,Inf)
+ nop.i 999
+}
+// cosf(+/-0) = 1.0
+// cosf(Inf) = NaN
+// cosf(NaN) = NaN
+{ .mfb
+ nop.m 999
+(p9) fma.s.s0 f8 = f8, f0, f1 // cosf(+/-0,NaN,Inf)
+ br.ret.sptk b0 // Exit for x = 0/Inf/NaN path
+};;
+
+GLOBAL_IEEE754_END(cosf)
+
+//////////// x >= 2^24 - large arguments routine call ////////////
+LOCAL_LIBM_ENTRY(__libm_callout_sincosf)
+_SINCOSF_LARGE_ARGS:
+.prologue
+{ .mfi
+ mov sincosf_GR_all_ones = -1 // 0xffffffff
+ nop.f 999
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS = ar.pfs
+}
+;;
+
+{ .mfi
+ mov GR_SAVE_GP = gp
+ nop.f 999
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0 = b0
+}
+.body
+
+{ .mbb
+ setf.sig sincosf_save_tmp = sincosf_GR_all_ones // inexact set
+ nop.b 999
+(p8) br.call.sptk.many b0 = __libm_sin_large# // sinf(large_X)
+};;
+
+{ .mbb
+ cmp.ne p9,p0 = sincosf_r_sincos, r0 // set p9 if cos
+ nop.b 999
+(p9) br.call.sptk.many b0 = __libm_cos_large# // cosf(large_X)
+};;
+
+{ .mfi
+ mov gp = GR_SAVE_GP
+ fma.s.s0 f8 = f8, f1, f0 // Round result to single
+ mov b0 = GR_SAVE_B0
+}
+{ .mfi // force inexact set
+ nop.m 999
+ fmpy.s0 sincosf_save_tmp = sincosf_save_tmp, sincosf_save_tmp
+ nop.i 999
+};;
+
+{ .mib
+ nop.m 999
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0 // Exit for large arguments routine call
+};;
+LOCAL_LIBM_END(__libm_callout_sincosf)
+
+.type __libm_sin_large#, @function
+.global __libm_sin_large#
+.type __libm_cos_large#, @function
+.global __libm_cos_large#
+
diff --git a/libc/sysdeps/ia64/fpu/s_cosl.S b/libc/sysdeps/ia64/fpu/s_cosl.S
new file mode 100644
index 000000000..8d71e50c1
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_cosl.S
@@ -0,0 +1,2365 @@
+.file "sincosl.s"
+
+
+// Copyright (c) 2000 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 02/02/00 (hand-optimized)
+// 04/04/00 Unwind support added
+// 07/30/01 Improved speed on all paths
+// 08/20/01 Fixed bundling typo
+// 05/13/02 Changed interface to __libm_pi_by_2_reduce
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+// 10/13/03 Corrected final .endp name to match .proc
+// 10/26/04 Avoided using r14-31 as scratch so not clobbered by dynamic loader
+//
+//*********************************************************************
+//
+// Function: Combined sinl(x) and cosl(x), where
+//
+// sinl(x) = sine(x), for double-extended precision x values
+// cosl(x) = cosine(x), for double-extended precision x values
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f32-f99
+//
+// General Purpose Registers:
+// r32-r58
+//
+// Predicate Registers: p6-p13
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// Denormal fault raised on denormal inputs
+// Overflow exceptions do not occur
+// Underflow exceptions raised when appropriate for sin
+// (No specialized error handling for this routine)
+// Inexact raised when appropriate by algorithm
+//
+// sinl(SNaN) = QNaN
+// sinl(QNaN) = QNaN
+// sinl(inf) = QNaN
+// sinl(+/-0) = +/-0
+// cosl(inf) = QNaN
+// cosl(SNaN) = QNaN
+// cosl(QNaN) = QNaN
+// cosl(0) = 1
+//
+//*********************************************************************
+//
+// Mathematical Description
+// ========================
+//
+// The computation of FSIN and FCOS is best handled in one piece of
+// code. The main reason is that given any argument Arg, computation
+// of trigonometric functions first calculate N and an approximation
+// to alpha where
+//
+// Arg = N pi/2 + alpha, |alpha| <= pi/4.
+//
+// Since
+//
+// cosl( Arg ) = sinl( (N+1) pi/2 + alpha ),
+//
+// therefore, the code for computing sine will produce cosine as long
+// as 1 is added to N immediately after the argument reduction
+// process.
+//
+// Let M = N if sine
+// N+1 if cosine.
+//
+// Now, given
+//
+// Arg = M pi/2 + alpha, |alpha| <= pi/4,
+//
+// let I = M mod 4, or I be the two lsb of M when M is represented
+// as 2's complement. I = [i_0 i_1]. Then
+//
+// sinl( Arg ) = (-1)^i_0 sinl( alpha ) if i_1 = 0,
+// = (-1)^i_0 cosl( alpha ) if i_1 = 1.
+//
+// For example:
+// if M = -1, I = 11
+// sin ((-pi/2 + alpha) = (-1) cos (alpha)
+// if M = 0, I = 00
+// sin (alpha) = sin (alpha)
+// if M = 1, I = 01
+// sin (pi/2 + alpha) = cos (alpha)
+// if M = 2, I = 10
+// sin (pi + alpha) = (-1) sin (alpha)
+// if M = 3, I = 11
+// sin ((3/2)pi + alpha) = (-1) cos (alpha)
+//
+// The value of alpha is obtained by argument reduction and
+// represented by two working precision numbers r and c where
+//
+// alpha = r + c accurately.
+//
+// The reduction method is described in a previous write up.
+// The argument reduction scheme identifies 4 cases. For Cases 2
+// and 4, because |alpha| is small, sinl(r+c) and cosl(r+c) can be
+// computed very easily by 2 or 3 terms of the Taylor series
+// expansion as follows:
+//
+// Case 2:
+// -------
+//
+// sinl(r + c) = r + c - r^3/6 accurately
+// cosl(r + c) = 1 - 2^(-67) accurately
+//
+// Case 4:
+// -------
+//
+// sinl(r + c) = r + c - r^3/6 + r^5/120 accurately
+// cosl(r + c) = 1 - r^2/2 + r^4/24 accurately
+//
+// The only cases left are Cases 1 and 3 of the argument reduction
+// procedure. These two cases will be merged since after the
+// argument is reduced in either cases, we have the reduced argument
+// represented as r + c and that the magnitude |r + c| is not small
+// enough to allow the usage of a very short approximation.
+//
+// The required calculation is either
+//
+// sinl(r + c) = sinl(r) + correction, or
+// cosl(r + c) = cosl(r) + correction.
+//
+// Specifically,
+//
+// sinl(r + c) = sinl(r) + c sin'(r) + O(c^2)
+// = sinl(r) + c cos (r) + O(c^2)
+// = sinl(r) + c(1 - r^2/2) accurately.
+// Similarly,
+//
+// cosl(r + c) = cosl(r) - c sinl(r) + O(c^2)
+// = cosl(r) - c(r - r^3/6) accurately.
+//
+// We therefore concentrate on accurately calculating sinl(r) and
+// cosl(r) for a working-precision number r, |r| <= pi/4 to within
+// 0.1% or so.
+//
+// The greatest challenge of this task is that the second terms of
+// the Taylor series
+//
+// r - r^3/3! + r^r/5! - ...
+//
+// and
+//
+// 1 - r^2/2! + r^4/4! - ...
+//
+// are not very small when |r| is close to pi/4 and the rounding
+// errors will be a concern if simple polynomial accumulation is
+// used. When |r| < 2^-3, however, the second terms will be small
+// enough (6 bits or so of right shift) that a normal Horner
+// recurrence suffices. Hence there are two cases that we consider
+// in the accurate computation of sinl(r) and cosl(r), |r| <= pi/4.
+//
+// Case small_r: |r| < 2^(-3)
+// --------------------------
+//
+// Since Arg = M pi/4 + r + c accurately, and M mod 4 is [i_0 i_1],
+// we have
+//
+// sinl(Arg) = (-1)^i_0 * sinl(r + c) if i_1 = 0
+// = (-1)^i_0 * cosl(r + c) if i_1 = 1
+//
+// can be accurately approximated by
+//
+// sinl(Arg) = (-1)^i_0 * [sinl(r) + c] if i_1 = 0
+// = (-1)^i_0 * [cosl(r) - c*r] if i_1 = 1
+//
+// because |r| is small and thus the second terms in the correction
+// are unneccessary.
+//
+// Finally, sinl(r) and cosl(r) are approximated by polynomials of
+// moderate lengths.
+//
+// sinl(r) = r + S_1 r^3 + S_2 r^5 + ... + S_5 r^11
+// cosl(r) = 1 + C_1 r^2 + C_2 r^4 + ... + C_5 r^10
+//
+// We can make use of predicates to selectively calculate
+// sinl(r) or cosl(r) based on i_1.
+//
+// Case normal_r: 2^(-3) <= |r| <= pi/4
+// ------------------------------------
+//
+// This case is more likely than the previous one if one considers
+// r to be uniformly distributed in [-pi/4 pi/4]. Again,
+//
+// sinl(Arg) = (-1)^i_0 * sinl(r + c) if i_1 = 0
+// = (-1)^i_0 * cosl(r + c) if i_1 = 1.
+//
+// Because |r| is now larger, we need one extra term in the
+// correction. sinl(Arg) can be accurately approximated by
+//
+// sinl(Arg) = (-1)^i_0 * [sinl(r) + c(1-r^2/2)] if i_1 = 0
+// = (-1)^i_0 * [cosl(r) - c*r*(1 - r^2/6)] i_1 = 1.
+//
+// Finally, sinl(r) and cosl(r) are approximated by polynomials of
+// moderate lengths.
+//
+// sinl(r) = r + PP_1_hi r^3 + PP_1_lo r^3 +
+// PP_2 r^5 + ... + PP_8 r^17
+//
+// cosl(r) = 1 + QQ_1 r^2 + QQ_2 r^4 + ... + QQ_8 r^16
+//
+// where PP_1_hi is only about 16 bits long and QQ_1 is -1/2.
+// The crux in accurate computation is to calculate
+//
+// r + PP_1_hi r^3 or 1 + QQ_1 r^2
+//
+// accurately as two pieces: U_hi and U_lo. The way to achieve this
+// is to obtain r_hi as a 10 sig. bit number that approximates r to
+// roughly 8 bits or so of accuracy. (One convenient way is
+//
+// r_hi := frcpa( frcpa( r ) ).)
+//
+// This way,
+//
+// r + PP_1_hi r^3 = r + PP_1_hi r_hi^3 +
+// PP_1_hi (r^3 - r_hi^3)
+// = [r + PP_1_hi r_hi^3] +
+// [PP_1_hi (r - r_hi)
+// (r^2 + r_hi r + r_hi^2) ]
+// = U_hi + U_lo
+//
+// Since r_hi is only 10 bit long and PP_1_hi is only 16 bit long,
+// PP_1_hi * r_hi^3 is only at most 46 bit long and thus computed
+// exactly. Furthermore, r and PP_1_hi r_hi^3 are of opposite sign
+// and that there is no more than 8 bit shift off between r and
+// PP_1_hi * r_hi^3. Hence the sum, U_hi, is representable and thus
+// calculated without any error. Finally, the fact that
+//
+// |U_lo| <= 2^(-8) |U_hi|
+//
+// says that U_hi + U_lo is approximating r + PP_1_hi r^3 to roughly
+// 8 extra bits of accuracy.
+//
+// Similarly,
+//
+// 1 + QQ_1 r^2 = [1 + QQ_1 r_hi^2] +
+// [QQ_1 (r - r_hi)(r + r_hi)]
+// = U_hi + U_lo.
+//
+// Summarizing, we calculate r_hi = frcpa( frcpa( r ) ).
+//
+// If i_1 = 0, then
+//
+// U_hi := r + PP_1_hi * r_hi^3
+// U_lo := PP_1_hi * (r - r_hi) * (r^2 + r*r_hi + r_hi^2)
+// poly := PP_1_lo r^3 + PP_2 r^5 + ... + PP_8 r^17
+// correction := c * ( 1 + C_1 r^2 )
+//
+// Else ...i_1 = 1
+//
+// U_hi := 1 + QQ_1 * r_hi * r_hi
+// U_lo := QQ_1 * (r - r_hi) * (r + r_hi)
+// poly := QQ_2 * r^4 + QQ_3 * r^6 + ... + QQ_8 r^16
+// correction := -c * r * (1 + S_1 * r^2)
+//
+// End
+//
+// Finally,
+//
+// V := poly + ( U_lo + correction )
+//
+// / U_hi + V if i_0 = 0
+// result := |
+// \ (-U_hi) - V if i_0 = 1
+//
+// It is important that in the last step, negation of U_hi is
+// performed prior to the subtraction which is to be performed in
+// the user-set rounding mode.
+//
+//
+// Algorithmic Description
+// =======================
+//
+// The argument reduction algorithm is tightly integrated into FSIN
+// and FCOS which share the same code. The following is complete and
+// self-contained. The argument reduction description given
+// previously is repeated below.
+//
+//
+// Step 0. Initialization.
+//
+// If FSIN is invoked, set N_inc := 0; else if FCOS is invoked,
+// set N_inc := 1.
+//
+// Step 1. Check for exceptional and special cases.
+//
+// * If Arg is +-0, +-inf, NaN, NaT, go to Step 10 for special
+// handling.
+// * If |Arg| < 2^24, go to Step 2 for reduction of moderate
+// arguments. This is the most likely case.
+// * If |Arg| < 2^63, go to Step 8 for pre-reduction of large
+// arguments.
+// * If |Arg| >= 2^63, go to Step 10 for special handling.
+//
+// Step 2. Reduction of moderate arguments.
+//
+// If |Arg| < pi/4 ...quick branch
+// N_fix := N_inc (integer)
+// r := Arg
+// c := 0.0
+// Branch to Step 4, Case_1_complete
+// Else ...cf. argument reduction
+// N := Arg * two_by_PI (fp)
+// N_fix := fcvt.fx( N ) (int)
+// N := fcvt.xf( N_fix )
+// N_fix := N_fix + N_inc
+// s := Arg - N * P_1 (first piece of pi/2)
+// w := -N * P_2 (second piece of pi/2)
+//
+// If |s| >= 2^(-33)
+// go to Step 3, Case_1_reduce
+// Else
+// go to Step 7, Case_2_reduce
+// Endif
+// Endif
+//
+// Step 3. Case_1_reduce.
+//
+// r := s + w
+// c := (s - r) + w ...observe order
+//
+// Step 4. Case_1_complete
+//
+// ...At this point, the reduced argument alpha is
+// ...accurately represented as r + c.
+// If |r| < 2^(-3), go to Step 6, small_r.
+//
+// Step 5. Normal_r.
+//
+// Let [i_0 i_1] by the 2 lsb of N_fix.
+// FR_rsq := r * r
+// r_hi := frcpa( frcpa( r ) )
+// r_lo := r - r_hi
+//
+// If i_1 = 0, then
+// poly := r*FR_rsq*(PP_1_lo + FR_rsq*(PP_2 + ... FR_rsq*PP_8))
+// U_hi := r + PP_1_hi*r_hi*r_hi*r_hi ...any order
+// U_lo := PP_1_hi*r_lo*(r*r + r*r_hi + r_hi*r_hi)
+// correction := c + c*C_1*FR_rsq ...any order
+// Else
+// poly := FR_rsq*FR_rsq*(QQ_2 + FR_rsq*(QQ_3 + ... + FR_rsq*QQ_8))
+// U_hi := 1 + QQ_1 * r_hi * r_hi ...any order
+// U_lo := QQ_1 * r_lo * (r + r_hi)
+// correction := -c*(r + S_1*FR_rsq*r) ...any order
+// Endif
+//
+// V := poly + (U_lo + correction) ...observe order
+//
+// result := (i_0 == 0? 1.0 : -1.0)
+//
+// Last instruction in user-set rounding mode
+//
+// result := (i_0 == 0? result*U_hi + V :
+// result*U_hi - V)
+//
+// Return
+//
+// Step 6. Small_r.
+//
+// ...Use flush to zero mode without causing exception
+// Let [i_0 i_1] be the two lsb of N_fix.
+//
+// FR_rsq := r * r
+//
+// If i_1 = 0 then
+// z := FR_rsq*FR_rsq; z := FR_rsq*z *r
+// poly_lo := S_3 + FR_rsq*(S_4 + FR_rsq*S_5)
+// poly_hi := r*FR_rsq*(S_1 + FR_rsq*S_2)
+// correction := c
+// result := r
+// Else
+// z := FR_rsq*FR_rsq; z := FR_rsq*z
+// poly_lo := C_3 + FR_rsq*(C_4 + FR_rsq*C_5)
+// poly_hi := FR_rsq*(C_1 + FR_rsq*C_2)
+// correction := -c*r
+// result := 1
+// Endif
+//
+// poly := poly_hi + (z * poly_lo + correction)
+//
+// If i_0 = 1, result := -result
+//
+// Last operation. Perform in user-set rounding mode
+//
+// result := (i_0 == 0? result + poly :
+// result - poly )
+// Return
+//
+// Step 7. Case_2_reduce.
+//
+// ...Refer to the write up for argument reduction for
+// ...rationale. The reduction algorithm below is taken from
+// ...argument reduction description and integrated this.
+//
+// w := N*P_3
+// U_1 := N*P_2 + w ...FMA
+// U_2 := (N*P_2 - U_1) + w ...2 FMA
+// ...U_1 + U_2 is N*(P_2+P_3) accurately
+//
+// r := s - U_1
+// c := ( (s - r) - U_1 ) - U_2
+//
+// ...The mathematical sum r + c approximates the reduced
+// ...argument accurately. Note that although compared to
+// ...Case 1, this case requires much more work to reduce
+// ...the argument, the subsequent calculation needed for
+// ...any of the trigonometric function is very little because
+// ...|alpha| < 1.01*2^(-33) and thus two terms of the
+// ...Taylor series expansion suffices.
+//
+// If i_1 = 0 then
+// poly := c + S_1 * r * r * r ...any order
+// result := r
+// Else
+// poly := -2^(-67)
+// result := 1.0
+// Endif
+//
+// If i_0 = 1, result := -result
+//
+// Last operation. Perform in user-set rounding mode
+//
+// result := (i_0 == 0? result + poly :
+// result - poly )
+//
+// Return
+//
+//
+// Step 8. Pre-reduction of large arguments.
+//
+// ...Again, the following reduction procedure was described
+// ...in the separate write up for argument reduction, which
+// ...is tightly integrated here.
+
+// N_0 := Arg * Inv_P_0
+// N_0_fix := fcvt.fx( N_0 )
+// N_0 := fcvt.xf( N_0_fix)
+
+// Arg' := Arg - N_0 * P_0
+// w := N_0 * d_1
+// N := Arg' * two_by_PI
+// N_fix := fcvt.fx( N )
+// N := fcvt.xf( N_fix )
+// N_fix := N_fix + N_inc
+//
+// s := Arg' - N * P_1
+// w := w - N * P_2
+//
+// If |s| >= 2^(-14)
+// go to Step 3
+// Else
+// go to Step 9
+// Endif
+//
+// Step 9. Case_4_reduce.
+//
+// ...first obtain N_0*d_1 and -N*P_2 accurately
+// U_hi := N_0 * d_1 V_hi := -N*P_2
+// U_lo := N_0 * d_1 - U_hi V_lo := -N*P_2 - U_hi ...FMAs
+//
+// ...compute the contribution from N_0*d_1 and -N*P_3
+// w := -N*P_3
+// w := w + N_0*d_2
+// t := U_lo + V_lo + w ...any order
+//
+// ...at this point, the mathematical value
+// ...s + U_hi + V_hi + t approximates the true reduced argument
+// ...accurately. Just need to compute this accurately.
+//
+// ...Calculate U_hi + V_hi accurately:
+// A := U_hi + V_hi
+// if |U_hi| >= |V_hi| then
+// a := (U_hi - A) + V_hi
+// else
+// a := (V_hi - A) + U_hi
+// endif
+// ...order in computing "a" must be observed. This branch is
+// ...best implemented by predicates.
+// ...A + a is U_hi + V_hi accurately. Moreover, "a" is
+// ...much smaller than A: |a| <= (1/2)ulp(A).
+//
+// ...Just need to calculate s + A + a + t
+// C_hi := s + A t := t + a
+// C_lo := (s - C_hi) + A
+// C_lo := C_lo + t
+//
+// ...Final steps for reduction
+// r := C_hi + C_lo
+// c := (C_hi - r) + C_lo
+//
+// ...At this point, we have r and c
+// ...And all we need is a couple of terms of the corresponding
+// ...Taylor series.
+//
+// If i_1 = 0
+// poly := c + r*FR_rsq*(S_1 + FR_rsq*S_2)
+// result := r
+// Else
+// poly := FR_rsq*(C_1 + FR_rsq*C_2)
+// result := 1
+// Endif
+//
+// If i_0 = 1, result := -result
+//
+// Last operation. Perform in user-set rounding mode
+//
+// result := (i_0 == 0? result + poly :
+// result - poly )
+// Return
+//
+// Large Arguments: For arguments above 2**63, a Payne-Hanek
+// style argument reduction is used and pi_by_2 reduce is called.
+//
+
+
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(FSINCOSL_CONSTANTS)
+
+sincosl_table_p:
+data8 0xA2F9836E4E44152A, 0x00003FFE // Inv_pi_by_2
+data8 0xC84D32B0CE81B9F1, 0x00004016 // P_0
+data8 0xC90FDAA22168C235, 0x00003FFF // P_1
+data8 0xECE675D1FC8F8CBB, 0x0000BFBD // P_2
+data8 0xB7ED8FBBACC19C60, 0x0000BF7C // P_3
+data8 0x8D848E89DBD171A1, 0x0000BFBF // d_1
+data8 0xD5394C3618A66F8E, 0x0000BF7C // d_2
+LOCAL_OBJECT_END(FSINCOSL_CONSTANTS)
+
+LOCAL_OBJECT_START(sincosl_table_d)
+data8 0xC90FDAA22168C234, 0x00003FFE // pi_by_4
+data8 0xA397E5046EC6B45A, 0x00003FE7 // Inv_P_0
+data4 0x3E000000, 0xBE000000 // 2^-3 and -2^-3
+data4 0x2F000000, 0xAF000000 // 2^-33 and -2^-33
+data4 0x9E000000, 0x00000000 // -2^-67
+data4 0x00000000, 0x00000000 // pad
+LOCAL_OBJECT_END(sincosl_table_d)
+
+LOCAL_OBJECT_START(sincosl_table_pp)
+data8 0xCC8ABEBCA21C0BC9, 0x00003FCE // PP_8
+data8 0xD7468A05720221DA, 0x0000BFD6 // PP_7
+data8 0xB092382F640AD517, 0x00003FDE // PP_6
+data8 0xD7322B47D1EB75A4, 0x0000BFE5 // PP_5
+data8 0xFFFFFFFFFFFFFFFE, 0x0000BFFD // C_1
+data8 0xAAAA000000000000, 0x0000BFFC // PP_1_hi
+data8 0xB8EF1D2ABAF69EEA, 0x00003FEC // PP_4
+data8 0xD00D00D00D03BB69, 0x0000BFF2 // PP_3
+data8 0x8888888888888962, 0x00003FF8 // PP_2
+data8 0xAAAAAAAAAAAB0000, 0x0000BFEC // PP_1_lo
+LOCAL_OBJECT_END(sincosl_table_pp)
+
+LOCAL_OBJECT_START(sincosl_table_qq)
+data8 0xD56232EFC2B0FE52, 0x00003FD2 // QQ_8
+data8 0xC9C99ABA2B48DCA6, 0x0000BFDA // QQ_7
+data8 0x8F76C6509C716658, 0x00003FE2 // QQ_6
+data8 0x93F27DBAFDA8D0FC, 0x0000BFE9 // QQ_5
+data8 0xAAAAAAAAAAAAAAAA, 0x0000BFFC // S_1
+data8 0x8000000000000000, 0x0000BFFE // QQ_1
+data8 0xD00D00D00C6E5041, 0x00003FEF // QQ_4
+data8 0xB60B60B60B607F60, 0x0000BFF5 // QQ_3
+data8 0xAAAAAAAAAAAAAA9B, 0x00003FFA // QQ_2
+LOCAL_OBJECT_END(sincosl_table_qq)
+
+LOCAL_OBJECT_START(sincosl_table_c)
+data8 0xFFFFFFFFFFFFFFFE, 0x0000BFFD // C_1
+data8 0xAAAAAAAAAAAA719F, 0x00003FFA // C_2
+data8 0xB60B60B60356F994, 0x0000BFF5 // C_3
+data8 0xD00CFFD5B2385EA9, 0x00003FEF // C_4
+data8 0x93E4BD18292A14CD, 0x0000BFE9 // C_5
+LOCAL_OBJECT_END(sincosl_table_c)
+
+LOCAL_OBJECT_START(sincosl_table_s)
+data8 0xAAAAAAAAAAAAAAAA, 0x0000BFFC // S_1
+data8 0x88888888888868DB, 0x00003FF8 // S_2
+data8 0xD00D00D0055EFD4B, 0x0000BFF2 // S_3
+data8 0xB8EF1C5D839730B9, 0x00003FEC // S_4
+data8 0xD71EA3A4E5B3F492, 0x0000BFE5 // S_5
+data4 0x38800000, 0xB8800000 // two**-14 and -two**-14
+LOCAL_OBJECT_END(sincosl_table_s)
+
+FR_Input_X = f8
+FR_Result = f8
+
+FR_r = f8
+FR_c = f9
+
+FR_norm_x = f9
+FR_inv_pi_2to63 = f10
+FR_rshf_2to64 = f11
+FR_2tom64 = f12
+FR_rshf = f13
+FR_N_float_signif = f14
+FR_abs_x = f15
+FR_Pi_by_4 = f34
+FR_Two_to_M14 = f35
+FR_Neg_Two_to_M14 = f36
+FR_Two_to_M33 = f37
+FR_Neg_Two_to_M33 = f38
+FR_Neg_Two_to_M67 = f39
+FR_Inv_pi_by_2 = f40
+FR_N_float = f41
+FR_N_fix = f42
+FR_P_1 = f43
+FR_P_2 = f44
+FR_P_3 = f45
+FR_s = f46
+FR_w = f47
+FR_d_2 = f48
+FR_tmp_result = f49
+FR_Z = f50
+FR_A = f51
+FR_a = f52
+FR_t = f53
+FR_U_1 = f54
+FR_U_2 = f55
+FR_C_1 = f56
+FR_C_2 = f57
+FR_C_3 = f58
+FR_C_4 = f59
+FR_C_5 = f60
+FR_S_1 = f61
+FR_S_2 = f62
+FR_S_3 = f63
+FR_S_4 = f64
+FR_S_5 = f65
+FR_poly_hi = f66
+FR_poly_lo = f67
+FR_r_hi = f68
+FR_r_lo = f69
+FR_rsq = f70
+FR_r_cubed = f71
+FR_C_hi = f72
+FR_N_0 = f73
+FR_d_1 = f74
+FR_V = f75
+FR_V_hi = f75
+FR_V_lo = f76
+FR_U_hi = f77
+FR_U_lo = f78
+FR_U_hiabs = f79
+FR_V_hiabs = f80
+FR_PP_8 = f81
+FR_QQ_8 = f101
+FR_PP_7 = f82
+FR_QQ_7 = f102
+FR_PP_6 = f83
+FR_QQ_6 = f103
+FR_PP_5 = f84
+FR_QQ_5 = f104
+FR_PP_4 = f85
+FR_QQ_4 = f105
+FR_PP_3 = f86
+FR_QQ_3 = f106
+FR_PP_2 = f87
+FR_QQ_2 = f107
+FR_QQ_1 = f108
+FR_r_hi_sq = f88
+FR_N_0_fix = f89
+FR_Inv_P_0 = f90
+FR_corr = f91
+FR_poly = f92
+FR_Neg_Two_to_M3 = f93
+FR_Two_to_M3 = f94
+FR_P_0 = f95
+FR_C_lo = f96
+FR_PP_1 = f97
+FR_PP_1_lo = f98
+FR_ArgPrime = f99
+FR_inexact = f100
+
+GR_exp_m2_to_m3= r36
+GR_N_Inc = r37
+GR_Sin_or_Cos = r38
+GR_signexp_x = r40
+GR_exp_x = r40
+GR_exp_mask = r41
+GR_exp_2_to_63 = r42
+GR_exp_2_to_m3 = r43
+GR_exp_2_to_24 = r44
+
+GR_sig_inv_pi = r45
+GR_rshf_2to64 = r46
+GR_exp_2tom64 = r47
+GR_rshf = r48
+GR_ad_p = r49
+GR_ad_d = r50
+GR_ad_pp = r51
+GR_ad_qq = r52
+GR_ad_c = r53
+GR_ad_s = r54
+GR_ad_ce = r55
+GR_ad_se = r56
+GR_ad_m14 = r57
+GR_ad_s1 = r58
+
+// Added for unwind support
+
+GR_SAVE_B0 = r39
+GR_SAVE_GP = r40
+GR_SAVE_PFS = r41
+
+
+.section .text
+
+GLOBAL_IEEE754_ENTRY(sinl)
+{ .mlx
+ alloc r32 = ar.pfs,0,27,2,0
+ movl GR_sig_inv_pi = 0xa2f9836e4e44152a // significand of 1/pi
+}
+{ .mlx
+ mov GR_Sin_or_Cos = 0x0
+ movl GR_rshf_2to64 = 0x47e8000000000000 // 1.1000 2^(63+64)
+}
+;;
+
+{ .mfi
+ addl GR_ad_p = @ltoff(FSINCOSL_CONSTANTS#), gp
+ fclass.m p6, p0 = FR_Input_X, 0x1E3 // Test x natval, nan, inf
+ mov GR_exp_2_to_m3 = 0xffff - 3 // Exponent of 2^-3
+}
+{ .mfb
+ nop.m 999
+ fnorm.s1 FR_norm_x = FR_Input_X // Normalize x
+ br.cond.sptk SINCOSL_CONTINUE
+}
+;;
+
+GLOBAL_IEEE754_END(sinl)
+
+GLOBAL_IEEE754_ENTRY(cosl)
+{ .mlx
+ alloc r32 = ar.pfs,0,27,2,0
+ movl GR_sig_inv_pi = 0xa2f9836e4e44152a // significand of 1/pi
+}
+{ .mlx
+ mov GR_Sin_or_Cos = 0x1
+ movl GR_rshf_2to64 = 0x47e8000000000000 // 1.1000 2^(63+64)
+}
+;;
+
+{ .mfi
+ addl GR_ad_p = @ltoff(FSINCOSL_CONSTANTS#), gp
+ fclass.m p6, p0 = FR_Input_X, 0x1E3 // Test x natval, nan, inf
+ mov GR_exp_2_to_m3 = 0xffff - 3 // Exponent of 2^-3
+}
+{ .mfi
+ nop.m 999
+ fnorm.s1 FR_norm_x = FR_Input_X // Normalize x
+ nop.i 999
+}
+;;
+
+SINCOSL_CONTINUE:
+{ .mfi
+ setf.sig FR_inv_pi_2to63 = GR_sig_inv_pi // Form 1/pi * 2^63
+ nop.f 999
+ mov GR_exp_2tom64 = 0xffff - 64 // Scaling constant to compute N
+}
+{ .mlx
+ setf.d FR_rshf_2to64 = GR_rshf_2to64 // Form const 1.1000 * 2^(63+64)
+ movl GR_rshf = 0x43e8000000000000 // Form const 1.1000 * 2^63
+}
+;;
+
+{ .mfi
+ ld8 GR_ad_p = [GR_ad_p] // Point to Inv_pi_by_2
+ fclass.m p7, p0 = FR_Input_X, 0x0b // Test x denormal
+ nop.i 999
+}
+;;
+
+{ .mfi
+ getf.exp GR_signexp_x = FR_Input_X // Get sign and exponent of x
+ fclass.m p10, p0 = FR_Input_X, 0x007 // Test x zero
+ nop.i 999
+}
+{ .mib
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+ nop.i 999
+(p6) br.cond.spnt SINCOSL_SPECIAL // Branch if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ setf.exp FR_2tom64 = GR_exp_2tom64 // Form 2^-64 for scaling N_float
+ nop.f 0
+ add GR_ad_d = 0x70, GR_ad_p // Point to constant table d
+}
+{ .mib
+ setf.d FR_rshf = GR_rshf // Form right shift const 1.1000 * 2^63
+ mov GR_exp_m2_to_m3 = 0x2fffc // Form -(2^-3)
+(p7) br.cond.spnt SINCOSL_DENORMAL // Branch if x denormal
+}
+;;
+
+SINCOSL_COMMON:
+{ .mfi
+ and GR_exp_x = GR_exp_mask, GR_signexp_x // Get exponent of x
+ fclass.nm p8, p0 = FR_Input_X, 0x1FF // Test x unsupported type
+ mov GR_exp_2_to_63 = 0xffff + 63 // Exponent of 2^63
+}
+{ .mib
+ add GR_ad_pp = 0x40, GR_ad_d // Point to constant table pp
+ mov GR_exp_2_to_24 = 0xffff + 24 // Exponent of 2^24
+(p10) br.cond.spnt SINCOSL_ZERO // Branch if x zero
+}
+;;
+
+{ .mfi
+ ldfe FR_Inv_pi_by_2 = [GR_ad_p], 16 // Load 2/pi
+ fcmp.eq.s0 p15, p0 = FR_Input_X, f0 // Dummy to set denormal
+ add GR_ad_qq = 0xa0, GR_ad_pp // Point to constant table qq
+}
+{ .mfi
+ ldfe FR_Pi_by_4 = [GR_ad_d], 16 // Load pi/4 for range test
+ nop.f 999
+ cmp.ge p10,p0 = GR_exp_x, GR_exp_2_to_63 // Is |x| >= 2^63
+}
+;;
+
+{ .mfi
+ ldfe FR_P_0 = [GR_ad_p], 16 // Load P_0 for pi/4 <= |x| < 2^63
+ fmerge.s FR_abs_x = f1, FR_norm_x // |x|
+ add GR_ad_c = 0x90, GR_ad_qq // Point to constant table c
+}
+{ .mfi
+ ldfe FR_Inv_P_0 = [GR_ad_d], 16 // Load 1/P_0 for pi/4 <= |x| < 2^63
+ nop.f 999
+ cmp.ge p7,p0 = GR_exp_x, GR_exp_2_to_24 // Is |x| >= 2^24
+}
+;;
+
+{ .mfi
+ ldfe FR_P_1 = [GR_ad_p], 16 // Load P_1 for pi/4 <= |x| < 2^63
+ nop.f 999
+ add GR_ad_s = 0x50, GR_ad_c // Point to constant table s
+}
+{ .mfi
+ ldfe FR_PP_8 = [GR_ad_pp], 16 // Load PP_8 for 2^-3 < |r| < pi/4
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe FR_P_2 = [GR_ad_p], 16 // Load P_2 for pi/4 <= |x| < 2^63
+ nop.f 999
+ add GR_ad_ce = 0x40, GR_ad_c // Point to end of constant table c
+}
+{ .mfi
+ ldfe FR_QQ_8 = [GR_ad_qq], 16 // Load QQ_8 for 2^-3 < |r| < pi/4
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe FR_QQ_7 = [GR_ad_qq], 16 // Load QQ_7 for 2^-3 < |r| < pi/4
+ fma.s1 FR_N_float_signif = FR_Input_X, FR_inv_pi_2to63, FR_rshf_2to64
+ add GR_ad_se = 0x40, GR_ad_s // Point to end of constant table s
+}
+{ .mib
+ ldfe FR_PP_7 = [GR_ad_pp], 16 // Load PP_7 for 2^-3 < |r| < pi/4
+ mov GR_ad_s1 = GR_ad_s // Save pointer to S_1
+(p10) br.cond.spnt SINCOSL_ARG_TOO_LARGE // Branch if |x| >= 2^63
+ // Use Payne-Hanek Reduction
+}
+;;
+
+{ .mfi
+ ldfe FR_P_3 = [GR_ad_p], 16 // Load P_3 for pi/4 <= |x| < 2^63
+ fmerge.se FR_r = FR_norm_x, FR_norm_x // r = x, in case |x| < pi/4
+ add GR_ad_m14 = 0x50, GR_ad_s // Point to constant table m14
+}
+{ .mfb
+ ldfps FR_Two_to_M3, FR_Neg_Two_to_M3 = [GR_ad_d], 8
+ fma.s1 FR_rsq = FR_norm_x, FR_norm_x, f0 // rsq = x*x, in case |x| < pi/4
+(p7) br.cond.spnt SINCOSL_LARGER_ARG // Branch if 2^24 <= |x| < 2^63
+ // Use pre-reduction
+}
+;;
+
+{ .mmf
+ ldfe FR_PP_6 = [GR_ad_pp], 16 // Load PP_6 for normal path
+ ldfe FR_QQ_6 = [GR_ad_qq], 16 // Load QQ_6 for normal path
+ fmerge.se FR_c = f0, f0 // c = 0 in case |x| < pi/4
+}
+;;
+
+{ .mmf
+ ldfe FR_PP_5 = [GR_ad_pp], 16 // Load PP_5 for normal path
+ ldfe FR_QQ_5 = [GR_ad_qq], 16 // Load QQ_5 for normal path
+ nop.f 999
+}
+;;
+
+// Here if 0 < |x| < 2^24
+{ .mfi
+ ldfe FR_S_5 = [GR_ad_se], -16 // Load S_5 if i_1=0
+ fcmp.lt.s1 p6, p7 = FR_abs_x, FR_Pi_by_4 // Test |x| < pi/4
+ nop.i 999
+}
+{ .mfi
+ ldfe FR_C_5 = [GR_ad_ce], -16 // Load C_5 if i_1=1
+ fms.s1 FR_N_float = FR_N_float_signif, FR_2tom64, FR_rshf
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ldfe FR_S_4 = [GR_ad_se], -16 // Load S_4 if i_1=0
+ ldfe FR_C_4 = [GR_ad_ce], -16 // Load C_4 if i_1=1
+ nop.i 999
+}
+;;
+
+//
+// N = Arg * 2/pi
+// Check if Arg < pi/4
+//
+//
+// Case 2: Convert integer N_fix back to normalized floating-point value.
+// Case 1: p8 is only affected when p6 is set
+//
+//
+// Grab the integer part of N and call it N_fix
+//
+{ .mfi
+(p7) ldfps FR_Two_to_M33, FR_Neg_Two_to_M33 = [GR_ad_d], 8
+(p6) fma.s1 FR_r_cubed = FR_r, FR_rsq, f0 // r^3 if |x| < pi/4
+(p6) mov GR_N_Inc = GR_Sin_or_Cos // N_Inc if |x| < pi/4
+}
+;;
+
+// If |x| < pi/4, r = x and c = 0
+// lf |x| < pi/4, is x < 2**(-3).
+// r = Arg
+// c = 0
+{ .mmi
+(p7) getf.sig GR_N_Inc = FR_N_float_signif
+(p6) cmp.lt.unc p8,p0 = GR_exp_x, GR_exp_2_to_m3 // Is |x| < 2^-3
+(p6) tbit.z p9,p10 = GR_N_Inc, 0 // p9 if i_1=0, N mod 4 = 0,1
+ // p10 if i_1=1, N mod 4 = 2,3
+}
+;;
+
+//
+// lf |x| < pi/4, is -2**(-3)< x < 2**(-3) - set p8.
+// If |x| >= pi/4,
+// Create the right N for |x| < pi/4 and otherwise
+// Case 2: Place integer part of N in GP register
+//
+
+
+{ .mbb
+ nop.m 999
+(p8) br.cond.spnt SINCOSL_SMALL_R_0 // Branch if 0 < |x| < 2^-3
+(p6) br.cond.spnt SINCOSL_NORMAL_R_0 // Branch if 2^-3 <= |x| < pi/4
+}
+;;
+
+// Here if pi/4 <= |x| < 2^24
+{ .mfi
+ ldfs FR_Neg_Two_to_M67 = [GR_ad_d], 8 // Load -2^-67
+ fnma.s1 FR_s = FR_N_float, FR_P_1, FR_Input_X // s = -N * P_1 + Arg
+ add GR_N_Inc = GR_N_Inc, GR_Sin_or_Cos // Adjust N_Inc for sin/cos
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_w = FR_N_float, FR_P_2, f0 // w = N * P_2
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fms.s1 FR_r = FR_s, f1, FR_w // r = s - w, assume |s| >= 2^-33
+ tbit.z p9,p10 = GR_N_Inc, 0 // p9 if i_1=0, N mod 4 = 0,1
+ // p10 if i_1=1, N mod 4 = 2,3
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fcmp.lt.s1 p7, p6 = FR_s, FR_Two_to_M33
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fcmp.gt.s1 p7, p6 = FR_s, FR_Neg_Two_to_M33 // p6 if |s| >= 2^-33, else p7
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fms.s1 FR_c = FR_s, f1, FR_r // c = s - r, for |s| >= 2^-33
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_rsq = FR_r, FR_r, f0 // rsq = r * r, for |s| >= 2^-33
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fma.s1 FR_w = FR_N_float, FR_P_3, f0
+ nop.i 999
+}
+;;
+
+{ .mmf
+(p9) ldfe FR_C_1 = [GR_ad_pp], 16 // Load C_1 if i_1=0
+(p10) ldfe FR_S_1 = [GR_ad_qq], 16 // Load S_1 if i_1=1
+ frcpa.s1 FR_r_hi, p15 = f1, FR_r // r_hi = frcpa(r)
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fcmp.lt.unc.s1 p8, p13 = FR_r, FR_Two_to_M3 // If big s, test r with 2^-3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fma.s1 FR_U_1 = FR_N_float, FR_P_2, FR_w
+ nop.i 999
+}
+;;
+
+//
+// For big s: r = s - w: No futher reduction is necessary
+// For small s: w = N * P_3 (change sign) More reduction
+//
+{ .mfi
+ nop.m 999
+(p8) fcmp.gt.s1 p8, p13 = FR_r, FR_Neg_Two_to_M3 // If big s, p8 if |r| < 2^-3
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly = FR_rsq, FR_PP_8, FR_PP_7 // poly = rsq*PP_8+PP_7 if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_QQ_8, FR_QQ_7 // poly = rsq*QQ_8+QQ_7 if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fms.s1 FR_r = FR_s, f1, FR_U_1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fma.s1 FR_r_cubed = FR_r, FR_rsq, f0 // rcubed = r * rsq
+ nop.i 999
+}
+;;
+
+{ .mfi
+//
+// For big s: Is |r| < 2**(-3)?
+// For big s: c = S - r
+// For small s: U_1 = N * P_2 + w
+//
+// If p8 is set, prepare to branch to Small_R.
+// If p9 is set, prepare to branch to Normal_R.
+// For big s, r is complete here.
+//
+//
+// For big s: c = c + w (w has not been negated.)
+// For small s: r = S - U_1
+//
+ nop.m 999
+(p6) fms.s1 FR_c = FR_c, f1, FR_w
+ nop.i 999
+}
+{ .mbb
+ nop.m 999
+(p8) br.cond.spnt SINCOSL_SMALL_R_1 // Branch if |s|>=2^-33, |r| < 2^-3,
+ // and pi/4 <= |x| < 2^24
+(p13) br.cond.sptk SINCOSL_NORMAL_R_1 // Branch if |s|>=2^-33, |r| >= 2^-3,
+ // and pi/4 <= |x| < 2^24
+}
+;;
+
+SINCOSL_S_TINY:
+//
+// Here if |s| < 2^-33, and pi/4 <= |x| < 2^24
+//
+{ .mfi
+ fms.s1 FR_U_2 = FR_N_float, FR_P_2, FR_U_1
+//
+// c = S - U_1
+// r = S_1 * r
+//
+//
+}
+;;
+
+{ .mmi
+ nop.m 999
+//
+// Get [i_0,i_1] - two lsb of N_fix_gr.
+// Do dummy fmpy so inexact is always set.
+//
+ tbit.z p9,p10 = GR_N_Inc, 0 // p9 if i_1=0, N mod 4 = 0,1
+ // p10 if i_1=1, N mod 4 = 2,3
+}
+;;
+
+//
+// For small s: U_2 = N * P_2 - U_1
+// S_1 stored constant - grab the one stored with the
+// coefficients.
+//
+{ .mfi
+ ldfe FR_S_1 = [GR_ad_s1], 16
+//
+// Check if i_1 and i_0 != 0
+//
+(p10) fma.s1 FR_poly = f0, f1, FR_Neg_Two_to_M67
+ tbit.z p11,p12 = GR_N_Inc, 1 // p11 if i_0=0, N mod 4 = 0,2
+ // p12 if i_0=1, N mod 4 = 1,3
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fms.s1 FR_s = FR_s, f1, FR_r
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// S = S - r
+// U_2 = U_2 + w
+// load S_1
+//
+ fma.s1 FR_rsq = FR_r, FR_r, f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_U_2 = FR_U_2, f1, FR_w
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmerge.se FR_tmp_result = FR_r, FR_r
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_tmp_result = f0, f1, f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// FR_rsq = r * r
+// Save r as the result.
+//
+ fms.s1 FR_c = FR_s, f1, FR_U_1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// if ( i_1 ==0) poly = c + S_1*r*r*r
+// else Result = 1
+//
+(p12) fnma.s1 FR_tmp_result = FR_tmp_result, f1, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_r = FR_S_1, FR_r, f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+ fma.s0 FR_S_1 = FR_S_1, FR_S_1, f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// If i_1 != 0, poly = 2**(-67)
+//
+ fms.s1 FR_c = FR_c, f1, FR_U_2
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// c = c - U_2
+//
+(p9) fma.s1 FR_poly = FR_r, FR_rsq, FR_c
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// i_0 != 0, so Result = -Result
+//
+(p11) fma.s0 FR_Result = FR_tmp_result, f1, FR_poly
+ nop.i 999 ;;
+}
+{ .mfb
+ nop.m 999
+(p12) fms.s0 FR_Result = FR_tmp_result, f1, FR_poly
+//
+// if (i_0 == 0), Result = Result + poly
+// else Result = Result - poly
+//
+ br.ret.sptk b0 // Exit if |s| < 2^-33, and pi/4 <= |x| < 2^24
+}
+;;
+
+SINCOSL_LARGER_ARG:
+//
+// Here if 2^24 <= |x| < 2^63
+//
+{ .mfi
+ ldfe FR_d_1 = [GR_ad_p], 16 // Load d_1 for |x| >= 2^24 path
+ fma.s1 FR_N_0 = FR_Input_X, FR_Inv_P_0, f0
+ nop.i 999
+}
+;;
+
+//
+// N_0 = Arg * Inv_P_0
+//
+// Load values 2**(-14) and -2**(-14)
+{ .mmi
+ ldfps FR_Two_to_M14, FR_Neg_Two_to_M14 = [GR_ad_m14]
+ nop.i 999 ;;
+}
+{ .mfi
+ ldfe FR_d_2 = [GR_ad_p], 16 // Load d_2 for |x| >= 2^24 path
+ nop.f 999
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+//
+ fcvt.fx.s1 FR_N_0_fix = FR_N_0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N_0_fix = integer part of N_0
+//
+ fcvt.xf FR_N_0 = FR_N_0_fix
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// Make N_0 the integer part
+//
+ fnma.s1 FR_ArgPrime = FR_N_0, FR_P_0, FR_Input_X
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_w = FR_N_0, FR_d_1, f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// Arg' = -N_0 * P_0 + Arg
+// w = N_0 * d_1
+//
+ fma.s1 FR_N_float = FR_ArgPrime, FR_Inv_pi_by_2, f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N = A' * 2/pi
+//
+ fcvt.fx.s1 FR_N_fix = FR_N_float
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N_fix is the integer part
+//
+ fcvt.xf FR_N_float = FR_N_fix
+ nop.i 999 ;;
+}
+{ .mfi
+ getf.sig GR_N_Inc = FR_N_fix
+ nop.f 999
+ nop.i 999 ;;
+}
+{ .mii
+ nop.m 999
+ nop.i 999 ;;
+ add GR_N_Inc = GR_N_Inc, GR_Sin_or_Cos ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N is the integer part of the reduced-reduced argument.
+// Put the integer in a GP register
+//
+ fnma.s1 FR_s = FR_N_float, FR_P_1, FR_ArgPrime
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnma.s1 FR_w = FR_N_float, FR_P_2, FR_w
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// s = -N*P_1 + Arg'
+// w = -N*P_2 + w
+// N_fix_gr = N_fix_gr + N_inc
+//
+ fcmp.lt.unc.s1 p9, p8 = FR_s, FR_Two_to_M14
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p9) fcmp.gt.s1 p9, p8 = FR_s, FR_Neg_Two_to_M14 // p9 if |s| < 2^-14
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// For |s| > 2**(-14) r = S + w (r complete)
+// Else U_hi = N_0 * d_1
+//
+(p9) fma.s1 FR_V_hi = FR_N_float, FR_P_2, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_U_hi = FR_N_0, FR_d_1, f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// Either S <= -2**(-14) or S >= 2**(-14)
+// or -2**(-14) < s < 2**(-14)
+//
+(p8) fma.s1 FR_r = FR_s, f1, FR_w
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_w = FR_N_float, FR_P_3, f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// We need abs of both U_hi and V_hi - don't
+// worry about switched sign of V_hi.
+//
+(p9) fms.s1 FR_A = FR_U_hi, f1, FR_V_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// Big s: finish up c = (S - r) + w (c complete)
+// Case 4: A = U_hi + V_hi
+// Note: Worry about switched sign of V_hi, so subtract instead of add.
+//
+(p9) fnma.s1 FR_V_lo = FR_N_float, FR_P_2, FR_V_hi
+ nop.i 999 ;;
+}
+{ .mmf
+ nop.m 999
+ nop.m 999
+(p9) fms.s1 FR_U_lo = FR_N_0, FR_d_1, FR_U_hi
+}
+{ .mfi
+ nop.m 999
+(p9) fmerge.s FR_V_hiabs = f0, FR_V_hi
+ nop.i 999 ;;
+}
+//{ .mfb
+//(p9) fmerge.s f8= FR_V_lo,FR_V_lo
+//(p9) br.ret.sptk b0
+//}
+//;;
+{ .mfi
+ nop.m 999
+// For big s: c = S - r
+// For small s do more work: U_lo = N_0 * d_1 - U_hi
+//
+(p9) fmerge.s FR_U_hiabs = f0, FR_U_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// For big s: Is |r| < 2**(-3)
+// For big s: if p12 set, prepare to branch to Small_R.
+// For big s: If p13 set, prepare to branch to Normal_R.
+//
+(p8) fms.s1 FR_c = FR_s, f1, FR_r
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// For small S: V_hi = N * P_2
+// w = N * P_3
+// Note the product does not include the (-) as in the writeup
+// so (-) missing for V_hi and w.
+//
+(p8) fcmp.lt.unc.s1 p12, p13 = FR_r, FR_Two_to_M3
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fcmp.gt.s1 p12, p13 = FR_r, FR_Neg_Two_to_M3
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_c = FR_c, f1, FR_w
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p9) fms.s1 FR_w = FR_N_0, FR_d_2, FR_w
+(p12) br.cond.spnt SINCOSL_SMALL_R // Branch if |r| < 2^-3
+ // and 2^24 <= |x| < 2^63
+}
+;;
+
+{ .mib
+ nop.m 999
+ nop.i 999
+(p13) br.cond.sptk SINCOSL_NORMAL_R // Branch if |r| >= 2^-3
+ // and 2^24 <= |x| < 2^63
+}
+;;
+
+SINCOSL_LARGER_S_TINY:
+//
+// Here if |s| < 2^-14, and 2^24 <= |x| < 2^63
+//
+{ .mfi
+ nop.m 999
+//
+// Big s: Vector off when |r| < 2**(-3). Recall that p8 will be true.
+// The remaining stuff is for Case 4.
+// Small s: V_lo = N * P_2 + U_hi (U_hi is in place of V_hi in writeup)
+// Note: the (-) is still missing for V_lo.
+// Small s: w = w + N_0 * d_2
+// Note: the (-) is now incorporated in w.
+//
+ fcmp.ge.unc.s1 p7, p8 = FR_U_hiabs, FR_V_hiabs
+}
+{ .mfi
+ nop.m 999
+//
+// C_hi = S + A
+//
+ fma.s1 FR_t = FR_U_lo, f1, FR_V_lo
+}
+;;
+
+{ .mfi
+ nop.m 999
+//
+// t = U_lo + V_lo
+//
+//
+(p7) fms.s1 FR_a = FR_U_hi, f1, FR_A
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_a = FR_V_hi, f1, FR_A
+ nop.i 999
+}
+;;
+
+{ .mfi
+//
+// Is U_hiabs >= V_hiabs?
+//
+ nop.m 999
+ fma.s1 FR_C_hi = FR_s, f1, FR_A
+ nop.i 999 ;;
+}
+{ .mmi
+ ldfe FR_C_1 = [GR_ad_c], 16 ;;
+ ldfe FR_C_2 = [GR_ad_c], 64
+ nop.i 999 ;;
+}
+//
+// c = c + C_lo finished.
+// Load C_2
+//
+{ .mfi
+ ldfe FR_S_1 = [GR_ad_s], 16
+//
+// C_lo = S - C_hi
+//
+ fma.s1 FR_t = FR_t, f1, FR_w
+ nop.i 999 ;;
+}
+//
+// r and c have been computed.
+// Make sure ftz mode is set - should be automatic when using wre
+// |r| < 2**(-3)
+// Get [i_0,i_1] - two lsb of N_fix.
+// Load S_1
+//
+{ .mfi
+ ldfe FR_S_2 = [GR_ad_s], 64
+//
+// t = t + w
+//
+(p7) fms.s1 FR_a = FR_a, f1, FR_V_hi
+ tbit.z p9,p10 = GR_N_Inc, 0 // p9 if i_1=0, N mod 4 = 0,1
+ // p10 if i_1=1, N mod 4 = 2,3
+}
+;;
+{ .mfi
+ nop.m 999
+//
+// For larger u than v: a = U_hi - A
+// Else a = V_hi - A (do an add to account for missing (-) on V_hi
+//
+ fms.s1 FR_C_lo = FR_s, f1, FR_C_hi
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p8) fms.s1 FR_a = FR_U_hi, f1, FR_a
+ tbit.z p11,p12 = GR_N_Inc, 1 // p11 if i_0=0, N mod 4 = 0,2
+ // p12 if i_0=1, N mod 4 = 1,3
+}
+;;
+
+{ .mfi
+ nop.m 999
+//
+// If u > v: a = (U_hi - A) + V_hi
+// Else a = (V_hi - A) + U_hi
+// In each case account for negative missing from V_hi.
+//
+ fma.s1 FR_C_lo = FR_C_lo, f1, FR_A
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// C_lo = (S - C_hi) + A
+//
+ fma.s1 FR_t = FR_t, f1, FR_a
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// t = t + a
+//
+ fma.s1 FR_C_lo = FR_C_lo, f1, FR_t
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// C_lo = C_lo + t
+//
+ fma.s1 FR_r = FR_C_hi, f1, FR_C_lo
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// Load S_2
+//
+ fma.s1 FR_rsq = FR_r, FR_r, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// r = C_hi + C_lo
+//
+ fms.s1 FR_c = FR_C_hi, f1, FR_r
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// if i_1 ==0: poly = S_2 * FR_rsq + S_1
+// else poly = C_2 * FR_rsq + C_1
+//
+(p9) fma.s1 FR_tmp_result = f0, f1, FR_r
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_tmp_result = f0, f1, f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// Compute r_cube = FR_rsq * r
+//
+(p9) fma.s1 FR_poly = FR_rsq, FR_S_2, FR_S_1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_C_2, FR_C_1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// Compute FR_rsq = r * r
+// Is i_1 == 0 ?
+//
+ fma.s1 FR_r_cubed = FR_rsq, FR_r, f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// c = C_hi - r
+// Load C_1
+//
+ fma.s1 FR_c = FR_c, f1, FR_C_lo
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// if i_1 ==0: poly = r_cube * poly + c
+// else poly = FR_rsq * poly
+//
+(p12) fms.s1 FR_tmp_result = f0, f1, FR_tmp_result
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// if i_1 ==0: Result = r
+// else Result = 1.0
+//
+(p9) fma.s1 FR_poly = FR_r_cubed, FR_poly, FR_c
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, f0
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// if i_0 !=0: Result = -Result
+//
+(p11) fma.s0 FR_Result = FR_tmp_result, f1, FR_poly
+ nop.i 999 ;;
+}
+{ .mfb
+ nop.m 999
+(p12) fms.s0 FR_Result = FR_tmp_result, f1, FR_poly
+//
+// if i_0 == 0: Result = Result + poly
+// else Result = Result - poly
+//
+ br.ret.sptk b0 // Exit for |s| < 2^-14, and 2^24 <= |x| < 2^63
+}
+;;
+
+
+SINCOSL_SMALL_R:
+//
+// Here if |r| < 2^-3
+//
+// Enter with r, c, and N_Inc computed
+//
+// Compare both i_1 and i_0 with 0.
+// if i_1 == 0, set p9.
+// if i_0 == 0, set p11.
+//
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_rsq = FR_r, FR_r, f0 // rsq = r * r
+ tbit.z p9,p10 = GR_N_Inc, 0 // p9 if i_1=0, N mod 4 = 0,1
+ // p10 if i_1=1, N mod 4 = 2,3
+}
+;;
+
+{ .mmi
+(p9) ldfe FR_S_5 = [GR_ad_se], -16 // Load S_5 if i_1=0
+(p10) ldfe FR_C_5 = [GR_ad_ce], -16 // Load C_5 if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mmi
+(p9) ldfe FR_S_4 = [GR_ad_se], -16 // Load S_4 if i_1=0
+(p10) ldfe FR_C_4 = [GR_ad_ce], -16 // Load C_4 if i_1=1
+ nop.i 999
+}
+;;
+
+SINCOSL_SMALL_R_0:
+// Entry point for 2^-3 < |x| < pi/4
+.pred.rel "mutex",p9,p10
+SINCOSL_SMALL_R_1:
+// Entry point for pi/4 < |x| < 2^24 and |r| < 2^-3
+.pred.rel "mutex",p9,p10
+{ .mfi
+(p9) ldfe FR_S_3 = [GR_ad_se], -16 // Load S_3 if i_1=0
+ fma.s1 FR_Z = FR_rsq, FR_rsq, f0 // Z = rsq * rsq
+ nop.i 999
+}
+{ .mfi
+(p10) ldfe FR_C_3 = [GR_ad_ce], -16 // Load C_3 if i_1=1
+(p10) fnma.s1 FR_c = FR_c, FR_r, f0 // c = -c * r if i_1=0
+ nop.i 999
+}
+;;
+
+{ .mmf
+(p9) ldfe FR_S_2 = [GR_ad_se], -16 // Load S_2 if i_1=0
+(p10) ldfe FR_C_2 = [GR_ad_ce], -16 // Load C_2 if i_1=1
+(p10) fmerge.s FR_r = f1, f1
+}
+;;
+
+{ .mmi
+(p9) ldfe FR_S_1 = [GR_ad_se], -16 // Load S_1 if i_1=0
+(p10) ldfe FR_C_1 = [GR_ad_ce], -16 // Load C_1 if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_Z = FR_Z, FR_r, f0 // Z = Z * r if i_1=0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_lo = FR_rsq, FR_S_5, FR_S_4 // poly_lo=rsq*S_5+S_4 if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly_lo = FR_rsq, FR_C_5, FR_C_4 // poly_lo=rsq*C_5+C_4 if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_hi = FR_rsq, FR_S_2, FR_S_1 // poly_hi=rsq*S_2+S_1 if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly_hi = FR_rsq, FR_C_2, FR_C_1 // poly_hi=rsq*C_2+C_1 if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_Z = FR_Z, FR_rsq, f0 // Z = Z * rsq
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_lo = FR_rsq, FR_poly_lo, FR_S_3 // p_lo=p_lo*rsq+S_3, i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly_lo = FR_rsq, FR_poly_lo, FR_C_3 // p_lo=p_lo*rsq+C_3, i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s0 FR_inexact = FR_S_4, FR_S_4, f0 // Dummy op to set inexact
+ tbit.z p11,p12 = GR_N_Inc, 1 // p11 if i_0=0, N mod 4 = 0,2
+ // p12 if i_0=1, N mod 4 = 1,3
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s0 FR_inexact = FR_C_1, FR_C_1, f0 // Dummy op to set inexact
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_hi = FR_poly_hi, FR_rsq, f0 // p_hi=p_hi*rsq if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly_hi = FR_poly_hi, FR_rsq, f0 // p_hi=p_hi*rsq if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_Z, FR_poly_lo, FR_c // poly=Z*poly_lo+c
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_hi = FR_r, FR_poly_hi, f0 // p_hi=r*p_hi if i_1=0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p12) fms.s1 FR_r = f0, f1, FR_r // r = -r if i_0=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_poly, f1, FR_poly_hi // poly=poly+poly_hi
+ nop.i 999
+}
+;;
+
+//
+// if (i_0 == 0) Result = r + poly
+// if (i_0 != 0) Result = r - poly
+//
+{ .mfi
+ nop.m 999
+(p11) fma.s0 FR_Result = FR_r, f1, FR_poly
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p12) fms.s0 FR_Result = FR_r, f1, FR_poly
+ br.ret.sptk b0 // Exit for |r| < 2^-3
+}
+;;
+
+
+SINCOSL_NORMAL_R:
+//
+// Here if 2^-3 <= |r| < pi/4
+// THIS IS THE MAIN PATH
+//
+// Enter with r, c, and N_Inc having been computed
+//
+{ .mfi
+ ldfe FR_PP_6 = [GR_ad_pp], 16 // Load PP_6
+ fma.s1 FR_rsq = FR_r, FR_r, f0 // rsq = r * r
+ tbit.z p9,p10 = GR_N_Inc, 0 // p9 if i_1=0, N mod 4 = 0,1
+ // p10 if i_1=1, N mod 4 = 2,3
+}
+{ .mfi
+ ldfe FR_QQ_6 = [GR_ad_qq], 16 // Load QQ_6
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mmi
+(p9) ldfe FR_PP_5 = [GR_ad_pp], 16 // Load PP_5 if i_1=0
+(p10) ldfe FR_QQ_5 = [GR_ad_qq], 16 // Load QQ_5 if i_1=1
+ nop.i 999
+}
+;;
+
+SINCOSL_NORMAL_R_0:
+// Entry for 2^-3 < |x| < pi/4
+.pred.rel "mutex",p9,p10
+{ .mmf
+(p9) ldfe FR_C_1 = [GR_ad_pp], 16 // Load C_1 if i_1=0
+(p10) ldfe FR_S_1 = [GR_ad_qq], 16 // Load S_1 if i_1=1
+ frcpa.s1 FR_r_hi, p6 = f1, FR_r // r_hi = frcpa(r)
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly = FR_rsq, FR_PP_8, FR_PP_7 // poly = rsq*PP_8+PP_7 if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_QQ_8, FR_QQ_7 // poly = rsq*QQ_8+QQ_7 if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_r_cubed = FR_r, FR_rsq, f0 // rcubed = r * rsq
+ nop.i 999
+}
+;;
+
+
+SINCOSL_NORMAL_R_1:
+// Entry for pi/4 <= |x| < 2^24
+.pred.rel "mutex",p9,p10
+{ .mmf
+(p9) ldfe FR_PP_1 = [GR_ad_pp], 16 // Load PP_1_hi if i_1=0
+(p10) ldfe FR_QQ_1 = [GR_ad_qq], 16 // Load QQ_1 if i_1=1
+ frcpa.s1 FR_r_hi, p6 = f1, FR_r_hi // r_hi = frpca(frcpa(r))
+}
+;;
+
+{ .mfi
+(p9) ldfe FR_PP_4 = [GR_ad_pp], 16 // Load PP_4 if i_1=0
+(p9) fma.s1 FR_poly = FR_rsq, FR_poly, FR_PP_6 // poly = rsq*poly+PP_6 if i_1=0
+ nop.i 999
+}
+{ .mfi
+(p10) ldfe FR_QQ_4 = [GR_ad_qq], 16 // Load QQ_4 if i_1=1
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, FR_QQ_6 // poly = rsq*poly+QQ_6 if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_corr = FR_C_1, FR_rsq, f0 // corr = C_1 * rsq if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_corr = FR_S_1, FR_r_cubed, FR_r // corr = S_1 * r^3 + r if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p9) ldfe FR_PP_3 = [GR_ad_pp], 16 // Load PP_3 if i_1=0
+ fma.s1 FR_r_hi_sq = FR_r_hi, FR_r_hi, f0 // r_hi_sq = r_hi * r_hi
+ nop.i 999
+}
+{ .mfi
+(p10) ldfe FR_QQ_3 = [GR_ad_qq], 16 // Load QQ_3 if i_1=1
+ fms.s1 FR_r_lo = FR_r, f1, FR_r_hi // r_lo = r - r_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p9) ldfe FR_PP_2 = [GR_ad_pp], 16 // Load PP_2 if i_1=0
+(p9) fma.s1 FR_poly = FR_rsq, FR_poly, FR_PP_5 // poly = rsq*poly+PP_5 if i_1=0
+ nop.i 999
+}
+{ .mfi
+(p10) ldfe FR_QQ_2 = [GR_ad_qq], 16 // Load QQ_2 if i_1=1
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, FR_QQ_5 // poly = rsq*poly+QQ_5 if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p9) ldfe FR_PP_1_lo = [GR_ad_pp], 16 // Load PP_1_lo if i_1=0
+(p9) fma.s1 FR_corr = FR_corr, FR_c, FR_c // corr = corr * c + c if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fnma.s1 FR_corr = FR_corr, FR_c, f0 // corr = -corr * c if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_U_lo = FR_r, FR_r_hi, FR_r_hi_sq // U_lo = r*r_hi+r_hi_sq, i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_U_lo = FR_r_hi, f1, FR_r // U_lo = r_hi + r if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_U_hi = FR_r_hi, FR_r_hi_sq, f0 // U_hi = r_hi*r_hi_sq if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_U_hi = FR_QQ_1, FR_r_hi_sq, f1 // U_hi = QQ_1*r_hi_sq+1, i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly = FR_rsq, FR_poly, FR_PP_4 // poly = poly*rsq+PP_4 if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, FR_QQ_4 // poly = poly*rsq+QQ_4 if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_U_lo = FR_r, FR_r, FR_U_lo // U_lo = r * r + U_lo if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_U_lo = FR_r_lo, FR_U_lo, f0 // U_lo = r_lo * U_lo if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_U_hi = FR_PP_1, FR_U_hi, f0 // U_hi = PP_1 * U_hi if i_1=0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly = FR_rsq, FR_poly, FR_PP_3 // poly = poly*rsq+PP_3 if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, FR_QQ_3 // poly = poly*rsq+QQ_3 if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_U_lo = FR_r_lo, FR_U_lo, f0 // U_lo = r_lo * U_lo if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_U_lo = FR_QQ_1,FR_U_lo, f0 // U_lo = QQ_1 * U_lo if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_U_hi = FR_r, f1, FR_U_hi // U_hi = r + U_hi if i_1=0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly = FR_rsq, FR_poly, FR_PP_2 // poly = poly*rsq+PP_2 if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, FR_QQ_2 // poly = poly*rsq+QQ_2 if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_U_lo = FR_PP_1, FR_U_lo, f0 // U_lo = PP_1 * U_lo if i_1=0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly = FR_rsq, FR_poly, FR_PP_1_lo // poly =poly*rsq+PP1lo i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, f0 // poly = poly*rsq if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_V = FR_U_lo, f1, FR_corr // V = U_lo + corr
+ tbit.z p11,p12 = GR_N_Inc, 1 // p11 if i_0=0, N mod 4 = 0,2
+ // p12 if i_0=1, N mod 4 = 1,3
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s0 FR_inexact = FR_PP_5, FR_PP_4, f0 // Dummy op to set inexact
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s0 FR_inexact = FR_QQ_5, FR_QQ_5, f0 // Dummy op to set inexact
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly = FR_r_cubed, FR_poly, f0 // poly = poly*r^3 if i_1=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fma.s1 FR_poly = FR_rsq, FR_poly, f0 // poly = poly*rsq if i_1=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p11) fma.s1 FR_tmp_result = f0, f1, f1// tmp_result=+1.0 if i_0=0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fms.s1 FR_tmp_result = f0, f1, f1// tmp_result=-1.0 if i_0=1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_V = FR_poly, f1, FR_V // V = poly + V
+ nop.i 999
+}
+;;
+
+// If i_0 = 0 Result = U_hi + V
+// If i_0 = 1 Result = -U_hi - V
+{ .mfi
+ nop.m 999
+(p11) fma.s0 FR_Result = FR_tmp_result, FR_U_hi, FR_V
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p12) fms.s0 FR_Result = FR_tmp_result, FR_U_hi, FR_V
+ br.ret.sptk b0 // Exit for 2^-3 <= |r| < pi/4
+}
+;;
+
+SINCOSL_ZERO:
+// Here if x = 0
+{ .mfi
+ cmp.eq.unc p6, p7 = 0x1, GR_Sin_or_Cos
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fmerge.s FR_Result = FR_Input_X, FR_Input_X // If sin, result = input
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p6) fma.s0 FR_Result = f1, f1, f0 // If cos, result=1.0
+ br.ret.sptk b0 // Exit for x=0
+}
+;;
+
+
+SINCOSL_DENORMAL:
+{ .mmb
+ getf.exp GR_signexp_x = FR_norm_x // Get sign and exponent of x
+ nop.m 999
+ br.cond.sptk SINCOSL_COMMON // Return to common code
+}
+;;
+
+SINCOSL_SPECIAL:
+{ .mfb
+ nop.m 999
+//
+// Path for Arg = +/- QNaN, SNaN, Inf
+// Invalid can be raised. SNaNs
+// become QNaNs
+//
+ fmpy.s0 FR_Result = FR_Input_X, f0
+ br.ret.sptk b0 ;;
+}
+
+GLOBAL_IEEE754_END(cosl)
+
+// *******************************************************************
+// *******************************************************************
+// *******************************************************************
+//
+// Special Code to handle very large argument case.
+// Call int __libm_pi_by_2_reduce(x,r,c) for |arguments| >= 2**63
+// The interface is custom:
+// On input:
+// (Arg or x) is in f8
+// On output:
+// r is in f8
+// c is in f9
+// N is in r8
+// Be sure to allocate at least 2 GP registers as output registers for
+// __libm_pi_by_2_reduce. This routine uses r59-60. These are used as
+// scratch registers within the __libm_pi_by_2_reduce routine (for speed).
+//
+// We know also that __libm_pi_by_2_reduce preserves f10-15, f71-127. We
+// use this to eliminate save/restore of key fp registers in this calling
+// function.
+//
+// *******************************************************************
+// *******************************************************************
+// *******************************************************************
+
+LOCAL_LIBM_ENTRY(__libm_callout)
+SINCOSL_ARG_TOO_LARGE:
+.prologue
+{ .mfi
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+};;
+
+{ .mmi
+ setf.exp FR_Two_to_M3 = GR_exp_2_to_m3 // Form 2^-3
+ mov GR_SAVE_GP=gp // Save gp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+//
+// Call argument reduction with x in f8
+// Returns with N in r8, r in f8, c in f9
+// Assumes f71-127 are preserved across the call
+//
+{ .mib
+ setf.exp FR_Neg_Two_to_M3 = GR_exp_m2_to_m3 // Form -(2^-3)
+ nop.i 0
+ br.call.sptk b0=__libm_pi_by_2_reduce#
+};;
+
+{ .mfi
+ add GR_N_Inc = GR_Sin_or_Cos,r8
+ fcmp.lt.unc.s1 p6, p0 = FR_r, FR_Two_to_M3
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mfi
+ mov gp = GR_SAVE_GP // Restore gp
+(p6) fcmp.gt.unc.s1 p6, p0 = FR_r, FR_Neg_Two_to_M3
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+};;
+
+{ .mbb
+ nop.m 999
+(p6) br.cond.spnt SINCOSL_SMALL_R // Branch if |r|< 2^-3 for |x| >= 2^63
+ br.cond.sptk SINCOSL_NORMAL_R // Branch if |r|>=2^-3 for |x| >= 2^63
+};;
+
+LOCAL_LIBM_END(__libm_callout)
+.type __libm_pi_by_2_reduce#,@function
+.global __libm_pi_by_2_reduce#
diff --git a/libc/sysdeps/ia64/fpu/s_erf.S b/libc/sysdeps/ia64/fpu/s_erf.S
new file mode 100644
index 000000000..7174a197f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_erf.S
@@ -0,0 +1,926 @@
+.file "erf.s"
+
+
+// Copyright (c) 2001 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/15/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// double erf(double)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+//
+// There are 9 paths:
+// 1. x = +/-0.0
+// Return erf(x) = +/-0.0
+//
+// 2. 0.0 < |x| < 0.5
+// Return erf(x) = x *Pol9(x^2)
+//
+// 3. For several subranges of 0.5 <= |x| < 5.90625
+// Return erf(x) = sign(x)*Pol19(y),
+// where y = (|x|-b)/a, Pol19(y) = A0 + A1*y^1 + A2*y^2 + ... + A19*y^19
+//
+// For each subrange there is particular set of coefficients.
+// Below is the list of subranges:
+// 3.1 0.5 <= |x| < 1.0 b = a = 0.5
+// 3.2 1.0 <= |x| < 2.0, b = a = 1.0
+// 3.3 2.0 <= |x| < 3.25 b = a = 2.0
+// 3.4 4.0 <= |x| < 5.90625 b = 4.0, a = 2.0
+//
+// 4. 3.25 <= |x| < 4.0
+// Return erf(x) = sign(x)*Pol14(|x| - 3.25)
+//
+// 5. 5.90625 <= |x| < +INF
+// Return erf(x) = sign(x)*(1.0d - 2^(-63))
+//
+// 6. |x| = INF
+// Return erf(x) = sign(x) * 1.0
+//
+// 7. x = [S,Q]NaN
+// Return erf(x) = QNaN
+//
+// 8. x is positive denormal
+// Return erf(x) = A0*x - x^2,
+// where A0 = 2.0/sqrt(Pi)
+//
+// 9. x is negative denormal
+// Return erf(x) = A0*x + x^2,
+// where A0 = 2.0/sqrt(Pi)
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input, output
+// f32 -> f63
+
+// General registers used:
+// r32 -> r48, r2, r3
+
+// Predicate registers used:
+// p0, p6 -> p15
+
+// p6 to filter out case when x = denormal
+// p7 to filter out case when x = [Q,S]NaN or +/-0,
+// used also to process denormals
+// p8 to filter out case when 3.25 <= |x| < 4.0,
+// used also to process denormals
+// p9 to filter out case when |x| = inf
+// p10 to filter out case when |x| < 0.5
+// p11 set when |x| < 3.25 or |x| > 4.0
+// p12 to filter out case when |x| >= 5.90625
+// p13 set if 4.0 <=|x| < 5.90625
+// p14 set to 1 for positive x
+// p15 set to 1 for negative x
+
+// Assembly macros
+//==============================================================
+rDataPtr = r2
+rDataPtr1 = r3
+
+rBias = r33
+rCoeffAddr3 = r34
+rThreeAndQ = r35
+rCoeffAddr2 = r36
+rMask = r37
+rArg = r38
+rSignBit = r39
+rAbsArg = r40
+rSaturation = r41
+rIndex = r42
+rCoeffAddr1 = r43
+rCoeffAddr4 = r44
+rShiftedArg = r45
+rShiftedArgMasked = r46
+rBiasedExpOf4 = r47
+rShiftedAbsArg = r48
+
+//==============================================================
+fA0 = f32
+fA1 = f33
+fA2 = f34
+fA3 = f35
+fA4 = f36
+fA5 = f37
+fA6 = f38
+fA7 = f39
+fA8 = f40
+fA9 = f41
+fA10 = f42
+fA11 = f43
+fA12 = f44
+fA13 = f45
+fA14 = f46
+fA15 = f47
+fA16 = f48
+fA17 = f49
+fA18 = f50
+fA19 = f51
+fArgSqr = f52
+fArgAbsNorm = f53
+fSignumX = f54
+fRes = f55
+fThreeAndQ = f56
+fArgAbs = f57
+fTSqr = f58
+fTQuadr = f59
+fTDeg3 = f60
+fTDeg7 = f61
+fArgAbsNormSgn = f62
+fTQuadrSgn = f63
+
+// Data tables
+//==============================================================
+RODATA
+
+.align 64
+
+LOCAL_OBJECT_START(erf_data)
+// Coefficients ##0..15
+// Polynomial coefficients for the erf(x), 0.5 <= |x| < 1.0
+data8 0xB69AC40646D1F6C1, 0x00003FD2 //A19
+data8 0x90AD48C0118FA10C, 0x00003FD7 //A18
+data8 0x826FBAD055EA4AB8, 0x0000BFDB //A17
+data8 0x8DAB171246CC2B89, 0x00003FDC //A16
+data8 0xC0B1D6662F8A7564, 0x00003FDF //A15
+data8 0xA46374AC35099BAF, 0x0000BFE1 //A14
+data8 0xB2F230996346EF27, 0x0000BFE4 //A13
+data8 0xCDEC50950FACE04A, 0x00003FE6 //A12
+data8 0x826014649396E9D2, 0x00003FE9 //A11
+data8 0xCDB787DC718B13F9, 0x0000BFEB //A10
+data8 0x8E0B23C24EE0C8EE, 0x0000BFED //A9
+data8 0xA49EA40A4E5A3F76, 0x00003FF0 //A8
+data8 0xB11E30BE912617D3, 0x00003FF0 //A7
+data8 0xCCF89D9351CE26E3, 0x0000BFF4 //A6
+data8 0xEFF75AD1F0F22809, 0x00003FF2 //A5
+data8 0xBB793EF404C09A22, 0x00003FF8 //A4
+// Polynomial coefficients for the erf(x), 1.0 <= |x| < 2.0
+data8 0xBAE93FF4174EA59B, 0x00003FE6 //A19
+data8 0x8A0FD46092F95D44, 0x0000BFEA //A18
+data8 0xA37B3242B7809E12, 0x00003FEC //A17
+data8 0xA0330A5CD2E91689, 0x0000BFED //A16
+data8 0x8E34A678F3497D17, 0x0000BFEC //A15
+data8 0xAC185D45A2772384, 0x00003FEF //A14
+data8 0xB0C11347CE7EEDE8, 0x00003FEF //A13
+data8 0xD3330DC14EA0E4EB, 0x0000BFF2 //A12
+data8 0xB4A6DFDE578A428F, 0x00003FF1 //A11
+data8 0xA0B4034310D2D9CB, 0x00003FF5 //A10
+data8 0xF71662D3132B7759, 0x0000BFF5 //A9
+data8 0x9C88BF157695E9EC, 0x0000BFF7 //A8
+data8 0xF84B80EFCA43895D, 0x00003FF8 //A7
+data8 0x9722D22DA628A17B, 0x00003FF7 //A6
+data8 0x8DB0A586F8F3381F, 0x0000BFFB //A5
+data8 0x8DB0A5879F87E5BE, 0x00003FFB //A4
+// Polynomial coefficients for the erf(x), 2.0 <= |x| < 3.25
+data8 0x9C4AF1F3A4B21AFC, 0x00003FF6 //A19
+data8 0x8D40D5D5DB741AB8, 0x0000BFF9 //A18
+data8 0xDEBE7099E0A75BA4, 0x00003FFA //A17
+data8 0xB99A33294D32429D, 0x0000BFFB //A16
+data8 0x8109D9C7197BC7C9, 0x00003FFB //A15
+data8 0xC30DE8E2EFC2D760, 0x00003FFA //A14
+data8 0x80DDA28C5B35DC73, 0x0000BFFC //A13
+data8 0x9BE4DE5095BACE0D, 0x00003FF9 //A12
+data8 0xDA4092509EE7D111, 0x00003FFC //A11
+data8 0x89D98C561B0C9040, 0x0000BFFD //A10
+data8 0xD20B26EB2F0881D4, 0x0000BFF9 //A9
+data8 0xD089C56948731561, 0x00003FFD //A8
+data8 0xDD704DEFFB21B7E7, 0x0000BFFD //A7
+data8 0xF0C9A6BBDE469115, 0x00003FF9 //A6
+data8 0xD673A02CB5766633, 0x00003FFD //A5
+data8 0x8D162CBAD8A12649, 0x0000BFFE //A4
+// Polynomial coefficients for the erf(x), 4.0 <= |x| < 6.0
+data8 0xD4428B75C6FE8FD1, 0x0000BFFC //A19
+data8 0xF76BE1935675D5C8, 0x00003FFE //A18
+data8 0xFD6BB3B14AA7A8E6, 0x0000BFFF //A17
+data8 0x8BE8F573D348DDA4, 0x00004000 //A16
+data8 0x81E91923A1030502, 0x0000BFFF //A15
+data8 0xCE7FE87B26CFD286, 0x0000BFFE //A14
+data8 0x84EF6B4E17404384, 0x00004000 //A13
+data8 0x91FEF33015404991, 0x0000C000 //A12
+data8 0xDEDF6A9370747E56, 0x00003FFF //A11
+data8 0x8397E6FF56CDFD9D, 0x0000BFFF //A10
+data8 0xFAD1CE912473937B, 0x00003FFD //A9
+data8 0xC48C1EA8AAA624EA, 0x0000BFFC //A8
+data8 0xFECAF0097ACF981B, 0x00003FFA //A7
+data8 0x8829A394065E4B95, 0x0000BFF9 //A6
+data8 0xED3003E477A53EE7, 0x00003FF6 //A5
+data8 0xA4C07E9BB3FCB0F3, 0x0000BFF4 //A4
+//
+// Coefficients ##16..19
+// Polynomial coefficients for the erf(x), 0.5 <= |x| < 1.0
+data8 0x95FA98C337005D13, 0x0000BFF9 //A3
+data8 0xE0F7E524D2808A97, 0x0000BFFB //A2
+data8 0xE0F7E524D2808A98, 0x00003FFD //A1
+data8 0x853F7AE0C76E915F, 0x00003FFE //A0
+// Polynomial coefficients for the erf(x), 1.0 <= |x| < 2.0
+data8 0x8DB0A587A96ABCF0, 0x00003FFC //A3
+data8 0xD488F84B7DE18DA8, 0x0000BFFD //A2
+data8 0xD488F84B7DE12E9C, 0x00003FFD //A1
+data8 0xD7BB3D3A08445636, 0x00003FFE //A0
+// Polynomial coefficients for the erf(x), 2.0 <= |x| < 3.25
+data8 0xC58571D23D5C4B3A, 0x00003FFD //A3
+data8 0xA94DCF467CD6AFF3, 0x0000BFFC //A2
+data8 0xA94DCF467CD10A16, 0x00003FFA //A1
+data8 0xFECD70A13CAF1997, 0x00003FFE //A0
+// Polynomial coefficients for the erf(x), 4.0 <= |x| < 6.0
+data8 0xB01D2B4F0D5AB8B0, 0x00003FF1 //A3
+data8 0x8858A465CE594BD1, 0x0000BFEE //A2
+data8 0x8858A447456DE61D, 0x00003FEA //A1
+data8 0xFFFFFFBDC88BB107, 0x00003FFE //A0
+// Polynomial coefficients for the erf(x), 0.0 <= |x| < 0.5
+data8 0xBE839EDBB36C7FCE //A9
+data8 0x3EBB7745A18DD242 //A8
+data8 0xBF4C02DB238F2AFC //A5
+data8 0x3F7565BCD0A9A3EA //A4
+data8 0xC093A3581BCF3333, 0x0000BFFD //A1
+data8 0xBEEF4BB82AD8AE22 //A7
+data8 0x3F1F9A2A57A218CD //A6
+data8 0xBF9B82CE3127F4E4 //A3
+data8 0x3FBCE2F21A042B25 //A2
+data8 0x906EBA8214DB688D, 0x00003FFF //A0
+// 1.0 - 2^(-63)
+data8 0xFFFFFFFFFFFFFFFF, 0x00003FFE
+// Polynomial coefficients for the erf(x), 3.25 <= |x| < 4.0
+data8 0x95E91576C7A12250, 0x00003FE7 //A14
+data8 0x8E5E0D0E1F5D3CB5, 0x0000BFEA //A13
+data8 0xED761DAFAF814DE9, 0x00003FEB //A12
+data8 0xB3A77D921D0ACFC7, 0x0000BFEC //A11
+data8 0xA662D27096B08D7C, 0x0000BFEC //A10
+data8 0xDA0F410AE6233EA5, 0x00003FEF //A9
+data8 0xAB4A8B16B3124327, 0x0000BFF1 //A8
+data8 0xB241E236A5EDCED3, 0x00003FF2 //A7
+data8 0x8A2A65BA1F551F77, 0x0000BFF3 //A6
+data8 0xA4852D0B1D87000A, 0x00003FF3 //A5
+data8 0x963EB00039489476, 0x0000BFF3 //A4
+data8 0xCD5244FF4F7313A5, 0x00003FF2 //A3
+data8 0xC6F1E695363BCB26, 0x0000BFF1 //A2
+data8 0xF4DAF4680DA54C02, 0x00003FEF //A1
+data8 0xFFFFB7CFB3F2ABBE, 0x00003FFE //A0
+// A = 2.0/sqrt(Pi)
+data8 0x906EBA8214DB688D, 0x00003FFF
+LOCAL_OBJECT_END(erf_data)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(erf)
+
+{ .mfi
+ alloc r32 = ar.pfs, 0, 17, 0, 0
+ fmerge.se fArgAbsNorm = f1, f8 // normalized x
+ adds rSignBit = 0x1, r0
+}
+{ .mfi
+ addl rDataPtr = @ltoff(erf_data), gp
+ fma.s1 fArgSqr = f8, f8, f0 // x^2
+ addl rThreeAndQ = 0x400A0, r0 // shifted bits of 3.25
+}
+;;
+{ .mfi
+ getf.d rArg = f8 // x in GR
+ fclass.m p6,p0 = f8, 0x0b // is x denormal ?
+ shl rThreeAndQ = rThreeAndQ, 44 // bits of 3.25
+}
+{ .mfi
+ ld8 rDataPtr = [rDataPtr]
+ nop.f 0
+ addl rBiasedExpOf4 = 0x40100, r0 // shifted bits of 4.0
+}
+;;
+{ .mfi
+ addl rSaturation = 0x4017A, r0 // shifted bits of 5.90625
+ fclass.m p7,p0 = f8, 0xc7 // is x [S,Q]NaN or +/-0 ?
+ shl rSignBit = rSignBit, 63 // mask for sign bit
+}
+{ .mfi
+ addl rMask = 0x7FF00, r0 // Mask for index bits
+ nop.f 0
+ addl rBias = 0x3FE00, r0 // bias of 0.5 << 8
+}
+;;
+{ .mfi
+ setf.d fThreeAndQ = rThreeAndQ // 3.25 if FP register
+ fclass.m p9,p0 = f8, 0x23 // is x +/- inf?
+ shr.u rShiftedArg = rArg, 44
+}
+{ .mfb
+ andcm rAbsArg = rArg, rSignBit // |x| in GR
+ nop.f 0
+(p6) br.cond.spnt erf_denormal // branch out if x is denormal
+}
+;;
+{ .mfi
+ and rShiftedArgMasked = rShiftedArg, rMask // bias of x << 8
+ fmerge.s fArgAbs = f1, f8 // |x|
+ shr rShiftedAbsArg = rAbsArg, 44
+}
+{ .mfb
+ cmp.lt p8, p11 = rThreeAndQ, rAbsArg // p8 = 1 if |x| >= 3.25
+(p7) fma.d.s0 f8 = f8,f1,f8 // NaN or +/-0
+(p7) br.ret.spnt b0 // exit for x = NaN or +/-0
+}
+;;
+{ .mfi
+ sub rIndex = rShiftedArgMasked, rBias // index << 8
+ nop.f 0
+ cmp.lt p10, p0 = rShiftedArgMasked, rBias // p10 = 1 if |x| < 0.5
+}
+{ .mfb
+ // p8 = 1 if 3.25 <= |x| < 4.0
+(p8) cmp.lt p8, p11 = rShiftedAbsArg, rBiasedExpOf4
+ fms.s1 fArgAbsNorm = fArgAbsNorm, f1, f1
+(p10) br.cond.spnt erf_near_zero // branch out if |x| < 0.5
+}
+;;
+.pred.rel "mutex", p8, p11
+{ .mfi
+(p8) adds rCoeffAddr1 = 1392, rDataPtr // coeff. for 3.25 <=|x|<4.0
+(p9) fmerge.s f8 = f8,f1 // +/- inf
+ nop.i 0
+}
+{ .mfb
+(p11) add rCoeffAddr1 = rDataPtr, rIndex// coeff. ##0,2,..14
+ nop.f 0
+(p9) br.ret.spnt b0 // exit for x = +/- inf
+}
+;;
+{ .mfi
+ adds rCoeffAddr2 = 16, rCoeffAddr1
+ fmerge.s fSignumX = f8, f1 // signum(x)
+ nop.i 0
+}
+{ .mfb
+ cmp.lt p12, p0 = rSaturation, rShiftedAbsArg // |x| > 5.90625?
+ nop.f 0
+(p12) br.cond.spnt erf_saturation // branch out if x |x| >= 6.0
+}
+;;
+// Here if paths #3,4
+// if path #4 we'll branch out after loading of 14 necessary coefficients
+{.mfi
+ ldfe fA19 = [rCoeffAddr1], 32
+ nop.f 0
+ nop.i 0
+}
+{.mfi
+ ldfe fA18 = [rCoeffAddr2], 32
+ nop.f 0
+ adds rCoeffAddr3 = 1024, rDataPtr
+}
+;;
+{.mfi
+ ldfe fA17 = [rCoeffAddr1], 32
+ nop.f 0
+ nop.i 0
+}
+{.mfi
+ ldfe fA16 = [rCoeffAddr2], 32
+ nop.f 0
+ nop.i 0
+}
+;;
+{.mfi
+ ldfe fA15 = [rCoeffAddr1], 32
+ fma.s1 fTSqr = fArgAbsNorm, fArgAbsNorm, f0
+ shr.u rIndex = rIndex, 2
+}
+{.mfi
+ ldfe fA14 = [rCoeffAddr2], 32
+ nop.f 0
+ adds rCoeffAddr4 = 16, r0
+}
+;;
+{.mfi
+ ldfe fA13 = [rCoeffAddr1], 32
+ nop.f 0
+ // address of coefficients ##16..23
+ add rCoeffAddr3 = rCoeffAddr3, rIndex
+}
+{.mfi
+ ldfe fA12 = [rCoeffAddr2], 32
+ nop.f 0
+ cmp.lt p15, p14 = rArg, r0
+}
+;;
+{.mfi
+ ldfe fA11 = [rCoeffAddr1], 32
+ nop.f 0
+ add rCoeffAddr4 = rCoeffAddr3, rCoeffAddr4
+}
+{.mfi
+ ldfe fA10 = [rCoeffAddr2], 32
+ nop.f 0
+ nop.i 0
+}
+;;
+{.mfi
+ ldfe fA9 = [rCoeffAddr1], 32
+ nop.f 0
+ nop.i 0
+}
+{.mfi
+ ldfe fA8 = [rCoeffAddr2], 32
+ nop.f 0
+ nop.i 0
+}
+;;
+{.mfi
+ ldfe fA7 = [rCoeffAddr1], 32
+ fms.s1 fArgAbs = fArgAbs, f1, fThreeAndQ
+ nop.i 0
+}
+{.mfb
+ ldfe fA6 = [rCoeffAddr2], 32
+ nop.f 0
+(p8) br.cond.spnt erf_3q_4 // branch out if 3.25 < |x| < 4.0
+}
+;;
+{.mfi
+ ldfe fA5 = [rCoeffAddr1], 32
+ fma.s1 fTDeg3 = fArgAbsNorm, fTSqr, f0
+ nop.i 0
+}
+{.mfi
+ ldfe fA4 = [rCoeffAddr2], 32
+ fma.s1 fTQuadr = fTSqr, fTSqr, f0
+ nop.i 0
+}
+;;
+// Path #3 Polynomial Pol19(y) computation; y = fArgAbsNorm
+{.mfi
+ ldfe fA3 = [rCoeffAddr3], 32
+ fma.s1 fArgAbsNormSgn = fArgAbsNorm, fSignumX, f0
+ nop.i 0
+}
+{.mfi
+ ldfe fA2 = [rCoeffAddr4], 32
+ nop.f 0
+ nop.i 0
+}
+;;
+{.mfi
+ ldfe fA1 = [rCoeffAddr3], 32
+ fma.s1 fRes = fA19, fArgAbsNorm, fA18
+ nop.i 0
+}
+{.mfi
+ ldfe fA0 = [rCoeffAddr4], 32
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, fArgAbsNorm, fA16
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, fArgAbsNorm, fA14
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fTDeg7 = fTDeg3, fTQuadr, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA13 = fA13, fArgAbsNorm, fA12
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, fArgAbsNorm, fA10
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, fArgAbsNorm, fA8
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTSqr, fA17
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fA7, fArgAbsNorm, fA6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA5 = fA5, fArgAbsNorm, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, fTSqr, fA13
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA4, fArgAbsNorm, fA3
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA2 = fA2, fArgAbsNorm, fA1
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, fTSqr, fA9
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fA7, fTSqr, fA5
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTQuadr, fA15
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA4, fTSqr, fA2
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTQuadr, fA11
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA7, fTDeg3, fA4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTDeg7, fA4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // result for negative argument
+(p15) fms.d.s0 f8 = fRes, fArgAbsNormSgn, fA0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ // result for positive argument
+(p14) fma.d.s0 f8 = fRes, fArgAbsNormSgn, fA0
+ br.ret.sptk b0
+}
+
+// Here if 3.25 < |x| < 4.0
+.align 32
+erf_3q_4:
+.pred.rel "mutex", p14, p15
+{ .mfi
+ ldfe fA5 = [rCoeffAddr1], 32
+ fma.s1 fTSqr = fArgAbs, fArgAbs, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fA19, fArgAbs, fA18
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, fArgAbs, fA16
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, fArgAbs, fA14
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA13 = fA13, fArgAbs, fA12
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, fArgAbs, fA10
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, fArgAbs, fA8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fArgAbsNormSgn = fArgAbs, fSignumX, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fTQuadr = fTSqr, fTSqr, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTSqr, fA17
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, fTSqr, fA13
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, fTSqr, fA9
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fA7, fArgAbs, fA6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fTDeg7 = fTQuadr, fTSqr, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTQuadr, fA15
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, fTSqr, fA7
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTDeg7, fA11
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ // result for negative argument
+(p15) fms.d.s0 f8 = fRes, fArgAbsNormSgn, fA5
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ // result for positive argument
+(p14) fma.d.s0 f8 = fRes, fArgAbsNormSgn, fA5
+ br.ret.sptk b0
+}
+;;
+
+// Here if |x| < 0.5
+.align 32
+erf_near_zero:
+{ .mfi
+ adds rCoeffAddr1 = 1280, rDataPtr // address of A9
+ fma.s1 fTSqr = fArgSqr, fArgSqr, f0 // x^4
+ nop.i 0
+}
+{ .mfi
+ adds rCoeffAddr2 = 1328, rDataPtr // address of A7
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA9, fA8 = [rCoeffAddr1], 16
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA7, fA6 = [rCoeffAddr2], 16
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfpd fA5, fA4 = [rCoeffAddr1], 16
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA3, fA2 = [rCoeffAddr2], 16
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fA1 = [rCoeffAddr1]
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe fA0 = [rCoeffAddr2]
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fTQuadr = fTSqr, fTSqr, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fA9, fArgSqr, fA8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fA7, fArgSqr, fA6
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA3 = fA3, fArgSqr, fA2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA5 = fA5, fArgSqr, fA4
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA1 = fA1, fArgSqr, fA0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fTQuadrSgn = fTQuadr, f8, f0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTSqr, fA7
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA1 = fA3, fTSqr, fA1
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTSqr, fA5
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA1 = fA1, f8, f0
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fRes, fTQuadrSgn, fA1 // x*Pol9(x^2)
+ br.ret.sptk b0 // Exit for |x| < 0.5
+};;
+
+// Here if 5.90625 <= |x| < +inf
+.align 32
+erf_saturation:
+{ .mfi
+ adds rDataPtr = 1376, rDataPtr // address of A0
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fA0 = [rDataPtr]
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fA0, fSignumX, f0 // sign(x)*(1.0 - 2^(-63))
+ // Exit for 5.90625 <= |x| < +inf
+ br.ret.sptk b0 // Exit for 5.90625 <=|x|< +inf
+}
+;;
+
+// Here if x is double precision denormal
+.align 32
+erf_denormal:
+{ .mfi
+ adds rDataPtr = 1632, rDataPtr // address of A0
+ fclass.m p7,p8 = f8, 0x0a // is x -denormal ?
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfe fA0 = [rDataPtr] // A0
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fA0 = fA0,f8,f0 // A0*x
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+(p7) fma.d.s0 f8 = f8,f8,fA0 // -denormal
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fnma.d.s0 f8 = f8,f8,fA0 // +denormal
+ br.ret.sptk b0 // Exit for denormal
+}
+;;
+
+GLOBAL_LIBM_END(erf)
+
+
diff --git a/libc/sysdeps/ia64/fpu/s_erfc.S b/libc/sysdeps/ia64/fpu/s_erfc.S
new file mode 100644
index 000000000..addfef44c
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_erfc.S
@@ -0,0 +1,1199 @@
+.file "erfc.s"
+
+
+// Copyright (c) 2001 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 11/12/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// double erfc(double)
+//
+// Overview of operation
+//==============================================================
+// 1. 0 <= x <= 28.0
+//
+// erfc(x) = P14(z) * exp( -x^2 ), z = x - x(i).
+//
+// Comment:
+//
+// Let x(i) = -1.0 + 2^(i/4),i=0,...19. So we have 20 unequal
+// argument intervals [x(i),x(i+1)] with length ratio q = 2^(1/4).
+// Values x(i) we have in the table erfc_xb_table.
+//
+// Let x(i)<= x < x(i+1).
+// We can find i as exponent of number (x + 1)^4.
+//
+// Let P14(z) - polynomial approximation of degree 14 for function
+// erfc(z+x(i)) * exp( (z+x(i))^2) and 0 <= z <= x(i+1)-x(i).
+// Polynomial coeffitients we have in the table erfc_p_table.
+//
+// So we can find result for erfc(x) as above.
+// Algorithm description for exp function see below.
+//
+// 2. -6 <= x < 0
+//
+// erfc(x) = 2.0 - erfc(-x)
+//
+// 3. x > 28.0
+// erfc(x) ~=~ 0.0
+//
+// 4. x < -6.0
+// erfc(x) ~=~ 2.0
+
+// Special values
+//==============================================================
+// erfc(+0) = 1.0
+// erfc(-0) = 1.0
+
+// erfc(+qnan) = +qnan
+// erfc(-qnan) = -qnan
+// erfc(+snan) = +qnan
+// erfc(-snan) = -qnan
+
+// erfc(-inf) = 2.0
+// erfc(+inf) = +0
+
+//==============================================================
+// Take double exp(double) from libm_64.
+//
+// Overview of operation
+//==============================================================
+// Take the input x. w is "how many log2/128 in x?"
+// w = x * 128/log2
+// n = int(w)
+// x = n log2/128 + r + delta
+
+// n = 128M + index_1 + 2^4 index_2
+// x = M log2 + (log2/128) index_1 + (log2/8) index_2 + r + delta
+
+// exp(x) = 2^M 2^(index_1/128) 2^(index_2/8) exp(r) exp(delta)
+// Construct 2^M
+// Get 2^(index_1/128) from table_1;
+// Get 2^(index_2/8) from table_2;
+// Calculate exp(r) by series
+// r = x - n (log2/128)_high
+// delta = - n (log2/128)_low
+// Calculate exp(delta) as 1 + delta
+//==============================================================
+// Comment for exp for erfc:
+//
+// We use quad precision for calculate input argument -x^2 and add
+// result low bits to value delta in exp.
+
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f9 -> f15, f32 -> f93
+
+// General registers used:
+// r32 -> r68
+
+// Predicate registers used:
+// p6 -> p15
+
+// Assembly macros
+//==============================================================
+
+exp_GR_rshf = r33
+EXP_AD_TB1 = r34
+EXP_AD_TB2 = r35
+EXP_AD_P = r36
+exp_GR_N = r37
+exp_GR_index_1 = r38
+exp_GR_index_2_16 = r39
+exp_GR_biased_M = r40
+EXP_AD_T1 = r41
+EXP_AD_T2 = r42
+exp_GR_sig_inv_ln2 = r43
+exp_GR_17ones = r44
+exp_TB1_size = r45
+exp_TB2_size = r46
+exp_GR_rshf_2to56 = r47
+exp_GR_exp_2tom56 = r48
+
+// GR for erfc(x)
+//==============================================================
+GR_POS_ARG_ASYMP = r49
+GR_NEG_ARG_ASYMP = r50
+GR_ARG_ASYMP = r51
+GR_ERFC_XB_TB = r52
+GR_ERFC_P_TB = r53
+GR_IndxPlusBias = r54
+GR_BIAS = r55
+GR_P_A12 = r56
+GR_P_A13 = r57
+GR_AbsArg = r58
+GR_ShftXBi = r59
+GR_ShftPi = r60
+GR_mBIAS = r61
+GR_ShftPi_bias = r62
+GR_ShftXBi_bias = r63
+GR_ShftA12 = r64
+GR_ShftA13 = r65
+GR_EpsNorm = r66
+GR_0x1 = r67
+GR_ShftPi_8 = r68
+
+// GR for __libm_support call
+
+//==============================================================
+
+GR_SAVE_B0 = r61
+GR_SAVE_PFS = r62
+GR_SAVE_GP = r63
+GR_SAVE_SP = r64
+
+GR_Parameter_X = r65
+GR_Parameter_Y = r66
+GR_Parameter_RESULT = r67
+GR_Parameter_TAG = r68
+
+
+// FR for exp(-x^2)
+//==============================================================
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+EXP_2TOM56 = f6
+EXP_INV_LN2_2TO63 = f7
+EXP_W_2TO56_RSH = f9
+EXP_RSHF_2TO56 = f10
+
+exp_P4 = f11
+exp_P3 = f12
+exp_P2 = f13
+exp_P1 = f14
+exp_ln2_by_128_hi = f15
+
+exp_ln2_by_128_lo = f32
+EXP_RSHF = f33
+EXP_Nfloat = f34
+exp_r = f35
+exp_f = f36
+exp_rsq = f37
+exp_rcube = f38
+EXP_2M = f39
+exp_S1 = f40
+exp_T1 = f41
+exp_rP4pP3 = f42
+exp_P_lo = f43
+exp_P_hi = f44
+exp_P = f45
+exp_S = f46
+EXP_NORM_f8 = f47
+exp_S2 = f48
+exp_T2 = f49
+
+// FR for erfc(x)
+//==============================================================
+FR_AbsArg = f50
+FR_Tmp = f51
+FR_Xb = f52
+FR_A0 = f53
+FR_A1 = f54
+FR_A2 = f55
+FR_A3 = f56
+FR_A4 = f57
+FR_A5 = f58
+FR_A6 = f59
+FR_A7 = f60
+FR_A8 = f61
+FR_A9 = f62
+FR_A10 = f63
+FR_A11 = f64
+FR_A12 = f65
+FR_A13 = f66
+FR_A14 = f67
+
+FR_P14_0_1 = f68
+FR_P14_0_2 = f69
+FR_P14_1_1 = f70
+FR_P14_1_2 = f71
+FR_P14_2_1 = f72
+FR_P14_2_2 = f73
+FR_P14_3_1 = f74
+FR_P14_3_2 = f75
+FR_P14_6_1 = f76
+
+FR_P14_7_1 = f77
+FR_P14_7_2 = f78
+FR_P14_8_1 = f79
+FR_P14_8_2 = f80
+FR_P14_12_1 = f81
+FR_P14_13_1 = f82
+FR_P14_13_2 = f83
+FR_Pol = f84
+FR_Exp = f85
+FR_2 = f86
+f8_sq_lo = f87
+FR_LocArg = f88
+FR_Tmpf = f89
+FR_Tmp1 = f90
+FR_EpsNorm = f91
+FR_UnfBound = f92
+FR_NormX = f93
+
+
+// Data tables
+//==============================================================
+RODATA
+.align 16
+
+// ************* DO NOT CHANGE ORDER OF THESE TABLES ********************
+
+LOCAL_OBJECT_START(exp_table_1)
+
+data8 0x403a8b12fc6e4892 , 0 // underflow boundary
+data8 0xb17217f7d1cf79ab , 0x00003ff7 // ln2/128 hi
+data8 0xc9e3b39803f2f6af , 0x00003fb7 // ln2/128 lo
+//
+// Table 1 is 2^(index_1/128) where
+// index_1 goes from 0 to 15
+//
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x80B1ED4FD999AB6C , 0x00003FFF
+data8 0x8164D1F3BC030773 , 0x00003FFF
+data8 0x8218AF4373FC25EC , 0x00003FFF
+data8 0x82CD8698AC2BA1D7 , 0x00003FFF
+data8 0x8383594EEFB6EE37 , 0x00003FFF
+data8 0x843A28C3ACDE4046 , 0x00003FFF
+data8 0x84F1F656379C1A29 , 0x00003FFF
+data8 0x85AAC367CC487B15 , 0x00003FFF
+data8 0x8664915B923FBA04 , 0x00003FFF
+data8 0x871F61969E8D1010 , 0x00003FFF
+data8 0x87DB357FF698D792 , 0x00003FFF
+data8 0x88980E8092DA8527 , 0x00003FFF
+data8 0x8955EE03618E5FDD , 0x00003FFF
+data8 0x8A14D575496EFD9A , 0x00003FFF
+data8 0x8AD4C6452C728924 , 0x00003FFF
+LOCAL_OBJECT_END(exp_table_1)
+
+// Table 2 is 2^(index_1/8) where
+// index_2 goes from 0 to 7
+LOCAL_OBJECT_START(exp_table_2)
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x8B95C1E3EA8BD6E7 , 0x00003FFF
+data8 0x9837F0518DB8A96F , 0x00003FFF
+data8 0xA5FED6A9B15138EA , 0x00003FFF
+data8 0xB504F333F9DE6484 , 0x00003FFF
+data8 0xC5672A115506DADD , 0x00003FFF
+data8 0xD744FCCAD69D6AF4 , 0x00003FFF
+data8 0xEAC0C6E7DD24392F , 0x00003FFF
+LOCAL_OBJECT_END(exp_table_2)
+
+LOCAL_OBJECT_START(exp_p_table)
+data8 0x3f8111116da21757 //P_4
+data8 0x3fa55555d787761c //P_3
+data8 0x3fc5555555555414 //P_2
+data8 0x3fdffffffffffd6a //P_1
+LOCAL_OBJECT_END(exp_p_table)
+
+LOCAL_OBJECT_START(erfc_xb_table)
+data8 0x0000000000000000, 0x00000000 //XB[0] = +0.00000000000000000000e-01L
+data8 0xC1BF828C6DC54B7A, 0x00003FFC //XB[1] = +1.89207115002721066717e-01L
+data8 0xD413CCCFE7799211, 0x00003FFD //XB[2] = +4.14213562373095048802e-01L
+data8 0xAE89F995AD3AD5E8, 0x00003FFE //XB[3] = +6.81792830507429086062e-01L
+data8 0x8000000000000000, 0x00003FFF //XB[4] = +1.00000000000000000000e+00L
+data8 0xB06FE0A31B7152DF, 0x00003FFF //XB[5] = +1.37841423000544213343e+00L
+data8 0xEA09E667F3BCC909, 0x00003FFF //XB[6] = +1.82842712474619009760e+00L
+data8 0x9744FCCAD69D6AF4, 0x00004000 //XB[7] = +2.36358566101485817212e+00L
+data8 0xC000000000000000, 0x00004000 //XB[8] = +3.00000000000000000000e+00L
+data8 0xF06FE0A31B7152DF, 0x00004000 //XB[9] = +3.75682846001088426687e+00L
+data8 0x9504F333F9DE6484, 0x00004001 //XB[10] = +4.65685424949238019521e+00L
+data8 0xB744FCCAD69D6AF4, 0x00004001 //XB[11] = +5.72717132202971634425e+00L
+data8 0xE000000000000000, 0x00004001 //XB[12] = +7.00000000000000000000e+00L
+data8 0x8837F0518DB8A96F, 0x00004002 //XB[13] = +8.51365692002176853374e+00L
+data8 0xA504F333F9DE6484, 0x00004002 //XB[14] = +1.03137084989847603904e+01L
+data8 0xC744FCCAD69D6AF4, 0x00004002 //XB[15] = +1.24543426440594326885e+01L
+data8 0xF000000000000000, 0x00004002 //XB[16] = +1.50000000000000000000e+01L
+data8 0x9037F0518DB8A96F, 0x00004003 //XB[17] = +1.80273138400435370675e+01L
+data8 0xAD04F333F9DE6484, 0x00004003 //XB[18] = +2.16274169979695207808e+01L
+data8 0xCF44FCCAD69D6AF4, 0x00004003 //XB[19] = +2.59086852881188653770e+01L
+LOCAL_OBJECT_END(erfc_xb_table)
+
+LOCAL_OBJECT_START(erfc_p_table)
+
+// Pol0
+data8 0x8000000000000000, 0x00003FFF //A0 = +1.00000000000000000000e+00L
+data8 0x906EBA8214DB688D, 0x0000BFFF //A1 = -1.12837916709551257389e+00L
+data8 0xFFFFFFFFFFFFFFEB, 0x00003FFE //A2 = +9.99999999999999998841e-01L
+data8 0xC093A3581BCF2925, 0x0000BFFE //A3 = -7.52252778063674869885e-01L
+data8 0xFFFFFFFFFFF7CDBD, 0x00003FFD //A4 = +4.99999999999985440383e-01L
+data8 0x9A0FB5E014AE3EFB, 0x0000BFFD //A5 = -3.00901111224757482205e-01L
+data8 0xAAAAAAAA4672B0BD, 0x00003FFC //A6 = +1.66666666643879582201e-01L
+data8 0xB011F45C9F590FC0, 0x0000BFFB //A7 = -8.59717455640916223912e-02L
+data8 0xAAAAA89474161033, 0x00003FFA //A8 = +4.16666588928413935202e-02L
+data8 0x9C818E2CE37D4214, 0x0000BFF9 //A9 = -1.91047455656271634308e-02L
+data8 0x8885969315AB76A1, 0x00003FF8 //A10 = +8.33263115449753085659e-03L
+data8 0xE36112A686F5165B, 0x0000BFF6 //A11 = -3.46953111013788405745e-03L
+data8 0xB3DD6B2DB3307D2E, 0x00003FF5 //A12 = +1.37226041156280127011e-03L
+data8 0x8018A34267FED226, 0x0000BFF4 //A13 = -4.88648380816410282971e-04L
+data8 0xFBBA6A7AEBD3ABD9, 0x00003FF1 //A14 = +1.20033353451879025825e-04L
+// Pol1
+data8 0xD15A1EF03BB91E71, 0x00003FFE //A0 = +8.17781385088640600540e-01L
+data8 0xD1A4ADDAC3337118, 0x0000BFFE //A1 = -8.18919053944410683867e-01L
+data8 0xA9AF9FFA2AD18CB0, 0x00003FFE //A2 = +6.62836073471060947628e-01L
+data8 0xECB77514F0F151B3, 0x0000BFFD //A3 = -4.62337168508812580002e-01L
+data8 0x934AB35EA5CD5EEB, 0x00003FFD //A4 = +2.87679295829458273854e-01L
+data8 0xA71410A68C1EF21C, 0x0000BFFC //A5 = -1.63162479558223113104e-01L
+data8 0xAF506A335238094A, 0x00003FFB //A6 = +8.56025978958108330224e-02L
+data8 0xABFDF67F968765A7, 0x0000BFFA //A7 = -4.19902447551140139048e-02L
+data8 0x9F0B0165A6CDCA99, 0x00003FF9 //A8 = +1.94144274984979538382e-02L
+data8 0x8B8197BFC346CDEA, 0x0000BFF8 //A9 = -8.51478404279186775501e-03L
+data8 0xE950D763FE51AB1E, 0x00003FF6 //A10 = +3.56011637267641495904e-03L
+data8 0xBA821A59FC05FBAD, 0x0000BFF5 //A11 = -1.42294475244146555952e-03L
+data8 0x8D535042E11A0D89, 0x00003FF4 //A12 = +5.39113782651680545599e-04L
+data8 0xBE589447DB26564E, 0x0000BFF2 //A13 = -1.81528103431449706486e-04L
+data8 0xABC8C7EF636F5B0A, 0x00003FF0 //A14 = +4.09565689009869217620e-05L
+// Pol2
+data8 0xA9973ABB272898B2, 0x00003FFE //A0 = +6.62463827792779356910e-01L
+data8 0x945F1A7993F7AADD, 0x0000BFFE //A1 = -5.79576162988785154930e-01L
+data8 0xD84439C6609A8A62, 0x00003FFD //A2 = +4.22395520654665085222e-01L
+data8 0x8A1BBAA7E9CB8C52, 0x0000BFFD //A3 = -2.69742806431984313298e-01L
+data8 0x9F0F67364B466975, 0x00003FFC //A4 = +1.55332195938916594663e-01L
+data8 0xA843F180287DAF7F, 0x0000BFFB //A5 = -8.21608416782158837025e-02L
+data8 0xA59D71B7C690E545, 0x00003FFA //A6 = +4.04333536247671644540e-02L
+data8 0x991A733518C74874, 0x0000BFF9 //A7 = -1.86893701691354422481e-02L
+data8 0x85E7F91148F9F6D2, 0x00003FF8 //A8 = +8.17298243522623724858e-03L
+data8 0xDEE0607CC9D6777E, 0x0000BFF6 //A9 = -3.40082507754089306495e-03L
+data8 0xB145D2CC470B306B, 0x00003FF5 //A10 = +1.35248373238824318949e-03L
+data8 0x86FAEBB4438A20FA, 0x0000BFF4 //A11 = -5.14908443679775343409e-04L
+data8 0xC2503856CE48A657, 0x00003FF2 //A12 = +1.85311660448280465934e-04L
+data8 0xF52642F22A26965B, 0x0000BFF0 //A13 = -5.84481856856861454591e-05L
+data8 0xC98588E1A95FFDBD, 0x00003FEE //A14 = +1.20116245684500489648e-05L
+// Pol3
+data8 0x887CBA2C47B1E2B5, 0x00003FFE //A0 = +5.33153186617432643784e-01L
+data8 0xCD81909CF194328E, 0x0000BFFD //A1 = -4.01379126699602646289e-01L
+data8 0x84DCA15C52122372, 0x00003FFD //A2 = +2.59495775718310530164e-01L
+data8 0x993AA9C76AD28157, 0x0000BFFC //A3 = -1.49637844845261107836e-01L
+data8 0xA140CD8A96FADBA5, 0x00003FFB //A4 = +7.87368829650154013961e-02L
+data8 0x9D36B25E76E56EEA, 0x0000BFFA //A5 = -3.83822410143975630292e-02L
+data8 0x8F8BCC2C0536ECD3, 0x00003FF9 //A6 = +1.75227153523910189727e-02L
+data8 0xF77EDC644BA17AF9, 0x0000BFF7 //A7 = -7.55296479527793552675e-03L
+data8 0xCAB8AC76793C1151, 0x00003FF6 //A8 = +3.09328279988546711083e-03L
+data8 0x9E8FCBC793D555AF, 0x0000BFF5 //A9 = -1.20972979110659888616e-03L
+data8 0xEDC1328664A0CE79, 0x00003FF3 //A10 = +4.53481058502015766058e-04L
+data8 0xAAE3CAAB9D117591, 0x0000BFF2 //A11 = -1.62973223928790256249e-04L
+data8 0xE7704D06A3080C19, 0x00003FF0 //A12 = +5.51792801195012080688e-05L
+data8 0x875A5B53E510F305, 0x0000BFEF //A13 = -1.61353297293572230995e-05L
+data8 0xC8F10CDDB9CC9A42, 0x00003FEC //A14 = +2.99426321046583353559e-06L
+// Pol4
+data8 0xDAEC3C07CAB590C1, 0x00003FFD //A0 = +4.27583576155807004411e-01L
+data8 0x8BE271F8BE0280AC, 0x0000BFFD //A1 = -2.73212014783898564863e-01L
+data8 0x9E13941E19661429, 0x00003FFC //A2 = +1.54371561371908397882e-01L
+data8 0xA241BFC48377449D, 0x0000BFFB //A3 = -7.92269689413235358504e-02L
+data8 0x99E56877AD00D1AE, 0x00003FFA //A4 = +3.75722962151600767952e-02L
+data8 0x887E78DA3BA57C80, 0x0000BFF9 //A5 = -1.66618690872055148862e-02L
+data8 0xE465CAA9F4D54FD8, 0x00003FF7 //A6 = +6.97014232347351913821e-03L
+data8 0xB57930370208D4A7, 0x0000BFF6 //A7 = -2.76906420823065422653e-03L
+data8 0x89A90B5DF0C0C55E, 0x00003FF5 //A8 = +1.05026496655247749532e-03L
+data8 0xC83DB867F08D93C6, 0x0000BFF3 //A9 = -3.81929578900287685559e-04L
+data8 0x8C0C9113FC8061FA, 0x00003FF2 //A10 = +1.33561218944256209215e-04L
+data8 0xBC17A73E9CA51313, 0x0000BFF0 //A11 = -4.48447217225392170834e-05L
+data8 0xED10FE8FC0E44CAD, 0x00003FEE //A12 = +1.41302576244352578317e-05L
+data8 0xFE49912328516F81, 0x0000BFEC //A13 = -3.78917710289305330220e-06L
+data8 0xA8F6077E25DAFD33, 0x00003FEA //A14 = +6.29428967202166402369e-07L
+// Pol5
+data8 0xAF72220985BED710, 0x00003FFD //A0 = +3.42667640364081975844e-01L
+data8 0xBC1CB559042410AB, 0x0000BFFC //A1 = -1.83703263815036934677e-01L
+data8 0xB730BF62E0B63A3C, 0x00003FFB //A2 = +8.94484474229911741150e-02L
+data8 0xA4F307B1D1A1534E, 0x0000BFFA //A3 = -4.02708340235238993824e-02L
+data8 0x8B0327F5117861DB, 0x00003FF9 //A4 = +1.69692783752415790321e-02L
+data8 0xDD4059307B2B081C, 0x0000BFF7 //A5 = -6.75205569219747369303e-03L
+data8 0xA761D738974FECF6, 0x00003FF6 //A6 = +2.55404953403837072821e-03L
+data8 0xF208F6D704F4B487, 0x0000BFF4 //A7 = -9.23290315545127419886e-04L
+data8 0xA7F3658D34EC10B9, 0x00003FF3 //A8 = +3.20340668304962386053e-04L
+data8 0xE079C35CEFD4E6D6, 0x0000BFF1 //A9 = -1.07038324953715640850e-04L
+data8 0x90C5CDD19BB3DD2F, 0x00003FF0 //A10 = +3.45164947021915687751e-05L
+data8 0xB3911863705825F6, 0x0000BFEE //A11 = -1.07030140392753204852e-05L
+data8 0xD023CF5C3F915685, 0x00003FEC //A12 = +3.10152594473606007552e-06L
+data8 0xCA7016FADFF584F5, 0x0000BFEA //A13 = -7.54139761055503416594e-07L
+data8 0xEEBB5CC0901D2BB0, 0x00003FE7 //A14 = +1.11168196441717301549e-07L
+// Pol6
+data8 0x8CD1160326A754AF, 0x00003FFD //A0 = +2.75032699474947383325e-01L
+data8 0xFB22A4C657119388, 0x0000BFFB //A1 = -1.22624671271190511269e-01L
+data8 0xD02B2CA872A774E9, 0x00003FFA //A2 = +5.08224243596176920409e-02L
+data8 0xA23302E146E9E406, 0x0000BFF9 //A3 = -1.97997146844646077750e-02L
+data8 0xEF8918FEDE237C98, 0x00003FF7 //A4 = +7.31004448401605074486e-03L
+data8 0xA8A8B598FA20D881, 0x0000BFF6 //A5 = -2.57353242430059589053e-03L
+data8 0xE3964D9788BFF50F, 0x00003FF4 //A6 = +8.68175969920725727944e-04L
+data8 0x93B83C10B7210AC7, 0x0000BFF3 //A7 = -2.81752903983413936245e-04L
+data8 0xB913B752B0D56A42, 0x00003FF1 //A8 = +8.82515983758695613094e-05L
+data8 0xE0623EFA0B1E8DE9, 0x0000BFEF //A9 = -2.67486302195396417310e-05L
+data8 0x83C4D1A4019E1D2E, 0x00003FEE //A10 = +7.85403393879249335151e-06L
+data8 0x950CBA5D80D8125E, 0x0000BFEC //A11 = -2.22101388436550539151e-06L
+data8 0x9CE72C0409A3E800, 0x00003FEA //A12 = +5.84509280984781223375e-07L
+data8 0x88CCD7A000D1C213, 0x0000BFE8 //A13 = -1.27405082040077425019e-07L
+data8 0x8DF4EC84F093B1C0, 0x00003FE5 //A14 = +1.65259388738830506389e-08L
+// Pol7
+data8 0xE2BF82A153B1B82E, 0x00003FFC //A0 = +2.21433678719152843912e-01L
+data8 0xA72A9AE0BD7F29D5, 0x0000BFFB //A1 = -8.16242313227913578068e-02L
+data8 0xE98939292289EDBE, 0x00003FF9 //A2 = +2.85078159732432477516e-02L
+data8 0x9B93E5E0EEFF9516, 0x0000BFF8 //A3 = -9.49571084105114051468e-03L
+data8 0xC6B39897AABC47BC, 0x00003FF6 //A4 = +3.03194499398790451607e-03L
+data8 0xF442AC7D84DDF1E0, 0x0000BFF4 //A5 = -9.31779649708690069328e-04L
+data8 0x90FBD9F8B41DF23E, 0x00003FF3 //A6 = +2.76534642660360753287e-04L
+data8 0xA6AC59077C78B437, 0x0000BFF1 //A7 = -7.94759910003852154521e-05L
+data8 0xB9FC0BADD531E5E9, 0x00003FEF //A8 = +2.21710864553358009804e-05L
+data8 0xC9CFC8CD93648856, 0x0000BFED //A9 = -6.01445608619100503330e-06L
+data8 0xD4FA51B86A9B2494, 0x00003FEB //A10 = +1.58680833469323702924e-06L
+data8 0xD8D0ED030032926D, 0x0000BFE9 //A11 = -4.03851487695924456733e-07L
+data8 0xCCA1CA2AC3EB8973, 0x00003FE7 //A12 = +9.52891963880517988726e-08L
+data8 0x9E26A080F9DA39DE, 0x0000BFE5 //A13 = -1.84111863600343741644e-08L
+data8 0x8F3DC58F64A92C62, 0x00003FE2 //A14 = +2.08443519336792003049e-09L
+// Pol8
+data8 0xB74C13E914E9666F, 0x00003FFC //A0 = +1.79001151181389950418e-01L
+data8 0xDEB57268A58B763B, 0x0000BFFA //A1 = -5.43722600071728705200e-02L
+data8 0x821FF0D4C605A4CD, 0x00003FF9 //A2 = +1.58843711598712515609e-02L
+data8 0x92C830DD423DB924, 0x0000BFF7 //A3 = -4.47943101836927657394e-03L
+data8 0xA04E61767A095BB6, 0x00003FF5 //A4 = +1.22303905230942532198e-03L
+data8 0xA9EF64E0F6654358, 0x0000BFF3 //A5 = -3.24125543666296226957e-04L
+data8 0xAF39C8969BD163E8, 0x00003FF1 //A6 = +8.35541329311315562274e-05L
+data8 0xB01273B34197330C, 0x0000BFEF //A7 = -2.09894273215824495783e-05L
+data8 0xACAE4C820B99EBAC, 0x00003FED //A8 = +5.14629050848703676006e-06L
+data8 0xA57BF2AEA52B92DF, 0x0000BFEB //A9 = -1.23295315941138567172e-06L
+data8 0x9AD6FE7A852DA239, 0x00003FE9 //A10 = +2.88411640627675721042e-07L
+data8 0x8BFE95FCD7B92763, 0x0000BFE7 //A11 = -6.51900079707465044843e-08L
+data8 0xE9F15C8E7F58CF90, 0x00003FE4 //A12 = +1.36172642554216769522e-08L
+data8 0x9E90F22B11FAF8B5, 0x0000BFE2 //A13 = -2.30744183054978535129e-09L
+data8 0xF8CF74F1A138FBBA, 0x00003FDE //A14 = +2.26291720693360003233e-10L
+// Pol9
+data8 0x94D45274A831ED57, 0x00003FFC //A0 = +1.45341194505862183128e-01L
+data8 0x94D4518B699A4A68, 0x0000BFFA //A1 = -3.63352952323113355459e-02L
+data8 0x90C3B59FF403A916, 0x00003FF8 //A2 = +8.83572327421709216515e-03L
+data8 0x893B796D0E9B4867, 0x0000BFF6 //A3 = -2.09399904729894563201e-03L
+data8 0xFDFFA94903DCB8EA, 0x00003FF3 //A4 = +4.84464029001979577664e-04L
+data8 0xE5CE7C2E4B05CF16, 0x0000BFF1 //A5 = -1.09580317663729186599e-04L
+data8 0xCB88CC8F1146FDAE, 0x00003FEF //A6 = +2.42631878042764234194e-05L
+data8 0xB0AA52C6F44E47C8, 0x0000BFED //A7 = -5.26503698764159271674e-06L
+data8 0x966DD813170F8EBD, 0x00003FEB //A8 = +1.12078397189300511086e-06L
+data8 0xFB75782788A6E378, 0x0000BFE8 //A9 = -2.34189317246047219283e-07L
+data8 0xCDF787C4E5FDCF2A, 0x00003FE6 //A10 = +4.79554094892420966704e-08L
+data8 0xA34CD3DFAC12AA45, 0x0000BFE4 //A11 = -9.50531730989412282035e-09L
+data8 0xEEBB49645DE0E34C, 0x00003FE1 //A12 = +1.73700091999434388879e-09L
+data8 0x8C86D8677DEACFBA, 0x0000BFDF //A13 = -2.55616650187281815453e-10L
+data8 0xBDB223D0FE2A7D6B, 0x00003FDB //A14 = +2.15659223402509415592e-11L
+// Pol10
+data8 0xF2C1812715E4050A, 0x00003FFB //A0 = +1.18533143048567888157e-01L
+data8 0xC7DA2C565ADAEE57, 0x0000BFF9 //A1 = -2.43960252726894623056e-02L
+data8 0xA15CEFFD632F697D, 0x00003FF7 //A2 = +4.92440908672041077933e-03L
+data8 0xFFCFF4D3FB118F69, 0x0000BFF4 //A3 = -9.75846593969603576904e-04L
+data8 0xC73F437D2F226C56, 0x00003FF2 //A4 = +1.90016864347860462550e-04L
+data8 0x989D7E1F60845811, 0x0000BFF0 //A5 = -3.63863004988760879054e-05L
+data8 0xE615A5A669361BE1, 0x00003FED //A6 = +6.85705419984646959791e-06L
+data8 0xAACD08E0BE6270F8, 0x0000BFEB //A7 = -1.27256599602163049440e-06L
+data8 0xF9DEE9C1C02A3062, 0x00003FE8 //A8 = +2.32710274258898439253e-07L
+data8 0xB420E960508A3003, 0x0000BFE6 //A9 = -4.19394488070741280136e-08L
+data8 0xFF5E3ECA229CB0C7, 0x00003FE3 //A10 = +7.43219121339261970485e-09L
+data8 0xAF86504D78D35E89, 0x0000BFE1 //A11 = -1.27711000692808421573e-09L
+data8 0xDE1CE78ADB6DDF04, 0x00003FDE //A12 = +2.02010513073041015283e-10L
+data8 0xE124FFAA267301A5, 0x0000BFDB //A13 = -2.55959692063871343080e-11L
+data8 0x81F1BEBEFBE168D2, 0x00003FD8 //A14 = +1.84661980716000872722e-12L
+// Pol11
+data8 0xC6CE5D7D18203EAA, 0x00003FFB //A0 = +9.70732978630764996752e-02L
+data8 0x86E8A30A76923C88, 0x0000BFF9 //A1 = -1.64683517829920230086e-02L
+data8 0xB4A1CBB7576B4183, 0x00003FF6 //A2 = +2.75622581042760461528e-03L
+data8 0xEEB782FBC8BB352B, 0x0000BFF3 //A3 = -4.55316242981110299585e-04L
+data8 0x9BC489CC00C7E63A, 0x00003FF1 //A4 = +7.42758405750422020216e-05L
+data8 0xC8D418A9F2A78515, 0x0000BFEE //A5 = -1.19703114831817055481e-05L
+data8 0xFFE671DCEE8665A8, 0x00003FEB //A6 = +1.90660487794668853072e-06L
+data8 0xA1313247D3E35365, 0x0000BFE9 //A7 = -3.00243820009225833104e-07L
+data8 0xC8D5A87C970712B1, 0x00003FE6 //A8 = +4.67604496871825103188e-08L
+data8 0xF77258CEF4675E25, 0x0000BFE3 //A9 = -7.20164586117313631144e-09L
+data8 0x96549D79C0F33C27, 0x00003FE1 //A10 = +1.09379854902340983112e-09L
+data8 0xB16A6CC5A3AE6E01, 0x0000BFDE //A11 = -1.61358659378896671620e-10L
+data8 0xC0970F2551C52F96, 0x00003FDB //A12 = +2.18949565869759698947e-11L
+data8 0xA6E029ABB3BB500C, 0x0000BFD8 //A13 = -2.37144541649446501026e-12L
+data8 0xA3E43F3857D1B6A5, 0x00003FD4 //A14 = +1.45564973108152568130e-13L
+// Pol12
+data8 0xA36E35FC807B3E64, 0x00003FFB //A0 = +7.98000543291529334886e-02L
+data8 0xB725A29237C8F94F, 0x0000BFF8 //A1 = -1.11784064873715046550e-02L
+data8 0xCB51EF23EAD5F327, 0x00003FF5 //A2 = +1.55120891755237931425e-03L
+data8 0xDFA838770AE711A2, 0x0000BFF2 //A3 = -2.13296043002775850891e-04L
+data8 0xF3D7B777730B202D, 0x00003FEF //A4 = +2.90683082614108095819e-05L
+data8 0x83C5FF0D475796DD, 0x0000BFED //A5 = -3.92715403535014263671e-06L
+data8 0x8D37B41345244FD5, 0x00003FEA //A6 = +5.26076523514903487927e-07L
+data8 0x9616B7E9C40C1DCC, 0x0000BFE7 //A7 = -6.98905176445499510102e-08L
+data8 0x9E38FDF61B26699A, 0x00003FE4 //A8 = +9.20976891314475742405e-09L
+data8 0xA565DFE27AEA03A1, 0x0000BFE1 //A9 = -1.20342845518628622757e-09L
+data8 0xAAEB9EFB497EC812, 0x00003FDE //A10 = +1.55451193328690040046e-10L
+data8 0xABD305A38349EAEB, 0x0000BFDB //A11 = -1.95341618552982314342e-11L
+data8 0x9EDB00104DB66DD9, 0x00003FD8 //A12 = +2.25747200093121867690e-12L
+data8 0xE9F80AF513F2B8AB, 0x0000BFD4 //A13 = -2.07806143133802417637e-13L
+data8 0xC2B840C3859AB166, 0x00003FD0 //A14 = +1.08091168358477817812e-14L
+// Pol13
+data8 0x86CD0BF01914407A, 0x00003FFB //A0 = +6.58207829138836028568e-02L
+data8 0xF9F4A17FA70807C3, 0x0000BFF7 //A1 = -7.62803922344113067603e-03L
+data8 0xE63BF84EDE20EDAA, 0x00003FF4 //A2 = +8.78273993036530088653e-04L
+data8 0xD2B746011B39D879, 0x0000BFF1 //A3 = -1.00477176633442906101e-04L
+data8 0xBFA4F1F66023C975, 0x00003FEE //A4 = +1.14228914411837438985e-05L
+data8 0xAD3A05E1F1F0EA8F, 0x0000BFEB //A5 = -1.29063913420827451449e-06L
+data8 0x9BA1F2E56DBE1B49, 0x00003FE8 //A6 = +1.44944165416032280452e-07L
+data8 0x8AFE93AF627BAFA6, 0x0000BFE5 //A7 = -1.61810825806733824014e-08L
+data8 0xF6CEAB6E78304875, 0x00003FE1 //A8 = +1.79575947795401009493e-09L
+data8 0xD9BFD64FD9166ECF, 0x0000BFDE //A9 = -1.98041892772535870322e-10L
+data8 0xBE482C8AEA403737, 0x00003FDB //A10 = +2.16325508593741350803e-11L
+data8 0xA1FB98FA19E62A4F, 0x0000BFD8 //A11 = -2.30191407969654156362e-12L
+data8 0xFDB2E0599016AD1E, 0x00003FD4 //A12 = +2.25329742249079975388e-13L
+data8 0x9E179A99CDD4BF4B, 0x0000BFD1 //A13 = -1.75517603530017718494e-14L
+data8 0xDE4DE992A707C7BC, 0x00003FCC //A14 = +7.71273133169032472595e-16L
+// Pol14
+data8 0xDF0639E60CF6E96C, 0x00003FFA //A0 = +5.44492971101228988138e-02L
+data8 0xAB6737B6065BD1C2, 0x0000BFF7 //A1 = -5.23081035867078490333e-03L
+data8 0x8322CC0765FD9C27, 0x00003FF4 //A2 = +5.00243857322493802503e-04L
+data8 0xC7C37C447AABC9BE, 0x0000BFF0 //A3 = -4.76273572257807668623e-05L
+data8 0x977C068C67DD09B3, 0x00003FED //A4 = +4.51458915834329225528e-06L
+data8 0xE4C00648054CBD72, 0x0000BFE9 //A5 = -4.26080256412742187632e-07L
+data8 0xABF9032C426C0F54, 0x00003FE6 //A6 = +4.00405155179176153559e-08L
+data8 0x80BD82177111B70D, 0x0000BFE3 //A7 = -3.74683488305340664541e-09L
+data8 0xBFEFB2BBFC4AAE16, 0x00003FDF //A8 = +3.49130134089615132836e-10L
+data8 0x8E68BCEC2A2F6025, 0x0000BFDC //A9 = -3.23800879252444001040e-11L
+data8 0xD19FEF92B2157585, 0x00003FD8 //A10 = +2.97894685764287382560e-12L
+data8 0x967A0ECC142382D9, 0x0000BFD5 //A11 = -2.67300472044743953909e-13L
+data8 0xC6D8869855133985, 0x00003FD1 //A12 = +2.20763189681614758000e-14L
+data8 0xD10AC0B228ABCECC, 0x0000BFCD //A13 = -1.45052027893524847250e-15L
+data8 0xF7C6DEB4522487A3, 0x00003FC8 //A14 = +5.37280367113168366711e-17L
+// Pol15
+data8 0xB8F57DECFAC3B255, 0x00003FFA //A0 = +4.51559943173131409760e-02L
+data8 0xEC1B8A6C822C036F, 0x0000BFF6 //A1 = -3.60271577347565115947e-03L
+data8 0x963A6DD66951B72E, 0x00003FF3 //A2 = +2.86537625289770759336e-04L
+data8 0xBE93F9E80DF4AE0A, 0x0000BFEF //A3 = -2.27186718010906557773e-05L
+data8 0xF10589FC10D908E0, 0x00003FEB //A4 = +1.79575113004740124999e-06L
+data8 0x97F1A2435C7877EF, 0x0000BFE8 //A5 = -1.41508767557208714648e-07L
+data8 0xBEFF2FB5F00E9327, 0x00003FE4 //A6 = +1.11174782364058338591e-08L
+data8 0xEF5E09DC714DF198, 0x0000BFE0 //A7 = -8.70813302639377671664e-10L
+data8 0x958A6EB9408970A4, 0x00003FDD //A8 = +6.80032608255179732632e-11L
+data8 0xBA31F40954675710, 0x0000BFD9 //A9 = -5.29198388081297293593e-12L
+data8 0xE63B9CEEDC4CF0E6, 0x00003FD5 //A10 = +4.08975721481205179918e-13L
+data8 0x8AF8F1E3FED32CEC, 0x0000BFD2 //A11 = -3.08580807479307213059e-14L
+data8 0x9A88033A08842BEA, 0x00003FCE //A12 = +2.14455258045503137285e-15L
+data8 0x88BCF775B7B3A939, 0x0000BFCA //A13 = -1.18601440246395438386e-16L
+data8 0x88687B63A5B7135E, 0x00003FC5 //A14 = +3.69734984736162880476e-18L
+// Pol16
+data8 0x99B8A501204BF3E7, 0x00003FFA //A0 = +3.75296063885057657456e-02L
+data8 0xA33FA20D2867C79C, 0x0000BFF6 //A1 = -2.49097544033960143953e-03L
+data8 0xACFD14CA6AA55829, 0x00003FF2 //A2 = +1.64974783411741182991e-04L
+data8 0xB6E9B4ED9B378B09, 0x0000BFEE //A3 = -1.09024594422859744844e-05L
+data8 0xC0FD95D38ADCF301, 0x00003FEA //A4 = +7.18945888498730738040e-07L
+data8 0xCB302F7AAFFFA074, 0x0000BFE6 //A5 = -4.73084450875945514829e-08L
+data8 0xD578674188198402, 0x00003FE2 //A6 = +3.10640208133938026422e-09L
+data8 0xDFCC6ED4219E7FC4, 0x0000BFDE //A7 = -2.03543610142159316364e-10L
+data8 0xEA1F448AA373E4A9, 0x00003FDA //A8 = +1.33083028465054001215e-11L
+data8 0xF44780B8EACD37B5, 0x0000BFD6 //A9 = -8.67854438613319891312e-13L
+data8 0xFD55794492F53AEE, 0x00003FD2 //A10 = +5.62514216652784597182e-14L
+data8 0x805C040421E7A098, 0x0000BFCF //A11 = -3.56269003968981157635e-15L
+data8 0xEFCCD20DE93A138E, 0x00003FCA //A12 = +2.07993414310230172191e-16L
+data8 0xB259764466732080, 0x0000BFC6 //A13 = -9.66834364652262630640e-18L
+data8 0x9597C1DB6AF830E4, 0x00003FC1 //A14 = +2.53420063550355940811e-19L
+// Pol17
+data8 0xFFFCBD66BAA4368C, 0x00003FF9 //A0 = +3.12484454387527380657e-02L
+data8 0xE28174723762D197, 0x0000BFF5 //A1 = -1.72810121976742793952e-03L
+data8 0xC81D832836019EC4, 0x00003FF1 //A2 = +9.54224026432644399736e-05L
+data8 0xB0885530C7D7AB5B, 0x0000BFED //A3 = -5.26107996417947739207e-06L
+data8 0x9B7EA64F62F6FD06, 0x00003FE9 //A4 = +2.89631495607631932854e-07L
+data8 0x88C24ACAA9042166, 0x0000BFE5 //A5 = -1.59208376111789845204e-08L
+data8 0xF033E5CD9B7F2822, 0x00003FE0 //A6 = +8.73852423930118273815e-10L
+data8 0xD2A1B161FB4DFBFE, 0x0000BFDC //A7 = -4.78920839886600387264e-11L
+data8 0xB86B27FCBB5A1E9D, 0x00003FD8 //A8 = +2.62074563162805723295e-12L
+data8 0xA124E1303F08E508, 0x0000BFD4 //A9 = -1.43124677534734729453e-13L
+data8 0x8C0B270950D7C697, 0x00003FD0 //A10 = +7.77397948226387851915e-15L
+data8 0xEE034E350C65D2D9, 0x0000BFCB //A11 = -4.12886586201102092942e-16L
+data8 0xBA94473E52495304, 0x00003FC7 //A12 = +2.02289587087169937807e-17L
+data8 0xE913D34CBB853CEE, 0x0000BFC2 //A13 = -7.89697093687557412061e-19L
+data8 0xA44576A85E8CAB59, 0x00003FBD //A14 = +1.73929048516879172258e-20L
+// Pol18
+data8 0xD579A3FE4622DED2, 0x00003FF9 //A0 = +2.60589793198885278242e-02L
+data8 0x9D97EB84E7CD89C8, 0x0000BFF5 //A1 = -1.20234251012583627659e-03L
+data8 0xE86EFDC2CCA5C47B, 0x00003FF0 //A2 = +5.54164790116744315389e-05L
+data8 0xAB39FA5621E39B15, 0x0000BFEC //A3 = -2.55147332073979814633e-06L
+data8 0xFC0244F58F8D8097, 0x00003FE7 //A4 = +1.17350772365097747003e-07L
+data8 0xB941D44B71B14FE2, 0x0000BFE3 //A5 = -5.39169255673480031672e-09L
+data8 0x880B4A40B6F2C901, 0x00003FDF //A6 = +2.47462779512141204748e-10L
+data8 0xC7998AE5652CDCFC, 0x0000BFDA //A7 = -1.13459336509953900777e-11L
+data8 0x92438AA45915CD95, 0x00003FD6 //A8 = +5.19633524685027215673e-13L
+data8 0xD6067243AD3AEAE6, 0x0000BFD1 //A9 = -2.37615683835509918256e-14L
+data8 0x9BD0722A07669E4D, 0x00003FCD //A10 = +1.08117849400479298186e-15L
+data8 0xDDF6F1B79F50E3C4, 0x0000BFC8 //A11 = -4.81309059042573202592e-17L
+data8 0x91F283C0351A9ACA, 0x00003FC4 //A12 = +1.97795505638619048412e-18L
+data8 0x990BC4FAFA9C7542, 0x0000BFBF //A13 = -6.48174913943425248713e-20L
+data8 0xB536865B89676892, 0x00003FB9 //A14 = +1.19916696090758913485e-21L
+// Pol19
+data8 0xB241CEB1B7C953F1, 0x00003FF9 //A0 = +2.17598950382519671244e-02L
+data8 0xDBD6FBA9B11B85E1, 0x0000BFF4 //A1 = -8.38622198373701898430e-04L
+data8 0x877605B1AD082441, 0x00003FF0 //A2 = +3.22964249573360786077e-05L
+data8 0xA6D04DC067A5D310, 0x0000BFEB //A3 = -1.24285881515578912302e-06L
+data8 0xCD458A72BC161315, 0x00003FE6 //A4 = +4.77935289502172654216e-08L
+data8 0xFC6902CFB5DE90A2, 0x0000BFE1 //A5 = -1.83652591038905929358e-09L
+data8 0x9B12B0707DFE615C, 0x00003FDD //A6 = +7.05190381049444126079e-11L
+data8 0xBE67972F2C8EE5AE, 0x0000BFD8 //A7 = -2.70581282732878853626e-12L
+data8 0xE99D8CAF9A3FFE02, 0x00003FD3 //A8 = +1.03746090805854376435e-13L
+data8 0x8F35F5BBEF9E4299, 0x0000BFCF //A9 = -3.97489765699919189983e-15L
+data8 0xAF6E62C3C91B7178, 0x00003FCA //A10 = +1.52162305785839987182e-16L
+data8 0xD6636229C1646963, 0x0000BFC5 //A11 = -5.81100425482928485309e-18L
+data8 0x810331BF289E068F, 0x00003FC1 //A12 = +2.18555638648715837944e-19L
+data8 0x8E3D07CA59546B83, 0x0000BFBC //A13 = -7.53003820427900359431e-21L
+data8 0xD5970B291ED73560, 0x00003FB6 //A14 = +1.76677518655145552907e-22L
+LOCAL_OBJECT_END(erfc_p_table)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(erfc)
+
+{ .mfi
+ alloc r32 = ar.pfs, 0, 33, 4, 0
+ fma.s1 FR_Tmp = f1, f1, f8 // |x|+1, if x >= 0
+ nop.i 0
+}
+{ .mfi
+ addl EXP_AD_TB1 = @ltoff(exp_table_1), gp
+ fms.s1 FR_Tmp1 = f1, f1, f8 // |x|+1, if x < 0
+ mov exp_GR_rshf_2to56 = 0x4768 // begin 1.1 2^(63+56)
+};;
+
+{ .mfi
+ ld8 EXP_AD_TB1 = [EXP_AD_TB1]
+ fcmp.ge.s1 p6,p7 = f8, f0 // p6: x >= 0 ,p7: x<0
+ mov exp_GR_rshf_2to56 = 0x4768 // begin 1.1 2^(63+56)
+}
+{ .mlx
+ mov exp_TB1_size = 0x100
+ movl exp_GR_sig_inv_ln2 = 0xb8aa3b295c17f0bc //signif. of 1/ln2
+};;
+
+{ .mfi
+ nop.m 0
+ fclass.m p8,p0 = f8,0x07 // p8: x = 0
+ shl exp_GR_rshf_2to56 = exp_GR_rshf_2to56, 48 //end 1.1 2^(63+56)
+}
+{ .mfi
+ mov exp_GR_exp_2tom56 = 0xffff-56
+ fnma.s1 EXP_NORM_f8 = f8, f8, f0 // high bits for -x^2
+ nop.i 0
+};;
+
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ setf.sig EXP_INV_LN2_2TO63 = exp_GR_sig_inv_ln2 // form 1/ln2 * 2^63
+(p6) fma.s1 FR_AbsArg = f1, f0, f8 // |x|, if x >= 0
+ mov GR_POS_ARG_ASYMP = 0x403C
+}
+{ .mfi
+ mov GR_NEG_ARG_ASYMP = 0x4018
+(p7) fms.s1 FR_AbsArg = f1, f0, f8 // |x|, if x < 0
+ mov exp_GR_rshf = 0x43e8 // begin 1.1 2^63 for right shift
+};;
+
+{ .mfi
+ setf.exp EXP_2TOM56 = exp_GR_exp_2tom56 // 2^-56 for scaling Nfloat
+ fclass.m p10,p0 = f8, 0x21 // p10: x = +inf
+ mov exp_GR_17ones = 0x1FFFF
+}
+{ .mlx
+ setf.d EXP_RSHF_2TO56 = exp_GR_rshf_2to56 // const 1.10*2^(63+56)
+ movl GR_ERFC_XB_TB = 0x1A0
+};;
+
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ ldfd FR_UnfBound = [EXP_AD_TB1], 16
+(p6) fma.s1 FR_Tmp = FR_Tmp, FR_Tmp, f0 // (|x|+1)^2,x >=0
+ shl exp_GR_rshf = exp_GR_rshf, 48 //end 1.1 2^63 for right shift
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s1 FR_Tmp = FR_Tmp1, FR_Tmp1, f0 // (|x|+1)^2, x<0
+ mov GR_0x1 = 0x1
+};;
+
+{ .mfi
+ mov GR_BIAS = 0x0FFFF
+ fclass.m p9,p0 = f8, 0x22 // p9: x = -inf
+ shl GR_EpsNorm = GR_0x1,53
+}
+{ .mfb
+ mov exp_TB2_size = 0x80
+(p8) fma.d.s0 f8 = f1, f1, f0 //p8: y = 1.0, x = 0
+(p8) br.ret.spnt b0 //p8: quick exit for x = 0
+};;
+
+{ .mfi
+ nop.m 0
+ fclass.m p11,p0 = f8, 0xc3 // p11: x = nan
+ nop.i 0
+}
+{ .mfi
+ setf.d EXP_RSHF = exp_GR_rshf //Form right shift const 1.100 * 2^63
+ fma.s1 FR_NormX = f8,f1,f0
+ nop.i 0
+};;
+
+{ .mfi
+ setf.d FR_EpsNorm = GR_EpsNorm
+ nop.f 0
+(p6) shl GR_ARG_ASYMP = GR_POS_ARG_ASYMP, 48//p6:ARG_ASYMP= 28.0,x>=0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_2 = f1, f1, f1
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe exp_ln2_by_128_hi = [EXP_AD_TB1],16
+ fma.s1 f8_sq_lo = f8, f8, EXP_NORM_f8 // low bits for -x^2
+(p7) shl GR_ARG_ASYMP = GR_NEG_ARG_ASYMP, 48//p6:ARG_ASYMP= 6.0,x < 0
+};;
+
+{ .mfi
+ sub GR_mBIAS = r0, GR_BIAS
+ fma.s1 FR_Tmp = FR_Tmp, FR_Tmp, f0 // (|x|+1)^4
+ nop.i 0
+}
+{ .mfi
+ ldfe exp_ln2_by_128_lo = [EXP_AD_TB1], 16
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ getf.d GR_AbsArg = FR_AbsArg
+ nop.f 0
+ add GR_ERFC_XB_TB = GR_ERFC_XB_TB, EXP_AD_TB1//pointer to XB_TBL
+}
+{ .mfb
+ shladd GR_ShftPi_bias = GR_BIAS, 4, GR_mBIAS // BIAS * 2^4 - BIAS
+(p9) fma.d.s0 f8 = f1, f1, f1 // p9: y = 2 for x = -inf
+(p9) br.ret.spnt b0 // p9: quick exit for x = -inf
+};;
+
+{ .mfi
+ add GR_ERFC_P_TB = 0x140, GR_ERFC_XB_TB // pointer to P_TBL
+ fma.s1 EXP_W_2TO56_RSH = EXP_NORM_f8,EXP_INV_LN2_2TO63,EXP_RSHF_2TO56
+ shladd GR_ShftPi_bias = GR_ShftPi_bias, 4, r0 // BIAS * 240
+}
+{ .mfb
+ nop.m 0
+(p10) fma.d.s0 f8 = f0, f1, f0 // p10: y = 0 for x = +inf
+(p10) br.ret.spnt b0 // p10: quick exit for x = +inf
+};;
+
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+(p6) cmp.gt.unc p15,p0 = GR_AbsArg,GR_ARG_ASYMP //p15: x > 28.0,p6: x >= 0
+ nop.f 0
+(p7) cmp.gt.unc p14,p0 = GR_AbsArg, GR_ARG_ASYMP //p14: x < - 6.0,p7: x < 0
+}
+{ .mfb
+ add EXP_AD_TB2 = exp_TB1_size, EXP_AD_TB1
+(p11) fma.d.s0 f8 = f8, f1, f0 //p11: y = x for x = nan
+(p11) br.ret.spnt b0 //p11: quick exit for x = nan
+};;
+
+{ .mfi
+ add EXP_AD_P = exp_TB2_size, EXP_AD_TB2
+ fms.s1 f8_sq_lo = f1, f1, f8_sq_lo // 1 - low bits for -x^2
+ nop.i 0
+};;
+
+{ .mfi
+ ldfpd exp_P4, exp_P3 = [EXP_AD_P], 16
+ fmerge.s FR_X = f8,f8
+ shladd GR_ShftXBi_bias = GR_mBIAS, 4, r0
+}
+{ .mfb
+ nop.m 0
+(p14) fnma.d.s0 FR_RESULT = FR_EpsNorm,FR_EpsNorm,FR_2 //p14:y ~=~ 2,x< -6.0
+(p14) br.ret.spnt b0 //p14: quick exit for x < -6.0
+};;
+
+//p15: y ~=~ 0.0(result with underflow error), x > ARG_ASYMP = 28,
+{ .mfi
+ ldfpd exp_P2, exp_P1 = [EXP_AD_P]
+ fma.d.s0 FR_Tmpf = f1, f1, FR_EpsNorm // flag i
+ nop.i 0
+}
+{ .mfb
+(p15) mov GR_Parameter_TAG = 208
+(p15) fma.d.s0 FR_RESULT = FR_EpsNorm,FR_EpsNorm,f0
+(p15) br.cond.spnt __libm_error_region
+};;
+
+//p8: x < 27.0, result without ungerflow error
+{ .mfi
+ getf.exp GR_IndxPlusBias = FR_Tmp // exp + bias for (|x|+1)^4
+ fcmp.lt.s1 p8,p0 = FR_NormX,FR_UnfBound
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 EXP_Nfloat = EXP_W_2TO56_RSH, EXP_2TOM56, EXP_RSHF
+ nop.i 0
+};;
+
+{ .mmi
+ shladd GR_ShftXBi = GR_IndxPlusBias, 4, GR_ShftXBi_bias
+ shladd GR_ShftPi = GR_IndxPlusBias, 4, GR_ShftPi_bias
+ shl GR_ShftPi_8 = GR_IndxPlusBias, 8
+};;
+
+{ .mmi
+ getf.sig exp_GR_N = EXP_W_2TO56_RSH
+ add GR_ERFC_XB_TB = GR_ERFC_XB_TB, GR_ShftXBi// pointer to XB[i]
+ sub GR_ShftPi = GR_ShftPi_8, GR_ShftPi // (256-16)*i
+};;
+
+{ .mmi
+ ldfe FR_Xb = [GR_ERFC_XB_TB]
+ add GR_ShftA12 = 0xC0, GR_ShftPi // pointer shift for A12
+ add GR_ShftA13 = 0xD0, GR_ShftPi // pointer shift for A13
+};;
+
+{ .mfi
+ add GR_P_A13 = GR_ERFC_P_TB, GR_ShftA13 // pointer to A13
+ nop.f 0
+ and exp_GR_index_1 = 0x0f, exp_GR_N
+}
+{ .mfi
+ add GR_P_A12 = GR_ERFC_P_TB, GR_ShftA12 // pointer to A12
+ fnma.s1 exp_r = EXP_Nfloat, exp_ln2_by_128_hi, EXP_NORM_f8
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_A12 = [GR_P_A12], -64
+ nop.f 0
+ and exp_GR_index_2_16 = 0x70, exp_GR_N
+}
+{ .mfi
+ ldfe FR_A13 = [GR_P_A13], -64
+ nop.f 0
+ shladd EXP_AD_T1 = exp_GR_index_1, 4, EXP_AD_TB1
+};;
+
+{ .mmi
+ ldfe FR_A8 = [GR_P_A12], 32
+ ldfe FR_A9 = [GR_P_A13], 32
+ add EXP_AD_T2 = EXP_AD_TB2, exp_GR_index_2_16
+};;
+
+{ .mmi
+ ldfe FR_A10 = [GR_P_A12], -96
+ ldfe FR_A11 = [GR_P_A13], -96
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe FR_A4 = [GR_P_A12], 32
+ ldfe FR_A5 = [GR_P_A13], 32
+ shr r2 = exp_GR_N, 0x7
+};;
+
+{ .mfi
+ ldfe FR_A6 = [GR_P_A12], -64
+ fma.s1 exp_rP4pP3 = exp_r, exp_P4, exp_P3
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A7 = [GR_P_A13], -64
+ fma.s1 exp_rsq = exp_r, exp_r, f0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe FR_A2 = [GR_P_A12], -32
+ ldfe FR_A3 = [GR_P_A13], -32
+ addl exp_GR_biased_M = 0xffff, r2
+};;
+
+{ .mmi
+ ldfe FR_A0 = [GR_P_A12], 224
+ ldfe FR_A1 = [GR_P_A13]
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_A14 = [GR_P_A12]
+ fms.s1 FR_LocArg = FR_AbsArg, f1, FR_Xb // xloc = x - x[i]
+ nop.i 0
+};;
+
+{ .mmi
+ setf.exp EXP_2M = exp_GR_biased_M
+ ldfe exp_T1 = [EXP_AD_T1]
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe exp_T2 = [EXP_AD_T2]
+ fma.s1 exp_P_hi = exp_rsq, exp_P1, exp_r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 exp_rcube = exp_r, exp_rsq, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 exp_P_lo = exp_r, exp_rP4pP3, exp_P2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 exp_f = EXP_Nfloat, exp_ln2_by_128_lo, f8_sq_lo
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_0_1 = FR_LocArg, FR_LocArg, f0 // xloc ^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_0_2 = FR_A13, FR_LocArg, FR_A12
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_1_1 = FR_A9, FR_LocArg, FR_A8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_1_2 = FR_A11, FR_LocArg, FR_A10
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_2_1 = FR_A5, FR_LocArg, FR_A4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_2_2 = FR_A7, FR_LocArg, FR_A6
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_3_1 = FR_A1, FR_LocArg, FR_A0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_3_2 = FR_A3, FR_LocArg, FR_A2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_6_1 = FR_P14_0_1, FR_A14, FR_P14_0_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_7_2 = FR_P14_0_1, FR_P14_0_1, f0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_7_1 = FR_P14_0_1, FR_P14_1_2, FR_P14_1_1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 exp_S2 = exp_f, exp_T2, f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 exp_S1 = EXP_2M, exp_T1, f0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_8_1 = FR_P14_0_1, FR_P14_3_2, FR_P14_3_1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_8_2 = FR_P14_0_1, FR_P14_2_2, FR_P14_2_1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_12_1 = FR_P14_7_2, FR_P14_6_1, FR_P14_7_1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 exp_S = exp_S1, exp_S2, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 exp_P = exp_rcube, exp_P_lo, exp_P_hi
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_13_1 = FR_P14_7_2, FR_P14_8_2, FR_P14_8_1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P14_13_2 = FR_P14_7_2, FR_P14_7_2, f0 // xloc^8
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Exp = exp_S, exp_P, exp_S // exp(-x^2)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Pol = FR_P14_13_2, FR_P14_12_1, FR_P14_13_1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.d.s0 FR_Tmpf = f8, f1, f0 // flag d
+ nop.i 0
+};;
+
+//p6: result for 0 < x < = 28.0,
+//p7: result for -6.0 <= x < 0,
+//p8: exit for - 6.0 <= x < UnfBound ~=~ 26.54..
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fma.d.s0 f8 = FR_Exp, FR_Pol, f0
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 208
+(p7) fnma.d.s0 f8 = FR_Exp, FR_Pol, FR_2
+(p8) br.ret.sptk b0
+};;
+
+GLOBAL_LIBM_END(erfc)
+
+// call via (p15) br.cond.spnt __libm_error_region
+// for x > ARG_ASYMP = 28.0
+// or
+//
+// after .endp erfc for UnfBound < = x < = ARG_ASYMP = 28.0
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/s_erfcf.S b/libc/sysdeps/ia64/fpu/s_erfcf.S
new file mode 100644
index 000000000..2e3eeab3c
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_erfcf.S
@@ -0,0 +1,983 @@
+.file "erfcf.s"
+
+
+// Copyright (c) 2002 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 01/17/02 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// float erfcf(float)
+//
+// Overview of operation
+//==============================================================
+// 1. 0 <= x <= 10.06
+//
+// erfcf(x) = P15(x) * exp( -x^2 )
+//
+// Comment:
+//
+// Let x(0)=0, x(i) = 2^(i), i=1,...3, x(4)= 10.06
+//
+// Let x(i)<= x < x(i+1).
+// We can find i as exponent of argument x (let i = 0 for 0<= x < 2 )
+//
+// Let P15(x) - polynomial approximation of degree 15 for function
+// erfcf(x) * exp( x^2) and x(i) <= x <= x(i+1), i = 0,1,2,3
+// Polynomial coeffitients we have in the table erfc_p_table.
+//
+// So we can find result for erfcf(x) as above.
+// Algorithm description for exp function see below.
+//
+// 2. -4.4 <= x < 0
+//
+// erfcf(x) = 2.0 - erfcf(-x)
+//
+// 3. x > 10.06
+//
+// erfcf(x) ~=~ 0.0
+//
+// 4. x < -4.4
+//
+// erfcf(x) ~=~ 2.0
+
+// Special values
+//==============================================================
+// erfcf(+0) = 1.0
+// erfcf(-0) = 1.0
+
+// erfcf(+qnan) = +qnan
+// erfcf(-qnan) = -qnan
+// erfcf(+snan) = +qnan
+// erfcf(-snan) = -qnan
+
+// erfcf(-inf) = 2.0
+// erfcf(+inf) = +0
+
+//==============================================================
+// Take double exp(double) from libm_64.
+//
+// Overview of operation
+//==============================================================
+// Take the input x. w is "how many log2/128 in x?"
+// w = x * 128/log2
+// n = int(w)
+// x = n log2/128 + r + delta
+
+// n = 128M + index_1 + 2^4 index_2
+// x = M log2 + (log2/128) index_1 + (log2/8) index_2 + r + delta
+
+// exp(x) = 2^M 2^(index_1/128) 2^(index_2/8) exp(r) exp(delta)
+// Construct 2^M
+// Get 2^(index_1/128) from table_1;
+// Get 2^(index_2/8) from table_2;
+// Calculate exp(r) by series
+// r = x - n (log2/128)_high
+// delta = - n (log2/128)_low
+// Calculate exp(delta) as 1 + delta
+//
+// Comment for erfcf:
+//
+// Let exp(r) = 1 + x + 0.5*x^2 + (1/6)*x^3
+// Let delta = 0.
+//==============================================================
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f6,f7,f9 -> f11, f32 -> f92
+
+// General registers used:
+// r14 -> r22,r32 -> r50
+
+// Predicate registers used:
+// p6 -> p15
+
+// Assembly macros
+//==============================================================
+EXP_AD_TB1 = r14
+exp_GR_sig_inv_ln2 = r15
+exp_TB1_size = r16
+exp_GR_rshf_2to56 = r17
+exp_GR_exp_2tom56 = r18
+
+exp_GR_rshf = r33
+EXP_AD_TB2 = r34
+EXP_AD_P = r35
+exp_GR_N = r36
+exp_GR_index_1 = r37
+exp_GR_index_2_16 = r38
+exp_GR_biased_M = r39
+EXP_AD_T1 = r40
+EXP_AD_T2 = r41
+exp_TB2_size = r42
+
+// GR for erfcf(x)
+//==============================================================
+GR_IndxPlusBias = r19
+GR_ExpMask = r20
+GR_BIAS = r21
+GR_ShftPi_bias = r22
+
+GR_P_POINT_1 = r43
+GR_P_POINT_2 = r44
+GR_P_POINT_3 = r45
+GR_P_POINT_4 = r46
+
+GR_ShftPi = r47
+GR_EpsNorm = r48
+
+GR_05 = r49
+GR_1_by_6 = r50
+
+// GR for __libm_support call
+//==============================================================
+
+GR_SAVE_B0 = r43
+GR_SAVE_PFS = r44
+GR_SAVE_GP = r45
+GR_SAVE_SP = r46
+
+GR_Parameter_X = r47
+GR_Parameter_Y = r48
+GR_Parameter_RESULT = r49
+GR_Parameter_TAG = r50
+
+
+// FR for exp(-x^2)
+//==============================================================
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+EXP_2TOM56 = f6
+EXP_INV_LN2_2TO63 = f7
+EXP_W_2TO56_RSH = f9
+exp_ln2_by_128_hi = f11
+
+EXP_RSHF_2TO56 = f32
+exp_ln2_by_128_lo = f33
+EXP_RSHF = f34
+EXP_Nfloat = f35
+exp_r = f36
+exp_rsq = f37
+EXP_2M = f38
+exp_S1 = f39
+exp_T1 = f40
+exp_P = f41
+exp_S = f42
+EXP_NORM_f8 = f43
+exp_S2 = f44
+exp_T2 = f45
+
+// FR for erfcf(x)
+//==============================================================
+FR_AbsArg = f46
+FR_Tmp = f47
+FR_Tmp1 = f48
+FR_Tmpf = f49
+FR_NormX = f50
+
+FR_A15 = f51
+FR_A14 = f52
+
+FR_A13 = f53
+FR_A12 = f54
+
+FR_A11 = f55
+FR_A10 = f56
+
+FR_A9 = f57
+FR_A8 = f58
+
+FR_A7 = f59
+FR_A6 = f60
+
+FR_A5 = f61
+FR_A4 = f62
+
+FR_A3 = f63
+FR_A2 = f64
+
+FR_A1 = f65
+FR_A0 = f66
+
+FR_P15_0_1 = f67
+FR_P15_1_1 = f68
+FR_P15_1_2 = f69
+FR_P15_2_1 = f70
+FR_P15_2_2 = f71
+FR_P15_3_1 = f72
+FR_P15_3_2 = f73
+FR_P15_4_1 = f74
+FR_P15_4_2 = f75
+FR_P15_7_1 = f76
+FR_P15_7_2 = f77
+FR_P15_8_1 = f78
+FR_P15_9_1 = f79
+FR_P15_9_2 = f80
+FR_P15_13_1 = f81
+FR_P15_14_1 = f82
+FR_P15_14_2 = f83
+
+FR_2 = f84
+FR_05 = f85
+FR_1_by_6 = f86
+FR_Pol = f87
+FR_Exp = f88
+
+FR_POS_ARG_ASYMP = f89
+FR_NEG_ARG_ASYMP = f90
+
+FR_UnfBound = f91
+FR_EpsNorm = f92
+
+// Data tables
+//==============================================================
+RODATA
+.align 16
+
+// ************* DO NOT CHANGE ORDER OF THESE TABLES ********************
+
+// double-extended 1/ln(2)
+// 3fff b8aa 3b29 5c17 f0bb be87fed0691d3e88
+// 3fff b8aa 3b29 5c17 f0bc
+// For speed the significand will be loaded directly with a movl and setf.sig
+// and the exponent will be bias+63 instead of bias+0. Thus subsequent
+// computations need to scale appropriately.
+// The constant 128/ln(2) is needed for the computation of w. This is also
+// obtained by scaling the computations.
+//
+// Two shifting constants are loaded directly with movl and setf.d.
+// 1. EXP_RSHF_2TO56 = 1.1000..00 * 2^(63-7)
+// This constant is added to x*1/ln2 to shift the integer part of
+// x*128/ln2 into the rightmost bits of the significand.
+// The result of this fma is EXP_W_2TO56_RSH.
+// 2. EXP_RSHF = 1.1000..00 * 2^(63)
+// This constant is subtracted from EXP_W_2TO56_RSH * 2^(-56) to give
+// the integer part of w, n, as a floating-point number.
+// The result of this fms is EXP_Nfloat.
+
+
+LOCAL_OBJECT_START(exp_table_1)
+
+data4 0x4120f5c3, 0x408ccccd //POS_ARG_ASYMP = 10.06, NEG_ARG_ASYMP = 4.4
+data4 0x41131Cdf, 0x00800000 //UnfBound ~=~ 9.1, EpsNorm ~=~ 1.1754944e-38
+//
+data8 0xb17217f7d1cf79ab , 0x00003ff7 // ln2/128 hi
+data8 0xc9e3b39803f2f6af , 0x00003fb7 // ln2/128 lo
+//
+// Table 1 is 2^(index_1/128) where
+// index_1 goes from 0 to 15
+//
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x80B1ED4FD999AB6C , 0x00003FFF
+data8 0x8164D1F3BC030773 , 0x00003FFF
+data8 0x8218AF4373FC25EC , 0x00003FFF
+data8 0x82CD8698AC2BA1D7 , 0x00003FFF
+data8 0x8383594EEFB6EE37 , 0x00003FFF
+data8 0x843A28C3ACDE4046 , 0x00003FFF
+data8 0x84F1F656379C1A29 , 0x00003FFF
+data8 0x85AAC367CC487B15 , 0x00003FFF
+data8 0x8664915B923FBA04 , 0x00003FFF
+data8 0x871F61969E8D1010 , 0x00003FFF
+data8 0x87DB357FF698D792 , 0x00003FFF
+data8 0x88980E8092DA8527 , 0x00003FFF
+data8 0x8955EE03618E5FDD , 0x00003FFF
+data8 0x8A14D575496EFD9A , 0x00003FFF
+data8 0x8AD4C6452C728924 , 0x00003FFF
+LOCAL_OBJECT_END(exp_table_1)
+
+// Table 2 is 2^(index_1/8) where
+// index_2 goes from 0 to 7
+
+LOCAL_OBJECT_START(exp_table_2)
+
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x8B95C1E3EA8BD6E7 , 0x00003FFF
+data8 0x9837F0518DB8A96F , 0x00003FFF
+data8 0xA5FED6A9B15138EA , 0x00003FFF
+data8 0xB504F333F9DE6484 , 0x00003FFF
+data8 0xC5672A115506DADD , 0x00003FFF
+data8 0xD744FCCAD69D6AF4 , 0x00003FFF
+data8 0xEAC0C6E7DD24392F , 0x00003FFF
+LOCAL_OBJECT_END(exp_table_2)
+
+LOCAL_OBJECT_START(erfc_p_table)
+
+// Pol_0
+data8 0xBEA3260C63CB0446 //A15 = -5.70673541831883454676e-07
+data8 0x3EE63D6178077654 //A14 = +1.06047480138940182343e-05
+data8 0xBF18646BC5FC70A7 //A13 = -9.30491237309283694347e-05
+data8 0x3F40F92F909117FE //A12 = +5.17986512144075019133e-04
+data8 0xBF611344289DE1E6 //A11 = -2.08438217390159994419e-03
+data8 0x3F7AF9FE6AD16DC0 //A10 = +6.58606893292862351928e-03
+data8 0xBF91D219E196CBA7 //A9 = -1.74030345858217321001e-02
+data8 0x3FA4AFDDA355854C //A8 = +4.04042493708041968315e-02
+data8 0xBFB5D465BB7025AE //A7 = -8.52721769916999425445e-02
+data8 0x3FC54C15A95B717D //A6 = +1.66384418195672549029e-01
+data8 0xBFD340A75B4B1AB5 //A5 = -3.00821150926292166899e-01
+data8 0x3FDFFFC0BFCD247F //A4 = +4.99984919839853542841e-01
+data8 0xBFE81270C361852B //A3 = -7.52251035312075583309e-01
+data8 0x3FEFFFFFC67295FC //A2 = +9.99999892800303301771e-01
+data8 0xBFF20DD74F8CD2BF //A1 = -1.12837916445020868099e+00
+data8 0x3FEFFFFFFFFE7C1D //A0 = +9.99999999988975570714e-01
+// Pol_1
+data8 0xBDE8EC4BDD953B56 //A15 = -1.81338928934942767144e-10
+data8 0x3E43607F269E2A1C //A14 = +9.02309090272196442358e-09
+data8 0xBE8C4D9E69C10E02 //A13 = -2.10875261143659275328e-07
+data8 0x3EC9CF2F84566725 //A12 = +3.07671055805877356583e-06
+data8 0xBF007980B1B46A4D //A11 = -3.14228438702169818945e-05
+data8 0x3F2F4C3AD6DEF24A //A10 = +2.38783056770846320260e-04
+data8 0xBF56F5129F8D30FA //A9 = -1.40120333363130546426e-03
+data8 0x3F7AA6C7ABFC38EE //A8 = +6.50671002200751820429e-03
+data8 0xBF98E7522CB84BEF //A7 = -2.43199195666185511109e-02
+data8 0x3FB2F68EB1C3D073 //A6 = +7.40746673580490638637e-02
+data8 0xBFC7C16055AC6385 //A5 = -1.85588876564704611769e-01
+data8 0x3FD8A707AEF5A440 //A4 = +3.85194702967570635211e-01
+data8 0xBFE547BFE39AE2EA //A3 = -6.65008492032112467310e-01
+data8 0x3FEE7C91BDF13578 //A2 = +9.52706213932898128515e-01
+data8 0xBFF1CB5B61F8C589 //A1 = -1.11214769621105541214e+00
+data8 0x3FEFEA56BC81FD37 //A0 = +9.97355812243688815239e-01
+// Pol_2
+data8 0xBD302724A12F46E0 //A15 = -5.73866382814058809406e-14
+data8 0x3D98889B75D3102E //A14 = +5.57829983681360947356e-12
+data8 0xBDF16EA15074A1E9 //A13 = -2.53671153922423457844e-10
+data8 0x3E3EC6E688CFEE5F //A12 = +7.16581828336436419561e-09
+data8 0xBE82E5ED44C52609 //A11 = -1.40802202239825487803e-07
+data8 0x3EC120BE5CE42353 //A10 = +2.04180535157522081699e-06
+data8 0xBEF7B8B0311A1911 //A9 = -2.26225266204633600888e-05
+data8 0x3F29A281F43FC238 //A8 = +1.95577968156184077632e-04
+data8 0xBF55E19858B3B7A4 //A7 = -1.33552434527526534043e-03
+data8 0x3F7DAC8C3D12E5FD //A6 = +7.24463253680473816303e-03
+data8 0xBF9FF9C04613FB47 //A5 = -3.12261622211693854028e-02
+data8 0x3FBB3D5DBF9D9366 //A4 = +1.06405123978743883370e-01
+data8 0xBFD224DE9F62C258 //A3 = -2.83500342989133623476e-01
+data8 0x3FE28A95CB8C6D3E //A2 = +5.79417131000276437708e-01
+data8 0xBFEC21205D358672 //A1 = -8.79043752717008257224e-01
+data8 0x3FEDAE44D5EDFE5B //A0 = +9.27523057776805771830e-01
+// Pol_3
+data8 0xBCA3BCA734AC82F1 //A15 = -1.36952437983096410260e-16
+data8 0x3D16740DC3990612 //A14 = +1.99425676175410093285e-14
+data8 0xBD77F4353812C46A //A13 = -1.36162367755616790260e-12
+data8 0x3DCFD0BE13C73DB4 //A12 = +5.78718761040355136007e-11
+data8 0xBE1D728DF71189B4 //A11 = -1.71406885583934105120e-09
+data8 0x3E64252C8CB710B5 //A10 = +3.75233795940731111303e-08
+data8 0xBEA514B93180F33D //A9 = -6.28261292774310809962e-07
+data8 0x3EE1381118CC7151 //A8 = +8.21066421390821904504e-06
+data8 0xBF1634404FB0FA72 //A7 = -8.47019436358372148764e-05
+data8 0x3F46B2CBBCF0EB32 //A6 = +6.92700845213200923490e-04
+data8 0xBF725C2B445E6D81 //A5 = -4.48243046949004063741e-03
+data8 0x3F974E7CFA4D89D9 //A4 = +2.27603462002522228717e-02
+data8 0xBFB6D7BAC2E342D1 //A3 = -8.92292714882032736443e-02
+data8 0x3FD0D156AD9CE2A6 //A2 = +2.62777013343603696631e-01
+data8 0xBFE1C228572AADB0 //A1 = -5.54950876471982857725e-01
+data8 0x3FE8A739F48B9A3B //A0 = +7.70413377406675619766e-01
+LOCAL_OBJECT_END(erfc_p_table)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(erfcf)
+
+// Form index i for table erfc_p_table as exponent of x
+// We use i + bias in real calculations
+{ .mlx
+ getf.exp GR_IndxPlusBias = f8 // (sign + exp + bias) of x
+ movl exp_GR_sig_inv_ln2 = 0xb8aa3b295c17f0bc //signif.of 1/ln2
+}
+{ .mlx
+ addl EXP_AD_TB1 = @ltoff(exp_table_1), gp
+ movl exp_GR_rshf_2to56 = 0x4768000000000000 // 1.100 2^(63+56)
+}
+;;
+
+// Form argument EXP_NORM_f8 for exp(-x^2)
+{ .mfi
+ ld8 EXP_AD_TB1 = [EXP_AD_TB1]
+ fcmp.ge.s1 p6,p7 = f8, f0 // p6: x >= 0 ,p7: x<0
+ mov GR_BIAS = 0x0FFFF
+}
+{ .mfi
+ mov exp_GR_exp_2tom56 = 0xffff-56
+ fnma.s1 EXP_NORM_f8 = f8, f8, f0 // -x^2
+ mov GR_ExpMask = 0x1ffff
+}
+;;
+
+// Form two constants we need
+// 1/ln2 * 2^63 to compute w = x * 1/ln2 * 128
+// 1.1000..000 * 2^(63+63-7) to right shift int(w) into the significand
+
+// p9: x = 0,+inf,-inf,nan,unnorm.
+// p10: x!= 0,+inf,-inf,nan,unnorm.
+{ .mfi
+ setf.sig EXP_INV_LN2_2TO63 = exp_GR_sig_inv_ln2 // Form 1/ln2*2^63
+ fclass.m p9,p10 = f8,0xef
+ shl GR_ShftPi_bias = GR_BIAS, 7
+}
+{ .mfi
+ setf.d EXP_RSHF_2TO56 = exp_GR_rshf_2to56 //Const 1.10*2^(63+56)
+ nop.f 0
+ and GR_IndxPlusBias = GR_IndxPlusBias, GR_ExpMask // i + bias
+}
+;;
+
+{ .mfi
+ alloc r32 = ar.pfs, 0, 15, 4, 0
+(p6) fma.s1 FR_AbsArg = f1, f0, f8 // |x| if x >= 0
+ cmp.lt p15,p0 = GR_IndxPlusBias, GR_BIAS//p15: i < 0 (for |x|<1)
+}
+{ .mlx
+ setf.exp EXP_2TOM56 = exp_GR_exp_2tom56 //2^-56 for scaling Nfloat
+ movl exp_GR_rshf = 0x43e8000000000000 //1.10 2^63,right shift.
+}
+;;
+
+{ .mfi
+ ldfps FR_POS_ARG_ASYMP, FR_NEG_ARG_ASYMP = [EXP_AD_TB1],8
+ nop.f 0
+(p15) mov GR_IndxPlusBias = GR_BIAS //Let i = 0 if i < 0
+}
+{ .mlx
+ mov GR_P_POINT_3 = 0x1A0
+ movl GR_05 = 0x3fe0000000000000
+}
+;;
+
+// Form shift GR_ShftPi from the beginning of erfc_p_table
+// to the polynomial with number i
+{ .mfi
+ ldfps FR_UnfBound, FR_EpsNorm = [EXP_AD_TB1],8
+ nop.f 0
+ shl GR_ShftPi = GR_IndxPlusBias, 7
+}
+{ .mfi
+ setf.d EXP_RSHF = exp_GR_rshf // Form right shift 1.100 * 2^63
+(p7) fms.s1 FR_AbsArg = f1, f0, f8 // |x| if x < 0
+ mov exp_TB1_size = 0x100
+}
+;;
+
+// Form pointer GR_P_POINT_3 to the beginning of erfc_p_table
+{ .mfi
+ setf.d FR_05 = GR_05
+ nop.f 0
+ sub GR_ShftPi = GR_ShftPi,GR_ShftPi_bias
+}
+{ .mfb
+ add GR_P_POINT_3 = GR_P_POINT_3, EXP_AD_TB1
+ nop.f 0
+(p9) br.cond.spnt SPECIAL // For x = 0,+inf,-inf,nan,unnorm
+}
+;;
+
+{ .mfi
+ add GR_P_POINT_1 = GR_P_POINT_3, GR_ShftPi
+ nop.f 0
+ add GR_P_POINT_2 = GR_P_POINT_3, GR_ShftPi
+}
+{ .mfi
+ ldfe exp_ln2_by_128_hi = [EXP_AD_TB1],16
+ fma.s1 FR_NormX = f8,f1,f0
+ add GR_P_POINT_3 = GR_P_POINT_3, GR_ShftPi
+}
+;;
+
+// Load coefficients for polynomial P15(x)
+{ .mfi
+ ldfpd FR_A15, FR_A14 = [GR_P_POINT_1], 16
+ nop.f 0
+ add GR_P_POINT_3 = 0x30, GR_P_POINT_3
+}
+{ .mfi
+ ldfe exp_ln2_by_128_lo = [EXP_AD_TB1], 16
+ nop.f 0
+ add GR_P_POINT_2 = 0x20, GR_P_POINT_2
+}
+;;
+
+// Now EXP_AD_TB1 points to the beginning of table 1
+{ .mlx
+ ldfpd FR_A13, FR_A12 = [GR_P_POINT_1]
+ movl GR_1_by_6 = 0x3FC5555555555555
+}
+{ .mfi
+ add GR_P_POINT_4 = 0x30, GR_P_POINT_2
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfpd FR_A11, FR_A10 = [GR_P_POINT_2]
+ fma.s1 FR_2 = f1, f1, f1
+ mov exp_TB2_size = 0x80
+}
+{ .mfi
+ ldfpd FR_A9, FR_A8 = [GR_P_POINT_3],16
+ nop.f 0
+ add GR_P_POINT_1 = 0x60 ,GR_P_POINT_1
+}
+;;
+
+// W = X * Inv_log2_by_128
+// By adding 1.10...0*2^63 we shift and get round_int(W) in significand.
+// We actually add 1.10...0*2^56 to X * Inv_log2 to do the same thing.
+{ .mfi
+ ldfpd FR_A7, FR_A6 = [GR_P_POINT_3]
+ fma.s1 EXP_W_2TO56_RSH = EXP_NORM_f8,EXP_INV_LN2_2TO63,EXP_RSHF_2TO56
+ add EXP_AD_TB2 = exp_TB1_size, EXP_AD_TB1
+
+}
+{ .mfi
+ ldfpd FR_A5, FR_A4 = [GR_P_POINT_4], 16
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfpd FR_A3, FR_A2 = [GR_P_POINT_4]
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+{ .mfi
+ ldfpd FR_A1, FR_A0 = [GR_P_POINT_1]
+ nop.f 0
+ nop.i 0
+}
+;;
+
+//p14: x < - NEG_ARG_ASYMP = -4.4 -> erfcf(x) ~=~ 2.0
+{ .mfi
+ setf.d FR_1_by_6 = GR_1_by_6
+(p7) fcmp.gt.unc.s1 p14,p0 = FR_AbsArg, FR_NEG_ARG_ASYMP //p7: x < 0
+ nop.i 0
+}
+;;
+
+//p15: x > POS_ARG_ASYMP = 10.06 -> erfcf(x) ~=~ 0.0
+{ .mfi
+ nop.m 0
+(p6) fcmp.gt.unc.s1 p15,p0 = FR_AbsArg, FR_POS_ARG_ASYMP //p6: x > 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.le.s1 p8,p0 = FR_NormX, FR_UnfBound // p8: x <= UnfBound
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p14) fnma.s.s0 FR_RESULT = FR_EpsNorm, FR_EpsNorm, FR_2//y = 2 if x <-4.4
+(p14) br.ret.spnt b0
+}
+;;
+
+// Nfloat = round_int(W)
+// The signficand of EXP_W_2TO56_RSH contains the rounded integer part of W,
+// as a twos complement number in the lower bits (that is, it may be negative).
+// That twos complement number (called N) is put into exp_GR_N.
+
+// Since EXP_W_2TO56_RSH is scaled by 2^56, it must be multiplied by 2^-56
+// before the shift constant 1.10000 * 2^63 is subtracted to yield EXP_Nfloat.
+// Thus, EXP_Nfloat contains the floating point version of N
+
+{ .mfi
+ nop.m 0
+ fms.s1 EXP_Nfloat = EXP_W_2TO56_RSH, EXP_2TOM56, EXP_RSHF
+ nop.i 0
+}
+{ .mfb
+(p15) mov GR_Parameter_TAG = 209
+(p15) fma.s.s0 FR_RESULT = FR_EpsNorm,FR_EpsNorm,f0 //Result.for x>10.06
+(p15) br.cond.spnt __libm_error_region
+}
+;;
+
+// Now we can calculate polynomial P15(x)
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_1_1 = FR_AbsArg, FR_AbsArg, f0 // x ^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_0_1 = FR_A15, FR_AbsArg, FR_A14
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_1_2 = FR_A13, FR_AbsArg, FR_A12
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.sig exp_GR_N = EXP_W_2TO56_RSH
+ fma.s1 FR_P15_2_1 = FR_A9, FR_AbsArg, FR_A8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_2_2 = FR_A11, FR_AbsArg, FR_A10
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_3_1 = FR_A5, FR_AbsArg, FR_A4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_3_2 = FR_A7, FR_AbsArg, FR_A6
+ nop.i 0
+}
+;;
+
+// exp_GR_index_1 has index_1
+// exp_GR_index_2_16 has index_2 * 16
+// exp_GR_biased_M has M
+// exp_GR_index_1_16 has index_1 * 16
+
+// r2 has true M
+{ .mfi
+ and exp_GR_index_1 = 0x0f, exp_GR_N
+ fma.s1 FR_P15_4_1 = FR_A1, FR_AbsArg, FR_A0
+ shr r2 = exp_GR_N, 0x7
+
+}
+{ .mfi
+ and exp_GR_index_2_16 = 0x70, exp_GR_N
+ fma.s1 FR_P15_4_2 = FR_A3, FR_AbsArg, FR_A2
+ nop.i 0
+}
+;;
+
+// EXP_AD_T1 has address of T1
+// EXP_AD_T2 has address if T2
+
+{ .mfi
+ add EXP_AD_T2 = EXP_AD_TB2, exp_GR_index_2_16
+ nop.f 0
+ shladd EXP_AD_T1 = exp_GR_index_1, 4, EXP_AD_TB1
+}
+{ .mfi
+ addl exp_GR_biased_M = 0xffff, r2
+ fnma.s1 exp_r = EXP_Nfloat, exp_ln2_by_128_hi, EXP_NORM_f8
+ nop.i 0
+}
+;;
+
+// Create Scale = 2^M
+// r = x - Nfloat * ln2_by_128_hi
+
+{ .mfi
+ setf.exp EXP_2M = exp_GR_biased_M
+ fma.s1 FR_P15_7_1 = FR_P15_0_1, FR_P15_1_1, FR_P15_1_2
+ nop.i 0
+}
+{ .mfi
+ ldfe exp_T2 = [EXP_AD_T2]
+ nop.f 0
+ nop.i 0
+}
+;;
+
+// Load T1 and T2
+
+{ .mfi
+ ldfe exp_T1 = [EXP_AD_T1]
+ fma.s1 FR_P15_7_2 = FR_P15_1_1, FR_P15_1_1, f0 // x^4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_8_1 = FR_P15_1_1, FR_P15_2_2, FR_P15_2_1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_9_1 = FR_P15_1_1, FR_P15_4_2, FR_P15_4_1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_9_2 = FR_P15_1_1, FR_P15_3_2, FR_P15_3_1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 exp_P = FR_1_by_6, exp_r, FR_05
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 exp_rsq = exp_r, exp_r, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_13_1 = FR_P15_7_2, FR_P15_7_1, FR_P15_8_1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_14_1 = FR_P15_7_2, FR_P15_9_2, FR_P15_9_1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_14_2 = FR_P15_7_2, FR_P15_7_2, f0 // x^8
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 exp_P = exp_P, exp_rsq, exp_r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 exp_S1 = EXP_2M, exp_T2, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Pol = FR_P15_14_2, FR_P15_13_1, FR_P15_14_1 // P15(x)
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 exp_S = exp_S1, exp_T1, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Exp = exp_S, exp_P, exp_S // exp(-x^2)
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s.s0 FR_Tmpf = f8, f1, f0 // Flag d
+ nop.i 0
+}
+;;
+
+//p6: result for 0 < x < = POS_ARG_ASYMP
+//p7: result for - NEG_ARG_ASYMP <= x < 0
+//p8: exit for - NEG_ARG_ASYMP <= x <= UnfBound, x!=0
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fma.s.s0 f8 = FR_Exp, FR_Pol, f0
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 209
+(p7) fnma.s.s0 f8 = FR_Exp, FR_Pol, FR_2
+(p8) br.ret.sptk b0
+}
+;;
+
+//p10: branch for UnfBound < x < = POS_ARG_ASYMP
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p10) br.cond.spnt __libm_error_region
+}
+;;
+
+//Only via (p9) br.cond.spnt SPECIAL for x = 0,+inf,-inf,nan,unnorm
+SPECIAL:
+
+{ .mfi
+ nop.m 0
+ fclass.m.unc p10,p0 = f8,0x07 // p10: x = 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m.unc p11,p0 = f8,0x21 // p11: x = +inf
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m.unc p12,p0 = f8,0x22 // p12 x = -inf
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p10) fma.s.s0 f8 = f1, f1, f0
+(p10) br.ret.sptk b0 // Quick exit for x = 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m.unc p13,p0 = f8,0xc3 // p13: x = nan
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p11) fma.s.s0 f8 = f0, f1, f0
+(p11) br.ret.spnt b0 // Quick exit for x = +inf
+}
+;;
+{ .mfi
+ nop.m 0
+ fclass.m.unc p14,p0 = f8,0x0b // P14: x = unnormalized
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p12) fma.s.s0 f8 = f1, f1, f1
+(p12) br.ret.spnt b0 // Quick exit for x = -inf
+}
+;;
+
+{ .mfb
+ nop.m 0
+(p13) fma.s.s0 f8 = f8, f1, f0
+(p13) br.ret.sptk b0 // Quick exit for x = nan
+}
+;;
+
+{ .mfb
+ nop.m 0
+(p14) fnma.s.s0 f8 = f8, f1, f1
+(p14) br.ret.sptk b0 // Quick exit for x = unnormalized
+}
+;;
+
+GLOBAL_LIBM_END(erfcf)
+
+
+// Call via (p10) br.cond.spnt __libm_error_region
+// for UnfBound < x < = POS_ARG_ASYMP
+// and
+//
+// call via (p15) br.cond.spnt __libm_error_region
+// for x > POS_ARG_ASYMP
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/s_erfcl.S b/libc/sysdeps/ia64/fpu/s_erfcl.S
new file mode 100644
index 000000000..266e1e1c9
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_erfcl.S
@@ -0,0 +1,2066 @@
+.file "erfcl.s"
+
+
+// Copyright (c) 2001 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 11/12/01 Initial version
+// 02/08/02 Added missing }
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// long double erfcl(long double)
+//
+// Implementation and Algorithm Notes:
+//==============================================================
+// 1. 0 <= x <= 107.0
+//
+// erfcl(x) ~=~ P15(z) * expl( -x^2 )/(dx + x), z = x - xc(i).
+//
+// Comment:
+//
+// Let x(i) = -1.0 + 2^(i/4),i=0,...27. So we have 28 unequal
+// argument intervals [x(i),x(i+1)] with length ratio q = 2^(1/4).
+// Values xc(i) we have in the table erfc_xc_table,xc(i)=x(i)for i = 0
+// and xc(i)= 0.5*( x(i)+x(i+1) ) for i>0.
+//
+// Let x(i)<= x < x(i+1).
+// We can find i as exponent of number (x + 1)^4.
+//
+// Let P15(z)= a0+ a1*z +..+a15*z^15 - polynomial approximation of degree 15
+// for function erfcl(z+xc(i)) * expl( (z+xc(i))^2)* (dx+z+xc(i)) and
+// -0.5*[x(i+1)-x(i)] <= z <= 0.5*[x(i+1)-x(i)].
+//
+// Let Q(z)= (P(z)- S)/S, S = a0, rounded to 16 bits.
+// Polynomial coeffitients for Q(z) we have in the table erfc_Q_table as
+// long double values
+//
+// We use multi precision to calculate input argument -x^2 for expl and
+// for u = 1/(dx + x).
+//
+// Algorithm description for expl function see below. In accordance with
+// denotation of this algorithm we have for expl:
+//
+// expl(X) ~=~ 2^K*T_1*(1+W_1)*T_2*(1+W_2)*(1+ poly(r)), X = -x^2.
+//
+// Final calculations for erfcl:
+//
+// erfcl(x) ~=~
+//
+// 2^K*T_1*(1+W_1)*T_2*(1+W_2)*(1+ poly(r))*(1-dy)*S*(1+Q(z))*u*(1+du),
+//
+// where dy - low bits of x^2 and u, u*du - hi and low bits of 1/(dx + x).
+//
+// The order of calculations is the next:
+//
+// 1) M = 2^K*T_1*T_2*S without rounding error,
+// 2) W = W_1 + (W_2 + W_1*W_2), where 1+W ~=~ (1+W_1)(1+W_2),
+// 3) H = W - dy, where 1+H ~=~ (1+W )(1-dy),
+// 4) R = poly(r)*H + poly(r),
+// 5) R = H + R , where 1+R ~=~ (1+H )(1+poly(r)),
+// 6) G = Q(z)*R + Q(z),
+// 7) R1 = R + du, where 1+R1 ~=~ (1+R)(1+du),
+// 8) G1 = R1 + G, where 1+G1 ~=~ (1+R1)(1+Q(z)),
+// 9) V = G1*M*u,
+// 10) erfcl(x) ~=~ M*u + V
+//
+// 2. -6.5 <= x < 0
+//
+// erfcl(x) = 2.0 - erfl(-x)
+//
+// 3. x > 107.0
+// erfcl(x) ~=~ 0.0
+//
+// 4. x < -6.5
+// erfcl(x) ~=~ 2.0
+
+// Special values
+//==============================================================
+// erfcl(+0) = 1.0
+// erfcl(-0) = 1.0
+
+// erfcl(+qnan) = +qnan
+// erfcl(-qnan) = -qnan
+// erfcl(+snan) = +qnan
+// erfcl(-snan) = -qnan
+
+// erfcl(-inf) = 2.0
+// erfcl(+inf) = +0
+
+//==============================================================
+// Algorithm description of used expl function.
+//
+// Implementation and Algorithm Notes:
+//
+// ker_exp_64( in_FR : X,
+// out_FR : Y_hi,
+// out_FR : Y_lo,
+// out_FR : scale,
+// out_PR : Safe )
+//
+// On input, X is in register format
+//
+// On output,
+//
+// scale*(Y_hi + Y_lo) approximates exp(X)
+//
+// The accuracy is sufficient for a highly accurate 64 sig.
+// bit implementation. Safe is set if there is no danger of
+// overflow/underflow when the result is composed from scale,
+// Y_hi and Y_lo. Thus, we can have a fast return if Safe is set.
+// Otherwise, one must prepare to handle the possible exception
+// appropriately. Note that SAFE not set (false) does not mean
+// that overflow/underflow will occur; only the setting of SAFE
+// guarantees the opposite.
+//
+// **** High Level Overview ****
+//
+// The method consists of three cases.
+//
+// If |X| < Tiny use case exp_tiny;
+// else if |X| < 2^(-6) use case exp_small;
+// else use case exp_regular;
+//
+// Case exp_tiny:
+//
+// 1 + X can be used to approximate exp(X)
+// X + X^2/2 can be used to approximate exp(X) - 1
+//
+// Case exp_small:
+//
+// Here, exp(X) and exp(X) - 1 can all be
+// appproximated by a relatively simple polynomial.
+//
+// This polynomial resembles the truncated Taylor series
+//
+// exp(w) = 1 + w + w^2/2! + w^3/3! + ... + w^n/n!
+//
+// Case exp_regular:
+//
+// Here we use a table lookup method. The basic idea is that in
+// order to compute exp(X), we accurately decompose X into
+//
+// X = N * log(2)/(2^12) + r, |r| <= log(2)/2^13.
+//
+// Hence
+//
+// exp(X) = 2^( N / 2^12 ) * exp(r).
+//
+// The value 2^( N / 2^12 ) is obtained by simple combinations
+// of values calculated beforehand and stored in table; exp(r)
+// is approximated by a short polynomial because |r| is small.
+//
+// We elaborate this method in 4 steps.
+//
+// Step 1: Reduction
+//
+// The value 2^12/log(2) is stored as a double-extended number
+// L_Inv.
+//
+// N := round_to_nearest_integer( X * L_Inv )
+//
+// The value log(2)/2^12 is stored as two numbers L_hi and L_lo so
+// that r can be computed accurately via
+//
+// r := (X - N*L_hi) - N*L_lo
+//
+// We pick L_hi such that N*L_hi is representable in 64 sig. bits
+// and thus the FMA X - N*L_hi is error free. So r is the
+// 1 rounding error from an exact reduction with respect to
+//
+// L_hi + L_lo.
+//
+// In particular, L_hi has 30 significant bit and can be stored
+// as a double-precision number; L_lo has 64 significant bits and
+// stored as a double-extended number.
+//
+// Step 2: Approximation
+//
+// exp(r) - 1 is approximated by a short polynomial of the form
+//
+// r + A_1 r^2 + A_2 r^3 + A_3 r^4 .
+//
+// Step 3: Composition from Table Values
+//
+// The value 2^( N / 2^12 ) can be composed from a couple of tables
+// of precalculated values. First, express N as three integers
+// K, M_1, and M_2 as
+//
+// N = K * 2^12 + M_1 * 2^6 + M_2
+//
+// Where 0 <= M_1, M_2 < 2^6; and K can be positive or negative.
+// When N is represented in 2's complement, M_2 is simply the 6
+// lsb's, M_1 is the next 6, and K is simply N shifted right
+// arithmetically (sign extended) by 12 bits.
+//
+// Now, 2^( N / 2^12 ) is simply
+//
+// 2^K * 2^( M_1 / 2^6 ) * 2^( M_2 / 2^12 )
+//
+// Clearly, 2^K needs no tabulation. The other two values are less
+// trivial because if we store each accurately to more than working
+// precision, than its product is too expensive to calculate. We
+// use the following method.
+//
+// Define two mathematical values, delta_1 and delta_2, implicitly
+// such that
+//
+// T_1 = exp( [M_1 log(2)/2^6] - delta_1 )
+// T_2 = exp( [M_2 log(2)/2^12] - delta_2 )
+//
+// are representable as 24 significant bits. To illustrate the idea,
+// we show how we define delta_1:
+//
+// T_1 := round_to_24_bits( exp( M_1 log(2)/2^6 ) )
+// delta_1 = (M_1 log(2)/2^6) - log( T_1 )
+//
+// The last equality means mathematical equality. We then tabulate
+//
+// W_1 := exp(delta_1) - 1
+// W_2 := exp(delta_2) - 1
+//
+// Both in double precision.
+//
+// From the tabulated values T_1, T_2, W_1, W_2, we compose the values
+// T and W via
+//
+// T := T_1 * T_2 ...exactly
+// W := W_1 + (1 + W_1)*W_2
+//
+// W approximates exp( delta ) - 1 where delta = delta_1 + delta_2.
+// The mathematical product of T and (W+1) is an accurate representation
+// of 2^(M_1/2^6) * 2^(M_2/2^12).
+//
+// Step 4. Reconstruction
+//
+// Finally, we can reconstruct exp(X), exp(X) - 1.
+// Because
+//
+// X = K * log(2) + (M_1*log(2)/2^6 - delta_1)
+// + (M_2*log(2)/2^12 - delta_2)
+// + delta_1 + delta_2 + r ...accurately
+// We have
+//
+// exp(X) ~=~ 2^K * ( T + T*[exp(delta_1+delta_2+r) - 1] )
+// ~=~ 2^K * ( T + T*[exp(delta + r) - 1] )
+// ~=~ 2^K * ( T + T*[(exp(delta)-1)
+// + exp(delta)*(exp(r)-1)] )
+// ~=~ 2^K * ( T + T*( W + (1+W)*poly(r) ) )
+// ~=~ 2^K * ( Y_hi + Y_lo )
+//
+// where Y_hi = T and Y_lo = T*(W + (1+W)*poly(r))
+//
+// For exp(X)-1, we have
+//
+// exp(X)-1 ~=~ 2^K * ( Y_hi + Y_lo ) - 1
+// ~=~ 2^K * ( Y_hi + Y_lo - 2^(-K) )
+//
+// and we combine Y_hi + Y_lo - 2^(-N) into the form of two
+// numbers Y_hi + Y_lo carefully.
+//
+// **** Algorithm Details ****
+//
+// A careful algorithm must be used to realize the mathematical ideas
+// accurately. We describe each of the three cases. We assume SAFE
+// is preset to be TRUE.
+//
+// Case exp_tiny:
+//
+// The important points are to ensure an accurate result under
+// different rounding directions and a correct setting of the SAFE
+// flag.
+//
+// If expm1 is 1, then
+// SAFE := False ...possibility of underflow
+// Scale := 1.0
+// Y_hi := X
+// Y_lo := 2^(-17000)
+// Else
+// Scale := 1.0
+// Y_hi := 1.0
+// Y_lo := X ...for different rounding modes
+// Endif
+//
+// Case exp_small:
+//
+// Here we compute a simple polynomial. To exploit parallelism, we split
+// the polynomial into several portions.
+//
+// Let r = X
+//
+// If exp ...i.e. exp( argument )
+//
+// rsq := r * r;
+// r4 := rsq*rsq
+// poly_lo := P_3 + r*(P_4 + r*(P_5 + r*P_6))
+// poly_hi := r + rsq*(P_1 + r*P_2)
+// Y_lo := poly_hi + r4 * poly_lo
+// Y_hi := 1.0
+// Scale := 1.0
+//
+// Else ...i.e. exp( argument ) - 1
+//
+// rsq := r * r
+// r4 := rsq * rsq
+// r6 := rsq * r4
+// poly_lo := r6*(Q_5 + r*(Q_6 + r*Q_7))
+// poly_hi := Q_1 + r*(Q_2 + r*(Q_3 + r*Q_4))
+// Y_lo := rsq*poly_hi + poly_lo
+// Y_hi := X
+// Scale := 1.0
+//
+// Endif
+//
+// Case exp_regular:
+//
+// The previous description contain enough information except the
+// computation of poly and the final Y_hi and Y_lo in the case for
+// exp(X)-1.
+//
+// The computation of poly for Step 2:
+//
+// rsq := r*r
+// poly := r + rsq*(A_1 + r*(A_2 + r*A_3))
+//
+// For the case exp(X) - 1, we need to incorporate 2^(-K) into
+// Y_hi and Y_lo at the end of Step 4.
+//
+// If K > 10 then
+// Y_lo := Y_lo - 2^(-K)
+// Else
+// If K < -10 then
+// Y_lo := Y_hi + Y_lo
+// Y_hi := -2^(-K)
+// Else
+// Y_hi := Y_hi - 2^(-K)
+// End If
+// End If
+//
+
+// Overview of operation
+//==============================================================
+
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f9 -> f14, f36 -> f126
+
+// General registers used:
+// r32 -> r71
+
+// Predicate registers used:
+// p6 -> p15
+
+// Assembly macros
+//==============================================================
+// GR for exp(X)
+GR_ad_Arg = r33
+GR_ad_C = r34
+GR_ERFC_S_TB = r35
+GR_signexp_x = r36
+GR_exp_x = r36
+GR_exp_mask = r37
+GR_ad_W1 = r38
+GR_ad_W2 = r39
+GR_M2 = r40
+GR_M1 = r41
+GR_K = r42
+GR_exp_2_k = r43
+GR_ad_T1 = r44
+GR_ad_T2 = r45
+GR_N_fix = r46
+GR_ad_P = r47
+GR_exp_bias = r48
+GR_BIAS = r48
+GR_exp_half = r49
+GR_sig_inv_ln2 = r50
+GR_rshf_2to51 = r51
+GR_exp_2tom51 = r52
+GR_rshf = r53
+
+// GR for erfcl(x)
+//==============================================================
+
+GR_ERFC_XC_TB = r54
+GR_ERFC_P_TB = r55
+GR_IndxPlusBias = r56
+GR_P_POINT_1 = r57
+GR_P_POINT_2 = r58
+GR_AbsArg = r59
+GR_ShftXBi = r60
+GR_ShftPi = r61
+GR_mBIAS = r62
+GR_ShftPi_bias = r63
+GR_ShftXBi_bias = r64
+GR_ShftA14 = r65
+GR_ShftA15 = r66
+GR_EpsNorm = r67
+GR_0x1 = r68
+GR_ShftPi_8 = r69
+GR_26PlusBias = r70
+GR_27PlusBias = r71
+
+// GR for __libm_support call
+//==============================================================
+GR_SAVE_B0 = r64
+GR_SAVE_PFS = r65
+GR_SAVE_GP = r66
+GR_SAVE_SP = r67
+
+GR_Parameter_X = r68
+GR_Parameter_Y = r69
+GR_Parameter_RESULT = r70
+GR_Parameter_TAG = r71
+
+//==============================================================
+// Floating Point Registers
+//
+FR_RSHF_2TO51 = f10
+FR_INV_LN2_2TO63 = f11
+FR_W_2TO51_RSH = f12
+FR_2TOM51 = f13
+FR_RSHF = f14
+
+FR_scale = f36
+FR_float_N = f37
+FR_N_signif = f38
+FR_L_hi = f39
+FR_L_lo = f40
+FR_r = f41
+FR_W1 = f42
+FR_T1 = f43
+FR_W2 = f44
+FR_T2 = f45
+FR_rsq = f46
+FR_C2 = f47
+FR_C3 = f48
+FR_poly = f49
+FR_P6 = f49
+FR_T = f50
+FR_P5 = f50
+FR_P4 = f51
+FR_W = f51
+FR_P3 = f52
+FR_Wp1 = f52
+FR_P2 = f53
+FR_P1 = f54
+FR_Q7 = f56
+FR_Q6 = f57
+FR_Q5 = f58
+FR_Q4 = f59
+FR_Q3 = f60
+FR_Q2 = f61
+FR_Q1 = f62
+FR_C1 = f63
+FR_A15 = f64
+FR_ch_dx = f65
+FR_T_scale = f66
+FR_norm_x = f67
+FR_AbsArg = f68
+FR_POS_ARG_ASYMP = f69
+FR_NEG_ARG_ASYMP = f70
+FR_Tmp = f71
+FR_Xc = f72
+FR_A0 = f73
+FR_A1 = f74
+FR_A2 = f75
+FR_A3 = f76
+FR_A4 = f77
+FR_A5 = f78
+FR_A6 = f79
+FR_A7 = f80
+FR_A8 = f81
+FR_A9 = f82
+FR_A10 = f83
+FR_A11 = f84
+FR_A12 = f85
+FR_A13 = f86
+FR_A14 = f87
+FR_P15_0_1 = f88
+FR_P15_8_1 = f88
+FR_P15_1_1 = f89
+FR_P15_8_2 = f89
+FR_P15_1_2 = f90
+FR_P15_2_1 = f91
+FR_P15_2_2 = f92
+FR_P15_3_1 = f93
+FR_P15_3_2 = f94
+FR_P15_4_2 = f95
+FR_P15_7_1 = f96
+FR_P15_7_2 = f97
+FR_P15_9_1 = f98
+FR_P15_9_2 = f99
+FR_P15_13_1 = f100
+FR_P15_14_1 = f101
+FR_P15_14_2 = f102
+FR_Tmp2 = f103
+FR_Xpdx_lo = f104
+FR_2 = f105
+FR_xsq_lo = f106
+FR_LocArg = f107
+FR_Tmpf = f108
+FR_Tmp1 = f109
+FR_EpsNorm = f110
+FR_UnfBound = f111
+FR_NormX = f112
+FR_Xpdx_hi = f113
+FR_dU = f114
+FR_H = f115
+FR_G = f116
+FR_V = f117
+FR_M = f118
+FR_U = f119
+FR_Q = f120
+FR_S = f121
+FR_R = f122
+FR_res_pos_x_hi = f123
+FR_res_pos_x_lo = f124
+FR_dx = f125
+FR_dx1 = f126
+
+// for error handler routine
+FR_X = f9
+FR_Y = f0
+FR_RESULT = f8
+
+// Data tables
+//==============================================================
+RODATA
+.align 16
+
+// ************* DO NOT CHANGE ORDER OF THESE TABLES ********************
+LOCAL_OBJECT_START(exp_table_1)
+
+data8 0xae89f995ad3ad5ea , 0x00003ffe // x = 0.681..,bound for dx = 0.875
+data8 0x405AC00000000000 , 0x401A000000000000 //ARG_ASYMP,NEG_ARG_ASYMP
+data8 0x3FE4000000000000 , 0x3FEC000000000000 //0.625,0.875
+data8 0xD5126065B720A4e9 , 0x00004005 // underflow boundary
+data8 0x8000000000000000 , 0x00000001 //FR_EpsNorm
+LOCAL_OBJECT_END(exp_table_1)
+
+LOCAL_OBJECT_START(Constants_exp_64_Arg)
+data8 0xB17217F400000000,0x00003FF2 //L_hi = hi part log(2)/2^12
+data8 0xF473DE6AF278ECE6,0x00003FD4 //L_lo = lo part log(2)/2^12
+LOCAL_OBJECT_END(Constants_exp_64_Arg)
+
+LOCAL_OBJECT_START(Constants_exp_64_C)
+data8 0xAAAAAAABB1B736A0,0x00003FFA // C3
+data8 0xAAAAAAAB90CD6327,0x00003FFC // C2
+data8 0xFFFFFFFFFFFFFFFF,0x00003FFD // C1
+LOCAL_OBJECT_END(Constants_exp_64_C)
+
+LOCAL_OBJECT_START(Constants_exp_64_T1)
+data4 0x3F800000,0x3F8164D2,0x3F82CD87,0x3F843A29
+data4 0x3F85AAC3,0x3F871F62,0x3F88980F,0x3F8A14D5
+data4 0x3F8B95C2,0x3F8D1ADF,0x3F8EA43A,0x3F9031DC
+data4 0x3F91C3D3,0x3F935A2B,0x3F94F4F0,0x3F96942D
+data4 0x3F9837F0,0x3F99E046,0x3F9B8D3A,0x3F9D3EDA
+data4 0x3F9EF532,0x3FA0B051,0x3FA27043,0x3FA43516
+data4 0x3FA5FED7,0x3FA7CD94,0x3FA9A15B,0x3FAB7A3A
+data4 0x3FAD583F,0x3FAF3B79,0x3FB123F6,0x3FB311C4
+data4 0x3FB504F3,0x3FB6FD92,0x3FB8FBAF,0x3FBAFF5B
+data4 0x3FBD08A4,0x3FBF179A,0x3FC12C4D,0x3FC346CD
+data4 0x3FC5672A,0x3FC78D75,0x3FC9B9BE,0x3FCBEC15
+data4 0x3FCE248C,0x3FD06334,0x3FD2A81E,0x3FD4F35B
+data4 0x3FD744FD,0x3FD99D16,0x3FDBFBB8,0x3FDE60F5
+data4 0x3FE0CCDF,0x3FE33F89,0x3FE5B907,0x3FE8396A
+data4 0x3FEAC0C7,0x3FED4F30,0x3FEFE4BA,0x3FF28177
+data4 0x3FF5257D,0x3FF7D0DF,0x3FFA83B3,0x3FFD3E0C
+LOCAL_OBJECT_END(Constants_exp_64_T1)
+
+LOCAL_OBJECT_START(Constants_exp_64_T2)
+data4 0x3F800000,0x3F80058C,0x3F800B18,0x3F8010A4
+data4 0x3F801630,0x3F801BBD,0x3F80214A,0x3F8026D7
+data4 0x3F802C64,0x3F8031F2,0x3F803780,0x3F803D0E
+data4 0x3F80429C,0x3F80482B,0x3F804DB9,0x3F805349
+data4 0x3F8058D8,0x3F805E67,0x3F8063F7,0x3F806987
+data4 0x3F806F17,0x3F8074A8,0x3F807A39,0x3F807FCA
+data4 0x3F80855B,0x3F808AEC,0x3F80907E,0x3F809610
+data4 0x3F809BA2,0x3F80A135,0x3F80A6C7,0x3F80AC5A
+data4 0x3F80B1ED,0x3F80B781,0x3F80BD14,0x3F80C2A8
+data4 0x3F80C83C,0x3F80CDD1,0x3F80D365,0x3F80D8FA
+data4 0x3F80DE8F,0x3F80E425,0x3F80E9BA,0x3F80EF50
+data4 0x3F80F4E6,0x3F80FA7C,0x3F810013,0x3F8105AA
+data4 0x3F810B41,0x3F8110D8,0x3F81166F,0x3F811C07
+data4 0x3F81219F,0x3F812737,0x3F812CD0,0x3F813269
+data4 0x3F813802,0x3F813D9B,0x3F814334,0x3F8148CE
+data4 0x3F814E68,0x3F815402,0x3F81599C,0x3F815F37
+LOCAL_OBJECT_END(Constants_exp_64_T2)
+
+LOCAL_OBJECT_START(Constants_exp_64_W1)
+data8 0x0000000000000000, 0xBE384454171EC4B4
+data8 0xBE6947414AA72766, 0xBE5D32B6D42518F8
+data8 0x3E68D96D3A319149, 0xBE68F4DA62415F36
+data8 0xBE6DDA2FC9C86A3B, 0x3E6B2E50F49228FE
+data8 0xBE49C0C21188B886, 0x3E64BFC21A4C2F1F
+data8 0xBE6A2FBB2CB98B54, 0x3E5DC5DE9A55D329
+data8 0x3E69649039A7AACE, 0x3E54728B5C66DBA5
+data8 0xBE62B0DBBA1C7D7D, 0x3E576E0409F1AF5F
+data8 0x3E6125001A0DD6A1, 0xBE66A419795FBDEF
+data8 0xBE5CDE8CE1BD41FC, 0xBE621376EA54964F
+data8 0x3E6370BE476E76EE, 0x3E390D1A3427EB92
+data8 0x3E1336DE2BF82BF8, 0xBE5FF1CBD0F7BD9E
+data8 0xBE60A3550CEB09DD, 0xBE5CA37E0980F30D
+data8 0xBE5C541B4C082D25, 0xBE5BBECA3B467D29
+data8 0xBE400D8AB9D946C5, 0xBE5E2A0807ED374A
+data8 0xBE66CB28365C8B0A, 0x3E3AAD5BD3403BCA
+data8 0x3E526055C7EA21E0, 0xBE442C75E72880D6
+data8 0x3E58B2BB85222A43, 0xBE5AAB79522C42BF
+data8 0xBE605CB4469DC2BC, 0xBE589FA7A48C40DC
+data8 0xBE51C2141AA42614, 0xBE48D087C37293F4
+data8 0x3E367A1CA2D673E0, 0xBE51BEBB114F7A38
+data8 0xBE6348E5661A4B48, 0xBDF526431D3B9962
+data8 0x3E3A3B5E35A78A53, 0xBE46C46C1CECD788
+data8 0xBE60B7EC7857D689, 0xBE594D3DD14F1AD7
+data8 0xBE4F9C304C9A8F60, 0xBE52187302DFF9D2
+data8 0xBE5E4C8855E6D68F, 0xBE62140F667F3DC4
+data8 0xBE36961B3BF88747, 0x3E602861C96EC6AA
+data8 0xBE3B5151D57FD718, 0x3E561CD0FC4A627B
+data8 0xBE3A5217CA913FEA, 0x3E40A3CC9A5D193A
+data8 0xBE5AB71310A9C312, 0x3E4FDADBC5F57719
+data8 0x3E361428DBDF59D5, 0x3E5DB5DB61B4180D
+data8 0xBE42AD5F7408D856, 0x3E2A314831B2B707
+LOCAL_OBJECT_END(Constants_exp_64_W1)
+
+LOCAL_OBJECT_START(Constants_exp_64_W2)
+data8 0x0000000000000000, 0xBE641F2537A3D7A2
+data8 0xBE68DD57AD028C40, 0xBE5C77D8F212B1B6
+data8 0x3E57878F1BA5B070, 0xBE55A36A2ECAE6FE
+data8 0xBE620608569DFA3B, 0xBE53B50EA6D300A3
+data8 0x3E5B5EF2223F8F2C, 0xBE56A0D9D6DE0DF4
+data8 0xBE64EEF3EAE28F51, 0xBE5E5AE2367EA80B
+data8 0x3E47CB1A5FCBC02D, 0xBE656BA09BDAFEB7
+data8 0x3E6E70C6805AFEE7, 0xBE6E0509A3415EBA
+data8 0xBE56856B49BFF529, 0x3E66DD3300508651
+data8 0x3E51165FC114BC13, 0x3E53333DC453290F
+data8 0x3E6A072B05539FDA, 0xBE47CD877C0A7696
+data8 0xBE668BF4EB05C6D9, 0xBE67C3E36AE86C93
+data8 0xBE533904D0B3E84B, 0x3E63E8D9556B53CE
+data8 0x3E212C8963A98DC8, 0xBE33138F032A7A22
+data8 0x3E530FA9BC584008, 0xBE6ADF82CCB93C97
+data8 0x3E5F91138370EA39, 0x3E5443A4FB6A05D8
+data8 0x3E63DACD181FEE7A, 0xBE62B29DF0F67DEC
+data8 0x3E65C4833DDE6307, 0x3E5BF030D40A24C1
+data8 0x3E658B8F14E437BE, 0xBE631C29ED98B6C7
+data8 0x3E6335D204CF7C71, 0x3E529EEDE954A79D
+data8 0x3E5D9257F64A2FB8, 0xBE6BED1B854ED06C
+data8 0x3E5096F6D71405CB, 0xBE3D4893ACB9FDF5
+data8 0xBDFEB15801B68349, 0x3E628D35C6A463B9
+data8 0xBE559725ADE45917, 0xBE68C29C042FC476
+data8 0xBE67593B01E511FA, 0xBE4A4313398801ED
+data8 0x3E699571DA7C3300, 0x3E5349BE08062A9E
+data8 0x3E5229C4755BB28E, 0x3E67E42677A1F80D
+data8 0xBE52B33F6B69C352, 0xBE6B3550084DA57F
+data8 0xBE6DB03FD1D09A20, 0xBE60CBC42161B2C1
+data8 0x3E56ED9C78A2B771, 0xBE508E319D0FA795
+data8 0xBE59482AFD1A54E9, 0xBE2A17CEB07FD23E
+data8 0x3E68BF5C17365712, 0x3E3956F9B3785569
+LOCAL_OBJECT_END(Constants_exp_64_W2)
+
+
+LOCAL_OBJECT_START(erfc_xc_table)
+
+data8 0x0000000000000000, 0x00000000 //XC[0] = +0.00000000000000000000e-01L
+data8 0x9A79C70000000000, 0x00003FFD //XC[1] = +3.01710337400436401367e-01L
+data8 0x8C49EF0000000000, 0x00003FFE //XC[2] = +5.48003137111663818359e-01L
+data8 0xD744FC0000000000, 0x00003FFE //XC[3] = +8.40896368026733398438e-01L
+data8 0x9837F00000000000, 0x00003FFF //XC[4] = +1.18920707702636718750e+00L
+data8 0xCD3CE30000000000, 0x00003FFF //XC[5] = +1.60342061519622802734e+00L
+data8 0x8624F70000000000, 0x00004000 //XC[6] = +2.09600615501403808594e+00L
+data8 0xABA27E0000000000, 0x00004000 //XC[7] = +2.68179273605346679688e+00L
+data8 0xD837F00000000000, 0x00004000 //XC[8] = +3.37841415405273437500e+00L
+data8 0x869E710000000000, 0x00004001 //XC[9] = +4.20684099197387695313e+00L
+data8 0xA624F70000000000, 0x00004001 //XC[10] = +5.19201231002807617188e+00L
+data8 0xCBA27E0000000000, 0x00004001 //XC[11] = +6.36358547210693359375e+00L
+data8 0xF837F00000000000, 0x00004001 //XC[12] = +7.75682830810546875000e+00L
+data8 0x969E710000000000, 0x00004002 //XC[13] = +9.41368198394775390625e+00L
+data8 0xB624F70000000000, 0x00004002 //XC[14] = +1.13840246200561523438e+01L
+data8 0xDBA27E0000000000, 0x00004002 //XC[15] = +1.37271709442138671875e+01L
+data8 0x841BF80000000000, 0x00004003 //XC[16] = +1.65136566162109375000e+01L
+data8 0x9E9E710000000000, 0x00004003 //XC[17] = +1.98273639678955078125e+01L
+data8 0xBE24F70000000000, 0x00004003 //XC[18] = +2.37680492401123046875e+01L
+data8 0xE3A27E0000000000, 0x00004003 //XC[19] = +2.84543418884277343750e+01L
+data8 0x881BF80000000000, 0x00004004 //XC[20] = +3.40273132324218750000e+01L
+data8 0xA29E710000000000, 0x00004004 //XC[21] = +4.06547279357910156250e+01L
+data8 0xC224F70000000000, 0x00004004 //XC[22] = +4.85360984802246093750e+01L
+data8 0xE7A27E0000000000, 0x00004004 //XC[23] = +5.79086837768554687500e+01L
+data8 0x8A1BF80000000000, 0x00004005 //XC[24] = +6.90546264648437500000e+01L
+data8 0xA49E710000000000, 0x00004005 //XC[25] = +8.23094558715820312500e+01L
+data8 0xC424F70000000000, 0x00004005 //XC[26] = +9.80721969604492187500e+01L
+data8 0xD5A27E0000000000, 0x00004005 //XC[27] = +1.06817367553710937500e+02L
+LOCAL_OBJECT_END(erfc_xc_table)
+
+LOCAL_OBJECT_START(erfc_s_table)
+
+data8 0xE000000000000000, 0x00003FFE //s[0] = +8.75000000000000000000e-01L
+data8 0xDCEF000000000000, 0x00003FFE //s[1] = +8.63021850585937500000e-01L
+data8 0xD79D000000000000, 0x00003FFE //s[2] = +8.42239379882812500000e-01L
+data8 0xB25E000000000000, 0x00003FFE //s[3] = +6.96746826171875000000e-01L
+data8 0xB0EA000000000000, 0x00003FFE //s[4] = +6.91070556640625000000e-01L
+data8 0xAE3F000000000000, 0x00003FFE //s[5] = +6.80648803710937500000e-01L
+data8 0xAB05000000000000, 0x00003FFE //s[6] = +6.68045043945312500000e-01L
+data8 0xA7AC000000000000, 0x00003FFE //s[7] = +6.54968261718750000000e-01L
+data8 0xA478000000000000, 0x00003FFE //s[8] = +6.42456054687500000000e-01L
+data8 0xA18D000000000000, 0x00003FFE //s[9] = +6.31057739257812500000e-01L
+data8 0x9EF8000000000000, 0x00003FFE //s[10] = +6.20971679687500000000e-01L
+data8 0x9CBA000000000000, 0x00003FFE //s[11] = +6.12213134765625000000e-01L
+data8 0x9ACD000000000000, 0x00003FFE //s[12] = +6.04690551757812500000e-01L
+data8 0x992A000000000000, 0x00003FFE //s[13] = +5.98297119140625000000e-01L
+data8 0x97C7000000000000, 0x00003FFE //s[14] = +5.92880249023437500000e-01L
+data8 0x969C000000000000, 0x00003FFE //s[15] = +5.88317871093750000000e-01L
+data8 0x95A0000000000000, 0x00003FFE //s[16] = +5.84472656250000000000e-01L
+data8 0x94CB000000000000, 0x00003FFE //s[17] = +5.81222534179687500000e-01L
+data8 0x9419000000000000, 0x00003FFE //s[18] = +5.78506469726562500000e-01L
+data8 0x9383000000000000, 0x00003FFE //s[19] = +5.76217651367187500000e-01L
+data8 0x9305000000000000, 0x00003FFE //s[20] = +5.74295043945312500000e-01L
+data8 0x929B000000000000, 0x00003FFE //s[21] = +5.72677612304687500000e-01L
+data8 0x9242000000000000, 0x00003FFE //s[22] = +5.71319580078125000000e-01L
+data8 0x91F8000000000000, 0x00003FFE //s[23] = +5.70190429687500000000e-01L
+data8 0x91B9000000000000, 0x00003FFE //s[24] = +5.69229125976562500000e-01L
+data8 0x9184000000000000, 0x00003FFE //s[25] = +5.68420410156250000000e-01L
+data8 0x9158000000000000, 0x00003FFE //s[26] = +5.67749023437500000000e-01L
+data8 0x9145000000000000, 0x00003FFE //s[27] = +5.67459106445312500000e-01L
+LOCAL_OBJECT_END(erfc_s_table)
+
+LOCAL_OBJECT_START(erfc_Q_table)
+// Q(z)= (P(z)- S)/S
+//
+// Pol0
+data8 0x98325D50F9DC3499, 0x0000BFAA //A0 = +3.07358861423101280650e-26L
+data8 0xED35081A2494DDD9, 0x00003FF8 //A1 = +1.44779757616302832466e-02L
+data8 0x9443549BCD0F94CE, 0x0000BFFD //A2 = -2.89576190966300084405e-01L
+data8 0xC7FD4B98ECF3DBBF, 0x00003FFD //A3 = +3.90604364793467799170e-01L
+data8 0xB82CE31288B49759, 0x0000BFFD //A4 = -3.59717460644199233866e-01L
+data8 0x8A8293447BEF69B5, 0x00003FFD //A5 = +2.70527460203054582368e-01L
+data8 0xB5793E30EE36766C, 0x0000BFFC //A6 = -1.77220317589265674647e-01L
+data8 0xD6066D16BBDECE17, 0x00003FFB //A7 = +1.04504444366724593714e-01L
+data8 0xE7C783CE3C997BD8, 0x0000BFFA //A8 = -5.65867565781331646771e-02L
+data8 0xE9969EBC2F5B2828, 0x00003FF9 //A9 = +2.85142040533900194955e-02L
+data8 0xDD31D619F29AD7BF, 0x0000BFF8 //A10 = -1.35006514390540367929e-02L
+data8 0xC63A20EB59768F3A, 0x00003FF7 //A11 = +6.04940993680332271481e-03L
+data8 0xA8DEC641AACEB600, 0x0000BFF6 //A12 = -2.57675495383156581601e-03L
+data8 0x87F0E77BA914FBEB, 0x00003FF5 //A13 = +1.03714776726541296794e-03L
+data8 0xC306C2894C5CEF2D, 0x0000BFF3 //A14 = -3.71983348634136412407e-04L
+data8 0xBDAB416A989D0697, 0x00003FF1 //A15 = +9.04412111877987292294e-05L
+// Pol1
+data8 0x82808893DA2DD83F, 0x00003FEE //A0 = +7.77853035974467145290e-06L
+data8 0xAE9CD9DCADC86113, 0x0000BFFB //A1 = -8.52601070853077921197e-02L
+data8 0x9D429743E312AD9F, 0x0000BFFB //A2 = -7.67871682732076080494e-02L
+data8 0x8637FC533AE805DC, 0x00003FFC //A3 = +1.31072943286859831330e-01L
+data8 0xF68DBE3639ABCB6E, 0x0000BFFB //A4 = -1.20387540845703264588e-01L
+data8 0xB168FFC3CFA71256, 0x00003FFB //A5 = +8.66260511047190247534e-02L
+data8 0xDBC5078A7EA89236, 0x0000BFFA //A6 = -5.36546988077281230848e-02L
+data8 0xF4331FEDB2CB838F, 0x00003FF9 //A7 = +2.98095344165515989564e-02L
+data8 0xF909173C0E61C25D, 0x0000BFF8 //A8 = -1.51999213123642373375e-02L
+data8 0xEC83560A2ACB23E9, 0x00003FF7 //A9 = +7.21780491979582106904e-03L
+data8 0xD350D62C4FEAD8F5, 0x0000BFF6 //A10 = -3.22442272982896360044e-03L
+data8 0xB2F44F4B3FD9B826, 0x00003FF5 //A11 = +1.36531322425499451283e-03L
+data8 0x9078BC61927671C6, 0x0000BFF4 //A12 = -5.51115510818844954547e-04L
+data8 0xDF67AC6287A63B03, 0x00003FF2 //A13 = +2.13055585989529858265e-04L
+data8 0xA719CFEE67FCE1CE, 0x0000BFF1 //A14 = -7.96798844477905965933e-05L
+data8 0xEF926367BABBB029, 0x00003FEF //A15 = +2.85591875675765038065e-05L
+// Pol2
+data8 0x82B5E5A93B059C50, 0x00003FEF //A0 = +1.55819100856330860049e-05L
+data8 0xDC856BC2542B1938, 0x0000BFFB //A1 = -1.07676355235999875911e-01L
+data8 0xDF225EF5694F14AE, 0x0000BFF8 //A2 = -1.36190345125628043277e-02L
+data8 0xDAF66A954ED22428, 0x00003FFA //A3 = +5.34576571853233908886e-02L
+data8 0xD28AE4F21A392EC6, 0x0000BFFA //A4 = -5.14019911949062230820e-02L
+data8 0x9441A95713F0DB5B, 0x00003FFA //A5 = +3.61954321717769771045e-02L
+data8 0xB0957B5C483C7A04, 0x0000BFF9 //A6 = -2.15556535133667988704e-02L
+data8 0xBB9260E812814F71, 0x00003FF8 //A7 = +1.14484735825400480057e-02L
+data8 0xB68AB17287ABAB04, 0x0000BFF7 //A8 = -5.57073273108465072470e-03L
+data8 0xA56A95E0BC0EF01B, 0x00003FF6 //A9 = +2.52405318381952650677e-03L
+data8 0x8D19C7D286839C00, 0x0000BFF5 //A10 = -1.07651294935087466892e-03L
+data8 0xE45DB3766711A0D3, 0x00003FF3 //A11 = +4.35573615323234291196e-04L
+data8 0xB05949F947FA7AEF, 0x0000BFF2 //A12 = -1.68179306983868501372e-04L
+data8 0x82901D055A0D5CB6, 0x00003FF1 //A13 = +6.22572626227726684168e-05L
+data8 0xBB957698542D6FD0, 0x0000BFEF //A14 = -2.23617364009159182821e-05L
+data8 0x810740E1DF572394, 0x00003FEE //A15 = +7.69068800065192940487e-06L
+// Pol3
+data8 0x9526D1C87655AFA8, 0x00003FEC //A0 = +2.22253260814242012255e-06L
+data8 0xA47E21EBFE73F72F, 0x0000BFF8 //A1 = -1.00398379581527733314e-02L
+data8 0xDE65685FCDF7A913, 0x0000BFFA //A2 = -5.42959286802879105148e-02L
+data8 0xED289CB8F97D4860, 0x00003FFA //A3 = +5.79000589346770417248e-02L
+data8 0xAA3100D5A7D870F1, 0x0000BFFA //A4 = -4.15506394006027604387e-02L
+data8 0xCA0567032C5308C0, 0x00003FF9 //A5 = +2.46607791863290331169e-02L
+data8 0xD3E1794A50F31BEB, 0x0000BFF8 //A6 = -1.29321751094401754013e-02L
+data8 0xCAA02CB4C87CC1F0, 0x00003FF7 //A7 = +6.18364508551740736863e-03L
+data8 0xB3F126AF16B121F2, 0x0000BFF6 //A8 = -2.74569696838501870748e-03L
+data8 0x962B2D64D3900510, 0x00003FF5 //A9 = +1.14569596409019883022e-03L
+data8 0xED8785714A9A00FB, 0x0000BFF3 //A10 = -4.53051338046340380512e-04L
+data8 0xB325DA4515D8B54C, 0x00003FF2 //A11 = +1.70848714622328427290e-04L
+data8 0x8179C36354571747, 0x0000BFF1 //A12 = -6.17387951061077132522e-05L
+data8 0xB40F241C01C907E9, 0x00003FEF //A13 = +2.14647227210702861416e-05L
+data8 0xF436D84AD7D4D316, 0x0000BFED //A14 = -7.27815144835213913238e-06L
+data8 0x9EB432503FB0B7BC, 0x00003FEC //A15 = +2.36487228755136968792e-06L
+// Pol4
+data8 0xE0BA539E4AFC4741, 0x00003FED //A0 = +6.69741148991838024429e-06L
+data8 0x8583BF71139452CF, 0x0000BFFA //A1 = -3.25963476363756051657e-02L
+data8 0x8384FEF6D08AD6CE, 0x0000BFF9 //A2 = -1.60546283500634200479e-02L
+data8 0xB1E67DFB84C97036, 0x00003FF9 //A3 = +2.17163525195697635702e-02L
+data8 0xFB6ACEE6899E360D, 0x0000BFF8 //A4 = -1.53452892792759316229e-02L
+data8 0x8D2B869EB9149905, 0x00003FF8 //A5 = +8.61633440480716870830e-03L
+data8 0x8A90BFE0FD869A41, 0x0000BFF7 //A6 = -4.22868126950622376530e-03L
+data8 0xF7536A76E59F54D2, 0x00003FF5 //A7 = +1.88694643606912107006e-03L
+data8 0xCCF6FE58C16E1CC7, 0x0000BFF4 //A8 = -7.81878732767742447339e-04L
+data8 0x9FCC6ED9914FAA24, 0x00003FF3 //A9 = +3.04791577214885118730e-04L
+data8 0xEC7F5AAACAE593E8, 0x0000BFF1 //A10 = -1.12770784960291779798e-04L
+data8 0xA72CE628A114C940, 0x00003FF0 //A11 = +3.98577182157456408782e-05L
+data8 0xE2DCC5750FD769BA, 0x0000BFEE //A12 = -1.35220520471857266339e-05L
+data8 0x9459160B1E6F1F8D, 0x00003FED //A13 = +4.42111470121432700283e-06L
+data8 0xBE0A05701BD0DD42, 0x0000BFEB //A14 = -1.41590196994052764542e-06L
+data8 0xE905D729105081BF, 0x00003FE9 //A15 = +4.34038814785401120999e-07L
+// Pol5
+data8 0xA33649C3AB459832, 0x00003FEE //A0 = +9.72819704141525206634e-06L
+data8 0x9E4EA2F44C9A24BD, 0x0000BFFA //A1 = -3.86492123987296806210e-02L
+data8 0xE80C0B1280F357BF, 0x0000BFF2 //A2 = -2.21297306012713370124e-04L
+data8 0xDAECCE90A4D45D9A, 0x00003FF7 //A3 = +6.68106161291482829670e-03L
+data8 0xA4006572071BDD4B, 0x0000BFF7 //A4 = -5.00493005170532147076e-03L
+data8 0xB07FD7EB1F4D8E8E, 0x00003FF6 //A5 = +2.69316693731732554959e-03L
+data8 0xA1F471D42ADD73A1, 0x0000BFF5 //A6 = -1.23561753760779610478e-03L
+data8 0x8611D0ED1B4C8176, 0x00003FF4 //A7 = +5.11434914439322741260e-04L
+data8 0xCDADB789B487A541, 0x0000BFF2 //A8 = -1.96150380913036018825e-04L
+data8 0x9470252731687FEE, 0x00003FF1 //A9 = +7.07807859951401721129e-05L
+data8 0xCB9399AD1C376D85, 0x0000BFEF //A10 = -2.42682175234436724152e-05L
+data8 0x858D815F9CA0A9F7, 0x00003FEE //A11 = +7.96036454038012144300e-06L
+data8 0xA878D338E6E6A079, 0x0000BFEC //A12 = -2.51042802626063073967e-06L
+data8 0xCD2C2F079D2FCB36, 0x00003FEA //A13 = +7.64327468786076941271e-07L
+data8 0xF5EF4A4B2EA426F2, 0x0000BFE8 //A14 = -2.29044563492386125272e-07L
+data8 0x8CE52181393820FC, 0x00003FE7 //A15 = +6.56093668622712763489e-08L
+// Pol6
+data8 0xB2015D7F1864B7CF, 0x00003FEC //A0 = +2.65248615880090351276e-06L
+data8 0x954EA7A861B4462A, 0x0000BFFA //A1 = -3.64519642954351295215e-02L
+data8 0x9E46F2A4D9157E69, 0x00003FF7 //A2 = +4.83023498390681965101e-03L
+data8 0xA0D12B422FFD5BAD, 0x00003FF5 //A3 = +1.22693684633643883352e-03L
+data8 0xB291D16A560A740E, 0x0000BFF5 //A4 = -1.36237794246703606647e-03L
+data8 0xC138941BC8AF4A9D, 0x00003FF4 //A5 = +7.37079658343628747256e-04L
+data8 0xA761669D61B405CF, 0x0000BFF3 //A6 = -3.19252914480518163396e-04L
+data8 0x8053680F1C84607E, 0x00003FF2 //A7 = +1.22381025852939439541e-04L
+data8 0xB518F4B6F25015F9, 0x0000BFF0 //A8 = -4.31770048258291369742e-05L
+data8 0xEFF526AC70B9411E, 0x00003FEE //A9 = +1.43025887824433324525e-05L
+data8 0x970B2A848DF5B5C2, 0x0000BFED //A10 = -4.50145058393497252604e-06L
+data8 0xB614D2E61DB86963, 0x00003FEB //A11 = +1.35661172167726780059e-06L
+data8 0xD34EA4D283EC33FA, 0x0000BFE9 //A12 = -3.93590335713880681528e-07L
+data8 0xED209EBD68E1145F, 0x00003FE7 //A13 = +1.10421060667544991323e-07L
+data8 0x83A126E22A17568D, 0x0000BFE6 //A14 = -3.06473811074239684132e-08L
+data8 0x8B778496EDE9F415, 0x00003FE4 //A15 = +8.11804009754249175736e-09L
+// Pol7
+data8 0x8E152F522501B7B9, 0x00003FEE //A0 = +8.46879203970927626532e-06L
+data8 0xFD22F92EE21F491E, 0x0000BFF9 //A1 = -3.09004656656418947425e-02L
+data8 0xAF0C41847D89EC14, 0x00003FF7 //A2 = +5.34203719233189217519e-03L
+data8 0xB7C539C400445956, 0x0000BFF3 //A3 = -3.50514245383356287965e-04L
+data8 0x8428C78B2B1E3622, 0x0000BFF3 //A4 = -2.52073850239006530978e-04L
+data8 0xAFC0CCC7D1A05F5B, 0x00003FF2 //A5 = +1.67611241057491801028e-04L
+data8 0x95DC7272C5695A5A, 0x0000BFF1 //A6 = -7.14593512262564106636e-05L
+data8 0xD6FCA68A61F0E835, 0x00003FEF //A7 = +2.56284375437771117850e-05L
+data8 0x8B71C74DEA936C66, 0x0000BFEE //A8 = -8.31153675277218441096e-06L
+data8 0xA8AC71E2A56AA2C9, 0x00003FEC //A9 = +2.51343269277107451413e-06L
+data8 0xC15DED6C44B46046, 0x0000BFEA //A10 = -7.20347851650066610771e-07L
+data8 0xD42BA1DFBD1277AC, 0x00003FE8 //A11 = +1.97599119274780745741e-07L
+data8 0xE03A81F2C976D11A, 0x0000BFE6 //A12 = -5.22072765405802337371e-08L
+data8 0xE56A19A67DD66100, 0x00003FE4 //A13 = +1.33536787408751203998e-08L
+data8 0xE964D255CB31DFFA, 0x0000BFE2 //A14 = -3.39632729387679010008e-09L
+data8 0xE22E62E932B704D4, 0x00003FE0 //A15 = +8.22842400379225526299e-10L
+// Pol8
+data8 0xB8B835882D46A6C8, 0x00003FEF //A0 = +2.20202883282415435401e-05L
+data8 0xC9D1F63F89B74E90, 0x0000BFF9 //A1 = -2.46362504515706189782e-02L
+data8 0x8E376748B1274F30, 0x00003FF7 //A2 = +4.34010070001387441657e-03L
+data8 0x98174C7EA49B5B37, 0x0000BFF4 //A3 = -5.80181163659971286762e-04L
+data8 0x8D2C40506AE9FF97, 0x00003FEF //A4 = +1.68291159100251734927e-05L
+data8 0xD9A580C115B9D150, 0x00003FEF //A5 = +2.59454841475194555896e-05L
+data8 0xDB35B21F1C3F99CE, 0x0000BFEE //A6 = -1.30659192305072674545e-05L
+data8 0x99FAADAE17A3050E, 0x00003FED //A7 = +4.58893813631592314881e-06L
+data8 0xBA1D259BCD6987A9, 0x0000BFEB //A8 = -1.38665627771423394637e-06L
+data8 0xCDD7FF5BEA0145C2, 0x00003FE9 //A9 = +3.83413844219813384124e-07L
+data8 0xD60857176CE6AB9D, 0x0000BFE7 //A10 = -9.96666862214499946343e-08L
+data8 0xD446A2402112DF4C, 0x00003FE5 //A11 = +2.47121687566658908126e-08L
+data8 0xCA87133235F1F495, 0x0000BFE3 //A12 = -5.89433000014933371980e-09L
+data8 0xBB15B0021581C8B6, 0x00003FE1 //A13 = +1.36122047057936849125e-09L
+data8 0xAC9D6585D4AF505E, 0x0000BFDF //A14 = -3.13984547328132268695e-10L
+data8 0x975A1439C3795183, 0x00003FDD //A15 = +6.88268624429648826457e-11L
+// Pol9
+data8 0x99A7676284CDC9FE, 0x00003FEF //A0 = +1.83169747921764176475e-05L
+data8 0x9AD0AE249A02896C, 0x0000BFF9 //A1 = -1.88983346204739151909e-02L
+data8 0xCB89B4AEC19898BE, 0x00003FF6 //A2 = +3.10574208447745576452e-03L
+data8 0xEBBC47E30E1AC2C2, 0x0000BFF3 //A3 = -4.49629730048297442064e-04L
+data8 0xD1E35B7FCE1CF859, 0x00003FF0 //A4 = +5.00412261289558493438e-05L
+data8 0xB40743664EF24552, 0x0000BFEB //A5 = -1.34131589671166307319e-06L
+data8 0xCAD2F5C596FFE1B4, 0x0000BFEB //A6 = -1.51115702599728593837e-06L
+data8 0xAE42B6D069DFDDF2, 0x00003FEA //A7 = +6.49171330116787223873e-07L
+data8 0xD0739A05BB43A714, 0x0000BFE8 //A8 = -1.94135651872623440782e-07L
+data8 0xD745B854AB601BD7, 0x00003FE6 //A9 = +5.01219983943456578062e-08L
+data8 0xCC4066E13E338B13, 0x0000BFE4 //A10 = -1.18890061172430768892e-08L
+data8 0xB6EAADB55A6C3CB4, 0x00003FE2 //A11 = +2.66178850259168707794e-09L
+data8 0x9CC6C178AD3F96AD, 0x0000BFE0 //A12 = -5.70349182959704086428e-10L
+data8 0x81D0E2AA27DEB74A, 0x00003FDE //A13 = +1.18066926578104076645e-10L
+data8 0xD75FB9049190BEFD, 0x0000BFDB //A14 = -2.44851795398843967972e-11L
+data8 0xA9384A51D48C8703, 0x00003FD9 //A15 = +4.80951837368635202609e-12L
+// Pol10
+data8 0xD2B3482EE449C535, 0x00003FEE //A0 = +1.25587177382575655080e-05L
+data8 0xE7939B2D0607DFCF, 0x0000BFF8 //A1 = -1.41343131436717436429e-02L
+data8 0x8810EB4AC5F0F1CE, 0x00003FF6 //A2 = +2.07620377002350121270e-03L
+data8 0x9546589602AEB955, 0x0000BFF3 //A3 = -2.84719065122144294949e-04L
+data8 0x9333434342229798, 0x00003FF0 //A4 = +3.50952732796136549298e-05L
+data8 0xEB36A98FD81D3DEB, 0x0000BFEC //A5 = -3.50495464815398722482e-06L
+data8 0xAC370EFA025D0477, 0x00003FE8 //A6 = +1.60387784498518639254e-07L
+data8 0xC8DF7F8ACA099426, 0x00003FE6 //A7 = +4.67693991699936842330e-08L
+data8 0xAC694AD4921C02CF, 0x0000BFE5 //A8 = -2.00713167514877937714e-08L
+data8 0xB6E29F2FDE2D8C1A, 0x00003FE3 //A9 = +5.32266106167252495164e-09L
+data8 0xA41F8EEA75474358, 0x0000BFE1 //A10 = -1.19415398856537468324e-09L
+data8 0x869D778A1C56D3D6, 0x00003FDF //A11 = +2.44863450057778470469e-10L
+data8 0xD02658BF31411F4C, 0x0000BFDC //A12 = -4.73277831746128372261e-11L
+data8 0x9A4A95EE59127779, 0x00003FDA //A13 = +8.77044784978207256260e-12L
+data8 0xE518330AF013C2F6, 0x0000BFD7 //A14 = -1.62781453276882333209e-12L
+data8 0xA036A9DF71BD108A, 0x00003FD5 //A15 = +2.84596398987114375607e-13L
+// Pol11
+data8 0x9191CFBF001F3BB3, 0x00003FEE //A0 = +8.67662287973472452343e-06L
+data8 0xAA47E0CF01AE9730, 0x0000BFF8 //A1 = -1.03931136509584404513e-02L
+data8 0xAEABE7F17B01D18F, 0x00003FF5 //A2 = +1.33263784731775399430e-03L
+data8 0xAC0D6A309D04E5DB, 0x0000BFF2 //A3 = -1.64081956462118568288e-04L
+data8 0xA08357DF458054D0, 0x00003FEF //A4 = +1.91346477952797715021e-05L
+data8 0x8A1596B557440FE0, 0x0000BFEC //A5 = -2.05761687274453412571e-06L
+data8 0xCDA0EAE0A5615E9A, 0x00003FE8 //A6 = +1.91506542215670149741e-07L
+data8 0xD36A08FB4E104F9A, 0x0000BFE4 //A7 = -1.23059260396551086769e-08L
+data8 0xD7433F91E78A7A11, 0x0000BFDF //A8 = -3.91560549815575091188e-10L
+data8 0xC2F5308FD4F5CE62, 0x00003FDF //A9 = +3.54626121852421163117e-10L
+data8 0xC83876915F49D630, 0x0000BFDD //A10 = -9.10497688901018285126e-11L
+data8 0xA11C605DEAE1FE9C, 0x00003FDB //A11 = +1.83161825409194847892e-11L
+data8 0xE7977BC1342D19BF, 0x0000BFD8 //A12 = -3.29111645807102123274e-12L
+data8 0x9BC3A7D6396C6756, 0x00003FD6 //A13 = +5.53385887288503961220e-13L
+data8 0xD0110D5683740B8C, 0x0000BFD3 //A14 = -9.24001363293241428519e-14L
+data8 0x81786D7856A5CC92, 0x00003FD1 //A15 = +1.43741041714595023996e-14L
+// Pol12
+data8 0xB85654F6033B3372, 0x00003FEF //A0 = +2.19747106911869287049e-05L
+data8 0xF78B40078736B406, 0x0000BFF7 //A1 = -7.55444170413862312647e-03L
+data8 0xDA8FDE84D88E5D5D, 0x00003FF4 //A2 = +8.33747822263358628569e-04L
+data8 0xBC2D3F3891721AA9, 0x0000BFF1 //A3 = -8.97296647669960333635e-05L
+data8 0x9D15ACFD3BF50064, 0x00003FEE //A4 = +9.36297600601039610762e-06L
+data8 0xFBED3D03F3C1B671, 0x0000BFEA //A5 = -9.38500137149172923985e-07L
+data8 0xBEE615E3B2FA16C8, 0x00003FE7 //A6 = +8.88941676851808958175e-08L
+data8 0x843D32692CF5662A, 0x0000BFE4 //A7 = -7.69732580860195238520e-09L
+data8 0x99E74472FD94E22B, 0x00003FE0 //A8 = +5.59897264617128952416e-10L
+data8 0xCEF63DABF4C32E15, 0x0000BFDB //A9 = -2.35288414996279313219e-11L
+data8 0xA2D86C25C0991123, 0x0000BFD8 //A10 = -2.31417232327307408235e-12L
+data8 0xF50C1B31D2E922BD, 0x00003FD6 //A11 = +8.70582858983364191159e-13L
+data8 0xC0F093DEC2B019A1, 0x0000BFD4 //A12 = -1.71364927865227509533e-13L
+data8 0xFC1441C4CD105981, 0x00003FD1 //A13 = +2.79864052545369490865e-14L
+data8 0x9CC959853267F026, 0x0000BFCF //A14 = -4.35170017302700609509e-15L
+data8 0xB06BA14016154F1E, 0x00003FCC //A15 = +6.12081320471295704631e-16L
+// Pol13
+data8 0xA59E74BF544F2422, 0x00003FEF //A0 = +1.97433196215210145261e-05L
+data8 0xB2814F4EDAE15330, 0x0000BFF7 //A1 = -5.44754383528015875700e-03L
+data8 0x867C249D378F0A23, 0x00003FF4 //A2 = +5.13019308804593120161e-04L
+data8 0xC76644393388AB68, 0x0000BFF0 //A3 = -4.75405403392600215101e-05L
+data8 0x91143AD5CCA229FE, 0x00003FED //A4 = +4.32369180778264703719e-06L
+data8 0xCE6A11FB6840A974, 0x0000BFE9 //A5 = -3.84476663329551178495e-07L
+data8 0x8EC29F66C59DE243, 0x00003FE6 //A6 = +3.32389596787155456596e-08L
+data8 0xBE3FCDDCA94CA24E, 0x0000BFE2 //A7 = -2.76849073931513325199e-09L
+data8 0xF06A84BDC70A0B0D, 0x00003FDE //A8 = +2.18657158231304988330e-10L
+data8 0x8B8E6969D056D124, 0x0000BFDB //A9 = -1.58657139740906811035e-11L
+data8 0x8984985AA29A0567, 0x00003FD7 //A10 = +9.77123802231106533829e-13L
+data8 0xA53ABA084300137C, 0x0000BFD2 //A11 = -3.66882970952892030306e-14L
+data8 0xA90EC851E91C3319, 0x0000BFCE //A12 = -2.34614750044359490986e-15L
+data8 0xEC9CAF64237B5060, 0x00003FCC //A13 = +8.20912960028437475035e-16L
+data8 0xA9156668FCF01479, 0x0000BFCA //A14 = -1.46656639874123613261e-16L
+data8 0xBAEF58D8118DD5D4, 0x00003FC7 //A15 = +2.02675278255254907493e-17L
+// Pol14
+data8 0xC698952E9CEAA800, 0x00003FEF //A0 = +2.36744912073515619263e-05L
+data8 0x800395F8C7B4FA00, 0x0000BFF7 //A1 = -3.90667746392883642897e-03L
+data8 0xA3B2467B6B391831, 0x00003FF3 //A2 = +3.12226081793919541155e-04L
+data8 0xCF2061122A69D72B, 0x0000BFEF //A3 = -2.46914006692526122176e-05L
+data8 0x817FAB6B5DEB9924, 0x00003FEC //A4 = +1.92968114320180123521e-06L
+data8 0x9FC190F5827740E7, 0x0000BFE8 //A5 = -1.48784479265231093475e-07L
+data8 0xC1FE5C1835C8AFCD, 0x00003FE4 //A6 = +1.12919132662720380018e-08L
+data8 0xE7216A9FBB204DA3, 0x0000BFE0 //A7 = -8.40847981461949000003e-10L
+data8 0x867566ED95C5C64F, 0x00003FDD //A8 = +6.11446929759298780795e-11L
+data8 0x97A8BFA723F0F014, 0x0000BFD9 //A9 = -4.31041298699752869577e-12L
+data8 0xA3D24B7034984522, 0x00003FD5 //A10 = +2.91005377301348717042e-13L
+data8 0xA5AAA371C22F3741, 0x0000BFD1 //A11 = -1.83926825395757259128e-14L
+data8 0x95352E5597EACC23, 0x00003FCD //A12 = +1.03533666540077850452e-15L
+data8 0xCCEBE3043B689428, 0x0000BFC8 //A13 = -4.44352525147076912166e-17L
+data8 0xA779DAB4BE1F80BB, 0x0000BFBC //A14 = -8.86610526981738255206e-21L
+data8 0xB171271F3517282C, 0x00003FC1 //A15 = +3.00598445879282370850e-19L
+// Pol15
+data8 0xB7AC727D1C3FEB05, 0x00003FEE //A0 = +1.09478009914822049780e-05L
+data8 0xB6E6274485C10B0A, 0x0000BFF6 //A1 = -2.79081782038927199588e-03L
+data8 0xC5CAE2122D009506, 0x00003FF2 //A2 = +1.88629638738336219173e-04L
+data8 0xD466E7957D0A3362, 0x0000BFEE //A3 = -1.26601440424012313479e-05L
+data8 0xE2593D798DA20E2E, 0x00003FEA //A4 = +8.43214222346512003230e-07L
+data8 0xEF2D2BBA7D2882CC, 0x0000BFE6 //A5 = -5.56876064495961858535e-08L
+data8 0xFA5819BB4AE974C2, 0x00003FE2 //A6 = +3.64298674151704370449e-09L
+data8 0x819BB0CE825FBB28, 0x0000BFDF //A7 = -2.35755881668932259913e-10L
+data8 0x84871099BF728B8F, 0x00003FDB //A8 = +1.50666434199945890414e-11L
+data8 0x858188962DFEBC9F, 0x0000BFD7 //A9 = -9.48617116568458677088e-13L
+data8 0x840F38FF2FBAE753, 0x00003FD3 //A10 = +5.86461827778372616657e-14L
+data8 0xFF47EAF69577B213, 0x0000BFCE //A11 = -3.54273456410181081472e-15L
+data8 0xEF402CCB4D29FAF8, 0x00003FCA //A12 = +2.07516888659313950588e-16L
+data8 0xD6B789E01141231B, 0x0000BFC6 //A13 = -1.16398290506765191078e-17L
+data8 0xB5EEE343E9CFE3EC, 0x00003FC2 //A14 = +6.16413506924643419723e-19L
+data8 0x859B41A39D600346, 0x0000BFBE //A15 = -2.82922705825870414438e-20L
+// Pol16
+data8 0x85708B69FD184E11, 0x00003FED //A0 = +3.97681079176353356199e-06L
+data8 0x824D92BC60A1F70A, 0x0000BFF6 //A1 = -1.98826630037499070532e-03L
+data8 0xEDCF7D3576BB5258, 0x00003FF1 //A2 = +1.13396885054265675352e-04L
+data8 0xD7FC59226A947CDF, 0x0000BFED //A3 = -6.43687650810478871875e-06L
+data8 0xC32C51B574E2651E, 0x00003FE9 //A4 = +3.63538268539251809118e-07L
+data8 0xAF67910F5681401F, 0x0000BFE5 //A5 = -2.04197779750247395258e-08L
+data8 0x9CB3E8D7DCD1EA9D, 0x00003FE1 //A6 = +1.14016272459029850306e-09L
+data8 0x8B14ECFBF7D4F114, 0x0000BFDD //A7 = -6.32470533185766848692e-11L
+data8 0xF518253AE4A3AE72, 0x00003FD8 //A8 = +3.48299974583453268369e-12L
+data8 0xD631A5699AA2F334, 0x0000BFD4 //A9 = -1.90242426474085078079e-13L
+data8 0xB971AD4C30C56E5D, 0x00003FD0 //A10 = +1.02942127356740047925e-14L
+data8 0x9ED0065A601F3160, 0x0000BFCC //A11 = -5.50991880383698965959e-16L
+data8 0x863A04008E12867C, 0x00003FC8 //A12 = +2.91057593756148904838e-17L
+data8 0xDF62F9F44F5C7170, 0x0000BFC3 //A13 = -1.51372666097522872780e-18L
+data8 0xBA4E118E88CFDD31, 0x00003FBF //A14 = +7.89032177282079635722e-20L
+data8 0x942AD897FC4D2F2A, 0x0000BFBB //A15 = -3.92195756076319409245e-21L
+// Pol17
+data8 0xCB8514540566C717, 0x00003FEF //A0 = +2.42614557068144130848e-05L
+data8 0xB94F08D6816E0CD4, 0x0000BFF5 //A1 = -1.41379340061829929314e-03L
+data8 0x8E7C342C2DABB51B, 0x00003FF1 //A2 = +6.79422240687700109911e-05L
+data8 0xDA69DAFF71E30D5B, 0x0000BFEC //A3 = -3.25461473899657142468e-06L
+data8 0xA6D5B2DB69B4B3F6, 0x00003FE8 //A4 = +1.55376978584082701045e-07L
+data8 0xFDF4F76BC1D1BD47, 0x0000BFE3 //A5 = -7.39111857092131684572e-09L
+data8 0xC08BC52C95B12C2D, 0x00003FDF //A6 = +3.50239092565793882444e-10L
+data8 0x91624BF6D3A3F6C9, 0x0000BFDB //A7 = -1.65282439890232458821e-11L
+data8 0xDA91F7A450DE4270, 0x00003FD6 //A8 = +7.76517285902715940501e-13L
+data8 0xA380ADF55416E624, 0x0000BFD2 //A9 = -3.63048822989374426852e-14L
+data8 0xF350FC0CEDEE0FD6, 0x00003FCD //A10 = +1.68834630987974622269e-15L
+data8 0xB3FA19FBDC8F023C, 0x0000BFC9 //A11 = -7.80525639701804380489e-17L
+data8 0x8435328C80940126, 0x00003FC5 //A12 = +3.58349966898667910204e-18L
+data8 0xC0D22F655BA5EF39, 0x0000BFC0 //A13 = -1.63325770165403860181e-19L
+data8 0x8F14B9EBD5A9AB25, 0x00003FBC //A14 = +7.57464305512080733773e-21L
+data8 0xCD4804BBF6DC1B6F, 0x0000BFB7 //A15 = -3.39609459750208886298e-22L
+// Pol18
+data8 0xE251DFE45AB0C22E, 0x00003FEE //A0 = +1.34897126299700418200e-05L
+data8 0x83943CC7D59D4215, 0x0000BFF5 //A1 = -1.00386850310061655307e-03L
+data8 0xAA57896951134BCA, 0x00003FF0 //A2 = +4.06126834109940757047e-05L
+data8 0xDC0A67051E1C4A2C, 0x0000BFEB //A3 = -1.63943048164477430317e-06L
+data8 0x8DCB3C0A8CD07BBE, 0x00003FE7 //A4 = +6.60279229777753829876e-08L
+data8 0xB64DE81C24F7F265, 0x0000BFE2 //A5 = -2.65287705357477481067e-09L
+data8 0xE9CBB7A990DBA8B5, 0x00003FDD //A6 = +1.06318007608620426224e-10L
+data8 0x9583D4B85C2ADC6F, 0x0000BFD9 //A7 = -4.24947087941505088222e-12L
+data8 0xBEB0EE8114EEDF77, 0x00003FD4 //A8 = +1.69367754741562774916e-13L
+data8 0xF2791BB8F06BDA93, 0x0000BFCF //A9 = -6.72997988617021128704e-15L
+data8 0x99A907F6A92195B4, 0x00003FCB //A10 = +2.66558091161711891239e-16L
+data8 0xC213E5E6F833BB93, 0x0000BFC6 //A11 = -1.05209746502719578617e-17L
+data8 0xF41FBBA6B343960F, 0x00003FC1 //A12 = +4.13562069721140021224e-19L
+data8 0x98F194AEE31D188D, 0x0000BFBD //A13 = -1.61935414722333263347e-20L
+data8 0xC42F5029BB622157, 0x00003FB8 //A14 = +6.49121108201931196678e-22L
+data8 0xF43BD08079E50E0F, 0x0000BFB3 //A15 = -2.52531675510242468317e-23L
+// Pol19
+data8 0x82557B149A04D08E, 0x00003FEF //A0 = +1.55370127331027842820e-05L
+data8 0xBAAB433307CE614B, 0x0000BFF4 //A1 = -7.12085701486669872724e-04L
+data8 0xCB52D9DBAC16FE82, 0x00003FEF //A2 = +2.42380662859334411743e-05L
+data8 0xDD214359DBBCE7D1, 0x0000BFEA //A3 = -8.23773197624244883859e-07L
+data8 0xF01E8E968139524C, 0x00003FE5 //A4 = +2.79535729459988509676e-08L
+data8 0x82286A057E0916CE, 0x0000BFE1 //A5 = -9.47023128967039348510e-10L
+data8 0x8CDDDC4E8D013365, 0x00003FDC //A6 = +3.20293663356974901319e-11L
+data8 0x982FEEE90D4E8751, 0x0000BFD7 //A7 = -1.08135537312234452657e-12L
+data8 0xA41D1E84083B8FD6, 0x00003FD2 //A8 = +3.64405720894915411836e-14L
+data8 0xB0A1B6111B72E159, 0x0000BFCD //A9 = -1.22562851790685744085e-15L
+data8 0xBDB77DE6B650FFA2, 0x00003FC8 //A10 = +4.11382657214908334175e-17L
+data8 0xCB54E95CDB66978A, 0x0000BFC3 //A11 = -1.37782909696752432371e-18L
+data8 0xD959E428A62B1B6C, 0x00003FBE //A12 = +4.60258936838597812582e-20L
+data8 0xE7D49EC23F1A16A0, 0x0000BFB9 //A13 = -1.53412587409583783059e-21L
+data8 0xFDE429BC9947B2BE, 0x00003FB4 //A14 = +5.25034823750902928092e-23L
+data8 0x872137A062C042EF, 0x0000BFB0 //A15 = -1.74651114923000080365e-24L
+// Pol20
+data8 0x8B9B185C6A2659AC, 0x00003FEF //A0 = +1.66423130594825442963e-05L
+data8 0x84503AD52588A1E8, 0x0000BFF4 //A1 = -5.04735556466270303549e-04L
+data8 0xF26C7C2B566388E1, 0x00003FEE //A2 = +1.44495826764677427386e-05L
+data8 0xDDDA15FEE262BB47, 0x0000BFE9 //A3 = -4.13231361893675488873e-07L
+data8 0xCACEBC73C90C2FE0, 0x00003FE4 //A4 = +1.18049538609157282958e-08L
+data8 0xB9314D00022B41DD, 0x0000BFDF //A5 = -3.36863342776746896664e-10L
+data8 0xA8E9FBDC714638B9, 0x00003FDA //A6 = +9.60164921624768038366e-12L
+data8 0x99E246C0CC8CA6F6, 0x0000BFD5 //A7 = -2.73352704217713596798e-13L
+data8 0x8C04E7B5DF372EA1, 0x00003FD0 //A8 = +7.77262480048865685174e-15L
+data8 0xFE7B90CAA0B6D5F7, 0x0000BFCA //A9 = -2.20728537958846147109e-16L
+data8 0xE6F40BAD4EC6CB4F, 0x00003FC5 //A10 = +6.26000182616999972048e-18L
+data8 0xD14F4E0538F0F992, 0x0000BFC0 //A11 = -1.77292283439752259258e-19L
+data8 0xBD5A7FAA548CC749, 0x00003FBB //A12 = +5.01214569023722089225e-21L
+data8 0xAB15D69425373A67, 0x0000BFB6 //A13 = -1.41518447770061562822e-22L
+data8 0x9EF95456F75B4DF4, 0x00003FB1 //A14 = +4.10938011540250142351e-24L
+data8 0x8FADCC45E81433E7, 0x0000BFAC //A15 = -1.16062889679749879834e-25L
+// Pol21
+data8 0xB47A917B0F7B50AE, 0x00003FEF //A0 = +2.15147474240529518138e-05L
+data8 0xBB77DC3BA0C937B3, 0x0000BFF3 //A1 = -3.57567223048598672970e-04L
+data8 0x90694DFF4EBF7370, 0x00003FEE //A2 = +8.60758700336677694536e-06L
+data8 0xDE5379AA90A98F3F, 0x0000BFE8 //A3 = -2.07057292787309736495e-07L
+data8 0xAB0322293F1F9CA0, 0x00003FE3 //A4 = +4.97711123919916694625e-09L
+data8 0x837119E59D3B7AC2, 0x0000BFDE //A5 = -1.19545621970063369582e-10L
+data8 0xC9E5B74A38ECF3FC, 0x00003FD8 //A6 = +2.86913359605586285967e-12L
+data8 0x9AEF5110C6885352, 0x0000BFD3 //A7 = -6.88048865490621757799e-14L
+data8 0xED988D52189CE6A3, 0x00003FCD //A8 = +1.64865278639132278935e-15L
+data8 0xB6063CECD8012B6D, 0x0000BFC8 //A9 = -3.94702428606368525374e-17L
+data8 0x8B541EB15E79CEEC, 0x00003FC3 //A10 = +9.44127272399408815784e-19L
+data8 0xD51A136D8C75BC25, 0x0000BFBD //A11 = -2.25630369561137931232e-20L
+data8 0xA2C1C5E19CC79E6F, 0x00003FB8 //A12 = +5.38517493921589837361e-22L
+data8 0xF86F9772306F56C1, 0x0000BFB2 //A13 = -1.28438352359240135735e-23L
+data8 0xC32F6FEEDE86528E, 0x00003FAD //A14 = +3.15338862172962186458e-25L
+data8 0x9534ED189744D7D4, 0x0000BFA8 //A15 = -7.53301543611470014315e-27L
+// Pol22
+data8 0xCBA0A2DB94A2C494, 0x00003FEF //A0 = +2.42742878212752702946e-05L
+data8 0x84C089154A49E0E8, 0x0000BFF3 //A1 = -2.53204520651046300034e-04L
+data8 0xABF5665BD0D8B0CD, 0x00003FED //A2 = +5.12476542947092361490e-06L
+data8 0xDEA1C518E3EEE872, 0x0000BFE7 //A3 = -1.03671063536324831083e-07L
+data8 0x900B77F271559AE8, 0x00003FE2 //A4 = +2.09612770408581408652e-09L
+data8 0xBA4C74A262BE3E4E, 0x0000BFDC //A5 = -4.23594098489216166935e-11L
+data8 0xF0D1680FCC1EAF97, 0x00003FD6 //A6 = +8.55557381760467917779e-13L
+data8 0x9B8F8E033BB83A24, 0x0000BFD1 //A7 = -1.72707138247091685914e-14L
+data8 0xC8DCA6A691DB8335, 0x00003FCB //A8 = +3.48439884388851942939e-16L
+data8 0x819A6CB9CEA5E9BD, 0x0000BFC6 //A9 = -7.02580471688245511753e-18L
+data8 0xA726B4F622585BEA, 0x00003FC0 //A10 = +1.41582572516648501043e-19L
+data8 0xD7727648A4095986, 0x0000BFBA //A11 = -2.85141885626054217632e-21L
+data8 0x8AB627E09CF45997, 0x00003FB5 //A12 = +5.73697507862703019314e-23L
+data8 0xB28C15C117CC604F, 0x0000BFAF //A13 = -1.15383428132352407085e-24L
+data8 0xECB8428626DA072C, 0x00003FA9 //A14 = +2.39025879246942839796e-26L
+data8 0x98B731BCFA2CE2B2, 0x0000BFA4 //A15 = -4.81885474332093262902e-28L
+// Pol23
+data8 0xC6D013811314D31B, 0x00003FED //A0 = +5.92508308918577687876e-06L
+data8 0xBBF3057B8DBACBCF, 0x0000BFF2 //A1 = -1.79242422493281965934e-04L
+data8 0xCCADECA501162313, 0x00003FEC //A2 = +3.04996061562356504918e-06L
+data8 0xDED1FDBE8CCAF3DB, 0x0000BFE6 //A3 = -5.18793887648024117154e-08L
+data8 0xF27B74EDDCA65859, 0x00003FE0 //A4 = +8.82145297317787820675e-10L
+data8 0x83E4415687F01A0C, 0x0000BFDB //A5 = -1.49943414247603665601e-11L
+data8 0x8F6CB350861CE446, 0x00003FD5 //A6 = +2.54773288906376920377e-13L
+data8 0x9BE8456A30CBFC02, 0x0000BFCF //A7 = -4.32729710913845745148e-15L
+data8 0xA9694F7E1033977D, 0x00003FC9 //A8 = +7.34704698157502347441e-17L
+data8 0xB8035A3D5AF82D85, 0x0000BFC3 //A9 = -1.24692123826025468001e-18L
+data8 0xC7CB4B3ACB905FDA, 0x00003FBD //A10 = +2.11540249352095943317e-20L
+data8 0xD8D70AEB2E58D729, 0x0000BFB7 //A11 = -3.58731705184186608576e-22L
+data8 0xEB27A61B1D5C7697, 0x00003FB1 //A12 = +6.07861113430709162243e-24L
+data8 0xFEF9ED74D4F4C9B0, 0x0000BFAB //A13 = -1.02984099170876754831e-25L
+data8 0x8E6F410068C12043, 0x00003FA6 //A14 = +1.79777721804459361762e-27L
+data8 0x9AE2F6705481630E, 0x0000BFA0 //A15 = -3.05459905177379058768e-29L
+// Pol24
+data8 0xD2D858D5B01C9434, 0x00003FEE //A0 = +1.25673476165670766128e-05L
+data8 0x8505330F8B4FDE49, 0x0000BFF2 //A1 = -1.26858053564784963985e-04L
+data8 0xF39171C8B1D418C2, 0x00003FEB //A2 = +1.81472407620770441249e-06L
+data8 0xDEF065C3D7BFD26E, 0x0000BFE5 //A3 = -2.59535215807652675043e-08L
+data8 0xCC0199EA6ACA630C, 0x00003FDF //A4 = +3.71085215769339916703e-10L
+data8 0xBAA25319F01ED248, 0x0000BFD9 //A5 = -5.30445960650683029105e-12L
+data8 0xAAB28A84F8CFE4D1, 0x00003FD3 //A6 = +7.58048850973457592162e-14L
+data8 0x9C14B931AEB311A8, 0x0000BFCD //A7 = -1.08302915828084288776e-15L
+data8 0x8EADA745715A0714, 0x00003FC7 //A8 = +1.54692159263197000533e-17L
+data8 0x82643F3F722CE6B5, 0x0000BFC1 //A9 = -2.20891945694400066611e-19L
+data8 0xEE42ECDE465A99E4, 0x00003FBA //A10 = +3.15336372779307614198e-21L
+data8 0xD99FC74326ACBFC0, 0x0000BFB4 //A11 = -4.50036161691276556269e-23L
+data8 0xC6A4DCACC554911E, 0x00003FAE //A12 = +6.41853356148678957077e-25L
+data8 0xB550CEA09DA96F44, 0x0000BFA8 //A13 = -9.15410112414783078242e-27L
+data8 0xAA9149317996F32F, 0x00003FA2 //A14 = +1.34554050666508391264e-28L
+data8 0x9C3008EFE3F52F19, 0x0000BF9C //A15 = -1.92516125328592532359e-30L
+// Pol25
+data8 0xA68E78218806283F, 0x00003FEF //A0 = +1.98550844852103406280e-05L
+data8 0xBC41423996DC8A37, 0x0000BFF1 //A1 = -8.97669395268764751516e-05L
+data8 0x90E55AE31A2F8271, 0x00003FEB //A2 = +1.07955871580069359702e-06L
+data8 0xDF022272DA4A3BEF, 0x0000BFE4 //A3 = -1.29807937275957214439e-08L
+data8 0xAB95DCBFFB0BAAB8, 0x00003FDE //A4 = +1.56056011861921437794e-10L
+data8 0x83FF2547BA9011FF, 0x0000BFD8 //A5 = -1.87578539510813332135e-12L
+data8 0xCB0C353560EEDC45, 0x00003FD1 //A6 = +2.25428217090412574481e-14L
+data8 0x9C24CEB86E76D2C5, 0x0000BFCB //A7 = -2.70866279585559299821e-16L
+data8 0xF01AFA23DDFDAE0E, 0x00003FC4 //A8 = +3.25403467375734083376e-18L
+data8 0xB892BDFBCF1D9740, 0x0000BFBE //A9 = -3.90848978133441513662e-20L
+data8 0x8DDBBF34415AAECA, 0x00003FB8 //A10 = +4.69370027479731756829e-22L
+data8 0xDA04170D07458C3B, 0x0000BFB1 //A11 = -5.63558091177482043435e-24L
+data8 0xA76F391095A9563A, 0x00003FAB //A12 = +6.76262416498584003290e-26L
+data8 0x8098FA125C18D8DB, 0x0000BFA5 //A13 = -8.11564737276592661642e-28L
+data8 0xCB9E4D5C08923227, 0x00003F9E //A14 = +1.00391606269366059664e-29L
+data8 0x9CEC3BF7A0BE2CAF, 0x0000BF98 //A15 = -1.20888920108938909316e-31L
+// Pol26
+data8 0xC17AB25E269272F7, 0x00003FEE //A0 = +1.15322640047234590651e-05L
+data8 0x85310509E633FEF2, 0x0000BFF1 //A1 = -6.35106483144690768696e-05L
+data8 0xAC5E4C4DCB2D940C, 0x00003FEA //A2 = +6.42122148740412561597e-07L
+data8 0xDF0AAD0571FFDD48, 0x0000BFE3 //A3 = -6.49136789710824396482e-09L
+data8 0x9049D8440AFD180F, 0x00003FDD //A4 = +6.56147932223174570008e-11L
+data8 0xBAA936477C5FA9D7, 0x0000BFD6 //A5 = -6.63153032879993841863e-13L
+data8 0xF17261294EAB1443, 0x00003FCF //A6 = +6.70149477756803680009e-15L
+data8 0x9C22F87C31DB007A, 0x0000BFC9 //A7 = -6.77134581402030645534e-17L
+data8 0xC9E98E633942AC12, 0x00003FC2 //A8 = +6.84105580182052870823e-19L
+data8 0x828998181309642C, 0x0000BFBC //A9 = -6.91059649300859944955e-21L
+data8 0xA8C3D4DCE1ECBAB6, 0x00003FB5 //A10 = +6.97995542988331257517e-23L
+data8 0xDA288D52CC4C351A, 0x0000BFAE //A11 = -7.04907829139578377009e-25L
+data8 0x8CEEACB790B5F374, 0x00003FA8 //A12 = +7.11526399101774993883e-27L
+data8 0xB61C8A29D98F24C0, 0x0000BFA1 //A13 = -7.18303147470398859453e-29L
+data8 0xF296F69FE45BDA7D, 0x00003F9A //A14 = +7.47537230021540031251e-31L
+data8 0x9D4B25BF6FB7234B, 0x0000BF94 //A15 = -7.57340869663212138051e-33L
+// Pol27
+data8 0xC7772CC326D6FBB8, 0x00003FEE //A0 = +1.18890718679826004395e-05L
+data8 0xE0F9D5410565D55D, 0x0000BFF0 //A1 = -5.36384368533203585378e-05L
+data8 0x85C0BE825680E148, 0x00003FEA //A2 = +4.98268406609692971520e-07L
+data8 0x9F058A389D7BA177, 0x0000BFE3 //A3 = -4.62813885933188677790e-09L
+data8 0xBD0B751F0A6BAC7A, 0x00003FDC //A4 = +4.29838009673609430305e-11L
+data8 0xE0B6823570502E9D, 0x0000BFD5 //A5 = -3.99170340031272728535e-13L
+data8 0x858A9C52FC426D86, 0x00003FCF //A6 = +3.70651975271664045723e-15L
+data8 0x9EB4438BFDF1928D, 0x0000BFC8 //A7 = -3.44134780748056488222e-17L
+data8 0xBC968DCD8C06D74E, 0x00003FC1 //A8 = +3.19480670422195579127e-19L
+data8 0xE0133A405F782125, 0x0000BFBA //A9 = -2.96560935615546392028e-21L
+data8 0x851AFEBB70D07E79, 0x00003FB4 //A10 = +2.75255617931932536111e-23L
+data8 0x9E1E21A841BF8738, 0x0000BFAD //A11 = -2.55452923487640676799e-25L
+data8 0xBBCF2EF1C6E72327, 0x00003FA6 //A12 = +2.37048675755308004410e-27L
+data8 0xDF0D320CF12B8BCB, 0x0000BF9F //A13 = -2.19945804585962185550e-29L
+data8 0x8470A76DE5FCADD8, 0x00003F99 //A14 = +2.04056213851532266258e-31L
+data8 0x9D41C15F6A6FBB04, 0x0000BF92 //A15 = -1.89291056020108587823e-33L
+LOCAL_OBJECT_END(erfc_Q_table)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(erfcl)
+
+{ .mfi
+ alloc r32 = ar.pfs, 0, 36, 4, 0
+ fma.s1 FR_Tmp = f1, f1, f8 // |x|+1, if x >= 0
+ nop.i 0
+}
+{ .mfi
+ addl GR_ad_Arg = @ltoff(exp_table_1), gp
+ fms.s1 FR_Tmp1 = f1, f1, f8 // |x|+1, if x < 0
+ mov GR_rshf_2to51 = 0x4718 // begin 1.10000 2^(63+51)
+}
+;;
+
+{ .mfi
+ ld8 GR_ad_Arg = [GR_ad_Arg] // Point to Arg table
+ fcmp.ge.s1 p6,p7 = f8, f0 // p6: x >= 0 ,p7: x<0
+ shl GR_rshf_2to51 = GR_rshf_2to51,48 // end 1.10000 2^(63+51)
+}
+{ .mlx
+ mov GR_rshf = 0x43e8 // begin 1.1000 2^63 for right shift
+ movl GR_sig_inv_ln2 = 0xb8aa3b295c17f0bc // signif. of 1/ln2
+}
+;;
+
+{ .mfi
+ mov GR_exp_2tom51 = 0xffff-51
+ fclass.m p8,p0 = f8,0x07 // p8: x = 0
+ shl GR_rshf = GR_rshf,48 // end 1.1000 2^63 for right shift
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_norm_x = f8, f8, f0 //high bits for -x^2
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ setf.sig FR_INV_LN2_2TO63 = GR_sig_inv_ln2 // form 1/ln2 * 2^63
+(p6) fma.s1 FR_AbsArg = f1, f0, f8 // |x|, if x >= 0
+ nop.i 0
+}
+{ .mfi
+ setf.d FR_RSHF_2TO51 = GR_rshf_2to51 //const 1.10 * 2^(63+51)
+(p7) fms.s1 FR_AbsArg = f1, f0, f8 // |x|, if x < 0
+ mov GR_exp_mask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ ldfe FR_ch_dx = [GR_ad_Arg], 16
+ fclass.m p10,p0 = f8, 0x21 // p10: x = +inf
+ mov GR_exp_bias = 0x0FFFF // Set exponent bias
+}
+{ .mlx
+ setf.d FR_RSHF = GR_rshf // Right shift const 1.1000 * 2^63
+ movl GR_ERFC_XC_TB = 0x650
+}
+;;
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ setf.exp FR_2TOM51 = GR_exp_2tom51 // 2^-51 for scaling float_N
+(p6) fma.s1 FR_Tmp = FR_Tmp, FR_Tmp, f0 // (|x|+1)^2,x >=0
+ nop.i 0
+}
+{ .mfi
+ ldfpd FR_POS_ARG_ASYMP,FR_NEG_ARG_ASYMP = [GR_ad_Arg], 16
+(p7) fma.s1 FR_Tmp = FR_Tmp1, FR_Tmp1, f0 // (|x|+1)^2, x<0
+ mov GR_0x1 = 0x1
+}
+;;
+
+//p8: y = 1.0, x = 0.0,quick exit
+{ .mfi
+ ldfpd FR_dx,FR_dx1 = [GR_ad_Arg], 16
+ fclass.m p9,p0 = f8, 0x22 // p9: x = -inf
+ nop.i 0
+
+}
+{ .mfb
+ nop.m 0
+(p8) fma.s0 f8 = f1, f1, f0
+(p8) br.ret.spnt b0
+}
+;;
+
+{ .mfi
+ ldfe FR_UnfBound = [GR_ad_Arg], 16
+ fclass.m p11,p0 = f8, 0xc3 // p11: x = nan
+ mov GR_BIAS = 0x0FFFF
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_NormX = f8,f1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe FR_EpsNorm = [GR_ad_Arg], 16
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_xsq_lo = f8, f8, FR_norm_x // low bits for -x^2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ add GR_ad_C = 0x20, GR_ad_Arg // Point to C table
+ nop.f 0
+ add GR_ad_T1 = 0x50, GR_ad_Arg // Point to T1 table
+}
+{ .mfi
+ add GR_ad_T2 = 0x150, GR_ad_Arg // Point to T2 table
+ nop.f 0
+ add GR_ERFC_XC_TB = GR_ERFC_XC_TB, GR_ad_Arg //poin.to XB_TBL
+}
+;;
+
+{ .mfi
+ getf.exp GR_signexp_x = FR_norm_x // Extr. sign and exponent of x
+ fma.s1 FR_Tmp = FR_Tmp, FR_Tmp, f0 // (|x|+1)^4
+ add GR_ad_W1 = 0x100, GR_ad_T2 // Point to W1 table
+}
+{ .mfi
+ ldfe FR_L_hi = [GR_ad_Arg],16 // Get L_hi
+ nop.f 0
+ add GR_ad_W2 = 0x300, GR_ad_T2 // Point to W2 table
+}
+;;
+
+// p9: y = 2.0, x = -inf, quick exit
+{ .mfi
+ sub GR_mBIAS = r0, GR_BIAS
+ fma.s1 FR_2 = f1, f1, f1
+ nop.i 0
+}
+{ .mfb
+ ldfe FR_L_lo = [GR_ad_Arg],16 // Get L_lo
+(p9) fma.s0 f8 = f1, f1, f1
+(p9) br.ret.spnt b0
+}
+;;
+
+// p10: y = 0.0, x = +inf, quick exit
+{ .mfi
+ adds GR_ERFC_P_TB = 0x380, GR_ERFC_XC_TB // pointer to P_TBL
+ fma.s1 FR_N_signif = FR_norm_x, FR_INV_LN2_2TO63, FR_RSHF_2TO51
+ and GR_exp_x = GR_signexp_x, GR_exp_mask
+}
+{ .mfb
+ adds GR_ERFC_S_TB = 0x1C0, GR_ERFC_XC_TB // pointer to S_TBL
+(p10) fma.s0 f8 = f0, f1, f0
+(p10) br.ret.spnt b0
+}
+;;
+
+// p12: |x| < 0.681... -> dx = 0.875 (else dx = 0.625 )
+// p11: y = x, x = nan, quick exit
+{ .mfi
+ ldfe FR_C3 = [GR_ad_C],16 // Get C3 for normal path
+ fcmp.lt.s1 p12,p0 = FR_AbsArg, FR_ch_dx
+ shl GR_ShftPi_bias = GR_BIAS, 8 // BIAS * 256
+}
+{ .mfb
+ sub GR_exp_x = GR_exp_x, GR_exp_bias // Get exponent
+(p11) fma.s0 f8 = f8, f1, f0
+(p11) br.ret.spnt b0
+
+}
+;;
+
+{ .mfi
+ ldfe FR_C2 = [GR_ad_C],16 // Get A2 for main path
+ nop.f 0
+ nop.i 0
+}
+;;
+
+//p15: x > POS_ARG_ASYMP = 107.0 -> erfcl(x) ~=~ 0.0
+{ .mfi
+ ldfe FR_C1 = [GR_ad_C],16 // Get C1 for main path
+(p6) fcmp.gt.unc.s1 p15,p0 = FR_AbsArg, FR_POS_ARG_ASYMP // p6: x >= 0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p12) fma.s1 FR_dx = FR_dx1, f1, f0 //p12: dx = 0.875 for x < 0.681
+ nop.b 0
+}
+;;
+
+//p14: x < - NEG_ARG_ASYMP = -6.5 -> erfcl(x) ~=~ 2.0
+{ .mfi
+ nop.m 0
+(p7) fcmp.gt.unc.s1 p14,p0 = FR_AbsArg,FR_NEG_ARG_ASYMP // p7: x < 0
+ shladd GR_ShftXBi_bias = GR_mBIAS, 4, r0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s0 FR_Tmpf = f1, f1, FR_EpsNorm // flag i
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_float_N = FR_N_signif, FR_2TOM51, FR_RSHF
+ nop.i 0
+}
+;;
+
+// p8: x < UnfBound ~=~ 106.53... -> result without underflow error
+// p14: y ~=~ 2, x < -6.5,quick exit
+{ .mfi
+ getf.exp GR_IndxPlusBias = FR_Tmp // exp + bias for (|x|+1)^4
+ fcmp.lt.s1 p8,p0 = FR_NormX,FR_UnfBound
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p14) fnma.s0 FR_RESULT = FR_EpsNorm,FR_EpsNorm,FR_2
+(p14) br.ret.spnt b0
+
+}
+;;
+
+// p15: y ~=~ 0.0 (result with underflow error), x > POS_ARG_ASYMP = 107.0,
+// call __libm_error_region
+{ .mfb
+(p15) mov GR_Parameter_TAG = 207
+(p15) fma.s0 FR_RESULT = FR_EpsNorm,FR_EpsNorm,f0
+(p15) br.cond.spnt __libm_error_region
+}
+;;
+
+{ .mfi
+ getf.sig GR_N_fix = FR_N_signif // Get N from significand
+ nop.f 0
+ shl GR_ShftPi = GR_IndxPlusBias, 8
+
+}
+{ .mfi
+ shladd GR_ShftXBi = GR_IndxPlusBias, 4, GR_ShftXBi_bias
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mmi
+ add GR_ERFC_S_TB = GR_ERFC_S_TB, GR_ShftXBi //poin.to S[i]
+ add GR_ERFC_XC_TB = GR_ERFC_XC_TB, GR_ShftXBi //poin.to XC[i]
+ sub GR_ShftPi = GR_ShftPi, GR_ShftPi_bias // 256*i
+}
+;;
+
+{ .mfi
+ ldfe FR_Xc = [GR_ERFC_XC_TB]
+ fma.s1 FR_Xpdx_hi = FR_AbsArg, f1, FR_dx // x + dx
+ add GR_ShftA14 = 0xE0, GR_ShftPi // pointer shift for A14
+
+
+}
+{ .mfi
+ ldfe FR_S = [GR_ERFC_S_TB]
+ fnma.s1 FR_r = FR_L_hi, FR_float_N, FR_norm_x//r= -L_hi*float_N+x
+ add GR_ShftA15 = 0xF0, GR_ShftPi // pointer shift for A15
+}
+;;
+
+{ .mfi
+ add GR_P_POINT_1 = GR_ERFC_P_TB, GR_ShftA14 // pointer to A14
+ fcmp.gt.s1 p9,p10 = FR_AbsArg, FR_dx //p9: x > dx, p10: x <= dx
+ extr.u GR_M1 = GR_N_fix, 6, 6 // Extract index M_1
+}
+{ .mfi
+ add GR_P_POINT_2 = GR_ERFC_P_TB, GR_ShftA15 // pointer to A15
+ nop.f 0
+ nop.i 0
+
+}
+;;
+
+{ .mfi
+ ldfe FR_A14 = [GR_P_POINT_1], -32
+ nop.f 0
+ extr.u GR_M2 = GR_N_fix, 0, 6 // Extract index M_2
+}
+{ .mfi
+ ldfe FR_A15 = [GR_P_POINT_2], -32
+ nop.f 0
+ shladd GR_ad_W1 = GR_M1,3,GR_ad_W1 // Point to W1
+}
+;;
+
+{ .mfi
+ ldfe FR_A12 = [GR_P_POINT_1], -64
+ nop.f 0
+ extr GR_K = GR_N_fix, 12, 32 // Extract limite range K
+}
+{ .mfi
+ ldfe FR_A13 = [GR_P_POINT_2], -64
+ nop.f 0
+ shladd GR_ad_T1 = GR_M1,2,GR_ad_T1 // Point to T1
+}
+;;
+
+{ .mfi
+ ldfe FR_A8 = [GR_P_POINT_1], 32
+ nop.f 0
+ add GR_exp_2_k = GR_exp_bias, GR_K // Form exponent of 2^k
+}
+{ .mfi
+ ldfe FR_A9 = [GR_P_POINT_2], 32
+ nop.f 0
+ shladd GR_ad_W2 = GR_M2,3,GR_ad_W2 // Point to W2
+}
+;;
+
+{ .mfi
+ ldfe FR_A10 = [GR_P_POINT_1], -96
+ nop.f 0
+ shladd GR_ad_T2 = GR_M2,2,GR_ad_T2 // Point to T2
+}
+{ .mfi
+ ldfe FR_A11 = [GR_P_POINT_2], -96
+ fnma.s1 FR_r = FR_L_lo, FR_float_N, FR_r //r = -L_lo*float_N + r
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe FR_A4 = [GR_P_POINT_1], 32
+(p10) fms.s1 FR_Tmp = FR_dx,f1, FR_Xpdx_hi //for lo of x+dx, x<=dx
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A5 = [GR_P_POINT_2], 32
+(p9) fms.s1 FR_Tmp = FR_AbsArg, f1, FR_Xpdx_hi //for lo of x+dx, x>dx
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe FR_A6 = [GR_P_POINT_1], -64
+ frcpa.s1 FR_U,p11 = f1, FR_Xpdx_hi // hi of 1 /(x + dx)
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A7 = [GR_P_POINT_2], -64
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe FR_A2 = [GR_P_POINT_1], -32
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A3 = [GR_P_POINT_2], -32
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe FR_A0 = [GR_P_POINT_1], 224
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A1 = [GR_P_POINT_2]
+ fms.s1 FR_LocArg = FR_AbsArg, f1, FR_Xc // xloc = x - x[i]
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfd FR_W1 = [GR_ad_W1],0 // Get W1
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfd FR_W2 = [GR_ad_W2],0 // Get W2
+ fma.s1 FR_poly = FR_r, FR_C3, FR_C2 // poly = r * A3 + A2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfs FR_T1 = [GR_ad_T1],0 // Get T1
+(p10) fma.s1 FR_Xpdx_lo = FR_AbsArg,f1, FR_Tmp//lo of x + dx , x <= dx
+ nop.i 0
+}
+{ .mfi
+ ldfs FR_T2 = [GR_ad_T2],0 // Get T2
+(p9) fma.s1 FR_Xpdx_lo = FR_dx,f1, FR_Tmp // lo of x + dx, x > dx
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_Tmp1 = FR_Xpdx_hi, FR_U, FR_2 // N-R, iter. N1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp FR_scale = GR_exp_2_k // Set scale = 2^k
+ fma.s1 FR_P15_1_1 = FR_LocArg, FR_LocArg, f0 // xloc ^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_0_1 = FR_A15, FR_LocArg, FR_A14
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_1_2 = FR_A13, FR_LocArg, FR_A12
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly = FR_r, FR_poly, FR_C1 // poly = r * poly + A1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_2_1 = FR_A9, FR_LocArg, FR_A8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_2_2 = FR_A11, FR_LocArg, FR_A10
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U = FR_U, FR_Tmp1, f0 // N-R, iter. N1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_3_1 = FR_A5, FR_LocArg, FR_A4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_3_2 = FR_A7, FR_LocArg, FR_A6
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_4_2 = FR_A3, FR_LocArg, FR_A2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_W = FR_W1, FR_W2, FR_W2 // W = W1 * W2 + W2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_T = FR_T1, FR_T2 // T = T1 * T2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_7_1 = FR_P15_0_1, FR_P15_1_1, FR_P15_1_2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_7_2 = FR_P15_1_1, FR_P15_1_1, f0 // xloc^4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_8_1 = FR_P15_1_1, FR_P15_2_2, FR_P15_2_1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_Tmp = FR_Xpdx_hi, FR_U, FR_2 // N-R, iter. N2
+ nop.i 0
+}
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_poly = FR_rsq, FR_poly, FR_r // poly = rsq * poly + r
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_9_1 = FR_P15_1_1, FR_P15_4_2, FR_A0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_9_2 = FR_P15_1_1, FR_P15_3_2, FR_P15_3_1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_W = FR_W, f1, FR_W1 // W = W + W1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_T_scale = FR_T, FR_scale, f0 // T_scale = T * scale
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_13_1 = FR_P15_7_2, FR_P15_7_1, FR_P15_8_1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U = FR_U, FR_Tmp, f0 // N-R, iter. N2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_14_1 = FR_P15_7_2, FR_P15_9_2, FR_P15_9_1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_P15_14_2 = FR_P15_7_2, FR_P15_7_2, f0 // xloc^8
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_M = FR_T_scale, FR_S, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_Tmp = FR_Xpdx_hi, FR_U, FR_2 // N-R, iter. N3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Q = FR_P15_14_2, FR_P15_13_1, FR_P15_14_1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_H = FR_W, f1, FR_xsq_lo // H = W - xsq_lo
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_U = FR_U, FR_Tmp, f0 // N-R, iter. N3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Q = FR_A1, FR_LocArg, FR_Q
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_Tmp = FR_Xpdx_hi, FR_U, f1 // for du
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_R = FR_H, FR_poly, FR_poly
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_res_pos_x_hi = FR_M, FR_U, f0 // M *U
+ nop.i 0
+
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_R = FR_R, f1, FR_H // R = H + P(r) + H*P(r)
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s0 FR_Tmpf = f8, f1, f0 // flag d
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_dU = FR_Xpdx_lo, FR_U, FR_Tmp
+ nop.i 0
+}
+;;
+
+// p7: we begin to calculate y(x) = 2 - erfcl(-x) in multi precision
+// for -6.5 <= x < 0
+{ .mfi
+ nop.m 0
+ fms.s1 FR_res_pos_x_lo = FR_M, FR_U, FR_res_pos_x_hi
+ nop.i 0
+
+}
+{ .mfi
+ nop.m 0
+(p7) fnma.s1 FR_Tmp1 = FR_res_pos_x_hi, f1, FR_2 //p7: x < 0
+ nop.i 0
+
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_G = FR_R, FR_Q, FR_Q
+ nop.i 0
+
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Tmp = FR_R, f1, FR_dU // R + du
+ nop.i 0
+
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p7) fnma.s1 FR_Tmp2 = FR_Tmp1, f1, FR_2 //p7: x < 0
+ nop.i 0
+
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_G = FR_G, f1, FR_Tmp
+ nop.i 0
+
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p7) fnma.s1 FR_Tmp2 = FR_res_pos_x_hi, f1, FR_Tmp2 //p7: x < 0
+ nop.i 0
+
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_V = FR_G, FR_res_pos_x_hi, f0 // V = G * M *U
+ nop.i 0
+
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p7) fma.s1 FR_res_pos_x_lo = FR_res_pos_x_lo, f1, FR_V //p7: x < 0
+ nop.i 0
+
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p7) fnma.s1 FR_Tmp2 = FR_res_pos_x_lo, f1, FR_Tmp2 //p7: x < 0
+ nop.i 0
+
+}
+;;
+
+
+//p6: result for 0 < x < = POS_ARG_ASYMP
+//p7: result for - NEG_ARG_ASYMP <= x < 0
+//p8: exit for - NEG_ARG_ASYMP <= x < UnfBound
+
+ERFC_RESULT:
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fma.s0 f8 = FR_M, FR_U, FR_V // p6: x >= 0
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 207
+(p7) fma.s0 f8 = FR_Tmp2, f1, FR_Tmp1 // p7: x < 0
+(p8) br.ret.sptk b0
+};;
+
+GLOBAL_LIBM_END(erfcl)
+
+// call via (p15) br.cond.spnt __libm_error_region
+// for x > POS_ARG_ASYMP
+// or
+//
+// after .endp erfcl for UnfBound < = x < = POS_ARG_ASYMP
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/s_erff.S b/libc/sysdeps/ia64/fpu/s_erff.S
new file mode 100644
index 000000000..ed0aaac48
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_erff.S
@@ -0,0 +1,558 @@
+.file "erff.s"
+
+
+// Copyright (c) 2001 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/14/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// float erff(float)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+//
+// There are 8 paths:
+// 1. x = +/-0.0
+// Return erff(x) = +/-0.0
+//
+// 2. 0.0 < |x| < 0.125
+// Return erff(x) = x *Pol3(x^2),
+// where Pol3(x^2) = C3*x^6 + C2*x^4 + C1*x^2 + C0
+//
+// 3. 0.125 <= |x| < 4.0
+// Return erff(x) = sign(x)*PolD(x)*PolC(|x|) + sign(x)*PolA(|x|),
+// where sign(x)*PolD(x) = sign(x)*(|x|^7 + D2*x^6 + D1*|x|^5 + D0*x^4),
+// PolC(|x|) = B0*x^4 + C3*|x|^3 + C2*|x|^2 + C1*|x| + C0,
+// PolA(|x|) = A3|x|^3 + A2*x^2 + A1*|x| + A0
+//
+// Actually range 0.125<=|x|< 4.0 is splitted to 5 subranges.
+// For each subrange there is particular set of coefficients.
+// Below is the list of subranges:
+// 3.1 0.125 <= |x| < 0.25
+// 3.2 0.25 <= |x| < 0.5
+// 3.3 0.5 <= |x| < 1.0
+// 3.4 1.0 <= |x| < 2.0
+// 3.5 2.0 <= |x| < 4.0
+//
+// 4. 4.0 <= |x| < +INF
+// Return erff(x) = sign(x)*(1.0d - 2^(-52))
+//
+// 5. |x| = INF
+// Return erff(x) = sign(x) * 1.0
+//
+// 6. x = [S,Q]NaN
+// Return erff(x) = QNaN
+//
+// 7. x is positive denormal
+// Return erff(x) = C0*x - x^2,
+// where C0 = 2.0/sqrt(Pi)
+//
+// 8. x is negative denormal
+// Return erff(x) = C0*x + x^2,
+// where C0 = 2.0/sqrt(Pi)
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f32 -> f59
+
+// General registers used:
+// r32 -> r45, r2, r3
+
+// Predicate registers used:
+// p0, p6 -> p12, p14, p15
+
+// p6 to filter out case when x = [Q,S]NaN or +/-0
+// p7 to filter out case when x = denormal
+// p8 set if |x| >= 0.3125, used also to process denormal input
+// p9 to filter out case when |x| = inf
+// p10 to filter out case when |x| < 0.125
+// p11 to filter out case when 0.125 <= |x| < 4.0
+// p12 to filter out case when |x| >= 4.0
+// p14 set to 1 for positive x
+// p15 set to 1 for negative x
+
+// Assembly macros
+//==============================================================
+rDataPtr = r2
+rDataPtr1 = r3
+
+rBias = r33
+rCoeffAddr3 = r34
+rCoeffAddr1 = r35
+rCoeffAddr2 = r36
+rOffset2 = r37
+rBias2 = r38
+rMask = r39
+rArg = r40
+rBound = r41
+rSignBit = r42
+rAbsArg = r43
+rDataPtr2 = r44
+rSaturation = r45
+
+//==============================================================
+fA0 = f32
+fA1 = f33
+fA2 = f34
+fA3 = f35
+fC0 = f36
+fC1 = f37
+fC2 = f38
+fC3 = f39
+fD0 = f40
+fD1 = f41
+fD2 = f42
+fB0 = f43
+fArgSqr = f44
+fAbsArg = f45
+fSignumX = f46
+fArg4 = f47
+fArg4Sgn = f48
+fArg3 = f49
+fArg3Sgn = f50
+fArg7Sgn = f51
+fArg6Sgn = f52
+fPolC = f53
+fPolCTmp = f54
+fPolA = f55
+fPolATmp = f56
+fPolD = f57
+fPolDTmp = f58
+fArgSqrSgn = f59
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(erff_data)
+// Polynomial coefficients for the erf(x), 0.125 <= |x| < 0.25
+data8 0xBE4218BB56B49E66 // C0
+data8 0x3F7AFB8315DA322B // C1
+data8 0x3F615D6EBEE0CA32 // C2
+data8 0xBF468D71CF4F0918 // C3
+data8 0x40312115B0932F24 // D0
+data8 0xC0160D6CD0991EA3 // D1
+data8 0xBFE04A567A6DBE4A // D2
+data8 0xBF4207BC640D1509 // B0
+// Polynomial coefficients for the erf(x), 0.25 <= |x| < 0.5
+data8 0x3F90849356383F58 // C0
+data8 0x3F830BD5BA240F09 // C1
+data8 0xBF3FA4970E2BCE23 // C2
+data8 0xBF6061798E58D0FD // C3
+data8 0xBF68C0D83DD22E02 // D0
+data8 0x401C0A9EE4108F94 // D1
+data8 0xC01056F9B5E387F5 // D2
+data8 0x3F1C9744E36A5706 // B0
+// Polynomial coefficients for the erf(x), 0.5 <= |x| < 1.0
+data8 0x3F85F7D419A13DE3 // C0
+data8 0x3F791A13FF66D45A // C1
+data8 0x3F46B17B16B5929F // C2
+data8 0xBF5124947A8BF45E // C3
+data8 0x3FA1B3FD95EA9564 // D0
+data8 0x40250CECD79A020A // D1
+data8 0xC0190DC96FF66CCD // D2
+data8 0x3F4401AE28BA4DD5 // B0
+// Polynomial coefficients for the erf(x), 1.0 <= |x| < 2.0
+data8 0xBF49E07E3584C3AE // C0
+data8 0x3F3166621131445C // C1
+data8 0xBF65B7FC1EAC2099 // C2
+data8 0x3F508C6BD211D736 // C3
+data8 0xC053FABD70601067 // D0
+data8 0x404A06640EE87808 // D1
+data8 0xC0283F30817A3F08 // D2
+data8 0xBF2F6DBBF4D6257F // B0
+// Polynomial coefficients for the erf(x), 2.0 <= |x| < 4.0
+data8 0xBF849855D67E9407 // C0
+data8 0x3F5ECA5FEC01C70C // C1
+data8 0xBF483110C30FABA4 // C2
+data8 0x3F1618DA72860403 // C3
+data8 0xC08A5C9D5FE8B9F6 // D0
+data8 0x406EFF5F088CEC4B // D1
+data8 0xC03A5743DF38FDE0 // D2
+data8 0xBEE397A9FA5686A2 // B0
+// Polynomial coefficients for the erf(x), -0.125 < x < 0.125
+data8 0x3FF20DD7504270CB // C0
+data8 0xBFD8127465AFE719 // C1
+data8 0x3FBCE2D77791DD77 // C2
+data8 0xBF9B582755CDF345 // C3
+// Polynomial coefficients for the erf(x), 0.125 <= |x| < 0.25
+data8 0xBD54E7E451AF0E36 // A0
+data8 0x3FF20DD75043FE20 // A1
+data8 0xBE05680ACF8280E4 // A2
+data8 0xBFD812745E92C3D3 // A3
+// Polynomial coefficients for the erf(x), 0.25 <= |x| < 0.5
+data8 0xBE1ACEC2859CB55F // A0
+data8 0x3FF20DD75E8D2B64 // A1
+data8 0xBEABC6A83208FCFC // A2
+data8 0xBFD81253E42E7B99 // A3
+// Polynomial coefficients for the erf(x), 0.5 <= |x| < 1.0
+data8 0x3EABD5A2482B4979 // A0
+data8 0x3FF20DCAA52085D5 // A1
+data8 0x3F13A994A348795B // A2
+data8 0xBFD8167B2DFCDE44 // A3
+// Polynomial coefficients for the erf(x), 1.0 <= |x| < 2.0
+data8 0xBF5BA377DDAB4E17 // A0
+data8 0x3FF2397F1D8FC0ED // A1
+data8 0xBF9945BFC1915C21 // A2
+data8 0xBFD747AAABB690D8 // A3
+// Polynomial coefficients for the erf(x), 2.0 <= |x| < 4.0
+data8 0x3FF0E2920E0391AF // A0
+data8 0xC00D249D1A95A5AE // A1
+data8 0x40233905061C3803 // A2
+data8 0xC027560B851F7690 // A3
+//
+data8 0x3FEFFFFFFFFFFFFF // 1.0 - epsilon
+data8 0x3FF20DD750429B6D // C0 = 2.0/sqrt(Pi)
+LOCAL_OBJECT_END(erff_data)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(erff)
+
+{ .mfi
+ alloc r32 = ar.pfs, 0, 14, 0, 0
+ fmerge.s fAbsArg = f1, f8 // |x|
+ addl rMask = 0x806, r0
+}
+{ .mfi
+ addl rDataPtr = @ltoff(erff_data), gp
+ fma.s1 fArgSqr = f8, f8, f0 // x^2
+ adds rSignBit = 0x1, r0
+}
+;;
+
+{ .mfi
+ getf.s rArg = f8 // x in GR
+ fclass.m p7,p0 = f8, 0x0b // is x denormal ?
+ // sign bit and 2 most bits in significand
+ shl rMask = rMask, 20
+}
+{ .mfi
+ ld8 rDataPtr = [rDataPtr]
+ nop.f 0
+ adds rBias2 = 0x1F0, r0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fmerge.s fSignumX = f8, f1 // signum(x)
+ shl rSignBit = rSignBit, 31 // mask for sign bit
+}
+{ .mfi
+ adds rBound = 0x3E0, r0
+ nop.f 0
+ adds rSaturation = 0x408, r0
+}
+;;
+
+{ .mfi
+ andcm rOffset2 = rArg, rMask
+ fclass.m p6,p0 = f8, 0xc7 // is x [S,Q]NaN or +/-0 ?
+ shl rBound = rBound, 20 // 0.125f in GR
+}
+{ .mfb
+ andcm rAbsArg = rArg, rSignBit // |x| in GR
+ nop.f 0
+(p7) br.cond.spnt erff_denormal // branch out if x is denormal
+}
+;;
+
+{ .mfi
+ adds rCoeffAddr2 = 352, rDataPtr
+ fclass.m p9,p0 = f8, 0x23 // is x +/- inf?
+ shr rOffset2 = rOffset2, 21
+}
+{ .mfi
+ cmp.lt p10, p8 = rAbsArg, rBound // |x| < 0.125?
+ nop.f 0
+ adds rCoeffAddr3 = 16, rDataPtr
+}
+;;
+
+{ .mfi
+(p8) sub rBias = rOffset2, rBias2
+ fma.s1 fArg4 = fArgSqr, fArgSqr, f0 // x^4
+ shl rSaturation = rSaturation, 20// 4.0 in GR (saturation bound)
+}
+{ .mfb
+(p10) adds rBias = 0x14, r0
+(p6) fma.s.s0 f8 = f8,f1,f8 // NaN or +/-0
+(p6) br.ret.spnt b0 // exit for x = NaN or +/-0
+}
+;;
+
+{ .mfi
+ shladd rCoeffAddr1 = rBias, 4, rDataPtr
+ fma.s1 fArg3Sgn = fArgSqr, f8, f0 // sign(x)*|x|^3
+ // is |x| < 4.0?
+ cmp.lt p11, p12 = rAbsArg, rSaturation
+}
+{ .mfi
+ shladd rCoeffAddr3 = rBias, 4, rCoeffAddr3
+ fma.s1 fArg3 = fArgSqr, fAbsArg, f0 // |x|^3
+ shladd rCoeffAddr2 = rBias, 3, rCoeffAddr2
+}
+;;
+
+{ .mfi
+(p11) ldfpd fC0, fC1 = [rCoeffAddr1]
+(p9) fmerge.s f8 = f8,f1 // +/- inf
+(p12) adds rDataPtr = 512, rDataPtr
+}
+{ .mfb
+(p11) ldfpd fC2, fC3 = [rCoeffAddr3], 16
+ nop.f 0
+(p9) br.ret.spnt b0 // exit for x = +/- inf
+}
+;;
+
+{ .mfi
+(p11) ldfpd fA0, fA1 = [rCoeffAddr2], 16
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ add rCoeffAddr1 = 48, rCoeffAddr1
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+(p11) ldfpd fD0, fD1 = [rCoeffAddr3]
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+(p11) ldfpd fD2, fB0 = [rCoeffAddr1]
+ // sign(x)*|x|^2
+ fma.s1 fArgSqrSgn = fArgSqr, fSignumX, f0
+(p10) br.cond.spnt erff_near_zero
+}
+;;
+
+{ .mfi
+(p11) ldfpd fA2, fA3 = [rCoeffAddr2], 16
+ fcmp.lt.s1 p15, p14 = f8,f0
+ nop.i 0
+}
+{ .mfb
+(p12) ldfd fA0 = [rDataPtr]
+ fma.s1 fArg4Sgn = fArg4, fSignumX, f0 // sign(x)*|x|^4
+(p12) br.cond.spnt erff_saturation
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fArg7Sgn = fArg4, fArg3Sgn, f0 // sign(x)*|x|^7
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fArg6Sgn = fArg3, fArg3Sgn, f0 // sign(x)*|x|^6
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fPolC = fC3, fAbsArg, fC2 // C3*|x| + C2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPolCTmp = fC1, fAbsArg, fC0 // C1*|x| + C0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fPolA = fA1, fAbsArg, fA0 // A1*|x| + A0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fPolD = fD1, fAbsArg, fD0 // D1*|x| + D0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // sign(x)*(|x|^7 + D2*x^6)
+ fma.s1 fPolDTmp = fArg6Sgn, fD2, fArg7Sgn
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fPolATmp = fA3, fAbsArg, fA2 // A3*|x| + A2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB0 = fB0, fArg4, f0 // B0*x^4
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ // C3*|x|^3 + C2*x^2 + C1*|x| + C0
+ fma.s1 fPolC = fPolC, fArgSqr, fPolCTmp
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // PolD = sign(x)*(|x|^7 + D2*x^6 + D1*|x|^5 + D0*x^4)
+ fma.d.s1 fPolD = fPolD, fArg4Sgn, fPolDTmp
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // PolA = A3|x|^3 + A2*x^2 + A1*|x| + A0
+ fma.d.s1 fPolA = fPolATmp, fArgSqr, fPolA
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // PolC = B0*x^4 + C3*|x|^3 + C2*|x|^2 + C1*|x| + C0
+ fma.d.s1 fPolC = fPolC, f1, fB0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p14) fma.s.s0 f8 = fPolC, fPolD, fPolA // for positive x
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p15) fms.s.s0 f8 = fPolC, fPolD, fPolA // for negative x
+ br.ret.sptk b0 // Exit for 0.125 <=|x|< 4.0
+};;
+
+
+// Here if |x| < 0.125
+erff_near_zero:
+{ .mfi
+ nop.m 0
+ fma.s1 fPolC = fC3, fArgSqr, fC2 // C3*x^2 + C2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPolCTmp = fC1, fArgSqr, fC0 // C1*x^2 + C0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fPolC = fPolC, fArg4, fPolCTmp // C3*x^6 + C2*x^4 + C1*x^2 + C0
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ // x*(C3*x^6 + C2*x^4 + C1*x^2 + C0)
+ fma.s.s0 f8 = fPolC, f8, f0
+ br.ret.sptk b0 // Exit for |x| < 0.125
+};;
+
+// Here if 4.0 <= |x| < +inf
+erff_saturation:
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = fA0, fSignumX, f0 // sign(x)*(1.0d - 2^(-52))
+ // Exit for 4.0 <= |x| < +inf
+ br.ret.sptk b0 // Exit for 4.0 <=|x|< +inf
+}
+;;
+
+// Here if x is single precision denormal
+erff_denormal:
+{ .mfi
+ adds rDataPtr = 520, rDataPtr // address of C0
+ fclass.m p7,p8 = f8, 0x0a // is x -denormal ?
+ nop.i 0
+}
+;;
+{ .mfi
+ ldfd fC0 = [rDataPtr] // C0
+ nop.f 0
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fC0 = fC0,f8,f0 // C0*x
+ nop.i 0
+}
+;;
+{ .mfi
+ nop.m 0
+(p7) fma.s.s0 f8 = f8,f8,fC0 // -denormal
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fnma.s.s0 f8 = f8,f8,fC0 // +denormal
+ br.ret.sptk b0 // Exit for denormal
+}
+;;
+
+GLOBAL_LIBM_END(erff)
diff --git a/libc/sysdeps/ia64/fpu/s_erfl.S b/libc/sysdeps/ia64/fpu/s_erfl.S
new file mode 100644
index 000000000..10da22ce3
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_erfl.S
@@ -0,0 +1,1240 @@
+.file "erfl.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 11/21/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 08/14/02 Changed mli templates to mlx
+// 02/06/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// long double erfl(long double)
+//
+// Overview of operation
+//==============================================================
+//
+// Algorithm description
+// ---------------------
+//
+// There are 4 paths:
+//
+// 1. Special path: x = 0, Inf, NaNs, denormal
+// Return erfl(x) = +/-0.0 for zeros
+// Return erfl(x) = QNaN for NaNs
+// Return erfl(x) = sign(x)*1.0 for Inf
+// Return erfl(x) = (A0H+A0L)*x + x^2, ((A0H+A0L) = 2.0/sqrt(Pi))
+// for denormals
+//
+// 2. [0;1/8] path: 0.0 < |x| < 1/8
+// Return erfl(x) = x*(A1H+A1L) + x^3*A3 + ... + x^15*A15
+//
+// 3. Main path: 1/8 <= |x| < 6.53
+// For several ranges of 1/8 <= |x| < 6.53
+// Return erfl(x) = sign(x)*((A0H+A0L) + y*(A1H+A1L) + y^2*(A2H+A2L) +
+// + y^3*A3 + y^4*A4 + ... + y^25*A25 )
+// where y = (|x|/a) - b
+//
+// For each range there is particular set of coefficients.
+// Below is the list of ranges:
+// 1/8 <= |x| < 1/4 a = 0.125, b = 1.5
+// 1/4 <= |x| < 1/2 a = 0.25, b = 1.5
+// 1/2 <= |x| < 1.0 a = 0.5, b = 1.5
+// 1.0 <= |x| < 2.0 a = 1.0, b = 1.5
+// 2.0 <= |x| < 3.25 a = 2.0, b = 1.5
+// 3.25 <= |x| < 4.0 a = 2.0, b = 2.0
+// 4.0 <= |x| < 6.53 a = 4.0, b = 1.5
+// ( [3.25;4.0] subrange separated for monotonicity issues resolve )
+//
+// 4. Saturation path: 6.53 <= |x| < +INF
+// Return erfl(x) = sign(x)*(1.0 - tiny_value)
+// (tiny_value ~ 1e-1233)
+//
+// Implementation notes
+// --------------------
+//
+// 1. Special path: x = 0, INF, NaNa, denormals
+//
+// This branch is cut off by one fclass operation.
+// Then zeros+nans, infinities and denormals processed separately.
+// For denormals we had to use multiprecision A0 coefficient to reach
+// necessary accuracy: (A0H+A0L)*x-x^2
+//
+// 2. [0;1/8] path: 0.0 < |x| < 1/8
+//
+// First coefficient of polynomial we must split to multiprecision too.
+// Also we can parallelise computations:
+// (x*(A1H+A1L)) calculated in parallel with "tail" (x^3*A3 + ... + x^15*A15)
+// Furthermore the second part is factorized using binary tree technique.
+//
+// 3. Main path: 1/8 <= |x| < 6.53
+//
+// Multiprecision have to be performed only for first few
+// polynomial iterations (up to 3-rd x degree)
+// Here we use the same parallelisation way as above:
+// Split whole polynomial to first, "multiprecision" part, and second,
+// so called "tail", native precision part.
+//
+// 1) Multiprecision part:
+// [v1=(A0H+A0L)+y*(A1H+A1L)] + [v2=y^2*((A2H+A2L)+y*A3)]
+// v1 and v2 terms calculated in parallel
+//
+// 2) Tail part:
+// v3 = x^4 * ( A4 + x*A5 + ... + x^21*A25 )
+// v3 is splitted to 2 even parts (10 coefficient in each one).
+// These 2 parts are also factorized using binary tree technique.
+//
+// So Multiprecision and Tail parts cost is almost the same
+// and we have both results ready before final summation.
+//
+// 4. Saturation path: 6.53 <= |x| < +INF
+//
+// We use formula sign(x)*(1.0 - tiny_value) instead of simple sign(x)*1.0
+// just to meet IEEE requirements for different rounding modes in this case.
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8 - input & output
+// f32 -> f90
+
+// General registers used:
+// r2, r3, r32 -> r52
+
+// Predicate registers used:
+// p0, p6 -> p11, p14, p15
+
+// p6 - arg is zero, denormal or special IEEE
+// p7 - arg is in [4;8] binary interval
+// p8 - arg is in [3.25;4] interval
+// p9 - arg < 1/8
+// p10 - arg is NOT in [3.25;4] interval
+// p11 - arg in saturation domain
+// p14 - arg is positive
+// p15 - arg is negative
+
+// Assembly macros
+//==============================================================
+rDataPtr = r2
+rTailDataPtr = r3
+
+rBias = r33
+rSignBit = r34
+rInterval = r35
+
+rArgExp = r36
+rArgSig = r37
+r3p25Offset = r38
+r2to4 = r39
+r1p25 = r40
+rOffset = r41
+r1p5 = r42
+rSaturation = r43
+r3p25Sign = r44
+rTiny = r45
+rAddr1 = r46
+rAddr2 = r47
+rTailAddr1 = r48
+rTailAddr2 = r49
+rTailOffset = r50
+rTailAddOffset = r51
+rShiftedDataPtr = r52
+
+//==============================================================
+fA0H = f32
+fA0L = f33
+fA1H = f34
+fA1L = f35
+fA2H = f36
+fA2L = f37
+fA3 = f38
+fA4 = f39
+fA5 = f40
+fA6 = f41
+fA7 = f42
+fA8 = f43
+fA9 = f44
+fA10 = f45
+fA11 = f46
+fA12 = f47
+fA13 = f48
+fA14 = f49
+fA15 = f50
+fA16 = f51
+fA17 = f52
+fA18 = f53
+fA19 = f54
+fA20 = f55
+fA21 = f56
+fA22 = f57
+fA23 = f58
+fA24 = f59
+fA25 = f60
+
+fArgSqr = f61
+fArgCube = f62
+fArgFour = f63
+fArgEight = f64
+
+fArgAbsNorm = f65
+fArgAbsNorm2 = f66
+fArgAbsNorm2L = f67
+fArgAbsNorm3 = f68
+fArgAbsNorm4 = f69
+fArgAbsNorm11 = f70
+
+fRes = f71
+fResH = f72
+fResL = f73
+fRes1H = f74
+fRes1L = f75
+fRes1Hd = f76
+fRes2H = f77
+fRes2L = f78
+fRes3H = f79
+fRes3L = f80
+fRes4 = f81
+
+fTT = f82
+fTH = f83
+fTL = f84
+fTT2 = f85
+fTH2 = f86
+fTL2 = f87
+
+f1p5 = f88
+f2p0 = f89
+fTiny = f90
+
+
+// Data tables
+//==============================================================
+RODATA
+
+.align 64
+LOCAL_OBJECT_START(erfl_data)
+////////// Main tables ///////////
+_0p125_to_0p25_data: // exp = 2^-3
+// Polynomial coefficients for the erf(x), 1/8 <= |x| < 1/4
+data8 0xACD9ED470F0BB048, 0x0000BFF4 //A3 = -6.5937529303909561891162915809e-04
+data8 0xBF6A254428DDB452 //A2H = -3.1915980570631852578089571182e-03
+data8 0xBC131B3BE3AC5079 //A2L = -2.5893976889070198978842231134e-19
+data8 0x3FC16E2D7093CD8C //A1H = 1.3617485043469590433318217038e-01
+data8 0x3C6979A52F906B4C //A1L = 1.1048096806003284897639351952e-17
+data8 0x3FCAC45E37FE2526 //A0H = 2.0911767705937583938791135552e-01
+data8 0x3C648D48536C61E3 //A0L = 8.9129592834861155344147026365e-18
+data8 0xD1FC135B4A30E746, 0x00003F90 //A25 = 6.3189963203954877364460345654e-34
+data8 0xB1C79B06DD8C988C, 0x00003F97 //A24 = 6.8478253118093953461840838106e-32
+data8 0xCC7AE121D1DEDA30, 0x0000BF9A //A23 = -6.3010264109146390803803408666e-31
+data8 0x8927B8841D1E0CA8, 0x0000BFA1 //A22 = -5.4098171537601308358556861717e-29
+data8 0xB4E84D6D0C8F3515, 0x00003FA4 //A21 = 5.7084320046554628404861183887e-28
+data8 0xC190EAE69A67959A, 0x00003FAA //A20 = 3.9090359419467121266470910523e-26
+data8 0x90122425D312F680, 0x0000BFAE //A19 = -4.6551806872355374409398000522e-25
+data8 0xF8456C9C747138D6, 0x0000BFB3 //A18 = -2.5670639225386507569611436435e-23
+data8 0xCDCAE0B3C6F65A3A, 0x00003FB7 //A17 = 3.4045511783329546779285646369e-22
+data8 0x8F41909107C62DCC, 0x00003FBD //A16 = 1.5167830861896169812375771948e-20
+data8 0x82F0FCB8A4B8C0A3, 0x0000BFC1 //A15 = -2.2182328575376704666050112195e-19
+data8 0x92E992C58B7C3847, 0x0000BFC6 //A14 = -7.9641369349930600223371163611e-18
+LOCAL_OBJECT_END(erfl_data)
+
+LOCAL_OBJECT_START(_0p25_to_0p5_data)
+// Polynomial coefficients for the erf(x), 1/4 <= |x| < 1/2
+data8 0xF083628E8F7CE71D, 0x0000BFF6 //A3 = -3.6699405305266733332335619531e-03
+data8 0xBF978749A434FE4E //A2H = -2.2977018973732214746075186440e-02
+data8 0xBC30B3FAFBC21107 //A2L = -9.0547407100537663337591537643e-19
+data8 0x3FCF5F0CDAF15313 //A1H = 2.4508820238647696654332719390e-01
+data8 0x3C1DFF29F5AD8117 //A1L = 4.0653155218104625249413579084e-19
+data8 0x3FD9DD0D2B721F38 //A0H = 4.0411690943482225790717166092e-01
+data8 0x3C874C71FEF1759E //A0L = 4.0416653425001310671815863946e-17
+data8 0xA621D99B8C12595E, 0x0000BFAB //A25 = -6.7100271986703749013021666304e-26
+data8 0xBD7BBACB439992E5, 0x00003FAE //A24 = 6.1225362452814749024566661525e-25
+data8 0xFF2FEFF03A98E410, 0x00003FB2 //A23 = 1.3192871864994282747963195183e-23
+data8 0xAE8180957ABE6FD5, 0x0000BFB6 //A22 = -1.4434787102181180110707433640e-22
+data8 0xAF0566617B453AA6, 0x0000BFBA //A21 = -2.3163848847252215762970075142e-21
+data8 0x8F33D3616B9B8257, 0x00003FBE //A20 = 3.0324297082969526400202995913e-20
+data8 0xD58AB73354438856, 0x00003FC1 //A19 = 3.6175397854863872232142412590e-19
+data8 0xD214550E2F3210DF, 0x0000BFC5 //A18 = -5.6942141660091333278722310354e-18
+data8 0xE2CA60C328F3BBF5, 0x0000BFC8 //A17 = -4.9177359011428870333915211291e-17
+data8 0x88D9BB274F9B3873, 0x00003FCD //A16 = 9.4959118337089189766177270051e-16
+data8 0xCA4A00AB538A2DB2, 0x00003FCF //A15 = 5.6146496538690657993449251855e-15
+data8 0x9CC8FFFBDDCF9853, 0x0000BFD4 //A14 = -1.3925319209173383944263942226e-13
+LOCAL_OBJECT_END(_0p25_to_0p5_data)
+
+LOCAL_OBJECT_START(_0p5_to_1_data)
+// Polynomial coefficients for the erf(x), 1/2 <= |x| < 1
+data8 0xDB742C8FB372DBE0, 0x00003FF6 //A3 = 3.3485993187250381721535255963e-03
+data8 0xBFBEDC5644353C26 //A2H = -1.2054957547410136142751468924e-01
+data8 0xBC6D7215B023455F //A2L = -1.2770012232203569059818773287e-17
+data8 0x3FD492E42D78D2C4 //A1H = 3.2146553459760363047337250464e-01
+data8 0x3C83A163CAC22E05 //A1L = 3.4053365952542489137756724868e-17
+data8 0x3FE6C1C9759D0E5F //A0H = 7.1115563365351508462453011816e-01
+data8 0x3C8B1432F2CBC455 //A0L = 4.6974407716428899960674098333e-17
+data8 0x95A6B92162813FF8, 0x00003FC3 //A25 = 1.0140763985766801318711038400e-18
+data8 0xFE5EC3217F457B83, 0x0000BFC6 //A24 = -1.3789434273280972156856405853e-17
+data8 0x9B49651031B5310B, 0x0000BFC8 //A23 = -3.3672435142472427475576375889e-17
+data8 0xDBF73927E19B7C8D, 0x00003FCC //A22 = 7.6315938248752024965922341872e-16
+data8 0xF55CBA3052730592, 0x00003FCB //A21 = 4.2563559623888750271176552350e-16
+data8 0xA1DC9380DA82CFF6, 0x0000BFD2 //A20 = -3.5940500736023122607663701015e-14
+data8 0xAAD1AE1067F3D577, 0x00003FD2 //A19 = 3.7929451192558641569555227613e-14
+data8 0xCD1DB83F3B9D2090, 0x00003FD7 //A18 = 1.4574374961011929143375716362e-12
+data8 0x87235ACB5E8BB298, 0x0000BFD9 //A17 = -3.8408559294899660346666452560e-12
+data8 0xDA417B78FF9F46B4, 0x0000BFDC //A16 = -4.9625621225715971268115023451e-11
+data8 0xF075762685484436, 0x00003FDE //A15 = 2.1869603559309150844390066920e-10
+data8 0xB989FDB3795165C7, 0x00003FE1 //A14 = 1.3499740992928183247608593000e-09
+LOCAL_OBJECT_END(_0p5_to_1_data)
+
+LOCAL_OBJECT_START(_1_to_2_data)
+// Polynomial coefficients for the erf(x), 1 <= |x| < 2.0
+data8 0x8E15015F5B55BEAC, 0x00003FFC //A3 = 1.3875200409423426678618977531e-01
+data8 0xBFC6D5A95D0A1B7E //A2H = -1.7839543383544403942764233761e-01
+data8 0xBC7499F704C80E02 //A2L = -1.7868888188464394090788198634e-17
+data8 0x3FBE723726B824A8 //A1H = 1.1893028922362935961842822508e-01
+data8 0x3C6B77F399C2AD27 //A1L = 1.1912589318015368492508652194e-17
+data8 0x3FEEEA5557137ADF //A0H = 9.6610514647531064991170524081e-01
+data8 0x3C963D0DDD0A762F //A0L = 7.7155271023949055047261953350e-17
+data8 0x8FAA405DAD409771, 0x0000BFDB //A25 = -1.6332824616946528652252813763e-11
+data8 0x941386F4697976D8, 0x0000BFDD //A24 = -6.7337295147729213955410252613e-11
+data8 0xBCBE75234530B404, 0x00003FDF //A23 = 3.4332329029092304943838374908e-10
+data8 0xF55E2CE71A00D040, 0x00003FDF //A22 = 4.4632156034175937694868068394e-10
+data8 0xA6CADFE489D2671F, 0x0000BFE3 //A21 = -4.8543000253822277507724949798e-09
+data8 0xA4C69F11FEAFB3A8, 0x00003FE2 //A20 = 2.3978044150868471771557059958e-09
+data8 0xD63441E3BED59703, 0x00003FE6 //A19 = 4.9873285553412397317802071288e-08
+data8 0xDFDAED9D3089D732, 0x0000BFE7 //A18 = -1.0424069510877052249228047044e-07
+data8 0xB47287FF165756A5, 0x0000BFE9 //A17 = -3.3610945128073834488448164164e-07
+data8 0xCDAF2DC0A79A9059, 0x00003FEB //A16 = 1.5324673941628851136481785187e-06
+data8 0x9FD6A7B2ECE8EDA9, 0x00003FEA //A15 = 5.9544479989469083598476592569e-07
+data8 0xEC6E63BB4507B585, 0x0000BFEE //A14 = -1.4092398243085031882423746824e-05
+LOCAL_OBJECT_END(_1_to_2_data)
+
+LOCAL_OBJECT_START(_2_to_3p25_data)
+// Polynomial coefficients for the erf(x), 2 <= |x| < 3.25
+data8 0xCEDBA58E8EE6F055, 0x00003FF7 //A3 = 6.3128050215859026984338771121e-03
+data8 0xBF5B60D5E974CBBD //A2H = -1.6710366233609740427984435840e-03
+data8 0xBC0E11E2AEC18AF6 //A2L = -2.0376133202996259839305825162e-19
+data8 0x3F32408E9BA3327E //A1H = 2.7850610389349567379974059733e-04
+data8 0x3BE41010E4B3B224 //A1L = 3.3987633691879253781833531576e-20
+data8 0x3FEFFFD1AC4135F9 //A0H = 9.9997790950300136092465663751e-01
+data8 0x3C8EEAFA1E97EAE0 //A0L = 5.3633970564750967956196033852e-17
+data8 0xBF9C6F2C6D7263C1, 0x00003FF0 //A25 = 4.5683639377039166585098497471e-05
+data8 0xCB4167CC4798096D, 0x00003FF0 //A24 = 4.8459885139772945417160731273e-05
+data8 0xE1394FECFE972D32, 0x0000BFF2 //A23 = -2.1479022581129892562916533804e-04
+data8 0xC7F9E47581FC2A5F, 0x0000BFF2 //A22 = -1.9071211076537531370822343363e-04
+data8 0xDD612EDFAA41BEAE, 0x00003FF2 //A21 = 2.1112405918671957390188348542e-04
+data8 0x8C166AA4CB2AD8FD, 0x0000BFF4 //A20 = -5.3439165021555312536009227942e-04
+data8 0xEFBE33D9F62B68D4, 0x0000BFF2 //A19 = -2.2863672131516067770956697877e-04
+data8 0xCCB92F5D91562494, 0x00003FF5 //A18 = 1.5619154280865226092321881421e-03
+data8 0x80A5DBE71D4BA0E2, 0x0000BFF6 //A17 = -1.9630109664962540123775799179e-03
+data8 0xA0ADEB2D4C41347A, 0x0000BFF4 //A16 = -6.1294315248639348947483422457e-04
+data8 0xB1F5D4911B911665, 0x00003FF7 //A15 = 5.4309165882071876864550213817e-03
+data8 0xF2F3D8D21E8762E0, 0x0000BFF7 //A14 = -7.4143227286535936033409745884e-03
+LOCAL_OBJECT_END(_2_to_3p25_data)
+
+LOCAL_OBJECT_START(_4_to_6p53_data)
+// Polynomial coefficients for the erf(x), 4 <= |x| < 6.53
+data8 0xDF3151BE8652827E, 0x00003FD5 //A3 = 3.9646979666953349095427642209e-13
+data8 0xBD1C4A9787DF888B //A2H = -2.5127788450714750484839908889e-14
+data8 0xB99B35483E4603FD //A2L = -3.3536613901268985626466020210e-31
+data8 0x3CD2DBF507F1A1F3 //A1H = 1.0468963266736687758710258897e-15
+data8 0x398A97B60913B4BD //A1L = 1.6388968267515149775818013207e-31
+data8 0x3FEFFFFFFFFFFFFF //A0H = 9.9999999999999988897769753748e-01
+data8 0x3C99CC25E658129E //A0L = 8.9502895736398715695745861054e-17
+data8 0xB367B21294713D39, 0x00003FFB //A25 = 8.7600127403270828432337605471e-02
+data8 0xCEE3A423ADEC0F4C, 0x00003FFD //A24 = 4.0408051429309221404807497715e-01
+data8 0xC389626CF2D727C0, 0x00003FFE //A23 = 7.6381507072332210580356159947e-01
+data8 0xD15A03E082D0A307, 0x00003FFE //A22 = 8.1777977210259904277239787430e-01
+data8 0x8FD3DA92675E8E00, 0x00003FFE //A21 = 5.6182638239203638864793584264e-01
+data8 0xFD375E6EE167AA58, 0x00003FFC //A20 = 2.4728152801285544751731937424e-01
+data8 0x89A9482FADE66AE1, 0x00003FFB //A19 = 6.7217410998398471333985773237e-02
+data8 0xC62E1F02606C04DD, 0x00003FF7 //A18 = 6.0479785358923404401184993359e-03
+data8 0xEE7BF2BE71CC531C, 0x0000BFF5 //A17 = -1.8194898432032114199803271708e-03
+data8 0x8084081981CDC79C, 0x0000BFF5 //A16 = -9.8049734947701208487713246099e-04
+data8 0x8975DFB834C118C3, 0x0000BFF0 //A15 = -3.2773123965143773578608926094e-05
+data8 0x965DA4A80008B7BC, 0x0000BFEE //A14 = -8.9624997201558650125662820562e-06
+LOCAL_OBJECT_END(_4_to_6p53_data)
+
+LOCAL_OBJECT_START(_3p25_to_4_data)
+// Polynomial coefficients for the erf(x), 3.25 <= |x| < 4
+data8 0xB01D29846286CE08, 0x00003FEE //A3 = 1.0497207328743021499800978059e-05
+data8 0xBEC10B1488AEB234 //A2H = -2.0317175474986489113480084279e-06
+data8 0xBB7F19701B8B74F9 //A2L = -4.1159669348226960337518214996e-22
+data8 0x3E910B1488AEB234 //A1H = 2.5396469343733111391850105348e-07
+data8 0x3B4F1944906D5D60 //A1L = 5.1448487494628801547474934193e-23
+data8 0x3FEFFFFFF7B91176 //A0H = 9.9999998458274208523732795584e-01
+data8 0x3C70B2865615DB3F //A0L = 1.4482653192002495179309994964e-17
+data8 0xA818D085D56F3021, 0x00003FEC //A25 = 2.5048394770210505593609705765e-06
+data8 0xD9C5C509AAE5561F, 0x00003FEC //A24 = 3.2450636894654766492719395406e-06
+data8 0x9682D71C549EEB07, 0x0000BFED //A23 = -4.4855801709974050650263470866e-06
+data8 0xBC230E1EB6FBF8B9, 0x00003FEA //A22 = 7.0086469577174843181452303996e-07
+data8 0xE1432649FF29D4DE, 0x0000BFEA //A21 = -8.3916747195472308725504497231e-07
+data8 0xB40CEEBD2803D2F0, 0x0000BFEF //A20 = -2.1463694318102769992677291330e-05
+data8 0xEAAB57ABFFA003EB, 0x00003FEF //A19 = 2.7974761309213643228699449426e-05
+data8 0xFBFA4D0B893A5BFB, 0x0000BFEE //A18 = -1.5019043571612821858165073446e-05
+data8 0xBB6AA248EED3E364, 0x0000BFF0 //A17 = -4.4683584873907316507141131797e-05
+data8 0x86C1B3AE3E500ED9, 0x00003FF2 //A16 = 1.2851395412345761361068234880e-04
+data8 0xB60729445F0C37B5, 0x0000BFF2 //A15 = -1.7359540313300841352152461287e-04
+data8 0xCA389F9E707337B1, 0x00003FF1 //A14 = 9.6426575465763394281615740282e-05
+LOCAL_OBJECT_END(_3p25_to_4_data)
+
+
+//////// "Tail" tables //////////
+LOCAL_OBJECT_START(_0p125_to_0p25_data_tail)
+// Polynomial coefficients for the erf(x), 1/8 <= |x| < 1/4
+data8 0x93086CBD21ED3962, 0x00003FCA //A13 = 1.2753071968462837024755878679e-16
+data8 0x83CB5045A6D4B419, 0x00003FCF //A12 = 3.6580237062957773626379648530e-15
+data8 0x8FCDB723209690EB, 0x0000BFD3 //A11 = -6.3861616307180801527566117146e-14
+data8 0xCAA173F680B5D56B, 0x0000BFD7 //A10 = -1.4397775466324880354578008779e-12
+data8 0xF0CEA934AD6AC013, 0x00003FDB //A9 = 2.7376616955640415767655526857e-11
+data8 0x81C69F9D0B5AB8EE, 0x00003FE0 //A8 = 4.7212187567505249115688961488e-10
+data8 0xA8B590298C20A194, 0x0000BFE4 //A7 = -9.8201697105565925460801441797e-09
+data8 0x84F3DE72AC964615, 0x0000BFE8 //A6 = -1.2382176987480830706988411266e-07
+data8 0xC01A1398868CC4BD, 0x00003FEC //A5 = 2.8625408039722670291121341583e-06
+data8 0xCC43247F4410C54A, 0x00003FEF //A4 = 2.4349960762505993017186935493e-05
+LOCAL_OBJECT_END(_0p125_to_0p25_data_tail)
+
+LOCAL_OBJECT_START(_0p25_to_0p5_data_tail)
+// Polynomial coefficients for the erf(x), 1/4 <= |x| < 1/2
+data8 0x8CEAC59AF361B78A, 0x0000BFD6 //A13 = -5.0063802958258679384986669123e-13
+data8 0x9BC67404F348C0CE, 0x00003FDB //A12 = 1.7709590771868743572061278273e-11
+data8 0xF4B5D0348AFAAC7A, 0x00003FDB //A11 = 2.7820329729584630464848160970e-11
+data8 0x83AB447FF619DA4A, 0x0000BFE2 //A10 = -1.9160363295631539615395477207e-09
+data8 0x82115AB487202E7B, 0x00003FE0 //A9 = 4.7318386460142606822119637959e-10
+data8 0xB84D5B0AE17054AA, 0x00003FE8 //A8 = 1.7164477188916895004843908951e-07
+data8 0xB2E085C1C4AA06E5, 0x0000BFE9 //A7 = -3.3318445266863554512523957574e-07
+data8 0xCD3CA2E6C3971666, 0x0000BFEE //A6 = -1.2233070175554502732980949519e-05
+data8 0xBA445C53F8DD40E6, 0x00003FF0 //A5 = 4.4409521535330413551781808621e-05
+data8 0xAA94D5E68033B764, 0x00003FF4 //A4 = 6.5071635765452563856926608000e-04
+LOCAL_OBJECT_END(_0p25_to_0p5_data_tail)
+
+LOCAL_OBJECT_START(_0p5_to_1_data_tail)
+// Polynomial coefficients for the erf(x), 1/2 <= |x| < 1
+data8 0x9ED99EDF111CB785, 0x0000BFE4 //A13 = -9.2462916180079278241704711522e-09
+data8 0xDEAF7539AE2FB062, 0x0000BFE5 //A12 = -2.5923990465973151101298441139e-08
+data8 0xA392D5E5CC9DB1A7, 0x00003FE9 //A11 = 3.0467952847327075747032372101e-07
+data8 0xC311A7619B96CA1A, 0x00003FE8 //A10 = 1.8167212632079596881709988649e-07
+data8 0x82082E6B6A93F116, 0x0000BFEE //A9 = -7.7505086843257228386931766018e-06
+data8 0x96D9997CF326A36D, 0x00003FEE //A8 = 8.9913605625817479172071008270e-06
+data8 0x97057D85DCB0ED99, 0x00003FF2 //A7 = 1.4402527482741758767786898553e-04
+data8 0xDC23BCB3599C0490, 0x0000BFF3 //A6 = -4.1988296144950673955519083419e-04
+data8 0xDA150C4867208A81, 0x0000BFF5 //A5 = -1.6638352864915033417887831090e-03
+data8 0x9A4DAF550A2CC29A, 0x00003FF8 //A4 = 9.4179355839141698591817907680e-03
+LOCAL_OBJECT_END(_0p5_to_1_data_tail)
+
+LOCAL_OBJECT_START(_1_to_2_data_tail)
+// Polynomial coefficients for the erf(x), 1 <= |x| < 2.0
+data8 0x969EAC5C7B46CAB9, 0x00003FEF //A13 = 1.7955281439310148162059582795e-05
+data8 0xA2ED832912E9FCD9, 0x00003FF1 //A12 = 7.7690020847111408916570845775e-05
+data8 0x85677C39C48E43E7, 0x0000BFF3 //A11 = -2.5444839340796031538582511806e-04
+data8 0xC2DAFA91683DAAE4, 0x0000BFF1 //A10 = -9.2914288456063075386925076097e-05
+data8 0xE01C061CBC6A2825, 0x00003FF5 //A9 = 1.7098195515864039518892834211e-03
+data8 0x9AD7271CAFD01C78, 0x0000BFF6 //A8 = -2.3626776207372761518718893636e-03
+data8 0x9B6B9D30EDD5F4FF, 0x0000BFF7 //A7 = -4.7430532011804570628999212874e-03
+data8 0x9E51EB9623F1D446, 0x00003FF9 //A6 = 1.9326171998839772791190405201e-02
+data8 0xF391B935C12546DE, 0x0000BFF8 //A5 = -1.4866286152953671441682166195e-02
+data8 0xB6AD4AE850DBF526, 0x0000BFFA //A4 = -4.4598858458861014323191919669e-02
+LOCAL_OBJECT_END(_1_to_2_data_tail)
+
+LOCAL_OBJECT_START(_2_to_3p25_data_tail)
+// Polynomial coefficients for the erf(x), 2 <= |x| < 3.25
+data8 0x847C24DAC7C7558B, 0x00003FF5 //A13 = 1.0107798565424606512130100541e-03
+data8 0xCB6340EAF02C3DF8, 0x00003FF8 //A12 = 1.2413800617425931997420375435e-02
+data8 0xB5163D252DBBC107, 0x0000BFF9 //A11 = -2.2105330871844825370020459523e-02
+data8 0x82FF9C0B68E331E4, 0x00003FF9 //A10 = 1.5991024756001692140897408128e-02
+data8 0xE9519E4A49752E04, 0x00003FF7 //A9 = 7.1203253651891723548763348088e-03
+data8 0x8D52F11B7AE846D9, 0x0000BFFA //A8 = -3.4502927613795425888684181521e-02
+data8 0xCCC5A3E32BC6FA30, 0x00003FFA //A7 = 4.9993171868423886228679106871e-02
+data8 0xC1791AD8284A1919, 0x0000BFFA //A6 = -4.7234635220336795411997070641e-02
+data8 0x853DAAA35A8A3C18, 0x00003FFA //A5 = 3.2529512934760303976755163452e-02
+data8 0x88E42D8F47FAB60E, 0x0000BFF9 //A4 = -1.6710366233609742619461063050e-02
+LOCAL_OBJECT_END(_2_to_3p25_data_tail)
+
+LOCAL_OBJECT_START(_4_to_6p53_data_tail)
+// Polynomial coefficients for the erf(x), 4 <= |x| < 6.53
+data8 0xD8235ABF08B8A6D1, 0x00003FEE //A13 = 1.2882834877224764938429832586e-05
+data8 0xAEDF44F9C77844C2, 0x0000BFEC //A12 = -2.6057980393716019511497492890e-06
+data8 0xCCD5490956A4FCFD, 0x00003FEA //A11 = 7.6306293047300300284923464089e-07
+data8 0xF71AF0126EE26AEA, 0x0000BFE8 //A10 = -2.3013467500738417953513680935e-07
+data8 0xE4CE68089858AC20, 0x00003FE6 //A9 = 5.3273112263151109935867439775e-08
+data8 0xBD15106FBBAEE593, 0x0000BFE4 //A8 = -1.1006037358336556244645388790e-08
+data8 0x8BBF9A5769B6E480, 0x00003FE2 //A7 = 2.0336075804332107927300019116e-09
+data8 0xB049D845D105E302, 0x0000BFDF //A6 = -3.2066683399502826067820249320e-10
+data8 0xBAC69B3F0DFE5483, 0x00003FDC //A5 = 4.2467901578369360007795282687e-11
+data8 0xA29C398F83F8A0D1, 0x0000BFD9 //A4 = -4.6216613698438694005327544047e-12
+LOCAL_OBJECT_END(_4_to_6p53_data_tail)
+
+LOCAL_OBJECT_START(_3p25_to_4_data_tail)
+// Polynomial coefficients for the erf(x), 3.25 <= |x| < 4
+data8 0x95BE1BEAD738160F, 0x00003FF2 //A13 = 1.4280568455209843005829620687e-04
+data8 0x8108C8FFAC0F0B21, 0x0000BFF4 //A12 = -4.9222685622046459346377033307e-04
+data8 0xD72A7FAEE7832BBE, 0x00003FF4 //A11 = 8.2079319302109644436194651098e-04
+data8 0x823AB4281CA7BBE7, 0x0000BFF5 //A10 = -9.9357079675971109178261577703e-04
+data8 0xFA1232D476048D11, 0x00003FF4 //A9 = 9.5394549599882496825916138915e-04
+data8 0xC463D7AF88025FB2, 0x0000BFF4 //A8 = -7.4916843357898101689031755368e-04
+data8 0xFEBE32B6B379D072, 0x00003FF3 //A7 = 4.8588363901002111193445057206e-04
+data8 0x882829BB68409BF3, 0x0000BFF3 //A6 = -2.5969865184916169002074135516e-04
+data8 0xED2F886E29DAAB09, 0x00003FF1 //A5 = 1.1309894347742479284610149994e-04
+data8 0xA4C07129436555B2, 0x0000BFF0 //A4 = -3.9279872584973887163830479579e-05
+LOCAL_OBJECT_END(_3p25_to_4_data_tail)
+
+
+LOCAL_OBJECT_START(_0_to_1o8_data)
+// Polynomial coefficients for the erf(x), 0.0 <= |x| < 0.125
+data8 0x3FF20DD750429B6D, 0x3C71AE3A8DDFFEDE //A1H, A1L
+data8 0xF8B0DACE42525CC2, 0x0000BFEE //A15
+data8 0xFCD02E1BF0EC2C37, 0x00003FF1 //A13
+data8 0xE016D968FE473B5E, 0x0000BFF4 //A11
+data8 0xAB2DE68711BF5A79, 0x00003FF7 //A9
+data8 0xDC16718944518309, 0x0000BFF9 //A7
+data8 0xE71790D0215F0C8F, 0x00003FFB //A5
+data8 0xC093A3581BCF3612, 0x0000BFFD //A3
+LOCAL_OBJECT_END(_0_to_1o8_data)
+
+
+LOCAL_OBJECT_START(_denorm_data)
+data8 0x3FF20DD750429B6D //A1H = 1.1283791670955125585606992900e+00
+data8 0x3C71AE3A914FED80 //A1L = 1.5335459613165880745599768129e-17
+LOCAL_OBJECT_END(_denorm_data)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(erfl)
+
+{ .mfi
+ alloc r32 = ar.pfs, 0, 21, 0, 0
+ fmerge.se fArgAbsNorm = f1, f8 // normalized x (1.0 <= x < 2.0)
+ addl rSignBit = 0x20000, r0 // Set sign bit for exponent
+}
+{ .mlx
+ addl rDataPtr = @ltoff(erfl_data), gp // Get common data ptr
+ movl r1p5 = 0x3FF8000000000000 // 1.5 in dbl repres.
+};;
+
+{ .mfi
+ getf.exp rArgExp = f8 // Get arg exponent
+ fclass.m p6,p0 = f8, 0xEF // Filter 0, denormals and specials
+ // 0xEF = @qnan|@snan|@pos|@neg|@zero|@unorm|@inf
+ addl rBias = 0xfffc, r0 // Value to subtract from exp
+ // to get actual interval number
+}
+{ .mfi
+ ld8 rDataPtr = [rDataPtr] // Get real common data pointer
+ fma.s1 fArgSqr = f8, f8, f0 // x^2 (for [0;1/8] path)
+ addl r2to4 = 0x10000, r0 // unbiased exponent
+ // for [2;4] binary interval
+};;
+
+{ .mfi
+ getf.sig rArgSig = f8 // Get arg significand
+ fcmp.lt.s1 p15, p14 = f8, f0 // Is arg negative/positive?
+ addl rSaturation = 0xd0e, r0 // First 12 bits of
+ // saturation value signif.
+}
+{ .mfi
+ setf.d f1p5 = r1p5 // 1.5 construction
+ fma.s1 f2p0 = f1,f1,f1 // 2.0 construction
+ addl r3p25Sign = 0xd00, r0 // First 12 bits of
+ // 3.25 value signif.
+};;
+
+{ .mfi
+ addl rTailDataPtr = 0x700, rDataPtr // Pointer to "tail" data
+ nop.f 0
+ andcm rArgExp = rArgExp, rSignBit // Remove sign of exp
+}
+{ .mfb
+ addl rTiny = 0xf000, r0 // Tiny value for saturation path
+ nop.f 0
+(p6) br.cond.spnt erfl_spec // Branch to zero, denorm & specs
+};;
+
+{ .mfi
+ sub rInterval = rArgExp, rBias // Get actual interval number
+ nop.f 0
+ shr.u rArgSig = rArgSig, 52 // Leave only 12 bits of sign.
+}
+{ .mfi
+ adds rShiftedDataPtr = 0x10, rDataPtr // Second ptr to data
+ nop.f 0
+ cmp.eq p8, p10 = r2to4, rArgExp // If exp is in 2to4 interval?
+};;
+
+{ .mfi
+(p8) cmp.le p8, p10 = r3p25Sign, rArgSig // If sign. is greater
+ // than 1.25? (means arg is in [3.25;4] interval)
+ nop.f 0
+ shl rOffset = rInterval, 8 // Make offset from
+ // interval number
+}
+{ .mfi
+ cmp.gt p9, p0 = 0x0, rInterval // If interval is less than 0
+ // (means arg is in [0; 1/8])
+ nop.f 0
+ cmp.eq p7, p0 = 0x5, rInterval // If arg is in [4:8] interv.?
+};;
+
+{ .mfi
+(p8) adds rOffset = 0x200, rOffset // Add additional offset
+ // if arg is in [3.25;4] (another data set)
+ fma.s1 fArgCube = fArgSqr, f8, f0 // x^3 (for [0;1/8] path)
+ shl rTailOffset = rInterval, 7 // Make offset to "tail" data
+ // from interval number
+}
+{ .mib
+ setf.exp fTiny = rTiny // Construct "tiny" value
+ // for saturation path
+ cmp.ltu p11, p0 = 0x5, rInterval // if arg > 8
+(p9) br.cond.spnt _0_to_1o8
+};;
+
+{ .mfi
+ add rAddr1 = rDataPtr, rOffset // Get address for
+ // interval data
+ nop.f 0
+ shl rTailAddOffset = rInterval, 5 // Offset to interval
+ // "tail" data
+}
+{ .mib
+ add rAddr2 = rShiftedDataPtr, rOffset // Get second
+ // address for interval data
+(p7) cmp.leu p11, p0 = rSaturation, rArgSig // if arg is
+ // in [6.53;8] interval
+(p11) br.cond.spnt _saturation // Branch to Saturation path
+};;
+
+{ .mmi
+ ldfe fA3 = [rAddr1], 0x90 // Load A3
+ ldfpd fA2H, fA2L = [rAddr2], 16 // Load A2High, A2Low
+ add rTailOffset = rTailOffset, rTailAddOffset // "Tail" offset
+};;
+
+{ .mmi
+ ldfe fA20 = [rAddr1], 16 // Load A20
+ ldfpd fA1H, fA1L = [rAddr2], 16 // Load A1High, A1Low
+(p8) adds rTailOffset = 0x140, rTailOffset // Additional offset
+ // for [3.24;4] interval
+};;
+
+{ .mmi
+ ldfe fA19 = [rAddr1], 16 // Load A19
+ ldfpd fA0H, fA0L = [rAddr2], 16 // Load A0High, A0Low
+ add rTailAddr1 = rTailDataPtr, rTailOffset // First tail
+ // data address
+};;
+
+.pred.rel "mutex",p8,p10
+{ .mfi
+ ldfe fA18 = [rAddr1], 16 // Load A18
+(p8) fms.s1 fArgAbsNorm = fArgAbsNorm, f1, f2p0 // Add 2.0
+ // to normalized arg (for [3.24;4] interval)
+ adds rTailAddr2 = 0x10, rTailAddr1 // First tail
+ // data address
+}
+{ .mfi
+ ldfe fA25 = [rAddr2], 16 // Load A25
+(p10) fms.s1 fArgAbsNorm = fArgAbsNorm, f1, f1p5 // Add 1.5
+ // to normalized arg
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA17 = [rAddr1], 16 // Load A17
+ ldfe fA24 = [rAddr2], 16 // Load A24
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA16 = [rAddr1], 16 // Load A16
+ ldfe fA23 = [rAddr2], 16 // Load A23
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA15 = [rAddr1], 16 // Load A15
+ ldfe fA22 = [rAddr2], 16 // Load A22
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA14 = [rAddr1], 16 // Load A14
+ ldfe fA21 = [rAddr2], 16 // Load A21
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe fA13 = [rTailAddr1], 32 // Load A13
+ fms.s1 fArgAbsNorm2 = fArgAbsNorm, fArgAbsNorm, f0 // x^2
+ nop.i 0
+}
+{ .mfi
+ ldfe fA12 = [rTailAddr2], 32 // Load A12
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe fA11 = [rTailAddr1], 32 // Load A11
+ fma.s1 fRes3H = fA3, fArgAbsNorm, fA2H // (A3*x+A2)*x^2
+ nop.i 0
+}
+{ .mfi
+ ldfe fA10 = [rTailAddr2], 32 // Load A10
+ fma.s1 fTH = fA3, fArgAbsNorm, f0 // (A3*x+A2)*x^2
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe fA9 = [rTailAddr1], 32 // Load A9
+ fma.s1 fTT2 = fA1L, fArgAbsNorm, f0 // A1*x+A0
+ nop.i 0
+}
+{ .mfi
+ ldfe fA8 = [rTailAddr2], 32 // Load A8
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA7 = [rTailAddr1], 32 // Load A7
+ ldfe fA6 = [rTailAddr2], 32 // Load A6
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA5 = [rTailAddr1], 32 // Load A5
+ ldfe fA4 = [rTailAddr2], 32 // Load A4
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fArgAbsNorm2L = fArgAbsNorm, fArgAbsNorm, fArgAbsNorm2
+ // Low part of x^2 (delta)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fArgAbsNorm4 = fArgAbsNorm2, fArgAbsNorm2, f0 // x^4
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fRes3L = fA2H, f1, fRes3H // // (A3*x+A2)*x^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fArgAbsNorm3 = fArgAbsNorm2, fArgAbsNorm, f0 // x^3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fTH2 = fA1H, fArgAbsNorm, fTT2 // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA23 = fA24, fArgAbsNorm, fA23 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA21 = fA22, fArgAbsNorm, fA21 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA12 = fA13, fArgAbsNorm, fA12 // Polynomial tail
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes3L = fRes3L, f1, fTH // (A3*x+A2)*x^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA19 = fA20, fArgAbsNorm, fA19 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1H = fTH2, f1, fA0H // A1*x+A0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fTL2 = fA1H, fArgAbsNorm, fTH2 // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA8 = fA9, fArgAbsNorm, fA8 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA10 = fA11, fArgAbsNorm, fA10 // Polynomial tail
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA16, fArgAbsNorm, fA15 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA18, fArgAbsNorm, fA17 // Polynomial tail
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fms.s1 fArgAbsNorm11 = fArgAbsNorm4, fArgAbsNorm4, f0 // x^8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA5, fArgAbsNorm, fA4 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes3L = fRes3L, f1, fA2L // (A3*x+A2)*x^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA6 = fA7, fArgAbsNorm, fA6 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fTL2 = fTL2, f1, fTT2 // A1*x+A0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fRes1L = fA0H, f1, fRes1H // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA23 = fA25, fArgAbsNorm2, fA23 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA12 = fA14, fArgAbsNorm2, fA12 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA19 = fA21, fArgAbsNorm2, fA19 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA8 = fA10, fArgAbsNorm2, fA8 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA17, fArgAbsNorm2, fA15 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fArgAbsNorm11 = fArgAbsNorm11, fArgAbsNorm3, f0 // x^11
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fTT = fRes3L, fArgAbsNorm2, f0 // (A3*x+A2)*x^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA6, fArgAbsNorm2, fA4 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1L = fRes1L, f1, fTH2 // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA19 = fA23, fArgAbsNorm4, fA19 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA8 = fA12, fArgAbsNorm4, fA8 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fTT = fRes3H, fArgAbsNorm2L, fTT // (A3*x+A2)*x^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1L = fRes1L, f1, fTL2 // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA19, fArgAbsNorm4, fA15 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA8, fArgAbsNorm4, fA4 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes2H = fRes3H, fArgAbsNorm2, fTT // (A3*x+A2)*x^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1L = fRes1L, f1, fA0L // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes4 = fA15, fArgAbsNorm11, fA4 // Result of
+ // polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fRes2L = fRes3H, fArgAbsNorm2, fRes2H // (A3*x+A2)*x^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fResH = fRes2H, f1, fRes1H // High result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1L = fRes4, fArgAbsNorm4, fRes1L // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes2L = fRes2L, f1, fTT // (A3*x+A2)*x^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fResL = fRes1H, f1, fResH // Low result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1L = fRes1L, f1, fRes2L // Low result
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fResL = fResL, f1, fRes2H // Low result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fneg fResH = fResH // Invert high result if arg is neg.
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fResL = fResL, f1, fRes1L // Low result
+ nop.i 0
+};;
+
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p14) fma.s0 f8 = fResH, f1, fResL // Add high and low results
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p15) fms.s0 f8 = fResH, f1, fResL // Add high and low results
+ br.ret.sptk b0 // Main path return
+};;
+
+// satiration path ////////////////////////////////////////////////////////////
+_saturation:
+
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p14) fms.s0 f8 = f1, f1, fTiny // Saturation result r = 1-tiny
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+(p15) fnma.s0 f8 = f1, f1, fTiny // Saturation result r = tiny-1
+ br.ret.sptk b0 // Saturation path return
+};;
+
+
+// 0, denormals and special IEEE numbers path /////////////////////////////////
+erfl_spec:
+
+{ .mfi
+ addl rDataPtr = 0xBE0, rDataPtr // Ptr to denormals coeffs
+ fclass.m p6,p0 = f8, 0x23 // To filter infinities
+ // 0x23 = @pos|@neg|@inf
+ nop.i 0
+};;
+
+{ .mfi
+ ldfpd fA1H, fA1L = [rDataPtr] // Load denormals coeffs A1H, A1L
+ fclass.m p7,p0 = f8, 0xC7 // To filter NaNs & Zeros
+ // 0xC7 = @pos|@neg|@zero|@qnan|@snan
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+(p6) fmerge.s f8 = f8, f1 // +/-1 for INF args
+(p6) br.ret.spnt b0 // exit for x = INF
+};;
+
+{ .mfb
+ nop.m 0
+(p7) fma.s0 f8 = f8, f1, f8 // +/-0 for 0 args
+ // and NaNs for NaNs
+(p7) br.ret.spnt b0 // exit for x = NaN or +/-0
+};;
+
+{ .mfi
+ nop.m 0
+ fnorm.s0 f8 = f8 // Normalize arg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fRes1H = f8, fA1H, f0 // HighRes
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fRes1L = f8, fA1L, f0 // LowRes
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fRes1Hd = f8, fA1H, fRes1H // HighRes delta
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes1L, f1, fRes1Hd // LowRes+HighRes delta
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = f8, f8, fRes // r=x^2+r
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ fma.s0 f8 = fRes, f1, fRes1H // res = r+ResHigh
+ br.ret.sptk b0 // 0, denormals, specials return
+};;
+
+
+// 0 < |x| < 1/8 path /////////////////////////////////////////////////////////
+_0_to_1o8:
+
+{ .mmi
+ adds rAddr1 = 0xB60, rDataPtr // Ptr 1 to coeffs
+ adds rAddr2 = 0xB80, rDataPtr // Ptr 2 to coeffs
+ nop.i 0
+};;
+
+{ .mmi
+ ldfpd fA1H, fA1L = [rAddr1], 16 // Load A1High, A1Low
+ ldfe fA13 = [rAddr2], 16 // Load A13
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA15 = [rAddr1], 48 // Load A15
+ ldfe fA11 = [rAddr2], 32 // Load A11
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA9 = [rAddr1], 32 // Load A9
+ ldfe fA7 = [rAddr2], 32 // Load A7
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA5 = [rAddr1] // Load A5
+ ldfe fA3 = [rAddr2] // Load A3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fRes1H = f8, fA1H, f0 // x*(A1H+A1L)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fRes1L = f8, fA1L, f0 // x*(A1H+A1L)
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA13, fArgSqr, fA11 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fArgFour = fArgSqr, fArgSqr, f0 // a^4
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA3 = fA5, fArgSqr, fA3 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fA9, fArgSqr, fA7 // Polynomial tail
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fms.s1 fRes1Hd = f8, fA1H, fRes1H // x*(A1H+A1L) delta
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA15, fArgFour, fA11 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA3 = fA7, fArgFour, fA3 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fArgEight = fArgFour, fArgFour, f0 // a^8
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f8 = fRes1L, f1, fRes1Hd // x*(A1H+A1L)
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fA11, fArgEight, fA3 //Polynomial tail result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 f8 = fRes, fArgCube, f8 // (Polynomial tail)*x^3
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ fma.s0 f8 = f8, f1, fRes1H // (Polynomial tail)*x^3 +
+ // + x*(A1H+A1L)
+ br.ret.sptk b0 // [0;1/8] interval return
+};;
+
+
+GLOBAL_LIBM_END(erfl)
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/s_expm1.S b/libc/sysdeps/ia64/fpu/s_expm1.S
new file mode 100644
index 000000000..09a22bbbd
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_expm1.S
@@ -0,0 +1,886 @@
+.file "exp_m1.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial Version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 07/07/01 Improved speed of all paths
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 11/20/02 Improved speed, algorithm based on exp
+// 03/31/05 Reformatted delimiters between data tables
+
+// API
+//==============================================================
+// double expm1(double)
+
+// Overview of operation
+//==============================================================
+// 1. Inputs of Nan, Inf, Zero, NatVal handled with special paths
+//
+// 2. |x| < 2^-60
+// Result = x, computed by x + x*x to handle appropriate flags and rounding
+//
+// 3. 2^-60 <= |x| < 2^-2
+// Result determined by 13th order Taylor series polynomial
+// expm1f(x) = x + Q2*x^2 + ... + Q13*x^13
+//
+// 4. x < -48.0
+// Here we know result is essentially -1 + eps, where eps only affects
+// rounded result. Set I.
+//
+// 5. x >= 709.7827
+// Result overflows. Set I, O, and call error support
+//
+// 6. 2^-2 <= x < 709.7827 or -48.0 <= x < -2^-2
+// This is the main path. The algorithm is described below:
+
+// Take the input x. w is "how many log2/128 in x?"
+// w = x * 128/log2
+// n = int(w)
+// x = n log2/128 + r + delta
+
+// n = 128M + index_1 + 2^4 index_2
+// x = M log2 + (log2/128) index_1 + (log2/8) index_2 + r + delta
+
+// exp(x) = 2^M 2^(index_1/128) 2^(index_2/8) exp(r) exp(delta)
+// Construct 2^M
+// Get 2^(index_1/128) from table_1;
+// Get 2^(index_2/8) from table_2;
+// Calculate exp(r) by series by 5th order polynomial
+// r = x - n (log2/128)_high
+// delta = - n (log2/128)_low
+// Calculate exp(delta) as 1 + delta
+
+
+// Special values
+//==============================================================
+// expm1(+0) = +0.0
+// expm1(-0) = -0.0
+
+// expm1(+qnan) = +qnan
+// expm1(-qnan) = -qnan
+// expm1(+snan) = +qnan
+// expm1(-snan) = -qnan
+
+// expm1(-inf) = -1.0
+// expm1(+inf) = +inf
+
+// Overflow and Underflow
+//=======================
+// expm1(x) = largest double normal when
+// x = 709.7827 = 40862e42fefa39ef
+//
+// Underflow is handled as described in case 2 above.
+
+
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f9 -> f15, f32 -> f75
+
+// General registers used:
+// r14 -> r40
+
+// Predicate registers used:
+// p6 -> p15
+
+// Assembly macros
+//==============================================================
+
+rRshf = r14
+rAD_TB1 = r15
+rAD_T1 = r15
+rAD_TB2 = r16
+rAD_T2 = r16
+rAD_Ln2_lo = r17
+rAD_P = r17
+
+rN = r18
+rIndex_1 = r19
+rIndex_2_16 = r20
+
+rM = r21
+rBiased_M = r21
+rIndex_1_16 = r22
+rSignexp_x = r23
+rExp_x = r24
+rSig_inv_ln2 = r25
+
+rAD_Q1 = r26
+rAD_Q2 = r27
+rTmp = r27
+rExp_bias = r28
+rExp_mask = r29
+rRshf_2to56 = r30
+
+rGt_ln = r31
+rExp_2tom56 = r31
+
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+fRSHF_2TO56 = f6
+fINV_LN2_2TO63 = f7
+fW_2TO56_RSH = f9
+f2TOM56 = f11
+fP5 = f12
+fP54 = f50
+fP5432 = f50
+fP4 = f13
+fP3 = f14
+fP32 = f14
+fP2 = f15
+
+fLn2_by_128_hi = f33
+fLn2_by_128_lo = f34
+
+fRSHF = f35
+fNfloat = f36
+fW = f37
+fR = f38
+fF = f39
+
+fRsq = f40
+fRcube = f41
+
+f2M = f42
+fS1 = f43
+fT1 = f44
+
+fMIN_DBL_OFLOW_ARG = f45
+fMAX_DBL_MINUS_1_ARG = f46
+fMAX_DBL_NORM_ARG = f47
+fP_lo = f51
+fP_hi = f52
+fP = f53
+fS = f54
+
+fNormX = f56
+
+fWre_urm_f8 = f57
+
+fGt_pln = f58
+fTmp = f58
+
+fS2 = f59
+fT2 = f60
+fSm1 = f61
+
+fXsq = f62
+fX6 = f63
+fX4 = f63
+fQ7 = f64
+fQ76 = f64
+fQ7654 = f64
+fQ765432 = f64
+fQ6 = f65
+fQ5 = f66
+fQ54 = f66
+fQ4 = f67
+fQ3 = f68
+fQ32 = f68
+fQ2 = f69
+fQD = f70
+fQDC = f70
+fQDCBA = f70
+fQDCBA98 = f70
+fQDCBA98765432 = f70
+fQC = f71
+fQB = f72
+fQBA = f72
+fQA = f73
+fQ9 = f74
+fQ98 = f74
+fQ8 = f75
+
+// Data tables
+//==============================================================
+
+RODATA
+.align 16
+
+// ************* DO NOT CHANGE ORDER OF THESE TABLES ********************
+
+// double-extended 1/ln(2)
+// 3fff b8aa 3b29 5c17 f0bb be87fed0691d3e88
+// 3fff b8aa 3b29 5c17 f0bc
+// For speed the significand will be loaded directly with a movl and setf.sig
+// and the exponent will be bias+63 instead of bias+0. Thus subsequent
+// computations need to scale appropriately.
+// The constant 128/ln(2) is needed for the computation of w. This is also
+// obtained by scaling the computations.
+//
+// Two shifting constants are loaded directly with movl and setf.d.
+// 1. fRSHF_2TO56 = 1.1000..00 * 2^(63-7)
+// This constant is added to x*1/ln2 to shift the integer part of
+// x*128/ln2 into the rightmost bits of the significand.
+// The result of this fma is fW_2TO56_RSH.
+// 2. fRSHF = 1.1000..00 * 2^(63)
+// This constant is subtracted from fW_2TO56_RSH * 2^(-56) to give
+// the integer part of w, n, as a floating-point number.
+// The result of this fms is fNfloat.
+
+
+LOCAL_OBJECT_START(exp_Table_1)
+data8 0x40862e42fefa39f0 // smallest dbl overflow arg
+data8 0xc048000000000000 // approx largest arg for minus one result
+data8 0x40862e42fefa39ef // largest dbl arg to give normal dbl result
+data8 0x0 // pad
+data8 0xb17217f7d1cf79ab , 0x00003ff7 // ln2/128 hi
+data8 0xc9e3b39803f2f6af , 0x00003fb7 // ln2/128 lo
+//
+// Table 1 is 2^(index_1/128) where
+// index_1 goes from 0 to 15
+//
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x80B1ED4FD999AB6C , 0x00003FFF
+data8 0x8164D1F3BC030773 , 0x00003FFF
+data8 0x8218AF4373FC25EC , 0x00003FFF
+data8 0x82CD8698AC2BA1D7 , 0x00003FFF
+data8 0x8383594EEFB6EE37 , 0x00003FFF
+data8 0x843A28C3ACDE4046 , 0x00003FFF
+data8 0x84F1F656379C1A29 , 0x00003FFF
+data8 0x85AAC367CC487B15 , 0x00003FFF
+data8 0x8664915B923FBA04 , 0x00003FFF
+data8 0x871F61969E8D1010 , 0x00003FFF
+data8 0x87DB357FF698D792 , 0x00003FFF
+data8 0x88980E8092DA8527 , 0x00003FFF
+data8 0x8955EE03618E5FDD , 0x00003FFF
+data8 0x8A14D575496EFD9A , 0x00003FFF
+data8 0x8AD4C6452C728924 , 0x00003FFF
+LOCAL_OBJECT_END(exp_Table_1)
+
+// Table 2 is 2^(index_1/8) where
+// index_2 goes from 0 to 7
+LOCAL_OBJECT_START(exp_Table_2)
+data8 0x8000000000000000 , 0x00003FFF
+data8 0x8B95C1E3EA8BD6E7 , 0x00003FFF
+data8 0x9837F0518DB8A96F , 0x00003FFF
+data8 0xA5FED6A9B15138EA , 0x00003FFF
+data8 0xB504F333F9DE6484 , 0x00003FFF
+data8 0xC5672A115506DADD , 0x00003FFF
+data8 0xD744FCCAD69D6AF4 , 0x00003FFF
+data8 0xEAC0C6E7DD24392F , 0x00003FFF
+LOCAL_OBJECT_END(exp_Table_2)
+
+
+LOCAL_OBJECT_START(exp_p_table)
+data8 0x3f8111116da21757 //P5
+data8 0x3fa55555d787761c //P4
+data8 0x3fc5555555555414 //P3
+data8 0x3fdffffffffffd6a //P2
+LOCAL_OBJECT_END(exp_p_table)
+
+LOCAL_OBJECT_START(exp_Q1_table)
+data8 0x3de6124613a86d09 // QD = 1/13!
+data8 0x3e21eed8eff8d898 // QC = 1/12!
+data8 0x3ec71de3a556c734 // Q9 = 1/9!
+data8 0x3efa01a01a01a01a // Q8 = 1/8!
+data8 0x8888888888888889,0x3ff8 // Q5 = 1/5!
+data8 0xaaaaaaaaaaaaaaab,0x3ffc // Q3 = 1/3!
+data8 0x0,0x0 // Pad to avoid bank conflicts
+LOCAL_OBJECT_END(exp_Q1_table)
+
+LOCAL_OBJECT_START(exp_Q2_table)
+data8 0x3e5ae64567f544e4 // QB = 1/11!
+data8 0x3e927e4fb7789f5c // QA = 1/10!
+data8 0x3f2a01a01a01a01a // Q7 = 1/7!
+data8 0x3f56c16c16c16c17 // Q6 = 1/6!
+data8 0xaaaaaaaaaaaaaaab,0x3ffa // Q4 = 1/4!
+data8 0x8000000000000000,0x3ffe // Q2 = 1/2!
+LOCAL_OBJECT_END(exp_Q2_table)
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(expm1)
+
+{ .mlx
+ getf.exp rSignexp_x = f8 // Must recompute if x unorm
+ movl rSig_inv_ln2 = 0xb8aa3b295c17f0bc // signif of 1/ln2
+}
+{ .mlx
+ addl rAD_TB1 = @ltoff(exp_Table_1), gp
+ movl rRshf_2to56 = 0x4768000000000000 // 1.10000 2^(63+56)
+}
+;;
+
+// We do this fnorm right at the beginning to normalize
+// any input unnormals so that SWA is not taken.
+{ .mfi
+ ld8 rAD_TB1 = [rAD_TB1]
+ fclass.m p6,p0 = f8,0x0b // Test for x=unorm
+ mov rExp_mask = 0x1ffff
+}
+{ .mfi
+ mov rExp_bias = 0xffff
+ fnorm.s1 fNormX = f8
+ mov rExp_2tom56 = 0xffff-56
+}
+;;
+
+// Form two constants we need
+// 1/ln2 * 2^63 to compute w = x * 1/ln2 * 128
+// 1.1000..000 * 2^(63+63-7) to right shift int(w) into the significand
+
+{ .mfi
+ setf.sig fINV_LN2_2TO63 = rSig_inv_ln2 // form 1/ln2 * 2^63
+ fclass.m p8,p0 = f8,0x07 // Test for x=0
+ nop.i 0
+}
+{ .mlx
+ setf.d fRSHF_2TO56 = rRshf_2to56 // Form 1.100 * 2^(63+56)
+ movl rRshf = 0x43e8000000000000 // 1.10000 2^63 for rshift
+}
+;;
+
+{ .mfi
+ setf.exp f2TOM56 = rExp_2tom56 // form 2^-56 for scaling Nfloat
+ fclass.m p9,p0 = f8,0x22 // Test for x=-inf
+ add rAD_TB2 = 0x140, rAD_TB1 // Point to Table 2
+}
+{ .mib
+ add rAD_Q1 = 0x1e0, rAD_TB1 // Point to Q table for small path
+ add rAD_Ln2_lo = 0x30, rAD_TB1 // Point to ln2_by_128_lo
+(p6) br.cond.spnt EXPM1_UNORM // Branch if x unorm
+}
+;;
+
+EXPM1_COMMON:
+{ .mfi
+ ldfpd fMIN_DBL_OFLOW_ARG, fMAX_DBL_MINUS_1_ARG = [rAD_TB1],16
+ fclass.m p10,p0 = f8,0x1e1 // Test for x=+inf, NaN, NaT
+ add rAD_Q2 = 0x50, rAD_Q1 // Point to Q table for small path
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p8) br.ret.spnt b0 // Exit for x=0, return x
+}
+;;
+
+{ .mfi
+ ldfd fMAX_DBL_NORM_ARG = [rAD_TB1],16
+ nop.f 0
+ and rExp_x = rExp_mask, rSignexp_x // Biased exponent of x
+}
+{ .mfb
+ setf.d fRSHF = rRshf // Form right shift const 1.100 * 2^63
+(p9) fms.d.s0 f8 = f0,f0,f1 // quick exit for x=-inf
+(p9) br.ret.spnt b0
+}
+;;
+
+{ .mfi
+ ldfpd fQD, fQC = [rAD_Q1], 16 // Load coeff for small path
+ nop.f 0
+ sub rExp_x = rExp_x, rExp_bias // True exponent of x
+}
+{ .mfb
+ ldfpd fQB, fQA = [rAD_Q2], 16 // Load coeff for small path
+(p10) fma.d.s0 f8 = f8, f1, f0 // For x=+inf, NaN, NaT
+(p10) br.ret.spnt b0 // Exit for x=+inf, NaN, NaT
+}
+;;
+
+{ .mfi
+ ldfpd fQ9, fQ8 = [rAD_Q1], 16 // Load coeff for small path
+ fma.s1 fXsq = fNormX, fNormX, f0 // x*x for small path
+ cmp.gt p7, p8 = -2, rExp_x // Test |x| < 2^(-2)
+}
+{ .mfi
+ ldfpd fQ7, fQ6 = [rAD_Q2], 16 // Load coeff for small path
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe fQ5 = [rAD_Q1], 16 // Load coeff for small path
+ nop.f 0
+ nop.i 0
+}
+{ .mib
+ ldfe fQ4 = [rAD_Q2], 16 // Load coeff for small path
+(p7) cmp.gt.unc p6, p7 = -60, rExp_x // Test |x| < 2^(-60)
+(p7) br.cond.spnt EXPM1_SMALL // Branch if 2^-60 <= |x| < 2^-2
+}
+;;
+
+// W = X * Inv_log2_by_128
+// By adding 1.10...0*2^63 we shift and get round_int(W) in significand.
+// We actually add 1.10...0*2^56 to X * Inv_log2 to do the same thing.
+
+{ .mfi
+ ldfe fLn2_by_128_hi = [rAD_TB1],32
+ fma.s1 fW_2TO56_RSH = fNormX, fINV_LN2_2TO63, fRSHF_2TO56
+ nop.i 0
+}
+{ .mfb
+ ldfe fLn2_by_128_lo = [rAD_Ln2_lo]
+(p6) fma.d.s0 f8 = f8, f8, f8 // If x < 2^-60, result=x+x*x
+(p6) br.ret.spnt b0 // Exit if x < 2^-60
+}
+;;
+
+// Divide arguments into the following categories:
+// Certain minus one p11 - -inf < x <= MAX_DBL_MINUS_1_ARG
+// Possible Overflow p14 - MAX_DBL_NORM_ARG < x < MIN_DBL_OFLOW_ARG
+// Certain Overflow p15 - MIN_DBL_OFLOW_ARG <= x < +inf
+//
+// If the input is really a double arg, then there will never be "Possible
+// Overflow" arguments.
+//
+
+// After that last load, rAD_TB1 points to the beginning of table 1
+
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p15,p14 = fNormX,fMIN_DBL_OFLOW_ARG
+ nop.i 0
+}
+;;
+
+{ .mfi
+ add rAD_P = 0x80, rAD_TB2
+ fcmp.le.s1 p11,p0 = fNormX,fMAX_DBL_MINUS_1_ARG
+ nop.i 0
+}
+;;
+
+{ .mfb
+ ldfpd fP5, fP4 = [rAD_P] ,16
+(p14) fcmp.gt.unc.s1 p14,p0 = fNormX,fMAX_DBL_NORM_ARG
+(p15) br.cond.spnt EXPM1_CERTAIN_OVERFLOW
+}
+;;
+
+// Nfloat = round_int(W)
+// The signficand of fW_2TO56_RSH contains the rounded integer part of W,
+// as a twos complement number in the lower bits (that is, it may be negative).
+// That twos complement number (called N) is put into rN.
+
+// Since fW_2TO56_RSH is scaled by 2^56, it must be multiplied by 2^-56
+// before the shift constant 1.10000 * 2^63 is subtracted to yield fNfloat.
+// Thus, fNfloat contains the floating point version of N
+
+{ .mfb
+ ldfpd fP3, fP2 = [rAD_P]
+ fms.s1 fNfloat = fW_2TO56_RSH, f2TOM56, fRSHF
+(p11) br.cond.spnt EXPM1_CERTAIN_MINUS_ONE
+}
+;;
+
+{ .mfi
+ getf.sig rN = fW_2TO56_RSH
+ nop.f 0
+ nop.i 0
+}
+;;
+
+// rIndex_1 has index_1
+// rIndex_2_16 has index_2 * 16
+// rBiased_M has M
+// rIndex_1_16 has index_1 * 16
+
+// r = x - Nfloat * ln2_by_128_hi
+// f = 1 - Nfloat * ln2_by_128_lo
+{ .mfi
+ and rIndex_1 = 0x0f, rN
+ fnma.s1 fR = fNfloat, fLn2_by_128_hi, fNormX
+ shr rM = rN, 0x7
+}
+{ .mfi
+ and rIndex_2_16 = 0x70, rN
+ fnma.s1 fF = fNfloat, fLn2_by_128_lo, f1
+ nop.i 0
+}
+;;
+
+// rAD_T1 has address of T1
+// rAD_T2 has address if T2
+
+{ .mmi
+ add rBiased_M = rExp_bias, rM
+ add rAD_T2 = rAD_TB2, rIndex_2_16
+ shladd rAD_T1 = rIndex_1, 4, rAD_TB1
+}
+;;
+
+// Create Scale = 2^M
+// Load T1 and T2
+{ .mmi
+ setf.exp f2M = rBiased_M
+ ldfe fT2 = [rAD_T2]
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ldfe fT1 = [rAD_T1]
+ fmpy.s0 fTmp = fLn2_by_128_lo, fLn2_by_128_lo // Force inexact
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP54 = fR, fP5, fP4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fP32 = fR, fP3, fP2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRsq = fR, fR, f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP5432 = fRsq, fP54, fP32
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fS2 = fF,fT2,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fS1 = f2M,fT1,f0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP = fRsq, fP5432, fR
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fSm1 = fS1,fS2,f1 // S - 1.0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s1 fS = fS1,fS2,f0
+(p14) br.cond.spnt EXPM1_POSSIBLE_OVERFLOW
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fS, fP, fSm1
+ br.ret.sptk b0 // Normal path exit
+}
+;;
+
+// Here if 2^-60 <= |x| <2^-2
+// Compute 13th order polynomial
+EXPM1_SMALL:
+{ .mmf
+ ldfe fQ3 = [rAD_Q1], 16
+ ldfe fQ2 = [rAD_Q2], 16
+ fma.s1 fX4 = fXsq, fXsq, f0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fQDC = fQD, fNormX, fQC
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fQBA = fQB, fNormX, fQA
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fQ98 = fQ9, fNormX, fQ8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fQ76= fQ7, fNormX, fQ6
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fQ54 = fQ5, fNormX, fQ4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fX6 = fX4, fXsq, f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fQ32= fQ3, fNormX, fQ2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fQDCBA = fQDC, fXsq, fQBA
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fQ7654 = fQ76, fXsq, fQ54
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fQDCBA98 = fQDCBA, fXsq, fQ98
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fQ765432 = fQ7654, fXsq, fQ32
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fQDCBA98765432 = fQDCBA98, fX6, fQ765432
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fQDCBA98765432, fXsq, fNormX
+ br.ret.sptk b0 // Exit small branch
+}
+;;
+
+
+EXPM1_POSSIBLE_OVERFLOW:
+
+// Here if fMAX_DBL_NORM_ARG < x < fMIN_DBL_OFLOW_ARG
+// This cannot happen if input is a double, only if input higher precision.
+// Overflow is a possibility, not a certainty.
+
+// Recompute result using status field 2 with user's rounding mode,
+// and wre set. If result is larger than largest double, then we have
+// overflow
+
+{ .mfi
+ mov rGt_ln = 0x103ff // Exponent for largest dbl + 1 ulp
+ fsetc.s2 0x7F,0x42 // Get user's round mode, set wre
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp fGt_pln = rGt_ln // Create largest double + 1 ulp
+ fma.d.s2 fWre_urm_f8 = fS, fP, fSm1 // Result with wre set
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40 // Turn off wre in sf2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p6, p0 = fWre_urm_f8, fGt_pln // Test for overflow
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p6) br.cond.spnt EXPM1_CERTAIN_OVERFLOW // Branch if overflow
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fS, fP, fSm1
+ br.ret.sptk b0 // Exit if really no overflow
+}
+;;
+
+EXPM1_CERTAIN_OVERFLOW:
+{ .mmi
+ sub rTmp = rExp_mask, r0, 1
+;;
+ setf.exp fTmp = rTmp
+ nop.i 0
+}
+;;
+
+{ .mfi
+ alloc r32=ar.pfs,1,4,4,0
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 41
+ fma.d.s0 FR_RESULT = fTmp, fTmp, f0 // Set I,O and +INF result
+ br.cond.sptk __libm_error_region
+}
+;;
+
+// Here if x unorm
+EXPM1_UNORM:
+{ .mfb
+ getf.exp rSignexp_x = fNormX // Must recompute if x unorm
+ fcmp.eq.s0 p6, p0 = f8, f0 // Set D flag
+ br.cond.sptk EXPM1_COMMON
+}
+;;
+
+// here if result will be -1 and inexact, x <= -48.0
+EXPM1_CERTAIN_MINUS_ONE:
+{ .mmi
+ mov rTmp = 1
+;;
+ setf.exp fTmp = rTmp
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fms.d.s0 FR_RESULT = fTmp, fTmp, f1 // Set I, rounded -1+eps result
+ br.ret.sptk b0
+}
+;;
+
+GLOBAL_IEEE754_END(expm1)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_expm1f.S b/libc/sysdeps/ia64/fpu/s_expm1f.S
new file mode 100644
index 000000000..8996977dd
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_expm1f.S
@@ -0,0 +1,671 @@
+.file "expf_m1.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+
+// History
+//*********************************************************************
+// 02/02/00 Initial Version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 07/07/01 Improved speed of all paths
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 11/20/02 Improved speed, algorithm based on expf
+// 03/31/05 Reformatted delimiters between data tables
+//
+//
+// API
+//*********************************************************************
+// float expm1f(float)
+//
+// Overview of operation
+//*********************************************************************
+// 1. Inputs of Nan, Inf, Zero, NatVal handled with special paths
+//
+// 2. |x| < 2^-40
+// Result = x, computed by x + x*x to handle appropriate flags and rounding
+//
+// 3. 2^-40 <= |x| < 2^-2
+// Result determined by 8th order Taylor series polynomial
+// expm1f(x) = x + A2*x^2 + ... + A8*x^8
+//
+// 4. x < -24.0
+// Here we know result is essentially -1 + eps, where eps only affects
+// rounded result. Set I.
+//
+// 5. x >= 88.7228
+// Result overflows. Set I, O, and call error support
+//
+// 6. 2^-2 <= x < 88.7228 or -24.0 <= x < -2^-2
+// This is the main path. The algorithm is described below:
+
+// Take the input x. w is "how many log2/128 in x?"
+// w = x * 64/log2
+// NJ = int(w)
+// x = NJ*log2/64 + R
+
+// NJ = 64*n + j
+// x = n*log2 + (log2/64)*j + R
+//
+// So, exp(x) = 2^n * 2^(j/64)* exp(R)
+//
+// T = 2^n * 2^(j/64)
+// Construct 2^n
+// Get 2^(j/64) table
+// actually all the entries of 2^(j/64) table are stored in DP and
+// with exponent bits set to 0 -> multiplication on 2^n can be
+// performed by doing logical "or" operation with bits presenting 2^n
+
+// exp(R) = 1 + (exp(R) - 1)
+// P = exp(R) - 1 approximated by Taylor series of 3rd degree
+// P = A3*R^3 + A2*R^2 + R, A3 = 1/6, A2 = 1/2
+//
+
+// The final result is reconstructed as follows
+// expm1f(x) = T*P + (T - 1.0)
+
+// Special values
+//*********************************************************************
+// expm1f(+0) = +0.0
+// expm1f(-0) = -0.0
+
+// expm1f(+qnan) = +qnan
+// expm1f(-qnan) = -qnan
+// expm1f(+snan) = +qnan
+// expm1f(-snan) = -qnan
+
+// expm1f(-inf) = -1.0
+// expm1f(+inf) = +inf
+
+// Overflow and Underflow
+//*********************************************************************
+// expm1f(x) = largest single normal when
+// x = 88.7228 = 0x42b17217
+//
+// Underflow is handled as described in case 2 above.
+
+
+// Registers used
+//*********************************************************************
+// Floating Point registers used:
+// f8, input
+// f6,f7, f9 -> f15, f32 -> f45
+
+// General registers used:
+// r3, r20 -> r38
+
+// Predicate registers used:
+// p9 -> p15
+
+// Assembly macros
+//*********************************************************************
+// integer registers used
+// scratch
+rNJ = r3
+
+rExp_half = r20
+rSignexp_x = r21
+rExp_x = r22
+rExp_mask = r23
+rExp_bias = r24
+rTmp = r25
+rM1_lim = r25
+rGt_ln = r25
+rJ = r26
+rN = r27
+rTblAddr = r28
+rLn2Div64 = r29
+rRightShifter = r30
+r64DivLn2 = r31
+// stacked
+GR_SAVE_PFS = r32
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Parameter_TAG = r38
+
+// floating point registers used
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+// scratch
+fRightShifter = f6
+f64DivLn2 = f7
+fNormX = f9
+fNint = f10
+fN = f11
+fR = f12
+fLn2Div64 = f13
+fA2 = f14
+fA3 = f15
+// stacked
+fP = f32
+fX3 = f33
+fT = f34
+fMIN_SGL_OFLOW_ARG = f35
+fMAX_SGL_NORM_ARG = f36
+fMAX_SGL_MINUS_1_ARG = f37
+fA4 = f38
+fA43 = f38
+fA432 = f38
+fRSqr = f39
+fA5 = f40
+fTmp = f41
+fGt_pln = f41
+fXsq = f41
+fA7 = f42
+fA6 = f43
+fA65 = f43
+fTm1 = f44
+fA8 = f45
+fA87 = f45
+fA8765 = f45
+fA8765432 = f45
+fWre_urm_f8 = f45
+
+RODATA
+.align 16
+LOCAL_OBJECT_START(_expf_table)
+data8 0x3efa01a01a01a01a // A8 = 1/8!
+data8 0x3f2a01a01a01a01a // A7 = 1/7!
+data8 0x3f56c16c16c16c17 // A6 = 1/6!
+data8 0x3f81111111111111 // A5 = 1/5!
+data8 0x3fa5555555555555 // A4 = 1/4!
+data8 0x3fc5555555555555 // A3 = 1/3!
+//
+data4 0x42b17218 // Smallest sgl arg to overflow sgl result
+data4 0x42b17217 // Largest sgl arg to give sgl result
+//
+// 2^(j/64) table, j goes from 0 to 63
+data8 0x0000000000000000 // 2^(0/64)
+data8 0x00002C9A3E778061 // 2^(1/64)
+data8 0x000059B0D3158574 // 2^(2/64)
+data8 0x0000874518759BC8 // 2^(3/64)
+data8 0x0000B5586CF9890F // 2^(4/64)
+data8 0x0000E3EC32D3D1A2 // 2^(5/64)
+data8 0x00011301D0125B51 // 2^(6/64)
+data8 0x0001429AAEA92DE0 // 2^(7/64)
+data8 0x000172B83C7D517B // 2^(8/64)
+data8 0x0001A35BEB6FCB75 // 2^(9/64)
+data8 0x0001D4873168B9AA // 2^(10/64)
+data8 0x0002063B88628CD6 // 2^(11/64)
+data8 0x0002387A6E756238 // 2^(12/64)
+data8 0x00026B4565E27CDD // 2^(13/64)
+data8 0x00029E9DF51FDEE1 // 2^(14/64)
+data8 0x0002D285A6E4030B // 2^(15/64)
+data8 0x000306FE0A31B715 // 2^(16/64)
+data8 0x00033C08B26416FF // 2^(17/64)
+data8 0x000371A7373AA9CB // 2^(18/64)
+data8 0x0003A7DB34E59FF7 // 2^(19/64)
+data8 0x0003DEA64C123422 // 2^(20/64)
+data8 0x0004160A21F72E2A // 2^(21/64)
+data8 0x00044E086061892D // 2^(22/64)
+data8 0x000486A2B5C13CD0 // 2^(23/64)
+data8 0x0004BFDAD5362A27 // 2^(24/64)
+data8 0x0004F9B2769D2CA7 // 2^(25/64)
+data8 0x0005342B569D4F82 // 2^(26/64)
+data8 0x00056F4736B527DA // 2^(27/64)
+data8 0x0005AB07DD485429 // 2^(28/64)
+data8 0x0005E76F15AD2148 // 2^(29/64)
+data8 0x0006247EB03A5585 // 2^(30/64)
+data8 0x0006623882552225 // 2^(31/64)
+data8 0x0006A09E667F3BCD // 2^(32/64)
+data8 0x0006DFB23C651A2F // 2^(33/64)
+data8 0x00071F75E8EC5F74 // 2^(34/64)
+data8 0x00075FEB564267C9 // 2^(35/64)
+data8 0x0007A11473EB0187 // 2^(36/64)
+data8 0x0007E2F336CF4E62 // 2^(37/64)
+data8 0x00082589994CCE13 // 2^(38/64)
+data8 0x000868D99B4492ED // 2^(39/64)
+data8 0x0008ACE5422AA0DB // 2^(40/64)
+data8 0x0008F1AE99157736 // 2^(41/64)
+data8 0x00093737B0CDC5E5 // 2^(42/64)
+data8 0x00097D829FDE4E50 // 2^(43/64)
+data8 0x0009C49182A3F090 // 2^(44/64)
+data8 0x000A0C667B5DE565 // 2^(45/64)
+data8 0x000A5503B23E255D // 2^(46/64)
+data8 0x000A9E6B5579FDBF // 2^(47/64)
+data8 0x000AE89F995AD3AD // 2^(48/64)
+data8 0x000B33A2B84F15FB // 2^(49/64)
+data8 0x000B7F76F2FB5E47 // 2^(50/64)
+data8 0x000BCC1E904BC1D2 // 2^(51/64)
+data8 0x000C199BDD85529C // 2^(52/64)
+data8 0x000C67F12E57D14B // 2^(53/64)
+data8 0x000CB720DCEF9069 // 2^(54/64)
+data8 0x000D072D4A07897C // 2^(55/64)
+data8 0x000D5818DCFBA487 // 2^(56/64)
+data8 0x000DA9E603DB3285 // 2^(57/64)
+data8 0x000DFC97337B9B5F // 2^(58/64)
+data8 0x000E502EE78B3FF6 // 2^(59/64)
+data8 0x000EA4AFA2A490DA // 2^(60/64)
+data8 0x000EFA1BEE615A27 // 2^(61/64)
+data8 0x000F50765B6E4540 // 2^(62/64)
+data8 0x000FA7C1819E90D8 // 2^(63/64)
+LOCAL_OBJECT_END(_expf_table)
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(expm1f)
+
+{ .mlx
+ getf.exp rSignexp_x = f8 // Must recompute if x unorm
+ movl r64DivLn2 = 0x40571547652B82FE // 64/ln(2)
+}
+{ .mlx
+ addl rTblAddr = @ltoff(_expf_table),gp
+ movl rRightShifter = 0x43E8000000000000 // DP Right Shifter
+}
+;;
+
+{ .mfi
+ // point to the beginning of the table
+ ld8 rTblAddr = [rTblAddr]
+ fclass.m p14, p0 = f8 , 0x22 // test for -INF
+ mov rExp_mask = 0x1ffff // Exponent mask
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNormX = f8 // normalized x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.d f64DivLn2 = r64DivLn2 // load 64/ln(2) to FP reg
+ fclass.m p9, p0 = f8 , 0x0b // test for x unorm
+ mov rExp_bias = 0xffff // Exponent bias
+}
+{ .mlx
+ // load Right Shifter to FP reg
+ setf.d fRightShifter = rRightShifter
+ movl rLn2Div64 = 0x3F862E42FEFA39EF // DP ln(2)/64 in GR
+}
+;;
+
+{ .mfi
+ ldfpd fA8, fA7 = [rTblAddr], 16
+ fcmp.eq.s1 p13, p0 = f0, f8 // test for x = 0.0
+ mov rExp_half = 0xfffe
+}
+{ .mfb
+ setf.d fLn2Div64 = rLn2Div64 // load ln(2)/64 to FP reg
+ nop.f 0
+(p9) br.cond.spnt EXPM1_UNORM // Branch if x unorm
+}
+;;
+
+EXPM1_COMMON:
+{ .mfb
+ ldfpd fA6, fA5 = [rTblAddr], 16
+(p14) fms.s.s0 f8 = f0, f0, f1 // result if x = -inf
+(p14) br.ret.spnt b0 // exit here if x = -inf
+}
+;;
+
+{ .mfb
+ ldfpd fA4, fA3 = [rTblAddr], 16
+ fclass.m p15, p0 = f8 , 0x1e1 // test for NaT,NaN,+Inf
+(p13) br.ret.spnt b0 // exit here if x =0.0, result is x
+}
+;;
+
+{ .mfi
+ // overflow thresholds
+ ldfps fMIN_SGL_OFLOW_ARG, fMAX_SGL_NORM_ARG = [rTblAddr], 8
+ fma.s1 fXsq = fNormX, fNormX, f0 // x^2 for small path
+ and rExp_x = rExp_mask, rSignexp_x // Biased exponent of x
+}
+{ .mlx
+ nop.m 0
+ movl rM1_lim = 0xc1c00000 // Minus -1 limit (-24.0), SP
+}
+;;
+
+{ .mfi
+ setf.exp fA2 = rExp_half
+ // x*(64/ln(2)) + Right Shifter
+ fma.s1 fNint = fNormX, f64DivLn2, fRightShifter
+ sub rExp_x = rExp_x, rExp_bias // True exponent of x
+}
+{ .mfb
+ nop.m 0
+(p15) fma.s.s0 f8 = f8, f1, f0 // result if x = NaT,NaN,+Inf
+(p15) br.ret.spnt b0 // exit here if x = NaT,NaN,+Inf
+}
+;;
+
+{ .mfi
+ setf.s fMAX_SGL_MINUS_1_ARG = rM1_lim // -1 threshold, -24.0
+ nop.f 0
+ cmp.gt p7, p8 = -2, rExp_x // Test |x| < 2^(-2)
+}
+;;
+
+{ .mfi
+(p7) cmp.gt.unc p6, p7 = -40, rExp_x // Test |x| < 2^(-40)
+ fma.s1 fA87 = fA8, fNormX, fA7 // Small path, A8*x+A7
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA65 = fA6, fNormX, fA5 // Small path, A6*x+A5
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+(p6) fma.s.s0 f8 = f8, f8, f8 // If x < 2^-40, result=x+x*x
+(p6) br.ret.spnt b0 // Exit if x < 2^-40
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // check for overflow
+ fcmp.gt.s1 p15, p14 = fNormX, fMIN_SGL_OFLOW_ARG
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fN = fNint, f1, fRightShifter // n in FP register
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p7) fma.s1 fA43 = fA4, fNormX, fA3 // Small path, A4*x+A3
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.sig rNJ = fNint // bits of n, j
+(p7) fma.s1 fA8765 = fA87, fXsq, fA65 // Small path, A87*xsq+A65
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.s1 fX3 = fXsq, fNormX, f0 // Small path, x^3
+ // branch out if overflow
+(p15) br.cond.spnt EXPM1_CERTAIN_OVERFLOW
+}
+;;
+
+{ .mfi
+ addl rN = 0xffff-63, rNJ // biased and shifted n
+ fnma.s1 fR = fLn2Div64, fN, fNormX // R = x - N*ln(2)/64
+ extr.u rJ = rNJ , 0 , 6 // bits of j
+}
+;;
+
+{ .mfi
+ shladd rJ = rJ, 3, rTblAddr // address in the 2^(j/64) table
+ // check for certain -1
+ fcmp.le.s1 p13, p0 = fNormX, fMAX_SGL_MINUS_1_ARG
+ shr rN = rN, 6 // biased n
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s1 fA432 = fA43, fNormX, fA2 // Small path, A43*x+A2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ ld8 rJ = [rJ]
+ nop.f 0
+ shl rN = rN , 52 // 2^n bits in DP format
+}
+;;
+
+{ .mmi
+ or rN = rN, rJ // bits of 2^n * 2^(j/64) in DP format
+(p13) mov rTmp = 1 // Make small value for -1 path
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.d fT = rN // 2^n
+ // check for possible overflow (only happens if input higher precision)
+(p14) fcmp.gt.s1 p14, p0 = fNormX, fMAX_SGL_NORM_ARG
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s1 fA8765432 = fA8765, fX3, fA432 // A8765*x^3+A432
+ nop.i 0
+}
+;;
+
+{ .mfi
+(p13) setf.exp fTmp = rTmp // Make small value for -1 path
+ fma.s1 fP = fA3, fR, fA2 // A3*R + A2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s1 fRSqr = fR, fR, f0 // R^2
+(p13) br.cond.spnt EXPM1_CERTAIN_MINUS_ONE // Branch if x < -24.0
+}
+;;
+
+{ .mfb
+ nop.m 0
+(p7) fma.s.s0 f8 = fA8765432, fXsq, fNormX // Small path,
+ // result=xsq*A8765432+x
+(p7) br.ret.spnt b0 // Exit if 2^-40 <= |x| < 2^-2
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fP = fP, fRSqr, fR // P = (A3*R + A2)*Rsqr + R
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fms.s1 fTm1 = fT, f1, f1 // T - 1.0
+(p14) br.cond.spnt EXPM1_POSSIBLE_OVERFLOW
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = fP, fT, fTm1
+ br.ret.sptk b0 // Result for main path
+ // minus_one_limit < x < -2^-2
+ // and +2^-2 <= x < overflow_limit
+}
+;;
+
+// Here if x unorm
+EXPM1_UNORM:
+{ .mfb
+ getf.exp rSignexp_x = fNormX // Must recompute if x unorm
+ fcmp.eq.s0 p6, p0 = f8, f0 // Set D flag
+ br.cond.sptk EXPM1_COMMON
+}
+;;
+
+// here if result will be -1 and inexact, x <= -24.0
+EXPM1_CERTAIN_MINUS_ONE:
+{ .mfb
+ nop.m 0
+ fms.s.s0 f8 = fTmp, fTmp, f1 // Result -1, and Inexact set
+ br.ret.sptk b0
+}
+;;
+
+EXPM1_POSSIBLE_OVERFLOW:
+
+// Here if fMAX_SGL_NORM_ARG < x < fMIN_SGL_OFLOW_ARG
+// This cannot happen if input is a single, only if input higher precision.
+// Overflow is a possibility, not a certainty.
+
+// Recompute result using status field 2 with user's rounding mode,
+// and wre set. If result is larger than largest single, then we have
+// overflow
+
+{ .mfi
+ mov rGt_ln = 0x1007f // Exponent for largest sgl + 1 ulp
+ fsetc.s2 0x7F,0x42 // Get user's round mode, set wre
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp fGt_pln = rGt_ln // Create largest single + 1 ulp
+ fma.s.s2 fWre_urm_f8 = fP, fT, fTm1 // Result with wre set
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40 // Turn off wre in sf2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p6, p0 = fWre_urm_f8, fGt_pln // Test for overflow
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p6) br.cond.spnt EXPM1_CERTAIN_OVERFLOW // Branch if overflow
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = fP, fT, fTm1
+ br.ret.sptk b0 // Exit if really no overflow
+}
+;;
+
+// here if overflow
+EXPM1_CERTAIN_OVERFLOW:
+{ .mmi
+ addl rTmp = 0x1FFFE, r0;;
+ setf.exp fTmp = rTmp
+ nop.i 999
+}
+;;
+
+{ .mfi
+ alloc r32 = ar.pfs, 0, 3, 4, 0 // get some registers
+ fmerge.s FR_X = fNormX,fNormX
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 43
+ fma.s.s0 FR_RESULT = fTmp, fTmp, f0 // Set I,O and +INF result
+ br.cond.sptk __libm_error_region
+}
+;;
+
+GLOBAL_IEEE754_END(expm1f)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 999
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // Store Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mfi
+ stfs [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ nop.f 0
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_expm1l.S b/libc/sysdeps/ia64/fpu/s_expm1l.S
new file mode 100644
index 000000000..5f135faf6
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_expm1l.S
@@ -0,0 +1,1431 @@
+.file "expl_m1.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial Version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 07/07/01 Improved speed of all paths
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+// 03/11/03 Improved accuracy and performance, corrected missing inexact flags
+// 04/17/03 Eliminated misplaced and unused data label
+// 12/15/03 Eliminated call to error support on expm1l underflow
+//
+//*********************************************************************
+//
+// Function: Combined expl(x) and expm1l(x), where
+// x
+// expl(x) = e , for double-extended precision x values
+// x
+// expm1l(x) = e - 1 for double-extended precision x values
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f9-f15,f32-f77
+//
+// General Purpose Registers:
+// r14-r38
+// r35-r38 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6-p15
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// Denormal fault raised on denormal inputs
+// Overflow exceptions raised when appropriate for exp and expm1
+// Underflow exceptions raised when appropriate for exp and expm1
+// (Error Handling Routine called for overflow and Underflow)
+// Inexact raised when appropriate by algorithm
+//
+// exp(inf) = inf
+// exp(-inf) = +0
+// exp(SNaN) = QNaN
+// exp(QNaN) = QNaN
+// exp(0) = 1
+// exp(EM_special Values) = QNaN
+// exp(inf) = inf
+// expm1(-inf) = -1
+// expm1(SNaN) = QNaN
+// expm1(QNaN) = QNaN
+// expm1(0) = 0
+// expm1(EM_special Values) = QNaN
+//
+//*********************************************************************
+//
+// Implementation and Algorithm Notes:
+//
+// ker_exp_64( in_FR : X,
+// out_FR : Y_hi,
+// out_FR : Y_lo,
+// out_FR : scale,
+// out_PR : Safe )
+//
+// On input, X is in register format
+// p6 for exp,
+// p7 for expm1,
+//
+// On output,
+//
+// scale*(Y_hi + Y_lo) approximates exp(X) if exp
+// scale*(Y_hi + Y_lo) approximates exp(X)-1 if expm1
+//
+// The accuracy is sufficient for a highly accurate 64 sig.
+// bit implementation. Safe is set if there is no danger of
+// overflow/underflow when the result is composed from scale,
+// Y_hi and Y_lo. Thus, we can have a fast return if Safe is set.
+// Otherwise, one must prepare to handle the possible exception
+// appropriately. Note that SAFE not set (false) does not mean
+// that overflow/underflow will occur; only the setting of SAFE
+// guarantees the opposite.
+//
+// **** High Level Overview ****
+//
+// The method consists of three cases.
+//
+// If |X| < Tiny use case exp_tiny;
+// else if |X| < 2^(-m) use case exp_small; m=12 for exp, m=7 for expm1
+// else use case exp_regular;
+//
+// Case exp_tiny:
+//
+// 1 + X can be used to approximate exp(X)
+// X + X^2/2 can be used to approximate exp(X) - 1
+//
+// Case exp_small:
+//
+// Here, exp(X) and exp(X) - 1 can all be
+// appproximated by a relatively simple polynomial.
+//
+// This polynomial resembles the truncated Taylor series
+//
+// exp(w) = 1 + w + w^2/2! + w^3/3! + ... + w^n/n!
+//
+// Case exp_regular:
+//
+// Here we use a table lookup method. The basic idea is that in
+// order to compute exp(X), we accurately decompose X into
+//
+// X = N * log(2)/(2^12) + r, |r| <= log(2)/2^13.
+//
+// Hence
+//
+// exp(X) = 2^( N / 2^12 ) * exp(r).
+//
+// The value 2^( N / 2^12 ) is obtained by simple combinations
+// of values calculated beforehand and stored in table; exp(r)
+// is approximated by a short polynomial because |r| is small.
+//
+// We elaborate this method in 4 steps.
+//
+// Step 1: Reduction
+//
+// The value 2^12/log(2) is stored as a double-extended number
+// L_Inv.
+//
+// N := round_to_nearest_integer( X * L_Inv )
+//
+// The value log(2)/2^12 is stored as two numbers L_hi and L_lo so
+// that r can be computed accurately via
+//
+// r := (X - N*L_hi) - N*L_lo
+//
+// We pick L_hi such that N*L_hi is representable in 64 sig. bits
+// and thus the FMA X - N*L_hi is error free. So r is the
+// 1 rounding error from an exact reduction with respect to
+//
+// L_hi + L_lo.
+//
+// In particular, L_hi has 30 significant bit and can be stored
+// as a double-precision number; L_lo has 64 significant bits and
+// stored as a double-extended number.
+//
+// Step 2: Approximation
+//
+// exp(r) - 1 is approximated by a short polynomial of the form
+//
+// r + A_1 r^2 + A_2 r^3 + A_3 r^4 .
+//
+// Step 3: Composition from Table Values
+//
+// The value 2^( N / 2^12 ) can be composed from a couple of tables
+// of precalculated values. First, express N as three integers
+// K, M_1, and M_2 as
+//
+// N = K * 2^12 + M_1 * 2^6 + M_2
+//
+// Where 0 <= M_1, M_2 < 2^6; and K can be positive or negative.
+// When N is represented in 2's complement, M_2 is simply the 6
+// lsb's, M_1 is the next 6, and K is simply N shifted right
+// arithmetically (sign extended) by 12 bits.
+//
+// Now, 2^( N / 2^12 ) is simply
+//
+// 2^K * 2^( M_1 / 2^6 ) * 2^( M_2 / 2^12 )
+//
+// Clearly, 2^K needs no tabulation. The other two values are less
+// trivial because if we store each accurately to more than working
+// precision, than its product is too expensive to calculate. We
+// use the following method.
+//
+// Define two mathematical values, delta_1 and delta_2, implicitly
+// such that
+//
+// T_1 = exp( [M_1 log(2)/2^6] - delta_1 )
+// T_2 = exp( [M_2 log(2)/2^12] - delta_2 )
+//
+// are representable as 24 significant bits. To illustrate the idea,
+// we show how we define delta_1:
+//
+// T_1 := round_to_24_bits( exp( M_1 log(2)/2^6 ) )
+// delta_1 = (M_1 log(2)/2^6) - log( T_1 )
+//
+// The last equality means mathematical equality. We then tabulate
+//
+// W_1 := exp(delta_1) - 1
+// W_2 := exp(delta_2) - 1
+//
+// Both in double precision.
+//
+// From the tabulated values T_1, T_2, W_1, W_2, we compose the values
+// T and W via
+//
+// T := T_1 * T_2 ...exactly
+// W := W_1 + (1 + W_1)*W_2
+//
+// W approximates exp( delta ) - 1 where delta = delta_1 + delta_2.
+// The mathematical product of T and (W+1) is an accurate representation
+// of 2^(M_1/2^6) * 2^(M_2/2^12).
+//
+// Step 4. Reconstruction
+//
+// Finally, we can reconstruct exp(X), exp(X) - 1.
+// Because
+//
+// X = K * log(2) + (M_1*log(2)/2^6 - delta_1)
+// + (M_2*log(2)/2^12 - delta_2)
+// + delta_1 + delta_2 + r ...accurately
+// We have
+//
+// exp(X) ~=~ 2^K * ( T + T*[exp(delta_1+delta_2+r) - 1] )
+// ~=~ 2^K * ( T + T*[exp(delta + r) - 1] )
+// ~=~ 2^K * ( T + T*[(exp(delta)-1)
+// + exp(delta)*(exp(r)-1)] )
+// ~=~ 2^K * ( T + T*( W + (1+W)*poly(r) ) )
+// ~=~ 2^K * ( Y_hi + Y_lo )
+//
+// where Y_hi = T and Y_lo = T*(W + (1+W)*poly(r))
+//
+// For exp(X)-1, we have
+//
+// exp(X)-1 ~=~ 2^K * ( Y_hi + Y_lo ) - 1
+// ~=~ 2^K * ( Y_hi + Y_lo - 2^(-K) )
+//
+// and we combine Y_hi + Y_lo - 2^(-N) into the form of two
+// numbers Y_hi + Y_lo carefully.
+//
+// **** Algorithm Details ****
+//
+// A careful algorithm must be used to realize the mathematical ideas
+// accurately. We describe each of the three cases. We assume SAFE
+// is preset to be TRUE.
+//
+// Case exp_tiny:
+//
+// The important points are to ensure an accurate result under
+// different rounding directions and a correct setting of the SAFE
+// flag.
+//
+// If expm1 is 1, then
+// SAFE := False ...possibility of underflow
+// Scale := 1.0
+// Y_hi := X
+// Y_lo := 2^(-17000)
+// Else
+// Scale := 1.0
+// Y_hi := 1.0
+// Y_lo := X ...for different rounding modes
+// Endif
+//
+// Case exp_small:
+//
+// Here we compute a simple polynomial. To exploit parallelism, we split
+// the polynomial into several portions.
+//
+// Let r = X
+//
+// If exp ...i.e. exp( argument )
+//
+// rsq := r * r;
+// r4 := rsq*rsq
+// poly_lo := P_3 + r*(P_4 + r*(P_5 + r*P_6))
+// poly_hi := r + rsq*(P_1 + r*P_2)
+// Y_lo := poly_hi + r4 * poly_lo
+// Y_hi := 1.0
+// Scale := 1.0
+//
+// Else ...i.e. exp( argument ) - 1
+//
+// rsq := r * r
+// r4 := rsq * rsq
+// poly_lo := Q_7 + r*(Q_8 + r*Q_9))
+// poly_med:= Q_3 + r*Q_4 + rsq*(Q_5 + r*Q_6)
+// poly_med:= poly_med + r4*poly_lo
+// poly_hi := Q_1 + r*Q_2
+// Y_lo := rsq*(poly_hi + rsq*poly_lo)
+// Y_hi := X
+// Scale := 1.0
+//
+// Endif
+//
+// Case exp_regular:
+//
+// The previous description contain enough information except the
+// computation of poly and the final Y_hi and Y_lo in the case for
+// exp(X)-1.
+//
+// The computation of poly for Step 2:
+//
+// rsq := r*r
+// poly := r + rsq*(A_1 + r*(A_2 + r*A_3))
+//
+// For the case exp(X) - 1, we need to incorporate 2^(-K) into
+// Y_hi and Y_lo at the end of Step 4.
+//
+// If K > 10 then
+// Y_lo := Y_lo - 2^(-K)
+// Else
+// If K < -10 then
+// Y_lo := Y_hi + Y_lo
+// Y_hi := -2^(-K)
+// Else
+// Y_hi := Y_hi - 2^(-K)
+// End If
+// End If
+//
+//=======================================================
+// General Purpose Registers
+//
+GR_ad_Arg = r14
+GR_ad_A = r15
+GR_sig_inv_ln2 = r15
+GR_rshf_2to51 = r16
+GR_ad_PQ = r16
+GR_ad_Q = r16
+GR_signexp_x = r17
+GR_exp_x = r17
+GR_small_exp = r18
+GR_rshf = r18
+GR_exp_mask = r19
+GR_ad_W1 = r20
+GR_exp_2tom51 = r20
+GR_ad_W2 = r21
+GR_exp_underflow = r21
+GR_M2 = r22
+GR_huge_exp = r22
+GR_M1 = r23
+GR_huge_signif = r23
+GR_K = r24
+GR_one = r24
+GR_minus_one = r24
+GR_exp_bias = r25
+GR_ad_Limits = r26
+GR_N_fix = r26
+GR_exp_2_mk = r26
+GR_ad_P = r27
+GR_exp_2_k = r27
+GR_big_expo_neg = r28
+GR_very_small_exp = r29
+GR_exp_half = r29
+GR_ad_T1 = r30
+GR_ad_T2 = r31
+
+GR_SAVE_PFS = r32
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Parameter_TAG = r38
+
+// Floating Point Registers
+//
+FR_norm_x = f9
+FR_RSHF_2TO51 = f10
+FR_INV_LN2_2TO63 = f11
+FR_W_2TO51_RSH = f12
+FR_2TOM51 = f13
+FR_RSHF = f14
+FR_Y_hi = f34
+FR_Y_lo = f35
+FR_scale = f36
+FR_tmp = f37
+FR_float_N = f38
+FR_N_signif = f39
+FR_L_hi = f40
+FR_L_lo = f41
+FR_r = f42
+FR_W1 = f43
+FR_T1 = f44
+FR_W2 = f45
+FR_T2 = f46
+FR_W1_p1 = f47
+FR_rsq = f48
+FR_A2 = f49
+FR_r4 = f50
+FR_A3 = f51
+FR_poly = f52
+FR_T = f53
+FR_W = f54
+FR_Wp1 = f55
+FR_p21 = f59
+FR_p210 = f59
+FR_p65 = f60
+FR_p654 = f60
+FR_p6543 = f60
+FR_2_mk = f61
+FR_P4Q7 = f61
+FR_P4 = f61
+FR_Q7 = f61
+FR_P3Q6 = f62
+FR_P3 = f62
+FR_Q6 = f62
+FR_q65 = f62
+FR_q6543 = f62
+FR_P2Q5 = f63
+FR_P2 = f63
+FR_Q5 = f63
+FR_P1Q4 = f64
+FR_P1 = f64
+FR_Q4 = f64
+FR_q43 = f64
+FR_Q3 = f65
+FR_Q2 = f66
+FR_q21 = f66
+FR_Q1 = f67
+FR_A1 = f68
+FR_P6Q9 = f68
+FR_P6 = f68
+FR_Q9 = f68
+FR_P5Q8 = f69
+FR_P5 = f69
+FR_Q8 = f69
+FR_q987 = f69
+FR_q98 = f69
+FR_q9876543 = f69
+FR_min_oflow_x = f70
+FR_huge_exp = f70
+FR_zero_uflow_x = f71
+FR_huge_signif = f71
+FR_huge = f72
+FR_small = f72
+FR_half = f73
+FR_T_scale = f74
+FR_result_lo = f75
+FR_W_T_scale = f76
+FR_Wp1_T_scale = f77
+FR_ftz = f77
+FR_half_x = f77
+//
+
+FR_X = f9
+FR_Y = f0
+FR_RESULT = f15
+
+// ************* DO NOT CHANGE ORDER OF THESE TABLES ********************
+
+// double-extended 1/ln(2)
+// 3fff b8aa 3b29 5c17 f0bb be87fed0691d3e88
+// 3fff b8aa 3b29 5c17 f0bc
+// For speed the significand will be loaded directly with a movl and setf.sig
+// and the exponent will be bias+63 instead of bias+0. Thus subsequent
+// computations need to scale appropriately.
+// The constant 2^12/ln(2) is needed for the computation of N. This is also
+// obtained by scaling the computations.
+//
+// Two shifting constants are loaded directly with movl and setf.d.
+// 1. RSHF_2TO51 = 1.1000..00 * 2^(63-12)
+// This constant is added to x*1/ln2 to shift the integer part of
+// x*2^12/ln2 into the rightmost bits of the significand.
+// The result of this fma is N_signif.
+// 2. RSHF = 1.1000..00 * 2^(63)
+// This constant is subtracted from N_signif * 2^(-51) to give
+// the integer part of N, N_fix, as a floating-point number.
+// The result of this fms is float_N.
+
+RODATA
+.align 64
+LOCAL_OBJECT_START(Constants_exp_64_Arg)
+//data8 0xB8AA3B295C17F0BC,0x0000400B // Inv_L = 2^12/log(2)
+data8 0xB17217F400000000,0x00003FF2 // L_hi = hi part log(2)/2^12
+data8 0xF473DE6AF278ECE6,0x00003FD4 // L_lo = lo part log(2)/2^12
+LOCAL_OBJECT_END(Constants_exp_64_Arg)
+
+LOCAL_OBJECT_START(Constants_exp_64_Limits)
+data8 0xb17217f7d1cf79ac,0x0000400c // Smallest long dbl oflow x
+data8 0xb220000000000000,0x0000c00c // Small long dbl uflow zero x
+LOCAL_OBJECT_END(Constants_exp_64_Limits)
+
+LOCAL_OBJECT_START(Constants_exp_64_A)
+data8 0xAAAAAAABB1B736A0,0x00003FFA // A3
+data8 0xAAAAAAAB90CD6327,0x00003FFC // A2
+data8 0xFFFFFFFFFFFFFFFF,0x00003FFD // A1
+LOCAL_OBJECT_END(Constants_exp_64_A)
+
+LOCAL_OBJECT_START(Constants_exp_64_P)
+data8 0xD00D6C8143914A8A,0x00003FF2 // P6
+data8 0xB60BC4AC30304B30,0x00003FF5 // P5
+data8 0x888888887474C518,0x00003FF8 // P4
+data8 0xAAAAAAAA8DAE729D,0x00003FFA // P3
+data8 0xAAAAAAAAAAAAAF61,0x00003FFC // P2
+data8 0x80000000000004C7,0x00003FFE // P1
+LOCAL_OBJECT_END(Constants_exp_64_P)
+
+LOCAL_OBJECT_START(Constants_exp_64_Q)
+data8 0x93F2AC5F7471F32E, 0x00003FE9 // Q9
+data8 0xB8DA0F3550B3E764, 0x00003FEC // Q8
+data8 0xD00D00D0028E89C4, 0x00003FEF // Q7
+data8 0xD00D00DAEB8C4E91, 0x00003FF2 // Q6
+data8 0xB60B60B60B60B6F5, 0x00003FF5 // Q5
+data8 0x888888888886CC23, 0x00003FF8 // Q4
+data8 0xAAAAAAAAAAAAAAAB, 0x00003FFA // Q3
+data8 0xAAAAAAAAAAAAAAAB, 0x00003FFC // Q2
+data8 0x8000000000000000, 0x00003FFE // Q1
+LOCAL_OBJECT_END(Constants_exp_64_Q)
+
+LOCAL_OBJECT_START(Constants_exp_64_T1)
+data4 0x3F800000,0x3F8164D2,0x3F82CD87,0x3F843A29
+data4 0x3F85AAC3,0x3F871F62,0x3F88980F,0x3F8A14D5
+data4 0x3F8B95C2,0x3F8D1ADF,0x3F8EA43A,0x3F9031DC
+data4 0x3F91C3D3,0x3F935A2B,0x3F94F4F0,0x3F96942D
+data4 0x3F9837F0,0x3F99E046,0x3F9B8D3A,0x3F9D3EDA
+data4 0x3F9EF532,0x3FA0B051,0x3FA27043,0x3FA43516
+data4 0x3FA5FED7,0x3FA7CD94,0x3FA9A15B,0x3FAB7A3A
+data4 0x3FAD583F,0x3FAF3B79,0x3FB123F6,0x3FB311C4
+data4 0x3FB504F3,0x3FB6FD92,0x3FB8FBAF,0x3FBAFF5B
+data4 0x3FBD08A4,0x3FBF179A,0x3FC12C4D,0x3FC346CD
+data4 0x3FC5672A,0x3FC78D75,0x3FC9B9BE,0x3FCBEC15
+data4 0x3FCE248C,0x3FD06334,0x3FD2A81E,0x3FD4F35B
+data4 0x3FD744FD,0x3FD99D16,0x3FDBFBB8,0x3FDE60F5
+data4 0x3FE0CCDF,0x3FE33F89,0x3FE5B907,0x3FE8396A
+data4 0x3FEAC0C7,0x3FED4F30,0x3FEFE4BA,0x3FF28177
+data4 0x3FF5257D,0x3FF7D0DF,0x3FFA83B3,0x3FFD3E0C
+LOCAL_OBJECT_END(Constants_exp_64_T1)
+
+LOCAL_OBJECT_START(Constants_exp_64_T2)
+data4 0x3F800000,0x3F80058C,0x3F800B18,0x3F8010A4
+data4 0x3F801630,0x3F801BBD,0x3F80214A,0x3F8026D7
+data4 0x3F802C64,0x3F8031F2,0x3F803780,0x3F803D0E
+data4 0x3F80429C,0x3F80482B,0x3F804DB9,0x3F805349
+data4 0x3F8058D8,0x3F805E67,0x3F8063F7,0x3F806987
+data4 0x3F806F17,0x3F8074A8,0x3F807A39,0x3F807FCA
+data4 0x3F80855B,0x3F808AEC,0x3F80907E,0x3F809610
+data4 0x3F809BA2,0x3F80A135,0x3F80A6C7,0x3F80AC5A
+data4 0x3F80B1ED,0x3F80B781,0x3F80BD14,0x3F80C2A8
+data4 0x3F80C83C,0x3F80CDD1,0x3F80D365,0x3F80D8FA
+data4 0x3F80DE8F,0x3F80E425,0x3F80E9BA,0x3F80EF50
+data4 0x3F80F4E6,0x3F80FA7C,0x3F810013,0x3F8105AA
+data4 0x3F810B41,0x3F8110D8,0x3F81166F,0x3F811C07
+data4 0x3F81219F,0x3F812737,0x3F812CD0,0x3F813269
+data4 0x3F813802,0x3F813D9B,0x3F814334,0x3F8148CE
+data4 0x3F814E68,0x3F815402,0x3F81599C,0x3F815F37
+LOCAL_OBJECT_END(Constants_exp_64_T2)
+
+LOCAL_OBJECT_START(Constants_exp_64_W1)
+data8 0x0000000000000000, 0xBE384454171EC4B4
+data8 0xBE6947414AA72766, 0xBE5D32B6D42518F8
+data8 0x3E68D96D3A319149, 0xBE68F4DA62415F36
+data8 0xBE6DDA2FC9C86A3B, 0x3E6B2E50F49228FE
+data8 0xBE49C0C21188B886, 0x3E64BFC21A4C2F1F
+data8 0xBE6A2FBB2CB98B54, 0x3E5DC5DE9A55D329
+data8 0x3E69649039A7AACE, 0x3E54728B5C66DBA5
+data8 0xBE62B0DBBA1C7D7D, 0x3E576E0409F1AF5F
+data8 0x3E6125001A0DD6A1, 0xBE66A419795FBDEF
+data8 0xBE5CDE8CE1BD41FC, 0xBE621376EA54964F
+data8 0x3E6370BE476E76EE, 0x3E390D1A3427EB92
+data8 0x3E1336DE2BF82BF8, 0xBE5FF1CBD0F7BD9E
+data8 0xBE60A3550CEB09DD, 0xBE5CA37E0980F30D
+data8 0xBE5C541B4C082D25, 0xBE5BBECA3B467D29
+data8 0xBE400D8AB9D946C5, 0xBE5E2A0807ED374A
+data8 0xBE66CB28365C8B0A, 0x3E3AAD5BD3403BCA
+data8 0x3E526055C7EA21E0, 0xBE442C75E72880D6
+data8 0x3E58B2BB85222A43, 0xBE5AAB79522C42BF
+data8 0xBE605CB4469DC2BC, 0xBE589FA7A48C40DC
+data8 0xBE51C2141AA42614, 0xBE48D087C37293F4
+data8 0x3E367A1CA2D673E0, 0xBE51BEBB114F7A38
+data8 0xBE6348E5661A4B48, 0xBDF526431D3B9962
+data8 0x3E3A3B5E35A78A53, 0xBE46C46C1CECD788
+data8 0xBE60B7EC7857D689, 0xBE594D3DD14F1AD7
+data8 0xBE4F9C304C9A8F60, 0xBE52187302DFF9D2
+data8 0xBE5E4C8855E6D68F, 0xBE62140F667F3DC4
+data8 0xBE36961B3BF88747, 0x3E602861C96EC6AA
+data8 0xBE3B5151D57FD718, 0x3E561CD0FC4A627B
+data8 0xBE3A5217CA913FEA, 0x3E40A3CC9A5D193A
+data8 0xBE5AB71310A9C312, 0x3E4FDADBC5F57719
+data8 0x3E361428DBDF59D5, 0x3E5DB5DB61B4180D
+data8 0xBE42AD5F7408D856, 0x3E2A314831B2B707
+LOCAL_OBJECT_END(Constants_exp_64_W1)
+
+LOCAL_OBJECT_START(Constants_exp_64_W2)
+data8 0x0000000000000000, 0xBE641F2537A3D7A2
+data8 0xBE68DD57AD028C40, 0xBE5C77D8F212B1B6
+data8 0x3E57878F1BA5B070, 0xBE55A36A2ECAE6FE
+data8 0xBE620608569DFA3B, 0xBE53B50EA6D300A3
+data8 0x3E5B5EF2223F8F2C, 0xBE56A0D9D6DE0DF4
+data8 0xBE64EEF3EAE28F51, 0xBE5E5AE2367EA80B
+data8 0x3E47CB1A5FCBC02D, 0xBE656BA09BDAFEB7
+data8 0x3E6E70C6805AFEE7, 0xBE6E0509A3415EBA
+data8 0xBE56856B49BFF529, 0x3E66DD3300508651
+data8 0x3E51165FC114BC13, 0x3E53333DC453290F
+data8 0x3E6A072B05539FDA, 0xBE47CD877C0A7696
+data8 0xBE668BF4EB05C6D9, 0xBE67C3E36AE86C93
+data8 0xBE533904D0B3E84B, 0x3E63E8D9556B53CE
+data8 0x3E212C8963A98DC8, 0xBE33138F032A7A22
+data8 0x3E530FA9BC584008, 0xBE6ADF82CCB93C97
+data8 0x3E5F91138370EA39, 0x3E5443A4FB6A05D8
+data8 0x3E63DACD181FEE7A, 0xBE62B29DF0F67DEC
+data8 0x3E65C4833DDE6307, 0x3E5BF030D40A24C1
+data8 0x3E658B8F14E437BE, 0xBE631C29ED98B6C7
+data8 0x3E6335D204CF7C71, 0x3E529EEDE954A79D
+data8 0x3E5D9257F64A2FB8, 0xBE6BED1B854ED06C
+data8 0x3E5096F6D71405CB, 0xBE3D4893ACB9FDF5
+data8 0xBDFEB15801B68349, 0x3E628D35C6A463B9
+data8 0xBE559725ADE45917, 0xBE68C29C042FC476
+data8 0xBE67593B01E511FA, 0xBE4A4313398801ED
+data8 0x3E699571DA7C3300, 0x3E5349BE08062A9E
+data8 0x3E5229C4755BB28E, 0x3E67E42677A1F80D
+data8 0xBE52B33F6B69C352, 0xBE6B3550084DA57F
+data8 0xBE6DB03FD1D09A20, 0xBE60CBC42161B2C1
+data8 0x3E56ED9C78A2B771, 0xBE508E319D0FA795
+data8 0xBE59482AFD1A54E9, 0xBE2A17CEB07FD23E
+data8 0x3E68BF5C17365712, 0x3E3956F9B3785569
+LOCAL_OBJECT_END(Constants_exp_64_W2)
+
+
+.section .text
+
+GLOBAL_IEEE754_ENTRY(expm1l)
+
+//
+// Set p7 true for expm1, p6 false
+//
+
+{ .mlx
+ getf.exp GR_signexp_x = f8 // Get sign and exponent of x, redo if unorm
+ movl GR_sig_inv_ln2 = 0xb8aa3b295c17f0bc // significand of 1/ln2
+}
+{ .mlx
+ addl GR_ad_Arg = @ltoff(Constants_exp_64_Arg#),gp
+ movl GR_rshf_2to51 = 0x4718000000000000 // 1.10000 2^(63+51)
+}
+;;
+
+{ .mfi
+ ld8 GR_ad_Arg = [GR_ad_Arg] // Point to Arg table
+ fclass.m p8, p0 = f8, 0x1E7 // Test x for natval, nan, inf, zero
+ cmp.eq p7, p6 = r0, r0
+}
+{ .mfb
+ mov GR_exp_half = 0x0FFFE // Exponent of 0.5, for very small path
+ fnorm.s1 FR_norm_x = f8 // Normalize x
+ br.cond.sptk exp_continue
+}
+;;
+
+GLOBAL_IEEE754_END(expm1l)
+
+
+GLOBAL_IEEE754_ENTRY(expl)
+//
+// Set p7 false for exp, p6 true
+//
+{ .mlx
+ getf.exp GR_signexp_x = f8 // Get sign and exponent of x, redo if unorm
+ movl GR_sig_inv_ln2 = 0xb8aa3b295c17f0bc // significand of 1/ln2
+}
+{ .mlx
+ addl GR_ad_Arg = @ltoff(Constants_exp_64_Arg#),gp
+ movl GR_rshf_2to51 = 0x4718000000000000 // 1.10000 2^(63+51)
+}
+;;
+
+{ .mfi
+ ld8 GR_ad_Arg = [GR_ad_Arg] // Point to Arg table
+ fclass.m p8, p0 = f8, 0x1E7 // Test x for natval, nan, inf, zero
+ cmp.eq p6, p7 = r0, r0
+}
+{ .mfi
+ mov GR_exp_half = 0x0FFFE // Exponent of 0.5, for very small path
+ fnorm.s1 FR_norm_x = f8 // Normalize x
+ nop.i 999
+}
+;;
+
+exp_continue:
+// Form two constants we need
+// 1/ln2 * 2^63 to compute w = x * 1/ln2 * 128
+// 1.1000..000 * 2^(63+63-12) to right shift int(N) into the significand
+
+{ .mfi
+ setf.sig FR_INV_LN2_2TO63 = GR_sig_inv_ln2 // form 1/ln2 * 2^63
+ fclass.nm.unc p9, p0 = f8, 0x1FF // Test x for unsupported
+ mov GR_exp_2tom51 = 0xffff-51
+}
+{ .mlx
+ setf.d FR_RSHF_2TO51 = GR_rshf_2to51 // Form const 1.1000 * 2^(63+51)
+ movl GR_rshf = 0x43e8000000000000 // 1.10000 2^63 for right shift
+}
+;;
+
+{ .mfi
+ setf.exp FR_half = GR_exp_half // Form 0.5 for very small path
+ fma.s1 FR_scale = f1,f1,f0 // Scale = 1.0
+ mov GR_exp_bias = 0x0FFFF // Set exponent bias
+}
+{ .mib
+ add GR_ad_Limits = 0x20, GR_ad_Arg // Point to Limits table
+ mov GR_exp_mask = 0x1FFFF // Form exponent mask
+(p8) br.cond.spnt EXP_64_SPECIAL // Branch if natval, nan, inf, zero
+}
+;;
+
+{ .mfi
+ setf.exp FR_2TOM51 = GR_exp_2tom51 // Form 2^-51 for scaling float_N
+ nop.f 999
+ add GR_ad_A = 0x40, GR_ad_Arg // Point to A table
+}
+{ .mib
+ setf.d FR_RSHF = GR_rshf // Form right shift const 1.1000 * 2^63
+ add GR_ad_T1 = 0x160, GR_ad_Arg // Point to T1 table
+(p9) br.cond.spnt EXP_64_UNSUPPORTED // Branch if unsupported
+}
+;;
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ ldfe FR_L_hi = [GR_ad_Arg],16 // Get L_hi
+ fcmp.eq.s0 p9,p0 = f8, f0 // Dummy op to flag denormals
+(p6) add GR_ad_PQ = 0x30, GR_ad_A // Point to P table for exp
+}
+{ .mfi
+ ldfe FR_min_oflow_x = [GR_ad_Limits],16 // Get min x to cause overflow
+ fmpy.s1 FR_rsq = f8, f8 // rsq = x * x for small path
+(p7) add GR_ad_PQ = 0x90, GR_ad_A // Point to Q table for expm1
+};;
+
+{ .mmi
+ ldfe FR_L_lo = [GR_ad_Arg],16 // Get L_lo
+ ldfe FR_zero_uflow_x = [GR_ad_Limits],16 // Get x for zero uflow result
+ add GR_ad_W1 = 0x200, GR_ad_T1 // Point to W1 table
+}
+;;
+
+{ .mfi
+ ldfe FR_P6Q9 = [GR_ad_PQ],16 // P6(exp) or Q9(expm1) for small path
+ mov FR_r = FR_norm_x // r = X for small path
+ mov GR_very_small_exp = -60 // Exponent of x for very small path
+}
+{ .mfi
+ add GR_ad_W2 = 0x400, GR_ad_T1 // Point to W2 table
+ nop.f 999
+(p7) mov GR_small_exp = -7 // Exponent of x for small path expm1
+}
+;;
+
+{ .mmi
+ ldfe FR_P5Q8 = [GR_ad_PQ],16 // P5(exp) or Q8(expm1) for small path
+ and GR_exp_x = GR_signexp_x, GR_exp_mask
+(p6) mov GR_small_exp = -12 // Exponent of x for small path exp
+}
+;;
+
+// N_signif = X * Inv_log2_by_2^12
+// By adding 1.10...0*2^63 we shift and get round_int(N_signif) in significand.
+// We actually add 1.10...0*2^51 to X * Inv_log2 to do the same thing.
+{ .mfi
+ ldfe FR_P4Q7 = [GR_ad_PQ],16 // P4(exp) or Q7(expm1) for small path
+ fma.s1 FR_N_signif = FR_norm_x, FR_INV_LN2_2TO63, FR_RSHF_2TO51
+ nop.i 999
+}
+{ .mfi
+ sub GR_exp_x = GR_exp_x, GR_exp_bias // Get exponent
+ fmpy.s1 FR_r4 = FR_rsq, FR_rsq // Form r4 for small path
+ cmp.eq.unc p15, p0 = r0, r0 // Set Safe as default
+}
+;;
+
+{ .mmi
+ ldfe FR_P3Q6 = [GR_ad_PQ],16 // P3(exp) or Q6(expm1) for small path
+ cmp.lt p14, p0 = GR_exp_x, GR_very_small_exp // Is |x| < 2^-60?
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe FR_P2Q5 = [GR_ad_PQ],16 // P2(exp) or Q5(expm1) for small path
+ fmpy.s1 FR_half_x = FR_half, FR_norm_x // 0.5 * x for very small path
+ cmp.lt p13, p0 = GR_exp_x, GR_small_exp // Is |x| < 2^-m?
+}
+{ .mib
+ nop.m 999
+ nop.i 999
+(p14) br.cond.spnt EXP_VERY_SMALL // Branch if |x| < 2^-60
+}
+;;
+
+{ .mfi
+ ldfe FR_A3 = [GR_ad_A],16 // Get A3 for normal path
+ fcmp.ge.s1 p10,p0 = FR_norm_x, FR_min_oflow_x // Will result overflow?
+ mov GR_big_expo_neg = -16381 // -0x3ffd
+}
+{ .mfb
+ ldfe FR_P1Q4 = [GR_ad_PQ],16 // P1(exp) or Q4(expm1) for small path
+ nop.f 999
+(p13) br.cond.spnt EXP_SMALL // Branch if |x| < 2^-m
+ // m=12 for exp, m=7 for expm1
+}
+;;
+
+// Now we are on the main path for |x| >= 2^-m, m=12 for exp, m=7 for expm1
+//
+// float_N = round_int(N_signif)
+// The signficand of N_signif contains the rounded integer part of X * 2^12/ln2,
+// as a twos complement number in the lower bits (that is, it may be negative).
+// That twos complement number (called N) is put into GR_N.
+
+// Since N_signif is scaled by 2^51, it must be multiplied by 2^-51
+// before the shift constant 1.10000 * 2^63 is subtracted to yield float_N.
+// Thus, float_N contains the floating point version of N
+
+
+{ .mfi
+ ldfe FR_A2 = [GR_ad_A],16 // Get A2 for main path
+ fcmp.lt.s1 p11,p0 = FR_norm_x, FR_zero_uflow_x // Certain zero, uflow?
+ add GR_ad_T2 = 0x100, GR_ad_T1 // Point to T2 table
+}
+{ .mfi
+ nop.m 999
+ fms.s1 FR_float_N = FR_N_signif, FR_2TOM51, FR_RSHF // Form float_N
+ nop.i 999
+}
+;;
+
+{ .mbb
+ getf.sig GR_N_fix = FR_N_signif // Get N from significand
+(p10) br.cond.spnt EXP_OVERFLOW // Branch if result will overflow
+(p11) br.cond.spnt EXP_CERTAIN_UNDERFLOW_ZERO // Branch if certain zero, uflow
+}
+;;
+
+{ .mfi
+ ldfe FR_A1 = [GR_ad_A],16 // Get A1 for main path
+ fnma.s1 FR_r = FR_L_hi, FR_float_N, FR_norm_x // r = -L_hi * float_N + x
+ extr.u GR_M1 = GR_N_fix, 6, 6 // Extract index M_1
+}
+{ .mfi
+ and GR_M2 = 0x3f, GR_N_fix // Extract index M_2
+ nop.f 999
+ nop.i 999
+}
+;;
+
+// N_fix is only correct up to 50 bits because of our right shift technique.
+// Actually in the normal path we will have restricted K to about 14 bits.
+// Somewhat arbitrarily we extract 32 bits.
+{ .mfi
+ shladd GR_ad_W1 = GR_M1,3,GR_ad_W1 // Point to W1
+ nop.f 999
+ extr GR_K = GR_N_fix, 12, 32 // Extract limited range K
+}
+{ .mfi
+ shladd GR_ad_T1 = GR_M1,2,GR_ad_T1 // Point to T1
+ nop.f 999
+ shladd GR_ad_T2 = GR_M2,2,GR_ad_T2 // Point to T2
+}
+;;
+
+{ .mmi
+ ldfs FR_T1 = [GR_ad_T1],0 // Get T1
+ ldfd FR_W1 = [GR_ad_W1],0 // Get W1
+ add GR_exp_2_k = GR_exp_bias, GR_K // Form exponent of 2^k
+}
+;;
+
+{ .mmi
+ ldfs FR_T2 = [GR_ad_T2],0 // Get T2
+ shladd GR_ad_W2 = GR_M2,3,GR_ad_W2 // Point to W2
+ sub GR_exp_2_mk = GR_exp_bias, GR_K // Form exponent of 2^-k
+}
+;;
+
+{ .mmf
+ ldfd FR_W2 = [GR_ad_W2],0 // Get W2
+ setf.exp FR_scale = GR_exp_2_k // Set scale = 2^k
+ fnma.s1 FR_r = FR_L_lo, FR_float_N, FR_r // r = -L_lo * float_N + r
+}
+;;
+
+{ .mfi
+ setf.exp FR_2_mk = GR_exp_2_mk // Form 2^-k
+ fma.s1 FR_poly = FR_r, FR_A3, FR_A2 // poly = r * A3 + A2
+ cmp.lt p8,p15 = GR_K,GR_big_expo_neg // Set Safe if K > big_expo_neg
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 FR_T = FR_T1, FR_T2 // T = T1 * T2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fadd.s1 FR_W1_p1 = FR_W1, f1 // W1_p1 = W1 + 1.0
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p7) cmp.lt.unc p8, p9 = 10, GR_K // If expm1, set p8 if K > 10
+ fma.s1 FR_poly = FR_r, FR_poly, FR_A1 // poly = r * poly + A1
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p7) cmp.eq p15, p0 = r0, r0 // If expm1, set Safe flag
+ fma.s1 FR_T_scale = FR_T, FR_scale, f0 // T_scale = T * scale
+(p9) cmp.gt.unc p9, p10 = -10, GR_K // If expm1, set p9 if K < -10
+ // If expm1, set p10 if -10<=K<=10
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_W = FR_W2, FR_W1_p1, FR_W1 // W = W2 * (W1+1.0) + W1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ mov FR_Y_hi = FR_T // Assume Y_hi = T
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_poly = FR_rsq, FR_poly, FR_r // poly = rsq * poly + r
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_Wp1_T_scale = FR_W, FR_T_scale, FR_T_scale // (W+1)*T*scale
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fma.s1 FR_W_T_scale = FR_W, FR_T_scale, f0 // W*T*scale
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fsub.s1 FR_Y_hi = f0, FR_2_mk // If expm1, if K < -10 set Y_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fsub.s1 FR_Y_hi = FR_T, FR_2_mk // If expm1, if |K|<=10 set Y_hi
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s1 FR_result_lo = FR_Wp1_T_scale, FR_poly, FR_W_T_scale
+ nop.i 999
+}
+;;
+
+.pred.rel "mutex",p8,p9
+// If K > 10 adjust result_lo = result_lo - scale * 2^-k
+// If |K| <= 10 adjust result_lo = result_lo + scale * T
+{ .mfi
+ nop.m 999
+(p8) fnma.s1 FR_result_lo = FR_scale, FR_2_mk, FR_result_lo // If K > 10
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_result_lo = FR_T_scale, f1, FR_result_lo // If |K| <= 10
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s0 FR_tmp = FR_A1, FR_A1 // Dummy op to set inexact
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p15) fma.s0 f8 = FR_Y_hi, FR_scale, FR_result_lo // Safe result
+(p15) br.ret.sptk b0 // Safe exit for normal path
+}
+;;
+
+// Here if unsafe, will only be here for exp with K < big_expo_neg
+{ .mfb
+ nop.m 999
+ fma.s0 FR_RESULT = FR_Y_hi, FR_scale, FR_result_lo // Prelim result
+ br.cond.sptk EXP_POSSIBLE_UNDERFLOW // Branch to unsafe code
+}
+;;
+
+
+EXP_SMALL:
+// Here if 2^-60 < |x| < 2^-m, m=12 for exp, m=7 for expm1
+{ .mfi
+(p7) ldfe FR_Q3 = [GR_ad_Q],16 // Get Q3 for small path, if expm1
+(p6) fma.s1 FR_p65 = FR_P6, FR_r, FR_P5 // If exp, p65 = P6 * r + P5
+ nop.i 999
+}
+{ .mfi
+ mov GR_minus_one = -1
+(p7) fma.s1 FR_q98 = FR_Q9, FR_r, FR_Q8 // If expm1, q98 = Q9 * r + Q8
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p7) ldfe FR_Q2 = [GR_ad_Q],16 // Get Q2 for small path, if expm1
+(p7) fma.s1 FR_q65 = FR_Q6, FR_r, FR_Q5 // If expm1, q65 = Q6 * r + Q5
+ nop.i 999
+}
+;;
+
+{ .mfi
+ setf.sig FR_tmp = GR_minus_one // Create value to force inexact
+(p6) fma.s1 FR_p21 = FR_P2, FR_r, FR_P1 // If exp, p21 = P2 * r + P1
+ nop.i 999
+}
+{ .mfi
+(p7) ldfe FR_Q1 = [GR_ad_Q],16 // Get Q1 for small path, if expm1
+(p7) fma.s1 FR_q43 = FR_Q4, FR_r, FR_Q3 // If expm1, q43 = Q4 * r + Q3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fma.s1 FR_p654 = FR_p65, FR_r, FR_P4 // If exp, p654 = p65 * r + P4
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fma.s1 FR_q987 = FR_q98, FR_r, FR_Q7 // If expm1, q987 = q98 * r + Q7
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fma.s1 FR_q21 = FR_Q2, FR_r, FR_Q1 // If expm1, q21 = Q2 * r + Q1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fma.s1 FR_p210 = FR_p21, FR_rsq, FR_r // If exp, p210 = p21 * r + P0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fma.s1 FR_q6543 = FR_q65, FR_rsq, FR_q43 // If expm1, q6543 = q65*r2+q43
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fma.s1 FR_p6543 = FR_p654, FR_r, FR_P3 // If exp, p6543 = p654 * r + P3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fma.s1 FR_q9876543 = FR_q987, FR_r4, FR_q6543 // If expm1, q9876543 = ...
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fma.s1 FR_Y_lo = FR_p6543, FR_r4, FR_p210 // If exp, form Y_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fma.s1 FR_Y_lo = FR_q9876543, FR_rsq, FR_q21 // If expm1, form Y_lo
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmpy.s0 FR_tmp = FR_tmp, FR_tmp // Dummy op to set inexact
+ nop.i 999
+}
+;;
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 999
+(p6) fma.s0 f8 = FR_Y_lo, f1, f1 // If exp, result = 1 + Y_lo
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p7) fma.s0 f8 = FR_Y_lo, FR_rsq, FR_norm_x // If expm1, result = Y_lo*r2+x
+ br.ret.sptk b0 // Exit for 2^-60 <= |x| < 2^-m
+ // m=12 for exp, m=7 for expm1
+}
+;;
+
+
+EXP_VERY_SMALL:
+//
+// Here if 0 < |x| < 2^-60
+// If exp, result = 1.0 + x
+// If expm1, result = x +x*x/2, but have to check for possible underflow
+//
+
+{ .mfi
+(p7) mov GR_exp_underflow = -16381 // Exponent for possible underflow
+(p6) fadd.s0 f8 = f1, FR_norm_x // If exp, result = 1+x
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p7) fmpy.s1 FR_result_lo = FR_half_x, FR_norm_x // If expm1 result_lo = x*x/2
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p7) cmp.lt.unc p0, p8 = GR_exp_x, GR_exp_underflow // Unsafe if expm1 x small
+(p7) mov FR_Y_hi = FR_norm_x // If expm1, Y_hi = x
+(p7) cmp.lt p0, p15 = GR_exp_x, GR_exp_underflow // Unsafe if expm1 x small
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p8) fma.s0 f8 = FR_norm_x, f1, FR_result_lo // If expm1, result=x+x*x/2
+(p15) br.ret.sptk b0 // If Safe, exit
+}
+;;
+
+// Here if expm1 and 0 < |x| < 2^-16381; may be possible underflow
+{ .mfb
+ nop.m 999
+ fma.s0 FR_RESULT = FR_Y_hi, FR_scale, FR_result_lo // Prelim result
+ br.cond.sptk EXP_POSSIBLE_UNDERFLOW // Branch to unsafe code
+}
+;;
+
+EXP_CERTAIN_UNDERFLOW_ZERO:
+// Here if x < zero_uflow_x
+// For exp, set result to tiny+0.0 and set I, U, and branch to error handling
+// For expm1, set result to tiny-1.0 and set I, and exit
+{ .mmi
+ alloc GR_SAVE_PFS = ar.pfs,0,3,4,0
+ nop.m 999
+ mov GR_one = 1
+}
+;;
+
+{ .mmi
+ setf.exp FR_small = GR_one // Form small value
+ nop.m 999
+(p6) mov GR_Parameter_TAG = 13 // Error tag for exp underflow
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmerge.s FR_X = f8,f8 // Save x for error call
+ nop.i 999
+}
+;;
+
+.pred.rel "mutex",p6,p7
+{ .mfb
+ nop.m 999
+(p6) fma.s0 FR_RESULT = FR_small, FR_small, f0 // If exp, set I,U, tiny result
+(p6) br.cond.sptk __libm_error_region // If exp, go to error handling
+}
+{ .mfb
+ nop.m 999
+(p7) fms.s0 f8 = FR_small, FR_small, f1 // If expm1, set I, result -1.0
+(p7) br.ret.sptk b0 // If expm1, exit
+}
+;;
+
+
+EXP_OVERFLOW:
+// Here if x >= min_oflow_x
+{ .mmi
+ alloc GR_SAVE_PFS = ar.pfs,0,3,4,0
+ mov GR_huge_exp = 0x1fffe
+ nop.i 999
+}
+{ .mfi
+ mov GR_huge_signif = -0x1
+ nop.f 999
+(p6) mov GR_Parameter_TAG = 12 // Error tag for exp overflow
+}
+;;
+
+{ .mmf
+ setf.exp FR_huge_exp = GR_huge_exp // Create huge value
+ setf.sig FR_huge_signif = GR_huge_signif // Create huge value
+ fmerge.s FR_X = f8,f8 // Save x for error call
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmerge.se FR_huge = FR_huge_exp, FR_huge_signif
+(p7) mov GR_Parameter_TAG = 39 // Error tag for expm1 overflow
+}
+;;
+
+{ .mfb
+ nop.m 999
+ fma.s0 FR_RESULT = FR_huge, FR_huge, FR_huge // Force I, O, and Inf
+ br.cond.sptk __libm_error_region // Branch to error handling
+}
+;;
+
+
+
+EXP_POSSIBLE_UNDERFLOW:
+// Here if exp and zero_uflow_x < x < about -11356 [where k < -16381]
+// Here if expm1 and |x| < 2^-16381
+{ .mfi
+ alloc GR_SAVE_PFS = ar.pfs,0,3,4,0
+ fsetc.s2 0x7F,0x41 // Set FTZ and disable traps
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fma.s2 FR_ftz = FR_Y_hi, FR_scale, FR_result_lo // Result with FTZ
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fsetc.s2 0x7F,0x40 // Disable traps (set s2 default)
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fclass.m.unc p11, p0 = FR_ftz, 0x00F // If exp, FTZ result denorm or zero?
+ nop.i 999
+}
+;;
+
+{ .mfb
+(p11) mov GR_Parameter_TAG = 13 // exp underflow
+ fmerge.s FR_X = f8,f8 // Save x for error call
+(p11) br.cond.spnt __libm_error_region // Branch on exp underflow
+}
+;;
+
+{ .mfb
+ nop.m 999
+ mov f8 = FR_RESULT // Was safe after all
+ br.ret.sptk b0
+}
+;;
+
+
+EXP_64_SPECIAL:
+// Here if x natval, nan, inf, zero
+// If x natval, +inf, or if expm1 and x zero, just return x.
+// The other cases must be tested for, and results set.
+// These cases do not generate exceptions.
+{ .mfi
+ nop.m 999
+ fclass.m p8, p0 = f8, 0x0c3 // Is x nan?
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fclass.m.unc p13, p0 = f8, 0x007 // If exp, is x zero?
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fclass.m.unc p11, p0 = f8, 0x022 // If exp, is x -inf?
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fadd.s0 f8 = f8, f1 // If x nan, result quietized x
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fclass.m.unc p10, p0 = f8, 0x022 // If expm1, is x -inf?
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p13) fadd.s0 f8 = f0, f1 // If exp and x zero, result 1.0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p11) mov f8 = f0 // If exp and x -inf, result 0
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p10) fsub.s1 f8 = f0, f1 // If expm1, x -inf, result -1.0
+ br.ret.sptk b0 // Exit special cases
+}
+;;
+
+
+EXP_64_UNSUPPORTED:
+// Here if x unsupported type
+{ .mfb
+ nop.m 999
+ fmpy.s0 f8 = f8, f0 // Return nan
+ br.ret.sptk b0
+}
+;;
+
+GLOBAL_IEEE754_END(expl)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+LOCAL_LIBM_END(__libm_error_region#)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_fabs.S b/libc/sysdeps/ia64/fpu/s_fabs.S
new file mode 100644
index 000000000..3434389a3
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fabs.S
@@ -0,0 +1,82 @@
+.file "fabs.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/07/02 Added __libm_fabs entry point to test in case compiler inlines
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// double fabs (double x)
+//
+// Overview of operation
+//==============================================================
+// returns absolute value of x
+
+// floating-point registers used: 1
+// f8, input
+
+.section .text
+.global __libm_fabs#
+
+.proc __libm_fabs#
+__libm_fabs:
+.endp __libm_fabs#
+
+GLOBAL_IEEE754_ENTRY(fabs)
+
+// set invalid or denormal flags and take fault if
+// necessary
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.unc.s0 p6,p7 = f8,f1
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fmerge.s f8 = f0,f8
+ br.ret.sptk b0 ;;
+}
+
+GLOBAL_IEEE754_END(fabs)
diff --git a/libc/sysdeps/ia64/fpu/s_fabsf.S b/libc/sysdeps/ia64/fpu/s_fabsf.S
new file mode 100644
index 000000000..71bb6da88
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fabsf.S
@@ -0,0 +1,82 @@
+.file "fabsf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/07/02 Added __libm_fabsf entry point to test in case compiler inlines
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// float fabsf (float x)
+//
+// Overview of operation
+//==============================================================
+// returns absolute value of x
+
+// floating-point registers used: 1
+// f8, input
+
+.section .text
+.global __libm_fabsf#
+
+.proc __libm_fabsf#
+__libm_fabsf:
+.endp __libm_fabsf#
+
+GLOBAL_IEEE754_ENTRY(fabsf)
+
+// set invalid or denormal flags and take fault if
+// necessary
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.unc.s0 p6,p7 = f8,f1
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fmerge.s f8 = f0,f8
+ br.ret.sptk b0 ;;
+}
+
+GLOBAL_IEEE754_END(fabsf)
diff --git a/libc/sysdeps/ia64/fpu/s_fabsl.S b/libc/sysdeps/ia64/fpu/s_fabsl.S
new file mode 100644
index 000000000..a04894914
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fabsl.S
@@ -0,0 +1,82 @@
+.file "fabsl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/07/02 Added __libm_fabsl entry point to test in case compiler inlines
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// long double fabsl (long double x)
+//
+// Overview of operation
+//==============================================================
+// returns absolute value of x
+
+// floating-point registers used: 1
+// f8, input
+
+.section .text
+.global __libm_fabsl#
+
+.proc __libm_fabsl#
+__libm_fabsl:
+.endp __libm_fabsl#
+
+GLOBAL_IEEE754_ENTRY(fabsl)
+
+// set invalid or denormal flags and take fault if
+// necessary
+
+{ .mfi
+ nop.m 999
+ fcmp.eq.unc.s0 p6,p7 = f8,f1
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fmerge.s f8 = f0,f8
+ br.ret.sptk b0 ;;
+}
+
+GLOBAL_IEEE754_END(fabsl)
diff --git a/libc/sysdeps/ia64/fpu/s_fdim.S b/libc/sysdeps/ia64/fpu/s_fdim.S
new file mode 100644
index 000000000..eff290c59
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fdim.S
@@ -0,0 +1,228 @@
+.file "fdim.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 06/08/01 Initial version
+// 08/23/01 Corrected error tag number
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/28/03 Improved performance
+//
+// API
+//==============================================================
+// double fdim( double x, double y );
+// input floating point f8, f9
+// output floating point f8
+//
+//
+// Overview of operation
+//==============================================================
+// fdim determines the positive difference between the arguments
+// Result = x - y if x > y
+// = +0 if x <= y
+//
+// Error support is called if x-y overflows for x > y
+//
+
+// Registers used
+//==============================================================
+// General purpose registers: r14, r32 - r39
+
+rExpBig = r14
+
+// r36-39 parameters for libm_error_support
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_SAVE_PFS = r35
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+// Floating-point registers: f8 - f12
+
+f_tmp_result = f10
+fBig = f11
+fNormX = f12
+
+// Predicate registers: p6 - p10
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(fdim)
+
+{ .mfi
+ mov rExpBig = 0x103ff // Exponent to indicate overflow
+ fcmp.le.s1 p6,p7 = f8, f9 // Is x <= y?
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNormX = f8 // Save x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp fBig = rExpBig // Constant to test for overflow
+ fcmp.eq.s0 p8,p0 = f8, f9 // Dummy op to set Denormal or Invalid
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p9,p10 = f8, 0x1e3 // Test for x natval, nan, inf
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fmerge.s f8 = f0, f0 // Result is +0 if x <= y
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fms.d.s0 f8 = f8, f1, f9 // Result is x - y if x > y
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p10) fclass.m p9,p10 = f9, 0x1e3 // Test for y natval, nan, inf
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p10) fcmp.ge.s1 p8,p0 = f8, fBig // Test result for overflow
+ nop.i 0
+}
+;;
+
+{ .mbb
+(p9) cmp.ne p8,p0 = r0,r0 // Clear p8 if x or y natval,nan,inf
+(p8) br.cond.spnt FDIM_OVERFLOW // Branch if result overflows
+ br.ret.sptk b0 // Normal return
+}
+;;
+
+
+// Here if result will overflow
+FDIM_OVERFLOW:
+{ .mfi
+ alloc r32=ar.pfs,2,2,4,0
+ fms.d.s0 f_tmp_result = f8,f1,f9 // Normalize result force overflow
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 196 // Error code
+ nop.f 0
+ br.cond.sptk __libm_error_region // Branch to error code
+}
+;;
+
+GLOBAL_LIBM_END(fdim)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+// Call error support to report possible range error
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfd [GR_Parameter_Y] = f9,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfd [GR_Parameter_X] = fNormX // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = f_tmp_result // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_fdimf.S b/libc/sysdeps/ia64/fpu/s_fdimf.S
new file mode 100644
index 000000000..76d69d1cc
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fdimf.S
@@ -0,0 +1,228 @@
+.file "fdimf.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 06/08/01 Initial version
+// 08/23/01 Corrected error tag number
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/28/03 Improved performance; fixed parameters for call to error routine
+//
+// API
+//==============================================================
+// float fdimf( float x, float y );
+// input floating point f8, f9
+// output floating point f8
+//
+//
+// Overview of operation
+//==============================================================
+// fdimf determines the positive difference between the arguments
+// Result = x - y if x > y
+// = +0 if x <= y
+//
+// Error support is called if x-y overflows for x > y
+//
+
+// Registers used
+//==============================================================
+// General purpose registers: r14, r32 - r39
+
+rExpBig = r14
+
+// r36-39 parameters for libm_error_support
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_SAVE_PFS = r35
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+// Floating-point registers: f8 - f12
+
+f_tmp_result = f10
+fBig = f11
+fNormX = f12
+
+// Predicate registers: p6 - p10
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(fdimf)
+
+{ .mfi
+ mov rExpBig = 0x1007f // Exponent to indicate overflow
+ fcmp.le.s1 p6,p7 = f8, f9 // Is x <= y?
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNormX = f8 // Save x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp fBig = rExpBig // Constant to test for overflow
+ fcmp.eq.s0 p8,p0 = f8, f9 // Dummy op to set Denormal or Invalid
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p9,p10 = f8, 0x1e3 // Test for x natval, nan, inf
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fmerge.s f8 = f0, f0 // Result is +0 if x <= y
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fms.s.s0 f8 = f8, f1, f9 // Result is x - y if x > y
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p10) fclass.m p9,p10 = f9, 0x1e3 // Test for y natval, nan, inf
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p10) fcmp.ge.s1 p8,p0 = f8, fBig // Test result for overflow
+ nop.i 0
+}
+;;
+
+{ .mbb
+(p9) cmp.ne p8,p0 = r0,r0 // Clear p8 if x or y natval,nan,inf
+(p8) br.cond.spnt FDIM_OVERFLOW // Branch if result overflows
+ br.ret.sptk b0 // Normal return
+}
+;;
+
+
+// Here if result will overflow
+FDIM_OVERFLOW:
+{ .mfi
+ alloc r32=ar.pfs,2,2,4,0
+ fms.s.s0 f_tmp_result = f8,f1,f9 // Normalize result force overflow
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 197 // Error code
+ nop.f 0
+ br.cond.sptk __libm_error_region // Branch to error code
+}
+;;
+
+GLOBAL_LIBM_END(fdimf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+// Call error support to report possible range error
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfs [GR_Parameter_Y] = f9,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfs [GR_Parameter_X] = fNormX // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = f_tmp_result // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_fdiml.S b/libc/sysdeps/ia64/fpu/s_fdiml.S
new file mode 100644
index 000000000..2227debdb
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fdiml.S
@@ -0,0 +1,228 @@
+.file "fdiml.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 06/08/01 Initial version
+// 08/23/01 Corrected error tag number
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/28/03 Improved performance; fixed parameters for call to error routine
+//
+// API
+//==============================================================
+// long double fdiml( long double x, long double y );
+// input floating point f8, f9
+// output floating point f8
+//
+//
+// Overview of operation
+//==============================================================
+// fdiml determines the positive difference between the arguments
+// Result = x - y if x > y
+// = +0 if x <= y
+//
+// Error support is called if x-y overflows for x > y
+//
+
+// Registers used
+//==============================================================
+// General purpose registers: r14, r32 - r39
+
+rExpBig = r14
+
+// r36-39 parameters for libm_error_support
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_SAVE_PFS = r35
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+// Floating-point registers: f8 - f12
+
+f_tmp_result = f10
+fBig = f11
+fNormX = f12
+
+// Predicate registers: p6 - p10
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(fdiml)
+
+{ .mfi
+ mov rExpBig = 0x13fff // Exponent to indicate overflow
+ fcmp.le.s1 p6,p7 = f8, f9 // Is x <= y?
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNormX = f8 // Save x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ setf.exp fBig = rExpBig // Constant to test for overflow
+ fcmp.eq.s0 p8,p0 = f8, f9 // Dummy op to set Denormal or Invalid
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p9,p10 = f8, 0x1e3 // Test for x natval, nan, inf
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fmerge.s f8 = f0, f0 // Result is +0 if x <= y
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fms.s0 f8 = f8, f1, f9 // Result is x - y if x > y
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p10) fclass.m p9,p10 = f9, 0x1e3 // Test for y natval, nan, inf
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p10) fcmp.ge.s1 p8,p0 = f8, fBig // Test result for overflow
+ nop.i 0
+}
+;;
+
+{ .mbb
+(p9) cmp.ne p8,p0 = r0,r0 // Clear p8 if x or y natval,nan,inf
+(p8) br.cond.spnt FDIM_OVERFLOW // Branch if result overflows
+ br.ret.sptk b0 // Normal return
+}
+;;
+
+
+// Here if result will overflow
+FDIM_OVERFLOW:
+{ .mfi
+ alloc r32=ar.pfs,2,2,4,0
+ fms.s0 f_tmp_result = f8,f1,f9 // Normalize result force overflow
+ nop.i 0
+}
+{ .mfb
+ mov GR_Parameter_TAG = 195 // Error code
+ nop.f 0
+ br.cond.sptk __libm_error_region // Branch to error code
+}
+;;
+
+GLOBAL_LIBM_END(fdiml)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+// Call error support to report possible range error
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfe [GR_Parameter_Y] = f9,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfe [GR_Parameter_X] = fNormX // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = f_tmp_result // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_finite.S b/libc/sysdeps/ia64/fpu/s_finite.S
new file mode 100644
index 000000000..78d3db503
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_finite.S
@@ -0,0 +1,45 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#undef ret
+
+ENTRY (__finite)
+{
+.mfi
+ fclass.m p6, p7 = farg0, @nat | @qnan | @snan | @inf
+ ;;
+}
+{
+.mib
+(p6) mov ret0 = 0
+(p7) mov ret0 = 1
+ br.ret.sptk.many rp
+}
+END (__finite)
+
+strong_alias (__finite, __finitef)
+strong_alias (__finite, __finitel)
+
+weak_alias (__finite, finite)
+weak_alias (__finitef, finitef)
+weak_alias (__finitel, finitel)
+
+hidden_def (__finite)
+hidden_def (__finitef)
+hidden_def (__finitel)
diff --git a/libc/sysdeps/ia64/fpu/s_finitef.S b/libc/sysdeps/ia64/fpu/s_finitef.S
new file mode 100644
index 000000000..cf9b5ce8b
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_finitef.S
@@ -0,0 +1 @@
+/* __finitef is in s_finite.S. */
diff --git a/libc/sysdeps/ia64/fpu/s_finitel.S b/libc/sysdeps/ia64/fpu/s_finitel.S
new file mode 100644
index 000000000..362b18642
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_finitel.S
@@ -0,0 +1 @@
+/* __finitel is in s_finite.S. */
diff --git a/libc/sysdeps/ia64/fpu/s_floor.S b/libc/sysdeps/ia64/fpu/s_floor.S
new file mode 100644
index 000000000..9ed9d6dcd
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_floor.S
@@ -0,0 +1,216 @@
+.file "floor.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 03/22/00 Updated to improve performance
+// 06/13/00 Improved speed, fixed setting of inexact flag
+// 06/27/00 Eliminated incorrect invalid flag setting
+// 02/07/01 Corrected sign of zero result in round to -inf mode
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/28/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// double floor(double x)
+//==============================================================
+
+// general input registers:
+// r14 - r18
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rM1 = r18
+
+// floating-point registers:
+// f8 - f13
+
+fXInt = f9
+fNormX = f10
+fTmp = f11
+fAdj = f12
+fPreResult = f13
+
+// predicate registers used:
+// p6 - p9
+
+// Overview of operation
+//==============================================================
+// double floor(double x)
+// Return an integer value (represented as a double) that is the largest
+// value not greater than x
+// This is x rounded toward -infinity to an integral value.
+// Inexact is set if x != floor(x)
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(floor)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ addl rBigexp = 0x10033, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rM1 = -1 // Set all ones
+ fcvt.fx.trunc.s1 fXInt = f8 // Convert to int in significand
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.lt.s1 p8,p9 = f8, f0 // Test x < 0
+ nop.i 0
+}
+{ .mfb
+ setf.sig fTmp = rM1 // Make const for setting inexact
+ fnorm.s1 fNormX = f8 // Normalize input
+(p7) br.cond.spnt FLOOR_UNORM // Branch if x unorm
+}
+;;
+
+FLOOR_COMMON:
+// Return here from FLOOR_UNORM
+{ .mfi
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x1e7 // Test x natval, nan, inf, 0
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 0
+(p8) fnma.s1 fAdj = f1, f1, f0 // If x < 0, adjustment is -1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fAdj = f0, f0, f0 // If x > 0, adjustment is 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf fPreResult = fXInt // trunc(x)
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p6) fma.d.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf, 0
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf, 0
+}
+;;
+
+{ .mmi
+ and rExp = rSignexp, rExpMask // Get biased exponent
+;;
+ cmp.ge p7,p6 = rExp, rBigexp // Is |x| >= 2^52?
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fma.d.s0 f8 = fPreResult, f1, fAdj // Result if !int, |x| < 2^52
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.d.s0 f8 = fNormX, f1, f0 // Result, if |x| >= 2^52
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fcmp.eq.unc.s1 p8, p9 = fPreResult, fNormX // Is trunc(x) = x ?
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fmpy.s0 fTmp = fTmp, fTmp // Dummy to set inexact
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fma.d.s0 f8 = fNormX, f1, f0 // If x int, result normalized x
+ br.ret.sptk b0 // Exit main path, 0 < |x| < 2^52
+}
+;;
+
+
+FLOOR_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk FLOOR_COMMON // Return to main path
+}
+;;
+
+GLOBAL_IEEE754_END(floor)
diff --git a/libc/sysdeps/ia64/fpu/s_floorf.S b/libc/sysdeps/ia64/fpu/s_floorf.S
new file mode 100644
index 000000000..a3f209593
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_floorf.S
@@ -0,0 +1,215 @@
+.file "floorf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 06/13/00 Improved speed
+// 06/27/00 Eliminated incorrect invalid flag setting
+// 02/07/01 Corrected sign of zero result in round to -inf mode
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/28/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// float floorf(float x)
+//==============================================================
+
+// general input registers:
+// r14 - r18
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rM1 = r18
+
+// floating-point registers:
+// f8 - f13
+
+fXInt = f9
+fNormX = f10
+fTmp = f11
+fAdj = f12
+fPreResult = f13
+
+// predicate registers used:
+// p6 - p9
+
+// Overview of operation
+//==============================================================
+// float floorf(float x)
+// Return an integer value (represented as a float) that is the largest
+// value not greater than x
+// This is x rounded toward -infinity to an integral value.
+// Inexact is set if x != floorf(x)
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(floorf)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ addl rBigexp = 0x10016, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rM1 = -1 // Set all ones
+ fcvt.fx.trunc.s1 fXInt = f8 // Convert to int in significand
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.lt.s1 p8,p9 = f8, f0 // Test x < 0
+ nop.i 0
+}
+{ .mfb
+ setf.sig fTmp = rM1 // Make const for setting inexact
+ fnorm.s1 fNormX = f8 // Normalize input
+(p7) br.cond.spnt FLOOR_UNORM // Branch if x unorm
+}
+;;
+
+FLOOR_COMMON:
+// Return here from FLOOR_UNORM
+{ .mfi
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x1e7 // Test x natval, nan, inf, 0
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 0
+(p8) fnma.s1 fAdj = f1, f1, f0 // If x < 0, adjustment is -1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fAdj = f0, f0, f0 // If x > 0, adjustment is 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf fPreResult = fXInt // trunc(x)
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p6) fma.s.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf, 0
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf, 0
+}
+;;
+
+{ .mmi
+ and rExp = rSignexp, rExpMask // Get biased exponent
+;;
+ cmp.ge p7,p6 = rExp, rBigexp // Is |x| >= 2^23?
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fma.s.s0 f8 = fPreResult, f1, fAdj // Result if !int, |x| < 2^23
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s.s0 f8 = fNormX, f1, f0 // Result, if |x| >= 2^23
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fcmp.eq.unc.s1 p8, p9 = fPreResult, fNormX // Is trunc(x) = x ?
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fmpy.s0 fTmp = fTmp, fTmp // Dummy to set inexact
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fma.s.s0 f8 = fNormX, f1, f0 // If x int, result normalized x
+ br.ret.sptk b0 // Exit main path, 0 < |x| < 2^23
+}
+;;
+
+
+FLOOR_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk FLOOR_COMMON // Return to main path
+}
+;;
+
+GLOBAL_IEEE754_END(floorf)
diff --git a/libc/sysdeps/ia64/fpu/s_floorl.S b/libc/sysdeps/ia64/fpu/s_floorl.S
new file mode 100644
index 000000000..345c4f30d
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_floorl.S
@@ -0,0 +1,215 @@
+.file "floorl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 06/13/00 Improved speed
+// 06/27/00 Eliminated incorrect invalid flag setting
+// 02/07/01 Corrected sign of zero result in round to -inf mode
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/28/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// long double floorl(long double x)
+//==============================================================
+
+// general input registers:
+// r14 - r18
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rM1 = r18
+
+// floating-point registers:
+// f8 - f13
+
+fXInt = f9
+fNormX = f10
+fTmp = f11
+fAdj = f12
+fPreResult = f13
+
+// predicate registers used:
+// p6 - p9
+
+// Overview of operation
+//==============================================================
+// long double floorl(long double x)
+// Return an integer value (represented as a long double) that is the largest
+// value not greater than x
+// This is x rounded toward -infinity to an integral value.
+// Inexact is set if x != floorl(x)
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+
+.section .text
+GLOBAL_IEEE754_ENTRY(floorl)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ addl rBigexp = 0x1003e, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rM1 = -1 // Set all ones
+ fcvt.fx.trunc.s1 fXInt = f8 // Convert to int in significand
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.lt.s1 p8,p9 = f8, f0 // Test x < 0
+ nop.i 0
+}
+{ .mfb
+ setf.sig fTmp = rM1 // Make const for setting inexact
+ fnorm.s1 fNormX = f8 // Normalize input
+(p7) br.cond.spnt FLOOR_UNORM // Branch if x unorm
+}
+;;
+
+FLOOR_COMMON:
+// Return here from FLOOR_UNORM
+{ .mfi
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x1e7 // Test x natval, nan, inf, 0
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 0
+(p8) fnma.s1 fAdj = f1, f1, f0 // If x < 0, adjustment is -1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fAdj = f0, f0, f0 // If x > 0, adjustment is 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf fPreResult = fXInt // trunc(x)
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p6) fma.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf, 0
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf, 0
+}
+;;
+
+{ .mmi
+ and rExp = rSignexp, rExpMask // Get biased exponent
+;;
+ cmp.ge p7,p6 = rExp, rBigexp // Is |x| >= 2^63?
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fma.s0 f8 = fPreResult, f1, fAdj // Result if !int, |x| < 2^63
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s0 f8 = fNormX, f1, f0 // Result, if |x| >= 2^63
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p6) fcmp.eq.unc.s1 p8, p9 = fPreResult, fNormX // Is trunc(x) = x ?
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fmpy.s0 fTmp = fTmp, fTmp // Dummy to set inexact
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fma.s0 f8 = fNormX, f1, f0 // If x int, result normalized x
+ br.ret.sptk b0 // Exit main path, 0 < |x| < 2^63
+}
+;;
+
+
+FLOOR_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk FLOOR_COMMON // Return to main path
+}
+;;
+
+GLOBAL_IEEE754_END(floorl)
diff --git a/libc/sysdeps/ia64/fpu/s_fma.S b/libc/sysdeps/ia64/fpu/s_fma.S
new file mode 100644
index 000000000..7798790d5
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fma.S
@@ -0,0 +1,71 @@
+.file "fma.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 06/07/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// double fma (double x, double y, double z)
+//
+// Overview of operation
+//==============================================================
+// returns x * y + z with one rounding error
+
+// All the special cases are handled by the fma instruction itself
+
+// floating-point registers used: 3
+// f8, input x, output
+// f9, input y
+// f10, input z
+
+.section .text
+GLOBAL_LIBM_ENTRY(fma)
+
+{ .mfb
+ nop.m 999
+ fma.d.s0 f8 = f8, f9, f10 // Result = x * y + z
+ br.ret.sptk b0
+}
+;;
+
+GLOBAL_LIBM_END(fma)
diff --git a/libc/sysdeps/ia64/fpu/s_fmaf.S b/libc/sysdeps/ia64/fpu/s_fmaf.S
new file mode 100644
index 000000000..db112b2a6
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fmaf.S
@@ -0,0 +1,71 @@
+.file "fmaf.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 06/07/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// float fmaf (float x, float y, float z)
+//
+// Overview of operation
+//==============================================================
+// returns x * y + z with one rounding error
+
+// All the special cases are handled by the fma instruction itself
+
+// floating-point registers used: 3
+// f8, input x, output
+// f9, input y
+// f10, input z
+
+.section .text
+GLOBAL_LIBM_ENTRY(fmaf)
+
+{ .mfb
+ nop.m 999
+ fma.s.s0 f8 = f8, f9, f10 // Result = x * y + z
+ br.ret.sptk b0
+}
+;;
+
+GLOBAL_LIBM_END(fmaf)
diff --git a/libc/sysdeps/ia64/fpu/s_fmal.S b/libc/sysdeps/ia64/fpu/s_fmal.S
new file mode 100644
index 000000000..2bdef0b3e
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fmal.S
@@ -0,0 +1,71 @@
+.file "fmal.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 06/07/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// long double fmal (long double x, long double y, long double z)
+//
+// Overview of operation
+//==============================================================
+// returns x * y + z with one rounding error
+
+// All the special cases are handled by the fma instruction itself
+
+// floating-point registers used: 3
+// f8, input x, output
+// f9, input y
+// f10, input z
+
+.section .text
+GLOBAL_LIBM_ENTRY(fmal)
+
+{ .mfb
+ nop.m 999
+ fma.s0 f8 = f8, f9, f10 // Result = x * y + z
+ br.ret.sptk b0
+}
+;;
+
+GLOBAL_LIBM_END(fmal)
diff --git a/libc/sysdeps/ia64/fpu/s_fmax.S b/libc/sysdeps/ia64/fpu/s_fmax.S
new file mode 100644
index 000000000..6fd38dfe9
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fmax.S
@@ -0,0 +1,114 @@
+.file "fmax.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 05/31/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// double fmax (double x, double y)
+//
+// Overview of operation
+//==============================================================
+// returns the algebraic maximum of 2 input values
+//
+// Special cases:
+// fmax(x, nan) returns x if x is numeric // Must special case this one
+// fmax(nan, y) returns y if y is numeric
+// fmax(nan1, nan2) returns quietized nan2
+// fmax(+0,+0) returns +0
+// fmax(-0,+0) returns +0
+// fmax(-0,-0) returns -0
+// fmax(+0,-0) returns +0 // Must special case this one
+//
+// SNaN causes invalid to be set
+
+// floating-point registers used: 2
+// f8, input x, output
+// f9, input y
+
+.section .text
+GLOBAL_LIBM_ENTRY(fmax)
+
+{ .mfi
+ nop.m 999
+ fcmp.unord.s0 p6,p7 = f8, f9 // Is x or y a nan? Raise invalid or denormal
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fclass.m.unc p8,p9 = f9, 0x06 // If no nan, is y=-0?
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fclass.m.unc p10,p0 = f8, 0xc3 // Is x nan?
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fmax.s0 f8 = f8, f9 // Normal case, no nan and y not -0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fmax.s0 f8 = f9, f8 // No nan and y -0
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p10) fmerge.s f8 = f9, f9 // If x nan, return y, else do nothing (returns x)
+ br.ret.sptk b0
+}
+;;
+
+GLOBAL_LIBM_END(fmax)
diff --git a/libc/sysdeps/ia64/fpu/s_fmaxf.S b/libc/sysdeps/ia64/fpu/s_fmaxf.S
new file mode 100644
index 000000000..cac283c66
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fmaxf.S
@@ -0,0 +1,114 @@
+.file "fmaxf.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 05/31/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// float fmaxf (float x, float y)
+//
+// Overview of operation
+//==============================================================
+// returns the algebraic maximum of 2 input values
+//
+// Special cases:
+// fmaxf(x, nan) returns x if x is numeric // Must special case this one
+// fmaxf(nan, y) returns y if y is numeric
+// fmaxf(nan1, nan2) returns quietized nan2
+// fmaxf(+0,+0) returns +0
+// fmaxf(-0,+0) returns +0
+// fmaxf(-0,-0) returns -0
+// fmaxf(+0,-0) returns +0 // Must special case this one
+//
+// SNaN causes invalid to be set
+
+// floating-point registers used: 2
+// f8, input x, output
+// f9, input y
+
+.section .text
+GLOBAL_LIBM_ENTRY(fmaxf)
+
+{ .mfi
+ nop.m 999
+ fcmp.unord.s0 p6,p7 = f8, f9 // Is x or y a nan? Raise invalid or denormal
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fclass.m.unc p8,p9 = f9, 0x06 // If no nan, is y=-0?
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fclass.m.unc p10,p0 = f8, 0xc3 // Is x nan?
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fmax.s0 f8 = f8, f9 // Normal case, no nan and y not -0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fmax.s0 f8 = f9, f8 // No nan and y -0
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p10) fmerge.s f8 = f9, f9 // If x nan, return y, else do nothing (returns x)
+ br.ret.sptk b0
+}
+;;
+
+GLOBAL_LIBM_END(fmaxf)
diff --git a/libc/sysdeps/ia64/fpu/s_fmaxl.S b/libc/sysdeps/ia64/fpu/s_fmaxl.S
new file mode 100644
index 000000000..fb8861dcd
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fmaxl.S
@@ -0,0 +1,114 @@
+.file "fmaxl.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 05/31/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// long double fmaxl (long double x, long double y)
+//
+// Overview of operation
+//==============================================================
+// returns the algebraic maximum of 2 input values
+//
+// Special cases:
+// fmaxl(x, nan) returns x if x is numeric // Must special case this one
+// fmaxl(nan, y) returns y if y is numeric
+// fmaxl(nan1, nan2) returns quietized nan2
+// fmaxl(+0,+0) returns +0
+// fmaxl(-0,+0) returns +0
+// fmaxl(-0,-0) returns -0
+// fmaxl(+0,-0) returns +0 // Must special case this one
+//
+// SNaN causes invalid to be set
+
+// floating-point registers used: 2
+// f8, input x, output
+// f9, input y
+
+.section .text
+GLOBAL_LIBM_ENTRY(fmaxl)
+
+{ .mfi
+ nop.m 999
+ fcmp.unord.s0 p6,p7 = f8, f9 // Is x or y a nan? Raise invalid or denormal
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p7) fclass.m.unc p8,p9 = f9, 0x06 // If no nan, is y=-0?
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fclass.m.unc p10,p0 = f8, 0xc3 // Is x nan?
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fmax.s0 f8 = f8, f9 // Normal case, no nan and y not -0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fmax.s0 f8 = f9, f8 // No nan and y -0
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+(p10) fmerge.s f8 = f9, f9 // If x nan, return y, else do nothing (returns x)
+ br.ret.sptk b0
+}
+;;
+
+GLOBAL_LIBM_END(fmaxl)
diff --git a/libc/sysdeps/ia64/fpu/s_fpclassify.S b/libc/sysdeps/ia64/fpu/s_fpclassify.S
new file mode 100644
index 000000000..a9df24a57
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fpclassify.S
@@ -0,0 +1,62 @@
+/* Return classification value corresponding to argument.
+ Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#undef ret
+
+ENTRY (__fpclassify)
+{
+.mfi
+ fclass.m p6, p7 = farg0, @nat | @qnan | @snan
+ ;;
+}
+{
+.mfb
+(p6) mov ret0 = 0
+(p7) fclass.m p7, p8 = farg0, @inf
+(p6) br.ret.sptk.many rp
+ ;;
+}
+{
+.mfb
+(p7) mov ret0 = 1
+(p8) fclass.m p8, p6 = farg0, @zero
+(p7) br.ret.sptk.many rp
+ ;;
+}
+{
+.mfb
+(p8) mov ret0 = 2
+(p6) fclass.m p6, p7 = farg0, @unorm
+(p8) br.ret.sptk.many rp
+ ;;
+}
+{
+ .pred.rel.mutex p6, p7
+(p6) mov ret0 = 3
+(p7) mov ret0 = 4
+ br.ret.sptk.many rp
+}
+END (__fpclassify)
+
+strong_alias (__fpclassify, __fpclassifyf)
+strong_alias (__fpclassify, __fpclassifyl)
+libm_hidden_def (__fpclassify)
+libm_hidden_def (__fpclassifyf)
+libm_hidden_def (__fpclassifyl)
diff --git a/libc/sysdeps/ia64/fpu/s_fpclassifyf.S b/libc/sysdeps/ia64/fpu/s_fpclassifyf.S
new file mode 100644
index 000000000..cf31fca7a
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fpclassifyf.S
@@ -0,0 +1 @@
+/* __fpclassifyf is in s_fpclassify.S. */
diff --git a/libc/sysdeps/ia64/fpu/s_fpclassifyl.S b/libc/sysdeps/ia64/fpu/s_fpclassifyl.S
new file mode 100644
index 000000000..621e3c53a
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_fpclassifyl.S
@@ -0,0 +1 @@
+/* __fpclassifyl is in s_fpclassify.S. */
diff --git a/libc/sysdeps/ia64/fpu/s_frexp.c b/libc/sysdeps/ia64/fpu/s_frexp.c
new file mode 100644
index 000000000..7d90213d6
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_frexp.c
@@ -0,0 +1,67 @@
+/* file: frexp.c */
+
+
+// Copyright (c) 2000-2002, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+// History
+//=====================================================================
+// 2/02/00 Initial version
+// 1/23/02 Calls kernel with parameter to specify 32- or 64-bit int
+//
+//=====================================================================
+
+#include "libm_support.h"
+
+double __libm_frexp(double, int*, int);
+
+double frexp(double x, int *y)
+{
+
+#ifdef SIZE_INT_64
+ return( __libm_frexp(x, y, 1) );
+
+#else
+
+#ifdef SIZE_INT_32
+ return( __libm_frexp(x, y, 0) );
+#endif
+
+#endif
+
+}
diff --git a/libc/sysdeps/ia64/fpu/s_frexpf.c b/libc/sysdeps/ia64/fpu/s_frexpf.c
new file mode 100644
index 000000000..920f09d4a
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_frexpf.c
@@ -0,0 +1,67 @@
+/* file: frexpf.c */
+
+
+// Copyright (c) 2000-2002, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+// History
+//=====================================================================
+// 2/02/00 Initial version
+// 1/23/02 Calls kernel with parameter to specify 32- or 64-bit int
+//
+//=====================================================================
+
+#include "libm_support.h"
+
+float __libm_frexpf(float, int*, int);
+
+float frexpf(float x, int *y)
+{
+
+#ifdef SIZE_INT_64
+ return( __libm_frexpf(x, y, 1) );
+
+#else
+
+#ifdef SIZE_INT_32
+ return( __libm_frexpf(x, y, 0) );
+#endif
+
+#endif
+
+}
diff --git a/libc/sysdeps/ia64/fpu/s_frexpl.c b/libc/sysdeps/ia64/fpu/s_frexpl.c
new file mode 100644
index 000000000..968cc3269
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_frexpl.c
@@ -0,0 +1,67 @@
+/* file: frexpl.c */
+
+
+// Copyright (c) 2000-2002, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+// History
+//=====================================================================
+// 2/02/00 Initial version
+// 1/23/02 Calls kernel with parameter to specify 32- or 64-bit int
+//
+//=====================================================================
+
+#include "libm_support.h"
+
+long double __libm_frexpl(long double, int*, int);
+
+long double frexpl(long double x, int *y)
+{
+
+#ifdef SIZE_INT_64
+ return( __libm_frexpl(x, y, 1) );
+
+#else
+
+#ifdef SIZE_INT_32
+ return( __libm_frexpl(x, y, 0) );
+#endif
+
+#endif
+
+}
diff --git a/libc/sysdeps/ia64/fpu/s_ilogb.S b/libc/sysdeps/ia64/fpu/s_ilogb.S
new file mode 100644
index 000000000..0102370cd
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_ilogb.S
@@ -0,0 +1,268 @@
+.file "ilogb.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/03/00 Initial version
+// 05/26/00 Fix bug when x a double-extended denormal;
+// if x=0 call error routine, per C9X
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 01/20/01 Fixed result for x=0, corrected error tag value.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance
+//
+// API
+//==============================================================
+// int ilogb( double x );
+//
+// Overview of operation
+//==============================================================
+// The ilogb function extracts the exponent of x as an integer
+// and returns it in r8
+//
+// ilogb is similar to logb but differs in the following ways:
+// +-inf
+// ilogb: returns INT_MAX
+// logb: returns +inf
+// Nan returns FP_LOGBNAN (which is either INT_MAX or INT_MIN)
+// ilogb: returns INT_MAX (7fffffff)
+// logb: returns QNAN (quietized SNAN)
+// 0 returns FP_ILOGB0 (which is either INT_MIN or -INT_MAX)
+// ilogb: returns -INT_MAX (80000001)
+// logb: returns -inf, raises the divide-by-zero exception,
+// and calls libm_error_support to set domain error
+//
+// Registers used
+//==============================================================
+// general registers used:
+// r26 -> r39
+// r36 -> r39 used as parameters to error path
+//
+// predicate registers used:
+// p6 -> p10
+// floating-point registers used:
+// f9, f10, f11
+// f8, input
+
+rExpBias = r26
+rExpMask = r27
+rSignexp_x = r28
+rExp_x = r29
+rIntMax = r30
+rExp_2to64 = r31
+
+GR_SAVE_PFS = r32
+rTrialResult = r33
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+fTmp = f9
+fNorm_x = f10
+f2to64 = f11
+
+.section .text
+GLOBAL_LIBM_ENTRY(ilogb)
+
+// X NORMAL
+// TrueExp_x = exp(f8) - 0xffff
+// r8 = TrueExp_x
+{ .mfi
+ getf.exp rSignexp_x = f8
+ fclass.m p8,p0 = f8, 0x0b // Test for x unorm
+ mov rExpBias = 0xffff // Exponent bias
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNorm_x = f8
+ mov rExpMask = 0x1ffff // Exponent mask
+}
+;;
+
+// Form signexp of 2^64 in case need to scale denormal
+{ .mfb
+ mov rExp_2to64 = 0x1003f
+ fclass.m p6,p9 = f8, 0x1e3 // Test x natval, nan, inf
+(p8) br.cond.spnt ILOGB_DENORM // Branch if x unorm
+}
+;;
+
+ILOGB_COMMON:
+// Return here from ILOGB_DENORM
+{ .mfi
+ and rExp_x = rSignexp_x, rExpMask // Get biased exponent
+ fclass.m p7,p10 = f8, 0x07 // Test x zero
+ nop.i 0
+}
+{ .mlx
+ nop.m 0
+ movl rIntMax = 0x000000007fffffff // Form INT_MAX
+}
+;;
+
+.pred.rel "mutex",p6,p9
+{ .mfi
+(p9) sub r8 = rExp_x, rExpBias // Get true exponent for normal path
+(p6) fma.s0 fTmp = f8, f8, f0 // Dummy to set Invalid flag
+(p6) mov r8 = rIntMax // If nan, inf, return INT_MAX
+}
+{ .mbb
+ nop.m 0
+(p7) br.cond.spnt ILOGB_ZERO // Branch if x zero
+(p10) br.ret.sptk b0 // Exit if x not zero
+}
+;;
+
+
+ILOGB_DENORM:
+// Form 2^64 in case need to scale denormal
+// Check to see if double-extended denormal
+{ .mfi
+ setf.exp f2to64 = rExp_2to64
+ fclass.m p8,p0 = fNorm_x, 0x0b
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ nop.i 0
+}
+;;
+
+// If double-extended denormal add 64 to exponent bias for scaling
+// If double-extended denormal form x * 2^64 which is normal
+{ .mfi
+(p8) add rExpBias = 64, rExpBias
+(p8) fmpy.s1 fNorm_x = fNorm_x, f2to64
+ nop.i 0
+}
+;;
+
+// Logic is the same as normal path but use normalized input
+{ .mib
+ getf.exp rSignexp_x = fNorm_x
+ nop.i 0
+ br.cond.sptk ILOGB_COMMON // Return to main path
+}
+;;
+
+ILOGB_ZERO:
+// Here if x zero
+// Return INT_MIN, call error support
+
+{ .mlx
+ alloc r32=ar.pfs,1,3,4,0
+ movl rTrialResult = 0x0000000080000000
+}
+{ .mib
+ mov GR_Parameter_TAG = 157 // Error code
+ nop.i 0
+ br.cond.sptk __libm_error_region // Call error support
+}
+;;
+
+GLOBAL_LIBM_END(ilogb)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfd [GR_Parameter_Y] = f0,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfd [GR_Parameter_X] = f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = f9 // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ mov r8 = rTrialResult
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_ilogbf.S b/libc/sysdeps/ia64/fpu/s_ilogbf.S
new file mode 100644
index 000000000..9e971bc63
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_ilogbf.S
@@ -0,0 +1,268 @@
+.file "ilogbf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/03/00 Initial version
+// 05/26/00 Fix bug when x a double-extended denormal;
+// if x=0 call error routine, per C9X
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 01/20/01 Fixed result for x=0
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance
+//
+// API
+//==============================================================
+// int ilogbf( float x );
+//
+// Overview of operation
+//==============================================================
+// The ilogbf function extracts the exponent of x as an integer
+// and returns it in r8
+//
+// ilogbf is similar to logbf but differs in the following ways:
+// +-inf
+// ilogbf: returns INT_MAX
+// logbf: returns +inf
+// Nan returns FP_LOGBNAN (which is either INT_MAX or INT_MIN)
+// ilogbf: returns INT_MAX (7fffffff)
+// logbf: returns QNAN (quietized SNAN)
+// 0 returns FP_ILOGB0 (which is either INT_MIN or -INT_MAX)
+// ilogbf: returns -INT_MAX (80000001)
+// logbf: returns -inf, raises the divide-by-zero exception,
+// and calls libm_error_support to set domain error
+//
+// Registers used
+//==============================================================
+// general registers used:
+// r26 -> r39
+// r36 -> r39 used as parameters to error path
+//
+// predicate registers used:
+// p6 -> p10
+// floating-point registers used:
+// f9, f10, f11
+// f8, input
+
+rExpBias = r26
+rExpMask = r27
+rSignexp_x = r28
+rExp_x = r29
+rIntMax = r30
+rExp_2to64 = r31
+
+GR_SAVE_PFS = r32
+rTrialResult = r33
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+fTmp = f9
+fNorm_x = f10
+f2to64 = f11
+
+.section .text
+GLOBAL_LIBM_ENTRY(ilogbf)
+
+// X NORMAL
+// TrueExp_x = exp(f8) - 0xffff
+// r8 = TrueExp_x
+{ .mfi
+ getf.exp rSignexp_x = f8
+ fclass.m p8,p0 = f8, 0x0b // Test for x unorm
+ mov rExpBias = 0xffff // Exponent bias
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNorm_x = f8
+ mov rExpMask = 0x1ffff // Exponent mask
+}
+;;
+
+// Form signexp of 2^64 in case need to scale denormal
+{ .mfb
+ mov rExp_2to64 = 0x1003f
+ fclass.m p6,p9 = f8, 0x1e3 // Test x natval, nan, inf
+(p8) br.cond.spnt ILOGB_DENORM // Branch if x unorm
+}
+;;
+
+ILOGB_COMMON:
+// Return here from ILOGB_DENORM
+{ .mfi
+ and rExp_x = rSignexp_x, rExpMask // Get biased exponent
+ fclass.m p7,p10 = f8, 0x07 // Test x zero
+ nop.i 0
+}
+{ .mlx
+ nop.m 0
+ movl rIntMax = 0x000000007fffffff // Form INT_MAX
+}
+;;
+
+.pred.rel "mutex",p6,p9
+{ .mfi
+(p9) sub r8 = rExp_x, rExpBias // Get true exponent for normal path
+(p6) fma.s0 fTmp = f8, f8, f0 // Dummy to set Invalid flag
+(p6) mov r8 = rIntMax // If nan, inf, return INT_MAX
+}
+{ .mbb
+ nop.m 0
+(p7) br.cond.spnt ILOGB_ZERO // Branch if x zero
+(p10) br.ret.sptk b0 // Exit if x not zero
+}
+;;
+
+
+ILOGB_DENORM:
+// Form 2^64 in case need to scale denormal
+// Check to see if double-extended denormal
+{ .mfi
+ setf.exp f2to64 = rExp_2to64
+ fclass.m p8,p0 = fNorm_x, 0x0b
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ nop.i 0
+}
+;;
+
+// If double-extended denormal add 64 to exponent bias for scaling
+// If double-extended denormal form x * 2^64 which is normal
+{ .mfi
+(p8) add rExpBias = 64, rExpBias
+(p8) fmpy.s1 fNorm_x = fNorm_x, f2to64
+ nop.i 0
+}
+;;
+
+// Logic is the same as normal path but use normalized input
+{ .mib
+ getf.exp rSignexp_x = fNorm_x
+ nop.i 0
+ br.cond.sptk ILOGB_COMMON // Return to main path
+}
+;;
+
+ILOGB_ZERO:
+// Here if x zero
+// Return INT_MIN, call error support
+
+{ .mlx
+ alloc r32=ar.pfs,1,3,4,0
+ movl rTrialResult = 0x0000000080000000
+}
+{ .mib
+ mov GR_Parameter_TAG = 158 // Error code
+ nop.i 0
+ br.cond.sptk __libm_error_region // Call error support
+}
+;;
+
+GLOBAL_LIBM_END(ilogbf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfs [GR_Parameter_Y] = f0,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfs [GR_Parameter_X] = f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = f9 // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ mov r8 = rTrialResult
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_ilogbl.S b/libc/sysdeps/ia64/fpu/s_ilogbl.S
new file mode 100644
index 000000000..8a6c9dc71
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_ilogbl.S
@@ -0,0 +1,268 @@
+.file "ilogbl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/03/00 Initial version
+// 05/26/00 Fix bug when x a double-extended denormal;
+// if x=0 call error routine, per C9X
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 01/20/01 Fixed result for x=0
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance
+//
+// API
+//==============================================================
+// int ilogbl( long double x );
+//
+// Overview of operation
+//==============================================================
+// The ilogbl function extracts the exponent of x as an integer
+// and returns it in r8
+//
+// ilogbl is similar to logbl but differs in the following ways:
+// +-inf
+// ilogbl: returns INT_MAX
+// logbl: returns +inf
+// Nan returns FP_LOGBNAN (which is either INT_MAX or INT_MIN)
+// ilogbl: returns INT_MAX (7fffffff)
+// logbl: returns QNAN (quietized SNAN)
+// 0 returns FP_ILOGB0 (which is either INT_MIN or -INT_MAX)
+// ilogbl: returns -INT_MAX (80000001)
+// logbl: returns -inf, raises the divide-by-zero exception,
+// and calls libm_error_support to set domain error
+//
+// Registers used
+//==============================================================
+// general registers used:
+// r26 -> r39
+// r36 -> r39 used as parameters to error path
+//
+// predicate registers used:
+// p6 -> p10
+// floating-point registers used:
+// f9, f10, f11
+// f8, input
+
+rExpBias = r26
+rExpMask = r27
+rSignexp_x = r28
+rExp_x = r29
+rIntMax = r30
+rExp_2to64 = r31
+
+GR_SAVE_PFS = r32
+rTrialResult = r33
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+fTmp = f9
+fNorm_x = f10
+f2to64 = f11
+
+.section .text
+GLOBAL_LIBM_ENTRY(ilogbl)
+
+// X NORMAL
+// TrueExp_x = exp(f8) - 0xffff
+// r8 = TrueExp_x
+{ .mfi
+ getf.exp rSignexp_x = f8
+ fclass.m p8,p0 = f8, 0x0b // Test for x unorm
+ mov rExpBias = 0xffff // Exponent bias
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNorm_x = f8
+ mov rExpMask = 0x1ffff // Exponent mask
+}
+;;
+
+// Form signexp of 2^64 in case need to scale denormal
+{ .mfb
+ mov rExp_2to64 = 0x1003f
+ fclass.m p6,p9 = f8, 0x1e3 // Test x natval, nan, inf
+(p8) br.cond.spnt ILOGB_DENORM // Branch if x unorm
+}
+;;
+
+ILOGB_COMMON:
+// Return here from ILOGB_DENORM
+{ .mfi
+ and rExp_x = rSignexp_x, rExpMask // Get biased exponent
+ fclass.m p7,p10 = f8, 0x07 // Test x zero
+ nop.i 0
+}
+{ .mlx
+ nop.m 0
+ movl rIntMax = 0x000000007fffffff // Form INT_MAX
+}
+;;
+
+.pred.rel "mutex",p6,p9
+{ .mfi
+(p9) sub r8 = rExp_x, rExpBias // Get true exponent for normal path
+(p6) fma.s0 fTmp = f8, f8, f0 // Dummy to set Invalid flag
+(p6) mov r8 = rIntMax // If nan, inf, return INT_MAX
+}
+{ .mbb
+ nop.m 0
+(p7) br.cond.spnt ILOGB_ZERO // Branch if x zero
+(p10) br.ret.sptk b0 // Exit if x not zero
+}
+;;
+
+
+ILOGB_DENORM:
+// Form 2^64 in case need to scale denormal
+// Check to see if double-extended denormal
+{ .mfi
+ setf.exp f2to64 = rExp_2to64
+ fclass.m p8,p0 = fNorm_x, 0x0b
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ nop.i 0
+}
+;;
+
+// If double-extended denormal add 64 to exponent bias for scaling
+// If double-extended denormal form x * 2^64 which is normal
+{ .mfi
+(p8) add rExpBias = 64, rExpBias
+(p8) fmpy.s1 fNorm_x = fNorm_x, f2to64
+ nop.i 0
+}
+;;
+
+// Logic is the same as normal path but use normalized input
+{ .mib
+ getf.exp rSignexp_x = fNorm_x
+ nop.i 0
+ br.cond.sptk ILOGB_COMMON // Return to main path
+}
+;;
+
+ILOGB_ZERO:
+// Here if x zero
+// Return INT_MIN, call error support
+
+{ .mlx
+ alloc r32=ar.pfs,1,3,4,0
+ movl rTrialResult = 0x0000000080000000
+}
+{ .mib
+ mov GR_Parameter_TAG = 156 // Error code
+ nop.i 0
+ br.cond.sptk __libm_error_region // Call error support
+}
+;;
+
+GLOBAL_LIBM_END(ilogbl)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfe [GR_Parameter_Y] = f0,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfe [GR_Parameter_X] = f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = f9 // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ mov r8 = rTrialResult
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_isinf.S b/libc/sysdeps/ia64/fpu/s_isinf.S
new file mode 100644
index 000000000..e435edf11
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_isinf.S
@@ -0,0 +1,58 @@
+/* Test for inf/-inf
+ Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jes Sorensen <jes@linuxcare.com>, October 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * isinf(x) returns 1 if x is inf, -1 for x == -inf, else 0;
+ */
+
+#include <sysdep.h>
+#undef ret
+
+ENTRY (__isinf)
+{
+.mfi
+ fclass.m p6, p7 = farg0, @inf|@pos
+ ;;
+}
+{
+.mfb
+(p6) mov ret0 = 1
+(p7) fclass.m p7, p8 = farg0, @inf|@neg
+(p6) br.ret.sptk.many rp
+ ;;
+}
+{
+ .pred.rel.mutex p7,p8
+(p7) mov ret0 = -1
+(p8) mov ret0 = 0
+ br.ret.sptk.many rp
+}
+END (__isinf)
+
+strong_alias (__isinf, __isinff)
+strong_alias (__isinf, __isinfl)
+
+weak_alias (__isinf, isinf)
+weak_alias (__isinff, isinff)
+weak_alias (__isinfl, isinfl)
+
+hidden_def (__isinf)
+hidden_def (__isinff)
+hidden_def (__isinfl)
diff --git a/libc/sysdeps/ia64/fpu/s_isinff.S b/libc/sysdeps/ia64/fpu/s_isinff.S
new file mode 100644
index 000000000..37da979e1
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_isinff.S
@@ -0,0 +1 @@
+/* __isinff is in s_isinf.S. */
diff --git a/libc/sysdeps/ia64/fpu/s_isinfl.S b/libc/sysdeps/ia64/fpu/s_isinfl.S
new file mode 100644
index 000000000..c3bca4099
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_isinfl.S
@@ -0,0 +1 @@
+/* __isinfl is in s_isinf.S. */
diff --git a/libc/sysdeps/ia64/fpu/s_isnan.S b/libc/sysdeps/ia64/fpu/s_isnan.S
new file mode 100644
index 000000000..83fd54f35
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_isnan.S
@@ -0,0 +1,51 @@
+/* Test for NaN
+ Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jes Sorensen <jes@linuxcare.com>, October 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * isnan(x) returns 1 is x is nan, else 0;
+ */
+
+#include <sysdep.h>
+#undef ret
+
+ENTRY (__isnan)
+{
+.mfi
+ fclass.m p6, p7 = farg0, @nat | @qnan | @snan
+ ;;
+}
+{
+.mib
+(p6) mov ret0 = 1
+(p7) mov ret0 = 0
+ br.ret.sptk.many rp
+}
+END (__isnan)
+
+strong_alias (__isnan, __isnanf)
+strong_alias (__isnan, __isnanl)
+
+weak_alias (__isnan, isnan)
+weak_alias (__isnanf, isnanf)
+weak_alias (__isnanl, isnanl)
+
+hidden_def (__isnan)
+hidden_def (__isnanf)
+hidden_def (__isnanl)
diff --git a/libc/sysdeps/ia64/fpu/s_isnanf.S b/libc/sysdeps/ia64/fpu/s_isnanf.S
new file mode 100644
index 000000000..a8911b15e
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_isnanf.S
@@ -0,0 +1 @@
+/* __isnanf is in s_isnan.S. */
diff --git a/libc/sysdeps/ia64/fpu/s_isnanl.S b/libc/sysdeps/ia64/fpu/s_isnanl.S
new file mode 100644
index 000000000..82fb19d72
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_isnanl.S
@@ -0,0 +1 @@
+/* __isnanl is in s_isnan.S. */
diff --git a/libc/sysdeps/ia64/fpu/s_ldexp.c b/libc/sysdeps/ia64/fpu/s_ldexp.c
new file mode 100644
index 000000000..a0bc14c29
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_ldexp.c
@@ -0,0 +1,61 @@
+/* file: ldexp.c */
+
+
+// Copyright (c) 2000, 2001, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+#include "libm_support.h"
+
+double __libm_ldexp(double, int, int);
+
+
+double ldexp(double x, int n)
+{
+
+#ifdef SIZE_INT_64
+ return __libm_ldexp(x,n,1);
+#else
+
+#ifdef SIZE_INT_32
+ return __libm_ldexp(x,n,0);
+#endif
+
+#endif
+
+}
diff --git a/libc/sysdeps/ia64/fpu/s_ldexpf.c b/libc/sysdeps/ia64/fpu/s_ldexpf.c
new file mode 100644
index 000000000..ad083fa1c
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_ldexpf.c
@@ -0,0 +1,61 @@
+/* file: ldexpf.c */
+
+
+// Copyright (c) 2000, 2001, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+#include "libm_support.h"
+
+float __libm_ldexpf(float, int, int);
+
+
+float ldexpf(float x, int n)
+{
+
+#ifdef SIZE_INT_64
+ return __libm_ldexpf(x,n,1);
+#else
+
+#ifdef SIZE_INT_32
+ return __libm_ldexpf(x,n,0);
+#endif
+
+#endif
+
+}
diff --git a/libc/sysdeps/ia64/fpu/s_ldexpl.c b/libc/sysdeps/ia64/fpu/s_ldexpl.c
new file mode 100644
index 000000000..61dfd21f1
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_ldexpl.c
@@ -0,0 +1,61 @@
+/* file: ldexpl.c */
+
+
+// Copyright (c) 2000, 2001, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+#include "libm_support.h"
+
+long double __libm_ldexpl(long double, int, int);
+
+
+long double ldexpl(long double x, int n)
+{
+
+#ifdef SIZE_INT_64
+ return __libm_ldexpl(x,n,1);
+#else
+
+#ifdef SIZE_INT_32
+ return __libm_ldexpl(x,n,0);
+#endif
+
+#endif
+
+}
diff --git a/libc/sysdeps/ia64/fpu/s_libm_ldexp.S b/libc/sysdeps/ia64/fpu/s_libm_ldexp.S
new file mode 100644
index 000000000..2aaf2c35f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_libm_ldexp.S
@@ -0,0 +1,452 @@
+.file "libm_ldexp.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 01/26/01 ldexp completely reworked and now standalone version
+// 01/04/02 Added handling for int 32 or 64 bits
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 08/04/03 Improved performance
+//
+// API
+//==============================================================
+// double __libm_ldexp (double x, int n, int int_type)
+// input floating point f8 and int n (r33), int int_type (r34)
+// output floating point f8
+//
+// int_type = 0 if int is 32 bits
+// int_type = 1 if int is 64 bits
+//
+// Returns x* 2**n using an fma and detects overflow
+// and underflow.
+//
+//
+// Strategy:
+// Compute biased exponent of result exp_Result = N + exp_X
+// Break into ranges:
+// exp_Result > 0x103fe -> Certain overflow
+// exp_Result = 0x103fe -> Possible overflow
+// 0x0fc01 <= exp_Result < 0x103fe -> No over/underflow (main path)
+// 0x0fc01 - 52 <= exp_Result < 0x0fc01 -> Possible underflow
+// exp_Result < 0x0fc01 - 52 -> Certain underflow
+
+FR_Big = f6
+FR_NBig = f7
+FR_Floating_X = f8
+FR_Result = f8
+FR_Result2 = f9
+FR_Result3 = f10
+FR_Norm_X = f11
+FR_Two_N = f12
+
+GR_neg_ov_limit= r14
+GR_N_Biased = r15
+GR_Big = r16
+GR_NBig = r17
+GR_exp_Result = r18
+GR_pos_ov_limit= r19
+GR_Bias = r20
+GR_N_as_int = r21
+GR_signexp_X = r22
+GR_exp_X = r23
+GR_exp_mask = r24
+GR_max_exp = r25
+GR_min_exp = r26
+GR_min_den_exp = r27
+
+GR_SAVE_B0 = r32
+GR_SAVE_GP = r33
+GR_SAVE_PFS = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Tag = r38
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_ldexp)
+
+//
+// Is x NAN, INF, ZERO, +-?
+// Build the exponent Bias
+//
+{ .mfi
+ getf.exp GR_signexp_X = FR_Floating_X // Get signexp of x
+ fclass.m p6,p0 = FR_Floating_X, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_Bias = 0x0ffff
+}
+//
+// Normalize x
+// Is integer type 32 bits?
+//
+{ .mfi
+ mov GR_Big = 35000 // If N this big then certain overflow
+ fnorm.s1 FR_Norm_X = FR_Floating_X
+ cmp.eq p8,p9 = r34,r0
+}
+;;
+
+// Sign extend N if int is 32 bits
+{ .mfi
+(p9) mov GR_N_as_int = r33 // Copy N if int is 64 bits
+ fclass.m p9,p0 = FR_Floating_X, 0x0b // Test for x=unorm
+(p8) sxt4 GR_N_as_int = r33 // Sign extend N if int is 32 bits
+}
+{ .mfi
+ mov GR_NBig = -35000 // If N this small then certain underflow
+ nop.f 0
+ mov GR_max_exp = 0x103fe // Exponent of maximum double
+}
+;;
+
+// Create biased exponent for 2**N
+{ .mfi
+ add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.ge p7, p0 = GR_N_as_int, GR_Big // Certain overflow?
+}
+{ .mib
+ cmp.le p8, p0 = GR_N_as_int, GR_NBig // Certain underflow?
+ mov GR_min_exp = 0x0fc01 // Exponent of minimum double
+(p9) br.cond.spnt LDEXP_UNORM // Branch if x=unorm
+}
+;;
+
+LDEXP_COMMON:
+// Main path continues. Also return here from x=unorm path.
+// Create 2**N
+.pred.rel "mutex",p7,p8
+{ .mfi
+ setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+(p7) mov GR_N_as_int = GR_Big // Limit max N
+}
+{ .mfi
+(p8) mov GR_N_as_int = GR_NBig // Limit min N
+ nop.f 0
+(p8) cmp.eq p7,p0 = r0,r0 // Set p7 if |N| big
+}
+;;
+
+//
+// Create biased exponent for 2**N for N big
+// Is N zero?
+//
+{ .mfi
+(p7) add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.eq.or p6,p0 = r33,r0
+}
+{ .mfi
+ mov GR_pos_ov_limit = 0x103ff // Exponent for positive overflow
+ nop.f 0
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+}
+;;
+
+//
+// Create 2**N for N big
+// Return x when N = 0 or X = Nan, Inf, Zero
+//
+{ .mfi
+(p7) setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+ mov GR_min_den_exp = 0x0fc01 - 52 // Exponent of min denorm dble
+}
+{ .mfb
+ and GR_exp_X = GR_exp_mask, GR_signexp_X
+(p6) fma.d.s0 FR_Result = FR_Floating_X, f1, f0
+(p6) br.ret.spnt b0
+}
+;;
+
+//
+// Raise Denormal operand flag with compare
+// Compute biased result exponent
+//
+{ .mfi
+ add GR_exp_Result = GR_exp_X, GR_N_as_int
+ fcmp.ge.s0 p0,p11 = FR_Floating_X,f0
+ mov GR_neg_ov_limit = 0x303ff // Exponent for negative overflow
+}
+;;
+
+//
+// Do final operation
+//
+{ .mfi
+ cmp.lt p7,p6 = GR_exp_Result, GR_max_exp // Test no overflow
+ fma.d.s0 FR_Result = FR_Two_N,FR_Norm_X,f0
+ cmp.lt p9,p0 = GR_exp_Result, GR_min_den_exp // Test sure underflow
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p9) br.cond.spnt LDEXP_UNDERFLOW // Branch if certain underflow
+}
+;;
+
+{ .mib
+(p6) cmp.gt.unc p6,p8 = GR_exp_Result, GR_max_exp // Test sure overflow
+(p7) cmp.ge.unc p7,p9 = GR_exp_Result, GR_min_exp // Test no over/underflow
+(p7) br.ret.sptk b0 // Return from main path
+}
+;;
+
+{ .bbb
+(p6) br.cond.spnt LDEXP_OVERFLOW // Branch if certain overflow
+(p8) br.cond.spnt LDEXP_POSSIBLE_OVERFLOW // Branch if possible overflow
+(p9) br.cond.spnt LDEXP_POSSIBLE_UNDERFLOW // Branch if possible underflow
+}
+;;
+
+// Here if possible underflow.
+// Resulting exponent: 0x0fc01-52 <= exp_Result < 0x0fc01
+LDEXP_POSSIBLE_UNDERFLOW:
+//
+// Here if possible overflow.
+// Resulting exponent: 0x103fe = exp_Result
+LDEXP_POSSIBLE_OVERFLOW:
+
+// Set up necessary status fields
+//
+// S0 user supplied status
+// S2 user supplied status + WRE + TD (Overflows)
+// S3 user supplied status + FZ + TD (Underflows)
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x41
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x42
+ nop.i 0
+}
+;;
+
+//
+// Do final operation with s2 and s3
+//
+{ .mfi
+ setf.exp FR_NBig = GR_neg_ov_limit
+ fma.d.s3 FR_Result3 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+{ .mfi
+ setf.exp FR_Big = GR_pos_ov_limit
+ fma.d.s2 FR_Result2 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+;;
+
+// Check for overflow or underflow.
+// Restore s3
+// Restore s2
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x40
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40
+ nop.i 0
+}
+;;
+
+//
+// Is the result zero?
+//
+{ .mfi
+ nop.m 0
+ fclass.m p6, p0 = FR_Result3, 0x007
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p7, p8 = FR_Result2 , FR_Big
+ nop.i 0
+}
+;;
+
+//
+// Detect masked underflow - Tiny + Inexact Only
+//
+{ .mfi
+ nop.m 0
+(p6) fcmp.neq.unc.s1 p6, p0 = FR_Result , FR_Result2
+ nop.i 0
+}
+;;
+
+//
+// Is result bigger the allowed range?
+// Branch out for underflow
+//
+{ .mfb
+ nop.m 0
+(p8) fcmp.le.unc.s1 p9, p10 = FR_Result2 , FR_NBig
+(p6) br.cond.spnt LDEXP_UNDERFLOW
+}
+;;
+
+//
+// Branch out for overflow
+//
+{ .bbb
+(p7) br.cond.spnt LDEXP_OVERFLOW
+(p9) br.cond.spnt LDEXP_OVERFLOW
+ br.ret.sptk b0 // Return from main path.
+}
+;;
+
+// Here if result overflows
+LDEXP_OVERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 146, r0 // Set error tag for overflow
+ br.cond.sptk __libm_error_region // Call error support for overflow
+}
+;;
+
+// Here if result underflows
+LDEXP_UNDERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 147, r0 // Set error tag for underflow
+ br.cond.sptk __libm_error_region // Call error support for underflow
+}
+;;
+
+// Here if x=unorm
+LDEXP_UNORM:
+{ .mib
+ getf.exp GR_signexp_X = FR_Norm_X // Get signexp of normalized x
+ nop.i 0
+ br.cond.sptk LDEXP_COMMON // Return to main path
+}
+;;
+
+
+GLOBAL_LIBM_END(__libm_ldexp)
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+//
+// Get stack address of N
+//
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs
+}
+//
+// Adjust sp
+//
+{ .mfi
+.fframe 64
+ add sp=-64,sp
+ nop.f 0
+ mov GR_SAVE_GP=gp
+};;
+
+//
+// Store N on stack in correct position
+// Locate the address of x on stack
+//
+{ .mmi
+ st8 [GR_Parameter_Y] = GR_N_as_int,16
+ add GR_Parameter_X = 16,sp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0
+};;
+
+//
+// Store x on the stack.
+// Get address for result on stack.
+//
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_Norm_X
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_Result
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support#
+};;
+
+//
+// Get location of result on stack
+//
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+//
+// Get the new result
+//
+{ .mmi
+ ldfd FR_Result = [GR_Parameter_RESULT]
+.restore sp
+ add sp = 64,sp
+ mov b0 = GR_SAVE_B0
+};;
+
+//
+// Restore gp, ar.pfs and return
+//
+{ .mib
+ mov gp = GR_SAVE_GP
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_libm_ldexpf.S b/libc/sysdeps/ia64/fpu/s_libm_ldexpf.S
new file mode 100644
index 000000000..1326a14c2
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_libm_ldexpf.S
@@ -0,0 +1,452 @@
+.file "libm_ldexpf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 01/26/01 ldexpf completely reworked and now standalone version
+// 01/04/02 Added handling for int 32 or 64 bits
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 08/04/03 Improved performance
+//
+// API
+//==============================================================
+// float __libm_ldexpf (float x, int n, int int_type)
+// input floating point f8 and int n (r33), int int_type (r34)
+// output floating point f8
+//
+// int_type = 0 if int is 32 bits
+// int_type = 1 if int is 64 bits
+//
+// Returns x* 2**n using an fma and detects overflow
+// and underflow.
+//
+//
+// Strategy:
+// Compute biased exponent of result exp_Result = N + exp_X
+// Break into ranges:
+// exp_Result > 0x1007e -> Certain overflow
+// exp_Result = 0x1007e -> Possible overflow
+// 0x0ff81 <= exp_Result < 0x1007e -> No over/underflow (main path)
+// 0x0ff81 - 23 <= exp_Result < 0x0ff81 -> Possible underflow
+// exp_Result < 0x0ff81 - 23 -> Certain underflow
+
+FR_Big = f6
+FR_NBig = f7
+FR_Floating_X = f8
+FR_Result = f8
+FR_Result2 = f9
+FR_Result3 = f10
+FR_Norm_X = f11
+FR_Two_N = f12
+
+GR_neg_ov_limit= r14
+GR_N_Biased = r15
+GR_Big = r16
+GR_NBig = r17
+GR_exp_Result = r18
+GR_pos_ov_limit= r19
+GR_Bias = r20
+GR_N_as_int = r21
+GR_signexp_X = r22
+GR_exp_X = r23
+GR_exp_mask = r24
+GR_max_exp = r25
+GR_min_exp = r26
+GR_min_den_exp = r27
+
+GR_SAVE_B0 = r32
+GR_SAVE_GP = r33
+GR_SAVE_PFS = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Tag = r38
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_ldexpf)
+
+//
+// Is x NAN, INF, ZERO, +-?
+// Build the exponent Bias
+//
+{ .mfi
+ getf.exp GR_signexp_X = FR_Floating_X // Get signexp of x
+ fclass.m p6,p0 = FR_Floating_X, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_Bias = 0x0ffff
+}
+//
+// Normalize x
+// Is integer type 32 bits?
+//
+{ .mfi
+ mov GR_Big = 35000 // If N this big then certain overflow
+ fnorm.s1 FR_Norm_X = FR_Floating_X
+ cmp.eq p8,p9 = r34,r0
+}
+;;
+
+// Sign extend N if int is 32 bits
+{ .mfi
+(p9) mov GR_N_as_int = r33 // Copy N if int is 64 bits
+ fclass.m p9,p0 = FR_Floating_X, 0x0b // Test for x=unorm
+(p8) sxt4 GR_N_as_int = r33 // Sign extend N if int is 32 bits
+}
+{ .mfi
+ mov GR_NBig = -35000 // If N this small then certain underflow
+ nop.f 0
+ mov GR_max_exp = 0x1007e // Exponent of maximum float
+}
+;;
+
+// Create biased exponent for 2**N
+{ .mfi
+ add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.ge p7, p0 = GR_N_as_int, GR_Big // Certain overflow?
+}
+{ .mib
+ cmp.le p8, p0 = GR_N_as_int, GR_NBig // Certain underflow?
+ mov GR_min_exp = 0x0ff81 // Exponent of minimum float
+(p9) br.cond.spnt LDEXPF_UNORM // Branch if x=unorm
+}
+;;
+
+LDEXPF_COMMON:
+// Main path continues. Also return here from x=unorm path.
+// Create 2**N
+.pred.rel "mutex",p7,p8
+{ .mfi
+ setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+(p7) mov GR_N_as_int = GR_Big // Limit max N
+}
+{ .mfi
+(p8) mov GR_N_as_int = GR_NBig // Limit min N
+ nop.f 0
+(p8) cmp.eq p7,p0 = r0,r0 // Set p7 if |N| big
+}
+;;
+
+//
+// Create biased exponent for 2**N for N big
+// Is N zero?
+//
+{ .mfi
+(p7) add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.eq.or p6,p0 = r33,r0
+}
+{ .mfi
+ mov GR_pos_ov_limit = 0x1007f // Exponent for positive overflow
+ nop.f 0
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+}
+;;
+
+//
+// Create 2**N for N big
+// Return x when N = 0 or X = Nan, Inf, Zero
+//
+{ .mfi
+(p7) setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+ mov GR_min_den_exp = 0x0ff81 - 23 // Exponent of min denorm float
+}
+{ .mfb
+ and GR_exp_X = GR_exp_mask, GR_signexp_X
+(p6) fma.s.s0 FR_Result = FR_Floating_X, f1, f0
+(p6) br.ret.spnt b0
+}
+;;
+
+//
+// Raise Denormal operand flag with compare
+// Compute biased result exponent
+//
+{ .mfi
+ add GR_exp_Result = GR_exp_X, GR_N_as_int
+ fcmp.ge.s0 p0,p11 = FR_Floating_X,f0
+ mov GR_neg_ov_limit = 0x3007f // Exponent for negative overflow
+}
+;;
+
+//
+// Do final operation
+//
+{ .mfi
+ cmp.lt p7,p6 = GR_exp_Result, GR_max_exp // Test no overflow
+ fma.s.s0 FR_Result = FR_Two_N,FR_Norm_X,f0
+ cmp.lt p9,p0 = GR_exp_Result, GR_min_den_exp // Test sure underflow
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p9) br.cond.spnt LDEXPF_UNDERFLOW // Branch if certain underflow
+}
+;;
+
+{ .mib
+(p6) cmp.gt.unc p6,p8 = GR_exp_Result, GR_max_exp // Test sure overflow
+(p7) cmp.ge.unc p7,p9 = GR_exp_Result, GR_min_exp // Test no over/underflow
+(p7) br.ret.sptk b0 // Return from main path
+}
+;;
+
+{ .bbb
+(p6) br.cond.spnt LDEXPF_OVERFLOW // Branch if certain overflow
+(p8) br.cond.spnt LDEXPF_POSSIBLE_OVERFLOW // Branch if possible overflow
+(p9) br.cond.spnt LDEXPF_POSSIBLE_UNDERFLOW // Branch if possible underflow
+}
+;;
+
+// Here if possible underflow.
+// Resulting exponent: 0x0ff81-23 <= exp_Result < 0x0ff81
+LDEXPF_POSSIBLE_UNDERFLOW:
+//
+// Here if possible overflow.
+// Resulting exponent: 0x1007e = exp_Result
+LDEXPF_POSSIBLE_OVERFLOW:
+
+// Set up necessary status fields
+//
+// S0 user supplied status
+// S2 user supplied status + WRE + TD (Overflows)
+// S3 user supplied status + FZ + TD (Underflows)
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x41
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x42
+ nop.i 0
+}
+;;
+
+//
+// Do final operation with s2 and s3
+//
+{ .mfi
+ setf.exp FR_NBig = GR_neg_ov_limit
+ fma.s.s3 FR_Result3 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+{ .mfi
+ setf.exp FR_Big = GR_pos_ov_limit
+ fma.s.s2 FR_Result2 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+;;
+
+// Check for overflow or underflow.
+// Restore s3
+// Restore s2
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x40
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40
+ nop.i 0
+}
+;;
+
+//
+// Is the result zero?
+//
+{ .mfi
+ nop.m 0
+ fclass.m p6, p0 = FR_Result3, 0x007
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p7, p8 = FR_Result2 , FR_Big
+ nop.i 0
+}
+;;
+
+//
+// Detect masked underflow - Tiny + Inexact Only
+//
+{ .mfi
+ nop.m 0
+(p6) fcmp.neq.unc.s1 p6, p0 = FR_Result , FR_Result2
+ nop.i 0
+}
+;;
+
+//
+// Is result bigger the allowed range?
+// Branch out for underflow
+//
+{ .mfb
+ nop.m 0
+(p8) fcmp.le.unc.s1 p9, p10 = FR_Result2 , FR_NBig
+(p6) br.cond.spnt LDEXPF_UNDERFLOW
+}
+;;
+
+//
+// Branch out for overflow
+//
+{ .bbb
+(p7) br.cond.spnt LDEXPF_OVERFLOW
+(p9) br.cond.spnt LDEXPF_OVERFLOW
+ br.ret.sptk b0 // Return from main path.
+}
+;;
+
+// Here if result overflows
+LDEXPF_OVERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 148, r0 // Set error tag for overflow
+ br.cond.sptk __libm_error_region // Call error support for overflow
+}
+;;
+
+// Here if result underflows
+LDEXPF_UNDERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 149, r0 // Set error tag for underflow
+ br.cond.sptk __libm_error_region // Call error support for underflow
+}
+;;
+
+// Here if x=unorm
+LDEXPF_UNORM:
+{ .mib
+ getf.exp GR_signexp_X = FR_Norm_X // Get signexp of normalized x
+ nop.i 0
+ br.cond.sptk LDEXPF_COMMON // Return to main path
+}
+;;
+
+
+GLOBAL_LIBM_END(__libm_ldexpf)
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+//
+// Get stack address of N
+//
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs
+}
+//
+// Adjust sp
+//
+{ .mfi
+.fframe 64
+ add sp=-64,sp
+ nop.f 0
+ mov GR_SAVE_GP=gp
+};;
+
+//
+// Store N on stack in correct position
+// Locate the address of x on stack
+//
+{ .mmi
+ st8 [GR_Parameter_Y] = GR_N_as_int,16
+ add GR_Parameter_X = 16,sp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0
+};;
+
+//
+// Store x on the stack.
+// Get address for result on stack.
+//
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_Norm_X
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_Result
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support#
+};;
+
+//
+// Get location of result on stack
+//
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+//
+// Get the new result
+//
+{ .mmi
+ ldfs FR_Result = [GR_Parameter_RESULT]
+.restore sp
+ add sp = 64,sp
+ mov b0 = GR_SAVE_B0
+};;
+
+//
+// Restore gp, ar.pfs and return
+//
+{ .mib
+ mov gp = GR_SAVE_GP
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_libm_ldexpl.S b/libc/sysdeps/ia64/fpu/s_libm_ldexpl.S
new file mode 100644
index 000000000..fffda9e55
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_libm_ldexpl.S
@@ -0,0 +1,452 @@
+.file "libm_ldexpl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 01/26/01 ldexpl completely reworked and now standalone version
+// 01/04/02 Added handling for int 32 or 64 bits
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 08/04/03 Improved performance
+//
+// API
+//==============================================================
+// long double __libm_ldexpl (long double x, int n, int int_type)
+// input floating point f8 and int n (r34), int int_type (r35)
+// output floating point f8
+//
+// int_type = 0 if int is 32 bits
+// int_type = 1 if int is 64 bits
+//
+// Returns x* 2**n using an fma and detects overflow
+// and underflow.
+//
+//
+// Strategy:
+// Compute biased exponent of result exp_Result = N + exp_X
+// Break into ranges:
+// exp_Result > 0x13ffe -> Certain overflow
+// exp_Result = 0x13ffe -> Possible overflow
+// 0x0c001 <= exp_Result < 0x13ffe -> No over/underflow (main path)
+// 0x0c001 - 63 <= exp_Result < 0x0c001 -> Possible underflow
+// exp_Result < 0x0c001 - 63 -> Certain underflow
+
+FR_Big = f6
+FR_NBig = f7
+FR_Floating_X = f8
+FR_Result = f8
+FR_Result2 = f9
+FR_Result3 = f10
+FR_Norm_X = f11
+FR_Two_N = f12
+
+GR_neg_ov_limit= r14
+GR_N_Biased = r15
+GR_Big = r16
+GR_NBig = r17
+GR_exp_Result = r18
+GR_pos_ov_limit= r19
+GR_Bias = r20
+GR_N_as_int = r21
+GR_signexp_X = r22
+GR_exp_X = r23
+GR_exp_mask = r24
+GR_max_exp = r25
+GR_min_exp = r26
+GR_min_den_exp = r27
+
+GR_SAVE_B0 = r32
+GR_SAVE_GP = r33
+GR_SAVE_PFS = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Tag = r38
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_ldexpl)
+
+//
+// Is x NAN, INF, ZERO, +-?
+// Build the exponent Bias
+//
+{ .mfi
+ getf.exp GR_signexp_X = FR_Floating_X // Get signexp of x
+ fclass.m p6,p0 = FR_Floating_X, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_Bias = 0x0ffff
+}
+//
+// Normalize x
+// Is integer type 32 bits?
+//
+{ .mfi
+ mov GR_Big = 35000 // If N this big then certain overflow
+ fnorm.s1 FR_Norm_X = FR_Floating_X
+ cmp.eq p8,p9 = r35,r0
+}
+;;
+
+// Sign extend N if int is 32 bits
+{ .mfi
+(p9) mov GR_N_as_int = r34 // Copy N if int is 64 bits
+ fclass.m p9,p0 = FR_Floating_X, 0x0b // Test for x=unorm
+(p8) sxt4 GR_N_as_int = r34 // Sign extend N if int is 32 bits
+}
+{ .mfi
+ mov GR_NBig = -35000 // If N this small then certain underflow
+ nop.f 0
+ mov GR_max_exp = 0x13ffe // Exponent of maximum long double
+}
+;;
+
+// Create biased exponent for 2**N
+{ .mfi
+ add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.ge p7, p0 = GR_N_as_int, GR_Big // Certain overflow?
+}
+{ .mib
+ cmp.le p8, p0 = GR_N_as_int, GR_NBig // Certain underflow?
+ mov GR_min_exp = 0x0c001 // Exponent of minimum long double
+(p9) br.cond.spnt LDEXPL_UNORM // Branch if x=unorm
+}
+;;
+
+LDEXPL_COMMON:
+// Main path continues. Also return here from x=unorm path.
+// Create 2**N
+.pred.rel "mutex",p7,p8
+{ .mfi
+ setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+(p7) mov GR_N_as_int = GR_Big // Limit max N
+}
+{ .mfi
+(p8) mov GR_N_as_int = GR_NBig // Limit min N
+ nop.f 0
+(p8) cmp.eq p7,p0 = r0,r0 // Set p7 if |N| big
+}
+;;
+
+//
+// Create biased exponent for 2**N for N big
+// Is N zero?
+//
+{ .mfi
+(p7) add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.eq.or p6,p0 = r34,r0
+}
+{ .mfi
+ mov GR_pos_ov_limit = 0x13fff // Exponent for positive overflow
+ nop.f 0
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+}
+;;
+
+//
+// Create 2**N for N big
+// Return x when N = 0 or X = Nan, Inf, Zero
+//
+{ .mfi
+(p7) setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+ mov GR_min_den_exp = 0x0c001 - 63 // Exp of min denorm long dble
+}
+{ .mfb
+ and GR_exp_X = GR_exp_mask, GR_signexp_X
+(p6) fma.s0 FR_Result = FR_Floating_X, f1, f0
+(p6) br.ret.spnt b0
+}
+;;
+
+//
+// Raise Denormal operand flag with compare
+// Compute biased result exponent
+//
+{ .mfi
+ add GR_exp_Result = GR_exp_X, GR_N_as_int
+ fcmp.ge.s0 p0,p11 = FR_Floating_X,f0
+ mov GR_neg_ov_limit = 0x33fff // Exponent for negative overflow
+}
+;;
+
+//
+// Do final operation
+//
+{ .mfi
+ cmp.lt p7,p6 = GR_exp_Result, GR_max_exp // Test no overflow
+ fma.s0 FR_Result = FR_Two_N,FR_Norm_X,f0
+ cmp.lt p9,p0 = GR_exp_Result, GR_min_den_exp // Test sure underflow
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p9) br.cond.spnt LDEXPL_UNDERFLOW // Branch if certain underflow
+}
+;;
+
+{ .mib
+(p6) cmp.gt.unc p6,p8 = GR_exp_Result, GR_max_exp // Test sure overflow
+(p7) cmp.ge.unc p7,p9 = GR_exp_Result, GR_min_exp // Test no over/underflow
+(p7) br.ret.sptk b0 // Return from main path
+}
+;;
+
+{ .bbb
+(p6) br.cond.spnt LDEXPL_OVERFLOW // Branch if certain overflow
+(p8) br.cond.spnt LDEXPL_POSSIBLE_OVERFLOW // Branch if possible overflow
+(p9) br.cond.spnt LDEXPL_POSSIBLE_UNDERFLOW // Branch if possible underflow
+}
+;;
+
+// Here if possible underflow.
+// Resulting exponent: 0x0c001-63 <= exp_Result < 0x0c001
+LDEXPL_POSSIBLE_UNDERFLOW:
+//
+// Here if possible overflow.
+// Resulting exponent: 0x13ffe = exp_Result
+LDEXPL_POSSIBLE_OVERFLOW:
+
+// Set up necessary status fields
+//
+// S0 user supplied status
+// S2 user supplied status + WRE + TD (Overflows)
+// S3 user supplied status + FZ + TD (Underflows)
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x41
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x42
+ nop.i 0
+}
+;;
+
+//
+// Do final operation with s2 and s3
+//
+{ .mfi
+ setf.exp FR_NBig = GR_neg_ov_limit
+ fma.s3 FR_Result3 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+{ .mfi
+ setf.exp FR_Big = GR_pos_ov_limit
+ fma.s2 FR_Result2 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+;;
+
+// Check for overflow or underflow.
+// Restore s3
+// Restore s2
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x40
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40
+ nop.i 0
+}
+;;
+
+//
+// Is the result zero?
+//
+{ .mfi
+ nop.m 0
+ fclass.m p6, p0 = FR_Result3, 0x007
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p7, p8 = FR_Result2 , FR_Big
+ nop.i 0
+}
+;;
+
+//
+// Detect masked underflow - Tiny + Inexact Only
+//
+{ .mfi
+ nop.m 0
+(p6) fcmp.neq.unc.s1 p6, p0 = FR_Result , FR_Result2
+ nop.i 0
+}
+;;
+
+//
+// Is result bigger the allowed range?
+// Branch out for underflow
+//
+{ .mfb
+ nop.m 0
+(p8) fcmp.le.unc.s1 p9, p10 = FR_Result2 , FR_NBig
+(p6) br.cond.spnt LDEXPL_UNDERFLOW
+}
+;;
+
+//
+// Branch out for overflow
+//
+{ .bbb
+(p7) br.cond.spnt LDEXPL_OVERFLOW
+(p9) br.cond.spnt LDEXPL_OVERFLOW
+ br.ret.sptk b0 // Return from main path.
+}
+;;
+
+// Here if result overflows
+LDEXPL_OVERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 144, r0 // Set error tag for overflow
+ br.cond.sptk __libm_error_region // Call error support for overflow
+}
+;;
+
+// Here if result underflows
+LDEXPL_UNDERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 145, r0 // Set error tag for underflow
+ br.cond.sptk __libm_error_region // Call error support for underflow
+}
+;;
+
+// Here if x=unorm
+LDEXPL_UNORM:
+{ .mib
+ getf.exp GR_signexp_X = FR_Norm_X // Get signexp of normalized x
+ nop.i 0
+ br.cond.sptk LDEXPL_COMMON // Return to main path
+}
+;;
+
+
+GLOBAL_LIBM_END(__libm_ldexpl)
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+//
+// Get stack address of N
+//
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs
+}
+//
+// Adjust sp
+//
+{ .mfi
+.fframe 64
+ add sp=-64,sp
+ nop.f 0
+ mov GR_SAVE_GP=gp
+};;
+
+//
+// Store N on stack in correct position
+// Locate the address of x on stack
+//
+{ .mmi
+ st8 [GR_Parameter_Y] = GR_N_as_int,16
+ add GR_Parameter_X = 16,sp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0
+};;
+
+//
+// Store x on the stack.
+// Get address for result on stack.
+//
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_Norm_X
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_Result
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support#
+};;
+
+//
+// Get location of result on stack
+//
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+//
+// Get the new result
+//
+{ .mmi
+ ldfe FR_Result = [GR_Parameter_RESULT]
+.restore sp
+ add sp = 64,sp
+ mov b0 = GR_SAVE_B0
+};;
+
+//
+// Restore gp, ar.pfs and return
+//
+{ .mib
+ mov gp = GR_SAVE_GP
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_libm_scalbn.S b/libc/sysdeps/ia64/fpu/s_libm_scalbn.S
new file mode 100644
index 000000000..eaccb7de7
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_libm_scalbn.S
@@ -0,0 +1,452 @@
+.file "libm_scalbn.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 01/26/01 Scalbn completely reworked and now standalone version
+// 01/04/02 Added handling for int 32 or 64 bits
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 08/04/03 Improved performance
+//
+// API
+//==============================================================
+// double __libm_scalbn (double x, int n, int int_type)
+// input floating point f8 and int n (r33), int int_type (r34)
+// output floating point f8
+//
+// int_type = 0 if int is 32 bits
+// int_type = 1 if int is 64 bits
+//
+// Returns x* 2**n using an fma and detects overflow
+// and underflow.
+//
+//
+// Strategy:
+// Compute biased exponent of result exp_Result = N + exp_X
+// Break into ranges:
+// exp_Result > 0x103fe -> Certain overflow
+// exp_Result = 0x103fe -> Possible overflow
+// 0x0fc01 <= exp_Result < 0x103fe -> No over/underflow (main path)
+// 0x0fc01 - 52 <= exp_Result < 0x0fc01 -> Possible underflow
+// exp_Result < 0x0fc01 - 52 -> Certain underflow
+
+FR_Big = f6
+FR_NBig = f7
+FR_Floating_X = f8
+FR_Result = f8
+FR_Result2 = f9
+FR_Result3 = f10
+FR_Norm_X = f11
+FR_Two_N = f12
+
+GR_neg_ov_limit= r14
+GR_N_Biased = r15
+GR_Big = r16
+GR_NBig = r17
+GR_exp_Result = r18
+GR_pos_ov_limit= r19
+GR_Bias = r20
+GR_N_as_int = r21
+GR_signexp_X = r22
+GR_exp_X = r23
+GR_exp_mask = r24
+GR_max_exp = r25
+GR_min_exp = r26
+GR_min_den_exp = r27
+
+GR_SAVE_B0 = r32
+GR_SAVE_GP = r33
+GR_SAVE_PFS = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Tag = r38
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_scalbn)
+
+//
+// Is x NAN, INF, ZERO, +-?
+// Build the exponent Bias
+//
+{ .mfi
+ getf.exp GR_signexp_X = FR_Floating_X // Get signexp of x
+ fclass.m p6,p0 = FR_Floating_X, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_Bias = 0x0ffff
+}
+//
+// Normalize x
+// Is integer type 32 bits?
+//
+{ .mfi
+ mov GR_Big = 35000 // If N this big then certain overflow
+ fnorm.s1 FR_Norm_X = FR_Floating_X
+ cmp.eq p8,p9 = r34,r0
+}
+;;
+
+// Sign extend N if int is 32 bits
+{ .mfi
+(p9) mov GR_N_as_int = r33 // Copy N if int is 64 bits
+ fclass.m p9,p0 = FR_Floating_X, 0x0b // Test for x=unorm
+(p8) sxt4 GR_N_as_int = r33 // Sign extend N if int is 32 bits
+}
+{ .mfi
+ mov GR_NBig = -35000 // If N this small then certain underflow
+ nop.f 0
+ mov GR_max_exp = 0x103fe // Exponent of maximum double
+}
+;;
+
+// Create biased exponent for 2**N
+{ .mfi
+ add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.ge p7, p0 = GR_N_as_int, GR_Big // Certain overflow?
+}
+{ .mib
+ cmp.le p8, p0 = GR_N_as_int, GR_NBig // Certain underflow?
+ mov GR_min_exp = 0x0fc01 // Exponent of minimum double
+(p9) br.cond.spnt SCALBN_UNORM // Branch if x=unorm
+}
+;;
+
+SCALBN_COMMON:
+// Main path continues. Also return here from x=unorm path.
+// Create 2**N
+.pred.rel "mutex",p7,p8
+{ .mfi
+ setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+(p7) mov GR_N_as_int = GR_Big // Limit max N
+}
+{ .mfi
+(p8) mov GR_N_as_int = GR_NBig // Limit min N
+ nop.f 0
+(p8) cmp.eq p7,p0 = r0,r0 // Set p7 if |N| big
+}
+;;
+
+//
+// Create biased exponent for 2**N for N big
+// Is N zero?
+//
+{ .mfi
+(p7) add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.eq.or p6,p0 = r33,r0
+}
+{ .mfi
+ mov GR_pos_ov_limit = 0x103ff // Exponent for positive overflow
+ nop.f 0
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+}
+;;
+
+//
+// Create 2**N for N big
+// Return x when N = 0 or X = Nan, Inf, Zero
+//
+{ .mfi
+(p7) setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+ mov GR_min_den_exp = 0x0fc01 - 52 // Exponent of min denorm dble
+}
+{ .mfb
+ and GR_exp_X = GR_exp_mask, GR_signexp_X
+(p6) fma.d.s0 FR_Result = FR_Floating_X, f1, f0
+(p6) br.ret.spnt b0
+}
+;;
+
+//
+// Raise Denormal operand flag with compare
+// Compute biased result exponent
+//
+{ .mfi
+ add GR_exp_Result = GR_exp_X, GR_N_as_int
+ fcmp.ge.s0 p0,p11 = FR_Floating_X,f0
+ mov GR_neg_ov_limit = 0x303ff // Exponent for negative overflow
+}
+;;
+
+//
+// Do final operation
+//
+{ .mfi
+ cmp.lt p7,p6 = GR_exp_Result, GR_max_exp // Test no overflow
+ fma.d.s0 FR_Result = FR_Two_N,FR_Norm_X,f0
+ cmp.lt p9,p0 = GR_exp_Result, GR_min_den_exp // Test sure underflow
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p9) br.cond.spnt SCALBN_UNDERFLOW // Branch if certain underflow
+}
+;;
+
+{ .mib
+(p6) cmp.gt.unc p6,p8 = GR_exp_Result, GR_max_exp // Test sure overflow
+(p7) cmp.ge.unc p7,p9 = GR_exp_Result, GR_min_exp // Test no over/underflow
+(p7) br.ret.sptk b0 // Return from main path
+}
+;;
+
+{ .bbb
+(p6) br.cond.spnt SCALBN_OVERFLOW // Branch if certain overflow
+(p8) br.cond.spnt SCALBN_POSSIBLE_OVERFLOW // Branch if possible overflow
+(p9) br.cond.spnt SCALBN_POSSIBLE_UNDERFLOW // Branch if possible underflow
+}
+;;
+
+// Here if possible underflow.
+// Resulting exponent: 0x0fc01-52 <= exp_Result < 0x0fc01
+SCALBN_POSSIBLE_UNDERFLOW:
+//
+// Here if possible overflow.
+// Resulting exponent: 0x103fe = exp_Result
+SCALBN_POSSIBLE_OVERFLOW:
+
+// Set up necessary status fields
+//
+// S0 user supplied status
+// S2 user supplied status + WRE + TD (Overflows)
+// S3 user supplied status + FZ + TD (Underflows)
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x41
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x42
+ nop.i 0
+}
+;;
+
+//
+// Do final operation with s2 and s3
+//
+{ .mfi
+ setf.exp FR_NBig = GR_neg_ov_limit
+ fma.d.s3 FR_Result3 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+{ .mfi
+ setf.exp FR_Big = GR_pos_ov_limit
+ fma.d.s2 FR_Result2 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+;;
+
+// Check for overflow or underflow.
+// Restore s3
+// Restore s2
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x40
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40
+ nop.i 0
+}
+;;
+
+//
+// Is the result zero?
+//
+{ .mfi
+ nop.m 0
+ fclass.m p6, p0 = FR_Result3, 0x007
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p7, p8 = FR_Result2 , FR_Big
+ nop.i 0
+}
+;;
+
+//
+// Detect masked underflow - Tiny + Inexact Only
+//
+{ .mfi
+ nop.m 0
+(p6) fcmp.neq.unc.s1 p6, p0 = FR_Result , FR_Result2
+ nop.i 0
+}
+;;
+
+//
+// Is result bigger the allowed range?
+// Branch out for underflow
+//
+{ .mfb
+ nop.m 0
+(p8) fcmp.le.unc.s1 p9, p10 = FR_Result2 , FR_NBig
+(p6) br.cond.spnt SCALBN_UNDERFLOW
+}
+;;
+
+//
+// Branch out for overflow
+//
+{ .bbb
+(p7) br.cond.spnt SCALBN_OVERFLOW
+(p9) br.cond.spnt SCALBN_OVERFLOW
+ br.ret.sptk b0 // Return from main path.
+}
+;;
+
+// Here if result overflows
+SCALBN_OVERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 176, r0 // Set error tag for overflow
+ br.cond.sptk __libm_error_region // Call error support for overflow
+}
+;;
+
+// Here if result underflows
+SCALBN_UNDERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 177, r0 // Set error tag for underflow
+ br.cond.sptk __libm_error_region // Call error support for underflow
+}
+;;
+
+// Here if x=unorm
+SCALBN_UNORM:
+{ .mib
+ getf.exp GR_signexp_X = FR_Norm_X // Get signexp of normalized x
+ nop.i 0
+ br.cond.sptk SCALBN_COMMON // Return to main path
+}
+;;
+
+
+GLOBAL_LIBM_END(__libm_scalbn)
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+//
+// Get stack address of N
+//
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs
+}
+//
+// Adjust sp
+//
+{ .mfi
+.fframe 64
+ add sp=-64,sp
+ nop.f 0
+ mov GR_SAVE_GP=gp
+};;
+
+//
+// Store N on stack in correct position
+// Locate the address of x on stack
+//
+{ .mmi
+ st8 [GR_Parameter_Y] = GR_N_as_int,16
+ add GR_Parameter_X = 16,sp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0
+};;
+
+//
+// Store x on the stack.
+// Get address for result on stack.
+//
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_Norm_X
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_Result
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support#
+};;
+
+//
+// Get location of result on stack
+//
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+//
+// Get the new result
+//
+{ .mmi
+ ldfd FR_Result = [GR_Parameter_RESULT]
+.restore sp
+ add sp = 64,sp
+ mov b0 = GR_SAVE_B0
+};;
+
+//
+// Restore gp, ar.pfs and return
+//
+{ .mib
+ mov gp = GR_SAVE_GP
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_libm_scalbnf.S b/libc/sysdeps/ia64/fpu/s_libm_scalbnf.S
new file mode 100644
index 000000000..e00997aba
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_libm_scalbnf.S
@@ -0,0 +1,452 @@
+.file "libm_scalbnf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 01/26/01 Scalbnf completely reworked and now standalone version
+// 01/04/02 Added handling for int 32 or 64 bits
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 08/04/03 Improved performance
+//
+// API
+//==============================================================
+// float __libm_scalbnf (float x, int n, int int_type)
+// input floating point f8 and int n (r33), int int_type (r34)
+// output floating point f8
+//
+// int_type = 0 if int is 32 bits
+// int_type = 1 if int is 64 bits
+//
+// Returns x* 2**n using an fma and detects overflow
+// and underflow.
+//
+//
+// Strategy:
+// Compute biased exponent of result exp_Result = N + exp_X
+// Break into ranges:
+// exp_Result > 0x1007e -> Certain overflow
+// exp_Result = 0x1007e -> Possible overflow
+// 0x0ff81 <= exp_Result < 0x1007e -> No over/underflow (main path)
+// 0x0ff81 - 23 <= exp_Result < 0x0ff81 -> Possible underflow
+// exp_Result < 0x0ff81 - 23 -> Certain underflow
+
+FR_Big = f6
+FR_NBig = f7
+FR_Floating_X = f8
+FR_Result = f8
+FR_Result2 = f9
+FR_Result3 = f10
+FR_Norm_X = f11
+FR_Two_N = f12
+
+GR_neg_ov_limit= r14
+GR_N_Biased = r15
+GR_Big = r16
+GR_NBig = r17
+GR_exp_Result = r18
+GR_pos_ov_limit= r19
+GR_Bias = r20
+GR_N_as_int = r21
+GR_signexp_X = r22
+GR_exp_X = r23
+GR_exp_mask = r24
+GR_max_exp = r25
+GR_min_exp = r26
+GR_min_den_exp = r27
+
+GR_SAVE_B0 = r32
+GR_SAVE_GP = r33
+GR_SAVE_PFS = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Tag = r38
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_scalbnf)
+
+//
+// Is x NAN, INF, ZERO, +-?
+// Build the exponent Bias
+//
+{ .mfi
+ getf.exp GR_signexp_X = FR_Floating_X // Get signexp of x
+ fclass.m p6,p0 = FR_Floating_X, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_Bias = 0x0ffff
+}
+//
+// Normalize x
+// Is integer type 32 bits?
+//
+{ .mfi
+ mov GR_Big = 35000 // If N this big then certain overflow
+ fnorm.s1 FR_Norm_X = FR_Floating_X
+ cmp.eq p8,p9 = r34,r0
+}
+;;
+
+// Sign extend N if int is 32 bits
+{ .mfi
+(p9) mov GR_N_as_int = r33 // Copy N if int is 64 bits
+ fclass.m p9,p0 = FR_Floating_X, 0x0b // Test for x=unorm
+(p8) sxt4 GR_N_as_int = r33 // Sign extend N if int is 32 bits
+}
+{ .mfi
+ mov GR_NBig = -35000 // If N this small then certain underflow
+ nop.f 0
+ mov GR_max_exp = 0x1007e // Exponent of maximum float
+}
+;;
+
+// Create biased exponent for 2**N
+{ .mfi
+ add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.ge p7, p0 = GR_N_as_int, GR_Big // Certain overflow?
+}
+{ .mib
+ cmp.le p8, p0 = GR_N_as_int, GR_NBig // Certain underflow?
+ mov GR_min_exp = 0x0ff81 // Exponent of minimum float
+(p9) br.cond.spnt SCALBNF_UNORM // Branch if x=unorm
+}
+;;
+
+SCALBNF_COMMON:
+// Main path continues. Also return here from x=unorm path.
+// Create 2**N
+.pred.rel "mutex",p7,p8
+{ .mfi
+ setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+(p7) mov GR_N_as_int = GR_Big // Limit max N
+}
+{ .mfi
+(p8) mov GR_N_as_int = GR_NBig // Limit min N
+ nop.f 0
+(p8) cmp.eq p7,p0 = r0,r0 // Set p7 if |N| big
+}
+;;
+
+//
+// Create biased exponent for 2**N for N big
+// Is N zero?
+//
+{ .mfi
+(p7) add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.eq.or p6,p0 = r33,r0
+}
+{ .mfi
+ mov GR_pos_ov_limit = 0x1007f // Exponent for positive overflow
+ nop.f 0
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+}
+;;
+
+//
+// Create 2**N for N big
+// Return x when N = 0 or X = Nan, Inf, Zero
+//
+{ .mfi
+(p7) setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+ mov GR_min_den_exp = 0x0ff81 - 23 // Exponent of min denorm float
+}
+{ .mfb
+ and GR_exp_X = GR_exp_mask, GR_signexp_X
+(p6) fma.s.s0 FR_Result = FR_Floating_X, f1, f0
+(p6) br.ret.spnt b0
+}
+;;
+
+//
+// Raise Denormal operand flag with compare
+// Compute biased result exponent
+//
+{ .mfi
+ add GR_exp_Result = GR_exp_X, GR_N_as_int
+ fcmp.ge.s0 p0,p11 = FR_Floating_X,f0
+ mov GR_neg_ov_limit = 0x3007f // Exponent for negative overflow
+}
+;;
+
+//
+// Do final operation
+//
+{ .mfi
+ cmp.lt p7,p6 = GR_exp_Result, GR_max_exp // Test no overflow
+ fma.s.s0 FR_Result = FR_Two_N,FR_Norm_X,f0
+ cmp.lt p9,p0 = GR_exp_Result, GR_min_den_exp // Test sure underflow
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p9) br.cond.spnt SCALBNF_UNDERFLOW // Branch if certain underflow
+}
+;;
+
+{ .mib
+(p6) cmp.gt.unc p6,p8 = GR_exp_Result, GR_max_exp // Test sure overflow
+(p7) cmp.ge.unc p7,p9 = GR_exp_Result, GR_min_exp // Test no over/underflow
+(p7) br.ret.sptk b0 // Return from main path
+}
+;;
+
+{ .bbb
+(p6) br.cond.spnt SCALBNF_OVERFLOW // Branch if certain overflow
+(p8) br.cond.spnt SCALBNF_POSSIBLE_OVERFLOW // Branch if possible overflow
+(p9) br.cond.spnt SCALBNF_POSSIBLE_UNDERFLOW // Branch if possible underflow
+}
+;;
+
+// Here if possible underflow.
+// Resulting exponent: 0x0ff81-23 <= exp_Result < 0x0ff81
+SCALBNF_POSSIBLE_UNDERFLOW:
+//
+// Here if possible overflow.
+// Resulting exponent: 0x1007e = exp_Result
+SCALBNF_POSSIBLE_OVERFLOW:
+
+// Set up necessary status fields
+//
+// S0 user supplied status
+// S2 user supplied status + WRE + TD (Overflows)
+// S3 user supplied status + FZ + TD (Underflows)
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x41
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x42
+ nop.i 0
+}
+;;
+
+//
+// Do final operation with s2 and s3
+//
+{ .mfi
+ setf.exp FR_NBig = GR_neg_ov_limit
+ fma.s.s3 FR_Result3 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+{ .mfi
+ setf.exp FR_Big = GR_pos_ov_limit
+ fma.s.s2 FR_Result2 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+;;
+
+// Check for overflow or underflow.
+// Restore s3
+// Restore s2
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x40
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40
+ nop.i 0
+}
+;;
+
+//
+// Is the result zero?
+//
+{ .mfi
+ nop.m 0
+ fclass.m p6, p0 = FR_Result3, 0x007
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p7, p8 = FR_Result2 , FR_Big
+ nop.i 0
+}
+;;
+
+//
+// Detect masked underflow - Tiny + Inexact Only
+//
+{ .mfi
+ nop.m 0
+(p6) fcmp.neq.unc.s1 p6, p0 = FR_Result , FR_Result2
+ nop.i 0
+}
+;;
+
+//
+// Is result bigger the allowed range?
+// Branch out for underflow
+//
+{ .mfb
+ nop.m 0
+(p8) fcmp.le.unc.s1 p9, p10 = FR_Result2 , FR_NBig
+(p6) br.cond.spnt SCALBNF_UNDERFLOW
+}
+;;
+
+//
+// Branch out for overflow
+//
+{ .bbb
+(p7) br.cond.spnt SCALBNF_OVERFLOW
+(p9) br.cond.spnt SCALBNF_OVERFLOW
+ br.ret.sptk b0 // Return from main path.
+}
+;;
+
+// Here if result overflows
+SCALBNF_OVERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 178, r0 // Set error tag for overflow
+ br.cond.sptk __libm_error_region // Call error support for overflow
+}
+;;
+
+// Here if result underflows
+SCALBNF_UNDERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 179, r0 // Set error tag for underflow
+ br.cond.sptk __libm_error_region // Call error support for underflow
+}
+;;
+
+// Here if x=unorm
+SCALBNF_UNORM:
+{ .mib
+ getf.exp GR_signexp_X = FR_Norm_X // Get signexp of normalized x
+ nop.i 0
+ br.cond.sptk SCALBNF_COMMON // Return to main path
+}
+;;
+
+
+GLOBAL_LIBM_END(__libm_scalbnf)
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+//
+// Get stack address of N
+//
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs
+}
+//
+// Adjust sp
+//
+{ .mfi
+.fframe 64
+ add sp=-64,sp
+ nop.f 0
+ mov GR_SAVE_GP=gp
+};;
+
+//
+// Store N on stack in correct position
+// Locate the address of x on stack
+//
+{ .mmi
+ st8 [GR_Parameter_Y] = GR_N_as_int,16
+ add GR_Parameter_X = 16,sp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0
+};;
+
+//
+// Store x on the stack.
+// Get address for result on stack.
+//
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_Norm_X
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_Result
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support#
+};;
+
+//
+// Get location of result on stack
+//
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+//
+// Get the new result
+//
+{ .mmi
+ ldfs FR_Result = [GR_Parameter_RESULT]
+.restore sp
+ add sp = 64,sp
+ mov b0 = GR_SAVE_B0
+};;
+
+//
+// Restore gp, ar.pfs and return
+//
+{ .mib
+ mov gp = GR_SAVE_GP
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_libm_scalbnl.S b/libc/sysdeps/ia64/fpu/s_libm_scalbnl.S
new file mode 100644
index 000000000..1edf9a05d
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_libm_scalbnl.S
@@ -0,0 +1,452 @@
+.file "libm_scalbnl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 01/26/01 Scalbnl completely reworked and now standalone version
+// 01/04/02 Added handling for int 32 or 64 bits
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 08/04/03 Improved performance
+//
+// API
+//==============================================================
+// long double __libm_scalbnl (long double x, int n, int int_type)
+// input floating point f8 and int n (r34), int int_type (r35)
+// output floating point f8
+//
+// int_type = 0 if int is 32 bits
+// int_type = 1 if int is 64 bits
+//
+// Returns x* 2**n using an fma and detects overflow
+// and underflow.
+//
+//
+// Strategy:
+// Compute biased exponent of result exp_Result = N + exp_X
+// Break into ranges:
+// exp_Result > 0x13ffe -> Certain overflow
+// exp_Result = 0x13ffe -> Possible overflow
+// 0x0c001 <= exp_Result < 0x13ffe -> No over/underflow (main path)
+// 0x0c001 - 63 <= exp_Result < 0x0c001 -> Possible underflow
+// exp_Result < 0x0c001 - 63 -> Certain underflow
+
+FR_Big = f6
+FR_NBig = f7
+FR_Floating_X = f8
+FR_Result = f8
+FR_Result2 = f9
+FR_Result3 = f10
+FR_Norm_X = f11
+FR_Two_N = f12
+
+GR_neg_ov_limit= r14
+GR_N_Biased = r15
+GR_Big = r16
+GR_NBig = r17
+GR_exp_Result = r18
+GR_pos_ov_limit= r19
+GR_Bias = r20
+GR_N_as_int = r21
+GR_signexp_X = r22
+GR_exp_X = r23
+GR_exp_mask = r24
+GR_max_exp = r25
+GR_min_exp = r26
+GR_min_den_exp = r27
+
+GR_SAVE_B0 = r32
+GR_SAVE_GP = r33
+GR_SAVE_PFS = r34
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Tag = r38
+
+.section .text
+GLOBAL_LIBM_ENTRY(__libm_scalbnl)
+
+//
+// Is x NAN, INF, ZERO, +-?
+// Build the exponent Bias
+//
+{ .mfi
+ getf.exp GR_signexp_X = FR_Floating_X // Get signexp of x
+ fclass.m p6,p0 = FR_Floating_X, 0xe7 // @snan | @qnan | @inf | @zero
+ mov GR_Bias = 0x0ffff
+}
+//
+// Normalize x
+// Is integer type 32 bits?
+//
+{ .mfi
+ mov GR_Big = 35000 // If N this big then certain overflow
+ fnorm.s1 FR_Norm_X = FR_Floating_X
+ cmp.eq p8,p9 = r35,r0
+}
+;;
+
+// Sign extend N if int is 32 bits
+{ .mfi
+(p9) mov GR_N_as_int = r34 // Copy N if int is 64 bits
+ fclass.m p9,p0 = FR_Floating_X, 0x0b // Test for x=unorm
+(p8) sxt4 GR_N_as_int = r34 // Sign extend N if int is 32 bits
+}
+{ .mfi
+ mov GR_NBig = -35000 // If N this small then certain underflow
+ nop.f 0
+ mov GR_max_exp = 0x13ffe // Exponent of maximum long double
+}
+;;
+
+// Create biased exponent for 2**N
+{ .mfi
+ add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.ge p7, p0 = GR_N_as_int, GR_Big // Certain overflow?
+}
+{ .mib
+ cmp.le p8, p0 = GR_N_as_int, GR_NBig // Certain underflow?
+ mov GR_min_exp = 0x0c001 // Exponent of minimum long double
+(p9) br.cond.spnt SCALBNL_UNORM // Branch if x=unorm
+}
+;;
+
+SCALBNL_COMMON:
+// Main path continues. Also return here from x=unorm path.
+// Create 2**N
+.pred.rel "mutex",p7,p8
+{ .mfi
+ setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+(p7) mov GR_N_as_int = GR_Big // Limit max N
+}
+{ .mfi
+(p8) mov GR_N_as_int = GR_NBig // Limit min N
+ nop.f 0
+(p8) cmp.eq p7,p0 = r0,r0 // Set p7 if |N| big
+}
+;;
+
+//
+// Create biased exponent for 2**N for N big
+// Is N zero?
+//
+{ .mfi
+(p7) add GR_N_Biased = GR_Bias,GR_N_as_int
+ nop.f 0
+ cmp.eq.or p6,p0 = r34,r0
+}
+{ .mfi
+ mov GR_pos_ov_limit = 0x13fff // Exponent for positive overflow
+ nop.f 0
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+}
+;;
+
+//
+// Create 2**N for N big
+// Return x when N = 0 or X = Nan, Inf, Zero
+//
+{ .mfi
+(p7) setf.exp FR_Two_N = GR_N_Biased
+ nop.f 0
+ mov GR_min_den_exp = 0x0c001 - 63 // Exp of min denorm long dble
+}
+{ .mfb
+ and GR_exp_X = GR_exp_mask, GR_signexp_X
+(p6) fma.s0 FR_Result = FR_Floating_X, f1, f0
+(p6) br.ret.spnt b0
+}
+;;
+
+//
+// Raise Denormal operand flag with compare
+// Compute biased result exponent
+//
+{ .mfi
+ add GR_exp_Result = GR_exp_X, GR_N_as_int
+ fcmp.ge.s0 p0,p11 = FR_Floating_X,f0
+ mov GR_neg_ov_limit = 0x33fff // Exponent for negative overflow
+}
+;;
+
+//
+// Do final operation
+//
+{ .mfi
+ cmp.lt p7,p6 = GR_exp_Result, GR_max_exp // Test no overflow
+ fma.s0 FR_Result = FR_Two_N,FR_Norm_X,f0
+ cmp.lt p9,p0 = GR_exp_Result, GR_min_den_exp // Test sure underflow
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p9) br.cond.spnt SCALBNL_UNDERFLOW // Branch if certain underflow
+}
+;;
+
+{ .mib
+(p6) cmp.gt.unc p6,p8 = GR_exp_Result, GR_max_exp // Test sure overflow
+(p7) cmp.ge.unc p7,p9 = GR_exp_Result, GR_min_exp // Test no over/underflow
+(p7) br.ret.sptk b0 // Return from main path
+}
+;;
+
+{ .bbb
+(p6) br.cond.spnt SCALBNL_OVERFLOW // Branch if certain overflow
+(p8) br.cond.spnt SCALBNL_POSSIBLE_OVERFLOW // Branch if possible overflow
+(p9) br.cond.spnt SCALBNL_POSSIBLE_UNDERFLOW // Branch if possible underflow
+}
+;;
+
+// Here if possible underflow.
+// Resulting exponent: 0x0c001-63 <= exp_Result < 0x0c001
+SCALBNL_POSSIBLE_UNDERFLOW:
+//
+// Here if possible overflow.
+// Resulting exponent: 0x13ffe = exp_Result
+SCALBNL_POSSIBLE_OVERFLOW:
+
+// Set up necessary status fields
+//
+// S0 user supplied status
+// S2 user supplied status + WRE + TD (Overflows)
+// S3 user supplied status + FZ + TD (Underflows)
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x41
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x42
+ nop.i 0
+}
+;;
+
+//
+// Do final operation with s2 and s3
+//
+{ .mfi
+ setf.exp FR_NBig = GR_neg_ov_limit
+ fma.s3 FR_Result3 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+{ .mfi
+ setf.exp FR_Big = GR_pos_ov_limit
+ fma.s2 FR_Result2 = FR_Two_N,FR_Norm_X,f0
+ nop.i 0
+}
+;;
+
+// Check for overflow or underflow.
+// Restore s3
+// Restore s2
+//
+{ .mfi
+ nop.m 0
+ fsetc.s3 0x7F,0x40
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7F,0x40
+ nop.i 0
+}
+;;
+
+//
+// Is the result zero?
+//
+{ .mfi
+ nop.m 0
+ fclass.m p6, p0 = FR_Result3, 0x007
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p7, p8 = FR_Result2 , FR_Big
+ nop.i 0
+}
+;;
+
+//
+// Detect masked underflow - Tiny + Inexact Only
+//
+{ .mfi
+ nop.m 0
+(p6) fcmp.neq.unc.s1 p6, p0 = FR_Result , FR_Result2
+ nop.i 0
+}
+;;
+
+//
+// Is result bigger the allowed range?
+// Branch out for underflow
+//
+{ .mfb
+ nop.m 0
+(p8) fcmp.le.unc.s1 p9, p10 = FR_Result2 , FR_NBig
+(p6) br.cond.spnt SCALBNL_UNDERFLOW
+}
+;;
+
+//
+// Branch out for overflow
+//
+{ .bbb
+(p7) br.cond.spnt SCALBNL_OVERFLOW
+(p9) br.cond.spnt SCALBNL_OVERFLOW
+ br.ret.sptk b0 // Return from main path.
+}
+;;
+
+// Here if result overflows
+SCALBNL_OVERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 174, r0 // Set error tag for overflow
+ br.cond.sptk __libm_error_region // Call error support for overflow
+}
+;;
+
+// Here if result underflows
+SCALBNL_UNDERFLOW:
+{ .mib
+ alloc r32=ar.pfs,3,0,4,0
+ addl GR_Tag = 175, r0 // Set error tag for underflow
+ br.cond.sptk __libm_error_region // Call error support for underflow
+}
+;;
+
+// Here if x=unorm
+SCALBNL_UNORM:
+{ .mib
+ getf.exp GR_signexp_X = FR_Norm_X // Get signexp of normalized x
+ nop.i 0
+ br.cond.sptk SCALBNL_COMMON // Return to main path
+}
+;;
+
+
+GLOBAL_LIBM_END(__libm_scalbnl)
+LOCAL_LIBM_ENTRY(__libm_error_region)
+
+//
+// Get stack address of N
+//
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs
+}
+//
+// Adjust sp
+//
+{ .mfi
+.fframe 64
+ add sp=-64,sp
+ nop.f 0
+ mov GR_SAVE_GP=gp
+};;
+
+//
+// Store N on stack in correct position
+// Locate the address of x on stack
+//
+{ .mmi
+ st8 [GR_Parameter_Y] = GR_N_as_int,16
+ add GR_Parameter_X = 16,sp
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0
+};;
+
+//
+// Store x on the stack.
+// Get address for result on stack.
+//
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_Norm_X
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_Result
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support#
+};;
+
+//
+// Get location of result on stack
+//
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+//
+// Get the new result
+//
+{ .mmi
+ ldfe FR_Result = [GR_Parameter_RESULT]
+.restore sp
+ add sp = 64,sp
+ mov b0 = GR_SAVE_B0
+};;
+
+//
+// Restore gp, ar.pfs and return
+//
+{ .mib
+ mov gp = GR_SAVE_GP
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_log1p.S b/libc/sysdeps/ia64/fpu/s_log1p.S
new file mode 100644
index 000000000..e1e6dcc80
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_log1p.S
@@ -0,0 +1,1103 @@
+.file "log1p.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 06/29/01 Improved speed of all paths
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 10/02/02 Improved performance by basing on log algorithm
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 04/18/03 Eliminate possible WAW dependency warning
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// double log1p(double)
+//
+// log1p(x) = log(x+1)
+//
+// Overview of operation
+//==============================================================
+// Background
+// ----------
+//
+// This algorithm is based on fact that
+// log1p(x) = log(1+x) and
+// log(a b) = log(a) + log(b).
+// In our case we have 1+x = 2^N f, where 1 <= f < 2.
+// So
+// log(1+x) = log(2^N f) = log(2^N) + log(f) = n*log(2) + log(f)
+//
+// To calculate log(f) we do following
+// log(f) = log(f * frcpa(f) / frcpa(f)) =
+// = log(f * frcpa(f)) + log(1/frcpa(f))
+//
+// According to definition of IA-64's frcpa instruction it's a
+// floating point that approximates 1/f using a lookup on the
+// top of 8 bits of the input number's + 1 significand with relative
+// error < 2^(-8.886). So we have following
+//
+// |(1/f - frcpa(f)) / (1/f))| = |1 - f*frcpa(f)| < 1/256
+//
+// and
+//
+// log(f) = log(f * frcpa(f)) + log(1/frcpa(f)) =
+// = log(1 + r) + T
+//
+// The first value can be computed by polynomial P(r) approximating
+// log(1 + r) on |r| < 1/256 and the second is precomputed tabular
+// value defined by top 8 bit of f.
+//
+// Finally we have that log(1+x) ~ (N*log(2) + T) + P(r)
+//
+// Note that if input argument is close to 0.0 (in our case it means
+// that |x| < 1/256) we can use just polynomial approximation
+// because 1+x = 2^0 * f = f = 1 + r and
+// log(1+x) = log(1 + r) ~ P(r)
+//
+//
+// Implementation
+// --------------
+//
+// 1. |x| >= 2^(-8), and x > -1
+// InvX = frcpa(x+1)
+// r = InvX*(x+1) - 1
+// P(r) = r*((r*A3 - A2) + r^4*((A4 + r*A5) + r^2*(A6 + r*A7)),
+// all coefficients are calcutated in quad and rounded to double
+// precision. A7,A6,A5,A4 are stored in memory whereas A3 and A2
+// created with setf.
+//
+// N = float(n) where n is true unbiased exponent of x
+//
+// T is tabular value of log(1/frcpa(x)) calculated in quad precision
+// and represented by two floating-point numbers 64-bit Thi and 32-bit Tlo.
+// To load Thi,Tlo we get bits from 55 to 62 of register format significand
+// as index and calculate two addresses
+// ad_Thi = Thi_table_base_addr + 8 * index
+// ad_Tlo = Tlo_table_base_addr + 4 * index
+//
+// L1 (log(2)) is calculated in quad
+// precision and represented by two floating-point 64-bit numbers L1hi,L1lo
+// stored in memory.
+//
+// And final result = ((L1hi*N + Thi) + (N*L1lo + Tlo)) + P(r)
+//
+//
+// 2. 2^(-80) <= |x| < 2^(-8)
+// r = x
+// P(r) = r*((r*A3 - A2) + r^4*((A4 + r*A5) + r^2*(A6 + r*A7)),
+// A7,A6,A5,A4,A3,A2 are the same as in case |x| >= 1/256
+//
+// And final results
+// log(1+x) = P(r)
+//
+// 3. 0 < |x| < 2^(-80)
+// Although log1p(x) is basically x, we would like to preserve the inexactness
+// nature as well as consistent behavior under different rounding modes.
+// We can do this by computing the result as
+//
+// log1p(x) = x - x*x
+//
+//
+// Note: NaT, any NaNs, +/-INF, +/-0, negatives and unnormalized numbers are
+// filtered and processed on special branches.
+//
+
+//
+// Special values
+//==============================================================
+//
+// log1p(-1) = -inf // Call error support
+//
+// log1p(+qnan) = +qnan
+// log1p(-qnan) = -qnan
+// log1p(+snan) = +qnan
+// log1p(-snan) = -qnan
+//
+// log1p(x),x<-1= QNAN Indefinite // Call error support
+// log1p(-inf) = QNAN Indefinite
+// log1p(+inf) = +inf
+// log1p(+/-0) = +/-0
+//
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f7 -> f15, f32 -> f40
+//
+// General registers used:
+// r8 -> r11
+// r14 -> r20
+//
+// Predicate registers used:
+// p6 -> p12
+
+// Assembly macros
+//==============================================================
+GR_TAG = r8
+GR_ad_1 = r8
+GR_ad_2 = r9
+GR_Exp = r10
+GR_N = r11
+
+GR_signexp_x = r14
+GR_exp_mask = r15
+GR_exp_bias = r16
+GR_05 = r17
+GR_A3 = r18
+GR_Sig = r19
+GR_Ind = r19
+GR_exp_x = r20
+
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+
+FR_NormX = f7
+FR_RcpX = f9
+FR_r = f10
+FR_r2 = f11
+FR_r4 = f12
+FR_N = f13
+FR_Ln2hi = f14
+FR_Ln2lo = f15
+
+FR_A7 = f32
+FR_A6 = f33
+FR_A5 = f34
+FR_A4 = f35
+FR_A3 = f36
+FR_A2 = f37
+
+FR_Thi = f38
+FR_NxLn2hipThi = f38
+FR_NxLn2pT = f38
+FR_Tlo = f39
+FR_NxLn2lopTlo = f39
+
+FR_Xp1 = f40
+
+
+FR_Y = f1
+FR_X = f10
+FR_RESULT = f8
+
+
+// Data
+//==============================================================
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(log_data)
+// coefficients of polynomial approximation
+data8 0x3FC2494104381A8E // A7
+data8 0xBFC5556D556BBB69 // A6
+data8 0x3FC999999988B5E9 // A5
+data8 0xBFCFFFFFFFF6FFF5 // A4
+//
+// hi parts of ln(1/frcpa(1+i/256)), i=0...255
+data8 0x3F60040155D5889D // 0
+data8 0x3F78121214586B54 // 1
+data8 0x3F841929F96832EF // 2
+data8 0x3F8C317384C75F06 // 3
+data8 0x3F91A6B91AC73386 // 4
+data8 0x3F95BA9A5D9AC039 // 5
+data8 0x3F99D2A8074325F3 // 6
+data8 0x3F9D6B2725979802 // 7
+data8 0x3FA0C58FA19DFAA9 // 8
+data8 0x3FA2954C78CBCE1A // 9
+data8 0x3FA4A94D2DA96C56 // 10
+data8 0x3FA67C94F2D4BB58 // 11
+data8 0x3FA85188B630F068 // 12
+data8 0x3FAA6B8ABE73AF4C // 13
+data8 0x3FAC441E06F72A9E // 14
+data8 0x3FAE1E6713606D06 // 15
+data8 0x3FAFFA6911AB9300 // 16
+data8 0x3FB0EC139C5DA600 // 17
+data8 0x3FB1DBD2643D190B // 18
+data8 0x3FB2CC7284FE5F1C // 19
+data8 0x3FB3BDF5A7D1EE64 // 20
+data8 0x3FB4B05D7AA012E0 // 21
+data8 0x3FB580DB7CEB5701 // 22
+data8 0x3FB674F089365A79 // 23
+data8 0x3FB769EF2C6B568D // 24
+data8 0x3FB85FD927506A47 // 25
+data8 0x3FB9335E5D594988 // 26
+data8 0x3FBA2B0220C8E5F4 // 27
+data8 0x3FBB0004AC1A86AB // 28
+data8 0x3FBBF968769FCA10 // 29
+data8 0x3FBCCFEDBFEE13A8 // 30
+data8 0x3FBDA727638446A2 // 31
+data8 0x3FBEA3257FE10F79 // 32
+data8 0x3FBF7BE9FEDBFDE5 // 33
+data8 0x3FC02AB352FF25F3 // 34
+data8 0x3FC097CE579D204C // 35
+data8 0x3FC1178E8227E47B // 36
+data8 0x3FC185747DBECF33 // 37
+data8 0x3FC1F3B925F25D41 // 38
+data8 0x3FC2625D1E6DDF56 // 39
+data8 0x3FC2D1610C868139 // 40
+data8 0x3FC340C59741142E // 41
+data8 0x3FC3B08B6757F2A9 // 42
+data8 0x3FC40DFB08378003 // 43
+data8 0x3FC47E74E8CA5F7C // 44
+data8 0x3FC4EF51F6466DE4 // 45
+data8 0x3FC56092E02BA516 // 46
+data8 0x3FC5D23857CD74D4 // 47
+data8 0x3FC6313A37335D76 // 48
+data8 0x3FC6A399DABBD383 // 49
+data8 0x3FC70337DD3CE41A // 50
+data8 0x3FC77654128F6127 // 51
+data8 0x3FC7E9D82A0B022D // 52
+data8 0x3FC84A6B759F512E // 53
+data8 0x3FC8AB47D5F5A30F // 54
+data8 0x3FC91FE49096581B // 55
+data8 0x3FC981634011AA75 // 56
+data8 0x3FC9F6C407089664 // 57
+data8 0x3FCA58E729348F43 // 58
+data8 0x3FCABB55C31693AC // 59
+data8 0x3FCB1E104919EFD0 // 60
+data8 0x3FCB94EE93E367CA // 61
+data8 0x3FCBF851C067555E // 62
+data8 0x3FCC5C0254BF23A5 // 63
+data8 0x3FCCC000C9DB3C52 // 64
+data8 0x3FCD244D99C85673 // 65
+data8 0x3FCD88E93FB2F450 // 66
+data8 0x3FCDEDD437EAEF00 // 67
+data8 0x3FCE530EFFE71012 // 68
+data8 0x3FCEB89A1648B971 // 69
+data8 0x3FCF1E75FADF9BDE // 70
+data8 0x3FCF84A32EAD7C35 // 71
+data8 0x3FCFEB2233EA07CD // 72
+data8 0x3FD028F9C7035C1C // 73
+data8 0x3FD05C8BE0D9635A // 74
+data8 0x3FD085EB8F8AE797 // 75
+data8 0x3FD0B9C8E32D1911 // 76
+data8 0x3FD0EDD060B78080 // 77
+data8 0x3FD122024CF0063F // 78
+data8 0x3FD14BE2927AECD4 // 79
+data8 0x3FD180618EF18ADF // 80
+data8 0x3FD1B50BBE2FC63B // 81
+data8 0x3FD1DF4CC7CF242D // 82
+data8 0x3FD214456D0EB8D4 // 83
+data8 0x3FD23EC5991EBA49 // 84
+data8 0x3FD2740D9F870AFB // 85
+data8 0x3FD29ECDABCDFA03 // 86
+data8 0x3FD2D46602ADCCEE // 87
+data8 0x3FD2FF66B04EA9D4 // 88
+data8 0x3FD335504B355A37 // 89
+data8 0x3FD360925EC44F5C // 90
+data8 0x3FD38BF1C3337E74 // 91
+data8 0x3FD3C25277333183 // 92
+data8 0x3FD3EDF463C1683E // 93
+data8 0x3FD419B423D5E8C7 // 94
+data8 0x3FD44591E0539F48 // 95
+data8 0x3FD47C9175B6F0AD // 96
+data8 0x3FD4A8B341552B09 // 97
+data8 0x3FD4D4F39089019F // 98
+data8 0x3FD501528DA1F967 // 99
+data8 0x3FD52DD06347D4F6 // 100
+data8 0x3FD55A6D3C7B8A89 // 101
+data8 0x3FD5925D2B112A59 // 102
+data8 0x3FD5BF406B543DB1 // 103
+data8 0x3FD5EC433D5C35AD // 104
+data8 0x3FD61965CDB02C1E // 105
+data8 0x3FD646A84935B2A1 // 106
+data8 0x3FD6740ADD31DE94 // 107
+data8 0x3FD6A18DB74A58C5 // 108
+data8 0x3FD6CF31058670EC // 109
+data8 0x3FD6F180E852F0B9 // 110
+data8 0x3FD71F5D71B894EF // 111
+data8 0x3FD74D5AEFD66D5C // 112
+data8 0x3FD77B79922BD37D // 113
+data8 0x3FD7A9B9889F19E2 // 114
+data8 0x3FD7D81B037EB6A6 // 115
+data8 0x3FD8069E33827230 // 116
+data8 0x3FD82996D3EF8BCA // 117
+data8 0x3FD85855776DCBFA // 118
+data8 0x3FD8873658327CCE // 119
+data8 0x3FD8AA75973AB8CE // 120
+data8 0x3FD8D992DC8824E4 // 121
+data8 0x3FD908D2EA7D9511 // 122
+data8 0x3FD92C59E79C0E56 // 123
+data8 0x3FD95BD750EE3ED2 // 124
+data8 0x3FD98B7811A3EE5B // 125
+data8 0x3FD9AF47F33D406B // 126
+data8 0x3FD9DF270C1914A7 // 127
+data8 0x3FDA0325ED14FDA4 // 128
+data8 0x3FDA33440224FA78 // 129
+data8 0x3FDA57725E80C382 // 130
+data8 0x3FDA87D0165DD199 // 131
+data8 0x3FDAAC2E6C03F895 // 132
+data8 0x3FDADCCC6FDF6A81 // 133
+data8 0x3FDB015B3EB1E790 // 134
+data8 0x3FDB323A3A635948 // 135
+data8 0x3FDB56FA04462909 // 136
+data8 0x3FDB881AA659BC93 // 137
+data8 0x3FDBAD0BEF3DB164 // 138
+data8 0x3FDBD21297781C2F // 139
+data8 0x3FDC039236F08818 // 140
+data8 0x3FDC28CB1E4D32FC // 141
+data8 0x3FDC4E19B84723C1 // 142
+data8 0x3FDC7FF9C74554C9 // 143
+data8 0x3FDCA57B64E9DB05 // 144
+data8 0x3FDCCB130A5CEBAF // 145
+data8 0x3FDCF0C0D18F326F // 146
+data8 0x3FDD232075B5A201 // 147
+data8 0x3FDD490246DEFA6B // 148
+data8 0x3FDD6EFA918D25CD // 149
+data8 0x3FDD9509707AE52F // 150
+data8 0x3FDDBB2EFE92C554 // 151
+data8 0x3FDDEE2F3445E4AE // 152
+data8 0x3FDE148A1A2726CD // 153
+data8 0x3FDE3AFC0A49FF3F // 154
+data8 0x3FDE6185206D516D // 155
+data8 0x3FDE882578823D51 // 156
+data8 0x3FDEAEDD2EAC990C // 157
+data8 0x3FDED5AC5F436BE2 // 158
+data8 0x3FDEFC9326D16AB8 // 159
+data8 0x3FDF2391A21575FF // 160
+data8 0x3FDF4AA7EE03192C // 161
+data8 0x3FDF71D627C30BB0 // 162
+data8 0x3FDF991C6CB3B379 // 163
+data8 0x3FDFC07ADA69A90F // 164
+data8 0x3FDFE7F18EB03D3E // 165
+data8 0x3FE007C053C5002E // 166
+data8 0x3FE01B942198A5A0 // 167
+data8 0x3FE02F74400C64EA // 168
+data8 0x3FE04360BE7603AC // 169
+data8 0x3FE05759AC47FE33 // 170
+data8 0x3FE06B5F1911CF51 // 171
+data8 0x3FE078BF0533C568 // 172
+data8 0x3FE08CD9687E7B0E // 173
+data8 0x3FE0A10074CF9019 // 174
+data8 0x3FE0B5343A234476 // 175
+data8 0x3FE0C974C89431CD // 176
+data8 0x3FE0DDC2305B9886 // 177
+data8 0x3FE0EB524BAFC918 // 178
+data8 0x3FE0FFB54213A475 // 179
+data8 0x3FE114253DA97D9F // 180
+data8 0x3FE128A24F1D9AFF // 181
+data8 0x3FE1365252BF0864 // 182
+data8 0x3FE14AE558B4A92D // 183
+data8 0x3FE15F85A19C765B // 184
+data8 0x3FE16D4D38C119FA // 185
+data8 0x3FE18203C20DD133 // 186
+data8 0x3FE196C7BC4B1F3A // 187
+data8 0x3FE1A4A738B7A33C // 188
+data8 0x3FE1B981C0C9653C // 189
+data8 0x3FE1CE69E8BB106A // 190
+data8 0x3FE1DC619DE06944 // 191
+data8 0x3FE1F160A2AD0DA3 // 192
+data8 0x3FE2066D7740737E // 193
+data8 0x3FE2147DBA47A393 // 194
+data8 0x3FE229A1BC5EBAC3 // 195
+data8 0x3FE237C1841A502E // 196
+data8 0x3FE24CFCE6F80D9A // 197
+data8 0x3FE25B2C55CD5762 // 198
+data8 0x3FE2707F4D5F7C40 // 199
+data8 0x3FE285E0842CA383 // 200
+data8 0x3FE294294708B773 // 201
+data8 0x3FE2A9A2670AFF0C // 202
+data8 0x3FE2B7FB2C8D1CC0 // 203
+data8 0x3FE2C65A6395F5F5 // 204
+data8 0x3FE2DBF557B0DF42 // 205
+data8 0x3FE2EA64C3F97654 // 206
+data8 0x3FE3001823684D73 // 207
+data8 0x3FE30E97E9A8B5CC // 208
+data8 0x3FE32463EBDD34E9 // 209
+data8 0x3FE332F4314AD795 // 210
+data8 0x3FE348D90E7464CF // 211
+data8 0x3FE35779F8C43D6D // 212
+data8 0x3FE36621961A6A99 // 213
+data8 0x3FE37C299F3C366A // 214
+data8 0x3FE38AE2171976E7 // 215
+data8 0x3FE399A157A603E7 // 216
+data8 0x3FE3AFCCFE77B9D1 // 217
+data8 0x3FE3BE9D503533B5 // 218
+data8 0x3FE3CD7480B4A8A2 // 219
+data8 0x3FE3E3C43918F76C // 220
+data8 0x3FE3F2ACB27ED6C6 // 221
+data8 0x3FE4019C2125CA93 // 222
+data8 0x3FE4181061389722 // 223
+data8 0x3FE42711518DF545 // 224
+data8 0x3FE436194E12B6BF // 225
+data8 0x3FE445285D68EA69 // 226
+data8 0x3FE45BCC464C893A // 227
+data8 0x3FE46AED21F117FC // 228
+data8 0x3FE47A1527E8A2D3 // 229
+data8 0x3FE489445EFFFCCB // 230
+data8 0x3FE4A018BCB69835 // 231
+data8 0x3FE4AF5A0C9D65D7 // 232
+data8 0x3FE4BEA2A5BDBE87 // 233
+data8 0x3FE4CDF28F10AC46 // 234
+data8 0x3FE4DD49CF994058 // 235
+data8 0x3FE4ECA86E64A683 // 236
+data8 0x3FE503C43CD8EB68 // 237
+data8 0x3FE513356667FC57 // 238
+data8 0x3FE522AE0738A3D7 // 239
+data8 0x3FE5322E26867857 // 240
+data8 0x3FE541B5CB979809 // 241
+data8 0x3FE55144FDBCBD62 // 242
+data8 0x3FE560DBC45153C6 // 243
+data8 0x3FE5707A26BB8C66 // 244
+data8 0x3FE587F60ED5B8FF // 245
+data8 0x3FE597A7977C8F31 // 246
+data8 0x3FE5A760D634BB8A // 247
+data8 0x3FE5B721D295F10E // 248
+data8 0x3FE5C6EA94431EF9 // 249
+data8 0x3FE5D6BB22EA86F5 // 250
+data8 0x3FE5E6938645D38F // 251
+data8 0x3FE5F673C61A2ED1 // 252
+data8 0x3FE6065BEA385926 // 253
+data8 0x3FE6164BFA7CC06B // 254
+data8 0x3FE62643FECF9742 // 255
+//
+// two parts of ln(2)
+data8 0x3FE62E42FEF00000,0x3DD473DE6AF278ED
+//
+// lo parts of ln(1/frcpa(1+i/256)), i=0...255
+data4 0x20E70672 // 0
+data4 0x1F60A5D0 // 1
+data4 0x218EABA0 // 2
+data4 0x21403104 // 3
+data4 0x20E9B54E // 4
+data4 0x21EE1382 // 5
+data4 0x226014E3 // 6
+data4 0x2095E5C9 // 7
+data4 0x228BA9D4 // 8
+data4 0x22932B86 // 9
+data4 0x22608A57 // 10
+data4 0x220209F3 // 11
+data4 0x212882CC // 12
+data4 0x220D46E2 // 13
+data4 0x21FA4C28 // 14
+data4 0x229E5BD9 // 15
+data4 0x228C9838 // 16
+data4 0x2311F954 // 17
+data4 0x221365DF // 18
+data4 0x22BD0CB3 // 19
+data4 0x223D4BB7 // 20
+data4 0x22A71BBE // 21
+data4 0x237DB2FA // 22
+data4 0x23194C9D // 23
+data4 0x22EC639E // 24
+data4 0x2367E669 // 25
+data4 0x232E1D5F // 26
+data4 0x234A639B // 27
+data4 0x2365C0E0 // 28
+data4 0x234646C1 // 29
+data4 0x220CBF9C // 30
+data4 0x22A00FD4 // 31
+data4 0x2306A3F2 // 32
+data4 0x23745A9B // 33
+data4 0x2398D756 // 34
+data4 0x23DD0B6A // 35
+data4 0x23DE338B // 36
+data4 0x23A222DF // 37
+data4 0x223164F8 // 38
+data4 0x23B4E87B // 39
+data4 0x23D6CCB8 // 40
+data4 0x220C2099 // 41
+data4 0x21B86B67 // 42
+data4 0x236D14F1 // 43
+data4 0x225A923F // 44
+data4 0x22748723 // 45
+data4 0x22200D13 // 46
+data4 0x23C296EA // 47
+data4 0x2302AC38 // 48
+data4 0x234B1996 // 49
+data4 0x2385E298 // 50
+data4 0x23175BE5 // 51
+data4 0x2193F482 // 52
+data4 0x23BFEA90 // 53
+data4 0x23D70A0C // 54
+data4 0x231CF30A // 55
+data4 0x235D9E90 // 56
+data4 0x221AD0CB // 57
+data4 0x22FAA08B // 58
+data4 0x23D29A87 // 59
+data4 0x20C4B2FE // 60
+data4 0x2381B8B7 // 61
+data4 0x23F8D9FC // 62
+data4 0x23EAAE7B // 63
+data4 0x2329E8AA // 64
+data4 0x23EC0322 // 65
+data4 0x2357FDCB // 66
+data4 0x2392A9AD // 67
+data4 0x22113B02 // 68
+data4 0x22DEE901 // 69
+data4 0x236A6D14 // 70
+data4 0x2371D33E // 71
+data4 0x2146F005 // 72
+data4 0x23230B06 // 73
+data4 0x22F1C77D // 74
+data4 0x23A89FA3 // 75
+data4 0x231D1241 // 76
+data4 0x244DA96C // 77
+data4 0x23ECBB7D // 78
+data4 0x223E42B4 // 79
+data4 0x23801BC9 // 80
+data4 0x23573263 // 81
+data4 0x227C1158 // 82
+data4 0x237BD749 // 83
+data4 0x21DDBAE9 // 84
+data4 0x23401735 // 85
+data4 0x241D9DEE // 86
+data4 0x23BC88CB // 87
+data4 0x2396D5F1 // 88
+data4 0x23FC89CF // 89
+data4 0x2414F9A2 // 90
+data4 0x2474A0F5 // 91
+data4 0x24354B60 // 92
+data4 0x23C1EB40 // 93
+data4 0x2306DD92 // 94
+data4 0x24353B6B // 95
+data4 0x23CD1701 // 96
+data4 0x237C7A1C // 97
+data4 0x245793AA // 98
+data4 0x24563695 // 99
+data4 0x23C51467 // 100
+data4 0x24476B68 // 101
+data4 0x212585A9 // 102
+data4 0x247B8293 // 103
+data4 0x2446848A // 104
+data4 0x246A53F8 // 105
+data4 0x246E496D // 106
+data4 0x23ED1D36 // 107
+data4 0x2314C258 // 108
+data4 0x233244A7 // 109
+data4 0x245B7AF0 // 110
+data4 0x24247130 // 111
+data4 0x22D67B38 // 112
+data4 0x2449F620 // 113
+data4 0x23BBC8B8 // 114
+data4 0x237D3BA0 // 115
+data4 0x245E8F13 // 116
+data4 0x2435573F // 117
+data4 0x242DE666 // 118
+data4 0x2463BC10 // 119
+data4 0x2466587D // 120
+data4 0x2408144B // 121
+data4 0x2405F0E5 // 122
+data4 0x22381CFF // 123
+data4 0x24154F9B // 124
+data4 0x23A4E96E // 125
+data4 0x24052967 // 126
+data4 0x2406963F // 127
+data4 0x23F7D3CB // 128
+data4 0x2448AFF4 // 129
+data4 0x24657A21 // 130
+data4 0x22FBC230 // 131
+data4 0x243C8DEA // 132
+data4 0x225DC4B7 // 133
+data4 0x23496EBF // 134
+data4 0x237C2B2B // 135
+data4 0x23A4A5B1 // 136
+data4 0x2394E9D1 // 137
+data4 0x244BC950 // 138
+data4 0x23C7448F // 139
+data4 0x2404A1AD // 140
+data4 0x246511D5 // 141
+data4 0x24246526 // 142
+data4 0x23111F57 // 143
+data4 0x22868951 // 144
+data4 0x243EB77F // 145
+data4 0x239F3DFF // 146
+data4 0x23089666 // 147
+data4 0x23EBFA6A // 148
+data4 0x23C51312 // 149
+data4 0x23E1DD5E // 150
+data4 0x232C0944 // 151
+data4 0x246A741F // 152
+data4 0x2414DF8D // 153
+data4 0x247B5546 // 154
+data4 0x2415C980 // 155
+data4 0x24324ABD // 156
+data4 0x234EB5E5 // 157
+data4 0x2465E43E // 158
+data4 0x242840D1 // 159
+data4 0x24444057 // 160
+data4 0x245E56F0 // 161
+data4 0x21AE30F8 // 162
+data4 0x23FB3283 // 163
+data4 0x247A4D07 // 164
+data4 0x22AE314D // 165
+data4 0x246B7727 // 166
+data4 0x24EAD526 // 167
+data4 0x24B41DC9 // 168
+data4 0x24EE8062 // 169
+data4 0x24A0C7C4 // 170
+data4 0x24E8DA67 // 171
+data4 0x231120F7 // 172
+data4 0x24401FFB // 173
+data4 0x2412DD09 // 174
+data4 0x248C131A // 175
+data4 0x24C0A7CE // 176
+data4 0x243DD4C8 // 177
+data4 0x24457FEB // 178
+data4 0x24DEEFBB // 179
+data4 0x243C70AE // 180
+data4 0x23E7A6FA // 181
+data4 0x24C2D311 // 182
+data4 0x23026255 // 183
+data4 0x2437C9B9 // 184
+data4 0x246BA847 // 185
+data4 0x2420B448 // 186
+data4 0x24C4CF5A // 187
+data4 0x242C4981 // 188
+data4 0x24DE1525 // 189
+data4 0x24F5CC33 // 190
+data4 0x235A85DA // 191
+data4 0x24A0B64F // 192
+data4 0x244BA0A4 // 193
+data4 0x24AAF30A // 194
+data4 0x244C86F9 // 195
+data4 0x246D5B82 // 196
+data4 0x24529347 // 197
+data4 0x240DD008 // 198
+data4 0x24E98790 // 199
+data4 0x2489B0CE // 200
+data4 0x22BC29AC // 201
+data4 0x23F37C7A // 202
+data4 0x24987FE8 // 203
+data4 0x22AFE20B // 204
+data4 0x24C8D7C2 // 205
+data4 0x24B28B7D // 206
+data4 0x23B6B271 // 207
+data4 0x24C77CB6 // 208
+data4 0x24EF1DCA // 209
+data4 0x24A4F0AC // 210
+data4 0x24CF113E // 211
+data4 0x2496BBAB // 212
+data4 0x23C7CC8A // 213
+data4 0x23AE3961 // 214
+data4 0x2410A895 // 215
+data4 0x23CE3114 // 216
+data4 0x2308247D // 217
+data4 0x240045E9 // 218
+data4 0x24974F60 // 219
+data4 0x242CB39F // 220
+data4 0x24AB8D69 // 221
+data4 0x23436788 // 222
+data4 0x24305E9E // 223
+data4 0x243E71A9 // 224
+data4 0x23C2A6B3 // 225
+data4 0x23FFE6CF // 226
+data4 0x2322D801 // 227
+data4 0x24515F21 // 228
+data4 0x2412A0D6 // 229
+data4 0x24E60D44 // 230
+data4 0x240D9251 // 231
+data4 0x247076E2 // 232
+data4 0x229B101B // 233
+data4 0x247B12DE // 234
+data4 0x244B9127 // 235
+data4 0x2499EC42 // 236
+data4 0x21FC3963 // 237
+data4 0x23E53266 // 238
+data4 0x24CE102D // 239
+data4 0x23CC45D2 // 240
+data4 0x2333171D // 241
+data4 0x246B3533 // 242
+data4 0x24931129 // 243
+data4 0x24405FFA // 244
+data4 0x24CF464D // 245
+data4 0x237095CD // 246
+data4 0x24F86CBD // 247
+data4 0x24E2D84B // 248
+data4 0x21ACBB44 // 249
+data4 0x24F43A8C // 250
+data4 0x249DB931 // 251
+data4 0x24A385EF // 252
+data4 0x238B1279 // 253
+data4 0x2436213E // 254
+data4 0x24F18A3B // 255
+LOCAL_OBJECT_END(log_data)
+
+
+// Code
+//==============================================================
+
+.section .text
+GLOBAL_IEEE754_ENTRY(log1p)
+{ .mfi
+ getf.exp GR_signexp_x = f8 // if x is unorm then must recompute
+ fadd.s1 FR_Xp1 = f8, f1 // Form 1+x
+ mov GR_05 = 0xfffe
+}
+{ .mlx
+ addl GR_ad_1 = @ltoff(log_data),gp
+ movl GR_A3 = 0x3fd5555555555557 // double precision memory
+ // representation of A3
+}
+;;
+
+{ .mfi
+ ld8 GR_ad_1 = [GR_ad_1]
+ fclass.m p8,p0 = f8,0xb // Is x unorm?
+ mov GR_exp_mask = 0x1ffff
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 FR_NormX = f8 // Normalize x
+ mov GR_exp_bias = 0xffff
+}
+;;
+
+{ .mfi
+ setf.exp FR_A2 = GR_05 // create A2 = 0.5
+ fclass.m p9,p0 = f8,0x1E1 // is x NaN, NaT or +Inf?
+ nop.i 0
+}
+{ .mib
+ setf.d FR_A3 = GR_A3 // create A3
+ add GR_ad_2 = 16,GR_ad_1 // address of A5,A4
+(p8) br.cond.spnt log1p_unorm // Branch if x=unorm
+}
+;;
+
+log1p_common:
+{ .mfi
+ nop.m 0
+ frcpa.s1 FR_RcpX,p0 = f1,FR_Xp1
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p9) fma.d.s0 f8 = f8,f1,f0 // set V-flag
+(p9) br.ret.spnt b0 // exit for NaN, NaT and +Inf
+}
+;;
+
+{ .mfi
+ getf.exp GR_Exp = FR_Xp1 // signexp of x+1
+ fclass.m p10,p0 = FR_Xp1,0x3A // is 1+x < 0?
+ and GR_exp_x = GR_exp_mask, GR_signexp_x // biased exponent of x
+}
+{ .mfi
+ ldfpd FR_A7,FR_A6 = [GR_ad_1]
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ getf.sig GR_Sig = FR_Xp1 // get significand to calculate index
+ // for Thi,Tlo if |x| >= 2^-8
+ fcmp.eq.s1 p12,p0 = f8,f0 // is x equal to 0?
+ sub GR_exp_x = GR_exp_x, GR_exp_bias // true exponent of x
+}
+;;
+
+{ .mfi
+ sub GR_N = GR_Exp,GR_exp_bias // true exponent of x+1
+ fcmp.eq.s1 p11,p0 = FR_Xp1,f0 // is x = -1?
+ cmp.gt p6,p7 = -8, GR_exp_x // Is |x| < 2^-8
+}
+{ .mfb
+ ldfpd FR_A5,FR_A4 = [GR_ad_2],16
+ nop.f 0
+(p10) br.cond.spnt log1p_lt_minus_1 // jump if x < -1
+}
+;;
+
+// p6 is true if |x| < 1/256
+// p7 is true if |x| >= 1/256
+.pred.rel "mutex",p6,p7
+{ .mfi
+(p7) add GR_ad_1 = 0x820,GR_ad_1 // address of log(2) parts
+(p6) fms.s1 FR_r = f8,f1,f0 // range reduction for |x|<1/256
+(p6) cmp.gt.unc p10,p0 = -80, GR_exp_x // Is |x| < 2^-80
+}
+{ .mfb
+(p7) setf.sig FR_N = GR_N // copy unbiased exponent of x to the
+ // significand field of FR_N
+(p7) fms.s1 FR_r = FR_RcpX,FR_Xp1,f1 // range reduction for |x|>=1/256
+(p12) br.ret.spnt b0 // exit for x=0, return x
+}
+;;
+
+{ .mib
+(p7) ldfpd FR_Ln2hi,FR_Ln2lo = [GR_ad_1],16
+(p7) extr.u GR_Ind = GR_Sig,55,8 // get bits from 55 to 62 as index
+(p11) br.cond.spnt log1p_eq_minus_1 // jump if x = -1
+}
+;;
+
+{ .mmf
+(p7) shladd GR_ad_2 = GR_Ind,3,GR_ad_2 // address of Thi
+(p7) shladd GR_ad_1 = GR_Ind,2,GR_ad_1 // address of Tlo
+(p10) fnma.d.s0 f8 = f8,f8,f8 // If |x| very small, result=x-x*x
+}
+;;
+
+{ .mmb
+(p7) ldfd FR_Thi = [GR_ad_2]
+(p7) ldfs FR_Tlo = [GR_ad_1]
+(p10) br.ret.spnt b0 // Exit if |x| < 2^(-80)
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r2 = FR_r,FR_r,f0 // r^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_A2 = FR_A3,FR_r,FR_A2 // A3*r+A2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A6 = FR_A7,FR_r,FR_A6 // A7*r+A6
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A4 = FR_A5,FR_r,FR_A4 // A5*r+A4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p7) fcvt.xf FR_N = FR_N
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r4 = FR_r2,FR_r2,f0 // r^4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (A3*r+A2)*r^2+r
+ fma.s1 FR_A2 = FR_A2,FR_r2,FR_r
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // (A7*r+A6)*r^2+(A5*r+A4)
+ fma.s1 FR_A4 = FR_A6,FR_r2,FR_A4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // N*Ln2hi+Thi
+(p7) fma.s1 FR_NxLn2hipThi = FR_N,FR_Ln2hi,FR_Thi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // N*Ln2lo+Tlo
+(p7) fma.s1 FR_NxLn2lopTlo = FR_N,FR_Ln2lo,FR_Tlo
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p7) fma.s1 f8 = FR_A4,FR_r4,FR_A2 // P(r) if |x| >= 1/256
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // (N*Ln2hi+Thi) + (N*Ln2lo+Tlo)
+(p7) fma.s1 FR_NxLn2pT = FR_NxLn2hipThi,f1,FR_NxLn2lopTlo
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fma.d.s0 f8 = FR_A4,FR_r4,FR_A2 // result if 2^(-80) <= |x| < 1/256
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.d.s0 f8 = f8,f1,FR_NxLn2pT // result if |x| >= 1/256
+ br.ret.sptk b0 // Exit if |x| >= 2^(-80)
+}
+;;
+
+.align 32
+log1p_unorm:
+// Here if x=unorm
+{ .mfb
+ getf.exp GR_signexp_x = FR_NormX // recompute biased exponent
+ nop.f 0
+ br.cond.sptk log1p_common
+}
+;;
+
+.align 32
+log1p_eq_minus_1:
+// Here if x=-1
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8,f8 // keep input argument for subsequent
+ // call of __libm_error_support#
+ nop.i 0
+}
+;;
+
+{ .mfi
+ mov GR_TAG = 140 // set libm error in case of log1p(-1).
+ frcpa.s0 f8,p0 = f8,f0 // log1p(-1) should be equal to -INF.
+ // We can get it using frcpa because it
+ // sets result to the IEEE-754 mandated
+ // quotient of f8/f0.
+ nop.i 0
+}
+{ .mib
+ nop.m 0
+ nop.i 0
+ br.cond.sptk log_libm_err
+}
+;;
+
+.align 32
+log1p_lt_minus_1:
+// Here if x < -1
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+;;
+
+{ .mfi
+ mov GR_TAG = 141 // set libm error in case of x < -1.
+ frcpa.s0 f8,p0 = f0,f0 // log1p(x) x < -1 should be equal to NaN.
+ // We can get it using frcpa because it
+ // sets result to the IEEE-754 mandated
+ // quotient of f0/f0 i.e. NaN.
+ nop.i 0
+}
+;;
+
+.align 32
+log_libm_err:
+{ .mmi
+ alloc r32 = ar.pfs,1,4,4,0
+ mov GR_Parameter_TAG = GR_TAG
+ nop.i 0
+}
+;;
+
+GLOBAL_IEEE754_END(log1p)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y = -32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS = ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp = -64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP = gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0 = b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_log1pf.S b/libc/sysdeps/ia64/fpu/s_log1pf.S
new file mode 100644
index 000000000..77e79c39d
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_log1pf.S
@@ -0,0 +1,789 @@
+.file "log1pf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 06/29/01 Improved speed of all paths
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 10/02/02 Improved performance by basing on log algorithm
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 04/18/03 Eliminate possible WAW dependency warning
+// 12/16/03 Fixed parameter passing to/from error handling routine
+//
+// API
+//==============================================================
+// float log1pf(float)
+//
+// log1p(x) = log(x+1)
+//
+// Overview of operation
+//==============================================================
+// Background
+// ----------
+//
+// This algorithm is based on fact that
+// log1p(x) = log(1+x) and
+// log(a b) = log(a) + log(b).
+// In our case we have 1+x = 2^N f, where 1 <= f < 2.
+// So
+// log(1+x) = log(2^N f) = log(2^N) + log(f) = n*log(2) + log(f)
+//
+// To calculate log(f) we do following
+// log(f) = log(f * frcpa(f) / frcpa(f)) =
+// = log(f * frcpa(f)) + log(1/frcpa(f))
+//
+// According to definition of IA-64's frcpa instruction it's a
+// floating point that approximates 1/f using a lookup on the
+// top of 8 bits of the input number's + 1 significand with relative
+// error < 2^(-8.886). So we have following
+//
+// |(1/f - frcpa(f)) / (1/f))| = |1 - f*frcpa(f)| < 1/256
+//
+// and
+//
+// log(f) = log(f * frcpa(f)) + log(1/frcpa(f)) =
+// = log(1 + r) + T
+//
+// The first value can be computed by polynomial P(r) approximating
+// log(1 + r) on |r| < 1/256 and the second is precomputed tabular
+// value defined by top 8 bit of f.
+//
+// Finally we have that log(1+x) ~ (N*log(2) + T) + P(r)
+//
+// Note that if input argument is close to 0.0 (in our case it means
+// that |x| < 1/256) we can use just polynomial approximation
+// because 1+x = 2^0 * f = f = 1 + r and
+// log(1+x) = log(1 + r) ~ P(r)
+//
+//
+// Implementation
+// --------------
+//
+// 1. |x| >= 2^(-8), and x > -1
+// InvX = frcpa(x+1)
+// r = InvX*(x+1) - 1
+// P(r) = r*((1 - A2*4) + r^2*(A3 - A4*r)) = r*P2(r),
+// A4,A3,A2 are created with setf instruction.
+// We use Taylor series and so A4 = 1/4, A3 = 1/3,
+// A2 = 1/2 rounded to double.
+//
+// N = float(n) where n is true unbiased exponent of x
+//
+// T is tabular value of log(1/frcpa(x)) calculated in quad precision
+// and rounded to double. To load T we get bits from 55 to 62 of register
+// format significand as index and calculate address
+// ad_T = table_base_addr + 8 * index
+//
+// L1 (log(2)) is calculated in quad precision and rounded to double;
+// it's created with setf
+//
+// And final result = P2(r)*r + (T + N*L1)
+//
+//
+// 2. 2^(-40) <= |x| < 2^(-8)
+// r = x
+// P(r) = r*((1 - A2*4) + r^2*(A3 - A4*r)) = r*P2(r),
+// A4,A3,A2 are the same as in case |x| >= 1/256
+//
+// And final result = P2(r)*r
+//
+// 3. 0 < |x| < 2^(-40)
+// Although log1p(x) is basically x, we would like to preserve the inexactness
+// nature as well as consistent behavior under different rounding modes.
+// We can do this by computing the result as
+//
+// log1p(x) = x - x*x
+//
+//
+// Note: NaT, any NaNs, +/-INF, +/-0, negatives and unnormalized numbers are
+// filtered and processed on special branches.
+//
+
+//
+// Special values
+//==============================================================
+//
+// log1p(-1) = -inf // Call error support
+//
+// log1p(+qnan) = +qnan
+// log1p(-qnan) = -qnan
+// log1p(+snan) = +qnan
+// log1p(-snan) = -qnan
+//
+// log1p(x),x<-1= QNAN Indefinite // Call error support
+// log1p(-inf) = QNAN Indefinite
+// log1p(+inf) = +inf
+// log1p(+/-0) = +/-0
+//
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f7 -> f15, f32 -> f36
+//
+// General registers used:
+// r8 -> r11
+// r14 -> r22
+//
+// Predicate registers used:
+// p6 -> p12
+
+// Assembly macros
+//==============================================================
+GR_TAG = r8
+GR_ad_T = r9
+GR_Exp = r10
+GR_N = r11
+
+GR_signexp_x = r14
+GR_exp_mask = r15
+GR_exp_bias = r16
+GR_05 = r17
+GR_A3 = r18
+GR_Sig = r19
+GR_Ind = r19
+GR_exp_x = r20
+GR_Ln2 = r21
+GR_025 = r22
+
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+
+FR_NormX = f7
+FR_RcpX = f9
+FR_r = f10
+FR_r2 = f11
+FR_r4 = f12
+FR_N = f13
+FR_Ln2 = f14
+FR_Xp1 = f15
+
+FR_A4 = f33
+FR_A3 = f34
+FR_A2 = f35
+
+FR_T = f36
+FR_NxLn2pT = f36
+
+
+
+FR_Y = f1
+FR_X = f10
+FR_RESULT = f8
+
+
+// Data
+//==============================================================
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(log_data)
+// ln(1/frcpa(1+i/256)), i=0...255
+data8 0x3F60040155D5889E // 0
+data8 0x3F78121214586B54 // 1
+data8 0x3F841929F96832F0 // 2
+data8 0x3F8C317384C75F06 // 3
+data8 0x3F91A6B91AC73386 // 4
+data8 0x3F95BA9A5D9AC039 // 5
+data8 0x3F99D2A8074325F4 // 6
+data8 0x3F9D6B2725979802 // 7
+data8 0x3FA0C58FA19DFAAA // 8
+data8 0x3FA2954C78CBCE1B // 9
+data8 0x3FA4A94D2DA96C56 // 10
+data8 0x3FA67C94F2D4BB58 // 11
+data8 0x3FA85188B630F068 // 12
+data8 0x3FAA6B8ABE73AF4C // 13
+data8 0x3FAC441E06F72A9E // 14
+data8 0x3FAE1E6713606D07 // 15
+data8 0x3FAFFA6911AB9301 // 16
+data8 0x3FB0EC139C5DA601 // 17
+data8 0x3FB1DBD2643D190B // 18
+data8 0x3FB2CC7284FE5F1C // 19
+data8 0x3FB3BDF5A7D1EE64 // 20
+data8 0x3FB4B05D7AA012E0 // 21
+data8 0x3FB580DB7CEB5702 // 22
+data8 0x3FB674F089365A7A // 23
+data8 0x3FB769EF2C6B568D // 24
+data8 0x3FB85FD927506A48 // 25
+data8 0x3FB9335E5D594989 // 26
+data8 0x3FBA2B0220C8E5F5 // 27
+data8 0x3FBB0004AC1A86AC // 28
+data8 0x3FBBF968769FCA11 // 29
+data8 0x3FBCCFEDBFEE13A8 // 30
+data8 0x3FBDA727638446A2 // 31
+data8 0x3FBEA3257FE10F7A // 32
+data8 0x3FBF7BE9FEDBFDE6 // 33
+data8 0x3FC02AB352FF25F4 // 34
+data8 0x3FC097CE579D204D // 35
+data8 0x3FC1178E8227E47C // 36
+data8 0x3FC185747DBECF34 // 37
+data8 0x3FC1F3B925F25D41 // 38
+data8 0x3FC2625D1E6DDF57 // 39
+data8 0x3FC2D1610C86813A // 40
+data8 0x3FC340C59741142E // 41
+data8 0x3FC3B08B6757F2A9 // 42
+data8 0x3FC40DFB08378003 // 43
+data8 0x3FC47E74E8CA5F7C // 44
+data8 0x3FC4EF51F6466DE4 // 45
+data8 0x3FC56092E02BA516 // 46
+data8 0x3FC5D23857CD74D5 // 47
+data8 0x3FC6313A37335D76 // 48
+data8 0x3FC6A399DABBD383 // 49
+data8 0x3FC70337DD3CE41B // 50
+data8 0x3FC77654128F6127 // 51
+data8 0x3FC7E9D82A0B022D // 52
+data8 0x3FC84A6B759F512F // 53
+data8 0x3FC8AB47D5F5A310 // 54
+data8 0x3FC91FE49096581B // 55
+data8 0x3FC981634011AA75 // 56
+data8 0x3FC9F6C407089664 // 57
+data8 0x3FCA58E729348F43 // 58
+data8 0x3FCABB55C31693AD // 59
+data8 0x3FCB1E104919EFD0 // 60
+data8 0x3FCB94EE93E367CB // 61
+data8 0x3FCBF851C067555F // 62
+data8 0x3FCC5C0254BF23A6 // 63
+data8 0x3FCCC000C9DB3C52 // 64
+data8 0x3FCD244D99C85674 // 65
+data8 0x3FCD88E93FB2F450 // 66
+data8 0x3FCDEDD437EAEF01 // 67
+data8 0x3FCE530EFFE71012 // 68
+data8 0x3FCEB89A1648B971 // 69
+data8 0x3FCF1E75FADF9BDE // 70
+data8 0x3FCF84A32EAD7C35 // 71
+data8 0x3FCFEB2233EA07CD // 72
+data8 0x3FD028F9C7035C1C // 73
+data8 0x3FD05C8BE0D9635A // 74
+data8 0x3FD085EB8F8AE797 // 75
+data8 0x3FD0B9C8E32D1911 // 76
+data8 0x3FD0EDD060B78081 // 77
+data8 0x3FD122024CF0063F // 78
+data8 0x3FD14BE2927AECD4 // 79
+data8 0x3FD180618EF18ADF // 80
+data8 0x3FD1B50BBE2FC63B // 81
+data8 0x3FD1DF4CC7CF242D // 82
+data8 0x3FD214456D0EB8D4 // 83
+data8 0x3FD23EC5991EBA49 // 84
+data8 0x3FD2740D9F870AFB // 85
+data8 0x3FD29ECDABCDFA04 // 86
+data8 0x3FD2D46602ADCCEE // 87
+data8 0x3FD2FF66B04EA9D4 // 88
+data8 0x3FD335504B355A37 // 89
+data8 0x3FD360925EC44F5D // 90
+data8 0x3FD38BF1C3337E75 // 91
+data8 0x3FD3C25277333184 // 92
+data8 0x3FD3EDF463C1683E // 93
+data8 0x3FD419B423D5E8C7 // 94
+data8 0x3FD44591E0539F49 // 95
+data8 0x3FD47C9175B6F0AD // 96
+data8 0x3FD4A8B341552B09 // 97
+data8 0x3FD4D4F3908901A0 // 98
+data8 0x3FD501528DA1F968 // 99
+data8 0x3FD52DD06347D4F6 // 100
+data8 0x3FD55A6D3C7B8A8A // 101
+data8 0x3FD5925D2B112A59 // 102
+data8 0x3FD5BF406B543DB2 // 103
+data8 0x3FD5EC433D5C35AE // 104
+data8 0x3FD61965CDB02C1F // 105
+data8 0x3FD646A84935B2A2 // 106
+data8 0x3FD6740ADD31DE94 // 107
+data8 0x3FD6A18DB74A58C5 // 108
+data8 0x3FD6CF31058670EC // 109
+data8 0x3FD6F180E852F0BA // 110
+data8 0x3FD71F5D71B894F0 // 111
+data8 0x3FD74D5AEFD66D5C // 112
+data8 0x3FD77B79922BD37E // 113
+data8 0x3FD7A9B9889F19E2 // 114
+data8 0x3FD7D81B037EB6A6 // 115
+data8 0x3FD8069E33827231 // 116
+data8 0x3FD82996D3EF8BCB // 117
+data8 0x3FD85855776DCBFB // 118
+data8 0x3FD8873658327CCF // 119
+data8 0x3FD8AA75973AB8CF // 120
+data8 0x3FD8D992DC8824E5 // 121
+data8 0x3FD908D2EA7D9512 // 122
+data8 0x3FD92C59E79C0E56 // 123
+data8 0x3FD95BD750EE3ED3 // 124
+data8 0x3FD98B7811A3EE5B // 125
+data8 0x3FD9AF47F33D406C // 126
+data8 0x3FD9DF270C1914A8 // 127
+data8 0x3FDA0325ED14FDA4 // 128
+data8 0x3FDA33440224FA79 // 129
+data8 0x3FDA57725E80C383 // 130
+data8 0x3FDA87D0165DD199 // 131
+data8 0x3FDAAC2E6C03F896 // 132
+data8 0x3FDADCCC6FDF6A81 // 133
+data8 0x3FDB015B3EB1E790 // 134
+data8 0x3FDB323A3A635948 // 135
+data8 0x3FDB56FA04462909 // 136
+data8 0x3FDB881AA659BC93 // 137
+data8 0x3FDBAD0BEF3DB165 // 138
+data8 0x3FDBD21297781C2F // 139
+data8 0x3FDC039236F08819 // 140
+data8 0x3FDC28CB1E4D32FD // 141
+data8 0x3FDC4E19B84723C2 // 142
+data8 0x3FDC7FF9C74554C9 // 143
+data8 0x3FDCA57B64E9DB05 // 144
+data8 0x3FDCCB130A5CEBB0 // 145
+data8 0x3FDCF0C0D18F326F // 146
+data8 0x3FDD232075B5A201 // 147
+data8 0x3FDD490246DEFA6B // 148
+data8 0x3FDD6EFA918D25CD // 149
+data8 0x3FDD9509707AE52F // 150
+data8 0x3FDDBB2EFE92C554 // 151
+data8 0x3FDDEE2F3445E4AF // 152
+data8 0x3FDE148A1A2726CE // 153
+data8 0x3FDE3AFC0A49FF40 // 154
+data8 0x3FDE6185206D516E // 155
+data8 0x3FDE882578823D52 // 156
+data8 0x3FDEAEDD2EAC990C // 157
+data8 0x3FDED5AC5F436BE3 // 158
+data8 0x3FDEFC9326D16AB9 // 159
+data8 0x3FDF2391A2157600 // 160
+data8 0x3FDF4AA7EE03192D // 161
+data8 0x3FDF71D627C30BB0 // 162
+data8 0x3FDF991C6CB3B379 // 163
+data8 0x3FDFC07ADA69A910 // 164
+data8 0x3FDFE7F18EB03D3E // 165
+data8 0x3FE007C053C5002E // 166
+data8 0x3FE01B942198A5A1 // 167
+data8 0x3FE02F74400C64EB // 168
+data8 0x3FE04360BE7603AD // 169
+data8 0x3FE05759AC47FE34 // 170
+data8 0x3FE06B5F1911CF52 // 171
+data8 0x3FE078BF0533C568 // 172
+data8 0x3FE08CD9687E7B0E // 173
+data8 0x3FE0A10074CF9019 // 174
+data8 0x3FE0B5343A234477 // 175
+data8 0x3FE0C974C89431CE // 176
+data8 0x3FE0DDC2305B9886 // 177
+data8 0x3FE0EB524BAFC918 // 178
+data8 0x3FE0FFB54213A476 // 179
+data8 0x3FE114253DA97D9F // 180
+data8 0x3FE128A24F1D9AFF // 181
+data8 0x3FE1365252BF0865 // 182
+data8 0x3FE14AE558B4A92D // 183
+data8 0x3FE15F85A19C765B // 184
+data8 0x3FE16D4D38C119FA // 185
+data8 0x3FE18203C20DD133 // 186
+data8 0x3FE196C7BC4B1F3B // 187
+data8 0x3FE1A4A738B7A33C // 188
+data8 0x3FE1B981C0C9653D // 189
+data8 0x3FE1CE69E8BB106B // 190
+data8 0x3FE1DC619DE06944 // 191
+data8 0x3FE1F160A2AD0DA4 // 192
+data8 0x3FE2066D7740737E // 193
+data8 0x3FE2147DBA47A394 // 194
+data8 0x3FE229A1BC5EBAC3 // 195
+data8 0x3FE237C1841A502E // 196
+data8 0x3FE24CFCE6F80D9A // 197
+data8 0x3FE25B2C55CD5762 // 198
+data8 0x3FE2707F4D5F7C41 // 199
+data8 0x3FE285E0842CA384 // 200
+data8 0x3FE294294708B773 // 201
+data8 0x3FE2A9A2670AFF0C // 202
+data8 0x3FE2B7FB2C8D1CC1 // 203
+data8 0x3FE2C65A6395F5F5 // 204
+data8 0x3FE2DBF557B0DF43 // 205
+data8 0x3FE2EA64C3F97655 // 206
+data8 0x3FE3001823684D73 // 207
+data8 0x3FE30E97E9A8B5CD // 208
+data8 0x3FE32463EBDD34EA // 209
+data8 0x3FE332F4314AD796 // 210
+data8 0x3FE348D90E7464D0 // 211
+data8 0x3FE35779F8C43D6E // 212
+data8 0x3FE36621961A6A99 // 213
+data8 0x3FE37C299F3C366A // 214
+data8 0x3FE38AE2171976E7 // 215
+data8 0x3FE399A157A603E7 // 216
+data8 0x3FE3AFCCFE77B9D1 // 217
+data8 0x3FE3BE9D503533B5 // 218
+data8 0x3FE3CD7480B4A8A3 // 219
+data8 0x3FE3E3C43918F76C // 220
+data8 0x3FE3F2ACB27ED6C7 // 221
+data8 0x3FE4019C2125CA93 // 222
+data8 0x3FE4181061389722 // 223
+data8 0x3FE42711518DF545 // 224
+data8 0x3FE436194E12B6BF // 225
+data8 0x3FE445285D68EA69 // 226
+data8 0x3FE45BCC464C893A // 227
+data8 0x3FE46AED21F117FC // 228
+data8 0x3FE47A1527E8A2D3 // 229
+data8 0x3FE489445EFFFCCC // 230
+data8 0x3FE4A018BCB69835 // 231
+data8 0x3FE4AF5A0C9D65D7 // 232
+data8 0x3FE4BEA2A5BDBE87 // 233
+data8 0x3FE4CDF28F10AC46 // 234
+data8 0x3FE4DD49CF994058 // 235
+data8 0x3FE4ECA86E64A684 // 236
+data8 0x3FE503C43CD8EB68 // 237
+data8 0x3FE513356667FC57 // 238
+data8 0x3FE522AE0738A3D8 // 239
+data8 0x3FE5322E26867857 // 240
+data8 0x3FE541B5CB979809 // 241
+data8 0x3FE55144FDBCBD62 // 242
+data8 0x3FE560DBC45153C7 // 243
+data8 0x3FE5707A26BB8C66 // 244
+data8 0x3FE587F60ED5B900 // 245
+data8 0x3FE597A7977C8F31 // 246
+data8 0x3FE5A760D634BB8B // 247
+data8 0x3FE5B721D295F10F // 248
+data8 0x3FE5C6EA94431EF9 // 249
+data8 0x3FE5D6BB22EA86F6 // 250
+data8 0x3FE5E6938645D390 // 251
+data8 0x3FE5F673C61A2ED2 // 252
+data8 0x3FE6065BEA385926 // 253
+data8 0x3FE6164BFA7CC06B // 254
+data8 0x3FE62643FECF9743 // 255
+LOCAL_OBJECT_END(log_data)
+
+
+// Code
+//==============================================================
+
+.section .text
+GLOBAL_IEEE754_ENTRY(log1pf)
+{ .mfi
+ getf.exp GR_signexp_x = f8 // if x is unorm then must recompute
+ fadd.s1 FR_Xp1 = f8, f1 // Form 1+x
+ mov GR_05 = 0xfffe
+}
+{ .mlx
+ addl GR_ad_T = @ltoff(log_data),gp
+ movl GR_A3 = 0x3fd5555555555555 // double precision memory
+ // representation of A3
+}
+;;
+
+{ .mfi
+ ld8 GR_ad_T = [GR_ad_T]
+ fclass.m p8,p0 = f8,0xb // Is x unorm?
+ mov GR_exp_mask = 0x1ffff
+}
+{ .mfi
+ mov GR_025 = 0xfffd // Exponent of 0.25
+ fnorm.s1 FR_NormX = f8 // Normalize x
+ mov GR_exp_bias = 0xffff
+}
+;;
+
+{ .mfi
+ setf.exp FR_A2 = GR_05 // create A2 = 0.5
+ fclass.m p9,p0 = f8,0x1E1 // is x NaN, NaT or +Inf?
+ nop.i 0
+}
+{ .mib
+ setf.d FR_A3 = GR_A3 // create A3
+ nop.i 0
+(p8) br.cond.spnt log1p_unorm // Branch if x=unorm
+}
+;;
+
+log1p_common:
+{ .mfi
+ setf.exp FR_A4 = GR_025 // create A4 = 0.25
+ frcpa.s1 FR_RcpX,p0 = f1,FR_Xp1
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p9) fma.s.s0 f8 = f8,f1,f0 // set V-flag
+(p9) br.ret.spnt b0 // exit for NaN, NaT and +Inf
+}
+;;
+
+{ .mfi
+ getf.exp GR_Exp = FR_Xp1 // signexp of x+1
+ fclass.m p10,p0 = FR_Xp1,0x3A // is 1+x < 0?
+ and GR_exp_x = GR_exp_mask, GR_signexp_x // biased exponent of x
+}
+{ .mlx
+ nop.m 0
+ movl GR_Ln2 = 0x3FE62E42FEFA39EF // double precision memory
+ // representation of log(2)
+}
+;;
+
+{ .mfi
+ getf.sig GR_Sig = FR_Xp1 // get significand to calculate index
+ // for T if |x| >= 2^-8
+ fcmp.eq.s1 p12,p0 = f8,f0 // is x equal to 0?
+ sub GR_exp_x = GR_exp_x, GR_exp_bias // true exponent of x
+}
+;;
+
+{ .mfi
+ sub GR_N = GR_Exp,GR_exp_bias // true exponent of x+1
+ fcmp.eq.s1 p11,p0 = FR_Xp1,f0 // is x = -1?
+ cmp.gt p6,p7 = -8, GR_exp_x // Is |x| < 2^-8
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p10) br.cond.spnt log1p_lt_minus_1 // jump if x < -1
+}
+;;
+
+// p6 is true if |x| < 1/256
+// p7 is true if |x| >= 1/256
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fms.s1 FR_r = f8,f1,f0 // range reduction for |x|<1/256
+(p6) cmp.gt.unc p10,p0 = -40, GR_exp_x // Is |x| < 2^-40
+}
+{ .mfb
+(p7) setf.sig FR_N = GR_N // copy unbiased exponent of x to the
+ // significand field of FR_N
+(p7) fms.s1 FR_r = FR_RcpX,FR_Xp1,f1 // range reduction for |x|>=1/256
+(p12) br.ret.spnt b0 // exit for x=0, return x
+}
+;;
+
+{ .mib
+ setf.d FR_Ln2 = GR_Ln2 // create log(2)
+(p7) extr.u GR_Ind = GR_Sig,55,8 // get bits from 55 to 62 as index
+(p11) br.cond.spnt log1p_eq_minus_1 // jump if x = -1
+}
+;;
+
+{ .mmf
+(p7) shladd GR_ad_T = GR_Ind,3,GR_ad_T // address of T
+ nop.m 0
+(p10) fnma.s.s0 f8 = f8,f8,f8 // If |x| very small, result=x-x*x
+}
+;;
+
+{ .mmb
+(p7) ldfd FR_T = [GR_ad_T]
+ nop.m 0
+(p10) br.ret.spnt b0 // Exit if |x| < 2^-40
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r2 = FR_r,FR_r,f0 // r^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_A2 = FR_A2,FR_r,f1 // 1.0 - A2*r
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_A3 = FR_A4,FR_r,FR_A3 // A3 - A4*r
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p7) fcvt.xf FR_N = FR_N
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // (A3*r+A2)*r^2+r
+ fma.s1 FR_A2 = FR_A3,FR_r2,FR_A2 // (A4*r+A3)*r^2+(A2*r+1)
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // N*Ln2hi+T
+(p7) fma.s1 FR_NxLn2pT = FR_N,FR_Ln2,FR_T
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fma.s.s0 f8 = FR_A2,FR_r,f0 // result if 2^(-40) <= |x| < 1/256
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.s.s0 f8 = FR_A2,FR_r,FR_NxLn2pT // result if |x| >= 1/256
+ br.ret.sptk b0 // Exit if |x| >= 2^(-40)
+}
+;;
+
+.align 32
+log1p_unorm:
+// Here if x=unorm
+{ .mfb
+ getf.exp GR_signexp_x = FR_NormX // recompute biased exponent
+ nop.f 0
+ br.cond.sptk log1p_common
+}
+;;
+
+.align 32
+log1p_eq_minus_1:
+// Here if x=-1
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8,f8 // keep input argument for subsequent
+ // call of __libm_error_support#
+ nop.i 0
+}
+;;
+
+{ .mfi
+ mov GR_TAG = 142 // set libm error in case of log1p(-1).
+ frcpa.s0 f8,p0 = f8,f0 // log1p(-1) should be equal to -INF.
+ // We can get it using frcpa because it
+ // sets result to the IEEE-754 mandated
+ // quotient of f8/f0.
+ nop.i 0
+}
+{ .mib
+ nop.m 0
+ nop.i 0
+ br.cond.sptk log_libm_err
+}
+;;
+
+.align 32
+log1p_lt_minus_1:
+// Here if x < -1
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+;;
+
+{ .mfi
+ mov GR_TAG = 143 // set libm error in case of x < -1.
+ frcpa.s0 f8,p0 = f0,f0 // log1p(x) x < -1 should be equal to NaN.
+ // We can get it using frcpa because it
+ // sets result to the IEEE-754 mandated
+ // quotient of f0/f0 i.e. NaN.
+ nop.i 0
+}
+;;
+
+.align 32
+log_libm_err:
+{ .mmi
+ alloc r32 = ar.pfs,1,4,4,0
+ mov GR_Parameter_TAG = GR_TAG
+ nop.i 0
+}
+;;
+
+GLOBAL_IEEE754_END(log1pf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y = -32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS = ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp = -64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP = gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0 = b0 // Save b0
+};;
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_log1pl.S b/libc/sysdeps/ia64/fpu/s_log1pl.S
new file mode 100644
index 000000000..965426500
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_log1pl.S
@@ -0,0 +1,1200 @@
+.file "log1pl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 05/21/01 Removed logl and log10l, putting them in a separate file
+// 06/29/01 Improved speed of all paths
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+//
+//*********************************************************************
+//
+//*********************************************************************
+//
+// Function: log1pl(x) = ln(x+1), for double-extended precision x values
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f34-f82
+//
+// General Purpose Registers:
+// r32-r56
+// r53-r56 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6-p13
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// Denormal fault raised on denormal inputs
+// Overflow exceptions cannot occur
+// Underflow exceptions raised when appropriate for log1p
+// Inexact raised when appropriate by algorithm
+//
+// log1pl(inf) = inf
+// log1pl(-inf) = QNaN
+// log1pl(+/-0) = +/-0
+// log1pl(-1) = -inf
+// log1pl(SNaN) = QNaN
+// log1pl(QNaN) = QNaN
+// log1pl(EM_special Values) = QNaN
+//
+//*********************************************************************
+//
+// Overview
+//
+// The method consists of three cases.
+//
+// If |X| < 2^(-80) use case log1p_small;
+// else |X| < 2^(-7) use case log_near1;
+// else use case log_regular;
+//
+// Case log1p_small:
+//
+// log1pl( X ) = logl( X+1 ) can be approximated by X
+//
+// Case log_near1:
+//
+// log1pl( X ) = log( X+1 ) can be approximated by a simple polynomial
+// in W = X. This polynomial resembles the truncated Taylor
+// series W - W^/2 + W^3/3 - ...
+//
+// Case log_regular:
+//
+// Here we use a table lookup method. The basic idea is that in
+// order to compute logl(Arg) = log1pl (Arg-1) for an argument Arg in [1,2),
+// we construct a value G such that G*Arg is close to 1 and that
+// logl(1/G) is obtainable easily from a table of values calculated
+// beforehand. Thus
+//
+// logl(Arg) = logl(1/G) + logl(G*Arg)
+// = logl(1/G) + logl(1 + (G*Arg - 1))
+//
+// Because |G*Arg - 1| is small, the second term on the right hand
+// side can be approximated by a short polynomial. We elaborate
+// this method in four steps.
+//
+// Step 0: Initialization
+//
+// We need to calculate logl( X+1 ). Obtain N, S_hi such that
+//
+// X+1 = 2^N * ( S_hi + S_lo ) exactly
+//
+// where S_hi in [1,2) and S_lo is a correction to S_hi in the sense
+// that |S_lo| <= ulp(S_hi).
+//
+// Step 1: Argument Reduction
+//
+// Based on S_hi, obtain G_1, G_2, G_3 from a table and calculate
+//
+// G := G_1 * G_2 * G_3
+// r := (G * S_hi - 1) + G * S_lo
+//
+// These G_j's have the property that the product is exactly
+// representable and that |r| < 2^(-12) as a result.
+//
+// Step 2: Approximation
+//
+//
+// logl(1 + r) is approximated by a short polynomial poly(r).
+//
+// Step 3: Reconstruction
+//
+//
+// Finally, log1pl( X ) = logl( X+1 ) is given by
+//
+// logl( X+1 ) = logl( 2^N * (S_hi + S_lo) )
+// ~=~ N*logl(2) + logl(1/G) + logl(1 + r)
+// ~=~ N*logl(2) + logl(1/G) + poly(r).
+//
+// **** Algorithm ****
+//
+// Case log1p_small:
+//
+// Although log1pl(X) is basically X, we would like to preserve the inexactness
+// nature as well as consistent behavior under different rounding modes.
+// We can do this by computing the result as
+//
+// log1pl(X) = X - X*X
+//
+//
+// Case log_near1:
+//
+// Here we compute a simple polynomial. To exploit parallelism, we split
+// the polynomial into two portions.
+//
+// W := X
+// Wsq := W * W
+// W4 := Wsq*Wsq
+// W6 := W4*Wsq
+// Y_hi := W + Wsq*(P_1 + W*(P_2 + W*(P_3 + W*P_4))
+// Y_lo := W6*(P_5 + W*(P_6 + W*(P_7 + W*P_8)))
+//
+// Case log_regular:
+//
+// We present the algorithm in four steps.
+//
+// Step 0. Initialization
+// ----------------------
+//
+// Z := X + 1
+// N := unbaised exponent of Z
+// S_hi := 2^(-N) * Z
+// S_lo := 2^(-N) * { (max(X,1)-Z) + min(X,1) }
+//
+// Step 1. Argument Reduction
+// --------------------------
+//
+// Let
+//
+// Z = 2^N * S_hi = 2^N * 1.d_1 d_2 d_3 ... d_63
+//
+// We obtain G_1, G_2, G_3 by the following steps.
+//
+//
+// Define X_0 := 1.d_1 d_2 ... d_14. This is extracted
+// from S_hi.
+//
+// Define A_1 := 1.d_1 d_2 d_3 d_4. This is X_0 truncated
+// to lsb = 2^(-4).
+//
+// Define index_1 := [ d_1 d_2 d_3 d_4 ].
+//
+// Fetch Z_1 := (1/A_1) rounded UP in fixed point with
+// fixed point lsb = 2^(-15).
+// Z_1 looks like z_0.z_1 z_2 ... z_15
+// Note that the fetching is done using index_1.
+// A_1 is actually not needed in the implementation
+// and is used here only to explain how is the value
+// Z_1 defined.
+//
+// Fetch G_1 := (1/A_1) truncated to 21 sig. bits.
+// floating pt. Again, fetching is done using index_1. A_1
+// explains how G_1 is defined.
+//
+// Calculate X_1 := X_0 * Z_1 truncated to lsb = 2^(-14)
+// = 1.0 0 0 0 d_5 ... d_14
+// This is accomplised by integer multiplication.
+// It is proved that X_1 indeed always begin
+// with 1.0000 in fixed point.
+//
+//
+// Define A_2 := 1.0 0 0 0 d_5 d_6 d_7 d_8. This is X_1
+// truncated to lsb = 2^(-8). Similar to A_1,
+// A_2 is not needed in actual implementation. It
+// helps explain how some of the values are defined.
+//
+// Define index_2 := [ d_5 d_6 d_7 d_8 ].
+//
+// Fetch Z_2 := (1/A_2) rounded UP in fixed point with
+// fixed point lsb = 2^(-15). Fetch done using index_2.
+// Z_2 looks like z_0.z_1 z_2 ... z_15
+//
+// Fetch G_2 := (1/A_2) truncated to 21 sig. bits.
+// floating pt.
+//
+// Calculate X_2 := X_1 * Z_2 truncated to lsb = 2^(-14)
+// = 1.0 0 0 0 0 0 0 0 d_9 d_10 ... d_14
+// This is accomplised by integer multiplication.
+// It is proved that X_2 indeed always begin
+// with 1.00000000 in fixed point.
+//
+//
+// Define A_3 := 1.0 0 0 0 0 0 0 0 d_9 d_10 d_11 d_12 d_13 1.
+// This is 2^(-14) + X_2 truncated to lsb = 2^(-13).
+//
+// Define index_3 := [ d_9 d_10 d_11 d_12 d_13 ].
+//
+// Fetch G_3 := (1/A_3) truncated to 21 sig. bits.
+// floating pt. Fetch is done using index_3.
+//
+// Compute G := G_1 * G_2 * G_3.
+//
+// This is done exactly since each of G_j only has 21 sig. bits.
+//
+// Compute
+//
+// r := (G*S_hi - 1) + G*S_lo using 2 FMA operations.
+//
+// Thus r approximates G*(S_hi + S_lo) - 1 to within a couple of
+// rounding errors.
+//
+//
+// Step 2. Approximation
+// ---------------------
+//
+// This step computes an approximation to logl( 1 + r ) where r is the
+// reduced argument just obtained. It is proved that |r| <= 1.9*2^(-13);
+// thus logl(1+r) can be approximated by a short polynomial:
+//
+// logl(1+r) ~=~ poly = r + Q1 r^2 + ... + Q4 r^5
+//
+//
+// Step 3. Reconstruction
+// ----------------------
+//
+// This step computes the desired result of logl(X+1):
+//
+// logl(X+1) = logl( 2^N * (S_hi + S_lo) )
+// = N*logl(2) + logl( S_hi + S_lo) )
+// = N*logl(2) + logl(1/G) +
+// logl(1 + G * ( S_hi + S_lo ) - 1 )
+//
+// logl(2), logl(1/G_j) are stored as pairs of (single,double) numbers:
+// log2_hi, log2_lo, log1byGj_hi, log1byGj_lo. The high parts are
+// single-precision numbers and the low parts are double precision
+// numbers. These have the property that
+//
+// N*log2_hi + SUM ( log1byGj_hi )
+//
+// is computable exactly in double-extended precision (64 sig. bits).
+// Finally
+//
+// Y_hi := N*log2_hi + SUM ( log1byGj_hi )
+// Y_lo := poly_hi + [ poly_lo +
+// ( SUM ( log1byGj_lo ) + N*log2_lo ) ]
+//
+
+RODATA
+.align 64
+
+// ************* DO NOT CHANGE THE ORDER OF THESE TABLES *************
+
+// P_8, P_7, P_6, P_5, P_4, P_3, P_2, and P_1
+
+LOCAL_OBJECT_START(Constants_P)
+//data4 0xEFD62B15,0xE3936754,0x00003FFB,0x00000000
+//data4 0xA5E56381,0x8003B271,0x0000BFFC,0x00000000
+//data4 0x73282DB0,0x9249248C,0x00003FFC,0x00000000
+//data4 0x47305052,0xAAAAAA9F,0x0000BFFC,0x00000000
+//data4 0xCCD17FC9,0xCCCCCCCC,0x00003FFC,0x00000000
+//data4 0x00067ED5,0x80000000,0x0000BFFD,0x00000000
+//data4 0xAAAAAAAA,0xAAAAAAAA,0x00003FFD,0x00000000
+//data4 0xFFFFFFFE,0xFFFFFFFF,0x0000BFFD,0x00000000
+data8 0xE3936754EFD62B15,0x00003FFB
+data8 0x8003B271A5E56381,0x0000BFFC
+data8 0x9249248C73282DB0,0x00003FFC
+data8 0xAAAAAA9F47305052,0x0000BFFC
+data8 0xCCCCCCCCCCD17FC9,0x00003FFC
+data8 0x8000000000067ED5,0x0000BFFD
+data8 0xAAAAAAAAAAAAAAAA,0x00003FFD
+data8 0xFFFFFFFFFFFFFFFE,0x0000BFFD
+LOCAL_OBJECT_END(Constants_P)
+
+// log2_hi, log2_lo, Q_4, Q_3, Q_2, and Q_1
+
+LOCAL_OBJECT_START(Constants_Q)
+//data4 0x00000000,0xB1721800,0x00003FFE,0x00000000
+//data4 0x4361C4C6,0x82E30865,0x0000BFE2,0x00000000
+//data4 0x328833CB,0xCCCCCAF2,0x00003FFC,0x00000000
+//data4 0xA9D4BAFB,0x80000077,0x0000BFFD,0x00000000
+//data4 0xAAABE3D2,0xAAAAAAAA,0x00003FFD,0x00000000
+//data4 0xFFFFDAB7,0xFFFFFFFF,0x0000BFFD,0x00000000
+data8 0xB172180000000000,0x00003FFE
+data8 0x82E308654361C4C6,0x0000BFE2
+data8 0xCCCCCAF2328833CB,0x00003FFC
+data8 0x80000077A9D4BAFB,0x0000BFFD
+data8 0xAAAAAAAAAAABE3D2,0x00003FFD
+data8 0xFFFFFFFFFFFFDAB7,0x0000BFFD
+LOCAL_OBJECT_END(Constants_Q)
+
+// 1/ln10_hi, 1/ln10_lo
+
+LOCAL_OBJECT_START(Constants_1_by_LN10)
+//data4 0x37287195,0xDE5BD8A9,0x00003FFD,0x00000000
+//data4 0xACCF70C8,0xD56EAABE,0x00003FBB,0x00000000
+data8 0xDE5BD8A937287195,0x00003FFD
+data8 0xD56EAABEACCF70C8,0x00003FBB
+LOCAL_OBJECT_END(Constants_1_by_LN10)
+
+
+// Z1 - 16 bit fixed
+
+LOCAL_OBJECT_START(Constants_Z_1)
+data4 0x00008000
+data4 0x00007879
+data4 0x000071C8
+data4 0x00006BCB
+data4 0x00006667
+data4 0x00006187
+data4 0x00005D18
+data4 0x0000590C
+data4 0x00005556
+data4 0x000051EC
+data4 0x00004EC5
+data4 0x00004BDB
+data4 0x00004925
+data4 0x0000469F
+data4 0x00004445
+data4 0x00004211
+LOCAL_OBJECT_END(Constants_Z_1)
+
+// G1 and H1 - IEEE single and h1 - IEEE double
+
+LOCAL_OBJECT_START(Constants_G_H_h1)
+data4 0x3F800000,0x00000000
+data8 0x0000000000000000
+data4 0x3F70F0F0,0x3D785196
+data8 0x3DA163A6617D741C
+data4 0x3F638E38,0x3DF13843
+data8 0x3E2C55E6CBD3D5BB
+data4 0x3F579430,0x3E2FF9A0
+data8 0xBE3EB0BFD86EA5E7
+data4 0x3F4CCCC8,0x3E647FD6
+data8 0x3E2E6A8C86B12760
+data4 0x3F430C30,0x3E8B3AE7
+data8 0x3E47574C5C0739BA
+data4 0x3F3A2E88,0x3EA30C68
+data8 0x3E20E30F13E8AF2F
+data4 0x3F321640,0x3EB9CEC8
+data8 0xBE42885BF2C630BD
+data4 0x3F2AAAA8,0x3ECF9927
+data8 0x3E497F3497E577C6
+data4 0x3F23D708,0x3EE47FC5
+data8 0x3E3E6A6EA6B0A5AB
+data4 0x3F1D89D8,0x3EF8947D
+data8 0xBDF43E3CD328D9BE
+data4 0x3F17B420,0x3F05F3A1
+data8 0x3E4094C30ADB090A
+data4 0x3F124920,0x3F0F4303
+data8 0xBE28FBB2FC1FE510
+data4 0x3F0D3DC8,0x3F183EBF
+data8 0x3E3A789510FDE3FA
+data4 0x3F088888,0x3F20EC80
+data8 0x3E508CE57CC8C98F
+data4 0x3F042108,0x3F29516A
+data8 0xBE534874A223106C
+LOCAL_OBJECT_END(Constants_G_H_h1)
+
+// Z2 - 16 bit fixed
+
+LOCAL_OBJECT_START(Constants_Z_2)
+data4 0x00008000
+data4 0x00007F81
+data4 0x00007F02
+data4 0x00007E85
+data4 0x00007E08
+data4 0x00007D8D
+data4 0x00007D12
+data4 0x00007C98
+data4 0x00007C20
+data4 0x00007BA8
+data4 0x00007B31
+data4 0x00007ABB
+data4 0x00007A45
+data4 0x000079D1
+data4 0x0000795D
+data4 0x000078EB
+LOCAL_OBJECT_END(Constants_Z_2)
+
+// G2 and H2 - IEEE single and h2 - IEEE double
+
+LOCAL_OBJECT_START(Constants_G_H_h2)
+data4 0x3F800000,0x00000000
+data8 0x0000000000000000
+data4 0x3F7F00F8,0x3B7F875D
+data8 0x3DB5A11622C42273
+data4 0x3F7E03F8,0x3BFF015B
+data8 0x3DE620CF21F86ED3
+data4 0x3F7D08E0,0x3C3EE393
+data8 0xBDAFA07E484F34ED
+data4 0x3F7C0FC0,0x3C7E0586
+data8 0xBDFE07F03860BCF6
+data4 0x3F7B1880,0x3C9E75D2
+data8 0x3DEA370FA78093D6
+data4 0x3F7A2328,0x3CBDC97A
+data8 0x3DFF579172A753D0
+data4 0x3F792FB0,0x3CDCFE47
+data8 0x3DFEBE6CA7EF896B
+data4 0x3F783E08,0x3CFC15D0
+data8 0x3E0CF156409ECB43
+data4 0x3F774E38,0x3D0D874D
+data8 0xBE0B6F97FFEF71DF
+data4 0x3F766038,0x3D1CF49B
+data8 0xBE0804835D59EEE8
+data4 0x3F757400,0x3D2C531D
+data8 0x3E1F91E9A9192A74
+data4 0x3F748988,0x3D3BA322
+data8 0xBE139A06BF72A8CD
+data4 0x3F73A0D0,0x3D4AE46F
+data8 0x3E1D9202F8FBA6CF
+data4 0x3F72B9D0,0x3D5A1756
+data8 0xBE1DCCC4BA796223
+data4 0x3F71D488,0x3D693B9D
+data8 0xBE049391B6B7C239
+LOCAL_OBJECT_END(Constants_G_H_h2)
+
+// G3 and H3 - IEEE single and h3 - IEEE double
+
+LOCAL_OBJECT_START(Constants_G_H_h3)
+data4 0x3F7FFC00,0x38800100
+data8 0x3D355595562224CD
+data4 0x3F7FF400,0x39400480
+data8 0x3D8200A206136FF6
+data4 0x3F7FEC00,0x39A00640
+data8 0x3DA4D68DE8DE9AF0
+data4 0x3F7FE400,0x39E00C41
+data8 0xBD8B4291B10238DC
+data4 0x3F7FDC00,0x3A100A21
+data8 0xBD89CCB83B1952CA
+data4 0x3F7FD400,0x3A300F22
+data8 0xBDB107071DC46826
+data4 0x3F7FCC08,0x3A4FF51C
+data8 0x3DB6FCB9F43307DB
+data4 0x3F7FC408,0x3A6FFC1D
+data8 0xBD9B7C4762DC7872
+data4 0x3F7FBC10,0x3A87F20B
+data8 0xBDC3725E3F89154A
+data4 0x3F7FB410,0x3A97F68B
+data8 0xBD93519D62B9D392
+data4 0x3F7FAC18,0x3AA7EB86
+data8 0x3DC184410F21BD9D
+data4 0x3F7FA420,0x3AB7E101
+data8 0xBDA64B952245E0A6
+data4 0x3F7F9C20,0x3AC7E701
+data8 0x3DB4B0ECAABB34B8
+data4 0x3F7F9428,0x3AD7DD7B
+data8 0x3D9923376DC40A7E
+data4 0x3F7F8C30,0x3AE7D474
+data8 0x3DC6E17B4F2083D3
+data4 0x3F7F8438,0x3AF7CBED
+data8 0x3DAE314B811D4394
+data4 0x3F7F7C40,0x3B03E1F3
+data8 0xBDD46F21B08F2DB1
+data4 0x3F7F7448,0x3B0BDE2F
+data8 0xBDDC30A46D34522B
+data4 0x3F7F6C50,0x3B13DAAA
+data8 0x3DCB0070B1F473DB
+data4 0x3F7F6458,0x3B1BD766
+data8 0xBDD65DDC6AD282FD
+data4 0x3F7F5C68,0x3B23CC5C
+data8 0xBDCDAB83F153761A
+data4 0x3F7F5470,0x3B2BC997
+data8 0xBDDADA40341D0F8F
+data4 0x3F7F4C78,0x3B33C711
+data8 0x3DCD1BD7EBC394E8
+data4 0x3F7F4488,0x3B3BBCC6
+data8 0xBDC3532B52E3E695
+data4 0x3F7F3C90,0x3B43BAC0
+data8 0xBDA3961EE846B3DE
+data4 0x3F7F34A0,0x3B4BB0F4
+data8 0xBDDADF06785778D4
+data4 0x3F7F2CA8,0x3B53AF6D
+data8 0x3DCC3ED1E55CE212
+data4 0x3F7F24B8,0x3B5BA620
+data8 0xBDBA31039E382C15
+data4 0x3F7F1CC8,0x3B639D12
+data8 0x3D635A0B5C5AF197
+data4 0x3F7F14D8,0x3B6B9444
+data8 0xBDDCCB1971D34EFC
+data4 0x3F7F0CE0,0x3B7393BC
+data8 0x3DC7450252CD7ADA
+data4 0x3F7F04F0,0x3B7B8B6D
+data8 0xBDB68F177D7F2A42
+LOCAL_OBJECT_END(Constants_G_H_h3)
+
+
+// Floating Point Registers
+
+FR_Input_X = f8
+
+FR_Y_hi = f34
+FR_Y_lo = f35
+
+FR_Scale = f36
+FR_X_Prime = f37
+FR_S_hi = f38
+FR_W = f39
+FR_G = f40
+
+FR_H = f41
+FR_wsq = f42
+FR_w4 = f43
+FR_h = f44
+FR_w6 = f45
+
+FR_G2 = f46
+FR_H2 = f47
+FR_poly_lo = f48
+FR_P8 = f49
+FR_poly_hi = f50
+
+FR_P7 = f51
+FR_h2 = f52
+FR_rsq = f53
+FR_P6 = f54
+FR_r = f55
+
+FR_log2_hi = f56
+FR_log2_lo = f57
+FR_p87 = f58
+FR_p876 = f58
+FR_p8765 = f58
+FR_float_N = f59
+FR_Q4 = f60
+
+FR_p43 = f61
+FR_p432 = f61
+FR_p4321 = f61
+FR_P4 = f62
+FR_G3 = f63
+FR_H3 = f64
+FR_h3 = f65
+
+FR_Q3 = f66
+FR_P3 = f67
+FR_Q2 = f68
+FR_P2 = f69
+FR_1LN10_hi = f70
+
+FR_Q1 = f71
+FR_P1 = f72
+FR_1LN10_lo = f73
+FR_P5 = f74
+FR_rcub = f75
+
+FR_Output_X_tmp = f76
+FR_Neg_One = f77
+FR_Z = f78
+FR_AA = f79
+FR_BB = f80
+FR_S_lo = f81
+FR_2_to_minus_N = f82
+
+FR_X = f8
+FR_Y = f0
+FR_RESULT = f76
+
+
+// General Purpose Registers
+
+GR_ad_p = r33
+GR_Index1 = r34
+GR_Index2 = r35
+GR_signif = r36
+GR_X_0 = r37
+GR_X_1 = r38
+GR_X_2 = r39
+GR_minus_N = r39
+GR_Z_1 = r40
+GR_Z_2 = r41
+GR_N = r42
+GR_Bias = r43
+GR_M = r44
+GR_Index3 = r45
+GR_exp_2tom80 = r45
+GR_ad_p2 = r46
+GR_exp_mask = r47
+GR_exp_2tom7 = r48
+GR_ad_ln10 = r49
+GR_ad_tbl_1 = r50
+GR_ad_tbl_2 = r51
+GR_ad_tbl_3 = r52
+GR_ad_q = r53
+GR_ad_z_1 = r54
+GR_ad_z_2 = r55
+GR_ad_z_3 = r56
+GR_minus_N = r39
+
+//
+// Added for unwind support
+//
+
+GR_SAVE_PFS = r50
+GR_SAVE_B0 = r51
+GR_SAVE_GP = r52
+GR_Parameter_X = r53
+GR_Parameter_Y = r54
+GR_Parameter_RESULT = r55
+GR_Parameter_TAG = r56
+
+.section .text
+GLOBAL_IEEE754_ENTRY(log1pl)
+{ .mfi
+ alloc r32 = ar.pfs,0,21,4,0
+ fclass.m p6, p0 = FR_Input_X, 0x1E3 // Test for natval, nan, inf
+ nop.i 999
+}
+{ .mfi
+ addl GR_ad_z_1 = @ltoff(Constants_Z_1#),gp
+ fma.s1 FR_Z = FR_Input_X, f1, f1 // x+1
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fmerge.ns FR_Neg_One = f1, f1 // Form -1.0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnorm.s1 FR_X_Prime = FR_Input_X // Normalize x
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ld8 GR_ad_z_1 = [GR_ad_z_1] // Get pointer to Constants_Z_1
+ nop.f 999
+ mov GR_exp_2tom7 = 0x0fff8 // Exponent of 2^-7
+}
+;;
+
+{ .mfb
+ getf.sig GR_signif = FR_Z // Get significand of x+1
+ fcmp.eq.s1 p9, p0 = FR_Input_X, f0 // Test for x=0
+(p6) br.cond.spnt LOG1P_special // Branch for nan, inf, natval
+}
+;;
+
+{ .mfi
+ add GR_ad_tbl_1 = 0x040, GR_ad_z_1 // Point to Constants_G_H_h1
+ fcmp.lt.s1 p13, p0 = FR_X_Prime, FR_Neg_One // Test for x<-1
+ add GR_ad_p = -0x100, GR_ad_z_1 // Point to Constants_P
+}
+{ .mfi
+ add GR_ad_z_2 = 0x140, GR_ad_z_1 // Point to Constants_Z_2
+ nop.f 999
+ add GR_ad_tbl_2 = 0x180, GR_ad_z_1 // Point to Constants_G_H_h2
+}
+;;
+
+{ .mfi
+ add GR_ad_q = 0x080, GR_ad_p // Point to Constants_Q
+ fcmp.eq.s1 p8, p0 = FR_X_Prime, FR_Neg_One // Test for x=-1
+ extr.u GR_Index1 = GR_signif, 59, 4 // Get high 4 bits of signif
+}
+{ .mfb
+ add GR_ad_tbl_3 = 0x280, GR_ad_z_1 // Point to Constants_G_H_h3
+ nop.f 999
+(p9) br.ret.spnt b0 // Exit if x=0, return input
+}
+;;
+
+{ .mfi
+ shladd GR_ad_z_1 = GR_Index1, 2, GR_ad_z_1 // Point to Z_1
+ fclass.nm p10, p0 = FR_Input_X, 0x1FF // Test for unsupported
+ extr.u GR_X_0 = GR_signif, 49, 15 // Get high 15 bits of significand
+}
+{ .mfi
+ ldfe FR_P8 = [GR_ad_p],16 // Load P_8 for near1 path
+ fsub.s1 FR_W = FR_X_Prime, f0 // W = x
+ add GR_ad_ln10 = 0x060, GR_ad_q // Point to Constants_1_by_LN10
+}
+;;
+
+{ .mfi
+ ld4 GR_Z_1 = [GR_ad_z_1] // Load Z_1
+ fmax.s1 FR_AA = FR_X_Prime, f1 // For S_lo, form AA = max(X,1.0)
+ mov GR_exp_mask = 0x1FFFF // Create exponent mask
+}
+{ .mib
+ shladd GR_ad_tbl_1 = GR_Index1, 4, GR_ad_tbl_1 // Point to G_1
+ mov GR_Bias = 0x0FFFF // Create exponent bias
+(p13) br.cond.spnt LOG1P_LT_Minus_1 // Branch if x<-1
+}
+;;
+
+{ .mfb
+ ldfps FR_G, FR_H = [GR_ad_tbl_1],8 // Load G_1, H_1
+ fmerge.se FR_S_hi = f1,FR_Z // Form |x+1|
+(p8) br.cond.spnt LOG1P_EQ_Minus_1 // Branch if x=-1
+}
+;;
+
+{ .mmb
+ getf.exp GR_N = FR_Z // Get N = exponent of x+1
+ ldfd FR_h = [GR_ad_tbl_1] // Load h_1
+(p10) br.cond.spnt LOG1P_unsupported // Branch for unsupported type
+}
+;;
+
+{ .mfi
+ ldfe FR_log2_hi = [GR_ad_q],16 // Load log2_hi
+ fcmp.eq.s0 p8, p0 = FR_Input_X, f0 // Dummy op to flag denormals
+ pmpyshr2.u GR_X_1 = GR_X_0,GR_Z_1,15 // Get bits 30-15 of X_0 * Z_1
+}
+;;
+
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mmi
+ ldfe FR_log2_lo = [GR_ad_q],16 // Load log2_lo
+ sub GR_N = GR_N, GR_Bias
+ mov GR_exp_2tom80 = 0x0ffaf // Exponent of 2^-80
+}
+;;
+
+{ .mfi
+ ldfe FR_Q4 = [GR_ad_q],16 // Load Q4
+ fms.s1 FR_S_lo = FR_AA, f1, FR_Z // Form S_lo = AA - Z
+ sub GR_minus_N = GR_Bias, GR_N // Form exponent of 2^(-N)
+}
+;;
+
+{ .mmf
+ ldfe FR_Q3 = [GR_ad_q],16 // Load Q3
+ setf.sig FR_float_N = GR_N // Put integer N into rightmost significand
+ fmin.s1 FR_BB = FR_X_Prime, f1 // For S_lo, form BB = min(X,1.0)
+}
+;;
+
+{ .mmi
+ getf.exp GR_M = FR_W // Get signexp of w = x
+ ldfe FR_Q2 = [GR_ad_q],16 // Load Q2
+ extr.u GR_Index2 = GR_X_1, 6, 4 // Extract bits 6-9 of X_1
+}
+;;
+
+{ .mmi
+ ldfe FR_Q1 = [GR_ad_q] // Load Q1
+ shladd GR_ad_z_2 = GR_Index2, 2, GR_ad_z_2 // Point to Z_2
+ add GR_ad_p2 = 0x30,GR_ad_p // Point to P_4
+}
+;;
+
+{ .mmi
+ ld4 GR_Z_2 = [GR_ad_z_2] // Load Z_2
+ shladd GR_ad_tbl_2 = GR_Index2, 4, GR_ad_tbl_2 // Point to G_2
+ and GR_M = GR_exp_mask, GR_M // Get exponent of w = x
+}
+;;
+
+{ .mmi
+ ldfps FR_G2, FR_H2 = [GR_ad_tbl_2],8 // Load G_2, H_2
+ cmp.lt p8, p9 = GR_M, GR_exp_2tom7 // Test |x| < 2^-7
+ cmp.lt p7, p0 = GR_M, GR_exp_2tom80 // Test |x| < 2^-80
+}
+;;
+
+// Small path is separate code
+// p7 is for the small path: |x| < 2^-80
+// near1 and regular paths are merged.
+// p8 is for the near1 path: |x| < 2^-7
+// p9 is for regular path: |x| >= 2^-7
+
+{ .mfi
+ ldfd FR_h2 = [GR_ad_tbl_2] // Load h_2
+ nop.f 999
+ nop.i 999
+}
+{ .mfb
+(p9) setf.exp FR_2_to_minus_N = GR_minus_N // Form 2^(-N)
+(p7) fnma.s0 f8 = FR_X_Prime, FR_X_Prime, FR_X_Prime // Result x - x*x
+(p7) br.ret.spnt b0 // Branch if |x| < 2^-80
+}
+;;
+
+{ .mmi
+(p8) ldfe FR_P7 = [GR_ad_p],16 // Load P_7 for near1 path
+(p8) ldfe FR_P4 = [GR_ad_p2],16 // Load P_4 for near1 path
+(p9) pmpyshr2.u GR_X_2 = GR_X_1,GR_Z_2,15 // Get bits 30-15 of X_1 * Z_2
+}
+;;
+
+//
+// For performance, don't use result of pmpyshr2.u for 4 cycles.
+//
+{ .mmf
+(p8) ldfe FR_P6 = [GR_ad_p],16 // Load P_6 for near1 path
+(p8) ldfe FR_P3 = [GR_ad_p2],16 // Load P_3 for near1 path
+(p9) fma.s1 FR_S_lo = FR_S_lo, f1, FR_BB // S_lo = S_lo + BB
+}
+;;
+
+{ .mmf
+(p8) ldfe FR_P5 = [GR_ad_p],16 // Load P_5 for near1 path
+(p8) ldfe FR_P2 = [GR_ad_p2],16 // Load P_2 for near1 path
+(p8) fmpy.s1 FR_wsq = FR_W, FR_W // wsq = w * w for near1 path
+}
+;;
+
+{ .mmi
+(p8) ldfe FR_P1 = [GR_ad_p2],16 ;; // Load P_1 for near1 path
+ nop.m 999
+(p9) extr.u GR_Index3 = GR_X_2, 1, 5 // Extract bits 1-5 of X_2
+}
+;;
+
+{ .mfi
+(p9) shladd GR_ad_tbl_3 = GR_Index3, 4, GR_ad_tbl_3 // Point to G_3
+(p9) fcvt.xf FR_float_N = FR_float_N
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p9) ldfps FR_G3, FR_H3 = [GR_ad_tbl_3],8 // Load G_3, H_3
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p9) ldfd FR_h3 = [GR_ad_tbl_3] // Load h_3
+(p9) fmpy.s1 FR_G = FR_G, FR_G2 // G = G_1 * G_2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fadd.s1 FR_H = FR_H, FR_H2 // H = H_1 + H_2
+ nop.i 999
+}
+;;
+
+{ .mmf
+ nop.m 999
+ nop.m 999
+(p9) fadd.s1 FR_h = FR_h, FR_h2 // h = h_1 + h_2
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fmpy.s1 FR_w4 = FR_wsq, FR_wsq // w4 = w^4 for near1 path
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_p87 = FR_W, FR_P8, FR_P7 // p87 = w * P8 + P7
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_S_lo = FR_S_lo, FR_2_to_minus_N, f0 // S_lo = S_lo * 2^(-N)
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_p43 = FR_W, FR_P4, FR_P3 // p43 = w * P4 + P3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fmpy.s1 FR_G = FR_G, FR_G3 // G = (G_1 * G_2) * G_3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fadd.s1 FR_H = FR_H, FR_H3 // H = (H_1 + H_2) + H_3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fadd.s1 FR_h = FR_h, FR_h3 // h = (h_1 + h_2) + h_3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fmpy.s1 FR_w6 = FR_w4, FR_wsq // w6 = w^6 for near1 path
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_p432 = FR_W, FR_p43, FR_P2 // p432 = w * p43 + P2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_p876 = FR_W, FR_p87, FR_P6 // p876 = w * p87 + P6
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fms.s1 FR_r = FR_G, FR_S_hi, f1 // r = G * S_hi - 1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_Y_hi = FR_float_N, FR_log2_hi, FR_H // Y_hi = N * log2_hi + H
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_h = FR_float_N, FR_log2_lo, FR_h // h = N * log2_lo + h
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_r = FR_G, FR_S_lo, FR_r // r = G * S_lo + (G * S_hi - 1)
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_p4321 = FR_W, FR_p432, FR_P1 // p4321 = w * p432 + P1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_p8765 = FR_W, FR_p876, FR_P5 // p8765 = w * p876 + P5
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_lo = FR_r, FR_Q4, FR_Q3 // poly_lo = r * Q4 + Q3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fmpy.s1 FR_rsq = FR_r, FR_r // rsq = r * r
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_Y_lo = FR_wsq, FR_p4321, f0 // Y_lo = wsq * p4321
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_Y_hi = FR_W, f1, f0 // Y_hi = w for near1 path
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_lo = FR_poly_lo, FR_r, FR_Q2 // poly_lo = poly_lo * r + Q2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_rcub = FR_rsq, FR_r, f0 // rcub = r^3
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 FR_Y_lo = FR_w6, FR_p8765,FR_Y_lo // Y_lo = w6 * p8765 + w2 * p4321
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_hi = FR_Q1, FR_rsq, FR_r // poly_hi = Q1 * rsq + r
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 FR_poly_lo = FR_poly_lo, FR_rcub, FR_h // poly_lo = poly_lo*r^3 + h
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fadd.s1 FR_Y_lo = FR_poly_hi, FR_poly_lo // Y_lo = poly_hi + poly_lo
+ nop.i 999
+}
+;;
+
+// Remainder of code is common for near1 and regular paths
+{ .mfb
+ nop.m 999
+ fadd.s0 f8 = FR_Y_lo,FR_Y_hi // Result=Y_lo+Y_hi
+ br.ret.sptk b0 // Common exit for 2^-80 < x < inf
+}
+;;
+
+
+// Here if x=-1
+LOG1P_EQ_Minus_1:
+//
+// If x=-1 raise divide by zero and return -inf
+//
+{ .mfi
+ mov GR_Parameter_TAG = 138
+ fsub.s1 FR_Output_X_tmp = f0, f1
+ nop.i 999
+}
+;;
+
+{ .mfb
+ nop.m 999
+ frcpa.s0 FR_Output_X_tmp, p8 = FR_Output_X_tmp, f0
+ br.cond.sptk __libm_error_region
+}
+;;
+
+LOG1P_special:
+{ .mfi
+ nop.m 999
+ fclass.m.unc p8, p0 = FR_Input_X, 0x1E1 // Test for natval, nan, +inf
+ nop.i 999
+}
+;;
+
+//
+// For SNaN raise invalid and return QNaN.
+// For QNaN raise invalid and return QNaN.
+// For +Inf return +Inf.
+//
+{ .mfb
+ nop.m 999
+(p8) fmpy.s0 f8 = FR_Input_X, f1
+(p8) br.ret.sptk b0 // Return for natval, nan, +inf
+}
+;;
+
+//
+// For -Inf raise invalid and return QNaN.
+//
+{ .mfb
+ mov GR_Parameter_TAG = 139
+ fmpy.s0 FR_Output_X_tmp = FR_Input_X, f0
+ br.cond.sptk __libm_error_region
+}
+;;
+
+
+LOG1P_unsupported:
+//
+// Return generated NaN or other value.
+//
+{ .mfb
+ nop.m 999
+ fmpy.s0 f8 = FR_Input_X, f0
+ br.ret.sptk b0
+}
+;;
+
+// Here if -inf < x < -1
+LOG1P_LT_Minus_1:
+//
+// Deal with x < -1 in a special way - raise
+// invalid and produce QNaN indefinite.
+//
+{ .mfb
+ mov GR_Parameter_TAG = 139
+ frcpa.s0 FR_Output_X_tmp, p8 = f0, f0
+ br.cond.sptk __libm_error_region
+}
+;;
+
+
+GLOBAL_IEEE754_END(log1pl)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 999
+ nop.m 999
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region#)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_logb.S b/libc/sysdeps/ia64/fpu/s_logb.S
new file mode 100644
index 000000000..7ee898712
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_logb.S
@@ -0,0 +1,281 @@
+.file "logb.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/16/00 Modified to conform to C9X
+// 03/16/00 Improved speed
+// 04/04/00 Unwind support added
+// 05/30/00 Fixed bug when x double-extended denormal
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance
+//
+// API
+//==============================================================
+// double logb( double x );
+//
+// Overview of operation
+//==============================================================
+// The logb function extracts the exponent of x as an integer in
+// floating-point format.
+// logb computes log2 of x as a double
+//
+// logb is similar to ilogb but differs in the following ways:
+// +-inf
+// ilogb: returns INT_MAX
+// logb: returns +inf
+// Nan returns FP_LOGBNAN (which is either INT_MAX or INT_MIN)
+// ilogb: returns INT_MAX (7fffffff)
+// logb: returns QNAN (quietized SNAN)
+// 0 returns FP_ILOGB0 (which is either INT_MIN or -INT_MAX)
+// ilogb: returns -INT_MAX (80000001)
+// logb: returns -inf, raises the divide-by-zero exception,
+// and calls libm_error_support to set domain error
+//
+// Registers used
+//==============================================================
+// general registers used:
+// r26 -> r38
+// r35 -> r38 used as parameters to error path
+//
+// predicate registers used:
+// p6, p7, p8
+// floating-point registers used:
+// f9, f10, f11
+// f8, input
+
+rExpBias = r26
+rExpMask = r27
+rSignexp_x = r28
+rExp_x = r29
+rTrueExp_x = r30
+rExp_2to64 = r31
+
+GR_SAVE_PFS = r32
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Parameter_TAG = r38
+
+fExp_in_signif = f9
+fNorm_x = f10
+fFloat_Exp = f10
+f2to64 = f11
+
+.section .text
+GLOBAL_LIBM_ENTRY(logb)
+
+// X NORMAL
+// TrueExp_x = exp(f8) - 0xffff
+// sig = TrueExp_x
+// f8 = convert_to_fp (sig))
+{ .mfi
+ getf.exp rSignexp_x = f8
+ fclass.m p8,p0 = f8, 0x0b // Test for x unorm
+ mov rExpBias = 0xffff // Exponent bias
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNorm_x = f8
+ mov rExpMask = 0x1ffff // Exponent mask
+}
+;;
+
+// Form signexp of 2^64 in case need to scale denormal
+{ .mfb
+ mov rExp_2to64 = 0x1003f
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+(p8) br.cond.spnt LOGB_DENORM // Branch if x unorm
+}
+;;
+
+LOGB_COMMON:
+// Return here from LOGB_DENORM
+{ .mfi
+ and rExp_x = rSignexp_x, rExpMask // Get biased exponent
+ fclass.m p7,p0 = f8, 0x07 // Test x zero
+ nop.i 0
+}
+;;
+
+// X NAN or INFINITY, return f8 * f8
+{ .mfb
+ sub rTrueExp_x = rExp_x, rExpBias // Get true exponent
+(p6) fma.d.s0 f8= f8,f8,f0 // Result if x natval, nan, inf
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf
+}
+;;
+
+{ .mib
+ setf.sig fExp_in_signif = rTrueExp_x // Exponent as integer in fp
+ nop.i 999
+(p7) br.cond.spnt LOGB_ZERO
+}
+;;
+
+// Result can be represented in less than 24 bits, so no precision completer
+// is needed.
+{ .mfb
+ nop.m 0
+ fcvt.xf f8 = fExp_in_signif
+ br.ret.sptk b0 // Exit main path, 0 < |x| < inf
+}
+;;
+
+LOGB_DENORM:
+// Form 2^64 in case need to scale denormal
+// Check to see if double-extended denormal
+{ .mfi
+ setf.exp f2to64 = rExp_2to64
+ fclass.m p8,p0 = fNorm_x, 0x0b
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ nop.i 0
+}
+;;
+
+// If double-extended denormal add 64 to exponent bias for scaling
+// If double-extended denormal form x * 2^64 which is normal
+{ .mfi
+(p8) add rExpBias = 64, rExpBias
+(p8) fmpy.s1 fNorm_x = fNorm_x, f2to64
+ nop.i 0
+}
+;;
+
+// Logic is the same as normal path but use normalized input
+{ .mib
+ getf.exp rSignexp_x = fNorm_x
+ nop.i 0
+ br.cond.sptk LOGB_COMMON // Return to main path
+}
+;;
+
+LOGB_ZERO:
+// Here if x zero
+// f10 = -|f8|
+// f9 = 1.0/f10 = -1.0/|f8| = -inf
+
+{ .mmf
+ alloc r32=ar.pfs,1,2,4,0
+ mov GR_Parameter_TAG = 151 // Error code
+ fmerge.ns f10 = f0,f8
+}
+;;
+
+{ .mfb
+ nop.m 0
+ frcpa.s0 f9,p6 = f1,f10 // Produce -inf, Z flag
+ br.cond.sptk __libm_error_region // Call error support
+}
+;;
+
+GLOBAL_LIBM_END(logb)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfd [GR_Parameter_Y] = f0,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfd [GR_Parameter_X] = f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = f9 // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_logbf.S b/libc/sysdeps/ia64/fpu/s_logbf.S
new file mode 100644
index 000000000..eefa270db
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_logbf.S
@@ -0,0 +1,281 @@
+.file "logbf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/16/00 Modified to conform to C9X
+// 03/16/00 Improved speed
+// 04/04/00 Unwind support added
+// 05/30/00 Fixed bug when x double-extended denormal
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance
+//
+// API
+//==============================================================
+// float logbf( float x );
+//
+// Overview of operation
+//==============================================================
+// The logbf function extracts the exponent of x as an integer in
+// floating-point format.
+// logbf computes log2 of x as a float
+//
+// logbf is similar to ilogbf but differs in the following ways:
+// +-inf
+// ilogbf: returns INT_MAX
+// logbf: returns +inf
+// Nan returns FP_LOGBNAN (which is either INT_MAX or INT_MIN)
+// ilogbf: returns INT_MAX (7fffffff)
+// logbf: returns QNAN (quietized SNAN)
+// 0 returns FP_ILOGB0 (which is either INT_MIN or -INT_MAX)
+// ilogbf: returns -INT_MAX (80000001)
+// logbf: returns -inf, raises the divide-by-zero exception,
+// and calls libm_error_support to set domain error
+//
+// Registers used
+//==============================================================
+// general registers used:
+// r26 -> r38
+// r35 -> r38 used as parameters to error path
+//
+// predicate registers used:
+// p6, p7, p8
+// floating-point registers used:
+// f9, f10, f11
+// f8, input
+
+rExpBias = r26
+rExpMask = r27
+rSignexp_x = r28
+rExp_x = r29
+rTrueExp_x = r30
+rExp_2to64 = r31
+
+GR_SAVE_PFS = r32
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Parameter_TAG = r38
+
+fExp_in_signif = f9
+fNorm_x = f10
+fFloat_Exp = f10
+f2to64 = f11
+
+.section .text
+GLOBAL_LIBM_ENTRY(logbf)
+
+// X NORMAL
+// TrueExp_x = exp(f8) - 0xffff
+// sig = TrueExp_x
+// f8 = convert_to_fp (sig))
+{ .mfi
+ getf.exp rSignexp_x = f8
+ fclass.m p8,p0 = f8, 0x0b // Test for x unorm
+ mov rExpBias = 0xffff // Exponent bias
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNorm_x = f8
+ mov rExpMask = 0x1ffff // Exponent mask
+}
+;;
+
+// Form signexp of 2^64 in case need to scale denormal
+{ .mfb
+ mov rExp_2to64 = 0x1003f
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+(p8) br.cond.spnt LOGB_DENORM // Branch if x unorm
+}
+;;
+
+LOGB_COMMON:
+// Return here from LOGB_DENORM
+{ .mfi
+ and rExp_x = rSignexp_x, rExpMask // Get biased exponent
+ fclass.m p7,p0 = f8, 0x07 // Test x zero
+ nop.i 0
+}
+;;
+
+// X NAN or INFINITY, return f8 * f8
+{ .mfb
+ sub rTrueExp_x = rExp_x, rExpBias // Get true exponent
+(p6) fma.s.s0 f8= f8,f8,f0 // Result if x natval, nan, inf
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf
+}
+;;
+
+{ .mib
+ setf.sig fExp_in_signif = rTrueExp_x // Exponent as integer in fp
+ nop.i 999
+(p7) br.cond.spnt LOGB_ZERO
+}
+;;
+
+// Result can be represented in less than 24 bits, so no precision completer
+// is needed.
+{ .mfb
+ nop.m 0
+ fcvt.xf f8 = fExp_in_signif
+ br.ret.sptk b0 // Exit main path, 0 < |x| < inf
+}
+;;
+
+LOGB_DENORM:
+// Form 2^64 in case need to scale denormal
+// Check to see if double-extended denormal
+{ .mfi
+ setf.exp f2to64 = rExp_2to64
+ fclass.m p8,p0 = fNorm_x, 0x0b
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ nop.i 0
+}
+;;
+
+// If double-extended denormal add 64 to exponent bias for scaling
+// If double-extended denormal form x * 2^64 which is normal
+{ .mfi
+(p8) add rExpBias = 64, rExpBias
+(p8) fmpy.s1 fNorm_x = fNorm_x, f2to64
+ nop.i 0
+}
+;;
+
+// Logic is the same as normal path but use normalized input
+{ .mib
+ getf.exp rSignexp_x = fNorm_x
+ nop.i 0
+ br.cond.sptk LOGB_COMMON // Return to main path
+}
+;;
+
+LOGB_ZERO:
+// Here if x zero
+// f10 = -|f8|
+// f9 = 1.0/f10 = -1.0/|f8| = -inf
+
+{ .mmf
+ alloc r32=ar.pfs,1,2,4,0
+ mov GR_Parameter_TAG = 152 // Error code
+ fmerge.ns f10 = f0,f8
+}
+;;
+
+{ .mfb
+ nop.m 0
+ frcpa.s0 f9,p6 = f1,f10 // Produce -inf, Z flag
+ br.cond.sptk __libm_error_region // Call error support
+}
+;;
+
+GLOBAL_LIBM_END(logbf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfs [GR_Parameter_Y] = f0,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfs [GR_Parameter_X] = f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = f9 // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_logbl.S b/libc/sysdeps/ia64/fpu/s_logbl.S
new file mode 100644
index 000000000..e312c1b43
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_logbl.S
@@ -0,0 +1,281 @@
+.file "logbl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/16/00 Modified to conform to C9X
+// 03/16/00 Improved speed
+// 04/04/00 Unwind support added
+// 05/30/00 Fixed bug when x double-extended denormal
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance
+//
+// API
+//==============================================================
+// long double logbl( long double x );
+//
+// Overview of operation
+//==============================================================
+// The logbl function extracts the exponent of x as an integer in
+// floating-point format.
+// logbl computes log2 of x as a long double
+//
+// logbl is similar to ilogbl but differs in the following ways:
+// +-inf
+// ilogbl: returns INT_MAX
+// logbl: returns +inf
+// Nan returns FP_LOGBNAN (which is either INT_MAX or INT_MIN)
+// ilogbl: returns INT_MAX (7fffffff)
+// logbl: returns QNAN (quietized SNAN)
+// 0 returns FP_ILOGB0 (which is either INT_MIN or -INT_MAX)
+// ilogbl: returns -INT_MAX (80000001)
+// logbl: returns -inf, raises the divide-by-zero exception,
+// and calls libm_error_support to set domain error
+//
+// Registers used
+//==============================================================
+// general registers used:
+// r26 -> r38
+// r35 -> r38 used as parameters to error path
+//
+// predicate registers used:
+// p6, p7, p8
+// floating-point registers used:
+// f9, f10, f11
+// f8, input
+
+rExpBias = r26
+rExpMask = r27
+rSignexp_x = r28
+rExp_x = r29
+rTrueExp_x = r30
+rExp_2to64 = r31
+
+GR_SAVE_PFS = r32
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+
+GR_Parameter_X = r35
+GR_Parameter_Y = r36
+GR_Parameter_RESULT = r37
+GR_Parameter_TAG = r38
+
+fExp_in_signif = f9
+fNorm_x = f10
+fFloat_Exp = f10
+f2to64 = f11
+
+.section .text
+GLOBAL_LIBM_ENTRY(logbl)
+
+// X NORMAL
+// TrueExp_x = exp(f8) - 0xffff
+// sig = TrueExp_x
+// f8 = convert_to_fp (sig))
+{ .mfi
+ getf.exp rSignexp_x = f8
+ fclass.m p8,p0 = f8, 0x0b // Test for x unorm
+ mov rExpBias = 0xffff // Exponent bias
+}
+{ .mfi
+ nop.m 0
+ fnorm.s1 fNorm_x = f8
+ mov rExpMask = 0x1ffff // Exponent mask
+}
+;;
+
+// Form signexp of 2^64 in case need to scale denormal
+{ .mfb
+ mov rExp_2to64 = 0x1003f
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+(p8) br.cond.spnt LOGB_DENORM // Branch if x unorm
+}
+;;
+
+LOGB_COMMON:
+// Return here from LOGB_DENORM
+{ .mfi
+ and rExp_x = rSignexp_x, rExpMask // Get biased exponent
+ fclass.m p7,p0 = f8, 0x07 // Test x zero
+ nop.i 0
+}
+;;
+
+// X NAN or INFINITY, return f8 * f8
+{ .mfb
+ sub rTrueExp_x = rExp_x, rExpBias // Get true exponent
+(p6) fma.s0 f8= f8,f8,f0 // Result if x natval, nan, inf
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf
+}
+;;
+
+{ .mib
+ setf.sig fExp_in_signif = rTrueExp_x // Exponent as integer in fp
+ nop.i 999
+(p7) br.cond.spnt LOGB_ZERO
+}
+;;
+
+// Result can be represented in less than 24 bits, so no precision completer
+// is needed.
+{ .mfb
+ nop.m 0
+ fcvt.xf f8 = fExp_in_signif
+ br.ret.sptk b0 // Exit main path, 0 < |x| < inf
+}
+;;
+
+LOGB_DENORM:
+// Form 2^64 in case need to scale denormal
+// Check to see if double-extended denormal
+{ .mfi
+ setf.exp f2to64 = rExp_2to64
+ fclass.m p8,p0 = fNorm_x, 0x0b
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ nop.i 0
+}
+;;
+
+// If double-extended denormal add 64 to exponent bias for scaling
+// If double-extended denormal form x * 2^64 which is normal
+{ .mfi
+(p8) add rExpBias = 64, rExpBias
+(p8) fmpy.s1 fNorm_x = fNorm_x, f2to64
+ nop.i 0
+}
+;;
+
+// Logic is the same as normal path but use normalized input
+{ .mib
+ getf.exp rSignexp_x = fNorm_x
+ nop.i 0
+ br.cond.sptk LOGB_COMMON // Return to main path
+}
+;;
+
+LOGB_ZERO:
+// Here if x zero
+// f10 = -|f8|
+// f9 = 1.0/f10 = -1.0/|f8| = -inf
+
+{ .mmf
+ alloc r32=ar.pfs,1,2,4,0
+ mov GR_Parameter_TAG = 150 // Error code
+ fmerge.ns f10 = f0,f8
+}
+;;
+
+{ .mfb
+ nop.m 0
+ frcpa.s0 f9,p6 = f1,f10 // Produce -inf, Z flag
+ br.cond.sptk __libm_error_region // Call error support
+}
+;;
+
+GLOBAL_LIBM_END(logbl)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+{ .mmi
+ stfe [GR_Parameter_Y] = f0,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+{ .mib
+ stfe [GR_Parameter_X] = f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = f9 // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+
+{ .mmi
+ add GR_Parameter_RESULT = 48,sp
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/fpu/s_matherrf.c b/libc/sysdeps/ia64/fpu/s_matherrf.c
new file mode 100644
index 000000000..4b3033ecc
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_matherrf.c
@@ -0,0 +1,33 @@
+/* Derived from: */
+/*
+ * ====================================================
+ * 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"
+#include "libm_support.h"
+
+#ifdef __STDC__
+ int
+ weak_function
+ __matherrf(struct exceptionf *x)
+#else
+ int
+ weak_function
+ __matherrf(x)
+ struct exceptionf *x;
+#endif
+{
+ int n=0;
+ if(x->arg1!=x->arg1) return 0;
+ return n;
+}
+weak_alias (__matherrf, matherrf)
diff --git a/libc/sysdeps/ia64/fpu/s_matherrl.c b/libc/sysdeps/ia64/fpu/s_matherrl.c
new file mode 100644
index 000000000..751cc6b51
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_matherrl.c
@@ -0,0 +1,33 @@
+/* Derived from: */
+/*
+ * ====================================================
+ * 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"
+#include "libm_support.h"
+
+#ifdef __STDC__
+ int
+ weak_function
+ __matherrl(struct exceptionl *x)
+#else
+ int
+ weak_function
+ __matherrl(x)
+ struct exceptionl *x;
+#endif
+{
+ int n=0;
+ if(x->arg1!=x->arg1) return 0;
+ return n;
+}
+weak_alias (__matherrl, matherrl)
diff --git a/libc/sysdeps/ia64/fpu/s_modf.S b/libc/sysdeps/ia64/fpu/s_modf.S
new file mode 100644
index 000000000..2008bbfc5
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_modf.S
@@ -0,0 +1,278 @@
+.file "modf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Improved speed, corrected result for NaN input
+// 12/22/00 Fixed so inexact flag is never set, and invalid is not set for
+// qnans nor for inputs larger than 2^63.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// double modf(double x, double *iptr)
+// break a floating point x number into fraction and an exponent
+//
+// input floating point f8, address in r33
+// output floating point f8 (x fraction), and *iptr (x integral part)
+//
+// OVERVIEW
+//==============================================================
+//
+// NO FRACTIONAL PART: HUGE
+// If
+// for double-extended
+// If the true exponent is greater than or equal 63
+// 1003e ==> 1003e -ffff = 3f = 63(dec)
+// for double
+// If the true exponent is greater than or equal 52
+// 10033 -ffff = 34 = 52(dec)
+// for single
+// If the true exponent is greater than or equal 23
+// 10016 -ffff = 17 = 23(dec)
+// then
+// we are already an integer (p9 true)
+
+// NO INTEGER PART: SMALL
+// Is f8 exponent less than register bias (that is, is it
+// less than 1). If it is, get the right sign of
+// zero and store this in iptr.
+
+// CALCULATION: NOT HUGE, NOT SMALL
+// To get the integer part
+// Take the floating-point input and truncate
+// then convert this integer to fp Call it MODF_INTEGER_PART
+
+// Subtract MODF_INTEGER_PART from MODF_NORM_F8 to get fraction part
+// Then put fraction part in f8
+// put integer part MODF_INTEGER_PART into *iptr
+
+// Registers used
+//==============================================================
+
+// predicate registers used:
+// p6 - p13
+
+// 0xFFFF 0x10033
+// -----------------------+-----------------+-------------
+// SMALL | NORMAL | HUGE
+// p11 --------------->|<----- p12 ----->| <-------------- p9
+// p10 --------------------------------->|
+// p13 --------------------------------------------------->|
+//
+
+// floating-point registers used:
+MODF_NORM_F8 = f9
+MODF_FRACTION_PART = f10
+MODF_INTEGER_PART = f11
+MODF_INT_INTEGER_PART = f12
+
+
+// general registers used
+modf_signexp = r14
+modf_GR_no_frac = r15
+modf_GR_FFFF = r16
+modf_17_ones = r17
+modf_exp = r18
+// r33 = iptr
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(modf)
+
+// Main path is p9, p11, p8 FALSE and p12 TRUE
+
+// Assume input is normalized and get signexp
+// Normalize input just in case
+// Form exponent bias
+{ .mfi
+ getf.exp modf_signexp = f8
+ fnorm.s0 MODF_NORM_F8 = f8
+ addl modf_GR_FFFF = 0xffff, r0
+}
+// Get integer part of input
+// Form exponent mask
+{ .mfi
+ nop.m 999
+ fcvt.fx.trunc.s1 MODF_INT_INTEGER_PART = f8
+ mov modf_17_ones = 0x1ffff ;;
+}
+
+// Is x nan or inf?
+// qnan snan inf norm unorm 0 -+
+// 1 1 1 0 0 0 11 = 0xe3 NAN_INF
+// Form biased exponent where input only has an integer part
+{ .mfi
+ nop.m 999
+ fclass.m.unc p6,p13 = f8, 0xe3
+ addl modf_GR_no_frac = 0x10033, r0 ;;
+}
+
+// Mask to get exponent
+// Is x unnorm?
+// qnan snan inf norm unorm 0 -+
+// 0 0 0 0 1 0 11 = 0x0b UNORM
+// Set p13 to indicate calculation path, else p6 if nan or inf
+{ .mfi
+ and modf_exp = modf_17_ones, modf_signexp
+ fclass.m.unc p8,p0 = f8, 0x0b
+ nop.i 999 ;;
+}
+
+// p11 <== SMALL, no integer part, fraction is everyting
+// p9 <== HUGE, no fraction part, integer is everything
+// p12 <== NORMAL, fraction part and integer part
+{ .mii
+(p13) cmp.lt.unc p11,p10 = modf_exp, modf_GR_FFFF
+ nop.i 999
+ nop.i 999 ;;
+}
+
+// Is x inf? p6 if inf, p7 if nan
+{ .mfb
+(p10) cmp.ge.unc p9,p12 = modf_exp, modf_GR_no_frac
+(p6) fclass.m.unc p6,p7 = f8, 0x23
+(p8) br.cond.spnt MODF_DENORM ;;
+}
+
+MODF_COMMON:
+// For HUGE set fraction to signed 0
+{ .mfi
+ nop.m 999
+(p9) fmerge.s f8 = f8,f0
+ nop.i 999
+}
+// For HUGE set integer part to normalized input
+{ .mfi
+ nop.m 999
+(p9) fnorm.d.s0 MODF_INTEGER_PART = MODF_NORM_F8
+ nop.i 999 ;;
+}
+
+// For SMALL set fraction to normalized input, integer part to signed 0
+{ .mfi
+ nop.m 999
+(p11) fmerge.s MODF_INTEGER_PART = f8,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fnorm.d.s0 f8 = MODF_NORM_F8
+ nop.i 999 ;;
+}
+
+// For NORMAL float the integer part
+{ .mfi
+ nop.m 999
+(p12) fcvt.xf MODF_INTEGER_PART = MODF_INT_INTEGER_PART
+ nop.i 999 ;;
+}
+
+// If x inf set integer part to INF, fraction to signed 0
+{ .mfi
+(p6) stfd [r33] = MODF_NORM_F8
+(p6) fmerge.s f8 = f8,f0
+ nop.i 999 ;;
+}
+
+// If x nan set integer and fraction parts to NaN (quietized)
+{ .mfi
+(p7) stfd [r33] = MODF_NORM_F8
+(p7) fmerge.s f8 = MODF_NORM_F8, MODF_NORM_F8
+ nop.i 999 ;;
+}
+
+{ .mmi
+(p9) stfd [r33] = MODF_INTEGER_PART
+ nop.m 999
+ nop.i 999 ;;
+}
+
+// For NORMAL compute fraction part
+{ .mfi
+(p11) stfd [r33] = MODF_INTEGER_PART
+(p12) fms.d.s0 f8 = MODF_NORM_F8,f1, MODF_INTEGER_PART
+ nop.i 999 ;;
+}
+
+// For NORMAL test if fraction part is zero; if so append correct sign
+{ .mfi
+ nop.m 999
+(p12) fcmp.eq.unc.s0 p7,p0 = MODF_NORM_F8, MODF_INTEGER_PART
+ nop.i 999 ;;
+}
+
+{ .mfi
+(p12) stfd [r33] = MODF_INTEGER_PART
+ nop.f 999
+ nop.i 999 ;;
+}
+
+// For NORMAL if fraction part is zero append sign of input
+{ .mfb
+ nop.m 999
+(p7) fmerge.s f8 = MODF_NORM_F8, f0
+ br.ret.sptk b0 ;;
+}
+
+MODF_DENORM:
+// If x unorm get signexp from normalized input
+// If x unorm get integer part from normalized input
+{ .mfi
+ getf.exp modf_signexp = MODF_NORM_F8
+ fcvt.fx.trunc.s1 MODF_INT_INTEGER_PART = MODF_NORM_F8
+ nop.i 999 ;;
+}
+
+// If x unorm mask to get exponent
+{ .mmi
+ and modf_exp = modf_17_ones, modf_signexp ;;
+ cmp.lt.unc p11,p10 = modf_exp, modf_GR_FFFF
+ nop.i 999 ;;
+}
+
+{ .mfb
+(p10) cmp.ge.unc p9,p12 = modf_exp, modf_GR_no_frac
+ nop.f 999
+ br.cond.spnt MODF_COMMON ;;
+}
+
+GLOBAL_LIBM_END(modf)
diff --git a/libc/sysdeps/ia64/fpu/s_modff.S b/libc/sysdeps/ia64/fpu/s_modff.S
new file mode 100644
index 000000000..edc112097
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_modff.S
@@ -0,0 +1,278 @@
+.file "modff.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Improved speed, corrected result for NaN input
+// 12/22/00 Fixed so inexact flag is never set, and invalid is not set for
+// qnans nor for inputs larger than 2^63.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// float modff(float x, float *iptr)
+// break a floating point x number into fraction and an exponent
+//
+// input floating point f8, address in r33
+// output floating point f8 (x fraction), and *iptr (x integral part)
+//
+// OVERVIEW
+//==============================================================
+
+// NO FRACTIONAL PART: HUGE
+// If
+// for double-extended
+// If the true exponent is greater than or equal 63
+// 1003e ==> 1003e -ffff = 3f = 63(dec)
+// for double
+// If the true exponent is greater than or equal 52
+// 10033 -ffff = 34 = 52(dec)
+// for single
+// If the true exponent is greater than or equal 23
+// 10016 -ffff = 17 = 23(dec)
+// then
+// we are already an integer (p9 true)
+
+// NO INTEGER PART: SMALL
+// Is f8 exponent less than register bias (that is, is it
+// less than 1). If it is, get the right sign of
+// zero and store this in iptr.
+
+// CALCULATION: NOT HUGE, NOT SMALL
+// To get the integer part
+// Take the floating-point input and truncate
+// then convert this integer to fp Call it MODF_INTEGER_PART
+
+// Subtract MODF_INTEGER_PART from MODF_NORM_F8 to get fraction part
+// Then put fraction part in f8
+// put integer part MODF_INTEGER_PART into *iptr
+
+// Registers used
+//==============================================================
+
+// predicate registers used:
+// p6 - p13
+
+// 0xFFFF 0x10016
+// -----------------------+-----------------+-------------
+// SMALL | NORMAL | HUGE
+// p11 --------------->|<----- p12 ----->| <-------------- p9
+// p10 --------------------------------->|
+// p13 --------------------------------------------------->|
+//
+
+// floating-point registers used:
+MODF_NORM_F8 = f9
+MODF_FRACTION_PART = f10
+MODF_INTEGER_PART = f11
+MODF_INT_INTEGER_PART = f12
+
+
+// general registers used
+modf_signexp = r14
+modf_GR_no_frac = r15
+modf_GR_FFFF = r16
+modf_17_ones = r17
+modf_exp = r18
+// r33 = iptr
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(modff)
+
+// Main path is p9, p11, p8 FALSE and p12 TRUE
+
+// Assume input is normalized and get signexp
+// Normalize input just in case
+// Form exponent bias
+{ .mfi
+ getf.exp modf_signexp = f8
+ fnorm.s0 MODF_NORM_F8 = f8
+ addl modf_GR_FFFF = 0xffff, r0
+}
+// Get integer part of input
+// Form exponent mask
+{ .mfi
+ nop.m 999
+ fcvt.fx.trunc.s1 MODF_INT_INTEGER_PART = f8
+ mov modf_17_ones = 0x1ffff ;;
+}
+
+// Is x nan or inf?
+// qnan snan inf norm unorm 0 -+
+// 1 1 1 0 0 0 11 = 0xe3 NAN_INF
+// Form biased exponent where input only has an integer part
+{ .mfi
+ nop.m 999
+ fclass.m.unc p6,p13 = f8, 0xe3
+ addl modf_GR_no_frac = 0x10016, r0 ;;
+}
+
+// Mask to get exponent
+// Is x unnorm?
+// qnan snan inf norm unorm 0 -+
+// 0 0 0 0 1 0 11 = 0x0b UNORM
+// Set p13 to indicate calculation path, else p6 if nan or inf
+{ .mfi
+ and modf_exp = modf_17_ones, modf_signexp
+ fclass.m.unc p8,p0 = f8, 0x0b
+ nop.i 999 ;;
+}
+
+// p11 <== SMALL, no integer part, fraction is everyting
+// p9 <== HUGE, no fraction part, integer is everything
+// p12 <== NORMAL, fraction part and integer part
+{ .mii
+(p13) cmp.lt.unc p11,p10 = modf_exp, modf_GR_FFFF
+ nop.i 999
+ nop.i 999 ;;
+}
+
+// Is x inf? p6 if inf, p7 if nan
+{ .mfb
+(p10) cmp.ge.unc p9,p12 = modf_exp, modf_GR_no_frac
+(p6) fclass.m.unc p6,p7 = f8, 0x23
+(p8) br.cond.spnt MODF_DENORM ;;
+}
+
+MODF_COMMON:
+// For HUGE set fraction to signed 0
+{ .mfi
+ nop.m 999
+(p9) fmerge.s f8 = f8,f0
+ nop.i 999
+}
+// For HUGE set integer part to normalized input
+{ .mfi
+ nop.m 999
+(p9) fnorm.s.s0 MODF_INTEGER_PART = MODF_NORM_F8
+ nop.i 999 ;;
+}
+
+// For SMALL set fraction to normalized input, integer part to signed 0
+{ .mfi
+ nop.m 999
+(p11) fmerge.s MODF_INTEGER_PART = f8,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fnorm.s.s0 f8 = MODF_NORM_F8
+ nop.i 999 ;;
+}
+
+// For NORMAL float the integer part
+{ .mfi
+ nop.m 999
+(p12) fcvt.xf MODF_INTEGER_PART = MODF_INT_INTEGER_PART
+ nop.i 999 ;;
+}
+
+// If x inf set integer part to INF, fraction to signed 0
+{ .mfi
+(p6) stfs [r33] = MODF_NORM_F8
+(p6) fmerge.s f8 = f8,f0
+ nop.i 999 ;;
+}
+
+// If x nan set integer and fraction parts to NaN (quietized)
+{ .mfi
+(p7) stfs [r33] = MODF_NORM_F8
+(p7) fmerge.s f8 = MODF_NORM_F8, MODF_NORM_F8
+ nop.i 999 ;;
+}
+
+{ .mmi
+(p9) stfs [r33] = MODF_INTEGER_PART
+ nop.m 999
+ nop.i 999 ;;
+}
+
+// For NORMAL compute fraction part
+{ .mfi
+(p11) stfs [r33] = MODF_INTEGER_PART
+(p12) fms.s.s0 f8 = MODF_NORM_F8,f1, MODF_INTEGER_PART
+ nop.i 999 ;;
+}
+
+// For NORMAL test if fraction part is zero; if so append correct sign
+{ .mfi
+ nop.m 999
+(p12) fcmp.eq.unc.s0 p7,p0 = MODF_NORM_F8, MODF_INTEGER_PART
+ nop.i 999 ;;
+}
+
+{ .mfi
+(p12) stfs [r33] = MODF_INTEGER_PART
+ nop.f 999
+ nop.i 999 ;;
+}
+
+// For NORMAL if fraction part is zero append sign of input
+{ .mfb
+ nop.m 999
+(p7) fmerge.s f8 = MODF_NORM_F8, f0
+ br.ret.sptk b0 ;;
+}
+
+MODF_DENORM:
+// If x unorm get signexp from normalized input
+// If x unorm get integer part from normalized input
+{ .mfi
+ getf.exp modf_signexp = MODF_NORM_F8
+ fcvt.fx.trunc.s1 MODF_INT_INTEGER_PART = MODF_NORM_F8
+ nop.i 999 ;;
+}
+
+// If x unorm mask to get exponent
+{ .mmi
+ and modf_exp = modf_17_ones, modf_signexp ;;
+ cmp.lt.unc p11,p10 = modf_exp, modf_GR_FFFF
+ nop.i 999 ;;
+}
+
+{ .mfb
+(p10) cmp.ge.unc p9,p12 = modf_exp, modf_GR_no_frac
+ nop.f 999
+ br.cond.spnt MODF_COMMON ;;
+}
+
+GLOBAL_LIBM_END(modff)
diff --git a/libc/sysdeps/ia64/fpu/s_modfl.S b/libc/sysdeps/ia64/fpu/s_modfl.S
new file mode 100644
index 000000000..eaf410cb6
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_modfl.S
@@ -0,0 +1,273 @@
+.file "modfl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Improved speed, corrected result for NaN input
+// 05/30/00 Fixed bug for exponent 0x1003e
+// 12/22/00 Fixed so inexact flag is never set, and invalid is not set for
+// qnans nor for inputs larger than 2^63.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// long double modfl(long double x, long double *iptr)
+// break a floating point x number into fraction and an exponent
+//
+// input floating point f8, address in r34
+// output floating point f8 (x fraction), and *iptr (x integral part)
+//
+// OVERVIEW
+//==============================================================
+//
+// NO FRACTIONAL PART: HUGE
+// If
+// for double-extended
+// If the true exponent is >= 63
+// 1003e ==> 1003e -ffff = 3f = 63(dec)
+// then
+// we are already an integer (p9 true)
+
+// NO INTEGER PART: SMALL
+// Is f8 exponent less than register bias (that is, is it
+// less than 1). If it is, get the right sign of
+// zero and store this in iptr.
+
+// CALCULATION: NOT HUGE, NOT SMALL
+// To get the integer part
+// Take the floating-point input and truncate
+// then convert this integer to fp Call it MODF_INTEGER_PART
+
+// Subtract MODF_INTEGER_PART from MODF_NORM_F8 to get fraction part
+// Then put fraction part in f8
+// put integer part MODF_INTEGER_PART into *iptr
+
+// Registers used
+//==============================================================
+
+// predicate registers used:
+// p6 - p13
+
+// 0xFFFF 0x1003e
+// -----------------------+-----------------+-------------
+// SMALL | NORMAL | HUGE
+// p11 --------------->|<----- p12 ----->| <-------------- p9
+// p10 --------------------------------->|
+// p13 --------------------------------------------------->|
+//
+
+// floating-point registers used:
+MODF_NORM_F8 = f9
+MODF_FRACTION_PART = f10
+MODF_INTEGER_PART = f11
+MODF_INT_INTEGER_PART = f12
+
+
+// general registers used
+modf_signexp = r14
+modf_GR_no_frac = r15
+modf_GR_FFFF = r16
+modf_17_ones = r17
+modf_exp = r18
+// r34 = iptr
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(modfl)
+
+// Main path is p9, p11, p8 FALSE and p12 TRUE
+
+// Assume input is normalized and get signexp
+// Normalize input just in case
+// Form exponent bias
+{ .mfi
+ getf.exp modf_signexp = f8
+ fnorm.s0 MODF_NORM_F8 = f8
+ addl modf_GR_FFFF = 0xffff, r0
+}
+// Get integer part of input
+// Form exponent mask
+{ .mfi
+ nop.m 999
+ fcvt.fx.trunc.s1 MODF_INT_INTEGER_PART = f8
+ mov modf_17_ones = 0x1ffff ;;
+}
+
+// Is x nan or inf?
+// qnan snan inf norm unorm 0 -+
+// 1 1 1 0 0 0 11 = 0xe3 NAN_INF
+// Form biased exponent where input only has an integer part
+{ .mfi
+ nop.m 999
+ fclass.m.unc p6,p13 = f8, 0xe3
+ addl modf_GR_no_frac = 0x1003e, r0 ;;
+}
+
+// Mask to get exponent
+// Is x unnorm?
+// qnan snan inf norm unorm 0 -+
+// 0 0 0 0 1 0 11 = 0x0b UNORM
+// Set p13 to indicate calculation path, else p6 if nan or inf
+{ .mfi
+ and modf_exp = modf_17_ones, modf_signexp
+ fclass.m.unc p8,p0 = f8, 0x0b
+ nop.i 999 ;;
+}
+
+// p11 <== SMALL, no integer part, fraction is everyting
+// p9 <== HUGE, no fraction part, integer is everything
+// p12 <== NORMAL, fraction part and integer part
+{ .mii
+(p13) cmp.lt.unc p11,p10 = modf_exp, modf_GR_FFFF
+ nop.i 999
+ nop.i 999 ;;
+}
+
+// Is x inf? p6 if inf, p7 if nan
+{ .mfb
+(p10) cmp.ge.unc p9,p12 = modf_exp, modf_GR_no_frac
+(p6) fclass.m.unc p6,p7 = f8, 0x23
+(p8) br.cond.spnt MODF_DENORM ;;
+}
+
+MODF_COMMON:
+// For HUGE set fraction to signed 0
+{ .mfi
+ nop.m 999
+(p9) fmerge.s f8 = f8,f0
+ nop.i 999
+}
+// For HUGE set integer part to normalized input
+{ .mfi
+ nop.m 999
+(p9) fnorm.s0 MODF_INTEGER_PART = MODF_NORM_F8
+ nop.i 999 ;;
+}
+
+// For SMALL set fraction to normalized input, integer part to signed 0
+{ .mfi
+ nop.m 999
+(p11) fmerge.s MODF_INTEGER_PART = f8,f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fnorm.s0 f8 = MODF_NORM_F8
+ nop.i 999 ;;
+}
+
+// For NORMAL float the integer part
+{ .mfi
+ nop.m 999
+(p12) fcvt.xf MODF_INTEGER_PART = MODF_INT_INTEGER_PART
+ nop.i 999 ;;
+}
+
+// If x inf set integer part to INF, fraction to signed 0
+{ .mfi
+(p6) stfe [r34] = MODF_NORM_F8
+(p6) fmerge.s f8 = f8,f0
+ nop.i 999 ;;
+}
+
+// If x nan set integer and fraction parts to NaN (quietized)
+{ .mfi
+(p7) stfe [r34] = MODF_NORM_F8
+(p7) fmerge.s f8 = MODF_NORM_F8, MODF_NORM_F8
+ nop.i 999 ;;
+}
+
+{ .mmi
+(p9) stfe [r34] = MODF_INTEGER_PART
+ nop.m 999
+ nop.i 999 ;;
+}
+
+// For NORMAL compute fraction part
+{ .mfi
+(p11) stfe [r34] = MODF_INTEGER_PART
+(p12) fms.s0 f8 = MODF_NORM_F8,f1, MODF_INTEGER_PART
+ nop.i 999 ;;
+}
+
+// For NORMAL test if fraction part is zero; if so append correct sign
+{ .mfi
+ nop.m 999
+(p12) fcmp.eq.unc.s0 p7,p0 = MODF_NORM_F8, MODF_INTEGER_PART
+ nop.i 999 ;;
+}
+
+{ .mfi
+(p12) stfe [r34] = MODF_INTEGER_PART
+ nop.f 999
+ nop.i 999 ;;
+}
+
+// For NORMAL if fraction part is zero append sign of input
+{ .mfb
+ nop.m 999
+(p7) fmerge.s f8 = MODF_NORM_F8, f0
+ br.ret.sptk b0 ;;
+}
+
+MODF_DENORM:
+// If x unorm get signexp from normalized input
+// If x unorm get integer part from normalized input
+{ .mfi
+ getf.exp modf_signexp = MODF_NORM_F8
+ fcvt.fx.trunc.s1 MODF_INT_INTEGER_PART = MODF_NORM_F8
+ nop.i 999 ;;
+}
+
+// If x unorm mask to get exponent
+{ .mmi
+ and modf_exp = modf_17_ones, modf_signexp ;;
+ cmp.lt.unc p11,p10 = modf_exp, modf_GR_FFFF
+ nop.i 999 ;;
+}
+
+{ .mfb
+(p10) cmp.ge.unc p9,p12 = modf_exp, modf_GR_no_frac
+ nop.f 999
+ br.cond.spnt MODF_COMMON ;;
+}
+
+GLOBAL_LIBM_END(modfl)
diff --git a/libc/sysdeps/ia64/fpu/s_nearbyint.S b/libc/sysdeps/ia64/fpu/s_nearbyint.S
new file mode 100644
index 000000000..ec1ff22db
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_nearbyint.S
@@ -0,0 +1,217 @@
+.file "nearbyint.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 10/19/00 Created
+// 02/08/01 Corrected behavior for all rounding modes.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 07/25/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// double nearbyint(double x)
+//==============================================================
+
+// general input registers:
+// r14 - r21
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rFpsr = r19
+rRcs0 = r20
+rRcs0Mask = r21
+
+// floating-point registers:
+// f8 - f10
+
+fXInt = f9
+fNormX = f10
+
+// predicate registers used:
+// p6 - p10
+
+// Overview of operation
+//==============================================================
+// double nearbyint(double x)
+// Return an integer value (represented as a double) that is x
+// rounded to integer in current rounding mode
+// Inexact is not set, otherwise result identical with rint.
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+.section .text
+GLOBAL_LIBM_ENTRY(nearbyint)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ addl rBigexp = 0x10033, r0 // Set exponent at which is integer
+}
+{ .mfi
+ nop.m 0
+ fcvt.fx.s1 fXInt = f8 // Convert to int in significand
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ mov rFpsr = ar40 // Read fpsr -- check rc.s0
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fnorm.s1 fNormX = f8 // Normalize input
+(p7) br.cond.spnt RINT_UNORM // Branch if x unorm
+}
+;;
+
+
+RINT_COMMON:
+// Return here from RINT_UNORM
+{ .mfb
+ and rExp = rSignexp, rExpMask // Get biased exponent
+(p6) fma.d.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ mov rRcs0Mask = 0x0c00 // Mask for rc.s0
+ fcvt.xf f8 = fXInt // Result assume |x| < 2^52
+ cmp.ge p7,p8 = rExp, rBigexp // Is |x| >= 2^52?
+}
+;;
+
+// We must correct result if |x| >= 2^52
+{ .mfi
+ nop.m 0
+(p7) fma.d.s0 f8 = fNormX, f1, f0 // If |x| >= 2^52, result x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p8) fmerge.s f8 = fNormX, f8 // Make sign nearbyint(x) = sign x
+ nop.i 0
+}
+;;
+
+{ .mfi
+(p8) and rRcs0 = rFpsr, rRcs0Mask // Get rounding mode for sf0
+ nop.f 0
+ nop.i 0
+}
+;;
+
+// If |x| < 2^52 we must test for other rounding modes
+{ .mbb
+(p8) cmp.ne.unc p10,p0 = rRcs0, r0 // Test for other rounding modes
+(p10) br.cond.spnt RINT_NOT_ROUND_NEAREST // Branch if not round nearest
+ br.ret.sptk b0 // Exit main path if round nearest
+}
+;;
+
+
+RINT_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk RINT_COMMON // Return to main path
+}
+;;
+
+RINT_NOT_ROUND_NEAREST:
+// Here if not round to nearest, and |x| < 2^52
+// Set rounding mode of s2 to that of s0, and repeat the conversion using s2
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7f, 0x40
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.fx.s2 fXInt = fNormX // Convert to int in significand
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf f8 = fXInt // Expected result
+ nop.i 0
+}
+;;
+
+// Be sure sign of result = sign of input. Fixes cases where result is 0.
+{ .mfb
+ nop.m 0
+ fmerge.s f8 = fNormX, f8
+ br.ret.sptk b0 // Exit main path
+}
+;;
+
+GLOBAL_LIBM_END(nearbyint)
diff --git a/libc/sysdeps/ia64/fpu/s_nearbyintf.S b/libc/sysdeps/ia64/fpu/s_nearbyintf.S
new file mode 100644
index 000000000..aac7b5c12
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_nearbyintf.S
@@ -0,0 +1,217 @@
+.file "nearbyintf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 10/19/00 Created
+// 02/08/01 Corrected behavior for all rounding modes.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 07/25/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// float nearbyintf(float x)
+//==============================================================
+
+// general input registers:
+// r14 - r21
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rFpsr = r19
+rRcs0 = r20
+rRcs0Mask = r21
+
+// floating-point registers:
+// f8 - f10
+
+fXInt = f9
+fNormX = f10
+
+// predicate registers used:
+// p6 - p10
+
+// Overview of operation
+//==============================================================
+// float nearbyintf(float x)
+// Return an integer value (represented as a float) that is x
+// rounded to integer in current rounding mode
+// Inexact is not set, otherwise result identical with rint.
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+.section .text
+GLOBAL_LIBM_ENTRY(nearbyintf)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ addl rBigexp = 0x10016, r0 // Set exponent at which is integer
+}
+{ .mfi
+ nop.m 0
+ fcvt.fx.s1 fXInt = f8 // Convert to int in significand
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ mov rFpsr = ar40 // Read fpsr -- check rc.s0
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fnorm.s1 fNormX = f8 // Normalize input
+(p7) br.cond.spnt RINT_UNORM // Branch if x unorm
+}
+;;
+
+
+RINT_COMMON:
+// Return here from RINT_UNORM
+{ .mfb
+ and rExp = rSignexp, rExpMask // Get biased exponent
+(p6) fma.s.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ mov rRcs0Mask = 0x0c00 // Mask for rc.s0
+ fcvt.xf f8 = fXInt // Result assume |x| < 2^23
+ cmp.ge p7,p8 = rExp, rBigexp // Is |x| >= 2^23?
+}
+;;
+
+// We must correct result if |x| >= 2^23
+{ .mfi
+ nop.m 0
+(p7) fma.s.s0 f8 = fNormX, f1, f0 // If |x| >= 2^23, result x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p8) fmerge.s f8 = fNormX, f8 // Make sign nearbyintf(x)= sign x
+ nop.i 0
+}
+;;
+
+{ .mfi
+(p8) and rRcs0 = rFpsr, rRcs0Mask // Get rounding mode for sf0
+ nop.f 0
+ nop.i 0
+}
+;;
+
+// If |x| < 2^23 we must test for other rounding modes
+{ .mbb
+(p8) cmp.ne.unc p10,p0 = rRcs0, r0 // Test for other rounding modes
+(p10) br.cond.spnt RINT_NOT_ROUND_NEAREST // Branch if not round nearest
+ br.ret.sptk b0 // Exit main path if round nearest
+}
+;;
+
+
+RINT_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk RINT_COMMON // Return to main path
+}
+;;
+
+RINT_NOT_ROUND_NEAREST:
+// Here if not round to nearest, and |x| < 2^23
+// Set rounding mode of s2 to that of s0, and repeat the conversion using s2
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7f, 0x40
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.fx.s2 fXInt = fNormX // Convert to int in significand
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf f8 = fXInt // Expected result
+ nop.i 0
+}
+;;
+
+// Be sure sign of result = sign of input. Fixes cases where result is 0.
+{ .mfb
+ nop.m 0
+ fmerge.s f8 = fNormX, f8
+ br.ret.sptk b0 // Exit main path
+}
+;;
+
+GLOBAL_LIBM_END(nearbyintf)
diff --git a/libc/sysdeps/ia64/fpu/s_nearbyintl.S b/libc/sysdeps/ia64/fpu/s_nearbyintl.S
new file mode 100644
index 000000000..ee6159c67
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_nearbyintl.S
@@ -0,0 +1,217 @@
+.file "nearbyintl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 10/19/00 Created
+// 02/08/01 Corrected behavior for all rounding modes.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 07/25/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// long double nearbyintl(long double x)
+//==============================================================
+
+// general input registers:
+// r14 - r21
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rFpsr = r19
+rRcs0 = r20
+rRcs0Mask = r21
+
+// floating-point registers:
+// f8 - f10
+
+fXInt = f9
+fNormX = f10
+
+// predicate registers used:
+// p6 - p10
+
+// Overview of operation
+//==============================================================
+// long double nearbyintl(long double x)
+// Return an integer value (represented as a long double) that is x
+// rounded to integer in current rounding mode
+// Inexact is not set, otherwise result identical with rint.
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+.section .text
+GLOBAL_LIBM_ENTRY(nearbyintl)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ addl rBigexp = 0x1003e, r0 // Set exponent at which is integer
+}
+{ .mfi
+ nop.m 0
+ fcvt.fx.s1 fXInt = f8 // Convert to int in significand
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ mov rFpsr = ar40 // Read fpsr -- check rc.s0
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fnorm.s1 fNormX = f8 // Normalize input
+(p7) br.cond.spnt RINT_UNORM // Branch if x unorm
+}
+;;
+
+
+RINT_COMMON:
+// Return here from RINT_UNORM
+{ .mfb
+ and rExp = rSignexp, rExpMask // Get biased exponent
+(p6) fma.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ mov rRcs0Mask = 0x0c00 // Mask for rc.s0
+ fcvt.xf f8 = fXInt // Result assume |x| < 2^63
+ cmp.ge p7,p8 = rExp, rBigexp // Is |x| >= 2^63?
+}
+;;
+
+// We must correct result if |x| >= 2^63
+{ .mfi
+ nop.m 0
+(p7) fma.s0 f8 = fNormX, f1, f0 // If |x| >= 2^63, result x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p8) fmerge.s f8 = fNormX, f8 // Make sign nearbyintl(x)= sign x
+ nop.i 0
+}
+;;
+
+{ .mfi
+(p8) and rRcs0 = rFpsr, rRcs0Mask // Get rounding mode for sf0
+ nop.f 0
+ nop.i 0
+}
+;;
+
+// If |x| < 2^63 we must test for other rounding modes
+{ .mbb
+(p8) cmp.ne.unc p10,p0 = rRcs0, r0 // Test for other rounding modes
+(p10) br.cond.spnt RINT_NOT_ROUND_NEAREST // Branch if not round nearest
+ br.ret.sptk b0 // Exit main path if round nearest
+}
+;;
+
+
+RINT_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk RINT_COMMON // Return to main path
+}
+;;
+
+RINT_NOT_ROUND_NEAREST:
+// Here if not round to nearest, and |x| < 2^63
+// Set rounding mode of s2 to that of s0, and repeat the conversion using s2
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7f, 0x40
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.fx.s2 fXInt = fNormX // Convert to int in significand
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf f8 = fXInt // Expected result
+ nop.i 0
+}
+;;
+
+// Be sure sign of result = sign of input. Fixes cases where result is 0.
+{ .mfb
+ nop.m 0
+ fmerge.s f8 = fNormX, f8
+ br.ret.sptk b0 // Exit main path
+}
+;;
+
+GLOBAL_LIBM_END(nearbyintl)
diff --git a/libc/sysdeps/ia64/fpu/s_nextafter.S b/libc/sysdeps/ia64/fpu/s_nextafter.S
new file mode 100644
index 000000000..6635a31df
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_nextafter.S
@@ -0,0 +1,498 @@
+.file "nextafter.s"
+
+
+// Copyright (c) 2000 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 03/03/00 Modified to conform to C9X, and improve speed of main path
+// 03/14/00 Fixed case where x is a power of 2, and x > y, improved speed
+// 04/04/00 Unwind support added
+// 05/12/00 Fixed erroneous denormal flag setting for exponent change cases 1,3
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 09/09/00 Updated fcmp so that qnans do not raise invalid
+// 12/15/00 Corrected behavior when both args are zero to conform to C99, and
+// fixed flag settings for several cases
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 12/14/04 Added error handling on underflow.
+//
+// API
+//==============================================================
+// double nextafter( double x, double y );
+// input floating point f8, f9
+// output floating point f8
+//
+// Registers used
+//==============================================================
+GR_max_pexp = r14
+GR_min_pexp = r15
+GR_exp = r16
+GR_sig = r17
+GR_lnorm_sig = r18
+GR_sign_mask = r19
+GR_exp_mask = r20
+GR_sden_sig = r21
+GR_new_sig = r22
+GR_new_exp = r23
+GR_lden_sig = r24
+GR_snorm_sig = r25
+GR_exp1 = r26
+GR_x_exp = r27
+GR_min_den_rexp = r28
+// r36-39 parameters for libm_error_support
+
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+GR_SAVE_PFS = r32
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+FR_lnorm_sig = f10
+FR_lnorm_exp = f11
+FR_lnorm = f12
+FR_sden_sig = f13
+FR_sden_exp = f14
+FR_sden = f15
+FR_save_f8 = f33
+FR_new_exp = f34
+FR_new_sig = f35
+FR_lden_sig = f36
+FR_snorm_sig = f37
+FR_exp1 = f38
+FR_tmp = f39
+
+//
+// Overview of operation
+//==============================================================
+// nextafter determines the next representable value
+// after x in the direction of y.
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(nextafter)
+
+// Extract signexp from x
+// Is x < y ? p10 if yes, p11 if no
+// Form smallest denormal significand = ulp size
+{ .mfi
+ getf.exp GR_exp = f8
+ fcmp.lt.s1 p10,p11 = f8, f9
+ addl GR_sden_sig = 0x800, r0
+}
+// Form largest normal significand 0xfffffffffffff800
+// Form smallest normal exponent
+{ .mfi
+ addl GR_lnorm_sig = -0x800,r0
+ nop.f 999
+ addl GR_min_pexp = 0x0fc01, r0 ;;
+}
+// Extract significand from x
+// Is x=y?
+// Form largest normal exponent
+{ .mfi
+ getf.sig GR_sig = f8
+ fcmp.eq.s0 p6,p0 = f8, f9
+ addl GR_max_pexp = 0x103fe, r0
+}
+// Move largest normal significand to fp reg for special cases
+{ .mfi
+ setf.sig FR_lnorm_sig = GR_lnorm_sig
+ nop.f 999
+ addl GR_sign_mask = 0x20000, r0 ;;
+}
+
+// Move smallest denormal significand and signexp to fp regs
+// Is x=nan?
+// Set p12 and p13 based on whether significand increases or decreases
+// It increases (p12 set) if x<y and x>=0 or if x>y and x<0
+// It decreases (p13 set) if x<y and x<0 or if x>y and x>=0
+{ .mfi
+ setf.sig FR_sden_sig = GR_sden_sig
+ fclass.m p8,p0 = f8, 0xc3
+(p10) cmp.lt p12,p13 = GR_exp, GR_sign_mask
+}
+{ .mfi
+ setf.exp FR_sden_exp = GR_min_pexp
+(p11) cmp.ge p12,p13 = GR_exp, GR_sign_mask ;;
+}
+
+.pred.rel "mutex",p12,p13
+
+// Form expected new significand, adding or subtracting 1 ulp increment
+// If x=y set result to y
+// Form smallest normal significand and largest denormal significand
+{ .mfi
+(p12) add GR_new_sig = GR_sig, GR_sden_sig
+(p6) fmerge.s f8=f9,f9
+ dep.z GR_snorm_sig = 1,63,1 // 0x8000000000000000
+}
+{ .mlx
+(p13) sub GR_new_sig = GR_sig, GR_sden_sig
+ movl GR_lden_sig = 0x7ffffffffffff800 ;;
+}
+
+// Move expected result significand and signexp to fp regs
+// Is y=nan?
+// Form new exponent in case result exponent needs incrementing or decrementing
+{ .mfi
+ setf.exp FR_new_exp = GR_exp
+ fclass.m p9,p0 = f9, 0xc3
+(p12) add GR_exp1 = 1, GR_exp
+}
+{ .mib
+ setf.sig FR_new_sig = GR_new_sig
+(p13) add GR_exp1 = -1, GR_exp
+(p6) br.ret.spnt b0 ;; // Exit if x=y
+}
+
+// Move largest normal signexp to fp reg for special cases
+// Is x=zero?
+{ .mfi
+ setf.exp FR_lnorm_exp = GR_max_pexp
+ fclass.m p7,p0 = f8, 0x7
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p8) fma.s0 f8 = f8,f1,f9
+(p8) br.ret.spnt b0 ;; // Exit if x=nan
+}
+
+// Move exp+-1 and smallest normal significand to fp regs for special cases
+// Is x=inf?
+{ .mfi
+ setf.exp FR_exp1 = GR_exp1
+ fclass.m p6,p0 = f8, 0x23
+ addl GR_exp_mask = 0x1ffff, r0
+}
+{ .mfb
+ setf.sig FR_snorm_sig = GR_snorm_sig
+(p9) fma.s0 f8 = f8,f1,f9
+(p9) br.ret.spnt b0 ;; // Exit if y=nan
+}
+
+// Move largest denormal significand to fp regs for special cases
+// Save x
+{ .mfb
+ setf.sig FR_lden_sig = GR_lden_sig
+ mov FR_save_f8 = f8
+(p7) br.cond.spnt NEXT_ZERO ;; // Exit if x=0
+}
+
+// Mask off the sign to get x_exp
+{ .mfb
+ and GR_x_exp = GR_exp_mask, GR_exp
+ nop.f 999
+(p6) br.cond.spnt NEXT_INF ;; // Exit if x=inf
+}
+
+// Check 6 special cases when significand rolls over:
+// 1 sig size incr, x_sig=max_sig, x_exp < max_exp
+// Set p6, result is sig=min_sig, exp++
+// 2 sig size incr, x_sig=max_sig, x_exp >= max_exp
+// Set p7, result is inf, signal overflow
+// 3 sig size decr, x_sig=min_sig, x_exp > min_exp
+// Set p8, result is sig=max_sig, exp--
+// 4 sig size decr, x_sig=min_sig, x_exp = min_exp
+// Set p9, result is sig=max_den_sig, exp same, signal underflow and inexact
+// 5 sig size decr, x_sig=min_den_sig, x_exp = min_exp
+// Set p10, result is zero, sign of x, signal underflow and inexact
+// 6 sig size decr, x_sig=min_sig, x_exp < min_exp
+// Set p14, result is zero, sign of x, signal underflow and inexact
+//
+// Form exponent of smallest double denormal (if normalized register format)
+{ .mmi
+ adds GR_min_den_rexp = -52, GR_min_pexp
+(p12) cmp.eq.unc p6,p0 = GR_new_sig, r0
+(p13) cmp.eq.unc p8,p10 = GR_new_sig, GR_lden_sig ;;
+}
+
+{ .mmi
+(p6) cmp.lt.unc p6,p7 = GR_x_exp, GR_max_pexp
+(p8) cmp.gt.unc p8,p9 = GR_x_exp, GR_min_pexp
+(p10) cmp.eq.unc p10,p0 = GR_new_sig, r0 ;;
+}
+
+// Create small normal in case need to generate underflow flag
+{ .mfi
+(p10) cmp.le.unc p10,p0 = GR_x_exp, GR_min_pexp
+ fmerge.se FR_tmp = FR_sden_exp, FR_lnorm_sig
+(p9) cmp.gt.unc p9,p14 = GR_x_exp, GR_min_den_rexp
+}
+// Branch if cases 1, 2, 3
+{ .bbb
+(p6) br.cond.spnt NEXT_EXPUP
+(p7) br.cond.spnt NEXT_OVERFLOW
+(p8) br.cond.spnt NEXT_EXPDOWN ;;
+}
+
+// Branch if cases 4, 5, 6
+{ .bbb
+(p9) br.cond.spnt NEXT_NORM_TO_DENORM
+(p10) br.cond.spnt NEXT_UNDERFLOW_TO_ZERO
+(p14) br.cond.spnt NEXT_UNDERFLOW_TO_ZERO ;;
+}
+
+// Here if no special cases
+// Set p6 if result will be a denormal, so can force underflow flag
+// Case 1: x_exp=min_exp, x_sig=unnormalized
+// Case 2: x_exp<min_exp
+{ .mfi
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_new_exp, FR_new_sig
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ nop.f 999
+(p7) tbit.z p6,p0 = GR_new_sig, 63 ;;
+}
+
+NEXT_COMMON_FINISH:
+// Force underflow and inexact if denormal result
+{ .mfi
+ nop.m 999
+(p6) fma.d.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fnorm.d.s0 f8 = f8 // Final normalization to result precision
+(p6) br.cond.spnt NEXT_UNDERFLOW ;;
+}
+
+{ .mfb
+ nop.m 999
+ nop.f 999
+ br.ret.sptk b0;;
+}
+
+//Special cases
+NEXT_EXPUP:
+{ .mfb
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_exp1, FR_snorm_sig
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_EXPDOWN:
+{ .mfb
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_exp1, FR_lnorm_sig
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_NORM_TO_DENORM:
+{ .mfi
+ nop.m 999
+ fmerge.se f8 = FR_new_exp, FR_lden_sig
+ nop.i 999
+}
+// Force underflow and inexact if denormal result
+{ .mfb
+ nop.m 999
+ fma.d.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ br.cond.sptk NEXT_UNDERFLOW ;;
+}
+
+NEXT_UNDERFLOW_TO_ZERO:
+{ .mfb
+ cmp.eq p6,p0 = r0,r0
+ fmerge.s f8 = FR_save_f8,f0
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_INF:
+// Here if f8 is +- infinity
+// INF
+// if f8 is +inf, no matter what y is return largest double
+// if f8 is -inf, no matter what y is return -largest double
+
+{ .mfi
+ nop.m 999
+ fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fmerge.s f8 = f8,FR_lnorm
+ br.ret.sptk b0 ;;
+}
+
+NEXT_ZERO:
+
+// Here if f8 is +- zero
+// ZERO
+// if f8 is zero and y is +, return + smallest double denormal
+// if f8 is zero and y is -, return - smallest double denormal
+
+{ .mfi
+ nop.m 999
+ fmerge.se FR_sden = FR_sden_exp,FR_sden_sig
+ nop.i 999 ;;
+}
+
+// Create small normal to generate underflow flag
+{ .mfi
+ nop.m 999
+ fmerge.se FR_tmp = FR_sden_exp, FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+// Add correct sign from direction arg
+{ .mfi
+ nop.m 999
+ fmerge.s f8 = f9,FR_sden
+ nop.i 999 ;;
+}
+
+// Force underflow and inexact flags
+{ .mfb
+ nop.m 999
+ fma.d.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ br.cond.sptk NEXT_UNDERFLOW ;;
+}
+
+NEXT_UNDERFLOW:
+// Here if result is a denorm, or input is finite and result is zero
+// Call error support to report possible range error
+{ .mib
+ alloc r32=ar.pfs,2,2,4,0
+ mov GR_Parameter_TAG = 268 // Error code
+ br.cond.sptk __libm_error_region // Branch to error call
+}
+;;
+
+NEXT_OVERFLOW:
+// Here if input is finite, but result will be infinite
+// Use frcpa to generate infinity of correct sign
+// Call error support to report possible range error
+{ .mfi
+ alloc r32=ar.pfs,2,2,4,0
+ frcpa.s1 f8,p6 = FR_save_f8, f0
+ nop.i 999 ;;
+}
+
+// Create largest double
+{ .mfi
+ nop.m 999
+ fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+// Force overflow and inexact flags to be set
+{ .mfb
+ mov GR_Parameter_TAG = 154 // Error code
+ fma.d.s0 FR_tmp = FR_lnorm,FR_lnorm,f0
+ br.cond.sptk __libm_error_region // Branch to error call
+}
+;;
+
+GLOBAL_LIBM_END(nextafter)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+
+// (2)
+{ .mmi
+ stfd [GR_Parameter_Y] = f9,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfd [GR_Parameter_X] = FR_save_f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+// (4)
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_nextafterf.S b/libc/sysdeps/ia64/fpu/s_nextafterf.S
new file mode 100644
index 000000000..0c269eca9
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_nextafterf.S
@@ -0,0 +1,504 @@
+.file "nextafterf.s"
+
+
+// Copyright (c) 2000 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 03/03/00 Modified to conform to C9X, and improve speed of main path
+// 03/14/00 Fixed case where x is a power of 2, and x > y, improved speed
+// 04/04/00 Unwind support added
+// 05/12/00 Fixed erroneous denormal flag setting for exponent change cases 1,3
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 09/09/00 Updated fcmp so that qnans do not raise invalid
+// 12/15/00 Corrected behavior when both args are zero to conform to C99, and
+// fixed flag settings for several cases
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 12/14/04 Added error handling on underflow.
+//
+// API
+//==============================================================
+// float nextafterf( float x, float y );
+// input floating point f8, f9
+// output floating point f8
+//
+// Registers used
+//==============================================================
+GR_max_pexp = r14
+GR_min_pexp = r15
+GR_exp = r16
+GR_sig = r17
+GR_lnorm_sig = r18
+GR_sign_mask = r19
+GR_exp_mask = r20
+GR_sden_sig = r21
+GR_new_sig = r22
+GR_new_exp = r23
+GR_lden_sig = r24
+GR_snorm_sig = r25
+GR_exp1 = r26
+GR_x_exp = r27
+GR_min_den_rexp = r28
+// r36-39 parameters for libm_error_support
+
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+GR_SAVE_PFS = r32
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+FR_lnorm_sig = f10
+FR_lnorm_exp = f11
+FR_lnorm = f12
+FR_sden_sig = f13
+FR_sden_exp = f14
+FR_sden = f15
+FR_save_f8 = f33
+FR_new_exp = f34
+FR_new_sig = f35
+FR_lden_sig = f36
+FR_snorm_sig = f37
+FR_exp1 = f38
+FR_tmp = f39
+
+//
+// Overview of operation
+//==============================================================
+// nextafterf determines the next representable value
+// after x in the direction of y.
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(nextafterf)
+
+// Extract signexp from x
+// Form smallest denormal significand = ulp size
+{ .mlx
+ getf.exp GR_exp = f8
+ movl GR_sden_sig = 0x0000010000000000
+}
+// Form largest normal exponent
+// Is x < y ? p10 if yes, p11 if no
+// Form smallest normal exponent
+{ .mfi
+ addl GR_max_pexp = 0x1007e, r0
+ fcmp.lt.s1 p10,p11 = f8, f9
+ addl GR_min_pexp = 0x0ff81, r0 ;;
+}
+
+// Is x=y?
+{ .mfi
+ getf.sig GR_sig = f8
+ fcmp.eq.s0 p6,p0 = f8, f9
+ nop.i 0
+}
+// Extract significand from x
+// Form largest normal significand
+{ .mlx
+ nop.m 0
+ movl GR_lnorm_sig = 0xffffff0000000000 ;;
+}
+
+// Move largest normal significand to fp reg for special cases
+{ .mfi
+ setf.sig FR_lnorm_sig = GR_lnorm_sig
+ nop.f 0
+ addl GR_sign_mask = 0x20000, r0 ;;
+}
+
+// Move smallest denormal significand and signexp to fp regs
+// Is x=nan?
+// Set p12 and p13 based on whether significand increases or decreases
+// It increases (p12 set) if x<y and x>=0 or if x>y and x<0
+// It decreases (p13 set) if x<y and x<0 or if x>y and x>=0
+{ .mfi
+ setf.sig FR_sden_sig = GR_sden_sig
+ fclass.m p8,p0 = f8, 0xc3
+(p10) cmp.lt p12,p13 = GR_exp, GR_sign_mask
+}
+{ .mfi
+ setf.exp FR_sden_exp = GR_min_pexp
+ nop.f 999
+(p11) cmp.ge p12,p13 = GR_exp, GR_sign_mask ;;
+}
+
+.pred.rel "mutex",p12,p13
+
+// Form expected new significand, adding or subtracting 1 ulp increment
+// If x=y set result to y
+// Form smallest normal significand and largest denormal significand
+{ .mfi
+(p12) add GR_new_sig = GR_sig, GR_sden_sig
+(p6) fmerge.s f8=f9,f9
+ dep.z GR_snorm_sig = 1,63,1 // 0x8000000000000000
+}
+{ .mlx
+(p13) sub GR_new_sig = GR_sig, GR_sden_sig
+ movl GR_lden_sig = 0x7fffff0000000000 ;;
+}
+
+// Move expected result significand and signexp to fp regs
+// Is y=nan?
+// Form new exponent in case result exponent needs incrementing or decrementing
+{ .mfi
+ setf.exp FR_new_exp = GR_exp
+ fclass.m p9,p0 = f9, 0xc3
+(p12) add GR_exp1 = 1, GR_exp
+}
+{ .mib
+ setf.sig FR_new_sig = GR_new_sig
+(p13) add GR_exp1 = -1, GR_exp
+(p6) br.ret.spnt b0 ;; // Exit if x=y
+}
+
+// Move largest normal signexp to fp reg for special cases
+// Is x=zero?
+{ .mfi
+ setf.exp FR_lnorm_exp = GR_max_pexp
+ fclass.m p7,p0 = f8, 0x7
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p8) fma.s0 f8 = f8,f1,f9
+(p8) br.ret.spnt b0 ;; // Exit if x=nan
+}
+
+// Move exp+-1 and smallest normal significand to fp regs for special cases
+// Is x=inf?
+{ .mfi
+ setf.exp FR_exp1 = GR_exp1
+ fclass.m p6,p0 = f8, 0x23
+ addl GR_exp_mask = 0x1ffff, r0
+}
+{ .mfb
+ setf.sig FR_snorm_sig = GR_snorm_sig
+(p9) fma.s0 f8 = f8,f1,f9
+(p9) br.ret.spnt b0 ;; // Exit if y=nan
+}
+
+// Move largest denormal significand to fp regs for special cases
+// Save x
+{ .mfb
+ setf.sig FR_lden_sig = GR_lden_sig
+ mov FR_save_f8 = f8
+(p7) br.cond.spnt NEXT_ZERO ;; // Exit if x=0
+}
+
+// Mask off the sign to get x_exp
+{ .mfb
+ and GR_x_exp = GR_exp_mask, GR_exp
+ nop.f 999
+(p6) br.cond.spnt NEXT_INF ;; // Exit if x=inf
+}
+
+// Check 6 special cases when significand rolls over:
+// 1 sig size incr, x_sig=max_sig, x_exp < max_exp
+// Set p6, result is sig=min_sig, exp++
+// 2 sig size incr, x_sig=max_sig, x_exp >= max_exp
+// Set p7, result is inf, signal overflow
+// 3 sig size decr, x_sig=min_sig, x_exp > min_exp
+// Set p8, result is sig=max_sig, exp--
+// 4 sig size decr, x_sig=min_sig, x_exp = min_exp
+// Set p9, result is sig=max_den_sig, exp same, signal underflow and inexact
+// 5 sig size decr, x_sig=min_den_sig, x_exp = min_exp
+// Set p10, result is zero, sign of x, signal underflow and inexact
+// 6 sig size decr, x_sig=min_sig, x_exp < min_exp
+// Set p14, result is zero, sign of x, signal underflow and inexact
+//
+// Form exponent of smallest float denormal (if normalized register format)
+{ .mmi
+ adds GR_min_den_rexp = -23, GR_min_pexp
+(p12) cmp.eq.unc p6,p0 = GR_new_sig, r0
+(p13) cmp.eq.unc p8,p10 = GR_new_sig, GR_lden_sig ;;
+}
+
+{ .mmi
+(p6) cmp.lt.unc p6,p7 = GR_x_exp, GR_max_pexp
+(p8) cmp.gt.unc p8,p9 = GR_x_exp, GR_min_pexp
+(p10) cmp.eq.unc p10,p0 = GR_new_sig, r0 ;;
+}
+
+// Create small normal in case need to generate underflow flag
+{ .mfi
+(p10) cmp.le.unc p10,p0 = GR_x_exp, GR_min_pexp
+ fmerge.se FR_tmp = FR_sden_exp, FR_lnorm_sig
+(p9) cmp.gt.unc p9,p14 = GR_x_exp, GR_min_den_rexp
+}
+// Branch if cases 1, 2, 3
+{ .bbb
+(p6) br.cond.spnt NEXT_EXPUP
+(p7) br.cond.spnt NEXT_OVERFLOW
+(p8) br.cond.spnt NEXT_EXPDOWN ;;
+}
+
+// Branch if cases 4, 5, 6
+{ .bbb
+(p9) br.cond.spnt NEXT_NORM_TO_DENORM
+(p10) br.cond.spnt NEXT_UNDERFLOW_TO_ZERO
+(p14) br.cond.spnt NEXT_UNDERFLOW_TO_ZERO ;;
+}
+
+// Here if no special cases
+// Set p6 if result will be a denormal, so can force underflow flag
+// Case 1: x_exp=min_exp, x_sig=unnormalized
+// Case 2: x_exp<min_exp
+{ .mfi
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_new_exp, FR_new_sig
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ nop.f 999
+(p7) tbit.z p6,p0 = GR_new_sig, 63 ;;
+}
+
+NEXT_COMMON_FINISH:
+// Force underflow and inexact if denormal result
+{ .mfi
+ nop.m 999
+(p6) fma.s.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fnorm.s.s0 f8 = f8 // Final normalization to result precision
+(p6) br.cond.spnt NEXT_UNDERFLOW ;;
+}
+
+{ .mfb
+ nop.m 999
+ nop.f 999
+ br.ret.sptk b0;;
+}
+
+//Special cases
+NEXT_EXPUP:
+{ .mfb
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_exp1, FR_snorm_sig
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_EXPDOWN:
+{ .mfb
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_exp1, FR_lnorm_sig
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_NORM_TO_DENORM:
+{ .mfi
+ nop.m 999
+ fmerge.se f8 = FR_new_exp, FR_lden_sig
+ nop.i 999
+}
+// Force underflow and inexact
+{ .mfb
+ nop.m 999
+ fma.s.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ br.cond.sptk NEXT_UNDERFLOW ;;
+}
+
+NEXT_UNDERFLOW_TO_ZERO:
+{ .mfb
+ cmp.eq p6,p0 = r0,r0
+ fmerge.s f8 = FR_save_f8,f0
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_INF:
+// Here if f8 is +- infinity
+// INF
+// if f8 is +inf, no matter what y is return largest float
+// if f8 is -inf, no matter what y is return -largest float
+
+{ .mfi
+ nop.m 999
+ fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fmerge.s f8 = f8,FR_lnorm
+ br.ret.sptk b0 ;;
+}
+
+NEXT_ZERO:
+
+// Here if f8 is +- zero
+// ZERO
+// if f8 is zero and y is +, return + smallest float denormal
+// if f8 is zero and y is -, return - smallest float denormal
+
+{ .mfi
+ nop.m 999
+ fmerge.se FR_sden = FR_sden_exp,FR_sden_sig
+ nop.i 999 ;;
+}
+
+// Create small normal to generate underflow flag
+{ .mfi
+ nop.m 999
+ fmerge.se FR_tmp = FR_sden_exp, FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+// Add correct sign from direction arg
+{ .mfi
+ nop.m 999
+ fmerge.s f8 = f9,FR_sden
+ nop.i 999 ;;
+}
+
+// Force underflow and inexact flags
+{ .mfb
+ nop.m 999
+ fma.s.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ br.cond.sptk NEXT_UNDERFLOW ;;
+}
+
+NEXT_UNDERFLOW:
+// Here if result is a denorm, or input is finite and result is zero
+// Call error support to report possible range error
+{ .mib
+ alloc r32=ar.pfs,2,2,4,0
+ mov GR_Parameter_TAG = 269 // Error code
+ br.cond.sptk __libm_error_region // Branch to error call
+}
+;;
+
+NEXT_OVERFLOW:
+// Here if input is finite, but result will be infinite
+// Use frcpa to generate infinity of correct sign
+// Call error support to report possible range error
+{ .mfi
+ alloc r32=ar.pfs,2,2,4,0
+ frcpa.s1 f8,p6 = FR_save_f8, f0
+ nop.i 999 ;;
+}
+
+// Create largest double
+{ .mfi
+ nop.m 999
+ fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+// Force overflow and inexact flags to be set
+{ .mfb
+ mov GR_Parameter_TAG = 155 // Error code
+ fma.s.s0 FR_tmp = FR_lnorm,FR_lnorm,f0
+ br.cond.sptk __libm_error_region // Branch to error call
+}
+;;
+
+GLOBAL_LIBM_END(nextafterf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+
+// (2)
+{ .mmi
+ stfs [GR_Parameter_Y] = f9,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfs [GR_Parameter_X] = FR_save_f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+// (4)
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_nextafterl.S b/libc/sysdeps/ia64/fpu/s_nextafterl.S
new file mode 100644
index 000000000..20c927b1c
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_nextafterl.S
@@ -0,0 +1,503 @@
+.file "nextafterl.s"
+
+
+// Copyright (c) 2000 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 03/03/00 Modified to conform to C9X, and improve speed of main path
+// 03/14/00 Fixed case where x is a power of 2, and x > y, improved speed
+// 04/04/00 Unwind support added
+// 05/12/00 Fixed erroneous denormal flag setting for exponent change cases 1,3
+// 08/15/00 Bundle added after call to __libm_error_support to properly
+// set [the previously overwritten] GR_Parameter_RESULT.
+// 09/09/00 Updated fcmp so that qnans do not raise invalid.
+// 12/15/00 Fixed case of smallest long double normal to largest denormal,
+// now adhere to C99 for two zero args, and fixed flag settings
+// for several cases
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 12/14/04 Added error handling on underflow.
+//
+// API
+//==============================================================
+// long double nextafterl( long double x, long double y );
+// input floating point f8, f9
+// output floating point f8
+//
+// Registers used
+//==============================================================
+GR_max_pexp = r14
+GR_min_pexp = r15
+GR_exp = r16
+GR_sig = r17
+GR_lnorm_sig = r18
+GR_sign_mask = r19
+GR_exp_mask = r20
+GR_sden_sig = r21
+GR_new_sig = r22
+GR_new_exp = r23
+GR_lden_sig = r24
+GR_snorm_sig = r25
+GR_exp1 = r26
+GR_x_exp = r27
+// r36-39 parameters for libm_error_support
+
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+GR_SAVE_PFS = r32
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+FR_lnorm_sig = f10
+FR_lnorm_exp = f11
+FR_lnorm = f12
+FR_sden_sig = f13
+FR_den_exp = f14
+FR_sden = f15
+FR_snorm_exp = f32
+FR_save_f8 = f33
+FR_new_exp = f34
+FR_new_sig = f35
+FR_lden_sig = f36
+FR_snorm_sig = f37
+FR_exp1 = f38
+FR_tmp = f39
+
+//
+// Overview of operation
+//==============================================================
+// nextafterl determines the next representable value
+// after x in the direction of y.
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(nextafterl)
+
+// Extract signexp from x
+// Is x < y ? p10 if yes, p11 if no
+// Form smallest denormal significand = ulp size
+{ .mfi
+ getf.exp GR_exp = f8
+ fcmp.lt.s1 p10,p11 = f8, f9
+ addl GR_sden_sig = 0x1, r0
+}
+// Form largest normal significand 0xffffffffffffffff
+// Form smallest normal exponent
+{ .mfi
+ addl GR_lnorm_sig = -0x1,r0
+ nop.f 999
+ addl GR_min_pexp = 0x0c001, r0 ;;
+}
+
+// Extract significand from x
+// Is x=y? This fcmp also sets Invalid and Denormal if required
+// Form largest normal exponent
+{ .mfi
+ getf.sig GR_sig = f8
+ fcmp.eq.s0 p6,p0 = f8, f9
+ addl GR_max_pexp = 0x13ffe, r0
+}
+// Move largest normal significand to fp reg for special cases
+{ .mfi
+ setf.sig FR_lnorm_sig = GR_lnorm_sig
+ nop.f 999
+ addl GR_sign_mask = 0x20000, r0 ;;
+}
+
+// Move smallest denormal significand and exp to fp regs
+// Is x=nan?
+// Set p12 and p13 based on whether significand increases or decreases
+// It increases (p12 set) if x<y and x>=0 or if x>y and x<0
+// It decreases (p13 set) if x<y and x<0 or if x>y and x>=0
+{ .mfi
+ setf.sig FR_sden_sig = GR_sden_sig
+ fclass.m p8,p0 = f8, 0xc3
+(p10) cmp.lt p12,p13 = GR_exp, GR_sign_mask
+}
+// Move smallest normal exp to fp regs
+{ .mfi
+ setf.exp FR_snorm_exp = GR_min_pexp
+ nop.f 999
+(p11) cmp.ge p12,p13 = GR_exp, GR_sign_mask ;;
+}
+
+.pred.rel "mutex",p12,p13
+
+// Form expected new significand, adding or subtracting 1 ulp increment
+// If x=y set result to y
+// Form smallest normal significand and largest denormal significand
+{ .mfi
+(p12) add GR_new_sig = GR_sig, GR_sden_sig
+(p6) fmerge.s f8=f9,f9
+ dep.z GR_snorm_sig = 1,63,1 // 0x8000000000000000
+}
+{ .mlx
+(p13) sub GR_new_sig = GR_sig, GR_sden_sig
+ movl GR_lden_sig = 0x7fffffffffffffff ;;
+}
+
+// Move expected result significand and signexp to fp regs
+// Is y=nan?
+// Form new exponent in case result exponent needs incrementing or decrementing
+{ .mfi
+ setf.exp FR_new_exp = GR_exp
+ fclass.m p9,p0 = f9, 0xc3
+(p12) add GR_exp1 = 1, GR_exp
+}
+{ .mib
+ setf.sig FR_new_sig = GR_new_sig
+(p13) add GR_exp1 = -1, GR_exp
+(p6) br.ret.spnt b0 ;; // Exit if x=y
+}
+
+// Move largest normal signexp to fp reg for special cases
+// Is x=zero?
+{ .mfi
+ setf.exp FR_lnorm_exp = GR_max_pexp
+ fclass.m p7,p0 = f8, 0x7
+ nop.i 999
+}
+{ .mfb
+ setf.exp FR_den_exp = GR_min_pexp
+(p8) fma.s0 f8 = f8,f1,f9
+(p8) br.ret.spnt b0 ;; // Exit if x=nan
+}
+
+// Move exp+-1 and smallest normal significand to fp regs for special cases
+// Is x=inf?
+{ .mfi
+ setf.exp FR_exp1 = GR_exp1
+ fclass.m p6,p0 = f8, 0x23
+ addl GR_exp_mask = 0x1ffff, r0
+}
+{ .mfb
+ setf.sig FR_snorm_sig = GR_snorm_sig
+(p9) fma.s0 f8 = f8,f1,f9
+(p9) br.ret.spnt b0 ;; // Exit if y=nan
+}
+
+// Move largest denormal significand to fp regs for special cases
+// Save x
+{ .mfb
+ setf.sig FR_lden_sig = GR_lden_sig
+ mov FR_save_f8 = f8
+(p7) br.cond.spnt NEXT_ZERO ;; // Exit if x=0
+}
+
+// Mask off the sign to get x_exp
+{ .mfb
+ and GR_x_exp = GR_exp_mask, GR_exp
+ nop.f 999
+(p6) br.cond.spnt NEXT_INF ;; // Exit if x=inf
+}
+
+// Check 5 special cases when significand rolls over:
+// 1 sig size incr, x_sig=max_sig, x_exp < max_exp
+// Set p6, result is sig=min_sig, exp++
+// 2 sig size incr, x_sig=max_sig, x_exp >= max_exp
+// Set p7, result is inf, signal overflow
+// 3 sig size decr, x_sig=min_sig, x_exp > min_exp
+// Set p8, result is sig=max_sig, exp--
+// 4 sig size decr, x_sig=min_sig, x_exp = min_exp
+// Set p9, result is sig=max_den_sig, exp same, signal underflow and inexact
+// 5 sig size decr, x_sig=min_den_sig, x_exp = min_exp
+// Set p10, result is zero, sign of x, signal underflow and inexact
+//
+{ .mmi
+(p12) cmp.eq.unc p6,p0 = GR_new_sig, r0
+(p13) cmp.eq.unc p9,p10 = GR_new_sig, GR_lden_sig
+ nop.i 999
+;;
+}
+
+{ .mmi
+(p6) cmp.lt.unc p6,p7 = GR_x_exp, GR_max_pexp
+(p10) cmp.eq.unc p10,p0 = GR_new_sig, r0
+(p9) cmp.le.unc p9,p8 = GR_x_exp, GR_min_pexp
+;;
+}
+
+// Create small normal in case need to generate underflow flag
+{ .mfi
+ nop.m 999
+ fmerge.se FR_tmp = FR_snorm_exp, FR_lnorm_sig
+ nop.i 999
+}
+// Branch if cases 1, 2, 3
+{ .bbb
+(p6) br.cond.spnt NEXT_EXPUP
+(p7) br.cond.spnt NEXT_OVERFLOW
+(p8) br.cond.spnt NEXT_EXPDOWN ;;
+}
+
+// Branch if cases 4, 5
+{ .mbb
+ nop.m 999
+(p9) br.cond.spnt NEXT_NORM_TO_DENORM
+(p10) br.cond.spnt NEXT_UNDERFLOW_TO_ZERO
+;;
+}
+
+// Here if no special cases
+// Set p6 if result will be a denormal, so can force underflow flag
+// Case 1: x_exp=min_exp, x_sig=unnormalized
+// Case 2: x_exp<min_exp
+{ .mfi
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_new_exp, FR_new_sig
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ nop.f 999
+(p6) tbit.z p6,p0 = GR_new_sig, 63 ;;
+}
+
+NEXT_COMMON_FINISH:
+// Force underflow and inexact if denormal result
+{ .mfi
+ nop.m 999
+(p6) fma.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fnorm.s0 f8 = f8 // Final normalization to result precision
+(p6) br.cond.spnt NEXT_UNDERFLOW ;;
+}
+
+{ .mfb
+ nop.m 999
+ nop.f 999
+ br.ret.sptk b0;;
+}
+
+//Special cases
+NEXT_EXPUP:
+{ .mfb
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_exp1, FR_snorm_sig
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_EXPDOWN:
+{ .mfb
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_exp1, FR_lnorm_sig
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_NORM_TO_DENORM:
+{ .mfi
+ nop.m 999
+ fmerge.se f8 = FR_exp1, FR_lden_sig
+ nop.i 999
+}
+// Force underflow and inexact
+{ .mfb
+ nop.m 999
+ fma.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ br.cond.sptk NEXT_UNDERFLOW ;;
+}
+
+NEXT_UNDERFLOW_TO_ZERO:
+{ .mfb
+ cmp.eq p6,p0 = r0,r0
+ fmerge.s f8 = FR_save_f8,f0
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_INF:
+// Here if f8 is +- infinity
+// INF
+// if f8 is +inf, no matter what y is return largest long double
+// if f8 is -inf, no matter what y is return -largest long double
+
+// Create largest long double
+{ .mfi
+ nop.m 999
+ fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fmerge.s f8 = f8,FR_lnorm
+ br.ret.sptk b0 ;;
+}
+
+NEXT_ZERO:
+
+// Here if f8 is +- zero
+// ZERO
+// if f8 is zero and y is +, return + smallest long double denormal
+// if f8 is zero and y is -, return - smallest long double denormal
+
+{ .mfi
+ nop.m 999
+ fmerge.se FR_sden = f0,FR_sden_sig
+ nop.i 999 ;;
+}
+
+// Create small normal to generate underflow flag
+{ .mfi
+ nop.m 999
+ fmerge.se FR_tmp = FR_snorm_exp, FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+// Add correct sign from direction arg
+{ .mfi
+ nop.m 999
+ fmerge.s f8 = f9,FR_sden
+ nop.i 999 ;;
+}
+
+// Force underflow and inexact flags
+{ .mfb
+ nop.m 999
+ fma.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ br.cond.sptk NEXT_UNDERFLOW ;;
+}
+
+NEXT_UNDERFLOW:
+// Here if result is a denorm, or input is finite and result is zero
+// Call error support to report possible range error
+{ .mib
+ alloc r32=ar.pfs,2,2,4,0
+ mov GR_Parameter_TAG = 267 // Error code
+ br.cond.sptk __libm_error_region // Branch to error call
+}
+;;
+
+NEXT_OVERFLOW:
+// Here if input is finite, but result will be infinite
+// Use frcpa to generate infinity of correct sign
+// Call error support to report possible range error
+{ .mfi
+ alloc r32=ar.pfs,2,2,4,0
+ frcpa.s1 f8,p6 = FR_save_f8, f0
+ nop.i 999 ;;
+}
+
+// Create largest double
+{ .mfi
+ nop.m 999
+ fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+// Force overflow and inexact flags to be set
+{ .mfb
+ mov GR_Parameter_TAG = 153 // Error code
+ fma.s0 FR_tmp = FR_lnorm,FR_lnorm,f0
+ br.cond.sptk __libm_error_region // Branch to error call
+}
+;;
+
+GLOBAL_LIBM_END(nextafterl)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+
+// (2)
+{ .mmi
+ stfe [GR_Parameter_Y] = f9,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfe [GR_Parameter_X] = FR_save_f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+// (4)
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_nexttoward.S b/libc/sysdeps/ia64/fpu/s_nexttoward.S
new file mode 100644
index 000000000..741fea02b
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_nexttoward.S
@@ -0,0 +1,490 @@
+.file "nexttoward.s"
+
+
+// Copyright (c) 2001 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/15/01 Initial version
+// 08/23/01 Corrected error tag number
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 12/14/04 Added error handling on underflow.
+//
+// API
+//==============================================================
+// double nexttoward( double x, long double y );
+// input floating point f8, f9
+// output floating point f8
+//
+// Registers used
+//==============================================================
+GR_max_pexp = r14
+GR_min_pexp = r15
+GR_exp = r16
+GR_sig = r17
+GR_lnorm_sig = r18
+GR_sign_mask = r19
+GR_exp_mask = r20
+GR_sden_sig = r21
+GR_new_sig = r22
+GR_new_exp = r23
+GR_lden_sig = r24
+GR_snorm_sig = r25
+GR_exp1 = r26
+GR_x_exp = r27
+GR_min_den_rexp = r28
+// r36-39 parameters for libm_error_support
+
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+GR_SAVE_PFS = r32
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+FR_lnorm_sig = f10
+FR_lnorm_exp = f11
+FR_lnorm = f12
+FR_sden_sig = f13
+FR_sden_exp = f14
+FR_sden = f15
+FR_save_f8 = f33
+FR_new_exp = f34
+FR_new_sig = f35
+FR_lden_sig = f36
+FR_snorm_sig = f37
+FR_exp1 = f38
+FR_tmp = f39
+
+//
+// Overview of operation
+//==============================================================
+// nexttoward determines the next representable value
+// after x in the direction of y.
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(nexttoward)
+
+// Extract signexp from x
+// Is x < y ? p10 if yes, p11 if no
+// Form smallest denormal significand = ulp size
+{ .mfi
+ getf.exp GR_exp = f8
+ fcmp.lt.s1 p10,p11 = f8, f9
+ addl GR_sden_sig = 0x800, r0
+}
+// Form largest normal significand 0xfffffffffffff800
+// Form smallest normal exponent
+{ .mfi
+ addl GR_lnorm_sig = -0x800,r0
+ nop.f 999
+ addl GR_min_pexp = 0x0fc01, r0 ;;
+}
+// Extract significand from x
+// Is x=y?
+// Form largest normal exponent
+{ .mfi
+ getf.sig GR_sig = f8
+ fcmp.eq.s0 p6,p0 = f8, f9
+ addl GR_max_pexp = 0x103fe, r0
+}
+// Move largest normal significand to fp reg for special cases
+{ .mfi
+ setf.sig FR_lnorm_sig = GR_lnorm_sig
+ nop.f 999
+ addl GR_sign_mask = 0x20000, r0 ;;
+}
+
+// Move smallest denormal significand and signexp to fp regs
+// Is x=nan?
+// Set p12 and p13 based on whether significand increases or decreases
+// It increases (p12 set) if x<y and x>=0 or if x>y and x<0
+// It decreases (p13 set) if x<y and x<0 or if x>y and x>=0
+{ .mfi
+ setf.sig FR_sden_sig = GR_sden_sig
+ fclass.m p8,p0 = f8, 0xc3
+(p10) cmp.lt p12,p13 = GR_exp, GR_sign_mask
+}
+{ .mfi
+ setf.exp FR_sden_exp = GR_min_pexp
+(p11) cmp.ge p12,p13 = GR_exp, GR_sign_mask ;;
+}
+
+.pred.rel "mutex",p12,p13
+
+// Form expected new significand, adding or subtracting 1 ulp increment
+// If x=y set result to y
+// Form smallest normal significand and largest denormal significand
+{ .mfi
+(p12) add GR_new_sig = GR_sig, GR_sden_sig
+(p6) fnorm.d.s0 f8=f9 //Normalise
+ dep.z GR_snorm_sig = 1,63,1 // 0x8000000000000000
+}
+{ .mlx
+(p13) sub GR_new_sig = GR_sig, GR_sden_sig
+ movl GR_lden_sig = 0x7ffffffffffff800 ;;
+}
+
+// Move expected result significand and signexp to fp regs
+// Is y=nan?
+// Form new exponent in case result exponent needs incrementing or decrementing
+{ .mfi
+ setf.exp FR_new_exp = GR_exp
+ fclass.m p9,p0 = f9, 0xc3
+(p12) add GR_exp1 = 1, GR_exp
+}
+{ .mib
+ setf.sig FR_new_sig = GR_new_sig
+(p13) add GR_exp1 = -1, GR_exp
+(p6) br.ret.spnt b0 ;; // Exit if x=y
+}
+
+// Move largest normal signexp to fp reg for special cases
+// Is x=zero?
+{ .mfi
+ setf.exp FR_lnorm_exp = GR_max_pexp
+ fclass.m p7,p0 = f8, 0x7
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p8) fma.s0 f8 = f8,f1,f9
+(p8) br.ret.spnt b0 ;; // Exit if x=nan
+}
+
+// Move exp+-1 and smallest normal significand to fp regs for special cases
+// Is x=inf?
+{ .mfi
+ setf.exp FR_exp1 = GR_exp1
+ fclass.m p6,p0 = f8, 0x23
+ addl GR_exp_mask = 0x1ffff, r0
+}
+{ .mfb
+ setf.sig FR_snorm_sig = GR_snorm_sig
+(p9) fma.s0 f8 = f8,f1,f9
+(p9) br.ret.spnt b0 ;; // Exit if y=nan
+}
+
+// Move largest denormal significand to fp regs for special cases
+// Save x
+{ .mfb
+ setf.sig FR_lden_sig = GR_lden_sig
+ mov FR_save_f8 = f8
+(p7) br.cond.spnt NEXT_ZERO ;; // Exit if x=0
+}
+
+// Mask off the sign to get x_exp
+{ .mfb
+ and GR_x_exp = GR_exp_mask, GR_exp
+ nop.f 999
+(p6) br.cond.spnt NEXT_INF ;; // Exit if x=inf
+}
+
+// Check 6 special cases when significand rolls over:
+// 1 sig size incr, x_sig=max_sig, x_exp < max_exp
+// Set p6, result is sig=min_sig, exp++
+// 2 sig size incr, x_sig=max_sig, x_exp >= max_exp
+// Set p7, result is inf, signal overflow
+// 3 sig size decr, x_sig=min_sig, x_exp > min_exp
+// Set p8, result is sig=max_sig, exp--
+// 4 sig size decr, x_sig=min_sig, x_exp = min_exp
+// Set p9, result is sig=max_den_sig, exp same, signal underflow and inexact
+// 5 sig size decr, x_sig=min_den_sig, x_exp = min_exp
+// Set p10, result is zero, sign of x, signal underflow and inexact
+// 6 sig size decr, x_sig=min_sig, x_exp < min_exp
+// Set p14, result is zero, sign of x, signal underflow and inexact
+//
+// Form exponent of smallest double denormal (if normalized register format)
+{ .mmi
+ adds GR_min_den_rexp = -52, GR_min_pexp
+(p12) cmp.eq.unc p6,p0 = GR_new_sig, r0
+(p13) cmp.eq.unc p8,p10 = GR_new_sig, GR_lden_sig ;;
+}
+
+{ .mmi
+(p6) cmp.lt.unc p6,p7 = GR_x_exp, GR_max_pexp
+(p8) cmp.gt.unc p8,p9 = GR_x_exp, GR_min_pexp
+(p10) cmp.eq.unc p10,p0 = GR_new_sig, r0 ;;
+}
+
+// Create small normal in case need to generate underflow flag
+{ .mfi
+(p10) cmp.le.unc p10,p0 = GR_x_exp, GR_min_pexp
+ fmerge.se FR_tmp = FR_sden_exp, FR_lnorm_sig
+(p9) cmp.gt.unc p9,p14 = GR_x_exp, GR_min_den_rexp
+}
+// Branch if cases 1, 2, 3
+{ .bbb
+(p6) br.cond.spnt NEXT_EXPUP
+(p7) br.cond.spnt NEXT_OVERFLOW
+(p8) br.cond.spnt NEXT_EXPDOWN ;;
+}
+
+// Branch if cases 4, 5, 6
+{ .bbb
+(p9) br.cond.spnt NEXT_NORM_TO_DENORM
+(p10) br.cond.spnt NEXT_UNDERFLOW_TO_ZERO
+(p14) br.cond.spnt NEXT_UNDERFLOW_TO_ZERO ;;
+}
+
+// Here if no special cases
+// Set p6 if result will be a denormal, so can force underflow flag
+// Case 1: x_exp=min_exp, x_sig=unnormalized
+// Case 2: x_exp<min_exp
+{ .mfi
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_new_exp, FR_new_sig
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ nop.f 999
+(p7) tbit.z p6,p0 = GR_new_sig, 63 ;;
+}
+
+NEXT_COMMON_FINISH:
+// Force underflow and inexact if denormal result
+{ .mfi
+ nop.m 999
+(p6) fma.d.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fnorm.d.s0 f8 = f8 // Final normalization to result precision
+(p6) br.cond.spnt NEXT_UNDERFLOW ;;
+}
+
+{ .mfb
+ nop.m 999
+ nop.f 999
+ br.ret.sptk b0;;
+}
+
+//Special cases
+NEXT_EXPUP:
+{ .mfb
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_exp1, FR_snorm_sig
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_EXPDOWN:
+{ .mfb
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_exp1, FR_lnorm_sig
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_NORM_TO_DENORM:
+{ .mfi
+ nop.m 999
+ fmerge.se f8 = FR_new_exp, FR_lden_sig
+ nop.i 999
+}
+// Force underflow and inexact if denormal result
+{ .mfb
+ nop.m 999
+ fma.d.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ br.cond.sptk NEXT_UNDERFLOW ;;
+}
+
+NEXT_UNDERFLOW_TO_ZERO:
+{ .mfb
+ cmp.eq p6,p0 = r0,r0
+ fmerge.s f8 = FR_save_f8,f0
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_INF:
+// Here if f8 is +- infinity
+// INF
+// if f8 is +inf, no matter what y is return largest double
+// if f8 is -inf, no matter what y is return -largest double
+
+{ .mfi
+ nop.m 999
+ fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fmerge.s f8 = f8,FR_lnorm
+ br.ret.sptk b0 ;;
+}
+
+NEXT_ZERO:
+
+// Here if f8 is +- zero
+// ZERO
+// if f8 is zero and y is +, return + smallest double denormal
+// if f8 is zero and y is -, return - smallest double denormal
+
+{ .mfi
+ nop.m 999
+ fmerge.se FR_sden = FR_sden_exp,FR_sden_sig
+ nop.i 999 ;;
+}
+
+// Create small normal to generate underflow flag
+{ .mfi
+ nop.m 999
+ fmerge.se FR_tmp = FR_sden_exp, FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+// Add correct sign from direction arg
+{ .mfi
+ nop.m 999
+ fmerge.s f8 = f9,FR_sden
+ nop.i 999 ;;
+}
+
+// Force underflow and inexact flags
+{ .mfb
+ nop.m 999
+ fma.d.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ br.cond.sptk NEXT_UNDERFLOW ;;
+}
+
+NEXT_UNDERFLOW:
+// Here if result is a denorm, or input is finite and result is zero
+// Call error support to report possible range error
+{ .mib
+ alloc r32=ar.pfs,2,2,4,0
+ mov GR_Parameter_TAG = 271 // Error code
+ br.cond.sptk __libm_error_region // Branch to error call
+}
+;;
+
+NEXT_OVERFLOW:
+// Here if input is finite, but result will be infinite
+// Use frcpa to generate infinity of correct sign
+// Call error support to report possible range error
+{ .mfi
+ alloc r32=ar.pfs,2,2,4,0
+ frcpa.s1 f8,p6 = FR_save_f8, f0
+ nop.i 999 ;;
+}
+
+// Create largest double
+{ .mfi
+ nop.m 999
+ fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+// Force overflow and inexact flags to be set
+{ .mfb
+ mov GR_Parameter_TAG = 199 // Error code
+ fma.d.s0 FR_tmp = FR_lnorm,FR_lnorm,f0
+ br.cond.sptk __libm_error_region // Branch to error call
+}
+;;
+
+GLOBAL_LIBM_END(nexttoward)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+
+// (2)
+{ .mmi
+ stfd [GR_Parameter_Y] = f9,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfd [GR_Parameter_X] = FR_save_f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+// (4)
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_nexttowardf.S b/libc/sysdeps/ia64/fpu/s_nexttowardf.S
new file mode 100644
index 000000000..b8b976271
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_nexttowardf.S
@@ -0,0 +1,496 @@
+.file "nexttowardf.s"
+
+
+// Copyright (c) 2001 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/15/01 Initial version
+// 08/23/01 Corrected error tag number
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 12/14/04 Added error handling on underflow.
+//
+// API
+//==============================================================
+// float nexttowardf( float x, long double y );
+// input floating point f8, f9
+// output floating point f8
+//
+// Registers used
+//==============================================================
+GR_max_pexp = r14
+GR_min_pexp = r15
+GR_exp = r16
+GR_sig = r17
+GR_lnorm_sig = r18
+GR_sign_mask = r19
+GR_exp_mask = r20
+GR_sden_sig = r21
+GR_new_sig = r22
+GR_new_exp = r23
+GR_lden_sig = r24
+GR_snorm_sig = r25
+GR_exp1 = r26
+GR_x_exp = r27
+GR_min_den_rexp = r28
+// r36-39 parameters for libm_error_support
+
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+GR_SAVE_PFS = r32
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+FR_lnorm_sig = f10
+FR_lnorm_exp = f11
+FR_lnorm = f12
+FR_sden_sig = f13
+FR_sden_exp = f14
+FR_sden = f15
+FR_save_f8 = f33
+FR_new_exp = f34
+FR_new_sig = f35
+FR_lden_sig = f36
+FR_snorm_sig = f37
+FR_exp1 = f38
+FR_tmp = f39
+
+//
+// Overview of operation
+//==============================================================
+// nexttowardf determines the next representable value
+// after x in the direction of y.
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(nexttowardf)
+
+// Extract signexp from x
+// Form smallest denormal significand = ulp size
+{ .mlx
+ getf.exp GR_exp = f8
+ movl GR_sden_sig = 0x0000010000000000
+}
+// Form largest normal exponent
+// Is x < y ? p10 if yes, p11 if no
+// Form smallest normal exponent
+{ .mfi
+ addl GR_max_pexp = 0x1007e, r0
+ fcmp.lt.s1 p10,p11 = f8, f9
+ addl GR_min_pexp = 0x0ff81, r0 ;;
+}
+
+// Is x=y?
+{ .mfi
+ getf.sig GR_sig = f8
+ fcmp.eq.s0 p6,p0 = f8, f9
+ nop.i 0
+}
+// Extract significand from x
+// Form largest normal significand
+{ .mlx
+ nop.m 0
+ movl GR_lnorm_sig = 0xffffff0000000000 ;;
+}
+
+// Move largest normal significand to fp reg for special cases
+{ .mfi
+ setf.sig FR_lnorm_sig = GR_lnorm_sig
+ nop.f 0
+ addl GR_sign_mask = 0x20000, r0 ;;
+}
+
+// Move smallest denormal significand and signexp to fp regs
+// Is x=nan?
+// Set p12 and p13 based on whether significand increases or decreases
+// It increases (p12 set) if x<y and x>=0 or if x>y and x<0
+// It decreases (p13 set) if x<y and x<0 or if x>y and x>=0
+{ .mfi
+ setf.sig FR_sden_sig = GR_sden_sig
+ fclass.m p8,p0 = f8, 0xc3
+(p10) cmp.lt p12,p13 = GR_exp, GR_sign_mask
+}
+{ .mfi
+ setf.exp FR_sden_exp = GR_min_pexp
+ nop.f 999
+(p11) cmp.ge p12,p13 = GR_exp, GR_sign_mask ;;
+}
+
+.pred.rel "mutex",p12,p13
+
+// Form expected new significand, adding or subtracting 1 ulp increment
+// If x=y set result to y
+// Form smallest normal significand and largest denormal significand
+{ .mfi
+(p12) add GR_new_sig = GR_sig, GR_sden_sig
+(p6) fnorm.s.s0 f8=f9 //Normalise
+ dep.z GR_snorm_sig = 1,63,1 // 0x8000000000000000
+}
+{ .mlx
+(p13) sub GR_new_sig = GR_sig, GR_sden_sig
+ movl GR_lden_sig = 0x7fffff0000000000 ;;
+}
+
+// Move expected result significand and signexp to fp regs
+// Is y=nan?
+// Form new exponent in case result exponent needs incrementing or decrementing
+{ .mfi
+ setf.exp FR_new_exp = GR_exp
+ fclass.m p9,p0 = f9, 0xc3
+(p12) add GR_exp1 = 1, GR_exp
+}
+{ .mib
+ setf.sig FR_new_sig = GR_new_sig
+(p13) add GR_exp1 = -1, GR_exp
+(p6) br.ret.spnt b0 ;; // Exit if x=y
+}
+
+// Move largest normal signexp to fp reg for special cases
+// Is x=zero?
+{ .mfi
+ setf.exp FR_lnorm_exp = GR_max_pexp
+ fclass.m p7,p0 = f8, 0x7
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p8) fma.s0 f8 = f8,f1,f9
+(p8) br.ret.spnt b0 ;; // Exit if x=nan
+}
+
+// Move exp+-1 and smallest normal significand to fp regs for special cases
+// Is x=inf?
+{ .mfi
+ setf.exp FR_exp1 = GR_exp1
+ fclass.m p6,p0 = f8, 0x23
+ addl GR_exp_mask = 0x1ffff, r0
+}
+{ .mfb
+ setf.sig FR_snorm_sig = GR_snorm_sig
+(p9) fma.s0 f8 = f8,f1,f9
+(p9) br.ret.spnt b0 ;; // Exit if y=nan
+}
+
+// Move largest denormal significand to fp regs for special cases
+// Save x
+{ .mfb
+ setf.sig FR_lden_sig = GR_lden_sig
+ mov FR_save_f8 = f8
+(p7) br.cond.spnt NEXT_ZERO ;; // Exit if x=0
+}
+
+// Mask off the sign to get x_exp
+{ .mfb
+ and GR_x_exp = GR_exp_mask, GR_exp
+ nop.f 999
+(p6) br.cond.spnt NEXT_INF ;; // Exit if x=inf
+}
+
+// Check 6 special cases when significand rolls over:
+// 1 sig size incr, x_sig=max_sig, x_exp < max_exp
+// Set p6, result is sig=min_sig, exp++
+// 2 sig size incr, x_sig=max_sig, x_exp >= max_exp
+// Set p7, result is inf, signal overflow
+// 3 sig size decr, x_sig=min_sig, x_exp > min_exp
+// Set p8, result is sig=max_sig, exp--
+// 4 sig size decr, x_sig=min_sig, x_exp = min_exp
+// Set p9, result is sig=max_den_sig, exp same, signal underflow and inexact
+// 5 sig size decr, x_sig=min_den_sig, x_exp = min_exp
+// Set p10, result is zero, sign of x, signal underflow and inexact
+// 6 sig size decr, x_sig=min_sig, x_exp < min_exp
+// Set p14, result is zero, sign of x, signal underflow and inexact
+//
+// Form exponent of smallest float denormal (if normalized register format)
+{ .mmi
+ adds GR_min_den_rexp = -23, GR_min_pexp
+(p12) cmp.eq.unc p6,p0 = GR_new_sig, r0
+(p13) cmp.eq.unc p8,p10 = GR_new_sig, GR_lden_sig ;;
+}
+
+{ .mmi
+(p6) cmp.lt.unc p6,p7 = GR_x_exp, GR_max_pexp
+(p8) cmp.gt.unc p8,p9 = GR_x_exp, GR_min_pexp
+(p10) cmp.eq.unc p10,p0 = GR_new_sig, r0 ;;
+}
+
+// Create small normal in case need to generate underflow flag
+{ .mfi
+(p10) cmp.le.unc p10,p0 = GR_x_exp, GR_min_pexp
+ fmerge.se FR_tmp = FR_sden_exp, FR_lnorm_sig
+(p9) cmp.gt.unc p9,p14 = GR_x_exp, GR_min_den_rexp
+}
+// Branch if cases 1, 2, 3
+{ .bbb
+(p6) br.cond.spnt NEXT_EXPUP
+(p7) br.cond.spnt NEXT_OVERFLOW
+(p8) br.cond.spnt NEXT_EXPDOWN ;;
+}
+
+// Branch if cases 4, 5, 6
+{ .bbb
+(p9) br.cond.spnt NEXT_NORM_TO_DENORM
+(p10) br.cond.spnt NEXT_UNDERFLOW_TO_ZERO
+(p14) br.cond.spnt NEXT_UNDERFLOW_TO_ZERO ;;
+}
+
+// Here if no special cases
+// Set p6 if result will be a denormal, so can force underflow flag
+// Case 1: x_exp=min_exp, x_sig=unnormalized
+// Case 2: x_exp<min_exp
+{ .mfi
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_new_exp, FR_new_sig
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ nop.f 999
+(p7) tbit.z p6,p0 = GR_new_sig, 63 ;;
+}
+
+NEXT_COMMON_FINISH:
+// Force underflow and inexact if denormal result
+{ .mfi
+ nop.m 999
+(p6) fma.s.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fnorm.s.s0 f8 = f8 // Final normalization to result precision
+(p6) br.cond.spnt NEXT_UNDERFLOW ;;
+}
+
+{ .mfb
+ nop.m 999
+ nop.f 999
+ br.ret.sptk b0;;
+}
+
+//Special cases
+NEXT_EXPUP:
+{ .mfb
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_exp1, FR_snorm_sig
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_EXPDOWN:
+{ .mfb
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_exp1, FR_lnorm_sig
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_NORM_TO_DENORM:
+{ .mfi
+ nop.m 999
+ fmerge.se f8 = FR_new_exp, FR_lden_sig
+ nop.i 999
+}
+// Force underflow and inexact
+{ .mfb
+ nop.m 999
+ fma.s.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ br.cond.sptk NEXT_UNDERFLOW ;;
+}
+
+NEXT_UNDERFLOW_TO_ZERO:
+{ .mfb
+ cmp.eq p6,p0 = r0,r0
+ fmerge.s f8 = FR_save_f8,f0
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_INF:
+// Here if f8 is +- infinity
+// INF
+// if f8 is +inf, no matter what y is return largest float
+// if f8 is -inf, no matter what y is return -largest float
+
+{ .mfi
+ nop.m 999
+ fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fmerge.s f8 = f8,FR_lnorm
+ br.ret.sptk b0 ;;
+}
+
+NEXT_ZERO:
+
+// Here if f8 is +- zero
+// ZERO
+// if f8 is zero and y is +, return + smallest float denormal
+// if f8 is zero and y is -, return - smallest float denormal
+
+{ .mfi
+ nop.m 999
+ fmerge.se FR_sden = FR_sden_exp,FR_sden_sig
+ nop.i 999 ;;
+}
+
+// Create small normal to generate underflow flag
+{ .mfi
+ nop.m 999
+ fmerge.se FR_tmp = FR_sden_exp, FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+// Add correct sign from direction arg
+{ .mfi
+ nop.m 999
+ fmerge.s f8 = f9,FR_sden
+ nop.i 999 ;;
+}
+
+// Force underflow and inexact flags
+{ .mfb
+ nop.m 999
+ fma.s.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ br.cond.sptk NEXT_UNDERFLOW ;;
+}
+
+NEXT_UNDERFLOW:
+// Here if result is a denorm, or input is finite and result is zero
+// Call error support to report possible range error
+{ .mib
+ alloc r32=ar.pfs,2,2,4,0
+ mov GR_Parameter_TAG = 272 // Error code
+ br.cond.sptk __libm_error_region // Branch to error call
+}
+;;
+
+NEXT_OVERFLOW:
+// Here if input is finite, but result will be infinite
+// Use frcpa to generate infinity of correct sign
+// Call error support to report possible range error
+{ .mfi
+ alloc r32=ar.pfs,2,2,4,0
+ frcpa.s1 f8,p6 = FR_save_f8, f0
+ nop.i 999 ;;
+}
+
+// Create largest double
+{ .mfi
+ nop.m 999
+ fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+// Force overflow and inexact flags to be set
+{ .mfb
+ mov GR_Parameter_TAG = 200 // Error code
+ fma.s.s0 FR_tmp = FR_lnorm,FR_lnorm,f0
+ br.cond.sptk __libm_error_region // Branch to error call
+}
+;;
+
+GLOBAL_LIBM_END(nexttowardf)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+
+// (2)
+{ .mmi
+ stfs [GR_Parameter_Y] = f9,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfs [GR_Parameter_X] = FR_save_f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+// (4)
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_nexttowardl.S b/libc/sysdeps/ia64/fpu/s_nexttowardl.S
new file mode 100644
index 000000000..fa2db125a
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_nexttowardl.S
@@ -0,0 +1,494 @@
+.file "nexttowardl.s"
+
+
+// Copyright (c) 2001 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 08/15/01 Initial version
+// 08/23/01 Corrected error tag number
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 12/14/04 Added error handling on underflow.
+//
+// API
+//==============================================================
+// long double nexttowardl( long double x, long double y );
+// input floating point f8, f9
+// output floating point f8
+//
+// Registers used
+//==============================================================
+GR_max_pexp = r14
+GR_min_pexp = r15
+GR_exp = r16
+GR_sig = r17
+GR_lnorm_sig = r18
+GR_sign_mask = r19
+GR_exp_mask = r20
+GR_sden_sig = r21
+GR_new_sig = r22
+GR_new_exp = r23
+GR_lden_sig = r24
+GR_snorm_sig = r25
+GR_exp1 = r26
+GR_x_exp = r27
+// r36-39 parameters for libm_error_support
+
+GR_SAVE_B0 = r34
+GR_SAVE_GP = r35
+GR_SAVE_PFS = r32
+
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_TAG = r39
+
+FR_lnorm_sig = f10
+FR_lnorm_exp = f11
+FR_lnorm = f12
+FR_sden_sig = f13
+FR_den_exp = f14
+FR_sden = f15
+FR_snorm_exp = f32
+FR_save_f8 = f33
+FR_new_exp = f34
+FR_new_sig = f35
+FR_lden_sig = f36
+FR_snorm_sig = f37
+FR_exp1 = f38
+FR_tmp = f39
+
+//
+// Overview of operation
+//==============================================================
+// nexttowardl determines the next representable value
+// after x in the direction of y.
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(nexttowardl)
+
+// Extract signexp from x
+// Is x < y ? p10 if yes, p11 if no
+// Form smallest denormal significand = ulp size
+{ .mfi
+ getf.exp GR_exp = f8
+ fcmp.lt.s1 p10,p11 = f8, f9
+ addl GR_sden_sig = 0x1, r0
+}
+// Form largest normal significand 0xffffffffffffffff
+// Form smallest normal exponent
+{ .mfi
+ addl GR_lnorm_sig = -0x1,r0
+ nop.f 999
+ addl GR_min_pexp = 0x0c001, r0 ;;
+}
+
+// Extract significand from x
+// Is x=y? This fcmp also sets Invalid and Denormal if required
+// Form largest normal exponent
+{ .mfi
+ getf.sig GR_sig = f8
+ fcmp.eq.s0 p6,p0 = f8, f9
+ addl GR_max_pexp = 0x13ffe, r0
+}
+// Move largest normal significand to fp reg for special cases
+{ .mfi
+ setf.sig FR_lnorm_sig = GR_lnorm_sig
+ nop.f 999
+ addl GR_sign_mask = 0x20000, r0 ;;
+}
+
+// Move smallest denormal significand and exp to fp regs
+// Is x=nan?
+// Set p12 and p13 based on whether significand increases or decreases
+// It increases (p12 set) if x<y and x>=0 or if x>y and x<0
+// It decreases (p13 set) if x<y and x<0 or if x>y and x>=0
+{ .mfi
+ setf.sig FR_sden_sig = GR_sden_sig
+ fclass.m p8,p0 = f8, 0xc3
+(p10) cmp.lt p12,p13 = GR_exp, GR_sign_mask
+}
+// Move smallest normal exp to fp regs
+{ .mfi
+ setf.exp FR_snorm_exp = GR_min_pexp
+ nop.f 999
+(p11) cmp.ge p12,p13 = GR_exp, GR_sign_mask ;;
+}
+
+.pred.rel "mutex",p12,p13
+
+// Form expected new significand, adding or subtracting 1 ulp increment
+// If x=y set result to y
+// Form smallest normal significand and largest denormal significand
+{ .mfi
+(p12) add GR_new_sig = GR_sig, GR_sden_sig
+(p6) fmerge.s f8=f9,f9
+ dep.z GR_snorm_sig = 1,63,1 // 0x8000000000000000
+}
+{ .mlx
+(p13) sub GR_new_sig = GR_sig, GR_sden_sig
+ movl GR_lden_sig = 0x7fffffffffffffff ;;
+}
+
+// Move expected result significand and signexp to fp regs
+// Is y=nan?
+// Form new exponent in case result exponent needs incrementing or decrementing
+{ .mfi
+ setf.exp FR_new_exp = GR_exp
+ fclass.m p9,p0 = f9, 0xc3
+(p12) add GR_exp1 = 1, GR_exp
+}
+{ .mib
+ setf.sig FR_new_sig = GR_new_sig
+(p13) add GR_exp1 = -1, GR_exp
+(p6) br.ret.spnt b0 ;; // Exit if x=y
+}
+
+// Move largest normal signexp to fp reg for special cases
+// Is x=zero?
+{ .mfi
+ setf.exp FR_lnorm_exp = GR_max_pexp
+ fclass.m p7,p0 = f8, 0x7
+ nop.i 999
+}
+{ .mfb
+ setf.exp FR_den_exp = GR_min_pexp
+(p8) fma.s0 f8 = f8,f1,f9
+(p8) br.ret.spnt b0 ;; // Exit if x=nan
+}
+
+// Move exp+-1 and smallest normal significand to fp regs for special cases
+// Is x=inf?
+{ .mfi
+ setf.exp FR_exp1 = GR_exp1
+ fclass.m p6,p0 = f8, 0x23
+ addl GR_exp_mask = 0x1ffff, r0
+}
+{ .mfb
+ setf.sig FR_snorm_sig = GR_snorm_sig
+(p9) fma.s0 f8 = f8,f1,f9
+(p9) br.ret.spnt b0 ;; // Exit if y=nan
+}
+
+// Move largest denormal significand to fp regs for special cases
+// Save x
+{ .mfb
+ setf.sig FR_lden_sig = GR_lden_sig
+ mov FR_save_f8 = f8
+(p7) br.cond.spnt NEXT_ZERO ;; // Exit if x=0
+}
+
+// Mask off the sign to get x_exp
+{ .mfb
+ and GR_x_exp = GR_exp_mask, GR_exp
+ nop.f 999
+(p6) br.cond.spnt NEXT_INF ;; // Exit if x=inf
+}
+
+// Check 5 special cases when significand rolls over:
+// 1 sig size incr, x_sig=max_sig, x_exp < max_exp
+// Set p6, result is sig=min_sig, exp++
+// 2 sig size incr, x_sig=max_sig, x_exp >= max_exp
+// Set p7, result is inf, signal overflow
+// 3 sig size decr, x_sig=min_sig, x_exp > min_exp
+// Set p8, result is sig=max_sig, exp--
+// 4 sig size decr, x_sig=min_sig, x_exp = min_exp
+// Set p9, result is sig=max_den_sig, exp same, signal underflow and inexact
+// 5 sig size decr, x_sig=min_den_sig, x_exp = min_exp
+// Set p10, result is zero, sign of x, signal underflow and inexact
+//
+{ .mmi
+(p12) cmp.eq.unc p6,p0 = GR_new_sig, r0
+(p13) cmp.eq.unc p9,p10 = GR_new_sig, GR_lden_sig
+ nop.i 999
+;;
+}
+
+{ .mmi
+(p6) cmp.lt.unc p6,p7 = GR_x_exp, GR_max_pexp
+(p10) cmp.eq.unc p10,p0 = GR_new_sig, r0
+(p9) cmp.le.unc p9,p8 = GR_x_exp, GR_min_pexp
+;;
+}
+
+// Create small normal in case need to generate underflow flag
+{ .mfi
+ nop.m 999
+ fmerge.se FR_tmp = FR_snorm_exp, FR_lnorm_sig
+ nop.i 999
+}
+// Branch if cases 1, 2, 3
+{ .bbb
+(p6) br.cond.spnt NEXT_EXPUP
+(p7) br.cond.spnt NEXT_OVERFLOW
+(p8) br.cond.spnt NEXT_EXPDOWN ;;
+}
+
+// Branch if cases 4, 5
+{ .mbb
+ nop.m 999
+(p9) br.cond.spnt NEXT_NORM_TO_DENORM
+(p10) br.cond.spnt NEXT_UNDERFLOW_TO_ZERO
+;;
+}
+
+// Here if no special cases
+// Set p6 if result will be a denormal, so can force underflow flag
+// Case 1: x_exp=min_exp, x_sig=unnormalized
+// Case 2: x_exp<min_exp
+{ .mfi
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_new_exp, FR_new_sig
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+ nop.f 999
+(p6) tbit.z p6,p0 = GR_new_sig, 63 ;;
+}
+
+NEXT_COMMON_FINISH:
+// Force underflow and inexact if denormal result
+{ .mfi
+ nop.m 999
+(p6) fma.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+ fnorm.s0 f8 = f8 // Final normalization to result precision
+(p6) br.cond.spnt NEXT_UNDERFLOW ;;
+}
+
+{ .mfb
+ nop.m 999
+ nop.f 999
+ br.ret.sptk b0;;
+}
+
+//Special cases
+NEXT_EXPUP:
+{ .mfb
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_exp1, FR_snorm_sig
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_EXPDOWN:
+{ .mfb
+ cmp.lt p6,p7 = GR_x_exp, GR_min_pexp
+ fmerge.se f8 = FR_exp1, FR_lnorm_sig
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_NORM_TO_DENORM:
+{ .mfi
+ nop.m 999
+ fmerge.se f8 = FR_exp1, FR_lden_sig
+ nop.i 999
+}
+// Force underflow and inexact
+{ .mfb
+ nop.m 999
+ fma.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ br.cond.sptk NEXT_UNDERFLOW ;;
+}
+
+NEXT_UNDERFLOW_TO_ZERO:
+{ .mfb
+ cmp.eq p6,p0 = r0,r0
+ fmerge.s f8 = FR_save_f8,f0
+ br.cond.sptk NEXT_COMMON_FINISH ;;
+}
+
+NEXT_INF:
+// Here if f8 is +- infinity
+// INF
+// if f8 is +inf, no matter what y is return largest long double
+// if f8 is -inf, no matter what y is return -largest long double
+
+// Create largest long double
+{ .mfi
+ nop.m 999
+ fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fmerge.s f8 = f8,FR_lnorm
+ br.ret.sptk b0 ;;
+}
+
+NEXT_ZERO:
+
+// Here if f8 is +- zero
+// ZERO
+// if f8 is zero and y is +, return + smallest long double denormal
+// if f8 is zero and y is -, return - smallest long double denormal
+
+{ .mfi
+ nop.m 999
+ fmerge.se FR_sden = f0,FR_sden_sig
+ nop.i 999 ;;
+}
+
+// Create small normal to generate underflow flag
+{ .mfi
+ nop.m 999
+ fmerge.se FR_tmp = FR_snorm_exp, FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+// Add correct sign from direction arg
+{ .mfi
+ nop.m 999
+ fmerge.s f8 = f9,FR_sden
+ nop.i 999 ;;
+}
+
+// Force underflow and inexact flags
+{ .mfb
+ nop.m 999
+ fma.s0 FR_tmp = FR_tmp,FR_tmp,f0
+ br.cond.sptk NEXT_UNDERFLOW ;;
+}
+
+NEXT_UNDERFLOW:
+// Here if result is a denorm, or input is finite and result is zero
+// Call error support to report possible range error
+{ .mib
+ alloc r32=ar.pfs,2,2,4,0
+ mov GR_Parameter_TAG = 270 // Error code
+ br.cond.sptk __libm_error_region // Branch to error call
+}
+;;
+
+NEXT_OVERFLOW:
+// Here if input is finite, but result will be infinite
+// Use frcpa to generate infinity of correct sign
+// Call error support to report possible range error
+{ .mfi
+ alloc r32=ar.pfs,2,2,4,0
+ frcpa.s1 f8,p6 = FR_save_f8, f0
+ nop.i 999 ;;
+}
+
+// Create largest double
+{ .mfi
+ nop.m 999
+ fmerge.se FR_lnorm = FR_lnorm_exp,FR_lnorm_sig
+ nop.i 999 ;;
+}
+
+// Force overflow and inexact flags to be set
+{ .mfb
+ mov GR_Parameter_TAG = 198 // Error code
+ fma.s0 FR_tmp = FR_lnorm,FR_lnorm,f0
+ br.cond.sptk __libm_error_region // Branch to error call
+}
+;;
+
+GLOBAL_LIBM_END(nexttowardl)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+
+// (2)
+{ .mmi
+ stfe [GR_Parameter_Y] = f9,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfe [GR_Parameter_X] = FR_save_f8 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+// (4)
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_rint.S b/libc/sysdeps/ia64/fpu/s_rint.S
new file mode 100644
index 000000000..1735d9b49
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_rint.S
@@ -0,0 +1,229 @@
+.file "rint.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/08/01 Corrected behavior for all rounding modes.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// double rint(double x)
+//==============================================================
+
+// general input registers:
+// r14 - r21
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rM1 = r18
+rFpsr = r19
+rRcs0 = r20
+rRcs0Mask = r21
+
+// floating-point registers:
+// f8 - f11
+
+fXInt = f9
+fNormX = f10
+fTmp = f11
+
+// predicate registers used:
+// p6 - p10
+
+// Overview of operation
+//==============================================================
+// double rint(double x)
+// Return an integer value (represented as a double) that is x
+// rounded to integer in current rounding mode
+// Inexact is set if x != rint(x)
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+.section .text
+GLOBAL_IEEE754_ENTRY(rint)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ addl rBigexp = 0x10033, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rM1 = -1 // Set all ones
+ fcvt.fx.s1 fXInt = f8 // Convert to int in significand
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ mov rFpsr = ar40 // Read fpsr -- check rc.s0
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+ nop.i 0
+}
+{ .mfb
+ setf.sig fTmp = rM1 // Make const for setting inexact
+ fnorm.s1 fNormX = f8 // Normalize input
+(p7) br.cond.spnt RINT_UNORM // Branch if x unorm
+}
+;;
+
+
+RINT_COMMON:
+// Return here from RINT_UNORM
+{ .mfb
+ and rExp = rSignexp, rExpMask // Get biased exponent
+(p6) fma.d.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ mov rRcs0Mask = 0x0c00 // Mask for rc.s0
+ fcvt.xf f8 = fXInt // Result assume |x| < 2^52
+ cmp.ge p7,p8 = rExp, rBigexp // Is |x| >= 2^52?
+}
+;;
+
+// We must correct result if |x| >= 2^52
+{ .mfi
+ nop.m 0
+(p7) fma.d.s0 f8 = fNormX, f1, f0 // If |x| >= 2^52, result x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.unc.s1 p0, p9 = f8, fNormX // Is result = x ?
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fmerge.s f8 = fNormX, f8 // Make sure sign rint(x) = sign x
+ nop.i 0
+}
+;;
+
+{ .mfi
+(p8) and rRcs0 = rFpsr, rRcs0Mask // Get rounding mode for sf0
+ nop.f 0
+ nop.i 0
+}
+;;
+
+// If |x| < 2^52 we must test for other rounding modes
+{ .mfi
+(p8) cmp.ne.unc p10,p0 = rRcs0, r0 // Test for other rounding modes
+(p9) fmpy.s0 fTmp = fTmp, fTmp // Dummy to set inexact
+ nop.i 0
+}
+{ .mbb
+ nop.m 0
+(p10) br.cond.spnt RINT_NOT_ROUND_NEAREST // Branch if not round nearest
+ br.ret.sptk b0 // Exit main path if round nearest
+}
+;;
+
+
+
+RINT_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk RINT_COMMON // Return to main path
+}
+;;
+
+RINT_NOT_ROUND_NEAREST:
+// Here if not round to nearest, and |x| < 2^52
+// Set rounding mode of s2 to that of s0, and repeat the conversion using s2
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7f, 0x40
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.fx.s2 fXInt = fNormX // Convert to int in significand
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf f8 = fXInt // Expected result
+ nop.i 0
+}
+;;
+
+// Be sure sign of result = sign of input. Fixes cases where result is 0.
+{ .mfb
+ nop.m 0
+ fmerge.s f8 = fNormX, f8
+ br.ret.sptk b0 // Exit main path
+}
+;;
+
+GLOBAL_IEEE754_END(rint)
diff --git a/libc/sysdeps/ia64/fpu/s_rintf.S b/libc/sysdeps/ia64/fpu/s_rintf.S
new file mode 100644
index 000000000..05d6b411f
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_rintf.S
@@ -0,0 +1,229 @@
+.file "rintf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/08/01 Corrected behavior for all rounding modes.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// float rintf(float x)
+//==============================================================
+
+// general input registers:
+// r14 - r21
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rM1 = r18
+rFpsr = r19
+rRcs0 = r20
+rRcs0Mask = r21
+
+// floating-point registers:
+// f8 - f11
+
+fXInt = f9
+fNormX = f10
+fTmp = f11
+
+// predicate registers used:
+// p6 - p10
+
+// Overview of operation
+//==============================================================
+// float rintf(float x)
+// Return an integer value (represented as a float) that is x
+// rounded to integer in current rounding mode
+// Inexact is set if x != rint(x)
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+.section .text
+GLOBAL_IEEE754_ENTRY(rintf)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ addl rBigexp = 0x10016, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rM1 = -1 // Set all ones
+ fcvt.fx.s1 fXInt = f8 // Convert to int in significand
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ mov rFpsr = ar40 // Read fpsr -- check rc.s0
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+ nop.i 0
+}
+{ .mfb
+ setf.sig fTmp = rM1 // Make const for setting inexact
+ fnorm.s1 fNormX = f8 // Normalize input
+(p7) br.cond.spnt RINT_UNORM // Branch if x unorm
+}
+;;
+
+
+RINT_COMMON:
+// Return here from RINT_UNORM
+{ .mfb
+ and rExp = rSignexp, rExpMask // Get biased exponent
+(p6) fma.s.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ mov rRcs0Mask = 0x0c00 // Mask for rc.s0
+ fcvt.xf f8 = fXInt // Result assume |x| < 2^23
+ cmp.ge p7,p8 = rExp, rBigexp // Is |x| >= 2^23?
+}
+;;
+
+// We must correct result if |x| >= 2^23
+{ .mfi
+ nop.m 0
+(p7) fma.s.s0 f8 = fNormX, f1, f0 // If |x| >= 2^23, result x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.unc.s1 p0, p9 = f8, fNormX // Is result = x ?
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fmerge.s f8 = fNormX, f8 // Make sure sign rint(x) = sign x
+ nop.i 0
+}
+;;
+
+{ .mfi
+(p8) and rRcs0 = rFpsr, rRcs0Mask // Get rounding mode for sf0
+ nop.f 0
+ nop.i 0
+}
+;;
+
+// If |x| < 2^23 we must test for other rounding modes
+{ .mfi
+(p8) cmp.ne.unc p10,p0 = rRcs0, r0 // Test for other rounding modes
+(p9) fmpy.s0 fTmp = fTmp, fTmp // Dummy to set inexact
+ nop.i 0
+}
+{ .mbb
+ nop.m 0
+(p10) br.cond.spnt RINT_NOT_ROUND_NEAREST // Branch if not round nearest
+ br.ret.sptk b0 // Exit main path if round nearest
+}
+;;
+
+
+
+RINT_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk RINT_COMMON // Return to main path
+}
+;;
+
+RINT_NOT_ROUND_NEAREST:
+// Here if not round to nearest, and |x| < 2^23
+// Set rounding mode of s2 to that of s0, and repeat the conversion using s2
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7f, 0x40
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.fx.s2 fXInt = fNormX // Convert to int in significand
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf f8 = fXInt // Expected result
+ nop.i 0
+}
+;;
+
+// Be sure sign of result = sign of input. Fixes cases where result is 0.
+{ .mfb
+ nop.m 0
+ fmerge.s f8 = fNormX, f8
+ br.ret.sptk b0 // Exit main path
+}
+;;
+
+GLOBAL_IEEE754_END(rintf)
diff --git a/libc/sysdeps/ia64/fpu/s_rintl.S b/libc/sysdeps/ia64/fpu/s_rintl.S
new file mode 100644
index 000000000..b5402149e
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_rintl.S
@@ -0,0 +1,229 @@
+.file "rintl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/08/01 Corrected behavior for all rounding modes.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// long double rintl(long double x)
+//==============================================================
+
+// general input registers:
+// r14 - r21
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rM1 = r18
+rFpsr = r19
+rRcs0 = r20
+rRcs0Mask = r21
+
+// floating-point registers:
+// f8 - f11
+
+fXInt = f9
+fNormX = f10
+fTmp = f11
+
+// predicate registers used:
+// p6 - p10
+
+// Overview of operation
+//==============================================================
+// long double rintl(long double x)
+// Return an integer value (represented as a long double) that is x
+// rounded to integer in current rounding mode
+// Inexact is set if x != rint(x)
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+.section .text
+GLOBAL_IEEE754_ENTRY(rintl)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ addl rBigexp = 0x1003e, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rM1 = -1 // Set all ones
+ fcvt.fx.s1 fXInt = f8 // Convert to int in significand
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ mov rFpsr = ar40 // Read fpsr -- check rc.s0
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+ nop.i 0
+}
+{ .mfb
+ setf.sig fTmp = rM1 // Make const for setting inexact
+ fnorm.s1 fNormX = f8 // Normalize input
+(p7) br.cond.spnt RINT_UNORM // Branch if x unorm
+}
+;;
+
+
+RINT_COMMON:
+// Return here from RINT_UNORM
+{ .mfb
+ and rExp = rSignexp, rExpMask // Get biased exponent
+(p6) fma.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ mov rRcs0Mask = 0x0c00 // Mask for rc.s0
+ fcvt.xf f8 = fXInt // Result assume |x| < 2^63
+ cmp.ge p7,p8 = rExp, rBigexp // Is |x| >= 2^63?
+}
+;;
+
+// We must correct result if |x| >= 2^63
+{ .mfi
+ nop.m 0
+(p7) fma.s0 f8 = fNormX, f1, f0 // If |x| >= 2^63, result x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.eq.unc.s1 p0, p9 = f8, fNormX // Is result = x ?
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fmerge.s f8 = fNormX, f8 // Make sure sign rint(x) = sign x
+ nop.i 0
+}
+;;
+
+{ .mfi
+(p8) and rRcs0 = rFpsr, rRcs0Mask // Get rounding mode for sf0
+ nop.f 0
+ nop.i 0
+}
+;;
+
+// If |x| < 2^63 we must test for other rounding modes
+{ .mfi
+(p8) cmp.ne.unc p10,p0 = rRcs0, r0 // Test for other rounding modes
+(p9) fmpy.s0 fTmp = fTmp, fTmp // Dummy to set inexact
+ nop.i 0
+}
+{ .mbb
+ nop.m 0
+(p10) br.cond.spnt RINT_NOT_ROUND_NEAREST // Branch if not round nearest
+ br.ret.sptk b0 // Exit main path if round nearest
+}
+;;
+
+
+
+RINT_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk RINT_COMMON // Return to main path
+}
+;;
+
+RINT_NOT_ROUND_NEAREST:
+// Here if not round to nearest, and |x| < 2^63
+// Set rounding mode of s2 to that of s0, and repeat the conversion using s2
+{ .mfi
+ nop.m 0
+ fsetc.s2 0x7f, 0x40
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.fx.s2 fXInt = fNormX // Convert to int in significand
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf f8 = fXInt // Expected result
+ nop.i 0
+}
+;;
+
+// Be sure sign of result = sign of input. Fixes cases where result is 0.
+{ .mfb
+ nop.m 0
+ fmerge.s f8 = fNormX, f8
+ br.ret.sptk b0 // Exit main path
+}
+;;
+
+GLOBAL_IEEE754_END(rintl)
diff --git a/libc/sysdeps/ia64/fpu/s_round.S b/libc/sysdeps/ia64/fpu/s_round.S
new file mode 100644
index 000000000..ed5ffae20
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_round.S
@@ -0,0 +1,233 @@
+.file "round.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 10/25/00 Initial version
+// 06/14/01 Changed cmp to an equivalent form
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance and reduced code size
+// 04/18/03 Eliminate possible WAW dependency warning
+// 09/03/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// double round(double x)
+//==============================================================
+
+// general input registers:
+// r14 - r18
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rExpHalf = r18
+
+// floating-point registers:
+// f8 - f13
+
+fXtruncInt = f9
+fNormX = f10
+fHalf = f11
+fInc = f12
+fRem = f13
+
+// predicate registers used:
+// p6 - p10
+
+// Overview of operation
+//==============================================================
+// double round(double x)
+// Return an integer value (represented as a double) that is x
+// rounded to nearest integer, halfway cases rounded away from
+// zero.
+// if x>0 result = trunc(x+0.5)
+// if x<0 result = trunc(x-0.5)
+//
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(round)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fcvt.fx.trunc.s1 fXtruncInt = f8 // Convert to int in significand
+ addl rBigexp = 0x10033, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rExpHalf = 0x0FFFE // Form sign and exponent of 0.5
+ fnorm.s1 fNormX = f8 // Normalize input
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ setf.exp fHalf = rExpHalf // Form 0.5
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+(p7) br.cond.spnt ROUND_UNORM // Branch if x unorm
+}
+;;
+
+ROUND_COMMON:
+// Return here from ROUND_UNORM
+{ .mfb
+ nop.m 0
+ fcmp.lt.s1 p8,p9 = f8, f0 // Test if x < 0
+(p6) br.cond.spnt ROUND_SPECIAL // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf f8 = fXtruncInt // Pre-Result if 0.5 <= |x| < 2^52
+ nop.i 0
+}
+;;
+
+{ .mfi
+ and rExp = rSignexp, rExpMask // Get biased exponent
+ fmerge.s fInc = fNormX, f1 // Form increment if |rem| >= 0.5
+ nop.i 0
+}
+;;
+
+{ .mmi
+ cmp.lt p6,p0 = rExp, rExpHalf // Is |x| < 0.5?
+ cmp.ge p7,p0 = rExp, rBigexp // Is |x| >= 2^52?
+ cmp.lt p10,p0 = rExp, rExpHalf // Is |x| < 0.5?
+}
+;;
+
+// We must correct result if |x| < 0.5, or |x| >= 2^52
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fmerge.s f8 = fNormX, f0 // If |x| < 0.5, result sgn(x)*0
+ nop.i 0
+}
+{ .mfb
+(p7) cmp.eq p10,p0 = r0, r0 // Also turn on p10 if |x| >= 2^52
+(p7) fma.d.s0 f8 = fNormX, f1, f0 // If |x| >= 2^52, result x
+(p10) br.ret.spnt b0 // Exit |x| < 0.5 or |x| >= 2^52
+}
+;;
+
+// Here if 0.5 <= |x| < 2^52
+{ .mfi
+ nop.m 0
+(p9) fms.s1 fRem = fNormX, f1, f8 // Get remainder = x - trunc(x)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fms.s1 fRem = f8, f1, fNormX // Get remainder = trunc(x) - x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p9,p0 = fRem, fHalf // Test |rem| >= 0.5
+ nop.i 0
+}
+;;
+
+// If x < 0 and remainder <= -0.5, then subtract 1 from result
+// If x > 0 and remainder >= +0.5, then add 1 to result
+{ .mfb
+ nop.m 0
+(p9) fma.d.s0 f8 = f8, f1, fInc
+ br.ret.sptk b0
+}
+;;
+
+
+ROUND_SPECIAL:
+// Here if x natval, nan, inf
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = f8, f1, f0
+ br.ret.sptk b0
+}
+;;
+
+ROUND_UNORM:
+// Here if x unorm
+{ .mfi
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fcvt.fx.trunc.s1 fXtruncInt = fNormX // Convert to int in significand
+ br.cond.sptk ROUND_COMMON // Return to main path
+}
+;;
+
+GLOBAL_LIBM_END(round)
diff --git a/libc/sysdeps/ia64/fpu/s_roundf.S b/libc/sysdeps/ia64/fpu/s_roundf.S
new file mode 100644
index 000000000..7cec860aa
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_roundf.S
@@ -0,0 +1,233 @@
+.file "roundf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 10/25/00 Initial version
+// 06/14/01 Changed cmp to an equivalent form
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance and reduced code size
+// 04/18/03 Eliminate possible WAW dependency warning
+// 09/03/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// float roundf(float x)
+//==============================================================
+
+// general input registers:
+// r14 - r18
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rExpHalf = r18
+
+// floating-point registers:
+// f8 - f13
+
+fXtruncInt = f9
+fNormX = f10
+fHalf = f11
+fInc = f12
+fRem = f13
+
+// predicate registers used:
+// p6 - p10
+
+// Overview of operation
+//==============================================================
+// float roundf(float x)
+// Return an integer value (represented as a float) that is x
+// rounded to nearest integer, halfway cases rounded away from
+// zero.
+// if x>0 result = trunc(x+0.5)
+// if x<0 result = trunc(x-0.5)
+//
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(roundf)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fcvt.fx.trunc.s1 fXtruncInt = f8 // Convert to int in significand
+ addl rBigexp = 0x10016, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rExpHalf = 0x0FFFE // Form sign and exponent of 0.5
+ fnorm.s1 fNormX = f8 // Normalize input
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ setf.exp fHalf = rExpHalf // Form 0.5
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+(p7) br.cond.spnt ROUND_UNORM // Branch if x unorm
+}
+;;
+
+ROUND_COMMON:
+// Return here from ROUND_UNORM
+{ .mfb
+ nop.m 0
+ fcmp.lt.s1 p8,p9 = f8, f0 // Test if x < 0
+(p6) br.cond.spnt ROUND_SPECIAL // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf f8 = fXtruncInt // Pre-Result if 0.5 <= |x| < 2^23
+ nop.i 0
+}
+;;
+
+{ .mfi
+ and rExp = rSignexp, rExpMask // Get biased exponent
+ fmerge.s fInc = fNormX, f1 // Form increment if |rem| >= 0.5
+ nop.i 0
+}
+;;
+
+{ .mmi
+ cmp.lt p6,p0 = rExp, rExpHalf // Is |x| < 0.5?
+ cmp.ge p7,p0 = rExp, rBigexp // Is |x| >= 2^23?
+ cmp.lt p10,p0 = rExp, rExpHalf // Is |x| < 0.5?
+}
+;;
+
+// We must correct result if |x| < 0.5, or |x| >= 2^23
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fmerge.s f8 = fNormX, f0 // If |x| < 0.5, result sgn(x)*0
+ nop.i 0
+}
+{ .mfb
+(p7) cmp.eq p10,p0 = r0, r0 // Also turn on p10 if |x| >= 2^23
+(p7) fma.s.s0 f8 = fNormX, f1, f0 // If |x| >= 2^23, result x
+(p10) br.ret.spnt b0 // Exit |x| < 0.5 or |x| >= 2^23
+}
+;;
+
+// Here if 0.5 <= |x| < 2^23
+{ .mfi
+ nop.m 0
+(p9) fms.s1 fRem = fNormX, f1, f8 // Get remainder = x - trunc(x)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fms.s1 fRem = f8, f1, fNormX // Get remainder = trunc(x) - x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p9,p0 = fRem, fHalf // Test |rem| >= 0.5
+ nop.i 0
+}
+;;
+
+// If x < 0 and remainder <= -0.5, then subtract 1 from result
+// If x > 0 and remainder >= +0.5, then add 1 to result
+{ .mfb
+ nop.m 0
+(p9) fma.s.s0 f8 = f8, f1, fInc
+ br.ret.sptk b0
+}
+;;
+
+
+ROUND_SPECIAL:
+// Here if x natval, nan, inf
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = f8, f1, f0
+ br.ret.sptk b0
+}
+;;
+
+ROUND_UNORM:
+// Here if x unorm
+{ .mfi
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fcvt.fx.trunc.s1 fXtruncInt = fNormX // Convert to int in significand
+ br.cond.sptk ROUND_COMMON // Return to main path
+}
+;;
+
+GLOBAL_LIBM_END(roundf)
diff --git a/libc/sysdeps/ia64/fpu/s_roundl.S b/libc/sysdeps/ia64/fpu/s_roundl.S
new file mode 100644
index 000000000..da6cbfe22
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_roundl.S
@@ -0,0 +1,233 @@
+.file "roundl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 10/25/00 Initial version
+// 06/14/01 Changed cmp to an equivalent form
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance and reduced code size
+// 04/18/03 Eliminate possible WAW dependency warning
+// 09/03/03 Improved performance
+//==============================================================
+
+// API
+//==============================================================
+// long double roundl(long double x)
+//==============================================================
+
+// general input registers:
+// r14 - r18
+
+rSignexp = r14
+rExp = r15
+rExpMask = r16
+rBigexp = r17
+rExpHalf = r18
+
+// floating-point registers:
+// f8 - f13
+
+fXtruncInt = f9
+fNormX = f10
+fHalf = f11
+fInc = f12
+fRem = f13
+
+// predicate registers used:
+// p6 - p10
+
+// Overview of operation
+//==============================================================
+// long double roundl(long double x)
+// Return an integer value (represented as a long double) that is x
+// rounded to nearest integer, halfway cases rounded away from
+// zero.
+// if x>0 result = trunc(x+0.5)
+// if x<0 result = trunc(x-0.5)
+//
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(roundl)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fcvt.fx.trunc.s1 fXtruncInt = f8 // Convert to int in significand
+ addl rBigexp = 0x1003e, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rExpHalf = 0x0FFFE // Form sign and exponent of 0.5
+ fnorm.s1 fNormX = f8 // Normalize input
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ setf.exp fHalf = rExpHalf // Form 0.5
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+(p7) br.cond.spnt ROUND_UNORM // Branch if x unorm
+}
+;;
+
+ROUND_COMMON:
+// Return here from ROUND_UNORM
+{ .mfb
+ nop.m 0
+ fcmp.lt.s1 p8,p9 = f8, f0 // Test if x < 0
+(p6) br.cond.spnt ROUND_SPECIAL // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcvt.xf f8 = fXtruncInt // Pre-Result if 0.5 <= |x| < 2^63
+ nop.i 0
+}
+;;
+
+{ .mfi
+ and rExp = rSignexp, rExpMask // Get biased exponent
+ fmerge.s fInc = fNormX, f1 // Form increment if |rem| >= 0.5
+ nop.i 0
+}
+;;
+
+{ .mmi
+ cmp.lt p6,p0 = rExp, rExpHalf // Is |x| < 0.5?
+ cmp.ge p7,p0 = rExp, rBigexp // Is |x| >= 2^63?
+ cmp.lt p10,p0 = rExp, rExpHalf // Is |x| < 0.5?
+}
+;;
+
+// We must correct result if |x| < 0.5, or |x| >= 2^63
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fmerge.s f8 = fNormX, f0 // If |x| < 0.5, result sgn(x)*0
+ nop.i 0
+}
+{ .mfb
+(p7) cmp.eq p10,p0 = r0, r0 // Also turn on p10 if |x| >= 2^63
+(p7) fma.s0 f8 = fNormX, f1, f0 // If |x| >= 2^63, result x
+(p10) br.ret.spnt b0 // Exit |x| < 0.5 or |x| >= 2^63
+}
+;;
+
+// Here if 0.5 <= |x| < 2^63
+{ .mfi
+ nop.m 0
+(p9) fms.s1 fRem = fNormX, f1, f8 // Get remainder = x - trunc(x)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fms.s1 fRem = f8, f1, fNormX // Get remainder = trunc(x) - x
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fcmp.ge.s1 p9,p0 = fRem, fHalf // Test |rem| >= 0.5
+ nop.i 0
+}
+;;
+
+// If x < 0 and remainder <= -0.5, then subtract 1 from result
+// If x > 0 and remainder >= +0.5, then add 1 to result
+{ .mfb
+ nop.m 0
+(p9) fma.s0 f8 = f8, f1, fInc
+ br.ret.sptk b0
+}
+;;
+
+
+ROUND_SPECIAL:
+// Here if x natval, nan, inf
+{ .mfb
+ nop.m 0
+ fma.s0 f8 = f8, f1, f0
+ br.ret.sptk b0
+}
+;;
+
+ROUND_UNORM:
+// Here if x unorm
+{ .mfi
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fcvt.fx.trunc.s1 fXtruncInt = fNormX // Convert to int in significand
+ br.cond.sptk ROUND_COMMON // Return to main path
+}
+;;
+
+GLOBAL_LIBM_END(roundl)
diff --git a/libc/sysdeps/ia64/fpu/s_scalblnf.c b/libc/sysdeps/ia64/fpu/s_scalblnf.c
new file mode 100644
index 000000000..2fa51ba11
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_scalblnf.c
@@ -0,0 +1,61 @@
+/* file: scalblnf.c */
+
+
+// Copyright (c) 2000, 2001, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+#include "libm_support.h"
+
+float __libm_scalblnf(float, long int, int);
+
+
+float scalblnf(float x, long int n)
+{
+
+#ifdef SIZE_LONG_INT_64
+ return __libm_scalblnf(x,n,1);
+#else
+
+#ifdef SIZE_LONG_INT_32
+ return __libm_scalblnf(x,n,0);
+#endif
+
+#endif
+
+}
diff --git a/libc/sysdeps/ia64/fpu/s_scalbn.c b/libc/sysdeps/ia64/fpu/s_scalbn.c
new file mode 100644
index 000000000..1f5714131
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_scalbn.c
@@ -0,0 +1,61 @@
+/* file: scalbn.c */
+
+
+// Copyright (c) 2000, 2001, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+#include "libm_support.h"
+
+double __libm_scalbn(double, int, int);
+
+
+double scalbn(double x, int n)
+{
+
+#ifdef SIZE_INT_64
+ return __libm_scalbn(x,n,1);
+#else
+
+#ifdef SIZE_INT_32
+ return __libm_scalbn(x,n,0);
+#endif
+
+#endif
+
+}
diff --git a/libc/sysdeps/ia64/fpu/s_scalbnf.c b/libc/sysdeps/ia64/fpu/s_scalbnf.c
new file mode 100644
index 000000000..97c06da08
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_scalbnf.c
@@ -0,0 +1,61 @@
+/* file: scalbnf.c */
+
+
+// Copyright (c) 2000, 2001, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+#include "libm_support.h"
+
+float __libm_scalbnf(float, int, int);
+
+
+float scalbnf(float x, int n)
+{
+
+#ifdef SIZE_INT_64
+ return __libm_scalbnf(x,n,1);
+#else
+
+#ifdef SIZE_INT_32
+ return __libm_scalbnf(x,n,0);
+#endif
+
+#endif
+
+}
diff --git a/libc/sysdeps/ia64/fpu/s_scalbnl.c b/libc/sysdeps/ia64/fpu/s_scalbnl.c
new file mode 100644
index 000000000..d7a81dfc5
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_scalbnl.c
@@ -0,0 +1,61 @@
+/* file: scalbnl.c */
+
+
+// Copyright (c) 2000, 2001, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+#include "libm_support.h"
+
+long double __libm_scalbnl(long double, int, int);
+
+
+long double scalbnl(long double x, int n)
+{
+
+#ifdef SIZE_INT_64
+ return __libm_scalbnl(x,n,1);
+#else
+
+#ifdef SIZE_INT_32
+ return __libm_scalbnl(x,n,0);
+#endif
+
+#endif
+
+}
diff --git a/libc/sysdeps/ia64/fpu/s_signbit.S b/libc/sysdeps/ia64/fpu/s_signbit.S
new file mode 100644
index 000000000..5703080fd
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_signbit.S
@@ -0,0 +1,37 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#undef ret
+
+ENTRY (__signbit)
+{
+.mfi
+ fclass.m p6, p7 = farg0, @zero | @unorm | @norm | @inf | @neg
+ ;;
+}
+{
+.mib
+(p6) mov ret0 = 1
+(p7) mov ret0 = 0
+ br.ret.sptk.many rp
+}
+END (__signbit)
+
+strong_alias (__signbit, __signbitf)
+strong_alias (__signbit, __signbitl)
diff --git a/libc/sysdeps/ia64/fpu/s_signbitf.S b/libc/sysdeps/ia64/fpu/s_signbitf.S
new file mode 100644
index 000000000..34eadfca3
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_signbitf.S
@@ -0,0 +1 @@
+/* __signbitf is in s_signbit.S. */
diff --git a/libc/sysdeps/ia64/fpu/s_signbitl.S b/libc/sysdeps/ia64/fpu/s_signbitl.S
new file mode 100644
index 000000000..52d767852
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_signbitl.S
@@ -0,0 +1 @@
+/* __signbitl is in s_signbit.S. */
diff --git a/libc/sysdeps/ia64/fpu/s_significand.S b/libc/sysdeps/ia64/fpu/s_significand.S
new file mode 100644
index 000000000..720e043e5
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_significand.S
@@ -0,0 +1,153 @@
+.file "significand.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 05/31/00 Fixed bug when x a double-extended denormal
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// double significand(double x)
+//
+// Overview of operation
+//==============================================================
+// If x = sig * 2**n with 1 <= sig < 2
+// significand returns sig
+//
+// predicate registers used:
+// p6, p7
+//
+// floating-point registers used:
+// f8, f9, f10
+
+.section .text
+GLOBAL_LIBM_ENTRY(significand)
+
+// qnan snan inf norm unorm 0 -+
+// 1 1 1 0 0 1 11
+
+// f10 gets f8(sign) with f1(exp,significand)
+{ .mfi
+ nop.m 999
+ fmerge.s f10 = f8,f1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnorm.s0 f9 = f8
+ nop.i 999 ;;
+}
+
+// Test for denormal input
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f8, 0x0b
+ nop.i 999 ;;
+}
+
+// p6 = TRUE ==> x is not (nan,inf,0)
+// return sign(f8) exp(f1) significand(f8)
+// else x is (nan,inf,0)
+// return sign(f8) exp(f8) significand(f8), normalized.
+{ .mfi
+ nop.m 999
+ fclass.m.unc p0,p6 = f8, 0xe7
+ nop.i 999 ;;
+}
+
+{ .mmb
+ nop.m 999
+ nop.m 999
+(p7) br.cond.spnt SIGNIFICAND_DENORM ;; // Branch if x denormal
+}
+
+{ .mfi
+ nop.m 999
+(p6) fmerge.se f8 = f10,f8
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fnorm.d.s0 f8 = f8
+ br.ret.sptk b0 ;;
+}
+
+SIGNIFICAND_DENORM:
+// Here if x denorm
+{ .mfi
+ nop.m 999
+ fmerge.se f8 = f10,f9
+ nop.i 999 ;;
+}
+
+// Check if fnorm(x) still denormal, means x double-extended denormal
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f9, 0x0b
+ nop.i 999 ;;
+}
+
+// This will be the final result unless x double-extended denormal
+{ .mfi
+ nop.m 999
+ fnorm.d.s0 f8 = f8
+ nop.i 999 ;;
+}
+
+// If x double-extended denorm, then significand ok, but must merge in
+// correct signexp
+{ .mfi
+ nop.m 999
+(p7) fmerge.se f8 = f10,f8
+ nop.i 999 ;;
+}
+
+// Final normalization if x double-extended denorm
+{ .mfb
+ nop.m 999
+(p7) fnorm.d.s0 f8 = f8
+ br.ret.sptk b0 ;;
+}
+
+GLOBAL_LIBM_END(significand)
diff --git a/libc/sysdeps/ia64/fpu/s_significandf.S b/libc/sysdeps/ia64/fpu/s_significandf.S
new file mode 100644
index 000000000..5c8299b94
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_significandf.S
@@ -0,0 +1,152 @@
+.file "significandf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/03/00 Modified to improve speed
+// 05/31/00 Fixed bug when x a double-extended denormal
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// float significandf(float x)
+// Overview of operation
+//==============================================================
+// If x = sig * 2**n with 1 <= sig < 2
+// significandf returns sig
+//
+// predicate registers used:
+// p6, p7
+//
+// floating-point registers used:
+// f8, f9, f10
+
+.section .text
+GLOBAL_LIBM_ENTRY(significandf)
+
+// qnan snan inf norm unorm 0 -+
+// 1 1 1 0 0 1 11
+
+// f10 gets f8(sign) with f1(exp,significand)
+{ .mfi
+ nop.m 999
+ fmerge.s f10 = f8,f1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnorm.s0 f9 = f8
+ nop.i 999 ;;
+}
+
+// Test for denormal input
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f8, 0x0b
+ nop.i 999 ;;
+}
+
+// p6 = TRUE ==> x is not (nan,inf,0)
+// return sign(f8) exp(f1) significand(f8)
+// else x is (nan,inf,0)
+// return sign(f8) exp(f8) significand(f8), normalized.
+{ .mfi
+ nop.m 999
+ fclass.m.unc p0,p6 = f8, 0xe7
+ nop.i 999 ;;
+}
+
+{ .mmb
+ nop.m 999
+ nop.m 999
+(p7) br.cond.spnt SIGNIFICAND_DENORM ;; // Branch if x denormal
+}
+
+{ .mfi
+ nop.m 999
+(p6) fmerge.se f8 = f10,f8
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fnorm.s.s0 f8 = f8
+ br.ret.sptk b0 ;;
+}
+
+SIGNIFICAND_DENORM:
+// Here if x denorm
+{ .mfi
+ nop.m 999
+ fmerge.se f8 = f10,f9
+ nop.i 999 ;;
+}
+
+// Check if fnorm(x) still denormal, means x double-extended denormal
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f9, 0x0b
+ nop.i 999 ;;
+}
+
+// This will be the final result unless x double-extended denormal
+{ .mfi
+ nop.m 999
+ fnorm.s.s0 f8 = f8
+ nop.i 999 ;;
+}
+
+// If x double-extended denorm, then significand ok, but must merge in
+// correct signexp
+{ .mfi
+ nop.m 999
+(p7) fmerge.se f8 = f10,f8
+ nop.i 999 ;;
+}
+
+// Final normalization if x double-extended denorm
+{ .mfb
+ nop.m 999
+(p7) fnorm.s.s0 f8 = f8
+ br.ret.sptk b0 ;;
+}
+
+GLOBAL_LIBM_END(significandf)
diff --git a/libc/sysdeps/ia64/fpu/s_significandl.S b/libc/sysdeps/ia64/fpu/s_significandl.S
new file mode 100644
index 000000000..f62df4310
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_significandl.S
@@ -0,0 +1,153 @@
+.file "significandl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 02/03/00 Modified to improve speed
+// 05/31/00 Fixed bug when x a double-extended denormal
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// long double significandl(long double x)
+//
+// Overview of operation
+//==============================================================
+// If x = sig * 2**n with 1 <= sig < 2
+// significandl returns sig
+//
+// predicate registers used:
+// p6, p7
+//
+// floating-point registers used:
+// f8, f9, f10
+
+.section .text
+GLOBAL_LIBM_ENTRY(significandl)
+
+// qnan snan inf norm unorm 0 -+
+// 1 1 1 0 0 1 11
+
+// f10 gets f8(sign) with f1(exp,significand)
+{ .mfi
+ nop.m 999
+ fmerge.s f10 = f8,f1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnorm.s0 f9 = f8
+ nop.i 999 ;;
+}
+
+// Test for denormal input
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f8, 0x0b
+ nop.i 999 ;;
+}
+
+// p6 = TRUE ==> x is not (nan,inf,0)
+// return sign(f8) exp(f1) significand(f8)
+// else x is (nan,inf,0)
+// return sign(f8) exp(f8) significand(f8), normalized.
+{ .mfi
+ nop.m 999
+ fclass.m.unc p0,p6 = f8, 0xe7
+ nop.i 999 ;;
+}
+
+{ .mmb
+ nop.m 999
+ nop.m 999
+(p7) br.cond.spnt SIGNIFICAND_DENORM ;; // Branch if x denormal
+}
+
+{ .mfi
+ nop.m 999
+(p6) fmerge.se f8 = f10,f8
+ nop.i 999 ;;
+}
+
+{ .mfb
+ nop.m 999
+ fnorm.s0 f8 = f8
+ br.ret.sptk b0 ;;
+}
+
+SIGNIFICAND_DENORM:
+// Here if x denorm
+{ .mfi
+ nop.m 999
+ fmerge.se f8 = f10,f9
+ nop.i 999 ;;
+}
+
+// Check if fnorm(x) still denormal, means x double-extended denormal
+{ .mfi
+ nop.m 999
+ fclass.m.unc p7,p0 = f9, 0x0b
+ nop.i 999 ;;
+}
+
+// This will be the final result unless x double-extended denormal
+{ .mfi
+ nop.m 999
+ fnorm.s0 f8 = f8
+ nop.i 999 ;;
+}
+
+// If x double-extended denorm, then significand ok, but must merge in
+// correct signexp
+{ .mfi
+ nop.m 999
+(p7) fmerge.se f8 = f10,f8
+ nop.i 999 ;;
+}
+
+// Final normalization if x double-extended denorm
+{ .mfb
+ nop.m 999
+(p7) fnorm.s0 f8 = f8
+ br.ret.sptk b0 ;;
+}
+
+GLOBAL_LIBM_END(significandl)
diff --git a/libc/sysdeps/ia64/fpu/s_sin.c b/libc/sysdeps/ia64/fpu/s_sin.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_sin.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/s_sincos.c b/libc/sysdeps/ia64/fpu/s_sincos.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_sincos.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/s_sincosf.c b/libc/sysdeps/ia64/fpu/s_sincosf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_sincosf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/s_sincosl.c b/libc/sysdeps/ia64/fpu/s_sincosl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_sincosl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/s_sinf.c b/libc/sysdeps/ia64/fpu/s_sinf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_sinf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/s_sinl.c b/libc/sysdeps/ia64/fpu/s_sinl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_sinl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/s_tan.S b/libc/sysdeps/ia64/fpu/s_tan.S
new file mode 100644
index 000000000..a2f80c885
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_tan.S
@@ -0,0 +1,878 @@
+.file "tancot.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 12/27/00 Improved speed
+// 02/21/01 Updated to call tanl
+// 05/30/02 Added cot
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// double tan(double x);
+// double cot(double x);
+//
+// Overview of operation
+//==============================================================
+// If the input value in radians is |x| >= 1.xxxxx 2^10 call the
+// older slower version.
+//
+// The new algorithm is used when |x| <= 1.xxxxx 2^9.
+//
+// Represent the input X as Nfloat * pi/2 + r
+// where r can be negative and |r| <= pi/4
+//
+// tan_W = x * 2/pi
+// Nfloat = round_int(tan_W)
+//
+// tan_r = x - Nfloat * (pi/2)_hi
+// a) tan_r = tan_r - Nfloat * (pi/2)_lo (for tan)
+// b) tan_r = Nfloat * (pi/2)_lo - tan_r (for cot)
+//
+// We have two paths: p8, when Nfloat is even and p9. when Nfloat is odd.
+// a) for tan: p8: tan(X) = tan(r)
+// p9: tan(X) = -cot(r)
+// b) for cot: p9: cot(X) = cot(r)
+// p8: cot(X) = -tan(r)
+//
+// Each is evaluated as a series. The p9 path requires 1/r.
+//
+// The coefficients used in the series are stored in a table as
+// are the pi constants.
+//
+// Registers used
+//==============================================================
+//
+// predicate registers used:
+// p6-12
+//
+// floating-point registers used:
+// f10-15, f32-106
+// f8, input
+//
+// general registers used
+// r14-26, r32-39
+//
+// Assembly macros
+//==============================================================
+TAN_INV_PI_BY_2_2TO64 = f10
+TAN_RSHF_2TO64 = f11
+TAN_2TOM64 = f12
+TAN_RSHF = f13
+TAN_W_2TO64_RSH = f14
+TAN_NFLOAT = f15
+
+tan_Inv_Pi_by_2 = f32
+tan_Pi_by_2_hi = f33
+tan_Pi_by_2_lo = f34
+
+
+tan_P0 = f35
+tan_P1 = f36
+tan_P2 = f37
+tan_P3 = f38
+tan_P4 = f39
+tan_P5 = f40
+tan_P6 = f41
+tan_P7 = f42
+tan_P8 = f43
+tan_P9 = f44
+tan_P10 = f45
+tan_P11 = f46
+tan_P12 = f47
+tan_P13 = f48
+tan_P14 = f49
+tan_P15 = f50
+
+tan_Q0 = f51
+tan_Q1 = f52
+tan_Q2 = f53
+tan_Q3 = f54
+tan_Q4 = f55
+tan_Q5 = f56
+tan_Q6 = f57
+tan_Q7 = f58
+tan_Q8 = f59
+tan_Q9 = f60
+tan_Q10 = f61
+
+tan_r = f62
+tan_rsq = f63
+tan_rcube = f64
+
+tan_v18 = f65
+tan_v16 = f66
+tan_v17 = f67
+tan_v12 = f68
+tan_v13 = f69
+tan_v7 = f70
+tan_v8 = f71
+tan_v4 = f72
+tan_v5 = f73
+tan_v15 = f74
+tan_v11 = f75
+tan_v14 = f76
+tan_v3 = f77
+tan_v6 = f78
+tan_v10 = f79
+tan_v2 = f80
+tan_v9 = f81
+tan_v1 = f82
+tan_int_Nfloat = f83
+tan_Nfloat = f84
+
+tan_NORM_f8 = f85
+tan_W = f86
+
+tan_y0 = f87
+tan_d = f88
+tan_y1 = f89
+tan_dsq = f90
+tan_y2 = f91
+tan_d4 = f92
+tan_inv_r = f93
+
+tan_z1 = f94
+tan_z2 = f95
+tan_z3 = f96
+tan_z4 = f97
+tan_z5 = f98
+tan_z6 = f99
+tan_z7 = f100
+tan_z8 = f101
+tan_z9 = f102
+tan_z10 = f103
+tan_z11 = f104
+tan_z12 = f105
+
+arg_copy = f106
+
+/////////////////////////////////////////////////////////////
+
+tan_GR_sig_inv_pi_by_2 = r14
+tan_GR_rshf_2to64 = r15
+tan_GR_exp_2tom64 = r16
+tan_GR_n = r17
+tan_GR_rshf = r18
+tan_AD = r19
+tan_GR_10009 = r20
+tan_GR_17_ones = r21
+tan_GR_N_odd_even = r22
+tan_GR_N = r23
+tan_signexp = r24
+tan_exp = r25
+tan_ADQ = r26
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_Tag = r39
+
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(double_tan_constants)
+ data8 0xC90FDAA22168C234, 0x00003FFF // pi/2 hi
+ data8 0xBEEA54580DDEA0E1 // P14
+ data8 0x3ED3021ACE749A59 // P15
+ data8 0xBEF312BD91DC8DA1 // P12
+ data8 0x3EFAE9AFC14C5119 // P13
+ data8 0x3F2F342BF411E769 // P8
+ data8 0x3F1A60FC9F3B0227 // P9
+ data8 0x3EFF246E78E5E45B // P10
+ data8 0x3F01D9D2E782875C // P11
+ data8 0x3F8226E34C4499B6 // P4
+ data8 0x3F6D6D3F12C236AC // P5
+ data8 0x3F57DA1146DCFD8B // P6
+ data8 0x3F43576410FE3D75 // P7
+ data8 0x3FD5555555555555 // P0
+ data8 0x3FC11111111111C2 // P1
+ data8 0x3FABA1BA1BA0E850 // P2
+ data8 0x3F9664F4886725A7 // P3
+LOCAL_OBJECT_END(double_tan_constants)
+
+LOCAL_OBJECT_START(double_Q_tan_constants)
+ data8 0xC4C6628B80DC1CD1, 0x00003FBF // pi/2 lo
+ data8 0x3E223A73BA576E48 // Q8
+ data8 0x3DF54AD8D1F2CA43 // Q9
+ data8 0x3EF66A8EE529A6AA // Q4
+ data8 0x3EC2281050410EE6 // Q5
+ data8 0x3E8D6BB992CC3CF5 // Q6
+ data8 0x3E57F88DE34832E4 // Q7
+ data8 0x3FD5555555555555 // Q0
+ data8 0x3F96C16C16C16DB8 // Q1
+ data8 0x3F61566ABBFFB489 // Q2
+ data8 0x3F2BBD77945C1733 // Q3
+ data8 0x3D927FB33E2B0E04 // Q10
+LOCAL_OBJECT_END(double_Q_tan_constants)
+
+
+.section .text
+
+////////////////////////////////////////////////////////
+
+LOCAL_LIBM_ENTRY(cot)
+// The initial fnorm will take any unmasked faults and
+// normalize any single/double unorms
+
+{ .mlx
+ cmp.eq p12, p11 = r0, r0 // set p12=1, p11=0 for cot
+ movl tan_GR_sig_inv_pi_by_2 = 0xA2F9836E4E44152A // significand of 2/pi
+}
+{ .mlx
+ addl tan_AD = @ltoff(double_tan_constants), gp
+ movl tan_GR_rshf_2to64 = 0x47e8000000000000 // 1.1000 2^(63+63+1)
+}
+;;
+
+{ .mlx
+ mov tan_GR_exp_2tom64 = 0xffff-64 // exponent of scaling factor 2^-64
+ movl tan_GR_rshf = 0x43e8000000000000 // 1.1000 2^63 for right shift
+}
+{ .mfb
+ ld8 tan_AD = [tan_AD]
+ fnorm.s0 tan_NORM_f8 = f8
+ br.cond.sptk COMMON_PATH
+}
+;;
+
+LOCAL_LIBM_END(cot)
+
+
+GLOBAL_IEEE754_ENTRY(tan)
+// The initial fnorm will take any unmasked faults and
+// normalize any single/double unorms
+
+{ .mlx
+ cmp.eq p11, p12 = r0, r0 // set p11=1, p12=0 for tan
+ movl tan_GR_sig_inv_pi_by_2 = 0xA2F9836E4E44152A // significand of 2/pi
+}
+{ .mlx
+ addl tan_AD = @ltoff(double_tan_constants), gp
+ movl tan_GR_rshf_2to64 = 0x47e8000000000000 // 1.1000 2^(63+63+1)
+}
+;;
+
+{ .mlx
+ mov tan_GR_exp_2tom64 = 0xffff-64 // exponent of scaling factor 2^-64
+ movl tan_GR_rshf = 0x43e8000000000000 // 1.1000 2^63 for right shift
+}
+{ .mfi
+ ld8 tan_AD = [tan_AD]
+ fnorm.s0 tan_NORM_f8 = f8
+ nop.i 0
+}
+;;
+
+
+// Common path for both tan and cot
+COMMON_PATH:
+// Form two constants we need
+// 2/pi * 2^1 * 2^63, scaled by 2^64 since we just loaded the significand
+// 1.1000...000 * 2^(63+63+1) to right shift int(W) into the significand
+{ .mmi
+ setf.sig TAN_INV_PI_BY_2_2TO64 = tan_GR_sig_inv_pi_by_2
+ setf.d TAN_RSHF_2TO64 = tan_GR_rshf_2to64
+ mov tan_GR_17_ones = 0x1ffff ;;
+}
+
+
+// Form another constant
+// 2^-64 for scaling Nfloat
+// 1.1000...000 * 2^63, the right shift constant
+{ .mmf
+ setf.exp TAN_2TOM64 = tan_GR_exp_2tom64
+ adds tan_ADQ = double_Q_tan_constants - double_tan_constants, tan_AD
+(p11) fclass.m.unc p6,p0 = f8, 0x07 // Test for x=0 (tan)
+}
+;;
+
+
+// Form another constant
+// 2^-64 for scaling Nfloat
+// 1.1000...000 * 2^63, the right shift constant
+{ .mmf
+ setf.d TAN_RSHF = tan_GR_rshf
+ ldfe tan_Pi_by_2_hi = [tan_AD],16
+ fclass.m.unc p7,p0 = f8, 0x23 // Test for x=inf
+}
+;;
+
+{ .mfb
+ ldfe tan_Pi_by_2_lo = [tan_ADQ],16
+ fclass.m.unc p8,p0 = f8, 0xc3 // Test for x=nan
+(p6) br.ret.spnt b0 ;; // Exit for x=0 (tan only)
+}
+
+{ .mfi
+ ldfpd tan_P14,tan_P15 = [tan_AD],16
+(p7) frcpa.s0 f8,p9=f0,f0 // Set qnan indef if x=inf
+ mov tan_GR_10009 = 0x10009
+}
+{ .mib
+ ldfpd tan_Q8,tan_Q9 = [tan_ADQ],16
+ nop.i 999
+(p7) br.ret.spnt b0 ;; // Exit for x=inf
+}
+
+{ .mfi
+ ldfpd tan_P12,tan_P13 = [tan_AD],16
+(p12) fclass.m.unc p6,p0 = f8, 0x07 // Test for x=0 (cot)
+ nop.i 999
+}
+{ .mfb
+ ldfpd tan_Q4,tan_Q5 = [tan_ADQ],16
+(p8) fma.d.s0 f8=f8,f1,f8 // Set qnan if x=nan
+(p8) br.ret.spnt b0 ;; // Exit for x=nan
+}
+
+{ .mmf
+ getf.exp tan_signexp = tan_NORM_f8
+ ldfpd tan_P8,tan_P9 = [tan_AD],16
+ fmerge.s arg_copy = f8, f8 ;; // Save input for error call
+}
+
+// Multiply x by scaled 2/pi and add large const to shift integer part of W to
+// rightmost bits of significand
+{ .mmf
+ alloc r32=ar.pfs,0,4,4,0
+ ldfpd tan_Q6,tan_Q7 = [tan_ADQ],16
+ fma.s1 TAN_W_2TO64_RSH = tan_NORM_f8,TAN_INV_PI_BY_2_2TO64,TAN_RSHF_2TO64
+};;
+
+{ .mmf
+ ldfpd tan_P10,tan_P11 = [tan_AD],16
+ and tan_exp = tan_GR_17_ones, tan_signexp
+(p6) frcpa.s0 f8, p0 = f1, f8 ;; // cot(+-0) = +-Inf
+}
+
+
+// p7 is true if we must call DBX TAN
+// p7 is true if f8 exp is > 0x10009 (which includes all ones
+// NAN or inf)
+{ .mmb
+ ldfpd tan_Q0,tan_Q1 = [tan_ADQ],16
+ cmp.ge.unc p7,p0 = tan_exp,tan_GR_10009
+(p7) br.cond.spnt TAN_DBX ;;
+}
+
+
+{ .mmb
+ ldfpd tan_P4,tan_P5 = [tan_AD],16
+(p6) mov GR_Parameter_Tag = 226 // (cot)
+(p6) br.cond.spnt __libm_error_region ;; // call error support if cot(+-0)
+}
+
+
+{ .mmi
+ ldfpd tan_Q2,tan_Q3 = [tan_ADQ],16
+ nop.m 999
+ nop.i 999 ;;
+}
+
+
+
+// TAN_NFLOAT = Round_Int_Nearest(tan_W)
+{ .mfi
+ ldfpd tan_P6,tan_P7 = [tan_AD],16
+ fms.s1 TAN_NFLOAT = TAN_W_2TO64_RSH,TAN_2TOM64,TAN_RSHF
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ ldfd tan_Q10 = [tan_ADQ]
+ nop.f 999
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ ldfpd tan_P0,tan_P1 = [tan_AD],16
+ nop.f 999
+ nop.i 999 ;;
+}
+
+
+{ .mmi
+ getf.sig tan_GR_n = TAN_W_2TO64_RSH
+ ldfpd tan_P2,tan_P3 = [tan_AD]
+ nop.i 999 ;;
+}
+
+// tan_r = -tan_Nfloat * tan_Pi_by_2_hi + x
+{ .mfi
+(p12) add tan_GR_n = 0x1, tan_GR_n // N = N + 1 (for cot)
+ fnma.s1 tan_r = TAN_NFLOAT, tan_Pi_by_2_hi, tan_NORM_f8
+ nop.i 999 ;;
+}
+
+
+// p8 ==> even
+// p9 ==> odd
+{ .mmi
+ and tan_GR_N_odd_even = 0x1, tan_GR_n ;;
+ nop.m 999
+ cmp.eq.unc p8,p9 = tan_GR_N_odd_even, r0 ;;
+}
+
+
+.pred.rel "mutex", p11, p12
+// tan_r = tan_r -tan_Nfloat * tan_Pi_by_2_lo (tan)
+{ .mfi
+ nop.m 999
+(p11) fnma.s1 tan_r = TAN_NFLOAT, tan_Pi_by_2_lo, tan_r
+ nop.i 999
+}
+// tan_r = -(tan_r -tan_Nfloat * tan_Pi_by_2_lo) (cot)
+{ .mfi
+ nop.m 999
+(p12) fms.s1 tan_r = TAN_NFLOAT, tan_Pi_by_2_lo, tan_r
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+ fma.s1 tan_rsq = tan_r, tan_r, f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p9) frcpa.s1 tan_y0, p0 = f1,tan_r
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v18 = tan_rsq, tan_P15, tan_P14
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v4 = tan_rsq, tan_P1, tan_P0
+ nop.i 999 ;;
+}
+
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v16 = tan_rsq, tan_P13, tan_P12
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v17 = tan_rsq, tan_rsq, f0
+ nop.i 999 ;;
+}
+
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v12 = tan_rsq, tan_P9, tan_P8
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v13 = tan_rsq, tan_P11, tan_P10
+ nop.i 999 ;;
+}
+
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v7 = tan_rsq, tan_P5, tan_P4
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v8 = tan_rsq, tan_P7, tan_P6
+ nop.i 999 ;;
+}
+
+
+
+{ .mfi
+ nop.m 999
+(p9) fnma.s1 tan_d = tan_r, tan_y0, f1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v5 = tan_rsq, tan_P3, tan_P2
+ nop.i 999 ;;
+}
+
+
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_z11 = tan_rsq, tan_Q9, tan_Q8
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_z12 = tan_rsq, tan_rsq, f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v15 = tan_v17, tan_v18, tan_v16
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_z7 = tan_rsq, tan_Q5, tan_Q4
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v11 = tan_v17, tan_v13, tan_v12
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_z8 = tan_rsq, tan_Q7, tan_Q6
+ nop.i 999 ;;
+}
+
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v14 = tan_v17, tan_v17, f0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_z3 = tan_rsq, tan_Q1, tan_Q0
+ nop.i 999 ;;
+}
+
+
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v3 = tan_v17, tan_v5, tan_v4
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v6 = tan_v17, tan_v8, tan_v7
+ nop.i 999 ;;
+}
+
+
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_y1 = tan_y0, tan_d, tan_y0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_dsq = tan_d, tan_d, f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_z10 = tan_z12, tan_Q10, tan_z11
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_z9 = tan_z12, tan_z12,f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_z4 = tan_rsq, tan_Q3, tan_Q2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_z6 = tan_z12, tan_z8, tan_z7
+ nop.i 999 ;;
+}
+
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v10 = tan_v14, tan_v15, tan_v11
+ nop.i 999 ;;
+}
+
+
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_y2 = tan_y1, tan_d, tan_y0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_d4 = tan_dsq, tan_dsq, tan_d
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v2 = tan_v14, tan_v6, tan_v3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v9 = tan_v14, tan_v14, f0
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_z2 = tan_z12, tan_z4, tan_z3
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_z5 = tan_z9, tan_z10, tan_z6
+ nop.i 999 ;;
+}
+
+
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_inv_r = tan_d4, tan_y2, tan_y0
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_rcube = tan_rsq, tan_r, f0
+ nop.i 999 ;;
+}
+
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.s1 tan_v1 = tan_v9, tan_v10, tan_v2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fma.s1 tan_z1 = tan_z9, tan_z5, tan_z2
+ nop.i 999 ;;
+}
+
+
+
+{ .mfi
+ nop.m 999
+(p8) fma.d.s0 f8 = tan_v1, tan_rcube, tan_r
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p9) fms.d.s0 f8 = tan_r, tan_z1, tan_inv_r
+ br.ret.sptk b0 ;;
+}
+GLOBAL_IEEE754_END(tan)
+
+
+LOCAL_LIBM_ENTRY(__libm_callout)
+TAN_DBX:
+.prologue
+
+{ .mfi
+ nop.m 0
+ fmerge.s f9 = f0,f0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs
+}
+;;
+
+{ .mfi
+ mov GR_SAVE_GP=gp
+ nop.f 0
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0
+}
+
+.body
+{ .mmb
+ nop.m 999
+ nop.m 999
+(p11) br.cond.sptk.many call_tanl ;;
+}
+
+// Here if we should call cotl
+{ .mmb
+ nop.m 999
+ nop.m 999
+ br.call.sptk.many b0=__libm_cotl# ;;
+}
+
+{ .mfi
+ mov gp = GR_SAVE_GP
+ fnorm.d.s0 f8 = f8
+ mov b0 = GR_SAVE_B0
+}
+;;
+
+{ .mib
+ nop.m 999
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+;;
+}
+
+// Here if we should call tanl
+call_tanl:
+{ .mmb
+ nop.m 999
+ nop.m 999
+ br.call.sptk.many b0=__libm_tanl# ;;
+}
+
+{ .mfi
+ mov gp = GR_SAVE_GP
+ fnorm.d.s0 f8 = f8
+ mov b0 = GR_SAVE_B0
+}
+;;
+
+{ .mib
+ nop.m 999
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+;;
+}
+
+LOCAL_LIBM_END(__libm_callout)
+
+.type __libm_tanl#,@function
+.global __libm_tanl#
+.type __libm_cotl#,@function
+.global __libm_cotl#
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+// (2)
+{ .mmi
+ stfd [GR_Parameter_Y] = f1,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfd [GR_Parameter_X] = arg_copy // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+// (4)
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_tanf.S b/libc/sysdeps/ia64/fpu/s_tanf.S
new file mode 100644
index 000000000..193d7568a
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_tanf.S
@@ -0,0 +1,692 @@
+.file "tancotf.s"
+
+
+// Copyright (c) 2000 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 02/02/00 Initial version
+// 04/04/00 Unwind support added
+// 12/27/00 Improved speed
+// 02/21/01 Updated to call tanl
+// 05/30/02 Improved speed, added cotf.
+// 11/25/02 Added explicit completer on fnorm
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 04/17/03 Eliminated redundant stop bits
+// 03/31/05 Reformatted delimiters between data tables
+//
+// APIs
+//==============================================================
+// float tanf(float)
+// float cotf(float)
+//
+// Algorithm Description for tanf
+//==============================================================
+// The tanf function computes the principle value of the tangent of x,
+// where x is radian argument.
+//
+// There are 5 paths:
+// 1. x = +/-0.0
+// Return tanf(x) = +/-0.0
+//
+// 2. x = [S,Q]NaN
+// Return tanf(x) = QNaN
+//
+// 3. x = +/-Inf
+// Return tanf(x) = QNaN
+//
+// 4. x = r + (Pi/2)*N, N = RoundInt(x*(2/Pi)), N is even, |r|<Pi/4
+// Return tanf(x) = P19(r) = A1*r + A3*r^3 + A5*r^5 + ... + A19*r^19 =
+// = r*(A1 + A3*t + A5*t^2 + ... + A19*t^9) = r*P9(t), where t = r^2
+//
+// 5. x = r + (Pi/2)*N, N = RoundInt(x*(2/Pi)), N is odd, |r|<Pi/4
+// Return tanf(x) = -1/r + P11(r) = -1/r + B1*r + B3*r^3 + ... + B11*r^11 =
+// = -1/r + r*(B1 + B3*t + B5*t^2 + ... + B11*t^5) = -1/r + r*P11(t),
+// where t = r^2
+//
+// Algorithm Description for cotf
+//==============================================================
+// The cotf function computes the principle value of the cotangent of x,
+// where x is radian argument.
+//
+// There are 5 paths:
+// 1. x = +/-0.0
+// Return cotf(x) = +/-Inf and error handling is called
+//
+// 2. x = [S,Q]NaN
+// Return cotf(x) = QNaN
+//
+// 3. x = +/-Inf
+// Return cotf(x) = QNaN
+//
+// 4. x = r + (Pi/2)*N, N = RoundInt(x*(2/Pi)), N is odd, |r|<Pi/4
+// Return cotf(x) = P19(-r) = A1*(-r) + A3*(-r^3) + ... + A19*(-r^19) =
+// = -r*(A1 + A3*t + A5*t^2 + ... + A19*t^9) = -r*P9(t), where t = r^2
+//
+// 5. x = r + (Pi/2)*N, N = RoundInt(x*(2/Pi)), N is even, |r|<Pi/4
+// Return cotf(x) = 1/r + P11(-r) = 1/r + B1*(-r) + ... + B11*(-r^11) =
+// = 1/r - r*(B1 + B3*t + B5*t^2 + ... + B11*t^5) = 1/r - r*P11(t),
+// where t = r^2
+//
+// We set p10 and clear p11 if computing tanf, vice versa for cotf.
+//
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f32 -> f80
+//
+// General registers used:
+// r14 -> r23, r32 -> r39
+//
+// Predicate registers used:
+// p6 -> p13
+//
+// Assembly macros
+//==============================================================
+// integer registers
+rExp = r14
+rSignMask = r15
+rRshf = r16
+rScFctrExp = r17
+rIntN = r18
+rSigRcpPiby2 = r19
+rScRshf = r20
+rCoeffA = r21
+rCoeffB = r22
+rExpCut = r23
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_Parameter_X = r36
+GR_Parameter_Y = r37
+GR_Parameter_RESULT = r38
+GR_Parameter_Tag = r39
+
+//==============================================================
+// floating point registers
+fScRcpPiby2 = f32
+fScRshf = f33
+fNormArg = f34
+fScFctr = f35
+fRshf = f36
+fShiftedN = f37
+fN = f38
+fR = f39
+fA01 = f40
+fA03 = f41
+fA05 = f42
+fA07 = f43
+fA09 = f44
+fA11 = f45
+fA13 = f46
+fA15 = f47
+fA17 = f48
+fA19 = f49
+fB01 = f50
+fB03 = f51
+fB05 = f52
+fB07 = f53
+fB09 = f54
+fB11 = f55
+fA03_01 = f56
+fA07_05 = f57
+fA11_09 = f58
+fA15_13 = f59
+fA19_17 = f60
+fA11_05 = f61
+fA19_13 = f62
+fA19_05 = f63
+fRbyA03_01 = f64
+fB03_01 = f65
+fB07_05 = f66
+fB11_09 = f67
+fB11_05 = f68
+fRbyB03_01 = f69
+fRbyB11_01 = f70
+fRp2 = f71
+fRp4 = f72
+fRp8 = f73
+fRp5 = f74
+fY0 = f75
+fY1 = f76
+fD = f77
+fDp2 = f78
+fInvR = f79
+fPiby2 = f80
+//==============================================================
+
+
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(coeff_A)
+data8 0x3FF0000000000000 // A1 = 1.00000000000000000000e+00
+data8 0x3FD5555556BCE758 // A3 = 3.33333334641442641606e-01
+data8 0x3FC111105C2DAE48 // A5 = 1.33333249100689099175e-01
+data8 0x3FABA1F876341060 // A7 = 5.39701122561673229739e-02
+data8 0x3F965FB86D12A38D // A9 = 2.18495194027670719750e-02
+data8 0x3F8265F62415F9D6 // A11 = 8.98353860497717439465e-03
+data8 0x3F69E3AE64CCF58D // A13 = 3.16032468108912746342e-03
+data8 0x3F63920D09D0E6F6 // A15 = 2.38897844840557235331e-03
+LOCAL_OBJECT_END(coeff_A)
+
+LOCAL_OBJECT_START(coeff_B)
+data8 0xC90FDAA22168C235, 0x3FFF // pi/2
+data8 0x3FD55555555358DB // B1 = 3.33333333326107426583e-01
+data8 0x3F96C16C252F643F // B3 = 2.22222230621336129239e-02
+data8 0x3F61566243AB3C60 // B5 = 2.11638633968606896785e-03
+data8 0x3F2BC1169BD4438B // B7 = 2.11748132564551094391e-04
+data8 0x3EF611B4CEA056A1 // B9 = 2.10467959860990200942e-05
+data8 0x3EC600F9E32194BF // B11 = 2.62305891234274186608e-06
+data8 0xBF42BA7BCC177616 // A17 =-5.71546981685324877205e-04
+data8 0x3F4F2614BC6D3BB8 // A19 = 9.50584530849832782542e-04
+LOCAL_OBJECT_END(coeff_B)
+
+
+.section .text
+
+LOCAL_LIBM_ENTRY(cotf)
+
+{ .mlx
+ getf.exp rExp = f8 // ***** Get 2ˆ17 * s + E
+ movl rSigRcpPiby2= 0xA2F9836E4E44152A // significand of 2/Pi
+}
+{ .mlx
+ addl rCoeffA = @ltoff(coeff_A), gp
+ movl rScRshf = 0x47e8000000000000 // 1.5*2^(63+63+1)
+}
+;;
+
+{ .mfi
+ alloc r32 = ar.pfs, 0, 4, 4, 0
+ fclass.m p9, p0 = f8, 0xc3 // Test for x=nan
+ cmp.eq p11, p10 = r0, r0 // if p11=1 we compute cotf
+}
+{ .mib
+ ld8 rCoeffA = [rCoeffA]
+ mov rExpCut = 0x10009 // cutoff for exponent
+ br.cond.sptk Common_Path
+}
+;;
+
+LOCAL_LIBM_END(cotf)
+
+
+GLOBAL_IEEE754_ENTRY(tanf)
+
+{ .mlx
+ getf.exp rExp = f8 // ***** Get 2ˆ17 * s + E
+ movl rSigRcpPiby2= 0xA2F9836E4E44152A // significand of 2/Pi
+}
+{ .mlx
+ addl rCoeffA = @ltoff(coeff_A), gp
+ movl rScRshf = 0x47e8000000000000 // 1.5*2^(63+63+1)
+}
+;;
+
+{ .mfi
+ alloc r32 = ar.pfs, 0, 4, 4, 0
+ fclass.m p9, p0 = f8, 0xc3 // Test for x=nan
+ cmp.eq p10, p11 = r0, r0 // if p10=1 we compute tandf
+}
+{ .mib
+ ld8 rCoeffA = [rCoeffA]
+ mov rExpCut = 0x10009 // cutoff for exponent
+ nop.b 0
+}
+;;
+
+// Below is common path for both tandf and cotdf
+Common_Path:
+{ .mfi
+ setf.sig fScRcpPiby2 = rSigRcpPiby2 // 2^(63+1)*(2/Pi)
+ fclass.m p8, p0 = f8, 0x23 // Test for x=inf
+ mov rSignMask = 0x1ffff // mask for sign bit
+}
+{ .mlx
+ setf.d fScRshf = rScRshf // 1.5*2^(63+63+1)
+ movl rRshf = 0x43e8000000000000 // 1.5 2^63 for right shift
+}
+;;
+
+{ .mfi
+ and rSignMask = rSignMask, rExp // clear sign bit
+(p10) fclass.m.unc p7, p0 = f8, 0x07 // Test for x=0 (for tanf)
+ mov rScFctrExp = 0xffff-64 // exp of scaling factor
+}
+{ .mfb
+ adds rCoeffB = coeff_B - coeff_A, rCoeffA
+(p9) fma.s.s0 f8 = f8, f1, f8 // Set qnan if x=nan
+(p9) br.ret.spnt b0 // Exit for x=nan
+}
+;;
+
+{ .mfi
+ cmp.ge p6, p0 = rSignMask, rExpCut // p6 = (E => 0x10009)
+(p8) frcpa.s0 f8, p0 = f0, f0 // Set qnan indef if x=inf
+ mov GR_Parameter_Tag = 227 // (cotf)
+}
+{ .mbb
+ ldfe fPiby2 = [rCoeffB], 16
+(p8) br.ret.spnt b0 // Exit for x=inf
+(p6) br.cond.spnt Huge_Argument // Branch if |x|>=2^10
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p11) fclass.m.unc p6, p0 = f8, 0x07 // Test for x=0 (for cotf)
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fnorm.s0 fNormArg = f8
+(p7) br.ret.spnt b0 // Exit for x=0 (for tanf)
+}
+;;
+
+{ .mmf
+ ldfpd fA01, fA03 = [rCoeffA], 16
+ ldfpd fB01, fB03 = [rCoeffB], 16
+ fmerge.s f10 = f8, f8 // Save input for error call
+}
+;;
+
+{ .mmf
+ setf.exp fScFctr = rScFctrExp // get as real
+ setf.d fRshf = rRshf // get right shifter as real
+(p6) frcpa.s0 f8, p0 = f1, f8 // cotf(+-0) = +-Inf
+}
+;;
+
+{ .mmb
+ ldfpd fA05, fA07 = [rCoeffA], 16
+ ldfpd fB05, fB07 = [rCoeffB], 16
+(p6) br.cond.spnt __libm_error_region // call error support if cotf(+-0)
+}
+;;
+
+{ .mmi
+ ldfpd fA09, fA11 = [rCoeffA], 16
+ ldfpd fB09, fB11 = [rCoeffB], 16
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fShiftedN = fNormArg,fScRcpPiby2,fScRshf // x*2^70*(2/Pi)+ScRshf
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fN = fShiftedN, fScFctr, fRshf // N = Y*2^(-70) - Rshf
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex", p10, p11
+{ .mfi
+ getf.sig rIntN = fShiftedN // get N as integer
+(p10) fnma.s1 fR = fN, fPiby2, fNormArg // R = x - (Pi/2)*N (tanf)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fms.s1 fR = fN, fPiby2, fNormArg // R = (Pi/2)*N - x (cotf)
+ nop.i 0
+}
+;;
+
+{ .mmi
+ ldfpd fA13, fA15 = [rCoeffA], 16
+ ldfpd fA17, fA19 = [rCoeffB], 16
+ nop.i 0
+}
+;;
+
+Return_From_Huges:
+{ .mfi
+ nop.m 0
+ fma.s1 fRp2 = fR, fR, f0 // R^2
+(p11) add rIntN = 0x1, rIntN // N = N + 1 (cotf)
+}
+;;
+
+{ .mfi
+ nop.m 0
+ frcpa.s1 fY0, p0 = f1, fR // Y0 ~ 1/R
+ tbit.z p8, p9 = rIntN, 0 // p8=1 if N is even
+}
+;;
+
+// Below are mixed polynomial calculations (mixed for even and odd N)
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fB03_01 = fRp2, fB03, fB01 // R^2*B3 + B1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fRp4 = fRp2, fRp2, f0 // R^4
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fA15_13 = fRp2, fA15, fA13 // R^2*A15 + A13
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fA19_17 = fRp2, fA19, fA17 // R^2*A19 + A17
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fA07_05 = fRp2, fA07, fA05 // R^2*A7 + A5
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fA11_09 = fRp2, fA11, fA09 // R^2*A11 + A9
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fB07_05 = fRp2, fB07, fB05 // R^2*B7 + B5
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fB11_09 = fRp2, fB11, fB09 // R^2*B11 + B9
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fnma.s1 fD = fR, fY0, f1 // D = 1 - R*Y0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fA03_01 = fRp2, fA03, fA01 // R^2*A3 + A1
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRp8 = fRp4, fRp4, f0 // R^8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fRp5 = fR, fRp4, f0 // R^5
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fA11_05 = fRp4, fA11_09, fA07_05 // R^4*(R^2*A11 + A9) + ...
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.s1 fA19_13 = fRp4, fA19_17, fA15_13 // R^4*(R^2*A19 + A17) + ..
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fB11_05 = fRp4, fB11_09, fB07_05 // R^4*(R^2*B11 + B9) + ...
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fRbyB03_01 = fR, fB03_01, f0 // R*(R^2*B3 + B1)
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fY1 = fY0, fD, fY0 // Y1 = Y0*D + Y0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 fDp2 = fD, fD, f0 // D^2
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // R^8*(R^6*A19 + R^4*A17 + R^2*A15 + A13) + R^6*A11 + R^4*A9 + R^2*A7 + A5
+(p8) fma.d.s1 fA19_05 = fRp8, fA19_13, fA11_05
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.d.s1 fRbyA03_01 = fR, fA03_01, f0 // R*(R^2*A3 + A1)
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p9) fma.d.s1 fInvR = fY1, fDp2, fY1 // 1/R = Y1*D^2 + Y1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // R^5*(R^6*B11 + R^4*B9 + R^2*B7 + B5) + R^3*B3 + R*B1
+(p9) fma.d.s1 fRbyB11_01 = fRp5, fB11_05, fRbyB03_01
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex", p8, p9
+{ .mfi
+ nop.m 0
+ // Result = R^5*(R^14*A19 + R^12*A17 + R^10*A15 + ...) + R^3*A3 + R*A1
+(p8) fma.s.s0 f8 = fRp5, fA19_05, fRbyA03_01
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ // Result = -1/R + R^11*B11 + R^9*B9 + R^7*B7 + R^5*B5 + R^3*B3 + R*B1
+(p9) fnma.s.s0 f8 = f1, fInvR, fRbyB11_01
+ br.ret.sptk b0 // exit for main path
+}
+;;
+
+GLOBAL_IEEE754_END(tanf)
+
+
+LOCAL_LIBM_ENTRY(__libm_callout)
+Huge_Argument:
+.prologue
+
+{ .mfi
+ nop.m 0
+ fmerge.s f9 = f0,f0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs
+}
+;;
+
+{ .mfi
+ mov GR_SAVE_GP=gp
+ nop.f 0
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0
+}
+
+.body
+{ .mmb
+ nop.m 999
+ nop.m 999
+(p10) br.cond.sptk.many call_tanl ;;
+}
+
+// Here if we should call cotl (p10=0, p11=1)
+{ .mmb
+ nop.m 999
+ nop.m 999
+ br.call.sptk.many b0=__libm_cotl# ;;
+}
+
+{ .mfi
+ mov gp = GR_SAVE_GP
+ fnorm.s.s0 f8 = f8
+ mov b0 = GR_SAVE_B0
+}
+;;
+
+{ .mib
+ nop.m 999
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+;;
+}
+
+// Here if we should call tanl (p10=1, p11=0)
+call_tanl:
+{ .mmb
+ nop.m 999
+ nop.m 999
+ br.call.sptk.many b0=__libm_tanl# ;;
+}
+
+{ .mfi
+ mov gp = GR_SAVE_GP
+ fnorm.s.s0 f8 = f8
+ mov b0 = GR_SAVE_B0
+}
+;;
+
+{ .mib
+ nop.m 999
+ mov ar.pfs = GR_SAVE_PFS
+ br.ret.sptk b0
+;;
+}
+
+LOCAL_LIBM_END(__libm_callout)
+
+.type __libm_tanl#,@function
+.global __libm_tanl#
+.type __libm_cotl#,@function
+.global __libm_cotl#
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+// (2)
+{ .mmi
+ stfs [GR_Parameter_Y] = f1,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfs [GR_Parameter_X] = f10 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+// (4)
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/s_tanh.S b/libc/sysdeps/ia64/fpu/s_tanh.S
new file mode 100644
index 000000000..9adbc9c46
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_tanh.S
@@ -0,0 +1,986 @@
+.file "tanh.s"
+
+
+// Copyright (c) 2001 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================================
+// 05/30/01 Initial version
+// 12/04/01 Rewritten version with erf-like algorithm.
+// Performance improved.
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 08/14/02 Changed mli templates to mlx
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================================
+// double tanh(double)
+//
+// Overview of operation
+//==============================================================================
+//
+// Algorithm description
+// ---------------------
+//
+// There are 4 paths:
+//
+// 1. Special path: x = 0, Inf, NaNs, denormals
+// Return tanh(x) = +/-0.0 for zeros
+// Return tanh(x) = QNaN for NaNs
+// Return tanh(x) = sign(x)*1.0 for Inf
+// Return tanh(x) = x + x^2 for - denormals
+// Return tanh(x) = x - x^2 for + denormals
+//
+// 2. Near zero path: 0.0 < |x| < 0.25
+// Return tanh(x) = x + x^3*A3 + ... + x^19*A19
+//
+// 3. Main path: 0.25 <= |x| < 19.0625
+// For several ranges of 0.25 <= |x| < 19.0625
+// Return tanh(x) = sign(x)*(A0 + y*A1 + y^2*A2 +
+// + y^3*A3 + ... + y^19*A19)
+// where y = (|x|/a) - b
+//
+// For each range there is particular set of coefficients.
+// Below is the list of ranges:
+// 1/4 <= |x| < 1/2 a = 0.25, b = 1.0
+// 1/2 <= |x| < 1.0 a = 0.5, b = 1.0
+// 1.0 <= |x| < 2.0 a = 1.0, b = 1.0
+// 2.0 <= |x| < 3.25 a = 2.0, b = 1.0
+// 3.25 <= |x| < 4.0 a = 2.0, b = 2.0
+// 4.0 <= |x| < 6.5 a = 4.0, b = 1.0
+// 6.5 <= |x| < 8.0 a = 4.0, b = 2.0
+// 8.0 <= |x| < 13.0 a = 8.0, b = 1.0
+// 13.0 <= |x| < 16.0 a = 8.0, b = 2.0
+// 16.0 <= |x| < 19.0625 a = 16.0, b = 1.0
+// ( [3.25;4.0], [6.5;8.0], [13.0;16.0] subranges separated
+// for monotonicity issues resolve )
+//
+// 4. Saturation path: 19.0625 <= |x| < +INF
+// Return tanh(x) = sign(x)*(1.0 - tiny_value)
+// (tiny_value ~ 2^(-63))
+//
+// Registers used
+//==============================================================================
+// Floating Point registers used:
+// f8 = input, output
+// f32 -> f64
+//
+// General registers used:
+// r32 -> r51, r2, r3
+//
+// Predicate registers used:
+// p6, p8, p10, p11, p12, p14, p15
+// p6 arg is zero, denormal or special IEEE
+// p8 to filter out case when signd(x) > 1.625
+// p10 to filter out case when |x| < 0.25
+// p11 to filter out case when signd(x) <= 1.625
+// p12 to filter out case when |x| >= 19.0625
+// p14 set to 1 for positive x
+// p15 set to 1 for negative x
+
+// Assembly macros
+//==============================================================================
+rDataPtr = r2
+rDataPtr1 = r3
+
+rBias = r33
+rCoeffAddr3 = r34
+rThreeAndQ = r35
+rCoeffAddr2 = r36
+rMask = r37
+rArg = r38
+rSignBit = r39
+rAbsArg = r40
+rSaturation = r41
+rIndex = r42
+rCoeffAddr1 = r43
+rCoeffAddr4 = r44
+rShiftedArg = r45
+rShiftedArgMasked = r46
+rBiasedExpOf4 = r47
+rShiftedAbsArg = r48
+rArgSgnd = r49
+r1625Sgnd = r50
+rTwo = r51
+
+//==============================================================================
+fA0 = f32
+fA1 = f33
+fA2 = f34
+fA3 = f35
+fA4 = f36
+fA5 = f37
+fA6 = f38
+fA7 = f39
+fA8 = f40
+fA9 = f41
+fA10 = f42
+fA11 = f43
+fA12 = f44
+fA13 = f45
+fA14 = f46
+fA15 = f47
+fA16 = f48
+fA17 = f49
+fA18 = f50
+fA19 = f51
+fArgSqr = f52
+fArgAbsNorm = f53
+fSignumX = f54
+fRes = f55
+fThreeAndQ = f56
+fArgAbs = f57
+fTSqr = f58
+fTQuadr = f59
+fTDeg3 = f60
+fTDeg7 = f61
+fArgAbsNormSgn = f62
+fTQuadrSgn = f63
+fTwo = f64
+
+// Data tables
+//==============================================================================
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(tanh_data)
+// CAUTION: The order of these table coefficients shouldn't be changed!
+
+// Main path coefficients:
+// Coefficients ##0..15 ("main" coefficient tables)
+// Polynomial coefficients for the tanh(x), 0.25 <= |x| < 0.5
+data8 0xE9D218BC9A3FB55A, 0x00003FC7 //A19
+data8 0xC8C0D38687F36EBA, 0x00003FCE //A18
+data8 0xA2663E519FAC8A43, 0x0000BFD2 //A17
+data8 0xD913F0490674B0DF, 0x00003FD3 //A16
+data8 0xF75D84789DE0AE52, 0x00003FD6 //A15
+data8 0xACB3C40EEF3A06F0, 0x0000BFD9 //A14
+data8 0xEBD7F5DC02CFD5BA, 0x0000BFDB //A13
+data8 0x8B52CDF66D709E2A, 0x00003FDF //A12
+data8 0x9EC21F28E05C4A3E, 0x00003FE0 //A11
+data8 0xC412B44D0176F3ED, 0x0000BFE4 //A10
+data8 0x97BF35A34DD1EA4C, 0x0000BFE0 //A9
+data8 0xF89F5B39E3A3AA36, 0x00003FE9 //A8
+data8 0xF2BA654BCEEBA433, 0x0000BFEA //A7
+data8 0x8E1C15876AA589AD, 0x0000BFEF //A6
+data8 0x942226246A8C2A86, 0x00003FF1 //A5
+data8 0x8F06D9FF7DB47261, 0x00003FF4 //A4
+//
+// Polynomial coefficients for the tanh(x), 0.5 <= |x| < 1.0
+data8 0xC4A7B8FB672A8520, 0x00003FDC //A19
+data8 0xA20724B847E13499, 0x0000BFE0 //A18
+data8 0xE17DB53F02E4D340, 0x00003FE2 //A17
+data8 0x90264A1012F4CA6F, 0x0000BFE4 //A16
+data8 0xEBEC9F776F0BF415, 0x0000BFE0 //A15
+data8 0x89AF912B305B45A4, 0x00003FE7 //A14
+data8 0xB4A960B81F5EC36A, 0x0000BFE7 //A13
+data8 0x969A4E95B2DA86B5, 0x0000BFEA //A12
+data8 0x8A3FC0EC082305CB, 0x00003FEC //A11
+data8 0x83D7795BCBE24373, 0x00003FEC //A10
+data8 0xDCBF42AEB82932EC, 0x0000BFEF //A9
+data8 0x83318E61ECAFD804, 0x00003FF0 //A8
+data8 0xEA4DE5746975A914, 0x00003FF2 //A7
+data8 0xCE63E8FA6B96480B, 0x0000BFF4 //A6
+data8 0xDF017BE0D4FE45D8, 0x0000BFF4 //A5
+data8 0xA8A0C6E2226DF3CD, 0x00003FF8 //A4
+//
+// Polynomial coefficients for the tanh(x), 1.0 <= |x| < 2.0
+data8 0x8E89D2EBFDAA160B, 0x00003FE9 //A19
+data8 0xDD9226310A272046, 0x0000BFEC //A18
+data8 0xA038042D28B0D665, 0x00003FEF //A17
+data8 0x8C04796F03516306, 0x0000BFF1 //A16
+data8 0x9CD6A9CB4E90A2FD, 0x00003FF2 //A15
+data8 0xC8980E166F5A84FD, 0x0000BFF2 //A14
+data8 0x9ADFE65F56B7BCFD, 0x00003FED //A13
+data8 0x8B11FDFB5D0A7B96, 0x00003FF4 //A12
+data8 0x8209A125E829CBFA, 0x0000BFF5 //A11
+data8 0xCF38AAC17B85BD76, 0x00003FF1 //A10
+data8 0xD5C2E248D8AB99AB, 0x00003FF6 //A9
+data8 0xE12BE2785727F2D6, 0x0000BFF7 //A8
+data8 0x9FC9EF90F87BF1E2, 0x00003FF6 //A7
+data8 0x9B02FE0DAF42C08F, 0x00003FF9 //A6
+data8 0xBDACE06F531D9491, 0x0000BFFA //A5
+data8 0xE3048AD1DB2F648C, 0x00003FF9 //A4
+//
+// Polynomial coefficients for the tanh(x), 2.0 <= |x| < 3.25
+data8 0x856EC3B0330A385A, 0x00003FEB //A19
+data8 0xC641D69DAE2D429C, 0x0000BFF2 //A18
+data8 0xC683EB0BE1343FFF, 0x00003FF5 //A17
+data8 0xC358954224E4E823, 0x0000BFF7 //A16
+data8 0xF813A8D6D396BC5F, 0x00003FF8 //A15
+data8 0xE0ECDFED078D37D6, 0x0000BFF9 //A14
+data8 0x950E4E619855E316, 0x00003FFA //A13
+data8 0x8453B8F93370FB58, 0x0000BFFA //A12
+data8 0xFDBA28430AEC95BA, 0x00003FF7 //A11
+data8 0x9371AAC1FDB1E664, 0x00003FFA //A10
+data8 0xAC972DA97782D88A, 0x0000BFFB //A9
+data8 0xE18F47B10B9CE1BC, 0x00003FFB //A8
+data8 0xAB7C81230BF13BC6, 0x0000BFFB //A7
+data8 0xA6CAAD4A3E31A7D5, 0x0000BFF8 //A6
+data8 0x9CABD76D1D5C3878, 0x00003FFC //A5
+data8 0x92906D077941CAA9, 0x0000BFFD //A4
+//
+// Polynomial coefficients for the tanh(x), 4.0 <= |x| < 6.5
+data8 0x9232D19F71709AC9, 0x0000BFF5 //A19
+data8 0x819E31323F5DD3F8, 0x00003FF8 //A18
+data8 0xDA8E1CDB8D23DC29, 0x0000BFF9 //A17
+data8 0xE97C7CD8FC0486D8, 0x00003FFA //A16
+data8 0xB0C4AD234D88C9F2, 0x0000BFFB //A15
+data8 0xC5989BFB28FDE267, 0x00003FFB //A14
+data8 0x9B26520EC4EFEE8E, 0x0000BFFB //A13
+data8 0xC4B6F758AD21E574, 0x00003FF9 //A12
+data8 0xCC36E3FFA10D2CFF, 0x00003FFA //A11
+data8 0x8738696FB06A5CED, 0x0000BFFC //A10
+data8 0xD31981825BF39228, 0x00003FFC //A9
+data8 0x82C58FB9BEE43992, 0x0000BFFD //A8
+data8 0x88D5AAE49164B6F3, 0x00003FFD //A7
+data8 0xF4CA0B968AF2DDE2, 0x0000BFFC //A6
+data8 0xB99874B482BD17EE, 0x00003FFC //A5
+data8 0xE93FB2F99431DC1D, 0x0000BFFB //A4
+//
+// Polynomial coefficients for the tanh(x), 8.0 <= |x| < 13.0
+data8 0xAAA9EB7EADA85CEC, 0x00003FF5 //A19
+data8 0x980C80EE05A6BE78, 0x0000BFF8 //A18
+data8 0x818DA9F5396390A5, 0x00003FFA //A17
+data8 0x8D8CC21E23D8A6A2, 0x0000BFFB //A16
+data8 0xE0EC19E55A886765, 0x00003FFB //A15
+data8 0x8C11197A7E6244C5, 0x0000BFFC //A14
+data8 0x901D2BF203C2F7F3, 0x00003FFC //A13
+data8 0xFEACAEE66EE803E5, 0x0000BFFB //A12
+data8 0xC684E4925E318C3F, 0x00003FFB //A11
+data8 0x8A9D8A970565F28D, 0x0000BFFB //A10
+data8 0xAE34C61DE5CEA4D4, 0x00003FFA //A9
+data8 0xC44C5714BD6208A0, 0x0000BFF9 //A8
+data8 0xC4612F7D6C8BDB79, 0x00003FF8 //A7
+data8 0xABD91DCE40D5EECB, 0x0000BFF7 //A6
+data8 0x80E375C1B847B72F, 0x00003FF6 //A5
+data8 0xA11C7DD978CF700A, 0x0000BFF4 //A4
+//
+// Polynomial coefficients for the tanh(x), 16.0 <= |x| < 19.0625
+data8 0xE29D17C510F86F6B, 0x00003FF3 //A19
+data8 0x88FE52EB39A3A98C, 0x0000BFF5 //A18
+data8 0xA406547E50360693, 0x00003FF5 //A17
+data8 0x83E6260B71C6D7DE, 0x0000BFF5 //A16
+data8 0xA36AB5B0CBC97B85, 0x00003FF4 //A15
+data8 0xA94931E0B7BA6C14, 0x0000BFF3 //A14
+data8 0x9A4596DAF350AD63, 0x00003FF2 //A13
+data8 0xFE47643F375AECA5, 0x0000BFF0 //A12
+data8 0xBF8433C5ABEE63B1, 0x00003FEF //A11
+data8 0x83CEE05D7AE90A0A, 0x0000BFEE //A10
+data8 0xA4CC45480BCEB02D, 0x00003FEC //A9
+data8 0xB967CBDCBC16CB10, 0x0000BFEA //A8
+data8 0xB9681B214EDC098D, 0x00003FE8 //A7
+data8 0xA23B20D87B80DFA8, 0x0000BFE6 //A6
+data8 0xF358B2C46F10CBAF, 0x00003FE3 //A5
+data8 0x98176FD06229A385, 0x0000BFE1 //A4
+//
+// Binary subranges
+// Polynomial coefficients for the tanh(x), 3.25 <= |x| < 4.0
+data8 0xEF2EE841288F6706, 0x00003FE9 //A19
+data8 0xE65D5B74B85F82A6, 0x00003FEB //A18
+data8 0xE495FC21E42A79FF, 0x00003FEA //A17
+data8 0xF99B267A913CF3E5, 0x00003FEC //A16
+data8 0xFE3D700F4A0A0FDE, 0x0000BFEC //A15
+data8 0x8F91BB4EE4E4EA52, 0x00003FEE //A14
+data8 0xBCA9F41A5C6EF8BA, 0x0000BFEE //A13
+data8 0xF93E00884027A9CF, 0x00003FED //A12
+data8 0xC4D4036A61BABC2F, 0x00003FEF //A11
+data8 0x86CC2AD1AD47C7D5, 0x0000BFF2 //A10
+data8 0xD3065DEF4CE9AD32, 0x00003FF3 //A9
+data8 0x82C44125F568D54E, 0x0000BFF5 //A8
+data8 0x88D588729BAF14CA, 0x00003FF6 //A7
+data8 0xF4CA0661307243C7, 0x0000BFF6 //A6
+data8 0xB998746D57061F74, 0x00003FF7 //A5
+data8 0xE93FB2F482327C19, 0x0000BFF7 //A4
+//
+// Polynomial coefficients for the tanh(x), 6.5 <= |x| < 8.0
+data8 0xEB189B71ADC40BE2, 0x00003FEA //A19
+data8 0xA60B46F9FF6DC2DF, 0x00003FEA //A18
+data8 0xBB061CDD9F368B9D, 0x00003FEC //A17
+data8 0x841E08BDF5429991, 0x0000BFEC //A16
+data8 0xDD33990B433F25BE, 0x00003FED //A15
+data8 0xBA5DE6B870F0A2BB, 0x0000BFEE //A14
+data8 0xA71D489AAA6DACF0, 0x00003FEF //A13
+data8 0x874CCB2B8F3FBC0E, 0x0000BFF0 //A12
+data8 0xCB1D2E9754EA534A, 0x00003FF0 //A11
+data8 0x8BA5ABB53BA6ABCF, 0x0000BFF1 //A10
+data8 0xAE91FD1C2391A32B, 0x00003FF1 //A9
+data8 0xC465A74B798E5761, 0x0000BFF1 //A8
+data8 0xC4666152397D15C1, 0x00003FF1 //A7
+data8 0xABD9E63CA575B950, 0x0000BFF1 //A6
+data8 0x80E38B18E8D0F460, 0x00003FF1 //A5
+data8 0xA11C80E20AAFDD3C, 0x0000BFF0 //A4
+//
+// Polynomial coefficients for the tanh(x), 13.0 <= |x| < 16.0
+data8 0xBECD0AF7E22E5594, 0x00003FE9 //A19
+data8 0xE2834E2D68C1128C, 0x00003FEA //A18
+data8 0x97B117611B317379, 0x00003FEB //A17
+data8 0xEE91A0D39A772F6B, 0x00003FEA //A16
+data8 0x92F6EC377DCADA4F, 0x00003FEA //A15
+data8 0xD8FCCD6A3277FAB7, 0x00003FE8 //A14
+data8 0xC15AB9CB0C3DCFE0, 0x00003FE7 //A13
+data8 0xC3C659704A7147CD, 0x00003FE2 //A12
+data8 0xFA17F09D27C97912, 0x00003FE4 //A11
+data8 0xF664147182B94788, 0x0000BFE3 //A10
+data8 0xA6C89FA741464DA1, 0x00003FE3 //A9
+data8 0xB90FE464A825EFA8, 0x0000BFE2 //A8
+data8 0xB973AE0FD86EC024, 0x00003FE1 //A7
+data8 0xA23A087F96846951, 0x0000BFE0 //A6
+data8 0xF358D8A7FC012D5D, 0x00003FDE //A5
+data8 0x98176E2309B7C73A, 0x0000BFDD //A4
+//
+// Coefficients ##16..19 ("tail" coefficient tables)
+// Polynomial coefficients for the tanh(x), 0.25 <= |x| < 0.5
+data8 0x838F209ABB9BA7B3, 0x0000BFF7 //A3
+data8 0xEBC0AC78DA4FC500, 0x0000BFF8 //A2
+data8 0xF0A4D02960B60E69, 0x00003FFC //A1
+data8 0xFACBF534D0E42F8A, 0x00003FFC //A0
+//
+// Polynomial coefficients for the tanh(x), 0.5 <= |x| < 1.0
+data8 0xC0ECBDC0A0D133A6, 0x0000BFF8 //A3
+data8 0xBA13A076BF8E812F, 0x0000BFFB //A2
+data8 0xC954A37D1A1CA070, 0x00003FFD //A1
+data8 0xEC9A9EBAB4579B29, 0x00003FFD //A0
+//
+// Polynomial coefficients for the tanh(x), 1.0 <= |x| < 2.0
+data8 0xD42E9175A6EA1397, 0x00003FFB //A3
+data8 0xA3C361378A55CF56, 0x0000BFFD //A2
+data8 0xD706E07CC8622983, 0x00003FFD //A1
+data8 0xC2F7D5A8A79CA2AC, 0x00003FFE //A0
+//
+// Polynomial coefficients for the tanh(x), 2.0 <= |x| < 3.25
+data8 0xAC7A7F8776817C7E, 0x00003FFD //A3
+data8 0x8B7CE95E69FCFE9A, 0x0000BFFD //A2
+data8 0x90B161317028D995, 0x00003FFC //A1
+data8 0xF6CA82F0DE1E9E9A, 0x00003FFE //A0
+//
+// Polynomial coefficients for the tanh(x), 4.0 <= |x| < 6.5
+data8 0xE9E072407BC22DC6, 0x00003FFA //A3
+data8 0xAFA4A913D8E6BB4A, 0x0000BFF9 //A2
+data8 0xAFC2D6A885BAA875, 0x00003FF7 //A1
+data8 0xFFD40B84505A10B2, 0x00003FFE //A0
+//
+// Polynomial coefficients for the tanh(x), 8.0 <= |x| < 13.0
+data8 0xA11C8A1FED168CD5, 0x00003FF2 //A3
+data8 0xF1AAD6B02063A5F5, 0x0000BFEF //A2
+data8 0xF1AADA46AD341C34, 0x00003FEC //A1
+data8 0xFFFFFC39548FC34B, 0x00003FFE //A0
+//
+// Polynomial coefficients for the tanh(x), 16.0 <= |x| < 19.0625
+data8 0x98176FD1F0950C16, 0x00003FDE //A3
+data8 0xE42327BB09C8B2A5, 0x0000BFDA //A2
+data8 0xE42327BB0B154F13, 0x00003FD6 //A1
+data8 0xFFFFFFFFFFF8DEE7, 0x00003FFE //A0
+//
+// Binary subranges
+// Polynomial coefficients for the tanh(x), 3.25 <= |x| < 4.0
+data8 0xE9E072404329293B, 0x00003FF7 //A3
+data8 0xAFA4A913D798300B, 0x0000BFF7 //A2
+data8 0xAFC2D6A885B48567, 0x00003FF6 //A1
+data8 0xFFD40B84505A10B4, 0x00003FFE //A0
+//
+// Polynomial coefficients for the tanh(x), 6.5 <= |x| < 8.0
+data8 0xA11C8A63815F7A28, 0x00003FEF //A3
+data8 0xF1AAD6B65B0EBF53, 0x0000BFED //A2
+data8 0xF1AADA46E799831F, 0x00003FEB //A1
+data8 0xFFFFFC39548FC348, 0x00003FFE //A0
+//
+// Polynomial coefficients for the tanh(x), 13.0 <= |x| < 16.0
+data8 0x98176FE982140A59, 0x00003FDB //A3
+data8 0xE42327B9B0D7202F, 0x0000BFD8 //A2
+data8 0xE42327BB13076BD6, 0x00003FD5 //A1
+data8 0xFFFFFFFFFFF8DEE7, 0x00003FFE //A0
+//
+// Polynomial coefficients for the tanh(x), 0.0 <= |x| < 0.25
+// ('tanh_near_zero' path)
+data8 0xBF2BA5D26E479D0C //A9
+data8 0x3F4336D96F81EE26 //A8
+data8 0xBF8226E34AE197B0 //A5
+data8 0x3F9664F488148657 //A4
+data8 0xAAAAAAAAAAAAAA99, 0x0000BFFD //A1
+data8 0xBF57D91925BB5EE2 //A7
+data8 0x3F6D6D36C3D5B7A1 //A6
+data8 0xBFABA1BA1BA19D32 //A3
+data8 0x3FC1111111111108 //A2
+//
+// 1.0 - 2^(-63)
+// ('tanh_saturation' path)
+data8 0xFFFFFFFFFFFFFFFF, 0x00003FFE
+LOCAL_OBJECT_END(tanh_data)
+
+// CAUTION: The order of table coefficients shouldn't be changed!
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(tanh)
+{ .mfi
+ alloc r32 = ar.pfs, 0, 20, 0, 0
+ fmerge.se fArgAbsNorm = f1, f8 // normalized x
+ adds rSignBit = 0x1, r0 // Bit for sign removing
+}
+{ .mfi
+ addl rDataPtr = @ltoff(tanh_data), gp // Data pointer
+ fma.s1 fTwo = f1, f1, f1 // 2.0 construct
+ addl rArgSgnd = 0xfff, r0 // mask for exponent
+};;
+
+{ .mfi
+ getf.d rArg = f8 // x in GR
+ fclass.m p6,p0 = f8, 0xEF // Filter 0, denormals and specials
+ // 0xEF = @qnan|@snan|@pos|@neg|@zero|@unorm|@inf
+ shl rArgSgnd = rArgSgnd, 52 // mask for exponent
+}
+{ .mlx
+ ld8 rDataPtr = [rDataPtr] // Real data pointer
+ movl r1625Sgnd = 0xA000000000000 // 1.625 signd
+ // 1.625 significand used to filter values greater than 3.25, 6.5, 13.0
+ // to enter binary subranges
+};;
+
+{ .mfi
+ addl rBias = 0x3FD00, r0 // bias of 0.25 << 8
+ fma.s1 fArgSqr = f8, f8, f0 // x^2
+ shl rSignBit = rSignBit, 63 // mask for sign bit
+}
+{ .mlx
+ addl rMask = 0x7FF00, r0 // Mask for index bits
+ movl rTwo = 0x4000000000000000 // 2.0
+};;
+
+{ .mfi
+ andcm rArgSgnd = rArg, rArgSgnd // Remove exponent
+ nop.f 0
+ shr.u rShiftedArg = rArg, 44 // Select only necessary bits of arg
+}
+{ .mfb
+ andcm rAbsArg = rArg, rSignBit // Remove sign
+ nop.f 0
+(p6) br.cond.spnt _tanh_spec // Branch to zero, denorm & specs
+};;
+
+{ .mfi
+ and rShiftedArgMasked = rShiftedArg, rMask // bias of x << 8
+ fmerge.s fArgAbs = f1, f8 // |x|
+ shr rShiftedAbsArg = rAbsArg, 44 // Select only necessary
+ // bits of absolute arg
+}
+{ .mfi
+ cmp.gt p8, p11 = rArgSgnd, r1625Sgnd // p8 = 1 if
+ // signd(x) > 1.625 - to filter values greater than 3.25, 6.5, 13.0
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ sub rIndex = rShiftedArgMasked, rBias // index << 8
+ nop.f 0
+ cmp.lt p10, p0 = rShiftedArgMasked, rBias // p10=1 if |x|<0.25
+}
+{ .mfb
+(p8) cmp.gt p8, p11 = rAbsArg, rTwo // If arg is greater than 2.0?
+ // (then we should use binary subranges)
+ nop.f 0
+(p10) br.cond.spnt tanh_near_zero // branch out if |x| < 0.25
+};;
+
+.pred.rel "mutex",p8,p11
+{ .mfi
+(p8) add rIndex = 0x400, rIndex // Make pointer to binary
+ // subranges
+(p11) fms.s1 fArgAbsNorm = fArgAbsNorm, f1, f1 // |x|/b - 1.0
+ addl rSaturation = 0x40331, r0 // shifted bits of 19.0625
+}
+{ .mfi
+ nop.m 0
+(p8) fms.s1 fArgAbsNorm = fArgAbsNorm, f1, fTwo // |x|/b - 2.0
+ // this is only for binary subranges [3.25;4], [6.5;8], [13.0;16]
+ nop.i 0
+}
+;;
+
+{ .mfi
+ add rCoeffAddr1 = rDataPtr, rIndex// coeff. ##0,2,..14
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ adds rCoeffAddr2 = 16, rCoeffAddr1 // Shifted pointer to coeffs
+ fmerge.s fSignumX = f8, f1 // signum(x)
+ nop.i 0
+}
+{ .mfb
+ cmp.le p12, p0 = rSaturation, rShiftedAbsArg // |x|>=19.0625?
+ nop.f 0
+(p12) br.cond.spnt tanh_saturation // branch out if x |x| >= 19.0625
+};;
+
+{.mfi
+ ldfe fA19 = [rCoeffAddr1], 32 // Load A19
+ nop.f 0
+ nop.i 0
+}
+{.mfi
+ ldfe fA18 = [rCoeffAddr2], 32 // Load A18
+ nop.f 0
+ adds rCoeffAddr3 = 0xA00, rDataPtr // Pointer to "tail"
+ // coefficients tables
+};;
+
+{.mfi
+ ldfe fA17 = [rCoeffAddr1], 32 // Load A17
+ nop.f 0
+ nop.i 0
+}
+{.mfi
+ ldfe fA16 = [rCoeffAddr2], 32 // Load A16
+ nop.f 0
+ nop.i 0
+};;
+
+{.mfi
+ ldfe fA15 = [rCoeffAddr1], 32 // Load A15
+ fma.s1 fTSqr = fArgAbsNorm, fArgAbsNorm, f0 // x^2
+ shr.u rIndex = rIndex, 2 // Index for "tail" tables
+}
+{.mfi
+ ldfe fA14 = [rCoeffAddr2], 32 // Load A14
+ nop.f 0
+ adds rCoeffAddr4 = 16, r0 // Shifter pointer
+ // to "tail" tables
+};;
+
+{.mfi
+ ldfe fA13 = [rCoeffAddr1], 32 // Load A13
+ nop.f 0
+ add rCoeffAddr3 = rCoeffAddr3, rIndex // "tail" coeffs to load
+ // ##16..23
+}
+{.mfi
+ ldfe fA12 = [rCoeffAddr2], 32 // Load A12
+ nop.f 0
+ cmp.lt p15, p14 = rArg, r0 // Arg positive (p14)
+ // or negative (p15)?
+};;
+
+{.mfi
+ ldfe fA11 = [rCoeffAddr1], 32 // Load A11
+ nop.f 0
+ add rCoeffAddr4 = rCoeffAddr3, rCoeffAddr4 // shifted "tail"
+ // coeffs to load
+}
+{.mfi
+ ldfe fA10 = [rCoeffAddr2], 32 // Load A10
+ nop.f 0
+ nop.i 0
+};;
+
+{.mfi
+ ldfe fA9 = [rCoeffAddr1], 32 // Load A9
+ nop.f 0
+ nop.i 0
+}
+{.mfi
+ ldfe fA8 = [rCoeffAddr2], 32 // Load A8
+ nop.f 0
+ nop.i 0
+};;
+
+{.mfi
+ ldfe fA7 = [rCoeffAddr1], 32 // Load A7
+ nop.f 0
+ nop.i 0
+}
+{.mfi
+ ldfe fA6 = [rCoeffAddr2], 32 // Load A6
+ nop.f 0
+ nop.i 0
+};;
+
+{.mfi
+ ldfe fA5 = [rCoeffAddr1], 32 // Load A5
+ fma.s1 fTDeg3 = fArgAbsNorm, fTSqr, f0 // x^3
+ nop.i 0
+}
+{.mfi
+ ldfe fA4 = [rCoeffAddr2], 32 // Load A4
+ fma.s1 fTQuadr = fTSqr, fTSqr, f0 // x^4
+ nop.i 0
+};;
+
+// Path #3 Polynomial Pol19(y) computation; y = fArgAbsNorm
+{.mfi
+ ldfe fA3 = [rCoeffAddr3], 32 // Load A3
+ fma.s1 fArgAbsNormSgn = fArgAbsNorm, fSignumX, f0 // sign(x)*x
+ nop.i 0
+}
+{.mfi
+ ldfe fA2 = [rCoeffAddr4], 32 // Load A2
+ nop.f 0
+ nop.i 0
+};;
+
+{.mfi
+ ldfe fA1 = [rCoeffAddr3], 32 // Load A1
+ fma.s1 fRes = fA19, fArgAbsNorm, fA18 // Polynomial
+ nop.i 0
+}
+{.mfi
+ ldfe fA0 = [rCoeffAddr4], 32 // Load A0
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA17, fArgAbsNorm, fA16 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, fArgAbsNorm, fA14 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fTDeg7 = fTDeg3, fTQuadr, f0 // Polynomial
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA13 = fA13, fArgAbsNorm, fA12 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, fArgAbsNorm, fA10 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA9 = fA9, fArgAbsNorm, fA8 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTSqr, fA17 // Polynomial
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fA7, fArgAbsNorm, fA6 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA5 = fA5, fArgAbsNorm, f0 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA15, fTSqr, fA13 // Polynomial
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA4, fArgAbsNorm, fA3 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA2 = fA2, fArgAbsNorm, fA1 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA11, fTSqr, fA9 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fA7, fTSqr, fA5 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTQuadr, fA15 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA4, fTSqr, fA2 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTQuadr, fA11 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA7, fTDeg3, fA4 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTDeg7, fA4 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ // result for negative argument
+(p15) fms.d.s0 f8 = fRes, fArgAbsNormSgn, fA0 // Polynomial
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ // result for positive argument
+(p14) fma.d.s0 f8 = fRes, fArgAbsNormSgn, fA0 // Polynomial
+ br.ret.sptk b0
+};;
+
+
+// |x| < 0.25 Path /////////////////////////////////////////////////////////////
+.align 32
+tanh_near_zero:
+{ .mfi
+ adds rCoeffAddr1 = 0xC80, rDataPtr // address of A9
+ fma.s0 fTSqr = fArgSqr, fArgSqr, f0 // x^4
+ nop.i 0
+}
+{ .mfi
+ adds rCoeffAddr2 = 0xCB0, rDataPtr // address of A7
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfpd fA9, fA8 = [rCoeffAddr1], 16 // Load A9, A8
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA7, fA6 = [rCoeffAddr2], 16 // Load A7, A6
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfpd fA5, fA4 = [rCoeffAddr1], 16 // Load A5, A4
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfpd fA3, fA2 = [rCoeffAddr2], 16 // Load A3, A2
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe fA1 = [rCoeffAddr1] // Load A1
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fTQuadr = fTSqr, fTSqr, f0 // x^4
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fA9, fArgSqr, fA8 // Polynomial
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fA7, fArgSqr, fA6 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA3 = fA3, fArgSqr, fA2 // Polynomial
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA5 = fA5, fArgSqr, fA4 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA1 = fA1, fArgSqr, f0 // Polynomial
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fTQuadrSgn = fTQuadr, f8, f0 // x^4 * x
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTSqr, fA7 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA1 = fA3, fTSqr, fA1 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTSqr, fA5 // Polynomial
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fRes, fTQuadr, fA1 // Polynomial
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fRes, f8, f8 // x+x*Polynomial
+ br.ret.sptk b0 // Exit for |x| < 0.25
+};;
+
+
+
+
+
+// 19.0625 <= |x| < +inf Saturation path ///////////////////////////////////////
+.align 32
+tanh_saturation:
+{ .mfi
+ adds rDataPtr = 0xCD0, rDataPtr // address of A0
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe fA0 = [rDataPtr] // Load A0 = 2^(-63)
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ fma.d.s0 f8 = fA0, fSignumX, f0 // sign(x)*(1.0-2^(-63))
+ br.ret.sptk b0 // Exit for 19.0625 <=|x|< +inf
+};;
+
+
+
+
+
+// 0, denormals and special IEEE numbers path /////////////////////////////////
+_tanh_spec:
+
+{ .mfi
+ cmp.lt p15, p14 = rArg, r0 // Is arg negative (p15)
+ // or positive p14)
+ fclass.m p6,p0 = f8, 0x23 // To filter infinities
+ // 0x23 = @pos|@neg|@inf
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fclass.m p7,p0 = f8, 0xC7 // To filter NaNs & Zeros
+ // 0xC7 = @pos|@neg|@zero|@qnan|@snan
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+(p6) fmerge.s f8 = f8, f1 // +/-1 for INF args
+(p6) br.ret.spnt b0 // exit for x = INF
+};;
+
+{ .mfb
+ nop.m 0
+(p7) fma.d.s0 f8 = f8, f1, f8 // +/-0 for 0 args
+ // and NaNs for NaNs
+(p7) br.ret.spnt b0 // exit for x = NaN or +/-0
+};;
+
+{ .mfi
+ nop.m 0
+ fnorm.s0 f8 = f8 // Normalize arg
+ nop.i 0
+};;
+
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p14) fnma.d.s0 f8 = f8, f8, f8 // res = r-r^2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p15) fma.d.s0 f8 = f8, f8, f8 // res = r+r^2
+ br.ret.sptk b0 // 0, denormals, specials return
+};;
+
+GLOBAL_LIBM_END(tanh)
+
+
diff --git a/libc/sysdeps/ia64/fpu/s_tanhf.S b/libc/sysdeps/ia64/fpu/s_tanhf.S
new file mode 100644
index 000000000..e4e91cfe6
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_tanhf.S
@@ -0,0 +1,581 @@
+.file "tanhf.s"
+
+
+// Copyright (c) 2001 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 05/30/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// float tanhf(float)
+//
+// Overview of operation
+//==============================================================
+// Background
+//
+//
+// There are 9 paths:
+// 1. x = +/-0.0
+// Return tanhf(x) = +/-0.0
+//
+// 2. 0.0 < |x| < 0.3125
+// Return tanhf(x) = x + x^3*Pol3(x^2),
+// where Pol3(x^2) = C3*x^6 + C2*x^4 + C1*x^2 + C0
+//
+// 3. 0.3125 <= |x| < 8.0
+// Return tanhf(x) = sign(x)*PolD(x)*PolC(|x|) + sign(x)*PolA(|x|),
+// where sign(x)*PolD(x) = sign(x)*(|x|^7 + D2*x^6 + D1*|x|^5 + D0*x^4),
+// PolC(|x|) = B0*x^4 + C3*|x|^3 + C2*|x|^2 + C1*|x| + C0,
+// PolA(|x|) = A3|x|^3 + A2*x^2 + A1*|x| + A0
+//
+// Actually range 0.3125<=|x|< 8.0 is split to 5 subranges.
+// For each subrange there is particular set of coefficients.
+// Below is the list of subranges:
+// 3.1 0.3125 <= |x| < 0.5
+// 3.2 0.5 <= |x| < 1.0
+// 3.3 1.0 <= |x| < 2.0
+// 3.4 2.0 <= |x| < 4.0
+// 3.5 4.0 <= |x| < 8.0
+//
+// 4. 8.0 <= |x| < 9.125
+// Return tanhf(x) = sign(x)*(A3|x|^3 + A2*x^2 + A1*|x| + A0)
+//
+// 5. 9.125 <= |x| < +INF
+// Return tanhf(x) = sign(x)*(1.0d - 2^(-52))
+//
+// 6. |x| = INF
+// Return tanhf(x) = sign(x) * 1.0
+//
+// 7. x = [S,Q]NaN
+// Return tanhf(x) = QNaN
+//
+// 8. x is positive denormal
+// Return tanhf(x) = x - x^2
+//
+// 9. x is negative denormal
+// Return tanhf(x) = x + x^2
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8, input
+// f32 -> f59
+
+// General registers used:
+// r32 -> r46, r2, r3
+
+// Predicate registers used:
+// p0, p6 -> p15
+
+// p6 to filter out case when x = [Q,S]NaN or +/-0
+// p7 to filter out case when x = denormal
+// p8 set if |x| >= 0.3125, used also to process denormal input
+// p9 to filter out case when |x| = inf
+// p10 to filter out case when |x| < 0.3125
+// p11 to filter out case when 0.3125 <= |x| < 9.125
+// p12 to filter out case when |x| >= 9.125
+// p13 to filter out case when 8.0 <= |x| < 9.125
+// p14 set to 1 for positive x
+// p15 set to 1 for negative x
+
+// Assembly macros
+//==============================================================
+rDataPtr = r2
+rDataPtr1 = r3
+
+rBias = r33
+rCoeffAddr3 = r34
+rNearSaturation = r35
+rCoeffAddr1 = r36
+rCoeffAddr2 = r37
+rOffset2 = r38
+rBias2 = r39
+rMask = r40
+rArg = r41
+rBound = r42
+rSignBit = r43
+rAbsArg = r44
+rDataPtr2 = r45
+rSaturation = r46
+
+//==============================================================
+fA0 = f32
+fA1 = f33
+fA2 = f34
+fA3 = f35
+fC0 = f36
+fC1 = f37
+fC2 = f38
+fC3 = f39
+fD0 = f40
+fD1 = f41
+fD2 = f42
+fB0 = f43
+fArgSqr = f44
+fAbsArg = f45
+fSignumX = f46
+fArg4 = f47
+fArg4Sgn = f48
+fArg3 = f49
+fArg3Sgn = f50
+fArg7Sgn = f51
+fArg6Sgn = f52
+fPolC = f53
+fPolCTmp = f54
+fPolA = f55
+fPolATmp = f56
+fPolD = f57
+fPolDTmp = f58
+fArgSqrSgn = f59
+
+// Data tables
+//==============================================================
+
+RODATA
+
+.align 16
+
+LOCAL_OBJECT_START(tanhf_data)
+// Polynomial coefficients for the tanh(x), 0.3125 <= |x| < 0.5
+data8 0x3F9BEEDFDD177D7B // C0
+data8 0x3F970D10C7F32458 // C1
+data8 0x3F766D6B051F3A38 // C2
+data8 0xBF732F2001B23402 // C3
+data8 0xBF854BE1CE1ED499 // D0
+data8 0x4013C944F3999A16 // D1
+data8 0xC01106C6975222C0 // D2
+data8 0x3F783D5ACCF9EBE8 // B0
+// Polynomial coefficients for the tanh(x), 0.5 <= |x| < 1.0
+data8 0xBF5D631440786869 // C0
+data8 0xBF575D79A0D52069 // C1
+data8 0xBF7E2237B7EFC705 // C2
+data8 0x3F6A7ACBC273041F // C3
+data8 0xC040E32EA52D91EB // D0
+data8 0x403D19463E5DB4D7 // D1
+data8 0xC02216F61F759F39 // D2
+data8 0xBF55B4EA0B844BE7 // B0
+// Polynomial coefficients for the tanh(x), 1.0 <= |x| < 2.0
+data8 0x3F8637DBE5B3E690 // C0
+data8 0xBF7F7FEC158C07F5 // C1
+data8 0x3F711C586706838A // C2
+data8 0xBF50EF7EF605554E // C3
+data8 0xC054D45448354E25 // D0
+data8 0x404ADFEEA282E730 // D1
+data8 0xC028AEE456D59549 // D2
+data8 0x3F25232D1BED59A8 // B0
+// Polynomial coefficients for the tanh(x), 2.0 <= |x| < 4.0
+data8 0xBF52602285F2D06C // C0
+data8 0x3F2E57C298FFE1E0 // C1
+data8 0xBF15ED575DB3C811 // C2
+data8 0x3EE428878A08525C // C3
+data8 0xC0895A26849039C1 // D0
+data8 0x406E3C60BBFBB575 // D1
+data8 0xC03A06F62867C75A // D2
+data8 0xBEB114C70F1C723E // B0
+// Polynomial coefficients for the tanh(x), 4.0 <= |x| < 8.0
+data8 0x3EF4B22BD17039A3 // C0
+data8 0xBEB704ADC040C57F // C1
+data8 0x3E937A98288AFE1A // C2
+data8 0xBE4F33B2C9FFE7E7 // C3
+data8 0xC0BE48CFADE2431E // D0
+data8 0x4090E74249760FDD // D1
+data8 0xC04B6F537FCF2F1E // D2
+data8 0x3E0DCD879C91ADEA // B0
+// Polynomial coefficients for the tanh(x), -0.3125 < x < 0.3125
+data8 0xBFD555551E8245B7 // A0
+data8 0x3FC110E63F52E689 // A1
+data8 0xBFAB8CD6A5B7BAFA // A2
+data8 0x3F945D467FCEB553 // A3
+// Polynomial coefficients for the tanh(x), 0.3125 <= |x| < 0.5
+data8 0xBE3DCC92FCAECBB6 // A0
+data8 0x3FF0000043B7D267 // A1
+data8 0xBED18BF28ACFC4B1 // A2
+data8 0xBFD554A56F82837E // A3
+// Polynomial coefficients for the tanh(x), 0.5 <= |x| < 1.0
+data8 0x3EFD6054758539F9 // A0
+data8 0x3FEFFBFC77198EBE // A1
+data8 0x3F700327CA98D237 // A2
+data8 0xBFD68955F5BB2FA1 // A3
+// Polynomial coefficients for the tanh(x), 1.0 <= |x| < 2.0
+data8 0xBF71A53F229DF01B // A0
+data8 0x3FF0AECFD730DE50 // A1
+data8 0xBFC882F88E5DF3BA // A2
+data8 0x3FC6EDF212CA2A8D // A3
+// Polynomial coefficients for the tanh(x), 2.0 <= |x| < 4.0
+data8 0xBFAF0B712E9EDA47 // A0
+data8 0x3FF1C208080BEA64 // A1
+data8 0x3FC3D29B20C8946E // A2
+data8 0xBFF04514ED900A6A // A3
+// Polynomial coefficients for the tanh(x), 4.0 <= |x| < 8.0
+data8 0xBFB1DEA49A831CBC // A0
+data8 0x3FFA729FC7085674 // A1
+data8 0xBFF2F44D923A8FA4 // A2
+data8 0x3FE092FC5712227E // A3
+// Polynomial coefficients for the tanh(x), 8.0 <= |x| <= 9.125
+data8 0x3FEFFF5769EE3041 // A0
+data8 0x3EFBBF148D850891 // A1
+data8 0xBEC86BCEF0F5C2FE // A2
+data8 0x3E7CBA4F3A885A5C // A3
+//
+data8 0x3FEFFFFFFFFFFFFF // 1.0 - epsilon
+LOCAL_OBJECT_END(tanhf_data)
+
+.section .text
+GLOBAL_LIBM_ENTRY(tanhf)
+
+{ .mfi
+ alloc r32 = ar.pfs, 1, 14, 0, 0
+ fmerge.s fAbsArg = f1, f8 // |x|
+ addl rMask = 0x806, r0
+}
+{ .mfi
+ addl rDataPtr = @ltoff(tanhf_data), gp
+ fma.s1 fArgSqr = f8, f8, f0 // x^2
+ adds rSignBit = 0x1, r0
+}
+;;
+
+{ .mfi
+ getf.s rArg = f8 // x in GR
+ fclass.m p7,p0 = f8, 0x0b // is x denormal ?
+ // sign bit and 2 most bits in significand
+ shl rMask = rMask, 20
+}
+{ .mfi
+ ld8 rDataPtr = [rDataPtr]
+ nop.f 0
+ adds rBias2 = 0x1F4, r0
+}
+;;
+
+{ .mfi
+ adds rNearSaturation = 0x14, r0
+ fmerge.s fSignumX = f8, f1 // signum(x)
+ shl rSignBit = rSignBit, 31 // mask for sign bit
+}
+{ .mfi
+ adds rBound = 0x3EA, r0
+ nop.f 0
+ addl rSaturation = 0x4112, r0
+}
+;;
+
+{ .mfi
+ andcm rOffset2 = rArg, rMask
+ fclass.m p6,p0 = f8, 0xc7 // is x [S,Q]NaN or +/-0 ?
+ shl rBound = rBound, 20 // 1.0f in GR
+}
+{ .mfb
+ andcm rAbsArg = rArg, rSignBit // |x| in GR
+ nop.f 0
+(p7) br.cond.spnt tanhf_denormal // branch out if x is denormal
+}
+;;
+
+{ .mfi
+ adds rCoeffAddr2 = 352, rDataPtr
+ fclass.m p9,p0 = f8, 0x23 // is x +/- inf?
+ shr rOffset2 = rOffset2, 21
+}
+{ .mfi
+ cmp.lt p10, p8 = rAbsArg, rBound // |x| < 0.3125?
+ nop.f 0
+ adds rCoeffAddr3 = 16, rDataPtr
+}
+;;
+
+{ .mfi
+(p8) sub rBias = rOffset2, rBias2
+ fma.s1 fArg4 = fArgSqr, fArgSqr, f0 // x^4
+ shl rSaturation = rSaturation, 16
+}
+{ .mfb
+(p10) adds rBias = 0x14, r0
+(p6) fma.s.s0 f8 = f8,f1,f8 // NaN or +/-0
+(p6) br.ret.spnt b0 // exit for x = NaN or +/-0
+}
+;;
+
+{ .mfi
+ shladd rCoeffAddr1 = rBias, 4, rDataPtr
+ fma.s1 fArg3Sgn = fArgSqr, f8, f0 // sign(x)*|x|^3
+ // is |x| < 9.125?
+ cmp.lt p11, p12 = rAbsArg, rSaturation
+}
+{ .mfi
+ shladd rCoeffAddr3 = rBias, 4, rCoeffAddr3
+ fma.s1 fArg3 = fArgSqr, fAbsArg, f0 // |x|^3
+ shladd rCoeffAddr2 = rBias, 3, rCoeffAddr2
+}
+;;
+
+{ .mfi
+(p11) ldfpd fC0, fC1 = [rCoeffAddr1]
+(p9) fmerge.s f8 = f8,f1 // +/- inf
+(p12) adds rDataPtr = 544, rDataPtr
+}
+{ .mfb
+(p11) ldfpd fC2, fC3 = [rCoeffAddr3], 16
+ nop.f 0
+(p9) br.ret.spnt b0 // exit for x = +/- inf
+}
+;;
+
+{ .mfi
+(p11) ldfpd fA0, fA1 = [rCoeffAddr2], 16
+ nop.f 0
+(p8) cmp.eq.unc p13, p0 = rBias, rNearSaturation
+}
+{ .mfi
+ add rCoeffAddr1 = 48, rCoeffAddr1
+ nop.f 0
+ nop.i 0
+}
+;;
+
+{ .mfi
+(p11) ldfpd fD0, fD1 = [rCoeffAddr3]
+ nop.f 0
+ nop.i 0
+}
+{ .mfb
+(p11) ldfpd fD2, fB0 = [rCoeffAddr1]
+ // sign(x)*|x|^2
+ fma.s1 fArgSqrSgn = fArgSqr, fSignumX, f0
+(p10) br.cond.spnt tanhf_near_zero
+}
+;;
+
+{ .mfi
+(p11) ldfpd fA2, fA3 = [rCoeffAddr2], 16
+ fcmp.lt.s1 p15, p14 = f8,f0
+ nop.i 0
+}
+{ .mfb
+(p12) ldfd fA0 = [rDataPtr]
+ fma.s1 fArg4Sgn = fArg4, fSignumX, f0 // sign(x)*|x|^4
+(p12) br.cond.spnt tanhf_saturation
+}
+;;
+{ .mfi
+ nop.m 0
+ fma.s1 fArg7Sgn = fArg4, fArg3Sgn, f0 // sign(x)*|x|^7
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s1 fArg6Sgn = fArg3, fArg3Sgn, f0 // sign(x)*|x|^6
+(p13) br.cond.spnt tanhf_close_to_saturation
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fPolC = fC3, fAbsArg, fC2 // C3*|x| + C2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPolCTmp = fC1, fAbsArg, fC0 // C1*|x| + C0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fPolA = fA1, fAbsArg, fA0 // A1*|x| + A0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fPolD = fD1, fAbsArg, fD0 // D1*|x| + D0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // sign(x)*(|x|^7 + D2*x^6)
+ fma.s1 fPolDTmp = fArg6Sgn, fD2, fArg7Sgn
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fPolATmp = fA3, fAbsArg, fA2 // A3*|x| + A2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fB0 = fB0, fArg4, f0 // B0*x^4
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ // C3*|x|^3 + C2*x^2 + C1*|x| + C0
+ fma.s1 fPolC = fPolC, fArgSqr, fPolCTmp
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // PolD = sign(x)*(|x|^7 + D2*x^6 + D1*|x|^5 + D0*x^4)
+ fma.d.s1 fPolD = fPolD, fArg4Sgn, fPolDTmp
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // PolA = A3|x|^3 + A2*x^2 + A1*|x| + A0
+ fma.d.s1 fPolA = fPolATmp, fArgSqr, fPolA
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ // PolC = B0*x^4 + C3*|x|^3 + C2*|x|^2 + C1*|x| + C0
+ fma.d.s1 fPolC = fPolC, f1, fB0
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p14) fma.s.s0 f8 = fPolC, fPolD, fPolA // for positive x
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p15) fms.s.s0 f8 = fPolC, fPolD, fPolA // for negative x
+ br.ret.sptk b0 // Exit for 0.3125 <=|x|< 8.0
+};;
+
+
+// Here if |x| < 0.3125
+tanhf_near_zero:
+{ .mfi
+ nop.m 0
+ fma.s1 fPolC = fC3, fArgSqr, fC2 // C3*x^2 + C2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPolCTmp = fC1, fArgSqr, fC0 // C1*x^2 + C0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fPolC = fPolC, fArg4, fPolCTmp // C3*x^6 + C2*x^4 + C1*x^2 + C0
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ // x + x^3*(C3*x^6 + C2*x^4 + C1*x^2 + C0)
+ fma.s.s0 f8 = fPolC, fArg3Sgn, f8
+ br.ret.sptk b0 // Exit for |x| < 0.3125
+};;
+
+// Here if 9.125 <= |x| < +inf
+tanhf_saturation:
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = fA0, fSignumX, f0 // sign(x)*(1.0d - 2^(-52))
+ // Exit for 9.125 <= |x| < +inf
+ br.ret.sptk b0 // Exit for 9.125 <=|x|< +inf
+}
+;;
+
+// Here if 8.0 <= |x| < 9.125
+tanhf_close_to_saturation:
+{ .mfi
+ nop.m 0
+ fma.s1 fPolATmp = fA1, fAbsArg, fA0 // A1*|x| + A0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fPolA = fA3, fAbsArg, fA2 // A3*|x| + A2
+ nop.i 0
+}
+;;
+
+.pred.rel "mutex", p14, p15
+{ .mfi
+ nop.m 0
+ // for positive x
+(p14) fma.s.s0 f8 = fPolA, fArgSqr, fPolATmp
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ // for negative x
+(p15) fms.s.s0 f8 = fPolA, fArgSqrSgn, fPolATmp
+ br.ret.sptk b0 // Exit for 8.0 <=|x|< 9.125
+};;
+
+// Here if x is single precision denormal
+tanhf_denormal:
+{ .mfi
+ nop.m 0
+ fclass.m p7,p8 = f8, 0x0a // is x -denormal ?
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+(p7) fma.s.s0 f8 = f8,f8,f8 // -denormal
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fnma.s.s0 f8 = f8,f8,f8 // +denormal
+ br.ret.sptk b0 // Exit for denormal
+}
+;;
+
+GLOBAL_LIBM_END(tanhf)
diff --git a/libc/sysdeps/ia64/fpu/s_tanhl.S b/libc/sysdeps/ia64/fpu/s_tanhl.S
new file mode 100644
index 000000000..3435f4313
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_tanhl.S
@@ -0,0 +1,1348 @@
+.file "tanhl.s"
+
+
+// Copyright (c) 2001 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 11/29/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 08/14/02 Changed mli templates to mlx
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+//
+// API
+//==============================================================
+// long double tanhl(long double)
+//
+// Overview of operation
+//==============================================================
+//
+// Algorithm description
+// ---------------------
+//
+// There are 4 paths:
+//
+// 1. Special path: x = 0, Inf, NaNs, denormal
+// Return tanhl(x) = +/-0.0 for zeros
+// Return tanhl(x) = QNaN for NaNs
+// Return tanhl(x) = sign(x)*1.0 for Inf
+// Return tanhl(x) = x + x^2 for - denormals
+// Return tanhl(x) = x - x^2 for + denormals
+//
+// 2. [0;1/8] path: 0.0 < |x| < 1/8
+// Return tanhl(x) = x + x^3*A3 + ... + x^15*A15
+//
+// 3. Main path: 1/8 <= |x| < 22.8
+// For several ranges of 1/8 <= |x| < 22.8
+// Return tanhl(x) = sign(x)*((A0H+A0L) + y*(A1H+A1L) + y^2*(A2H+A2L) +
+// + y^3*A3 + y^4*A4 + ... + y^25*A25 )
+// where y = (|x|/a) - b
+//
+// For each range there is particular set of coefficients.
+// Below is the list of ranges:
+// 1/8 <= |x| < 1/4 a = 0.125, b = 1.5
+// 1/4 <= |x| < 1/2 a = 0.25, b = 1.5
+// 1/2 <= |x| < 1.0 a = 0.5, b = 1.5
+// 1.0 <= |x| < 2.0 a = 1.0, b = 1.5
+// 2.0 <= |x| < 3.25 a = 2.0, b = 1.5
+// 3.25 <= |x| < 4.0 a = 2.0, b = 2.0
+// 4.0 <= |x| < 6.5 a = 4.0, b = 1.5
+// 6.5 <= |x| < 8.0 a = 4.0, b = 2.0
+// 8.0 <= |x| < 13.0 a = 8.0, b = 1.5
+// 13.0 <= |x| < 16.0 a = 8.0, b = 2.0
+// 16.0 <= |x| < 22.8 a = 16.0, b = 1.5
+// ( [3.25;4.0], [6.5;8.0], [13.9;16.0] subranges separated
+// for monotonicity issues resolve )
+//
+// 4. Saturation path: 22.8 <= |x| < +INF
+// Return tanhl(x) = sign(x)*(1.0 - tiny_value)
+// (tiny_value ~ 1e-1233)
+//
+// Implementation notes
+// --------------------
+//
+// 1. Special path: x = 0, INF, NaNa, denormals
+//
+// This branch is cut off by one fclass operation.
+// Then zeros+nans, infinities and denormals processed separately.
+// For denormals we use simple fma operaton x+x*x (- for +denorms)
+//
+// 2. [0;1/8] path: 0.0 < |x| < 1/8
+//
+// Here we use simple polynimial computations, where last step
+// is performed as x + x^3*A3+...
+// The rest of polynomial is factorized using binary tree technique.
+//
+// 3. Main path: 1/8 <= |x| < 22.8
+//
+// Multiprecision have to be performed only for first few
+// polynomial iterations (up to 3-rd x degree)
+// Here we use the same parallelisation way as above:
+// Split whole polynomial to first, "multiprecision" part, and second,
+// so called "tail", native precision part.
+//
+// 1) Multiprecision part:
+// [v1=(A0H+A0L)+y*(A1H+A1L)] + [v2=y^2*((A2H+A2L)+y*A3)]
+// v1 and v2 terms calculated in parallel
+//
+// 2) Tail part:
+// v3 = x^4 * ( A4 + x*A5 + ... + x^21*A25 )
+// v3 is splitted to 2 even parts (10 coefficient in each one).
+// These 2 parts are also factorized using binary tree technique.
+//
+// So Multiprecision and Tail parts cost is almost the same
+// and we have both results ready before final summation.
+//
+// Some tricks were applied to maintain symmetry at direct
+// rounding modes (to +/-inf). We had to set result sign
+// not at the last operation but much more earlier and at
+// several places.
+//
+// 4. Saturation path: 22.8 <= |x| < +INF
+//
+// We use formula sign(x)*(1.0 - tiny_value) instead of simple sign(x)*1.0
+// just to meet IEEE requirements for different rounding modes in this case.
+//
+// Registers used
+//==============================================================
+// Floating Point registers used:
+// f8 - input & output
+// f32 -> f92
+
+// General registers used:
+// r2, r3, r32 -> r52
+
+// Predicate registers used:
+// p0, p6 -> p11, p14, p15
+
+// p6 - arg is zero, denormal or special IEEE
+// p7 - arg is in [16;32] binary interval
+// p8 - arg is in one of subranges
+// [3.25;4.0], [6.5;8.0], [13.9;16.0]
+// p9 - arg < 1/8
+// p10 - arg is NOT in one of subranges
+// [3.25;4.0], [6.5;8.0], [13.9;16.0]
+// p11 - arg in saturation domain
+// p14 - arg is positive
+// p15 - arg is negative
+
+// Assembly macros
+//==============================================================
+rDataPtr = r2
+rTailDataPtr = r3
+
+rBias = r33
+rSignBit = r34
+rInterval = r35
+
+rArgExp = r36
+rArgSig = r37
+r3p25Offset = r38
+r2to4 = r39
+r1p25 = r40
+rOffset = r41
+r1p5 = r42
+rSaturation = r43
+r1625Sign = r44
+rTiny = r45
+rAddr1 = r46
+rAddr2 = r47
+rTailAddr1 = r48
+rTailAddr2 = r49
+rTailOffset = r50
+rTailAddOffset = r51
+rShiftedDataPtr = r52
+
+//==============================================================
+fA0H = f32
+fA0L = f33
+fA1H = f34
+fA1L = f35
+fA2H = f36
+fA2L = f37
+fA3 = f38
+fA4 = f39
+fA5 = f40
+fA6 = f41
+fA7 = f42
+fA8 = f43
+fA9 = f44
+fA10 = f45
+fA11 = f46
+fA12 = f47
+fA13 = f48
+fA14 = f49
+fA15 = f50
+fA16 = f51
+fA17 = f52
+fA18 = f53
+fA19 = f54
+fA20 = f55
+fA21 = f56
+fA22 = f57
+fA23 = f58
+fA24 = f59
+fA25 = f60
+
+fArgSqr = f61
+fArgCube = f62
+fArgFour = f63
+fArgEight = f64
+
+fArgAbsNorm = f65
+fArgAbsNorm2 = f66
+fArgAbsNorm2L = f67
+fArgAbsNorm3 = f68
+fArgAbsNorm4 = f69
+fArgAbsNorm11 = f70
+
+fRes = f71
+fResH = f72
+fResL = f73
+fRes1H = f74
+fRes1L = f75
+fRes1Hd = f76
+fRes2H = f77
+fRes2L = f78
+fRes3H = f79
+fRes3L = f80
+fRes4 = f81
+
+fTT = f82
+fTH = f83
+fTL = f84
+fTT2 = f85
+fTH2 = f86
+fTL2 = f87
+
+f1p5 = f88
+f2p0 = f89
+fTiny = f90
+fSignumX = f91
+fArgAbsNorm4X = f92
+
+// Data tables
+//==============================================================
+RODATA
+
+.align 16
+LOCAL_OBJECT_START(tanhl_data)
+
+////////// Main tables ///////////
+_0p125_to_0p25_data: // exp = 2^-3
+// Polynomial coefficients for the tanh(x), 1/8 <= |x| < 1/4
+data8 0x93D27D6AE7E835F8, 0x0000BFF4 //A3 = -5.6389704216278164626050408239e-04
+data8 0xBF66E8668A78A8BC //A2H = -2.7963640930198357253955165902e-03
+data8 0xBBD5384EFD0E7A54 //A2L = -1.7974001252014762983581666453e-20
+data8 0x3FBEE69E31DB6156 //A1H = 1.2070645062647619716322822114e-01
+data8 0x3C43A0B4E24A3DCA //A1L = 2.1280460108882061756490131241e-18
+data8 0x3FC7B8FF903BF776 //A0H = 1.8533319990813951205765874874e-01
+data8 0x3C593F1A61986FD4 //A0L = 5.4744612262799573374268254539e-18
+data8 0xDB9E6735560AAE5A, 0x0000BFA3 //A25 = -3.4649731131719154051239475238e-28
+data8 0xF0DDE953E4327704, 0x00003FA4 //A24 = 7.6004173864565644629900702857e-28
+data8 0x8532AED11DEC5612, 0x00003FAB //A23 = 5.3798235684551098715428515761e-26
+data8 0xAEF72A34D88B0038, 0x0000BFAD //A22 = -2.8267199091484508912273222600e-25
+data8 0x9645EF1DCB759DDD, 0x0000BFB2 //A21 = -7.7689413112830095709522203109e-24
+data8 0xA5D12364E121F70F, 0x00003FB5 //A20 = 6.8580281614531622113161030550e-23
+data8 0x9CF166EA815AC705, 0x00003FB9 //A19 = 1.0385615003184753213024737634e-21
+data8 0x852B1D0252498752, 0x0000BFBD //A18 = -1.4099753997949827217635356478e-20
+data8 0x9270F5716D25EC9F, 0x0000BFC0 //A17 = -1.2404055949090177751123473821e-19
+data8 0xC216A9C4EEBDDDCA, 0x00003FC4 //A16 = 2.6303900460415782677749729120e-18
+data8 0xDCE944D89FF592F2, 0x00003FC6 //A15 = 1.1975620514752377092265425941e-17
+data8 0x83C8DDF213711381, 0x0000BFCC //A14 = -4.5721980583985311263109531319e-16
+LOCAL_OBJECT_END(tanhl_data)
+
+LOCAL_OBJECT_START(_0p25_to_0p5_data)
+// Polynomial coefficients for the tanh(x), 1/4 <= |x| < 1/2
+data8 0xB6E27B747C47C8AD, 0x0000BFF6 //A3 = -2.7905990032063258105302045572e-03
+data8 0xBF93FD54E226F8F7 //A2H = -1.9521070769536099515084615064e-02
+data8 0xBC491BC884F6F18A //A2L = -2.7222721075104525371410300625e-18
+data8 0x3FCBE3FBB015A591 //A1H = 2.1789499376181400980279079249e-01
+data8 0x3C76AFC2D1AE35F7 //A1L = 1.9677459707672596091076696742e-17
+data8 0x3FD6EF53DE8C8FAF //A0H = 3.5835739835078589399230963863e-01
+data8 0x3C8E2A1C14355F9D //A0L = 5.2327050592919416045278607775e-17
+data8 0xF56D363AAE3BAD53, 0x00003FBB //A25 = 6.4963882412697389947564301120e-21
+data8 0xAD6348526CEEB897, 0x0000BFBD //A24 = -1.8358149767147407353343152624e-20
+data8 0x85D96A988565FD65, 0x0000BFC1 //A23 = -2.2674950494950919052759556703e-19
+data8 0xD52CAF6B1E4D9717, 0x00003FC3 //A22 = 1.4445269502644677106995571101e-18
+data8 0xBD7E1BE5CBEF7A01, 0x00003FC5 //A21 = 5.1362075721080004718090799595e-18
+data8 0xAE84A9B12ADD6948, 0x0000BFC9 //A20 = -7.5685210830925426342786733068e-17
+data8 0xEAC2D5FCF80E250C, 0x00003FC6 //A19 = 1.2726423522879522181100392135e-17
+data8 0xE0D2A8AC8C2EDB95, 0x00003FCE //A18 = 3.1200443098733419749016380203e-15
+data8 0xB22F0AB7B417F78E, 0x0000BFD0 //A17 = -9.8911854977385933809488291835e-15
+data8 0xE25A627BAEFFA7A4, 0x0000BFD3 //A16 = -1.0052095388666003876301743498e-13
+data8 0xC90F32EC4A17F908, 0x00003FD6 //A15 = 7.1430637679768183097897337145e-13
+data8 0x905F6F124AF956B1, 0x00003FD8 //A14 = 2.0516607231389483452611375485e-12
+LOCAL_OBJECT_END(_0p25_to_0p5_data)
+
+LOCAL_OBJECT_START(_0p5_to_1_data)
+// Polynomial coefficients for the tanh(x), 1/2 <= |x| < 1
+data8 0xAB402BE491EE72A7, 0x00003FF7 //A3 = 5.2261556931080934657023772945e-03
+data8 0xBFB8403D3DDA87BE //A2H = -9.4730212784752659826992271519e-02
+data8 0xBC6FF7BC2AB71A8B //A2L = -1.3863786398568460929625760740e-17
+data8 0x3FD3173B1EFA6EF4 //A1H = 2.9829290414066567116435635398e-01
+data8 0x3C881E4DCABDE840 //A1L = 4.1838710466827119847963316219e-17
+data8 0x3FE45323E552F228 //A0H = 6.3514895238728730220145735075e-01
+data8 0x3C739D5832BF7BCF //A0L = 1.7012977006567066423682445459e-17
+data8 0xF153980BECD8AE12, 0x00003FD0 //A25 = 1.3396313991261493342597057700e-14
+data8 0xEC9ACCD245368129, 0x0000BFD3 //A24 = -1.0507358886349528807350792383e-13
+data8 0x8AE6498CA36D2D1A, 0x00003FD4 //A23 = 1.2336759149738309660361813001e-13
+data8 0x8DF02FBF5AC70E64, 0x00003FD7 //A22 = 1.0085317723615282268326194551e-12
+data8 0x9E15C7125DA204EE, 0x0000BFD9 //A21 = -4.4930478919612724261941857560e-12
+data8 0xA62C6F39BDDCEC1C, 0x00003FD7 //A20 = 1.1807342457875095150035780314e-12
+data8 0xDFD8D65D30F80F52, 0x00003FDC //A19 = 5.0896919887121116317817665996e-11
+data8 0xB795AFFD458F743E, 0x0000BFDE //A18 = -1.6696932710534097241291327756e-10
+data8 0xFEF30234CB01EC89, 0x0000BFDD //A17 = -1.1593749714588103589483091370e-10
+data8 0xA2F638356E13761E, 0x00003FE2 //A16 = 2.3714062288761887457674853605e-09
+data8 0xC429CC0D031E4FD5, 0x0000BFE3 //A15 = -5.7091025466377379046489586383e-09
+data8 0xC78363FF929EFF62, 0x0000BFE4 //A14 = -1.1613199289622686725595739572e-08
+LOCAL_OBJECT_END(_0p5_to_1_data)
+
+LOCAL_OBJECT_START(_1_to_2_data)
+// Polynomial coefficients for the tanh(x), 1 <= |x| < 2.0
+data8 0xB3D8FB48A548D99A, 0x00003FFB //A3 = 8.7816203264683800892441646129e-02
+data8 0xBFC4EFBD8FB38E3B //A2H = -1.6356629864377389416141284073e-01
+data8 0xBC77687FD8087B23 //A2L = -2.0303377679446772162287121190e-17
+data8 0x3FC72165282C6F72 //A1H = 1.8070663892364852154415189034e-01
+data8 0x3C64E01F7A76D777 //A1L = 9.0532964466719018524360408402e-18
+data8 0x3FECF6F9786DF577 //A0H = 9.0514825364486639625027919465e-01
+data8 0x3C8834EDCE71A65B //A0L = 4.1992023813070331863928976191e-17
+data8 0xC3EEEB3EFA688094, 0x00003FE2 //A25 = 2.8512044383274095705865793485e-09
+data8 0x88461973672AEB12, 0x0000BFE1 //A24 = -9.9152258079470849685057375343e-10
+data8 0xFC2AF9950DC5027E, 0x0000BFE4 //A23 = -1.4678101918123116001692289670e-08
+data8 0x9C80CA742F89B7B5, 0x00003FE6 //A22 = 3.6438714992394138274843759814e-08
+data8 0xA0B3D7FAA606260A, 0x0000BFE6 //A21 = -3.7416469848124568887944709492e-08
+data8 0xDA5858432FBD9D9D, 0x0000BFE6 //A20 = -5.0837429421503142141842414978e-08
+data8 0xB0244D1E1AE9C1B0, 0x00003FE9 //A19 = 3.2808967255272595749004827841e-07
+data8 0xC8D3109ACF740738, 0x0000BFEA //A18 = -7.4812945767507614821609020680e-07
+data8 0xBB0F3440EEA55BBF, 0x00003FEA //A17 = 6.9685053481643125932497676583e-07
+data8 0xC13A8B08D8576C19, 0x00003FEB //A16 = 1.4396658837712390333960587173e-06
+data8 0xFF3A1163CC5522A1, 0x0000BFED //A15 = -7.6063522055104010298762276148e-06
+data8 0x8672AF27EB0823B7, 0x00003FEF //A14 = 1.6027448793338500004496520337e-05
+LOCAL_OBJECT_END(_1_to_2_data)
+
+LOCAL_OBJECT_START(_2_to_3p25_data)
+// Polynomial coefficients for the tanh(x), 2 <= |x| < 3.25
+data8 0xD45657BEC559E366, 0x00003FFA //A3 = 5.1840155367548909799883161889e-02
+data8 0xBFA41B109CA6AB81 //A2H = -3.9268988726084870510835145296e-02
+data8 0xBC2C3D708A4E56C5 //A2L = -7.6544669252238280132415018518e-19
+data8 0x3F9434A517BBC5F4 //A1H = 1.9732074330880380874653212686e-02
+data8 0x3C3ED62DD9585229 //A1L = 1.6716574468135097509707871438e-18
+data8 0x3FEFD77D111A0AFF //A0H = 9.9505475368673035330147058630e-01
+data8 0x3C9C415E151C6CA5 //A0L = 9.8030409604070051319822874013e-17
+data8 0xB1596391D4534D52, 0x00003FEC //A25 = 2.6427086526487251988631279067e-06
+data8 0xC4DC44E243D1AF5F, 0x00003FEF //A24 = 2.3467591534149209236830008333e-05
+data8 0xAED5786023982BB8, 0x00003FF0 //A23 = 4.1683642395739762658623742687e-05
+data8 0xCF39926C9FBC6A10, 0x00003FF0 //A22 = 4.9406263949321793291856681624e-05
+data8 0xA255A72359928142, 0x00003FF0 //A21 = 3.8703580278108400672236161973e-05
+data8 0xA2E573B9FC332C0D, 0x00003FED //A20 = 4.8546879618263642155709302480e-06
+data8 0x82C7BD01830ACA93, 0x00003FF0 //A19 = 3.1180436075031301077175550468e-05
+data8 0xB38AF4C76E96444B, 0x0000BFF0 //A18 = -4.2806338675404452784440167120e-05
+data8 0xEC08FF0FB194464C, 0x00003FF0 //A17 = 5.6275163156181928637744511210e-05
+data8 0xB850825D9E235135, 0x0000BFF0 //A16 = -4.3943998628289568813056822585e-05
+data8 0xF98436E838763687, 0x0000BFEF //A15 = -2.9744680263523220185672219686e-05
+data8 0xE1851A2D00737A5D, 0x00003FF2 //A14 = 2.1507256570895163202182573369e-04
+LOCAL_OBJECT_END(_2_to_3p25_data)
+
+LOCAL_OBJECT_START(_4_to_6p5_data)
+// Polynomial coefficients for the tanh(x), 4 <= |x| < 6.5
+data8 0x896FDBD321A0BE58, 0x00003FF5 //A3 = 1.0485606995331904734870550114e-03
+data8 0xBF39C522B95A37D6 //A2H = -3.9321992640217512306882730044e-04
+data8 0xBBA9B3EC39A45338 //A2L = -2.7213922673282819034134988241e-21
+data8 0x3F19C5377A48B5AD //A1H = 9.8306189621330793766869338146e-05
+data8 0x3BCAFCB1D08A891C //A1L = 1.1429476443042275163117526657e-20
+data8 0x3FEFFFE63ABE253B //A0H = 9.9998771165079547440512897083e-01
+data8 0x3C9BB74C4EE0D16F //A0L = 9.6159219890436197391279544561e-17
+data8 0x8D86121D469AFA7E, 0x0000BFEF //A25 = -1.6870941388985743600323604423e-05
+data8 0x9D3656A36593C5C4, 0x00003FEF //A24 = 1.8741161763079973068909254398e-05
+data8 0xDCD772D5BF9ADB96, 0x00003FF0 //A23 = 5.2652739523018349983563695656e-05
+data8 0xFF79ADCF0DCBCC2D, 0x00003FF1 //A22 = 1.2182012003034659966028035977e-04
+data8 0x84D24E394DEFD0D2, 0x00003FF1 //A21 = 6.3334229517535065590380468696e-05
+data8 0xA66B56BFD2782544, 0x00003FF1 //A20 = 7.9354902476954571736114945842e-05
+data8 0xFB15771FBF3155FE, 0x0000BFEE //A19 = -1.4965763624796745134798717707e-05
+data8 0xC774790126BE54C3, 0x00003FEF //A18 = 2.3776885435831770523136610539e-05
+data8 0x825A13DACB8C68CD, 0x00003FEF //A17 = 1.5539153272890695426189818556e-05
+data8 0xCFF96E6810AACE27, 0x0000BFF1 //A16 = -9.9169893703251156059893890295e-05
+data8 0x8A85D2061B865024, 0x00003FF3 //A15 = 2.6421115104625621420758344535e-04
+data8 0x922EC6F3CFE0496E, 0x0000BFF4 //A14 = -5.5764283474946207558456581668e-04
+LOCAL_OBJECT_END(_4_to_6p5_data)
+
+LOCAL_OBJECT_START(_8_to_13_data)
+// Polynomial coefficients for the tanh(x), 8 <= |x| < 13
+data8 0xDD6050A898303460, 0x00003FE6 //A3 = 5.1543170295688189081352133793e-08
+data8 0xBE44C1078FDBADC0 //A2H = -9.6643444318955652627581125180e-09
+data8 0xBAF95FCAA6DBBA6F //A2L = -1.3118146684038113473094275420e-24
+data8 0x3E14C1078FE26748 //A1H = 1.2080430540780827633746315479e-09
+data8 0x3A88168082F37D95 //A1L = 9.7290246966246404028418245094e-27
+data8 0x3FEFFFFFFFF59F7C //A0H = 9.9999999992449728480892190419e-01
+data8 0x3C7C068EBC5C2EEB //A0L = 2.4308346546749583521003998922e-17
+data8 0x9DC155C77A6C46E5, 0x00003FF2 //A25 = 1.5044709695520252096006763473e-04
+data8 0xF2F9E09CA47F46E9, 0x00003FF3 //A24 = 4.6344010077547944693833282056e-04
+data8 0xCBFD67E704734BC8, 0x00003FF4 //A23 = 7.7815958662026429864083620142e-04
+data8 0xC18DC821CD67E621, 0x00003FF4 //A22 = 7.3834928521190855055818897104e-04
+data8 0x8AF72BCAB05A296E, 0x00003FF4 //A21 = 5.3011135848666430331904214879e-04
+data8 0xC2E73BE9B9AB4007, 0x00003FF2 //A20 = 1.8587423129049905806822275188e-04
+data8 0xE7E8C2058E2FF9F7, 0x00003FF1 //A19 = 1.1058292891321512917337425414e-04
+data8 0xC46309F52E429F97, 0x0000BFF0 //A18 = -4.6822278664829811025251866877e-05
+data8 0x81966C1E007E9BEB, 0x00003FF1 //A17 = 6.1792176836716291200611553354e-05
+data8 0x8CEDC4BEFCAB9A7E, 0x0000BFF1 //A16 = -6.7200080564674449915571760779e-05
+data8 0x8B64E9FA53210018, 0x00003FF1 //A15 = 6.6468331917938095774361868182e-05
+data8 0x82DEDAA539A3A3F1, 0x0000BFF1 //A14 = -6.2403928644276709411156885292e-05
+LOCAL_OBJECT_END(_8_to_13_data)
+
+LOCAL_OBJECT_START(_16_to_22p8_data)
+// Polynomial coefficients for the tanh(x), 16 <= |x| < 22.88
+data8 0x992C00F33DDE804D, 0x00003FCE //A3 = 2.1256869805798788337547274131e-15
+data8 0x3C8D42EA28102760 //A2H = 5.0760412270332007485198379096e-17
+data8 0x391A747B43B072DD //A2L = 1.2737621993898125881520341053e-33
+data8 0x3C309BC5C3CB4D5F //A1H = 9.0034785192019775952205276560e-19
+data8 0x38A8EF3B5C9DCE71 //A1L = 9.3793162715476168397242934494e-36
+data8 0x3FF0000000000000 //A0H = 1.0000000000000000000000000000e+00
+data8 0x3BACC66AFD5CA22A //A0L = 3.0466790472070565954180861749e-21
+data8 0xF020FB351C2F37CB, 0x00003FF1 //A25 = 1.1450235038836625246604146870e-04
+data8 0xBE80596C51302A7B, 0x00003FF4 //A24 = 7.2670503421185030764546828414e-04
+data8 0x91343CF8577E0131, 0x00003FF6 //A23 = 2.2156380512949603402001207105e-03
+data8 0x8D029A8679641286, 0x00003FF7 //A22 = 4.3032888906494613055765544559e-03
+data8 0xC3713F64D8DC4BAB, 0x00003FF7 //A21 = 5.9644279041951657632420721490e-03
+data8 0xCD678C455A5D06C2, 0x00003FF7 //A20 = 6.2684473911812928601693994403e-03
+data8 0xA9E1C825BDCEEBCC, 0x00003FF7 //A19 = 5.1843859941826642445235686826e-03
+data8 0xE29C919AD93F6EB9, 0x00003FF6 //A18 = 3.4578185539872939928152204329e-03
+data8 0xF7E615A75994A607, 0x00003FF5 //A17 = 1.8913175041916131006881986311e-03
+data8 0xE102EFE0F7F2B2AD, 0x00003FF4 //A16 = 8.5835064987089641065525269712e-04
+data8 0xAAD62946DEE96996, 0x00003FF3 //A15 = 3.2584489313998677644253007210e-04
+data8 0xDA2470DE110B293E, 0x00003FF1 //A14 = 1.0401837693241806604296821650e-04
+LOCAL_OBJECT_END(_16_to_22p8_data)
+
+LOCAL_OBJECT_START(_3p25_to_4_data)
+// Polynomial coefficients for the tanh(x), 3.25 <= |x| < 4
+data8 0xE9E07240432926E6, 0x00003FF7 //A3 = 7.1373517862636557382403555215e-03
+data8 0xBF75F495227AF306 //A2H = -5.3602052282115727338540622782e-03
+data8 0xBBBE92D355A6B716 //A2L = -6.4741983326810209847018826624e-21
+data8 0x3F65F85AD510B690 //A1H = 2.6819013660517934671823070403e-03
+data8 0x3C159A0B73E6EC01 //A1L = 2.9275813076637328121849573333e-19
+data8 0x3FEFFA81708A0B42 //A0H = 9.9932929973906703402519724477e-01
+data8 0x3C66857246C19DC6 //A0L = 9.7670460995685717424398031188e-18
+data8 0xE6B6B8365B1E4D6C, 0x00003FE3 //A25 = 6.7146538162212081470554423396e-09
+data8 0xE0453CEEF483A510, 0x00003FE2 //A24 = 3.2635647369924061614015292015e-09
+data8 0x9C7D83B56E92CF1A, 0x00003FE5 //A23 = 1.8217867585545497089756353348e-08
+data8 0xA94635C48ABA9EB4, 0x0000BFE4 //A22 = -9.8530586070049930796756799547e-09
+data8 0xB1B0C14443067646, 0x00003FE5 //A21 = 2.0685890807654992387562340307e-08
+data8 0x9C6E549781E293C3, 0x00003FDE //A20 = 1.4227314592865135171341122138e-10
+data8 0xB0CBFCE7C80F57A7, 0x0000BFE7 //A19 = -8.2327438416004542109809245219e-08
+data8 0xB151AB3876E896E1, 0x00003FE9 //A18 = 3.3028241036175815328309577940e-07
+data8 0xFCF3A5C1A5CB7EEE, 0x0000BFEA //A17 = -9.4231869277542043001280640966e-07
+data8 0x96A9016C7C95BEDA, 0x00003FEC //A16 = 2.2450115975007100522962781833e-06
+data8 0x9B9B0A3901DEC05B, 0x0000BFED //A15 = -4.6374089937147736266514566049e-06
+data8 0x8987DF26A6789CCF, 0x00003FEE //A14 = 8.1974714257536543772040700977e-06
+LOCAL_OBJECT_END(_3p25_to_4_data)
+
+LOCAL_OBJECT_START(_6p5_to_8_data)
+// Polynomial coefficients for the tanh(x), 6.5 <= |x| < 8.0
+data8 0xA11C8A63815E5657, 0x00003FEF //A3 = 1.9205985861286093001394561449e-05
+data8 0xBEDE355AD6CB61D8 //A2H = -7.2022479400070228499307345427e-06
+data8 0xBB8E6B50B8468A63 //A2L = -8.0518953122203408718779840543e-22
+data8 0x3EBE355B48DCF330 //A1H = 1.8005623902549165889479948488e-06
+data8 0x3B5837550FFA98DA //A1L = 8.0124491698609178046195694087e-23
+data8 0x3FEFFFFF872A91F8 //A0H = 9.9999977492967584424832239165e-01
+data8 0x3C8A43B839B4EB63 //A0L = 4.5561696441306660142461355317e-17
+data8 0xB5BC1948966B8826, 0x0000BFE6 //A25 = -4.2313421330480692560677276010e-08
+data8 0x91D0BE367389BDFC, 0x0000BFE8 //A24 = -1.3580117599617083801153887619e-07
+data8 0xFFD950AF282AB36C, 0x0000BFE8 //A23 = -2.3827784451962439125197203287e-07
+data8 0x959B1770EBB8903A, 0x0000BFE9 //A22 = -2.7866256690165347051403663794e-07
+data8 0xCC78060D1C0CFF3C, 0x0000BFE8 //A21 = -1.9042644867126442102188429523e-07
+data8 0xF8919BAF2E87F31D, 0x0000BFE8 //A20 = -2.3149771783868910586746973299e-07
+data8 0xC5B6AC942A3F2440, 0x00003FE8 //A19 = 1.8413511183396213757149263639e-07
+data8 0xABF1A4703056450A, 0x0000BFEA //A18 = -6.4054099983863829656292958643e-07
+data8 0xBB543D8BDB670453, 0x00003FEB //A17 = 1.3957102903892251890348444989e-06
+data8 0xC9D6F37700C1D092, 0x0000BFEC //A16 = -3.0076451968978522605262647414e-06
+data8 0xCA6EF4BB64E49EC8, 0x00003FED //A15 = 6.0329860989478473738709576062e-06
+data8 0xBE25D0FD069D0A93, 0x0000BFEE //A14 = -1.1333687314965721384777951065e-05
+LOCAL_OBJECT_END(_6p5_to_8_data)
+
+LOCAL_OBJECT_START(_13_to_16_data)
+// Polynomial coefficients for the tanh(x), 13 <= |x| < 16
+data8 0x98176FD2075BDBD5, 0x00003FDB //A3 = 1.7290807363028159200235264756e-11
+data8 0xBD8C8464F76162D1 //A2H = -3.2420263805679445515400340441e-12
+data8 0xBA2D56B508E0F1FD //A2L = -1.8515322669984580704502445180e-28
+data8 0x3D5C8464F761639C //A1H = 4.0525329757100331782338488690e-13
+data8 0x3A0A09D9E328E620 //A1L = 4.1081479300866418212862258651e-29
+data8 0x3FEFFFFFFFFFFF1B //A0H = 9.9999999999997457589273608392e-01
+data8 0x3C9B9B089E9BFD89 //A0L = 9.5776165728054091471814161399e-17
+data8 0xC5395B9EC765BDB7, 0x00003FE6 //A25 = 4.5919803498257974411526879804e-08
+data8 0x9A0F1FCB1DC24C3A, 0x00003FE8 //A24 = 1.4347869798460288751020493795e-07
+data8 0x8AA5C3459FAD0B28, 0x00003FE9 //A23 = 2.5825111356333853968900510087e-07
+data8 0x9578B747988CFF9D, 0x00003FE9 //A22 = 2.7841245127068220034870119246e-07
+data8 0x810DF1A589D9CAF1, 0x00003FE9 //A21 = 2.4038267971021370956311255310e-07
+data8 0x8A00D77B9416EB75, 0x00003FE8 //A20 = 1.2852557749068320312899366352e-07
+data8 0xB2436C4A1849C498, 0x00003FE7 //A19 = 8.3010350873515703893886683374e-08
+data8 0xEA6405B18356600B, 0x00003FE3 //A18 = 6.8216675390299296071261114202e-09
+data8 0xF7606C022194B7E8, 0x00003FE5 //A17 = 2.8798432098264655723769995993e-08
+data8 0xAF4B0C453FCAF34E, 0x0000BFE5 //A16 = -2.0406809167824936143455638336e-08
+data8 0xC324C1F10D5FA7CC, 0x00003FE5 //A15 = 2.2717703170390130238356558599e-08
+data8 0xB34A2E3A4D3B9C31, 0x0000BFE5 //A14 = -2.0872076027950789618606920471e-08
+LOCAL_OBJECT_END(_13_to_16_data)
+
+
+//////// "Tail" tables //////////
+LOCAL_OBJECT_START(_0p125_to_0p25_data_tail)
+// Polynomial coefficients for the erf(x), 1/8 <= |x| < 1/4
+data8 0x9D7D206E97ADC83A, 0x0000BFCC //A13 = -5.4639895428711257047470806445e-16
+data8 0xA8972B666A845810, 0x00003FD3 //A12 = 7.4869224589947988668562043110e-14
+data8 0x9A5B31511C9F4698, 0x0000BFD4 //A11 = -1.3709586467430093373657009487e-13
+data8 0xCBB8047BCB274982, 0x0000BFDA //A10 = -1.1580074124926108509393610532e-11
+data8 0xF95EB849E5F9247C, 0x00003FDC //A9 = 5.6700173336564916962945623180e-11
+data8 0xE7893404C6A53386, 0x00003FE1 //A8 = 1.6846457582993065168777704528e-09
+data8 0xF2E5C7E2B5F55ECC, 0x0000BFE4 //A7 = -1.4138500046802141367543484859e-08
+data8 0xF43906FF53A002C0, 0x0000BFE8 //A6 = -2.2745017243678613107034288816e-07
+data8 0xC6175D5E47D1D259, 0x00003FEC //A5 = 2.9517899220726077077586632607e-06
+data8 0xE7C2AE92CB36769B, 0x00003FEF //A4 = 2.7628001723157068127646694830e-05
+LOCAL_OBJECT_END(_0p125_to_0p25_data_tail)
+
+LOCAL_OBJECT_START(_0p25_to_0p5_data_tail)
+// Polynomial coefficients for the tanh(x), 1/4 <= |x| < 1/2
+data8 0x9E2972C008B9965E, 0x0000BFDC //A13 = -3.5961854154738002253192260213e-11
+data8 0xC3EABA3D219BEA8A, 0x00003FDB //A12 = 2.2273173303628274478819473067e-11
+data8 0xC50FB68D960D5CD9, 0x00003FE1 //A11 = 1.4338102430978399800743148719e-09
+data8 0xB3BB92499EF2D583, 0x0000BFE3 //A10 = -5.2309100551458044083112632491e-09
+data8 0xBD915BE632F1D04E, 0x0000BFE6 //A9 = -4.4137194873936112573773943707e-08
+data8 0xBC48C813FA819141, 0x00003FE9 //A8 = 3.5070684356359066908197915734e-07
+data8 0xD3E34EA031AC611B, 0x00003FEA //A7 = 7.8934400708919584259192272835e-07
+data8 0x8EAC489D859541CD, 0x0000BFEF //A6 = -1.7007944944124693133572815137e-05
+data8 0x98D4D7E5D1508B8A, 0x00003FEF //A5 = 1.8218924920302265989878708948e-05
+data8 0xAC262F3F8CF49C02, 0x00003FF4 //A4 = 6.5669692402266433496312492412e-04
+LOCAL_OBJECT_END(_0p25_to_0p5_data_tail)
+
+LOCAL_OBJECT_START(_0p5_to_1_data_tail)
+// Polynomial coefficients for the tanh(x), 1/2 <= |x| < 1
+data8 0xDF67FB36FFA2A538, 0x00003FE7 //A13 = 1.0403160796697495720021114635e-07
+data8 0xB7FB80FB5AFA63A4, 0x0000BFE8 //A12 = -1.7134699677764282023124981753e-07
+data8 0xC87625A0BA7D6C5F, 0x0000BFEA //A11 = -7.4677732458471897291461679095e-07
+data8 0x90DA375DD9AF6D79, 0x00003FED //A10 = 4.3169381418023765618186668159e-06
+data8 0x82DFB03317B17316, 0x0000BFED //A9 = -3.9003426534601562552753368105e-06
+data8 0xAA582FD4F3438BB4, 0x0000BFF0 //A8 = -4.0613288845040776435400454867e-05
+data8 0xB1532D8CF763B21C, 0x00003FF2 //A7 = 1.6911021594787399557528570601e-04
+data8 0x82E12AEF7CAB76C6, 0x0000BFEF //A6 = -1.5602059530458172761585925044e-05
+data8 0x83256E3D0FBA5C93, 0x0000BFF6 //A5 = -2.0011324059500451791903108104e-03
+data8 0xCC4AB2EC0965499B, 0x00003FF7 //A4 = 6.2344907419841579664122448353e-03
+LOCAL_OBJECT_END(_0p5_to_1_data_tail)
+
+LOCAL_OBJECT_START(_1_to_2_data_tail)
+// Polynomial coefficients for the tanh(x), 1 <= |x| < 2.0
+data8 0xCCAEE174EAC17F78, 0x0000BFEE //A13 = -1.2200065117856038355953618829e-05
+data8 0xA39DD0981D1A2776, 0x0000BFF0 //A12 = -3.9009204899026604074167603200e-05
+data8 0xB7104FA27FAF80D0, 0x00003FF2 //A11 = 1.7458316338540792661905876072e-04
+data8 0xB219A7274436A734, 0x0000BFF3 //A10 = -3.3969918595931391572998415468e-04
+data8 0xCCD9D03C0C73CECF, 0x00003FF2 //A9 = 1.9536097875337884986025498958e-04
+data8 0x85321EA40CFEEBEE, 0x00003FF5 //A8 = 1.0162031558369402750607778300e-03
+data8 0x81F272C08C308220, 0x0000BFF7 //A7 = -3.9656696618251138315464862909e-03
+data8 0xE8761C6BDEA9ED87, 0x00003FF7 //A6 = 7.0941580558970243020090656343e-03
+data8 0xAE4E9F3691F66877, 0x0000BFF6 //A5 = -2.6597155288710984120834711909e-03
+data8 0xCC8286B331BD8AAA, 0x0000BFF9 //A4 = -2.4964583478826523250880337777e-02
+LOCAL_OBJECT_END(_1_to_2_data_tail)
+
+LOCAL_OBJECT_START(_2_to_3p25_data_tail)
+// Polynomial coefficients for the tanh(x), 2 <= |x| < 3.25
+data8 0x92E1711A3BD6408B, 0x0000BFF4 //A13 = -5.6030514548041036913731470443e-04
+data8 0x8B9BD885FF3E98C5, 0x00003FF5 //A12 = 1.0651304064581604055612602669e-03
+data8 0xD041356C7FA26A22, 0x0000BFF5 //A11 = -1.5888574328066952147023520244e-03
+data8 0xDFA210BE9BE6B7FD, 0x00003FF5 //A10 = 1.7061849060196387827639060629e-03
+data8 0x8ECC3606808028E9, 0x0000BFF4 //A9 = -5.4472999329435778312080340471e-04
+data8 0xD5C053B8EEBD10C8, 0x0000BFF6 //A8 = -3.2615856552479930645151033322e-03
+data8 0xB7BFD63AC5051539, 0x00003FF8 //A7 = 1.1215171059191957498023766643e-02
+data8 0xC367C59D7FA3ADA2, 0x0000BFF9 //A6 = -2.3853193251842394834616848995e-02
+data8 0x9FC9FB890BB053CF, 0x00003FFA //A5 = 3.9010984954739386625695104667e-02
+data8 0xD01D077B42E7ED76, 0x0000BFFA //A4 = -5.0808934425896607486919526567e-02
+LOCAL_OBJECT_END(_2_to_3p25_data_tail)
+
+LOCAL_OBJECT_START(_4_to_6p5_data_tail)
+// Polynomial coefficients for the tanh(x), 4 <= |x| < 6.5
+data8 0x870CCE8C76C52C7E, 0x00003FF5 //A13 = 1.0303499350193060915603525934e-03
+data8 0xE1431E54AD2A738B, 0x0000BFF5 //A12 = -1.7186140560972621669872002486e-03
+data8 0xAB20056533E28734, 0x00003FF6 //A11 = 2.6111615345168277554841545330e-03
+data8 0xECCB91D64718B9BD, 0x0000BFF6 //A10 = -3.6132079169671860943878776041e-03
+data8 0x94771DA3B8C2EB4F, 0x00003FF7 //A9 = 4.5308012699419563988381317896e-03
+data8 0xA7497377E4946F2C, 0x0000BFF7 //A8 = -5.1051915941441437592654444804e-03
+data8 0xA76B2D6FCA088AE9, 0x00003FF7 //A7 = 5.1092120989582196669504468168e-03
+data8 0x928C8961F33C9560, 0x0000BFF7 //A6 = -4.4723196805537430568162704711e-03
+data8 0xDBDDDF6CDE9AB9BE, 0x00003FF6 //A5 = 3.3548994514326736175581084349e-03
+data8 0x896E211733AD9D40, 0x0000BFF6 //A4 = -2.0970183170010094667442967500e-03
+LOCAL_OBJECT_END(_4_to_6p5_data_tail)
+
+LOCAL_OBJECT_START(_8_to_13_data_tail)
+// Polynomial coefficients for the tanh(x), 8 <= |x| < 13
+data8 0xE50C3476BED020AA, 0x00003FF0 //A13 = 5.4609221347524272615754239857e-05
+data8 0xBA16F5F4EDC0EABC, 0x0000BFF0 //A12 = -4.4367239594986428539386662937e-05
+data8 0x8B916C2F002C3D91, 0x00003FF0 //A11 = 3.3275617838067362533536610680e-05
+data8 0xBFE8031097CB4442, 0x0000BFEF //A10 = -2.2877013297722792747267224605e-05
+data8 0xEFE1FFD106B2DA41, 0x00003FEE //A9 = 1.4298129659899553350478452989e-05
+data8 0x86EF1FF403A6622E, 0x0000BFEE //A8 = -8.0426979849841642112688693288e-06
+data8 0x86EF200FD047306B, 0x00003FED //A7 = 4.0213490418736097707257704218e-06
+data8 0xEC22782377882553, 0x0000BFEB //A6 = -1.7593402092805559754997565942e-06
+data8 0xB119DA1DB7C47773, 0x00003FEA //A5 = 6.5975257917246601211360847253e-07
+data8 0xDD6050A7761D67BB, 0x0000BFE8 //A4 = -2.0617268111985310661707082242e-07
+LOCAL_OBJECT_END(_8_to_13_data_tail)
+
+LOCAL_OBJECT_START(_16_to_22p8_data_tail)
+// Polynomial coefficients for the tanh(x), 16 <= |x| < 22.88
+data8 0xEAF4AF87336E81B1, 0x00003FEF //A13 = 2.8008914392791730186582989654e-05
+data8 0xD5B309EA768E2711, 0x00003FED //A12 = 6.3687375204024238267961143128e-06
+data8 0xA4048CA537113538, 0x00003FEB //A11 = 1.2220276227448617951538196845e-06
+data8 0xD3EC78BB3425377D, 0x00003FE8 //A10 = 1.9736934193679794194181457250e-07
+data8 0xE5763CD37440266E, 0x00003FE5 //A9 = 2.6712876934440631473215182284e-08
+data8 0xCECA765EEB4A265F, 0x00003FE2 //A8 = 3.0092031912460315516888139627e-09
+data8 0x99ABF588DF81A52E, 0x00003FDF //A7 = 2.7952722177649984066847682907e-10
+data8 0xB9C78918294A4685, 0x00003FDB //A6 = 2.1120676552098603524020495036e-11
+data8 0xB3A3C42AD539D50F, 0x00003FD7 //A5 = 1.2764169243389521270291967366e-12
+data8 0x86BC347939478174, 0x00003FD3 //A4 = 5.9834437707863962671883176163e-14
+LOCAL_OBJECT_END(_16_to_22p8_data_tail)
+
+LOCAL_OBJECT_START(_3p25_to_4_data_tail)
+// Polynomial coefficients for the tanh(x), 3.25 <= |x| < 4
+data8 0xBE9A2BE19F21BA1C, 0x0000BFEE //A13 = -1.1360778336288065244475976873e-05
+data8 0xF84910F515BDB014, 0x00003FED //A12 = 7.3994819819577018481862729782e-06
+data8 0xC4C84FB788AA4007, 0x00003FEF //A11 = 2.3458298013663976251972482656e-05
+data8 0x86CC6243C170E5ED, 0x0000BFF2 //A10 = -1.2855374755847770638424932233e-04
+data8 0xD3065AC539ABABFF, 0x00003FF3 //A9 = 4.0249790677367806832685138089e-04
+data8 0x82C4413795EC381B, 0x0000BFF5 //A8 = -9.9767013652382759950854031514e-04
+data8 0x88D588720888899A, 0x00003FF6 //A7 = 2.0879228705174076794011525274e-03
+data8 0xF4CA066137741469, 0x0000BFF6 //A6 = -3.7351861548964870836350490741e-03
+data8 0xB998746D56E81737, 0x00003FF7 //A5 = 5.6639259807333999973200378964e-03
+data8 0xE93FB2F48233275B, 0x0000BFF7 //A4 = -7.1181892208343798194003322900e-03
+LOCAL_OBJECT_END(_3p25_to_4_data_tail)
+
+LOCAL_OBJECT_START(_6p5_to_8_data_tail)
+// Polynomial coefficients for the tanh(x), 6.5 <= |x| < 8.0
+data8 0xA6881D7D21774BFD, 0x00003FEF //A13 = 1.9852125640303530752913966680e-05
+data8 0x875E983AA042E605, 0x0000BFF0 //A12 = -3.2274606306629334402383651599e-05
+data8 0xCB19E01E94FC133C, 0x00003FF0 //A11 = 4.8423069963831314927026982707e-05
+data8 0x8BA5E8D9E72D56B2, 0x0000BFF1 //A10 = -6.6589395655200734237190902534e-05
+data8 0xAE91F647ED4E46B2, 0x00003FF1 //A9 = 8.3241541003842930001632190258e-05
+data8 0xC465A7E0B22F884E, 0x0000BFF1 //A8 = -9.3649431639051891449916386619e-05
+data8 0xC4666148AA01A4D7, 0x00003FF1 //A7 = 9.3650780646160216748407869111e-05
+data8 0xABD9E63D181B0C6C, 0x0000BFF1 //A6 = -8.1945023256769295802996591839e-05
+data8 0x80E38B18E509387A, 0x00003FF1 //A5 = 6.1458988764532931141264026311e-05
+data8 0xA11C80E20ADA5A64, 0x0000BFF0 //A4 = -3.8411937140983728563216440713e-05
+LOCAL_OBJECT_END(_6p5_to_8_data_tail)
+
+LOCAL_OBJECT_START(_13_to_16_data_tail)
+// Polynomial coefficients for the tanh(x), 13 <= |x| < 16
+data8 0x9D6CCDA4767CA6D9, 0x00003FE5 //A13 = 1.8326683535066775712253572575e-08
+data8 0xFFAF154F334BF403, 0x0000BFE4 //A12 = -1.4882762852665077172347508377e-08
+data8 0xBFC68FA7C61B6C17, 0x00003FE4 //A11 = 1.1162810813806544919835662888e-08
+data8 0x83D8439A6B19A015, 0x0000BFE4 //A10 = -7.6743763372603959795701788561e-09
+data8 0xA4CE5BE9DC6A2962, 0x00003FE3 //A9 = 4.7964885012772346158732715382e-09
+data8 0xB96826C0697253CA, 0x0000BFE2 //A8 = -2.6980246373950994097953903952e-09
+data8 0xB96826CADDC00E35, 0x00003FE1 //A7 = 1.3490123232313844006540534789e-09
+data8 0xA23B21F1155DF322, 0x0000BFE0 //A6 = -5.9019289132168830718664922372e-10
+data8 0xF358B2E9A50C349C, 0x00003FDE //A5 = 2.2132233424669131155945897524e-10
+data8 0x98176FD2074C1D77, 0x0000BFDD //A4 = -6.9163229452106125388824134881e-11
+LOCAL_OBJECT_END(_13_to_16_data_tail)
+
+LOCAL_OBJECT_START(_0_to_1o8_data)
+// Polynomial coefficients for the tanh(x), 0.0 <= |x| < 0.125
+data8 0xBA0EC1879495150B, 0x0000BFF5 // A15 = -1.4195071451378679802688367813e-03
+data8 0xEB5A82898D1BCBA4, 0x00003FF6 // A13 = 3.5912102408030526706365632879e-03
+data8 0x91370DAFE0B64438, 0x0000BFF8 // A11 = -8.8632234251336964576640807982e-03
+data8 0xB327A435358F1200, 0x00003FF9 // A9 = 2.1869488447622383899199238857e-02
+data8 0xDD0DD0DD07A0775F, 0x0000BFFA // A7 = -5.3968253967902161405327069187e-02
+data8 0x888888888887C299, 0x00003FFC // A5 = 1.3333333333333264660338062012e-01
+data8 0xAAAAAAAAAAAAAA98, 0x0000BFFD // A3 = -3.3333333333333333282255458755e-01
+LOCAL_OBJECT_END(_0_to_1o8_data)
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(tanhl)
+
+{ .mfi
+ alloc r32 = ar.pfs, 0, 21, 0, 0
+ fmerge.se fArgAbsNorm = f1, f8 // normalized x (1.0 <= x < 2.0)
+ addl rSignBit = 0x20000, r0 // Set sign bit for exponent
+}
+{ .mlx
+ addl rDataPtr = @ltoff(tanhl_data), gp // Get common data ptr
+ movl r1p5 = 0x3FF8000000000000 // 1.5 in dbl repres.
+};;
+
+{ .mfi
+ getf.exp rArgExp = f8 // Get arg exponent
+ fclass.m p6,p0 = f8, 0xEF // Filter 0, denormals and specials
+ // 0xEF = @qnan|@snan|@pos|@neg|@zero|@unorm|@inf
+ addl rBias = 0xfffc, r0 // Value to subtract from exp
+ // to get actual interval number
+}
+{ .mfi
+ ld8 rDataPtr = [rDataPtr] // Get real common data pointer
+ fma.s1 fArgSqr = f8, f8, f0 // x^2 (for [0;1/8] path)
+ addl r2to4 = 0x10000, r0 // unbiased exponent
+ // for [2;4] binary interval
+};;
+
+{ .mfi
+ getf.sig rArgSig = f8 // Get arg significand
+ fcmp.lt.s1 p15, p14 = f8, f0 // Is arg negative/positive?
+ addl rSaturation = 0xb70, r0 // First 12 bits of
+ // saturation value signif.
+}
+{ .mfi
+ setf.d f1p5 = r1p5 // 1.5 construction
+ fma.s1 f2p0 = f1,f1,f1 // 2.0 construction
+ addl r1625Sign = 0xd01, r0 // First 12 bits of
+ // 1.625 value signif.
+ // 1.625 significand used to filter values greater than 3.25, 6.5, 13.0
+};;
+
+{ .mfi
+ addl rTailDataPtr = 0xB00, rDataPtr // Pointer to "tail" data
+ fmerge.s fSignumX = f8, f1 // signum(x)
+ andcm rArgExp = rArgExp, rSignBit // Remove sign of exp
+}
+{ .mfb
+ addl rTiny = 0xf000, r0 // Tiny value for saturation path
+ nop.f 0
+(p6) br.cond.spnt tanhl_spec // Branch to zero, denorm & specs
+};;
+
+{ .mfi
+ sub rInterval = rArgExp, rBias // Get actual interval number
+ nop.f 0
+ shr.u rArgSig = rArgSig, 52 // Leave only 12 bits of sign.
+}
+{ .mfi
+ adds rShiftedDataPtr = 0x10, rDataPtr // Second ptr to data
+ nop.f 0
+ cmp.ge p8, p10 = rArgExp, r2to4 // If exp >= 2to4 interval?
+};;
+
+{ .mfi
+(p8) cmp.le p8, p10 = r1625Sign, rArgSig // If signd is greater
+ // than 1.625? (arg is at one of binary subranges)
+ nop.f 0
+ shl rOffset = rInterval, 8 // Make offset from
+ // interval number
+}
+{ .mfi
+ cmp.gt p9, p0 = 0x0, rInterval // If interval is less than 0
+ // (means arg is in [0; 1/8])
+ nop.f 0
+ cmp.eq p7, p0 = 0x7, rInterval // If arg is in [16;] interv.?
+};;
+
+{ .mfi
+(p8) adds rOffset = 0x400, rOffset // Add additional offset
+ // (arg is at one of binary subranges)
+ fma.s1 fArgCube = fArgSqr, f8, f0 // x^3 (for [0;1/8] path)
+ shl rTailOffset = rInterval, 7 // Make offset to "tail" data
+ // from interval number
+}
+{ .mib
+ setf.exp fTiny = rTiny // Construct "tiny" value
+ // for saturation path
+ cmp.ltu p11, p0 = 0x7, rInterval // if arg > 32
+(p9) br.cond.spnt _0_to_1o8
+};;
+
+{ .mfi
+ add rAddr1 = rDataPtr, rOffset // Get address for
+ // interval data
+ nop.f 0
+ shl rTailAddOffset = rInterval, 5 // Offset to interval
+ // "tail" data
+}
+{ .mib
+ add rAddr2 = rShiftedDataPtr, rOffset // Get second
+ // address for interval data
+(p7) cmp.leu p11, p0 = rSaturation, rArgSig // if arg is
+ // in [22.8;32] interval
+(p11) br.cond.spnt _saturation // Branch to Saturation path
+};;
+
+{ .mmi
+ ldfe fA3 = [rAddr1], 0x90 // Load A3
+ ldfpd fA2H, fA2L = [rAddr2], 16 // Load A2High, A2Low
+ add rTailOffset = rTailOffset, rTailAddOffset // "Tail" offset
+};;
+
+{ .mmi
+ ldfe fA20 = [rAddr1], 16 // Load A20
+ ldfpd fA1H, fA1L = [rAddr2], 16 // Load A1High, A1Low
+(p8) adds rTailOffset = 0x280, rTailOffset // Additional offset
+ // (arg is at one of binary subranges)
+};;
+
+{ .mmi
+ ldfe fA19 = [rAddr1], 16 // Load A19
+ ldfpd fA0H, fA0L = [rAddr2], 16 // Load A0High, A0Low
+ add rTailAddr1 = rTailDataPtr, rTailOffset // First tail
+ // data address
+};;
+
+.pred.rel "mutex",p8,p10
+{ .mfi
+ ldfe fA18 = [rAddr1], 16 // Load A18
+(p8) fms.s1 fArgAbsNorm = fArgAbsNorm, f1, f2p0 // Add 2.0
+ // (arg is at one of binary subranges)
+ adds rTailAddr2 = 0x10, rTailAddr1 // First tail
+ // data address
+}
+{ .mfi
+ ldfe fA25 = [rAddr2], 16 // Load A25
+(p10) fms.s1 fArgAbsNorm = fArgAbsNorm, f1, f1p5 // Add 1.5
+ // to normalized arg
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA17 = [rAddr1], 16 // Load A17
+ ldfe fA24 = [rAddr2], 16 // Load A24
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA16 = [rAddr1], 16 // Load A16
+ ldfe fA23 = [rAddr2], 16 // Load A23
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA15 = [rAddr1], 16 // Load A15
+ ldfe fA22 = [rAddr2], 16 // Load A22
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA14 = [rAddr1], 16 // Load A14
+ ldfe fA21 = [rAddr2], 16 // Load A21
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe fA13 = [rTailAddr1], 32 // Load A13
+ fms.s1 fArgAbsNorm2 = fArgAbsNorm, fArgAbsNorm, f0 // x^2
+ nop.i 0
+}
+{ .mfi
+ ldfe fA12 = [rTailAddr2], 32 // Load A12
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe fA11 = [rTailAddr1], 32 // Load A11
+ fma.s1 fRes3H = fA3, fArgAbsNorm, fA2H // (A3*x+A2)*x^2
+ nop.i 0
+}
+{ .mfi
+ ldfe fA10 = [rTailAddr2], 32 // Load A10
+ fma.s1 fTH = fA3, fArgAbsNorm, f0 // (A3*x+A2)*x^2
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe fA9 = [rTailAddr1], 32 // Load A9
+ fma.s1 fTT2 = fA1L, fArgAbsNorm, f0 // A1*x+A0
+ nop.i 0
+}
+{ .mfi
+ ldfe fA8 = [rTailAddr2], 32 // Load A8
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA7 = [rTailAddr1], 32 // Load A7
+ ldfe fA6 = [rTailAddr2], 32 // Load A6
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA5 = [rTailAddr1], 32 // Load A5
+ ldfe fA4 = [rTailAddr2], 32 // Load A4
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fArgAbsNorm2L = fArgAbsNorm, fArgAbsNorm, fArgAbsNorm2
+ // Low part of x^2 (delta)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fArgAbsNorm4 = fArgAbsNorm2, fArgAbsNorm2, f0 // x^4
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fRes3L = fA2H, f1, fRes3H // // (A3*x+A2)*x^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fArgAbsNorm3 = fArgAbsNorm2, fArgAbsNorm, f0 // x^3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fTH2 = fA1H, fArgAbsNorm, fTT2 // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA23 = fA24, fArgAbsNorm, fA23 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA21 = fA22, fArgAbsNorm, fA21 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA12 = fA13, fArgAbsNorm, fA12 // Polynomial tail
+ nop.i 0
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes3L = fRes3L, f1, fTH // (A3*x+A2)*x^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA19 = fA20, fArgAbsNorm, fA19 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1H = fTH2, f1, fA0H // A1*x+A0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fTL2 = fA1H, fArgAbsNorm, fTH2 // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA8 = fA9, fArgAbsNorm, fA8 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA10 = fA11, fArgAbsNorm, fA10 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA16, fArgAbsNorm, fA15 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA17 = fA18, fArgAbsNorm, fA17 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fArgAbsNorm11 = fArgAbsNorm4, fArgAbsNorm4, f0 // x^8
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA5, fArgAbsNorm, fA4 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes3L = fRes3L, f1, fA2L // (A3*x+A2)*x^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA6 = fA7, fArgAbsNorm, fA6 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fTL2 = fTL2, f1, fTT2 // A1*x+A0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fRes1L = fA0H, f1, fRes1H // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA23 = fA25, fArgAbsNorm2, fA23 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA12 = fA14, fArgAbsNorm2, fA12 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA19 = fA21, fArgAbsNorm2, fA19 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA8 = fA10, fArgAbsNorm2, fA8 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA17, fArgAbsNorm2, fA15 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fArgAbsNorm11 = fArgAbsNorm11, fArgAbsNorm3, f0 // x^11
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fTT = fRes3L, fArgAbsNorm2, f0 // (A3*x+A2)*x^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA6, fArgAbsNorm2, fA4 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1L = fRes1L, f1, fTH2 // A1*x+A0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fArgAbsNorm4X = fArgAbsNorm4, fSignumX, f0 // x^4 * signum
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA19 = fA23, fArgAbsNorm4, fA19 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA8 = fA12, fArgAbsNorm4, fA8 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fTT = fRes3H, fArgAbsNorm2L, fTT // (A3*x+A2)*x^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1L = fRes1L, f1, fTL2 // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA15 = fA19, fArgAbsNorm4, fA15 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA4 = fA8, fArgAbsNorm4, fA4 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes2H = fRes3H, fArgAbsNorm2, fTT // (A3*x+A2)*x^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes1L = fRes1L, f1, fA0L // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes4 = fA15, fArgAbsNorm11, fA4 // Result of
+ // polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 fRes2L = fRes3H, fArgAbsNorm2, fRes2H // (A3*x+A2)*x^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fResH = fRes2H, f1, fRes1H // High result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p14) fma.s1 fRes1L = fRes4, fArgAbsNorm4X, fRes1L // A1*x+A0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fms.s1 fRes1L = fRes4, fArgAbsNorm4X, fRes1L // A1*x+A0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes2L = fRes2L, f1, fTT // (A3*x+A2)*x^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 fResL = fRes1H, f1, fResH // Low result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s0 fRes1L = fRes2L, fSignumX, fRes1L // Low result
+ // .s0 - for symmetry issue resolving at +/-inf rounding mode
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fResL = fResL, f1, fRes2H // Low result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p14) fma.s0 fResL = fRes1L, f1, fResL // Low result
+ // .s0 - for symmetry issue resolving at +/-inf rounding mode
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fms.s0 fResL = fRes1L, f1, fResL // Low result
+ // .s0 - for symmetry issue resolving at +/-inf rounding mode
+ nop.i 0
+};;
+
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p14) fma.s0 f8 = fResL, f1, fResH// Add high and low results
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p15) fms.s0 f8 = fResL, f1, fResH // Add high and low results
+ br.ret.sptk b0 // Main path return
+};;
+
+// satiration path ////////////////////////////////////////////////////////////
+_saturation:
+
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p14) fms.s0 f8 = f1, f1, fTiny // Saturation result r = 1-tiny
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+(p15) fnma.s0 f8 = f1, f1, fTiny // Saturation result r = tiny-1
+ br.ret.sptk b0 // Saturation path return
+};;
+
+
+// 0, denormals and special IEEE numbers path /////////////////////////////////
+tanhl_spec:
+
+{ .mfi
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x23 // To filter infinities
+ // 0x23 = @pos|@neg|@inf
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fclass.m p7,p0 = f8, 0xC7 // To filter NaNs & Zeros
+ // 0xC7 = @pos|@neg|@zero|@qnan|@snan
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+(p6) fmerge.s f8 = f8, f1 // +/-1 for INF args
+(p6) br.ret.spnt b0 // exit for x = INF
+};;
+
+{ .mfb
+ nop.m 0
+(p7) fma.s0 f8 = f8, f1, f8 // +/-0 for 0 args
+ // and NaNs for NaNs
+(p7) br.ret.spnt b0 // exit for x = NaN or +/-0
+};;
+
+{ .mfi
+ nop.m 0
+ fnorm.s0 f8 = f8 // Normalize arg
+ nop.i 0
+};;
+
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p14) fnma.s0 f8 = f8, f8, f8 // res = r-r^2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p15) fma.s0 f8 = f8, f8, f8 // res = r+r^2
+ br.ret.sptk b0 // 0, denormals, IEEE specials return
+};;
+
+
+// 0 < |x| < 1/8 path /////////////////////////////////////////////////////////
+_0_to_1o8:
+
+{ .mmi
+ adds rAddr1 = 0x11e0, rDataPtr // Ptr 1 to coeffs
+ adds rAddr2 = 0x11f0, rDataPtr // Ptr 2 to coeffs
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA15 = [rAddr1], 32 // Load A15
+ ldfe fA13 = [rAddr2], 32 // Load A13
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA11 = [rAddr1], 32 // Load A11
+ ldfe fA9 = [rAddr2], 32 // Load A9
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe fA7 = [rAddr1], 32 // Load A7
+ ldfe fA5 = [rAddr2] // Load A5
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe fA3 = [rAddr1] // Load A3
+ fma.s1 fA11 = fA13, fArgSqr, fA11 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fArgFour = fArgSqr, fArgSqr, f0 // a^4
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA3 = fA5, fArgSqr, fA3 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fA7 = fA9, fArgSqr, fA7 // Polynomial tail
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA11 = fA15, fArgFour, fA11 // Polynomial tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fA3 = fA7, fArgFour, fA3 // Polynomial tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 fArgEight = fArgFour, fArgFour, f0 // a^8
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 fRes = fA11, fArgEight, fA3 //Polynomial tail result
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+ fma.s0 f8 = fRes, fArgCube, f8 // (Polynomial tail)*x^3
+ br.ret.sptk b0 // [0;1/8] interval return
+};;
+
+GLOBAL_LIBM_END(tanhl)
+
+
+
+
diff --git a/libc/sysdeps/ia64/fpu/s_tanl.S b/libc/sysdeps/ia64/fpu/s_tanl.S
new file mode 100644
index 000000000..607a27154
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_tanl.S
@@ -0,0 +1,3248 @@
+.file "tancotl.s"
+
+
+// Copyright (c) 2000 - 2004, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+//
+// 02/02/00 (hand-optimized)
+// 04/04/00 Unwind support added
+// 12/28/00 Fixed false invalid flags
+// 02/06/02 Improved speed
+// 05/07/02 Changed interface to __libm_pi_by_2_reduce
+// 05/30/02 Added cotl
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+// 05/15/03 Reformatted data tables
+// 10/26/04 Avoided using r14-31 as scratch so not clobbered by dynamic loader
+//
+//*********************************************************************
+//
+// Functions: tanl(x) = tangent(x), for double-extended precision x values
+// cotl(x) = cotangent(x), for double-extended precision x values
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8 (Input and Return Value)
+// f9-f15
+// f32-f121
+//
+// General Purpose Registers:
+// r32-r70
+//
+// Predicate Registers: p6-p15
+//
+//*********************************************************************
+//
+// IEEE Special Conditions for tanl:
+//
+// Denormal fault raised on denormal inputs
+// Overflow exceptions do not occur
+// Underflow exceptions raised when appropriate for tan
+// (No specialized error handling for this routine)
+// Inexact raised when appropriate by algorithm
+//
+// tanl(SNaN) = QNaN
+// tanl(QNaN) = QNaN
+// tanl(inf) = QNaN
+// tanl(+/-0) = +/-0
+//
+//*********************************************************************
+//
+// IEEE Special Conditions for cotl:
+//
+// Denormal fault raised on denormal inputs
+// Overflow exceptions occur at zero and near zero
+// Underflow exceptions do not occur
+// Inexact raised when appropriate by algorithm
+//
+// cotl(SNaN) = QNaN
+// cotl(QNaN) = QNaN
+// cotl(inf) = QNaN
+// cotl(+/-0) = +/-Inf and error handling is called
+//
+//*********************************************************************
+//
+// Below are mathematical and algorithmic descriptions for tanl.
+// For cotl we use next identity cot(x) = -tan(x + Pi/2).
+// So, to compute cot(x) we just need to increment N (N = N + 1)
+// and invert sign of the computed result.
+//
+//*********************************************************************
+//
+// Mathematical Description
+//
+// We consider the computation of FPTANL of Arg. Now, given
+//
+// Arg = N pi/2 + alpha, |alpha| <= pi/4,
+//
+// basic mathematical relationship shows that
+//
+// tan( Arg ) = tan( alpha ) if N is even;
+// = -cot( alpha ) otherwise.
+//
+// The value of alpha is obtained by argument reduction and
+// represented by two working precision numbers r and c where
+//
+// alpha = r + c accurately.
+//
+// The reduction method is described in a previous write up.
+// The argument reduction scheme identifies 4 cases. For Cases 2
+// and 4, because |alpha| is small, tan(r+c) and -cot(r+c) can be
+// computed very easily by 2 or 3 terms of the Taylor series
+// expansion as follows:
+//
+// Case 2:
+// -------
+//
+// tan(r + c) = r + c + r^3/3 ...accurately
+// -cot(r + c) = -1/(r+c) + r/3 ...accurately
+//
+// Case 4:
+// -------
+//
+// tan(r + c) = r + c + r^3/3 + 2r^5/15 ...accurately
+// -cot(r + c) = -1/(r+c) + r/3 + r^3/45 ...accurately
+//
+//
+// The only cases left are Cases 1 and 3 of the argument reduction
+// procedure. These two cases will be merged since after the
+// argument is reduced in either cases, we have the reduced argument
+// represented as r + c and that the magnitude |r + c| is not small
+// enough to allow the usage of a very short approximation.
+//
+// The greatest challenge of this task is that the second terms of
+// the Taylor series for tan(r) and -cot(r)
+//
+// r + r^3/3 + 2 r^5/15 + ...
+//
+// and
+//
+// -1/r + r/3 + r^3/45 + ...
+//
+// are not very small when |r| is close to pi/4 and the rounding
+// errors will be a concern if simple polynomial accumulation is
+// used. When |r| < 2^(-2), however, the second terms will be small
+// enough (5 bits or so of right shift) that a normal Horner
+// recurrence suffices. Hence there are two cases that we consider
+// in the accurate computation of tan(r) and cot(r), |r| <= pi/4.
+//
+// Case small_r: |r| < 2^(-2)
+// --------------------------
+//
+// Since Arg = N pi/4 + r + c accurately, we have
+//
+// tan(Arg) = tan(r+c) for N even,
+// = -cot(r+c) otherwise.
+//
+// Here for this case, both tan(r) and -cot(r) can be approximated
+// by simple polynomials:
+//
+// tan(r) = r + P1_1 r^3 + P1_2 r^5 + ... + P1_9 r^19
+// -cot(r) = -1/r + Q1_1 r + Q1_2 r^3 + ... + Q1_7 r^13
+//
+// accurately. Since |r| is relatively small, tan(r+c) and
+// -cot(r+c) can be accurately approximated by replacing r with
+// r+c only in the first two terms of the corresponding polynomials.
+//
+// Note that P1_1 (and Q1_1 for that matter) approximates 1/3 to
+// almost 64 sig. bits, thus
+//
+// P1_1 (r+c)^3 = P1_1 r^3 + c * r^2 accurately.
+//
+// Hence,
+//
+// tan(r+c) = r + P1_1 r^3 + P1_2 r^5 + ... + P1_9 r^19
+// + c*(1 + r^2)
+//
+// -cot(r+c) = -1/(r+c) + Q1_1 r + Q1_2 r^3 + ... + Q1_7 r^13
+// + Q1_1*c
+//
+//
+// Case normal_r: 2^(-2) <= |r| <= pi/4
+// ------------------------------------
+//
+// This case is more likely than the previous one if one considers
+// r to be uniformly distributed in [-pi/4 pi/4].
+//
+// The required calculation is either
+//
+// tan(r + c) = tan(r) + correction, or
+// -cot(r + c) = -cot(r) + correction.
+//
+// Specifically,
+//
+// tan(r + c) = tan(r) + c tan'(r) + O(c^2)
+// = tan(r) + c sec^2(r) + O(c^2)
+// = tan(r) + c SEC_sq ...accurately
+// as long as SEC_sq approximates sec^2(r)
+// to, say, 5 bits or so.
+//
+// Similarly,
+//
+// -cot(r + c) = -cot(r) - c cot'(r) + O(c^2)
+// = -cot(r) + c csc^2(r) + O(c^2)
+// = -cot(r) + c CSC_sq ...accurately
+// as long as CSC_sq approximates csc^2(r)
+// to, say, 5 bits or so.
+//
+// We therefore concentrate on accurately calculating tan(r) and
+// cot(r) for a working-precision number r, |r| <= pi/4 to within
+// 0.1% or so.
+//
+// We will employ a table-driven approach. Let
+//
+// r = sgn_r * 2^k * 1.b_1 b_2 ... b_5 ... b_63
+// = sgn_r * ( B + x )
+//
+// where
+//
+// B = 2^k * 1.b_1 b_2 ... b_5 1
+// x = |r| - B
+//
+// Now,
+// tan(B) + tan(x)
+// tan( B + x ) = ------------------------
+// 1 - tan(B)*tan(x)
+//
+// / \
+// | tan(B) + tan(x) |
+
+// = tan(B) + | ------------------------ - tan(B) |
+// | 1 - tan(B)*tan(x) |
+// \ /
+//
+// sec^2(B) * tan(x)
+// = tan(B) + ------------------------
+// 1 - tan(B)*tan(x)
+//
+// (1/[sin(B)*cos(B)]) * tan(x)
+// = tan(B) + --------------------------------
+// cot(B) - tan(x)
+//
+//
+// Clearly, the values of tan(B), cot(B) and 1/(sin(B)*cos(B)) are
+// calculated beforehand and stored in a table. Since
+//
+// |x| <= 2^k * 2^(-6) <= 2^(-7) (because k = -1, -2)
+//
+// a very short polynomial will be sufficient to approximate tan(x)
+// accurately. The details involved in computing the last expression
+// will be given in the next section on algorithm description.
+//
+//
+// Now, we turn to the case where cot( B + x ) is needed.
+//
+//
+// 1 - tan(B)*tan(x)
+// cot( B + x ) = ------------------------
+// tan(B) + tan(x)
+//
+// / \
+// | 1 - tan(B)*tan(x) |
+
+// = cot(B) + | ----------------------- - cot(B) |
+// | tan(B) + tan(x) |
+// \ /
+//
+// [tan(B) + cot(B)] * tan(x)
+// = cot(B) - ----------------------------
+// tan(B) + tan(x)
+//
+// (1/[sin(B)*cos(B)]) * tan(x)
+// = cot(B) - --------------------------------
+// tan(B) + tan(x)
+//
+//
+// Note that the values of tan(B), cot(B) and 1/(sin(B)*cos(B)) that
+// are needed are the same set of values needed in the previous
+// case.
+//
+// Finally, we can put all the ingredients together as follows:
+//
+// Arg = N * pi/2 + r + c ...accurately
+//
+// tan(Arg) = tan(r) + correction if N is even;
+// = -cot(r) + correction otherwise.
+//
+// For Cases 2 and 4,
+//
+// Case 2:
+// tan(Arg) = tan(r + c) = r + c + r^3/3 N even
+// = -cot(r + c) = -1/(r+c) + r/3 N odd
+// Case 4:
+// tan(Arg) = tan(r + c) = r + c + r^3/3 + 2r^5/15 N even
+// = -cot(r + c) = -1/(r+c) + r/3 + r^3/45 N odd
+//
+//
+// For Cases 1 and 3,
+//
+// Case small_r: |r| < 2^(-2)
+//
+// tan(Arg) = r + P1_1 r^3 + P1_2 r^5 + ... + P1_9 r^19
+// + c*(1 + r^2) N even
+//
+// = -1/(r+c) + Q1_1 r + Q1_2 r^3 + ... + Q1_7 r^13
+// + Q1_1*c N odd
+//
+// Case normal_r: 2^(-2) <= |r| <= pi/4
+//
+// tan(Arg) = tan(r) + c * sec^2(r) N even
+// = -cot(r) + c * csc^2(r) otherwise
+//
+// For N even,
+//
+// tan(Arg) = tan(r) + c*sec^2(r)
+// = tan( sgn_r * (B+x) ) + c * sec^2(|r|)
+// = sgn_r * ( tan(B+x) + sgn_r*c*sec^2(|r|) )
+// = sgn_r * ( tan(B+x) + sgn_r*c*sec^2(B) )
+//
+// since B approximates |r| to 2^(-6) in relative accuracy.
+//
+// / (1/[sin(B)*cos(B)]) * tan(x)
+// tan(Arg) = sgn_r * | tan(B) + --------------------------------
+// \ cot(B) - tan(x)
+// \
+// + CORR |
+
+// /
+// where
+//
+// CORR = sgn_r*c*tan(B)*SC_inv(B); SC_inv(B) = 1/(sin(B)*cos(B)).
+//
+// For N odd,
+//
+// tan(Arg) = -cot(r) + c*csc^2(r)
+// = -cot( sgn_r * (B+x) ) + c * csc^2(|r|)
+// = sgn_r * ( -cot(B+x) + sgn_r*c*csc^2(|r|) )
+// = sgn_r * ( -cot(B+x) + sgn_r*c*csc^2(B) )
+//
+// since B approximates |r| to 2^(-6) in relative accuracy.
+//
+// / (1/[sin(B)*cos(B)]) * tan(x)
+// tan(Arg) = sgn_r * | -cot(B) + --------------------------------
+// \ tan(B) + tan(x)
+// \
+// + CORR |
+
+// /
+// where
+//
+// CORR = sgn_r*c*cot(B)*SC_inv(B); SC_inv(B) = 1/(sin(B)*cos(B)).
+//
+//
+// The actual algorithm prescribes how all the mathematical formulas
+// are calculated.
+//
+//
+// 2. Algorithmic Description
+// ==========================
+//
+// 2.1 Computation for Cases 2 and 4.
+// ----------------------------------
+//
+// For Case 2, we use two-term polynomials.
+//
+// For N even,
+//
+// rsq := r * r
+// Poly := c + r * rsq * P1_1
+// Result := r + Poly ...in user-defined rounding
+//
+// For N odd,
+// S_hi := -frcpa(r) ...8 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...16 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...32 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...64 bits
+// S_lo := S_hi*( (1 + S_hi*r) + S_hi*c )
+// ...S_hi + S_lo is -1/(r+c) to extra precision
+// S_lo := S_lo + Q1_1*r
+//
+// Result := S_hi + S_lo ...in user-defined rounding
+//
+// For Case 4, we use three-term polynomials
+//
+// For N even,
+//
+// rsq := r * r
+// Poly := c + r * rsq * (P1_1 + rsq * P1_2)
+// Result := r + Poly ...in user-defined rounding
+//
+// For N odd,
+// S_hi := -frcpa(r) ...8 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...16 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...32 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...64 bits
+// S_lo := S_hi*( (1 + S_hi*r) + S_hi*c )
+// ...S_hi + S_lo is -1/(r+c) to extra precision
+// rsq := r * r
+// P := Q1_1 + rsq*Q1_2
+// S_lo := S_lo + r*P
+//
+// Result := S_hi + S_lo ...in user-defined rounding
+//
+//
+// Note that the coefficients P1_1, P1_2, Q1_1, and Q1_2 are
+// the same as those used in the small_r case of Cases 1 and 3
+// below.
+//
+//
+// 2.2 Computation for Cases 1 and 3.
+// ----------------------------------
+// This is further divided into the case of small_r,
+// where |r| < 2^(-2), and the case of normal_r, where |r| lies between
+// 2^(-2) and pi/4.
+//
+// Algorithm for the case of small_r
+// ---------------------------------
+//
+// For N even,
+// rsq := r * r
+// Poly1 := rsq*(P1_1 + rsq*(P1_2 + rsq*P1_3))
+// r_to_the_8 := rsq * rsq
+// r_to_the_8 := r_to_the_8 * r_to_the_8
+// Poly2 := P1_4 + rsq*(P1_5 + rsq*(P1_6 + ... rsq*P1_9))
+// CORR := c * ( 1 + rsq )
+// Poly := Poly1 + r_to_the_8*Poly2
+// Poly := r*Poly + CORR
+// Result := r + Poly ...in user-defined rounding
+// ...note that Poly1 and r_to_the_8 can be computed in parallel
+// ...with Poly2 (Poly1 is intentionally set to be much
+// ...shorter than Poly2 so that r_to_the_8 and CORR can be hidden)
+//
+// For N odd,
+// S_hi := -frcpa(r) ...8 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...16 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...32 bits
+// S_hi := S_hi + S_hi*(1 + S_hi*r) ...64 bits
+// S_lo := S_hi*( (1 + S_hi*r) + S_hi*c )
+// ...S_hi + S_lo is -1/(r+c) to extra precision
+// S_lo := S_lo + Q1_1*c
+//
+// ...S_hi and S_lo are computed in parallel with
+// ...the following
+// rsq := r*r
+// P := Q1_1 + rsq*(Q1_2 + rsq*(Q1_3 + ... + rsq*Q1_7))
+//
+// Poly := r*P + S_lo
+// Result := S_hi + Poly ...in user-defined rounding
+//
+//
+// Algorithm for the case of normal_r
+// ----------------------------------
+//
+// Here, we first consider the computation of tan( r + c ). As
+// presented in the previous section,
+//
+// tan( r + c ) = tan(r) + c * sec^2(r)
+// = sgn_r * [ tan(B+x) + CORR ]
+// CORR = sgn_r * c * tan(B) * 1/[sin(B)*cos(B)]
+//
+// because sec^2(r) = sec^(|r|), and B approximate |r| to 6.5 bits.
+//
+// tan( r + c ) =
+// / (1/[sin(B)*cos(B)]) * tan(x)
+// sgn_r * | tan(B) + -------------------------------- +
+// \ cot(B) - tan(x)
+// \
+// CORR |
+
+// /
+//
+// The values of tan(B), cot(B) and 1/(sin(B)*cos(B)) are
+// calculated beforehand and stored in a table. Specifically,
+// the table values are
+//
+// tan(B) as T_hi + T_lo;
+// cot(B) as C_hi + C_lo;
+// 1/[sin(B)*cos(B)] as SC_inv
+//
+// T_hi, C_hi are in double-precision memory format;
+// T_lo, C_lo are in single-precision memory format;
+// SC_inv is in extended-precision memory format.
+//
+// The value of tan(x) will be approximated by a short polynomial of
+// the form
+//
+// tan(x) as x + x * P, where
+// P = x^2 * (P2_1 + x^2 * (P2_2 + x^2 * P2_3))
+//
+// Because |x| <= 2^(-7), cot(B) - x approximates cot(B) - tan(x)
+// to a relative accuracy better than 2^(-20). Thus, a good
+// initial guess of 1/( cot(B) - tan(x) ) to initiate the iterative
+// division is:
+//
+// 1/(cot(B) - tan(x)) is approximately
+// 1/(cot(B) - x) is
+// tan(B)/(1 - x*tan(B)) is approximately
+// T_hi / ( 1 - T_hi * x ) is approximately
+//
+// T_hi * [ 1 + (Thi * x) + (T_hi * x)^2 ]
+//
+// The calculation of tan(r+c) therefore proceed as follows:
+//
+// Tx := T_hi * x
+// xsq := x * x
+//
+// V_hi := T_hi*(1 + Tx*(1 + Tx))
+// P := xsq * (P1_1 + xsq*(P1_2 + xsq*P1_3))
+// ...V_hi serves as an initial guess of 1/(cot(B) - tan(x))
+// ...good to about 20 bits of accuracy
+//
+// tanx := x + x*P
+// D := C_hi - tanx
+// ...D is a double precision denominator: cot(B) - tan(x)
+//
+// V_hi := V_hi + V_hi*(1 - V_hi*D)
+// ....V_hi approximates 1/(cot(B)-tan(x)) to 40 bits
+//
+// V_lo := V_hi * ( [ (1 - V_hi*C_hi) + V_hi*tanx ]
+// - V_hi*C_lo ) ...observe all order
+// ...V_hi + V_lo approximates 1/(cot(B) - tan(x))
+// ...to extra accuracy
+//
+// ... SC_inv(B) * (x + x*P)
+// ... tan(B) + ------------------------- + CORR
+// ... cot(B) - (x + x*P)
+// ...
+// ... = tan(B) + SC_inv(B)*(x + x*P)*(V_hi + V_lo) + CORR
+// ...
+//
+// Sx := SC_inv * x
+// CORR := sgn_r * c * SC_inv * T_hi
+//
+// ...put the ingredients together to compute
+// ... SC_inv(B) * (x + x*P)
+// ... tan(B) + ------------------------- + CORR
+// ... cot(B) - (x + x*P)
+// ...
+// ... = tan(B) + SC_inv(B)*(x + x*P)*(V_hi + V_lo) + CORR
+// ...
+// ... = T_hi + T_lo + CORR +
+// ... Sx * V_hi + Sx * V_lo + Sx * P *(V_hi + V_lo)
+//
+// CORR := CORR + T_lo
+// tail := V_lo + P*(V_hi + V_lo)
+// tail := Sx * tail + CORR
+// tail := Sx * V_hi + tail
+// T_hi := sgn_r * T_hi
+//
+// ...T_hi + sgn_r*tail now approximate
+// ...sgn_r*(tan(B+x) + CORR) accurately
+//
+// Result := T_hi + sgn_r*tail ...in user-defined
+// ...rounding control
+// ...It is crucial that independent paths be fully
+// ...exploited for performance's sake.
+//
+//
+// Next, we consider the computation of -cot( r + c ). As
+// presented in the previous section,
+//
+// -cot( r + c ) = -cot(r) + c * csc^2(r)
+// = sgn_r * [ -cot(B+x) + CORR ]
+// CORR = sgn_r * c * cot(B) * 1/[sin(B)*cos(B)]
+//
+// because csc^2(r) = csc^(|r|), and B approximate |r| to 6.5 bits.
+//
+// -cot( r + c ) =
+// / (1/[sin(B)*cos(B)]) * tan(x)
+// sgn_r * | -cot(B) + -------------------------------- +
+// \ tan(B) + tan(x)
+// \
+// CORR |
+
+// /
+//
+// The values of tan(B), cot(B) and 1/(sin(B)*cos(B)) are
+// calculated beforehand and stored in a table. Specifically,
+// the table values are
+//
+// tan(B) as T_hi + T_lo;
+// cot(B) as C_hi + C_lo;
+// 1/[sin(B)*cos(B)] as SC_inv
+//
+// T_hi, C_hi are in double-precision memory format;
+// T_lo, C_lo are in single-precision memory format;
+// SC_inv is in extended-precision memory format.
+//
+// The value of tan(x) will be approximated by a short polynomial of
+// the form
+//
+// tan(x) as x + x * P, where
+// P = x^2 * (P2_1 + x^2 * (P2_2 + x^2 * P2_3))
+//
+// Because |x| <= 2^(-7), tan(B) + x approximates tan(B) + tan(x)
+// to a relative accuracy better than 2^(-18). Thus, a good
+// initial guess of 1/( tan(B) + tan(x) ) to initiate the iterative
+// division is:
+//
+// 1/(tan(B) + tan(x)) is approximately
+// 1/(tan(B) + x) is
+// cot(B)/(1 + x*cot(B)) is approximately
+// C_hi / ( 1 + C_hi * x ) is approximately
+//
+// C_hi * [ 1 - (C_hi * x) + (C_hi * x)^2 ]
+//
+// The calculation of -cot(r+c) therefore proceed as follows:
+//
+// Cx := C_hi * x
+// xsq := x * x
+//
+// V_hi := C_hi*(1 - Cx*(1 - Cx))
+// P := xsq * (P1_1 + xsq*(P1_2 + xsq*P1_3))
+// ...V_hi serves as an initial guess of 1/(tan(B) + tan(x))
+// ...good to about 18 bits of accuracy
+//
+// tanx := x + x*P
+// D := T_hi + tanx
+// ...D is a double precision denominator: tan(B) + tan(x)
+//
+// V_hi := V_hi + V_hi*(1 - V_hi*D)
+// ....V_hi approximates 1/(tan(B)+tan(x)) to 40 bits
+//
+// V_lo := V_hi * ( [ (1 - V_hi*T_hi) - V_hi*tanx ]
+// - V_hi*T_lo ) ...observe all order
+// ...V_hi + V_lo approximates 1/(tan(B) + tan(x))
+// ...to extra accuracy
+//
+// ... SC_inv(B) * (x + x*P)
+// ... -cot(B) + ------------------------- + CORR
+// ... tan(B) + (x + x*P)
+// ...
+// ... =-cot(B) + SC_inv(B)*(x + x*P)*(V_hi + V_lo) + CORR
+// ...
+//
+// Sx := SC_inv * x
+// CORR := sgn_r * c * SC_inv * C_hi
+//
+// ...put the ingredients together to compute
+// ... SC_inv(B) * (x + x*P)
+// ... -cot(B) + ------------------------- + CORR
+// ... tan(B) + (x + x*P)
+// ...
+// ... =-cot(B) + SC_inv(B)*(x + x*P)*(V_hi + V_lo) + CORR
+// ...
+// ... =-C_hi - C_lo + CORR +
+// ... Sx * V_hi + Sx * V_lo + Sx * P *(V_hi + V_lo)
+//
+// CORR := CORR - C_lo
+// tail := V_lo + P*(V_hi + V_lo)
+// tail := Sx * tail + CORR
+// tail := Sx * V_hi + tail
+// C_hi := -sgn_r * C_hi
+//
+// ...C_hi + sgn_r*tail now approximates
+// ...sgn_r*(-cot(B+x) + CORR) accurately
+//
+// Result := C_hi + sgn_r*tail in user-defined rounding control
+// ...It is crucial that independent paths be fully
+// ...exploited for performance's sake.
+//
+// 3. Implementation Notes
+// =======================
+//
+// Table entries T_hi, T_lo; C_hi, C_lo; SC_inv
+//
+// Recall that 2^(-2) <= |r| <= pi/4;
+//
+// r = sgn_r * 2^k * 1.b_1 b_2 ... b_63
+//
+// and
+//
+// B = 2^k * 1.b_1 b_2 b_3 b_4 b_5 1
+//
+// Thus, for k = -2, possible values of B are
+//
+// B = 2^(-2) * ( 1 + index/32 + 1/64 ),
+// index ranges from 0 to 31
+//
+// For k = -1, however, since |r| <= pi/4 = 0.78...
+// possible values of B are
+//
+// B = 2^(-1) * ( 1 + index/32 + 1/64 )
+// index ranges from 0 to 19.
+//
+//
+
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(TANL_BASE_CONSTANTS)
+
+tanl_table_1:
+data8 0xA2F9836E4E44152A, 0x00003FFE // two_by_pi
+data8 0xC84D32B0CE81B9F1, 0x00004016 // P_0
+data8 0xC90FDAA22168C235, 0x00003FFF // P_1
+data8 0xECE675D1FC8F8CBB, 0x0000BFBD // P_2
+data8 0xB7ED8FBBACC19C60, 0x0000BF7C // P_3
+LOCAL_OBJECT_END(TANL_BASE_CONSTANTS)
+
+LOCAL_OBJECT_START(tanl_table_2)
+data8 0xC90FDAA22168C234, 0x00003FFE // PI_BY_4
+data8 0xA397E5046EC6B45A, 0x00003FE7 // Inv_P_0
+data8 0x8D848E89DBD171A1, 0x0000BFBF // d_1
+data8 0xD5394C3618A66F8E, 0x0000BF7C // d_2
+data4 0x3E800000 // two**-2
+data4 0xBE800000 // -two**-2
+data4 0x00000000 // pad
+data4 0x00000000 // pad
+LOCAL_OBJECT_END(tanl_table_2)
+
+LOCAL_OBJECT_START(tanl_table_p1)
+data8 0xAAAAAAAAAAAAAABD, 0x00003FFD // P1_1
+data8 0x8888888888882E6A, 0x00003FFC // P1_2
+data8 0xDD0DD0DD0F0177B6, 0x00003FFA // P1_3
+data8 0xB327A440646B8C6D, 0x00003FF9 // P1_4
+data8 0x91371B251D5F7D20, 0x00003FF8 // P1_5
+data8 0xEB69A5F161C67914, 0x00003FF6 // P1_6
+data8 0xBEDD37BE019318D2, 0x00003FF5 // P1_7
+data8 0x9979B1463C794015, 0x00003FF4 // P1_8
+data8 0x8EBD21A38C6EB58A, 0x00003FF3 // P1_9
+LOCAL_OBJECT_END(tanl_table_p1)
+
+LOCAL_OBJECT_START(tanl_table_q1)
+data8 0xAAAAAAAAAAAAAAB4, 0x00003FFD // Q1_1
+data8 0xB60B60B60B5FC93E, 0x00003FF9 // Q1_2
+data8 0x8AB355E00C9BBFBF, 0x00003FF6 // Q1_3
+data8 0xDDEBBC89CBEE3D4C, 0x00003FF2 // Q1_4
+data8 0xB3548A685F80BBB6, 0x00003FEF // Q1_5
+data8 0x913625604CED5BF1, 0x00003FEC // Q1_6
+data8 0xF189D95A8EE92A83, 0x00003FE8 // Q1_7
+LOCAL_OBJECT_END(tanl_table_q1)
+
+LOCAL_OBJECT_START(tanl_table_p2)
+data8 0xAAAAAAAAAAAB362F, 0x00003FFD // P2_1
+data8 0x88888886E97A6097, 0x00003FFC // P2_2
+data8 0xDD108EE025E716A1, 0x00003FFA // P2_3
+LOCAL_OBJECT_END(tanl_table_p2)
+
+LOCAL_OBJECT_START(tanl_table_tm2)
+//
+// Entries T_hi double-precision memory format
+// Index = 0,1,...,31 B = 2^(-2)*(1+Index/32+1/64)
+// Entries T_lo single-precision memory format
+// Index = 0,1,...,31 B = 2^(-2)*(1+Index/32+1/64)
+//
+data8 0x3FD09BC362400794
+data4 0x23A05C32, 0x00000000
+data8 0x3FD124A9DFFBC074
+data4 0x240078B2, 0x00000000
+data8 0x3FD1AE235BD4920F
+data4 0x23826B8E, 0x00000000
+data8 0x3FD2383515E2701D
+data4 0x22D31154, 0x00000000
+data8 0x3FD2C2E463739C2D
+data4 0x2265C9E2, 0x00000000
+data8 0x3FD34E36AFEEA48B
+data4 0x245C05EB, 0x00000000
+data8 0x3FD3DA317DBB35D1
+data4 0x24749F2D, 0x00000000
+data8 0x3FD466DA67321619
+data4 0x2462CECE, 0x00000000
+data8 0x3FD4F4371F94A4D5
+data4 0x246D0DF1, 0x00000000
+data8 0x3FD5824D740C3E6D
+data4 0x240A85B5, 0x00000000
+data8 0x3FD611234CB1E73D
+data4 0x23F96E33, 0x00000000
+data8 0x3FD6A0BEAD9EA64B
+data4 0x247C5393, 0x00000000
+data8 0x3FD73125B804FD01
+data4 0x241F3B29, 0x00000000
+data8 0x3FD7C25EAB53EE83
+data4 0x2479989B, 0x00000000
+data8 0x3FD8546FE6640EED
+data4 0x23B343BC, 0x00000000
+data8 0x3FD8E75FE8AF1892
+data4 0x241454D1, 0x00000000
+data8 0x3FD97B3553928BDA
+data4 0x238613D9, 0x00000000
+data8 0x3FDA0FF6EB9DE4DE
+data4 0x22859FA7, 0x00000000
+data8 0x3FDAA5AB99ECF92D
+data4 0x237A6D06, 0x00000000
+data8 0x3FDB3C5A6D8F1796
+data4 0x23952F6C, 0x00000000
+data8 0x3FDBD40A9CFB8BE4
+data4 0x2280FC95, 0x00000000
+data8 0x3FDC6CC387943100
+data4 0x245D2EC0, 0x00000000
+data8 0x3FDD068CB736C500
+data4 0x23C4AD7D, 0x00000000
+data8 0x3FDDA16DE1DDBC31
+data4 0x23D076E6, 0x00000000
+data8 0x3FDE3D6EEB515A93
+data4 0x244809A6, 0x00000000
+data8 0x3FDEDA97E6E9E5F1
+data4 0x220856C8, 0x00000000
+data8 0x3FDF78F11963CE69
+data4 0x244BE993, 0x00000000
+data8 0x3FE00C417D635BCE
+data4 0x23D21799, 0x00000000
+data8 0x3FE05CAB1C302CD3
+data4 0x248A1B1D, 0x00000000
+data8 0x3FE0ADB9DB6A1FA0
+data4 0x23D53E33, 0x00000000
+data8 0x3FE0FF724A20BA81
+data4 0x24DB9ED5, 0x00000000
+data8 0x3FE151D9153FA6F5
+data4 0x24E9E451, 0x00000000
+LOCAL_OBJECT_END(tanl_table_tm2)
+
+LOCAL_OBJECT_START(tanl_table_tm1)
+//
+// Entries T_hi double-precision memory format
+// Index = 0,1,...,19 B = 2^(-1)*(1+Index/32+1/64)
+// Entries T_lo single-precision memory format
+// Index = 0,1,...,19 B = 2^(-1)*(1+Index/32+1/64)
+//
+data8 0x3FE1CEC4BA1BE39E
+data4 0x24B60F9E, 0x00000000
+data8 0x3FE277E45ABD9B2D
+data4 0x248C2474, 0x00000000
+data8 0x3FE324180272B110
+data4 0x247B8311, 0x00000000
+data8 0x3FE3D38B890E2DF0
+data4 0x24C55751, 0x00000000
+data8 0x3FE4866D46236871
+data4 0x24E5BC34, 0x00000000
+data8 0x3FE53CEE45E044B0
+data4 0x24001BA4, 0x00000000
+data8 0x3FE5F74282EC06E4
+data4 0x24B973DC, 0x00000000
+data8 0x3FE6B5A125DF43F9
+data4 0x24895440, 0x00000000
+data8 0x3FE77844CAFD348C
+data4 0x240021CA, 0x00000000
+data8 0x3FE83F6BCEED6B92
+data4 0x24C45372, 0x00000000
+data8 0x3FE90B58A34F3665
+data4 0x240DAD33, 0x00000000
+data8 0x3FE9DC522C1E56B4
+data4 0x24F846CE, 0x00000000
+data8 0x3FEAB2A427041578
+data4 0x2323FB6E, 0x00000000
+data8 0x3FEB8E9F9DD8C373
+data4 0x24B3090B, 0x00000000
+data8 0x3FEC709B65C9AA7B
+data4 0x2449F611, 0x00000000
+data8 0x3FED58F4ACCF8435
+data4 0x23616A7E, 0x00000000
+data8 0x3FEE480F97635082
+data4 0x24C2FEAE, 0x00000000
+data8 0x3FEF3E57F0ACC544
+data4 0x242CE964, 0x00000000
+data8 0x3FF01E20F7E06E4B
+data4 0x2480D3EE, 0x00000000
+data8 0x3FF0A1258A798A69
+data4 0x24DB8967, 0x00000000
+LOCAL_OBJECT_END(tanl_table_tm1)
+
+LOCAL_OBJECT_START(tanl_table_cm2)
+//
+// Entries C_hi double-precision memory format
+// Index = 0,1,...,31 B = 2^(-2)*(1+Index/32+1/64)
+// Entries C_lo single-precision memory format
+// Index = 0,1,...,31 B = 2^(-2)*(1+Index/32+1/64)
+//
+data8 0x400ED3E2E63EFBD0
+data4 0x259D94D4, 0x00000000
+data8 0x400DDDB4C515DAB5
+data4 0x245F0537, 0x00000000
+data8 0x400CF57ABE19A79F
+data4 0x25D4EA9F, 0x00000000
+data8 0x400C1A06D15298ED
+data4 0x24AE40A0, 0x00000000
+data8 0x400B4A4C164B2708
+data4 0x25A5AAB6, 0x00000000
+data8 0x400A855A5285B068
+data4 0x25524F18, 0x00000000
+data8 0x4009CA5A3FFA549F
+data4 0x24C999C0, 0x00000000
+data8 0x4009188A646AF623
+data4 0x254FD801, 0x00000000
+data8 0x40086F3C6084D0E7
+data4 0x2560F5FD, 0x00000000
+data8 0x4007CDD2A29A76EE
+data4 0x255B9D19, 0x00000000
+data8 0x400733BE6C8ECA95
+data4 0x25CB021B, 0x00000000
+data8 0x4006A07E1F8DDC52
+data4 0x24AB4722, 0x00000000
+data8 0x4006139BC298AD58
+data4 0x252764E2, 0x00000000
+data8 0x40058CABBAD7164B
+data4 0x24DAF5DB, 0x00000000
+data8 0x40050B4BAE31A5D3
+data4 0x25EA20F4, 0x00000000
+data8 0x40048F2189F85A8A
+data4 0x2583A3E8, 0x00000000
+data8 0x400417DAA862380D
+data4 0x25DCC4CC, 0x00000000
+data8 0x4003A52B1088FCFE
+data4 0x2430A492, 0x00000000
+data8 0x400336CCCD3527D5
+data4 0x255F77CF, 0x00000000
+data8 0x4002CC7F5760766D
+data4 0x25DA0BDA, 0x00000000
+data8 0x4002660711CE02E3
+data4 0x256FF4A2, 0x00000000
+data8 0x4002032CD37BBE04
+data4 0x25208AED, 0x00000000
+data8 0x4001A3BD7F050775
+data4 0x24B72DD6, 0x00000000
+data8 0x40014789A554848A
+data4 0x24AB4DAA, 0x00000000
+data8 0x4000EE65323E81B7
+data4 0x2584C440, 0x00000000
+data8 0x4000982721CF1293
+data4 0x25C9428D, 0x00000000
+data8 0x400044A93D415EEB
+data4 0x25DC8482, 0x00000000
+data8 0x3FFFE78FBD72C577
+data4 0x257F5070, 0x00000000
+data8 0x3FFF4AC375EFD28E
+data4 0x23EBBF7A, 0x00000000
+data8 0x3FFEB2AF60B52DDE
+data4 0x22EECA07, 0x00000000
+data8 0x3FFE1F1935204180
+data4 0x24191079, 0x00000000
+data8 0x3FFD8FCA54F7E60A
+data4 0x248D3058, 0x00000000
+LOCAL_OBJECT_END(tanl_table_cm2)
+
+LOCAL_OBJECT_START(tanl_table_cm1)
+//
+// Entries C_hi double-precision memory format
+// Index = 0,1,...,19 B = 2^(-1)*(1+Index/32+1/64)
+// Entries C_lo single-precision memory format
+// Index = 0,1,...,19 B = 2^(-1)*(1+Index/32+1/64)
+//
+data8 0x3FFCC06A79F6FADE
+data4 0x239C7886, 0x00000000
+data8 0x3FFBB91F891662A6
+data4 0x250BD191, 0x00000000
+data8 0x3FFABFB6529F155D
+data4 0x256CC3E6, 0x00000000
+data8 0x3FF9D3002E964AE9
+data4 0x250843E3, 0x00000000
+data8 0x3FF8F1EF89DCB383
+data4 0x2277C87E, 0x00000000
+data8 0x3FF81B937C87DBD6
+data4 0x256DA6CF, 0x00000000
+data8 0x3FF74F141042EDE4
+data4 0x2573D28A, 0x00000000
+data8 0x3FF68BAF1784B360
+data4 0x242E489A, 0x00000000
+data8 0x3FF5D0B57C923C4C
+data4 0x2532D940, 0x00000000
+data8 0x3FF51D88F418EF20
+data4 0x253C7DD6, 0x00000000
+data8 0x3FF4719A02F88DAE
+data4 0x23DB59BF, 0x00000000
+data8 0x3FF3CC6649DA0788
+data4 0x252B4756, 0x00000000
+data8 0x3FF32D770B980DB8
+data4 0x23FE585F, 0x00000000
+data8 0x3FF2945FE56C987A
+data4 0x25378A63, 0x00000000
+data8 0x3FF200BDB16523F6
+data4 0x247BB2E0, 0x00000000
+data8 0x3FF172358CE27778
+data4 0x24446538, 0x00000000
+data8 0x3FF0E873FDEFE692
+data4 0x2514638F, 0x00000000
+data8 0x3FF0632C33154062
+data4 0x24A7FC27, 0x00000000
+data8 0x3FEFC42EB3EF115F
+data4 0x248FD0FE, 0x00000000
+data8 0x3FEEC9E8135D26F6
+data4 0x2385C719, 0x00000000
+LOCAL_OBJECT_END(tanl_table_cm1)
+
+LOCAL_OBJECT_START(tanl_table_scim2)
+//
+// Entries SC_inv in Swapped IEEE format (extended)
+// Index = 0,1,...,31 B = 2^(-2)*(1+Index/32+1/64)
+//
+data8 0x839D6D4A1BF30C9E, 0x00004001
+data8 0x80092804554B0EB0, 0x00004001
+data8 0xF959F94CA1CF0DE9, 0x00004000
+data8 0xF3086BA077378677, 0x00004000
+data8 0xED154515CCD4723C, 0x00004000
+data8 0xE77909441C27CF25, 0x00004000
+data8 0xE22D037D8DDACB88, 0x00004000
+data8 0xDD2B2D8A89C73522, 0x00004000
+data8 0xD86E1A23BB2C1171, 0x00004000
+data8 0xD3F0E288DFF5E0F9, 0x00004000
+data8 0xCFAF16B1283BEBD5, 0x00004000
+data8 0xCBA4AFAA0D88DD53, 0x00004000
+data8 0xC7CE03CCCA67C43D, 0x00004000
+data8 0xC427BC820CA0DDB0, 0x00004000
+data8 0xC0AECD57F13D8CAB, 0x00004000
+data8 0xBD606C3871ECE6B1, 0x00004000
+data8 0xBA3A0A96A44C4929, 0x00004000
+data8 0xB7394F6FE5CCCEC1, 0x00004000
+data8 0xB45C12039637D8BC, 0x00004000
+data8 0xB1A0552892CB051B, 0x00004000
+data8 0xAF04432B6BA2FFD0, 0x00004000
+data8 0xAC862A237221235F, 0x00004000
+data8 0xAA2478AF5F00A9D1, 0x00004000
+data8 0xA7DDBB0C81E082BF, 0x00004000
+data8 0xA5B0987D45684FEE, 0x00004000
+data8 0xA39BD0F5627A8F53, 0x00004000
+data8 0xA19E3B036EC5C8B0, 0x00004000
+data8 0x9FB6C1F091CD7C66, 0x00004000
+data8 0x9DE464101FA3DF8A, 0x00004000
+data8 0x9C263139A8F6B888, 0x00004000
+data8 0x9A7B4968C27B0450, 0x00004000
+data8 0x98E2DB7E5EE614EE, 0x00004000
+LOCAL_OBJECT_END(tanl_table_scim2)
+
+LOCAL_OBJECT_START(tanl_table_scim1)
+//
+// Entries SC_inv in Swapped IEEE format (extended)
+// Index = 0,1,...,19 B = 2^(-1)*(1+Index/32+1/64)
+//
+data8 0x969F335C13B2B5BA, 0x00004000
+data8 0x93D446D9D4C0F548, 0x00004000
+data8 0x9147094F61B798AF, 0x00004000
+data8 0x8EF317CC758787AC, 0x00004000
+data8 0x8CD498B3B99EEFDB, 0x00004000
+data8 0x8AE82A7DDFF8BC37, 0x00004000
+data8 0x892AD546E3C55D42, 0x00004000
+data8 0x8799FEA9D15573C1, 0x00004000
+data8 0x86335F88435A4B4C, 0x00004000
+data8 0x84F4FB6E3E93A87B, 0x00004000
+data8 0x83DD195280A382FB, 0x00004000
+data8 0x82EA3D7FA4CB8C9E, 0x00004000
+data8 0x821B247C6861D0A8, 0x00004000
+data8 0x816EBED163E8D244, 0x00004000
+data8 0x80E42D9127E4CFC6, 0x00004000
+data8 0x807ABF8D28E64AFD, 0x00004000
+data8 0x8031EF26863B4FD8, 0x00004000
+data8 0x800960ADAE8C11FD, 0x00004000
+data8 0x8000E1475FDBEC21, 0x00004000
+data8 0x80186650A07791FA, 0x00004000
+LOCAL_OBJECT_END(tanl_table_scim1)
+
+Arg = f8
+Save_Norm_Arg = f8 // For input to reduction routine
+Result = f8
+r = f8 // For output from reduction routine
+c = f9 // For output from reduction routine
+U_2 = f10
+rsq = f11
+C_hi = f12
+C_lo = f13
+T_hi = f14
+T_lo = f15
+
+d_1 = f33
+N_0 = f34
+tail = f35
+tanx = f36
+Cx = f37
+Sx = f38
+sgn_r = f39
+CORR = f40
+P = f41
+D = f42
+ArgPrime = f43
+P_0 = f44
+
+P2_1 = f45
+P2_2 = f46
+P2_3 = f47
+
+P1_1 = f45
+P1_2 = f46
+P1_3 = f47
+
+P1_4 = f48
+P1_5 = f49
+P1_6 = f50
+P1_7 = f51
+P1_8 = f52
+P1_9 = f53
+
+x = f56
+xsq = f57
+Tx = f58
+Tx1 = f59
+Set = f60
+poly1 = f61
+poly2 = f62
+Poly = f63
+Poly1 = f64
+Poly2 = f65
+r_to_the_8 = f66
+B = f67
+SC_inv = f68
+Pos_r = f69
+N_0_fix = f70
+d_2 = f71
+PI_BY_4 = f72
+TWO_TO_NEG14 = f74
+TWO_TO_NEG33 = f75
+NEGTWO_TO_NEG14 = f76
+NEGTWO_TO_NEG33 = f77
+two_by_PI = f78
+N = f79
+N_fix = f80
+P_1 = f81
+P_2 = f82
+P_3 = f83
+s_val = f84
+w = f85
+B_mask1 = f86
+B_mask2 = f87
+w2 = f88
+A = f89
+a = f90
+t = f91
+U_1 = f92
+NEGTWO_TO_NEG2 = f93
+TWO_TO_NEG2 = f94
+Q1_1 = f95
+Q1_2 = f96
+Q1_3 = f97
+Q1_4 = f98
+Q1_5 = f99
+Q1_6 = f100
+Q1_7 = f101
+Q1_8 = f102
+S_hi = f103
+S_lo = f104
+V_hi = f105
+V_lo = f106
+U_hi = f107
+U_lo = f108
+U_hiabs = f109
+V_hiabs = f110
+V = f111
+Inv_P_0 = f112
+
+FR_inv_pi_2to63 = f113
+FR_rshf_2to64 = f114
+FR_2tom64 = f115
+FR_rshf = f116
+Norm_Arg = f117
+Abs_Arg = f118
+TWO_TO_NEG65 = f119
+fp_tmp = f120
+mOne = f121
+
+GR_SAVE_B0 = r33
+GR_SAVE_GP = r34
+GR_SAVE_PFS = r35
+table_base = r36
+table_ptr1 = r37
+table_ptr2 = r38
+table_ptr3 = r39
+lookup = r40
+N_fix_gr = r41
+GR_exp_2tom2 = r42
+GR_exp_2tom65 = r43
+exp_r = r44
+sig_r = r45
+bmask1 = r46
+table_offset = r47
+bmask2 = r48
+gr_tmp = r49
+cot_flag = r50
+
+GR_sig_inv_pi = r51
+GR_rshf_2to64 = r52
+GR_exp_2tom64 = r53
+GR_rshf = r54
+GR_exp_2_to_63 = r55
+GR_exp_2_to_24 = r56
+GR_signexp_x = r57
+GR_exp_x = r58
+GR_exp_mask = r59
+GR_exp_2tom14 = r60
+GR_exp_m2tom14 = r61
+GR_exp_2tom33 = r62
+GR_exp_m2tom33 = r63
+
+GR_SAVE_B0 = r64
+GR_SAVE_PFS = r65
+GR_SAVE_GP = r66
+
+GR_Parameter_X = r67
+GR_Parameter_Y = r68
+GR_Parameter_RESULT = r69
+GR_Parameter_Tag = r70
+
+
+.section .text
+.global __libm_tanl#
+.global __libm_cotl#
+
+.proc __libm_cotl#
+__libm_cotl:
+.endp __libm_cotl#
+LOCAL_LIBM_ENTRY(cotl)
+
+{ .mlx
+ alloc r32 = ar.pfs, 0,35,4,0
+ movl GR_sig_inv_pi = 0xa2f9836e4e44152a // significand of 1/pi
+}
+{ .mlx
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+ movl GR_rshf_2to64 = 0x47e8000000000000 // 1.1000 2^(63+64)
+}
+;;
+
+// Check for NatVals, Infs , NaNs, and Zeros
+{ .mfi
+ getf.exp GR_signexp_x = Arg // Get sign and exponent of x
+ fclass.m p6,p0 = Arg, 0x1E7 // Test for natval, nan, inf, zero
+ mov cot_flag = 0x1
+}
+{ .mfb
+ addl table_base = @ltoff(TANL_BASE_CONSTANTS), gp // Pointer to table ptr
+ fnorm.s1 Norm_Arg = Arg // Normalize x
+ br.cond.sptk COMMON_PATH
+};;
+
+LOCAL_LIBM_END(cotl)
+
+
+.proc __libm_tanl#
+__libm_tanl:
+.endp __libm_tanl#
+GLOBAL_IEEE754_ENTRY(tanl)
+
+{ .mlx
+ alloc r32 = ar.pfs, 0,35,4,0
+ movl GR_sig_inv_pi = 0xa2f9836e4e44152a // significand of 1/pi
+}
+{ .mlx
+ mov GR_exp_mask = 0x1ffff // Exponent mask
+ movl GR_rshf_2to64 = 0x47e8000000000000 // 1.1000 2^(63+64)
+}
+;;
+
+// Check for NatVals, Infs , NaNs, and Zeros
+{ .mfi
+ getf.exp GR_signexp_x = Arg // Get sign and exponent of x
+ fclass.m p6,p0 = Arg, 0x1E7 // Test for natval, nan, inf, zero
+ mov cot_flag = 0x0
+}
+{ .mfi
+ addl table_base = @ltoff(TANL_BASE_CONSTANTS), gp // Pointer to table ptr
+ fnorm.s1 Norm_Arg = Arg // Normalize x
+ nop.i 0
+};;
+
+// Common path for both tanl and cotl
+COMMON_PATH:
+{ .mfi
+ setf.sig FR_inv_pi_2to63 = GR_sig_inv_pi // Form 1/pi * 2^63
+ fclass.m p9, p0 = Arg, 0x0b // Test x denormal
+ mov GR_exp_2tom64 = 0xffff - 64 // Scaling constant to compute N
+}
+{ .mlx
+ setf.d FR_rshf_2to64 = GR_rshf_2to64 // Form const 1.1000 * 2^(63+64)
+ movl GR_rshf = 0x43e8000000000000 // Form const 1.1000 * 2^63
+}
+;;
+
+// Check for everything - if false, then must be pseudo-zero or pseudo-nan.
+// Branch out to deal with special values.
+{ .mfi
+ addl gr_tmp = -1,r0
+ fclass.nm p7,p0 = Arg, 0x1FF // Test x unsupported
+ mov GR_exp_2_to_63 = 0xffff + 63 // Exponent of 2^63
+}
+{ .mfb
+ ld8 table_base = [table_base] // Get pointer to constant table
+ fms.s1 mOne = f0, f0, f1
+(p6) br.cond.spnt TANL_SPECIAL // Branch if x natval, nan, inf, zero
+}
+;;
+
+{ .mmb
+ setf.sig fp_tmp = gr_tmp // Make a constant so fmpy produces inexact
+ mov GR_exp_2_to_24 = 0xffff + 24 // Exponent of 2^24
+(p9) br.cond.spnt TANL_DENORMAL // Branch if x denormal
+}
+;;
+
+TANL_COMMON:
+// Return to here if x denormal
+//
+// Do fcmp to generate Denormal exception
+// - can't do FNORM (will generate Underflow when U is unmasked!)
+// Branch out to deal with unsupporteds values.
+{ .mfi
+ setf.exp FR_2tom64 = GR_exp_2tom64 // Form 2^-64 for scaling N_float
+ fcmp.eq.s0 p0, p6 = Arg, f1 // Dummy to flag denormals
+ add table_ptr1 = 0, table_base // Point to tanl_table_1
+}
+{ .mib
+ setf.d FR_rshf = GR_rshf // Form right shift const 1.1000 * 2^63
+ add table_ptr2 = 80, table_base // Point to tanl_table_2
+(p7) br.cond.spnt TANL_UNSUPPORTED // Branch if x unsupported type
+}
+;;
+
+{ .mfi
+ and GR_exp_x = GR_exp_mask, GR_signexp_x // Get exponent of x
+ fmpy.s1 Save_Norm_Arg = Norm_Arg, f1 // Save x if large arg reduction
+ dep.z bmask1 = 0x7c, 56, 8 // Form mask to get 5 msb of r
+ // bmask1 = 0x7c00000000000000
+}
+;;
+
+//
+// Decide about the paths to take:
+// Set PR_6 if |Arg| >= 2**63
+// Set PR_9 if |Arg| < 2**24 - CASE 1 OR 2
+// OTHERWISE Set PR_8 - CASE 3 OR 4
+//
+// Branch out if the magnitude of the input argument is >= 2^63
+// - do this branch before the next.
+{ .mfi
+ ldfe two_by_PI = [table_ptr1],16 // Load 2/pi
+ nop.f 999
+ dep.z bmask2 = 0x41, 57, 7 // Form mask to OR to produce B
+ // bmask2 = 0x8200000000000000
+}
+{ .mib
+ ldfe PI_BY_4 = [table_ptr2],16 // Load pi/4
+ cmp.ge p6,p0 = GR_exp_x, GR_exp_2_to_63 // Is |x| >= 2^63
+(p6) br.cond.spnt TANL_ARG_TOO_LARGE // Branch if |x| >= 2^63
+}
+;;
+
+{ .mmi
+ ldfe P_0 = [table_ptr1],16 // Load P_0
+ ldfe Inv_P_0 = [table_ptr2],16 // Load Inv_P_0
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe P_1 = [table_ptr1],16 // Load P_1
+ fmerge.s Abs_Arg = f0, Norm_Arg // Get |x|
+ mov GR_exp_m2tom33 = 0x2ffff - 33 // Form signexp of -2^-33
+}
+{ .mfi
+ ldfe d_1 = [table_ptr2],16 // Load d_1 for 2^24 <= |x| < 2^63
+ nop.f 999
+ mov GR_exp_2tom33 = 0xffff - 33 // Form signexp of 2^-33
+}
+;;
+
+{ .mmi
+ ldfe P_2 = [table_ptr1],16 // Load P_2
+ ldfe d_2 = [table_ptr2],16 // Load d_2 for 2^24 <= |x| < 2^63
+ cmp.ge p8,p0 = GR_exp_x, GR_exp_2_to_24 // Is |x| >= 2^24
+}
+;;
+
+// Use special scaling to right shift so N=Arg * 2/pi is in rightmost bits
+// Branch to Cases 3 or 4 if Arg <= -2**24 or Arg >= 2**24
+{ .mfb
+ ldfe P_3 = [table_ptr1],16 // Load P_3
+ fma.s1 N_fix = Norm_Arg, FR_inv_pi_2to63, FR_rshf_2to64
+(p8) br.cond.spnt TANL_LARGER_ARG // Branch if 2^24 <= |x| < 2^63
+}
+;;
+
+// Here if 0 < |x| < 2^24
+// ARGUMENT REDUCTION CODE - CASE 1 and 2
+//
+{ .mmf
+ setf.exp TWO_TO_NEG33 = GR_exp_2tom33 // Form 2^-33
+ setf.exp NEGTWO_TO_NEG33 = GR_exp_m2tom33 // Form -2^-33
+ fmerge.s r = Norm_Arg,Norm_Arg // Assume r=x, ok if |x| < pi/4
+}
+;;
+
+//
+// If |Arg| < pi/4, set PR_8, else pi/4 <=|Arg| < 2^24 - set PR_9.
+//
+// Case 2: Convert integer N_fix back to normalized floating-point value.
+{ .mfi
+ getf.sig sig_r = Norm_Arg // Get sig_r if 1/4 <= |x| < pi/4
+ fcmp.lt.s1 p8,p9= Abs_Arg,PI_BY_4 // Test |x| < pi/4
+ mov GR_exp_2tom2 = 0xffff - 2 // Form signexp of 2^-2
+}
+{ .mfi
+ ldfps TWO_TO_NEG2, NEGTWO_TO_NEG2 = [table_ptr2] // Load 2^-2, -2^-2
+ fms.s1 N = N_fix, FR_2tom64, FR_rshf // Use scaling to get N floated
+ mov N_fix_gr = r0 // Assume N=0, ok if |x| < pi/4
+}
+;;
+
+//
+// Case 1: Is |r| < 2**(-2).
+// Arg is the same as r in this case.
+// r = Arg
+// c = 0
+//
+// Case 2: Place integer part of N in GP register.
+{ .mfi
+(p9) getf.sig N_fix_gr = N_fix
+ fmerge.s c = f0, f0 // Assume c=0, ok if |x| < pi/4
+ cmp.lt p10, p0 = GR_exp_x, GR_exp_2tom2 // Test if |x| < 1/4
+}
+;;
+
+{ .mfi
+ setf.sig B_mask1 = bmask1 // Form mask to get 5 msb of r
+ nop.f 999
+ mov exp_r = GR_exp_x // Get exp_r if 1/4 <= |x| < pi/4
+}
+{ .mbb
+ setf.sig B_mask2 = bmask2 // Form mask to form B from r
+(p10) br.cond.spnt TANL_SMALL_R // Branch if 0 < |x| < 1/4
+(p8) br.cond.spnt TANL_NORMAL_R // Branch if 1/4 <= |x| < pi/4
+}
+;;
+
+// Here if pi/4 <= |x| < 2^24
+//
+// Case 1: PR_3 is only affected when PR_1 is set.
+//
+//
+// Case 2: w = N * P_2
+// Case 2: s_val = -N * P_1 + Arg
+//
+
+{ .mfi
+ nop.m 999
+ fnma.s1 s_val = N, P_1, Norm_Arg
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 w = N, P_2 // w = N * P_2 for |s| >= 2^-33
+ nop.i 999
+}
+;;
+
+// Case 2_reduce: w = N * P_3 (change sign)
+{ .mfi
+ nop.m 999
+ fmpy.s1 w2 = N, P_3 // w = N * P_3 for |s| < 2^-33
+ nop.i 999
+}
+;;
+
+// Case 1_reduce: r = s + w (change sign)
+{ .mfi
+ nop.m 999
+ fsub.s1 r = s_val, w // r = s_val - w for |s| >= 2^-33
+ nop.i 999
+}
+;;
+
+// Case 2_reduce: U_1 = N * P_2 + w
+{ .mfi
+ nop.m 999
+ fma.s1 U_1 = N, P_2, w2 // U_1 = N * P_2 + w for |s| < 2^-33
+ nop.i 999
+}
+;;
+
+//
+// Decide between case_1 and case_2 reduce:
+// Case 1_reduce: |s| >= 2**(-33)
+// Case 2_reduce: |s| < 2**(-33)
+//
+{ .mfi
+ nop.m 999
+ fcmp.lt.s1 p9, p8 = s_val, TWO_TO_NEG33
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p9) fcmp.gt.s1 p9, p8 = s_val, NEGTWO_TO_NEG33
+ nop.i 999
+}
+;;
+
+// Case 1_reduce: c = s - r
+{ .mfi
+ nop.m 999
+ fsub.s1 c = s_val, r // c = s_val - r for |s| >= 2^-33
+ nop.i 999
+}
+;;
+
+// Case 2_reduce: r is complete here - continue to calculate c .
+// r = s - U_1
+{ .mfi
+ nop.m 999
+(p9) fsub.s1 r = s_val, U_1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p9) fms.s1 U_2 = N, P_2, U_1
+ nop.i 999
+}
+;;
+
+//
+// Case 1_reduce: Is |r| < 2**(-2), if so set PR_10
+// else set PR_13.
+//
+
+{ .mfi
+ nop.m 999
+ fand B = B_mask1, r
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fcmp.lt.unc.s1 p10, p13 = r, TWO_TO_NEG2
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p8) getf.sig sig_r = r // Get signif of r if |s| >= 2^-33
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p8) getf.exp exp_r = r // Extract signexp of r if |s| >= 2^-33
+(p10) fcmp.gt.s1 p10, p13 = r, NEGTWO_TO_NEG2
+ nop.i 999
+}
+;;
+
+// Case 1_reduce: c is complete here.
+// Case 1: Branch to SMALL_R or NORMAL_R.
+// c = c + w (w has not been negated.)
+{ .mfi
+ nop.m 999
+(p8) fsub.s1 c = c, w // c = c - w for |s| >= 2^-33
+ nop.i 999
+}
+{ .mbb
+ nop.m 999
+(p10) br.cond.spnt TANL_SMALL_R // Branch if pi/4 < |x| < 2^24 and |r|<1/4
+(p13) br.cond.sptk TANL_NORMAL_R_A // Branch if pi/4 < |x| < 2^24 and |r|>=1/4
+}
+;;
+
+
+// Here if pi/4 < |x| < 2^24 and |s| < 2^-33
+//
+// Is i_1 = lsb of N_fix_gr even or odd?
+// if i_1 == 0, set p11, else set p12.
+//
+{ .mfi
+ nop.m 999
+ fsub.s1 s_val = s_val, r
+ add N_fix_gr = N_fix_gr, cot_flag // N = N + 1 (for cotl)
+}
+{ .mfi
+ nop.m 999
+//
+// Case 2_reduce:
+// U_2 = N * P_2 - U_1
+// Not needed until later.
+//
+ fadd.s1 U_2 = U_2, w2
+//
+// Case 2_reduce:
+// s = s - r
+// U_2 = U_2 + w
+//
+ nop.i 999
+}
+;;
+
+//
+// Case 2_reduce:
+// c = c - U_2
+// c is complete here
+// Argument reduction ends here.
+//
+{ .mfi
+ nop.m 999
+ fmpy.s1 rsq = r, r
+ tbit.z p11, p12 = N_fix_gr, 0 ;; // Set p11 if N even, p12 if odd
+}
+
+{ .mfi
+ nop.m 999
+(p12) frcpa.s1 S_hi,p0 = f1, r
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fsub.s1 c = s_val, U_1
+ nop.i 999
+}
+;;
+
+{ .mmi
+ add table_ptr1 = 160, table_base ;; // Point to tanl_table_p1
+ ldfe P1_1 = [table_ptr1],144
+ nop.i 999 ;;
+}
+//
+// Load P1_1 and point to Q1_1 .
+//
+{ .mfi
+ ldfe Q1_1 = [table_ptr1]
+//
+// N even: rsq = r * Z
+// N odd: S_hi = frcpa(r)
+//
+(p12) fmerge.ns S_hi = S_hi, S_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// Case 2_reduce:
+// c = s - U_1
+//
+(p9) fsub.s1 c = c, U_2
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: Change sign of S_hi
+//
+(p11) fmpy.s1 rsq = rsq, P1_1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: rsq = rsq * P1_1
+// N odd: poly1 = 1.0 + S_hi * r 16 bits partial account for necessary
+//
+(p11) fma.s1 Poly = r, rsq, c
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: Poly = c + r * rsq
+// N odd: S_hi = S_hi + S_hi*poly1 16 bits account for necessary
+//
+(p12) fma.s1 poly1 = S_hi, r, f1
+(p11) tbit.z.unc p14, p15 = cot_flag, 0 ;; // p14=1 for tanl; p15=1 for cotl
+}
+{ .mfi
+ nop.m 999
+//
+// N even: Result = Poly + r
+// N odd: poly1 = 1.0 + S_hi * r 32 bits partial
+//
+(p14) fadd.s0 Result = r, Poly // for tanl
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p15) fms.s0 Result = r, mOne, Poly // for cotl
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: Result1 = Result + r
+// N odd: S_hi = S_hi * poly1 + S_hi 32 bits
+//
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * r + 1.0 64 bits partial
+//
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * poly + 1.0 64 bits
+//
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * r + 1.0
+//
+(p12) fma.s1 poly1 = S_hi, c, poly1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * c + poly1
+//
+(p12) fmpy.s1 S_lo = S_hi, poly1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: S_lo = S_hi * poly1
+//
+(p12) fma.s1 S_lo = Q1_1, r, S_lo
+(p12) tbit.z.unc p14, p15 = cot_flag, 0 // p14=1 for tanl; p15=1 for cotl
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: Result = S_hi + S_lo
+//
+ fmpy.s0 fp_tmp = fp_tmp, fp_tmp // Dummy mult to set inexact
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: S_lo = S_lo + Q1_1 * r
+//
+(p14) fadd.s0 Result = S_hi, S_lo // for tanl
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p15) fms.s0 Result = S_hi, mOne, S_lo // for cotl
+ br.ret.sptk b0 ;; // Exit for pi/4 <= |x| < 2^24 and |s| < 2^-33
+}
+
+
+TANL_LARGER_ARG:
+// Here if 2^24 <= |x| < 2^63
+//
+// ARGUMENT REDUCTION CODE - CASE 3 and 4
+//
+
+{ .mmf
+ mov GR_exp_2tom14 = 0xffff - 14 // Form signexp of 2^-14
+ mov GR_exp_m2tom14 = 0x2ffff - 14 // Form signexp of -2^-14
+ fmpy.s1 N_0 = Norm_Arg, Inv_P_0
+}
+;;
+
+{ .mmi
+ setf.exp TWO_TO_NEG14 = GR_exp_2tom14 // Form 2^-14
+ setf.exp NEGTWO_TO_NEG14 = GR_exp_m2tom14// Form -2^-14
+ nop.i 999
+}
+;;
+
+
+//
+// Adjust table_ptr1 to beginning of table.
+// N_0 = Arg * Inv_P_0
+//
+{ .mmi
+ add table_ptr2 = 144, table_base ;; // Point to 2^-2
+ ldfps TWO_TO_NEG2, NEGTWO_TO_NEG2 = [table_ptr2]
+ nop.i 999
+}
+;;
+
+//
+// N_0_fix = integer part of N_0 .
+//
+//
+// Make N_0 the integer part.
+//
+{ .mfi
+ nop.m 999
+ fcvt.fx.s1 N_0_fix = N_0
+ nop.i 999 ;;
+}
+{ .mfi
+ setf.sig B_mask1 = bmask1 // Form mask to get 5 msb of r
+ fcvt.xf N_0 = N_0_fix
+ nop.i 999 ;;
+}
+{ .mfi
+ setf.sig B_mask2 = bmask2 // Form mask to form B from r
+ fnma.s1 ArgPrime = N_0, P_0, Norm_Arg
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 w = N_0, d_1
+ nop.i 999 ;;
+}
+//
+// ArgPrime = -N_0 * P_0 + Arg
+// w = N_0 * d_1
+//
+//
+// N = ArgPrime * 2/pi
+//
+// fcvt.fx.s1 N_fix = N
+// Use special scaling to right shift so N=Arg * 2/pi is in rightmost bits
+// Branch to Cases 3 or 4 if Arg <= -2**24 or Arg >= 2**24
+{ .mfi
+ nop.m 999
+ fma.s1 N_fix = ArgPrime, FR_inv_pi_2to63, FR_rshf_2to64
+
+ nop.i 999 ;;
+}
+// Convert integer N_fix back to normalized floating-point value.
+{ .mfi
+ nop.m 999
+ fms.s1 N = N_fix, FR_2tom64, FR_rshf // Use scaling to get N floated
+ nop.i 999
+}
+;;
+
+//
+// N is the integer part of the reduced-reduced argument.
+// Put the integer in a GP register.
+//
+{ .mfi
+ getf.sig N_fix_gr = N_fix
+ nop.f 999
+ nop.i 999
+}
+;;
+
+//
+// s_val = -N*P_1 + ArgPrime
+// w = -N*P_2 + w
+//
+{ .mfi
+ nop.m 999
+ fnma.s1 s_val = N, P_1, ArgPrime
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnma.s1 w = N, P_2, w
+ nop.i 999
+}
+;;
+
+// Case 4: V_hi = N * P_2
+// Case 4: U_hi = N_0 * d_1
+{ .mfi
+ nop.m 999
+ fmpy.s1 V_hi = N, P_2 // V_hi = N * P_2 for |s| < 2^-14
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 U_hi = N_0, d_1 // U_hi = N_0 * d_1 for |s| < 2^-14
+ nop.i 999
+}
+;;
+
+// Case 3: r = s_val + w (Z complete)
+// Case 4: w = N * P_3
+{ .mfi
+ nop.m 999
+ fadd.s1 r = s_val, w // r = s_val + w for |s| >= 2^-14
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 w2 = N, P_3 // w = N * P_3 for |s| < 2^-14
+ nop.i 999
+}
+;;
+
+// Case 4: A = U_hi + V_hi
+// Note: Worry about switched sign of V_hi, so subtract instead of add.
+// Case 4: V_lo = -N * P_2 - V_hi (U_hi is in place of V_hi in writeup)
+// Note: the (-) is still missing for V_hi.
+{ .mfi
+ nop.m 999
+ fsub.s1 A = U_hi, V_hi // A = U_hi - V_hi for |s| < 2^-14
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fnma.s1 V_lo = N, P_2, V_hi // V_lo = V_hi - N * P_2 for |s| < 2^-14
+ nop.i 999
+}
+;;
+
+// Decide between case 3 and 4:
+// Case 3: |s| >= 2**(-14) Set p10
+// Case 4: |s| < 2**(-14) Set p11
+//
+// Case 4: U_lo = N_0 * d_1 - U_hi
+{ .mfi
+ nop.m 999
+ fms.s1 U_lo = N_0, d_1, U_hi // U_lo = N_0*d_1 - U_hi for |s| < 2^-14
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fcmp.lt.s1 p11, p10 = s_val, TWO_TO_NEG14
+ nop.i 999
+}
+;;
+
+// Case 4: We need abs of both U_hi and V_hi - dont
+// worry about switched sign of V_hi.
+{ .mfi
+ nop.m 999
+ fabs V_hiabs = V_hi // |V_hi| for |s| < 2^-14
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fcmp.gt.s1 p11, p10 = s_val, NEGTWO_TO_NEG14
+ nop.i 999
+}
+;;
+
+// Case 3: c = s_val - r
+{ .mfi
+ nop.m 999
+ fabs U_hiabs = U_hi // |U_hi| for |s| < 2^-14
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fsub.s1 c = s_val, r // c = s_val - r for |s| >= 2^-14
+ nop.i 999
+}
+;;
+
+// For Case 3, |s| >= 2^-14, determine if |r| < 1/4
+//
+// Case 4: C_hi = s_val + A
+//
+{ .mfi
+ nop.m 999
+(p11) fadd.s1 C_hi = s_val, A // C_hi = s_val + A for |s| < 2^-14
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p10) fcmp.lt.unc.s1 p14, p15 = r, TWO_TO_NEG2
+ nop.i 999
+}
+;;
+
+{ .mfi
+ getf.sig sig_r = r // Get signif of r if |s| >= 2^-33
+ fand B = B_mask1, r
+ nop.i 999
+}
+;;
+
+// Case 4: t = U_lo + V_lo
+{ .mfi
+ getf.exp exp_r = r // Extract signexp of r if |s| >= 2^-33
+(p11) fadd.s1 t = U_lo, V_lo // t = U_lo + V_lo for |s| < 2^-14
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p14) fcmp.gt.s1 p14, p15 = r, NEGTWO_TO_NEG2
+ nop.i 999
+}
+;;
+
+// Case 3: c = (s - r) + w (c complete)
+{ .mfi
+ nop.m 999
+(p10) fadd.s1 c = c, w // c = c + w for |s| >= 2^-14
+ nop.i 999
+}
+{ .mbb
+ nop.m 999
+(p14) br.cond.spnt TANL_SMALL_R // Branch if 2^24 <= |x| < 2^63 and |r|< 1/4
+(p15) br.cond.sptk TANL_NORMAL_R_A // Branch if 2^24 <= |x| < 2^63 and |r|>=1/4
+}
+;;
+
+
+// Here if 2^24 <= |x| < 2^63 and |s| < 2^-14 >>>>>>> Case 4.
+//
+// Case 4: Set P_12 if U_hiabs >= V_hiabs
+// Case 4: w = w + N_0 * d_2
+// Note: the (-) is now incorporated in w .
+{ .mfi
+ add table_ptr1 = 160, table_base // Point to tanl_table_p1
+ fcmp.ge.unc.s1 p12, p13 = U_hiabs, V_hiabs
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fms.s1 w2 = N_0, d_2, w2
+ nop.i 999
+}
+;;
+
+// Case 4: C_lo = s_val - C_hi
+{ .mfi
+ ldfe P1_1 = [table_ptr1], 16 // Load P1_1
+ fsub.s1 C_lo = s_val, C_hi
+ nop.i 999
+}
+;;
+
+//
+// Case 4: a = U_hi - A
+// a = V_hi - A (do an add to account for missing (-) on V_hi
+//
+{ .mfi
+ ldfe P1_2 = [table_ptr1], 128 // Load P1_2
+(p12) fsub.s1 a = U_hi, A
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p13) fadd.s1 a = V_hi, A
+ nop.i 999
+}
+;;
+
+// Case 4: t = U_lo + V_lo + w
+{ .mfi
+ ldfe Q1_1 = [table_ptr1], 16 // Load Q1_1
+ fadd.s1 t = t, w2
+ nop.i 999
+}
+;;
+
+// Case 4: a = (U_hi - A) + V_hi
+// a = (V_hi - A) + U_hi
+// In each case account for negative missing form V_hi .
+//
+{ .mfi
+ ldfe Q1_2 = [table_ptr1], 16 // Load Q1_2
+(p12) fsub.s1 a = a, V_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p13) fsub.s1 a = U_hi, a
+ nop.i 999
+}
+;;
+
+//
+// Case 4: C_lo = (s_val - C_hi) + A
+//
+{ .mfi
+ nop.m 999
+ fadd.s1 C_lo = C_lo, A
+ nop.i 999 ;;
+}
+//
+// Case 4: t = t + a
+//
+{ .mfi
+ nop.m 999
+ fadd.s1 t = t, a
+ nop.i 999
+}
+;;
+
+// Case 4: C_lo = C_lo + t
+// Case 4: r = C_hi + C_lo
+{ .mfi
+ nop.m 999
+ fadd.s1 C_lo = C_lo, t
+ nop.i 999
+}
+;;
+
+{ .mfi
+ nop.m 999
+ fadd.s1 r = C_hi, C_lo
+ nop.i 999
+}
+;;
+
+//
+// Case 4: c = C_hi - r
+//
+{ .mfi
+ nop.m 999
+ fsub.s1 c = C_hi, r
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 rsq = r, r
+ add N_fix_gr = N_fix_gr, cot_flag // N = N + 1 (for cotl)
+}
+;;
+
+// Case 4: c = c + C_lo finished.
+//
+// Is i_1 = lsb of N_fix_gr even or odd?
+// if i_1 == 0, set PR_11, else set PR_12.
+//
+{ .mfi
+ nop.m 999
+ fadd.s1 c = c , C_lo
+ tbit.z p11, p12 = N_fix_gr, 0
+}
+;;
+
+// r and c have been computed.
+{ .mfi
+ nop.m 999
+(p12) frcpa.s1 S_hi, p0 = f1, r
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: Change sign of S_hi
+//
+(p11) fma.s1 Poly = rsq, P1_2, P1_1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 P = rsq, Q1_2, Q1_1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: Result = S_hi + S_lo (User supplied rounding mode for C1)
+//
+ fmpy.s0 fp_tmp = fp_tmp, fp_tmp // Dummy mult to set inexact
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: rsq = r * r
+// N odd: S_hi = frcpa(r)
+//
+(p12) fmerge.ns S_hi = S_hi, S_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// N even: rsq = rsq * P1_2 + P1_1
+// N odd: poly1 = 1.0 + S_hi * r 16 bits partial account for necessary
+//
+(p11) fmpy.s1 Poly = rsq, Poly
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, r,f1
+(p11) tbit.z.unc p14, p15 = cot_flag, 0 // p14=1 for tanl; p15=1 for cotl
+}
+{ .mfi
+ nop.m 999
+//
+// N even: Poly = Poly * rsq
+// N odd: S_hi = S_hi + S_hi*poly1 16 bits account for necessary
+//
+(p11) fma.s1 Poly = r, Poly, c
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: S_hi = S_hi * poly1 + S_hi 32 bits
+//
+(p14) fadd.s0 Result = r, Poly // for tanl
+ nop.i 999 ;;
+}
+
+.pred.rel "mutex",p15,p12
+{ .mfi
+ nop.m 999
+(p15) fms.s0 Result = r, mOne, Poly // for cotl
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: Poly = Poly * r + c
+// N odd: poly1 = 1.0 + S_hi * r 32 bits partial
+//
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: Result = Poly + r (Rounding mode S0)
+// N odd: poly1 = S_hi * r + 1.0 64 bits partial
+//
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * poly + S_hi 64 bits
+//
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * r + 1.0
+//
+(p12) fma.s1 poly1 = S_hi, c, poly1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * c + poly1
+//
+(p12) fmpy.s1 S_lo = S_hi, poly1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: S_lo = S_hi * poly1
+//
+(p12) fma.s1 S_lo = P, r, S_lo
+(p12) tbit.z.unc p14, p15 = cot_flag, 0 ;; // p14=1 for tanl; p15=1 for cotl
+}
+
+{ .mfi
+ nop.m 999
+(p14) fadd.s0 Result = S_hi, S_lo // for tanl
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+//
+// N odd: S_lo = S_lo + r * P
+//
+(p15) fms.s0 Result = S_hi, mOne, S_lo // for cotl
+ br.ret.sptk b0 ;; // Exit for 2^24 <= |x| < 2^63 and |s| < 2^-14
+}
+
+
+TANL_SMALL_R:
+// Here if |r| < 1/4
+// r and c have been computed.
+// *****************************************************************
+// *****************************************************************
+// *****************************************************************
+// N odd: S_hi = frcpa(r)
+// Get [i_1] - lsb of N_fix_gr. Set p11 if N even, p12 if N odd.
+// N even: rsq = r * r
+{ .mfi
+ add table_ptr1 = 160, table_base // Point to tanl_table_p1
+ frcpa.s1 S_hi, p0 = f1, r // S_hi for N odd
+ add N_fix_gr = N_fix_gr, cot_flag // N = N + 1 (for cotl)
+}
+{ .mfi
+ add table_ptr2 = 400, table_base // Point to Q1_7
+ fmpy.s1 rsq = r, r
+ nop.i 999
+}
+;;
+
+{ .mmi
+ ldfe P1_1 = [table_ptr1], 16
+;;
+ ldfe P1_2 = [table_ptr1], 16
+ tbit.z p11, p12 = N_fix_gr, 0
+}
+;;
+
+
+{ .mfi
+ ldfe P1_3 = [table_ptr1], 96
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mfi
+(p11) ldfe P1_9 = [table_ptr1], -16
+(p12) fmerge.ns S_hi = S_hi, S_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fmpy.s1 r_to_the_8 = rsq, rsq
+ nop.i 999
+}
+;;
+
+//
+// N even: Poly2 = P1_7 + Poly2 * rsq
+// N odd: poly2 = Q1_5 + poly2 * rsq
+//
+{ .mfi
+(p11) ldfe P1_8 = [table_ptr1], -16
+(p11) fadd.s1 CORR = rsq, f1
+ nop.i 999
+}
+;;
+
+//
+// N even: Poly1 = P1_2 + P1_3 * rsq
+// N odd: poly1 = 1.0 + S_hi * r
+// 16 bits partial account for necessary (-1)
+//
+{ .mmi
+(p11) ldfe P1_7 = [table_ptr1], -16
+;;
+(p11) ldfe P1_6 = [table_ptr1], -16
+ nop.i 999
+}
+;;
+
+//
+// N even: Poly1 = P1_1 + Poly1 * rsq
+// N odd: S_hi = S_hi + S_hi * poly1) 16 bits account for necessary
+//
+//
+// N even: Poly2 = P1_5 + Poly2 * rsq
+// N odd: poly2 = Q1_3 + poly2 * rsq
+//
+{ .mfi
+(p11) ldfe P1_5 = [table_ptr1], -16
+(p11) fmpy.s1 r_to_the_8 = r_to_the_8, r_to_the_8
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999
+}
+;;
+
+//
+// N even: Poly1 = Poly1 * rsq
+// N odd: poly1 = 1.0 + S_hi * r 32 bits partial
+//
+
+//
+// N even: CORR = CORR * c
+// N odd: S_hi = S_hi * poly1 + S_hi 32 bits
+//
+
+//
+// N even: Poly2 = P1_6 + Poly2 * rsq
+// N odd: poly2 = Q1_4 + poly2 * rsq
+//
+
+{ .mmf
+(p11) ldfe P1_4 = [table_ptr1], -16
+ nop.m 999
+(p11) fmpy.s1 CORR = CORR, c
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p11) fma.s1 Poly1 = P1_3, rsq, P1_2
+ nop.i 999 ;;
+}
+{ .mfi
+(p12) ldfe Q1_7 = [table_ptr2], -16
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999 ;;
+}
+{ .mfi
+(p12) ldfe Q1_6 = [table_ptr2], -16
+(p11) fma.s1 Poly2 = P1_9, rsq, P1_8
+ nop.i 999 ;;
+}
+{ .mmi
+(p12) ldfe Q1_5 = [table_ptr2], -16 ;;
+(p12) ldfe Q1_4 = [table_ptr2], -16
+ nop.i 999 ;;
+}
+{ .mfi
+(p12) ldfe Q1_3 = [table_ptr2], -16
+//
+// N even: Poly2 = P1_8 + P1_9 * rsq
+// N odd: poly2 = Q1_6 + Q1_7 * rsq
+//
+(p11) fma.s1 Poly1 = Poly1, rsq, P1_1
+ nop.i 999 ;;
+}
+{ .mfi
+(p12) ldfe Q1_2 = [table_ptr2], -16
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999 ;;
+}
+{ .mfi
+(p12) ldfe Q1_1 = [table_ptr2], -16
+(p11) fma.s1 Poly2 = Poly2, rsq, P1_7
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: CORR = rsq + 1
+// N even: r_to_the_8 = rsq * rsq
+//
+(p11) fmpy.s1 Poly1 = Poly1, rsq
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly2 = Q1_7, rsq, Q1_6
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p11) fma.s1 Poly2 = Poly2, rsq, P1_6
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly2 = poly2, rsq, Q1_5
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p11) fma.s1 Poly2= Poly2, rsq, P1_5
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 S_hi = S_hi, poly1, S_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly2 = poly2, rsq, Q1_4
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: r_to_the_8 = r_to_the_8 * r_to_the_8
+// N odd: poly1 = S_hi * r + 1.0 64 bits partial
+//
+(p11) fma.s1 Poly2 = Poly2, rsq, P1_4
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: Poly = CORR + Poly * r
+// N odd: P = Q1_1 + poly2 * rsq
+//
+(p12) fma.s1 poly1 = S_hi, r, f1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly2 = poly2, rsq, Q1_3
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: Poly2 = P1_4 + Poly2 * rsq
+// N odd: poly2 = Q1_2 + poly2 * rsq
+//
+(p11) fma.s1 Poly = Poly2, r_to_the_8, Poly1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly1 = S_hi, c, poly1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 poly2 = poly2, rsq, Q1_2
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N even: Poly = Poly1 + Poly2 * r_to_the_8
+// N odd: S_hi = S_hi * poly1 + S_hi 64 bits
+//
+(p11) fma.s1 Poly = Poly, r, CORR
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: Result = r + Poly (User supplied rounding mode)
+// N odd: poly1 = S_hi * c + poly1
+//
+(p12) fmpy.s1 S_lo = S_hi, poly1
+(p11) tbit.z.unc p14, p15 = cot_flag, 0 // p14=1 for tanl; p15=1 for cotl
+}
+{ .mfi
+ nop.m 999
+(p12) fma.s1 P = poly2, rsq, Q1_1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: poly1 = S_hi * r + 1.0
+//
+//
+// N odd: S_lo = S_hi * poly1
+//
+(p14) fadd.s0 Result = Poly, r // for tanl
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p15) fms.s0 Result = Poly, mOne, r // for cotl
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+//
+// N odd: S_lo = Q1_1 * c + S_lo
+//
+(p12) fma.s1 S_lo = Q1_1, c, S_lo
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s0 fp_tmp = fp_tmp, fp_tmp // Dummy mult to set inexact
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: Result = S_lo + r * P
+//
+(p12) fma.s1 Result = P, r, S_lo
+(p12) tbit.z.unc p14, p15 = cot_flag, 0 ;; // p14=1 for tanl; p15=1 for cotl
+}
+
+//
+// N odd: Result = Result + S_hi (user supplied rounding mode)
+//
+{ .mfi
+ nop.m 999
+(p14) fadd.s0 Result = Result, S_hi // for tanl
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p15) fms.s0 Result = Result, mOne, S_hi // for cotl
+ br.ret.sptk b0 ;; // Exit |r| < 1/4 path
+}
+
+
+TANL_NORMAL_R:
+// Here if 1/4 <= |x| < pi/4 or if |x| >= 2^63 and |r| >= 1/4
+// *******************************************************************
+// *******************************************************************
+// *******************************************************************
+//
+// r and c have been computed.
+//
+{ .mfi
+ nop.m 999
+ fand B = B_mask1, r
+ nop.i 999
+}
+;;
+
+TANL_NORMAL_R_A:
+// Enter here if pi/4 <= |x| < 2^63 and |r| >= 1/4
+// Get the 5 bits or r for the lookup. 1.xxxxx ....
+{ .mmi
+ add table_ptr1 = 416, table_base // Point to tanl_table_p2
+ mov GR_exp_2tom65 = 0xffff - 65 // Scaling constant for B
+ extr.u lookup = sig_r, 58, 5
+}
+;;
+
+{ .mmi
+ ldfe P2_1 = [table_ptr1], 16
+ setf.exp TWO_TO_NEG65 = GR_exp_2tom65 // 2^-65 for scaling B if exp_r=-2
+ add N_fix_gr = N_fix_gr, cot_flag // N = N + 1 (for cotl)
+}
+;;
+
+.pred.rel "mutex",p11,p12
+// B = 2^63 * 1.xxxxx 100...0
+{ .mfi
+ ldfe P2_2 = [table_ptr1], 16
+ for B = B_mask2, B
+ mov table_offset = 512 // Assume table offset is 512
+}
+;;
+
+{ .mfi
+ ldfe P2_3 = [table_ptr1], 16
+ fmerge.s Pos_r = f1, r
+ tbit.nz p8,p9 = exp_r, 0
+}
+;;
+
+// Is B = 2** -2 or B= 2** -1? If 2**-1, then
+// we want an offset of 512 for table addressing.
+{ .mii
+ add table_ptr2 = 1296, table_base // Point to tanl_table_cm2
+(p9) shladd table_offset = lookup, 4, table_offset
+(p8) shladd table_offset = lookup, 4, r0
+}
+;;
+
+{ .mmi
+ add table_ptr1 = table_ptr1, table_offset // Point to T_hi
+ add table_ptr2 = table_ptr2, table_offset // Point to C_hi
+ add table_ptr3 = 2128, table_base // Point to tanl_table_scim2
+}
+;;
+
+{ .mmi
+ ldfd T_hi = [table_ptr1], 8 // Load T_hi
+;;
+ ldfd C_hi = [table_ptr2], 8 // Load C_hi
+ add table_ptr3 = table_ptr3, table_offset // Point to SC_inv
+}
+;;
+
+//
+// x = |r| - B
+//
+// Convert B so it has the same exponent as Pos_r before subtracting
+{ .mfi
+ ldfs T_lo = [table_ptr1] // Load T_lo
+(p9) fnma.s1 x = B, FR_2tom64, Pos_r
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p8) fnma.s1 x = B, TWO_TO_NEG65, Pos_r
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfs C_lo = [table_ptr2] // Load C_lo
+ nop.f 999
+ nop.i 999
+}
+;;
+
+{ .mfi
+ ldfe SC_inv = [table_ptr3] // Load SC_inv
+ fmerge.s sgn_r = r, f1
+ tbit.z p11, p12 = N_fix_gr, 0 // p11 if N even, p12 if odd
+
+}
+;;
+
+//
+// xsq = x * x
+// N even: Tx = T_hi * x
+//
+// N even: Tx1 = Tx + 1
+// N odd: Cx1 = 1 - Cx
+//
+
+{ .mfi
+ nop.m 999
+ fmpy.s1 xsq = x, x
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fmpy.s1 Tx = T_hi, x
+ nop.i 999
+}
+;;
+
+//
+// N odd: Cx = C_hi * x
+//
+{ .mfi
+ nop.m 999
+(p12) fmpy.s1 Cx = C_hi, x
+ nop.i 999
+}
+;;
+//
+// N even and odd: P = P2_3 + P2_2 * xsq
+//
+{ .mfi
+ nop.m 999
+ fma.s1 P = P2_3, xsq, P2_2
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p11) fadd.s1 Tx1 = Tx, f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: D = C_hi - tanx
+// N odd: D = T_hi + tanx
+//
+(p11) fmpy.s1 CORR = SC_inv, T_hi
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 Sx = SC_inv, x
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fmpy.s1 CORR = SC_inv, C_hi
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fsub.s1 V_hi = f1, Cx
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+ fma.s1 P = P, xsq, P2_1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// N even and odd: P = P2_1 + P * xsq
+//
+(p11) fma.s1 V_hi = Tx, Tx1, f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: Result = sgn_r * tail + T_hi (user rounding mode for C1)
+// N odd: Result = sgn_r * tail + C_hi (user rounding mode for C1)
+//
+ fmpy.s0 fp_tmp = fp_tmp, fp_tmp // Dummy mult to set inexact
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 CORR = CORR, c
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fnma.s1 V_hi = Cx,V_hi,f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: V_hi = Tx * Tx1 + 1
+// N odd: Cx1 = 1 - Cx * Cx1
+//
+ fmpy.s1 P = P, xsq
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+//
+// N even and odd: P = P * xsq
+//
+(p11) fmpy.s1 V_hi = V_hi, T_hi
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even and odd: tail = P * tail + V_lo
+//
+(p11) fmpy.s1 T_hi = sgn_r, T_hi
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+ fmpy.s1 CORR = CORR, sgn_r
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+(p12) fmpy.s1 V_hi = V_hi,C_hi
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: V_hi = T_hi * V_hi
+// N odd: V_hi = C_hi * V_hi
+//
+ fma.s1 tanx = P, x, x
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fnmpy.s1 C_hi = sgn_r, C_hi
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: V_lo = 1 - V_hi + C_hi
+// N odd: V_lo = 1 - V_hi + T_hi
+//
+(p11) fadd.s1 CORR = CORR, T_lo
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fsub.s1 CORR = CORR, C_lo
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even and odd: tanx = x + x * P
+// N even and odd: Sx = SC_inv * x
+//
+(p11) fsub.s1 D = C_hi, tanx
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fadd.s1 D = T_hi, tanx
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N odd: CORR = SC_inv * C_hi
+// N even: CORR = SC_inv * T_hi
+//
+ fnma.s1 D = V_hi, D, f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even and odd: D = 1 - V_hi * D
+// N even and odd: CORR = CORR * c
+//
+ fma.s1 V_hi = V_hi, D, V_hi
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even and odd: V_hi = V_hi + V_hi * D
+// N even and odd: CORR = sgn_r * CORR
+//
+(p11) fnma.s1 V_lo = V_hi, C_hi, f1
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fnma.s1 V_lo = V_hi, T_hi, f1
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: CORR = COOR + T_lo
+// N odd: CORR = CORR - C_lo
+//
+(p11) fma.s1 V_lo = tanx, V_hi, V_lo
+ tbit.nz p15, p0 = cot_flag, 0 // p15=1 if we compute cotl
+}
+{ .mfi
+ nop.m 999
+(p12) fnma.s1 V_lo = tanx, V_hi, V_lo
+ nop.i 999 ;;
+}
+
+{ .mfi
+ nop.m 999
+(p15) fms.s1 T_hi = f0, f0, T_hi // to correct result's sign for cotl
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p15) fms.s1 C_hi = f0, f0, C_hi // to correct result's sign for cotl
+ nop.i 999
+};;
+
+{ .mfi
+ nop.m 999
+(p15) fms.s1 sgn_r = f0, f0, sgn_r // to correct result's sign for cotl
+ nop.i 999
+};;
+
+{ .mfi
+ nop.m 999
+//
+// N even: V_lo = V_lo + V_hi * tanx
+// N odd: V_lo = V_lo - V_hi * tanx
+//
+(p11) fnma.s1 V_lo = C_lo, V_hi, V_lo
+ nop.i 999
+}
+{ .mfi
+ nop.m 999
+(p12) fnma.s1 V_lo = T_lo, V_hi, V_lo
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: V_lo = V_lo - V_hi * C_lo
+// N odd: V_lo = V_lo - V_hi * T_lo
+//
+ fmpy.s1 V_lo = V_hi, V_lo
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even and odd: V_lo = V_lo * V_hi
+//
+ fadd.s1 tail = V_hi, V_lo
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even and odd: tail = V_hi + V_lo
+//
+ fma.s1 tail = tail, P, V_lo
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even: T_hi = sgn_r * T_hi
+// N odd : C_hi = -sgn_r * C_hi
+//
+ fma.s1 tail = tail, Sx, CORR
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even and odd: tail = Sx * tail + CORR
+//
+ fma.s1 tail = V_hi, Sx, tail
+ nop.i 999 ;;
+}
+{ .mfi
+ nop.m 999
+//
+// N even an odd: tail = Sx * V_hi + tail
+//
+(p11) fma.s0 Result = sgn_r, tail, T_hi
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p12) fma.s0 Result = sgn_r, tail, C_hi
+ br.ret.sptk b0 ;; // Exit for 1/4 <= |r| < pi/4
+}
+
+TANL_DENORMAL:
+// Here if x denormal
+{ .mfb
+ getf.exp GR_signexp_x = Norm_Arg // Get sign and exponent of x
+ nop.f 999
+ br.cond.sptk TANL_COMMON // Return to common code
+}
+;;
+
+
+TANL_SPECIAL:
+TANL_UNSUPPORTED:
+//
+// Code for NaNs, Unsupporteds, Infs, or +/- zero ?
+// Invalid raised for Infs and SNaNs.
+//
+
+{ .mfi
+ nop.m 999
+ fmerge.s f10 = f8, f8 // Save input for error call
+ tbit.nz p6, p7 = cot_flag, 0 // p6=1 if we compute cotl
+}
+;;
+
+{ .mfi
+ nop.m 999
+(p6) fclass.m p6, p7 = f8, 0x7 // Test for zero (cotl only)
+ nop.i 999
+}
+;;
+
+.pred.rel "mutex", p6, p7
+{ .mfi
+(p6) mov GR_Parameter_Tag = 225 // (cotl)
+(p6) frcpa.s0 f8, p0 = f1, f8 // cotl(+-0) = +-Inf
+ nop.i 999
+}
+{ .mfb
+ nop.m 999
+(p7) fmpy.s0 f8 = f8, f0
+(p7) br.ret.sptk b0
+}
+;;
+
+GLOBAL_IEEE754_END(tanl)
+
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+
+// (1)
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+
+// (2)
+{ .mmi
+ stfe [GR_Parameter_Y] = f1,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+// (3)
+{ .mib
+ stfe [GR_Parameter_X] = f10 // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfe [GR_Parameter_Y] = f8 // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+
+// (4)
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
+
+// *******************************************************************
+// *******************************************************************
+// *******************************************************************
+//
+// Special Code to handle very large argument case.
+// Call int __libm_pi_by_2_reduce(x,r,c) for |arguments| >= 2**63
+// The interface is custom:
+// On input:
+// (Arg or x) is in f8
+// On output:
+// r is in f8
+// c is in f9
+// N is in r8
+// We know also that __libm_pi_by_2_reduce preserves f10-15, f71-127. We
+// use this to eliminate save/restore of key fp registers in this calling
+// function.
+//
+// *******************************************************************
+// *******************************************************************
+// *******************************************************************
+
+LOCAL_LIBM_ENTRY(__libm_callout)
+TANL_ARG_TOO_LARGE:
+.prologue
+{ .mfi
+ add table_ptr2 = 144, table_base // Point to 2^-2
+ nop.f 999
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+;;
+
+// Load 2^-2, -2^-2
+{ .mmi
+ ldfps TWO_TO_NEG2, NEGTWO_TO_NEG2 = [table_ptr2]
+ setf.sig B_mask1 = bmask1 // Form mask to get 5 msb of r
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+
+.body
+//
+// Call argument reduction with x in f8
+// Returns with N in r8, r in f8, c in f9
+// Assumes f71-127 are preserved across the call
+//
+{ .mib
+ setf.sig B_mask2 = bmask2 // Form mask to form B from r
+ mov GR_SAVE_GP=gp // Save gp
+ br.call.sptk b0=__libm_pi_by_2_reduce#
+}
+;;
+
+//
+// Is |r| < 2**(-2)
+//
+{ .mfi
+ getf.sig sig_r = r // Extract significand of r
+ fcmp.lt.s1 p6, p0 = r, TWO_TO_NEG2
+ mov gp = GR_SAVE_GP // Restore gp
+}
+;;
+
+{ .mfi
+ getf.exp exp_r = r // Extract signexp of r
+ nop.f 999
+ mov b0 = GR_SAVE_B0 // Restore return address
+}
+;;
+
+//
+// Get N_fix_gr
+//
+{ .mfi
+ mov N_fix_gr = r8
+(p6) fcmp.gt.unc.s1 p6, p0 = r, NEGTWO_TO_NEG2
+ mov ar.pfs = GR_SAVE_PFS // Restore pfs
+}
+;;
+
+{ .mbb
+ nop.m 999
+(p6) br.cond.spnt TANL_SMALL_R // Branch if |r| < 1/4
+ br.cond.sptk TANL_NORMAL_R // Branch if 1/4 <= |r| < pi/4
+}
+;;
+
+LOCAL_LIBM_END(__libm_callout)
+
+.type __libm_pi_by_2_reduce#,@function
+.global __libm_pi_by_2_reduce#
diff --git a/libc/sysdeps/ia64/fpu/s_trunc.S b/libc/sysdeps/ia64/fpu/s_trunc.S
new file mode 100644
index 000000000..b9ad03b5a
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_trunc.S
@@ -0,0 +1,166 @@
+.file "trunc.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 07/07/00 Created
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance and reduced code size
+//==============================================================
+
+// API
+//==============================================================
+// double trunc(double x)
+//==============================================================
+
+// general input registers:
+// r14 - r18
+
+rExpBias = r14
+rSignexp = r15
+rExp = r16
+rExpMask = r17
+rBigexp = r18
+
+// floating-point registers:
+// f8 - f10
+
+fXtruncInt = f9
+fNormX = f10
+
+// predicate registers used:
+// p6, p7
+
+// Overview of operation
+//==============================================================
+// double trunc(double x)
+// Return an integer value (represented as a double) less than or
+// equal to x in magnitude.
+// This is x rounded toward zero to an integral value.
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+.section .text
+GLOBAL_LIBM_ENTRY(trunc)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fcvt.fx.trunc.s1 fXtruncInt = f8 // Convert to int in significand
+ addl rBigexp = 0x10033, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rExpBias = 0x0FFFF // Form exponent bias
+ fnorm.s1 fNormX = f8 // Normalize input
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+(p7) br.cond.spnt TRUNC_UNORM // Branch if x unorm
+}
+;;
+
+TRUNC_COMMON:
+// Return here from TRUNC_UNORM
+{ .mfb
+ and rExp = rSignexp, rExpMask // Get biased exponent
+(p6) fma.d.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ cmp.lt p6,p0 = rExp, rExpBias // Is |x| < 1?
+ fcvt.xf f8 = fXtruncInt // Result, assume 1 <= |x| < 2^52
+ cmp.ge p7,p0 = rExp, rBigexp // Is |x| >= 2^52?
+}
+;;
+
+// We must correct result if |x| < 1, or |x| >= 2^52
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fmerge.s f8 = fNormX, f0 // If |x| < 1, result sgn(x)*0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.d.s0 f8 = fNormX, f1, f0 // If |x| >= 2^52, result x
+ br.ret.sptk b0 // Exit main path
+}
+;;
+
+
+TRUNC_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk TRUNC_COMMON // Return to main path
+}
+;;
+
+GLOBAL_LIBM_END(trunc)
diff --git a/libc/sysdeps/ia64/fpu/s_truncf.S b/libc/sysdeps/ia64/fpu/s_truncf.S
new file mode 100644
index 000000000..ff40bc710
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_truncf.S
@@ -0,0 +1,166 @@
+.file "truncf.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 07/07/00 Created
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance and reduced code size
+//==============================================================
+
+// API
+//==============================================================
+// float truncf(float x)
+//==============================================================
+
+// general input registers:
+// r14 - r18
+
+rExpBias = r14
+rSignexp = r15
+rExp = r16
+rExpMask = r17
+rBigexp = r18
+
+// floating-point registers:
+// f8 - f10
+
+fXtruncInt = f9
+fNormX = f10
+
+// predicate registers used:
+// p6, p7
+
+// Overview of operation
+//==============================================================
+// float truncf(float x)
+// Return an integer value (represented as a float) less than or
+// equal to x in magnitude.
+// This is x rounded toward zero to an integral value.
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+.section .text
+GLOBAL_LIBM_ENTRY(truncf)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fcvt.fx.trunc.s1 fXtruncInt = f8 // Convert to int in significand
+ addl rBigexp = 0x10016, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rExpBias = 0x0FFFF // Form exponent bias
+ fnorm.s1 fNormX = f8 // Normalize input
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+(p7) br.cond.spnt TRUNC_UNORM // Branch if x unorm
+}
+;;
+
+TRUNC_COMMON:
+// Return here from TRUNC_UNORM
+{ .mfb
+ and rExp = rSignexp, rExpMask // Get biased exponent
+(p6) fma.s.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ cmp.lt p6,p0 = rExp, rExpBias // Is |x| < 1?
+ fcvt.xf f8 = fXtruncInt // Result, assume 1 <= |x| < 2^23
+ cmp.ge p7,p0 = rExp, rBigexp // Is |x| >= 2^23?
+}
+;;
+
+// We must correct result if |x| < 1, or |x| >= 2^23
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fmerge.s f8 = fNormX, f0 // If |x| < 1, result sgn(x)*0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.s.s0 f8 = fNormX, f1, f0 // If |x| >= 2^23, result x
+ br.ret.sptk b0 // Exit main path
+}
+;;
+
+
+TRUNC_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk TRUNC_COMMON // Return to main path
+}
+;;
+
+GLOBAL_LIBM_END(truncf)
diff --git a/libc/sysdeps/ia64/fpu/s_truncl.S b/libc/sysdeps/ia64/fpu/s_truncl.S
new file mode 100644
index 000000000..1afa19ba2
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/s_truncl.S
@@ -0,0 +1,166 @@
+.file "truncl.s"
+
+
+// Copyright (c) 2000 - 2003, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2000 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 07/07/00 Created
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 01/20/03 Improved performance and reduced code size
+//==============================================================
+
+// API
+//==============================================================
+// long double truncl(long double x)
+//==============================================================
+
+// general input registers:
+// r14 - r18
+
+rExpBias = r14
+rSignexp = r15
+rExp = r16
+rExpMask = r17
+rBigexp = r18
+
+// floating-point registers:
+// f8 - f10
+
+fXtruncInt = f9
+fNormX = f10
+
+// predicate registers used:
+// p6, p7
+
+// Overview of operation
+//==============================================================
+// long double truncl(long double x)
+// Return an integer value (represented as a long double) less than or
+// equal to x in magnitude.
+// This is x rounded toward zero to an integral value.
+//==============================================================
+
+// double_extended
+// if the exponent is > 1003e => 3F(true) = 63(decimal)
+// we have a significand of 64 bits 1.63-bits.
+// If we multiply by 2^63, we no longer have a fractional part
+// So input is an integer value already.
+
+// double
+// if the exponent is >= 10033 => 34(true) = 52(decimal)
+// 34 + 3ff = 433
+// we have a significand of 53 bits 1.52-bits. (implicit 1)
+// If we multiply by 2^52, we no longer have a fractional part
+// So input is an integer value already.
+
+// single
+// if the exponent is > 10016 => 17(true) = 23(decimal)
+// we have a significand of 24 bits 1.23-bits. (implicit 1)
+// If we multiply by 2^23, we no longer have a fractional part
+// So input is an integer value already.
+
+.section .text
+GLOBAL_LIBM_ENTRY(truncl)
+
+{ .mfi
+ getf.exp rSignexp = f8 // Get signexp, recompute if unorm
+ fcvt.fx.trunc.s1 fXtruncInt = f8 // Convert to int in significand
+ addl rBigexp = 0x1003e, r0 // Set exponent at which is integer
+}
+{ .mfi
+ mov rExpBias = 0x0FFFF // Form exponent bias
+ fnorm.s1 fNormX = f8 // Normalize input
+ mov rExpMask = 0x1FFFF // Form exponent mask
+}
+;;
+
+{ .mfi
+ nop.m 0
+ fclass.m p7,p0 = f8, 0x0b // Test x unorm
+ nop.i 0
+}
+;;
+
+{ .mfb
+ nop.m 0
+ fclass.m p6,p0 = f8, 0x1e3 // Test x natval, nan, inf
+(p7) br.cond.spnt TRUNC_UNORM // Branch if x unorm
+}
+;;
+
+TRUNC_COMMON:
+// Return here from TRUNC_UNORM
+{ .mfb
+ and rExp = rSignexp, rExpMask // Get biased exponent
+(p6) fma.s0 f8 = f8, f1, f0 // Result if x natval, nan, inf
+(p6) br.ret.spnt b0 // Exit if x natval, nan, inf
+}
+;;
+
+{ .mfi
+ cmp.lt p6,p0 = rExp, rExpBias // Is |x| < 1?
+ fcvt.xf f8 = fXtruncInt // Result, assume 1 <= |x| < 2^63
+ cmp.ge p7,p0 = rExp, rBigexp // Is |x| >= 2^63?
+}
+;;
+
+// We must correct result if |x| < 1, or |x| >= 2^63
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fmerge.s f8 = fNormX, f0 // If |x| < 1, result sgn(x)*0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.s0 f8 = fNormX, f1, f0 // If |x| >= 2^63, result x
+ br.ret.sptk b0 // Exit main path
+}
+;;
+
+
+TRUNC_UNORM:
+// Here if x unorm
+{ .mfb
+ getf.exp rSignexp = fNormX // Get signexp, recompute if unorm
+ fcmp.eq.s0 p7,p0 = f8, f0 // Dummy op to set denormal flag
+ br.cond.sptk TRUNC_COMMON // Return to main path
+}
+;;
+
+GLOBAL_LIBM_END(truncl)
diff --git a/libc/sysdeps/ia64/fpu/sincos32.c b/libc/sysdeps/ia64/fpu/sincos32.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/sincos32.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/slowexp.c b/libc/sysdeps/ia64/fpu/slowexp.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/slowexp.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/slowpow.c b/libc/sysdeps/ia64/fpu/slowpow.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/slowpow.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/t_exp.c b/libc/sysdeps/ia64/fpu/t_exp.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/t_exp.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_acos.c b/libc/sysdeps/ia64/fpu/w_acos.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_acos.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_acosf.c b/libc/sysdeps/ia64/fpu/w_acosf.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_acosf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_acosh.c b/libc/sysdeps/ia64/fpu/w_acosh.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_acosh.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_acoshf.c b/libc/sysdeps/ia64/fpu/w_acoshf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_acoshf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_acoshl.c b/libc/sysdeps/ia64/fpu/w_acoshl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_acoshl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_acosl.c b/libc/sysdeps/ia64/fpu/w_acosl.c
new file mode 100644
index 000000000..1cc893170
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_acosl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_asin.c b/libc/sysdeps/ia64/fpu/w_asin.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_asin.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_asinf.c b/libc/sysdeps/ia64/fpu/w_asinf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_asinf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_asinl.c b/libc/sysdeps/ia64/fpu/w_asinl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_asinl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_atan2.c b/libc/sysdeps/ia64/fpu/w_atan2.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_atan2.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_atan2f.c b/libc/sysdeps/ia64/fpu/w_atan2f.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_atan2f.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_atan2l.c b/libc/sysdeps/ia64/fpu/w_atan2l.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_atan2l.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_atanh.c b/libc/sysdeps/ia64/fpu/w_atanh.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_atanh.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_atanhf.c b/libc/sysdeps/ia64/fpu/w_atanhf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_atanhf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_atanhl.c b/libc/sysdeps/ia64/fpu/w_atanhl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_atanhl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_cosh.c b/libc/sysdeps/ia64/fpu/w_cosh.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_cosh.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_coshf.c b/libc/sysdeps/ia64/fpu/w_coshf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_coshf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_coshl.c b/libc/sysdeps/ia64/fpu/w_coshl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_coshl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_exp.c b/libc/sysdeps/ia64/fpu/w_exp.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_exp.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_exp10.c b/libc/sysdeps/ia64/fpu/w_exp10.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_exp10.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_exp10f.c b/libc/sysdeps/ia64/fpu/w_exp10f.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_exp10f.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_exp10l.c b/libc/sysdeps/ia64/fpu/w_exp10l.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_exp10l.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_exp2.c b/libc/sysdeps/ia64/fpu/w_exp2.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_exp2.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_exp2f.c b/libc/sysdeps/ia64/fpu/w_exp2f.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_exp2f.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_exp2l.c b/libc/sysdeps/ia64/fpu/w_exp2l.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_exp2l.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_expf.c b/libc/sysdeps/ia64/fpu/w_expf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_expf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_expl.c b/libc/sysdeps/ia64/fpu/w_expl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_expl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_fmod.c b/libc/sysdeps/ia64/fpu/w_fmod.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_fmod.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_fmodf.c b/libc/sysdeps/ia64/fpu/w_fmodf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_fmodf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_fmodl.c b/libc/sysdeps/ia64/fpu/w_fmodl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_fmodl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_hypot.c b/libc/sysdeps/ia64/fpu/w_hypot.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_hypot.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_hypotf.c b/libc/sysdeps/ia64/fpu/w_hypotf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_hypotf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_hypotl.c b/libc/sysdeps/ia64/fpu/w_hypotl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_hypotl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_lgamma.c b/libc/sysdeps/ia64/fpu/w_lgamma.c
new file mode 100644
index 000000000..2006d3e80
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_lgamma.c
@@ -0,0 +1,80 @@
+/* file: lgamma.c */
+
+
+// Copyright (c) 2002 Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+// History
+//==============================================================
+// 02/04/02: Initial version
+// 02/22/02: Removed lgammaf/gammaf
+//
+/*
+// FUNCTIONS: double lgamma(double x)
+// double gamma(double x)
+// Natural logarithm of GAMMA function
+*/
+
+#include "libm_support.h"
+
+
+extern double __libm_lgamma(double /*x*/, int* /*signgam*/, int /*signgamsz*/);
+
+
+double __ieee754_lgamma(double x)
+{
+#ifdef __POSIX__
+ extern int signgam;
+#else
+ int signgam;
+#endif
+ return __libm_lgamma(x, &signgam, sizeof(signgam));
+}
+weak_alias (__ieee754_lgamma, lgamma)
+
+double __ieee754_gamma(double x)
+{
+#ifdef __POSIX__
+ extern int signgam;
+#else
+ int signgam;
+#endif
+ return __libm_lgamma(x, &signgam, sizeof(signgam));
+}
+weak_alias (__ieee754_gamma, gamma)
diff --git a/libc/sysdeps/ia64/fpu/w_lgamma_r.c b/libc/sysdeps/ia64/fpu/w_lgamma_r.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_lgamma_r.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_lgammaf.c b/libc/sysdeps/ia64/fpu/w_lgammaf.c
new file mode 100644
index 000000000..cd0b4f666
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_lgammaf.c
@@ -0,0 +1,80 @@
+/* file: lgammaf.c */
+
+
+// Copyright (c) 2002 Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+// History
+//==============================================================
+// 02/04/02: Initial version
+// 02/22/02: Removed lgamma/gamma
+//
+/*
+// FUNCTIONS: float lgammaf(float x)
+// float gammaf(float x)
+// Natural logarithm of GAMMA function
+*/
+
+#include "libm_support.h"
+
+
+extern float __libm_lgammaf(float /*x*/, int* /*signgam*/, int /*signgamsz*/);
+
+
+float __ieee754_lgammaf(float x)
+{
+#ifdef __POSIX__
+ extern int signgam;
+#else
+ int signgam;
+#endif
+ return __libm_lgammaf(x, &signgam, sizeof(signgam));
+}
+weak_alias (__ieee754_lgammaf, lgammaf)
+
+float __ieee754_gammaf(float x)
+{
+#ifdef __POSIX__
+ extern int signgam;
+#else
+ int signgam;
+#endif
+ return __libm_lgammaf(x, &signgam, sizeof(signgam));
+}
+weak_alias (__ieee754_gammaf, gammaf)
diff --git a/libc/sysdeps/ia64/fpu/w_lgammaf_r.c b/libc/sysdeps/ia64/fpu/w_lgammaf_r.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_lgammaf_r.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_lgammal.c b/libc/sysdeps/ia64/fpu/w_lgammal.c
new file mode 100644
index 000000000..e3885296e
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_lgammal.c
@@ -0,0 +1,79 @@
+/* file: lgammal.c */
+
+
+// Copyright (c) 2002 Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//
+
+// History
+//==============================================================
+// 08/15/02: Initial version
+//
+/*
+// FUNCTIONS: long double lgammal(long double x)
+// long double gammal(long double x)
+// Natural logarithm of GAMMA function
+*/
+
+#include "libm_support.h"
+
+
+extern double __libm_lgammal(long double /*x*/, int* /*signgam*/, int /*signgamsz*/);
+
+
+long double __ieee754_lgammal(long double x)
+{
+#ifdef __POSIX__
+ extern int signgam;
+#else
+ int signgam;
+#endif
+ return __libm_lgammal(x, &signgam, sizeof(signgam));
+}
+weak_alias (__ieee754_lgammal, lgammal)
+
+long double __ieee754_gammal(long double x)
+{
+#ifdef __POSIX__
+ extern int signgam;
+#else
+ int signgam;
+#endif
+ return __libm_lgammal(x, &signgam, sizeof(signgam));
+}
+weak_alias (__ieee754_gammal, gammal)
diff --git a/libc/sysdeps/ia64/fpu/w_lgammal_r.c b/libc/sysdeps/ia64/fpu/w_lgammal_r.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_lgammal_r.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_log.c b/libc/sysdeps/ia64/fpu/w_log.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_log.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_log10.c b/libc/sysdeps/ia64/fpu/w_log10.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_log10.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_log10f.c b/libc/sysdeps/ia64/fpu/w_log10f.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_log10f.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_log10l.c b/libc/sysdeps/ia64/fpu/w_log10l.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_log10l.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_log2.c b/libc/sysdeps/ia64/fpu/w_log2.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_log2.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_log2f.c b/libc/sysdeps/ia64/fpu/w_log2f.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_log2f.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_log2l.c b/libc/sysdeps/ia64/fpu/w_log2l.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_log2l.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_logf.c b/libc/sysdeps/ia64/fpu/w_logf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_logf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_logl.c b/libc/sysdeps/ia64/fpu/w_logl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_logl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_pow.c b/libc/sysdeps/ia64/fpu/w_pow.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_pow.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_powf.c b/libc/sysdeps/ia64/fpu/w_powf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_powf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_powl.c b/libc/sysdeps/ia64/fpu/w_powl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_powl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_remainder.c b/libc/sysdeps/ia64/fpu/w_remainder.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_remainder.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_remainderf.c b/libc/sysdeps/ia64/fpu/w_remainderf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_remainderf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_remainderl.c b/libc/sysdeps/ia64/fpu/w_remainderl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_remainderl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_scalb.c b/libc/sysdeps/ia64/fpu/w_scalb.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_scalb.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_scalbf.c b/libc/sysdeps/ia64/fpu/w_scalbf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_scalbf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_scalbl.c b/libc/sysdeps/ia64/fpu/w_scalbl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_scalbl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_sinh.c b/libc/sysdeps/ia64/fpu/w_sinh.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_sinh.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_sinhf.c b/libc/sysdeps/ia64/fpu/w_sinhf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_sinhf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_sinhl.c b/libc/sysdeps/ia64/fpu/w_sinhl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_sinhl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_sqrt.c b/libc/sysdeps/ia64/fpu/w_sqrt.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_sqrt.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_sqrtf.c b/libc/sysdeps/ia64/fpu/w_sqrtf.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_sqrtf.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_sqrtl.c b/libc/sysdeps/ia64/fpu/w_sqrtl.c
new file mode 100644
index 000000000..41254ae60
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_sqrtl.c
@@ -0,0 +1 @@
+/* Not needed. */
diff --git a/libc/sysdeps/ia64/fpu/w_tgamma.S b/libc/sysdeps/ia64/fpu/w_tgamma.S
new file mode 100644
index 000000000..24f3d1184
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_tgamma.S
@@ -0,0 +1,1836 @@
+.file "tgamma.s"
+
+
+// Copyright (c) 2001 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING,BUT NOT
+// LIMITED TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code,and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 10/12/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 04/04/03 Changed error codes for overflow and negative integers
+// 04/10/03 Changed code for overflow near zero handling
+// 03/31/05 Reformatted delimiters between data tables
+//
+//*********************************************************************
+//
+//*********************************************************************
+//
+// Function: tgamma(x) computes the principle value of the GAMMA
+// function of x.
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8-f15
+// f33-f87
+//
+// General Purpose Registers:
+// r8-r11
+// r14-r28
+// r32-r36
+// r37-r40 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6-p15
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// tgamma(+inf) = +inf
+// tgamma(-inf) = QNaN
+// tgamma(+/-0) = +/-inf
+// tgamma(x<0, x - integer) = QNaN
+// tgamma(SNaN) = QNaN
+// tgamma(QNaN) = QNaN
+//
+//*********************************************************************
+//
+// Overview
+//
+// The method consists of three cases.
+//
+// If 2 <= x < OVERFLOW_BOUNDARY use case tgamma_regular;
+// else if 0 < x < 2 use case tgamma_from_0_to_2;
+// else if -(i+1) < x < -i, i = 0...184 use case tgamma_negatives;
+//
+// Case 2 <= x < OVERFLOW_BOUNDARY
+// -------------------------------
+// Here we use algorithm based on the recursive formula
+// GAMMA(x+1) = x*GAMMA(x). For that we subdivide interval
+// [2; OVERFLOW_BOUNDARY] into intervals [16*n; 16*(n+1)] and
+// approximate GAMMA(x) by polynomial of 22th degree on each
+// [16*n; 16*n+1], recursive formula is used to expand GAMMA(x)
+// to [16*n; 16*n+1]. In other words we need to find n, i and r
+// such that x = 16 * n + i + r where n and i are integer numbers
+// and r is fractional part of x. So GAMMA(x) = GAMMA(16*n+i+r) =
+// = (x-1)*(x-2)*...*(x-i)*GAMMA(x-i) =
+// = (x-1)*(x-2)*...*(x-i)*GAMMA(16*n+r) ~
+// ~ (x-1)*(x-2)*...*(x-i)*P22n(r).
+//
+// Step 1: Reduction
+// -----------------
+// N = [x] with truncate
+// r = x - N, note 0 <= r < 1
+//
+// n = N & ~0xF - index of table that contains coefficient of
+// polynomial approximation
+// i = N & 0xF - is used in recursive formula
+//
+//
+// Step 2: Approximation
+// ---------------------
+// We use factorized minimax approximation polynomials
+// P22n(r) = A22*(r^2+C01(n)*R+C00(n))*
+// *(r^2+C11(n)*R+C10(n))*...*(r^2+CA1(n)*R+CA0(n))
+//
+// Step 3: Recursion
+// -----------------
+// In case when i > 0 we need to multiply P22n(r) by product
+// R(i)=(x-1)*(x-2)*...*(x-i). To reduce number of fp-instructions
+// we can calculate R as follow:
+// R(i) = ((x-1)*(x-2))*((x-3)*(x-4))*...*((x-(i-1))*(x-i)) if i is
+// even or R = ((x-1)*(x-2))*((x-3)*(x-4))*...*((x-(i-2))*(x-(i-1)))*
+// *(i-1) if i is odd. In both cases we need to calculate
+// R2(i) = (x^2-3*x+2)*(x^2-7*x+12)*...*(x^2+x+2*j*(2*j-1)) =
+// = (x^2-3*x+2)*(x^2-7*x+12)*...*((x^2+x)+2*j*(2*(j-1)+(1-2*x))) =
+// = (RA+2*(2-RB))*(RA+4*(4-RB))*...*(RA+2*j*(2*(j-1)+RB))
+// where j = 1..[i/2], RA = x^2+x, RB = 1-2*x.
+//
+// Step 4: Reconstruction
+// ----------------------
+// Reconstruction is just simple multiplication i.e.
+// GAMMA(x) = P22n(r)*R(i)
+//
+// Case 0 < x < 2
+// --------------
+// To calculate GAMMA(x) on this interval we do following
+// if 1 <= x < 1.25 than GAMMA(x) = P15(x-1)
+// if 1.25 <= x < 1.5 than GAMMA(x) = P15(x-x_min) where
+// x_min is point of local minimum on [1; 2] interval.
+// if 1.5 <= x < 2.0 than GAMMA(x) = P15(x-1.5)
+// and
+// if 0 < x < 1 than GAMMA(x) = GAMMA(x+1)/x
+//
+// Case -(i+1) < x < -i, i = 0...184
+// ----------------------------------
+// Here we use the fact that GAMMA(-x) = PI/(x*GAMMA(x)*sin(PI*x)) and
+// so we need to calculate GAMMA(x), sin(PI*x)/PI. Calculation of
+// GAMMA(x) is described above.
+//
+// Step 1: Reduction
+// -----------------
+// Note that period of sin(PI*x) is 2 and range reduction for
+// sin(PI*x) is like to range reduction for GAMMA(x)
+// i.e r = x - [x] with exception of cases
+// when r > 0.5 (in such cases r = 1 - (x - [x])).
+//
+// Step 2: Approximation
+// ---------------------
+// To approximate sin(PI*x)/PI = sin(PI*(2*n+r))/PI =
+// = (-1)^n*sin(PI*r)/PI Taylor series is used.
+// sin(PI*r)/PI ~ S21(r).
+//
+// Step 3: Division
+// ----------------
+// To calculate 1/(x*GAMMA(x)*S21(r)) we use frcpa instruction
+// with following Newton-Raphson interations.
+//
+//
+//*********************************************************************
+
+GR_Sig = r8
+GR_TAG = r8
+GR_ad_Data = r9
+GR_SigRqLin = r10
+GR_iSig = r11
+GR_ExpOf1 = r11
+GR_ExpOf8 = r11
+
+
+GR_Sig2 = r14
+GR_Addr_Mask1 = r15
+GR_Sign_Exp = r16
+GR_Tbl_Offs = r17
+GR_Addr_Mask2 = r18
+GR_ad_Co = r19
+GR_Bit2 = r19
+GR_ad_Ce = r20
+GR_ad_Co7 = r21
+GR_NzOvfBound = r21
+GR_ad_Ce7 = r22
+GR_Tbl_Ind = r23
+GR_Tbl_16xInd = r24
+GR_ExpOf025 = r24
+GR_ExpOf05 = r25
+GR_0x30033 = r26
+GR_10 = r26
+GR_12 = r27
+GR_185 = r27
+GR_14 = r28
+GR_2 = r28
+GR_fpsr = r28
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+
+FR_X = f10
+FR_Y = f1 // tgamma is single argument function
+FR_RESULT = f8
+
+FR_AbsX = f9
+FR_NormX = f9
+FR_r02 = f11
+FR_AbsXp1 = f12
+FR_X2pX = f13
+FR_1m2X = f14
+FR_Rq1 = f14
+FR_Xt = f15
+
+FR_r = f33
+FR_OvfBound = f34
+FR_Xmin = f35
+FR_2 = f36
+FR_Rcp1 = f36
+FR_Rcp3 = f36
+FR_4 = f37
+FR_5 = f38
+FR_6 = f39
+FR_8 = f40
+FR_10 = f41
+FR_12 = f42
+FR_14 = f43
+FR_GAMMA = f43
+FR_05 = f44
+
+FR_Rq2 = f45
+FR_Rq3 = f46
+FR_Rq4 = f47
+FR_Rq5 = f48
+FR_Rq6 = f49
+FR_Rq7 = f50
+FR_RqLin = f51
+
+FR_InvAn = f52
+
+FR_C01 = f53
+FR_A15 = f53
+FR_C11 = f54
+FR_A14 = f54
+FR_C21 = f55
+FR_A13 = f55
+FR_C31 = f56
+FR_A12 = f56
+FR_C41 = f57
+FR_A11 = f57
+FR_C51 = f58
+FR_A10 = f58
+FR_C61 = f59
+FR_A9 = f59
+FR_C71 = f60
+FR_A8 = f60
+FR_C81 = f61
+FR_A7 = f61
+FR_C91 = f62
+FR_A6 = f62
+FR_CA1 = f63
+FR_A5 = f63
+FR_C00 = f64
+FR_A4 = f64
+FR_rs2 = f64
+FR_C10 = f65
+FR_A3 = f65
+FR_rs3 = f65
+FR_C20 = f66
+FR_A2 = f66
+FR_rs4 = f66
+FR_C30 = f67
+FR_A1 = f67
+FR_rs7 = f67
+FR_C40 = f68
+FR_A0 = f68
+FR_rs8 = f68
+FR_C50 = f69
+FR_r2 = f69
+FR_C60 = f70
+FR_r3 = f70
+FR_C70 = f71
+FR_r4 = f71
+FR_C80 = f72
+FR_r7 = f72
+FR_C90 = f73
+FR_r8 = f73
+FR_CA0 = f74
+FR_An = f75
+
+FR_S21 = f76
+FR_S19 = f77
+FR_Rcp0 = f77
+FR_Rcp2 = f77
+FR_S17 = f78
+FR_S15 = f79
+FR_S13 = f80
+FR_S11 = f81
+FR_S9 = f82
+FR_S7 = f83
+FR_S5 = f84
+FR_S3 = f85
+
+FR_iXt = f86
+FR_rs = f87
+
+
+// Data tables
+//==============================================================
+RODATA
+.align 16
+
+LOCAL_OBJECT_START(tgamma_data)
+data8 0x406573FAE561F648 // overflow boundary (171.624376956302739927196)
+data8 0x3FDD8B618D5AF8FE // point of local minium (0.461632144968362356785)
+//
+//[2; 3]
+data8 0xEF0E85C9AE40ABE2,0x00004000 // C01
+data8 0xCA2049DDB4096DD8,0x00004000 // C11
+data8 0x99A203B4DC2D1A8C,0x00004000 // C21
+data8 0xBF5D9D9C0C295570,0x00003FFF // C31
+data8 0xE8DD037DEB833BAB,0x00003FFD // C41
+data8 0xB6AE39A2A36AA03A,0x0000BFFE // C51
+data8 0x804960DC2850277B,0x0000C000 // C61
+data8 0xD9F3973841C09F80,0x0000C000 // C71
+data8 0x9C198A676F8A2239,0x0000C001 // C81
+data8 0xC98B7DAE02BE3226,0x0000C001 // C91
+data8 0xE9CAF31AC69301BA,0x0000C001 // CA1
+data8 0xFBBDD58608A0D172,0x00004000 // C00
+data8 0xFDD0316D1E078301,0x00004000 // C10
+data8 0x8630B760468C15E4,0x00004001 // C20
+data8 0x93EDE20E47D9152E,0x00004001 // C30
+data8 0xA86F3A38C77D6B19,0x00004001 // C40
+//[16; 17]
+data8 0xF87F757F365EE813,0x00004000 // C01
+data8 0xECA84FBA92759DA4,0x00004000 // C11
+data8 0xD4E0A55E07A8E913,0x00004000 // C21
+data8 0xB0EB45E94C8A5F7B,0x00004000 // C31
+data8 0x8050D6B4F7C8617D,0x00004000 // C41
+data8 0x8471B111AA691E5A,0x00003FFF // C51
+data8 0xADAF462AF96585C9,0x0000BFFC // C61
+data8 0xD327C7A587A8C32B,0x0000BFFF // C71
+data8 0xDEF5192B4CF5E0F1,0x0000C000 // C81
+data8 0xBADD64BB205AEF02,0x0000C001 // C91
+data8 0x9330A24AA67D6860,0x0000C002 // CA1
+data8 0xF57EEAF36D8C47BE,0x00004000 // C00
+data8 0x807092E12A251B38,0x00004001 // C10
+data8 0x8C458F80DEE7ED1C,0x00004001 // C20
+data8 0x9F30C731DC77F1A6,0x00004001 // C30
+data8 0xBAC4E7E099C3A373,0x00004001 // C40
+//[32; 33]
+data8 0xC3059A415F142DEF,0x00004000 // C01
+data8 0xB9C1DAC24664587A,0x00004000 // C11
+data8 0xA7101D910992FFB2,0x00004000 // C21
+data8 0x8A9522B8E4AA0AB4,0x00004000 // C31
+data8 0xC76A271E4BA95DCC,0x00003FFF // C41
+data8 0xC5D6DE2A38DB7FF2,0x00003FFE // C51
+data8 0xDBA42086997818B2,0x0000BFFC // C61
+data8 0xB8EDDB1424C1C996,0x0000BFFF // C71
+data8 0xBF7372FB45524B5D,0x0000C000 // C81
+data8 0xA03DDE759131580A,0x0000C001 // C91
+data8 0xFDA6FC4022C1FFE3,0x0000C001 // CA1
+data8 0x9759ABF797B2533D,0x00004000 // C00
+data8 0x9FA160C6CF18CEC5,0x00004000 // C10
+data8 0xB0EFF1E3530E0FCD,0x00004000 // C20
+data8 0xCCD60D5C470165D1,0x00004000 // C30
+data8 0xF5E53F6307B0B1C1,0x00004000 // C40
+//[48; 49]
+data8 0xAABE577FBCE37F5E,0x00004000 // C01
+data8 0xA274CAEEB5DF7172,0x00004000 // C11
+data8 0x91B90B6646C1B924,0x00004000 // C21
+data8 0xF06718519CA256D9,0x00003FFF // C31
+data8 0xAA9EE181C0E30263,0x00003FFF // C41
+data8 0xA07BDB5325CB28D2,0x00003FFE // C51
+data8 0x86C8B873204F9219,0x0000BFFD // C61
+data8 0xB0192C5D3E4787D6,0x0000BFFF // C71
+data8 0xB1E0A6263D4C19EF,0x0000C000 // C81
+data8 0x93BA32A118EAC9AE,0x0000C001 // C91
+data8 0xE942A39CD9BEE887,0x0000C001 // CA1
+data8 0xE838B0957B0D3D0D,0x00003FFF // C00
+data8 0xF60E0F00074FCF34,0x00003FFF // C10
+data8 0x89869936AE00C2A5,0x00004000 // C20
+data8 0xA0FE4E8AA611207F,0x00004000 // C30
+data8 0xC3B1229CFF1DDAFE,0x00004000 // C40
+//[64; 65]
+data8 0x9C00DDF75CDC6183,0x00004000 // C01
+data8 0x9446AE9C0F6A833E,0x00004000 // C11
+data8 0x84ABC5083310B774,0x00004000 // C21
+data8 0xD9BA3A0977B1ED83,0x00003FFF // C31
+data8 0x989B18C99411D300,0x00003FFF // C41
+data8 0x886E66402318CE6F,0x00003FFE // C51
+data8 0x99028C2468F18F38,0x0000BFFD // C61
+data8 0xAB72D17DCD40CCE1,0x0000BFFF // C71
+data8 0xA9D9AC9BE42C2EF9,0x0000C000 // C81
+data8 0x8C11D983AA177AD2,0x0000C001 // C91
+data8 0xDC779E981C1F0F06,0x0000C001 // CA1
+data8 0xC1FD4AC85965E8D6,0x00003FFF // C00
+data8 0xCE3D2D909D389EC2,0x00003FFF // C10
+data8 0xE7F79980AD06F5D8,0x00003FFF // C20
+data8 0x88DD9F73C8680B5D,0x00004000 // C30
+data8 0xA7D6CB2CB2D46F9D,0x00004000 // C40
+//[80; 81]
+data8 0x91C7FF4E993430D0,0x00004000 // C01
+data8 0x8A6E7AB83E45A7E9,0x00004000 // C11
+data8 0xF72D6382E427BEA9,0x00003FFF // C21
+data8 0xC9E2E4F9B3B23ED6,0x00003FFF // C31
+data8 0x8BEFEF56AE05D775,0x00003FFF // C41
+data8 0xEE9666AB6A185560,0x00003FFD // C51
+data8 0xA6AFAF5CEFAEE04D,0x0000BFFD // C61
+data8 0xA877EAFEF1F9C880,0x0000BFFF // C71
+data8 0xA45BD433048ECA15,0x0000C000 // C81
+data8 0x86BD1636B774CC2E,0x0000C001 // C91
+data8 0xD3721BE006E10823,0x0000C001 // CA1
+data8 0xA97EFABA91854208,0x00003FFF // C00
+data8 0xB4AF0AEBB3F97737,0x00003FFF // C10
+data8 0xCC38241936851B0B,0x00003FFF // C20
+data8 0xF282A6261006EA84,0x00003FFF // C30
+data8 0x95B8E9DB1BD45BAF,0x00004000 // C40
+//[96; 97]
+data8 0x8A1FA3171B35A106,0x00004000 // C01
+data8 0x830D5B8843890F21,0x00004000 // C11
+data8 0xE98B0F1616677A23,0x00003FFF // C21
+data8 0xBDF8347F5F67D4EC,0x00003FFF // C31
+data8 0x825F15DE34EC055D,0x00003FFF // C41
+data8 0xD4846186B8AAC7BE,0x00003FFD // C51
+data8 0xB161093AB14919B1,0x0000BFFD // C61
+data8 0xA65758EEA4800EF4,0x0000BFFF // C71
+data8 0xA046B67536FA329C,0x0000C000 // C81
+data8 0x82BBEC1BCB9E9068,0x0000C001 // C91
+data8 0xCC9DE2B23BA91B0B,0x0000C001 // CA1
+data8 0x983B16148AF77F94,0x00003FFF // C00
+data8 0xA2A4D8EE90FEE5DD,0x00003FFF // C10
+data8 0xB89446FA37FF481C,0x00003FFF // C20
+data8 0xDC5572648485FB01,0x00003FFF // C30
+data8 0x88CD5D7DB976129A,0x00004000 // C40
+//[112; 113]
+data8 0x8417098FD62AC5E3,0x00004000 // C01
+data8 0xFA7896486B779CBB,0x00003FFF // C11
+data8 0xDEC98B14AF5EEBD1,0x00003FFF // C21
+data8 0xB48E153C6BF0B5A3,0x00003FFF // C31
+data8 0xF597B038BC957582,0x00003FFE // C41
+data8 0xBFC6F0884A415694,0x00003FFD // C51
+data8 0xBA075A1392BDB5E5,0x0000BFFD // C61
+data8 0xA4B79E01B44C7DB4,0x0000BFFF // C71
+data8 0x9D12FA7711BFAB0F,0x0000C000 // C81
+data8 0xFF24C47C8E108AB4,0x0000C000 // C91
+data8 0xC7325EC86562606A,0x0000C001 // CA1
+data8 0x8B47DCD9E1610938,0x00003FFF // C00
+data8 0x9518B111B70F88B8,0x00003FFF // C10
+data8 0xA9CC197206F68682,0x00003FFF // C20
+data8 0xCB98294CC0D7A6A6,0x00003FFF // C30
+data8 0xFE09493EA9165181,0x00003FFF // C40
+//[128; 129]
+data8 0xFE53D03442270D90,0x00003FFF // C01
+data8 0xF0F857BAEC1993E4,0x00003FFF // C11
+data8 0xD5FF6D70DBBC2FD3,0x00003FFF // C21
+data8 0xACDAA5F4988B1074,0x00003FFF // C31
+data8 0xE92E069F8AD75B54,0x00003FFE // C41
+data8 0xAEBB64645BD94234,0x00003FFD // C51
+data8 0xC13746249F39B43C,0x0000BFFD // C61
+data8 0xA36B74F5B6297A1F,0x0000BFFF // C71
+data8 0x9A77860DF180F6E5,0x0000C000 // C81
+data8 0xF9F8457D84410A0C,0x0000C000 // C91
+data8 0xC2BF44C649EB8597,0x0000C001 // CA1
+data8 0x81225E7489BCDC0E,0x00003FFF // C00
+data8 0x8A788A09CE0EED11,0x00003FFF // C10
+data8 0x9E2E6F86D1B1D89C,0x00003FFF // C20
+data8 0xBE6866B21CF6CCB5,0x00003FFF // C30
+data8 0xEE94426EC1486AAE,0x00003FFF // C40
+//[144; 145]
+data8 0xF6113E09732A6497,0x00003FFF // C01
+data8 0xE900D45931B04FC8,0x00003FFF // C11
+data8 0xCE9FD58F745EBA5D,0x00003FFF // C21
+data8 0xA663A9636C864C86,0x00003FFF // C31
+data8 0xDEBF5315896CE629,0x00003FFE // C41
+data8 0xA05FEA415EBD7737,0x00003FFD // C51
+data8 0xC750F112BD9C4031,0x0000BFFD // C61
+data8 0xA2593A35C51C6F6C,0x0000BFFF // C71
+data8 0x9848E1DA7FB40C8C,0x0000C000 // C81
+data8 0xF59FEE87A5759A4B,0x0000C000 // C91
+data8 0xBF00203909E45A1D,0x0000C001 // CA1
+data8 0xF1D8E157200127E5,0x00003FFE // C00
+data8 0x81DD5397CB08D487,0x00003FFF // C10
+data8 0x94C1DC271A8B766F,0x00003FFF // C20
+data8 0xB3AFAF9B5D6EDDCF,0x00003FFF // C30
+data8 0xE1FB4C57CA81BE1E,0x00003FFF // C40
+//[160; 161]
+data8 0xEEFFE5122AC72FFD,0x00003FFF // C01
+data8 0xE22F70BB52AD54B3,0x00003FFF // C11
+data8 0xC84FF021FE993EEA,0x00003FFF // C21
+data8 0xA0DA2208EB5B2752,0x00003FFF // C31
+data8 0xD5CDD2FCF8AD2DF5,0x00003FFE // C41
+data8 0x940BEC6DCD811A59,0x00003FFD // C51
+data8 0xCC954EF4FD4EBB81,0x0000BFFD // C61
+data8 0xA1712E29A8C04554,0x0000BFFF // C71
+data8 0x966B55DFB243521A,0x0000C000 // C81
+data8 0xF1E6A2B9CEDD0C4C,0x0000C000 // C91
+data8 0xBBC87BCC031012DB,0x0000C001 // CA1
+data8 0xE43974E6D2818583,0x00003FFE // C00
+data8 0xF5702A516B64C5B7,0x00003FFE // C10
+data8 0x8CEBCB1B32E19471,0x00003FFF // C20
+data8 0xAAC10F05BB77E0AF,0x00003FFF // C30
+data8 0xD776EFCAB205CC58,0x00003FFF // C40
+//[176; 177]
+data8 0xE8DA614119811E5D,0x00003FFF // C01
+data8 0xDC415E0288B223D8,0x00003FFF // C11
+data8 0xC2D2243E44EC970E,0x00003FFF // C21
+data8 0x9C086664B5307BEA,0x00003FFF // C31
+data8 0xCE03D7A08B461156,0x00003FFE // C41
+data8 0x894BE3BAAAB66ADC,0x00003FFD // C51
+data8 0xD131EDD71A702D4D,0x0000BFFD // C61
+data8 0xA0A907CDDBE10898,0x0000BFFF // C71
+data8 0x94CC3CD9C765C808,0x0000C000 // C81
+data8 0xEEA85F237815FC0D,0x0000C000 // C91
+data8 0xB8FA04B023E43F91,0x0000C001 // CA1
+data8 0xD8B2C7D9FCBD7EF9,0x00003FFE // C00
+data8 0xE9566E93AAE7E38F,0x00003FFE // C10
+data8 0x8646E78AABEF0255,0x00003FFF // C20
+data8 0xA32AEDB62E304345,0x00003FFF // C30
+data8 0xCE83E40280EE7DF0,0x00003FFF // C40
+//
+//[2; 3]
+data8 0xC44FB47E90584083,0x00004001 // C50
+data8 0xE863EE77E1C45981,0x00004001 // C60
+data8 0x8AC15BE238B9D70E,0x00004002 // C70
+data8 0xA5D94B6592350EF4,0x00004002 // C80
+data8 0xC379DB3E20A148B3,0x00004002 // C90
+data8 0xDACA49B73974F6C9,0x00004002 // CA0
+data8 0x810E496A1AFEC895,0x00003FE1 // An
+//[16; 17]
+data8 0xE17C0357AAF3F817,0x00004001 // C50
+data8 0x8BA8804750FBFBFE,0x00004002 // C60
+data8 0xB18EAB3CB64BEBEE,0x00004002 // C70
+data8 0xE90AB7015AF1C28F,0x00004002 // C80
+data8 0xA0AB97CE9E259196,0x00004003 // C90
+data8 0xF5E0E0A000C2D720,0x00004003 // CA0
+data8 0xD97F0F87EC791954,0x00004005 // An
+//[32; 33]
+data8 0x980C293F3696040D,0x00004001 // C50
+data8 0xC0DBFFBB948A9A4E,0x00004001 // C60
+data8 0xFAB54625E9A588A2,0x00004001 // C70
+data8 0xA7E08176D6050FBF,0x00004002 // C80
+data8 0xEBAAEC4952270A9F,0x00004002 // C90
+data8 0xB7479CDAD20550FE,0x00004003 // CA0
+data8 0xAACD45931C3FF634,0x00004054 // An
+//[48; 49]
+data8 0xF5180F0000419AD5,0x00004000 // C50
+data8 0x9D507D07BFBB2273,0x00004001 // C60
+data8 0xCEB53F7A13A383E3,0x00004001 // C70
+data8 0x8BAFEF9E0A49128F,0x00004002 // C80
+data8 0xC58EF912D39E228C,0x00004002 // C90
+data8 0x9A88118422BA208E,0x00004003 // CA0
+data8 0xBD6C0E2477EC12CB,0x000040AC // An
+//[64; 65]
+data8 0xD410AC48BF7748DA,0x00004000 // C50
+data8 0x89399B90AFEBD931,0x00004001 // C60
+data8 0xB596DF8F77EB8560,0x00004001 // C70
+data8 0xF6D9445A047FB4A6,0x00004001 // C80
+data8 0xAF52F0DD65221357,0x00004002 // C90
+data8 0x8989B45BFC881989,0x00004003 // CA0
+data8 0xB7FCAE86E6E10D5A,0x0000410B // An
+//[80; 81]
+data8 0xBE759740E3B5AA84,0x00004000 // C50
+data8 0xF8037B1B07D27609,0x00004000 // C60
+data8 0xA4F6F6C7F0977D4F,0x00004001 // C70
+data8 0xE131960233BF02C4,0x00004001 // C80
+data8 0xA06DF43D3922BBE2,0x00004002 // C90
+data8 0xFC266AB27255A360,0x00004002 // CA0
+data8 0xD9F4B012EDAFEF2F,0x0000416F // An
+//[96; 97]
+data8 0xAEFC84CDA8E1EAA6,0x00004000 // C50
+data8 0xE5009110DB5F3C8A,0x00004000 // C60
+data8 0x98F5F48738E7B232,0x00004001 // C70
+data8 0xD17EE64E21FFDC6B,0x00004001 // C80
+data8 0x9596F7A7E36145CC,0x00004002 // C90
+data8 0xEB64DBE50E125CAF,0x00004002 // CA0
+data8 0xA090530D79E32D2E,0x000041D8 // An
+//[112; 113]
+data8 0xA33AEA22A16B2655,0x00004000 // C50
+data8 0xD682B93BD7D7945C,0x00004000 // C60
+data8 0x8FC854C6E6E30CC3,0x00004001 // C70
+data8 0xC5754D828AFFDC7A,0x00004001 // C80
+data8 0x8D41216B397139C2,0x00004002 // C90
+data8 0xDE78D746848116E5,0x00004002 // CA0
+data8 0xB8A297A2DC0630DB,0x00004244 // An
+//[128; 129]
+data8 0x99EB00F11D95E292,0x00004000 // C50
+data8 0xCB005CB911EB779A,0x00004000 // C60
+data8 0x8879AA2FDFF3A37A,0x00004001 // C70
+data8 0xBBDA538AD40CAC2C,0x00004001 // C80
+data8 0x8696D849D311B9DE,0x00004002 // C90
+data8 0xD41E1C041481199F,0x00004002 // CA0
+data8 0xEBA1A43D34EE61EE,0x000042B3 // An
+//[144; 145]
+data8 0x924F822578AA9F3D,0x00004000 // C50
+data8 0xC193FAF9D3B36960,0x00004000 // C60
+data8 0x827AE3A6B68ED0CA,0x00004001 // C70
+data8 0xB3F52A27EED23F0B,0x00004001 // C80
+data8 0x811A079FB3C94D79,0x00004002 // C90
+data8 0xCB94415470B6F8D2,0x00004002 // CA0
+data8 0x80A0260DCB3EC9AC,0x00004326 // An
+//[160; 161]
+data8 0x8BF24091E88B331D,0x00004000 // C50
+data8 0xB9ADE01187E65201,0x00004000 // C60
+data8 0xFAE4508F6E7625FE,0x00004000 // C70
+data8 0xAD516668AD6D7367,0x00004001 // C80
+data8 0xF8F5FF171154F637,0x00004001 // C90
+data8 0xC461321268990C82,0x00004002 // CA0
+data8 0xC3B693F344B0E6FE,0x0000439A // An
+//
+//[176; 177]
+data8 0x868545EB42A258ED,0x00004000 // C50
+data8 0xB2EF04ACE8BA0E6E,0x00004000 // C60
+data8 0xF247D22C22E69230,0x00004000 // C70
+data8 0xA7A1AB93E3981A90,0x00004001 // C80
+data8 0xF10951733E2C697F,0x00004001 // C90
+data8 0xBE3359BFAD128322,0x00004002 // CA0
+data8 0x8000000000000000,0x00003fff
+//
+//[160; 161] for negatives
+data8 0xA76DBD55B2E32D71,0x00003C63 // 1/An
+//
+// sin(pi*x)/pi
+data8 0xBCBC4342112F52A2,0x00003FDE // S21
+data8 0xFAFCECB86536F655,0x0000BFE3 // S19
+data8 0x87E4C97F9CF09B92,0x00003FE9 // S17
+data8 0xEA124C68E704C5CB,0x0000BFED // S15
+data8 0x9BA38CFD59C8AA1D,0x00003FF2 // S13
+data8 0x99C0B552303D5B21,0x0000BFF6 // S11
+//
+//[176; 177] for negatives
+data8 0xBA5D5869211696FF,0x00003BEC // 1/An
+//
+// sin(pi*x)/pi
+data8 0xD63402E79A853175,0x00003FF9 // S9
+data8 0xC354723906DB36BA,0x0000BFFC // S7
+data8 0xCFCE5A015E236291,0x00003FFE // S5
+data8 0xD28D3312983E9918,0x0000BFFF // S3
+//
+//
+// [1.0;1.25]
+data8 0xA405530B067ECD3C,0x0000BFFC // A15
+data8 0xF5B5413F95E1C282,0x00003FFD // A14
+data8 0xC4DED71C782F76C8,0x0000BFFE // A13
+data8 0xECF7DDDFD27C9223,0x00003FFE // A12
+data8 0xFB73D31793068463,0x0000BFFE // A11
+data8 0xFF173B7E66FD1D61,0x00003FFE // A10
+data8 0xFFA5EF3959089E94,0x0000BFFE // A9
+data8 0xFF8153BD42E71A4F,0x00003FFE // A8
+data8 0xFEF9CAEE2CB5B533,0x0000BFFE // A7
+data8 0xFE3F02E5EDB6811E,0x00003FFE // A6
+data8 0xFB64074CED2658FB,0x0000BFFE // A5
+data8 0xFB52882A095B18A4,0x00003FFE // A4
+data8 0xE8508C7990A0DAC0,0x0000BFFE // A3
+data8 0xFD32C611D8A881D0,0x00003FFE // A2
+data8 0x93C467E37DB0C536,0x0000BFFE // A1
+data8 0x8000000000000000,0x00003FFF // A0
+//
+// [1.25;1.5]
+data8 0xD038092400619677,0x0000BFF7 // A15
+data8 0xEA6DE925E6EB8C8F,0x00003FF3 // A14
+data8 0xC53F83645D4597FC,0x0000BFF7 // A13
+data8 0xE366DB2FB27B7ECD,0x00003FF7 // A12
+data8 0xAC8FD5E11F6EEAD8,0x0000BFF8 // A11
+data8 0xFB14010FB3697785,0x00003FF8 // A10
+data8 0xB6F91CB5C371177B,0x0000BFF9 // A9
+data8 0x85A262C6F8FEEF71,0x00003FFA // A8
+data8 0xC038E6E3261568F9,0x0000BFFA // A7
+data8 0x8F4BDE8883232364,0x00003FFB // A6
+data8 0xBCFBBD5786537E9A,0x0000BFFB // A5
+data8 0xA4C08BAF0A559479,0x00003FFC // A4
+data8 0x85D74FA063E81476,0x0000BFFC // A3
+data8 0xDB629FB9BBDC1C4E,0x00003FFD // A2
+data8 0xF4F8FBC7C0C9D317,0x00003FC6 // A1
+data8 0xE2B6E4153A57746C,0x00003FFE // A0
+//
+// [1.25;1.5]
+data8 0x9533F9D3723B448C,0x0000BFF2 // A15
+data8 0xF1F75D3C561CBBAF,0x00003FF5 // A14
+data8 0xBA55A9A1FC883523,0x0000BFF8 // A13
+data8 0xB5D5E9E5104FA995,0x00003FFA // A12
+data8 0xFD84F35B70CD9AE2,0x0000BFFB // A11
+data8 0x87445235F4688CC5,0x00003FFD // A10
+data8 0xE7F236EBFB9F774E,0x0000BFFD // A9
+data8 0xA6605F2721F787CE,0x00003FFE // A8
+data8 0xCF579312AD7EAD72,0x0000BFFE // A7
+data8 0xE96254A2407A5EAC,0x00003FFE // A6
+data8 0xF41312A8572ED346,0x0000BFFE // A5
+data8 0xF9535027C1B1F795,0x00003FFE // A4
+data8 0xE7E82D0C613A8DE4,0x0000BFFE // A3
+data8 0xFD23CD9741B460B8,0x00003FFE // A2
+data8 0x93C30FD9781DBA88,0x0000BFFE // A1
+data8 0xFFFFF1781FDBEE84,0x00003FFE // A0
+LOCAL_OBJECT_END(tgamma_data)
+
+
+//==============================================================
+// Code
+//==============================================================
+
+.section .text
+GLOBAL_LIBM_ENTRY(tgamma)
+{ .mfi
+ getf.exp GR_Sign_Exp = f8
+ fma.s1 FR_1m2X = f8,f1,f8 // 2x
+ addl GR_ad_Data = @ltoff(tgamma_data), gp
+}
+{ .mfi
+ mov GR_ExpOf8 = 0x10002 // 8
+ fcvt.fx.trunc.s1 FR_iXt = f8 // [x]
+ mov GR_ExpOf05 = 0xFFFE // 0.5
+};;
+{ .mfi
+ getf.sig GR_Sig = f8
+ fma.s1 FR_2 = f1,f1,f1 // 2
+ mov GR_Addr_Mask1 = 0x780
+}
+{ .mlx
+ setf.exp FR_8 = GR_ExpOf8
+ movl GR_10 = 0x4024000000000000
+};;
+{ .mfi
+ ld8 GR_ad_Data = [GR_ad_Data]
+ fcmp.lt.s1 p14,p15 = f8,f0
+ tbit.z p12,p13 = GR_Sign_Exp,0x10 // p13 if x >= 2
+}
+{ .mlx
+ and GR_Bit2 = 4,GR_Sign_Exp
+ movl GR_12 = 0x4028000000000000
+};;
+{ .mfi
+ setf.d FR_10 = GR_10
+ fma.s1 FR_r02 = f8,f1,f0
+ extr.u GR_Tbl_Offs = GR_Sig,58,6
+}
+{ .mfi
+(p12) mov GR_Addr_Mask1 = r0
+ fma.s1 FR_NormX = f8,f1,f0
+ cmp.ne p8,p0 = GR_Bit2,r0
+};;
+{ .mfi
+(p8) shladd GR_Tbl_Offs = GR_Tbl_Offs,4,r0
+ fclass.m p10,p0 = f8,0x1E7 // Test x for NaTVal, NaN, +/-0, +/-INF
+ tbit.nz p11,p0 = GR_Sign_Exp,1
+}
+{ .mlx
+ add GR_Addr_Mask2 = GR_Addr_Mask1,GR_Addr_Mask1
+ movl GR_14 = 0x402C000000000000
+};;
+.pred.rel "mutex",p14,p15
+{ .mfi
+ setf.d FR_12 = GR_12
+(p14) fma.s1 FR_1m2X = f1,f1,FR_1m2X // RB=1-2|x|
+ tbit.nz p8,p9 = GR_Sign_Exp,0
+}
+{ .mfi
+ ldfpd FR_OvfBound,FR_Xmin = [GR_ad_Data],16
+(p15) fms.s1 FR_1m2X = f1,f1,FR_1m2X // RB=1-2|x|
+(p11) shladd GR_Tbl_Offs = GR_Tbl_Offs,2,r0
+};;
+.pred.rel "mutex",p9,p8
+{ .mfi
+ setf.d FR_14 = GR_14
+ fma.s1 FR_4 = FR_2,FR_2,f0
+(p8) and GR_Tbl_Offs = GR_Tbl_Offs, GR_Addr_Mask1
+}
+{ .mfi
+ setf.exp FR_05 = GR_ExpOf05
+ fma.s1 FR_6 = FR_2,FR_2,FR_2
+(p9) and GR_Tbl_Offs = GR_Tbl_Offs, GR_Addr_Mask2
+};;
+.pred.rel "mutex",p9,p8
+{ .mfi
+(p8) shladd GR_ad_Co = GR_Tbl_Offs,1,GR_ad_Data
+ fcvt.xf FR_Xt = FR_iXt // [x]
+(p15) tbit.z.unc p11,p0 = GR_Sign_Exp,0x10 // p11 if 0 < x < 2
+}
+{ .mfi
+(p9) add GR_ad_Co = GR_ad_Data,GR_Tbl_Offs
+ fma.s1 FR_5 = FR_2,FR_2,f1
+(p15) cmp.lt.unc p7,p6 = GR_ExpOf05,GR_Sign_Exp // p7 if 0 < x < 1
+};;
+{ .mfi
+ add GR_ad_Ce = 16,GR_ad_Co
+(p11) frcpa.s1 FR_Rcp0,p0 = f1,f8
+ sub GR_Tbl_Offs = GR_ad_Co,GR_ad_Data
+}
+{ .mfb
+ ldfe FR_C01 = [GR_ad_Co],32
+(p7) fms.s1 FR_r02 = FR_r02,f1,f1
+ // jump if x is NaTVal, NaN, +/-0, +/-INF
+(p10) br.cond.spnt tgamma_spec
+};;
+.pred.rel "mutex",p14,p15
+{ .mfi
+ ldfe FR_C11 = [GR_ad_Ce],32
+(p14) fms.s1 FR_X2pX = f8,f8,f8 // RA=x^2+|x|
+ shr GR_Tbl_Ind = GR_Tbl_Offs,8
+}
+{ .mfb
+ ldfe FR_C21 = [GR_ad_Co],32
+(p15) fma.s1 FR_X2pX = f8,f8,f8 // RA=x^2+x
+ // jump if 0 < x < 2
+(p11) br.cond.spnt tgamma_from_0_to_2
+};;
+{ .mfi
+ ldfe FR_C31 = [GR_ad_Ce],32
+ fma.s1 FR_Rq2 = FR_2,f1,FR_1m2X // 2 + B
+ cmp.ltu p7,p0=0xB,GR_Tbl_Ind
+}
+{ .mfb
+ ldfe FR_C41 = [GR_ad_Co],32
+ fma.s1 FR_Rq3 = FR_2,FR_2,FR_1m2X // 4 + B
+ // jump if GR_Tbl_Ind > 11, i.e |x| is more than 192
+(p7) br.cond.spnt tgamma_spec_res
+};;
+{ .mfi
+ ldfe FR_C51 = [GR_ad_Ce],32
+ fma.s1 FR_Rq4 = FR_6,f1,FR_1m2X // 6 + B
+ shr GR_Tbl_Offs = GR_Tbl_Offs,1
+}
+{ .mfi
+ ldfe FR_C61 = [GR_ad_Co],32
+ fma.s1 FR_Rq5 = FR_4,FR_2,FR_1m2X // 8 + B
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_C71 = [GR_ad_Ce],32
+(p14) fms.s1 FR_r = FR_Xt,f1,f8 // r = |x| - [|x|]
+ shr GR_Tbl_16xInd = GR_Tbl_Offs,3
+}
+{ .mfi
+ ldfe FR_C81 = [GR_ad_Co],32
+(p15) fms.s1 FR_r = f8,f1,FR_Xt // r = x - [x]
+ add GR_ad_Data = 0xC00,GR_ad_Data
+};;
+{ .mfi
+ ldfe FR_C91 = [GR_ad_Ce],32
+ fma.s1 FR_Rq6 = FR_5,FR_2,FR_1m2X // 10 + B
+(p14) mov GR_0x30033 = 0x30033
+}
+{ .mfi
+ ldfe FR_CA1 = [GR_ad_Co],32
+ fma.s1 FR_Rq7 = FR_6,FR_2,FR_1m2X // 12 + B
+ sub GR_Tbl_Offs = GR_Tbl_Offs,GR_Tbl_16xInd
+};;
+{ .mfi
+ ldfe FR_C00 = [GR_ad_Ce],32
+ fma.s1 FR_Rq1 = FR_Rq1,FR_2,FR_X2pX // (x-1)*(x-2)
+(p13) cmp.eq.unc p8,p0 = r0,GR_Tbl_16xInd // index is 0 i.e. arg from [2;16)
+}
+{ .mfi
+ ldfe FR_C10 = [GR_ad_Co],32
+(p14) fms.s1 FR_AbsX = f0,f0,FR_NormX // absolute value of argument
+ add GR_ad_Co7 = GR_ad_Data,GR_Tbl_Offs
+};;
+{ .mfi
+ ldfe FR_C20 = [GR_ad_Ce],32
+ fma.s1 FR_Rq2 = FR_Rq2,FR_4,FR_X2pX // (x-3)*(x-4)
+ add GR_ad_Ce7 = 16,GR_ad_Co7
+}
+{ .mfi
+ ldfe FR_C30 = [GR_ad_Co],32
+ fma.s1 FR_Rq3 = FR_Rq3,FR_6,FR_X2pX // (x-5)*(x-6)
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_C40 = [GR_ad_Ce],32
+ fma.s1 FR_Rq4 = FR_Rq4,FR_8,FR_X2pX // (x-7)*(x-8)
+(p14) cmp.leu.unc p7,p0 = GR_0x30033,GR_Sign_Exp
+}
+{ .mfb
+ ldfe FR_C50 = [GR_ad_Co7],32
+ fma.s1 FR_Rq5 = FR_Rq5,FR_10,FR_X2pX // (x-9)*(x-10)
+ // jump if x is less or equal to -2^52, i.e. x is big negative integer
+(p7) br.cond.spnt tgamma_singularity
+};;
+{ .mfi
+ ldfe FR_C60 = [GR_ad_Ce7],32
+ fma.s1 FR_C01 = FR_C01,f1,FR_r
+ add GR_ad_Ce = 0x560,GR_ad_Data
+}
+{ .mfi
+ ldfe FR_C70 = [GR_ad_Co7],32
+ fma.s1 FR_rs = f0,f0,FR_r // reduced arg for sin(pi*x)
+ add GR_ad_Co = 0x550,GR_ad_Data
+};;
+{ .mfi
+ ldfe FR_C80 = [GR_ad_Ce7],32
+ fma.s1 FR_C11 = FR_C11,f1,FR_r
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_C90 = [GR_ad_Co7],32
+ fma.s1 FR_C21 = FR_C21,f1,FR_r
+ nop.i 0
+};;
+.pred.rel "mutex",p12,p13
+{ .mfi
+(p13) getf.sig GR_iSig = FR_iXt
+ fcmp.lt.s1 p11,p0 = FR_05,FR_r
+ mov GR_185 = 185
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Rq6 = FR_Rq6,FR_12,FR_X2pX // (x-11)*(x-12)
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_CA0 = [GR_ad_Ce7],32
+ fma.s1 FR_C31 = FR_C31,f1,FR_r
+(p12) mov GR_iSig = 0
+}
+{ .mfi
+ ldfe FR_An = [GR_ad_Co7],0x80
+ fma.s1 FR_C41 = FR_C41,f1,FR_r
+ nop.i 0
+};;
+{ .mfi
+(p14) getf.sig GR_Sig = FR_r
+ fma.s1 FR_C51 = FR_C51,f1,FR_r
+(p14) sub GR_iSig = r0,GR_iSig
+}
+{ .mfi
+ ldfe FR_S21 = [GR_ad_Co],32
+ fma.s1 FR_C61 = FR_C61,f1,FR_r
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_S19 = [GR_ad_Ce],32
+ fma.s1 FR_C71 = FR_C71,f1,FR_r
+ and GR_SigRqLin = 0xF,GR_iSig
+}
+{ .mfi
+ ldfe FR_S17 = [GR_ad_Co],32
+ fma.s1 FR_C81 = FR_C81,f1,FR_r
+ mov GR_2 = 2
+};;
+{ .mfi
+(p14) ldfe FR_InvAn = [GR_ad_Co7]
+ fma.s1 FR_C91 = FR_C91,f1,FR_r
+ // if significand of r is 0 tnan argument is negative integer
+(p14) cmp.eq.unc p12,p0 = r0,GR_Sig
+}
+{ .mfb
+(p8) sub GR_SigRqLin = GR_SigRqLin,GR_2 // subtract 2 if 2 <= x < 16
+ fma.s1 FR_CA1 = FR_CA1,f1,FR_r
+ // jump if x is negative integer such that -2^52 < x < -185
+(p12) br.cond.spnt tgamma_singularity
+};;
+{ .mfi
+ setf.sig FR_Xt = GR_SigRqLin
+(p11) fms.s1 FR_rs = f1,f1,FR_r
+(p14) cmp.ltu.unc p7,p0 = GR_185,GR_iSig
+}
+{ .mfb
+ ldfe FR_S15 = [GR_ad_Ce],32
+ fma.s1 FR_Rq7 = FR_Rq7,FR_14,FR_X2pX // (x-13)*(x-14)
+ // jump if x is noninteger such that -2^52 < x < -185
+(p7) br.cond.spnt tgamma_underflow
+};;
+{ .mfi
+ ldfe FR_S13 = [GR_ad_Co],48
+ fma.s1 FR_C01 = FR_C01,FR_r,FR_C00
+ and GR_Sig2 = 0xE,GR_SigRqLin
+}
+{ .mfi
+ ldfe FR_S11 = [GR_ad_Ce],48
+ fma.s1 FR_C11 = FR_C11,FR_r,FR_C10
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_S9 = [GR_ad_Co],32
+ fma.s1 FR_C21 = FR_C21,FR_r,FR_C20
+ // should we mul by polynomial of recursion?
+ cmp.eq p13,p12 = r0,GR_SigRqLin
+}
+{ .mfi
+ ldfe FR_S7 = [GR_ad_Ce],32
+ fma.s1 FR_C31 = FR_C31,FR_r,FR_C30
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_S5 = [GR_ad_Co],32
+ fma.s1 FR_C41 = FR_C41,FR_r,FR_C40
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_S3 = [GR_ad_Ce],32
+ fma.s1 FR_C51 = FR_C51,FR_r,FR_C50
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C61 = FR_C61,FR_r,FR_C60
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C71 = FR_C71,FR_r,FR_C70
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C81 = FR_C81,FR_r,FR_C80
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C91 = FR_C91,FR_r,FR_C90
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_CA1 = FR_CA1,FR_r,FR_CA0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C01 = FR_C01,FR_C11,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C21 = FR_C21,FR_C31,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rs2 = FR_rs,FR_rs,f0
+(p12) cmp.lt.unc p7,p0 = 2,GR_Sig2 // should mul by FR_Rq2?
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C41 = FR_C41,FR_C51,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s1 FR_Rq1 = FR_Rq1,FR_Rq2,f0
+(p12) cmp.lt.unc p9,p0 = 6,GR_Sig2 // should mul by FR_Rq4?
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C61 = FR_C61,FR_C71,f0
+(p15) cmp.eq p11,p0 = r0,r0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 FR_Rq3 = FR_Rq3,FR_Rq4,f0
+(p12) cmp.lt.unc p8,p0 = 10,GR_Sig2 // should mul by FR_Rq6?
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C81 = FR_C81,FR_C91,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.s1 FR_Rq5 = FR_Rq5,FR_Rq6,f0
+(p14) cmp.ltu p0,p11 = 0x9,GR_Tbl_Ind
+};;
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_RqLin = FR_Xt
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fma.s1 FR_CA1 = FR_CA1,FR_An,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S21 = FR_S21,FR_rs2,FR_S19
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S17 = FR_S17,FR_rs2,FR_S15
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C01 = FR_C01,FR_C21,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rs4 = FR_rs2,FR_rs2,f0
+(p12) cmp.lt.unc p8,p0 = 4,GR_Sig2 // should mul by FR_Rq3?
+};;
+{ .mfi
+ nop.m 0
+(p8) fma.s1 FR_Rq1 = FR_Rq1,FR_Rq3,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S13 = FR_S13,FR_rs2,FR_S11
+(p12) cmp.lt.unc p9,p0 = 12,GR_Sig2 // should mul by FR_Rq7?
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C41 = FR_C41,FR_C61,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 FR_Rq5 = FR_Rq5,FR_Rq7,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C81 = FR_C81,FR_CA1,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S9 = FR_S9,FR_rs2,FR_S7
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S5 = FR_S5,FR_rs2,FR_S3
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rs3 = FR_rs2,FR_rs,f0
+(p12) tbit.nz.unc p6,p0 = GR_SigRqLin,0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rs8 = FR_rs4,FR_rs4,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S21 = FR_S21,FR_rs4,FR_S17
+ mov GR_ExpOf1 = 0x2FFFF
+}
+{ .mfi
+ nop.m 0
+(p6) fms.s1 FR_RqLin = FR_AbsX,f1,FR_RqLin
+(p12) cmp.lt.unc p8,p0 = 8,GR_Sig2 // should mul by FR_Rq5?
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C01 = FR_C01,FR_C41,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.s1 FR_Rq1 = FR_Rq1,FR_Rq5,f0
+(p14) cmp.gtu.unc p7,p0 = GR_Sign_Exp,GR_ExpOf1
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S13 = FR_S13,FR_rs4,FR_S9
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s1 FR_C81 = FR_C81,FR_AbsX,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_AbsXp1 = f1,f1,FR_AbsX // |x|+1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fcmp.lt.unc.s1 p0,p10 = FR_AbsX,FR_OvfBound // x >= overflow_boundary
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_rs7 = FR_rs4,FR_rs3,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S5 = FR_S5,FR_rs3,FR_rs
+ nop.i 0
+};;
+{ .mib
+(p14) cmp.lt p13,p0 = r0,r0 // set p13 to 0 if x < 0
+(p12) cmp.eq.unc p8,p9 = 1,GR_SigRqLin
+(p10) br.cond.spnt tgamma_spec_res
+};;
+{ .mfi
+ getf.sig GR_Sig = FR_iXt
+(p6) fma.s1 FR_Rq1 = FR_Rq1,FR_RqLin,f0
+ // should we mul by polynomial of recursion?
+(p15) cmp.eq.unc p0,p11 = r0,GR_SigRqLin
+}
+{ .mfb
+ nop.m 0
+ fma.s1 FR_GAMMA = FR_C01,FR_C81,f0
+(p11) br.cond.spnt tgamma_positives
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S21 = FR_S21,FR_rs8,FR_S13
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p13) fma.d.s0 f8 = FR_C01,FR_C81,f0
+(p13) br.ret.spnt b0
+};;
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 0
+(p9) fma.s1 FR_GAMMA = FR_GAMMA,FR_Rq1,f0
+ tbit.z p6,p7 = GR_Sig,0 // p6 if sin<0, p7 if sin>0
+}
+{ .mfi
+ nop.m 0
+(p8) fma.s1 FR_GAMMA = FR_GAMMA,FR_RqLin,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_S21 = FR_S21,FR_rs7,FR_S5
+ nop.i 0
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fnma.s1 FR_GAMMA = FR_GAMMA,FR_S21,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s1 FR_GAMMA = FR_GAMMA,FR_S21,f0
+ mov GR_Sig2 = 1
+};;
+{ .mfi
+ nop.m 0
+ frcpa.s1 FR_Rcp0,p0 = f1,FR_GAMMA
+ cmp.ltu p13,p0 = GR_Sign_Exp,GR_ExpOf1
+};;
+// NR method: ineration #1
+{ .mfi
+(p13) getf.exp GR_Sign_Exp = FR_AbsX
+ fnma.s1 FR_Rcp1 = FR_Rcp0,FR_GAMMA,f1 // t = 1 - r0*x
+(p13) shl GR_Sig2 = GR_Sig2,63
+};;
+{ .mfi
+(p13) getf.sig GR_Sig = FR_AbsX
+ nop.f 0
+(p13) mov GR_NzOvfBound = 0xFBFF
+};;
+{ .mfi
+(p13) cmp.ltu.unc p8,p0 = GR_Sign_Exp,GR_NzOvfBound // p8 <- overflow
+ nop.f 0
+(p13) cmp.eq.unc p9,p0 = GR_Sign_Exp,GR_NzOvfBound
+};;
+{ .mfb
+ nop.m 0
+(p13) fma.d.s0 FR_X = f1,f1,f8 // set deno & inexact flags
+(p8) br.cond.spnt tgamma_ovf_near_0 //tgamma_neg_overflow
+};;
+{ .mib
+ nop.m 0
+(p9) cmp.eq.unc p8,p0 = GR_Sig,GR_Sig2
+(p8) br.cond.spnt tgamma_ovf_near_0_boundary //tgamma_neg_overflow
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Rcp1 = FR_Rcp0,FR_Rcp1,FR_Rcp0
+ nop.i 0
+};;
+// NR method: ineration #2
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_Rcp2 = FR_Rcp1,FR_GAMMA,f1 // t = 1 - r1*x
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_Rcp2 = FR_Rcp1,FR_Rcp2,FR_Rcp1
+ nop.i 0
+};;
+// NR method: ineration #3
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_Rcp3 = FR_Rcp2,FR_GAMMA,f1 // t = 1 - r2*x
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_Rcp2 = FR_Rcp2,FR_AbsXp1,f0
+(p14) cmp.ltu p10,p11 = 0x9,GR_Tbl_Ind
+};;
+.pred.rel "mutex",p10,p11
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_GAMMA = FR_Rcp2,FR_Rcp3,FR_Rcp2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fma.d.s0 f8 = FR_Rcp2,FR_Rcp3,FR_Rcp2
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+(p10) fma.d.s0 f8 = FR_GAMMA,FR_InvAn,f0
+ br.ret.sptk b0
+};;
+
+
+// here if x >= 3
+//--------------------------------------------------------------------
+.align 32
+tgamma_positives:
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 0
+(p9) fma.d.s0 f8 = FR_GAMMA,FR_Rq1,f0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p8) fma.d.s0 f8 = FR_GAMMA,FR_RqLin,f0
+ br.ret.sptk b0
+};;
+
+// here if 0 < x < 1
+//--------------------------------------------------------------------
+.align 32
+tgamma_from_0_to_2:
+{ .mfi
+ getf.exp GR_Sign_Exp = FR_r02
+ fms.s1 FR_r = FR_r02,f1,FR_Xmin
+ mov GR_ExpOf025 = 0xFFFD
+}
+{ .mfi
+ add GR_ad_Co = 0x1200,GR_ad_Data
+(p6) fnma.s1 FR_Rcp1 = FR_Rcp0,FR_NormX,f1 // t = 1 - r0*x
+(p6) mov GR_Sig2 = 1
+};;
+{ .mfi
+(p6) getf.sig GR_Sig = FR_NormX
+ nop.f 0
+(p6) shl GR_Sig2 = GR_Sig2,63
+}
+{ .mfi
+ add GR_ad_Ce = 0x1210,GR_ad_Data
+ nop.f 0
+(p6) mov GR_NzOvfBound = 0xFBFF
+};;
+{ .mfi
+ cmp.eq p8,p0 = GR_Sign_Exp,GR_ExpOf05 // r02 >= 1/2
+ nop.f 0
+ cmp.eq p9,p10 = GR_Sign_Exp,GR_ExpOf025 // r02 >= 1/4
+}
+{ .mfi
+(p6) cmp.ltu.unc p11,p0 = GR_Sign_Exp,GR_NzOvfBound // p11 <- overflow
+ nop.f 0
+(p6) cmp.eq.unc p12,p0 = GR_Sign_Exp,GR_NzOvfBound
+};;
+.pred.rel "mutex",p8,p9
+{ .mfi
+(p8) add GR_ad_Co = 0x200,GR_ad_Co
+(p6) fma.d.s0 FR_X = f1,f1,f8 // set deno & inexact flags
+(p9) add GR_ad_Co = 0x100,GR_ad_Co
+}
+{ .mib
+(p8) add GR_ad_Ce = 0x200,GR_ad_Ce
+(p9) add GR_ad_Ce = 0x100,GR_ad_Ce
+(p11) br.cond.spnt tgamma_ovf_near_0 //tgamma_spec_res
+};;
+{ .mfi
+ ldfe FR_A15 = [GR_ad_Co],32
+ nop.f 0
+(p12) cmp.eq.unc p13,p0 = GR_Sig,GR_Sig2
+}
+{ .mfb
+ ldfe FR_A14 = [GR_ad_Ce],32
+ nop.f 0
+(p13) br.cond.spnt tgamma_ovf_near_0_boundary //tgamma_spec_res
+};;
+{ .mfi
+ ldfe FR_A13 = [GR_ad_Co],32
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A12 = [GR_ad_Ce],32
+ nop.f 0
+ nop.i 0
+};;
+.pred.rel "mutex",p9,p10
+{ .mfi
+ ldfe FR_A11 = [GR_ad_Co],32
+(p10) fma.s1 FR_r2 = FR_r02,FR_r02,f0
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A10 = [GR_ad_Ce],32
+(p9) fma.s1 FR_r2 = FR_r,FR_r,f0
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_A9 = [GR_ad_Co],32
+(p6) fma.s1 FR_Rcp1 = FR_Rcp0,FR_Rcp1,FR_Rcp0
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A8 = [GR_ad_Ce],32
+(p10) fma.s1 FR_r = f0,f0,FR_r02
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_A7 = [GR_ad_Co],32
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A6 = [GR_ad_Ce],32
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_A5 = [GR_ad_Co],32
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A4 = [GR_ad_Ce],32
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_A3 = [GR_ad_Co],32
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A2 = [GR_ad_Ce],32
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ ldfe FR_A1 = [GR_ad_Co],32
+ fma.s1 FR_r4 = FR_r2,FR_r2,f0
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_A0 = [GR_ad_Ce],32
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p6) fnma.s1 FR_Rcp2 = FR_Rcp1,FR_NormX,f1 // t = 1 - r1*x
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A15 = FR_A15,FR_r,FR_A14
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A11 = FR_A11,FR_r,FR_A10
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r8 = FR_r4,FR_r4,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p6) fma.s1 FR_Rcp2 = FR_Rcp1,FR_Rcp2,FR_Rcp1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A7 = FR_A7,FR_r,FR_A6
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A3 = FR_A3,FR_r,FR_A2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A15 = FR_A15,FR_r,FR_A13
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A11 = FR_A11,FR_r,FR_A9
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p6) fnma.s1 FR_Rcp3 = FR_Rcp2,FR_NormX,f1 // t = 1 - r1*x
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A7 = FR_A7,FR_r,FR_A5
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A3 = FR_A3,FR_r,FR_A1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A15 = FR_A15,FR_r,FR_A12
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A11 = FR_A11,FR_r,FR_A8
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p6) fma.s1 FR_Rcp3 = FR_Rcp2,FR_Rcp3,FR_Rcp2
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A7 = FR_A7,FR_r,FR_A4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A3 = FR_A3,FR_r,FR_A0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A15 = FR_A15,FR_r4,FR_A11
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A7 = FR_A7,FR_r4,FR_A3
+ nop.i 0
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fma.s1 FR_A15 = FR_A15,FR_r8,FR_A7
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.d.s0 f8 = FR_A15,FR_r8,FR_A7
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+(p6) fma.d.s0 f8 = FR_A15,FR_Rcp3,f0
+ br.ret.sptk b0
+};;
+
+// overflow
+//--------------------------------------------------------------------
+.align 32
+tgamma_ovf_near_0_boundary:
+.pred.rel "mutex",p14,p15
+{ .mfi
+ mov GR_fpsr = ar.fpsr
+ nop.f 0
+(p15) mov r8 = 0x7ff
+}
+{ .mfi
+ nop.m 0
+ nop.f 0
+(p14) mov r8 = 0xfff
+};;
+{ .mfi
+ nop.m 0
+ nop.f 0
+ shl r8 = r8,52
+};;
+{ .mfi
+ sub r8 = r8,r0,1
+ nop.f 0
+ extr.u GR_fpsr = GR_fpsr,10,2 // rounding mode
+};;
+.pred.rel "mutex",p14,p15
+{ .mfi
+ // set p8 to 0 in case of overflow and to 1 otherwise
+ // for negative arg:
+ // no overflow if rounding mode either Z or +Inf, i.e.
+ // GR_fpsr > 1
+(p14) cmp.lt p8,p0 = 1,GR_fpsr
+ nop.f 0
+ // for positive arg:
+ // no overflow if rounding mode either Z or -Inf, i.e.
+ // (GR_fpsr & 1) == 0
+(p15) tbit.z p0,p8 = GR_fpsr,0
+};;
+{ .mib
+(p8) setf.d f8 = r8 // set result to 0x7fefffffffffffff without
+ // OVERFLOW flag raising
+ nop.i 0
+(p8) br.ret.sptk b0
+};;
+.align 32
+tgamma_ovf_near_0:
+{ .mfi
+ mov r8 = 0x1FFFE
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ setf.exp f9 = r8
+ fmerge.s FR_X = f8,f8
+ mov GR_TAG = 258 // overflow
+};;
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p15) fma.d.s0 f8 = f9,f9,f0 // Set I,O and +INF result
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p14) fnma.d.s0 f8 = f9,f9,f0 // Set I,O and -INF result
+ br.cond.sptk tgamma_libm_err
+};;
+// overflow or absolute value of x is too big
+//--------------------------------------------------------------------
+.align 32
+tgamma_spec_res:
+{ .mfi
+ mov GR_0x30033 = 0x30033
+(p14) fcmp.eq.unc.s1 p10,p11 = f8,FR_Xt
+(p15) mov r8 = 0x1FFFE
+};;
+{ .mfi
+(p15) setf.exp f9 = r8
+ nop.f 0
+ nop.i 0
+};;
+{ .mfb
+(p11) cmp.ltu.unc p7,p8 = GR_0x30033,GR_Sign_Exp
+ nop.f 0
+(p10) br.cond.spnt tgamma_singularity
+};;
+.pred.rel "mutex",p7,p8
+{ .mbb
+ nop.m 0
+(p7) br.cond.spnt tgamma_singularity
+(p8) br.cond.spnt tgamma_underflow
+};;
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8,f8
+ mov GR_TAG = 258 // overflow
+}
+{ .mfb
+ nop.m 0
+(p15) fma.d.s0 f8 = f9,f9,f0 // Set I,O and +INF result
+ br.cond.sptk tgamma_libm_err
+};;
+
+// x is negative integer or +/-0
+//--------------------------------------------------------------------
+.align 32
+tgamma_singularity:
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8,f8
+ mov GR_TAG = 259 // negative
+}
+{ .mfb
+ nop.m 0
+ frcpa.s0 f8,p0 = f0,f0
+ br.cond.sptk tgamma_libm_err
+};;
+// x is negative noninteger with big absolute value
+//--------------------------------------------------------------------
+.align 32
+tgamma_underflow:
+{ .mmi
+ getf.sig GR_Sig = FR_iXt
+ mov r11 = 0x00001
+ nop.i 0
+};;
+{ .mfi
+ setf.exp f9 = r11
+ nop.f 0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ nop.f 0
+ tbit.z p6,p7 = GR_Sig,0
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fms.d.s0 f8 = f9,f9,f9
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.d.s0 f8 = f9,f9,f9
+ br.ret.sptk b0
+};;
+
+// x for natval, nan, +/-inf or +/-0
+//--------------------------------------------------------------------
+.align 32
+tgamma_spec:
+{ .mfi
+ nop.m 0
+ fclass.m p6,p0 = f8,0x1E1 // Test x for natval, nan, +inf
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fclass.m p7,p8 = f8,0x7 // +/-0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p6) fma.d.s0 f8 = f8,f1,f8
+(p6) br.ret.spnt b0
+};;
+.pred.rel "mutex",p7,p8
+{ .mfi
+(p7) mov GR_TAG = 259 // negative
+(p7) frcpa.s0 f8,p0 = f1,f8
+ nop.i 0
+}
+{ .mib
+ nop.m 0
+ nop.i 0
+(p8) br.cond.spnt tgamma_singularity
+};;
+
+.align 32
+tgamma_libm_err:
+{ .mfi
+ alloc r32 = ar.pfs,1,4,4,0
+ nop.f 0
+ mov GR_Parameter_TAG = GR_TAG
+};;
+
+GLOBAL_LIBM_END(tgamma)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfd [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfd [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfd [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfd f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/w_tgammaf.S b/libc/sysdeps/ia64/fpu/w_tgammaf.S
new file mode 100644
index 000000000..dda0d0fe9
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_tgammaf.S
@@ -0,0 +1,1331 @@
+.file "tgammaf.s"
+
+
+// Copyright (c) 2001 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2001 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING,BUT NOT
+// LIMITED TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code,and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+//*********************************************************************
+//
+// History:
+// 11/30/01 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align
+// 04/04/03 Changed error codes for overflow and negative integers
+// 04/10/03 Changed code for overflow near zero handling
+// 12/16/03 Fixed parameter passing to/from error handling routine
+// 03/31/05 Reformatted delimiters between data tables
+//
+//*********************************************************************
+//
+//*********************************************************************
+//
+// Function: tgammaf(x) computes the principle value of the GAMMA
+// function of x.
+//
+//*********************************************************************
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8-f15
+// f33-f75
+//
+// General Purpose Registers:
+// r8-r11
+// r14-r29
+// r32-r36
+// r37-r40 (Used to pass arguments to error handling routine)
+//
+// Predicate Registers: p6-p15
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// tgammaf(+inf) = +inf
+// tgammaf(-inf) = QNaN
+// tgammaf(+/-0) = +/-inf
+// tgammaf(x<0, x - integer) = QNaN
+// tgammaf(SNaN) = QNaN
+// tgammaf(QNaN) = QNaN
+//
+//*********************************************************************
+//
+// Overview
+//
+// The method consists of three cases.
+//
+// If 2 <= x < OVERFLOW_BOUNDARY use case tgamma_regular;
+// else if 0 < x < 2 use case tgamma_from_0_to_2;
+// else if -(i+1) < x < -i, i = 0...43 use case tgamma_negatives;
+//
+// Case 2 <= x < OVERFLOW_BOUNDARY
+// -------------------------------
+// Here we use algorithm based on the recursive formula
+// GAMMA(x+1) = x*GAMMA(x). For that we subdivide interval
+// [2; OVERFLOW_BOUNDARY] into intervals [8*n; 8*(n+1)] and
+// approximate GAMMA(x) by polynomial of 22th degree on each
+// [8*n; 8*n+1], recursive formula is used to expand GAMMA(x)
+// to [8*n; 8*n+1]. In other words we need to find n, i and r
+// such that x = 8 * n + i + r where n and i are integer numbers
+// and r is fractional part of x. So GAMMA(x) = GAMMA(8*n+i+r) =
+// = (x-1)*(x-2)*...*(x-i)*GAMMA(x-i) =
+// = (x-1)*(x-2)*...*(x-i)*GAMMA(8*n+r) ~
+// ~ (x-1)*(x-2)*...*(x-i)*P12n(r).
+//
+// Step 1: Reduction
+// -----------------
+// N = [x] with truncate
+// r = x - N, note 0 <= r < 1
+//
+// n = N & ~0xF - index of table that contains coefficient of
+// polynomial approximation
+// i = N & 0xF - is used in recursive formula
+//
+//
+// Step 2: Approximation
+// ---------------------
+// We use factorized minimax approximation polynomials
+// P12n(r) = A12*(r^2+C01(n)*r+C00(n))*
+// *(r^2+C11(n)*r+C10(n))*...*(r^2+C51(n)*r+C50(n))
+//
+// Step 3: Recursion
+// -----------------
+// In case when i > 0 we need to multiply P12n(r) by product
+// R(i,x)=(x-1)*(x-2)*...*(x-i). To reduce number of fp-instructions
+// we can calculate R as follow:
+// R(i,x) = ((x-1)*(x-2))*((x-3)*(x-4))*...*((x-(i-1))*(x-i)) if i is
+// even or R = ((x-1)*(x-2))*((x-3)*(x-4))*...*((x-(i-2))*(x-(i-1)))*
+// *(i-1) if i is odd. In both cases we need to calculate
+// R2(i,x) = (x^2-3*x+2)*(x^2-7*x+12)*...*(x^2+x+2*j*(2*j-1)) =
+// = ((x^2-x)+2*(1-x))*((x^2-x)+6*(2-x))*...*((x^2-x)+2*(2*j-1)*(j-x)) =
+// = (RA+2*RB)*(RA+6*(1-RB))*...*(RA+2*(2*j-1)*(j-1+RB))
+// where j = 1..[i/2], RA = x^2-x, RB = 1-x.
+//
+// Step 4: Reconstruction
+// ----------------------
+// Reconstruction is just simple multiplication i.e.
+// GAMMA(x) = P12n(r)*R(i,x)
+//
+// Case 0 < x < 2
+// --------------
+// To calculate GAMMA(x) on this interval we do following
+// if 1.0 <= x < 1.25 than GAMMA(x) = P7(x-1)
+// if 1.25 <= x < 1.5 than GAMMA(x) = P7(x-x_min) where
+// x_min is point of local minimum on [1; 2] interval.
+// if 1.5 <= x < 1.75 than GAMMA(x) = P7(x-1.5)
+// if 1.75 <= x < 2.0 than GAMMA(x) = P7(x-1.5)
+// and
+// if 0 < x < 1 than GAMMA(x) = GAMMA(x+1)/x
+//
+// Case -(i+1) < x < -i, i = 0...43
+// ----------------------------------
+// Here we use the fact that GAMMA(-x) = PI/(x*GAMMA(x)*sin(PI*x)) and
+// so we need to calculate GAMMA(x), sin(PI*x)/PI. Calculation of
+// GAMMA(x) is described above.
+//
+// Step 1: Reduction
+// -----------------
+// Note that period of sin(PI*x) is 2 and range reduction for
+// sin(PI*x) is like to range reduction for GAMMA(x)
+// i.e rs = x - round(x) and |rs| <= 0.5.
+//
+// Step 2: Approximation
+// ---------------------
+// To approximate sin(PI*x)/PI = sin(PI*(2*n+rs))/PI =
+// = (-1)^n*sin(PI*rs)/PI Taylor series is used.
+// sin(PI*rs)/PI ~ S17(rs).
+//
+// Step 3: Division
+// ----------------
+// To calculate 1/x and 1/(GAMMA(x)*S12(rs)) we use frcpa
+// instruction with following Newton-Raphson interations.
+//
+//
+//*********************************************************************
+
+GR_ad_Data = r8
+GR_TAG = r8
+GR_SignExp = r9
+GR_Sig = r10
+GR_ArgNz = r10
+GR_RqDeg = r11
+
+GR_NanBound = r14
+GR_ExpOf025 = r15
+GR_ExpOf05 = r16
+GR_ad_Co = r17
+GR_ad_Ce = r18
+GR_TblOffs = r19
+GR_Arg = r20
+GR_Exp2Ind = r21
+GR_TblOffsMask = r21
+GR_Offs = r22
+GR_OvfNzBound = r23
+GR_ZeroResBound = r24
+GR_ad_SinO = r25
+GR_ad_SinE = r26
+GR_Correction = r27
+GR_Tbl12Offs = r28
+GR_NzBound = r28
+GR_ExpOf1 = r29
+GR_fpsr = r29
+
+GR_SAVE_B0 = r33
+GR_SAVE_PFS = r34
+GR_SAVE_GP = r35
+GR_SAVE_SP = r36
+
+GR_Parameter_X = r37
+GR_Parameter_Y = r38
+GR_Parameter_RESULT = r39
+GR_Parameter_TAG = r40
+
+
+FR_X = f10
+FR_Y = f1
+FR_RESULT = f8
+
+FR_iXt = f11
+FR_Xt = f12
+FR_r = f13
+FR_r2 = f14
+FR_r4 = f15
+
+FR_C01 = f33
+FR_A7 = f33
+FR_C11 = f34
+FR_A6 = f34
+FR_C21 = f35
+FR_A5 = f35
+FR_C31 = f36
+FR_A4 = f36
+FR_C41 = f37
+FR_A3 = f37
+FR_C51 = f38
+FR_A2 = f38
+
+FR_C00 = f39
+FR_A1 = f39
+FR_C10 = f40
+FR_A0 = f40
+FR_C20 = f41
+FR_C30 = f42
+FR_C40 = f43
+FR_C50 = f44
+FR_An = f45
+FR_OvfBound = f46
+FR_InvAn = f47
+
+FR_Multplr = f48
+FR_NormX = f49
+FR_X2mX = f50
+FR_1mX = f51
+FR_Rq0 = f51
+FR_Rq1 = f52
+FR_Rq2 = f53
+FR_Rq3 = f54
+
+FR_Rcp0 = f55
+FR_Rcp1 = f56
+FR_Rcp2 = f57
+
+FR_InvNormX1 = f58
+FR_InvNormX2 = f59
+
+FR_rs = f60
+FR_rs2 = f61
+
+FR_LocalMin = f62
+FR_10 = f63
+
+FR_05 = f64
+
+FR_S32 = f65
+FR_S31 = f66
+FR_S01 = f67
+FR_S11 = f68
+FR_S21 = f69
+FR_S00 = f70
+FR_S10 = f71
+FR_S20 = f72
+
+FR_GAMMA = f73
+FR_2 = f74
+FR_6 = f75
+
+
+
+
+// Data tables
+//==============================================================
+RODATA
+.align 16
+LOCAL_OBJECT_START(tgammaf_data)
+data8 0x3FDD8B618D5AF8FE // local minimum (0.461632144968362356785)
+data8 0x4024000000000000 // 10.0
+data8 0x3E90FC992FF39E13 // S32
+data8 0xBEC144B2760626E2 // S31
+//
+//[2; 8)
+data8 0x4009EFD1BA0CB3B4 // C01
+data8 0x3FFFB35378FF4822 // C11
+data8 0xC01032270413B896 // C41
+data8 0xC01F171A4C0D6827 // C51
+data8 0x40148F8E197396AC // C20
+data8 0x401C601959F1249C // C30
+data8 0x3EE21AD881741977 // An
+data8 0x4041852200000000 // overflow boundary (35.04010009765625)
+data8 0x3FD9CE68F695B198 // C21
+data8 0xBFF8C30AC900DA03 // C31
+data8 0x400E17D2F0535C02 // C00
+data8 0x4010689240F7FAC8 // C10
+data8 0x402563147DDCCF8D // C40
+data8 0x4033406D0480A21C // C50
+//
+//[8; 16)
+data8 0x4006222BAE0B793B // C01
+data8 0x4002452733473EDA // C11
+data8 0xC0010EF3326FDDB3 // C41
+data8 0xC01492B817F99C0F // C51
+data8 0x40099C905A249B75 // C20
+data8 0x4012B972AE0E533D // C30
+data8 0x3FE6F6DB91D0D4CC // An
+data8 0x4041852200000000 // overflow boundary
+data8 0x3FF545828F7B73C5 // C21
+data8 0xBFBBD210578764DF // C31
+data8 0x4000542098F53CFC // C00
+data8 0x40032C1309AD6C81 // C10
+data8 0x401D7331E19BD2E1 // C40
+data8 0x402A06807295EF57 // C50
+//
+//[16; 24)
+data8 0x4000131002867596 // C01
+data8 0x3FFAA362D5D1B6F2 // C11
+data8 0xBFFCB6985697DB6D // C41
+data8 0xC0115BEE3BFC3B3B // C51
+data8 0x3FFE62FF83456F73 // C20
+data8 0x4007E33478A114C4 // C30
+data8 0x41E9B2B73795ED57 // An
+data8 0x4041852200000000 // overflow boundary
+data8 0x3FEEB1F345BC2769 // C21
+data8 0xBFC3BBE6E7F3316F // C31
+data8 0x3FF14E07DA5E9983 // C00
+data8 0x3FF53B76BF81E2C0 // C10
+data8 0x4014051E0269A3DC // C40
+data8 0x40229D4227468EDB // C50
+//
+//[24; 32)
+data8 0x3FFAF7BD498384DE // C01
+data8 0x3FF62AD8B4D1C3D2 // C11
+data8 0xBFFABCADCD004C32 // C41
+data8 0xC00FADE97C097EC9 // C51
+data8 0x3FF6DA9ED737707E // C20
+data8 0x4002A29E9E0C782C // C30
+data8 0x44329D5B5167C6C3 // An
+data8 0x4041852200000000 // overflow boundary
+data8 0x3FE8943CBBB4B727 // C21
+data8 0xBFCB39D466E11756 // C31
+data8 0x3FE879AF3243D8C1 // C00
+data8 0x3FEEC7DEBB14CE1E // C10
+data8 0x401017B79BA80BCB // C40
+data8 0x401E941DC3C4DE80 // C50
+//
+//[32; 40)
+data8 0x3FF7ECB3A0E8FE5C // C01
+data8 0x3FF3815A8516316B // C11
+data8 0xBFF9ABD8FCC000C3 // C41
+data8 0xC00DD89969A4195B // C51
+data8 0x3FF2E43139CBF563 // C20
+data8 0x3FFF96DC3474A606 // C30
+data8 0x46AFF4CA9B0DDDF0 // An
+data8 0x4041852200000000 // overflow boundary
+data8 0x3FE4CE76DA1B5783 // C21
+data8 0xBFD0524DB460BC4E // C31
+data8 0x3FE35852DF14E200 // C00
+data8 0x3FE8C7610359F642 // C10
+data8 0x400BCF750EC16173 // C40
+data8 0x401AC14E02EA701C // C50
+//
+//[40; 48)
+data8 0x3FF5DCE4D8193097 // C01
+data8 0x3FF1B0D8C4974FFA // C11
+data8 0xBFF8FB450194CAEA // C41
+data8 0xC00C9658E030A6C4 // C51
+data8 0x3FF068851118AB46 // C20
+data8 0x3FFBF7C7BB46BF7D // C30
+data8 0x3FF0000000000000 // An
+data8 0x4041852200000000 // overflow boundary
+data8 0x3FE231DEB11D847A // C21
+data8 0xBFD251ECAFD7E935 // C31
+data8 0x3FE0368AE288F6BF // C00
+data8 0x3FE513AE4215A70C // C10
+data8 0x4008F960F7141B8B // C40
+data8 0x40183BA08134397B // C50
+//
+//[1.0; 1.25)
+data8 0xBFD9909648921868 // A7
+data8 0x3FE96FFEEEA8520F // A6
+data8 0xBFED0800D93449B8 // A3
+data8 0x3FEFA648D144911C // A2
+data8 0xBFEE3720F7720B4D // A5
+data8 0x3FEF4857A010CA3B // A4
+data8 0xBFE2788CCD545AA4 // A1
+data8 0x3FEFFFFFFFE9209E // A0
+//
+//[1.25; 1.5)
+data8 0xBFB421236426936C // A7
+data8 0x3FAF237514F36691 // A6
+data8 0xBFC0BADE710A10B9 // A3
+data8 0x3FDB6C5465BBEF1F // A2
+data8 0xBFB7E7F83A546EBE // A5
+data8 0x3FC496A01A545163 // A4
+data8 0xBDEE86A39D8452EB // A1
+data8 0x3FEC56DC82A39AA2 // A0
+//
+//[1.5; 1.75)
+data8 0xBF94730B51795867 // A7
+data8 0x3FBF4203E3816C7B // A6
+data8 0xBFE85B427DBD23E4 // A3
+data8 0x3FEE65557AB26771 // A2
+data8 0xBFD59D31BE3AB42A // A5
+data8 0x3FE3C90CC8F09147 // A4
+data8 0xBFE245971DF735B8 // A1
+data8 0x3FEFFC613AE7FBC8 // A0
+//
+//[1.75; 2.0)
+data8 0xBF7746A85137617E // A7
+data8 0x3FA96E37D09735F3 // A6
+data8 0xBFE3C24AC40AC0BB // A3
+data8 0x3FEC56A80A977CA5 // A2
+data8 0xBFC6F0E707560916 // A5
+data8 0x3FDB262D949175BE // A4
+data8 0xBFE1C1AEDFB25495 // A1
+data8 0x3FEFEE1E644B2022 // A0
+//
+// sin(pi*x)/pi
+data8 0xC026FB0D377656CC // S01
+data8 0x3FFFB15F95A22324 // S11
+data8 0x406CE58F4A41C6E7 // S10
+data8 0x404453786302C61E // S20
+data8 0xC023D59A47DBFCD3 // S21
+data8 0x405541D7ABECEFCA // S00
+//
+// 1/An for [40; 48)
+data8 0xCAA7576DE621FCD5, 0x3F68
+LOCAL_OBJECT_END(tgammaf_data)
+
+//==============================================================
+// Code
+//==============================================================
+
+.section .text
+GLOBAL_LIBM_ENTRY(tgammaf)
+{ .mfi
+ getf.exp GR_SignExp = f8
+ fma.s1 FR_NormX = f8,f1,f0
+ addl GR_ad_Data = @ltoff(tgammaf_data), gp
+}
+{ .mfi
+ mov GR_ExpOf05 = 0xFFFE
+ fcvt.fx.trunc.s1 FR_iXt = f8 // [x]
+ mov GR_Offs = 0 // 2 <= x < 8
+};;
+{ .mfi
+ getf.d GR_Arg = f8
+ fcmp.lt.s1 p14,p15 = f8,f0
+ mov GR_Tbl12Offs = 0
+}
+{ .mfi
+ setf.exp FR_05 = GR_ExpOf05
+ fma.s1 FR_2 = f1,f1,f1 // 2
+ mov GR_Correction = 0
+};;
+{ .mfi
+ ld8 GR_ad_Data = [GR_ad_Data]
+ fclass.m p10,p0 = f8,0x1E7 // is x NaTVal, NaN, +/-0 or +/-INF?
+ tbit.z p12,p13 = GR_SignExp,16 // p13 if |x| >= 2
+}
+{ .mfi
+ mov GR_ExpOf1 = 0xFFFF
+ fcvt.fx.s1 FR_rs = f8 // round(x)
+ and GR_Exp2Ind = 7,GR_SignExp
+};;
+.pred.rel "mutex",p14,p15
+{ .mfi
+(p15) cmp.eq.unc p11,p0 = GR_ExpOf1,GR_SignExp // p11 if 1 <= x < 2
+(p14) fma.s1 FR_1mX = f1,f1,f8 // 1 - |x|
+ mov GR_Sig = 0 // if |x| < 2
+}
+{ .mfi
+(p13) cmp.eq.unc p7,p0 = 2,GR_Exp2Ind
+(p15) fms.s1 FR_1mX = f1,f1,f8 // 1 - |x|
+(p13) cmp.eq.unc p8,p0 = 3,GR_Exp2Ind
+};;
+.pred.rel "mutex",p7,p8
+{ .mfi
+(p7) mov GR_Offs = 0x7 // 8 <= |x| < 16
+ nop.f 0
+(p8) tbit.z.unc p0,p6 = GR_Arg,51
+}
+{ .mib
+(p13) cmp.lt.unc p9,p0 = 3,GR_Exp2Ind
+(p8) mov GR_Offs = 0xE // 16 <= |x| < 32
+ // jump if x is NaTVal, NaN, +/-0 or +/-INF?
+(p10) br.cond.spnt tgammaf_spec_args
+};;
+.pred.rel "mutex",p14,p15
+.pred.rel "mutex",p6,p9
+{ .mfi
+(p9) mov GR_Offs = 0x1C // 32 <= |x|
+(p14) fma.s1 FR_X2mX = FR_NormX,FR_NormX,FR_NormX // x^2-|x|
+(p9) tbit.z.unc p0,p8 = GR_Arg,50
+}
+{ .mfi
+ ldfpd FR_LocalMin,FR_10 = [GR_ad_Data],16
+(p15) fms.s1 FR_X2mX = FR_NormX,FR_NormX,FR_NormX // x^2-|x|
+(p6) add GR_Offs = 0x7,GR_Offs // 24 <= x < 32
+};;
+.pred.rel "mutex",p8,p12
+{ .mfi
+ add GR_ad_Ce = 0x50,GR_ad_Data
+(p15) fcmp.lt.unc.s1 p10,p0 = f8,f1 // p10 if 0 <= x < 1
+ mov GR_OvfNzBound = 2
+}
+{ .mib
+ ldfpd FR_S32,FR_S31 = [GR_ad_Data],16
+(p8) add GR_Offs = 0x7,GR_Offs // 40 <= |x|
+ // jump if 1 <= x < 2
+(p11) br.cond.spnt tgammaf_from_1_to_2
+};;
+{ .mfi
+ shladd GR_ad_Ce = GR_Offs,4,GR_ad_Ce
+ fcvt.xf FR_Xt = FR_iXt // [x]
+(p13) cmp.eq.unc p7,p0 = r0,GR_Offs // p7 if 2 <= |x| < 8
+}
+{ .mfi
+ shladd GR_ad_Co = GR_Offs,4,GR_ad_Data
+ fma.s1 FR_6 = FR_2,FR_2,FR_2
+ mov GR_ExpOf05 = 0x7FC
+};;
+{ .mfi
+(p13) getf.sig GR_Sig = FR_iXt // if |x| >= 2
+ frcpa.s1 FR_Rcp0,p0 = f1,FR_NormX
+(p10) shr GR_Arg = GR_Arg,51
+}
+{ .mib
+ ldfpd FR_C01,FR_C11 = [GR_ad_Co],16
+(p7) mov GR_Correction = 2
+ // jump if 0 < x < 1
+(p10) br.cond.spnt tgammaf_from_0_to_1
+};;
+{ .mfi
+ ldfpd FR_C21,FR_C31 = [GR_ad_Ce],16
+ fma.s1 FR_Rq2 = f1,f1,FR_1mX // 2 - |x|
+(p14) sub GR_Correction = r0,GR_Correction
+}
+{ .mfi
+ ldfpd FR_C41,FR_C51 = [GR_ad_Co],16
+(p14) fcvt.xf FR_rs = FR_rs
+(p14) add GR_ad_SinO = 0x3A0,GR_ad_Data
+};;
+.pred.rel "mutex",p14,p15
+{ .mfi
+ ldfpd FR_C00,FR_C10 = [GR_ad_Ce],16
+ nop.f 0
+(p14) sub GR_Sig = GR_Correction,GR_Sig
+}
+{ .mfi
+ ldfpd FR_C20,FR_C30 = [GR_ad_Co],16
+ fma.s1 FR_Rq1 = FR_1mX,FR_2,FR_X2mX // (x-1)*(x-2)
+(p15) sub GR_Sig = GR_Sig,GR_Correction
+};;
+{ .mfi
+(p14) ldfpd FR_S01,FR_S11 = [GR_ad_SinO],16
+ fma.s1 FR_Rq3 = FR_2,f1,FR_1mX // 3 - |x|
+ and GR_RqDeg = 0x6,GR_Sig
+}
+{ .mfi
+ ldfpd FR_C40,FR_C50 = [GR_ad_Ce],16
+(p14) fma.d.s0 FR_X = f0,f0,f8 // set deno flag
+ mov GR_NanBound = 0x30016 // -2^23
+};;
+.pred.rel "mutex",p14,p15
+{ .mfi
+(p14) add GR_ad_SinE = 0x3C0,GR_ad_Data
+(p15) fms.s1 FR_r = FR_NormX,f1,FR_Xt // r = x - [x]
+ cmp.eq p8,p0 = 2,GR_RqDeg
+}
+{ .mfi
+ ldfpd FR_An,FR_OvfBound = [GR_ad_Co]
+(p14) fms.s1 FR_r = FR_Xt,f1,FR_NormX // r = |x - [x]|
+ cmp.eq p9,p0 = 4,GR_RqDeg
+};;
+.pred.rel "mutex",p8,p9
+{ .mfi
+(p14) ldfpd FR_S21,FR_S00 = [GR_ad_SinE],16
+(p8) fma.s1 FR_Rq0 = FR_2,f1,FR_1mX // (3-x)
+ tbit.z p0,p6 = GR_Sig,0
+}
+{ .mfi
+(p14) ldfpd FR_S10,FR_S20 = [GR_ad_SinO],16
+(p9) fma.s1 FR_Rq0 = FR_2,FR_2,FR_1mX // (5-x)
+ cmp.eq p10,p0 = 6,GR_RqDeg
+};;
+{ .mfi
+(p14) getf.s GR_Arg = f8
+(p14) fcmp.eq.unc.s1 p13,p0 = FR_NormX,FR_Xt
+(p14) mov GR_ZeroResBound = 0xC22C // -43
+}
+{ .mfi
+(p14) ldfe FR_InvAn = [GR_ad_SinE]
+(p10) fma.s1 FR_Rq0 = FR_6,f1,FR_1mX // (7-x)
+ cmp.eq p7,p0 = r0,GR_RqDeg
+};;
+{ .mfi
+(p14) cmp.ge.unc p11,p0 = GR_SignExp,GR_NanBound
+ fma.s1 FR_Rq2 = FR_Rq2,FR_6,FR_X2mX // (x-3)*(x-4)
+(p14) shl GR_ZeroResBound = GR_ZeroResBound,16
+}
+{ .mfb
+(p14) mov GR_OvfNzBound = 0x802
+(p14) fms.s1 FR_rs = FR_rs,f1,FR_NormX // rs = round(x) - x
+ // jump if x < -2^23 i.e. x is negative integer
+(p11) br.cond.spnt tgammaf_singularity
+};;
+{ .mfi
+ nop.m 0
+(p7) fma.s1 FR_Rq1 = f0,f0,f1
+(p14) shl GR_OvfNzBound = GR_OvfNzBound,20
+}
+{ .mfb
+ nop.m 0
+ fma.s1 FR_Rq3 = FR_Rq3,FR_10,FR_X2mX // (x-5)*(x-6)
+ // jump if x is negative integer such that -2^23 < x < 0
+(p13) br.cond.spnt tgammaf_singularity
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C01 = FR_C01,f1,FR_r
+(p14) mov GR_ExpOf05 = 0xFFFE
+}
+{ .mfi
+(p14) cmp.eq.unc p7,p0 = GR_Arg,GR_OvfNzBound
+ fma.s1 FR_C11 = FR_C11,f1,FR_r
+(p14) cmp.ltu.unc p11,p0 = GR_Arg,GR_OvfNzBound
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C21 = FR_C21,f1,FR_r
+(p14) cmp.ltu.unc p9,p0 = GR_ZeroResBound,GR_Arg
+}
+{ .mfb
+ nop.m 0
+ fma.s1 FR_C31 = FR_C31,f1,FR_r
+ // jump if argument is close to 0 negative
+(p11) br.cond.spnt tgammaf_overflow
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C41 = FR_C41,f1,FR_r
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s1 FR_C51 = FR_C51,f1,FR_r
+ // jump if x is negative noninteger such that -2^23 < x < -43
+(p9) br.cond.spnt tgammaf_underflow
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_rs2 = FR_rs,FR_rs,f0
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p14) fma.s1 FR_S01 = FR_rs,FR_rs,FR_S01
+ // jump if argument is 0x80200000
+(p7) br.cond.spnt tgammaf_overflow_near0_bound
+};;
+{ .mfi
+ nop.m 0
+(p6) fnma.s1 FR_Rq1 = FR_Rq1,FR_Rq0,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_Rq2 = FR_Rq2,FR_Rq3,f0
+ and GR_Sig = 0x7,GR_Sig
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C01 = FR_C01,FR_r,FR_C00
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C11 = FR_C11,FR_r,FR_C10
+ cmp.eq p6,p7 = r0,GR_Sig // p6 if |x| from one of base intervals
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C21 = FR_C21,FR_r,FR_C20
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C31 = FR_C31,FR_r,FR_C30
+(p7) cmp.lt.unc p9,p0 = 2,GR_RqDeg
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_S11 = FR_rs,FR_rs,FR_S11
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_S21 = FR_rs,FR_rs,FR_S21
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C41 = FR_C41,FR_r,FR_C40
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_S32 = FR_rs2,FR_S32,FR_S31
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p9) fma.s1 FR_Rq1 = FR_Rq1,FR_Rq2,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C51 = FR_C51,FR_r,FR_C50
+ nop.i 0
+};;
+{ .mfi
+(p14) getf.exp GR_SignExp = FR_rs
+ fma.s1 FR_C01 = FR_C01,FR_C11,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_S01 = FR_S01,FR_rs2,FR_S00
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C21 = FR_C21,FR_C31,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // NR-iteration
+(p14) fnma.s1 FR_InvNormX1 = FR_Rcp0,FR_NormX,f1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_S11 = FR_S11,FR_rs2,FR_S10
+(p14) tbit.z.unc p11,p12 = GR_SignExp,17
+}
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_S21 = FR_S21,FR_rs2,FR_S20
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p15) fcmp.lt.unc.s1 p0,p13 = FR_NormX,FR_OvfBound
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_S32 = FR_rs2,FR_S32,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C41 = FR_C41,FR_C51,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p7) fma.s1 FR_An = FR_Rq1,FR_An,f0
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ nop.f 0
+ // jump if x > 35.04010009765625
+(p13) br.cond.spnt tgammaf_overflow
+};;
+{ .mfi
+ nop.m 0
+ // NR-iteration
+(p14) fma.s1 FR_InvNormX1 = FR_Rcp0,FR_InvNormX1,FR_Rcp0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_S01 = FR_S01,FR_S11,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_S21 = FR_S21,FR_S32,f0
+ nop.i 0
+};;
+{ .mfi
+(p14) getf.exp GR_SignExp = FR_NormX
+ fma.s1 FR_C01 = FR_C01,FR_C21,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_C41 = FR_C41,FR_An,f0
+(p14) mov GR_ExpOf1 = 0x2FFFF
+};;
+{ .mfi
+ nop.m 0
+ // NR-iteration
+(p14) fnma.s1 FR_InvNormX2 = FR_InvNormX1,FR_NormX,f1
+ nop.i 0
+};;
+.pred.rel "mutex",p11,p12
+{ .mfi
+ nop.m 0
+(p12) fnma.s1 FR_S01 = FR_S01,FR_S21,f0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fma.s1 FR_S01 = FR_S01,FR_S21,f0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_GAMMA = FR_C01,FR_C41,f0
+(p14) tbit.z.unc p6,p7 = GR_Sig,0
+}
+{ .mfb
+ nop.m 0
+(p15) fma.s.s0 f8 = FR_C01,FR_C41,f0
+(p15) br.ret.spnt b0 // exit for positives
+};;
+.pred.rel "mutex",p11,p12
+{ .mfi
+ nop.m 0
+(p12) fms.s1 FR_S01 = FR_rs,FR_S01,FR_rs
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fma.s1 FR_S01 = FR_rs,FR_S01,FR_rs
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ // NR-iteration
+ fma.s1 FR_InvNormX2 = FR_InvNormX1,FR_InvNormX2,FR_InvNormX1
+ cmp.eq p10,p0 = 0x23,GR_Offs
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fma.s1 FR_GAMMA = FR_S01,FR_GAMMA,f0
+ cmp.gtu p8,p0 = GR_SignExp,GR_ExpOf1
+}
+{ .mfi
+ nop.m 0
+(p7) fnma.s1 FR_GAMMA = FR_S01,FR_GAMMA,f0
+ cmp.eq p9,p0 = GR_SignExp,GR_ExpOf1
+};;
+{ .mfi
+ nop.m 0
+ // NR-iteration
+ fnma.s1 FR_InvNormX1 = FR_InvNormX2,FR_NormX,f1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_InvNormX2 = FR_InvNormX2,FR_InvAn,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ frcpa.s1 FR_Rcp0,p0 = f1,FR_GAMMA
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_Multplr = FR_NormX,f1,f1 // x - 1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ // NR-iteration
+ fnma.s1 FR_Rcp1 = FR_Rcp0,FR_GAMMA,f1
+ nop.i 0
+};;
+.pred.rel "mutex",p8,p9
+{ .mfi
+ nop.m 0
+ // 1/x or 1/(An*x)
+(p8) fma.s1 FR_Multplr = FR_InvNormX2,FR_InvNormX1,FR_InvNormX2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p9) fma.s1 FR_Multplr = f1,f1,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ // NR-iteration
+ fma.s1 FR_Rcp1 = FR_Rcp0,FR_Rcp1,FR_Rcp0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ // NR-iteration
+ fnma.s1 FR_Rcp2 = FR_Rcp1,FR_GAMMA,f1
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ // NR-iteration
+ fma.s1 FR_Rcp1 = FR_Rcp1,FR_Multplr,f0
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+ fma.s.s0 f8 = FR_Rcp1,FR_Rcp2,FR_Rcp1
+ br.ret.sptk b0
+};;
+
+// here if 0 < x < 1
+//--------------------------------------------------------------------
+.align 32
+tgammaf_from_0_to_1:
+{ .mfi
+ cmp.lt p7,p0 = GR_Arg,GR_ExpOf05
+ // NR-iteration
+ fnma.s1 FR_Rcp1 = FR_Rcp0,FR_NormX,f1
+ cmp.eq p8,p0 = GR_Arg,GR_ExpOf05
+}
+{ .mfi
+ cmp.gt p9,p0 = GR_Arg,GR_ExpOf05
+ fma.s1 FR_r = f0,f0,FR_NormX // reduced arg for (0;1)
+ mov GR_ExpOf025 = 0x7FA
+};;
+{ .mfi
+ getf.s GR_ArgNz = f8
+ fma.d.s0 FR_X = f0,f0,f8 // set deno flag
+ shl GR_OvfNzBound = GR_OvfNzBound,20
+}
+{ .mfi
+(p8) mov GR_Tbl12Offs = 0x80 // 0.5 <= x < 0.75
+ nop.f 0
+(p7) cmp.ge.unc p6,p0 = GR_Arg,GR_ExpOf025
+};;
+.pred.rel "mutex",p6,p9
+{ .mfi
+(p9) mov GR_Tbl12Offs = 0xC0 // 0.75 <= x < 1
+ nop.f 0
+(p6) mov GR_Tbl12Offs = 0x40 // 0.25 <= x < 0.5
+}
+{ .mfi
+ add GR_ad_Ce = 0x2C0,GR_ad_Data
+ nop.f 0
+ add GR_ad_Co = 0x2A0,GR_ad_Data
+};;
+{ .mfi
+ add GR_ad_Co = GR_ad_Co,GR_Tbl12Offs
+ nop.f 0
+ cmp.lt p12,p0 = GR_ArgNz,GR_OvfNzBound
+}
+{ .mib
+ add GR_ad_Ce = GR_ad_Ce,GR_Tbl12Offs
+ cmp.eq p7,p0 = GR_ArgNz,GR_OvfNzBound
+ // jump if argument is 0x00200000
+(p7) br.cond.spnt tgammaf_overflow_near0_bound
+};;
+{ .mmb
+ ldfpd FR_A7,FR_A6 = [GR_ad_Co],16
+ ldfpd FR_A5,FR_A4 = [GR_ad_Ce],16
+ // jump if argument is close to 0 positive
+(p12) br.cond.spnt tgammaf_overflow
+};;
+{ .mfi
+ ldfpd FR_A3,FR_A2 = [GR_ad_Co],16
+ // NR-iteration
+ fma.s1 FR_Rcp1 = FR_Rcp0,FR_Rcp1,FR_Rcp0
+ nop.i 0
+}
+{ .mfb
+ ldfpd FR_A1,FR_A0 = [GR_ad_Ce],16
+ nop.f 0
+ br.cond.sptk tgamma_from_0_to_2
+};;
+
+// here if 1 < x < 2
+//--------------------------------------------------------------------
+.align 32
+tgammaf_from_1_to_2:
+{ .mfi
+ add GR_ad_Co = 0x2A0,GR_ad_Data
+ fms.s1 FR_r = f0,f0,FR_1mX
+ shr GR_TblOffs = GR_Arg,47
+}
+{ .mfi
+ add GR_ad_Ce = 0x2C0,GR_ad_Data
+ nop.f 0
+ mov GR_TblOffsMask = 0x18
+};;
+{ .mfi
+ nop.m 0
+ nop.f 0
+ and GR_TblOffs = GR_TblOffs,GR_TblOffsMask
+};;
+{ .mfi
+ shladd GR_ad_Co = GR_TblOffs,3,GR_ad_Co
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ shladd GR_ad_Ce = GR_TblOffs,3,GR_ad_Ce
+ nop.f 0
+ cmp.eq p6,p7 = 8,GR_TblOffs
+};;
+{ .mmi
+ ldfpd FR_A7,FR_A6 = [GR_ad_Co],16
+ ldfpd FR_A5,FR_A4 = [GR_ad_Ce],16
+ nop.i 0
+};;
+{ .mmi
+ ldfpd FR_A3,FR_A2 = [GR_ad_Co],16
+ ldfpd FR_A1,FR_A0 = [GR_ad_Ce],16
+ nop.i 0
+};;
+
+.align 32
+tgamma_from_0_to_2:
+{ .mfi
+ nop.m 0
+(p6) fms.s1 FR_r = FR_r,f1,FR_LocalMin
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ // NR-iteration
+(p10) fnma.s1 FR_Rcp2 = FR_Rcp1,FR_NormX,f1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r2 = FR_r,FR_r,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A7 = FR_A7,FR_r,FR_A6
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A5 = FR_A5,FR_r,FR_A4
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A3 = FR_A3,FR_r,FR_A2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A1 = FR_A1,FR_r,FR_A0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ // NR-iteration
+(p10) fma.s1 FR_Rcp2 = FR_Rcp1,FR_Rcp2,FR_Rcp1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A7 = FR_A7,FR_r2,FR_A5
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r4 = FR_r2,FR_r2,f0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fma.s1 FR_A3 = FR_A3,FR_r2,FR_A1
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+(p10) fma.s1 FR_GAMMA = FR_A7,FR_r4,FR_A3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p11) fma.s.s0 f8 = FR_A7,FR_r4,FR_A3
+ nop.i 0
+};;
+{ .mfb
+ nop.m 0
+(p10) fma.s.s0 f8 = FR_GAMMA,FR_Rcp2,f0
+ br.ret.sptk b0
+};;
+
+
+// overflow
+//--------------------------------------------------------------------
+.align 32
+tgammaf_overflow_near0_bound:
+.pred.rel "mutex",p14,p15
+{ .mfi
+ mov GR_fpsr = ar.fpsr
+ nop.f 0
+(p15) mov r8 = 0x7f8
+}
+{ .mfi
+ nop.m 0
+ nop.f 0
+(p14) mov r8 = 0xff8
+};;
+{ .mfi
+ nop.m 0
+ nop.f 0
+ shl r8 = r8,20
+};;
+{ .mfi
+ sub r8 = r8,r0,1
+ nop.f 0
+ extr.u GR_fpsr = GR_fpsr,10,2 // rounding mode
+};;
+.pred.rel "mutex",p14,p15
+{ .mfi
+ // set p8 to 0 in case of overflow and to 1 otherwise
+ // for negative arg:
+ // no overflow if rounding mode either Z or +Inf, i.e.
+ // GR_fpsr > 1
+(p14) cmp.lt p8,p0 = 1,GR_fpsr
+ nop.f 0
+ // for positive arg:
+ // no overflow if rounding mode either Z or -Inf, i.e.
+ // (GR_fpsr & 1) == 0
+(p15) tbit.z p0,p8 = GR_fpsr,0
+};;
+{ .mib
+(p8) setf.s f8 = r8 // set result to 0x7f7fffff without
+ // OVERFLOW flag raising
+ nop.i 0
+(p8) br.ret.sptk b0
+};;
+
+.align 32
+tgammaf_overflow:
+{ .mfi
+ nop.m 0
+ nop.f 0
+ mov r8 = 0x1FFFE
+};;
+{ .mfi
+ setf.exp f9 = r8
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+};;
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p14) fnma.s.s0 f8 = f9,f9,f0 // set I,O and -INF result
+ mov GR_TAG = 261 // overflow
+}
+{ .mfb
+ nop.m 0
+(p15) fma.s.s0 f8 = f9,f9,f0 // set I,O and +INF result
+ br.cond.sptk tgammaf_libm_err
+};;
+
+// x is negative integer or +/-0
+//--------------------------------------------------------------------
+.align 32
+tgammaf_singularity:
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8,f8
+ mov GR_TAG = 262 // negative
+}
+{ .mfb
+ nop.m 0
+ frcpa.s0 f8,p0 = f0,f0
+ br.cond.sptk tgammaf_libm_err
+};;
+// x is negative noninteger with big absolute value
+//--------------------------------------------------------------------
+.align 32
+tgammaf_underflow:
+{ .mfi
+ mov r8 = 0x00001
+ nop.f 0
+ tbit.z p6,p7 = GR_Sig,0
+};;
+{ .mfi
+ setf.exp f9 = r8
+ nop.f 0
+ nop.i 0
+};;
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fms.s.s0 f8 = f9,f9,f9
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.s.s0 f8 = f9,f9,f9
+ br.ret.sptk b0
+};;
+
+// x for natval, nan, +/-inf or +/-0
+//--------------------------------------------------------------------
+.align 32
+tgammaf_spec_args:
+{ .mfi
+ nop.m 0
+ fclass.m p6,p0 = f8,0x1E1 // Test x for natval, nan, +inf
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fclass.m p7,p8 = f8,0x7 // +/-0
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fmerge.s FR_X = f8,f8
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p6) fma.s.s0 f8 = f8,f1,f8
+(p6) br.ret.spnt b0
+};;
+.pred.rel "mutex",p7,p8
+{ .mfi
+(p7) mov GR_TAG = 262 // negative
+(p7) frcpa.s0 f8,p0 = f1,f8
+ nop.i 0
+}
+{ .mib
+ nop.m 0
+ nop.i 0
+(p8) br.cond.spnt tgammaf_singularity
+};;
+
+.align 32
+tgammaf_libm_err:
+{ .mfi
+ alloc r32 = ar.pfs,1,4,4,0
+ nop.f 0
+ mov GR_Parameter_TAG = GR_TAG
+};;
+
+GLOBAL_LIBM_END(tgammaf)
+
+LOCAL_LIBM_ENTRY(__libm_error_region)
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfs [GR_Parameter_Y] = FR_Y,16 // STORE Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfs [GR_Parameter_X] = FR_X // STORE Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y // Parameter 3 address
+ nop.b 0
+}
+{ .mib
+ stfs [GR_Parameter_Y] = FR_RESULT // STORE Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 0
+ nop.m 0
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfs f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region)
+.type __libm_error_support#,@function
+.global __libm_error_support#
+
diff --git a/libc/sysdeps/ia64/fpu/w_tgammal.S b/libc/sysdeps/ia64/fpu/w_tgammal.S
new file mode 100644
index 000000000..f64e21326
--- /dev/null
+++ b/libc/sysdeps/ia64/fpu/w_tgammal.S
@@ -0,0 +1,4487 @@
+.file "tgammal.s"
+
+
+// Copyright (c) 2002 - 2005, Intel Corporation
+// All rights reserved.
+//
+// Contributed 2002 by the Intel Numerics Group, Intel Corporation
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * The name of Intel Corporation may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
+// 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.
+//
+// Intel Corporation is the author of this code, and requests that all
+// problem reports or change requests be submitted to it directly at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+//
+// History
+//==============================================================
+// 01/16/02 Initial version
+// 05/20/02 Cleaned up namespace and sf0 syntax
+// 02/10/03 Reordered header: .section, .global, .proc, .align;
+// used data8 for long double table values
+// 03/17/03 Moved tgammal_libm_err label into .proc region
+// 04/10/03 Changed error codes for overflow and negative integers
+// 03/31/05 Reformatted delimiters between data tables
+//
+// API
+//==============================================================
+// long double tgammal(long double)
+//
+// Resources Used:
+//
+// Floating-Point Registers: f8-f15
+// f32-f127
+//
+// General Purpose Registers: r32-r67
+//
+// Predicate Registers: p6-p15
+//
+//*********************************************************************
+//
+// IEEE Special Conditions:
+//
+// tgammal(+inf) = +inf
+// tgammal(-inf) = QNaN
+// tgammal(+/-0) = +/-inf
+// tgammal(x<0, x - integer) = QNaN
+// tgammal(SNaN) = QNaN
+// tgammal(QNaN) = QNaN
+//
+//*********************************************************************
+// Overview of operation
+//==============================================================
+//
+// Algorithm description
+// ---------------------
+//
+// There are 3 main paths in the implementation
+// (and additional special values branches)
+//
+// 1) |X| >= 13 - Stirling formula computation
+// a) Positive arguments:
+// TGAMMAL(X) = exp((X-0.5)*ln(X) - X + C + S(Z)),
+// where C = 0.5*ln(2*Pi) , Z = 1/Z, S(Z) - Bernulli polynomial
+// (up to 'B18' term).
+// Some of these calculation done in multiprecision.
+// Ln returns multiprecision result too
+// and exp also accepts and returns pair of values.
+//
+// b) Negative arguments
+// TGAMMAL(-X) = PI/(X*TGAMMAL(X)*sin(PI*X)).
+// (X*sin(PI*X))/PI calculated in parallel with TGAMMAL.
+// Here we use polynomial of 9th degree with 2 multiprecision steps.
+// Argument range reduction is:
+// N = [x] with round to nearest, r = x - N, -0.5 <= r < 0.5
+// After ((X-0.5)*ln(X) - X + C + S(Z)) completed we just invert
+// its result and compute exp with negative argument (1/exp(x)=exp(-x))
+// Then we multiply exp result to PI/(X*sin(PI*X)).
+//
+// 2) 1 <= |X| < 13 - Polynomial part
+// a) Positive arguments:
+// All values are splitted to such intervals as:
+// #0->[2;3], #1->[3,4], #2->[5,6]...
+// For even intervals we just use polynomial computation with degree 20
+// and first 6 multiprecision computations.
+// Range reduction looks like
+// N = [x] with truncate, r = x - N - 0.5, -0.5 <= r < 0.5
+// For odd intervals we use reccurent formula:
+// TGAMMAL(X) = TGAMMA(X-1)*(X-1)
+// [1;2] interval is splitted to 3 subranges:
+// [1;1.25], [1.25;1.75], [1.75;2] with the same polynomial forms
+//
+// b) Negative arguments
+// TGAMMAL(-X) = PI/(X*TGAMMAL(X)*sin(PI*X)).
+// (X*sin(PI*X))/PI calculated in parallel with TGAMMAL.
+// After multiplication by TGAMMAL(X) result we calculate reciprocal
+// and get final result.
+//
+// 3) 0 < |X| < 1 - Near 0 part
+// a) Here we use reccurent formula TGAMMAL(X) = TGAMMAL(X+1)/X
+// TGAMMAL(X+1) calculated as shown above,
+// 1/X result obtained in parallel. Then we just multiply these values.
+// There is only additional separated subrange: [0;0.125] with specific
+// polynomial constants set.
+//
+// b) Negative arguments
+// TGAMMAL(-X) = PI/(TGAMMAL(X+1)*sin(PI*X)).
+// There is no need to compute 1/X.
+
+
+
+RODATA
+
+.align 16
+LOCAL_OBJECT_START(Constants_Tgammal_log_80_Q)
+// log2_hi, log2_lo, Q_6, Q_5, Q_4, Q_3, Q_2, Q_1
+data4 0x00000000,0xB1721800,0x00003FFE,0x00000000
+data4 0x4361C4C6,0x82E30865,0x0000BFE2,0x00000000
+data4 0xA51BE0AF,0x92492453,0x00003FFC,0x00000000
+data4 0xA0CFD29F,0xAAAAAB73,0x0000BFFC,0x00000000
+data4 0xCCCE3872,0xCCCCCCCC,0x00003FFC,0x00000000
+data4 0xFFFFB4FB,0xFFFFFFFF,0x0000BFFC,0x00000000
+data4 0xAAAAAAAB,0xAAAAAAAA,0x00003FFD,0x00000000
+data4 0x00000000,0x80000000,0x0000BFFE,0x00000000
+LOCAL_OBJECT_END(Constants_Tgammal_log_80_Q)
+
+.align 64
+LOCAL_OBJECT_START(Constants_Tgammal_log_80_Z_G_H_h1)
+// Z1 - 16 bit fixed, G1 and H1 IEEE single, h1 IEEE double
+data4 0x00008000,0x3F800000,0x00000000,0x00000000
+data4 0x00000000,0x00000000,0x00000000,0x00000000
+data4 0x00007879,0x3F70F0F0,0x3D785196,0x00000000
+data4 0xEBA0E0D1,0x8B1D330B,0x00003FDA,0x00000000
+data4 0x000071C8,0x3F638E38,0x3DF13843,0x00000000
+data4 0x9EADD553,0xE2AF365E,0x00003FE2,0x00000000
+data4 0x00006BCB,0x3F579430,0x3E2FF9A0,0x00000000
+data4 0x752F34A2,0xF585FEC3,0x0000BFE3,0x00000000
+data4 0x00006667,0x3F4CCCC8,0x3E647FD6,0x00000000
+data4 0x893B03F3,0xF3546435,0x00003FE2,0x00000000
+data4 0x00006187,0x3F430C30,0x3E8B3AE7,0x00000000
+data4 0x39CDD2AC,0xBABA62E0,0x00003FE4,0x00000000
+data4 0x00005D18,0x3F3A2E88,0x3EA30C68,0x00000000
+data4 0x457978A1,0x8718789F,0x00003FE2,0x00000000
+data4 0x0000590C,0x3F321640,0x3EB9CEC8,0x00000000
+data4 0x3185E56A,0x9442DF96,0x0000BFE4,0x00000000
+data4 0x00005556,0x3F2AAAA8,0x3ECF9927,0x00000000
+data4 0x2BBE2CBD,0xCBF9A4BF,0x00003FE4,0x00000000
+data4 0x000051EC,0x3F23D708,0x3EE47FC5,0x00000000
+data4 0x852D5935,0xF3537535,0x00003FE3,0x00000000
+data4 0x00004EC5,0x3F1D89D8,0x3EF8947D,0x00000000
+data4 0x46CDF32F,0xA1F1E699,0x0000BFDF,0x00000000
+data4 0x00004BDB,0x3F17B420,0x3F05F3A1,0x00000000
+data4 0xD8484CE3,0x84A61856,0x00003FE4,0x00000000
+data4 0x00004925,0x3F124920,0x3F0F4303,0x00000000
+data4 0xFF28821B,0xC7DD97E0,0x0000BFE2,0x00000000
+data4 0x0000469F,0x3F0D3DC8,0x3F183EBF,0x00000000
+data4 0xEF1FD32F,0xD3C4A887,0x00003FE3,0x00000000
+data4 0x00004445,0x3F088888,0x3F20EC80,0x00000000
+data4 0x464C76DA,0x84672BE6,0x00003FE5,0x00000000
+data4 0x00004211,0x3F042108,0x3F29516A,0x00000000
+data4 0x18835FB9,0x9A43A511,0x0000BFE5,0x00000000
+LOCAL_OBJECT_END(Constants_Tgammal_log_80_Z_G_H_h1)
+
+.align 64
+LOCAL_OBJECT_START(Constants_Tgammal_log_80_Z_G_H_h2)
+// Z2 - 16 bit fixed, G2 and H2 IEEE single, h2 IEEE double
+data4 0x00008000,0x3F800000,0x00000000,0x00000000
+data4 0x00000000,0x00000000,0x00000000,0x00000000
+data4 0x00007F81,0x3F7F00F8,0x3B7F875D,0x00000000
+data4 0x211398BF,0xAD08B116,0x00003FDB,0x00000000
+data4 0x00007F02,0x3F7E03F8,0x3BFF015B,0x00000000
+data4 0xC376958E,0xB106790F,0x00003FDE,0x00000000
+data4 0x00007E85,0x3F7D08E0,0x3C3EE393,0x00000000
+data4 0x79A7679A,0xFD03F242,0x0000BFDA,0x00000000
+data4 0x00007E08,0x3F7C0FC0,0x3C7E0586,0x00000000
+data4 0x05E7AE08,0xF03F81C3,0x0000BFDF,0x00000000
+data4 0x00007D8D,0x3F7B1880,0x3C9E75D2,0x00000000
+data4 0x049EB22F,0xD1B87D3C,0x00003FDE,0x00000000
+data4 0x00007D12,0x3F7A2328,0x3CBDC97A,0x00000000
+data4 0x3A9E81E0,0xFABC8B95,0x00003FDF,0x00000000
+data4 0x00007C98,0x3F792FB0,0x3CDCFE47,0x00000000
+data4 0x7C4B5443,0xF5F3653F,0x00003FDF,0x00000000
+data4 0x00007C20,0x3F783E08,0x3CFC15D0,0x00000000
+data4 0xF65A1773,0xE78AB204,0x00003FE0,0x00000000
+data4 0x00007BA8,0x3F774E38,0x3D0D874D,0x00000000
+data4 0x7B8EF695,0xDB7CBFFF,0x0000BFE0,0x00000000
+data4 0x00007B31,0x3F766038,0x3D1CF49B,0x00000000
+data4 0xCF773FB3,0xC0241AEA,0x0000BFE0,0x00000000
+data4 0x00007ABB,0x3F757400,0x3D2C531D,0x00000000
+data4 0xC9539FDF,0xFC8F4D48,0x00003FE1,0x00000000
+data4 0x00007A45,0x3F748988,0x3D3BA322,0x00000000
+data4 0x954665C2,0x9CD035FB,0x0000BFE1,0x00000000
+data4 0x000079D1,0x3F73A0D0,0x3D4AE46F,0x00000000
+data4 0xDD367A30,0xEC9017C7,0x00003FE1,0x00000000
+data4 0x0000795D,0x3F72B9D0,0x3D5A1756,0x00000000
+data4 0xCB11189C,0xEE6625D3,0x0000BFE1,0x00000000
+data4 0x000078EB,0x3F71D488,0x3D693B9D,0x00000000
+data4 0xBE11C424,0xA49C8DB5,0x0000BFE0,0x00000000
+LOCAL_OBJECT_END(Constants_Tgammal_log_80_Z_G_H_h2)
+
+.align 64
+LOCAL_OBJECT_START(Constants_Tgammal_log_80_h3_G_H)
+// h3 IEEE double extended, H3 and G3 IEEE single
+data4 0x112666B0,0xAAACAAB1,0x00003FD3,0x3F7FFC00
+data4 0x9B7FAD21,0x90051030,0x00003FD8,0x3F7FF400
+data4 0xF4D783C4,0xA6B46F46,0x00003FDA,0x3F7FEC00
+data4 0x11C6DDCA,0xDA148D88,0x0000BFD8,0x3F7FE400
+data4 0xCA964D95,0xCE65C1D8,0x0000BFD8,0x3F7FDC00
+data4 0x23412D13,0x883838EE,0x0000BFDB,0x3F7FD400
+data4 0x983ED687,0xB7E5CFA1,0x00003FDB,0x3F7FCC08
+data4 0xE3C3930B,0xDBE23B16,0x0000BFD9,0x3F7FC408
+data4 0x48AA4DFC,0x9B92F1FC,0x0000BFDC,0x3F7FBC10
+data4 0xCE9C8F7E,0x9A8CEB15,0x0000BFD9,0x3F7FB410
+data4 0x0DECE74A,0x8C220879,0x00003FDC,0x3F7FAC18
+data4 0x2F053150,0xB25CA912,0x0000BFDA,0x3F7FA420
+data4 0xD9A5BE20,0xA5876555,0x00003FDB,0x3F7F9C20
+data4 0x2053F087,0xC919BB6E,0x00003FD9,0x3F7F9428
+data4 0x041E9A77,0xB70BDA79,0x00003FDC,0x3F7F8C30
+data4 0xEA1C9C30,0xF18A5C08,0x00003FDA,0x3F7F8438
+data4 0x796D89E5,0xA3790D84,0x0000BFDD,0x3F7F7C40
+data4 0xA2915A3A,0xE1852369,0x0000BFDD,0x3F7F7448
+data4 0xA39ED868,0xD803858F,0x00003FDC,0x3F7F6C50
+data4 0x9417EBB7,0xB2EEE356,0x0000BFDD,0x3F7F6458
+data4 0x9BB0D07F,0xED5C1F8A,0x0000BFDC,0x3F7F5C68
+data4 0xE87C740A,0xD6D201A0,0x0000BFDD,0x3F7F5470
+data4 0x1CA74025,0xE8DEBF5E,0x00003FDC,0x3F7F4C78
+data4 0x1F34A7EB,0x9A995A97,0x0000BFDC,0x3F7F4488
+data4 0x359EED97,0x9CB0F742,0x0000BFDA,0x3F7F3C90
+data4 0xBBC6A1C8,0xD6F833C2,0x0000BFDD,0x3F7F34A0
+data4 0xE71090EC,0xE1F68F2A,0x00003FDC,0x3F7F2CA8
+data4 0xC160A74F,0xD1881CF1,0x0000BFDB,0x3F7F24B8
+data4 0xD78CB5A4,0x9AD05AE2,0x00003FD6,0x3F7F1CC8
+data4 0x9A77DC4B,0xE658CB8E,0x0000BFDD,0x3F7F14D8
+data4 0x6BD6D312,0xBA281296,0x00003FDC,0x3F7F0CE0
+data4 0xF95210D0,0xB478BBEB,0x0000BFDB,0x3F7F04F0
+data4 0x38800100,0x39400480,0x39A00640,0x39E00C41 // H's start here
+data4 0x3A100A21,0x3A300F22,0x3A4FF51C,0x3A6FFC1D
+data4 0x3A87F20B,0x3A97F68B,0x3AA7EB86,0x3AB7E101
+data4 0x3AC7E701,0x3AD7DD7B,0x3AE7D474,0x3AF7CBED
+data4 0x3B03E1F3,0x3B0BDE2F,0x3B13DAAA,0x3B1BD766
+data4 0x3B23CC5C,0x3B2BC997,0x3B33C711,0x3B3BBCC6
+data4 0x3B43BAC0,0x3B4BB0F4,0x3B53AF6D,0x3B5BA620
+data4 0x3B639D12,0x3B6B9444,0x3B7393BC,0x3B7B8B6D
+LOCAL_OBJECT_END(Constants_Tgammal_log_80_h3_G_H)
+
+.align 64
+LOCAL_OBJECT_START(Constants_Tgammal_stirling)
+//0.5*ln(2*Pi)=9.1893853320467266954096885e-01 + 7.2239360881843238220057778e-17
+data8 0x3FED67F1C864BEB4, 0x3C94D252F2400510
+// Bernulli numbers
+data8 0xAAAAAAAAAAAAAAAB, 0x00003FFB //B2 = 8.3333333333333333333333333333e-02
+data8 0xBF66C16C16C16C17 //B4 = -2.7777777777777777777777777778e-03
+data8 0x3F4A01A01A01A01A //B6 = 7.9365079365079365079365079365e-04
+data8 0xBF43813813813814 //B8 = -5.9523809523809523809523809524e-04
+data8 0x3F4B951E2B18FF23 //B10 = 8.4175084175084175084175084175e-04
+data8 0xBF5F6AB0D9993C7D //B12 = -1.9175269175269175269175269175e-03
+data8 0x3F7A41A41A41A41A //B14 = 6.4102564102564102564102564103e-03
+data8 0xBF9E4286CB0F5398 //B16 = -2.9550653594771241830065359477e-02
+data8 0x3FC6FE96381E0680 //B18 = 1.7964437236883057316493849002e-01
+data8 0x3FE0000000000000 // 0.5
+LOCAL_OBJECT_END(Constants_Tgammal_stirling)
+
+.align 64
+LOCAL_OBJECT_START(Constants_Tgammal_sin)
+// Polynomial coefficients for the sin(Pi*x)/Pi, 0 <= |x| < 0.5
+//A2 = 8.1174242528335360802316245099e-01 + 5.1302254650266899774269946201e-18
+data8 0x3FE9F9CB402BC46C, 0x3C57A8B3819B7CEC
+//A1 = -1.6449340668482264060656916627e+00 + -3.0210280454695477893051351574e-17
+data8 0xBFFA51A6625307D3, 0xBC816A402079D0EF
+data8 0xF3AEF1FFCCE6C813, 0x0000BFE3 //A9 = -7.0921197799923779127089910470e-09
+data8 0x87D54408E6D4BB9D, 0x00003FE9 //A8 = 2.5300880778252693946712766029e-07
+data8 0xEA12033DCE7B8ED9, 0x0000BFED //A7 = -6.9758403885461690048189307819e-06
+data8 0x9BA38C952A59D1A8, 0x00003FF2 //A6 = 1.4842878710882320255092707181e-04
+data8 0x99C0B55178FF0E38, 0x0000BFF6 //A5 = -2.3460810348048124421268761990e-03
+data8 0xD63402E798FEC896, 0x00003FF9 //A4 = 2.6147847817611456327417812320e-02
+data8 0xC354723906D95E92, 0x0000BFFC //A3 = -1.9075182412208257558294507774e-01
+LOCAL_OBJECT_END(Constants_Tgammal_sin)
+
+.align 64
+LOCAL_OBJECT_START(Constants_Tgammal_exp_64_Arg)
+data4 0x00000000,0xB17217F4,0x00003FF2,0x00000000 // L_hi = hi part log(2)/2^12
+data4 0xF278ECE6,0xF473DE6A,0x00003FD4,0x00000000 // L_lo = lo part log(2)/2^12
+LOCAL_OBJECT_END(Constants_Tgammal_exp_64_Arg)
+
+LOCAL_OBJECT_START(Constants_Tgammal_exp_64_A)
+data4 0xB1B736A0,0xAAAAAAAB,0x00003FFA,0x00000000 // A3
+data4 0x90CD6327,0xAAAAAAAB,0x00003FFC,0x00000000 // A2
+data4 0xFFFFFFFF,0xFFFFFFFF,0x00003FFD,0x00000000 // A1
+LOCAL_OBJECT_END(Constants_Tgammal_exp_64_A)
+
+LOCAL_OBJECT_START(Constants_Tgammal_exp_64_T1)
+data4 0x3F800000,0x3F8164D2,0x3F82CD87,0x3F843A29
+data4 0x3F85AAC3,0x3F871F62,0x3F88980F,0x3F8A14D5
+data4 0x3F8B95C2,0x3F8D1ADF,0x3F8EA43A,0x3F9031DC
+data4 0x3F91C3D3,0x3F935A2B,0x3F94F4F0,0x3F96942D
+data4 0x3F9837F0,0x3F99E046,0x3F9B8D3A,0x3F9D3EDA
+data4 0x3F9EF532,0x3FA0B051,0x3FA27043,0x3FA43516
+data4 0x3FA5FED7,0x3FA7CD94,0x3FA9A15B,0x3FAB7A3A
+data4 0x3FAD583F,0x3FAF3B79,0x3FB123F6,0x3FB311C4
+data4 0x3FB504F3,0x3FB6FD92,0x3FB8FBAF,0x3FBAFF5B
+data4 0x3FBD08A4,0x3FBF179A,0x3FC12C4D,0x3FC346CD
+data4 0x3FC5672A,0x3FC78D75,0x3FC9B9BE,0x3FCBEC15
+data4 0x3FCE248C,0x3FD06334,0x3FD2A81E,0x3FD4F35B
+data4 0x3FD744FD,0x3FD99D16,0x3FDBFBB8,0x3FDE60F5
+data4 0x3FE0CCDF,0x3FE33F89,0x3FE5B907,0x3FE8396A
+data4 0x3FEAC0C7,0x3FED4F30,0x3FEFE4BA,0x3FF28177
+data4 0x3FF5257D,0x3FF7D0DF,0x3FFA83B3,0x3FFD3E0C
+LOCAL_OBJECT_END(Constants_Tgammal_exp_64_T1)
+
+LOCAL_OBJECT_START(Constants_Tgammal_exp_64_T2)
+data4 0x3F800000,0x3F80058C,0x3F800B18,0x3F8010A4
+data4 0x3F801630,0x3F801BBD,0x3F80214A,0x3F8026D7
+data4 0x3F802C64,0x3F8031F2,0x3F803780,0x3F803D0E
+data4 0x3F80429C,0x3F80482B,0x3F804DB9,0x3F805349
+data4 0x3F8058D8,0x3F805E67,0x3F8063F7,0x3F806987
+data4 0x3F806F17,0x3F8074A8,0x3F807A39,0x3F807FCA
+data4 0x3F80855B,0x3F808AEC,0x3F80907E,0x3F809610
+data4 0x3F809BA2,0x3F80A135,0x3F80A6C7,0x3F80AC5A
+data4 0x3F80B1ED,0x3F80B781,0x3F80BD14,0x3F80C2A8
+data4 0x3F80C83C,0x3F80CDD1,0x3F80D365,0x3F80D8FA
+data4 0x3F80DE8F,0x3F80E425,0x3F80E9BA,0x3F80EF50
+data4 0x3F80F4E6,0x3F80FA7C,0x3F810013,0x3F8105AA
+data4 0x3F810B41,0x3F8110D8,0x3F81166F,0x3F811C07
+data4 0x3F81219F,0x3F812737,0x3F812CD0,0x3F813269
+data4 0x3F813802,0x3F813D9B,0x3F814334,0x3F8148CE
+data4 0x3F814E68,0x3F815402,0x3F81599C,0x3F815F37
+LOCAL_OBJECT_END(Constants_Tgammal_exp_64_T2)
+
+LOCAL_OBJECT_START(Constants_Tgammal_exp_64_W1)
+data8 0x0000000000000000, 0xBE384454171EC4B4
+data8 0xBE6947414AA72766, 0xBE5D32B6D42518F8
+data8 0x3E68D96D3A319149, 0xBE68F4DA62415F36
+data8 0xBE6DDA2FC9C86A3B, 0x3E6B2E50F49228FE
+data8 0xBE49C0C21188B886, 0x3E64BFC21A4C2F1F
+data8 0xBE6A2FBB2CB98B54, 0x3E5DC5DE9A55D329
+data8 0x3E69649039A7AACE, 0x3E54728B5C66DBA5
+data8 0xBE62B0DBBA1C7D7D, 0x3E576E0409F1AF5F
+data8 0x3E6125001A0DD6A1, 0xBE66A419795FBDEF
+data8 0xBE5CDE8CE1BD41FC, 0xBE621376EA54964F
+data8 0x3E6370BE476E76EE, 0x3E390D1A3427EB92
+data8 0x3E1336DE2BF82BF8, 0xBE5FF1CBD0F7BD9E
+data8 0xBE60A3550CEB09DD, 0xBE5CA37E0980F30D
+data8 0xBE5C541B4C082D25, 0xBE5BBECA3B467D29
+data8 0xBE400D8AB9D946C5, 0xBE5E2A0807ED374A
+data8 0xBE66CB28365C8B0A, 0x3E3AAD5BD3403BCA
+data8 0x3E526055C7EA21E0, 0xBE442C75E72880D6
+data8 0x3E58B2BB85222A43, 0xBE5AAB79522C42BF
+data8 0xBE605CB4469DC2BC, 0xBE589FA7A48C40DC
+data8 0xBE51C2141AA42614, 0xBE48D087C37293F4
+data8 0x3E367A1CA2D673E0, 0xBE51BEBB114F7A38
+data8 0xBE6348E5661A4B48, 0xBDF526431D3B9962
+data8 0x3E3A3B5E35A78A53, 0xBE46C46C1CECD788
+data8 0xBE60B7EC7857D689, 0xBE594D3DD14F1AD7
+data8 0xBE4F9C304C9A8F60, 0xBE52187302DFF9D2
+data8 0xBE5E4C8855E6D68F, 0xBE62140F667F3DC4
+data8 0xBE36961B3BF88747, 0x3E602861C96EC6AA
+data8 0xBE3B5151D57FD718, 0x3E561CD0FC4A627B
+data8 0xBE3A5217CA913FEA, 0x3E40A3CC9A5D193A
+data8 0xBE5AB71310A9C312, 0x3E4FDADBC5F57719
+data8 0x3E361428DBDF59D5, 0x3E5DB5DB61B4180D
+data8 0xBE42AD5F7408D856, 0x3E2A314831B2B707
+LOCAL_OBJECT_END(Constants_Tgammal_exp_64_W1)
+
+LOCAL_OBJECT_START(Constants_Tgammal_exp_64_W2)
+data8 0x0000000000000000, 0xBE641F2537A3D7A2
+data8 0xBE68DD57AD028C40, 0xBE5C77D8F212B1B6
+data8 0x3E57878F1BA5B070, 0xBE55A36A2ECAE6FE
+data8 0xBE620608569DFA3B, 0xBE53B50EA6D300A3
+data8 0x3E5B5EF2223F8F2C, 0xBE56A0D9D6DE0DF4
+data8 0xBE64EEF3EAE28F51, 0xBE5E5AE2367EA80B
+data8 0x3E47CB1A5FCBC02D, 0xBE656BA09BDAFEB7
+data8 0x3E6E70C6805AFEE7, 0xBE6E0509A3415EBA
+data8 0xBE56856B49BFF529, 0x3E66DD3300508651
+data8 0x3E51165FC114BC13, 0x3E53333DC453290F
+data8 0x3E6A072B05539FDA, 0xBE47CD877C0A7696
+data8 0xBE668BF4EB05C6D9, 0xBE67C3E36AE86C93
+data8 0xBE533904D0B3E84B, 0x3E63E8D9556B53CE
+data8 0x3E212C8963A98DC8, 0xBE33138F032A7A22
+data8 0x3E530FA9BC584008, 0xBE6ADF82CCB93C97
+data8 0x3E5F91138370EA39, 0x3E5443A4FB6A05D8
+data8 0x3E63DACD181FEE7A, 0xBE62B29DF0F67DEC
+data8 0x3E65C4833DDE6307, 0x3E5BF030D40A24C1
+data8 0x3E658B8F14E437BE, 0xBE631C29ED98B6C7
+data8 0x3E6335D204CF7C71, 0x3E529EEDE954A79D
+data8 0x3E5D9257F64A2FB8, 0xBE6BED1B854ED06C
+data8 0x3E5096F6D71405CB, 0xBE3D4893ACB9FDF5
+data8 0xBDFEB15801B68349, 0x3E628D35C6A463B9
+data8 0xBE559725ADE45917, 0xBE68C29C042FC476
+data8 0xBE67593B01E511FA, 0xBE4A4313398801ED
+data8 0x3E699571DA7C3300, 0x3E5349BE08062A9E
+data8 0x3E5229C4755BB28E, 0x3E67E42677A1F80D
+data8 0xBE52B33F6B69C352, 0xBE6B3550084DA57F
+data8 0xBE6DB03FD1D09A20, 0xBE60CBC42161B2C1
+data8 0x3E56ED9C78A2B771, 0xBE508E319D0FA795
+data8 0xBE59482AFD1A54E9, 0xBE2A17CEB07FD23E
+data8 0x3E68BF5C17365712, 0x3E3956F9B3785569
+LOCAL_OBJECT_END(Constants_Tgammal_exp_64_W2)
+
+
+
+LOCAL_OBJECT_START(Constants_Tgammal_poly)
+
+// Polynomial coefficients for the tgammal(x), 2 <= |x| < 3
+//A5 = 2.8360780594841213109180699803e-02 + 2.2504152891014320704380000000e-19
+data8 0x3F9D0A9BC49353D2, 0x3C109AEA0F23CE2D
+//A4 = 1.0967323400216015538699565468e-01 + 9.9225166000430644587276000000e-18
+data8 0x3FBC138B89492C5B, 0x3C66E138506D5652
+//A3 = 2.5387124684114281691904579930e-01 + 2.2667777637607113205546600000e-17
+data8 0x3FD03F6D2FA4F4F8, 0x3C7A2258DA8CD8B1
+data8 0xC5866457328BC39B, 0x00003FE3 //A20 = 5.7487331964156762795056629138e-09
+data8 0xE93D9F1ACD59C929, 0x0000BFE4 //A19= -1.3576396100397317396956445658e-08
+data8 0xE33389C8F6CBA813, 0x00003FE5 //A18 = 2.6449714924964597501721434271e-08
+data8 0x8FE7B25B9CD26D2A, 0x0000BFE7 //A17= -6.7011017946055513660266853311e-08
+data8 0xB89F4721BFBC15B0, 0x00003FE8 //A16 = 1.7194280320370423615174419192e-07
+data8 0xE49CBDC1874EBABA, 0x0000BFE9 //A15= -4.2582353660153782928729466776e-07
+data8 0x913AF50A336129CA, 0x00003FEB //A14 = 1.0820500665257088283172211622e-06
+data8 0xABCF0F7313B3B332, 0x0000BFEC //A13= -2.5601510627710417669568115706e-06
+//A2 = 6.5455857798133676439533701341e-01 + 1.3292075193155190798867000000e-18
+data8 0x3FE4F224D4B7E01C, 0x3C3885014A2B8319
+//A1 = 9.3473452162608550164435428087e-01 + 3.2785154201417136611642400000e-17
+data8 0x3FEDE9585F1A7093, 0x3C82E63C1B5028BF
+//A0 = 1.3293403881791368004172682049e+00 + 2.2005689328949279282607500000e-16
+data8 0x3FF544FA6D47B38F, 0x3CAFB6AA9829E81F
+data8 0xF3668F799997C76D, 0x00003FED //A12 = 7.2539039479124273660331538367e-06
+data8 0xD6C6BBD54CDEAEB1, 0x0000BFEE //A11= -1.2801665282681088568639378920e-05
+data8 0x809E4763B06F6883, 0x00003FF1 //A10 = 6.1329973609906572700697893187e-05
+data8 0x8443B000F8F9A71A, 0x00003FED //A9 = 3.9417864189995544394564413428e-06
+data8 0xC5C7E6D62A6991D8, 0x00003FF4 //A8 = 7.5447412886334708803357581519e-04
+data8 0xD2AF690725C62D88, 0x00003FF5 //A7 = 1.6074004848394703022110823298e-03
+data8 0xAA44E635D4B7B682, 0x00003FF8 //A6 = 1.0392403425906843901680697839e-02
+//
+// Polynomial coefficients for the tgammal(x), 4 <= |x| < 5
+//A5 = 1.1600674810589555185913468449e+00 + 3.0229979112715124660731000000e-17
+data8 0x3FF28FA2EB44D22E, 0x3C816D285234C815
+//A4 = 3.1374268565470946334983182169e+00 + 1.3694868953995008497659600000e-16
+data8 0x400919734073B1E1, 0x3CA3BC83CD7E9565
+//A3 = 7.0834593993741057360580271052e+00 + 3.3899702569039156457249800000e-16
+data8 0x401C5576617B6C1F, 0x3CB86D6431213296
+data8 0xA4A5FB49C094966B, 0x00003FDA //A20 = 9.3591760106637809309720130828e-12
+data8 0xA9260DA0F51D7ED8, 0x00003FDD //A19 = 7.6919898428091669411809372180e-11
+data8 0xA16441DFB14BD6E1, 0x00003FE0 //A18 = 5.8713933014370867331213494535e-10
+data8 0x95F098D9C2234849, 0x00003FE3 //A17 = 4.3638234584169302324461091035e-09
+data8 0x8581817400E5AD2B, 0x00003FE6 //A16 = 3.1084260332429955234755367839e-08
+data8 0xE272940E373EBE15, 0x00003FE8 //A15 = 2.1089573544273993580820317236e-07
+data8 0xB6B3391145D226FB, 0x00003FEB //A14 = 1.3612217421122787182942706259e-06
+data8 0x8B9428C4DF95FCD5, 0x00003FEE //A13 = 8.3195416382628990683949003789e-06
+//A2 = 1.2665135075272345943631080445e+01 + 9.8721896915973874255877000000e-16
+data8 0x4029548C95A76F38, 0x3CD1C8BE715B8E13
+//A1 = 1.6154969393303069580269948347e+01 + 9.6850518810678379641029000000e-16
+data8 0x403027AC12FC1E1E, 0x3CD172711C15501B
+//A0 = 1.1631728396567448058362970187e+01 + 8.7078125362814179268673000000e-16
+data8 0x40274371E7866C65, 0x3CCF5F8A1A5FACA0
+data8 0xC94A903114272C03, 0x00003FF0 //A12 = 4.7991576836334427243159066630e-05
+data8 0x8844262960E04BE6, 0x00003FF3 //A11 = 2.5990716419283017929486175141e-04
+data8 0xAC5418A76767678D, 0x00003FF5 //A10 = 1.3147621245497801180184809726e-03
+data8 0xCA231B6EFE959132, 0x00003FF7 //A9 = 6.1687358811367989146517222415e-03
+data8 0xDA38E39C13819D2A, 0x00003FF9 //A8 = 2.6638454961912040754759086920e-02
+data8 0xD696DF8D8389FE53, 0x00003FFB //A7 = 1.0477995539298934056097943975e-01
+data8 0xBDD5C153048BC435, 0x00003FFD //A6 = 3.7077144754791605130056406006e-01
+//
+// Polynomial coefficients for the tgammal(x), 6 <= |x| < 7
+//A5 = 6.7169398121054200601065531373e+01 + 2.9481001527213915901489600000e-15
+data8 0x4050CAD76B377BA0, 0x3CEA8DDB2B2DE93E
+//A4 = 1.6115104376855398982115730178e+02 + 1.3422421925418824418257300000e-14
+data8 0x406424D559BDC687, 0x3D0E397FDB5B33DC
+//A3 = 3.1812194028053562533386866562e+02 + 3.9881709875858650942409600000e-14
+data8 0x4073E1F377A6CF73, 0x3D26738F63FE9C4C
+data8 0xD6E1B5FF90CAABD3, 0x00003FE1 //A20 = 1.5634700199277480081025480635e-09
+data8 0xD451987B925DD37E, 0x00003FE4 //A19 = 1.2358576813211397717382327174e-08
+data8 0xBFC151B67FA58E6B, 0x00003FE7 //A18 = 8.9292951435632759686382657901e-08
+data8 0xA9034C5E1D67572E, 0x00003FEA //A17 = 6.2962205718327848327368724720e-07
+data8 0x8E40F6EAA30A71EC, 0x00003FED //A16 = 4.2394926442967995119170095258e-06
+data8 0xE3C3541B03A1C350, 0x00003FEF //A15 = 2.7151465666109594512258841637e-05
+data8 0xACE2E58436B2DDCE, 0x00003FF2 //A14 = 1.6487723793339152877117376243e-04
+data8 0xF7EAF8D8D1CAA3D1, 0x00003FF4 //A13 = 9.4573158112768812533636022369e-04
+//A2 = 4.8664351544258869353143381886e+02 + 4.7424047995944376868895400000e-14
+data8 0x407E6A4BD6D9463B, 0x3D2AB2868D79E192
+//A1 = 5.1615277644992545447166776285e+02 + 3.0901956935588717379242200000e-14
+data8 0x40802138E2DC003B, 0x3D216570FB601AEA
+//A0 = 2.8788527781504433278314536437e+02 + 2.8213174117085164944959600000e-14
+data8 0x4071FE2A1911F7D6, 0x3D1FC3E4CF4DB5AF
+data8 0xA72B88E48D3D1BAB, 0x00003FF7 //A12 = 5.1016252919939028020562237471e-03
+data8 0xD2EFB1067DB4FFB2, 0x00003FF9 //A11 = 2.5749059441230515023024615917e-02
+data8 0xF788AF9522205C24, 0x00003FFB //A10 = 1.2086617635601742290221382521e-01
+data8 0x861A6CE06CB29EAF, 0x00003FFE //A9 = 5.2384071807018493367136112163e-01
+data8 0x84FBDE0947718B58, 0x00004000 //A8 = 2.0778727617851237754568261869e+00
+data8 0xEEC1371E265A2C3A, 0x00004001 //A7 = 7.4610858525146049022238037342e+00
+data8 0xBF514B9BE68ED59D, 0x00004003 //A6 = 2.3914694993947572859629197920e+01
+//
+// Polynomial coefficients for the tgammal(x), 8 <= |x| < 9
+//A5 = 5.8487447114416836484451778233e+03 + 4.7365465221455983144182900000e-13
+data8 0x40B6D8BEA568B6FD, 0x3D60AA4D44C2589B
+//A4 = 1.2796464063087094473303295672e+04 + 1.2373341702514898266244200000e-12
+data8 0x40C8FE3B666B532D, 0x3D75C4752C5B4783
+//A3 = 2.2837606581322281272150576115e+04 + 2.6598064610627891398831000000e-13
+data8 0x40D64D66D23A7764, 0x3D52B77B3A10EA5C
+data8 0xB23418F75B0BE22A, 0x00003FE9 //A20 = 3.3192989594206801808678663868e-07
+data8 0xA984A7BC8B856ED2, 0x00003FEC //A19 = 2.5260177918662350066375115788e-06
+data8 0x921A49729416372C, 0x00003FEF //A18 = 1.7416797068239475136398213598e-05
+data8 0xF5BB9415CC399CA4, 0x00003FF1 //A17 = 1.1717449586392814601938207599e-04
+data8 0xC50B91A40B81F9DF, 0x00003FF4 //A16 = 7.5166775151159345732094429036e-04
+data8 0x96002572326DB203, 0x00003FF7 //A15 = 4.5776541559407384162139204300e-03
+data8 0xD81A1A595E4157BA, 0x00003FF9 //A14 = 2.6379634345126284099420760736e-02
+data8 0x92B700D0CFECADD8, 0x00003FFC //A13 = 1.4327622675407940907282658100e-01
+//A2 = 3.1237895525940199149772524834e+04 + 3.1280450505163186432331700000e-12
+data8 0x40DE8179504C0878, 0x3D8B83BB33FBB766
+//A1 = 2.9192841741344487672904506326e+04 + 7.9300780509779689630767000000e-13
+data8 0x40DC8235DF171691, 0x3D6BE6C780EE54DF
+//A0 = 1.4034407293483411194756627083e+04 + 1.4038139346291543309253700000e-12
+data8 0x40CB693422315F90, 0x3D78B23746113FCE
+data8 0xBAE50807548BC711, 0x00003FFE //A12 = 7.3005724123917935346868107005e-01
+data8 0xDE28B1F57E68CFB6, 0x00004000 //A11 = 3.4712338349724065462763671443e+00
+data8 0xF4DCA5A5FF901118, 0x00004002 //A10 = 1.5303868912154033908205911714e+01
+data8 0xF85AAA1AD5E84E5E, 0x00004004 //A9 = 6.2088539523416399361048051373e+01
+data8 0xE5AA8BB1BF02934D, 0x00004006 //A8 = 2.2966619406617480799195651466e+02
+data8 0xBF6CFEFD67F59845, 0x00004008 //A7 = 7.6570306334640770654588802417e+02
+data8 0x8DB5D2F001635C29, 0x0000400A //A6 = 2.2673639984182571062068713002e+03
+//
+// Polynomial coefficients for the tgammal(x), 10 <= |x| < 11
+//A5 = 7.2546009516580589115619659424e+05 + 1.0343348865365065212891728822e-10
+data8 0x412623A830B99290, 0x3DDC6E7C157611C4
+//A4 = 1.4756292870840241666883230209e+06 + 8.1516565365333844166705674775e-11
+data8 0x4136842D497E56AF, 0x3DD66837E4C3F9EE
+//A3 = 2.4356116926500420086085796356e+06 + 3.5508860076560925641351069404e-10
+data8 0x4142950DD8A8C1AF, 0x3DF866C8E3DD0980
+data8 0xB7FD0D1EEAC38EB4, 0x00003FF1 //A20 = 8.7732544640091602721643775932e-05
+data8 0xA9345C64AC750AE9, 0x00003FF4 //A19 = 6.4546407626804942279126469603e-04
+data8 0x8BEABC81BE1E93C9, 0x00003FF7 //A18 = 4.2699261134524096128048819443e-03
+data8 0xE1CD281EDD7315F8, 0x00003FF9 //A17 = 2.7563646660310313164706189622e-02
+data8 0xAD8A5BA6D0FD9758, 0x00003FFC //A16 = 1.6947310643831556048460963841e-01
+data8 0xFCDDA464AD3F182E, 0x00003FFE //A15 = 9.8775699098518676937088606052e-01
+data8 0xAE0DCE2F7B60D1AE, 0x00004001 //A14 = 5.4391852309591064073782104822e+00
+data8 0xE1745D9ABEB8D1A7, 0x00004003 //A13 = 2.8181819161363002758615770457e+01
+//A2 = 3.0619656223573554307222366333e+06 + 1.0819940302945474471259520006e-10
+data8 0x41475C66CFA967E4, 0x3DDDBDDB2A27334B
+//A1 = 2.6099413018962685018777847290e+06 + 3.6851882860056025385268615240e-10
+data8 0x4143E98AA6A48974, 0x3DF9530D42589AB6
+//A0 = 1.1332783889487853739410638809e+06 + 1.9339350553312096248591829758e-10
+data8 0x41314ADE639225C9, 0x3DEA946DD6C2C8D3
+data8 0x88BCFAAE71812A1C, 0x00004006 //A12 = 1.3673820009490115307300592012e+02
+data8 0x9A770F5AB540A326, 0x00004008 //A11 = 6.1786031215382040427126476507e+02
+data8 0xA170C1D2C6B413FC, 0x0000400A //A10 = 2.5830473201524594051391525170e+03
+data8 0x9AE56061CB02EB55, 0x0000400C //A9 = 9.9133441230507404119297200255e+03
+data8 0x872390769650FBE2, 0x0000400E //A8 = 3.4595564309496661629764193479e+04
+data8 0xD3E5E8D6923910C1, 0x0000400F //A7 = 1.0849181904819284819615140521e+05
+data8 0x930D70602F50B754, 0x00004011 //A6 = 3.0116351174131169193070583741e+05
+//
+// Polynomial coefficients for the tgammal(x), 12 <= |x| < 13
+//A5 = 1.2249876249976964294910430908e+08 + 6.0051348061679753770848000000e-09
+data8 0x419D34BB29FFC39D, 0x3E39CAB72E01818D
+//A4 = 2.3482765927605420351028442383e+08 + 1.1874729051592862323641700000e-08
+data8 0x41ABFE5F168D56FA, 0x3E4980338AA7B04B
+//A3 = 3.6407329688125067949295043945e+08 + 2.6657200942150363994658700000e-08
+data8 0x41B5B35150E199A5, 0x3E5C9F79C0EB5300
+data8 0xE89AE0F8D726329D, 0x00003FF9 //A20 = 2.8394164465429105626588451540e-02
+data8 0xCF90981F86E38013, 0x00003FFC //A19 = 2.0270002071785908652476845915e-01
+data8 0xA56C658079CA8C4A, 0x00003FFF //A18 = 1.2923704984019263122675412350e+00
+data8 0x80AEF96A67C5615A, 0x00004002 //A17 = 8.0427183300456238315262463506e+00
+data8 0xBE886D7529678931, 0x00004004 //A16 = 4.7633230047847868242503413461e+01
+data8 0x858EDBA4CE2F7508, 0x00004007 //A15 = 2.6711607799594541057655957154e+02
+data8 0xB0B0A3AF388274F0, 0x00004009 //A14 = 1.4135199810126975119809102782e+03
+data8 0xDBA87137988751EF, 0x0000400B //A13 = 7.0290552818218513870879313985e+03
+//A2 = 4.2828433593031734228134155273e+08 + 3.9760422293645854535247300000e-08
+data8 0x41B98719AFEE2947, 0x3E6558A17E0D3007
+//A1 = 3.4008253676084774732589721680e+08 + 1.2558352335001093116071000000e-09
+data8 0x41B4453F68C2C6EB, 0x3E159338C5BC7EC3
+//A0 = 1.3684336546556583046913146973e+08 + 2.6786516700381562934240300000e-08
+data8 0x41A05020CAEE5EA5, 0x3E5CC3058A858579
+data8 0xFF5E3940FB4BA576, 0x0000400D //A12 = 3.2687111823895439312116108631e+04
+data8 0x8A08C124C7F74B6C, 0x00004010 //A11 = 1.4134701786994123329786229006e+05
+data8 0x89D701953540BFFB, 0x00004012 //A10 = 5.6459209892773907605385652281e+05
+data8 0xFC46344B3116C3AD, 0x00004013 //A9 = 2.0666305367147234406757715163e+06
+data8 0xD183EBD7A400151F, 0x00004015 //A8 = 6.8653979211730981618367536737e+06
+data8 0x9C083A40742112F4, 0x00004017 //A7 = 2.0451444503543981795037456447e+07
+data8 0xCD3C475B1A8B6662, 0x00004018 //A6 = 5.3801245423495149598177886823e+07
+LOCAL_OBJECT_END(Constants_Tgammal_poly)
+
+
+LOCAL_OBJECT_START(Constants_Tgammal_poly_splitted)
+
+// Polynomial coefficients for the tgammal(x), 1 <= |x| < 1.25
+//A5 = -9.8199506890310417350775651357e-01+ -3.2546247786122976510752200000e-17
+data8 0xBFEF6C80EC38B509, 0xBC82C2FA7A3DE3BD
+//A4 = 9.8172808683439960475425323239e-01 + 4.4847611775298520359811400000e-17
+data8 0x3FEF6A51055096B0, 0x3C89DA56DE95EFE4
+//A3 = -9.0747907608088618225394839101e-01 +-1.0244057366544064435443970000e-16
+data8 0xBFED0A118F324B62, 0xBC9D86C7B9EBCFFF
+data8 0xB8E3FDAA66CC738E, 0x00003FFB //A20 = 9.0278608095877488976217714815e-02
+data8 0xA76067AE1738699C, 0x0000BFFD //A19 =-3.2690738678103132837070881737e-01
+data8 0x9D66B13718408C44, 0x00003FFE //A18 = 6.1484820933424283818320582920e-01
+data8 0xD4AC67BBB4AE5599, 0x0000BFFE //A17 =-8.3075569470082063491389474937e-01
+data8 0xF1426ED1C1488DB3, 0x00003FFE //A16 = 9.4241993542644505594957058785e-01
+data8 0xFC12EB07AA6F4B6B, 0x0000BFFE //A15 =-9.8466366707947121954333549690e-01
+data8 0xFF2B32CFE5B0DDC8, 0x00003FFE //A14 = 9.9675290656677214804168895915e-01
+data8 0xFFD8E7E6FF3662EA, 0x0000BFFE //A13 =-9.9940347089360552383472582319e-01
+//A2 = 9.8905599532797250361682017683e-01 + 5.1760162410376024240867300000e-17
+data8 0x3FEFA658C23B1578, 0x3C8DD673A61F6FE7
+//A1 = -5.7721566490153275452712478000e-01+ -1.0607935612223465065923310000e-16
+data8 0xBFE2788CFC6FB618, 0xBC9E9346622D53B7
+//A0 = 9.9999999999999988897769753748e-01 + 1.1102230245372554544790880000e-16
+data8 0x3FEFFFFFFFFFFFFF, 0x3C9FFFFFFFF51E4E
+data8 0xFFF360DF628F0BC9, 0x00003FFE //A12 = 9.9980740979895815468216470840e-01
+data8 0xFFEF8F9A72B40480, 0x0000BFFE //A11 = -9.9974916001038145045939523470e-01
+data8 0xFFE037B8C7E39952, 0x00003FFE //A10 = 9.9951504002809911822597567307e-01
+data8 0xFFC01E08F348BED2, 0x0000BFFE //A9 = -9.9902522772325406705059517941e-01
+data8 0xFF83DAC83119B52C, 0x00003FFE //A8 = 9.9810569179053383842734164901e-01
+data8 0xFEF9F8AB891ABB24, 0x0000BFFE //A7 = -9.9600176036720260345608796766e-01
+data8 0xFE3F0537573C8235, 0x00003FFE //A6 = 9.9314911461918778676646301341e-01
+//
+// Polynomial coefficients for the tgammal(x), 1.25 <= |x| < 1.75
+//A5 = -7.7523052299853054125655660300e-02+ -1.2693512521686721504433600000e-17
+data8 0xBFB3D88CFE50601B, 0xBC6D44ED60EE2170
+//A4 = 1.4464535904462152982041800442e-01 + 2.5426820829345729856648800000e-17
+data8 0x3FC283BD374EB2A9, 0x3C7D50AC436187C3
+//A3 = -1.0729480456477220873257039102e-01+ -6.2429894945456418196551000000e-18
+data8 0xBFBB77AC1CA2EBA5, 0xBC5CCA6BCC422D41
+data8 0xF732D2689F323283, 0x00003FF2 //A20 = 2.3574688251652899567587145422e-04
+data8 0xB6B00E23DE89D13A, 0x0000BFF3 //A19 =-3.4844916488842618776630058875e-04
+data8 0xE98396FE4A1B2799, 0x00003FF3 //A18 =4.4539265198744452020440735977e-04
+data8 0xAF8D235A640DB1A2, 0x0000BFF4 //A17 =-6.6967514303333563295261178346e-04
+data8 0x8513B736C918B261, 0x00003FF5 //A16 = 1.0152970456990865810615917715e-03
+data8 0xC790A1A2C78D8E17, 0x0000BFF5 //A15 =-1.5225598630329403515321688394e-03
+data8 0x959706CFA638CDE2, 0x00003FF6 //A14 = 2.2825614575133879623648932383e-03
+data8 0xE050A6021E129860, 0x0000BFF6 //A13 =-3.4227757733947066666295285936e-03
+//A2 = 4.1481345368830113695679528973e-01 + 3.1252439808354284892632100000e-17
+data8 0x3FDA8C4DBA620D56, 0x3C82040BCB483C76
+//A1 = 3.2338397448885010387886751460e-02 + 3.4437825798552300531443100000e-18
+data8 0x3FA08EA88EE561B1, 0x3C4FC366D6C64806
+//A0 = 8.8622692545275794095971377828e-01 + 7.2689375867553992399219000000e-17
+data8 0x3FEC5BF891B4EF6A, 0x3C94F3877D311C0C
+data8 0xA8275AADC09D16FC, 0x00003FF7 //A12 = 5.1316445128621071486146117136e-03
+data8 0xFBFE2CE9215267A2, 0x0000BFF7 //A11= -7.6902121820788373000579382408e-03
+data8 0xBCC8EEAB67ECD91D, 0x00003FF8 //A10 = 1.1522515369164312742737727262e-02
+data8 0x8D1614BB97E5E8C2, 0x0000BFF9 //A9 = -1.7222443097804730395560633583e-02
+data8 0xD3A963578BE291E3, 0x00003FF9 //A8 = 2.5837606456090186343624210891e-02
+data8 0x9BA7EAE64C42FDF7, 0x0000BFFA //A7 = -3.8001935555045161419575037512e-02
+data8 0xF0115BA1A77607E7, 0x00003FFA //A6 = 5.8610303817173477119764956736e-02
+//
+// Polynomial coefficients for the tgammal(x), 1.75 <= |x| < 2.0
+//A5 = 2.6698206874501426502654943818e-04 + 3.4033756836921062797887300000e-20
+data8 0x3F317F3740FE2A68, 0x3BE417093234B06E
+//A4 = 7.4249010753513894345090307070e-02 + 3.9810018444482764697014200000e-18
+data8 0x3FB301FBB0F25A92, 0x3C525BEFFABB622F
+//A3 = -8.1576919247086265851720554565e-02+ -5.2716624487804746360745000000e-19
+data8 0xBFB4E239984650AC, 0xBC2372F1C4F276FF
+data8 0xFEF3AEE71038E9A3, 0x00003FEB //A20 = 1.8995395865421509009969188571e-06
+data8 0xA11CFA2672BF876A, 0x0000BFEB //A19 =-1.2003868221414015771269244270e-06
+data8 0xF8E107215DAE2164, 0x00003FEC //A18 = 3.7085863210303833432006027217e-06
+data8 0xBCDDD3FC011EF7D6, 0x00003FEC //A17 = 2.8143303971756051015245433043e-06
+data8 0x8683C4687FA22E68, 0x00003FEE //A16 = 8.0177018464360416764308252462e-06
+data8 0xFDA09E5D33E32968, 0x00003FEE //A15 = 1.5117372062443781157389064848e-05
+data8 0xFFB00D0CFF4089B4, 0x00003FEF //A14 = 3.0480348961227424242198174995e-05
+data8 0xFEF6C39566785085, 0x00003FF0 //A13 = 6.0788135974125244644334004947e-05
+//A2 = 4.1184033042643969357854416558e-01 + 1.2103396182129232634761000000e-18
+data8 0x3FDA5B978B96BEBF, 0x3C3653AAD0A139E4
+//A1 = -4.2278433509846713445057275749e-01+ -4.9429151528135657430413000000e-18
+data8 0xBFDB0EE6072093CE, 0xBC56CB907027554F
+//A0 = 1.0000000000000000000000000000e+00 + 1.0969171200000000000000000000e-31
+data8 0x3FF0000000000000, 0x3981CC6A5B20B4D5
+data8 0xFF2B7BA9A8D68C37, 0x00003FF1 //A12 = 1.2167446884801403650547161615e-04
+data8 0xFCA53468E3692EF1, 0x00003FF2 //A11 = 2.4094136329542400976250900707e-04
+data8 0x808D698A9C993615, 0x00003FF4 //A10 = 4.9038845704938303659791698883e-04
+data8 0xF10F8E3FB8BB4AFB, 0x00003FF4 //A9 = 9.1957383840999861214472423976e-04
+data8 0x89E224E42F93F005, 0x00003FF6 //A8 = 2.1039333407187324139473634747e-03
+data8 0xBAF374824937A323, 0x00003FF6 //A7 = 2.8526458211545152218493600470e-03
+data8 0xB6BF7564F52140C6, 0x00003FF8 //A6 = 1.1154045718131014476684982178e-02
+//
+// Polynomial coefficients for the tgammal(x), 0.0 <= |x| < 0.125
+//A5 = -9.8199506890314514073736518185e-01+ -5.9363811993837985890950900000e-17
+data8 0xBFEF6C80EC38B67A, 0xBC911C46B447C81F
+//A4 = 9.8172808683440015986576554496e-01 + 2.7457414262802803699834200000e-17
+data8 0x3FEF6A51055096B5, 0x3C7FA7FF90ACAD1F
+//A3 = -9.0747907608088618225394839101e-01 + -1.0676255850934306734701780000e-16
+data8 0xBFED0A118F324B62, 0xBC9EC5AFB633438D
+data8 0x9217E83FA207CB80, 0x00003FFD //A20 = 2.8533864762086088781083621561e-01
+data8 0xA8DABFA52FDF03EC, 0x0000BFFE //A19= -6.5958783896337186303285832783e-01
+data8 0xE331ED293AF39F9B, 0x00003FFE //A18 = 8.8748056656454687449654731184e-01
+data8 0xF9163C5DDB52419D, 0x0000BFFE //A17= -9.7299554149078295602977718525e-01
+data8 0xFEC0A1C672CB9265, 0x00003FFE //A16 = 9.9512683005268190987854104489e-01
+data8 0xFFD2D65B8EA7B5F4, 0x0000BFFE //A15= -9.9931087241443958201592847861e-01
+data8 0xFFF93AA39EE53445, 0x00003FFE //A14 = 9.9989668364186884793382816496e-01
+data8 0xFFFB99A9A3F5F480, 0x0000BFFE //A13= -9.9993286506283835663204999212e-01
+//A2 = 9.8905599532797250361682017683e-01 + 5.1778575360788420716540100000e-17
+data8 0x3FEFA658C23B1578, 0x3C8DD92B45408D07
+//A1 = -5.7721566490153275452712478000e-01+ -1.0607938730998824663273110000e-16
+data8 0xBFE2788CFC6FB618, 0xBC9E9346F8FDE55B
+//A0 = 9.9999999999999988897769753748e-01 + 1.1102230246251564036631420000e-16
+data8 0x3FEFFFFFFFFFFFFF, 0x3C9FFFFFFFFFFFFF
+data8 0xFFF7FEBB545812C1, 0x00003FFE //A12 = 9.9987785409425126648628395084e-01
+data8 0xFFF00C02E943A3F2, 0x0000BFFE //A11= -9.9975657530855116454438747397e-01
+data8 0xFFE0420AADC53820, 0x00003FFE //A10 = 9.9951565514290485919027183699e-01
+data8 0xFFC01EB42EF27EEB, 0x0000BFFE //A9 = -9.9902526759155739377365522320e-01
+data8 0xFF83DAD0BF23FF12, 0x00003FFE //A8 = 9.9810569378236378800364235948e-01
+data8 0xFEF9F8ABDBCDB2F3, 0x0000BFFE //A7 = -9.9600176044241699109053158187e-01
+data8 0xFE3F05375988491D, 0x00003FFE //A6 = 9.9314911462127599008937257662e-01
+LOCAL_OBJECT_END(Constants_Tgammal_poly_splitted)
+
+.align 64
+LOCAL_OBJECT_START(Constants_Tgammal_common)
+// Positive overflow value
+data8 0x3FE0000000000000 // 0.5
+data8 0x3FF8000000000000 // 1.5
+data8 0x3FD0000000000000 // 0.25
+data8 0x0000000000000000 // 0
+data8 0xDB718C066B352E21, 0x00004009 // Positive overflow value
+LOCAL_OBJECT_END(Constants_Tgammal_common)
+
+
+
+//=======================================================
+// Lgamma registers
+
+// General Purpose Registers
+GR_l_Log_Table = r33
+GR_l_Log_Table1 = r34
+GR_l_BIAS = r34
+GR_l_Index1 = r35
+GR_l_Index2 = r36
+GR_l_signif_Z = r37
+GR_l_X_0 = r38
+GR_l_X_1 = r39
+GR_l_X_2 = r40
+GR_l_Z_1 = r41
+GR_l_Z_2 = r42
+GR_l_N = r43
+GR_l_Index3 = r44
+GR_l_Stirling_Table = r45
+GR_l_N_Unbiased = r46
+
+// Floating Point Registers
+FR_l_logl_X = f8
+
+FR_l_h_3 = f10
+FR_l_poly_hi = f10
+FR_l_W = f11
+FR_l_S = f12
+FR_l_GS_hi = f13
+FR_l_Y_lo = f13
+FR_l_r_cor = f14
+FR_l_G_1 = f15
+FR_l_G = f15
+FR_l_H_1 = f32
+FR_l_H = f32
+FR_l_h = f33
+FR_l_h_1 = f33
+FR_l_N = f33
+FR_l_G_2 = f34
+FR_l_H_2 = f35
+FR_l_h_2 = f36
+FR_l_G_3 = f37
+FR_l_log2_hi = f38
+FR_l_GS_lo = f39
+FR_l_H_3 = f40
+FR_l_float_N = f41
+FR_l_Q_4 = f42
+FR_l_Q_3 = f43
+FR_l_Q_2 = f44
+FR_l_Q_1 = f45
+FR_l_Q_5 = f46
+FR_l_Q_6 = f47
+FR_l_log2_lo = f48
+FR_l_r = f49
+FR_l_poly_lo = f50
+FR_l_poly = f51
+FR_l_rsq = f52
+FR_l_Y_lo_res = f53
+
+FR_l_Y0 = f55
+FR_l_Q0 = f56
+FR_l_E0 = f57
+FR_l_E2 = f58
+FR_l_E1 = f59
+FR_l_Y1 = f60
+FR_l_E3 = f61
+FR_l_Y2 = f62
+
+FR_l_Z = f63
+FR_l_Z2 = f64
+FR_l_Z4 = f65
+FR_l_Z8 = f66
+
+FR_l_CH = f67
+FR_l_CL = f68
+
+FR_l_B2 = f69
+FR_l_B4 = f70
+FR_l_B6 = f71
+FR_l_B8 = f72
+FR_l_B10 = f73
+FR_l_B12 = f74
+FR_l_B14 = f75
+FR_l_B16 = f76
+FR_l_B18 = f77
+FR_l_Half = f78
+FR_l_SS = f79
+FR_l_AbsX_m_Half = f80
+FR_l_CXH = f81
+FR_l_CXL = f82
+FR_l_SSCXH = f83
+FR_l_SSCXL = f84
+FR_l_XYH = f85
+FR_l_XYL = f86
+FR_l_Temp = f87
+
+FR_l_logl_YHi = f88
+FR_l_logl_YLo = f89
+
+FR_l_SignedXYH = f123
+
+FR_l_AbsX = f127
+
+
+
+//=======================================================
+// Negative part registers
+
+// General Purpose Registers
+GR_n_sin_Table = r47
+GR_n_XN = r48
+
+// Float point registers
+FR_n_IXNS = f125
+FR_n_IXN = f126
+
+FR_n_XNS = f90
+FR_n_XS = f91
+FR_n_XS2 = f92
+FR_n_XS2L = f93
+FR_n_XS4 = f94
+FR_n_XS7 = f95
+FR_n_XS8 = f96
+FR_n_TT = f97
+FR_n_TH = f98
+FR_n_TL = f99
+
+FR_n_A2H = f100
+FR_n_A2L = f101
+FR_n_A1H = f102
+FR_n_A1L = f103
+FR_n_A9 = f104
+FR_n_A8 = f105
+FR_n_A7 = f106
+FR_n_A6 = f107
+FR_n_A5 = f108
+FR_n_A4 = f109
+FR_n_A3 = f110
+
+FR_n_PolyH = f111
+FR_n_PolyL = f112
+
+FR_n_Poly1H = f113
+FR_n_SinxH = f113 // the same as FR_n_Poly1H
+FR_n_Poly1L = f114
+FR_n_SinxL = f114 // the same as FR_n_Poly1L
+
+FR_n_Tail = f115
+FR_n_NegOne = f116
+
+FR_n_Y0 = f117
+
+FR_n_Q0 = f118
+FR_n_E0 = f119
+
+FR_n_E2 = f120
+FR_n_E1 = f121
+
+FR_n_Y1 = f55
+FR_n_E3 = f56
+
+FR_n_Y2 = f57
+FR_n_R0 = f58
+
+FR_n_E4 = f59
+FR_n_RcpResH = f60
+
+FR_n_Y3 = f61
+FR_n_R1 = f62
+FR_n_Temp = f63
+
+FR_n_RcpResL = f64
+
+FR_n_ResH = f65
+FR_n_ResL = f66
+
+
+
+
+//=======================================================
+// Exp registers
+
+// General Purpose Registers
+GR_e_ad_Arg = r33
+GR_e_ad_A = r34
+GR_e_signexp_x = r35
+GR_e_exp_x = r35
+GR_e_exp_mask = r36
+GR_e_ad_W1 = r37
+GR_e_ad_W2 = r38
+GR_e_M2 = r39
+GR_e_M1 = r40
+GR_e_K = r41
+GR_e_exp_2_mk = r42
+GR_e_exp_2_k = r43
+GR_e_ad_T1 = r44
+GR_e_ad_T2 = r45
+GR_e_N_fix = r46
+GR_e_one = r47
+GR_e_exp_bias = r48
+GR_e_sig_inv_ln2 = r49
+GR_e_rshf_2to51 = r50
+GR_e_exp_2tom51 = r51
+GR_e_rshf = r52
+
+// Floating Point Registers
+FR_e_RSHF_2TO51 = f10
+FR_e_INV_LN2_2TO63 = f11
+FR_e_W_2TO51_RSH = f12
+FR_e_2TOM51 = f13
+FR_e_RSHF = f14
+FR_e_Y_hi = f15
+FR_e_Y_lo = f32
+FR_e_scale = f33
+FR_e_float_N = f34
+FR_e_N_signif = f35
+FR_e_L_hi = f36
+FR_e_L_lo = f37
+FR_e_r = f38
+FR_e_W1 = f39
+FR_e_T1 = f40
+FR_e_W2 = f41
+FR_e_T2 = f42
+FR_e_W1_p1 = f43
+FR_e_rsq = f44
+FR_e_A2 = f45
+FR_e_r4 = f46
+FR_e_A3 = f47
+FR_e_poly = f48
+FR_e_T = f49
+FR_e_W = f50
+FR_e_Wp1 = f51
+FR_e_r6 = f52
+FR_e_2_mk = f53
+FR_e_A1 = f54
+FR_e_T_scale = f55
+FR_e_result_lo = f56
+FR_e_W_T_scale = f57
+FR_e_Wp1_T_scale = f58
+
+FR_e_expl_Input_X = f123
+FR_e_expl_Input_Y = f124
+FR_e_expl_Output_X = f123
+FR_e_expl_Output_Y = f124
+
+
+FR_e_expl_Input_AbsX = f122
+
+
+
+//=======================================================
+// Common registers
+
+// General Purpose Registers
+GR_c_Table = r53
+GR_c_NegUnderflow = r54
+GR_c_NegSingularity = r55
+GR_c_X = r56
+GR_c_SignBit = r57
+GR_c_13 = r58
+
+
+// Floating Point Registers
+FR_c_PosOverflow = f123
+FR_c_XN = f124
+
+
+//=======================================================
+// Polynomial part registers
+
+// General Purpose Registers
+GR_p_Table = r59
+GR_p_XN = r33
+GR_p_Table2 = r34
+GR_p_Int = r35
+GR_p_Offset = r36
+GR_p_Offset2 = r38
+GR_p_X_Sgnd = GR_l_signif_Z // = r37
+GR_p_Exp = r61
+GR_p_Bias = r62
+GR_p_0p75 = r63
+
+// Floating Point Registers
+FR_p_AbsX = FR_l_AbsX // = f127
+FR_p_IXN = FR_n_IXN // = f126
+FR_p_XN = f32
+FR_p_0p5 = f33
+FR_p_1p5 = f34
+FR_p_AbsXM1 = f35
+FR_p_2 = f36
+
+FR_p_A20 = f37
+FR_p_A19 = f38
+FR_p_A18 = f39
+FR_p_A17 = f40
+FR_p_A16 = f41
+FR_p_A15 = f42
+FR_p_A14 = f43
+FR_p_A13 = f44
+FR_p_A12 = f45
+FR_p_A11 = f46
+FR_p_A10 = f47
+FR_p_A9 = f48
+FR_p_A8 = f49
+FR_p_A7 = f50
+FR_p_A6 = f51
+FR_p_A5H = f52
+FR_p_A5L = f53
+FR_p_A4H = f54
+FR_p_A4L = f55
+FR_p_A3H = f56
+FR_p_A3L = f57
+FR_p_A2H = f58
+FR_p_A2L = f59
+FR_p_A1H = f60
+FR_p_A1L = f61
+FR_p_A0H = f62
+FR_p_A0L = f63
+
+FR_p_XR = f64
+FR_p_XR2 = f65
+FR_p_XR2L = f52
+
+FR_p_XR3 = f58
+FR_p_XR3L = f38
+
+FR_p_XR4 = f42
+FR_p_XR6 = f40
+FR_p_XR8 = f37
+
+FR_p_Poly5H = f66
+FR_p_Poly5L = f67
+FR_p_Poly4H = f53
+FR_p_Poly4L = f44
+FR_p_Poly3H = f41
+FR_p_Poly3L = f47
+FR_p_Poly2H = f68
+FR_p_Poly2L = f54
+FR_p_Poly1H = f55
+FR_p_Poly1L = f46
+FR_p_Poly0H = f39
+FR_p_Poly0L = f43
+
+FR_p_Temp5H = f69
+FR_p_Temp5L = f70
+FR_p_Temp4H = f71
+FR_p_Temp4L = f60
+FR_p_Temp2H = f72
+FR_p_Temp2L = f73
+FR_p_Temp1H = f59
+FR_p_Temp1L = f61
+FR_p_Temp0H = f49
+FR_p_Temp0L = f48
+FR_p_PolyTail = f45
+FR_p_OddPoly0H = f56
+FR_p_OddPoly0L = f51
+
+FR_p_0p25 = f73
+
+
+//=======================================================
+// Negative polynomial part registers
+// General Purpose Registers
+GR_r_sin_Table = r47
+GR_r_sin_Table2 = r60
+
+// Floating Point Registers
+FR_r_IXNS = FR_n_IXNS
+FR_r_IXN = FR_n_IXN
+
+FR_r_AbsX = FR_l_AbsX
+
+FR_r_A9 = f74
+FR_r_A8 = f75
+FR_r_A7 = f76
+FR_r_A6 = f77
+FR_r_A5 = f78
+FR_r_A4 = f79
+FR_r_A3 = f80
+FR_r_A2H = f81
+FR_r_A2L = f82
+FR_r_A1H = f83
+FR_r_A1L = f84
+
+FR_r_XNS = f85
+FR_r_XS = f86
+FR_r_XS2 = f87
+FR_r_XS2L = f88
+FR_r_XS4 = f89
+FR_r_XS7 = f90
+FR_r_XS8 = f91
+
+FR_r_Tail = f92
+
+FR_r_TT = f93
+FR_r_TH = f94
+FR_r_TL = f95
+
+FR_r_ResH = f96
+FR_r_ResL = f97
+
+FR_r_Res3H = f98
+FR_r_Res3L = f99
+
+FR_r_Res1H = f100
+FR_r_Res1L = f101
+
+
+
+FR_r_Y0 = f102
+FR_r_Q0 = f103
+FR_r_E0 = f104
+FR_r_E2 = f105
+FR_r_E1 = f106
+FR_r_Y1 = f107
+FR_r_E3 = f108
+FR_r_Y2 = f109
+FR_r_R0 = f110
+FR_r_E4 = f111
+FR_r_ZH = f112
+FR_r_Y3 = f113
+FR_r_R1 = f114
+FR_r_ZHN = f115
+FR_r_ZL = f115
+FR_r_NegOne = f116
+
+FR_z_Y0 = f102
+FR_z_Q0 = f103
+FR_z_E0 = f104
+FR_z_E2 = f105
+FR_z_E1 = f106
+FR_z_Y1 = f107
+FR_z_E3 = f108
+FR_z_Y2 = f109
+FR_z_R0 = f110
+FR_z_E4 = f111
+FR_z_ZH = f112
+FR_z_Y3 = f113
+FR_z_R1 = f114
+FR_z_ZL = f115
+
+
+// General Purpose Registers
+GR_SAVE_PFS = r32
+GR_DenOverflow = r33
+GR_u_XN = r34
+
+GR_SAVE_B0 = r35
+GR_SAVE_GP = r36
+GR_SAVE_SP = r37
+
+// Floating Point Registers
+FR_u_IXN = f34
+
+
+// ERROR HANDLER REGISTERS
+GR_Parameter_X = r64
+GR_Parameter_Y = r65
+GR_Parameter_RESULT = r66
+GR_Parameter_TAG = r67
+
+FR_RESULT = f8
+FR_X = f32
+FR_Y = f1
+
+
+.section .text
+GLOBAL_LIBM_ENTRY(tgammal)
+{ .mfi
+ alloc r32 = ar.pfs,0,32,4,0
+ fabs FR_l_AbsX = f8 // Get absolute value of X
+ addl GR_n_sin_Table = @ltoff(Constants_Tgammal_sin), gp
+}
+{ .mfi
+ addl GR_l_Log_Table=@ltoff(Constants_Tgammal_log_80_Z_G_H_h1#),gp
+ nop.f 0
+ addl GR_l_Stirling_Table = @ltoff(Constants_Tgammal_stirling), gp
+};;
+
+{ .mfi
+ getf.sig GR_l_signif_Z = f8 // Significand of X
+ fcvt.fx.s1 FR_n_IXNS = f8 // Convert to fixed point
+ addl GR_c_Table = @ltoff(Constants_Tgammal_common), gp
+}
+{ .mfi
+ ld8 GR_l_Log_Table = [GR_l_Log_Table]
+ nop.f 0
+ addl GR_p_Table = @ltoff(Constants_Tgammal_poly), gp
+};;
+
+{ .mfi
+ ld8 GR_n_sin_Table = [GR_n_sin_Table]
+ fclass.m p6,p0 = f8,0x1EF // Check x for NaN, 0, INF, denorm
+ // NatVal.
+ addl GR_c_NegSingularity = 0x1003E, r0
+}
+{ .mlx
+ ld8 GR_l_Stirling_Table = [GR_l_Stirling_Table]
+ movl GR_c_13 = 0x402A000000000000 // 13.0
+};;
+
+{ .mfi
+ getf.d GR_c_X = f8 // Double prec. X to general register
+ frcpa.s1 FR_z_Y0,p0 = f1,f8 // y = frcpa(x) (for negatives)
+ extr.u GR_l_Index1 = GR_l_signif_Z, 59, 4 // = High 4 bits of Z
+}
+{ .mlx
+ ld8 GR_c_Table = [GR_c_Table]
+ movl GR_c_SignBit = 0x8000000000000000 // High bit (sign)
+};;
+
+{ .mfi
+ ld8 GR_p_Table = [GR_p_Table]
+ fcmp.lt.s1 p15, p14 = f8,f0 // p14 - positive arg, p15 - negative
+ shl GR_l_Index1 = GR_l_Index1,5 // Adjust Index1 ptr (x32)
+}
+{ .mfb
+ adds GR_c_NegUnderflow = 1765, r0
+ nop.f 0
+(p6) br.cond.spnt tgammal_spec // Spec. values processing branch ////////////
+ // (0s, INFs, NANs, NatVals, denormals) //////
+};;
+
+{ .mfi
+ ldfpd FR_l_CH,FR_l_CL= [GR_l_Stirling_Table], 16 // Load CH, CL
+ fcvt.fx.trunc.s1 FR_n_IXN = FR_l_AbsX // Abs arg to int by trunc
+ extr.u GR_l_X_0 = GR_l_signif_Z, 49, 15 // High 15 bit of Z
+}
+{ .mfi
+ add GR_l_Index1 = GR_l_Index1,GR_l_Log_Table // Add offset
+ fma.s1 FR_p_2 = f1, f1, f1 // 2.0
+ andcm GR_c_X = GR_c_X, GR_c_SignBit // Remove sign
+};;
+
+{ .mfi
+ addl GR_l_Log_Table = @ltoff(Constants_Tgammal_log_80_Z_G_H_h2#), gp
+ fcmp.lt.s1 p10, p0 = FR_l_AbsX, f1 // If |X|<1 then p10 = 1
+ nop.i 0
+}
+{ .mlx
+ ld2 GR_l_Z_1 = [GR_l_Index1],4 // load Z_1 from Index1
+ movl GR_l_BIAS = 0x000000000000FFFF // Bias for exponent
+};;
+
+{ .mfi
+ ld8 GR_l_Log_Table = [GR_l_Log_Table]
+ frcpa.s1 FR_l_Y0, p0 = f1, FR_l_AbsX // y = frcpa(x)
+ nop.i 0
+}
+{ .mfi
+ ldfs FR_l_G_1 = [GR_l_Index1],4 // Load G_1
+ fsub.s1 FR_l_W = FR_l_AbsX, f1 // W = |X|-1
+ nop.i 0
+};;
+
+{ .mfi
+ getf.exp GR_l_N_Unbiased= FR_l_AbsX // exponent of |X|
+ fmerge.se FR_l_S = f1, FR_l_AbsX // S = merging of X and 1.0
+ cmp.gtu p11, p0 = GR_c_13, GR_c_X // If 1 <= |X| < 13
+ // then p11 = 1
+}
+{ .mfb
+ ldfs FR_l_H_1 = [GR_l_Index1],8 // Load H_1
+ fcvt.xf FR_n_XNS = FR_n_IXNS // Convert to FP repr. of int X
+(p10) br.cond.spnt tgamma_lt_1 // Branch to |X| < 1 path ///////////////////
+};;
+
+{ .mfi
+ ldfpd FR_n_A2H, FR_n_A2L = [GR_n_sin_Table], 16
+ nop.f 0
+ pmpyshr2.u GR_l_X_1 = GR_l_X_0,GR_l_Z_1,15 // Adjust Index2 (x32)
+}
+{ .mfb
+ ldfe FR_l_B2 = [GR_l_Stirling_Table], 16
+ nop.f 0
+(p11) br.cond.spnt tgamma_lt_13 // Branch to 1 <= |X| < 13 path ///////////////
+};;
+
+{ .mfi
+ ldfe FR_l_h_1 = [GR_l_Index1],0
+ nop.f 0
+ sub GR_l_N = GR_l_N_Unbiased, GR_l_BIAS // N - BIAS
+}
+{ .mib
+ ldfpd FR_l_B4,FR_l_B6= [GR_l_Stirling_Table], 16 // Load C
+(p15) cmp.geu.unc p8,p0 = GR_l_N_Unbiased, GR_c_NegSingularity
+(p8) br.cond.spnt tgammal_singularity // Singularity for arg < to -2^63 //////
+};;
+
+{ .mmi
+(p15) ldfpd FR_n_A1H, FR_n_A1L = [GR_n_sin_Table], 16
+ ldfpd FR_l_B8, FR_l_B10 = [GR_l_Stirling_Table], 16
+ add GR_c_Table = 0x20, GR_c_Table
+};;
+
+{ .mfi
+(p15) ldfe FR_n_A9 = [GR_n_sin_Table], 16
+ fma.s1 FR_l_Q0 = f1,FR_l_Y0,f0 // Q0 = Y0
+ nop.i 0
+}
+{ .mfi
+ ldfpd FR_l_B12, FR_l_B14 = [GR_l_Stirling_Table], 16
+ fnma.s1 FR_l_E0 = FR_l_Y0,FR_l_AbsX,f1 // e = 1-b*y
+ nop.i 0
+};;
+
+{ .mfi
+(p15) ldfe FR_n_A8 = [GR_n_sin_Table], 16
+ fcvt.xf FR_c_XN = FR_n_IXN // Convert to FP repr. of int X
+ extr.u GR_l_Index2 = GR_l_X_1, 6, 4 // Extract Index2
+}
+{ .mfi
+ ldfpd FR_l_B16, FR_l_B18 = [GR_l_Stirling_Table], 16
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+(p15) ldfe FR_n_A7 = [GR_n_sin_Table], 16
+ fms.s1 FR_l_CXH = FR_l_CH, f1, FR_l_AbsX // CXH = CH+|X|
+ shl GR_l_Index2 = GR_l_Index2,5
+}
+{ .mfi
+ ldfd FR_l_Half = [GR_l_Stirling_Table] // Load 0.5
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ add GR_l_Index2 = GR_l_Index2, GR_l_Log_Table // Add offset
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+(p15) ldfe FR_n_A6 = [GR_n_sin_Table], 16
+(p15) fma.s1 FR_n_XS = FR_l_AbsX , f1, FR_n_XNS // xs = x - int(x)
+ nop.i 0
+};;
+
+{ .mmi
+ ld2 GR_l_Z_2 = [GR_l_Index2],4
+ addl GR_l_Log_Table = @ltoff(Constants_Tgammal_log_80_h3_G_H#),gp
+ nop.i 0
+};;
+
+{ .mfi
+ ld8 GR_l_Log_Table = [GR_l_Log_Table]
+ fma.s1 FR_l_E2 = FR_l_E0,FR_l_E0,FR_l_E0 // e2 = e+e^2
+ nop.i 0
+}
+{ .mfi
+ ldfs FR_l_G_2 = [GR_l_Index2],4
+ fma.s1 FR_l_E1 = FR_l_E0,FR_l_E0,f0 // e1 = e^2
+ nop.i 0
+};;
+
+{ .mmi
+ ldfs FR_l_H_2 = [GR_l_Index2],8
+(p15) ldfe FR_n_A5 = [GR_n_sin_Table], 16
+ nop.i 0
+};;
+
+{ .mfi
+ setf.sig FR_l_float_N = GR_l_N // float_N = Make N a fp number
+ nop.f 0
+ pmpyshr2.u GR_l_X_2 = GR_l_X_1,GR_l_Z_2,15 // X_2 = X_1 * Z_2
+}
+{ .mfi
+ ldfe FR_l_h_2 = [GR_l_Index2],0
+ fma.s1 FR_l_CXL = FR_l_AbsX, f1, FR_l_CXH // CXL = |X|+CXH
+ add GR_l_Log_Table1= 0x200, GR_l_Log_Table
+};;
+
+{ .mfi
+(p15) ldfe FR_n_A4 = [GR_n_sin_Table], 16
+(p15) fcmp.eq.unc.s1 p9,p0 = FR_l_AbsX, FR_c_XN //if argument is integer
+ // and negative
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_c_PosOverflow = [GR_c_Table],16 //Load pos overflow value
+(p15) fma.s1 FR_n_XS2 = FR_n_XS, FR_n_XS, f0 // xs^2 = xs*xs
+ nop.i 0
+};;
+
+{ .mfi
+(p15) ldfe FR_n_A3 = [GR_n_sin_Table], 16
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+(p15) getf.sig GR_n_XN = FR_n_IXN // int(x) to general reg
+ fma.s1 FR_l_Y1 = FR_l_Y0,FR_l_E2,FR_l_Y0 // y1 = y+y*e2
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fma.s1 FR_l_E3 = FR_l_E1,FR_l_E1,FR_l_E0 // e3 = e+e1^2
+(p9) br.cond.spnt tgammal_singularity // Singularity for integer /////////////
+ // and negative arguments //////////////
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_l_AbsX_m_Half = FR_l_AbsX, f1, FR_l_Half // |x|-0.5
+ extr.u GR_l_Index2 = GR_l_X_2, 1, 5 // Get Index3
+};;
+
+{ .mfi
+ shladd GR_l_Log_Table1= GR_l_Index2, 2, GR_l_Log_Table1
+ nop.f 0
+ shladd GR_l_Index3 = GR_l_Index2,4, GR_l_Log_Table // Index3
+}
+{ .mfb
+(p15) cmp.gtu.unc p11, p0 = GR_n_XN, GR_c_NegUnderflow // X < -1765
+ fms.s1 FR_l_CXL = FR_l_CH, f1, FR_l_CXL // CXL = CH - CXL
+(p11) br.cond.spnt tgammal_underflow // Singularity for negative argument //////
+ // at underflow domain (X < -1765) //////
+};;
+
+{ .mfi
+ addl GR_l_Log_Table = @ltoff(Constants_Tgammal_log_80_Q#), gp
+(p15) fma.s1 FR_n_TT = FR_n_A2L, FR_n_XS2, f0 // T=A2L*x^2
+ tbit.nz.unc p13, p12 = GR_n_XN, 0x0 // whether [X] odd or even
+}
+{ .mfi
+ nop.m 0
+(p15) fms.s1 FR_n_XS2L = FR_n_XS, FR_n_XS, FR_n_XS2 // xs^2 Low part
+ nop.i 0
+};;
+
+{ .mfi
+ ld8 GR_l_Log_Table = [GR_l_Log_Table]
+(p15) fma.s1 FR_n_A7 = FR_n_A8, FR_n_XS2, FR_n_A7 // poly tail
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_l_h_3 = [GR_l_Index3],12
+(p15) fma.s1 FR_n_XS4 = FR_n_XS2, FR_n_XS2, f0 // xs^4 = xs^2*xs^2
+ nop.i 0
+};;
+
+{ .mfi
+ ldfs FR_l_H_3 = [GR_l_Log_Table1], 0
+ fma.s1 FR_l_Y2 = FR_l_Y1, FR_l_E3, FR_l_Y0 // y2 = y+y1*e3
+ nop.i 0
+}
+{ .mfi
+ ldfs FR_l_G_3 = [GR_l_Index3], 0
+ fnma.s1 FR_l_Z = FR_l_AbsX,FR_l_Q0,f1 // r = a-b*q
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_l_G = FR_l_G_1, FR_l_G_2 // G = G1 * G_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_l_H = FR_l_H_1, FR_l_H_2 // H = H_1 + H_2
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_l_log2_hi = [GR_l_Log_Table],16 // load log2_hi part
+ fadd.s1 FR_l_h = FR_l_h_1, FR_l_h_2 // h = h_1 + h_2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fcvt.xf FR_l_float_N = FR_l_float_N // int(N)
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_l_log2_lo = [GR_l_Log_Table],16 // Load log2_lo part
+ fma.s1 FR_l_CXL = FR_l_CXL, f1, FR_l_CL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_TT = FR_n_A2H, FR_n_XS2L, FR_n_TT // T=A2H*x2L+T
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_l_Q_6 = [GR_l_Log_Table],16
+(p15) fma.s1 FR_n_A3 = FR_n_A4, FR_n_XS2, FR_n_A3 // poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_A5 = FR_n_A6, FR_n_XS2, FR_n_A5 // poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_l_Q_5 = [GR_l_Log_Table],16
+(p15) fabs FR_n_XS = FR_n_XS // abs(xs)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_Z = FR_l_Z,FR_l_Y2,FR_l_Q0 // x_hi = q+r*y2
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_l_Q_4 = [GR_l_Log_Table],16
+(p15) fma.s1 FR_n_A7 = FR_n_A9, FR_n_XS4, FR_n_A7 // poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_XS7 = FR_n_XS4, FR_n_XS2, f0 // = x^4*x^2
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_l_Q_3 = [GR_l_Log_Table],16
+ fneg FR_n_NegOne = f1 // -1.0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_XS8 = FR_n_XS4, FR_n_XS4, f0 // xs^8 = xs^4*xs^4
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_l_Q_2 = [GR_l_Log_Table],16
+ fadd.s1 FR_l_h = FR_l_h, FR_l_h_3 // h = h_1 + h_2 + h_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_TH = FR_n_A2H, FR_n_XS2, FR_n_TT // A2H*xs2+T
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_l_Q_1 = [GR_l_Log_Table],16
+ fmpy.s1 FR_l_G = FR_l_G, FR_l_G_3 // G = G_1 * G_2 * G_3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_l_H = FR_l_H, FR_l_H_3 // H = H_1 + H_2 + H_3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_Z2 = FR_l_Z, FR_l_Z, f0 // Z^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_A3 = FR_n_A5, FR_n_XS4, FR_n_A3 // poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p14) fcmp.gt.unc.s1 p7,p0 = FR_l_AbsX, FR_c_PosOverflow //X > 1755.5483
+ // (overflow domain, result cannot be represented by normal value)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_XS7 = FR_n_XS7, FR_n_XS, f0 // x^7 construction
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fms.s1 FR_n_TL = FR_n_A2H, FR_n_XS2, FR_n_TH // A2H*xs2+TH
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_PolyH = FR_n_TH, f1, FR_n_A1H // PolyH=TH+A1H
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_l_GS_hi = FR_l_G, FR_l_S // GS_hi = G*S
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ fms.s1 FR_l_r = FR_l_G, FR_l_S, f1 // r = G*S -1
+(p7) br.cond.spnt tgammal_overflow // Overflow path for arg > 1755.5483 //////
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_B14 = FR_l_B16, FR_l_Z2, FR_l_B14// bernulli tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_Z4 = FR_l_Z2, FR_l_Z2, f0 // Z^4 = Z^2*Z^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_B2 = FR_l_B4, FR_l_Z2, FR_l_B2 // bernulli tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_B6 = FR_l_B8, FR_l_Z2, FR_l_B6 // bernulli tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_B10 = FR_l_B12, FR_l_Z2, FR_l_B10// bernulli tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_Tail = FR_n_A7, FR_n_XS8, FR_n_A3 // poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_TL = FR_n_TL, f1, FR_n_TT // TL = TL+T
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fms.s1 FR_n_PolyL = FR_n_A1H, f1, FR_n_PolyH // polyH+A1H
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_poly_lo = FR_l_r, FR_l_Q_6, FR_l_Q_5 // Q_5+r*Q_6
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 FR_l_r_cor = FR_l_GS_hi, f1 // r_cor = GS_hi -1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_l_GS_lo = FR_l_G, FR_l_S, FR_l_GS_hi // G*S-GS_hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_poly = FR_l_r, FR_l_Q_2, FR_l_Q_1 //poly=r*Q2+Q1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_l_rsq = FR_l_r, FR_l_r // rsq = r * r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_G = FR_l_float_N, FR_l_log2_hi, FR_l_H // Tbl =
+ // float_N*log2_hi + H
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_Y_lo = FR_l_float_N, FR_l_log2_lo, FR_l_h // Y_lo=
+ // float_N*log2_lo + h
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_B14 = FR_l_B18, FR_l_Z4, FR_l_B14 //bernulli tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_B2 = FR_l_B6, FR_l_Z4, FR_l_B2 //bernulli tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_Z8 = FR_l_Z4, FR_l_Z4, f0 //bernulli tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_poly_lo = FR_l_r, FR_l_poly_lo, FR_l_Q_4 // poly_lo =
+ // Q_4 + r * poly_lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fsub.s1 FR_l_r_cor = FR_l_r_cor, FR_l_r // r_cor = r_cor - r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_PolyL = FR_n_PolyL, f1, FR_n_TH // polyL+TH
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_TT = FR_n_TL, f1, FR_n_A1L // TL+A1L
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_l_logl_YHi = FR_l_G, FR_l_r // Y_hi = Tbl + r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_B10 = FR_l_B14, FR_l_Z4, FR_l_B10 //bernulli tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_poly_lo = FR_l_r, FR_l_poly_lo, FR_l_Q_3 // poly_lo =
+ // Q_3 + r * poly_lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_l_r_cor = FR_l_r_cor, FR_l_GS_lo // r_cor=r_cor+GS_lo
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_PolyL = FR_n_PolyL, f1, FR_n_TT // polyL+TT
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fsub.s1 FR_l_Y_lo_res = FR_l_G, FR_l_logl_YHi // Y_lo = Tbl - Y_hi
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_XYH = FR_l_logl_YHi, FR_l_AbsX_m_Half, f0 // XYH=
+ // YHi*|x-0.5|
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_SS = FR_l_B10, FR_l_Z8, FR_l_B2 // bernulli tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_l_r_cor = FR_l_r_cor, FR_l_Y_lo // r_cor = r_cor+Y_lo
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_poly = FR_l_rsq, FR_l_poly_lo, FR_l_poly //poly=
+ // r^2*polyLo+poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_TT = FR_n_PolyL, FR_n_XS2, f0 // T=polyL*xs^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_l_Y_lo = FR_l_Y_lo_res, FR_l_r // Y_lo = Y_lo + r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_l_XYL = FR_l_logl_YHi, FR_l_AbsX_m_Half, FR_l_XYH
+ // XYL = YHi*|x-0.5|-XYH
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_SSCXH = FR_l_SS, FR_l_Z, FR_l_CXH // SS*Z+CXH
+ nop.i 0
+}
+{ .mfi
+ mov GR_e_exp_2tom51= 0xffff-51 // 2^-51
+(p15) fma.s1 FR_l_SignedXYH = FR_l_XYH, FR_n_NegOne, f0 // XYH = -XYH
+ // for negatives
+ nop.i 0
+};;
+
+{ .mlx
+ nop.m 0
+ movl GR_e_rshf_2to51 = 0x4718000000000000 // 1.10000 2^(63+51)
+}
+{ .mlx
+ nop.m 0
+ movl GR_e_sig_inv_ln2 = 0xb8aa3b295c17f0bc //significand of 1/ln2
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_poly = FR_l_rsq, FR_l_poly, FR_l_r_cor // poly =
+ // rsq * poly + r_cor
+ nop.i 0
+};;
+
+{ .mfi
+ addl GR_e_ad_Arg = @ltoff(Constants_Tgammal_exp_64_Arg#),gp
+(p15) fma.s1 FR_n_TT = FR_n_PolyH, FR_n_XS2L, FR_n_TT
+ mov GR_e_exp_mask = 0x1FFFF // Form exponent mask
+}
+{ .mlx
+ nop.m 0
+ movl GR_e_rshf = 0x43e8000000000000 // 1.10000 2^63 rshift
+};;
+
+
+{ .mmi
+ setf.sig FR_e_INV_LN2_2TO63 = GR_e_sig_inv_ln2 // form 1/ln2 * 2^63
+ setf.d FR_e_RSHF_2TO51 = GR_e_rshf_2to51 // 1.1000 * 2^(63+51)
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_l_SSCXL = FR_l_CXH, f1, FR_l_SSCXH // CXH+SS*CXH
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_expl_Input_AbsX = FR_l_XYH, f1, FR_l_SSCXH // HI EXP
+ nop.i 0
+};;
+
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_e_expl_Input_X = FR_l_XYH, f1, FR_l_SSCXH // HI EXP
+ mov GR_e_exp_bias = 0x0FFFF // Set exponent bias
+}
+{ .mfi
+ ld8 GR_e_ad_Arg = [GR_e_ad_Arg] // Point to Arg table
+(p15) fms.s1 FR_e_expl_Input_X = FR_l_SignedXYH, f1, FR_l_SSCXH // HI EXP
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_l_logl_YLo = FR_l_Y_lo, FR_l_poly // YLo = YLo+poly
+ nop.i 0
+};;
+
+{ .mfi
+ setf.exp FR_e_2TOM51 = GR_e_exp_2tom51 //2^-51 for scaling float_N
+(p15) fma.s1 FR_n_TH = FR_n_PolyH, FR_n_XS2, FR_n_TT // TH=
+ // polyH*xs^2+T
+ nop.i 0
+}
+{ .mib
+ setf.d FR_e_RSHF = GR_e_rshf // Right shift const 1.1000*2^63
+ nop.i 0
+ nop.b 0
+};;
+
+{ .mfi
+ add GR_e_ad_A = 0x20, GR_e_ad_Arg // Point to A table
+ nop.f 0
+ add GR_e_ad_T1 = 0x50, GR_e_ad_Arg // Point to T1 table
+}
+{ .mfi
+ add GR_e_ad_T2 = 0x150, GR_e_ad_Arg // Point to T2 table
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_SSCXL = FR_l_SS, FR_l_Z, FR_l_SSCXL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_e_expl_Input_Y = FR_l_XYH, f1, FR_e_expl_Input_AbsX
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_e_L_hi = [GR_e_ad_Arg],16 // Get L_hi
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_XYL = FR_l_logl_YLo, FR_l_AbsX_m_Half, FR_l_XYL
+ // XYL = YLo*|x-0.5|+XYL
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_e_L_lo = [GR_e_ad_Arg],16 // Get L_lo
+(p15) fms.s1 FR_n_TL = FR_n_PolyH, FR_n_XS2, FR_n_TH // TL =
+ // = polyH*xs^2-TH
+ add GR_e_ad_W1 = 0x100, GR_e_ad_T2 // Point to W1 table
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_Poly1H = FR_n_TH, f1, f1 // poly1H = TH+1
+ add GR_e_ad_W2 = 0x300, GR_e_ad_T2 // Point to W2 table
+};;
+
+{ .mmi
+ getf.exp GR_e_signexp_x = FR_e_expl_Input_X // Extract sign and exp
+ ldfe FR_e_A3 = [GR_e_ad_A],16 // Get A3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_SSCXL = FR_l_SSCXL, f1, FR_l_CXL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_expl_Input_Y = FR_e_expl_Input_Y, f1, FR_l_SSCXH
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_N_signif=FR_e_expl_Input_X,FR_e_INV_LN2_2TO63,FR_e_RSHF_2TO51
+ and GR_e_exp_x = GR_e_signexp_x, GR_e_exp_mask
+};;
+
+{ .mmi
+ sub GR_e_exp_x = GR_e_exp_x, GR_e_exp_bias // Get exponent
+ ldfe FR_e_A2 = [GR_e_ad_A],16 // Get A2 for main path
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_PolyH = FR_n_Poly1H, FR_n_XS, f0//sin(Pi*x) poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fms.s1 FR_n_Poly1L = f1, f1, FR_n_Poly1H//sin(Pi*x) poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_TL = FR_n_TL, f1, FR_n_TT//sin(Pi*x) poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_l_Temp = FR_l_XYL, f1, FR_l_SSCXL // XYL+SS*CXL
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_e_expl_Input_Y = FR_e_expl_Input_Y, FR_n_NegOne, f0
+ // Negate lo part of exp argument for negative input values
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_e_A1 = [GR_e_ad_A],16 // Get A1
+ nop.f 0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_e_float_N = FR_e_N_signif, FR_e_2TOM51, FR_e_RSHF
+ // Get float N = signd*2^51-RSHIFTER
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_Poly1L = FR_n_Poly1L, f1, FR_n_TH //sin(Pi*x) poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fms.s1 FR_n_PolyL = FR_n_Poly1H, FR_n_XS, FR_n_PolyH//sin(Pi*x)
+ nop.i 0
+};;
+
+{ .mfi
+ getf.sig GR_e_N_fix = FR_e_N_signif // Get N from significand
+ nop.f 0
+ nop.i 0
+};;
+
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_e_expl_Input_Y = FR_e_expl_Input_Y, f1, FR_l_Temp
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fms.s1 FR_e_expl_Input_Y = FR_e_expl_Input_Y, f1, FR_l_Temp
+ // arguments for exp computation
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_e_r = FR_e_L_hi, FR_e_float_N, FR_e_expl_Input_X
+ // r = -L_hi * float_N + x
+ extr.u GR_e_M1 = GR_e_N_fix, 6, 6 // Extract index M_1
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_Poly1L = FR_n_Poly1L, f1, FR_n_TL //sin(Pi*x) poly
+ nop.i 0
+};;
+
+
+{ .mmf
+ nop.m 0
+ nop.m 0
+ fma.s1 FR_e_r = FR_e_r, f1, FR_e_expl_Input_Y
+ // r = r + FR_e_expl_Input_Y
+};;
+
+{ .mmi
+ shladd GR_e_ad_W1 = GR_e_M1,3,GR_e_ad_W1 // Point to W1
+ shladd GR_e_ad_T1 = GR_e_M1,2,GR_e_ad_T1 // Point to T1
+ extr.u GR_e_M2 = GR_e_N_fix, 0, 6 // Extract index M_2
+};;
+
+
+{ .mfi
+ ldfs FR_e_T1 = [GR_e_ad_T1],0 // Get T1
+ nop.f 0
+ extr GR_e_K = GR_e_N_fix, 12, 32 //Extract limit range K
+}
+{ .mfi
+ shladd GR_e_ad_T2 = GR_e_M2,2,GR_e_ad_T2 // Point to T2
+(p15) fma.s1 FR_n_PolyL = FR_n_Poly1L, FR_n_XS, FR_n_PolyL
+ //sin(Pi*x) poly
+ shladd GR_e_ad_W2 = GR_e_M2,3,GR_e_ad_W2 // Point to W2
+};;
+
+{ .mfi
+ ldfs FR_e_T2 = [GR_e_ad_T2],0 // Get T2
+ nop.f 0
+ add GR_e_exp_2_k = GR_e_exp_bias, GR_e_K // exp of 2^k
+}
+{ .mfi
+ ldfd FR_e_W1 = [GR_e_ad_W1],0 // Get W1
+ nop.f 0
+ sub GR_e_exp_2_mk = GR_e_exp_bias, GR_e_K // exp of 2^-k
+};;
+
+{ .mmi
+ ldfd FR_e_W2 = [GR_e_ad_W2],0 // Get W2
+ nop.m 0
+ nop.i 0
+};;
+
+{ .mmf
+ setf.exp FR_e_scale = GR_e_exp_2_k // Set scale = 2^k
+ setf.exp FR_e_2_mk = GR_e_exp_2_mk // Form 2^-k
+ fnma.s1 FR_e_r = FR_e_L_lo, FR_e_float_N, FR_e_r
+ // r = -L_lo * float_N + r
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_PolyL = FR_n_Tail, FR_n_XS7, FR_n_PolyL
+ //sin(Pi*x) poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_poly = FR_e_r, FR_e_A3, FR_e_A2 // poly=r*A3+A2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_e_rsq = FR_e_r, FR_e_r // rsq = r * r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fmpy.s1 FR_e_T = FR_e_T1, FR_e_T2 // T = T1 * T2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fadd.s1 FR_e_W1_p1 = FR_e_W1, f1 // W1_p1 = W1 + 1.0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_TT = FR_n_PolyL, FR_l_AbsX, f0 //sin(Pi*x) poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_poly = FR_e_r, FR_e_poly, FR_e_A1
+ // poly = r * poly + A1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_T_scale = FR_e_T, FR_e_scale, f0 // T_scale=T*scale
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_W = FR_e_W2, FR_e_W1_p1, FR_e_W1
+ // W = W2 * (W1+1.0) + W1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_SinxH = FR_n_PolyH, FR_l_AbsX, FR_n_TT
+ // sin(Pi*x) poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ mov FR_e_Y_hi = FR_e_T // Assume Y_hi = T
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_poly = FR_e_rsq, FR_e_poly, FR_e_r
+ // poly = rsq * poly + r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_Wp1_T_scale = FR_e_W, FR_e_T_scale, FR_e_T_scale
+ // (W+1)*T*scale
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_W_T_scale = FR_e_W, FR_e_T_scale, f0 // W*T*scale
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fms.s1 FR_n_SinxL = FR_n_PolyH, FR_l_AbsX, FR_n_SinxH
+ // Low part of sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) frcpa.s1 FR_n_Y0, p0 = f1, FR_n_SinxH // y = frcpa(b)
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_result_lo = FR_e_Wp1_T_scale, FR_e_poly, FR_e_W_T_scale
+ // Low part of exp result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_SinxL = FR_n_SinxL, f1, FR_n_TT // sin low result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p15) fma.s1 FR_n_Q0 = f1,FR_n_Y0,f0 // q = y
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p15) fnma.s1 FR_n_E0 = FR_n_Y0, FR_n_SinxH, f1 // e = 1-b*y
+ nop.i 0
+};;
+
+
+{ .mfb
+ nop.m 0
+(p14) fma.s0 f8 = FR_e_Y_hi, FR_e_scale, FR_e_result_lo
+(p14) br.ret.spnt b0 // Exit for positive Stirling path //////////////////////
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_expl_Output_X = FR_e_Y_hi, FR_e_scale, f0 // exp result
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_e_expl_Output_Y = FR_e_result_lo, f1, f0// exp lo result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_n_E2 = FR_n_E0,FR_n_E0,FR_n_E0 // e2 = e+e^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_n_E1 = FR_n_E0,FR_n_E0,f0 // e1 = e^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_n_Y1 = FR_n_Y0,FR_n_E2,FR_n_Y0 // y1 = y+y*e2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_n_E3 = FR_n_E1,FR_n_E1,FR_n_E0 // e3 = e+e1^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_n_Y2 = FR_n_Y1,FR_n_E3,FR_n_Y0 // y2 = y+y1*e3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_n_R0 = FR_n_SinxH,FR_n_Q0,f1 // r = a-b*q
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_n_E4 = FR_n_SinxH,FR_n_Y2,f1 // e4 = 1-b*y2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_n_RcpResH = FR_n_R0,FR_n_Y2,FR_n_Q0 // x = q+r*y2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_n_Y3 = FR_n_Y2,FR_n_E4,FR_n_Y2 // y3 = y2+y2*e4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_n_R1 = FR_n_SinxH,FR_n_RcpResH,f1 // r1 = a-b*x
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_n_R1 = FR_n_SinxL,FR_n_RcpResH,FR_n_R1
+ // r1 = r1 - b_lo*X
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_n_RcpResL = FR_n_R1,FR_n_Y3,f0 // x_lo = r1*y3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_n_Temp = FR_n_RcpResH, FR_e_expl_Output_Y, f0
+ // Multiplying exp and sin result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_n_Temp = FR_n_RcpResL, FR_e_expl_Output_X, FR_n_Temp
+ // Multiplying exp and sin result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_n_ResH = FR_n_RcpResH, FR_e_expl_Output_X, FR_n_Temp
+ // Multiplying exp and sin result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_n_ResL = FR_n_RcpResH, FR_e_expl_Output_X, FR_n_ResH
+ // Multiplying exp and sin result
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p12) fma.s1 FR_n_ResH = FR_n_ResH, FR_n_NegOne, f0 // Negate
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_n_ResL = FR_n_ResL, f1, FR_n_Temp
+ // Multiplying exp and sin result - low result obtained
+ nop.i 0
+};;
+
+.pred.rel "mutex",p12,p13
+{ .mfi
+ nop.m 0
+(p13) fma.s0 f8 = FR_n_ResH, f1, FR_n_ResL // For odd
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p12) fms.s0 f8 = FR_n_ResH, f1, FR_n_ResL // For even
+ br.ret.sptk b0 // Exit for negative Stirling path //////////////////////
+};;
+
+
+//////////// 1 <= |X| < 13 path ////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+.align 64
+tgamma_lt_13:
+{ .mfi
+ getf.sig GR_p_XN = FR_p_IXN // Get significand
+ fcvt.xf FR_p_XN = FR_p_IXN // xn = [x]
+ add GR_r_sin_Table2= 0x40, GR_r_sin_Table // Shifted table addr.
+}
+{ .mfi
+ ldfpd FR_p_0p5, FR_p_1p5 = [GR_c_Table], 16 // 0.5 & 1.5
+ fms.s1 FR_p_AbsXM1 = FR_p_AbsX, f1, f1 // X-1
+ add GR_p_Table2 = 0xB0, GR_p_Table
+};;
+
+{ .mfi
+ add GR_r_sin_Table = -16, GR_r_sin_Table // For compensation
+ fcvt.xf FR_r_XNS = FR_r_IXNS // Convert int repr to float
+ shr.u GR_p_X_Sgnd = GR_p_X_Sgnd, 59 // Get only 5 bit of signd
+};;
+
+{ .mfi
+ ldfpd FR_r_A2H,FR_r_A2L = [GR_r_sin_Table], 16 // Load A2
+ nop.f 0
+ add GR_p_Int = -2, GR_p_XN // int = int - 2
+}
+{ .mfi
+ ldfe FR_r_A6 = [GR_r_sin_Table2], 16
+ nop.f 0
+ cmp.gtu p11, p12 = 0x2, GR_p_XN // p11: x < 2 (splitted intervals),
+ // p12: x > 2 (base intervals)
+};;
+
+{ .mfi
+ ldfpd FR_r_A1H, FR_r_A1L = [GR_r_sin_Table], 16
+ nop.f 0
+ shr GR_p_Int = GR_p_Int, 1 // int/2
+}
+{ .mfi
+ ldfe FR_r_A5 = [GR_r_sin_Table2], 16
+ nop.f 0
+(p11) cmp.gtu.unc p10, p11 = 0x1C, GR_p_X_Sgnd // sgnd(x) < 0.75
+};;
+
+{ .mfi
+ ldfe FR_r_A9 = [GR_r_sin_Table], 16
+ nop.f 0
+ shl GR_p_Offset = GR_p_Int, 4 // offset = int*16
+}
+{ .mfi
+ ldfe FR_r_A4 = [GR_r_sin_Table2], 16
+ nop.f 0
+(p10) cmp.gtu.unc p9, p10 = 0x14, GR_p_X_Sgnd // sgnd(x) < 0.25
+};;
+
+
+{ .mfi
+ ldfe FR_r_A8 = [GR_r_sin_Table], 16
+ nop.f 0
+(p12) tbit.nz.unc p13, p12 = GR_p_XN, 0x0 // p13: reccurent computations
+ // X is at [3;4], [5;6], [7;8]... interval
+}
+{ .mfi
+ ldfe FR_r_A3 = [GR_r_sin_Table2], 16
+ nop.f 0
+ shladd GR_p_Offset = GR_p_Int, 2, GR_p_Offset // +int*4
+};;
+
+.pred.rel "mutex",p9,p11
+{ .mfi
+ add GR_p_Offset = GR_p_Int, GR_p_Offset
+ // +int, so offset = int*21
+(p9) fms.s1 FR_p_XR = FR_p_AbsX, f1, f1 // r = x-1
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_r_A7 = [GR_r_sin_Table], 16
+(p11) fms.s1 FR_p_XR = FR_p_2, f1, FR_p_AbsX
+ // r = 2-x for 1.75 < x < 2
+ nop.i 0
+};;
+
+.pred.rel "mutex",p9,p10
+.pred.rel "mutex",p10,p11
+.pred.rel "mutex",p9,p11
+{ .mfi
+(p9) add GR_p_Offset = 126, r0 // 1.0 < x < 1.25 table
+(p15) fcmp.eq.unc.s1 p7,p0 = FR_p_AbsX, FR_p_XN
+ // If arg is integer and negative - singularity branch
+ nop.i 0
+}
+{ .mfi
+(p10) add GR_p_Offset = 147, r0 // 1.25 < x < 1.75 table
+ nop.f 0
+(p11) add GR_p_Offset = 168, r0 // 1.75 < x < 2.0 table
+};;
+
+{ .mmf
+ shladd GR_p_Table = GR_p_Offset, 4, GR_p_Table
+ shladd GR_p_Table2 = GR_p_Offset, 4, GR_p_Table2
+ fma.s1 FR_r_XS = FR_r_AbsX , f1, FR_r_XNS // xs = x - [x]
+};;
+
+{ .mmb
+ ldfpd FR_p_A5H, FR_p_A5L = [GR_p_Table], 16
+ ldfpd FR_p_A2H, FR_p_A2L = [GR_p_Table2], 16
+(p7) br.cond.spnt tgammal_singularity // Singularity for integer /////////////
+ // and negative argument ///////////////
+};;
+
+{ .mfi
+ ldfpd FR_p_A4H, FR_p_A4L = [GR_p_Table], 16
+ fma.s1 FR_p_XN = FR_p_XN, f1, FR_p_0p5 // xn = xn+0.5
+ nop.i 0
+}
+{ .mfi
+ ldfpd FR_p_A1H, FR_p_A1L = [GR_p_Table2], 16
+(p10) fms.s1 FR_p_XR = FR_p_AbsX, f1, FR_p_1p5 // r = x - 1.5
+ nop.i 0
+};;
+
+{ .mmi
+ ldfpd FR_p_A3H, FR_p_A3L = [GR_p_Table], 16
+ ldfpd FR_p_A0H, FR_p_A0L = [GR_p_Table2], 16
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe FR_p_A20 = [GR_p_Table], 16
+ ldfe FR_p_A12 = [GR_p_Table2], 16
+ nop.i 0
+};;
+
+{ .mmf
+ ldfe FR_p_A19 = [GR_p_Table], 16
+ ldfe FR_p_A11 = [GR_p_Table2], 16
+ fma.s1 FR_r_XS2 = FR_r_XS, FR_r_XS, f0 // xs2 = xs*xs
+};;
+
+{ .mmi
+ ldfe FR_p_A18 = [GR_p_Table], 16
+ ldfe FR_p_A10 = [GR_p_Table2], 16
+ nop.i 0
+};;
+
+.pred.rel "mutex",p12,p13
+{ .mfi
+ ldfe FR_p_A17 = [GR_p_Table], 16
+(p12) fms.s1 FR_p_XR = FR_p_AbsX, f1, FR_p_XN // r = x - xn
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_p_A9 = [GR_p_Table2], 16
+(p13) fms.s1 FR_p_XR = FR_p_AbsX, f1, FR_p_XN
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe FR_p_A16 = [GR_p_Table], 16
+ ldfe FR_p_A8 = [GR_p_Table2], 16
+(p9) cmp.eq p12, p0 = r0, r0 // clear p12
+};;
+
+{ .mmi
+ ldfe FR_p_A15 = [GR_p_Table], 16
+ ldfe FR_p_A7 = [GR_p_Table2], 16
+(p10) cmp.eq p12, p0 = r0, r0 // clear p12
+};;
+
+{ .mfi
+ ldfe FR_p_A14 = [GR_p_Table], 16
+ fma.s1 FR_r_TH = FR_r_A2H, FR_r_XS2, f0 // sin for neg
+(p11) cmp.eq p12, p0 = r0, r0 // clear p12
+}
+{ .mfi
+ ldfe FR_p_A6 = [GR_p_Table2], 16
+ fma.s1 FR_r_TL = FR_r_A2L, FR_r_XS2, f0 // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_p_A13 = [GR_p_Table], 16
+ fms.s1 FR_r_XS2L = FR_r_XS, FR_r_XS, FR_r_XS2 // x2Lo part
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp5H = FR_p_A5H, FR_p_XR, f0 // A5H*r
+ // 'Low poly'
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_XR2 = FR_p_XR, FR_p_XR, f0 // r^2 = r*r
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fabs FR_r_XS = FR_r_XS // abs(xs)
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp2H = FR_p_A2H, FR_p_XR, f0 // A2H*r
+ // 'High poly'
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_TT = FR_r_A2H, FR_r_XS2, FR_r_TH // sin for neg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResH = FR_r_TH, f1, FR_r_A1H // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_r_A2H, FR_r_XS2L, FR_r_TL // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Temp5L = FR_p_A5H,FR_p_XR,FR_p_Temp5H //A5H*r delta
+ // 'Low poly'
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly5H = FR_p_Temp5H, f1, FR_p_A4H // A5H*r+A4H
+ // 'Low poly'
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Temp2L = FR_p_A2H, FR_p_XR, FR_p_Temp2H//A2H*r delta
+ //'High poly'
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly2H = FR_p_Temp2H, f1, FR_p_A1H // A2H*r+A1H
+ //'High poly'
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_XR3 = FR_p_XR2, FR_p_XR, f0 // r^3 = r^2*r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_XR2L = FR_p_XR, FR_p_XR, FR_p_XR2 // r^2 delta
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A18 = FR_p_A19, FR_p_XR, FR_p_A18 // Poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A14 = FR_p_A15, FR_p_XR, FR_p_A14 // Poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_XR4 = FR_p_XR2, FR_p_XR2, f0 // r^4 = r^2*r^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp5L = FR_p_A5L, FR_p_XR, FR_p_Temp5L// Low part
+ // of A5*r+A4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Poly5L = FR_p_A4H, f1, FR_p_Poly5H // Low part
+ // of A5*r+A4
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp4H = FR_p_Poly5H, FR_p_XR, f0 // (A5H*r+A4H)*r
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp2L = FR_p_A2L, FR_p_XR, FR_p_Temp2L // A2*r low
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Poly2L = FR_p_A1H, f1, FR_p_Poly2H // High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp1H = FR_p_Poly2H, FR_p_XR, f0 // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_XR3L = FR_p_XR2, FR_p_XR, FR_p_XR3 // x^3 delta
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A16 = FR_p_A17, FR_p_XR, FR_p_A16 // Poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_ResL = FR_r_A1H, f1, FR_r_ResH // sin for neg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_r_TL, f1, FR_r_TT // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp5L = FR_p_Temp5L, f1, FR_p_A4L // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly5L = FR_p_Poly5L, f1, FR_p_Temp5H // Low poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Temp4L = FR_p_Poly5H,FR_p_XR,FR_p_Temp4H //Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly4H = FR_p_Temp4H, f1, FR_p_A3H // Low poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp2L = FR_p_Temp2L, f1, FR_p_A1L // High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly2L = FR_p_Poly2L, f1, FR_p_Temp2H // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Temp1L = FR_p_Poly2H,FR_p_XR,FR_p_Temp1H //High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly1H = FR_p_Temp1H, f1, FR_p_A0H // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A12 = FR_p_A13, FR_p_XR, FR_p_A12 // Poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_XR3L = FR_p_XR2L, FR_p_XR, FR_p_XR3L // x^3 low
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly5L = FR_p_Poly5L, f1, FR_p_Temp5L // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A10 = FR_p_A11, FR_p_XR, FR_p_A10 // Poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Poly4L = FR_p_A3H, f1, FR_p_Poly4H // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A6 = FR_p_A7, FR_p_XR, FR_p_A6 // Poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A8 = FR_p_A9, FR_p_XR, FR_p_A8 // Poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_XR6 = FR_p_XR4, FR_p_XR2, f0 // Poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly2L = FR_p_Poly2L, f1, FR_p_Temp2L // High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Poly1L = FR_p_A0H, f1, FR_p_Poly1H // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResL = FR_r_ResL, f1, FR_r_TH // sin for neg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TT = FR_r_TL, f1, FR_r_A1L // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp4L = FR_p_Poly5L,FR_p_XR,FR_p_Temp4L // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A18 = FR_p_A20, FR_p_XR2, FR_p_A18 // Poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly4L = FR_p_Poly4L, f1, FR_p_Temp4H // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A14 = FR_p_A16, FR_p_XR2, FR_p_A14 // Poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A6 = FR_p_A8, FR_p_XR2, FR_p_A6 // Poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A10 = FR_p_A12, FR_p_XR2, FR_p_A10 // Poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp1L = FR_p_Poly2L,FR_p_XR,FR_p_Temp1L //High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly1L = FR_p_Poly1L, f1, FR_p_Temp1H // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResL = FR_r_ResL, f1, FR_r_TT // sin for neg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TH = FR_r_ResH, FR_r_XS2, f0 // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp4L = FR_p_Temp4L, f1, FR_p_A3L // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly3H = FR_p_Poly4H, FR_p_XR3, f0 // Low poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A14 = FR_p_A18, FR_p_XR4, FR_p_A14 // Poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_XR8 = FR_p_XR4, FR_p_XR4, f0 // Poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_r_ResH, FR_r_XS2L, f0 // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp1L = FR_p_Temp1L, f1, FR_p_A0L // High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A6 = FR_p_A10, FR_p_XR4, FR_p_A6 // Poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_TT = FR_r_ResH, FR_r_XS2, FR_r_TH // sin for neg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Res3H = FR_r_TH, f1, f1 // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly4L = FR_p_Poly4L, f1, FR_p_Temp4L // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly3L = FR_p_Poly4H, FR_p_XR3L, f0 // Low poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly0H = FR_p_Poly3H,f1,FR_p_Poly1H //Low & High add
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_A7 = FR_r_A8, FR_r_XS2, FR_r_A7 // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_r_ResL, FR_r_XS2, FR_r_TL // sin for neg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_XS4 = FR_r_XS2, FR_r_XS2, f0 // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly1L = FR_p_Poly1L, f1, FR_p_Temp1L // High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_PolyTail = FR_p_A14, FR_p_XR8, FR_p_A6 // Poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_Res3L = f1, f1, FR_r_Res3H // sin for neg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResH = FR_r_Res3H, FR_r_XS, f0 // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Temp0L = FR_p_Poly4H,FR_p_XR3,FR_p_Poly3H //Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly3L = FR_p_Poly4L,FR_p_XR3,FR_p_Poly3L //Low poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Poly0L = FR_p_Poly1H,f1,FR_p_Poly0H //Low & High add
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_p_OddPoly0H = FR_p_Poly0H, FR_p_AbsXM1, f0
+ // Reccurent computations - multiplying by X-1
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_r_TL, f1, FR_r_TT // sin for neg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_A3 = FR_r_A4, FR_r_XS2, FR_r_A3 // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly1L = FR_p_PolyTail,FR_p_XR6,FR_p_Poly1L//High
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_A5 = FR_r_A6, FR_r_XS2, FR_r_A5 // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Res3L = FR_r_Res3L, f1, FR_r_TH // sin for neg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_ResL = FR_r_Res3H, FR_r_XS, FR_r_ResH//sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly3L = FR_p_Poly3L, f1, FR_p_Temp0L // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_A7 = FR_r_A9, FR_r_XS4, FR_r_A7 // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly0L = FR_p_Poly0L,f1,FR_p_Poly3H //Low & High add
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fms.s1 FR_p_OddPoly0L = FR_p_Poly0H, FR_p_AbsXM1, FR_p_OddPoly0H
+ // Reccurent computations - multiplying by X-1 (low part)
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_A3 = FR_r_A5, FR_r_XS4, FR_r_A3 // sin for neg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_XS7 = FR_r_XS4, FR_r_XS2, f0 // xs^6
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Res3L = FR_r_Res3L, f1, FR_r_TL // sin for neg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_XS8 = FR_r_XS4, FR_r_XS4, f0 // sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp0H = FR_p_Poly3L,f1,FR_p_Poly1L //Low & High add
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_XS7 = FR_r_XS7, FR_r_XS, f0 // xs^7
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResL = FR_r_Res3L, FR_r_XS, FR_r_ResL//sin for neg
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Tail = FR_r_A7, FR_r_XS8, FR_r_A3 // sin tail res
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly0L = FR_p_Poly0L,f1,FR_p_Temp0H //Low & High add
+ nop.i 0
+};;
+
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResL = FR_r_Tail,FR_r_XS7,FR_r_ResL //sin for neg
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_p_OddPoly0L = FR_p_Poly0L, FR_p_AbsXM1, FR_p_OddPoly0L
+ // Reccurent computations - multiplying by X-1 (low part)
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TT = FR_r_ResL, FR_r_AbsX, f0 // X*sin
+ nop.i 0
+};;
+
+.pred.rel "mutex",p12,p13
+{ .mfi
+ nop.m 0
+(p12) fma.s0 f8 = FR_p_Poly0H, f1, FR_p_Poly0L // Even
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p13) fma.s0 f8 = FR_p_OddPoly0H, f1, FR_p_OddPoly0L // Odd
+(p14) br.ret.spnt b0 // Exit for 1 <= |X| < 13 path (positive arguments)/////
+};;
+
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_p_Poly0H = FR_p_OddPoly0H, f1, f0
+ // Reccurent computations
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p13) fma.s1 FR_p_Poly0L = FR_p_OddPoly0L, f1, f0
+ // Reccurent computations
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Res1H = FR_r_ResH, FR_r_AbsX, FR_r_TT // X*sin
+(p11) cmp.eq p13, p12 = r0, r0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_Res1L = FR_r_ResH,FR_r_AbsX,FR_r_Res1H// X*sin
+(p9) cmp.eq p13, p12 = r0, r0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Res1L = FR_r_Res1L, f1, FR_r_TT // sin for neg
+(p10) cmp.eq p13, p12 = r0, r0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_p_Poly0L, FR_r_Res1H, f0 // mult by sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_p_Poly0H,FR_r_Res1L,FR_r_TL//mult by sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResH = FR_p_Poly0H,FR_r_Res1H,FR_r_TL//mult by sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_ResL = FR_p_Poly0H,FR_r_Res1H,FR_r_ResH//sin mult
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ frcpa.s1 FR_r_Y0,p0 = f1,FR_r_ResH // y = frcpa(b)
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fneg FR_r_NegOne = f1 // Form -1.0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResL = FR_r_ResL, f1, FR_r_TL //Low result of mult
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Q0 = f1,FR_r_Y0,f0 // q = a*y
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_r_E0 = FR_r_Y0,FR_r_ResH,f1 // e = 1-b*y
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_E2 = FR_r_E0,FR_r_E0,FR_r_E0 // e2 = e+e^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_E1 = FR_r_E0,FR_r_E0,f0 // e1 = e^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Y1 = FR_r_Y0,FR_r_E2,FR_r_Y0 // y1 = y+y*e2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_E3 = FR_r_E1,FR_r_E1,FR_r_E0 // e3 = e+e1^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Y2 = FR_r_Y1,FR_r_E3,FR_r_Y0 // y2 = y+y1*e3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_r_R0 = FR_r_ResH,FR_r_Q0,f1 // r = a-b*q
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_r_E4 = FR_r_ResH,FR_r_Y2,f1 // e4 = 1-b*y2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ZH = FR_r_R0,FR_r_Y2,FR_r_Q0 // x = q+r*y2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Y3 = FR_r_Y2,FR_r_E4,FR_r_Y2 // y3 = y2+y2*e4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_r_R1 = FR_r_ResH,FR_r_ZH,f1 // r1 = a-b*x
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_r_R1 = FR_r_ResL,FR_r_ZH,FR_r_R1 // r1=r1-b_lo*X
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+(p12) fma.s1 FR_r_ZHN = FR_r_ZH,FR_r_NegOne, f0 // Negate for evens
+ nop.i 0
+};;
+
+.pred.rel "mutex",p13,p12
+{ .mfi
+ nop.m 0
+(p13) fma.s0 f8 = FR_r_R1,FR_r_Y3,FR_r_ZH // Final result
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p12) fnma.s0 f8 = FR_r_R1,FR_r_Y3,FR_r_ZHN // Final result
+ br.ret.sptk b0 // Exit for 1 <= |X| < 13 path (negative arguments)//////
+};;
+
+
+//////////// |X| < 1 path /////////////////////////////////////////////////////
+//------------------------------------------------------------------------------
+.align 64
+tgamma_lt_1:
+{ .mfi
+ getf.exp GR_p_Exp = FR_p_AbsX // exp of abs X
+ fma.s1 FR_z_Q0 = f1,FR_z_Y0,f0 // q = a*y
+ add GR_r_sin_Table2= 0x50, GR_r_sin_Table
+}
+{ .mfi
+ ldfpd FR_p_0p5, FR_p_1p5 = [GR_c_Table], 16
+ fnma.s1 FR_z_E0 = FR_z_Y0,f8,f1 // e = 1-b*y
+ add GR_p_Table2 = 0xB0, GR_p_Table
+};;
+
+{ .mfi
+ ldfd FR_p_0p25 = [GR_c_Table]
+ fcvt.xf FR_r_XNS = FR_r_IXNS // Convert int repr to float
+ shr.u GR_p_X_Sgnd = GR_p_X_Sgnd, 60
+ // Obtain only 4 bits of significand
+}
+{ .mfi
+ nop.m 0
+ nop.f 0
+ add GR_p_Bias = 0xffff, r0 // Set bias
+};;
+
+{ .mfi
+ ldfpd FR_r_A2H, FR_r_A2L = [GR_r_sin_Table], 16
+ nop.f 0
+ shl GR_p_XN = GR_p_Exp, 4
+ // Shift exp to 4 bits left to set place for significand
+}
+{ .mlx
+ ldfe FR_r_A6 = [GR_r_sin_Table2], 16
+ movl GR_p_0p75 = 0xfffec // 0.75
+};;
+
+{ .mfi
+ ldfpd FR_r_A1H, FR_r_A1L = [GR_r_sin_Table], 16
+ nop.f 0
+ or GR_p_XN = GR_p_XN, GR_p_X_Sgnd
+ // Combine exp with 4 high bits of significand
+}
+{ .mfi
+ ldfe FR_r_A5 = [GR_r_sin_Table2], 16
+ nop.f 0
+ sub GR_p_Exp = GR_p_Exp, GR_p_Bias // Unbiased exp
+};;
+
+{ .mmi
+ ldfe FR_r_A9 = [GR_r_sin_Table], 16
+ ldfe FR_r_A4 = [GR_r_sin_Table2], 16
+ cmp.gtu.unc p10, p11 = GR_p_0p75, GR_p_XN // sgnd(x) < 0.75
+};;
+
+{ .mfi
+ ldfe FR_r_A8 = [GR_r_sin_Table], 16
+ fma.s1 FR_z_E2 = FR_z_E0,FR_z_E0,FR_z_E0 // e2 = e+e^2
+(p10) cmp.gt.unc p9, p10 = -2, GR_p_Exp // x < 0.25
+}
+{ .mfi
+ ldfe FR_r_A3 = [GR_r_sin_Table2], 16
+ fma.s1 FR_z_E1 = FR_z_E0,FR_z_E0,f0 // e1 = e^2
+(p11) add GR_p_Offset = 168, r0 // [0.75;1] interval
+};;
+
+{ .mmi
+(p10) add GR_p_Offset = 147, r0 // [0.25;0.75] interval
+ ldfe FR_r_A7 = [GR_r_sin_Table], 16
+(p9) cmp.gt.unc p8, p9 = -3, GR_p_Exp // x < 0.125
+};;
+
+.pred.rel "mutex",p9,p8
+{ .mmi
+(p9) add GR_p_Offset = 126, r0 // [0.125;0.25] interval
+(p8) add GR_p_Offset = 189, r0 // [0.;0.125] interval
+ nop.i 0
+};;
+
+{ .mmf
+ shladd GR_p_Table = GR_p_Offset, 4, GR_p_Table //Make addresses
+ shladd GR_p_Table2 = GR_p_Offset, 4, GR_p_Table2
+ fma.s1 FR_r_XS = FR_r_AbsX , f1, FR_r_XNS // xs = |x|-[x]
+};;
+
+.pred.rel "mutex",p8,p11
+{ .mfi
+ ldfpd FR_p_A5H, FR_p_A5L = [GR_p_Table], 16
+(p11) fms.s1 FR_p_XR = f1, f1, FR_p_AbsX // r = 1 - |x|
+ // for [0.75;1] interval
+ nop.i 0
+}
+{ .mfi
+ ldfpd FR_p_A2H, FR_p_A2L = [GR_p_Table2], 16
+(p8) fms.s1 FR_p_XR = FR_p_AbsX, f1, f0 // r = |x|
+ // for [0.;0.125] interval
+ nop.i 0
+};;
+
+{ .mfi
+ ldfpd FR_p_A4H, FR_p_A4L = [GR_p_Table], 16
+ fma.s1 FR_z_Y1 = FR_z_Y0,FR_z_E2,FR_z_Y0 // y1 = y+y*e2
+ nop.i 0
+}
+{ .mfi
+ ldfpd FR_p_A1H, FR_p_A1L = [GR_p_Table2], 16
+ fma.s1 FR_z_E3 = FR_z_E1,FR_z_E1,FR_z_E0 // e3 = e+e1^2
+ nop.i 0
+};;
+
+.pred.rel "mutex",p9,p10
+{ .mfi
+ ldfpd FR_p_A3H, FR_p_A3L = [GR_p_Table], 16
+(p9) fms.s1 FR_p_XR = FR_p_AbsX, f1, f0 // r = |x|
+ // for [0.125;0.25] interval
+ nop.i 0
+}
+{ .mfi
+ ldfpd FR_p_A0H, FR_p_A0L = [GR_p_Table2], 16
+(p10) fms.s1 FR_p_XR = FR_p_AbsX, f1, FR_p_0p5 // r = |x| - 0.5
+ // for [0.25;0.75] interval
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe FR_p_A20 = [GR_p_Table], 16
+ ldfe FR_p_A12 = [GR_p_Table2], 16
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_p_A19 = [GR_p_Table], 16
+ fma.s1 FR_r_XS2 = FR_r_XS, FR_r_XS, f0 // xs^2
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_p_A11 = [GR_p_Table2], 16
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe FR_p_A18 = [GR_p_Table], 16
+ ldfe FR_p_A10 = [GR_p_Table2], 16
+ nop.i 0
+};;
+
+.pred.rel "mutex",p12,p13
+{ .mfi
+ ldfe FR_p_A17 = [GR_p_Table], 16
+ fma.s1 FR_z_Y2 = FR_z_Y1,FR_z_E3,FR_z_Y0 // y2 = y+y1*e3
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_p_A9 = [GR_p_Table2], 16
+ fnma.s1 FR_z_R0 = f8,FR_z_Q0,f1 // r = a-b*q
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe FR_p_A16 = [GR_p_Table], 16
+ ldfe FR_p_A8 = [GR_p_Table2], 16
+ nop.i 0
+};;
+
+{ .mmi
+ ldfe FR_p_A15 = [GR_p_Table], 16
+ ldfe FR_p_A7 = [GR_p_Table2], 16
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_p_A14 = [GR_p_Table], 16
+ fma.s1 FR_r_TH = FR_r_A2H, FR_r_XS2, f0 // neg sin
+ nop.i 0
+}
+{ .mfi
+ ldfe FR_p_A6 = [GR_p_Table2], 16
+ fma.s1 FR_r_TL = FR_r_A2L, FR_r_XS2, f0 // neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ ldfe FR_p_A13 = [GR_p_Table], 16
+ fms.s1 FR_r_XS2L = FR_r_XS, FR_r_XS, FR_r_XS2 // xs^2 delta
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp5H = FR_p_A5H, FR_p_XR, f0 // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_XR2 = FR_p_XR, FR_p_XR, f0 // poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fabs FR_r_XS = FR_r_XS // Absolute value of xs
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp2H = FR_p_A2H, FR_p_XR, f0 // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_z_E4 = f8,FR_z_Y2,f1 // e4 = 1-b*y2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_z_ZH = FR_z_R0,FR_z_Y2,FR_z_Q0 // 1/x = q+r*y2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_TT = FR_r_A2H, FR_r_XS2, FR_r_TH // neg sin
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResH = FR_r_TH, f1, FR_r_A1H // neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_r_A2H, FR_r_XS2L, FR_r_TL // neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Temp5L = FR_p_A5H, FR_p_XR, FR_p_Temp5H // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly5H = FR_p_Temp5H, f1, FR_p_A4H // Low poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Temp2L = FR_p_A2H, FR_p_XR, FR_p_Temp2H // High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly2H = FR_p_Temp2H, f1, FR_p_A1H // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_XR3 = FR_p_XR2, FR_p_XR, f0 // r^3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_XR2L = FR_p_XR, FR_p_XR, FR_p_XR2 // r^2 delta
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A18 = FR_p_A19, FR_p_XR, FR_p_A18 // poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A14 = FR_p_A15, FR_p_XR, FR_p_A14 // poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_XR4 = FR_p_XR2, FR_p_XR2, f0 // poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_z_Y3 = FR_z_Y2,FR_z_E4,FR_z_Y2 // y3 = y2+y2*e4
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp5L = FR_p_A5L, FR_p_XR, FR_p_Temp5L // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Poly5L = FR_p_A4H, f1, FR_p_Poly5H // Low poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp4H = FR_p_Poly5H, FR_p_XR, f0 // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp2L = FR_p_A2L, FR_p_XR, FR_p_Temp2L // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Poly2L = FR_p_A1H, f1, FR_p_Poly2H // High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp1H = FR_p_Poly2H, FR_p_XR, f0 // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_XR3L = FR_p_XR2, FR_p_XR, FR_p_XR3 // x^3 delta
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A16 = FR_p_A17, FR_p_XR, FR_p_A16 //poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_ResL = FR_r_A1H, f1, FR_r_ResH // neg sin
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_r_TL, f1, FR_r_TT // neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp5L = FR_p_Temp5L, f1, FR_p_A4L // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly5L = FR_p_Poly5L, f1, FR_p_Temp5H //Low poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Temp4L = FR_p_Poly5H, FR_p_XR, FR_p_Temp4H//Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly4H = FR_p_Temp4H, f1, FR_p_A3H // Low poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp2L = FR_p_Temp2L, f1, FR_p_A1L // High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly2L = FR_p_Poly2L, f1, FR_p_Temp2H // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Temp1L = FR_p_Poly2H,FR_p_XR,FR_p_Temp1H //High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly1H = FR_p_Temp1H, f1, FR_p_A0H // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A12 = FR_p_A13, FR_p_XR, FR_p_A12 // poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_XR3L = FR_p_XR2L, FR_p_XR, FR_p_XR3L // x^3 low
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly5L = FR_p_Poly5L, f1, FR_p_Temp5L //Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A10 = FR_p_A11, FR_p_XR, FR_p_A10 //poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Poly4L = FR_p_A3H, f1, FR_p_Poly4H /// Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A6 = FR_p_A7, FR_p_XR, FR_p_A6 // poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A8 = FR_p_A9, FR_p_XR, FR_p_A8 // poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_XR6 = FR_p_XR4, FR_p_XR2, f0 // r^6
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly2L = FR_p_Poly2L, f1, FR_p_Temp2L // High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Poly1L = FR_p_A0H, f1, FR_p_Poly1H // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResL = FR_r_ResL, f1, FR_r_TH // neg sin
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TT = FR_r_TL, f1, FR_r_A1L // neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp4L = FR_p_Poly5L,FR_p_XR,FR_p_Temp4L //Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A18 = FR_p_A20, FR_p_XR2, FR_p_A18 // poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly4L = FR_p_Poly4L, f1, FR_p_Temp4H // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A14 = FR_p_A16, FR_p_XR2, FR_p_A14 // poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A6 = FR_p_A8, FR_p_XR2, FR_p_A6 // poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A10 = FR_p_A12, FR_p_XR2, FR_p_A10 // poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp1L = FR_p_Poly2L,FR_p_XR,FR_p_Temp1L //High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly1L = FR_p_Poly1L, f1, FR_p_Temp1H // High poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResL = FR_r_ResL, f1, FR_r_TT // neg sin
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TH = FR_r_ResH, FR_r_XS2, f0 // neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp4L = FR_p_Temp4L, f1, FR_p_A3L // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly3H = FR_p_Poly4H, FR_p_XR3, f0 // Low poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A14 = FR_p_A18, FR_p_XR4, FR_p_A14 // poly tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_XR8 = FR_p_XR4, FR_p_XR4, f0 // r^8
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_r_ResH, FR_r_XS2L, f0 // neg sin
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_z_R1 = f8,FR_z_ZH,f1 // r1 = a-b*x
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp1L = FR_p_Temp1L, f1, FR_p_A0L // High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_A6 = FR_p_A10, FR_p_XR4, FR_p_A6 // poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_TT = FR_r_ResH, FR_r_XS2, FR_r_TH // neg sin
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Res3H = FR_r_TH, f1, f1 // neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly4L = FR_p_Poly4L, f1, FR_p_Temp4L // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly3L = FR_p_Poly4H, FR_p_XR3L, f0 // Low poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly0H = FR_p_Poly3H, f1, FR_p_Poly1H // Result
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_A7 = FR_r_A8, FR_r_XS2, FR_r_A7 // neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_r_ResL, FR_r_XS2, FR_r_TL // neg sin
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_XS4 = FR_r_XS2, FR_r_XS2, f0 // xs^4
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly1L = FR_p_Poly1L, f1, FR_p_Temp1L // High poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_PolyTail = FR_p_A14, FR_p_XR8, FR_p_A6 // poly tail
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_Res3L = f1, f1, FR_r_Res3H // neg sin
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResH = FR_r_Res3H, FR_r_XS, f0 // neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Temp0L = FR_p_Poly4H,FR_p_XR3,FR_p_Poly3H //Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly3L = FR_p_Poly4L,FR_p_XR3,FR_p_Poly3L //Low poly
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_p_Poly0L = FR_p_Poly1H, f1, FR_p_Poly0H // Result
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_z_ZL = FR_z_R1,FR_z_Y3, f0 // x_lo = r1*y3
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_r_TL, f1, FR_r_TT // neg sin
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_A3 = FR_r_A4, FR_r_XS2, FR_r_A3 /// neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly1L = FR_p_PolyTail,FR_p_XR6,FR_p_Poly1L // High
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_A5 = FR_r_A6, FR_r_XS2, FR_r_A5 // neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Res3L = FR_r_Res3L, f1, FR_r_TH // neg sin
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_ResL = FR_r_Res3H, FR_r_XS, FR_r_ResH // neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly3L = FR_p_Poly3L, f1, FR_p_Temp0L // Low poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_A7 = FR_r_A9, FR_r_XS4, FR_r_A7 // neg sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly0L = FR_p_Poly0L, f1, FR_p_Poly3H // result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p14) fma.s1 f8 = FR_p_Poly0H, FR_z_ZH, f0 // z*poly
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp1L = FR_p_Poly0H, FR_z_ZL, f0 // z*poly low
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_A3 = FR_r_A5, FR_r_XS4, FR_r_A3 // sin tail
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_XS7 = FR_r_XS4, FR_r_XS2, f0 // xs^6
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Res3L = FR_r_Res3L, f1, FR_r_TL // sin low
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_XS8 = FR_r_XS4, FR_r_XS4, f0 // xs^8
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Temp0H = FR_p_Poly3L, f1, FR_p_Poly1L // result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p14) fms.s1 FR_p_Temp1H = FR_p_Poly0H, FR_z_ZH, f8 // hi result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_XS7 = FR_r_XS7, FR_r_XS, f0 // xs^7
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResL = FR_r_Res3L, FR_r_XS, FR_r_ResL // lo result
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Tail = FR_r_A7, FR_r_XS8, FR_r_A3 // tail result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_p_Poly0L = FR_p_Poly0L, f1, FR_p_Temp0H // lo result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResL = FR_r_Tail, FR_r_XS7, FR_r_ResL // lo result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_p_Temp1L = FR_p_Poly0L,FR_z_ZH,FR_p_Temp1L //hi result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TT = FR_r_ResL, f1, f0 // for low result
+ nop.i 0
+};;
+
+.pred.rel "mutex",p12,p13
+{ .mfi
+ nop.m 0
+(p14) fma.s1 FR_p_Temp1L = FR_p_Temp1L, f1, FR_p_Temp1H // for lo res
+ nop.i 0
+};;
+
+{ .mfi
+(p10) cmp.eq p13, p12 = r0, r0 // set p13, clear p12
+ fma.s1 FR_r_Res1H = FR_r_ResH, f1, FR_r_TT // hi res
+ nop.i 0
+};;
+
+{ .mfb
+(p9) cmp.eq p13, p12 = r0, r0 // set p13, clear p12
+(p14) fma.s0 f8 = f8, f1, FR_p_Temp1L // Final result
+(p14) br.ret.spnt b0 // Exit for 0 < |X| < 1 path (positive arguments)///////
+};;
+
+{ .mfi
+(p11) cmp.eq p13, p12 = r0, r0 // set p13, clear p12
+ fms.s1 FR_r_Res1L = FR_r_ResH, f1, FR_r_Res1H // Low sin result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Res1L = FR_r_Res1L, f1, FR_r_TT // Low sin result
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_p_Poly0L,FR_r_Res1H,f0 //Low sin result
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_TL = FR_p_Poly0H, FR_r_Res1L, FR_r_TL //Low sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResH = FR_p_Poly0H, FR_r_Res1H, FR_r_TL //High sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fms.s1 FR_r_ResL = FR_p_Poly0H,FR_r_Res1H,FR_r_ResH //Low res
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ frcpa.s1 FR_r_Y0,p0 = f1,FR_r_ResH // y = frcpa(b)
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fneg FR_r_NegOne = f1 // Construct -1.0
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ResL = FR_r_ResL, f1, FR_r_TL // low sin
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Q0 = f1,FR_r_Y0,f0 // q = a*y
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_r_E0 = FR_r_Y0,FR_r_ResH,f1 // e = 1-b*y
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_E2 = FR_r_E0,FR_r_E0,FR_r_E0 // e2 = e+e^2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_E1 = FR_r_E0,FR_r_E0,f0 // e1 = e^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Y1 = FR_r_Y0,FR_r_E2,FR_r_Y0 // y1 = y+y*e2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_E3 = FR_r_E1,FR_r_E1,FR_r_E0 // e3 = e+e1^2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Y2 = FR_r_Y1,FR_r_E3,FR_r_Y0 // y2 = y+y1*e3
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_r_R0 = FR_r_ResH,FR_r_Q0,f1 // r = a-b*q
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_r_E4 = FR_r_ResH,FR_r_Y2,f1 // e4 = 1-b*y2
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ZH = FR_r_R0,FR_r_Y2,FR_r_Q0 // x = q+r*y2
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_Y3 = FR_r_Y2,FR_r_E4,FR_r_Y2 // y3 = y2+y2*e4
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_r_R1 = FR_r_ResH,FR_r_ZH,f1 // r1 = a-b*x
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ fnma.s1 FR_r_R1 = FR_r_ResL,FR_r_ZH,FR_r_R1 // r1=r1 - b_lo*X
+ nop.i 0
+}
+{ .mfi
+ nop.m 0
+ fma.s1 FR_r_ZHN = FR_r_ZH,FR_r_NegOne, f0 // Negate
+ nop.i 0
+};;
+
+.pred.rel "mutex",p13,p12
+{ .mfb
+ nop.m 0
+ fnma.s0 f8 = FR_r_R1,FR_r_Y3,FR_r_ZHN // Result for neg
+ br.ret.sptk b0 // Exit for 0 < |X| < 1 path (negative arguments)//////
+};;
+
+
+
+
+// SPECIALS (x for natval, nan, +/-inf or +/-0) ///////////////////////////////
+//------------------------------------------------------------------------------
+.align 32
+tgammal_spec:
+{ .mlx
+ nop.m 0
+ movl GR_DenOverflow = 0x2000000000000001
+}
+{ .mfi
+ nop.m 0
+ fclass.m p9,p0 = f8,0xB // +/-denormals
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fclass.m p6,p0 = f8,0x1E1 // Test x for natval, nan, +inf
+ nop.i 0
+};;
+{ .mfi
+ nop.m 0
+ fclass.m p7,p8 = f8,0x7 // +/-0
+ nop.i 0
+}
+
+{ .mfi
+(p9) cmp.ltu.unc p10,p11 = GR_l_signif_Z, GR_DenOverflow
+(p9) fnorm.s0 f8 = f8
+ nop.i 0
+};;
+
+{ .mfb
+ nop.m 0
+(p9) fcvt.fx.trunc.s1 FR_n_IXN = FR_l_AbsX // Round by truncate
+(p11) br.cond.sptk tgamma_lt_1 // Return to gamma ('good' denormal)////////////
+};;
+
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p10) br.cond.spnt tgammal_overflow // "Bad" denormal - overflow! /////////////
+};;
+
+{ .mfi
+ nop.m 0
+ mov FR_X = f8 // for error handler
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p6) fma.s0 f8 = f8,f1,f8 // res = x + x
+(p6) br.ret.spnt b0 // Exit for NAN, INF and NatVals ////////////////////////
+};;
+.pred.rel "mutex",p7,p8
+{ .mfi
+(p7) mov GR_Parameter_TAG = 256 // negative
+(p7) frcpa.s0 f8,p0 = f1,f8 // Raise V flag
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+ nop.f 0
+(p8) br.cond.spnt tgammal_singularity // Branch for +ZERO ////////////////////
+};;
+
+{ .mfb
+ nop.m 0
+ nop.f 0
+ br.cond.spnt tgammal_libm_err // Branch for -ZERO ///////////////////////
+};;
+
+
+
+
+// SINGULARITY (x is negative integer or 0) ////////////////////////////////////
+//------------------------------------------------------------------------------
+.align 32
+tgammal_singularity:
+{ .mfi
+ nop.m 0
+ mov FR_X = f8 // For error handler
+ mov GR_Parameter_TAG = 256 // negative
+}
+{ .mfb
+ nop.m 0
+ frcpa.s0 f8,p0 = f0,f0 // Raise V flag
+ br.cond.sptk tgammal_libm_err // Call error handler /////////////////////
+ // with singularity error /////////////////
+};;
+
+
+
+
+// OVERFLOW (result is too big and cannot be represented by normal value) //////
+// ( X > 1755.54 and for denormals with abs value less than 0x2000000000000001 )
+//------------------------------------------------------------------------------
+.align 32
+tgammal_overflow:
+{ .mfi
+ addl r8 = 0x1FFFE, r0 // Exp of INF
+ fcmp.lt.s1 p15,p14 = f8,f0 // p14 - pos arg, p15 - neg arg
+ nop.i 0
+};;
+
+{ .mfi
+ setf.exp f9 = r8
+ mov FR_X = f8 // For error handler
+ mov GR_Parameter_TAG = 255 // overflow
+};;
+
+.pred.rel "mutex",p14,p15
+{ .mfi
+ nop.m 0
+(p14) fma.s0 f8 = f9,f9,f0 // Set I,O and +INF result
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p15) fnma.s0 f8 = f9,f9,f0 // Set I,O and -INF result
+ br.cond.sptk tgammal_libm_err // Call error handler /////////////////////
+ // with overflow error ////////////////////
+};;
+
+
+
+
+
+// UNDERFLOW (x is negative noninteger with big absolute value) ////////////////
+//------------------------------------------------------------------------------
+.align 32
+tgammal_underflow:
+{ .mfi
+ nop.m 0
+ fcvt.fx.trunc.s1 FR_u_IXN = f8 // Convert arg to int repres. in FR
+ nop.i 0
+};;
+
+{ .mmi
+ getf.sig GR_u_XN = FR_u_IXN
+ mov r11 = 0x00001
+ nop.i 0
+};;
+
+{ .mfi
+ setf.exp f9 = r11
+ nop.f 0
+ nop.i 0
+};;
+
+{ .mfi
+ nop.m 0
+ nop.f 0
+ tbit.z p6,p7 = GR_u_XN,0 // even or odd
+};;
+
+.pred.rel "mutex",p6,p7
+{ .mfi
+ nop.m 0
+(p6) fms.s0 f8 = f9,f9,f9 // for negatives
+ nop.i 0
+}
+{ .mfb
+ nop.m 0
+(p7) fma.s0 f8 = f9,f9,f9 // for positives
+ br.ret.sptk b0 // Exit for underflow path //////////////////////////////
+};;
+
+
+GLOBAL_LIBM_END(tgammal)
+
+
+
+
+////////////////// Tgammal error handler ///////////////////////////////////////
+//------------------------------------------------------------------------------
+LOCAL_LIBM_ENTRY(__libm_error_region)
+tgammal_libm_err:
+.prologue
+{ .mfi
+ add GR_Parameter_Y=-32,sp // Parameter 2 value
+ nop.f 0
+.save ar.pfs,GR_SAVE_PFS
+ mov GR_SAVE_PFS=ar.pfs // Save ar.pfs
+}
+{ .mfi
+.fframe 64
+ add sp=-64,sp // Create new stack
+ nop.f 0
+ mov GR_SAVE_GP=gp // Save gp
+};;
+{ .mmi
+ stfe [GR_Parameter_Y] = FR_Y,16 // Save Parameter 2 on stack
+ add GR_Parameter_X = 16,sp // Parameter 1 address
+.save b0, GR_SAVE_B0
+ mov GR_SAVE_B0=b0 // Save b0
+};;
+.body
+{ .mib
+ stfe [GR_Parameter_X] = FR_X // Store Parameter 1 on stack
+ add GR_Parameter_RESULT = 0,GR_Parameter_Y
+ nop.b 0 // Parameter 3 address
+}
+{ .mib
+ stfe [GR_Parameter_Y] = FR_RESULT // Store Parameter 3 on stack
+ add GR_Parameter_Y = -16,GR_Parameter_Y
+ br.call.sptk b0=__libm_error_support# // Call error handling function
+};;
+{ .mmi
+ nop.m 999
+ nop.m 999
+ add GR_Parameter_RESULT = 48,sp
+};;
+{ .mmi
+ ldfe f8 = [GR_Parameter_RESULT] // Get return result off stack
+.restore sp
+ add sp = 64,sp // Restore stack pointer
+ mov b0 = GR_SAVE_B0 // Restore return address
+};;
+{ .mib
+ mov gp = GR_SAVE_GP // Restore gp
+ mov ar.pfs = GR_SAVE_PFS // Restore ar.pfs
+ br.ret.sptk b0 // Return
+};;
+
+LOCAL_LIBM_END(__libm_error_region#)
+
+.type __libm_error_support#,@function
+.global __libm_error_support#
diff --git a/libc/sysdeps/ia64/gccframe.h b/libc/sysdeps/ia64/gccframe.h
new file mode 100644
index 000000000..745b50cfa
--- /dev/null
+++ b/libc/sysdeps/ia64/gccframe.h
@@ -0,0 +1,32 @@
+/* Definition of object in frame unwind info. ia64 version.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This must match what's in frame.h in gcc. */
+
+struct object
+{
+ void *pc_base; /* This field will be set by find_fde. */
+ void *pc_begin;
+ void *pc_end;
+ void *fde_begin;
+ void *fde_end;
+ void *fde_array;
+ __SIZE_TYPE__ count;
+ struct object *next;
+};
diff --git a/libc/sysdeps/ia64/hp-timing.c b/libc/sysdeps/ia64/hp-timing.c
new file mode 100644
index 000000000..ae8680f9a
--- /dev/null
+++ b/libc/sysdeps/ia64/hp-timing.c
@@ -0,0 +1,24 @@
+/* Support for high precision, low overhead timing functions. IA-64 version.
+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hp-timing.h>
+
+/* We have to define the variable for the overhead. */
+hp_timing_t _dl_hp_timing_overhead;
diff --git a/libc/sysdeps/ia64/hp-timing.h b/libc/sysdeps/ia64/hp-timing.h
new file mode 100644
index 000000000..3c2166ee5
--- /dev/null
+++ b/libc/sysdeps/ia64/hp-timing.h
@@ -0,0 +1,148 @@
+/* High precision, low overhead timing functions. IA-64 version.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H 1
+
+#include <string.h>
+#include <sys/param.h>
+#include <stdio-common/_itoa.h>
+#include <ia64intrin.h>
+
+/* The macros defined here use the timestamp counter in IA-64. They
+ provide a very accurate way to measure the time with very little
+ overhead. The time values themself have no real meaning, only
+ differences are interesting.
+
+ The list of macros we need includes the following:
+
+ - HP_TIMING_AVAIL: test for availability.
+
+ - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
+ implemented using function calls but instead uses some inlined code
+ which might simply consist of a few assembler instructions. We have to
+ know this since we might want to use the macros here in places where we
+ cannot make function calls.
+
+ - hp_timing_t: This is the type for variables used to store the time
+ values.
+
+ - HP_TIMING_ZERO: clear `hp_timing_t' object.
+
+ - HP_TIMING_NOW: place timestamp for current time in variable given as
+ parameter.
+
+ - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
+ HP_TIMING_DIFF macro.
+
+ - HP_TIMING_DIFF: compute difference between two times and store it
+ in a third. Source and destination might overlap.
+
+ - HP_TIMING_ACCUM: add time difference to another variable. This might
+ be a bit more complicated to implement for some platforms as the
+ operation should be thread-safe and 64bit arithmetic on 32bit platforms
+ is not.
+
+ - HP_TIMING_ACCUM_NT: this is the variant for situations where we know
+ there are no threads involved.
+
+ - HP_TIMING_PRINT: write decimal representation of the timing value into
+ the given string. This operation need not be inline even though
+ HP_TIMING_INLINE is specified.
+
+*/
+
+/* We always assume having the timestamp register. */
+#define HP_TIMING_AVAIL (1)
+
+/* We indeed have inlined functions. */
+#define HP_TIMING_INLINE (1)
+
+/* We use 64bit values for the times. */
+typedef unsigned long int hp_timing_t;
+
+/* Set timestamp value to zero. */
+#define HP_TIMING_ZERO(Var) (Var) = (0)
+
+
+/* The Itanium/Merced has a bug where the ar.itc register value read
+ is not correct in some situations. The solution is to read again.
+ For now we always do this until we know how to recognize a fixed
+ processor implementation. */
+#define REPEAT_READ(val) __builtin_expect ((long int) val == -1, 0)
+
+/* That's quite simple. Use the `ar.itc' instruction. */
+#define HP_TIMING_NOW(Var) \
+ ({ unsigned long int __itc; \
+ do \
+ asm volatile ("mov %0=ar.itc" : "=r" (__itc) : : "memory"); \
+ while (REPEAT_READ (__itc)); \
+ Var = __itc; })
+
+/* Use two 'ar.itc' instructions in a row to find out how long it takes. */
+#define HP_TIMING_DIFF_INIT() \
+ do { \
+ int __cnt = 5; \
+ GLRO(dl_hp_timing_overhead) = ~0ul; \
+ do \
+ { \
+ hp_timing_t __t1, __t2; \
+ HP_TIMING_NOW (__t1); \
+ HP_TIMING_NOW (__t2); \
+ if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \
+ GLRO(dl_hp_timing_overhead) = __t2 - __t1; \
+ } \
+ while (--__cnt > 0); \
+ } while (0)
+
+/* It's simple arithmetic for us. */
+#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start))
+
+/* We have to jump through hoops to get this correctly implemented. */
+#define HP_TIMING_ACCUM(Sum, Diff) \
+ do { \
+ hp_timing_t __oldval; \
+ hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \
+ hp_timing_t __newval; \
+ do \
+ { \
+ __oldval = (Sum); \
+ __newval = __oldval + __diff; \
+ } \
+ while (! __sync_bool_compare_and_swap (&Sum, __oldvar, __newval)); \
+ } while (0)
+
+/* No threads, no extra work. */
+#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff)
+
+/* Print the time value. */
+#define HP_TIMING_PRINT(Buf, Len, Val) \
+ do { \
+ char __buf[20]; \
+ char *__cp = _itoa_word (Val, __buf + sizeof (__buf), 10, 0); \
+ int __len = (Len); \
+ char *__dest = (Buf); \
+ while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \
+ *__dest++ = *__cp++; \
+ memcpy (__dest, " clock cycles", MIN (__len, \
+ (int) sizeof (" clock cycles"))); \
+ } while (0)
+
+#endif /* hp-timing.h */
diff --git a/libc/sysdeps/ia64/htonl.S b/libc/sysdeps/ia64/htonl.S
new file mode 100644
index 000000000..92c3cae4d
--- /dev/null
+++ b/libc/sysdeps/ia64/htonl.S
@@ -0,0 +1,31 @@
+/* Change byte order in 32-bit value. ia64 version.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Dan Pop <Dan.Pop@cern.ch>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#include <sysdep.h>
+
+ENTRY(htonl)
+ shl ret0 = r32, 32
+ ;;
+ mux1 ret0 = ret0, @rev
+ ret
+END(htonl)
+
+weak_alias (htonl, ntohl)
diff --git a/libc/sysdeps/ia64/htons.S b/libc/sysdeps/ia64/htons.S
new file mode 100644
index 000000000..317ab6179
--- /dev/null
+++ b/libc/sysdeps/ia64/htons.S
@@ -0,0 +1,31 @@
+/* Change byte order in 16-bit value. ia64 version.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Dan Pop <Dan.Pop@cern.ch>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#include <sysdep.h>
+
+ENTRY(htons)
+ shl ret0 = r32, 48
+ ;;
+ mux1 ret0 = ret0, @rev
+ ret
+END(htons)
+
+weak_alias (htons, ntohs)
diff --git a/libc/sysdeps/ia64/ia64libgcc.S b/libc/sysdeps/ia64/ia64libgcc.S
new file mode 100644
index 000000000..3f77b06a5
--- /dev/null
+++ b/libc/sysdeps/ia64/ia64libgcc.S
@@ -0,0 +1,350 @@
+/* From the Intel IA-64 Optimization Guide, choose the minimum latency
+ alternative. */
+
+#include <sysdep.h>
+#undef ret
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_2, GLIBC_2_2_6)
+
+/* __divtf3
+ Compute a 80-bit IEEE double-extended quotient.
+ farg0 holds the dividend. farg1 holds the divisor. */
+
+ENTRY(___divtf3)
+ cmp.eq p7, p0 = r0, r0
+ frcpa.s0 f10, p6 = farg0, farg1
+ ;;
+(p6) cmp.ne p7, p0 = r0, r0
+ .pred.rel.mutex p6, p7
+(p6) fnma.s1 f11 = farg1, f10, f1
+(p6) fma.s1 f12 = farg0, f10, f0
+ ;;
+(p6) fma.s1 f13 = f11, f11, f0
+(p6) fma.s1 f14 = f11, f11, f11
+ ;;
+(p6) fma.s1 f11 = f13, f13, f11
+(p6) fma.s1 f13 = f14, f10, f10
+ ;;
+(p6) fma.s1 f10 = f13, f11, f10
+(p6) fnma.s1 f11 = farg1, f12, farg0
+ ;;
+(p6) fma.s1 f11 = f11, f10, f12
+(p6) fnma.s1 f12 = farg1, f10, f1
+ ;;
+(p6) fma.s1 f10 = f12, f10, f10
+(p6) fnma.s1 f12 = farg1, f11, farg0
+ ;;
+(p6) fma.s0 fret0 = f12, f10, f11
+(p7) mov fret0 = f10
+ br.ret.sptk rp
+END(___divtf3)
+ .symver ___divtf3, __divtf3@GLIBC_2.2
+
+/* __divdf3
+ Compute a 64-bit IEEE double quotient.
+ farg0 holds the dividend. farg1 holds the divisor. */
+
+ENTRY(___divdf3)
+ cmp.eq p7, p0 = r0, r0
+ frcpa.s0 f10, p6 = farg0, farg1
+ ;;
+(p6) cmp.ne p7, p0 = r0, r0
+ .pred.rel.mutex p6, p7
+(p6) fmpy.s1 f11 = farg0, f10
+(p6) fnma.s1 f12 = farg1, f10, f1
+ ;;
+(p6) fma.s1 f11 = f12, f11, f11
+(p6) fmpy.s1 f13 = f12, f12
+ ;;
+(p6) fma.s1 f10 = f12, f10, f10
+(p6) fma.s1 f11 = f13, f11, f11
+ ;;
+(p6) fmpy.s1 f12 = f13, f13
+(p6) fma.s1 f10 = f13, f10, f10
+ ;;
+(p6) fma.d.s1 f11 = f12, f11, f11
+(p6) fma.s1 f10 = f12, f10, f10
+ ;;
+(p6) fnma.d.s1 f8 = farg1, f11, farg0
+ ;;
+(p6) fma.d fret0 = f8, f10, f11
+(p7) mov fret0 = f10
+ br.ret.sptk rp
+ ;;
+END(___divdf3)
+ .symver ___divdf3, __divdf3@GLIBC_2.2
+
+/* __divsf3
+ Compute a 32-bit IEEE float quotient.
+ farg0 holds the dividend. farg1 holds the divisor. */
+
+ENTRY(___divsf3)
+ cmp.eq p7, p0 = r0, r0
+ frcpa.s0 f10, p6 = farg0, farg1
+ ;;
+(p6) cmp.ne p7, p0 = r0, r0
+ .pred.rel.mutex p6, p7
+(p6) fmpy.s1 f8 = farg0, f10
+(p6) fnma.s1 f9 = farg1, f10, f1
+ ;;
+(p6) fma.s1 f8 = f9, f8, f8
+(p6) fmpy.s1 f9 = f9, f9
+ ;;
+(p6) fma.s1 f8 = f9, f8, f8
+(p6) fmpy.s1 f9 = f9, f9
+ ;;
+(p6) fma.d.s1 f10 = f9, f8, f8
+ ;;
+(p6) fnorm.s.s0 fret0 = f10
+(p7) mov fret0 = f10
+ br.ret.sptk rp
+ ;;
+END(___divsf3)
+ .symver ___divsf3, __divsf3@GLIBC_2.2
+
+/* __divdi3
+ Compute a 64-bit integer quotient.
+ in0 holds the dividend. in1 holds the divisor. */
+
+ENTRY(___divdi3)
+ .regstk 2,0,0,0
+ /* Transfer inputs to FP registers. */
+ setf.sig f8 = in0
+ setf.sig f9 = in1
+ ;;
+ /* Convert the inputs to FP, so that they won't be treated as
+ unsigned. */
+ fcvt.xf f8 = f8
+ fcvt.xf f9 = f9
+ ;;
+ /* Compute the reciprocal approximation. */
+ frcpa.s1 f10, p6 = f8, f9
+ ;;
+ /* 3 Newton-Raphson iterations. */
+(p6) fnma.s1 f11 = f9, f10, f1
+(p6) fmpy.s1 f12 = f8, f10
+ ;;
+(p6) fmpy.s1 f13 = f11, f11
+(p6) fma.s1 f12 = f11, f12, f12
+ ;;
+(p6) fma.s1 f10 = f11, f10, f10
+(p6) fma.s1 f11 = f13, f12, f12
+ ;;
+(p6) fma.s1 f10 = f13, f10, f10
+(p6) fnma.s1 f12 = f9, f11, f8
+ ;;
+(p6) fma.s1 f10 = f12, f10, f11
+ ;;
+ /* Round quotient to an integer. */
+ fcvt.fx.trunc.s1 f10 = f10
+ ;;
+ /* Transfer result to GP registers. */
+ getf.sig ret0 = f10
+ br.ret.sptk rp
+ ;;
+END(___divdi3)
+ .symver ___divdi3, __divdi3@GLIBC_2.2
+
+/* __moddi3
+ Compute a 64-bit integer modulus.
+ in0 holds the dividend (a). in1 holds the divisor (b). */
+
+ENTRY(___moddi3)
+ .regstk 2,0,0,0
+ /* Transfer inputs to FP registers. */
+ setf.sig f14 = in0
+ setf.sig f9 = in1
+ ;;
+ /* Convert the inputs to FP, so that they won't be treated as
+ unsigned. */
+ fcvt.xf f8 = f14
+ fcvt.xf f9 = f9
+ ;;
+ /* Compute the reciprocal approximation. */
+ frcpa.s1 f10, p6 = f8, f9
+ ;;
+ /* 3 Newton-Raphson iterations. */
+(p6) fmpy.s1 f12 = f8, f10
+(p6) fnma.s1 f11 = f9, f10, f1
+ ;;
+(p6) fma.s1 f12 = f11, f12, f12
+(p6) fmpy.s1 f13 = f11, f11
+ ;;
+(p6) fma.s1 f10 = f11, f10, f10
+(p6) fma.s1 f11 = f13, f12, f12
+ ;;
+ sub in1 = r0, in1
+(p6) fma.s1 f10 = f13, f10, f10
+(p6) fnma.s1 f12 = f9, f11, f8
+ ;;
+ setf.sig f9 = in1
+(p6) fma.s1 f10 = f12, f10, f11
+ ;;
+ fcvt.fx.trunc.s1 f10 = f10
+ ;;
+ /* r = q * (-b) + a */
+ xma.l f10 = f10, f9, f14
+ ;;
+ /* Transfer result to GP registers. */
+ getf.sig ret0 = f10
+ br.ret.sptk rp
+ ;;
+END(___moddi3)
+ .symver ___moddi3, __moddi3@GLIBC_2.2
+
+/* __udivdi3
+ Compute a 64-bit unsigned integer quotient.
+ in0 holds the dividend. in1 holds the divisor. */
+
+ENTRY(___udivdi3)
+ .regstk 2,0,0,0
+ /* Transfer inputs to FP registers. */
+ setf.sig f8 = in0
+ setf.sig f9 = in1
+ ;;
+ /* Convert the inputs to FP, to avoid FP software-assist faults. */
+ fcvt.xuf.s1 f8 = f8
+ fcvt.xuf.s1 f9 = f9
+ ;;
+ /* Compute the reciprocal approximation. */
+ frcpa.s1 f10, p6 = f8, f9
+ ;;
+ /* 3 Newton-Raphson iterations. */
+(p6) fnma.s1 f11 = f9, f10, f1
+(p6) fmpy.s1 f12 = f8, f10
+ ;;
+(p6) fmpy.s1 f13 = f11, f11
+(p6) fma.s1 f12 = f11, f12, f12
+ ;;
+(p6) fma.s1 f10 = f11, f10, f10
+(p6) fma.s1 f11 = f13, f12, f12
+ ;;
+(p6) fma.s1 f10 = f13, f10, f10
+(p6) fnma.s1 f12 = f9, f11, f8
+ ;;
+(p6) fma.s1 f10 = f12, f10, f11
+ ;;
+ /* Round quotient to an unsigned integer. */
+ fcvt.fxu.trunc.s1 f10 = f10
+ ;;
+ /* Transfer result to GP registers. */
+ getf.sig ret0 = f10
+ br.ret.sptk rp
+ ;;
+END(___udivdi3)
+ .symver ___udivdi3, __udivdi3@GLIBC_2.2
+
+/* __umoddi3
+ Compute a 64-bit unsigned integer modulus.
+ in0 holds the dividend (a). in1 holds the divisor (b). */
+
+ENTRY(___umoddi3)
+ .regstk 2,0,0,0
+ /* Transfer inputs to FP registers. */
+ setf.sig f14 = in0
+ setf.sig f9 = in1
+ ;;
+ /* Convert the inputs to FP, to avoid FP software assist faults. */
+ fcvt.xuf.s1 f8 = f14
+ fcvt.xuf.s1 f9 = f9
+ ;;
+ /* Compute the reciprocal approximation. */
+ frcpa.s1 f10, p6 = f8, f9
+ ;;
+ /* 3 Newton-Raphson iterations. */
+(p6) fmpy.s1 f12 = f8, f10
+(p6) fnma.s1 f11 = f9, f10, f1
+ ;;
+(p6) fma.s1 f12 = f11, f12, f12
+(p6) fmpy.s1 f13 = f11, f11
+ ;;
+(p6) fma.s1 f10 = f11, f10, f10
+(p6) fma.s1 f11 = f13, f12, f12
+ ;;
+ sub in1 = r0, in1
+(p6) fma.s1 f10 = f13, f10, f10
+(p6) fnma.s1 f12 = f9, f11, f8
+ ;;
+ setf.sig f9 = in1
+(p6) fma.s1 f10 = f12, f10, f11
+ ;;
+ /* Round quotient to an unsigned integer. */
+ fcvt.fxu.trunc.s1 f10 = f10
+ ;;
+ /* r = q * (-b) + a */
+ xma.l f10 = f10, f9, f14
+ ;;
+ /* Transfer result to GP registers. */
+ getf.sig ret0 = f10
+ br.ret.sptk rp
+ ;;
+END(___umoddi3)
+ .symver ___umoddi3, __umoddi3@GLIBC_2.2
+
+/* __multi3
+ Compute a 128-bit multiply of 128-bit multiplicands.
+ in0/in1 holds one multiplicand (a), in2/in3 holds the other one (b). */
+
+ENTRY(___multi3)
+ .regstk 4,0,0,0
+ setf.sig f6 = in1
+ movl r19 = 0xffffffff
+ setf.sig f7 = in2
+ ;;
+ and r14 = r19, in0
+ ;;
+ setf.sig f10 = r14
+ and r14 = r19, in2
+ xmpy.l f9 = f6, f7
+ ;;
+ setf.sig f6 = r14
+ shr.u r14 = in0, 32
+ ;;
+ setf.sig f7 = r14
+ shr.u r14 = in2, 32
+ ;;
+ setf.sig f8 = r14
+ xmpy.l f11 = f10, f6
+ xmpy.l f6 = f7, f6
+ ;;
+ getf.sig r16 = f11
+ xmpy.l f7 = f7, f8
+ ;;
+ shr.u r14 = r16, 32
+ and r16 = r19, r16
+ getf.sig r17 = f6
+ setf.sig f6 = in0
+ ;;
+ setf.sig f11 = r14
+ getf.sig r21 = f7
+ setf.sig f7 = in3
+ ;;
+ xma.l f11 = f10, f8, f11
+ xma.l f6 = f6, f7, f9
+ ;;
+ getf.sig r18 = f11
+ ;;
+ add r18 = r18, r17
+ ;;
+ and r15 = r19, r18
+ cmp.ltu p7, p6 = r18, r17
+ ;;
+ getf.sig r22 = f6
+(p7) adds r14 = 1, r19
+ ;;
+(p7) add r21 = r21, r14
+ shr.u r14 = r18, 32
+ shl r15 = r15, 32
+ ;;
+ add r20 = r21, r14
+ ;;
+ add ret0 = r15, r16
+ add ret1 = r22, r20
+ br.ret.sptk rp
+ ;;
+END(___multi3)
+ .symver ___multi3, __multi3@GLIBC_2.2
+
+#endif
diff --git a/libc/sysdeps/ia64/ieee754.h b/libc/sysdeps/ia64/ieee754.h
new file mode 100644
index 000000000..f5a71f5b9
--- /dev/null
+++ b/libc/sysdeps/ia64/ieee754.h
@@ -0,0 +1,205 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _IEEE754_H
+
+#define _IEEE754_H 1
+#include <features.h>
+
+#include <endian.h>
+
+__BEGIN_DECLS
+
+union ieee754_float
+ {
+ float f;
+
+ /* This is the IEEE 754 single-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int mantissa:23;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int mantissa:23;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int quiet_nan:1;
+ unsigned int mantissa:22;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int mantissa:22;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee_nan;
+ };
+
+#define IEEE754_FLOAT_BIAS 0x7f /* Added to exponent. */
+
+
+union ieee754_double
+ {
+ double d;
+
+ /* This is the IEEE 754 double-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:20;
+ unsigned int mantissa1:32;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# if __FLOAT_WORD_ORDER == BIG_ENDIAN
+ unsigned int mantissa0:20;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+ unsigned int mantissa1:32;
+# else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:20;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+# endif
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ unsigned int quiet_nan:1;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:19;
+ unsigned int mantissa1:32;
+#else
+# if __FLOAT_WORD_ORDER == BIG_ENDIAN
+ unsigned int mantissa0:19;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+ unsigned int mantissa1:32;
+# else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:19;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+# endif
+#endif
+ } ieee_nan;
+ };
+
+#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */
+
+
+union ieee854_long_double
+ {
+ long double d;
+
+ /* This is the IEEE 854 double-extended-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int empty0:32;
+ unsigned int negative:1;
+ unsigned int exponent:15;
+ unsigned int empty1:16;
+ unsigned int mantissa0:32;
+ unsigned int mantissa1:32;
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# if __FLOAT_WORD_ORDER == BIG_ENDIAN
+ unsigned int empty0:32;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty1:16;
+ unsigned int mantissa0:32;
+ unsigned int mantissa1:32;
+# else
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:32;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty1:16;
+ unsigned int empty0:32;
+# endif
+#endif
+ } ieee;
+
+ /* This is for NaNs in the IEEE 854 double-extended-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int empty0:32;
+ unsigned int negative:1;
+ unsigned int exponent:15;
+ unsigned int empty1:16;
+ unsigned int one:1;
+ unsigned int quiet_nan:1;
+ unsigned int mantissa0:30;
+ unsigned int mantissa1:32;
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# if __FLOAT_WORD_ORDER == BIG_ENDIAN
+ unsigned int empty0:32;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty1:16;
+ unsigned int mantissa0:30;
+ unsigned int quiet_nan:1;
+ unsigned int one:1;
+ unsigned int mantissa1:32;
+# else
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:30;
+ unsigned int quiet_nan:1;
+ unsigned int one:1;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty1:16;
+ unsigned int empty0:32;
+# endif
+#endif
+ } ieee_nan;
+ };
+
+#define IEEE854_LONG_DOUBLE_BIAS 0x3fff
+
+__END_DECLS
+
+#endif /* ieee754.h */
diff --git a/libc/sysdeps/ia64/jmpbuf-unwind.h b/libc/sysdeps/ia64/jmpbuf-unwind.h
new file mode 100644
index 000000000..c53447223
--- /dev/null
+++ b/libc/sysdeps/ia64/jmpbuf-unwind.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame containing a local
+ variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(_jmpbuf, _address, _demangle) \
+ ((void *) (_address) < (void *) (((long int *) _jmpbuf)[0]))
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ ({ uintptr_t _cfa = (uintptr_t) _Unwind_GetCFA (_context) - (_adj); \
+ (_cfa < (uintptr_t)(((long *)(_jmpbuf))[0]) - (_adj) \
+ || (_cfa == (uintptr_t)(((long *)(_jmpbuf))[0]) - (_adj) \
+ && (uintptr_t) _Unwind_GetBSP (_context) - (_adj) \
+ >= (uintptr_t)(((long *)(_jmpbuf))[17]) - (_adj))); \
+ })
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t)(_address) - (_adj) < (uintptr_t)(((long *)_jmpbuf)[0]) - (_adj))
+
+/* We use a longjmp() which can cross from the alternate signal-stack
+ to the normal stack. */
+extern void __libc_unwind_longjmp (sigjmp_buf env, int val)
+ __attribute__ ((noreturn));
+hidden_proto (__libc_unwind_longjmp)
diff --git a/libc/sysdeps/ia64/libc-tls.c b/libc/sysdeps/ia64/libc-tls.c
new file mode 100644
index 000000000..2c0eeae86
--- /dev/null
+++ b/libc/sysdeps/ia64/libc-tls.c
@@ -0,0 +1,36 @@
+/* Thread-local storage handling in the ELF dynamic linker. IA-64 version.
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <csu/libc-tls.c>
+
+#if USE_TLS
+
+/* On IA-64, as it lacks linker optimizations, __tls_get_addr can be
+ called even in statically linked binaries.
+ In this case module must be always 1 and PT_TLS segment
+ exist in the binary, otherwise it would not link. */
+
+void *
+__tls_get_addr (size_t m, size_t offset)
+{
+ dtv_t *dtv = THREAD_DTV ();
+ return (char *) dtv[1].pointer.val + offset;
+}
+
+#endif
diff --git a/libc/sysdeps/ia64/machine-gmon.h b/libc/sysdeps/ia64/machine-gmon.h
new file mode 100644
index 000000000..b8d0b4559
--- /dev/null
+++ b/libc/sysdeps/ia64/machine-gmon.h
@@ -0,0 +1,26 @@
+/* Machine-specific calling sequence for `mcount' profiling function. IA-64.
+ Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define _MCOUNT_DECL(from, self) \
+ void __mcount (u_long from, u_long self)
+
+/* Call __mcount with our the return PC for our caller, and the return
+ PC our caller will return to. Empty since we use an assembly stub
+ instead. */
+#define MCOUNT
diff --git a/libc/sysdeps/ia64/memccpy.S b/libc/sysdeps/ia64/memccpy.S
new file mode 100644
index 000000000..dd638d43c
--- /dev/null
+++ b/libc/sysdeps/ia64/memccpy.S
@@ -0,0 +1,250 @@
+/* Optimized version of the memccpy() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000,2001,2003,2006 Free Software Foundation, Inc.
+ Contributed by Dan Pop <Dan.Pop@cern.ch>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: a pointer to the next byte after char in dest or NULL
+
+ Inputs:
+ in0: dest
+ in1: src
+ in2: char
+ in3: byte count
+
+ This implementation assumes little endian mode (UM.be = 0).
+
+ This implementation assumes that it is safe to do read ahead
+ in the src block, without getting beyond its limit. */
+
+#include <sysdep.h>
+#undef ret
+
+#define OP_T_THRES 16
+#define OPSIZ 8
+
+#define saved_pr r17
+#define saved_lc r18
+#define dest r19
+#define src r20
+#define len r21
+#define asrc r22
+#define tmp r23
+#define char r24
+#define charx8 r25
+#define saved_ec r26
+#define sh2 r28
+#define sh1 r29
+#define loopcnt r30
+#define value r31
+
+#ifdef GAS_ALIGN_BREAKS_UNWIND_INFO
+/* Manually force proper loop-alignment. Note: be sure to
+ double-check the code-layout after making any changes to
+ this routine! */
+# define ALIGN(n) { nop 0 }
+#else
+# define ALIGN(n) .align n
+#endif
+
+ENTRY(memccpy)
+ .prologue
+ alloc r2 = ar.pfs, 4, 40 - 4, 0, 40
+
+#include "softpipe.h"
+ .rotr r[MEMLAT + 7], tmp1[4], tmp2[4], val[4], tmp3[2], pos0[2]
+ .rotp p[MEMLAT + 6 + 1]
+
+ mov ret0 = r0 // return NULL if no match
+ .save pr, saved_pr
+ mov saved_pr = pr // save the predicate registers
+ mov dest = in0 // dest
+ .save ar.lc, saved_lc
+ mov saved_lc = ar.lc // save the loop counter
+ mov saved_ec = ar.ec // save the loop counter
+ .body
+ mov src = in1 // src
+ extr.u char = in2, 0, 8 // char
+ mov len = in3 // len
+ sub tmp = r0, in0 // tmp = -dest
+ cmp.ne p7, p0 = r0, r0 // clear p7
+ ;;
+ and loopcnt = 7, tmp // loopcnt = -dest % 8
+ cmp.ge p6, p0 = OP_T_THRES, len // is len <= OP_T_THRES
+ mov ar.ec = 0 // ec not guaranteed zero on entry
+(p6) br.cond.spnt .cpyfew // copy byte by byte
+ ;;
+ cmp.eq p6, p0 = loopcnt, r0
+ mux1 charx8 = char, @brcst
+(p6) br.cond.sptk .dest_aligned
+ sub len = len, loopcnt // len -= -dest % 8
+ adds loopcnt = -1, loopcnt // --loopcnt
+ ;;
+ mov ar.lc = loopcnt
+.l1: // copy -dest % 8 bytes
+ ld1 value = [src], 1 // value = *src++
+ ;;
+ st1 [dest] = value, 1 // *dest++ = value
+ cmp.eq p6, p0 = value, char
+(p6) br.cond.spnt .foundit
+ br.cloop.dptk .l1
+.dest_aligned:
+ and sh1 = 7, src // sh1 = src % 8
+ and tmp = -8, len // tmp = len & -OPSIZ
+ and asrc = -8, src // asrc = src & -OPSIZ -- align src
+ shr.u loopcnt = len, 3 // loopcnt = len / 8
+ and len = 7, len ;; // len = len % 8
+ shl sh1 = sh1, 3 // sh1 = 8 * (src % 8)
+ adds loopcnt = -1, loopcnt // --loopcnt
+ mov pr.rot = 1 << 16 ;; // set rotating predicates
+ sub sh2 = 64, sh1 // sh2 = 64 - sh1
+ mov ar.lc = loopcnt // set LC
+ cmp.eq p6, p0 = sh1, r0 // is the src aligned?
+(p6) br.cond.sptk .src_aligned ;;
+ add src = src, tmp // src += len & -OPSIZ
+ mov ar.ec = MEMLAT + 6 + 1 // six more passes needed
+ ld8 r[1] = [asrc], 8 // r[1] = w0
+ cmp.ne p6, p0 = r0, r0 ;; // clear p6
+ ALIGN(32)
+.l2:
+(p[0]) ld8.s r[0] = [asrc], 8 // r[0] = w1
+(p[MEMLAT]) shr.u tmp1[0] = r[1 + MEMLAT], sh1 // tmp1 = w0 >> sh1
+(p[MEMLAT]) shl tmp2[0] = r[0 + MEMLAT], sh2 // tmp2 = w1 << sh2
+(p[MEMLAT+4]) xor tmp3[0] = val[1], charx8
+(p[MEMLAT+5]) czx1.r pos0[0] = tmp3[1]
+(p[MEMLAT+6]) chk.s r[6 + MEMLAT], .recovery1 // our data isn't
+ // valid - rollback!
+(p[MEMLAT+6]) cmp.ne p6, p0 = 8, pos0[1]
+(p6) br.cond.spnt .gotit
+(p[MEMLAT+6]) st8 [dest] = val[3], 8 // store val to dest
+(p[MEMLAT+3]) or val[0] = tmp1[3], tmp2[3] // val = tmp1 | tmp2
+ br.ctop.sptk .l2
+ br.cond.sptk .cpyfew
+
+.src_aligned:
+ cmp.ne p6, p0 = r0, r0 // clear p6
+ mov ar.ec = MEMLAT + 2 + 1 ;; // set EC
+.l3:
+(p[0]) ld8.s r[0] = [src], 8
+(p[MEMLAT]) xor tmp3[0] = r[MEMLAT], charx8
+(p[MEMLAT+1]) czx1.r pos0[0] = tmp3[1]
+(p[MEMLAT+2]) cmp.ne p7, p0 = 8, pos0[1]
+(p[MEMLAT+2]) chk.s r[MEMLAT+2], .recovery2
+(p7) br.cond.spnt .gotit
+.back2:
+(p[MEMLAT+2]) st8 [dest] = r[MEMLAT+2], 8
+ br.ctop.dptk .l3
+.cpyfew:
+ cmp.eq p6, p0 = len, r0 // is len == 0 ?
+ adds len = -1, len // --len;
+(p6) br.cond.spnt .restore_and_exit ;;
+ mov ar.lc = len
+.l4:
+ ld1 value = [src], 1
+ ;;
+ st1 [dest] = value, 1
+ cmp.eq p6, p0 = value, char
+(p6) br.cond.spnt .foundit
+ br.cloop.dptk .l4 ;;
+.foundit:
+(p6) mov ret0 = dest
+.restore_and_exit:
+ mov pr = saved_pr, -1 // restore the predicate registers
+ mov ar.lc = saved_lc // restore the loop counter
+ mov ar.ec = saved_ec ;; // restore the epilog counter
+ br.ret.sptk.many b0
+.gotit:
+ .pred.rel "mutex" p6, p7
+(p6) mov value = val[3] // if coming from l2
+(p7) mov value = r[MEMLAT+2] // if coming from l3
+ mov ar.lc = pos0[1] ;;
+.l5:
+ extr.u tmp = value, 0, 8 ;;
+ st1 [dest] = tmp, 1
+ shr.u value = value, 8
+ br.cloop.sptk .l5 ;;
+ mov ret0 = dest
+ mov pr = saved_pr, -1
+ mov ar.lc = saved_lc
+ br.ret.sptk.many b0
+
+.recovery1:
+#if MEMLAT != 6
+# error "MEMLAT must be 6!"
+#endif
+ adds src = -8, asrc
+ mov loopcnt = ar.lc
+ mov tmp = ar.ec
+ ;;
+(p[0]) adds src = -8, src
+ ;;
+(p[1]) adds src = -8, src
+ sub sh1 = (MEMLAT + 6 + 1), tmp
+ ;;
+(p[2]) adds src = -8, src
+ ;;
+(p[3]) adds src = -8, src
+ shl loopcnt = loopcnt, 3
+ ;;
+(p[4]) adds src = -8, src
+ ;;
+(p[5]) adds src = -8, src
+ shl sh1 = sh1, 3
+ ;;
+(p[6]) adds src = -8, src
+ ;;
+(p[7]) adds src = -8, src
+ shl tmp = tmp, 3
+ ;;
+(p[8]) adds src = -8, src
+ ;;
+(p[9]) adds src = -8, src
+ shr.u sh2 = sh2, 3
+ ;;
+(p[10]) adds src = -8, src
+ ;;
+(p[11]) adds src = -8, src
+ add len = len, loopcnt
+ ;;
+ sub src = src, sh2
+ ;;
+ add len = tmp, len
+ add src = sh1, src
+ br.cond.sptk .cpyfew
+
+.recovery2:
+#if MEMLAT != 6
+# error "MEMLAT must be 6!"
+#endif
+ add tmp = -8, src
+(p7) br.cond.spnt .gotit
+ ;;
+(p[0]) add tmp = -8, tmp ;;
+(p[1]) add tmp = -8, tmp ;;
+(p[2]) add tmp = -8, tmp ;;
+(p[3]) add tmp = -8, tmp ;;
+(p[4]) add tmp = -8, tmp ;;
+(p[5]) add tmp = -8, tmp ;;
+(p[6]) add tmp = -8, tmp ;;
+(p[7]) add tmp = -8, tmp ;;
+ ld8 r[MEMLAT+2] = [tmp] ;;
+ xor pos0[1] = r[MEMLAT+2], charx8 ;;
+ czx1.r pos0[1] = pos0[1] ;;
+ cmp.ne p7, p6 = 8, pos0[1]
+(p7) br.cond.spnt .gotit
+ br.cond.sptk .back2
+END(memccpy)
diff --git a/libc/sysdeps/ia64/memchr.S b/libc/sysdeps/ia64/memchr.S
new file mode 100644
index 000000000..e9a7ba823
--- /dev/null
+++ b/libc/sysdeps/ia64/memchr.S
@@ -0,0 +1,133 @@
+/* Optimized version of the standard memchr() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Dan Pop <Dan.Pop@cern.ch>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: the address of the first occurence of chr in str or NULL
+
+ Inputs:
+ in0: str
+ in1: chr
+ in2: byte count
+
+ This implementation assumes little endian mode. For big endian mode,
+ the instruction czx1.r should be replaced by czx1.l.
+
+ The algorithm is fairly straightforward: search byte by byte until we
+ we get to a word aligned address, then search word by word as much as
+ possible; the remaining few bytes are searched one at a time.
+
+ The word by word search is performed by xor-ing the word with a word
+ containing chr in every byte. If there is a hit, the result will
+ contain a zero byte in the corresponding position. The presence and
+ position of that zero byte is detected with a czx instruction.
+
+ All the loops in this function could have had the internal branch removed
+ if br.ctop and br.cloop could be predicated :-(. */
+
+#include <sysdep.h>
+#undef ret
+
+#define saved_pr r15
+#define saved_lc r16
+#define chr r17
+#define len r18
+#define pos0 r20
+#define val r21
+#define tmp r24
+#define chrx8 r25
+#define loopcnt r30
+
+#define str in0
+
+ENTRY(__memchr)
+ .prologue
+ alloc r2 = ar.pfs, 3, 0, 29, 32
+#include "softpipe.h"
+ .rotr value[MEMLAT+1], addr[MEMLAT+3], aux[2], poschr[2]
+ .rotp p[MEMLAT+3]
+ .save ar.lc, saved_lc
+ mov saved_lc = ar.lc // save the loop counter
+ .save pr, saved_pr
+ mov saved_pr = pr // save the predicates
+ .body
+ mov ret0 = str
+ and tmp = 7, str // tmp = str % 8
+ cmp.ne p7, p0 = r0, r0 // clear p7
+ extr.u chr = in1, 0, 8 // chr = (unsigned char) in1
+ mov len = in2
+ cmp.gtu p6, p0 = 16, in2 // use a simple loop for short
+(p6) br.cond.spnt .srchfew ;; // searches
+ sub loopcnt = 8, tmp // loopcnt = 8 - tmp
+ cmp.eq p6, p0 = tmp, r0
+(p6) br.cond.sptk .str_aligned;;
+ sub len = len, loopcnt
+ adds loopcnt = -1, loopcnt;;
+ mov ar.lc = loopcnt
+.l1:
+ ld1 val = [ret0], 1
+ ;;
+ cmp.eq p6, p0 = val, chr
+(p6) br.cond.spnt .foundit
+ br.cloop.sptk .l1 ;;
+.str_aligned:
+ cmp.ne p6, p0 = r0, r0 // clear p6
+ shr.u loopcnt = len, 3 // loopcnt = len / 8
+ and len = 7, len ;; // remaining len = len & 7
+ adds loopcnt = -1, loopcnt
+ mov ar.ec = MEMLAT + 3
+ mux1 chrx8 = chr, @brcst ;; // get a word full of chr
+ mov ar.lc = loopcnt
+ mov pr.rot = 1 << 16 ;;
+.l2:
+(p[0]) mov addr[0] = ret0
+(p[0]) ld8 value[0] = [ret0], 8
+(p[MEMLAT]) xor aux[0] = value[MEMLAT], chrx8
+(p[MEMLAT+1]) czx1.r poschr[0] = aux[1]
+(p[MEMLAT+2]) cmp.ne p7, p0 = 8, poschr[1]
+(p7) br.cond.dpnt .foundit
+ br.ctop.dptk .l2
+.srchfew:
+ adds loopcnt = -1, len
+ cmp.eq p6, p0 = len, r0
+(p6) br.cond.spnt .notfound ;;
+ mov ar.lc = loopcnt
+.l3:
+ ld1 val = [ret0], 1
+ ;;
+ cmp.eq p6, p0 = val, chr
+(p6) br.cond.dpnt .foundit
+ br.cloop.sptk .l3 ;;
+.notfound:
+ cmp.ne p6, p0 = r0, r0 // clear p6 (p7 was already 0 when we got here)
+ mov ret0 = r0 ;; // return NULL
+.foundit:
+ .pred.rel "mutex" p6, p7
+(p6) adds ret0 = -1, ret0 // if we got here from l1 or l3
+(p7) add ret0 = addr[MEMLAT+2], poschr[1] // if we got here from l2
+ mov pr = saved_pr, -1
+ mov ar.lc = saved_lc
+ br.ret.sptk.many b0
+
+END(__memchr)
+
+weak_alias (__memchr, memchr)
+#if !__BOUNDED_POINTERS__
+weak_alias (__memchr, __ubp_memchr)
+#endif
+libc_hidden_builtin_def (memchr)
diff --git a/libc/sysdeps/ia64/memcmp.S b/libc/sysdeps/ia64/memcmp.S
new file mode 100644
index 000000000..2eed49a2e
--- /dev/null
+++ b/libc/sysdeps/ia64/memcmp.S
@@ -0,0 +1,165 @@
+/* Optimized version of the standard memcmp() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+ Contributed by Dan Pop <Dan.Pop@cern.ch>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: the result of the comparison
+
+ Inputs:
+ in0: dest (aka s1)
+ in1: src (aka s2)
+ in2: byte count
+
+ In this form, it assumes little endian mode. For big endian mode, the
+ the two shifts in .l2 must be inverted:
+
+ shl tmp1[0] = r[1 + MEMLAT], sh1 // tmp1 = w0 << sh1
+ shr.u tmp2[0] = r[0 + MEMLAT], sh2 // tmp2 = w1 >> sh2
+
+ and all the mux1 instructions should be replaced by plain mov's. */
+
+#include <sysdep.h>
+#undef ret
+
+#define OP_T_THRES 16
+#define OPSIZ 8
+#define MEMLAT 2
+
+#define start r15
+#define saved_pr r17
+#define saved_lc r18
+#define dest r19
+#define src r20
+#define len r21
+#define asrc r22
+#define tmp r23
+#define value1 r24
+#define value2 r25
+#define sh2 r28
+#define sh1 r29
+#define loopcnt r30
+
+ENTRY(memcmp)
+ .prologue
+ alloc r2 = ar.pfs, 3, 37, 0, 40
+
+ .rotr r[MEMLAT + 2], q[MEMLAT + 5], tmp1[4], tmp2[4], val[2]
+ .rotp p[MEMLAT + 4 + 1]
+
+ mov ret0 = r0 // by default return value = 0
+ .save pr, saved_pr
+ mov saved_pr = pr // save the predicate registers
+ .save ar.lc, saved_lc
+ mov saved_lc = ar.lc // save the loop counter
+ .body
+ mov dest = in0 // dest
+ mov src = in1 // src
+ mov len = in2 // len
+ sub tmp = r0, in0 // tmp = -dest
+ ;;
+ and loopcnt = 7, tmp // loopcnt = -dest % 8
+ cmp.ge p6, p0 = OP_T_THRES, len // is len <= OP_T_THRES
+(p6) br.cond.spnt .cmpfew // compare byte by byte
+ ;;
+ cmp.eq p6, p0 = loopcnt, r0
+(p6) br.cond.sptk .dest_aligned
+ sub len = len, loopcnt // len -= -dest % 8
+ adds loopcnt = -1, loopcnt // --loopcnt
+ ;;
+ mov ar.lc = loopcnt
+.l1: // copy -dest % 8 bytes
+ ld1 value1 = [src], 1 // value = *src++
+ ld1 value2 = [dest], 1
+ ;;
+ cmp.ne p6, p0 = value1, value2
+(p6) br.cond.spnt .done
+ br.cloop.dptk .l1
+.dest_aligned:
+ and sh1 = 7, src // sh1 = src % 8
+ and tmp = -8, len // tmp = len & -OPSIZ
+ and asrc = -8, src // asrc = src & -OPSIZ -- align src
+ shr.u loopcnt = len, 3 // loopcnt = len / 8
+ and len = 7, len ;; // len = len % 8
+ shl sh1 = sh1, 3 // sh1 = 8 * (src % 8)
+ adds loopcnt = -1, loopcnt // --loopcnt
+ mov pr.rot = 1 << 16 ;; // set rotating predicates
+ sub sh2 = 64, sh1 // sh2 = 64 - sh1
+ mov ar.lc = loopcnt // set LC
+ cmp.eq p6, p0 = sh1, r0 // is the src aligned?
+(p6) br.cond.sptk .src_aligned
+ add src = src, tmp // src += len & -OPSIZ
+ mov ar.ec = MEMLAT + 4 + 1 // four more passes needed
+ ld8 r[1] = [asrc], 8 ;; // r[1] = w0
+ .align 32
+
+// We enter this loop with p6 cleared by the above comparison
+
+.l2:
+(p[0]) ld8 r[0] = [asrc], 8 // r[0] = w1
+(p[0]) ld8 q[0] = [dest], 8
+(p[MEMLAT]) shr.u tmp1[0] = r[1 + MEMLAT], sh1 // tmp1 = w0 >> sh1
+(p[MEMLAT]) shl tmp2[0] = r[0 + MEMLAT], sh2 // tmp2 = w1 << sh2
+(p[MEMLAT+4]) cmp.ne p6, p0 = q[MEMLAT + 4], val[1]
+(p[MEMLAT+3]) or val[0] = tmp1[3], tmp2[3] // val = tmp1 | tmp2
+(p6) br.cond.spnt .l2exit
+ br.ctop.sptk .l2
+ br.cond.sptk .cmpfew
+.l3exit:
+ mux1 value1 = r[MEMLAT], @rev
+ mux1 value2 = q[MEMLAT], @rev
+ cmp.ne p6, p0 = r0, r0 ;; // clear p6
+.l2exit:
+(p6) mux1 value1 = val[1], @rev
+(p6) mux1 value2 = q[MEMLAT + 4], @rev ;;
+ cmp.ltu p6, p7 = value2, value1 ;;
+(p6) mov ret0 = -1
+(p7) mov ret0 = 1
+ mov pr = saved_pr, -1 // restore the predicate registers
+ mov ar.lc = saved_lc // restore the loop counter
+ br.ret.sptk.many b0
+.src_aligned:
+ cmp.ne p6, p0 = r0, r0 // clear p6
+ mov ar.ec = MEMLAT + 1 ;; // set EC
+.l3:
+(p[0]) ld8 r[0] = [src], 8
+(p[0]) ld8 q[0] = [dest], 8
+(p[MEMLAT]) cmp.ne p6, p0 = r[MEMLAT], q[MEMLAT]
+(p6) br.cond.spnt .l3exit
+ br.ctop.dptk .l3 ;;
+.cmpfew:
+ cmp.eq p6, p0 = len, r0 // is len == 0 ?
+ adds len = -1, len // --len;
+(p6) br.cond.spnt .restore_and_exit ;;
+ mov ar.lc = len
+.l4:
+ ld1 value1 = [src], 1
+ ld1 value2 = [dest], 1
+ ;;
+ cmp.ne p6, p0 = value1, value2
+(p6) br.cond.spnt .done
+ br.cloop.dptk .l4 ;;
+.done:
+(p6) sub ret0 = value2, value1 // don't execute it if falling thru
+.restore_and_exit:
+ mov pr = saved_pr, -1 // restore the predicate registers
+ mov ar.lc = saved_lc // restore the loop counter
+ br.ret.sptk.many b0
+END(memcmp)
+
+weak_alias (memcmp, bcmp)
+libc_hidden_builtin_def (memcmp)
diff --git a/libc/sysdeps/ia64/memcpy.S b/libc/sysdeps/ia64/memcpy.S
new file mode 100644
index 000000000..a2aeea00f
--- /dev/null
+++ b/libc/sysdeps/ia64/memcpy.S
@@ -0,0 +1,436 @@
+/* Optimized version of the standard memcpy() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Dan Pop for Itanium <Dan.Pop@cern.ch>.
+ Rewritten for McKinley by Sverre Jarp, HP Labs/CERN <Sverre.Jarp@cern.ch>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: dest
+
+ Inputs:
+ in0: dest
+ in1: src
+ in2: byte count
+
+ An assembly implementation of the algorithm used by the generic C
+ version from glibc. The case when source and sest are aligned is
+ treated separately, for extra performance.
+
+ In this form, memcpy assumes little endian mode. For big endian mode,
+ sh1 must be computed using an extra instruction: sub sh1 = 64, sh1
+ and the order of r[MEMLAT] and r[MEMLAT+1] must be reverted in the
+ shrp instruction. */
+
+#define USE_LFETCH
+#define USE_FLP
+#include <sysdep.h>
+#undef ret
+
+#define LFETCH_DIST 500
+
+#define ALIGN_UNROLL_no 4 // no. of elements
+#define ALIGN_UNROLL_sh 2 // (shift amount)
+
+#define MEMLAT 8
+#define Nrot ((4*(MEMLAT+2) + 7) & ~7)
+
+#define OP_T_THRES 16
+#define OPSIZ 8
+
+#define loopcnt r14
+#define elemcnt r15
+#define saved_pr r16
+#define saved_lc r17
+#define adest r18
+#define dest r19
+#define asrc r20
+#define src r21
+#define len r22
+#define tmp2 r23
+#define tmp3 r24
+#define tmp4 r25
+#define ptable r26
+#define ploop56 r27
+#define loopaddr r28
+#define sh1 r29
+#define ptr1 r30
+#define ptr2 r31
+
+#define movi0 mov
+
+#define p_scr p6
+#define p_xtr p7
+#define p_nxtr p8
+#define p_few p9
+
+#if defined(USE_FLP)
+#define load ldf8
+#define store stf8
+#define tempreg f6
+#define the_r fr
+#define the_s fs
+#define the_t ft
+#define the_q fq
+#define the_w fw
+#define the_x fx
+#define the_y fy
+#define the_z fz
+#elif defined(USE_INT)
+#define load ld8
+#define store st8
+#define tempreg tmp2
+#define the_r r
+#define the_s s
+#define the_t t
+#define the_q q
+#define the_w w
+#define the_x x
+#define the_y y
+#define the_z z
+#endif
+
+#ifdef GAS_ALIGN_BREAKS_UNWIND_INFO
+/* Manually force proper loop-alignment. Note: be sure to
+ double-check the code-layout after making any changes to
+ this routine! */
+# define ALIGN(n) { nop 0 }
+#else
+# define ALIGN(n) .align n
+#endif
+
+#if defined(USE_LFETCH)
+#define LOOP(shift) \
+ ALIGN(32); \
+.loop##shift##: \
+{ .mmb \
+(p[0]) ld8.nt1 r[0] = [asrc], 8 ; \
+(p[0]) lfetch.nt1 [ptr1], 16 ; \
+ nop.b 0 ; \
+} { .mib \
+(p[MEMLAT+1]) st8 [dest] = tmp3, 8 ; \
+(p[MEMLAT]) shrp tmp3 = r[MEMLAT], s[MEMLAT+1], shift ; \
+ nop.b 0 ;; \
+ } { .mmb \
+(p[0]) ld8.nt1 s[0] = [asrc], 8 ; \
+(p[0]) lfetch.nt1 [ptr2], 16 ; \
+ nop.b 0 ; \
+} { .mib \
+(p[MEMLAT+1]) st8 [dest] = tmp4, 8 ; \
+(p[MEMLAT]) shrp tmp4 = s[MEMLAT], r[MEMLAT], shift ; \
+ br.ctop.sptk.many .loop##shift \
+;; } \
+{ .mib \
+ br.cond.sptk.many .copy_bytes ; /* deal with the remaining bytes */ \
+}
+#else
+#define LOOP(shift) \
+ ALIGN(32); \
+.loop##shift##: \
+{ .mmb \
+(p[0]) ld8.nt1 r[0] = [asrc], 8 ; \
+ nop.b 0 ; \
+} { .mib \
+(p[MEMLAT+1]) st8 [dest] = tmp3, 8 ; \
+(p[MEMLAT]) shrp tmp3 = r[MEMLAT], s[MEMLAT+1], shift ; \
+ nop.b 0 ;; \
+ } { .mmb \
+(p[0]) ld8.nt1 s[0] = [asrc], 8 ; \
+ nop.b 0 ; \
+} { .mib \
+(p[MEMLAT+1]) st8 [dest] = tmp4, 8 ; \
+(p[MEMLAT]) shrp tmp4 = s[MEMLAT], r[MEMLAT], shift ; \
+ br.ctop.sptk.many .loop##shift \
+;; } \
+{ .mib \
+ br.cond.sptk.many .copy_bytes ; /* deal with the remaining bytes */ \
+}
+#endif
+
+
+ENTRY(memcpy)
+{ .mmi
+ .prologue
+ alloc r2 = ar.pfs, 3, Nrot - 3, 0, Nrot
+ .rotr r[MEMLAT+1], s[MEMLAT+2], q[MEMLAT+1], t[MEMLAT+1]
+ .rotp p[MEMLAT+2]
+ .rotf fr[MEMLAT+1], fq[MEMLAT+1], fs[MEMLAT+1], ft[MEMLAT+1]
+ mov ret0 = in0 // return tmp2 = dest
+ .save pr, saved_pr
+ movi0 saved_pr = pr // save the predicate registers
+} { .mmi
+ and tmp4 = 7, in0 // check if destination is aligned
+ mov dest = in0 // dest
+ mov src = in1 // src
+;; }
+{ .mii
+ cmp.eq p_scr, p0 = in2, r0 // if (len == 0)
+ .save ar.lc, saved_lc
+ movi0 saved_lc = ar.lc // save the loop counter
+ .body
+ cmp.ge p_few, p0 = OP_T_THRES, in2 // is len <= OP_T_THRESH
+} { .mbb
+ mov len = in2 // len
+(p_scr) br.cond.dpnt.few .restore_and_exit // Branch no. 1: return dest
+(p_few) br.cond.dpnt.many .copy_bytes // Branch no. 2: copy byte by byte
+;; }
+{ .mmi
+#if defined(USE_LFETCH)
+ lfetch.nt1 [dest] //
+ lfetch.nt1 [src] //
+#endif
+ shr.u elemcnt = len, 3 // elemcnt = len / 8
+} { .mib
+ cmp.eq p_scr, p0 = tmp4, r0 // is destination aligned?
+ sub loopcnt = 7, tmp4 //
+(p_scr) br.cond.dptk.many .dest_aligned
+;; }
+{ .mmi
+ ld1 tmp2 = [src], 1 //
+ sub len = len, loopcnt, 1 // reduce len
+ movi0 ar.lc = loopcnt //
+} { .mib
+ cmp.ne p_scr, p0 = 0, loopcnt // avoid loading beyond end-point
+;; }
+
+.l0: // ---------------------------- // L0: Align src on 8-byte boundary
+{ .mmi
+ st1 [dest] = tmp2, 1 //
+(p_scr) ld1 tmp2 = [src], 1 //
+} { .mib
+ cmp.lt p_scr, p0 = 1, loopcnt // avoid load beyond end-point
+ add loopcnt = -1, loopcnt
+ br.cloop.dptk.few .l0 //
+;; }
+
+.dest_aligned:
+{ .mmi
+ and tmp4 = 7, src // ready for alignment check
+ shr.u elemcnt = len, 3 // elemcnt = len / 8
+;; }
+{ .mib
+ cmp.ne p_scr, p0 = tmp4, r0 // is source also aligned
+ tbit.nz p_xtr, p_nxtr = src, 3 // prepare a separate move if src
+} { .mib // is not 16B aligned
+ add ptr2 = LFETCH_DIST, dest // prefetch address
+ add ptr1 = LFETCH_DIST, src
+(p_scr) br.cond.dptk.many .src_not_aligned
+;; }
+
+// The optimal case, when dest, and src are aligned
+
+.both_aligned:
+{ .mmi
+ .pred.rel "mutex",p_xtr,p_nxtr
+(p_xtr) cmp.gt p_scr, p0 = ALIGN_UNROLL_no+1, elemcnt // Need N + 1 to qualify
+(p_nxtr) cmp.gt p_scr, p0 = ALIGN_UNROLL_no, elemcnt // Need only N to qualify
+ movi0 pr.rot = 1 << 16 // set rotating predicates
+} { .mib
+(p_scr) br.cond.dpnt.many .copy_full_words
+;; }
+
+{ .mmi
+(p_xtr) load tempreg = [src], 8
+(p_xtr) add elemcnt = -1, elemcnt
+ movi0 ar.ec = MEMLAT + 1 // set the epilog counter
+;; }
+{ .mmi
+(p_xtr) add len = -8, len //
+ add asrc = 16, src // one bank apart (for USE_INT)
+ shr.u loopcnt = elemcnt, ALIGN_UNROLL_sh // cater for unrolling
+;;}
+{ .mmi
+ add loopcnt = -1, loopcnt
+(p_xtr) store [dest] = tempreg, 8 // copy the "extra" word
+ nop.i 0
+;; }
+{ .mib
+ add adest = 16, dest
+ movi0 ar.lc = loopcnt // set the loop counter
+;; }
+
+#ifdef GAS_ALIGN_BREAKS_UNWIND_INFO
+ { nop 0 }
+#else
+ .align 32
+#endif
+#if defined(USE_FLP)
+.l1: // ------------------------------- // L1: Everything a multiple of 8
+{ .mmi
+#if defined(USE_LFETCH)
+(p[0]) lfetch.nt1 [ptr2],32
+#endif
+(p[0]) ldfp8 the_r[0],the_q[0] = [src], 16
+(p[0]) add len = -32, len
+} {.mmb
+(p[MEMLAT]) store [dest] = the_r[MEMLAT], 8
+(p[MEMLAT]) store [adest] = the_s[MEMLAT], 8
+;; }
+{ .mmi
+#if defined(USE_LFETCH)
+(p[0]) lfetch.nt1 [ptr1],32
+#endif
+(p[0]) ldfp8 the_s[0], the_t[0] = [src], 16
+} {.mmb
+(p[MEMLAT]) store [dest] = the_q[MEMLAT], 24
+(p[MEMLAT]) store [adest] = the_t[MEMLAT], 24
+ br.ctop.dptk.many .l1
+;; }
+#elif defined(USE_INT)
+.l1: // ------------------------------- // L1: Everything a multiple of 8
+{ .mmi
+(p[0]) load the_r[0] = [src], 8
+(p[0]) load the_q[0] = [asrc], 8
+(p[0]) add len = -32, len
+} {.mmb
+(p[MEMLAT]) store [dest] = the_r[MEMLAT], 8
+(p[MEMLAT]) store [adest] = the_q[MEMLAT], 8
+;; }
+{ .mmi
+(p[0]) load the_s[0] = [src], 24
+(p[0]) load the_t[0] = [asrc], 24
+} {.mmb
+(p[MEMLAT]) store [dest] = the_s[MEMLAT], 24
+(p[MEMLAT]) store [adest] = the_t[MEMLAT], 24
+#if defined(USE_LFETCH)
+;; }
+{ .mmb
+(p[0]) lfetch.nt1 [ptr2],32
+(p[0]) lfetch.nt1 [ptr1],32
+#endif
+ br.ctop.dptk.many .l1
+;; }
+#endif
+
+.copy_full_words:
+{ .mib
+ cmp.gt p_scr, p0 = 8, len //
+ shr.u elemcnt = len, 3 //
+(p_scr) br.cond.dpnt.many .copy_bytes
+;; }
+{ .mii
+ load tempreg = [src], 8
+ add loopcnt = -1, elemcnt //
+;; }
+{ .mii
+ cmp.ne p_scr, p0 = 0, loopcnt //
+ mov ar.lc = loopcnt //
+;; }
+
+.l2: // ------------------------------- // L2: Max 4 words copied separately
+{ .mmi
+ store [dest] = tempreg, 8
+(p_scr) load tempreg = [src], 8 //
+ add len = -8, len
+} { .mib
+ cmp.lt p_scr, p0 = 1, loopcnt // avoid load beyond end-point
+ add loopcnt = -1, loopcnt
+ br.cloop.dptk.few .l2
+;; }
+
+.copy_bytes:
+{ .mib
+ cmp.eq p_scr, p0 = len, r0 // is len == 0 ?
+ add loopcnt = -1, len // len--;
+(p_scr) br.cond.spnt .restore_and_exit
+;; }
+{ .mii
+ ld1 tmp2 = [src], 1
+ movi0 ar.lc = loopcnt
+ cmp.ne p_scr, p0 = 0, loopcnt // avoid load beyond end-point
+;; }
+
+.l3: // ------------------------------- // L3: Final byte move
+{ .mmi
+ st1 [dest] = tmp2, 1
+(p_scr) ld1 tmp2 = [src], 1
+} { .mib
+ cmp.lt p_scr, p0 = 1, loopcnt // avoid load beyond end-point
+ add loopcnt = -1, loopcnt
+ br.cloop.dptk.few .l3
+;; }
+
+.restore_and_exit:
+{ .mmi
+ movi0 pr = saved_pr, -1 // restore the predicate registers
+;; }
+{ .mib
+ movi0 ar.lc = saved_lc // restore the loop counter
+ br.ret.sptk.many b0
+;; }
+
+
+.src_not_aligned:
+{ .mmi
+ cmp.gt p_scr, p0 = 16, len
+ and sh1 = 7, src // sh1 = src % 8
+ shr.u loopcnt = len, 4 // element-cnt = len / 16
+} { .mib
+ add tmp4 = @ltoff(.table), gp
+ add tmp3 = @ltoff(.loop56), gp
+(p_scr) br.cond.dpnt.many .copy_bytes // do byte by byte if too few
+;; }
+{ .mmi
+ and asrc = -8, src // asrc = (-8) -- align src for loop
+ add loopcnt = -1, loopcnt // loopcnt--
+ shl sh1 = sh1, 3 // sh1 = 8 * (src % 8)
+} { .mmi
+ ld8 ptable = [tmp4] // ptable = &table
+ ld8 ploop56 = [tmp3] // ploop56 = &loop56
+ and tmp2 = -16, len // tmp2 = len & -OPSIZ
+;; }
+{ .mmi
+ add tmp3 = ptable, sh1 // tmp3 = &table + sh1
+ add src = src, tmp2 // src += len & (-16)
+ movi0 ar.lc = loopcnt // set LC
+;; }
+{ .mmi
+ ld8 tmp4 = [tmp3] // tmp4 = loop offset
+ sub len = len, tmp2 // len -= len & (-16)
+ movi0 ar.ec = MEMLAT + 2 // one more pass needed
+;; }
+{ .mmi
+ ld8 s[1] = [asrc], 8 // preload
+ sub loopaddr = ploop56,tmp4 // loopadd = &loop56 - loop offset
+ movi0 pr.rot = 1 << 16 // set rotating predicates
+;; }
+{ .mib
+ nop.m 0
+ movi0 b6 = loopaddr
+ br b6 // jump to the appropriate loop
+;; }
+
+ LOOP(8)
+ LOOP(16)
+ LOOP(24)
+ LOOP(32)
+ LOOP(40)
+ LOOP(48)
+ LOOP(56)
+END(memcpy)
+libc_hidden_builtin_def (memcpy)
+
+ .rodata
+ .align 8
+.table:
+ data8 0 // dummy entry
+ data8 .loop56 - .loop8
+ data8 .loop56 - .loop16
+ data8 .loop56 - .loop24
+ data8 .loop56 - .loop32
+ data8 .loop56 - .loop40
+ data8 .loop56 - .loop48
+ data8 .loop56 - .loop56
diff --git a/libc/sysdeps/ia64/memmove.S b/libc/sysdeps/ia64/memmove.S
new file mode 100644
index 000000000..7b8c86b32
--- /dev/null
+++ b/libc/sysdeps/ia64/memmove.S
@@ -0,0 +1,251 @@
+/* Optimized version of the standard memmove() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Dan Pop <Dan.Pop@cern.ch>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: dest
+
+ Inputs:
+ in0: dest
+ in1: src
+ in2: byte count
+
+ The core of the function is the memcpy implementation used in memcpy.S.
+ When bytes have to be copied backwards, only the easy case, when
+ all arguments are multiples of 8, is optimised.
+
+ In this form, it assumes little endian mode. For big endian mode,
+ sh1 must be computed using an extra instruction: sub sh1 = 64, sh1
+ or the UM.be bit should be cleared at the beginning and set at the end. */
+
+#include <sysdep.h>
+#undef ret
+
+#define OP_T_THRES 16
+#define OPSIZ 8
+
+#define adest r15
+#define saved_pr r17
+#define saved_lc r18
+#define dest r19
+#define src r20
+#define len r21
+#define asrc r22
+#define tmp2 r23
+#define tmp3 r24
+#define tmp4 r25
+#define ptable r26
+#define ploop56 r27
+#define loopaddr r28
+#define sh1 r29
+#define loopcnt r30
+#define value r31
+
+#ifdef GAS_ALIGN_BREAKS_UNWIND_INFO
+# define ALIGN(n) { nop 0 }
+#else
+# define ALIGN(n) .align n
+#endif
+
+#define LOOP(shift) \
+ ALIGN(32); \
+.loop##shift##: \
+(p[0]) ld8 r[0] = [asrc], 8 ; /* w1 */ \
+(p[MEMLAT+1]) st8 [dest] = value, 8 ; \
+(p[MEMLAT]) shrp value = r[MEMLAT], r[MEMLAT+1], shift ; \
+ nop.b 0 ; \
+ nop.b 0 ; \
+ br.ctop.sptk .loop##shift ; \
+ br.cond.sptk .cpyfew ; /* deal with the remaining bytes */
+
+#define MEMLAT 21
+#define Nrot (((2*MEMLAT+3) + 7) & ~7)
+
+ENTRY(memmove)
+ .prologue
+ alloc r2 = ar.pfs, 3, Nrot - 3, 0, Nrot
+ .rotr r[MEMLAT + 2], q[MEMLAT + 1]
+ .rotp p[MEMLAT + 2]
+ mov ret0 = in0 // return value = dest
+ .save pr, saved_pr
+ mov saved_pr = pr // save the predicate registers
+ .save ar.lc, saved_lc
+ mov saved_lc = ar.lc // save the loop counter
+ .body
+ or tmp3 = in0, in1 ;; // tmp3 = dest | src
+ or tmp3 = tmp3, in2 // tmp3 = dest | src | len
+ mov dest = in0 // dest
+ mov src = in1 // src
+ mov len = in2 // len
+ sub tmp2 = r0, in0 // tmp2 = -dest
+ cmp.eq p6, p0 = in2, r0 // if (len == 0)
+(p6) br.cond.spnt .restore_and_exit;;// return dest;
+ and tmp4 = 7, tmp3 // tmp4 = (dest | src | len) & 7
+ cmp.le p6, p0 = dest, src // if dest <= src it's always safe
+(p6) br.cond.spnt .forward // to copy forward
+ add tmp3 = src, len;;
+ cmp.lt p6, p0 = dest, tmp3 // if dest > src && dest < src + len
+(p6) br.cond.spnt .backward // we have to copy backward
+
+.forward:
+ shr.u loopcnt = len, 4 ;; // loopcnt = len / 16
+ cmp.ne p6, p0 = tmp4, r0 // if ((dest | src | len) & 7 != 0)
+(p6) br.cond.sptk .next // goto next;
+
+// The optimal case, when dest, src and len are all multiples of 8
+
+ and tmp3 = 0xf, len
+ mov pr.rot = 1 << 16 // set rotating predicates
+ mov ar.ec = MEMLAT + 1 ;; // set the epilog counter
+ cmp.ne p6, p0 = tmp3, r0 // do we have to copy an extra word?
+ adds loopcnt = -1, loopcnt;; // --loopcnt
+(p6) ld8 value = [src], 8;;
+(p6) st8 [dest] = value, 8 // copy the "odd" word
+ mov ar.lc = loopcnt // set the loop counter
+ cmp.eq p6, p0 = 8, len
+(p6) br.cond.spnt .restore_and_exit;;// the one-word special case
+ adds adest = 8, dest // set adest one word ahead of dest
+ adds asrc = 8, src ;; // set asrc one word ahead of src
+ nop.b 0 // get the "golden" alignment for
+ nop.b 0 // the next loop
+.l0:
+(p[0]) ld8 r[0] = [src], 16
+(p[0]) ld8 q[0] = [asrc], 16
+(p[MEMLAT]) st8 [dest] = r[MEMLAT], 16
+(p[MEMLAT]) st8 [adest] = q[MEMLAT], 16
+ br.ctop.dptk .l0 ;;
+
+ mov pr = saved_pr, -1 // restore the predicate registers
+ mov ar.lc = saved_lc // restore the loop counter
+ br.ret.sptk.many b0
+.next:
+ cmp.ge p6, p0 = OP_T_THRES, len // is len <= OP_T_THRES
+ and loopcnt = 7, tmp2 // loopcnt = -dest % 8
+(p6) br.cond.spnt .cpyfew // copy byte by byte
+ ;;
+ cmp.eq p6, p0 = loopcnt, r0
+(p6) br.cond.sptk .dest_aligned
+ sub len = len, loopcnt // len -= -dest % 8
+ adds loopcnt = -1, loopcnt // --loopcnt
+ ;;
+ mov ar.lc = loopcnt
+.l1: // copy -dest % 8 bytes
+ ld1 value = [src], 1 // value = *src++
+ ;;
+ st1 [dest] = value, 1 // *dest++ = value
+ br.cloop.dptk .l1
+.dest_aligned:
+ and sh1 = 7, src // sh1 = src % 8
+ and tmp2 = -8, len // tmp2 = len & -OPSIZ
+ and asrc = -8, src // asrc = src & -OPSIZ -- align src
+ shr.u loopcnt = len, 3 // loopcnt = len / 8
+ and len = 7, len;; // len = len % 8
+ adds loopcnt = -1, loopcnt // --loopcnt
+ addl tmp4 = @ltoff(.table), gp
+ addl tmp3 = @ltoff(.loop56), gp
+ mov ar.ec = MEMLAT + 1 // set EC
+ mov pr.rot = 1 << 16;; // set rotating predicates
+ mov ar.lc = loopcnt // set LC
+ cmp.eq p6, p0 = sh1, r0 // is the src aligned?
+(p6) br.cond.sptk .src_aligned
+ add src = src, tmp2 // src += len & -OPSIZ
+ shl sh1 = sh1, 3 // sh1 = 8 * (src % 8)
+ ld8 ploop56 = [tmp3] // ploop56 = &loop56
+ ld8 ptable = [tmp4];; // ptable = &table
+ add tmp3 = ptable, sh1;; // tmp3 = &table + sh1
+ mov ar.ec = MEMLAT + 1 + 1 // one more pass needed
+ ld8 tmp4 = [tmp3];; // tmp4 = loop offset
+ sub loopaddr = ploop56,tmp4 // loopadd = &loop56 - loop offset
+ ld8 r[1] = [asrc], 8;; // w0
+ mov b6 = loopaddr;;
+ br b6 // jump to the appropriate loop
+
+ LOOP(8)
+ LOOP(16)
+ LOOP(24)
+ LOOP(32)
+ LOOP(40)
+ LOOP(48)
+ LOOP(56)
+
+.src_aligned:
+.l3:
+(p[0]) ld8 r[0] = [src], 8
+(p[MEMLAT]) st8 [dest] = r[MEMLAT], 8
+ br.ctop.dptk .l3
+.cpyfew:
+ cmp.eq p6, p0 = len, r0 // is len == 0 ?
+ adds len = -1, len // --len;
+(p6) br.cond.spnt .restore_and_exit ;;
+ mov ar.lc = len
+.l4:
+ ld1 value = [src], 1
+ ;;
+ st1 [dest] = value, 1
+ br.cloop.dptk .l4 ;;
+.restore_and_exit:
+ mov pr = saved_pr, -1 // restore the predicate registers
+ mov ar.lc = saved_lc // restore the loop counter
+ br.ret.sptk.many b0
+
+// In the case of a backward copy, optimise only the case when everything
+// is a multiple of 8, otherwise copy byte by byte. The backward copy is
+// used only when the blocks are overlapping and dest > src.
+
+.backward:
+ shr.u loopcnt = len, 3 // loopcnt = len / 8
+ add src = src, len // src points one byte past the end
+ add dest = dest, len ;; // dest points one byte past the end
+ mov ar.ec = MEMLAT + 1 // set the epilog counter
+ mov pr.rot = 1 << 16 // set rotating predicates
+ adds loopcnt = -1, loopcnt // --loopcnt
+ cmp.ne p6, p0 = tmp4, r0 // if ((dest | src | len) & 7 != 0)
+(p6) br.cond.sptk .bytecopy ;; // copy byte by byte backward
+ adds src = -8, src // src points to the last word
+ adds dest = -8, dest // dest points to the last word
+ mov ar.lc = loopcnt;; // set the loop counter
+.l5:
+(p[0]) ld8 r[0] = [src], -8
+(p[MEMLAT]) st8 [dest] = r[MEMLAT], -8
+ br.ctop.dptk .l5
+ br.cond.sptk .restore_and_exit
+.bytecopy:
+ adds src = -1, src // src points to the last byte
+ adds dest = -1, dest // dest points to the last byte
+ adds loopcnt = -1, len;; // loopcnt = len - 1
+ mov ar.lc = loopcnt;; // set the loop counter
+.l6:
+(p[0]) ld1 r[0] = [src], -1
+(p[MEMLAT]) st1 [dest] = r[MEMLAT], -1
+ br.ctop.dptk .l6
+ br.cond.sptk .restore_and_exit
+END(memmove)
+
+ .rodata
+ .align 8
+.table:
+ data8 0 // dummy entry
+ data8 .loop56 - .loop8
+ data8 .loop56 - .loop16
+ data8 .loop56 - .loop24
+ data8 .loop56 - .loop32
+ data8 .loop56 - .loop40
+ data8 .loop56 - .loop48
+ data8 .loop56 - .loop56
+
+libc_hidden_builtin_def (memmove)
diff --git a/libc/sysdeps/ia64/memset.S b/libc/sysdeps/ia64/memset.S
new file mode 100644
index 000000000..84d8f0a19
--- /dev/null
+++ b/libc/sysdeps/ia64/memset.S
@@ -0,0 +1,400 @@
+/* Optimized version of the standard memset() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Dan Pop for Itanium <Dan.Pop@cern.ch>.
+ Rewritten for McKinley by Sverre Jarp, HP Labs/CERN <Sverre.Jarp@cern.ch>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: dest
+
+ Inputs:
+ in0: dest
+ in1: value
+ in2: count
+
+ The algorithm is fairly straightforward: set byte by byte until we
+ we get to a 16B-aligned address, then loop on 128 B chunks using an
+ early store as prefetching, then loop on 32B chucks, then clear remaining
+ words, finally clear remaining bytes.
+ Since a stf.spill f0 can store 16B in one go, we use this instruction
+ to get peak speed when value = 0. */
+
+#include <sysdep.h>
+#undef ret
+
+#define dest in0
+#define value in1
+#define cnt in2
+
+#define tmp r31
+#define save_lc r30
+#define ptr0 r29
+#define ptr1 r28
+#define ptr2 r27
+#define ptr3 r26
+#define ptr9 r24
+#define loopcnt r23
+#define linecnt r22
+#define bytecnt r21
+
+#define fvalue f6
+
+// This routine uses only scratch predicate registers (p6 - p15)
+#define p_scr p6 // default register for same-cycle branches
+#define p_nz p7
+#define p_zr p8
+#define p_unalgn p9
+#define p_y p11
+#define p_n p12
+#define p_yy p13
+#define p_nn p14
+
+#define movi0 mov
+
+#define MIN1 15
+#define MIN1P1HALF 8
+#define LINE_SIZE 128
+#define LSIZE_SH 7 // shift amount
+#define PREF_AHEAD 8
+
+#define USE_FLP
+#if defined(USE_INT)
+#define store st8
+#define myval value
+#elif defined(USE_FLP)
+#define store stf8
+#define myval fvalue
+#endif
+
+.align 64
+ENTRY(memset)
+{ .mmi
+ .prologue
+ alloc tmp = ar.pfs, 3, 0, 0, 0
+ lfetch.nt1 [dest]
+ .save ar.lc, save_lc
+ movi0 save_lc = ar.lc
+} { .mmi
+ .body
+ mov ret0 = dest // return value
+ cmp.ne p_nz, p_zr = value, r0 // use stf.spill if value is zero
+ cmp.eq p_scr, p0 = cnt, r0
+;; }
+{ .mmi
+ and ptr2 = -(MIN1+1), dest // aligned address
+ and tmp = MIN1, dest // prepare to check for alignment
+ tbit.nz p_y, p_n = dest, 0 // Do we have an odd address? (M_B_U)
+} { .mib
+ mov ptr1 = dest
+ mux1 value = value, @brcst // create 8 identical bytes in word
+(p_scr) br.ret.dpnt.many rp // return immediately if count = 0
+;; }
+{ .mib
+ cmp.ne p_unalgn, p0 = tmp, r0
+} { .mib // NB: # of bytes to move is 1 higher
+ sub bytecnt = (MIN1+1), tmp // than loopcnt
+ cmp.gt p_scr, p0 = 16, cnt // is it a minimalistic task?
+(p_scr) br.cond.dptk.many .move_bytes_unaligned // go move just a few (M_B_U)
+;; }
+{ .mmi
+(p_unalgn) add ptr1 = (MIN1+1), ptr2 // after alignment
+(p_unalgn) add ptr2 = MIN1P1HALF, ptr2 // after alignment
+(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 3 // should we do a st8 ?
+;; }
+{ .mib
+(p_y) add cnt = -8, cnt
+(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 2 // should we do a st4 ?
+} { .mib
+(p_y) st8 [ptr2] = value, -4
+(p_n) add ptr2 = 4, ptr2
+;; }
+{ .mib
+(p_yy) add cnt = -4, cnt
+(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 1 // should we do a st2 ?
+} { .mib
+(p_yy) st4 [ptr2] = value, -2
+(p_nn) add ptr2 = 2, ptr2
+;; }
+{ .mmi
+ mov tmp = LINE_SIZE+1 // for compare
+(p_y) add cnt = -2, cnt
+(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 0 // should we do a st1 ?
+} { .mmi
+ setf.sig fvalue=value // transfer value to FLP side
+(p_y) st2 [ptr2] = value, -1
+(p_n) add ptr2 = 1, ptr2
+;; }
+
+{ .mmi
+(p_yy) st1 [ptr2] = value
+ cmp.gt p_scr, p0 = tmp, cnt // is it a minimalistic task?
+} { .mbb
+(p_yy) add cnt = -1, cnt
+(p_scr) br.cond.dpnt.many .fraction_of_line // go move just a few
+;; }
+
+{ .mib
+ nop.m 0
+ shr.u linecnt = cnt, LSIZE_SH
+(p_zr) br.cond.dptk.many .l1b // Jump to use stf.spill
+;; }
+
+#ifndef GAS_ALIGN_BREAKS_UNWIND_INFO
+ .align 32 // -------- // L1A: store ahead into cache lines; fill later
+#endif
+{ .mmi
+ and tmp = -(LINE_SIZE), cnt // compute end of range
+ mov ptr9 = ptr1 // used for prefetching
+ and cnt = (LINE_SIZE-1), cnt // remainder
+} { .mmi
+ mov loopcnt = PREF_AHEAD-1 // default prefetch loop
+ cmp.gt p_scr, p0 = PREF_AHEAD, linecnt // check against actual value
+;; }
+{ .mmi
+(p_scr) add loopcnt = -1, linecnt // start of stores
+ add ptr2 = 8, ptr1 // (beyond prefetch stores)
+ add ptr1 = tmp, ptr1 // first address beyond total
+;; } // range
+{ .mmi
+ add tmp = -1, linecnt // next loop count
+ movi0 ar.lc = loopcnt
+;; }
+.pref_l1a:
+{ .mib
+ store [ptr9] = myval, 128 // Do stores one cache line apart
+ nop.i 0
+ br.cloop.dptk.few .pref_l1a
+;; }
+{ .mmi
+ add ptr0 = 16, ptr2 // Two stores in parallel
+ movi0 ar.lc = tmp
+;; }
+.l1ax:
+ { .mmi
+ store [ptr2] = myval, 8
+ store [ptr0] = myval, 8
+ ;; }
+ { .mmi
+ store [ptr2] = myval, 24
+ store [ptr0] = myval, 24
+ ;; }
+ { .mmi
+ store [ptr2] = myval, 8
+ store [ptr0] = myval, 8
+ ;; }
+ { .mmi
+ store [ptr2] = myval, 24
+ store [ptr0] = myval, 24
+ ;; }
+ { .mmi
+ store [ptr2] = myval, 8
+ store [ptr0] = myval, 8
+ ;; }
+ { .mmi
+ store [ptr2] = myval, 24
+ store [ptr0] = myval, 24
+ ;; }
+ { .mmi
+ store [ptr2] = myval, 8
+ store [ptr0] = myval, 32
+ cmp.lt p_scr, p0 = ptr9, ptr1 // do we need more prefetching?
+ ;; }
+{ .mmb
+ store [ptr2] = myval, 24
+(p_scr) store [ptr9] = myval, 128
+ br.cloop.dptk.few .l1ax
+;; }
+{ .mbb
+ cmp.le p_scr, p0 = 8, cnt // just a few bytes left ?
+(p_scr) br.cond.dpnt.many .fraction_of_line // Branch no. 2
+ br.cond.dpnt.many .move_bytes_from_alignment // Branch no. 3
+;; }
+
+#ifdef GAS_ALIGN_BREAKS_UNWIND_INFO
+ { nop 0 }
+#else
+ .align 32
+#endif
+.l1b: // ------------------ // L1B: store ahead into cache lines; fill later
+{ .mmi
+ and tmp = -(LINE_SIZE), cnt // compute end of range
+ mov ptr9 = ptr1 // used for prefetching
+ and cnt = (LINE_SIZE-1), cnt // remainder
+} { .mmi
+ mov loopcnt = PREF_AHEAD-1 // default prefetch loop
+ cmp.gt p_scr, p0 = PREF_AHEAD, linecnt // check against actual value
+;; }
+{ .mmi
+(p_scr) add loopcnt = -1, linecnt
+ add ptr2 = 16, ptr1 // start of stores (beyond prefetch stores)
+ add ptr1 = tmp, ptr1 // first address beyond total range
+;; }
+{ .mmi
+ add tmp = -1, linecnt // next loop count
+ movi0 ar.lc = loopcnt
+;; }
+.pref_l1b:
+{ .mib
+ stf.spill [ptr9] = f0, 128 // Do stores one cache line apart
+ nop.i 0
+ br.cloop.dptk.few .pref_l1b
+;; }
+{ .mmi
+ add ptr0 = 16, ptr2 // Two stores in parallel
+ movi0 ar.lc = tmp
+;; }
+.l1bx:
+ { .mmi
+ stf.spill [ptr2] = f0, 32
+ stf.spill [ptr0] = f0, 32
+ ;; }
+ { .mmi
+ stf.spill [ptr2] = f0, 32
+ stf.spill [ptr0] = f0, 32
+ ;; }
+ { .mmi
+ stf.spill [ptr2] = f0, 32
+ stf.spill [ptr0] = f0, 64
+ cmp.lt p_scr, p0 = ptr9, ptr1 // do we need more prefetching?
+ ;; }
+{ .mmb
+ stf.spill [ptr2] = f0, 32
+(p_scr) stf.spill [ptr9] = f0, 128
+ br.cloop.dptk.few .l1bx
+;; }
+{ .mib
+ cmp.gt p_scr, p0 = 8, cnt // just a few bytes left ?
+(p_scr) br.cond.dpnt.many .move_bytes_from_alignment
+;; }
+
+.fraction_of_line:
+{ .mib
+ add ptr2 = 16, ptr1
+ shr.u loopcnt = cnt, 5 // loopcnt = cnt / 32
+;; }
+{ .mib
+ cmp.eq p_scr, p0 = loopcnt, r0
+ add loopcnt = -1, loopcnt
+(p_scr) br.cond.dpnt.many store_words
+;; }
+{ .mib
+ and cnt = 0x1f, cnt // compute the remaining cnt
+ movi0 ar.lc = loopcnt
+;; }
+#ifndef GAS_ALIGN_BREAKS_UNWIND_INFO
+ .align 32
+#endif
+.l2: // ---------------------------- // L2A: store 32B in 2 cycles
+{ .mmb
+ store [ptr1] = myval, 8
+ store [ptr2] = myval, 8
+;; } { .mmb
+ store [ptr1] = myval, 24
+ store [ptr2] = myval, 24
+ br.cloop.dptk.many .l2
+;; }
+store_words:
+{ .mib
+ cmp.gt p_scr, p0 = 8, cnt // just a few bytes left ?
+(p_scr) br.cond.dpnt.many .move_bytes_from_alignment // Branch
+;; }
+
+{ .mmi
+ store [ptr1] = myval, 8 // store
+ cmp.le p_y, p_n = 16, cnt //
+ add cnt = -8, cnt // subtract
+;; }
+{ .mmi
+(p_y) store [ptr1] = myval, 8 // store
+(p_y) cmp.le.unc p_yy, p_nn = 16, cnt //
+(p_y) add cnt = -8, cnt // subtract
+;; }
+{ .mmi // store
+(p_yy) store [ptr1] = myval, 8 //
+(p_yy) add cnt = -8, cnt // subtract
+;; }
+
+.move_bytes_from_alignment:
+{ .mib
+ cmp.eq p_scr, p0 = cnt, r0
+ tbit.nz.unc p_y, p0 = cnt, 2 // should we terminate with a st4 ?
+(p_scr) br.cond.dpnt.few .restore_and_exit
+;; }
+{ .mib
+(p_y) st4 [ptr1] = value, 4
+ tbit.nz.unc p_yy, p0 = cnt, 1 // should we terminate with a st2 ?
+;; }
+{ .mib
+(p_yy) st2 [ptr1] = value, 2
+ tbit.nz.unc p_y, p0 = cnt, 0
+;; }
+
+{ .mib
+(p_y) st1 [ptr1] = value
+;; }
+.restore_and_exit:
+{ .mib
+ nop.m 0
+ movi0 ar.lc = save_lc
+ br.ret.sptk.many rp
+;; }
+
+.move_bytes_unaligned:
+{ .mmi
+ .pred.rel "mutex",p_y, p_n
+ .pred.rel "mutex",p_yy, p_nn
+(p_n) cmp.le p_yy, p_nn = 4, cnt
+(p_y) cmp.le p_yy, p_nn = 5, cnt
+(p_n) add ptr2 = 2, ptr1
+} { .mmi
+(p_y) add ptr2 = 3, ptr1
+(p_y) st1 [ptr1] = value, 1 // fill 1 (odd-aligned) byte
+(p_y) add cnt = -1, cnt // [15, 14 (or less) left]
+;; }
+{ .mmi
+(p_yy) cmp.le.unc p_y, p0 = 8, cnt
+ add ptr3 = ptr1, cnt // prepare last store
+ movi0 ar.lc = save_lc
+} { .mmi
+(p_yy) st2 [ptr1] = value, 4 // fill 2 (aligned) bytes
+(p_yy) st2 [ptr2] = value, 4 // fill 2 (aligned) bytes
+(p_yy) add cnt = -4, cnt // [11, 10 (o less) left]
+;; }
+{ .mmi
+(p_y) cmp.le.unc p_yy, p0 = 8, cnt
+ add ptr3 = -1, ptr3 // last store
+ tbit.nz p_scr, p0 = cnt, 1 // will there be a st2 at the end ?
+} { .mmi
+(p_y) st2 [ptr1] = value, 4 // fill 2 (aligned) bytes
+(p_y) st2 [ptr2] = value, 4 // fill 2 (aligned) bytes
+(p_y) add cnt = -4, cnt // [7, 6 (or less) left]
+;; }
+{ .mmi
+(p_yy) st2 [ptr1] = value, 4 // fill 2 (aligned) bytes
+(p_yy) st2 [ptr2] = value, 4 // fill 2 (aligned) bytes
+ // [3, 2 (or less) left]
+ tbit.nz p_y, p0 = cnt, 0 // will there be a st1 at the end ?
+} { .mmi
+(p_yy) add cnt = -4, cnt
+;; }
+{ .mmb
+(p_scr) st2 [ptr1] = value // fill 2 (aligned) bytes
+(p_y) st1 [ptr3] = value // fill last byte (using ptr3)
+ br.ret.sptk.many rp
+;; }
+END(memset)
+libc_hidden_builtin_def (memset)
diff --git a/libc/sysdeps/ia64/memusage.h b/libc/sysdeps/ia64/memusage.h
new file mode 100644
index 000000000..5f395b88d
--- /dev/null
+++ b/libc/sysdeps/ia64/memusage.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hp-timing.h>
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("%r12"); stack_ptr; })
+#define GETTIME(low, high) \
+ { \
+ hp_timing_t __now; \
+ HP_TIMING_NOW (__now); \
+ low = __now & 0xffffffff; \
+ high = __now >> 32; \
+ }
+
+#include <sysdeps/generic/memusage.h>
diff --git a/libc/sysdeps/ia64/softpipe.h b/libc/sysdeps/ia64/softpipe.h
new file mode 100644
index 000000000..cf0eb5355
--- /dev/null
+++ b/libc/sysdeps/ia64/softpipe.h
@@ -0,0 +1,29 @@
+/* This file is part of the GNU C Library.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The latency of a memory load assumed by the assembly implementation
+ of the mem and str functions. Since we don't have any clue about
+ where the data might be, let's assume it's in the L2 cache.
+ Assuming L3 would be too pessimistic :-)
+
+ Some functions define MEMLAT as 2, because they expect their data
+ to be in the L1D cache. */
+
+#ifndef MEMLAT
+# define MEMLAT 6
+#endif
diff --git a/libc/sysdeps/ia64/stackinfo.h b/libc/sysdeps/ia64/stackinfo.h
new file mode 100644
index 000000000..b7dc5d91d
--- /dev/null
+++ b/libc/sysdeps/ia64/stackinfo.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file contains a bit of information about the stack allocation
+ of the processor. */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H 1
+
+/* On IA-64 the stack grows down. The register stack is of no concern
+ here. */
+#define _STACK_GROWS_DOWN 1
+
+#endif /* stackinfo.h */
diff --git a/libc/sysdeps/ia64/strcat.c b/libc/sysdeps/ia64/strcat.c
new file mode 100644
index 000000000..8633aa07b
--- /dev/null
+++ b/libc/sysdeps/ia64/strcat.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+
+char *
+strcat (char *dest, const char *src)
+{
+ strcpy (dest + strlen (dest), src);
+ return dest;
+}
+libc_hidden_builtin_def (strcat)
diff --git a/libc/sysdeps/ia64/strchr.S b/libc/sysdeps/ia64/strchr.S
new file mode 100644
index 000000000..63db7ff7e
--- /dev/null
+++ b/libc/sysdeps/ia64/strchr.S
@@ -0,0 +1,112 @@
+/* Optimized version of the standard strchr() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Dan Pop <Dan.Pop@cern.ch>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: the address of the first occurence of chr in str or NULL
+
+ Inputs:
+ in0: str
+ in1: chr
+
+ A modified version of memchr.S, the search ends when the character is
+ found or the terminating null character is encountered.
+
+ This implementation assumes little endian mode. For big endian mode,
+ the instruction czx1.r should be replaced by czx1.l. */
+
+#include <sysdep.h>
+#undef ret
+
+#define saved_lc r18
+#define poschr r19
+#define pos0 r20
+#define val1 r21
+#define val2 r22
+#define tmp r24
+#define chrx8 r25
+#define loopcnt r30
+
+#define str in0
+#define chr in1
+
+ENTRY(strchr)
+ .prologue
+ alloc r2 = ar.pfs, 2, 0, 0, 0
+ .save ar.lc, saved_lc
+ mov saved_lc = ar.lc // save the loop counter
+ .body
+ mov ret0 = str
+ and tmp = 7, str // tmp = str % 8
+ mux1 chrx8 = chr, @brcst
+ extr.u chr = chr, 0, 8 // retain only the last byte
+ cmp.ne p8, p0 = r0, r0 // clear p8
+ ;;
+ sub loopcnt = 8, tmp // loopcnt = 8 - tmp
+ cmp.eq p6, p0 = tmp, r0
+(p6) br.cond.sptk .str_aligned;;
+ adds loopcnt = -1, loopcnt;;
+ mov ar.lc = loopcnt
+.l1:
+ ld1 val2 = [ret0], 1
+ ;;
+ cmp.eq p6, p0 = val2, chr
+ cmp.eq p7, p0 = val2, r0
+(p6) br.cond.spnt .restore_and_exit
+(p7) br.cond.spnt .notfound
+ br.cloop.sptk .l1
+.str_aligned:
+ ld8 val1 = [ret0], 8;;
+ nop.b 0
+ nop.b 0
+.l2:
+ ld8.s val2 = [ret0], 8 // don't bomb out here
+ czx1.r pos0 = val1
+ xor tmp = val1, chrx8 // if val1 contains chr, tmp will
+ ;; // contain a zero in its position
+ czx1.r poschr = tmp
+ cmp.ne p6, p0 = 8, pos0
+ ;;
+ cmp.ne p7, p0 = 8, poschr
+(p7) br.cond.spnt .foundit
+(p6) br.cond.spnt .notfound
+ chk.s val2, .recovery
+.back:
+ mov val1 = val2
+ br.cond.dptk .l2
+.foundit:
+(p6) cmp.lt p8, p0 = pos0, poschr // we found chr and null in the word
+(p8) br.cond.spnt .notfound // null was found before chr
+ add ret0 = ret0, poschr ;;
+ adds ret0 = -15, ret0 ;; // should be -16, but we decrement
+.restore_and_exit: // ret0 in the next instruction
+ adds ret0 = -1, ret0 // ret0 was pointing 1 char too far
+ mov ar.lc = saved_lc // restore the loop counter
+ br.ret.sptk.many b0
+.notfound:
+ mov ret0 = r0 // return NULL if null was found
+ mov ar.lc = saved_lc
+ br.ret.sptk.many b0
+.recovery:
+ adds ret0 = -8, ret0;;
+ ld8 val2 = [ret0], 8 // bomb out here
+ br.cond.sptk .back
+END(strchr)
+
+weak_alias (strchr, index)
+libc_hidden_builtin_def (strchr)
diff --git a/libc/sysdeps/ia64/strcmp.S b/libc/sysdeps/ia64/strcmp.S
new file mode 100644
index 000000000..15bfeb4a7
--- /dev/null
+++ b/libc/sysdeps/ia64/strcmp.S
@@ -0,0 +1,54 @@
+/* Optimized version of the standard strcmp() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Dan Pop <Dan.Pop@cern.ch>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: the result of the comparison
+
+ Inputs:
+ in0: s1
+ in1: s2
+
+ Unlike memcmp(), this function is optimized for mismatches within the
+ first few characters. */
+
+#include <sysdep.h>
+#undef ret
+
+#define s1 in0
+#define s2 in1
+
+#define val1 r15
+#define val2 r16
+
+
+ENTRY(strcmp)
+ alloc r2 = ar.pfs, 2, 0, 0, 0
+.loop:
+ ld1 val1 = [s1], 1
+ ld1 val2 = [s2], 1
+ cmp.eq p6, p0 = r0, r0 // set p6
+ ;;
+ cmp.ne.and p6, p0 = val1, r0
+ cmp.ne.and p6, p0 = val2, r0
+ cmp.eq.and p6, p0 = val1, val2
+(p6) br.cond.sptk .loop
+ sub ret0 = val1, val2
+ br.ret.sptk.many b0
+END(strcmp)
+libc_hidden_builtin_def (strcmp)
diff --git a/libc/sysdeps/ia64/strcpy.S b/libc/sysdeps/ia64/strcpy.S
new file mode 100644
index 000000000..8745c8e8e
--- /dev/null
+++ b/libc/sysdeps/ia64/strcpy.S
@@ -0,0 +1,145 @@
+/* Optimized version of the standard strcpy() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Dan Pop <Dan.Pop@cern.ch>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: dest
+
+ Inputs:
+ in0: dest
+ in1: src
+
+ In this form, it assumes little endian mode. For big endian mode, the
+ the two shifts in .l2 must be inverted:
+
+ shl value = r[1], sh1 // value = w0 << sh1
+ shr.u tmp = r[0], sh2 // tmp = w1 >> sh2
+ */
+
+#include <sysdep.h>
+#undef ret
+
+#define saved_lc r15
+#define saved_pr r16
+#define thresh r17
+#define dest r19
+#define src r20
+#define len r21
+#define asrc r22
+#define tmp r23
+#define pos r24
+#define w0 r25
+#define w1 r26
+#define c r27
+#define sh2 r28
+#define sh1 r29
+#define loopcnt r30
+#define value r31
+
+ENTRY(strcpy)
+ .prologue
+ alloc r2 = ar.pfs, 2, 0, 30, 32
+
+#define MEMLAT 2
+ .rotr r[MEMLAT + 2]
+ .rotp p[MEMLAT + 1]
+
+ mov ret0 = in0 // return value = dest
+ .save pr, saved_pr
+ mov saved_pr = pr // save the predicate registers
+ .save ar.lc, saved_lc
+ mov saved_lc = ar.lc // save the loop counter
+ .body
+ sub tmp = r0, in0 ;; // tmp = -dest
+ mov dest = in0 // dest
+ mov src = in1 // src
+ and loopcnt = 7, tmp ;; // loopcnt = -dest % 8
+ cmp.eq p6, p0 = loopcnt, r0
+ adds loopcnt = -1, loopcnt // --loopcnt
+(p6) br.cond.sptk .dest_aligned ;;
+ mov ar.lc = loopcnt
+.l1: // copy -dest % 8 bytes
+ ld1 c = [src], 1 // c = *src++
+ ;;
+ st1 [dest] = c, 1 // *dest++ = c
+ cmp.eq p6, p0 = c, r0
+(p6) br.cond.dpnt .restore_and_exit
+ br.cloop.dptk .l1 ;;
+.dest_aligned:
+ and sh1 = 7, src // sh1 = src % 8
+ mov ar.lc = -1 // "infinite" loop
+ and asrc = -8, src ;; // asrc = src & -OPSIZ -- align src
+ sub thresh = 8, sh1
+ mov pr.rot = 1 << 16 // set rotating predicates
+ cmp.ne p7, p0 = r0, r0 // clear p7
+ shl sh1 = sh1, 3 ;; // sh1 = 8 * (src % 8)
+ sub sh2 = 64, sh1 // sh2 = 64 - sh1
+ cmp.eq p6, p0 = sh1, r0 // is the src aligned?
+(p6) br.cond.sptk .src_aligned ;;
+ ld8 r[1] = [asrc],8 ;;
+
+ .align 32
+.l2:
+ ld8.s r[0] = [asrc], 8
+ shr.u value = r[1], sh1 ;; // value = w0 >> sh1
+ czx1.r pos = value ;; // do we have an "early" zero
+ cmp.lt p7, p0 = pos, thresh // in w0 >> sh1?
+(p7) br.cond.dpnt .found0
+ chk.s r[0], .recovery2 // it is safe to do that only
+.back2: // after the previous test
+ shl tmp = r[0], sh2 // tmp = w1 << sh2
+ ;;
+ or value = value, tmp ;; // value |= tmp
+ czx1.r pos = value ;;
+ cmp.ne p7, p0 = 8, pos
+(p7) br.cond.dpnt .found0
+ st8 [dest] = value, 8 // store val to dest
+ br.ctop.dptk .l2 ;;
+.src_aligned:
+.l3:
+(p[0]) ld8.s r[0] = [src], 8
+(p[MEMLAT]) chk.s r[MEMLAT], .recovery3
+.back3:
+(p[MEMLAT]) mov value = r[MEMLAT]
+(p[MEMLAT]) czx1.r pos = r[MEMLAT] ;;
+(p[MEMLAT]) cmp.ne p7, p0 = 8, pos
+(p7) br.cond.dpnt .found0
+(p[MEMLAT]) st8 [dest] = r[MEMLAT], 8
+ br.ctop.dptk .l3 ;;
+.found0:
+ mov ar.lc = pos
+.l4:
+ extr.u c = value, 0, 8 // c = value & 0xff
+ shr.u value = value, 8
+ ;;
+ st1 [dest] = c, 1
+ br.cloop.dptk .l4 ;;
+.restore_and_exit:
+ mov ar.lc = saved_lc // restore the loop counter
+ mov pr = saved_pr, -1 // restore the predicate registers
+ br.ret.sptk.many b0
+.recovery2:
+ add tmp = -8, asrc ;;
+ ld8 r[0] = [tmp]
+ br.cond.sptk .back2
+.recovery3:
+ add tmp = -(MEMLAT + 1) * 8, src ;;
+ ld8 r[MEMLAT] = [tmp]
+ br.cond.sptk .back3
+END(strcpy)
+libc_hidden_builtin_def (strcpy)
diff --git a/libc/sysdeps/ia64/strlen.S b/libc/sysdeps/ia64/strlen.S
new file mode 100644
index 000000000..518d86b0d
--- /dev/null
+++ b/libc/sysdeps/ia64/strlen.S
@@ -0,0 +1,98 @@
+/* Optimized version of the standard strlen() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
+ Contributed by Dan Pop <Dan.Pop@cern.ch>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: the length of the input string
+
+ Input:
+ in0: str
+
+ Look for the null character byte by byte, until we reach a word aligned
+ address, then search word by word, using the czx instruction. We're
+ also doing one word of read ahead, which could cause problems if the
+ null character is on the last word of a page and the next page is not
+ mapped in the process address space. Hence the use of the speculative
+ load.
+
+ This implementation assumes little endian mode. For big endian mode,
+ the instruction czx1.r should be replaced by czx1.l. */
+
+#include <sysdep.h>
+#undef ret
+
+#define saved_lc r18
+#define str r19
+#define pos0 r20
+#define val1 r21
+#define val2 r22
+#define origadd r23
+#define tmp r24
+#define loopcnt r30
+#define len ret0
+
+ENTRY(strlen)
+ .prologue
+ alloc r2 = ar.pfs, 1, 0, 0, 0
+ .save ar.lc, saved_lc
+ mov saved_lc = ar.lc // save the loop counter
+ .body
+ mov str = in0
+ mov len = r0 // len = 0
+ and tmp = 7, in0 // tmp = str % 8
+ ;;
+ sub loopcnt = 8, tmp // loopcnt = 8 - tmp
+ cmp.eq p6, p0 = tmp, r0
+(p6) br.cond.sptk .str_aligned;;
+ adds loopcnt = -1, loopcnt;;
+ mov ar.lc = loopcnt
+.l1:
+ ld1 val2 = [str], 1
+ ;;
+ cmp.eq p6, p0 = val2, r0
+(p6) br.cond.spnt .restore_and_exit
+ adds len = 1, len
+ br.cloop.dptk .l1
+.str_aligned:
+ mov origadd = str // origadd = orig
+ ld8 val1 = [str], 8;;
+ nop.b 0
+ nop.b 0
+.l2: ld8.s val2 = [str], 8 // don't bomb out here
+ czx1.r pos0 = val1
+ ;;
+ cmp.ne p6, p0 = 8, pos0
+(p6) br.cond.spnt .foundit
+ chk.s val2, .recovery
+.back:
+ mov val1 = val2
+ br.cond.dptk .l2
+.foundit:
+ sub tmp = str, origadd // tmp = crt address - orig
+ add len = len, pos0;;
+ add len = len, tmp;;
+ adds len = -16, len
+.restore_and_exit:
+ mov ar.lc = saved_lc // restore the loop counter
+ br.ret.sptk.many b0
+.recovery:
+ adds str = -8, str;;
+ ld8 val2 = [str], 8 // bomb out here
+ br.cond.sptk .back
+END(strlen)
+libc_hidden_builtin_def (strlen)
diff --git a/libc/sysdeps/ia64/strncmp.S b/libc/sysdeps/ia64/strncmp.S
new file mode 100644
index 000000000..743121d88
--- /dev/null
+++ b/libc/sysdeps/ia64/strncmp.S
@@ -0,0 +1,62 @@
+/* Optimized version of the standard strncmp() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Dan Pop <Dan.Pop@cern.ch>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: the result of the comparison
+
+ Inputs:
+ in0: s1
+ in1: s2
+ in2: n
+
+ Unlike memcmp(), this function is optimized for mismatches within the
+ first few characters. */
+
+#include <sysdep.h>
+#undef ret
+
+#define s1 in0
+#define s2 in1
+#define n in2
+
+#define val1 r15
+#define val2 r16
+
+
+ENTRY(strncmp)
+ alloc r2 = ar.pfs, 3, 0, 0, 0
+ mov ret0 = r0
+ cmp.eq p6, p0 = r0, r0 // set p6
+ cmp.eq p7, p0 = n, r0 // return immediately if n == 0
+(p7) br.cond.spnt .restore_and_exit ;;
+.loop:
+ ld1 val1 = [s1], 1
+ ld1 val2 = [s2], 1
+ adds n = -1, n // n--
+ ;;
+ cmp.ne.and p6, p0 = val1, r0
+ cmp.ne.and p6, p0 = val2, r0
+ cmp.ne.and p6, p0 = n, r0
+ cmp.eq.and p6, p0 = val1, val2
+(p6) br.cond.sptk .loop
+ sub ret0 = val1, val2
+.restore_and_exit:
+ br.ret.sptk.many b0
+END(strncmp)
+libc_hidden_builtin_def (strncmp)
diff --git a/libc/sysdeps/ia64/strncpy.S b/libc/sysdeps/ia64/strncpy.S
new file mode 100644
index 000000000..6706ab711
--- /dev/null
+++ b/libc/sysdeps/ia64/strncpy.S
@@ -0,0 +1,232 @@
+/* Optimized version of the standard strncpy() function.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Dan Pop <Dan.Pop@cern.ch>
+ and Jakub Jelinek <jakub@redhat.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Return: dest
+
+ Inputs:
+ in0: dest
+ in1: src
+ in2: len
+
+ In this form, it assumes little endian mode.
+ */
+
+#include <sysdep.h>
+#undef ret
+
+#define saved_lc r15
+#define saved_pr r16
+#define thresh r17
+#define dest r18
+#define dest2 r19
+#define src r20
+#define len r21
+#define asrc r22
+#define tmp r23
+#define pos r24
+#define w0 r25
+#define w1 r26
+#define c r27
+#define sh2 r28
+#define sh1 r29
+#define loopcnt r30
+#define value r31
+
+ENTRY(strncpy)
+ .prologue
+ alloc r2 = ar.pfs, 3, 0, 29, 32
+
+#define MEMLAT 2
+ .rotr r[MEMLAT + 2]
+ .rotp p[MEMLAT + 1]
+
+ mov ret0 = in0 // return value = dest
+ .save pr, saved_pr
+ mov saved_pr = pr // save the predicate registers
+ .save ar.lc, saved_lc
+ mov saved_lc = ar.lc // save the loop counter
+ mov ar.ec = 0 // ec is not guaranteed to
+ // be zero upon function entry
+ .body
+ cmp.geu p6, p5 = 24, in2
+(p6) br.cond.spnt .short_len
+ sub tmp = r0, in0 ;; // tmp = -dest
+ mov len = in2 // len
+ mov dest = in0 // dest
+ mov src = in1 // src
+ and tmp = 7, tmp ;; // loopcnt = -dest % 8
+ cmp.eq p6, p7 = tmp, r0
+ adds loopcnt = -1, tmp // --loopcnt
+(p6) br.cond.sptk .dest_aligned ;;
+ sub len = len, tmp // len -= -dest % 8
+ mov ar.lc = loopcnt
+.l1: // copy -dest % 8 bytes
+(p5) ld1 c = [src], 1 // c = *src++
+ ;;
+ st1 [dest] = c, 1 // *dest++ = c
+ cmp.ne p5, p7 = c, r0
+ br.cloop.dptk .l1 ;;
+(p7) br.cond.dpnt .found0_align
+
+.dest_aligned: // p7 should be cleared here
+ shr.u c = len, 3 // c = len / 8
+ and sh1 = 7, src // sh1 = src % 8
+ and asrc = -8, src ;; // asrc = src & -OPSIZ -- align src
+ adds c = (MEMLAT-1), c // c = (len / 8) + MEMLAT - 1
+ sub thresh = 8, sh1
+ mov pr.rot = 1 << 16 // set rotating predicates
+ shl sh1 = sh1, 3 ;; // sh1 = 8 * (src % 8)
+ mov ar.lc = c // "infinite" loop
+ sub sh2 = 64, sh1 // sh2 = 64 - sh1
+ cmp.eq p6, p0 = sh1, r0 // is the src aligned?
+(p6) br.cond.sptk .src_aligned
+ adds c = -(MEMLAT-1), c ;; // c = (len / 8)
+ ld8 r[1] = [asrc],8
+ mov ar.lc = c ;;
+
+ .align 32
+.l2:
+(p6) st8 [dest] = value, 8 // store val to dest
+ ld8.s r[0] = [asrc], 8
+ shr.u value = r[1], sh1 ;; // value = w0 >> sh1
+ czx1.r pos = value ;; // do we have an "early" zero
+ cmp.lt p7, p0 = pos, thresh // in w0 >> sh1?
+ adds len = -8, len // len -= 8
+(p7) br.cond.dpnt .nonalign_found0
+ chk.s r[0], .recovery2 // it is safe to do that only
+.back2: // after the previous test
+ shl tmp = r[0], sh2 // tmp = w1 << sh2
+ ;;
+ or value = value, tmp ;; // value |= tmp
+ czx1.r pos = value ;;
+ cmp.ne p7, p6 = 8, pos
+(p7) br.cond.dpnt .nonalign_found0
+ br.ctop.dptk .l2 ;;
+ adds len = 8, len
+ br.cond.sptk .not_found0 ;;
+.nonalign_found0:
+ cmp.gtu p6, p0 = -8, len
+(p6) br.cond.dptk .found0
+ adds len = 8, len
+ br.cond.sptk .not_found0 ;;
+
+ .align 32
+.src_aligned:
+.l3:
+(p[0]) ld8.s r[0] = [src], 8
+(p[MEMLAT]) chk.s r[MEMLAT], .recovery3
+.back3:
+(p[MEMLAT]) mov value = r[MEMLAT]
+(p[MEMLAT]) czx1.r pos = r[MEMLAT] ;;
+(p[MEMLAT]) cmp.ne p7, p0 = 8, pos
+(p[MEMLAT]) adds len = -8, len // len -= 8
+(p7) br.cond.dpnt .found0
+(p[MEMLAT]) st8 [dest] = r[MEMLAT], 8
+ br.ctop.dptk .l3 ;;
+
+ chk.s r[MEMLAT-1], .recovery4
+.back4:
+ mov value = r[MEMLAT-1]
+
+.not_found0:
+ cmp.eq p5, p6 = len, r0
+ adds len = -1, len
+(p5) br.cond.dptk .restore_and_exit ;;
+ mov ar.lc = len
+.l4:
+(p6) extr.u c = value, 0, 8 // c = value & 0xff
+(p6) shr.u value = value, 8 ;;
+ st1 [dest] = c, 1
+ cmp.ne p6, p0 = c, r0
+ br.cloop.dptk .l4
+ br.cond.sptk .restore_and_exit
+
+.found0_align:
+ mov pos = 0
+ adds len = -8, len
+ mov value = 0 ;;
+.found0:
+ shl tmp = pos, 3
+ shr.u loopcnt = len, 4 // loopcnt = len / 16
+ mov c = -1 ;;
+ cmp.eq p6, p0 = loopcnt, r0
+ adds loopcnt = -1, loopcnt
+ shl c = c, tmp ;;
+ and len = 0xf, len
+ andcm value = value, c
+ mov ar.lc = loopcnt ;;
+ cmp.le p7, p0 = 8, len
+ adds dest2 = 16, dest
+ st8 [dest] = value, 8
+ and len = 0x7, len
+(p6) br.cond.dpnt .l6 ;;
+.l5:
+ st8 [dest] = r0, 16
+ st8 [dest2] = r0, 16
+ br.cloop.dptk .l5 ;;
+.l6:
+(p7) st8 [dest] = r0, 8
+ cmp.eq p5, p0 = len, r0
+ adds len = -1, len
+(p5) br.cond.dptk .restore_and_exit ;;
+ mov ar.lc = len ;;
+.l7:
+ st1 [dest] = r0, 1
+ br.cloop.dptk .l7 ;;
+.restore_and_exit:
+ mov ar.lc = saved_lc // restore the loop counter
+ mov pr = saved_pr, -1 // restore the predicate registers
+ br.ret.sptk.many b0
+
+.short_len:
+ cmp.eq p5, p0 = in2, r0
+ adds loopcnt = -1, in2
+(p5) br.cond.spnt .restore_and_exit ;;
+ mov ar.lc = loopcnt // p6 should be set when we get here
+.l8:
+(p6) ld1 c = [in1], 1 // c = *src++
+ ;;
+ st1 [in0] = c, 1 // *dest++ = c
+(p6) cmp.ne p6, p0 = c, r0
+ br.cloop.dptk .l8
+ ;;
+ mov ar.lc = saved_lc // restore the loop counter
+ mov pr = saved_pr, -1 // restore the predicate registers
+ br.ret.sptk.many b0
+.recovery2:
+ add c = 8, len
+ add tmp = -8, asrc ;;
+ cmp.gtu p8, p5 = c, thresh ;;
+(p8) ld8 r[0] = [tmp]
+(p5) mov r[0] = r0
+ br.cond.sptk .back2
+.recovery3:
+ add tmp = -(MEMLAT + 1) * 8, src ;;
+ ld8 r[MEMLAT] = [tmp]
+ br.cond.sptk .back3
+.recovery4:
+ cmp.eq p5, p6 = len, r0
+ add tmp = -MEMLAT * 8, src ;;
+(p6) ld8 r[MEMLAT - 1] = [tmp]
+(p5) mov r[MEMLAT - 1] = r0
+ br.cond.sptk .back4
+END(strncpy)
+libc_hidden_builtin_def (strncpy)
diff --git a/libc/sysdeps/ia64/sysdep.h b/libc/sysdeps/ia64/sysdep.h
new file mode 100644
index 000000000..83d30a49b
--- /dev/null
+++ b/libc/sysdeps/ia64/sysdep.h
@@ -0,0 +1,63 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+/* Macros to help writing .prologue directives in assembly code. */
+#define ASM_UNW_PRLG_RP 0x8
+#define ASM_UNW_PRLG_PFS 0x4
+#define ASM_UNW_PRLG_PSP 0x2
+#define ASM_UNW_PRLG_PR 0x1
+#define ASM_UNW_PRLG_GRSAVE(ninputs) (32+(ninputs))
+
+#define ENTRY(name) \
+ .text; \
+ .align 32; \
+ .proc C_SYMBOL_NAME(name); \
+ .global C_SYMBOL_NAME(name); \
+ C_LABEL(name) \
+ CALL_MCOUNT
+
+#define LOCAL_ENTRY(name) \
+ .text; \
+ .align 32; \
+ .proc C_SYMBOL_NAME(name); \
+ C_LABEL(name) \
+ CALL_MCOUNT
+
+#define LEAF(name) \
+ .text; \
+ .align 32; \
+ .proc C_SYMBOL_NAME(name); \
+ .global name; \
+ C_LABEL(name)
+
+#define LOCAL_LEAF(name) \
+ .text; \
+ .align 32; \
+ .proc C_SYMBOL_NAME(name); \
+ C_LABEL(name)
+
+/* Mark the end of function SYM. */
+#undef END
+#define END(sym) .endp C_SYMBOL_NAME(sym)
+
+#endif /* ASSEMBLER */
diff --git a/libc/sysdeps/ieee754/Makefile b/libc/sysdeps/ieee754/Makefile
new file mode 100644
index 000000000..1168406c1
--- /dev/null
+++ b/libc/sysdeps/ieee754/Makefile
@@ -0,0 +1,5 @@
+ifeq ($(subdir),math)
+sysdep_headers += ieee754.h
+CFLAGS-k_standard.c = -Wno-write-strings
+endif
+
diff --git a/libc/sysdeps/ieee754/bits/huge_val.h b/libc/sysdeps/ieee754/bits/huge_val.h
new file mode 100644
index 000000000..11ca11f18
--- /dev/null
+++ b/libc/sysdeps/ieee754/bits/huge_val.h
@@ -0,0 +1,55 @@
+/* `HUGE_VAL' constant for IEEE 754 machines (where it is infinity).
+ Used by <stdlib.h> and <math.h> functions for overflow.
+ Copyright (C) 1992, 1995, 1996, 1997, 1999, 2000, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/huge_val.h> directly; include <math.h> instead."
+#endif
+
+/* IEEE positive infinity (-HUGE_VAL is negative infinity). */
+
+#if __GNUC_PREREQ(3,3)
+# define HUGE_VAL (__builtin_huge_val())
+#elif __GNUC_PREREQ(2,96)
+# define HUGE_VAL (__extension__ 0x1.0p2047)
+#elif defined __GNUC__
+
+# define HUGE_VAL \
+ (__extension__ \
+ ((union { unsigned __l __attribute__((__mode__(__DI__))); double __d; }) \
+ { __l: 0x7ff0000000000000ULL }).__d)
+
+#else /* not GCC */
+
+# include <endian.h>
+
+typedef union { unsigned char __c[8]; double __d; } __huge_val_t;
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define __HUGE_VAL_bytes { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
+# endif
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define __HUGE_VAL_bytes { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }
+# endif
+
+static __huge_val_t __huge_val = { __HUGE_VAL_bytes };
+# define HUGE_VAL (__huge_val.__d)
+
+#endif /* GCC. */
diff --git a/libc/sysdeps/ieee754/bits/huge_valf.h b/libc/sysdeps/ieee754/bits/huge_valf.h
new file mode 100644
index 000000000..1785342cd
--- /dev/null
+++ b/libc/sysdeps/ieee754/bits/huge_valf.h
@@ -0,0 +1,53 @@
+/* `HUGE_VALF' constant for IEEE 754 machines (where it is infinity).
+ Used by <stdlib.h> and <math.h> functions for overflow.
+ Copyright (C) 1992, 1995, 1996, 1997, 1999, 2000, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/huge_valf.h> directly; include <math.h> instead."
+#endif
+
+/* IEEE positive infinity (-HUGE_VAL is negative infinity). */
+
+#if __GNUC_PREREQ(3,3)
+# define HUGE_VALF (__builtin_huge_valf())
+#elif __GNUC_PREREQ(2,96)
+# define HUGE_VALF (__extension__ 0x1.0p255f)
+#elif defined __GNUC__
+
+# define HUGE_VALF \
+ (__extension__ \
+ ((union { unsigned __l __attribute__((__mode__(__SI__))); float __d; }) \
+ { __l: 0x7f800000UL }).__d)
+
+#else /* not GCC */
+
+typedef union { unsigned char __c[4]; float __f; } __huge_valf_t;
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define __HUGE_VALF_bytes { 0x7f, 0x80, 0, 0 }
+# endif
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define __HUGE_VALF_bytes { 0, 0, 0x80, 0x7f }
+# endif
+
+static __huge_valf_t __huge_valf = { __HUGE_VALF_bytes };
+# define HUGE_VALF (__huge_valf.__f)
+
+#endif /* GCC. */
diff --git a/libc/sysdeps/ieee754/bits/inf.h b/libc/sysdeps/ieee754/bits/inf.h
new file mode 100644
index 000000000..1619f756e
--- /dev/null
+++ b/libc/sysdeps/ieee754/bits/inf.h
@@ -0,0 +1,30 @@
+/* `INFINITY' constant for IEEE 754 machines.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/inf.h> directly; include <math.h> instead."
+#endif
+
+/* IEEE positive infinity. */
+
+#if __GNUC_PREREQ(3,3)
+# define INFINITY (__builtin_inff())
+#else
+# define INFINITY HUGE_VALF
+#endif
diff --git a/libc/sysdeps/ieee754/bits/nan.h b/libc/sysdeps/ieee754/bits/nan.h
new file mode 100644
index 000000000..bae97f216
--- /dev/null
+++ b/libc/sysdeps/ieee754/bits/nan.h
@@ -0,0 +1,53 @@
+/* `NAN' constant for IEEE 754 machines.
+ Copyright (C) 1992,1996,1997,1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/nan.h> directly; include <math.h> instead."
+#endif
+
+
+/* IEEE Not A Number. */
+
+#if __GNUC_PREREQ(3,3)
+
+# define NAN (__builtin_nanf (""))
+
+#elif defined __GNUC__
+
+# define NAN \
+ (__extension__ \
+ ((union { unsigned __l __attribute__ ((__mode__ (__SI__))); float __d; }) \
+ { __l: 0x7fc00000UL }).__d)
+
+#else
+
+# include <endian.h>
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define __nan_bytes { 0x7f, 0xc0, 0, 0 }
+# endif
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define __nan_bytes { 0, 0, 0xc0, 0x7f }
+# endif
+
+static union { unsigned char __c[4]; float __d; } __nan_union
+ __attribute_used__ = { __nan_bytes };
+# define NAN (__nan_union.__d)
+
+#endif /* GCC. */
diff --git a/libc/sysdeps/ieee754/dbl-64/MathLib.h b/libc/sysdeps/ieee754/dbl-64/MathLib.h
new file mode 100644
index 000000000..7e271425d
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/MathLib.h
@@ -0,0 +1,103 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/********************************************************************/
+/* Ultimate math functions. Each function computes the exact */
+/* theoretical value of its argument rounded to nearest or even. */
+/* */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round nearest mode of IEEE 754 standard. */
+/********************************************************************/
+
+#ifndef UMATH_LIB
+#define UMATH_LIB
+/********************************************************************/
+/* Function changes the precision mode to IEEE 754 double precision */
+/* and the rounding mode to nearest or even. */
+/* It returns the original status of these modes. */
+/* See further explanations of usage in DPChange.h */
+/********************************************************************/
+unsigned short Init_Lib(void);
+
+/********************************************************************/
+/* Function that changes the precision and rounding modes to the */
+/* specified by the argument received. See further explanations in */
+/* DPChange.h */
+/********************************************************************/
+void Exit_Lib(unsigned short);
+
+
+/* The asin() function calculates the arc sine of its argument. */
+/* The function returns the arc sine in radians */
+/* (between -PI/2 and PI/2). */
+/* If the argument is greater than 1 or less than -1 it returns */
+/* a NaN. */
+double uasin(double );
+
+
+/* The acos() function calculates the arc cosine of its argument. */
+/* The function returns the arc cosine in radians */
+/* (between -PI/2 and PI/2). */
+/* If the argument is greater than 1 or less than -1 it returns */
+/* a NaN. */
+double uacos(double );
+
+/* The atan() function calculates the arctanget of its argument. */
+/* The function returns the arc tangent in radians */
+/* (between -PI/2 and PI/2). */
+double uatan(double );
+
+
+/* The uatan2() function calculates the arc tangent of the two arguments x */
+/* and y (x is the right argument and y is the left one).The signs of both */
+/* arguments are used to determine the quadrant of the result. */
+/* The function returns the result in radians, which is between -PI and PI */
+double uatan2(double ,double );
+
+/* Compute log(x). The base of log is e (natural logarithm) */
+double ulog(double );
+
+/* Compute e raised to the power of argument x. */
+double uexp(double );
+
+/* Compute sin(x). The argument x is assumed to be given in radians.*/
+double usin(double );
+
+/* Compute cos(x). The argument x is assumed to be given in radians.*/
+double ucos(double );
+
+/* Compute tan(x). The argument x is assumed to be given in radians.*/
+double utan(double );
+
+/* Compute the square root of non-negative argument x. */
+/* If x is negative the returned value is NaN. */
+double usqrt(double );
+
+/* Compute x raised to the power of y, where x is the left argument */
+/* and y is the right argument. The function returns a NaN if x<0. */
+/* If x equals zero it returns -inf */
+double upow(double , double );
+
+/* Computing x mod y, where x is the left argument and y is the */
+/* right one. */
+double uremainder(double , double );
+
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/asincos.tbl b/libc/sysdeps/ieee754/dbl-64/asincos.tbl
new file mode 100644
index 000000000..ff6795725
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/asincos.tbl
@@ -0,0 +1,5169 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/***************************************************************************/
+/* Table for arcsin() and arccos() FUNCTIONS */
+/***************************************************************************/
+
+#ifdef BIG_ENDI
+static const union {int4 i[5136];double x[2568];} asncs = { .i = {
+/**/ 0x3FC04000, 0x00000000,
+/**/ 0x3FF02169, 0x88994424,
+/**/ 0x3FB0A6A2, 0xB799B115,
+/**/ 0x3FC6EF15, 0xD57409A0,
+/**/ 0x3FAA141E, 0xAF52EAA0,
+/**/ 0x3FB75591, 0xABBBE261,
+/**/ 0x3FA72B51, 0xD206D88F,
+/**/ 0x3C96B595, 0x5BB33E7D,
+/**/ 0x3FC04B41, 0xA03E2700,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF7E9677, 0x66BBDC7C,
+/**/ 0x3FC0C000, 0x00000000,
+/**/ 0x3FF02386, 0xF9E23A56,
+/**/ 0x3FB1308C, 0x60FD0235,
+/**/ 0x3FC7099F, 0x14D16B02,
+/**/ 0x3FAAFED6, 0x27C01EE1,
+/**/ 0x3FB79C6F, 0xDBCD5F98,
+/**/ 0x3FA8144A, 0x4084DAAC,
+/**/ 0xBC87C092, 0x38D8505E,
+/**/ 0x3FC0CC55, 0x56C9F380,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF7C7906, 0x1DC5AA24,
+/**/ 0x3FC14000, 0x00000000,
+/**/ 0x3FF025B5, 0xB27141F6,
+/**/ 0x3FB1BB18, 0x04CE7400,
+/**/ 0x3FC72514, 0x72907342,
+/**/ 0x3FABEC60, 0x0BF4222C,
+/**/ 0x3FB7E610, 0x75B3736C,
+/**/ 0x3FA9024C, 0x5199C343,
+/**/ 0xBC8AE84C, 0x06B56F60,
+/**/ 0x3FC14D7A, 0x3DEFA070,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF7A4A4D, 0x8EBE0A5C,
+/**/ 0x3FC1C000, 0x00000000,
+/**/ 0x3FF027F5, 0xC6DE8F57,
+/**/ 0x3FB2464B, 0x345751E1,
+/**/ 0x3FC74178, 0xCF026805,
+/**/ 0x3FACDCD8, 0x40A9E0D6,
+/**/ 0x3FB83282, 0xEB1D9C38,
+/**/ 0x3FA9F590, 0xD7BE707B,
+/**/ 0xBCAB9768, 0x03A2A6D6,
+/**/ 0x3FC1CEB0, 0xE03B4870,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF780A39, 0x2170A943,
+/**/ 0x3FC24000, 0x00000000,
+/**/ 0x3FF02A47, 0x4C759796,
+/**/ 0x3FB2D22B, 0x92771935,
+/**/ 0x3FC75ECF, 0x26ABA06D,
+/**/ 0x3FADD05B, 0x486A1932,
+/**/ 0x3FB881D7, 0x5AF971D5,
+/**/ 0x3FAAEE52, 0x831AEE0C,
+/**/ 0x3CA13F57, 0xAD1B1BEF,
+/**/ 0x3FC24FF9, 0xC8E09330,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF75B8B3, 0x8A68699B,
+/**/ 0x3FC2C000, 0x00000000,
+/**/ 0x3FF02CAA, 0x59374E09,
+/**/ 0x3FB35EBE, 0xD44E8BEA,
+/**/ 0x3FC77D1A, 0x92E4BE8A,
+/**/ 0x3FAEC706, 0x4A6C34FD,
+/**/ 0x3FB8D41E, 0x972F6E07,
+/**/ 0x3FABECCD, 0xF9845F69,
+/**/ 0x3C8BA1FA, 0x945C4185,
+/**/ 0x3FC2D155, 0x83C058B0,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF7355A6, 0xC8B1F774,
+/**/ 0x3FC34000, 0x00000000,
+/**/ 0x3FF02F1F, 0x03DC7745,
+/**/ 0x3FB3EC0A, 0xC1EE9F61,
+/**/ 0x3FC79C5E, 0x4A82E6D2,
+/**/ 0x3FAFC0F7, 0x19B1EF72,
+/**/ 0x3FB9296A, 0x2AA943E5,
+/**/ 0x3FACF141, 0xEF8B9DE7,
+/**/ 0xBC834081, 0x083C8716,
+/**/ 0x3FC352C4, 0x9D6E5610,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF70E0FC, 0x2388BB30,
+/**/ 0x3FC3C000, 0x00000000,
+/**/ 0x3FF031A5, 0x63D81251,
+/**/ 0x3FB47A15, 0x370B721F,
+/**/ 0x3FC7BC9D, 0xA28731E5,
+/**/ 0x3FB05F26, 0x1E305BE9,
+/**/ 0x3FB981CC, 0x5FA50FBD,
+/**/ 0x3FADFBEF, 0x42AC4083,
+/**/ 0x3CA20ACB, 0xA8E107C7,
+/**/ 0x3FC3D447, 0xA336F5E0,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF6CB538, 0x4FDB5D5C,
+/**/ 0x3FC44000, 0x00000000,
+/**/ 0x3FF0343D, 0x9159D86F,
+/**/ 0x3FB508E4, 0x23B3747C,
+/**/ 0x3FC7DDDC, 0x0ED597CB,
+/**/ 0x3FB0DF92, 0x79ADF104,
+/**/ 0x3FB9DD58, 0x4658D945,
+/**/ 0x3FAF0D19, 0x14ACA06B,
+/**/ 0xBCA4E10D, 0xDF636EFE,
+/**/ 0x3FC455DF, 0x23252C00,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF6784DD, 0x4C4F221A,
+/**/ 0x3FC4C000, 0x00000000,
+/**/ 0x3FF036E7, 0xA550D410,
+/**/ 0x3FB5987D, 0x8D0AF1E7,
+/**/ 0x3FC8001D, 0x22F39726,
+/**/ 0x3FB161D0, 0xA1116D73,
+/**/ 0x3FBA3C21, 0xBBEA1528,
+/**/ 0x3FB01282, 0x74202FF6,
+/**/ 0x3CAA0611, 0xD10866E2,
+/**/ 0x3FC4D78B, 0xAC086560,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF6230B5, 0x5E57DF8A,
+/**/ 0x3FC54000, 0x00000000,
+/**/ 0x3FF039A3, 0xB96E0F8A,
+/**/ 0x3FB628E7, 0x8E0C29F6,
+/**/ 0x3FC82364, 0x92CEDE01,
+/**/ 0x3FB1E5F0, 0xFB7B5D84,
+/**/ 0x3FBA9E3D, 0x71BD08EE,
+/**/ 0x3FB0A1FD, 0x5F7FFAB4,
+/**/ 0xBC90F980, 0xEF04F6E7,
+/**/ 0x3FC5594D, 0xCD7A8DC0,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF59711A, 0x47C1D879,
+/**/ 0x3FC5C000, 0x00000000,
+/**/ 0x3FF03C71, 0xE8275C12,
+/**/ 0x3FB6BA28, 0x584C2A23,
+/**/ 0x3FC847B6, 0x338C3D4B,
+/**/ 0x3FB26C04, 0x59A55DD8,
+/**/ 0x3FBB03C0, 0xF5202D6A,
+/**/ 0x3FB13522, 0x9C6466A4,
+/**/ 0x3C983C9A, 0x2A268973,
+/**/ 0x3FC5DB26, 0x17E62A20,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF4C70BE, 0xC51F7008,
+/**/ 0x3FC64000, 0x00000000,
+/**/ 0x3FF03F52, 0x4CBA31A9,
+/**/ 0x3FB74C46, 0x34C49ADE,
+/**/ 0x3FC86D15, 0xFC5F33CC,
+/**/ 0x3FB2F41B, 0xFA419D7C,
+/**/ 0x3FBB6CC2, 0xB757E82A,
+/**/ 0x3FB1CC18, 0xDA4D5C39,
+/**/ 0xBCA862D4, 0x2DFB224D,
+/**/ 0x3FC65D15, 0x1C8C8AF0,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0xBF25B668, 0xB9CADBBF,
+/**/ 0x3FC6C000, 0x00000000,
+/**/ 0x3FF04245, 0x032EA88F,
+/**/ 0x3FB7DF47, 0x84A2B473,
+/**/ 0x3FC89388, 0x076A60F5,
+/**/ 0x3FB37E49, 0x8E8394C1,
+/**/ 0x3FBBD95A, 0x160F3472,
+/**/ 0x3FB26708, 0x39844810,
+/**/ 0x3C994228, 0x698BC8EA,
+/**/ 0x3FC6DF1B, 0x6D8C14A0,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0x3F422819, 0x754477AC,
+/**/ 0x3FC74000, 0x00000000,
+/**/ 0x3FF0454A, 0x285A8CEB,
+/**/ 0x3FB87332, 0xC21B9224,
+/**/ 0x3FC8BB10, 0x92A93402,
+/**/ 0x3FB40A9F, 0x3ED3F586,
+/**/ 0x3FBC499F, 0x643217C8,
+/**/ 0x3FB3061A, 0x5D29A16B,
+/**/ 0xBCA3B2DF, 0x3DF9F2D7,
+/**/ 0x3FC76139, 0x9DE6A160,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0x3F5528A1, 0x6A33AB4B,
+/**/ 0x3FC7C000, 0x00000000,
+/**/ 0x3FF04861, 0xD9E48D58,
+/**/ 0x3FB9080E, 0x81461BF6,
+/**/ 0x3FC8E3B4, 0x00E32FFA,
+/**/ 0x3FB4992F, 0xAFB1F2A5,
+/**/ 0x3FBCBDAB, 0xF33705D5,
+/**/ 0x3FB3A97A, 0x7E23EE89,
+/**/ 0x3C7AAD12, 0xCCE44C41,
+/**/ 0x3FC7E370, 0x4187FAE0,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0x3F60C3B3, 0xC91AAF11,
+/**/ 0x3FC84000, 0x00000000,
+/**/ 0x3FF04B8C, 0x36478509,
+/**/ 0x3FB99DE1, 0x70FAC1B4,
+/**/ 0x3FC90D76, 0xDAA92166,
+/**/ 0x3FB52A0E, 0x06C416A6,
+/**/ 0x3FBD359A, 0x1CDCA344,
+/**/ 0x3FB45155, 0x7EFD4CA0,
+/**/ 0x3C396CA5, 0x35A8895D,
+/**/ 0x3FC865BF, 0xED4C6EF0,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0x3F67186C, 0x8F0A11A4,
+/**/ 0x3FC8C000, 0x00000000,
+/**/ 0x3FF04EC9, 0x5CD5E248,
+/**/ 0x3FBA34B2, 0x5BB94403,
+/**/ 0x3FC9385D, 0xCF5CA73A,
+/**/ 0x3FB5BD4D, 0xF01AFDBE,
+/**/ 0x3FBDB185, 0x4D61A7A9,
+/**/ 0x3FB4FDDA, 0x00BD47CF,
+/**/ 0xBC9D1119, 0x727E8B64,
+/**/ 0x3FC8E829, 0x37077E20,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0x3F6D92B9, 0xABC490CB,
+/**/ 0x3FC94000, 0x00000000,
+/**/ 0x3FF05219, 0x6DBD2A10,
+/**/ 0x3FBACC88, 0x2894CAA1,
+/**/ 0x3FC9646D, 0xB6427516,
+/**/ 0x3FB65303, 0xA3A864D7,
+/**/ 0x3FBE318A, 0x0E3CF3D4,
+/**/ 0x3FB5AF38, 0x78CDA678,
+/**/ 0x3CA3841D, 0xDA9D51DF,
+/**/ 0x3FC96AAC, 0xB58AA660,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0x3F72196D, 0xBD2A1052,
+/**/ 0x3FC9C000, 0x00000000,
+/**/ 0x3FF0557C, 0x8A099990,
+/**/ 0x3FBB6569, 0xDC268965,
+/**/ 0x3FC991AB, 0x8F9FBA21,
+/**/ 0x3FB6EB43, 0xEAED1E85,
+/**/ 0x3FBEB5C6, 0x115C4C63,
+/**/ 0x3FB665A3, 0x47F9AEFA,
+/**/ 0xBCA1F8FD, 0x03AB3673,
+/**/ 0x3FC9ED4B, 0x00AC4A60,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0x3F757C8A, 0x0999905B,
+/**/ 0x3FCA4000, 0x00000000,
+/**/ 0x3FF058F2, 0xD3A9E674,
+/**/ 0x3FBBFF5E, 0x99873832,
+/**/ 0x3FC9C01C, 0x85E31CE9,
+/**/ 0x3FB78624, 0x26E09FF2,
+/**/ 0x3FBF3E58, 0x3CF0885C,
+/**/ 0x3FB7214E, 0xD2986239,
+/**/ 0x3C97E3E5, 0x3E594694,
+/**/ 0x3FCA7004, 0xB14EB5D0,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0x3F78F2D3, 0xA9E6746B,
+/**/ 0x3FCAC000, 0x00000000,
+/**/ 0x3FF05C7C, 0x6D731ECB,
+/**/ 0x3FBC9A6D, 0xA34FA4B3,
+/**/ 0x3FC9EFC5, 0xEED9C253,
+/**/ 0x3FB823BA, 0x5614FAEB,
+/**/ 0x3FBFCB60, 0xB7CE698F,
+/**/ 0x3FB7E271, 0x99F3292F,
+/**/ 0xBC9842C6, 0x068D709C,
+/**/ 0x3FCAF2DA, 0x61674110,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0x3F7C7C6D, 0x731ECAE2,
+/**/ 0x3FCB4000, 0x00000000,
+/**/ 0x3FF06019, 0x7B24A973,
+/**/ 0x3FBD369E, 0x5CA0A798,
+/**/ 0x3FCA20AD, 0x4CF0DB64,
+/**/ 0x3FB8C41D, 0x1B1A3F31,
+/**/ 0x3FC02E80, 0x7B35E049,
+/**/ 0x3FB8A944, 0x56FB8A97,
+/**/ 0xBCACBF9C, 0xD337B37C,
+/**/ 0x3FCB75CC, 0xAC059370,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0xBF7FE684, 0xDB568D78,
+/**/ 0x3FCBC000, 0x00000000,
+/**/ 0x3FF063CA, 0x216C6801,
+/**/ 0x3FBDD3F8, 0x4A32C9FD,
+/**/ 0x3FCA52D8, 0x50843BC9,
+/**/ 0x3FB96763, 0xC324648A,
+/**/ 0x3FC079AD, 0xE4407899,
+/**/ 0x3FB97602, 0x1663A5DC,
+/**/ 0xBCA3ADC3, 0xC637289D,
+/**/ 0x3FCBF8DC, 0x2D5B06A0,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0xBF7C35DE, 0x9397FEA6,
+/**/ 0x3FCC4000, 0x00000000,
+/**/ 0x3FF0678E, 0x85EAFB1F,
+/**/ 0x3FBE7283, 0x136DEAC6,
+/**/ 0x3FCA864C, 0xD93A817D,
+/**/ 0x3FBA0DA6, 0x4CF7089B,
+/**/ 0x3FC0C74A, 0xB3ABB322,
+/**/ 0x3FBA48E8, 0x562E6E1E,
+/**/ 0xBC951E3E, 0x7EB8FFF8,
+/**/ 0x3FCC7C09, 0x82C22B80,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0xBF78717A, 0x1504E0D3,
+/**/ 0x3FCCC000, 0x00000000,
+/**/ 0x3FF06B66, 0xCF382A59,
+/**/ 0x3FBF1246, 0x838936FB,
+/**/ 0x3FCABB10, 0xF76F5C94,
+/**/ 0x3FBAB6FD, 0x701A77AE,
+/**/ 0x3FC11769, 0xC26702C6,
+/**/ 0x3FBB2237, 0x24CDF38E,
+/**/ 0xBC8DB69A, 0xE28307A9,
+/**/ 0x3FCCFF55, 0x4AC67190,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0xBF749930, 0xC7D5A6B9,
+/**/ 0x3FCD4000, 0x00000000,
+/**/ 0x3FF06F53, 0x24E7707F,
+/**/ 0x3FBFB34A, 0x8AB3CBB2,
+/**/ 0x3FCAF12A, 0xEDAC8D74,
+/**/ 0x3FBB6382, 0xA45DA614,
+/**/ 0x3FC16A1E, 0xAD8E9F44,
+/**/ 0x3FBC0231, 0x41E7749D,
+/**/ 0x3C76CA27, 0x22DC16A2,
+/**/ 0x3FCD82C0, 0x252BF240,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0xBF70ACDB, 0x188F814B,
+/**/ 0x3FCDC000, 0x00000000,
+/**/ 0x3FF07353, 0xAF8CADA0,
+/**/ 0x3FC02ACB, 0x9FA32DC9,
+/**/ 0x3FCB28A1, 0x32323718,
+/**/ 0x3FBC1350, 0x29A8F15E,
+/**/ 0x3FC1BF7D, 0xDEB270E1,
+/**/ 0x3FBCE91C, 0x40D67463,
+/**/ 0x3CA6E976, 0x104BAA08,
+/**/ 0x3FCE064A, 0xB2F76140,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0xBF6958A0, 0xE6A4BFC9,
+/**/ 0x3FCE4000, 0x00000000,
+/**/ 0x3FF07768, 0x98C0FFD9,
+/**/ 0x3FC07C9A, 0x6F7F1AF0,
+/**/ 0x3FCB617A, 0x708F2AFB,
+/**/ 0x3FBCC681, 0x1025B50C,
+/**/ 0x3FC2179C, 0x9487453A,
+/**/ 0x3FBDD740, 0xAD09B3AB,
+/**/ 0xBC8D32DB, 0x189038C0,
+/**/ 0x3FCE89F5, 0x96762300,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0xBF612ECE, 0x7E004D50,
+/**/ 0x3FCEC000, 0x00000000,
+/**/ 0x3FF07B92, 0x0B27C417,
+/**/ 0x3FC0CF15, 0xE821087A,
+/**/ 0x3FCB9BBD, 0x8B49DC8C,
+/**/ 0x3FBD7D31, 0x40BEF5C2,
+/**/ 0x3FC27290, 0xEC080575,
+/**/ 0x3FBECCEA, 0x3056A6A9,
+/**/ 0x3C9DE506, 0x0C9B27A2,
+/**/ 0x3FCF0DC1, 0x73468A50,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0xBF51B7D3, 0x60EFA34D,
+/**/ 0x3FCF4000, 0x00000000,
+/**/ 0x3FF07FD0, 0x3273C018,
+/**/ 0x3FC12242, 0x51B87F08,
+/**/ 0x3FCBD771, 0x9D9AB2BC,
+/**/ 0x3FBE377D, 0x85FFA125,
+/**/ 0x3FC2D071, 0xEA0CFE55,
+/**/ 0x3FBFCA67, 0xBB61DDD3,
+/**/ 0xBCA25383, 0x88A645E7,
+/**/ 0x3FCF91AE, 0xEE603F40,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0xBF07E6C6, 0x1FF422B6,
+/**/ 0x3FCFC000, 0x00000000,
+/**/ 0x3FF08423, 0x3B6C76F2,
+/**/ 0x3FC17624, 0x0A1DF897,
+/**/ 0x3FCC149D, 0xFD38779D,
+/**/ 0x3FBEF583, 0x95531ECD,
+/**/ 0x3FC33157, 0x855FA966,
+/**/ 0x3FC06805, 0xD81E6BAA,
+/**/ 0x3C86827E, 0x1B47FAEC,
+/**/ 0x3FD00ADF, 0x570E6798,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0x3F508CED, 0xB1DBC656,
+/**/ 0x3FD02000, 0x00000000,
+/**/ 0x3FF0888B, 0x53F3A97B,
+/**/ 0x3FC1CABF, 0x858525D6,
+/**/ 0x3FCC534A, 0x3C37AF90,
+/**/ 0x3FBFB762, 0x18AD312A,
+/**/ 0x3FC3955A, 0xB151CAAD,
+/**/ 0x3FC0EF16, 0x07ADE82D,
+/**/ 0x3CAEEF44, 0xFCDE8746,
+/**/ 0x3FD04CF8, 0xAD203480,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0x3F6116A7, 0xE752F5A1,
+/**/ 0x3FD06000, 0x00000000,
+/**/ 0x3FF08D08, 0xAB0B03F8,
+/**/ 0x3FC22019, 0x4F34EEE8,
+/**/ 0x3FCC937E, 0x2AFDABDE,
+/**/ 0x3FC03E9C, 0x5C4F35BA,
+/**/ 0x3FC3FC95, 0x68DF21A6,
+/**/ 0x3FC17A91, 0x53843C52,
+/**/ 0xBC9D6F54, 0xC2BB835A,
+/**/ 0x3FD08F23, 0xCE0162B8,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0x3F6A1156, 0x1607EF23,
+/**/ 0x3FD0A000, 0x00000000,
+/**/ 0x3FF0919B, 0x70D9FA87,
+/**/ 0x3FC27636, 0x0A456C09,
+/**/ 0x3FCCD541, 0xDA483778,
+/**/ 0x3FC0A394, 0x136D6630,
+/**/ 0x3FC46722, 0xBA615E9C,
+/**/ 0x3FC20AA6, 0xA2BC6F73,
+/**/ 0x3CA9D006, 0x7F1D9D86,
+/**/ 0x3FD0D161, 0x0F0C1EC8,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0x3F719B70, 0xD9FA8688,
+/**/ 0x3FD0E000, 0x00000000,
+/**/ 0x3FF09643, 0xD6B3D5D1,
+/**/ 0x3FC2CD1A, 0x72641546,
+/**/ 0x3FCD189D, 0x9D4AC7EC,
+/**/ 0x3FC10AA9, 0x149C2E66,
+/**/ 0x3FC4D51E, 0xD3DE8741,
+/**/ 0x3FC29F86, 0xF6DA4768,
+/**/ 0x3CAEA900, 0x828C2A81,
+/**/ 0x3FD113B0, 0xC65D88C8,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0x3F7643D6, 0xB3D5D119,
+/**/ 0x3FD12000, 0x00000000,
+/**/ 0x3FF09B02, 0x0F1DF195,
+/**/ 0x3FC324CB, 0x5C9E6B3F,
+/**/ 0x3FCD5D9A, 0x0BE228B7,
+/**/ 0x3FC173EC, 0xD29602B0,
+/**/ 0x3FC546A7, 0x0FFA7799,
+/**/ 0x3FC33965, 0x87BA569F,
+/**/ 0xBCAE3258, 0x9956F2C3,
+/**/ 0x3FD15613, 0x4ADA6FF0,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0x3F7B020F, 0x1DF1952F,
+/**/ 0x3FD16000, 0x00000000,
+/**/ 0x3FF09FD6, 0x4DD62EB0,
+/**/ 0x3FC37D4D, 0xB8335DE5,
+/**/ 0x3FCDA440, 0x04DFA3F1,
+/**/ 0x3FC1DF71, 0x55E59412,
+/**/ 0x3FC5BBDA, 0x0394B72E,
+/**/ 0x3FC3D877, 0xE1177398,
+/**/ 0x3CA8AC88, 0x3B5720A7,
+/**/ 0x3FD19888, 0xF43427A8,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0x3F7FD64D, 0xD62EAF85,
+/**/ 0x3FD1A000, 0x00000000,
+/**/ 0x3FF0A4C0, 0xC7D99A5F,
+/**/ 0x3FC3D6A6, 0x8F6BB942,
+/**/ 0x3FCDEC98, 0xB06CB8A9,
+/**/ 0x3FC24D49, 0x432C74B1,
+/**/ 0x3FC634D7, 0x8C1C6EC6,
+/**/ 0x3FC47CF6, 0x01BF2560,
+/**/ 0x3CA3EDE7, 0x476E25C7,
+/**/ 0x3FD1DB12, 0x1AED7720,
+/**/ 0x3FF0C000, 0x00000000,
+/**/ 0xBF7B3F38, 0x2665A126,
+/**/ 0x3FD1E000, 0x00000000,
+/**/ 0x3FF0A9C1, 0xB36B4C8B,
+/**/ 0x3FC430DB, 0x0879E39B,
+/**/ 0x3FCE36AD, 0x82887D8B,
+/**/ 0x3FC2BD87, 0xE1B33C79,
+/**/ 0x3FC6B1C0, 0xDEA4E95E,
+/**/ 0x3FC5271A, 0x7C90504A,
+/**/ 0x3CAAFAD9, 0x8A6EBD08,
+/**/ 0x3FD21DAF, 0x185FA360,
+/**/ 0x3FF0C000, 0x00000000,
+/**/ 0xBF763E4C, 0x94B3751C,
+/**/ 0x3FD22000, 0x00000000,
+/**/ 0x3FF0AED9, 0x481B7EED,
+/**/ 0x3FC48BF0, 0x66613BB3,
+/**/ 0x3FCE8288, 0x3D9FDD8F,
+/**/ 0x3FC33041, 0x22470BF2,
+/**/ 0x3FC732B8, 0x97C5B476,
+/**/ 0x3FC5D722, 0x9B614F73,
+/**/ 0x3CA96B82, 0x759745C8,
+/**/ 0x3FD26060, 0x46BF95B8,
+/**/ 0x3FF0C000, 0x00000000,
+/**/ 0xBF7126B7, 0xE48112DC,
+/**/ 0x3FD26000, 0x00000000,
+/**/ 0x3FF0B407, 0xBECEDF0E,
+/**/ 0x3FC4E7EC, 0x09E5699A,
+/**/ 0x3FCED032, 0xF541EC2D,
+/**/ 0x3FC3A589, 0xA6688484,
+/**/ 0x3FC7B7E2, 0xCC5228BD,
+/**/ 0x3FC68D4E, 0x83ECAD1F,
+/**/ 0x3CA98586, 0x7CB79363,
+/**/ 0x3FD2A326, 0x01231EC8,
+/**/ 0x3FF0C000, 0x00000000,
+/**/ 0xBF67F082, 0x6241E449,
+/**/ 0x3FD2A000, 0x00000000,
+/**/ 0x3FF0B94D, 0x51C61D1C,
+/**/ 0x3FC544D3, 0x7281F837,
+/**/ 0x3FCF1FB8, 0x10F19F89,
+/**/ 0x3FC41D76, 0xC7D08A44,
+/**/ 0x3FC84165, 0x1AF4E5E6,
+/**/ 0x3FC749E1, 0x5EE5D838,
+/**/ 0x3C8A2A36, 0xA1F9A890,
+/**/ 0x3FD2E600, 0xA3865760,
+/**/ 0x3FF0C000, 0x00000000,
+/**/ 0xBF5ACAB8, 0xE78B8E2F,
+/**/ 0x3FD2E000, 0x00000000,
+/**/ 0x3FF0BEAA, 0x3CA5B9C1,
+/**/ 0x3FC5A2AC, 0x3F6A91D3,
+/**/ 0x3FCF7122, 0x4F1650DB,
+/**/ 0x3FC4981E, 0xA04F63E7,
+/**/ 0x3FC8CF66, 0xBEBC9B64,
+/**/ 0x3FC80D21, 0x81598BF7,
+/**/ 0xBC984143, 0x8E0FD320,
+/**/ 0x3FD328F0, 0x8AD12008,
+/**/ 0x3FF0C000, 0x00000000,
+/**/ 0xBF355C35, 0xA463F3FD,
+/**/ 0x3FD32000, 0x00000000,
+/**/ 0x3FF0C41E, 0xBC7E151A,
+/**/ 0x3FC6017C, 0x30943E19,
+/**/ 0x3FCFC47C, 0xC80C760D,
+/**/ 0x3FC51598, 0x120B129D,
+/**/ 0x3FC96210, 0xA2A855B5,
+/**/ 0x3FC8D758, 0x9880230D,
+/**/ 0xBCA4D129, 0xBF178596,
+/**/ 0x3FD36BF6, 0x14DCC050,
+/**/ 0x3FF0C000, 0x00000000,
+/**/ 0x3F507AF1, 0xF854661E,
+/**/ 0x3FD36000, 0x00000000,
+/**/ 0x3FF0C9AB, 0x0FD3C135,
+/**/ 0x3FC66149, 0x27C80482,
+/**/ 0x3FD00CE9, 0x78AC0DDD,
+/**/ 0x3FC595FA, 0xD02204B1,
+/**/ 0x3FC9F98D, 0x7642750D,
+/**/ 0x3FC9A8D3, 0xD82AC48A,
+/**/ 0x3C977587, 0x289B3951,
+/**/ 0x3FD3AF11, 0xA079A6D8,
+/**/ 0x3FF0C000, 0x00000000,
+/**/ 0x3F63561F, 0xA7826A0D,
+/**/ 0x3FD3A000, 0x00000000,
+/**/ 0x3FF0CF4F, 0x76A81A69,
+/**/ 0x3FC6C219, 0x29BF5ACD,
+/**/ 0x3FD03898, 0x507D5DD4,
+/**/ 0x3FC6195F, 0x67B79439,
+/**/ 0x3FCA9609, 0xC35A709F,
+/**/ 0x3FCA81E4, 0x2BF7455C,
+/**/ 0x3CA03304, 0xF424551E,
+/**/ 0x3FD3F243, 0x8D754B40,
+/**/ 0x3FF0C000, 0x00000000,
+/**/ 0x3F6E9EED, 0x5034D2A8,
+/**/ 0x3FD3E000, 0x00000000,
+/**/ 0x3FF0D50C, 0x3282280D,
+/**/ 0x3FC723F2, 0x5F4ACC23,
+/**/ 0x3FD06551, 0x08771131,
+/**/ 0x3FC69FDF, 0x4970163E,
+/**/ 0x3FCB37B4, 0x04EE9A0A,
+/**/ 0x3FCB62DE, 0x6B79BC18,
+/**/ 0x3CAECF25, 0x02A2F456,
+/**/ 0x3FD4358C, 0x3CA032E0,
+/**/ 0x3FF0C000, 0x00000000,
+/**/ 0x3F750C32, 0x82280D28,
+/**/ 0x3FD42000, 0x00000000,
+/**/ 0x3FF0DAE1, 0x8677C82D,
+/**/ 0x3FC786DB, 0x16834ABE,
+/**/ 0x3FD09319, 0xF1631731,
+/**/ 0x3FC72994, 0xD36297AF,
+/**/ 0x3FCBDEBC, 0xBF583888,
+/**/ 0x3FCC4C1B, 0x918E2AE6,
+/**/ 0x3CA92F70, 0xF34A155C,
+/**/ 0x3FD478EC, 0x0FD419C8,
+/**/ 0x3FF0C000, 0x00000000,
+/**/ 0x3F7AE186, 0x77C82D53,
+/**/ 0x3FD46000, 0x00000000,
+/**/ 0x3FF0E0CF, 0xB73728F8,
+/**/ 0x3FC7EAD9, 0xC406A36A,
+/**/ 0x3FD0C1F9, 0x91BDA616,
+/**/ 0x3FC7B69B, 0x5B86C42B,
+/**/ 0x3FCC8B56, 0x99CD8C9F,
+/**/ 0x3FCD3DF8, 0xF7084936,
+/**/ 0xBC923B74, 0x54942387,
+/**/ 0x3FD4BC63, 0x69FA40E8,
+/**/ 0x3FF10000, 0x00000000,
+/**/ 0xBF7F3048, 0xC8D707BB,
+/**/ 0x3FD4A000, 0x00000000,
+/**/ 0x3FF0E6D7, 0x0B1092B8,
+/**/ 0x3FC84FF5, 0x043F9011,
+/**/ 0x3FD0F1F6, 0xA7AFD6EB,
+/**/ 0x3FC8470F, 0x3AA5D7B9,
+/**/ 0x3FCD3DB6, 0x794E9CFD,
+/**/ 0x3FCE38D8, 0x90FB69FD,
+/**/ 0x3C9CFA2D, 0xC2327DC5,
+/**/ 0x3FD4FFF2, 0xAF11E2C0,
+/**/ 0x3FF10000, 0x00000000,
+/**/ 0xBF7928F4, 0xEF6D4848,
+/**/ 0x3FD4E000, 0x00000000,
+/**/ 0x3FF0ECF7, 0xCA008550,
+/**/ 0x3FC8B633, 0x9CB9ECA7,
+/**/ 0x3FD12318, 0x2B20AC3D,
+/**/ 0x3FC8DB0D, 0xD7D5E860,
+/**/ 0x3FCDF613, 0x9D1315AF,
+/**/ 0x3FCF3D21, 0x32D8BC6F,
+/**/ 0x3C9C6A36, 0x92E48EEE,
+/**/ 0x3FD5439A, 0x4436D008,
+/**/ 0x3FF10000, 0x00000000,
+/**/ 0xBF730835, 0xFF7AAF92,
+/**/ 0x3FD52000, 0x00000000,
+/**/ 0x3FF0F332, 0x3DBA2C62,
+/**/ 0x3FC91D9C, 0x7D83983C,
+/**/ 0x3FD15565, 0x4FDDA02E,
+/**/ 0x3FC972B5, 0xB48747C7,
+/**/ 0x3FCEB4A7, 0xBC9105F9,
+/**/ 0x3FD0259F, 0x6A535ECF,
+/**/ 0x3C87EB36, 0xF6EA55C1,
+/**/ 0x3FD5875A, 0x8FA83538,
+/**/ 0x3FF10000, 0x00000000,
+/**/ 0xBF699B84, 0x8BA73C6A,
+/**/ 0x3FD56000, 0x00000000,
+/**/ 0x3FF0F986, 0xB1B22D42,
+/**/ 0x3FC98636, 0xC29A92ED,
+/**/ 0x3FD188E5, 0x87DBE62D,
+/**/ 0x3FCA0E26, 0x792C37EB,
+/**/ 0x3FCF79AF, 0x2735E8CD,
+/**/ 0x3FD0B1D1, 0x6ECCD4C0,
+/**/ 0x3C9502B5, 0xBEAE0510,
+/**/ 0x3FD5CB33, 0xF8CF8AC0,
+/**/ 0x3FF10000, 0x00000000,
+/**/ 0xBF59E539, 0x374AF74C,
+/**/ 0x3FD5A000, 0x00000000,
+/**/ 0x3FF0FFF5, 0x7329D23A,
+/**/ 0x3FC9F009, 0xB568F082,
+/**/ 0x3FD1BDA0, 0x85939DB2,
+/**/ 0x3FCAAD81, 0x0283B18A,
+/**/ 0x3FD022B4, 0x72F69148,
+/**/ 0x3FD14362, 0x39AD0B79,
+/**/ 0xBCAD7968, 0x80828B86,
+/**/ 0x3FD60F26, 0xE847B130,
+/**/ 0x3FF10000, 0x00000000,
+/**/ 0xBEE519AC, 0x5B8BC081,
+/**/ 0x3FD5E000, 0x00000000,
+/**/ 0x3FF1067E, 0xD13A9687,
+/**/ 0x3FCA5B1C, 0xCE4F3F61,
+/**/ 0x3FD1F39E, 0x3E764545,
+/**/ 0x3FCB50E7, 0x6F90871B,
+/**/ 0x3FD08C0B, 0x6F487F97,
+/**/ 0x3FD1DA90, 0x67265C20,
+/**/ 0x3CAE5B02, 0x995723AD,
+/**/ 0x3FD65333, 0xC7E43AA0,
+/**/ 0x3FF10000, 0x00000000,
+/**/ 0x3F59FB44, 0xEA5A1D64,
+/**/ 0x3FD62000, 0x00000000,
+/**/ 0x3FF10D23, 0x1CE216D9,
+/**/ 0x3FCAC777, 0xB63E0B53,
+/**/ 0x3FD22AE6, 0xED81D055,
+/**/ 0x3FCBF87D, 0x3046C5AC,
+/**/ 0x3FD0F8FE, 0xFCB29FE4,
+/**/ 0x3FD2779D, 0xC99A404E,
+/**/ 0xBCA2AF1E, 0xC3202AE8,
+/**/ 0x3FD6975B, 0x02B8E378,
+/**/ 0x3FF10000, 0x00000000,
+/**/ 0x3F6A4639, 0xC42DB2AB,
+/**/ 0x3FD66000, 0x00000000,
+/**/ 0x3FF113E2, 0xA90E6A24,
+/**/ 0x3FCB3522, 0x485F2C6B,
+/**/ 0x3FD26383, 0x15F1D6CC,
+/**/ 0x3FCCA467, 0x14F9D555,
+/**/ 0x3FD169B3, 0x245E397E,
+/**/ 0x3FD31ACF, 0x99479CF7,
+/**/ 0xBC730D3F, 0x8992C228,
+/**/ 0x3FD6DB9D, 0x05213B28,
+/**/ 0x3FF10000, 0x00000000,
+/**/ 0x3F73E2A9, 0x0E6A2469,
+/**/ 0x3FD6A000, 0x00000000,
+/**/ 0x3FF11ABD, 0xCAAAE6D5,
+/**/ 0x3FCBA424, 0x93CF9B23,
+/**/ 0x3FD29D7B, 0x86106AD4,
+/**/ 0x3FCD54CB, 0x5E96870B,
+/**/ 0x3FD1DE4D, 0x9975D46D,
+/**/ 0x3FD3C46E, 0xA709F8A4,
+/**/ 0xBC9CB630, 0x457B6F5C,
+/**/ 0x3FD71FFA, 0x3CC87FC8,
+/**/ 0x3FF10000, 0x00000000,
+/**/ 0x3F7ABDCA, 0xAAE6D53D,
+/**/ 0x3FD6E000, 0x00000000,
+/**/ 0x3FF121B4, 0xD8AD589E,
+/**/ 0x3FCC1486, 0xDD6A8C89,
+/**/ 0x3FD2D8D9, 0x5A283891,
+/**/ 0x3FCE09D1, 0xCFB4F5A1,
+/**/ 0x3FD256F5, 0xCF594BB6,
+/**/ 0x3FD474C7, 0x92614C29,
+/**/ 0xBC88FB31, 0x533051E9,
+/**/ 0x3FD76473, 0x18B1AD28,
+/**/ 0x3FF14000, 0x00000000,
+/**/ 0xBF7E4B27, 0x52A761D6,
+/**/ 0x3FD72000, 0x00000000,
+/**/ 0x3FF128C8, 0x2C23AB4A,
+/**/ 0x3FCC8651, 0xA1A6A356,
+/**/ 0x3FD315A5, 0xFF99ABE3,
+/**/ 0x3FCEC3A3, 0xBE8EE4C2,
+/**/ 0x3FD2D3D5, 0x11207D5D,
+/**/ 0x3FD52C2B, 0x02FE6DF8,
+/**/ 0xBCA3F304, 0xFE4D8DF3,
+/**/ 0x3FD7A908, 0x093FC1F0,
+/**/ 0x3FF14000, 0x00000000,
+/**/ 0xBF7737D3, 0xDC54B622,
+/**/ 0x3FD76000, 0x00000000,
+/**/ 0x3FF12FF8, 0x20420F33,
+/**/ 0x3FCCF98D, 0x96860D89,
+/**/ 0x3FD353EB, 0x3814F292,
+/**/ 0x3FCF826C, 0x27E81BF7,
+/**/ 0x3FD35516, 0x9A827352,
+/**/ 0x3FD5EAED, 0xE614C6DF,
+/**/ 0x3C80AEDB, 0x36C1700C,
+/**/ 0x3FD7EDB9, 0x803E3C28,
+/**/ 0x3FF14000, 0x00000000,
+/**/ 0xBF7007DF, 0xBDF0CCC6,
+/**/ 0x3FD7A000, 0x00000000,
+/**/ 0x3FF13745, 0x12719C3A,
+/**/ 0x3FCD6E43, 0xAD9A717F,
+/**/ 0x3FD393B3, 0x1CFACD12,
+/**/ 0x3FD0232B, 0xE17B8F05,
+/**/ 0x3FD3DAE7, 0xB23873BC,
+/**/ 0x3FD6B169, 0xAFB712E5,
+/**/ 0x3C994C0C, 0x0BC74599,
+/**/ 0x3FD83287, 0xF0E9CF80,
+/**/ 0x3FF14000, 0x00000000,
+/**/ 0xBF6175DB, 0x1CC78CA5,
+/**/ 0x3FD7E000, 0x00000000,
+/**/ 0x3FF13EAF, 0x625F7844,
+/**/ 0x3FCDE47D, 0x161D9978,
+/**/ 0x3FD3D508, 0x22E63DCA,
+/**/ 0x3FD087CA, 0x8B2EC7EB,
+/**/ 0x3FD46577, 0xC5F619C8,
+/**/ 0x3FD77FFC, 0xA08A73DE,
+/**/ 0x3CA1DBDE, 0x6E7B547F,
+/**/ 0x3FD87773, 0xCFF956F8,
+/**/ 0x3FF14000, 0x00000000,
+/**/ 0xBF3509DA, 0x087BC752,
+/**/ 0x3FD82000, 0x00000000,
+/**/ 0x3FF14637, 0x720C869D,
+/**/ 0x3FCE5C43, 0x3F1FD940,
+/**/ 0x3FD417F5, 0x1D614654,
+/**/ 0x3FD0EF2A, 0x472052ED,
+/**/ 0x3FD4F4F8, 0x88116DA6,
+/**/ 0x3FD8570A, 0x102117B6,
+/**/ 0xBCAB6E89, 0x214A7328,
+/**/ 0x3FD8BC7D, 0x93A70458,
+/**/ 0x3FF14000, 0x00000000,
+/**/ 0x3F58DDC8, 0x321A7479,
+/**/ 0x3FD86000, 0x00000000,
+/**/ 0x3FF14DDD, 0xA5DDA5C4,
+/**/ 0x3FCED59F, 0xD9CD3739,
+/**/ 0x3FD45C85, 0x42C70412,
+/**/ 0x3FD15964, 0x49C983A8,
+/**/ 0x3FD5899E, 0x0EF7ED0B,
+/**/ 0x3FD936FA, 0xBC543499,
+/**/ 0x3CAFF50D, 0x7B29F22E,
+/**/ 0x3FD901A5, 0xB3B9CF50,
+/**/ 0x3FF14000, 0x00000000,
+/**/ 0x3F6BBB4B, 0xBB4B87E0,
+/**/ 0x3FD8A000, 0x00000000,
+/**/ 0x3FF155A2, 0x64AC8172,
+/**/ 0x3FCF509C, 0xDBCA7047,
+/**/ 0x3FD4A2C4, 0x3055A16F,
+/**/ 0x3FD1C692, 0xD25160C7,
+/**/ 0x3FD6239E, 0xF68F9906,
+/**/ 0x3FDA203D, 0x1DFC2EE2,
+/**/ 0x3CAD2019, 0x671EF39F,
+/**/ 0x3FD946EC, 0xA98F2718,
+/**/ 0x3FF14000, 0x00000000,
+/**/ 0x3F75A264, 0xAC8171A9,
+/**/ 0x3FD8E000, 0x00000000,
+/**/ 0x3FF15D86, 0x17D8FF02,
+/**/ 0x3FCFCD44, 0x81AAFD5E,
+/**/ 0x3FD4EABD, 0xEE72B776,
+/**/ 0x3FD236D1, 0x377F943F,
+/**/ 0x3FD6C334, 0x83A56DB7,
+/**/ 0x3FDB1345, 0xC36D6C50,
+/**/ 0xBC7841E5, 0x761537BB,
+/**/ 0x3FD98C52, 0xF024E808,
+/**/ 0x3FF14000, 0x00000000,
+/**/ 0x3F7D8617, 0xD8FF01DE,
+/**/ 0x3FD92000, 0x00000000,
+/**/ 0x3FF16589, 0x2B5B4A9A,
+/**/ 0x3FD025D0, 0xA8C0A8C6,
+/**/ 0x3FD5347E, 0xF524E4B6,
+/**/ 0x3FD2AA3B, 0xF565EDBD,
+/**/ 0x3FD7689A, 0xC98D2842,
+/**/ 0x3FDC108F, 0xB128B4DD,
+/**/ 0xBC8A5EEB, 0x4452A669,
+/**/ 0x3FD9D1D9, 0x04239878,
+/**/ 0x3FF18000, 0x00000000,
+/**/ 0xBF7A76D4, 0xA4B56661,
+/**/ 0x3FD96000, 0x00000000,
+/**/ 0x3FF16DAC, 0x0DD68BC8,
+/**/ 0x3FD065DF, 0x0EC54C3A,
+/**/ 0x3FD58014, 0x30C58A12,
+/**/ 0x3FD320F0, 0xBBCBCCEF,
+/**/ 0x3FD81410, 0xD218F380,
+/**/ 0x3FDD189C, 0xC9371D29,
+/**/ 0x3C58C3C1, 0x1D6E6EC7,
+/**/ 0x3FDA177F, 0x63E8EF18,
+/**/ 0x3FF18000, 0x00000000,
+/**/ 0xBF7253F2, 0x29743866,
+/**/ 0x3FD9A000, 0x00000000,
+/**/ 0x3FF175EF, 0x30AC48A8,
+/**/ 0x3FD0A6D3, 0x037BA7C0,
+/**/ 0x3FD5CD8B, 0x06EDCD18,
+/**/ 0x3FD39B0E, 0x7D679188,
+/**/ 0x3FD8C5D8, 0xC8128143,
+/**/ 0x3FDE2BF6, 0x39B3613A,
+/**/ 0xBC874080, 0xC70C9C76,
+/**/ 0x3FDA5D46, 0x8F92A560,
+/**/ 0x3FF18000, 0x00000000,
+/**/ 0xBF64219E, 0xA76EB06E,
+/**/ 0x3FD9E000, 0x00000000,
+/**/ 0x3FF17E53, 0x08107EEF,
+/**/ 0x3FD0E8B2, 0x40691386,
+/**/ 0x3FD61CF1, 0x5BA2319A,
+/**/ 0x3FD418B5, 0x7FF30656,
+/**/ 0x3FD97E38, 0x24624146,
+/**/ 0x3FDF4B2C, 0xF30D6589,
+/**/ 0xBC8D4AD9, 0x74DD0C9B,
+/**/ 0x3FDAA32F, 0x090998F8,
+/**/ 0x3FF18000, 0x00000000,
+/**/ 0xBF3ACF7E, 0xF81116BC,
+/**/ 0x3FDA2000, 0x00000000,
+/**/ 0x3FF186D8, 0x0B1E7A9D,
+/**/ 0x3FD12B82, 0xA98356F0,
+/**/ 0x3FD66E55, 0x96C051D8,
+/**/ 0x3FD49A07, 0x6D28A49D,
+/**/ 0x3FDA3D77, 0xDE14D616,
+/**/ 0x3FE03B6D, 0x13502F53,
+/**/ 0x3CA51700, 0x4AD59707,
+/**/ 0x3FDAE939, 0x540D3F08,
+/**/ 0x3FF18000, 0x00000000,
+/**/ 0x3F5B602C, 0x79EA752F,
+/**/ 0x3FDA6000, 0x00000000,
+/**/ 0x3FF18F7E, 0xB3EE7285,
+/**/ 0x3FD16F4A, 0x4EC4AF40,
+/**/ 0x3FD6C1C6, 0xA9B275FD,
+/**/ 0x3FD51F27, 0x64B886B9,
+/**/ 0x3FDB03E4, 0x9D72A144,
+/**/ 0x3FE0D7CF, 0xE7207DD5,
+/**/ 0xBCAACE1E, 0x8E77D1B2,
+/**/ 0x3FDB2F65, 0xF63F6C78,
+/**/ 0x3FF18000, 0x00000000,
+/**/ 0x3F6EFD67, 0xDCE509F5,
+/**/ 0x3FDAA000, 0x00000000,
+/**/ 0x3FF19847, 0x7FABF325,
+/**/ 0x3FD1B40F, 0x6DD15EDB,
+/**/ 0x3FD71754, 0x156D090D,
+/**/ 0x3FD5A83A, 0x0F44EE42,
+/**/ 0x3FDBD1CE, 0xF26149CC,
+/**/ 0x3FE17B14, 0x9EBB7D53,
+/**/ 0x3CA18867, 0x054C177A,
+/**/ 0x3FDB75B5, 0x773075F8,
+/**/ 0x3FF18000, 0x00000000,
+/**/ 0x3F78477F, 0xABF3257B,
+/**/ 0x3FDAE000, 0x00000000,
+/**/ 0x3FF1A132, 0xEEAD20E6,
+/**/ 0x3FD1F9D8, 0x73AFA8F4,
+/**/ 0x3FD76F0D, 0xF0BA2B44,
+/**/ 0x3FD63565, 0xB2776412,
+/**/ 0x3FDCA78B, 0x8E4B8181,
+/**/ 0x3FE22595, 0xDE92725A,
+/**/ 0xBCABDA45, 0x225EE470,
+/**/ 0x3FDBBC28, 0x606BABE0,
+/**/ 0x3FF1C000, 0x00000000,
+/**/ 0xBF7ECD11, 0x52DF1A7E,
+/**/ 0x3FDB2000, 0x00000000,
+/**/ 0x3FF1AA41, 0x848ADB16,
+/**/ 0x3FD240AB, 0xFE932ABB,
+/**/ 0x3FD7C904, 0xEED7E85D,
+/**/ 0x3FD6C6D2, 0x4640B1B3,
+/**/ 0x3FDD8573, 0x81D01020,
+/**/ 0x3FE2D7B3, 0x9938B939,
+/**/ 0x3CA12ECB, 0x36D76E02,
+/**/ 0x3FDC02BF, 0x3D843430,
+/**/ 0x3FF1C000, 0x00000000,
+/**/ 0xBF75BE7B, 0x7524EA70,
+/**/ 0x3FDB6000, 0x00000000,
+/**/ 0x3FF1B373, 0xC839C9AC,
+/**/ 0x3FD28890, 0xDFBC912D,
+/**/ 0x3FD8254A, 0x666DE3CA,
+/**/ 0x3FD75CA9, 0x8B57457C,
+/**/ 0x3FDE6BE4, 0x7E7E55FE,
+/**/ 0x3FE391D3, 0x68EC3777,
+/**/ 0xBC9F7EFE, 0x4D8A80A5,
+/**/ 0x3FDC497A, 0x9C2247A0,
+/**/ 0x3FF1C000, 0x00000000,
+/**/ 0xBF69186F, 0x8C6CA8A7,
+/**/ 0x3FDBA000, 0x00000000,
+/**/ 0x3FF1BCCA, 0x44246029,
+/**/ 0x3FD2D18E, 0x1D6EB966,
+/**/ 0x3FD883F0, 0x58DF9E20,
+/**/ 0x3FD7F717, 0x2308FF84,
+/**/ 0x3FDF5B41, 0x1CEC1692,
+/**/ 0x3FE45460, 0xEFAE7F7E,
+/**/ 0xBCACA88A, 0xC247C281,
+/**/ 0x3FDC905B, 0x0C10D428,
+/**/ 0x3FF1C000, 0x00000000,
+/**/ 0xBF49ADDE, 0xDCFEB6F6,
+/**/ 0x3FDBE000, 0x00000000,
+/**/ 0x3FF1C645, 0x8645E0A6,
+/**/ 0x3FD31BAA, 0xF4FA598C,
+/**/ 0x3FD8E509, 0x7A00CDBD,
+/**/ 0x3FD89648, 0xA876EFA4,
+/**/ 0x3FE029F8, 0x93BB3BA0,
+/**/ 0x3FE51FCE, 0x3E769492,
+/**/ 0xBC63BD0A, 0xDAC78BA6,
+/**/ 0x3FDCD761, 0x1F4B8A08,
+/**/ 0x3FF1C000, 0x00000000,
+/**/ 0x3F591619, 0x178298DB,
+/**/ 0x3FDC2000, 0x00000000,
+/**/ 0x3FF1CFE6, 0x20466A93,
+/**/ 0x3FD366EE, 0xDCE16113,
+/**/ 0x3FD948A9, 0x3831A262,
+/**/ 0x3FD93A6D, 0xCB5336B7,
+/**/ 0x3FE0AB30, 0xF50362A5,
+/**/ 0x3FE5F494, 0x440F45E4,
+/**/ 0xBCA1B23F, 0x79A811B8,
+/**/ 0x3FDD1E8D, 0x6A0D56C8,
+/**/ 0x3FF1C000, 0x00000000,
+/**/ 0x3F6FCC40, 0x8CD52690,
+/**/ 0x3FDC6000, 0x00000000,
+/**/ 0x3FF1D9AC, 0xA798215A,
+/**/ 0x3FD3B361, 0x87135170,
+/**/ 0x3FD9AEE3, 0xC4E92F90,
+/**/ 0x3FD9E3B8, 0x6C3B0A06,
+/**/ 0x3FE13183, 0x439D6983,
+/**/ 0x3FE6D333, 0x444347EE,
+/**/ 0x3C9E6687, 0x141D7ADE,
+/**/ 0x3FDD65E0, 0x82DF5278,
+/**/ 0x3FF1C000, 0x00000000,
+/**/ 0x3F79ACA7, 0x98215A4D,
+/**/ 0x3FDCA000, 0x00000000,
+/**/ 0x3FF1E399, 0xB59577B1,
+/**/ 0x3FD4010A, 0xE343E389,
+/**/ 0x3FDA17CE, 0x1DB4A57B,
+/**/ 0x3FDA925C, 0xBAC8CA27,
+/**/ 0x3FE1BD2C, 0x29AC5009,
+/**/ 0x3FE7BC33, 0x5806ABBE,
+/**/ 0x3C89743A, 0xD953CBEA,
+/**/ 0x3FDDAD5B, 0x02A82420,
+/**/ 0x3FF20000, 0x00000000,
+/**/ 0xBF7C664A, 0x6A884EAF,
+/**/ 0x3FDCE000, 0x00000000,
+/**/ 0x3FF1EDAD, 0xE7A0AD1E,
+/**/ 0x3FD44FF3, 0x215D62D8,
+/**/ 0x3FDA837E, 0x15B2742E,
+/**/ 0x3FDB4691, 0x557C3A62,
+/**/ 0x3FE24E6B, 0x9ABECCA0,
+/**/ 0x3FE8B024, 0xF75D3619,
+/**/ 0xBC60A42B, 0x953C1F21,
+/**/ 0x3FDDF4FD, 0x84BBE168,
+/**/ 0x3FF20000, 0x00000000,
+/**/ 0xBF725218, 0x5F52E269,
+/**/ 0x3FDD2000, 0x00000000,
+/**/ 0x3FF1F7E9, 0xDF448BE1,
+/**/ 0x3FD4A022, 0xB4103D45,
+/**/ 0x3FDAF20A, 0x5F90F152,
+/**/ 0x3FDC008F, 0x6B992E26,
+/**/ 0x3FE2E585, 0x07C18F30,
+/**/ 0x3FE9AFA1, 0x8DCE89C2,
+/**/ 0xBC8B90A5, 0xE5B4E0DD,
+/**/ 0x3FDE3CC8, 0xA6EC6EF0,
+/**/ 0x3FF20000, 0x00000000,
+/**/ 0xBF602C41, 0x76E83DEE,
+/**/ 0x3FDD6000, 0x00000000,
+/**/ 0x3FF2024E, 0x42567651,
+/**/ 0x3FD4F1A2, 0x53815E48,
+/**/ 0x3FDB638A, 0x98189F26,
+/**/ 0x3FDCC092, 0xE11F7BB9,
+/**/ 0x3FE382BF, 0x968E1C3C,
+/**/ 0x3FEABB4C, 0x1A4C4551,
+/**/ 0xBCAC384D, 0xC65EE1E9,
+/**/ 0x3FDE84BD, 0x099A6620,
+/**/ 0x3FF20000, 0x00000000,
+/**/ 0x3F427212, 0xB3B2877E,
+/**/ 0x3FDDA000, 0x00000000,
+/**/ 0x3FF20CDB, 0xBB19D366,
+/**/ 0x3FD5447B, 0x00190520,
+/**/ 0x3FDBD817, 0x514AC3D7,
+/**/ 0x3FDD86DA, 0x7501B24E,
+/**/ 0x3FE42666, 0x5D5DCC91,
+/**/ 0x3FEBD3D1, 0xDB834BBA,
+/**/ 0xBCA62892, 0x64307FE4,
+/**/ 0x3FDECCDB, 0x4FC685E0,
+/**/ 0x3FF20000, 0x00000000,
+/**/ 0x3F69B776, 0x33A6CD00,
+/**/ 0x3FDDE000, 0x00000000,
+/**/ 0x3FF21792, 0xF864EB38,
+/**/ 0x3FD598B6, 0x0573E0CA,
+/**/ 0x3FDC4FCA, 0x1E1D9C05,
+/**/ 0x3FDE53A7, 0xE9C2FB44,
+/**/ 0x3FE4D0C8, 0xA26E99AF,
+/**/ 0x3FECF9EB, 0x09A8A359,
+/**/ 0xBCADF861, 0xD9AFA9E0,
+/**/ 0x3FDF1524, 0x1F23B3F8,
+/**/ 0x3FF20000, 0x00000000,
+/**/ 0x3F7792F8, 0x64EB3836,
+/**/ 0x3FDE2000, 0x00000000,
+/**/ 0x3FF22274, 0xADC744F8,
+/**/ 0x3FD5EE5C, 0xFD785957,
+/**/ 0x3FDCCABD, 0x9EE01B3A,
+/**/ 0x3FDF2740, 0x30A7B7B5,
+/**/ 0x3FE5823A, 0x202E0D0D,
+/**/ 0x3FEE2E5B, 0x9EEBE829,
+/**/ 0xBC93BB42, 0xE2EA9787,
+/**/ 0x3FDF5D98, 0x202994B8,
+/**/ 0x3FF24000, 0x00000000,
+/**/ 0xBF7D8B52, 0x38BB0864,
+/**/ 0x3FDE6000, 0x00000000,
+/**/ 0x3FF22D81, 0x93B1990A,
+/**/ 0x3FD64579, 0xD3920D0F,
+/**/ 0x3FDD490D, 0x8E4FE1FE,
+/**/ 0x3FE000F5, 0xCBD3ED59,
+/**/ 0x3FE63B13, 0x4E45F774,
+/**/ 0x3FEF71F4, 0x2FD578CE,
+/**/ 0x3CA8AD1C, 0xC0E1AC47,
+/**/ 0x3FDFA637, 0xFE27BF60,
+/**/ 0x3FF24000, 0x00000000,
+/**/ 0xBF727E6C, 0x4E66F5A1,
+/**/ 0x3FDEA000, 0x00000000,
+/**/ 0x3FF238BA, 0x679F6AE1,
+/**/ 0x3FD69E16, 0xC815A8F5,
+/**/ 0x3FDDCAD6, 0xCF6CD4C9,
+/**/ 0x3FE071FA, 0xFD2ADE38,
+/**/ 0x3FE6FBB1, 0xAFEE9630,
+/**/ 0x3FF062C9, 0x6A7ACB82,
+/**/ 0x3C7E3580, 0x35D3555B,
+/**/ 0x3FDFEF04, 0x67599588,
+/**/ 0x3FF24000, 0x00000000,
+/**/ 0xBF5D1661, 0x82547B6F,
+/**/ 0x3FDEE000, 0x00000000,
+/**/ 0x3FF2441F, 0xEC425F4B,
+/**/ 0x3FD6F83E, 0x73CF67B4,
+/**/ 0x3FDE5037, 0x7C1691BA,
+/**/ 0x3FE0E6D7, 0x7AF8190E,
+/**/ 0x3FE7C478, 0x27F29078,
+/**/ 0x3FF11512, 0x13B5FFDC,
+/**/ 0x3C6CC7A1, 0x5FEBA301,
+/**/ 0x3FE01BFF, 0x067D6224,
+/**/ 0x3FF24000, 0x00000000,
+/**/ 0x3F507FB1, 0x097D2BDC,
+/**/ 0x3FDF2000, 0x00000000,
+/**/ 0x3FF24FB2, 0xE9AF6533,
+/**/ 0x3FD753FB, 0xCBBEA804,
+/**/ 0x3FDED94E, 0xF480E731,
+/**/ 0x3FE15FB5, 0x106D90C6,
+/**/ 0x3FE895CF, 0x52DAD430,
+/**/ 0x3FF1D052, 0x28FAAE13,
+/**/ 0xBCA50976, 0xE849F35A,
+/**/ 0x3FE04092, 0xD1AE3B48,
+/**/ 0x3FF24000, 0x00000000,
+/**/ 0x3F6F65D3, 0x5ECA665D,
+/**/ 0x3FDF6000, 0x00000000,
+/**/ 0x3FF25B74, 0x2D8DC7FA,
+/**/ 0x3FD7B15A, 0x25013475,
+/**/ 0x3FDF663D, 0xEF8D6387,
+/**/ 0x3FE1DCBF, 0xA2DF4BFF,
+/**/ 0x3FE97025, 0xE7C2E4E5,
+/**/ 0x3FF29510, 0x1C2AE4AB,
+/**/ 0x3CA4C8DC, 0xB02A3D13,
+/**/ 0x3FE0653D, 0xF0FD9FD8,
+/**/ 0x3FF24000, 0x00000000,
+/**/ 0x3F7B742D, 0x8DC7FA40,
+/**/ 0x3FDFA000, 0x00000000,
+/**/ 0x3FF26764, 0x8B4843F2,
+/**/ 0x3FD81065, 0x38F10257,
+/**/ 0x3FDFF726, 0x8C1920B1,
+/**/ 0x3FE25E25, 0x5148D4E4,
+/**/ 0x3FEA53F1, 0x2061C3FE,
+/**/ 0x3FF363DB, 0x5B9300E5,
+/**/ 0xBCA47774, 0x624B8B97,
+/**/ 0x3FE08A00, 0xC1CAE338,
+/**/ 0x3FF28000, 0x00000000,
+/**/ 0xBF789B74, 0xB7BC0E50,
+/**/ 0x3FDFE000, 0x00000000,
+/**/ 0x3FF27384, 0xDC4036F2,
+/**/ 0x3FD87129, 0x29775C8F,
+/**/ 0x3FE04616, 0x31A78776,
+/**/ 0x3FE2E416, 0x95EE0C65,
+/**/ 0x3FEB41AD, 0x28E05161,
+/**/ 0x3FF43D4C, 0xFF1DF849,
+/**/ 0x3CA5941C, 0xBABBA919,
+/**/ 0x3FE0AEDB, 0xA3221C1C,
+/**/ 0x3FF28000, 0x00000000,
+/**/ 0xBF68F647, 0x7F921C27,
+/**/ 0x3FE01000, 0x00000000,
+/**/ 0x3FF27FD6, 0x00030888,
+/**/ 0x3FD8D3B2, 0x8598A1B5,
+/**/ 0x3FE092BA, 0x4E0BC755,
+/**/ 0x3FE36EC6, 0x6A428EEC,
+/**/ 0x3FEC39C0, 0x44F514C9,
+/**/ 0x3FF52205, 0x18C4EF3A,
+/**/ 0x4000C1D1, 0xA852F235,
+/**/ 0x3CA78082, 0xD00F64B8,
+/**/ 0x3FE0D3CE, 0xF5C846F8,
+/**/ 0x3FF28000, 0x00000000,
+/**/ 0xBF04FFFE, 0x7BBC39DF,
+/**/ 0x3FE03000, 0x00000000,
+/**/ 0x3FF28C58, 0xDC81E6D7,
+/**/ 0x3FD9380E, 0x4E3BF356,
+/**/ 0x3FE0E192, 0xFFC646A7,
+/**/ 0x3FE3FE6A, 0x6D34756D,
+/**/ 0x3FED3CEF, 0x139ABC91,
+/**/ 0x3FF612B8, 0xF80111C0,
+/**/ 0x4001A33C, 0x3467C688,
+/**/ 0xBC8A9954, 0x34F59445,
+/**/ 0x3FE0F8DB, 0x1C47D550,
+/**/ 0x3FF28000, 0x00000000,
+/**/ 0x3F68B1B9, 0x03CDAE3F,
+/**/ 0x3FE05000, 0x00000000,
+/**/ 0x3FF2990E, 0x5E4BF713,
+/**/ 0x3FD99E49, 0xFB326E9E,
+/**/ 0x3FE132B4, 0x8779391A,
+/**/ 0x3FE4933B, 0x0C2FE325,
+/**/ 0x3FEE4BB1, 0xAEAAE1D0,
+/**/ 0x3FF71020, 0x1F4377BD,
+/**/ 0x40029271, 0x1C886605,
+/**/ 0xBCA33AB1, 0x7130CE99,
+/**/ 0x3FE11E00, 0x7AFDAF10,
+/**/ 0x3FF28000, 0x00000000,
+/**/ 0x3F790E5E, 0x4BF712C7,
+/**/ 0x3FE07000, 0x00000000,
+/**/ 0x3FF2A5F7, 0x78CB1A3B,
+/**/ 0x3FDA0673, 0x8081C5D1,
+/**/ 0x3FE18634, 0x0D5E6499,
+/**/ 0x3FE52D73, 0xAEDD6BE6,
+/**/ 0x3FEF66A5, 0x1CF1AAA0,
+/**/ 0x3FF81B02, 0x4834E5A9,
+/**/ 0x40039066, 0xFCE48906,
+/**/ 0xBCA34E4F, 0x6BFB4C85,
+/**/ 0x3FE1433F, 0x7826AAD4,
+/**/ 0x3FF2C000, 0x00000000,
+/**/ 0xBF7A0887, 0x34E5C574,
+/**/ 0x3FE09000, 0x00000000,
+/**/ 0x3FF2B315, 0x268368DB,
+/**/ 0x3FDA7099, 0x53F655B7,
+/**/ 0x3FE1DC27, 0xAD9032EC,
+/**/ 0x3FE5CD52, 0xE5F88E23,
+/**/ 0x3FF04738, 0x0A68BDFC,
+/**/ 0x3FF93435, 0x2F057820,
+/**/ 0x40049E27, 0xDAE8A2FC,
+/**/ 0x3C86832C, 0xFAA44565,
+/**/ 0x3FE16898, 0x7BED8260,
+/**/ 0x3FF2C000, 0x00000000,
+/**/ 0xBF69D5B2, 0xF92E4A41,
+/**/ 0x3FE0B000, 0x00000000,
+/**/ 0x3FF2C068, 0x69558A9E,
+/**/ 0x3FDADCCA, 0x73011B64,
+/**/ 0x3FE234A6, 0x8511146A,
+/**/ 0x3FE6731A, 0x9D6CBF3C,
+/**/ 0x3FF0E1E1, 0xD575F00A,
+/**/ 0x3FFA5C9D, 0xADEA17E7,
+/**/ 0x4005BCD2, 0xD9123E7C,
+/**/ 0xBCA23E4F, 0xCC2AE1E4,
+/**/ 0x3FE18E0B, 0xF07948F0,
+/**/ 0x3FF2C000, 0x00000000,
+/**/ 0x3F1A1A55, 0x62A7614A,
+/**/ 0x3FE0D000, 0x00000000,
+/**/ 0x3FF2CDF2, 0x4AC410C6,
+/**/ 0x3FDB4B16, 0x68E63D97,
+/**/ 0x3FE28FC8, 0xBFA256B2,
+/**/ 0x3FE71F10, 0x51FDF05A,
+/**/ 0x3FF183AE, 0x0753C882,
+/**/ 0x3FFB9530, 0xF1921090,
+/**/ 0x4006ED9E, 0x14F942BC,
+/**/ 0x3CA27879, 0x89C77FA3,
+/**/ 0x3FE1B39A, 0x41FC691C,
+/**/ 0x3FF2C000, 0x00000000,
+/**/ 0x3F6BE495, 0x88218CD6,
+/**/ 0x3FE0F000, 0x00000000,
+/**/ 0x3FF2DBB3, 0xDC3BFD25,
+/**/ 0x3FDBBB8D, 0x55413207,
+/**/ 0x3FE2EDA7, 0xA6792BF1,
+/**/ 0x3FE7D17D, 0x4AC4E230,
+/**/ 0x3FF22D00, 0xAAE6CB05,
+/**/ 0x3FFCDEF5, 0xC9028E71,
+/**/ 0x400831D8, 0xB40C626C,
+/**/ 0x3C953FEF, 0x9873F484,
+/**/ 0x3FE1D943, 0xDEC430C0,
+/**/ 0x3FF2C000, 0x00000000,
+/**/ 0x3F7BB3DC, 0x3BFD24A1,
+/**/ 0x3FE11000, 0x00000000,
+/**/ 0x3FF2E9AE, 0x3760A19B,
+/**/ 0x3FDC2E3F, 0xF2E3E2EB,
+/**/ 0x3FE34E5D, 0xAFE1CD38,
+/**/ 0x3FE88AAE, 0xD6CE0B26,
+/**/ 0x3FF2DE44, 0x2C4B06C6,
+/**/ 0x3FFE3B06, 0x138813D2,
+/**/ 0x40098AED, 0x23FD5612,
+/**/ 0xBC91EC19, 0xB7AF0E54,
+/**/ 0x3FE1FF09, 0x3748F114,
+/**/ 0x3FF30000, 0x00000000,
+/**/ 0xBF7651C8, 0x9F5E657E,
+/**/ 0x3FE13000, 0x00000000,
+/**/ 0x3FF2F7E2, 0x7E5B072B,
+/**/ 0x3FDCA33F, 0x9F169C4D,
+/**/ 0x3FE3B206, 0x8FE1EB56,
+/**/ 0x3FE94AF6, 0x8F30E1B7,
+/**/ 0x3FF397E9, 0xCFCF9887,
+/**/ 0x3FFFAA90, 0x4FB7F25F,
+/**/ 0x400AFA63, 0x94745D90,
+/**/ 0x3C96955C, 0x2A139390,
+/**/ 0x3FE224EA, 0xBE3EBA20,
+/**/ 0x3FF30000, 0x00000000,
+/**/ 0xBF603B03, 0x49F1AA85,
+/**/ 0x3FE15000, 0x00000000,
+/**/ 0x3FF30651, 0xDC2D0E76,
+/**/ 0x3FDD1A9E, 0x613EF408,
+/**/ 0x3FE418BF, 0x49ED083D,
+/**/ 0x3FEA12AA, 0x9DFD1E23,
+/**/ 0x3FF45A6A, 0x32B75F76,
+/**/ 0x4000976C, 0xA7673F47,
+/**/ 0x400C81E4, 0xB046AC6A,
+/**/ 0x3C879FF7, 0x7D1BEB80,
+/**/ 0x3FE24AE8, 0xE8A6B8B0,
+/**/ 0x3FF30000, 0x00000000,
+/**/ 0x3F594770, 0xB439D90E,
+/**/ 0x3FE17000, 0x00000000,
+/**/ 0x3FF314FD, 0x85087ECD,
+/**/ 0x3FDD946E, 0xF2F45390,
+/**/ 0x3FE482A6, 0x43BEDA05,
+/**/ 0x3FEAE226, 0x0A640DD7,
+/**/ 0x3FF52645, 0xD6A3D695,
+/**/ 0x4001649F, 0x08098FE0,
+/**/ 0x400E233C, 0x9D2BADE7,
+/**/ 0x3C9E948C, 0x4E5F8348,
+/**/ 0x3FE27104, 0x2DE13E58,
+/**/ 0x3FF30000, 0x00000000,
+/**/ 0x3F74FD85, 0x087ECD1A,
+/**/ 0x3FE19000, 0x00000000,
+/**/ 0x3FF323E6, 0xB6AA3C67,
+/**/ 0x3FDE10C4, 0xC8894828,
+/**/ 0x3FE4EFDB, 0x59718389,
+/**/ 0x3FEBB9C9, 0x0A8D7622,
+/**/ 0x3FF5FC05, 0xB8A62B12,
+/**/ 0x40023D9A, 0xE4296831,
+/**/ 0x400FE05E, 0x49C0B830,
+/**/ 0x3CA19107, 0xC1189DE8,
+/**/ 0x3FE2973D, 0x07C07BCC,
+/**/ 0x3FF34000, 0x00000000,
+/**/ 0xBF7C1949, 0x55C3993D,
+/**/ 0x3FE1B000, 0x00000000,
+/**/ 0x3FF3330E, 0xB8B9E20B,
+/**/ 0x3FDE8FB4, 0x1A11468B,
+/**/ 0x3FE5607F, 0xF2E740E1,
+/**/ 0x3FEC99F9, 0x5B91DB14,
+/**/ 0x3FF6DC3B, 0xF50C5FAA,
+/**/ 0x4003232A, 0x0CFAC1C7,
+/**/ 0x4010DDB3, 0x894EFD30,
+/**/ 0xBCA7760F, 0x3783D916,
+/**/ 0x3FE2BD93, 0xF29BF5F0,
+/**/ 0x3FF34000, 0x00000000,
+/**/ 0xBF69E28E, 0x8C3BEA7F,
+/**/ 0x3FE1D000, 0x00000000,
+/**/ 0x3FF34276, 0xDD2DFE6D,
+/**/ 0x3FDF1151, 0xECEB226B,
+/**/ 0x3FE5D4B7, 0x1AA123CE,
+/**/ 0x3FED8322, 0xA01F65F8,
+/**/ 0x3FF7C784, 0x791CE583,
+/**/ 0x40041625, 0xC15A6B9C,
+/**/ 0x4011DB51, 0x64280FEB,
+/**/ 0x3CA10463, 0x28CA6DBB,
+/**/ 0x3FE2E409, 0x6D64BEAC,
+/**/ 0x3FF34000, 0x00000000,
+/**/ 0x3F43B6E9, 0x6FF364E1,
+/**/ 0x3FE1F000, 0x00000000,
+/**/ 0x3FF35220, 0x80B539C7,
+/**/ 0x3FDF95B4, 0x1DD91A82,
+/**/ 0x3FE64CA5, 0x961EA9CA,
+/**/ 0x3FEE75B6, 0xC65B3B2F,
+/**/ 0x3FF8BE85, 0xC412E59F,
+/**/ 0x40051778, 0x02462A51,
+/**/ 0x4012EA48, 0x109FC81B,
+/**/ 0x3C959E4C, 0x9F70CA98,
+/**/ 0x3FE30A9D, 0xF9BA7B3C,
+/**/ 0x3FF34000, 0x00000000,
+/**/ 0x3F722080, 0xB539C6A2,
+/**/ 0x3FE21000, 0x00000000,
+/**/ 0x3FF3620D, 0x0B24ACDA,
+/**/ 0x3FE00E78, 0xB5D803B6,
+/**/ 0x3FE6C871, 0xFFE457FB,
+/**/ 0x3FEF722E, 0x759EF386,
+/**/ 0x3FF9C1F1, 0xB8D0E874,
+/**/ 0x4006281D, 0x080FB06E,
+/**/ 0x40140BF2, 0xD1F69DF7,
+/**/ 0xBC8489EA, 0xCBFAF37F,
+/**/ 0x3FE33152, 0x1C0141BC,
+/**/ 0x3FF38000, 0x00000000,
+/**/ 0xBF7DF2F4, 0xDB532667,
+/**/ 0x3FE23000, 0x00000000,
+/**/ 0x3FF3723D, 0xEFEBB76D,
+/**/ 0x3FE05390, 0xC153FC4C,
+/**/ 0x3FE74844, 0xE34A2666,
+/**/ 0x3FF03C84, 0xC260A400,
+/**/ 0x3FFAD286, 0x81E70F01,
+/**/ 0x40074924, 0xDBC4A78E,
+/**/ 0x401541CB, 0x8BBCA2E0,
+/**/ 0x3C9C7528, 0x7BEA8472,
+/**/ 0x3FE35826, 0x5B7858F8,
+/**/ 0x3FF38000, 0x00000000,
+/**/ 0xBF6B8420, 0x28912510,
+/**/ 0x3FE25000, 0x00000000,
+/**/ 0x3FF382B4, 0xAE8DA9C7,
+/**/ 0x3FE09A2E, 0x842CABB9,
+/**/ 0x3FE7CC48, 0xDA356141,
+/**/ 0x3FF0C567, 0xBCD4FDB8,
+/**/ 0x3FFBF10F, 0x89B62C32,
+/**/ 0x40087BB5, 0x18ADC4B9,
+/**/ 0x40168D6D, 0xC516F6F1,
+/**/ 0xBC933A6B, 0x2E37D6A3,
+/**/ 0x3FE37F1B, 0x4251E5AC,
+/**/ 0x3FF38000, 0x00000000,
+/**/ 0x3F45A574, 0x6D4E3A7A,
+/**/ 0x3FE27000, 0x00000000,
+/**/ 0x3FF39372, 0xD3219A4C,
+/**/ 0x3FE0E25E, 0xD4394437,
+/**/ 0x3FE854AA, 0xACE4CC74,
+/**/ 0x3FF15408, 0x0981EE13,
+/**/ 0x3FFD1E66, 0x88AA5332,
+/**/ 0x4009C10A, 0xDA3BD18F,
+/**/ 0x4017F099, 0xFFE4AE21,
+/**/ 0xBCAED56B, 0x7B588ABE,
+/**/ 0x3FE3A631, 0x5DCB911C,
+/**/ 0x3FF38000, 0x00000000,
+/**/ 0x3F7372D3, 0x219A4BA9,
+/**/ 0x3FE29000, 0x00000000,
+/**/ 0x3FF3A479, 0xF6D8C6BC,
+/**/ 0x3FE12C2F, 0x11197A32,
+/**/ 0x3FE8E199, 0x73F949D5,
+/**/ 0x3FF1E8B1, 0xEE7A481D,
+/**/ 0x3FFE5B74, 0xABBE8828,
+/**/ 0x400B1A7C, 0xDB3D83BC,
+/**/ 0x40196D39, 0x6DC46100,
+/**/ 0x3CA7798C, 0xACD8F69C,
+/**/ 0x3FE3CD69, 0x3E4835E8,
+/**/ 0x3FF3C000, 0x00000000,
+/**/ 0xBF7B8609, 0x27394391,
+/**/ 0x3FE2B000, 0x00000000,
+/**/ 0x3FF3B5CB, 0xC08BE738,
+/**/ 0x3FE177AD, 0x2B5CB6B7,
+/**/ 0x3FE97346, 0xBCE90EB1,
+/**/ 0x3FF283B6, 0x68EC7F04,
+/**/ 0x3FFFA933, 0xD5B8ED04,
+/**/ 0x400C897D, 0xCBCDFF9A,
+/**/ 0x401B0562, 0x0E4ABF55,
+/**/ 0x3C881FF6, 0x1EE42043,
+/**/ 0x3FE3F4C3, 0x776AA08C,
+/**/ 0x3FF3C000, 0x00000000,
+/**/ 0xBF64687E, 0xE8319086,
+/**/ 0x3FE2D000, 0x00000000,
+/**/ 0x3FF3C769, 0xE54FE05E,
+/**/ 0x3FE1C4E7, 0xAC1A81A0,
+/**/ 0x3FEA09E6, 0xB10FA326,
+/**/ 0x3FF3256B, 0x840F679B,
+/**/ 0x40008457, 0xFEE9EF1A,
+/**/ 0x400E0F9E, 0xE4146343,
+/**/ 0x401CBB5B, 0x433496A9,
+/**/ 0xBCA57A4C, 0x59F087C0,
+/**/ 0x3FE41C40, 0xA03171A8,
+/**/ 0x3FF3C000, 0x00000000,
+/**/ 0x3F5DA795, 0x3F81773D,
+/**/ 0x3FE2F000, 0x00000000,
+/**/ 0x3FF3D956, 0x291249DC,
+/**/ 0x3FE213ED, 0xBD044AC9,
+/**/ 0x3FEAA5B0, 0x3F917FA8,
+/**/ 0x3FF3CE2C, 0xB7380A79,
+/**/ 0x40013D84, 0x576AFAE8,
+/**/ 0x400FAE92, 0xBAAB74F3,
+/**/ 0x401E91A2, 0xE9129E4A,
+/**/ 0x3C905671, 0x0CEC83F7,
+/**/ 0x3FE443E1, 0x53143194,
+/**/ 0x3FF3C000, 0x00000000,
+/**/ 0x3F795629, 0x1249DBC4,
+/**/ 0x3FE31000, 0x00000000,
+/**/ 0x3FF3EB92, 0x5F3E4715,
+/**/ 0x3FE264CF, 0x30F965D1,
+/**/ 0x3FEB46DD, 0x4A4F2FB2,
+/**/ 0x3FF47E5B, 0x4BC2E94F,
+/**/ 0x400200B9, 0x54F8F9EB,
+/**/ 0x4010B418, 0x33305D9F,
+/**/ 0x40204579, 0x826EF167,
+/**/ 0xBC9737A0, 0xE06EBCAE,
+/**/ 0x3FE46BA6, 0x2E21A53C,
+/**/ 0x3FF40000, 0x00000000,
+/**/ 0xBF746DA0, 0xC1B8EB04,
+/**/ 0x3FE33000, 0x00000000,
+/**/ 0x3FF3FE20, 0x6B6A38D5,
+/**/ 0x3FE2B79C, 0x8D26C7A0,
+/**/ 0x3FEBEDAA, 0xD62978F8,
+/**/ 0x3FF5365E, 0xCB8CC6D1,
+/**/ 0x4002CE9C, 0xD894AF54,
+/**/ 0x40119F3B, 0x79F7C63E,
+/**/ 0x40215524, 0x0C8E7B9E,
+/**/ 0x3CA485D0, 0x13DC9A80,
+/**/ 0x3FE4938F, 0xD31F754C,
+/**/ 0x3FF40000, 0x00000000,
+/**/ 0xBF3DF949, 0x5C72B1E7,
+/**/ 0x3FE35000, 0x00000000,
+/**/ 0x3FF41102, 0x420ED8E7,
+/**/ 0x3FE30C67, 0x12BCE2B2,
+/**/ 0x3FEC9A59, 0x3EDE345E,
+/**/ 0x3FF5F6A5, 0x78CAB466,
+/**/ 0x4003A7E1, 0x3EAD62EE,
+/**/ 0x401299C8, 0x9CB9A228,
+/**/ 0x40227974, 0x1BE749B0,
+/**/ 0x3CAFE28F, 0xC6A9831F,
+/**/ 0x3FE4BB9E, 0xE7AB3A40,
+/**/ 0x3FF40000, 0x00000000,
+/**/ 0x3F710242, 0x0ED8E776,
+/**/ 0x3FE37000, 0x00000000,
+/**/ 0x3FF42439, 0xE9485B43,
+/**/ 0x3FE36340, 0xC946E033,
+/**/ 0x3FED4D2C, 0x6ECC5A7E,
+/**/ 0x3FF6BFA4, 0xD027255A,
+/**/ 0x40048D46, 0x72504BE1,
+/**/ 0x4013A4ED, 0x09445BD5,
+/**/ 0x4023B435, 0x749E19F9,
+/**/ 0xBC40E7E5, 0xEAAAF53E,
+/**/ 0x3FE4E3D4, 0x155D0070,
+/**/ 0x3FF44000, 0x00000000,
+/**/ 0xBF7BC616, 0xB7A4BD36,
+/**/ 0x3FE39000, 0x00000000,
+/**/ 0x3FF437C9, 0x79A23C23,
+/**/ 0x3FE3BC3C, 0x89AF6A9D,
+/**/ 0x3FEE066C, 0x1AF553BA,
+/**/ 0x3FF791DA, 0x1622569A,
+/**/ 0x40057F9B, 0x1B18AE2B,
+/**/ 0x4014C1F0, 0x88BFF240,
+/**/ 0x40250761, 0x019A4522,
+/**/ 0x3CA4C238, 0xFDFCCB13,
+/**/ 0x3FE50C30, 0x09EB58F8,
+/**/ 0x3FF44000, 0x00000000,
+/**/ 0xBF606D0C, 0xBB87B9E1,
+/**/ 0x3FE3B000, 0x00000000,
+/**/ 0x3FF44BB3, 0x1EEE6F35,
+/**/ 0x3FE4176E, 0x0A004D1D,
+/**/ 0x3FEEC664, 0x0399FA54,
+/**/ 0x3FF86DCA, 0xF0CFD106,
+/**/ 0x40067FBD, 0xE8C80E97,
+/**/ 0x4015F237, 0xD9CD2D79,
+/**/ 0x40267521, 0xC8076345,
+/**/ 0x3CAEC756, 0xB089F7AF,
+/**/ 0x3FE534B3, 0x77510D94,
+/**/ 0x3FF44000, 0x00000000,
+/**/ 0x3F67663D, 0xDCDE698F,
+/**/ 0x3FE3D000, 0x00000000,
+/**/ 0x3FF45FF9, 0x1928B1BE,
+/**/ 0x3FE474E9, 0xE9EB53E9,
+/**/ 0x3FEF8D64, 0x39DB03B6,
+/**/ 0x3FF95406, 0x0F298B87,
+/**/ 0x40078E9E, 0xFFC72AB6,
+/**/ 0x40173747, 0x941456E7,
+/**/ 0x4027FFDA, 0x74A71E71,
+/**/ 0xBCAEED93, 0xFE7483B3,
+/**/ 0x3FE55D5F, 0x13F48EC0,
+/**/ 0x3FF44000, 0x00000000,
+/**/ 0x3F7FF919, 0x28B1BDFF,
+/**/ 0x3FE3F000, 0x00000000,
+/**/ 0x3FF4749D, 0xBD66D0C4,
+/**/ 0x3FE4D4C5, 0xC02C2013,
+/**/ 0x3FF02DE0, 0xB56768CC,
+/**/ 0x3FFA4523, 0xDF53A7BD,
+/**/ 0x4008AD41, 0x8A357386,
+/**/ 0x401892C7, 0x5E392799,
+/**/ 0x4029AA2B, 0x97746ACD,
+/**/ 0x3C924F0A, 0xB4A71E44,
+/**/ 0x3FE58633, 0x9AD13548,
+/**/ 0x3FF48000, 0x00000000,
+/**/ 0xBF66C485, 0x325E775E,
+/**/ 0x3FE41000, 0x00000000,
+/**/ 0x3FF489A3, 0x76D6C491,
+/**/ 0x3FE53718, 0x28D40829,
+/**/ 0x3FF098EA, 0x98450D83,
+/**/ 0x3FFB41C7, 0x55526E3B,
+/**/ 0x4009DCBD, 0x719F540E,
+/**/ 0x401A0685, 0x805D08D1,
+/**/ 0x402B76FA, 0xA5142633,
+/**/ 0x3C2AD9A7, 0xF1FF56FC,
+/**/ 0x3FE5AF31, 0xCBA27244,
+/**/ 0x3FF48000, 0x00000000,
+/**/ 0x3F6346ED, 0xAD892100,
+/**/ 0x3FE43000, 0x00000000,
+/**/ 0x3FF49F0C, 0xC7CB94CC,
+/**/ 0x3FE59BF8, 0xD492AA1E,
+/**/ 0x3FF107FF, 0x34D2CA82,
+/**/ 0x3FFC4A9E, 0xC3DF9E51,
+/**/ 0x400B1E41, 0x45F5874E,
+/**/ 0x401B947A, 0xDEB92648,
+/**/ 0x402D6979, 0xD903D532,
+/**/ 0x3CA43231, 0x04C67F5E,
+/**/ 0x3FE5D85A, 0x6B1109A4,
+/**/ 0x3FF48000, 0x00000000,
+/**/ 0x3F7F0CC7, 0xCB94CC1A,
+/**/ 0x3FE45000, 0x00000000,
+/**/ 0x3FF4B4DC, 0x4ADA0BF0,
+/**/ 0x3FE60380, 0x990F861F,
+/**/ 0x3FF17B50, 0xCBEC7542,
+/**/ 0x3FFD6064, 0xC93CFE8F,
+/**/ 0x400C7314, 0x56F36FE3,
+/**/ 0x401D3ECF, 0x696E5374,
+/**/ 0x402F8531, 0x1778AF1D,
+/**/ 0x3C7A53BF, 0x31EBDA84,
+/**/ 0x3FE601AE, 0x42E27660,
+/**/ 0x3FF4C000, 0x00000000,
+/**/ 0xBF66476A, 0x4BE81F81,
+/**/ 0x3FE47000, 0x00000000,
+/**/ 0x3FF4CB14, 0xB4065600,
+/**/ 0x3FE66DC9, 0x826ADA4F,
+/**/ 0x3FF1F314, 0xA3298D4D,
+/**/ 0x3FFE83E1, 0x52191CB4,
+/**/ 0x400DDC99, 0x05CA69AF,
+/**/ 0x401F07DF, 0x1079C46A,
+/**/ 0x4030E703, 0xF9440EB0,
+/**/ 0x3CA495E1, 0x5817D0DD,
+/**/ 0x3FE62B2E, 0x222A98A0,
+/**/ 0x3FF4C000, 0x00000000,
+/**/ 0x3F662968, 0x0CAC00D4,
+/**/ 0x3FE49000, 0x00000000,
+/**/ 0x3FF4E1B8, 0xD203BDC9,
+/**/ 0x3FE6DAEE, 0xE5FE0976,
+/**/ 0x3FF26F83, 0x3C44F71E,
+/**/ 0x3FFFB5EA, 0xB4D92F91,
+/**/ 0x400F5C4F, 0x55A779C8,
+/**/ 0x4020791F, 0xA66A7536,
+/**/ 0x40322428, 0x7DCE5D75,
+/**/ 0x3CADE7E8, 0x964F770B,
+/**/ 0x3FE654DA, 0xDD7FD12C,
+/**/ 0x3FF50000, 0x00000000,
+/**/ 0xBF7E472D, 0xFC42374B,
+/**/ 0x3FE4B000, 0x00000000,
+/**/ 0x3FF4F8CB, 0x8F87D541,
+/**/ 0x3FE74B0D, 0x767620C4,
+/**/ 0x3FF2F0D8, 0x9126F083,
+/**/ 0x40007BB3, 0x73F08794,
+/**/ 0x401079EB, 0xE1419117,
+/**/ 0x40218062, 0xA917F81E,
+/**/ 0x40337C6B, 0x48444DEE,
+/**/ 0x3C907A41, 0xF4061E08,
+/**/ 0x3FE67EB5, 0x4F31AF70,
+/**/ 0x3FF50000, 0x00000000,
+/**/ 0xBF5CD1C1, 0xE0AAFA85,
+/**/ 0x3FE4D000, 0x00000000,
+/**/ 0x3FF5104F, 0xF4B2718C,
+/**/ 0x3FE7BE43, 0x59659939,
+/**/ 0x3FF37754, 0x5502EAE6,
+/**/ 0x400124A6, 0x6AE0AC51,
+/**/ 0x4011527B, 0x33524D17,
+/**/ 0x40229B46, 0x7FBF7A2D,
+/**/ 0x4034F274, 0xAD716768,
+/**/ 0xBC9C610F, 0x7C204EA8,
+/**/ 0x3FE6A8BE, 0x57825A6C,
+/**/ 0x3FF50000, 0x00000000,
+/**/ 0x3F704FF4, 0xB2718C01,
+/**/ 0x3FE4F000, 0x00000000,
+/**/ 0x3FF52849, 0x288C017D,
+/**/ 0x3FE834B0, 0x3E6D3F7F,
+/**/ 0x3FF4033A, 0x3B0747CB,
+/**/ 0x4001D652, 0xE946B196,
+/**/ 0x401238CB, 0x3C2F8CB4,
+/**/ 0x4023CB80, 0x53E520C1,
+/**/ 0x40368938, 0x607BC0F6,
+/**/ 0xBC84274C, 0xCC053597,
+/**/ 0x3FE6D2F6, 0xDCE2DFB8,
+/**/ 0x3FF54000, 0x00000000,
+/**/ 0xBF77B6D7, 0x73FE8364,
+/**/ 0x3FE51000, 0x00000000,
+/**/ 0x3FF540BA, 0x729BE713,
+/**/ 0x3FE8AE75, 0x781F49A2,
+/**/ 0x3FF494D2, 0x432AC103,
+/**/ 0x40029147, 0x9B0015B6,
+/**/ 0x40132DE7, 0x156B74E9,
+/**/ 0x402512F0, 0xE8362EC8,
+/**/ 0x403843FE, 0xC8D2E0F8,
+/**/ 0xBC8F55DB, 0xBB3ACC53,
+/**/ 0x3FE6FD5F, 0xCC3296F0,
+/**/ 0x3FF54000, 0x00000000,
+/**/ 0x3F274E53, 0x7CE2565E,
+/**/ 0x3FE53000, 0x00000000,
+/**/ 0x3FF559A7, 0x3C98A101,
+/**/ 0x3FE92BB6, 0x16C3163D,
+/**/ 0x3FF52C69, 0x0DB2C44D,
+/**/ 0x4003561E, 0x0F4546B8,
+/**/ 0x401432F1, 0x7F099A82,
+/**/ 0x402673A9, 0x831E227A,
+/**/ 0x403A266F, 0xA02BBCD5,
+/**/ 0x3CA279A8, 0xAEA9CB9D,
+/**/ 0x3FE727FA, 0x1901CB44,
+/**/ 0x3FF54000, 0x00000000,
+/**/ 0x3F79A73C, 0x98A10084,
+/**/ 0x3FE55000, 0x00000000,
+/**/ 0x3FF57313, 0x1433B9BD,
+/**/ 0x3FE9AC97, 0x0523E7B2,
+/**/ 0x3FF5CA50, 0x361F7393,
+/**/ 0x4004257B, 0xB0F40825,
+/**/ 0x40154927, 0x46286025,
+/**/ 0x4027EFF1, 0x781495B4,
+/**/ 0x403C349E, 0x0A1139F1,
+/**/ 0xBC5D2C66, 0x8B6015DA,
+/**/ 0x3FE752C6, 0xBDD7E0E0,
+/**/ 0x3FF58000, 0x00000000,
+/**/ 0xBF69D9D7, 0x988C865F,
+/**/ 0x3FE57000, 0x00000000,
+/**/ 0x3FF58D01, 0xAD039E07,
+/**/ 0x3FEA313F, 0x279933CD,
+/**/ 0x3FF66EDE, 0xB63D93A6,
+/**/ 0x40050012, 0xD836441A,
+/**/ 0x401671E1, 0xF23D152C,
+/**/ 0x40298A4C, 0x65D3A1DD,
+/**/ 0x403E7316, 0x5EBDBF39,
+/**/ 0xBCAE5B6C, 0x7AAA4996,
+/**/ 0x3FE77DC6, 0xBC7D2FA0,
+/**/ 0x3FF58000, 0x00000000,
+/**/ 0x3F6A035A, 0x073C0E86,
+/**/ 0x3FE59000, 0x00000000,
+/**/ 0x3FF5A776, 0xE28DADB6,
+/**/ 0x3FEAB9D7, 0x7D7BE2B5,
+/**/ 0x3FF71A71, 0x5234C8A9,
+/**/ 0x4005E6A3, 0xF873554C,
+/**/ 0x4017AE9A, 0xC1F33F9B,
+/**/ 0x402B4581, 0x4310046E,
+/**/ 0x40407376, 0xF64B03E7,
+/**/ 0xBCA3F39B, 0xB3AB0542,
+/**/ 0x3FE7A8FB, 0x1E48D158,
+/**/ 0x3FF5C000, 0x00000000,
+/**/ 0xBF78891D, 0x725249CA,
+/**/ 0x3FE5B000, 0x00000000,
+/**/ 0x3FF5C276, 0xBA730F9B,
+/**/ 0x3FEB468B, 0x454127C3,
+/**/ 0x3FF7CD6B, 0x0E816ADB,
+/**/ 0x4006D9FE, 0xEDDAC837,
+/**/ 0x401900EE, 0x0209E3B7,
+/**/ 0x402D24A2, 0x57489C7E,
+/**/ 0x4041CAEA, 0x7F810E14,
+/**/ 0xBC84F20E, 0x24F9675B,
+/**/ 0x3FE7D464, 0xF472A690,
+/**/ 0x3FF5C000, 0x00000000,
+/**/ 0x3F43B5D3, 0x987CD623,
+/**/ 0x3FE5D000, 0x00000000,
+/**/ 0x3FF5DE05, 0x66C30CDC,
+/**/ 0x3FEBD788, 0x23798D1A,
+/**/ 0x3FF88835, 0xB0E567D8,
+/**/ 0x4007DB04, 0x6E46660A,
+/**/ 0x401A6A9E, 0xCA07CAA5,
+/**/ 0x402F2B16, 0x41ECEF64,
+/**/ 0x40434315, 0xC36F367B,
+/**/ 0xBCA08CA1, 0x542594A6,
+/**/ 0x3FE80005, 0x5869D9E8,
+/**/ 0x3FF5C000, 0x00000000,
+/**/ 0x3F7E0566, 0xC30CDBD9,
+/**/ 0x3FE5F000, 0x00000000,
+/**/ 0x3FF5FA27, 0x4875FA03,
+/**/ 0x3FEC6CFE, 0x4CF96D63,
+/**/ 0x3FF94B42, 0x4D7B8313,
+/**/ 0x4008EAA7, 0xA1B04592,
+/**/ 0x401BED9B, 0x2C5A9D87,
+/**/ 0x4030AE51, 0x1BC92F68,
+/**/ 0x4044DF8C, 0x685FBD64,
+/**/ 0xBCAC07A8, 0x30FE6378,
+/**/ 0x3FE82BDD, 0x6C30303C,
+/**/ 0x3FF60000, 0x00000000,
+/**/ 0xBF5762DE, 0x2817F40C,
+/**/ 0x3FE61000, 0x00000000,
+/**/ 0x3FF616E0, 0xF213FCD6,
+/**/ 0x3FED0720, 0xB47784FF,
+/**/ 0x3FFA1709, 0xE13C6707,
+/**/ 0x400A09EF, 0xE70B2E72,
+/**/ 0x401D8C00, 0xE976AAD9,
+/**/ 0x4031DEBA, 0xD1AE1EA8,
+/**/ 0x4046A453, 0x6424341F,
+/**/ 0x3CA13E53, 0xA65D40B1,
+/**/ 0x3FE857EE, 0x5ABA79E8,
+/**/ 0x3FF60000, 0x00000000,
+/**/ 0x3F76E0F2, 0x13FCD614,
+/**/ 0x3FE63000, 0x00000000,
+/**/ 0x3FF63437, 0x2A8B4ED8,
+/**/ 0x3FEDA625, 0x3BF69915,
+/**/ 0x3FFAEC0D, 0xFB6DF86F,
+/**/ 0x400B39FA, 0xCAF2D64B,
+/**/ 0x401F4822, 0xB7E2DC06,
+/**/ 0x4033291B, 0xB12537E3,
+/**/ 0x404895F0, 0xAF3EF0D1,
+/**/ 0x3CAEA588, 0x71E7ED76,
+/**/ 0x3FE88439, 0x5856807C,
+/**/ 0x3FF64000, 0x00000000,
+/**/ 0xBF6791AA, 0xE9624F1C,
+/**/ 0x3FE65000, 0x00000000,
+/**/ 0x3FF6522E, 0xF039F5E3,
+/**/ 0x3FEE4A44, 0xEA588E54,
+/**/ 0x3FFBCAD9, 0x77A3F8A4,
+/**/ 0x400C7BFE, 0x3669F2F2,
+/**/ 0x40209247, 0x1AEA54A4,
+/**/ 0x4034900A, 0x6B866959,
+/**/ 0x404AB97D, 0x620634CF,
+/**/ 0x3C948649, 0xDA91B0FD,
+/**/ 0x3FE8B0BF, 0xA316D3A0,
+/**/ 0x3FF64000, 0x00000000,
+/**/ 0x3F722EF0, 0x39F5E2AD,
+/**/ 0x3FE67000, 0x00000000,
+/**/ 0x3FF670CD, 0x7C2F4FC3,
+/**/ 0x3FEEF3BC, 0x2583CF60,
+/**/ 0x3FFCB401, 0x4A2E1684,
+/**/ 0x400DD14A, 0xDCB9F8FB,
+/**/ 0x40219209, 0x4E164373,
+/**/ 0x40361669, 0x8FC171BC,
+/**/ 0x404D14BA, 0xA46B7BE1,
+/**/ 0xBCABAC31, 0xBBDFE65A,
+/**/ 0x3FE8DD82, 0x8344E08C,
+/**/ 0x3FF68000, 0x00000000,
+/**/ 0xBF6E6507, 0xA1607A77,
+/**/ 0x3FE69000, 0x00000000,
+/**/ 0x3FF69018, 0x45AA3C85,
+/**/ 0x3FEFA2CA, 0xF18FBD18,
+/**/ 0x3FFDA825, 0x610C140E,
+/**/ 0x400F3B4E, 0xF08895E1,
+/**/ 0x4022A4E4, 0x272CD203,
+/**/ 0x4037BF71, 0x60C4A0EE,
+/**/ 0x404FAE29, 0xEC79351D,
+/**/ 0x3C6BF5BB, 0x3E22FB0A,
+/**/ 0x3FE90A83, 0x4BD9C858,
+/**/ 0x3FF68000, 0x00000000,
+/**/ 0x3F701845, 0xAA3C8533,
+/**/ 0x3FE6B000, 0x00000000,
+/**/ 0x3FF6B015, 0x05D92E4E,
+/**/ 0x3FF02BDA, 0x9ABD20D8,
+/**/ 0x3FFEA7F1, 0x9BC5CC13,
+/**/ 0x40105DCC, 0x94AFB2BB,
+/**/ 0x4023CC8C, 0xB382B54A,
+/**/ 0x40398EBB, 0x19C28EAE,
+/**/ 0x40514694, 0x8F7609B5,
+/**/ 0x3C9CD223, 0xF66137E5,
+/**/ 0x3FE937C3, 0x5AFE73AC,
+/**/ 0x3FF6C000, 0x00000000,
+/**/ 0xBF6FD5F4, 0x4DA36334,
+/**/ 0x3FE6D000, 0x00000000,
+/**/ 0x3FF6D0C9, 0xBBE1EF2B,
+/**/ 0x3FF08961, 0x82FBDD29,
+/**/ 0x3FFFB41E, 0xDCD403EC,
+/**/ 0x401129EE, 0x121D0023,
+/**/ 0x40250AE5, 0xB34159B2,
+/**/ 0x403B884D, 0xDB5CEAC4,
+/**/ 0x4052DD09, 0xA0B334B0,
+/**/ 0xBC96BF1D, 0xD8F14BF9,
+/**/ 0x3FE96544, 0x1A936D24,
+/**/ 0x3FF6C000, 0x00000000,
+/**/ 0x3F70C9BB, 0xE1EF2AEE,
+/**/ 0x3FE6F000, 0x00000000,
+/**/ 0x3FF6F23C, 0xB13786CF,
+/**/ 0x3FF0EA20, 0x7B7FC134,
+/**/ 0x400066BA, 0x1BD0D518,
+/**/ 0x401202F9, 0x159EC945,
+/**/ 0x40266205, 0x16FF868A,
+/**/ 0x403DB0AD, 0x87398014,
+/**/ 0x40549F33, 0x47D58711,
+/**/ 0x3C8D858F, 0x54B11A28,
+/**/ 0x3FE99307, 0x00C1184C,
+/**/ 0x3FF70000, 0x00000000,
+/**/ 0xBF6B869D, 0x90F2626A,
+/**/ 0x3FE71000, 0x00000000,
+/**/ 0x3FF71474, 0x7E455603,
+/**/ 0x3FF14E40, 0x3A65655F,
+/**/ 0x4000FA64, 0x1F4AA7A1,
+/**/ 0x4012E9F0, 0xB946C70A,
+/**/ 0x4027D43A, 0x3CC53936,
+/**/ 0x40400675, 0xEE087279,
+/**/ 0x40569278, 0x77313CEF,
+/**/ 0xBCAB1BA1, 0x772D6E62,
+/**/ 0x3FE9C10D, 0x9090E874,
+/**/ 0x3FF70000, 0x00000000,
+/**/ 0x3F74747E, 0x455602D3,
+/**/ 0x3FE73000, 0x00000000,
+/**/ 0x3FF73778, 0x0F773DEC,
+/**/ 0x3FF1B5EC, 0x1288B243,
+/**/ 0x40019581, 0x3A853FA5,
+/**/ 0x4013DFF0, 0x6D2743E5,
+/**/ 0x40296415, 0x09B4B924,
+/**/ 0x4041515E, 0x19A59D1F,
+/**/ 0x4058BD01, 0xF3E53877,
+/**/ 0x3C962269, 0xFC348BAE,
+/**/ 0x3FE9EF59, 0x5A90493C,
+/**/ 0x3FF74000, 0x00000000,
+/**/ 0xBF610FE1, 0x11842743,
+/**/ 0x3FE75000, 0x00000000,
+/**/ 0x3FF75B4E, 0xAAA78140,
+/**/ 0x3FF22152, 0x28B49576,
+/**/ 0x4002388E, 0x74D66746,
+/**/ 0x4014E62E, 0xA43083A8,
+/**/ 0x402B146E, 0x02885ED7,
+/**/ 0x4042BC45, 0x29A3BC2C,
+/**/ 0x405B25D8, 0xCDAFE7E5,
+/**/ 0x3CA8862D, 0xF03F8A74,
+/**/ 0x3FEA1DEB, 0xFD7DFBD8,
+/**/ 0x3FF74000, 0x00000000,
+/**/ 0x3F7B4EAA, 0xA7813FBA,
+/**/ 0x3FE77000, 0x00000000,
+/**/ 0x3FF77FFF, 0xF4FC0008,
+/**/ 0x3FF290A3, 0xADE499E4,
+/**/ 0x4002E412, 0xFF22FE11,
+/**/ 0x4015FDFF, 0xD7A17943,
+/**/ 0x402CE86F, 0x8AF79AEF,
+/**/ 0x40444ACA, 0x6F8EDF86,
+/**/ 0x405DD50A, 0x29CF9F92,
+/**/ 0x3CA49DB0, 0xC5865233,
+/**/ 0x3FEA4CC7, 0x2702BD90,
+/**/ 0x3FF78000, 0x00000000,
+/**/ 0xBE6607FF, 0xF08268E1,
+/**/ 0x3FE79000, 0x00000000,
+/**/ 0x3FF7A593, 0xF93D7FBC,
+/**/ 0x3FF30415, 0x1F293A81,
+/**/ 0x400398A1, 0x31649EA4,
+/**/ 0x401728D9, 0xED75DA1E,
+/**/ 0x402EE3A0, 0x7B1736CA,
+/**/ 0x40460106, 0x036EC9D4,
+/**/ 0x406069E8, 0xB3E5A09F,
+/**/ 0xBCA79BBD, 0x4E8EB882,
+/**/ 0x3FEA7BEC, 0x94762100,
+/**/ 0x3FF7C000, 0x00000000,
+/**/ 0xBF7A6C06, 0xC280445C,
+/**/ 0x3FE7B000, 0x00000000,
+/**/ 0x3FF7CC13, 0x2EB4E536,
+/**/ 0x3FF37BDE, 0x8BD25D7D,
+/**/ 0x400456D7, 0xA51DF797,
+/**/ 0x40186858, 0x103AF33E,
+/**/ 0x403084F8, 0x21121C2E,
+/**/ 0x4047E39A, 0x9D7C6DE3,
+/**/ 0x40621664, 0xEF4C9A12,
+/**/ 0x3C804D2D, 0x39DB72FF,
+/**/ 0x3FEAAB5E, 0x13B099B0,
+/**/ 0x3FF7C000, 0x00000000,
+/**/ 0x3F68265D, 0x69CA6C2F,
+/**/ 0x3FE7D000, 0x00000000,
+/**/ 0x3FF7F386, 0x809BA1CD,
+/**/ 0x3FF3F83B, 0xE298B2EB,
+/**/ 0x40051F62, 0x708A6ABE,
+/**/ 0x4019BE3F, 0x090F77AB,
+/**/ 0x4031AFE2, 0x6C13BF38,
+/**/ 0x4049F7CA, 0x65FF02A8,
+/**/ 0x4063F614, 0xDA840FE0,
+/**/ 0xBCA7BDE9, 0xAB5D1A54,
+/**/ 0x3FEADB1D, 0x83EBD320,
+/**/ 0x3FF80000, 0x00000000,
+/**/ 0xBF68F2FE, 0xC8BC6562,
+/**/ 0x3FE7F000, 0x00000000,
+/**/ 0x3FF81BF7, 0x562E1E24,
+/**/ 0x3FF4796D, 0x469724DB,
+/**/ 0x4005F2FC, 0x86E67917,
+/**/ 0x401B2C82, 0x2F5AE582,
+/**/ 0x4032F505, 0x65EE1919,
+/**/ 0x404C438F, 0x4744D220,
+/**/ 0x40661003, 0xD66309FD,
+/**/ 0x3C8470C8, 0xFC828894,
+/**/ 0x3FEB0B2C, 0xD6B287DC,
+/**/ 0x3FF80000, 0x00000000,
+/**/ 0x3F7BF756, 0x2E1E23E5,
+/**/ 0x3FE81000, 0x00000000,
+/**/ 0x3FF8456F, 0x9B70AB1D,
+/**/ 0x3FF4FFB7, 0x6D01A674,
+/**/ 0x4006D271, 0x42D7B667,
+/**/ 0x401CB549, 0x05DD4055,
+/**/ 0x40345723, 0xE490CA9B,
+/**/ 0x404ECD17, 0x47C5589B,
+/**/ 0x40686C46, 0x3D6DB036,
+/**/ 0x4084044D, 0xECF23C2E,
+/**/ 0xBC7F0990, 0x0D173A5F,
+/**/ 0x3FEB3B8E, 0x10E12D3C,
+/**/ 0x3FF84000, 0x00000000,
+/**/ 0x3F55BE6D, 0xC2AC733C,
+/**/ 0x3FE83000, 0x00000000,
+/**/ 0x3FF86FF9, 0xCAB97B9D,
+/**/ 0x3FF58B64, 0x04A71B42,
+/**/ 0x4007BE9E, 0x20C0FB6E,
+/**/ 0x401E5AF5, 0x9B426297,
+/**/ 0x4035D958, 0x013C40EE,
+/**/ 0x4050CEA9, 0x2215E48C,
+/**/ 0x406B146B, 0xB8C0669A,
+/**/ 0x40868C96, 0xFB8EB0FE,
+/**/ 0x3CA55848, 0x1FCCBAD4,
+/**/ 0x3FEB6C43, 0x4BB8EA98,
+/**/ 0x3FF88000, 0x00000000,
+/**/ 0xBF700635, 0x46846319,
+/**/ 0x3FE85000, 0x00000000,
+/**/ 0x3FF89BA0, 0xF71469BF,
+/**/ 0x3FF61CC2, 0x28717EFA,
+/**/ 0x4008B874, 0xAFB7BAF7,
+/**/ 0x40201015, 0xEC7286DB,
+/**/ 0x40377F1F, 0x8329A469,
+/**/ 0x40525E49, 0x2927F0DD,
+/**/ 0x406E135C, 0x5AE80CD9,
+/**/ 0x40897364, 0x40DF64FD,
+/**/ 0x3C89F53B, 0x1ED91B03,
+/**/ 0x3FEB9D4E, 0xB6067ABC,
+/**/ 0x3FF88000, 0x00000000,
+/**/ 0x3F7BA0F7, 0x1469BF33,
+/**/ 0x3FE87000, 0x00000000,
+/**/ 0x3FF8C870, 0xD797DABF,
+/**/ 0x3FF6B426, 0xDE42D55F,
+/**/ 0x4009C0FC, 0xC0E06552,
+/**/ 0x402103EC, 0xEB059907,
+/**/ 0x40394C6A, 0x49A75AA7,
+/**/ 0x40541A81, 0xB2A496D0,
+/**/ 0x4070BAEE, 0x209CB693,
+/**/ 0x408CC860, 0x285808C5,
+/**/ 0xBCAE6D8C, 0x9B0DC6F3,
+/**/ 0x3FEBCEB2, 0x955EC1C4,
+/**/ 0x3FF8C000, 0x00000000,
+/**/ 0x3F60E1AF, 0x2FB57EE7,
+/**/ 0x3FE89000, 0x00000000,
+/**/ 0x3FF8F675, 0xD3C502F4,
+/**/ 0x3FF751ED, 0xA3BFB2E4,
+/**/ 0x400AD956, 0xDE3987BC,
+/**/ 0x40220AA0, 0xB30AAD0A,
+/**/ 0x403B45AB, 0x16220014,
+/**/ 0x40560929, 0xEC84429C,
+/**/ 0x4072A569, 0x0D747939,
+/**/ 0x40904F10, 0x5407F41E,
+/**/ 0xBC675CEB, 0xFC269962,
+/**/ 0x3FEC0071, 0x4773138C,
+/**/ 0x3FF90000, 0x00000000,
+/**/ 0xBF631458, 0x75FA1750,
+/**/ 0x3FE8B000, 0x00000000,
+/**/ 0x3FF925BD, 0x111125DF,
+/**/ 0x3FF7F679, 0x0AD2B4C2,
+/**/ 0x400C02BF, 0x1359A3C8,
+/**/ 0x40232601, 0x88857C21,
+/**/ 0x403D6FEB, 0x2515D90E,
+/**/ 0x405830FA, 0xD421145E,
+/**/ 0x4074D1D6, 0xFD789544,
+/**/ 0x40928561, 0x4B30EBF1,
+/**/ 0x3CA13E7B, 0x7876F9D2,
+/**/ 0x3FEC328D, 0x437F5E74,
+/**/ 0x3FF94000, 0x00000000,
+/**/ 0xBF7A42EE, 0xEEDA20A4,
+/**/ 0x3FE8D000, 0x00000000,
+/**/ 0x3FF95654, 0x81B9477B,
+/**/ 0x3FF8A233, 0x67F87779,
+/**/ 0x400D3E90, 0x14665EA0,
+/**/ 0x40245815, 0x5A415747,
+/**/ 0x403FD0E1, 0x1D7511C0,
+/**/ 0x405A99B6, 0x01EC30FB,
+/**/ 0x40774A72, 0xDD7EE7A1,
+/**/ 0x40951454, 0x5C2F1724,
+/**/ 0x3C8185B3, 0x774A5205,
+/**/ 0x3FEC6509, 0x1BD4AD0C,
+/**/ 0x3FF94000, 0x00000000,
+/**/ 0x3F765481, 0xB9477AC0,
+/**/ 0x3FE8F000, 0x00000000,
+/**/ 0x3FF9884A, 0xF50630B5,
+/**/ 0x3FF9558F, 0x94B35A8D,
+/**/ 0x400E8E46, 0xD1A32B1D,
+/**/ 0x4025A31F, 0x0AEC68DB,
+/**/ 0x40413785, 0xFD21A759,
+/**/ 0x405D4C53, 0xF56DFCA6,
+/**/ 0x407A1B45, 0xF89C0F5F,
+/**/ 0x40980BB3, 0xC92C8CF3,
+/**/ 0xBC8696E8, 0xFEB6A05E,
+/**/ 0x3FEC97E7, 0x7F82B8CC,
+/**/ 0x3FF98000, 0x00000000,
+/**/ 0x3F6095EA, 0x0C6169C6,
+/**/ 0x3FE91000, 0x00000000,
+/**/ 0x3FF9BBB0, 0x292BC29F,
+/**/ 0x3FFA1109, 0xC8E3D76B,
+/**/ 0x400FF386, 0x8873C480,
+/**/ 0x402709A6, 0xDE619C77,
+/**/ 0x4042A8E9, 0x5A9417B9,
+/**/ 0x4060299D, 0xBFE20B57,
+/**/ 0x407D5283, 0xE1225431,
+/**/ 0x409B7E74, 0xC225406C,
+/**/ 0xBC879431, 0x74F396DB,
+/**/ 0x3FECCB2B, 0x3C239888,
+/**/ 0x3FF9C000, 0x00000000,
+/**/ 0xBF513F5B, 0x50F5839F,
+/**/ 0x3FE93000, 0x00000000,
+/**/ 0x3FF9F094, 0xDEF4783D,
+/**/ 0x3FFAD528, 0x8E300736,
+/**/ 0x4010B80E, 0xB2D4D4EE,
+/**/ 0x40288E84, 0x3F3D0057,
+/**/ 0x404440D4, 0xD20263C0,
+/**/ 0x4061DD42, 0x26E14927,
+/**/ 0x4080807D, 0x5EF13D09,
+/**/ 0x409F836C, 0xFE9E94BE,
+/**/ 0xBC813C84, 0xE5FD9D2D,
+/**/ 0x3FECFED7, 0x3FCCF104,
+/**/ 0x3FFA0000, 0x00000000,
+/**/ 0xBF6ED642, 0x170F854B,
+/**/ 0x3FE95000, 0x00000000,
+/**/ 0x3FFA270A, 0xEF70C9F9,
+/**/ 0x3FFBA27D, 0xD12662D9,
+/**/ 0x40118304, 0xE8433B59,
+/**/ 0x402A34E9, 0x1B4DD8D9,
+/**/ 0x4046041F, 0x58AA354C,
+/**/ 0x4063C823, 0x87EB035B,
+/**/ 0x40829D4E, 0x7F89A6B6,
+/**/ 0x40A21B1A, 0xB4BED54D,
+/**/ 0x3C855D66, 0xFD8283D4,
+/**/ 0x3FED32EE, 0x9B2A7684,
+/**/ 0x3FFA4000, 0x00000000,
+/**/ 0xBF78F510, 0x8F3606B9,
+/**/ 0x3FE97000, 0x00000000,
+/**/ 0x3FFA5F25, 0x63EA127F,
+/**/ 0x3FFC79A8, 0x1460C218,
+/**/ 0x40125BC0, 0x3D14975C,
+/**/ 0x402C006F, 0x2249DB66,
+/**/ 0x4047F856, 0xED0AEFCD,
+/**/ 0x4065F27F, 0x2E2028D0,
+/**/ 0x40850B95, 0x6CE59595,
+/**/ 0x40A4DC23, 0x18C497E2,
+/**/ 0x3C8BDFAE, 0x76BA54CA,
+/**/ 0x3FED6774, 0x83C60554,
+/**/ 0x3FFA4000, 0x00000000,
+/**/ 0x3F7F2563, 0xEA127F53,
+/**/ 0x3FE99000, 0x00000000,
+/**/ 0x3FFA98F8, 0x9061CEFE,
+/**/ 0x3FFD5B53, 0xCAA1F466,
+/**/ 0x40134379, 0xA92630E8,
+/**/ 0x402DF527, 0x41E37357,
+/**/ 0x404A23DF, 0xD7DE2305,
+/**/ 0x406865FE, 0x1911C50F,
+/**/ 0x4087D981, 0xD5CE543D,
+/**/ 0x40A8192E, 0x2134A322,
+/**/ 0xBC915CF9, 0x4FE6DAC8,
+/**/ 0x3FED9C6C, 0x56821F74,
+/**/ 0x3FFA8000, 0x00000000,
+/**/ 0x3F78F890, 0x61CEFDBB,
+/**/ 0x3FE9B000, 0x00000000,
+/**/ 0x3FFAD49A, 0x30F0DACC,
+/**/ 0x3FFE483C, 0xDDBFEE70,
+/**/ 0x40143B8C, 0xC4418459,
+/**/ 0x40300BD5, 0xE6E7E816,
+/**/ 0x404C8E1A, 0x02EE200E,
+/**/ 0x406B2DFC, 0x83038A03,
+/**/ 0x408B1814, 0xD987E3D9,
+/**/ 0x40ABEB1E, 0x8827CEFA,
+/**/ 0x3CA8829A, 0xE22AFCE0,
+/**/ 0x3FEDD1D9, 0x9A4C39D0,
+/**/ 0x3FFAC000, 0x00000000,
+/**/ 0x3F749A30, 0xF0DACB86,
+/**/ 0x3FE9D000, 0x00000000,
+/**/ 0x3FFB1221, 0x8A66E40D,
+/**/ 0x3FFF4130, 0x692DC10A,
+/**/ 0x4015457C, 0x64621A80,
+/**/ 0x4031369A, 0xED2A1AB4,
+/**/ 0x404F3F8D, 0xBC003A70,
+/**/ 0x406E57E1, 0x462E99D6,
+/**/ 0x408EDBC2, 0xC53F5717,
+/**/ 0x40B0383D, 0x0A71E453,
+/**/ 0x3C90AF9F, 0xBEDD86A9,
+/**/ 0x3FEE07C0, 0x030CF708,
+/**/ 0x3FFB0000, 0x00000000,
+/**/ 0x3F72218A, 0x66E40CBE,
+/**/ 0x3FE9F000, 0x00000000,
+/**/ 0x3FFB51A7, 0x8E9927E5,
+/**/ 0x40002387, 0x581637B3,
+/**/ 0x401662F7, 0xF5B2C17E,
+/**/ 0x40327DDB, 0x36EAC07E,
+/**/ 0x40512110, 0xC70D9C43,
+/**/ 0x4070F9C4, 0x88C52943,
+/**/ 0x40919E9E, 0xB1AB4848,
+/**/ 0x40B2E76B, 0xB1EC7695,
+/**/ 0x3CAA2400, 0x5E9F6FD9,
+/**/ 0x3FEE3E23, 0x74DD3C64,
+/**/ 0x3FFB4000, 0x00000000,
+/**/ 0x3F71A78E, 0x9927E571,
+/**/ 0x3FEA1000, 0x00000000,
+/**/ 0x3FFB9347, 0x04E0F95F,
+/**/ 0x4000AD66, 0xAC8DC27B,
+/**/ 0x401795E1, 0xAE05A580,
+/**/ 0x4033E4FA, 0x299AA0A0,
+/**/ 0x4052D0AD, 0xA33AB75C,
+/**/ 0x407309E5, 0x39D64C89,
+/**/ 0x40942D39, 0x154C34C4,
+/**/ 0x40B61A59, 0x59D15B1D,
+/**/ 0xBCAFC899, 0x114BE565,
+/**/ 0x3FEE7508, 0x0787FD30,
+/**/ 0x3FFB8000, 0x00000000,
+/**/ 0x3F734704, 0xE0F95E8B,
+/**/ 0x3FEA3000, 0x00000000,
+/**/ 0x3FFBD71C, 0xB75F37A1,
+/**/ 0x40013EBC, 0xFC9006E1,
+/**/ 0x4018E055, 0xC48D2C09,
+/**/ 0x40356FD7, 0xC2C8C9CD,
+/**/ 0x4054B557, 0x6198B971,
+/**/ 0x4075678C, 0x9680F9AF,
+/**/ 0x40972BE5, 0x8AF946DD,
+/**/ 0x40B9EDE4, 0xE1B531F9,
+/**/ 0xBC447F69, 0xE4527544,
+/**/ 0x3FEEAC72, 0x0A61AD1C,
+/**/ 0x3FFBC000, 0x00000000,
+/**/ 0x3F771CB7, 0x5F37A0DF,
+/**/ 0x3FEA5000, 0x00000000,
+/**/ 0x3FFC1D47, 0xA5B24F80,
+/**/ 0x4001D81E, 0x7EB9F789,
+/**/ 0x401A44B2, 0xDF42B6B7,
+/**/ 0x403722E5, 0xB4766752,
+/**/ 0x4056D6EE, 0xECFADFF0,
+/**/ 0x40782028, 0x8B1EB8D5,
+/**/ 0x409AB0E2, 0xCA840144,
+/**/ 0x40BE8614, 0xE2126BBF,
+/**/ 0xBC8D9A93, 0x2CC624E2,
+/**/ 0x3FEEE466, 0x087F8D20,
+/**/ 0x3FFC0000, 0x00000000,
+/**/ 0x3F7D47A5, 0xB24F8064,
+/**/ 0x3FEA7000, 0x00000000,
+/**/ 0x3FFC65E9, 0x3DE98207,
+/**/ 0x40027A2E, 0x811F641B,
+/**/ 0x401BC5A3, 0xF223266D,
+/**/ 0x40390340, 0xA6ECBE29,
+/**/ 0x40593EB6, 0xC3D499AF,
+/**/ 0x407B43D9, 0xAD8CC2F1,
+/**/ 0x409ED77C, 0xA519B816,
+/**/ 0x40C2080A, 0x5B3B703B,
+/**/ 0x3C7B187D, 0xE993C3DD,
+/**/ 0x3FEF1CE8, 0xCD5A7CE8,
+/**/ 0x3FFC8000, 0x00000000,
+/**/ 0xBF7A16C2, 0x167DF937,
+/**/ 0x3FEA9000, 0x00000000,
+/**/ 0x3FFCB125, 0x9CA2F05E,
+/**/ 0x400325A1, 0x54FC4C95,
+/**/ 0x401D662B, 0xD9C5FF75,
+/**/ 0x403B16CE, 0x8E93577D,
+/**/ 0x405BF79A, 0xE0E3029E,
+/**/ 0x407EE612, 0x04BCDF91,
+/**/ 0x40A1E0AC, 0x31EFE3F1,
+/**/ 0x40C56267, 0x85DF051C,
+/**/ 0xBCAD6122, 0x2D0BC06E,
+/**/ 0x3FEF55FF, 0x69EAB2F0,
+/**/ 0x3FFCC000, 0x00000000,
+/**/ 0xBF6DB4C6, 0xBA1F43E4,
+/**/ 0x3FEAB000, 0x00000000,
+/**/ 0x3FFCFF23, 0xD56B9F55,
+/**/ 0x4003DB3E, 0x86149A3B,
+/**/ 0x401F29B3, 0x0B8D0DAD,
+/**/ 0x403D6463, 0x40E9D1A7,
+/**/ 0x405F0E89, 0x619D6679,
+/**/ 0x40818F2E, 0x92CF3FBC,
+/**/ 0x40A4CC10, 0x844E51BD,
+/**/ 0x40C9762D, 0xF3A9EB60,
+/**/ 0x3CA20E79, 0xEF4B1E02,
+/**/ 0x3FEF8FAF, 0x3A4BC01C,
+/**/ 0x3FFD0000, 0x00000000,
+/**/ 0xBF2B8552, 0x8C156248,
+/**/ 0x3FEAD000, 0x00000000,
+/**/ 0x3FFD500E, 0x44AAD4F2,
+/**/ 0x40049BE3, 0x6B85DB68,
+/**/ 0x40208A0B, 0xE558F351,
+/**/ 0x403FF3EC, 0xC1BCC632,
+/**/ 0x40614970, 0x2A555E45,
+/**/ 0x408404AE, 0xDD057F33,
+/**/ 0x40A847D9, 0x22610A18,
+/**/ 0x40CE7146, 0x3C7AA2B4,
+/**/ 0xBC9571D0, 0x53CA14EC,
+/**/ 0x3FEFC9FD, 0xEBFAA348,
+/**/ 0x3FFD4000, 0x00000000,
+/**/ 0x3F700E44, 0xAAD4F267,
+/**/ 0x3FEAF000, 0x00000000,
+/**/ 0x3FFDA412, 0xEC9EDC5A,
+/**/ 0x40056886, 0x22B6D908,
+/**/ 0x402194E0, 0xB605B3B4,
+/**/ 0x40416754, 0x9338560C,
+/**/ 0x40634B7B, 0x34B16169,
+/**/ 0x4086E508, 0x3B1BAF9C,
+/**/ 0x40AC7475, 0xFB9DFBF5,
+/**/ 0x40D2473E, 0xF4B4BB01,
+/**/ 0x3CA82B31, 0xE9F06EFC,
+/**/ 0x3FF00278, 0xC2613F02,
+/**/ 0x3FFDC000, 0x00000000,
+/**/ 0xBF7BED13, 0x6123A5D1,
+/**/ 0x3FEB1000, 0x00000000,
+/**/ 0x3FFDFB63, 0xDF3AE0DB,
+/**/ 0x40064239, 0x08AD38CF,
+/**/ 0x4022B7DB, 0xAA166573,
+/**/ 0x4042FFB4, 0x38210D3E,
+/**/ 0x40659862, 0xFB634456,
+/**/ 0x408A45B4, 0xEE8F3E34,
+/**/ 0x40B0BD59, 0xD39A6C6F,
+/**/ 0x40D60CCD, 0x2B4867E8,
+/**/ 0xBCA6097F, 0x1CBB85B3,
+/**/ 0x3FF02048, 0x3537E800,
+/**/ 0x3FFE0000, 0x00000000,
+/**/ 0xBF527083, 0x147C93ED,
+/**/ 0x3FEB3000, 0x00000000,
+/**/ 0x3FFE5637, 0xB70F5F72,
+/**/ 0x40072A2E, 0xCA935102,
+/**/ 0x4023F5DE, 0x43559218,
+/**/ 0x4044C96E, 0xB4E19CA3,
+/**/ 0x40683D62, 0x1272DDA3,
+/**/ 0x408E4135, 0xC6BFAAED,
+/**/ 0x40B3C717, 0x099FB249,
+/**/ 0x40DABA6D, 0xD5294F7D,
+/**/ 0x3CA488B1, 0xC91FFA21,
+/**/ 0x3FF03E70, 0xB5B309E0,
+/**/ 0x3FFE4000, 0x00000000,
+/**/ 0x3F7637B7, 0x0F5F723E,
+/**/ 0x3FEB5000, 0x00000000,
+/**/ 0x3FFEB4CA, 0x21D4B842,
+/**/ 0x400821BF, 0x2BE08FC5,
+/**/ 0x40255238, 0x6A6A3BD0,
+/**/ 0x4046CC00, 0xBAC907E2,
+/**/ 0x406B4A78, 0x94202458,
+/**/ 0x40917C35, 0xFE065CA6,
+/**/ 0x40B77848, 0xE8D5B845,
+/**/ 0x40E04820, 0x0CD72D76,
+/**/ 0x3CA54B6E, 0x9CBE508B,
+/**/ 0x3FF05CF5, 0xE41C2ACE,
+/**/ 0x3FFEC000, 0x00000000,
+/**/ 0xBF666BBC, 0x568F7C18,
+/**/ 0x3FEB7000, 0x00000000,
+/**/ 0x3FFF175C, 0x7FB6EB26,
+/**/ 0x40092A6C, 0xA7BA9C35,
+/**/ 0x4026D0BC, 0x80F5BA9F,
+/**/ 0x40491048, 0x33BD74FB,
+/**/ 0x406ED319, 0x61FCE21F,
+/**/ 0x40944A2E, 0x60DF5AED,
+/**/ 0x40BBFAFC, 0x1AC97175,
+/**/ 0x40E3F145, 0xC3A8BC22,
+/**/ 0xBC994B5D, 0xA70A42D9,
+/**/ 0x3FF07BDB, 0x9F358760,
+/**/ 0x3FFF0000, 0x00000000,
+/**/ 0x3F775C7F, 0xB6EB2582,
+/**/ 0x3FEB9000, 0x00000000,
+/**/ 0x3FFF7E36, 0x9B29492C,
+/**/ 0x400A45EB, 0x1C35AD8A,
+/**/ 0x402875D7, 0xC8373BB1,
+/**/ 0x404BA0D1, 0x885E6AE6,
+/**/ 0x40717784, 0x0831631E,
+/**/ 0x4097A441, 0x7F51DA78,
+/**/ 0x40C0C2B2, 0x6D7642FB,
+/**/ 0x40E89073, 0x594961FB,
+/**/ 0xBCA5DECE, 0x96CDC181,
+/**/ 0x3FF09B26, 0x0A46374E,
+/**/ 0x3FFF8000, 0x00000000,
+/**/ 0xBF3C964D, 0x6B6D3D05,
+/**/ 0x3FEBB000, 0x00000000,
+/**/ 0x3FFFE9A7, 0x7DD9B1CF,
+/**/ 0x400B7627, 0xB9AE77AF,
+/**/ 0x402A46B0, 0x3338306D,
+/**/ 0x404E8A38, 0xA0CAACE9,
+/**/ 0x4073DDBB, 0x864F53A2,
+/**/ 0x409BAAF0, 0xD6C97F8D,
+/**/ 0x40C42EEF, 0xDFAE5A98,
+/**/ 0x40EE701A, 0xE19501DA,
+/**/ 0x3C9CC4F4, 0xC7D3D675,
+/**/ 0x3FF0BAD9, 0x93EC49AE,
+/**/ 0x40000000, 0x00000000,
+/**/ 0xBF765882, 0x264E310D,
+/**/ 0x3FEBD000, 0x00000000,
+/**/ 0x40002D03, 0x34302F3B,
+/**/ 0x400CBD52, 0x7F5AAF0D,
+/**/ 0x402C4949, 0x0C635C0A,
+/**/ 0x4050EDD1, 0xB6BB1732,
+/**/ 0x4076AE3D, 0x9691A9F4,
+/**/ 0x40A043C7, 0x61482FC6,
+/**/ 0x40C87037, 0xF81EB6E0,
+/**/ 0x40F2FA30, 0xE84FE55E,
+/**/ 0xBC9820F1, 0x228FC41D,
+/**/ 0x3FF0DAFA, 0xFDD4AE68,
+/**/ 0x40002000, 0x00000000,
+/**/ 0x3F7A0668, 0x605E76B0,
+/**/ 0x3FEBF000, 0x00000000,
+/**/ 0x400067D9, 0xF9C947A3,
+/**/ 0x400E1DE9, 0xA1722882,
+/**/ 0x402E84B0, 0x41FE0247,
+/**/ 0x4052D3AE, 0xDBD1D676,
+/**/ 0x4079FF78, 0xE088BEF5,
+/**/ 0x40A33780, 0x64D9A484,
+/**/ 0x40CDC32D, 0x1974F9B5,
+/**/ 0x40F7D295, 0xCE268611,
+/**/ 0xBCA5A192, 0xD437D23F,
+/**/ 0x3FF0FB8F, 0x657EFDCA,
+/**/ 0x40006000, 0x00000000,
+/**/ 0x3F6F67E7, 0x251E8CF3,
+/**/ 0x3FEC1000, 0x00000000,
+/**/ 0x4000A58D, 0xB1FFFA6D,
+/**/ 0x400F9AC7, 0x4E7307C3,
+/**/ 0x4030809B, 0x5EA15962,
+/**/ 0x405501D0, 0x5418E1B6,
+/**/ 0x407DED80, 0xB476D79F,
+/**/ 0x40A6D2BF, 0x37F33D5F,
+/**/ 0x40D23C31, 0xA43F6C6F,
+/**/ 0x40FE1E46, 0xDB17BBAA,
+/**/ 0xBCA7EB62, 0x41D8AD56,
+/**/ 0x3FF11C9C, 0x4E3ADE0A,
+/**/ 0x4000A000, 0x00000000,
+/**/ 0x3F6636C7, 0xFFE9B457,
+/**/ 0x3FEC3000, 0x00000000,
+/**/ 0x4000E65A, 0x1D1BDCC6,
+/**/ 0x40109B99, 0x3503CCCE,
+/**/ 0x4031E45B, 0x7580EC24,
+/**/ 0x405785CA, 0x1803E176,
+/**/ 0x40814DDB, 0x8458A77D,
+/**/ 0x40AB41D9, 0x6C115AB7,
+/**/ 0x40D67DF0, 0xD7BCE584,
+/**/ 0x41032EF5, 0xF5487646,
+/**/ 0xBC9C4040, 0xF3631254,
+/**/ 0x3FF13E27, 0xAC964DA8,
+/**/ 0x4000E000, 0x00000000,
+/**/ 0x3F696874, 0x6F731770,
+/**/ 0x3FEC5000, 0x00000000,
+/**/ 0x40012A82, 0x068FBCB4,
+/**/ 0x40117B79, 0x7FE89A5F,
+/**/ 0x40337376, 0xD37F3897,
+/**/ 0x405A704E, 0xDF3B47A2,
+/**/ 0x40841B83, 0xEB114449,
+/**/ 0x40B05F75, 0x8D323120,
+/**/ 0x40DBEFEC, 0x8AE65DDD,
+/**/ 0x4108A2A2, 0xD1814341,
+/**/ 0x3CA3E83D, 0xFB25EC76,
+/**/ 0x3FF16037, 0xF37FFEDA,
+/**/ 0x40012000, 0x00000000,
+/**/ 0x3F75040D, 0x1F796787,
+/**/ 0x3FEC7000, 0x00000000,
+/**/ 0x40017250, 0x5F8F574B,
+/**/ 0x40126F35, 0xB566493D,
+/**/ 0x403534F5, 0x95186E3D,
+/**/ 0x405DD60B, 0x947D5EA5,
+/**/ 0x40877C77, 0x568C5D73,
+/**/ 0x40B3CB66, 0xA26261F0,
+/**/ 0x40E17B06, 0xBF32194D,
+/**/ 0x410FE921, 0x11490E42,
+/**/ 0xBCA34428, 0x5376CB61,
+/**/ 0x3FF182D4, 0x236FE314,
+/**/ 0x40018000, 0x00000000,
+/**/ 0xBF7B5F40, 0xE15169A9,
+/**/ 0x3FEC9000, 0x00000000,
+/**/ 0x4001BE19, 0x91B4C8D8,
+/**/ 0x4013795B, 0xBE69BAE6,
+/**/ 0x40373151, 0xCD6F8B02,
+/**/ 0x4060E864, 0xD86A7BFF,
+/**/ 0x408B95CC, 0x515F5BD6,
+/**/ 0x40B8180C, 0xD070B4A1,
+/**/ 0x40E60D2C, 0xC9B24D80,
+/**/ 0x4114DBF6, 0xAA392CAF,
+/**/ 0xBCA89BD0, 0xF5844C55,
+/**/ 0x3FF1A603, 0xDBFAF236,
+/**/ 0x4001C000, 0x00000000,
+/**/ 0xBF4E66E4, 0xB37285FC,
+/**/ 0x3FECB000, 0x00000000,
+/**/ 0x40020E3D, 0x1757F6B1,
+/**/ 0x40149CE9, 0xAE890640,
+/**/ 0x403972D4, 0xD6174F60,
+/**/ 0x40634079, 0x8C82DF92,
+/**/ 0x40904BE6, 0xACAB5569,
+/**/ 0x40BD8A99, 0xB362E75A,
+/**/ 0x40EC0ED7, 0x389374DC,
+/**/ 0x411B8ADF, 0xCA5E9653,
+/**/ 0xBC80CBC7, 0x4A1E3E49,
+/**/ 0x3FF1C9CF, 0x704F5D26,
+/**/ 0x40020000, 0x00000000,
+/**/ 0x3F7C7A2E, 0xAFED62A2,
+/**/ 0x3FECD000, 0x00000000,
+/**/ 0x40026327, 0x6B3395AA,
+/**/ 0x4015DD66, 0x33FB1467,
+/**/ 0x403C0610, 0xDCF3437C,
+/**/ 0x406607CE, 0xC9D7C47A,
+/**/ 0x409360FB, 0xA330DC5C,
+/**/ 0x40C240B4, 0x38A3194B,
+/**/ 0x40F20437, 0xBAA6A879,
+/**/ 0x41226106, 0x04D6F19C,
+/**/ 0x3CABCCF5, 0x15E5252C,
+/**/ 0x3FF1EE3F, 0xFF35681A,
+/**/ 0x40026000, 0x00000000,
+/**/ 0x3F593B59, 0x9CAD4CE9,
+/**/ 0x3FECF000, 0x00000000,
+/**/ 0x4002BD54, 0x664A8350,
+/**/ 0x40173EFF, 0x945190A0,
+/**/ 0x403EFA80, 0xC7CC5224,
+/**/ 0x406958AA, 0x896F1658,
+/**/ 0x40973450, 0x4FD54E04,
+/**/ 0x40C6BF55, 0x4CD60C4A,
+/**/ 0x40F75EBE, 0x3EFFD07C,
+/**/ 0x4128D03C, 0x9E2E6981,
+/**/ 0xBC987CEE, 0xC8A488FF,
+/**/ 0x3FF2135F, 0x8F597306,
+/**/ 0x4002C000, 0x00000000,
+/**/ 0xBF555CCD, 0xABE583FE,
+/**/ 0x3FED1000, 0x00000000,
+/**/ 0x40031D52, 0x2A40EA5C,
+/**/ 0x4018C6B3, 0x52B4947D,
+/**/ 0x404131AE, 0x5D01146E,
+/**/ 0x406D54FB, 0x0163E71C,
+/**/ 0x409BFE8A, 0xEF3ED15B,
+/**/ 0x40CC9C28, 0xA33A6B00,
+/**/ 0x40FEA523, 0x1456E1A6,
+/**/ 0x4130F60F, 0xFC8790DB,
+/**/ 0x3CAC104F, 0x6FABCA41,
+/**/ 0x3FF23939, 0x30D87C68,
+/**/ 0x40032000, 0x00000000,
+/**/ 0xBF556EAD, 0xF8AD1CF9,
+/**/ 0x3FED3000, 0x00000000,
+/**/ 0x400383C4, 0xC053C623,
+/**/ 0x401A7A81, 0x6ADBFF2C,
+/**/ 0x40432C5B, 0xE219A24E,
+/**/ 0x40711484, 0x30F4B8D8,
+/**/ 0x40A10659, 0xBC59423E,
+/**/ 0x40D22C09, 0x3D537AE5,
+/**/ 0x410454A2, 0xA4B7D930,
+/**/ 0x41378151, 0xC151F3C3,
+/**/ 0xBCA2F226, 0x779E9951,
+/**/ 0x3FF25FD9, 0x254E3F9C,
+/**/ 0x40038000, 0x00000000,
+/**/ 0x3F5E2602, 0x9E311A8B,
+/**/ 0x3FED5000, 0x00000000,
+/**/ 0x4003F16A, 0xA2F65F8C,
+/**/ 0x401C61AF, 0x36C0308E,
+/**/ 0x40457C82, 0x5337FF7D,
+/**/ 0x407407A3, 0x7FB84BA9,
+/**/ 0x40A4E476, 0x4C74DEA7,
+/**/ 0x40D75638, 0xDF1C2124,
+/**/ 0x410B5320, 0xA2556E94,
+/**/ 0x414087CD, 0x7D68ABBE,
+/**/ 0xBCACD58C, 0x73A87AB9,
+/**/ 0x3FF2874D, 0x10017B06,
+/**/ 0x40040000, 0x00000000,
+/**/ 0xBF7D2ABA, 0x1340E849,
+/**/ 0x3FED7000, 0x00000000,
+/**/ 0x40046722, 0x7BA9A810,
+/**/ 0x401E851F, 0xCBC74735,
+/**/ 0x40483596, 0xF3879985,
+/**/ 0x4077AAEB, 0xCD297F00,
+/**/ 0x40A9E3C8, 0x31669F50,
+/**/ 0x40DE5420, 0xB7CBB664,
+/**/ 0x41129F7B, 0xB75100A0,
+/**/ 0x4147A1C1, 0x51D127BF,
+/**/ 0x3CAC647E, 0x46D9C78F,
+/**/ 0x3FF2AFA4, 0x304962AE,
+/**/ 0x40046000, 0x00000000,
+/**/ 0x3F6C89EE, 0xA6A041C9,
+/**/ 0x3FED9000, 0x00000000,
+/**/ 0x4004E5F2, 0x7A99A835,
+/**/ 0x402077E5, 0x15B0232D,
+/**/ 0x404B70C1, 0xEE468866,
+/**/ 0x407C334A, 0x43A041C3,
+/**/ 0x40B036D1, 0x53D2C164,
+/**/ 0x40E3F7B1, 0x10CCEDBE,
+/**/ 0x4119C160, 0xF6C2E560,
+/**/ 0x415131DD, 0x6D21D20F,
+/**/ 0x41878683, 0x2EC50766,
+/**/ 0xBCA95596, 0xD1134ECC,
+/**/ 0x3FF2D8EF, 0xA8F4B028,
+/**/ 0x4004E000, 0x00000000,
+/**/ 0x3F67C9EA, 0x66A0D2C7,
+/**/ 0x3FEDB000, 0x00000000,
+/**/ 0x40056F11, 0xD6373B90,
+/**/ 0x4021D7AC, 0xC3747DF3,
+/**/ 0x404F4EF3, 0x6A014D6F,
+/**/ 0x4080F4C4, 0x505C454B,
+/**/ 0x40B48D16, 0x214975C5,
+/**/ 0x40EAACFD, 0xF57BFAC6,
+/**/ 0x41222235, 0x5225A6ED,
+/**/ 0x41598643, 0xACBA67AB,
+/**/ 0x419267B9, 0xDE5D19B9,
+/**/ 0xBCAEF63C, 0x42C92439,
+/**/ 0x3FF30342, 0xD86BED76,
+/**/ 0x40056000, 0x00000000,
+/**/ 0x3F7E23AC, 0x6E771F48,
+/**/ 0x3FEDD000, 0x00000000,
+/**/ 0x400603F5, 0x3D2D8CF1,
+/**/ 0x40236A84, 0xEF4A10FA,
+/**/ 0x4051FDF3, 0x4EA265AF,
+/**/ 0x408499B5, 0xD944F636,
+/**/ 0x40BA64B8, 0x37F73BAC,
+/**/ 0x40F21B9F, 0x259B27FC,
+/**/ 0x412A0669, 0x265D5B9F,
+/**/ 0x41635D8E, 0x3DC806E2,
+/**/ 0x419D8657, 0x36AD8B00,
+/**/ 0x3CA4CEEB, 0x3FFCDCA3,
+/**/ 0x3FF32EB3, 0xC69D2D10,
+/**/ 0x40060000, 0x00000000,
+/**/ 0x3F5FA9E9, 0x6C678625,
+/**/ 0x3FEDF000, 0x00000000,
+/**/ 0x4006A65F, 0x5FCDF915,
+/**/ 0x40253B6E, 0x68321BDA,
+/**/ 0x4054D949, 0x706E8DA9,
+/**/ 0x408950EF, 0x4A70D2D7,
+/**/ 0x40C13319, 0x1F15E14E,
+/**/ 0x40F907B1, 0x846A9BD5,
+/**/ 0x4133139C, 0x17C39016,
+/**/ 0x416E1DA3, 0xBC86F11B,
+/**/ 0x41A8597F, 0xD9F86F3B,
+/**/ 0x3C32D4F8, 0x7D0D5190,
+/**/ 0x3FF35B5B, 0xAFA88354,
+/**/ 0x4006A000, 0x00000000,
+/**/ 0x3F697D7F, 0x37E455FD,
+/**/ 0x3FEE1000, 0x00000000,
+/**/ 0x40075877, 0x41D1DBF9,
+/**/ 0x402758A8, 0xF5852184,
+/**/ 0x405861EE, 0x65C0F467,
+/**/ 0x408F83C0, 0xD2D91276,
+/**/ 0x40C6CA7C, 0x43EC3B0E,
+/**/ 0x4101A722, 0x718322C8,
+/**/ 0x413CA4C6, 0x9533D806,
+/**/ 0x417812B7, 0xE9899583,
+/**/ 0x41B4B875, 0x85EE8B86,
+/**/ 0xBC99DEFB, 0xD1AEEED1,
+/**/ 0x3FF38957, 0xB510476E,
+/**/ 0x40076000, 0x00000000,
+/**/ 0xBF6E22F8, 0xB8901BF9,
+/**/ 0x3FEE3000, 0x00000000,
+/**/ 0x40081CE6, 0xE1C37E57,
+/**/ 0x4029D4F3, 0xD3DC9910,
+/**/ 0x405CD074, 0xE3095065,
+/**/ 0x4093E764, 0xC5C38224,
+/**/ 0x40CEC5AE, 0x3CAE1F31,
+/**/ 0x41097A50, 0xC0645F38,
+/**/ 0x41461866, 0xD8A7F25E,
+/**/ 0x4183DAF5, 0x8C2F04A3,
+/**/ 0x41C2450E, 0xA9143C1F,
+/**/ 0x3C7D25BE, 0x9FD995BC,
+/**/ 0x3FF3B8C9, 0xC35D33E6,
+/**/ 0x40082000, 0x00000000,
+/**/ 0xBF58C8F1, 0xE40D49E0,
+/**/ 0x3FEE5000, 0x00000000,
+/**/ 0x4008F706, 0x285640BB,
+/**/ 0x402CC96B, 0x3B2B7CD1,
+/**/ 0x40613ADF, 0xC5341328,
+/**/ 0x4099908D, 0x16E928A9,
+/**/ 0x40D53986, 0x7CC08A3C,
+/**/ 0x4112DFC5, 0x31DD3E45,
+/**/ 0x41519499, 0xE2A13787,
+/**/ 0x4190F943, 0xF94424AD,
+/**/ 0x41D0C6BC, 0xCDCD49BE,
+/**/ 0xBC9E2458, 0x6D41701D,
+/**/ 0x3FF3E9D9, 0xC088BD28,
+/**/ 0x40090000, 0x00000000,
+/**/ 0xBF71F3AF, 0x537E8A00,
+/**/ 0x3FEE7000, 0x00000000,
+/**/ 0x4009EB18, 0x6562D1E0,
+/**/ 0x40302C31, 0x75651223,
+/**/ 0x4064E431, 0x336E41C7,
+/**/ 0x40A0BCA6, 0xA065DA69,
+/**/ 0x40DE034D, 0x917AF357,
+/**/ 0x411CD2C1, 0x4168FB0F,
+/**/ 0x415CFEB6, 0x15BB794D,
+/**/ 0x419E3EE1, 0x6EFFD5E5,
+/**/ 0x41E024E7, 0x1ACB4D9C,
+/**/ 0xBC9C29C8, 0xD93F153F,
+/**/ 0x3FF41CB7, 0x2183E810,
+/**/ 0x4009E000, 0x00000000,
+/**/ 0x3F7630CA, 0xC5A3C038,
+/**/ 0x3FEE9000, 0x00000000,
+/**/ 0x400AFEA6, 0xA364196F,
+/**/ 0x403258F3, 0x0B19A2EB,
+/**/ 0x4069BDA5, 0x2520AC75,
+/**/ 0x40A669BC, 0x8F67EDEA,
+/**/ 0x40E5D78C, 0xC026C9F8,
+/**/ 0x4126CCB4, 0x1E3B36C2,
+/**/ 0x4168EDE4, 0xBF45C805,
+/**/ 0x41AC2F6A, 0x8AC89E76,
+/**/ 0x41F0675E, 0x4CA9EB55,
+/**/ 0x42336AC1, 0x0D13E3DF,
+/**/ 0x3C9B1D74, 0xF2DE93A6,
+/**/ 0x3FF4519B, 0x155FB22E,
+/**/ 0x400B0000, 0x00000000,
+/**/ 0xBF4595C9, 0xBE690E67,
+/**/ 0x3FEEB000, 0x00000000,
+/**/ 0x400C3908, 0x4BD1C065,
+/**/ 0x40350D88, 0x26C39FFD,
+/**/ 0x4070296B, 0x69D3E79E,
+/**/ 0x40AED279, 0xD7FEEA5D,
+/**/ 0x40F072A8, 0xFD5BD547,
+/**/ 0x4132CDB9, 0x4A08BB38,
+/**/ 0x41768482, 0x536BED06,
+/**/ 0x41BBE1FF, 0x2F10E88D,
+/**/ 0x4201C966, 0xABDBBDAC,
+/**/ 0x42471011, 0x02E62DDA,
+/**/ 0xBCA0855D, 0x3E907E71,
+/**/ 0x3FF488CB, 0x8FA73920,
+/**/ 0x400C4000, 0x00000000,
+/**/ 0xBF6BDED0, 0xB8FE6DDF,
+/**/ 0x3FEED000, 0x00000000,
+/**/ 0x400DA439, 0x12AAF9A9,
+/**/ 0x40387D46, 0x62F25109,
+/**/ 0x4074C339, 0x3F133A3F,
+/**/ 0x40B5E143, 0x662036F9,
+/**/ 0x40F9CF04, 0x74467831,
+/**/ 0x41404E10, 0x576C6FA8,
+/**/ 0x41859489, 0xFF4F8E88,
+/**/ 0x41CD88D2, 0xB44962A9,
+/**/ 0x4214D838, 0x97A288F3,
+/**/ 0x425DE10B, 0x6CF738B3,
+/**/ 0xBC8E9EA7, 0x5F7263CC,
+/**/ 0x3FF4C29F, 0xAA786F36,
+/**/ 0x400DA000, 0x00000000,
+/**/ 0x3F60E44A, 0xABE6A2AD,
+/**/ 0x3FEEF000, 0x00000000,
+/**/ 0x400F4E35, 0xC169B52F,
+/**/ 0x403CF773, 0x29E8699C,
+/**/ 0x407B6D37, 0xFC1818D6,
+/**/ 0x40C02655, 0x1386790A,
+/**/ 0x41054A1F, 0x4FF79D1E,
+/**/ 0x414E104A, 0x7DB0265A,
+/**/ 0x41963C39, 0xE5C8114B,
+/**/ 0x41E10156, 0xF52A87DB,
+/**/ 0x422ADD76, 0x2E9E7ABE,
+/**/ 0x427586AB, 0x6EC81361,
+/**/ 0x3C935690, 0xE395EEA6,
+/**/ 0x3FF4FF86, 0x2E5965A2,
+/**/ 0x400F4000, 0x00000000,
+/**/ 0x3F7C6B82, 0xD36A5E70 } };
+
+#else
+#ifdef LITTLE_ENDI
+static const union {int4 i[5136];double x[2568];} asncs = { .i = {
+/**/ 0x00000000, 0x3FC04000,
+/**/ 0x88994424, 0x3FF02169,
+/**/ 0xB799B115, 0x3FB0A6A2,
+/**/ 0xD57409A0, 0x3FC6EF15,
+/**/ 0xAF52EAA0, 0x3FAA141E,
+/**/ 0xABBBE261, 0x3FB75591,
+/**/ 0xD206D88F, 0x3FA72B51,
+/**/ 0x5BB33E7D, 0x3C96B595,
+/**/ 0xA03E2700, 0x3FC04B41,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x66BBDC7C, 0xBF7E9677,
+/**/ 0x00000000, 0x3FC0C000,
+/**/ 0xF9E23A56, 0x3FF02386,
+/**/ 0x60FD0235, 0x3FB1308C,
+/**/ 0x14D16B02, 0x3FC7099F,
+/**/ 0x27C01EE1, 0x3FAAFED6,
+/**/ 0xDBCD5F98, 0x3FB79C6F,
+/**/ 0x4084DAAC, 0x3FA8144A,
+/**/ 0x38D8505E, 0xBC87C092,
+/**/ 0x56C9F380, 0x3FC0CC55,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x1DC5AA24, 0xBF7C7906,
+/**/ 0x00000000, 0x3FC14000,
+/**/ 0xB27141F6, 0x3FF025B5,
+/**/ 0x04CE7400, 0x3FB1BB18,
+/**/ 0x72907342, 0x3FC72514,
+/**/ 0x0BF4222C, 0x3FABEC60,
+/**/ 0x75B3736C, 0x3FB7E610,
+/**/ 0x5199C343, 0x3FA9024C,
+/**/ 0x06B56F60, 0xBC8AE84C,
+/**/ 0x3DEFA070, 0x3FC14D7A,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x8EBE0A5C, 0xBF7A4A4D,
+/**/ 0x00000000, 0x3FC1C000,
+/**/ 0xC6DE8F57, 0x3FF027F5,
+/**/ 0x345751E1, 0x3FB2464B,
+/**/ 0xCF026805, 0x3FC74178,
+/**/ 0x40A9E0D6, 0x3FACDCD8,
+/**/ 0xEB1D9C38, 0x3FB83282,
+/**/ 0xD7BE707B, 0x3FA9F590,
+/**/ 0x03A2A6D6, 0xBCAB9768,
+/**/ 0xE03B4870, 0x3FC1CEB0,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x2170A943, 0xBF780A39,
+/**/ 0x00000000, 0x3FC24000,
+/**/ 0x4C759796, 0x3FF02A47,
+/**/ 0x92771935, 0x3FB2D22B,
+/**/ 0x26ABA06D, 0x3FC75ECF,
+/**/ 0x486A1932, 0x3FADD05B,
+/**/ 0x5AF971D5, 0x3FB881D7,
+/**/ 0x831AEE0C, 0x3FAAEE52,
+/**/ 0xAD1B1BEF, 0x3CA13F57,
+/**/ 0xC8E09330, 0x3FC24FF9,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x8A68699B, 0xBF75B8B3,
+/**/ 0x00000000, 0x3FC2C000,
+/**/ 0x59374E09, 0x3FF02CAA,
+/**/ 0xD44E8BEA, 0x3FB35EBE,
+/**/ 0x92E4BE8A, 0x3FC77D1A,
+/**/ 0x4A6C34FD, 0x3FAEC706,
+/**/ 0x972F6E07, 0x3FB8D41E,
+/**/ 0xF9845F69, 0x3FABECCD,
+/**/ 0x945C4185, 0x3C8BA1FA,
+/**/ 0x83C058B0, 0x3FC2D155,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0xC8B1F774, 0xBF7355A6,
+/**/ 0x00000000, 0x3FC34000,
+/**/ 0x03DC7745, 0x3FF02F1F,
+/**/ 0xC1EE9F61, 0x3FB3EC0A,
+/**/ 0x4A82E6D2, 0x3FC79C5E,
+/**/ 0x19B1EF72, 0x3FAFC0F7,
+/**/ 0x2AA943E5, 0x3FB9296A,
+/**/ 0xEF8B9DE7, 0x3FACF141,
+/**/ 0x083C8716, 0xBC834081,
+/**/ 0x9D6E5610, 0x3FC352C4,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x2388BB30, 0xBF70E0FC,
+/**/ 0x00000000, 0x3FC3C000,
+/**/ 0x63D81251, 0x3FF031A5,
+/**/ 0x370B721F, 0x3FB47A15,
+/**/ 0xA28731E5, 0x3FC7BC9D,
+/**/ 0x1E305BE9, 0x3FB05F26,
+/**/ 0x5FA50FBD, 0x3FB981CC,
+/**/ 0x42AC4083, 0x3FADFBEF,
+/**/ 0xA8E107C7, 0x3CA20ACB,
+/**/ 0xA336F5E0, 0x3FC3D447,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x4FDB5D5C, 0xBF6CB538,
+/**/ 0x00000000, 0x3FC44000,
+/**/ 0x9159D86F, 0x3FF0343D,
+/**/ 0x23B3747C, 0x3FB508E4,
+/**/ 0x0ED597CB, 0x3FC7DDDC,
+/**/ 0x79ADF104, 0x3FB0DF92,
+/**/ 0x4658D945, 0x3FB9DD58,
+/**/ 0x14ACA06B, 0x3FAF0D19,
+/**/ 0xDF636EFE, 0xBCA4E10D,
+/**/ 0x23252C00, 0x3FC455DF,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x4C4F221A, 0xBF6784DD,
+/**/ 0x00000000, 0x3FC4C000,
+/**/ 0xA550D410, 0x3FF036E7,
+/**/ 0x8D0AF1E7, 0x3FB5987D,
+/**/ 0x22F39726, 0x3FC8001D,
+/**/ 0xA1116D73, 0x3FB161D0,
+/**/ 0xBBEA1528, 0x3FBA3C21,
+/**/ 0x74202FF6, 0x3FB01282,
+/**/ 0xD10866E2, 0x3CAA0611,
+/**/ 0xAC086560, 0x3FC4D78B,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x5E57DF8A, 0xBF6230B5,
+/**/ 0x00000000, 0x3FC54000,
+/**/ 0xB96E0F8A, 0x3FF039A3,
+/**/ 0x8E0C29F6, 0x3FB628E7,
+/**/ 0x92CEDE01, 0x3FC82364,
+/**/ 0xFB7B5D84, 0x3FB1E5F0,
+/**/ 0x71BD08EE, 0x3FBA9E3D,
+/**/ 0x5F7FFAB4, 0x3FB0A1FD,
+/**/ 0xEF04F6E7, 0xBC90F980,
+/**/ 0xCD7A8DC0, 0x3FC5594D,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x47C1D879, 0xBF59711A,
+/**/ 0x00000000, 0x3FC5C000,
+/**/ 0xE8275C12, 0x3FF03C71,
+/**/ 0x584C2A23, 0x3FB6BA28,
+/**/ 0x338C3D4B, 0x3FC847B6,
+/**/ 0x59A55DD8, 0x3FB26C04,
+/**/ 0xF5202D6A, 0x3FBB03C0,
+/**/ 0x9C6466A4, 0x3FB13522,
+/**/ 0x2A268973, 0x3C983C9A,
+/**/ 0x17E62A20, 0x3FC5DB26,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0xC51F7008, 0xBF4C70BE,
+/**/ 0x00000000, 0x3FC64000,
+/**/ 0x4CBA31A9, 0x3FF03F52,
+/**/ 0x34C49ADE, 0x3FB74C46,
+/**/ 0xFC5F33CC, 0x3FC86D15,
+/**/ 0xFA419D7C, 0x3FB2F41B,
+/**/ 0xB757E82A, 0x3FBB6CC2,
+/**/ 0xDA4D5C39, 0x3FB1CC18,
+/**/ 0x2DFB224D, 0xBCA862D4,
+/**/ 0x1C8C8AF0, 0x3FC65D15,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0xB9CADBBF, 0xBF25B668,
+/**/ 0x00000000, 0x3FC6C000,
+/**/ 0x032EA88F, 0x3FF04245,
+/**/ 0x84A2B473, 0x3FB7DF47,
+/**/ 0x076A60F5, 0x3FC89388,
+/**/ 0x8E8394C1, 0x3FB37E49,
+/**/ 0x160F3472, 0x3FBBD95A,
+/**/ 0x39844810, 0x3FB26708,
+/**/ 0x698BC8EA, 0x3C994228,
+/**/ 0x6D8C14A0, 0x3FC6DF1B,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x754477AC, 0x3F422819,
+/**/ 0x00000000, 0x3FC74000,
+/**/ 0x285A8CEB, 0x3FF0454A,
+/**/ 0xC21B9224, 0x3FB87332,
+/**/ 0x92A93402, 0x3FC8BB10,
+/**/ 0x3ED3F586, 0x3FB40A9F,
+/**/ 0x643217C8, 0x3FBC499F,
+/**/ 0x5D29A16B, 0x3FB3061A,
+/**/ 0x3DF9F2D7, 0xBCA3B2DF,
+/**/ 0x9DE6A160, 0x3FC76139,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x6A33AB4B, 0x3F5528A1,
+/**/ 0x00000000, 0x3FC7C000,
+/**/ 0xD9E48D58, 0x3FF04861,
+/**/ 0x81461BF6, 0x3FB9080E,
+/**/ 0x00E32FFA, 0x3FC8E3B4,
+/**/ 0xAFB1F2A5, 0x3FB4992F,
+/**/ 0xF33705D5, 0x3FBCBDAB,
+/**/ 0x7E23EE89, 0x3FB3A97A,
+/**/ 0xCCE44C41, 0x3C7AAD12,
+/**/ 0x4187FAE0, 0x3FC7E370,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0xC91AAF11, 0x3F60C3B3,
+/**/ 0x00000000, 0x3FC84000,
+/**/ 0x36478509, 0x3FF04B8C,
+/**/ 0x70FAC1B4, 0x3FB99DE1,
+/**/ 0xDAA92166, 0x3FC90D76,
+/**/ 0x06C416A6, 0x3FB52A0E,
+/**/ 0x1CDCA344, 0x3FBD359A,
+/**/ 0x7EFD4CA0, 0x3FB45155,
+/**/ 0x35A8895D, 0x3C396CA5,
+/**/ 0xED4C6EF0, 0x3FC865BF,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x8F0A11A4, 0x3F67186C,
+/**/ 0x00000000, 0x3FC8C000,
+/**/ 0x5CD5E248, 0x3FF04EC9,
+/**/ 0x5BB94403, 0x3FBA34B2,
+/**/ 0xCF5CA73A, 0x3FC9385D,
+/**/ 0xF01AFDBE, 0x3FB5BD4D,
+/**/ 0x4D61A7A9, 0x3FBDB185,
+/**/ 0x00BD47CF, 0x3FB4FDDA,
+/**/ 0x727E8B64, 0xBC9D1119,
+/**/ 0x37077E20, 0x3FC8E829,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0xABC490CB, 0x3F6D92B9,
+/**/ 0x00000000, 0x3FC94000,
+/**/ 0x6DBD2A10, 0x3FF05219,
+/**/ 0x2894CAA1, 0x3FBACC88,
+/**/ 0xB6427516, 0x3FC9646D,
+/**/ 0xA3A864D7, 0x3FB65303,
+/**/ 0x0E3CF3D4, 0x3FBE318A,
+/**/ 0x78CDA678, 0x3FB5AF38,
+/**/ 0xDA9D51DF, 0x3CA3841D,
+/**/ 0xB58AA660, 0x3FC96AAC,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0xBD2A1052, 0x3F72196D,
+/**/ 0x00000000, 0x3FC9C000,
+/**/ 0x8A099990, 0x3FF0557C,
+/**/ 0xDC268965, 0x3FBB6569,
+/**/ 0x8F9FBA21, 0x3FC991AB,
+/**/ 0xEAED1E85, 0x3FB6EB43,
+/**/ 0x115C4C63, 0x3FBEB5C6,
+/**/ 0x47F9AEFA, 0x3FB665A3,
+/**/ 0x03AB3673, 0xBCA1F8FD,
+/**/ 0x00AC4A60, 0x3FC9ED4B,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x0999905B, 0x3F757C8A,
+/**/ 0x00000000, 0x3FCA4000,
+/**/ 0xD3A9E674, 0x3FF058F2,
+/**/ 0x99873832, 0x3FBBFF5E,
+/**/ 0x85E31CE9, 0x3FC9C01C,
+/**/ 0x26E09FF2, 0x3FB78624,
+/**/ 0x3CF0885C, 0x3FBF3E58,
+/**/ 0xD2986239, 0x3FB7214E,
+/**/ 0x3E594694, 0x3C97E3E5,
+/**/ 0xB14EB5D0, 0x3FCA7004,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0xA9E6746B, 0x3F78F2D3,
+/**/ 0x00000000, 0x3FCAC000,
+/**/ 0x6D731ECB, 0x3FF05C7C,
+/**/ 0xA34FA4B3, 0x3FBC9A6D,
+/**/ 0xEED9C253, 0x3FC9EFC5,
+/**/ 0x5614FAEB, 0x3FB823BA,
+/**/ 0xB7CE698F, 0x3FBFCB60,
+/**/ 0x99F3292F, 0x3FB7E271,
+/**/ 0x068D709C, 0xBC9842C6,
+/**/ 0x61674110, 0x3FCAF2DA,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x731ECAE2, 0x3F7C7C6D,
+/**/ 0x00000000, 0x3FCB4000,
+/**/ 0x7B24A973, 0x3FF06019,
+/**/ 0x5CA0A798, 0x3FBD369E,
+/**/ 0x4CF0DB64, 0x3FCA20AD,
+/**/ 0x1B1A3F31, 0x3FB8C41D,
+/**/ 0x7B35E049, 0x3FC02E80,
+/**/ 0x56FB8A97, 0x3FB8A944,
+/**/ 0xD337B37C, 0xBCACBF9C,
+/**/ 0xAC059370, 0x3FCB75CC,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0xDB568D78, 0xBF7FE684,
+/**/ 0x00000000, 0x3FCBC000,
+/**/ 0x216C6801, 0x3FF063CA,
+/**/ 0x4A32C9FD, 0x3FBDD3F8,
+/**/ 0x50843BC9, 0x3FCA52D8,
+/**/ 0xC324648A, 0x3FB96763,
+/**/ 0xE4407899, 0x3FC079AD,
+/**/ 0x1663A5DC, 0x3FB97602,
+/**/ 0xC637289D, 0xBCA3ADC3,
+/**/ 0x2D5B06A0, 0x3FCBF8DC,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0x9397FEA6, 0xBF7C35DE,
+/**/ 0x00000000, 0x3FCC4000,
+/**/ 0x85EAFB1F, 0x3FF0678E,
+/**/ 0x136DEAC6, 0x3FBE7283,
+/**/ 0xD93A817D, 0x3FCA864C,
+/**/ 0x4CF7089B, 0x3FBA0DA6,
+/**/ 0xB3ABB322, 0x3FC0C74A,
+/**/ 0x562E6E1E, 0x3FBA48E8,
+/**/ 0x7EB8FFF8, 0xBC951E3E,
+/**/ 0x82C22B80, 0x3FCC7C09,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0x1504E0D3, 0xBF78717A,
+/**/ 0x00000000, 0x3FCCC000,
+/**/ 0xCF382A59, 0x3FF06B66,
+/**/ 0x838936FB, 0x3FBF1246,
+/**/ 0xF76F5C94, 0x3FCABB10,
+/**/ 0x701A77AE, 0x3FBAB6FD,
+/**/ 0xC26702C6, 0x3FC11769,
+/**/ 0x24CDF38E, 0x3FBB2237,
+/**/ 0xE28307A9, 0xBC8DB69A,
+/**/ 0x4AC67190, 0x3FCCFF55,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0xC7D5A6B9, 0xBF749930,
+/**/ 0x00000000, 0x3FCD4000,
+/**/ 0x24E7707F, 0x3FF06F53,
+/**/ 0x8AB3CBB2, 0x3FBFB34A,
+/**/ 0xEDAC8D74, 0x3FCAF12A,
+/**/ 0xA45DA614, 0x3FBB6382,
+/**/ 0xAD8E9F44, 0x3FC16A1E,
+/**/ 0x41E7749D, 0x3FBC0231,
+/**/ 0x22DC16A2, 0x3C76CA27,
+/**/ 0x252BF240, 0x3FCD82C0,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0x188F814B, 0xBF70ACDB,
+/**/ 0x00000000, 0x3FCDC000,
+/**/ 0xAF8CADA0, 0x3FF07353,
+/**/ 0x9FA32DC9, 0x3FC02ACB,
+/**/ 0x32323718, 0x3FCB28A1,
+/**/ 0x29A8F15E, 0x3FBC1350,
+/**/ 0xDEB270E1, 0x3FC1BF7D,
+/**/ 0x40D67463, 0x3FBCE91C,
+/**/ 0x104BAA08, 0x3CA6E976,
+/**/ 0xB2F76140, 0x3FCE064A,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0xE6A4BFC9, 0xBF6958A0,
+/**/ 0x00000000, 0x3FCE4000,
+/**/ 0x98C0FFD9, 0x3FF07768,
+/**/ 0x6F7F1AF0, 0x3FC07C9A,
+/**/ 0x708F2AFB, 0x3FCB617A,
+/**/ 0x1025B50C, 0x3FBCC681,
+/**/ 0x9487453A, 0x3FC2179C,
+/**/ 0xAD09B3AB, 0x3FBDD740,
+/**/ 0x189038C0, 0xBC8D32DB,
+/**/ 0x96762300, 0x3FCE89F5,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0x7E004D50, 0xBF612ECE,
+/**/ 0x00000000, 0x3FCEC000,
+/**/ 0x0B27C417, 0x3FF07B92,
+/**/ 0xE821087A, 0x3FC0CF15,
+/**/ 0x8B49DC8C, 0x3FCB9BBD,
+/**/ 0x40BEF5C2, 0x3FBD7D31,
+/**/ 0xEC080575, 0x3FC27290,
+/**/ 0x3056A6A9, 0x3FBECCEA,
+/**/ 0x0C9B27A2, 0x3C9DE506,
+/**/ 0x73468A50, 0x3FCF0DC1,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0x60EFA34D, 0xBF51B7D3,
+/**/ 0x00000000, 0x3FCF4000,
+/**/ 0x3273C018, 0x3FF07FD0,
+/**/ 0x51B87F08, 0x3FC12242,
+/**/ 0x9D9AB2BC, 0x3FCBD771,
+/**/ 0x85FFA125, 0x3FBE377D,
+/**/ 0xEA0CFE55, 0x3FC2D071,
+/**/ 0xBB61DDD3, 0x3FBFCA67,
+/**/ 0x88A645E7, 0xBCA25383,
+/**/ 0xEE603F40, 0x3FCF91AE,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0x1FF422B6, 0xBF07E6C6,
+/**/ 0x00000000, 0x3FCFC000,
+/**/ 0x3B6C76F2, 0x3FF08423,
+/**/ 0x0A1DF897, 0x3FC17624,
+/**/ 0xFD38779D, 0x3FCC149D,
+/**/ 0x95531ECD, 0x3FBEF583,
+/**/ 0x855FA966, 0x3FC33157,
+/**/ 0xD81E6BAA, 0x3FC06805,
+/**/ 0x1B47FAEC, 0x3C86827E,
+/**/ 0x570E6798, 0x3FD00ADF,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0xB1DBC656, 0x3F508CED,
+/**/ 0x00000000, 0x3FD02000,
+/**/ 0x53F3A97B, 0x3FF0888B,
+/**/ 0x858525D6, 0x3FC1CABF,
+/**/ 0x3C37AF90, 0x3FCC534A,
+/**/ 0x18AD312A, 0x3FBFB762,
+/**/ 0xB151CAAD, 0x3FC3955A,
+/**/ 0x07ADE82D, 0x3FC0EF16,
+/**/ 0xFCDE8746, 0x3CAEEF44,
+/**/ 0xAD203480, 0x3FD04CF8,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0xE752F5A1, 0x3F6116A7,
+/**/ 0x00000000, 0x3FD06000,
+/**/ 0xAB0B03F8, 0x3FF08D08,
+/**/ 0x4F34EEE8, 0x3FC22019,
+/**/ 0x2AFDABDE, 0x3FCC937E,
+/**/ 0x5C4F35BA, 0x3FC03E9C,
+/**/ 0x68DF21A6, 0x3FC3FC95,
+/**/ 0x53843C52, 0x3FC17A91,
+/**/ 0xC2BB835A, 0xBC9D6F54,
+/**/ 0xCE0162B8, 0x3FD08F23,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0x1607EF23, 0x3F6A1156,
+/**/ 0x00000000, 0x3FD0A000,
+/**/ 0x70D9FA87, 0x3FF0919B,
+/**/ 0x0A456C09, 0x3FC27636,
+/**/ 0xDA483778, 0x3FCCD541,
+/**/ 0x136D6630, 0x3FC0A394,
+/**/ 0xBA615E9C, 0x3FC46722,
+/**/ 0xA2BC6F73, 0x3FC20AA6,
+/**/ 0x7F1D9D86, 0x3CA9D006,
+/**/ 0x0F0C1EC8, 0x3FD0D161,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0xD9FA8688, 0x3F719B70,
+/**/ 0x00000000, 0x3FD0E000,
+/**/ 0xD6B3D5D1, 0x3FF09643,
+/**/ 0x72641546, 0x3FC2CD1A,
+/**/ 0x9D4AC7EC, 0x3FCD189D,
+/**/ 0x149C2E66, 0x3FC10AA9,
+/**/ 0xD3DE8741, 0x3FC4D51E,
+/**/ 0xF6DA4768, 0x3FC29F86,
+/**/ 0x828C2A81, 0x3CAEA900,
+/**/ 0xC65D88C8, 0x3FD113B0,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0xB3D5D119, 0x3F7643D6,
+/**/ 0x00000000, 0x3FD12000,
+/**/ 0x0F1DF195, 0x3FF09B02,
+/**/ 0x5C9E6B3F, 0x3FC324CB,
+/**/ 0x0BE228B7, 0x3FCD5D9A,
+/**/ 0xD29602B0, 0x3FC173EC,
+/**/ 0x0FFA7799, 0x3FC546A7,
+/**/ 0x87BA569F, 0x3FC33965,
+/**/ 0x9956F2C3, 0xBCAE3258,
+/**/ 0x4ADA6FF0, 0x3FD15613,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0x1DF1952F, 0x3F7B020F,
+/**/ 0x00000000, 0x3FD16000,
+/**/ 0x4DD62EB0, 0x3FF09FD6,
+/**/ 0xB8335DE5, 0x3FC37D4D,
+/**/ 0x04DFA3F1, 0x3FCDA440,
+/**/ 0x55E59412, 0x3FC1DF71,
+/**/ 0x0394B72E, 0x3FC5BBDA,
+/**/ 0xE1177398, 0x3FC3D877,
+/**/ 0x3B5720A7, 0x3CA8AC88,
+/**/ 0xF43427A8, 0x3FD19888,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0xD62EAF85, 0x3F7FD64D,
+/**/ 0x00000000, 0x3FD1A000,
+/**/ 0xC7D99A5F, 0x3FF0A4C0,
+/**/ 0x8F6BB942, 0x3FC3D6A6,
+/**/ 0xB06CB8A9, 0x3FCDEC98,
+/**/ 0x432C74B1, 0x3FC24D49,
+/**/ 0x8C1C6EC6, 0x3FC634D7,
+/**/ 0x01BF2560, 0x3FC47CF6,
+/**/ 0x476E25C7, 0x3CA3EDE7,
+/**/ 0x1AED7720, 0x3FD1DB12,
+/**/ 0x00000000, 0x3FF0C000,
+/**/ 0x2665A126, 0xBF7B3F38,
+/**/ 0x00000000, 0x3FD1E000,
+/**/ 0xB36B4C8B, 0x3FF0A9C1,
+/**/ 0x0879E39B, 0x3FC430DB,
+/**/ 0x82887D8B, 0x3FCE36AD,
+/**/ 0xE1B33C79, 0x3FC2BD87,
+/**/ 0xDEA4E95E, 0x3FC6B1C0,
+/**/ 0x7C90504A, 0x3FC5271A,
+/**/ 0x8A6EBD08, 0x3CAAFAD9,
+/**/ 0x185FA360, 0x3FD21DAF,
+/**/ 0x00000000, 0x3FF0C000,
+/**/ 0x94B3751C, 0xBF763E4C,
+/**/ 0x00000000, 0x3FD22000,
+/**/ 0x481B7EED, 0x3FF0AED9,
+/**/ 0x66613BB3, 0x3FC48BF0,
+/**/ 0x3D9FDD8F, 0x3FCE8288,
+/**/ 0x22470BF2, 0x3FC33041,
+/**/ 0x97C5B476, 0x3FC732B8,
+/**/ 0x9B614F73, 0x3FC5D722,
+/**/ 0x759745C8, 0x3CA96B82,
+/**/ 0x46BF95B8, 0x3FD26060,
+/**/ 0x00000000, 0x3FF0C000,
+/**/ 0xE48112DC, 0xBF7126B7,
+/**/ 0x00000000, 0x3FD26000,
+/**/ 0xBECEDF0E, 0x3FF0B407,
+/**/ 0x09E5699A, 0x3FC4E7EC,
+/**/ 0xF541EC2D, 0x3FCED032,
+/**/ 0xA6688484, 0x3FC3A589,
+/**/ 0xCC5228BD, 0x3FC7B7E2,
+/**/ 0x83ECAD1F, 0x3FC68D4E,
+/**/ 0x7CB79363, 0x3CA98586,
+/**/ 0x01231EC8, 0x3FD2A326,
+/**/ 0x00000000, 0x3FF0C000,
+/**/ 0x6241E449, 0xBF67F082,
+/**/ 0x00000000, 0x3FD2A000,
+/**/ 0x51C61D1C, 0x3FF0B94D,
+/**/ 0x7281F837, 0x3FC544D3,
+/**/ 0x10F19F89, 0x3FCF1FB8,
+/**/ 0xC7D08A44, 0x3FC41D76,
+/**/ 0x1AF4E5E6, 0x3FC84165,
+/**/ 0x5EE5D838, 0x3FC749E1,
+/**/ 0xA1F9A890, 0x3C8A2A36,
+/**/ 0xA3865760, 0x3FD2E600,
+/**/ 0x00000000, 0x3FF0C000,
+/**/ 0xE78B8E2F, 0xBF5ACAB8,
+/**/ 0x00000000, 0x3FD2E000,
+/**/ 0x3CA5B9C1, 0x3FF0BEAA,
+/**/ 0x3F6A91D3, 0x3FC5A2AC,
+/**/ 0x4F1650DB, 0x3FCF7122,
+/**/ 0xA04F63E7, 0x3FC4981E,
+/**/ 0xBEBC9B64, 0x3FC8CF66,
+/**/ 0x81598BF7, 0x3FC80D21,
+/**/ 0x8E0FD320, 0xBC984143,
+/**/ 0x8AD12008, 0x3FD328F0,
+/**/ 0x00000000, 0x3FF0C000,
+/**/ 0xA463F3FD, 0xBF355C35,
+/**/ 0x00000000, 0x3FD32000,
+/**/ 0xBC7E151A, 0x3FF0C41E,
+/**/ 0x30943E19, 0x3FC6017C,
+/**/ 0xC80C760D, 0x3FCFC47C,
+/**/ 0x120B129D, 0x3FC51598,
+/**/ 0xA2A855B5, 0x3FC96210,
+/**/ 0x9880230D, 0x3FC8D758,
+/**/ 0xBF178596, 0xBCA4D129,
+/**/ 0x14DCC050, 0x3FD36BF6,
+/**/ 0x00000000, 0x3FF0C000,
+/**/ 0xF854661E, 0x3F507AF1,
+/**/ 0x00000000, 0x3FD36000,
+/**/ 0x0FD3C135, 0x3FF0C9AB,
+/**/ 0x27C80482, 0x3FC66149,
+/**/ 0x78AC0DDD, 0x3FD00CE9,
+/**/ 0xD02204B1, 0x3FC595FA,
+/**/ 0x7642750D, 0x3FC9F98D,
+/**/ 0xD82AC48A, 0x3FC9A8D3,
+/**/ 0x289B3951, 0x3C977587,
+/**/ 0xA079A6D8, 0x3FD3AF11,
+/**/ 0x00000000, 0x3FF0C000,
+/**/ 0xA7826A0D, 0x3F63561F,
+/**/ 0x00000000, 0x3FD3A000,
+/**/ 0x76A81A69, 0x3FF0CF4F,
+/**/ 0x29BF5ACD, 0x3FC6C219,
+/**/ 0x507D5DD4, 0x3FD03898,
+/**/ 0x67B79439, 0x3FC6195F,
+/**/ 0xC35A709F, 0x3FCA9609,
+/**/ 0x2BF7455C, 0x3FCA81E4,
+/**/ 0xF424551E, 0x3CA03304,
+/**/ 0x8D754B40, 0x3FD3F243,
+/**/ 0x00000000, 0x3FF0C000,
+/**/ 0x5034D2A8, 0x3F6E9EED,
+/**/ 0x00000000, 0x3FD3E000,
+/**/ 0x3282280D, 0x3FF0D50C,
+/**/ 0x5F4ACC23, 0x3FC723F2,
+/**/ 0x08771131, 0x3FD06551,
+/**/ 0x4970163E, 0x3FC69FDF,
+/**/ 0x04EE9A0A, 0x3FCB37B4,
+/**/ 0x6B79BC18, 0x3FCB62DE,
+/**/ 0x02A2F456, 0x3CAECF25,
+/**/ 0x3CA032E0, 0x3FD4358C,
+/**/ 0x00000000, 0x3FF0C000,
+/**/ 0x82280D28, 0x3F750C32,
+/**/ 0x00000000, 0x3FD42000,
+/**/ 0x8677C82D, 0x3FF0DAE1,
+/**/ 0x16834ABE, 0x3FC786DB,
+/**/ 0xF1631731, 0x3FD09319,
+/**/ 0xD36297AF, 0x3FC72994,
+/**/ 0xBF583888, 0x3FCBDEBC,
+/**/ 0x918E2AE6, 0x3FCC4C1B,
+/**/ 0xF34A155C, 0x3CA92F70,
+/**/ 0x0FD419C8, 0x3FD478EC,
+/**/ 0x00000000, 0x3FF0C000,
+/**/ 0x77C82D53, 0x3F7AE186,
+/**/ 0x00000000, 0x3FD46000,
+/**/ 0xB73728F8, 0x3FF0E0CF,
+/**/ 0xC406A36A, 0x3FC7EAD9,
+/**/ 0x91BDA616, 0x3FD0C1F9,
+/**/ 0x5B86C42B, 0x3FC7B69B,
+/**/ 0x99CD8C9F, 0x3FCC8B56,
+/**/ 0xF7084936, 0x3FCD3DF8,
+/**/ 0x54942387, 0xBC923B74,
+/**/ 0x69FA40E8, 0x3FD4BC63,
+/**/ 0x00000000, 0x3FF10000,
+/**/ 0xC8D707BB, 0xBF7F3048,
+/**/ 0x00000000, 0x3FD4A000,
+/**/ 0x0B1092B8, 0x3FF0E6D7,
+/**/ 0x043F9011, 0x3FC84FF5,
+/**/ 0xA7AFD6EB, 0x3FD0F1F6,
+/**/ 0x3AA5D7B9, 0x3FC8470F,
+/**/ 0x794E9CFD, 0x3FCD3DB6,
+/**/ 0x90FB69FD, 0x3FCE38D8,
+/**/ 0xC2327DC5, 0x3C9CFA2D,
+/**/ 0xAF11E2C0, 0x3FD4FFF2,
+/**/ 0x00000000, 0x3FF10000,
+/**/ 0xEF6D4848, 0xBF7928F4,
+/**/ 0x00000000, 0x3FD4E000,
+/**/ 0xCA008550, 0x3FF0ECF7,
+/**/ 0x9CB9ECA7, 0x3FC8B633,
+/**/ 0x2B20AC3D, 0x3FD12318,
+/**/ 0xD7D5E860, 0x3FC8DB0D,
+/**/ 0x9D1315AF, 0x3FCDF613,
+/**/ 0x32D8BC6F, 0x3FCF3D21,
+/**/ 0x92E48EEE, 0x3C9C6A36,
+/**/ 0x4436D008, 0x3FD5439A,
+/**/ 0x00000000, 0x3FF10000,
+/**/ 0xFF7AAF92, 0xBF730835,
+/**/ 0x00000000, 0x3FD52000,
+/**/ 0x3DBA2C62, 0x3FF0F332,
+/**/ 0x7D83983C, 0x3FC91D9C,
+/**/ 0x4FDDA02E, 0x3FD15565,
+/**/ 0xB48747C7, 0x3FC972B5,
+/**/ 0xBC9105F9, 0x3FCEB4A7,
+/**/ 0x6A535ECF, 0x3FD0259F,
+/**/ 0xF6EA55C1, 0x3C87EB36,
+/**/ 0x8FA83538, 0x3FD5875A,
+/**/ 0x00000000, 0x3FF10000,
+/**/ 0x8BA73C6A, 0xBF699B84,
+/**/ 0x00000000, 0x3FD56000,
+/**/ 0xB1B22D42, 0x3FF0F986,
+/**/ 0xC29A92ED, 0x3FC98636,
+/**/ 0x87DBE62D, 0x3FD188E5,
+/**/ 0x792C37EB, 0x3FCA0E26,
+/**/ 0x2735E8CD, 0x3FCF79AF,
+/**/ 0x6ECCD4C0, 0x3FD0B1D1,
+/**/ 0xBEAE0510, 0x3C9502B5,
+/**/ 0xF8CF8AC0, 0x3FD5CB33,
+/**/ 0x00000000, 0x3FF10000,
+/**/ 0x374AF74C, 0xBF59E539,
+/**/ 0x00000000, 0x3FD5A000,
+/**/ 0x7329D23A, 0x3FF0FFF5,
+/**/ 0xB568F082, 0x3FC9F009,
+/**/ 0x85939DB2, 0x3FD1BDA0,
+/**/ 0x0283B18A, 0x3FCAAD81,
+/**/ 0x72F69148, 0x3FD022B4,
+/**/ 0x39AD0B79, 0x3FD14362,
+/**/ 0x80828B86, 0xBCAD7968,
+/**/ 0xE847B130, 0x3FD60F26,
+/**/ 0x00000000, 0x3FF10000,
+/**/ 0x5B8BC081, 0xBEE519AC,
+/**/ 0x00000000, 0x3FD5E000,
+/**/ 0xD13A9687, 0x3FF1067E,
+/**/ 0xCE4F3F61, 0x3FCA5B1C,
+/**/ 0x3E764545, 0x3FD1F39E,
+/**/ 0x6F90871B, 0x3FCB50E7,
+/**/ 0x6F487F97, 0x3FD08C0B,
+/**/ 0x67265C20, 0x3FD1DA90,
+/**/ 0x995723AD, 0x3CAE5B02,
+/**/ 0xC7E43AA0, 0x3FD65333,
+/**/ 0x00000000, 0x3FF10000,
+/**/ 0xEA5A1D64, 0x3F59FB44,
+/**/ 0x00000000, 0x3FD62000,
+/**/ 0x1CE216D9, 0x3FF10D23,
+/**/ 0xB63E0B53, 0x3FCAC777,
+/**/ 0xED81D055, 0x3FD22AE6,
+/**/ 0x3046C5AC, 0x3FCBF87D,
+/**/ 0xFCB29FE4, 0x3FD0F8FE,
+/**/ 0xC99A404E, 0x3FD2779D,
+/**/ 0xC3202AE8, 0xBCA2AF1E,
+/**/ 0x02B8E378, 0x3FD6975B,
+/**/ 0x00000000, 0x3FF10000,
+/**/ 0xC42DB2AB, 0x3F6A4639,
+/**/ 0x00000000, 0x3FD66000,
+/**/ 0xA90E6A24, 0x3FF113E2,
+/**/ 0x485F2C6B, 0x3FCB3522,
+/**/ 0x15F1D6CC, 0x3FD26383,
+/**/ 0x14F9D555, 0x3FCCA467,
+/**/ 0x245E397E, 0x3FD169B3,
+/**/ 0x99479CF7, 0x3FD31ACF,
+/**/ 0x8992C228, 0xBC730D3F,
+/**/ 0x05213B28, 0x3FD6DB9D,
+/**/ 0x00000000, 0x3FF10000,
+/**/ 0x0E6A2469, 0x3F73E2A9,
+/**/ 0x00000000, 0x3FD6A000,
+/**/ 0xCAAAE6D5, 0x3FF11ABD,
+/**/ 0x93CF9B23, 0x3FCBA424,
+/**/ 0x86106AD4, 0x3FD29D7B,
+/**/ 0x5E96870B, 0x3FCD54CB,
+/**/ 0x9975D46D, 0x3FD1DE4D,
+/**/ 0xA709F8A4, 0x3FD3C46E,
+/**/ 0x457B6F5C, 0xBC9CB630,
+/**/ 0x3CC87FC8, 0x3FD71FFA,
+/**/ 0x00000000, 0x3FF10000,
+/**/ 0xAAE6D53D, 0x3F7ABDCA,
+/**/ 0x00000000, 0x3FD6E000,
+/**/ 0xD8AD589E, 0x3FF121B4,
+/**/ 0xDD6A8C89, 0x3FCC1486,
+/**/ 0x5A283891, 0x3FD2D8D9,
+/**/ 0xCFB4F5A1, 0x3FCE09D1,
+/**/ 0xCF594BB6, 0x3FD256F5,
+/**/ 0x92614C29, 0x3FD474C7,
+/**/ 0x533051E9, 0xBC88FB31,
+/**/ 0x18B1AD28, 0x3FD76473,
+/**/ 0x00000000, 0x3FF14000,
+/**/ 0x52A761D6, 0xBF7E4B27,
+/**/ 0x00000000, 0x3FD72000,
+/**/ 0x2C23AB4A, 0x3FF128C8,
+/**/ 0xA1A6A356, 0x3FCC8651,
+/**/ 0xFF99ABE3, 0x3FD315A5,
+/**/ 0xBE8EE4C2, 0x3FCEC3A3,
+/**/ 0x11207D5D, 0x3FD2D3D5,
+/**/ 0x02FE6DF8, 0x3FD52C2B,
+/**/ 0xFE4D8DF3, 0xBCA3F304,
+/**/ 0x093FC1F0, 0x3FD7A908,
+/**/ 0x00000000, 0x3FF14000,
+/**/ 0xDC54B622, 0xBF7737D3,
+/**/ 0x00000000, 0x3FD76000,
+/**/ 0x20420F33, 0x3FF12FF8,
+/**/ 0x96860D89, 0x3FCCF98D,
+/**/ 0x3814F292, 0x3FD353EB,
+/**/ 0x27E81BF7, 0x3FCF826C,
+/**/ 0x9A827352, 0x3FD35516,
+/**/ 0xE614C6DF, 0x3FD5EAED,
+/**/ 0x36C1700C, 0x3C80AEDB,
+/**/ 0x803E3C28, 0x3FD7EDB9,
+/**/ 0x00000000, 0x3FF14000,
+/**/ 0xBDF0CCC6, 0xBF7007DF,
+/**/ 0x00000000, 0x3FD7A000,
+/**/ 0x12719C3A, 0x3FF13745,
+/**/ 0xAD9A717F, 0x3FCD6E43,
+/**/ 0x1CFACD12, 0x3FD393B3,
+/**/ 0xE17B8F05, 0x3FD0232B,
+/**/ 0xB23873BC, 0x3FD3DAE7,
+/**/ 0xAFB712E5, 0x3FD6B169,
+/**/ 0x0BC74599, 0x3C994C0C,
+/**/ 0xF0E9CF80, 0x3FD83287,
+/**/ 0x00000000, 0x3FF14000,
+/**/ 0x1CC78CA5, 0xBF6175DB,
+/**/ 0x00000000, 0x3FD7E000,
+/**/ 0x625F7844, 0x3FF13EAF,
+/**/ 0x161D9978, 0x3FCDE47D,
+/**/ 0x22E63DCA, 0x3FD3D508,
+/**/ 0x8B2EC7EB, 0x3FD087CA,
+/**/ 0xC5F619C8, 0x3FD46577,
+/**/ 0xA08A73DE, 0x3FD77FFC,
+/**/ 0x6E7B547F, 0x3CA1DBDE,
+/**/ 0xCFF956F8, 0x3FD87773,
+/**/ 0x00000000, 0x3FF14000,
+/**/ 0x087BC752, 0xBF3509DA,
+/**/ 0x00000000, 0x3FD82000,
+/**/ 0x720C869D, 0x3FF14637,
+/**/ 0x3F1FD940, 0x3FCE5C43,
+/**/ 0x1D614654, 0x3FD417F5,
+/**/ 0x472052ED, 0x3FD0EF2A,
+/**/ 0x88116DA6, 0x3FD4F4F8,
+/**/ 0x102117B6, 0x3FD8570A,
+/**/ 0x214A7328, 0xBCAB6E89,
+/**/ 0x93A70458, 0x3FD8BC7D,
+/**/ 0x00000000, 0x3FF14000,
+/**/ 0x321A7479, 0x3F58DDC8,
+/**/ 0x00000000, 0x3FD86000,
+/**/ 0xA5DDA5C4, 0x3FF14DDD,
+/**/ 0xD9CD3739, 0x3FCED59F,
+/**/ 0x42C70412, 0x3FD45C85,
+/**/ 0x49C983A8, 0x3FD15964,
+/**/ 0x0EF7ED0B, 0x3FD5899E,
+/**/ 0xBC543499, 0x3FD936FA,
+/**/ 0x7B29F22E, 0x3CAFF50D,
+/**/ 0xB3B9CF50, 0x3FD901A5,
+/**/ 0x00000000, 0x3FF14000,
+/**/ 0xBB4B87E0, 0x3F6BBB4B,
+/**/ 0x00000000, 0x3FD8A000,
+/**/ 0x64AC8172, 0x3FF155A2,
+/**/ 0xDBCA7047, 0x3FCF509C,
+/**/ 0x3055A16F, 0x3FD4A2C4,
+/**/ 0xD25160C7, 0x3FD1C692,
+/**/ 0xF68F9906, 0x3FD6239E,
+/**/ 0x1DFC2EE2, 0x3FDA203D,
+/**/ 0x671EF39F, 0x3CAD2019,
+/**/ 0xA98F2718, 0x3FD946EC,
+/**/ 0x00000000, 0x3FF14000,
+/**/ 0xAC8171A9, 0x3F75A264,
+/**/ 0x00000000, 0x3FD8E000,
+/**/ 0x17D8FF02, 0x3FF15D86,
+/**/ 0x81AAFD5E, 0x3FCFCD44,
+/**/ 0xEE72B776, 0x3FD4EABD,
+/**/ 0x377F943F, 0x3FD236D1,
+/**/ 0x83A56DB7, 0x3FD6C334,
+/**/ 0xC36D6C50, 0x3FDB1345,
+/**/ 0x761537BB, 0xBC7841E5,
+/**/ 0xF024E808, 0x3FD98C52,
+/**/ 0x00000000, 0x3FF14000,
+/**/ 0xD8FF01DE, 0x3F7D8617,
+/**/ 0x00000000, 0x3FD92000,
+/**/ 0x2B5B4A9A, 0x3FF16589,
+/**/ 0xA8C0A8C6, 0x3FD025D0,
+/**/ 0xF524E4B6, 0x3FD5347E,
+/**/ 0xF565EDBD, 0x3FD2AA3B,
+/**/ 0xC98D2842, 0x3FD7689A,
+/**/ 0xB128B4DD, 0x3FDC108F,
+/**/ 0x4452A669, 0xBC8A5EEB,
+/**/ 0x04239878, 0x3FD9D1D9,
+/**/ 0x00000000, 0x3FF18000,
+/**/ 0xA4B56661, 0xBF7A76D4,
+/**/ 0x00000000, 0x3FD96000,
+/**/ 0x0DD68BC8, 0x3FF16DAC,
+/**/ 0x0EC54C3A, 0x3FD065DF,
+/**/ 0x30C58A12, 0x3FD58014,
+/**/ 0xBBCBCCEF, 0x3FD320F0,
+/**/ 0xD218F380, 0x3FD81410,
+/**/ 0xC9371D29, 0x3FDD189C,
+/**/ 0x1D6E6EC7, 0x3C58C3C1,
+/**/ 0x63E8EF18, 0x3FDA177F,
+/**/ 0x00000000, 0x3FF18000,
+/**/ 0x29743866, 0xBF7253F2,
+/**/ 0x00000000, 0x3FD9A000,
+/**/ 0x30AC48A8, 0x3FF175EF,
+/**/ 0x037BA7C0, 0x3FD0A6D3,
+/**/ 0x06EDCD18, 0x3FD5CD8B,
+/**/ 0x7D679188, 0x3FD39B0E,
+/**/ 0xC8128143, 0x3FD8C5D8,
+/**/ 0x39B3613A, 0x3FDE2BF6,
+/**/ 0xC70C9C76, 0xBC874080,
+/**/ 0x8F92A560, 0x3FDA5D46,
+/**/ 0x00000000, 0x3FF18000,
+/**/ 0xA76EB06E, 0xBF64219E,
+/**/ 0x00000000, 0x3FD9E000,
+/**/ 0x08107EEF, 0x3FF17E53,
+/**/ 0x40691386, 0x3FD0E8B2,
+/**/ 0x5BA2319A, 0x3FD61CF1,
+/**/ 0x7FF30656, 0x3FD418B5,
+/**/ 0x24624146, 0x3FD97E38,
+/**/ 0xF30D6589, 0x3FDF4B2C,
+/**/ 0x74DD0C9B, 0xBC8D4AD9,
+/**/ 0x090998F8, 0x3FDAA32F,
+/**/ 0x00000000, 0x3FF18000,
+/**/ 0xF81116BC, 0xBF3ACF7E,
+/**/ 0x00000000, 0x3FDA2000,
+/**/ 0x0B1E7A9D, 0x3FF186D8,
+/**/ 0xA98356F0, 0x3FD12B82,
+/**/ 0x96C051D8, 0x3FD66E55,
+/**/ 0x6D28A49D, 0x3FD49A07,
+/**/ 0xDE14D616, 0x3FDA3D77,
+/**/ 0x13502F53, 0x3FE03B6D,
+/**/ 0x4AD59707, 0x3CA51700,
+/**/ 0x540D3F08, 0x3FDAE939,
+/**/ 0x00000000, 0x3FF18000,
+/**/ 0x79EA752F, 0x3F5B602C,
+/**/ 0x00000000, 0x3FDA6000,
+/**/ 0xB3EE7285, 0x3FF18F7E,
+/**/ 0x4EC4AF40, 0x3FD16F4A,
+/**/ 0xA9B275FD, 0x3FD6C1C6,
+/**/ 0x64B886B9, 0x3FD51F27,
+/**/ 0x9D72A144, 0x3FDB03E4,
+/**/ 0xE7207DD5, 0x3FE0D7CF,
+/**/ 0x8E77D1B2, 0xBCAACE1E,
+/**/ 0xF63F6C78, 0x3FDB2F65,
+/**/ 0x00000000, 0x3FF18000,
+/**/ 0xDCE509F5, 0x3F6EFD67,
+/**/ 0x00000000, 0x3FDAA000,
+/**/ 0x7FABF325, 0x3FF19847,
+/**/ 0x6DD15EDB, 0x3FD1B40F,
+/**/ 0x156D090D, 0x3FD71754,
+/**/ 0x0F44EE42, 0x3FD5A83A,
+/**/ 0xF26149CC, 0x3FDBD1CE,
+/**/ 0x9EBB7D53, 0x3FE17B14,
+/**/ 0x054C177A, 0x3CA18867,
+/**/ 0x773075F8, 0x3FDB75B5,
+/**/ 0x00000000, 0x3FF18000,
+/**/ 0xABF3257B, 0x3F78477F,
+/**/ 0x00000000, 0x3FDAE000,
+/**/ 0xEEAD20E6, 0x3FF1A132,
+/**/ 0x73AFA8F4, 0x3FD1F9D8,
+/**/ 0xF0BA2B44, 0x3FD76F0D,
+/**/ 0xB2776412, 0x3FD63565,
+/**/ 0x8E4B8181, 0x3FDCA78B,
+/**/ 0xDE92725A, 0x3FE22595,
+/**/ 0x225EE470, 0xBCABDA45,
+/**/ 0x606BABE0, 0x3FDBBC28,
+/**/ 0x00000000, 0x3FF1C000,
+/**/ 0x52DF1A7E, 0xBF7ECD11,
+/**/ 0x00000000, 0x3FDB2000,
+/**/ 0x848ADB16, 0x3FF1AA41,
+/**/ 0xFE932ABB, 0x3FD240AB,
+/**/ 0xEED7E85D, 0x3FD7C904,
+/**/ 0x4640B1B3, 0x3FD6C6D2,
+/**/ 0x81D01020, 0x3FDD8573,
+/**/ 0x9938B939, 0x3FE2D7B3,
+/**/ 0x36D76E02, 0x3CA12ECB,
+/**/ 0x3D843430, 0x3FDC02BF,
+/**/ 0x00000000, 0x3FF1C000,
+/**/ 0x7524EA70, 0xBF75BE7B,
+/**/ 0x00000000, 0x3FDB6000,
+/**/ 0xC839C9AC, 0x3FF1B373,
+/**/ 0xDFBC912D, 0x3FD28890,
+/**/ 0x666DE3CA, 0x3FD8254A,
+/**/ 0x8B57457C, 0x3FD75CA9,
+/**/ 0x7E7E55FE, 0x3FDE6BE4,
+/**/ 0x68EC3777, 0x3FE391D3,
+/**/ 0x4D8A80A5, 0xBC9F7EFE,
+/**/ 0x9C2247A0, 0x3FDC497A,
+/**/ 0x00000000, 0x3FF1C000,
+/**/ 0x8C6CA8A7, 0xBF69186F,
+/**/ 0x00000000, 0x3FDBA000,
+/**/ 0x44246029, 0x3FF1BCCA,
+/**/ 0x1D6EB966, 0x3FD2D18E,
+/**/ 0x58DF9E20, 0x3FD883F0,
+/**/ 0x2308FF84, 0x3FD7F717,
+/**/ 0x1CEC1692, 0x3FDF5B41,
+/**/ 0xEFAE7F7E, 0x3FE45460,
+/**/ 0xC247C281, 0xBCACA88A,
+/**/ 0x0C10D428, 0x3FDC905B,
+/**/ 0x00000000, 0x3FF1C000,
+/**/ 0xDCFEB6F6, 0xBF49ADDE,
+/**/ 0x00000000, 0x3FDBE000,
+/**/ 0x8645E0A6, 0x3FF1C645,
+/**/ 0xF4FA598C, 0x3FD31BAA,
+/**/ 0x7A00CDBD, 0x3FD8E509,
+/**/ 0xA876EFA4, 0x3FD89648,
+/**/ 0x93BB3BA0, 0x3FE029F8,
+/**/ 0x3E769492, 0x3FE51FCE,
+/**/ 0xDAC78BA6, 0xBC63BD0A,
+/**/ 0x1F4B8A08, 0x3FDCD761,
+/**/ 0x00000000, 0x3FF1C000,
+/**/ 0x178298DB, 0x3F591619,
+/**/ 0x00000000, 0x3FDC2000,
+/**/ 0x20466A93, 0x3FF1CFE6,
+/**/ 0xDCE16113, 0x3FD366EE,
+/**/ 0x3831A262, 0x3FD948A9,
+/**/ 0xCB5336B7, 0x3FD93A6D,
+/**/ 0xF50362A5, 0x3FE0AB30,
+/**/ 0x440F45E4, 0x3FE5F494,
+/**/ 0x79A811B8, 0xBCA1B23F,
+/**/ 0x6A0D56C8, 0x3FDD1E8D,
+/**/ 0x00000000, 0x3FF1C000,
+/**/ 0x8CD52690, 0x3F6FCC40,
+/**/ 0x00000000, 0x3FDC6000,
+/**/ 0xA798215A, 0x3FF1D9AC,
+/**/ 0x87135170, 0x3FD3B361,
+/**/ 0xC4E92F90, 0x3FD9AEE3,
+/**/ 0x6C3B0A06, 0x3FD9E3B8,
+/**/ 0x439D6983, 0x3FE13183,
+/**/ 0x444347EE, 0x3FE6D333,
+/**/ 0x141D7ADE, 0x3C9E6687,
+/**/ 0x82DF5278, 0x3FDD65E0,
+/**/ 0x00000000, 0x3FF1C000,
+/**/ 0x98215A4D, 0x3F79ACA7,
+/**/ 0x00000000, 0x3FDCA000,
+/**/ 0xB59577B1, 0x3FF1E399,
+/**/ 0xE343E389, 0x3FD4010A,
+/**/ 0x1DB4A57B, 0x3FDA17CE,
+/**/ 0xBAC8CA27, 0x3FDA925C,
+/**/ 0x29AC5009, 0x3FE1BD2C,
+/**/ 0x5806ABBE, 0x3FE7BC33,
+/**/ 0xD953CBEA, 0x3C89743A,
+/**/ 0x02A82420, 0x3FDDAD5B,
+/**/ 0x00000000, 0x3FF20000,
+/**/ 0x6A884EAF, 0xBF7C664A,
+/**/ 0x00000000, 0x3FDCE000,
+/**/ 0xE7A0AD1E, 0x3FF1EDAD,
+/**/ 0x215D62D8, 0x3FD44FF3,
+/**/ 0x15B2742E, 0x3FDA837E,
+/**/ 0x557C3A62, 0x3FDB4691,
+/**/ 0x9ABECCA0, 0x3FE24E6B,
+/**/ 0xF75D3619, 0x3FE8B024,
+/**/ 0x953C1F21, 0xBC60A42B,
+/**/ 0x84BBE168, 0x3FDDF4FD,
+/**/ 0x00000000, 0x3FF20000,
+/**/ 0x5F52E269, 0xBF725218,
+/**/ 0x00000000, 0x3FDD2000,
+/**/ 0xDF448BE1, 0x3FF1F7E9,
+/**/ 0xB4103D45, 0x3FD4A022,
+/**/ 0x5F90F152, 0x3FDAF20A,
+/**/ 0x6B992E26, 0x3FDC008F,
+/**/ 0x07C18F30, 0x3FE2E585,
+/**/ 0x8DCE89C2, 0x3FE9AFA1,
+/**/ 0xE5B4E0DD, 0xBC8B90A5,
+/**/ 0xA6EC6EF0, 0x3FDE3CC8,
+/**/ 0x00000000, 0x3FF20000,
+/**/ 0x76E83DEE, 0xBF602C41,
+/**/ 0x00000000, 0x3FDD6000,
+/**/ 0x42567651, 0x3FF2024E,
+/**/ 0x53815E48, 0x3FD4F1A2,
+/**/ 0x98189F26, 0x3FDB638A,
+/**/ 0xE11F7BB9, 0x3FDCC092,
+/**/ 0x968E1C3C, 0x3FE382BF,
+/**/ 0x1A4C4551, 0x3FEABB4C,
+/**/ 0xC65EE1E9, 0xBCAC384D,
+/**/ 0x099A6620, 0x3FDE84BD,
+/**/ 0x00000000, 0x3FF20000,
+/**/ 0xB3B2877E, 0x3F427212,
+/**/ 0x00000000, 0x3FDDA000,
+/**/ 0xBB19D366, 0x3FF20CDB,
+/**/ 0x00190520, 0x3FD5447B,
+/**/ 0x514AC3D7, 0x3FDBD817,
+/**/ 0x7501B24E, 0x3FDD86DA,
+/**/ 0x5D5DCC91, 0x3FE42666,
+/**/ 0xDB834BBA, 0x3FEBD3D1,
+/**/ 0x64307FE4, 0xBCA62892,
+/**/ 0x4FC685E0, 0x3FDECCDB,
+/**/ 0x00000000, 0x3FF20000,
+/**/ 0x33A6CD00, 0x3F69B776,
+/**/ 0x00000000, 0x3FDDE000,
+/**/ 0xF864EB38, 0x3FF21792,
+/**/ 0x0573E0CA, 0x3FD598B6,
+/**/ 0x1E1D9C05, 0x3FDC4FCA,
+/**/ 0xE9C2FB44, 0x3FDE53A7,
+/**/ 0xA26E99AF, 0x3FE4D0C8,
+/**/ 0x09A8A359, 0x3FECF9EB,
+/**/ 0xD9AFA9E0, 0xBCADF861,
+/**/ 0x1F23B3F8, 0x3FDF1524,
+/**/ 0x00000000, 0x3FF20000,
+/**/ 0x64EB3836, 0x3F7792F8,
+/**/ 0x00000000, 0x3FDE2000,
+/**/ 0xADC744F8, 0x3FF22274,
+/**/ 0xFD785957, 0x3FD5EE5C,
+/**/ 0x9EE01B3A, 0x3FDCCABD,
+/**/ 0x30A7B7B5, 0x3FDF2740,
+/**/ 0x202E0D0D, 0x3FE5823A,
+/**/ 0x9EEBE829, 0x3FEE2E5B,
+/**/ 0xE2EA9787, 0xBC93BB42,
+/**/ 0x202994B8, 0x3FDF5D98,
+/**/ 0x00000000, 0x3FF24000,
+/**/ 0x38BB0864, 0xBF7D8B52,
+/**/ 0x00000000, 0x3FDE6000,
+/**/ 0x93B1990A, 0x3FF22D81,
+/**/ 0xD3920D0F, 0x3FD64579,
+/**/ 0x8E4FE1FE, 0x3FDD490D,
+/**/ 0xCBD3ED59, 0x3FE000F5,
+/**/ 0x4E45F774, 0x3FE63B13,
+/**/ 0x2FD578CE, 0x3FEF71F4,
+/**/ 0xC0E1AC47, 0x3CA8AD1C,
+/**/ 0xFE27BF60, 0x3FDFA637,
+/**/ 0x00000000, 0x3FF24000,
+/**/ 0x4E66F5A1, 0xBF727E6C,
+/**/ 0x00000000, 0x3FDEA000,
+/**/ 0x679F6AE1, 0x3FF238BA,
+/**/ 0xC815A8F5, 0x3FD69E16,
+/**/ 0xCF6CD4C9, 0x3FDDCAD6,
+/**/ 0xFD2ADE38, 0x3FE071FA,
+/**/ 0xAFEE9630, 0x3FE6FBB1,
+/**/ 0x6A7ACB82, 0x3FF062C9,
+/**/ 0x35D3555B, 0x3C7E3580,
+/**/ 0x67599588, 0x3FDFEF04,
+/**/ 0x00000000, 0x3FF24000,
+/**/ 0x82547B6F, 0xBF5D1661,
+/**/ 0x00000000, 0x3FDEE000,
+/**/ 0xEC425F4B, 0x3FF2441F,
+/**/ 0x73CF67B4, 0x3FD6F83E,
+/**/ 0x7C1691BA, 0x3FDE5037,
+/**/ 0x7AF8190E, 0x3FE0E6D7,
+/**/ 0x27F29078, 0x3FE7C478,
+/**/ 0x13B5FFDC, 0x3FF11512,
+/**/ 0x5FEBA301, 0x3C6CC7A1,
+/**/ 0x067D6224, 0x3FE01BFF,
+/**/ 0x00000000, 0x3FF24000,
+/**/ 0x097D2BDC, 0x3F507FB1,
+/**/ 0x00000000, 0x3FDF2000,
+/**/ 0xE9AF6533, 0x3FF24FB2,
+/**/ 0xCBBEA804, 0x3FD753FB,
+/**/ 0xF480E731, 0x3FDED94E,
+/**/ 0x106D90C6, 0x3FE15FB5,
+/**/ 0x52DAD430, 0x3FE895CF,
+/**/ 0x28FAAE13, 0x3FF1D052,
+/**/ 0xE849F35A, 0xBCA50976,
+/**/ 0xD1AE3B48, 0x3FE04092,
+/**/ 0x00000000, 0x3FF24000,
+/**/ 0x5ECA665D, 0x3F6F65D3,
+/**/ 0x00000000, 0x3FDF6000,
+/**/ 0x2D8DC7FA, 0x3FF25B74,
+/**/ 0x25013475, 0x3FD7B15A,
+/**/ 0xEF8D6387, 0x3FDF663D,
+/**/ 0xA2DF4BFF, 0x3FE1DCBF,
+/**/ 0xE7C2E4E5, 0x3FE97025,
+/**/ 0x1C2AE4AB, 0x3FF29510,
+/**/ 0xB02A3D13, 0x3CA4C8DC,
+/**/ 0xF0FD9FD8, 0x3FE0653D,
+/**/ 0x00000000, 0x3FF24000,
+/**/ 0x8DC7FA40, 0x3F7B742D,
+/**/ 0x00000000, 0x3FDFA000,
+/**/ 0x8B4843F2, 0x3FF26764,
+/**/ 0x38F10257, 0x3FD81065,
+/**/ 0x8C1920B1, 0x3FDFF726,
+/**/ 0x5148D4E4, 0x3FE25E25,
+/**/ 0x2061C3FE, 0x3FEA53F1,
+/**/ 0x5B9300E5, 0x3FF363DB,
+/**/ 0x624B8B97, 0xBCA47774,
+/**/ 0xC1CAE338, 0x3FE08A00,
+/**/ 0x00000000, 0x3FF28000,
+/**/ 0xB7BC0E50, 0xBF789B74,
+/**/ 0x00000000, 0x3FDFE000,
+/**/ 0xDC4036F2, 0x3FF27384,
+/**/ 0x29775C8F, 0x3FD87129,
+/**/ 0x31A78776, 0x3FE04616,
+/**/ 0x95EE0C65, 0x3FE2E416,
+/**/ 0x28E05161, 0x3FEB41AD,
+/**/ 0xFF1DF849, 0x3FF43D4C,
+/**/ 0xBABBA919, 0x3CA5941C,
+/**/ 0xA3221C1C, 0x3FE0AEDB,
+/**/ 0x00000000, 0x3FF28000,
+/**/ 0x7F921C27, 0xBF68F647,
+/**/ 0x00000000, 0x3FE01000,
+/**/ 0x00030888, 0x3FF27FD6,
+/**/ 0x8598A1B5, 0x3FD8D3B2,
+/**/ 0x4E0BC755, 0x3FE092BA,
+/**/ 0x6A428EEC, 0x3FE36EC6,
+/**/ 0x44F514C9, 0x3FEC39C0,
+/**/ 0x18C4EF3A, 0x3FF52205,
+/**/ 0xA852F235, 0x4000C1D1,
+/**/ 0xD00F64B8, 0x3CA78082,
+/**/ 0xF5C846F8, 0x3FE0D3CE,
+/**/ 0x00000000, 0x3FF28000,
+/**/ 0x7BBC39DF, 0xBF04FFFE,
+/**/ 0x00000000, 0x3FE03000,
+/**/ 0xDC81E6D7, 0x3FF28C58,
+/**/ 0x4E3BF356, 0x3FD9380E,
+/**/ 0xFFC646A7, 0x3FE0E192,
+/**/ 0x6D34756D, 0x3FE3FE6A,
+/**/ 0x139ABC91, 0x3FED3CEF,
+/**/ 0xF80111C0, 0x3FF612B8,
+/**/ 0x3467C688, 0x4001A33C,
+/**/ 0x34F59445, 0xBC8A9954,
+/**/ 0x1C47D550, 0x3FE0F8DB,
+/**/ 0x00000000, 0x3FF28000,
+/**/ 0x03CDAE3F, 0x3F68B1B9,
+/**/ 0x00000000, 0x3FE05000,
+/**/ 0x5E4BF713, 0x3FF2990E,
+/**/ 0xFB326E9E, 0x3FD99E49,
+/**/ 0x8779391A, 0x3FE132B4,
+/**/ 0x0C2FE325, 0x3FE4933B,
+/**/ 0xAEAAE1D0, 0x3FEE4BB1,
+/**/ 0x1F4377BD, 0x3FF71020,
+/**/ 0x1C886605, 0x40029271,
+/**/ 0x7130CE99, 0xBCA33AB1,
+/**/ 0x7AFDAF10, 0x3FE11E00,
+/**/ 0x00000000, 0x3FF28000,
+/**/ 0x4BF712C7, 0x3F790E5E,
+/**/ 0x00000000, 0x3FE07000,
+/**/ 0x78CB1A3B, 0x3FF2A5F7,
+/**/ 0x8081C5D1, 0x3FDA0673,
+/**/ 0x0D5E6499, 0x3FE18634,
+/**/ 0xAEDD6BE6, 0x3FE52D73,
+/**/ 0x1CF1AAA0, 0x3FEF66A5,
+/**/ 0x4834E5A9, 0x3FF81B02,
+/**/ 0xFCE48906, 0x40039066,
+/**/ 0x6BFB4C85, 0xBCA34E4F,
+/**/ 0x7826AAD4, 0x3FE1433F,
+/**/ 0x00000000, 0x3FF2C000,
+/**/ 0x34E5C574, 0xBF7A0887,
+/**/ 0x00000000, 0x3FE09000,
+/**/ 0x268368DB, 0x3FF2B315,
+/**/ 0x53F655B7, 0x3FDA7099,
+/**/ 0xAD9032EC, 0x3FE1DC27,
+/**/ 0xE5F88E23, 0x3FE5CD52,
+/**/ 0x0A68BDFC, 0x3FF04738,
+/**/ 0x2F057820, 0x3FF93435,
+/**/ 0xDAE8A2FC, 0x40049E27,
+/**/ 0xFAA44565, 0x3C86832C,
+/**/ 0x7BED8260, 0x3FE16898,
+/**/ 0x00000000, 0x3FF2C000,
+/**/ 0xF92E4A41, 0xBF69D5B2,
+/**/ 0x00000000, 0x3FE0B000,
+/**/ 0x69558A9E, 0x3FF2C068,
+/**/ 0x73011B64, 0x3FDADCCA,
+/**/ 0x8511146A, 0x3FE234A6,
+/**/ 0x9D6CBF3C, 0x3FE6731A,
+/**/ 0xD575F00A, 0x3FF0E1E1,
+/**/ 0xADEA17E7, 0x3FFA5C9D,
+/**/ 0xD9123E7C, 0x4005BCD2,
+/**/ 0xCC2AE1E4, 0xBCA23E4F,
+/**/ 0xF07948F0, 0x3FE18E0B,
+/**/ 0x00000000, 0x3FF2C000,
+/**/ 0x62A7614A, 0x3F1A1A55,
+/**/ 0x00000000, 0x3FE0D000,
+/**/ 0x4AC410C6, 0x3FF2CDF2,
+/**/ 0x68E63D97, 0x3FDB4B16,
+/**/ 0xBFA256B2, 0x3FE28FC8,
+/**/ 0x51FDF05A, 0x3FE71F10,
+/**/ 0x0753C882, 0x3FF183AE,
+/**/ 0xF1921090, 0x3FFB9530,
+/**/ 0x14F942BC, 0x4006ED9E,
+/**/ 0x89C77FA3, 0x3CA27879,
+/**/ 0x41FC691C, 0x3FE1B39A,
+/**/ 0x00000000, 0x3FF2C000,
+/**/ 0x88218CD6, 0x3F6BE495,
+/**/ 0x00000000, 0x3FE0F000,
+/**/ 0xDC3BFD25, 0x3FF2DBB3,
+/**/ 0x55413207, 0x3FDBBB8D,
+/**/ 0xA6792BF1, 0x3FE2EDA7,
+/**/ 0x4AC4E230, 0x3FE7D17D,
+/**/ 0xAAE6CB05, 0x3FF22D00,
+/**/ 0xC9028E71, 0x3FFCDEF5,
+/**/ 0xB40C626C, 0x400831D8,
+/**/ 0x9873F484, 0x3C953FEF,
+/**/ 0xDEC430C0, 0x3FE1D943,
+/**/ 0x00000000, 0x3FF2C000,
+/**/ 0x3BFD24A1, 0x3F7BB3DC,
+/**/ 0x00000000, 0x3FE11000,
+/**/ 0x3760A19B, 0x3FF2E9AE,
+/**/ 0xF2E3E2EB, 0x3FDC2E3F,
+/**/ 0xAFE1CD38, 0x3FE34E5D,
+/**/ 0xD6CE0B26, 0x3FE88AAE,
+/**/ 0x2C4B06C6, 0x3FF2DE44,
+/**/ 0x138813D2, 0x3FFE3B06,
+/**/ 0x23FD5612, 0x40098AED,
+/**/ 0xB7AF0E54, 0xBC91EC19,
+/**/ 0x3748F114, 0x3FE1FF09,
+/**/ 0x00000000, 0x3FF30000,
+/**/ 0x9F5E657E, 0xBF7651C8,
+/**/ 0x00000000, 0x3FE13000,
+/**/ 0x7E5B072B, 0x3FF2F7E2,
+/**/ 0x9F169C4D, 0x3FDCA33F,
+/**/ 0x8FE1EB56, 0x3FE3B206,
+/**/ 0x8F30E1B7, 0x3FE94AF6,
+/**/ 0xCFCF9887, 0x3FF397E9,
+/**/ 0x4FB7F25F, 0x3FFFAA90,
+/**/ 0x94745D90, 0x400AFA63,
+/**/ 0x2A139390, 0x3C96955C,
+/**/ 0xBE3EBA20, 0x3FE224EA,
+/**/ 0x00000000, 0x3FF30000,
+/**/ 0x49F1AA85, 0xBF603B03,
+/**/ 0x00000000, 0x3FE15000,
+/**/ 0xDC2D0E76, 0x3FF30651,
+/**/ 0x613EF408, 0x3FDD1A9E,
+/**/ 0x49ED083D, 0x3FE418BF,
+/**/ 0x9DFD1E23, 0x3FEA12AA,
+/**/ 0x32B75F76, 0x3FF45A6A,
+/**/ 0xA7673F47, 0x4000976C,
+/**/ 0xB046AC6A, 0x400C81E4,
+/**/ 0x7D1BEB80, 0x3C879FF7,
+/**/ 0xE8A6B8B0, 0x3FE24AE8,
+/**/ 0x00000000, 0x3FF30000,
+/**/ 0xB439D90E, 0x3F594770,
+/**/ 0x00000000, 0x3FE17000,
+/**/ 0x85087ECD, 0x3FF314FD,
+/**/ 0xF2F45390, 0x3FDD946E,
+/**/ 0x43BEDA05, 0x3FE482A6,
+/**/ 0x0A640DD7, 0x3FEAE226,
+/**/ 0xD6A3D695, 0x3FF52645,
+/**/ 0x08098FE0, 0x4001649F,
+/**/ 0x9D2BADE7, 0x400E233C,
+/**/ 0x4E5F8348, 0x3C9E948C,
+/**/ 0x2DE13E58, 0x3FE27104,
+/**/ 0x00000000, 0x3FF30000,
+/**/ 0x087ECD1A, 0x3F74FD85,
+/**/ 0x00000000, 0x3FE19000,
+/**/ 0xB6AA3C67, 0x3FF323E6,
+/**/ 0xC8894828, 0x3FDE10C4,
+/**/ 0x59718389, 0x3FE4EFDB,
+/**/ 0x0A8D7622, 0x3FEBB9C9,
+/**/ 0xB8A62B12, 0x3FF5FC05,
+/**/ 0xE4296831, 0x40023D9A,
+/**/ 0x49C0B830, 0x400FE05E,
+/**/ 0xC1189DE8, 0x3CA19107,
+/**/ 0x07C07BCC, 0x3FE2973D,
+/**/ 0x00000000, 0x3FF34000,
+/**/ 0x55C3993D, 0xBF7C1949,
+/**/ 0x00000000, 0x3FE1B000,
+/**/ 0xB8B9E20B, 0x3FF3330E,
+/**/ 0x1A11468B, 0x3FDE8FB4,
+/**/ 0xF2E740E1, 0x3FE5607F,
+/**/ 0x5B91DB14, 0x3FEC99F9,
+/**/ 0xF50C5FAA, 0x3FF6DC3B,
+/**/ 0x0CFAC1C7, 0x4003232A,
+/**/ 0x894EFD30, 0x4010DDB3,
+/**/ 0x3783D916, 0xBCA7760F,
+/**/ 0xF29BF5F0, 0x3FE2BD93,
+/**/ 0x00000000, 0x3FF34000,
+/**/ 0x8C3BEA7F, 0xBF69E28E,
+/**/ 0x00000000, 0x3FE1D000,
+/**/ 0xDD2DFE6D, 0x3FF34276,
+/**/ 0xECEB226B, 0x3FDF1151,
+/**/ 0x1AA123CE, 0x3FE5D4B7,
+/**/ 0xA01F65F8, 0x3FED8322,
+/**/ 0x791CE583, 0x3FF7C784,
+/**/ 0xC15A6B9C, 0x40041625,
+/**/ 0x64280FEB, 0x4011DB51,
+/**/ 0x28CA6DBB, 0x3CA10463,
+/**/ 0x6D64BEAC, 0x3FE2E409,
+/**/ 0x00000000, 0x3FF34000,
+/**/ 0x6FF364E1, 0x3F43B6E9,
+/**/ 0x00000000, 0x3FE1F000,
+/**/ 0x80B539C7, 0x3FF35220,
+/**/ 0x1DD91A82, 0x3FDF95B4,
+/**/ 0x961EA9CA, 0x3FE64CA5,
+/**/ 0xC65B3B2F, 0x3FEE75B6,
+/**/ 0xC412E59F, 0x3FF8BE85,
+/**/ 0x02462A51, 0x40051778,
+/**/ 0x109FC81B, 0x4012EA48,
+/**/ 0x9F70CA98, 0x3C959E4C,
+/**/ 0xF9BA7B3C, 0x3FE30A9D,
+/**/ 0x00000000, 0x3FF34000,
+/**/ 0xB539C6A2, 0x3F722080,
+/**/ 0x00000000, 0x3FE21000,
+/**/ 0x0B24ACDA, 0x3FF3620D,
+/**/ 0xB5D803B6, 0x3FE00E78,
+/**/ 0xFFE457FB, 0x3FE6C871,
+/**/ 0x759EF386, 0x3FEF722E,
+/**/ 0xB8D0E874, 0x3FF9C1F1,
+/**/ 0x080FB06E, 0x4006281D,
+/**/ 0xD1F69DF7, 0x40140BF2,
+/**/ 0xCBFAF37F, 0xBC8489EA,
+/**/ 0x1C0141BC, 0x3FE33152,
+/**/ 0x00000000, 0x3FF38000,
+/**/ 0xDB532667, 0xBF7DF2F4,
+/**/ 0x00000000, 0x3FE23000,
+/**/ 0xEFEBB76D, 0x3FF3723D,
+/**/ 0xC153FC4C, 0x3FE05390,
+/**/ 0xE34A2666, 0x3FE74844,
+/**/ 0xC260A400, 0x3FF03C84,
+/**/ 0x81E70F01, 0x3FFAD286,
+/**/ 0xDBC4A78E, 0x40074924,
+/**/ 0x8BBCA2E0, 0x401541CB,
+/**/ 0x7BEA8472, 0x3C9C7528,
+/**/ 0x5B7858F8, 0x3FE35826,
+/**/ 0x00000000, 0x3FF38000,
+/**/ 0x28912510, 0xBF6B8420,
+/**/ 0x00000000, 0x3FE25000,
+/**/ 0xAE8DA9C7, 0x3FF382B4,
+/**/ 0x842CABB9, 0x3FE09A2E,
+/**/ 0xDA356141, 0x3FE7CC48,
+/**/ 0xBCD4FDB8, 0x3FF0C567,
+/**/ 0x89B62C32, 0x3FFBF10F,
+/**/ 0x18ADC4B9, 0x40087BB5,
+/**/ 0xC516F6F1, 0x40168D6D,
+/**/ 0x2E37D6A3, 0xBC933A6B,
+/**/ 0x4251E5AC, 0x3FE37F1B,
+/**/ 0x00000000, 0x3FF38000,
+/**/ 0x6D4E3A7A, 0x3F45A574,
+/**/ 0x00000000, 0x3FE27000,
+/**/ 0xD3219A4C, 0x3FF39372,
+/**/ 0xD4394437, 0x3FE0E25E,
+/**/ 0xACE4CC74, 0x3FE854AA,
+/**/ 0x0981EE13, 0x3FF15408,
+/**/ 0x88AA5332, 0x3FFD1E66,
+/**/ 0xDA3BD18F, 0x4009C10A,
+/**/ 0xFFE4AE21, 0x4017F099,
+/**/ 0x7B588ABE, 0xBCAED56B,
+/**/ 0x5DCB911C, 0x3FE3A631,
+/**/ 0x00000000, 0x3FF38000,
+/**/ 0x219A4BA9, 0x3F7372D3,
+/**/ 0x00000000, 0x3FE29000,
+/**/ 0xF6D8C6BC, 0x3FF3A479,
+/**/ 0x11197A32, 0x3FE12C2F,
+/**/ 0x73F949D5, 0x3FE8E199,
+/**/ 0xEE7A481D, 0x3FF1E8B1,
+/**/ 0xABBE8828, 0x3FFE5B74,
+/**/ 0xDB3D83BC, 0x400B1A7C,
+/**/ 0x6DC46100, 0x40196D39,
+/**/ 0xACD8F69C, 0x3CA7798C,
+/**/ 0x3E4835E8, 0x3FE3CD69,
+/**/ 0x00000000, 0x3FF3C000,
+/**/ 0x27394391, 0xBF7B8609,
+/**/ 0x00000000, 0x3FE2B000,
+/**/ 0xC08BE738, 0x3FF3B5CB,
+/**/ 0x2B5CB6B7, 0x3FE177AD,
+/**/ 0xBCE90EB1, 0x3FE97346,
+/**/ 0x68EC7F04, 0x3FF283B6,
+/**/ 0xD5B8ED04, 0x3FFFA933,
+/**/ 0xCBCDFF9A, 0x400C897D,
+/**/ 0x0E4ABF55, 0x401B0562,
+/**/ 0x1EE42043, 0x3C881FF6,
+/**/ 0x776AA08C, 0x3FE3F4C3,
+/**/ 0x00000000, 0x3FF3C000,
+/**/ 0xE8319086, 0xBF64687E,
+/**/ 0x00000000, 0x3FE2D000,
+/**/ 0xE54FE05E, 0x3FF3C769,
+/**/ 0xAC1A81A0, 0x3FE1C4E7,
+/**/ 0xB10FA326, 0x3FEA09E6,
+/**/ 0x840F679B, 0x3FF3256B,
+/**/ 0xFEE9EF1A, 0x40008457,
+/**/ 0xE4146343, 0x400E0F9E,
+/**/ 0x433496A9, 0x401CBB5B,
+/**/ 0x59F087C0, 0xBCA57A4C,
+/**/ 0xA03171A8, 0x3FE41C40,
+/**/ 0x00000000, 0x3FF3C000,
+/**/ 0x3F81773D, 0x3F5DA795,
+/**/ 0x00000000, 0x3FE2F000,
+/**/ 0x291249DC, 0x3FF3D956,
+/**/ 0xBD044AC9, 0x3FE213ED,
+/**/ 0x3F917FA8, 0x3FEAA5B0,
+/**/ 0xB7380A79, 0x3FF3CE2C,
+/**/ 0x576AFAE8, 0x40013D84,
+/**/ 0xBAAB74F3, 0x400FAE92,
+/**/ 0xE9129E4A, 0x401E91A2,
+/**/ 0x0CEC83F7, 0x3C905671,
+/**/ 0x53143194, 0x3FE443E1,
+/**/ 0x00000000, 0x3FF3C000,
+/**/ 0x1249DBC4, 0x3F795629,
+/**/ 0x00000000, 0x3FE31000,
+/**/ 0x5F3E4715, 0x3FF3EB92,
+/**/ 0x30F965D1, 0x3FE264CF,
+/**/ 0x4A4F2FB2, 0x3FEB46DD,
+/**/ 0x4BC2E94F, 0x3FF47E5B,
+/**/ 0x54F8F9EB, 0x400200B9,
+/**/ 0x33305D9F, 0x4010B418,
+/**/ 0x826EF167, 0x40204579,
+/**/ 0xE06EBCAE, 0xBC9737A0,
+/**/ 0x2E21A53C, 0x3FE46BA6,
+/**/ 0x00000000, 0x3FF40000,
+/**/ 0xC1B8EB04, 0xBF746DA0,
+/**/ 0x00000000, 0x3FE33000,
+/**/ 0x6B6A38D5, 0x3FF3FE20,
+/**/ 0x8D26C7A0, 0x3FE2B79C,
+/**/ 0xD62978F8, 0x3FEBEDAA,
+/**/ 0xCB8CC6D1, 0x3FF5365E,
+/**/ 0xD894AF54, 0x4002CE9C,
+/**/ 0x79F7C63E, 0x40119F3B,
+/**/ 0x0C8E7B9E, 0x40215524,
+/**/ 0x13DC9A80, 0x3CA485D0,
+/**/ 0xD31F754C, 0x3FE4938F,
+/**/ 0x00000000, 0x3FF40000,
+/**/ 0x5C72B1E7, 0xBF3DF949,
+/**/ 0x00000000, 0x3FE35000,
+/**/ 0x420ED8E7, 0x3FF41102,
+/**/ 0x12BCE2B2, 0x3FE30C67,
+/**/ 0x3EDE345E, 0x3FEC9A59,
+/**/ 0x78CAB466, 0x3FF5F6A5,
+/**/ 0x3EAD62EE, 0x4003A7E1,
+/**/ 0x9CB9A228, 0x401299C8,
+/**/ 0x1BE749B0, 0x40227974,
+/**/ 0xC6A9831F, 0x3CAFE28F,
+/**/ 0xE7AB3A40, 0x3FE4BB9E,
+/**/ 0x00000000, 0x3FF40000,
+/**/ 0x0ED8E776, 0x3F710242,
+/**/ 0x00000000, 0x3FE37000,
+/**/ 0xE9485B43, 0x3FF42439,
+/**/ 0xC946E033, 0x3FE36340,
+/**/ 0x6ECC5A7E, 0x3FED4D2C,
+/**/ 0xD027255A, 0x3FF6BFA4,
+/**/ 0x72504BE1, 0x40048D46,
+/**/ 0x09445BD5, 0x4013A4ED,
+/**/ 0x749E19F9, 0x4023B435,
+/**/ 0xEAAAF53E, 0xBC40E7E5,
+/**/ 0x155D0070, 0x3FE4E3D4,
+/**/ 0x00000000, 0x3FF44000,
+/**/ 0xB7A4BD36, 0xBF7BC616,
+/**/ 0x00000000, 0x3FE39000,
+/**/ 0x79A23C23, 0x3FF437C9,
+/**/ 0x89AF6A9D, 0x3FE3BC3C,
+/**/ 0x1AF553BA, 0x3FEE066C,
+/**/ 0x1622569A, 0x3FF791DA,
+/**/ 0x1B18AE2B, 0x40057F9B,
+/**/ 0x88BFF240, 0x4014C1F0,
+/**/ 0x019A4522, 0x40250761,
+/**/ 0xFDFCCB13, 0x3CA4C238,
+/**/ 0x09EB58F8, 0x3FE50C30,
+/**/ 0x00000000, 0x3FF44000,
+/**/ 0xBB87B9E1, 0xBF606D0C,
+/**/ 0x00000000, 0x3FE3B000,
+/**/ 0x1EEE6F35, 0x3FF44BB3,
+/**/ 0x0A004D1D, 0x3FE4176E,
+/**/ 0x0399FA54, 0x3FEEC664,
+/**/ 0xF0CFD106, 0x3FF86DCA,
+/**/ 0xE8C80E97, 0x40067FBD,
+/**/ 0xD9CD2D79, 0x4015F237,
+/**/ 0xC8076345, 0x40267521,
+/**/ 0xB089F7AF, 0x3CAEC756,
+/**/ 0x77510D94, 0x3FE534B3,
+/**/ 0x00000000, 0x3FF44000,
+/**/ 0xDCDE698F, 0x3F67663D,
+/**/ 0x00000000, 0x3FE3D000,
+/**/ 0x1928B1BE, 0x3FF45FF9,
+/**/ 0xE9EB53E9, 0x3FE474E9,
+/**/ 0x39DB03B6, 0x3FEF8D64,
+/**/ 0x0F298B87, 0x3FF95406,
+/**/ 0xFFC72AB6, 0x40078E9E,
+/**/ 0x941456E7, 0x40173747,
+/**/ 0x74A71E71, 0x4027FFDA,
+/**/ 0xFE7483B3, 0xBCAEED93,
+/**/ 0x13F48EC0, 0x3FE55D5F,
+/**/ 0x00000000, 0x3FF44000,
+/**/ 0x28B1BDFF, 0x3F7FF919,
+/**/ 0x00000000, 0x3FE3F000,
+/**/ 0xBD66D0C4, 0x3FF4749D,
+/**/ 0xC02C2013, 0x3FE4D4C5,
+/**/ 0xB56768CC, 0x3FF02DE0,
+/**/ 0xDF53A7BD, 0x3FFA4523,
+/**/ 0x8A357386, 0x4008AD41,
+/**/ 0x5E392799, 0x401892C7,
+/**/ 0x97746ACD, 0x4029AA2B,
+/**/ 0xB4A71E44, 0x3C924F0A,
+/**/ 0x9AD13548, 0x3FE58633,
+/**/ 0x00000000, 0x3FF48000,
+/**/ 0x325E775E, 0xBF66C485,
+/**/ 0x00000000, 0x3FE41000,
+/**/ 0x76D6C491, 0x3FF489A3,
+/**/ 0x28D40829, 0x3FE53718,
+/**/ 0x98450D83, 0x3FF098EA,
+/**/ 0x55526E3B, 0x3FFB41C7,
+/**/ 0x719F540E, 0x4009DCBD,
+/**/ 0x805D08D1, 0x401A0685,
+/**/ 0xA5142633, 0x402B76FA,
+/**/ 0xF1FF56FC, 0x3C2AD9A7,
+/**/ 0xCBA27244, 0x3FE5AF31,
+/**/ 0x00000000, 0x3FF48000,
+/**/ 0xAD892100, 0x3F6346ED,
+/**/ 0x00000000, 0x3FE43000,
+/**/ 0xC7CB94CC, 0x3FF49F0C,
+/**/ 0xD492AA1E, 0x3FE59BF8,
+/**/ 0x34D2CA82, 0x3FF107FF,
+/**/ 0xC3DF9E51, 0x3FFC4A9E,
+/**/ 0x45F5874E, 0x400B1E41,
+/**/ 0xDEB92648, 0x401B947A,
+/**/ 0xD903D532, 0x402D6979,
+/**/ 0x04C67F5E, 0x3CA43231,
+/**/ 0x6B1109A4, 0x3FE5D85A,
+/**/ 0x00000000, 0x3FF48000,
+/**/ 0xCB94CC1A, 0x3F7F0CC7,
+/**/ 0x00000000, 0x3FE45000,
+/**/ 0x4ADA0BF0, 0x3FF4B4DC,
+/**/ 0x990F861F, 0x3FE60380,
+/**/ 0xCBEC7542, 0x3FF17B50,
+/**/ 0xC93CFE8F, 0x3FFD6064,
+/**/ 0x56F36FE3, 0x400C7314,
+/**/ 0x696E5374, 0x401D3ECF,
+/**/ 0x1778AF1D, 0x402F8531,
+/**/ 0x31EBDA84, 0x3C7A53BF,
+/**/ 0x42E27660, 0x3FE601AE,
+/**/ 0x00000000, 0x3FF4C000,
+/**/ 0x4BE81F81, 0xBF66476A,
+/**/ 0x00000000, 0x3FE47000,
+/**/ 0xB4065600, 0x3FF4CB14,
+/**/ 0x826ADA4F, 0x3FE66DC9,
+/**/ 0xA3298D4D, 0x3FF1F314,
+/**/ 0x52191CB4, 0x3FFE83E1,
+/**/ 0x05CA69AF, 0x400DDC99,
+/**/ 0x1079C46A, 0x401F07DF,
+/**/ 0xF9440EB0, 0x4030E703,
+/**/ 0x5817D0DD, 0x3CA495E1,
+/**/ 0x222A98A0, 0x3FE62B2E,
+/**/ 0x00000000, 0x3FF4C000,
+/**/ 0x0CAC00D4, 0x3F662968,
+/**/ 0x00000000, 0x3FE49000,
+/**/ 0xD203BDC9, 0x3FF4E1B8,
+/**/ 0xE5FE0976, 0x3FE6DAEE,
+/**/ 0x3C44F71E, 0x3FF26F83,
+/**/ 0xB4D92F91, 0x3FFFB5EA,
+/**/ 0x55A779C8, 0x400F5C4F,
+/**/ 0xA66A7536, 0x4020791F,
+/**/ 0x7DCE5D75, 0x40322428,
+/**/ 0x964F770B, 0x3CADE7E8,
+/**/ 0xDD7FD12C, 0x3FE654DA,
+/**/ 0x00000000, 0x3FF50000,
+/**/ 0xFC42374B, 0xBF7E472D,
+/**/ 0x00000000, 0x3FE4B000,
+/**/ 0x8F87D541, 0x3FF4F8CB,
+/**/ 0x767620C4, 0x3FE74B0D,
+/**/ 0x9126F083, 0x3FF2F0D8,
+/**/ 0x73F08794, 0x40007BB3,
+/**/ 0xE1419117, 0x401079EB,
+/**/ 0xA917F81E, 0x40218062,
+/**/ 0x48444DEE, 0x40337C6B,
+/**/ 0xF4061E08, 0x3C907A41,
+/**/ 0x4F31AF70, 0x3FE67EB5,
+/**/ 0x00000000, 0x3FF50000,
+/**/ 0xE0AAFA85, 0xBF5CD1C1,
+/**/ 0x00000000, 0x3FE4D000,
+/**/ 0xF4B2718C, 0x3FF5104F,
+/**/ 0x59659939, 0x3FE7BE43,
+/**/ 0x5502EAE6, 0x3FF37754,
+/**/ 0x6AE0AC51, 0x400124A6,
+/**/ 0x33524D17, 0x4011527B,
+/**/ 0x7FBF7A2D, 0x40229B46,
+/**/ 0xAD716768, 0x4034F274,
+/**/ 0x7C204EA8, 0xBC9C610F,
+/**/ 0x57825A6C, 0x3FE6A8BE,
+/**/ 0x00000000, 0x3FF50000,
+/**/ 0xB2718C01, 0x3F704FF4,
+/**/ 0x00000000, 0x3FE4F000,
+/**/ 0x288C017D, 0x3FF52849,
+/**/ 0x3E6D3F7F, 0x3FE834B0,
+/**/ 0x3B0747CB, 0x3FF4033A,
+/**/ 0xE946B196, 0x4001D652,
+/**/ 0x3C2F8CB4, 0x401238CB,
+/**/ 0x53E520C1, 0x4023CB80,
+/**/ 0x607BC0F6, 0x40368938,
+/**/ 0xCC053597, 0xBC84274C,
+/**/ 0xDCE2DFB8, 0x3FE6D2F6,
+/**/ 0x00000000, 0x3FF54000,
+/**/ 0x73FE8364, 0xBF77B6D7,
+/**/ 0x00000000, 0x3FE51000,
+/**/ 0x729BE713, 0x3FF540BA,
+/**/ 0x781F49A2, 0x3FE8AE75,
+/**/ 0x432AC103, 0x3FF494D2,
+/**/ 0x9B0015B6, 0x40029147,
+/**/ 0x156B74E9, 0x40132DE7,
+/**/ 0xE8362EC8, 0x402512F0,
+/**/ 0xC8D2E0F8, 0x403843FE,
+/**/ 0xBB3ACC53, 0xBC8F55DB,
+/**/ 0xCC3296F0, 0x3FE6FD5F,
+/**/ 0x00000000, 0x3FF54000,
+/**/ 0x7CE2565E, 0x3F274E53,
+/**/ 0x00000000, 0x3FE53000,
+/**/ 0x3C98A101, 0x3FF559A7,
+/**/ 0x16C3163D, 0x3FE92BB6,
+/**/ 0x0DB2C44D, 0x3FF52C69,
+/**/ 0x0F4546B8, 0x4003561E,
+/**/ 0x7F099A82, 0x401432F1,
+/**/ 0x831E227A, 0x402673A9,
+/**/ 0xA02BBCD5, 0x403A266F,
+/**/ 0xAEA9CB9D, 0x3CA279A8,
+/**/ 0x1901CB44, 0x3FE727FA,
+/**/ 0x00000000, 0x3FF54000,
+/**/ 0x98A10084, 0x3F79A73C,
+/**/ 0x00000000, 0x3FE55000,
+/**/ 0x1433B9BD, 0x3FF57313,
+/**/ 0x0523E7B2, 0x3FE9AC97,
+/**/ 0x361F7393, 0x3FF5CA50,
+/**/ 0xB0F40825, 0x4004257B,
+/**/ 0x46286025, 0x40154927,
+/**/ 0x781495B4, 0x4027EFF1,
+/**/ 0x0A1139F1, 0x403C349E,
+/**/ 0x8B6015DA, 0xBC5D2C66,
+/**/ 0xBDD7E0E0, 0x3FE752C6,
+/**/ 0x00000000, 0x3FF58000,
+/**/ 0x988C865F, 0xBF69D9D7,
+/**/ 0x00000000, 0x3FE57000,
+/**/ 0xAD039E07, 0x3FF58D01,
+/**/ 0x279933CD, 0x3FEA313F,
+/**/ 0xB63D93A6, 0x3FF66EDE,
+/**/ 0xD836441A, 0x40050012,
+/**/ 0xF23D152C, 0x401671E1,
+/**/ 0x65D3A1DD, 0x40298A4C,
+/**/ 0x5EBDBF39, 0x403E7316,
+/**/ 0x7AAA4996, 0xBCAE5B6C,
+/**/ 0xBC7D2FA0, 0x3FE77DC6,
+/**/ 0x00000000, 0x3FF58000,
+/**/ 0x073C0E86, 0x3F6A035A,
+/**/ 0x00000000, 0x3FE59000,
+/**/ 0xE28DADB6, 0x3FF5A776,
+/**/ 0x7D7BE2B5, 0x3FEAB9D7,
+/**/ 0x5234C8A9, 0x3FF71A71,
+/**/ 0xF873554C, 0x4005E6A3,
+/**/ 0xC1F33F9B, 0x4017AE9A,
+/**/ 0x4310046E, 0x402B4581,
+/**/ 0xF64B03E7, 0x40407376,
+/**/ 0xB3AB0542, 0xBCA3F39B,
+/**/ 0x1E48D158, 0x3FE7A8FB,
+/**/ 0x00000000, 0x3FF5C000,
+/**/ 0x725249CA, 0xBF78891D,
+/**/ 0x00000000, 0x3FE5B000,
+/**/ 0xBA730F9B, 0x3FF5C276,
+/**/ 0x454127C3, 0x3FEB468B,
+/**/ 0x0E816ADB, 0x3FF7CD6B,
+/**/ 0xEDDAC837, 0x4006D9FE,
+/**/ 0x0209E3B7, 0x401900EE,
+/**/ 0x57489C7E, 0x402D24A2,
+/**/ 0x7F810E14, 0x4041CAEA,
+/**/ 0x24F9675B, 0xBC84F20E,
+/**/ 0xF472A690, 0x3FE7D464,
+/**/ 0x00000000, 0x3FF5C000,
+/**/ 0x987CD623, 0x3F43B5D3,
+/**/ 0x00000000, 0x3FE5D000,
+/**/ 0x66C30CDC, 0x3FF5DE05,
+/**/ 0x23798D1A, 0x3FEBD788,
+/**/ 0xB0E567D8, 0x3FF88835,
+/**/ 0x6E46660A, 0x4007DB04,
+/**/ 0xCA07CAA5, 0x401A6A9E,
+/**/ 0x41ECEF64, 0x402F2B16,
+/**/ 0xC36F367B, 0x40434315,
+/**/ 0x542594A6, 0xBCA08CA1,
+/**/ 0x5869D9E8, 0x3FE80005,
+/**/ 0x00000000, 0x3FF5C000,
+/**/ 0xC30CDBD9, 0x3F7E0566,
+/**/ 0x00000000, 0x3FE5F000,
+/**/ 0x4875FA03, 0x3FF5FA27,
+/**/ 0x4CF96D63, 0x3FEC6CFE,
+/**/ 0x4D7B8313, 0x3FF94B42,
+/**/ 0xA1B04592, 0x4008EAA7,
+/**/ 0x2C5A9D87, 0x401BED9B,
+/**/ 0x1BC92F68, 0x4030AE51,
+/**/ 0x685FBD64, 0x4044DF8C,
+/**/ 0x30FE6378, 0xBCAC07A8,
+/**/ 0x6C30303C, 0x3FE82BDD,
+/**/ 0x00000000, 0x3FF60000,
+/**/ 0x2817F40C, 0xBF5762DE,
+/**/ 0x00000000, 0x3FE61000,
+/**/ 0xF213FCD6, 0x3FF616E0,
+/**/ 0xB47784FF, 0x3FED0720,
+/**/ 0xE13C6707, 0x3FFA1709,
+/**/ 0xE70B2E72, 0x400A09EF,
+/**/ 0xE976AAD9, 0x401D8C00,
+/**/ 0xD1AE1EA8, 0x4031DEBA,
+/**/ 0x6424341F, 0x4046A453,
+/**/ 0xA65D40B1, 0x3CA13E53,
+/**/ 0x5ABA79E8, 0x3FE857EE,
+/**/ 0x00000000, 0x3FF60000,
+/**/ 0x13FCD614, 0x3F76E0F2,
+/**/ 0x00000000, 0x3FE63000,
+/**/ 0x2A8B4ED8, 0x3FF63437,
+/**/ 0x3BF69915, 0x3FEDA625,
+/**/ 0xFB6DF86F, 0x3FFAEC0D,
+/**/ 0xCAF2D64B, 0x400B39FA,
+/**/ 0xB7E2DC06, 0x401F4822,
+/**/ 0xB12537E3, 0x4033291B,
+/**/ 0xAF3EF0D1, 0x404895F0,
+/**/ 0x71E7ED76, 0x3CAEA588,
+/**/ 0x5856807C, 0x3FE88439,
+/**/ 0x00000000, 0x3FF64000,
+/**/ 0xE9624F1C, 0xBF6791AA,
+/**/ 0x00000000, 0x3FE65000,
+/**/ 0xF039F5E3, 0x3FF6522E,
+/**/ 0xEA588E54, 0x3FEE4A44,
+/**/ 0x77A3F8A4, 0x3FFBCAD9,
+/**/ 0x3669F2F2, 0x400C7BFE,
+/**/ 0x1AEA54A4, 0x40209247,
+/**/ 0x6B866959, 0x4034900A,
+/**/ 0x620634CF, 0x404AB97D,
+/**/ 0xDA91B0FD, 0x3C948649,
+/**/ 0xA316D3A0, 0x3FE8B0BF,
+/**/ 0x00000000, 0x3FF64000,
+/**/ 0x39F5E2AD, 0x3F722EF0,
+/**/ 0x00000000, 0x3FE67000,
+/**/ 0x7C2F4FC3, 0x3FF670CD,
+/**/ 0x2583CF60, 0x3FEEF3BC,
+/**/ 0x4A2E1684, 0x3FFCB401,
+/**/ 0xDCB9F8FB, 0x400DD14A,
+/**/ 0x4E164373, 0x40219209,
+/**/ 0x8FC171BC, 0x40361669,
+/**/ 0xA46B7BE1, 0x404D14BA,
+/**/ 0xBBDFE65A, 0xBCABAC31,
+/**/ 0x8344E08C, 0x3FE8DD82,
+/**/ 0x00000000, 0x3FF68000,
+/**/ 0xA1607A77, 0xBF6E6507,
+/**/ 0x00000000, 0x3FE69000,
+/**/ 0x45AA3C85, 0x3FF69018,
+/**/ 0xF18FBD18, 0x3FEFA2CA,
+/**/ 0x610C140E, 0x3FFDA825,
+/**/ 0xF08895E1, 0x400F3B4E,
+/**/ 0x272CD203, 0x4022A4E4,
+/**/ 0x60C4A0EE, 0x4037BF71,
+/**/ 0xEC79351D, 0x404FAE29,
+/**/ 0x3E22FB0A, 0x3C6BF5BB,
+/**/ 0x4BD9C858, 0x3FE90A83,
+/**/ 0x00000000, 0x3FF68000,
+/**/ 0xAA3C8533, 0x3F701845,
+/**/ 0x00000000, 0x3FE6B000,
+/**/ 0x05D92E4E, 0x3FF6B015,
+/**/ 0x9ABD20D8, 0x3FF02BDA,
+/**/ 0x9BC5CC13, 0x3FFEA7F1,
+/**/ 0x94AFB2BB, 0x40105DCC,
+/**/ 0xB382B54A, 0x4023CC8C,
+/**/ 0x19C28EAE, 0x40398EBB,
+/**/ 0x8F7609B5, 0x40514694,
+/**/ 0xF66137E5, 0x3C9CD223,
+/**/ 0x5AFE73AC, 0x3FE937C3,
+/**/ 0x00000000, 0x3FF6C000,
+/**/ 0x4DA36334, 0xBF6FD5F4,
+/**/ 0x00000000, 0x3FE6D000,
+/**/ 0xBBE1EF2B, 0x3FF6D0C9,
+/**/ 0x82FBDD29, 0x3FF08961,
+/**/ 0xDCD403EC, 0x3FFFB41E,
+/**/ 0x121D0023, 0x401129EE,
+/**/ 0xB34159B2, 0x40250AE5,
+/**/ 0xDB5CEAC4, 0x403B884D,
+/**/ 0xA0B334B0, 0x4052DD09,
+/**/ 0xD8F14BF9, 0xBC96BF1D,
+/**/ 0x1A936D24, 0x3FE96544,
+/**/ 0x00000000, 0x3FF6C000,
+/**/ 0xE1EF2AEE, 0x3F70C9BB,
+/**/ 0x00000000, 0x3FE6F000,
+/**/ 0xB13786CF, 0x3FF6F23C,
+/**/ 0x7B7FC134, 0x3FF0EA20,
+/**/ 0x1BD0D518, 0x400066BA,
+/**/ 0x159EC945, 0x401202F9,
+/**/ 0x16FF868A, 0x40266205,
+/**/ 0x87398014, 0x403DB0AD,
+/**/ 0x47D58711, 0x40549F33,
+/**/ 0x54B11A28, 0x3C8D858F,
+/**/ 0x00C1184C, 0x3FE99307,
+/**/ 0x00000000, 0x3FF70000,
+/**/ 0x90F2626A, 0xBF6B869D,
+/**/ 0x00000000, 0x3FE71000,
+/**/ 0x7E455603, 0x3FF71474,
+/**/ 0x3A65655F, 0x3FF14E40,
+/**/ 0x1F4AA7A1, 0x4000FA64,
+/**/ 0xB946C70A, 0x4012E9F0,
+/**/ 0x3CC53936, 0x4027D43A,
+/**/ 0xEE087279, 0x40400675,
+/**/ 0x77313CEF, 0x40569278,
+/**/ 0x772D6E62, 0xBCAB1BA1,
+/**/ 0x9090E874, 0x3FE9C10D,
+/**/ 0x00000000, 0x3FF70000,
+/**/ 0x455602D3, 0x3F74747E,
+/**/ 0x00000000, 0x3FE73000,
+/**/ 0x0F773DEC, 0x3FF73778,
+/**/ 0x1288B243, 0x3FF1B5EC,
+/**/ 0x3A853FA5, 0x40019581,
+/**/ 0x6D2743E5, 0x4013DFF0,
+/**/ 0x09B4B924, 0x40296415,
+/**/ 0x19A59D1F, 0x4041515E,
+/**/ 0xF3E53877, 0x4058BD01,
+/**/ 0xFC348BAE, 0x3C962269,
+/**/ 0x5A90493C, 0x3FE9EF59,
+/**/ 0x00000000, 0x3FF74000,
+/**/ 0x11842743, 0xBF610FE1,
+/**/ 0x00000000, 0x3FE75000,
+/**/ 0xAAA78140, 0x3FF75B4E,
+/**/ 0x28B49576, 0x3FF22152,
+/**/ 0x74D66746, 0x4002388E,
+/**/ 0xA43083A8, 0x4014E62E,
+/**/ 0x02885ED7, 0x402B146E,
+/**/ 0x29A3BC2C, 0x4042BC45,
+/**/ 0xCDAFE7E5, 0x405B25D8,
+/**/ 0xF03F8A74, 0x3CA8862D,
+/**/ 0xFD7DFBD8, 0x3FEA1DEB,
+/**/ 0x00000000, 0x3FF74000,
+/**/ 0xA7813FBA, 0x3F7B4EAA,
+/**/ 0x00000000, 0x3FE77000,
+/**/ 0xF4FC0008, 0x3FF77FFF,
+/**/ 0xADE499E4, 0x3FF290A3,
+/**/ 0xFF22FE11, 0x4002E412,
+/**/ 0xD7A17943, 0x4015FDFF,
+/**/ 0x8AF79AEF, 0x402CE86F,
+/**/ 0x6F8EDF86, 0x40444ACA,
+/**/ 0x29CF9F92, 0x405DD50A,
+/**/ 0xC5865233, 0x3CA49DB0,
+/**/ 0x2702BD90, 0x3FEA4CC7,
+/**/ 0x00000000, 0x3FF78000,
+/**/ 0xF08268E1, 0xBE6607FF,
+/**/ 0x00000000, 0x3FE79000,
+/**/ 0xF93D7FBC, 0x3FF7A593,
+/**/ 0x1F293A81, 0x3FF30415,
+/**/ 0x31649EA4, 0x400398A1,
+/**/ 0xED75DA1E, 0x401728D9,
+/**/ 0x7B1736CA, 0x402EE3A0,
+/**/ 0x036EC9D4, 0x40460106,
+/**/ 0xB3E5A09F, 0x406069E8,
+/**/ 0x4E8EB882, 0xBCA79BBD,
+/**/ 0x94762100, 0x3FEA7BEC,
+/**/ 0x00000000, 0x3FF7C000,
+/**/ 0xC280445C, 0xBF7A6C06,
+/**/ 0x00000000, 0x3FE7B000,
+/**/ 0x2EB4E536, 0x3FF7CC13,
+/**/ 0x8BD25D7D, 0x3FF37BDE,
+/**/ 0xA51DF797, 0x400456D7,
+/**/ 0x103AF33E, 0x40186858,
+/**/ 0x21121C2E, 0x403084F8,
+/**/ 0x9D7C6DE3, 0x4047E39A,
+/**/ 0xEF4C9A12, 0x40621664,
+/**/ 0x39DB72FF, 0x3C804D2D,
+/**/ 0x13B099B0, 0x3FEAAB5E,
+/**/ 0x00000000, 0x3FF7C000,
+/**/ 0x69CA6C2F, 0x3F68265D,
+/**/ 0x00000000, 0x3FE7D000,
+/**/ 0x809BA1CD, 0x3FF7F386,
+/**/ 0xE298B2EB, 0x3FF3F83B,
+/**/ 0x708A6ABE, 0x40051F62,
+/**/ 0x090F77AB, 0x4019BE3F,
+/**/ 0x6C13BF38, 0x4031AFE2,
+/**/ 0x65FF02A8, 0x4049F7CA,
+/**/ 0xDA840FE0, 0x4063F614,
+/**/ 0xAB5D1A54, 0xBCA7BDE9,
+/**/ 0x83EBD320, 0x3FEADB1D,
+/**/ 0x00000000, 0x3FF80000,
+/**/ 0xC8BC6562, 0xBF68F2FE,
+/**/ 0x00000000, 0x3FE7F000,
+/**/ 0x562E1E24, 0x3FF81BF7,
+/**/ 0x469724DB, 0x3FF4796D,
+/**/ 0x86E67917, 0x4005F2FC,
+/**/ 0x2F5AE582, 0x401B2C82,
+/**/ 0x65EE1919, 0x4032F505,
+/**/ 0x4744D220, 0x404C438F,
+/**/ 0xD66309FD, 0x40661003,
+/**/ 0xFC828894, 0x3C8470C8,
+/**/ 0xD6B287DC, 0x3FEB0B2C,
+/**/ 0x00000000, 0x3FF80000,
+/**/ 0x2E1E23E5, 0x3F7BF756,
+/**/ 0x00000000, 0x3FE81000,
+/**/ 0x9B70AB1D, 0x3FF8456F,
+/**/ 0x6D01A674, 0x3FF4FFB7,
+/**/ 0x42D7B667, 0x4006D271,
+/**/ 0x05DD4055, 0x401CB549,
+/**/ 0xE490CA9B, 0x40345723,
+/**/ 0x47C5589B, 0x404ECD17,
+/**/ 0x3D6DB036, 0x40686C46,
+/**/ 0xECF23C2E, 0x4084044D,
+/**/ 0x0D173A5F, 0xBC7F0990,
+/**/ 0x10E12D3C, 0x3FEB3B8E,
+/**/ 0x00000000, 0x3FF84000,
+/**/ 0xC2AC733C, 0x3F55BE6D,
+/**/ 0x00000000, 0x3FE83000,
+/**/ 0xCAB97B9D, 0x3FF86FF9,
+/**/ 0x04A71B42, 0x3FF58B64,
+/**/ 0x20C0FB6E, 0x4007BE9E,
+/**/ 0x9B426297, 0x401E5AF5,
+/**/ 0x013C40EE, 0x4035D958,
+/**/ 0x2215E48C, 0x4050CEA9,
+/**/ 0xB8C0669A, 0x406B146B,
+/**/ 0xFB8EB0FE, 0x40868C96,
+/**/ 0x1FCCBAD4, 0x3CA55848,
+/**/ 0x4BB8EA98, 0x3FEB6C43,
+/**/ 0x00000000, 0x3FF88000,
+/**/ 0x46846319, 0xBF700635,
+/**/ 0x00000000, 0x3FE85000,
+/**/ 0xF71469BF, 0x3FF89BA0,
+/**/ 0x28717EFA, 0x3FF61CC2,
+/**/ 0xAFB7BAF7, 0x4008B874,
+/**/ 0xEC7286DB, 0x40201015,
+/**/ 0x8329A469, 0x40377F1F,
+/**/ 0x2927F0DD, 0x40525E49,
+/**/ 0x5AE80CD9, 0x406E135C,
+/**/ 0x40DF64FD, 0x40897364,
+/**/ 0x1ED91B03, 0x3C89F53B,
+/**/ 0xB6067ABC, 0x3FEB9D4E,
+/**/ 0x00000000, 0x3FF88000,
+/**/ 0x1469BF33, 0x3F7BA0F7,
+/**/ 0x00000000, 0x3FE87000,
+/**/ 0xD797DABF, 0x3FF8C870,
+/**/ 0xDE42D55F, 0x3FF6B426,
+/**/ 0xC0E06552, 0x4009C0FC,
+/**/ 0xEB059907, 0x402103EC,
+/**/ 0x49A75AA7, 0x40394C6A,
+/**/ 0xB2A496D0, 0x40541A81,
+/**/ 0x209CB693, 0x4070BAEE,
+/**/ 0x285808C5, 0x408CC860,
+/**/ 0x9B0DC6F3, 0xBCAE6D8C,
+/**/ 0x955EC1C4, 0x3FEBCEB2,
+/**/ 0x00000000, 0x3FF8C000,
+/**/ 0x2FB57EE7, 0x3F60E1AF,
+/**/ 0x00000000, 0x3FE89000,
+/**/ 0xD3C502F4, 0x3FF8F675,
+/**/ 0xA3BFB2E4, 0x3FF751ED,
+/**/ 0xDE3987BC, 0x400AD956,
+/**/ 0xB30AAD0A, 0x40220AA0,
+/**/ 0x16220014, 0x403B45AB,
+/**/ 0xEC84429C, 0x40560929,
+/**/ 0x0D747939, 0x4072A569,
+/**/ 0x5407F41E, 0x40904F10,
+/**/ 0xFC269962, 0xBC675CEB,
+/**/ 0x4773138C, 0x3FEC0071,
+/**/ 0x00000000, 0x3FF90000,
+/**/ 0x75FA1750, 0xBF631458,
+/**/ 0x00000000, 0x3FE8B000,
+/**/ 0x111125DF, 0x3FF925BD,
+/**/ 0x0AD2B4C2, 0x3FF7F679,
+/**/ 0x1359A3C8, 0x400C02BF,
+/**/ 0x88857C21, 0x40232601,
+/**/ 0x2515D90E, 0x403D6FEB,
+/**/ 0xD421145E, 0x405830FA,
+/**/ 0xFD789544, 0x4074D1D6,
+/**/ 0x4B30EBF1, 0x40928561,
+/**/ 0x7876F9D2, 0x3CA13E7B,
+/**/ 0x437F5E74, 0x3FEC328D,
+/**/ 0x00000000, 0x3FF94000,
+/**/ 0xEEDA20A4, 0xBF7A42EE,
+/**/ 0x00000000, 0x3FE8D000,
+/**/ 0x81B9477B, 0x3FF95654,
+/**/ 0x67F87779, 0x3FF8A233,
+/**/ 0x14665EA0, 0x400D3E90,
+/**/ 0x5A415747, 0x40245815,
+/**/ 0x1D7511C0, 0x403FD0E1,
+/**/ 0x01EC30FB, 0x405A99B6,
+/**/ 0xDD7EE7A1, 0x40774A72,
+/**/ 0x5C2F1724, 0x40951454,
+/**/ 0x774A5205, 0x3C8185B3,
+/**/ 0x1BD4AD0C, 0x3FEC6509,
+/**/ 0x00000000, 0x3FF94000,
+/**/ 0xB9477AC0, 0x3F765481,
+/**/ 0x00000000, 0x3FE8F000,
+/**/ 0xF50630B5, 0x3FF9884A,
+/**/ 0x94B35A8D, 0x3FF9558F,
+/**/ 0xD1A32B1D, 0x400E8E46,
+/**/ 0x0AEC68DB, 0x4025A31F,
+/**/ 0xFD21A759, 0x40413785,
+/**/ 0xF56DFCA6, 0x405D4C53,
+/**/ 0xF89C0F5F, 0x407A1B45,
+/**/ 0xC92C8CF3, 0x40980BB3,
+/**/ 0xFEB6A05E, 0xBC8696E8,
+/**/ 0x7F82B8CC, 0x3FEC97E7,
+/**/ 0x00000000, 0x3FF98000,
+/**/ 0x0C6169C6, 0x3F6095EA,
+/**/ 0x00000000, 0x3FE91000,
+/**/ 0x292BC29F, 0x3FF9BBB0,
+/**/ 0xC8E3D76B, 0x3FFA1109,
+/**/ 0x8873C480, 0x400FF386,
+/**/ 0xDE619C77, 0x402709A6,
+/**/ 0x5A9417B9, 0x4042A8E9,
+/**/ 0xBFE20B57, 0x4060299D,
+/**/ 0xE1225431, 0x407D5283,
+/**/ 0xC225406C, 0x409B7E74,
+/**/ 0x74F396DB, 0xBC879431,
+/**/ 0x3C239888, 0x3FECCB2B,
+/**/ 0x00000000, 0x3FF9C000,
+/**/ 0x50F5839F, 0xBF513F5B,
+/**/ 0x00000000, 0x3FE93000,
+/**/ 0xDEF4783D, 0x3FF9F094,
+/**/ 0x8E300736, 0x3FFAD528,
+/**/ 0xB2D4D4EE, 0x4010B80E,
+/**/ 0x3F3D0057, 0x40288E84,
+/**/ 0xD20263C0, 0x404440D4,
+/**/ 0x26E14927, 0x4061DD42,
+/**/ 0x5EF13D09, 0x4080807D,
+/**/ 0xFE9E94BE, 0x409F836C,
+/**/ 0xE5FD9D2D, 0xBC813C84,
+/**/ 0x3FCCF104, 0x3FECFED7,
+/**/ 0x00000000, 0x3FFA0000,
+/**/ 0x170F854B, 0xBF6ED642,
+/**/ 0x00000000, 0x3FE95000,
+/**/ 0xEF70C9F9, 0x3FFA270A,
+/**/ 0xD12662D9, 0x3FFBA27D,
+/**/ 0xE8433B59, 0x40118304,
+/**/ 0x1B4DD8D9, 0x402A34E9,
+/**/ 0x58AA354C, 0x4046041F,
+/**/ 0x87EB035B, 0x4063C823,
+/**/ 0x7F89A6B6, 0x40829D4E,
+/**/ 0xB4BED54D, 0x40A21B1A,
+/**/ 0xFD8283D4, 0x3C855D66,
+/**/ 0x9B2A7684, 0x3FED32EE,
+/**/ 0x00000000, 0x3FFA4000,
+/**/ 0x8F3606B9, 0xBF78F510,
+/**/ 0x00000000, 0x3FE97000,
+/**/ 0x63EA127F, 0x3FFA5F25,
+/**/ 0x1460C218, 0x3FFC79A8,
+/**/ 0x3D14975C, 0x40125BC0,
+/**/ 0x2249DB66, 0x402C006F,
+/**/ 0xED0AEFCD, 0x4047F856,
+/**/ 0x2E2028D0, 0x4065F27F,
+/**/ 0x6CE59595, 0x40850B95,
+/**/ 0x18C497E2, 0x40A4DC23,
+/**/ 0x76BA54CA, 0x3C8BDFAE,
+/**/ 0x83C60554, 0x3FED6774,
+/**/ 0x00000000, 0x3FFA4000,
+/**/ 0xEA127F53, 0x3F7F2563,
+/**/ 0x00000000, 0x3FE99000,
+/**/ 0x9061CEFE, 0x3FFA98F8,
+/**/ 0xCAA1F466, 0x3FFD5B53,
+/**/ 0xA92630E8, 0x40134379,
+/**/ 0x41E37357, 0x402DF527,
+/**/ 0xD7DE2305, 0x404A23DF,
+/**/ 0x1911C50F, 0x406865FE,
+/**/ 0xD5CE543D, 0x4087D981,
+/**/ 0x2134A322, 0x40A8192E,
+/**/ 0x4FE6DAC8, 0xBC915CF9,
+/**/ 0x56821F74, 0x3FED9C6C,
+/**/ 0x00000000, 0x3FFA8000,
+/**/ 0x61CEFDBB, 0x3F78F890,
+/**/ 0x00000000, 0x3FE9B000,
+/**/ 0x30F0DACC, 0x3FFAD49A,
+/**/ 0xDDBFEE70, 0x3FFE483C,
+/**/ 0xC4418459, 0x40143B8C,
+/**/ 0xE6E7E816, 0x40300BD5,
+/**/ 0x02EE200E, 0x404C8E1A,
+/**/ 0x83038A03, 0x406B2DFC,
+/**/ 0xD987E3D9, 0x408B1814,
+/**/ 0x8827CEFA, 0x40ABEB1E,
+/**/ 0xE22AFCE0, 0x3CA8829A,
+/**/ 0x9A4C39D0, 0x3FEDD1D9,
+/**/ 0x00000000, 0x3FFAC000,
+/**/ 0xF0DACB86, 0x3F749A30,
+/**/ 0x00000000, 0x3FE9D000,
+/**/ 0x8A66E40D, 0x3FFB1221,
+/**/ 0x692DC10A, 0x3FFF4130,
+/**/ 0x64621A80, 0x4015457C,
+/**/ 0xED2A1AB4, 0x4031369A,
+/**/ 0xBC003A70, 0x404F3F8D,
+/**/ 0x462E99D6, 0x406E57E1,
+/**/ 0xC53F5717, 0x408EDBC2,
+/**/ 0x0A71E453, 0x40B0383D,
+/**/ 0xBEDD86A9, 0x3C90AF9F,
+/**/ 0x030CF708, 0x3FEE07C0,
+/**/ 0x00000000, 0x3FFB0000,
+/**/ 0x66E40CBE, 0x3F72218A,
+/**/ 0x00000000, 0x3FE9F000,
+/**/ 0x8E9927E5, 0x3FFB51A7,
+/**/ 0x581637B3, 0x40002387,
+/**/ 0xF5B2C17E, 0x401662F7,
+/**/ 0x36EAC07E, 0x40327DDB,
+/**/ 0xC70D9C43, 0x40512110,
+/**/ 0x88C52943, 0x4070F9C4,
+/**/ 0xB1AB4848, 0x40919E9E,
+/**/ 0xB1EC7695, 0x40B2E76B,
+/**/ 0x5E9F6FD9, 0x3CAA2400,
+/**/ 0x74DD3C64, 0x3FEE3E23,
+/**/ 0x00000000, 0x3FFB4000,
+/**/ 0x9927E571, 0x3F71A78E,
+/**/ 0x00000000, 0x3FEA1000,
+/**/ 0x04E0F95F, 0x3FFB9347,
+/**/ 0xAC8DC27B, 0x4000AD66,
+/**/ 0xAE05A580, 0x401795E1,
+/**/ 0x299AA0A0, 0x4033E4FA,
+/**/ 0xA33AB75C, 0x4052D0AD,
+/**/ 0x39D64C89, 0x407309E5,
+/**/ 0x154C34C4, 0x40942D39,
+/**/ 0x59D15B1D, 0x40B61A59,
+/**/ 0x114BE565, 0xBCAFC899,
+/**/ 0x0787FD30, 0x3FEE7508,
+/**/ 0x00000000, 0x3FFB8000,
+/**/ 0xE0F95E8B, 0x3F734704,
+/**/ 0x00000000, 0x3FEA3000,
+/**/ 0xB75F37A1, 0x3FFBD71C,
+/**/ 0xFC9006E1, 0x40013EBC,
+/**/ 0xC48D2C09, 0x4018E055,
+/**/ 0xC2C8C9CD, 0x40356FD7,
+/**/ 0x6198B971, 0x4054B557,
+/**/ 0x9680F9AF, 0x4075678C,
+/**/ 0x8AF946DD, 0x40972BE5,
+/**/ 0xE1B531F9, 0x40B9EDE4,
+/**/ 0xE4527544, 0xBC447F69,
+/**/ 0x0A61AD1C, 0x3FEEAC72,
+/**/ 0x00000000, 0x3FFBC000,
+/**/ 0x5F37A0DF, 0x3F771CB7,
+/**/ 0x00000000, 0x3FEA5000,
+/**/ 0xA5B24F80, 0x3FFC1D47,
+/**/ 0x7EB9F789, 0x4001D81E,
+/**/ 0xDF42B6B7, 0x401A44B2,
+/**/ 0xB4766752, 0x403722E5,
+/**/ 0xECFADFF0, 0x4056D6EE,
+/**/ 0x8B1EB8D5, 0x40782028,
+/**/ 0xCA840144, 0x409AB0E2,
+/**/ 0xE2126BBF, 0x40BE8614,
+/**/ 0x2CC624E2, 0xBC8D9A93,
+/**/ 0x087F8D20, 0x3FEEE466,
+/**/ 0x00000000, 0x3FFC0000,
+/**/ 0xB24F8064, 0x3F7D47A5,
+/**/ 0x00000000, 0x3FEA7000,
+/**/ 0x3DE98207, 0x3FFC65E9,
+/**/ 0x811F641B, 0x40027A2E,
+/**/ 0xF223266D, 0x401BC5A3,
+/**/ 0xA6ECBE29, 0x40390340,
+/**/ 0xC3D499AF, 0x40593EB6,
+/**/ 0xAD8CC2F1, 0x407B43D9,
+/**/ 0xA519B816, 0x409ED77C,
+/**/ 0x5B3B703B, 0x40C2080A,
+/**/ 0xE993C3DD, 0x3C7B187D,
+/**/ 0xCD5A7CE8, 0x3FEF1CE8,
+/**/ 0x00000000, 0x3FFC8000,
+/**/ 0x167DF937, 0xBF7A16C2,
+/**/ 0x00000000, 0x3FEA9000,
+/**/ 0x9CA2F05E, 0x3FFCB125,
+/**/ 0x54FC4C95, 0x400325A1,
+/**/ 0xD9C5FF75, 0x401D662B,
+/**/ 0x8E93577D, 0x403B16CE,
+/**/ 0xE0E3029E, 0x405BF79A,
+/**/ 0x04BCDF91, 0x407EE612,
+/**/ 0x31EFE3F1, 0x40A1E0AC,
+/**/ 0x85DF051C, 0x40C56267,
+/**/ 0x2D0BC06E, 0xBCAD6122,
+/**/ 0x69EAB2F0, 0x3FEF55FF,
+/**/ 0x00000000, 0x3FFCC000,
+/**/ 0xBA1F43E4, 0xBF6DB4C6,
+/**/ 0x00000000, 0x3FEAB000,
+/**/ 0xD56B9F55, 0x3FFCFF23,
+/**/ 0x86149A3B, 0x4003DB3E,
+/**/ 0x0B8D0DAD, 0x401F29B3,
+/**/ 0x40E9D1A7, 0x403D6463,
+/**/ 0x619D6679, 0x405F0E89,
+/**/ 0x92CF3FBC, 0x40818F2E,
+/**/ 0x844E51BD, 0x40A4CC10,
+/**/ 0xF3A9EB60, 0x40C9762D,
+/**/ 0xEF4B1E02, 0x3CA20E79,
+/**/ 0x3A4BC01C, 0x3FEF8FAF,
+/**/ 0x00000000, 0x3FFD0000,
+/**/ 0x8C156248, 0xBF2B8552,
+/**/ 0x00000000, 0x3FEAD000,
+/**/ 0x44AAD4F2, 0x3FFD500E,
+/**/ 0x6B85DB68, 0x40049BE3,
+/**/ 0xE558F351, 0x40208A0B,
+/**/ 0xC1BCC632, 0x403FF3EC,
+/**/ 0x2A555E45, 0x40614970,
+/**/ 0xDD057F33, 0x408404AE,
+/**/ 0x22610A18, 0x40A847D9,
+/**/ 0x3C7AA2B4, 0x40CE7146,
+/**/ 0x53CA14EC, 0xBC9571D0,
+/**/ 0xEBFAA348, 0x3FEFC9FD,
+/**/ 0x00000000, 0x3FFD4000,
+/**/ 0xAAD4F267, 0x3F700E44,
+/**/ 0x00000000, 0x3FEAF000,
+/**/ 0xEC9EDC5A, 0x3FFDA412,
+/**/ 0x22B6D908, 0x40056886,
+/**/ 0xB605B3B4, 0x402194E0,
+/**/ 0x9338560C, 0x40416754,
+/**/ 0x34B16169, 0x40634B7B,
+/**/ 0x3B1BAF9C, 0x4086E508,
+/**/ 0xFB9DFBF5, 0x40AC7475,
+/**/ 0xF4B4BB01, 0x40D2473E,
+/**/ 0xE9F06EFC, 0x3CA82B31,
+/**/ 0xC2613F02, 0x3FF00278,
+/**/ 0x00000000, 0x3FFDC000,
+/**/ 0x6123A5D1, 0xBF7BED13,
+/**/ 0x00000000, 0x3FEB1000,
+/**/ 0xDF3AE0DB, 0x3FFDFB63,
+/**/ 0x08AD38CF, 0x40064239,
+/**/ 0xAA166573, 0x4022B7DB,
+/**/ 0x38210D3E, 0x4042FFB4,
+/**/ 0xFB634456, 0x40659862,
+/**/ 0xEE8F3E34, 0x408A45B4,
+/**/ 0xD39A6C6F, 0x40B0BD59,
+/**/ 0x2B4867E8, 0x40D60CCD,
+/**/ 0x1CBB85B3, 0xBCA6097F,
+/**/ 0x3537E800, 0x3FF02048,
+/**/ 0x00000000, 0x3FFE0000,
+/**/ 0x147C93ED, 0xBF527083,
+/**/ 0x00000000, 0x3FEB3000,
+/**/ 0xB70F5F72, 0x3FFE5637,
+/**/ 0xCA935102, 0x40072A2E,
+/**/ 0x43559218, 0x4023F5DE,
+/**/ 0xB4E19CA3, 0x4044C96E,
+/**/ 0x1272DDA3, 0x40683D62,
+/**/ 0xC6BFAAED, 0x408E4135,
+/**/ 0x099FB249, 0x40B3C717,
+/**/ 0xD5294F7D, 0x40DABA6D,
+/**/ 0xC91FFA21, 0x3CA488B1,
+/**/ 0xB5B309E0, 0x3FF03E70,
+/**/ 0x00000000, 0x3FFE4000,
+/**/ 0x0F5F723E, 0x3F7637B7,
+/**/ 0x00000000, 0x3FEB5000,
+/**/ 0x21D4B842, 0x3FFEB4CA,
+/**/ 0x2BE08FC5, 0x400821BF,
+/**/ 0x6A6A3BD0, 0x40255238,
+/**/ 0xBAC907E2, 0x4046CC00,
+/**/ 0x94202458, 0x406B4A78,
+/**/ 0xFE065CA6, 0x40917C35,
+/**/ 0xE8D5B845, 0x40B77848,
+/**/ 0x0CD72D76, 0x40E04820,
+/**/ 0x9CBE508B, 0x3CA54B6E,
+/**/ 0xE41C2ACE, 0x3FF05CF5,
+/**/ 0x00000000, 0x3FFEC000,
+/**/ 0x568F7C18, 0xBF666BBC,
+/**/ 0x00000000, 0x3FEB7000,
+/**/ 0x7FB6EB26, 0x3FFF175C,
+/**/ 0xA7BA9C35, 0x40092A6C,
+/**/ 0x80F5BA9F, 0x4026D0BC,
+/**/ 0x33BD74FB, 0x40491048,
+/**/ 0x61FCE21F, 0x406ED319,
+/**/ 0x60DF5AED, 0x40944A2E,
+/**/ 0x1AC97175, 0x40BBFAFC,
+/**/ 0xC3A8BC22, 0x40E3F145,
+/**/ 0xA70A42D9, 0xBC994B5D,
+/**/ 0x9F358760, 0x3FF07BDB,
+/**/ 0x00000000, 0x3FFF0000,
+/**/ 0xB6EB2582, 0x3F775C7F,
+/**/ 0x00000000, 0x3FEB9000,
+/**/ 0x9B29492C, 0x3FFF7E36,
+/**/ 0x1C35AD8A, 0x400A45EB,
+/**/ 0xC8373BB1, 0x402875D7,
+/**/ 0x885E6AE6, 0x404BA0D1,
+/**/ 0x0831631E, 0x40717784,
+/**/ 0x7F51DA78, 0x4097A441,
+/**/ 0x6D7642FB, 0x40C0C2B2,
+/**/ 0x594961FB, 0x40E89073,
+/**/ 0x96CDC181, 0xBCA5DECE,
+/**/ 0x0A46374E, 0x3FF09B26,
+/**/ 0x00000000, 0x3FFF8000,
+/**/ 0x6B6D3D05, 0xBF3C964D,
+/**/ 0x00000000, 0x3FEBB000,
+/**/ 0x7DD9B1CF, 0x3FFFE9A7,
+/**/ 0xB9AE77AF, 0x400B7627,
+/**/ 0x3338306D, 0x402A46B0,
+/**/ 0xA0CAACE9, 0x404E8A38,
+/**/ 0x864F53A2, 0x4073DDBB,
+/**/ 0xD6C97F8D, 0x409BAAF0,
+/**/ 0xDFAE5A98, 0x40C42EEF,
+/**/ 0xE19501DA, 0x40EE701A,
+/**/ 0xC7D3D675, 0x3C9CC4F4,
+/**/ 0x93EC49AE, 0x3FF0BAD9,
+/**/ 0x00000000, 0x40000000,
+/**/ 0x264E310D, 0xBF765882,
+/**/ 0x00000000, 0x3FEBD000,
+/**/ 0x34302F3B, 0x40002D03,
+/**/ 0x7F5AAF0D, 0x400CBD52,
+/**/ 0x0C635C0A, 0x402C4949,
+/**/ 0xB6BB1732, 0x4050EDD1,
+/**/ 0x9691A9F4, 0x4076AE3D,
+/**/ 0x61482FC6, 0x40A043C7,
+/**/ 0xF81EB6E0, 0x40C87037,
+/**/ 0xE84FE55E, 0x40F2FA30,
+/**/ 0x228FC41D, 0xBC9820F1,
+/**/ 0xFDD4AE68, 0x3FF0DAFA,
+/**/ 0x00000000, 0x40002000,
+/**/ 0x605E76B0, 0x3F7A0668,
+/**/ 0x00000000, 0x3FEBF000,
+/**/ 0xF9C947A3, 0x400067D9,
+/**/ 0xA1722882, 0x400E1DE9,
+/**/ 0x41FE0247, 0x402E84B0,
+/**/ 0xDBD1D676, 0x4052D3AE,
+/**/ 0xE088BEF5, 0x4079FF78,
+/**/ 0x64D9A484, 0x40A33780,
+/**/ 0x1974F9B5, 0x40CDC32D,
+/**/ 0xCE268611, 0x40F7D295,
+/**/ 0xD437D23F, 0xBCA5A192,
+/**/ 0x657EFDCA, 0x3FF0FB8F,
+/**/ 0x00000000, 0x40006000,
+/**/ 0x251E8CF3, 0x3F6F67E7,
+/**/ 0x00000000, 0x3FEC1000,
+/**/ 0xB1FFFA6D, 0x4000A58D,
+/**/ 0x4E7307C3, 0x400F9AC7,
+/**/ 0x5EA15962, 0x4030809B,
+/**/ 0x5418E1B6, 0x405501D0,
+/**/ 0xB476D79F, 0x407DED80,
+/**/ 0x37F33D5F, 0x40A6D2BF,
+/**/ 0xA43F6C6F, 0x40D23C31,
+/**/ 0xDB17BBAA, 0x40FE1E46,
+/**/ 0x41D8AD56, 0xBCA7EB62,
+/**/ 0x4E3ADE0A, 0x3FF11C9C,
+/**/ 0x00000000, 0x4000A000,
+/**/ 0xFFE9B457, 0x3F6636C7,
+/**/ 0x00000000, 0x3FEC3000,
+/**/ 0x1D1BDCC6, 0x4000E65A,
+/**/ 0x3503CCCE, 0x40109B99,
+/**/ 0x7580EC24, 0x4031E45B,
+/**/ 0x1803E176, 0x405785CA,
+/**/ 0x8458A77D, 0x40814DDB,
+/**/ 0x6C115AB7, 0x40AB41D9,
+/**/ 0xD7BCE584, 0x40D67DF0,
+/**/ 0xF5487646, 0x41032EF5,
+/**/ 0xF3631254, 0xBC9C4040,
+/**/ 0xAC964DA8, 0x3FF13E27,
+/**/ 0x00000000, 0x4000E000,
+/**/ 0x6F731770, 0x3F696874,
+/**/ 0x00000000, 0x3FEC5000,
+/**/ 0x068FBCB4, 0x40012A82,
+/**/ 0x7FE89A5F, 0x40117B79,
+/**/ 0xD37F3897, 0x40337376,
+/**/ 0xDF3B47A2, 0x405A704E,
+/**/ 0xEB114449, 0x40841B83,
+/**/ 0x8D323120, 0x40B05F75,
+/**/ 0x8AE65DDD, 0x40DBEFEC,
+/**/ 0xD1814341, 0x4108A2A2,
+/**/ 0xFB25EC76, 0x3CA3E83D,
+/**/ 0xF37FFEDA, 0x3FF16037,
+/**/ 0x00000000, 0x40012000,
+/**/ 0x1F796787, 0x3F75040D,
+/**/ 0x00000000, 0x3FEC7000,
+/**/ 0x5F8F574B, 0x40017250,
+/**/ 0xB566493D, 0x40126F35,
+/**/ 0x95186E3D, 0x403534F5,
+/**/ 0x947D5EA5, 0x405DD60B,
+/**/ 0x568C5D73, 0x40877C77,
+/**/ 0xA26261F0, 0x40B3CB66,
+/**/ 0xBF32194D, 0x40E17B06,
+/**/ 0x11490E42, 0x410FE921,
+/**/ 0x5376CB61, 0xBCA34428,
+/**/ 0x236FE314, 0x3FF182D4,
+/**/ 0x00000000, 0x40018000,
+/**/ 0xE15169A9, 0xBF7B5F40,
+/**/ 0x00000000, 0x3FEC9000,
+/**/ 0x91B4C8D8, 0x4001BE19,
+/**/ 0xBE69BAE6, 0x4013795B,
+/**/ 0xCD6F8B02, 0x40373151,
+/**/ 0xD86A7BFF, 0x4060E864,
+/**/ 0x515F5BD6, 0x408B95CC,
+/**/ 0xD070B4A1, 0x40B8180C,
+/**/ 0xC9B24D80, 0x40E60D2C,
+/**/ 0xAA392CAF, 0x4114DBF6,
+/**/ 0xF5844C55, 0xBCA89BD0,
+/**/ 0xDBFAF236, 0x3FF1A603,
+/**/ 0x00000000, 0x4001C000,
+/**/ 0xB37285FC, 0xBF4E66E4,
+/**/ 0x00000000, 0x3FECB000,
+/**/ 0x1757F6B1, 0x40020E3D,
+/**/ 0xAE890640, 0x40149CE9,
+/**/ 0xD6174F60, 0x403972D4,
+/**/ 0x8C82DF92, 0x40634079,
+/**/ 0xACAB5569, 0x40904BE6,
+/**/ 0xB362E75A, 0x40BD8A99,
+/**/ 0x389374DC, 0x40EC0ED7,
+/**/ 0xCA5E9653, 0x411B8ADF,
+/**/ 0x4A1E3E49, 0xBC80CBC7,
+/**/ 0x704F5D26, 0x3FF1C9CF,
+/**/ 0x00000000, 0x40020000,
+/**/ 0xAFED62A2, 0x3F7C7A2E,
+/**/ 0x00000000, 0x3FECD000,
+/**/ 0x6B3395AA, 0x40026327,
+/**/ 0x33FB1467, 0x4015DD66,
+/**/ 0xDCF3437C, 0x403C0610,
+/**/ 0xC9D7C47A, 0x406607CE,
+/**/ 0xA330DC5C, 0x409360FB,
+/**/ 0x38A3194B, 0x40C240B4,
+/**/ 0xBAA6A879, 0x40F20437,
+/**/ 0x04D6F19C, 0x41226106,
+/**/ 0x15E5252C, 0x3CABCCF5,
+/**/ 0xFF35681A, 0x3FF1EE3F,
+/**/ 0x00000000, 0x40026000,
+/**/ 0x9CAD4CE9, 0x3F593B59,
+/**/ 0x00000000, 0x3FECF000,
+/**/ 0x664A8350, 0x4002BD54,
+/**/ 0x945190A0, 0x40173EFF,
+/**/ 0xC7CC5224, 0x403EFA80,
+/**/ 0x896F1658, 0x406958AA,
+/**/ 0x4FD54E04, 0x40973450,
+/**/ 0x4CD60C4A, 0x40C6BF55,
+/**/ 0x3EFFD07C, 0x40F75EBE,
+/**/ 0x9E2E6981, 0x4128D03C,
+/**/ 0xC8A488FF, 0xBC987CEE,
+/**/ 0x8F597306, 0x3FF2135F,
+/**/ 0x00000000, 0x4002C000,
+/**/ 0xABE583FE, 0xBF555CCD,
+/**/ 0x00000000, 0x3FED1000,
+/**/ 0x2A40EA5C, 0x40031D52,
+/**/ 0x52B4947D, 0x4018C6B3,
+/**/ 0x5D01146E, 0x404131AE,
+/**/ 0x0163E71C, 0x406D54FB,
+/**/ 0xEF3ED15B, 0x409BFE8A,
+/**/ 0xA33A6B00, 0x40CC9C28,
+/**/ 0x1456E1A6, 0x40FEA523,
+/**/ 0xFC8790DB, 0x4130F60F,
+/**/ 0x6FABCA41, 0x3CAC104F,
+/**/ 0x30D87C68, 0x3FF23939,
+/**/ 0x00000000, 0x40032000,
+/**/ 0xF8AD1CF9, 0xBF556EAD,
+/**/ 0x00000000, 0x3FED3000,
+/**/ 0xC053C623, 0x400383C4,
+/**/ 0x6ADBFF2C, 0x401A7A81,
+/**/ 0xE219A24E, 0x40432C5B,
+/**/ 0x30F4B8D8, 0x40711484,
+/**/ 0xBC59423E, 0x40A10659,
+/**/ 0x3D537AE5, 0x40D22C09,
+/**/ 0xA4B7D930, 0x410454A2,
+/**/ 0xC151F3C3, 0x41378151,
+/**/ 0x779E9951, 0xBCA2F226,
+/**/ 0x254E3F9C, 0x3FF25FD9,
+/**/ 0x00000000, 0x40038000,
+/**/ 0x9E311A8B, 0x3F5E2602,
+/**/ 0x00000000, 0x3FED5000,
+/**/ 0xA2F65F8C, 0x4003F16A,
+/**/ 0x36C0308E, 0x401C61AF,
+/**/ 0x5337FF7D, 0x40457C82,
+/**/ 0x7FB84BA9, 0x407407A3,
+/**/ 0x4C74DEA7, 0x40A4E476,
+/**/ 0xDF1C2124, 0x40D75638,
+/**/ 0xA2556E94, 0x410B5320,
+/**/ 0x7D68ABBE, 0x414087CD,
+/**/ 0x73A87AB9, 0xBCACD58C,
+/**/ 0x10017B06, 0x3FF2874D,
+/**/ 0x00000000, 0x40040000,
+/**/ 0x1340E849, 0xBF7D2ABA,
+/**/ 0x00000000, 0x3FED7000,
+/**/ 0x7BA9A810, 0x40046722,
+/**/ 0xCBC74735, 0x401E851F,
+/**/ 0xF3879985, 0x40483596,
+/**/ 0xCD297F00, 0x4077AAEB,
+/**/ 0x31669F50, 0x40A9E3C8,
+/**/ 0xB7CBB664, 0x40DE5420,
+/**/ 0xB75100A0, 0x41129F7B,
+/**/ 0x51D127BF, 0x4147A1C1,
+/**/ 0x46D9C78F, 0x3CAC647E,
+/**/ 0x304962AE, 0x3FF2AFA4,
+/**/ 0x00000000, 0x40046000,
+/**/ 0xA6A041C9, 0x3F6C89EE,
+/**/ 0x00000000, 0x3FED9000,
+/**/ 0x7A99A835, 0x4004E5F2,
+/**/ 0x15B0232D, 0x402077E5,
+/**/ 0xEE468866, 0x404B70C1,
+/**/ 0x43A041C3, 0x407C334A,
+/**/ 0x53D2C164, 0x40B036D1,
+/**/ 0x10CCEDBE, 0x40E3F7B1,
+/**/ 0xF6C2E560, 0x4119C160,
+/**/ 0x6D21D20F, 0x415131DD,
+/**/ 0x2EC50766, 0x41878683,
+/**/ 0xD1134ECC, 0xBCA95596,
+/**/ 0xA8F4B028, 0x3FF2D8EF,
+/**/ 0x00000000, 0x4004E000,
+/**/ 0x66A0D2C7, 0x3F67C9EA,
+/**/ 0x00000000, 0x3FEDB000,
+/**/ 0xD6373B90, 0x40056F11,
+/**/ 0xC3747DF3, 0x4021D7AC,
+/**/ 0x6A014D6F, 0x404F4EF3,
+/**/ 0x505C454B, 0x4080F4C4,
+/**/ 0x214975C5, 0x40B48D16,
+/**/ 0xF57BFAC6, 0x40EAACFD,
+/**/ 0x5225A6ED, 0x41222235,
+/**/ 0xACBA67AB, 0x41598643,
+/**/ 0xDE5D19B9, 0x419267B9,
+/**/ 0x42C92439, 0xBCAEF63C,
+/**/ 0xD86BED76, 0x3FF30342,
+/**/ 0x00000000, 0x40056000,
+/**/ 0x6E771F48, 0x3F7E23AC,
+/**/ 0x00000000, 0x3FEDD000,
+/**/ 0x3D2D8CF1, 0x400603F5,
+/**/ 0xEF4A10FA, 0x40236A84,
+/**/ 0x4EA265AF, 0x4051FDF3,
+/**/ 0xD944F636, 0x408499B5,
+/**/ 0x37F73BAC, 0x40BA64B8,
+/**/ 0x259B27FC, 0x40F21B9F,
+/**/ 0x265D5B9F, 0x412A0669,
+/**/ 0x3DC806E2, 0x41635D8E,
+/**/ 0x36AD8B00, 0x419D8657,
+/**/ 0x3FFCDCA3, 0x3CA4CEEB,
+/**/ 0xC69D2D10, 0x3FF32EB3,
+/**/ 0x00000000, 0x40060000,
+/**/ 0x6C678625, 0x3F5FA9E9,
+/**/ 0x00000000, 0x3FEDF000,
+/**/ 0x5FCDF915, 0x4006A65F,
+/**/ 0x68321BDA, 0x40253B6E,
+/**/ 0x706E8DA9, 0x4054D949,
+/**/ 0x4A70D2D7, 0x408950EF,
+/**/ 0x1F15E14E, 0x40C13319,
+/**/ 0x846A9BD5, 0x40F907B1,
+/**/ 0x17C39016, 0x4133139C,
+/**/ 0xBC86F11B, 0x416E1DA3,
+/**/ 0xD9F86F3B, 0x41A8597F,
+/**/ 0x7D0D5190, 0x3C32D4F8,
+/**/ 0xAFA88354, 0x3FF35B5B,
+/**/ 0x00000000, 0x4006A000,
+/**/ 0x37E455FD, 0x3F697D7F,
+/**/ 0x00000000, 0x3FEE1000,
+/**/ 0x41D1DBF9, 0x40075877,
+/**/ 0xF5852184, 0x402758A8,
+/**/ 0x65C0F467, 0x405861EE,
+/**/ 0xD2D91276, 0x408F83C0,
+/**/ 0x43EC3B0E, 0x40C6CA7C,
+/**/ 0x718322C8, 0x4101A722,
+/**/ 0x9533D806, 0x413CA4C6,
+/**/ 0xE9899583, 0x417812B7,
+/**/ 0x85EE8B86, 0x41B4B875,
+/**/ 0xD1AEEED1, 0xBC99DEFB,
+/**/ 0xB510476E, 0x3FF38957,
+/**/ 0x00000000, 0x40076000,
+/**/ 0xB8901BF9, 0xBF6E22F8,
+/**/ 0x00000000, 0x3FEE3000,
+/**/ 0xE1C37E57, 0x40081CE6,
+/**/ 0xD3DC9910, 0x4029D4F3,
+/**/ 0xE3095065, 0x405CD074,
+/**/ 0xC5C38224, 0x4093E764,
+/**/ 0x3CAE1F31, 0x40CEC5AE,
+/**/ 0xC0645F38, 0x41097A50,
+/**/ 0xD8A7F25E, 0x41461866,
+/**/ 0x8C2F04A3, 0x4183DAF5,
+/**/ 0xA9143C1F, 0x41C2450E,
+/**/ 0x9FD995BC, 0x3C7D25BE,
+/**/ 0xC35D33E6, 0x3FF3B8C9,
+/**/ 0x00000000, 0x40082000,
+/**/ 0xE40D49E0, 0xBF58C8F1,
+/**/ 0x00000000, 0x3FEE5000,
+/**/ 0x285640BB, 0x4008F706,
+/**/ 0x3B2B7CD1, 0x402CC96B,
+/**/ 0xC5341328, 0x40613ADF,
+/**/ 0x16E928A9, 0x4099908D,
+/**/ 0x7CC08A3C, 0x40D53986,
+/**/ 0x31DD3E45, 0x4112DFC5,
+/**/ 0xE2A13787, 0x41519499,
+/**/ 0xF94424AD, 0x4190F943,
+/**/ 0xCDCD49BE, 0x41D0C6BC,
+/**/ 0x6D41701D, 0xBC9E2458,
+/**/ 0xC088BD28, 0x3FF3E9D9,
+/**/ 0x00000000, 0x40090000,
+/**/ 0x537E8A00, 0xBF71F3AF,
+/**/ 0x00000000, 0x3FEE7000,
+/**/ 0x6562D1E0, 0x4009EB18,
+/**/ 0x75651223, 0x40302C31,
+/**/ 0x336E41C7, 0x4064E431,
+/**/ 0xA065DA69, 0x40A0BCA6,
+/**/ 0x917AF357, 0x40DE034D,
+/**/ 0x4168FB0F, 0x411CD2C1,
+/**/ 0x15BB794D, 0x415CFEB6,
+/**/ 0x6EFFD5E5, 0x419E3EE1,
+/**/ 0x1ACB4D9C, 0x41E024E7,
+/**/ 0xD93F153F, 0xBC9C29C8,
+/**/ 0x2183E810, 0x3FF41CB7,
+/**/ 0x00000000, 0x4009E000,
+/**/ 0xC5A3C038, 0x3F7630CA,
+/**/ 0x00000000, 0x3FEE9000,
+/**/ 0xA364196F, 0x400AFEA6,
+/**/ 0x0B19A2EB, 0x403258F3,
+/**/ 0x2520AC75, 0x4069BDA5,
+/**/ 0x8F67EDEA, 0x40A669BC,
+/**/ 0xC026C9F8, 0x40E5D78C,
+/**/ 0x1E3B36C2, 0x4126CCB4,
+/**/ 0xBF45C805, 0x4168EDE4,
+/**/ 0x8AC89E76, 0x41AC2F6A,
+/**/ 0x4CA9EB55, 0x41F0675E,
+/**/ 0x0D13E3DF, 0x42336AC1,
+/**/ 0xF2DE93A6, 0x3C9B1D74,
+/**/ 0x155FB22E, 0x3FF4519B,
+/**/ 0x00000000, 0x400B0000,
+/**/ 0xBE690E67, 0xBF4595C9,
+/**/ 0x00000000, 0x3FEEB000,
+/**/ 0x4BD1C065, 0x400C3908,
+/**/ 0x26C39FFD, 0x40350D88,
+/**/ 0x69D3E79E, 0x4070296B,
+/**/ 0xD7FEEA5D, 0x40AED279,
+/**/ 0xFD5BD547, 0x40F072A8,
+/**/ 0x4A08BB38, 0x4132CDB9,
+/**/ 0x536BED06, 0x41768482,
+/**/ 0x2F10E88D, 0x41BBE1FF,
+/**/ 0xABDBBDAC, 0x4201C966,
+/**/ 0x02E62DDA, 0x42471011,
+/**/ 0x3E907E71, 0xBCA0855D,
+/**/ 0x8FA73920, 0x3FF488CB,
+/**/ 0x00000000, 0x400C4000,
+/**/ 0xB8FE6DDF, 0xBF6BDED0,
+/**/ 0x00000000, 0x3FEED000,
+/**/ 0x12AAF9A9, 0x400DA439,
+/**/ 0x62F25109, 0x40387D46,
+/**/ 0x3F133A3F, 0x4074C339,
+/**/ 0x662036F9, 0x40B5E143,
+/**/ 0x74467831, 0x40F9CF04,
+/**/ 0x576C6FA8, 0x41404E10,
+/**/ 0xFF4F8E88, 0x41859489,
+/**/ 0xB44962A9, 0x41CD88D2,
+/**/ 0x97A288F3, 0x4214D838,
+/**/ 0x6CF738B3, 0x425DE10B,
+/**/ 0x5F7263CC, 0xBC8E9EA7,
+/**/ 0xAA786F36, 0x3FF4C29F,
+/**/ 0x00000000, 0x400DA000,
+/**/ 0xABE6A2AD, 0x3F60E44A,
+/**/ 0x00000000, 0x3FEEF000,
+/**/ 0xC169B52F, 0x400F4E35,
+/**/ 0x29E8699C, 0x403CF773,
+/**/ 0xFC1818D6, 0x407B6D37,
+/**/ 0x1386790A, 0x40C02655,
+/**/ 0x4FF79D1E, 0x41054A1F,
+/**/ 0x7DB0265A, 0x414E104A,
+/**/ 0xE5C8114B, 0x41963C39,
+/**/ 0xF52A87DB, 0x41E10156,
+/**/ 0x2E9E7ABE, 0x422ADD76,
+/**/ 0x6EC81361, 0x427586AB,
+/**/ 0xE395EEA6, 0x3C935690,
+/**/ 0x2E5965A2, 0x3FF4FF86,
+/**/ 0x00000000, 0x400F4000,
+/**/ 0xD36A5E70, 0x3F7C6B82 } };
+
+#endif
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/atnat.h b/libc/sysdeps/ieee754/dbl-64/atnat.h
new file mode 100644
index 000000000..72f67f01f
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/atnat.h
@@ -0,0 +1,167 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/************************************************************************/
+/* MODULE_NAME: atnat.h */
+/* */
+/* */
+/* common data and variables definition for BIG or LITTLE ENDIAN */
+/************************************************************************/
+#ifndef ATNAT_H
+#define ATNAT_H
+
+#define M 4
+
+#ifdef BIG_ENDI
+ static const number
+ /* polynomial I */
+/**/ d3 = {{0xbfd55555, 0x55555555} }, /* -0.333... */
+/**/ d5 = {{0x3fc99999, 0x999997fd} }, /* 0.199... */
+/**/ d7 = {{0xbfc24924, 0x923f7603} }, /* -0.142... */
+/**/ d9 = {{0x3fbc71c6, 0xe5129a3b} }, /* 0.111... */
+/**/ d11 = {{0xbfb74580, 0x22b13c25} }, /* -0.090... */
+/**/ d13 = {{0x3fb375f0, 0x8b31cbce} }, /* 0.076... */
+ /* polynomial II */
+/**/ f3 = {{0xbfd55555, 0x55555555} }, /* -1/3 */
+/**/ ff3 = {{0xbc755555, 0x55555555} }, /* -1/3-f3 */
+/**/ f5 = {{0x3fc99999, 0x9999999a} }, /* 1/5 */
+/**/ ff5 = {{0xbc699999, 0x9999999a} }, /* 1/5-f5 */
+/**/ f7 = {{0xbfc24924, 0x92492492} }, /* -1/7 */
+/**/ ff7 = {{0xbc624924, 0x92492492} }, /* -1/7-f7 */
+/**/ f9 = {{0x3fbc71c7, 0x1c71c71c} }, /* 1/9 */
+/**/ ff9 = {{0x3c5c71c7, 0x1c71c71c} }, /* 1/9-f9 */
+/**/ f11 = {{0xbfb745d1, 0x745d1746} }, /* -1/11 */
+/**/ f13 = {{0x3fb3b13b, 0x13b13b14} }, /* 1/13 */
+/**/ f15 = {{0xbfb11111, 0x11111111} }, /* -1/15 */
+/**/ f17 = {{0x3fae1e1e, 0x1e1e1e1e} }, /* 1/17 */
+/**/ f19 = {{0xbfaaf286, 0xbca1af28} }, /* -1/19 */
+ /* constants */
+/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */
+/**/ one = {{0x3ff00000, 0x00000000} }, /* 1 */
+/**/ a = {{0x3e4bb67a, 0x00000000} }, /* 1.290e-8 */
+/**/ b = {{0x3fb00000, 0x00000000} }, /* 1/16 */
+/**/ c = {{0x3ff00000, 0x00000000} }, /* 1 */
+/**/ d = {{0x40300000, 0x00000000} }, /* 16 */
+/**/ e = {{0x43349ff2, 0x00000000} }, /* 5.805e15 */
+/**/ hpi = {{0x3ff921fb, 0x54442d18} }, /* pi/2 */
+/**/ mhpi = {{0xbff921fb, 0x54442d18} }, /* -pi/2 */
+/**/ hpi1 = {{0x3c91a626, 0x33145c07} }, /* pi/2-hpi */
+/**/ u1 = {{0x3c2d3382, 0x00000000} }, /* 7.915e-19 */
+/**/ u21 = {{0x3c6dffc0, 0x00000000} }, /* 1.301e-17 */
+/**/ u22 = {{0x3c527bd0, 0x00000000} }, /* 4.008e-18 */
+/**/ u23 = {{0x3c3cd057, 0x00000000} }, /* 1.562e-18 */
+/**/ u24 = {{0x3c329cdf, 0x00000000} }, /* 1.009e-18 */
+/**/ u31 = {{0x3c3a1edf, 0x00000000} }, /* 1.416e-18 */
+/**/ u32 = {{0x3c33f0e1, 0x00000000} }, /* 1.081e-18 */
+/**/ u4 = {{0x3bf955e4, 0x00000000} }, /* 8.584e-20 */
+/**/ u5 = {{0x3aaef2d1, 0x00000000} }, /* 5e-26 */
+/**/ u6 = {{0x3a98c56d, 0x00000000} }, /* 2.001e-26 */
+/**/ u7 = {{0x3a9375de, 0x00000000} }, /* 1.572e-26 */
+/**/ u8 = {{0x3a6eeb36, 0x00000000} }, /* 3.122e-27 */
+/**/ u9[M] ={{{0x38c1aa5b, 0x00000000} }, /* 2.658e-35 */
+/**/ {{0x35c1aa4d, 0x00000000} }, /* 9.443e-50 */
+/**/ {{0x32c1aa88, 0x00000000} }, /* 3.355e-64 */
+/**/ {{0x11c1aa56, 0x00000000} }},/* 3.818e-223 */
+/**/ two8 = {{0x40700000, 0x00000000} }, /* 2**8=256 */
+/**/ two52 = {{0x43300000, 0x00000000} }; /* 2**52 */
+
+#else
+#ifdef LITTLE_ENDI
+ static const number
+ /* polynomial I */
+/**/ d3 = {{0x55555555, 0xbfd55555} }, /* -0.333... */
+/**/ d5 = {{0x999997fd, 0x3fc99999} }, /* 0.199... */
+/**/ d7 = {{0x923f7603, 0xbfc24924} }, /* -0.142... */
+/**/ d9 = {{0xe5129a3b, 0x3fbc71c6} }, /* 0.111... */
+/**/ d11 = {{0x22b13c25, 0xbfb74580} }, /* -0.090... */
+/**/ d13 = {{0x8b31cbce, 0x3fb375f0} }, /* 0.076... */
+ /* polynomial II */
+/**/ f3 = {{0x55555555, 0xbfd55555} }, /* -1/3 */
+/**/ ff3 = {{0x55555555, 0xbc755555} }, /* -1/3-f3 */
+/**/ f5 = {{0x9999999a, 0x3fc99999} }, /* 1/5 */
+/**/ ff5 = {{0x9999999a, 0xbc699999} }, /* 1/5-f5 */
+/**/ f7 = {{0x92492492, 0xbfc24924} }, /* -1/7 */
+/**/ ff7 = {{0x92492492, 0xbc624924} }, /* -1/7-f7 */
+/**/ f9 = {{0x1c71c71c, 0x3fbc71c7} }, /* 1/9 */
+/**/ ff9 = {{0x1c71c71c, 0x3c5c71c7} }, /* 1/9-f9 */
+/**/ f11 = {{0x745d1746, 0xbfb745d1} }, /* -1/11 */
+/**/ f13 = {{0x13b13b14, 0x3fb3b13b} }, /* 1/13 */
+/**/ f15 = {{0x11111111, 0xbfb11111} }, /* -1/15 */
+/**/ f17 = {{0x1e1e1e1e, 0x3fae1e1e} }, /* 1/17 */
+/**/ f19 = {{0xbca1af28, 0xbfaaf286} }, /* -1/19 */
+ /* constants */
+/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */
+/**/ one = {{0x00000000, 0x3ff00000} }, /* 1 */
+/**/ a = {{0x00000000, 0x3e4bb67a} }, /* 1.290e-8 */
+/**/ b = {{0x00000000, 0x3fb00000} }, /* 1/16 */
+/**/ c = {{0x00000000, 0x3ff00000} }, /* 1 */
+/**/ d = {{0x00000000, 0x40300000} }, /* 16 */
+/**/ e = {{0x00000000, 0x43349ff2} }, /* 5.805e15 */
+/**/ hpi = {{0x54442d18, 0x3ff921fb} }, /* pi/2 */
+/**/ mhpi = {{0x54442d18, 0xbff921fb} }, /* -pi/2 */
+/**/ hpi1 = {{0x33145c07, 0x3c91a626} }, /* pi/2-hpi */
+/**/ u1 = {{0x00000000, 0x3c2d3382} }, /* 7.915e-19 */
+/**/ u21 = {{0x00000000, 0x3c6dffc0} }, /* 1.301e-17 */
+/**/ u22 = {{0x00000000, 0x3c527bd0} }, /* 4.008e-18 */
+/**/ u23 = {{0x00000000, 0x3c3cd057} }, /* 1.562e-18 */
+/**/ u24 = {{0x00000000, 0x3c329cdf} }, /* 1.009e-18 */
+/**/ u31 = {{0x00000000, 0x3c3a1edf} }, /* 1.416e-18 */
+/**/ u32 = {{0x00000000, 0x3c33f0e1} }, /* 1.081e-18 */
+/**/ u4 = {{0x00000000, 0x3bf955e4} }, /* 8.584e-20 */
+/**/ u5 = {{0x00000000, 0x3aaef2d1} }, /* 5e-26 */
+/**/ u6 = {{0x00000000, 0x3a98c56d} }, /* 2.001e-26 */
+/**/ u7 = {{0x00000000, 0x3a9375de} }, /* 1.572e-26 */
+/**/ u8 = {{0x00000000, 0x3a6eeb36} }, /* 3.122e-27 */
+/**/ u9[M] ={{{0x00000000, 0x38c1aa5b} }, /* 2.658e-35 */
+/**/ {{0x00000000, 0x35c1aa4d} }, /* 9.443e-50 */
+/**/ {{0x00000000, 0x32c1aa88} }, /* 3.355e-64 */
+/**/ {{0x00000000, 0x11c1aa56} }},/* 3.818e-223 */
+/**/ two8 = {{0x00000000, 0x40700000} }, /* 2**8=256 */
+/**/ two52 = {{0x00000000, 0x43300000} }; /* 2**52 */
+
+#endif
+#endif
+
+#define ZERO zero.d
+#define ONE one.d
+#define A a.d
+#define B b.d
+#define C c.d
+#define D d.d
+#define E e.d
+#define HPI hpi.d
+#define MHPI mhpi.d
+#define HPI1 hpi1.d
+#define U1 u1.d
+#define U21 u21.d
+#define U22 u22.d
+#define U23 u23.d
+#define U24 u24.d
+#define U31 u31.d
+#define U32 u32.d
+#define U4 u4.d
+#define U5 u5.d
+#define U6 u6.d
+#define U7 u7.d
+#define U8 u8.d
+#define TWO8 two8.d
+#define TWO52 two52.d
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/atnat2.h b/libc/sysdeps/ieee754/dbl-64/atnat2.h
new file mode 100644
index 000000000..c6914ac0f
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/atnat2.h
@@ -0,0 +1,185 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/************************************************************************/
+/* MODULE_NAME: atnat2.h */
+/* */
+/* */
+/* common data and variables definition for BIG or LITTLE ENDIAN */
+/************************************************************************/
+
+
+
+#ifndef ATNAT2_H
+#define ATNAT2_H
+
+
+#define MM 5
+#ifdef BIG_ENDI
+
+ static const number
+ /* polynomial I */
+/**/ d3 = {{0xbfd55555, 0x55555555} }, /* -0.333... */
+/**/ d5 = {{0x3fc99999, 0x999997fd} }, /* 0.199... */
+/**/ d7 = {{0xbfc24924, 0x923f7603} }, /* -0.142... */
+/**/ d9 = {{0x3fbc71c6, 0xe5129a3b} }, /* 0.111... */
+/**/ d11 = {{0xbfb74580, 0x22b13c25} }, /* -0.090... */
+/**/ d13 = {{0x3fb375f0, 0x8b31cbce} }, /* 0.076... */
+ /* polynomial II */
+/**/ f3 = {{0xbfd55555, 0x55555555} }, /* -1/3 */
+/**/ ff3 = {{0xbc755555, 0x55555555} }, /* -1/3-f3 */
+/**/ f5 = {{0x3fc99999, 0x9999999a} }, /* 1/5 */
+/**/ ff5 = {{0xbc699999, 0x9999999a} }, /* 1/5-f5 */
+/**/ f7 = {{0xbfc24924, 0x92492492} }, /* -1/7 */
+/**/ ff7 = {{0xbc624924, 0x92492492} }, /* -1/7-f7 */
+/**/ f9 = {{0x3fbc71c7, 0x1c71c71c} }, /* 1/9 */
+/**/ ff9 = {{0x3c5c71c7, 0x1c71c71c} }, /* 1/9-f9 */
+/**/ f11 = {{0xbfb745d1, 0x745d1746} }, /* -1/11 */
+/**/ f13 = {{0x3fb3b13b, 0x13b13b14} }, /* 1/13 */
+/**/ f15 = {{0xbfb11111, 0x11111111} }, /* -1/15 */
+/**/ f17 = {{0x3fae1e1e, 0x1e1e1e1e} }, /* 1/17 */
+/**/ f19 = {{0xbfaaf286, 0xbca1af28} }, /* -1/19 */
+ /* constants */
+/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */
+/**/ mzero = {{0x80000000, 0x00000000} }, /* -0 */
+/**/ one = {{0x3ff00000, 0x00000000} }, /* 1 */
+/**/ inv16 = {{0x3fb00000, 0x00000000} }, /* 1/16 */
+/**/ opi = {{0x400921fb, 0x54442d18} }, /* pi */
+/**/ opi1 = {{0x3ca1a626, 0x33145c07} }, /* pi-opi */
+/**/ mopi = {{0xc00921fb, 0x54442d18} }, /* -pi */
+/**/ hpi = {{0x3ff921fb, 0x54442d18} }, /* pi/2 */
+/**/ hpi1 = {{0x3c91a626, 0x33145c07} }, /* pi/2-hpi */
+/**/ mhpi = {{0xbff921fb, 0x54442d18} }, /* -pi/2 */
+/**/ qpi = {{0x3fe921fb, 0x54442d18} }, /* pi/4 */
+/**/ qpi1 = {{0x3c81a626, 0x33145c07} }, /* pi/4-qpi */
+/**/ mqpi = {{0xbfe921fb, 0x54442d18} }, /* -pi/4 */
+/**/ tqpi = {{0x4002d97c, 0x7f3321d2} }, /* 3pi/4 */
+/**/ tqpi1 = {{0x3c9a7939, 0x4c9e8a0a} }, /* 3pi/4-tqpi */
+/**/ mtqpi = {{0xc002d97c, 0x7f3321d2} }, /* -3pi/4 */
+/**/ u1 = {{0x3c314c2a, 0x00000000} }, /* 9.377e-19 */
+/**/ u2 = {{0x3bf955e4, 0x00000000} }, /* 8.584e-20 */
+/**/ u3 = {{0x3bf955e4, 0x00000000} }, /* 8.584e-20 */
+/**/ u4 = {{0x3bf955e4, 0x00000000} }, /* 8.584e-20 */
+/**/ u5 = {{0x3aaef2d1, 0x00000000} }, /* 5e-26 */
+/**/ u6 = {{0x3a6eeb36, 0x00000000} }, /* 3.122e-27 */
+/**/ u7 = {{0x3a6eeb36, 0x00000000} }, /* 3.122e-27 */
+/**/ u8 = {{0x3a6eeb36, 0x00000000} }, /* 3.122e-27 */
+/**/ u91 = {{0x3c6dffc0, 0x00000000} }, /* 1.301e-17 */
+/**/ u92 = {{0x3c527bd0, 0x00000000} }, /* 4.008e-18 */
+/**/ u93 = {{0x3c3cd057, 0x00000000} }, /* 1.562e-18 */
+/**/ u94 = {{0x3c329cdf, 0x00000000} }, /* 1.009e-18 */
+/**/ ua1 = {{0x3c3a1edf, 0x00000000} }, /* 1.416e-18 */
+/**/ ua2 = {{0x3c33f0e1, 0x00000000} }, /* 1.081e-18 */
+/**/ ub = {{0x3a98c56d, 0x00000000} }, /* 2.001e-26 */
+/**/ uc = {{0x3a9375de, 0x00000000} }, /* 1.572e-26 */
+/**/ ud[MM] ={{{0x38c6eddf, 0x00000000} }, /* 3.450e-35 */
+/**/ {{0x35c6ef60, 0x00000000} }, /* 1.226e-49 */
+/**/ {{0x32c6ed2f, 0x00000000} }, /* 4.354e-64 */
+/**/ {{0x23c6eee8, 0x00000000} }, /* 2.465e-136 */
+/**/ {{0x11c6ed16, 0x00000000} }},/* 4.955e-223 */
+/**/ ue = {{0x38900e9d, 0x00000000} }, /* 3.02e-36 */
+/**/ two8 = {{0x40700000, 0x00000000} }, /* 2**8=256 */
+/**/ two52 = {{0x43300000, 0x00000000} }, /* 2**52 */
+/**/ two500 = {{0x5f300000, 0x00000000} }, /* 2**500 */
+/**/ twom500 = {{0x20b00000, 0x00000000} }, /* 2**(-500) */
+/**/ twom1022 = {{0x00100000, 0x00000000} }; /* 2**(-1022) */
+
+#else
+#ifdef LITTLE_ENDI
+
+ static const number
+ /* polynomial I */
+/**/ d3 = {{0x55555555, 0xbfd55555} }, /* -0.333... */
+/**/ d5 = {{0x999997fd, 0x3fc99999} }, /* 0.199... */
+/**/ d7 = {{0x923f7603, 0xbfc24924} }, /* -0.142... */
+/**/ d9 = {{0xe5129a3b, 0x3fbc71c6} }, /* 0.111... */
+/**/ d11 = {{0x22b13c25, 0xbfb74580} }, /* -0.090... */
+/**/ d13 = {{0x8b31cbce, 0x3fb375f0} }, /* 0.076... */
+ /* polynomial II */
+/**/ f3 = {{0x55555555, 0xbfd55555} }, /* -1/3 */
+/**/ ff3 = {{0x55555555, 0xbc755555} }, /* -1/3-f3 */
+/**/ f5 = {{0x9999999a, 0x3fc99999} }, /* 1/5 */
+/**/ ff5 = {{0x9999999a, 0xbc699999} }, /* 1/5-f5 */
+/**/ f7 = {{0x92492492, 0xbfc24924} }, /* -1/7 */
+/**/ ff7 = {{0x92492492, 0xbc624924} }, /* -1/7-f7 */
+/**/ f9 = {{0x1c71c71c, 0x3fbc71c7} }, /* 1/9 */
+/**/ ff9 = {{0x1c71c71c, 0x3c5c71c7} }, /* 1/9-f9 */
+/**/ f11 = {{0x745d1746, 0xbfb745d1} }, /* -1/11 */
+/**/ f13 = {{0x13b13b14, 0x3fb3b13b} }, /* 1/13 */
+/**/ f15 = {{0x11111111, 0xbfb11111} }, /* -1/15 */
+/**/ f17 = {{0x1e1e1e1e, 0x3fae1e1e} }, /* 1/17 */
+/**/ f19 = {{0xbca1af28, 0xbfaaf286} }, /* -1/19 */
+ /* constants */
+/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */
+/**/ mzero = {{0x00000000, 0x80000000} }, /* -0 */
+/**/ one = {{0x00000000, 0x3ff00000} }, /* 1 */
+/**/ inv16 = {{0x00000000, 0x3fb00000} }, /* 1/16 */
+/**/ opi = {{0x54442d18, 0x400921fb} }, /* pi */
+/**/ opi1 = {{0x33145c07, 0x3ca1a626} }, /* pi-opi */
+/**/ mopi = {{0x54442d18, 0xc00921fb} }, /* -pi */
+/**/ hpi = {{0x54442d18, 0x3ff921fb} }, /* pi/2 */
+/**/ hpi1 = {{0x33145c07, 0x3c91a626} }, /* pi/2-hpi */
+/**/ mhpi = {{0x54442d18, 0xbff921fb} }, /* -pi/2 */
+/**/ qpi = {{0x54442d18, 0x3fe921fb} }, /* pi/4 */
+/**/ qpi1 = {{0x33145c07, 0x3c81a626} }, /* pi/4-qpi */
+/**/ mqpi = {{0x54442d18, 0xbfe921fb} }, /* -pi/4 */
+/**/ tqpi = {{0x7f3321d2, 0x4002d97c} }, /* 3pi/4 */
+/**/ tqpi1 = {{0x4c9e8a0a, 0x3c9a7939} }, /* 3pi/4-tqpi */
+/**/ mtqpi = {{0x7f3321d2, 0xc002d97c} }, /* -3pi/4 */
+/**/ u1 = {{0x00000000, 0x3c314c2a} }, /* 9.377e-19 */
+/**/ u2 = {{0x00000000, 0x3bf955e4} }, /* 8.584e-20 */
+/**/ u3 = {{0x00000000, 0x3bf955e4} }, /* 8.584e-20 */
+/**/ u4 = {{0x00000000, 0x3bf955e4} }, /* 8.584e-20 */
+/**/ u5 = {{0x00000000, 0x3aaef2d1} }, /* 5e-26 */
+/**/ u6 = {{0x00000000, 0x3a6eeb36} }, /* 3.122e-27 */
+/**/ u7 = {{0x00000000, 0x3a6eeb36} }, /* 3.122e-27 */
+/**/ u8 = {{0x00000000, 0x3a6eeb36} }, /* 3.122e-27 */
+/**/ u91 = {{0x00000000, 0x3c6dffc0} }, /* 1.301e-17 */
+/**/ u92 = {{0x00000000, 0x3c527bd0} }, /* 4.008e-18 */
+/**/ u93 = {{0x00000000, 0x3c3cd057} }, /* 1.562e-18 */
+/**/ u94 = {{0x00000000, 0x3c329cdf} }, /* 1.009e-18 */
+/**/ ua1 = {{0x00000000, 0x3c3a1edf} }, /* 1.416e-18 */
+/**/ ua2 = {{0x00000000, 0x3c33f0e1} }, /* 1.081e-18 */
+/**/ ub = {{0x00000000, 0x3a98c56d} }, /* 2.001e-26 */
+/**/ uc = {{0x00000000, 0x3a9375de} }, /* 1.572e-26 */
+/**/ ud[MM] ={{{0x00000000, 0x38c6eddf} }, /* 3.450e-35 */
+/**/ {{0x00000000, 0x35c6ef60} }, /* 1.226e-49 */
+/**/ {{0x00000000, 0x32c6ed2f} }, /* 4.354e-64 */
+/**/ {{0x00000000, 0x23c6eee8} }, /* 2.465e-136 */
+/**/ {{0x00000000, 0x11c6ed16} }},/* 4.955e-223 */
+/**/ ue = {{0x00000000, 0x38900e9d} }, /* 3.02e-36 */
+/**/ two8 = {{0x00000000, 0x40700000} }, /* 2**8=256 */
+/**/ two52 = {{0x00000000, 0x43300000} }, /* 2**52 */
+/**/ two500 = {{0x00000000, 0x5f300000} }, /* 2**500 */
+/**/ twom500 = {{0x00000000, 0x20b00000} }, /* 2**(-500) */
+/**/ twom1022 = {{0x00000000, 0x00100000} }; /* 2**(-1022) */
+
+#endif
+#endif
+
+#define ZERO zero.d
+#define MZERO mzero.d
+#define ONE one.d
+#define TWO8 two8.d
+#define TWO52 two52.d
+#define TWOM1022 twom1022.d
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/branred.c b/libc/sysdeps/ieee754/dbl-64/branred.c
new file mode 100644
index 000000000..76015f0c5
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/branred.c
@@ -0,0 +1,144 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*******************************************************************/
+/* */
+/* MODULE_NAME: branred.c */
+/* */
+/* FUNCTIONS: branred */
+/* */
+/* FILES NEEDED: branred.h mydefs.h endian.h mpa.h */
+/* mha.c */
+/* */
+/* Routine branred() performs range reduction of a double number */
+/* x into Double length number a+aa,such that */
+/* x=n*pi/2+(a+aa), abs(a+aa)<pi/4, n=0,+-1,+-2,.... */
+/* Routine returns the integer (n mod 4) of the above description */
+/* of x. */
+/*******************************************************************/
+
+#include "endian.h"
+#include "mydefs.h"
+#include "branred.h"
+#include "math_private.h"
+
+
+/*******************************************************************/
+/* Routine branred() performs range reduction of a double number */
+/* x into Double length number a+aa,such that */
+/* x=n*pi/2+(a+aa), abs(a+aa)<pi/4, n=0,+-1,+-2,.... */
+/* Routine return integer (n mod 4) */
+/*******************************************************************/
+int __branred(double x, double *a, double *aa)
+{
+ int i,k;
+#if 0
+ int n;
+#endif
+ mynumber u,gor;
+#if 0
+ mynumber v;
+#endif
+ double r[6],s,t,sum,b,bb,sum1,sum2,b1,bb1,b2,bb2,x1,x2,t1,t2;
+
+ x*=tm600.x;
+ t=x*split; /* split x to two numbers */
+ x1=t-(t-x);
+ x2=x-x1;
+ sum=0;
+ u.x = x1;
+ k = (u.i[HIGH_HALF]>>20)&2047;
+ k = (k-450)/24;
+ if (k<0)
+ k=0;
+ gor.x = t576.x;
+ gor.i[HIGH_HALF] -= ((k*24)<<20);
+ for (i=0;i<6;i++)
+ { r[i] = x1*toverp[k+i]*gor.x; gor.x *= tm24.x; }
+ for (i=0;i<3;i++) {
+ s=(r[i]+big.x)-big.x;
+ sum+=s;
+ r[i]-=s;
+ }
+ t=0;
+ for (i=0;i<6;i++)
+ t+=r[5-i];
+ bb=(((((r[0]-t)+r[1])+r[2])+r[3])+r[4])+r[5];
+ s=(t+big.x)-big.x;
+ sum+=s;
+ t-=s;
+ b=t+bb;
+ bb=(t-b)+bb;
+ s=(sum+big1.x)-big1.x;
+ sum-=s;
+ b1=b;
+ bb1=bb;
+ sum1=sum;
+ sum=0;
+
+ u.x = x2;
+ k = (u.i[HIGH_HALF]>>20)&2047;
+ k = (k-450)/24;
+ if (k<0)
+ k=0;
+ gor.x = t576.x;
+ gor.i[HIGH_HALF] -= ((k*24)<<20);
+ for (i=0;i<6;i++)
+ { r[i] = x2*toverp[k+i]*gor.x; gor.x *= tm24.x; }
+ for (i=0;i<3;i++) {
+ s=(r[i]+big.x)-big.x;
+ sum+=s;
+ r[i]-=s;
+ }
+ t=0;
+ for (i=0;i<6;i++)
+ t+=r[5-i];
+ bb=(((((r[0]-t)+r[1])+r[2])+r[3])+r[4])+r[5];
+ s=(t+big.x)-big.x;
+ sum+=s;
+ t-=s;
+ b=t+bb;
+ bb=(t-b)+bb;
+ s=(sum+big1.x)-big1.x;
+ sum-=s;
+
+ b2=b;
+ bb2=bb;
+ sum2=sum;
+
+ sum=sum1+sum2;
+ b=b1+b2;
+ bb = (ABS(b1)>ABS(b2))? (b1-b)+b2 : (b2-b)+b1;
+ if (b > 0.5)
+ {b-=1.0; sum+=1.0;}
+ else if (b < -0.5)
+ {b+=1.0; sum-=1.0;}
+ s=b+(bb+bb1+bb2);
+ t=((b-s)+bb)+(bb1+bb2);
+ b=s*split;
+ t1=b-(b-s);
+ t2=s-t1;
+ b=s*hp0.x;
+ bb=(((t1*mp1.x-b)+t1*mp2.x)+t2*mp1.x)+(t2*mp2.x+s*hp1.x+t*hp0.x);
+ s=b+bb;
+ t=(b-s)+bb;
+ *a=s;
+ *aa=t;
+ return ((int) sum)&3; /* return quater of unit circle */
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/branred.h b/libc/sysdeps/ieee754/dbl-64/branred.h
new file mode 100644
index 000000000..48f897664
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/branred.h
@@ -0,0 +1,80 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/************************************************************************/
+/* MODULE_NAME: branred.h */
+/* */
+/* */
+/* common data and variables definition for BIG or LITTLE ENDIAN */
+/************************************************************************/
+
+#ifndef BRANRED_H
+#define BRANRED_H
+
+
+#ifdef BIG_ENDI
+static const mynumber
+
+/**/ t576 = {{0x63f00000, 0x00000000}}, /* 2 ^ 576 */
+/**/ tm600 = {{0x1a700000, 0x00000000}}, /* 2 ^- 600 */
+/**/ tm24 = {{0x3e700000, 0x00000000}}, /* 2 ^- 24 */
+/**/ big = {{0x43380000, 0x00000000}}, /* 6755399441055744 */
+/**/ big1 = {{0x43580000, 0x00000000}}, /* 27021597764222976 */
+/**/ hp0 = {{0x3FF921FB, 0x54442D18}} ,/* 1.5707963267948966 */
+/**/ hp1 = {{0x3C91A626, 0x33145C07}} ,/* 6.123233995736766e-17 */
+/**/ mp1 = {{0x3FF921FB, 0x58000000}}, /* 1.5707963407039642 */
+/**/ mp2 = {{0xBE4DDE97, 0x40000000}}; /*-1.3909067675399456e-08 */
+
+#else
+#ifdef LITTLE_ENDI
+static const mynumber
+
+/**/ t576 = {{0x00000000, 0x63f00000}}, /* 2 ^ 576 */
+/**/ tm600 = {{0x00000000, 0x1a700000}}, /* 2 ^- 600 */
+/**/ tm24 = {{0x00000000, 0x3e700000}}, /* 2 ^- 24 */
+/**/ big = {{0x00000000, 0x43380000}}, /* 6755399441055744 */
+/**/ big1 = {{0x00000000, 0x43580000}}, /* 27021597764222976 */
+/**/ hp0 = {{0x54442D18, 0x3FF921FB}}, /* 1.5707963267948966 */
+/**/ hp1 = {{0x33145C07, 0x3C91A626}}, /* 6.123233995736766e-17 */
+/**/ mp1 = {{0x58000000, 0x3FF921FB}}, /* 1.5707963407039642 */
+/**/ mp2 = {{0x40000000, 0xBE4DDE97}}; /*-1.3909067675399456e-08 */
+
+#endif
+#endif
+
+static const double toverp[75] = { /* 2/ PI base 24*/
+ 10680707.0, 7228996.0, 1387004.0, 2578385.0, 16069853.0,
+ 12639074.0, 9804092.0, 4427841.0, 16666979.0, 11263675.0,
+ 12935607.0, 2387514.0, 4345298.0, 14681673.0, 3074569.0,
+ 13734428.0, 16653803.0, 1880361.0, 10960616.0, 8533493.0,
+ 3062596.0, 8710556.0, 7349940.0, 6258241.0, 3772886.0,
+ 3769171.0, 3798172.0, 8675211.0, 12450088.0, 3874808.0,
+ 9961438.0, 366607.0, 15675153.0, 9132554.0, 7151469.0,
+ 3571407.0, 2607881.0, 12013382.0, 4155038.0, 6285869.0,
+ 7677882.0, 13102053.0, 15825725.0, 473591.0, 9065106.0,
+ 15363067.0, 6271263.0, 9264392.0, 5636912.0, 4652155.0,
+ 7056368.0, 13614112.0, 10155062.0, 1944035.0, 9527646.0,
+ 15080200.0, 6658437.0, 6231200.0, 6832269.0, 16767104.0,
+ 5075751.0, 3212806.0, 1398474.0, 7579849.0, 6349435.0,
+ 12618859.0, 4703257.0, 12806093.0, 14477321.0, 2786137.0,
+ 12875403.0, 9837734.0, 14528324.0, 13719321.0, 343717.0 };
+
+static const double split = 134217729.0;
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/dbl2mpn.c b/libc/sysdeps/ieee754/dbl-64/dbl2mpn.c
new file mode 100644
index 000000000..d04c0e183
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/dbl2mpn.c
@@ -0,0 +1,108 @@
+/* Copyright (C) 1993,1994,1995,1996,1997,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include <ieee754.h>
+#include <float.h>
+#include <stdlib.h>
+
+/* Convert a `double' in IEEE754 standard double-precision format to a
+ multi-precision integer representing the significand scaled up by its
+ number of bits (52 for double) and an integral power of two (MPN frexp). */
+
+mp_size_t
+__mpn_extract_double (mp_ptr res_ptr, mp_size_t size,
+ int *expt, int *is_neg,
+ double value)
+{
+ union ieee754_double u;
+ u.d = value;
+
+ *is_neg = u.ieee.negative;
+ *expt = (int) u.ieee.exponent - IEEE754_DOUBLE_BIAS;
+
+#if BITS_PER_MP_LIMB == 32
+ res_ptr[0] = u.ieee.mantissa1; /* Low-order 32 bits of fraction. */
+ res_ptr[1] = u.ieee.mantissa0; /* High-order 20 bits. */
+ #define N 2
+#elif BITS_PER_MP_LIMB == 64
+ /* Hopefully the compiler will combine the two bitfield extracts
+ and this composition into just the original quadword extract. */
+ res_ptr[0] = ((mp_limb_t) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
+ #define N 1
+#else
+ #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+/* The format does not fill the last limb. There are some zeros. */
+#define NUM_LEADING_ZEROS (BITS_PER_MP_LIMB \
+ - (DBL_MANT_DIG - ((N - 1) * BITS_PER_MP_LIMB)))
+
+ if (u.ieee.exponent == 0)
+ {
+ /* A biased exponent of zero is a special case.
+ Either it is a zero or it is a denormal number. */
+ if (res_ptr[0] == 0 && res_ptr[N - 1] == 0) /* Assumes N<=2. */
+ /* It's zero. */
+ *expt = 0;
+ else
+ {
+ /* It is a denormal number, meaning it has no implicit leading
+ one bit, and its exponent is in fact the format minimum. */
+ int cnt;
+
+ if (res_ptr[N - 1] != 0)
+ {
+ count_leading_zeros (cnt, res_ptr[N - 1]);
+ cnt -= NUM_LEADING_ZEROS;
+#if N == 2
+ res_ptr[N - 1] = res_ptr[1] << cnt
+ | (N - 1)
+ * (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt));
+ res_ptr[0] <<= cnt;
+#else
+ res_ptr[N - 1] <<= cnt;
+#endif
+ *expt = DBL_MIN_EXP - 1 - cnt;
+ }
+ else
+ {
+ count_leading_zeros (cnt, res_ptr[0]);
+ if (cnt >= NUM_LEADING_ZEROS)
+ {
+ res_ptr[N - 1] = res_ptr[0] << (cnt - NUM_LEADING_ZEROS);
+ res_ptr[0] = 0;
+ }
+ else
+ {
+ res_ptr[N - 1] = res_ptr[0] >> (NUM_LEADING_ZEROS - cnt);
+ res_ptr[0] <<= BITS_PER_MP_LIMB - (NUM_LEADING_ZEROS - cnt);
+ }
+ *expt = DBL_MIN_EXP - 1
+ - (BITS_PER_MP_LIMB - NUM_LEADING_ZEROS) - cnt;
+ }
+ }
+ }
+ else
+ /* Add the implicit leading one bit for a normalized number. */
+ res_ptr[N - 1] |= (mp_limb_t) 1 << (DBL_MANT_DIG - 1
+ - ((N - 1) * BITS_PER_MP_LIMB));
+
+ return N;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/dla.h b/libc/sysdeps/ieee754/dbl-64/dla.h
new file mode 100644
index 000000000..bf73fa902
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/dla.h
@@ -0,0 +1,174 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/***********************************************************************/
+/*MODULE_NAME: dla.h */
+/* */
+/* This file holds C language macros for 'Double Length Floating Point */
+/* Arithmetic'. The macros are based on the paper: */
+/* T.J.Dekker, "A floating-point Technique for extending the */
+/* Available Precision", Number. Math. 18, 224-242 (1971). */
+/* A Double-Length number is defined by a pair (r,s), of IEEE double */
+/* precision floating point numbers that satisfy, */
+/* */
+/* abs(s) <= abs(r+s)*2**(-53)/(1+2**(-53)). */
+/* */
+/* The computer arithmetic assumed is IEEE double precision in */
+/* round to nearest mode. All variables in the macros must be of type */
+/* IEEE double. */
+/***********************************************************************/
+
+/* CN = 1+2**27 = '41a0000002000000' IEEE double format */
+#define CN 134217729.0
+
+
+/* Exact addition of two single-length floating point numbers, Dekker. */
+/* The macro produces a double-length number (z,zz) that satisfies */
+/* z+zz = x+y exactly. */
+
+#define EADD(x,y,z,zz) \
+ z=(x)+(y); zz=(ABS(x)>ABS(y)) ? (((x)-(z))+(y)) : (((y)-(z))+(x));
+
+
+/* Exact subtraction of two single-length floating point numbers, Dekker. */
+/* The macro produces a double-length number (z,zz) that satisfies */
+/* z+zz = x-y exactly. */
+
+#define ESUB(x,y,z,zz) \
+ z=(x)-(y); zz=(ABS(x)>ABS(y)) ? (((x)-(z))-(y)) : ((x)-((y)+(z)));
+
+
+/* Exact multiplication of two single-length floating point numbers, */
+/* Veltkamp. The macro produces a double-length number (z,zz) that */
+/* satisfies z+zz = x*y exactly. p,hx,tx,hy,ty are temporary */
+/* storage variables of type double. */
+
+#define EMULV(x,y,z,zz,p,hx,tx,hy,ty) \
+ p=CN*(x); hx=((x)-p)+p; tx=(x)-hx; \
+ p=CN*(y); hy=((y)-p)+p; ty=(y)-hy; \
+ z=(x)*(y); zz=(((hx*hy-z)+hx*ty)+tx*hy)+tx*ty;
+
+
+/* Exact multiplication of two single-length floating point numbers, Dekker. */
+/* The macro produces a nearly double-length number (z,zz) (see Dekker) */
+/* that satisfies z+zz = x*y exactly. p,hx,tx,hy,ty,q are temporary */
+/* storage variables of type double. */
+
+#define MUL12(x,y,z,zz,p,hx,tx,hy,ty,q) \
+ p=CN*(x); hx=((x)-p)+p; tx=(x)-hx; \
+ p=CN*(y); hy=((y)-p)+p; ty=(y)-hy; \
+ p=hx*hy; q=hx*ty+tx*hy; z=p+q; zz=((p-z)+q)+tx*ty;
+
+
+/* Double-length addition, Dekker. The macro produces a double-length */
+/* number (z,zz) which satisfies approximately z+zz = x+xx + y+yy. */
+/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy) */
+/* are assumed to be double-length numbers. r,s are temporary */
+/* storage variables of type double. */
+
+#define ADD2(x,xx,y,yy,z,zz,r,s) \
+ r=(x)+(y); s=(ABS(x)>ABS(y)) ? \
+ (((((x)-r)+(y))+(yy))+(xx)) : \
+ (((((y)-r)+(x))+(xx))+(yy)); \
+ z=r+s; zz=(r-z)+s;
+
+
+/* Double-length subtraction, Dekker. The macro produces a double-length */
+/* number (z,zz) which satisfies approximately z+zz = x+xx - (y+yy). */
+/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy) */
+/* are assumed to be double-length numbers. r,s are temporary */
+/* storage variables of type double. */
+
+#define SUB2(x,xx,y,yy,z,zz,r,s) \
+ r=(x)-(y); s=(ABS(x)>ABS(y)) ? \
+ (((((x)-r)-(y))-(yy))+(xx)) : \
+ ((((x)-((y)+r))+(xx))-(yy)); \
+ z=r+s; zz=(r-z)+s;
+
+
+/* Double-length multiplication, Dekker. The macro produces a double-length */
+/* number (z,zz) which satisfies approximately z+zz = (x+xx)*(y+yy). */
+/* An error bound: abs((x+xx)*(y+yy))*1.24e-31. (x,xx), (y,yy) */
+/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc are */
+/* temporary storage variables of type double. */
+
+#define MUL2(x,xx,y,yy,z,zz,p,hx,tx,hy,ty,q,c,cc) \
+ MUL12(x,y,c,cc,p,hx,tx,hy,ty,q) \
+ cc=((x)*(yy)+(xx)*(y))+cc; z=c+cc; zz=(c-z)+cc;
+
+
+/* Double-length division, Dekker. The macro produces a double-length */
+/* number (z,zz) which satisfies approximately z+zz = (x+xx)/(y+yy). */
+/* An error bound: abs((x+xx)/(y+yy))*1.50e-31. (x,xx), (y,yy) */
+/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc,u,uu */
+/* are temporary storage variables of type double. */
+
+#define DIV2(x,xx,y,yy,z,zz,p,hx,tx,hy,ty,q,c,cc,u,uu) \
+ c=(x)/(y); MUL12(c,y,u,uu,p,hx,tx,hy,ty,q) \
+ cc=(((((x)-u)-uu)+(xx))-c*(yy))/(y); z=c+cc; zz=(c-z)+cc;
+
+
+/* Double-length addition, slower but more accurate than ADD2. */
+/* The macro produces a double-length */
+/* number (z,zz) which satisfies approximately z+zz = (x+xx)+(y+yy). */
+/* An error bound: abs(x+xx + y+yy)*1.50e-31. (x,xx), (y,yy) */
+/* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */
+/* are temporary storage variables of type double. */
+
+#define ADD2A(x,xx,y,yy,z,zz,r,rr,s,ss,u,uu,w) \
+ r=(x)+(y); \
+ if (ABS(x)>ABS(y)) { rr=((x)-r)+(y); s=(rr+(yy))+(xx); } \
+ else { rr=((y)-r)+(x); s=(rr+(xx))+(yy); } \
+ if (rr!=0.0) { \
+ z=r+s; zz=(r-z)+s; } \
+ else { \
+ ss=(ABS(xx)>ABS(yy)) ? (((xx)-s)+(yy)) : (((yy)-s)+(xx)); \
+ u=r+s; \
+ uu=(ABS(r)>ABS(s)) ? ((r-u)+s) : ((s-u)+r) ; \
+ w=uu+ss; z=u+w; \
+ zz=(ABS(u)>ABS(w)) ? ((u-z)+w) : ((w-z)+u) ; }
+
+
+/* Double-length subtraction, slower but more accurate than SUB2. */
+/* The macro produces a double-length */
+/* number (z,zz) which satisfies approximately z+zz = (x+xx)-(y+yy). */
+/* An error bound: abs(x+xx - (y+yy))*1.50e-31. (x,xx), (y,yy) */
+/* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */
+/* are temporary storage variables of type double. */
+
+#define SUB2A(x,xx,y,yy,z,zz,r,rr,s,ss,u,uu,w) \
+ r=(x)-(y); \
+ if (ABS(x)>ABS(y)) { rr=((x)-r)-(y); s=(rr-(yy))+(xx); } \
+ else { rr=(x)-((y)+r); s=(rr+(xx))-(yy); } \
+ if (rr!=0.0) { \
+ z=r+s; zz=(r-z)+s; } \
+ else { \
+ ss=(ABS(xx)>ABS(yy)) ? (((xx)-s)-(yy)) : ((xx)-((yy)+s)); \
+ u=r+s; \
+ uu=(ABS(r)>ABS(s)) ? ((r-u)+s) : ((s-u)+r) ; \
+ w=uu+ss; z=u+w; \
+ zz=(ABS(u)>ABS(w)) ? ((u-z)+w) : ((w-z)+u) ; }
+
+
+
+
+
+
+
diff --git a/libc/sysdeps/ieee754/dbl-64/doasin.c b/libc/sysdeps/ieee754/dbl-64/doasin.c
new file mode 100644
index 000000000..79f344af2
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/doasin.c
@@ -0,0 +1,76 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/**********************************************************************/
+/* MODULE_NAME: doasin.c */
+/* */
+/* FUNCTION: doasin */
+/* */
+/* FILES NEEDED:endian.h mydefs.h dla.h doasin.h */
+/* mpa.c */
+/* */
+/* Compute arcsin(x,dx,v) of double-length number (x+dx) the result */
+/* stored in v where v= v[0]+v[1] =arcsin(x+dx) */
+/**********************************************************************/
+
+#include "endian.h"
+#include "mydefs.h"
+#include "dla.h"
+#include "math_private.h"
+
+/********************************************************************/
+/* Compute arcsin(x,dx,v) of double-length number (x+dx) the result */
+/* stored in v where v= v[0]+v[1] =arcsin(x+dx) */
+/********************************************************************/
+void __doasin(double x, double dx, double v[]) {
+
+#include "doasin.h"
+
+ static const double
+ d5 = 0.22372159090911789889975459505194491E-01,
+ d6 = 0.17352764422456822913014975683014622E-01,
+ d7 = 0.13964843843786693521653681033981614E-01,
+ d8 = 0.11551791438485242609036067259086589E-01,
+ d9 = 0.97622386568166960207425666787248914E-02,
+ d10 = 0.83638737193775788576092749009744976E-02,
+ d11 = 0.79470250400727425881446981833568758E-02;
+
+ double xx,p,pp,u,uu,r,s;
+ double hx,tx,hy,ty,tp,tq,tc,tcc;
+
+
+/* Taylor series for arcsin for Double-Length numbers */
+ xx = x*x+2.0*x*dx;
+ p = ((((((d11*xx+d10)*xx+d9)*xx+d8)*xx+d7)*xx+d6)*xx+d5)*xx;
+ pp = 0;
+
+ MUL2(x,dx,x,dx,u,uu,tp,hx,tx,hy,ty,tq,tc,tcc);
+ ADD2(p,pp,c4.x,cc4.x,p,pp,r,s);
+ MUL2(p,pp,u,uu,p,pp,tp,hx,tx,hy,ty,tq,tc,tcc);
+ ADD2(p,pp,c3.x,cc3.x,p,pp,r,s);
+ MUL2(p,pp,u,uu,p,pp,tp,hx,tx,hy,ty,tq,tc,tcc);
+ ADD2(p,pp,c2.x,cc2.x,p,pp,r,s);
+ MUL2(p,pp,u,uu,p,pp,tp,hx,tx,hy,ty,tq,tc,tcc);
+ ADD2(p,pp,c1.x,cc1.x,p,pp,r,s);
+ MUL2(p,pp,u,uu,p,pp,tp,hx,tx,hy,ty,tq,tc,tcc);
+ MUL2(p,pp,x,dx,p,pp,tp,hx,tx,hy,ty,tq,tc,tcc);
+ ADD2(p,pp,x,dx,p,pp,r,s);
+ v[0]=p;
+ v[1]=pp; /* arcsin(x+dx)=v[0]+v[1] */
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/doasin.h b/libc/sysdeps/ieee754/dbl-64/doasin.h
new file mode 100644
index 000000000..0625e5185
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/doasin.h
@@ -0,0 +1,64 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/************************************************************************/
+/* MODULE_NAME: doasin.h */
+/* */
+/* */
+/* common data and variables definition for BIG or LITTLE ENDIAN */
+/************************************************************************/
+
+
+
+#ifndef DOASIN_H
+#define DOASIN_H
+
+#ifdef BIG_ENDI
+
+ static const mynumber
+/**/ c1 = {{0x3FC55555, 0x55555555}}, /* 0.16666666666666666 */
+/**/ cc1 = {{0x3C655555, 0x55775389}}, /* 9.2518585419753846e-18 */
+/**/ c2 = {{0x3FB33333, 0x33333333}}, /* 0.074999999999999997 */
+/**/ cc2 = {{0x3C499993, 0x63F1A115}}, /* 2.7755472886508899e-18 */
+/**/ c3 = {{0x3FA6DB6D, 0xB6DB6DB7}}, /* 0.044642857142857144 */
+/**/ cc3 = {{0xBC320FC0, 0x3D5CF0C5}}, /* -9.7911734574147224e-19 */
+/**/ c4 = {{0x3F9F1C71, 0xC71C71C5}}, /* 0.030381944444444437 */
+/**/ cc4 = {{0xBC02B240, 0xFF23ED1E}}; /* -1.2669108566898312e-19 */
+
+#else
+#ifdef LITTLE_ENDI
+
+ static const mynumber
+/**/ c1 = {{0x55555555, 0x3FC55555}}, /* 0.16666666666666666 */
+/**/ cc1 = {{0x55775389, 0x3C655555}}, /* 9.2518585419753846e-18 */
+/**/ c2 = {{0x33333333, 0x3FB33333}}, /* 0.074999999999999997 */
+/**/ cc2 = {{0x63F1A115, 0x3C499993}}, /* 2.7755472886508899e-18 */
+/**/ c3 = {{0xB6DB6DB7, 0x3FA6DB6D}}, /* 0.044642857142857144 */
+/**/ cc3 = {{0x3D5CF0C5, 0xBC320FC0}}, /* -9.7911734574147224e-19 */
+/**/ c4 = {{0xC71C71C5, 0x3F9F1C71}}, /* 0.030381944444444437 */
+/**/ cc4 = {{0xFF23ED1E, 0xBC02B240}}; /* -1.2669108566898312e-19 */
+
+
+#endif
+#endif
+
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/dosincos.c b/libc/sysdeps/ieee754/dbl-64/dosincos.c
new file mode 100644
index 000000000..1d347a4bc
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/dosincos.c
@@ -0,0 +1,189 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/********************************************************************/
+/* */
+/* MODULE_NAME: dosincos.c */
+/* */
+/* */
+/* FUNCTIONS: dubsin */
+/* dubcos */
+/* docos */
+/* FILES NEEDED: endian.h mydefs.h dla.h dosincos.h */
+/* sincos.tbl */
+/* */
+/* Routines compute sin() and cos() as Double-Length numbers */
+/********************************************************************/
+
+
+
+#include "endian.h"
+#include "mydefs.h"
+#include "sincos.tbl"
+#include "dla.h"
+#include "dosincos.h"
+#include "math_private.h"
+
+/***********************************************************************/
+/* Routine receive Double-Length number (x+dx) and computing sin(x+dx) */
+/* as Double-Length number and store it at array v .It computes it by */
+/* arithmetic action on Double-Length numbers */
+/*(x+dx) between 0 and PI/4 */
+/***********************************************************************/
+
+void __dubsin(double x, double dx, double v[]) {
+ double r,s,p,hx,tx,hy,ty,q,c,cc,d,dd,d2,dd2,e,ee,
+ sn,ssn,cs,ccs,ds,dss,dc,dcc;
+#if 0
+ double xx,y,yy,z,zz;
+#endif
+ mynumber u;
+ int4 k;
+
+ u.x=x+big.x;
+ k = u.i[LOW_HALF]<<2;
+ x=x-(u.x-big.x);
+ d=x+dx;
+ dd=(x-d)+dx;
+ /* sin(x+dx)=sin(Xi+t)=sin(Xi)*cos(t) + cos(Xi)sin(t) where t ->0 */
+ MUL2(d,dd,d,dd,d2,dd2,p,hx,tx,hy,ty,q,c,cc);
+ sn=sincos.x[k]; /* */
+ ssn=sincos.x[k+1]; /* sin(Xi) and cos(Xi) */
+ cs=sincos.x[k+2]; /* */
+ ccs=sincos.x[k+3]; /* */
+ MUL2(d2,dd2,s7.x,ss7.x,ds,dss,p,hx,tx,hy,ty,q,c,cc); /* Taylor */
+ ADD2(ds,dss,s5.x,ss5.x,ds,dss,r,s);
+ MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); /* series */
+ ADD2(ds,dss,s3.x,ss3.x,ds,dss,r,s);
+ MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); /* for sin */
+ MUL2(d,dd,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(ds,dss,d,dd,ds,dss,r,s); /* ds=sin(t) */
+
+ MUL2(d2,dd2,c8.x,cc8.x,dc,dcc,p,hx,tx,hy,ty,q,c,cc); ;/* Taylor */
+ ADD2(dc,dcc,c6.x,cc6.x,dc,dcc,r,s);
+ MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); /* series */
+ ADD2(dc,dcc,c4.x,cc4.x,dc,dcc,r,s);
+ MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); /* for cos */
+ ADD2(dc,dcc,c2.x,cc2.x,dc,dcc,r,s);
+ MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); /* dc=cos(t) */
+
+ MUL2(cs,ccs,ds,dss,e,ee,p,hx,tx,hy,ty,q,c,cc);
+ MUL2(dc,dcc,sn,ssn,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
+ SUB2(e,ee,dc,dcc,e,ee,r,s);
+ ADD2(e,ee,sn,ssn,e,ee,r,s); /* e+ee=sin(x+dx) */
+
+ v[0]=e;
+ v[1]=ee;
+}
+/**********************************************************************/
+/* Routine receive Double-Length number (x+dx) and computes cos(x+dx) */
+/* as Double-Length number and store it in array v .It computes it by */
+/* arithmetic action on Double-Length numbers */
+/*(x+dx) between 0 and PI/4 */
+/**********************************************************************/
+
+void __dubcos(double x, double dx, double v[]) {
+ double r,s,p,hx,tx,hy,ty,q,c,cc,d,dd,d2,dd2,e,ee,
+ sn,ssn,cs,ccs,ds,dss,dc,dcc;
+#if 0
+ double xx,y,yy,z,zz;
+#endif
+ mynumber u;
+ int4 k;
+ u.x=x+big.x;
+ k = u.i[LOW_HALF]<<2;
+ x=x-(u.x-big.x);
+ d=x+dx;
+ dd=(x-d)+dx; /* cos(x+dx)=cos(Xi+t)=cos(Xi)cos(t) - sin(Xi)sin(t) */
+ MUL2(d,dd,d,dd,d2,dd2,p,hx,tx,hy,ty,q,c,cc);
+ sn=sincos.x[k]; /* */
+ ssn=sincos.x[k+1]; /* sin(Xi) and cos(Xi) */
+ cs=sincos.x[k+2]; /* */
+ ccs=sincos.x[k+3]; /* */
+ MUL2(d2,dd2,s7.x,ss7.x,ds,dss,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(ds,dss,s5.x,ss5.x,ds,dss,r,s);
+ MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(ds,dss,s3.x,ss3.x,ds,dss,r,s);
+ MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
+ MUL2(d,dd,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(ds,dss,d,dd,ds,dss,r,s);
+
+ MUL2(d2,dd2,c8.x,cc8.x,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(dc,dcc,c6.x,cc6.x,dc,dcc,r,s);
+ MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(dc,dcc,c4.x,cc4.x,dc,dcc,r,s);
+ MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(dc,dcc,c2.x,cc2.x,dc,dcc,r,s);
+ MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
+
+ MUL2(cs,ccs,ds,dss,e,ee,p,hx,tx,hy,ty,q,c,cc);
+ MUL2(dc,dcc,sn,ssn,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
+
+ MUL2(d2,dd2,s7.x,ss7.x,ds,dss,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(ds,dss,s5.x,ss5.x,ds,dss,r,s);
+ MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(ds,dss,s3.x,ss3.x,ds,dss,r,s);
+ MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
+ MUL2(d,dd,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(ds,dss,d,dd,ds,dss,r,s);
+ MUL2(d2,dd2,c8.x,cc8.x,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(dc,dcc,c6.x,cc6.x,dc,dcc,r,s);
+ MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(dc,dcc,c4.x,cc4.x,dc,dcc,r,s);
+ MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(dc,dcc,c2.x,cc2.x,dc,dcc,r,s);
+ MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
+ MUL2(sn,ssn,ds,dss,e,ee,p,hx,tx,hy,ty,q,c,cc);
+ MUL2(dc,dcc,cs,ccs,dc,dcc,p,hx,tx,hy,ty,q,c,cc);
+ ADD2(e,ee,dc,dcc,e,ee,r,s);
+ SUB2(cs,ccs,e,ee,e,ee,r,s);
+
+ v[0]=e;
+ v[1]=ee;
+}
+/**********************************************************************/
+/* Routine receive Double-Length number (x+dx) and computes cos(x+dx) */
+/* as Double-Length number and store it in array v */
+/**********************************************************************/
+void __docos(double x, double dx, double v[]) {
+ double y,yy,p,w[2];
+ if (x>0) {y=x; yy=dx;}
+ else {y=-x; yy=-dx;}
+ if (y<0.5*hp0.x) /* y< PI/4 */
+ {__dubcos(y,yy,w); v[0]=w[0]; v[1]=w[1];}
+ else if (y<1.5*hp0.x) { /* y< 3/4 * PI */
+ p=hp0.x-y; /* p = PI/2 - y */
+ yy=hp1.x-yy;
+ y=p+yy;
+ yy=(p-y)+yy;
+ if (y>0) {__dubsin(y,yy,w); v[0]=w[0]; v[1]=w[1];}
+ /* cos(x) = sin ( 90 - x ) */
+ else {__dubsin(-y,-yy,w); v[0]=-w[0]; v[1]=-w[1];
+ }
+ }
+ else { /* y>= 3/4 * PI */
+ p=2.0*hp0.x-y; /* p = PI- y */
+ yy=2.0*hp1.x-yy;
+ y=p+yy;
+ yy=(p-y)+yy;
+ __dubcos(y,yy,w);
+ v[0]=-w[0];
+ v[1]=-w[1];
+ }
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/dosincos.h b/libc/sysdeps/ieee754/dbl-64/dosincos.h
new file mode 100644
index 000000000..49d61cd91
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/dosincos.h
@@ -0,0 +1,81 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/************************************************************************/
+/* MODULE_NAME: dosincos.h */
+/* */
+/* */
+/* common data and variables definition for BIG or LITTLE ENDIAN */
+/************************************************************************/
+
+
+
+#ifndef DOSINCOS_H
+#define DOSINCOS_H
+
+
+#ifdef BIG_ENDI
+static const mynumber
+/**/ s3 = {{0xBFC55555, 0x55555555}},/* -0.16666666666666666 */
+/**/ ss3 = {{0xBC6553AA, 0xE77EE482}},/* -9.2490366677784492e-18 */
+/**/ s5 = {{0x3F811111, 0x11110F15}},/* 0.008333333333332452 */
+/**/ ss5 = {{0xBC21AC06, 0xDA488820}},/* -4.7899996586987931e-19 */
+/**/ s7 = {{0xBF2A019F, 0x5816C78D}},/* -0.00019841261022928957 */
+/**/ ss7 = {{0x3BCDCEC9, 0x6A18BF2A}},/* 1.2624077757871259e-20 */
+/**/ c2 = {{0x3FE00000, 0x00000000}},/* 0.5 */
+/**/ cc2 = {{0xBA282FD8, 0x00000000}},/* -1.5264073330037701e-28 */
+/**/ c4 = {{0xBFA55555, 0x55555555}},/* -0.041666666666666664 */
+/**/ cc4 = {{0xBC4554BC, 0x2FFF257E}},/* -2.312711276085743e-18 */
+/**/ c6 = {{0x3F56C16C, 0x16C16A96}},/* 0.0013888888888888055 */
+/**/ cc6 = {{0xBBD2E846, 0xE6346F14}},/* -1.6015133010194884e-20 */
+/**/ c8 = {{0xBEFA019F, 0x821D5987}},/* -2.480157866754367e-05 */
+/**/ cc8 = {{0x3B7AB71E, 0x72FFE5CC}},/* 3.5357416224857556e-22 */
+
+/**/ big = {{0x42c80000, 0x00000000}}, /* 52776558133248 */
+
+/**/ hp0 = {{0x3FF921FB, 0x54442D18}}, /* PI / 2 */
+/**/ hp1 = {{0x3C91A626, 0x33145C07}}; /* 6.123233995736766e-17 */
+#else
+#ifdef LITTLE_ENDI
+static const mynumber
+/**/ s3 = {{0x55555555, 0xBFC55555}},/* -0.16666666666666666 */
+/**/ ss3 = {{0xE77EE482, 0xBC6553AA}},/* -9.2490366677784492e-18 */
+/**/ s5 = {{0x11110F15, 0x3F811111}},/* 0.008333333333332452 */
+/**/ ss5 = {{0xDA488820, 0xBC21AC06}},/* -4.7899996586987931e-19 */
+/**/ s7 = {{0x5816C78D, 0xBF2A019F}},/* -0.00019841261022928957 */
+/**/ ss7 = {{0x6A18BF2A, 0x3BCDCEC9}},/* 1.2624077757871259e-20 */
+/**/ c2 = {{0x00000000, 0x3FE00000}},/* 0.5 */
+/**/ cc2 = {{0x00000000, 0xBA282FD8}},/* -1.5264073330037701e-28 */
+/**/ c4 = {{0x55555555, 0xBFA55555}},/* -0.041666666666666664 */
+/**/ cc4 = {{0x2FFF257E, 0xBC4554BC}},/* -2.312711276085743e-18 */
+/**/ c6 = {{0x16C16A96, 0x3F56C16C}},/* 0.0013888888888888055 */
+/**/ cc6 = {{0xE6346F14, 0xBBD2E846}},/* -1.6015133010194884e-20 */
+/**/ c8 = {{0x821D5987, 0xBEFA019F}},/* -2.480157866754367e-05 */
+/**/ cc8 = {{0x72FFE5CC, 0x3B7AB71E}},/* 3.5357416224857556e-22 */
+
+/**/ big = {{0x00000000, 0x42c80000}}, /* 52776558133248 */
+
+/**/ hp0 = {{0x54442D18, 0x3FF921FB}}, /* PI / 2 */
+/**/ hp1 = {{0x33145C07, 0x3C91A626}}; /* 6.123233995736766e-17 */
+#endif
+#endif
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/e_acos.c b/libc/sysdeps/ieee754/dbl-64/e_acos.c
new file mode 100644
index 000000000..8f7cd8924
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_acos.c
@@ -0,0 +1 @@
+/* In e_asin.c */
diff --git a/libc/sysdeps/ieee754/dbl-64/e_acosh.c b/libc/sysdeps/ieee754/dbl-64/e_acosh.c
new file mode 100644
index 000000000..27c29cd8c
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_acosh.c
@@ -0,0 +1,69 @@
+/* @(#)e_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: e_acosh.c,v 1.9 1995/05/12 04:57:18 jtc Exp $";
+#endif
+
+/* __ieee754_acosh(x)
+ * Method :
+ * Based on
+ * acosh(x) = log [ x + sqrt(x*x-1) ]
+ * we have
+ * acosh(x) := log(x)+ln2, if x is large; else
+ * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
+ * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
+ *
+ * Special cases:
+ * acosh(x) is NaN with signal if x<1.
+ * acosh(NaN) is NaN without signal.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.0,
+ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */
+
+#ifdef __STDC__
+ double __ieee754_acosh(double x)
+#else
+ double __ieee754_acosh(x)
+ double x;
+#endif
+{
+ double t;
+ int32_t hx;
+ u_int32_t lx;
+ EXTRACT_WORDS(hx,lx,x);
+ if(hx<0x3ff00000) { /* x < 1 */
+ return (x-x)/(x-x);
+ } else if(hx >=0x41b00000) { /* x > 2**28 */
+ if(hx >=0x7ff00000) { /* x is inf of NaN */
+ return x+x;
+ } else
+ return __ieee754_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)));
+ } else { /* 1<x<2 */
+ t = x-one;
+ return __log1p(t+__sqrt(2.0*t+t*t));
+ }
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_asin.c b/libc/sysdeps/ieee754/dbl-64/e_asin.c
new file mode 100644
index 000000000..ce5d227b7
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_asin.c
@@ -0,0 +1,637 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/******************************************************************/
+/* MODULE_NAME:uasncs.c */
+/* */
+/* FUNCTIONS: uasin */
+/* uacos */
+/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h usncs.h */
+/* doasin.c sincos32.c dosincos.c mpa.c */
+/* sincos.tbl asincos.tbl powtwo.tbl root.tbl */
+/* */
+/* Ultimate asin/acos routines. Given an IEEE double machine */
+/* number x, compute the correctly rounded value of */
+/* arcsin(x)or arccos(x) according to the function called. */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round to nearest mode of IEEE 754 standard. */
+/* */
+/******************************************************************/
+#include "endian.h"
+#include "mydefs.h"
+#include "asincos.tbl"
+#include "root.tbl"
+#include "powtwo.tbl"
+#include "MathLib.h"
+#include "uasncs.h"
+#include "math_private.h"
+
+void __doasin(double x, double dx, double w[]);
+void __dubsin(double x, double dx, double v[]);
+void __dubcos(double x, double dx, double v[]);
+void __docos(double x, double dx, double v[]);
+double __sin32(double x, double res, double res1);
+double __cos32(double x, double res, double res1);
+
+/***************************************************************************/
+/* An ultimate asin routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of arcsin(x) */
+/***************************************************************************/
+double __ieee754_asin(double x){
+ double x1,x2,xx,s1,s2,res1,p,t,res,r,cor,cc,y,c,z,w[2];
+ mynumber u,v;
+ int4 k,m,n;
+#if 0
+ int4 nn;
+#endif
+
+ u.x = x;
+ m = u.i[HIGH_HALF];
+ k = 0x7fffffff&m; /* no sign */
+
+ if (k < 0x3e500000) return x; /* for x->0 => sin(x)=x */
+ /*----------------------2^-26 <= |x| < 2^ -3 -----------------*/
+ else
+ if (k < 0x3fc00000) {
+ x2 = x*x;
+ t = (((((f6*x2 + f5)*x2 + f4)*x2 + f3)*x2 + f2)*x2 + f1)*(x2*x);
+ res = x+t; /* res=arcsin(x) according to Taylor series */
+ cor = (x-res)+t;
+ if (res == res+1.025*cor) return res;
+ else {
+ x1 = x+big;
+ xx = x*x;
+ x1 -= big;
+ x2 = x - x1;
+ p = x1*x1*x1;
+ s1 = a1.x*p;
+ s2 = ((((((c7*xx + c6)*xx + c5)*xx + c4)*xx + c3)*xx + c2)*xx*xx*x +
+ ((a1.x+a2.x)*x2*x2+ 0.5*x1*x)*x2) + a2.x*p;
+ res1 = x+s1;
+ s2 = ((x-res1)+s1)+s2;
+ res = res1+s2;
+ cor = (res1-res)+s2;
+ if (res == res+1.00014*cor) return res;
+ else {
+ __doasin(x,0,w);
+ if (w[0]==(w[0]+1.00000001*w[1])) return w[0];
+ else {
+ y=ABS(x);
+ res=ABS(w[0]);
+ res1=ABS(w[0]+1.1*w[1]);
+ return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
+ }
+ }
+ }
+ }
+ /*---------------------0.125 <= |x| < 0.5 -----------------------------*/
+ else if (k < 0x3fe00000) {
+ if (k<0x3fd00000) n = 11*((k&0x000fffff)>>15);
+ else n = 11*((k&0x000fffff)>>14)+352;
+ if (m>0) xx = x - asncs.x[n];
+ else xx = -x - asncs.x[n];
+ t = asncs.x[n+1]*xx;
+ p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
+ +xx*asncs.x[n+6]))))+asncs.x[n+7];
+ t+=p;
+ res =asncs.x[n+8] +t;
+ cor = (asncs.x[n+8]-res)+t;
+ if (res == res+1.05*cor) return (m>0)?res:-res;
+ else {
+ r=asncs.x[n+8]+xx*asncs.x[n+9];
+ t=((asncs.x[n+8]-r)+xx*asncs.x[n+9])+(p+xx*asncs.x[n+10]);
+ res = r+t;
+ cor = (r-res)+t;
+ if (res == res+1.0005*cor) return (m>0)?res:-res;
+ else {
+ res1=res+1.1*cor;
+ z=0.5*(res1-res);
+ __dubsin(res,z,w);
+ z=(w[0]-ABS(x))+w[1];
+ if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
+ else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
+ else {
+ y=ABS(x);
+ return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
+ }
+ }
+ }
+ } /* else if (k < 0x3fe00000) */
+ /*-------------------- 0.5 <= |x| < 0.75 -----------------------------*/
+ else
+ if (k < 0x3fe80000) {
+ n = 1056+((k&0x000fe000)>>11)*3;
+ if (m>0) xx = x - asncs.x[n];
+ else xx = -x - asncs.x[n];
+ t = asncs.x[n+1]*xx;
+ p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
+ +xx*(asncs.x[n+6]+xx*asncs.x[n+7])))))+asncs.x[n+8];
+ t+=p;
+ res =asncs.x[n+9] +t;
+ cor = (asncs.x[n+9]-res)+t;
+ if (res == res+1.01*cor) return (m>0)?res:-res;
+ else {
+ r=asncs.x[n+9]+xx*asncs.x[n+10];
+ t=((asncs.x[n+9]-r)+xx*asncs.x[n+10])+(p+xx*asncs.x[n+11]);
+ res = r+t;
+ cor = (r-res)+t;
+ if (res == res+1.0005*cor) return (m>0)?res:-res;
+ else {
+ res1=res+1.1*cor;
+ z=0.5*(res1-res);
+ __dubsin(res,z,w);
+ z=(w[0]-ABS(x))+w[1];
+ if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
+ else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
+ else {
+ y=ABS(x);
+ return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
+ }
+ }
+ }
+ } /* else if (k < 0x3fe80000) */
+ /*--------------------- 0.75 <= |x|< 0.921875 ----------------------*/
+ else
+ if (k < 0x3fed8000) {
+ n = 992+((k&0x000fe000)>>13)*13;
+ if (m>0) xx = x - asncs.x[n];
+ else xx = -x - asncs.x[n];
+ t = asncs.x[n+1]*xx;
+ p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
+ +xx*(asncs.x[n+6]+xx*(asncs.x[n+7]+xx*asncs.x[n+8]))))))+asncs.x[n+9];
+ t+=p;
+ res =asncs.x[n+10] +t;
+ cor = (asncs.x[n+10]-res)+t;
+ if (res == res+1.01*cor) return (m>0)?res:-res;
+ else {
+ r=asncs.x[n+10]+xx*asncs.x[n+11];
+ t=((asncs.x[n+10]-r)+xx*asncs.x[n+11])+(p+xx*asncs.x[n+12]);
+ res = r+t;
+ cor = (r-res)+t;
+ if (res == res+1.0008*cor) return (m>0)?res:-res;
+ else {
+ res1=res+1.1*cor;
+ z=0.5*(res1-res);
+ y=hp0.x-res;
+ z=((hp0.x-y)-res)+(hp1.x-z);
+ __dubcos(y,z,w);
+ z=(w[0]-ABS(x))+w[1];
+ if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
+ else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
+ else {
+ y=ABS(x);
+ return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
+ }
+ }
+ }
+ } /* else if (k < 0x3fed8000) */
+ /*-------------------0.921875 <= |x| < 0.953125 ------------------------*/
+ else
+ if (k < 0x3fee8000) {
+ n = 884+((k&0x000fe000)>>13)*14;
+ if (m>0) xx = x - asncs.x[n];
+ else xx = -x - asncs.x[n];
+ t = asncs.x[n+1]*xx;
+ p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
+ xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
+ +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
+ xx*asncs.x[n+9])))))))+asncs.x[n+10];
+ t+=p;
+ res =asncs.x[n+11] +t;
+ cor = (asncs.x[n+11]-res)+t;
+ if (res == res+1.01*cor) return (m>0)?res:-res;
+ else {
+ r=asncs.x[n+11]+xx*asncs.x[n+12];
+ t=((asncs.x[n+11]-r)+xx*asncs.x[n+12])+(p+xx*asncs.x[n+13]);
+ res = r+t;
+ cor = (r-res)+t;
+ if (res == res+1.0007*cor) return (m>0)?res:-res;
+ else {
+ res1=res+1.1*cor;
+ z=0.5*(res1-res);
+ y=(hp0.x-res)-z;
+ z=y+hp1.x;
+ y=(y-z)+hp1.x;
+ __dubcos(z,y,w);
+ z=(w[0]-ABS(x))+w[1];
+ if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
+ else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
+ else {
+ y=ABS(x);
+ return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
+ }
+ }
+ }
+ } /* else if (k < 0x3fee8000) */
+
+ /*--------------------0.953125 <= |x| < 0.96875 ------------------------*/
+ else
+ if (k < 0x3fef0000) {
+ n = 768+((k&0x000fe000)>>13)*15;
+ if (m>0) xx = x - asncs.x[n];
+ else xx = -x - asncs.x[n];
+ t = asncs.x[n+1]*xx;
+ p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
+ xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
+ +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
+ xx*(asncs.x[n+9]+xx*asncs.x[n+10]))))))))+asncs.x[n+11];
+ t+=p;
+ res =asncs.x[n+12] +t;
+ cor = (asncs.x[n+12]-res)+t;
+ if (res == res+1.01*cor) return (m>0)?res:-res;
+ else {
+ r=asncs.x[n+12]+xx*asncs.x[n+13];
+ t=((asncs.x[n+12]-r)+xx*asncs.x[n+13])+(p+xx*asncs.x[n+14]);
+ res = r+t;
+ cor = (r-res)+t;
+ if (res == res+1.0007*cor) return (m>0)?res:-res;
+ else {
+ res1=res+1.1*cor;
+ z=0.5*(res1-res);
+ y=(hp0.x-res)-z;
+ z=y+hp1.x;
+ y=(y-z)+hp1.x;
+ __dubcos(z,y,w);
+ z=(w[0]-ABS(x))+w[1];
+ if (z>1.0e-27) return (m>0)?min(res,res1):-min(res,res1);
+ else if (z<-1.0e-27) return (m>0)?max(res,res1):-max(res,res1);
+ else {
+ y=ABS(x);
+ return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
+ }
+ }
+ }
+ } /* else if (k < 0x3fef0000) */
+ /*--------------------0.96875 <= |x| < 1 --------------------------------*/
+ else
+ if (k<0x3ff00000) {
+ z = 0.5*((m>0)?(1.0-x):(1.0+x));
+ v.x=z;
+ k=v.i[HIGH_HALF];
+ t=inroot[(k&0x001fffff)>>14]*powtwo[511-(k>>21)];
+ r=1.0-t*t*z;
+ t = t*(rt0+r*(rt1+r*(rt2+r*rt3)));
+ c=t*z;
+ t=c*(1.5-0.5*t*c);
+ y=(c+t24)-t24;
+ cc = (z-y*y)/(t+y);
+ p=(((((f6*z+f5)*z+f4)*z+f3)*z+f2)*z+f1)*z;
+ cor = (hp1.x - 2.0*cc)-2.0*(y+cc)*p;
+ res1 = hp0.x - 2.0*y;
+ res =res1 + cor;
+ if (res == res+1.003*((res1-res)+cor)) return (m>0)?res:-res;
+ else {
+ c=y+cc;
+ cc=(y-c)+cc;
+ __doasin(c,cc,w);
+ res1=hp0.x-2.0*w[0];
+ cor=((hp0.x-res1)-2.0*w[0])+(hp1.x-2.0*w[1]);
+ res = res1+cor;
+ cor = (res1-res)+cor;
+ if (res==(res+1.0000001*cor)) return (m>0)?res:-res;
+ else {
+ y=ABS(x);
+ res1=res+1.1*cor;
+ return (m>0)?__sin32(y,res,res1):-__sin32(y,res,res1);
+ }
+ }
+ } /* else if (k < 0x3ff00000) */
+ /*---------------------------- |x|>=1 -------------------------------*/
+ else if (k==0x3ff00000 && u.i[LOW_HALF]==0) return (m>0)?hp0.x:-hp0.x;
+ else
+ if (k>0x7ff00000 || (k == 0x7ff00000 && u.i[LOW_HALF] != 0)) return x;
+ else {
+ u.i[HIGH_HALF]=0x7ff00000;
+ v.i[HIGH_HALF]=0x7ff00000;
+ u.i[LOW_HALF]=0;
+ v.i[LOW_HALF]=0;
+ return u.x/v.x; /* NaN */
+ }
+}
+
+/*******************************************************************/
+/* */
+/* End of arcsine, below is arccosine */
+/* */
+/*******************************************************************/
+
+double __ieee754_acos(double x)
+{
+ double x1,x2,xx,s1,s2,res1,p,t,res,r,cor,cc,y,c,z,w[2],eps;
+#if 0
+ double fc;
+#endif
+ mynumber u,v;
+ int4 k,m,n;
+#if 0
+ int4 nn;
+#endif
+ u.x = x;
+ m = u.i[HIGH_HALF];
+ k = 0x7fffffff&m;
+ /*------------------- |x|<2.77556*10^-17 ----------------------*/
+ if (k < 0x3c880000) return hp0.x;
+
+ /*----------------- 2.77556*10^-17 <= |x| < 2^-3 --------------*/
+ else
+ if (k < 0x3fc00000) {
+ x2 = x*x;
+ t = (((((f6*x2 + f5)*x2 + f4)*x2 + f3)*x2 + f2)*x2 + f1)*(x2*x);
+ r=hp0.x-x;
+ cor=(((hp0.x-r)-x)+hp1.x)-t;
+ res = r+cor;
+ cor = (r-res)+cor;
+ if (res == res+1.004*cor) return res;
+ else {
+ x1 = x+big;
+ xx = x*x;
+ x1 -= big;
+ x2 = x - x1;
+ p = x1*x1*x1;
+ s1 = a1.x*p;
+ s2 = ((((((c7*xx + c6)*xx + c5)*xx + c4)*xx + c3)*xx + c2)*xx*xx*x +
+ ((a1.x+a2.x)*x2*x2+ 0.5*x1*x)*x2) + a2.x*p;
+ res1 = x+s1;
+ s2 = ((x-res1)+s1)+s2;
+ r=hp0.x-res1;
+ cor=(((hp0.x-r)-res1)+hp1.x)-s2;
+ res = r+cor;
+ cor = (r-res)+cor;
+ if (res == res+1.00004*cor) return res;
+ else {
+ __doasin(x,0,w);
+ r=hp0.x-w[0];
+ cor=((hp0.x-r)-w[0])+(hp1.x-w[1]);
+ res=r+cor;
+ cor=(r-res)+cor;
+ if (res ==(res +1.00000001*cor)) return res;
+ else {
+ res1=res+1.1*cor;
+ return __cos32(x,res,res1);
+ }
+ }
+ }
+ } /* else if (k < 0x3fc00000) */
+ /*---------------------- 0.125 <= |x| < 0.5 --------------------*/
+ else
+ if (k < 0x3fe00000) {
+ if (k<0x3fd00000) n = 11*((k&0x000fffff)>>15);
+ else n = 11*((k&0x000fffff)>>14)+352;
+ if (m>0) xx = x - asncs.x[n];
+ else xx = -x - asncs.x[n];
+ t = asncs.x[n+1]*xx;
+ p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
+ xx*(asncs.x[n+5]+xx*asncs.x[n+6]))))+asncs.x[n+7];
+ t+=p;
+ y = (m>0)?(hp0.x-asncs.x[n+8]):(hp0.x+asncs.x[n+8]);
+ t = (m>0)?(hp1.x-t):(hp1.x+t);
+ res = y+t;
+ if (res == res+1.02*((y-res)+t)) return res;
+ else {
+ r=asncs.x[n+8]+xx*asncs.x[n+9];
+ t=((asncs.x[n+8]-r)+xx*asncs.x[n+9])+(p+xx*asncs.x[n+10]);
+ if (m>0)
+ {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; }
+ else
+ {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); }
+ res = p+t;
+ cor = (p-res)+t;
+ if (res == (res+1.0002*cor)) return res;
+ else {
+ res1=res+1.1*cor;
+ z=0.5*(res1-res);
+ __docos(res,z,w);
+ z=(w[0]-x)+w[1];
+ if (z>1.0e-27) return max(res,res1);
+ else if (z<-1.0e-27) return min(res,res1);
+ else return __cos32(x,res,res1);
+ }
+ }
+ } /* else if (k < 0x3fe00000) */
+
+ /*--------------------------- 0.5 <= |x| < 0.75 ---------------------*/
+ else
+ if (k < 0x3fe80000) {
+ n = 1056+((k&0x000fe000)>>11)*3;
+ if (m>0) {xx = x - asncs.x[n]; eps=1.04; }
+ else {xx = -x - asncs.x[n]; eps=1.02; }
+ t = asncs.x[n+1]*xx;
+ p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
+ xx*(asncs.x[n+5]+xx*(asncs.x[n+6]+
+ xx*asncs.x[n+7])))))+asncs.x[n+8];
+ t+=p;
+ y = (m>0)?(hp0.x-asncs.x[n+9]):(hp0.x+asncs.x[n+9]);
+ t = (m>0)?(hp1.x-t):(hp1.x+t);
+ res = y+t;
+ if (res == res+eps*((y-res)+t)) return res;
+ else {
+ r=asncs.x[n+9]+xx*asncs.x[n+10];
+ t=((asncs.x[n+9]-r)+xx*asncs.x[n+10])+(p+xx*asncs.x[n+11]);
+ if (m>0) {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; eps=1.0004; }
+ else {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); eps=1.0002; }
+ res = p+t;
+ cor = (p-res)+t;
+ if (res == (res+eps*cor)) return res;
+ else {
+ res1=res+1.1*cor;
+ z=0.5*(res1-res);
+ __docos(res,z,w);
+ z=(w[0]-x)+w[1];
+ if (z>1.0e-27) return max(res,res1);
+ else if (z<-1.0e-27) return min(res,res1);
+ else return __cos32(x,res,res1);
+ }
+ }
+ } /* else if (k < 0x3fe80000) */
+
+/*------------------------- 0.75 <= |x| < 0.921875 -------------*/
+ else
+ if (k < 0x3fed8000) {
+ n = 992+((k&0x000fe000)>>13)*13;
+ if (m>0) {xx = x - asncs.x[n]; eps = 1.04; }
+ else {xx = -x - asncs.x[n]; eps = 1.01; }
+ t = asncs.x[n+1]*xx;
+ p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
+ xx*(asncs.x[n+5]+xx*(asncs.x[n+6]+xx*(asncs.x[n+7]+
+ xx*asncs.x[n+8]))))))+asncs.x[n+9];
+ t+=p;
+ y = (m>0)?(hp0.x-asncs.x[n+10]):(hp0.x+asncs.x[n+10]);
+ t = (m>0)?(hp1.x-t):(hp1.x+t);
+ res = y+t;
+ if (res == res+eps*((y-res)+t)) return res;
+ else {
+ r=asncs.x[n+10]+xx*asncs.x[n+11];
+ t=((asncs.x[n+10]-r)+xx*asncs.x[n+11])+(p+xx*asncs.x[n+12]);
+ if (m>0) {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; eps=1.0032; }
+ else {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); eps=1.0008; }
+ res = p+t;
+ cor = (p-res)+t;
+ if (res == (res+eps*cor)) return res;
+ else {
+ res1=res+1.1*cor;
+ z=0.5*(res1-res);
+ __docos(res,z,w);
+ z=(w[0]-x)+w[1];
+ if (z>1.0e-27) return max(res,res1);
+ else if (z<-1.0e-27) return min(res,res1);
+ else return __cos32(x,res,res1);
+ }
+ }
+ } /* else if (k < 0x3fed8000) */
+
+/*-------------------0.921875 <= |x| < 0.953125 ------------------*/
+ else
+ if (k < 0x3fee8000) {
+ n = 884+((k&0x000fe000)>>13)*14;
+ if (m>0) {xx = x - asncs.x[n]; eps=1.04; }
+ else {xx = -x - asncs.x[n]; eps =1.005; }
+ t = asncs.x[n+1]*xx;
+ p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
+ xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
+ +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
+ xx*asncs.x[n+9])))))))+asncs.x[n+10];
+ t+=p;
+ y = (m>0)?(hp0.x-asncs.x[n+11]):(hp0.x+asncs.x[n+11]);
+ t = (m>0)?(hp1.x-t):(hp1.x+t);
+ res = y+t;
+ if (res == res+eps*((y-res)+t)) return res;
+ else {
+ r=asncs.x[n+11]+xx*asncs.x[n+12];
+ t=((asncs.x[n+11]-r)+xx*asncs.x[n+12])+(p+xx*asncs.x[n+13]);
+ if (m>0) {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; eps=1.0030; }
+ else {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); eps=1.0005; }
+ res = p+t;
+ cor = (p-res)+t;
+ if (res == (res+eps*cor)) return res;
+ else {
+ res1=res+1.1*cor;
+ z=0.5*(res1-res);
+ __docos(res,z,w);
+ z=(w[0]-x)+w[1];
+ if (z>1.0e-27) return max(res,res1);
+ else if (z<-1.0e-27) return min(res,res1);
+ else return __cos32(x,res,res1);
+ }
+ }
+ } /* else if (k < 0x3fee8000) */
+
+ /*--------------------0.953125 <= |x| < 0.96875 ----------------*/
+ else
+ if (k < 0x3fef0000) {
+ n = 768+((k&0x000fe000)>>13)*15;
+ if (m>0) {xx = x - asncs.x[n]; eps=1.04; }
+ else {xx = -x - asncs.x[n]; eps=1.005;}
+ t = asncs.x[n+1]*xx;
+ p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
+ xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
+ +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+xx*(asncs.x[n+9]+
+ xx*asncs.x[n+10]))))))))+asncs.x[n+11];
+ t+=p;
+ y = (m>0)?(hp0.x-asncs.x[n+12]):(hp0.x+asncs.x[n+12]);
+ t = (m>0)?(hp1.x-t):(hp1.x+t);
+ res = y+t;
+ if (res == res+eps*((y-res)+t)) return res;
+ else {
+ r=asncs.x[n+12]+xx*asncs.x[n+13];
+ t=((asncs.x[n+12]-r)+xx*asncs.x[n+13])+(p+xx*asncs.x[n+14]);
+ if (m>0) {p = hp0.x-r; t = (((hp0.x-p)-r)-t)+hp1.x; eps=1.0030; }
+ else {p = hp0.x+r; t = ((hp0.x-p)+r)+(hp1.x+t); eps=1.0005; }
+ res = p+t;
+ cor = (p-res)+t;
+ if (res == (res+eps*cor)) return res;
+ else {
+ res1=res+1.1*cor;
+ z=0.5*(res1-res);
+ __docos(res,z,w);
+ z=(w[0]-x)+w[1];
+ if (z>1.0e-27) return max(res,res1);
+ else if (z<-1.0e-27) return min(res,res1);
+ else return __cos32(x,res,res1);
+ }
+ }
+ } /* else if (k < 0x3fef0000) */
+ /*-----------------0.96875 <= |x| < 1 ---------------------------*/
+
+ else
+ if (k<0x3ff00000) {
+ z = 0.5*((m>0)?(1.0-x):(1.0+x));
+ v.x=z;
+ k=v.i[HIGH_HALF];
+ t=inroot[(k&0x001fffff)>>14]*powtwo[511-(k>>21)];
+ r=1.0-t*t*z;
+ t = t*(rt0+r*(rt1+r*(rt2+r*rt3)));
+ c=t*z;
+ t=c*(1.5-0.5*t*c);
+ y = (t27*c+c)-t27*c;
+ cc = (z-y*y)/(t+y);
+ p=(((((f6*z+f5)*z+f4)*z+f3)*z+f2)*z+f1)*z;
+ if (m<0) {
+ cor = (hp1.x - cc)-(y+cc)*p;
+ res1 = hp0.x - y;
+ res =res1 + cor;
+ if (res == res+1.002*((res1-res)+cor)) return (res+res);
+ else {
+ c=y+cc;
+ cc=(y-c)+cc;
+ __doasin(c,cc,w);
+ res1=hp0.x-w[0];
+ cor=((hp0.x-res1)-w[0])+(hp1.x-w[1]);
+ res = res1+cor;
+ cor = (res1-res)+cor;
+ if (res==(res+1.000001*cor)) return (res+res);
+ else {
+ res=res+res;
+ res1=res+1.2*cor;
+ return __cos32(x,res,res1);
+ }
+ }
+ }
+ else {
+ cor = cc+p*(y+cc);
+ res = y + cor;
+ if (res == res+1.03*((y-res)+cor)) return (res+res);
+ else {
+ c=y+cc;
+ cc=(y-c)+cc;
+ __doasin(c,cc,w);
+ res = w[0];
+ cor=w[1];
+ if (res==(res+1.000001*cor)) return (res+res);
+ else {
+ res=res+res;
+ res1=res+1.2*cor;
+ return __cos32(x,res,res1);
+ }
+ }
+ }
+ } /* else if (k < 0x3ff00000) */
+
+ /*---------------------------- |x|>=1 -----------------------*/
+ else
+ if (k==0x3ff00000 && u.i[LOW_HALF]==0) return (m>0)?0:2.0*hp0.x;
+ else
+ if (k>0x7ff00000 || (k == 0x7ff00000 && u.i[LOW_HALF] != 0)) return x;
+ else {
+ u.i[HIGH_HALF]=0x7ff00000;
+ v.i[HIGH_HALF]=0x7ff00000;
+ u.i[LOW_HALF]=0;
+ v.i[LOW_HALF]=0;
+ return u.x/v.x;
+ }
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_atan2.c b/libc/sysdeps/ieee754/dbl-64/e_atan2.c
new file mode 100644
index 000000000..9e1a794ec
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_atan2.c
@@ -0,0 +1,406 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/************************************************************************/
+/* MODULE_NAME: atnat2.c */
+/* */
+/* FUNCTIONS: uatan2 */
+/* atan2Mp */
+/* signArctan2 */
+/* normalized */
+/* */
+/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h atnat2.h */
+/* mpatan.c mpatan2.c mpsqrt.c */
+/* uatan.tbl */
+/* */
+/* An ultimate atan2() routine. Given two IEEE double machine numbers y,*/
+/* x it computes the correctly rounded (to nearest) value of atan2(y,x).*/
+/* */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round to nearest mode of IEEE 754 standard. */
+/* */
+/************************************************************************/
+
+#include "dla.h"
+#include "mpa.h"
+#include "MathLib.h"
+#include "uatan.tbl"
+#include "atnat2.h"
+#include "math_private.h"
+
+/************************************************************************/
+/* An ultimate atan2 routine. Given two IEEE double machine numbers y,x */
+/* it computes the correctly rounded (to nearest) value of atan2(y,x). */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round to nearest mode of IEEE 754 standard. */
+/************************************************************************/
+static double atan2Mp(double ,double ,const int[]);
+static double signArctan2(double ,double);
+static double normalized(double ,double,double ,double);
+void __mpatan2(mp_no *,mp_no *,mp_no *,int);
+
+double __ieee754_atan2(double y,double x) {
+
+ int i,de,ux,dx,uy,dy;
+#if 0
+ int p;
+#endif
+ static const int pr[MM]={6,8,10,20,32};
+ double ax,ay,u,du,u9,ua,v,vv,dv,t1,t2,t3,t4,t5,t6,t7,t8,
+ z,zz,cor,s1,ss1,s2,ss2;
+#if 0
+ double z1,z2;
+#endif
+ number num;
+#if 0
+ mp_no mperr,mpt1,mpx,mpy,mpz,mpz1,mpz2;
+#endif
+
+ static const int ep= 59768832, /* 57*16**5 */
+ em=-59768832; /* -57*16**5 */
+
+ /* x=NaN or y=NaN */
+ num.d = x; ux = num.i[HIGH_HALF]; dx = num.i[LOW_HALF];
+ if ((ux&0x7ff00000) ==0x7ff00000) {
+ if (((ux&0x000fffff)|dx)!=0x00000000) return x+x; }
+ num.d = y; uy = num.i[HIGH_HALF]; dy = num.i[LOW_HALF];
+ if ((uy&0x7ff00000) ==0x7ff00000) {
+ if (((uy&0x000fffff)|dy)!=0x00000000) return y+y; }
+
+ /* y=+-0 */
+ if (uy==0x00000000) {
+ if (dy==0x00000000) {
+ if ((ux&0x80000000)==0x00000000) return ZERO;
+ else return opi.d; } }
+ else if (uy==0x80000000) {
+ if (dy==0x00000000) {
+ if ((ux&0x80000000)==0x00000000) return MZERO;
+ else return mopi.d;} }
+
+ /* x=+-0 */
+ if (x==ZERO) {
+ if ((uy&0x80000000)==0x00000000) return hpi.d;
+ else return mhpi.d; }
+
+ /* x=+-INF */
+ if (ux==0x7ff00000) {
+ if (dx==0x00000000) {
+ if (uy==0x7ff00000) {
+ if (dy==0x00000000) return qpi.d; }
+ else if (uy==0xfff00000) {
+ if (dy==0x00000000) return mqpi.d; }
+ else {
+ if ((uy&0x80000000)==0x00000000) return ZERO;
+ else return MZERO; }
+ }
+ }
+ else if (ux==0xfff00000) {
+ if (dx==0x00000000) {
+ if (uy==0x7ff00000) {
+ if (dy==0x00000000) return tqpi.d; }
+ else if (uy==0xfff00000) {
+ if (dy==0x00000000) return mtqpi.d; }
+ else {
+ if ((uy&0x80000000)==0x00000000) return opi.d;
+ else return mopi.d; }
+ }
+ }
+
+ /* y=+-INF */
+ if (uy==0x7ff00000) {
+ if (dy==0x00000000) return hpi.d; }
+ else if (uy==0xfff00000) {
+ if (dy==0x00000000) return mhpi.d; }
+
+ /* either x/y or y/x is very close to zero */
+ ax = (x<ZERO) ? -x : x; ay = (y<ZERO) ? -y : y;
+ de = (uy & 0x7ff00000) - (ux & 0x7ff00000);
+ if (de>=ep) { return ((y>ZERO) ? hpi.d : mhpi.d); }
+ else if (de<=em) {
+ if (x>ZERO) {
+ if ((z=ay/ax)<TWOM1022) return normalized(ax,ay,y,z);
+ else return signArctan2(y,z); }
+ else { return ((y>ZERO) ? opi.d : mopi.d); } }
+
+ /* if either x or y is extremely close to zero, scale abs(x), abs(y). */
+ if (ax<twom500.d || ay<twom500.d) { ax*=two500.d; ay*=two500.d; }
+
+ /* x,y which are neither special nor extreme */
+ if (ay<ax) {
+ u=ay/ax;
+ EMULV(ax,u,v,vv,t1,t2,t3,t4,t5)
+ du=((ay-v)-vv)/ax; }
+ else {
+ u=ax/ay;
+ EMULV(ay,u,v,vv,t1,t2,t3,t4,t5)
+ du=((ax-v)-vv)/ay; }
+
+ if (x>ZERO) {
+
+ /* (i) x>0, abs(y)< abs(x): atan(ay/ax) */
+ if (ay<ax) {
+ if (u<inv16.d) {
+ v=u*u; zz=du+u*v*(d3.d+v*(d5.d+v*(d7.d+v*(d9.d+v*(d11.d+v*d13.d)))));
+ if ((z=u+(zz-u1.d*u)) == u+(zz+u1.d*u)) return signArctan2(y,z);
+
+ MUL2(u,du,u,du,v,vv,t1,t2,t3,t4,t5,t6,t7,t8)
+ s1=v*(f11.d+v*(f13.d+v*(f15.d+v*(f17.d+v*f19.d))));
+ ADD2(f9.d,ff9.d,s1,ZERO,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f7.d,ff7.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f5.d,ff5.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f3.d,ff3.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(u,du,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(u,du,s2,ss2,s1,ss1,t1,t2)
+ if ((z=s1+(ss1-u5.d*s1)) == s1+(ss1+u5.d*s1)) return signArctan2(y,z);
+ return atan2Mp(x,y,pr);
+ }
+ else {
+ i=(TWO52+TWO8*u)-TWO52; i-=16;
+ t3=u-cij[i][0].d;
+ EADD(t3,du,v,dv)
+ t1=cij[i][1].d; t2=cij[i][2].d;
+ zz=v*t2+(dv*t2+v*v*(cij[i][3].d+v*(cij[i][4].d+
+ v*(cij[i][5].d+v* cij[i][6].d))));
+ if (i<112) {
+ if (i<48) u9=u91.d; /* u < 1/4 */
+ else u9=u92.d; } /* 1/4 <= u < 1/2 */
+ else {
+ if (i<176) u9=u93.d; /* 1/2 <= u < 3/4 */
+ else u9=u94.d; } /* 3/4 <= u <= 1 */
+ if ((z=t1+(zz-u9*t1)) == t1+(zz+u9*t1)) return signArctan2(y,z);
+
+ t1=u-hij[i][0].d;
+ EADD(t1,du,v,vv)
+ s1=v*(hij[i][11].d+v*(hij[i][12].d+v*(hij[i][13].d+
+ v*(hij[i][14].d+v* hij[i][15].d))));
+ ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][5].d,hij[i][6].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][3].d,hij[i][4].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][1].d,hij[i][2].d,s1,ss1,s2,ss2,t1,t2)
+ if ((z=s2+(ss2-ub.d*s2)) == s2+(ss2+ub.d*s2)) return signArctan2(y,z);
+ return atan2Mp(x,y,pr);
+ }
+ }
+
+ /* (ii) x>0, abs(x)<=abs(y): pi/2-atan(ax/ay) */
+ else {
+ if (u<inv16.d) {
+ v=u*u;
+ zz=u*v*(d3.d+v*(d5.d+v*(d7.d+v*(d9.d+v*(d11.d+v*d13.d)))));
+ ESUB(hpi.d,u,t2,cor)
+ t3=((hpi1.d+cor)-du)-zz;
+ if ((z=t2+(t3-u2.d)) == t2+(t3+u2.d)) return signArctan2(y,z);
+
+ MUL2(u,du,u,du,v,vv,t1,t2,t3,t4,t5,t6,t7,t8)
+ s1=v*(f11.d+v*(f13.d+v*(f15.d+v*(f17.d+v*f19.d))));
+ ADD2(f9.d,ff9.d,s1,ZERO,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f7.d,ff7.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f5.d,ff5.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f3.d,ff3.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(u,du,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(u,du,s2,ss2,s1,ss1,t1,t2)
+ SUB2(hpi.d,hpi1.d,s1,ss1,s2,ss2,t1,t2)
+ if ((z=s2+(ss2-u6.d)) == s2+(ss2+u6.d)) return signArctan2(y,z);
+ return atan2Mp(x,y,pr);
+ }
+ else {
+ i=(TWO52+TWO8*u)-TWO52; i-=16;
+ v=(u-cij[i][0].d)+du;
+ zz=hpi1.d-v*(cij[i][2].d+v*(cij[i][3].d+v*(cij[i][4].d+
+ v*(cij[i][5].d+v* cij[i][6].d))));
+ t1=hpi.d-cij[i][1].d;
+ if (i<112) ua=ua1.d; /* w < 1/2 */
+ else ua=ua2.d; /* w >= 1/2 */
+ if ((z=t1+(zz-ua)) == t1+(zz+ua)) return signArctan2(y,z);
+
+ t1=u-hij[i][0].d;
+ EADD(t1,du,v,vv)
+ s1=v*(hij[i][11].d+v*(hij[i][12].d+v*(hij[i][13].d+
+ v*(hij[i][14].d+v* hij[i][15].d))));
+ ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][5].d,hij[i][6].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][3].d,hij[i][4].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][1].d,hij[i][2].d,s1,ss1,s2,ss2,t1,t2)
+ SUB2(hpi.d,hpi1.d,s2,ss2,s1,ss1,t1,t2)
+ if ((z=s1+(ss1-uc.d)) == s1+(ss1+uc.d)) return signArctan2(y,z);
+ return atan2Mp(x,y,pr);
+ }
+ }
+ }
+ else {
+
+ /* (iii) x<0, abs(x)< abs(y): pi/2+atan(ax/ay) */
+ if (ax<ay) {
+ if (u<inv16.d) {
+ v=u*u;
+ zz=u*v*(d3.d+v*(d5.d+v*(d7.d+v*(d9.d+v*(d11.d+v*d13.d)))));
+ EADD(hpi.d,u,t2,cor)
+ t3=((hpi1.d+cor)+du)+zz;
+ if ((z=t2+(t3-u3.d)) == t2+(t3+u3.d)) return signArctan2(y,z);
+
+ MUL2(u,du,u,du,v,vv,t1,t2,t3,t4,t5,t6,t7,t8)
+ s1=v*(f11.d+v*(f13.d+v*(f15.d+v*(f17.d+v*f19.d))));
+ ADD2(f9.d,ff9.d,s1,ZERO,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f7.d,ff7.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f5.d,ff5.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f3.d,ff3.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(u,du,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(u,du,s2,ss2,s1,ss1,t1,t2)
+ ADD2(hpi.d,hpi1.d,s1,ss1,s2,ss2,t1,t2)
+ if ((z=s2+(ss2-u7.d)) == s2+(ss2+u7.d)) return signArctan2(y,z);
+ return atan2Mp(x,y,pr);
+ }
+ else {
+ i=(TWO52+TWO8*u)-TWO52; i-=16;
+ v=(u-cij[i][0].d)+du;
+ zz=hpi1.d+v*(cij[i][2].d+v*(cij[i][3].d+v*(cij[i][4].d+
+ v*(cij[i][5].d+v* cij[i][6].d))));
+ t1=hpi.d+cij[i][1].d;
+ if (i<112) ua=ua1.d; /* w < 1/2 */
+ else ua=ua2.d; /* w >= 1/2 */
+ if ((z=t1+(zz-ua)) == t1+(zz+ua)) return signArctan2(y,z);
+
+ t1=u-hij[i][0].d;
+ EADD(t1,du,v,vv)
+ s1=v*(hij[i][11].d+v*(hij[i][12].d+v*(hij[i][13].d+
+ v*(hij[i][14].d+v* hij[i][15].d))));
+ ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][5].d,hij[i][6].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][3].d,hij[i][4].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][1].d,hij[i][2].d,s1,ss1,s2,ss2,t1,t2)
+ ADD2(hpi.d,hpi1.d,s2,ss2,s1,ss1,t1,t2)
+ if ((z=s1+(ss1-uc.d)) == s1+(ss1+uc.d)) return signArctan2(y,z);
+ return atan2Mp(x,y,pr);
+ }
+ }
+
+ /* (iv) x<0, abs(y)<=abs(x): pi-atan(ax/ay) */
+ else {
+ if (u<inv16.d) {
+ v=u*u;
+ zz=u*v*(d3.d+v*(d5.d+v*(d7.d+v*(d9.d+v*(d11.d+v*d13.d)))));
+ ESUB(opi.d,u,t2,cor)
+ t3=((opi1.d+cor)-du)-zz;
+ if ((z=t2+(t3-u4.d)) == t2+(t3+u4.d)) return signArctan2(y,z);
+
+ MUL2(u,du,u,du,v,vv,t1,t2,t3,t4,t5,t6,t7,t8)
+ s1=v*(f11.d+v*(f13.d+v*(f15.d+v*(f17.d+v*f19.d))));
+ ADD2(f9.d,ff9.d,s1,ZERO,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f7.d,ff7.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f5.d,ff5.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f3.d,ff3.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(u,du,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(u,du,s2,ss2,s1,ss1,t1,t2)
+ SUB2(opi.d,opi1.d,s1,ss1,s2,ss2,t1,t2)
+ if ((z=s2+(ss2-u8.d)) == s2+(ss2+u8.d)) return signArctan2(y,z);
+ return atan2Mp(x,y,pr);
+ }
+ else {
+ i=(TWO52+TWO8*u)-TWO52; i-=16;
+ v=(u-cij[i][0].d)+du;
+ zz=opi1.d-v*(cij[i][2].d+v*(cij[i][3].d+v*(cij[i][4].d+
+ v*(cij[i][5].d+v* cij[i][6].d))));
+ t1=opi.d-cij[i][1].d;
+ if (i<112) ua=ua1.d; /* w < 1/2 */
+ else ua=ua2.d; /* w >= 1/2 */
+ if ((z=t1+(zz-ua)) == t1+(zz+ua)) return signArctan2(y,z);
+
+ t1=u-hij[i][0].d;
+ EADD(t1,du,v,vv)
+ s1=v*(hij[i][11].d+v*(hij[i][12].d+v*(hij[i][13].d+
+ v*(hij[i][14].d+v* hij[i][15].d))));
+ ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][5].d,hij[i][6].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][3].d,hij[i][4].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][1].d,hij[i][2].d,s1,ss1,s2,ss2,t1,t2)
+ SUB2(opi.d,opi1.d,s2,ss2,s1,ss1,t1,t2)
+ if ((z=s1+(ss1-uc.d)) == s1+(ss1+uc.d)) return signArctan2(y,z);
+ return atan2Mp(x,y,pr);
+ }
+ }
+ }
+}
+ /* Treat the Denormalized case */
+static double normalized(double ax,double ay,double y, double z)
+ { int p;
+ mp_no mpx,mpy,mpz,mperr,mpz2,mpt1;
+ p=6;
+ __dbl_mp(ax,&mpx,p); __dbl_mp(ay,&mpy,p); __dvd(&mpy,&mpx,&mpz,p);
+ __dbl_mp(ue.d,&mpt1,p); __mul(&mpz,&mpt1,&mperr,p);
+ __sub(&mpz,&mperr,&mpz2,p); __mp_dbl(&mpz2,&z,p);
+ return signArctan2(y,z);
+}
+ /* Fix the sign and return after stage 1 or stage 2 */
+static double signArctan2(double y,double z)
+{
+ return ((y<ZERO) ? -z : z);
+}
+ /* Stage 3: Perform a multi-Precision computation */
+static double atan2Mp(double x,double y,const int pr[])
+{
+ double z1,z2;
+ int i,p;
+ mp_no mpx,mpy,mpz,mpz1,mpz2,mperr,mpt1;
+ for (i=0; i<MM; i++) {
+ p = pr[i];
+ __dbl_mp(x,&mpx,p); __dbl_mp(y,&mpy,p);
+ __mpatan2(&mpy,&mpx,&mpz,p);
+ __dbl_mp(ud[i].d,&mpt1,p); __mul(&mpz,&mpt1,&mperr,p);
+ __add(&mpz,&mperr,&mpz1,p); __sub(&mpz,&mperr,&mpz2,p);
+ __mp_dbl(&mpz1,&z1,p); __mp_dbl(&mpz2,&z2,p);
+ if (z1==z2) return z1;
+ }
+ return z1; /*if unpossible to do exact computing */
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_atanh.c b/libc/sysdeps/ieee754/dbl-64/e_atanh.c
new file mode 100644
index 000000000..fa4fe675c
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_atanh.c
@@ -0,0 +1,74 @@
+/* @(#)e_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: e_atanh.c,v 1.8 1995/05/10 20:44:55 jtc Exp $";
+#endif
+
+/* __ieee754_atanh(x)
+ * Method :
+ * 1.Reduced x to positive by atanh(-x) = -atanh(x)
+ * 2.For x>=0.5
+ * 1 2x x
+ * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
+ * 2 1 - x 1 - x
+ *
+ * For x<0.5
+ * atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
+ *
+ * Special cases:
+ * atanh(x) is NaN if |x| > 1 with signal;
+ * atanh(NaN) is that NaN with no signal;
+ * atanh(+-1) is +-INF with signal.
+ *
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one = 1.0, huge = 1e300;
+#else
+static double one = 1.0, huge = 1e300;
+#endif
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_atanh(double x)
+#else
+ double __ieee754_atanh(x)
+ double x;
+#endif
+{
+ double t;
+ int32_t hx,ix;
+ u_int32_t lx;
+ EXTRACT_WORDS(hx,lx,x);
+ ix = hx&0x7fffffff;
+ if ((ix|((lx|(-lx))>>31))>0x3ff00000) /* |x|>1 */
+ return (x-x)/(x-x);
+ if(ix==0x3ff00000)
+ return x/zero;
+ if(ix<0x3e300000&&(huge+x)>zero) return x; /* x<2**-28 */
+ SET_HIGH_WORD(x,ix);
+ if(ix<0x3fe00000) { /* x < 0.5 */
+ t = x+x;
+ t = 0.5*__log1p(t+t*x/(one-x));
+ } else
+ t = 0.5*__log1p((x+x)/(one-x));
+ if(hx>=0) return t; else return -t;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_cosh.c b/libc/sysdeps/ieee754/dbl-64/e_cosh.c
new file mode 100644
index 000000000..65106b998
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_cosh.c
@@ -0,0 +1,92 @@
+/* @(#)e_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: e_cosh.c,v 1.7 1995/05/10 20:44:58 jtc Exp $";
+#endif
+
+/* __ieee754_cosh(x)
+ * Method :
+ * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
+ * 1. Replace x by |x| (cosh(x) = cosh(-x)).
+ * 2.
+ * [ exp(x) - 1 ]^2
+ * 0 <= x <= ln2/2 : cosh(x) := 1 + -------------------
+ * 2*exp(x)
+ *
+ * exp(x) + 1/exp(x)
+ * ln2/2 <= x <= 22 : cosh(x) := -------------------
+ * 2
+ * 22 <= x <= lnovft : cosh(x) := exp(x)/2
+ * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2)
+ * ln2ovft < x : cosh(x) := huge*huge (overflow)
+ *
+ * Special cases:
+ * cosh(x) is |x| if x is +INF, -INF, or NaN.
+ * only cosh(0)=1 is exact for finite x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one = 1.0, half=0.5, huge = 1.0e300;
+#else
+static double one = 1.0, half=0.5, huge = 1.0e300;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_cosh(double x)
+#else
+ double __ieee754_cosh(x)
+ double x;
+#endif
+{
+ double t,w;
+ int32_t ix;
+ u_int32_t lx;
+
+ /* High word of |x|. */
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7ff00000) return x*x;
+
+ /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
+ if(ix<0x3fd62e43) {
+ t = __expm1(fabs(x));
+ w = one+t;
+ if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */
+ return one+(t*t)/(w+w);
+ }
+
+ /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
+ if (ix < 0x40360000) {
+ t = __ieee754_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));
+
+ /* |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));
+ t = half*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, cosh(x) overflow */
+ return huge*huge;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_exp.c b/libc/sysdeps/ieee754/dbl-64/e_exp.c
new file mode 100644
index 000000000..717469e25
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_exp.c
@@ -0,0 +1,252 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/***************************************************************************/
+/* MODULE_NAME:uexp.c */
+/* */
+/* FUNCTION:uexp */
+/* exp1 */
+/* */
+/* FILES NEEDED:dla.h endian.h mpa.h mydefs.h uexp.h */
+/* mpa.c mpexp.x slowexp.c */
+/* */
+/* An ultimate exp routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of e^x */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round to nearest mode of IEEE 754 standard. */
+/* */
+/***************************************************************************/
+
+#include "endian.h"
+#include "uexp.h"
+#include "mydefs.h"
+#include "MathLib.h"
+#include "uexp.tbl"
+#include "math_private.h"
+
+double __slowexp(double);
+
+/***************************************************************************/
+/* An ultimate exp routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of e^x */
+/***************************************************************************/
+double __ieee754_exp(double x) {
+ double bexp, t, eps, del, base, y, al, bet, res, rem, cor;
+ mynumber junk1, junk2, binexp = {{0,0}};
+#if 0
+ int4 k;
+#endif
+ int4 i,j,m,n,ex;
+
+ junk1.x = x;
+ m = junk1.i[HIGH_HALF];
+ n = m&hugeint;
+
+ if (n > smallint && n < bigint) {
+
+ y = x*log2e.x + three51.x;
+ bexp = y - three51.x; /* multiply the result by 2**bexp */
+
+ junk1.x = y;
+
+ eps = bexp*ln_two2.x; /* x = bexp*ln(2) + t - eps */
+ t = x - bexp*ln_two1.x;
+
+ y = t + three33.x;
+ base = y - three33.x; /* t rounded to a multiple of 2**-18 */
+ junk2.x = y;
+ del = (t - base) - eps; /* x = bexp*ln(2) + base + del */
+ eps = del + del*del*(p3.x*del + p2.x);
+
+ binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+1023)<<20;
+
+ i = ((junk2.i[LOW_HALF]>>8)&0xfffffffe)+356;
+ j = (junk2.i[LOW_HALF]&511)<<1;
+
+ al = coar.x[i]*fine.x[j];
+ bet =(coar.x[i]*fine.x[j+1] + coar.x[i+1]*fine.x[j]) + coar.x[i+1]*fine.x[j+1];
+
+ rem=(bet + bet*eps)+al*eps;
+ res = al + rem;
+ cor = (al - res) + rem;
+ if (res == (res+cor*err_0)) return res*binexp.x;
+ else return __slowexp(x); /*if error is over bound */
+ }
+
+ if (n <= smallint) return 1.0;
+
+ if (n >= badint) {
+ if (n > infint) return(x+x); /* x is NaN */
+ if (n < infint) return ( (x>0) ? (hhuge*hhuge) : (tiny*tiny) );
+ /* x is finite, cause either overflow or underflow */
+ if (junk1.i[LOW_HALF] != 0) return (x+x); /* x is NaN */
+ return ((x>0)?inf.x:zero ); /* |x| = inf; return either inf or 0 */
+ }
+
+ y = x*log2e.x + three51.x;
+ bexp = y - three51.x;
+ junk1.x = y;
+ eps = bexp*ln_two2.x;
+ t = x - bexp*ln_two1.x;
+ y = t + three33.x;
+ base = y - three33.x;
+ junk2.x = y;
+ del = (t - base) - eps;
+ eps = del + del*del*(p3.x*del + p2.x);
+ i = ((junk2.i[LOW_HALF]>>8)&0xfffffffe)+356;
+ j = (junk2.i[LOW_HALF]&511)<<1;
+ al = coar.x[i]*fine.x[j];
+ bet =(coar.x[i]*fine.x[j+1] + coar.x[i+1]*fine.x[j]) + coar.x[i+1]*fine.x[j+1];
+ rem=(bet + bet*eps)+al*eps;
+ res = al + rem;
+ cor = (al - res) + rem;
+ if (m>>31) {
+ ex=junk1.i[LOW_HALF];
+ if (res < 1.0) {res+=res; cor+=cor; ex-=1;}
+ if (ex >=-1022) {
+ binexp.i[HIGH_HALF] = (1023+ex)<<20;
+ if (res == (res+cor*err_0)) return res*binexp.x;
+ else return __slowexp(x); /*if error is over bound */
+ }
+ ex = -(1022+ex);
+ binexp.i[HIGH_HALF] = (1023-ex)<<20;
+ res*=binexp.x;
+ cor*=binexp.x;
+ eps=1.0000000001+err_0*binexp.x;
+ t=1.0+res;
+ y = ((1.0-t)+res)+cor;
+ res=t+y;
+ cor = (t-res)+y;
+ if (res == (res + eps*cor))
+ { binexp.i[HIGH_HALF] = 0x00100000;
+ return (res-1.0)*binexp.x;
+ }
+ else return __slowexp(x); /* if error is over bound */
+ }
+ else {
+ binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+767)<<20;
+ if (res == (res+cor*err_0)) return res*binexp.x*t256.x;
+ else return __slowexp(x);
+ }
+}
+
+/************************************************************************/
+/* Compute e^(x+xx)(Double-Length number) .The routine also receive */
+/* bound of error of previous calculation .If after computing exp */
+/* error bigger than allows routine return non positive number */
+/*else return e^(x + xx) (always positive ) */
+/************************************************************************/
+
+double __exp1(double x, double xx, double error) {
+ double bexp, t, eps, del, base, y, al, bet, res, rem, cor;
+ mynumber junk1, junk2, binexp = {{0,0}};
+#if 0
+ int4 k;
+#endif
+ int4 i,j,m,n,ex;
+
+ junk1.x = x;
+ m = junk1.i[HIGH_HALF];
+ n = m&hugeint; /* no sign */
+
+ if (n > smallint && n < bigint) {
+ y = x*log2e.x + three51.x;
+ bexp = y - three51.x; /* multiply the result by 2**bexp */
+
+ junk1.x = y;
+
+ eps = bexp*ln_two2.x; /* x = bexp*ln(2) + t - eps */
+ t = x - bexp*ln_two1.x;
+
+ y = t + three33.x;
+ base = y - three33.x; /* t rounded to a multiple of 2**-18 */
+ junk2.x = y;
+ del = (t - base) + (xx-eps); /* x = bexp*ln(2) + base + del */
+ eps = del + del*del*(p3.x*del + p2.x);
+
+ binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+1023)<<20;
+
+ i = ((junk2.i[LOW_HALF]>>8)&0xfffffffe)+356;
+ j = (junk2.i[LOW_HALF]&511)<<1;
+
+ al = coar.x[i]*fine.x[j];
+ bet =(coar.x[i]*fine.x[j+1] + coar.x[i+1]*fine.x[j]) + coar.x[i+1]*fine.x[j+1];
+
+ rem=(bet + bet*eps)+al*eps;
+ res = al + rem;
+ cor = (al - res) + rem;
+ if (res == (res+cor*(1.0+error+err_1))) return res*binexp.x;
+ else return -10.0;
+ }
+
+ if (n <= smallint) return 1.0; /* if x->0 e^x=1 */
+
+ if (n >= badint) {
+ if (n > infint) return(zero/zero); /* x is NaN, return invalid */
+ if (n < infint) return ( (x>0) ? (hhuge*hhuge) : (tiny*tiny) );
+ /* x is finite, cause either overflow or underflow */
+ if (junk1.i[LOW_HALF] != 0) return (zero/zero); /* x is NaN */
+ return ((x>0)?inf.x:zero ); /* |x| = inf; return either inf or 0 */
+ }
+
+ y = x*log2e.x + three51.x;
+ bexp = y - three51.x;
+ junk1.x = y;
+ eps = bexp*ln_two2.x;
+ t = x - bexp*ln_two1.x;
+ y = t + three33.x;
+ base = y - three33.x;
+ junk2.x = y;
+ del = (t - base) + (xx-eps);
+ eps = del + del*del*(p3.x*del + p2.x);
+ i = ((junk2.i[LOW_HALF]>>8)&0xfffffffe)+356;
+ j = (junk2.i[LOW_HALF]&511)<<1;
+ al = coar.x[i]*fine.x[j];
+ bet =(coar.x[i]*fine.x[j+1] + coar.x[i+1]*fine.x[j]) + coar.x[i+1]*fine.x[j+1];
+ rem=(bet + bet*eps)+al*eps;
+ res = al + rem;
+ cor = (al - res) + rem;
+ if (m>>31) {
+ ex=junk1.i[LOW_HALF];
+ if (res < 1.0) {res+=res; cor+=cor; ex-=1;}
+ if (ex >=-1022) {
+ binexp.i[HIGH_HALF] = (1023+ex)<<20;
+ if (res == (res+cor*(1.0+error+err_1))) return res*binexp.x;
+ else return -10.0;
+ }
+ ex = -(1022+ex);
+ binexp.i[HIGH_HALF] = (1023-ex)<<20;
+ res*=binexp.x;
+ cor*=binexp.x;
+ eps=1.00000000001+(error+err_1)*binexp.x;
+ t=1.0+res;
+ y = ((1.0-t)+res)+cor;
+ res=t+y;
+ cor = (t-res)+y;
+ if (res == (res + eps*cor))
+ {binexp.i[HIGH_HALF] = 0x00100000; return (res-1.0)*binexp.x;}
+ else return -10.0;
+ }
+ else {
+ binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+767)<<20;
+ if (res == (res+cor*(1.0+error+err_1)))
+ return res*binexp.x*t256.x;
+ else return -10.0;
+ }
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_exp2.c b/libc/sysdeps/ieee754/dbl-64/e_exp2.c
new file mode 100644
index 000000000..ce6368be4
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_exp2.c
@@ -0,0 +1,135 @@
+/* Double-precision floating point 2^x.
+ Copyright (C) 1997,1998,2000,2001,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Geoffrey Keating <geoffk@ozemail.com.au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The basic design here is from
+ Shmuel Gal and Boris Bachelis, "An Accurate Elementary Mathematical
+ Library for the IEEE Floating Point Standard", ACM Trans. Math. Soft.,
+ 17 (1), March 1991, pp. 26-45.
+ It has been slightly modified to compute 2^x instead of e^x.
+ */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdlib.h>
+#include <float.h>
+#include <ieee754.h>
+#include <math.h>
+#include <fenv.h>
+#include <inttypes.h>
+#include <math_private.h>
+
+#include "t_exp2.h"
+
+/* XXX I know the assembler generates a warning about incorrect section
+ attributes. But without the attribute here the compiler places the
+ constants in the .data section. Ideally the constant is placed in
+ .rodata.cst8 so that it can be merged, but gcc sucks, it ICEs when
+ we try to force this section on it. --drepper */
+static const volatile double TWO1023 = 8.988465674311579539e+307;
+static const volatile double TWOM1000 = 9.3326361850321887899e-302;
+
+double
+__ieee754_exp2 (double x)
+{
+ static const double himark = (double) DBL_MAX_EXP;
+ static const double lomark = (double) (DBL_MIN_EXP - DBL_MANT_DIG - 1);
+
+ /* Check for usual case. */
+ if (isless (x, himark) && isgreaterequal (x, lomark))
+ {
+ static const double THREEp42 = 13194139533312.0;
+ int tval, unsafe;
+ double rx, x22, result;
+ union ieee754_double ex2_u, scale_u;
+ fenv_t oldenv;
+
+ feholdexcept (&oldenv);
+#ifdef FE_TONEAREST
+ /* If we don't have this, it's too bad. */
+ fesetround (FE_TONEAREST);
+#endif
+
+ /* 1. Argument reduction.
+ Choose integers ex, -256 <= t < 256, and some real
+ -1/1024 <= x1 <= 1024 so that
+ x = ex + t/512 + x1.
+
+ First, calculate rx = ex + t/512. */
+ rx = x + THREEp42;
+ rx -= THREEp42;
+ x -= rx; /* Compute x=x1. */
+ /* Compute tval = (ex*512 + t)+256.
+ Now, t = (tval mod 512)-256 and ex=tval/512 [that's mod, NOT %; and
+ /-round-to-nearest not the usual c integer /]. */
+ tval = (int) (rx * 512.0 + 256.0);
+
+ /* 2. Adjust for accurate table entry.
+ Find e so that
+ x = ex + t/512 + e + x2
+ where -1e6 < e < 1e6, and
+ (double)(2^(t/512+e))
+ is accurate to one part in 2^-64. */
+
+ /* 'tval & 511' is the same as 'tval%512' except that it's always
+ positive.
+ Compute x = x2. */
+ x -= exp2_deltatable[tval & 511];
+
+ /* 3. Compute ex2 = 2^(t/512+e+ex). */
+ ex2_u.d = exp2_accuratetable[tval & 511];
+ tval >>= 9;
+ unsafe = abs(tval) >= -DBL_MIN_EXP - 1;
+ ex2_u.ieee.exponent += tval >> unsafe;
+ scale_u.d = 1.0;
+ scale_u.ieee.exponent += tval - (tval >> unsafe);
+
+ /* 4. Approximate 2^x2 - 1, using a fourth-degree polynomial,
+ with maximum error in [-2^-10-2^-30,2^-10+2^-30]
+ less than 10^-19. */
+
+ x22 = (((.0096181293647031180
+ * x + .055504110254308625)
+ * x + .240226506959100583)
+ * x + .69314718055994495) * ex2_u.d;
+
+ /* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex). */
+ fesetenv (&oldenv);
+
+ result = x22 * x + ex2_u.d;
+
+ if (!unsafe)
+ return result;
+ else
+ return result * scale_u.d;
+ }
+ /* Exceptional cases: */
+ else if (isless (x, himark))
+ {
+ if (__isinf (x))
+ /* e^-inf == 0, with no error. */
+ return 0;
+ else
+ /* Underflow */
+ return TWOM1000 * TWOM1000;
+ }
+ else
+ /* Return x, if x is a NaN or Inf; or overflow, otherwise. */
+ return TWO1023*x;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_fmod.c b/libc/sysdeps/ieee754/dbl-64/e_fmod.c
new file mode 100644
index 000000000..2ce613574
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_fmod.c
@@ -0,0 +1,140 @@
+/* @(#)e_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: e_fmod.c,v 1.8 1995/05/10 20:45:07 jtc Exp $";
+#endif
+
+/*
+ * __ieee754_fmod(x,y)
+ * Return x mod y in exact arithmetic
+ * Method: shift and subtract
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one = 1.0, Zero[] = {0.0, -0.0,};
+#else
+static double one = 1.0, Zero[] = {0.0, -0.0,};
+#endif
+
+#ifdef __STDC__
+ double __ieee754_fmod(double x, double y)
+#else
+ double __ieee754_fmod(x,y)
+ double x,y ;
+#endif
+{
+ int32_t n,hx,hy,hz,ix,iy,sx,i;
+ u_int32_t lx,ly,lz;
+
+ EXTRACT_WORDS(hx,lx,x);
+ EXTRACT_WORDS(hy,ly,y);
+ sx = hx&0x80000000; /* sign of x */
+ hx ^=sx; /* |x| */
+ hy &= 0x7fffffff; /* |y| */
+
+ /* purge off exception values */
+ if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
+ ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */
+ return (x*y)/(x*y);
+ if(hx<=hy) {
+ if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
+ if(lx==ly)
+ return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/
+ }
+
+ /* determine ix = ilogb(x) */
+ if(hx<0x00100000) { /* subnormal x */
+ if(hx==0) {
+ for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
+ } else {
+ for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
+ }
+ } else ix = (hx>>20)-1023;
+
+ /* determine iy = ilogb(y) */
+ if(hy<0x00100000) { /* subnormal y */
+ if(hy==0) {
+ for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
+ } else {
+ for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
+ }
+ } else iy = (hy>>20)-1023;
+
+ /* set up {hx,lx}, {hy,ly} and align y to x */
+ if(ix >= -1022)
+ hx = 0x00100000|(0x000fffff&hx);
+ else { /* subnormal x, shift x to normal */
+ n = -1022-ix;
+ if(n<=31) {
+ hx = (hx<<n)|(lx>>(32-n));
+ lx <<= n;
+ } else {
+ hx = lx<<(n-32);
+ lx = 0;
+ }
+ }
+ if(iy >= -1022)
+ hy = 0x00100000|(0x000fffff&hy);
+ else { /* subnormal y, shift y to normal */
+ n = -1022-iy;
+ if(n<=31) {
+ hy = (hy<<n)|(ly>>(32-n));
+ ly <<= n;
+ } else {
+ hy = ly<<(n-32);
+ ly = 0;
+ }
+ }
+
+ /* fix point fmod */
+ n = ix - iy;
+ while(n--) {
+ hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
+ else {
+ if((hz|lz)==0) /* return sign(x)*0 */
+ return Zero[(u_int32_t)sx>>31];
+ hx = hz+hz+(lz>>31); lx = lz+lz;
+ }
+ }
+ hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ if(hz>=0) {hx=hz;lx=lz;}
+
+ /* convert back to floating value and restore the sign */
+ if((hx|lx)==0) /* return sign(x)*0 */
+ return Zero[(u_int32_t)sx>>31];
+ while(hx<0x00100000) { /* normalize x */
+ hx = hx+hx+(lx>>31); lx = lx+lx;
+ iy -= 1;
+ }
+ if(iy>= -1022) { /* normalize output */
+ hx = ((hx-0x00100000)|((iy+1023)<<20));
+ INSERT_WORDS(x,hx|sx,lx);
+ } else { /* subnormal output */
+ n = -1022 - iy;
+ if(n<=20) {
+ lx = (lx>>n)|((u_int32_t)hx<<(32-n));
+ hx >>= n;
+ } else if (n<=31) {
+ lx = (hx<<(32-n))|(lx>>n); hx = sx;
+ } else {
+ lx = hx>>(n-32); hx = sx;
+ }
+ INSERT_WORDS(x,hx|sx,lx);
+ x *= one; /* create necessary signal */
+ }
+ return x; /* exact output */
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_gamma_r.c b/libc/sysdeps/ieee754/dbl-64/e_gamma_r.c
new file mode 100644
index 000000000..f32309350
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_gamma_r.c
@@ -0,0 +1,57 @@
+/* Implementation of gamma function according to ISO C.
+ Copyright (C) 1997, 1999, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_private.h>
+
+
+double
+__ieee754_gamma_r (double x, int *signgamp)
+{
+ /* We don't have a real gamma implementation now. We'll use lgamma
+ and the exp function. But due to the required boundary
+ conditions we must check some values separately. */
+ int32_t hx;
+ u_int32_t lx;
+
+ EXTRACT_WORDS (hx, lx, x);
+
+ if (((hx & 0x7fffffff) | lx) == 0)
+ {
+ /* Return value for x == 0 is Inf with divide by zero exception. */
+ *signgamp = 0;
+ return 1.0 / x;
+ }
+ if (hx < 0 && (u_int32_t) hx < 0xfff00000 && __rint (x) == x)
+ {
+ /* Return value for integer x < 0 is NaN with invalid exception. */
+ *signgamp = 0;
+ return (x - x) / (x - x);
+ }
+ if ((unsigned int) hx == 0xfff00000 && lx==0)
+ {
+ /* x == -Inf. According to ISO this is NaN. */
+ *signgamp = 0;
+ return x - x;
+ }
+
+ /* XXX FIXME. */
+ return __ieee754_exp (__ieee754_lgamma_r (x, signgamp));
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_hypot.c b/libc/sysdeps/ieee754/dbl-64/e_hypot.c
new file mode 100644
index 000000000..76a77ec33
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_hypot.c
@@ -0,0 +1,128 @@
+/* @(#)e_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: e_hypot.c,v 1.9 1995/05/12 04:57:27 jtc Exp $";
+#endif
+
+/* __ieee754_hypot(x,y)
+ *
+ * Method :
+ * If (assume round-to-nearest) z=x*x+y*y
+ * has error less than sqrt(2)/2 ulp, than
+ * sqrt(z) has error less than 1 ulp (exercise).
+ *
+ * So, compute sqrt(x*x+y*y) with some care as
+ * follows to get the error below 1 ulp:
+ *
+ * Assume x>y>0;
+ * (if possible, set rounding to round-to-nearest)
+ * 1. if x > 2y use
+ * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
+ * where x1 = x with lower 32 bits cleared, x2 = x-x1; else
+ * 2. if x <= 2y use
+ * t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
+ * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
+ * y1= y with lower 32 bits chopped, y2 = y-y1.
+ *
+ * NOTE: scaling may be necessary if some argument is too
+ * large or too tiny
+ *
+ * Special cases:
+ * hypot(x,y) is INF if x or y is +INF or -INF; else
+ * hypot(x,y) is NAN if x or y is NAN.
+ *
+ * Accuracy:
+ * hypot(x,y) returns sqrt(x^2+y^2) with error less
+ * than 1 ulps (units in the last place)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __ieee754_hypot(double x, double y)
+#else
+ double __ieee754_hypot(x,y)
+ double x, y;
+#endif
+{
+ double a,b,t1,t2,y1,y2,w;
+ int32_t j,k,ha,hb;
+
+ GET_HIGH_WORD(ha,x);
+ ha &= 0x7fffffff;
+ GET_HIGH_WORD(hb,y);
+ hb &= 0x7fffffff;
+ if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
+ SET_HIGH_WORD(a,ha); /* a <- |a| */
+ SET_HIGH_WORD(b,hb); /* b <- |b| */
+ if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
+ k=0;
+ if(ha > 0x5f300000) { /* a>2**500 */
+ if(ha >= 0x7ff00000) { /* Inf or NaN */
+ u_int32_t low;
+ w = a+b; /* for sNaN */
+ GET_LOW_WORD(low,a);
+ if(((ha&0xfffff)|low)==0) w = a;
+ GET_LOW_WORD(low,b);
+ if(((hb^0x7ff00000)|low)==0) w = b;
+ return w;
+ }
+ /* scale a and b by 2**-600 */
+ ha -= 0x25800000; hb -= 0x25800000; k += 600;
+ SET_HIGH_WORD(a,ha);
+ SET_HIGH_WORD(b,hb);
+ }
+ if(hb < 0x20b00000) { /* b < 2**-500 */
+ if(hb <= 0x000fffff) { /* subnormal b or 0 */
+ u_int32_t low;
+ GET_LOW_WORD(low,b);
+ if((hb|low)==0) return a;
+ t1=0;
+ SET_HIGH_WORD(t1,0x7fd00000); /* t1=2^1022 */
+ b *= t1;
+ a *= t1;
+ k -= 1022;
+ } else { /* scale a and b by 2^600 */
+ ha += 0x25800000; /* a *= 2^600 */
+ hb += 0x25800000; /* b *= 2^600 */
+ k -= 600;
+ SET_HIGH_WORD(a,ha);
+ SET_HIGH_WORD(b,hb);
+ }
+ }
+ /* medium size a and b */
+ w = a-b;
+ if (w>b) {
+ t1 = 0;
+ SET_HIGH_WORD(t1,ha);
+ t2 = a-t1;
+ w = __ieee754_sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
+ } else {
+ a = a+a;
+ y1 = 0;
+ SET_HIGH_WORD(y1,hb);
+ y2 = b - y1;
+ t1 = 0;
+ SET_HIGH_WORD(t1,ha+0x00100000);
+ t2 = a - t1;
+ w = __ieee754_sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
+ }
+ if(k!=0) {
+ u_int32_t high;
+ t1 = 1.0;
+ GET_HIGH_WORD(high,t1);
+ SET_HIGH_WORD(t1,high+(k<<20));
+ return t1*w;
+ } else return w;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_j0.c b/libc/sysdeps/ieee754/dbl-64/e_j0.c
new file mode 100644
index 000000000..302df49d6
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_j0.c
@@ -0,0 +1,529 @@
+/* @(#)e_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.
+ * ====================================================
+ */
+/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/26,
+ for performance improvement on pipelined processors.
+*/
+
+#if defined(LIBM_SCCS) && !defined(lint)
+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)
+ * 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 - ...
+ * 2. Reduce x to |x| since j0(x)=j0(-x), and
+ * for x in (0,2)
+ * j0(x) = 1-z/4+ z^2*R0/S0, where z = x*x;
+ * (precision: |j0-1+z/4-z^2R0/S0 |<2**-63.67 )
+ * for x in (2,inf)
+ * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0))
+ * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
+ * as follow:
+ * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+ * = 1/sqrt(2) * (cos(x) + sin(x))
+ * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * (To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.)
+ *
+ * 3 Special cases
+ * j0(nan)= nan
+ * j0(0) = 1
+ * j0(inf) = 0
+ *
+ * Method -- y0(x):
+ * 1. For x<2.
+ * Since
+ * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...)
+ * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function.
+ * We use the following function to approximate y0,
+ * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2
+ * where
+ * U(z) = u00 + u01*z + ... + u06*z^6
+ * V(z) = 1 + v01*z + ... + v04*z^4
+ * with absolute approximation error bounded by 2**-72.
+ * Note: For tiny x, U/V = u0 and j0(x)~1, hence
+ * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27)
+ * 2. For x>=2.
+ * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0))
+ * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
+ * by the method mentioned above.
+ * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static double pzero(double), qzero(double);
+#else
+static double pzero(), qzero();
+#endif
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+huge = 1e300,
+one = 1.0,
+invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+ /* R0/S0 on [0, 2.00] */
+R[] = {0.0, 0.0, 1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */
+ -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */
+ 1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */
+ -4.61832688532103189199e-09}, /* 0xBE33D5E7, 0x73D63FCE */
+S[] = {0.0, 1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */
+ 1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */
+ 5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */
+ 1.16614003333790000205e-09}; /* 0x3E1408BC, 0xF4745D8F */
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_j0(double x)
+#else
+ double __ieee754_j0(x)
+ double x;
+#endif
+{
+ double z, s,c,ss,cc,r,u,v,r1,r2,s1,s2,z2,z4;
+ int32_t hx,ix;
+
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) return one/(x*x);
+ x = fabs(x);
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ __sincos (x, &s, &c);
+ ss = s-c;
+ cc = s+c;
+ if(ix<0x7fe00000) { /* make sure x+x not overflow */
+ z = -__cos(x+x);
+ if ((s*c)<zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /*
+ * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+ * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+ */
+ if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrt(x);
+ else {
+ u = pzero(x); v = qzero(x);
+ z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrt(x);
+ }
+ return z;
+ }
+ if(ix<0x3f200000) { /* |x| < 2**-13 */
+ if(huge+x>one) { /* raise inexact if x != 0 */
+ if(ix<0x3e400000) return one; /* |x|<2**-27 */
+ else return one - 0.25*x*x;
+ }
+ }
+ z = x*x;
+#ifdef DO_NOT_USE_THIS
+ r = z*(R02+z*(R03+z*(R04+z*R05)));
+ s = one+z*(S01+z*(S02+z*(S03+z*S04)));
+#else
+ r1 = z*R[2]; z2=z*z;
+ r2 = R[3]+z*R[4]; z4=z2*z2;
+ r = r1 + z2*r2 + z4*R[5];
+ s1 = one+z*S[1];
+ s2 = S[2]+z*S[3];
+ s = s1 + z2*s2 + z4*S[4];
+#endif
+ if(ix < 0x3FF00000) { /* |x| < 1.00 */
+ return one + z*(-0.25+(r/s));
+ } else {
+ u = 0.5*x;
+ return((one+u)*(one-u)+z*(r/s));
+ }
+}
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+U[] = {-7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */
+ 1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */
+ -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */
+ 3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */
+ -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */
+ 1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */
+ -3.98205194132103398453e-11}, /* 0xBDC5E43D, 0x693FB3C8 */
+V[] = {1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */
+ 7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */
+ 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */
+ 4.41110311332675467403e-10}; /* 0x3DFE5018, 0x3BD6D9EF */
+
+#ifdef __STDC__
+ double __ieee754_y0(double x)
+#else
+ double __ieee754_y0(x)
+ double x;
+#endif
+{
+ double z, s,c,ss,cc,u,v,z2,z4,z6,u1,u2,u3,v1,v2;
+ int32_t hx,ix,lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+ ix = 0x7fffffff&hx;
+ /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0, y0(0) is -inf. */
+ if(ix>=0x7ff00000) return one/(x+x*x);
+ if((ix|lx)==0) return -HUGE_VAL+x; /* -inf and overflow exception. */
+ if(hx<0) return zero/(zero*x);
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
+ * where x0 = x-pi/4
+ * Better formula:
+ * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+ * = 1/sqrt(2) * (sin(x) + cos(x))
+ * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.
+ */
+ __sincos (x, &s, &c);
+ ss = s-c;
+ cc = s+c;
+ /*
+ * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+ * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+ */
+ if(ix<0x7fe00000) { /* make sure x+x not overflow */
+ z = -__cos(x+x);
+ if ((s*c)<zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrt(x);
+ else {
+ u = pzero(x); v = qzero(x);
+ z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrt(x);
+ }
+ return z;
+ }
+ if(ix<=0x3e400000) { /* x < 2**-27 */
+ return(U[0] + tpi*__ieee754_log(x));
+ }
+ z = x*x;
+#ifdef DO_NOT_USE_THIS
+ u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
+ v = one+z*(v01+z*(v02+z*(v03+z*v04)));
+#else
+ u1 = U[0]+z*U[1]; z2=z*z;
+ u2 = U[2]+z*U[3]; z4=z2*z2;
+ u3 = U[4]+z*U[5]; z6=z4*z2;
+ u = u1 + z2*u2 + z4*u3 + z6*U[6];
+ v1 = one+z*V[0];
+ v2 = V[1]+z*V[2];
+ v = v1 + z2*v2 + z4*V[3];
+#endif
+ return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x)));
+}
+
+/* The asymptotic expansions of pzero is
+ * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x.
+ * For x >= 2, We approximate pzero by
+ * pzero(x) = 1 + (R/S)
+ * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10
+ * S = 1 + pS0*s^2 + ... + pS4*s^10
+ * and
+ * | pzero(x)-1-R/S | <= 2 ** ( -60.26)
+ */
+#ifdef __STDC__
+static const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+ -7.03124999999900357484e-02, /* 0xBFB1FFFF, 0xFFFFFD32 */
+ -8.08167041275349795626e+00, /* 0xC02029D0, 0xB44FA779 */
+ -2.57063105679704847262e+02, /* 0xC0701102, 0x7B19E863 */
+ -2.48521641009428822144e+03, /* 0xC0A36A6E, 0xCD4DCAFC */
+ -5.25304380490729545272e+03, /* 0xC0B4850B, 0x36CC643D */
+};
+#ifdef __STDC__
+static const double pS8[5] = {
+#else
+static double pS8[5] = {
+#endif
+ 1.16534364619668181717e+02, /* 0x405D2233, 0x07A96751 */
+ 3.83374475364121826715e+03, /* 0x40ADF37D, 0x50596938 */
+ 4.05978572648472545552e+04, /* 0x40E3D2BB, 0x6EB6B05F */
+ 1.16752972564375915681e+05, /* 0x40FC810F, 0x8F9FA9BD */
+ 4.76277284146730962675e+04, /* 0x40E74177, 0x4F2C49DC */
+};
+
+#ifdef __STDC__
+static const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ -1.14125464691894502584e-11, /* 0xBDA918B1, 0x47E495CC */
+ -7.03124940873599280078e-02, /* 0xBFB1FFFF, 0xE69AFBC6 */
+ -4.15961064470587782438e+00, /* 0xC010A370, 0xF90C6BBF */
+ -6.76747652265167261021e+01, /* 0xC050EB2F, 0x5A7D1783 */
+ -3.31231299649172967747e+02, /* 0xC074B3B3, 0x6742CC63 */
+ -3.46433388365604912451e+02, /* 0xC075A6EF, 0x28A38BD7 */
+};
+#ifdef __STDC__
+static const double pS5[5] = {
+#else
+static double pS5[5] = {
+#endif
+ 6.07539382692300335975e+01, /* 0x404E6081, 0x0C98C5DE */
+ 1.05125230595704579173e+03, /* 0x40906D02, 0x5C7E2864 */
+ 5.97897094333855784498e+03, /* 0x40B75AF8, 0x8FBE1D60 */
+ 9.62544514357774460223e+03, /* 0x40C2CCB8, 0xFA76FA38 */
+ 2.40605815922939109441e+03, /* 0x40A2CC1D, 0xC70BE864 */
+};
+
+#ifdef __STDC__
+static const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#else
+static double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ -2.54704601771951915620e-09, /* 0xBE25E103, 0x6FE1AA86 */
+ -7.03119616381481654654e-02, /* 0xBFB1FFF6, 0xF7C0E24B */
+ -2.40903221549529611423e+00, /* 0xC00345B2, 0xAEA48074 */
+ -2.19659774734883086467e+01, /* 0xC035F74A, 0x4CB94E14 */
+ -5.80791704701737572236e+01, /* 0xC04D0A22, 0x420A1A45 */
+ -3.14479470594888503854e+01, /* 0xC03F72AC, 0xA892D80F */
+};
+#ifdef __STDC__
+static const double pS3[5] = {
+#else
+static double pS3[5] = {
+#endif
+ 3.58560338055209726349e+01, /* 0x4041ED92, 0x84077DD3 */
+ 3.61513983050303863820e+02, /* 0x40769839, 0x464A7C0E */
+ 1.19360783792111533330e+03, /* 0x4092A66E, 0x6D1061D6 */
+ 1.12799679856907414432e+03, /* 0x40919FFC, 0xB8C39B7E */
+ 1.73580930813335754692e+02, /* 0x4065B296, 0xFC379081 */
+};
+
+#ifdef __STDC__
+static const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ -8.87534333032526411254e-08, /* 0xBE77D316, 0xE927026D */
+ -7.03030995483624743247e-02, /* 0xBFB1FF62, 0x495E1E42 */
+ -1.45073846780952986357e+00, /* 0xBFF73639, 0x8A24A843 */
+ -7.63569613823527770791e+00, /* 0xC01E8AF3, 0xEDAFA7F3 */
+ -1.11931668860356747786e+01, /* 0xC02662E6, 0xC5246303 */
+ -3.23364579351335335033e+00, /* 0xC009DE81, 0xAF8FE70F */
+};
+#ifdef __STDC__
+static const double pS2[5] = {
+#else
+static double pS2[5] = {
+#endif
+ 2.22202997532088808441e+01, /* 0x40363865, 0x908B5959 */
+ 1.36206794218215208048e+02, /* 0x4061069E, 0x0EE8878F */
+ 2.70470278658083486789e+02, /* 0x4070E786, 0x42EA079B */
+ 1.53875394208320329881e+02, /* 0x40633C03, 0x3AB6FAFF */
+ 1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */
+};
+
+#ifdef __STDC__
+ static double pzero(double x)
+#else
+ static double pzero(x)
+ double x;
+#endif
+{
+#ifdef __STDC__
+ const double *p,*q;
+#else
+ double *p,*q;
+#endif
+ double z,r,s,z2,z4,r1,r2,r3,s1,s2,s3;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x40200000) {p = pR8; q= pS8;}
+ else if(ix>=0x40122E8B){p = pR5; q= pS5;}
+ else if(ix>=0x4006DB6D){p = pR3; q= pS3;}
+ else if(ix>=0x40000000){p = pR2; q= pS2;}
+ z = one/(x*x);
+#ifdef DO_NOT_USE_THIS
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+#else
+ r1 = p[0]+z*p[1]; z2=z*z;
+ r2 = p[2]+z*p[3]; z4=z2*z2;
+ r3 = p[4]+z*p[5];
+ r = r1 + z2*r2 + z4*r3;
+ s1 = one+z*q[0];
+ s2 = q[1]+z*q[2];
+ s3 = q[3]+z*q[4];
+ s = s1 + z2*s2 + z4*s3;
+#endif
+ return one+ r/s;
+}
+
+
+/* For x >= 8, the asymptotic expansions of qzero is
+ * -1/8 s + 75/1024 s^3 - ..., where s = 1/x.
+ * We approximate pzero by
+ * qzero(x) = s*(-1.25 + (R/S))
+ * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10
+ * S = 1 + qS0*s^2 + ... + qS5*s^12
+ * and
+ * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22)
+ */
+#ifdef __STDC__
+static const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+ 7.32421874999935051953e-02, /* 0x3FB2BFFF, 0xFFFFFE2C */
+ 1.17682064682252693899e+01, /* 0x40278952, 0x5BB334D6 */
+ 5.57673380256401856059e+02, /* 0x40816D63, 0x15301825 */
+ 8.85919720756468632317e+03, /* 0x40C14D99, 0x3E18F46D */
+ 3.70146267776887834771e+04, /* 0x40E212D4, 0x0E901566 */
+};
+#ifdef __STDC__
+static const double qS8[6] = {
+#else
+static double qS8[6] = {
+#endif
+ 1.63776026895689824414e+02, /* 0x406478D5, 0x365B39BC */
+ 8.09834494656449805916e+03, /* 0x40BFA258, 0x4E6B0563 */
+ 1.42538291419120476348e+05, /* 0x41016652, 0x54D38C3F */
+ 8.03309257119514397345e+05, /* 0x412883DA, 0x83A52B43 */
+ 8.40501579819060512818e+05, /* 0x4129A66B, 0x28DE0B3D */
+ -3.43899293537866615225e+05, /* 0xC114FD6D, 0x2C9530C5 */
+};
+
+#ifdef __STDC__
+static const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ 1.84085963594515531381e-11, /* 0x3DB43D8F, 0x29CC8CD9 */
+ 7.32421766612684765896e-02, /* 0x3FB2BFFF, 0xD172B04C */
+ 5.83563508962056953777e+00, /* 0x401757B0, 0xB9953DD3 */
+ 1.35111577286449829671e+02, /* 0x4060E392, 0x0A8788E9 */
+ 1.02724376596164097464e+03, /* 0x40900CF9, 0x9DC8C481 */
+ 1.98997785864605384631e+03, /* 0x409F17E9, 0x53C6E3A6 */
+};
+#ifdef __STDC__
+static const double qS5[6] = {
+#else
+static double qS5[6] = {
+#endif
+ 8.27766102236537761883e+01, /* 0x4054B1B3, 0xFB5E1543 */
+ 2.07781416421392987104e+03, /* 0x40A03BA0, 0xDA21C0CE */
+ 1.88472887785718085070e+04, /* 0x40D267D2, 0x7B591E6D */
+ 5.67511122894947329769e+04, /* 0x40EBB5E3, 0x97E02372 */
+ 3.59767538425114471465e+04, /* 0x40E19118, 0x1F7A54A0 */
+ -5.35434275601944773371e+03, /* 0xC0B4EA57, 0xBEDBC609 */
+};
+
+#ifdef __STDC__
+static const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#else
+static double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ 4.37741014089738620906e-09, /* 0x3E32CD03, 0x6ADECB82 */
+ 7.32411180042911447163e-02, /* 0x3FB2BFEE, 0x0E8D0842 */
+ 3.34423137516170720929e+00, /* 0x400AC0FC, 0x61149CF5 */
+ 4.26218440745412650017e+01, /* 0x40454F98, 0x962DAEDD */
+ 1.70808091340565596283e+02, /* 0x406559DB, 0xE25EFD1F */
+ 1.66733948696651168575e+02, /* 0x4064D77C, 0x81FA21E0 */
+};
+#ifdef __STDC__
+static const double qS3[6] = {
+#else
+static double qS3[6] = {
+#endif
+ 4.87588729724587182091e+01, /* 0x40486122, 0xBFE343A6 */
+ 7.09689221056606015736e+02, /* 0x40862D83, 0x86544EB3 */
+ 3.70414822620111362994e+03, /* 0x40ACF04B, 0xE44DFC63 */
+ 6.46042516752568917582e+03, /* 0x40B93C6C, 0xD7C76A28 */
+ 2.51633368920368957333e+03, /* 0x40A3A8AA, 0xD94FB1C0 */
+ -1.49247451836156386662e+02, /* 0xC062A7EB, 0x201CF40F */
+};
+
+#ifdef __STDC__
+static const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ 1.50444444886983272379e-07, /* 0x3E84313B, 0x54F76BDB */
+ 7.32234265963079278272e-02, /* 0x3FB2BEC5, 0x3E883E34 */
+ 1.99819174093815998816e+00, /* 0x3FFFF897, 0xE727779C */
+ 1.44956029347885735348e+01, /* 0x402CFDBF, 0xAAF96FE5 */
+ 3.16662317504781540833e+01, /* 0x403FAA8E, 0x29FBDC4A */
+ 1.62527075710929267416e+01, /* 0x403040B1, 0x71814BB4 */
+};
+#ifdef __STDC__
+static const double qS2[6] = {
+#else
+static double qS2[6] = {
+#endif
+ 3.03655848355219184498e+01, /* 0x403E5D96, 0xF7C07AED */
+ 2.69348118608049844624e+02, /* 0x4070D591, 0xE4D14B40 */
+ 8.44783757595320139444e+02, /* 0x408A6645, 0x22B3BF22 */
+ 8.82935845112488550512e+02, /* 0x408B977C, 0x9C5CC214 */
+ 2.12666388511798828631e+02, /* 0x406A9553, 0x0E001365 */
+ -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */
+};
+
+#ifdef __STDC__
+ static double qzero(double x)
+#else
+ static double qzero(x)
+ double x;
+#endif
+{
+#ifdef __STDC__
+ const double *p,*q;
+#else
+ double *p,*q;
+#endif
+ double s,r,z,z2,z4,z6,r1,r2,r3,s1,s2,s3;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x40200000) {p = qR8; q= qS8;}
+ else if(ix>=0x40122E8B){p = qR5; q= qS5;}
+ else if(ix>=0x4006DB6D){p = qR3; q= qS3;}
+ else if(ix>=0x40000000){p = qR2; q= qS2;}
+ z = one/(x*x);
+#ifdef DO_NOT_USE_THIS
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+#else
+ r1 = p[0]+z*p[1]; z2=z*z;
+ r2 = p[2]+z*p[3]; z4=z2*z2;
+ r3 = p[4]+z*p[5]; z6=z4*z2;
+ r= r1 + z2*r2 + z4*r3;
+ s1 = one+z*q[0];
+ s2 = q[1]+z*q[2];
+ s3 = q[3]+z*q[4];
+ s = s1 + z2*s2 + z4*s3 +z6*q[5];
+#endif
+ return (-.125 + r/s)/x;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_j1.c b/libc/sysdeps/ieee754/dbl-64/e_j1.c
new file mode 100644
index 000000000..8a3b2ffd1
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_j1.c
@@ -0,0 +1,530 @@
+/* @(#)e_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.
+ * ====================================================
+ */
+/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/26,
+ for performance improvement on pipelined processors.
+*/
+
+#if defined(LIBM_SCCS) && !defined(lint)
+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)
+ * 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 - ...
+ * 2. Reduce x to |x| since j1(x)=-j1(-x), and
+ * for x in (0,2)
+ * j1(x) = x/2 + x*z*R0/S0, where z = x*x;
+ * (precision: |j1/x - 1/2 - R0/S0 |<2**-61.51 )
+ * for x in (2,inf)
+ * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1))
+ * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
+ * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
+ * as follow:
+ * cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = -1/sqrt(2) * (sin(x) + cos(x))
+ * (To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.)
+ *
+ * 3 Special cases
+ * j1(nan)= nan
+ * j1(0) = 0
+ * j1(inf) = 0
+ *
+ * Method -- y1(x):
+ * 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN
+ * 2. For x<2.
+ * Since
+ * y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...)
+ * therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function.
+ * We use the following function to approximate y1,
+ * y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2
+ * where for x in [0,2] (abs err less than 2**-65.89)
+ * U(z) = U0[0] + U0[1]*z + ... + U0[4]*z^4
+ * V(z) = 1 + v0[0]*z + ... + v0[4]*z^5
+ * Note: For tiny x, 1/x dominate y1 and hence
+ * y1(tiny) = -2/pi/tiny, (choose tiny<2**-54)
+ * 3. For x>=2.
+ * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
+ * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
+ * by method mentioned above.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static double pone(double), qone(double);
+#else
+static double pone(), qone();
+#endif
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+huge = 1e300,
+one = 1.0,
+invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+ /* R0/S0 on [0,2] */
+R[] = {-6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */
+ 1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */
+ -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */
+ 4.96727999609584448412e-08}, /* 0x3E6AAAFA, 0x46CA0BD9 */
+S[] = {0.0, 1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */
+ 1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */
+ 1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */
+ 5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */
+ 1.23542274426137913908e-11}; /* 0x3DAB2ACF, 0xCFB97ED8 */
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_j1(double x)
+#else
+ double __ieee754_j1(x)
+ double x;
+#endif
+{
+ double z, s,c,ss,cc,r,u,v,y,r1,r2,s1,s2,s3,z2,z4;
+ int32_t hx,ix;
+
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) return one/x;
+ y = fabs(x);
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ __sincos (y, &s, &c);
+ ss = -s-c;
+ cc = s-c;
+ if(ix<0x7fe00000) { /* make sure y+y not overflow */
+ z = __cos(y+y);
+ if ((s*c)>zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /*
+ * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
+ * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
+ */
+ if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrt(y);
+ else {
+ u = pone(y); v = qone(y);
+ z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrt(y);
+ }
+ if(hx<0) return -z;
+ else return z;
+ }
+ if(ix<0x3e400000) { /* |x|<2**-27 */
+ if(huge+x>one) return 0.5*x;/* inexact if x!=0 necessary */
+ }
+ z = x*x;
+#ifdef DO_NOT_USE_THIS
+ r = z*(r00+z*(r01+z*(r02+z*r03)));
+ s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
+ r *= x;
+#else
+ r1 = z*R[0]; z2=z*z;
+ r2 = R[1]+z*R[2]; z4=z2*z2;
+ r = r1 + z2*r2 + z4*R[3];
+ r *= x;
+ s1 = one+z*S[1];
+ s2 = S[2]+z*S[3];
+ s3 = S[4]+z*S[5];
+ s = s1 + z2*s2 + z4*s3;
+#endif
+ return(x*0.5+r/s);
+}
+
+#ifdef __STDC__
+static const double U0[5] = {
+#else
+static double U0[5] = {
+#endif
+ -1.96057090646238940668e-01, /* 0xBFC91866, 0x143CBC8A */
+ 5.04438716639811282616e-02, /* 0x3FA9D3C7, 0x76292CD1 */
+ -1.91256895875763547298e-03, /* 0xBF5F55E5, 0x4844F50F */
+ 2.35252600561610495928e-05, /* 0x3EF8AB03, 0x8FA6B88E */
+ -9.19099158039878874504e-08, /* 0xBE78AC00, 0x569105B8 */
+};
+#ifdef __STDC__
+static const double V0[5] = {
+#else
+static double V0[5] = {
+#endif
+ 1.99167318236649903973e-02, /* 0x3F94650D, 0x3F4DA9F0 */
+ 2.02552581025135171496e-04, /* 0x3F2A8C89, 0x6C257764 */
+ 1.35608801097516229404e-06, /* 0x3EB6C05A, 0x894E8CA6 */
+ 6.22741452364621501295e-09, /* 0x3E3ABF1D, 0x5BA69A86 */
+ 1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */
+};
+
+#ifdef __STDC__
+ double __ieee754_y1(double x)
+#else
+ double __ieee754_y1(x)
+ double x;
+#endif
+{
+ double z, s,c,ss,cc,u,v,u1,u2,v1,v2,v3,z2,z4;
+ int32_t hx,ix,lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+ ix = 0x7fffffff&hx;
+ /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
+ if(ix>=0x7ff00000) return one/(x+x*x);
+ if((ix|lx)==0) return -HUGE_VAL+x; /* -inf and overflow exception. */;
+ if(hx<0) return zero/(zero*x);
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ __sincos (x, &s, &c);
+ ss = -s-c;
+ cc = s-c;
+ if(ix<0x7fe00000) { /* make sure x+x not overflow */
+ z = __cos(x+x);
+ if ((s*c)>zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0))
+ * where x0 = x-3pi/4
+ * Better formula:
+ * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = -1/sqrt(2) * (cos(x) + sin(x))
+ * To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.
+ */
+ if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrt(x);
+ else {
+ u = pone(x); v = qone(x);
+ z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrt(x);
+ }
+ return z;
+ }
+ if(ix<=0x3c900000) { /* x < 2**-54 */
+ return(-tpi/x);
+ }
+ z = x*x;
+#ifdef DO_NOT_USE_THIS
+ 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]))));
+#else
+ u1 = U0[0]+z*U0[1];z2=z*z;
+ u2 = U0[2]+z*U0[3];z4=z2*z2;
+ u = u1 + z2*u2 + z4*U0[4];
+ v1 = one+z*V0[0];
+ v2 = V0[1]+z*V0[2];
+ v3 = V0[3]+z*V0[4];
+ v = v1 + z2*v2 + z4*v3;
+#endif
+ return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x));
+}
+
+/* For x >= 8, the asymptotic expansions of pone is
+ * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x.
+ * We approximate pone by
+ * pone(x) = 1 + (R/S)
+ * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10
+ * S = 1 + ps0*s^2 + ... + ps4*s^10
+ * and
+ * | pone(x)-1-R/S | <= 2 ** ( -60.06)
+ */
+
+#ifdef __STDC__
+static const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+ 1.17187499999988647970e-01, /* 0x3FBDFFFF, 0xFFFFFCCE */
+ 1.32394806593073575129e+01, /* 0x402A7A9D, 0x357F7FCE */
+ 4.12051854307378562225e+02, /* 0x4079C0D4, 0x652EA590 */
+ 3.87474538913960532227e+03, /* 0x40AE457D, 0xA3A532CC */
+ 7.91447954031891731574e+03, /* 0x40BEEA7A, 0xC32782DD */
+};
+#ifdef __STDC__
+static const double ps8[5] = {
+#else
+static double ps8[5] = {
+#endif
+ 1.14207370375678408436e+02, /* 0x405C8D45, 0x8E656CAC */
+ 3.65093083420853463394e+03, /* 0x40AC85DC, 0x964D274F */
+ 3.69562060269033463555e+04, /* 0x40E20B86, 0x97C5BB7F */
+ 9.76027935934950801311e+04, /* 0x40F7D42C, 0xB28F17BB */
+ 3.08042720627888811578e+04, /* 0x40DE1511, 0x697A0B2D */
+};
+
+#ifdef __STDC__
+static const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ 1.31990519556243522749e-11, /* 0x3DAD0667, 0xDAE1CA7D */
+ 1.17187493190614097638e-01, /* 0x3FBDFFFF, 0xE2C10043 */
+ 6.80275127868432871736e+00, /* 0x401B3604, 0x6E6315E3 */
+ 1.08308182990189109773e+02, /* 0x405B13B9, 0x452602ED */
+ 5.17636139533199752805e+02, /* 0x40802D16, 0xD052D649 */
+ 5.28715201363337541807e+02, /* 0x408085B8, 0xBB7E0CB7 */
+};
+#ifdef __STDC__
+static const double ps5[5] = {
+#else
+static double ps5[5] = {
+#endif
+ 5.92805987221131331921e+01, /* 0x404DA3EA, 0xA8AF633D */
+ 9.91401418733614377743e+02, /* 0x408EFB36, 0x1B066701 */
+ 5.35326695291487976647e+03, /* 0x40B4E944, 0x5706B6FB */
+ 7.84469031749551231769e+03, /* 0x40BEA4B0, 0xB8A5BB15 */
+ 1.50404688810361062679e+03, /* 0x40978030, 0x036F5E51 */
+};
+
+#ifdef __STDC__
+static const double pr3[6] = {
+#else
+static double pr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ 3.02503916137373618024e-09, /* 0x3E29FC21, 0xA7AD9EDD */
+ 1.17186865567253592491e-01, /* 0x3FBDFFF5, 0x5B21D17B */
+ 3.93297750033315640650e+00, /* 0x400F76BC, 0xE85EAD8A */
+ 3.51194035591636932736e+01, /* 0x40418F48, 0x9DA6D129 */
+ 9.10550110750781271918e+01, /* 0x4056C385, 0x4D2C1837 */
+ 4.85590685197364919645e+01, /* 0x4048478F, 0x8EA83EE5 */
+};
+#ifdef __STDC__
+static const double ps3[5] = {
+#else
+static double ps3[5] = {
+#endif
+ 3.47913095001251519989e+01, /* 0x40416549, 0xA134069C */
+ 3.36762458747825746741e+02, /* 0x40750C33, 0x07F1A75F */
+ 1.04687139975775130551e+03, /* 0x40905B7C, 0x5037D523 */
+ 8.90811346398256432622e+02, /* 0x408BD67D, 0xA32E31E9 */
+ 1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */
+};
+
+#ifdef __STDC__
+static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ 1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */
+ 1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */
+ 2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */
+ 1.22426109148261232917e+01, /* 0x40287C37, 0x7F71A964 */
+ 1.76939711271687727390e+01, /* 0x4031B1A8, 0x177F8EE2 */
+ 5.07352312588818499250e+00, /* 0x40144B49, 0xA574C1FE */
+};
+#ifdef __STDC__
+static const double ps2[5] = {
+#else
+static double ps2[5] = {
+#endif
+ 2.14364859363821409488e+01, /* 0x40356FBD, 0x8AD5ECDC */
+ 1.25290227168402751090e+02, /* 0x405F5293, 0x14F92CD5 */
+ 2.32276469057162813669e+02, /* 0x406D08D8, 0xD5A2DBD9 */
+ 1.17679373287147100768e+02, /* 0x405D6B7A, 0xDA1884A9 */
+ 8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */
+};
+
+#ifdef __STDC__
+ static double pone(double x)
+#else
+ static double pone(x)
+ double x;
+#endif
+{
+#ifdef __STDC__
+ const double *p,*q;
+#else
+ double *p,*q;
+#endif
+ double z,r,s,r1,r2,r3,s1,s2,s3,z2,z4;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x40200000) {p = pr8; q= ps8;}
+ else if(ix>=0x40122E8B){p = pr5; q= ps5;}
+ else if(ix>=0x4006DB6D){p = pr3; q= ps3;}
+ else if(ix>=0x40000000){p = pr2; q= ps2;}
+ z = one/(x*x);
+#ifdef DO_NOT_USE_THIS
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+#else
+ r1 = p[0]+z*p[1]; z2=z*z;
+ r2 = p[2]+z*p[3]; z4=z2*z2;
+ r3 = p[4]+z*p[5];
+ r = r1 + z2*r2 + z4*r3;
+ s1 = one+z*q[0];
+ s2 = q[1]+z*q[2];
+ s3 = q[3]+z*q[4];
+ s = s1 + z2*s2 + z4*s3;
+#endif
+ return one+ r/s;
+}
+
+
+/* For x >= 8, the asymptotic expansions of qone is
+ * 3/8 s - 105/1024 s^3 - ..., where s = 1/x.
+ * We approximate pone by
+ * qone(x) = s*(0.375 + (R/S))
+ * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10
+ * S = 1 + qs1*s^2 + ... + qs6*s^12
+ * and
+ * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13)
+ */
+
+#ifdef __STDC__
+static const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+ -1.02539062499992714161e-01, /* 0xBFBA3FFF, 0xFFFFFDF3 */
+ -1.62717534544589987888e+01, /* 0xC0304591, 0xA26779F7 */
+ -7.59601722513950107896e+02, /* 0xC087BCD0, 0x53E4B576 */
+ -1.18498066702429587167e+04, /* 0xC0C724E7, 0x40F87415 */
+ -4.84385124285750353010e+04, /* 0xC0E7A6D0, 0x65D09C6A */
+};
+#ifdef __STDC__
+static const double qs8[6] = {
+#else
+static double qs8[6] = {
+#endif
+ 1.61395369700722909556e+02, /* 0x40642CA6, 0xDE5BCDE5 */
+ 7.82538599923348465381e+03, /* 0x40BE9162, 0xD0D88419 */
+ 1.33875336287249578163e+05, /* 0x4100579A, 0xB0B75E98 */
+ 7.19657723683240939863e+05, /* 0x4125F653, 0x72869C19 */
+ 6.66601232617776375264e+05, /* 0x412457D2, 0x7719AD5C */
+ -2.94490264303834643215e+05, /* 0xC111F969, 0x0EA5AA18 */
+};
+
+#ifdef __STDC__
+static const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ -2.08979931141764104297e-11, /* 0xBDB6FA43, 0x1AA1A098 */
+ -1.02539050241375426231e-01, /* 0xBFBA3FFF, 0xCB597FEF */
+ -8.05644828123936029840e+00, /* 0xC0201CE6, 0xCA03AD4B */
+ -1.83669607474888380239e+02, /* 0xC066F56D, 0x6CA7B9B0 */
+ -1.37319376065508163265e+03, /* 0xC09574C6, 0x6931734F */
+ -2.61244440453215656817e+03, /* 0xC0A468E3, 0x88FDA79D */
+};
+#ifdef __STDC__
+static const double qs5[6] = {
+#else
+static double qs5[6] = {
+#endif
+ 8.12765501384335777857e+01, /* 0x405451B2, 0xFF5A11B2 */
+ 1.99179873460485964642e+03, /* 0x409F1F31, 0xE77BF839 */
+ 1.74684851924908907677e+04, /* 0x40D10F1F, 0x0D64CE29 */
+ 4.98514270910352279316e+04, /* 0x40E8576D, 0xAABAD197 */
+ 2.79480751638918118260e+04, /* 0x40DB4B04, 0xCF7C364B */
+ -4.71918354795128470869e+03, /* 0xC0B26F2E, 0xFCFFA004 */
+};
+
+#ifdef __STDC__
+static const double qr3[6] = {
+#else
+static double qr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ -5.07831226461766561369e-09, /* 0xBE35CFA9, 0xD38FC84F */
+ -1.02537829820837089745e-01, /* 0xBFBA3FEB, 0x51AEED54 */
+ -4.61011581139473403113e+00, /* 0xC01270C2, 0x3302D9FF */
+ -5.78472216562783643212e+01, /* 0xC04CEC71, 0xC25D16DA */
+ -2.28244540737631695038e+02, /* 0xC06C87D3, 0x4718D55F */
+ -2.19210128478909325622e+02, /* 0xC06B66B9, 0x5F5C1BF6 */
+};
+#ifdef __STDC__
+static const double qs3[6] = {
+#else
+static double qs3[6] = {
+#endif
+ 4.76651550323729509273e+01, /* 0x4047D523, 0xCCD367E4 */
+ 6.73865112676699709482e+02, /* 0x40850EEB, 0xC031EE3E */
+ 3.38015286679526343505e+03, /* 0x40AA684E, 0x448E7C9A */
+ 5.54772909720722782367e+03, /* 0x40B5ABBA, 0xA61D54A6 */
+ 1.90311919338810798763e+03, /* 0x409DBC7A, 0x0DD4DF4B */
+ -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */
+};
+
+#ifdef __STDC__
+static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */
+ -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */
+ -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */
+ -1.96636162643703720221e+01, /* 0xC033A9E2, 0xC168907F */
+ -4.23253133372830490089e+01, /* 0xC04529A3, 0xDE104AAA */
+ -2.13719211703704061733e+01, /* 0xC0355F36, 0x39CF6E52 */
+};
+#ifdef __STDC__
+static const double qs2[6] = {
+#else
+static double qs2[6] = {
+#endif
+ 2.95333629060523854548e+01, /* 0x403D888A, 0x78AE64FF */
+ 2.52981549982190529136e+02, /* 0x406F9F68, 0xDB821CBA */
+ 7.57502834868645436472e+02, /* 0x4087AC05, 0xCE49A0F7 */
+ 7.39393205320467245656e+02, /* 0x40871B25, 0x48D4C029 */
+ 1.55949003336666123687e+02, /* 0x40637E5E, 0x3C3ED8D4 */
+ -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */
+};
+
+#ifdef __STDC__
+ static double qone(double x)
+#else
+ static double qone(x)
+ double x;
+#endif
+{
+#ifdef __STDC__
+ const double *p,*q;
+#else
+ double *p,*q;
+#endif
+ double s,r,z,r1,r2,r3,s1,s2,s3,z2,z4,z6;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x40200000) {p = qr8; q= qs8;}
+ else if(ix>=0x40122E8B){p = qr5; q= qs5;}
+ else if(ix>=0x4006DB6D){p = qr3; q= qs3;}
+ else if(ix>=0x40000000){p = qr2; q= qs2;}
+ z = one/(x*x);
+#ifdef DO_NOT_USE_THIS
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+#else
+ r1 = p[0]+z*p[1]; z2=z*z;
+ r2 = p[2]+z*p[3]; z4=z2*z2;
+ r3 = p[4]+z*p[5]; z6=z4*z2;
+ r = r1 + z2*r2 + z4*r3;
+ s1 = one+z*q[0];
+ s2 = q[1]+z*q[2];
+ s3 = q[3]+z*q[4];
+ s = s1 + z2*s2 + z4*s3 + z6*q[5];
+#endif
+ return (.375 + r/s)/x;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_jn.c b/libc/sysdeps/ieee754/dbl-64/e_jn.c
new file mode 100644
index 000000000..bf4a13d97
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_jn.c
@@ -0,0 +1,287 @@
+/* @(#)e_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: e_jn.c,v 1.9 1995/05/10 20:45:34 jtc Exp $";
+#endif
+
+/*
+ * __ieee754_jn(n, x), __ieee754_yn(n, 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 overflow 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"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
+one = 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */
+
+#ifdef __STDC__
+static const double zero = 0.00000000000000000000e+00;
+#else
+static double zero = 0.00000000000000000000e+00;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_jn(int n, double x)
+#else
+ double __ieee754_jn(n,x)
+ int n; double x;
+#endif
+{
+ int32_t i,hx,ix,lx, sgn;
+ double a, b, temp, di;
+ double z, w;
+
+ /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
+ * Thus, J(-n,x) = J(n,-x)
+ */
+ EXTRACT_WORDS(hx,lx,x);
+ ix = 0x7fffffff&hx;
+ /* if J(n,NaN) is NaN */
+ if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x;
+ if(n<0){
+ n = -n;
+ x = -x;
+ hx ^= 0x80000000;
+ }
+ if(n==0) return(__ieee754_j0(x));
+ if(n==1) return(__ieee754_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 */
+ b = zero;
+ else if((double)n<=x) {
+ /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
+ if(ix>=0x52D00000) { /* x > 2**302 */
+ /* (x >> n**2)
+ * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Let s=sin(x), c=cos(x),
+ * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+ *
+ * n sin(xn)*sqt2 cos(xn)*sqt2
+ * ----------------------------------
+ * 0 s-c c+s
+ * 1 -s-c -c+s
+ * 2 -s+c -c-s
+ * 3 s+c c-s
+ */
+ double s;
+ double c;
+ __sincos (x, &s, &c);
+ switch(n&3) {
+ case 0: temp = c + s; break;
+ case 1: temp = -c + s; break;
+ case 2: temp = -c - s; break;
+ case 3: temp = c - s; break;
+ }
+ b = invsqrtpi*temp/__ieee754_sqrt(x);
+ } else {
+ a = __ieee754_j0(x);
+ b = __ieee754_j1(x);
+ for(i=1;i<n;i++){
+ temp = b;
+ b = b*((double)(i+i)/x) - a; /* avoid underflow */
+ a = temp;
+ }
+ }
+ } else {
+ if(ix<0x3e100000) { /* x < 2**-29 */
+ /* x is tiny, return the first Taylor expansion of J(n,x)
+ * J(n,x) = 1/n!*(x/2)^n - ...
+ */
+ if(n>33) /* underflow */
+ b = zero;
+ else {
+ temp = x*0.5; b = temp;
+ for (a=one,i=2;i<=n;i++) {
+ a *= (double)i; /* a = n! */
+ b *= temp; /* b = (x/2)^n */
+ }
+ b = b/a;
+ }
+ } else {
+ /* use backward recurrence */
+ /* x x^2 x^2
+ * J(n,x)/J(n-1,x) = ---- ------ ------ .....
+ * 2n - 2(n+1) - 2(n+2)
+ *
+ * 1 1 1
+ * (for large x) = ---- ------ ------ .....
+ * 2n 2(n+1) 2(n+2)
+ * -- - ------ - ------ -
+ * x x x
+ *
+ * Let w = 2n/x and h=2/x, then the above quotient
+ * is equal to the continued fraction:
+ * 1
+ * = -----------------------
+ * 1
+ * w - -----------------
+ * 1
+ * w+h - ---------
+ * w+2h - ...
+ *
+ * To determine how many terms needed, let
+ * Q(0) = w, Q(1) = w(w+h) - 1,
+ * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
+ * When Q(k) > 1e4 good for single
+ * When Q(k) > 1e9 good for double
+ * When Q(k) > 1e17 good for quadruple
+ */
+ /* determine k */
+ double t,v;
+ double q0,q1,h,tmp; int32_t k,m;
+ w = (n+n)/(double)x; h = 2.0/(double)x;
+ q0 = w; z = w+h; q1 = w*z - 1.0; k=1;
+ while(q1<1.0e9) {
+ k += 1; z += h;
+ tmp = z*q1 - q0;
+ q0 = q1;
+ q1 = tmp;
+ }
+ m = n+n;
+ for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t);
+ a = t;
+ b = one;
+ /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
+ * Hence, if n*(log(2n/x)) > ...
+ * single 8.8722839355e+01
+ * double 7.09782712893383973096e+02
+ * long double 1.1356523406294143949491931077970765006170e+04
+ * then recurrent value may overflow and the result is
+ * likely underflow to zero
+ */
+ tmp = n;
+ v = two/x;
+ tmp = tmp*__ieee754_log(fabs(v*tmp));
+ if(tmp<7.09782712893383973096e+02) {
+ for(i=n-1,di=(double)(i+i);i>0;i--){
+ temp = b;
+ b *= di;
+ b = b/x - a;
+ a = temp;
+ di -= two;
+ }
+ } else {
+ for(i=n-1,di=(double)(i+i);i>0;i--){
+ temp = b;
+ b *= di;
+ b = b/x - a;
+ a = temp;
+ di -= two;
+ /* scale b to avoid spurious overflow */
+ if(b>1e100) {
+ a /= b;
+ t /= b;
+ b = one;
+ }
+ }
+ }
+ b = (t*__ieee754_j0(x)/b);
+ }
+ }
+ if(sgn==1) return -b; else return b;
+}
+
+#ifdef __STDC__
+ double __ieee754_yn(int n, double x)
+#else
+ double __ieee754_yn(n,x)
+ int n; double x;
+#endif
+{
+ int32_t i,hx,ix,lx;
+ int32_t sign;
+ double a, b, temp;
+
+ EXTRACT_WORDS(hx,lx,x);
+ ix = 0x7fffffff&hx;
+ /* if Y(n,NaN) is NaN */
+ if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x;
+ if((ix|lx)==0) return -HUGE_VAL+x; /* -inf and overflow exception. */;
+ if(hx<0) return zero/(zero*x);
+ sign = 1;
+ if(n<0){
+ n = -n;
+ sign = 1 - ((n&1)<<1);
+ }
+ if(n==0) return(__ieee754_y0(x));
+ if(n==1) return(sign*__ieee754_y1(x));
+ if(ix==0x7ff00000) return zero;
+ if(ix>=0x52D00000) { /* x > 2**302 */
+ /* (x >> n**2)
+ * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Let s=sin(x), c=cos(x),
+ * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+ *
+ * n sin(xn)*sqt2 cos(xn)*sqt2
+ * ----------------------------------
+ * 0 s-c c+s
+ * 1 -s-c -c+s
+ * 2 -s+c -c-s
+ * 3 s+c c-s
+ */
+ double c;
+ double s;
+ __sincos (x, &s, &c);
+ switch(n&3) {
+ case 0: temp = s - c; break;
+ case 1: temp = -s - c; break;
+ case 2: temp = -s + c; break;
+ case 3: temp = s + c; break;
+ }
+ b = invsqrtpi*temp/__ieee754_sqrt(x);
+ } else {
+ u_int32_t high;
+ a = __ieee754_y0(x);
+ b = __ieee754_y1(x);
+ /* quit if b is -inf */
+ GET_HIGH_WORD(high,b);
+ for(i=1;i<n&&high!=0xfff00000;i++){
+ temp = b;
+ b = ((double)(i+i)/x)*b - a;
+ GET_HIGH_WORD(high,b);
+ a = temp;
+ }
+ }
+ if(sign>0) return b; else return -b;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_lgamma_r.c b/libc/sysdeps/ieee754/dbl-64/e_lgamma_r.c
new file mode 100644
index 000000000..cc44b048f
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_lgamma_r.c
@@ -0,0 +1,312 @@
+/* @(#)er_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: e_lgamma_r.c,v 1.7 1995/05/10 20:45:42 jtc Exp $";
+#endif
+
+/* __ieee754_lgamma_r(x, signgamp)
+ * Reentrant version of the logarithm of the Gamma function
+ * with user provide pointer for the sign of Gamma(x).
+ *
+ * Method:
+ * 1. Argument Reduction for 0 < x <= 8
+ * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may
+ * reduce x to a number in [1.5,2.5] by
+ * lgamma(1+s) = log(s) + lgamma(s)
+ * for example,
+ * lgamma(7.3) = log(6.3) + lgamma(6.3)
+ * = log(6.3*5.3) + lgamma(5.3)
+ * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
+ * 2. Polynomial approximation of lgamma around its
+ * minimun ymin=1.461632144968362245 to maintain monotonicity.
+ * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
+ * Let z = x-ymin;
+ * lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
+ * where
+ * poly(z) is a 14 degree polynomial.
+ * 2. Rational approximation in the primary interval [2,3]
+ * We use the following approximation:
+ * s = x-2.0;
+ * lgamma(x) = 0.5*s + s*P(s)/Q(s)
+ * with accuracy
+ * |P/Q - (lgamma(x)-0.5s)| < 2**-61.71
+ * Our algorithms are based on the following observation
+ *
+ * zeta(2)-1 2 zeta(3)-1 3
+ * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ...
+ * 2 3
+ *
+ * where Euler = 0.5771... is the Euler constant, which is very
+ * close to 0.5.
+ *
+ * 3. For x>=8, we have
+ * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....
+ * (better formula:
+ * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)
+ * Let z = 1/x, then we approximation
+ * f(z) = lgamma(x) - (x-0.5)(log(x)-1)
+ * by
+ * 3 5 11
+ * w = w0 + w1*z + w2*z + w3*z + ... + w6*z
+ * where
+ * |w - f(z)| < 2**-58.74
+ *
+ * 4. For negative x, since (G is gamma function)
+ * -x*G(-x)*G(x) = pi/sin(pi*x),
+ * we have
+ * G(x) = pi/(sin(pi*x)*(-x)*G(-x))
+ * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0
+ * Hence, for x<0, signgam = sign(sin(pi*x)) and
+ * lgamma(x) = log(|Gamma(x)|)
+ * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);
+ * Note: one should avoid compute pi*(-x) directly in the
+ * computation of sin(pi*(-x)).
+ *
+ * 5. Special Cases
+ * lgamma(2+s) ~ s*(1-Euler) for tiny s
+ * lgamma(1)=lgamma(2)=0
+ * lgamma(x) ~ -log(x) for tiny x
+ * lgamma(0) = lgamma(inf) = inf
+ * lgamma(-integer) = +-inf
+ *
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two52= 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
+a0 = 7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */
+a1 = 3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */
+a2 = 6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */
+a3 = 2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */
+a4 = 7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */
+a5 = 2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */
+a6 = 1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */
+a7 = 5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */
+a8 = 2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */
+a9 = 1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */
+a10 = 2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */
+a11 = 4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */
+tc = 1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */
+tf = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */
+/* tt = -(tail of tf) */
+tt = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */
+t0 = 4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */
+t1 = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */
+t2 = 6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */
+t3 = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */
+t4 = 1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */
+t5 = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */
+t6 = 6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */
+t7 = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */
+t8 = 2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */
+t9 = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */
+t10 = 8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */
+t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */
+t12 = 3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */
+t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */
+t14 = 3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */
+u0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
+u1 = 6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */
+u2 = 1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */
+u3 = 9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */
+u4 = 2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */
+u5 = 1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */
+v1 = 2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */
+v2 = 2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */
+v3 = 7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */
+v4 = 1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */
+v5 = 3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */
+s0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
+s1 = 2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */
+s2 = 3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */
+s3 = 1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */
+s4 = 2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */
+s5 = 1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */
+s6 = 3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */
+r1 = 1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */
+r2 = 7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */
+r3 = 1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */
+r4 = 1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */
+r5 = 7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */
+r6 = 7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */
+w0 = 4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */
+w1 = 8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */
+w2 = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */
+w3 = 7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */
+w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */
+w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */
+w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */
+
+#ifdef __STDC__
+static const double zero= 0.00000000000000000000e+00;
+#else
+static double zero= 0.00000000000000000000e+00;
+#endif
+
+#ifdef __STDC__
+ static double sin_pi(double x)
+#else
+ static double sin_pi(x)
+ double x;
+#endif
+{
+ double y,z;
+ int n,ix;
+
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff;
+
+ if(ix<0x3fd00000) return __sin(pi*x);
+ y = -x; /* x is assume negative */
+
+ /*
+ * argument reduction, make sure inexact flag not raised if input
+ * is an integer
+ */
+ z = __floor(y);
+ if(z!=y) { /* inexact anyway */
+ y *= 0.5;
+ y = 2.0*(y - __floor(y)); /* y = |x| mod 2.0 */
+ n = (int) (y*4.0);
+ } else {
+ if(ix>=0x43400000) {
+ y = zero; n = 0; /* y must be even */
+ } else {
+ if(ix<0x43300000) z = y+two52; /* exact */
+ GET_LOW_WORD(n,z);
+ n &= 1;
+ y = n;
+ n<<= 2;
+ }
+ }
+ switch (n) {
+ case 0: y = __sin(pi*y); break;
+ case 1:
+ case 2: y = __cos(pi*(0.5-y)); break;
+ case 3:
+ case 4: y = __sin(pi*(one-y)); break;
+ case 5:
+ case 6: y = -__cos(pi*(y-1.5)); break;
+ default: y = __sin(pi*(y-2.0)); break;
+ }
+ return -y;
+}
+
+
+#ifdef __STDC__
+ double __ieee754_lgamma_r(double x, int *signgamp)
+#else
+ double __ieee754_lgamma_r(x,signgamp)
+ double x; int *signgamp;
+#endif
+{
+ double t,y,z,nadj,p,p1,p2,p3,q,r,w;
+ int i,hx,lx,ix;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ /* purge off +-inf, NaN, +-0, and negative arguments */
+ *signgamp = 1;
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) return x*x;
+ if((ix|lx)==0) return one/fabs(x);
+ if(ix<0x3b900000) { /* |x|<2**-70, return -log(|x|) */
+ if(hx<0) {
+ *signgamp = -1;
+ return -__ieee754_log(-x);
+ } else return -__ieee754_log(x);
+ }
+ if(hx<0) {
+ if(ix>=0x43300000) /* |x|>=2**52, must be -integer */
+ return x/zero;
+ t = sin_pi(x);
+ if(t==zero) return one/fabsf(t); /* -integer */
+ nadj = __ieee754_log(pi/fabs(t*x));
+ if(t<zero) *signgamp = -1;
+ x = -x;
+ }
+
+ /* purge off 1 and 2 */
+ if((((ix-0x3ff00000)|lx)==0)||(((ix-0x40000000)|lx)==0)) r = 0;
+ /* for x < 2.0 */
+ else if(ix<0x40000000) {
+ if(ix<=0x3feccccc) { /* lgamma(x) = lgamma(x+1)-log(x) */
+ r = -__ieee754_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;}
+ } else {
+ r = zero;
+ if(ix>=0x3FFBB4C3) {y=2.0-x;i=0;} /* [1.7316,2] */
+ else if(ix>=0x3FF3B4C4) {y=x-tc;i=1;} /* [1.23,1.73] */
+ else {y=x-one;i=2;}
+ }
+ switch(i) {
+ case 0:
+ z = y*y;
+ p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
+ p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
+ p = y*p1+p2;
+ r += (p-0.5*y); break;
+ case 1:
+ z = y*y;
+ w = z*y;
+ p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */
+ p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
+ p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
+ p = z*p1-(tt-w*(p2+y*p3));
+ r += (tf + p); break;
+ case 2:
+ p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
+ p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
+ r += (-0.5*y + p1/p2);
+ }
+ }
+ else if(ix<0x40200000) { /* x < 8.0 */
+ i = (int)x;
+ t = zero;
+ y = x-(double)i;
+ p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
+ q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
+ r = half*y+p/q;
+ z = one; /* lgamma(1+s) = log(s) + lgamma(s) */
+ switch(i) {
+ case 7: z *= (y+6.0); /* FALLTHRU */
+ case 6: z *= (y+5.0); /* FALLTHRU */
+ 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;
+ }
+ /* 8.0 <= x < 2**58 */
+ } else if (ix < 0x43900000) {
+ t = __ieee754_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);
+ if(hx<0) r = nadj - r;
+ return r;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_log.c b/libc/sysdeps/ieee754/dbl-64/e_log.c
new file mode 100644
index 000000000..1a9967b54
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_log.c
@@ -0,0 +1,203 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*********************************************************************/
+/* */
+/* MODULE_NAME:ulog.c */
+/* */
+/* FUNCTION:ulog */
+/* */
+/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h ulog.h */
+/* mpexp.c mplog.c mpa.c */
+/* ulog.tbl */
+/* */
+/* An ultimate log routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of log(x). */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round to nearest mode of IEEE 754 standard. */
+/* */
+/*********************************************************************/
+
+
+#include "endian.h"
+#include "dla.h"
+#include "mpa.h"
+#include "MathLib.h"
+#include "math_private.h"
+
+void __mplog(mp_no *, mp_no *, int);
+
+/*********************************************************************/
+/* An ultimate log routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of log(x). */
+/*********************************************************************/
+double __ieee754_log(double x) {
+#define M 4
+ static const int pr[M]={8,10,18,32};
+ int i,j,n,ux,dx,p;
+#if 0
+ int k;
+#endif
+ double dbl_n,u,p0,q,r0,w,nln2a,luai,lubi,lvaj,lvbj,
+ sij,ssij,ttij,A,B,B0,y,y1,y2,polI,polII,sa,sb,
+ t1,t2,t3,t4,t5,t6,t7,t8,t,ra,rb,ww,
+ a0,aa0,s1,s2,ss2,s3,ss3,a1,aa1,a,aa,b,bb,c;
+ number num;
+ mp_no mpx,mpy,mpy1,mpy2,mperr;
+
+#include "ulog.tbl"
+#include "ulog.h"
+
+ /* Treating special values of x ( x<=0, x=INF, x=NaN etc.). */
+
+ num.d = x; ux = num.i[HIGH_HALF]; dx = num.i[LOW_HALF];
+ n=0;
+ if (ux < 0x00100000) {
+ if (((ux & 0x7fffffff) | dx) == 0) return MHALF/ZERO; /* return -INF */
+ if (ux < 0) return (x-x)/ZERO; /* return NaN */
+ n -= 54; x *= two54.d; /* scale x */
+ num.d = x;
+ }
+ if (ux >= 0x7ff00000) return x+x; /* INF or NaN */
+
+ /* Regular values of x */
+
+ w = x-ONE;
+ if (ABS(w) > U03) { goto case_03; }
+
+
+ /*--- Stage I, the case abs(x-1) < 0.03 */
+
+ t8 = MHALF*w;
+ EMULV(t8,w,a,aa,t1,t2,t3,t4,t5)
+ EADD(w,a,b,bb)
+
+ /* Evaluate polynomial II */
+ polII = (b0.d+w*(b1.d+w*(b2.d+w*(b3.d+w*(b4.d+
+ w*(b5.d+w*(b6.d+w*(b7.d+w*b8.d))))))))*w*w*w;
+ c = (aa+bb)+polII;
+
+ /* End stage I, case abs(x-1) < 0.03 */
+ if ((y=b+(c+b*E2)) == b+(c-b*E2)) return y;
+
+ /*--- Stage II, the case abs(x-1) < 0.03 */
+
+ a = d11.d+w*(d12.d+w*(d13.d+w*(d14.d+w*(d15.d+w*(d16.d+
+ w*(d17.d+w*(d18.d+w*(d19.d+w*d20.d))))))));
+ EMULV(w,a,s2,ss2,t1,t2,t3,t4,t5)
+ ADD2(d10.d,dd10.d,s2,ss2,s3,ss3,t1,t2)
+ MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(d9.d,dd9.d,s2,ss2,s3,ss3,t1,t2)
+ MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(d8.d,dd8.d,s2,ss2,s3,ss3,t1,t2)
+ MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(d7.d,dd7.d,s2,ss2,s3,ss3,t1,t2)
+ MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(d6.d,dd6.d,s2,ss2,s3,ss3,t1,t2)
+ MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(d5.d,dd5.d,s2,ss2,s3,ss3,t1,t2)
+ MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(d4.d,dd4.d,s2,ss2,s3,ss3,t1,t2)
+ MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(d3.d,dd3.d,s2,ss2,s3,ss3,t1,t2)
+ MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(d2.d,dd2.d,s2,ss2,s3,ss3,t1,t2)
+ MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(w,ZERO,s2,ss2,s3,ss3,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(w,ZERO, s3,ss3, b, bb,t1,t2)
+
+ /* End stage II, case abs(x-1) < 0.03 */
+ if ((y=b+(bb+b*E4)) == b+(bb-b*E4)) return y;
+ goto stage_n;
+
+ /*--- Stage I, the case abs(x-1) > 0.03 */
+ case_03:
+
+ /* Find n,u such that x = u*2**n, 1/sqrt(2) < u < sqrt(2) */
+ n += (num.i[HIGH_HALF] >> 20) - 1023;
+ num.i[HIGH_HALF] = (num.i[HIGH_HALF] & 0x000fffff) | 0x3ff00000;
+ if (num.d > SQRT_2) { num.d *= HALF; n++; }
+ u = num.d; dbl_n = (double) n;
+
+ /* Find i such that ui=1+(i-75)/2**8 is closest to u (i= 0,1,2,...,181) */
+ num.d += h1.d;
+ i = (num.i[HIGH_HALF] & 0x000fffff) >> 12;
+
+ /* Find j such that vj=1+(j-180)/2**16 is closest to v=u/ui (j= 0,...,361) */
+ num.d = u*Iu[i].d + h2.d;
+ j = (num.i[HIGH_HALF] & 0x000fffff) >> 4;
+
+ /* Compute w=(u-ui*vj)/(ui*vj) */
+ p0=(ONE+(i-75)*DEL_U)*(ONE+(j-180)*DEL_V);
+ q=u-p0; r0=Iu[i].d*Iv[j].d; w=q*r0;
+
+ /* Evaluate polynomial I */
+ polI = w+(a2.d+a3.d*w)*w*w;
+
+ /* Add up everything */
+ nln2a = dbl_n*LN2A;
+ luai = Lu[i][0].d; lubi = Lu[i][1].d;
+ lvaj = Lv[j][0].d; lvbj = Lv[j][1].d;
+ EADD(luai,lvaj,sij,ssij)
+ EADD(nln2a,sij,A ,ttij)
+ B0 = (((lubi+lvbj)+ssij)+ttij)+dbl_n*LN2B;
+ B = polI+B0;
+
+ /* End stage I, case abs(x-1) >= 0.03 */
+ if ((y=A+(B+E1)) == A+(B-E1)) return y;
+
+
+ /*--- Stage II, the case abs(x-1) > 0.03 */
+
+ /* Improve the accuracy of r0 */
+ EMULV(p0,r0,sa,sb,t1,t2,t3,t4,t5)
+ t=r0*((ONE-sa)-sb);
+ EADD(r0,t,ra,rb)
+
+ /* Compute w */
+ MUL2(q,ZERO,ra,rb,w,ww,t1,t2,t3,t4,t5,t6,t7,t8)
+
+ EADD(A,B0,a0,aa0)
+
+ /* Evaluate polynomial III */
+ s1 = (c3.d+(c4.d+c5.d*w)*w)*w;
+ EADD(c2.d,s1,s2,ss2)
+ MUL2(s2,ss2,w,ww,s3,ss3,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(s3,ss3,w,ww,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(s2,ss2,w,ww,s3,ss3,t1,t2)
+ ADD2(s3,ss3,a0,aa0,a1,aa1,t1,t2)
+
+ /* End stage II, case abs(x-1) >= 0.03 */
+ if ((y=a1+(aa1+E3)) == a1+(aa1-E3)) return y;
+
+
+ /* Final stages. Use multi-precision arithmetic. */
+ stage_n:
+
+ for (i=0; i<M; i++) {
+ p = pr[i];
+ __dbl_mp(x,&mpx,p); __dbl_mp(y,&mpy,p);
+ __mplog(&mpx,&mpy,p);
+ __dbl_mp(e[i].d,&mperr,p);
+ __add(&mpy,&mperr,&mpy1,p); __sub(&mpy,&mperr,&mpy2,p);
+ __mp_dbl(&mpy1,&y1,p); __mp_dbl(&mpy2,&y2,p);
+ if (y1==y2) return y1;
+ }
+ return y1;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_log10.c b/libc/sysdeps/ieee754/dbl-64/e_log10.c
new file mode 100644
index 000000000..e8a3278ea
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_log10.c
@@ -0,0 +1,98 @@
+/* @(#)e_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: e_log10.c,v 1.9 1995/05/10 20:45:51 jtc Exp $";
+#endif
+
+/* __ieee754_log10(x)
+ * Return the base 10 logarithm of x
+ *
+ * Method :
+ * Let log10_2hi = leading 40 bits of log10(2) and
+ * log10_2lo = log10(2) - log10_2hi,
+ * ivln10 = 1/log(10) rounded.
+ * Then
+ * n = ilogb(x),
+ * if(n<0) n = n+1;
+ * x = scalbn(x,-n);
+ * log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x))
+ *
+ * Note 1:
+ * To guarantee log10(10**n)=n, where 10**n is normal, the rounding
+ * mode must set to Round-to-Nearest.
+ * Note 2:
+ * [1/log(10)] rounded to 53 bits has error .198 ulps;
+ * log10 is monotonic at all binary break points.
+ *
+ * Special cases:
+ * log10(x) is NaN with signal if x < 0;
+ * log10(+INF) is +INF with no signal; log10(0) is -INF with signal;
+ * log10(NaN) is that NaN with no signal;
+ * log10(10**N) = N for N=0,1,...,22.
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+ivln10 = 4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */
+log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
+log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_log10(double x)
+#else
+ double __ieee754_log10(x)
+ double x;
+#endif
+{
+ double y,z;
+ int32_t i,k,hx;
+ u_int32_t lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ k=0;
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+ if (((hx&0x7fffffff)|lx)==0)
+ return -two54/(x-x); /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/(x-x); /* 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;
+ i = ((u_int32_t)k&0x80000000)>>31;
+ hx = (hx&0x000fffff)|((0x3ff-i)<<20);
+ y = (double)(k+i);
+ SET_HIGH_WORD(x,hx);
+ z = y*log10_2lo + ivln10*__ieee754_log(x);
+ return z+y*log10_2hi;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_log2.c b/libc/sysdeps/ieee754/dbl-64/e_log2.c
new file mode 100644
index 000000000..f05d0ce96
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_log2.c
@@ -0,0 +1,130 @@
+/* Adapted for log2 by Ulrich Drepper <drepper@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.
+ * ====================================================
+ */
+
+/* __ieee754_log2(x)
+ * Return the logarithm to base 2 of x
+ *
+ * Method :
+ * 1. Argument Reduction: find k and f such that
+ * x = 2^k * (1+f),
+ * where sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ * 2. Approximation of log(1+f).
+ * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ * = 2s + s*R
+ * We use a special Reme algorithm on [0,0.1716] to generate
+ * a polynomial of degree 14 to approximate R The maximum error
+ * of this polynomial approximation is bounded by 2**-58.45. In
+ * other words,
+ * 2 4 6 8 10 12 14
+ * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s
+ * (the values of Lg1 to Lg7 are listed in the program)
+ * and
+ * | 2 14 | -58.45
+ * | Lg1*s +...+Lg7*s - R(z) | <= 2
+ * | |
+ * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ * In order to guarantee error in log below 1ulp, we compute log
+ * by
+ * log(1+f) = f - s*(f - R) (if f is not too large)
+ * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
+ *
+ * 3. Finally, log(x) = k + log(1+f).
+ * = k+(f-(hfsq-(s*(hfsq+R))))
+ *
+ * Special cases:
+ * log2(x) is NaN with signal if x < 0 (including -INF) ;
+ * log2(+INF) is +INF; log(0) is -INF with signal;
+ * log2(NaN) is that NaN with no signal.
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+ln2 = 0.69314718055994530942,
+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 */
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_log2(double x)
+#else
+ double __ieee754_log2(x)
+ double x;
+#endif
+{
+ 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/(x-x); /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/(x-x); /* 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);
+ dk = (double) k;
+ f = x-1.0;
+ 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/libc/sysdeps/ieee754/dbl-64/e_pow.c b/libc/sysdeps/ieee754/dbl-64/e_pow.c
new file mode 100644
index 000000000..d9bd8b479
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_pow.c
@@ -0,0 +1,388 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001, 2002, 2004 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/***************************************************************************/
+/* MODULE_NAME: upow.c */
+/* */
+/* FUNCTIONS: upow */
+/* power1 */
+/* my_log2 */
+/* log1 */
+/* checkint */
+/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h */
+/* halfulp.c mpexp.c mplog.c slowexp.c slowpow.c mpa.c */
+/* uexp.c upow.c */
+/* root.tbl uexp.tbl upow.tbl */
+/* An ultimate power routine. Given two IEEE double machine numbers y,x */
+/* it computes the correctly rounded (to nearest) value of x^y. */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round to nearest mode of IEEE 754 standard. */
+/* */
+/***************************************************************************/
+#include "endian.h"
+#include "upow.h"
+#include "dla.h"
+#include "mydefs.h"
+#include "MathLib.h"
+#include "upow.tbl"
+#include "math_private.h"
+
+
+double __exp1(double x, double xx, double error);
+static double log1(double x, double *delta, double *error);
+static double my_log2(double x, double *delta, double *error);
+double __slowpow(double x, double y,double z);
+static double power1(double x, double y);
+static int checkint(double x);
+
+/***************************************************************************/
+/* An ultimate power routine. Given two IEEE double machine numbers y,x */
+/* it computes the correctly rounded (to nearest) value of X^y. */
+/***************************************************************************/
+double __ieee754_pow(double x, double y) {
+ double z,a,aa,error, t,a1,a2,y1,y2;
+#if 0
+ double gor=1.0;
+#endif
+ mynumber u,v;
+ int k;
+ int4 qx,qy;
+ v.x=y;
+ u.x=x;
+ if (v.i[LOW_HALF] == 0) { /* of y */
+ qx = u.i[HIGH_HALF]&0x7fffffff;
+ /* Checking if x is not too small to compute */
+ if (((qx==0x7ff00000)&&(u.i[LOW_HALF]!=0))||(qx>0x7ff00000)) return NaNQ.x;
+ if (y == 1.0) return x;
+ if (y == 2.0) return x*x;
+ if (y == -1.0) return 1.0/x;
+ if (y == 0) return 1.0;
+ }
+ /* else */
+ if(((u.i[HIGH_HALF]>0 && u.i[HIGH_HALF]<0x7ff00000)|| /* x>0 and not x->0 */
+ (u.i[HIGH_HALF]==0 && u.i[LOW_HALF]!=0)) &&
+ /* 2^-1023< x<= 2^-1023 * 0x1.0000ffffffff */
+ (v.i[HIGH_HALF]&0x7fffffff) < 0x4ff00000) { /* if y<-1 or y>1 */
+ z = log1(x,&aa,&error); /* x^y =e^(y log (X)) */
+ t = y*134217729.0;
+ y1 = t - (t-y);
+ y2 = y - y1;
+ t = z*134217729.0;
+ a1 = t - (t-z);
+ a2 = (z - a1)+aa;
+ a = y1*a1;
+ aa = y2*a1 + y*a2;
+ a1 = a+aa;
+ a2 = (a-a1)+aa;
+ error = error*ABS(y);
+ t = __exp1(a1,a2,1.9e16*error); /* return -10 or 0 if wasn't computed exactly */
+ return (t>0)?t:power1(x,y);
+ }
+
+ if (x == 0) {
+ if (((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] != 0)
+ || (v.i[HIGH_HALF] & 0x7fffffff) > 0x7ff00000)
+ return y;
+ if (ABS(y) > 1.0e20) return (y>0)?0:INF.x;
+ k = checkint(y);
+ if (k == -1)
+ return y < 0 ? 1.0/x : x;
+ else
+ return y < 0 ? 1.0/ABS(x) : 0.0; /* return 0 */
+ }
+ /* if x<0 */
+ if (u.i[HIGH_HALF] < 0) {
+ k = checkint(y);
+ if (k==0) {
+ if ((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] == 0) {
+ if (x == -1.0) return 1.0;
+ else if (x > -1.0) return v.i[HIGH_HALF] < 0 ? INF.x : 0.0;
+ else return v.i[HIGH_HALF] < 0 ? 0.0 : INF.x;
+ }
+ else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0)
+ return y < 0 ? 0.0 : INF.x;
+ return NaNQ.x; /* y not integer and x<0 */
+ }
+ else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0)
+ {
+ if (k < 0)
+ return y < 0 ? nZERO.x : nINF.x;
+ else
+ return y < 0 ? 0.0 : INF.x;
+ }
+ return (k==1)?__ieee754_pow(-x,y):-__ieee754_pow(-x,y); /* if y even or odd */
+ }
+ /* x>0 */
+ qx = u.i[HIGH_HALF]&0x7fffffff; /* no sign */
+ qy = v.i[HIGH_HALF]&0x7fffffff; /* no sign */
+
+ if (qx > 0x7ff00000 || (qx == 0x7ff00000 && u.i[LOW_HALF] != 0)) return NaNQ.x;
+ /* if 0<x<2^-0x7fe */
+ if (qy > 0x7ff00000 || (qy == 0x7ff00000 && v.i[LOW_HALF] != 0))
+ return x == 1.0 ? 1.0 : NaNQ.x;
+ /* if y<2^-0x7fe */
+
+ if (qx == 0x7ff00000) /* x= 2^-0x3ff */
+ {if (y == 0) return NaNQ.x;
+ return (y>0)?x:0; }
+
+ if (qy > 0x45f00000 && qy < 0x7ff00000) {
+ if (x == 1.0) return 1.0;
+ if (y>0) return (x>1.0)?INF.x:0;
+ if (y<0) return (x<1.0)?INF.x:0;
+ }
+
+ if (x == 1.0) return 1.0;
+ if (y>0) return (x>1.0)?INF.x:0;
+ if (y<0) return (x<1.0)?INF.x:0;
+ return 0; /* unreachable, to make the compiler happy */
+}
+
+/**************************************************************************/
+/* Computing x^y using more accurate but more slow log routine */
+/**************************************************************************/
+static double power1(double x, double y) {
+ double z,a,aa,error, t,a1,a2,y1,y2;
+ z = my_log2(x,&aa,&error);
+ t = y*134217729.0;
+ y1 = t - (t-y);
+ y2 = y - y1;
+ t = z*134217729.0;
+ a1 = t - (t-z);
+ a2 = z - a1;
+ a = y*z;
+ aa = ((y1*a1-a)+y1*a2+y2*a1)+y2*a2+aa*y;
+ a1 = a+aa;
+ a2 = (a-a1)+aa;
+ error = error*ABS(y);
+ t = __exp1(a1,a2,1.9e16*error);
+ return (t >= 0)?t:__slowpow(x,y,z);
+}
+
+/****************************************************************************/
+/* Computing log(x) (x is left argument). The result is the returned double */
+/* + the parameter delta. */
+/* The result is bounded by error (rightmost argument) */
+/****************************************************************************/
+static double log1(double x, double *delta, double *error) {
+ int i,j,m;
+#if 0
+ int n;
+#endif
+ double uu,vv,eps,nx,e,e1,e2,t,t1,t2,res,add=0;
+#if 0
+ double cor;
+#endif
+ mynumber u,v;
+#ifdef BIG_ENDI
+ mynumber
+/**/ two52 = {{0x43300000, 0x00000000}}; /* 2**52 */
+#else
+#ifdef LITTLE_ENDI
+ mynumber
+/**/ two52 = {{0x00000000, 0x43300000}}; /* 2**52 */
+#endif
+#endif
+
+ u.x = x;
+ m = u.i[HIGH_HALF];
+ *error = 0;
+ *delta = 0;
+ if (m < 0x00100000) /* 1<x<2^-1007 */
+ { x = x*t52.x; add = -52.0; u.x = x; m = u.i[HIGH_HALF];}
+
+ if ((m&0x000fffff) < 0x0006a09e)
+ {u.i[HIGH_HALF] = (m&0x000fffff)|0x3ff00000; two52.i[LOW_HALF]=(m>>20); }
+ else
+ {u.i[HIGH_HALF] = (m&0x000fffff)|0x3fe00000; two52.i[LOW_HALF]=(m>>20)+1; }
+
+ v.x = u.x + bigu.x;
+ uu = v.x - bigu.x;
+ i = (v.i[LOW_HALF]&0x000003ff)<<2;
+ if (two52.i[LOW_HALF] == 1023) /* nx = 0 */
+ {
+ if (i > 1192 && i < 1208) /* |x-1| < 1.5*2**-10 */
+ {
+ t = x - 1.0;
+ t1 = (t+5.0e6)-5.0e6;
+ t2 = t-t1;
+ e1 = t - 0.5*t1*t1;
+ e2 = t*t*t*(r3+t*(r4+t*(r5+t*(r6+t*(r7+t*r8)))))-0.5*t2*(t+t1);
+ res = e1+e2;
+ *error = 1.0e-21*ABS(t);
+ *delta = (e1-res)+e2;
+ return res;
+ } /* |x-1| < 1.5*2**-10 */
+ else
+ {
+ v.x = u.x*(ui.x[i]+ui.x[i+1])+bigv.x;
+ vv = v.x-bigv.x;
+ j = v.i[LOW_HALF]&0x0007ffff;
+ j = j+j+j;
+ eps = u.x - uu*vv;
+ e1 = eps*ui.x[i];
+ e2 = eps*(ui.x[i+1]+vj.x[j]*(ui.x[i]+ui.x[i+1]));
+ e = e1+e2;
+ e2 = ((e1-e)+e2);
+ t=ui.x[i+2]+vj.x[j+1];
+ t1 = t+e;
+ t2 = (((t-t1)+e)+(ui.x[i+3]+vj.x[j+2]))+e2+e*e*(p2+e*(p3+e*p4));
+ res=t1+t2;
+ *error = 1.0e-24;
+ *delta = (t1-res)+t2;
+ return res;
+ }
+ } /* nx = 0 */
+ else /* nx != 0 */
+ {
+ eps = u.x - uu;
+ nx = (two52.x - two52e.x)+add;
+ e1 = eps*ui.x[i];
+ e2 = eps*ui.x[i+1];
+ e=e1+e2;
+ e2 = (e1-e)+e2;
+ t=nx*ln2a.x+ui.x[i+2];
+ t1=t+e;
+ t2=(((t-t1)+e)+nx*ln2b.x+ui.x[i+3]+e2)+e*e*(q2+e*(q3+e*(q4+e*(q5+e*q6))));
+ res = t1+t2;
+ *error = 1.0e-21;
+ *delta = (t1-res)+t2;
+ return res;
+ } /* nx != 0 */
+}
+
+/****************************************************************************/
+/* More slow but more accurate routine of log */
+/* Computing log(x)(x is left argument).The result is return double + delta.*/
+/* The result is bounded by error (right argument) */
+/****************************************************************************/
+static double my_log2(double x, double *delta, double *error) {
+ int i,j,m;
+#if 0
+ int n;
+#endif
+ double uu,vv,eps,nx,e,e1,e2,t,t1,t2,res,add=0;
+#if 0
+ double cor;
+#endif
+ double ou1,ou2,lu1,lu2,ov,lv1,lv2,a,a1,a2;
+ double y,yy,z,zz,j1,j2,j3,j4,j5,j6,j7,j8;
+ mynumber u,v;
+#ifdef BIG_ENDI
+ mynumber
+/**/ two52 = {{0x43300000, 0x00000000}}; /* 2**52 */
+#else
+#ifdef LITTLE_ENDI
+ mynumber
+/**/ two52 = {{0x00000000, 0x43300000}}; /* 2**52 */
+#endif
+#endif
+
+ u.x = x;
+ m = u.i[HIGH_HALF];
+ *error = 0;
+ *delta = 0;
+ add=0;
+ if (m<0x00100000) { /* x < 2^-1022 */
+ x = x*t52.x; add = -52.0; u.x = x; m = u.i[HIGH_HALF]; }
+
+ if ((m&0x000fffff) < 0x0006a09e)
+ {u.i[HIGH_HALF] = (m&0x000fffff)|0x3ff00000; two52.i[LOW_HALF]=(m>>20); }
+ else
+ {u.i[HIGH_HALF] = (m&0x000fffff)|0x3fe00000; two52.i[LOW_HALF]=(m>>20)+1; }
+
+ v.x = u.x + bigu.x;
+ uu = v.x - bigu.x;
+ i = (v.i[LOW_HALF]&0x000003ff)<<2;
+ /*------------------------------------- |x-1| < 2**-11------------------------------- */
+ if ((two52.i[LOW_HALF] == 1023) && (i == 1200))
+ {
+ t = x - 1.0;
+ EMULV(t,s3,y,yy,j1,j2,j3,j4,j5);
+ ADD2(-0.5,0,y,yy,z,zz,j1,j2);
+ MUL2(t,0,z,zz,y,yy,j1,j2,j3,j4,j5,j6,j7,j8);
+ MUL2(t,0,y,yy,z,zz,j1,j2,j3,j4,j5,j6,j7,j8);
+
+ e1 = t+z;
+ e2 = (((t-e1)+z)+zz)+t*t*t*(ss3+t*(s4+t*(s5+t*(s6+t*(s7+t*s8)))));
+ res = e1+e2;
+ *error = 1.0e-25*ABS(t);
+ *delta = (e1-res)+e2;
+ return res;
+ }
+ /*----------------------------- |x-1| > 2**-11 -------------------------- */
+ else
+ { /*Computing log(x) according to log table */
+ nx = (two52.x - two52e.x)+add;
+ ou1 = ui.x[i];
+ ou2 = ui.x[i+1];
+ lu1 = ui.x[i+2];
+ lu2 = ui.x[i+3];
+ v.x = u.x*(ou1+ou2)+bigv.x;
+ vv = v.x-bigv.x;
+ j = v.i[LOW_HALF]&0x0007ffff;
+ j = j+j+j;
+ eps = u.x - uu*vv;
+ ov = vj.x[j];
+ lv1 = vj.x[j+1];
+ lv2 = vj.x[j+2];
+ a = (ou1+ou2)*(1.0+ov);
+ a1 = (a+1.0e10)-1.0e10;
+ a2 = a*(1.0-a1*uu*vv);
+ e1 = eps*a1;
+ e2 = eps*a2;
+ e = e1+e2;
+ e2 = (e1-e)+e2;
+ t=nx*ln2a.x+lu1+lv1;
+ t1 = t+e;
+ t2 = (((t-t1)+e)+(lu2+lv2+nx*ln2b.x+e2))+e*e*(p2+e*(p3+e*p4));
+ res=t1+t2;
+ *error = 1.0e-27;
+ *delta = (t1-res)+t2;
+ return res;
+ }
+}
+
+/**********************************************************************/
+/* Routine receives a double x and checks if it is an integer. If not */
+/* it returns 0, else it returns 1 if even or -1 if odd. */
+/**********************************************************************/
+static int checkint(double x) {
+ union {int4 i[2]; double x;} u;
+ int k,m,n;
+#if 0
+ int l;
+#endif
+ u.x = x;
+ m = u.i[HIGH_HALF]&0x7fffffff; /* no sign */
+ if (m >= 0x7ff00000) return 0; /* x is +/-inf or NaN */
+ if (m >= 0x43400000) return 1; /* |x| >= 2**53 */
+ if (m < 0x40000000) return 0; /* |x| < 2, can not be 0 or 1 */
+ n = u.i[LOW_HALF];
+ k = (m>>20)-1023; /* 1 <= k <= 52 */
+ if (k == 52) return (n&1)? -1:1; /* odd or even*/
+ if (k>20) {
+ if (n<<(k-20)) return 0; /* if not integer */
+ return (n<<(k-21))?-1:1;
+ }
+ if (n) return 0; /*if not integer*/
+ if (k == 20) return (m&1)? -1:1;
+ if (m<<(k+12)) return 0;
+ return (m<<(k+11))?-1:1;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_rem_pio2.c b/libc/sysdeps/ieee754/dbl-64/e_rem_pio2.c
new file mode 100644
index 000000000..a8a8cdb2b
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_rem_pio2.c
@@ -0,0 +1,183 @@
+/* @(#)e_rem_pio2.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: e_rem_pio2.c,v 1.8 1995/05/10 20:46:02 jtc Exp $";
+#endif
+
+/* __ieee754_rem_pio2(x,y)
+ *
+ * return the remainder of x rem pi/2 in y[0]+y[1]
+ * use __kernel_rem_pio2()
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+/*
+ * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
+ */
+#ifdef __STDC__
+static const int32_t two_over_pi[] = {
+#else
+static int32_t two_over_pi[] = {
+#endif
+0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
+0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
+0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
+0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
+0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
+0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
+0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
+0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
+0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
+0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
+0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
+};
+
+#ifdef __STDC__
+static const int32_t npio2_hw[] = {
+#else
+static int32_t npio2_hw[] = {
+#endif
+0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
+0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
+0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
+0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
+0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
+0x404858EB, 0x404921FB,
+};
+
+/*
+ * invpio2: 53 bits of 2/pi
+ * pio2_1: first 33 bit of pi/2
+ * pio2_1t: pi/2 - pio2_1
+ * pio2_2: second 33 bit of pi/2
+ * pio2_2t: pi/2 - (pio2_1+pio2_2)
+ * pio2_3: third 33 bit of pi/2
+ * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
+ */
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
+pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
+pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
+pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
+pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
+pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
+
+#ifdef __STDC__
+ int32_t __ieee754_rem_pio2(double x, double *y)
+#else
+ int32_t __ieee754_rem_pio2(x,y)
+ double x,y[];
+#endif
+{
+ double z,w,t,r,fn;
+ double tx[3];
+ int32_t e0,i,j,nx,n,ix,hx;
+ u_int32_t low;
+
+ GET_HIGH_WORD(hx,x); /* high word of x */
+ ix = hx&0x7fffffff;
+ if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */
+ {y[0] = x; y[1] = 0; return 0;}
+ if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */
+ if(hx>0) {
+ z = x - pio2_1;
+ if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
+ y[0] = z - pio2_1t;
+ y[1] = (z-y[0])-pio2_1t;
+ } else { /* near pi/2, use 33+33+53 bit pi */
+ z -= pio2_2;
+ y[0] = z - pio2_2t;
+ y[1] = (z-y[0])-pio2_2t;
+ }
+ return 1;
+ } else { /* negative x */
+ z = x + pio2_1;
+ if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
+ y[0] = z + pio2_1t;
+ y[1] = (z-y[0])+pio2_1t;
+ } else { /* near pi/2, use 33+33+53 bit pi */
+ z += pio2_2;
+ y[0] = z + pio2_2t;
+ y[1] = (z-y[0])+pio2_2t;
+ }
+ return -1;
+ }
+ }
+ if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
+ t = fabs(x);
+ n = (int32_t) (t*invpio2+half);
+ fn = (double)n;
+ r = t-fn*pio2_1;
+ w = fn*pio2_1t; /* 1st round good to 85 bit */
+ if(n<32&&ix!=npio2_hw[n-1]) {
+ y[0] = r-w; /* quick check no cancellation */
+ } else {
+ u_int32_t high;
+ j = ix>>20;
+ y[0] = r-w;
+ GET_HIGH_WORD(high,y[0]);
+ i = j-((high>>20)&0x7ff);
+ if(i>16) { /* 2nd iteration needed, good to 118 */
+ t = r;
+ w = fn*pio2_2;
+ r = t-w;
+ w = fn*pio2_2t-((t-r)-w);
+ y[0] = r-w;
+ GET_HIGH_WORD(high,y[0]);
+ i = j-((high>>20)&0x7ff);
+ if(i>49) { /* 3rd iteration need, 151 bits acc */
+ t = r; /* will cover all possible cases */
+ w = fn*pio2_3;
+ r = t-w;
+ w = fn*pio2_3t-((t-r)-w);
+ y[0] = r-w;
+ }
+ }
+ }
+ y[1] = (r-y[0])-w;
+ if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+ else return n;
+ }
+ /*
+ * all other (large) arguments
+ */
+ if(ix>=0x7ff00000) { /* x is inf or NaN */
+ y[0]=y[1]=x-x; return 0;
+ }
+ /* set z = scalbn(|x|,ilogb(x)-23) */
+ GET_LOW_WORD(low,x);
+ SET_LOW_WORD(z,low);
+ e0 = (ix>>20)-1046; /* e0 = ilogb(z)-23; */
+ SET_HIGH_WORD(z, ix - ((int32_t)(e0<<20)));
+ for(i=0;i<2;i++) {
+ tx[i] = (double)((int32_t)(z));
+ z = (z-tx[i])*two24;
+ }
+ tx[2] = z;
+ nx = 3;
+ while(tx[nx-1]==zero) nx--; /* skip zero term */
+ n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
+ if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+ return n;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_remainder.c b/libc/sysdeps/ieee754/dbl-64/e_remainder.c
new file mode 100644
index 000000000..cc06e18ce
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_remainder.c
@@ -0,0 +1,130 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/**************************************************************************/
+/* MODULE_NAME urem.c */
+/* */
+/* FUNCTION: uremainder */
+/* */
+/* An ultimate remainder routine. Given two IEEE double machine numbers x */
+/* ,y it computes the correctly rounded (to nearest) value of remainder */
+/* of dividing x by y. */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round to nearest mode of IEEE 754 standard. */
+/* */
+/* ************************************************************************/
+
+#include "endian.h"
+#include "mydefs.h"
+#include "urem.h"
+#include "MathLib.h"
+#include "math_private.h"
+
+/**************************************************************************/
+/* An ultimate remainder routine. Given two IEEE double machine numbers x */
+/* ,y it computes the correctly rounded (to nearest) value of remainder */
+/**************************************************************************/
+double __ieee754_remainder(double x, double y)
+{
+ double z,d,xx;
+#if 0
+ double yy;
+#endif
+ int4 kx,ky,n,nn,n1,m1,l;
+#if 0
+ int4 m;
+#endif
+ mynumber u,t,w={{0,0}},v={{0,0}},ww={{0,0}},r;
+ u.x=x;
+ t.x=y;
+ kx=u.i[HIGH_HALF]&0x7fffffff; /* no sign for x*/
+ t.i[HIGH_HALF]&=0x7fffffff; /*no sign for y */
+ ky=t.i[HIGH_HALF];
+ /*------ |x| < 2^1023 and 2^-970 < |y| < 2^1024 ------------------*/
+ if (kx<0x7fe00000 && ky<0x7ff00000 && ky>=0x03500000) {
+ if (kx+0x00100000<ky) return x;
+ if ((kx-0x01500000)<ky) {
+ z=x/t.x;
+ v.i[HIGH_HALF]=t.i[HIGH_HALF];
+ d=(z+big.x)-big.x;
+ xx=(x-d*v.x)-d*(t.x-v.x);
+ if (d-z!=0.5&&d-z!=-0.5) return (xx!=0)?xx:((x>0)?ZERO.x:nZERO.x);
+ else {
+ if (ABS(xx)>0.5*t.x) return (z>d)?xx-t.x:xx+t.x;
+ else return xx;
+ }
+ } /* (kx<(ky+0x01500000)) */
+ else {
+ r.x=1.0/t.x;
+ n=t.i[HIGH_HALF];
+ nn=(n&0x7ff00000)+0x01400000;
+ w.i[HIGH_HALF]=n;
+ ww.x=t.x-w.x;
+ l=(kx-nn)&0xfff00000;
+ n1=ww.i[HIGH_HALF];
+ m1=r.i[HIGH_HALF];
+ while (l>0) {
+ r.i[HIGH_HALF]=m1-l;
+ z=u.x*r.x;
+ w.i[HIGH_HALF]=n+l;
+ ww.i[HIGH_HALF]=(n1)?n1+l:n1;
+ d=(z+big.x)-big.x;
+ u.x=(u.x-d*w.x)-d*ww.x;
+ l=(u.i[HIGH_HALF]&0x7ff00000)-nn;
+ }
+ r.i[HIGH_HALF]=m1;
+ w.i[HIGH_HALF]=n;
+ ww.i[HIGH_HALF]=n1;
+ z=u.x*r.x;
+ d=(z+big.x)-big.x;
+ u.x=(u.x-d*w.x)-d*ww.x;
+ if (ABS(u.x)<0.5*t.x) return (u.x!=0)?u.x:((x>0)?ZERO.x:nZERO.x);
+ else
+ if (ABS(u.x)>0.5*t.x) return (d>z)?u.x+t.x:u.x-t.x;
+ else
+ {z=u.x/t.x; d=(z+big.x)-big.x; return ((u.x-d*w.x)-d*ww.x);}
+ }
+
+ } /* (kx<0x7fe00000&&ky<0x7ff00000&&ky>=0x03500000) */
+ else {
+ if (kx<0x7fe00000&&ky<0x7ff00000&&(ky>0||t.i[LOW_HALF]!=0)) {
+ y=ABS(y)*t128.x;
+ z=__ieee754_remainder(x,y)*t128.x;
+ z=__ieee754_remainder(z,y)*tm128.x;
+ return z;
+ }
+ else {
+ if ((kx&0x7ff00000)==0x7fe00000&&ky<0x7ff00000&&(ky>0||t.i[LOW_HALF]!=0)) {
+ y=ABS(y);
+ z=2.0*__ieee754_remainder(0.5*x,y);
+ d = ABS(z);
+ if (d <= ABS(d-y)) return z;
+ else return (z>0)?z-y:z+y;
+ }
+ else { /* if x is too big */
+ if (kx == 0x7ff00000 && u.i[LOW_HALF] == 0 && y == 1.0)
+ return x / x;
+ if (kx>=0x7ff00000||(ky==0&&t.i[LOW_HALF]==0)||ky>0x7ff00000||
+ (ky==0x7ff00000&&t.i[LOW_HALF]!=0))
+ return (u.i[HIGH_HALF]&0x80000000)?nNAN.x:NAN.x;
+ else return x;
+ }
+ }
+ }
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_sinh.c b/libc/sysdeps/ieee754/dbl-64/e_sinh.c
new file mode 100644
index 000000000..1701b9bb6
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_sinh.c
@@ -0,0 +1,86 @@
+/* @(#)e_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: e_sinh.c,v 1.7 1995/05/10 20:46:13 jtc Exp $";
+#endif
+
+/* __ieee754_sinh(x)
+ * Method :
+ * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+ * 1. Replace x by |x| (sinh(-x) = -sinh(x)).
+ * 2.
+ * E + E/(E+1)
+ * 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x)
+ * 2
+ *
+ * 22 <= x <= lnovft : sinh(x) := exp(x)/2
+ * lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2)
+ * ln2ovft < x : sinh(x) := x*shuge (overflow)
+ *
+ * Special cases:
+ * sinh(x) is |x| if x is +INF, -INF, or NaN.
+ * only sinh(0)=0 is exact for finite x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one = 1.0, shuge = 1.0e307;
+#else
+static double one = 1.0, shuge = 1.0e307;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_sinh(double x)
+#else
+ double __ieee754_sinh(x)
+ double x;
+#endif
+{
+ double t,w,h;
+ int32_t ix,jx;
+ u_int32_t lx;
+
+ /* High word of |x|. */
+ GET_HIGH_WORD(jx,x);
+ ix = jx&0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7ff00000) return x+x;
+
+ h = 0.5;
+ if (jx<0) h = -h;
+ /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
+ if (ix < 0x40360000) { /* |x|<22 */
+ if (ix<0x3e300000) /* |x|<2**-28 */
+ if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
+ t = __expm1(fabs(x));
+ if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one));
+ return h*(t+t/(t+one));
+ }
+
+ /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
+ if (ix < 0x40862e42) return h*__ieee754_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));
+ t = h*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, sinh(x) overflow */
+ return x*shuge;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/e_sqrt.c b/libc/sysdeps/ieee754/dbl-64/e_sqrt.c
new file mode 100644
index 000000000..f7e805549
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/e_sqrt.c
@@ -0,0 +1,88 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*********************************************************************/
+/* MODULE_NAME: uroot.c */
+/* */
+/* FUNCTION: usqrt */
+/* */
+/* FILES NEEDED: dla.h endian.h mydefs.h uroot.h */
+/* uroot.tbl */
+/* */
+/* An ultimate sqrt routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of square */
+/* root of x. */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round to nearest mode of IEEE 754 standard. */
+/* */
+/*********************************************************************/
+
+#include "endian.h"
+#include "mydefs.h"
+#include "dla.h"
+#include "MathLib.h"
+#include "root.tbl"
+#include "math_private.h"
+
+/*********************************************************************/
+/* An ultimate sqrt routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of square */
+/* root of x. */
+/*********************************************************************/
+double __ieee754_sqrt(double x) {
+#include "uroot.h"
+ static const double
+ rt0 = 9.99999999859990725855365213134618E-01,
+ rt1 = 4.99999999495955425917856814202739E-01,
+ rt2 = 3.75017500867345182581453026130850E-01,
+ rt3 = 3.12523626554518656309172508769531E-01;
+ static const double big = 134217728.0;
+ double y,t,del,res,res1,hy,z,zz,p,hx,tx,ty,s;
+ mynumber a,c={{0,0}};
+ int4 k;
+
+ a.x=x;
+ k=a.i[HIGH_HALF];
+ a.i[HIGH_HALF]=(k&0x001fffff)|0x3fe00000;
+ t=inroot[(k&0x001fffff)>>14];
+ s=a.x;
+ /*----------------- 2^-1022 <= | x |< 2^1024 -----------------*/
+ if (k>0x000fffff && k<0x7ff00000) {
+ y=1.0-t*(t*s);
+ t=t*(rt0+y*(rt1+y*(rt2+y*rt3)));
+ c.i[HIGH_HALF]=0x20000000+((k&0x7fe00000)>>1);
+ y=t*s;
+ hy=(y+big)-big;
+ del=0.5*t*((s-hy*hy)-(y-hy)*(y+hy));
+ res=y+del;
+ if (res == (res+1.002*((y-res)+del))) return res*c.x;
+ else {
+ res1=res+1.5*((y-res)+del);
+ EMULV(res,res1,z,zz,p,hx,tx,hy,ty); /* (z+zz)=res*res1 */
+ return ((((z-s)+zz)<0)?max(res,res1):min(res,res1))*c.x;
+ }
+ }
+ else {
+ if ((k & 0x7ff00000) == 0x7ff00000)
+ return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
+ if (x==0) return x; /* sqrt(+0)=+0, sqrt(-0)=-0 */
+ if (k<0) return (x-x)/(x-x); /* sqrt(-ve)=sNaN */
+ return tm256.x*__ieee754_sqrt(x*t512.x);
+ }
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/halfulp.c b/libc/sysdeps/ieee754/dbl-64/halfulp.c
new file mode 100644
index 000000000..478a4bacf
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/halfulp.c
@@ -0,0 +1,123 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001, 2005 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/************************************************************************/
+/* */
+/* MODULE_NAME:halfulp.c */
+/* */
+/* FUNCTIONS:halfulp */
+/* FILES NEEDED: mydefs.h dla.h endian.h */
+/* uroot.c */
+/* */
+/*Routine halfulp(double x, double y) computes x^y where result does */
+/*not need rounding. If the result is closer to 0 than can be */
+/*represented it returns 0. */
+/* In the following cases the function does not compute anything */
+/*and returns a negative number: */
+/*1. if the result needs rounding, */
+/*2. if y is outside the interval [0, 2^20-1], */
+/*3. if x can be represented by x=2**n for some integer n. */
+/************************************************************************/
+
+#include "endian.h"
+#include "mydefs.h"
+#include "dla.h"
+#include "math_private.h"
+
+double __ieee754_sqrt(double x);
+
+static const int4 tab54[32] = {
+ 262143, 11585, 1782, 511, 210, 107, 63, 42,
+ 30, 22, 17, 14, 12, 10, 9, 7,
+ 7, 6, 5, 5, 5, 4, 4, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3 };
+
+
+double __halfulp(double x, double y)
+{
+ mynumber v;
+ double z,u,uu,j1,j2,j3,j4,j5;
+ int4 k,l,m,n;
+ if (y <= 0) { /*if power is negative or zero */
+ v.x = y;
+ if (v.i[LOW_HALF] != 0) return -10.0;
+ v.x = x;
+ if (v.i[LOW_HALF] != 0) return -10.0;
+ if ((v.i[HIGH_HALF]&0x000fffff) != 0) return -10; /* if x =2 ^ n */
+ k = ((v.i[HIGH_HALF]&0x7fffffff)>>20)-1023; /* find this n */
+ z = (double) k;
+ return (z*y == -1075.0)?0: -10.0;
+ }
+ /* if y > 0 */
+ v.x = y;
+ if (v.i[LOW_HALF] != 0) return -10.0;
+
+ v.x=x;
+ /* case where x = 2**n for some integer n */
+ if (((v.i[HIGH_HALF]&0x000fffff)|v.i[LOW_HALF]) == 0) {
+ k=(v.i[HIGH_HALF]>>20)-1023;
+ return (((double) k)*y == -1075.0)?0:-10.0;
+ }
+
+ v.x = y;
+ k = v.i[HIGH_HALF];
+ m = k<<12;
+ l = 0;
+ while (m)
+ {m = m<<1; l++; }
+ n = (k&0x000fffff)|0x00100000;
+ n = n>>(20-l); /* n is the odd integer of y */
+ k = ((k>>20) -1023)-l; /* y = n*2**k */
+ if (k>5) return -10.0;
+ if (k>0) for (;k>0;k--) n *= 2;
+ if (n > 34) return -10.0;
+ k = -k;
+ if (k>5) return -10.0;
+
+ /* now treat x */
+ while (k>0) {
+ z = __ieee754_sqrt(x);
+ EMULV(z,z,u,uu,j1,j2,j3,j4,j5);
+ if (((u-x)+uu) != 0) break;
+ x = z;
+ k--;
+ }
+ if (k) return -10.0;
+
+ /* it is impossible that n == 2, so the mantissa of x must be short */
+
+ v.x = x;
+ if (v.i[LOW_HALF]) return -10.0;
+ k = v.i[HIGH_HALF];
+ m = k<<12;
+ l = 0;
+ while (m) {m = m<<1; l++; }
+ m = (k&0x000fffff)|0x00100000;
+ m = m>>(20-l); /* m is the odd integer of x */
+
+ /* now check whether the length of m**n is at most 54 bits */
+
+ if (m > tab54[n-3]) return -10.0;
+
+ /* yes, it is - now compute x**n by simple multiplications */
+
+ u = x;
+ for (k=1;k<n;k++) u = u*x;
+ return u;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/k_cos.c b/libc/sysdeps/ieee754/dbl-64/k_cos.c
new file mode 100644
index 000000000..cc5c205a5
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/k_cos.c
@@ -0,0 +1 @@
+/* Not needed anymore. */
diff --git a/libc/sysdeps/ieee754/dbl-64/k_rem_pio2.c b/libc/sysdeps/ieee754/dbl-64/k_rem_pio2.c
new file mode 100644
index 000000000..ccf1633bd
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/k_rem_pio2.c
@@ -0,0 +1,320 @@
+/* @(#)k_rem_pio2.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_rem_pio2.c,v 1.7 1995/05/10 20:46:25 jtc Exp $";
+#endif
+
+/*
+ * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
+ * double x[],y[]; int e0,nx,prec; int ipio2[];
+ *
+ * __kernel_rem_pio2 return the last three digits of N with
+ * y = x - N*pi/2
+ * so that |y| < pi/2.
+ *
+ * The method is to compute the integer (mod 8) and fraction parts of
+ * (2/pi)*x without doing the full multiplication. In general we
+ * skip the part of the product that are known to be a huge integer (
+ * more accurately, = 0 mod 8 ). Thus the number of operations are
+ * independent of the exponent of the input.
+ *
+ * (2/pi) is represented by an array of 24-bit integers in ipio2[].
+ *
+ * Input parameters:
+ * x[] The input value (must be positive) is broken into nx
+ * pieces of 24-bit integers in double precision format.
+ * x[i] will be the i-th 24 bit of x. The scaled exponent
+ * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
+ * match x's up to 24 bits.
+ *
+ * Example of breaking a double positive z into x[0]+x[1]+x[2]:
+ * e0 = ilogb(z)-23
+ * z = scalbn(z,-e0)
+ * for i = 0,1,2
+ * x[i] = floor(z)
+ * z = (z-x[i])*2**24
+ *
+ *
+ * y[] ouput result in an array of double precision numbers.
+ * The dimension of y[] is:
+ * 24-bit precision 1
+ * 53-bit precision 2
+ * 64-bit precision 2
+ * 113-bit precision 3
+ * The actual value is the sum of them. Thus for 113-bit
+ * precision, one may have to do something like:
+ *
+ * long double t,w,r_head, r_tail;
+ * t = (long double)y[2] + (long double)y[1];
+ * w = (long double)y[0];
+ * r_head = t+w;
+ * r_tail = w - (r_head - t);
+ *
+ * e0 The exponent of x[0]
+ *
+ * nx dimension of x[]
+ *
+ * prec an integer indicating the precision:
+ * 0 24 bits (single)
+ * 1 53 bits (double)
+ * 2 64 bits (extended)
+ * 3 113 bits (quad)
+ *
+ * ipio2[]
+ * integer array, contains the (24*i)-th to (24*i+23)-th
+ * bit of 2/pi after binary point. The corresponding
+ * floating value is
+ *
+ * ipio2[i] * 2^(-24(i+1)).
+ *
+ * External function:
+ * double scalbn(), floor();
+ *
+ *
+ * Here is the description of some local variables:
+ *
+ * jk jk+1 is the initial number of terms of ipio2[] needed
+ * in the computation. The recommended value is 2,3,4,
+ * 6 for single, double, extended,and quad.
+ *
+ * jz local integer variable indicating the number of
+ * terms of ipio2[] used.
+ *
+ * jx nx - 1
+ *
+ * jv index for pointing to the suitable ipio2[] for the
+ * computation. In general, we want
+ * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
+ * is an integer. Thus
+ * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
+ * Hence jv = max(0,(e0-3)/24).
+ *
+ * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
+ *
+ * q[] double array with integral value, representing the
+ * 24-bits chunk of the product of x and 2/pi.
+ *
+ * q0 the corresponding exponent of q[0]. Note that the
+ * exponent for q[i] would be q0-24*i.
+ *
+ * PIo2[] double precision array, obtained by cutting pi/2
+ * into 24 bits chunks.
+ *
+ * f[] ipio2[] in floating point
+ *
+ * iq[] integer array by breaking up q[] in 24-bits chunk.
+ *
+ * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
+ *
+ * ih integer. If >0 it indicates q[] is >= 0.5, hence
+ * it also indicates the *sign* of the result.
+ *
+ */
+
+
+/*
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
+#else
+static int init_jk[] = {2,3,4,6};
+#endif
+
+#ifdef __STDC__
+static const double PIo2[] = {
+#else
+static double PIo2[] = {
+#endif
+ 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
+ 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
+ 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
+ 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
+ 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
+ 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
+ 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
+ 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
+};
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+zero = 0.0,
+one = 1.0,
+two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
+
+#ifdef __STDC__
+ int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int32_t *ipio2)
+#else
+ int __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
+ double x[], y[]; int e0,nx,prec; int32_t ipio2[];
+#endif
+{
+ int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
+ double z,fw,f[20],fq[20],q[20];
+
+ /* initialize jk*/
+ jk = init_jk[prec];
+ jp = jk;
+
+ /* determine jx,jv,q0, note that 3>q0 */
+ jx = nx-1;
+ jv = (e0-3)/24; if(jv<0) jv=0;
+ q0 = e0-24*(jv+1);
+
+ /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
+ j = jv-jx; m = jx+jk;
+ for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
+
+ /* compute q[0],q[1],...q[jk] */
+ for (i=0;i<=jk;i++) {
+ for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
+ }
+
+ jz = jk;
+recompute:
+ /* distill q[] into iq[] reversingly */
+ for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
+ fw = (double)((int32_t)(twon24* z));
+ iq[i] = (int32_t)(z-two24*fw);
+ z = q[j-1]+fw;
+ }
+
+ /* compute n */
+ z = __scalbn(z,q0); /* actual value of z */
+ z -= 8.0*__floor(z*0.125); /* trim off integer >= 8 */
+ n = (int32_t) z;
+ z -= (double)n;
+ ih = 0;
+ if(q0>0) { /* need iq[jz-1] to determine n */
+ i = (iq[jz-1]>>(24-q0)); n += i;
+ iq[jz-1] -= i<<(24-q0);
+ ih = iq[jz-1]>>(23-q0);
+ }
+ else if(q0==0) ih = iq[jz-1]>>23;
+ else if(z>=0.5) ih=2;
+
+ if(ih>0) { /* q > 0.5 */
+ n += 1; carry = 0;
+ for(i=0;i<jz ;i++) { /* compute 1-q */
+ j = iq[i];
+ if(carry==0) {
+ if(j!=0) {
+ carry = 1; iq[i] = 0x1000000- j;
+ }
+ } else iq[i] = 0xffffff - j;
+ }
+ if(q0>0) { /* rare case: chance is 1 in 12 */
+ switch(q0) {
+ case 1:
+ iq[jz-1] &= 0x7fffff; break;
+ case 2:
+ iq[jz-1] &= 0x3fffff; break;
+ }
+ }
+ if(ih==2) {
+ z = one - z;
+ if(carry!=0) z -= __scalbn(one,q0);
+ }
+ }
+
+ /* check if recomputation is needed */
+ if(z==zero) {
+ j = 0;
+ for (i=jz-1;i>=jk;i--) j |= iq[i];
+ if(j==0) { /* need recomputation */
+ for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */
+
+ for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */
+ f[jx+i] = (double) ipio2[jv+i];
+ for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
+ q[i] = fw;
+ }
+ jz += k;
+ goto recompute;
+ }
+ }
+
+ /* chop off zero terms */
+ if(z==0.0) {
+ jz -= 1; q0 -= 24;
+ while(iq[jz]==0) { jz--; q0-=24;}
+ } else { /* break z into 24-bit if necessary */
+ z = __scalbn(z,-q0);
+ if(z>=two24) {
+ fw = (double)((int32_t)(twon24*z));
+ iq[jz] = (int32_t)(z-two24*fw);
+ jz += 1; q0 += 24;
+ iq[jz] = (int32_t) fw;
+ } else iq[jz] = (int32_t) z ;
+ }
+
+ /* convert integer "bit" chunk to floating-point value */
+ fw = __scalbn(one,q0);
+ for(i=jz;i>=0;i--) {
+ q[i] = fw*(double)iq[i]; fw*=twon24;
+ }
+
+ /* compute PIo2[0,...,jp]*q[jz,...,0] */
+ for(i=jz;i>=0;i--) {
+ for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
+ fq[jz-i] = fw;
+ }
+
+ /* compress fq[] into y[] */
+ switch(prec) {
+ case 0:
+ fw = 0.0;
+ for (i=jz;i>=0;i--) fw += fq[i];
+ y[0] = (ih==0)? fw: -fw;
+ break;
+ case 1:
+ case 2:
+ fw = 0.0;
+ for (i=jz;i>=0;i--) fw += fq[i];
+ y[0] = (ih==0)? fw: -fw;
+ fw = fq[0]-fw;
+ for (i=1;i<=jz;i++) fw += fq[i];
+ y[1] = (ih==0)? fw: -fw;
+ break;
+ case 3: /* painful */
+ for (i=jz;i>0;i--) {
+ fw = fq[i-1]+fq[i];
+ fq[i] += fq[i-1]-fw;
+ fq[i-1] = fw;
+ }
+ for (i=jz;i>1;i--) {
+ fw = fq[i-1]+fq[i];
+ fq[i] += fq[i-1]-fw;
+ fq[i-1] = fw;
+ }
+ for (fw=0.0,i=jz;i>=2;i--) fw += fq[i];
+ if(ih==0) {
+ y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
+ } else {
+ y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
+ }
+ }
+ return n&7;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/k_sin.c b/libc/sysdeps/ieee754/dbl-64/k_sin.c
new file mode 100644
index 000000000..cc5c205a5
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/k_sin.c
@@ -0,0 +1 @@
+/* Not needed anymore. */
diff --git a/libc/sysdeps/ieee754/dbl-64/k_tan.c b/libc/sysdeps/ieee754/dbl-64/k_tan.c
new file mode 100644
index 000000000..55dafb8eb
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/k_tan.c
@@ -0,0 +1,145 @@
+/* @(#)k_tan.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.
+ * ====================================================
+ */
+/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25,
+ for performance improvement on pipelined processors.
+*/
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: k_tan.c,v 1.8 1995/05/10 20:46:37 jtc Exp $";
+#endif
+
+/* __kernel_tan( x, y, k )
+ * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input k indicates whether tan (if k=1) or
+ * -1/tan (if k= -1) is returned.
+ *
+ * Algorithm
+ * 1. Since tan(-x) = -tan(x), we need only to consider positive x.
+ * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0.
+ * 3. tan(x) is approximated by a odd polynomial of degree 27 on
+ * [0,0.67434]
+ * 3 27
+ * tan(x) ~ x + T1*x + ... + T13*x
+ * where
+ *
+ * |tan(x) 2 4 26 | -59.2
+ * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2
+ * | x |
+ *
+ * Note: tan(x+y) = tan(x) + tan'(x)*y
+ * ~ tan(x) + (1+x*x)*y
+ * Therefore, for better accuracy in computing tan(x+y), let
+ * 3 2 2 2 2
+ * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
+ * then
+ * 3 2
+ * tan(x+y) = x + (T1*x + (x *(r+y)+y))
+ *
+ * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
+ * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
+ * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
+ */
+
+#include "math.h"
+#include "math_private.h"
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+pio4 = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
+pio4lo= 3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */
+T[] = {
+ 3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */
+ 1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */
+ 5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */
+ 2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */
+ 8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */
+ 3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */
+ 1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */
+ 5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */
+ 2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */
+ 7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */
+ 7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */
+ -1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */
+ 2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */
+};
+
+#ifdef __STDC__
+ double __kernel_tan(double x, double y, int iy)
+#else
+ double __kernel_tan(x, y, iy)
+ double x,y; int iy;
+#endif
+{
+ double z,r,v,w,s,r1,r2,r3,v1,v2,v3,w2,w4;
+ int32_t ix,hx;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff; /* high word of |x| */
+ if(ix<0x3e300000) /* x < 2**-28 */
+ {if((int)x==0) { /* generate inexact */
+ u_int32_t low;
+ GET_LOW_WORD(low,x);
+ if(((ix|low)|(iy+1))==0) return one/fabs(x);
+ else return (iy==1)? x: -one/x;
+ }
+ }
+ if(ix>=0x3FE59428) { /* |x|>=0.6744 */
+ if(hx<0) {x = -x; y = -y;}
+ z = pio4-x;
+ w = pio4lo-y;
+ x = z+w; y = 0.0;
+ }
+ z = x*x;
+ w = z*z;
+ /* Break x^5*(T[1]+x^2*T[2]+...) into
+ * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
+ * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
+ */
+#ifdef DO_NOT_USE_THIS
+ r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11]))));
+ v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12])))));
+#else
+ v1 = T[10]+w*T[12]; w2=w*w;
+ v2 = T[6]+w*T[8]; w4=w2*w2;
+ v3 = T[2]+w*T[4]; v1=z*v1;
+ r1 = T[9]+w*T[11]; v2=z*v2;
+ r2 = T[5]+w*T[7]; v3=z*v3;
+ r3 = T[1]+w*T[3];
+ v = v3 + w2*v2 + w4*v1;
+ r = r3 + w2*r2 + w4*r1;
+#endif
+ s = z*x;
+ r = y + z*(s*(r+v)+y);
+ r += T[0]*s;
+ w = x+r;
+ if(ix>=0x3FE59428) {
+ v = (double)iy;
+ return (double)(1-((hx>>30)&2))*(v-2.0*(x-(w*w/(w+v)-r)));
+ }
+ if(iy==1) return w;
+ else { /* if allow error up to 2 ulp,
+ simply return -1.0/(x+r) here */
+ /* compute -1.0/(x+r) accurately */
+ double a,t;
+ z = w;
+ SET_LOW_WORD(z,0);
+ v = r-(z - x); /* z+v = r+x */
+ t = a = -1.0/w; /* a = -1.0/w */
+ SET_LOW_WORD(t,0);
+ s = 1.0+t*z;
+ return t+a*(s+t*v);
+ }
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/mpa.c b/libc/sysdeps/ieee754/dbl-64/mpa.c
new file mode 100644
index 000000000..68647ba33
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mpa.c
@@ -0,0 +1,508 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/************************************************************************/
+/* MODULE_NAME: mpa.c */
+/* */
+/* FUNCTIONS: */
+/* mcr */
+/* acr */
+/* cr */
+/* cpy */
+/* cpymn */
+/* norm */
+/* denorm */
+/* mp_dbl */
+/* dbl_mp */
+/* add_magnitudes */
+/* sub_magnitudes */
+/* add */
+/* sub */
+/* mul */
+/* inv */
+/* dvd */
+/* */
+/* Arithmetic functions for multiple precision numbers. */
+/* Relative errors are bounded */
+/************************************************************************/
+
+
+#include "endian.h"
+#include "mpa.h"
+#include "mpa2.h"
+#include <sys/param.h> /* For MIN() */
+/* mcr() compares the sizes of the mantissas of two multiple precision */
+/* numbers. Mantissas are compared regardless of the signs of the */
+/* numbers, even if x->d[0] or y->d[0] are zero. Exponents are also */
+/* disregarded. */
+static int mcr(const mp_no *x, const mp_no *y, int p) {
+ int i;
+ for (i=1; i<=p; i++) {
+ if (X[i] == Y[i]) continue;
+ else if (X[i] > Y[i]) return 1;
+ else return -1; }
+ return 0;
+}
+
+
+
+/* acr() compares the absolute values of two multiple precision numbers */
+int __acr(const mp_no *x, const mp_no *y, int p) {
+ int i;
+
+ if (X[0] == ZERO) {
+ if (Y[0] == ZERO) i= 0;
+ else i=-1;
+ }
+ else if (Y[0] == ZERO) i= 1;
+ else {
+ if (EX > EY) i= 1;
+ else if (EX < EY) i=-1;
+ else i= mcr(x,y,p);
+ }
+
+ return i;
+}
+
+
+/* cr90 compares the values of two multiple precision numbers */
+int __cr(const mp_no *x, const mp_no *y, int p) {
+ int i;
+
+ if (X[0] > Y[0]) i= 1;
+ else if (X[0] < Y[0]) i=-1;
+ else if (X[0] < ZERO ) i= __acr(y,x,p);
+ else i= __acr(x,y,p);
+
+ return i;
+}
+
+
+/* Copy a multiple precision number. Set *y=*x. x=y is permissible. */
+void __cpy(const mp_no *x, mp_no *y, int p) {
+ int i;
+
+ EY = EX;
+ for (i=0; i <= p; i++) Y[i] = X[i];
+
+ return;
+}
+
+
+/* Copy a multiple precision number x of precision m into a */
+/* multiple precision number y of precision n. In case n>m, */
+/* the digits of y beyond the m'th are set to zero. In case */
+/* n<m, the digits of x beyond the n'th are ignored. */
+/* x=y is permissible. */
+
+void __cpymn(const mp_no *x, int m, mp_no *y, int n) {
+
+ int i,k;
+
+ EY = EX; k=MIN(m,n);
+ for (i=0; i <= k; i++) Y[i] = X[i];
+ for ( ; i <= n; i++) Y[i] = ZERO;
+
+ return;
+}
+
+/* Convert a multiple precision number *x into a double precision */
+/* number *y, normalized case (|x| >= 2**(-1022))) */
+static void norm(const mp_no *x, double *y, int p)
+{
+ #define R radixi.d
+ int i;
+#if 0
+ int k;
+#endif
+ double a,c,u,v,z[5];
+ if (p<5) {
+ if (p==1) c = X[1];
+ else if (p==2) c = X[1] + R* X[2];
+ else if (p==3) c = X[1] + R*(X[2] + R* X[3]);
+ else if (p==4) c =(X[1] + R* X[2]) + R*R*(X[3] + R*X[4]);
+ }
+ else {
+ for (a=ONE, z[1]=X[1]; z[1] < TWO23; )
+ {a *= TWO; z[1] *= TWO; }
+
+ for (i=2; i<5; i++) {
+ z[i] = X[i]*a;
+ u = (z[i] + CUTTER)-CUTTER;
+ if (u > z[i]) u -= RADIX;
+ z[i] -= u;
+ z[i-1] += u*RADIXI;
+ }
+
+ u = (z[3] + TWO71) - TWO71;
+ if (u > z[3]) u -= TWO19;
+ v = z[3]-u;
+
+ if (v == TWO18) {
+ if (z[4] == ZERO) {
+ for (i=5; i <= p; i++) {
+ if (X[i] == ZERO) continue;
+ else {z[3] += ONE; break; }
+ }
+ }
+ else z[3] += ONE;
+ }
+
+ c = (z[1] + R *(z[2] + R * z[3]))/a;
+ }
+
+ c *= X[0];
+
+ for (i=1; i<EX; i++) c *= RADIX;
+ for (i=1; i>EX; i--) c *= RADIXI;
+
+ *y = c;
+ return;
+#undef R
+}
+
+/* Convert a multiple precision number *x into a double precision */
+/* number *y, denormalized case (|x| < 2**(-1022))) */
+static void denorm(const mp_no *x, double *y, int p)
+{
+ int i,k;
+ double c,u,z[5];
+#if 0
+ double a,v;
+#endif
+
+#define R radixi.d
+ if (EX<-44 || (EX==-44 && X[1]<TWO5))
+ { *y=ZERO; return; }
+
+ if (p==1) {
+ if (EX==-42) {z[1]=X[1]+TWO10; z[2]=ZERO; z[3]=ZERO; k=3;}
+ else if (EX==-43) {z[1]= TWO10; z[2]=X[1]; z[3]=ZERO; k=2;}
+ else {z[1]= TWO10; z[2]=ZERO; z[3]=X[1]; k=1;}
+ }
+ else if (p==2) {
+ if (EX==-42) {z[1]=X[1]+TWO10; z[2]=X[2]; z[3]=ZERO; k=3;}
+ else if (EX==-43) {z[1]= TWO10; z[2]=X[1]; z[3]=X[2]; k=2;}
+ else {z[1]= TWO10; z[2]=ZERO; z[3]=X[1]; k=1;}
+ }
+ else {
+ if (EX==-42) {z[1]=X[1]+TWO10; z[2]=X[2]; k=3;}
+ else if (EX==-43) {z[1]= TWO10; z[2]=X[1]; k=2;}
+ else {z[1]= TWO10; z[2]=ZERO; k=1;}
+ z[3] = X[k];
+ }
+
+ u = (z[3] + TWO57) - TWO57;
+ if (u > z[3]) u -= TWO5;
+
+ if (u==z[3]) {
+ for (i=k+1; i <= p; i++) {
+ if (X[i] == ZERO) continue;
+ else {z[3] += ONE; break; }
+ }
+ }
+
+ c = X[0]*((z[1] + R*(z[2] + R*z[3])) - TWO10);
+
+ *y = c*TWOM1032;
+ return;
+
+#undef R
+}
+
+/* Convert a multiple precision number *x into a double precision number *y. */
+/* The result is correctly rounded to the nearest/even. *x is left unchanged */
+
+void __mp_dbl(const mp_no *x, double *y, int p) {
+#if 0
+ int i,k;
+ double a,c,u,v,z[5];
+#endif
+
+ if (X[0] == ZERO) {*y = ZERO; return; }
+
+ if (EX> -42) norm(x,y,p);
+ else if (EX==-42 && X[1]>=TWO10) norm(x,y,p);
+ else denorm(x,y,p);
+}
+
+
+/* dbl_mp() converts a double precision number x into a multiple precision */
+/* number *y. If the precision p is too small the result is truncated. x is */
+/* left unchanged. */
+
+void __dbl_mp(double x, mp_no *y, int p) {
+
+ int i,n;
+ double u;
+
+ /* Sign */
+ if (x == ZERO) {Y[0] = ZERO; return; }
+ else if (x > ZERO) Y[0] = ONE;
+ else {Y[0] = MONE; x=-x; }
+
+ /* Exponent */
+ for (EY=ONE; x >= RADIX; EY += ONE) x *= RADIXI;
+ for ( ; x < ONE; EY -= ONE) x *= RADIX;
+
+ /* Digits */
+ n=MIN(p,4);
+ for (i=1; i<=n; i++) {
+ u = (x + TWO52) - TWO52;
+ if (u>x) u -= ONE;
+ Y[i] = u; x -= u; x *= RADIX; }
+ for ( ; i<=p; i++) Y[i] = ZERO;
+ return;
+}
+
+
+/* add_magnitudes() adds the magnitudes of *x & *y assuming that */
+/* abs(*x) >= abs(*y) > 0. */
+/* The sign of the sum *z is undefined. x&y may overlap but not x&z or y&z. */
+/* No guard digit is used. The result equals the exact sum, truncated. */
+/* *x & *y are left unchanged. */
+
+static void add_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) {
+
+ int i,j,k;
+
+ EZ = EX;
+
+ i=p; j=p+ EY - EX; k=p+1;
+
+ if (j<1)
+ {__cpy(x,z,p); return; }
+ else Z[k] = ZERO;
+
+ for (; j>0; i--,j--) {
+ Z[k] += X[i] + Y[j];
+ if (Z[k] >= RADIX) {
+ Z[k] -= RADIX;
+ Z[--k] = ONE; }
+ else
+ Z[--k] = ZERO;
+ }
+
+ for (; i>0; i--) {
+ Z[k] += X[i];
+ if (Z[k] >= RADIX) {
+ Z[k] -= RADIX;
+ Z[--k] = ONE; }
+ else
+ Z[--k] = ZERO;
+ }
+
+ if (Z[1] == ZERO) {
+ for (i=1; i<=p; i++) Z[i] = Z[i+1]; }
+ else EZ += ONE;
+}
+
+
+/* sub_magnitudes() subtracts the magnitudes of *x & *y assuming that */
+/* abs(*x) > abs(*y) > 0. */
+/* The sign of the difference *z is undefined. x&y may overlap but not x&z */
+/* or y&z. One guard digit is used. The error is less than one ulp. */
+/* *x & *y are left unchanged. */
+
+static void sub_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) {
+
+ int i,j,k;
+
+ EZ = EX;
+
+ if (EX == EY) {
+ i=j=k=p;
+ Z[k] = Z[k+1] = ZERO; }
+ else {
+ j= EX - EY;
+ if (j > p) {__cpy(x,z,p); return; }
+ else {
+ i=p; j=p+1-j; k=p;
+ if (Y[j] > ZERO) {
+ Z[k+1] = RADIX - Y[j--];
+ Z[k] = MONE; }
+ else {
+ Z[k+1] = ZERO;
+ Z[k] = ZERO; j--;}
+ }
+ }
+
+ for (; j>0; i--,j--) {
+ Z[k] += (X[i] - Y[j]);
+ if (Z[k] < ZERO) {
+ Z[k] += RADIX;
+ Z[--k] = MONE; }
+ else
+ Z[--k] = ZERO;
+ }
+
+ for (; i>0; i--) {
+ Z[k] += X[i];
+ if (Z[k] < ZERO) {
+ Z[k] += RADIX;
+ Z[--k] = MONE; }
+ else
+ Z[--k] = ZERO;
+ }
+
+ for (i=1; Z[i] == ZERO; i++) ;
+ EZ = EZ - i + 1;
+ for (k=1; i <= p+1; )
+ Z[k++] = Z[i++];
+ for (; k <= p; )
+ Z[k++] = ZERO;
+
+ return;
+}
+
+
+/* Add two multiple precision numbers. Set *z = *x + *y. x&y may overlap */
+/* but not x&z or y&z. One guard digit is used. The error is less than */
+/* one ulp. *x & *y are left unchanged. */
+
+void __add(const mp_no *x, const mp_no *y, mp_no *z, int p) {
+
+ int n;
+
+ if (X[0] == ZERO) {__cpy(y,z,p); return; }
+ else if (Y[0] == ZERO) {__cpy(x,z,p); return; }
+
+ if (X[0] == Y[0]) {
+ if (__acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; }
+ else {add_magnitudes(y,x,z,p); Z[0] = Y[0]; }
+ }
+ else {
+ if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; }
+ else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = Y[0]; }
+ else Z[0] = ZERO;
+ }
+ return;
+}
+
+
+/* Subtract two multiple precision numbers. *z is set to *x - *y. x&y may */
+/* overlap but not x&z or y&z. One guard digit is used. The error is */
+/* less than one ulp. *x & *y are left unchanged. */
+
+void __sub(const mp_no *x, const mp_no *y, mp_no *z, int p) {
+
+ int n;
+
+ if (X[0] == ZERO) {__cpy(y,z,p); Z[0] = -Z[0]; return; }
+ else if (Y[0] == ZERO) {__cpy(x,z,p); return; }
+
+ if (X[0] != Y[0]) {
+ if (__acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; }
+ else {add_magnitudes(y,x,z,p); Z[0] = -Y[0]; }
+ }
+ else {
+ if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; }
+ else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = -Y[0]; }
+ else Z[0] = ZERO;
+ }
+ return;
+}
+
+
+/* Multiply two multiple precision numbers. *z is set to *x * *y. x&y */
+/* may overlap but not x&z or y&z. In case p=1,2,3 the exact result is */
+/* truncated to p digits. In case p>3 the error is bounded by 1.001 ulp. */
+/* *x & *y are left unchanged. */
+
+void __mul(const mp_no *x, const mp_no *y, mp_no *z, int p) {
+
+ int i, i1, i2, j, k, k2;
+ double u;
+
+ /* Is z=0? */
+ if (X[0]*Y[0]==ZERO)
+ { Z[0]=ZERO; return; }
+
+ /* Multiply, add and carry */
+ k2 = (p<3) ? p+p : p+3;
+ Z[k2]=ZERO;
+ for (k=k2; k>1; ) {
+ if (k > p) {i1=k-p; i2=p+1; }
+ else {i1=1; i2=k; }
+ for (i=i1,j=i2-1; i<i2; i++,j--) Z[k] += X[i]*Y[j];
+
+ u = (Z[k] + CUTTER)-CUTTER;
+ if (u > Z[k]) u -= RADIX;
+ Z[k] -= u;
+ Z[--k] = u*RADIXI;
+ }
+
+ /* Is there a carry beyond the most significant digit? */
+ if (Z[1] == ZERO) {
+ for (i=1; i<=p; i++) Z[i]=Z[i+1];
+ EZ = EX + EY - 1; }
+ else
+ EZ = EX + EY;
+
+ Z[0] = X[0] * Y[0];
+ return;
+}
+
+
+/* Invert a multiple precision number. Set *y = 1 / *x. */
+/* Relative error bound = 1.001*r**(1-p) for p=2, 1.063*r**(1-p) for p=3, */
+/* 2.001*r**(1-p) for p>3. */
+/* *x=0 is not permissible. *x is left unchanged. */
+
+void __inv(const mp_no *x, mp_no *y, int p) {
+ int i;
+#if 0
+ int l;
+#endif
+ double t;
+ mp_no z,w;
+ static const int np1[] = {0,0,0,0,1,2,2,2,2,3,3,3,3,3,3,3,3,3,
+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4};
+ const mp_no mptwo = {1,{1.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}};
+
+ __cpy(x,&z,p); z.e=0; __mp_dbl(&z,&t,p);
+ t=ONE/t; __dbl_mp(t,y,p); EY -= EX;
+
+ for (i=0; i<np1[p]; i++) {
+ __cpy(y,&w,p);
+ __mul(x,&w,y,p);
+ __sub(&mptwo,y,&z,p);
+ __mul(&w,&z,y,p);
+ }
+ return;
+}
+
+
+/* Divide one multiple precision number by another.Set *z = *x / *y. *x & *y */
+/* are left unchanged. x&y may overlap but not x&z or y&z. */
+/* Relative error bound = 2.001*r**(1-p) for p=2, 2.063*r**(1-p) for p=3 */
+/* and 3.001*r**(1-p) for p>3. *y=0 is not permissible. */
+
+void __dvd(const mp_no *x, const mp_no *y, mp_no *z, int p) {
+
+ mp_no w;
+
+ if (X[0] == ZERO) Z[0] = ZERO;
+ else {__inv(y,&w,p); __mul(x,&w,z,p);}
+ return;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/mpa.h b/libc/sysdeps/ieee754/dbl-64/mpa.h
new file mode 100644
index 000000000..4aec48e90
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mpa.h
@@ -0,0 +1,85 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/************************************************************************/
+/* MODULE_NAME: mpa.h */
+/* */
+/* FUNCTIONS: */
+/* mcr */
+/* acr */
+/* cr */
+/* cpy */
+/* cpymn */
+/* mp_dbl */
+/* dbl_mp */
+/* add */
+/* sub */
+/* mul */
+/* inv */
+/* dvd */
+/* */
+/* Arithmetic functions for multiple precision numbers. */
+/* Common types and definition */
+/************************************************************************/
+
+
+typedef struct {/* This structure holds the details of a multi-precision */
+ int e; /* floating point number, x: d[0] holds its sign (-1,0 or 1) */
+ double d[40]; /* e holds its exponent (...,-2,-1,0,1,2,...) and */
+} mp_no; /* d[1]...d[p] hold its mantissa digits. The value of x is, */
+ /* x = d[1]*r**(e-1) + d[2]*r**(e-2) + ... + d[p]*r**(e-p). */
+ /* Here r = 2**24, 0 <= d[i] < r and 1 <= p <= 32. */
+ /* p is a global variable. A multi-precision number is */
+ /* always normalized. Namely, d[1] > 0. An exception is */
+ /* a zero which is characterized by d[0] = 0. The terms */
+ /* d[p+1], d[p+2], ... of a none zero number have no */
+ /* significance and so are the terms e, d[1],d[2],... */
+ /* of a zero. */
+
+typedef union { int i[2]; double d; } number;
+
+#define X x->d
+#define Y y->d
+#define Z z->d
+#define EX x->e
+#define EY y->e
+#define EZ z->e
+
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+
+int __acr(const mp_no *, const mp_no *, int);
+int __cr(const mp_no *, const mp_no *, int);
+void __cpy(const mp_no *, mp_no *, int);
+void __cpymn(const mp_no *, int, mp_no *, int);
+void __mp_dbl(const mp_no *, double *, int);
+void __dbl_mp(double, mp_no *, int);
+void __add(const mp_no *, const mp_no *, mp_no *, int);
+void __sub(const mp_no *, const mp_no *, mp_no *, int);
+void __mul(const mp_no *, const mp_no *, mp_no *, int);
+void __inv(const mp_no *, mp_no *, int);
+void __dvd(const mp_no *, const mp_no *, mp_no *, int);
+
+extern void __mpatan (mp_no *, mp_no *, int);
+extern void __mpatan2 (mp_no *, mp_no *, mp_no *, int);
+extern void __mpsqrt (mp_no *, mp_no *, int);
+extern void __mpexp (mp_no *, mp_no *__y, int);
+extern void __c32 (mp_no *, mp_no *, mp_no *, int);
+extern int __mpranred (double, mp_no *, int);
diff --git a/libc/sysdeps/ieee754/dbl-64/mpa2.h b/libc/sysdeps/ieee754/dbl-64/mpa2.h
new file mode 100644
index 000000000..ba93e8fc1
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mpa2.h
@@ -0,0 +1,95 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**************************************************************************/
+/* */
+/* MODULE_NAME:mpa2.h */
+/* */
+/* */
+/* variables prototype and definition according to type of processor */
+/* types definition */
+/**************************************************************************/
+
+#ifndef MPA2_H
+#define MPA2_H
+
+
+#ifdef BIG_ENDI
+static const number
+/**/ radix = {{0x41700000, 0x00000000} }, /* 2**24 */
+/**/ radixi = {{0x3e700000, 0x00000000} }, /* 2**-24 */
+/**/ cutter = {{0x44b00000, 0x00000000} }, /* 2**76 */
+/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */
+/**/ one = {{0x3ff00000, 0x00000000} }, /* 1 */
+/**/ mone = {{0xbff00000, 0x00000000} }, /* -1 */
+/**/ two = {{0x40000000, 0x00000000} }, /* 2 */
+/**/ two5 = {{0x40400000, 0x00000000} }, /* 2**5 */
+/**/ two10 = {{0x40900000, 0x00000000} }, /* 2**10 */
+/**/ two18 = {{0x41100000, 0x00000000} }, /* 2**18 */
+/**/ two19 = {{0x41200000, 0x00000000} }, /* 2**19 */
+/**/ two23 = {{0x41600000, 0x00000000} }, /* 2**23 */
+/**/ two52 = {{0x43300000, 0x00000000} }, /* 2**52 */
+/**/ two57 = {{0x43800000, 0x00000000} }, /* 2**57 */
+/**/ two71 = {{0x44600000, 0x00000000} }, /* 2**71 */
+/**/ twom1032 = {{0x00000400, 0x00000000} }; /* 2**-1032 */
+
+#else
+#ifdef LITTLE_ENDI
+static const number
+/**/ radix = {{0x00000000, 0x41700000} }, /* 2**24 */
+/**/ radixi = {{0x00000000, 0x3e700000} }, /* 2**-24 */
+/**/ cutter = {{0x00000000, 0x44b00000} }, /* 2**76 */
+/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */
+/**/ one = {{0x00000000, 0x3ff00000} }, /* 1 */
+/**/ mone = {{0x00000000, 0xbff00000} }, /* -1 */
+/**/ two = {{0x00000000, 0x40000000} }, /* 2 */
+/**/ two5 = {{0x00000000, 0x40400000} }, /* 2**5 */
+/**/ two10 = {{0x00000000, 0x40900000} }, /* 2**10 */
+/**/ two18 = {{0x00000000, 0x41100000} }, /* 2**18 */
+/**/ two19 = {{0x00000000, 0x41200000} }, /* 2**19 */
+/**/ two23 = {{0x00000000, 0x41600000} }, /* 2**23 */
+/**/ two52 = {{0x00000000, 0x43300000} }, /* 2**52 */
+/**/ two57 = {{0x00000000, 0x43800000} }, /* 2**57 */
+/**/ two71 = {{0x00000000, 0x44600000} }, /* 2**71 */
+/**/ twom1032 = {{0x00000000, 0x00000400} }; /* 2**-1032 */
+
+#endif
+#endif
+
+#define RADIX radix.d
+#define RADIXI radixi.d
+#define CUTTER cutter.d
+#define ZERO zero.d
+#define ONE one.d
+#define MONE mone.d
+#define TWO two.d
+#define TWO5 two5.d
+#define TWO10 two10.d
+#define TWO18 two18.d
+#define TWO19 two19.d
+#define TWO23 two23.d
+#define TWO52 two52.d
+#define TWO57 two57.d
+#define TWO71 two71.d
+#define TWOM1032 twom1032.d
+
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/mpatan.c b/libc/sysdeps/ieee754/dbl-64/mpatan.c
new file mode 100644
index 000000000..ee21c2513
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mpatan.c
@@ -0,0 +1,102 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/******************************************************************/
+/* */
+/* MODULE_NAME:mpatan.c */
+/* */
+/* FUNCTIONS:mpatan */
+/* */
+/* FILES NEEDED: mpa.h endian.h mpatan.h */
+/* mpa.c */
+/* */
+/* Multi-Precision Atan function subroutine, for precision p >= 4.*/
+/* The relative error of the result is bounded by 34.32*r**(1-p), */
+/* where r=2**24. */
+/******************************************************************/
+
+#include "endian.h"
+#include "mpa.h"
+void __mpsqrt(mp_no *, mp_no *, int);
+
+void __mpatan(mp_no *x, mp_no *y, int p) {
+#include "mpatan.h"
+
+ int i,m,n;
+ double dx;
+ mp_no
+ mpone = {0,{0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}},
+ mptwo = {0,{0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}},
+ mptwoim1 = {0,{0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}};
+
+ mp_no mps,mpsm,mpt,mpt1,mpt2,mpt3;
+
+ /* Choose m and initiate mpone, mptwo & mptwoim1 */
+ if (EX>0) m=7;
+ else if (EX<0) m=0;
+ else {
+ __mp_dbl(x,&dx,p); dx=ABS(dx);
+ for (m=6; m>0; m--)
+ {if (dx>xm[m].d) break;}
+ }
+ mpone.e = mptwo.e = mptwoim1.e = 1;
+ mpone.d[0] = mpone.d[1] = mptwo.d[0] = mptwoim1.d[0] = ONE;
+ mptwo.d[1] = TWO;
+
+ /* Reduce x m times */
+ __mul(x,x,&mpsm,p);
+ if (m==0) __cpy(x,&mps,p);
+ else {
+ for (i=0; i<m; i++) {
+ __add(&mpone,&mpsm,&mpt1,p);
+ __mpsqrt(&mpt1,&mpt2,p);
+ __add(&mpt2,&mpt2,&mpt1,p);
+ __add(&mptwo,&mpsm,&mpt2,p);
+ __add(&mpt1,&mpt2,&mpt3,p);
+ __dvd(&mpsm,&mpt3,&mpt1,p);
+ __cpy(&mpt1,&mpsm,p);
+ }
+ __mpsqrt(&mpsm,&mps,p); mps.d[0] = X[0];
+ }
+
+ /* Evaluate a truncated power series for Atan(s) */
+ n=np[p]; mptwoim1.d[1] = twonm1[p].d;
+ __dvd(&mpsm,&mptwoim1,&mpt,p);
+ for (i=n-1; i>1; i--) {
+ mptwoim1.d[1] -= TWO;
+ __dvd(&mpsm,&mptwoim1,&mpt1,p);
+ __mul(&mpsm,&mpt,&mpt2,p);
+ __sub(&mpt1,&mpt2,&mpt,p);
+ }
+ __mul(&mps,&mpt,&mpt1,p);
+ __sub(&mps,&mpt1,&mpt,p);
+
+ /* Compute Atan(x) */
+ mptwoim1.d[1] = twom[m].d;
+ __mul(&mptwoim1,&mpt,y,p);
+
+ return;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/mpatan.h b/libc/sysdeps/ieee754/dbl-64/mpatan.h
new file mode 100644
index 000000000..d420ff340
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mpatan.h
@@ -0,0 +1,174 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/******************************************************************/
+/* */
+/* MODULE_NAME:mpatan.h */
+/* */
+/* common data and variables prototype and definition */
+/******************************************************************/
+
+#ifndef MPATAN_H
+#define MPATAN_H
+
+#ifdef BIG_ENDI
+ static const number
+ xm[8] = { /* x[m] */
+/**/ {{0x00000000, 0x00000000} }, /* 0.0 */
+/**/ {{0x3f8930be, 0x00000000} }, /* 0.0123 */
+/**/ {{0x3f991687, 0x00000000} }, /* 0.0245 */
+/**/ {{0x3fa923a2, 0x00000000} }, /* 0.0491 */
+/**/ {{0x3fb930be, 0x00000000} }, /* 0.0984 */
+/**/ {{0x3fc95810, 0x00000000} }, /* 0.198 */
+/**/ {{0x3fda7ef9, 0x00000000} }, /* 0.414 */
+/**/ {{0x3ff00000, 0x00000000} }, /* 1.0 */
+ };
+ static const number
+ twonm1[33] = { /* 2n-1 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x40260000, 0x00000000} }, /* 11 */
+/**/ {{0x402e0000, 0x00000000} }, /* 15 */
+/**/ {{0x40330000, 0x00000000} }, /* 19 */
+/**/ {{0x40350000, 0x00000000} }, /* 21 */
+/**/ {{0x40390000, 0x00000000} }, /* 25 */
+/**/ {{0x403d0000, 0x00000000} }, /* 29 */
+/**/ {{0x40408000, 0x00000000} }, /* 33 */
+/**/ {{0x40428000, 0x00000000} }, /* 37 */
+/**/ {{0x40448000, 0x00000000} }, /* 41 */
+/**/ {{0x40468000, 0x00000000} }, /* 45 */
+/**/ {{0x40488000, 0x00000000} }, /* 49 */
+/**/ {{0x404a8000, 0x00000000} }, /* 53 */
+/**/ {{0x404b8000, 0x00000000} }, /* 55 */
+/**/ {{0x404d8000, 0x00000000} }, /* 59 */
+/**/ {{0x404f8000, 0x00000000} }, /* 63 */
+/**/ {{0x4050c000, 0x00000000} }, /* 67 */
+/**/ {{0x4051c000, 0x00000000} }, /* 71 */
+/**/ {{0x4052c000, 0x00000000} }, /* 75 */
+/**/ {{0x4053c000, 0x00000000} }, /* 79 */
+/**/ {{0x4054c000, 0x00000000} }, /* 83 */
+/**/ {{0x40554000, 0x00000000} }, /* 85 */
+/**/ {{0x40564000, 0x00000000} }, /* 89 */
+/**/ {{0x40574000, 0x00000000} }, /* 93 */
+/**/ {{0x40584000, 0x00000000} }, /* 97 */
+/**/ {{0x40594000, 0x00000000} }, /* 101 */
+/**/ {{0x405a4000, 0x00000000} }, /* 105 */
+/**/ {{0x405b4000, 0x00000000} }, /* 109 */
+/**/ {{0x405c4000, 0x00000000} }, /* 113 */
+/**/ {{0x405d4000, 0x00000000} }, /* 117 */
+ };
+
+ static const number
+ twom[8] = { /* 2**m */
+/**/ {{0x3ff00000, 0x00000000} }, /* 1.0 */
+/**/ {{0x40000000, 0x00000000} }, /* 2.0 */
+/**/ {{0x40100000, 0x00000000} }, /* 4.0 */
+/**/ {{0x40200000, 0x00000000} }, /* 8.0 */
+/**/ {{0x40300000, 0x00000000} }, /* 16.0 */
+/**/ {{0x40400000, 0x00000000} }, /* 32.0 */
+/**/ {{0x40500000, 0x00000000} }, /* 64.0 */
+/**/ {{0x40600000, 0x00000000} }, /* 128.0 */
+ };
+
+ static const number
+/**/ one = {{0x3ff00000, 0x00000000} }, /* 1 */
+/**/ two = {{0x40000000, 0x00000000} }; /* 2 */
+
+#else
+#ifdef LITTLE_ENDI
+
+ static const number
+ xm[8] = { /* x[m] */
+/**/ {{0x00000000, 0x00000000} }, /* 0.0 */
+/**/ {{0x00000000, 0x3f8930be} }, /* 0.0123 */
+/**/ {{0x00000000, 0x3f991687} }, /* 0.0245 */
+/**/ {{0x00000000, 0x3fa923a2} }, /* 0.0491 */
+/**/ {{0x00000000, 0x3fb930be} }, /* 0.0984 */
+/**/ {{0x00000000, 0x3fc95810} }, /* 0.198 */
+/**/ {{0x00000000, 0x3fda7ef9} }, /* 0.414 */
+/**/ {{0x00000000, 0x3ff00000} }, /* 1.0 */
+ };
+ static const number
+ twonm1[33] = { /* 2n-1 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x40260000} }, /* 11 */
+/**/ {{0x00000000, 0x402e0000} }, /* 15 */
+/**/ {{0x00000000, 0x40330000} }, /* 19 */
+/**/ {{0x00000000, 0x40350000} }, /* 21 */
+/**/ {{0x00000000, 0x40390000} }, /* 25 */
+/**/ {{0x00000000, 0x403d0000} }, /* 29 */
+/**/ {{0x00000000, 0x40408000} }, /* 33 */
+/**/ {{0x00000000, 0x40428000} }, /* 37 */
+/**/ {{0x00000000, 0x40448000} }, /* 41 */
+/**/ {{0x00000000, 0x40468000} }, /* 45 */
+/**/ {{0x00000000, 0x40488000} }, /* 49 */
+/**/ {{0x00000000, 0x404a8000} }, /* 53 */
+/**/ {{0x00000000, 0x404b8000} }, /* 55 */
+/**/ {{0x00000000, 0x404d8000} }, /* 59 */
+/**/ {{0x00000000, 0x404f8000} }, /* 63 */
+/**/ {{0x00000000, 0x4050c000} }, /* 67 */
+/**/ {{0x00000000, 0x4051c000} }, /* 71 */
+/**/ {{0x00000000, 0x4052c000} }, /* 75 */
+/**/ {{0x00000000, 0x4053c000} }, /* 79 */
+/**/ {{0x00000000, 0x4054c000} }, /* 83 */
+/**/ {{0x00000000, 0x40554000} }, /* 85 */
+/**/ {{0x00000000, 0x40564000} }, /* 89 */
+/**/ {{0x00000000, 0x40574000} }, /* 93 */
+/**/ {{0x00000000, 0x40584000} }, /* 97 */
+/**/ {{0x00000000, 0x40594000} }, /* 101 */
+/**/ {{0x00000000, 0x405a4000} }, /* 105 */
+/**/ {{0x00000000, 0x405b4000} }, /* 109 */
+/**/ {{0x00000000, 0x405c4000} }, /* 113 */
+/**/ {{0x00000000, 0x405d4000} }, /* 117 */
+ };
+
+ static const number
+ twom[8] = { /* 2**m */
+/**/ {{0x00000000, 0x3ff00000} }, /* 1.0 */
+/**/ {{0x00000000, 0x40000000} }, /* 2.0 */
+/**/ {{0x00000000, 0x40100000} }, /* 4.0 */
+/**/ {{0x00000000, 0x40200000} }, /* 8.0 */
+/**/ {{0x00000000, 0x40300000} }, /* 16.0 */
+/**/ {{0x00000000, 0x40400000} }, /* 32.0 */
+/**/ {{0x00000000, 0x40500000} }, /* 64.0 */
+/**/ {{0x00000000, 0x40600000} }, /* 128.0 */
+ };
+
+ static const number
+/**/ one = {{0x00000000, 0x3ff00000} }, /* 1 */
+/**/ two = {{0x00000000, 0x40000000} }; /* 2 */
+
+#endif
+#endif
+
+#define ONE one.d
+#define TWO two.d
+
+ static const int
+ np[33] = { 0, 0, 0, 0, 6, 8,10,11,13,15,17,19,21,23,25,27,28,
+ 30,32,34,36,38,40,42,43,45,47,49,51,53,55,57,59};
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/mpatan2.c b/libc/sysdeps/ieee754/dbl-64/mpatan2.c
new file mode 100644
index 000000000..8977ec904
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mpatan2.c
@@ -0,0 +1,70 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/******************************************************************/
+/* MODULE_NAME: mpatan2.c */
+/* */
+/* FUNCTIONS:mpatan2 */
+/* */
+/* FILES NEEDED: mpa.h */
+/* mpa.c mpatan.c mpsqrt.c */
+/* */
+/* Multi-Precision Atan2(y,x) function subroutine, */
+/* for precision p >= 4. */
+/* y=0 is not permitted if x<=0. No error messages are given. */
+/* The relative error of the result is bounded by 44.84*r**(1-p) */
+/* if x <= 0, y != 0 and by 37.33*r**(1-p) if x>0. here r=2**24. */
+/* */
+/******************************************************************/
+
+
+
+#include "mpa.h"
+
+void __mpsqrt(mp_no *, mp_no *, int);
+void __mpatan(mp_no *, mp_no *, int);
+
+/* Multi-Precision Atan2(y,x) function subroutine, for p >= 4. */
+/* y=0 is not permitted if x<=0. No error messages are given. */
+void __mpatan2(mp_no *y, mp_no *x, mp_no *z, int p) {
+
+ static const double ZERO = 0.0, ONE = 1.0;
+
+ mp_no mpone = {0,{0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}};
+ mp_no mpt1,mpt2,mpt3;
+
+
+ if (X[0] <= ZERO) {
+ mpone.e = 1; mpone.d[0] = mpone.d[1] = ONE;
+ __dvd(x,y,&mpt1,p); __mul(&mpt1,&mpt1,&mpt2,p);
+ if (mpt1.d[0] != ZERO) mpt1.d[0] = ONE;
+ __add(&mpt2,&mpone,&mpt3,p); __mpsqrt(&mpt3,&mpt2,p);
+ __add(&mpt1,&mpt2,&mpt3,p); mpt3.d[0]=Y[0];
+ __mpatan(&mpt3,&mpt1,p); __add(&mpt1,&mpt1,z,p);
+ }
+ else
+ { __dvd(y,x,&mpt1,p);
+ __mpatan(&mpt1,z,p);
+ }
+
+ return;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/mpexp.c b/libc/sysdeps/ieee754/dbl-64/mpexp.c
new file mode 100644
index 000000000..e2ab71b2c
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mpexp.c
@@ -0,0 +1,105 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*************************************************************************/
+/* MODULE_NAME:mpexp.c */
+/* */
+/* FUNCTIONS: mpexp */
+/* */
+/* FILES NEEDED: mpa.h endian.h mpexp.h */
+/* mpa.c */
+/* */
+/* Multi-Precision exponential function subroutine */
+/* ( for p >= 4, 2**(-55) <= abs(x) <= 1024 ). */
+/*************************************************************************/
+
+#include "endian.h"
+#include "mpa.h"
+#include "mpexp.h"
+
+/* Multi-Precision exponential function subroutine (for p >= 4, */
+/* 2**(-55) <= abs(x) <= 1024). */
+void __mpexp(mp_no *x, mp_no *y, int p) {
+
+ int i,j,k,m,m1,m2,n;
+ double a,b;
+ static const int np[33] = {0,0,0,0,3,3,4,4,5,4,4,5,5,5,6,6,6,6,6,6,
+ 6,6,6,6,7,7,7,7,8,8,8,8,8};
+ static const int m1p[33]= {0,0,0,0,17,23,23,28,27,38,42,39,43,47,43,47,50,54,
+ 57,60,64,67,71,74,68,71,74,77,70,73,76,78,81};
+ static const int m1np[7][18] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0,36,48,60,72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0,24,32,40,48,56,64,72, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0,17,23,29,35,41,47,53,59,65, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0,23,28,33,38,42,47,52,57,62,66, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0,27, 0, 0,39,43,47,51,55,59,63},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,43,47,50,54}};
+ mp_no mpone = {0,{0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}};
+ mp_no mpk = {0,{0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}};
+ mp_no mps,mpak,mpt1,mpt2;
+
+ /* Choose m,n and compute a=2**(-m) */
+ n = np[p]; m1 = m1p[p]; a = twomm1[p].d;
+ for (i=0; i<EX; i++) a *= RADIXI;
+ for ( ; i>EX; i--) a *= RADIX;
+ b = X[1]*RADIXI; m2 = 24*EX;
+ for (; b<HALF; m2--) { a *= TWO; b *= TWO; }
+ if (b == HALF) {
+ for (i=2; i<=p; i++) { if (X[i]!=ZERO) break; }
+ if (i==p+1) { m2--; a *= TWO; }
+ }
+ if ((m=m1+m2) <= 0) {
+ m=0; a=ONE;
+ for (i=n-1; i>0; i--,n--) { if (m1np[i][p]+m2>0) break; }
+ }
+
+ /* Compute s=x*2**(-m). Put result in mps */
+ __dbl_mp(a,&mpt1,p);
+ __mul(x,&mpt1,&mps,p);
+
+ /* Evaluate the polynomial. Put result in mpt2 */
+ mpone.e=1; mpone.d[0]=ONE; mpone.d[1]=ONE;
+ mpk.e = 1; mpk.d[0] = ONE; mpk.d[1]=nn[n].d;
+ __dvd(&mps,&mpk,&mpt1,p);
+ __add(&mpone,&mpt1,&mpak,p);
+ for (k=n-1; k>1; k--) {
+ __mul(&mps,&mpak,&mpt1,p);
+ mpk.d[1]=nn[k].d;
+ __dvd(&mpt1,&mpk,&mpt2,p);
+ __add(&mpone,&mpt2,&mpak,p);
+ }
+ __mul(&mps,&mpak,&mpt1,p);
+ __add(&mpone,&mpt1,&mpt2,p);
+
+ /* Raise polynomial value to the power of 2**m. Put result in y */
+ for (k=0,j=0; k<m; ) {
+ __mul(&mpt2,&mpt2,&mpt1,p); k++;
+ if (k==m) { j=1; break; }
+ __mul(&mpt1,&mpt1,&mpt2,p); k++;
+ }
+ if (j) __cpy(&mpt1,y,p);
+ else __cpy(&mpt2,y,p);
+ return;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/mpexp.h b/libc/sysdeps/ieee754/dbl-64/mpexp.h
new file mode 100644
index 000000000..a0b08ccb4
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mpexp.h
@@ -0,0 +1,158 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/******************************************************************/
+/* */
+/* MODULE_NAME:mpexp.h */
+/* */
+/* common data and variables prototype and definition */
+/******************************************************************/
+
+#ifndef MPEXP_H
+#define MPEXP_H
+
+#ifdef BIG_ENDI
+ static const number
+ twomm1[33] = { /* 2**-m1 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x3ee00000, 0x00000000} }, /* 2**-17 */
+/**/ {{0x3e800000, 0x00000000} }, /* 2**-23 */
+/**/ {{0x3e800000, 0x00000000} }, /* 2**-23 */
+/**/ {{0x3e300000, 0x00000000} }, /* 2**-28 */
+/**/ {{0x3e400000, 0x00000000} }, /* 2**-27 */
+/**/ {{0x3d900000, 0x00000000} }, /* 2**-38 */
+/**/ {{0x3d500000, 0x00000000} }, /* 2**-42 */
+/**/ {{0x3d800000, 0x00000000} }, /* 2**-39 */
+/**/ {{0x3d400000, 0x00000000} }, /* 2**-43 */
+/**/ {{0x3d000000, 0x00000000} }, /* 2**-47 */
+/**/ {{0x3d400000, 0x00000000} }, /* 2**-43 */
+/**/ {{0x3d000000, 0x00000000} }, /* 2**-47 */
+/**/ {{0x3cd00000, 0x00000000} }, /* 2**-50 */
+/**/ {{0x3c900000, 0x00000000} }, /* 2**-54 */
+/**/ {{0x3c600000, 0x00000000} }, /* 2**-57 */
+/**/ {{0x3c300000, 0x00000000} }, /* 2**-60 */
+/**/ {{0x3bf00000, 0x00000000} }, /* 2**-64 */
+/**/ {{0x3bc00000, 0x00000000} }, /* 2**-67 */
+/**/ {{0x3b800000, 0x00000000} }, /* 2**-71 */
+/**/ {{0x3b500000, 0x00000000} }, /* 2**-74 */
+/**/ {{0x3bb00000, 0x00000000} }, /* 2**-68 */
+/**/ {{0x3b800000, 0x00000000} }, /* 2**-71 */
+/**/ {{0x3b500000, 0x00000000} }, /* 2**-74 */
+/**/ {{0x3b200000, 0x00000000} }, /* 2**-77 */
+/**/ {{0x3b900000, 0x00000000} }, /* 2**-70 */
+/**/ {{0x3b600000, 0x00000000} }, /* 2**-73 */
+/**/ {{0x3b300000, 0x00000000} }, /* 2**-76 */
+/**/ {{0x3b100000, 0x00000000} }, /* 2**-78 */
+/**/ {{0x3ae00000, 0x00000000} }, /* 2**-81 */
+ };
+ static const number
+ nn[9]={ /* n */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x3ff00000, 0x00000000} }, /* 1 */
+/**/ {{0x40000000, 0x00000000} }, /* 2 */
+/**/ {{0x40080000, 0x00000000} }, /* 3 */
+/**/ {{0x40100000, 0x00000000} }, /* 4 */
+/**/ {{0x40140000, 0x00000000} }, /* 5 */
+/**/ {{0x40180000, 0x00000000} }, /* 6 */
+/**/ {{0x401c0000, 0x00000000} }, /* 7 */
+/**/ {{0x40200000, 0x00000000} }, /* 8 */
+ };
+
+ static const number
+/**/ radix = {{0x41700000, 0x00000000} }, /* 2**24 */
+/**/ radixi = {{0x3e700000, 0x00000000} }, /* 2**-24 */
+/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */
+/**/ one = {{0x3ff00000, 0x00000000} }, /* 1 */
+/**/ two = {{0x40000000, 0x00000000} }, /* 2 */
+/**/ half = {{0x3fe00000, 0x00000000} }; /* 1/2 */
+
+#else
+#ifdef LITTLE_ENDI
+ static const number
+ twomm1[33] = { /* 2**-m1 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x3ee00000} }, /* 2**-17 */
+/**/ {{0x00000000, 0x3e800000} }, /* 2**-23 */
+/**/ {{0x00000000, 0x3e800000} }, /* 2**-23 */
+/**/ {{0x00000000, 0x3e300000} }, /* 2**-28 */
+/**/ {{0x00000000, 0x3e400000} }, /* 2**-27 */
+/**/ {{0x00000000, 0x3d900000} }, /* 2**-38 */
+/**/ {{0x00000000, 0x3d500000} }, /* 2**-42 */
+/**/ {{0x00000000, 0x3d800000} }, /* 2**-39 */
+/**/ {{0x00000000, 0x3d400000} }, /* 2**-43 */
+/**/ {{0x00000000, 0x3d000000} }, /* 2**-47 */
+/**/ {{0x00000000, 0x3d400000} }, /* 2**-43 */
+/**/ {{0x00000000, 0x3d000000} }, /* 2**-47 */
+/**/ {{0x00000000, 0x3cd00000} }, /* 2**-50 */
+/**/ {{0x00000000, 0x3c900000} }, /* 2**-54 */
+/**/ {{0x00000000, 0x3c600000} }, /* 2**-57 */
+/**/ {{0x00000000, 0x3c300000} }, /* 2**-60 */
+/**/ {{0x00000000, 0x3bf00000} }, /* 2**-64 */
+/**/ {{0x00000000, 0x3bc00000} }, /* 2**-67 */
+/**/ {{0x00000000, 0x3b800000} }, /* 2**-71 */
+/**/ {{0x00000000, 0x3b500000} }, /* 2**-74 */
+/**/ {{0x00000000, 0x3bb00000} }, /* 2**-68 */
+/**/ {{0x00000000, 0x3b800000} }, /* 2**-71 */
+/**/ {{0x00000000, 0x3b500000} }, /* 2**-74 */
+/**/ {{0x00000000, 0x3b200000} }, /* 2**-77 */
+/**/ {{0x00000000, 0x3b900000} }, /* 2**-70 */
+/**/ {{0x00000000, 0x3b600000} }, /* 2**-73 */
+/**/ {{0x00000000, 0x3b300000} }, /* 2**-76 */
+/**/ {{0x00000000, 0x3b100000} }, /* 2**-78 */
+/**/ {{0x00000000, 0x3ae00000} }, /* 2**-81 */
+ };
+ static const number
+ nn[9]={ /* n */
+/**/ {{0x00000000, 0x00000000} }, /* 0 */
+/**/ {{0x00000000, 0x3ff00000} }, /* 1 */
+/**/ {{0x00000000, 0x40000000} }, /* 2 */
+/**/ {{0x00000000, 0x40080000} }, /* 3 */
+/**/ {{0x00000000, 0x40100000} }, /* 4 */
+/**/ {{0x00000000, 0x40140000} }, /* 5 */
+/**/ {{0x00000000, 0x40180000} }, /* 6 */
+/**/ {{0x00000000, 0x401c0000} }, /* 7 */
+/**/ {{0x00000000, 0x40200000} }, /* 8 */
+ };
+
+ static const number
+/**/ radix = {{0x00000000, 0x41700000} }, /* 2**24 */
+/**/ radixi = {{0x00000000, 0x3e700000} }, /* 2**-24 */
+/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */
+/**/ one = {{0x00000000, 0x3ff00000} }, /* 1 */
+/**/ two = {{0x00000000, 0x40000000} }, /* 2 */
+/**/ half = {{0x00000000, 0x3fe00000} }; /* 1/2 */
+
+#endif
+#endif
+
+#define RADIX radix.d
+#define RADIXI radixi.d
+#define ZERO zero.d
+#define ONE one.d
+#define TWO two.d
+#define HALF half.d
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/mplog.c b/libc/sysdeps/ieee754/dbl-64/mplog.c
new file mode 100644
index 000000000..d9cb6a535
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mplog.c
@@ -0,0 +1,72 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/************************************************************************/
+/* */
+/* MODULE_NAME:mplog.c */
+/* */
+/* FUNCTIONS: mplog */
+/* */
+/* FILES NEEDED: endian.h mpa.h mplog.h */
+/* mpexp.c */
+/* */
+/* Multi-Precision logarithm function subroutine (for precision p >= 4, */
+/* 2**(-1024) < x < 2**1024) and x is outside of the interval */
+/* [1-2**(-54),1+2**(-54)]. Upon entry, x should be set to the */
+/* multi-precision value of the input and y should be set into a multi- */
+/* precision value of an approximation of log(x) with relative error */
+/* bound of at most 2**(-52). The routine improves the accuracy of y. */
+/* */
+/************************************************************************/
+#include "endian.h"
+#include "mpa.h"
+
+void __mpexp(mp_no *, mp_no *, int);
+
+void __mplog(mp_no *x, mp_no *y, int p) {
+#include "mplog.h"
+ int i,m;
+#if 0
+ int j,k,m1,m2,n;
+ double a,b;
+#endif
+ static const int mp[33] = {0,0,0,0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4};
+ mp_no mpone = {0,{0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}};
+ mp_no mpt1,mpt2;
+
+ /* Choose m and initiate mpone */
+ m = mp[p]; mpone.e = 1; mpone.d[0]=mpone.d[1]=ONE;
+
+ /* Perform m newton iterations to solve for y: exp(y)-x=0. */
+ /* The iterations formula is: y(n+1)=y(n)+(x*exp(-y(n))-1). */
+ __cpy(y,&mpt1,p);
+ for (i=0; i<m; i++) {
+ mpt1.d[0]=-mpt1.d[0];
+ __mpexp(&mpt1,&mpt2,p);
+ __mul(x,&mpt2,&mpt1,p);
+ __sub(&mpt1,&mpone,&mpt2,p);
+ __add(y,&mpt2,&mpt1,p);
+ __cpy(&mpt1,y,p);
+ }
+ return;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/mplog.h b/libc/sysdeps/ieee754/dbl-64/mplog.h
new file mode 100644
index 000000000..336a8ecca
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mplog.h
@@ -0,0 +1,45 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/******************************************************************/
+/* */
+/* MODULE_NAME:mplog.h */
+/* */
+/* common data and variables prototype and definition */
+/******************************************************************/
+
+#ifndef MPLOG_H
+#define MPLOG_H
+
+#ifdef BIG_ENDI
+ static const number
+/**/ one = {{0x3ff00000, 0x00000000} }; /* 1 */
+
+#else
+#ifdef LITTLE_ENDI
+ static const number
+/**/ one = {{0x00000000, 0x3ff00000} }; /* 1 */
+
+#endif
+#endif
+
+#define ONE one.d
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/mpn2dbl.c b/libc/sysdeps/ieee754/dbl-64/mpn2dbl.c
new file mode 100644
index 000000000..2af3092ce
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mpn2dbl.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1995,1996,1997,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include <ieee754.h>
+#include <float.h>
+
+/* Convert a multi-precision integer of the needed number of bits (53 for
+ double) and an integral power of two to a `double' in IEEE754 double-
+ precision format. */
+
+double
+__mpn_construct_double (mp_srcptr frac_ptr, int expt, int negative)
+{
+ union ieee754_double u;
+
+ u.ieee.negative = negative;
+ u.ieee.exponent = expt + IEEE754_DOUBLE_BIAS;
+#if BITS_PER_MP_LIMB == 32
+ u.ieee.mantissa1 = frac_ptr[0];
+ u.ieee.mantissa0 = frac_ptr[1] & (((mp_limb_t) 1
+ << (DBL_MANT_DIG - 32)) - 1);
+#elif BITS_PER_MP_LIMB == 64
+ u.ieee.mantissa1 = frac_ptr[0] & (((mp_limb_t) 1 << 32) - 1);
+ u.ieee.mantissa0 = (frac_ptr[0] >> 32) & (((mp_limb_t) 1
+ << (DBL_MANT_DIG - 32)) - 1);
+#else
+ #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+
+ return u.d;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/mpsqrt.c b/libc/sysdeps/ieee754/dbl-64/mpsqrt.c
new file mode 100644
index 000000000..9945de306
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mpsqrt.c
@@ -0,0 +1,103 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/****************************************************************************/
+/* MODULE_NAME:mpsqrt.c */
+/* */
+/* FUNCTION:mpsqrt */
+/* fastiroot */
+/* */
+/* FILES NEEDED:endian.h mpa.h mpsqrt.h */
+/* mpa.c */
+/* Multi-Precision square root function subroutine for precision p >= 4. */
+/* The relative error is bounded by 3.501*r**(1-p), where r=2**24. */
+/* */
+/****************************************************************************/
+#include "endian.h"
+#include "mpa.h"
+
+/****************************************************************************/
+/* Multi-Precision square root function subroutine for precision p >= 4. */
+/* The relative error is bounded by 3.501*r**(1-p), where r=2**24. */
+/* Routine receives two pointers to Multi Precision numbers: */
+/* x (left argument) and y (next argument). Routine also receives precision */
+/* p as integer. Routine computes sqrt(*x) and stores result in *y */
+/****************************************************************************/
+
+double fastiroot(double);
+
+void __mpsqrt(mp_no *x, mp_no *y, int p) {
+#include "mpsqrt.h"
+
+ int i,m,ex,ey;
+ double dx,dy;
+ mp_no
+ mphalf = {0,{0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}},
+ mp3halfs = {0,{0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}};
+ mp_no mpxn,mpz,mpu,mpt1,mpt2;
+
+ /* Prepare multi-precision 1/2 and 3/2 */
+ mphalf.e =0; mphalf.d[0] =ONE; mphalf.d[1] =HALFRAD;
+ mp3halfs.e=1; mp3halfs.d[0]=ONE; mp3halfs.d[1]=ONE; mp3halfs.d[2]=HALFRAD;
+
+ ex=EX; ey=EX/2; __cpy(x,&mpxn,p); mpxn.e -= (ey+ey);
+ __mp_dbl(&mpxn,&dx,p); dy=fastiroot(dx); __dbl_mp(dy,&mpu,p);
+ __mul(&mpxn,&mphalf,&mpz,p);
+
+ m=mp[p];
+ for (i=0; i<m; i++) {
+ __mul(&mpu,&mpu,&mpt1,p);
+ __mul(&mpt1,&mpz,&mpt2,p);
+ __sub(&mp3halfs,&mpt2,&mpt1,p);
+ __mul(&mpu,&mpt1,&mpt2,p);
+ __cpy(&mpt2,&mpu,p);
+ }
+ __mul(&mpxn,&mpu,y,p); EY += ey;
+
+ return;
+}
+
+/***********************************************************/
+/* Compute a double precision approximation for 1/sqrt(x) */
+/* with the relative error bounded by 2**-51. */
+/***********************************************************/
+double fastiroot(double x) {
+ union {int i[2]; double d;} p,q;
+ double y,z, t;
+ int n;
+ static const double c0 = 0.99674, c1 = -0.53380, c2 = 0.45472, c3 = -0.21553;
+
+ p.d = x;
+ p.i[HIGH_HALF] = (p.i[HIGH_HALF] & 0x3FFFFFFF ) | 0x3FE00000 ;
+ q.d = x;
+ y = p.d;
+ z = y -1.0;
+ n = (q.i[HIGH_HALF] - p.i[HIGH_HALF])>>1;
+ z = ((c3*z + c2)*z + c1)*z + c0; /* 2**-7 */
+ z = z*(1.5 - 0.5*y*z*z); /* 2**-14 */
+ p.d = z*(1.5 - 0.5*y*z*z); /* 2**-28 */
+ p.i[HIGH_HALF] -= n;
+ t = x*p.d;
+ return p.d*(1.5 - 0.5*p.d*t);
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/mpsqrt.h b/libc/sysdeps/ieee754/dbl-64/mpsqrt.h
new file mode 100644
index 000000000..729d57af2
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mpsqrt.h
@@ -0,0 +1,51 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/******************************************************************/
+/* */
+/* MODULE_NAME:mpatan.h */
+/* */
+/* common data and variables prototype and definition */
+/******************************************************************/
+
+#ifndef MPSQRT_H
+#define MPSQRT_H
+
+#ifdef BIG_ENDI
+ static const number
+/**/ one = {{0x3ff00000, 0x00000000} }, /* 1 */
+/**/ halfrad = {{0x41600000, 0x00000000} }; /* 2**23 */
+
+#else
+#ifdef LITTLE_ENDI
+ static const number
+/**/ one = {{0x00000000, 0x3ff00000} }, /* 1 */
+/**/ halfrad = {{0x00000000, 0x41600000} }; /* 2**23 */
+
+#endif
+#endif
+
+#define ONE one.d
+#define HALFRAD halfrad.d
+
+ static const int mp[33] = {0,0,0,0,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,
+ 4,4,4,4,4,4,4,4,4};
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/mptan.c b/libc/sysdeps/ieee754/dbl-64/mptan.c
new file mode 100644
index 000000000..267445a19
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mptan.c
@@ -0,0 +1,60 @@
+
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/**********************************************************************/
+/* MODULE_NAME:mptan.c */
+/* */
+/* FUNCTION: mptan */
+/* */
+/* FILES NEEDED: endian.h mpa.h */
+/* mpa.c sincos32.c branred.c */
+/* */
+/* Multi-Precision tan() function subroutine, for p=32. It is based */
+/* on the routines mpranred() and c32(). mpranred() performs range */
+/* reduction of a double number x into a multiple precision number */
+/* y, such that y=x-n*pi/2, abs(y)<pi/4, n=0,+-1,+-2,.... c32() */
+/* computes both sin(y), cos(y). tan(x) is either sin(y)/cos(y) */
+/* or -cos(y)/sin(y). The precision of the result is of about 559 */
+/* significant bits. */
+/* */
+/**********************************************************************/
+#include "endian.h"
+#include "mpa.h"
+
+int __mpranred(double, mp_no *, int);
+void __c32(mp_no *, mp_no *, mp_no *, int);
+
+void __mptan(double x, mp_no *mpy, int p) {
+
+ static const double MONE = -1.0;
+
+ int n;
+ mp_no mpw, mpc, mps;
+
+ n = __mpranred(x, &mpw, p) & 0x00000001; /* negative or positive result */
+ __c32(&mpw, &mpc, &mps, p); /* computing sin(x) and cos(x) */
+ if (n) /* second or fourth quarter of unit circle */
+ { __dvd(&mpc,&mps,mpy,p);
+ mpy->d[0] *= MONE;
+ } /* tan is negative in this area */
+ else __dvd(&mps,&mpc,mpy,p);
+
+ return;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/mydefs.h b/libc/sysdeps/ieee754/dbl-64/mydefs.h
new file mode 100644
index 000000000..a47f2b506
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/mydefs.h
@@ -0,0 +1,38 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/******************************************************************/
+/* */
+/* MODULE_NAME:mydefs.h */
+/* */
+/* common data and definition */
+/******************************************************************/
+
+#ifndef MY_H
+#define MY_H
+
+typedef int int4;
+typedef union {int4 i[2]; double x;} mynumber;
+
+#define ABS(x) (((x)>0)?(x):-(x))
+#define max(x,y) (((y)>(x))?(y):(x))
+#define min(x,y) (((y)<(x))?(y):(x))
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/powtwo.tbl b/libc/sysdeps/ieee754/dbl-64/powtwo.tbl
new file mode 100644
index 000000000..53c49c10f
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/powtwo.tbl
@@ -0,0 +1,32 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/****************************************************************/
+/* TABLES FOR THE upow() FUNCTION */
+/****************************************************************/
+
+
+
+static const double powtwo[] = { 1.0, 2.0, 4.0,
+ 8.0, 16.0, 32.0, 64.0, 128.0,
+ 256.0, 512.0, 1024.0, 2048.0, 4096.0,
+ 8192.0, 16384.0, 32768.0, 65536.0, 131072.0,
+ 262144.0, 524288.0, 1048576.0, 2097152.0, 4194304.0,
+ 8388608.0, 16777216.0, 33554432.0, 67108864.0, 134217728.0 };
diff --git a/libc/sysdeps/ieee754/dbl-64/root.tbl b/libc/sysdeps/ieee754/dbl-64/root.tbl
new file mode 100644
index 000000000..066e588ce
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/root.tbl
@@ -0,0 +1,58 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/****************************************************************/
+/* TABLES FOR THE usqrt() FUNCTION */
+/****************************************************************/
+
+
+static const double inroot[128] = {
+ 1.40872145012100, 1.39792649065766, 1.38737595123859, 1.37706074531819,
+ 1.36697225234682, 1.35710228748795, 1.34744307370643, 1.33798721601135,
+ 1.32872767765984, 1.31965775814772, 1.31077107283046, 1.30206153403386,
+ 1.29352333352711, 1.28515092624400, 1.27693901514820, 1.26888253714903,
+ 1.26097664998256, 1.25321671998073, 1.24559831065844, 1.23811717205462,
+ 1.23076923076923, 1.22355058064300, 1.21645747403153, 1.20948631362953,
+ 1.20263364480453, 1.19589614840310, 1.18927063399547, 1.18275403352732,
+ 1.17634339535009, 1.17003587860341, 1.16382874792529, 1.15771936846787,
+ 1.15170520119791, 1.14578379846309, 1.13995279980655, 1.13420992801334,
+ 1.12855298537376, 1.12297985014975, 1.11748847323133, 1.11207687497107,
+ 1.10674314218572, 1.10148542531442, 1.09630193572405, 1.09119094315276,
+ 1.08615077328341, 1.08117980543918, 1.07627647039410, 1.07143924829188,
+ 1.06666666666667, 1.06195729855996, 1.05730976072814, 1.05272271193563,
+ 1.04819485132867, 1.04372491688551, 1.03931168393861, 1.03495396376504,
+ 1.03065060224133, 1.02640047855933, 1.02220250399990, 1.01805562076124,
+ 1.01395880083916, 1.00991104495649, 1.00591138153909, 1.00195886573624,
+ 0.99611649018350, 0.98848330114434, 0.98102294317595, 0.97372899112030,
+ 0.96659534932828, 0.95961623024651, 0.95278613468066, 0.94609983358253,
+ 0.93955235122353, 0.93313894963169, 0.92685511418159, 0.92069654023750,
+ 0.91465912076005, 0.90873893479530, 0.90293223677296, 0.89723544654727,
+ 0.89164514012056, 0.88615804099474, 0.88077101210109, 0.87548104826333,
+ 0.87028526915267, 0.86518091269740, 0.86016532891275, 0.85523597411976,
+ 0.85039040552437, 0.84562627613070, 0.84094132996422, 0.83633339758291,
+ 0.83180039185606, 0.82734030399203, 0.82295119979782, 0.81863121615464,
+ 0.81437855769486, 0.81019149366693, 0.80606835497581, 0.80200753138734,
+ 0.79800746888611, 0.79406666717674, 0.79018367731967, 0.78635709949278,
+ 0.78258558087123, 0.77886781361798, 0.77520253297841, 0.77158851547266,
+ 0.76802457717971, 0.76450957210799, 0.76104239064719, 0.75762195809661,
+ 0.75424723326565, 0.75091720714229, 0.74763090162560, 0.74438736831878,
+ 0.74118568737933, 0.73802496642311, 0.73490433947940, 0.73182296599416,
+ 0.72878002987884, 0.72577473860242, 0.72280632232420, 0.71987403306536,
+ 0.71697714391715, 0.71411494828392, 0.71128675915902, 0.70849190843208 };
diff --git a/libc/sysdeps/ieee754/dbl-64/s_asinh.c b/libc/sysdeps/ieee754/dbl-64/s_asinh.c
new file mode 100644
index 000000000..985cfe32e
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_asinh.c
@@ -0,0 +1,70 @@
+/* @(#)s_asinh.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_asinh.c,v 1.9 1995/05/12 04:57:37 jtc Exp $";
+#endif
+
+/* asinh(x)
+ * Method :
+ * Based on
+ * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
+ * we have
+ * asinh(x) := x if 1+x*x=1,
+ * := sign(x)*(log(x)+ln2)) for large |x|, else
+ * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
+ * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+ln2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+huge= 1.00000000000000000000e+300;
+
+#ifdef __STDC__
+ double __asinh(double x)
+#else
+ double __asinh(x)
+ double x;
+#endif
+{
+ double t,w;
+ int32_t hx,ix;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) return x+x; /* x is inf or NaN */
+ if(ix< 0x3e300000) { /* |x|<2**-28 */
+ if(huge+x>one) return x; /* return x inexact except 0 */
+ }
+ if(ix>0x41b00000) { /* |x| > 2**28 */
+ w = __ieee754_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));
+ } else { /* 2.0 > |x| > 2**-28 */
+ t = x*x;
+ w =__log1p(fabs(x)+t/(one+__ieee754_sqrt(one+t)));
+ }
+ if(hx>0) return w; else return -w;
+}
+weak_alias (__asinh, asinh)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__asinh, __asinhl)
+weak_alias (__asinh, asinhl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_atan.c b/libc/sysdeps/ieee754/dbl-64/s_atan.c
new file mode 100644
index 000000000..556f5b216
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_atan.c
@@ -0,0 +1,230 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/************************************************************************/
+/* MODULE_NAME: atnat.c */
+/* */
+/* FUNCTIONS: uatan */
+/* atanMp */
+/* signArctan */
+/* */
+/* */
+/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h atnat.h */
+/* mpatan.c mpatan2.c mpsqrt.c */
+/* uatan.tbl */
+/* */
+/* An ultimate atan() routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of atan(x). */
+/* */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round to nearest mode of IEEE 754 standard. */
+/* */
+/************************************************************************/
+
+#include "dla.h"
+#include "mpa.h"
+#include "MathLib.h"
+#include "uatan.tbl"
+#include "atnat.h"
+#include "math.h"
+
+void __mpatan(mp_no *,mp_no *,int); /* see definition in mpatan.c */
+static double atanMp(double,const int[]);
+double __signArctan(double,double);
+/* An ultimate atan() routine. Given an IEEE double machine number x, */
+/* routine computes the correctly rounded (to nearest) value of atan(x). */
+double atan(double x) {
+
+
+ double cor,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,u,u2,u3,
+ v,vv,w,ww,y,yy,z,zz;
+#if 0
+ double y1,y2;
+#endif
+ int i,ux,dx;
+#if 0
+ int p;
+#endif
+ static const int pr[M]={6,8,10,32};
+ number num;
+#if 0
+ mp_no mpt1,mpx,mpy,mpy1,mpy2,mperr;
+#endif
+
+ num.d = x; ux = num.i[HIGH_HALF]; dx = num.i[LOW_HALF];
+
+ /* x=NaN */
+ if (((ux&0x7ff00000)==0x7ff00000) && (((ux&0x000fffff)|dx)!=0x00000000))
+ return x+x;
+
+ /* Regular values of x, including denormals +-0 and +-INF */
+ u = (x<ZERO) ? -x : x;
+ if (u<C) {
+ if (u<B) {
+ if (u<A) { /* u < A */
+ return x; }
+ else { /* A <= u < B */
+ v=x*x; yy=x*v*(d3.d+v*(d5.d+v*(d7.d+v*(d9.d+v*(d11.d+v*d13.d)))));
+ if ((y=x+(yy-U1*x)) == x+(yy+U1*x)) return y;
+
+ EMULV(x,x,v,vv,t1,t2,t3,t4,t5) /* v+vv=x^2 */
+ s1=v*(f11.d+v*(f13.d+v*(f15.d+v*(f17.d+v*f19.d))));
+ ADD2(f9.d,ff9.d,s1,ZERO,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f7.d,ff7.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f5.d,ff5.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f3.d,ff3.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(x,ZERO,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(x,ZERO,s2,ss2,s1,ss1,t1,t2)
+ if ((y=s1+(ss1-U5*s1)) == s1+(ss1+U5*s1)) return y;
+
+ return atanMp(x,pr);
+ } }
+ else { /* B <= u < C */
+ i=(TWO52+TWO8*u)-TWO52; i-=16;
+ z=u-cij[i][0].d;
+ yy=z*(cij[i][2].d+z*(cij[i][3].d+z*(cij[i][4].d+
+ z*(cij[i][5].d+z* cij[i][6].d))));
+ t1=cij[i][1].d;
+ if (i<112) {
+ if (i<48) u2=U21; /* u < 1/4 */
+ else u2=U22; } /* 1/4 <= u < 1/2 */
+ else {
+ if (i<176) u2=U23; /* 1/2 <= u < 3/4 */
+ else u2=U24; } /* 3/4 <= u <= 1 */
+ if ((y=t1+(yy-u2*t1)) == t1+(yy+u2*t1)) return __signArctan(x,y);
+
+ z=u-hij[i][0].d;
+ s1=z*(hij[i][11].d+z*(hij[i][12].d+z*(hij[i][13].d+
+ z*(hij[i][14].d+z* hij[i][15].d))));
+ ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2)
+ MUL2(z,ZERO,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(z,ZERO,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][5].d,hij[i][6].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(z,ZERO,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][3].d,hij[i][4].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(z,ZERO,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][1].d,hij[i][2].d,s1,ss1,s2,ss2,t1,t2)
+ if ((y=s2+(ss2-U6*s2)) == s2+(ss2+U6*s2)) return __signArctan(x,y);
+
+ return atanMp(x,pr);
+ }
+ }
+ else {
+ if (u<D) { /* C <= u < D */
+ w=ONE/u;
+ EMULV(w,u,t1,t2,t3,t4,t5,t6,t7)
+ ww=w*((ONE-t1)-t2);
+ i=(TWO52+TWO8*w)-TWO52; i-=16;
+ z=(w-cij[i][0].d)+ww;
+ yy=HPI1-z*(cij[i][2].d+z*(cij[i][3].d+z*(cij[i][4].d+
+ z*(cij[i][5].d+z* cij[i][6].d))));
+ t1=HPI-cij[i][1].d;
+ if (i<112) u3=U31; /* w < 1/2 */
+ else u3=U32; /* w >= 1/2 */
+ if ((y=t1+(yy-u3)) == t1+(yy+u3)) return __signArctan(x,y);
+
+ DIV2(ONE,ZERO,u,ZERO,w,ww,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ t1=w-hij[i][0].d;
+ EADD(t1,ww,z,zz)
+ s1=z*(hij[i][11].d+z*(hij[i][12].d+z*(hij[i][13].d+
+ z*(hij[i][14].d+z* hij[i][15].d))));
+ ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2)
+ MUL2(z,zz,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(z,zz,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][5].d,hij[i][6].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(z,zz,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][3].d,hij[i][4].d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(z,zz,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(hij[i][1].d,hij[i][2].d,s1,ss1,s2,ss2,t1,t2)
+ SUB2(HPI,HPI1,s2,ss2,s1,ss1,t1,t2)
+ if ((y=s1+(ss1-U7)) == s1+(ss1+U7)) return __signArctan(x,y);
+
+ return atanMp(x,pr);
+ }
+ else {
+ if (u<E) { /* D <= u < E */
+ w=ONE/u; v=w*w;
+ EMULV(w,u,t1,t2,t3,t4,t5,t6,t7)
+ yy=w*v*(d3.d+v*(d5.d+v*(d7.d+v*(d9.d+v*(d11.d+v*d13.d)))));
+ ww=w*((ONE-t1)-t2);
+ ESUB(HPI,w,t3,cor)
+ yy=((HPI1+cor)-ww)-yy;
+ if ((y=t3+(yy-U4)) == t3+(yy+U4)) return __signArctan(x,y);
+
+ DIV2(ONE,ZERO,u,ZERO,w,ww,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ MUL2(w,ww,w,ww,v,vv,t1,t2,t3,t4,t5,t6,t7,t8)
+ s1=v*(f11.d+v*(f13.d+v*(f15.d+v*(f17.d+v*f19.d))));
+ ADD2(f9.d,ff9.d,s1,ZERO,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f7.d,ff7.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f5.d,ff5.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(f3.d,ff3.d,s1,ss1,s2,ss2,t1,t2)
+ MUL2(v,vv,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(w,ww,s1,ss1,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(w,ww,s2,ss2,s1,ss1,t1,t2)
+ SUB2(HPI,HPI1,s1,ss1,s2,ss2,t1,t2)
+ if ((y=s2+(ss2-U8)) == s2+(ss2+U8)) return __signArctan(x,y);
+
+ return atanMp(x,pr);
+ }
+ else {
+ /* u >= E */
+ if (x>0) return HPI;
+ else return MHPI; }
+ }
+ }
+
+}
+
+
+ /* Fix the sign of y and return */
+double __signArctan(double x,double y){
+
+ if (x<ZERO) return -y;
+ else return y;
+}
+
+ /* Final stages. Compute atan(x) by multiple precision arithmetic */
+static double atanMp(double x,const int pr[]){
+ mp_no mpx,mpy,mpy2,mperr,mpt1,mpy1;
+ double y1,y2;
+ int i,p;
+
+for (i=0; i<M; i++) {
+ p = pr[i];
+ __dbl_mp(x,&mpx,p); __mpatan(&mpx,&mpy,p);
+ __dbl_mp(u9[i].d,&mpt1,p); __mul(&mpy,&mpt1,&mperr,p);
+ __add(&mpy,&mperr,&mpy1,p); __sub(&mpy,&mperr,&mpy2,p);
+ __mp_dbl(&mpy1,&y1,p); __mp_dbl(&mpy2,&y2,p);
+ if (y1==y2) return y1;
+ }
+ return y1; /*if unpossible to do exact computing */
+}
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (atan, atanl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_cbrt.c b/libc/sysdeps/ieee754/dbl-64/s_cbrt.c
new file mode 100644
index 000000000..22a1984e2
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_cbrt.c
@@ -0,0 +1,76 @@
+/* Compute cubic root of double value.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
+ Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#define CBRT2 1.2599210498948731648 /* 2^(1/3) */
+#define SQR_CBRT2 1.5874010519681994748 /* 2^(2/3) */
+
+static const double factor[5] =
+{
+ 1.0 / SQR_CBRT2,
+ 1.0 / CBRT2,
+ 1.0,
+ CBRT2,
+ SQR_CBRT2
+};
+
+
+double
+__cbrt (double x)
+{
+ double xm, ym, u, t2;
+ int xe;
+
+ /* Reduce X. XM now is an range 1.0 to 0.5. */
+ xm = __frexp (fabs (x), &xe);
+
+ /* If X is not finite or is null return it (with raising exceptions
+ if necessary.
+ Note: *Our* version of `frexp' sets XE to zero if the argument is
+ Inf or NaN. This is not portable but faster. */
+ if (xe == 0 && fpclassify (x) <= FP_ZERO)
+ return x + x;
+
+ u = (0.354895765043919860
+ + ((1.50819193781584896
+ + ((-2.11499494167371287
+ + ((2.44693122563534430
+ + ((-1.83469277483613086
+ + (0.784932344976639262 - 0.145263899385486377 * xm) * xm)
+ * xm))
+ * xm))
+ * xm))
+ * xm));
+
+ t2 = u * u * u;
+
+ ym = u * (t2 + 2.0 * xm) / (2.0 * t2 + xm) * factor[2 + xe % 3];
+
+ return __ldexp (x > 0.0 ? ym : -ym, xe / 3);
+}
+weak_alias (__cbrt, cbrt)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__cbrt, __cbrtl)
+weak_alias (__cbrt, cbrtl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_ceil.c b/libc/sysdeps/ieee754/dbl-64/s_ceil.c
new file mode 100644
index 000000000..1b352a679
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_ceil.c
@@ -0,0 +1,85 @@
+/* @(#)s_ceil.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_ceil.c,v 1.8 1995/05/10 20:46:53 jtc Exp $";
+#endif
+
+/*
+ * ceil(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to ceil(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double huge = 1.0e300;
+#else
+static double huge = 1.0e300;
+#endif
+
+#ifdef __STDC__
+ double __ceil(double x)
+#else
+ double __ceil(x)
+ double x;
+#endif
+{
+ int32_t i0,i1,j0;
+ u_int32_t i,j;
+ EXTRACT_WORDS(i0,i1,x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0<0) {i0=0x80000000;i1=0;}
+ else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
+ }
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0>0) i0 += (0x00100000)>>j0;
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0>0) {
+ if(j0==20) i0+=1;
+ else {
+ j = i1 + (1<<(52-j0));
+ if(j<i1) i0+=1; /* got a carry */
+ i1 = j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ INSERT_WORDS(x,i0,i1);
+ return x;
+}
+weak_alias (__ceil, ceil)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__ceil, __ceill)
+weak_alias (__ceil, ceill)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_copysign.c b/libc/sysdeps/ieee754/dbl-64/s_copysign.c
new file mode 100644
index 000000000..5e35e6943
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_copysign.c
@@ -0,0 +1,43 @@
+/* @(#)s_copysign.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_copysign.c,v 1.8 1995/05/10 20:46:57 jtc Exp $";
+#endif
+
+/*
+ * copysign(double x, double y)
+ * copysign(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __copysign(double x, double y)
+#else
+ double __copysign(x,y)
+ double x,y;
+#endif
+{
+ u_int32_t hx,hy;
+ GET_HIGH_WORD(hx,x);
+ GET_HIGH_WORD(hy,y);
+ SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
+ return x;
+}
+weak_alias (__copysign, copysign)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__copysign, __copysignl)
+weak_alias (__copysign, copysignl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_cos.c b/libc/sysdeps/ieee754/dbl-64/s_cos.c
new file mode 100644
index 000000000..4be1276cc
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_cos.c
@@ -0,0 +1 @@
+/* In s_sin.c. */
diff --git a/libc/sysdeps/ieee754/dbl-64/s_erf.c b/libc/sysdeps/ieee754/dbl-64/s_erf.c
new file mode 100644
index 000000000..94fb5c964
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_erf.c
@@ -0,0 +1,431 @@
+/* @(#)s_erf.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.
+ * ====================================================
+ */
+/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25,
+ for performance improvement on pipelined processors.
+*/
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: s_erf.c,v 1.8 1995/05/10 20:47:05 jtc Exp $";
+#endif
+
+/* double erf(double x)
+ * double erfc(double x)
+ * x
+ * 2 |\
+ * erf(x) = --------- | exp(-t*t)dt
+ * sqrt(pi) \|
+ * 0
+ *
+ * erfc(x) = 1-erf(x)
+ * Note that
+ * erf(-x) = -erf(x)
+ * erfc(-x) = 2 - erfc(x)
+ *
+ * Method:
+ * 1. For |x| in [0, 0.84375]
+ * erf(x) = x + x*R(x^2)
+ * erfc(x) = 1 - erf(x) if x in [-.84375,0.25]
+ * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375]
+ * where R = P/Q where P is an odd poly of degree 8 and
+ * Q is an odd poly of degree 10.
+ * -57.90
+ * | R - (erf(x)-x)/x | <= 2
+ *
+ *
+ * Remark. The formula is derived by noting
+ * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ * and that
+ * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ * is close to one. The interval is chosen because the fix
+ * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
+ * near 0.6174), and by some experiment, 0.84375 is chosen to
+ * guarantee the error is less than one ulp for erf.
+ *
+ * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and
+ * c = 0.84506291151 rounded to single (24 bits)
+ * erf(x) = sign(x) * (c + P1(s)/Q1(s))
+ * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0
+ * 1+(c+P1(s)/Q1(s)) if x < 0
+ * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06
+ * Remark: here we use the taylor series expansion at x=1.
+ * erf(1+s) = erf(1) + s*Poly(s)
+ * = 0.845.. + P1(s)/Q1(s)
+ * That is, we use rational approximation to approximate
+ * erf(1+s) - (c = (single)0.84506291151)
+ * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ * where
+ * P1(s) = degree 6 poly in s
+ * Q1(s) = degree 6 poly in s
+ *
+ * 3. For x in [1.25,1/0.35(~2.857143)],
+ * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)
+ * erf(x) = 1 - erfc(x)
+ * where
+ * R1(z) = degree 7 poly in z, (z=1/x^2)
+ * S1(z) = degree 8 poly in z
+ *
+ * 4. For x in [1/0.35,28]
+ * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
+ * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0
+ * = 2.0 - tiny (if x <= -6)
+ * erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6, else
+ * erf(x) = sign(x)*(1.0 - tiny)
+ * where
+ * R2(z) = degree 6 poly in z, (z=1/x^2)
+ * S2(z) = degree 7 poly in z
+ *
+ * Note1:
+ * To compute exp(-x*x-0.5625+R/S), let s be a single
+ * precision number and s := x; then
+ * -x*x = -s*s + (s-x)*(s+x)
+ * exp(-x*x-0.5626+R/S) =
+ * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
+ * Note2:
+ * Here 4 and 5 make use of the asymptotic series
+ * exp(-x*x)
+ * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
+ * x*sqrt(pi)
+ * We use rational approximation to approximate
+ * g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625
+ * Here is the error bound for R1/S1 and R2/S2
+ * |R1/S1 - f(x)| < 2**(-62.57)
+ * |R2/S2 - f(x)| < 2**(-61.52)
+ *
+ * 5. For inf > x >= 28
+ * erf(x) = sign(x) *(1 - tiny) (raise inexact)
+ * erfc(x) = tiny*tiny (raise underflow) if x > 0
+ * = 2 - tiny if x<0
+ *
+ * 7. Special case:
+ * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
+ * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
+ * erfc/erf(NaN) is NaN
+ */
+
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+tiny = 1e-300,
+half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
+ /* c = (float)0.84506291151 */
+erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */
+/*
+ * Coefficients for approximation to erf on [0,0.84375]
+ */
+efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */
+efx8= 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */
+pp[] = {1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */
+ -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */
+ -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */
+ -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */
+ -2.37630166566501626084e-05}, /* 0xBEF8EAD6, 0x120016AC */
+qq[] = {0.0, 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */
+ 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */
+ 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */
+ 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */
+ -3.96022827877536812320e-06}, /* 0xBED09C43, 0x42A26120 */
+/*
+ * Coefficients for approximation to erf in [0.84375,1.25]
+ */
+pa[] = {-2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */
+ 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */
+ -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */
+ 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */
+ -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */
+ 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */
+ -2.16637559486879084300e-03}, /* 0xBF61BF38, 0x0A96073F */
+qa[] = {0.0, 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */
+ 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */
+ 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */
+ 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */
+ 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */
+ 1.19844998467991074170e-02}, /* 0x3F888B54, 0x5735151D */
+/*
+ * Coefficients for approximation to erfc in [1.25,1/0.35]
+ */
+ra[] = {-9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */
+ -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */
+ -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */
+ -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */
+ -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */
+ -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */
+ -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */
+ -9.81432934416914548592e+00}, /* 0xC023A0EF, 0xC69AC25C */
+sa[] = {0.0,1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */
+ 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */
+ 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */
+ 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */
+ 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */
+ 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */
+ 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */
+ -6.04244152148580987438e-02}, /* 0xBFAEEFF2, 0xEE749A62 */
+/*
+ * Coefficients for approximation to erfc in [1/.35,28]
+ */
+rb[] = {-9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */
+ -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */
+ -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */
+ -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */
+ -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */
+ -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */
+ -4.83519191608651397019e+02}, /* 0xC07E384E, 0x9BDC383F */
+sb[] = {0.0,3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */
+ 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */
+ 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */
+ 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */
+ 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */
+ 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */
+ -2.24409524465858183362e+01}; /* 0xC03670E2, 0x42712D62 */
+
+#ifdef __STDC__
+ double __erf(double x)
+#else
+ double __erf(x)
+ double x;
+#endif
+{
+ int32_t hx,ix,i;
+ double R,S,P,Q,s,y,z,r;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) { /* erf(nan)=nan */
+ i = ((u_int32_t)hx>>31)<<1;
+ return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */
+ }
+
+ if(ix < 0x3feb0000) { /* |x|<0.84375 */
+ double r1,r2,s1,s2,s3,z2,z4;
+ if(ix < 0x3e300000) { /* |x|<2**-28 */
+ if (ix < 0x00800000)
+ return 0.125*(8.0*x+efx8*x); /*avoid underflow */
+ return x + efx*x;
+ }
+ z = x*x;
+#ifdef DO_NOT_USE_THIS
+ r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+ s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+#else
+ r1 = pp[0]+z*pp[1]; z2=z*z;
+ r2 = pp[2]+z*pp[3]; z4=z2*z2;
+ s1 = one+z*qq[1];
+ s2 = qq[2]+z*qq[3];
+ s3 = qq[4]+z*qq[5];
+ r = r1 + z2*r2 + z4*pp[4];
+ s = s1 + z2*s2 + z4*s3;
+#endif
+ y = r/s;
+ return x + x*y;
+ }
+ if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */
+ double s2,s4,s6,P1,P2,P3,P4,Q1,Q2,Q3,Q4;
+ s = fabs(x)-one;
+#ifdef DO_NOT_USE_THIS
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+#else
+ P1 = pa[0]+s*pa[1]; s2=s*s;
+ Q1 = one+s*qa[1]; s4=s2*s2;
+ P2 = pa[2]+s*pa[3]; s6=s4*s2;
+ Q2 = qa[2]+s*qa[3];
+ P3 = pa[4]+s*pa[5];
+ Q3 = qa[4]+s*qa[5];
+ P4 = pa[6];
+ Q4 = qa[6];
+ P = P1 + s2*P2 + s4*P3 + s6*P4;
+ Q = Q1 + s2*Q2 + s4*Q3 + s6*Q4;
+#endif
+ if(hx>=0) return erx + P/Q; else return -erx - P/Q;
+ }
+ if (ix >= 0x40180000) { /* inf>|x|>=6 */
+ if(hx>=0) return one-tiny; else return tiny-one;
+ }
+ x = fabs(x);
+ s = one/(x*x);
+ if(ix< 0x4006DB6E) { /* |x| < 1/0.35 */
+#ifdef DO_NOT_USE_THIS
+ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+ ra5+s*(ra6+s*ra7))))));
+ S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+ sa5+s*(sa6+s*(sa7+s*sa8)))))));
+#else
+ double R1,R2,R3,R4,S1,S2,S3,S4,s2,s4,s6,s8;
+ R1 = ra[0]+s*ra[1];s2 = s*s;
+ S1 = one+s*sa[1]; s4 = s2*s2;
+ R2 = ra[2]+s*ra[3];s6 = s4*s2;
+ S2 = sa[2]+s*sa[3];s8 = s4*s4;
+ R3 = ra[4]+s*ra[5];
+ S3 = sa[4]+s*sa[5];
+ R4 = ra[6]+s*ra[7];
+ S4 = sa[6]+s*sa[7];
+ R = R1 + s2*R2 + s4*R3 + s6*R4;
+ S = S1 + s2*S2 + s4*S3 + s6*S4 + s8*sa[8];
+#endif
+ } else { /* |x| >= 1/0.35 */
+#ifdef DO_NOT_USE_THIS
+ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+ rb5+s*rb6)))));
+ S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+ sb5+s*(sb6+s*sb7))))));
+#else
+ double R1,R2,R3,S1,S2,S3,S4,s2,s4,s6;
+ R1 = rb[0]+s*rb[1];s2 = s*s;
+ S1 = one+s*sb[1]; s4 = s2*s2;
+ R2 = rb[2]+s*rb[3];s6 = s4*s2;
+ S2 = sb[2]+s*sb[3];
+ R3 = rb[4]+s*rb[5];
+ S3 = sb[4]+s*sb[5];
+ S4 = sb[6]+s*sb[7];
+ R = R1 + s2*R2 + s4*R3 + s6*rb[6];
+ S = S1 + s2*S2 + s4*S3 + s6*S4;
+#endif
+ }
+ z = x;
+ SET_LOW_WORD(z,0);
+ r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S);
+ if(hx>=0) return one-r/x; else return r/x-one;
+}
+weak_alias (__erf, erf)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__erf, __erfl)
+weak_alias (__erf, erfl)
+#endif
+
+#ifdef __STDC__
+ double __erfc(double x)
+#else
+ double __erfc(x)
+ double x;
+#endif
+{
+ int32_t hx,ix;
+ double R,S,P,Q,s,y,z,r;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) { /* erfc(nan)=nan */
+ /* erfc(+-inf)=0,2 */
+ return (double)(((u_int32_t)hx>>31)<<1)+one/x;
+ }
+
+ if(ix < 0x3feb0000) { /* |x|<0.84375 */
+ double r1,r2,s1,s2,s3,z2,z4;
+ if(ix < 0x3c700000) /* |x|<2**-56 */
+ return one-x;
+ z = x*x;
+#ifdef DO_NOT_USE_THIS
+ r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+ s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+#else
+ r1 = pp[0]+z*pp[1]; z2=z*z;
+ r2 = pp[2]+z*pp[3]; z4=z2*z2;
+ s1 = one+z*qq[1];
+ s2 = qq[2]+z*qq[3];
+ s3 = qq[4]+z*qq[5];
+ r = r1 + z2*r2 + z4*pp[4];
+ s = s1 + z2*s2 + z4*s3;
+#endif
+ y = r/s;
+ if(hx < 0x3fd00000) { /* x<1/4 */
+ return one-(x+x*y);
+ } else {
+ r = x*y;
+ r += (x-half);
+ return half - r ;
+ }
+ }
+ if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */
+ double s2,s4,s6,P1,P2,P3,P4,Q1,Q2,Q3,Q4;
+ s = fabs(x)-one;
+#ifdef DO_NOT_USE_THIS
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+#else
+ P1 = pa[0]+s*pa[1]; s2=s*s;
+ Q1 = one+s*qa[1]; s4=s2*s2;
+ P2 = pa[2]+s*pa[3]; s6=s4*s2;
+ Q2 = qa[2]+s*qa[3];
+ P3 = pa[4]+s*pa[5];
+ Q3 = qa[4]+s*qa[5];
+ P4 = pa[6];
+ Q4 = qa[6];
+ P = P1 + s2*P2 + s4*P3 + s6*P4;
+ Q = Q1 + s2*Q2 + s4*Q3 + s6*Q4;
+#endif
+ if(hx>=0) {
+ z = one-erx; return z - P/Q;
+ } else {
+ z = erx+P/Q; return one+z;
+ }
+ }
+ if (ix < 0x403c0000) { /* |x|<28 */
+ x = fabs(x);
+ s = one/(x*x);
+ if(ix< 0x4006DB6D) { /* |x| < 1/.35 ~ 2.857143*/
+#ifdef DO_NOT_USE_THIS
+ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+ ra5+s*(ra6+s*ra7))))));
+ S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+ sa5+s*(sa6+s*(sa7+s*sa8)))))));
+#else
+ double R1,R2,R3,R4,S1,S2,S3,S4,s2,s4,s6,s8;
+ R1 = ra[0]+s*ra[1];s2 = s*s;
+ S1 = one+s*sa[1]; s4 = s2*s2;
+ R2 = ra[2]+s*ra[3];s6 = s4*s2;
+ S2 = sa[2]+s*sa[3];s8 = s4*s4;
+ R3 = ra[4]+s*ra[5];
+ S3 = sa[4]+s*sa[5];
+ R4 = ra[6]+s*ra[7];
+ S4 = sa[6]+s*sa[7];
+ R = R1 + s2*R2 + s4*R3 + s6*R4;
+ S = S1 + s2*S2 + s4*S3 + s6*S4 + s8*sa[8];
+#endif
+ } else { /* |x| >= 1/.35 ~ 2.857143 */
+ double R1,R2,R3,S1,S2,S3,S4,s2,s4,s6;
+ if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */
+#ifdef DO_NOT_USE_THIS
+ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+ rb5+s*rb6)))));
+ S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+ sb5+s*(sb6+s*sb7))))));
+#else
+ R1 = rb[0]+s*rb[1];s2 = s*s;
+ S1 = one+s*sb[1]; s4 = s2*s2;
+ R2 = rb[2]+s*rb[3];s6 = s4*s2;
+ S2 = sb[2]+s*sb[3];
+ R3 = rb[4]+s*rb[5];
+ S3 = sb[4]+s*sb[5];
+ S4 = sb[6]+s*sb[7];
+ R = R1 + s2*R2 + s4*R3 + s6*rb[6];
+ S = S1 + s2*S2 + s4*S3 + s6*S4;
+#endif
+ }
+ z = x;
+ SET_LOW_WORD(z,0);
+ r = __ieee754_exp(-z*z-0.5625)*
+ __ieee754_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;
+ }
+}
+weak_alias (__erfc, erfc)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__erfc, __erfcl)
+weak_alias (__erfc, erfcl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_expm1.c b/libc/sysdeps/ieee754/dbl-64/s_expm1.c
new file mode 100644
index 000000000..bfd15b2e3
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_expm1.c
@@ -0,0 +1,243 @@
+/* @(#)s_expm1.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.
+ * ====================================================
+ */
+/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25,
+ for performance improvement on pipelined processors.
+*/
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: s_expm1.c,v 1.8 1995/05/10 20:47:09 jtc Exp $";
+#endif
+
+/* expm1(x)
+ * Returns exp(x)-1, the exponential of x minus 1.
+ *
+ * Method
+ * 1. Argument reduction:
+ * Given x, find r and integer k such that
+ *
+ * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658
+ *
+ * Here a correction term c will be computed to compensate
+ * the error in r when rounded to a floating-point number.
+ *
+ * 2. Approximating expm1(r) by a special rational function on
+ * the interval [0,0.34658]:
+ * Since
+ * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
+ * we define R1(r*r) by
+ * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
+ * That is,
+ * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
+ * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
+ * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
+ * We use a special Reme algorithm on [0,0.347] to generate
+ * a polynomial of degree 5 in r*r to approximate R1. The
+ * maximum error of this polynomial approximation is bounded
+ * by 2**-61. In other words,
+ * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
+ * where Q1 = -1.6666666666666567384E-2,
+ * Q2 = 3.9682539681370365873E-4,
+ * Q3 = -9.9206344733435987357E-6,
+ * Q4 = 2.5051361420808517002E-7,
+ * Q5 = -6.2843505682382617102E-9;
+ * (where z=r*r, and the values of Q1 to Q5 are listed below)
+ * with error bounded by
+ * | 5 | -61
+ * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
+ * | |
+ *
+ * expm1(r) = exp(r)-1 is then computed by the following
+ * specific way which minimize the accumulation rounding error:
+ * 2 3
+ * r r [ 3 - (R1 + R1*r/2) ]
+ * expm1(r) = r + --- + --- * [--------------------]
+ * 2 2 [ 6 - r*(3 - R1*r/2) ]
+ *
+ * To compensate the error in the argument reduction, we use
+ * expm1(r+c) = expm1(r) + c + expm1(r)*c
+ * ~ expm1(r) + c + r*c
+ * Thus c+r*c will be added in as the correction terms for
+ * expm1(r+c). Now rearrange the term to avoid optimization
+ * screw up:
+ * ( 2 2 )
+ * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r )
+ * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
+ * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 )
+ * ( )
+ *
+ * = r - E
+ * 3. Scale back to obtain expm1(x):
+ * From step 1, we have
+ * expm1(x) = either 2^k*[expm1(r)+1] - 1
+ * = or 2^k*[expm1(r) + (1-2^-k)]
+ * 4. Implementation notes:
+ * (A). To save one multiplication, we scale the coefficient Qi
+ * to Qi*2^i, and replace z by (x^2)/2.
+ * (B). To achieve maximum accuracy, we compute expm1(x) by
+ * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
+ * (ii) if k=0, return r-E
+ * (iii) if k=-1, return 0.5*(r-E)-0.5
+ * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E)
+ * else return 1.0+2.0*(r-E);
+ * (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
+ * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else
+ * (vii) return 2^k(1-((E+2^-k)-r))
+ *
+ * Special cases:
+ * expm1(INF) is INF, expm1(NaN) is NaN;
+ * expm1(-INF) is -1, and
+ * for finite argument, only expm1(0)=0 is exact.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ * For IEEE double
+ * if x > 7.09782712893383973096e+02 then expm1(x) overflow
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#define one Q[0]
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+huge = 1.0e+300,
+tiny = 1.0e-300,
+o_threshold = 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */
+ln2_hi = 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */
+ln2_lo = 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */
+invln2 = 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */
+ /* scaled coefficients related to expm1 */
+Q[] = {1.0, -3.33333333333331316428e-02, /* BFA11111 111110F4 */
+ 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
+ -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
+ 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
+ -2.01099218183624371326e-07}; /* BE8AFDB7 6E09C32D */
+
+#ifdef __STDC__
+ double __expm1(double x)
+#else
+ double __expm1(x)
+ double x;
+#endif
+{
+ double y,hi,lo,c,t,e,hxs,hfx,r1,h2,h4,R1,R2,R3;
+ int32_t k,xsb;
+ u_int32_t hx;
+
+ GET_HIGH_WORD(hx,x);
+ xsb = hx&0x80000000; /* sign bit of x */
+ if(xsb==0) y=x; else y= -x; /* y = |x| */
+ hx &= 0x7fffffff; /* high word of |x| */
+
+ /* filter out huge and non-finite argument */
+ if(hx >= 0x4043687A) { /* if |x|>=56*ln2 */
+ if(hx >= 0x40862E42) { /* if |x|>=709.78... */
+ if(hx>=0x7ff00000) {
+ u_int32_t low;
+ GET_LOW_WORD(low,x);
+ if(((hx&0xfffff)|low)!=0)
+ return x+x; /* NaN */
+ else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
+ }
+ if(x > o_threshold) return huge*huge; /* overflow */
+ }
+ if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */
+ if(x+tiny<0.0) /* raise inexact */
+ return tiny-one; /* return -1 */
+ }
+ }
+
+ /* argument reduction */
+ if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
+ if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
+ if(xsb==0)
+ {hi = x - ln2_hi; lo = ln2_lo; k = 1;}
+ else
+ {hi = x + ln2_hi; lo = -ln2_lo; k = -1;}
+ } else {
+ k = invln2*x+((xsb==0)?0.5:-0.5);
+ t = k;
+ hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
+ lo = t*ln2_lo;
+ }
+ x = hi - lo;
+ c = (hi-x)-lo;
+ }
+ else if(hx < 0x3c900000) { /* when |x|<2**-54, return x */
+ t = huge+x; /* return x with inexact flags when x!=0 */
+ return x - (t-(huge+x));
+ }
+ else k = 0;
+
+ /* x is now in primary range */
+ hfx = 0.5*x;
+ hxs = x*hfx;
+#ifdef DO_NOT_USE_THIS
+ r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
+#else
+ R1 = one+hxs*Q[1]; h2 = hxs*hxs;
+ R2 = Q[2]+hxs*Q[3]; h4 = h2*h2;
+ R3 = Q[4]+hxs*Q[5];
+ r1 = R1 + h2*R2 + h4*R3;
+#endif
+ t = 3.0-r1*hfx;
+ e = hxs*((r1-t)/(6.0 - x*t));
+ if(k==0) return x - (x*e-hxs); /* c is 0 */
+ else {
+ e = (x*(e-c)-c);
+ e -= hxs;
+ if(k== -1) return 0.5*(x-e)-0.5;
+ if(k==1) {
+ if(x < -0.25) return -2.0*(e-(x+0.5));
+ else return one+2.0*(x-e);
+ }
+ if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */
+ u_int32_t high;
+ y = one-(e-x);
+ GET_HIGH_WORD(high,y);
+ SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */
+ return y-one;
+ }
+ t = one;
+ if(k<20) {
+ u_int32_t high;
+ SET_HIGH_WORD(t,0x3ff00000 - (0x200000>>k)); /* t=1-2^-k */
+ y = t-(e-x);
+ GET_HIGH_WORD(high,y);
+ SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */
+ } else {
+ u_int32_t high;
+ SET_HIGH_WORD(t,((0x3ff-k)<<20)); /* 2^-k */
+ y = x-(e+t);
+ y += one;
+ GET_HIGH_WORD(high,y);
+ SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */
+ }
+ }
+ return y;
+}
+weak_alias (__expm1, expm1)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__expm1, __expm1l)
+weak_alias (__expm1, expm1l)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_fabs.c b/libc/sysdeps/ieee754/dbl-64/s_fabs.c
new file mode 100644
index 000000000..1abe9432a
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_fabs.c
@@ -0,0 +1,40 @@
+/* @(#)s_fabs.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_fabs.c,v 1.7 1995/05/10 20:47:13 jtc Exp $";
+#endif
+
+/*
+ * fabs(x) returns the absolute value of x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __fabs(double x)
+#else
+ double __fabs(x)
+ double x;
+#endif
+{
+ u_int32_t high;
+ GET_HIGH_WORD(high,x);
+ SET_HIGH_WORD(x,high&0x7fffffff);
+ return x;
+}
+weak_alias (__fabs, fabs)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__fabs, __fabsl)
+weak_alias (__fabs, fabsl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_finite.c b/libc/sysdeps/ieee754/dbl-64/s_finite.c
new file mode 100644
index 000000000..90de0f9d1
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_finite.c
@@ -0,0 +1,41 @@
+/* @(#)s_finite.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_finite.c,v 1.8 1995/05/10 20:47:17 jtc Exp $";
+#endif
+
+/*
+ * finite(x) returns 1 is x is finite, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __finite(double x)
+#else
+ int __finite(x)
+ double x;
+#endif
+{
+ int32_t hx;
+ GET_HIGH_WORD(hx,x);
+ return (int)((u_int32_t)((hx&0x7fffffff)-0x7ff00000)>>31);
+}
+hidden_def (__finite)
+weak_alias (__finite, finite)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__finite, __finitel)
+weak_alias (__finite, finitel)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_floor.c b/libc/sysdeps/ieee754/dbl-64/s_floor.c
new file mode 100644
index 000000000..77db9ef39
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_floor.c
@@ -0,0 +1,86 @@
+/* @(#)s_floor.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_floor.c,v 1.8 1995/05/10 20:47:20 jtc Exp $";
+#endif
+
+/*
+ * floor(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to floor(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double huge = 1.0e300;
+#else
+static double huge = 1.0e300;
+#endif
+
+#ifdef __STDC__
+ double __floor(double x)
+#else
+ double __floor(x)
+ double x;
+#endif
+{
+ int32_t i0,i1,j0;
+ u_int32_t i,j;
+ EXTRACT_WORDS(i0,i1,x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0>=0) {i0=i1=0;}
+ else if(((i0&0x7fffffff)|i1)!=0)
+ { i0=0xbff00000;i1=0;}
+ }
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0<0) i0 += (0x00100000)>>j0;
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0<0) {
+ if(j0==20) i0+=1;
+ else {
+ j = i1+(1<<(52-j0));
+ if(j<i1) i0 +=1 ; /* got a carry */
+ i1=j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ INSERT_WORDS(x,i0,i1);
+ return x;
+}
+weak_alias (__floor, floor)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__floor, __floorl)
+weak_alias (__floor, floorl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_fpclassify.c b/libc/sysdeps/ieee754/dbl-64/s_fpclassify.c
new file mode 100644
index 000000000..b3a723ebc
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_fpclassify.c
@@ -0,0 +1,44 @@
+/* Return classification value corresponding to argument.
+ Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+int
+__fpclassify (double x)
+{
+ u_int32_t hx, lx;
+ int retval = FP_NORMAL;
+
+ EXTRACT_WORDS (hx, lx, x);
+ lx |= hx & 0xfffff;
+ hx &= 0x7ff00000;
+ if ((hx | lx) == 0)
+ retval = FP_ZERO;
+ else if (hx == 0)
+ retval = FP_SUBNORMAL;
+ else if (hx == 0x7ff00000)
+ retval = lx != 0 ? FP_NAN : FP_INFINITE;
+
+ return retval;
+}
+libm_hidden_def (__fpclassify)
diff --git a/libc/sysdeps/ieee754/dbl-64/s_frexp.c b/libc/sysdeps/ieee754/dbl-64/s_frexp.c
new file mode 100644
index 000000000..7dbddfde0
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_frexp.c
@@ -0,0 +1,64 @@
+/* @(#)s_frexp.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_frexp.c,v 1.9 1995/05/10 20:47:24 jtc Exp $";
+#endif
+
+/*
+ * for non-zero x
+ * x = frexp(arg,&exp);
+ * return a double fp quantity x such that 0.5 <= |x| <1.0
+ * and the corresponding binary exponent "exp". That is
+ * arg = x*2^exp.
+ * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg
+ * with *exp=0.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
+
+#ifdef __STDC__
+ double __frexp(double x, int *eptr)
+#else
+ double __frexp(x, eptr)
+ double x; int *eptr;
+#endif
+{
+ int32_t hx, ix, lx;
+ EXTRACT_WORDS(hx,lx,x);
+ ix = 0x7fffffff&hx;
+ *eptr = 0;
+ if(ix>=0x7ff00000||((ix|lx)==0)) return x; /* 0,inf,nan */
+ if (ix<0x00100000) { /* subnormal */
+ x *= two54;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ *eptr = -54;
+ }
+ *eptr += (ix>>20)-1022;
+ hx = (hx&0x800fffff)|0x3fe00000;
+ SET_HIGH_WORD(x,hx);
+ return x;
+}
+weak_alias (__frexp, frexp)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__frexp, __frexpl)
+weak_alias (__frexp, frexpl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_ilogb.c b/libc/sysdeps/ieee754/dbl-64/s_ilogb.c
new file mode 100644
index 000000000..89a833781
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_ilogb.c
@@ -0,0 +1,64 @@
+/* @(#)s_ilogb.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_ilogb.c,v 1.9 1995/05/10 20:47:28 jtc Exp $";
+#endif
+
+/* ilogb(double x)
+ * return the binary exponent of non-zero x
+ * ilogb(0) = FP_ILOGB0
+ * ilogb(NaN) = FP_ILOGBNAN (no signal is raised)
+ * ilogb(+-Inf) = INT_MAX (no signal is raised)
+ */
+
+#include <limits.h>
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __ilogb(double x)
+#else
+ int __ilogb(x)
+ double x;
+#endif
+{
+ int32_t hx,lx,ix;
+
+ GET_HIGH_WORD(hx,x);
+ hx &= 0x7fffffff;
+ if(hx<0x00100000) {
+ GET_LOW_WORD(lx,x);
+ if((hx|lx)==0)
+ return FP_ILOGB0; /* ilogb(0) = FP_ILOGB0 */
+ else /* subnormal x */
+ if(hx==0) {
+ for (ix = -1043; lx>0; lx<<=1) ix -=1;
+ } else {
+ for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
+ }
+ return ix;
+ }
+ else if (hx<0x7ff00000) return (hx>>20)-1023;
+ else if (FP_ILOGBNAN != INT_MAX) {
+ /* ISO C99 requires ilogb(+-Inf) == INT_MAX. */
+ GET_LOW_WORD(lx,x);
+ if(((hx^0x7ff00000)|lx) == 0)
+ return INT_MAX;
+ }
+ return FP_ILOGBNAN;
+}
+weak_alias (__ilogb, ilogb)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__ilogb, __ilogbl)
+weak_alias (__ilogb, ilogbl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_isinf.c b/libc/sysdeps/ieee754/dbl-64/s_isinf.c
new file mode 100644
index 000000000..24b29ae01
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_isinf.c
@@ -0,0 +1,33 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changed to return -1 for -Inf by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: s_isinf.c,v 1.3 1995/05/11 23:20:14 jtc Exp $";
+#endif
+
+/*
+ * isinf(x) returns 1 is x is inf, -1 if x is -inf, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+int
+__isinf (double x)
+{
+ int32_t hx,lx;
+ EXTRACT_WORDS(hx,lx,x);
+ lx |= (hx & 0x7fffffff) ^ 0x7ff00000;
+ lx |= -lx;
+ return ~(lx >> 31) & (hx >> 30);
+}
+hidden_def (__isinf)
+weak_alias (__isinf, isinf)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__isinf, __isinfl)
+weak_alias (__isinf, isinfl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_isnan.c b/libc/sysdeps/ieee754/dbl-64/s_isnan.c
new file mode 100644
index 000000000..3a089e99a
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_isnan.c
@@ -0,0 +1,44 @@
+/* @(#)s_isnan.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_isnan.c,v 1.8 1995/05/10 20:47:36 jtc Exp $";
+#endif
+
+/*
+ * isnan(x) returns 1 is x is nan, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __isnan(double x)
+#else
+ int __isnan(x)
+ double x;
+#endif
+{
+ int32_t hx,lx;
+ EXTRACT_WORDS(hx,lx,x);
+ hx &= 0x7fffffff;
+ hx |= (u_int32_t)(lx|(-lx))>>31;
+ hx = 0x7ff00000 - hx;
+ return (int)(((u_int32_t)hx)>>31);
+}
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__isnan, __isnanl)
+weak_alias (__isnan, isnanl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_llrint.c b/libc/sysdeps/ieee754/dbl-64/s_llrint.c
new file mode 100644
index 000000000..893bd716b
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_llrint.c
@@ -0,0 +1,98 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+static const long double two52[2] =
+{
+ 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+};
+
+
+long long int
+__llrint (double x)
+{
+ int32_t j0;
+ u_int32_t i1, i0;
+ long long int result;
+ volatile double w;
+ double t;
+ int sx;
+
+ EXTRACT_WORDS (i0, i1, x);
+ j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+ sx = i0 >> 31;
+ i0 &= 0xfffff;
+ i0 |= 0x100000;
+
+ if (j0 < 20)
+ {
+ if (j0 < -1)
+ return 0;
+ else
+ {
+ w = two52[sx] + x;
+ t = w - two52[sx];
+ EXTRACT_WORDS (i0, i1, t);
+ j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+ i0 &= 0xfffff;
+ i0 |= 0x100000;
+
+ result = i0 >> (20 - j0);
+ }
+ }
+ else if (j0 < (int32_t) (8 * sizeof (long long int)) - 1)
+ {
+ if (j0 >= 52)
+ result = (((long long int) i0 << 32) | i1) << (j0 - 52);
+ else
+ {
+ w = two52[sx] + x;
+ t = w - two52[sx];
+ EXTRACT_WORDS (i0, i1, t);
+ j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+ i0 &= 0xfffff;
+ i0 |= 0x100000;
+
+ if (j0 == 20)
+ result = (long long int) i0;
+ else
+ result = ((long long int) i0 << (j0 - 20)) | (i1 >> (52 - j0));
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long long int) x;
+ }
+
+ return sx ? -result : result;
+}
+
+weak_alias (__llrint, llrint)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__llrint, __llrintl)
+weak_alias (__llrint, llrintl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_llround.c b/libc/sysdeps/ieee754/dbl-64/s_llround.c
new file mode 100644
index 000000000..dc1dc772f
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_llround.c
@@ -0,0 +1,81 @@
+/* Round double value to long long int.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+long long int
+__llround (double x)
+{
+ int32_t j0;
+ u_int32_t i1, i0;
+ long long int result;
+ int sign;
+
+ EXTRACT_WORDS (i0, i1, x);
+ j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+ sign = (i0 & 0x80000000) != 0 ? -1 : 1;
+ i0 &= 0xfffff;
+ i0 |= 0x100000;
+
+ if (j0 < 20)
+ {
+ if (j0 < 0)
+ return j0 < -1 ? 0 : sign;
+ else
+ {
+ i0 += 0x80000 >> j0;
+
+ result = i0 >> (20 - j0);
+ }
+ }
+ else if (j0 < (int32_t) (8 * sizeof (long long int)) - 1)
+ {
+ if (j0 >= 52)
+ result = (((long long int) i0 << 32) | i1) << (j0 - 52);
+ else
+ {
+ u_int32_t j = i1 + (0x80000000 >> (j0 - 20));
+ if (j < i1)
+ ++i0;
+
+ if (j0 == 20)
+ result = (long long int) i0;
+ else
+ result = ((long long int) i0 << (j0 - 20)) | (j >> (52 - j0));
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long long int) x;
+ }
+
+ return sign * result;
+}
+
+weak_alias (__llround, llround)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__llround, __llroundl)
+weak_alias (__llround, llroundl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_log1p.c b/libc/sysdeps/ieee754/dbl-64/s_log1p.c
new file mode 100644
index 000000000..0a9801a93
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_log1p.c
@@ -0,0 +1,191 @@
+/* @(#)s_log1p.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.
+ * ====================================================
+ */
+/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25,
+ for performance improvement on pipelined processors.
+*/
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: s_log1p.c,v 1.8 1995/05/10 20:47:46 jtc Exp $";
+#endif
+
+/* double log1p(double x)
+ *
+ * Method :
+ * 1. Argument Reduction: find k and f such that
+ * 1+x = 2^k * (1+f),
+ * where sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ * Note. If k=0, then f=x is exact. However, if k!=0, then f
+ * may not be representable exactly. In that case, a correction
+ * term is need. Let u=1+x rounded. Let c = (1+x)-u, then
+ * log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),
+ * and add back the correction term c/u.
+ * (Note: when x > 2**53, one can simply return log(x))
+ *
+ * 2. Approximation of log1p(f).
+ * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ * = 2s + s*R
+ * We use a special Reme algorithm on [0,0.1716] to generate
+ * a polynomial of degree 14 to approximate R The maximum error
+ * of this polynomial approximation is bounded by 2**-58.45. In
+ * other words,
+ * 2 4 6 8 10 12 14
+ * R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s +Lp6*s +Lp7*s
+ * (the values of Lp1 to Lp7 are listed in the program)
+ * and
+ * | 2 14 | -58.45
+ * | Lp1*s +...+Lp7*s - R(z) | <= 2
+ * | |
+ * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ * In order to guarantee error in log below 1ulp, we compute log
+ * by
+ * log1p(f) = f - (hfsq - s*(hfsq+R)).
+ *
+ * 3. Finally, log1p(x) = k*ln2 + log1p(f).
+ * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ * Here ln2 is split into two floating point number:
+ * ln2_hi + ln2_lo,
+ * where n*ln2_hi is always exact for |n| < 2000.
+ *
+ * Special cases:
+ * log1p(x) is NaN with signal if x < -1 (including -INF) ;
+ * log1p(+INF) is +INF; log1p(-1) is -INF with signal;
+ * log1p(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ *
+ * Note: Assuming log() return accurate answer, the following
+ * algorithm can be used to compute log1p(x) to within a few ULP:
+ *
+ * u = 1+x;
+ * if(u==1.0) return x ; else
+ * return log(u)*(x/(u-1.0));
+ *
+ * See HP-15C Advanced Functions Handbook, p.193.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
+ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
+two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */
+Lp[] = {0.0, 6.666666666666735130e-01, /* 3FE55555 55555593 */
+ 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
+ 2.857142874366239149e-01, /* 3FD24924 94229359 */
+ 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
+ 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
+ 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
+ 1.479819860511658591e-01}; /* 3FC2F112 DF3E5244 */
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __log1p(double x)
+#else
+ double __log1p(x)
+ double x;
+#endif
+{
+ double hfsq,f,c,s,z,R,u,z2,z4,z6,R1,R2,R3,R4;
+ int32_t k,hx,hu,ax;
+
+ GET_HIGH_WORD(hx,x);
+ ax = hx&0x7fffffff;
+
+ k = 1;
+ if (hx < 0x3FDA827A) { /* x < 0.41422 */
+ if(ax>=0x3ff00000) { /* x <= -1.0 */
+ if(x==-1.0) return -two54/(x-x);/* log1p(-1)=+inf */
+ else return (x-x)/(x-x); /* log1p(x<-1)=NaN */
+ }
+ if(ax<0x3e200000) { /* |x| < 2**-29 */
+ if(two54+x>zero /* raise inexact */
+ &&ax<0x3c900000) /* |x| < 2**-54 */
+ return x;
+ else
+ return x - x*x*0.5;
+ }
+ if(hx>0||hx<=((int32_t)0xbfd2bec3)) {
+ k=0;f=x;hu=1;} /* -0.2929<x<0.41422 */
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ if(k!=0) {
+ if(hx<0x43400000) {
+ u = 1.0+x;
+ GET_HIGH_WORD(hu,u);
+ k = (hu>>20)-1023;
+ c = (k>0)? 1.0-(u-x):x-(u-1.0);/* correction term */
+ c /= u;
+ } else {
+ u = x;
+ GET_HIGH_WORD(hu,u);
+ k = (hu>>20)-1023;
+ c = 0;
+ }
+ hu &= 0x000fffff;
+ if(hu<0x6a09e) {
+ SET_HIGH_WORD(u,hu|0x3ff00000); /* normalize u */
+ } else {
+ k += 1;
+ SET_HIGH_WORD(u,hu|0x3fe00000); /* normalize u/2 */
+ hu = (0x00100000-hu)>>2;
+ }
+ f = u-1.0;
+ }
+ hfsq=0.5*f*f;
+ if(hu==0) { /* |f| < 2**-20 */
+ if(f==zero) {
+ if(k==0) return zero;
+ else {c += k*ln2_lo; return k*ln2_hi+c;}
+ }
+ R = hfsq*(1.0-0.66666666666666666*f);
+ if(k==0) return f-R; else
+ return k*ln2_hi-((R-(k*ln2_lo+c))-f);
+ }
+ s = f/(2.0+f);
+ z = s*s;
+#ifdef DO_NOT_USE_THIS
+ R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7))))));
+#else
+ R1 = z*Lp[1]; z2=z*z;
+ R2 = Lp[2]+z*Lp[3]; z4=z2*z2;
+ R3 = Lp[4]+z*Lp[5]; z6=z4*z2;
+ R4 = Lp[6]+z*Lp[7];
+ R = R1 + z2*R2 + z4*R3 + z6*R4;
+#endif
+ if(k==0) return f-(hfsq-s*(hfsq+R)); else
+ return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f);
+}
+weak_alias (__log1p, log1p)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__log1p, __log1pl)
+weak_alias (__log1p, log1pl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_logb.c b/libc/sysdeps/ieee754/dbl-64/s_logb.c
new file mode 100644
index 000000000..4668cf78f
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_logb.c
@@ -0,0 +1,47 @@
+/* @(#)s_logb.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_logb.c,v 1.8 1995/05/10 20:47:50 jtc Exp $";
+#endif
+
+/*
+ * double logb(x)
+ * IEEE 754 logb. Included to pass IEEE test suite. Not recommend.
+ * Use ilogb instead.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ double __logb(double x)
+#else
+ double __logb(x)
+ double x;
+#endif
+{
+ int32_t lx,ix;
+ EXTRACT_WORDS(ix,lx,x);
+ ix &= 0x7fffffff; /* high |x| */
+ if((ix|lx)==0) return -1.0/fabs(x);
+ if(ix>=0x7ff00000) return x*x;
+ if((ix>>=20)==0) /* IEEE 754 logb */
+ return -1022.0;
+ else
+ return (double) (ix-1023);
+}
+weak_alias (__logb, logb)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__logb, __logbl)
+weak_alias (__logb, logbl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_lrint.c b/libc/sysdeps/ieee754/dbl-64/s_lrint.c
new file mode 100644
index 000000000..2da68d4dc
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_lrint.c
@@ -0,0 +1,98 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+static const double two52[2] =
+{
+ 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+};
+
+
+long int
+__lrint (double x)
+{
+ int32_t j0;
+ u_int32_t i0,i1;
+ volatile double w;
+ double t;
+ long int result;
+ int sx;
+
+ EXTRACT_WORDS (i0, i1, x);
+ j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+ sx = i0 >> 31;
+ i0 &= 0xfffff;
+ i0 |= 0x100000;
+
+ if (j0 < 20)
+ {
+ if (j0 < -1)
+ return 0;
+ else
+ {
+ w = two52[sx] + x;
+ t = w - two52[sx];
+ EXTRACT_WORDS (i0, i1, t);
+ j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+ i0 &= 0xfffff;
+ i0 |= 0x100000;
+
+ result = i0 >> (20 - j0);
+ }
+ }
+ else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
+ {
+ if (j0 >= 52)
+ result = ((long int) i0 << (j0 - 20)) | (i1 << (j0 - 52));
+ else
+ {
+ w = two52[sx] + x;
+ t = w - two52[sx];
+ EXTRACT_WORDS (i0, i1, t);
+ j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+ i0 &= 0xfffff;
+ i0 |= 0x100000;
+
+ if (j0 == 20)
+ result = (long int) i0;
+ else
+ result = ((long int) i0 << (j0 - 20)) | (i1 >> (52 - j0));
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long int) x;
+ }
+
+ return sx ? -result : result;
+}
+
+weak_alias (__lrint, lrint)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__lrint, __lrintl)
+weak_alias (__lrint, lrintl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_lround.c b/libc/sysdeps/ieee754/dbl-64/s_lround.c
new file mode 100644
index 000000000..4e1302ad4
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_lround.c
@@ -0,0 +1,81 @@
+/* Round double value to long int.
+ Copyright (C) 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+long int
+__lround (double x)
+{
+ int32_t j0;
+ u_int32_t i1, i0;
+ long int result;
+ int sign;
+
+ EXTRACT_WORDS (i0, i1, x);
+ j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+ sign = (i0 & 0x80000000) != 0 ? -1 : 1;
+ i0 &= 0xfffff;
+ i0 |= 0x100000;
+
+ if (j0 < 20)
+ {
+ if (j0 < 0)
+ return j0 < -1 ? 0 : sign;
+ else
+ {
+ i0 += 0x80000 >> j0;
+
+ result = i0 >> (20 - j0);
+ }
+ }
+ else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
+ {
+ if (j0 >= 52)
+ result = ((long int) i0 << (j0 - 20)) | (i1 << (j0 - 52));
+ else
+ {
+ u_int32_t j = i1 + (0x80000000 >> (j0 - 20));
+ if (j < i1)
+ ++i0;
+
+ if (j0 == 20)
+ result = (long int) i0;
+ else
+ result = ((long int) i0 << (j0 - 20)) | (j >> (52 - j0));
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long int) x;
+ }
+
+ return sign * result;
+}
+
+weak_alias (__lround, lround)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__lround, __lroundl)
+weak_alias (__lround, lroundl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_modf.c b/libc/sysdeps/ieee754/dbl-64/s_modf.c
new file mode 100644
index 000000000..7851f675a
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_modf.c
@@ -0,0 +1,85 @@
+/* @(#)s_modf.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_modf.c,v 1.8 1995/05/10 20:47:55 jtc Exp $";
+#endif
+
+/*
+ * modf(double x, double *iptr)
+ * return fraction part of x, and return x's integral part in *iptr.
+ * Method:
+ * Bit twiddling.
+ *
+ * Exception:
+ * No exception.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one = 1.0;
+#else
+static double one = 1.0;
+#endif
+
+#ifdef __STDC__
+ double __modf(double x, double *iptr)
+#else
+ double __modf(x, iptr)
+ double x,*iptr;
+#endif
+{
+ int32_t i0,i1,j0;
+ u_int32_t i;
+ EXTRACT_WORDS(i0,i1,x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */
+ if(j0<20) { /* integer part in high x */
+ if(j0<0) { /* |x|<1 */
+ INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */
+ return x;
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) { /* x is integral */
+ *iptr = x;
+ INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
+ return x;
+ } else {
+ INSERT_WORDS(*iptr,i0&(~i),0);
+ return x - *iptr;
+ }
+ }
+ } else if (j0>51) { /* no fraction part */
+ *iptr = x*one;
+ /* We must handle NaNs separately. */
+ if (j0 == 0x400 && ((i0 & 0xfffff) | i1))
+ return x*one;
+ INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
+ return x;
+ } else { /* fraction part in low x */
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) { /* x is integral */
+ *iptr = x;
+ INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
+ return x;
+ } else {
+ INSERT_WORDS(*iptr,i0,i1&(~i));
+ return x - *iptr;
+ }
+ }
+}
+weak_alias (__modf, modf)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__modf, __modfl)
+weak_alias (__modf, modfl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_nearbyint.c b/libc/sysdeps/ieee754/dbl-64/s_nearbyint.c
new file mode 100644
index 000000000..32f5bf944
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_nearbyint.c
@@ -0,0 +1,98 @@
+/* Adapted for use as nearbyint by Ulrich Drepper <drepper@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: s_rint.c,v 1.8 1995/05/10 20:48:04 jtc Exp $";
+#endif
+
+/*
+ * rint(x)
+ * Return x rounded to integral value according to the prevailing
+ * rounding mode.
+ * Method:
+ * Using floating addition.
+ * Exception:
+ * Inexact flag raised if x not equal to rint(x).
+ */
+
+#include <fenv.h>
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+TWO52[2]={
+ 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+};
+
+#ifdef __STDC__
+ double __nearbyint(double x)
+#else
+ double __nearbyint(x)
+ double x;
+#endif
+{
+ fenv_t env;
+ int32_t i0,j0,sx;
+ u_int32_t i,i1;
+ double w,t;
+ EXTRACT_WORDS(i0,i1,x);
+ sx = (i0>>31)&1;
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) {
+ if(((i0&0x7fffffff)|i1)==0) return x;
+ i1 |= (i0&0x0fffff);
+ i0 &= 0xfffe0000;
+ i0 |= ((i1|-i1)>>12)&0x80000;
+ SET_HIGH_WORD(x,i0);
+ feholdexcept (&env);
+ w = TWO52[sx]+x;
+ t = w-TWO52[sx];
+ fesetenv (&env);
+ GET_HIGH_WORD(i0,t);
+ SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
+ return t;
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ i>>=1;
+ if(((i0&i)|i1)!=0) {
+ if(j0==19) i1 = 0x40000000; else
+ i0 = (i0&(~i))|((0x20000)>>j0);
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ i>>=1;
+ if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
+ }
+ INSERT_WORDS(x,i0,i1);
+ feholdexcept (&env);
+ w = TWO52[sx]+x;
+ t = w-TWO52[sx];
+ fesetenv (&env);
+ return t;
+}
+weak_alias (__nearbyint, nearbyint)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__nearbyint, __nearbyintl)
+weak_alias (__nearbyint, nearbyintl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_nexttoward.c b/libc/sysdeps/ieee754/dbl-64/s_nexttoward.c
new file mode 100644
index 000000000..c68ba98cb
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_nexttoward.c
@@ -0,0 +1 @@
+/* This function is the same as nextafter so we use an alias there. */
diff --git a/libc/sysdeps/ieee754/dbl-64/s_remquo.c b/libc/sysdeps/ieee754/dbl-64/s_remquo.c
new file mode 100644
index 000000000..820f18bd6
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_remquo.c
@@ -0,0 +1,113 @@
+/* Compute remainder and a congruent to the quotient.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+static const double zero = 0.0;
+
+
+double
+__remquo (double x, double y, int *quo)
+{
+ int32_t hx,hy;
+ u_int32_t sx,lx,ly;
+ int cquo, qs;
+
+ EXTRACT_WORDS (hx, lx, x);
+ EXTRACT_WORDS (hy, ly, y);
+ sx = hx & 0x80000000;
+ qs = sx ^ (hy & 0x80000000);
+ hy &= 0x7fffffff;
+ hx &= 0x7fffffff;
+
+ /* Purge off exception values. */
+ if ((hy | ly) == 0)
+ return (x * y) / (x * y); /* y = 0 */
+ if ((hx >= 0x7ff00000) /* x not finite */
+ || ((hy >= 0x7ff00000) /* p is NaN */
+ && (((hy - 0x7ff00000) | ly) != 0)))
+ return (x * y) / (x * y);
+
+ if (hy <= 0x7fbfffff)
+ x = __ieee754_fmod (x, 8 * y); /* now x < 8y */
+
+ if (((hx - hy) | (lx - ly)) == 0)
+ {
+ *quo = qs ? -1 : 1;
+ return zero * x;
+ }
+
+ x = fabs (x);
+ y = fabs (y);
+ cquo = 0;
+
+ if (x >= 4 * y)
+ {
+ x -= 4 * y;
+ cquo += 4;
+ }
+ if (x >= 2 * y)
+ {
+ x -= 2 * y;
+ cquo += 2;
+ }
+
+ if (hy < 0x00200000)
+ {
+ if (x + x > y)
+ {
+ x -= y;
+ ++cquo;
+ if (x + x >= y)
+ {
+ x -= y;
+ ++cquo;
+ }
+ }
+ }
+ else
+ {
+ double y_half = 0.5 * y;
+ if (x > y_half)
+ {
+ x -= y;
+ ++cquo;
+ if (x >= y_half)
+ {
+ x -= y;
+ ++cquo;
+ }
+ }
+ }
+
+ *quo = qs ? -cquo : cquo;
+
+ if (sx)
+ x = -x;
+ return x;
+}
+weak_alias (__remquo, remquo)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__remquo, __remquol)
+weak_alias (__remquo, remquol)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_rint.c b/libc/sysdeps/ieee754/dbl-64/s_rint.c
new file mode 100644
index 000000000..e5f241291
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_rint.c
@@ -0,0 +1,91 @@
+/* @(#)s_rint.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_rint.c,v 1.8 1995/05/10 20:48:04 jtc Exp $";
+#endif
+
+/*
+ * rint(x)
+ * Return x rounded to integral value according to the prevailing
+ * rounding mode.
+ * Method:
+ * Using floating addition.
+ * Exception:
+ * Inexact flag raised if x not equal to rint(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+TWO52[2]={
+ 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+};
+
+#ifdef __STDC__
+ double __rint(double x)
+#else
+ double __rint(x)
+ double x;
+#endif
+{
+ int32_t i0,j0,sx;
+ u_int32_t i,i1;
+ double w,t;
+ EXTRACT_WORDS(i0,i1,x);
+ sx = (i0>>31)&1;
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) {
+ if(((i0&0x7fffffff)|i1)==0) return x;
+ i1 |= (i0&0x0fffff);
+ i0 &= 0xfffe0000;
+ i0 |= ((i1|-i1)>>12)&0x80000;
+ SET_HIGH_WORD(x,i0);
+ w = TWO52[sx]+x;
+ t = w-TWO52[sx];
+ GET_HIGH_WORD(i0,t);
+ SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
+ return t;
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ i>>=1;
+ if(((i0&i)|i1)!=0) {
+ if(j0==19) i1 = 0x40000000; else
+ i0 = (i0&(~i))|((0x20000)>>j0);
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ i>>=1;
+ if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
+ }
+ INSERT_WORDS(x,i0,i1);
+ w = TWO52[sx]+x;
+ return w-TWO52[sx];
+}
+weak_alias (__rint, rint)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__rint, __rintl)
+weak_alias (__rint, rintl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_round.c b/libc/sysdeps/ieee754/dbl-64/s_round.c
new file mode 100644
index 000000000..94fcde0e4
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_round.c
@@ -0,0 +1,97 @@
+/* Round double to integer away from zero.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+static const double huge = 1.0e300;
+
+
+double
+__round (double x)
+{
+ int32_t i0, j0;
+ u_int32_t i1;
+
+ EXTRACT_WORDS (i0, i1, x);
+ j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+ if (j0 < 20)
+ {
+ if (j0 < 0)
+ {
+ if (huge + x > 0.0)
+ {
+ i0 &= 0x80000000;
+ if (j0 == -1)
+ i0 |= 0x3ff00000;
+ i1 = 0;
+ }
+ }
+ else
+ {
+ u_int32_t i = 0x000fffff >> j0;
+ if (((i0 & i) | i1) == 0)
+ /* X is integral. */
+ return x;
+ if (huge + x > 0.0)
+ {
+ /* Raise inexact if x != 0. */
+ i0 += 0x00080000 >> j0;
+ i0 &= ~i;
+ i1 = 0;
+ }
+ }
+ }
+ else if (j0 > 51)
+ {
+ if (j0 == 0x400)
+ /* Inf or NaN. */
+ return x + x;
+ else
+ return x;
+ }
+ else
+ {
+ u_int32_t i = 0xffffffff >> (j0 - 20);
+ if ((i1 & i) == 0)
+ /* X is integral. */
+ return x;
+
+ if (huge + x > 0.0)
+ {
+ /* Raise inexact if x != 0. */
+ u_int32_t j = i1 + (1 << (51 - j0));
+ if (j < i1)
+ i0 += 1;
+ i1 = j;
+ }
+ i1 &= ~i;
+ }
+
+ INSERT_WORDS (x, i0, i1);
+ return x;
+}
+weak_alias (__round, round)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__round, __roundl)
+weak_alias (__round, roundl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_scalbln.c b/libc/sysdeps/ieee754/dbl-64/s_scalbln.c
new file mode 100644
index 000000000..aa6134f09
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_scalbln.c
@@ -0,0 +1,70 @@
+/* @(#)s_scalbn.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_scalbn.c,v 1.8 1995/05/10 20:48:08 jtc Exp $";
+#endif
+
+/*
+ * scalbn (double x, int n)
+ * scalbn(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
+huge = 1.0e+300,
+tiny = 1.0e-300;
+
+#ifdef __STDC__
+ double __scalbln (double x, long int n)
+#else
+ double __scalbln (x,n)
+ double x; long int n;
+#endif
+{
+ int32_t k,hx,lx;
+ EXTRACT_WORDS(hx,lx,x);
+ k = (hx&0x7ff00000)>>20; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+ x *= two54;
+ GET_HIGH_WORD(hx,x);
+ k = ((hx&0x7ff00000)>>20) - 54;
+ }
+ if (k==0x7ff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (n> 50000 || k > 0x7fe)
+ return huge*__copysign(huge,x); /* overflow */
+ if (n< -50000) return tiny*__copysign(tiny,x); /*underflow*/
+ if (k > 0) /* normal result */
+ {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
+ if (k <= -54)
+ return tiny*__copysign(tiny,x); /*underflow*/
+ k += 54; /* subnormal result */
+ SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
+ return x*twom54;
+}
+weak_alias (__scalbln, scalbln)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__scalbln, __scalblnl)
+weak_alias (__scalbln, scalblnl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_scalbn.c b/libc/sysdeps/ieee754/dbl-64/s_scalbn.c
new file mode 100644
index 000000000..3dbfe8fef
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_scalbn.c
@@ -0,0 +1,70 @@
+/* @(#)s_scalbn.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_scalbn.c,v 1.8 1995/05/10 20:48:08 jtc Exp $";
+#endif
+
+/*
+ * scalbn (double x, int n)
+ * scalbn(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
+huge = 1.0e+300,
+tiny = 1.0e-300;
+
+#ifdef __STDC__
+ double __scalbn (double x, int n)
+#else
+ double __scalbn (x,n)
+ double x; int n;
+#endif
+{
+ int32_t k,hx,lx;
+ EXTRACT_WORDS(hx,lx,x);
+ k = (hx&0x7ff00000)>>20; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+ x *= two54;
+ GET_HIGH_WORD(hx,x);
+ k = ((hx&0x7ff00000)>>20) - 54;
+ }
+ if (k==0x7ff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (n> 50000 || k > 0x7fe)
+ return huge*__copysign(huge,x); /* overflow */
+ if (n< -50000) return tiny*__copysign(tiny,x); /*underflow*/
+ if (k > 0) /* normal result */
+ {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
+ if (k <= -54)
+ return tiny*__copysign(tiny,x); /*underflow*/
+ k += 54; /* subnormal result */
+ SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
+ return x*twom54;
+}
+weak_alias (__scalbn, scalbn)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__scalbn, __scalbnl)
+weak_alias (__scalbn, scalbnl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_signbit.c b/libc/sysdeps/ieee754/dbl-64/s_signbit.c
new file mode 100644
index 000000000..c69f5287d
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_signbit.c
@@ -0,0 +1,32 @@
+/* Return nonzero value if number is negative.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+int
+__signbit (double x)
+{
+ int32_t hx;
+
+ GET_HIGH_WORD (hx, x);
+ return hx & 0x80000000;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/s_sin.c b/libc/sysdeps/ieee754/dbl-64/s_sin.c
new file mode 100644
index 000000000..86e1a6d12
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_sin.c
@@ -0,0 +1,1129 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/****************************************************************************/
+/* */
+/* MODULE_NAME:usncs.c */
+/* */
+/* FUNCTIONS: usin */
+/* ucos */
+/* slow */
+/* slow1 */
+/* slow2 */
+/* sloww */
+/* sloww1 */
+/* sloww2 */
+/* bsloww */
+/* bsloww1 */
+/* bsloww2 */
+/* cslow2 */
+/* csloww */
+/* csloww1 */
+/* csloww2 */
+/* FILES NEEDED: dla.h endian.h mpa.h mydefs.h usncs.h */
+/* branred.c sincos32.c dosincos.c mpa.c */
+/* sincos.tbl */
+/* */
+/* An ultimate sin and routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of sin(x) or cos(x) */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round to nearest mode of IEEE 754 standard. */
+/* */
+/****************************************************************************/
+
+
+#include "endian.h"
+#include "mydefs.h"
+#include "usncs.h"
+#include "MathLib.h"
+#include "sincos.tbl"
+#include "math_private.h"
+
+static const double
+ sn3 = -1.66666666666664880952546298448555E-01,
+ sn5 = 8.33333214285722277379541354343671E-03,
+ cs2 = 4.99999999999999999999950396842453E-01,
+ cs4 = -4.16666666666664434524222570944589E-02,
+ cs6 = 1.38888874007937613028114285595617E-03;
+
+void __dubsin(double x, double dx, double w[]);
+void __docos(double x, double dx, double w[]);
+double __mpsin(double x, double dx);
+double __mpcos(double x, double dx);
+double __mpsin1(double x);
+double __mpcos1(double x);
+static double slow(double x);
+static double slow1(double x);
+static double slow2(double x);
+static double sloww(double x, double dx, double orig);
+static double sloww1(double x, double dx, double orig);
+static double sloww2(double x, double dx, double orig, int n);
+static double bsloww(double x, double dx, double orig, int n);
+static double bsloww1(double x, double dx, double orig, int n);
+static double bsloww2(double x, double dx, double orig, int n);
+int __branred(double x, double *a, double *aa);
+static double cslow2(double x);
+static double csloww(double x, double dx, double orig);
+static double csloww1(double x, double dx, double orig);
+static double csloww2(double x, double dx, double orig, int n);
+/*******************************************************************/
+/* An ultimate sin routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of sin(x) */
+/*******************************************************************/
+double __sin(double x){
+ double xx,res,t,cor,y,s,c,sn,ssn,cs,ccs,xn,a,da,db,eps,xn1,xn2;
+#if 0
+ double w[2];
+#endif
+ mynumber u,v;
+ int4 k,m,n;
+#if 0
+ int4 nn;
+#endif
+
+ u.x = x;
+ m = u.i[HIGH_HALF];
+ k = 0x7fffffff&m; /* no sign */
+ if (k < 0x3e500000) /* if x->0 =>sin(x)=x */
+ return x;
+ /*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/
+ else if (k < 0x3fd00000){
+ xx = x*x;
+ /*Taylor series */
+ t = ((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*(xx*x);
+ res = x+t;
+ cor = (x-res)+t;
+ return (res == res + 1.07*cor)? res : slow(x);
+ } /* else if (k < 0x3fd00000) */
+/*---------------------------- 0.25<|x|< 0.855469---------------------- */
+ else if (k < 0x3feb6000) {
+ u.x=(m>0)?big.x+x:big.x-x;
+ y=(m>0)?x-(u.x-big.x):x+(u.x-big.x);
+ xx=y*y;
+ s = y + y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=(m>0)?sincos.x[k]:-sincos.x[k];
+ ssn=(m>0)?sincos.x[k+1]:-sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ cor=(ssn+s*ccs-sn*c)+cs*s;
+ res=sn+cor;
+ cor=(sn-res)+cor;
+ return (res==res+1.025*cor)? res : slow1(x);
+ } /* else if (k < 0x3feb6000) */
+
+/*----------------------- 0.855469 <|x|<2.426265 ----------------------*/
+ else if (k < 0x400368fd ) {
+
+ y = (m>0)? hp0.x-x:hp0.x+x;
+ if (y>=0) {
+ u.x = big.x+y;
+ y = (y-(u.x-big.x))+hp1.x;
+ }
+ else {
+ u.x = big.x-y;
+ y = (-hp1.x) - (y+(u.x-big.x));
+ }
+ xx=y*y;
+ s = y + y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ cor=(ccs-s*ssn-cs*c)-sn*s;
+ res=cs+cor;
+ cor=(cs-res)+cor;
+ return (res==res+1.020*cor)? ((m>0)?res:-res) : slow2(x);
+ } /* else if (k < 0x400368fd) */
+
+/*-------------------------- 2.426265<|x|< 105414350 ----------------------*/
+ else if (k < 0x419921FB ) {
+ t = (x*hpinv.x + toint.x);
+ xn = t - toint.x;
+ v.x = t;
+ y = (x - xn*mp1.x) - xn*mp2.x;
+ n =v.i[LOW_HALF]&3;
+ da = xn*mp3.x;
+ a=y-da;
+ da = (y-a)-da;
+ eps = ABS(x)*1.2e-30;
+
+ switch (n) { /* quarter of unit circle */
+ case 0:
+ case 2:
+ xx = a*a;
+ if (n) {a=-a;da=-da;}
+ if (xx < 0.01588) {
+ /*Taylor series */
+ t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
+ res = a+t;
+ cor = (a-res)+t;
+ cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
+ return (res == res + cor)? res : sloww(a,da,x);
+ }
+ else {
+ if (a>0)
+ {m=1;t=a;db=da;}
+ else
+ {m=0;t=-a;db=-da;}
+ u.x=big.x+t;
+ y=t-(u.x-big.x);
+ xx=y*y;
+ s = y + (db+y*xx*(sn3 +xx*sn5));
+ c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ cor=(ssn+s*ccs-sn*c)+cs*s;
+ res=sn+cor;
+ cor=(sn-res)+cor;
+ cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
+ return (res==res+cor)? ((m)?res:-res) : sloww1(a,da,x);
+ }
+ break;
+
+ case 1:
+ case 3:
+ if (a<0)
+ {a=-a;da=-da;}
+ u.x=big.x+a;
+ y=a-(u.x-big.x)+da;
+ xx=y*y;
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ s = y + y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ cor=(ccs-s*ssn-cs*c)-sn*s;
+ res=cs+cor;
+ cor=(cs-res)+cor;
+ cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
+ return (res==res+cor)? ((n&2)?-res:res) : sloww2(a,da,x,n);
+
+ break;
+
+ }
+
+ } /* else if (k < 0x419921FB ) */
+
+/*---------------------105414350 <|x|< 281474976710656 --------------------*/
+ else if (k < 0x42F00000 ) {
+ t = (x*hpinv.x + toint.x);
+ xn = t - toint.x;
+ v.x = t;
+ xn1 = (xn+8.0e22)-8.0e22;
+ xn2 = xn - xn1;
+ y = ((((x - xn1*mp1.x) - xn1*mp2.x)-xn2*mp1.x)-xn2*mp2.x);
+ n =v.i[LOW_HALF]&3;
+ da = xn1*pp3.x;
+ t=y-da;
+ da = (y-t)-da;
+ da = (da - xn2*pp3.x) -xn*pp4.x;
+ a = t+da;
+ da = (t-a)+da;
+ eps = 1.0e-24;
+
+ switch (n) {
+ case 0:
+ case 2:
+ xx = a*a;
+ if (n) {a=-a;da=-da;}
+ if (xx < 0.01588) {
+ /* Taylor series */
+ t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
+ res = a+t;
+ cor = (a-res)+t;
+ cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
+ return (res == res + cor)? res : bsloww(a,da,x,n);
+ }
+ else {
+ if (a>0) {m=1;t=a;db=da;}
+ else {m=0;t=-a;db=-da;}
+ u.x=big.x+t;
+ y=t-(u.x-big.x);
+ xx=y*y;
+ s = y + (db+y*xx*(sn3 +xx*sn5));
+ c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ cor=(ssn+s*ccs-sn*c)+cs*s;
+ res=sn+cor;
+ cor=(sn-res)+cor;
+ cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
+ return (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
+ }
+ break;
+
+ case 1:
+ case 3:
+ if (a<0)
+ {a=-a;da=-da;}
+ u.x=big.x+a;
+ y=a-(u.x-big.x)+da;
+ xx=y*y;
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ s = y + y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ cor=(ccs-s*ssn-cs*c)-sn*s;
+ res=cs+cor;
+ cor=(cs-res)+cor;
+ cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
+ return (res==res+cor)? ((n&2)?-res:res) : bsloww2(a,da,x,n);
+
+ break;
+
+ }
+
+ } /* else if (k < 0x42F00000 ) */
+
+/* -----------------281474976710656 <|x| <2^1024----------------------------*/
+ else if (k < 0x7ff00000) {
+
+ n = __branred(x,&a,&da);
+ switch (n) {
+ case 0:
+ if (a*a < 0.01588) return bsloww(a,da,x,n);
+ else return bsloww1(a,da,x,n);
+ break;
+ case 2:
+ if (a*a < 0.01588) return bsloww(-a,-da,x,n);
+ else return bsloww1(-a,-da,x,n);
+ break;
+
+ case 1:
+ case 3:
+ return bsloww2(a,da,x,n);
+ break;
+ }
+
+ } /* else if (k < 0x7ff00000 ) */
+
+/*--------------------- |x| > 2^1024 ----------------------------------*/
+ else return x / x;
+ return 0; /* unreachable */
+}
+
+
+/*******************************************************************/
+/* An ultimate cos routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of cos(x) */
+/*******************************************************************/
+
+double __cos(double x)
+{
+ double y,xx,res,t,cor,s,c,sn,ssn,cs,ccs,xn,a,da,db,eps,xn1,xn2;
+ mynumber u,v;
+ int4 k,m,n;
+
+ u.x = x;
+ m = u.i[HIGH_HALF];
+ k = 0x7fffffff&m;
+
+ if (k < 0x3e400000 ) return 1.0; /* |x|<2^-27 => cos(x)=1 */
+
+ else if (k < 0x3feb6000 ) {/* 2^-27 < |x| < 0.855469 */
+ y=ABS(x);
+ u.x = big.x+y;
+ y = y-(u.x-big.x);
+ xx=y*y;
+ s = y + y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ cor=(ccs-s*ssn-cs*c)-sn*s;
+ res=cs+cor;
+ cor=(cs-res)+cor;
+ return (res==res+1.020*cor)? res : cslow2(x);
+
+} /* else if (k < 0x3feb6000) */
+
+ else if (k < 0x400368fd ) {/* 0.855469 <|x|<2.426265 */;
+ y=hp0.x-ABS(x);
+ a=y+hp1.x;
+ da=(y-a)+hp1.x;
+ xx=a*a;
+ if (xx < 0.01588) {
+ t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
+ res = a+t;
+ cor = (a-res)+t;
+ cor = (cor>0)? 1.02*cor+1.0e-31 : 1.02*cor -1.0e-31;
+ return (res == res + cor)? res : csloww(a,da,x);
+ }
+ else {
+ if (a>0) {m=1;t=a;db=da;}
+ else {m=0;t=-a;db=-da;}
+ u.x=big.x+t;
+ y=t-(u.x-big.x);
+ xx=y*y;
+ s = y + (db+y*xx*(sn3 +xx*sn5));
+ c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ cor=(ssn+s*ccs-sn*c)+cs*s;
+ res=sn+cor;
+ cor=(sn-res)+cor;
+ cor = (cor>0)? 1.035*cor+1.0e-31 : 1.035*cor-1.0e-31;
+ return (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
+}
+
+} /* else if (k < 0x400368fd) */
+
+
+ else if (k < 0x419921FB ) {/* 2.426265<|x|< 105414350 */
+ t = (x*hpinv.x + toint.x);
+ xn = t - toint.x;
+ v.x = t;
+ y = (x - xn*mp1.x) - xn*mp2.x;
+ n =v.i[LOW_HALF]&3;
+ da = xn*mp3.x;
+ a=y-da;
+ da = (y-a)-da;
+ eps = ABS(x)*1.2e-30;
+
+ switch (n) {
+ case 1:
+ case 3:
+ xx = a*a;
+ if (n == 1) {a=-a;da=-da;}
+ if (xx < 0.01588) {
+ t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
+ res = a+t;
+ cor = (a-res)+t;
+ cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
+ return (res == res + cor)? res : csloww(a,da,x);
+ }
+ else {
+ if (a>0) {m=1;t=a;db=da;}
+ else {m=0;t=-a;db=-da;}
+ u.x=big.x+t;
+ y=t-(u.x-big.x);
+ xx=y*y;
+ s = y + (db+y*xx*(sn3 +xx*sn5));
+ c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ cor=(ssn+s*ccs-sn*c)+cs*s;
+ res=sn+cor;
+ cor=(sn-res)+cor;
+ cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
+ return (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
+ }
+ break;
+
+ case 0:
+ case 2:
+ if (a<0) {a=-a;da=-da;}
+ u.x=big.x+a;
+ y=a-(u.x-big.x)+da;
+ xx=y*y;
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ s = y + y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ cor=(ccs-s*ssn-cs*c)-sn*s;
+ res=cs+cor;
+ cor=(cs-res)+cor;
+ cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
+ return (res==res+cor)? ((n)?-res:res) : csloww2(a,da,x,n);
+
+ break;
+
+ }
+
+ } /* else if (k < 0x419921FB ) */
+
+
+ else if (k < 0x42F00000 ) {
+ t = (x*hpinv.x + toint.x);
+ xn = t - toint.x;
+ v.x = t;
+ xn1 = (xn+8.0e22)-8.0e22;
+ xn2 = xn - xn1;
+ y = ((((x - xn1*mp1.x) - xn1*mp2.x)-xn2*mp1.x)-xn2*mp2.x);
+ n =v.i[LOW_HALF]&3;
+ da = xn1*pp3.x;
+ t=y-da;
+ da = (y-t)-da;
+ da = (da - xn2*pp3.x) -xn*pp4.x;
+ a = t+da;
+ da = (t-a)+da;
+ eps = 1.0e-24;
+
+ switch (n) {
+ case 1:
+ case 3:
+ xx = a*a;
+ if (n==1) {a=-a;da=-da;}
+ if (xx < 0.01588) {
+ t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
+ res = a+t;
+ cor = (a-res)+t;
+ cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
+ return (res == res + cor)? res : bsloww(a,da,x,n);
+ }
+ else {
+ if (a>0) {m=1;t=a;db=da;}
+ else {m=0;t=-a;db=-da;}
+ u.x=big.x+t;
+ y=t-(u.x-big.x);
+ xx=y*y;
+ s = y + (db+y*xx*(sn3 +xx*sn5));
+ c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ cor=(ssn+s*ccs-sn*c)+cs*s;
+ res=sn+cor;
+ cor=(sn-res)+cor;
+ cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
+ return (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
+ }
+ break;
+
+ case 0:
+ case 2:
+ if (a<0) {a=-a;da=-da;}
+ u.x=big.x+a;
+ y=a-(u.x-big.x)+da;
+ xx=y*y;
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ s = y + y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ cor=(ccs-s*ssn-cs*c)-sn*s;
+ res=cs+cor;
+ cor=(cs-res)+cor;
+ cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
+ return (res==res+cor)? ((n)?-res:res) : bsloww2(a,da,x,n);
+ break;
+
+ }
+
+ } /* else if (k < 0x42F00000 ) */
+
+ else if (k < 0x7ff00000) {/* 281474976710656 <|x| <2^1024 */
+
+ n = __branred(x,&a,&da);
+ switch (n) {
+ case 1:
+ if (a*a < 0.01588) return bsloww(-a,-da,x,n);
+ else return bsloww1(-a,-da,x,n);
+ break;
+ case 3:
+ if (a*a < 0.01588) return bsloww(a,da,x,n);
+ else return bsloww1(a,da,x,n);
+ break;
+
+ case 0:
+ case 2:
+ return bsloww2(a,da,x,n);
+ break;
+ }
+
+ } /* else if (k < 0x7ff00000 ) */
+
+
+
+
+ else return x / x; /* |x| > 2^1024 */
+ return 0;
+
+}
+
+/************************************************************************/
+/* Routine compute sin(x) for 2^-26 < |x|< 0.25 by Taylor with more */
+/* precision and if still doesn't accurate enough by mpsin or dubsin */
+/************************************************************************/
+
+static double slow(double x) {
+static const double th2_36 = 206158430208.0; /* 1.5*2**37 */
+ double y,x1,x2,xx,r,t,res,cor,w[2];
+ x1=(x+th2_36)-th2_36;
+ y = aa.x*x1*x1*x1;
+ r=x+y;
+ x2=x-x1;
+ xx=x*x;
+ t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + bb.x)*xx + 3.0*aa.x*x1*x2)*x +aa.x*x2*x2*x2;
+ t=((x-r)+y)+t;
+ res=r+t;
+ cor = (r-res)+t;
+ if (res == res + 1.0007*cor) return res;
+ else {
+ __dubsin(ABS(x),0,w);
+ if (w[0] == w[0]+1.000000001*w[1]) return (x>0)?w[0]:-w[0];
+ else return (x>0)?__mpsin(x,0):-__mpsin(-x,0);
+ }
+}
+/*******************************************************************************/
+/* Routine compute sin(x) for 0.25<|x|< 0.855469 by sincos.tbl and Taylor */
+/* and if result still doesn't accurate enough by mpsin or dubsin */
+/*******************************************************************************/
+
+static double slow1(double x) {
+ mynumber u;
+ double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,c1,c2,xx,cor,res;
+ static const double t22 = 6291456.0;
+ int4 k;
+ y=ABS(x);
+ u.x=big.x+y;
+ y=y-(u.x-big.x);
+ xx=y*y;
+ s = y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k]; /* Data */
+ ssn=sincos.x[k+1]; /* from */
+ cs=sincos.x[k+2]; /* tables */
+ ccs=sincos.x[k+3]; /* sincos.tbl */
+ y1 = (y+t22)-t22;
+ y2 = y - y1;
+ c1 = (cs+t22)-t22;
+ c2=(cs-c1)+ccs;
+ cor=(ssn+s*ccs+cs*s+c2*y+c1*y2)-sn*c;
+ y=sn+c1*y1;
+ cor = cor+((sn-y)+c1*y1);
+ res=y+cor;
+ cor=(y-res)+cor;
+ if (res == res+1.0005*cor) return (x>0)?res:-res;
+ else {
+ __dubsin(ABS(x),0,w);
+ if (w[0] == w[0]+1.000000005*w[1]) return (x>0)?w[0]:-w[0];
+ else return (x>0)?__mpsin(x,0):-__mpsin(-x,0);
+ }
+}
+/**************************************************************************/
+/* Routine compute sin(x) for 0.855469 <|x|<2.426265 by sincos.tbl */
+/* and if result still doesn't accurate enough by mpsin or dubsin */
+/**************************************************************************/
+static double slow2(double x) {
+ mynumber u;
+ double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,e1,e2,xx,cor,res,del;
+ static const double t22 = 6291456.0;
+ int4 k;
+ y=ABS(x);
+ y = hp0.x-y;
+ if (y>=0) {
+ u.x = big.x+y;
+ y = y-(u.x-big.x);
+ del = hp1.x;
+ }
+ else {
+ u.x = big.x-y;
+ y = -(y+(u.x-big.x));
+ del = -hp1.x;
+ }
+ xx=y*y;
+ s = y*xx*(sn3 +xx*sn5);
+ c = y*del+xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ y1 = (y+t22)-t22;
+ y2 = (y - y1)+del;
+ e1 = (sn+t22)-t22;
+ e2=(sn-e1)+ssn;
+ cor=(ccs-cs*c-e1*y2-e2*y)-sn*s;
+ y=cs-e1*y1;
+ cor = cor+((cs-y)-e1*y1);
+ res=y+cor;
+ cor=(y-res)+cor;
+ if (res == res+1.0005*cor) return (x>0)?res:-res;
+ else {
+ y=ABS(x)-hp0.x;
+ y1=y-hp1.x;
+ y2=(y-y1)-hp1.x;
+ __docos(y1,y2,w);
+ if (w[0] == w[0]+1.000000005*w[1]) return (x>0)?w[0]:-w[0];
+ else return (x>0)?__mpsin(x,0):-__mpsin(-x,0);
+ }
+}
+/***************************************************************************/
+/* Routine compute sin(x+dx) (Double-Length number) where x is small enough*/
+/* to use Taylor series around zero and (x+dx) */
+/* in first or third quarter of unit circle.Routine receive also */
+/* (right argument) the original value of x for computing error of */
+/* result.And if result not accurate enough routine calls mpsin1 or dubsin */
+/***************************************************************************/
+
+static double sloww(double x,double dx, double orig) {
+ static const double th2_36 = 206158430208.0; /* 1.5*2**37 */
+ double y,x1,x2,xx,r,t,res,cor,w[2],a,da,xn;
+ union {int4 i[2]; double x;} v;
+ int4 n;
+ x1=(x+th2_36)-th2_36;
+ y = aa.x*x1*x1*x1;
+ r=x+y;
+ x2=(x-x1)+dx;
+ xx=x*x;
+ t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + bb.x)*xx + 3.0*aa.x*x1*x2)*x +aa.x*x2*x2*x2+dx;
+ t=((x-r)+y)+t;
+ res=r+t;
+ cor = (r-res)+t;
+ cor = (cor>0)? 1.0005*cor+ABS(orig)*3.1e-30 : 1.0005*cor-ABS(orig)*3.1e-30;
+ if (res == res + cor) return res;
+ else {
+ (x>0)? __dubsin(x,dx,w) : __dubsin(-x,-dx,w);
+ cor = (w[1]>0)? 1.000000001*w[1] + ABS(orig)*1.1e-30 : 1.000000001*w[1] - ABS(orig)*1.1e-30;
+ if (w[0] == w[0]+cor) return (x>0)?w[0]:-w[0];
+ else {
+ t = (orig*hpinv.x + toint.x);
+ xn = t - toint.x;
+ v.x = t;
+ y = (orig - xn*mp1.x) - xn*mp2.x;
+ n =v.i[LOW_HALF]&3;
+ da = xn*pp3.x;
+ t=y-da;
+ da = (y-t)-da;
+ y = xn*pp4.x;
+ a = t - y;
+ da = ((t-a)-y)+da;
+ if (n&2) {a=-a; da=-da;}
+ (a>0)? __dubsin(a,da,w) : __dubsin(-a,-da,w);
+ cor = (w[1]>0)? 1.000000001*w[1] + ABS(orig)*1.1e-40 : 1.000000001*w[1] - ABS(orig)*1.1e-40;
+ if (w[0] == w[0]+cor) return (a>0)?w[0]:-w[0];
+ else return __mpsin1(orig);
+ }
+ }
+}
+/***************************************************************************/
+/* Routine compute sin(x+dx) (Double-Length number) where x in first or */
+/* third quarter of unit circle.Routine receive also (right argument) the */
+/* original value of x for computing error of result.And if result not */
+/* accurate enough routine calls mpsin1 or dubsin */
+/***************************************************************************/
+
+static double sloww1(double x, double dx, double orig) {
+ mynumber u;
+ double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,c1,c2,xx,cor,res;
+ static const double t22 = 6291456.0;
+ int4 k;
+ y=ABS(x);
+ u.x=big.x+y;
+ y=y-(u.x-big.x);
+ dx=(x>0)?dx:-dx;
+ xx=y*y;
+ s = y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ y1 = (y+t22)-t22;
+ y2 = (y - y1)+dx;
+ c1 = (cs+t22)-t22;
+ c2=(cs-c1)+ccs;
+ cor=(ssn+s*ccs+cs*s+c2*y+c1*y2-sn*y*dx)-sn*c;
+ y=sn+c1*y1;
+ cor = cor+((sn-y)+c1*y1);
+ res=y+cor;
+ cor=(y-res)+cor;
+ cor = (cor>0)? 1.0005*cor+3.1e-30*ABS(orig) : 1.0005*cor-3.1e-30*ABS(orig);
+ if (res == res + cor) return (x>0)?res:-res;
+ else {
+ __dubsin(ABS(x),dx,w);
+ cor = (w[1]>0)? 1.000000005*w[1]+1.1e-30*ABS(orig) : 1.000000005*w[1]-1.1e-30*ABS(orig);
+ if (w[0] == w[0]+cor) return (x>0)?w[0]:-w[0];
+ else return __mpsin1(orig);
+ }
+}
+/***************************************************************************/
+/* Routine compute sin(x+dx) (Double-Length number) where x in second or */
+/* fourth quarter of unit circle.Routine receive also the original value */
+/* and quarter(n= 1or 3)of x for computing error of result.And if result not*/
+/* accurate enough routine calls mpsin1 or dubsin */
+/***************************************************************************/
+
+static double sloww2(double x, double dx, double orig, int n) {
+ mynumber u;
+ double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,e1,e2,xx,cor,res;
+ static const double t22 = 6291456.0;
+ int4 k;
+ y=ABS(x);
+ u.x=big.x+y;
+ y=y-(u.x-big.x);
+ dx=(x>0)?dx:-dx;
+ xx=y*y;
+ s = y*xx*(sn3 +xx*sn5);
+ c = y*dx+xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+
+ y1 = (y+t22)-t22;
+ y2 = (y - y1)+dx;
+ e1 = (sn+t22)-t22;
+ e2=(sn-e1)+ssn;
+ cor=(ccs-cs*c-e1*y2-e2*y)-sn*s;
+ y=cs-e1*y1;
+ cor = cor+((cs-y)-e1*y1);
+ res=y+cor;
+ cor=(y-res)+cor;
+ cor = (cor>0)? 1.0005*cor+3.1e-30*ABS(orig) : 1.0005*cor-3.1e-30*ABS(orig);
+ if (res == res + cor) return (n&2)?-res:res;
+ else {
+ __docos(ABS(x),dx,w);
+ cor = (w[1]>0)? 1.000000005*w[1]+1.1e-30*ABS(orig) : 1.000000005*w[1]-1.1e-30*ABS(orig);
+ if (w[0] == w[0]+cor) return (n&2)?-w[0]:w[0];
+ else return __mpsin1(orig);
+ }
+}
+/***************************************************************************/
+/* Routine compute sin(x+dx) or cos(x+dx) (Double-Length number) where x */
+/* is small enough to use Taylor series around zero and (x+dx) */
+/* in first or third quarter of unit circle.Routine receive also */
+/* (right argument) the original value of x for computing error of */
+/* result.And if result not accurate enough routine calls other routines */
+/***************************************************************************/
+
+static double bsloww(double x,double dx, double orig,int n) {
+ static const double th2_36 = 206158430208.0; /* 1.5*2**37 */
+ double y,x1,x2,xx,r,t,res,cor,w[2];
+#if 0
+ double a,da,xn;
+ union {int4 i[2]; double x;} v;
+#endif
+ x1=(x+th2_36)-th2_36;
+ y = aa.x*x1*x1*x1;
+ r=x+y;
+ x2=(x-x1)+dx;
+ xx=x*x;
+ t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + bb.x)*xx + 3.0*aa.x*x1*x2)*x +aa.x*x2*x2*x2+dx;
+ t=((x-r)+y)+t;
+ res=r+t;
+ cor = (r-res)+t;
+ cor = (cor>0)? 1.0005*cor+1.1e-24 : 1.0005*cor-1.1e-24;
+ if (res == res + cor) return res;
+ else {
+ (x>0)? __dubsin(x,dx,w) : __dubsin(-x,-dx,w);
+ cor = (w[1]>0)? 1.000000001*w[1] + 1.1e-24 : 1.000000001*w[1] - 1.1e-24;
+ if (w[0] == w[0]+cor) return (x>0)?w[0]:-w[0];
+ else return (n&1)?__mpcos1(orig):__mpsin1(orig);
+ }
+}
+
+/***************************************************************************/
+/* Routine compute sin(x+dx) or cos(x+dx) (Double-Length number) where x */
+/* in first or third quarter of unit circle.Routine receive also */
+/* (right argument) the original value of x for computing error of result.*/
+/* And if result not accurate enough routine calls other routines */
+/***************************************************************************/
+
+static double bsloww1(double x, double dx, double orig,int n) {
+mynumber u;
+ double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,c1,c2,xx,cor,res;
+ static const double t22 = 6291456.0;
+ int4 k;
+ y=ABS(x);
+ u.x=big.x+y;
+ y=y-(u.x-big.x);
+ dx=(x>0)?dx:-dx;
+ xx=y*y;
+ s = y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ y1 = (y+t22)-t22;
+ y2 = (y - y1)+dx;
+ c1 = (cs+t22)-t22;
+ c2=(cs-c1)+ccs;
+ cor=(ssn+s*ccs+cs*s+c2*y+c1*y2-sn*y*dx)-sn*c;
+ y=sn+c1*y1;
+ cor = cor+((sn-y)+c1*y1);
+ res=y+cor;
+ cor=(y-res)+cor;
+ cor = (cor>0)? 1.0005*cor+1.1e-24 : 1.0005*cor-1.1e-24;
+ if (res == res + cor) return (x>0)?res:-res;
+ else {
+ __dubsin(ABS(x),dx,w);
+ cor = (w[1]>0)? 1.000000005*w[1]+1.1e-24: 1.000000005*w[1]-1.1e-24;
+ if (w[0] == w[0]+cor) return (x>0)?w[0]:-w[0];
+ else return (n&1)?__mpcos1(orig):__mpsin1(orig);
+ }
+}
+
+/***************************************************************************/
+/* Routine compute sin(x+dx) or cos(x+dx) (Double-Length number) where x */
+/* in second or fourth quarter of unit circle.Routine receive also the */
+/* original value and quarter(n= 1or 3)of x for computing error of result. */
+/* And if result not accurate enough routine calls other routines */
+/***************************************************************************/
+
+static double bsloww2(double x, double dx, double orig, int n) {
+mynumber u;
+ double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,e1,e2,xx,cor,res;
+ static const double t22 = 6291456.0;
+ int4 k;
+ y=ABS(x);
+ u.x=big.x+y;
+ y=y-(u.x-big.x);
+ dx=(x>0)?dx:-dx;
+ xx=y*y;
+ s = y*xx*(sn3 +xx*sn5);
+ c = y*dx+xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+
+ y1 = (y+t22)-t22;
+ y2 = (y - y1)+dx;
+ e1 = (sn+t22)-t22;
+ e2=(sn-e1)+ssn;
+ cor=(ccs-cs*c-e1*y2-e2*y)-sn*s;
+ y=cs-e1*y1;
+ cor = cor+((cs-y)-e1*y1);
+ res=y+cor;
+ cor=(y-res)+cor;
+ cor = (cor>0)? 1.0005*cor+1.1e-24 : 1.0005*cor-1.1e-24;
+ if (res == res + cor) return (n&2)?-res:res;
+ else {
+ __docos(ABS(x),dx,w);
+ cor = (w[1]>0)? 1.000000005*w[1]+1.1e-24 : 1.000000005*w[1]-1.1e-24;
+ if (w[0] == w[0]+cor) return (n&2)?-w[0]:w[0];
+ else return (n&1)?__mpsin1(orig):__mpcos1(orig);
+ }
+}
+
+/************************************************************************/
+/* Routine compute cos(x) for 2^-27 < |x|< 0.25 by Taylor with more */
+/* precision and if still doesn't accurate enough by mpcos or docos */
+/************************************************************************/
+
+static double cslow2(double x) {
+ mynumber u;
+ double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,e1,e2,xx,cor,res;
+ static const double t22 = 6291456.0;
+ int4 k;
+ y=ABS(x);
+ u.x = big.x+y;
+ y = y-(u.x-big.x);
+ xx=y*y;
+ s = y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ y1 = (y+t22)-t22;
+ y2 = y - y1;
+ e1 = (sn+t22)-t22;
+ e2=(sn-e1)+ssn;
+ cor=(ccs-cs*c-e1*y2-e2*y)-sn*s;
+ y=cs-e1*y1;
+ cor = cor+((cs-y)-e1*y1);
+ res=y+cor;
+ cor=(y-res)+cor;
+ if (res == res+1.0005*cor)
+ return res;
+ else {
+ y=ABS(x);
+ __docos(y,0,w);
+ if (w[0] == w[0]+1.000000005*w[1]) return w[0];
+ else return __mpcos(x,0);
+ }
+}
+
+/***************************************************************************/
+/* Routine compute cos(x+dx) (Double-Length number) where x is small enough*/
+/* to use Taylor series around zero and (x+dx) .Routine receive also */
+/* (right argument) the original value of x for computing error of */
+/* result.And if result not accurate enough routine calls other routines */
+/***************************************************************************/
+
+
+static double csloww(double x,double dx, double orig) {
+ static const double th2_36 = 206158430208.0; /* 1.5*2**37 */
+ double y,x1,x2,xx,r,t,res,cor,w[2],a,da,xn;
+ union {int4 i[2]; double x;} v;
+ int4 n;
+ x1=(x+th2_36)-th2_36;
+ y = aa.x*x1*x1*x1;
+ r=x+y;
+ x2=(x-x1)+dx;
+ xx=x*x;
+ /* Taylor series */
+ t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + bb.x)*xx + 3.0*aa.x*x1*x2)*x +aa.x*x2*x2*x2+dx;
+ t=((x-r)+y)+t;
+ res=r+t;
+ cor = (r-res)+t;
+ cor = (cor>0)? 1.0005*cor+ABS(orig)*3.1e-30 : 1.0005*cor-ABS(orig)*3.1e-30;
+ if (res == res + cor) return res;
+ else {
+ (x>0)? __dubsin(x,dx,w) : __dubsin(-x,-dx,w);
+ cor = (w[1]>0)? 1.000000001*w[1] + ABS(orig)*1.1e-30 : 1.000000001*w[1] - ABS(orig)*1.1e-30;
+ if (w[0] == w[0]+cor) return (x>0)?w[0]:-w[0];
+ else {
+ t = (orig*hpinv.x + toint.x);
+ xn = t - toint.x;
+ v.x = t;
+ y = (orig - xn*mp1.x) - xn*mp2.x;
+ n =v.i[LOW_HALF]&3;
+ da = xn*pp3.x;
+ t=y-da;
+ da = (y-t)-da;
+ y = xn*pp4.x;
+ a = t - y;
+ da = ((t-a)-y)+da;
+ if (n==1) {a=-a; da=-da;}
+ (a>0)? __dubsin(a,da,w) : __dubsin(-a,-da,w);
+ cor = (w[1]>0)? 1.000000001*w[1] + ABS(orig)*1.1e-40 : 1.000000001*w[1] - ABS(orig)*1.1e-40;
+ if (w[0] == w[0]+cor) return (a>0)?w[0]:-w[0];
+ else return __mpcos1(orig);
+ }
+ }
+}
+
+/***************************************************************************/
+/* Routine compute sin(x+dx) (Double-Length number) where x in first or */
+/* third quarter of unit circle.Routine receive also (right argument) the */
+/* original value of x for computing error of result.And if result not */
+/* accurate enough routine calls other routines */
+/***************************************************************************/
+
+static double csloww1(double x, double dx, double orig) {
+ mynumber u;
+ double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,c1,c2,xx,cor,res;
+ static const double t22 = 6291456.0;
+ int4 k;
+ y=ABS(x);
+ u.x=big.x+y;
+ y=y-(u.x-big.x);
+ dx=(x>0)?dx:-dx;
+ xx=y*y;
+ s = y*xx*(sn3 +xx*sn5);
+ c = xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+ y1 = (y+t22)-t22;
+ y2 = (y - y1)+dx;
+ c1 = (cs+t22)-t22;
+ c2=(cs-c1)+ccs;
+ cor=(ssn+s*ccs+cs*s+c2*y+c1*y2-sn*y*dx)-sn*c;
+ y=sn+c1*y1;
+ cor = cor+((sn-y)+c1*y1);
+ res=y+cor;
+ cor=(y-res)+cor;
+ cor = (cor>0)? 1.0005*cor+3.1e-30*ABS(orig) : 1.0005*cor-3.1e-30*ABS(orig);
+ if (res == res + cor) return (x>0)?res:-res;
+ else {
+ __dubsin(ABS(x),dx,w);
+ cor = (w[1]>0)? 1.000000005*w[1]+1.1e-30*ABS(orig) : 1.000000005*w[1]-1.1e-30*ABS(orig);
+ if (w[0] == w[0]+cor) return (x>0)?w[0]:-w[0];
+ else return __mpcos1(orig);
+ }
+}
+
+
+/***************************************************************************/
+/* Routine compute sin(x+dx) (Double-Length number) where x in second or */
+/* fourth quarter of unit circle.Routine receive also the original value */
+/* and quarter(n= 1or 3)of x for computing error of result.And if result not*/
+/* accurate enough routine calls other routines */
+/***************************************************************************/
+
+static double csloww2(double x, double dx, double orig, int n) {
+ mynumber u;
+ double sn,ssn,cs,ccs,s,c,w[2],y,y1,y2,e1,e2,xx,cor,res;
+ static const double t22 = 6291456.0;
+ int4 k;
+ y=ABS(x);
+ u.x=big.x+y;
+ y=y-(u.x-big.x);
+ dx=(x>0)?dx:-dx;
+ xx=y*y;
+ s = y*xx*(sn3 +xx*sn5);
+ c = y*dx+xx*(cs2 +xx*(cs4 + xx*cs6));
+ k=u.i[LOW_HALF]<<2;
+ sn=sincos.x[k];
+ ssn=sincos.x[k+1];
+ cs=sincos.x[k+2];
+ ccs=sincos.x[k+3];
+
+ y1 = (y+t22)-t22;
+ y2 = (y - y1)+dx;
+ e1 = (sn+t22)-t22;
+ e2=(sn-e1)+ssn;
+ cor=(ccs-cs*c-e1*y2-e2*y)-sn*s;
+ y=cs-e1*y1;
+ cor = cor+((cs-y)-e1*y1);
+ res=y+cor;
+ cor=(y-res)+cor;
+ cor = (cor>0)? 1.0005*cor+3.1e-30*ABS(orig) : 1.0005*cor-3.1e-30*ABS(orig);
+ if (res == res + cor) return (n)?-res:res;
+ else {
+ __docos(ABS(x),dx,w);
+ cor = (w[1]>0)? 1.000000005*w[1]+1.1e-30*ABS(orig) : 1.000000005*w[1]-1.1e-30*ABS(orig);
+ if (w[0] == w[0]+cor) return (n)?-w[0]:w[0];
+ else return __mpcos1(orig);
+ }
+}
+
+weak_alias (__cos, cos)
+weak_alias (__sin, sin)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__sin, __sinl)
+weak_alias (__sin, sinl)
+strong_alias (__cos, __cosl)
+weak_alias (__cos, cosl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_sincos.c b/libc/sysdeps/ieee754/dbl-64/s_sincos.c
new file mode 100644
index 000000000..e946f9f97
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_sincos.c
@@ -0,0 +1,51 @@
+/* Compute sine and cosine of argument.
+ Copyright (C) 1997, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+void
+__sincos (double x, double *sinx, double *cosx)
+{
+ int32_t ix;
+
+ /* High word of x. */
+ GET_HIGH_WORD (ix, x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if (ix>=0x7ff00000)
+ {
+ /* sin(Inf or NaN) is NaN */
+ *sinx = *cosx = x - x;
+ }
+ else
+ {
+ *sinx = __sin (x);
+ *cosx = __cos (x);
+ }
+}
+weak_alias (__sincos, sincos)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__sincos, __sincosl)
+weak_alias (__sincos, sincosl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_tan.c b/libc/sysdeps/ieee754/dbl-64/s_tan.c
new file mode 100644
index 000000000..cf8d4d026
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_tan.c
@@ -0,0 +1,486 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*********************************************************************/
+/* MODULE_NAME: utan.c */
+/* */
+/* FUNCTIONS: utan */
+/* tanMp */
+/* */
+/* FILES NEEDED:dla.h endian.h mpa.h mydefs.h utan.h */
+/* branred.c sincos32.c mptan.c */
+/* utan.tbl */
+/* */
+/* An ultimate tan routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of tan(x). */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round to nearest mode of IEEE 754 standard. */
+/* */
+/*********************************************************************/
+#include "endian.h"
+#include "dla.h"
+#include "mpa.h"
+#include "MathLib.h"
+#include "math.h"
+
+static double tanMp(double);
+void __mptan(double, mp_no *, int);
+
+double tan(double x) {
+#include "utan.h"
+#include "utan.tbl"
+
+ int ux,i,n;
+ double a,da,a2,b,db,c,dc,c1,cc1,c2,cc2,c3,cc3,fi,ffi,gi,pz,s,sy,
+ t,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,w,x2,xn,xx2,y,ya,yya,z0,z,zz,z2,zz2;
+ int p;
+ number num,v;
+ mp_no mpa,mpt1,mpt2;
+#if 0
+ mp_no mpy;
+#endif
+
+ int __branred(double, double *, double *);
+ int __mpranred(double, mp_no *, int);
+
+ /* x=+-INF, x=NaN */
+ num.d = x; ux = num.i[HIGH_HALF];
+ if ((ux&0x7ff00000)==0x7ff00000) return x-x;
+
+ w=(x<ZERO) ? -x : x;
+
+ /* (I) The case abs(x) <= 1.259e-8 */
+ if (w<=g1.d) return x;
+
+ /* (II) The case 1.259e-8 < abs(x) <= 0.0608 */
+ if (w<=g2.d) {
+
+ /* First stage */
+ x2 = x*x;
+ t2 = x*x2*(d3.d+x2*(d5.d+x2*(d7.d+x2*(d9.d+x2*d11.d))));
+ if ((y=x+(t2-u1.d*t2)) == x+(t2+u1.d*t2)) return y;
+
+ /* Second stage */
+ c1 = x2*(a15.d+x2*(a17.d+x2*(a19.d+x2*(a21.d+x2*(a23.d+x2*(a25.d+
+ x2*a27.d))))));
+ EMULV(x,x,x2,xx2,t1,t2,t3,t4,t5)
+ ADD2(a13.d,aa13.d,c1,zero.d,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a11.d,aa11.d,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a9.d ,aa9.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a7.d ,aa7.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a5.d ,aa5.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a3.d ,aa3.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(x ,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(x ,zero.d,c2,cc2,c1,cc1,t1,t2)
+ if ((y=c1+(cc1-u2.d*c1)) == c1+(cc1+u2.d*c1)) return y;
+ return tanMp(x);
+ }
+
+ /* (III) The case 0.0608 < abs(x) <= 0.787 */
+ if (w<=g3.d) {
+
+ /* First stage */
+ i = ((int) (mfftnhf.d+TWO8*w));
+ z = w-xfg[i][0].d; z2 = z*z; s = (x<ZERO) ? MONE : ONE;
+ pz = z+z*z2*(e0.d+z2*e1.d);
+ fi = xfg[i][1].d; gi = xfg[i][2].d; t2 = pz*(gi+fi)/(gi-pz);
+ if ((y=fi+(t2-fi*u3.d))==fi+(t2+fi*u3.d)) return (s*y);
+ t3 = (t2<ZERO) ? -t2 : t2;
+ if ((y=fi+(t2-(t4=fi*ua3.d+t3*ub3.d)))==fi+(t2+t4)) return (s*y);
+
+ /* Second stage */
+ ffi = xfg[i][3].d;
+ c1 = z2*(a7.d+z2*(a9.d+z2*a11.d));
+ EMULV(z,z,z2,zz2,t1,t2,t3,t4,t5)
+ ADD2(a5.d,aa5.d,c1,zero.d,c2,cc2,t1,t2)
+ MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a3.d,aa3.d,c1,cc1,c2,cc2,t1,t2)
+ MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(z ,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(z ,zero.d,c2,cc2,c1,cc1,t1,t2)
+
+ ADD2(fi ,ffi,c1,cc1,c2,cc2,t1,t2)
+ MUL2(fi ,ffi,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8)
+ SUB2(one.d,zero.d,c3,cc3,c1,cc1,t1,t2)
+ DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+
+ if ((y=c3+(cc3-u4.d*c3))==c3+(cc3+u4.d*c3)) return (s*y);
+ return tanMp(x);
+ }
+
+ /* (---) The case 0.787 < abs(x) <= 25 */
+ if (w<=g4.d) {
+ /* Range reduction by algorithm i */
+ t = (x*hpinv.d + toint.d);
+ xn = t - toint.d;
+ v.d = t;
+ t1 = (x - xn*mp1.d) - xn*mp2.d;
+ n =v.i[LOW_HALF] & 0x00000001;
+ da = xn*mp3.d;
+ a=t1-da;
+ da = (t1-a)-da;
+ if (a<ZERO) {ya=-a; yya=-da; sy=MONE;}
+ else {ya= a; yya= da; sy= ONE;}
+
+ /* (IV),(V) The case 0.787 < abs(x) <= 25, abs(y) <= 1e-7 */
+ if (ya<=gy1.d) return tanMp(x);
+
+ /* (VI) The case 0.787 < abs(x) <= 25, 1e-7 < abs(y) <= 0.0608 */
+ if (ya<=gy2.d) {
+ a2 = a*a;
+ t2 = da+a*a2*(d3.d+a2*(d5.d+a2*(d7.d+a2*(d9.d+a2*d11.d))));
+ if (n) {
+ /* First stage -cot */
+ EADD(a,t2,b,db)
+ DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ if ((y=c+(dc-u6.d*c))==c+(dc+u6.d*c)) return (-y); }
+ else {
+ /* First stage tan */
+ if ((y=a+(t2-u5.d*a))==a+(t2+u5.d*a)) return y; }
+ /* Second stage */
+ /* Range reduction by algorithm ii */
+ t = (x*hpinv.d + toint.d);
+ xn = t - toint.d;
+ v.d = t;
+ t1 = (x - xn*mp1.d) - xn*mp2.d;
+ n =v.i[LOW_HALF] & 0x00000001;
+ da = xn*pp3.d;
+ t=t1-da;
+ da = (t1-t)-da;
+ t1 = xn*pp4.d;
+ a = t - t1;
+ da = ((t-a)-t1)+da;
+
+ /* Second stage */
+ EADD(a,da,t1,t2) a=t1; da=t2;
+ MUL2(a,da,a,da,x2,xx2,t1,t2,t3,t4,t5,t6,t7,t8)
+ c1 = x2*(a15.d+x2*(a17.d+x2*(a19.d+x2*(a21.d+x2*(a23.d+x2*(a25.d+
+ x2*a27.d))))));
+ ADD2(a13.d,aa13.d,c1,zero.d,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a11.d,aa11.d,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a9.d ,aa9.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a7.d ,aa7.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a5.d ,aa5.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a3.d ,aa3.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(a ,da ,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a ,da ,c2,cc2,c1,cc1,t1,t2)
+
+ if (n) {
+ /* Second stage -cot */
+ DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ if ((y=c2+(cc2-u8.d*c2)) == c2+(cc2+u8.d*c2)) return (-y); }
+ else {
+ /* Second stage tan */
+ if ((y=c1+(cc1-u7.d*c1)) == c1+(cc1+u7.d*c1)) return y; }
+ return tanMp(x);
+ }
+
+ /* (VII) The case 0.787 < abs(x) <= 25, 0.0608 < abs(y) <= 0.787 */
+
+ /* First stage */
+ i = ((int) (mfftnhf.d+TWO8*ya));
+ z = (z0=(ya-xfg[i][0].d))+yya; z2 = z*z;
+ pz = z+z*z2*(e0.d+z2*e1.d);
+ fi = xfg[i][1].d; gi = xfg[i][2].d;
+
+ if (n) {
+ /* -cot */
+ t2 = pz*(fi+gi)/(fi+pz);
+ if ((y=gi-(t2-gi*u10.d))==gi-(t2+gi*u10.d)) return (-sy*y);
+ t3 = (t2<ZERO) ? -t2 : t2;
+ if ((y=gi-(t2-(t4=gi*ua10.d+t3*ub10.d)))==gi-(t2+t4)) return (-sy*y); }
+ else {
+ /* tan */
+ t2 = pz*(gi+fi)/(gi-pz);
+ if ((y=fi+(t2-fi*u9.d))==fi+(t2+fi*u9.d)) return (sy*y);
+ t3 = (t2<ZERO) ? -t2 : t2;
+ if ((y=fi+(t2-(t4=fi*ua9.d+t3*ub9.d)))==fi+(t2+t4)) return (sy*y); }
+
+ /* Second stage */
+ ffi = xfg[i][3].d;
+ EADD(z0,yya,z,zz)
+ MUL2(z,zz,z,zz,z2,zz2,t1,t2,t3,t4,t5,t6,t7,t8)
+ c1 = z2*(a7.d+z2*(a9.d+z2*a11.d));
+ ADD2(a5.d,aa5.d,c1,zero.d,c2,cc2,t1,t2)
+ MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a3.d,aa3.d,c1,cc1,c2,cc2,t1,t2)
+ MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(z ,zz ,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(z ,zz ,c2,cc2,c1,cc1,t1,t2)
+
+ ADD2(fi ,ffi,c1,cc1,c2,cc2,t1,t2)
+ MUL2(fi ,ffi,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8)
+ SUB2(one.d,zero.d,c3,cc3,c1,cc1,t1,t2)
+
+ if (n) {
+ /* -cot */
+ DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ if ((y=c3+(cc3-u12.d*c3))==c3+(cc3+u12.d*c3)) return (-sy*y); }
+ else {
+ /* tan */
+ DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ if ((y=c3+(cc3-u11.d*c3))==c3+(cc3+u11.d*c3)) return (sy*y); }
+
+ return tanMp(x);
+ }
+
+ /* (---) The case 25 < abs(x) <= 1e8 */
+ if (w<=g5.d) {
+ /* Range reduction by algorithm ii */
+ t = (x*hpinv.d + toint.d);
+ xn = t - toint.d;
+ v.d = t;
+ t1 = (x - xn*mp1.d) - xn*mp2.d;
+ n =v.i[LOW_HALF] & 0x00000001;
+ da = xn*pp3.d;
+ t=t1-da;
+ da = (t1-t)-da;
+ t1 = xn*pp4.d;
+ a = t - t1;
+ da = ((t-a)-t1)+da;
+ EADD(a,da,t1,t2) a=t1; da=t2;
+ if (a<ZERO) {ya=-a; yya=-da; sy=MONE;}
+ else {ya= a; yya= da; sy= ONE;}
+
+ /* (+++) The case 25 < abs(x) <= 1e8, abs(y) <= 1e-7 */
+ if (ya<=gy1.d) return tanMp(x);
+
+ /* (VIII) The case 25 < abs(x) <= 1e8, 1e-7 < abs(y) <= 0.0608 */
+ if (ya<=gy2.d) {
+ a2 = a*a;
+ t2 = da+a*a2*(d3.d+a2*(d5.d+a2*(d7.d+a2*(d9.d+a2*d11.d))));
+ if (n) {
+ /* First stage -cot */
+ EADD(a,t2,b,db)
+ DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ if ((y=c+(dc-u14.d*c))==c+(dc+u14.d*c)) return (-y); }
+ else {
+ /* First stage tan */
+ if ((y=a+(t2-u13.d*a))==a+(t2+u13.d*a)) return y; }
+
+ /* Second stage */
+ MUL2(a,da,a,da,x2,xx2,t1,t2,t3,t4,t5,t6,t7,t8)
+ c1 = x2*(a15.d+x2*(a17.d+x2*(a19.d+x2*(a21.d+x2*(a23.d+x2*(a25.d+
+ x2*a27.d))))));
+ ADD2(a13.d,aa13.d,c1,zero.d,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a11.d,aa11.d,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a9.d ,aa9.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a7.d ,aa7.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a5.d ,aa5.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a3.d ,aa3.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(a ,da ,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a ,da ,c2,cc2,c1,cc1,t1,t2)
+
+ if (n) {
+ /* Second stage -cot */
+ DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ if ((y=c2+(cc2-u16.d*c2)) == c2+(cc2+u16.d*c2)) return (-y); }
+ else {
+ /* Second stage tan */
+ if ((y=c1+(cc1-u15.d*c1)) == c1+(cc1+u15.d*c1)) return (y); }
+ return tanMp(x);
+ }
+
+ /* (IX) The case 25 < abs(x) <= 1e8, 0.0608 < abs(y) <= 0.787 */
+ /* First stage */
+ i = ((int) (mfftnhf.d+TWO8*ya));
+ z = (z0=(ya-xfg[i][0].d))+yya; z2 = z*z;
+ pz = z+z*z2*(e0.d+z2*e1.d);
+ fi = xfg[i][1].d; gi = xfg[i][2].d;
+
+ if (n) {
+ /* -cot */
+ t2 = pz*(fi+gi)/(fi+pz);
+ if ((y=gi-(t2-gi*u18.d))==gi-(t2+gi*u18.d)) return (-sy*y);
+ t3 = (t2<ZERO) ? -t2 : t2;
+ if ((y=gi-(t2-(t4=gi*ua18.d+t3*ub18.d)))==gi-(t2+t4)) return (-sy*y); }
+ else {
+ /* tan */
+ t2 = pz*(gi+fi)/(gi-pz);
+ if ((y=fi+(t2-fi*u17.d))==fi+(t2+fi*u17.d)) return (sy*y);
+ t3 = (t2<ZERO) ? -t2 : t2;
+ if ((y=fi+(t2-(t4=fi*ua17.d+t3*ub17.d)))==fi+(t2+t4)) return (sy*y); }
+
+ /* Second stage */
+ ffi = xfg[i][3].d;
+ EADD(z0,yya,z,zz)
+ MUL2(z,zz,z,zz,z2,zz2,t1,t2,t3,t4,t5,t6,t7,t8)
+ c1 = z2*(a7.d+z2*(a9.d+z2*a11.d));
+ ADD2(a5.d,aa5.d,c1,zero.d,c2,cc2,t1,t2)
+ MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a3.d,aa3.d,c1,cc1,c2,cc2,t1,t2)
+ MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(z ,zz ,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(z ,zz ,c2,cc2,c1,cc1,t1,t2)
+
+ ADD2(fi ,ffi,c1,cc1,c2,cc2,t1,t2)
+ MUL2(fi ,ffi,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8)
+ SUB2(one.d,zero.d,c3,cc3,c1,cc1,t1,t2)
+
+ if (n) {
+ /* -cot */
+ DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ if ((y=c3+(cc3-u20.d*c3))==c3+(cc3+u20.d*c3)) return (-sy*y); }
+ else {
+ /* tan */
+ DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ if ((y=c3+(cc3-u19.d*c3))==c3+(cc3+u19.d*c3)) return (sy*y); }
+ return tanMp(x);
+ }
+
+ /* (---) The case 1e8 < abs(x) < 2**1024 */
+ /* Range reduction by algorithm iii */
+ n = (__branred(x,&a,&da)) & 0x00000001;
+ EADD(a,da,t1,t2) a=t1; da=t2;
+ if (a<ZERO) {ya=-a; yya=-da; sy=MONE;}
+ else {ya= a; yya= da; sy= ONE;}
+
+ /* (+++) The case 1e8 < abs(x) < 2**1024, abs(y) <= 1e-7 */
+ if (ya<=gy1.d) return tanMp(x);
+
+ /* (X) The case 1e8 < abs(x) < 2**1024, 1e-7 < abs(y) <= 0.0608 */
+ if (ya<=gy2.d) {
+ a2 = a*a;
+ t2 = da+a*a2*(d3.d+a2*(d5.d+a2*(d7.d+a2*(d9.d+a2*d11.d))));
+ if (n) {
+ /* First stage -cot */
+ EADD(a,t2,b,db)
+ DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ if ((y=c+(dc-u22.d*c))==c+(dc+u22.d*c)) return (-y); }
+ else {
+ /* First stage tan */
+ if ((y=a+(t2-u21.d*a))==a+(t2+u21.d*a)) return y; }
+
+ /* Second stage */
+ /* Reduction by algorithm iv */
+ p=10; n = (__mpranred(x,&mpa,p)) & 0x00000001;
+ __mp_dbl(&mpa,&a,p); __dbl_mp(a,&mpt1,p);
+ __sub(&mpa,&mpt1,&mpt2,p); __mp_dbl(&mpt2,&da,p);
+
+ MUL2(a,da,a,da,x2,xx2,t1,t2,t3,t4,t5,t6,t7,t8)
+ c1 = x2*(a15.d+x2*(a17.d+x2*(a19.d+x2*(a21.d+x2*(a23.d+x2*(a25.d+
+ x2*a27.d))))));
+ ADD2(a13.d,aa13.d,c1,zero.d,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a11.d,aa11.d,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a9.d ,aa9.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a7.d ,aa7.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a5.d ,aa5.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a3.d ,aa3.d ,c1,cc1,c2,cc2,t1,t2)
+ MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(a ,da ,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a ,da ,c2,cc2,c1,cc1,t1,t2)
+
+ if (n) {
+ /* Second stage -cot */
+ DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ if ((y=c2+(cc2-u24.d*c2)) == c2+(cc2+u24.d*c2)) return (-y); }
+ else {
+ /* Second stage tan */
+ if ((y=c1+(cc1-u23.d*c1)) == c1+(cc1+u23.d*c1)) return y; }
+ return tanMp(x);
+ }
+
+ /* (XI) The case 1e8 < abs(x) < 2**1024, 0.0608 < abs(y) <= 0.787 */
+ /* First stage */
+ i = ((int) (mfftnhf.d+TWO8*ya));
+ z = (z0=(ya-xfg[i][0].d))+yya; z2 = z*z;
+ pz = z+z*z2*(e0.d+z2*e1.d);
+ fi = xfg[i][1].d; gi = xfg[i][2].d;
+
+ if (n) {
+ /* -cot */
+ t2 = pz*(fi+gi)/(fi+pz);
+ if ((y=gi-(t2-gi*u26.d))==gi-(t2+gi*u26.d)) return (-sy*y);
+ t3 = (t2<ZERO) ? -t2 : t2;
+ if ((y=gi-(t2-(t4=gi*ua26.d+t3*ub26.d)))==gi-(t2+t4)) return (-sy*y); }
+ else {
+ /* tan */
+ t2 = pz*(gi+fi)/(gi-pz);
+ if ((y=fi+(t2-fi*u25.d))==fi+(t2+fi*u25.d)) return (sy*y);
+ t3 = (t2<ZERO) ? -t2 : t2;
+ if ((y=fi+(t2-(t4=fi*ua25.d+t3*ub25.d)))==fi+(t2+t4)) return (sy*y); }
+
+ /* Second stage */
+ ffi = xfg[i][3].d;
+ EADD(z0,yya,z,zz)
+ MUL2(z,zz,z,zz,z2,zz2,t1,t2,t3,t4,t5,t6,t7,t8)
+ c1 = z2*(a7.d+z2*(a9.d+z2*a11.d));
+ ADD2(a5.d,aa5.d,c1,zero.d,c2,cc2,t1,t2)
+ MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(a3.d,aa3.d,c1,cc1,c2,cc2,t1,t2)
+ MUL2(z2,zz2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+ MUL2(z ,zz ,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
+ ADD2(z ,zz ,c2,cc2,c1,cc1,t1,t2)
+
+ ADD2(fi ,ffi,c1,cc1,c2,cc2,t1,t2)
+ MUL2(fi ,ffi,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8)
+ SUB2(one.d,zero.d,c3,cc3,c1,cc1,t1,t2)
+
+ if (n) {
+ /* -cot */
+ DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ if ((y=c3+(cc3-u28.d*c3))==c3+(cc3+u28.d*c3)) return (-sy*y); }
+ else {
+ /* tan */
+ DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+ if ((y=c3+(cc3-u27.d*c3))==c3+(cc3+u27.d*c3)) return (sy*y); }
+ return tanMp(x);
+}
+
+
+/* multiple precision stage */
+/* Convert x to multi precision number,compute tan(x) by mptan() routine */
+/* and converts result back to double */
+static double tanMp(double x)
+{
+ int p;
+ double y;
+ mp_no mpy;
+ p=32;
+ __mptan(x, &mpy, p);
+ __mp_dbl(&mpy,&y,p);
+ return y;
+}
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (tan, tanl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_tanh.c b/libc/sysdeps/ieee754/dbl-64/s_tanh.c
new file mode 100644
index 000000000..944f96386
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_tanh.c
@@ -0,0 +1,93 @@
+/* @(#)s_tanh.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_tanh.c,v 1.7 1995/05/10 20:48:22 jtc Exp $";
+#endif
+
+/* Tanh(x)
+ * Return the Hyperbolic Tangent of x
+ *
+ * Method :
+ * x -x
+ * e - e
+ * 0. tanh(x) is defined to be -----------
+ * x -x
+ * e + e
+ * 1. reduce x to non-negative by tanh(-x) = -tanh(x).
+ * 2. 0 <= x <= 2**-55 : tanh(x) := x*(one+x)
+ * -t
+ * 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x)
+ * t + 2
+ * 2
+ * 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t=expm1(2x)
+ * t + 2
+ * 22.0 < x <= INF : tanh(x) := 1.
+ *
+ * Special cases:
+ * tanh(NaN) is NaN;
+ * only tanh(0)=0 is exact for finite argument.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double one=1.0, two=2.0, tiny = 1.0e-300;
+#else
+static double one=1.0, two=2.0, tiny = 1.0e-300;
+#endif
+
+#ifdef __STDC__
+ double __tanh(double x)
+#else
+ double __tanh(x)
+ double x;
+#endif
+{
+ double t,z;
+ int32_t jx,ix,lx;
+
+ /* High word of |x|. */
+ EXTRACT_WORDS(jx,lx,x);
+ ix = jx&0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7ff00000) {
+ if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */
+ else return one/x-one; /* tanh(NaN) = NaN */
+ }
+
+ /* |x| < 22 */
+ if (ix < 0x40360000) { /* |x|<22 */
+ if ((ix | lx) == 0)
+ return x; /* x == +-0 */
+ if (ix<0x3c800000) /* |x|<2**-55 */
+ return x*(one+x); /* tanh(small) = small */
+ if (ix>=0x3ff00000) { /* |x|>=1 */
+ t = __expm1(two*fabs(x));
+ z = one - two/(t+two);
+ } else {
+ t = __expm1(-two*fabs(x));
+ z= -t/(t+two);
+ }
+ /* |x| > 22, return +-1 */
+ } else {
+ z = one - tiny; /* raised inexact flag */
+ }
+ return (jx>=0)? z: -z;
+}
+weak_alias (__tanh, tanh)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__tanh, __tanhl)
+weak_alias (__tanh, tanhl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/s_trunc.c b/libc/sysdeps/ieee754/dbl-64/s_trunc.c
new file mode 100644
index 000000000..9ce7a4009
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/s_trunc.c
@@ -0,0 +1,61 @@
+/* Truncate argument to nearest integral value not larger than the argument.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+double
+__trunc (double x)
+{
+ int32_t i0, j0;
+ u_int32_t i1;
+ int sx;
+
+ EXTRACT_WORDS (i0, i1, x);
+ sx = i0 & 0x80000000;
+ j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+ if (j0 < 20)
+ {
+ if (j0 < 0)
+ /* The magnitude of the number is < 1 so the result is +-0. */
+ INSERT_WORDS (x, sx, 0);
+ else
+ INSERT_WORDS (x, sx | (i0 & ~(0x000fffff >> j0)), 0);
+ }
+ else if (j0 > 51)
+ {
+ if (j0 == 0x400)
+ /* x is inf or NaN. */
+ return x + x;
+ }
+ else
+ {
+ INSERT_WORDS (x, i0, i1 & ~(0xffffffffu >> (j0 - 20)));
+ }
+
+ return x;
+}
+weak_alias (__trunc, trunc)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__trunc, __truncl)
+weak_alias (__trunc, truncl)
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/sincos.tbl b/libc/sysdeps/ieee754/dbl-64/sincos.tbl
new file mode 100644
index 000000000..9dd550284
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/sincos.tbl
@@ -0,0 +1,912 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/****************************************************************/
+/* TABLES FOR THE usin() and ucos() FUNCTION */
+/****************************************************************/
+
+
+#ifdef BIG_ENDI
+static const union {int4 i[880]; double x[40];}sincos = { .i = {
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x3FF00000, 0x00000000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x3F7FFFEA, 0xAAAEEEEF,
+/**/ 0xBC1E45E2, 0xEC67B77C,
+/**/ 0x3FEFFFC0, 0x00155552,
+/**/ 0x3C8F4A01, 0xA0196DAE,
+/**/ 0x3F8FFFAA, 0xAAEEEED5,
+/**/ 0xBC02AB63, 0x9A9F0777,
+/**/ 0x3FEFFF00, 0x0155549F,
+/**/ 0x3C828A28, 0xA03A5EF3,
+/**/ 0x3F97FF70, 0x01033255,
+/**/ 0x3BFEFE2B, 0x51527336,
+/**/ 0x3FEFFDC0, 0x06BFF7E6,
+/**/ 0x3C8AE6DA, 0xE86977BD,
+/**/ 0x3F9FFEAA, 0xAEEEE86F,
+/**/ 0xBC3CD406, 0xFB224AE2,
+/**/ 0x3FEFFC00, 0x155527D3,
+/**/ 0xBC83B544, 0x92D89B5B,
+/**/ 0x3FA3FEB2, 0xB12D45D5,
+/**/ 0x3C34EC54, 0x203D1C11,
+/**/ 0x3FEFF9C0, 0x3414A7BA,
+/**/ 0x3C6991F4, 0xBE6C59BF,
+/**/ 0x3FA7FDC0, 0x1032FBA9,
+/**/ 0xBC4599BD, 0xF46E997A,
+/**/ 0x3FEFF700, 0x6BFDF99F,
+/**/ 0xBC78B3B5, 0x60648D5F,
+/**/ 0x3FABFC6D, 0x78586DAC,
+/**/ 0x3C18E4FD, 0x03DBF236,
+/**/ 0x3FEFF3C0, 0xC8103A31,
+/**/ 0x3C74856D, 0xBDDC0E66,
+/**/ 0x3FAFFAAA, 0xEEED4EDB,
+/**/ 0xBC42D16D, 0x32684B69,
+/**/ 0x3FEFF001, 0x5549F4D3,
+/**/ 0x3C832838, 0x7B99426F,
+/**/ 0x3FB1FC34, 0x3D808BEF,
+/**/ 0xBC5F3D32, 0xE6F3BE4F,
+/**/ 0x3FEFEBC2, 0x22A8EF9F,
+/**/ 0x3C579349, 0x34F54C77,
+/**/ 0x3FB3FACB, 0x12D1755B,
+/**/ 0xBC592191, 0x5299468C,
+/**/ 0x3FEFE703, 0x4129EF6F,
+/**/ 0xBC6CBF43, 0x37C96F97,
+/**/ 0x3FB5F911, 0xFD10B737,
+/**/ 0xBC50184F, 0x02BE9102,
+/**/ 0x3FEFE1C4, 0xC3C873EB,
+/**/ 0xBC35A9C9, 0x057C4A02,
+/**/ 0x3FB7F701, 0x032550E4,
+/**/ 0x3C3AFC2D, 0x1800501A,
+/**/ 0x3FEFDC06, 0xBF7E6B9B,
+/**/ 0x3C831902, 0xB535F8DB,
+/**/ 0x3FB9F490, 0x2D55D1F9,
+/**/ 0x3C52696D, 0x7EAC1DC1,
+/**/ 0x3FEFD5C9, 0x4B43E000,
+/**/ 0xBC62E768, 0xCB4F92F9,
+/**/ 0x3FBBF1B7, 0x8568391D,
+/**/ 0x3C5E9184, 0x1DEA4CC8,
+/**/ 0x3FEFCF0C, 0x800E99B1,
+/**/ 0x3C6EA3D7, 0x86D186AC,
+/**/ 0x3FBDEE6F, 0x16C1CCE6,
+/**/ 0xBC450F8E, 0x2FB71673,
+/**/ 0x3FEFC7D0, 0x78D1BC88,
+/**/ 0x3C8075D2, 0x447DB685,
+/**/ 0x3FBFEAAE, 0xEE86EE36,
+/**/ 0xBC4AFCB2, 0xBCC6F03B,
+/**/ 0x3FEFC015, 0x527D5BD3,
+/**/ 0x3C8B68F3, 0x5094EFB8,
+/**/ 0x3FC0F337, 0x8DDD71D1,
+/**/ 0x3C6D8468, 0x724F0F9E,
+/**/ 0x3FEFB7DB, 0x2BFE0695,
+/**/ 0x3C821DAD, 0xF4F65AB1,
+/**/ 0x3FC1F0D3, 0xD7AFCEAF,
+/**/ 0xBC66EF95, 0x099769A5,
+/**/ 0x3FEFAF22, 0x263C4BD3,
+/**/ 0xBC552ACE, 0x133A2769,
+/**/ 0x3FC2EE28, 0x5E4AB88F,
+/**/ 0xBC6E4D0F, 0x05DEE058,
+/**/ 0x3FEFA5EA, 0x641C36F2,
+/**/ 0x3C404DA6, 0xED17CC7C,
+/**/ 0x3FC3EB31, 0x2C5D66CB,
+/**/ 0x3C647D66, 0x6B66CB91,
+/**/ 0x3FEF9C34, 0x0A7CC428,
+/**/ 0x3C8C5B6B, 0x063B7462,
+/**/ 0x3FC4E7EA, 0x4DC5F27B,
+/**/ 0x3C5949DB, 0x2AC072FC,
+/**/ 0x3FEF91FF, 0x40374D01,
+/**/ 0xBC67D03F, 0x4D3A9E4C,
+/**/ 0x3FC5E44F, 0xCFA126F3,
+/**/ 0xBC66F443, 0x063F89B6,
+/**/ 0x3FEF874C, 0x2E1EECF6,
+/**/ 0xBC8C6514, 0xE1332B16,
+/**/ 0x3FC6E05D, 0xC05A4D4C,
+/**/ 0xBBD32C5C, 0x8B81C940,
+/**/ 0x3FEF7C1A, 0xFEFFDE24,
+/**/ 0xBC78F55B, 0xC47540B1,
+/**/ 0x3FC7DC10, 0x2FBAF2B5,
+/**/ 0x3C45AB50, 0xE23C97C3,
+/**/ 0x3FEF706B, 0xDF9ECE1C,
+/**/ 0xBC8698C8, 0x0C36DCB4,
+/**/ 0x3FC8D763, 0x2EFAA944,
+/**/ 0xBC620FA2, 0x62CBB953,
+/**/ 0x3FEF643E, 0xFEB82ACD,
+/**/ 0x3C76B00A, 0xC1FE28AC,
+/**/ 0x3FC9D252, 0xD0CEC312,
+/**/ 0x3C59C43D, 0x80B1137D,
+/**/ 0x3FEF5794, 0x8CFF6797,
+/**/ 0x3C6E3A0D, 0x3E03B1D5,
+/**/ 0x3FCACCDB, 0x297A0765,
+/**/ 0xBC59883B, 0x57D6CDEB,
+/**/ 0x3FEF4A6C, 0xBD1E3A79,
+/**/ 0x3C813DF0, 0xEDAEBB57,
+/**/ 0x3FCBC6F8, 0x4EDC6199,
+/**/ 0x3C69C1A5, 0x6A7B0CAB,
+/**/ 0x3FEF3CC7, 0xC3B3D16E,
+/**/ 0xBC621A3A, 0xD28A3494,
+/**/ 0x3FCCC0A6, 0x588289A3,
+/**/ 0xBC6868D0, 0x9BC87C6B,
+/**/ 0x3FEF2EA5, 0xD753FFED,
+/**/ 0x3C8CC421, 0x5F56D583,
+/**/ 0x3FCDB9E1, 0x5FB5A5D0,
+/**/ 0xBC632E20, 0xD6CC6FC2,
+/**/ 0x3FEF2007, 0x3086649F,
+/**/ 0x3C7B9404, 0x16C1984B,
+/**/ 0x3FCEB2A5, 0x7F8AE5A3,
+/**/ 0xBC60BE06, 0xAF572CEB,
+/**/ 0x3FEF10EC, 0x09C5873B,
+/**/ 0x3C8D9072, 0x762C1283,
+/**/ 0x3FCFAAEE, 0xD4F31577,
+/**/ 0xBC615D88, 0x508E32B8,
+/**/ 0x3FEF0154, 0x9F7DEEA1,
+/**/ 0x3C8D3C1E, 0x99E5CAFD,
+/**/ 0x3FD0515C, 0xBF65155C,
+/**/ 0xBC79B8C2, 0x9DFD8EC8,
+/**/ 0x3FEEF141, 0x300D2F26,
+/**/ 0xBC82AA1B, 0x08DED372,
+/**/ 0x3FD0CD00, 0xCEF36436,
+/**/ 0xBC79FB0A, 0x0C93E2B5,
+/**/ 0x3FEEE0B1, 0xFBC0F11C,
+/**/ 0xBC4BFD23, 0x80BBC3B1,
+/**/ 0x3FD14861, 0xAA94DDEB,
+/**/ 0xBC6BE881, 0xB5B615A4,
+/**/ 0x3FEECFA7, 0x44D5EFA1,
+/**/ 0xBC556D0A, 0x4AF541D0,
+/**/ 0x3FD1C37D, 0x64C6B876,
+/**/ 0x3C746076, 0xFE0DCFF5,
+/**/ 0x3FEEBE21, 0x4F76EFA8,
+/**/ 0xBC802F9F, 0x12BA543E,
+/**/ 0x3FD23E52, 0x111AAF36,
+/**/ 0xBC74F080, 0x334EFF18,
+/**/ 0x3FEEAC20, 0x61BBAF4F,
+/**/ 0x3C62C1D5, 0x3E94658D,
+/**/ 0x3FD2B8DD, 0xC43EB49F,
+/**/ 0x3C615538, 0x99F2D807,
+/**/ 0x3FEE99A4, 0xC3A7CD83,
+/**/ 0xBC82264B, 0x1BC53CE8,
+/**/ 0x3FD3331E, 0x94049F87,
+/**/ 0x3C7E0CB6, 0xB40C302C,
+/**/ 0x3FEE86AE, 0xBF29A9ED,
+/**/ 0x3C89397A, 0xFDBB58A7,
+/**/ 0x3FD3AD12, 0x9769D3D8,
+/**/ 0x3C003D55, 0x04878398,
+/**/ 0x3FEE733E, 0xA0193D40,
+/**/ 0xBC86428B, 0x3546CE13,
+/**/ 0x3FD426B7, 0xE69EE697,
+/**/ 0xBC7F09C7, 0x5705C59F,
+/**/ 0x3FEE5F54, 0xB436E9D0,
+/**/ 0x3C87EB0F, 0xD02FC8BC,
+/**/ 0x3FD4A00C, 0x9B0F3D20,
+/**/ 0x3C7823BA, 0x6BB08EAD,
+/**/ 0x3FEE4AF1, 0x4B2A449C,
+/**/ 0xBC868CA0, 0x2E8A6833,
+/**/ 0x3FD5190E, 0xCF68A77A,
+/**/ 0x3C7B3571, 0x55EEF0F3,
+/**/ 0x3FEE3614, 0xB680D6A5,
+/**/ 0xBC727793, 0xAA015237,
+/**/ 0x3FD591BC, 0x9FA2F597,
+/**/ 0x3C67C74B, 0xAC3FE0CB,
+/**/ 0x3FEE20BF, 0x49ACD6C1,
+/**/ 0xBC5660AE, 0xC7EF636C,
+/**/ 0x3FD60A14, 0x29078775,
+/**/ 0x3C5B1FD8, 0x0BA89133,
+/**/ 0x3FEE0AF1, 0x5A03DBCE,
+/**/ 0x3C5FE8E7, 0x02771AE6,
+/**/ 0x3FD68213, 0x8A38D7F7,
+/**/ 0xBC7D8892, 0x02444AAD,
+/**/ 0x3FEDF4AB, 0x3EBD875E,
+/**/ 0xBC8E2D8A, 0x7E6736C4,
+/**/ 0x3FD6F9B8, 0xE33A0255,
+/**/ 0x3C742BC1, 0x4EE9DA0D,
+/**/ 0x3FEDDDED, 0x50F228D6,
+/**/ 0xBC6E80C8, 0xD42BA2BF,
+/**/ 0x3FD77102, 0x55764214,
+/**/ 0xBC66EAD7, 0x314BB6CE,
+/**/ 0x3FEDC6B7, 0xEB995912,
+/**/ 0x3C54B364, 0x776DCD35,
+/**/ 0x3FD7E7EE, 0x03C86D4E,
+/**/ 0xBC7B63BC, 0xDABF5AF2,
+/**/ 0x3FEDAF0B, 0x6B888E83,
+/**/ 0x3C8A249E, 0x2B5E5CEA,
+/**/ 0x3FD85E7A, 0x12826949,
+/**/ 0x3C78A40E, 0x9B5FACE0,
+/**/ 0x3FED96E8, 0x2F71A9DC,
+/**/ 0x3C8FF61B, 0xD5D2039D,
+/**/ 0x3FD8D4A4, 0xA774992F,
+/**/ 0x3C744A02, 0xEA766326,
+/**/ 0x3FED7E4E, 0x97E17B4A,
+/**/ 0xBC63B770, 0x352BED94,
+/**/ 0x3FD94A6B, 0xE9F546C5,
+/**/ 0xBC769CE1, 0x3E683F58,
+/**/ 0x3FED653F, 0x073E4040,
+/**/ 0xBC876236, 0x434BEC37,
+/**/ 0x3FD9BFCE, 0x02E80510,
+/**/ 0x3C709E39, 0xA320B0A4,
+/**/ 0x3FED4BB9, 0xE1C619E0,
+/**/ 0x3C8F34BB, 0x77858F61,
+/**/ 0x3FDA34C9, 0x1CC50CCA,
+/**/ 0xBC5A310E, 0x3B50CECD,
+/**/ 0x3FED31BF, 0x8D8D7C06,
+/**/ 0x3C7E60DD, 0x3089CBDD,
+/**/ 0x3FDAA95B, 0x63A09277,
+/**/ 0xBC66293E, 0xB13C0381,
+/**/ 0x3FED1750, 0x727D94F0,
+/**/ 0x3C80D52B, 0x1EC1A48E,
+/**/ 0x3FDB1D83, 0x05321617,
+/**/ 0xBC7AE242, 0xCB99F519,
+/**/ 0x3FECFC6C, 0xFA52AD9F,
+/**/ 0x3C88B5B5, 0x508F2A0D,
+/**/ 0x3FDB913E, 0x30DBAC43,
+/**/ 0xBC7E38AD, 0x2F6C3FF1,
+/**/ 0x3FECE115, 0x909A82E5,
+/**/ 0x3C81F139, 0xBB31109A,
+/**/ 0x3FDC048B, 0x17B140A3,
+/**/ 0x3C619FE6, 0x757E9FA7,
+/**/ 0x3FECC54A, 0xA2B2972E,
+/**/ 0x3C64EE16, 0x2BA83A98,
+/**/ 0x3FDC7767, 0xEC7FD19E,
+/**/ 0xBC5EB14D, 0x1A3D5826,
+/**/ 0x3FECA90C, 0x9FC67D0B,
+/**/ 0xBC646A81, 0x485E3462,
+/**/ 0x3FDCE9D2, 0xE3D4A51F,
+/**/ 0xBC62FC8A, 0x12DAE298,
+/**/ 0x3FEC8C5B, 0xF8CE1A84,
+/**/ 0x3C7AB3D1, 0xA1590123,
+/**/ 0x3FDD5BCA, 0x34047661,
+/**/ 0x3C728A44, 0xA75FC29C,
+/**/ 0x3FEC6F39, 0x208BE53B,
+/**/ 0xBC8741DB, 0xFBAADB42,
+/**/ 0x3FDDCD4C, 0x15329C9A,
+/**/ 0x3C70D4C6, 0xE171FD9A,
+/**/ 0x3FEC51A4, 0x8B8B175E,
+/**/ 0xBC61BBB4, 0x3B9AA880,
+/**/ 0x3FDE3E56, 0xC1582A69,
+/**/ 0xBC50A482, 0x1099F88F,
+/**/ 0x3FEC339E, 0xB01DDD81,
+/**/ 0xBC8CAAF5, 0xEE82C5C0,
+/**/ 0x3FDEAEE8, 0x744B05F0,
+/**/ 0xBC5789B4, 0x3C9B027D,
+/**/ 0x3FEC1528, 0x065B7D50,
+/**/ 0xBC889211, 0x1312E828,
+/**/ 0x3FDF1EFF, 0x6BC4F97B,
+/**/ 0x3C717212, 0xF8A7525C,
+/**/ 0x3FEBF641, 0x081E7536,
+/**/ 0x3C8B7BD7, 0x1628A9A1,
+/**/ 0x3FDF8E99, 0xE76ABC97,
+/**/ 0x3C59D950, 0xAF2D00A3,
+/**/ 0x3FEBD6EA, 0x310294F5,
+/**/ 0x3C731BBC, 0xC88C109D,
+/**/ 0x3FDFFDB6, 0x28D2F57A,
+/**/ 0x3C6F4A99, 0x2E905B6A,
+/**/ 0x3FEBB723, 0xFE630F32,
+/**/ 0x3C772BD2, 0x452D0A39,
+/**/ 0x3FE03629, 0x39C69955,
+/**/ 0xBC82D8CD, 0x78397B01,
+/**/ 0x3FEB96EE, 0xEF58840E,
+/**/ 0x3C545A3C, 0xC78FADE0,
+/**/ 0x3FE06D36, 0x86946E5B,
+/**/ 0x3C83F5AE, 0x4538FF1B,
+/**/ 0x3FEB764B, 0x84B704C2,
+/**/ 0xBC8F5848, 0xC21B389B,
+/**/ 0x3FE0A402, 0x1E9E1001,
+/**/ 0xBC86F643, 0xA13914F6,
+/**/ 0x3FEB553A, 0x410C104E,
+/**/ 0x3C58FF79, 0x47027A16,
+/**/ 0x3FE0DA8B, 0x26B5672E,
+/**/ 0xBC8A58DE, 0xF0BEE909,
+/**/ 0x3FEB33BB, 0xA89C8948,
+/**/ 0x3C8EA6A5, 0x1D1F6CA9,
+/**/ 0x3FE110D0, 0xC4B69C3B,
+/**/ 0x3C8D9189, 0x98809981,
+/**/ 0x3FEB11D0, 0x4162A4C6,
+/**/ 0x3C71DD56, 0x1EFBC0C2,
+/**/ 0x3FE146D2, 0x1F8B7F82,
+/**/ 0x3C7BF953, 0x5E2739A8,
+/**/ 0x3FEAEF78, 0x930BD275,
+/**/ 0xBC7F8362, 0x79746F94,
+/**/ 0x3FE17C8E, 0x5F2EEDB0,
+/**/ 0x3C635E57, 0x102E2488,
+/**/ 0x3FEACCB5, 0x26F69DE5,
+/**/ 0x3C88FB6A, 0x8DD6B6CC,
+/**/ 0x3FE1B204, 0xACB02FDD,
+/**/ 0xBC5F190C, 0x70CBB5FF,
+/**/ 0x3FEAA986, 0x88308913,
+/**/ 0xBC0B83D6, 0x07CD5070,
+/**/ 0x3FE1E734, 0x3236574C,
+/**/ 0x3C722A3F, 0xA4F41D5A,
+/**/ 0x3FEA85ED, 0x4373E02D,
+/**/ 0x3C69BE06, 0x385EC792,
+/**/ 0x3FE21C1C, 0x1B0394CF,
+/**/ 0x3C5E5B32, 0x4B23AA31,
+/**/ 0x3FEA61E9, 0xE72586AF,
+/**/ 0x3C858330, 0xE2FD453F,
+/**/ 0x3FE250BB, 0x93788BBB,
+/**/ 0x3C7EA3D0, 0x2457BCCE,
+/**/ 0x3FEA3D7D, 0x0352BDCF,
+/**/ 0xBC868DBA, 0xECA19669,
+/**/ 0x3FE28511, 0xC917A067,
+/**/ 0xBC801DF1, 0xD9A16B70,
+/**/ 0x3FEA18A7, 0x29AEE445,
+/**/ 0x3C395E25, 0x736C0358,
+/**/ 0x3FE2B91D, 0xEA88421E,
+/**/ 0xBC8FA371, 0xDB216AB0,
+/**/ 0x3FE9F368, 0xED912F85,
+/**/ 0xBC81D200, 0xC5791606,
+/**/ 0x3FE2ECDF, 0x279A3082,
+/**/ 0x3C8D3557, 0xE0E7E37E,
+/**/ 0x3FE9CDC2, 0xE3F25E5C,
+/**/ 0x3C83F991, 0x12993F62,
+/**/ 0x3FE32054, 0xB148BC4F,
+/**/ 0x3C8F6B42, 0x095A135B,
+/**/ 0x3FE9A7B5, 0xA36A6514,
+/**/ 0x3C8722CF, 0xCC9FA7A9,
+/**/ 0x3FE3537D, 0xB9BE0367,
+/**/ 0x3C6B327E, 0x7AF040F0,
+/**/ 0x3FE98141, 0xC42E1310,
+/**/ 0x3C8D1FF8, 0x0488F08D,
+/**/ 0x3FE38659, 0x7456282B,
+/**/ 0xBC710FAD, 0xA93B07A8,
+/**/ 0x3FE95A67, 0xE00CB1FD,
+/**/ 0xBC80BEFD, 0xA21F862D,
+/**/ 0x3FE3B8E7, 0x15A2840A,
+/**/ 0xBC797653, 0xA7D2F07B,
+/**/ 0x3FE93328, 0x926D9E92,
+/**/ 0xBC8BB770, 0x03600CDA,
+/**/ 0x3FE3EB25, 0xD36CD53A,
+/**/ 0xBC5BE570, 0xE1570FC0,
+/**/ 0x3FE90B84, 0x784DDAF7,
+/**/ 0xBC70FEB1, 0x0AB93B87,
+/**/ 0x3FE41D14, 0xE4BA6790,
+/**/ 0x3C84608F, 0xD287ECF5,
+/**/ 0x3FE8E37C, 0x303D9AD1,
+/**/ 0xBC6463A4, 0xB53D4BF8,
+/**/ 0x3FE44EB3, 0x81CF386B,
+/**/ 0xBC83ED6C, 0x1E6A5505,
+/**/ 0x3FE8BB10, 0x5A5DC900,
+/**/ 0x3C8863E0, 0x3E9474C1,
+/**/ 0x3FE48000, 0xE431159F,
+/**/ 0xBC8B194A, 0x7463ED10,
+/**/ 0x3FE89241, 0x985D871F,
+/**/ 0x3C8C48D9, 0xC413ED84,
+/**/ 0x3FE4B0FC, 0x46AAB761,
+/**/ 0x3C20DA05, 0x738CC59A,
+/**/ 0x3FE86910, 0x8D77A6C6,
+/**/ 0x3C7338FF, 0xE2BFE9DD,
+/**/ 0x3FE4E1A4, 0xE54ED51B,
+/**/ 0xBC8A492F, 0x89B7C76A,
+/**/ 0x3FE83F7D, 0xDE701CA0,
+/**/ 0xBC4152CF, 0x609BC6E8,
+/**/ 0x3FE511F9, 0xFD7B351C,
+/**/ 0xBC85C0E8, 0x61C48831,
+/**/ 0x3FE8158A, 0x31916D5D,
+/**/ 0xBC6DE8B9, 0x0B8228DE,
+/**/ 0x3FE541FA, 0xCDDBB724,
+/**/ 0x3C7232C2, 0x8520D391,
+/**/ 0x3FE7EB36, 0x2EAA1488,
+/**/ 0x3C5A1D65, 0xA4A5959F,
+/**/ 0x3FE571A6, 0x966D59B3,
+/**/ 0x3C5C843B, 0x4D0FB198,
+/**/ 0x3FE7C082, 0x7F09E54F,
+/**/ 0xBC6C73D6, 0xD72AEE68,
+/**/ 0x3FE5A0FC, 0x98813A12,
+/**/ 0xBC8D82E2, 0xB7D4227B,
+/**/ 0x3FE7956F, 0xCD7F6543,
+/**/ 0xBC8AB276, 0xE9D45AE4,
+/**/ 0x3FE5CFFC, 0x16BF8F0D,
+/**/ 0x3C896CB3, 0x70EB578A,
+/**/ 0x3FE769FE, 0xC655211F,
+/**/ 0xBC6827D5, 0xCF8C68C5,
+/**/ 0x3FE5FEA4, 0x552A9E57,
+/**/ 0x3C80B6CE, 0xF7EE20B7,
+/**/ 0x3FE73E30, 0x174EFBA1,
+/**/ 0xBC65D3AE, 0x3D94AD5F,
+/**/ 0x3FE62CF4, 0x9921AC79,
+/**/ 0xBC8EDD98, 0x55B6241A,
+/**/ 0x3FE71204, 0x6FA77678,
+/**/ 0x3C8425B0, 0xA5029C81,
+/**/ 0x3FE65AEC, 0x2963E755,
+/**/ 0x3C8126F9, 0x6B71053C,
+/**/ 0x3FE6E57C, 0x800CF55E,
+/**/ 0x3C860286, 0xDEDBD0A6,
+/**/ 0x3FE6888A, 0x4E134B2F,
+/**/ 0xBC86B7D3, 0x7644D5E6,
+/**/ 0x3FE6B898, 0xFA9EFB5D,
+/**/ 0x3C715AC7, 0x86CCF4B2,
+/**/ 0x3FE6B5CE, 0x50B7821A,
+/**/ 0xBC65D515, 0x8F702E0F,
+/**/ 0x3FE68B5A, 0x92EB6253,
+/**/ 0xBC89A91A, 0xD985F89C,
+/**/ 0x3FE6E2B7, 0x7C40BDE1,
+/**/ 0xBC70E729, 0x857FAD53,
+/**/ 0x3FE65DC1, 0xFDEB8CBA,
+/**/ 0xBC597C1B, 0x47337C77,
+/**/ 0x3FE70F45, 0x1D0A8C40,
+/**/ 0x3C697EDE, 0x3885770D,
+/**/ 0x3FE62FCF, 0xF20191C7,
+/**/ 0x3C6D9143, 0x895756EF,
+/**/ 0x3FE73B76, 0x80DEA578,
+/**/ 0xBC722483, 0x06DC12A2,
+/**/ 0x3FE60185, 0x26F563DF,
+/**/ 0x3C846CA5, 0xE0E432D0,
+/**/ 0x3FE7674A, 0xF6F7B524,
+/**/ 0x3C7E9D3F, 0x94AC84A8,
+/**/ 0x3FE5D2E2, 0x55F1F17A,
+/**/ 0x3C803141, 0x04C8892B,
+/**/ 0x3FE792C1, 0xD0041D52,
+/**/ 0xBC8ABF05, 0xEEB354EB,
+/**/ 0x3FE5A3E8, 0x39824077,
+/**/ 0x3C8428AA, 0x2759BE62,
+/**/ 0x3FE7BDDA, 0x5E28B3C2,
+/**/ 0x3C4AD119, 0x7CCD0393,
+/**/ 0x3FE57497, 0x8D8E83F2,
+/**/ 0x3C8F4714, 0xAF282D23,
+/**/ 0x3FE7E893, 0xF5037959,
+/**/ 0x3C80EEFB, 0xAA650C4C,
+/**/ 0x3FE544F1, 0x0F592CA5,
+/**/ 0xBC8E7AE8, 0xE6C7A62F,
+/**/ 0x3FE812ED, 0xE9AE4BA4,
+/**/ 0xBC87830A, 0xDF402DDA,
+/**/ 0x3FE514F5, 0x7D7BF3DA,
+/**/ 0x3C747A10, 0x8073C259 } };
+#else
+#ifdef LITTLE_ENDI
+static const union {int4 i[880]; double x[440];} sincos = { .i = {
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00000000, 0x3FF00000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0xAAAEEEEF, 0x3F7FFFEA,
+/**/ 0xEC67B77C, 0xBC1E45E2,
+/**/ 0x00155552, 0x3FEFFFC0,
+/**/ 0xA0196DAE, 0x3C8F4A01,
+/**/ 0xAAEEEED5, 0x3F8FFFAA,
+/**/ 0x9A9F0777, 0xBC02AB63,
+/**/ 0x0155549F, 0x3FEFFF00,
+/**/ 0xA03A5EF3, 0x3C828A28,
+/**/ 0x01033255, 0x3F97FF70,
+/**/ 0x51527336, 0x3BFEFE2B,
+/**/ 0x06BFF7E6, 0x3FEFFDC0,
+/**/ 0xE86977BD, 0x3C8AE6DA,
+/**/ 0xAEEEE86F, 0x3F9FFEAA,
+/**/ 0xFB224AE2, 0xBC3CD406,
+/**/ 0x155527D3, 0x3FEFFC00,
+/**/ 0x92D89B5B, 0xBC83B544,
+/**/ 0xB12D45D5, 0x3FA3FEB2,
+/**/ 0x203D1C11, 0x3C34EC54,
+/**/ 0x3414A7BA, 0x3FEFF9C0,
+/**/ 0xBE6C59BF, 0x3C6991F4,
+/**/ 0x1032FBA9, 0x3FA7FDC0,
+/**/ 0xF46E997A, 0xBC4599BD,
+/**/ 0x6BFDF99F, 0x3FEFF700,
+/**/ 0x60648D5F, 0xBC78B3B5,
+/**/ 0x78586DAC, 0x3FABFC6D,
+/**/ 0x03DBF236, 0x3C18E4FD,
+/**/ 0xC8103A31, 0x3FEFF3C0,
+/**/ 0xBDDC0E66, 0x3C74856D,
+/**/ 0xEEED4EDB, 0x3FAFFAAA,
+/**/ 0x32684B69, 0xBC42D16D,
+/**/ 0x5549F4D3, 0x3FEFF001,
+/**/ 0x7B99426F, 0x3C832838,
+/**/ 0x3D808BEF, 0x3FB1FC34,
+/**/ 0xE6F3BE4F, 0xBC5F3D32,
+/**/ 0x22A8EF9F, 0x3FEFEBC2,
+/**/ 0x34F54C77, 0x3C579349,
+/**/ 0x12D1755B, 0x3FB3FACB,
+/**/ 0x5299468C, 0xBC592191,
+/**/ 0x4129EF6F, 0x3FEFE703,
+/**/ 0x37C96F97, 0xBC6CBF43,
+/**/ 0xFD10B737, 0x3FB5F911,
+/**/ 0x02BE9102, 0xBC50184F,
+/**/ 0xC3C873EB, 0x3FEFE1C4,
+/**/ 0x057C4A02, 0xBC35A9C9,
+/**/ 0x032550E4, 0x3FB7F701,
+/**/ 0x1800501A, 0x3C3AFC2D,
+/**/ 0xBF7E6B9B, 0x3FEFDC06,
+/**/ 0xB535F8DB, 0x3C831902,
+/**/ 0x2D55D1F9, 0x3FB9F490,
+/**/ 0x7EAC1DC1, 0x3C52696D,
+/**/ 0x4B43E000, 0x3FEFD5C9,
+/**/ 0xCB4F92F9, 0xBC62E768,
+/**/ 0x8568391D, 0x3FBBF1B7,
+/**/ 0x1DEA4CC8, 0x3C5E9184,
+/**/ 0x800E99B1, 0x3FEFCF0C,
+/**/ 0x86D186AC, 0x3C6EA3D7,
+/**/ 0x16C1CCE6, 0x3FBDEE6F,
+/**/ 0x2FB71673, 0xBC450F8E,
+/**/ 0x78D1BC88, 0x3FEFC7D0,
+/**/ 0x447DB685, 0x3C8075D2,
+/**/ 0xEE86EE36, 0x3FBFEAAE,
+/**/ 0xBCC6F03B, 0xBC4AFCB2,
+/**/ 0x527D5BD3, 0x3FEFC015,
+/**/ 0x5094EFB8, 0x3C8B68F3,
+/**/ 0x8DDD71D1, 0x3FC0F337,
+/**/ 0x724F0F9E, 0x3C6D8468,
+/**/ 0x2BFE0695, 0x3FEFB7DB,
+/**/ 0xF4F65AB1, 0x3C821DAD,
+/**/ 0xD7AFCEAF, 0x3FC1F0D3,
+/**/ 0x099769A5, 0xBC66EF95,
+/**/ 0x263C4BD3, 0x3FEFAF22,
+/**/ 0x133A2769, 0xBC552ACE,
+/**/ 0x5E4AB88F, 0x3FC2EE28,
+/**/ 0x05DEE058, 0xBC6E4D0F,
+/**/ 0x641C36F2, 0x3FEFA5EA,
+/**/ 0xED17CC7C, 0x3C404DA6,
+/**/ 0x2C5D66CB, 0x3FC3EB31,
+/**/ 0x6B66CB91, 0x3C647D66,
+/**/ 0x0A7CC428, 0x3FEF9C34,
+/**/ 0x063B7462, 0x3C8C5B6B,
+/**/ 0x4DC5F27B, 0x3FC4E7EA,
+/**/ 0x2AC072FC, 0x3C5949DB,
+/**/ 0x40374D01, 0x3FEF91FF,
+/**/ 0x4D3A9E4C, 0xBC67D03F,
+/**/ 0xCFA126F3, 0x3FC5E44F,
+/**/ 0x063F89B6, 0xBC66F443,
+/**/ 0x2E1EECF6, 0x3FEF874C,
+/**/ 0xE1332B16, 0xBC8C6514,
+/**/ 0xC05A4D4C, 0x3FC6E05D,
+/**/ 0x8B81C940, 0xBBD32C5C,
+/**/ 0xFEFFDE24, 0x3FEF7C1A,
+/**/ 0xC47540B1, 0xBC78F55B,
+/**/ 0x2FBAF2B5, 0x3FC7DC10,
+/**/ 0xE23C97C3, 0x3C45AB50,
+/**/ 0xDF9ECE1C, 0x3FEF706B,
+/**/ 0x0C36DCB4, 0xBC8698C8,
+/**/ 0x2EFAA944, 0x3FC8D763,
+/**/ 0x62CBB953, 0xBC620FA2,
+/**/ 0xFEB82ACD, 0x3FEF643E,
+/**/ 0xC1FE28AC, 0x3C76B00A,
+/**/ 0xD0CEC312, 0x3FC9D252,
+/**/ 0x80B1137D, 0x3C59C43D,
+/**/ 0x8CFF6797, 0x3FEF5794,
+/**/ 0x3E03B1D5, 0x3C6E3A0D,
+/**/ 0x297A0765, 0x3FCACCDB,
+/**/ 0x57D6CDEB, 0xBC59883B,
+/**/ 0xBD1E3A79, 0x3FEF4A6C,
+/**/ 0xEDAEBB57, 0x3C813DF0,
+/**/ 0x4EDC6199, 0x3FCBC6F8,
+/**/ 0x6A7B0CAB, 0x3C69C1A5,
+/**/ 0xC3B3D16E, 0x3FEF3CC7,
+/**/ 0xD28A3494, 0xBC621A3A,
+/**/ 0x588289A3, 0x3FCCC0A6,
+/**/ 0x9BC87C6B, 0xBC6868D0,
+/**/ 0xD753FFED, 0x3FEF2EA5,
+/**/ 0x5F56D583, 0x3C8CC421,
+/**/ 0x5FB5A5D0, 0x3FCDB9E1,
+/**/ 0xD6CC6FC2, 0xBC632E20,
+/**/ 0x3086649F, 0x3FEF2007,
+/**/ 0x16C1984B, 0x3C7B9404,
+/**/ 0x7F8AE5A3, 0x3FCEB2A5,
+/**/ 0xAF572CEB, 0xBC60BE06,
+/**/ 0x09C5873B, 0x3FEF10EC,
+/**/ 0x762C1283, 0x3C8D9072,
+/**/ 0xD4F31577, 0x3FCFAAEE,
+/**/ 0x508E32B8, 0xBC615D88,
+/**/ 0x9F7DEEA1, 0x3FEF0154,
+/**/ 0x99E5CAFD, 0x3C8D3C1E,
+/**/ 0xBF65155C, 0x3FD0515C,
+/**/ 0x9DFD8EC8, 0xBC79B8C2,
+/**/ 0x300D2F26, 0x3FEEF141,
+/**/ 0x08DED372, 0xBC82AA1B,
+/**/ 0xCEF36436, 0x3FD0CD00,
+/**/ 0x0C93E2B5, 0xBC79FB0A,
+/**/ 0xFBC0F11C, 0x3FEEE0B1,
+/**/ 0x80BBC3B1, 0xBC4BFD23,
+/**/ 0xAA94DDEB, 0x3FD14861,
+/**/ 0xB5B615A4, 0xBC6BE881,
+/**/ 0x44D5EFA1, 0x3FEECFA7,
+/**/ 0x4AF541D0, 0xBC556D0A,
+/**/ 0x64C6B876, 0x3FD1C37D,
+/**/ 0xFE0DCFF5, 0x3C746076,
+/**/ 0x4F76EFA8, 0x3FEEBE21,
+/**/ 0x12BA543E, 0xBC802F9F,
+/**/ 0x111AAF36, 0x3FD23E52,
+/**/ 0x334EFF18, 0xBC74F080,
+/**/ 0x61BBAF4F, 0x3FEEAC20,
+/**/ 0x3E94658D, 0x3C62C1D5,
+/**/ 0xC43EB49F, 0x3FD2B8DD,
+/**/ 0x99F2D807, 0x3C615538,
+/**/ 0xC3A7CD83, 0x3FEE99A4,
+/**/ 0x1BC53CE8, 0xBC82264B,
+/**/ 0x94049F87, 0x3FD3331E,
+/**/ 0xB40C302C, 0x3C7E0CB6,
+/**/ 0xBF29A9ED, 0x3FEE86AE,
+/**/ 0xFDBB58A7, 0x3C89397A,
+/**/ 0x9769D3D8, 0x3FD3AD12,
+/**/ 0x04878398, 0x3C003D55,
+/**/ 0xA0193D40, 0x3FEE733E,
+/**/ 0x3546CE13, 0xBC86428B,
+/**/ 0xE69EE697, 0x3FD426B7,
+/**/ 0x5705C59F, 0xBC7F09C7,
+/**/ 0xB436E9D0, 0x3FEE5F54,
+/**/ 0xD02FC8BC, 0x3C87EB0F,
+/**/ 0x9B0F3D20, 0x3FD4A00C,
+/**/ 0x6BB08EAD, 0x3C7823BA,
+/**/ 0x4B2A449C, 0x3FEE4AF1,
+/**/ 0x2E8A6833, 0xBC868CA0,
+/**/ 0xCF68A77A, 0x3FD5190E,
+/**/ 0x55EEF0F3, 0x3C7B3571,
+/**/ 0xB680D6A5, 0x3FEE3614,
+/**/ 0xAA015237, 0xBC727793,
+/**/ 0x9FA2F597, 0x3FD591BC,
+/**/ 0xAC3FE0CB, 0x3C67C74B,
+/**/ 0x49ACD6C1, 0x3FEE20BF,
+/**/ 0xC7EF636C, 0xBC5660AE,
+/**/ 0x29078775, 0x3FD60A14,
+/**/ 0x0BA89133, 0x3C5B1FD8,
+/**/ 0x5A03DBCE, 0x3FEE0AF1,
+/**/ 0x02771AE6, 0x3C5FE8E7,
+/**/ 0x8A38D7F7, 0x3FD68213,
+/**/ 0x02444AAD, 0xBC7D8892,
+/**/ 0x3EBD875E, 0x3FEDF4AB,
+/**/ 0x7E6736C4, 0xBC8E2D8A,
+/**/ 0xE33A0255, 0x3FD6F9B8,
+/**/ 0x4EE9DA0D, 0x3C742BC1,
+/**/ 0x50F228D6, 0x3FEDDDED,
+/**/ 0xD42BA2BF, 0xBC6E80C8,
+/**/ 0x55764214, 0x3FD77102,
+/**/ 0x314BB6CE, 0xBC66EAD7,
+/**/ 0xEB995912, 0x3FEDC6B7,
+/**/ 0x776DCD35, 0x3C54B364,
+/**/ 0x03C86D4E, 0x3FD7E7EE,
+/**/ 0xDABF5AF2, 0xBC7B63BC,
+/**/ 0x6B888E83, 0x3FEDAF0B,
+/**/ 0x2B5E5CEA, 0x3C8A249E,
+/**/ 0x12826949, 0x3FD85E7A,
+/**/ 0x9B5FACE0, 0x3C78A40E,
+/**/ 0x2F71A9DC, 0x3FED96E8,
+/**/ 0xD5D2039D, 0x3C8FF61B,
+/**/ 0xA774992F, 0x3FD8D4A4,
+/**/ 0xEA766326, 0x3C744A02,
+/**/ 0x97E17B4A, 0x3FED7E4E,
+/**/ 0x352BED94, 0xBC63B770,
+/**/ 0xE9F546C5, 0x3FD94A6B,
+/**/ 0x3E683F58, 0xBC769CE1,
+/**/ 0x073E4040, 0x3FED653F,
+/**/ 0x434BEC37, 0xBC876236,
+/**/ 0x02E80510, 0x3FD9BFCE,
+/**/ 0xA320B0A4, 0x3C709E39,
+/**/ 0xE1C619E0, 0x3FED4BB9,
+/**/ 0x77858F61, 0x3C8F34BB,
+/**/ 0x1CC50CCA, 0x3FDA34C9,
+/**/ 0x3B50CECD, 0xBC5A310E,
+/**/ 0x8D8D7C06, 0x3FED31BF,
+/**/ 0x3089CBDD, 0x3C7E60DD,
+/**/ 0x63A09277, 0x3FDAA95B,
+/**/ 0xB13C0381, 0xBC66293E,
+/**/ 0x727D94F0, 0x3FED1750,
+/**/ 0x1EC1A48E, 0x3C80D52B,
+/**/ 0x05321617, 0x3FDB1D83,
+/**/ 0xCB99F519, 0xBC7AE242,
+/**/ 0xFA52AD9F, 0x3FECFC6C,
+/**/ 0x508F2A0D, 0x3C88B5B5,
+/**/ 0x30DBAC43, 0x3FDB913E,
+/**/ 0x2F6C3FF1, 0xBC7E38AD,
+/**/ 0x909A82E5, 0x3FECE115,
+/**/ 0xBB31109A, 0x3C81F139,
+/**/ 0x17B140A3, 0x3FDC048B,
+/**/ 0x757E9FA7, 0x3C619FE6,
+/**/ 0xA2B2972E, 0x3FECC54A,
+/**/ 0x2BA83A98, 0x3C64EE16,
+/**/ 0xEC7FD19E, 0x3FDC7767,
+/**/ 0x1A3D5826, 0xBC5EB14D,
+/**/ 0x9FC67D0B, 0x3FECA90C,
+/**/ 0x485E3462, 0xBC646A81,
+/**/ 0xE3D4A51F, 0x3FDCE9D2,
+/**/ 0x12DAE298, 0xBC62FC8A,
+/**/ 0xF8CE1A84, 0x3FEC8C5B,
+/**/ 0xA1590123, 0x3C7AB3D1,
+/**/ 0x34047661, 0x3FDD5BCA,
+/**/ 0xA75FC29C, 0x3C728A44,
+/**/ 0x208BE53B, 0x3FEC6F39,
+/**/ 0xFBAADB42, 0xBC8741DB,
+/**/ 0x15329C9A, 0x3FDDCD4C,
+/**/ 0xE171FD9A, 0x3C70D4C6,
+/**/ 0x8B8B175E, 0x3FEC51A4,
+/**/ 0x3B9AA880, 0xBC61BBB4,
+/**/ 0xC1582A69, 0x3FDE3E56,
+/**/ 0x1099F88F, 0xBC50A482,
+/**/ 0xB01DDD81, 0x3FEC339E,
+/**/ 0xEE82C5C0, 0xBC8CAAF5,
+/**/ 0x744B05F0, 0x3FDEAEE8,
+/**/ 0x3C9B027D, 0xBC5789B4,
+/**/ 0x065B7D50, 0x3FEC1528,
+/**/ 0x1312E828, 0xBC889211,
+/**/ 0x6BC4F97B, 0x3FDF1EFF,
+/**/ 0xF8A7525C, 0x3C717212,
+/**/ 0x081E7536, 0x3FEBF641,
+/**/ 0x1628A9A1, 0x3C8B7BD7,
+/**/ 0xE76ABC97, 0x3FDF8E99,
+/**/ 0xAF2D00A3, 0x3C59D950,
+/**/ 0x310294F5, 0x3FEBD6EA,
+/**/ 0xC88C109D, 0x3C731BBC,
+/**/ 0x28D2F57A, 0x3FDFFDB6,
+/**/ 0x2E905B6A, 0x3C6F4A99,
+/**/ 0xFE630F32, 0x3FEBB723,
+/**/ 0x452D0A39, 0x3C772BD2,
+/**/ 0x39C69955, 0x3FE03629,
+/**/ 0x78397B01, 0xBC82D8CD,
+/**/ 0xEF58840E, 0x3FEB96EE,
+/**/ 0xC78FADE0, 0x3C545A3C,
+/**/ 0x86946E5B, 0x3FE06D36,
+/**/ 0x4538FF1B, 0x3C83F5AE,
+/**/ 0x84B704C2, 0x3FEB764B,
+/**/ 0xC21B389B, 0xBC8F5848,
+/**/ 0x1E9E1001, 0x3FE0A402,
+/**/ 0xA13914F6, 0xBC86F643,
+/**/ 0x410C104E, 0x3FEB553A,
+/**/ 0x47027A16, 0x3C58FF79,
+/**/ 0x26B5672E, 0x3FE0DA8B,
+/**/ 0xF0BEE909, 0xBC8A58DE,
+/**/ 0xA89C8948, 0x3FEB33BB,
+/**/ 0x1D1F6CA9, 0x3C8EA6A5,
+/**/ 0xC4B69C3B, 0x3FE110D0,
+/**/ 0x98809981, 0x3C8D9189,
+/**/ 0x4162A4C6, 0x3FEB11D0,
+/**/ 0x1EFBC0C2, 0x3C71DD56,
+/**/ 0x1F8B7F82, 0x3FE146D2,
+/**/ 0x5E2739A8, 0x3C7BF953,
+/**/ 0x930BD275, 0x3FEAEF78,
+/**/ 0x79746F94, 0xBC7F8362,
+/**/ 0x5F2EEDB0, 0x3FE17C8E,
+/**/ 0x102E2488, 0x3C635E57,
+/**/ 0x26F69DE5, 0x3FEACCB5,
+/**/ 0x8DD6B6CC, 0x3C88FB6A,
+/**/ 0xACB02FDD, 0x3FE1B204,
+/**/ 0x70CBB5FF, 0xBC5F190C,
+/**/ 0x88308913, 0x3FEAA986,
+/**/ 0x07CD5070, 0xBC0B83D6,
+/**/ 0x3236574C, 0x3FE1E734,
+/**/ 0xA4F41D5A, 0x3C722A3F,
+/**/ 0x4373E02D, 0x3FEA85ED,
+/**/ 0x385EC792, 0x3C69BE06,
+/**/ 0x1B0394CF, 0x3FE21C1C,
+/**/ 0x4B23AA31, 0x3C5E5B32,
+/**/ 0xE72586AF, 0x3FEA61E9,
+/**/ 0xE2FD453F, 0x3C858330,
+/**/ 0x93788BBB, 0x3FE250BB,
+/**/ 0x2457BCCE, 0x3C7EA3D0,
+/**/ 0x0352BDCF, 0x3FEA3D7D,
+/**/ 0xECA19669, 0xBC868DBA,
+/**/ 0xC917A067, 0x3FE28511,
+/**/ 0xD9A16B70, 0xBC801DF1,
+/**/ 0x29AEE445, 0x3FEA18A7,
+/**/ 0x736C0358, 0x3C395E25,
+/**/ 0xEA88421E, 0x3FE2B91D,
+/**/ 0xDB216AB0, 0xBC8FA371,
+/**/ 0xED912F85, 0x3FE9F368,
+/**/ 0xC5791606, 0xBC81D200,
+/**/ 0x279A3082, 0x3FE2ECDF,
+/**/ 0xE0E7E37E, 0x3C8D3557,
+/**/ 0xE3F25E5C, 0x3FE9CDC2,
+/**/ 0x12993F62, 0x3C83F991,
+/**/ 0xB148BC4F, 0x3FE32054,
+/**/ 0x095A135B, 0x3C8F6B42,
+/**/ 0xA36A6514, 0x3FE9A7B5,
+/**/ 0xCC9FA7A9, 0x3C8722CF,
+/**/ 0xB9BE0367, 0x3FE3537D,
+/**/ 0x7AF040F0, 0x3C6B327E,
+/**/ 0xC42E1310, 0x3FE98141,
+/**/ 0x0488F08D, 0x3C8D1FF8,
+/**/ 0x7456282B, 0x3FE38659,
+/**/ 0xA93B07A8, 0xBC710FAD,
+/**/ 0xE00CB1FD, 0x3FE95A67,
+/**/ 0xA21F862D, 0xBC80BEFD,
+/**/ 0x15A2840A, 0x3FE3B8E7,
+/**/ 0xA7D2F07B, 0xBC797653,
+/**/ 0x926D9E92, 0x3FE93328,
+/**/ 0x03600CDA, 0xBC8BB770,
+/**/ 0xD36CD53A, 0x3FE3EB25,
+/**/ 0xE1570FC0, 0xBC5BE570,
+/**/ 0x784DDAF7, 0x3FE90B84,
+/**/ 0x0AB93B87, 0xBC70FEB1,
+/**/ 0xE4BA6790, 0x3FE41D14,
+/**/ 0xD287ECF5, 0x3C84608F,
+/**/ 0x303D9AD1, 0x3FE8E37C,
+/**/ 0xB53D4BF8, 0xBC6463A4,
+/**/ 0x81CF386B, 0x3FE44EB3,
+/**/ 0x1E6A5505, 0xBC83ED6C,
+/**/ 0x5A5DC900, 0x3FE8BB10,
+/**/ 0x3E9474C1, 0x3C8863E0,
+/**/ 0xE431159F, 0x3FE48000,
+/**/ 0x7463ED10, 0xBC8B194A,
+/**/ 0x985D871F, 0x3FE89241,
+/**/ 0xC413ED84, 0x3C8C48D9,
+/**/ 0x46AAB761, 0x3FE4B0FC,
+/**/ 0x738CC59A, 0x3C20DA05,
+/**/ 0x8D77A6C6, 0x3FE86910,
+/**/ 0xE2BFE9DD, 0x3C7338FF,
+/**/ 0xE54ED51B, 0x3FE4E1A4,
+/**/ 0x89B7C76A, 0xBC8A492F,
+/**/ 0xDE701CA0, 0x3FE83F7D,
+/**/ 0x609BC6E8, 0xBC4152CF,
+/**/ 0xFD7B351C, 0x3FE511F9,
+/**/ 0x61C48831, 0xBC85C0E8,
+/**/ 0x31916D5D, 0x3FE8158A,
+/**/ 0x0B8228DE, 0xBC6DE8B9,
+/**/ 0xCDDBB724, 0x3FE541FA,
+/**/ 0x8520D391, 0x3C7232C2,
+/**/ 0x2EAA1488, 0x3FE7EB36,
+/**/ 0xA4A5959F, 0x3C5A1D65,
+/**/ 0x966D59B3, 0x3FE571A6,
+/**/ 0x4D0FB198, 0x3C5C843B,
+/**/ 0x7F09E54F, 0x3FE7C082,
+/**/ 0xD72AEE68, 0xBC6C73D6,
+/**/ 0x98813A12, 0x3FE5A0FC,
+/**/ 0xB7D4227B, 0xBC8D82E2,
+/**/ 0xCD7F6543, 0x3FE7956F,
+/**/ 0xE9D45AE4, 0xBC8AB276,
+/**/ 0x16BF8F0D, 0x3FE5CFFC,
+/**/ 0x70EB578A, 0x3C896CB3,
+/**/ 0xC655211F, 0x3FE769FE,
+/**/ 0xCF8C68C5, 0xBC6827D5,
+/**/ 0x552A9E57, 0x3FE5FEA4,
+/**/ 0xF7EE20B7, 0x3C80B6CE,
+/**/ 0x174EFBA1, 0x3FE73E30,
+/**/ 0x3D94AD5F, 0xBC65D3AE,
+/**/ 0x9921AC79, 0x3FE62CF4,
+/**/ 0x55B6241A, 0xBC8EDD98,
+/**/ 0x6FA77678, 0x3FE71204,
+/**/ 0xA5029C81, 0x3C8425B0,
+/**/ 0x2963E755, 0x3FE65AEC,
+/**/ 0x6B71053C, 0x3C8126F9,
+/**/ 0x800CF55E, 0x3FE6E57C,
+/**/ 0xDEDBD0A6, 0x3C860286,
+/**/ 0x4E134B2F, 0x3FE6888A,
+/**/ 0x7644D5E6, 0xBC86B7D3,
+/**/ 0xFA9EFB5D, 0x3FE6B898,
+/**/ 0x86CCF4B2, 0x3C715AC7,
+/**/ 0x50B7821A, 0x3FE6B5CE,
+/**/ 0x8F702E0F, 0xBC65D515,
+/**/ 0x92EB6253, 0x3FE68B5A,
+/**/ 0xD985F89C, 0xBC89A91A,
+/**/ 0x7C40BDE1, 0x3FE6E2B7,
+/**/ 0x857FAD53, 0xBC70E729,
+/**/ 0xFDEB8CBA, 0x3FE65DC1,
+/**/ 0x47337C77, 0xBC597C1B,
+/**/ 0x1D0A8C40, 0x3FE70F45,
+/**/ 0x3885770D, 0x3C697EDE,
+/**/ 0xF20191C7, 0x3FE62FCF,
+/**/ 0x895756EF, 0x3C6D9143,
+/**/ 0x80DEA578, 0x3FE73B76,
+/**/ 0x06DC12A2, 0xBC722483,
+/**/ 0x26F563DF, 0x3FE60185,
+/**/ 0xE0E432D0, 0x3C846CA5,
+/**/ 0xF6F7B524, 0x3FE7674A,
+/**/ 0x94AC84A8, 0x3C7E9D3F,
+/**/ 0x55F1F17A, 0x3FE5D2E2,
+/**/ 0x04C8892B, 0x3C803141,
+/**/ 0xD0041D52, 0x3FE792C1,
+/**/ 0xEEB354EB, 0xBC8ABF05,
+/**/ 0x39824077, 0x3FE5A3E8,
+/**/ 0x2759BE62, 0x3C8428AA,
+/**/ 0x5E28B3C2, 0x3FE7BDDA,
+/**/ 0x7CCD0393, 0x3C4AD119,
+/**/ 0x8D8E83F2, 0x3FE57497,
+/**/ 0xAF282D23, 0x3C8F4714,
+/**/ 0xF5037959, 0x3FE7E893,
+/**/ 0xAA650C4C, 0x3C80EEFB,
+/**/ 0x0F592CA5, 0x3FE544F1,
+/**/ 0xE6C7A62F, 0xBC8E7AE8,
+/**/ 0xE9AE4BA4, 0x3FE812ED,
+/**/ 0xDF402DDA, 0xBC87830A,
+/**/ 0x7D7BF3DA, 0x3FE514F5,
+/**/ 0x8073C259, 0x3C747A10 } };
+#endif
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/sincos32.c b/libc/sysdeps/ieee754/dbl-64/sincos32.c
new file mode 100644
index 000000000..a4f896a46
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/sincos32.c
@@ -0,0 +1,352 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/****************************************************************/
+/* MODULE_NAME: sincos32.c */
+/* */
+/* FUNCTIONS: ss32 */
+/* cc32 */
+/* c32 */
+/* sin32 */
+/* cos32 */
+/* mpsin */
+/* mpcos */
+/* mpranred */
+/* mpsin1 */
+/* mpcos1 */
+/* */
+/* FILES NEEDED: endian.h mpa.h sincos32.h */
+/* mpa.c */
+/* */
+/* Multi Precision sin() and cos() function with p=32 for sin()*/
+/* cos() arcsin() and arccos() routines */
+/* In addition mpranred() routine performs range reduction of */
+/* a double number x into multi precision number y, */
+/* such that y=x-n*pi/2, abs(y)<pi/4, n=0,+-1,+-2,.... */
+/****************************************************************/
+#include "endian.h"
+#include "mpa.h"
+#include "sincos32.h"
+#include "math_private.h"
+
+/****************************************************************/
+/* Compute Multi-Precision sin() function for given p. Receive */
+/* Multi Precision number x and result stored at y */
+/****************************************************************/
+static void ss32(mp_no *x, mp_no *y, int p) {
+ int i;
+ double a;
+#if 0
+ double b;
+ static const mp_no mpone = {1,{1.0,1.0}};
+#endif
+ mp_no mpt1,x2,gor,sum ,mpk={1,{1.0}};
+#if 0
+ mp_no mpt2;
+#endif
+ for (i=1;i<=p;i++) mpk.d[i]=0;
+
+ __mul(x,x,&x2,p);
+ __cpy(&oofac27,&gor,p);
+ __cpy(&gor,&sum,p);
+ for (a=27.0;a>1.0;a-=2.0) {
+ mpk.d[1]=a*(a-1.0);
+ __mul(&gor,&mpk,&mpt1,p);
+ __cpy(&mpt1,&gor,p);
+ __mul(&x2,&sum,&mpt1,p);
+ __sub(&gor,&mpt1,&sum,p);
+ }
+ __mul(x,&sum,y,p);
+}
+
+/**********************************************************************/
+/* Compute Multi-Precision cos() function for given p. Receive Multi */
+/* Precision number x and result stored at y */
+/**********************************************************************/
+static void cc32(mp_no *x, mp_no *y, int p) {
+ int i;
+ double a;
+#if 0
+ double b;
+ static const mp_no mpone = {1,{1.0,1.0}};
+#endif
+ mp_no mpt1,x2,gor,sum ,mpk={1,{1.0}};
+#if 0
+ mp_no mpt2;
+#endif
+ for (i=1;i<=p;i++) mpk.d[i]=0;
+
+ __mul(x,x,&x2,p);
+ mpk.d[1]=27.0;
+ __mul(&oofac27,&mpk,&gor,p);
+ __cpy(&gor,&sum,p);
+ for (a=26.0;a>2.0;a-=2.0) {
+ mpk.d[1]=a*(a-1.0);
+ __mul(&gor,&mpk,&mpt1,p);
+ __cpy(&mpt1,&gor,p);
+ __mul(&x2,&sum,&mpt1,p);
+ __sub(&gor,&mpt1,&sum,p);
+ }
+ __mul(&x2,&sum,y,p);
+}
+
+/***************************************************************************/
+/* c32() computes both sin(x), cos(x) as Multi precision numbers */
+/***************************************************************************/
+void __c32(mp_no *x, mp_no *y, mp_no *z, int p) {
+ static const mp_no mpt={1,{1.0,2.0}}, one={1,{1.0,1.0}};
+ mp_no u,t,t1,t2,c,s;
+ int i;
+ __cpy(x,&u,p);
+ u.e=u.e-1;
+ cc32(&u,&c,p);
+ ss32(&u,&s,p);
+ for (i=0;i<24;i++) {
+ __mul(&c,&s,&t,p);
+ __sub(&s,&t,&t1,p);
+ __add(&t1,&t1,&s,p);
+ __sub(&mpt,&c,&t1,p);
+ __mul(&t1,&c,&t2,p);
+ __add(&t2,&t2,&c,p);
+ }
+ __sub(&one,&c,y,p);
+ __cpy(&s,z,p);
+}
+
+/************************************************************************/
+/*Routine receive double x and two double results of sin(x) and return */
+/*result which is more accurate */
+/*Computing sin(x) with multi precision routine c32 */
+/************************************************************************/
+double __sin32(double x, double res, double res1) {
+ int p;
+ mp_no a,b,c;
+ p=32;
+ __dbl_mp(res,&a,p);
+ __dbl_mp(0.5*(res1-res),&b,p);
+ __add(&a,&b,&c,p);
+ if (x>0.8)
+ { __sub(&hp,&c,&a,p);
+ __c32(&a,&b,&c,p);
+ }
+ else __c32(&c,&a,&b,p); /* b=sin(0.5*(res+res1)) */
+ __dbl_mp(x,&c,p); /* c = x */
+ __sub(&b,&c,&a,p);
+ /* if a>0 return min(res,res1), otherwise return max(res,res1) */
+ if (a.d[0]>0) return (res<res1)?res:res1;
+ else return (res>res1)?res:res1;
+}
+
+/************************************************************************/
+/*Routine receive double x and two double results of cos(x) and return */
+/*result which is more accurate */
+/*Computing cos(x) with multi precision routine c32 */
+/************************************************************************/
+double __cos32(double x, double res, double res1) {
+ int p;
+ mp_no a,b,c;
+ p=32;
+ __dbl_mp(res,&a,p);
+ __dbl_mp(0.5*(res1-res),&b,p);
+ __add(&a,&b,&c,p);
+ if (x>2.4)
+ { __sub(&pi,&c,&a,p);
+ __c32(&a,&b,&c,p);
+ b.d[0]=-b.d[0];
+ }
+ else if (x>0.8)
+ { __sub(&hp,&c,&a,p);
+ __c32(&a,&c,&b,p);
+ }
+ else __c32(&c,&b,&a,p); /* b=cos(0.5*(res+res1)) */
+ __dbl_mp(x,&c,p); /* c = x */
+ __sub(&b,&c,&a,p);
+ /* if a>0 return max(res,res1), otherwise return min(res,res1) */
+ if (a.d[0]>0) return (res>res1)?res:res1;
+ else return (res<res1)?res:res1;
+}
+
+/*******************************************************************/
+/*Compute sin(x+dx) as Multi Precision number and return result as */
+/* double */
+/*******************************************************************/
+double __mpsin(double x, double dx) {
+ int p;
+ double y;
+ mp_no a,b,c;
+ p=32;
+ __dbl_mp(x,&a,p);
+ __dbl_mp(dx,&b,p);
+ __add(&a,&b,&c,p);
+ if (x>0.8) { __sub(&hp,&c,&a,p); __c32(&a,&b,&c,p); }
+ else __c32(&c,&a,&b,p); /* b = sin(x+dx) */
+ __mp_dbl(&b,&y,p);
+ return y;
+}
+
+/*******************************************************************/
+/* Compute cos()of double-length number (x+dx) as Multi Precision */
+/* number and return result as double */
+/*******************************************************************/
+double __mpcos(double x, double dx) {
+ int p;
+ double y;
+ mp_no a,b,c;
+ p=32;
+ __dbl_mp(x,&a,p);
+ __dbl_mp(dx,&b,p);
+ __add(&a,&b,&c,p);
+ if (x>0.8)
+ { __sub(&hp,&c,&b,p);
+ __c32(&b,&c,&a,p);
+ }
+ else __c32(&c,&a,&b,p); /* a = cos(x+dx) */
+ __mp_dbl(&a,&y,p);
+ return y;
+}
+
+/******************************************************************/
+/* mpranred() performs range reduction of a double number x into */
+/* multi precision number y, such that y=x-n*pi/2, abs(y)<pi/4, */
+/* n=0,+-1,+-2,.... */
+/* Return int which indicates in which quarter of circle x is */
+/******************************************************************/
+int __mpranred(double x, mp_no *y, int p)
+{
+ number v;
+ double t,xn;
+ int i,k,n;
+ static const mp_no one = {1,{1.0,1.0}};
+ mp_no a,b,c;
+
+ if (ABS(x) < 2.8e14) {
+ t = (x*hpinv.d + toint.d);
+ xn = t - toint.d;
+ v.d = t;
+ n =v.i[LOW_HALF]&3;
+ __dbl_mp(xn,&a,p);
+ __mul(&a,&hp,&b,p);
+ __dbl_mp(x,&c,p);
+ __sub(&c,&b,y,p);
+ return n;
+ }
+ else { /* if x is very big more precision required */
+ __dbl_mp(x,&a,p);
+ a.d[0]=1.0;
+ k = a.e-5;
+ if (k < 0) k=0;
+ b.e = -k;
+ b.d[0] = 1.0;
+ for (i=0;i<p;i++) b.d[i+1] = toverp[i+k];
+ __mul(&a,&b,&c,p);
+ t = c.d[c.e];
+ for (i=1;i<=p-c.e;i++) c.d[i]=c.d[i+c.e];
+ for (i=p+1-c.e;i<=p;i++) c.d[i]=0;
+ c.e=0;
+ if (c.d[1] >= 8388608.0)
+ { t +=1.0;
+ __sub(&c,&one,&b,p);
+ __mul(&b,&hp,y,p);
+ }
+ else __mul(&c,&hp,y,p);
+ n = (int) t;
+ if (x < 0) { y->d[0] = - y->d[0]; n = -n; }
+ return (n&3);
+ }
+}
+
+/*******************************************************************/
+/* Multi-Precision sin() function subroutine, for p=32. It is */
+/* based on the routines mpranred() and c32(). */
+/*******************************************************************/
+double __mpsin1(double x)
+{
+ int p;
+ int n;
+ mp_no u,s,c;
+ double y;
+ p=32;
+ n=__mpranred(x,&u,p); /* n is 0, 1, 2 or 3 */
+ __c32(&u,&c,&s,p);
+ switch (n) { /* in which quarter of unit circle y is*/
+ case 0:
+ __mp_dbl(&s,&y,p);
+ return y;
+ break;
+
+ case 2:
+ __mp_dbl(&s,&y,p);
+ return -y;
+ break;
+
+ case 1:
+ __mp_dbl(&c,&y,p);
+ return y;
+ break;
+
+ case 3:
+ __mp_dbl(&c,&y,p);
+ return -y;
+ break;
+
+ }
+ return 0; /* unreachable, to make the compiler happy */
+}
+
+/*****************************************************************/
+/* Multi-Precision cos() function subroutine, for p=32. It is */
+/* based on the routines mpranred() and c32(). */
+/*****************************************************************/
+
+double __mpcos1(double x)
+{
+ int p;
+ int n;
+ mp_no u,s,c;
+ double y;
+
+ p=32;
+ n=__mpranred(x,&u,p); /* n is 0, 1, 2 or 3 */
+ __c32(&u,&c,&s,p);
+ switch (n) { /* in what quarter of unit circle y is*/
+
+ case 0:
+ __mp_dbl(&c,&y,p);
+ return y;
+ break;
+
+ case 2:
+ __mp_dbl(&c,&y,p);
+ return -y;
+ break;
+
+ case 1:
+ __mp_dbl(&s,&y,p);
+ return -y;
+ break;
+
+ case 3:
+ __mp_dbl(&s,&y,p);
+ return y;
+ break;
+
+ }
+ return 0; /* unreachable, to make the compiler happy */
+}
+/******************************************************************/
diff --git a/libc/sysdeps/ieee754/dbl-64/sincos32.h b/libc/sysdeps/ieee754/dbl-64/sincos32.h
new file mode 100644
index 000000000..ee9d5a4cc
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/sincos32.h
@@ -0,0 +1,82 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/******************************************************************/
+/* */
+/* MODULE_NAME:sincos32.h */
+/* */
+/* common data and variables prototype and definition */
+/******************************************************************/
+
+#ifndef SINCOS32_H
+#define SINCCOS32_H
+
+#ifdef BIG_ENDI
+static const number
+/**/ hpinv = {{0x3FE45F30, 0x6DC9C883}}, /* 0.63661977236758138 */
+/**/ toint = {{0x43380000, 0x00000000}}; /* 6755399441055744 */
+
+#else
+#ifdef LITTLE_ENDI
+static const number
+/**/ hpinv = {{0x6DC9C883, 0x3FE45F30}}, /* 0.63661977236758138 */
+/**/ toint = {{0x00000000, 0x43380000}}; /* 6755399441055744 */
+
+#endif
+#endif
+
+static const mp_no
+ oofac27 = {-3,{1.0,7.0,4631664.0,12006312.0,13118056.0,6538613.0,646354.0,
+ 8508025.0,9131256.0,7548776.0,2529842.0,8864927.0,660489.0,15595125.0,12777885.0,
+ 11618489.0,13348664.0,5486686.0,514518.0,11275535.0,4727621.0,3575562.0,
+ 13579710.0,5829745.0,7531862.0,9507898.0,6915060.0,4079264.0,1907586.0,
+ 6078398.0,13789314.0,5504104.0,14136.0}},
+ pi = {1,{1.0,3.0,
+ 2375530.0,8947107.0,578323.0,1673774.0,225395.0,4498441.0,3678761.0,
+ 10432976.0,536314.0,10021966.0,7113029.0,2630118.0,3723283.0,7847508.0,
+ 6737716.0,15273068.0,12626985.0,12044668.0,5299519.0,8705461.0,11880201.0,
+ 1544726.0,14014857.0,7994139.0,13709579.0,10918111.0,11906095.0,16610011.0,
+ 13638367.0,12040417.0,11529578.0,2522774.0}},
+ hp = {1,{1.0, 1.0,
+ 9576373.0,4473553.0,8677769.0,9225495.0,112697.0,10637828.0,
+ 10227988.0,13605096.0,268157.0,5010983.0,3556514.0,9703667.0,
+ 1861641.0,12312362.0,3368858.0,7636534.0,6313492.0,14410942.0,
+ 2649759.0,12741338.0,14328708.0,9160971.0,7007428.0,12385677.0,
+ 15243397.0,13847663.0,14341655.0,16693613.0,15207791.0,14408816.0,
+ 14153397.0,1261387.0,6110792.0,2291862.0,4181138.0,5295267.0}};
+
+static const double toverp[75] = {
+ 10680707.0, 7228996.0, 1387004.0, 2578385.0, 16069853.0,
+ 12639074.0, 9804092.0, 4427841.0, 16666979.0, 11263675.0,
+ 12935607.0, 2387514.0, 4345298.0, 14681673.0, 3074569.0,
+ 13734428.0, 16653803.0, 1880361.0, 10960616.0, 8533493.0,
+ 3062596.0, 8710556.0, 7349940.0, 6258241.0, 3772886.0,
+ 3769171.0, 3798172.0, 8675211.0, 12450088.0, 3874808.0,
+ 9961438.0, 366607.0, 15675153.0, 9132554.0, 7151469.0,
+ 3571407.0, 2607881.0, 12013382.0, 4155038.0, 6285869.0,
+ 7677882.0, 13102053.0, 15825725.0, 473591.0, 9065106.0,
+ 15363067.0, 6271263.0, 9264392.0, 5636912.0, 4652155.0,
+ 7056368.0, 13614112.0, 10155062.0, 1944035.0, 9527646.0,
+ 15080200.0, 6658437.0, 6231200.0, 6832269.0, 16767104.0,
+ 5075751.0, 3212806.0, 1398474.0, 7579849.0, 6349435.0,
+ 12618859.0, 4703257.0, 12806093.0, 14477321.0, 2786137.0,
+ 12875403.0, 9837734.0, 14528324.0, 13719321.0, 343717.0 };
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/slowexp.c b/libc/sysdeps/ieee754/dbl-64/slowexp.c
new file mode 100644
index 000000000..78c107f70
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/slowexp.c
@@ -0,0 +1,66 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/**************************************************************************/
+/* MODULE_NAME:slowexp.c */
+/* */
+/* FUNCTION:slowexp */
+/* */
+/* FILES NEEDED:mpa.h */
+/* mpa.c mpexp.c */
+/* */
+/*Converting from double precision to Multi-precision and calculating */
+/* e^x */
+/**************************************************************************/
+#include "mpa.h"
+#include "math_private.h"
+
+void __mpexp(mp_no *x, mp_no *y, int p);
+
+/*Converting from double precision to Multi-precision and calculating e^x */
+double __slowexp(double x) {
+ double w,z,res,eps=3.0e-26;
+#if 0
+ double y;
+#endif
+ int p;
+#if 0
+ int orig,i;
+#endif
+ mp_no mpx, mpy, mpz,mpw,mpeps,mpcor;
+
+ p=6;
+ __dbl_mp(x,&mpx,p); /* Convert a double precision number x */
+ /* into a multiple precision number mpx with prec. p. */
+ __mpexp(&mpx, &mpy, p); /* Multi-Precision exponential function */
+ __dbl_mp(eps,&mpeps,p);
+ __mul(&mpeps,&mpy,&mpcor,p);
+ __add(&mpy,&mpcor,&mpw,p);
+ __sub(&mpy,&mpcor,&mpz,p);
+ __mp_dbl(&mpw, &w, p);
+ __mp_dbl(&mpz, &z, p);
+ if (w == z) return w;
+ else { /* if calculating is not exactly */
+ p = 32;
+ __dbl_mp(x,&mpx,p);
+ __mpexp(&mpx, &mpy, p);
+ __mp_dbl(&mpy, &res, p);
+ return res;
+ }
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/slowpow.c b/libc/sysdeps/ieee754/dbl-64/slowpow.c
new file mode 100644
index 000000000..e11a532bf
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/slowpow.c
@@ -0,0 +1,74 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*************************************************************************/
+/* MODULE_NAME:slowpow.c */
+/* */
+/* FUNCTION:slowpow */
+/* */
+/*FILES NEEDED:mpa.h */
+/* mpa.c mpexp.c mplog.c halfulp.c */
+/* */
+/* Given two IEEE double machine numbers y,x , routine computes the */
+/* correctly rounded (to nearest) value of x^y. Result calculated by */
+/* multiplication (in halfulp.c) or if result isn't accurate enough */
+/* then routine converts x and y into multi-precision doubles and */
+/* calls to mpexp routine */
+/*************************************************************************/
+
+#include "mpa.h"
+#include "math_private.h"
+
+void __mpexp(mp_no *x, mp_no *y, int p);
+void __mplog(mp_no *x, mp_no *y, int p);
+double ulog(double);
+double __halfulp(double x,double y);
+
+double __slowpow(double x, double y, double z) {
+ double res,res1;
+ mp_no mpx, mpy, mpz,mpw,mpp,mpr,mpr1;
+ static const mp_no eps = {-3,{1.0,4.0}};
+ int p;
+
+ res = __halfulp(x,y); /* halfulp() returns -10 or x^y */
+ if (res >= 0) return res; /* if result was really computed by halfulp */
+ /* else, if result was not really computed by halfulp */
+ p = 10; /* p=precision */
+ __dbl_mp(x,&mpx,p);
+ __dbl_mp(y,&mpy,p);
+ __dbl_mp(z,&mpz,p);
+ __mplog(&mpx, &mpz, p); /* log(x) = z */
+ __mul(&mpy,&mpz,&mpw,p); /* y * z =w */
+ __mpexp(&mpw, &mpp, p); /* e^w =pp */
+ __add(&mpp,&eps,&mpr,p); /* pp+eps =r */
+ __mp_dbl(&mpr, &res, p);
+ __sub(&mpp,&eps,&mpr1,p); /* pp -eps =r1 */
+ __mp_dbl(&mpr1, &res1, p); /* converting into double precision */
+ if (res == res1) return res;
+
+ p = 32; /* if we get here result wasn't calculated exactly, continue */
+ __dbl_mp(x,&mpx,p); /* for more exact calculation */
+ __dbl_mp(y,&mpy,p);
+ __dbl_mp(z,&mpz,p);
+ __mplog(&mpx, &mpz, p); /* log(c)=z */
+ __mul(&mpy,&mpz,&mpw,p); /* y*z =w */
+ __mpexp(&mpw, &mpp, p); /* e^w=pp */
+ __mp_dbl(&mpp, &res, p); /* converting into double precision */
+ return res;
+}
diff --git a/libc/sysdeps/ieee754/dbl-64/t_exp.c b/libc/sysdeps/ieee754/dbl-64/t_exp.c
new file mode 100644
index 000000000..7a33a9080
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/t_exp.c
@@ -0,0 +1,436 @@
+/* Accurate tables for exp().
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Geoffrey Keating <geoffk@ozemail.com.au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This table has the property that, for all integers -177 <= i <= 177,
+ exp(i/512.0 + __exp_deltatable[abs(i)]) == __exp_atable[i+177] + r
+ for some -2^-64 < r < 2^-64 (abs(r) < 2^-65 if i <= 0); and that
+ __exp_deltatable[abs(i)] == t * 2^-60
+ for integer t so that abs(t) <= 8847927 * 2^8. */
+
+#define W52 (2.22044605e-16)
+#define W55 (2.77555756e-17)
+#define W58 (3.46944695e-18)
+#define W59 (1.73472348e-18)
+#define W60 (8.67361738e-19)
+const float __exp_deltatable[178] = {
+ 0*W60, 16558714*W60, -10672149*W59, 1441652*W60,
+ -15787963*W55, 462888*W60, 7291806*W60, 1698880*W60,
+ -14375103*W58, -2021016*W60, 728829*W60, -3759654*W60,
+ 3202123*W60, -10916019*W58, -251570*W60, -1043086*W60,
+ 8207536*W60, -409964*W60, -5993931*W60, -475500*W60,
+ 2237522*W60, 324170*W60, -244117*W60, 32077*W60,
+ 123907*W60, -1019734*W60, -143*W60, 813077*W60,
+ 743345*W60, 462461*W60, 629794*W60, 2125066*W60,
+ -2339121*W60, -337951*W60, 9922067*W60, -648704*W60,
+ 149407*W60, -2687209*W60, -631608*W60, 2128280*W60,
+ -4882082*W60, 2001360*W60, 175074*W60, 2923216*W60,
+ -538947*W60, -1212193*W60, -1920926*W60, -1080577*W60,
+ 3690196*W60, 2643367*W60, 2911937*W60, 671455*W60,
+ -1128674*W60, 593282*W60, -5219347*W60, -1941490*W60,
+ 11007953*W60, 239609*W60, -2969658*W60, -1183650*W60,
+ 942998*W60, 699063*W60, 450569*W60, -329250*W60,
+ -7257875*W60, -312436*W60, 51626*W60, 555877*W60,
+ -641761*W60, 1565666*W60, 884327*W60, -10960035*W60,
+ -2004679*W60, -995793*W60, -2229051*W60, -146179*W60,
+ -510327*W60, 1453482*W60, -3778852*W60, -2238056*W60,
+ -4895983*W60, 3398883*W60, -252738*W60, 1230155*W60,
+ 346918*W60, 1109352*W60, 268941*W60, -2930483*W60,
+ -1036263*W60, -1159280*W60, 1328176*W60, 2937642*W60,
+ -9371420*W60, -6902650*W60, -1419134*W60, 1442904*W60,
+ -1319056*W60, -16369*W60, 696555*W60, -279987*W60,
+ -7919763*W60, 252741*W60, 459711*W60, -1709645*W60,
+ 354913*W60, 6025867*W60, -421460*W60, -853103*W60,
+ -338649*W60, 962151*W60, 955965*W60, 784419*W60,
+ -3633653*W60, 2277133*W60, -8847927*W52, 1223028*W60,
+ 5907079*W60, 623167*W60, 5142888*W60, 2599099*W60,
+ 1214280*W60, 4870359*W60, 593349*W60, -57705*W60,
+ 7761209*W60, -5564097*W60, 2051261*W60, 6216869*W60,
+ 4692163*W60, 601691*W60, -5264906*W60, 1077872*W60,
+ -3205949*W60, 1833082*W60, 2081746*W60, -987363*W60,
+ -1049535*W60, 2015244*W60, 874230*W60, 2168259*W60,
+ -1740124*W60, -10068269*W60, -18242*W60, -3013583*W60,
+ 580601*W60, -2547161*W60, -535689*W60, 2220815*W60,
+ 1285067*W60, 2806933*W60, -983086*W60, -1729097*W60,
+ -1162985*W60, -2561904*W60, 801988*W60, 244351*W60,
+ 1441893*W60, -7517981*W60, 271781*W60, -15021588*W60,
+ -2341588*W60, -919198*W60, 1642232*W60, 4771771*W60,
+ -1220099*W60, -3062372*W60, 628624*W60, 1278114*W60,
+ 13083513*W60, -10521925*W60, 3180310*W60, -1659307*W60,
+ 3543773*W60, 2501203*W60, 4151*W60, -340748*W60,
+ -2285625*W60, 2495202*W60
+};
+
+const double __exp_atable[355] /* __attribute__((mode(DF))) */ = {
+ 0.707722561055888932371, /* 0x0.b52d4e46605c27ffd */
+ 0.709106182438804188967, /* 0x0.b587fb96f75097ffb */
+ 0.710492508843861281234, /* 0x0.b5e2d649899167ffd */
+ 0.711881545564593931623, /* 0x0.b63dde74d36bdfffe */
+ 0.713273297897442870573, /* 0x0.b699142f945f87ffc */
+ 0.714667771153751463236, /* 0x0.b6f477909c4ea0001 */
+ 0.716064970655995725059, /* 0x0.b75008aec758f8004 */
+ 0.717464901723956938193, /* 0x0.b7abc7a0eea7e0002 */
+ 0.718867569715736398602, /* 0x0.b807b47e1586c7ff8 */
+ 0.720272979947266023271, /* 0x0.b863cf5d10e380003 */
+ 0.721681137825144314297, /* 0x0.b8c01855195c37ffb */
+ 0.723092048691992950199, /* 0x0.b91c8f7d213740004 */
+ 0.724505717938892290800, /* 0x0.b97934ec5002d0007 */
+ 0.725922150953176470431, /* 0x0.b9d608b9c92ea7ffc */
+ 0.727341353138962865022, /* 0x0.ba330afcc29e98003 */
+ 0.728763329918453162104, /* 0x0.ba903bcc8618b7ffc */
+ 0.730188086709957051568, /* 0x0.baed9b40591ba0000 */
+ 0.731615628948127705309, /* 0x0.bb4b296f931e30002 */
+ 0.733045962086486091436, /* 0x0.bba8e671a05617ff9 */
+ 0.734479091556371366251, /* 0x0.bc06d25dd49568001 */
+ 0.735915022857225542529, /* 0x0.bc64ed4bce8f6fff9 */
+ 0.737353761441304711410, /* 0x0.bcc33752f915d7ff9 */
+ 0.738795312814142124419, /* 0x0.bd21b08af98e78005 */
+ 0.740239682467211168593, /* 0x0.bd80590b65e9a8000 */
+ 0.741686875913991849885, /* 0x0.bddf30ebec4a10000 */
+ 0.743136898669507939299, /* 0x0.be3e38443c84e0007 */
+ 0.744589756269486091620, /* 0x0.be9d6f2c1d32a0002 */
+ 0.746045454254026796384, /* 0x0.befcd5bb59baf8004 */
+ 0.747503998175051087583, /* 0x0.bf5c6c09ca84c0003 */
+ 0.748965393601880857739, /* 0x0.bfbc322f5b18b7ff8 */
+ 0.750429646104262104698, /* 0x0.c01c2843f776fffff */
+ 0.751896761271877989160, /* 0x0.c07c4e5fa18b88002 */
+ 0.753366744698445112140, /* 0x0.c0dca49a5fb18fffd */
+ 0.754839601988627206827, /* 0x0.c13d2b0c444db0005 */
+ 0.756315338768691947122, /* 0x0.c19de1cd798578006 */
+ 0.757793960659406629066, /* 0x0.c1fec8f623723fffd */
+ 0.759275473314173443536, /* 0x0.c25fe09e8a0f47ff8 */
+ 0.760759882363831851927, /* 0x0.c2c128dedc88f8000 */
+ 0.762247193485956486805, /* 0x0.c322a1cf7d6e7fffa */
+ 0.763737412354726363781, /* 0x0.c3844b88cb9347ffc */
+ 0.765230544649828092739, /* 0x0.c3e626232bd8f7ffc */
+ 0.766726596071518051729, /* 0x0.c44831b719bf18002 */
+ 0.768225572321911687194, /* 0x0.c4aa6e5d12d078001 */
+ 0.769727479119219348810, /* 0x0.c50cdc2da64a37ffb */
+ 0.771232322196981678892, /* 0x0.c56f7b41744490001 */
+ 0.772740107296721268087, /* 0x0.c5d24bb1259e70004 */
+ 0.774250840160724651565, /* 0x0.c6354d95640dd0007 */
+ 0.775764526565368872643, /* 0x0.c6988106fec447fff */
+ 0.777281172269557396602, /* 0x0.c6fbe61eb1bd0ffff */
+ 0.778800783068235302750, /* 0x0.c75f7cf560942fffc */
+ 0.780323364758801041312, /* 0x0.c7c345a3f1983fffe */
+ 0.781848923151573727006, /* 0x0.c8274043594cb0002 */
+ 0.783377464064598849602, /* 0x0.c88b6cec94b3b7ff9 */
+ 0.784908993312207869935, /* 0x0.c8efcbb89cba27ffe */
+ 0.786443516765346961618, /* 0x0.c9545cc0a88c70003 */
+ 0.787981040257604625744, /* 0x0.c9b9201dc643bfffa */
+ 0.789521569657452682047, /* 0x0.ca1e15e92a5410007 */
+ 0.791065110849462849192, /* 0x0.ca833e3c1ae510005 */
+ 0.792611669712891875319, /* 0x0.cae8992fd84667ffd */
+ 0.794161252150049179450, /* 0x0.cb4e26ddbc207fff8 */
+ 0.795713864077794763584, /* 0x0.cbb3e75f301b60003 */
+ 0.797269511407239561694, /* 0x0.cc19dacd978cd8002 */
+ 0.798828200086368567220, /* 0x0.cc8001427e55d7ffb */
+ 0.800389937624300440456, /* 0x0.cce65ade24d360006 */
+ 0.801954725261124767840, /* 0x0.cd4ce7a5de839fffb */
+ 0.803522573691593189330, /* 0x0.cdb3a7c79a678fffd */
+ 0.805093487311204114563, /* 0x0.ce1a9b563965ffffc */
+ 0.806667472122675088819, /* 0x0.ce81c26b838db8000 */
+ 0.808244534127439906441, /* 0x0.cee91d213f8428002 */
+ 0.809824679342317166307, /* 0x0.cf50ab9144d92fff9 */
+ 0.811407913793616542005, /* 0x0.cfb86dd5758c2ffff */
+ 0.812994243520784198882, /* 0x0.d0206407c20e20005 */
+ 0.814583674571603966162, /* 0x0.d0888e4223facfff9 */
+ 0.816176213022088536960, /* 0x0.d0f0ec9eb3f7c8002 */
+ 0.817771864936188586101, /* 0x0.d1597f377d6768002 */
+ 0.819370636400374108252, /* 0x0.d1c24626a46eafff8 */
+ 0.820972533518165570298, /* 0x0.d22b41865ff1e7ff9 */
+ 0.822577562404315121269, /* 0x0.d2947170f32ec7ff9 */
+ 0.824185729164559344159, /* 0x0.d2fdd60097795fff8 */
+ 0.825797039949601741075, /* 0x0.d3676f4fb796d0001 */
+ 0.827411500902565544264, /* 0x0.d3d13d78b5f68fffb */
+ 0.829029118181348834154, /* 0x0.d43b40960546d8001 */
+ 0.830649897953322891022, /* 0x0.d4a578c222a058000 */
+ 0.832273846408250750368, /* 0x0.d50fe617a3ba78005 */
+ 0.833900969738858188772, /* 0x0.d57a88b1218e90002 */
+ 0.835531274148056613016, /* 0x0.d5e560a94048f8006 */
+ 0.837164765846411529371, /* 0x0.d6506e1aac8078003 */
+ 0.838801451086016225394, /* 0x0.d6bbb1204074e0001 */
+ 0.840441336100884561780, /* 0x0.d72729d4c28518004 */
+ 0.842084427144139224814, /* 0x0.d792d8530e12b0001 */
+ 0.843730730487052604790, /* 0x0.d7febcb61273e7fff */
+ 0.845380252404570153833, /* 0x0.d86ad718c308dfff9 */
+ 0.847032999194574087728, /* 0x0.d8d727962c69d7fff */
+ 0.848688977161248581090, /* 0x0.d943ae49621ce7ffb */
+ 0.850348192619261200615, /* 0x0.d9b06b4d832ef8005 */
+ 0.852010651900976245816, /* 0x0.da1d5ebdc22220005 */
+ 0.853676361342631029337, /* 0x0.da8a88b555baa0006 */
+ 0.855345327311054837175, /* 0x0.daf7e94f965f98004 */
+ 0.857017556155879489641, /* 0x0.db6580a7c98f7fff8 */
+ 0.858693054267390953857, /* 0x0.dbd34ed9617befff8 */
+ 0.860371828028939855647, /* 0x0.dc4153ffc8b65fff9 */
+ 0.862053883854957292436, /* 0x0.dcaf90368bfca8004 */
+ 0.863739228154875360306, /* 0x0.dd1e0399328d87ffe */
+ 0.865427867361348468455, /* 0x0.dd8cae435d303fff9 */
+ 0.867119807911702289458, /* 0x0.ddfb9050b1cee8006 */
+ 0.868815056264353846599, /* 0x0.de6aa9dced8448001 */
+ 0.870513618890481399881, /* 0x0.ded9fb03db7320006 */
+ 0.872215502247877139094, /* 0x0.df4983e1380657ff8 */
+ 0.873920712852848668986, /* 0x0.dfb94490ffff77ffd */
+ 0.875629257204025623884, /* 0x0.e0293d2f1cb01fff9 */
+ 0.877341141814212965880, /* 0x0.e0996dd786fff0007 */
+ 0.879056373217612985183, /* 0x0.e109d6a64f5d57ffc */
+ 0.880774957955916648615, /* 0x0.e17a77b78e72a7ffe */
+ 0.882496902590150900078, /* 0x0.e1eb5127722cc7ff8 */
+ 0.884222213673356738383, /* 0x0.e25c63121fb0c8006 */
+ 0.885950897802399772740, /* 0x0.e2cdad93ec5340003 */
+ 0.887682961567391237685, /* 0x0.e33f30c925fb97ffb */
+ 0.889418411575228162725, /* 0x0.e3b0ecce2d05ffff9 */
+ 0.891157254447957902797, /* 0x0.e422e1bf727718006 */
+ 0.892899496816652704641, /* 0x0.e4950fb9713fc7ffe */
+ 0.894645145323828439008, /* 0x0.e50776d8b0e60fff8 */
+ 0.896394206626591749641, /* 0x0.e57a1739c8fadfffc */
+ 0.898146687421414902124, /* 0x0.e5ecf0f97c5798007 */
+ 0.899902594367530173098, /* 0x0.e660043464e378005 */
+ 0.901661934163603406867, /* 0x0.e6d3510747e150006 */
+ 0.903424713533971135418, /* 0x0.e746d78f06cd97ffd */
+ 0.905190939194458810123, /* 0x0.e7ba97e879c91fffc */
+ 0.906960617885092856864, /* 0x0.e82e92309390b0007 */
+ 0.908733756358986566306, /* 0x0.e8a2c6845544afffa */
+ 0.910510361377119825629, /* 0x0.e9173500c8abc7ff8 */
+ 0.912290439722343249336, /* 0x0.e98bddc30f98b0002 */
+ 0.914073998177417412765, /* 0x0.ea00c0e84bc4c7fff */
+ 0.915861043547953501680, /* 0x0.ea75de8db8094fffe */
+ 0.917651582652244779397, /* 0x0.eaeb36d09d3137ffe */
+ 0.919445622318405764159, /* 0x0.eb60c9ce4ed3dffff */
+ 0.921243169397334638073, /* 0x0.ebd697a43995b0007 */
+ 0.923044230737526172328, /* 0x0.ec4ca06fc7768fffa */
+ 0.924848813220121135342, /* 0x0.ecc2e44e865b6fffb */
+ 0.926656923710931002014, /* 0x0.ed39635df34e70006 */
+ 0.928468569126343790092, /* 0x0.edb01dbbc2f5b7ffa */
+ 0.930283756368834757725, /* 0x0.ee2713859aab57ffa */
+ 0.932102492359406786818, /* 0x0.ee9e44d9342870004 */
+ 0.933924784042873379360, /* 0x0.ef15b1d4635438005 */
+ 0.935750638358567643520, /* 0x0.ef8d5a94f60f50007 */
+ 0.937580062297704630580, /* 0x0.f0053f38f345cffff */
+ 0.939413062815381727516, /* 0x0.f07d5fde3a2d98001 */
+ 0.941249646905368053689, /* 0x0.f0f5bca2d481a8004 */
+ 0.943089821583810716806, /* 0x0.f16e55a4e497d7ffe */
+ 0.944933593864477061592, /* 0x0.f1e72b028a2827ffb */
+ 0.946780970781518460559, /* 0x0.f2603cd9fb5430001 */
+ 0.948631959382661205081, /* 0x0.f2d98b497d2a87ff9 */
+ 0.950486566729423554277, /* 0x0.f353166f63e3dffff */
+ 0.952344799896018723290, /* 0x0.f3ccde6a11ae37ffe */
+ 0.954206665969085765512, /* 0x0.f446e357f66120000 */
+ 0.956072172053890279009, /* 0x0.f4c12557964f0fff9 */
+ 0.957941325265908139014, /* 0x0.f53ba48781046fffb */
+ 0.959814132734539637840, /* 0x0.f5b66106555d07ffa */
+ 0.961690601603558903308, /* 0x0.f6315af2c2027fffc */
+ 0.963570739036113010927, /* 0x0.f6ac926b8aeb80004 */
+ 0.965454552202857141381, /* 0x0.f728078f7c5008002 */
+ 0.967342048278315158608, /* 0x0.f7a3ba7d66a908001 */
+ 0.969233234469444204768, /* 0x0.f81fab543e1897ffb */
+ 0.971128118008140250896, /* 0x0.f89bda33122c78007 */
+ 0.973026706099345495256, /* 0x0.f9184738d4cf97ff8 */
+ 0.974929006031422851235, /* 0x0.f994f284d3a5c0008 */
+ 0.976835024947348973265, /* 0x0.fa11dc35bc7820002 */
+ 0.978744770239899142285, /* 0x0.fa8f046b4fb7f8007 */
+ 0.980658249138918636210, /* 0x0.fb0c6b449ab1cfff9 */
+ 0.982575468959622777535, /* 0x0.fb8a10e1088fb7ffa */
+ 0.984496437054508843888, /* 0x0.fc07f5602d79afffc */
+ 0.986421160608523028820, /* 0x0.fc8618e0e55e47ffb */
+ 0.988349647107594098099, /* 0x0.fd047b83571b1fffa */
+ 0.990281903873210800357, /* 0x0.fd831d66f4c018002 */
+ 0.992217938695037382475, /* 0x0.fe01fead3320bfff8 */
+ 0.994157757657894713987, /* 0x0.fe811f703491e8006 */
+ 0.996101369488558541238, /* 0x0.ff007fd5744490005 */
+ 0.998048781093141101932, /* 0x0.ff801ffa9b9280007 */
+ 1.000000000000000000000, /* 0x1.00000000000000000 */
+ 1.001955033605393285965, /* 0x1.0080200565d29ffff */
+ 1.003913889319761887310, /* 0x1.0100802aa0e80fff0 */
+ 1.005876574715736104818, /* 0x1.01812090377240007 */
+ 1.007843096764807100351, /* 0x1.020201541aad7fff6 */
+ 1.009813464316352327214, /* 0x1.0283229c4c9820007 */
+ 1.011787683565730677817, /* 0x1.030484836910a000e */
+ 1.013765762469146736174, /* 0x1.0386272b9c077fffe */
+ 1.015747708536026694351, /* 0x1.04080ab526304fff0 */
+ 1.017733529475172815584, /* 0x1.048a2f412375ffff0 */
+ 1.019723232714418781378, /* 0x1.050c94ef7ad5e000a */
+ 1.021716825883923762690, /* 0x1.058f3be0f1c2d0004 */
+ 1.023714316605201180057, /* 0x1.06122436442e2000e */
+ 1.025715712440059545995, /* 0x1.06954e0fec63afff2 */
+ 1.027721021151397406936, /* 0x1.0718b98f41c92fff6 */
+ 1.029730250269221158939, /* 0x1.079c66d49bb2ffff1 */
+ 1.031743407506447551857, /* 0x1.082056011a9230009 */
+ 1.033760500517691527387, /* 0x1.08a487359ebd50002 */
+ 1.035781537016238873464, /* 0x1.0928fa93490d4fff3 */
+ 1.037806524719013578963, /* 0x1.09adb03b3e5b3000d */
+ 1.039835471338248051878, /* 0x1.0a32a84e9e5760004 */
+ 1.041868384612101516848, /* 0x1.0ab7e2eea5340ffff */
+ 1.043905272300907460835, /* 0x1.0b3d603ca784f0009 */
+ 1.045946142174331239262, /* 0x1.0bc3205a042060000 */
+ 1.047991002016745332165, /* 0x1.0c4923682a086fffe */
+ 1.050039859627715177527, /* 0x1.0ccf698898f3a000d */
+ 1.052092722826109660856, /* 0x1.0d55f2dce5d1dfffb */
+ 1.054149599440827866881, /* 0x1.0ddcbf86b09a5fff6 */
+ 1.056210497317612961855, /* 0x1.0e63cfa7abc97fffd */
+ 1.058275424318780855142, /* 0x1.0eeb23619c146fffb */
+ 1.060344388322010722446, /* 0x1.0f72bad65714bffff */
+ 1.062417397220589476718, /* 0x1.0ffa9627c38d30004 */
+ 1.064494458915699715017, /* 0x1.1082b577d0eef0003 */
+ 1.066575581342167566880, /* 0x1.110b18e893a90000a */
+ 1.068660772440545025953, /* 0x1.1193c09c267610006 */
+ 1.070750040138235936705, /* 0x1.121cacb4959befff6 */
+ 1.072843392435016474095, /* 0x1.12a5dd543cf36ffff */
+ 1.074940837302467588937, /* 0x1.132f529d59552000b */
+ 1.077042382749654914030, /* 0x1.13b90cb250d08fff5 */
+ 1.079148036789447484528, /* 0x1.14430bb58da3dfff9 */
+ 1.081257807444460983297, /* 0x1.14cd4fc984c4a000e */
+ 1.083371702785017154417, /* 0x1.1557d910df9c7000e */
+ 1.085489730853784307038, /* 0x1.15e2a7ae292d30002 */
+ 1.087611899742884524772, /* 0x1.166dbbc422d8c0004 */
+ 1.089738217537583819804, /* 0x1.16f9157586772ffff */
+ 1.091868692357631731528, /* 0x1.1784b4e533cacfff0 */
+ 1.094003332327482702577, /* 0x1.18109a360fc23fff2 */
+ 1.096142145591650907149, /* 0x1.189cc58b155a70008 */
+ 1.098285140311341168136, /* 0x1.1929370751ea50002 */
+ 1.100432324652149906842, /* 0x1.19b5eecdd79cefff0 */
+ 1.102583706811727015711, /* 0x1.1a42ed01dbdba000e */
+ 1.104739294993289488947, /* 0x1.1ad031c69a2eafff0 */
+ 1.106899097422573863281, /* 0x1.1b5dbd3f66e120003 */
+ 1.109063122341542140286, /* 0x1.1beb8f8fa8150000b */
+ 1.111231377994659874592, /* 0x1.1c79a8dac6ad0fff4 */
+ 1.113403872669181282605, /* 0x1.1d0809445a97ffffc */
+ 1.115580614653132185460, /* 0x1.1d96b0effc9db000e */
+ 1.117761612217810673898, /* 0x1.1e25a001332190000 */
+ 1.119946873713312474002, /* 0x1.1eb4d69bdb2a9fff1 */
+ 1.122136407473298902480, /* 0x1.1f4454e3bfae00006 */
+ 1.124330221845670330058, /* 0x1.1fd41afcbb48bfff8 */
+ 1.126528325196519908506, /* 0x1.2064290abc98c0001 */
+ 1.128730725913251964394, /* 0x1.20f47f31c9aa7000f */
+ 1.130937432396844410880, /* 0x1.21851d95f776dfff0 */
+ 1.133148453059692917203, /* 0x1.2216045b6784efffa */
+ 1.135363796355857157764, /* 0x1.22a733a6692ae0004 */
+ 1.137583470716100553249, /* 0x1.2338ab9b3221a0004 */
+ 1.139807484614418608939, /* 0x1.23ca6c5e27aadfff7 */
+ 1.142035846532929888057, /* 0x1.245c7613b7f6c0004 */
+ 1.144268564977221958089, /* 0x1.24eec8e06b035000c */
+ 1.146505648458203463465, /* 0x1.258164e8cea85fff8 */
+ 1.148747105501412235671, /* 0x1.26144a5180d380009 */
+ 1.150992944689175123667, /* 0x1.26a7793f5de2efffa */
+ 1.153243174560058870217, /* 0x1.273af1d712179000d */
+ 1.155497803703682491111, /* 0x1.27ceb43d81d42fff1 */
+ 1.157756840726344771440, /* 0x1.2862c097a3d29000c */
+ 1.160020294239811677834, /* 0x1.28f7170a74cf4fff1 */
+ 1.162288172883275239058, /* 0x1.298bb7bb0faed0004 */
+ 1.164560485298402170388, /* 0x1.2a20a2ce920dffff4 */
+ 1.166837240167474476460, /* 0x1.2ab5d86a4631ffff6 */
+ 1.169118446164539637555, /* 0x1.2b4b58b36d5220009 */
+ 1.171404112007080167155, /* 0x1.2be123cf786790002 */
+ 1.173694246390975415341, /* 0x1.2c7739e3c0aac000d */
+ 1.175988858069749065617, /* 0x1.2d0d9b15deb58fff6 */
+ 1.178287955789017793514, /* 0x1.2da4478b627040002 */
+ 1.180591548323240091978, /* 0x1.2e3b3f69fb794fffc */
+ 1.182899644456603782686, /* 0x1.2ed282d76421d0004 */
+ 1.185212252993012693694, /* 0x1.2f6a11f96c685fff3 */
+ 1.187529382762033236513, /* 0x1.3001ecf60082ffffa */
+ 1.189851042595508889847, /* 0x1.309a13f30f28a0004 */
+ 1.192177241354644978669, /* 0x1.31328716a758cfff7 */
+ 1.194507987909589896687, /* 0x1.31cb4686e1e85fffb */
+ 1.196843291137896336843, /* 0x1.32645269dfd04000a */
+ 1.199183159977805113226, /* 0x1.32fdaae604c39000f */
+ 1.201527603343041317132, /* 0x1.339750219980dfff3 */
+ 1.203876630171082595692, /* 0x1.3431424300e480007 */
+ 1.206230249419600664189, /* 0x1.34cb8170b3fee000e */
+ 1.208588470077065268869, /* 0x1.35660dd14dbd4fffc */
+ 1.210951301134513435915, /* 0x1.3600e78b6bdfc0005 */
+ 1.213318751604272271958, /* 0x1.369c0ec5c38ebfff2 */
+ 1.215690830512196507537, /* 0x1.373783a718d29000f */
+ 1.218067546930756250870, /* 0x1.37d3465662f480007 */
+ 1.220448909901335365929, /* 0x1.386f56fa770fe0008 */
+ 1.222834928513994334780, /* 0x1.390bb5ba5fc540004 */
+ 1.225225611877684750397, /* 0x1.39a862bd3c7a8fff3 */
+ 1.227620969111500981433, /* 0x1.3a455e2a37bcafffd */
+ 1.230021009336254911271, /* 0x1.3ae2a8287dfbefff6 */
+ 1.232425741726685064472, /* 0x1.3b8040df76f39fffa */
+ 1.234835175450728295084, /* 0x1.3c1e287682e48fff1 */
+ 1.237249319699482263931, /* 0x1.3cbc5f151b86bfff8 */
+ 1.239668183679933477545, /* 0x1.3d5ae4e2cc0a8000f */
+ 1.242091776620540377629, /* 0x1.3df9ba07373bf0006 */
+ 1.244520107762172811399, /* 0x1.3e98deaa0d8cafffe */
+ 1.246953186383919165383, /* 0x1.3f3852f32973efff0 */
+ 1.249391019292643401078, /* 0x1.3fd816ffc72b90001 */
+ 1.251833623164381181797, /* 0x1.40782b17863250005 */
+ 1.254280999953110153911, /* 0x1.41188f42caf400000 */
+ 1.256733161434815393410, /* 0x1.41b943b42945bfffd */
+ 1.259190116985283935980, /* 0x1.425a4893e5f10000a */
+ 1.261651875958665236542, /* 0x1.42fb9e0a2df4c0009 */
+ 1.264118447754797758244, /* 0x1.439d443f608c4fff9 */
+ 1.266589841787181258708, /* 0x1.443f3b5bebf850008 */
+ 1.269066067469190262045, /* 0x1.44e183883e561fff7 */
+ 1.271547134259576328224, /* 0x1.45841cecf7a7a0001 */
+ 1.274033051628237434048, /* 0x1.462707b2c43020009 */
+ 1.276523829025464573684, /* 0x1.46ca44023aa410007 */
+ 1.279019475999373156531, /* 0x1.476dd2045d46ffff0 */
+ 1.281520002043128991825, /* 0x1.4811b1e1f1f19000b */
+ 1.284025416692967214122, /* 0x1.48b5e3c3edd74fff4 */
+ 1.286535729509738823464, /* 0x1.495a67d3613c8fff7 */
+ 1.289050950070396384145, /* 0x1.49ff3e396e19d000b */
+ 1.291571087985403654081, /* 0x1.4aa4671f5b401fff1 */
+ 1.294096152842774794011, /* 0x1.4b49e2ae56d19000d */
+ 1.296626154297237043484, /* 0x1.4befb10fd84a3fff4 */
+ 1.299161101984141142272, /* 0x1.4c95d26d41d84fff8 */
+ 1.301701005575179204100, /* 0x1.4d3c46f01d9f0fff3 */
+ 1.304245874766450485904, /* 0x1.4de30ec21097d0003 */
+ 1.306795719266019562007, /* 0x1.4e8a2a0ccce3d0002 */
+ 1.309350548792467483458, /* 0x1.4f3198fa10346fff5 */
+ 1.311910373099227200545, /* 0x1.4fd95bb3be8cffffd */
+ 1.314475201942565174546, /* 0x1.50817263bf0e5fffb */
+ 1.317045045107389400535, /* 0x1.5129dd3418575000e */
+ 1.319619912422941299109, /* 0x1.51d29c4f01c54ffff */
+ 1.322199813675649204855, /* 0x1.527bafde83a310009 */
+ 1.324784758729532718739, /* 0x1.5325180cfb8b3fffd */
+ 1.327374757430096474625, /* 0x1.53ced504b2bd0fff4 */
+ 1.329969819671041886272, /* 0x1.5478e6f02775e0001 */
+ 1.332569955346704748651, /* 0x1.55234df9d8a59fff8 */
+ 1.335175174370685002822, /* 0x1.55ce0a4c5a6a9fff6 */
+ 1.337785486688218616860, /* 0x1.56791c1263abefff7 */
+ 1.340400902247843806217, /* 0x1.57248376aef21fffa */
+ 1.343021431036279800211, /* 0x1.57d040a420c0bfff3 */
+ 1.345647083048053138662, /* 0x1.587c53c5a630f0002 */
+ 1.348277868295411074918, /* 0x1.5928bd063fd7bfff9 */
+ 1.350913796821875845231, /* 0x1.59d57c9110ad60006 */
+ 1.353554878672557082439, /* 0x1.5a8292913d68cfffc */
+ 1.356201123929036356254, /* 0x1.5b2fff3212db00007 */
+ 1.358852542671913132777, /* 0x1.5bddc29edcc06fff3 */
+ 1.361509145047255398051, /* 0x1.5c8bdd032ed16000f */
+ 1.364170941142184734180, /* 0x1.5d3a4e8a5bf61fff4 */
+ 1.366837941171020309735, /* 0x1.5de9176042f1effff */
+ 1.369510155261156381121, /* 0x1.5e9837b062f4e0005 */
+ 1.372187593620959988833, /* 0x1.5f47afa69436cfff1 */
+ 1.374870266463378287715, /* 0x1.5ff77f6eb3f8cfffd */
+ 1.377558184010425845733, /* 0x1.60a7a734a9742fff9 */
+ 1.380251356531521533853, /* 0x1.6158272490016000c */
+ 1.382949794301995272203, /* 0x1.6208ff6a8978a000f */
+ 1.385653507605306700170, /* 0x1.62ba3032c0a280004 */
+ 1.388362506772382154503, /* 0x1.636bb9a994784000f */
+ 1.391076802081129493127, /* 0x1.641d9bfb29a7bfff6 */
+ 1.393796403973427855412, /* 0x1.64cfd7545928b0002 */
+ 1.396521322756352656542, /* 0x1.65826be167badfff8 */
+ 1.399251568859207761660, /* 0x1.663559cf20826000c */
+ 1.401987152677323100733, /* 0x1.66e8a14a29486fffc */
+ 1.404728084651919228815, /* 0x1.679c427f5a4b6000b */
+ 1.407474375243217723560, /* 0x1.68503d9ba0add000f */
+ 1.410226034922914983815, /* 0x1.690492cbf6303fff9 */
+ 1.412983074197955213304, /* 0x1.69b9423d7b548fff6 */
+};
diff --git a/libc/sysdeps/ieee754/dbl-64/t_exp2.h b/libc/sysdeps/ieee754/dbl-64/t_exp2.h
new file mode 100644
index 000000000..1fd73338c
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/t_exp2.h
@@ -0,0 +1,585 @@
+/* These values are accurate to 52+12 bits when represented as
+ a double. */
+static const double exp2_accuratetable[512] = {
+0.707106781187802013759 /* 0x0.b504f333fb3f80007 */,
+0.708064712808760599040 /* 0x0.b543baa0f71b38000 */,
+0.709023942160304065938 /* 0x0.b58297d3a8d518002 */,
+0.709984470998547667624 /* 0x0.b5c18ad39b4ba0001 */,
+0.710946301084324217006 /* 0x0.b60093a85e8d30001 */,
+0.711909434180505784637 /* 0x0.b63fb25984e628005 */,
+0.712873872052760648733 /* 0x0.b67ee6eea3b5f8003 */,
+0.713839616467838999908 /* 0x0.b6be316f518c98001 */,
+0.714806669195984345523 /* 0x0.b6fd91e328d148007 */,
+0.715775032009894562898 /* 0x0.b73d0851c69e20002 */,
+0.716744706683768884058 /* 0x0.b77c94c2c9b3d0003 */,
+0.717715694995770148178 /* 0x0.b7bc373dd52eb0003 */,
+0.718687998724665488852 /* 0x0.b7fbefca8cd530004 */,
+0.719661619652575468291 /* 0x0.b83bbe70981da8001 */,
+0.720636559564428180758 /* 0x0.b87ba337a194b0006 */,
+0.721612820246623098989 /* 0x0.b8bb9e27556508004 */,
+0.722590403488338473025 /* 0x0.b8fbaf4762c798006 */,
+0.723569311081411870036 /* 0x0.b93bd69f7be1d0000 */,
+0.724549544820974333906 /* 0x0.b97c1437567828007 */,
+0.725531106502312561633 /* 0x0.b9bc6816a87ae8002 */,
+0.726513997924421062181 /* 0x0.b9fcd2452bee00000 */,
+0.727498220889519875430 /* 0x0.ba3d52ca9e6148002 */,
+0.728483777200401694265 /* 0x0.ba7de9aebe05c8003 */,
+0.729470668664712662563 /* 0x0.babe96f94e62a8002 */,
+0.730458897090379144517 /* 0x0.baff5ab2134df0004 */,
+0.731448464287988597833 /* 0x0.bb4034e0d38ab0000 */,
+0.732439372072965166897 /* 0x0.bb81258d5b2d60001 */,
+0.733431622260458326859 /* 0x0.bbc22cbf75fd28001 */,
+0.734425216668725511232 /* 0x0.bc034a7ef32c00001 */,
+0.735420157118880535324 /* 0x0.bc447ed3a50fe0005 */,
+0.736416445434497690674 /* 0x0.bc85c9c560b350001 */,
+0.737414083433310718618 /* 0x0.bcc72b5bf4b4e0000 */,
+0.738413072966152328496 /* 0x0.bd08a39f5417a8007 */,
+0.739413415848264365956 /* 0x0.bd4a32974abcd0002 */,
+0.740415113911250699637 /* 0x0.bd8bd84bb68300002 */,
+0.741418168994518067562 /* 0x0.bdcd94c47ddd30003 */,
+0.742422582936659858376 /* 0x0.be0f6809865968006 */,
+0.743428357577745613238 /* 0x0.be515222b72530003 */,
+0.744435494762383687126 /* 0x0.be935317fc6ba0002 */,
+0.745443996335090397492 /* 0x0.bed56af1423de8001 */,
+0.746453864145572798553 /* 0x0.bf1799b67a6248007 */,
+0.747465100043933849969 /* 0x0.bf59df6f970e70002 */,
+0.748477705883256683178 /* 0x0.bf9c3c248dbee8001 */,
+0.749491683518965001732 /* 0x0.bfdeafdd568308000 */,
+0.750507034813367890373 /* 0x0.c0213aa1f0fc38004 */,
+0.751523761622240105153 /* 0x0.c063dc7a559ca0003 */,
+0.752541865811731880422 /* 0x0.c0a6956e883ed8000 */,
+0.753561349247157341600 /* 0x0.c0e965868bd220006 */,
+0.754582213796583967110 /* 0x0.c12c4cca664cb8002 */,
+0.755604461332336940791 /* 0x0.c16f4b42225350006 */,
+0.756628093726406381068 /* 0x0.c1b260f5ca2c48002 */,
+0.757653112855631305506 /* 0x0.c1f58ded6d72d8001 */,
+0.758679520599333412360 /* 0x0.c238d2311e7d08001 */,
+0.759707318837184453227 /* 0x0.c27c2dc8f00368005 */,
+0.760736509456435783249 /* 0x0.c2bfa0bcfd1400000 */,
+0.761767094336480043995 /* 0x0.c3032b155818d0000 */,
+0.762799075372231349951 /* 0x0.c346ccda248cc0001 */,
+0.763832454453522768941 /* 0x0.c38a8613805488005 */,
+0.764867233473625618441 /* 0x0.c3ce56c98d1ca8005 */,
+0.765903414329434539816 /* 0x0.c4123f04708d80002 */,
+0.766940998920452976510 /* 0x0.c4563ecc532dc0001 */,
+0.767979989148100838946 /* 0x0.c49a56295f9f88006 */,
+0.769020386915772125040 /* 0x0.c4de8523c2b0a0001 */,
+0.770062194131770905170 /* 0x0.c522cbc3ae94e0003 */,
+0.771105412703856241146 /* 0x0.c5672a1154e6b8004 */,
+0.772150044545352520777 /* 0x0.c5aba014ed5f18003 */,
+0.773196091570364285606 /* 0x0.c5f02dd6b09288003 */,
+0.774243555696622731700 /* 0x0.c634d35edb1260003 */,
+0.775292438842697939641 /* 0x0.c67990b5aa5c18004 */,
+0.776342742931542928455 /* 0x0.c6be65e360bed8000 */,
+0.777394469888802008854 /* 0x0.c70352f0437f50004 */,
+0.778447621641124243320 /* 0x0.c74857e498fd00006 */,
+0.779502200118583399303 /* 0x0.c78d74c8ab5b60000 */,
+0.780558207255445668515 /* 0x0.c7d2a9a4c959f8000 */,
+0.781615644985491186966 /* 0x0.c817f681412f80002 */,
+0.782674515247667956808 /* 0x0.c85d5b6666c150006 */,
+0.783734819983036512536 /* 0x0.c8a2d85c904760003 */,
+0.784796561133562109454 /* 0x0.c8e86d6c14f850002 */,
+0.785859740645942328471 /* 0x0.c92e1a9d513ec8002 */,
+0.786924360469767103536 /* 0x0.c973dff8a4b390007 */,
+0.787990422552312885808 /* 0x0.c9b9bd866c6440007 */,
+0.789057928854407064640 /* 0x0.c9ffb34f1444b0001 */,
+0.790126881326406182996 /* 0x0.ca45c15afcc570001 */,
+0.791197281930050233534 /* 0x0.ca8be7b292db38000 */,
+0.792269132620954885659 /* 0x0.cad2265e3cbee8000 */,
+0.793342435380726906957 /* 0x0.cb187d667d3d38006 */,
+0.794417192158282659010 /* 0x0.cb5eecd3b33158006 */,
+0.795493404931386649540 /* 0x0.cba574ae5d2e80001 */,
+0.796571075671306805268 /* 0x0.cbec14fef2a348004 */,
+0.797650206352955137846 /* 0x0.cc32cdcdef0000000 */,
+0.798730798954342069432 /* 0x0.cc799f23d11d18000 */,
+0.799812855456121796232 /* 0x0.ccc089091abb28004 */,
+0.800896377841454287795 /* 0x0.cd078b86505c18003 */,
+0.801981368096190028208 /* 0x0.cd4ea6a3f97720007 */,
+0.803067828208752554378 /* 0x0.cd95da6aa057b8007 */,
+0.804155760170129796375 /* 0x0.cddd26e2d21b28001 */,
+0.805245165974338261710 /* 0x0.ce248c151f3330001 */,
+0.806336047619038653883 /* 0x0.ce6c0a0a1c1350001 */,
+0.807428407102107836855 /* 0x0.ceb3a0ca5d6be0006 */,
+0.808522246427078927792 /* 0x0.cefb505e7e2550007 */,
+0.809617567597010201484 /* 0x0.cf4318cf18a268002 */,
+0.810714372621179513182 /* 0x0.cf8afa24ce1c98004 */,
+0.811812663508675536069 /* 0x0.cfd2f4683f9810005 */,
+0.812912442272482604912 /* 0x0.d01b07a2126188003 */,
+0.814013710929394895825 /* 0x0.d06333daeff618001 */,
+0.815116471495287542325 /* 0x0.d0ab791b80d028006 */,
+0.816220725993571205593 /* 0x0.d0f3d76c75b330000 */,
+0.817326476447408967199 /* 0x0.d13c4ed67f1cf8000 */,
+0.818433724883006474832 /* 0x0.d184df6250e3b0001 */,
+0.819542473330909460055 /* 0x0.d1cd8918a3a328004 */,
+0.820652723822034690935 /* 0x0.d2164c02305fa0002 */,
+0.821764478391968422618 /* 0x0.d25f2827b53fb0005 */,
+0.822877739077315761840 /* 0x0.d2a81d91f188b8000 */,
+0.823992507918612782109 /* 0x0.d2f12c49a8d290005 */,
+0.825108786960634610365 /* 0x0.d33a5457a35e40003 */,
+0.826226578247117093869 /* 0x0.d38395c4a84848007 */,
+0.827345883828319528258 /* 0x0.d3ccf09985d958004 */,
+0.828466705754248966560 /* 0x0.d41664df0a1320005 */,
+0.829589046080638992111 /* 0x0.d45ff29e094330000 */,
+0.830712906863802391671 /* 0x0.d4a999df585a20005 */,
+0.831838290163696481037 /* 0x0.d4f35aabd04a60006 */,
+0.832965198041969556729 /* 0x0.d53d350c4be258002 */,
+0.834093632565442222342 /* 0x0.d5872909aba050007 */,
+0.835223595802037643865 /* 0x0.d5d136acd138e8006 */,
+0.836355089820669306292 /* 0x0.d61b5dfe9f7780004 */,
+0.837488116698010487424 /* 0x0.d6659f0801afa8005 */,
+0.838622678508982644113 /* 0x0.d6aff9d1e147d8004 */,
+0.839758777333464490056 /* 0x0.d6fa6e652d19e0000 */,
+0.840896415254110962690 /* 0x0.d744fccad70d00003 */,
+0.842035594355151628676 /* 0x0.d78fa50bd2c3b0000 */,
+0.843176316724478125433 /* 0x0.d7da673117e730007 */,
+0.844318584453106590905 /* 0x0.d8254343a19038003 */,
+0.845462399634695271912 /* 0x0.d870394c6dbf30003 */,
+0.846607764365415071965 /* 0x0.d8bb49547d37c0004 */,
+0.847754680744707056494 /* 0x0.d9067364d45608003 */,
+0.848903150873708822763 /* 0x0.d951b7867953b0006 */,
+0.850053176859071113491 /* 0x0.d99d15c2787a30006 */,
+0.851204760807439786431 /* 0x0.d9e88e21de11a0003 */,
+0.852357904828824897169 /* 0x0.da3420adba1508003 */,
+0.853512611037803181642 /* 0x0.da7fcd6f2184d8005 */,
+0.854668881550406100980 /* 0x0.dacb946f2afaf8000 */,
+0.855826718478671755185 /* 0x0.db1775b6e8ad48000 */,
+0.856986123964844970247 /* 0x0.db63714f8e0818006 */,
+0.858147100114499461478 /* 0x0.dbaf87422625b8000 */,
+0.859309649060962410524 /* 0x0.dbfbb797daa460002 */,
+0.860473772936213743282 /* 0x0.dc480259d3a710001 */,
+0.861639473872910177676 /* 0x0.dc9467913a0f48006 */,
+0.862806754008130227807 /* 0x0.dce0e7473b9b28003 */,
+0.863975615481124226159 /* 0x0.dd2d8185086c20006 */,
+0.865146060433749419813 /* 0x0.dd7a3653d38168005 */,
+0.866318091005120138881 /* 0x0.ddc705bcccd628000 */,
+0.867491709362415264210 /* 0x0.de13efc9434100004 */,
+0.868666917636779056818 /* 0x0.de60f4825df9b8005 */,
+0.869843717989716047624 /* 0x0.deae13f16599c0003 */,
+0.871022112578215268471 /* 0x0.defb4e1f9dc388002 */,
+0.872202103559697183859 /* 0x0.df48a3164a92f0001 */,
+0.873383693097737778847 /* 0x0.df9612deb6e878007 */,
+0.874566883362160263365 /* 0x0.dfe39d82348310001 */,
+0.875751676517234511901 /* 0x0.e031430a0f0688000 */,
+0.876938074732511840819 /* 0x0.e07f037f97e548001 */,
+0.878126080186539592654 /* 0x0.e0ccdeec2a75e0006 */,
+0.879315695055312818168 /* 0x0.e11ad5591f4078001 */,
+0.880506921518618312932 /* 0x0.e168e6cfd2f880004 */,
+0.881699761760385225541 /* 0x0.e1b71359a6df60003 */,
+0.882894217964411143207 /* 0x0.e2055afffc1178000 */,
+0.884090292325693805080 /* 0x0.e253bdcc3ffbb8001 */,
+0.885287987031581180559 /* 0x0.e2a23bc7d7a1d8002 */,
+0.886487304278189114386 /* 0x0.e2f0d4fc31ab80004 */,
+0.887688246263368285778 /* 0x0.e33f8972bea8a8005 */,
+0.888890815189881999840 /* 0x0.e38e5934f49010007 */,
+0.890095013257492739835 /* 0x0.e3dd444c460bd0007 */,
+0.891300842677948068626 /* 0x0.e42c4ac232f380000 */,
+0.892508305659222567226 /* 0x0.e47b6ca036f8b8005 */,
+0.893717404414979710310 /* 0x0.e4caa9efd40e58002 */,
+0.894928141160697743242 /* 0x0.e51a02ba8e2610007 */,
+0.896140518115016826430 /* 0x0.e5697709ecab90000 */,
+0.897354537501434679237 /* 0x0.e5b906e77c61d0006 */,
+0.898570201543732793877 /* 0x0.e608b25cca5ba8005 */,
+0.899787512470129891014 /* 0x0.e6587973688ce8002 */,
+0.901006472512270728537 /* 0x0.e6a85c34ecadb8000 */,
+0.902227083902570559127 /* 0x0.e6f85aaaed4f20006 */,
+0.903449348881299796343 /* 0x0.e74874df09a530003 */,
+0.904673269686823378091 /* 0x0.e798aadadecba0007 */,
+0.905898848559668845585 /* 0x0.e7e8fca80c3ee0001 */,
+0.907126087750156795426 /* 0x0.e8396a503c3fe0005 */,
+0.908354989505901100354 /* 0x0.e889f3dd1615b0002 */,
+0.909585556079328783087 /* 0x0.e8da9958465228007 */,
+0.910817789726044213523 /* 0x0.e92b5acb7d0578001 */,
+0.912051692703457872481 /* 0x0.e97c38406c3c30003 */,
+0.913287267274154990210 /* 0x0.e9cd31c0cbb370001 */,
+0.914524515702244578108 /* 0x0.ea1e475654d540000 */,
+0.915763440256158633982 /* 0x0.ea6f790ac5cc78001 */,
+0.917004043205012497909 /* 0x0.eac0c6e7dd8448007 */,
+0.918246326823137892807 /* 0x0.eb1230f760a428007 */,
+0.919490293387826285200 /* 0x0.eb63b7431714a8007 */,
+0.920735945178816406225 /* 0x0.ebb559d4cb6f30007 */,
+0.921983284479243714322 /* 0x0.ec0718b64c0940002 */,
+0.923232313574974705626 /* 0x0.ec58f3f16a3910002 */,
+0.924483034755387955725 /* 0x0.ecaaeb8ffb3168005 */,
+0.925735450311948926408 /* 0x0.ecfcff9bd67078000 */,
+0.926989562542820610982 /* 0x0.ed4f301edad1a0007 */,
+0.928245373740515189457 /* 0x0.eda17d22e0f9b0001 */,
+0.929502886213858126045 /* 0x0.edf3e6b1d37d40001 */,
+0.930762102264245716494 /* 0x0.ee466cd594c5c8005 */,
+0.932023024199046146183 /* 0x0.ee990f980dcdb0005 */,
+0.933285654329454095216 /* 0x0.eeebcf032bc470007 */,
+0.934549994971191289044 /* 0x0.ef3eab20e0d3c0001 */,
+0.935816048439005676599 /* 0x0.ef91a3fb1e1340004 */,
+0.937083817055075818404 /* 0x0.efe4b99bdcc618006 */,
+0.938353303143720007819 /* 0x0.f037ec0d1889b8000 */,
+0.939624509028518128972 /* 0x0.f08b3b58cc2bb8006 */,
+0.940897437041863904384 /* 0x0.f0dea788fc2a90000 */,
+0.942172089516254085427 /* 0x0.f13230a7ad21b8003 */,
+0.943448468787511540534 /* 0x0.f185d6bee754e0006 */,
+0.944726577195256100890 /* 0x0.f1d999d8b73478005 */,
+0.946006417082291717338 /* 0x0.f22d79ff2cb130000 */,
+0.947287990793413858827 /* 0x0.f281773c59ec48007 */,
+0.948571300678290207925 /* 0x0.f2d5919a566268001 */,
+0.949856349088629370320 /* 0x0.f329c9233bceb0001 */,
+0.951143138379053731954 /* 0x0.f37e1de1272068002 */,
+0.952431670908847949364 /* 0x0.f3d28fde3a6728006 */,
+0.953721949039916472305 /* 0x0.f4271f249a93f0001 */,
+0.955013975135367898520 /* 0x0.f47bcbbe6deab0001 */,
+0.956307751564417496418 /* 0x0.f4d095b5e16638004 */,
+0.957603280698967163097 /* 0x0.f5257d1524f590006 */,
+0.958900564911197350604 /* 0x0.f57a81e668d628000 */,
+0.960199606581278120057 /* 0x0.f5cfa433e60e50007 */,
+0.961500408088936442422 /* 0x0.f624e407d527a0007 */,
+0.962802971817578789903 /* 0x0.f67a416c72b760006 */,
+0.964107300155846558292 /* 0x0.f6cfbc6c011458004 */,
+0.965413395493874504368 /* 0x0.f7255510c439a8002 */,
+0.966721260225105960572 /* 0x0.f77b0b6503c5b8006 */,
+0.968030896745834645873 /* 0x0.f7d0df730a7940005 */,
+0.969342307458006424716 /* 0x0.f826d145294be8003 */,
+0.970655494764855020231 /* 0x0.f87ce0e5b29fd8000 */,
+0.971970461071268720958 /* 0x0.f8d30e5efaa8f0004 */,
+0.973287208789983648852 /* 0x0.f92959bb5e3c08001 */,
+0.974605740331924708124 /* 0x0.f97fc305383028004 */,
+0.975926058115625383329 /* 0x0.f9d64a46ebb9f8004 */,
+0.977248164559556209435 /* 0x0.fa2cef8adbfc68004 */,
+0.978572062087848637573 /* 0x0.fa83b2db7253d0007 */,
+0.979897753126343307191 /* 0x0.fada944319fda0005 */,
+0.981225240104636631254 /* 0x0.fb3193cc425870002 */,
+0.982554525455618277276 /* 0x0.fb88b1815e61d0003 */,
+0.983885611617111077747 /* 0x0.fbdfed6ce683e0007 */,
+0.985218501026348891812 /* 0x0.fc3747995282f8006 */,
+0.986553196127724962867 /* 0x0.fc8ec0112202a0005 */,
+0.987889699367056062238 /* 0x0.fce656ded63710002 */,
+0.989228013193998778636 /* 0x0.fd3e0c0cf48d50005 */,
+0.990568140061241164686 /* 0x0.fd95dfa605c7b0003 */,
+0.991910082424819927754 /* 0x0.fdedd1b4965710004 */,
+0.993253842749249660216 /* 0x0.fe45e2433bfea0000 */,
+0.994599423484053835071 /* 0x0.fe9e115c7c05f0005 */,
+0.995946827107488830167 /* 0x0.fef65f0afb4c28006 */,
+0.997296056085008264529 /* 0x0.ff4ecb59509cc8001 */,
+0.998647112892057764479 /* 0x0.ffa756521dbfd0007 */,
+1.000000000000000000000 /* 0x1.00000000000000000 */,
+1.001354719891689004659 /* 0x1.0058c86da14aa0005 */,
+1.002711275050312211844 /* 0x1.00b1afa5abead0003 */,
+1.004069667960743483835 /* 0x1.010ab5b2cc0660009 */,
+1.005429901112333324093 /* 0x1.0163da9fb2af30008 */,
+1.006791976999887428009 /* 0x1.01bd1e7716f6a0008 */,
+1.008155898118476168101 /* 0x1.02168143b03890006 */,
+1.009521666967782227439 /* 0x1.027003103ae320002 */,
+1.010889286051850133326 /* 0x1.02c9a3e7783030002 */,
+1.012258757875921233497 /* 0x1.032363d42aaa8000e */,
+1.013630084952214405194 /* 0x1.037d42e11c88d0000 */,
+1.015003269791313389451 /* 0x1.03d741191635a0001 */,
+1.016378314911229763267 /* 0x1.04315e86e84630008 */,
+1.017755222831652872635 /* 0x1.048b9b35652800002 */,
+1.019133996077934645224 /* 0x1.04e5f72f65827000b */,
+1.020514637175266248212 /* 0x1.0540727fc1cfa0006 */,
+1.021897148653734488385 /* 0x1.059b0d3157ebb0002 */,
+1.023281533050062419584 /* 0x1.05f5c74f0cfeb0002 */,
+1.024667792897328677539 /* 0x1.0650a0e3c22ee0003 */,
+1.026055930738840826806 /* 0x1.06ab99fa63e1b0008 */,
+1.027445949118511947550 /* 0x1.0706b29ddf2700009 */,
+1.028837850584049418178 /* 0x1.0761ead9253ab0009 */,
+1.030231637685799839262 /* 0x1.07bd42b72a3f80008 */,
+1.031627312979383592802 /* 0x1.0818ba42e824a000c */,
+1.033024879021186448496 /* 0x1.0874518759b0b0008 */,
+1.034424338374263729911 /* 0x1.08d0088f80ffa0006 */,
+1.035825693601787333992 /* 0x1.092bdf66604e30005 */,
+1.037228947273990842283 /* 0x1.0987d617019cd000a */,
+1.038634101961269928846 /* 0x1.09e3ecac6f199000f */,
+1.040041160239590700707 /* 0x1.0a402331b91270002 */,
+1.041450124688240164200 /* 0x1.0a9c79b1f37c3000b */,
+1.042860997889083929381 /* 0x1.0af8f038352160000 */,
+1.044273782427270314011 /* 0x1.0b5586cf986890006 */,
+1.045688480893644856116 /* 0x1.0bb23d833dfbf0006 */,
+1.047105095879385272564 /* 0x1.0c0f145e46e330007 */,
+1.048523629981608529302 /* 0x1.0c6c0b6bdaadc000f */,
+1.049944085800634585634 /* 0x1.0cc922b72470a000f */,
+1.051366465939483019223 /* 0x1.0d265a4b5238b0007 */,
+1.052790773004648849929 /* 0x1.0d83b23395e510002 */,
+1.054217009607077093512 /* 0x1.0de12a7b263970006 */,
+1.055645178360430591625 /* 0x1.0e3ec32d3cf680000 */,
+1.057075281882416506511 /* 0x1.0e9c7c55184f5000e */,
+1.058507322794714378170 /* 0x1.0efa55fdfad51000a */,
+1.059941303721639416236 /* 0x1.0f58503329fed0003 */,
+1.061377227289284297385 /* 0x1.0fb66affed37f0000 */,
+1.062815096132297298980 /* 0x1.1014a66f95540000c */,
+1.064254912884593951029 /* 0x1.1073028d725850007 */,
+1.065696680185205469411 /* 0x1.10d17f64d9ea2000b */,
+1.067140400676658718053 /* 0x1.11301d012586a0007 */,
+1.068586077004890055886 /* 0x1.118edb6db26ab0003 */,
+1.070033711820396415998 /* 0x1.11edbab5e2d6e000b */,
+1.071483307775789262099 /* 0x1.124cbae51b5ef0001 */,
+1.072934867526001312439 /* 0x1.12abdc06c3240000c */,
+1.074388393734249103080 /* 0x1.130b1e264a62e0005 */,
+1.075843889063253344684 /* 0x1.136a814f20ccd0003 */,
+1.077301356179926061823 /* 0x1.13ca058cbaaed000b */,
+1.078760797756675327056 /* 0x1.1429aaea9260e000e */,
+1.080222216468626150775 /* 0x1.148971742537c0009 */,
+1.081685614993597610617 /* 0x1.14e95934f37e8000b */,
+1.083150996013011013776 /* 0x1.1549623881762000d */,
+1.084618362213087383633 /* 0x1.15a98c8a58a6a000b */,
+1.086087716284427351384 /* 0x1.1609d8360768c0008 */,
+1.087559060917626885283 /* 0x1.166a45471c13f0008 */,
+1.089032398810997337465 /* 0x1.16cad3c92d7b50009 */,
+1.090507732647478578212 /* 0x1.172b83c7c18b5000f */,
+1.091985065182095926460 /* 0x1.178c554ead72a000c */,
+1.093464399073070136880 /* 0x1.17ed48695befe000c */,
+1.094945737045367906172 /* 0x1.184e5d23812500007 */,
+1.096429081816546080591 /* 0x1.18af9388c90e40005 */,
+1.097914436104650892651 /* 0x1.1910eba4e031a0001 */,
+1.099401802629782043408 /* 0x1.19726583755720003 */,
+1.100891184121537858001 /* 0x1.19d4013041b860007 */,
+1.102382583308144647940 /* 0x1.1a35beb6fd0cd0007 */,
+1.103876002922312915544 /* 0x1.1a979e2363fa10000 */,
+1.105371445702084232160 /* 0x1.1af99f8139025000e */,
+1.106868914387219016199 /* 0x1.1b5bc2dc408b9000e */,
+1.108368411723785085252 /* 0x1.1bbe084045eb30002 */,
+1.109869940458469095340 /* 0x1.1c206fb91524c000e */,
+1.111373503344554869449 /* 0x1.1c82f952817cc0001 */,
+1.112879103137133007859 /* 0x1.1ce5a51860344000f */,
+1.114386742595953938610 /* 0x1.1d4873168babf000e */,
+1.115896424484008608911 /* 0x1.1dab6358e1d4a000f */,
+1.117408151567338414664 /* 0x1.1e0e75eb43f9c000c */,
+1.118921926613465345265 /* 0x1.1e71aad995078000f */,
+1.120437752409564780022 /* 0x1.1ed5022fcd8600003 */,
+1.121955631720569668277 /* 0x1.1f387bf9cd88b0000 */,
+1.123475567332998359439 /* 0x1.1f9c18438cdec000a */,
+1.124997562033035469759 /* 0x1.1fffd71902f970002 */,
+1.126521618608448571713 /* 0x1.2063b88629079000e */,
+1.128047739853580200284 /* 0x1.20c7bc96ff72a0002 */,
+1.129575928566289189112 /* 0x1.212be3578a81e0006 */,
+1.131106187546149888259 /* 0x1.21902cd3d05f70007 */,
+1.132638519598779369743 /* 0x1.21f49917ddda5000c */,
+1.134172927531616359481 /* 0x1.2259282fc1c24000e */,
+1.135709414157753949251 /* 0x1.22bdda27911e90007 */,
+1.137247982292643566662 /* 0x1.2322af0b638e60007 */,
+1.138788634756517259562 /* 0x1.2387a6e755f270000 */,
+1.140331374372893558110 /* 0x1.23ecc1c788c890006 */,
+1.141876203969685699176 /* 0x1.2451ffb821639000c */,
+1.143423126377846266197 /* 0x1.24b760c5486dc0009 */,
+1.144972144431494420774 /* 0x1.251ce4fb2a0cc0005 */,
+1.146523260971646252006 /* 0x1.25828c65f9fb8000d */,
+1.148076478839068270690 /* 0x1.25e85711ebaeb0000 */,
+1.149631800883562204903 /* 0x1.264e450b3c8a30008 */,
+1.151189229953253789786 /* 0x1.26b4565e281a20003 */,
+1.152748768902654319399 /* 0x1.271a8b16f0f000002 */,
+1.154310420590433317050 /* 0x1.2780e341de2fc0001 */,
+1.155874187878668246681 /* 0x1.27e75eeb3abc90007 */,
+1.157440073633736243899 /* 0x1.284dfe1f5633e000a */,
+1.159008080725518974322 /* 0x1.28b4c0ea840d90001 */,
+1.160578212048386514965 /* 0x1.291ba75932ae60000 */,
+1.162150470417516290340 /* 0x1.2982b177796850008 */,
+1.163724858777502646494 /* 0x1.29e9df51fdd900001 */,
+1.165301379991388053320 /* 0x1.2a5130f50bf34000e */,
+1.166880036952526289469 /* 0x1.2ab8a66d10fdc0008 */,
+1.168460832550151540268 /* 0x1.2b203fc675b7a000a */,
+1.170043769683112966389 /* 0x1.2b87fd0dad7260008 */,
+1.171628851252754177681 /* 0x1.2befde4f2e3da000d */,
+1.173216080163546060084 /* 0x1.2c57e397719940002 */,
+1.174805459325657830448 /* 0x1.2cc00cf2f7491000c */,
+1.176396991650083379037 /* 0x1.2d285a6e3ff90000b */,
+1.177990680055698513602 /* 0x1.2d90cc15d4ff90005 */,
+1.179586527463262646306 /* 0x1.2df961f641c57000c */,
+1.181184536796979545103 /* 0x1.2e621c1c157cd000d */,
+1.182784710984701836994 /* 0x1.2ecafa93e35af0004 */,
+1.184387052960675701386 /* 0x1.2f33fd6a459cb0000 */,
+1.185991565661414393112 /* 0x1.2f9d24abd8fd1000e */,
+1.187598252026902612178 /* 0x1.300670653e083000a */,
+1.189207115003001469262 /* 0x1.306fe0a31bc040008 */,
+1.190818157535919796833 /* 0x1.30d9757219895000e */,
+1.192431382587621380206 /* 0x1.31432edef01a1000f */,
+1.194046793097208292195 /* 0x1.31ad0cf63f0630008 */,
+1.195664392040319823392 /* 0x1.32170fc4ce0db000c */,
+1.197284182375793593084 /* 0x1.32813757527750005 */,
+1.198906167074650808198 /* 0x1.32eb83ba8eef3000f */,
+1.200530349107333139048 /* 0x1.3355f4fb457e5000d */,
+1.202156731453099647353 /* 0x1.33c08b2641df9000c */,
+1.203785317090505513368 /* 0x1.342b46484f07b0005 */,
+1.205416109005122526928 /* 0x1.3496266e3fa270005 */,
+1.207049110184904572310 /* 0x1.35012ba4e8fa10000 */,
+1.208684323627194912036 /* 0x1.356c55f92aabb0004 */,
+1.210321752322854882437 /* 0x1.35d7a577dd33f0004 */,
+1.211961399276747286580 /* 0x1.36431a2de8748000d */,
+1.213603267492579629347 /* 0x1.36aeb4283309e000c */,
+1.215247359985374142610 /* 0x1.371a7373b00160000 */,
+1.216893679753690671322 /* 0x1.3786581d404e90000 */,
+1.218542229828181611183 /* 0x1.37f26231e82e4000c */,
+1.220193013225231215567 /* 0x1.385e91be9c2d20002 */,
+1.221846032973555429280 /* 0x1.38cae6d05e66f0000 */,
+1.223501292099485437962 /* 0x1.393761742e5830001 */,
+1.225158793636904830441 /* 0x1.39a401b713cb3000e */,
+1.226818540625497444577 /* 0x1.3a10c7a61ceae0007 */,
+1.228480536107136034131 /* 0x1.3a7db34e5a4a50003 */,
+1.230144783126481566885 /* 0x1.3aeac4bcdf8d60001 */,
+1.231811284734168454619 /* 0x1.3b57fbfec6e950008 */,
+1.233480043984379381835 /* 0x1.3bc559212e7a2000f */,
+1.235151063936380300149 /* 0x1.3c32dc3139f2a0004 */,
+1.236824347652524913647 /* 0x1.3ca0853c106ac000e */,
+1.238499898199571624970 /* 0x1.3d0e544eddd240003 */,
+1.240177718649636107175 /* 0x1.3d7c4976d3fcd0000 */,
+1.241857812073360767273 /* 0x1.3dea64c1231f70004 */,
+1.243540181554270152039 /* 0x1.3e58a63b099920005 */,
+1.245224830175077013244 /* 0x1.3ec70df1c4e46000e */,
+1.246911761022835740725 /* 0x1.3f359bf29741c000e */,
+1.248600977188942806639 /* 0x1.3fa4504ac7b800009 */,
+1.250292481770148400634 /* 0x1.40132b07a330d000a */,
+1.251986277866492969263 /* 0x1.40822c367a340000b */,
+1.253682368581898742876 /* 0x1.40f153e4a18e0000d */,
+1.255380757024939564249 /* 0x1.4160a21f73289000d */,
+1.257081446308726757662 /* 0x1.41d016f44deaa000c */,
+1.258784439550028944083 /* 0x1.423fb27094c090008 */,
+1.260489739869405489991 /* 0x1.42af74a1aec1c0006 */,
+1.262197350394008266193 /* 0x1.431f5d950a453000c */,
+1.263907274252603851764 /* 0x1.438f6d58176860004 */,
+1.265619514578811388761 /* 0x1.43ffa3f84b9eb000d */,
+1.267334074511444086425 /* 0x1.44700183221180008 */,
+1.269050957191869555296 /* 0x1.44e0860618b930006 */,
+1.270770165768063009230 /* 0x1.4551318eb4d20000e */,
+1.272491703389059036805 /* 0x1.45c2042a7cc26000b */,
+1.274215573211836316547 /* 0x1.4632fde6ffacd000d */,
+1.275941778396075143580 /* 0x1.46a41ed1cfac40001 */,
+1.277670322103555911043 /* 0x1.471566f8812ac0000 */,
+1.279401207505722393185 /* 0x1.4786d668b33260005 */,
+1.281134437771823675369 /* 0x1.47f86d3002637000a */,
+1.282870016078732078362 /* 0x1.486a2b5c13c00000e */,
+1.284607945607987078432 /* 0x1.48dc10fa916bd0004 */,
+1.286348229545787758022 /* 0x1.494e1e192aaa30007 */,
+1.288090871080605159846 /* 0x1.49c052c5913df000c */,
+1.289835873406902644341 /* 0x1.4a32af0d7d8090002 */,
+1.291583239722392528754 /* 0x1.4aa532feab5e10002 */,
+1.293332973229098792374 /* 0x1.4b17dea6db8010008 */,
+1.295085077135345708087 /* 0x1.4b8ab213d57d9000d */,
+1.296839554650994097442 /* 0x1.4bfdad53629e10003 */,
+1.298596408992440220988 /* 0x1.4c70d0735358a000d */,
+1.300355643380135983739 /* 0x1.4ce41b817c99e0001 */,
+1.302117261036232376282 /* 0x1.4d578e8bb52cb0003 */,
+1.303881265192249561154 /* 0x1.4dcb299fde2920008 */,
+1.305647659079073541490 /* 0x1.4e3eeccbd7f4c0003 */,
+1.307416445934474813521 /* 0x1.4eb2d81d8a86f000b */,
+1.309187629001237640529 /* 0x1.4f26eba2e35a5000e */,
+1.310961211525240921493 /* 0x1.4f9b2769d35090009 */,
+1.312737196755087820678 /* 0x1.500f8b804e4a30000 */,
+1.314515587949291131086 /* 0x1.508417f4530d00009 */,
+1.316296388365203462468 /* 0x1.50f8ccd3df1840003 */,
+1.318079601265708777911 /* 0x1.516daa2cf60020002 */,
+1.319865229921343141607 /* 0x1.51e2b00da3c2b0007 */,
+1.321653277603506371251 /* 0x1.5257de83f5512000d */,
+1.323443747588034513690 /* 0x1.52cd359dfc7d5000e */,
+1.325236643161341820781 /* 0x1.5342b569d6baa000f */,
+1.327031967602244177939 /* 0x1.53b85df59921b0000 */,
+1.328829724206201046165 /* 0x1.542e2f4f6b17e0006 */,
+1.330629916266568235675 /* 0x1.54a4298571b27000e */,
+1.332432547083447937938 /* 0x1.551a4ca5d97190009 */,
+1.334237619959296017340 /* 0x1.559098bed16bf0008 */,
+1.336045138203900251029 /* 0x1.56070dde90c800000 */,
+1.337855105129210686631 /* 0x1.567dac13510cd0009 */,
+1.339667524053662184301 /* 0x1.56f4736b52e2c000c */,
+1.341482398296830025383 /* 0x1.576b63f4d8333000f */,
+1.343299731186792467254 /* 0x1.57e27dbe2c40e0003 */,
+1.345119526053918823702 /* 0x1.5859c0d59cd37000f */,
+1.346941786233264881662 /* 0x1.58d12d497cd9a0005 */,
+1.348766515064854010261 /* 0x1.5948c32824b87000c */,
+1.350593715891792223641 /* 0x1.59c0827ff03890007 */,
+1.352423392064920459908 /* 0x1.5a386b5f43a3e0006 */,
+1.354255546937278120764 /* 0x1.5ab07dd485af1000c */,
+1.356090183865519494030 /* 0x1.5b28b9ee21085000f */,
+1.357927306213322804534 /* 0x1.5ba11fba8816e000b */,
+1.359766917346459269620 /* 0x1.5c19af482f8f2000f */,
+1.361609020638567812980 /* 0x1.5c9268a594cc00004 */,
+1.363453619463660171403 /* 0x1.5d0b4be135916000c */,
+1.365300717204201985683 /* 0x1.5d84590998eeb0005 */,
+1.367150317245710233754 /* 0x1.5dfd902d494e40001 */,
+1.369002422974674892971 /* 0x1.5e76f15ad22c40008 */,
+1.370857037789471544224 /* 0x1.5ef07ca0cc166000b */,
+1.372714165088220639199 /* 0x1.5f6a320dcf5280006 */,
+1.374573808273481745378 /* 0x1.5fe411b0790800009 */,
+1.376435970755022220096 /* 0x1.605e1b976e4b1000e */,
+1.378300655944092456600 /* 0x1.60d84fd155d15000e */,
+1.380167867259843417228 /* 0x1.6152ae6cdf0030003 */,
+1.382037608124419003675 /* 0x1.61cd3778bc879000d */,
+1.383909881963391264069 /* 0x1.6247eb03a4dc40009 */,
+1.385784692209972801544 /* 0x1.62c2c91c56d9b0002 */,
+1.387662042298923203992 /* 0x1.633dd1d1930ec0001 */,
+1.389541935670444372533 /* 0x1.63b90532200630004 */,
+1.391424375772021271329 /* 0x1.6434634ccc4cc0007 */,
+1.393309366052102982208 /* 0x1.64afec30677e90008 */,
+1.395196909966106124701 /* 0x1.652b9febc8e0f000d */,
+1.397087010973788290271 /* 0x1.65a77e8dcc7f10004 */,
+1.398979672539331309267 /* 0x1.66238825534170000 */,
+1.400874898129892187656 /* 0x1.669fbcc1415600008 */,
+1.402772691220124823310 /* 0x1.671c1c708328e000a */,
+1.404673055288671035301 /* 0x1.6798a7420988b000d */,
+1.406575993818903302975 /* 0x1.68155d44ca77a000f */,
+1.408481510297352468121 /* 0x1.68923e87bf70e000a */,
+1.410389608216942924956 /* 0x1.690f4b19e8f74000c */,
+1.412300291075172076232 /* 0x1.698c830a4c94c0008 */
+};
+#define S (1.0/4503599627370496.0) /* 2^-52 */
+static const float exp2_deltatable[512] = {
+ 11527*S, -963*S, 884*S, -781*S, -2363*S, -3441*S, 123*S, 526*S,
+ -6*S, 1254*S, -1138*S, 1519*S, 1576*S, -65*S, 1040*S, 793*S,
+ -1662*S, -5063*S, -387*S, 968*S, -941*S, 984*S, -2856*S, -545*S,
+ 495*S, -5246*S, -2109*S, 1281*S, 2075*S, 909*S, -1642*S,-78233*S,
+-31653*S, -265*S, 130*S, 430*S, 2482*S, -742*S, 1616*S, -2213*S,
+ -519*S, 20*S, -3134*S,-13981*S, 1343*S, -1740*S, 247*S, 1679*S,
+ -1097*S, 3131*S, 871*S, -1480*S, 1936*S, -1827*S, 17325*S, 528*S,
+ -322*S, 1404*S, -152*S, -1845*S, -212*S, 2639*S, -476*S, 2960*S,
+ -962*S, -1012*S, -1231*S, 3030*S, 1659*S, -486*S, 2154*S, 1728*S,
+ -2793*S, 699*S, -1560*S, -2125*S, 2156*S, 142*S, -1888*S, 4426*S,
+-13443*S, 1970*S, -50*S, 1771*S,-43399*S, 4979*S, -2448*S, -370*S,
+ 1414*S, 1075*S, 232*S, 206*S, 873*S, 2141*S, 2970*S, 1279*S,
+ -2331*S, 336*S, -2595*S, 753*S, -3384*S, -616*S, 89*S, -818*S,
+ 5755*S, -241*S, -528*S, -661*S, -3777*S, -354*S, 250*S, 3881*S,
+ 2632*S, -2131*S, 2565*S, -316*S, 1746*S, -2541*S, -1324*S, -50*S,
+ 2564*S, -782*S, 1176*S, 6452*S, -1002*S, 1288*S, 336*S, -185*S,
+ 3063*S, 3784*S, 2169*S, 686*S, 328*S, -400*S, 312*S, -4517*S,
+ -1457*S, 1046*S, -1530*S, -685*S, 1328*S,-49815*S, -895*S, 1063*S,
+ -2091*S, -672*S, -1710*S, -665*S, 1545*S, 1819*S,-45265*S, 3548*S,
+ -554*S, -568*S, 4752*S, -1907*S,-13738*S, 675*S, 9611*S, -1115*S,
+ -815*S, 408*S, -1281*S, -937*S,-16376*S, -4772*S, -1440*S, 992*S,
+ 788*S, 10364*S, -1602*S, -661*S, -1783*S, -265*S, -20*S, -3781*S,
+ -861*S, -345*S, -994*S, 1364*S, -5339*S, 1620*S, 9390*S, -1066*S,
+ -305*S, -170*S, 175*S, 2461*S, -490*S, -769*S, -1450*S, 3315*S,
+ 2418*S, -45*S, -852*S, -1295*S, -488*S, -96*S, 1142*S, -2639*S,
+ 7905*S, -9306*S, -3859*S, 760*S, 1057*S, -1570*S, 3977*S, 209*S,
+ -514*S, 7151*S, 1646*S, 627*S, 599*S, -774*S, -1468*S, 633*S,
+ -473*S, 851*S, 2406*S, 143*S, 74*S, 4260*S, 1177*S, -913*S,
+ 2670*S, -3298*S, -1662*S, -120*S, -3264*S, -2148*S, 410*S, 2078*S,
+ -2098*S, -926*S, 3580*S, -1289*S, 2450*S, -1158*S, 907*S, -590*S,
+ 986*S, 1801*S, 1145*S, -1677*S, 3455*S, 956*S, 710*S, 144*S,
+ 153*S, -255*S, -1898*S, 28102*S, 2748*S, 1194*S, -3009*S, 7076*S,
+ 0*S, -2720*S, 711*S, 1225*S, -3034*S, -473*S, 378*S, -1046*S,
+ 962*S, -2006*S, 4647*S, 3206*S, 1769*S, -2665*S, 1254*S, 2025*S,
+ -2430*S, 6193*S, 1224*S, -856*S, -1592*S, -325*S, -1521*S, 1827*S,
+ -264*S, 2403*S, -1065*S, 967*S, -681*S, -2106*S, -474*S, 1333*S,
+ -893*S, 2296*S, 592*S, -1220*S, -326*S, 990*S, 139*S, 206*S,
+ -779*S, -1683*S, 1238*S, 6098*S, 136*S, 1197*S, 790*S, -107*S,
+ -1004*S, -2449*S, 939*S, 5568*S, 156*S, 1812*S, 2792*S, -1094*S,
+ -2677*S, -251*S, 2297*S, 943*S, -1329*S, 2883*S, -853*S, -2626*S,
+-105929*S, -6552*S, 1095*S, -1508*S, 1003*S, 5039*S, -2600*S, -749*S,
+ 1790*S, 890*S, 2016*S, -1073*S, 624*S, -2084*S, -1536*S, -1330*S,
+ 358*S, 2444*S, -179*S,-25759*S, -243*S, -552*S, -124*S, 3766*S,
+ 1192*S, -1614*S, 6*S, -1227*S, 345*S, -981*S, -295*S, -1006*S,
+ -995*S, -1195*S, 706*S, 2512*S, -1758*S, -734*S, -6286*S, -922*S,
+ 1530*S, 1542*S, 1223*S, 61*S, -83*S, 522*S,116937*S, -914*S,
+ -418*S, -7339*S, 249*S, -520*S, -762*S, 426*S, -505*S, 2664*S,
+ -1093*S, -1035*S, 2130*S, 4878*S, 1982*S, 1551*S, 2304*S, 193*S,
+ 1532*S, -7268*S, 24357*S, 531*S, 2676*S, -1170*S, 1465*S, -1917*S,
+ 2143*S, 1466*S, -7*S, -7300*S, 3297*S, -1197*S, -289*S, -1548*S,
+ 26226*S, 4401*S, 4123*S, -1588*S, 4243*S, 4069*S, -1276*S, -2010*S,
+ 1407*S, 1478*S, 488*S, -2366*S, -2909*S, -2534*S, -1285*S, 7095*S,
+ -645*S, -2089*S, -944*S, -40*S, -1363*S, -833*S, 917*S, 1609*S,
+ 1286*S, 1677*S, 1613*S, -2295*S, -1248*S, 40*S, 26*S, 2038*S,
+ 698*S, 2675*S, -1755*S, -3522*S, -1614*S, -6111*S, 270*S, 1822*S,
+ -234*S, -2844*S, -1201*S, -830*S, 1193*S, 2354*S, 47*S, 1522*S,
+ -78*S, -640*S, 2425*S, -1596*S, 1563*S, 1169*S, -1006*S, -83*S,
+ 2362*S, -3521*S, -314*S, 1814*S, -1751*S, 305*S, 1715*S, -3741*S,
+ 7847*S, 1291*S, 1206*S, 36*S, 1397*S, -1419*S, -1194*S, -2014*S,
+ 1742*S, -578*S, -207*S, 875*S, 1539*S, 2826*S, -1165*S, -909*S,
+ 1849*S, 927*S, 2018*S, -981*S, 1637*S, -463*S, 905*S, 6618*S,
+ 400*S, 630*S, 2614*S, 900*S, 2323*S, -1094*S, -1858*S, -212*S,
+ -2069*S, 747*S, 1845*S, -1450*S, 444*S, -213*S, -438*S, 1158*S,
+ 4738*S, 2497*S, -370*S, -2016*S, -518*S, -1160*S, -1510*S, 123*S
+};
+/* Maximum magnitude in above table: 116937 */
+#undef S
diff --git a/libc/sysdeps/ieee754/dbl-64/uasncs.h b/libc/sysdeps/ieee754/dbl-64/uasncs.h
new file mode 100644
index 000000000..69fbb58a5
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/uasncs.h
@@ -0,0 +1,70 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/******************************************************************/
+/* */
+/* MODULE_NAME:uasncs.h */
+/* */
+/* common data and variables prototype and definition */
+/******************************************************************/
+
+#ifndef UANSNCS_H
+#define UANSNCS_H
+
+#ifdef BIG_ENDI
+ static const mynumber
+/**/ a1 = {{0x3FC55580, 0x00000000 }}, /* 0.1666717529296875 */
+/**/ a2 = {{0xBED55555, 0x55552330 }}, /* -5.0862630208224597e-06 */
+/**/ hp0 = {{0x3FF921FB, 0x54442D18 }}, /* 1.5707963267948966 */
+/**/ hp1 = {{0x3C91A626, 0x33145C07 }}; /* 6.123233995736766e-17 */
+
+#else
+#ifdef LITTLE_ENDI
+ static const mynumber
+/**/ a1 = {{0x00000000, 0x3FC55580 }}, /* 0.1666717529296875 */
+/**/ a2 = {{0x55552330, 0xBED55555 }}, /* -5.0862630208224597e-06 */
+/**/ hp0 = {{0x54442D18, 0x3FF921FB }}, /* 1.5707963267948966 */
+/**/ hp1 = {{0x33145C07, 0x3C91A626 }}; /* 6.123233995736766e-17 */
+
+#endif
+#endif
+
+static const double
+ f1 = 1.66666666666664110590506577996662E-01,
+ f2 = 7.50000000026122686814431784722623E-02,
+ f3 = 4.46428561421059750978517350006940E-02,
+ f4 = 3.03821268582119319911193410625235E-02,
+ f5 = 2.23551211026525610742786300334557E-02,
+ f6 = 1.81382903404565056280372531963613E-02;
+static const double
+ c2 = 0.74999999999985410757087492918602258E-01,
+ c3 = 0.44642857150311968932423372477866076E-01,
+ c4 = 0.30381942574778615766200591683810471E-01,
+ c5 = 0.22372413472984868331447708777000650E-01,
+ c6 = 0.17333630246451830686009693735025490E-01,
+ c7 = 0.14710362893628210269950864741085777E-01;
+
+static const double big = 103079215104.0, t24 = 16777216.0, t27 = 134217728.0;
+static const double
+ rt0 = 9.99999999859990725855365213134618E-01,
+ rt1 = 4.99999999495955425917856814202739E-01,
+ rt2 = 3.75017500867345182581453026130850E-01,
+ rt3 = 3.12523626554518656309172508769531E-01;
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/uatan.tbl b/libc/sysdeps/ieee754/dbl-64/uatan.tbl
new file mode 100644
index 000000000..5b4b5f27a
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/uatan.tbl
@@ -0,0 +1,11135 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/****************************************************************/
+/* TABLES FOR THE uatan() FUNCTION */
+/****************************************************************/
+
+#include "endian.h"
+
+#ifdef BIG_ENDI
+
+ static const number
+ cij[241][7] = { /* x0,cij for (1/16,1) */
+/**/ {{{0X3FB04006, 0X65E0244E} },
+/**/ {{0X3FB03A73, 0X7B53DD20} },
+/**/ {{0X3FEFDF1F, 0XCF5CFB72} },
+/**/ {{0XBFB01EB3, 0XCE2AE4C2} },
+/**/ {{0XBFD4D29E, 0XDD58A40D} },
+/**/ {{0X3FAFDA4A, 0XD907A18A} },
+/**/ {{0X3FC814DF, 0X4DF65B18} } },
+/**/ {{{0X3FB0FFFD, 0XB9B88CD8} },
+/**/ {{0X3FB0F99C, 0X63645300} },
+/**/ {{0X3FEFDC08, 0XA3DED30F} },
+/**/ {{0XBFB0D9DC, 0X669C1AED} },
+/**/ {{0XBFD4C669, 0XF7138DE2} },
+/**/ {{0X3FB0A12F, 0X29D085A7} },
+/**/ {{0X3FC7F0EE, 0XCFD48D20} } },
+/**/ {{{0X3FB1FFF1, 0X5A73D4F1} },
+/**/ {{0X3FB1F85F, 0X2BEE2040} },
+/**/ {{0X3FEFD7B3, 0X42B56D31} },
+/**/ {{0XBFB1D2B7, 0XB69DEA40} },
+/**/ {{0XBFD4B552, 0X3922ECC9} },
+/**/ {{0X3FB18F93, 0X522B1A04} },
+/**/ {{0X3FC7BEAD, 0X5660F061} } },
+/**/ {{{0X3FB2FFFD, 0XB2524AA2} },
+/**/ {{0X3FB2F716, 0XE71790A0} },
+/**/ {{0X3FEFD31F, 0X53B496A4} },
+/**/ {{0XBFB2CAD8, 0X4AAB7374} },
+/**/ {{0XBFD4A34B, 0X58DD2FB2} },
+/**/ {{0X3FB27C0A, 0XD0CECC18} },
+/**/ {{0X3FC789D2, 0X5D2743D7} } },
+/**/ {{{0X3FB3FFFE, 0X0573F3AC} },
+/**/ {{0X3FB3F59D, 0X1702F6A0} },
+/**/ {{0X3FEFCE4D, 0XB071ACC2} },
+/**/ {{0XBFB3C20F, 0X64DB3686} },
+/**/ {{0XBFD49059, 0XEB3BFE93} },
+/**/ {{0X3FB36659, 0XCAF74FED} },
+/**/ {{0X3FC75269, 0X1C011FB0} } },
+/**/ {{{0X3FB4FFEF, 0X894384D6} },
+/**/ {{0X3FB4F3ED, 0X0CE204C0} },
+/**/ {{0X3FEFC93E, 0XA8EA5A01} },
+/**/ {{0XBFB4B84F, 0X7B5457C9} },
+/**/ {{0XBFD47C80, 0X7401F2F9} },
+/**/ {{0X3FB44E64, 0XB4F67209} },
+/**/ {{0X3FC7187D, 0X4C540B77} } },
+/**/ {{{0X3FB5FFF8, 0XDF406528} },
+/**/ {{0X3FB5F22B, 0X3C73D820} },
+/**/ {{0X3FEFC3F1, 0XB1F60F13} },
+/**/ {{0XBFB5ADB2, 0XCB7FA73B} },
+/**/ {{0XBFD467BE, 0X2B1EB555} },
+/**/ {{0X3FB53435, 0X99EDC463} },
+/**/ {{0X3FC6DC1B, 0X238F5059} } },
+/**/ {{{0X3FB7000F, 0X8C4F0D56} },
+/**/ {{0X3FB6F04B, 0X495A2FA0} },
+/**/ {{0X3FEFBE67, 0X340DCE97} },
+/**/ {{0XBFB6A224, 0X4D98E1AD} },
+/**/ {{0XBFD45216, 0X14064DF1} },
+/**/ {{0X3FB617AA, 0X2BA78A66} },
+/**/ {{0X3FC69D4F, 0X50A3D7AC} } },
+/**/ {{{0X3FB8000F, 0XBB4057CF} },
+/**/ {{0X3FB7EE27, 0XBE2CD3A0} },
+/**/ {{0X3FEFB8A0, 0X39EC9246} },
+/**/ {{0XBFB79577, 0X31D9C773} },
+/**/ {{0XBFD43B8D, 0XB6DC7D72} },
+/**/ {{0X3FB6F88A, 0XD69547DF} },
+/**/ {{0X3FC65C26, 0XF633CE8C} } },
+/**/ {{{0X3FB8FFF2, 0X39CF2B7F} },
+/**/ {{0X3FB8EBB7, 0X9F979E80} },
+/**/ {{0X3FEFB29D, 0X435506E1} },
+/**/ {{0XBFB8879A, 0X69B9CDB5} },
+/**/ {{0XBFD42428, 0X85FEAFA9} },
+/**/ {{0X3FB7D6BA, 0XB6191A0E} },
+/**/ {{0X3FC618AF, 0XA7CB8BB5} } },
+/**/ {{{0X3FB9FFF9, 0X6E2F0772} },
+/**/ {{0X3FB9E93A, 0XD32A9480} },
+/**/ {{0X3FEFAC5D, 0X04A3EC40} },
+/**/ {{0XBFB978C2, 0X53F6EA97} },
+/**/ {{0XBFD40BE3, 0X089C36F6} },
+/**/ {{0X3FB8B25C, 0X885AEB77} },
+/**/ {{0X3FC5D2F7, 0X63CADCE1} } },
+/**/ {{{0X3FBB0002, 0X6316B097} },
+/**/ {{0X3FBAE68C, 0XCE24CC00} },
+/**/ {{0X3FEFA5E0, 0X938C5C66} },
+/**/ {{0XBFBA68C3, 0X76F14E4B} },
+/**/ {{0XBFD3F2C3, 0X1696CD7C} },
+/**/ {{0X3FB98B3B, 0X722A2CB4} },
+/**/ {{0X3FC58B0C, 0X9067AD62} } },
+/**/ {{{0X3FBC0008, 0X604F58B1} },
+/**/ {{0X3FBBE3A7, 0X05650780} },
+/**/ {{0X3FEF9F28, 0X5A7A2773} },
+/**/ {{0XBFBB578F, 0X3D5AC0A4} },
+/**/ {{0XBFD3D8CB, 0XF767119F} },
+/**/ {{0X3FBA613D, 0XC7E31B88} },
+/**/ {{0X3FC540FD, 0XF5594565} } },
+/**/ {{{0X3FBD0002, 0X6CCA4EBA} },
+/**/ {{0X3FBCE07E, 0XC1298A80} },
+/**/ {{0X3FEF9834, 0XE8D36C4A} },
+/**/ {{0XBFBC4513, 0X5BCAC5FE} },
+/**/ {{0XBFD3BE01, 0X8B5236F1} },
+/**/ {{0X3FBB3447, 0X2E991970} },
+/**/ {{0X3FC4F4DA, 0XB8ADB373} } },
+/**/ {{{0X3FBDFFF4, 0XB2B47FCA} },
+/**/ {{0X3FBDDD16, 0X4A051D80} },
+/**/ {{0X3FEF9106, 0X78DCC895} },
+/**/ {{0XBFBD3149, 0XF0966844} },
+/**/ {{0XBFD3A266, 0X744F9A5F} },
+/**/ {{0X3FBC0446, 0XEDB7F27A} },
+/**/ {{0X3FC4A6B2, 0X583F9ECA} } },
+/**/ {{{0X3FBF000A, 0XA9A05BE0} },
+/**/ {{0X3FBED996, 0XA3BDA540} },
+/**/ {{0X3FEF899C, 0X1B8BA97F} },
+/**/ {{0XBFBE1C51, 0X2287A677} },
+/**/ {{0XBFD385F8, 0XEDC130BB} },
+/**/ {{0X3FBCD14B, 0XF306FF50} },
+/**/ {{0X3FC45694, 0XA667A72B} } },
+/**/ {{{0X3FBFFFFA, 0XBA8F63DE} },
+/**/ {{0X3FBFD5B5, 0X69FE4780} },
+/**/ {{0X3FEF81F8, 0X4863DC7D} },
+/**/ {{0XBFBF05DB, 0XD1518706} },
+/**/ {{0XBFD368C4, 0X4687A69C} },
+/**/ {{0X3FBD9B08, 0X1B3868DA} },
+/**/ {{0X3FC40491, 0XC345ADFC} } },
+/**/ {{{0X3FC07FFA, 0X6ECCADA8} },
+/**/ {{0X3FC068D0, 0X0A396400} },
+/**/ {{0X3FEF7A19, 0XF1FCFC6B} },
+/**/ {{0XBFBFEE0C, 0X861DF0DF} },
+/**/ {{0XBFD34AC6, 0X5A586C0C} },
+/**/ {{0X3FBE618F, 0X189D637A} },
+/**/ {{0X3FC3B0BA, 0X195779D4} } },
+/**/ {{{0X3FC10003, 0X33432713} },
+/**/ {{0X3FC0E6B0, 0XF203D1A0} },
+/**/ {{0X3FEF7200, 0XFE0EB463} },
+/**/ {{0XBFC06A72, 0XE15CB19A} },
+/**/ {{0XBFD32C00, 0XB8DB761E} },
+/**/ {{0X3FBF24D8, 0XA11F5E3E} },
+/**/ {{0X3FC35B1E, 0X569E85DD} } },
+/**/ {{{0X3FC17FFC, 0XDA1C4811} },
+/**/ {{0X3FC16462, 0X29EBDA00} },
+/**/ {{0X3FEF69AF, 0X7D558737} },
+/**/ {{0XBFC0DD17, 0X0B33969B} },
+/**/ {{0XBFD30C7D, 0X33AC50D1} },
+/**/ {{0X3FBFE4AA, 0X9BE43F0F} },
+/**/ {{0X3FC303CF, 0X692539CB} } },
+/**/ {{{0X3FC1FFFF, 0X3CCA418D} },
+/**/ {{0X3FC1E1FA, 0X3B978EA0} },
+/**/ {{0X3FEF6124, 0X45D421A9} },
+/**/ {{0XBFC14F03, 0XACAC8AA8} },
+/**/ {{0XBFD2EC39, 0X62E675A3} },
+/**/ {{0X3FC0508C, 0X2FA6B426} },
+/**/ {{0X3FC2AADE, 0X780A6467} } },
+/**/ {{{0X3FC27FF7, 0XD9C78922} },
+/**/ {{0X3FC25F66, 0X1B91E640} },
+/**/ {{0X3FEF5860, 0XF52E192C} },
+/**/ {{0XBFC1C023, 0XE5DE2394} },
+/**/ {{0XBFD2CB3D, 0X6BEE0ABD} },
+/**/ {{0X3FC0ACFB, 0X5E075C1A} },
+/**/ {{0X3FC2505C, 0XDFFE453A} } },
+/**/ {{{0X3FC2FFF7, 0XA1FC1AAA} },
+/**/ {{0X3FC2DCB5, 0X83257C40} },
+/**/ {{0X3FEF4F64, 0XC719B6FB} },
+/**/ {{0XBFC23082, 0X61514083} },
+/**/ {{0XBFD2A988, 0X7F7B72D5} },
+/**/ {{0X3FC107A7, 0X7C887402} },
+/**/ {{0X3FC1F45C, 0X2C3CD6D1} } },
+/**/ {{{0X3FC38005, 0X9D78E15E} },
+/**/ {{0X3FC359EE, 0X6AC98EE0} },
+/**/ {{0X3FEF462F, 0X944CEC16} },
+/**/ {{0XBFC2A020, 0XD85B87A9} },
+/**/ {{0XBFD2871C, 0X2E4AB369} },
+/**/ {{0X3FC1608D, 0XC31A65D9} },
+/**/ {{0X3FC196EE, 0X130BBE50} } },
+/**/ {{{0X3FC40004, 0X9F431B1A} },
+/**/ {{0X3FC3D6F3, 0X6BD65360} },
+/**/ {{0X3FEF3CC3, 0XDD99B68A} },
+/**/ {{0XBFC30EE1, 0XB3DD00ED} },
+/**/ {{0XBFD26403, 0XF8482664} },
+/**/ {{0X3FC1B792, 0XFE136626} },
+/**/ {{0X3FC13824, 0X6EAC7440} } },
+/**/ {{{0X3FC48004, 0XE01D95A1} },
+/**/ {{0X3FC453D3, 0X86F00CC0} },
+/**/ {{0X3FEF3320, 0XE3970539} },
+/**/ {{0XBFC37CCF, 0X0A5279AA} },
+/**/ {{0XBFD2403F, 0X3B151D5D} },
+/**/ {{0X3FC20CBB, 0XE331C9E6} },
+/**/ {{0X3FC0D811, 0X39E3F097} } },
+/**/ {{{0X3FC4FFF7, 0XAA9382DD} },
+/**/ {{0X3FC4D07F, 0X8C590A80} },
+/**/ {{0X3FEF2948, 0X34DF28E0} },
+/**/ {{0XBFC3E9D8, 0X5B43915C} },
+/**/ {{0XBFD21BD5, 0XEB8845A2} },
+/**/ {{0X3FC25FF8, 0XAC6AC8AD} },
+/**/ {{0X3FC076C6, 0X88ED96CA} } },
+/**/ {{{0X3FC58006, 0X352408BE} },
+/**/ {{0X3FC54D1E, 0XC39A73E0} },
+/**/ {{0X3FEF1F37, 0X09AE009C} },
+/**/ {{0XBFC4561C, 0XB9BE8550} },
+/**/ {{0XBFD1F6C0, 0X0053F52E} },
+/**/ {{0X3FC2B15D, 0XEF783BE9} },
+/**/ {{0X3FC01456, 0X8615239B} } },
+/**/ {{{0X3FC5FFFF, 0X2B193F81} },
+/**/ {{0X3FC5C980, 0X4F73E000} },
+/**/ {{0X3FEF14F1, 0XAE110E29} },
+/**/ {{0XBFC4C16E, 0X9098B3D2} },
+/**/ {{0XBFD1D10F, 0X8F058241} },
+/**/ {{0X3FC300C6, 0XA14FA897} },
+/**/ {{0X3FBF61A6, 0XD56607C0} } },
+/**/ {{{0X3FC68008, 0X4460E6E1} },
+/**/ {{0X3FC645C8, 0X04A55E20} },
+/**/ {{0X3FEF0A75, 0X8FA36EC5} },
+/**/ {{0XBFC52BE9, 0XD62FA883} },
+/**/ {{0XBFD1AABD, 0X69A74048} },
+/**/ {{0X3FC34E45, 0X1679EB02} },
+/**/ {{0X3FBE989E, 0XF7C14C3D} } },
+/**/ {{{0X3FC6FFFB, 0X9E99A846} },
+/**/ {{0X3FC6C1D0, 0X4B35FD40} },
+/**/ {{0X3FEEFFC6, 0X3EF8EF95} },
+/**/ {{0XBFC5956B, 0X76A2FE63} },
+/**/ {{0XBFD183D8, 0XDDC78DDF} },
+/**/ {{0X3FC399BD, 0XAC606D66} },
+/**/ {{0X3FBDCDBA, 0X070D286A} } },
+/**/ {{{0X3FC78008, 0X0FFCD490} },
+/**/ {{0X3FC73DC5, 0XB55758E0} },
+/**/ {{0X3FEEF4E0, 0X457E2065} },
+/**/ {{0XBFC5FE16, 0X7D6FF9BC} },
+/**/ {{0XBFD15C57, 0X9FADD384} },
+/**/ {{0X3FC3E347, 0X73E52D32} },
+/**/ {{0X3FBD011C, 0X9A65AE4B} } },
+/**/ {{{0X3FC80006, 0X148E79C1} },
+/**/ {{0X3FC7B981, 0X2B7F8CA0} },
+/**/ {{0X3FEEE9C7, 0X701687ED} },
+/**/ {{0XBFC665C7, 0X0E1EF36D} },
+/**/ {{0XBFD13449, 0XCCBCBDAB} },
+/**/ {{0X3FC42AC7, 0X5C71B3E8} },
+/**/ {{0X3FBC32EB, 0X3E81980E} } },
+/**/ {{{0X3FC88006, 0X0F487C17} },
+/**/ {{0X3FC83511, 0XBC0E3640} },
+/**/ {{0X3FEEDE7A, 0XD2D55329} },
+/**/ {{0XBFC6CC87, 0X37E644BA} },
+/**/ {{0XBFD10BAE, 0X60597557} },
+/**/ {{0X3FC47043, 0X13E26FBE} },
+/**/ {{0X3FBB634A, 0X6FB18BF4} } },
+/**/ {{{0X3FC90004, 0XD3518D76} },
+/**/ {{0X3FC8B073, 0X8874C100} },
+/**/ {{0X3FEED2FB, 0X2ED6673B} },
+/**/ {{0XBFC73251, 0X2A6EBAC3} },
+/**/ {{0XBFD0E28A, 0X6924232F} },
+/**/ {{0X3FC4B3B5, 0X73BCC03F} },
+/**/ {{0X3FBA925E, 0X8C72507F} } },
+/**/ {{{0X3FC97FFF, 0XD2F20D5C} },
+/**/ {{0X3FC92BA3, 0X51AF5920} },
+/**/ {{0X3FEEC749, 0X3D32449F} },
+/**/ {{0XBFC7971F, 0XC308255F} },
+/**/ {{0XBFD0B8E2, 0XD572D28F} },
+/**/ {{0X3FC4F51A, 0X337448FE} },
+/**/ {{0X3FB9C04B, 0XCFCBC620} } },
+/**/ {{{0X3FCA0005, 0XBF80F060} },
+/**/ {{0X3FC9A6AE, 0X6E9E8960} },
+/**/ {{0X3FEEBB64, 0X1EF200E7} },
+/**/ {{0XBFC7FAFB, 0X6E96E5C1} },
+/**/ {{0XBFD08EB6, 0XEC6AD647} },
+/**/ {{0X3FC53475, 0XF53D0BA6} },
+/**/ {{0X3FB8ED36, 0X4433C20E} } },
+/**/ {{{0X3FCA7FF7, 0XDEECA8E4} },
+/**/ {{0X3FCA2176, 0X948578E0} },
+/**/ {{0X3FEEAF4F, 0X328FF98B} },
+/**/ {{0XBFC85DC9, 0X58149B1C} },
+/**/ {{0XBFD06414, 0XF933A1AB} },
+/**/ {{0X3FC571B7, 0X60C45A8F} },
+/**/ {{0X3FB81941, 0XBE58C308} } },
+/**/ {{{0X3FCAFFFF, 0X7DEFD553} },
+/**/ {{0X3FCA9C22, 0X9EBA6B80} },
+/**/ {{0X3FEEA307, 0X10A85E10} },
+/**/ {{0XBFC8BFA6, 0X7F9DEA61} },
+/**/ {{0XBFD038F3, 0X5A474E8F} },
+/**/ {{0X3FC5ACF0, 0X30C225D2} },
+/**/ {{0X3FB74491, 0XD062812F} } },
+/**/ {{{0X3FCB7FFE, 0X669932A5} },
+/**/ {{0X3FCB1694, 0XCFF6DFE0} },
+/**/ {{0X3FEE968F, 0X1921D387} },
+/**/ {{0XBFC92078, 0XE075D95A} },
+/**/ {{0XBFD00D60, 0X526793C4} },
+/**/ {{0X3FC5E610, 0X73842A52} },
+/**/ {{0X3FB66F49, 0XC5331D5A} } },
+/**/ {{{0X3FCBFFF9, 0XB44759F3} },
+/**/ {{0X3FCB90D1, 0X5073A2A0} },
+/**/ {{0X3FEE89E7, 0X56598313} },
+/**/ {{0XBFC98041, 0XCFB9203D} },
+/**/ {{0XBFCFC2BC, 0XBED91B37} },
+/**/ {{0X3FC61D19, 0X6D4FC2FC} },
+/**/ {{0X3FB5998C, 0X9411537E} } },
+/**/ {{{0X3FCC8007, 0X5568F3EC} },
+/**/ {{0X3FCC0AEC, 0X4A31DBE0} },
+/**/ {{0X3FEE7D0E, 0X18F270A8} },
+/**/ {{0XBFC9DF0E, 0XF522B132} },
+/**/ {{0XBFCF69D4, 0X2179C242} },
+/**/ {{0X3FC65213, 0X36646FCD} },
+/**/ {{0X3FB4C37C, 0XDC699095} } },
+/**/ {{{0X3FCCFFF8, 0X601A799F} },
+/**/ {{0X3FCC84B8, 0X49DB66A0} },
+/**/ {{0X3FEE7008, 0XA0EE780E} },
+/**/ {{0XBFCA3CBB, 0X3A403934} },
+/**/ {{0XBFCF102F, 0XD490BE32} },
+/**/ {{0X3FC684EA, 0X037D4137} },
+/**/ {{0X3FB3ED3C, 0XD9EC855A} } },
+/**/ {{{0X3FCD7FF9, 0X7BBF1497} },
+/**/ {{0X3FCCFE5F, 0X1E008CE0} },
+/**/ {{0X3FEE62D2, 0XF04615C7} },
+/**/ {{0XBFCA9965, 0X15AADE2C} },
+/**/ {{0XBFCEB5B9, 0X0B44B682} },
+/**/ {{0X3FC6B5AF, 0X92EC8D57} },
+/**/ {{0X3FB316EE, 0X60D831AE} } },
+/**/ {{{0X3FCE0008, 0X40209B20} },
+/**/ {{0X3FCD77DD, 0XB145A760} },
+/**/ {{0X3FEE556D, 0XBE1DFDF1} },
+/**/ {{0XBFCAF508, 0X2186AF0F} },
+/**/ {{0XBFCE5A79, 0X9420489D} },
+/**/ {{0X3FC6E462, 0X454FEB2C} },
+/**/ {{0X3FB240B2, 0XD2945A8C} } },
+/**/ {{{0X3FCE8000, 0XC0AE943C} },
+/**/ {{0X3FCDF111, 0X3CA10100} },
+/**/ {{0X3FEE47DD, 0X59E7308B} },
+/**/ {{0XBFCB4F88, 0X9439F69F} },
+/**/ {{0XBFCDFE93, 0X798DE600} },
+/**/ {{0X3FC710F5, 0X8F267389} },
+/**/ {{0X3FB16AAB, 0X1A8A373E} } },
+/**/ {{{0X3FCF0003, 0X6D532803} },
+/**/ {{0X3FCE6A17, 0XCB4E5C80} },
+/**/ {{0X3FEE3A1E, 0XE3D0F6C2} },
+/**/ {{0XBFCBA8FB, 0X6E31F768} },
+/**/ {{0XBFCDA1F7, 0XE6A382E3} },
+/**/ {{0X3FC73B75, 0XB36AC4C0} },
+/**/ {{0X3FB094F7, 0XA3470B0A} } },
+/**/ {{{0X3FCF7FFA, 0X48B8AFC3} },
+/**/ {{0X3FCEE2DB, 0XE1654560} },
+/**/ {{0X3FEE2C35, 0X43F2AB37} },
+/**/ {{0XBFCC014F, 0X598207D6} },
+/**/ {{0XBFCD44BF, 0X1EFE809A} },
+/**/ {{0X3FC763DC, 0X698A561E} },
+/**/ {{0X3FAF7F70, 0XA7CF78A3} } },
+/**/ {{{0X3FD00002, 0XEB334FAE} },
+/**/ {{0X3FCF5B7B, 0X77AB25E0} },
+/**/ {{0X3FEE1E1D, 0X78A5C127} },
+/**/ {{0XBFCC5898, 0XC555D571} },
+/**/ {{0XBFCCE6D9, 0XB706CF86} },
+/**/ {{0X3FC78A35, 0X0823F643} },
+/**/ {{0X3FADD619, 0X0B9118E8} } },
+/**/ {{{0X3FD03FFC, 0XA8AF86FE} },
+/**/ {{0X3FCFD3CB, 0XB53A0C00} },
+/**/ {{0X3FEE0FDC, 0XFDCBAC8B} },
+/**/ {{0XBFCCAEB7, 0X6C3246FF} },
+/**/ {{0XBFCC8870, 0XD6E19AD3} },
+/**/ {{0X3FC7AE73, 0XD2C48E91} },
+/**/ {{0X3FAC2E26, 0X0510FDB0} } },
+/**/ {{{0X3FD07FFC, 0XD38984B7} },
+/**/ {{0X3FD025F7, 0X5732D4A0} },
+/**/ {{0X3FEE0170, 0X49C17AB3} },
+/**/ {{0XBFCD03C2, 0X9AFE5028} },
+/**/ {{0XBFCC2971, 0X9A2C1833} },
+/**/ {{0X3FC7D0A5, 0X69041DCF} },
+/**/ {{0X3FAA87D3, 0XF497C653} } },
+/**/ {{{0X3FD0BFFF, 0X1ED2ADD7} },
+/**/ {{0X3FD061ED, 0XCD7F7420} },
+/**/ {{0X3FEDF2D8, 0XDA96B750} },
+/**/ {{0XBFCD57B2, 0XC777881E} },
+/**/ {{0XBFCBC9EA, 0X8692B503} },
+/**/ {{0X3FC7F0C9, 0X42ABF9E7} },
+/**/ {{0X3FA8E35E, 0X04B42BB4} } },
+/**/ {{{0X3FD10003, 0XA8515CDA} },
+/**/ {{0X3FD09DC9, 0X027416A0} },
+/**/ {{0X3FEDE417, 0X34899950} },
+/**/ {{0XBFCDAA86, 0X7983EDE4} },
+/**/ {{0XBFCB69E3, 0X999706B6} },
+/**/ {{0X3FC80EE1, 0XB0F126DB} },
+/**/ {{0X3FA740FE, 0X17EE9BAB} } },
+/**/ {{{0X3FD14001, 0XF3AF9CC5} },
+/**/ {{0X3FD0D980, 0XB6E1ABA0} },
+/**/ {{0X3FEDD52D, 0XE0412681} },
+/**/ {{0XBFCDFC31, 0X6863B28B} },
+/**/ {{0XBFCB0971, 0XC55B8D5A} },
+/**/ {{0X3FC82AED, 0XA6731AAC} },
+/**/ {{0X3FA5A0EC, 0XC73BD8F0} } },
+/**/ {{{0X3FD18003, 0XB6122509} },
+/**/ {{0X3FD1151D, 0XAA1E67A0} },
+/**/ {{0X3FEDC61B, 0X2E0C1F32} },
+/**/ {{0XBFCE4CBE, 0XB9BA6B7E} },
+/**/ {{0XBFCAA88E, 0X90C2431C} },
+/**/ {{0X3FC844F4, 0X8BCBDA5E} },
+/**/ {{0X3FA40361, 0X50E585FF} } },
+/**/ {{{0X3FD1BFFF, 0XA6A2A153} },
+/**/ {{0X3FD15096, 0XE7A18DC0} },
+/**/ {{0X3FEDB6E1, 0XE1218F3F} },
+/**/ {{0XBFCE9C21, 0X9621D6A2} },
+/**/ {{0XBFCA4750, 0X22627B04} },
+/**/ {{0X3FC85CF5, 0XFF8B908E} },
+/**/ {{0X3FA26891, 0X9833C0D6} } },
+/**/ {{{0X3FD1FFFD, 0X2D345AAF} },
+/**/ {{0X3FD18BF3, 0X053BF760} },
+/**/ {{0X3FEDA780, 0XCC3ACB29} },
+/**/ {{0XBFCEEA62, 0X2AA756AE} },
+/**/ {{0XBFC9E5B3, 0X47ED9793} },
+/**/ {{0X3FC872F8, 0X87AB542A} },
+/**/ {{0X3FA0D0B2, 0X158E9E9A} } },
+/**/ {{{0X3FD23FFC, 0XF14CF05A} },
+/**/ {{0X3FD1C732, 0X4D568460} },
+/**/ {{0X3FED97F8, 0X55F32D3D} },
+/**/ {{0XBFCF3780, 0X21D457C8} },
+/**/ {{0XBFC983BE, 0XF065B845} },
+/**/ {{0X3FC886FF, 0XFBA70CD8} },
+/**/ {{0X3F9E77EB, 0XAEB85CCC} } },
+/**/ {{{0X3FD27FFE, 0X0BAE6FC9} },
+/**/ {{0X3FD20253, 0X9A27C160} },
+/**/ {{0X3FED8849, 0X4619176E} },
+/**/ {{0XBFCF8379, 0X5C0AC9EC} },
+/**/ {{0XBFC9217C, 0X5E645195} },
+/**/ {{0X3FC8990F, 0XF4264515} },
+/**/ {{0X3F9B551C, 0XE6B92E65} } },
+/**/ {{{0X3FD2C001, 0XA297A7DE} },
+/**/ {{0X3FD23D57, 0XACB927C0} },
+/**/ {{0X3FED7873, 0XE4958FB6} },
+/**/ {{0XBFCFCE4E, 0X43572249} },
+/**/ {{0XBFC8BEF1, 0X9F3560F3} },
+/**/ {{0X3FC8A92C, 0XDF7F0E5B} },
+/**/ {{0X3F983958, 0X116F3B19} } },
+/**/ {{{0X3FD2FFFE, 0X7267616A} },
+/**/ {{0X3FD27835, 0XB2F378C0} },
+/**/ {{0X3FED687B, 0X13906586} },
+/**/ {{0XBFD00BF9, 0XAFDA1A0F} },
+/**/ {{0XBFC85C34, 0XC197AD7D} },
+/**/ {{0X3FC8B759, 0X1E99F0A7} },
+/**/ {{0X3F9524FA, 0X6525C365} } },
+/**/ {{{0X3FD33FFE, 0X48153B20} },
+/**/ {{0X3FD2B2F6, 0X6A2FDCC0} },
+/**/ {{0X3FED585C, 0XF827FBE4} },
+/**/ {{0XBFD03039, 0XB45A6918} },
+/**/ {{0XBFC7F93E, 0X5DFC3F72} },
+/**/ {{0X3FC8C39B, 0XC5210022} },
+/**/ {{0X3F92185E, 0X168FB62E} } },
+/**/ {{{0X3FD38003, 0X8122579A} },
+/**/ {{0X3FD2ED9B, 0XAF6EC1E0} },
+/**/ {{0X3FED4819, 0X872F20D3} },
+/**/ {{0XBFD053E8, 0X1F4C1031} },
+/**/ {{0XBFC79612, 0X621FFD79} },
+/**/ {{0X3FC8CDF9, 0XDB9D9DFC} },
+/**/ {{0X3F8E27B4, 0X80C6852F} } },
+/**/ {{{0X3FD3C003, 0X3EF39141} },
+/**/ {{0X3FD3281B, 0X4668C700} },
+/**/ {{0X3FED37B4, 0X18590D1A} },
+/**/ {{0XBFD076FE, 0XA3EF2560} },
+/**/ {{0XBFC732C9, 0X3033287A} },
+/**/ {{0X3FC8D676, 0XCA2E5458} },
+/**/ {{0X3F882F85, 0XD80944B1} } },
+/**/ {{{0X3FD40001, 0X63FA0E31} },
+/**/ {{0X3FD36278, 0X7B565000} },
+/**/ {{0X3FED272C, 0X47A813DA} },
+/**/ {{0XBFD0997F, 0X493B9D88} },
+/**/ {{0XBFC6CF64, 0X3DA9FE3C} },
+/**/ {{0X3FC8DD18, 0XC1CD3331} },
+/**/ {{0X3F8248D1, 0XF70F6E07} } },
+/**/ {{{0X3FD44003, 0X74071092} },
+/**/ {{0X3FD39CB8, 0X0F0A4000} },
+/**/ {{0X3FED1681, 0X3BA47A6B} },
+/**/ {{0XBFD0BB6C, 0XD8788947} },
+/**/ {{0XBFC66BE2, 0X589596A6} },
+/**/ {{0X3FC8E1E5, 0XC9B3EC1E} },
+/**/ {{0X3F78E868, 0XD20FAB86} } },
+/**/ {{{0X3FD48000, 0XC880F200} },
+/**/ {{0X3FD3D6D1, 0XDEFFB460} },
+/**/ {{0X3FED05B5, 0XCADC576C} },
+/**/ {{0XBFD0DCC2, 0XA1D352C2} },
+/**/ {{0XBFC60858, 0X3D7D2574} },
+/**/ {{0X3FC8E4E3, 0X03208BC0} },
+/**/ {{0X3F6AC909, 0X6379E732} } },
+/**/ {{{0X3FD4C000, 0X4D97D2CB} },
+/**/ {{0X3FD410CB, 0XF3A2E220} },
+/**/ {{0X3FECF4C8, 0XBB7ED511} },
+/**/ {{0XBFD0FD84, 0X37766A49} },
+/**/ {{0XBFC5A4C2, 0X5AABC13C} },
+/**/ {{0X3FC8E616, 0XC80DAC4B} },
+/**/ {{0X3F4038AA, 0XB04695C2} } },
+/**/ {{{0X3FD4FFFD, 0X9397539F} },
+/**/ {{0X3FD44AA2, 0X06A7DEC0} },
+/**/ {{0X3FECE3BB, 0XCF479DDE} },
+/**/ {{0XBFD11DAF, 0X4D122984} },
+/**/ {{0XBFC5412E, 0XB1024DF0} },
+/**/ {{0X3FC8E587, 0X1B2C560D} },
+/**/ {{0XBF625DA8, 0X951C088D} } },
+/**/ {{{0X3FD53FFF, 0XF304715F} },
+/**/ {{0X3FD4845A, 0X791F3900} },
+/**/ {{0X3FECD28D, 0XA45E0FD8} },
+/**/ {{0XBFD13D47, 0X8D61F221} },
+/**/ {{0XBFC4DD98, 0XD3E9BB99} },
+/**/ {{0X3FC8E33A, 0X0F181507} },
+/**/ {{0XBF743C33, 0XD08BD25C} } },
+/**/ {{{0X3FD58002, 0XE88EA386} },
+/**/ {{0X3FD4BDF0, 0XF575D6C0} },
+/**/ {{0X3FECC140, 0X02035609} },
+/**/ {{0XBFD15C4A, 0XB808071E} },
+/**/ {{0XBFC47A0E, 0XB2945FCF} },
+/**/ {{0X3FC8DF35, 0XFC056447} },
+/**/ {{0XBF7F2011, 0XB00A45CD} } },
+/**/ {{{0X3FD5BFFD, 0X70F4D590} },
+/**/ {{0X3FD4F75D, 0X284D7AE0} },
+/**/ {{0X3FECAFD5, 0XF2DE98B6} },
+/**/ {{0XBFD17AB4, 0XA2B42F42} },
+/**/ {{0XBFC416A5, 0X1C285A92} },
+/**/ {{0X3FC8D982, 0X511D6C5A} },
+/**/ {{0XBF84ECC1, 0X77008605} } },
+/**/ {{{0X3FD5FFFD, 0XB70D6E53} },
+/**/ {{0X3FD530AB, 0X8E2FF500} },
+/**/ {{0X3FEC9E4C, 0X32D2429D} },
+/**/ {{0XBFD1988C, 0X35190681} },
+/**/ {{0XBFC3B34C, 0XBF748319} },
+/**/ {{0X3FC8D224, 0X98D3A613} },
+/**/ {{0XBF8A33D4, 0XAA295F9F} } },
+/**/ {{{0X3FD63FFC, 0X5C7399E2} },
+/**/ {{0X3FD569D5, 0X4F022E80} },
+/**/ {{0X3FEC8CA5, 0X58DD180F} },
+/**/ {{0XBFD1B5CE, 0X1D701DE4} },
+/**/ {{0XBFC35017, 0XA7806A5A} },
+/**/ {{0X3FC8C924, 0X56C01CF9} },
+/**/ {{0XBF8F64D9, 0X942059E1} } },
+/**/ {{{0X3FD67FFD, 0X9A1AC7D2} },
+/**/ {{0X3FD5A2DD, 0XF50031E0} },
+/**/ {{0X3FEC7AE0, 0XCEFF6DEB} },
+/**/ {{0XBFD1D27C, 0X7C8C245B} },
+/**/ {{0XBFC2ED05, 0XC6AA933F} },
+/**/ {{0X3FC8BE87, 0XDDC5CF1F} },
+/**/ {{0XBF923FB6, 0XD594386F} } },
+/**/ {{{0X3FD6BFFD, 0X6F7B9353} },
+/**/ {{0X3FD5DBC1, 0XB4E066C0} },
+/**/ {{0X3FEC6900, 0X456B591A} },
+/**/ {{0XBFD1EE95, 0XC2D6D0AA} },
+/**/ {{0XBFC28A23, 0XB11086F7} },
+/**/ {{0X3FC8B256, 0XDDE22D5A} },
+/**/ {{0XBF94C19A, 0X489D85A4} } },
+/**/ {{{0X3FD6FFFB, 0XF02A83E4} },
+/**/ {{0X3FD61480, 0X6A237DC0} },
+/**/ {{0X3FEC5704, 0X4CC81773} },
+/**/ {{0XBFD20A1A, 0X4B9029CA} },
+/**/ {{0XBFC22777, 0X89F5FB1C} },
+/**/ {{0X3FC8A498, 0X9B09E911} },
+/**/ {{0XBF9737EC, 0X130D419A} } },
+/**/ {{{0X3FD73FFE, 0X128C213A} },
+/**/ {{0X3FD64D1E, 0X42499480} },
+/**/ {{0X3FEC44EC, 0X129C0D30} },
+/**/ {{0XBFD2250C, 0X83787259} },
+/**/ {{0XBFC1C4FF, 0XD55BE4FC} },
+/**/ {{0X3FC89553, 0X36B2D603} },
+/**/ {{0XBF99A284, 0X2E43DF46} } },
+/**/ {{{0X3FD77FFB, 0XEA0CDC7A} },
+/**/ {{0X3FD68594, 0X05B0E220} },
+/**/ {{0X3FEC32BA, 0X687132C0} },
+/**/ {{0XBFD23F69, 0X7273497E} },
+/**/ {{0XBFC162CE, 0XCD39B037} },
+/**/ {{0X3FC8848F, 0XFA930AAF} },
+/**/ {{0XBF9C013D, 0XA4554412} } },
+/**/ {{{0X3FD7C003, 0XF18EDAB8} },
+/**/ {{0X3FD6BDEE, 0X4127BEE0} },
+/**/ {{0X3FEC206B, 0XC01607BD} },
+/**/ {{0XBFD25937, 0X5FEE2F42} },
+/**/ {{0XBFC100D4, 0X307761E1} },
+/**/ {{0X3FC87252, 0X5DFEC556} },
+/**/ {{0XBF9E53F6, 0X7958F973} } },
+/**/ {{{0X3FD7FFFD, 0X41F35C4C} },
+/**/ {{0X3FD6F616, 0XDA6607A0} },
+/**/ {{0X3FEC0E07, 0XCDDC8437} },
+/**/ {{0XBFD2726C, 0XBFB4DAEA} },
+/**/ {{0XBFC09F3B, 0XE0DB1472} },
+/**/ {{0X3FC85EA9, 0X2A95AA1B} },
+/**/ {{0XBFA04D47, 0XD872CFA2} } },
+/**/ {{{0X3FD84003, 0X26C7C46B} },
+/**/ {{0X3FD72E25, 0X96B8BE00} },
+/**/ {{0X3FEBFB87, 0X4CDEDF38} },
+/**/ {{0XBFD28B14, 0XD09404F3} },
+/**/ {{0XBFC03DE1, 0XE7FB61F2} },
+/**/ {{0X3FC84993, 0XACB33BE9} },
+/**/ {{0XBFA16A76, 0X9B1DE607} } },
+/**/ {{{0X3FD88003, 0XCA90B179} },
+/**/ {{0X3FD7660A, 0XA104A220} },
+/**/ {{0X3FEBE8EF, 0XF236E2F6} },
+/**/ {{0XBFD2A329, 0X19A94DDF} },
+/**/ {{0XBFBFB9CE, 0X0856A081} },
+/**/ {{0X3FC8331F, 0X33F70280} },
+/**/ {{0XBFA2817A, 0XF01308CC} } },
+/**/ {{{0X3FD8C003, 0XE9692FD5} },
+/**/ {{0X3FD79DC9, 0XF0B2CB00} },
+/**/ {{0X3FEBD640, 0XF2966495} },
+/**/ {{0XBFD2BAAB, 0XFD6EC2EA} },
+/**/ {{0XBFBEF892, 0XE08E9C2D} },
+/**/ {{0X3FC81B52, 0X031873E3} },
+/**/ {{0XBFA39249, 0XAC12113D} } },
+/**/ {{{0X3FD8FFFE, 0X35BE5C5F} },
+/**/ {{0X3FD7D55E, 0XBDCCDFC0} },
+/**/ {{0X3FEBC37C, 0X6EABCF77} },
+/**/ {{0XBFD2D19C, 0X2D74F445} },
+/**/ {{0XBFBE382C, 0XE63F2CDB} },
+/**/ {{0X3FC80236, 0X0E6FE2AE} },
+/**/ {{0XBFA49CD9, 0X0E66AB41} } },
+/**/ {{{0X3FD94002, 0XAA8974CD} },
+/**/ {{0X3FD80CD6, 0XB8AFD880} },
+/**/ {{0X3FEBB09E, 0X4468CCBA} },
+/**/ {{0XBFD2E7FF, 0XEC84E686} },
+/**/ {{0XBFBD7876, 0X88C659E8} },
+/**/ {{0X3FC7E7CC, 0XC2F15460} },
+/**/ {{0XBFA5A120, 0XB410D3ED} } },
+/**/ {{{0X3FD98002, 0XE08EFDEA} },
+/**/ {{0X3FD84425, 0X34856920} },
+/**/ {{0X3FEB9DAB, 0X3F290478} },
+/**/ {{0XBFD2FDD2, 0XBB81EDEF} },
+/**/ {{0XBFBCB9A5, 0X31E68398} },
+/**/ {{0X3FC7CC23, 0XC2DBB11B} },
+/**/ {{0XBFA69F19, 0X98467E78} } },
+/**/ {{{0X3FD9C002, 0X75294B6B} },
+/**/ {{0X3FD87B4D, 0X299F6200} },
+/**/ {{0X3FEB8AA2, 0XDE96CF1F} },
+/**/ {{0XBFD31316, 0X8C4D45D2} },
+/**/ {{0XBFBBFBB7, 0XEDCE4DBA} },
+/**/ {{0X3FC7AF41, 0X8907FEC9} },
+/**/ {{0XBFA796BE, 0X07419F55} } },
+/**/ {{{0X3FDA0002, 0XF3E490EC} },
+/**/ {{0X3FD8B24F, 0XC21A4500} },
+/**/ {{0X3FEB7785, 0X3B5EF7DD} },
+/**/ {{0XBFD327CC, 0X8EAE70CD} },
+/**/ {{0XBFBB3EB3, 0XD49E40DA} },
+/**/ {{0X3FC7912D, 0X4D93F7EA} },
+/**/ {{0XBFA88809, 0X9E21606A} } },
+/**/ {{{0X3FDA3FFF, 0X458461B6} },
+/**/ {{0X3FD8E928, 0X7754D2C0} },
+/**/ {{0X3FEB6454, 0X6A0DAF0E} },
+/**/ {{0XBFD33BF3, 0XDC2A9A3F} },
+/**/ {{0XBFBA82B1, 0X4917D003} },
+/**/ {{0X3FC771F1, 0X7C7566CF} },
+/**/ {{0XBFA972F9, 0X3D700DD8} } },
+/**/ {{{0X3FDA8002, 0X87E12AAE} },
+/**/ {{0X3FD91FE0, 0XA5DFD000} },
+/**/ {{0X3FEB510D, 0XA0D82E05} },
+/**/ {{0XBFD34F90, 0XA76AD312} },
+/**/ {{0XBFB9C798, 0XDEEC35AD} },
+/**/ {{0X3FC75190, 0X8A0EF43E} },
+/**/ {{0XBFAA578B, 0X0872EFC8} } },
+/**/ {{{0X3FDAC001, 0X49A86C84} },
+/**/ {{0X3FD9566E, 0X5C4516E0} },
+/**/ {{0X3FEB3DB4, 0XDD03F6B6} },
+/**/ {{0XBFD362A0, 0X291C1F82} },
+/**/ {{0XBFB90D95, 0X03F6DF60} },
+/**/ {{0X3FC73018, 0X25091E92} },
+/**/ {{0XBFAB35BE, 0X577A022B} } },
+/**/ {{{0X3FDAFFFF, 0X2F4CC2E1} },
+/**/ {{0X3FD98CD4, 0X94226540} },
+/**/ {{0X3FEB2A49, 0X9297200A} },
+/**/ {{0XBFD37524, 0X5153FD01} },
+/**/ {{0XBFB854A3, 0XAE3DE27E} },
+/**/ {{0X3FC70D8E, 0X7EB3F331} },
+/**/ {{0XBFAC0D93, 0XB6AD570E} } },
+/**/ {{{0X3FDB4000, 0XC2F3711E} },
+/**/ {{0X3FD9C317, 0X01CDC4C0} },
+/**/ {{0X3FEB16CA, 0XEA63781B} },
+/**/ {{0XBFD3871F, 0X3665B649} },
+/**/ {{0XBFB79CC0, 0X3F70FBC6} },
+/**/ {{0X3FC6E9F9, 0X061DFC2E} },
+/**/ {{0XBFACDF0C, 0XD837F9C3} } },
+/**/ {{{0X3FDB8000, 0XA777E180} },
+/**/ {{0X3FD9F930, 0XF3748F20} },
+/**/ {{0X3FEB033B, 0X0FB0162A} },
+/**/ {{0XBFD39890, 0X25978CAB} },
+/**/ {{0XBFB6E602, 0X5C765AAB} },
+/**/ {{0X3FC6C562, 0X9C16D678} },
+/**/ {{0XBFADAA2C, 0X92A16EBF} } },
+/**/ {{{0X3FDBBFFD, 0X087E14ED} },
+/**/ {{0X3FDA2F20, 0XBF0DDB00} },
+/**/ {{0X3FEAEF9B, 0X1CCE6E94} },
+/**/ {{0XBFD3A977, 0X8B73E3C3} },
+/**/ {{0XBFB63077, 0X09EFD1CC} },
+/**/ {{0X3FC69FD4, 0X58408D3A} },
+/**/ {{0XBFAE6EF6, 0XD2E48013} } },
+/**/ {{{0X3FDC0000, 0XF0086783} },
+/**/ {{0X3FDA64EF, 0X8D448080} },
+/**/ {{0X3FEADBE8, 0X35990B5A} },
+/**/ {{0XBFD3B9D9, 0X27241B86} },
+/**/ {{0XBFB57C06, 0XC20E4001} },
+/**/ {{0X3FC6794F, 0X90E6C8AB} },
+/**/ {{0XBFAF2D70, 0X9A630A27} } },
+/**/ {{{0X3FDC4001, 0X863E58F8} },
+/**/ {{0X3FDA9A94, 0X1C3A1BA0} },
+/**/ {{0X3FEAC826, 0X35ED7DD2} },
+/**/ {{0XBFD3C9B3, 0X0C075B50} },
+/**/ {{0XBFB4C8D7, 0XA429793C} },
+/**/ {{0X3FC651E2, 0X95903C22} },
+/**/ {{0XBFAFE59F, 0XF0F8B649} } },
+/**/ {{{0X3FDC7FFC, 0X6C62C3BF} },
+/**/ {{0X3FDAD00C, 0X580A5840} },
+/**/ {{0X3FEAB456, 0X62D1D808} },
+/**/ {{0XBFD3D905, 0XACBB06EC} },
+/**/ {{0XBFB416F7, 0X421E42DC} },
+/**/ {{0X3FC62996, 0XE5608EFD} },
+/**/ {{0XBFB04BC5, 0XF14B649A} } },
+/**/ {{{0X3FDCC002, 0X34B2A209} },
+/**/ {{0X3FDB0565, 0XF68F3B40} },
+/**/ {{0X3FEAA074, 0X1E3DC946} },
+/**/ {{0XBFD3E7D5, 0XE2DB674E} },
+/**/ {{0XBFB3663E, 0XA4833FFE} },
+/**/ {{0X3FC60069, 0XC4F0392B} },
+/**/ {{0XBFB0A19E, 0X38B10201} } },
+/**/ {{{0X3FDCFFFC, 0XAAC5F9F9} },
+/**/ {{0X3FDB3A8E, 0X59C45CC0} },
+/**/ {{0X3FEA8C86, 0XD2389C24} },
+/**/ {{0XBFD3F61F, 0X8362B2CB} },
+/**/ {{0XBFB2B6F1, 0XC6C746A6} },
+/**/ {{0X3FC5D671, 0X426D2946} },
+/**/ {{0XBFB0F45D, 0X4981CE75} } },
+/**/ {{{0X3FDD4004, 0X0D800C64} },
+/**/ {{0X3FDB6F99, 0X88AF6580} },
+/**/ {{0X3FEA7887, 0X7498CED2} },
+/**/ {{0XBFD403E8, 0XEF8975C0} },
+/**/ {{0XBFB208D4, 0XBEA81E2B} },
+/**/ {{0X3FC5ABA5, 0X283FFA4E} },
+/**/ {{0XBFB14408, 0X11705130} } },
+/**/ {{{0X3FDD7FFE, 0XB0E64500} },
+/**/ {{0X3FDBA472, 0X2324E140} },
+/**/ {{0X3FEA647E, 0X8C5AD680} },
+/**/ {{0XBFD4112D, 0XA03F042D} },
+/**/ {{0XBFB15C33, 0X9580389C} },
+/**/ {{0X3FC5801E, 0X49D9889E} },
+/**/ {{0XBFB190A3, 0XEF96554F} } },
+/**/ {{{0X3FDDBFFE, 0X2DFCF4EB} },
+/**/ {{0X3FDBD926, 0X9F1D27A0} },
+/**/ {{0X3FEA5067, 0X1AC286CA} },
+/**/ {{0XBFD41DF2, 0X590A4DE1} },
+/**/ {{0XBFB0B0E4, 0X8BD1EFA5} },
+/**/ {{0X3FC553D8, 0X702506D0} },
+/**/ {{0XBFB1DA36, 0XADA415A6} } },
+/**/ {{{0X3FDDFFFD, 0X8A34BBC2} },
+/**/ {{0X3FDC0DB2, 0XC4F7A2C0} },
+/**/ {{0X3FEA3C43, 0X2EF70BB3} },
+/**/ {{0XBFD42A37, 0X16EE647C} },
+/**/ {{0XBFB006FA, 0XDB6270BB} },
+/**/ {{0X3FC526DE, 0X86F08DE6} },
+/**/ {{0XBFB220C6, 0X7E5061FB} } },
+/**/ {{{0X3FDE3FFD, 0XD26415C0} },
+/**/ {{0X3FDC4217, 0X58282940} },
+/**/ {{0X3FEA2812, 0XF391DDCB} },
+/**/ {{0XBFD435FD, 0X18EDDF0A} },
+/**/ {{0XBFAEBCF2, 0X88A589AF} },
+/**/ {{0X3FC4F937, 0X4CF96163} },
+/**/ {{0XBFB26459, 0XF6A18481} } },
+/**/ {{{0X3FDE7FFF, 0X37F72672} },
+/**/ {{0X3FDC7654, 0X67AA3DC0} },
+/**/ {{0X3FEA13D6, 0XD6CE86B3} },
+/**/ {{0XBFD44145, 0X74037E91} },
+/**/ {{0XBFAD6EC9, 0X3B2CC445} },
+/**/ {{0X3FC4CAEA, 0X0564F101} },
+/**/ {{0XBFB2A4F8, 0X0C49CD64} } },
+/**/ {{{0X3FDEBFFD, 0XA11BC00F} },
+/**/ {{0X3FDCAA66, 0X85E23660} },
+/**/ {{0X3FE9FF90, 0XA25C2396} },
+/**/ {{0XBFD44C10, 0X8A64724F} },
+/**/ {{0XBFAC2399, 0X2F871E82} },
+/**/ {{0X3FC49C01, 0X0AFBFB85} },
+/**/ {{0XBFB2E2A8, 0X0F0FF3FE} } },
+/**/ {{{0X3FDEFFFF, 0X3313756D} },
+/**/ {{0X3FDCDE52, 0X9D30CC20} },
+/**/ {{0X3FE9EB3E, 0XDFF9491F} },
+/**/ {{0XBFD45660, 0X7E6ABAAE} },
+/**/ {{0XBFAADB4C, 0X3E8AA98D} },
+/**/ {{0X3FC46C7F, 0X25D8FF7D} },
+/**/ {{0XBFB31D71, 0XA71D448D} } },
+/**/ {{{0X3FDF4001, 0X914B856E} },
+/**/ {{0X3FDD1216, 0XAAC1BB20} },
+/**/ {{0X3FE9D6E2, 0XC9BC4315} },
+/**/ {{0XBFD46036, 0X004E7E91} },
+/**/ {{0XBFA995F7, 0XFB901F89} },
+/**/ {{0X3FC43C6D, 0X3F5BE04A} },
+/**/ {{0XBFB3555C, 0XCE8ABF92} } },
+/**/ {{{0X3FDF8003, 0XCD144428} },
+/**/ {{0X3FDD45B1, 0XD93E9640} },
+/**/ {{0X3FE9C27D, 0X256FDFEB} },
+/**/ {{0XBFD46992, 0X09F7C145} },
+/**/ {{0XBFA853A9, 0XED521174} },
+/**/ {{0X3FC40BD3, 0X2B27751F} },
+/**/ {{0XBFB38A71, 0XCFA5C5F2} } },
+/**/ {{{0X3FDFC002, 0X00545BD9} },
+/**/ {{0X3FDD7920, 0XF536D960} },
+/**/ {{0X3FE9AE0F, 0XAAE99EA5} },
+/**/ {{0XBFD47275, 0X38DD66F4} },
+/**/ {{0XBFA7147D, 0XB5484F74} },
+/**/ {{0X3FC3DABA, 0XF8EFC373} },
+/**/ {{0XBFB3BCB9, 0X3EA6B864} } },
+/**/ {{{0X3FDFFFFB, 0XDA6F2AA8} },
+/**/ {{0X3FDDAC63, 0XB420FAA0} },
+/**/ {{0X3FE9999A, 0XED4D0CAB} },
+/**/ {{0XBFD47AE0, 0XBFCC6072} },
+/**/ {{0XBFA5D87C, 0X25BF7A4A} },
+/**/ {{0X3FC3A92B, 0XF5999EE5} },
+/**/ {{0XBFB3EC3B, 0XF7F09D08} } },
+/**/ {{{0X3FE01FFF, 0XA65118C8} },
+/**/ {{0X3FDDDF85, 0X2BF70C00} },
+/**/ {{0X3FE9851A, 0XECD72AE5} },
+/**/ {{0XBFD482D7, 0X8F5794C5} },
+/**/ {{0XBFA49F68, 0X2E4A020B} },
+/**/ {{0X3FC37722, 0X25A156DA} },
+/**/ {{0XBFB41903, 0X19F58064} } },
+/**/ {{{0X3FE04001, 0X9C0B0556} },
+/**/ {{0X3FDE127D, 0XFA2BA200} },
+/**/ {{0X3FE97093, 0X08C17A55} },
+/**/ {{0XBFD48A59, 0X957A7EFD} },
+/**/ {{0XBFA36976, 0X2648F2BB} },
+/**/ {{0X3FC344AB, 0X592569B1} },
+/**/ {{0XBFB44318, 0X03752DDB} } },
+/**/ {{{0X3FE05FFF, 0XC24501DB} },
+/**/ {{0X3FDE4547, 0XA495BCC0} },
+/**/ {{0X3FE95C06, 0X4F225B79} },
+/**/ {{0XBFD49167, 0X2163F5B8} },
+/**/ {{0XBFA236D3, 0X4B79B89F} },
+/**/ {{0X3FC311D4, 0XB530B7BE} },
+/**/ {{0XBFB46A84, 0X4D931476} } },
+/**/ {{{0X3FE07FFE, 0X865125FC} },
+/**/ {{0X3FDE77E9, 0X2A5FAD60} },
+/**/ {{0X3FE94772, 0X5C13B0EA} },
+/**/ {{0XBFD49802, 0X6F33ABCA} },
+/**/ {{0XBFA1075A, 0XDE947C6B} },
+/**/ {{0X3FC2DE9D, 0XD8D5E01B} },
+/**/ {{0XBFB48F51, 0XCA17CA60} } },
+/**/ {{{0X3FE0A002, 0X107EAC25} },
+/**/ {{0X3FDEAA69, 0X08243180} },
+/**/ {{0X3FE932D4, 0XF339824B} },
+/**/ {{0XBFD49E2D, 0X7145F475} },
+/**/ {{0XBF9FB5D8, 0X00571424} },
+/**/ {{0X3FC2AB06, 0X85D1CF84} },
+/**/ {{0XBFB4B18A, 0X7DBBBABE} } },
+/**/ {{{0X3FE0BFFF, 0X7376E5D4} },
+/**/ {{0X3FDEDCB5, 0XF79FF560} },
+/**/ {{0X3FE91E35, 0X8EE1B492} },
+/**/ {{0XBFD4A3E7, 0X49498453} },
+/**/ {{0XBF9D63E4, 0XBE685C6F} },
+/**/ {{0X3FC27726, 0XC4B1F032} },
+/**/ {{0XBFB4D138, 0X9E6ECC3A} } },
+/**/ {{{0X3FE0DFFE, 0X1715EE2E} },
+/**/ {{0X3FDF0EDB, 0X9BE1BB80} },
+/**/ {{0X3FE9098F, 0XD993BD60} },
+/**/ {{0XBFD4A932, 0X9B84E907} },
+/**/ {{0XBF9B185A, 0XE07DBA5E} },
+/**/ {{0X3FC242F8, 0XF2D7A804} },
+/**/ {{0XBFB4EE66, 0X8DDAA340} } },
+/**/ {{{0X3FE10001, 0X7F3D776C} },
+/**/ {{0X3FDF40DF, 0X6119E100} },
+/**/ {{0X3FE8F4E1, 0XFB44BCFB} },
+/**/ {{0XBFD4AE11, 0X16E3467E} },
+/**/ {{0XBF98D304, 0XCF368422} },
+/**/ {{0X3FC20E7D, 0X736708AE} },
+/**/ {{0XBFB5091E, 0XD7B3658D} } },
+/**/ {{{0X3FE11FFE, 0XFD8C7B65} },
+/**/ {{0X3FDF72B0, 0X8FD21560} },
+/**/ {{0X3FE8E033, 0X4770FB0A} },
+/**/ {{0XBFD4B282, 0X5C0F6783} },
+/**/ {{0XBF9694AC, 0X7FFE0364} },
+/**/ {{0X3FC1D9CB, 0XE529BF4C} },
+/**/ {{0XBFB5216C, 0X2C73E5F0} } },
+/**/ {{{0X3FE14000, 0XAFA3EE71} },
+/**/ {{0X3FDFA45E, 0XE3324D60} },
+/**/ {{0X3FE8CB7D, 0X9FF684DF} },
+/**/ {{0XBFD4B689, 0X17ADD34D} },
+/**/ {{0XBF945CA3, 0X67276E70} },
+/**/ {{0X3FC1A4D9, 0XA1FBF3B1} },
+/**/ {{0XBFB53759, 0X5FBA2374} } },
+/**/ {{{0X3FE15FFF, 0X73336187} },
+/**/ {{0X3FDFD5DF, 0X3DE48D00} },
+/**/ {{0X3FE8B6C6, 0X0CBE3546} },
+/**/ {{0XBFD4BA25, 0X9B291BCB} },
+/**/ {{0XBF922B6F, 0X5FB712CC} },
+/**/ {{0X3FC16FB8, 0X55E28B0B} },
+/**/ {{0XBFB54AF1, 0X633F423C} } },
+/**/ {{{0X3FE17FFF, 0X6C447B82} },
+/**/ {{0X3FE0039C, 0X0208ECC0} },
+/**/ {{0X3FE8A20A, 0X48F15926} },
+/**/ {{0XBFD4BD59, 0XA5808AC3} },
+/**/ {{0XBF9000CD, 0X5EEF6F2A} },
+/**/ {{0X3FC13A66, 0XEBE54AA7} },
+/**/ {{0XBFB55C3F, 0X45420CE4} } },
+/**/ {{{0X3FE19FFF, 0XAE932B61} },
+/**/ {{0X3FE01C33, 0XE0091BC0} },
+/**/ {{0X3FE88D4B, 0X55664E00} },
+/**/ {{0XBFD4C026, 0X579F5ABB} },
+/**/ {{0XBF8BB9A6, 0X8797C32A} },
+/**/ {{0X3FC104EC, 0X95D4F64E} },
+/**/ {{0XBFB56B4E, 0X2BBC325E} } },
+/**/ {{{0X3FE1BFFF, 0XBA12AE50} },
+/**/ {{0X3FE034B6, 0XD3ABA020} },
+/**/ {{0X3FE87889, 0XEBDCCF04} },
+/**/ {{0XBFD4C28C, 0XE6D463C1} },
+/**/ {{0XBF877F1C, 0XB36211FC} },
+/**/ {{0X3FC0CF4F, 0XB90B11E7} },
+/**/ {{0XBFB57829, 0X52DCBE1A} } },
+/**/ {{{0X3FE1E001, 0X4B459E41} },
+/**/ {{0X3FE04D26, 0X2DC05800} },
+/**/ {{0X3FE863C5, 0X51625B6A} },
+/**/ {{0XBFD4C48E, 0XAFFDD399} },
+/**/ {{0XBF8351CB, 0X603059CA} },
+/**/ {{0X3FC09992, 0XDE65D0D9} },
+/**/ {{0XBFB582DC, 0X087BB367} } },
+/**/ {{{0X3FE20000, 0X32306F33} },
+/**/ {{0X3FE0657E, 0XBAFB6CE0} },
+/**/ {{0X3FE84F00, 0XA1E2EEC3} },
+/**/ {{0XBFD4C62C, 0XB79EC8C6} },
+/**/ {{0XBF7E6488, 0XD95DE8D1} },
+/**/ {{0X3FC063C2, 0X661DF241} },
+/**/ {{0XBFB58B71, 0XAAA63BAD} } },
+/**/ {{{0X3FE22000, 0XD30A486C} },
+/**/ {{0X3FE07DC3, 0XD2165080} },
+/**/ {{0X3FE83A39, 0X66B3E5BF} },
+/**/ {{0XBFD4C768, 0X7DE04DEE} },
+/**/ {{0XBF763FF7, 0X800F052F} },
+/**/ {{0X3FC02DDC, 0X28F35EDD} },
+/**/ {{0XBFB591F5, 0XA351CF91} } },
+/**/ {{{0X3FE23FFE, 0X215E03FC} },
+/**/ {{0X3FE095F1, 0X9F380A00} },
+/**/ {{0X3FE82573, 0X48BE5F3F} },
+/**/ {{0XBFD4C843, 0X1B793F77} },
+/**/ {{0XBF6C6E63, 0X625993B8} },
+/**/ {{0X3FBFEFDB, 0X8C5E4B3B} },
+/**/ {{0XBFB59673, 0X66FE9CA7} } },
+/**/ {{{0X3FE26000, 0X6833D65D} },
+/**/ {{0X3FE0AE0E, 0X6496A8C0} },
+/**/ {{0X3FE810A9, 0X45B44AA3} },
+/**/ {{0XBFD4C8BE, 0X055B407A} },
+/**/ {{0XBF5920A7, 0XAE83F0A4} },
+/**/ {{0X3FBF83DC, 0X860A6A5E} },
+/**/ {{0XBFB598F6, 0X70D98EE7} } },
+/**/ {{{0X3FE28000, 0XE82D4D50} },
+/**/ {{0X3FE0C615, 0X095F5300} },
+/**/ {{0X3FE7FBE0, 0X1E9337B7} },
+/**/ {{0XBFD4C8DA, 0X573C6F6A} },
+/**/ {{0X3F38B6C7, 0XC50F565D} },
+/**/ {{0X3FBF17DB, 0XC9C4B6CA} },
+/**/ {{0XBFB5998A, 0X45D6DAE0} } },
+/**/ {{{0X3FE29FFF, 0X203B6A0B} },
+/**/ {{0X3FE0DE05, 0X30852720} },
+/**/ {{0X3FE7E718, 0X8520538D} },
+/**/ {{0XBFD4C899, 0X668C6963} },
+/**/ {{0X3F6286EC, 0XBECA8AB0} },
+/**/ {{0X3FBEABE4, 0X9B6AC5BD} },
+/**/ {{0XBFB5983A, 0X575A9684} } },
+/**/ {{{0X3FE2C001, 0XE91A9D93} },
+/**/ {{0X3FE0F5E3, 0XF7817A20} },
+/**/ {{0X3FE7D24E, 0X63A45D97} },
+/**/ {{0XBFD4C7FC, 0X5F83C46D} },
+/**/ {{0X3F70E199, 0X5D9C800A} },
+/**/ {{0X3FBE3FE9, 0X3721A8E0} },
+/**/ {{0XBFB59512, 0X377DA840} } },
+/**/ {{{0X3FE2DFFF, 0XC6FB4948} },
+/**/ {{0X3FE10DAA, 0X4CE36040} },
+/**/ {{0X3FE7BD88, 0X3E39011F} },
+/**/ {{0XBFD4C704, 0XB5EAE11F} },
+/**/ {{0X3F786398, 0X192C622B} },
+/**/ {{0X3FBDD412, 0XB62BA357} },
+/**/ {{0XBFB5901D, 0X5F0E020E} } },
+/**/ {{{0X3FE2FFFF, 0X39CB4EED} },
+/**/ {{0X3FE1255D, 0X0970AD60} },
+/**/ {{0X3FE7A8C2, 0X365B7A9B} },
+/**/ {{0XBFD4C5B3, 0X8925F532} },
+/**/ {{0X3F7FCB03, 0X785E3070} },
+/**/ {{0X3FBD6854, 0X0EEDF3B3} },
+/**/ {{0XBFB58967, 0X479C252A} } },
+/**/ {{{0X3FE31FFE, 0X002E31CB} },
+/**/ {{0X3FE13CFA, 0X81FD3780} },
+/**/ {{0X3FE793FE, 0X1BBE9667} },
+/**/ {{0XBFD4C40A, 0X3046F4C7} },
+/**/ {{0X3F838BAE, 0X8F5E6BF1} },
+/**/ {{0X3FBCFCBD, 0X83775C98} },
+/**/ {{0XBFB580FB, 0X62E887AB} } },
+/**/ {{{0X3FE34000, 0XEDC7BFFD} },
+/**/ {{0X3FE15486, 0X44D05200} },
+/**/ {{0X3FE77F39, 0X244A1DA5} },
+/**/ {{0XBFD4C209, 0X9FB764C1} },
+/**/ {{0X3F8724E2, 0X851B0BE5} },
+/**/ {{0X3FBC9147, 0X507C76E0} },
+/**/ {{0XBFB576E5, 0X19C7F0AB} } },
+/**/ {{{0X3FE36001, 0XCE042830} },
+/**/ {{0X3FE16BFB, 0XC1656AE0} },
+/**/ {{0X3FE76A77, 0XAD3B2B77} },
+/**/ {{0XBFD4BFB3, 0X74AAC296} },
+/**/ {{0X3F8AB070, 0X05B229C2} },
+/**/ {{0X3FBC260E, 0X87DCA54B} },
+/**/ {{0XBFB56B2F, 0XC90DF763} } },
+/**/ {{{0X3FE37FFE, 0X89B8FC54} },
+/**/ {{0X3FE18359, 0X77D0BA80} },
+/**/ {{0X3FE755BB, 0X660CAA3D} },
+/**/ {{0XBFD4BD09, 0X308BB975} },
+/**/ {{0X3F8E2E26, 0XFE0A1240} },
+/**/ {{0X3FBBBB22, 0X18790F26} },
+/**/ {{0XBFB55DE6, 0XC094F3DA} } },
+/**/ {{{0X3FE3A001, 0X9B4DA842} },
+/**/ {{0X3FE19AA7, 0X100CD140} },
+/**/ {{0X3FE740FD, 0XD801F889} },
+/**/ {{0XBFD4BA0B, 0X2C32C656} },
+/**/ {{0X3F90CF99, 0X8ECA44A2} },
+/**/ {{0X3FBB5066, 0XC9863443} },
+/**/ {{0XBFB54F15, 0X406672B5} } },
+/**/ {{{0X3FE3C000, 0XCE6B63E8} },
+/**/ {{0X3FE1B1DD, 0X1D0B0AE0} },
+/**/ {{0X3FE72C45, 0XF28670E6} },
+/**/ {{0XBFD4B6BB, 0X92422E2E} },
+/**/ {{0X3F928141, 0XA0D32146} },
+/**/ {{0X3FBAE606, 0X37452321} },
+/**/ {{0XBFB53EC6, 0X77D91F56} } },
+/**/ {{{0X3FE3DFFF, 0X114A2607} },
+/**/ {{0X3FE1C8FD, 0XC6FF6F20} },
+/**/ {{0X3FE71792, 0X206847A7} },
+/**/ {{0XBFD4B31B, 0X669BD306} },
+/**/ {{0X3F942C3A, 0X04FFD28A} },
+/**/ {{0X3FBA7BFD, 0XE7FC0825} },
+/**/ {{0XBFB52D05, 0X82F471BA} } },
+/**/ {{{0X3FE3FFFF, 0XC1DA9B7D} },
+/**/ {{0X3FE1E00B, 0X7F2E8840} },
+/**/ {{0X3FE702E0, 0X84371133} },
+/**/ {{0XBFD4AF2B, 0X8012FBE4} },
+/**/ {{0X3F95D0B4, 0XBFC47F4B} },
+/**/ {{0X3FBA1249, 0XD80AB6C5} },
+/**/ {{0XBFB519DD, 0X69A4108D} } },
+/**/ {{{0X3FE41FFE, 0XE11D9C33} },
+/**/ {{0X3FE1F703, 0X67C3EC20} },
+/**/ {{0X3FE6EE34, 0X026A76A0} },
+/**/ {{0XBFD4AAED, 0X96514B12} },
+/**/ {{0X3F976E83, 0X07BA2905} },
+/**/ {{0X3FB9A8FE, 0X261A1221} },
+/**/ {{0XBFB50559, 0X1D552BA0} } },
+/**/ {{{0X3FE43FFF, 0XFA174676} },
+/**/ {{0X3FE20DE8, 0X0FAFF860} },
+/**/ {{0X3FE6D98A, 0X9EA6D162} },
+/**/ {{0XBFD4A662, 0X6B927B3B} },
+/**/ {{0X3F9905D8, 0XF84ADBB0} },
+/**/ {{0X3FB94015, 0XDD484DB5} },
+/**/ {{0XBFB4EF83, 0X783EEF44} } },
+/**/ {{{0X3FE45FFF, 0X0D457FA4} },
+/**/ {{0X3FE224B6, 0X9F675300} },
+/**/ {{0X3FE6C4E7, 0X3A093351} },
+/**/ {{0XBFD4A18B, 0XCBF2BFF8} },
+/**/ {{0X3F9A968A, 0X84BB8C16} },
+/**/ {{0X3FB8D7A4, 0X93FBB975} },
+/**/ {{0XBFB4D867, 0X3B37E4FB} } },
+/**/ {{{0X3FE47FFE, 0X8F910E57} },
+/**/ {{0X3FE23B70, 0XDD92B840} },
+/**/ {{0X3FE6B048, 0X89B04359} },
+/**/ {{0XBFD49C6A, 0X974B07FF} },
+/**/ {{0X3F9C20BE, 0X25F20251} },
+/**/ {{0X3FB86FA8, 0X82E9673D} },
+/**/ {{0XBFB4C00F, 0X0D12F550} } },
+/**/ {{{0X3FE4A001, 0X7323FC6B} },
+/**/ {{0X3FE25218, 0XE34E3420} },
+/**/ {{0X3FE69BAC, 0XF277FE27} },
+/**/ {{0XBFD496FF, 0X7F856ABA} },
+/**/ {{0X3F9DA49E, 0X9928150C} },
+/**/ {{0X3FB8081E, 0X3EB66A26} },
+/**/ {{0XBFB4A685, 0X78AB06C5} } },
+/**/ {{{0X3FE4C000, 0XB1BF0500} },
+/**/ {{0X3FE268A9, 0XBD8B2C80} },
+/**/ {{0X3FE68719, 0X42ABBD42} },
+/**/ {{0XBFD4914C, 0XEC74E64A} },
+/**/ {{0X3F9F21DE, 0XD0C3EEEC} },
+/**/ {{0X3FB7A122, 0X5B30AA05} },
+/**/ {{0XBFB48BD4, 0XEC53EF43} } },
+/**/ {{{0X3FE4E001, 0X1D07207B} },
+/**/ {{0X3FE27F26, 0XDA64F7A0} },
+/**/ {{0X3FE6728A, 0XA7CFBEB2} },
+/**/ {{0XBFD48B53, 0X3FCBB247} },
+/**/ {{0X3FA04C60, 0XA7354A41} },
+/**/ {{0X3FB73AAA, 0XEFF6F27A} },
+/**/ {{0XBFB47007, 0XB81A6BB2} } },
+/**/ {{{0X3FE4FFFE, 0X5F36EB46} },
+/**/ {{0X3FE2958D, 0X35DDD180} },
+/**/ {{0X3FE65E04, 0X307B6AF3} },
+/**/ {{0XBFD48514, 0X828BB6E6} },
+/**/ {{0X3FA1048E, 0X48993ED9} },
+/**/ {{0X3FB6D4CB, 0X468D7C59} },
+/**/ {{0XBFB45328, 0X0D484989} } },
+/**/ {{{0X3FE52001, 0X2AFDF759} },
+/**/ {{0X3FE2ABE2, 0XEB1C3280} },
+/**/ {{0X3FE64980, 0X8DC5DAAD} },
+/**/ {{0XBFD47E90, 0X2C11E3B7} },
+/**/ {{0X3FA1B9AE, 0X88E1B343} },
+/**/ {{0X3FB66F6C, 0XFF4501BF} },
+/**/ {{0XBFB4353F, 0XFCD6B8DE} } },
+/**/ {{{0X3FE54001, 0XDFDB2423} },
+/**/ {{0X3FE2C222, 0XAB0402C0} },
+/**/ {{0X3FE63504, 0XE7E657FB} },
+/**/ {{0XBFD477C8, 0XEEE53FA9} },
+/**/ {{0X3FA26B9A, 0X696CD845} },
+/**/ {{0X3FB60AAD, 0X6A3AA6EF} },
+/**/ {{0XBFB41659, 0X7704E1F4} } },
+/**/ {{{0X3FE55FFE, 0X72D2A74F} },
+/**/ {{0X3FE2D84B, 0X16BE7240} },
+/**/ {{0X3FE62092, 0XCE54AEDE} },
+/**/ {{0XBFD470C0, 0X7B764156} },
+/**/ {{0X3FA31A4C, 0X4D9ABEE7} },
+/**/ {{0X3FB5A697, 0XA899A63D} },
+/**/ {{0XBFB3F67E, 0X49FA7FB1} } },
+/**/ {{{0X3FE58000, 0XEE716C33} },
+/**/ {{0X3FE2EE63, 0X284F3FE0} },
+/**/ {{0X3FE60C24, 0X181C5720} },
+/**/ {{0XBFD46975, 0XC383B0C1} },
+/**/ {{0X3FA3C5FF, 0XC40A1A5A} },
+/**/ {{0X3FB54311, 0X0B7B3B72} },
+/**/ {{0XBFB3D5B8, 0X21700401} } },
+/**/ {{{0X3FE59FFF, 0X9825CD2A} },
+/**/ {{0X3FE30464, 0X2DEFCF40} },
+/**/ {{0X3FE5F7BF, 0X3C14A317} },
+/**/ {{0XBFD461EC, 0X227A4CDE} },
+/**/ {{0X3FA46E85, 0X6DA8D837} },
+/**/ {{0X3FB4E03C, 0X6162F4C8} },
+/**/ {{0XBFB3B410, 0X857F5976} } },
+/**/ {{{0X3FE5BFFD, 0XFE2A42CD} },
+/**/ {{0X3FE31A50, 0XA5110DC0} },
+/**/ {{0X3FE5E362, 0X33CF1268} },
+/**/ {{0XBFD45A23, 0XF68B7DBC} },
+/**/ {{0X3FA513F5, 0XDE40F0E9} },
+/**/ {{0X3FB47E12, 0XDE05901E} },
+/**/ {{0XBFB39190, 0XDA5CABB5} } },
+/**/ {{{0X3FE5E000, 0X57330799} },
+/**/ {{0X3FE3302B, 0X75253480} },
+/**/ {{0X3FE5CF0A, 0X901DA45A} },
+/**/ {{0XBFD4521D, 0X552754CF} },
+/**/ {{0X3FA5B66B, 0XBBF000BB} },
+/**/ {{0X3FB41C8B, 0XD2BAF7B2} },
+/**/ {{0XBFB36E42, 0X5F53241A} } },
+/**/ {{{0X3FE60001, 0X4D6055DA} },
+/**/ {{0X3FE345F0, 0XFF2EDA60} },
+/**/ {{0X3FE5BABB, 0XF2EA5900} },
+/**/ {{0XBFD449DA, 0XB2008754} },
+/**/ {{0X3FA655D1, 0X18F56FBB} },
+/**/ {{0X3FB3BBBB, 0X89A0C1B2} },
+/**/ {{0XBFB34A2E, 0X2E8D60FC} } },
+/**/ {{{0X3FE62001, 0X2C3809CB} },
+/**/ {{0X3FE35BA1, 0X812D5040} },
+/**/ {{0X3FE5A676, 0X671E49E9} },
+/**/ {{0XBFD4415D, 0X230E6216} },
+/**/ {{0X3FA6F22D, 0X6B05C7F7} },
+/**/ {{0X3FB35BA4, 0XCFE6B72B} },
+/**/ {{0XBFB3255D, 0X3C3BFA3B} } },
+/**/ {{{0X3FE64000, 0X87B47ECC} },
+/**/ {{0X3FE3713D, 0X69715580} },
+/**/ {{0X3FE59239, 0XC8FB0E69} },
+/**/ {{0XBFD438A5, 0XA5BD1F6E} },
+/**/ {{0X3FA78B89, 0X7F9B13CF} },
+/**/ {{0X3FB2FC49, 0X74F57C8F} },
+/**/ {{0XBFB2FFD8, 0X566CAACA} } },
+/**/ {{{0X3FE66000, 0XA746397F} },
+/**/ {{0X3FE386C5, 0X9D968940} },
+/**/ {{0X3FE57E05, 0X83073C58} },
+/**/ {{0XBFD42FB4, 0XFE3D0083} },
+/**/ {{0X3FA821F1, 0X4B9E1EEB} },
+/**/ {{0X3FB29DA9, 0X1952EE82} },
+/**/ {{0XBFB2D9A8, 0X245866A8} } },
+/**/ {{{0X3FE68000, 0XE4E3094B} },
+/**/ {{0X3FE39C39, 0XB5FE3900} },
+/**/ {{0X3FE569DA, 0X36DD131E} },
+/**/ {{0XBFD4268C, 0X74778FE0} },
+/**/ {{0X3FA8B567, 0X9AB0310F} },
+/**/ {{0X3FB23FC8, 0XF2E43205} },
+/**/ {{0XBFB2B2D5, 0X26483573} } },
+/**/ {{{0X3FE6A001, 0XE2E37787} },
+/**/ {{0X3FE3B19A, 0X27D52620} },
+/**/ {{0X3FE555B7, 0XB5D865CD} },
+/**/ {{0XBFD41D2C, 0XF1600CD3} },
+/**/ {{0X3FA945F5, 0X4B79E859} },
+/**/ {{0X3FB1E2AA, 0X46A0B02D} },
+/**/ {{0XBFB28B67, 0XB508A35B} } },
+/**/ {{{0X3FE6BFFE, 0X0DF4BBFB} },
+/**/ {{0X3FE3C6E3, 0X46F2B6E0} },
+/**/ {{0X3FE541A1, 0XB658AFBE} },
+/**/ {{0XBFD41399, 0X388DA137} },
+/**/ {{0X3FA9D387, 0XE5B3C2BA} },
+/**/ {{0X3FB18660, 0X173397F9} },
+/**/ {{0XBFB26368, 0X01DB4945} } },
+/**/ {{{0X3FE6DFFF, 0XEA406CEA} },
+/**/ {{0X3FE3DC1C, 0X1BB3D400} },
+/**/ {{0X3FE52D91, 0XD33FFE8E} },
+/**/ {{0XBFD409CF, 0X36BCFFE9} },
+/**/ {{0X3FAA5E54, 0X174405AF} },
+/**/ {{0X3FB12ACE, 0XDC041806} },
+/**/ {{0XBFB23ADE, 0X160D6557} } },
+/**/ {{{0X3FE70000, 0XED01EA65} },
+/**/ {{0X3FE3F140, 0X54E51400} },
+/**/ {{0X3FE5198C, 0X5C8B9119} },
+/**/ {{0XBFD3FFD1, 0XF2EA4FF7} },
+/**/ {{0X3FAAE643, 0X308C81CD} },
+/**/ {{0X3FB0D00C, 0X1960AAF7} },
+/**/ {{0XBFB211D1, 0XD2F50D25} } },
+/**/ {{{0X3FE72002, 0X00D515EB} },
+/**/ {{0X3FE40650, 0X983BB3E0} },
+/**/ {{0X3FE50590, 0XF2175C71} },
+/**/ {{0XBFD3F5A2, 0X361BB15C} },
+/**/ {{0X3FAB6B5F, 0X9B536AFC} },
+/**/ {{0X3FB07617, 0XA731624D} },
+/**/ {{0XBFB1E84A, 0XF1A8C054} } },
+/**/ {{{0X3FE74001, 0X1323DE6D} },
+/**/ {{0X3FE41B4B, 0X9483E720} },
+/**/ {{0X3FE4F1A1, 0X1027BA01} },
+/**/ {{0XBFD3EB41, 0XBB978C8F} },
+/**/ {{0X3FABEDA7, 0X7765626A} },
+/**/ {{0X3FB01CF9, 0X97F58C8A} },
+/**/ {{0XBFB1BE51, 0X03074348} } },
+/**/ {{{0X3FE75FFF, 0X25CAB4CA} },
+/**/ {{0X3FE43032, 0X0001D5C0} },
+/**/ {{0X3FE4DDBC, 0X4573FB6C} },
+/**/ {{0XBFD3E0B1, 0X41F21D2A} },
+/**/ {{0X3FAC6D25, 0XD1BDA00F} },
+/**/ {{0X3FAF8962, 0X5935EE68} },
+/**/ {{0XBFB193EB, 0X6F8E0689} } },
+/**/ {{{0X3FE77FFE, 0X90921F76} },
+/**/ {{0X3FE44505, 0X6CC6AF00} },
+/**/ {{0X3FE4C9E1, 0X4CFFBDAE} },
+/**/ {{0XBFD3D5F1, 0X0B247EC4} },
+/**/ {{0X3FACE9EA, 0X943F4516} },
+/**/ {{0X3FAEDA73, 0XF24A8AF1} },
+/**/ {{0XBFB16921, 0X776AAC42} } },
+/**/ {{{0X3FE79FFE, 0X47B2F83B} },
+/**/ {{0X3FE459C5, 0X35C19F20} },
+/**/ {{0X3FE4B610, 0XFC8F20BD} },
+/**/ {{0XBFD3CB02, 0X73DF2A0D} },
+/**/ {{0X3FAD63F8, 0X23C5D6DE} },
+/**/ {{0X3FAE2D31, 0X9C5116AB} },
+/**/ {{0XBFB13DFA, 0X326E2972} } },
+/**/ {{{0X3FE7BFFF, 0X2F1E79A9} },
+/**/ {{0X3FE46E71, 0XF84DF5C0} },
+/**/ {{0X3FE4A24A, 0XF586B1BD} },
+/**/ {{0XBFD3BFE6, 0X2EF81E5B} },
+/**/ {{0X3FADDB58, 0X738896F0} },
+/**/ {{0X3FAD819A, 0X2515DE78} },
+/**/ {{0XBFB1127C, 0X9026FDD0} } },
+/**/ {{{0X3FE7E001, 0X973C8D05} },
+/**/ {{0X3FE4830B, 0XF0FB9580} },
+/**/ {{0X3FE48E8F, 0X3466B08E} },
+/**/ {{0XBFD3B49D, 0X1C53A01A} },
+/**/ {{0X3FAE5013, 0X25103EED} },
+/**/ {{0X3FACD7AF, 0X5290F4AF} },
+/**/ {{0XBFB0E6AF, 0X57EF003B} } },
+/**/ {{{0X3FE7FFFF, 0X69EFC092} },
+/**/ {{0X3FE4978F, 0X431C3800} },
+/**/ {{0X3FE47AE1, 0XA3E1064A} },
+/**/ {{0XBFD3A92A, 0X666C50C4} },
+/**/ {{0X3FAEC219, 0X4098A4BE} },
+/**/ {{0X3FAC2F94, 0X2EEE57E0} },
+/**/ {{0XBFB0BA99, 0X290D5730} } },
+/**/ {{{0X3FE82001, 0XC52B5232} },
+/**/ {{0X3FE4AC01, 0XD2B83340} },
+/**/ {{0X3FE4673C, 0XD31B7CF5} },
+/**/ {{0XBFD39D8B, 0XC67D05F0} },
+/**/ {{0X3FAF3192, 0X2A81B5D5} },
+/**/ {{0X3FAB891B, 0X8AA20E90} },
+/**/ {{0XBFB08E40, 0X7ADCEFD6} } },
+/**/ {{{0X3FE84000, 0XBD4D4E3F} },
+/**/ {{0X3FE4C05E, 0X9B1DBC60} },
+/**/ {{0X3FE453A5, 0XC8D629F7} },
+/**/ {{0XBFD391C5, 0X13E9EF47} },
+/**/ {{0X3FAF9E69, 0X17383D6B} },
+/**/ {{0X3FAAE471, 0X278E21B9} },
+/**/ {{0XBFB061AB, 0X9CF54D10} } },
+/**/ {{{0X3FE86001, 0X8C869CBD} },
+/**/ {{0X3FE4D4A8, 0XFD2285A0} },
+/**/ {{0X3FE44019, 0X79B82471} },
+/**/ {{0XBFD385D5, 0X5C3E2929} },
+/**/ {{0X3FB0045B, 0X7B2C8FF2} },
+/**/ {{0X3FAA417C, 0X39D7CA4F} },
+/**/ {{0XBFB034E0, 0XB767B7D4} } },
+/**/ {{{0X3FE87FFE, 0XB5DB3710} },
+/**/ {{0X3FE4E8DD, 0X8B93BCA0} },
+/**/ {{0X3FE42C9B, 0X66C6E6BF} },
+/**/ {{0XBFD379BF, 0XA32EE2A1} },
+/**/ {{0X3FB03838, 0X6187FE0F} },
+/**/ {{0X3FA9A05A, 0X8B3A0B33} },
+/**/ {{0XBFB007E5, 0XCAEE03A9} } },
+/**/ {{{0X3FE8A000, 0X863C77E3} },
+/**/ {{0X3FE4FD01, 0X8FCD1E80} },
+/**/ {{0X3FE41926, 0XA8A8093F} },
+/**/ {{0XBFD36D81, 0XB5EE344D} },
+/**/ {{0X3FB06ADC, 0X2841F292} },
+/**/ {{0X3FA900E4, 0X2484560B} },
+/**/ {{0XBFAFB581, 0X62792F0A} } },
+/**/ {{{0X3FE8BFFF, 0X0ED982AF} },
+/**/ {{0X3FE51110, 0X16E28AC0} },
+/**/ {{0X3FE405C0, 0X389112EE} },
+/**/ {{0XBFD3611F, 0X89D38DC7} },
+/**/ {{0X3FB09C3D, 0XB450B9F7} },
+/**/ {{0X3FA86342, 0X312D0C4A} },
+/**/ {{0XBFAF5AEE, 0X3A6CA012} } },
+/**/ {{{0X3FE8E000, 0X02C3AEAE} },
+/**/ {{0X3FE5250C, 0XC0AB0A40} },
+/**/ {{0X3FE3F264, 0XC65593C5} },
+/**/ {{0XBFD35497, 0XD82BE900} },
+/**/ {{0X3FB0CC69, 0X68546D39} },
+/**/ {{0X3FA7C759, 0XDB8499FD} },
+/**/ {{0XBFAF001D, 0X36A32337} } },
+/**/ {{{0X3FE90000, 0XECBFA97B} },
+/**/ {{0X3FE538F6, 0X0E8D4EE0} },
+/**/ {{0X3FE3DF15, 0XF4119333} },
+/**/ {{0XBFD347EC, 0X7D2149F4} },
+/**/ {{0X3FB0FB5E, 0XFA921D3C} },
+/**/ {{0X3FA72D38, 0X69693E89} },
+/**/ {{0XBFAEA519, 0X23A0F5F3} } },
+/**/ {{{0X3FE91FFF, 0XD251C01C} },
+/**/ {{0X3FE54CCA, 0XD3F3BD20} },
+/**/ {{0X3FE3CBD5, 0X1554DD15} },
+/**/ {{0XBFD33B1F, 0X2BC94245} },
+/**/ {{0X3FB1291F, 0X2FC4C3F6} },
+/**/ {{0X3FA694E8, 0X1B7A765C} },
+/**/ {{0XBFAE49EC, 0X826E86F6} } },
+/**/ {{{0X3FE94001, 0XD90AF4E6} },
+/**/ {{0X3FE5608E, 0X4D4EC640} },
+/**/ {{0X3FE3B89F, 0X3445EF72} },
+/**/ {{0XBFD32E2E, 0XB7BBD79A} },
+/**/ {{0X3FB155B4, 0XE401D071} },
+/**/ {{0X3FA5FE51, 0X3A256F1C} },
+/**/ {{0XBFADEEA1, 0X890FF662} } },
+/**/ {{{0X3FE96001, 0X04FD6C17} },
+/**/ {{0X3FE5743C, 0XD5673C20} },
+/**/ {{0X3FE3A578, 0X09EBC6E2} },
+/**/ {{0XBFD3211E, 0X6DA5039C} },
+/**/ {{0X3FB1811B, 0X4E62286B} },
+/**/ {{0X3FA56990, 0X71BECE9D} },
+/**/ {{0XBFAD9342, 0X23911641} } },
+/**/ {{{0X3FE98000, 0X2D214B82} },
+/**/ {{0X3FE587D8, 0X3B0D6120} },
+/**/ {{0X3FE3925E, 0X01EAAC3E} },
+/**/ {{0XBFD313EE, 0X08425504} },
+/**/ {{0X3FB1AB5A, 0X02BDB571} },
+/**/ {{0X3FA4D698, 0X9EBD70B8} },
+/**/ {{0XBFAD37D7, 0XF482965A} } },
+/**/ {{{0X3FE99FFD, 0XEB980651} },
+/**/ {{0X3FE59B5F, 0XB16BA7A0} },
+/**/ {{0X3FE37F52, 0X10B1AB7A} },
+/**/ {{0XBFD3069E, 0XF993D676} },
+/**/ {{0X3FB1D472, 0XCDED25A8} },
+/**/ {{0X3FA44570, 0X2D0ABD9A} },
+/**/ {{0XBFACDC6C, 0X56221AA1} } },
+/**/ {{{0X3FE9BFFF, 0XE5504053} },
+/**/ {{0X3FE5AED6, 0XB55DE6A0} },
+/**/ {{0X3FE36C50, 0XFA91C51E} },
+/**/ {{0XBFD2F92F, 0XBE311E56} },
+/**/ {{0X3FB1FC70, 0X5BE3AF05} },
+/**/ {{0X3FA3B5FD, 0XACD5CDC7} },
+/**/ {{0XBFAC8108, 0X5ADBB9B8} } },
+/**/ {{{0X3FE9E001, 0X6E60A234} },
+/**/ {{0X3FE5C23A, 0X79ACD480} },
+/**/ {{0X3FE3595D, 0XA5FAB2EA} },
+/**/ {{0XBFD2EBA3, 0X1DDECEEA} },
+/**/ {{0X3FB22350, 0X35736518} },
+/**/ {{0X3FA32856, 0X22F9FD28} },
+/**/ {{0XBFAC25B4, 0XCE8B2259} } },
+/**/ {{{0X3FE9FFFF, 0XB685741B} },
+/**/ {{0X3FE5D589, 0X5AD40460} },
+/**/ {{0X3FE34679, 0XD832B8D3} },
+/**/ {{0XBFD2DDFB, 0X230EDA41} },
+/**/ {{0X3FB24912, 0XB23C0BA2} },
+/**/ {{0X3FA29C85, 0X4C4E86DA} },
+/**/ {{0XBFABCA7A, 0X37002A55} } },
+/**/ {{{0X3FEA2001, 0X9D59B943} },
+/**/ {{0X3FE5E8C7, 0X8C187EA0} },
+/**/ {{0X3FE333A1, 0X9EDE2183} },
+/**/ {{0XBFD2D035, 0XB0043779} },
+/**/ {{0X3FB26DC3, 0X7AB9110C} },
+/**/ {{0X3FA2126C, 0X959CFC0E} },
+/**/ {{0XBFAB6F60, 0XD556233E} } },
+/**/ {{{0X3FEA3FFF, 0XBE9E153F} },
+/**/ {{0X3FE5FBF0, 0XA9C08AE0} },
+/**/ {{0X3FE320D9, 0X6F7861AA} },
+/**/ {{0XBFD2C256, 0XC2200F18} },
+/**/ {{0X3FB2915D, 0XA6795293} },
+/**/ {{0X3FA18A2B, 0X256A8FDE} },
+/**/ {{0XBFAB1470, 0XA67A4E89} } },
+/**/ {{{0X3FEA5FFE, 0X7A23A1CE} },
+/**/ {{0X3FE60F07, 0X63200600} },
+/**/ {{0X3FE30E1E, 0XD13D395E} },
+/**/ {{0XBFD2B45D, 0X44403932} },
+/**/ {{0X3FB2B3E9, 0XC967F013} },
+/**/ {{0X3FA103AD, 0X35D002B8} },
+/**/ {{0XBFAAB9B1, 0X6496A8F1} } },
+/**/ {{{0X3FEA8001, 0X57F250B8} },
+/**/ {{0X3FE6220D, 0XDD6453A0} },
+/**/ {{0X3FE2FB6F, 0XCFFFCC1E} },
+/**/ {{0XBFD2A648, 0X6F8D8291} },
+/**/ {{0X3FB2D56F, 0X03654CC3} },
+/**/ {{0X3FA07EE3, 0X4BB6E7A6} },
+/**/ {{0XBFAA5F2A, 0X87992F03} } },
+/**/ {{{0X3FEAA000, 0XDD839D49} },
+/**/ {{0X3FE634FF, 0XB412C9A0} },
+/**/ {{0X3FE2E8D0, 0XE2D59E01} },
+/**/ {{0XBFD2981C, 0X5467CFDD} },
+/**/ {{0X3FB2F5E8, 0XFF1FADB5} },
+/**/ {{0X3F9FF7D6, 0XA3BA803C} },
+/**/ {{0XBFAA04E3, 0X46AF8DB7} } },
+/**/ {{{0X3FEAC000, 0X770DF220} },
+/**/ {{0X3FE647DE, 0XFEF70020} },
+/**/ {{0X3FE2D640, 0X220AFF7F} },
+/**/ {{0XBFD289D8, 0X36F9E74F} },
+/**/ {{0X3FB3155E, 0XE509140A} },
+/**/ {{0X3F9EF56B, 0X61AB0B7F} },
+/**/ {{0XBFA9AAE2, 0X98CE391F} } },
+/**/ {{{0X3FEAE001, 0X125BBE48} },
+/**/ {{0X3FE65AAC, 0X57A24D20} },
+/**/ {{0X3FE2C3BD, 0X1BFB3559} },
+/**/ {{0XBFD27B7C, 0X6DDE55DD} },
+/**/ {{0X3FB333D5, 0X15C4C270} },
+/**/ {{0X3F9DF67A, 0X9BAC4ECF} },
+/**/ {{0XBFA9512F, 0X363A972B} } },
+/**/ {{{0X3FEAFFFE, 0X7C321839} },
+/**/ {{0X3FE66D65, 0X569B83C0} },
+/**/ {{0X3FE2B14A, 0X53FBF8D9} },
+/**/ {{0XBFD26D0B, 0X9CFA03CE} },
+/**/ {{0X3FB3514B, 0X2CAA2E0C} },
+/**/ {{0X3F9CFB22, 0X4597BE9A} },
+/**/ {{0XBFA8F7CF, 0X99110022} } },
+/**/ {{{0X3FEB1FFE, 0X75486924} },
+/**/ {{0X3FE6800D, 0X68CEFB40} },
+/**/ {{0X3FE29EE4, 0X8E6AA814} },
+/**/ {{0XBFD25E83, 0XE8AFA7EB} },
+/**/ {{0X3FB36DC9, 0XFB0E8AC8} },
+/**/ {{0X3F9C0331, 0XAD5D66CA} },
+/**/ {{0XBFA89EC9, 0XFEDB1E8B} } },
+/**/ {{{0X3FEB4001, 0X5FB8DEB8} },
+/**/ {{0X3FE692A4, 0XD137C500} },
+/**/ {{0X3FE28C8B, 0XABFF668E} },
+/**/ {{0XBFD24FE5, 0XD8E71E0A} },
+/**/ {{0X3FB38955, 0X1297317A} },
+/**/ {{0X3F9B0EA3, 0X1D844655} },
+/**/ {{0XBFA84624, 0X6914067D} } },
+/**/ {{{0X3FEB6000, 0X386C27B9} },
+/**/ {{0X3FE6A527, 0X8CDF6FC0} },
+/**/ {{0X3FE27A43, 0XC5758DB8} },
+/**/ {{0XBFD24135, 0X59CADCE0} },
+/**/ {{0X3FB3A3E9, 0XEE34AE91} },
+/**/ {{0X3F9A1DA8, 0X1C5FFF05} },
+/**/ {{0XBFA7EDE4, 0X9EC8AAC6} } },
+/**/ {{{0X3FEB8000, 0XD1EFDDB3} },
+/**/ {{0X3FE6B799, 0X0ACCB660} },
+/**/ {{0X3FE26809, 0X9983AAB2} },
+/**/ {{0XBFD23270, 0X76047E08} },
+/**/ {{0X3FB3BD90, 0XF132139B} },
+/**/ {{0X3F993010, 0X58DEB3E1} },
+/**/ {{0XBFA79610, 0X2D194CE9} } },
+/**/ {{{0X3FEB9FFE, 0X42CC4047} },
+/**/ {{0X3FE6C9F6, 0X86445E60} },
+/**/ {{0X3FE255E0, 0X069F871F} },
+/**/ {{0XBFD2239A, 0X25461639} },
+/**/ {{0X3FB3D649, 0XA926C127} },
+/**/ {{0X3F9845FB, 0XC5A21F70} },
+/**/ {{0XBFA73EAC, 0X68E20BE6} } },
+/**/ {{{0X3FEBC001, 0X951AEAAD} },
+/**/ {{0X3FE6DC45, 0X3C4E45A0} },
+/**/ {{0X3FE243C1, 0XFF6573B0} },
+/**/ {{0XBFD214AE, 0XE38FA7E7} },
+/**/ {{0X3FB3EE1E, 0X5EA1330F} },
+/**/ {{0X3F975F24, 0X2BCCE6DF} },
+/**/ {{0XBFA6E7BE, 0X6F3902C5} } },
+/**/ {{{0X3FEBDFFE, 0X6616FE11} },
+/**/ {{0X3FE6EE7E, 0X27106FE0} },
+/**/ {{0X3FE231B6, 0X97B587F0} },
+/**/ {{0XBFD205B5, 0X240FEF32} },
+/**/ {{0X3FB40509, 0X44EB818C} },
+/**/ {{0X3F967BDE, 0X108160F9} },
+/**/ {{0XBFA6914B, 0X271D18AD} } },
+/**/ {{{0X3FEBFFFF, 0X54511C72} },
+/**/ {{0X3FE700A7, 0X643BBB40} },
+/**/ {{0X3FE21FB7, 0XE1823C8B} },
+/**/ {{0XBFD1F6A8, 0X9A854F7A} },
+/**/ {{0X3FB41B15, 0X71F04837} },
+/**/ {{0X3F959BD8, 0XBBD10F7C} },
+/**/ {{0XBFA63B57, 0X41F03711} } },
+/**/ {{{0X3FEC2000, 0XC537593E} },
+/**/ {{0X3FE712BE, 0XF36D6400} },
+/**/ {{0X3FE20DC7, 0XF754B2D5} },
+/**/ {{0XBFD1E78B, 0X9D24DBED} },
+/**/ {{0X3FB43043, 0X94F485E0} },
+/**/ {{0X3F94BF29, 0X122A6884} },
+/**/ {{0XBFA5E5E7, 0X3D2AA4E9} } },
+/**/ {{{0X3FEC4000, 0XDDD35719} },
+/**/ {{0X3FE724C3, 0XD7FA3000} },
+/**/ {{0X3FE1FBE7, 0XF2A8B1BF} },
+/**/ {{0XBFD1D85F, 0XB25DDDF6} },
+/**/ {{0X3FB44495, 0XD2E3B20F} },
+/**/ {{0X3F93E5D6, 0X7FCC1B30} },
+/**/ {{0XBFA590FF, 0X62D0D00F} } },
+/**/ {{{0X3FEC6000, 0X402375B6} },
+/**/ {{0X3FE736B6, 0X7DFF3720} },
+/**/ {{0X3FE1EA17, 0X86C92387} },
+/**/ {{0XBFD1C925, 0X31DDFC58} },
+/**/ {{0X3FB4580F, 0XF8B6CBC2} },
+/**/ {{0X3F930FD7, 0X00CE998E} },
+/**/ {{0XBFA53CA3, 0XCB299E5F} } },
+/**/ {{{0X3FEC7FFF, 0X19904FE4} },
+/**/ {{0X3FE74897, 0X0F395860} },
+/**/ {{0X3FE1D856, 0XA825BA33} },
+/**/ {{0XBFD1B9DC, 0XA75E0FC5} },
+/**/ {{0X3FB46AB5, 0X79F8FD7D} },
+/**/ {{0X3F923D23, 0XA5A90AFE} },
+/**/ {{0XBFA4E8D8, 0X5D2F574B} } },
+/**/ {{{0X3FEC9FFE, 0XF9E2409D} },
+/**/ {{0X3FE75A66, 0X79E7F1C0} },
+/**/ {{0X3FE1C6A4, 0X8740D2E9} },
+/**/ {{0XBFD1AA85, 0XF198392C} },
+/**/ {{0X3FB47C8A, 0X808C583A} },
+/**/ {{0X3F916DAC, 0X857F2526} },
+/**/ {{0XBFA495A0, 0XD0477576} } },
+/**/ {{{0X3FECC001, 0XE038EF72} },
+/**/ {{0X3FE76C25, 0XE6815140} },
+/**/ {{0X3FE1B500, 0X19BDADF8} },
+/**/ {{0XBFD19B20, 0XB4A469AE} },
+/**/ {{0X3FB48D93, 0X42387EA2} },
+/**/ {{0X3F90A15F, 0X7305BAF5} },
+/**/ {{0XBFA44300, 0XACAE4E17} } },
+/**/ {{{0X3FECDFFE, 0XEB72037F} },
+/**/ {{0X3FE77DD0, 0X7A7A4AA0} },
+/**/ {{0X3FE1A36E, 0X4F1F6702} },
+/**/ {{0XBFD18BB1, 0XD0992CF8} },
+/**/ {{0X3FB49DCE, 0X5AA4990D} },
+/**/ {{0X3F8FB0DD, 0X63759665} },
+/**/ {{0XBFA3F0FB, 0X4D2F0C0F} } },
+/**/ {{{0X3FECFFFF, 0XEA4839ED} },
+/**/ {{0X3FE78F6B, 0XB17088C0} },
+/**/ {{0X3FE191E9, 0XCF32122F} },
+/**/ {{0XBFD17C35, 0X220400AC} },
+/**/ {{0X3FB4AD44, 0X0A159641} },
+/**/ {{0X3F8E252C, 0X80894CA9} },
+/**/ {{0XBFA39F93, 0XDF89C265} } },
+/**/ {{{0X3FED1FFD, 0XEC3EC8B2} },
+/**/ {{0X3FE7A0F3, 0XC8C6C880} },
+/**/ {{0X3FE18076, 0X729F01D6} },
+/**/ {{0XBFD16CAE, 0X98515540} },
+/**/ {{0X3FB4BBF4, 0X1B0933FF} },
+/**/ {{0X3F8C9FF5, 0XE09A60CD} },
+/**/ {{0XBFA34ECD, 0X662A5704} } },
+/**/ {{{0X3FED3FFF, 0X7084EDD4} },
+/**/ {{0X3FE7B26C, 0X5F02F220} },
+/**/ {{0X3FE16F10, 0XB9973206} },
+/**/ {{0XBFD15D1B, 0X9E1E0A54} },
+/**/ {{0X3FB4C9E4, 0XAC2C9A30} },
+/**/ {{0X3F8B20DD, 0XEFCE76CC} },
+/**/ {{0XBFA2FEAA, 0XB888BC37} } },
+/**/ {{{0X3FED5FFE, 0X8D728E7C} },
+/**/ {{0X3FE7C3D2, 0X488D7E80} },
+/**/ {{0X3FE15DBB, 0XE622A5A7} },
+/**/ {{0XBFD14D7F, 0XA305CEB2} },
+/**/ {{0X3FB4D716, 0X417BF1C7} },
+/**/ {{0X3F89A81E, 0XE19FE239} },
+/**/ {{0XBFA2AF2E, 0X84DDAD07} } },
+/**/ {{{0X3FED7FFF, 0X70AA3B03} },
+/**/ {{0X3FE7D527, 0XDB239580} },
+/**/ {{0X3FE14C75, 0XBE4FEA01} },
+/**/ {{0XBFD13DD9, 0X2AD706AA} },
+/**/ {{0X3FB4E38D, 0XB49D32AA} },
+/**/ {{0X3F88357A, 0X37DF2B6D} },
+/**/ {{0XBFA2605B, 0X507CD77B} } },
+/**/ {{{0X3FED9FFF, 0X1434FBA3} },
+/**/ {{0X3FE7E66B, 0X82C8A720} },
+/**/ {{0X3FE13B3F, 0XED9B7FED} },
+/**/ {{0XBFD12E2A, 0X3AC9D646} },
+/**/ {{0X3FB4EF4C, 0XE7B01CF5} },
+/**/ {{0X3F86C905, 0XD25FD52D} },
+/**/ {{0XBFA21233, 0X798666EF} } },
+/**/ {{{0X3FEDBFFE, 0XA8C8DE8C} },
+/**/ {{0X3FE7F79D, 0XF4A0A520} },
+/**/ {{0X3FE12A19, 0XD7FC2119} },
+/**/ {{0XBFD11E72, 0XC6BE19DF} },
+/**/ {{0X3FB4FA57, 0X634E1B91} },
+/**/ {{0X3F8562A6, 0X47F96DF5} },
+/**/ {{0XBFA1C4B9, 0X373AF599} } },
+/**/ {{{0X3FEDE000, 0X26573DF5} },
+/**/ {{0X3FE808C0, 0X4DBCB960} },
+/**/ {{0X3FE11902, 0X7903E4B9} },
+/**/ {{0XBFD10EB2, 0X5CDFED06} },
+/**/ {{0X3FB504B0, 0XCCA681FA} },
+/**/ {{0X3F840238, 0X6F3CDE09} },
+/**/ {{0XBFA177EE, 0X9BA8FA6A} } },
+/**/ {{{0X3FEDFFFE, 0X35009B66} },
+/**/ {{0X3FE819CF, 0XC2CB5340} },
+/**/ {{0X3FE107FC, 0XB1C942B5} },
+/**/ {{0XBFD0FEEC, 0X230D7D92} },
+/**/ {{0X3FB50E5A, 0X75C5B4F1} },
+/**/ {{0X3F82A7E8, 0XE3C139D8} },
+/**/ {{0XBFA12BD5, 0X93FA642B} } },
+/**/ {{{0X3FEE2000, 0X492D4C68} },
+/**/ {{0X3FE82AD0, 0X5CCB8680} },
+/**/ {{0X3FE0F704, 0X928E55DF} },
+/**/ {{0XBFD0EF1C, 0XEE0B0721} },
+/**/ {{0X3FB51759, 0X937BFB74} },
+/**/ {{0X3F815359, 0X2BC9FDDB} },
+/**/ {{0XBFA0E06F, 0XEA1D1824} } },
+/**/ {{{0X3FEE4000, 0X9412BB65} },
+/**/ {{0X3FE83BBF, 0X14001A60} },
+/**/ {{0X3FE0E61D, 0X37F485DA} },
+/**/ {{0XBFD0DF48, 0X1B2BD37D} },
+/**/ {{0X3FB51FAF, 0X64024D14} },
+/**/ {{0X3F8004B9, 0X9B849698} },
+/**/ {{0XBFA095BF, 0X450A2434} } },
+/**/ {{{0X3FEE5FFF, 0X4758EF2F} },
+/**/ {{0X3FE84C9C, 0X1531C180} },
+/**/ {{0X3FE0D546, 0X8B7FECE7} },
+/**/ {{0XBFD0CF6E, 0X105BFE1E} },
+/**/ {{0X3FB5275E, 0XF9C5E03A} },
+/**/ {{0X3F7D77F2, 0X17AA1137} },
+/**/ {{0XBFA04BC5, 0X2A6891E1} } },
+/**/ {{{0X3FEE8000, 0X380F819F} },
+/**/ {{0X3FE85D69, 0X74CCC060} },
+/**/ {{0X3FE0C47E, 0X8F1DA5B5} },
+/**/ {{0XBFD0BF8D, 0X62AD700F} },
+/**/ {{0X3FB52E6C, 0X1F3FBC2B} },
+/**/ {{0X3F7AF1C3, 0XEE24AD7D} },
+/**/ {{0XBFA00282, 0XFECE26C9} } },
+/**/ {{{0X3FEEA000, 0XA6D8CB7B} },
+/**/ {{0X3FE86E25, 0XD00E3A60} },
+/**/ {{0X3FE0B3C6, 0XBA314D62} },
+/**/ {{0XBFD0AFA7, 0XE7CB2D84} },
+/**/ {{0X3FB534D9, 0X08E9071F} },
+/**/ {{0X3F787704, 0X4CE5E5C9} },
+/**/ {{0XBF9F73F4, 0X0EB7C9D5} } },
+/**/ {{{0X3FEEC000, 0X5A13BA60} },
+/**/ {{0X3FE87ED1, 0X19B163E0} },
+/**/ {{0X3FE0A31F, 0X2EBB7AD7} },
+/**/ {{0XBFD09FBE, 0X33A3FCE1} },
+/**/ {{0X3FB53AA8, 0X89D9AF5D} },
+/**/ {{0X3F760799, 0XF7F7040B} },
+/**/ {{0XBF9EE456, 0XD3F0B3FB} } },
+/**/ {{{0X3FEEDFFF, 0X58F8DD18} },
+/**/ {{0X3FE88F6B, 0X6681CA80} },
+/**/ {{0X3FE09287, 0XEC4360B3} },
+/**/ {{0XBFD08FD0, 0XB7CE07E5} },
+/**/ {{0X3FB53FDD, 0X7BDEDD3F} },
+/**/ {{0X3F73A366, 0X70C52E66} },
+/**/ {{0XBF9E5630, 0X5DCA7315} } },
+/**/ {{{0X3FEEFFFF, 0XBE033400} },
+/**/ {{0X3FE89FF5, 0XDD4D7960} },
+/**/ {{0X3FE081FF, 0XDFFE15BD} },
+/**/ {{0XBFD07FDE, 0XDAE56C0F} },
+/**/ {{0X3FB5447A, 0XF84D6F5D} },
+/**/ {{0X3F714A24, 0X7982941E} },
+/**/ {{0XBF9DC982, 0X81E68835} } },
+/**/ {{{0X3FEF2001, 0XE6B5125D} },
+/**/ {{0X3FE8B070, 0XBBE88160} },
+/**/ {{0X3FE07186, 0XDF7122E2} },
+/**/ {{0XBFD06FE8, 0XDE905325} },
+/**/ {{0X3FB54883, 0XB5DEEC7A} },
+/**/ {{0X3F6DF762, 0XB4A186D5} },
+/**/ {{0XBF9D3E4E, 0XDE20F495} } },
+/**/ {{{0X3FEF3FFD, 0XF770E0DB} },
+/**/ {{0X3FE8C0D8, 0X09E96380} },
+/**/ {{0X3FE06120, 0XF5A576A9} },
+/**/ {{0XBFD05FF3, 0X1D2912FF} },
+/**/ {{0X3FB54BF9, 0X8CD1001F} },
+/**/ {{0X3F6970FC, 0X6E90DC16} },
+/**/ {{0XBF9CB496, 0XD8EB587E} } },
+/**/ {{{0X3FEF5FFE, 0X4E16DA33} },
+/**/ {{0X3FE8D131, 0X29BCCDC0} },
+/**/ {{0X3FE050C8, 0XD33BA4E9} },
+/**/ {{0XBFD04FF8, 0XD74C83D2} },
+/**/ {{0X3FB54EE0, 0X592BB252} },
+/**/ {{0X3F64FF61, 0X7193EEB5} },
+/**/ {{0XBF9C2C5B, 0XA459AC86} } },
+/**/ {{{0X3FEF8000, 0X4576FF2E} },
+/**/ {{0X3FE8E17A, 0XCCE443A0} },
+/**/ {{0X3FE0407F, 0XD8A97B6C} },
+/**/ {{0XBFD03FFB, 0XC91B3E55} },
+/**/ {{0X3FB5513A, 0X5F3357F7} },
+/**/ {{0X3F60A2BA, 0X14C92B53} },
+/**/ {{0XBF9BA59E, 0X3E70DF71} } },
+/**/ {{{0X3FEF9FFF, 0X39B6A330} },
+/**/ {{0X3FE8F1B2, 0XA7F515A0} },
+/**/ {{0X3FE03048, 0X63064158} },
+/**/ {{0XBFD02FFE, 0XACBAADA8} },
+/**/ {{0X3FB55309, 0XF27448C0} },
+/**/ {{0X3F58B6D6, 0X4850006B} },
+/**/ {{0XBF9B205F, 0X742323DF} } },
+/**/ {{{0X3FEFC001, 0XAA76C0B9} },
+/**/ {{0X3FE901DC, 0X15D66D80} },
+/**/ {{0X3FE0201F, 0X28D9B4AA} },
+/**/ {{0XBFD01FFE, 0XA98D4C38} },
+/**/ {{0X3FB55452, 0X089780F8} },
+/**/ {{0X3F5050B5, 0X7F35C5BB} },
+/**/ {{0XBF9A9C9F, 0XE19247AF} } },
+/**/ {{{0X3FEFDFFE, 0X39A592CA} },
+/**/ {{0X3FE911F2, 0X6D88A780} },
+/**/ {{0X3FE01008, 0XE40C6538} },
+/**/ {{0XBFD01000, 0XD31688DE} },
+/**/ {{0X3FB55514, 0XE32F1816} },
+/**/ {{0X3F402A15, 0X4E1628D2} },
+/**/ {{0XBF9A1A5F, 0XF4FAF5A0} } },
+/**/ {{{0X3FEFF801, 0X8E92D1B0} },
+/**/ {{0X3FE91DFB, 0X9BB4BF00} },
+/**/ {{0X3FE003FF, 0XB884C5A9} },
+/**/ {{0XBFD003FF, 0X3876A954} },
+/**/ {{0X3FB55551, 0X5539DDFB} },
+/**/ {{0X3F2007E7, 0X7B95E6C2} },
+/**/ {{0XBF99B9A7, 0X18A3BA58} } },
+ };
+
+ static const number
+ hij[241][16] = { /* x0,hij for (1/16,1) */
+/**/ {{{0x3fb04000, 0x00000000} },
+/**/ {{0x3fb03a6d, 0x1c06693d} },
+/**/ {{0xbc428a02, 0xd4e7f128} },
+/**/ {{0x3fefdf1f, 0xe92592ae} },
+/**/ {{0x3c88bfc0, 0xb5490162} },
+/**/ {{0xbfb01ead, 0x8f7e4151} },
+/**/ {{0xbc5395e8, 0x0b64d205} },
+/**/ {{0xbfd4d29f, 0x433dd49b} },
+/**/ {{0xbc75b19d, 0x4aa42633} },
+/**/ {{0x3fafda41, 0xce35961d} },
+/**/ {{0x3c4e6a5f, 0x425d7696} },
+/**/ {{0x3fc814dd, 0x6c1bb5e2} },
+/**/ {{0xbfaf4cb7, 0x2b33739f} },
+/**/ {{0xbfc048b2, 0xc267d8ec} },
+/**/ {{0x3fae9649, 0xe8ababc6} },
+/**/ {{0x3fb78293, 0xfe802692} } },
+/**/ {{{0x3fb10000, 0x00000000} },
+/**/ {{0x3fb0f99e, 0xa71d52a7} },
+/**/ {{0xbc22069f, 0xeec3624f} },
+/**/ {{0x3fefdc08, 0x9a49d2a9} },
+/**/ {{0x3c7780f7, 0x68b2ce25} },
+/**/ {{0xbfb0d9de, 0x9da73e1d} },
+/**/ {{0x3c4ebf46, 0xa1a487bf} },
+/**/ {{0xbfd4c669, 0xd13ea108} },
+/**/ {{0x3c7354bc, 0xebb4528c} },
+/**/ {{0x3fb0a137, 0x789374c1} },
+/**/ {{0xbc56c223, 0xc3f2c5c2} },
+/**/ {{0x3fc7f0e7, 0x79c60cda} },
+/**/ {{0xbfb05062, 0xcdcc7b81} },
+/**/ {{0xbfc019e4, 0xc5266783} },
+/**/ {{0x3fafd0b2, 0xf2540289} },
+/**/ {{0x3fb71107, 0xf6d3cd8a} } },
+/**/ {{{0x3fb20000, 0x00000000} },
+/**/ {{0x3fb1f86d, 0xbf082d59} },
+/**/ {{0xbc4095dc, 0x7732ef81} },
+/**/ {{0x3fefd7b3, 0x01722b81} },
+/**/ {{0xbc5e618c, 0x8a212e02} },
+/**/ {{0xbfb1d2c5, 0xee4e9cfa} },
+/**/ {{0x3c426273, 0x29abece0} },
+/**/ {{0xbfd4b551, 0x37eb7f46} },
+/**/ {{0x3c73b360, 0x01d8bf12} },
+/**/ {{0x3fb18fa7, 0x6adb6a7c} },
+/**/ {{0xbc5c00d8, 0x398999ad} },
+/**/ {{0x3fc7bea5, 0xf4a7cff3} },
+/**/ {{0xbfb13008, 0x61f84829} },
+/**/ {{0xbfbfb14f, 0xa8e135a1} },
+/**/ {{0x3fb0b532, 0x4324f177} },
+/**/ {{0x3fb6734a, 0x3498dd9d} } },
+/**/ {{{0x3fb30000, 0x00000000} },
+/**/ {{0x3fb2f719, 0x318a4a9a} },
+/**/ {{0x3c03fd17, 0x79b9801f} },
+/**/ {{0x3fefd31f, 0x48e238fe} },
+/**/ {{0xbc876a7a, 0xd8c45327} },
+/**/ {{0xbfb2cada, 0x852096e2} },
+/**/ {{0x3c460860, 0x11efd787} },
+/**/ {{0xbfd4a34b, 0x2e476a39} },
+/**/ {{0x3c7254f2, 0xeb11ee51} },
+/**/ {{0x3fb27c13, 0xc54ae225} },
+/**/ {{0x3c513096, 0x4ae66f0c} },
+/**/ {{0x3fc789ca, 0xef0d59d0} },
+/**/ {{0xbfb20c06, 0x6d9aaa8c} },
+/**/ {{0xbfbf2885, 0x846ba912} },
+/**/ {{0x3fb17c5f, 0xc697ef5e} },
+/**/ {{0x3fb5ce93, 0xcad31e6e} } },
+/**/ {{{0x3fb40000, 0x00000000} },
+/**/ {{0x3fb3f59f, 0x0e7c559d} },
+/**/ {{0x3c5ac4ce, 0x285df847} },
+/**/ {{0x3fefce4d, 0xa6ab93e9} },
+/**/ {{0xbc6be46b, 0x18a97736} },
+/**/ {{0xbfb3c211, 0x4d22b635} },
+/**/ {{0x3c42033c, 0x6950679f} },
+/**/ {{0xbfd49059, 0xc4d74033} },
+/**/ {{0x3c57dd7c, 0xd7e376aa} },
+/**/ {{0x3fb36662, 0xc0896a7c} },
+/**/ {{0xbc36cf6a, 0xd79232cf} },
+/**/ {{0x3fc75261, 0xa13a97a2} },
+/**/ {{0xbfb2e431, 0x5fdd1509} },
+/**/ {{0xbfbe9999, 0x6e52db32} },
+/**/ {{0x3fb23da4, 0xb0a71e9f} },
+/**/ {{0x3fb52335, 0xe3bc8178} } },
+/**/ {{{0x3fb50000, 0x00000000} },
+/**/ {{0x3fb4f3fd, 0x677292fb} },
+/**/ {{0x3c4008d3, 0x6264979e} },
+/**/ {{0x3fefc93e, 0x53a1ee0d} },
+/**/ {{0xbc64421a, 0x20fd2bdf} },
+/**/ {{0xbfb4b85f, 0x4aba88e3} },
+/**/ {{0x3c54f184, 0x3c9d1e89} },
+/**/ {{0xbfd47c7f, 0x25ae4668} },
+/**/ {{0xbc7d7581, 0x816630d1} },
+/**/ {{0x3fb44e7b, 0x07f85056} },
+/**/ {{0x3c56d63c, 0x910bdf4f} },
+/**/ {{0x3fc71875, 0xc439029c} },
+/**/ {{0xbfb3b85e, 0xf2bcfa10} },
+/**/ {{0xbfbe04bb, 0x9707b205} },
+/**/ {{0x3fb2f8c6, 0x95e3e0cc} },
+/**/ {{0x3fb47184, 0x8093431b} } },
+/**/ {{{0x3fb60000, 0x00000000} },
+/**/ {{0x3fb5f232, 0x4fd2d7b2} },
+/**/ {{0x3c58a8da, 0x4401318e} },
+/**/ {{0x3fefc3f1, 0x8b549418} },
+/**/ {{0x3c34d896, 0x836f8130} },
+/**/ {{0xbfb5adb9, 0x9cdd92e7} },
+/**/ {{0x3c4d4161, 0xeb397cc3} },
+/**/ {{0xbfd467bd, 0x93f8f1dc} },
+/**/ {{0xbc609d7b, 0xffc760ad} },
+/**/ {{0x3fb53443, 0xbea6b2fe} },
+/**/ {{0x3c5eb03c, 0x4b24f5db} },
+/**/ {{0x3fc6dc13, 0x8de3d005} },
+/**/ {{0xbfb48866, 0x37d2d99d} },
+/**/ {{0xbfbd6a1d, 0xf6663fcb} },
+/**/ {{0x3fb3ad8e, 0x0adff464} },
+/**/ {{0x3fb3b9d6, 0x4159c223} } },
+/**/ {{{0x3fb70000, 0x00000000} },
+/**/ {{0x3fb6f03b, 0xdcea4b0d} },
+/**/ {{0xbc33f00e, 0x512fa17d} },
+/**/ {{0x3fefbe67, 0x8c07a436} },
+/**/ {{0xbc84baaa, 0x46250d6f} },
+/**/ {{0xbfb6a215, 0x7e3ba4c7} },
+/**/ {{0xbc3504e7, 0x54503f8d} },
+/**/ {{0xbfd45217, 0x6b82d03a} },
+/**/ {{0x3c7d1f0d, 0xbebdd1db} },
+/**/ {{0x3fb617a4, 0x841d5604} },
+/**/ {{0xbc47168b, 0x6681c436} },
+/**/ {{0x3fc69d47, 0xaccec6ce} },
+/**/ {{0xbfb5541f, 0xa4715800} },
+/**/ {{0xbfbcc9f4, 0x335a1c1b} },
+/**/ {{0x3fb45bc6, 0xbac0061f} },
+/**/ {{0x3fb2fc84, 0x2b3853b6} } },
+/**/ {{{0x3fb80000, 0x00000000} },
+/**/ {{0x3fb7ee18, 0x2602f10f} },
+/**/ {{0xbc5cfb65, 0x4c0c3d98} },
+/**/ {{0x3fefb8a0, 0x96acfacc} },
+/**/ {{0xbc82962e, 0x18495af3} },
+/**/ {{0xbfb79568, 0x46635c89} },
+/**/ {{0x3c5ac468, 0xa6bfd498} },
+/**/ {{0xbfd43b8f, 0x2037b997} },
+/**/ {{0xbc72ad53, 0xe2f12373} },
+/**/ {{0x3fb6f885, 0x7900c4ee} },
+/**/ {{0x3c53145d, 0x0aef1f9d} },
+/**/ {{0x3fc65c1f, 0x4409ba0e} },
+/**/ {{0xbfb61b65, 0x1d176e0c} },
+/**/ {{0xbfbc2473, 0x8ad65152} },
+/**/ {{0x3fb5033f, 0x7bc246c1} },
+/**/ {{0x3fb239e9, 0x6db30b46} } },
+/**/ {{{0x3fb90000, 0x00000000} },
+/**/ {{0x3fb8ebc5, 0x4478fb28} },
+/**/ {{0x3c473288, 0x0cad24cc} },
+/**/ {{0x3fefb29c, 0xeedcd6d7} },
+/**/ {{0x3c8efa9e, 0x23ea50f0} },
+/**/ {{0xbfb887a7, 0x6ae09982} },
+/**/ {{0x3c5b2275, 0x53801511} },
+/**/ {{0xbfd42427, 0x3da0757c} },
+/**/ {{0xbc7199e5, 0x311c7ac8} },
+/**/ {{0x3fb7d6cf, 0x4388717b} },
+/**/ {{0xbc5c4eb2, 0x3dd070b4} },
+/**/ {{0x3fc618a7, 0xe6c2b5f3} },
+/**/ {{0xbfb6de12, 0x00313569} },
+/**/ {{0xbfbb79d2, 0xb6316619} },
+/**/ {{0x3fb5a3ca, 0x61af5c21} },
+/**/ {{0x3fb17263, 0x26e60289} } },
+/**/ {{{0x3fba0000, 0x00000000} },
+/**/ {{0x3fb9e941, 0x53cfdcf1} },
+/**/ {{0x3c5a332e, 0x1d69c47e} },
+/**/ {{0x3fefac5c, 0xdace3776} },
+/**/ {{0xbc8c9a78, 0x1ad91ab5} },
+/**/ {{0xbfb978c8, 0x8054ad75} },
+/**/ {{0xbc5e35b8, 0x8ed66c17} },
+/**/ {{0xbfd40be2, 0x665afed1} },
+/**/ {{0x3c62eeef, 0x08ef10fb} },
+/**/ {{0x3fb8b26b, 0x13c989d2} },
+/**/ {{0x3c329f11, 0xbfeab3ba} },
+/**/ {{0x3fc5d2ef, 0x93c8f97c} },
+/**/ {{0xbfb79c03, 0x30234881} },
+/**/ {{0xbfbaca49, 0xd0f650c8} },
+/**/ {{0x3fb63d3c, 0xce2dcccc} },
+/**/ {{0x3fb0a650, 0x26fb0af2} } },
+/**/ {{{0x3fbb0000, 0x00000000} },
+/**/ {{0x3fbae68a, 0x71c722b8} },
+/**/ {{0x3c4c014e, 0x6910b9db} },
+/**/ {{0x3fefa5e0, 0xa34ef42b} },
+/**/ {{0xbc836583, 0xeb56d5b9} },
+/**/ {{0xbfba68c1, 0x3b881779} },
+/**/ {{0xbc473a0d, 0x13a09314} },
+/**/ {{0xbfd3f2c3, 0x538e939c} },
+/**/ {{0xbc68ed49, 0xee53e648} },
+/**/ {{0x3fb98b42, 0xa7d45973} },
+/**/ {{0xbc523943, 0x461ca7c4} },
+/**/ {{0x3fc58b04, 0xb0f2e2bb} },
+/**/ {{0xbfb85517, 0x1c9d23dc} },
+/**/ {{0xbfba1612, 0x3e3b5a66} },
+/**/ {{0x3fb6cf6f, 0x7ef1d0b9} },
+/**/ {{0x3fafac21, 0x6617b315} } },
+/**/ {{{0x3fbc0000, 0x00000000} },
+/**/ {{0x3fbbe39e, 0xbe6f07c3} },
+/**/ {{0x3c5f7b8f, 0x29a05987} },
+/**/ {{0x3fef9f28, 0x93bb9192} },
+/**/ {{0x3c78260b, 0x7cd1bdab} },
+/**/ {{0xbfbb5787, 0x72759741} },
+/**/ {{0x3c52f93f, 0xa6767247} },
+/**/ {{0xbfd3d8cc, 0xd45bbe91} },
+/**/ {{0x3c664839, 0x2edc0762} },
+/**/ {{0x3fba6140, 0x4fa31d26} },
+/**/ {{0x3c400647, 0x97891510} },
+/**/ {{0x3fc540f6, 0x0668fd66} },
+/**/ {{0xbfb9092d, 0xcb2f6e8f} },
+/**/ {{0xbfb95d66, 0x8d902073} },
+/**/ {{0x3fb75a3e, 0x99c53d16} },
+/**/ {{0x3fae040c, 0x8f475e61} } },
+/**/ {{{0x3fbd0000, 0x00000000} },
+/**/ {{0x3fbce07c, 0x5c3cca32} },
+/**/ {{0x3c4138e6, 0x425918a7} },
+/**/ {{0x3fef9834, 0xf9f6d421} },
+/**/ {{0x3c6f3089, 0x8c22a239} },
+/**/ {{0xbfbc4511, 0x1d4e69a5} },
+/**/ {{0x3c254c0f, 0xd2083ce8} },
+/**/ {{0xbfd3be01, 0xcd488978} },
+/**/ {{0x3c5612db, 0x6362ec0f} },
+/**/ {{0x3fbb344e, 0xf0d94873} },
+/**/ {{0xbc182beb, 0xfdf7db72} },
+/**/ {{0x3fc4f4d2, 0xb9d86c04} },
+/**/ {{0xbfb9b828, 0xdf238807} },
+/**/ {{0xbfb8a082, 0x5f93ffd6} },
+/**/ {{0x3fb7dd89, 0xb6650b0c} },
+/**/ {{0x3fac5526, 0xb62676ef} } },
+/**/ {{{0x3fbe0000, 0x00000000} },
+/**/ {{0x3fbddd21, 0x701eba6e} },
+/**/ {{0x3c594eff, 0xcd76fe58} },
+/**/ {{0x3fef9106, 0x266112ba} },
+/**/ {{0x3c74c302, 0x6b7e18b1} },
+/**/ {{0xbfbd3154, 0x5777816c} },
+/**/ {{0x3c5dc7e4, 0x1f9dbddd} },
+/**/ {{0xbfd3a265, 0x37a90881} },
+/**/ {{0xbc75bd61, 0xeb7ba840} },
+/**/ {{0x3fbc045a, 0x0a52514b} },
+/**/ {{0xbc35ca88, 0xcff49a99} },
+/**/ {{0x3fc4a6aa, 0x498eeb56} },
+/**/ {{0xbfba61eb, 0xa09232cf} },
+/**/ {{0xbfb7dfa2, 0x4a464027} },
+/**/ {{0x3fb85933, 0xe633c053} },
+/**/ {{0x3faaa036, 0x3f920107} } },
+/**/ {{{0x3fbf0000, 0x00000000} },
+/**/ {{0x3fbed98c, 0x2190043b} },
+/**/ {{0xbc23a598, 0x592c7b13} },
+/**/ {{0x3fef899c, 0x6bcf4ad8} },
+/**/ {{0x3c55fd73, 0x912c09b0} },
+/**/ {{0xbfbe1c47, 0x607f91a0} },
+/**/ {{0x3c576677, 0x5b5db022} },
+/**/ {{0xbfd385fa, 0x21046f5f} },
+/**/ {{0x3c7f01c3, 0x4487f4b8} },
+/**/ {{0x3fbcd14d, 0xb77f2d51} },
+/**/ {{0x3c57a86d, 0x30a2ccfe} },
+/**/ {{0x3fc4568c, 0x8782b530} },
+/**/ {{0xbfbb065b, 0x02b7ad2d} },
+/**/ {{0xbfb71b03, 0xbd215555} },
+/**/ {{0x3fb8cd23, 0xb9c1c1de} },
+/**/ {{0x3fa8e602, 0x8dbfa69b} } },
+/**/ {{{0x3fc00000, 0x00000000} },
+/**/ {{0x3fbfd5ba, 0x9aac2f6e} },
+/**/ {{0xbc4cd376, 0x86760c17} },
+/**/ {{0x3fef81f8, 0x1f81f820} },
+/**/ {{0xbc8f81f8, 0x1f81f820} },
+/**/ {{0xbfbf05e0, 0x9d0dc11b} },
+/**/ {{0xbc35a199, 0x1d821725} },
+/**/ {{0xbfd368c3, 0xaa76e1d7} },
+/**/ {{0xbc672d4c, 0xc796f8cd} },
+/**/ {{0x3fbd9b16, 0xb391c2e3} },
+/**/ {{0x3c58051b, 0x8086c51d} },
+/**/ {{0x3fc40489, 0x94488c86} },
+/**/ {{0xbfbba55d, 0xa98401c8} },
+/**/ {{0xbfb652e4, 0xe5127e64} },
+/**/ {{0x3fb93943, 0x442e53ae} },
+/**/ {{0x3fa72753, 0x86286f75} } },
+/**/ {{{0x3fc08000, 0x00000000} },
+/**/ {{0x3fc068d5, 0x84212b3e} },
+/**/ {{0xbc69e2d2, 0x83019bfd} },
+/**/ {{0x3fef7a19, 0x991bb133} },
+/**/ {{0x3c7a956a, 0x66627723} },
+/**/ {{0xbfbfee16, 0x97c8e137} },
+/**/ {{0x3c4d9399, 0x66dbe7af} },
+/**/ {{0xbfd34ac5, 0x0810323a} },
+/**/ {{0x3c6a1a57, 0x6bc6c512} },
+/**/ {{0x3fbe61a2, 0x5c75a6f9} },
+/**/ {{0xbc492b99, 0xd75c8f85} },
+/**/ {{0x3fc3b0b1, 0xd9fa3f20} },
+/**/ {{0xbfbc3edb, 0xee66d309} },
+/**/ {{0xbfb58784, 0x905eeb33} },
+/**/ {{0x3fb99d80, 0x1c65bb14} },
+/**/ {{0x3fa564f1, 0x18a09884} } },
+/**/ {{{0x3fc10000, 0x00000000} },
+/**/ {{0x3fc0e6ad, 0xccf40882} },
+/**/ {{0xbc6d71a3, 0x1bb98d0d} },
+/**/ {{0x3fef7201, 0x32978bad} },
+/**/ {{0x3c816476, 0x599381e9} },
+/**/ {{0xbfc06a70, 0x011b81fd} },
+/**/ {{0xbc422f5d, 0x9ba697ca} },
+/**/ {{0xbfd32c01, 0x802fc0a5} },
+/**/ {{0x3c7d8e47, 0x08a20868} },
+/**/ {{0x3fbf24de, 0xb59597fe} },
+/**/ {{0xbc43288f, 0x410d31eb} },
+/**/ {{0x3fc35b16, 0x070feb24} },
+/**/ {{0xbfbcd2bf, 0xe4565b78} },
+/**/ {{0xbfb4b922, 0x128768c6} },
+/**/ {{0x3fb9f9cb, 0x5c42a097} },
+/**/ {{0x3fa39fa2, 0xc7f97f2e} } },
+/**/ {{{0x3fc18000, 0x00000000} },
+/**/ {{0x3fc16465, 0x41060850} },
+/**/ {{0x3c66bcee, 0x8ae7ea92} },
+/**/ {{0x3fef69af, 0x483f492b} },
+/**/ {{0xbc6e3280, 0x57db963e} },
+/**/ {{0xbfc0dd19, 0xdacaa844} },
+/**/ {{0xbc6133c7, 0xad7fc21e} },
+/**/ {{0xbfd30c7c, 0x6addaea8} },
+/**/ {{0xbc71443d, 0x89161c76} },
+/**/ {{0x3fbfe4ba, 0x6a6d3cd2} },
+/**/ {{0x3c50d4b8, 0x423ee67a} },
+/**/ {{0x3fc303c7, 0x092e569a} },
+/**/ {{0xbfbd60f5, 0x5b11d3b6} },
+/**/ {{0xbfb3e7fd, 0x283b5c55} },
+/**/ {{0x3fba4e19, 0x9d9a6ab7} },
+/**/ {{0x3fa1d82f, 0x3487cc29} } },
+/**/ {{{0x3fc20000, 0x00000000} },
+/**/ {{0x3fc1e1fa, 0xfb043727} },
+/**/ {{0xbc4b4859, 0x14dacf8c} },
+/**/ {{0x3fef6124, 0x38a14f5e} },
+/**/ {{0x3c798e9e, 0x001f6124} },
+/**/ {{0xbfc14f04, 0x59d3fb7c} },
+/**/ {{0x3c531efa, 0x4cc99cb2} },
+/**/ {{0xbfd2ec39, 0x31219b34} },
+/**/ {{0xbc618697, 0x6e004611} },
+/**/ {{0x3fc05092, 0x68736312} },
+/**/ {{0x3c67aad4, 0x8a06e4b5} },
+/**/ {{0x3fc2aad6, 0x07eca5ec} },
+/**/ {{0xbfbde969, 0xe19fe31c} },
+/**/ {{0xbfb31455, 0xdb6b9127} },
+/**/ {{0x3fba9a62, 0xf53dd9ee} },
+/**/ {{0x3fa00f5b, 0xa8e4ede0} } },
+/**/ {{{0x3fc28000, 0x00000000} },
+/**/ {{0x3fc25f6e, 0x171a535c} },
+/**/ {{0x3c67c6d7, 0xbde1a310} },
+/**/ {{0x3fef5860, 0x64866d22} },
+/**/ {{0x3c88c6ff, 0xd1f6326c} },
+/**/ {{0xbfc1c02b, 0x13c11396} },
+/**/ {{0xbc51b469, 0xffeb1a0f} },
+/**/ {{0xbfd2cb3b, 0x4c571b0f} },
+/**/ {{0x3c6e4f76, 0x2fb0b163} },
+/**/ {{0x3fc0ad06, 0xf5c213ab} },
+/**/ {{0x3c625bf2, 0xabea9e66} },
+/**/ {{0x3fc25054, 0x5f93bbb2} },
+/**/ {{0xbfbe6c0c, 0xc80a32c8} },
+/**/ {{0xbfb23e6c, 0x678d0d1e} },
+/**/ {{0x3fbadea2, 0xebf8ae4b} },
+/**/ {{0x3f9c8bd7, 0x527f133b} } },
+/**/ {{{0x3fc30000, 0x00000000} },
+/**/ {{0x3fc2dcbd, 0xb2fba1ff} },
+/**/ {{0x3c58f287, 0x05561534} },
+/**/ {{0x3fef4f64, 0x2ee76e94} },
+/**/ {{0x3c80ec89, 0xc6da5865} },
+/**/ {{0xbfc23089, 0xb322f867} },
+/**/ {{0x3c4c2b54, 0x5fcd0d6f} },
+/**/ {{0xbfd2a986, 0x45802261} },
+/**/ {{0xbc79a132, 0x5ae78b8a} },
+/**/ {{0x3fc107b3, 0x35a9d974} },
+/**/ {{0x3c5ef22d, 0xb725e335} },
+/**/ {{0x3fc1f453, 0x9bd98832} },
+/**/ {{0xbfbee8cf, 0x2057aad4} },
+/**/ {{0xbfb16681, 0x1e1bc3a1} },
+/**/ {{0x3fbb1ad8, 0x759c8f58} },
+/**/ {{0x3f98f941, 0x0b15b4aa} } },
+/**/ {{{0x3fc38000, 0x00000000} },
+/**/ {{0x3fc359e8, 0xedeb99a4} },
+/**/ {{0xbc6a5fd7, 0x4e4604c6} },
+/**/ {{0x3fef462f, 0xfce28238} },
+/**/ {{0x3c83dc01, 0xd90595d1} },
+/**/ {{0xbfc2a01b, 0xf7edfa6d} },
+/**/ {{0xbc6b11fb, 0x4a3b5c9a} },
+/**/ {{0xbfd2871d, 0xb4959402} },
+/**/ {{0xbc4a3702, 0x2fcf7ea3} },
+/**/ {{0x3fc1608f, 0xd8d7fe8c} },
+/**/ {{0x3c61ac60, 0xf8f1d41c} },
+/**/ {{0x3fc196e5, 0x729a89ca} },
+/**/ {{0xbfbf5fa3, 0xbec74f31} },
+/**/ {{0xbfb08cd4, 0x4b6c9767} },
+/**/ {{0x3fbb4f05, 0xe624ce15} },
+/**/ {{0x3f956871, 0xddb2020c} } },
+/**/ {{{0x3fc40000, 0x00000000} },
+/**/ {{0x3fc3d6ee, 0xe8c6626c} },
+/**/ {{0x3c661a3b, 0x0ce9281b} },
+/**/ {{0x3fef3cc4, 0x35b0713c} },
+/**/ {{0x3c81d0a7, 0xe69ea094} },
+/**/ {{0xbfc30edd, 0xb7d169f0} },
+/**/ {{0x3c6b3394, 0xae999b97} },
+/**/ {{0xbfd26405, 0x3fd62b3c} },
+/**/ {{0x3c73e339, 0xc0736df9} },
+/**/ {{0x3fc1b795, 0xe8e57ee3} },
+/**/ {{0xbc6130dc, 0x0a42c7f6} },
+/**/ {{0x3fc1381b, 0xbe93b8e5} },
+/**/ {{0xbfbfd07f, 0x394e1bf7} },
+/**/ {{0xbfaf634c, 0x37bb5315} },
+/**/ {{0x3fbb7b30, 0xe501e57b} },
+/**/ {{0x3f91dae1, 0x20503792} } },
+/**/ {{{0x3fc48000, 0x00000000} },
+/**/ {{0x3fc453ce, 0xc6092a9e} },
+/**/ {{0x3c61f653, 0xb3a5a78b} },
+/**/ {{0x3fef3321, 0x4299ace8} },
+/**/ {{0xbc87414c, 0x3a742b30} },
+/**/ {{0xbfc37cca, 0xde8b2323} },
+/**/ {{0x3c649378, 0x7b50aedf} },
+/**/ {{0xbfd24040, 0x9b13f4d0} },
+/**/ {{0x3c7e271f, 0xb7dc85c0} },
+/**/ {{0x3fc20cbe, 0xc9024068} },
+/**/ {{0x3c50921f, 0x88ef3da7} },
+/**/ {{0x3fc0d808, 0x7a1f1270} },
+/**/ {{0xbfc01dab, 0xf32d5436} },
+/**/ {{0xbfadaa6d, 0x02e6f09c} },
+/**/ {{0x3fbb9f62, 0x5e9cd766} },
+/**/ {{0x3f8ca3fe, 0xab964c04} } },
+/**/ {{{0x3fc50000, 0x00000000} },
+/**/ {{0x3fc4d087, 0xa9da4f17} },
+/**/ {{0x3c61f323, 0xf1adf158} },
+/**/ {{0x3fef2947, 0x8eeb3352} },
+/**/ {{0x3c871eb0, 0x8799a164} },
+/**/ {{0xbfc3e9df, 0x6e36e75c} },
+/**/ {{0x3c541555, 0x4e37666f} },
+/**/ {{0xbfd21bd3, 0x87008bd0} },
+/**/ {{0xbc609e14, 0xc24ff75f} },
+/**/ {{0x3fc26004, 0x36860504} },
+/**/ {{0xbc58f8ca, 0x1ebc8c40} },
+/**/ {{0x3fc076bd, 0xb9f4ead3} },
+/**/ {{0xbfc05012, 0xed70ddd5} },
+/**/ {{0xbfabef8a, 0x33e194b1} },
+/**/ {{0x3fbbbba6, 0x7423a91f} },
+/**/ {{0x3f859e6a, 0xdd99da12} } },
+/**/ {{{0x3fc58000, 0x00000000} },
+/**/ {{0x3fc54d18, 0xba11570a} },
+/**/ {{0x3c618282, 0xf2884073} },
+/**/ {{0x3fef1f37, 0x87eb4d7d} },
+/**/ {{0x3c8476f0, 0xedda13e6} },
+/**/ {{0xbfc45617, 0x7f997c7c} },
+/**/ {{0xbc46bf5b, 0x6423ceda} },
+/**/ {{0xbfd1f6c1, 0xd0784ec7} },
+/**/ {{0xbc74ec12, 0xd106a8e0} },
+/**/ {{0x3fc2b160, 0x4967338d} },
+/**/ {{0x3c5309c0, 0x61339c25} },
+/**/ {{0x3fc0144d, 0xa7f42962} },
+/**/ {{0xbfc07f71, 0x73dbaeec} },
+/**/ {{0xbfaa3322, 0x2aeda9a4} },
+/**/ {{0x3fbbd00c, 0x69b152b3} },
+/**/ {{0x3f7d4f90, 0x4c782821} } },
+/**/ {{{0x3fc60000, 0x00000000} },
+/**/ {{0x3fc5c981, 0x1e3ec26a} },
+/**/ {{0xbc5054ab, 0x2c010f3d} },
+/**/ {{0x3fef14f1, 0x9cce28eb} },
+/**/ {{0xbc8b7c25, 0x2708cd6e} },
+/**/ {{0xbfc4c16f, 0x42678d07} },
+/**/ {{0x3c5f55ba, 0xc1560017} },
+/**/ {{0xbfd1d10f, 0x4fccc153} },
+/**/ {{0x3c529588, 0x1bcc361d} },
+/**/ {{0x3fc300cd, 0x74979f8c} },
+/**/ {{0xbc6b1da5, 0x0bc1e891} },
+/**/ {{0x3fbf6194, 0xfbe70208} },
+/**/ {{0xbfc0abc5, 0x4b1c266f} },
+/**/ {{0xbfa875b2, 0x3b74e858} },
+/**/ {{0x3fbbdca6, 0x92e46f11} },
+/**/ {{0x3f6f0b17, 0x9de94aef} } },
+/**/ {{{0x3fc68000, 0x00000000} },
+/**/ {{0x3fc645bf, 0xffb3aa74} },
+/**/ {{0xbc3f536b, 0x677c2cb4} },
+/**/ {{0x3fef0a76, 0x3eaa4ed6} },
+/**/ {{0x3c888c52, 0x0b06c761} },
+/**/ {{0xbfc52be2, 0xfd884489} },
+/**/ {{0x3c67ec59, 0xbe5c728a} },
+/**/ {{0xbfd1aabf, 0xe80e4e0a} },
+/**/ {{0xbc71320e, 0xe90c909e} },
+/**/ {{0x3fc34e46, 0x864781ca} },
+/**/ {{0x3c42fcb3, 0x126138ee} },
+/**/ {{0x3fbe988d, 0x013b5d4f} },
+/**/ {{0xbfc0d50d, 0x122409a2} },
+/**/ {{0xbfa6b7b6, 0x7bb562c1} },
+/**/ {{0x3fbbe18a, 0x3df8dee8} },
+/**/ {{0x3f3e4009, 0x8809e1ef} } },
+/**/ {{{0x3fc70000, 0x00000000} },
+/**/ {{0x3fc6c1d4, 0x898933d9} },
+/**/ {{0xbc52954a, 0x7603c427} },
+/**/ {{0x3feeffc5, 0xe06cfb34} },
+/**/ {{0xbc85c037, 0x379877c2} },
+/**/ {{0xbfc5956f, 0x0f53a52c} },
+/**/ {{0x3c4d46a2, 0xe566376c} },
+/**/ {{0xbfd183d7, 0x86559c11} },
+/**/ {{0x3c7d2520, 0x64734c7f} },
+/**/ {{0x3fc399c6, 0xa80eddd5} },
+/**/ {{0x3c616c26, 0x40fbef6f} },
+/**/ {{0x3fbdcda7, 0xf4b571a7} },
+/**/ {{0xbfc0fb48, 0x3fd42996} },
+/**/ {{0xbfa4f9a9, 0x95c85118} },
+/**/ {{0x3fbbdecf, 0x9d795df4} },
+/**/ {{0xbf672003, 0xb85bf719} } },
+/**/ {{{0x3fc78000, 0x00000000} },
+/**/ {{0x3fc73dbd, 0xe8a7d202} },
+/**/ {{0xbc55ad0f, 0x6d4a665d} },
+/**/ {{0x3feef4e0, 0xf6ce5590} },
+/**/ {{0xbc833df6, 0x556900ef} },
+/**/ {{0xbfc5fe0f, 0xedcc9488} },
+/**/ {{0x3c5078de, 0xd2b9e35c} },
+/**/ {{0xbfd15c5a, 0x210cab36} },
+/**/ {{0x3c67fa93, 0xf55e532a} },
+/**/ {{0x3fc3e349, 0x5efd9a41} },
+/**/ {{0xbc6cf709, 0xc8573a12} },
+/**/ {{0x3fbd010a, 0x6c903aef} },
+/**/ {{0xbfc11e77, 0x20571328} },
+/**/ {{0xbfa33c04, 0x9a1875dd} },
+/**/ {{0x3fbbd491, 0xb09ec0ce} },
+/**/ {{0xbf78d197, 0x35537a65} } },
+/**/ {{{0x3fc80000, 0x00000000} },
+/**/ {{0x3fc7b97b, 0x4bce5b02} },
+/**/ {{0x3c5347b0, 0xb4f881ca} },
+/**/ {{0x3feee9c7, 0xf8458e02} },
+/**/ {{0xbc616380, 0x7ba71fe1} },
+/**/ {{0xbfc665c2, 0x26d69eeb} },
+/**/ {{0xbc572a33, 0xfdb5eea8} },
+/**/ {{0xbfd1344b, 0xb737e8f3} },
+/**/ {{0xbc757b70, 0x62badf41} },
+/**/ {{0x3fc42aca, 0x8b929b0b} },
+/**/ {{0x3c43cdb5, 0x7a8b7d91} },
+/**/ {{0x3fbc32d8, 0xf683981c} },
+/**/ {{0xbfc13e9a, 0xd22d5ecc} },
+/**/ {{0xbfa17f3e, 0xd35c8c33} },
+/**/ {{0x3fbbc2ee, 0x2a73307e} },
+/**/ {{0xbf82ee04, 0x2bddc834} } },
+/**/ {{{0x3fc88000, 0x00000000} },
+/**/ {{0x3fc8350b, 0xe398ebc8} },
+/**/ {{0xbc55a913, 0x32b9c90d} },
+/**/ {{0x3feede7b, 0x5cfce04c} },
+/**/ {{0x3c8507c2, 0x3b51a72f} },
+/**/ {{0xbfc6cc82, 0x6067718b} },
+/**/ {{0x3c6d00ca, 0xdbfc430f} },
+/**/ {{0xbfd10bb0, 0x4fbf6fe8} },
+/**/ {{0x3c321748, 0x53749c72} },
+/**/ {{0x3fc47046, 0x699a36ad} },
+/**/ {{0xbc63924c, 0x3994d40c} },
+/**/ {{0x3fbb6338, 0x0dfb7483} },
+/**/ {{0xbfc15bb5, 0x42ee5820} },
+/**/ {{0xbf9f879b, 0x385194fc} },
+/**/ {{0x3fbbaa05, 0x57d040e9} },
+/**/ {{0xbf895566, 0xada71ca0} } },
+/**/ {{{0x3fc90000, 0x00000000} },
+/**/ {{0x3fc8b06e, 0xe2879c29} },
+/**/ {{0xbc6118cd, 0x30308c4f} },
+/**/ {{0x3feed2fb, 0x9ec57f51} },
+/**/ {{0xbc83fdc5, 0xc0d106ba} },
+/**/ {{0xbfc7324d, 0x58b40d27} },
+/**/ {{0x3c68e240, 0xfc062163} },
+/**/ {{0xbfd0e28b, 0xf8b8a2bf} },
+/**/ {{0xbc7b8d8a, 0x64c55b39} },
+/**/ {{0x3fc4b3b9, 0x8ff46730} },
+/**/ {{0xbc5af146, 0x988563da} },
+/**/ {{0x3fba924c, 0x1277a10d} },
+/**/ {{0xbfc175c9, 0x2bbfd54d} },
+/**/ {{0xbf9c1448, 0x6c522340} },
+/**/ {{0x3fbb89fa, 0x044f2f6b} },
+/**/ {{0xbf8f9cc7, 0xaaecc742} } },
+/**/ {{{0x3fc98000, 0x00000000} },
+/**/ {{0x3fc92ba3, 0x7d050272} },
+/**/ {{0xbc60d3de, 0xd0ff4764} },
+/**/ {{0x3feec749, 0x390b6afe} },
+/**/ {{0xbc5c3d17, 0x4e3659ca} },
+/**/ {{0xbfc7971f, 0xe659b3de} },
+/**/ {{0x3c4cab11, 0x373f554d} },
+/**/ {{0xbfd0b8e2, 0xc6b052a4} },
+/**/ {{0x3c7da014, 0x6f3b74bc} },
+/**/ {{0x3fc4f520, 0xf0432146} },
+/**/ {{0xbc6769ad, 0xa8027290} },
+/**/ {{0x3fb9c039, 0x3e17b570} },
+/**/ {{0xbfc18cda, 0x0d8833a4} },
+/**/ {{0xbf98a567, 0x4627d340} },
+/**/ {{0x3fbb62f1, 0x5e42eff7} },
+/**/ {{0xbf92e10a, 0x7ee3bed3} } },
+/**/ {{{0x3fca0000, 0x00000000} },
+/**/ {{0x3fc9a6a8, 0xe96c8626} },
+/**/ {{0x3c4cf601, 0xe7b4348e} },
+/**/ {{0x3feebb64, 0xa8c932d7} },
+/**/ {{0x3c20538d, 0x79aae302} },
+/**/ {{0xbfc7faf6, 0xf88295fe} },
+/**/ {{0xbc687a81, 0x932909e9} },
+/**/ {{0xbfd08eb8, 0xd3f5a07b} },
+/**/ {{0xbc620a05, 0xfb7d6aaa} },
+/**/ {{0x3fc53479, 0xd6814372} },
+/**/ {{0xbc53c682, 0x0a0c6620} },
+/**/ {{0x3fb8ed23, 0x9c562d77} },
+/**/ {{0xbfc1a0ec, 0x2cdd89fd} },
+/**/ {{0xbf953bd4, 0xfec9df82} },
+/**/ {{0x3fbb3512, 0xd9d3f0f6} },
+/**/ {{0xbf95e1ab, 0x4534ccf5} } },
+/**/ {{{0x3fca8000, 0x00000000} },
+/**/ {{0x3fca217e, 0x601081a6} },
+/**/ {{0xbc60def8, 0xa60af374} },
+/**/ {{0x3feeaf4e, 0x6c7ba732} },
+/**/ {{0x3c89fa72, 0xe91fffe1} },
+/**/ {{0xbfc85dcf, 0x970642c3} },
+/**/ {{0xbc5732c2, 0x5b7f0ad0} },
+/**/ {{0xbfd06412, 0x3fe5c74d} },
+/**/ {{0xbc7d0053, 0x4a82f9b1} },
+/**/ {{0x3fc571c1, 0xe882973d} },
+/**/ {{0x3c59d9a3, 0x9090f12c} },
+/**/ {{0x3fb8192f, 0x00f5d0e0} },
+/**/ {{0xbfc1b204, 0x8db53983} },
+/**/ {{0xbf91d869, 0xbdd7b47e} },
+/**/ {{0x3fbb0088, 0x1355a903} },
+/**/ {{0xbf98cf57, 0x724a2ad9} } },
+/**/ {{{0x3fcb0000, 0x00000000} },
+/**/ {{0x3fca9c23, 0x1b403279} },
+/**/ {{0x3c60e8bb, 0xe89cca85} },
+/**/ {{0x3feea307, 0x04157b4f} },
+/**/ {{0x3c8ad743, 0xfd8bf1f0} },
+/**/ {{0xbfc8bfa6, 0xe285e2fd} },
+/**/ {{0xbc6ce765, 0x9c834c8f} },
+/**/ {{0xbfd038f3, 0x2e38fd26} },
+/**/ {{0x3c6a42ec, 0xef212a80} },
+/**/ {{0x3fc5acf7, 0x255d65d5} },
+/**/ {{0xbc619fba, 0xbe486771} },
+/**/ {{0x3fb7447e, 0xff244e15} },
+/**/ {{0xbfc1c028, 0xeed71b69} },
+/**/ {{0xbf8cf7f0, 0xaceecf68} },
+/**/ {{0x3fbac57c, 0xb0ee161b} },
+/**/ {{0xbf9ba92d, 0xefc8f53e} } },
+/**/ {{{0x3fcb8000, 0x00000000} },
+/**/ {{0x3fcb1696, 0x574d780c} },
+/**/ {{0xbc585ab8, 0xfc15a673} },
+/**/ {{0x3fee968e, 0xf0f2da5a} },
+/**/ {{0xbc6fffe1, 0x69710f0d} },
+/**/ {{0xbfc9207a, 0x148444b5} },
+/**/ {{0xbc66661a, 0x1802fa91} },
+/**/ {{0xbfd00d5f, 0xc65096ca} },
+/**/ {{0x3c7f2a2e, 0x8920e744} },
+/**/ {{0x3fc5e617, 0xe4be288d} },
+/**/ {{0x3c67fa48, 0x99be934f} },
+/**/ {{0x3fb66f36, 0xe0d4c87a} },
+/**/ {{0xbfc1cb5f, 0xc5179ce8} },
+/**/ {{0xbf864e9c, 0x1011bb6c} },
+/**/ {{0x3fba841e, 0x43a75476} },
+/**/ {{0xbf9e6e5b, 0x845fc859} } },
+/**/ {{{0x3fcc0000, 0x00000000} },
+/**/ {{0x3fcb90d7, 0x529260a2} },
+/**/ {{0x3c217b10, 0xd2e0e5ab} },
+/**/ {{0x3fee89e6, 0xb5ccf172} },
+/**/ {{0x3c820357, 0x153be26a} },
+/**/ {{0xbfc98046, 0x7f79bfd6} },
+/**/ {{0xbc0799ee, 0xf5d60955} },
+/**/ {{0xbfcfc2b8, 0x650d32f4} },
+/**/ {{0xbc6b59de, 0x4d01b49e} },
+/**/ {{0x3fc61d22, 0xd625e475} },
+/**/ {{0xbc68013f, 0xe23c6105} },
+/**/ {{0x3fb59979, 0x9e54f300} },
+/**/ {{0xbfc1d3b0, 0x365c2b85} },
+/**/ {{0xbf7f6cc9, 0x0afb6b97} },
+/**/ {{0x3fba3c9c, 0x28035c12} },
+/**/ {{0xbfa08f0d, 0x8331488a} } },
+/**/ {{{0x3fcc8000, 0x00000000} },
+/**/ {{0x3fcc0ae5, 0x4d768467} },
+/**/ {{0xbc604cdb, 0xf55f26dc} },
+/**/ {{0x3fee7d0e, 0xd6ad70cb} },
+/**/ {{0x3c8e6761, 0xee20d17d} },
+/**/ {{0xbfc9df09, 0x8ee3fcf8} },
+/**/ {{0x3c62daa3, 0xed723e81} },
+/**/ {{0xbfcf69d9, 0x3efdc9b4} },
+/**/ {{0x3c6c7b6f, 0x85a20110} },
+/**/ {{0x3fc65217, 0x0013c661} },
+/**/ {{0xbc678a0c, 0xab1387be} },
+/**/ {{0x3fb4c369, 0xd61f268e} },
+/**/ {{0xbfc1d922, 0x146d6110} },
+/**/ {{0xbf726199, 0xc0b0ed0a} },
+/**/ {{0x3fb9ef27, 0x6629c856} },
+/**/ {{0xbfa1dbda, 0xc1ea955d} } },
+/**/ {{{0x3fcd0000, 0x00000000} },
+/**/ {{0x3fcc84bf, 0x8a742e6e} },
+/**/ {{0xbc595bdd, 0x0682ea26} },
+/**/ {{0x3fee7007, 0xd8e205ea} },
+/**/ {{0x3c816199, 0x7b2991c1} },
+/**/ {{0xbfca3cc0, 0xc751a854} },
+/**/ {{0xbc66a2fd, 0x4efbc78c} },
+/**/ {{0xbfcf102a, 0x76f43baa} },
+/**/ {{0x3c6cfc38, 0x38d996b1} },
+/**/ {{0x3fc684f3, 0xbf1a9ad6} },
+/**/ {{0x3c52eaf7, 0x7c3b6690} },
+/**/ {{0x3fb3ed29, 0xc4ebba84} },
+/**/ {{0xbfc1dbbd, 0xd79a6a53} },
+/**/ {{0xbf55fa5b, 0xfd09510e} },
+/**/ {{0x3fb99bf2, 0x91c74d50} },
+/**/ {{0xbfa31d41, 0x3002c38b} } },
+/**/ {{{0x3fcd8000, 0x00000000} },
+/**/ {{0x3fccfe65, 0x4e1d5395} },
+/**/ {{0x3c647b9a, 0x3f71eafb} },
+/**/ {{0x3fee62d2, 0x42efd10e} },
+/**/ {{0x3c850a65, 0xa021973e} },
+/**/ {{0xbfca9969, 0xc66a1be4} },
+/**/ {{0x3c326164, 0x3753f036} },
+/**/ {{0xbfceb5b4, 0x6b550477} },
+/**/ {{0xbc64cacb, 0xa3ef610f} },
+/**/ {{0x3fc6b5b8, 0xc4e2c295} },
+/**/ {{0x3c66b228, 0x98b2ac7f} },
+/**/ {{0x3fb316db, 0x3e03bb80} },
+/**/ {{0xbfc1db8c, 0x99312ba1} },
+/**/ {{0x3f5ce5b0, 0x8536556f} },
+/**/ {{0x3fb94331, 0xa9b62abf} },
+/**/ {{0xbfa452f3, 0xb36f42fc} } },
+/**/ {{{0x3fce0000, 0x00000000} },
+/**/ {{0x3fcd77d5, 0xdf205736} },
+/**/ {{0x3c6c648d, 0x1534597e} },
+/**/ {{0x3fee556e, 0x9c86d7c6} },
+/**/ {{0xbc830c25, 0x34c9abfd} },
+/**/ {{0xbfcaf502, 0x42f10c89} },
+/**/ {{0xbc411261, 0xf8576d95} },
+/**/ {{0xbfce5a7f, 0x7b1596d9} },
+/**/ {{0x3c574baa, 0x78f7ae18} },
+/**/ {{0x3fc6e466, 0x171949b1} },
+/**/ {{0xbc6ff86b, 0x52f9c399} },
+/**/ {{0x3fb2409f, 0xa3d6f244} },
+/**/ {{0xbfc1d898, 0x0dceacbf} },
+/**/ {{0x3f73c3b6, 0xdc715080} },
+/**/ {{0x3fb8e519, 0xf78687ab} },
+/**/ {{0xbfa57cac, 0x6b1251ec} } },
+/**/ {{{0x3fce8000, 0x00000000} },
+/**/ {{0x3fcdf110, 0x864c9d9e} },
+/**/ {{0xbc35818b, 0x53bf4781} },
+/**/ {{0x3fee47dd, 0x6e7576a6} },
+/**/ {{0x3c89d322, 0x24b84595} },
+/**/ {{0xbfcb4f88, 0x0cc64717} },
+/**/ {{0xbc624035, 0x44bb97a3} },
+/**/ {{0xbfcdfe94, 0x046e8a3b} },
+/**/ {{0xbc6078ee, 0xd278da00} },
+/**/ {{0x3fc710fc, 0x0e4ccbb7} },
+/**/ {{0xbc58c89c, 0x1da51f71} },
+/**/ {{0x3fb16a97, 0xe0d7022a} },
+/**/ {{0xbfc1d2ea, 0x7f8b58f8} },
+/**/ {{0x3f800ed5, 0xaf259d18} },
+/**/ {{0x3fb881e1, 0xeefd29c7} },
+/**/ {{0xbfa69a2c, 0xae6aa0c1} } },
+/**/ {{{0x3fcf0000, 0x00000000} },
+/**/ {{0x3fce6a14, 0x8e96ec4d} },
+/**/ {{0x3c6866b2, 0x2029f765} },
+/**/ {{0x3fee3a1f, 0x429bd423} },
+/**/ {{0xbc86174a, 0x48961291} },
+/**/ {{0xbfcba8f9, 0x0ce18ad9} },
+/**/ {{0x3c62e3e9, 0xb50eb15d} },
+/**/ {{0xbfcda1fa, 0x63927806} },
+/**/ {{0xbbed7b15, 0x8073bacf} },
+/**/ {{0x3fc73b7b, 0x54b8d3bb} },
+/**/ {{0x3c602afb, 0x74869c1c} },
+/**/ {{0x3fb094e4, 0x60993bd6} },
+/**/ {{0xbfc1ca8e, 0xc806a157} },
+/**/ {{0x3f862263, 0xa854d278} },
+/**/ {{0x3fb819c1, 0x0d9e7452} },
+/**/ {{0xbfa7ab3d, 0x08743869} } },
+/**/ {{{0x3fcf8000, 0x00000000} },
+/**/ {{0x3fcee2e1, 0x451d980d} },
+/**/ {{0xbc59a770, 0x8c46ba91} },
+/**/ {{0x3fee2c34, 0xa3df5666} },
+/**/ {{0xbc8ef949, 0x19a92865} },
+/**/ {{0xbfcc0153, 0x454a9009} },
+/**/ {{0x3c5572bf, 0xda1123ca} },
+/**/ {{0xbfcd44ba, 0xf169cd42} },
+/**/ {{0xbc6db0f2, 0xf1052e0a} },
+/**/ {{0x3fc763e4, 0xe5006ad1} },
+/**/ {{0x3c66e21a, 0x3e902796} },
+/**/ {{0x3faf7f4a, 0x12812c7d} },
+/**/ {{0xbfc1bf90, 0x4a558d9d} },
+/**/ {{0x3f8c1b52, 0x2be7fbfd} },
+/**/ {{0x3fb7acef, 0xba5b0263} },
+/**/ {{0xbfa8afad, 0x2dddf4e5} } },
+/**/ {{{0x3fd00000, 0x00000000} },
+/**/ {{0x3fcf5b75, 0xf92c80dd} },
+/**/ {{0x3c68ab6e, 0x3cf7afbd} },
+/**/ {{0x3fee1e1e, 0x1e1e1e1e} },
+/**/ {{0x3c6e1e1e, 0x1e1e1e1e} },
+/**/ {{0xbfcc5894, 0xd10d4986} },
+/**/ {{0x3c5f00e2, 0xc4a6886a} },
+/**/ {{0xbfcce6de, 0x0253d27e} },
+/**/ {{0xbc65d764, 0x3c5fce89} },
+/**/ {{0x3fc78a3a, 0x08d88b02} },
+/**/ {{0x3c4fc5d6, 0x32bd57e4} },
+/**/ {{0x3fadd5f2, 0x6a622b44} },
+/**/ {{0xbfc1b1fa, 0xecd7c4e0} },
+/**/ {{0x3f90fc3e, 0x1fc8b549} },
+/**/ {{0x3fb73ba7, 0x25728acf} },
+/**/ {{0xbfa9a753, 0xeeba051f} } },
+/**/ {{{0x3fd04000, 0x00000000} },
+/**/ {{0x3fcfd3d1, 0xfc40dbe4} },
+/**/ {{0x3c437146, 0xf3a1c5ea} },
+/**/ {{0x3fee0fdc, 0x3e228818} },
+/**/ {{0xbc62e075, 0x8c042ef5} },
+/**/ {{0xbfccaebb, 0xe42a71b9} },
+/**/ {{0xbc69fa0a, 0x8025fd1d} },
+/**/ {{0xbfcc886b, 0xe4ed28e5} },
+/**/ {{0xbc59ccc3, 0x7604b95a} },
+/**/ {{0x3fc7ae7c, 0x57a32fb9} },
+/**/ {{0x3c67393b, 0xe36848c2} },
+/**/ {{0x3fac2dff, 0x5a1b7b6f} },
+/**/ {{0xbfc1a1db, 0x12f690d4} },
+/**/ {{0x3f93dc65, 0xa575dc1d} },
+/**/ {{0x3fb6c621, 0x28a107f6} },
+/**/ {{0xbfaa920f, 0x23d2c35f} } },
+/**/ {{{0x3fd08000, 0x00000000} },
+/**/ {{0x3fd025fa, 0x510665b6} },
+/**/ {{0xbc7672df, 0x6832fa48} },
+/**/ {{0x3fee016f, 0x9196b776} },
+/**/ {{0x3c81da3a, 0xb14efc08} },
+/**/ {{0xbfcd03c6, 0xcb847375} },
+/**/ {{0xbc6819f2, 0xfc4c6f52} },
+/**/ {{0xbfcc296c, 0xe0dbf8a5} },
+/**/ {{0xbc55cc84, 0x27fb1c17} },
+/**/ {{0x3fc7d0ad, 0xb4fbbf40} },
+/**/ {{0x3c6378b3, 0x41b71641} },
+/**/ {{0x3faa87ad, 0x440404cd} },
+/**/ {{0xbfc18f3d, 0x96d156a8} },
+/**/ {{0x3f96ad9b, 0x9ef40490} },
+/**/ {{0x3fb64c98, 0x27a95e14} },
+/**/ {{0xbfab6fc3, 0x97cfdce0} } },
+/**/ {{{0x3fd0c000, 0x00000000} },
+/**/ {{0x3fd061ee, 0xa03d6291} },
+/**/ {{0xbc45f760, 0xdb154301} },
+/**/ {{0x3fedf2d8, 0xa6f82a61} },
+/**/ {{0xbc6cedbb, 0x560866af} },
+/**/ {{0xbfcd57b3, 0xecc8c02c} },
+/**/ {{0x3c641512, 0x85b9541c} },
+/**/ {{0xbfcbc9e9, 0x35a209c0} },
+/**/ {{0x3c65bfd8, 0x4914a5d1} },
+/**/ {{0x3fc7f0d0, 0x4f358b07} },
+/**/ {{0xbc60dc70, 0x3f47a5cc} },
+/**/ {{0x3fa8e337, 0x50af01c1} },
+/**/ {{0xbfc17a2f, 0xc2daf61b} },
+/**/ {{0x3f996f63, 0x57b649f0} },
+/**/ {{0x3fb5cf46, 0xf14fef28} },
+/**/ {{0xbfac405c, 0xec5a22c2} } },
+/**/ {{{0x3fd10000, 0x00000000} },
+/**/ {{0x3fd09dc5, 0x97d86362} },
+/**/ {{0x3c762e47, 0x390cb865} },
+/**/ {{0x3fede418, 0x0d8b5ae6} },
+/**/ {{0x3c719298, 0x23f66cf0} },
+/**/ {{0xbfcdaa81, 0xc655a596} },
+/**/ {{0x3c666d0d, 0x6a90480b} },
+/**/ {{0xbfcb69e9, 0x1974fd6c} },
+/**/ {{0xbc68e199, 0xec28723f} },
+/**/ {{0x3fc80ee6, 0x9dcd2641} },
+/**/ {{0x3c37ccfe, 0x45b4bb82} },
+/**/ {{0x3fa740d7, 0x64b143be} },
+/**/ {{0xbfc162bf, 0x4b6b7330} },
+/**/ {{0x3f9c2147, 0x7a20d203} },
+/**/ {{0x3fb54e68, 0xa0d6b625} },
+/**/ {{0xbfad03cd, 0x7b6e81ad} } },
+/**/ {{{0x3fd14000, 0x00000000} },
+/**/ {{0x3fd0d97e, 0xe509acb3} },
+/**/ {{0x3c747c31, 0x7bd5a3eb} },
+/**/ {{0x3fedd52e, 0x554f6dcf} },
+/**/ {{0xbc75c686, 0xddcd060b} },
+/**/ {{0xbfcdfc2e, 0xef1cb578} },
+/**/ {{0xbc46ae20, 0xd1677d50} },
+/**/ {{0xbfcb0974, 0xb81cdb34} },
+/**/ {{0x3c36ed8e, 0xda61c86c} },
+/**/ {{0x3fc82af3, 0x5fcd53c1} },
+/**/ {{0xbc424fe5, 0x57b559e7} },
+/**/ {{0x3fa5a0c6, 0x17013aef} },
+/**/ {{0xbfc148fa, 0x484940dd} },
+/**/ {{0x3f9ec2da, 0x1737ca6d} },
+/**/ {{0x3fb4ca38, 0x800ba495} },
+/**/ {{0xbfadba0e, 0x35128042} } },
+/**/ {{{0x3fd18000, 0x00000000} },
+/**/ {{0x3fd1151a, 0x362431ca} },
+/**/ {{0xbc74dc8d, 0xc9077b9f} },
+/**/ {{0x3fedc61c, 0x0ef1f116} },
+/**/ {{0xbc8fe39f, 0x2d41c166} },
+/**/ {{0xbfce4cba, 0x1681d2c9} },
+/**/ {{0x3c340fb4, 0x369a3c18} },
+/**/ {{0xbfcaa894, 0x31d921e2} },
+/**/ {{0x3c6bf59e, 0x64c48da4} },
+/**/ {{0x3fc844f9, 0x9a284cea} },
+/**/ {{0xbc563be0, 0x629cfeb8} },
+/**/ {{0x3fa4033a, 0xa7f26285} },
+/**/ {{0xbfc12cef, 0x2e2d72ea} },
+/**/ {{0x3fa0a9da, 0x554d151d} },
+/**/ {{0x3fb442f1, 0xe9f9174f} },
+/**/ {{0xbfae631e, 0x799e467c} } },
+/**/ {{{0x3fd1c000, 0x00000000} },
+/**/ {{0x3fd15097, 0x3a9ce547} },
+/**/ {{0xbc7796ba, 0x7f9ca328} },
+/**/ {{0x3fedb6e1, 0xcbc2abaa} },
+/**/ {{0xbc823b7a, 0xc39a4e7c} },
+/**/ {{0xbfce9c22, 0x0436f806} },
+/**/ {{0xbc64a5ec, 0x885803cb} },
+/**/ {{0xbfca474f, 0x9a4c8963} },
+/**/ {{0x3c671cf3, 0x6793b663} },
+/**/ {{0x3fc85cfc, 0x9606243b} },
+/**/ {{0x3c5fd2b2, 0x1dcd45ed} },
+/**/ {{0x3fa2686a, 0xf8cc655f} },
+/**/ {{0xbfc10eac, 0xc8460b94} },
+/**/ {{0x3fa1e9bc, 0x0d6eb5ba} },
+/**/ {{0x3fb3b8d0, 0x2e4749c2} },
+/**/ {{0xbfaeff03, 0xf0d19201} } },
+/**/ {{{0x3fd20000, 0x00000000} },
+/**/ {{0x3fd18bf5, 0xa30bf178} },
+/**/ {{0x3c630ca4, 0x748b1bf9} },
+/**/ {{0x3feda780, 0x1da7801e} },
+/**/ {{0xbc861ff8, 0x961ff896} },
+/**/ {{0xbfceea65, 0x9814cb11} },
+/**/ {{0xbc5f9845, 0x34cb01ca} },
+/**/ {{0xbfc9e5ae, 0xf76f9fa1} },
+/**/ {{0x3c688b7a, 0xa3ee6a86} },
+/**/ {{0x3fc872ff, 0xdf090624} },
+/**/ {{0x3c31016f, 0x6fbad4bb} },
+/**/ {{0x3fa0d08b, 0x83fe02bc} },
+/**/ {{0xbfc0ee42, 0x31b98637} },
+/**/ {{0x3fa320e6, 0x5b309f28} },
+/**/ {{0x3fb32c0e, 0x755cbc43} },
+/**/ {{0xbfaf8dca, 0x5dea1ddb} } },
+/**/ {{{0x3fd24000, 0x00000000} },
+/**/ {{0x3fd1c735, 0x212dd884} },
+/**/ {{0xbc67d9ac, 0x78cb2f2e} },
+/**/ {{0x3fed97f7, 0x971063d2} },
+/**/ {{0x3c67a20b, 0xc8b326b7} },
+/**/ {{0xbfcf3783, 0xc9f01359} },
+/**/ {{0x3c4a8b96, 0xd0a651ad} },
+/**/ {{0xbfc983ba, 0x408a6757} },
+/**/ {{0x3c6dfff9, 0xe6424f06} },
+/**/ {{0x3fc88707, 0x41881aad} },
+/**/ {{0xbc63baf9, 0x2204fd29} },
+/**/ {{0x3f9e779e, 0xabd6e10d} },
+/**/ {{0xbfc0cbbe, 0xcf2eab41} },
+/**/ {{0x3fa44f31, 0x1659f377} },
+/**/ {{0x3fb29ce7, 0xa54a8a94} },
+/**/ {{0xbfb007c1, 0xb87973d7} } },
+/**/ {{{0x3fd28000, 0x00000000} },
+/**/ {{0x3fd20255, 0x67e47c96} },
+/**/ {{0xbc618323, 0x28f4290e} },
+/**/ {{0x3fed8848, 0xcaeb6c2a} },
+/**/ {{0x3c81e70d, 0xa08296a2} },
+/**/ {{0xbfcf837b, 0xa96c2792} },
+/**/ {{0xbc6ab5ce, 0xc6884369} },
+/**/ {{0xbfc92179, 0x5d351cdb} },
+/**/ {{0x3c617000, 0x68719d81} },
+/**/ {{0x3fc89916, 0xc8c1ca07} },
+/**/ {{0xbc6a3339, 0x18b0f81b} },
+/**/ {{0x3f9b54d0, 0x0caf6121} },
+/**/ {{0xbfc0a732, 0x485ba392} },
+/**/ {{0x3fa57477, 0xc250c31e} },
+/**/ {{0x3fb20b96, 0x4790b4a8} },
+/**/ {{0xbfb04223, 0x4ac23178} } },
+/**/ {{{0x3fd2c000, 0x00000000} },
+/**/ {{0x3fd23d56, 0x2b381042} },
+/**/ {{0xbc5c5317, 0x16200088} },
+/**/ {{0x3fed7874, 0x4c98f347} },
+/**/ {{0xbc8a7dac, 0x9a72647e} },
+/**/ {{0xbfcfce4c, 0x5dca68a2} },
+/**/ {{0x3c6433de, 0x8fb9ffdd} },
+/**/ {{0xbfc8bef4, 0x246041ce} },
+/**/ {{0xbc66c620, 0x1fb39160} },
+/**/ {{0x3fc8a932, 0xbd062535} },
+/**/ {{0xbc6e24c7, 0xfbc3a86c} },
+/**/ {{0x3f98390b, 0x64d0109d} },
+/**/ {{0xbfc080ac, 0x819f2998} },
+/**/ {{0x3fa69099, 0x8784ffb8} },
+/**/ {{0x3fb17854, 0x6fc55e9b} },
+/**/ {{0xbfb07618, 0x5f970a81} } },
+/**/ {{{0x3fd30000, 0x00000000} },
+/**/ {{0x3fd27837, 0x2057ef46} },
+/**/ {{0xbc7077cd, 0xd36dfc81} },
+/**/ {{0x3fed687a, 0xafdfd5ba} },
+/**/ {{0xbc782e68, 0xe19d8d3d} },
+/**/ {{0xbfd00bfa, 0x92db6fdb} },
+/**/ {{0x3c7854cd, 0xc0af523f} },
+/**/ {{0xbfc85c32, 0x5b640da2} },
+/**/ {{0x3c5d5bdd, 0x5e6f23d6} },
+/**/ {{0x3fc8b75f, 0xa1da32d2} },
+/**/ {{0x3c2788df, 0x29860bfe} },
+/**/ {{0x3f9524ad, 0xee810d60} },
+/**/ {{0xbfc0583d, 0x95a69dea} },
+/**/ {{0x3fa7a379, 0x2b4d3dec} },
+/**/ {{0x3fb0e35b, 0xa3290dfe} },
+/**/ {{0xbfb0a3b2, 0x19e12287} } },
+/**/ {{{0x3fd34000, 0x00000000} },
+/**/ {{0x3fd2b2f7, 0xfd9b5fe2} },
+/**/ {{0x3c2423cf, 0xc1c2d443} },
+/**/ {{0x3fed585c, 0x88e1caa2} },
+/**/ {{0xbc2c8af2, 0x01239e18} },
+/**/ {{0xbfd0303a, 0xab890af7} },
+/**/ {{0x3c7d42bf, 0x726290e6} },
+/**/ {{0xbfc7f93b, 0xb5175de0} },
+/**/ {{0x3c5d5d4b, 0xe0ddc367} },
+/**/ {{0x3fc8c3a2, 0x3414de7c} },
+/**/ {{0x3c5ade9b, 0xba92bfce} },
+/**/ {{0x3f921811, 0xda70853d} },
+/**/ {{0xbfc02df5, 0xcf23aaf0} },
+/**/ {{0x3fa8acfd, 0x06445ff8} },
+/**/ {{0x3fb04ce4, 0xc130eba4} },
+/**/ {{0xbfb0cb04, 0x29de3135} } },
+/**/ {{{0x3fd38000, 0x00000000} },
+/**/ {{0x3fd2ed98, 0x7a823cfe} },
+/**/ {{0x3c6b9125, 0x8ea012ca} },
+/**/ {{0x3fed481a, 0x6c0fd782} },
+/**/ {{0x3c82dda4, 0x85ff74ea} },
+/**/ {{0xbfd053e6, 0x2f5c1e18} },
+/**/ {{0xbc679cf2, 0x8ec637b8} },
+/**/ {{0xbfc79617, 0xd0ee3e3b} },
+/**/ {{0xbc4e91e0, 0x732049a6} },
+/**/ {{0x3fc8cdff, 0x67f6478d} },
+/**/ {{0xbc5cb659, 0xf5079e63} },
+/**/ {{0x3f8e271c, 0x8e8ef686} },
+/**/ {{0xbfc001e5, 0xa2940881} },
+/**/ {{0x3fa9ad0e, 0xf937caae} },
+/**/ {{0x3faf6a4f, 0xda1e257f} },
+/**/ {{0xbfb0ec24, 0xb07d42be} } },
+/**/ {{{0x3fd3c000, 0x00000000} },
+/**/ {{0x3fd32818, 0x4fb58952} },
+/**/ {{0xbc7a95f0, 0xa9939f2f} },
+/**/ {{0x3fed37b4, 0xee1ee130} },
+/**/ {{0x3c747541, 0x6fbb1f2d} },
+/**/ {{0xbfd076fc, 0xe022dd0d} },
+/**/ {{0x3c6d8659, 0x5534523a} },
+/**/ {{0xbfc732ce, 0x3a201d6b} },
+/**/ {{0xbc56a551, 0xc98a3a62} },
+/**/ {{0x3fc8d67c, 0x673a29b8} },
+/**/ {{0xbc54ae9d, 0xff95efe6} },
+/**/ {{0x3f882eee, 0x74ce6814} },
+/**/ {{0xbfbfa83b, 0x503ba8f4} },
+/**/ {{0x3faaa39c, 0x60b63f75} },
+/**/ {{0x3fae38b8, 0xf07ff274} },
+/**/ {{0xbfb1072c, 0x2200fe4d} } },
+/**/ {{{0x3fd40000, 0x00000000} },
+/**/ {{0x3fd36277, 0x3707ebcc} },
+/**/ {{0xbc6963a5, 0x44b672d8} },
+/**/ {{0x3fed272c, 0xa3fc5b1a} },
+/**/ {{0x3c8ae01d, 0x272ca3fc} },
+/**/ {{0xbfd0997e, 0x8aec9d8e} },
+/**/ {{0x3c74aeda, 0x72595f36} },
+/**/ {{0xbfc6cf66, 0x66d5c0ff} },
+/**/ {{0x3c410e2a, 0x3ca66cc1} },
+/**/ {{0x3fc8dd1e, 0x8f2617b5} },
+/**/ {{0xbc6d173e, 0x4facfb67} },
+/**/ {{0x3f82483b, 0x33966883} },
+/**/ {{0xbfbf495d, 0x2b05b16b} },
+/**/ {{0x3fab9096, 0x074fdeaf} },
+/**/ {{0x3fad0571, 0x9c4605c9} },
+/**/ {{0xbfb11c35, 0x280318fd} } },
+/**/ {{{0x3fd44000, 0x00000000} },
+/**/ {{0x3fd39cb4, 0xeb76157c} },
+/**/ {{0xbc72f4da, 0x5a214713} },
+/**/ {{0x3fed1682, 0x22c31625} },
+/**/ {{0x3c8ac111, 0xd5e51b41} },
+/**/ {{0xbfd0bb6b, 0x07e9a89a} },
+/**/ {{0x3c76fb53, 0x7faa1dda} },
+/**/ {{0xbfc66be7, 0xb75f0772} },
+/**/ {{0xbc69a77d, 0xee6d618b} },
+/**/ {{0x3fc8e1eb, 0x6e943d69} },
+/**/ {{0xbc6982c4, 0xc5ec9ebe} },
+/**/ {{0x3f78e73c, 0x9c2d3c0c} },
+/**/ {{0xbfbee752, 0x7059f387} },
+/**/ {{0x3fac73f0, 0x16982f58} },
+/**/ {{0x3fabd0e4, 0xc146b407} },
+/**/ {{0xbfb12b5c, 0x82f43254} } },
+/**/ {{{0x3fd48000, 0x00000000} },
+/**/ {{0x3fd3d6d1, 0x29271134} },
+/**/ {{0x3c7137ca, 0x41cc958a} },
+/**/ {{0x3fed05b5, 0xffb0304c} },
+/**/ {{0xbc8fc921, 0x33e896e5} },
+/**/ {{0xbfd0dcc2, 0x3a49e254} },
+/**/ {{0x3c704578, 0x925cb599} },
+/**/ {{0xbfc60859, 0x75708502} },
+/**/ {{0xbc5f88bc, 0x9feebe6c} },
+/**/ {{0x3fc8e4e8, 0xc3fb5c1c} },
+/**/ {{0x3c6de114, 0xd6b77a05} },
+/**/ {{0x3f6ac6b3, 0xdbc6c857} },
+/**/ {{0xbfbe823c, 0xdeabd793} },
+/**/ {{0x3fad4da2, 0x06fb52a7} },
+/**/ {{0x3faa9b7b, 0x2bea698c} },
+/**/ {{0xbfb134c0, 0xeb32d745} } },
+/**/ {{{0x3fd4c000, 0x00000000} },
+/**/ {{0x3fd410cb, 0xad6c7d33} },
+/**/ {{0xbc7b0c8b, 0xae13b512} },
+/**/ {{0x3fecf4c8, 0xd0182625} },
+/**/ {{0x3c8e6308, 0xf4103798} },
+/**/ {{0xbfd0fd84, 0x101a5438} },
+/**/ {{0x3c425fcd, 0x7d2e3e34} },
+/**/ {{0xbfc5a4c2, 0xd36904f6} },
+/**/ {{0x3c5d3583, 0x54f27bb6} },
+/**/ {{0x3fc8e61c, 0x7b74b00c} },
+/**/ {{0x3c32f7ad, 0xefe568b6} },
+/**/ {{0x3f402f60, 0xaa3667f2} },
+/**/ {{0xbfbe1a3e, 0x4c9859c0} },
+/**/ {{0x3fae1da6, 0x8e77c589} },
+/**/ {{0x3fa9659b, 0x6ed5823e} },
+/**/ {{0xbfb13882, 0xf1d3d420} } },
+/**/ {{{0x3fd50000, 0x00000000} },
+/**/ {{0x3fd44aa4, 0x36c2af0a} },
+/**/ {{0xbc75d5e4, 0x3c55b3ba} },
+/**/ {{0x3fece3bb, 0x295c0773} },
+/**/ {{0xbc826fd5, 0x91851b41} },
+/**/ {{0xbfd11db0, 0x8221a582} },
+/**/ {{0x3c7e9654, 0xa9f31d11} },
+/**/ {{0xbfc5412a, 0xeb9ef661} },
+/**/ {{0x3c573faf, 0x5e60433c} },
+/**/ {{0x3fc8e58c, 0xacc06b3a} },
+/**/ {{0xbc5dba9a, 0x64dd81ed} },
+/**/ {{0xbf625ff7, 0xcfe3f01e} },
+/**/ {{0xbfbdaf78, 0x9dae4b1c} },
+/**/ {{0x3faee3fb, 0x8e4e3e16} },
+/**/ {{0x3fa82fa9, 0xc2c60fed} },
+/**/ {{0xbfb136c4, 0xe13555d9} } },
+/**/ {{{0x3fd54000, 0x00000000} },
+/**/ {{0x3fd4845a, 0x84d0c21b} },
+/**/ {{0x3c71e28a, 0x7563c6a6} },
+/**/ {{0x3fecd28d, 0xa0decfad} },
+/**/ {{0xbc72b2c8, 0x49610c12} },
+/**/ {{0xbfd13d47, 0x93bb8da8} },
+/**/ {{0x3c5df07a, 0x1b48d912} },
+/**/ {{0xbfc4dd98, 0xbfb5c8b7} },
+/**/ {{0x3c58a9ff, 0x39a108d7} },
+/**/ {{0x3fc8e33f, 0x99496dc4} },
+/**/ {{0x3c380d8b, 0x19d3995c} },
+/**/ {{0xbf743d59, 0xba1bc2d2} },
+/**/ {{0xbfbd420d, 0xb77862a1} },
+/**/ {{0x3fafa0a1, 0xffb9511c} },
+/**/ {{0x3fa6fa07, 0xe8a86cad} },
+/**/ {{0xbfb12faa, 0x9d75a109} } },
+/**/ {{{0x3fd58000, 0x00000000} },
+/**/ {{0x3fd4bdee, 0x586890e7} },
+/**/ {{0xbc6e4dc7, 0x7c22a757} },
+/**/ {{0x3fecc140, 0xcbfae3a7} },
+/**/ {{0xbc41045d, 0xd8b6f9b9} },
+/**/ {{0xbfd15c49, 0x52b34cdc} },
+/**/ {{0x3c729992, 0x2daa60ac} },
+/**/ {{0xbfc47a13, 0x37fb39ef} },
+/**/ {{0x3c5cb3b2, 0x3482d371} },
+/**/ {{0x3fc8df3b, 0xaa28e022} },
+/**/ {{0xbc61a8ab, 0x969a5447} },
+/**/ {{0xbf7f2135, 0xc651ecb4} },
+/**/ {{0xbfbcd21f, 0x76cc63f7} },
+/**/ {{0x3fb029ce, 0xefdf4de1} },
+/**/ {{0x3fa5c515, 0x0de3bf96} },
+/**/ {{0xbfb12359, 0x84e55ab4} } },
+/**/ {{{0x3fd5c000, 0x00000000} },
+/**/ {{0x3fd4f75f, 0x73869979} },
+/**/ {{0xbc595a1c, 0xf7ff1108} },
+/**/ {{0x3fecafd5, 0x3ff7b52c} },
+/**/ {{0x3c86e099, 0x684b6314} },
+/**/ {{0xbfd17ab5, 0xd71d366e} },
+/**/ {{0x3c602f2c, 0xae2f7b71} },
+/**/ {{0xbfc416a1, 0x22cc956f} },
+/**/ {{0x3c61d29e, 0xe98c24c1} },
+/**/ {{0x3fc8d987, 0x6e2a4f9f} },
+/**/ {{0xbc60de73, 0x4a6a7880} },
+/**/ {{0xbf84ed52, 0x909e42ec} },
+/**/ {{0xbfbc5fcf, 0xa56263a8} },
+/**/ {{0x3fb07e7b, 0x0d159803} },
+/**/ {{0x3fa4912d, 0xb2ddf20b} },
+/**/ {{0xbfb111f8, 0x508c8585} } },
+/**/ {{{0x3fd60000, 0x00000000} },
+/**/ {{0x3fd530ad, 0x9951cd4a} },
+/**/ {{0xbc625664, 0x80884082} },
+/**/ {{0x3fec9e4b, 0x91ff8d87} },
+/**/ {{0xbc7723ff, 0x1b0da370} },
+/**/ {{0xbfd1988d, 0x432f5908} },
+/**/ {{0x3c7d065e, 0xf8714cda} },
+/**/ {{0xbfc3b349, 0x3403e07c} },
+/**/ {{0x3c6b571d, 0x2717fbb0} },
+/**/ {{0x3fc8d229, 0x97d0e938} },
+/**/ {{0x3c66b228, 0xb08a0625} },
+/**/ {{0xbf8a3464, 0xc2fe9cde} },
+/**/ {{0xbfbbeb3f, 0xefb6f244} },
+/**/ {{0x3fb0ce5a, 0x39e67c0b} },
+/**/ {{0x3fa35eab, 0x93b4fb73} },
+/**/ {{0xbfb0fbae, 0xf4d86f78} } },
+/**/ {{{0x3fd64000, 0x00000000} },
+/**/ {{0x3fd569d8, 0x8e1b4cd8} },
+/**/ {{0xbc6fec61, 0xe713cfe2} },
+/**/ {{0x3fec8ca4, 0x57157fc9} },
+/**/ {{0x3c70da14, 0x515734ba} },
+/**/ {{0xbfd1b5cf, 0xc3195094} },
+/**/ {{0x3c740cce, 0xa9537e45} },
+/**/ {{0xbfc35012, 0x046cee83} },
+/**/ {{0xbc651b6c, 0xe446fd10} },
+/**/ {{0x3fc8c928, 0xfb5e6a95} },
+/**/ {{0x3c656cd2, 0x82469bf3} },
+/**/ {{0xbf8f6568, 0xa4afbb1b} },
+/**/ {{0xbfbb7491, 0xdb3aba50} },
+/**/ {{0x3fb11972, 0xb9fd56ec} },
+/**/ {{0x3fa22de5, 0x9329e15e} },
+/**/ {{0xbfb0e0a6, 0x8287d93d} } },
+/**/ {{{0x3fd68000, 0x00000000} },
+/**/ {{0x3fd5a2e0, 0x175e0f4e} },
+/**/ {{0x3c713b7a, 0x8f82e457} },
+/**/ {{0x3fec7ae0, 0x240b83ae} },
+/**/ {{0xbc885b56, 0x10d398ed} },
+/**/ {{0xbfd1d27d, 0x8cdb4db0} },
+/**/ {{0x3c11d95f, 0x2db0447f} },
+/**/ {{0xbfc2ed02, 0x11425541} },
+/**/ {{0xbc11d124, 0x6b2cbaa3} },
+/**/ {{0x3fc8be8c, 0x8cdc5c4d} },
+/**/ {{0xbc542511, 0x794444b0} },
+/**/ {{0xbf923ffd, 0xd25a5415} },
+/**/ {{0xbfbafbe6, 0xbcd1df44} },
+/**/ {{0x3fb15fcc, 0x26bdf05c} },
+/**/ {{0x3fa0ff2f, 0xa7b853e6} },
+/**/ {{0xbfb0c109, 0x07e9a35f} } },
+/**/ {{{0x3fd6c000, 0x00000000} },
+/**/ {{0x3fd5dbc3, 0xfbbe768d} },
+/**/ {{0x3c6ea0ec, 0x1b76f7da} },
+/**/ {{0x3fec68ff, 0x8d78b9ce} },
+/**/ {{0xbc83ab41, 0x4cb5a0c3} },
+/**/ {{0xbfd1ee96, 0xe01c5e6e} },
+/**/ {{0x3c73922c, 0xfb76d8dd} },
+/**/ {{0xbfc28a1f, 0xbbb23677} },
+/**/ {{0x3c6e592a, 0x288601f2} },
+/**/ {{0x3fc8b25b, 0x5e282403} },
+/**/ {{0xbbef7d58, 0x707e09fa} },
+/**/ {{0xbf94c1e0, 0xb65add31} },
+/**/ {{0xbfba815f, 0xafa52f1b} },
+/**/ {{0x3fb1a16f, 0x63712acc} },
+/**/ {{0x3f9fa5b5, 0x95a8d3ad} },
+/**/ {{0xbfb09d01, 0x72814750} } },
+/**/ {{{0x3fd70000, 0x00000000} },
+/**/ {{0x3fd61484, 0x0309cfe2} },
+/**/ {{0xbc7a7257, 0x15711f00} },
+/**/ {{0x3fec5703, 0x27afd9eb} },
+/**/ {{0x3c63c2ab, 0xb32c1d72} },
+/**/ {{0xbfd20a1c, 0x06000419} },
+/**/ {{0xbc7b5fe7, 0xf51a3a28} },
+/**/ {{0xbfc22771, 0x486ad2c8} },
+/**/ {{0xbc499ab5, 0xf84a7eae} },
+/**/ {{0x3fc8a49c, 0x9d027817} },
+/**/ {{0xbc53fcab, 0x2e376ecc} },
+/**/ {{0xbf973831, 0xeaabcb23} },
+/**/ {{0xbfba051d, 0x8c46fbce} },
+/**/ {{0x3fb1de66, 0x9132e9cc} },
+/**/ {{0x3f9d5269, 0xd48d5d65} },
+/**/ {{0xbfb074bb, 0x712354a4} } },
+/**/ {{{0x3fd74000, 0x00000000} },
+/**/ {{0x3fd64d1f, 0xf635c1c6} },
+/**/ {{0xbc7fa403, 0xe7c0fdbe} },
+/**/ {{0x3fec44eb, 0x86b5cbf8} },
+/**/ {{0xbc6a4101, 0xbc5b562d} },
+/**/ {{0xbfd2250d, 0x50fb21ad} },
+/**/ {{0xbc750066, 0xa39bdc1a} },
+/**/ {{0xbfc1c4fc, 0xdf2ed728} },
+/**/ {{0x3c6a87bb, 0x006772e9} },
+/**/ {{0x3fc89557, 0x9122b9b7} },
+/**/ {{0xbc05454e, 0x45b04f75} },
+/**/ {{0xbf99a2c9, 0x6c7888f1} },
+/**/ {{0xbfb98740, 0xe02d36ad} },
+/**/ {{0x3fb216bd, 0x02a99665} },
+/**/ {{0x3f9b0511, 0xb73aeccb} },
+/**/ {{0xbfb04863, 0x569b1738} } },
+/**/ {{{0x3fd78000, 0x00000000} },
+/**/ {{0x3fd68597, 0x9f5fa6fe} },
+/**/ {{0xbc425781, 0x4d1ada9c} },
+/**/ {{0x3fec32b9, 0x3e386c7f} },
+/**/ {{0x3c756033, 0x8cbaa5bf} },
+/**/ {{0xbfd23f6b, 0x1ca84e79} },
+/**/ {{0x3c604cc0, 0xf123d574} },
+/**/ {{0xbfc162c8, 0x8a715435} },
+/**/ {{0x3c5cf6db, 0x454fb8fd} },
+/**/ {{0x3fc88493, 0x9a4eb534} },
+/**/ {{0xbc668a5c, 0x42b959b0} },
+/**/ {{0xbf9c0182, 0x42580bb5} },
+/**/ {{0xbfb907e9, 0xe5822d56} },
+/**/ {{0x3fb24a7f, 0x2f8f8273} },
+/**/ {{0x3f98be3c, 0xa3527f46} },
+/**/ {{0xbfb01825, 0xfce97270} } },
+/**/ {{{0x3fd7c000, 0x00000000} },
+/**/ {{0x3fd6bdea, 0xc9cbd76d} },
+/**/ {{0xbc5a5c56, 0x3e6de828} },
+/**/ {{0x3fec206c, 0xe1857d04} },
+/**/ {{0xbc80439f, 0xf5c83872} },
+/**/ {{0xbfd25935, 0xcd9b9870} },
+/**/ {{0x3c6aaf98, 0xf1ec7306} },
+/**/ {{0xbfc100da, 0x36f94d02} },
+/**/ {{0xbc6e72ca, 0xd96d84ff} },
+/**/ {{0x3fc87258, 0x2e774351} },
+/**/ {{0x3c6c50a2, 0xb8860ef0} },
+/**/ {{0xbf9e543a, 0x741ef0ec} },
+/**/ {{0xbfb88738, 0x7b4d0ec2} },
+/**/ {{0x3fb279ba, 0xa8164103} },
+/**/ {{0x3f967e73, 0xa7f1ae35} },
+/**/ {{0xbfafc861, 0x5257c3de} } },
+/**/ {{{0x3fd80000, 0x00000000} },
+/**/ {{0x3fd6f619, 0x41e4def1} },
+/**/ {{0xbc7c63aa, 0xe6f6e918} },
+/**/ {{0x3fec0e07, 0x0381c0e0} },
+/**/ {{0x3c8c0e07, 0x0381c0e0} },
+/**/ {{0xbfd2726d, 0xd135c174} },
+/**/ {{0xbc2d352d, 0xe0951cf8} },
+/**/ {{0xbfc09f37, 0xb38cc8cf} },
+/**/ {{0xbc69db81, 0xae75327f} },
+/**/ {{0x3fc85eac, 0xd7da413c} },
+/**/ {{0x3c5b1a89, 0x6ebae2bc} },
+/**/ {{0xbfa04d69, 0x80fcc815} },
+/**/ {{0xbfb8054c, 0x1df326f9} },
+/**/ {{0x3fb2a47e, 0x082bda60} },
+/**/ {{0x3f944639, 0x7091d5a4} },
+/**/ {{0xbfaf5961, 0xe072e48c} } },
+/**/ {{{0x3fd84000, 0x00000000} },
+/**/ {{0x3fd72e22, 0xd53aa2aa} },
+/**/ {{0xbc7d9c93, 0x4e79f27c} },
+/**/ {{0x3febfb88, 0x36a04729} },
+/**/ {{0xbc872745, 0x9ac2ea21} },
+/**/ {{0xbfd28b13, 0x9d7702cf} },
+/**/ {{0x3c7819b9, 0x4be8bff6} },
+/**/ {{0xbfc03de6, 0xb0a35176} },
+/**/ {{0x3c5dbfb0, 0xc83347af} },
+/**/ {{0x3fc84999, 0x332a4f86} },
+/**/ {{0x3c5d304e, 0x0a22d12d} },
+/**/ {{0xbfa16a97, 0xed6b2d30} },
+/**/ {{0xbfb78243, 0xe0128950} },
+/**/ {{0x3fb2cad8, 0xeaa98f57} },
+/**/ {{0x3f92160a, 0x3bb39c5b} },
+/**/ {{0xbfaee3a9, 0x3804caa3} } },
+/**/ {{{0x3fd88000, 0x00000000} },
+/**/ {{0x3fd76607, 0x52817502} },
+/**/ {{0xbc4dd117, 0x91cc7600} },
+/**/ {{0x3febe8f1, 0x0cd9e1fe} },
+/**/ {{0xbc7a9688, 0xa21e102a} },
+/**/ {{0xbfd2a327, 0xb0d161e9} },
+/**/ {{0xbc60a2a9, 0x14b44140} },
+/**/ {{0xbfbfb9d9, 0x803f8d3b} },
+/**/ {{0x3c5e5779, 0x2a5c4097} },
+/**/ {{0x3fc83324, 0xedbcc363} },
+/**/ {{0x3c651fbc, 0xa0442744} },
+/**/ {{0xbfa2819b, 0xe91477c3} },
+/**/ {{0xbfb6fe3e, 0x63b6abf0} },
+/**/ {{0x3fb2ecdb, 0xdc73a89a} },
+/**/ {{0x3f8fdcb7, 0xaa755298} },
+/**/ {{0xbfae6793, 0x237c2f3d} } },
+/**/ {{{0x3fd8c000, 0x00000000} },
+/**/ {{0x3fd79dc6, 0x899118d1} },
+/**/ {{0x3c2b7413, 0xa0ef606d} },
+/**/ {{0x3febd642, 0x17a4cbc3} },
+/**/ {{0xbc55ee5d, 0x3200a548} },
+/**/ {{0xbfd2baaa, 0x91faa133} },
+/**/ {{0xbc6bd391, 0xfaf41548} },
+/**/ {{0xbfbef89e, 0xaa22d832} },
+/**/ {{0x3c413b3b, 0xc874fdb9} },
+/**/ {{0x3fc81b57, 0xc3be300a} },
+/**/ {{0x3c6baf9b, 0xc01a615f} },
+/**/ {{0xbfa3926a, 0x4a872ec7} },
+/**/ {{0xbfb67959, 0xd3e743cd} },
+/**/ {{0x3fb30a98, 0x4f919505} },
+/**/ {{0x3f8b9f3b, 0x28b78b08} },
+/**/ {{0xbfade57b, 0x71e33e9d} } },
+/**/ {{{0x3fd90000, 0x00000000} },
+/**/ {{0x3fd7d560, 0x4b63b3f7} },
+/**/ {{0x3c769c88, 0x5c2b249a} },
+/**/ {{0x3febc37b, 0xe7ec7a8d} },
+/**/ {{0xbc6f1246, 0x2b0e2727} },
+/**/ {{0xbfd2d19c, 0xcfbdd7fa} },
+/**/ {{0x3c7d0b11, 0x5e00c582} },
+/**/ {{0xbfbe3827, 0x86f8309b} },
+/**/ {{0x3c5d64e9, 0xfa6c56a7} },
+/**/ {{0x3fc80239, 0x7e6de8de} },
+/**/ {{0x3c68d62f, 0x7776e849} },
+/**/ {{0xbfa49cf9, 0x4f6d8017} },
+/**/ {{0xbfb5f3b3, 0xde917e27} },
+/**/ {{0x3fb32420, 0x8e455cc2} },
+/**/ {{0x3f877470, 0xb9fc88fe} },
+/**/ {{0xbfad5dbd, 0xc6b10536} } },
+/**/ {{{0x3fd94000, 0x00000000} },
+/**/ {{0x3fd80cd4, 0x6a14b1d1} },
+/**/ {{0xbc7e79f9, 0x9684fa19} },
+/**/ {{0x3febb09f, 0x0e09a222} },
+/**/ {{0x3c85748e, 0x7e047edd} },
+/**/ {{0xbfd2e7ff, 0x00ccbbc8} },
+/**/ {{0xbc78eb0a, 0x96875561} },
+/**/ {{0xbfbd787e, 0x804ecc06} },
+/**/ {{0xbc27263b, 0x2e4351f8} },
+/**/ {{0x3fc7e7d1, 0xf260d7b4} },
+/**/ {{0xbc430525, 0x8ed258e3} },
+/**/ {{0xbfa5a140, 0x968d3d02} },
+/**/ {{0xbfb56d69, 0xaecb845e} },
+/**/ {{0x3fb33987, 0xae292f95} },
+/**/ {{0x3f835d1d, 0x48e09ecd} },
+/**/ {{0xbfacd0b5, 0x6b6f9aca} } },
+/**/ {{{0x3fd98000, 0x00000000} },
+/**/ {{0x3fd84422, 0xb8df95d7} },
+/**/ {{0x3c7d76a0, 0x299b41b6} },
+/**/ {{0x3feb9dac, 0x19ba64d6} },
+/**/ {{0xbc4f643a, 0xa13ee09f} },
+/**/ {{0xbfd2fdd1, 0xc390a5c9} },
+/**/ {{0x3c575152, 0xaa856fcc} },
+/**/ {{0xbfbcb9ad, 0xc0e99751} },
+/**/ {{0x3c4e2d44, 0x1347a357} },
+/**/ {{0x3fc7cc28, 0xfdcbfd40} },
+/**/ {{0x3c60dc32, 0xe516db08} },
+/**/ {{0xbfa69f39, 0x19851d86} },
+/**/ {{0xbfb4e697, 0xe772087d} },
+/**/ {{0x3fb34ae1, 0x835992de} },
+/**/ {{0x3f7eb3f1, 0xe5326389} },
+/**/ {{0xbfac3ebd, 0x234575e8} } },
+/**/ {{{0x3fd9c000, 0x00000000} },
+/**/ {{0x3fd87b4b, 0x0c1ebedc} },
+/**/ {{0xbc76dcfa, 0xa2fa470f} },
+/**/ {{0x3feb8aa3, 0x9a1ab378} },
+/**/ {{0x3c8efdb0, 0xb797ab93} },
+/**/ {{0xbfd31315, 0xbdfb5e5a} },
+/**/ {{0x3c5813a8, 0x862f0c0d} },
+/**/ {{0xbfbbfbbf, 0x3478f169} },
+/**/ {{0xbc51e810, 0xd9e52582} },
+/**/ {{0x3fc7af46, 0x86d6ec76} },
+/**/ {{0xbc6336de, 0x3c13b159} },
+/**/ {{0xbfa796dd, 0x264b8050} },
+/**/ {{0xbfb45f5a, 0x9e1f6bef} },
+/**/ {{0x3fb35842, 0x93b26fc1} },
+/**/ {{0x3f76d75e, 0x39bc3abf} },
+/**/ {{0xbfaba82f, 0x006e38b2} } },
+/**/ {{{0x3fda0000, 0x00000000} },
+/**/ {{0x3fd8b24d, 0x394a1b25} },
+/**/ {{0x3c7b6d0b, 0xa3748fa8} },
+/**/ {{0x3feb7786, 0x1d9cdc98} },
+/**/ {{0xbc62e22c, 0x345bd7a8} },
+/**/ {{0xbfd327cb, 0x9d57b8f5} },
+/**/ {{0xbc135343, 0x753cc4f1} },
+/**/ {{0xbfbb3ebc, 0x8761b154} },
+/**/ {{0x3c5abeec, 0x8c168fdd} },
+/**/ {{0x3fc79132, 0x79f68c54} },
+/**/ {{0xbc658ab9, 0xd8d15eda} },
+/**/ {{0xbfa88828, 0x5872d73c} },
+/**/ {{0xbfb3d7cd, 0x567be750} },
+/**/ {{0x3fb361c0, 0x0a24fc71} },
+/**/ {{0x3f6e4b7a, 0x46aa98b6} },
+/**/ {{0xbfab0d64, 0x3bad3a76} } },
+/**/ {{{0x3fda4000, 0x00000000} },
+/**/ {{0x3fd8e929, 0x16f5cde8} },
+/**/ {{0x3c74c0a7, 0xe12bfafb} },
+/**/ {{0x3feb6454, 0x32024b37} },
+/**/ {{0xbc7987f7, 0x69cc9b53} },
+/**/ {{0xbfd33bf4, 0x161a0a40} },
+/**/ {{0x3c7a2321, 0x83ff46db} },
+/**/ {{0xbfba82af, 0x26913418} },
+/**/ {{0x3c3c4c62, 0x10a559fe} },
+/**/ {{0x3fc771f4, 0xc8506679} },
+/**/ {{0xbc54aaed, 0x63c7ccc3} },
+/**/ {{0xbfa97317, 0x9237e7ff} },
+/**/ {{0xbfb3500a, 0xfde5f112} },
+/**/ {{0x3fb3676f, 0xaa2c3459} },
+/**/ {{0x3f5e80cd, 0x04721907} },
+/**/ {{0xbfaa6eb5, 0x0dc212a5} } },
+/**/ {{{0x3fda8000, 0x00000000} },
+/**/ {{0x3fd91fde, 0x7cd0c662} },
+/**/ {{0x3c710741, 0x88054b53} },
+/**/ {{0x3feb510e, 0x6454751c} },
+/**/ {{0xbc199bfd, 0x7e0f2dca} },
+/**/ {{0xbfd34f8f, 0xe3b081f4} },
+/**/ {{0x3c7d7209, 0x3e2c0515} },
+/**/ {{0xbfb9c7a0, 0x3f5e2d2f} },
+/**/ {{0xbc20b02e, 0xea3bd312} },
+/**/ {{0x3fc75195, 0x6626c39a} },
+/**/ {{0x3c6f30d2, 0xb4219a8a} },
+/**/ {{0xbfaa57a8, 0xf55dfea5} },
+/**/ {{0xbfb2c82d, 0xe771fa17} },
+/**/ {{0x3fb36967, 0xc3654ab4} },
+/**/ {{0x3f11f322, 0xa23eb6eb} },
+/**/ {{0xbfa9cc78, 0x8ae579b1} } },
+/**/ {{{0x3fdac000, 0x00000000} },
+/**/ {{0x3fd9566d, 0x43a34907} },
+/**/ {{0x3c69b015, 0x37e0af2b} },
+/**/ {{0x3feb3db5, 0x40ddf8d3} },
+/**/ {{0xbc616f46, 0x793c10b8} },
+/**/ {{0xbfd3629f, 0xc8537217} },
+/**/ {{0x3c505738, 0x38143614} },
+/**/ {{0xbfb90d98, 0xbf75f20a} },
+/**/ {{0x3c4dc715, 0x6b842647} },
+/**/ {{0x3fc7301c, 0x494dd1e6} },
+/**/ {{0x3c5ec3d6, 0xf49f85b4} },
+/**/ {{0xbfab35db, 0xdbdd23b1} },
+/**/ {{0xbfb2404f, 0xc8407216} },
+/**/ {{0x3fb367bf, 0x255139f9} },
+/**/ {{0xbf5b8a0d, 0x65acd6da} },
+/**/ {{0xbfa92704, 0x8052f51d} } },
+/**/ {{{0x3fdb0000, 0x00000000} },
+/**/ {{0x3fd98cd5, 0x454d6b18} },
+/**/ {{0x3c79e6c9, 0x88fd0a77} },
+/**/ {{0x3feb2a49, 0x5323eb6a} },
+/**/ {{0xbc572202, 0x70cc9678} },
+/**/ {{0xbfd37524, 0x8cd58cc4} },
+/**/ {{0x3c6978a3, 0xda42aa4e} },
+/**/ {{0xbfb854a1, 0x54d5f784} },
+/**/ {{0xbc5e9a15, 0xb33b3d0d} },
+/**/ {{0x3fc70d91, 0x67aa0c46} },
+/**/ {{0xbc6aa72f, 0xa4ac9df8} },
+/**/ {{0xbfac0db0, 0xd0665a46} },
+/**/ {{0xbfb1b889, 0xb428e30d} },
+/**/ {{0x3fb3628d, 0x134448b0} },
+/**/ {{0xbf6bbbc1, 0x67619c9c} },
+/**/ {{0xbfa87ead, 0x53e1f653} } },
+/**/ {{{0x3fdb4000, 0x00000000} },
+/**/ {{0x3fd9c316, 0x5cc58107} },
+/**/ {{0x3c4b6696, 0x02250cfb} },
+/**/ {{0x3feb16cb, 0x25df55f4} },
+/**/ {{0xbc653abc, 0xf48e26bc} },
+/**/ {{0xbfd3871f, 0x00742189} },
+/**/ {{0xbc725ae2, 0xc05df451} },
+/**/ {{0xbfb79cc2, 0x6dd13675} },
+/**/ {{0x3be1d4e0, 0x991905e4} },
+/**/ {{0x3fc6e9fc, 0xb5b8147e} },
+/**/ {{0x3c46463b, 0xa57d4eca} },
+/**/ {{0xbfacdf29, 0x86c1db89} },
+/**/ {{0xbfb130f4, 0x1ab8d1c4} },
+/**/ {{0x3fb359e9, 0x38881228} },
+/**/ {{0xbf74a987, 0x53bec2ff} },
+/**/ {{0xbfa7d3c5, 0xe5af58b6} } },
+/**/ {{{0x3fdb8000, 0x00000000} },
+/**/ {{0x3fd9f930, 0x66168002} },
+/**/ {{0xbc7c8270, 0x47c9439a} },
+/**/ {{0x3feb033b, 0x42f6e2c9} },
+/**/ {{0xbc6eb80c, 0xc48702a7} },
+/**/ {{0xbfd3988f, 0xf8a76337} },
+/**/ {{0xbc636968, 0x5b1bb38a} },
+/**/ {{0xbfb6e604, 0x39212b04} },
+/**/ {{0xbc3c2e20, 0xba255e71} },
+/**/ {{0x3fc6c566, 0x251e2d41} },
+/**/ {{0x3c230ab3, 0x47236369} },
+/**/ {{0xbfadaa48, 0xd40b3417} },
+/**/ {{0xbfb0a9a6, 0xc484f2cc} },
+/**/ {{0x3fb34deb, 0x9cb4573e} },
+/**/ {{0xbf7b44ca, 0x1def6f17} },
+/**/ {{0xbfa7269f, 0x73d683b8} } },
+/**/ {{{0x3fdbc000, 0x00000000} },
+/**/ {{0x3fda2f23, 0x3e5e530b} },
+/**/ {{0x3c5814d5, 0xf797086b} },
+/**/ {{0x3feaef9a, 0x3378ba79} },
+/**/ {{0x3c7da16a, 0x4476e241} },
+/**/ {{0xbfd3a978, 0x50f2beab} },
+/**/ {{0x3c7b7e7f, 0xad5a31ea} },
+/**/ {{0xbfb6306e, 0xa602212f} },
+/**/ {{0xbc31ec15, 0x9ec38d55} },
+/**/ {{0x3fc69fd5, 0xa3477c6a} },
+/**/ {{0x3c571f2f, 0xb2996038} },
+/**/ {{0xbfae6f12, 0xa6cf162d} },
+/**/ {{0xbfb022b8, 0xd0cb2655} },
+/**/ {{0x3fb33eac, 0x9842912f} },
+/**/ {{0xbf80d789, 0x4919e78d} },
+/**/ {{0xbfa67789, 0x8037e242} } },
+/**/ {{{0x3fdc0000, 0x00000000} },
+/**/ {{0x3fda64ee, 0xc3cc23fd} },
+/**/ {{0xbc724dec, 0x1b50b7ff} },
+/**/ {{0x3feadbe8, 0x7f94905e} },
+/**/ {{0x3c2adbe8, 0x7f94905e} },
+/**/ {{0xbfd3b9d8, 0xeab54af9} },
+/**/ {{0x3c75b97d, 0x54fd0941} },
+/**/ {{0xbfb57c09, 0x645a7f9e} },
+/**/ {{0xbc5e79f6, 0x09320811} },
+/**/ {{0x3fc67953, 0x180938f2} },
+/**/ {{0x3c6246f2, 0xe7aee726} },
+/**/ {{0xbfaf2d8b, 0xff0ea012} },
+/**/ {{0xbfaf3881, 0x66c7250c} },
+/**/ {{0x3fb32c44, 0xc95ff694} },
+/**/ {{0xbf83f3f0, 0x25d7ff49} },
+/**/ {{0xbfa5c6d1, 0xb848e1d1} } },
+/**/ {{{0x3fdc4000, 0x00000000} },
+/**/ {{0x3fda9a92, 0xd59e98cf} },
+/**/ {{0x3c42e42d, 0xff75d817} },
+/**/ {{0x3feac826, 0xae95dea9} },
+/**/ {{0xbc534eec, 0x633dec57} },
+/**/ {{0xbfd3c9b2, 0xacfa5b18} },
+/**/ {{0x3c7a7e0c, 0x6c4d8d27} },
+/**/ {{0xbfb4c8db, 0xe4ecc0f6} },
+/**/ {{0xbc534990, 0xc0c32772} },
+/**/ {{0x3fc651e6, 0x6451e377} },
+/**/ {{0xbc6ea814, 0x2a9bb1f1} },
+/**/ {{0xbfafe5ba, 0xe62bc1b2} },
+/**/ {{0xbfae2ca8, 0x65fe3642} },
+/**/ {{0x3fb316cd, 0x09015968} },
+/**/ {{0xbf86f764, 0x3ce97a26} },
+/**/ {{0xbfa514c3, 0xdee8421b} } },
+/**/ {{{0x3fdc8000, 0x00000000} },
+/**/ {{0x3fdad00f, 0x5422058b} },
+/**/ {{0x3c7fc4c3, 0x3891d2e8} },
+/**/ {{0x3feab455, 0x46de51cf} },
+/**/ {{0xbc5b834a, 0xdbc38cc9} },
+/**/ {{0xbfd3d906, 0x844a38eb} },
+/**/ {{0x3c6198e5, 0xbc44eee8} },
+/**/ {{0xbfb416ed, 0x5993cade} },
+/**/ {{0xbc235ccb, 0xfa289b6c} },
+/**/ {{0x3fc62997, 0x60e2a3af} },
+/**/ {{0xbc69a660, 0xcf7bda0e} },
+/**/ {{0xbfb04bd3, 0x33612b72} },
+/**/ {{0xbfad2210, 0xcf62bcd9} },
+/**/ {{0x3fb2fe5e, 0x603bfc37} },
+/**/ {{0xbf89e1ba, 0xa9bce7ec} },
+/**/ {{0xbfa461a9, 0xb83029d5} } },
+/**/ {{{0x3fdcc000, 0x00000000} },
+/**/ {{0x3fdb0564, 0x20ae9344} },
+/**/ {{0xbc793139, 0x46363455} },
+/**/ {{0x3feaa074, 0xcde0631f} },
+/**/ {{0x3c84b49a, 0x143fe6d4} },
+/**/ {{0xbfd3e7d5, 0x627b115b} },
+/**/ {{0x3c77a502, 0x332989c0} },
+/**/ {{0xbfb36644, 0xb589513f} },
+/**/ {{0x3c3abdc9, 0x105eec96} },
+/**/ {{0x3fc6006d, 0xdd12e0be} },
+/**/ {{0xbc4f0281, 0x5d67cb35} },
+/**/ {{0xbfb0a1ab, 0x4238ba83} },
+/**/ {{0xbfac18e3, 0x73889526} },
+/**/ {{0x3fb2e311, 0xfde6351a} },
+/**/ {{0xbf8cb2d2, 0xc256833f} },
+/**/ {{0xbfa3adca, 0xf73e36f0} } },
+/**/ {{{0x3fdd0000, 0x00000000} },
+/**/ {{0x3fdb3a91, 0x1da65c6c} },
+/**/ {{0x3c7ae187, 0xb1ca5040} },
+/**/ {{0x3fea8c85, 0xc81a2254} },
+/**/ {{0xbc83c191, 0x8d67728b} },
+/**/ {{0xbfd3f620, 0x3e8218e0} },
+/**/ {{0xbc72bf32, 0x52bd43ef} },
+/**/ {{0xbfb2b6e8, 0xadb5f398} },
+/**/ {{0x3c340287, 0x6b74d451} },
+/**/ {{0x3fc5d671, 0x9d9e25fc} },
+/**/ {{0x3c639669, 0x518d7a71} },
+/**/ {{0xbfb0f46a, 0x19cc29a0} },
+/**/ {{0xbfab1147, 0xc1a69750} },
+/**/ {{0x3fb2c501, 0x2c826e6b} },
+/**/ {{0xbf8f6a95, 0xcbc1b186} },
+/**/ {{0xbfa2f96d, 0x2de89811} } },
+/**/ {{{0x3fdd4000, 0x00000000} },
+/**/ {{0x3fdb6f96, 0x2e737efc} },
+/**/ {{0xbc5ca534, 0x64981e71} },
+/**/ {{0x3fea7888, 0xb9102ddc} },
+/**/ {{0xbc7791b2, 0x3c46d7d5} },
+/**/ {{0xbfd403e8, 0x1444efb5} },
+/**/ {{0xbc6047c5, 0x4f3d22a6} },
+/**/ {{0xbfb208df, 0xb90ac1cc} },
+/**/ {{0x3c4078b1, 0x2d2115d8} },
+/**/ {{0x3fc5abaa, 0x5b7c61a2} },
+/**/ {{0x3c3eef6a, 0x2bd2d19a} },
+/**/ {{0xbfb14414, 0xa8850e1a} },
+/**/ {{0xbfaa0b63, 0xc6580343} },
+/**/ {{0x3fb2a445, 0x4876cfdf} },
+/**/ {{0xbf91047b, 0x562d0829} },
+/**/ {{0xbfa244d3, 0xbe562a83} } },
+/**/ {{{0x3fdd8000, 0x00000000} },
+/**/ {{0x3fdba473, 0x378624a5} },
+/**/ {{0x3c7519a1, 0xb46e4aff} },
+/**/ {{0x3fea647e, 0x2348d9a3} },
+/**/ {{0xbc84f6c2, 0x9156e59f} },
+/**/ {{0xbfd4112d, 0xe46b4c91} },
+/**/ {{0xbc78c11d, 0x110fe0b7} },
+/**/ {{0xbfb15c30, 0x10e3d572} },
+/**/ {{0x3c53b45b, 0x4427c00b} },
+/**/ {{0x3fc5801f, 0xc2c486ae} },
+/**/ {{0xbc49bb5e, 0xc20ced8b} },
+/**/ {{0xbfb190b0, 0x4cddef65} },
+/**/ {{0xbfa9075c, 0x2ae4bcd0} },
+/**/ {{0x3fb280f7, 0xb69396b9} },
+/**/ {{0xbf9246f8, 0xce179ccb} },
+/**/ {{0xbfa1903f, 0xce6e9b2b} } },
+/**/ {{{0x3fddc000, 0x00000000} },
+/**/ {{0x3fdbd928, 0x1e528192} },
+/**/ {{0xbc74b154, 0x39af6b66} },
+/**/ {{0x3fea5066, 0x88478403} },
+/**/ {{0xbc85c7e8, 0xbe71620f} },
+/**/ {{0xbfd41df2, 0xb430f4ac} },
+/**/ {{0xbc55db82, 0xe79c7595} },
+/**/ {{0xbfb0b0df, 0xb173ac76} },
+/**/ {{0x3c57f440, 0xe4738d25} },
+/**/ {{0x3fc553d9, 0x7199976b} },
+/**/ {{0x3c54990c, 0x2a872a12} },
+/**/ {{0xbfb1da42, 0xd137dd01} },
+/**/ {{0xbfa80554, 0x350bfdb5} },
+/**/ {{0x3fb25b31, 0xdae9e17f} },
+/**/ {{0xbf937cc5, 0xe9e265b4} },
+/**/ {{0xbfa0dbf0, 0x3d16a202} } },
+/**/ {{{0x3fde0000, 0x00000000} },
+/**/ {{0x3fdc0db4, 0xc94ec9f0} },
+/**/ {{0xbc7cc1ce, 0x70934c34} },
+/**/ {{0x3fea3c42, 0x68881898} },
+/**/ {{0x3c8f907f, 0xe5c3bd97} },
+/**/ {{0xbfd42a37, 0x8d38076d} },
+/**/ {{0xbc6b8354, 0x7e19d62d} },
+/**/ {{0xbfb006f4, 0x5a36f1bd} },
+/**/ {{0xbc41701e, 0xca398c09} },
+/**/ {{0x3fc526de, 0xf7221a2a} },
+/**/ {{0xbc211868, 0x8041247e} },
+/**/ {{0xbfb220d2, 0x67b0229a} },
+/**/ {{0xbfa7056d, 0xc74d0c66} },
+/**/ {{0x3fb2330d, 0x0ff472e2} },
+/**/ {{0xbf94a5e9, 0x9cb74216} },
+/**/ {{0xbfa02821, 0x992b9e1f} } },
+/**/ {{{0x3fde4000, 0x00000000} },
+/**/ {{0x3fdc4219, 0x1ff11eb7} },
+/**/ {{0xbc7b17df, 0x434b3eee} },
+/**/ {{0x3fea2812, 0x437ac09e} },
+/**/ {{0xbc540368, 0xf9618c21} },
+/**/ {{0xbfd435fd, 0x7d5ba406} },
+/**/ {{0x3c75605b, 0x5e0a732a} },
+/**/ {{0xbfaebce7, 0x1ce0c104} },
+/**/ {{0xbc446d02, 0xd4eb3297} },
+/**/ {{0x3fc4f937, 0xd289f60b} },
+/**/ {{0x3c5b88b7, 0xe736fa8b} },
+/**/ {{0xbfb26465, 0xa5f78db4} },
+/**/ {{0xbfa607c9, 0x61a972db} },
+/**/ {{0x3fb208a2, 0x9e13b088} },
+/**/ {{0xbf95c26f, 0x06c33653} },
+/**/ {{0xbf9eea1c, 0x346237b1} } },
+/**/ {{{0x3fde8000, 0x00000000} },
+/**/ {{0x3fdc7655, 0x0aad71f9} },
+/**/ {{0xbc774b8b, 0xff7043e4} },
+/**/ {{0x3fea13d6, 0x977fc070} },
+/**/ {{0xbc86c451, 0xd9440881} },
+/**/ {{0xbfd44145, 0x9682eee2} },
+/**/ {{0x3c74156f, 0xb13901b4} },
+/**/ {{0xbfad6ec5, 0x2b58de73} },
+/**/ {{0x3c2ced26, 0xdf653988} },
+/**/ {{0x3fc4caeb, 0x720eb232} },
+/**/ {{0x3c614246, 0x92f3f809} },
+/**/ {{0xbfb2a503, 0x812caa81} },
+/**/ {{0xbfa50c86, 0x22dc20a7} },
+/**/ {{0x3fb1dc0b, 0xb35de59d} },
+/**/ {{0xbf96d265, 0x4adc8c38} },
+/**/ {{0xbf9d85db, 0x35444e0c} } },
+/**/ {{{0x3fdec000, 0x00000000} },
+/**/ {{0x3fdcaa68, 0x72f3631b} },
+/**/ {{0x3c295067, 0x81636f48} },
+/**/ {{0x3fe9ff8f, 0xe1e381db} },
+/**/ {{0xbc6fffe6, 0x00701e1c} },
+/**/ {{0xbfd44c10, 0xee747cac} },
+/**/ {{0xbc7a7f22, 0xced401ad} },
+/**/ {{0xbfac238c, 0xf898de26} },
+/**/ {{0x3c1eb191, 0xdaa7d32f} },
+/**/ {{0x3fc49c01, 0x32160e42} },
+/**/ {{0x3c649f02, 0x03d0023c} },
+/**/ {{0xbfb2e2b3, 0x49ba4fb7} },
+/**/ {{0xbfa413c1, 0xca00d6c7} },
+/**/ {{0x3fb1ad61, 0x5bc495cf} },
+/**/ {{0xbf97d5df, 0x63d0ff69} },
+/**/ {{0xbf9c23eb, 0x27af7010} } },
+/**/ {{{0x3fdf0000, 0x00000000} },
+/**/ {{0x3fdcde53, 0x432c1351} },
+/**/ {{0xbc7a2cfa, 0x4418f1ad} },
+/**/ {{0x3fe9eb3e, 0x9edacacc} },
+/**/ {{0xbc8942c5, 0x87d23ca5} },
+/**/ {{0xbfd45660, 0x9eaa285d} },
+/**/ {{0x3c4fe8e6, 0x52cf85b4} },
+/**/ {{0xbfaadb48, 0x28319af3} },
+/**/ {{0xbc207b46, 0x31b456b0} },
+/**/ {{0x3fc46c80, 0x5c4ee7c2} },
+/**/ {{0x3c4bdfc1, 0xb4443c76} },
+/**/ {{0xbfb31d7c, 0xa73bc33f} },
+/**/ {{0xbfa31d98, 0xb8a731f5} },
+/**/ {{0x3fb17cbc, 0x798f7481} },
+/**/ {{0xbf98ccf3, 0xf977e9ca} },
+/**/ {{0xbf9ac4b2, 0x36ea1578} } },
+/**/ {{{0x3fdf4000, 0x00000000} },
+/**/ {{0x3fdd1215, 0x66b7f2ad} },
+/**/ {{0x3c7be678, 0x35886c30} },
+/**/ {{0x3fe9d6e3, 0x497f1fed} },
+/**/ {{0xbc8ec056, 0x9a35c454} },
+/**/ {{0xbfd46035, 0xc4255988} },
+/**/ {{0x3c7ddb7b, 0x7144427c} },
+/**/ {{0xbfa995ff, 0xe9b44acd} },
+/**/ {{0x3c3c9d56, 0xb529cf65} },
+/**/ {{0x3fc43c70, 0x26dc5cda} },
+/**/ {{0x3c6d6ee6, 0xfde6cd82} },
+/**/ {{0xbfb35567, 0x9467b39a} },
+/**/ {{0xbfa22a25, 0xf54ca1ba} },
+/**/ {{0x3fb14a35, 0xbe2d5d2d} },
+/**/ {{0xbf99b7bd, 0x35a34e74} },
+/**/ {{0xbf996891, 0xc4948489} } },
+/**/ {{{0x3fdf8000, 0x00000000} },
+/**/ {{0x3fdd45ae, 0xc9ec862b} },
+/**/ {{0x3c689421, 0x163ef92d} },
+/**/ {{0x3fe9c27e, 0x5bcb52c7} },
+/**/ {{0xbc892d91, 0xf148a350} },
+/**/ {{0xbfd46991, 0x7f43bff0} },
+/**/ {{0xbc738b23, 0x8da13c27} },
+/**/ {{0xbfa853bc, 0xf9f19dcd} },
+/**/ {{0x3c2ea7a9, 0x2433c5cf} },
+/**/ {{0x3fc40bd7, 0xb38b19e0} },
+/**/ {{0xbc5d466e, 0x1c2a2863} },
+/**/ {{0xbfb38a7c, 0x5b0333a7} },
+/**/ {{0xbfa13983, 0x2e3896d7} },
+/**/ {{0x3fb115e5, 0xa35b7545} },
+/**/ {{0xbf9a9658, 0x99098556} },
+/**/ {{0xbf980fe6, 0x693ac59e} } },
+/**/ {{{0x3fdfc000, 0x00000000} },
+/**/ {{0x3fdd791f, 0x5a1226f5} },
+/**/ {{0xbc64017e, 0xa5b64a76} },
+/**/ {{0x3fe9ae10, 0x4e983ae9} },
+/**/ {{0xbc8d45ed, 0x52b783d7} },
+/**/ {{0xbfd47274, 0xf394891f} },
+/**/ {{0xbc7cd478, 0x22e08713} },
+/**/ {{0xbfa71487, 0xa445379d} },
+/**/ {{0x3c1569aa, 0x831d87b7} },
+/**/ {{0x3fc3dabe, 0x0f10bc36} },
+/**/ {{0x3bd8df2b, 0x1cb9bbe6} },
+/**/ {{0xbfb3bcc3, 0x8fddd862} },
+/**/ {{0xbfa04bc8, 0xbcb632d9} },
+/**/ {{0x3fb0dfe4, 0x64a26d77} },
+/**/ {{0xbf9b68e6, 0xd04027d1} },
+/**/ {{0xbf96bb07, 0xf792c5d9} } },
+/**/ {{{0x3fe00000, 0x00000000} },
+/**/ {{0x3fddac67, 0x0561bb4f} },
+/**/ {{0x3c7a2b7f, 0x222f65e2} },
+/**/ {{0x3fe99999, 0x9999999a} },
+/**/ {{0xbc899999, 0x9999999a} },
+/**/ {{0xbfd47ae1, 0x47ae147b} },
+/**/ {{0x3c5eb851, 0xeb851eb8} },
+/**/ {{0xbfa5d867, 0xc3ece2a5} },
+/**/ {{0xbc3a485c, 0xd7b900af} },
+/**/ {{0x3fc3a92a, 0x30553261} },
+/**/ {{0x3c6f06f6, 0x94467382} },
+/**/ {{0xbfb3ec46, 0x0ed80a18} },
+/**/ {{0xbf9ec21b, 0x514d88d8} },
+/**/ {{0x3fb0a849, 0xf929a833} },
+/**/ {{0xbf9c2f8b, 0x88dfb80c} },
+/**/ {{0xbf956a49, 0x8245bf09} } },
+/**/ {{{0x3fe02000, 0x00000000} },
+/**/ {{0x3fdddf85, 0xbb026974} },
+/**/ {{0x3c643bbb, 0x0c0a1226} },
+/**/ {{0x3fe9851a, 0xb35b2797} },
+/**/ {{0x3c89cd14, 0x18a8fead} },
+/**/ {{0xbfd482d7, 0xa5042a2d} },
+/**/ {{0x3c0dbc04, 0xa8224d16} },
+/**/ {{0xbfa49f64, 0xc56ade02} },
+/**/ {{0x3c451e52, 0x47da7eea} },
+/**/ {{0x3fc37722, 0xf7c5fe7d} },
+/**/ {{0xbc5165be, 0xd22c4b5c} },
+/**/ {{0xbfb4190c, 0xf6f48c5d} },
+/**/ {{0xbf9cf2cf, 0x58d0c132} },
+/**/ {{0x3fb06f2e, 0x0ddfdd74} },
+/**/ {{0xbf9cea6d, 0x46e65336} },
+/**/ {{0xbf941df9, 0x6423af3b} } },
+/**/ {{{0x3fe04000, 0x00000000} },
+/**/ {{0x3fde127b, 0x6b0744b0} },
+/**/ {{0xbc52b098, 0x6398d4ab} },
+/**/ {{0x3fe97094, 0x113dcc5a} },
+/**/ {{0xbc842780, 0x4de8c575} },
+/**/ {{0xbfd48a59, 0x37beb8e5} },
+/**/ {{0xbc601dd2, 0x9dc7541e} },
+/**/ {{0xbfa36985, 0xa7f2a8fe} },
+/**/ {{0xbc45e414, 0x7437d42d} },
+/**/ {{0x3fc344af, 0x2eb33dd6} },
+/**/ {{0xbc6d66e9, 0xe3a3193c} },
+/**/ {{0xbfb44321, 0xa6763232} },
+/**/ {{0xbf9b29d6, 0x7217dfc9} },
+/**/ {{0x3fb034a7, 0xfff8a866} },
+/**/ {{0xbf9d99b5, 0x3a6e931d} },
+/**/ {{0xbf92d661, 0x4a9f7e19} } },
+/**/ {{{0x3fe06000, 0x00000000} },
+/**/ {{0x3fde4548, 0x066cf51a} },
+/**/ {{0x3c43a3aa, 0x12ce98f2} },
+/**/ {{0x3fe95c06, 0x2774fe53} },
+/**/ {{0x3c810dfd, 0x3b851412} },
+/**/ {{0xbfd49167, 0x2e911e43} },
+/**/ {{0xbc7f6506, 0x09466fcd} },
+/**/ {{0xbfa236d0, 0xfedfb0c1} },
+/**/ {{0xbc3f6870, 0x79cb63a9} },
+/**/ {{0x3fc311d5, 0x86b6561c} },
+/**/ {{0x3c561982, 0x9543fc9a} },
+/**/ {{0xbfb46a8d, 0xb70aa5a7} },
+/**/ {{0xbf996756, 0xf5ac1efc} },
+/**/ {{0x3faff19d, 0xaf7c84b3} },
+/**/ {{0xbf9e3d8f, 0x15ce96b8} },
+/**/ {{0xbf9193c6, 0x42726021} } },
+/**/ {{{0x3fe08000, 0x00000000} },
+/**/ {{0x3fde77eb, 0x7f175a34} },
+/**/ {{0x3c70e53d, 0xc1bf3435} },
+/**/ {{0x3fe94771, 0x69044ba4} },
+/**/ {{0xbc7d53e2, 0x92d5fbc1} },
+/**/ {{0xbfd49802, 0xba91fd89} },
+/**/ {{0x3c71963e, 0xc3c8c4f3} },
+/**/ {{0xbfa1074c, 0xf33546d5} },
+/**/ {{0x3c4bc296, 0xc71ad288} },
+/**/ {{0x3fc2de9c, 0x99222665} },
+/**/ {{0x3c6e4a10, 0x28dadb64} },
+/**/ {{0xbfb48f5a, 0xfa031cb1} },
+/**/ {{0xbf97ab74, 0xbc0c6420} },
+/**/ {{0x3faf7772, 0x876d0f75} },
+/**/ {{0xbf9ed628, 0xe431fc96} },
+/**/ {{0xbf905668, 0xc64515ec} } },
+/**/ {{{0x3fe0a000, 0x00000000} },
+/**/ {{0x3fdeaa65, 0xc7cf28c4} },
+/**/ {{0x3c62fb2c, 0xeca3bf05} },
+/**/ {{0x3fe932d6, 0x47bd0aaa} },
+/**/ {{0x3c6bdfec, 0x697b6e3c} },
+/**/ {{0xbfd49e2d, 0x0f13a7e8} },
+/**/ {{0x3c6198c5, 0x20412940} },
+/**/ {{0xbf9fb5fe, 0x8a4e92df} },
+/**/ {{0xbc3cbb58, 0x6309a51a} },
+/**/ {{0x3fc2ab0a, 0xe67c9829} },
+/**/ {{0xbc647643, 0x06a4c4ef} },
+/**/ {{0xbfb4b193, 0x749bc711} },
+/**/ {{0xbf95f651, 0x27bef265} },
+/**/ {{0x3faefafb, 0x28347ebf} },
+/**/ {{0xbf9f63b2, 0xe0c06e2f} },
+/**/ {{0xbf8e3d09, 0x9e7b9dd7} } },
+/**/ {{{0x3fe0c000, 0x00000000} },
+/**/ {{0x3fdedcb6, 0xd43f8435} },
+/**/ {{0xbc5fc976, 0x330884e4} },
+/**/ {{0x3fe91e35, 0x343c31e5} },
+/**/ {{0xbc8fd46f, 0x9bb96799} },
+/**/ {{0xbfd4a3e7, 0x617d19a1} },
+/**/ {{0xbc7d7303, 0xea58b250} },
+/**/ {{0xbf9d63da, 0x9b55d156} },
+/**/ {{0xbc14bf72, 0xd5b4cc6c} },
+/**/ {{0x3fc27726, 0xd6016a7c} },
+/**/ {{0x3c4eba22, 0x435ec4b4} },
+/**/ {{0xbfb4d141, 0x5c52b3c6} },
+/**/ {{0xbf94480b, 0x2fdd9fbd} },
+/**/ {{0x3fae7c63, 0x6d3af4b6} },
+/**/ {{0xbf9fe65f, 0x4e61315b} },
+/**/ {{0xbf8bd8a3, 0xcea37283} } },
+/**/ {{{0x3fe0e000, 0x00000000} },
+/**/ {{0x3fdf0ede, 0x98f393d0} },
+/**/ {{0xbc72f40a, 0x87cb1894} },
+/**/ {{0x3fe9098e, 0x9de85688} },
+/**/ {{0xbc7c2de1, 0xa3791e64} },
+/**/ {{0xbfd4a932, 0xe9238ed7} },
+/**/ {{0xbc67a1bb, 0x28864386} },
+/**/ {{0xbf9b1838, 0x001dec68} },
+/**/ {{0xbc33ee0e, 0x8f0ffbdd} },
+/**/ {{0x3fc242f6, 0xb52e1005} },
+/**/ {{0xbc5476eb, 0x371fd2c1} },
+/**/ {{0xbfb4ee6f, 0x134edf2d} },
+/**/ {{0xbf92a0bf, 0x6b13becc} },
+/**/ {{0x3fadfbd6, 0x650f859c} },
+/**/ {{0xbfa02f31, 0x281586f4} },
+/**/ {{0xbf898006, 0x7a73449e} } },
+/**/ {{{0x3fe10000, 0x00000000} },
+/**/ {{0x3fdf40dd, 0x0b541418} },
+/**/ {{0xbc6a3992, 0xdc382a23} },
+/**/ {{0x3fe8f4e2, 0xf2efd135} },
+/**/ {{0xbc74c3c0, 0xd4218911} },
+/**/ {{0xbfd4ae10, 0xdf24b2d1} },
+/**/ {{0x3c713b12, 0x79d0ac37} },
+/**/ {{0xbf98d31f, 0xd7365f3f} },
+/**/ {{0xbc18bf3b, 0x62531dc5} },
+/**/ {{0x3fc20e80, 0xb7567664} },
+/**/ {{0xbc54a699, 0xd450197f} },
+/**/ {{0xbfb50927, 0x24d80ddd} },
+/**/ {{0xbf910088, 0x1b0516ab} },
+/**/ {{0x3fad797e, 0x4a356567} },
+/**/ {{0xbfa065f8, 0xe14758ed} },
+/**/ {{0xbf87338f, 0x73d2f6bb} } },
+/**/ {{{0x3fe12000, 0x00000000} },
+/**/ {{0x3fdf72b2, 0x21a4e495} },
+/**/ {{0x3c5489c2, 0x0f7eb740} },
+/**/ {{0x3fe8e032, 0xa0470831} },
+/**/ {{0xbc8c154a, 0xe75570cd} },
+/**/ {{0xbfd4b282, 0x7e416c35} },
+/**/ {{0xbc7f1837, 0x60646afd} },
+/**/ {{0xbf96949a, 0x7a6bec27} },
+/**/ {{0x3c38238f, 0xe6b77ba9} },
+/**/ {{0x3fc1d9ca, 0xf5428c61} },
+/**/ {{0x3c6a968d, 0xcd7881aa} },
+/**/ {{0xbfb52174, 0x41e00b6e} },
+/**/ {{0xbf8ecefa, 0x702ad3de} },
+/**/ {{0x3facf584, 0x7c8ae0dc} },
+/**/ {{0xbfa097a2, 0x8aa44fa8} },
+/**/ {{0xbf84f394, 0x2ed63408} } },
+/**/ {{{0x3fe14000, 0x00000000} },
+/**/ {{0x3fdfa45d, 0xd3029259} },
+/**/ {{0xbc7ca563, 0xdc28d8b5} },
+/**/ {{0x3fe8cb7e, 0x11a6de80} },
+/**/ {{0x3c610be6, 0xac22b8f8} },
+/**/ {{0xbfd4b689, 0x02b9488a} },
+/**/ {{0x3c5ea0bd, 0xaf91d442} },
+/**/ {{0xbf945caf, 0x821fd17e} },
+/**/ {{0x3c38e464, 0x0e51a049} },
+/**/ {{0x3fc1a4db, 0x6cd45aad} },
+/**/ {{0x3c2288e0, 0xf4200d5e} },
+/**/ {{0xbfb53761, 0x3d9dd7c4} },
+/**/ {{0xbf8bab68, 0xfb107457} },
+/**/ {{0x3fac7011, 0x7b46ebd1} },
+/**/ {{0xbfa0c44a, 0x93134a8f} },
+/**/ {{0xbf82c061, 0xf1fa4589} } },
+/**/ {{{0x3fe16000, 0x00000000} },
+/**/ {{0x3fdfd5e0, 0x175fdf83} },
+/**/ {{0x3c63a87b, 0x1ec49b15} },
+/**/ {{0x3fe8b6c5, 0xb18b4749} },
+/**/ {{0xbc5fabb8, 0xb7d58c0a} },
+/**/ {{0xbfd4ba25, 0xaa26890c} },
+/**/ {{0x3c50e395, 0x0ef9b688} },
+/**/ {{0xbf922b65, 0xc8a9b4c0} },
+/**/ {{0x3c2835ee, 0xd319146f} },
+/**/ {{0x3fc16fb8, 0x00b681bd} },
+/**/ {{0x3c1df633, 0x279133b0} },
+/**/ {{0xbfb54af9, 0x0a3b410c} },
+/**/ {{0xbf889682, 0xebe14682} },
+/**/ {{0x3fabe94c, 0xdf89e086} },
+/**/ {{0xbfa0ec0e, 0x0e55a6f8} },
+/**/ {{0xbf809a3e, 0x08af68f3} } },
+/**/ {{{0x3fe18000, 0x00000000} },
+/**/ {{0x3fe0039c, 0x73c1a40c} },
+/**/ {{0xbc8b32c9, 0x49c9d593} },
+/**/ {{0x3fe8a209, 0xe931fcd3} },
+/**/ {{0x3c6cb8f0, 0x8e68c94c} },
+/**/ {{0xbfd4bd59, 0xb35ad2d8} },
+/**/ {{0xbc61ac1a, 0xcaa606b4} },
+/**/ {{0xbf9000c3, 0x6dc339ef} },
+/**/ {{0x3c2c62e2, 0xaeaeaa73} },
+/**/ {{0x3fc13a66, 0x7812ee2d} },
+/**/ {{0x3c6a8cc2, 0x948ffe5b} },
+/**/ {{0xbfb55c46, 0xb5955c9c} },
+/**/ {{0xbf85906b, 0x0fd2b503} },
+/**/ {{0x3fab615d, 0x577de2da} },
+/**/ {{0xbfa10f0a, 0xa34d31ec} },
+/**/ {{0xbf7d02cb, 0xefe48ad0} } },
+/**/ {{{0x3fe1a000, 0x00000000} },
+/**/ {{0x3fe01c34, 0x1e82422d} },
+/**/ {{0x3c83db44, 0xfcca90ee} },
+/**/ {{0x3fe88d4b, 0x20995a88} },
+/**/ {{0x3c802777, 0x1e42e681} },
+/**/ {{0xbfd4c026, 0x5e3c840f} },
+/**/ {{0x3c7d7c65, 0x3800420d} },
+/**/ {{0xbf8bb99b, 0xb3f88703} },
+/**/ {{0x3c1f62ec, 0x4bf63e82} },
+/**/ {{0x3fc104ec, 0x7e5193ee} },
+/**/ {{0xbc27771e, 0xbae4e07d} },
+/**/ {{0xbfb56b55, 0x66104515} },
+/**/ {{0xbf829940, 0x061a20d1} },
+/**/ {{0x3faad868, 0xa20334d9} },
+/**/ {{0xbfa12d5e, 0x7aba8ee6} },
+/**/ {{0xbf78ec1f, 0x69774b8d} } },
+/**/ {{{0x3fe1c000, 0x00000000} },
+/**/ {{0x3fe034b7, 0x09250488} },
+/**/ {{0x3c78f9b3, 0x8d855410} },
+/**/ {{0x3fe87889, 0xbe7f594b} },
+/**/ {{0xbc7530e1, 0xc826e7a3} },
+/**/ {{0xbfd4c28c, 0xeba4af80} },
+/**/ {{0x3c7104a9, 0xe6a95faa} },
+/**/ {{0xbf877f13, 0x846dba10} },
+/**/ {{0x3c2bc924, 0x4abd0010} },
+/**/ {{0x3fc0cf4f, 0xa2deff9f} },
+/**/ {{0xbc67d17e, 0xa013c015} },
+/**/ {{0xbfb57830, 0x577e7899} },
+/**/ {{0xbf7f6238, 0xb49ea16d} },
+/**/ {{0x3faa4e93, 0x8ae4a926} },
+/**/ {{0xbfa14728, 0x2e77f633} },
+/**/ {{0xbf74f0d3, 0xb81c893e} } },
+/**/ {{{0x3fe1e000, 0x00000000} },
+/**/ {{0x3fe04d25, 0x314342e6} },
+/**/ {{0xbc81c863, 0x6442c767} },
+/**/ {{0x3fe863c6, 0x2860ad7e} },
+/**/ {{0xbc81dcb2, 0x137a2d8f} },
+/**/ {{0xbfd4c48e, 0x9d3dc03a} },
+/**/ {{0xbc7d92af, 0x197b1db9} },
+/**/ {{0xbf8351f6, 0x5653b1a7} },
+/**/ {{0xbbe368b4, 0x2127dea7} },
+/**/ {{0x3fc09995, 0x58fa8ca4} },
+/**/ {{0xbc446391, 0x530429e5} },
+/**/ {{0xbfb582e2, 0xd81c26eb} },
+/**/ {{0xbf79b02d, 0x3e63c109} },
+/**/ {{0x3fa9c401, 0xe7904294} },
+/**/ {{0xbfa15c86, 0xb933b0f3} },
+/**/ {{0xbf711137, 0xd8d860e1} } },
+/**/ {{{0x3fe20000, 0x00000000} },
+/**/ {{0x3fe0657e, 0x94db30d0} },
+/**/ {{0xbc7d5b49, 0x5f6349e6} },
+/**/ {{0x3fe84f00, 0xc2780614} },
+/**/ {{0xbc7fe7b0, 0xff3d87fa} },
+/**/ {{0xbfd4c62c, 0xb562c625} },
+/**/ {{0x3c77b2c3, 0xa78e848c} },
+/**/ {{0xbf7e6495, 0xb3a4bcb7} },
+/**/ {{0x3c14eb89, 0xe3f2b0a5} },
+/**/ {{0x3fc063c2, 0xf78c0dc4} },
+/**/ {{0xbc6badf0, 0x7539dc13} },
+/**/ {{0xbfb58b78, 0x459eb443} },
+/**/ {{0xbf741c83, 0x1386e6b4} },
+/**/ {{0x3fa938d6, 0x944ff706} },
+/**/ {{0xbfa16d99, 0x66ad4037} },
+/**/ {{0xbf6a9b1a, 0x01fc736a} } },
+/**/ {{{0x3fe22000, 0x00000000} },
+/**/ {{0x3fe07dc3, 0x324e9b38} },
+/**/ {{0x3c7b70c9, 0xe04450ac} },
+/**/ {{0x3fe83a39, 0xefbd6bfe} },
+/**/ {{0xbc7b2885, 0x21f5de26} },
+/**/ {{0xbfd4c768, 0x76ff6c9e} },
+/**/ {{0x3c56a2c0, 0xdebc1603} },
+/**/ {{0xbf76402c, 0xd9cccfd7} },
+/**/ {{0xbc1b39c0, 0x4e9786c1} },
+/**/ {{0x3fc02ddd, 0xb900b57a} },
+/**/ {{0x3c45d916, 0xea88a215} },
+/**/ {{0xbfb591fc, 0x0a58ab40} },
+/**/ {{0xbf6d4eb0, 0x32a37ac9} },
+/**/ {{0x3fa8ad33, 0x71fe75f8} },
+/**/ {{0xbfa17a7f, 0xc477a855} },
+/**/ {{0xbf634c0e, 0x2b035011} } },
+/**/ {{{0x3fe24000, 0x00000000} },
+/**/ {{0x3fe095f3, 0x0861a590} },
+/**/ {{0xbc7121b2, 0x0a15a9f3} },
+/**/ {{0x3fe82572, 0x11e5c14d} },
+/**/ {{0xbc7df9fc, 0xacd80b09} },
+/**/ {{0xbfd4c843, 0x25709bff} },
+/**/ {{0x3c7a9ef6, 0x1790f484} },
+/**/ {{0xbf6c6d74, 0x8a0def34} },
+/**/ {{0xbc051e57, 0x2a8142d7} },
+/**/ {{0x3fbfefd5, 0x765e156b} },
+/**/ {{0xbc3e6048, 0xf0e29c9e} },
+/**/ {{0xbfb59679, 0x9a724e28} },
+/**/ {{0xbf62a185, 0xcf13e192} },
+/**/ {{0x3fa82139, 0x6433c13f} },
+/**/ {{0xbfa18359, 0x9342e95d} },
+/**/ {{0xbf586b34, 0x8f974107} } },
+/**/ {{{0x3fe26000, 0x00000000} },
+/**/ {{0x3fe0ae0e, 0x1639866c} },
+/**/ {{0x3c7075ab, 0xf2de445a} },
+/**/ {{0x3fe810a9, 0x89625f5d} },
+/**/ {{0xbc8e4bea, 0x0fcf7262} },
+/**/ {{0xbfd4c8be, 0x0465c69b} },
+/**/ {{0x3c462ef4, 0xd7f7f89c} },
+/**/ {{0xbf59210e, 0x4de612d5} },
+/**/ {{0xbbf43659, 0xba53898d} },
+/**/ {{0x3fbf83dd, 0xfe836c69} },
+/**/ {{0xbc36cb56, 0x27f5499a} },
+/**/ {{0xbfb598fc, 0x7136edda} },
+/**/ {{0xbf50634c, 0x00013fb7} },
+/**/ {{0x3fa79508, 0x4fe557c2} },
+/**/ {{0xbfa18846, 0xb8ae41dc} },
+/**/ {{0xbf455fce, 0xe36bd239} } },
+/**/ {{{0x3fe28000, 0x00000000} },
+/**/ {{0x3fe0c614, 0x5b5b43da} },
+/**/ {{0x3c5974fa, 0x13b5404f} },
+/**/ {{0x3fe7fbe0, 0xb560d35c} },
+/**/ {{0xbc84f066, 0xae5a0887} },
+/**/ {{0xbfd4c8da, 0x57c2e1cb} },
+/**/ {{0x3c73de0e, 0xe0a3774c} },
+/**/ {{0x3f38b341, 0x61c69f3c} },
+/**/ {{0x3bd7b2e2, 0x7b200371} },
+/**/ {{0x3fbf17de, 0xd351e8ed} },
+/**/ {{0x3c5bce38, 0x650c5a9c} },
+/**/ {{0xbfb59990, 0x0e77234c} },
+/**/ {{0x3f3006ef, 0x99f594ee} },
+/**/ {{0x3fa708bf, 0x1a75a6cc} },
+/**/ {{0xbfa18967, 0x31a471d5} },
+/**/ {{0x3f24cc7e, 0x59bf0521} } },
+/**/ {{{0x3fe2a000, 0x00000000} },
+/**/ {{0x3fe0de05, 0xd7aa6f7d} },
+/**/ {{0xbc783684, 0xb1c529ab} },
+/**/ {{0x3fe7e717, 0xf3cab884} },
+/**/ {{0x3c7e1b21, 0x3b1fa4c7} },
+/**/ {{0xbfd4c899, 0x63830b4b} },
+/**/ {{0xbc7b6e32, 0xae3ffeff} },
+/**/ {{0x3f628757, 0xfc06cc4f} },
+/**/ {{0xbbb4c155, 0x56f01f66} },
+/**/ {{0x3fbeabe1, 0x8424efd8} },
+/**/ {{0x3bdf5129, 0x6e5604ea} },
+/**/ {{0xbfb5983f, 0xf3ffff64} },
+/**/ {{0x3f57ec04, 0x1f564189} },
+/**/ {{0x3fa67c7b, 0xa92e6e68} },
+/**/ {{0xbfa186db, 0x0542d0ff} },
+/**/ {{0x3f4ee247, 0x11a37bde} } },
+/**/ {{{0x3fe2c000, 0x00000000} },
+/**/ {{0x3fe0f5e2, 0x8b67e295} },
+/**/ {{0x3be311b1, 0x7ec990d0} },
+/**/ {{0x3fe7d24f, 0xa145af59} },
+/**/ {{0xbc83c6d1, 0xabdb623b} },
+/**/ {{0xbfd4c7fc, 0x6b9bdb30} },
+/**/ {{0x3c7c2fae, 0xd3bbb84b} },
+/**/ {{0x3f70e125, 0xc729b366} },
+/**/ {{0x3c1291fb, 0x7a19993c} },
+/**/ {{0x3fbe3fef, 0x66cf0dd8} },
+/**/ {{0xbc5428b7, 0xcd5e7640} },
+/**/ {{0xbfb59517, 0xa3273c21} },
+/**/ {{0x3f65adcf, 0x36891acb} },
+/**/ {{0x3fa5f05a, 0xe121c017} },
+/**/ {{0xbfa180c2, 0x384bad65} },
+/**/ {{0x3f5bd6f1, 0xd31e02a7} } },
+/**/ {{{0x3fe2e000, 0x00000000} },
+/**/ {{0x3fe10daa, 0x77307a0d} },
+/**/ {{0x3c869c33, 0xd44c7b05} },
+/**/ {{0x3fe7bd88, 0x19337139} },
+/**/ {{0xbc7fd248, 0x00e777ef} },
+/**/ {{0xbfd4c704, 0xb3e16264} },
+/**/ {{0xbc7ed720, 0xd46ed4e3} },
+/**/ {{0x3f7863a5, 0x62c1daf7} },
+/**/ {{0x3c155e73, 0x30cc82d1} },
+/**/ {{0x3fbdd411, 0x97a241da} },
+/**/ {{0x3c27a15a, 0x9ac44edd} },
+/**/ {{0xbfb59022, 0x9a6c71a6} },
+/**/ {{0x3f6f285a, 0xb5534ebe} },
+/**/ {{0x3fa56478, 0xa76d3cf7} },
+/**/ {{0xbfa1773c, 0xc1240db6} },
+/**/ {{0x3f63e5a1, 0x3891a70c} } },
+/**/ {{{0x3fe30000, 0x00000000} },
+/**/ {{0x3fe1255d, 0x9bfbd2a9} },
+/**/ {{0xbc52bdae, 0xe1c0ee35} },
+/**/ {{0x3fe7a8c1, 0xb5b1ffa1} },
+/**/ {{0x3c873e4a, 0x4e005ea3} },
+/**/ {{0xbfd4c5b3, 0x7fead5b8} },
+/**/ {{0x3c77958e, 0x55abc25a} },
+/**/ {{0x3f7fcb31, 0x01e4c970} },
+/**/ {{0xbc1ad968, 0xc5337fda} },
+/**/ {{0x3fbd6850, 0xf983ecf1} },
+/**/ {{0xbc3e45e6, 0x02ed6910} },
+/**/ {{0xbfb5896c, 0x532f49b6} },
+/**/ {{0x3f7432e2, 0xeaefcf7f} },
+/**/ {{0x3fa4d8ef, 0xe1db38f0} },
+/**/ {{0xbfa16a6a, 0x7c5c9def} },
+/**/ {{0x3f69a742, 0x7b6fe5d0} } },
+/**/ {{{0x3fe32000, 0x00000000} },
+/**/ {{0x3fe13cfb, 0xfb1b056e} },
+/**/ {{0x3c83110e, 0x6fc3ed38} },
+/**/ {{0x3fe793fc, 0xcf9bee6c} },
+/**/ {{0xbc8dc7d2, 0xd8d91b6c} },
+/**/ {{0xbfd4c40a, 0x12f7e51f} },
+/**/ {{0x3c7d1e10, 0x0d5d686d} },
+/**/ {{0x3f838be8, 0x839d28fa} },
+/**/ {{0x3c13427a, 0x52131640} },
+/**/ {{0x3fbcfcb6, 0x360bfed5} },
+/**/ {{0xbc5e3cb4, 0xa36f599f} },
+/**/ {{0xbfb58100, 0x3f7aa463} },
+/**/ {{0x3f78b31e, 0xb76f2bc0} },
+/**/ {{0x3fa44dda, 0x77dd6b80} },
+/**/ {{0xbfa15a6b, 0x21c53ca9} },
+/**/ {{0x3f6f30a7, 0x6cd99ed4} } },
+/**/ {{{0x3fe34000, 0x00000000} },
+/**/ {{0x3fe15485, 0x9637646a} },
+/**/ {{0xbc84ba7c, 0x548bf3c3} },
+/**/ {{0x3fe77f39, 0xbe88c85e} },
+/**/ {{0xbc6a983f, 0x9b6750c8} },
+/**/ {{0xbfd4c209, 0xafd6bee5} },
+/**/ {{0x3c7d21ef, 0x5e73e93a} },
+/**/ {{0x3f8724c7, 0xfc556ca7} },
+/**/ {{0xbc23cef2, 0x42e5673e} },
+/**/ {{0x3fbc9149, 0xbdaef67d} },
+/**/ {{0xbc1e549c, 0x3f04fcdc} },
+/**/ {{0xbfb576e9, 0xc7e4996a} },
+/**/ {{0x3f7d14fc, 0xba6ceedb} },
+/**/ {{0x3fa3c351, 0x53dcdc4a} },
+/**/ {{0xbfa1475e, 0x3a0a53a1} },
+/**/ {{0x3f724116, 0x62102619} } },
+/**/ {{{0x3fe36000, 0x00000000} },
+/**/ {{0x3fe16bfa, 0x6f5137e1} },
+/**/ {{0x3c79606f, 0xe141bd35} },
+/**/ {{0x3fe76a78, 0xd8cd8d65} },
+/**/ {{0x3c854a99, 0xddf1f71f} },
+/**/ {{0xbfd4bfb3, 0x98cabe40} },
+/**/ {{0xbc61e24d, 0x9ef99598} },
+/**/ {{0x3f8ab03d, 0x388e6864} },
+/**/ {{0x3c210541, 0xc340d113} },
+/**/ {{0x3fbc2613, 0xc7f24ec4} },
+/**/ {{0x3c54042a, 0x0a59af31} },
+/**/ {{0xbfb56b34, 0x49833ac1} },
+/**/ {{0x3f80ac4f, 0x22f6cd28} },
+/**/ {{0x3fa3396c, 0x64dac153} },
+/**/ {{0xbfa13163, 0x14dadf32} },
+/**/ {{0x3f74ce20, 0x21aeee27} } },
+/**/ {{{0x3fe38000, 0x00000000} },
+/**/ {{0x3fe1835a, 0x88be7c13} },
+/**/ {{0x3c8c621c, 0xec00c301} },
+/**/ {{0x3fe755ba, 0x737d49ca} },
+/**/ {{0xbc8abaf3, 0xd4cb44c6} },
+/**/ {{0xbfd4bd09, 0x0f73c4b3} },
+/**/ {{0x3c3e9ebf, 0xa9936e0b} },
+/**/ {{0x3f8e2e4f, 0x8920477f} },
+/**/ {{0xbc0889e3, 0x0360e009} },
+/**/ {{0x3fbbbb1c, 0x53aaefa0} },
+/**/ {{0xbc5edb26, 0xa1007b7f} },
+/**/ {{0xbfb55deb, 0x13f5f619} },
+/**/ {{0x3f82bf14, 0xe675741e} },
+/**/ {{0x3fa2b042, 0xa05e0ebf} },
+/**/ {{0xbfa11898, 0xbf95c5c1} },
+/**/ {{0x3f773faf, 0xe421ee51} } },
+/**/ {{{0x3fe3a000, 0x00000000} },
+/**/ {{0x3fe19aa5, 0xe5299f9a} },
+/**/ {{0xbc8a606c, 0x2c58f835} },
+/**/ {{0x3fe740fe, 0xe269c5b3} },
+/**/ {{0x3c873eff, 0x4c82509c} },
+/**/ {{0xbfd4ba0b, 0x54b63d79} },
+/**/ {{0xbc51d68a, 0x75bceeff} },
+/**/ {{0x3f90cf83, 0x9d9b3eb0} },
+/**/ {{0xbc107399, 0x68a7ca2f} },
+/**/ {{0x3fbb506b, 0x27453d35} },
+/**/ {{0x3c326b36, 0x00bdfedd} },
+/**/ {{0xbfb54f19, 0x67836cef} },
+/**/ {{0x3f84c2e5, 0x567ed6e8} },
+/**/ {{0x3fa227ea, 0x04a983e8} },
+/**/ {{0xbfa0fd1d, 0xfc7ce22f} },
+/**/ {{0x3f79960c, 0x2ffea71d} } },
+/**/ {{{0x3fe3c000, 0x00000000} },
+/**/ {{0x3fe1b1dc, 0x87904285} },
+/**/ {{0xbc621e8c, 0x8aef8f29} },
+/**/ {{0x3fe72c46, 0x78244c5a} },
+/**/ {{0x3c888c36, 0xe664f3a2} },
+/**/ {{0xbfd4b6bb, 0xa8a3ca2f} },
+/**/ {{0xbc778793, 0x1e1f3e19} },
+/**/ {{0x3f928136, 0xc8a3d8bb} },
+/**/ {{0x3c3dc4d8, 0x140daf1c} },
+/**/ {{0x3fbae607, 0xd1165ef3} },
+/**/ {{0xbc5fbfaa, 0x6305876c} },
+/**/ {{0xbfb53eca, 0x734b94bd} },
+/**/ {{0x3f86b7d8, 0x7c458eb1} },
+/**/ {{0x3fa1a077, 0x9b360f57} },
+/**/ {{0xbfa0df11, 0x3a6beabd} },
+/**/ {{0x3f7bd182, 0xaf42dc87} } },
+/**/ {{{0x3fe3e000, 0x00000000} },
+/**/ {{0x3fe1c8fe, 0x7341f64f} },
+/**/ {{0x3c728bbc, 0x9d5e792a} },
+/**/ {{0x3fe71791, 0x85fe8a32} },
+/**/ {{0x3c8f15bd, 0xe8bbb0d0} },
+/**/ {{0xbfd4b31b, 0x4a6497be} },
+/**/ {{0x3c737223, 0x782968f7} },
+/**/ {{0x3f942c46, 0x5e0c3122} },
+/**/ {{0xbc33e26a, 0x86422b13} },
+/**/ {{0x3fba7bf9, 0xa7b659b8} },
+/**/ {{0xbc3cdf63, 0x25381986} },
+/**/ {{0xbfb52d09, 0x538deb45} },
+/**/ {{0x3f889e08, 0xa0c1f425} },
+/**/ {{0x3fa119ff, 0x7b6d72e6} },
+/**/ {{0xbfa0be90, 0x8d11287b} },
+/**/ {{0x3f7df267, 0xbce83ad4} } },
+/**/ {{{0x3fe40000, 0x00000000} },
+/**/ {{0x3fe1e00b, 0xabdefeb4} },
+/**/ {{0xbc5928df, 0x287a668f} },
+/**/ {{0x3fe702e0, 0x5c0b8170} },
+/**/ {{0x3c7702e0, 0x5c0b8170} },
+/**/ {{0xbfd4af2b, 0x78215a76} },
+/**/ {{0xbc581c2e, 0xab3a13d8} },
+/**/ {{0x3f95d0b7, 0xe9e4a9d0} },
+/**/ {{0xbc3aa02a, 0xebf91fc7} },
+/**/ {{0x3fba1247, 0xca629942} },
+/**/ {{0xbc46961a, 0xc245db83} },
+/**/ {{0xbfb519e1, 0x100385b4} },
+/**/ {{0x3f8a7592, 0x32616ed8} },
+/**/ {{0x3fa09494, 0xcda1223a} },
+/**/ {{0xbfa09bb9, 0xa5a5c251} },
+/**/ {{0x3f7ff915, 0xf489d8ba} } },
+/**/ {{{0x3fe42000, 0x00000000} },
+/**/ {{0x3fe1f704, 0x3557138a} },
+/**/ {{0x3c76c659, 0xf6d7dd47} },
+/**/ {{0x3fe6ee33, 0x4920943e} },
+/**/ {{0xbc62723e, 0x61a3a541} },
+/**/ {{0xbfd4aaed, 0x6eedf042} },
+/**/ {{0x3c5b337a, 0xe7561ed4} },
+/**/ {{0x3f976e91, 0x68796803} },
+/**/ {{0xbc0e806f, 0x44d1db93} },
+/**/ {{0x3fb9a8f9, 0x21688625} },
+/**/ {{0x3c540185, 0xb1ec0554} },
+/**/ {{0xbfb5055c, 0x9a4cbc61} },
+/**/ {{0x3f8c3e93, 0xab0be204} },
+/**/ {{0x3fa01049, 0xce3968a1} },
+/**/ {{0xbfa076a9, 0xcc2331ba} },
+/**/ {{0x3f80f2f6, 0xe220db7e} } },
+/**/ {{{0x3fe44000, 0x00000000} },
+/**/ {{0x3fe20de8, 0x13e823b2} },
+/**/ {{0xbc8791d7, 0x53ebb744} },
+/**/ {{0x3fe6d98a, 0x9ad6a3fd} },
+/**/ {{0xbc808110, 0xc4e69862} },
+/**/ {{0xbfd4a662, 0x6ab4a79d} },
+/**/ {{0x3c52ed25, 0x9fc1cc2b} },
+/**/ {{0x3f9905d9, 0x42e6dc28} },
+/**/ {{0xbc228c79, 0xe39b7707} },
+/**/ {{0x3fb94014, 0x5e97c6f4} },
+/**/ {{0xbc52b822, 0xf8779202} },
+/**/ {{0xbfb4ef86, 0xcc723054} },
+/**/ {{0x3f8df92d, 0x76852811} },
+/**/ {{0x3f9f1a5f, 0xa231ee3f} },
+/**/ {{0xbfa04f7d, 0xd8f34e77} },
+/**/ {{0x3f81dcaa, 0x80706a34} } },
+/**/ {{{0x3fe46000, 0x00000000} },
+/**/ {{0x3fe224b7, 0x4c1d192a} },
+/**/ {{0x3c8d6d3d, 0xf88a60c4} },
+/**/ {{0x3fe6c4e6, 0x9d8b44ec} },
+/**/ {{0xbc589d5c, 0x4ed04ec2} },
+/**/ {{0xbfd4a18b, 0xa6222a08} },
+/**/ {{0xbc66c919, 0xd3867dbd} },
+/**/ {{0x3f9a9696, 0x4bb5a8a0} },
+/**/ {{0x3c36698e, 0x927bb5bd} },
+/**/ {{0x3fb8d79f, 0xfdbbcc76} },
+/**/ {{0x3c2578bd, 0x4efb71a1} },
+/**/ {{0xbfb4d86a, 0x6778e363} },
+/**/ {{0x3f8fa581, 0xd930230d} },
+/**/ {{0x3f9e16ae, 0x8a6221aa} },
+/**/ {{0xbfa02652, 0x2f183972} },
+/**/ {{0x3f82b9db, 0x3e507f4f} } },
+/**/ {{{0x3fe48000, 0x00000000} },
+/**/ {{0x3fe23b71, 0xe2cc9e6a} },
+/**/ {{0x3c6c421c, 0x9f38224e} },
+/**/ {{0x3fe6b047, 0x9c620595} },
+/**/ {{0x3c8867df, 0x07d7f0c2} },
+/**/ {{0xbfd49c6a, 0x5a920887} },
+/**/ {{0xbc764547, 0x37bcc433} },
+/**/ {{0x3f9c20cf, 0xbb7e5931} },
+/**/ {{0xbc3d86f5, 0x4db6bef2} },
+/**/ {{0x3fb86fa2, 0x451c4a5d} },
+/**/ {{0xbc475142, 0x15afb52c} },
+/**/ {{0xbfb4c012, 0x120917da} },
+/**/ {{0x3f90a1da, 0x6b9c3fad} },
+/**/ {{0x3f9d159f, 0x708543e5} },
+/**/ {{0xbf9ff685, 0x6d929bce} },
+/**/ {{0x3f838ac0, 0xd0361a66} } },
+/**/ {{{0x3fe4a000, 0x00000000} },
+/**/ {{0x3fe25217, 0xdd17e501} },
+/**/ {{0x3c856aa8, 0x8c1b679c} },
+/**/ {{0x3fe69bad, 0xe145c95d} },
+/**/ {{0xbc873257, 0x5605046d} },
+/**/ {{0xbfd496ff, 0xbffbe8a8} },
+/**/ {{0x3c36a5c5, 0xc7b45e6f} },
+/**/ {{0x3f9da48d, 0x2d9556eb} },
+/**/ {{0x3c3ff0e8, 0x1871a19d} },
+/**/ {{0x3fb80821, 0x46043f42} },
+/**/ {{0x3c550eec, 0xe660cfa1} },
+/**/ {{0xbfb4a688, 0x5727a8cb} },
+/**/ {{0x3f9169f6, 0x0e13efbc} },
+/**/ {{0x3f9c174f, 0xb59149dd} },
+/**/ {{0xbf9f9cd5, 0xb10444dd} },
+/**/ {{0x3f844f95, 0x03e91dd9} } },
+/**/ {{{0x3fe4c000, 0x00000000} },
+/**/ {{0x3fe268a9, 0x40696da6} },
+/**/ {{0x3c5d1348, 0xa04c73cc} },
+/**/ {{0x3fe68719, 0xb4ea3592} },
+/**/ {{0xbc7ecf86, 0x088ed284} },
+/**/ {{0xbfd4914d, 0x0ce1507d} },
+/**/ {{0xbc6410ef, 0x4dff2946} },
+/**/ {{0x3f9f21d6, 0x9cbf7eb7} },
+/**/ {{0x3c39bc22, 0xeaaad7e2} },
+/**/ {{0x3fb7a122, 0xdd4f3070} },
+/**/ {{0x3c50d950, 0x1cfe44af} },
+/**/ {{0xbfb48bd7, 0xa50188df} },
+/**/ {{0x3f922b27, 0x71756204} },
+/**/ {{0x3f9b1bdb, 0x0810a33a} },
+/**/ {{0xbf9f3fca, 0xf1011313} },
+/**/ {{0x3f850893, 0x8fe0f49b} } },
+/**/ {{{0x3fe4e000, 0x00000000} },
+/**/ {{0x3fe27f26, 0x1273d1b3} },
+/**/ {{0x3c843bf3, 0x6151dd9f} },
+/**/ {{0x3fe6728b, 0x5ecd3069} },
+/**/ {{0x3c67417b, 0x539f23ff} },
+/**/ {{0xbfd48b53, 0x763c0fe8} },
+/**/ {{0xbc677a1a, 0x6027975c} },
+/**/ {{0x3fa04c5a, 0x2ff7dd6a} },
+/**/ {{0xbc40808e, 0x496202e8} },
+/**/ {{0x3fb73aac, 0xb3fc3f7c} },
+/**/ {{0x3c4b58cb, 0x86b114ff} },
+/**/ {{0xbfb4700a, 0x4bc91249} },
+/**/ {{0x3f92e582, 0xef2490f8} },
+/**/ {{0x3f9a235b, 0x6c875580} },
+/**/ {{0xbf9edf99, 0xe55cd596} },
+/**/ {{0x3f85b5f9, 0xe40c5a18} } },
+/**/ {{{0x3fe50000, 0x00000000} },
+/**/ {{0x3fe2958e, 0x59308e31} },
+/**/ {{0xbc709e73, 0xb0c6c087} },
+/**/ {{0x3fe65e03, 0x2538713c} },
+/**/ {{0xbc601392, 0x42c09163} },
+/**/ {{0xbfd48514, 0x2f6d4575} },
+/**/ {{0xbc356341, 0x4568af3f} },
+/**/ {{0x3fa10497, 0x9386fd1d} },
+/**/ {{0xbc4a756a, 0x230a452f} },
+/**/ {{0x3fb6d4c4, 0x3fc6c180} },
+/**/ {{0x3c5ab2b9, 0xdb3fe137} },
+/**/ {{0xbfb4532a, 0x7ca4cfd0} },
+/**/ {{0x3f93991d, 0x90eb1d30} },
+/**/ {{0x3f992de9, 0x46163051} },
+/**/ {{0xbf9e7c76, 0x2de874ff} },
+/**/ {{0x3f865806, 0xfc0c1cb2} } },
+/**/ {{{0x3fe52000, 0x00000000} },
+/**/ {{0x3fe2abe2, 0x1aded073} },
+/**/ {{0x3c8c28c0, 0x01ad022e} },
+/**/ {{0x3fe64981, 0x4d432177} },
+/**/ {{0x3c83f41b, 0x055e240c} },
+/**/ {{0xbfd47e90, 0x6a2cfd01} },
+/**/ {{0x3c628585, 0xf152d080} },
+/**/ {{0x3fa1b9a7, 0xfbe3ed9e} },
+/**/ {{0xbc18a085, 0xf259fe04} },
+/**/ {{0x3fb66f6e, 0xc3c40175} },
+/**/ {{0x3c41d80a, 0xb0fda762} },
+/**/ {{0xbfb43542, 0x48af643a} },
+/**/ {{0x3f94460d, 0x05ad7652} },
+/**/ {{0x3f983b9b, 0x5f55ab26} },
+/**/ {{0xbf9e1692, 0x4be18b23} },
+/**/ {{0x3f86eefb, 0x32e755a3} } },
+/**/ {{{0x3fe54000, 0x00000000} },
+/**/ {{0x3fe2c221, 0x5e024466} },
+/**/ {{0xbc44b810, 0xda3a4be1} },
+/**/ {{0x3fe63506, 0x1ad38da0} },
+/**/ {{0xbc67f12a, 0x94ec14b0} },
+/**/ {{0xbfd477c9, 0x567a6652} },
+/**/ {{0x3c7be71c, 0xbbb9df88} },
+/**/ {{0x3fa26b90, 0x1535acb9} },
+/**/ {{0xbc30ff6c, 0xff041454} },
+/**/ {{0x3fb60ab1, 0x5105d8fa} },
+/**/ {{0x3c535a89, 0x3f2d6492} },
+/**/ {{0xbfb4165b, 0xa0083319} },
+/**/ {{0x3f94ec67, 0x965eb0a7} },
+/**/ {{0x3f974c86, 0xf36231e5} },
+/**/ {{0xbf9dae1f, 0x9c25f4a4} },
+/**/ {{0x3f877b18, 0x183e42dc} } },
+/**/ {{{0x3fe56000, 0x00000000} },
+/**/ {{0x3fe2d84c, 0x2961e48c} },
+/**/ {{0xbc7f2542, 0x0a36e506} },
+/**/ {{0x3fe62091, 0xd0a0e5d4} },
+/**/ {{0x3c82a27d, 0xcccb008e} },
+/**/ {{0xbfd470c0, 0x228ca1b6} },
+/**/ {{0xbc788e9b, 0x32884415} },
+/**/ {{0x3fa31a54, 0xb365e4d9} },
+/**/ {{0x3c3e6e70, 0xda0f99ae} },
+/**/ {{0x3fb5a690, 0xc741ccb7} },
+/**/ {{0xbc383905, 0x6508ffe1} },
+/**/ {{0xbfb3f680, 0x50f46c17} },
+/**/ {{0x3f958c44, 0x1b344c30} },
+/**/ {{0x3f9660bf, 0xb713db8a} },
+/**/ {{0xbf9d434e, 0x5224992a} },
+/**/ {{0x3f87fca0, 0x46ffb16e} } },
+/**/ {{{0x3fe58000, 0x00000000} },
+/**/ {{0x3fe2ee62, 0x8406cbca} },
+/**/ {{0x3c8c5d5e, 0x9ff0cf8d} },
+/**/ {{0x3fe60c24, 0xb0350d38} },
+/**/ {{0x3c81ffe9, 0xf3db4fcb} },
+/**/ {{0xbfd46975, 0xfac420bd} },
+/**/ {{0x3c7e6994, 0x850528a0} },
+/**/ {{0x3fa3c5fa, 0xd098b4ee} },
+/**/ {{0x3c353c41, 0xaa6a6874} },
+/**/ {{0x3fb54311, 0xd57c5b53} },
+/**/ {{0x3c50d02e, 0x72d146e0} },
+/**/ {{0xbfb3d5ba, 0x071017e0} },
+/**/ {{0x3f9625b9, 0xf11b08a7} },
+/**/ {{0x3f957857, 0xe25bbc6f} },
+/**/ {{0xbf9cd64d, 0x7384981f} },
+/**/ {{0x3f8873d7, 0x3da3b8d5} } },
+/**/ {{{0x3fe5a000, 0x00000000} },
+/**/ {{0x3fe30464, 0x753b090b} },
+/**/ {{0xbc73e712, 0x61da18f3} },
+/**/ {{0x3fe5f7be, 0xf9ee77b6} },
+/**/ {{0x3c8949f7, 0x854f9928} },
+/**/ {{0xbfd461ec, 0x099c98f6} },
+/**/ {{0x3c5da491, 0x3eafe889} },
+/**/ {{0x3fa46e87, 0x8ba9e286} },
+/**/ {{0x3c42573a, 0x5377a1a9} },
+/**/ {{0x3fb4e038, 0xfab82ffb} },
+/**/ {{0xbc414e45, 0x402ef939} },
+/**/ {{0xbfb3b412, 0x4a8ec478} },
+/**/ {{0x3f96b8e0, 0xef6dba07} },
+/**/ {{0x3f949360, 0x39c13c6e} },
+/**/ {{0xbf9c674a, 0xd47bfddb} },
+/**/ {{0x3f88e101, 0x37ed6935} } },
+/**/ {{{0x3fe5c000, 0x00000000} },
+/**/ {{0x3fe31a52, 0x048874be} },
+/**/ {{0x3c840cab, 0x87a7ac24} },
+/**/ {{0x3fe5e360, 0xed021586} },
+/**/ {{0x3c86a444, 0xb32ab7e4} },
+/**/ {{0xbfd45a23, 0x779f86c4} },
+/**/ {{0xbc75b9dc, 0x6b782501} },
+/**/ {{0x3fa51400, 0x26af940c} },
+/**/ {{0x3c4f700e, 0xf9ce64e2} },
+/**/ {{0x3fb47e0a, 0x86a8eb42} },
+/**/ {{0xbc5a4df9, 0x36377584} },
+/**/ {{0xbfb39192, 0x7f8b6d42} },
+/**/ {{0x3f9745d1, 0x5deeeabc} },
+/**/ {{0x3f93b1e8, 0x17fa1033} },
+/**/ {{0xbf9bf673, 0x14cf2061} },
+/**/ {{0x3f894463, 0x0a340016} } },
+/**/ {{{0x3fe5e000, 0x00000000} },
+/**/ {{0x3fe3302b, 0x39b78856} },
+/**/ {{0x3c85dd2e, 0xd87ba82b} },
+/**/ {{0x3fe5cf0a, 0xc77d4bea} },
+/**/ {{0xbc8684ab, 0x0d42ab66} },
+/**/ {{0xbfd4521d, 0x6b573e11} },
+/**/ {{0xbc7601b9, 0xb90c9c27} },
+/**/ {{0x3fa5b66a, 0x0582aeaa} },
+/**/ {{0x3c281575, 0x8cc985ad} },
+/**/ {{0x3fb41c8a, 0x9a69373d} },
+/**/ {{0xbc33df07, 0x25ea8f67} },
+/**/ {{0xbfb36e43, 0xe5673a18} },
+/**/ {{0x3f97cca3, 0xeb05f3bc} },
+/**/ {{0x3f92d3fd, 0x7797abe9} },
+/**/ {{0xbf9b83f1, 0x9d71c254} },
+/**/ {{0x3f899e41, 0xfe333861} } },
+/**/ {{{0x3fe60000, 0x00000000} },
+/**/ {{0x3fe345f0, 0x1cce37bb} },
+/**/ {{0x3c810211, 0x37c71102} },
+/**/ {{0x3fe5babc, 0xc647fa91} },
+/**/ {{0x3c84339b, 0x8056eaf3} },
+/**/ {{0xbfd449db, 0x094286d0} },
+/**/ {{0x3c75e178, 0x512b1c7b} },
+/**/ {{0x3fa655ca, 0xac4cf102} },
+/**/ {{0xbc27a1e4, 0x61e8206a} },
+/**/ {{0x3fb3bbbd, 0x2933dd9c} },
+/**/ {{0xbc517633, 0xbd42c006} },
+/**/ {{0xbfb34a2f, 0x9636afc9} },
+/**/ {{0x3f984d71, 0xa2400f6f} },
+/**/ {{0x3f91f9ac, 0xfcc53cab} },
+/**/ {{0xbf9b0ff0, 0x9ec31ef1} },
+/**/ {{0x3f89eee3, 0xb1615b05} } },
+/**/ {{{0x3fe62000, 0x00000000} },
+/**/ {{0x3fe35ba0, 0xb60eccce} },
+/**/ {{0x3c8e3ba1, 0x9b9368b9} },
+/**/ {{0x3fe5a677, 0x25268d22} },
+/**/ {{0x3c7bc76e, 0xaf72cee6} },
+/**/ {{0xbfd4415d, 0x73c8c31c} },
+/**/ {{0xbc3e5b3c, 0xe00e5645} },
+/**/ {{0x3fa6f227, 0xbe1ce1b6} },
+/**/ {{0xbc04a922, 0xe699fcac} },
+/**/ {{0x3fb35ba5, 0xf91f9885} },
+/**/ {{0xbc43f8be, 0x418827b3} },
+/**/ {{0xbfb3255e, 0x863cebc9} },
+/**/ {{0x3f98c853, 0xe315ca66} },
+/**/ {{0x3f912301, 0xff116cac} },
+/**/ {{0xbf9a9a99, 0x0f5e09c2} },
+/**/ {{0x3f8a368d, 0xf4c8d587} } },
+/**/ {{{0x3fe64000, 0x00000000} },
+/**/ {{0x3fe3713d, 0x0df6c504} },
+/**/ {{0xbc54f789, 0xe031606d} },
+/**/ {{0x3fe5923a, 0x1ebc184f} },
+/**/ {{0x3c829fe8, 0xbe5956dd} },
+/**/ {{0xbfd438a5, 0xcb2e9cc9} },
+/**/ {{0xbc7c1839, 0x7d6ce3eb} },
+/**/ {{0x3fa78b86, 0xfb7fa678} },
+/**/ {{0x3befb53e, 0xd082025e} },
+/**/ {{0x3fb2fc48, 0xa3dd5905} },
+/**/ {{0x3c5fd567, 0x06b78682} },
+/**/ {{0xbfb2ffd9, 0x8374843c} },
+/**/ {{0x3f993d64, 0x57f51471} },
+/**/ {{0x3f905006, 0x933f6cc5} },
+/**/ {{0xbf9a2412, 0xab7658df} },
+/**/ {{0x3f8a7586, 0xae624ab4} } },
+/**/ {{{0x3fe66000, 0x00000000} },
+/**/ {{0x3fe386c5, 0x2d3db11f} },
+/**/ {{0xbc8b78e1, 0xcbebe6a0} },
+/**/ {{0x3fe57e05, 0xec8c8203} },
+/**/ {{0x3c8ea585, 0x5e7f92dc} },
+/**/ {{0xbfd42fb5, 0x2d8b381e} },
+/**/ {{0xbc63afe6, 0x5cff451e} },
+/**/ {{0x3fa821ee, 0x4120d643} },
+/**/ {{0xbc3e664f, 0xcbc4d2dc} },
+/**/ {{0x3fb29da8, 0x9778bfdb} },
+/**/ {{0x3c3760dd, 0x7c2057a5} },
+/**/ {{0xbfb2d9a9, 0x3525a55a} },
+/**/ {{0x3f99acbc, 0xed9015c8} },
+/**/ {{0x3f8f0187, 0x2a35e7d2} },
+/**/ {{0xbf99ac83, 0xf4bcdfc7} },
+/**/ {{0x3f8aac13, 0xbbeb4f11} } },
+/**/ {{{0x3fe68000, 0x00000000} },
+/**/ {{0x3fe39c39, 0x1cd4171a} },
+/**/ {{0xbc823043, 0x31d8bf46} },
+/**/ {{0x3fe569da, 0xc6feb417} },
+/**/ {{0x3c803ce5, 0x0625e450} },
+/**/ {{0xbfd4268c, 0xb6bde980} },
+/**/ {{0xbc6e8f76, 0xe8258561} },
+/**/ {{0x3fa8b563, 0x86705749} },
+/**/ {{0x3c418e14, 0xe6172281} },
+/**/ {{0x3fb23fc9, 0x171a8768} },
+/**/ {{0xbc562184, 0x3225d825} },
+/**/ {{0xbfb2b2d6, 0x1b8904fd} },
+/**/ {{0x3f9a1677, 0xca70ce88} },
+/**/ {{0x3f8d6a81, 0x62963581} },
+/**/ {{0xbf993412, 0x32c353bb} },
+/**/ {{0x3f8ada7a, 0xd7354ec0} } },
+/**/ {{{0x3fe6a000, 0x00000000} },
+/**/ {{0x3fe3b198, 0xe5e2564b} },
+/**/ {{0xbc72f922, 0x1f0752ac} },
+/**/ {{0x3fe555b8, 0xe55ed910} },
+/**/ {{0xbc5615bc, 0x656f2eb2} },
+/**/ {{0xbfd41d2d, 0x80646bca} },
+/**/ {{0xbc75d1d6, 0x1ff3506f} },
+/**/ {{0x3fa945ec, 0xdc4e5727} },
+/**/ {{0x3c213c8e, 0x18968922} },
+/**/ {{0x3fb1e2ad, 0x3bcc9fa4} },
+/**/ {{0x3c2b899c, 0x0a43c591} },
+/**/ {{0xbfb28b68, 0x8f774533} },
+/**/ {{0x3f9a7aaf, 0x46d16acc} },
+/**/ {{0x3f8bdb08, 0xde405cc6} },
+/**/ {{0xbf98bae1, 0x73d9884b} },
+/**/ {{0x3f8b0101, 0x7be7742a} } },
+/**/ {{{0x3fe6c000, 0x00000000} },
+/**/ {{0x3fe3c6e4, 0x91c78dc5} },
+/**/ {{0xbc8e1450, 0x94fd0ba7} },
+/**/ {{0x3fe541a0, 0x7de0a269} },
+/**/ {{0x3c8b9072, 0x163b639c} },
+/**/ {{0xbfd41398, 0xa1d194fc} },
+/**/ {{0xbc7ef191, 0x8629402d} },
+/**/ {{0x3fa9d390, 0x6bbd69eb} },
+/**/ {{0x3c488aec, 0xd2c4a6a5} },
+/**/ {{0x3fb18657, 0xf53fbee6} },
+/**/ {{0x3c54e6aa, 0x0104d1dd} },
+/**/ {{0xbfb26368, 0xc2245ee6} },
+/**/ {{0x3f9ad97d, 0xe4b91b16} },
+/**/ {{0x3f8a5328, 0x74b192c7} },
+/**/ {{0xbf984114, 0x8e5d8b31} },
+/**/ {{0x3f8b1fec, 0xceadce82} } },
+/**/ {{{0x3fe6e000, 0x00000000} },
+/**/ {{0x3fe3dc1c, 0x2a188504} },
+/**/ {{0x3c82ce63, 0x70f4e971} },
+/**/ {{0x3fe52d91, 0xc5a197ed} },
+/**/ {{0xbc804b92, 0x1baab820} },
+/**/ {{0xbfd409cf, 0x300486f8} },
+/**/ {{0xbc6d3bb8, 0xae804189} },
+/**/ {{0x3faa5e54, 0x749adab8} },
+/**/ {{0x3c20b0d5, 0xc631cfd3} },
+/**/ {{0x3fb12acc, 0x0a922c54} },
+/**/ {{0x3c521a06, 0x7cbc4417} },
+/**/ {{0xbfb23ade, 0xbce6ae05} },
+/**/ {{0x3f9b32fe, 0x485d279b} },
+/**/ {{0x3f88d2e8, 0xd9b56b96} },
+/**/ {{0xbf97c6cd, 0x227841f4} },
+/**/ {{0x3f8b3781, 0x85cf6ba0} } },
+/**/ {{{0x3fe70000, 0x00000000} },
+/**/ {{0x3fe3f13f, 0xb89e96f4} },
+/**/ {{0x3c7ecf8b, 0x492644f0} },
+/**/ {{0x3fe5198c, 0xf0ab6f99} },
+/**/ {{0x3c71b875, 0x5e1ffaba} },
+/**/ {{0xbfd3ffd2, 0x3da059f4} },
+/**/ {{0x3c5bba8e, 0x77eee53d} },
+/**/ {{0x3faae63f, 0x4c5d36dc} },
+/**/ {{0xbc4e6e4e, 0x2a3994d6} },
+/**/ {{0x3fb0d00c, 0x1b178ada} },
+/**/ {{0x3c4b94c3, 0xb3e710cc} },
+/**/ {{0xbfb211d2, 0x61093929} },
+/**/ {{0x3f9b874b, 0x30c5dd59} },
+/**/ {{0x3f875a50, 0xb0b899ed} },
+/**/ {{0xbf974c2b, 0x9c404912} },
+/**/ {{0x3f8b4803, 0xd3249a4d} } },
+/**/ {{{0x3fe72000, 0x00000000} },
+/**/ {{0x3fe4064f, 0x47569f49} },
+/**/ {{0xbc8aad88, 0xf91bf2b2} },
+/**/ {{0x3fe50592, 0x31f66da7} },
+/**/ {{0xbc8837f1, 0x134b7507} },
+/**/ {{0xbfd3f5a2, 0xdae43e4d} },
+/**/ {{0xbc7f29b0, 0xdc59e382} },
+/**/ {{0x3fab6b57, 0x5cd91a8c} },
+/**/ {{0xbc225bf7, 0xd6ab0dfc} },
+/**/ {{0x3fb0761a, 0x9f216d7a} },
+/**/ {{0x3c577818, 0xe546203e} },
+/**/ {{0xbfb1e84b, 0x67a8cf31} },
+/**/ {{0x3f9bd67f, 0x70b6dd6f} },
+/**/ {{0x3f85e964, 0x9ff677e5} },
+/**/ {{0xbf96d14f, 0x363cf426} },
+/**/ {{0x3f8b51b7, 0x4f6617de} } },
+/**/ {{{0x3fe74000, 0x00000000} },
+/**/ {{0x3fe41b4a, 0xe06fea41} },
+/**/ {{0x3c63d60a, 0x53277652} },
+/**/ {{0x3fe4f1a1, 0xbb6bcc2c} },
+/**/ {{0x3c5c8d69, 0x7c81f558} },
+/**/ {{0xbfd3eb42, 0x15a41364} },
+/**/ {{0x3c728a9c, 0x617c316a} },
+/**/ {{0x3fabeda3, 0x230c44b8} },
+/**/ {{0x3c41fa15, 0x50d9e9da} },
+/**/ {{0x3fb01cf9, 0xe8c87fc3} },
+/**/ {{0x3c410990, 0xa175df34} },
+/**/ {{0xbfb1be51, 0x619b963c} },
+/**/ {{0x3f9c20b5, 0xe7da421c} },
+/**/ {{0x3f848027, 0x637b86b0} },
+/**/ {{0xbf965655, 0xfc436ff1} },
+/**/ {{0x3f8b54de, 0xe6cd859f} } },
+/**/ {{{0x3fe76000, 0x00000000} },
+/**/ {{0x3fe43032, 0x8e4b26d6} },
+/**/ {{0xbc813159, 0x1070b99f} },
+/**/ {{0x3fe4ddbb, 0xbde829f5} },
+/**/ {{0xbc735ff2, 0xb6d17615} },
+/**/ {{0xbfd3e0b0, 0xf941711a} },
+/**/ {{0x3c7d3454, 0xe9027227} },
+/**/ {{0x3fac6d29, 0x2deef5c2} },
+/**/ {{0x3c476533, 0x0ba13bb6} },
+/**/ {{0x3faf8958, 0x496c1e5e} },
+/**/ {{0x3c49ebf2, 0xe1abdf2f} },
+/**/ {{0xbfb193eb, 0xb762a82c} },
+/**/ {{0x3f9c6609, 0x7c2df93f} },
+/**/ {{0x3f831e99, 0xdff7724a} },
+/**/ {{0xbf95db5c, 0xcea82a5a} },
+/**/ {{0x3f8b51bc, 0xc6ff27bb} } },
+/**/ {{{0x3fe78000, 0x00000000} },
+/**/ {{0x3fe44506, 0x5b795b56} },
+/**/ {{0xbc7f76d0, 0x163f79c8} },
+/**/ {{0x3fe4c9e0, 0x693e0015} },
+/**/ {{0xbc7b0fcb, 0x60fff59b} },
+/**/ {{0xbfd3d5f0, 0x8ea521a8} },
+/**/ {{0x3c561573, 0xb5bcc402} },
+/**/ {{0x3face9f0, 0x1d4b9b62} },
+/**/ {{0x3c481226, 0xf2c93cfb} },
+/**/ {{0x3faeda66, 0xb5db8847} },
+/**/ {{0xbc44ec99, 0x3a386670} },
+/**/ {{0xbfb16921, 0xa92559e3} },
+/**/ {{0x3f9ca695, 0x13b2a17d} },
+/**/ {{0x3f81c4bb, 0x355982b3} },
+/**/ {{0xbf95607f, 0x65bec936} },
+/**/ {{0x3f8b4892, 0x4e349f67} } },
+/**/ {{{0x3fe7a000, 0x00000000} },
+/**/ {{0x3fe459c6, 0x52badc7f} },
+/**/ {{0x3c819969, 0x8e8e135c} },
+/**/ {{0x3fe4b60f, 0xec381dcb} },
+/**/ {{0xbc6b9874, 0x4724e4f2} },
+/**/ {{0xbfd3cb01, 0xdc390960} },
+/**/ {{0xbc7243b1, 0x7ba1320c} },
+/**/ {{0x3fad63fe, 0xa09cca72} },
+/**/ {{0x3c48308c, 0xe5ab8d04} },
+/**/ {{0x3fae2d22, 0xdf2eb652} },
+/**/ {{0xbc4988a3, 0x4eb29ad3} },
+/**/ {{0xbfb13dfa, 0x4eb5cb96} },
+/**/ {{0x3f9ce273, 0x8e5b2657} },
+/**/ {{0x3f807288, 0xd132be74} },
+/**/ {{0xbf94e5d8, 0x55a31e9e} },
+/**/ {{0x3f8b399f, 0xfba00cb2} } },
+/**/ {{{0x3fe7c000, 0x00000000} },
+/**/ {{0x3fe46e72, 0x7efe4716} },
+/**/ {{0xbc639b9b, 0x1b844cc9} },
+/**/ {{0x3fe4a24a, 0x749c2a47} },
+/**/ {{0xbc8f9d05, 0x82d8a2e5} },
+/**/ {{0xbfd3bfe5, 0xe5e27a03} },
+/**/ {{0xbc5047da, 0xb30f6d58} },
+/**/ {{0x3faddb5b, 0x75f185ec} },
+/**/ {{0x3c43b680, 0x23d5084a} },
+/**/ {{0x3fad8190, 0x479061d2} },
+/**/ {{0xbbf4565c, 0x602d3547} },
+/**/ {{0xbfb1127c, 0x979e619e} },
+/**/ {{0x3f9d19bf, 0xc03c4720} },
+/**/ {{0x3f7e4ffd, 0x01b2b45f} },
+/**/ {{0xbf946b81, 0x1245b0bb} },
+/**/ {{0x3f8b2525, 0x60fec8ec} } },
+/**/ {{{0x3fe7e000, 0x00000000} },
+/**/ {{0x3fe4830a, 0xeb5f7bfe} },
+/**/ {{0xbc5a2656, 0x66764a73} },
+/**/ {{0x3fe48e90, 0x2f2d2be4} },
+/**/ {{0x3c810a8e, 0x969bba3b} },
+/**/ {{0xbfd3b49d, 0xacfcef4d} },
+/**/ {{0xbc6a4f98, 0xb7a61548} },
+/**/ {{0x3fae500d, 0x68d7d101} },
+/**/ {{0xbc305c3e, 0x04860c21} },
+/**/ {{0x3facd7b2, 0x2c98ea9c} },
+/**/ {{0x3c48692b, 0xd46adca0} },
+/**/ {{0xbfb0e6af, 0x4b37c6a5} },
+/**/ {{0x3f9d4c94, 0x6bfb2662} },
+/**/ {{0x3f7bca2d, 0x0692cc75} },
+/**/ {{0xbf93f191, 0xf3b69312} },
+/**/ {{0x3f8b0b61, 0x1552b8ee} } },
+/**/ {{{0x3fe80000, 0x00000000} },
+/**/ {{0x3fe4978f, 0xa3269ee1} },
+/**/ {{0x3c72419a, 0x87f2a458} },
+/**/ {{0x3fe47ae1, 0x47ae147b} },
+/**/ {{0xbc6eb851, 0xeb851eb8} },
+/**/ {{0xbfd3a92a, 0x30553261} },
+/**/ {{0xbc7f06f6, 0x94467382} },
+/**/ {{0x3faec21b, 0x514d88d8} },
+/**/ {{0x3c3cd061, 0xf45873a6} },
+/**/ {{0x3fac2f8b, 0x88dfb80c} },
+/**/ {{0xbc14fcbc, 0x53add20b} },
+/**/ {{0xbfb0ba99, 0x08c71945} },
+/**/ {{0x3f9d7b0c, 0x3d79f13f} },
+/**/ {{0x3f795393, 0x357dfc67} },
+/**/ {{0xbf937822, 0x3aa97829} },
+/**/ {{0x3f8aec90, 0xa8b90db0} } },
+/**/ {{{0x3fe82000, 0x00000000} },
+/**/ {{0x3fe4ac00, 0xb1c71762} },
+/**/ {{0x3c8b20e7, 0x2382b900} },
+/**/ {{0x3fe4673d, 0xe8e45252} },
+/**/ {{0x3c57d208, 0x67458f9c} },
+/**/ {{0xbfd39d8c, 0x6c24e1b3} },
+/**/ {{0xbc7830c5, 0x973c6d15} },
+/**/ {{0x3faf318c, 0x12b78147} },
+/**/ {{0xbc4fa440, 0xd318184c} },
+/**/ {{0x3fab891f, 0x158b44e7} },
+/**/ {{0x3c4d5f9f, 0x45d7f1f3} },
+/**/ {{0xbfb08e40, 0x47a3e8ba} },
+/**/ {{0x3f9da541, 0xc4c1a21a} },
+/**/ {{0x3f76ec1e, 0x3c0d1d71} },
+/**/ {{0xbf92ff48, 0x152e0bfc} },
+/**/ {{0x3f8ac8f0, 0x9955298f} } },
+/**/ {{{0x3fe84000, 0x00000000} },
+/**/ {{0x3fe4c05e, 0x22de94e5} },
+/**/ {{0xbc8c0ac1, 0xf09f2edf} },
+/**/ {{0x3fe453a6, 0x3c9a6560} },
+/**/ {{0x3c77a95f, 0x828bba02} },
+/**/ {{0xbfd391c5, 0x5a0e5b1c} },
+/**/ {{0x3c7d553d, 0xcd3f76d2} },
+/**/ {{0x3faf9e66, 0x9adede86} },
+/**/ {{0xbc225e54, 0xd6d2bac0} },
+/**/ {{0x3faae46f, 0x4bdf89d7} },
+/**/ {{0x3c39c98c, 0x2b25b8d9} },
+/**/ {{0xbfb061ab, 0x5765a5c1} },
+/**/ {{0x3f9dcb4f, 0x7127d649} },
+/**/ {{0x3f7493ba, 0x13002646} },
+/**/ {{0xbf928718, 0xa397d1a6} },
+/**/ {{0x3f8aa0bc, 0x494648b5} } },
+/**/ {{{0x3fe86000, 0x00000000} },
+/**/ {{0x3fe4d4a8, 0x023414e8} },
+/**/ {{0x3c6e3a89, 0x1daa88b0} },
+/**/ {{0x3fe4401a, 0x6ba2786e} },
+/**/ {{0xbc4b8213, 0xe3b5f317} },
+/**/ {{0xbfd385d5, 0xf11905c0} },
+/**/ {{0xbc72a1e9, 0xa2f42dd1} },
+/**/ {{0x3fb00458, 0xf07a526f} },
+/**/ {{0xbc14f965, 0xac5fd817} },
+/**/ {{0x3faa417e, 0x66ca7da2} },
+/**/ {{0x3c4b1e1a, 0xa050b433} },
+/**/ {{0xbfb034e0, 0x60182e4f} },
+/**/ {{0x3f9ded4f, 0x8cafa41b} },
+/**/ {{0x3f724a50, 0x1fa4f037} },
+/**/ {{0xbf920fa7, 0xfd90e915} },
+/**/ {{0x3f8a742d, 0xf59e7acf} } },
+/**/ {{{0x3fe88000, 0x00000000} },
+/**/ {{0x3fe4e8de, 0x5bb6ec04} },
+/**/ {{0x3c84a33d, 0xbeb3796c} },
+/**/ {{0x3fe42c9a, 0x9dd8fdc1} },
+/**/ {{0x3c5192da, 0xaf80050b} },
+/**/ {{0xbfd379bf, 0x25adf97f} },
+/**/ {{0xbc774019, 0x20cd3651} },
+/**/ {{0x3fb0383a, 0x724dbb01} },
+/**/ {{0x3c5c4e67, 0xeb93e538} },
+/**/ {{0x3fa9a04e, 0x646e65df} },
+/**/ {{0x3c21a7cb, 0x894a6b77} },
+/**/ {{0xbfb007e5, 0x62771c79} },
+/**/ {{0x3f9e0b5c, 0x37a45544} },
+/**/ {{0x3f700fc7, 0x54993092} },
+/**/ {{0xbf919909, 0x37534c25} },
+/**/ {{0x3f8a437e, 0xae51732a} } },
+/**/ {{{0x3fe8a000, 0x00000000} },
+/**/ {{0x3fe4fd01, 0x3b7dd17e} },
+/**/ {{0x3c7d513f, 0x3e7c24b5} },
+/**/ {{0x3fe41926, 0xfa274ef1} },
+/**/ {{0x3c8ad830, 0x4d72ecb3} },
+/**/ {{0xbfd36d81, 0xe995018a} },
+/**/ {{0x3c7e7ec5, 0x6fd6094d} },
+/**/ {{0x3fb06adb, 0x567bb975} },
+/**/ {{0x3c5212c1, 0xf0d7364f} },
+/**/ {{0x3fa900e1, 0x07a9b624} },
+/**/ {{0xbc4e5b5b, 0xc16bcc85} },
+/**/ {{0xbfafb580, 0x705f052b} },
+/**/ {{0x3f9e258f, 0x646ce12e} },
+/**/ {{0x3f6bc808, 0xa3c63841} },
+/**/ {{0xbf91234e, 0x67043d41} },
+/**/ {{0x3f8a0ee6, 0x4f11b221} } },
+/**/ {{{0x3fe8c000, 0x00000000} },
+/**/ {{0x3fe51110, 0xadc5ed81} },
+/**/ {{0x3c723dcd, 0x6832a63e} },
+/**/ {{0x3fe405bf, 0xa6864f90} },
+/**/ {{0xbc7419c5, 0x662cd5df} },
+/**/ {{0xbfd3611f, 0x2bf1f7e4} },
+/**/ {{0xbc6e94dd, 0x65483b78} },
+/**/ {{0x3fb09c3f, 0x23e21be9} },
+/**/ {{0x3c22db63, 0xcaca858d} },
+/**/ {{0x3fa86337, 0xd99c3f1d} },
+/**/ {{0x3c034382, 0xdc0a6dfc} },
+/**/ {{0xbfaf5aed, 0x284f8093} },
+/**/ {{0x3f9e3c02, 0xd396fb43} },
+/**/ {{0x3f678dd3, 0x08b96150} },
+/**/ {{0xbf90ae88, 0xaa2dcc3a} },
+/**/ {{0x3f89d69b, 0x79128ee7} } },
+/**/ {{{0x3fe8e000, 0x00000000} },
+/**/ {{0x3fe5250c, 0xbef1e9fb} },
+/**/ {{0xbc5539b7, 0xa3228870} },
+/**/ {{0x3fe3f264, 0xc8011245} },
+/**/ {{0xbc6641f1, 0x44cc720b} },
+/**/ {{0xbfd35497, 0xd942778a} },
+/**/ {{0x3c750a5a, 0x9bd7dbd6} },
+/**/ {{0x3fb0cc69, 0x6438739e} },
+/**/ {{0x3bf5d933, 0x435f798d} },
+/**/ {{0x3fa7c754, 0x2b29722f} },
+/**/ {{0xbbe736fe, 0x5b3af27b} },
+/**/ {{0xbfaf001c, 0x059a3c24} },
+/**/ {{0x3f9e4ed0, 0x101882b0} },
+/**/ {{0x3f6370ae, 0x88dc4269} },
+/**/ {{0xbf903ac8, 0x2b5280b6} },
+/**/ {{0x3f899ad3, 0x8da5b2ad} } },
+/**/ {{{0x3fe90000, 0x00000000} },
+/**/ {{0x3fe538f5, 0x7b89061f} },
+/**/ {{0xbc81bb74, 0xabda520c} },
+/**/ {{0x3fe3df16, 0x82b78014} },
+/**/ {{0xbc7074be, 0xa43ff610} },
+/**/ {{0xbfd347ec, 0xdb5be2e4} },
+/**/ {{0x3c7848c8, 0x8a0e9303} },
+/**/ {{0x3fb0fb5d, 0xa3a11be4} },
+/**/ {{0x3c3d68f2, 0x09dd0d69} },
+/**/ {{0x3fa72d37, 0x16778170} },
+/**/ {{0xbc4ea85d, 0x2200d1d4} },
+/**/ {{0xbfaea517, 0xd4cdbd49} },
+/**/ {{0x3f9e5e10, 0x6bc61b6f} },
+/**/ {{0x3f5ee0af, 0xd0517524} },
+/**/ {{0xbf8f9038, 0x4f2ec799} },
+/**/ {{0x3f895bc2, 0xa9aaa5bb} } },
+/**/ {{{0x3fe92000, 0x00000000} },
+/**/ {{0x3fe54cca, 0xf0362c8f} },
+/**/ {{0x3c88a324, 0x7f8f43c1} },
+/**/ {{0x3fe3cbd4, 0xf9e1016e} },
+/**/ {{0xbc88dea6, 0x431b67e7} },
+/**/ {{0xbfd33b1f, 0x1969bc63} },
+/**/ {{0x3c6ef16e, 0x5f3d8fd8} },
+/**/ {{0x3fb1291f, 0x703d3bf6} },
+/**/ {{0xbc566e82, 0xb04e0672} },
+/**/ {{0x3fa694e1, 0x806b26f2} },
+/**/ {{0x3c302819, 0xafcee740} },
+/**/ {{0xbfae49eb, 0x16dcee96} },
+/**/ {{0x3f9e69dc, 0xfbfdb35f} },
+/**/ {{0x3f571910, 0x70c48510} },
+/**/ {{0xbf8ead25, 0xe90198c8} },
+/**/ {{0x3f89199b, 0xa1c723cb} } },
+/**/ {{{0x3fe94000, 0x00000000} },
+/**/ {{0x3fe5608d, 0x29c70c34} },
+/**/ {{0x3c89939c, 0xf0de8088} },
+/**/ {{0x3fe3b8a0, 0x4fcf28c3} },
+/**/ {{0xbc469c2b, 0xcb80013c} },
+/**/ {{0xbfd32e2f, 0x77ec4ef9} },
+/**/ {{0x3c7f9d06, 0xc61f7341} },
+/**/ {{0x3fb155b2, 0x59c3bcdf} },
+/**/ {{0xbc2d692e, 0x3583c01b} },
+/**/ {{0x3fa5fe54, 0x1a1fe15d} },
+/**/ {{0x3c430dc5, 0x5d9bad81} },
+/**/ {{0xbfadeea0, 0x01d944a8} },
+/**/ {{0x3f9e724e, 0x9683b244} },
+/**/ {{0x3f4f13d4, 0x491379ef} },
+/**/ {{0xbf8dcc74, 0x0b7cf74b} },
+/**/ {{0x3f88d48f, 0xff5f0625} } },
+/**/ {{{0x3fe96000, 0x00000000} },
+/**/ {{0x3fe5743c, 0x352b33ba} },
+/**/ {{0xbc8ea00d, 0x34c87ea6} },
+/**/ {{0x3fe3a578, 0xa5f05e48} },
+/**/ {{0xbc8ba1ec, 0x00e4639b} },
+/**/ {{0xbfd3211e, 0xd8b7a43f} },
+/**/ {{0xbc6d4b54, 0x676e23a8} },
+/**/ {{0x3fb18119, 0xf11b2c2d} },
+/**/ {{0x3c34855b, 0x3a3bf5fa} },
+/**/ {{0x3fa5698f, 0x625c76bf} },
+/**/ {{0xbc2f758a, 0xbedb0264} },
+/**/ {{0xbfad9340, 0x81b60103} },
+/**/ {{0x3f9e777d, 0xce91900f} },
+/**/ {{0x3f406543, 0x34fddb2f} },
+/**/ {{0xbf8cee3b, 0xe6077f81} },
+/**/ {{0x3f888ccf, 0xfe42afde} } },
+/**/ {{{0x3fe98000, 0x00000000} },
+/**/ {{0x3fe587d8, 0x1f732fbb} },
+/**/ {{0xbc75e5c9, 0xd8c5a950} },
+/**/ {{0x3fe3925e, 0x1cd28c98} },
+/**/ {{0x3c8c8443, 0x1ffec6da} },
+/**/ {{0xbfd313ee, 0x1af2c622} },
+/**/ {{0x3c0a0e9b, 0xbc3f7ac8} },
+/**/ {{0x3fb1ab59, 0xc7f683c3} },
+/**/ {{0x3c5eaf17, 0x12c04500} },
+/**/ {{0x3fa4d693, 0xa7039179} },
+/**/ {{0xbc4c8d74, 0xa4ce58a2} },
+/**/ {{0xbfad37d6, 0x391400b3} },
+/**/ {{0x3f9e7982, 0xf2148a36} },
+/**/ {{0x3f112956, 0xb6df63ca} },
+/**/ {{0xbf8c1294, 0xfbd0f7ee} },
+/**/ {{0x3f88428a, 0x8b0b0a0e} } },
+/**/ {{{0x3fe9a000, 0x00000000} },
+/**/ {{0x3fe59b60, 0xf5cfab9e} },
+/**/ {{0xbc81b04c, 0x41026bc5} },
+/**/ {{0x3fe37f50, 0xd425cdfc} },
+/**/ {{0x3c865633, 0x518aef64} },
+/**/ {{0xbfd3069e, 0x1b1749db} },
+/**/ {{0xbc311c20, 0xa119d9bc} },
+/**/ {{0x3fb1d475, 0x7074cee3} },
+/**/ {{0xbc5102e0, 0x4ff61e2c} },
+/**/ {{0x3fa44561, 0x06804def} },
+/**/ {{0x3c4e829f, 0xc3865804} },
+/**/ {{0xbfacdc6a, 0x82158836} },
+/**/ {{0x3f9e7876, 0x071b2eec} },
+/**/ {{0xbf375b85, 0xf17c4beb} },
+/**/ {{0xbf8b3995, 0x2fa03971} },
+/**/ {{0x3f87f5ed, 0x421a433b} } },
+/**/ {{{0x3fe9c000, 0x00000000} },
+/**/ {{0x3fe5aed6, 0xc5909517} },
+/**/ {{0x3c87312f, 0x714a9436} },
+/**/ {{0x3fe36c50, 0xeabf19f5} },
+/**/ {{0x3c70d1dc, 0x52485cca} },
+/**/ {{0xbfd2f92f, 0xb2f12226} },
+/**/ {{0x3c5400ba, 0x3e5d3d61} },
+/**/ {{0x3fb1fc70, 0x7cc3a41b} },
+/**/ {{0x3c4b58e7, 0x8819ff5b} },
+/**/ {{0x3fa3b5f7, 0x712e9269} },
+/**/ {{0xbc4e436a, 0x7879d8ab} },
+/**/ {{0xbfac8106, 0x6f398221} },
+/**/ {{0x3f9e746e, 0xc97073c7} },
+/**/ {{0xbf4914de, 0xecfc2d6a} },
+/**/ {{0xbf8a6350, 0xcfa74bd5} },
+/**/ {{0x3f87a724, 0x6f38ad9e} } },
+/**/ {{{0x3fe9e000, 0x00000000} },
+/**/ {{0x3fe5c239, 0x9c244261} },
+/**/ {{0xbc831bd4, 0xe9e56b35} },
+/**/ {{0x3fe3595e, 0x7e9af2dc} },
+/**/ {{0x3c81ef2d, 0x9dc90e6a} },
+/**/ {{0xbfd2eba3, 0xb99eb689} },
+/**/ {{0xbc7b12ef, 0x6a2f2701} },
+/**/ {{0x3fb2234e, 0x7ec46b9b} },
+/**/ {{0x3c59f30c, 0x8d415d66} },
+/**/ {{0x3fa32856, 0xaabf0d26} },
+/**/ {{0xbc122571, 0x3f33d7ea} },
+/**/ {{0xbfac25b2, 0xcc3da9ce} },
+/**/ {{0x3f9e6d84, 0xa8630cad} },
+/**/ {{0xbf5308c5, 0xbeba707a} },
+/**/ {{0xbf898fda, 0xa1585fd1} },
+/**/ {{0x3f87565b, 0x0dc54356} } },
+/**/ {{{0x3fea0000, 0x00000000} },
+/**/ {{0x3fe5d589, 0x87169b18} },
+/**/ {{0x3c60028e, 0x4bc5e7ca} },
+/**/ {{0x3fe34679, 0xace01346} },
+/**/ {{0x3c8e6b38, 0x04d19e6b} },
+/**/ {{0xbfd2ddfb, 0x03913da2} },
+/**/ {{0xbc763ec8, 0x9a19adbd} },
+/**/ {{0x3fb24913, 0x07b46905} },
+/**/ {{0xbc4e7be8, 0xd6f0307f} },
+/**/ {{0x3fa29c7e, 0x4b96b773} },
+/**/ {{0xbc24c2cd, 0x9182d783} },
+/**/ {{0xbfabca78, 0x1f071f44} },
+/**/ {{0x3f9e63ce, 0xc4b7b7c4} },
+/**/ {{0xbf59529a, 0x125f35b0} },
+/**/ {{0xbf88bf43, 0xed369b2b} },
+/**/ {{0x3f8703ba, 0xc97185cd} } },
+/**/ {{{0x3fea2000, 0x00000000} },
+/**/ {{0x3fe5e8c6, 0x941043d0} },
+/**/ {{0xbc70bf75, 0xbe451e70} },
+/**/ {{0x3fe333a2, 0x91e21aec} },
+/**/ {{0x3c7ae035, 0x7acfc84f} },
+/**/ {{0xbfd2d036, 0x628d5861} },
+/**/ {{0x3c67c5fb, 0xe463d006} },
+/**/ {{0x3fb26dc1, 0xa7d77fb2} },
+/**/ {{0xbc5432bd, 0xc47ba861} },
+/**/ {{0x3fa2126d, 0xc229bece} },
+/**/ {{0xbc4be1bf, 0x1da8ed9e} },
+/**/ {{0xbfab6f5e, 0xa890e568} },
+/**/ {{0x3f9e5763, 0xeec5339a} },
+/**/ {{0xbf5f68a6, 0x5274aa52} },
+/**/ {{0xbf87f19c, 0x8a9df558} },
+/**/ {{0x3f86af6b, 0xff809dc5} } },
+/**/ {{{0x3fea4000, 0x00000000} },
+/**/ {{0x3fe5fbf0, 0xd0d5cc4a} },
+/**/ {{0xbc5b4cfd, 0x000b7158} },
+/**/ {{0x3fe320d9, 0x49243ad8} },
+/**/ {{0xbc8ce5e0, 0x433f7be5} },
+/**/ {{0xbfd2c256, 0xa5abec2f} },
+/**/ {{0xbc68785b, 0x04494dc1} },
+/**/ {{0x3fb2915d, 0xee25a81c} },
+/**/ {{0x3c3e7045, 0x68b37e8b} },
+/**/ {{0x3fa18a24, 0x5451b7d2} },
+/**/ {{0xbc3b2d29, 0x79d21dd5} },
+/**/ {{0xbfab146e, 0x65dfcf66} },
+/**/ {{0x3f9e485a, 0xa4b895b9} },
+/**/ {{0xbf62a5d4, 0x14770b65} },
+/**/ {{0xbf8726f2, 0xeb7dab0f} },
+/**/ {{0x3f865995, 0xc081d40d} } },
+/**/ {{{0x3fea6000, 0x00000000} },
+/**/ {{0x3fe60f08, 0x4b46e05f} },
+/**/ {{0xbc8dbb86, 0x99945193} },
+/**/ {{0x3fe30e1d, 0xed5be099} },
+/**/ {{0x3c6c6e78, 0x373fae45} },
+/**/ {{0xbfd2b45c, 0x995b3a02} },
+/**/ {{0x3c7cb97b, 0xe7cea2ad} },
+/**/ {{0x3fb2b3eb, 0x67fb0cde} },
+/**/ {{0xbc402927, 0x4920d50b} },
+/**/ {{0x3fa103a1, 0x209f00e4} },
+/**/ {{0xbc36fb57, 0xecac275a} },
+/**/ {{0xbfaab9af, 0x10fb6629} },
+/**/ {{0x3f9e36c9, 0x1100b94a} },
+/**/ {{0xbf657e30, 0x58620e6c} },
+/**/ {{0xbf865f54, 0x2801158e} },
+/**/ {{0x3f86025d, 0xd27eaf07} } },
+/**/ {{{0x3fea8000, 0x00000000} },
+/**/ {{0x3fe6220d, 0x115d7b8e} },
+/**/ {{0xbc62b785, 0x350ee8c1} },
+/**/ {{0x3fe2fb70, 0x98736048} },
+/**/ {{0x3c87a751, 0x4df7c4fa} },
+/**/ {{0xbfd2a649, 0x07603054} },
+/**/ {{0x3c7c41eb, 0xf564247c} },
+/**/ {{0x3fb2d56d, 0xa0cac592} },
+/**/ {{0x3c333138, 0x4e757ddf} },
+/**/ {{0x3fa07ee3, 0x1fa53ce5} },
+/**/ {{0xbc41bd0c, 0x28113a76} },
+/**/ {{0xbfaa5f28, 0x21eb5271} },
+/**/ {{0x3f9e22c5, 0x08df7f4f} },
+/**/ {{0xbf683dca, 0x107b528f} },
+/**/ {{0xbf859acc, 0x0a22f693} },
+/**/ {{0x3f85a9e8, 0xb39536ba} } },
+/**/ {{{0x3feaa000, 0x00000000} },
+/**/ {{0x3fe634ff, 0x312d1f3b} },
+/**/ {{0x3c89d2f3, 0x15f2b598} },
+/**/ {{0x3fe2e8d1, 0x638c9d15} },
+/**/ {{0x3c831ae5, 0xfe1a437d} },
+/**/ {{0xbfd2981c, 0xb6d7f622} },
+/**/ {{0xbc53da87, 0x86e9fe4d} },
+/**/ {{0x3fb2f5e8, 0x21d425b2} },
+/**/ {{0xbc186482, 0xae2616cb} },
+/**/ {{0x3f9ff7d2, 0x4a85a0e4} },
+/**/ {{0xbc294288, 0xe2d9205b} },
+/**/ {{0xbfaa04e0, 0xcfb8dc09} },
+/**/ {{0x3f9e0c64, 0x0b1f9c73} },
+/**/ {{0xbf6ae504, 0xbd3845d8} },
+/**/ {{0xbf84d965, 0x19278cae} },
+/**/ {{0x3f855059, 0x9cf7183b} } },
+/**/ {{{0x3feac000, 0x00000000} },
+/**/ {{0x3fe647de, 0xb8e20b90} },
+/**/ {{0xbc5eca04, 0x023a51cf} },
+/**/ {{0x3fe2d640, 0x6703b033} },
+/**/ {{0x3c870ae6, 0x38039b02} },
+/**/ {{0xbfd289d8, 0x6c39acf5} },
+/**/ {{0xbc71f038, 0x0238a7ee} },
+/**/ {{0x3fb3155e, 0x71da955f} },
+/**/ {{0xbc5faa02, 0xd41f84df} },
+/**/ {{0x3f9ef563, 0xc3c69caa} },
+/**/ {{0x3c331d29, 0x75403dbd} },
+/**/ {{0xbfa9aae0, 0x1174124f} },
+/**/ {{0x3f9df3bb, 0x3eedb30b} },
+/**/ {{0xbf6d7445, 0x1c632765} },
+/**/ {{0xbf841b28, 0xa4fa03e7} },
+/**/ {{0x3f84f5d2, 0x8646990d} } },
+/**/ {{{0x3feae000, 0x00000000} },
+/**/ {{0x3fe65aab, 0xb6c07b03} },
+/**/ {{0xbc67939b, 0x3af32729} },
+/**/ {{0x3fe2c3bd, 0xba718de8} },
+/**/ {{0xbc82d2fc, 0xc4990a2b} },
+/**/ {{0xbfd27b7c, 0xe9586818} },
+/**/ {{0x3c780d5e, 0x880839ca} },
+/**/ {{0x3fb333d4, 0x14dfe9e3} },
+/**/ {{0x3c536469, 0xbce74cae} },
+/**/ {{0x3f9df677, 0xc77983b8} },
+/**/ {{0x3c373272, 0xb42f53aa} },
+/**/ {{0xbfa9512c, 0x9f3c360e} },
+/**/ {{0x3f9dd8df, 0x72d37b24} },
+/**/ {{0xbf6febf1, 0x02e417f5} },
+/**/ {{0xbf83601e, 0xd16a1579} },
+/**/ {{0x3f849a74, 0x294a83e4} } },
+/**/ {{{0x3feb0000, 0x00000000} },
+/**/ {{0x3fe66d66, 0x3923e087} },
+/**/ {{0xbc76ea6f, 0xebe8bbba} },
+/**/ {{0x3fe2b149, 0x74aea886} },
+/**/ {{0x3c868ffd, 0xa9d6d16a} },
+/**/ {{0xbfd26d0a, 0xed65571e} },
+/**/ {{0x3c6cf972, 0x476fb5f2} },
+/**/ {{0x3fb3514c, 0x8be1339f} },
+/**/ {{0x3c5c8c0f, 0x3f722216} },
+/**/ {{0x3f9cfb0b, 0x300f8f9b} },
+/**/ {{0xbc0edd81, 0x38d1c932} },
+/**/ {{0xbfa8f7cc, 0xf34b004f} },
+/**/ {{0x3f9dbbe5, 0x1bd3bde0} },
+/**/ {{0xbf712637, 0x9bf7dceb} },
+/**/ {{0xbf82a84e, 0xa146e5b2} },
+/**/ {{0x3f843e5e, 0x05f2718e} } },
+/**/ {{{0x3feb2000, 0x00000000} },
+/**/ {{0x3fe6800e, 0x4e7e2858} },
+/**/ {{0xbc58ea6a, 0x1b3e90f0} },
+/**/ {{0x3fe29ee3, 0xabd5912c} },
+/**/ {{0xbc61b3cd, 0xb17c28e3} },
+/**/ {{0xbfd25e83, 0x34f221eb} },
+/**/ {{0xbc74c483, 0xfa300585} },
+/**/ {{0x3fb36dcb, 0x5495f6e3} },
+/**/ {{0x3c59b55b, 0x311973fe} },
+/**/ {{0x3f9c031a, 0x9864d139} },
+/**/ {{0x3c28fdf3, 0xbd00e171} },
+/**/ {{0xbfa89ec7, 0x4b026585} },
+/**/ {{0x3f9d9ce0, 0x54a5ed3d} },
+/**/ {{0xbf724b13, 0xa8cb6dfc} },
+/**/ {{0xbf81f3be, 0x015469a9} },
+/**/ {{0x3f83e1ae, 0x66a50a89} } },
+/**/ {{{0x3feb4000, 0x00000000} },
+/**/ {{0x3fe692a4, 0x0556fb6a} },
+/**/ {{0x3c8d94b9, 0x5a8ea2cc} },
+/**/ {{0x3fe28c8c, 0x75459603} },
+/**/ {{0x3c8b1c3b, 0x2945fc08} },
+/**/ {{0xbfd24fe6, 0x79f37468} },
+/**/ {{0xbc4e3751, 0x0ec1ef94} },
+/**/ {{0x3fb38953, 0xe931c53b} },
+/**/ {{0xbc3b108d, 0x16d80688} },
+/**/ {{0x3f9b0ea2, 0x5e1b50b5} },
+/**/ {{0x3c0074c0, 0x63fd1067} },
+/**/ {{0xbfa84621, 0xa7fc7800} },
+/**/ {{0x3f9d7be4, 0xdd10256e} },
+/**/ {{0xbf7364c0, 0xc9592c5e} },
+/**/ {{0xbf814271, 0xd318d707} },
+/**/ {{0x3f838482, 0x64d217b8} } },
+/**/ {{{0x3feb6000, 0x00000000} },
+/**/ {{0x3fe6a527, 0x6c4b0576} },
+/**/ {{0xbc8f6b65, 0x9c46a69e} },
+/**/ {{0x3fe27a43, 0xe5a55de9} },
+/**/ {{0x3c66846e, 0xedc25d49} },
+/**/ {{0xbfd24135, 0x73c3b821} },
+/**/ {{0xbc79202a, 0x56ab5808} },
+/**/ {{0x3fb3a3e9, 0xc0282c84} },
+/**/ {{0x3c4057ca, 0x03d25dab} },
+/**/ {{0x3f9a1d9e, 0xa3eb854d} },
+/**/ {{0xbc3775ed, 0xf03e2fb1} },
+/**/ {{0xbfa7ede1, 0xd11d1043} },
+/**/ {{0x3f9d5906, 0x195e6961} },
+/**/ {{0xbf747373, 0x65130256} },
+/**/ {{0xbf80946d, 0xf77fd664} },
+/**/ {{0x3f8326f5, 0xedc272c2} } },
+/**/ {{{0x3feb8000, 0x00000000} },
+/**/ {{0x3fe6b798, 0x920b3d99} },
+/**/ {{0xbc8a8038, 0x6188c50e} },
+/**/ {{0x3fe2680a, 0x10e5813e} },
+/**/ {{0xbc8f5497, 0x2242a6bc} },
+/**/ {{0xbfd23270, 0xd725fa1c} },
+/**/ {{0x3c757282, 0x5c781b14} },
+/**/ {{0x3fb3bd90, 0x4bf2f124} },
+/**/ {{0x3c31ae9c, 0x6a14ed74} },
+/**/ {{0x3f99300b, 0x53ea1533} },
+/**/ {{0x3c2a8d88, 0x68f98d7e} },
+/**/ {{0xbfa7960d, 0x53a4e537} },
+/**/ {{0x3f9d3457, 0x11f5f086} },
+/**/ {{0xbf757760, 0x19baa1da} },
+/**/ {{0xbf7fd36a, 0xb2a2ca7e} },
+/**/ {{0x3f82c923, 0xc7a02081} } },
+/**/ {{{0x3feba000, 0x00000000} },
+/**/ {{0x3fe6c9f7, 0x855c3198} },
+/**/ {{0x3c7c09de, 0x29bd280d} },
+/**/ {{0x3fe255df, 0x0a431fbd} },
+/**/ {{0x3c8d9866, 0xf09a745d} },
+/**/ {{0xbfd22399, 0x5648fb1f} },
+/**/ {{0x3c412100, 0xb4df0b3e} },
+/**/ {{0x3fb3d64a, 0xfada8899} },
+/**/ {{0x3c3dd891, 0x659c4346} },
+/**/ {{0x3f9845e4, 0x21c2d0a1} },
+/**/ {{0x3c28c6b1, 0xf397827c} },
+/**/ {{0xbfa73ea9, 0x8445c1cc} },
+/**/ {{0x3f9d0dea, 0x730360f8} },
+/**/ {{0xbf7670bb, 0xac51ce30} },
+/**/ {{0xbf7e8493, 0xeef50deb} },
+/**/ {{0x3f826b25, 0x96b119a9} } },
+/**/ {{{0x3febc000, 0x00000000} },
+/**/ {{0x3fe6dc44, 0x551553af} },
+/**/ {{0xbc5bf886, 0x3573828e} },
+/**/ {{0x3fe243c2, 0xe44a7335} },
+/**/ {{0xbc667287, 0x65d1ffd7} },
+/**/ {{0xbfd214af, 0xa0ca68d3} },
+/**/ {{0xbc71296c, 0x88820895} },
+/**/ {{0x3fb3ee1d, 0x36c0c9a2} },
+/**/ {{0x3c540bf6, 0x831dfabe} },
+/**/ {{0x3f975f24, 0x8ce8de84} },
+/**/ {{0xbc125368, 0x43eb5853} },
+/**/ {{0xbfa6e7bb, 0x803788f8} },
+/**/ {{0x3f9ce5d2, 0x8c42d5f9} },
+/**/ {{0xbf775fba, 0xfaadb3ab} },
+/**/ {{0xbf7d3c59, 0xde4c28da} },
+/**/ {{0x3f820d13, 0xe2bf7ef5} } },
+/**/ {{{0x3febe000, 0x00000000} },
+/**/ {{0x3fe6ee7f, 0x10204aef} },
+/**/ {{0x3c8692ee, 0xa3066272} },
+/**/ {{0x3fe231b5, 0xb0d95ee5} },
+/**/ {{0x3c7aae7e, 0x1eb505b6} },
+/**/ {{0xbfd205b4, 0x63ba3e08} },
+/**/ {{0x3c71c6d1, 0xb975517d} },
+/**/ {{0x3fb4050a, 0x64edc729} },
+/**/ {{0x3c4960ed, 0x715db809} },
+/**/ {{0x3f967bc7, 0xe2bc143b} },
+/**/ {{0xbc2cbf17, 0xf0823143} },
+/**/ {{0xbfa69148, 0x2e4dbc47} },
+/**/ {{0x3f9cbc21, 0x50e0982e} },
+/**/ {{0xbf784492, 0xedaa432a} },
+/**/ {{0xbf7bfabd, 0x0b4850f3} },
+/**/ {{0x3f81af06, 0x1caa2f2c} } },
+/**/ {{{0x3fec0000, 0x00000000} },
+/**/ {{0x3fe700a7, 0xc5784634} },
+/**/ {{0xbc78c34d, 0x25aadef6} },
+/**/ {{0x3fe21fb7, 0x8121fb78} },
+/**/ {{0x3c621fb7, 0x8121fb78} },
+/**/ {{0xbfd1f6a8, 0x499e4889} },
+/**/ {{0xbc60e934, 0x6d4e0249} },
+/**/ {{0x3fb41b15, 0xe5decb17} },
+/**/ {{0x3c5194f4, 0xab3541e6} },
+/**/ {{0x3f959bc9, 0x40a374b5} },
+/**/ {{0xbc39dc6e, 0x54be0e10} },
+/**/ {{0xbfa63b54, 0x400d3c9a} },
+/**/ {{0x3f9c90e8, 0x57717232} },
+/**/ {{0xbf791f78, 0x6bfa704e} },
+/**/ {{0xbf7abfbc, 0x643da6dd} },
+/**/ {{0x3f815112, 0xa418ed31} } },
+/**/ {{{0x3fec2000, 0x00000000} },
+/**/ {{0x3fe712be, 0x84295198} },
+/**/ {{0x3c85cd90, 0x337d8881} },
+/**/ {{0x3fe20dc8, 0x65ad1f5b} },
+/**/ {{0xbc88102a, 0xd7b50d48} },
+/**/ {{0xbfd1e78b, 0xfa75d2f4} },
+/**/ {{0x3c723734, 0x619624d2} },
+/**/ {{0x3fb43043, 0x1517663e} },
+/**/ {{0xbc4af8a4, 0xe5e1ddf1} },
+/**/ {{0x3f94bf23, 0x961cd605} },
+/**/ {{0xbc26e86e, 0x5ca14507} },
+/**/ {{0xbfa5e5e4, 0x32c1ffd7} },
+/**/ {{0x3f9c6438, 0xda0191cd} },
+/**/ {{0xbf79f0a0, 0x4d921d2b} },
+/**/ {{0xbf798b55, 0x4e35d54e} },
+/**/ {{0x3f80f34e, 0xcd4f7bfd} } },
+/**/ {{{0x3fec4000, 0x00000000} },
+/**/ {{0x3fe724c3, 0x5b4fae7b} },
+/**/ {{0x3c5948b3, 0x2db3499b} },
+/**/ {{0x3fe1fbe8, 0x6e5ce35d} },
+/**/ {{0x3c8101d1, 0x561e27a3} },
+/**/ {{0xbfd1d860, 0x1bbd70f4} },
+/**/ {{0xbc7b4c97, 0xfa32c4d1} },
+/**/ {{0x3fb44495, 0x48f48a77} },
+/**/ {{0xbc2ccfed, 0xb47fdf89} },
+/**/ {{0x3f93e5d1, 0xa6c1af2c} },
+/**/ {{0xbc14af58, 0xc3b5a19b} },
+/**/ {{0xbfa590fc, 0x5094795f} },
+/**/ {{0x3f9c3623, 0xb638ebc2} },
+/**/ {{0xbf7ab83f, 0x4fa66d0e} },
+/**/ {{0xbf785d83, 0xb787e297} },
+/**/ {{0x3f8095ce, 0xe71b4cea} } },
+/**/ {{{0x3fec6000, 0x00000000} },
+/**/ {{0x3fe736b6, 0x5a172dff} },
+/**/ {{0x3c7775fd, 0x06a892d1} },
+/**/ {{0x3fe1ea17, 0xaa6f2377} },
+/**/ {{0xbc8395a8, 0xcb44ec07} },
+/**/ {{0xbfd1c925, 0x5072ec76} },
+/**/ {{0xbc6e11b3, 0xf650d5de} },
+/**/ {{0x3fb4580f, 0xd281a42b} },
+/**/ {{0xbc55bbce, 0xf63226cb} },
+/**/ {{0x3f930fce, 0x0c411254} },
+/**/ {{0x3c3a4412, 0xc9852726} },
+/**/ {{0xbfa53ca0, 0xb19e766e} },
+/**/ {{0x3f9c06b9, 0x6d941dd5} },
+/**/ {{0xbf7b768a, 0x094128b2} },
+/**/ {{0xbf773642, 0x2a047c42} },
+/**/ {{0x3f8038a6, 0x40d7925f} } },
+/**/ {{{0x3fec8000, 0x00000000} },
+/**/ {{0x3fe74897, 0x8fba8e0f} },
+/**/ {{0x3c47b2a6, 0x165884a1} },
+/**/ {{0x3fe1d856, 0x287ffb8a} },
+/**/ {{0xbc658a1f, 0xfee27a9d} },
+/**/ {{0xbfd1b9dc, 0x39195240} },
+/**/ {{0x3c604646, 0x551dc6bf} },
+/**/ {{0x3fb46ab5, 0xfd4fa866} },
+/**/ {{0x3c5f62a7, 0xc2febe43} },
+/**/ {{0x3f923d13, 0x384eda2c} },
+/**/ {{0x3c3b9a7c, 0x1dfd9f34} },
+/**/ {{0xbfa4e8d5, 0x3cff324c} },
+/**/ {{0x3f9bd60a, 0x25b0d0ad} },
+/**/ {{0xbf7c2bb4, 0xe063d1e6} },
+/**/ {{0xbf761589, 0xdcb54dd5} },
+/**/ {{0x3f7fb7ce, 0x61077b85} } },
+/**/ {{{0x3feca000, 0x00000000} },
+/**/ {{0x3fe75a67, 0x0b82d8d8} },
+/**/ {{0x3c8ee4ac, 0x4c729087} },
+/**/ {{0x3fe1c6a3, 0xf68c4011} },
+/**/ {{0xbc8e54e4, 0x32671c29} },
+/**/ {{0xbfd1aa85, 0x73bd1c8f} },
+/**/ {{0x3c7525ad, 0x41d7bd80} },
+/**/ {{0x3fb47c8b, 0x0f4e0cc0} },
+/**/ {{0x3c2efdd1, 0xd854875c} },
+/**/ {{0x3f916d9b, 0x7688134d} },
+/**/ {{0xbc1abef6, 0x42a6f922} },
+/**/ {{0xbfa4959d, 0xa9ee694e} },
+/**/ {{0x3f9ba425, 0xa8aca118} },
+/**/ {{0xbf7cd7f3, 0xffb6fa1f} },
+/**/ {{0xbf74fb52, 0xc52e395a} },
+/**/ {{0x3f7eff46, 0x31d14661} } },
+/**/ {{{0x3fecc000, 0x00000000} },
+/**/ {{0x3fe76c24, 0xdcc6c6c0} },
+/**/ {{0x3c819525, 0x51adc83d} },
+/**/ {{0x3fe1b501, 0x21f3f28c} },
+/**/ {{0xbc45712f, 0x5f1d67b6} },
+/**/ {{0xbfd19b21, 0x9bf87a43} },
+/**/ {{0xbc64520a, 0xb2071e48} },
+/**/ {{0x3fb48d92, 0x48a59e43} },
+/**/ {{0x3c5f8e56, 0x42014b8b} },
+/**/ {{0x3f90a160, 0xee4caccb} },
+/**/ {{0x3c2bd92b, 0x7b6daa67} },
+/**/ {{0xbfa442fd, 0x80ce3489} },
+/**/ {{0x3f9b711b, 0x65959e45} },
+/**/ {{0xbf7d7b7b, 0x4cc2673a} },
+/**/ {{0xbf73e793, 0xa86f8a8e} },
+/**/ {{0x3f7e47d4, 0xdf91602d} } },
+/**/ {{{0x3fece000, 0x00000000} },
+/**/ {{0x3fe77dd1, 0x12ea22c7} },
+/**/ {{0x3c873260, 0x8fc10d3d} },
+/**/ {{0x3fe1a36d, 0xb77cb1a2} },
+/**/ {{0xbc42c20d, 0x6e625be9} },
+/**/ {{0xbfd18bb1, 0x4af7b13c} },
+/**/ {{0xbc68446b, 0xbc063e5a} },
+/**/ {{0x3fb49dce, 0xe3952cbb} },
+/**/ {{0x3c588e60, 0x58cf9123} },
+/**/ {{0x3f8fb0bb, 0x491cfa44} },
+/**/ {{0x3c1534fc, 0x0e3f2a43} },
+/**/ {{0xbfa3f0f8, 0x1c3b7aca} },
+/**/ {{0x3f9b3cfa, 0x70eb708a} },
+/**/ {{0xbf7e167e, 0x5eaa8b7f} },
+/**/ {{0xbf72da42, 0x2b587c04} },
+/**/ {{0x3f7d9199, 0x882fa65b} } },
+/**/ {{{0x3fed0000, 0x00000000} },
+/**/ {{0x3fe78f6b, 0xbd5d315e} },
+/**/ {{0x3c8406a0, 0x89803740} },
+/**/ {{0x3fe191e9, 0xc35424ca} },
+/**/ {{0xbc8fa3c1, 0xf4be863f} },
+/**/ {{0xbfd17c35, 0x177d9a85} },
+/**/ {{0xbc717b81, 0x6a99d546} },
+/**/ {{0x3fb4ad44, 0x144fffae} },
+/**/ {{0x3c3538b3, 0xdccca2a3} },
+/**/ {{0x3f8e2516, 0xfb2b5523} },
+/**/ {{0x3c0f7c11, 0x60181bd9} },
+/**/ {{0xbfa39f90, 0xaa1cc641} },
+/**/ {{0x3f9b07d1, 0x85304289} },
+/**/ {{0xbf7ea930, 0x756fd193} },
+/**/ {{0xbf71d352, 0xe2a9a0de} },
+/**/ {{0x3f7cdcb1, 0x886fc912} } },
+/**/ {{{0x3fed2000, 0x00000000} },
+/**/ {{0x3fe7a0f4, 0xeb9c19a2} },
+/**/ {{0x3c613c67, 0xcd815f57} },
+/**/ {{0x3fe18075, 0x5112636f} },
+/**/ {{0x3c80a172, 0x7a335b20} },
+/**/ {{0xbfd16cad, 0x95e83705} },
+/**/ {{0x3c62a94b, 0x7b21d5e1} },
+/**/ {{0x3fb4bbf5, 0x08de0a7c} },
+/**/ {{0x3c3570d0, 0x057457a0} },
+/**/ {{0x3f8c9fc8, 0x7d750fdf} },
+/**/ {{0x3c2900a7, 0xfe4cff3c} },
+/**/ {{0xbfa34eca, 0x2caf50ea} },
+/**/ {{0x3f9ad1af, 0x03888c77} },
+/**/ {{0xbf7f33c4, 0x71ac3a86} },
+/**/ {{0xbf70d2b9, 0x6296fd58} },
+/**/ {{0x3f7c2938, 0x886d16b8} } },
+/**/ {{{0x3fed4000, 0x00000000} },
+/**/ {{0x3fe7b26c, 0xad2e50fe} },
+/**/ {{0xbc8ce80d, 0xf30411fb} },
+/**/ {{0x3fe16f10, 0x6bbc577a} },
+/**/ {{0xbc7d0db6, 0xbd8abf47} },
+/**/ {{0xbfd15d1b, 0x58355b5f} },
+/**/ {{0xbc5b5457, 0xbcc70038} },
+/**/ {{0x3fb4c9e4, 0xe8fdd51d} },
+/**/ {{0x3c462959, 0x28ac9383} },
+/**/ {{0x3f8b20c3, 0x2029f143} },
+/**/ {{0xbc2f8a44, 0x2b420400} },
+/**/ {{0xbfa2fea7, 0x7b921c49} },
+/**/ {{0x3f9a9aa0, 0xf468e79e} },
+/**/ {{0xbf7fb66c, 0xcccbcb4f} },
+/**/ {{0xbf6fb0d0, 0x9bd39a5f} },
+/**/ {{0x3f7b7748, 0x8813998f} } },
+/**/ {{{0x3fed6000, 0x00000000} },
+/**/ {{0x3fe7c3d3, 0x11a6092b} },
+/**/ {{0x3c8bb3cb, 0x2d303288} },
+/**/ {{0x3fe15dbb, 0x1dc61b17} },
+/**/ {{0xbc8f0487, 0xbb77dc56} },
+/**/ {{0xbfd14d7e, 0xee0771ca} },
+/**/ {{0x3c72d38b, 0xdc2fcbd0} },
+/**/ {{0x3fb4d716, 0xd6080f0e} },
+/**/ {{0xbc5cb5bc, 0xa9fbc2c3} },
+/**/ {{0x3f89a7f9, 0xfc42e02f} },
+/**/ {{0xbc201eec, 0x857be8a4} },
+/**/ {{0xbfa2af2b, 0x44ceebb3} },
+/**/ {{0x3f9a62b5, 0x08511639} },
+/**/ {{0xbf8018ad, 0xc8de23de} },
+/**/ {{0xbf6dc8a2, 0xc964501a} },
+/**/ {{0x3f7ac6f9, 0xeb913697} } },
+/**/ {{{0x3fed8000, 0x00000000} },
+/**/ {{0x3fe7d528, 0x289fa093} },
+/**/ {{0x3c856082, 0x1e2f3aa9} },
+/**/ {{0x3fe14c75, 0x711551bb} },
+/**/ {{0xbc80c88e, 0x71970f2c} },
+/**/ {{0xbfd13dd8, 0xe4aa5095} },
+/**/ {{0x3c66dd31, 0xb4b7ae12} },
+/**/ {{0x3fb4e38d, 0xead4c211} },
+/**/ {{0x3c513fb0, 0xe392a31e} },
+/**/ {{0x3f88355f, 0xf6b74576} },
+/**/ {{0x3ba8cb44, 0xf3561ab7} },
+/**/ {{0xbfa26058, 0x0de0faaa} },
+/**/ {{0x3f9a29f8, 0x989371f0} },
+/**/ {{0xbf805261, 0x2b085d9a} },
+/**/ {{0xbf6beccb, 0x2511c555} },
+/**/ {{0x3f7a1863, 0x87b9d333} } },
+/**/ {{{0x3feda000, 0x00000000} },
+/**/ {{0x3fe7e66c, 0x01c114fe} },
+/**/ {{0xbc8c82b8, 0x8b760b8d} },
+/**/ {{0x3fe13b3f, 0x6f037c44} },
+/**/ {{0xbc635393, 0x8562c8c0} },
+/**/ {{0xbfd12e29, 0xc7182435} },
+/**/ {{0xbc73da80, 0x0d0fda95} },
+/**/ {{0x3fb4ef4d, 0x3ba21a8b} },
+/**/ {{0xbc17c450, 0x9aa41146} },
+/**/ {{0x3f86c8e7, 0xc39dff46} },
+/**/ {{0x3c1ddd70, 0x800ba9ae} },
+/**/ {{0xbfa21230, 0x34b94b56} },
+/**/ {{0x3f99f078, 0xa827f95a} },
+/**/ {{0xbf808869, 0x19caa997} },
+/**/ {{0xbf6a1d29, 0xf8c46d26} },
+/**/ {{0x3f796b9a, 0xae59da17} } },
+/**/ {{{0x3fedc000, 0x00000000} },
+/**/ {{0x3fe7f79e, 0xacb97898} },
+/**/ {{0x3c8fd5ca, 0x80ead221} },
+/**/ {{0x3fe12a19, 0x20604825} },
+/**/ {{0xbc5cc7d6, 0xa18970f8} },
+/**/ {{0xbfd11e72, 0x1dfe6ba4} },
+/**/ {{0x3c706717, 0x9d653d1c} },
+/**/ {{0x3fb4fa57, 0xd5fcbb3b} },
+/**/ {{0x3c1922c8, 0x5f50bc06} },
+/**/ {{0x3f856283, 0xe93a179f} },
+/**/ {{0xbc01c2ec, 0x5ea7135a} },
+/**/ {{0xbfa1c4b5, 0xf0c06b4f} },
+/**/ {{0x3f99b641, 0xe48a3b04} },
+/**/ {{0xbf80badd, 0xe1280a21} },
+/**/ {{0xbf68599e, 0x1be3c5dd} },
+/**/ {{0x3f78c0b3, 0x3a72c8e6} } },
+/**/ {{{0x3fede000, 0x00000000} },
+/**/ {{0x3fe808c0, 0x3940694b} },
+/**/ {{0xbc800f32, 0x7715f6a5} },
+/**/ {{0x3fe11902, 0x8d73d98e} },
+/**/ {{0x3c71d158, 0x30f8e290} },
+/**/ {{0xbfd10eb2, 0x6fc305eb} },
+/**/ {{0xbc7fd2e3, 0x3858c4b7} },
+/**/ {{0x3fb504b0, 0xc0a99255} },
+/**/ {{0x3c55c054, 0x142e134f} },
+/**/ {{0x3f840226, 0xc2f371cf} },
+/**/ {{0xbbfc85b0, 0xfc7d6225} },
+/**/ {{0xbfa177eb, 0x53d58f53} },
+/**/ {{0x3f997b60, 0xa6a1627d} },
+/**/ {{0xbf80e9d7, 0x89757c78} },
+/**/ {{0xbf66a205, 0x0d433cd6} },
+/**/ {{0x3f7817bf, 0x9c5dbd9f} } },
+/**/ {{{0x3fee0000, 0x00000000} },
+/**/ {{0x3fe819d0, 0xb7158a4d} },
+/**/ {{0xbc7bf762, 0x29d3b917} },
+/**/ {{0x3fe107fb, 0xbe011080} },
+/**/ {{0xbc8107fb, 0xbe011080} },
+/**/ {{0xbfd0feeb, 0x40894fcd} },
+/**/ {{0x3c76fbb9, 0xc155af9a} },
+/**/ {{0x3fb50e5a, 0xfb9125f7} },
+/**/ {{0x3c357762, 0x2f3313b0} },
+/**/ {{0x3f82a7c2, 0x843ba55a} },
+/**/ {{0x3c1f4994, 0x3fc197b7} },
+/**/ {{0xbfa12bd2, 0x4b4ae875} },
+/**/ {{0x3f993fe0, 0xf3b1b1ee} },
+/**/ {{0xbf81156d, 0xd4c2083b} },
+/**/ {{0xbf64f63b, 0x0c35aa9c} },
+/**/ {{0x3f7770d0, 0xe5d0462f} } },
+/**/ {{{0x3fee2000, 0x00000000} },
+/**/ {{0x3fe82ad0, 0x36000005} },
+/**/ {{0x3c74592f, 0xce924d24} },
+/**/ {{0x3fe0f704, 0xb947c8b7} },
+/**/ {{0x3c436cd7, 0x48a651b3} },
+/**/ {{0xbfd0ef1d, 0x1237505b} },
+/**/ {{0x3c69239b, 0x1b86b9d1} },
+/**/ {{0x3fb51759, 0x7fac4e21} },
+/**/ {{0xbc42a8cc, 0xbfce0e36} },
+/**/ {{0x3f815349, 0x3b5f3edd} },
+/**/ {{0xbc25e1f1, 0x88c702d9} },
+/**/ {{0xbfa0e06c, 0xa0df17a9} },
+/**/ {{0x3f9903ce, 0x7e56b8b1} },
+/**/ {{0xbf813db8, 0x3c701e30} },
+/**/ {{0xbf63561b, 0x30c99e47} },
+/**/ {{0x3f76cbf6, 0xd5bffce0} } },
+/**/ {{{0x3fee4000, 0x00000000} },
+/**/ {{0x3fe83bbe, 0xc5cdee22} },
+/**/ {{0x3c631071, 0x04ffc6c3} },
+/**/ {{0x3fe0e61d, 0x86071468} },
+/**/ {{0xbc70ccc4, 0x59be09c9} },
+/**/ {{0xbfd0df48, 0x647af38b} },
+/**/ {{0x3c7dd47c, 0x427c295b} },
+/**/ {{0x3fb51faf, 0x3ef25277} },
+/**/ {{0x3bdf056a, 0xa81026a7} },
+/**/ {{0x3f8004ac, 0xd443a18b} },
+/**/ {{0x3c027610, 0x8178f329} },
+/**/ {{0xbfa095bb, 0xfbb3a658} },
+/**/ {{0x3f98c734, 0xa7859d46} },
+/**/ {{0xbf8162cd, 0xeefe9a81} },
+/**/ {{0xbf61c17f, 0x8330eac0} },
+/**/ {{0x3f76293f, 0xe421c20a} } },
+/**/ {{{0x3fee6000, 0x00000000} },
+/**/ {{0x3fe84c9c, 0x7653f7eb} },
+/**/ {{0xbc383611, 0xfe0a3e8f} },
+/**/ {{0x3fe0d546, 0x2a7f71b5} },
+/**/ {{0x3c757061, 0x596848c6} },
+/**/ {{0xbfd0cf6d, 0xb4cf51a6} },
+/**/ {{0x3c4c99ab, 0x5b18bb8c} },
+/**/ {{0x3fb5275f, 0x24486227} },
+/**/ {{0x3c5b4a59, 0xbb1f4f56} },
+/**/ {{0x3f7d77be, 0x36238bb2} },
+/**/ {{0x3c1ddbd1, 0xcaec6ba2} },
+/**/ {{0xbfa04bc1, 0xe1406cd0} },
+/**/ {{0x3f988a1e, 0x7f96d6ca} },
+/**/ {{0xbf8184c5, 0xcdffc380} },
+/**/ {{0xbf603841, 0x12561f8b} },
+/**/ {{0x3f7588b9, 0x4d81a668} } },
+/**/ {{{0x3fee8000, 0x00000000} },
+/**/ {{0x3fe85d69, 0x576cc2c5} },
+/**/ {{0x3c66b66e, 0x7fc8b8c3} },
+/**/ {{0x3fe0c47e, 0xac74fadc} },
+/**/ {{0xbc8035f8, 0x77bb1887} },
+/**/ {{0xbfd0bf8d, 0x7e8202a9} },
+/**/ {{0x3c798048, 0x1f4d2357} },
+/**/ {{0x3fb52e6c, 0x13725c73} },
+/**/ {{0xbc34c3af, 0xf5b19ded} },
+/**/ {{0x3f7af1a3, 0x7d9c2711} },
+/**/ {{0x3bea7ec7, 0x1af1098d} },
+/**/ {{0xbfa0027f, 0xb643d11f} },
+/**/ {{0x3f984c96, 0xc756b7d7} },
+/**/ {{0xbf81a3b6, 0x6c3ca3ae} },
+/**/ {{0xbf5d7470, 0x13459246} },
+/**/ {{0x3f74ea6f, 0x1e70d9a4} } },
+/**/ {{{0x3feea000, 0x00000000} },
+/**/ {{0x3fe86e25, 0x78f87ae5} },
+/**/ {{0x3c8022b1, 0x375cfe34} },
+/**/ {{0x3fe0b3c7, 0x11319104} },
+/**/ {{0x3c8ac394, 0x25152519} },
+/**/ {{0xbfd0afa8, 0x3ab87c8a} },
+/**/ {{0x3c724f26, 0x27b31384} },
+/**/ {{0x3fb534d8, 0xe904e078} },
+/**/ {{0xbc55bfde, 0xf8948323} },
+/**/ {{0x3f7876ec, 0xa7bb2dfb} },
+/**/ {{0xbc197116, 0x8a87be50} },
+/**/ {{0xbf9f73ed, 0x7f5f95b4} },
+/**/ {{0x3f980ea7, 0xf11c3266} },
+/**/ {{0xbf81bfb6, 0x0c032389} },
+/**/ {{0xbf5a8e77, 0x8bf305a1} },
+/**/ {{0x3f744e6c, 0x3ec72e6d} } },
+/**/ {{{0x3feec000, 0x00000000} },
+/**/ {{0x3fe87ed0, 0xeadc5a2a} },
+/**/ {{0x3c70af5a, 0xd957f4bc} },
+/**/ {{0x3fe0a31f, 0x5d8701b3} },
+/**/ {{0xbc869b25, 0x263ce937} },
+/**/ {{0xbfd09fbe, 0x60757b83} },
+/**/ {{0x3c767aff, 0xa96db9ef} },
+/**/ {{0x3fb53aa8, 0x7a589afb} },
+/**/ {{0xbc4b7e8e, 0x0844ff86} },
+/**/ {{0x3f76077c, 0xacf1a65c} },
+/**/ {{0xbc19a3b2, 0xb13331a9} },
+/**/ {{0xbf9ee450, 0x472733eb} },
+/**/ {{0x3f97d05c, 0x21e541d7} },
+/**/ {{0xbf81d8da, 0x9d9d4dfc} },
+/**/ {{0xbf57be45, 0xd3ce1b4a} },
+/**/ {{0x3f73b4ba, 0x7cb60047} } },
+/**/ {{{0x3feee000, 0x00000000} },
+/**/ {{0x3fe88f6b, 0xbd023119} },
+/**/ {{0xbc532d1d, 0x25aba660} },
+/**/ {{0x3fe09287, 0x95d126c6} },
+/**/ {{0x3c85aad3, 0xeccc37a6} },
+/**/ {{0xbfd08fd0, 0x649e7367} },
+/**/ {{0x3c71e96c, 0xed21a127} },
+/**/ {{0x3fb53fdd, 0x957ec910} },
+/**/ {{0xbc339c23, 0xaf97a601} },
+/**/ {{0x3f73a336, 0x5a18e5a2} },
+/**/ {{0xbc1f7225, 0x477571de} },
+/**/ {{0xbf9e5629, 0xd4044135} },
+/**/ {{0x3f9791bd, 0x32786dc4} },
+/**/ {{0xbf81ef39, 0xbdf030c4} },
+/**/ {{0xbf550386, 0xe21b8bcb} },
+/**/ {{0x3f731d62, 0x97aa7fb2} } },
+/**/ {{{0x3fef0000, 0x00000000} },
+/**/ {{0x3fe89ff5, 0xff57f1f8} },
+/**/ {{0xbc855b9a, 0x5e177a1b} },
+/**/ {{0x3fe081ff, 0xbdf80108} },
+/**/ {{0x3c6ffbdf, 0x80108200} },
+/**/ {{0xbfd07fde, 0xba010928} },
+/**/ {{0x3c38d37f, 0x7bae0295} },
+/**/ {{0x3fb5447b, 0x0136e69f} },
+/**/ {{0x3c50316a, 0x0dda278d} },
+/**/ {{0x3f7149fc, 0x55103947} },
+/**/ {{0x3c176e96, 0x849e505f} },
+/**/ {{0xbf9dc97b, 0xfbe9a2ee} },
+/**/ {{0x3f9752d4, 0xb08adda9} },
+/**/ {{0xbf8202e8, 0xb540d106} },
+/**/ {{0xbf525de5, 0x859de3e9} },
+/**/ {{0x3f72886c, 0x4afd9f21} } },
+/**/ {{{0x3fef2000, 0x00000000} },
+/**/ {{0x3fe8b06f, 0xc1cf3dff} },
+/**/ {{0xbc80fb31, 0x2656db6d} },
+/**/ {{0x3fe07187, 0xd971cd38} },
+/**/ {{0x3c89baa4, 0x202c20ac} },
+/**/ {{0xbfd06fe9, 0xd15893ab} },
+/**/ {{0xbc7a864b, 0xdc0cb586} },
+/**/ {{0x3fb54883, 0x7ce57fed} },
+/**/ {{0xbc49498e, 0x294f4b18} },
+/**/ {{0x3f6df762, 0x426ebecc} },
+/**/ {{0xbc022f08, 0xf28644c0} },
+/**/ {{0xbf9d3e48, 0x5c564b44} },
+/**/ {{0x3f9713ab, 0xdfea7acf} },
+/**/ {{0xbf8213fc, 0x761db35c} },
+/**/ {{0xbf4f9a17, 0x10d60f49} },
+/**/ {{0x3f71f5de, 0x58700e9b} } },
+/**/ {{{0x3fef4000, 0x00000000} },
+/**/ {{0x3fe8c0d9, 0x145cf49d} },
+/**/ {{0x3c8bea40, 0x76dc4333} },
+/**/ {{0x3fe0611f, 0xeb45139a} },
+/**/ {{0x3c7e4998, 0x65aadb1f} },
+/**/ {{0xbfd05ff2, 0x1953a316} },
+/**/ {{0x3c759922, 0xa1b67b0f} },
+/**/ {{0x3fb54bf9, 0xc08c1d66} },
+/**/ {{0x3c5b9353, 0xd220330c} },
+/**/ {{0x3f69706e, 0x478cb604} },
+/**/ {{0xbbfdb6d3, 0xa22fd45a} },
+/**/ {{0xbf9cb490, 0x5c0d1d38} },
+/**/ {{0x3f96d44b, 0xbbaba2f2} },
+/**/ {{0xbf822289, 0x9c6b7de1} },
+/**/ {{0xbf4aa143, 0xa49803b6} },
+/**/ {{0x3f7165be, 0x9270e49e} } },
+/**/ {{{0x3fef6000, 0x00000000} },
+/**/ {{0x3fe8d132, 0x06f8c4cb} },
+/**/ {{0xbc7b018c, 0xbaa89a8b} },
+/**/ {{0x3fe050c7, 0xf60ab1f4} },
+/**/ {{0x3c63f8e2, 0xc6cf5796} },
+/**/ {{0xbfd04ff7, 0xfe998dc0} },
+/**/ {{0x3c77873c, 0x7dc56419} },
+/**/ {{0x3fb54ee0, 0x7cc24121} },
+/**/ {{0x3c313117, 0x8e5c84c5} },
+/**/ {{0x3f64fee1, 0x50066301} },
+/**/ {{0x3c043698, 0x017261a1} },
+/**/ {{0xbf9c2c55, 0x2cc5b4f1} },
+/**/ {{0x3f9694bc, 0xf759f369} },
+/**/ {{0xbf822ea4, 0x6c93426a} },
+/**/ {{0xbf45d0a1, 0x135d6c51} },
+/**/ {{0x3f70d811, 0xe62dc18f} } },
+/**/ {{{0x3fef8000, 0x00000000} },
+/**/ {{0x3fe8e17a, 0xa99cc05e} },
+/**/ {{0xbc7ec182, 0xab042f61} },
+/**/ {{0x3fe0407f, 0xfbefe001} },
+/**/ {{0x3c401ffe, 0xfbf80041} },
+/**/ {{0xbfd03ffb, 0xebd00209} },
+/**/ {{0xbc53ff3c, 0xb9004112} },
+/**/ {{0x3fb5513a, 0x5aaf6d91} },
+/**/ {{0x3c54a20d, 0xc0516ddb} },
+/**/ {{0x3f60a27f, 0xc6ac4038} },
+/**/ {{0x3bf06bee, 0x2a340912} },
+/**/ {{0xbf9ba597, 0xccd6032a} },
+/**/ {{0x3f965508, 0x002bb974} },
+/**/ {{0xbf823860, 0xd2d1068b} },
+/**/ {{0xbf41277e, 0x666265bc} },
+/**/ {{0x3f704cdc, 0x656b66ea} } },
+/**/ {{{0x3fefa000, 0x00000000} },
+/**/ {{0x3fe8f1b3, 0x0c44f167} },
+/**/ {{0x3c6dd1ca, 0xb93933fd} },
+/**/ {{0x3fe03047, 0xfeb82e4e} },
+/**/ {{0x3c69ee56, 0x5272e5ac} },
+/**/ {{0xbfd02ffe, 0x49a09c45} },
+/**/ {{0xbc700a59, 0xb26267bb} },
+/**/ {{0x3fb55309, 0xfc062d2f} },
+/**/ {{0x3c5dba48, 0xb11938e0} },
+/**/ {{0x3f58b61b, 0xe4f365be} },
+/**/ {{0x3bf8b585, 0xa79ad31a} },
+/**/ {{0xbf9b2059, 0x08d4ad17} },
+/**/ {{0x3f961534, 0xfe379940} },
+/**/ {{0xbf823fd2, 0x62a1270e} },
+/**/ {{0xbf394a53, 0x3f3a0aec} },
+/**/ {{0x3f6f8842, 0xa04bcae2} } },
+/**/ {{{0x3fefc000, 0x00000000} },
+/**/ {{0x3fe901db, 0x3eeef187} },
+/**/ {{0x3c868665, 0xe5603c8f} },
+/**/ {{0x3fe0201f, 0xffbf7f80} },
+/**/ {{0x3c20201f, 0xffbf7f80} },
+/**/ {{0xbfd01fff, 0x7ebe8004} },
+/**/ {{0xbc4213ff, 0xcf979001} },
+/**/ {{0x3fb55451, 0xfb0012db} },
+/**/ {{0xbc395606, 0xf73aa59f} },
+/**/ {{0x3f50509f, 0xfc757100} },
+/**/ {{0x3bebc7da, 0xfee554d0} },
+/**/ {{0xbf9a9c99, 0x7d3424d0} },
+/**/ {{0x3f95d54b, 0xd5ac0217} },
+/**/ {{0xbf82450c, 0x564b3c49} },
+/**/ {{0xbf3091df, 0xe6d3e986} },
+/**/ {{0x3f6e7bc6, 0x3bef5a22} } },
+/**/ {{{0x3fefe000, 0x00000000} },
+/**/ {{0x3fe911f3, 0x5199833b} },
+/**/ {{0x3c63ae8a, 0x0edbf522} },
+/**/ {{0x3fe01007, 0xfffbfbfe} },
+/**/ {{0x3ba01007, 0xfffbfbfe} },
+/**/ {{0xbfd00fff, 0xefebf400} },
+/**/ {{0xbc401209, 0xfff9f97d} },
+/**/ {{0x3fb55514, 0xea5aaaf6} },
+/**/ {{0xbc529baa, 0xb5b7b240} },
+/**/ {{0x3f402827, 0xffc7abc4} },
+/**/ {{0x3b5ba3d6, 0xbfee6ab3} },
+/**/ {{0xbf9a1a59, 0x97d67093} },
+/**/ {{0x3f959554, 0x28080aaf} },
+/**/ {{0xbf824821, 0x8e892ce2} },
+/**/ {{0xbf204877, 0xfe70a2a6} },
+/**/ {{0x3f6d7447, 0x0e8ddd67} } },
+/**/ {{{0x3feff800, 0x00000000} },
+/**/ {{0x3fe91dfa, 0xd439826e} },
+/**/ {{0xbc786a19, 0x6df48d55} },
+/**/ {{0x3fe00400, 0x7ffffbff} },
+/**/ {{0xbbeffffe, 0xffbff800} },
+/**/ {{0xbfd003ff, 0xffbfebfd} },
+/**/ {{0xbb600480, 0x9ffff9fe} },
+/**/ {{0x3fb55551, 0x53aa5aab} },
+/**/ {{0xbc542a4a, 0x9baaab5b} },
+/**/ {{0x3f200a02, 0x7fffc7eb} },
+/**/ {{0xbb7dfffe, 0x4770e940} },
+/**/ {{0xbf99b9a5, 0x9997d8d0} },
+/**/ {{0x3f956555, 0x50a80a03} },
+/**/ {{0xbf824914, 0x86456493} },
+/**/ {{0xbf001207, 0x7ffe7329} },
+/**/ {{0x3f6cb1ef, 0x1c63fe2a} } },
+ };
+
+#else
+#ifdef LITTLE_ENDI
+
+ static const number
+ cij[241][7] = { /* x0,cij for (1/16,1) */
+/**/ {{{0X65E0244E, 0X3FB04006} },
+/**/ {{0X7B53DD20, 0X3FB03A73} },
+/**/ {{0XCF5CFB72, 0X3FEFDF1F} },
+/**/ {{0XCE2AE4C2, 0XBFB01EB3} },
+/**/ {{0XDD58A40D, 0XBFD4D29E} },
+/**/ {{0XD907A18A, 0X3FAFDA4A} },
+/**/ {{0X4DF65B18, 0X3FC814DF} } },
+/**/ {{{0XB9B88CD8, 0X3FB0FFFD} },
+/**/ {{0X63645300, 0X3FB0F99C} },
+/**/ {{0XA3DED30F, 0X3FEFDC08} },
+/**/ {{0X669C1AED, 0XBFB0D9DC} },
+/**/ {{0XF7138DE2, 0XBFD4C669} },
+/**/ {{0X29D085A7, 0X3FB0A12F} },
+/**/ {{0XCFD48D20, 0X3FC7F0EE} } },
+/**/ {{{0X5A73D4F1, 0X3FB1FFF1} },
+/**/ {{0X2BEE2040, 0X3FB1F85F} },
+/**/ {{0X42B56D31, 0X3FEFD7B3} },
+/**/ {{0XB69DEA40, 0XBFB1D2B7} },
+/**/ {{0X3922ECC9, 0XBFD4B552} },
+/**/ {{0X522B1A04, 0X3FB18F93} },
+/**/ {{0X5660F061, 0X3FC7BEAD} } },
+/**/ {{{0XB2524AA2, 0X3FB2FFFD} },
+/**/ {{0XE71790A0, 0X3FB2F716} },
+/**/ {{0X53B496A4, 0X3FEFD31F} },
+/**/ {{0X4AAB7374, 0XBFB2CAD8} },
+/**/ {{0X58DD2FB2, 0XBFD4A34B} },
+/**/ {{0XD0CECC18, 0X3FB27C0A} },
+/**/ {{0X5D2743D7, 0X3FC789D2} } },
+/**/ {{{0X0573F3AC, 0X3FB3FFFE} },
+/**/ {{0X1702F6A0, 0X3FB3F59D} },
+/**/ {{0XB071ACC2, 0X3FEFCE4D} },
+/**/ {{0X64DB3686, 0XBFB3C20F} },
+/**/ {{0XEB3BFE93, 0XBFD49059} },
+/**/ {{0XCAF74FED, 0X3FB36659} },
+/**/ {{0X1C011FB0, 0X3FC75269} } },
+/**/ {{{0X894384D6, 0X3FB4FFEF} },
+/**/ {{0X0CE204C0, 0X3FB4F3ED} },
+/**/ {{0XA8EA5A01, 0X3FEFC93E} },
+/**/ {{0X7B5457C9, 0XBFB4B84F} },
+/**/ {{0X7401F2F9, 0XBFD47C80} },
+/**/ {{0XB4F67209, 0X3FB44E64} },
+/**/ {{0X4C540B77, 0X3FC7187D} } },
+/**/ {{{0XDF406528, 0X3FB5FFF8} },
+/**/ {{0X3C73D820, 0X3FB5F22B} },
+/**/ {{0XB1F60F13, 0X3FEFC3F1} },
+/**/ {{0XCB7FA73B, 0XBFB5ADB2} },
+/**/ {{0X2B1EB555, 0XBFD467BE} },
+/**/ {{0X99EDC463, 0X3FB53435} },
+/**/ {{0X238F5059, 0X3FC6DC1B} } },
+/**/ {{{0X8C4F0D56, 0X3FB7000F} },
+/**/ {{0X495A2FA0, 0X3FB6F04B} },
+/**/ {{0X340DCE97, 0X3FEFBE67} },
+/**/ {{0X4D98E1AD, 0XBFB6A224} },
+/**/ {{0X14064DF1, 0XBFD45216} },
+/**/ {{0X2BA78A66, 0X3FB617AA} },
+/**/ {{0X50A3D7AC, 0X3FC69D4F} } },
+/**/ {{{0XBB4057CF, 0X3FB8000F} },
+/**/ {{0XBE2CD3A0, 0X3FB7EE27} },
+/**/ {{0X39EC9246, 0X3FEFB8A0} },
+/**/ {{0X31D9C773, 0XBFB79577} },
+/**/ {{0XB6DC7D72, 0XBFD43B8D} },
+/**/ {{0XD69547DF, 0X3FB6F88A} },
+/**/ {{0XF633CE8C, 0X3FC65C26} } },
+/**/ {{{0X39CF2B7F, 0X3FB8FFF2} },
+/**/ {{0X9F979E80, 0X3FB8EBB7} },
+/**/ {{0X435506E1, 0X3FEFB29D} },
+/**/ {{0X69B9CDB5, 0XBFB8879A} },
+/**/ {{0X85FEAFA9, 0XBFD42428} },
+/**/ {{0XB6191A0E, 0X3FB7D6BA} },
+/**/ {{0XA7CB8BB5, 0X3FC618AF} } },
+/**/ {{{0X6E2F0772, 0X3FB9FFF9} },
+/**/ {{0XD32A9480, 0X3FB9E93A} },
+/**/ {{0X04A3EC40, 0X3FEFAC5D} },
+/**/ {{0X53F6EA97, 0XBFB978C2} },
+/**/ {{0X089C36F6, 0XBFD40BE3} },
+/**/ {{0X885AEB77, 0X3FB8B25C} },
+/**/ {{0X63CADCE1, 0X3FC5D2F7} } },
+/**/ {{{0X6316B097, 0X3FBB0002} },
+/**/ {{0XCE24CC00, 0X3FBAE68C} },
+/**/ {{0X938C5C66, 0X3FEFA5E0} },
+/**/ {{0X76F14E4B, 0XBFBA68C3} },
+/**/ {{0X1696CD7C, 0XBFD3F2C3} },
+/**/ {{0X722A2CB4, 0X3FB98B3B} },
+/**/ {{0X9067AD62, 0X3FC58B0C} } },
+/**/ {{{0X604F58B1, 0X3FBC0008} },
+/**/ {{0X05650780, 0X3FBBE3A7} },
+/**/ {{0X5A7A2773, 0X3FEF9F28} },
+/**/ {{0X3D5AC0A4, 0XBFBB578F} },
+/**/ {{0XF767119F, 0XBFD3D8CB} },
+/**/ {{0XC7E31B88, 0X3FBA613D} },
+/**/ {{0XF5594565, 0X3FC540FD} } },
+/**/ {{{0X6CCA4EBA, 0X3FBD0002} },
+/**/ {{0XC1298A80, 0X3FBCE07E} },
+/**/ {{0XE8D36C4A, 0X3FEF9834} },
+/**/ {{0X5BCAC5FE, 0XBFBC4513} },
+/**/ {{0X8B5236F1, 0XBFD3BE01} },
+/**/ {{0X2E991970, 0X3FBB3447} },
+/**/ {{0XB8ADB373, 0X3FC4F4DA} } },
+/**/ {{{0XB2B47FCA, 0X3FBDFFF4} },
+/**/ {{0X4A051D80, 0X3FBDDD16} },
+/**/ {{0X78DCC895, 0X3FEF9106} },
+/**/ {{0XF0966844, 0XBFBD3149} },
+/**/ {{0X744F9A5F, 0XBFD3A266} },
+/**/ {{0XEDB7F27A, 0X3FBC0446} },
+/**/ {{0X583F9ECA, 0X3FC4A6B2} } },
+/**/ {{{0XA9A05BE0, 0X3FBF000A} },
+/**/ {{0XA3BDA540, 0X3FBED996} },
+/**/ {{0X1B8BA97F, 0X3FEF899C} },
+/**/ {{0X2287A677, 0XBFBE1C51} },
+/**/ {{0XEDC130BB, 0XBFD385F8} },
+/**/ {{0XF306FF50, 0X3FBCD14B} },
+/**/ {{0XA667A72B, 0X3FC45694} } },
+/**/ {{{0XBA8F63DE, 0X3FBFFFFA} },
+/**/ {{0X69FE4780, 0X3FBFD5B5} },
+/**/ {{0X4863DC7D, 0X3FEF81F8} },
+/**/ {{0XD1518706, 0XBFBF05DB} },
+/**/ {{0X4687A69C, 0XBFD368C4} },
+/**/ {{0X1B3868DA, 0X3FBD9B08} },
+/**/ {{0XC345ADFC, 0X3FC40491} } },
+/**/ {{{0X6ECCADA8, 0X3FC07FFA} },
+/**/ {{0X0A396400, 0X3FC068D0} },
+/**/ {{0XF1FCFC6B, 0X3FEF7A19} },
+/**/ {{0X861DF0DF, 0XBFBFEE0C} },
+/**/ {{0X5A586C0C, 0XBFD34AC6} },
+/**/ {{0X189D637A, 0X3FBE618F} },
+/**/ {{0X195779D4, 0X3FC3B0BA} } },
+/**/ {{{0X33432713, 0X3FC10003} },
+/**/ {{0XF203D1A0, 0X3FC0E6B0} },
+/**/ {{0XFE0EB463, 0X3FEF7200} },
+/**/ {{0XE15CB19A, 0XBFC06A72} },
+/**/ {{0XB8DB761E, 0XBFD32C00} },
+/**/ {{0XA11F5E3E, 0X3FBF24D8} },
+/**/ {{0X569E85DD, 0X3FC35B1E} } },
+/**/ {{{0XDA1C4811, 0X3FC17FFC} },
+/**/ {{0X29EBDA00, 0X3FC16462} },
+/**/ {{0X7D558737, 0X3FEF69AF} },
+/**/ {{0X0B33969B, 0XBFC0DD17} },
+/**/ {{0X33AC50D1, 0XBFD30C7D} },
+/**/ {{0X9BE43F0F, 0X3FBFE4AA} },
+/**/ {{0X692539CB, 0X3FC303CF} } },
+/**/ {{{0X3CCA418D, 0X3FC1FFFF} },
+/**/ {{0X3B978EA0, 0X3FC1E1FA} },
+/**/ {{0X45D421A9, 0X3FEF6124} },
+/**/ {{0XACAC8AA8, 0XBFC14F03} },
+/**/ {{0X62E675A3, 0XBFD2EC39} },
+/**/ {{0X2FA6B426, 0X3FC0508C} },
+/**/ {{0X780A6467, 0X3FC2AADE} } },
+/**/ {{{0XD9C78922, 0X3FC27FF7} },
+/**/ {{0X1B91E640, 0X3FC25F66} },
+/**/ {{0XF52E192C, 0X3FEF5860} },
+/**/ {{0XE5DE2394, 0XBFC1C023} },
+/**/ {{0X6BEE0ABD, 0XBFD2CB3D} },
+/**/ {{0X5E075C1A, 0X3FC0ACFB} },
+/**/ {{0XDFFE453A, 0X3FC2505C} } },
+/**/ {{{0XA1FC1AAA, 0X3FC2FFF7} },
+/**/ {{0X83257C40, 0X3FC2DCB5} },
+/**/ {{0XC719B6FB, 0X3FEF4F64} },
+/**/ {{0X61514083, 0XBFC23082} },
+/**/ {{0X7F7B72D5, 0XBFD2A988} },
+/**/ {{0X7C887402, 0X3FC107A7} },
+/**/ {{0X2C3CD6D1, 0X3FC1F45C} } },
+/**/ {{{0X9D78E15E, 0X3FC38005} },
+/**/ {{0X6AC98EE0, 0X3FC359EE} },
+/**/ {{0X944CEC16, 0X3FEF462F} },
+/**/ {{0XD85B87A9, 0XBFC2A020} },
+/**/ {{0X2E4AB369, 0XBFD2871C} },
+/**/ {{0XC31A65D9, 0X3FC1608D} },
+/**/ {{0X130BBE50, 0X3FC196EE} } },
+/**/ {{{0X9F431B1A, 0X3FC40004} },
+/**/ {{0X6BD65360, 0X3FC3D6F3} },
+/**/ {{0XDD99B68A, 0X3FEF3CC3} },
+/**/ {{0XB3DD00ED, 0XBFC30EE1} },
+/**/ {{0XF8482664, 0XBFD26403} },
+/**/ {{0XFE136626, 0X3FC1B792} },
+/**/ {{0X6EAC7440, 0X3FC13824} } },
+/**/ {{{0XE01D95A1, 0X3FC48004} },
+/**/ {{0X86F00CC0, 0X3FC453D3} },
+/**/ {{0XE3970539, 0X3FEF3320} },
+/**/ {{0X0A5279AA, 0XBFC37CCF} },
+/**/ {{0X3B151D5D, 0XBFD2403F} },
+/**/ {{0XE331C9E6, 0X3FC20CBB} },
+/**/ {{0X39E3F097, 0X3FC0D811} } },
+/**/ {{{0XAA9382DD, 0X3FC4FFF7} },
+/**/ {{0X8C590A80, 0X3FC4D07F} },
+/**/ {{0X34DF28E0, 0X3FEF2948} },
+/**/ {{0X5B43915C, 0XBFC3E9D8} },
+/**/ {{0XEB8845A2, 0XBFD21BD5} },
+/**/ {{0XAC6AC8AD, 0X3FC25FF8} },
+/**/ {{0X88ED96CA, 0X3FC076C6} } },
+/**/ {{{0X352408BE, 0X3FC58006} },
+/**/ {{0XC39A73E0, 0X3FC54D1E} },
+/**/ {{0X09AE009C, 0X3FEF1F37} },
+/**/ {{0XB9BE8550, 0XBFC4561C} },
+/**/ {{0X0053F52E, 0XBFD1F6C0} },
+/**/ {{0XEF783BE9, 0X3FC2B15D} },
+/**/ {{0X8615239B, 0X3FC01456} } },
+/**/ {{{0X2B193F81, 0X3FC5FFFF} },
+/**/ {{0X4F73E000, 0X3FC5C980} },
+/**/ {{0XAE110E29, 0X3FEF14F1} },
+/**/ {{0X9098B3D2, 0XBFC4C16E} },
+/**/ {{0X8F058241, 0XBFD1D10F} },
+/**/ {{0XA14FA897, 0X3FC300C6} },
+/**/ {{0XD56607C0, 0X3FBF61A6} } },
+/**/ {{{0X4460E6E1, 0X3FC68008} },
+/**/ {{0X04A55E20, 0X3FC645C8} },
+/**/ {{0X8FA36EC5, 0X3FEF0A75} },
+/**/ {{0XD62FA883, 0XBFC52BE9} },
+/**/ {{0X69A74048, 0XBFD1AABD} },
+/**/ {{0X1679EB02, 0X3FC34E45} },
+/**/ {{0XF7C14C3D, 0X3FBE989E} } },
+/**/ {{{0X9E99A846, 0X3FC6FFFB} },
+/**/ {{0X4B35FD40, 0X3FC6C1D0} },
+/**/ {{0X3EF8EF95, 0X3FEEFFC6} },
+/**/ {{0X76A2FE63, 0XBFC5956B} },
+/**/ {{0XDDC78DDF, 0XBFD183D8} },
+/**/ {{0XAC606D66, 0X3FC399BD} },
+/**/ {{0X070D286A, 0X3FBDCDBA} } },
+/**/ {{{0X0FFCD490, 0X3FC78008} },
+/**/ {{0XB55758E0, 0X3FC73DC5} },
+/**/ {{0X457E2065, 0X3FEEF4E0} },
+/**/ {{0X7D6FF9BC, 0XBFC5FE16} },
+/**/ {{0X9FADD384, 0XBFD15C57} },
+/**/ {{0X73E52D32, 0X3FC3E347} },
+/**/ {{0X9A65AE4B, 0X3FBD011C} } },
+/**/ {{{0X148E79C1, 0X3FC80006} },
+/**/ {{0X2B7F8CA0, 0X3FC7B981} },
+/**/ {{0X701687ED, 0X3FEEE9C7} },
+/**/ {{0X0E1EF36D, 0XBFC665C7} },
+/**/ {{0XCCBCBDAB, 0XBFD13449} },
+/**/ {{0X5C71B3E8, 0X3FC42AC7} },
+/**/ {{0X3E81980E, 0X3FBC32EB} } },
+/**/ {{{0X0F487C17, 0X3FC88006} },
+/**/ {{0XBC0E3640, 0X3FC83511} },
+/**/ {{0XD2D55329, 0X3FEEDE7A} },
+/**/ {{0X37E644BA, 0XBFC6CC87} },
+/**/ {{0X60597557, 0XBFD10BAE} },
+/**/ {{0X13E26FBE, 0X3FC47043} },
+/**/ {{0X6FB18BF4, 0X3FBB634A} } },
+/**/ {{{0XD3518D76, 0X3FC90004} },
+/**/ {{0X8874C100, 0X3FC8B073} },
+/**/ {{0X2ED6673B, 0X3FEED2FB} },
+/**/ {{0X2A6EBAC3, 0XBFC73251} },
+/**/ {{0X6924232F, 0XBFD0E28A} },
+/**/ {{0X73BCC03F, 0X3FC4B3B5} },
+/**/ {{0X8C72507F, 0X3FBA925E} } },
+/**/ {{{0XD2F20D5C, 0X3FC97FFF} },
+/**/ {{0X51AF5920, 0X3FC92BA3} },
+/**/ {{0X3D32449F, 0X3FEEC749} },
+/**/ {{0XC308255F, 0XBFC7971F} },
+/**/ {{0XD572D28F, 0XBFD0B8E2} },
+/**/ {{0X337448FE, 0X3FC4F51A} },
+/**/ {{0XCFCBC620, 0X3FB9C04B} } },
+/**/ {{{0XBF80F060, 0X3FCA0005} },
+/**/ {{0X6E9E8960, 0X3FC9A6AE} },
+/**/ {{0X1EF200E7, 0X3FEEBB64} },
+/**/ {{0X6E96E5C1, 0XBFC7FAFB} },
+/**/ {{0XEC6AD647, 0XBFD08EB6} },
+/**/ {{0XF53D0BA6, 0X3FC53475} },
+/**/ {{0X4433C20E, 0X3FB8ED36} } },
+/**/ {{{0XDEECA8E4, 0X3FCA7FF7} },
+/**/ {{0X948578E0, 0X3FCA2176} },
+/**/ {{0X328FF98B, 0X3FEEAF4F} },
+/**/ {{0X58149B1C, 0XBFC85DC9} },
+/**/ {{0XF933A1AB, 0XBFD06414} },
+/**/ {{0X60C45A8F, 0X3FC571B7} },
+/**/ {{0XBE58C308, 0X3FB81941} } },
+/**/ {{{0X7DEFD553, 0X3FCAFFFF} },
+/**/ {{0X9EBA6B80, 0X3FCA9C22} },
+/**/ {{0X10A85E10, 0X3FEEA307} },
+/**/ {{0X7F9DEA61, 0XBFC8BFA6} },
+/**/ {{0X5A474E8F, 0XBFD038F3} },
+/**/ {{0X30C225D2, 0X3FC5ACF0} },
+/**/ {{0XD062812F, 0X3FB74491} } },
+/**/ {{{0X669932A5, 0X3FCB7FFE} },
+/**/ {{0XCFF6DFE0, 0X3FCB1694} },
+/**/ {{0X1921D387, 0X3FEE968F} },
+/**/ {{0XE075D95A, 0XBFC92078} },
+/**/ {{0X526793C4, 0XBFD00D60} },
+/**/ {{0X73842A52, 0X3FC5E610} },
+/**/ {{0XC5331D5A, 0X3FB66F49} } },
+/**/ {{{0XB44759F3, 0X3FCBFFF9} },
+/**/ {{0X5073A2A0, 0X3FCB90D1} },
+/**/ {{0X56598313, 0X3FEE89E7} },
+/**/ {{0XCFB9203D, 0XBFC98041} },
+/**/ {{0XBED91B37, 0XBFCFC2BC} },
+/**/ {{0X6D4FC2FC, 0X3FC61D19} },
+/**/ {{0X9411537E, 0X3FB5998C} } },
+/**/ {{{0X5568F3EC, 0X3FCC8007} },
+/**/ {{0X4A31DBE0, 0X3FCC0AEC} },
+/**/ {{0X18F270A8, 0X3FEE7D0E} },
+/**/ {{0XF522B132, 0XBFC9DF0E} },
+/**/ {{0X2179C242, 0XBFCF69D4} },
+/**/ {{0X36646FCD, 0X3FC65213} },
+/**/ {{0XDC699095, 0X3FB4C37C} } },
+/**/ {{{0X601A799F, 0X3FCCFFF8} },
+/**/ {{0X49DB66A0, 0X3FCC84B8} },
+/**/ {{0XA0EE780E, 0X3FEE7008} },
+/**/ {{0X3A403934, 0XBFCA3CBB} },
+/**/ {{0XD490BE32, 0XBFCF102F} },
+/**/ {{0X037D4137, 0X3FC684EA} },
+/**/ {{0XD9EC855A, 0X3FB3ED3C} } },
+/**/ {{{0X7BBF1497, 0X3FCD7FF9} },
+/**/ {{0X1E008CE0, 0X3FCCFE5F} },
+/**/ {{0XF04615C7, 0X3FEE62D2} },
+/**/ {{0X15AADE2C, 0XBFCA9965} },
+/**/ {{0X0B44B682, 0XBFCEB5B9} },
+/**/ {{0X92EC8D57, 0X3FC6B5AF} },
+/**/ {{0X60D831AE, 0X3FB316EE} } },
+/**/ {{{0X40209B20, 0X3FCE0008} },
+/**/ {{0XB145A760, 0X3FCD77DD} },
+/**/ {{0XBE1DFDF1, 0X3FEE556D} },
+/**/ {{0X2186AF0F, 0XBFCAF508} },
+/**/ {{0X9420489D, 0XBFCE5A79} },
+/**/ {{0X454FEB2C, 0X3FC6E462} },
+/**/ {{0XD2945A8C, 0X3FB240B2} } },
+/**/ {{{0XC0AE943C, 0X3FCE8000} },
+/**/ {{0X3CA10100, 0X3FCDF111} },
+/**/ {{0X59E7308B, 0X3FEE47DD} },
+/**/ {{0X9439F69F, 0XBFCB4F88} },
+/**/ {{0X798DE600, 0XBFCDFE93} },
+/**/ {{0X8F267389, 0X3FC710F5} },
+/**/ {{0X1A8A373E, 0X3FB16AAB} } },
+/**/ {{{0X6D532803, 0X3FCF0003} },
+/**/ {{0XCB4E5C80, 0X3FCE6A17} },
+/**/ {{0XE3D0F6C2, 0X3FEE3A1E} },
+/**/ {{0X6E31F768, 0XBFCBA8FB} },
+/**/ {{0XE6A382E3, 0XBFCDA1F7} },
+/**/ {{0XB36AC4C0, 0X3FC73B75} },
+/**/ {{0XA3470B0A, 0X3FB094F7} } },
+/**/ {{{0X48B8AFC3, 0X3FCF7FFA} },
+/**/ {{0XE1654560, 0X3FCEE2DB} },
+/**/ {{0X43F2AB37, 0X3FEE2C35} },
+/**/ {{0X598207D6, 0XBFCC014F} },
+/**/ {{0X1EFE809A, 0XBFCD44BF} },
+/**/ {{0X698A561E, 0X3FC763DC} },
+/**/ {{0XA7CF78A3, 0X3FAF7F70} } },
+/**/ {{{0XEB334FAE, 0X3FD00002} },
+/**/ {{0X77AB25E0, 0X3FCF5B7B} },
+/**/ {{0X78A5C127, 0X3FEE1E1D} },
+/**/ {{0XC555D571, 0XBFCC5898} },
+/**/ {{0XB706CF86, 0XBFCCE6D9} },
+/**/ {{0X0823F643, 0X3FC78A35} },
+/**/ {{0X0B9118E8, 0X3FADD619} } },
+/**/ {{{0XA8AF86FE, 0X3FD03FFC} },
+/**/ {{0XB53A0C00, 0X3FCFD3CB} },
+/**/ {{0XFDCBAC8B, 0X3FEE0FDC} },
+/**/ {{0X6C3246FF, 0XBFCCAEB7} },
+/**/ {{0XD6E19AD3, 0XBFCC8870} },
+/**/ {{0XD2C48E91, 0X3FC7AE73} },
+/**/ {{0X0510FDB0, 0X3FAC2E26} } },
+/**/ {{{0XD38984B7, 0X3FD07FFC} },
+/**/ {{0X5732D4A0, 0X3FD025F7} },
+/**/ {{0X49C17AB3, 0X3FEE0170} },
+/**/ {{0X9AFE5028, 0XBFCD03C2} },
+/**/ {{0X9A2C1833, 0XBFCC2971} },
+/**/ {{0X69041DCF, 0X3FC7D0A5} },
+/**/ {{0XF497C653, 0X3FAA87D3} } },
+/**/ {{{0X1ED2ADD7, 0X3FD0BFFF} },
+/**/ {{0XCD7F7420, 0X3FD061ED} },
+/**/ {{0XDA96B750, 0X3FEDF2D8} },
+/**/ {{0XC777881E, 0XBFCD57B2} },
+/**/ {{0X8692B503, 0XBFCBC9EA} },
+/**/ {{0X42ABF9E7, 0X3FC7F0C9} },
+/**/ {{0X04B42BB4, 0X3FA8E35E} } },
+/**/ {{{0XA8515CDA, 0X3FD10003} },
+/**/ {{0X027416A0, 0X3FD09DC9} },
+/**/ {{0X34899950, 0X3FEDE417} },
+/**/ {{0X7983EDE4, 0XBFCDAA86} },
+/**/ {{0X999706B6, 0XBFCB69E3} },
+/**/ {{0XB0F126DB, 0X3FC80EE1} },
+/**/ {{0X17EE9BAB, 0X3FA740FE} } },
+/**/ {{{0XF3AF9CC5, 0X3FD14001} },
+/**/ {{0XB6E1ABA0, 0X3FD0D980} },
+/**/ {{0XE0412681, 0X3FEDD52D} },
+/**/ {{0X6863B28B, 0XBFCDFC31} },
+/**/ {{0XC55B8D5A, 0XBFCB0971} },
+/**/ {{0XA6731AAC, 0X3FC82AED} },
+/**/ {{0XC73BD8F0, 0X3FA5A0EC} } },
+/**/ {{{0XB6122509, 0X3FD18003} },
+/**/ {{0XAA1E67A0, 0X3FD1151D} },
+/**/ {{0X2E0C1F32, 0X3FEDC61B} },
+/**/ {{0XB9BA6B7E, 0XBFCE4CBE} },
+/**/ {{0X90C2431C, 0XBFCAA88E} },
+/**/ {{0X8BCBDA5E, 0X3FC844F4} },
+/**/ {{0X50E585FF, 0X3FA40361} } },
+/**/ {{{0XA6A2A153, 0X3FD1BFFF} },
+/**/ {{0XE7A18DC0, 0X3FD15096} },
+/**/ {{0XE1218F3F, 0X3FEDB6E1} },
+/**/ {{0X9621D6A2, 0XBFCE9C21} },
+/**/ {{0X22627B04, 0XBFCA4750} },
+/**/ {{0XFF8B908E, 0X3FC85CF5} },
+/**/ {{0X9833C0D6, 0X3FA26891} } },
+/**/ {{{0X2D345AAF, 0X3FD1FFFD} },
+/**/ {{0X053BF760, 0X3FD18BF3} },
+/**/ {{0XCC3ACB29, 0X3FEDA780} },
+/**/ {{0X2AA756AE, 0XBFCEEA62} },
+/**/ {{0X47ED9793, 0XBFC9E5B3} },
+/**/ {{0X87AB542A, 0X3FC872F8} },
+/**/ {{0X158E9E9A, 0X3FA0D0B2} } },
+/**/ {{{0XF14CF05A, 0X3FD23FFC} },
+/**/ {{0X4D568460, 0X3FD1C732} },
+/**/ {{0X55F32D3D, 0X3FED97F8} },
+/**/ {{0X21D457C8, 0XBFCF3780} },
+/**/ {{0XF065B845, 0XBFC983BE} },
+/**/ {{0XFBA70CD8, 0X3FC886FF} },
+/**/ {{0XAEB85CCC, 0X3F9E77EB} } },
+/**/ {{{0X0BAE6FC9, 0X3FD27FFE} },
+/**/ {{0X9A27C160, 0X3FD20253} },
+/**/ {{0X4619176E, 0X3FED8849} },
+/**/ {{0X5C0AC9EC, 0XBFCF8379} },
+/**/ {{0X5E645195, 0XBFC9217C} },
+/**/ {{0XF4264515, 0X3FC8990F} },
+/**/ {{0XE6B92E65, 0X3F9B551C} } },
+/**/ {{{0XA297A7DE, 0X3FD2C001} },
+/**/ {{0XACB927C0, 0X3FD23D57} },
+/**/ {{0XE4958FB6, 0X3FED7873} },
+/**/ {{0X43572249, 0XBFCFCE4E} },
+/**/ {{0X9F3560F3, 0XBFC8BEF1} },
+/**/ {{0XDF7F0E5B, 0X3FC8A92C} },
+/**/ {{0X116F3B19, 0X3F983958} } },
+/**/ {{{0X7267616A, 0X3FD2FFFE} },
+/**/ {{0XB2F378C0, 0X3FD27835} },
+/**/ {{0X13906586, 0X3FED687B} },
+/**/ {{0XAFDA1A0F, 0XBFD00BF9} },
+/**/ {{0XC197AD7D, 0XBFC85C34} },
+/**/ {{0X1E99F0A7, 0X3FC8B759} },
+/**/ {{0X6525C365, 0X3F9524FA} } },
+/**/ {{{0X48153B20, 0X3FD33FFE} },
+/**/ {{0X6A2FDCC0, 0X3FD2B2F6} },
+/**/ {{0XF827FBE4, 0X3FED585C} },
+/**/ {{0XB45A6918, 0XBFD03039} },
+/**/ {{0X5DFC3F72, 0XBFC7F93E} },
+/**/ {{0XC5210022, 0X3FC8C39B} },
+/**/ {{0X168FB62E, 0X3F92185E} } },
+/**/ {{{0X8122579A, 0X3FD38003} },
+/**/ {{0XAF6EC1E0, 0X3FD2ED9B} },
+/**/ {{0X872F20D3, 0X3FED4819} },
+/**/ {{0X1F4C1031, 0XBFD053E8} },
+/**/ {{0X621FFD79, 0XBFC79612} },
+/**/ {{0XDB9D9DFC, 0X3FC8CDF9} },
+/**/ {{0X80C6852F, 0X3F8E27B4} } },
+/**/ {{{0X3EF39141, 0X3FD3C003} },
+/**/ {{0X4668C700, 0X3FD3281B} },
+/**/ {{0X18590D1A, 0X3FED37B4} },
+/**/ {{0XA3EF2560, 0XBFD076FE} },
+/**/ {{0X3033287A, 0XBFC732C9} },
+/**/ {{0XCA2E5458, 0X3FC8D676} },
+/**/ {{0XD80944B1, 0X3F882F85} } },
+/**/ {{{0X63FA0E31, 0X3FD40001} },
+/**/ {{0X7B565000, 0X3FD36278} },
+/**/ {{0X47A813DA, 0X3FED272C} },
+/**/ {{0X493B9D88, 0XBFD0997F} },
+/**/ {{0X3DA9FE3C, 0XBFC6CF64} },
+/**/ {{0XC1CD3331, 0X3FC8DD18} },
+/**/ {{0XF70F6E07, 0X3F8248D1} } },
+/**/ {{{0X74071092, 0X3FD44003} },
+/**/ {{0X0F0A4000, 0X3FD39CB8} },
+/**/ {{0X3BA47A6B, 0X3FED1681} },
+/**/ {{0XD8788947, 0XBFD0BB6C} },
+/**/ {{0X589596A6, 0XBFC66BE2} },
+/**/ {{0XC9B3EC1E, 0X3FC8E1E5} },
+/**/ {{0XD20FAB86, 0X3F78E868} } },
+/**/ {{{0XC880F200, 0X3FD48000} },
+/**/ {{0XDEFFB460, 0X3FD3D6D1} },
+/**/ {{0XCADC576C, 0X3FED05B5} },
+/**/ {{0XA1D352C2, 0XBFD0DCC2} },
+/**/ {{0X3D7D2574, 0XBFC60858} },
+/**/ {{0X03208BC0, 0X3FC8E4E3} },
+/**/ {{0X6379E732, 0X3F6AC909} } },
+/**/ {{{0X4D97D2CB, 0X3FD4C000} },
+/**/ {{0XF3A2E220, 0X3FD410CB} },
+/**/ {{0XBB7ED511, 0X3FECF4C8} },
+/**/ {{0X37766A49, 0XBFD0FD84} },
+/**/ {{0X5AABC13C, 0XBFC5A4C2} },
+/**/ {{0XC80DAC4B, 0X3FC8E616} },
+/**/ {{0XB04695C2, 0X3F4038AA} } },
+/**/ {{{0X9397539F, 0X3FD4FFFD} },
+/**/ {{0X06A7DEC0, 0X3FD44AA2} },
+/**/ {{0XCF479DDE, 0X3FECE3BB} },
+/**/ {{0X4D122984, 0XBFD11DAF} },
+/**/ {{0XB1024DF0, 0XBFC5412E} },
+/**/ {{0X1B2C560D, 0X3FC8E587} },
+/**/ {{0X951C088D, 0XBF625DA8} } },
+/**/ {{{0XF304715F, 0X3FD53FFF} },
+/**/ {{0X791F3900, 0X3FD4845A} },
+/**/ {{0XA45E0FD8, 0X3FECD28D} },
+/**/ {{0X8D61F221, 0XBFD13D47} },
+/**/ {{0XD3E9BB99, 0XBFC4DD98} },
+/**/ {{0X0F181507, 0X3FC8E33A} },
+/**/ {{0XD08BD25C, 0XBF743C33} } },
+/**/ {{{0XE88EA386, 0X3FD58002} },
+/**/ {{0XF575D6C0, 0X3FD4BDF0} },
+/**/ {{0X02035609, 0X3FECC140} },
+/**/ {{0XB808071E, 0XBFD15C4A} },
+/**/ {{0XB2945FCF, 0XBFC47A0E} },
+/**/ {{0XFC056447, 0X3FC8DF35} },
+/**/ {{0XB00A45CD, 0XBF7F2011} } },
+/**/ {{{0X70F4D590, 0X3FD5BFFD} },
+/**/ {{0X284D7AE0, 0X3FD4F75D} },
+/**/ {{0XF2DE98B6, 0X3FECAFD5} },
+/**/ {{0XA2B42F42, 0XBFD17AB4} },
+/**/ {{0X1C285A92, 0XBFC416A5} },
+/**/ {{0X511D6C5A, 0X3FC8D982} },
+/**/ {{0X77008605, 0XBF84ECC1} } },
+/**/ {{{0XB70D6E53, 0X3FD5FFFD} },
+/**/ {{0X8E2FF500, 0X3FD530AB} },
+/**/ {{0X32D2429D, 0X3FEC9E4C} },
+/**/ {{0X35190681, 0XBFD1988C} },
+/**/ {{0XBF748319, 0XBFC3B34C} },
+/**/ {{0X98D3A613, 0X3FC8D224} },
+/**/ {{0XAA295F9F, 0XBF8A33D4} } },
+/**/ {{{0X5C7399E2, 0X3FD63FFC} },
+/**/ {{0X4F022E80, 0X3FD569D5} },
+/**/ {{0X58DD180F, 0X3FEC8CA5} },
+/**/ {{0X1D701DE4, 0XBFD1B5CE} },
+/**/ {{0XA7806A5A, 0XBFC35017} },
+/**/ {{0X56C01CF9, 0X3FC8C924} },
+/**/ {{0X942059E1, 0XBF8F64D9} } },
+/**/ {{{0X9A1AC7D2, 0X3FD67FFD} },
+/**/ {{0XF50031E0, 0X3FD5A2DD} },
+/**/ {{0XCEFF6DEB, 0X3FEC7AE0} },
+/**/ {{0X7C8C245B, 0XBFD1D27C} },
+/**/ {{0XC6AA933F, 0XBFC2ED05} },
+/**/ {{0XDDC5CF1F, 0X3FC8BE87} },
+/**/ {{0XD594386F, 0XBF923FB6} } },
+/**/ {{{0X6F7B9353, 0X3FD6BFFD} },
+/**/ {{0XB4E066C0, 0X3FD5DBC1} },
+/**/ {{0X456B591A, 0X3FEC6900} },
+/**/ {{0XC2D6D0AA, 0XBFD1EE95} },
+/**/ {{0XB11086F7, 0XBFC28A23} },
+/**/ {{0XDDE22D5A, 0X3FC8B256} },
+/**/ {{0X489D85A4, 0XBF94C19A} } },
+/**/ {{{0XF02A83E4, 0X3FD6FFFB} },
+/**/ {{0X6A237DC0, 0X3FD61480} },
+/**/ {{0X4CC81773, 0X3FEC5704} },
+/**/ {{0X4B9029CA, 0XBFD20A1A} },
+/**/ {{0X89F5FB1C, 0XBFC22777} },
+/**/ {{0X9B09E911, 0X3FC8A498} },
+/**/ {{0X130D419A, 0XBF9737EC} } },
+/**/ {{{0X128C213A, 0X3FD73FFE} },
+/**/ {{0X42499480, 0X3FD64D1E} },
+/**/ {{0X129C0D30, 0X3FEC44EC} },
+/**/ {{0X83787259, 0XBFD2250C} },
+/**/ {{0XD55BE4FC, 0XBFC1C4FF} },
+/**/ {{0X36B2D603, 0X3FC89553} },
+/**/ {{0X2E43DF46, 0XBF99A284} } },
+/**/ {{{0XEA0CDC7A, 0X3FD77FFB} },
+/**/ {{0X05B0E220, 0X3FD68594} },
+/**/ {{0X687132C0, 0X3FEC32BA} },
+/**/ {{0X7273497E, 0XBFD23F69} },
+/**/ {{0XCD39B037, 0XBFC162CE} },
+/**/ {{0XFA930AAF, 0X3FC8848F} },
+/**/ {{0XA4554412, 0XBF9C013D} } },
+/**/ {{{0XF18EDAB8, 0X3FD7C003} },
+/**/ {{0X4127BEE0, 0X3FD6BDEE} },
+/**/ {{0XC01607BD, 0X3FEC206B} },
+/**/ {{0X5FEE2F42, 0XBFD25937} },
+/**/ {{0X307761E1, 0XBFC100D4} },
+/**/ {{0X5DFEC556, 0X3FC87252} },
+/**/ {{0X7958F973, 0XBF9E53F6} } },
+/**/ {{{0X41F35C4C, 0X3FD7FFFD} },
+/**/ {{0XDA6607A0, 0X3FD6F616} },
+/**/ {{0XCDDC8437, 0X3FEC0E07} },
+/**/ {{0XBFB4DAEA, 0XBFD2726C} },
+/**/ {{0XE0DB1472, 0XBFC09F3B} },
+/**/ {{0X2A95AA1B, 0X3FC85EA9} },
+/**/ {{0XD872CFA2, 0XBFA04D47} } },
+/**/ {{{0X26C7C46B, 0X3FD84003} },
+/**/ {{0X96B8BE00, 0X3FD72E25} },
+/**/ {{0X4CDEDF38, 0X3FEBFB87} },
+/**/ {{0XD09404F3, 0XBFD28B14} },
+/**/ {{0XE7FB61F2, 0XBFC03DE1} },
+/**/ {{0XACB33BE9, 0X3FC84993} },
+/**/ {{0X9B1DE607, 0XBFA16A76} } },
+/**/ {{{0XCA90B179, 0X3FD88003} },
+/**/ {{0XA104A220, 0X3FD7660A} },
+/**/ {{0XF236E2F6, 0X3FEBE8EF} },
+/**/ {{0X19A94DDF, 0XBFD2A329} },
+/**/ {{0X0856A081, 0XBFBFB9CE} },
+/**/ {{0X33F70280, 0X3FC8331F} },
+/**/ {{0XF01308CC, 0XBFA2817A} } },
+/**/ {{{0XE9692FD5, 0X3FD8C003} },
+/**/ {{0XF0B2CB00, 0X3FD79DC9} },
+/**/ {{0XF2966495, 0X3FEBD640} },
+/**/ {{0XFD6EC2EA, 0XBFD2BAAB} },
+/**/ {{0XE08E9C2D, 0XBFBEF892} },
+/**/ {{0X031873E3, 0X3FC81B52} },
+/**/ {{0XAC12113D, 0XBFA39249} } },
+/**/ {{{0X35BE5C5F, 0X3FD8FFFE} },
+/**/ {{0XBDCCDFC0, 0X3FD7D55E} },
+/**/ {{0X6EABCF77, 0X3FEBC37C} },
+/**/ {{0X2D74F445, 0XBFD2D19C} },
+/**/ {{0XE63F2CDB, 0XBFBE382C} },
+/**/ {{0X0E6FE2AE, 0X3FC80236} },
+/**/ {{0X0E66AB41, 0XBFA49CD9} } },
+/**/ {{{0XAA8974CD, 0X3FD94002} },
+/**/ {{0XB8AFD880, 0X3FD80CD6} },
+/**/ {{0X4468CCBA, 0X3FEBB09E} },
+/**/ {{0XEC84E686, 0XBFD2E7FF} },
+/**/ {{0X88C659E8, 0XBFBD7876} },
+/**/ {{0XC2F15460, 0X3FC7E7CC} },
+/**/ {{0XB410D3ED, 0XBFA5A120} } },
+/**/ {{{0XE08EFDEA, 0X3FD98002} },
+/**/ {{0X34856920, 0X3FD84425} },
+/**/ {{0X3F290478, 0X3FEB9DAB} },
+/**/ {{0XBB81EDEF, 0XBFD2FDD2} },
+/**/ {{0X31E68398, 0XBFBCB9A5} },
+/**/ {{0XC2DBB11B, 0X3FC7CC23} },
+/**/ {{0X98467E78, 0XBFA69F19} } },
+/**/ {{{0X75294B6B, 0X3FD9C002} },
+/**/ {{0X299F6200, 0X3FD87B4D} },
+/**/ {{0XDE96CF1F, 0X3FEB8AA2} },
+/**/ {{0X8C4D45D2, 0XBFD31316} },
+/**/ {{0XEDCE4DBA, 0XBFBBFBB7} },
+/**/ {{0X8907FEC9, 0X3FC7AF41} },
+/**/ {{0X07419F55, 0XBFA796BE} } },
+/**/ {{{0XF3E490EC, 0X3FDA0002} },
+/**/ {{0XC21A4500, 0X3FD8B24F} },
+/**/ {{0X3B5EF7DD, 0X3FEB7785} },
+/**/ {{0X8EAE70CD, 0XBFD327CC} },
+/**/ {{0XD49E40DA, 0XBFBB3EB3} },
+/**/ {{0X4D93F7EA, 0X3FC7912D} },
+/**/ {{0X9E21606A, 0XBFA88809} } },
+/**/ {{{0X458461B6, 0X3FDA3FFF} },
+/**/ {{0X7754D2C0, 0X3FD8E928} },
+/**/ {{0X6A0DAF0E, 0X3FEB6454} },
+/**/ {{0XDC2A9A3F, 0XBFD33BF3} },
+/**/ {{0X4917D003, 0XBFBA82B1} },
+/**/ {{0X7C7566CF, 0X3FC771F1} },
+/**/ {{0X3D700DD8, 0XBFA972F9} } },
+/**/ {{{0X87E12AAE, 0X3FDA8002} },
+/**/ {{0XA5DFD000, 0X3FD91FE0} },
+/**/ {{0XA0D82E05, 0X3FEB510D} },
+/**/ {{0XA76AD312, 0XBFD34F90} },
+/**/ {{0XDEEC35AD, 0XBFB9C798} },
+/**/ {{0X8A0EF43E, 0X3FC75190} },
+/**/ {{0X0872EFC8, 0XBFAA578B} } },
+/**/ {{{0X49A86C84, 0X3FDAC001} },
+/**/ {{0X5C4516E0, 0X3FD9566E} },
+/**/ {{0XDD03F6B6, 0X3FEB3DB4} },
+/**/ {{0X291C1F82, 0XBFD362A0} },
+/**/ {{0X03F6DF60, 0XBFB90D95} },
+/**/ {{0X25091E92, 0X3FC73018} },
+/**/ {{0X577A022B, 0XBFAB35BE} } },
+/**/ {{{0X2F4CC2E1, 0X3FDAFFFF} },
+/**/ {{0X94226540, 0X3FD98CD4} },
+/**/ {{0X9297200A, 0X3FEB2A49} },
+/**/ {{0X5153FD01, 0XBFD37524} },
+/**/ {{0XAE3DE27E, 0XBFB854A3} },
+/**/ {{0X7EB3F331, 0X3FC70D8E} },
+/**/ {{0XB6AD570E, 0XBFAC0D93} } },
+/**/ {{{0XC2F3711E, 0X3FDB4000} },
+/**/ {{0X01CDC4C0, 0X3FD9C317} },
+/**/ {{0XEA63781B, 0X3FEB16CA} },
+/**/ {{0X3665B649, 0XBFD3871F} },
+/**/ {{0X3F70FBC6, 0XBFB79CC0} },
+/**/ {{0X061DFC2E, 0X3FC6E9F9} },
+/**/ {{0XD837F9C3, 0XBFACDF0C} } },
+/**/ {{{0XA777E180, 0X3FDB8000} },
+/**/ {{0XF3748F20, 0X3FD9F930} },
+/**/ {{0X0FB0162A, 0X3FEB033B} },
+/**/ {{0X25978CAB, 0XBFD39890} },
+/**/ {{0X5C765AAB, 0XBFB6E602} },
+/**/ {{0X9C16D678, 0X3FC6C562} },
+/**/ {{0X92A16EBF, 0XBFADAA2C} } },
+/**/ {{{0X087E14ED, 0X3FDBBFFD} },
+/**/ {{0XBF0DDB00, 0X3FDA2F20} },
+/**/ {{0X1CCE6E94, 0X3FEAEF9B} },
+/**/ {{0X8B73E3C3, 0XBFD3A977} },
+/**/ {{0X09EFD1CC, 0XBFB63077} },
+/**/ {{0X58408D3A, 0X3FC69FD4} },
+/**/ {{0XD2E48013, 0XBFAE6EF6} } },
+/**/ {{{0XF0086783, 0X3FDC0000} },
+/**/ {{0X8D448080, 0X3FDA64EF} },
+/**/ {{0X35990B5A, 0X3FEADBE8} },
+/**/ {{0X27241B86, 0XBFD3B9D9} },
+/**/ {{0XC20E4001, 0XBFB57C06} },
+/**/ {{0X90E6C8AB, 0X3FC6794F} },
+/**/ {{0X9A630A27, 0XBFAF2D70} } },
+/**/ {{{0X863E58F8, 0X3FDC4001} },
+/**/ {{0X1C3A1BA0, 0X3FDA9A94} },
+/**/ {{0X35ED7DD2, 0X3FEAC826} },
+/**/ {{0X0C075B50, 0XBFD3C9B3} },
+/**/ {{0XA429793C, 0XBFB4C8D7} },
+/**/ {{0X95903C22, 0X3FC651E2} },
+/**/ {{0XF0F8B649, 0XBFAFE59F} } },
+/**/ {{{0X6C62C3BF, 0X3FDC7FFC} },
+/**/ {{0X580A5840, 0X3FDAD00C} },
+/**/ {{0X62D1D808, 0X3FEAB456} },
+/**/ {{0XACBB06EC, 0XBFD3D905} },
+/**/ {{0X421E42DC, 0XBFB416F7} },
+/**/ {{0XE5608EFD, 0X3FC62996} },
+/**/ {{0XF14B649A, 0XBFB04BC5} } },
+/**/ {{{0X34B2A209, 0X3FDCC002} },
+/**/ {{0XF68F3B40, 0X3FDB0565} },
+/**/ {{0X1E3DC946, 0X3FEAA074} },
+/**/ {{0XE2DB674E, 0XBFD3E7D5} },
+/**/ {{0XA4833FFE, 0XBFB3663E} },
+/**/ {{0XC4F0392B, 0X3FC60069} },
+/**/ {{0X38B10201, 0XBFB0A19E} } },
+/**/ {{{0XAAC5F9F9, 0X3FDCFFFC} },
+/**/ {{0X59C45CC0, 0X3FDB3A8E} },
+/**/ {{0XD2389C24, 0X3FEA8C86} },
+/**/ {{0X8362B2CB, 0XBFD3F61F} },
+/**/ {{0XC6C746A6, 0XBFB2B6F1} },
+/**/ {{0X426D2946, 0X3FC5D671} },
+/**/ {{0X4981CE75, 0XBFB0F45D} } },
+/**/ {{{0X0D800C64, 0X3FDD4004} },
+/**/ {{0X88AF6580, 0X3FDB6F99} },
+/**/ {{0X7498CED2, 0X3FEA7887} },
+/**/ {{0XEF8975C0, 0XBFD403E8} },
+/**/ {{0XBEA81E2B, 0XBFB208D4} },
+/**/ {{0X283FFA4E, 0X3FC5ABA5} },
+/**/ {{0X11705130, 0XBFB14408} } },
+/**/ {{{0XB0E64500, 0X3FDD7FFE} },
+/**/ {{0X2324E140, 0X3FDBA472} },
+/**/ {{0X8C5AD680, 0X3FEA647E} },
+/**/ {{0XA03F042D, 0XBFD4112D} },
+/**/ {{0X9580389C, 0XBFB15C33} },
+/**/ {{0X49D9889E, 0X3FC5801E} },
+/**/ {{0XEF96554F, 0XBFB190A3} } },
+/**/ {{{0X2DFCF4EB, 0X3FDDBFFE} },
+/**/ {{0X9F1D27A0, 0X3FDBD926} },
+/**/ {{0X1AC286CA, 0X3FEA5067} },
+/**/ {{0X590A4DE1, 0XBFD41DF2} },
+/**/ {{0X8BD1EFA5, 0XBFB0B0E4} },
+/**/ {{0X702506D0, 0X3FC553D8} },
+/**/ {{0XADA415A6, 0XBFB1DA36} } },
+/**/ {{{0X8A34BBC2, 0X3FDDFFFD} },
+/**/ {{0XC4F7A2C0, 0X3FDC0DB2} },
+/**/ {{0X2EF70BB3, 0X3FEA3C43} },
+/**/ {{0X16EE647C, 0XBFD42A37} },
+/**/ {{0XDB6270BB, 0XBFB006FA} },
+/**/ {{0X86F08DE6, 0X3FC526DE} },
+/**/ {{0X7E5061FB, 0XBFB220C6} } },
+/**/ {{{0XD26415C0, 0X3FDE3FFD} },
+/**/ {{0X58282940, 0X3FDC4217} },
+/**/ {{0XF391DDCB, 0X3FEA2812} },
+/**/ {{0X18EDDF0A, 0XBFD435FD} },
+/**/ {{0X88A589AF, 0XBFAEBCF2} },
+/**/ {{0X4CF96163, 0X3FC4F937} },
+/**/ {{0XF6A18481, 0XBFB26459} } },
+/**/ {{{0X37F72672, 0X3FDE7FFF} },
+/**/ {{0X67AA3DC0, 0X3FDC7654} },
+/**/ {{0XD6CE86B3, 0X3FEA13D6} },
+/**/ {{0X74037E91, 0XBFD44145} },
+/**/ {{0X3B2CC445, 0XBFAD6EC9} },
+/**/ {{0X0564F101, 0X3FC4CAEA} },
+/**/ {{0X0C49CD64, 0XBFB2A4F8} } },
+/**/ {{{0XA11BC00F, 0X3FDEBFFD} },
+/**/ {{0X85E23660, 0X3FDCAA66} },
+/**/ {{0XA25C2396, 0X3FE9FF90} },
+/**/ {{0X8A64724F, 0XBFD44C10} },
+/**/ {{0X2F871E82, 0XBFAC2399} },
+/**/ {{0X0AFBFB85, 0X3FC49C01} },
+/**/ {{0X0F0FF3FE, 0XBFB2E2A8} } },
+/**/ {{{0X3313756D, 0X3FDEFFFF} },
+/**/ {{0X9D30CC20, 0X3FDCDE52} },
+/**/ {{0XDFF9491F, 0X3FE9EB3E} },
+/**/ {{0X7E6ABAAE, 0XBFD45660} },
+/**/ {{0X3E8AA98D, 0XBFAADB4C} },
+/**/ {{0X25D8FF7D, 0X3FC46C7F} },
+/**/ {{0XA71D448D, 0XBFB31D71} } },
+/**/ {{{0X914B856E, 0X3FDF4001} },
+/**/ {{0XAAC1BB20, 0X3FDD1216} },
+/**/ {{0XC9BC4315, 0X3FE9D6E2} },
+/**/ {{0X004E7E91, 0XBFD46036} },
+/**/ {{0XFB901F89, 0XBFA995F7} },
+/**/ {{0X3F5BE04A, 0X3FC43C6D} },
+/**/ {{0XCE8ABF92, 0XBFB3555C} } },
+/**/ {{{0XCD144428, 0X3FDF8003} },
+/**/ {{0XD93E9640, 0X3FDD45B1} },
+/**/ {{0X256FDFEB, 0X3FE9C27D} },
+/**/ {{0X09F7C145, 0XBFD46992} },
+/**/ {{0XED521174, 0XBFA853A9} },
+/**/ {{0X2B27751F, 0X3FC40BD3} },
+/**/ {{0XCFA5C5F2, 0XBFB38A71} } },
+/**/ {{{0X00545BD9, 0X3FDFC002} },
+/**/ {{0XF536D960, 0X3FDD7920} },
+/**/ {{0XAAE99EA5, 0X3FE9AE0F} },
+/**/ {{0X38DD66F4, 0XBFD47275} },
+/**/ {{0XB5484F74, 0XBFA7147D} },
+/**/ {{0XF8EFC373, 0X3FC3DABA} },
+/**/ {{0X3EA6B864, 0XBFB3BCB9} } },
+/**/ {{{0XDA6F2AA8, 0X3FDFFFFB} },
+/**/ {{0XB420FAA0, 0X3FDDAC63} },
+/**/ {{0XED4D0CAB, 0X3FE9999A} },
+/**/ {{0XBFCC6072, 0XBFD47AE0} },
+/**/ {{0X25BF7A4A, 0XBFA5D87C} },
+/**/ {{0XF5999EE5, 0X3FC3A92B} },
+/**/ {{0XF7F09D08, 0XBFB3EC3B} } },
+/**/ {{{0XA65118C8, 0X3FE01FFF} },
+/**/ {{0X2BF70C00, 0X3FDDDF85} },
+/**/ {{0XECD72AE5, 0X3FE9851A} },
+/**/ {{0X8F5794C5, 0XBFD482D7} },
+/**/ {{0X2E4A020B, 0XBFA49F68} },
+/**/ {{0X25A156DA, 0X3FC37722} },
+/**/ {{0X19F58064, 0XBFB41903} } },
+/**/ {{{0X9C0B0556, 0X3FE04001} },
+/**/ {{0XFA2BA200, 0X3FDE127D} },
+/**/ {{0X08C17A55, 0X3FE97093} },
+/**/ {{0X957A7EFD, 0XBFD48A59} },
+/**/ {{0X2648F2BB, 0XBFA36976} },
+/**/ {{0X592569B1, 0X3FC344AB} },
+/**/ {{0X03752DDB, 0XBFB44318} } },
+/**/ {{{0XC24501DB, 0X3FE05FFF} },
+/**/ {{0XA495BCC0, 0X3FDE4547} },
+/**/ {{0X4F225B79, 0X3FE95C06} },
+/**/ {{0X2163F5B8, 0XBFD49167} },
+/**/ {{0X4B79B89F, 0XBFA236D3} },
+/**/ {{0XB530B7BE, 0X3FC311D4} },
+/**/ {{0X4D931476, 0XBFB46A84} } },
+/**/ {{{0X865125FC, 0X3FE07FFE} },
+/**/ {{0X2A5FAD60, 0X3FDE77E9} },
+/**/ {{0X5C13B0EA, 0X3FE94772} },
+/**/ {{0X6F33ABCA, 0XBFD49802} },
+/**/ {{0XDE947C6B, 0XBFA1075A} },
+/**/ {{0XD8D5E01B, 0X3FC2DE9D} },
+/**/ {{0XCA17CA60, 0XBFB48F51} } },
+/**/ {{{0X107EAC25, 0X3FE0A002} },
+/**/ {{0X08243180, 0X3FDEAA69} },
+/**/ {{0XF339824B, 0X3FE932D4} },
+/**/ {{0X7145F475, 0XBFD49E2D} },
+/**/ {{0X00571424, 0XBF9FB5D8} },
+/**/ {{0X85D1CF84, 0X3FC2AB06} },
+/**/ {{0X7DBBBABE, 0XBFB4B18A} } },
+/**/ {{{0X7376E5D4, 0X3FE0BFFF} },
+/**/ {{0XF79FF560, 0X3FDEDCB5} },
+/**/ {{0X8EE1B492, 0X3FE91E35} },
+/**/ {{0X49498453, 0XBFD4A3E7} },
+/**/ {{0XBE685C6F, 0XBF9D63E4} },
+/**/ {{0XC4B1F032, 0X3FC27726} },
+/**/ {{0X9E6ECC3A, 0XBFB4D138} } },
+/**/ {{{0X1715EE2E, 0X3FE0DFFE} },
+/**/ {{0X9BE1BB80, 0X3FDF0EDB} },
+/**/ {{0XD993BD60, 0X3FE9098F} },
+/**/ {{0X9B84E907, 0XBFD4A932} },
+/**/ {{0XE07DBA5E, 0XBF9B185A} },
+/**/ {{0XF2D7A804, 0X3FC242F8} },
+/**/ {{0X8DDAA340, 0XBFB4EE66} } },
+/**/ {{{0X7F3D776C, 0X3FE10001} },
+/**/ {{0X6119E100, 0X3FDF40DF} },
+/**/ {{0XFB44BCFB, 0X3FE8F4E1} },
+/**/ {{0X16E3467E, 0XBFD4AE11} },
+/**/ {{0XCF368422, 0XBF98D304} },
+/**/ {{0X736708AE, 0X3FC20E7D} },
+/**/ {{0XD7B3658D, 0XBFB5091E} } },
+/**/ {{{0XFD8C7B65, 0X3FE11FFE} },
+/**/ {{0X8FD21560, 0X3FDF72B0} },
+/**/ {{0X4770FB0A, 0X3FE8E033} },
+/**/ {{0X5C0F6783, 0XBFD4B282} },
+/**/ {{0X7FFE0364, 0XBF9694AC} },
+/**/ {{0XE529BF4C, 0X3FC1D9CB} },
+/**/ {{0X2C73E5F0, 0XBFB5216C} } },
+/**/ {{{0XAFA3EE71, 0X3FE14000} },
+/**/ {{0XE3324D60, 0X3FDFA45E} },
+/**/ {{0X9FF684DF, 0X3FE8CB7D} },
+/**/ {{0X17ADD34D, 0XBFD4B689} },
+/**/ {{0X67276E70, 0XBF945CA3} },
+/**/ {{0XA1FBF3B1, 0X3FC1A4D9} },
+/**/ {{0X5FBA2374, 0XBFB53759} } },
+/**/ {{{0X73336187, 0X3FE15FFF} },
+/**/ {{0X3DE48D00, 0X3FDFD5DF} },
+/**/ {{0X0CBE3546, 0X3FE8B6C6} },
+/**/ {{0X9B291BCB, 0XBFD4BA25} },
+/**/ {{0X5FB712CC, 0XBF922B6F} },
+/**/ {{0X55E28B0B, 0X3FC16FB8} },
+/**/ {{0X633F423C, 0XBFB54AF1} } },
+/**/ {{{0X6C447B82, 0X3FE17FFF} },
+/**/ {{0X0208ECC0, 0X3FE0039C} },
+/**/ {{0X48F15926, 0X3FE8A20A} },
+/**/ {{0XA5808AC3, 0XBFD4BD59} },
+/**/ {{0X5EEF6F2A, 0XBF9000CD} },
+/**/ {{0XEBE54AA7, 0X3FC13A66} },
+/**/ {{0X45420CE4, 0XBFB55C3F} } },
+/**/ {{{0XAE932B61, 0X3FE19FFF} },
+/**/ {{0XE0091BC0, 0X3FE01C33} },
+/**/ {{0X55664E00, 0X3FE88D4B} },
+/**/ {{0X579F5ABB, 0XBFD4C026} },
+/**/ {{0X8797C32A, 0XBF8BB9A6} },
+/**/ {{0X95D4F64E, 0X3FC104EC} },
+/**/ {{0X2BBC325E, 0XBFB56B4E} } },
+/**/ {{{0XBA12AE50, 0X3FE1BFFF} },
+/**/ {{0XD3ABA020, 0X3FE034B6} },
+/**/ {{0XEBDCCF04, 0X3FE87889} },
+/**/ {{0XE6D463C1, 0XBFD4C28C} },
+/**/ {{0XB36211FC, 0XBF877F1C} },
+/**/ {{0XB90B11E7, 0X3FC0CF4F} },
+/**/ {{0X52DCBE1A, 0XBFB57829} } },
+/**/ {{{0X4B459E41, 0X3FE1E001} },
+/**/ {{0X2DC05800, 0X3FE04D26} },
+/**/ {{0X51625B6A, 0X3FE863C5} },
+/**/ {{0XAFFDD399, 0XBFD4C48E} },
+/**/ {{0X603059CA, 0XBF8351CB} },
+/**/ {{0XDE65D0D9, 0X3FC09992} },
+/**/ {{0X087BB367, 0XBFB582DC} } },
+/**/ {{{0X32306F33, 0X3FE20000} },
+/**/ {{0XBAFB6CE0, 0X3FE0657E} },
+/**/ {{0XA1E2EEC3, 0X3FE84F00} },
+/**/ {{0XB79EC8C6, 0XBFD4C62C} },
+/**/ {{0XD95DE8D1, 0XBF7E6488} },
+/**/ {{0X661DF241, 0X3FC063C2} },
+/**/ {{0XAAA63BAD, 0XBFB58B71} } },
+/**/ {{{0XD30A486C, 0X3FE22000} },
+/**/ {{0XD2165080, 0X3FE07DC3} },
+/**/ {{0X66B3E5BF, 0X3FE83A39} },
+/**/ {{0X7DE04DEE, 0XBFD4C768} },
+/**/ {{0X800F052F, 0XBF763FF7} },
+/**/ {{0X28F35EDD, 0X3FC02DDC} },
+/**/ {{0XA351CF91, 0XBFB591F5} } },
+/**/ {{{0X215E03FC, 0X3FE23FFE} },
+/**/ {{0X9F380A00, 0X3FE095F1} },
+/**/ {{0X48BE5F3F, 0X3FE82573} },
+/**/ {{0X1B793F77, 0XBFD4C843} },
+/**/ {{0X625993B8, 0XBF6C6E63} },
+/**/ {{0X8C5E4B3B, 0X3FBFEFDB} },
+/**/ {{0X66FE9CA7, 0XBFB59673} } },
+/**/ {{{0X6833D65D, 0X3FE26000} },
+/**/ {{0X6496A8C0, 0X3FE0AE0E} },
+/**/ {{0X45B44AA3, 0X3FE810A9} },
+/**/ {{0X055B407A, 0XBFD4C8BE} },
+/**/ {{0XAE83F0A4, 0XBF5920A7} },
+/**/ {{0X860A6A5E, 0X3FBF83DC} },
+/**/ {{0X70D98EE7, 0XBFB598F6} } },
+/**/ {{{0XE82D4D50, 0X3FE28000} },
+/**/ {{0X095F5300, 0X3FE0C615} },
+/**/ {{0X1E9337B7, 0X3FE7FBE0} },
+/**/ {{0X573C6F6A, 0XBFD4C8DA} },
+/**/ {{0XC50F565D, 0X3F38B6C7} },
+/**/ {{0XC9C4B6CA, 0X3FBF17DB} },
+/**/ {{0X45D6DAE0, 0XBFB5998A} } },
+/**/ {{{0X203B6A0B, 0X3FE29FFF} },
+/**/ {{0X30852720, 0X3FE0DE05} },
+/**/ {{0X8520538D, 0X3FE7E718} },
+/**/ {{0X668C6963, 0XBFD4C899} },
+/**/ {{0XBECA8AB0, 0X3F6286EC} },
+/**/ {{0X9B6AC5BD, 0X3FBEABE4} },
+/**/ {{0X575A9684, 0XBFB5983A} } },
+/**/ {{{0XE91A9D93, 0X3FE2C001} },
+/**/ {{0XF7817A20, 0X3FE0F5E3} },
+/**/ {{0X63A45D97, 0X3FE7D24E} },
+/**/ {{0X5F83C46D, 0XBFD4C7FC} },
+/**/ {{0X5D9C800A, 0X3F70E199} },
+/**/ {{0X3721A8E0, 0X3FBE3FE9} },
+/**/ {{0X377DA840, 0XBFB59512} } },
+/**/ {{{0XC6FB4948, 0X3FE2DFFF} },
+/**/ {{0X4CE36040, 0X3FE10DAA} },
+/**/ {{0X3E39011F, 0X3FE7BD88} },
+/**/ {{0XB5EAE11F, 0XBFD4C704} },
+/**/ {{0X192C622B, 0X3F786398} },
+/**/ {{0XB62BA357, 0X3FBDD412} },
+/**/ {{0X5F0E020E, 0XBFB5901D} } },
+/**/ {{{0X39CB4EED, 0X3FE2FFFF} },
+/**/ {{0X0970AD60, 0X3FE1255D} },
+/**/ {{0X365B7A9B, 0X3FE7A8C2} },
+/**/ {{0X8925F532, 0XBFD4C5B3} },
+/**/ {{0X785E3070, 0X3F7FCB03} },
+/**/ {{0X0EEDF3B3, 0X3FBD6854} },
+/**/ {{0X479C252A, 0XBFB58967} } },
+/**/ {{{0X002E31CB, 0X3FE31FFE} },
+/**/ {{0X81FD3780, 0X3FE13CFA} },
+/**/ {{0X1BBE9667, 0X3FE793FE} },
+/**/ {{0X3046F4C7, 0XBFD4C40A} },
+/**/ {{0X8F5E6BF1, 0X3F838BAE} },
+/**/ {{0X83775C98, 0X3FBCFCBD} },
+/**/ {{0X62E887AB, 0XBFB580FB} } },
+/**/ {{{0XEDC7BFFD, 0X3FE34000} },
+/**/ {{0X44D05200, 0X3FE15486} },
+/**/ {{0X244A1DA5, 0X3FE77F39} },
+/**/ {{0X9FB764C1, 0XBFD4C209} },
+/**/ {{0X851B0BE5, 0X3F8724E2} },
+/**/ {{0X507C76E0, 0X3FBC9147} },
+/**/ {{0X19C7F0AB, 0XBFB576E5} } },
+/**/ {{{0XCE042830, 0X3FE36001} },
+/**/ {{0XC1656AE0, 0X3FE16BFB} },
+/**/ {{0XAD3B2B77, 0X3FE76A77} },
+/**/ {{0X74AAC296, 0XBFD4BFB3} },
+/**/ {{0X05B229C2, 0X3F8AB070} },
+/**/ {{0X87DCA54B, 0X3FBC260E} },
+/**/ {{0XC90DF763, 0XBFB56B2F} } },
+/**/ {{{0X89B8FC54, 0X3FE37FFE} },
+/**/ {{0X77D0BA80, 0X3FE18359} },
+/**/ {{0X660CAA3D, 0X3FE755BB} },
+/**/ {{0X308BB975, 0XBFD4BD09} },
+/**/ {{0XFE0A1240, 0X3F8E2E26} },
+/**/ {{0X18790F26, 0X3FBBBB22} },
+/**/ {{0XC094F3DA, 0XBFB55DE6} } },
+/**/ {{{0X9B4DA842, 0X3FE3A001} },
+/**/ {{0X100CD140, 0X3FE19AA7} },
+/**/ {{0XD801F889, 0X3FE740FD} },
+/**/ {{0X2C32C656, 0XBFD4BA0B} },
+/**/ {{0X8ECA44A2, 0X3F90CF99} },
+/**/ {{0XC9863443, 0X3FBB5066} },
+/**/ {{0X406672B5, 0XBFB54F15} } },
+/**/ {{{0XCE6B63E8, 0X3FE3C000} },
+/**/ {{0X1D0B0AE0, 0X3FE1B1DD} },
+/**/ {{0XF28670E6, 0X3FE72C45} },
+/**/ {{0X92422E2E, 0XBFD4B6BB} },
+/**/ {{0XA0D32146, 0X3F928141} },
+/**/ {{0X37452321, 0X3FBAE606} },
+/**/ {{0X77D91F56, 0XBFB53EC6} } },
+/**/ {{{0X114A2607, 0X3FE3DFFF} },
+/**/ {{0XC6FF6F20, 0X3FE1C8FD} },
+/**/ {{0X206847A7, 0X3FE71792} },
+/**/ {{0X669BD306, 0XBFD4B31B} },
+/**/ {{0X04FFD28A, 0X3F942C3A} },
+/**/ {{0XE7FC0825, 0X3FBA7BFD} },
+/**/ {{0X82F471BA, 0XBFB52D05} } },
+/**/ {{{0XC1DA9B7D, 0X3FE3FFFF} },
+/**/ {{0X7F2E8840, 0X3FE1E00B} },
+/**/ {{0X84371133, 0X3FE702E0} },
+/**/ {{0X8012FBE4, 0XBFD4AF2B} },
+/**/ {{0XBFC47F4B, 0X3F95D0B4} },
+/**/ {{0XD80AB6C5, 0X3FBA1249} },
+/**/ {{0X69A4108D, 0XBFB519DD} } },
+/**/ {{{0XE11D9C33, 0X3FE41FFE} },
+/**/ {{0X67C3EC20, 0X3FE1F703} },
+/**/ {{0X026A76A0, 0X3FE6EE34} },
+/**/ {{0X96514B12, 0XBFD4AAED} },
+/**/ {{0X07BA2905, 0X3F976E83} },
+/**/ {{0X261A1221, 0X3FB9A8FE} },
+/**/ {{0X1D552BA0, 0XBFB50559} } },
+/**/ {{{0XFA174676, 0X3FE43FFF} },
+/**/ {{0X0FAFF860, 0X3FE20DE8} },
+/**/ {{0X9EA6D162, 0X3FE6D98A} },
+/**/ {{0X6B927B3B, 0XBFD4A662} },
+/**/ {{0XF84ADBB0, 0X3F9905D8} },
+/**/ {{0XDD484DB5, 0X3FB94015} },
+/**/ {{0X783EEF44, 0XBFB4EF83} } },
+/**/ {{{0X0D457FA4, 0X3FE45FFF} },
+/**/ {{0X9F675300, 0X3FE224B6} },
+/**/ {{0X3A093351, 0X3FE6C4E7} },
+/**/ {{0XCBF2BFF8, 0XBFD4A18B} },
+/**/ {{0X84BB8C16, 0X3F9A968A} },
+/**/ {{0X93FBB975, 0X3FB8D7A4} },
+/**/ {{0X3B37E4FB, 0XBFB4D867} } },
+/**/ {{{0X8F910E57, 0X3FE47FFE} },
+/**/ {{0XDD92B840, 0X3FE23B70} },
+/**/ {{0X89B04359, 0X3FE6B048} },
+/**/ {{0X974B07FF, 0XBFD49C6A} },
+/**/ {{0X25F20251, 0X3F9C20BE} },
+/**/ {{0X82E9673D, 0X3FB86FA8} },
+/**/ {{0X0D12F550, 0XBFB4C00F} } },
+/**/ {{{0X7323FC6B, 0X3FE4A001} },
+/**/ {{0XE34E3420, 0X3FE25218} },
+/**/ {{0XF277FE27, 0X3FE69BAC} },
+/**/ {{0X7F856ABA, 0XBFD496FF} },
+/**/ {{0X9928150C, 0X3F9DA49E} },
+/**/ {{0X3EB66A26, 0X3FB8081E} },
+/**/ {{0X78AB06C5, 0XBFB4A685} } },
+/**/ {{{0XB1BF0500, 0X3FE4C000} },
+/**/ {{0XBD8B2C80, 0X3FE268A9} },
+/**/ {{0X42ABBD42, 0X3FE68719} },
+/**/ {{0XEC74E64A, 0XBFD4914C} },
+/**/ {{0XD0C3EEEC, 0X3F9F21DE} },
+/**/ {{0X5B30AA05, 0X3FB7A122} },
+/**/ {{0XEC53EF43, 0XBFB48BD4} } },
+/**/ {{{0X1D07207B, 0X3FE4E001} },
+/**/ {{0XDA64F7A0, 0X3FE27F26} },
+/**/ {{0XA7CFBEB2, 0X3FE6728A} },
+/**/ {{0X3FCBB247, 0XBFD48B53} },
+/**/ {{0XA7354A41, 0X3FA04C60} },
+/**/ {{0XEFF6F27A, 0X3FB73AAA} },
+/**/ {{0XB81A6BB2, 0XBFB47007} } },
+/**/ {{{0X5F36EB46, 0X3FE4FFFE} },
+/**/ {{0X35DDD180, 0X3FE2958D} },
+/**/ {{0X307B6AF3, 0X3FE65E04} },
+/**/ {{0X828BB6E6, 0XBFD48514} },
+/**/ {{0X48993ED9, 0X3FA1048E} },
+/**/ {{0X468D7C59, 0X3FB6D4CB} },
+/**/ {{0X0D484989, 0XBFB45328} } },
+/**/ {{{0X2AFDF759, 0X3FE52001} },
+/**/ {{0XEB1C3280, 0X3FE2ABE2} },
+/**/ {{0X8DC5DAAD, 0X3FE64980} },
+/**/ {{0X2C11E3B7, 0XBFD47E90} },
+/**/ {{0X88E1B343, 0X3FA1B9AE} },
+/**/ {{0XFF4501BF, 0X3FB66F6C} },
+/**/ {{0XFCD6B8DE, 0XBFB4353F} } },
+/**/ {{{0XDFDB2423, 0X3FE54001} },
+/**/ {{0XAB0402C0, 0X3FE2C222} },
+/**/ {{0XE7E657FB, 0X3FE63504} },
+/**/ {{0XEEE53FA9, 0XBFD477C8} },
+/**/ {{0X696CD845, 0X3FA26B9A} },
+/**/ {{0X6A3AA6EF, 0X3FB60AAD} },
+/**/ {{0X7704E1F4, 0XBFB41659} } },
+/**/ {{{0X72D2A74F, 0X3FE55FFE} },
+/**/ {{0X16BE7240, 0X3FE2D84B} },
+/**/ {{0XCE54AEDE, 0X3FE62092} },
+/**/ {{0X7B764156, 0XBFD470C0} },
+/**/ {{0X4D9ABEE7, 0X3FA31A4C} },
+/**/ {{0XA899A63D, 0X3FB5A697} },
+/**/ {{0X49FA7FB1, 0XBFB3F67E} } },
+/**/ {{{0XEE716C33, 0X3FE58000} },
+/**/ {{0X284F3FE0, 0X3FE2EE63} },
+/**/ {{0X181C5720, 0X3FE60C24} },
+/**/ {{0XC383B0C1, 0XBFD46975} },
+/**/ {{0XC40A1A5A, 0X3FA3C5FF} },
+/**/ {{0X0B7B3B72, 0X3FB54311} },
+/**/ {{0X21700401, 0XBFB3D5B8} } },
+/**/ {{{0X9825CD2A, 0X3FE59FFF} },
+/**/ {{0X2DEFCF40, 0X3FE30464} },
+/**/ {{0X3C14A317, 0X3FE5F7BF} },
+/**/ {{0X227A4CDE, 0XBFD461EC} },
+/**/ {{0X6DA8D837, 0X3FA46E85} },
+/**/ {{0X6162F4C8, 0X3FB4E03C} },
+/**/ {{0X857F5976, 0XBFB3B410} } },
+/**/ {{{0XFE2A42CD, 0X3FE5BFFD} },
+/**/ {{0XA5110DC0, 0X3FE31A50} },
+/**/ {{0X33CF1268, 0X3FE5E362} },
+/**/ {{0XF68B7DBC, 0XBFD45A23} },
+/**/ {{0XDE40F0E9, 0X3FA513F5} },
+/**/ {{0XDE05901E, 0X3FB47E12} },
+/**/ {{0XDA5CABB5, 0XBFB39190} } },
+/**/ {{{0X57330799, 0X3FE5E000} },
+/**/ {{0X75253480, 0X3FE3302B} },
+/**/ {{0X901DA45A, 0X3FE5CF0A} },
+/**/ {{0X552754CF, 0XBFD4521D} },
+/**/ {{0XBBF000BB, 0X3FA5B66B} },
+/**/ {{0XD2BAF7B2, 0X3FB41C8B} },
+/**/ {{0X5F53241A, 0XBFB36E42} } },
+/**/ {{{0X4D6055DA, 0X3FE60001} },
+/**/ {{0XFF2EDA60, 0X3FE345F0} },
+/**/ {{0XF2EA5900, 0X3FE5BABB} },
+/**/ {{0XB2008754, 0XBFD449DA} },
+/**/ {{0X18F56FBB, 0X3FA655D1} },
+/**/ {{0X89A0C1B2, 0X3FB3BBBB} },
+/**/ {{0X2E8D60FC, 0XBFB34A2E} } },
+/**/ {{{0X2C3809CB, 0X3FE62001} },
+/**/ {{0X812D5040, 0X3FE35BA1} },
+/**/ {{0X671E49E9, 0X3FE5A676} },
+/**/ {{0X230E6216, 0XBFD4415D} },
+/**/ {{0X6B05C7F7, 0X3FA6F22D} },
+/**/ {{0XCFE6B72B, 0X3FB35BA4} },
+/**/ {{0X3C3BFA3B, 0XBFB3255D} } },
+/**/ {{{0X87B47ECC, 0X3FE64000} },
+/**/ {{0X69715580, 0X3FE3713D} },
+/**/ {{0XC8FB0E69, 0X3FE59239} },
+/**/ {{0XA5BD1F6E, 0XBFD438A5} },
+/**/ {{0X7F9B13CF, 0X3FA78B89} },
+/**/ {{0X74F57C8F, 0X3FB2FC49} },
+/**/ {{0X566CAACA, 0XBFB2FFD8} } },
+/**/ {{{0XA746397F, 0X3FE66000} },
+/**/ {{0X9D968940, 0X3FE386C5} },
+/**/ {{0X83073C58, 0X3FE57E05} },
+/**/ {{0XFE3D0083, 0XBFD42FB4} },
+/**/ {{0X4B9E1EEB, 0X3FA821F1} },
+/**/ {{0X1952EE82, 0X3FB29DA9} },
+/**/ {{0X245866A8, 0XBFB2D9A8} } },
+/**/ {{{0XE4E3094B, 0X3FE68000} },
+/**/ {{0XB5FE3900, 0X3FE39C39} },
+/**/ {{0X36DD131E, 0X3FE569DA} },
+/**/ {{0X74778FE0, 0XBFD4268C} },
+/**/ {{0X9AB0310F, 0X3FA8B567} },
+/**/ {{0XF2E43205, 0X3FB23FC8} },
+/**/ {{0X26483573, 0XBFB2B2D5} } },
+/**/ {{{0XE2E37787, 0X3FE6A001} },
+/**/ {{0X27D52620, 0X3FE3B19A} },
+/**/ {{0XB5D865CD, 0X3FE555B7} },
+/**/ {{0XF1600CD3, 0XBFD41D2C} },
+/**/ {{0X4B79E859, 0X3FA945F5} },
+/**/ {{0X46A0B02D, 0X3FB1E2AA} },
+/**/ {{0XB508A35B, 0XBFB28B67} } },
+/**/ {{{0X0DF4BBFB, 0X3FE6BFFE} },
+/**/ {{0X46F2B6E0, 0X3FE3C6E3} },
+/**/ {{0XB658AFBE, 0X3FE541A1} },
+/**/ {{0X388DA137, 0XBFD41399} },
+/**/ {{0XE5B3C2BA, 0X3FA9D387} },
+/**/ {{0X173397F9, 0X3FB18660} },
+/**/ {{0X01DB4945, 0XBFB26368} } },
+/**/ {{{0XEA406CEA, 0X3FE6DFFF} },
+/**/ {{0X1BB3D400, 0X3FE3DC1C} },
+/**/ {{0XD33FFE8E, 0X3FE52D91} },
+/**/ {{0X36BCFFE9, 0XBFD409CF} },
+/**/ {{0X174405AF, 0X3FAA5E54} },
+/**/ {{0XDC041806, 0X3FB12ACE} },
+/**/ {{0X160D6557, 0XBFB23ADE} } },
+/**/ {{{0XED01EA65, 0X3FE70000} },
+/**/ {{0X54E51400, 0X3FE3F140} },
+/**/ {{0X5C8B9119, 0X3FE5198C} },
+/**/ {{0XF2EA4FF7, 0XBFD3FFD1} },
+/**/ {{0X308C81CD, 0X3FAAE643} },
+/**/ {{0X1960AAF7, 0X3FB0D00C} },
+/**/ {{0XD2F50D25, 0XBFB211D1} } },
+/**/ {{{0X00D515EB, 0X3FE72002} },
+/**/ {{0X983BB3E0, 0X3FE40650} },
+/**/ {{0XF2175C71, 0X3FE50590} },
+/**/ {{0X361BB15C, 0XBFD3F5A2} },
+/**/ {{0X9B536AFC, 0X3FAB6B5F} },
+/**/ {{0XA731624D, 0X3FB07617} },
+/**/ {{0XF1A8C054, 0XBFB1E84A} } },
+/**/ {{{0X1323DE6D, 0X3FE74001} },
+/**/ {{0X9483E720, 0X3FE41B4B} },
+/**/ {{0X1027BA01, 0X3FE4F1A1} },
+/**/ {{0XBB978C8F, 0XBFD3EB41} },
+/**/ {{0X7765626A, 0X3FABEDA7} },
+/**/ {{0X97F58C8A, 0X3FB01CF9} },
+/**/ {{0X03074348, 0XBFB1BE51} } },
+/**/ {{{0X25CAB4CA, 0X3FE75FFF} },
+/**/ {{0X0001D5C0, 0X3FE43032} },
+/**/ {{0X4573FB6C, 0X3FE4DDBC} },
+/**/ {{0X41F21D2A, 0XBFD3E0B1} },
+/**/ {{0XD1BDA00F, 0X3FAC6D25} },
+/**/ {{0X5935EE68, 0X3FAF8962} },
+/**/ {{0X6F8E0689, 0XBFB193EB} } },
+/**/ {{{0X90921F76, 0X3FE77FFE} },
+/**/ {{0X6CC6AF00, 0X3FE44505} },
+/**/ {{0X4CFFBDAE, 0X3FE4C9E1} },
+/**/ {{0X0B247EC4, 0XBFD3D5F1} },
+/**/ {{0X943F4516, 0X3FACE9EA} },
+/**/ {{0XF24A8AF1, 0X3FAEDA73} },
+/**/ {{0X776AAC42, 0XBFB16921} } },
+/**/ {{{0X47B2F83B, 0X3FE79FFE} },
+/**/ {{0X35C19F20, 0X3FE459C5} },
+/**/ {{0XFC8F20BD, 0X3FE4B610} },
+/**/ {{0X73DF2A0D, 0XBFD3CB02} },
+/**/ {{0X23C5D6DE, 0X3FAD63F8} },
+/**/ {{0X9C5116AB, 0X3FAE2D31} },
+/**/ {{0X326E2972, 0XBFB13DFA} } },
+/**/ {{{0X2F1E79A9, 0X3FE7BFFF} },
+/**/ {{0XF84DF5C0, 0X3FE46E71} },
+/**/ {{0XF586B1BD, 0X3FE4A24A} },
+/**/ {{0X2EF81E5B, 0XBFD3BFE6} },
+/**/ {{0X738896F0, 0X3FADDB58} },
+/**/ {{0X2515DE78, 0X3FAD819A} },
+/**/ {{0X9026FDD0, 0XBFB1127C} } },
+/**/ {{{0X973C8D05, 0X3FE7E001} },
+/**/ {{0XF0FB9580, 0X3FE4830B} },
+/**/ {{0X3466B08E, 0X3FE48E8F} },
+/**/ {{0X1C53A01A, 0XBFD3B49D} },
+/**/ {{0X25103EED, 0X3FAE5013} },
+/**/ {{0X5290F4AF, 0X3FACD7AF} },
+/**/ {{0X57EF003B, 0XBFB0E6AF} } },
+/**/ {{{0X69EFC092, 0X3FE7FFFF} },
+/**/ {{0X431C3800, 0X3FE4978F} },
+/**/ {{0XA3E1064A, 0X3FE47AE1} },
+/**/ {{0X666C50C4, 0XBFD3A92A} },
+/**/ {{0X4098A4BE, 0X3FAEC219} },
+/**/ {{0X2EEE57E0, 0X3FAC2F94} },
+/**/ {{0X290D5730, 0XBFB0BA99} } },
+/**/ {{{0XC52B5232, 0X3FE82001} },
+/**/ {{0XD2B83340, 0X3FE4AC01} },
+/**/ {{0XD31B7CF5, 0X3FE4673C} },
+/**/ {{0XC67D05F0, 0XBFD39D8B} },
+/**/ {{0X2A81B5D5, 0X3FAF3192} },
+/**/ {{0X8AA20E90, 0X3FAB891B} },
+/**/ {{0X7ADCEFD6, 0XBFB08E40} } },
+/**/ {{{0XBD4D4E3F, 0X3FE84000} },
+/**/ {{0X9B1DBC60, 0X3FE4C05E} },
+/**/ {{0XC8D629F7, 0X3FE453A5} },
+/**/ {{0X13E9EF47, 0XBFD391C5} },
+/**/ {{0X17383D6B, 0X3FAF9E69} },
+/**/ {{0X278E21B9, 0X3FAAE471} },
+/**/ {{0X9CF54D10, 0XBFB061AB} } },
+/**/ {{{0X8C869CBD, 0X3FE86001} },
+/**/ {{0XFD2285A0, 0X3FE4D4A8} },
+/**/ {{0X79B82471, 0X3FE44019} },
+/**/ {{0X5C3E2929, 0XBFD385D5} },
+/**/ {{0X7B2C8FF2, 0X3FB0045B} },
+/**/ {{0X39D7CA4F, 0X3FAA417C} },
+/**/ {{0XB767B7D4, 0XBFB034E0} } },
+/**/ {{{0XB5DB3710, 0X3FE87FFE} },
+/**/ {{0X8B93BCA0, 0X3FE4E8DD} },
+/**/ {{0X66C6E6BF, 0X3FE42C9B} },
+/**/ {{0XA32EE2A1, 0XBFD379BF} },
+/**/ {{0X6187FE0F, 0X3FB03838} },
+/**/ {{0X8B3A0B33, 0X3FA9A05A} },
+/**/ {{0XCAEE03A9, 0XBFB007E5} } },
+/**/ {{{0X863C77E3, 0X3FE8A000} },
+/**/ {{0X8FCD1E80, 0X3FE4FD01} },
+/**/ {{0XA8A8093F, 0X3FE41926} },
+/**/ {{0XB5EE344D, 0XBFD36D81} },
+/**/ {{0X2841F292, 0X3FB06ADC} },
+/**/ {{0X2484560B, 0X3FA900E4} },
+/**/ {{0X62792F0A, 0XBFAFB581} } },
+/**/ {{{0X0ED982AF, 0X3FE8BFFF} },
+/**/ {{0X16E28AC0, 0X3FE51110} },
+/**/ {{0X389112EE, 0X3FE405C0} },
+/**/ {{0X89D38DC7, 0XBFD3611F} },
+/**/ {{0XB450B9F7, 0X3FB09C3D} },
+/**/ {{0X312D0C4A, 0X3FA86342} },
+/**/ {{0X3A6CA012, 0XBFAF5AEE} } },
+/**/ {{{0X02C3AEAE, 0X3FE8E000} },
+/**/ {{0XC0AB0A40, 0X3FE5250C} },
+/**/ {{0XC65593C5, 0X3FE3F264} },
+/**/ {{0XD82BE900, 0XBFD35497} },
+/**/ {{0X68546D39, 0X3FB0CC69} },
+/**/ {{0XDB8499FD, 0X3FA7C759} },
+/**/ {{0X36A32337, 0XBFAF001D} } },
+/**/ {{{0XECBFA97B, 0X3FE90000} },
+/**/ {{0X0E8D4EE0, 0X3FE538F6} },
+/**/ {{0XF4119333, 0X3FE3DF15} },
+/**/ {{0X7D2149F4, 0XBFD347EC} },
+/**/ {{0XFA921D3C, 0X3FB0FB5E} },
+/**/ {{0X69693E89, 0X3FA72D38} },
+/**/ {{0X23A0F5F3, 0XBFAEA519} } },
+/**/ {{{0XD251C01C, 0X3FE91FFF} },
+/**/ {{0XD3F3BD20, 0X3FE54CCA} },
+/**/ {{0X1554DD15, 0X3FE3CBD5} },
+/**/ {{0X2BC94245, 0XBFD33B1F} },
+/**/ {{0X2FC4C3F6, 0X3FB1291F} },
+/**/ {{0X1B7A765C, 0X3FA694E8} },
+/**/ {{0X826E86F6, 0XBFAE49EC} } },
+/**/ {{{0XD90AF4E6, 0X3FE94001} },
+/**/ {{0X4D4EC640, 0X3FE5608E} },
+/**/ {{0X3445EF72, 0X3FE3B89F} },
+/**/ {{0XB7BBD79A, 0XBFD32E2E} },
+/**/ {{0XE401D071, 0X3FB155B4} },
+/**/ {{0X3A256F1C, 0X3FA5FE51} },
+/**/ {{0X890FF662, 0XBFADEEA1} } },
+/**/ {{{0X04FD6C17, 0X3FE96001} },
+/**/ {{0XD5673C20, 0X3FE5743C} },
+/**/ {{0X09EBC6E2, 0X3FE3A578} },
+/**/ {{0X6DA5039C, 0XBFD3211E} },
+/**/ {{0X4E62286B, 0X3FB1811B} },
+/**/ {{0X71BECE9D, 0X3FA56990} },
+/**/ {{0X23911641, 0XBFAD9342} } },
+/**/ {{{0X2D214B82, 0X3FE98000} },
+/**/ {{0X3B0D6120, 0X3FE587D8} },
+/**/ {{0X01EAAC3E, 0X3FE3925E} },
+/**/ {{0X08425504, 0XBFD313EE} },
+/**/ {{0X02BDB571, 0X3FB1AB5A} },
+/**/ {{0X9EBD70B8, 0X3FA4D698} },
+/**/ {{0XF482965A, 0XBFAD37D7} } },
+/**/ {{{0XEB980651, 0X3FE99FFD} },
+/**/ {{0XB16BA7A0, 0X3FE59B5F} },
+/**/ {{0X10B1AB7A, 0X3FE37F52} },
+/**/ {{0XF993D676, 0XBFD3069E} },
+/**/ {{0XCDED25A8, 0X3FB1D472} },
+/**/ {{0X2D0ABD9A, 0X3FA44570} },
+/**/ {{0X56221AA1, 0XBFACDC6C} } },
+/**/ {{{0XE5504053, 0X3FE9BFFF} },
+/**/ {{0XB55DE6A0, 0X3FE5AED6} },
+/**/ {{0XFA91C51E, 0X3FE36C50} },
+/**/ {{0XBE311E56, 0XBFD2F92F} },
+/**/ {{0X5BE3AF05, 0X3FB1FC70} },
+/**/ {{0XACD5CDC7, 0X3FA3B5FD} },
+/**/ {{0X5ADBB9B8, 0XBFAC8108} } },
+/**/ {{{0X6E60A234, 0X3FE9E001} },
+/**/ {{0X79ACD480, 0X3FE5C23A} },
+/**/ {{0XA5FAB2EA, 0X3FE3595D} },
+/**/ {{0X1DDECEEA, 0XBFD2EBA3} },
+/**/ {{0X35736518, 0X3FB22350} },
+/**/ {{0X22F9FD28, 0X3FA32856} },
+/**/ {{0XCE8B2259, 0XBFAC25B4} } },
+/**/ {{{0XB685741B, 0X3FE9FFFF} },
+/**/ {{0X5AD40460, 0X3FE5D589} },
+/**/ {{0XD832B8D3, 0X3FE34679} },
+/**/ {{0X230EDA41, 0XBFD2DDFB} },
+/**/ {{0XB23C0BA2, 0X3FB24912} },
+/**/ {{0X4C4E86DA, 0X3FA29C85} },
+/**/ {{0X37002A55, 0XBFABCA7A} } },
+/**/ {{{0X9D59B943, 0X3FEA2001} },
+/**/ {{0X8C187EA0, 0X3FE5E8C7} },
+/**/ {{0X9EDE2183, 0X3FE333A1} },
+/**/ {{0XB0043779, 0XBFD2D035} },
+/**/ {{0X7AB9110C, 0X3FB26DC3} },
+/**/ {{0X959CFC0E, 0X3FA2126C} },
+/**/ {{0XD556233E, 0XBFAB6F60} } },
+/**/ {{{0XBE9E153F, 0X3FEA3FFF} },
+/**/ {{0XA9C08AE0, 0X3FE5FBF0} },
+/**/ {{0X6F7861AA, 0X3FE320D9} },
+/**/ {{0XC2200F18, 0XBFD2C256} },
+/**/ {{0XA6795293, 0X3FB2915D} },
+/**/ {{0X256A8FDE, 0X3FA18A2B} },
+/**/ {{0XA67A4E89, 0XBFAB1470} } },
+/**/ {{{0X7A23A1CE, 0X3FEA5FFE} },
+/**/ {{0X63200600, 0X3FE60F07} },
+/**/ {{0XD13D395E, 0X3FE30E1E} },
+/**/ {{0X44403932, 0XBFD2B45D} },
+/**/ {{0XC967F013, 0X3FB2B3E9} },
+/**/ {{0X35D002B8, 0X3FA103AD} },
+/**/ {{0X6496A8F1, 0XBFAAB9B1} } },
+/**/ {{{0X57F250B8, 0X3FEA8001} },
+/**/ {{0XDD6453A0, 0X3FE6220D} },
+/**/ {{0XCFFFCC1E, 0X3FE2FB6F} },
+/**/ {{0X6F8D8291, 0XBFD2A648} },
+/**/ {{0X03654CC3, 0X3FB2D56F} },
+/**/ {{0X4BB6E7A6, 0X3FA07EE3} },
+/**/ {{0X87992F03, 0XBFAA5F2A} } },
+/**/ {{{0XDD839D49, 0X3FEAA000} },
+/**/ {{0XB412C9A0, 0X3FE634FF} },
+/**/ {{0XE2D59E01, 0X3FE2E8D0} },
+/**/ {{0X5467CFDD, 0XBFD2981C} },
+/**/ {{0XFF1FADB5, 0X3FB2F5E8} },
+/**/ {{0XA3BA803C, 0X3F9FF7D6} },
+/**/ {{0X46AF8DB7, 0XBFAA04E3} } },
+/**/ {{{0X770DF220, 0X3FEAC000} },
+/**/ {{0XFEF70020, 0X3FE647DE} },
+/**/ {{0X220AFF7F, 0X3FE2D640} },
+/**/ {{0X36F9E74F, 0XBFD289D8} },
+/**/ {{0XE509140A, 0X3FB3155E} },
+/**/ {{0X61AB0B7F, 0X3F9EF56B} },
+/**/ {{0X98CE391F, 0XBFA9AAE2} } },
+/**/ {{{0X125BBE48, 0X3FEAE001} },
+/**/ {{0X57A24D20, 0X3FE65AAC} },
+/**/ {{0X1BFB3559, 0X3FE2C3BD} },
+/**/ {{0X6DDE55DD, 0XBFD27B7C} },
+/**/ {{0X15C4C270, 0X3FB333D5} },
+/**/ {{0X9BAC4ECF, 0X3F9DF67A} },
+/**/ {{0X363A972B, 0XBFA9512F} } },
+/**/ {{{0X7C321839, 0X3FEAFFFE} },
+/**/ {{0X569B83C0, 0X3FE66D65} },
+/**/ {{0X53FBF8D9, 0X3FE2B14A} },
+/**/ {{0X9CFA03CE, 0XBFD26D0B} },
+/**/ {{0X2CAA2E0C, 0X3FB3514B} },
+/**/ {{0X4597BE9A, 0X3F9CFB22} },
+/**/ {{0X99110022, 0XBFA8F7CF} } },
+/**/ {{{0X75486924, 0X3FEB1FFE} },
+/**/ {{0X68CEFB40, 0X3FE6800D} },
+/**/ {{0X8E6AA814, 0X3FE29EE4} },
+/**/ {{0XE8AFA7EB, 0XBFD25E83} },
+/**/ {{0XFB0E8AC8, 0X3FB36DC9} },
+/**/ {{0XAD5D66CA, 0X3F9C0331} },
+/**/ {{0XFEDB1E8B, 0XBFA89EC9} } },
+/**/ {{{0X5FB8DEB8, 0X3FEB4001} },
+/**/ {{0XD137C500, 0X3FE692A4} },
+/**/ {{0XABFF668E, 0X3FE28C8B} },
+/**/ {{0XD8E71E0A, 0XBFD24FE5} },
+/**/ {{0X1297317A, 0X3FB38955} },
+/**/ {{0X1D844655, 0X3F9B0EA3} },
+/**/ {{0X6914067D, 0XBFA84624} } },
+/**/ {{{0X386C27B9, 0X3FEB6000} },
+/**/ {{0X8CDF6FC0, 0X3FE6A527} },
+/**/ {{0XC5758DB8, 0X3FE27A43} },
+/**/ {{0X59CADCE0, 0XBFD24135} },
+/**/ {{0XEE34AE91, 0X3FB3A3E9} },
+/**/ {{0X1C5FFF05, 0X3F9A1DA8} },
+/**/ {{0X9EC8AAC6, 0XBFA7EDE4} } },
+/**/ {{{0XD1EFDDB3, 0X3FEB8000} },
+/**/ {{0X0ACCB660, 0X3FE6B799} },
+/**/ {{0X9983AAB2, 0X3FE26809} },
+/**/ {{0X76047E08, 0XBFD23270} },
+/**/ {{0XF132139B, 0X3FB3BD90} },
+/**/ {{0X58DEB3E1, 0X3F993010} },
+/**/ {{0X2D194CE9, 0XBFA79610} } },
+/**/ {{{0X42CC4047, 0X3FEB9FFE} },
+/**/ {{0X86445E60, 0X3FE6C9F6} },
+/**/ {{0X069F871F, 0X3FE255E0} },
+/**/ {{0X25461639, 0XBFD2239A} },
+/**/ {{0XA926C127, 0X3FB3D649} },
+/**/ {{0XC5A21F70, 0X3F9845FB} },
+/**/ {{0X68E20BE6, 0XBFA73EAC} } },
+/**/ {{{0X951AEAAD, 0X3FEBC001} },
+/**/ {{0X3C4E45A0, 0X3FE6DC45} },
+/**/ {{0XFF6573B0, 0X3FE243C1} },
+/**/ {{0XE38FA7E7, 0XBFD214AE} },
+/**/ {{0X5EA1330F, 0X3FB3EE1E} },
+/**/ {{0X2BCCE6DF, 0X3F975F24} },
+/**/ {{0X6F3902C5, 0XBFA6E7BE} } },
+/**/ {{{0X6616FE11, 0X3FEBDFFE} },
+/**/ {{0X27106FE0, 0X3FE6EE7E} },
+/**/ {{0X97B587F0, 0X3FE231B6} },
+/**/ {{0X240FEF32, 0XBFD205B5} },
+/**/ {{0X44EB818C, 0X3FB40509} },
+/**/ {{0X108160F9, 0X3F967BDE} },
+/**/ {{0X271D18AD, 0XBFA6914B} } },
+/**/ {{{0X54511C72, 0X3FEBFFFF} },
+/**/ {{0X643BBB40, 0X3FE700A7} },
+/**/ {{0XE1823C8B, 0X3FE21FB7} },
+/**/ {{0X9A854F7A, 0XBFD1F6A8} },
+/**/ {{0X71F04837, 0X3FB41B15} },
+/**/ {{0XBBD10F7C, 0X3F959BD8} },
+/**/ {{0X41F03711, 0XBFA63B57} } },
+/**/ {{{0XC537593E, 0X3FEC2000} },
+/**/ {{0XF36D6400, 0X3FE712BE} },
+/**/ {{0XF754B2D5, 0X3FE20DC7} },
+/**/ {{0X9D24DBED, 0XBFD1E78B} },
+/**/ {{0X94F485E0, 0X3FB43043} },
+/**/ {{0X122A6884, 0X3F94BF29} },
+/**/ {{0X3D2AA4E9, 0XBFA5E5E7} } },
+/**/ {{{0XDDD35719, 0X3FEC4000} },
+/**/ {{0XD7FA3000, 0X3FE724C3} },
+/**/ {{0XF2A8B1BF, 0X3FE1FBE7} },
+/**/ {{0XB25DDDF6, 0XBFD1D85F} },
+/**/ {{0XD2E3B20F, 0X3FB44495} },
+/**/ {{0X7FCC1B30, 0X3F93E5D6} },
+/**/ {{0X62D0D00F, 0XBFA590FF} } },
+/**/ {{{0X402375B6, 0X3FEC6000} },
+/**/ {{0X7DFF3720, 0X3FE736B6} },
+/**/ {{0X86C92387, 0X3FE1EA17} },
+/**/ {{0X31DDFC58, 0XBFD1C925} },
+/**/ {{0XF8B6CBC2, 0X3FB4580F} },
+/**/ {{0X00CE998E, 0X3F930FD7} },
+/**/ {{0XCB299E5F, 0XBFA53CA3} } },
+/**/ {{{0X19904FE4, 0X3FEC7FFF} },
+/**/ {{0X0F395860, 0X3FE74897} },
+/**/ {{0XA825BA33, 0X3FE1D856} },
+/**/ {{0XA75E0FC5, 0XBFD1B9DC} },
+/**/ {{0X79F8FD7D, 0X3FB46AB5} },
+/**/ {{0XA5A90AFE, 0X3F923D23} },
+/**/ {{0X5D2F574B, 0XBFA4E8D8} } },
+/**/ {{{0XF9E2409D, 0X3FEC9FFE} },
+/**/ {{0X79E7F1C0, 0X3FE75A66} },
+/**/ {{0X8740D2E9, 0X3FE1C6A4} },
+/**/ {{0XF198392C, 0XBFD1AA85} },
+/**/ {{0X808C583A, 0X3FB47C8A} },
+/**/ {{0X857F2526, 0X3F916DAC} },
+/**/ {{0XD0477576, 0XBFA495A0} } },
+/**/ {{{0XE038EF72, 0X3FECC001} },
+/**/ {{0XE6815140, 0X3FE76C25} },
+/**/ {{0X19BDADF8, 0X3FE1B500} },
+/**/ {{0XB4A469AE, 0XBFD19B20} },
+/**/ {{0X42387EA2, 0X3FB48D93} },
+/**/ {{0X7305BAF5, 0X3F90A15F} },
+/**/ {{0XACAE4E17, 0XBFA44300} } },
+/**/ {{{0XEB72037F, 0X3FECDFFE} },
+/**/ {{0X7A7A4AA0, 0X3FE77DD0} },
+/**/ {{0X4F1F6702, 0X3FE1A36E} },
+/**/ {{0XD0992CF8, 0XBFD18BB1} },
+/**/ {{0X5AA4990D, 0X3FB49DCE} },
+/**/ {{0X63759665, 0X3F8FB0DD} },
+/**/ {{0X4D2F0C0F, 0XBFA3F0FB} } },
+/**/ {{{0XEA4839ED, 0X3FECFFFF} },
+/**/ {{0XB17088C0, 0X3FE78F6B} },
+/**/ {{0XCF32122F, 0X3FE191E9} },
+/**/ {{0X220400AC, 0XBFD17C35} },
+/**/ {{0X0A159641, 0X3FB4AD44} },
+/**/ {{0X80894CA9, 0X3F8E252C} },
+/**/ {{0XDF89C265, 0XBFA39F93} } },
+/**/ {{{0XEC3EC8B2, 0X3FED1FFD} },
+/**/ {{0XC8C6C880, 0X3FE7A0F3} },
+/**/ {{0X729F01D6, 0X3FE18076} },
+/**/ {{0X98515540, 0XBFD16CAE} },
+/**/ {{0X1B0933FF, 0X3FB4BBF4} },
+/**/ {{0XE09A60CD, 0X3F8C9FF5} },
+/**/ {{0X662A5704, 0XBFA34ECD} } },
+/**/ {{{0X7084EDD4, 0X3FED3FFF} },
+/**/ {{0X5F02F220, 0X3FE7B26C} },
+/**/ {{0XB9973206, 0X3FE16F10} },
+/**/ {{0X9E1E0A54, 0XBFD15D1B} },
+/**/ {{0XAC2C9A30, 0X3FB4C9E4} },
+/**/ {{0XEFCE76CC, 0X3F8B20DD} },
+/**/ {{0XB888BC37, 0XBFA2FEAA} } },
+/**/ {{{0X8D728E7C, 0X3FED5FFE} },
+/**/ {{0X488D7E80, 0X3FE7C3D2} },
+/**/ {{0XE622A5A7, 0X3FE15DBB} },
+/**/ {{0XA305CEB2, 0XBFD14D7F} },
+/**/ {{0X417BF1C7, 0X3FB4D716} },
+/**/ {{0XE19FE239, 0X3F89A81E} },
+/**/ {{0X84DDAD07, 0XBFA2AF2E} } },
+/**/ {{{0X70AA3B03, 0X3FED7FFF} },
+/**/ {{0XDB239580, 0X3FE7D527} },
+/**/ {{0XBE4FEA01, 0X3FE14C75} },
+/**/ {{0X2AD706AA, 0XBFD13DD9} },
+/**/ {{0XB49D32AA, 0X3FB4E38D} },
+/**/ {{0X37DF2B6D, 0X3F88357A} },
+/**/ {{0X507CD77B, 0XBFA2605B} } },
+/**/ {{{0X1434FBA3, 0X3FED9FFF} },
+/**/ {{0X82C8A720, 0X3FE7E66B} },
+/**/ {{0XED9B7FED, 0X3FE13B3F} },
+/**/ {{0X3AC9D646, 0XBFD12E2A} },
+/**/ {{0XE7B01CF5, 0X3FB4EF4C} },
+/**/ {{0XD25FD52D, 0X3F86C905} },
+/**/ {{0X798666EF, 0XBFA21233} } },
+/**/ {{{0XA8C8DE8C, 0X3FEDBFFE} },
+/**/ {{0XF4A0A520, 0X3FE7F79D} },
+/**/ {{0XD7FC2119, 0X3FE12A19} },
+/**/ {{0XC6BE19DF, 0XBFD11E72} },
+/**/ {{0X634E1B91, 0X3FB4FA57} },
+/**/ {{0X47F96DF5, 0X3F8562A6} },
+/**/ {{0X373AF599, 0XBFA1C4B9} } },
+/**/ {{{0X26573DF5, 0X3FEDE000} },
+/**/ {{0X4DBCB960, 0X3FE808C0} },
+/**/ {{0X7903E4B9, 0X3FE11902} },
+/**/ {{0X5CDFED06, 0XBFD10EB2} },
+/**/ {{0XCCA681FA, 0X3FB504B0} },
+/**/ {{0X6F3CDE09, 0X3F840238} },
+/**/ {{0X9BA8FA6A, 0XBFA177EE} } },
+/**/ {{{0X35009B66, 0X3FEDFFFE} },
+/**/ {{0XC2CB5340, 0X3FE819CF} },
+/**/ {{0XB1C942B5, 0X3FE107FC} },
+/**/ {{0X230D7D92, 0XBFD0FEEC} },
+/**/ {{0X75C5B4F1, 0X3FB50E5A} },
+/**/ {{0XE3C139D8, 0X3F82A7E8} },
+/**/ {{0X93FA642B, 0XBFA12BD5} } },
+/**/ {{{0X492D4C68, 0X3FEE2000} },
+/**/ {{0X5CCB8680, 0X3FE82AD0} },
+/**/ {{0X928E55DF, 0X3FE0F704} },
+/**/ {{0XEE0B0721, 0XBFD0EF1C} },
+/**/ {{0X937BFB74, 0X3FB51759} },
+/**/ {{0X2BC9FDDB, 0X3F815359} },
+/**/ {{0XEA1D1824, 0XBFA0E06F} } },
+/**/ {{{0X9412BB65, 0X3FEE4000} },
+/**/ {{0X14001A60, 0X3FE83BBF} },
+/**/ {{0X37F485DA, 0X3FE0E61D} },
+/**/ {{0X1B2BD37D, 0XBFD0DF48} },
+/**/ {{0X64024D14, 0X3FB51FAF} },
+/**/ {{0X9B849698, 0X3F8004B9} },
+/**/ {{0X450A2434, 0XBFA095BF} } },
+/**/ {{{0X4758EF2F, 0X3FEE5FFF} },
+/**/ {{0X1531C180, 0X3FE84C9C} },
+/**/ {{0X8B7FECE7, 0X3FE0D546} },
+/**/ {{0X105BFE1E, 0XBFD0CF6E} },
+/**/ {{0XF9C5E03A, 0X3FB5275E} },
+/**/ {{0X17AA1137, 0X3F7D77F2} },
+/**/ {{0X2A6891E1, 0XBFA04BC5} } },
+/**/ {{{0X380F819F, 0X3FEE8000} },
+/**/ {{0X74CCC060, 0X3FE85D69} },
+/**/ {{0X8F1DA5B5, 0X3FE0C47E} },
+/**/ {{0X62AD700F, 0XBFD0BF8D} },
+/**/ {{0X1F3FBC2B, 0X3FB52E6C} },
+/**/ {{0XEE24AD7D, 0X3F7AF1C3} },
+/**/ {{0XFECE26C9, 0XBFA00282} } },
+/**/ {{{0XA6D8CB7B, 0X3FEEA000} },
+/**/ {{0XD00E3A60, 0X3FE86E25} },
+/**/ {{0XBA314D62, 0X3FE0B3C6} },
+/**/ {{0XE7CB2D84, 0XBFD0AFA7} },
+/**/ {{0X08E9071F, 0X3FB534D9} },
+/**/ {{0X4CE5E5C9, 0X3F787704} },
+/**/ {{0X0EB7C9D5, 0XBF9F73F4} } },
+/**/ {{{0X5A13BA60, 0X3FEEC000} },
+/**/ {{0X19B163E0, 0X3FE87ED1} },
+/**/ {{0X2EBB7AD7, 0X3FE0A31F} },
+/**/ {{0X33A3FCE1, 0XBFD09FBE} },
+/**/ {{0X89D9AF5D, 0X3FB53AA8} },
+/**/ {{0XF7F7040B, 0X3F760799} },
+/**/ {{0XD3F0B3FB, 0XBF9EE456} } },
+/**/ {{{0X58F8DD18, 0X3FEEDFFF} },
+/**/ {{0X6681CA80, 0X3FE88F6B} },
+/**/ {{0XEC4360B3, 0X3FE09287} },
+/**/ {{0XB7CE07E5, 0XBFD08FD0} },
+/**/ {{0X7BDEDD3F, 0X3FB53FDD} },
+/**/ {{0X70C52E66, 0X3F73A366} },
+/**/ {{0X5DCA7315, 0XBF9E5630} } },
+/**/ {{{0XBE033400, 0X3FEEFFFF} },
+/**/ {{0XDD4D7960, 0X3FE89FF5} },
+/**/ {{0XDFFE15BD, 0X3FE081FF} },
+/**/ {{0XDAE56C0F, 0XBFD07FDE} },
+/**/ {{0XF84D6F5D, 0X3FB5447A} },
+/**/ {{0X7982941E, 0X3F714A24} },
+/**/ {{0X81E68835, 0XBF9DC982} } },
+/**/ {{{0XE6B5125D, 0X3FEF2001} },
+/**/ {{0XBBE88160, 0X3FE8B070} },
+/**/ {{0XDF7122E2, 0X3FE07186} },
+/**/ {{0XDE905325, 0XBFD06FE8} },
+/**/ {{0XB5DEEC7A, 0X3FB54883} },
+/**/ {{0XB4A186D5, 0X3F6DF762} },
+/**/ {{0XDE20F495, 0XBF9D3E4E} } },
+/**/ {{{0XF770E0DB, 0X3FEF3FFD} },
+/**/ {{0X09E96380, 0X3FE8C0D8} },
+/**/ {{0XF5A576A9, 0X3FE06120} },
+/**/ {{0X1D2912FF, 0XBFD05FF3} },
+/**/ {{0X8CD1001F, 0X3FB54BF9} },
+/**/ {{0X6E90DC16, 0X3F6970FC} },
+/**/ {{0XD8EB587E, 0XBF9CB496} } },
+/**/ {{{0X4E16DA33, 0X3FEF5FFE} },
+/**/ {{0X29BCCDC0, 0X3FE8D131} },
+/**/ {{0XD33BA4E9, 0X3FE050C8} },
+/**/ {{0XD74C83D2, 0XBFD04FF8} },
+/**/ {{0X592BB252, 0X3FB54EE0} },
+/**/ {{0X7193EEB5, 0X3F64FF61} },
+/**/ {{0XA459AC86, 0XBF9C2C5B} } },
+/**/ {{{0X4576FF2E, 0X3FEF8000} },
+/**/ {{0XCCE443A0, 0X3FE8E17A} },
+/**/ {{0XD8A97B6C, 0X3FE0407F} },
+/**/ {{0XC91B3E55, 0XBFD03FFB} },
+/**/ {{0X5F3357F7, 0X3FB5513A} },
+/**/ {{0X14C92B53, 0X3F60A2BA} },
+/**/ {{0X3E70DF71, 0XBF9BA59E} } },
+/**/ {{{0X39B6A330, 0X3FEF9FFF} },
+/**/ {{0XA7F515A0, 0X3FE8F1B2} },
+/**/ {{0X63064158, 0X3FE03048} },
+/**/ {{0XACBAADA8, 0XBFD02FFE} },
+/**/ {{0XF27448C0, 0X3FB55309} },
+/**/ {{0X4850006B, 0X3F58B6D6} },
+/**/ {{0X742323DF, 0XBF9B205F} } },
+/**/ {{{0XAA76C0B9, 0X3FEFC001} },
+/**/ {{0X15D66D80, 0X3FE901DC} },
+/**/ {{0X28D9B4AA, 0X3FE0201F} },
+/**/ {{0XA98D4C38, 0XBFD01FFE} },
+/**/ {{0X089780F8, 0X3FB55452} },
+/**/ {{0X7F35C5BB, 0X3F5050B5} },
+/**/ {{0XE19247AF, 0XBF9A9C9F} } },
+/**/ {{{0X39A592CA, 0X3FEFDFFE} },
+/**/ {{0X6D88A780, 0X3FE911F2} },
+/**/ {{0XE40C6538, 0X3FE01008} },
+/**/ {{0XD31688DE, 0XBFD01000} },
+/**/ {{0XE32F1816, 0X3FB55514} },
+/**/ {{0X4E1628D2, 0X3F402A15} },
+/**/ {{0XF4FAF5A0, 0XBF9A1A5F} } },
+/**/ {{{0X8E92D1B0, 0X3FEFF801} },
+/**/ {{0X9BB4BF00, 0X3FE91DFB} },
+/**/ {{0XB884C5A9, 0X3FE003FF} },
+/**/ {{0X3876A954, 0XBFD003FF} },
+/**/ {{0X5539DDFB, 0X3FB55551} },
+/**/ {{0X7B95E6C2, 0X3F2007E7} },
+/**/ {{0X18A3BA58, 0XBF99B9A7} } },
+ };
+
+ static const number
+ hij[241][16] = { /* x0,hij for (1/16,1) */
+/**/ {{{0x00000000, 0x3fb04000} },
+/**/ {{0x1c06693d, 0x3fb03a6d} },
+/**/ {{0xd4e7f128, 0xbc428a02} },
+/**/ {{0xe92592ae, 0x3fefdf1f} },
+/**/ {{0xb5490162, 0x3c88bfc0} },
+/**/ {{0x8f7e4151, 0xbfb01ead} },
+/**/ {{0x0b64d205, 0xbc5395e8} },
+/**/ {{0x433dd49b, 0xbfd4d29f} },
+/**/ {{0x4aa42633, 0xbc75b19d} },
+/**/ {{0xce35961d, 0x3fafda41} },
+/**/ {{0x425d7696, 0x3c4e6a5f} },
+/**/ {{0x6c1bb5e2, 0x3fc814dd} },
+/**/ {{0x2b33739f, 0xbfaf4cb7} },
+/**/ {{0xc267d8ec, 0xbfc048b2} },
+/**/ {{0xe8ababc6, 0x3fae9649} },
+/**/ {{0xfe802692, 0x3fb78293} } },
+/**/ {{{0x00000000, 0x3fb10000} },
+/**/ {{0xa71d52a7, 0x3fb0f99e} },
+/**/ {{0xeec3624f, 0xbc22069f} },
+/**/ {{0x9a49d2a9, 0x3fefdc08} },
+/**/ {{0x68b2ce25, 0x3c7780f7} },
+/**/ {{0x9da73e1d, 0xbfb0d9de} },
+/**/ {{0xa1a487bf, 0x3c4ebf46} },
+/**/ {{0xd13ea108, 0xbfd4c669} },
+/**/ {{0xebb4528c, 0x3c7354bc} },
+/**/ {{0x789374c1, 0x3fb0a137} },
+/**/ {{0xc3f2c5c2, 0xbc56c223} },
+/**/ {{0x79c60cda, 0x3fc7f0e7} },
+/**/ {{0xcdcc7b81, 0xbfb05062} },
+/**/ {{0xc5266783, 0xbfc019e4} },
+/**/ {{0xf2540289, 0x3fafd0b2} },
+/**/ {{0xf6d3cd8a, 0x3fb71107} } },
+/**/ {{{0x00000000, 0x3fb20000} },
+/**/ {{0xbf082d59, 0x3fb1f86d} },
+/**/ {{0x7732ef81, 0xbc4095dc} },
+/**/ {{0x01722b81, 0x3fefd7b3} },
+/**/ {{0x8a212e02, 0xbc5e618c} },
+/**/ {{0xee4e9cfa, 0xbfb1d2c5} },
+/**/ {{0x29abece0, 0x3c426273} },
+/**/ {{0x37eb7f46, 0xbfd4b551} },
+/**/ {{0x01d8bf12, 0x3c73b360} },
+/**/ {{0x6adb6a7c, 0x3fb18fa7} },
+/**/ {{0x398999ad, 0xbc5c00d8} },
+/**/ {{0xf4a7cff3, 0x3fc7bea5} },
+/**/ {{0x61f84829, 0xbfb13008} },
+/**/ {{0xa8e135a1, 0xbfbfb14f} },
+/**/ {{0x4324f177, 0x3fb0b532} },
+/**/ {{0x3498dd9d, 0x3fb6734a} } },
+/**/ {{{0x00000000, 0x3fb30000} },
+/**/ {{0x318a4a9a, 0x3fb2f719} },
+/**/ {{0x79b9801f, 0x3c03fd17} },
+/**/ {{0x48e238fe, 0x3fefd31f} },
+/**/ {{0xd8c45327, 0xbc876a7a} },
+/**/ {{0x852096e2, 0xbfb2cada} },
+/**/ {{0x11efd787, 0x3c460860} },
+/**/ {{0x2e476a39, 0xbfd4a34b} },
+/**/ {{0xeb11ee51, 0x3c7254f2} },
+/**/ {{0xc54ae225, 0x3fb27c13} },
+/**/ {{0x4ae66f0c, 0x3c513096} },
+/**/ {{0xef0d59d0, 0x3fc789ca} },
+/**/ {{0x6d9aaa8c, 0xbfb20c06} },
+/**/ {{0x846ba912, 0xbfbf2885} },
+/**/ {{0xc697ef5e, 0x3fb17c5f} },
+/**/ {{0xcad31e6e, 0x3fb5ce93} } },
+/**/ {{{0x00000000, 0x3fb40000} },
+/**/ {{0x0e7c559d, 0x3fb3f59f} },
+/**/ {{0x285df847, 0x3c5ac4ce} },
+/**/ {{0xa6ab93e9, 0x3fefce4d} },
+/**/ {{0x18a97736, 0xbc6be46b} },
+/**/ {{0x4d22b635, 0xbfb3c211} },
+/**/ {{0x6950679f, 0x3c42033c} },
+/**/ {{0xc4d74033, 0xbfd49059} },
+/**/ {{0xd7e376aa, 0x3c57dd7c} },
+/**/ {{0xc0896a7c, 0x3fb36662} },
+/**/ {{0xd79232cf, 0xbc36cf6a} },
+/**/ {{0xa13a97a2, 0x3fc75261} },
+/**/ {{0x5fdd1509, 0xbfb2e431} },
+/**/ {{0x6e52db32, 0xbfbe9999} },
+/**/ {{0xb0a71e9f, 0x3fb23da4} },
+/**/ {{0xe3bc8178, 0x3fb52335} } },
+/**/ {{{0x00000000, 0x3fb50000} },
+/**/ {{0x677292fb, 0x3fb4f3fd} },
+/**/ {{0x6264979e, 0x3c4008d3} },
+/**/ {{0x53a1ee0d, 0x3fefc93e} },
+/**/ {{0x20fd2bdf, 0xbc64421a} },
+/**/ {{0x4aba88e3, 0xbfb4b85f} },
+/**/ {{0x3c9d1e89, 0x3c54f184} },
+/**/ {{0x25ae4668, 0xbfd47c7f} },
+/**/ {{0x816630d1, 0xbc7d7581} },
+/**/ {{0x07f85056, 0x3fb44e7b} },
+/**/ {{0x910bdf4f, 0x3c56d63c} },
+/**/ {{0xc439029c, 0x3fc71875} },
+/**/ {{0xf2bcfa10, 0xbfb3b85e} },
+/**/ {{0x9707b205, 0xbfbe04bb} },
+/**/ {{0x95e3e0cc, 0x3fb2f8c6} },
+/**/ {{0x8093431b, 0x3fb47184} } },
+/**/ {{{0x00000000, 0x3fb60000} },
+/**/ {{0x4fd2d7b2, 0x3fb5f232} },
+/**/ {{0x4401318e, 0x3c58a8da} },
+/**/ {{0x8b549418, 0x3fefc3f1} },
+/**/ {{0x836f8130, 0x3c34d896} },
+/**/ {{0x9cdd92e7, 0xbfb5adb9} },
+/**/ {{0xeb397cc3, 0x3c4d4161} },
+/**/ {{0x93f8f1dc, 0xbfd467bd} },
+/**/ {{0xffc760ad, 0xbc609d7b} },
+/**/ {{0xbea6b2fe, 0x3fb53443} },
+/**/ {{0x4b24f5db, 0x3c5eb03c} },
+/**/ {{0x8de3d005, 0x3fc6dc13} },
+/**/ {{0x37d2d99d, 0xbfb48866} },
+/**/ {{0xf6663fcb, 0xbfbd6a1d} },
+/**/ {{0x0adff464, 0x3fb3ad8e} },
+/**/ {{0x4159c223, 0x3fb3b9d6} } },
+/**/ {{{0x00000000, 0x3fb70000} },
+/**/ {{0xdcea4b0d, 0x3fb6f03b} },
+/**/ {{0x512fa17d, 0xbc33f00e} },
+/**/ {{0x8c07a436, 0x3fefbe67} },
+/**/ {{0x46250d6f, 0xbc84baaa} },
+/**/ {{0x7e3ba4c7, 0xbfb6a215} },
+/**/ {{0x54503f8d, 0xbc3504e7} },
+/**/ {{0x6b82d03a, 0xbfd45217} },
+/**/ {{0xbebdd1db, 0x3c7d1f0d} },
+/**/ {{0x841d5604, 0x3fb617a4} },
+/**/ {{0x6681c436, 0xbc47168b} },
+/**/ {{0xaccec6ce, 0x3fc69d47} },
+/**/ {{0xa4715800, 0xbfb5541f} },
+/**/ {{0x335a1c1b, 0xbfbcc9f4} },
+/**/ {{0xbac0061f, 0x3fb45bc6} },
+/**/ {{0x2b3853b6, 0x3fb2fc84} } },
+/**/ {{{0x00000000, 0x3fb80000} },
+/**/ {{0x2602f10f, 0x3fb7ee18} },
+/**/ {{0x4c0c3d98, 0xbc5cfb65} },
+/**/ {{0x96acfacc, 0x3fefb8a0} },
+/**/ {{0x18495af3, 0xbc82962e} },
+/**/ {{0x46635c89, 0xbfb79568} },
+/**/ {{0xa6bfd498, 0x3c5ac468} },
+/**/ {{0x2037b997, 0xbfd43b8f} },
+/**/ {{0xe2f12373, 0xbc72ad53} },
+/**/ {{0x7900c4ee, 0x3fb6f885} },
+/**/ {{0x0aef1f9d, 0x3c53145d} },
+/**/ {{0x4409ba0e, 0x3fc65c1f} },
+/**/ {{0x1d176e0c, 0xbfb61b65} },
+/**/ {{0x8ad65152, 0xbfbc2473} },
+/**/ {{0x7bc246c1, 0x3fb5033f} },
+/**/ {{0x6db30b46, 0x3fb239e9} } },
+/**/ {{{0x00000000, 0x3fb90000} },
+/**/ {{0x4478fb28, 0x3fb8ebc5} },
+/**/ {{0x0cad24cc, 0x3c473288} },
+/**/ {{0xeedcd6d7, 0x3fefb29c} },
+/**/ {{0x23ea50f0, 0x3c8efa9e} },
+/**/ {{0x6ae09982, 0xbfb887a7} },
+/**/ {{0x53801511, 0x3c5b2275} },
+/**/ {{0x3da0757c, 0xbfd42427} },
+/**/ {{0x311c7ac8, 0xbc7199e5} },
+/**/ {{0x4388717b, 0x3fb7d6cf} },
+/**/ {{0x3dd070b4, 0xbc5c4eb2} },
+/**/ {{0xe6c2b5f3, 0x3fc618a7} },
+/**/ {{0x00313569, 0xbfb6de12} },
+/**/ {{0xb6316619, 0xbfbb79d2} },
+/**/ {{0x61af5c21, 0x3fb5a3ca} },
+/**/ {{0x26e60289, 0x3fb17263} } },
+/**/ {{{0x00000000, 0x3fba0000} },
+/**/ {{0x53cfdcf1, 0x3fb9e941} },
+/**/ {{0x1d69c47e, 0x3c5a332e} },
+/**/ {{0xdace3776, 0x3fefac5c} },
+/**/ {{0x1ad91ab5, 0xbc8c9a78} },
+/**/ {{0x8054ad75, 0xbfb978c8} },
+/**/ {{0x8ed66c17, 0xbc5e35b8} },
+/**/ {{0x665afed1, 0xbfd40be2} },
+/**/ {{0x08ef10fb, 0x3c62eeef} },
+/**/ {{0x13c989d2, 0x3fb8b26b} },
+/**/ {{0xbfeab3ba, 0x3c329f11} },
+/**/ {{0x93c8f97c, 0x3fc5d2ef} },
+/**/ {{0x30234881, 0xbfb79c03} },
+/**/ {{0xd0f650c8, 0xbfbaca49} },
+/**/ {{0xce2dcccc, 0x3fb63d3c} },
+/**/ {{0x26fb0af2, 0x3fb0a650} } },
+/**/ {{{0x00000000, 0x3fbb0000} },
+/**/ {{0x71c722b8, 0x3fbae68a} },
+/**/ {{0x6910b9db, 0x3c4c014e} },
+/**/ {{0xa34ef42b, 0x3fefa5e0} },
+/**/ {{0xeb56d5b9, 0xbc836583} },
+/**/ {{0x3b881779, 0xbfba68c1} },
+/**/ {{0x13a09314, 0xbc473a0d} },
+/**/ {{0x538e939c, 0xbfd3f2c3} },
+/**/ {{0xee53e648, 0xbc68ed49} },
+/**/ {{0xa7d45973, 0x3fb98b42} },
+/**/ {{0x461ca7c4, 0xbc523943} },
+/**/ {{0xb0f2e2bb, 0x3fc58b04} },
+/**/ {{0x1c9d23dc, 0xbfb85517} },
+/**/ {{0x3e3b5a66, 0xbfba1612} },
+/**/ {{0x7ef1d0b9, 0x3fb6cf6f} },
+/**/ {{0x6617b315, 0x3fafac21} } },
+/**/ {{{0x00000000, 0x3fbc0000} },
+/**/ {{0xbe6f07c3, 0x3fbbe39e} },
+/**/ {{0x29a05987, 0x3c5f7b8f} },
+/**/ {{0x93bb9192, 0x3fef9f28} },
+/**/ {{0x7cd1bdab, 0x3c78260b} },
+/**/ {{0x72759741, 0xbfbb5787} },
+/**/ {{0xa6767247, 0x3c52f93f} },
+/**/ {{0xd45bbe91, 0xbfd3d8cc} },
+/**/ {{0x2edc0762, 0x3c664839} },
+/**/ {{0x4fa31d26, 0x3fba6140} },
+/**/ {{0x97891510, 0x3c400647} },
+/**/ {{0x0668fd66, 0x3fc540f6} },
+/**/ {{0xcb2f6e8f, 0xbfb9092d} },
+/**/ {{0x8d902073, 0xbfb95d66} },
+/**/ {{0x99c53d16, 0x3fb75a3e} },
+/**/ {{0x8f475e61, 0x3fae040c} } },
+/**/ {{{0x00000000, 0x3fbd0000} },
+/**/ {{0x5c3cca32, 0x3fbce07c} },
+/**/ {{0x425918a7, 0x3c4138e6} },
+/**/ {{0xf9f6d421, 0x3fef9834} },
+/**/ {{0x8c22a239, 0x3c6f3089} },
+/**/ {{0x1d4e69a5, 0xbfbc4511} },
+/**/ {{0xd2083ce8, 0x3c254c0f} },
+/**/ {{0xcd488978, 0xbfd3be01} },
+/**/ {{0x6362ec0f, 0x3c5612db} },
+/**/ {{0xf0d94873, 0x3fbb344e} },
+/**/ {{0xfdf7db72, 0xbc182beb} },
+/**/ {{0xb9d86c04, 0x3fc4f4d2} },
+/**/ {{0xdf238807, 0xbfb9b828} },
+/**/ {{0x5f93ffd6, 0xbfb8a082} },
+/**/ {{0xb6650b0c, 0x3fb7dd89} },
+/**/ {{0xb62676ef, 0x3fac5526} } },
+/**/ {{{0x00000000, 0x3fbe0000} },
+/**/ {{0x701eba6e, 0x3fbddd21} },
+/**/ {{0xcd76fe58, 0x3c594eff} },
+/**/ {{0x266112ba, 0x3fef9106} },
+/**/ {{0x6b7e18b1, 0x3c74c302} },
+/**/ {{0x5777816c, 0xbfbd3154} },
+/**/ {{0x1f9dbddd, 0x3c5dc7e4} },
+/**/ {{0x37a90881, 0xbfd3a265} },
+/**/ {{0xeb7ba840, 0xbc75bd61} },
+/**/ {{0x0a52514b, 0x3fbc045a} },
+/**/ {{0xcff49a99, 0xbc35ca88} },
+/**/ {{0x498eeb56, 0x3fc4a6aa} },
+/**/ {{0xa09232cf, 0xbfba61eb} },
+/**/ {{0x4a464027, 0xbfb7dfa2} },
+/**/ {{0xe633c053, 0x3fb85933} },
+/**/ {{0x3f920107, 0x3faaa036} } },
+/**/ {{{0x00000000, 0x3fbf0000} },
+/**/ {{0x2190043b, 0x3fbed98c} },
+/**/ {{0x592c7b13, 0xbc23a598} },
+/**/ {{0x6bcf4ad8, 0x3fef899c} },
+/**/ {{0x912c09b0, 0x3c55fd73} },
+/**/ {{0x607f91a0, 0xbfbe1c47} },
+/**/ {{0x5b5db022, 0x3c576677} },
+/**/ {{0x21046f5f, 0xbfd385fa} },
+/**/ {{0x4487f4b8, 0x3c7f01c3} },
+/**/ {{0xb77f2d51, 0x3fbcd14d} },
+/**/ {{0x30a2ccfe, 0x3c57a86d} },
+/**/ {{0x8782b530, 0x3fc4568c} },
+/**/ {{0x02b7ad2d, 0xbfbb065b} },
+/**/ {{0xbd215555, 0xbfb71b03} },
+/**/ {{0xb9c1c1de, 0x3fb8cd23} },
+/**/ {{0x8dbfa69b, 0x3fa8e602} } },
+/**/ {{{0x00000000, 0x3fc00000} },
+/**/ {{0x9aac2f6e, 0x3fbfd5ba} },
+/**/ {{0x86760c17, 0xbc4cd376} },
+/**/ {{0x1f81f820, 0x3fef81f8} },
+/**/ {{0x1f81f820, 0xbc8f81f8} },
+/**/ {{0x9d0dc11b, 0xbfbf05e0} },
+/**/ {{0x1d821725, 0xbc35a199} },
+/**/ {{0xaa76e1d7, 0xbfd368c3} },
+/**/ {{0xc796f8cd, 0xbc672d4c} },
+/**/ {{0xb391c2e3, 0x3fbd9b16} },
+/**/ {{0x8086c51d, 0x3c58051b} },
+/**/ {{0x94488c86, 0x3fc40489} },
+/**/ {{0xa98401c8, 0xbfbba55d} },
+/**/ {{0xe5127e64, 0xbfb652e4} },
+/**/ {{0x442e53ae, 0x3fb93943} },
+/**/ {{0x86286f75, 0x3fa72753} } },
+/**/ {{{0x00000000, 0x3fc08000} },
+/**/ {{0x84212b3e, 0x3fc068d5} },
+/**/ {{0x83019bfd, 0xbc69e2d2} },
+/**/ {{0x991bb133, 0x3fef7a19} },
+/**/ {{0x66627723, 0x3c7a956a} },
+/**/ {{0x97c8e137, 0xbfbfee16} },
+/**/ {{0x66dbe7af, 0x3c4d9399} },
+/**/ {{0x0810323a, 0xbfd34ac5} },
+/**/ {{0x6bc6c512, 0x3c6a1a57} },
+/**/ {{0x5c75a6f9, 0x3fbe61a2} },
+/**/ {{0xd75c8f85, 0xbc492b99} },
+/**/ {{0xd9fa3f20, 0x3fc3b0b1} },
+/**/ {{0xee66d309, 0xbfbc3edb} },
+/**/ {{0x905eeb33, 0xbfb58784} },
+/**/ {{0x1c65bb14, 0x3fb99d80} },
+/**/ {{0x18a09884, 0x3fa564f1} } },
+/**/ {{{0x00000000, 0x3fc10000} },
+/**/ {{0xccf40882, 0x3fc0e6ad} },
+/**/ {{0x1bb98d0d, 0xbc6d71a3} },
+/**/ {{0x32978bad, 0x3fef7201} },
+/**/ {{0x599381e9, 0x3c816476} },
+/**/ {{0x011b81fd, 0xbfc06a70} },
+/**/ {{0x9ba697ca, 0xbc422f5d} },
+/**/ {{0x802fc0a5, 0xbfd32c01} },
+/**/ {{0x08a20868, 0x3c7d8e47} },
+/**/ {{0xb59597fe, 0x3fbf24de} },
+/**/ {{0x410d31eb, 0xbc43288f} },
+/**/ {{0x070feb24, 0x3fc35b16} },
+/**/ {{0xe4565b78, 0xbfbcd2bf} },
+/**/ {{0x128768c6, 0xbfb4b922} },
+/**/ {{0x5c42a097, 0x3fb9f9cb} },
+/**/ {{0xc7f97f2e, 0x3fa39fa2} } },
+/**/ {{{0x00000000, 0x3fc18000} },
+/**/ {{0x41060850, 0x3fc16465} },
+/**/ {{0x8ae7ea92, 0x3c66bcee} },
+/**/ {{0x483f492b, 0x3fef69af} },
+/**/ {{0x57db963e, 0xbc6e3280} },
+/**/ {{0xdacaa844, 0xbfc0dd19} },
+/**/ {{0xad7fc21e, 0xbc6133c7} },
+/**/ {{0x6addaea8, 0xbfd30c7c} },
+/**/ {{0x89161c76, 0xbc71443d} },
+/**/ {{0x6a6d3cd2, 0x3fbfe4ba} },
+/**/ {{0x423ee67a, 0x3c50d4b8} },
+/**/ {{0x092e569a, 0x3fc303c7} },
+/**/ {{0x5b11d3b6, 0xbfbd60f5} },
+/**/ {{0x283b5c55, 0xbfb3e7fd} },
+/**/ {{0x9d9a6ab7, 0x3fba4e19} },
+/**/ {{0x3487cc29, 0x3fa1d82f} } },
+/**/ {{{0x00000000, 0x3fc20000} },
+/**/ {{0xfb043727, 0x3fc1e1fa} },
+/**/ {{0x14dacf8c, 0xbc4b4859} },
+/**/ {{0x38a14f5e, 0x3fef6124} },
+/**/ {{0x001f6124, 0x3c798e9e} },
+/**/ {{0x59d3fb7c, 0xbfc14f04} },
+/**/ {{0x4cc99cb2, 0x3c531efa} },
+/**/ {{0x31219b34, 0xbfd2ec39} },
+/**/ {{0x6e004611, 0xbc618697} },
+/**/ {{0x68736312, 0x3fc05092} },
+/**/ {{0x8a06e4b5, 0x3c67aad4} },
+/**/ {{0x07eca5ec, 0x3fc2aad6} },
+/**/ {{0xe19fe31c, 0xbfbde969} },
+/**/ {{0xdb6b9127, 0xbfb31455} },
+/**/ {{0xf53dd9ee, 0x3fba9a62} },
+/**/ {{0xa8e4ede0, 0x3fa00f5b} } },
+/**/ {{{0x00000000, 0x3fc28000} },
+/**/ {{0x171a535c, 0x3fc25f6e} },
+/**/ {{0xbde1a310, 0x3c67c6d7} },
+/**/ {{0x64866d22, 0x3fef5860} },
+/**/ {{0xd1f6326c, 0x3c88c6ff} },
+/**/ {{0x13c11396, 0xbfc1c02b} },
+/**/ {{0xffeb1a0f, 0xbc51b469} },
+/**/ {{0x4c571b0f, 0xbfd2cb3b} },
+/**/ {{0x2fb0b163, 0x3c6e4f76} },
+/**/ {{0xf5c213ab, 0x3fc0ad06} },
+/**/ {{0xabea9e66, 0x3c625bf2} },
+/**/ {{0x5f93bbb2, 0x3fc25054} },
+/**/ {{0xc80a32c8, 0xbfbe6c0c} },
+/**/ {{0x678d0d1e, 0xbfb23e6c} },
+/**/ {{0xebf8ae4b, 0x3fbadea2} },
+/**/ {{0x527f133b, 0x3f9c8bd7} } },
+/**/ {{{0x00000000, 0x3fc30000} },
+/**/ {{0xb2fba1ff, 0x3fc2dcbd} },
+/**/ {{0x05561534, 0x3c58f287} },
+/**/ {{0x2ee76e94, 0x3fef4f64} },
+/**/ {{0xc6da5865, 0x3c80ec89} },
+/**/ {{0xb322f867, 0xbfc23089} },
+/**/ {{0x5fcd0d6f, 0x3c4c2b54} },
+/**/ {{0x45802261, 0xbfd2a986} },
+/**/ {{0x5ae78b8a, 0xbc79a132} },
+/**/ {{0x35a9d974, 0x3fc107b3} },
+/**/ {{0xb725e335, 0x3c5ef22d} },
+/**/ {{0x9bd98832, 0x3fc1f453} },
+/**/ {{0x2057aad4, 0xbfbee8cf} },
+/**/ {{0x1e1bc3a1, 0xbfb16681} },
+/**/ {{0x759c8f58, 0x3fbb1ad8} },
+/**/ {{0x0b15b4aa, 0x3f98f941} } },
+/**/ {{{0x00000000, 0x3fc38000} },
+/**/ {{0xedeb99a4, 0x3fc359e8} },
+/**/ {{0x4e4604c6, 0xbc6a5fd7} },
+/**/ {{0xfce28238, 0x3fef462f} },
+/**/ {{0xd90595d1, 0x3c83dc01} },
+/**/ {{0xf7edfa6d, 0xbfc2a01b} },
+/**/ {{0x4a3b5c9a, 0xbc6b11fb} },
+/**/ {{0xb4959402, 0xbfd2871d} },
+/**/ {{0x2fcf7ea3, 0xbc4a3702} },
+/**/ {{0xd8d7fe8c, 0x3fc1608f} },
+/**/ {{0xf8f1d41c, 0x3c61ac60} },
+/**/ {{0x729a89ca, 0x3fc196e5} },
+/**/ {{0xbec74f31, 0xbfbf5fa3} },
+/**/ {{0x4b6c9767, 0xbfb08cd4} },
+/**/ {{0xe624ce15, 0x3fbb4f05} },
+/**/ {{0xddb2020c, 0x3f956871} } },
+/**/ {{{0x00000000, 0x3fc40000} },
+/**/ {{0xe8c6626c, 0x3fc3d6ee} },
+/**/ {{0x0ce9281b, 0x3c661a3b} },
+/**/ {{0x35b0713c, 0x3fef3cc4} },
+/**/ {{0xe69ea094, 0x3c81d0a7} },
+/**/ {{0xb7d169f0, 0xbfc30edd} },
+/**/ {{0xae999b97, 0x3c6b3394} },
+/**/ {{0x3fd62b3c, 0xbfd26405} },
+/**/ {{0xc0736df9, 0x3c73e339} },
+/**/ {{0xe8e57ee3, 0x3fc1b795} },
+/**/ {{0x0a42c7f6, 0xbc6130dc} },
+/**/ {{0xbe93b8e5, 0x3fc1381b} },
+/**/ {{0x394e1bf7, 0xbfbfd07f} },
+/**/ {{0x37bb5315, 0xbfaf634c} },
+/**/ {{0xe501e57b, 0x3fbb7b30} },
+/**/ {{0x20503792, 0x3f91dae1} } },
+/**/ {{{0x00000000, 0x3fc48000} },
+/**/ {{0xc6092a9e, 0x3fc453ce} },
+/**/ {{0xb3a5a78b, 0x3c61f653} },
+/**/ {{0x4299ace8, 0x3fef3321} },
+/**/ {{0x3a742b30, 0xbc87414c} },
+/**/ {{0xde8b2323, 0xbfc37cca} },
+/**/ {{0x7b50aedf, 0x3c649378} },
+/**/ {{0x9b13f4d0, 0xbfd24040} },
+/**/ {{0xb7dc85c0, 0x3c7e271f} },
+/**/ {{0xc9024068, 0x3fc20cbe} },
+/**/ {{0x88ef3da7, 0x3c50921f} },
+/**/ {{0x7a1f1270, 0x3fc0d808} },
+/**/ {{0xf32d5436, 0xbfc01dab} },
+/**/ {{0x02e6f09c, 0xbfadaa6d} },
+/**/ {{0x5e9cd766, 0x3fbb9f62} },
+/**/ {{0xab964c04, 0x3f8ca3fe} } },
+/**/ {{{0x00000000, 0x3fc50000} },
+/**/ {{0xa9da4f17, 0x3fc4d087} },
+/**/ {{0xf1adf158, 0x3c61f323} },
+/**/ {{0x8eeb3352, 0x3fef2947} },
+/**/ {{0x8799a164, 0x3c871eb0} },
+/**/ {{0x6e36e75c, 0xbfc3e9df} },
+/**/ {{0x4e37666f, 0x3c541555} },
+/**/ {{0x87008bd0, 0xbfd21bd3} },
+/**/ {{0xc24ff75f, 0xbc609e14} },
+/**/ {{0x36860504, 0x3fc26004} },
+/**/ {{0x1ebc8c40, 0xbc58f8ca} },
+/**/ {{0xb9f4ead3, 0x3fc076bd} },
+/**/ {{0xed70ddd5, 0xbfc05012} },
+/**/ {{0x33e194b1, 0xbfabef8a} },
+/**/ {{0x7423a91f, 0x3fbbbba6} },
+/**/ {{0xdd99da12, 0x3f859e6a} } },
+/**/ {{{0x00000000, 0x3fc58000} },
+/**/ {{0xba11570a, 0x3fc54d18} },
+/**/ {{0xf2884073, 0x3c618282} },
+/**/ {{0x87eb4d7d, 0x3fef1f37} },
+/**/ {{0xedda13e6, 0x3c8476f0} },
+/**/ {{0x7f997c7c, 0xbfc45617} },
+/**/ {{0x6423ceda, 0xbc46bf5b} },
+/**/ {{0xd0784ec7, 0xbfd1f6c1} },
+/**/ {{0xd106a8e0, 0xbc74ec12} },
+/**/ {{0x4967338d, 0x3fc2b160} },
+/**/ {{0x61339c25, 0x3c5309c0} },
+/**/ {{0xa7f42962, 0x3fc0144d} },
+/**/ {{0x73dbaeec, 0xbfc07f71} },
+/**/ {{0x2aeda9a4, 0xbfaa3322} },
+/**/ {{0x69b152b3, 0x3fbbd00c} },
+/**/ {{0x4c782821, 0x3f7d4f90} } },
+/**/ {{{0x00000000, 0x3fc60000} },
+/**/ {{0x1e3ec26a, 0x3fc5c981} },
+/**/ {{0x2c010f3d, 0xbc5054ab} },
+/**/ {{0x9cce28eb, 0x3fef14f1} },
+/**/ {{0x2708cd6e, 0xbc8b7c25} },
+/**/ {{0x42678d07, 0xbfc4c16f} },
+/**/ {{0xc1560017, 0x3c5f55ba} },
+/**/ {{0x4fccc153, 0xbfd1d10f} },
+/**/ {{0x1bcc361d, 0x3c529588} },
+/**/ {{0x74979f8c, 0x3fc300cd} },
+/**/ {{0x0bc1e891, 0xbc6b1da5} },
+/**/ {{0xfbe70208, 0x3fbf6194} },
+/**/ {{0x4b1c266f, 0xbfc0abc5} },
+/**/ {{0x3b74e858, 0xbfa875b2} },
+/**/ {{0x92e46f11, 0x3fbbdca6} },
+/**/ {{0x9de94aef, 0x3f6f0b17} } },
+/**/ {{{0x00000000, 0x3fc68000} },
+/**/ {{0xffb3aa74, 0x3fc645bf} },
+/**/ {{0x677c2cb4, 0xbc3f536b} },
+/**/ {{0x3eaa4ed6, 0x3fef0a76} },
+/**/ {{0x0b06c761, 0x3c888c52} },
+/**/ {{0xfd884489, 0xbfc52be2} },
+/**/ {{0xbe5c728a, 0x3c67ec59} },
+/**/ {{0xe80e4e0a, 0xbfd1aabf} },
+/**/ {{0xe90c909e, 0xbc71320e} },
+/**/ {{0x864781ca, 0x3fc34e46} },
+/**/ {{0x126138ee, 0x3c42fcb3} },
+/**/ {{0x013b5d4f, 0x3fbe988d} },
+/**/ {{0x122409a2, 0xbfc0d50d} },
+/**/ {{0x7bb562c1, 0xbfa6b7b6} },
+/**/ {{0x3df8dee8, 0x3fbbe18a} },
+/**/ {{0x8809e1ef, 0x3f3e4009} } },
+/**/ {{{0x00000000, 0x3fc70000} },
+/**/ {{0x898933d9, 0x3fc6c1d4} },
+/**/ {{0x7603c427, 0xbc52954a} },
+/**/ {{0xe06cfb34, 0x3feeffc5} },
+/**/ {{0x379877c2, 0xbc85c037} },
+/**/ {{0x0f53a52c, 0xbfc5956f} },
+/**/ {{0xe566376c, 0x3c4d46a2} },
+/**/ {{0x86559c11, 0xbfd183d7} },
+/**/ {{0x64734c7f, 0x3c7d2520} },
+/**/ {{0xa80eddd5, 0x3fc399c6} },
+/**/ {{0x40fbef6f, 0x3c616c26} },
+/**/ {{0xf4b571a7, 0x3fbdcda7} },
+/**/ {{0x3fd42996, 0xbfc0fb48} },
+/**/ {{0x95c85118, 0xbfa4f9a9} },
+/**/ {{0x9d795df4, 0x3fbbdecf} },
+/**/ {{0xb85bf719, 0xbf672003} } },
+/**/ {{{0x00000000, 0x3fc78000} },
+/**/ {{0xe8a7d202, 0x3fc73dbd} },
+/**/ {{0x6d4a665d, 0xbc55ad0f} },
+/**/ {{0xf6ce5590, 0x3feef4e0} },
+/**/ {{0x556900ef, 0xbc833df6} },
+/**/ {{0xedcc9488, 0xbfc5fe0f} },
+/**/ {{0xd2b9e35c, 0x3c5078de} },
+/**/ {{0x210cab36, 0xbfd15c5a} },
+/**/ {{0xf55e532a, 0x3c67fa93} },
+/**/ {{0x5efd9a41, 0x3fc3e349} },
+/**/ {{0xc8573a12, 0xbc6cf709} },
+/**/ {{0x6c903aef, 0x3fbd010a} },
+/**/ {{0x20571328, 0xbfc11e77} },
+/**/ {{0x9a1875dd, 0xbfa33c04} },
+/**/ {{0xb09ec0ce, 0x3fbbd491} },
+/**/ {{0x35537a65, 0xbf78d197} } },
+/**/ {{{0x00000000, 0x3fc80000} },
+/**/ {{0x4bce5b02, 0x3fc7b97b} },
+/**/ {{0xb4f881ca, 0x3c5347b0} },
+/**/ {{0xf8458e02, 0x3feee9c7} },
+/**/ {{0x7ba71fe1, 0xbc616380} },
+/**/ {{0x26d69eeb, 0xbfc665c2} },
+/**/ {{0xfdb5eea8, 0xbc572a33} },
+/**/ {{0xb737e8f3, 0xbfd1344b} },
+/**/ {{0x62badf41, 0xbc757b70} },
+/**/ {{0x8b929b0b, 0x3fc42aca} },
+/**/ {{0x7a8b7d91, 0x3c43cdb5} },
+/**/ {{0xf683981c, 0x3fbc32d8} },
+/**/ {{0xd22d5ecc, 0xbfc13e9a} },
+/**/ {{0xd35c8c33, 0xbfa17f3e} },
+/**/ {{0x2a73307e, 0x3fbbc2ee} },
+/**/ {{0x2bddc834, 0xbf82ee04} } },
+/**/ {{{0x00000000, 0x3fc88000} },
+/**/ {{0xe398ebc8, 0x3fc8350b} },
+/**/ {{0x32b9c90d, 0xbc55a913} },
+/**/ {{0x5cfce04c, 0x3feede7b} },
+/**/ {{0x3b51a72f, 0x3c8507c2} },
+/**/ {{0x6067718b, 0xbfc6cc82} },
+/**/ {{0xdbfc430f, 0x3c6d00ca} },
+/**/ {{0x4fbf6fe8, 0xbfd10bb0} },
+/**/ {{0x53749c72, 0x3c321748} },
+/**/ {{0x699a36ad, 0x3fc47046} },
+/**/ {{0x3994d40c, 0xbc63924c} },
+/**/ {{0x0dfb7483, 0x3fbb6338} },
+/**/ {{0x42ee5820, 0xbfc15bb5} },
+/**/ {{0x385194fc, 0xbf9f879b} },
+/**/ {{0x57d040e9, 0x3fbbaa05} },
+/**/ {{0xada71ca0, 0xbf895566} } },
+/**/ {{{0x00000000, 0x3fc90000} },
+/**/ {{0xe2879c29, 0x3fc8b06e} },
+/**/ {{0x30308c4f, 0xbc6118cd} },
+/**/ {{0x9ec57f51, 0x3feed2fb} },
+/**/ {{0xc0d106ba, 0xbc83fdc5} },
+/**/ {{0x58b40d27, 0xbfc7324d} },
+/**/ {{0xfc062163, 0x3c68e240} },
+/**/ {{0xf8b8a2bf, 0xbfd0e28b} },
+/**/ {{0x64c55b39, 0xbc7b8d8a} },
+/**/ {{0x8ff46730, 0x3fc4b3b9} },
+/**/ {{0x988563da, 0xbc5af146} },
+/**/ {{0x1277a10d, 0x3fba924c} },
+/**/ {{0x2bbfd54d, 0xbfc175c9} },
+/**/ {{0x6c522340, 0xbf9c1448} },
+/**/ {{0x044f2f6b, 0x3fbb89fa} },
+/**/ {{0xaaecc742, 0xbf8f9cc7} } },
+/**/ {{{0x00000000, 0x3fc98000} },
+/**/ {{0x7d050272, 0x3fc92ba3} },
+/**/ {{0xd0ff4764, 0xbc60d3de} },
+/**/ {{0x390b6afe, 0x3feec749} },
+/**/ {{0x4e3659ca, 0xbc5c3d17} },
+/**/ {{0xe659b3de, 0xbfc7971f} },
+/**/ {{0x373f554d, 0x3c4cab11} },
+/**/ {{0xc6b052a4, 0xbfd0b8e2} },
+/**/ {{0x6f3b74bc, 0x3c7da014} },
+/**/ {{0xf0432146, 0x3fc4f520} },
+/**/ {{0xa8027290, 0xbc6769ad} },
+/**/ {{0x3e17b570, 0x3fb9c039} },
+/**/ {{0x0d8833a4, 0xbfc18cda} },
+/**/ {{0x4627d340, 0xbf98a567} },
+/**/ {{0x5e42eff7, 0x3fbb62f1} },
+/**/ {{0x7ee3bed3, 0xbf92e10a} } },
+/**/ {{{0x00000000, 0x3fca0000} },
+/**/ {{0xe96c8626, 0x3fc9a6a8} },
+/**/ {{0xe7b4348e, 0x3c4cf601} },
+/**/ {{0xa8c932d7, 0x3feebb64} },
+/**/ {{0x79aae302, 0x3c20538d} },
+/**/ {{0xf88295fe, 0xbfc7faf6} },
+/**/ {{0x932909e9, 0xbc687a81} },
+/**/ {{0xd3f5a07b, 0xbfd08eb8} },
+/**/ {{0xfb7d6aaa, 0xbc620a05} },
+/**/ {{0xd6814372, 0x3fc53479} },
+/**/ {{0x0a0c6620, 0xbc53c682} },
+/**/ {{0x9c562d77, 0x3fb8ed23} },
+/**/ {{0x2cdd89fd, 0xbfc1a0ec} },
+/**/ {{0xfec9df82, 0xbf953bd4} },
+/**/ {{0xd9d3f0f6, 0x3fbb3512} },
+/**/ {{0x4534ccf5, 0xbf95e1ab} } },
+/**/ {{{0x00000000, 0x3fca8000} },
+/**/ {{0x601081a6, 0x3fca217e} },
+/**/ {{0xa60af374, 0xbc60def8} },
+/**/ {{0x6c7ba732, 0x3feeaf4e} },
+/**/ {{0xe91fffe1, 0x3c89fa72} },
+/**/ {{0x970642c3, 0xbfc85dcf} },
+/**/ {{0x5b7f0ad0, 0xbc5732c2} },
+/**/ {{0x3fe5c74d, 0xbfd06412} },
+/**/ {{0x4a82f9b1, 0xbc7d0053} },
+/**/ {{0xe882973d, 0x3fc571c1} },
+/**/ {{0x9090f12c, 0x3c59d9a3} },
+/**/ {{0x00f5d0e0, 0x3fb8192f} },
+/**/ {{0x8db53983, 0xbfc1b204} },
+/**/ {{0xbdd7b47e, 0xbf91d869} },
+/**/ {{0x1355a903, 0x3fbb0088} },
+/**/ {{0x724a2ad9, 0xbf98cf57} } },
+/**/ {{{0x00000000, 0x3fcb0000} },
+/**/ {{0x1b403279, 0x3fca9c23} },
+/**/ {{0xe89cca85, 0x3c60e8bb} },
+/**/ {{0x04157b4f, 0x3feea307} },
+/**/ {{0xfd8bf1f0, 0x3c8ad743} },
+/**/ {{0xe285e2fd, 0xbfc8bfa6} },
+/**/ {{0x9c834c8f, 0xbc6ce765} },
+/**/ {{0x2e38fd26, 0xbfd038f3} },
+/**/ {{0xef212a80, 0x3c6a42ec} },
+/**/ {{0x255d65d5, 0x3fc5acf7} },
+/**/ {{0xbe486771, 0xbc619fba} },
+/**/ {{0xff244e15, 0x3fb7447e} },
+/**/ {{0xeed71b69, 0xbfc1c028} },
+/**/ {{0xaceecf68, 0xbf8cf7f0} },
+/**/ {{0xb0ee161b, 0x3fbac57c} },
+/**/ {{0xefc8f53e, 0xbf9ba92d} } },
+/**/ {{{0x00000000, 0x3fcb8000} },
+/**/ {{0x574d780c, 0x3fcb1696} },
+/**/ {{0xfc15a673, 0xbc585ab8} },
+/**/ {{0xf0f2da5a, 0x3fee968e} },
+/**/ {{0x69710f0d, 0xbc6fffe1} },
+/**/ {{0x148444b5, 0xbfc9207a} },
+/**/ {{0x1802fa91, 0xbc66661a} },
+/**/ {{0xc65096ca, 0xbfd00d5f} },
+/**/ {{0x8920e744, 0x3c7f2a2e} },
+/**/ {{0xe4be288d, 0x3fc5e617} },
+/**/ {{0x99be934f, 0x3c67fa48} },
+/**/ {{0xe0d4c87a, 0x3fb66f36} },
+/**/ {{0xc5179ce8, 0xbfc1cb5f} },
+/**/ {{0x1011bb6c, 0xbf864e9c} },
+/**/ {{0x43a75476, 0x3fba841e} },
+/**/ {{0x845fc859, 0xbf9e6e5b} } },
+/**/ {{{0x00000000, 0x3fcc0000} },
+/**/ {{0x529260a2, 0x3fcb90d7} },
+/**/ {{0xd2e0e5ab, 0x3c217b10} },
+/**/ {{0xb5ccf172, 0x3fee89e6} },
+/**/ {{0x153be26a, 0x3c820357} },
+/**/ {{0x7f79bfd6, 0xbfc98046} },
+/**/ {{0xf5d60955, 0xbc0799ee} },
+/**/ {{0x650d32f4, 0xbfcfc2b8} },
+/**/ {{0x4d01b49e, 0xbc6b59de} },
+/**/ {{0xd625e475, 0x3fc61d22} },
+/**/ {{0xe23c6105, 0xbc68013f} },
+/**/ {{0x9e54f300, 0x3fb59979} },
+/**/ {{0x365c2b85, 0xbfc1d3b0} },
+/**/ {{0x0afb6b97, 0xbf7f6cc9} },
+/**/ {{0x28035c12, 0x3fba3c9c} },
+/**/ {{0x8331488a, 0xbfa08f0d} } },
+/**/ {{{0x00000000, 0x3fcc8000} },
+/**/ {{0x4d768467, 0x3fcc0ae5} },
+/**/ {{0xf55f26dc, 0xbc604cdb} },
+/**/ {{0xd6ad70cb, 0x3fee7d0e} },
+/**/ {{0xee20d17d, 0x3c8e6761} },
+/**/ {{0x8ee3fcf8, 0xbfc9df09} },
+/**/ {{0xed723e81, 0x3c62daa3} },
+/**/ {{0x3efdc9b4, 0xbfcf69d9} },
+/**/ {{0x85a20110, 0x3c6c7b6f} },
+/**/ {{0x0013c661, 0x3fc65217} },
+/**/ {{0xab1387be, 0xbc678a0c} },
+/**/ {{0xd61f268e, 0x3fb4c369} },
+/**/ {{0x146d6110, 0xbfc1d922} },
+/**/ {{0xc0b0ed0a, 0xbf726199} },
+/**/ {{0x6629c856, 0x3fb9ef27} },
+/**/ {{0xc1ea955d, 0xbfa1dbda} } },
+/**/ {{{0x00000000, 0x3fcd0000} },
+/**/ {{0x8a742e6e, 0x3fcc84bf} },
+/**/ {{0x0682ea26, 0xbc595bdd} },
+/**/ {{0xd8e205ea, 0x3fee7007} },
+/**/ {{0x7b2991c1, 0x3c816199} },
+/**/ {{0xc751a854, 0xbfca3cc0} },
+/**/ {{0x4efbc78c, 0xbc66a2fd} },
+/**/ {{0x76f43baa, 0xbfcf102a} },
+/**/ {{0x38d996b1, 0x3c6cfc38} },
+/**/ {{0xbf1a9ad6, 0x3fc684f3} },
+/**/ {{0x7c3b6690, 0x3c52eaf7} },
+/**/ {{0xc4ebba84, 0x3fb3ed29} },
+/**/ {{0xd79a6a53, 0xbfc1dbbd} },
+/**/ {{0xfd09510e, 0xbf55fa5b} },
+/**/ {{0x91c74d50, 0x3fb99bf2} },
+/**/ {{0x3002c38b, 0xbfa31d41} } },
+/**/ {{{0x00000000, 0x3fcd8000} },
+/**/ {{0x4e1d5395, 0x3fccfe65} },
+/**/ {{0x3f71eafb, 0x3c647b9a} },
+/**/ {{0x42efd10e, 0x3fee62d2} },
+/**/ {{0xa021973e, 0x3c850a65} },
+/**/ {{0xc66a1be4, 0xbfca9969} },
+/**/ {{0x3753f036, 0x3c326164} },
+/**/ {{0x6b550477, 0xbfceb5b4} },
+/**/ {{0xa3ef610f, 0xbc64cacb} },
+/**/ {{0xc4e2c295, 0x3fc6b5b8} },
+/**/ {{0x98b2ac7f, 0x3c66b228} },
+/**/ {{0x3e03bb80, 0x3fb316db} },
+/**/ {{0x99312ba1, 0xbfc1db8c} },
+/**/ {{0x8536556f, 0x3f5ce5b0} },
+/**/ {{0xa9b62abf, 0x3fb94331} },
+/**/ {{0xb36f42fc, 0xbfa452f3} } },
+/**/ {{{0x00000000, 0x3fce0000} },
+/**/ {{0xdf205736, 0x3fcd77d5} },
+/**/ {{0x1534597e, 0x3c6c648d} },
+/**/ {{0x9c86d7c6, 0x3fee556e} },
+/**/ {{0x34c9abfd, 0xbc830c25} },
+/**/ {{0x42f10c89, 0xbfcaf502} },
+/**/ {{0xf8576d95, 0xbc411261} },
+/**/ {{0x7b1596d9, 0xbfce5a7f} },
+/**/ {{0x78f7ae18, 0x3c574baa} },
+/**/ {{0x171949b1, 0x3fc6e466} },
+/**/ {{0x52f9c399, 0xbc6ff86b} },
+/**/ {{0xa3d6f244, 0x3fb2409f} },
+/**/ {{0x0dceacbf, 0xbfc1d898} },
+/**/ {{0xdc715080, 0x3f73c3b6} },
+/**/ {{0xf78687ab, 0x3fb8e519} },
+/**/ {{0x6b1251ec, 0xbfa57cac} } },
+/**/ {{{0x00000000, 0x3fce8000} },
+/**/ {{0x864c9d9e, 0x3fcdf110} },
+/**/ {{0x53bf4781, 0xbc35818b} },
+/**/ {{0x6e7576a6, 0x3fee47dd} },
+/**/ {{0x24b84595, 0x3c89d322} },
+/**/ {{0x0cc64717, 0xbfcb4f88} },
+/**/ {{0x44bb97a3, 0xbc624035} },
+/**/ {{0x046e8a3b, 0xbfcdfe94} },
+/**/ {{0xd278da00, 0xbc6078ee} },
+/**/ {{0x0e4ccbb7, 0x3fc710fc} },
+/**/ {{0x1da51f71, 0xbc58c89c} },
+/**/ {{0xe0d7022a, 0x3fb16a97} },
+/**/ {{0x7f8b58f8, 0xbfc1d2ea} },
+/**/ {{0xaf259d18, 0x3f800ed5} },
+/**/ {{0xeefd29c7, 0x3fb881e1} },
+/**/ {{0xae6aa0c1, 0xbfa69a2c} } },
+/**/ {{{0x00000000, 0x3fcf0000} },
+/**/ {{0x8e96ec4d, 0x3fce6a14} },
+/**/ {{0x2029f765, 0x3c6866b2} },
+/**/ {{0x429bd423, 0x3fee3a1f} },
+/**/ {{0x48961291, 0xbc86174a} },
+/**/ {{0x0ce18ad9, 0xbfcba8f9} },
+/**/ {{0xb50eb15d, 0x3c62e3e9} },
+/**/ {{0x63927806, 0xbfcda1fa} },
+/**/ {{0x8073bacf, 0xbbed7b15} },
+/**/ {{0x54b8d3bb, 0x3fc73b7b} },
+/**/ {{0x74869c1c, 0x3c602afb} },
+/**/ {{0x60993bd6, 0x3fb094e4} },
+/**/ {{0xc806a157, 0xbfc1ca8e} },
+/**/ {{0xa854d278, 0x3f862263} },
+/**/ {{0x0d9e7452, 0x3fb819c1} },
+/**/ {{0x08743869, 0xbfa7ab3d} } },
+/**/ {{{0x00000000, 0x3fcf8000} },
+/**/ {{0x451d980d, 0x3fcee2e1} },
+/**/ {{0x8c46ba91, 0xbc59a770} },
+/**/ {{0xa3df5666, 0x3fee2c34} },
+/**/ {{0x19a92865, 0xbc8ef949} },
+/**/ {{0x454a9009, 0xbfcc0153} },
+/**/ {{0xda1123ca, 0x3c5572bf} },
+/**/ {{0xf169cd42, 0xbfcd44ba} },
+/**/ {{0xf1052e0a, 0xbc6db0f2} },
+/**/ {{0xe5006ad1, 0x3fc763e4} },
+/**/ {{0x3e902796, 0x3c66e21a} },
+/**/ {{0x12812c7d, 0x3faf7f4a} },
+/**/ {{0x4a558d9d, 0xbfc1bf90} },
+/**/ {{0x2be7fbfd, 0x3f8c1b52} },
+/**/ {{0xba5b0263, 0x3fb7acef} },
+/**/ {{0x2dddf4e5, 0xbfa8afad} } },
+/**/ {{{0x00000000, 0x3fd00000} },
+/**/ {{0xf92c80dd, 0x3fcf5b75} },
+/**/ {{0x3cf7afbd, 0x3c68ab6e} },
+/**/ {{0x1e1e1e1e, 0x3fee1e1e} },
+/**/ {{0x1e1e1e1e, 0x3c6e1e1e} },
+/**/ {{0xd10d4986, 0xbfcc5894} },
+/**/ {{0xc4a6886a, 0x3c5f00e2} },
+/**/ {{0x0253d27e, 0xbfcce6de} },
+/**/ {{0x3c5fce89, 0xbc65d764} },
+/**/ {{0x08d88b02, 0x3fc78a3a} },
+/**/ {{0x32bd57e4, 0x3c4fc5d6} },
+/**/ {{0x6a622b44, 0x3fadd5f2} },
+/**/ {{0xecd7c4e0, 0xbfc1b1fa} },
+/**/ {{0x1fc8b549, 0x3f90fc3e} },
+/**/ {{0x25728acf, 0x3fb73ba7} },
+/**/ {{0xeeba051f, 0xbfa9a753} } },
+/**/ {{{0x00000000, 0x3fd04000} },
+/**/ {{0xfc40dbe4, 0x3fcfd3d1} },
+/**/ {{0xf3a1c5ea, 0x3c437146} },
+/**/ {{0x3e228818, 0x3fee0fdc} },
+/**/ {{0x8c042ef5, 0xbc62e075} },
+/**/ {{0xe42a71b9, 0xbfccaebb} },
+/**/ {{0x8025fd1d, 0xbc69fa0a} },
+/**/ {{0xe4ed28e5, 0xbfcc886b} },
+/**/ {{0x7604b95a, 0xbc59ccc3} },
+/**/ {{0x57a32fb9, 0x3fc7ae7c} },
+/**/ {{0xe36848c2, 0x3c67393b} },
+/**/ {{0x5a1b7b6f, 0x3fac2dff} },
+/**/ {{0x12f690d4, 0xbfc1a1db} },
+/**/ {{0xa575dc1d, 0x3f93dc65} },
+/**/ {{0x28a107f6, 0x3fb6c621} },
+/**/ {{0x23d2c35f, 0xbfaa920f} } },
+/**/ {{{0x00000000, 0x3fd08000} },
+/**/ {{0x510665b6, 0x3fd025fa} },
+/**/ {{0x6832fa48, 0xbc7672df} },
+/**/ {{0x9196b776, 0x3fee016f} },
+/**/ {{0xb14efc08, 0x3c81da3a} },
+/**/ {{0xcb847375, 0xbfcd03c6} },
+/**/ {{0xfc4c6f52, 0xbc6819f2} },
+/**/ {{0xe0dbf8a5, 0xbfcc296c} },
+/**/ {{0x27fb1c17, 0xbc55cc84} },
+/**/ {{0xb4fbbf40, 0x3fc7d0ad} },
+/**/ {{0x41b71641, 0x3c6378b3} },
+/**/ {{0x440404cd, 0x3faa87ad} },
+/**/ {{0x96d156a8, 0xbfc18f3d} },
+/**/ {{0x9ef40490, 0x3f96ad9b} },
+/**/ {{0x27a95e14, 0x3fb64c98} },
+/**/ {{0x97cfdce0, 0xbfab6fc3} } },
+/**/ {{{0x00000000, 0x3fd0c000} },
+/**/ {{0xa03d6291, 0x3fd061ee} },
+/**/ {{0xdb154301, 0xbc45f760} },
+/**/ {{0xa6f82a61, 0x3fedf2d8} },
+/**/ {{0x560866af, 0xbc6cedbb} },
+/**/ {{0xecc8c02c, 0xbfcd57b3} },
+/**/ {{0x85b9541c, 0x3c641512} },
+/**/ {{0x35a209c0, 0xbfcbc9e9} },
+/**/ {{0x4914a5d1, 0x3c65bfd8} },
+/**/ {{0x4f358b07, 0x3fc7f0d0} },
+/**/ {{0x3f47a5cc, 0xbc60dc70} },
+/**/ {{0x50af01c1, 0x3fa8e337} },
+/**/ {{0xc2daf61b, 0xbfc17a2f} },
+/**/ {{0x57b649f0, 0x3f996f63} },
+/**/ {{0xf14fef28, 0x3fb5cf46} },
+/**/ {{0xec5a22c2, 0xbfac405c} } },
+/**/ {{{0x00000000, 0x3fd10000} },
+/**/ {{0x97d86362, 0x3fd09dc5} },
+/**/ {{0x390cb865, 0x3c762e47} },
+/**/ {{0x0d8b5ae6, 0x3fede418} },
+/**/ {{0x23f66cf0, 0x3c719298} },
+/**/ {{0xc655a596, 0xbfcdaa81} },
+/**/ {{0x6a90480b, 0x3c666d0d} },
+/**/ {{0x1974fd6c, 0xbfcb69e9} },
+/**/ {{0xec28723f, 0xbc68e199} },
+/**/ {{0x9dcd2641, 0x3fc80ee6} },
+/**/ {{0x45b4bb82, 0x3c37ccfe} },
+/**/ {{0x64b143be, 0x3fa740d7} },
+/**/ {{0x4b6b7330, 0xbfc162bf} },
+/**/ {{0x7a20d203, 0x3f9c2147} },
+/**/ {{0xa0d6b625, 0x3fb54e68} },
+/**/ {{0x7b6e81ad, 0xbfad03cd} } },
+/**/ {{{0x00000000, 0x3fd14000} },
+/**/ {{0xe509acb3, 0x3fd0d97e} },
+/**/ {{0x7bd5a3eb, 0x3c747c31} },
+/**/ {{0x554f6dcf, 0x3fedd52e} },
+/**/ {{0xddcd060b, 0xbc75c686} },
+/**/ {{0xef1cb578, 0xbfcdfc2e} },
+/**/ {{0xd1677d50, 0xbc46ae20} },
+/**/ {{0xb81cdb34, 0xbfcb0974} },
+/**/ {{0xda61c86c, 0x3c36ed8e} },
+/**/ {{0x5fcd53c1, 0x3fc82af3} },
+/**/ {{0x57b559e7, 0xbc424fe5} },
+/**/ {{0x17013aef, 0x3fa5a0c6} },
+/**/ {{0x484940dd, 0xbfc148fa} },
+/**/ {{0x1737ca6d, 0x3f9ec2da} },
+/**/ {{0x800ba495, 0x3fb4ca38} },
+/**/ {{0x35128042, 0xbfadba0e} } },
+/**/ {{{0x00000000, 0x3fd18000} },
+/**/ {{0x362431ca, 0x3fd1151a} },
+/**/ {{0xc9077b9f, 0xbc74dc8d} },
+/**/ {{0x0ef1f116, 0x3fedc61c} },
+/**/ {{0x2d41c166, 0xbc8fe39f} },
+/**/ {{0x1681d2c9, 0xbfce4cba} },
+/**/ {{0x369a3c18, 0x3c340fb4} },
+/**/ {{0x31d921e2, 0xbfcaa894} },
+/**/ {{0x64c48da4, 0x3c6bf59e} },
+/**/ {{0x9a284cea, 0x3fc844f9} },
+/**/ {{0x629cfeb8, 0xbc563be0} },
+/**/ {{0xa7f26285, 0x3fa4033a} },
+/**/ {{0x2e2d72ea, 0xbfc12cef} },
+/**/ {{0x554d151d, 0x3fa0a9da} },
+/**/ {{0xe9f9174f, 0x3fb442f1} },
+/**/ {{0x799e467c, 0xbfae631e} } },
+/**/ {{{0x00000000, 0x3fd1c000} },
+/**/ {{0x3a9ce547, 0x3fd15097} },
+/**/ {{0x7f9ca328, 0xbc7796ba} },
+/**/ {{0xcbc2abaa, 0x3fedb6e1} },
+/**/ {{0xc39a4e7c, 0xbc823b7a} },
+/**/ {{0x0436f806, 0xbfce9c22} },
+/**/ {{0x885803cb, 0xbc64a5ec} },
+/**/ {{0x9a4c8963, 0xbfca474f} },
+/**/ {{0x6793b663, 0x3c671cf3} },
+/**/ {{0x9606243b, 0x3fc85cfc} },
+/**/ {{0x1dcd45ed, 0x3c5fd2b2} },
+/**/ {{0xf8cc655f, 0x3fa2686a} },
+/**/ {{0xc8460b94, 0xbfc10eac} },
+/**/ {{0x0d6eb5ba, 0x3fa1e9bc} },
+/**/ {{0x2e4749c2, 0x3fb3b8d0} },
+/**/ {{0xf0d19201, 0xbfaeff03} } },
+/**/ {{{0x00000000, 0x3fd20000} },
+/**/ {{0xa30bf178, 0x3fd18bf5} },
+/**/ {{0x748b1bf9, 0x3c630ca4} },
+/**/ {{0x1da7801e, 0x3feda780} },
+/**/ {{0x961ff896, 0xbc861ff8} },
+/**/ {{0x9814cb11, 0xbfceea65} },
+/**/ {{0x34cb01ca, 0xbc5f9845} },
+/**/ {{0xf76f9fa1, 0xbfc9e5ae} },
+/**/ {{0xa3ee6a86, 0x3c688b7a} },
+/**/ {{0xdf090624, 0x3fc872ff} },
+/**/ {{0x6fbad4bb, 0x3c31016f} },
+/**/ {{0x83fe02bc, 0x3fa0d08b} },
+/**/ {{0x31b98637, 0xbfc0ee42} },
+/**/ {{0x5b309f28, 0x3fa320e6} },
+/**/ {{0x755cbc43, 0x3fb32c0e} },
+/**/ {{0x5dea1ddb, 0xbfaf8dca} } },
+/**/ {{{0x00000000, 0x3fd24000} },
+/**/ {{0x212dd884, 0x3fd1c735} },
+/**/ {{0x78cb2f2e, 0xbc67d9ac} },
+/**/ {{0x971063d2, 0x3fed97f7} },
+/**/ {{0xc8b326b7, 0x3c67a20b} },
+/**/ {{0xc9f01359, 0xbfcf3783} },
+/**/ {{0xd0a651ad, 0x3c4a8b96} },
+/**/ {{0x408a6757, 0xbfc983ba} },
+/**/ {{0xe6424f06, 0x3c6dfff9} },
+/**/ {{0x41881aad, 0x3fc88707} },
+/**/ {{0x2204fd29, 0xbc63baf9} },
+/**/ {{0xabd6e10d, 0x3f9e779e} },
+/**/ {{0xcf2eab41, 0xbfc0cbbe} },
+/**/ {{0x1659f377, 0x3fa44f31} },
+/**/ {{0xa54a8a94, 0x3fb29ce7} },
+/**/ {{0xb87973d7, 0xbfb007c1} } },
+/**/ {{{0x00000000, 0x3fd28000} },
+/**/ {{0x67e47c96, 0x3fd20255} },
+/**/ {{0x28f4290e, 0xbc618323} },
+/**/ {{0xcaeb6c2a, 0x3fed8848} },
+/**/ {{0xa08296a2, 0x3c81e70d} },
+/**/ {{0xa96c2792, 0xbfcf837b} },
+/**/ {{0xc6884369, 0xbc6ab5ce} },
+/**/ {{0x5d351cdb, 0xbfc92179} },
+/**/ {{0x68719d81, 0x3c617000} },
+/**/ {{0xc8c1ca07, 0x3fc89916} },
+/**/ {{0x18b0f81b, 0xbc6a3339} },
+/**/ {{0x0caf6121, 0x3f9b54d0} },
+/**/ {{0x485ba392, 0xbfc0a732} },
+/**/ {{0xc250c31e, 0x3fa57477} },
+/**/ {{0x4790b4a8, 0x3fb20b96} },
+/**/ {{0x4ac23178, 0xbfb04223} } },
+/**/ {{{0x00000000, 0x3fd2c000} },
+/**/ {{0x2b381042, 0x3fd23d56} },
+/**/ {{0x16200088, 0xbc5c5317} },
+/**/ {{0x4c98f347, 0x3fed7874} },
+/**/ {{0x9a72647e, 0xbc8a7dac} },
+/**/ {{0x5dca68a2, 0xbfcfce4c} },
+/**/ {{0x8fb9ffdd, 0x3c6433de} },
+/**/ {{0x246041ce, 0xbfc8bef4} },
+/**/ {{0x1fb39160, 0xbc66c620} },
+/**/ {{0xbd062535, 0x3fc8a932} },
+/**/ {{0xfbc3a86c, 0xbc6e24c7} },
+/**/ {{0x64d0109d, 0x3f98390b} },
+/**/ {{0x819f2998, 0xbfc080ac} },
+/**/ {{0x8784ffb8, 0x3fa69099} },
+/**/ {{0x6fc55e9b, 0x3fb17854} },
+/**/ {{0x5f970a81, 0xbfb07618} } },
+/**/ {{{0x00000000, 0x3fd30000} },
+/**/ {{0x2057ef46, 0x3fd27837} },
+/**/ {{0xd36dfc81, 0xbc7077cd} },
+/**/ {{0xafdfd5ba, 0x3fed687a} },
+/**/ {{0xe19d8d3d, 0xbc782e68} },
+/**/ {{0x92db6fdb, 0xbfd00bfa} },
+/**/ {{0xc0af523f, 0x3c7854cd} },
+/**/ {{0x5b640da2, 0xbfc85c32} },
+/**/ {{0x5e6f23d6, 0x3c5d5bdd} },
+/**/ {{0xa1da32d2, 0x3fc8b75f} },
+/**/ {{0x29860bfe, 0x3c2788df} },
+/**/ {{0xee810d60, 0x3f9524ad} },
+/**/ {{0x95a69dea, 0xbfc0583d} },
+/**/ {{0x2b4d3dec, 0x3fa7a379} },
+/**/ {{0xa3290dfe, 0x3fb0e35b} },
+/**/ {{0x19e12287, 0xbfb0a3b2} } },
+/**/ {{{0x00000000, 0x3fd34000} },
+/**/ {{0xfd9b5fe2, 0x3fd2b2f7} },
+/**/ {{0xc1c2d443, 0x3c2423cf} },
+/**/ {{0x88e1caa2, 0x3fed585c} },
+/**/ {{0x01239e18, 0xbc2c8af2} },
+/**/ {{0xab890af7, 0xbfd0303a} },
+/**/ {{0x726290e6, 0x3c7d42bf} },
+/**/ {{0xb5175de0, 0xbfc7f93b} },
+/**/ {{0xe0ddc367, 0x3c5d5d4b} },
+/**/ {{0x3414de7c, 0x3fc8c3a2} },
+/**/ {{0xba92bfce, 0x3c5ade9b} },
+/**/ {{0xda70853d, 0x3f921811} },
+/**/ {{0xcf23aaf0, 0xbfc02df5} },
+/**/ {{0x06445ff8, 0x3fa8acfd} },
+/**/ {{0xc130eba4, 0x3fb04ce4} },
+/**/ {{0x29de3135, 0xbfb0cb04} } },
+/**/ {{{0x00000000, 0x3fd38000} },
+/**/ {{0x7a823cfe, 0x3fd2ed98} },
+/**/ {{0x8ea012ca, 0x3c6b9125} },
+/**/ {{0x6c0fd782, 0x3fed481a} },
+/**/ {{0x85ff74ea, 0x3c82dda4} },
+/**/ {{0x2f5c1e18, 0xbfd053e6} },
+/**/ {{0x8ec637b8, 0xbc679cf2} },
+/**/ {{0xd0ee3e3b, 0xbfc79617} },
+/**/ {{0x732049a6, 0xbc4e91e0} },
+/**/ {{0x67f6478d, 0x3fc8cdff} },
+/**/ {{0xf5079e63, 0xbc5cb659} },
+/**/ {{0x8e8ef686, 0x3f8e271c} },
+/**/ {{0xa2940881, 0xbfc001e5} },
+/**/ {{0xf937caae, 0x3fa9ad0e} },
+/**/ {{0xda1e257f, 0x3faf6a4f} },
+/**/ {{0xb07d42be, 0xbfb0ec24} } },
+/**/ {{{0x00000000, 0x3fd3c000} },
+/**/ {{0x4fb58952, 0x3fd32818} },
+/**/ {{0xa9939f2f, 0xbc7a95f0} },
+/**/ {{0xee1ee130, 0x3fed37b4} },
+/**/ {{0x6fbb1f2d, 0x3c747541} },
+/**/ {{0xe022dd0d, 0xbfd076fc} },
+/**/ {{0x5534523a, 0x3c6d8659} },
+/**/ {{0x3a201d6b, 0xbfc732ce} },
+/**/ {{0xc98a3a62, 0xbc56a551} },
+/**/ {{0x673a29b8, 0x3fc8d67c} },
+/**/ {{0xff95efe6, 0xbc54ae9d} },
+/**/ {{0x74ce6814, 0x3f882eee} },
+/**/ {{0x503ba8f4, 0xbfbfa83b} },
+/**/ {{0x60b63f75, 0x3faaa39c} },
+/**/ {{0xf07ff274, 0x3fae38b8} },
+/**/ {{0x2200fe4d, 0xbfb1072c} } },
+/**/ {{{0x00000000, 0x3fd40000} },
+/**/ {{0x3707ebcc, 0x3fd36277} },
+/**/ {{0x44b672d8, 0xbc6963a5} },
+/**/ {{0xa3fc5b1a, 0x3fed272c} },
+/**/ {{0x272ca3fc, 0x3c8ae01d} },
+/**/ {{0x8aec9d8e, 0xbfd0997e} },
+/**/ {{0x72595f36, 0x3c74aeda} },
+/**/ {{0x66d5c0ff, 0xbfc6cf66} },
+/**/ {{0x3ca66cc1, 0x3c410e2a} },
+/**/ {{0x8f2617b5, 0x3fc8dd1e} },
+/**/ {{0x4facfb67, 0xbc6d173e} },
+/**/ {{0x33966883, 0x3f82483b} },
+/**/ {{0x2b05b16b, 0xbfbf495d} },
+/**/ {{0x074fdeaf, 0x3fab9096} },
+/**/ {{0x9c4605c9, 0x3fad0571} },
+/**/ {{0x280318fd, 0xbfb11c35} } },
+/**/ {{{0x00000000, 0x3fd44000} },
+/**/ {{0xeb76157c, 0x3fd39cb4} },
+/**/ {{0x5a214713, 0xbc72f4da} },
+/**/ {{0x22c31625, 0x3fed1682} },
+/**/ {{0xd5e51b41, 0x3c8ac111} },
+/**/ {{0x07e9a89a, 0xbfd0bb6b} },
+/**/ {{0x7faa1dda, 0x3c76fb53} },
+/**/ {{0xb75f0772, 0xbfc66be7} },
+/**/ {{0xee6d618b, 0xbc69a77d} },
+/**/ {{0x6e943d69, 0x3fc8e1eb} },
+/**/ {{0xc5ec9ebe, 0xbc6982c4} },
+/**/ {{0x9c2d3c0c, 0x3f78e73c} },
+/**/ {{0x7059f387, 0xbfbee752} },
+/**/ {{0x16982f58, 0x3fac73f0} },
+/**/ {{0xc146b407, 0x3fabd0e4} },
+/**/ {{0x82f43254, 0xbfb12b5c} } },
+/**/ {{{0x00000000, 0x3fd48000} },
+/**/ {{0x29271134, 0x3fd3d6d1} },
+/**/ {{0x41cc958a, 0x3c7137ca} },
+/**/ {{0xffb0304c, 0x3fed05b5} },
+/**/ {{0x33e896e5, 0xbc8fc921} },
+/**/ {{0x3a49e254, 0xbfd0dcc2} },
+/**/ {{0x925cb599, 0x3c704578} },
+/**/ {{0x75708502, 0xbfc60859} },
+/**/ {{0x9feebe6c, 0xbc5f88bc} },
+/**/ {{0xc3fb5c1c, 0x3fc8e4e8} },
+/**/ {{0xd6b77a05, 0x3c6de114} },
+/**/ {{0xdbc6c857, 0x3f6ac6b3} },
+/**/ {{0xdeabd793, 0xbfbe823c} },
+/**/ {{0x06fb52a7, 0x3fad4da2} },
+/**/ {{0x2bea698c, 0x3faa9b7b} },
+/**/ {{0xeb32d745, 0xbfb134c0} } },
+/**/ {{{0x00000000, 0x3fd4c000} },
+/**/ {{0xad6c7d33, 0x3fd410cb} },
+/**/ {{0xae13b512, 0xbc7b0c8b} },
+/**/ {{0xd0182625, 0x3fecf4c8} },
+/**/ {{0xf4103798, 0x3c8e6308} },
+/**/ {{0x101a5438, 0xbfd0fd84} },
+/**/ {{0x7d2e3e34, 0x3c425fcd} },
+/**/ {{0xd36904f6, 0xbfc5a4c2} },
+/**/ {{0x54f27bb6, 0x3c5d3583} },
+/**/ {{0x7b74b00c, 0x3fc8e61c} },
+/**/ {{0xefe568b6, 0x3c32f7ad} },
+/**/ {{0xaa3667f2, 0x3f402f60} },
+/**/ {{0x4c9859c0, 0xbfbe1a3e} },
+/**/ {{0x8e77c589, 0x3fae1da6} },
+/**/ {{0x6ed5823e, 0x3fa9659b} },
+/**/ {{0xf1d3d420, 0xbfb13882} } },
+/**/ {{{0x00000000, 0x3fd50000} },
+/**/ {{0x36c2af0a, 0x3fd44aa4} },
+/**/ {{0x3c55b3ba, 0xbc75d5e4} },
+/**/ {{0x295c0773, 0x3fece3bb} },
+/**/ {{0x91851b41, 0xbc826fd5} },
+/**/ {{0x8221a582, 0xbfd11db0} },
+/**/ {{0xa9f31d11, 0x3c7e9654} },
+/**/ {{0xeb9ef661, 0xbfc5412a} },
+/**/ {{0x5e60433c, 0x3c573faf} },
+/**/ {{0xacc06b3a, 0x3fc8e58c} },
+/**/ {{0x64dd81ed, 0xbc5dba9a} },
+/**/ {{0xcfe3f01e, 0xbf625ff7} },
+/**/ {{0x9dae4b1c, 0xbfbdaf78} },
+/**/ {{0x8e4e3e16, 0x3faee3fb} },
+/**/ {{0xc2c60fed, 0x3fa82fa9} },
+/**/ {{0xe13555d9, 0xbfb136c4} } },
+/**/ {{{0x00000000, 0x3fd54000} },
+/**/ {{0x84d0c21b, 0x3fd4845a} },
+/**/ {{0x7563c6a6, 0x3c71e28a} },
+/**/ {{0xa0decfad, 0x3fecd28d} },
+/**/ {{0x49610c12, 0xbc72b2c8} },
+/**/ {{0x93bb8da8, 0xbfd13d47} },
+/**/ {{0x1b48d912, 0x3c5df07a} },
+/**/ {{0xbfb5c8b7, 0xbfc4dd98} },
+/**/ {{0x39a108d7, 0x3c58a9ff} },
+/**/ {{0x99496dc4, 0x3fc8e33f} },
+/**/ {{0x19d3995c, 0x3c380d8b} },
+/**/ {{0xba1bc2d2, 0xbf743d59} },
+/**/ {{0xb77862a1, 0xbfbd420d} },
+/**/ {{0xffb9511c, 0x3fafa0a1} },
+/**/ {{0xe8a86cad, 0x3fa6fa07} },
+/**/ {{0x9d75a109, 0xbfb12faa} } },
+/**/ {{{0x00000000, 0x3fd58000} },
+/**/ {{0x586890e7, 0x3fd4bdee} },
+/**/ {{0x7c22a757, 0xbc6e4dc7} },
+/**/ {{0xcbfae3a7, 0x3fecc140} },
+/**/ {{0xd8b6f9b9, 0xbc41045d} },
+/**/ {{0x52b34cdc, 0xbfd15c49} },
+/**/ {{0x2daa60ac, 0x3c729992} },
+/**/ {{0x37fb39ef, 0xbfc47a13} },
+/**/ {{0x3482d371, 0x3c5cb3b2} },
+/**/ {{0xaa28e022, 0x3fc8df3b} },
+/**/ {{0x969a5447, 0xbc61a8ab} },
+/**/ {{0xc651ecb4, 0xbf7f2135} },
+/**/ {{0x76cc63f7, 0xbfbcd21f} },
+/**/ {{0xefdf4de1, 0x3fb029ce} },
+/**/ {{0x0de3bf96, 0x3fa5c515} },
+/**/ {{0x84e55ab4, 0xbfb12359} } },
+/**/ {{{0x00000000, 0x3fd5c000} },
+/**/ {{0x73869979, 0x3fd4f75f} },
+/**/ {{0xf7ff1108, 0xbc595a1c} },
+/**/ {{0x3ff7b52c, 0x3fecafd5} },
+/**/ {{0x684b6314, 0x3c86e099} },
+/**/ {{0xd71d366e, 0xbfd17ab5} },
+/**/ {{0xae2f7b71, 0x3c602f2c} },
+/**/ {{0x22cc956f, 0xbfc416a1} },
+/**/ {{0xe98c24c1, 0x3c61d29e} },
+/**/ {{0x6e2a4f9f, 0x3fc8d987} },
+/**/ {{0x4a6a7880, 0xbc60de73} },
+/**/ {{0x909e42ec, 0xbf84ed52} },
+/**/ {{0xa56263a8, 0xbfbc5fcf} },
+/**/ {{0x0d159803, 0x3fb07e7b} },
+/**/ {{0xb2ddf20b, 0x3fa4912d} },
+/**/ {{0x508c8585, 0xbfb111f8} } },
+/**/ {{{0x00000000, 0x3fd60000} },
+/**/ {{0x9951cd4a, 0x3fd530ad} },
+/**/ {{0x80884082, 0xbc625664} },
+/**/ {{0x91ff8d87, 0x3fec9e4b} },
+/**/ {{0x1b0da370, 0xbc7723ff} },
+/**/ {{0x432f5908, 0xbfd1988d} },
+/**/ {{0xf8714cda, 0x3c7d065e} },
+/**/ {{0x3403e07c, 0xbfc3b349} },
+/**/ {{0x2717fbb0, 0x3c6b571d} },
+/**/ {{0x97d0e938, 0x3fc8d229} },
+/**/ {{0xb08a0625, 0x3c66b228} },
+/**/ {{0xc2fe9cde, 0xbf8a3464} },
+/**/ {{0xefb6f244, 0xbfbbeb3f} },
+/**/ {{0x39e67c0b, 0x3fb0ce5a} },
+/**/ {{0x93b4fb73, 0x3fa35eab} },
+/**/ {{0xf4d86f78, 0xbfb0fbae} } },
+/**/ {{{0x00000000, 0x3fd64000} },
+/**/ {{0x8e1b4cd8, 0x3fd569d8} },
+/**/ {{0xe713cfe2, 0xbc6fec61} },
+/**/ {{0x57157fc9, 0x3fec8ca4} },
+/**/ {{0x515734ba, 0x3c70da14} },
+/**/ {{0xc3195094, 0xbfd1b5cf} },
+/**/ {{0xa9537e45, 0x3c740cce} },
+/**/ {{0x046cee83, 0xbfc35012} },
+/**/ {{0xe446fd10, 0xbc651b6c} },
+/**/ {{0xfb5e6a95, 0x3fc8c928} },
+/**/ {{0x82469bf3, 0x3c656cd2} },
+/**/ {{0xa4afbb1b, 0xbf8f6568} },
+/**/ {{0xdb3aba50, 0xbfbb7491} },
+/**/ {{0xb9fd56ec, 0x3fb11972} },
+/**/ {{0x9329e15e, 0x3fa22de5} },
+/**/ {{0x8287d93d, 0xbfb0e0a6} } },
+/**/ {{{0x00000000, 0x3fd68000} },
+/**/ {{0x175e0f4e, 0x3fd5a2e0} },
+/**/ {{0x8f82e457, 0x3c713b7a} },
+/**/ {{0x240b83ae, 0x3fec7ae0} },
+/**/ {{0x10d398ed, 0xbc885b56} },
+/**/ {{0x8cdb4db0, 0xbfd1d27d} },
+/**/ {{0x2db0447f, 0x3c11d95f} },
+/**/ {{0x11425541, 0xbfc2ed02} },
+/**/ {{0x6b2cbaa3, 0xbc11d124} },
+/**/ {{0x8cdc5c4d, 0x3fc8be8c} },
+/**/ {{0x794444b0, 0xbc542511} },
+/**/ {{0xd25a5415, 0xbf923ffd} },
+/**/ {{0xbcd1df44, 0xbfbafbe6} },
+/**/ {{0x26bdf05c, 0x3fb15fcc} },
+/**/ {{0xa7b853e6, 0x3fa0ff2f} },
+/**/ {{0x07e9a35f, 0xbfb0c109} } },
+/**/ {{{0x00000000, 0x3fd6c000} },
+/**/ {{0xfbbe768d, 0x3fd5dbc3} },
+/**/ {{0x1b76f7da, 0x3c6ea0ec} },
+/**/ {{0x8d78b9ce, 0x3fec68ff} },
+/**/ {{0x4cb5a0c3, 0xbc83ab41} },
+/**/ {{0xe01c5e6e, 0xbfd1ee96} },
+/**/ {{0xfb76d8dd, 0x3c73922c} },
+/**/ {{0xbbb23677, 0xbfc28a1f} },
+/**/ {{0x288601f2, 0x3c6e592a} },
+/**/ {{0x5e282403, 0x3fc8b25b} },
+/**/ {{0x707e09fa, 0xbbef7d58} },
+/**/ {{0xb65add31, 0xbf94c1e0} },
+/**/ {{0xafa52f1b, 0xbfba815f} },
+/**/ {{0x63712acc, 0x3fb1a16f} },
+/**/ {{0x95a8d3ad, 0x3f9fa5b5} },
+/**/ {{0x72814750, 0xbfb09d01} } },
+/**/ {{{0x00000000, 0x3fd70000} },
+/**/ {{0x0309cfe2, 0x3fd61484} },
+/**/ {{0x15711f00, 0xbc7a7257} },
+/**/ {{0x27afd9eb, 0x3fec5703} },
+/**/ {{0xb32c1d72, 0x3c63c2ab} },
+/**/ {{0x06000419, 0xbfd20a1c} },
+/**/ {{0xf51a3a28, 0xbc7b5fe7} },
+/**/ {{0x486ad2c8, 0xbfc22771} },
+/**/ {{0xf84a7eae, 0xbc499ab5} },
+/**/ {{0x9d027817, 0x3fc8a49c} },
+/**/ {{0x2e376ecc, 0xbc53fcab} },
+/**/ {{0xeaabcb23, 0xbf973831} },
+/**/ {{0x8c46fbce, 0xbfba051d} },
+/**/ {{0x9132e9cc, 0x3fb1de66} },
+/**/ {{0xd48d5d65, 0x3f9d5269} },
+/**/ {{0x712354a4, 0xbfb074bb} } },
+/**/ {{{0x00000000, 0x3fd74000} },
+/**/ {{0xf635c1c6, 0x3fd64d1f} },
+/**/ {{0xe7c0fdbe, 0xbc7fa403} },
+/**/ {{0x86b5cbf8, 0x3fec44eb} },
+/**/ {{0xbc5b562d, 0xbc6a4101} },
+/**/ {{0x50fb21ad, 0xbfd2250d} },
+/**/ {{0xa39bdc1a, 0xbc750066} },
+/**/ {{0xdf2ed728, 0xbfc1c4fc} },
+/**/ {{0x006772e9, 0x3c6a87bb} },
+/**/ {{0x9122b9b7, 0x3fc89557} },
+/**/ {{0x45b04f75, 0xbc05454e} },
+/**/ {{0x6c7888f1, 0xbf99a2c9} },
+/**/ {{0xe02d36ad, 0xbfb98740} },
+/**/ {{0x02a99665, 0x3fb216bd} },
+/**/ {{0xb73aeccb, 0x3f9b0511} },
+/**/ {{0x569b1738, 0xbfb04863} } },
+/**/ {{{0x00000000, 0x3fd78000} },
+/**/ {{0x9f5fa6fe, 0x3fd68597} },
+/**/ {{0x4d1ada9c, 0xbc425781} },
+/**/ {{0x3e386c7f, 0x3fec32b9} },
+/**/ {{0x8cbaa5bf, 0x3c756033} },
+/**/ {{0x1ca84e79, 0xbfd23f6b} },
+/**/ {{0xf123d574, 0x3c604cc0} },
+/**/ {{0x8a715435, 0xbfc162c8} },
+/**/ {{0x454fb8fd, 0x3c5cf6db} },
+/**/ {{0x9a4eb534, 0x3fc88493} },
+/**/ {{0x42b959b0, 0xbc668a5c} },
+/**/ {{0x42580bb5, 0xbf9c0182} },
+/**/ {{0xe5822d56, 0xbfb907e9} },
+/**/ {{0x2f8f8273, 0x3fb24a7f} },
+/**/ {{0xa3527f46, 0x3f98be3c} },
+/**/ {{0xfce97270, 0xbfb01825} } },
+/**/ {{{0x00000000, 0x3fd7c000} },
+/**/ {{0xc9cbd76d, 0x3fd6bdea} },
+/**/ {{0x3e6de828, 0xbc5a5c56} },
+/**/ {{0xe1857d04, 0x3fec206c} },
+/**/ {{0xf5c83872, 0xbc80439f} },
+/**/ {{0xcd9b9870, 0xbfd25935} },
+/**/ {{0xf1ec7306, 0x3c6aaf98} },
+/**/ {{0x36f94d02, 0xbfc100da} },
+/**/ {{0xd96d84ff, 0xbc6e72ca} },
+/**/ {{0x2e774351, 0x3fc87258} },
+/**/ {{0xb8860ef0, 0x3c6c50a2} },
+/**/ {{0x741ef0ec, 0xbf9e543a} },
+/**/ {{0x7b4d0ec2, 0xbfb88738} },
+/**/ {{0xa8164103, 0x3fb279ba} },
+/**/ {{0xa7f1ae35, 0x3f967e73} },
+/**/ {{0x5257c3de, 0xbfafc861} } },
+/**/ {{{0x00000000, 0x3fd80000} },
+/**/ {{0x41e4def1, 0x3fd6f619} },
+/**/ {{0xe6f6e918, 0xbc7c63aa} },
+/**/ {{0x0381c0e0, 0x3fec0e07} },
+/**/ {{0x0381c0e0, 0x3c8c0e07} },
+/**/ {{0xd135c174, 0xbfd2726d} },
+/**/ {{0xe0951cf8, 0xbc2d352d} },
+/**/ {{0xb38cc8cf, 0xbfc09f37} },
+/**/ {{0xae75327f, 0xbc69db81} },
+/**/ {{0xd7da413c, 0x3fc85eac} },
+/**/ {{0x6ebae2bc, 0x3c5b1a89} },
+/**/ {{0x80fcc815, 0xbfa04d69} },
+/**/ {{0x1df326f9, 0xbfb8054c} },
+/**/ {{0x082bda60, 0x3fb2a47e} },
+/**/ {{0x7091d5a4, 0x3f944639} },
+/**/ {{0xe072e48c, 0xbfaf5961} } },
+/**/ {{{0x00000000, 0x3fd84000} },
+/**/ {{0xd53aa2aa, 0x3fd72e22} },
+/**/ {{0x4e79f27c, 0xbc7d9c93} },
+/**/ {{0x36a04729, 0x3febfb88} },
+/**/ {{0x9ac2ea21, 0xbc872745} },
+/**/ {{0x9d7702cf, 0xbfd28b13} },
+/**/ {{0x4be8bff6, 0x3c7819b9} },
+/**/ {{0xb0a35176, 0xbfc03de6} },
+/**/ {{0xc83347af, 0x3c5dbfb0} },
+/**/ {{0x332a4f86, 0x3fc84999} },
+/**/ {{0x0a22d12d, 0x3c5d304e} },
+/**/ {{0xed6b2d30, 0xbfa16a97} },
+/**/ {{0xe0128950, 0xbfb78243} },
+/**/ {{0xeaa98f57, 0x3fb2cad8} },
+/**/ {{0x3bb39c5b, 0x3f92160a} },
+/**/ {{0x3804caa3, 0xbfaee3a9} } },
+/**/ {{{0x00000000, 0x3fd88000} },
+/**/ {{0x52817502, 0x3fd76607} },
+/**/ {{0x91cc7600, 0xbc4dd117} },
+/**/ {{0x0cd9e1fe, 0x3febe8f1} },
+/**/ {{0xa21e102a, 0xbc7a9688} },
+/**/ {{0xb0d161e9, 0xbfd2a327} },
+/**/ {{0x14b44140, 0xbc60a2a9} },
+/**/ {{0x803f8d3b, 0xbfbfb9d9} },
+/**/ {{0x2a5c4097, 0x3c5e5779} },
+/**/ {{0xedbcc363, 0x3fc83324} },
+/**/ {{0xa0442744, 0x3c651fbc} },
+/**/ {{0xe91477c3, 0xbfa2819b} },
+/**/ {{0x63b6abf0, 0xbfb6fe3e} },
+/**/ {{0xdc73a89a, 0x3fb2ecdb} },
+/**/ {{0xaa755298, 0x3f8fdcb7} },
+/**/ {{0x237c2f3d, 0xbfae6793} } },
+/**/ {{{0x00000000, 0x3fd8c000} },
+/**/ {{0x899118d1, 0x3fd79dc6} },
+/**/ {{0xa0ef606d, 0x3c2b7413} },
+/**/ {{0x17a4cbc3, 0x3febd642} },
+/**/ {{0x3200a548, 0xbc55ee5d} },
+/**/ {{0x91faa133, 0xbfd2baaa} },
+/**/ {{0xfaf41548, 0xbc6bd391} },
+/**/ {{0xaa22d832, 0xbfbef89e} },
+/**/ {{0xc874fdb9, 0x3c413b3b} },
+/**/ {{0xc3be300a, 0x3fc81b57} },
+/**/ {{0xc01a615f, 0x3c6baf9b} },
+/**/ {{0x4a872ec7, 0xbfa3926a} },
+/**/ {{0xd3e743cd, 0xbfb67959} },
+/**/ {{0x4f919505, 0x3fb30a98} },
+/**/ {{0x28b78b08, 0x3f8b9f3b} },
+/**/ {{0x71e33e9d, 0xbfade57b} } },
+/**/ {{{0x00000000, 0x3fd90000} },
+/**/ {{0x4b63b3f7, 0x3fd7d560} },
+/**/ {{0x5c2b249a, 0x3c769c88} },
+/**/ {{0xe7ec7a8d, 0x3febc37b} },
+/**/ {{0x2b0e2727, 0xbc6f1246} },
+/**/ {{0xcfbdd7fa, 0xbfd2d19c} },
+/**/ {{0x5e00c582, 0x3c7d0b11} },
+/**/ {{0x86f8309b, 0xbfbe3827} },
+/**/ {{0xfa6c56a7, 0x3c5d64e9} },
+/**/ {{0x7e6de8de, 0x3fc80239} },
+/**/ {{0x7776e849, 0x3c68d62f} },
+/**/ {{0x4f6d8017, 0xbfa49cf9} },
+/**/ {{0xde917e27, 0xbfb5f3b3} },
+/**/ {{0x8e455cc2, 0x3fb32420} },
+/**/ {{0xb9fc88fe, 0x3f877470} },
+/**/ {{0xc6b10536, 0xbfad5dbd} } },
+/**/ {{{0x00000000, 0x3fd94000} },
+/**/ {{0x6a14b1d1, 0x3fd80cd4} },
+/**/ {{0x9684fa19, 0xbc7e79f9} },
+/**/ {{0x0e09a222, 0x3febb09f} },
+/**/ {{0x7e047edd, 0x3c85748e} },
+/**/ {{0x00ccbbc8, 0xbfd2e7ff} },
+/**/ {{0x96875561, 0xbc78eb0a} },
+/**/ {{0x804ecc06, 0xbfbd787e} },
+/**/ {{0x2e4351f8, 0xbc27263b} },
+/**/ {{0xf260d7b4, 0x3fc7e7d1} },
+/**/ {{0x8ed258e3, 0xbc430525} },
+/**/ {{0x968d3d02, 0xbfa5a140} },
+/**/ {{0xaecb845e, 0xbfb56d69} },
+/**/ {{0xae292f95, 0x3fb33987} },
+/**/ {{0x48e09ecd, 0x3f835d1d} },
+/**/ {{0x6b6f9aca, 0xbfacd0b5} } },
+/**/ {{{0x00000000, 0x3fd98000} },
+/**/ {{0xb8df95d7, 0x3fd84422} },
+/**/ {{0x299b41b6, 0x3c7d76a0} },
+/**/ {{0x19ba64d6, 0x3feb9dac} },
+/**/ {{0xa13ee09f, 0xbc4f643a} },
+/**/ {{0xc390a5c9, 0xbfd2fdd1} },
+/**/ {{0xaa856fcc, 0x3c575152} },
+/**/ {{0xc0e99751, 0xbfbcb9ad} },
+/**/ {{0x1347a357, 0x3c4e2d44} },
+/**/ {{0xfdcbfd40, 0x3fc7cc28} },
+/**/ {{0xe516db08, 0x3c60dc32} },
+/**/ {{0x19851d86, 0xbfa69f39} },
+/**/ {{0xe772087d, 0xbfb4e697} },
+/**/ {{0x835992de, 0x3fb34ae1} },
+/**/ {{0xe5326389, 0x3f7eb3f1} },
+/**/ {{0x234575e8, 0xbfac3ebd} } },
+/**/ {{{0x00000000, 0x3fd9c000} },
+/**/ {{0x0c1ebedc, 0x3fd87b4b} },
+/**/ {{0xa2fa470f, 0xbc76dcfa} },
+/**/ {{0x9a1ab378, 0x3feb8aa3} },
+/**/ {{0xb797ab93, 0x3c8efdb0} },
+/**/ {{0xbdfb5e5a, 0xbfd31315} },
+/**/ {{0x862f0c0d, 0x3c5813a8} },
+/**/ {{0x3478f169, 0xbfbbfbbf} },
+/**/ {{0xd9e52582, 0xbc51e810} },
+/**/ {{0x86d6ec76, 0x3fc7af46} },
+/**/ {{0x3c13b159, 0xbc6336de} },
+/**/ {{0x264b8050, 0xbfa796dd} },
+/**/ {{0x9e1f6bef, 0xbfb45f5a} },
+/**/ {{0x93b26fc1, 0x3fb35842} },
+/**/ {{0x39bc3abf, 0x3f76d75e} },
+/**/ {{0x006e38b2, 0xbfaba82f} } },
+/**/ {{{0x00000000, 0x3fda0000} },
+/**/ {{0x394a1b25, 0x3fd8b24d} },
+/**/ {{0xa3748fa8, 0x3c7b6d0b} },
+/**/ {{0x1d9cdc98, 0x3feb7786} },
+/**/ {{0x345bd7a8, 0xbc62e22c} },
+/**/ {{0x9d57b8f5, 0xbfd327cb} },
+/**/ {{0x753cc4f1, 0xbc135343} },
+/**/ {{0x8761b154, 0xbfbb3ebc} },
+/**/ {{0x8c168fdd, 0x3c5abeec} },
+/**/ {{0x79f68c54, 0x3fc79132} },
+/**/ {{0xd8d15eda, 0xbc658ab9} },
+/**/ {{0x5872d73c, 0xbfa88828} },
+/**/ {{0x567be750, 0xbfb3d7cd} },
+/**/ {{0x0a24fc71, 0x3fb361c0} },
+/**/ {{0x46aa98b6, 0x3f6e4b7a} },
+/**/ {{0x3bad3a76, 0xbfab0d64} } },
+/**/ {{{0x00000000, 0x3fda4000} },
+/**/ {{0x16f5cde8, 0x3fd8e929} },
+/**/ {{0xe12bfafb, 0x3c74c0a7} },
+/**/ {{0x32024b37, 0x3feb6454} },
+/**/ {{0x69cc9b53, 0xbc7987f7} },
+/**/ {{0x161a0a40, 0xbfd33bf4} },
+/**/ {{0x83ff46db, 0x3c7a2321} },
+/**/ {{0x26913418, 0xbfba82af} },
+/**/ {{0x10a559fe, 0x3c3c4c62} },
+/**/ {{0xc8506679, 0x3fc771f4} },
+/**/ {{0x63c7ccc3, 0xbc54aaed} },
+/**/ {{0x9237e7ff, 0xbfa97317} },
+/**/ {{0xfde5f112, 0xbfb3500a} },
+/**/ {{0xaa2c3459, 0x3fb3676f} },
+/**/ {{0x04721907, 0x3f5e80cd} },
+/**/ {{0x0dc212a5, 0xbfaa6eb5} } },
+/**/ {{{0x00000000, 0x3fda8000} },
+/**/ {{0x7cd0c662, 0x3fd91fde} },
+/**/ {{0x88054b53, 0x3c710741} },
+/**/ {{0x6454751c, 0x3feb510e} },
+/**/ {{0x7e0f2dca, 0xbc199bfd} },
+/**/ {{0xe3b081f4, 0xbfd34f8f} },
+/**/ {{0x3e2c0515, 0x3c7d7209} },
+/**/ {{0x3f5e2d2f, 0xbfb9c7a0} },
+/**/ {{0xea3bd312, 0xbc20b02e} },
+/**/ {{0x6626c39a, 0x3fc75195} },
+/**/ {{0xb4219a8a, 0x3c6f30d2} },
+/**/ {{0xf55dfea5, 0xbfaa57a8} },
+/**/ {{0xe771fa17, 0xbfb2c82d} },
+/**/ {{0xc3654ab4, 0x3fb36967} },
+/**/ {{0xa23eb6eb, 0x3f11f322} },
+/**/ {{0x8ae579b1, 0xbfa9cc78} } },
+/**/ {{{0x00000000, 0x3fdac000} },
+/**/ {{0x43a34907, 0x3fd9566d} },
+/**/ {{0x37e0af2b, 0x3c69b015} },
+/**/ {{0x40ddf8d3, 0x3feb3db5} },
+/**/ {{0x793c10b8, 0xbc616f46} },
+/**/ {{0xc8537217, 0xbfd3629f} },
+/**/ {{0x38143614, 0x3c505738} },
+/**/ {{0xbf75f20a, 0xbfb90d98} },
+/**/ {{0x6b842647, 0x3c4dc715} },
+/**/ {{0x494dd1e6, 0x3fc7301c} },
+/**/ {{0xf49f85b4, 0x3c5ec3d6} },
+/**/ {{0xdbdd23b1, 0xbfab35db} },
+/**/ {{0xc8407216, 0xbfb2404f} },
+/**/ {{0x255139f9, 0x3fb367bf} },
+/**/ {{0x65acd6da, 0xbf5b8a0d} },
+/**/ {{0x8052f51d, 0xbfa92704} } },
+/**/ {{{0x00000000, 0x3fdb0000} },
+/**/ {{0x454d6b18, 0x3fd98cd5} },
+/**/ {{0x88fd0a77, 0x3c79e6c9} },
+/**/ {{0x5323eb6a, 0x3feb2a49} },
+/**/ {{0x70cc9678, 0xbc572202} },
+/**/ {{0x8cd58cc4, 0xbfd37524} },
+/**/ {{0xda42aa4e, 0x3c6978a3} },
+/**/ {{0x54d5f784, 0xbfb854a1} },
+/**/ {{0xb33b3d0d, 0xbc5e9a15} },
+/**/ {{0x67aa0c46, 0x3fc70d91} },
+/**/ {{0xa4ac9df8, 0xbc6aa72f} },
+/**/ {{0xd0665a46, 0xbfac0db0} },
+/**/ {{0xb428e30d, 0xbfb1b889} },
+/**/ {{0x134448b0, 0x3fb3628d} },
+/**/ {{0x67619c9c, 0xbf6bbbc1} },
+/**/ {{0x53e1f653, 0xbfa87ead} } },
+/**/ {{{0x00000000, 0x3fdb4000} },
+/**/ {{0x5cc58107, 0x3fd9c316} },
+/**/ {{0x02250cfb, 0x3c4b6696} },
+/**/ {{0x25df55f4, 0x3feb16cb} },
+/**/ {{0xf48e26bc, 0xbc653abc} },
+/**/ {{0x00742189, 0xbfd3871f} },
+/**/ {{0xc05df451, 0xbc725ae2} },
+/**/ {{0x6dd13675, 0xbfb79cc2} },
+/**/ {{0x991905e4, 0x3be1d4e0} },
+/**/ {{0xb5b8147e, 0x3fc6e9fc} },
+/**/ {{0xa57d4eca, 0x3c46463b} },
+/**/ {{0x86c1db89, 0xbfacdf29} },
+/**/ {{0x1ab8d1c4, 0xbfb130f4} },
+/**/ {{0x38881228, 0x3fb359e9} },
+/**/ {{0x53bec2ff, 0xbf74a987} },
+/**/ {{0xe5af58b6, 0xbfa7d3c5} } },
+/**/ {{{0x00000000, 0x3fdb8000} },
+/**/ {{0x66168002, 0x3fd9f930} },
+/**/ {{0x47c9439a, 0xbc7c8270} },
+/**/ {{0x42f6e2c9, 0x3feb033b} },
+/**/ {{0xc48702a7, 0xbc6eb80c} },
+/**/ {{0xf8a76337, 0xbfd3988f} },
+/**/ {{0x5b1bb38a, 0xbc636968} },
+/**/ {{0x39212b04, 0xbfb6e604} },
+/**/ {{0xba255e71, 0xbc3c2e20} },
+/**/ {{0x251e2d41, 0x3fc6c566} },
+/**/ {{0x47236369, 0x3c230ab3} },
+/**/ {{0xd40b3417, 0xbfadaa48} },
+/**/ {{0xc484f2cc, 0xbfb0a9a6} },
+/**/ {{0x9cb4573e, 0x3fb34deb} },
+/**/ {{0x1def6f17, 0xbf7b44ca} },
+/**/ {{0x73d683b8, 0xbfa7269f} } },
+/**/ {{{0x00000000, 0x3fdbc000} },
+/**/ {{0x3e5e530b, 0x3fda2f23} },
+/**/ {{0xf797086b, 0x3c5814d5} },
+/**/ {{0x3378ba79, 0x3feaef9a} },
+/**/ {{0x4476e241, 0x3c7da16a} },
+/**/ {{0x50f2beab, 0xbfd3a978} },
+/**/ {{0xad5a31ea, 0x3c7b7e7f} },
+/**/ {{0xa602212f, 0xbfb6306e} },
+/**/ {{0x9ec38d55, 0xbc31ec15} },
+/**/ {{0xa3477c6a, 0x3fc69fd5} },
+/**/ {{0xb2996038, 0x3c571f2f} },
+/**/ {{0xa6cf162d, 0xbfae6f12} },
+/**/ {{0xd0cb2655, 0xbfb022b8} },
+/**/ {{0x9842912f, 0x3fb33eac} },
+/**/ {{0x4919e78d, 0xbf80d789} },
+/**/ {{0x8037e242, 0xbfa67789} } },
+/**/ {{{0x00000000, 0x3fdc0000} },
+/**/ {{0xc3cc23fd, 0x3fda64ee} },
+/**/ {{0x1b50b7ff, 0xbc724dec} },
+/**/ {{0x7f94905e, 0x3feadbe8} },
+/**/ {{0x7f94905e, 0x3c2adbe8} },
+/**/ {{0xeab54af9, 0xbfd3b9d8} },
+/**/ {{0x54fd0941, 0x3c75b97d} },
+/**/ {{0x645a7f9e, 0xbfb57c09} },
+/**/ {{0x09320811, 0xbc5e79f6} },
+/**/ {{0x180938f2, 0x3fc67953} },
+/**/ {{0xe7aee726, 0x3c6246f2} },
+/**/ {{0xff0ea012, 0xbfaf2d8b} },
+/**/ {{0x66c7250c, 0xbfaf3881} },
+/**/ {{0xc95ff694, 0x3fb32c44} },
+/**/ {{0x25d7ff49, 0xbf83f3f0} },
+/**/ {{0xb848e1d1, 0xbfa5c6d1} } },
+/**/ {{{0x00000000, 0x3fdc4000} },
+/**/ {{0xd59e98cf, 0x3fda9a92} },
+/**/ {{0xff75d817, 0x3c42e42d} },
+/**/ {{0xae95dea9, 0x3feac826} },
+/**/ {{0x633dec57, 0xbc534eec} },
+/**/ {{0xacfa5b18, 0xbfd3c9b2} },
+/**/ {{0x6c4d8d27, 0x3c7a7e0c} },
+/**/ {{0xe4ecc0f6, 0xbfb4c8db} },
+/**/ {{0xc0c32772, 0xbc534990} },
+/**/ {{0x6451e377, 0x3fc651e6} },
+/**/ {{0x2a9bb1f1, 0xbc6ea814} },
+/**/ {{0xe62bc1b2, 0xbfafe5ba} },
+/**/ {{0x65fe3642, 0xbfae2ca8} },
+/**/ {{0x09015968, 0x3fb316cd} },
+/**/ {{0x3ce97a26, 0xbf86f764} },
+/**/ {{0xdee8421b, 0xbfa514c3} } },
+/**/ {{{0x00000000, 0x3fdc8000} },
+/**/ {{0x5422058b, 0x3fdad00f} },
+/**/ {{0x3891d2e8, 0x3c7fc4c3} },
+/**/ {{0x46de51cf, 0x3feab455} },
+/**/ {{0xdbc38cc9, 0xbc5b834a} },
+/**/ {{0x844a38eb, 0xbfd3d906} },
+/**/ {{0xbc44eee8, 0x3c6198e5} },
+/**/ {{0x5993cade, 0xbfb416ed} },
+/**/ {{0xfa289b6c, 0xbc235ccb} },
+/**/ {{0x60e2a3af, 0x3fc62997} },
+/**/ {{0xcf7bda0e, 0xbc69a660} },
+/**/ {{0x33612b72, 0xbfb04bd3} },
+/**/ {{0xcf62bcd9, 0xbfad2210} },
+/**/ {{0x603bfc37, 0x3fb2fe5e} },
+/**/ {{0xa9bce7ec, 0xbf89e1ba} },
+/**/ {{0xb83029d5, 0xbfa461a9} } },
+/**/ {{{0x00000000, 0x3fdcc000} },
+/**/ {{0x20ae9344, 0x3fdb0564} },
+/**/ {{0x46363455, 0xbc793139} },
+/**/ {{0xcde0631f, 0x3feaa074} },
+/**/ {{0x143fe6d4, 0x3c84b49a} },
+/**/ {{0x627b115b, 0xbfd3e7d5} },
+/**/ {{0x332989c0, 0x3c77a502} },
+/**/ {{0xb589513f, 0xbfb36644} },
+/**/ {{0x105eec96, 0x3c3abdc9} },
+/**/ {{0xdd12e0be, 0x3fc6006d} },
+/**/ {{0x5d67cb35, 0xbc4f0281} },
+/**/ {{0x4238ba83, 0xbfb0a1ab} },
+/**/ {{0x73889526, 0xbfac18e3} },
+/**/ {{0xfde6351a, 0x3fb2e311} },
+/**/ {{0xc256833f, 0xbf8cb2d2} },
+/**/ {{0xf73e36f0, 0xbfa3adca} } },
+/**/ {{{0x00000000, 0x3fdd0000} },
+/**/ {{0x1da65c6c, 0x3fdb3a91} },
+/**/ {{0xb1ca5040, 0x3c7ae187} },
+/**/ {{0xc81a2254, 0x3fea8c85} },
+/**/ {{0x8d67728b, 0xbc83c191} },
+/**/ {{0x3e8218e0, 0xbfd3f620} },
+/**/ {{0x52bd43ef, 0xbc72bf32} },
+/**/ {{0xadb5f398, 0xbfb2b6e8} },
+/**/ {{0x6b74d451, 0x3c340287} },
+/**/ {{0x9d9e25fc, 0x3fc5d671} },
+/**/ {{0x518d7a71, 0x3c639669} },
+/**/ {{0x19cc29a0, 0xbfb0f46a} },
+/**/ {{0xc1a69750, 0xbfab1147} },
+/**/ {{0x2c826e6b, 0x3fb2c501} },
+/**/ {{0xcbc1b186, 0xbf8f6a95} },
+/**/ {{0x2de89811, 0xbfa2f96d} } },
+/**/ {{{0x00000000, 0x3fdd4000} },
+/**/ {{0x2e737efc, 0x3fdb6f96} },
+/**/ {{0x64981e71, 0xbc5ca534} },
+/**/ {{0xb9102ddc, 0x3fea7888} },
+/**/ {{0x3c46d7d5, 0xbc7791b2} },
+/**/ {{0x1444efb5, 0xbfd403e8} },
+/**/ {{0x4f3d22a6, 0xbc6047c5} },
+/**/ {{0xb90ac1cc, 0xbfb208df} },
+/**/ {{0x2d2115d8, 0x3c4078b1} },
+/**/ {{0x5b7c61a2, 0x3fc5abaa} },
+/**/ {{0x2bd2d19a, 0x3c3eef6a} },
+/**/ {{0xa8850e1a, 0xbfb14414} },
+/**/ {{0xc6580343, 0xbfaa0b63} },
+/**/ {{0x4876cfdf, 0x3fb2a445} },
+/**/ {{0x562d0829, 0xbf91047b} },
+/**/ {{0xbe562a83, 0xbfa244d3} } },
+/**/ {{{0x00000000, 0x3fdd8000} },
+/**/ {{0x378624a5, 0x3fdba473} },
+/**/ {{0xb46e4aff, 0x3c7519a1} },
+/**/ {{0x2348d9a3, 0x3fea647e} },
+/**/ {{0x9156e59f, 0xbc84f6c2} },
+/**/ {{0xe46b4c91, 0xbfd4112d} },
+/**/ {{0x110fe0b7, 0xbc78c11d} },
+/**/ {{0x10e3d572, 0xbfb15c30} },
+/**/ {{0x4427c00b, 0x3c53b45b} },
+/**/ {{0xc2c486ae, 0x3fc5801f} },
+/**/ {{0xc20ced8b, 0xbc49bb5e} },
+/**/ {{0x4cddef65, 0xbfb190b0} },
+/**/ {{0x2ae4bcd0, 0xbfa9075c} },
+/**/ {{0xb69396b9, 0x3fb280f7} },
+/**/ {{0xce179ccb, 0xbf9246f8} },
+/**/ {{0xce6e9b2b, 0xbfa1903f} } },
+/**/ {{{0x00000000, 0x3fddc000} },
+/**/ {{0x1e528192, 0x3fdbd928} },
+/**/ {{0x39af6b66, 0xbc74b154} },
+/**/ {{0x88478403, 0x3fea5066} },
+/**/ {{0xbe71620f, 0xbc85c7e8} },
+/**/ {{0xb430f4ac, 0xbfd41df2} },
+/**/ {{0xe79c7595, 0xbc55db82} },
+/**/ {{0xb173ac76, 0xbfb0b0df} },
+/**/ {{0xe4738d25, 0x3c57f440} },
+/**/ {{0x7199976b, 0x3fc553d9} },
+/**/ {{0x2a872a12, 0x3c54990c} },
+/**/ {{0xd137dd01, 0xbfb1da42} },
+/**/ {{0x350bfdb5, 0xbfa80554} },
+/**/ {{0xdae9e17f, 0x3fb25b31} },
+/**/ {{0xe9e265b4, 0xbf937cc5} },
+/**/ {{0x3d16a202, 0xbfa0dbf0} } },
+/**/ {{{0x00000000, 0x3fde0000} },
+/**/ {{0xc94ec9f0, 0x3fdc0db4} },
+/**/ {{0x70934c34, 0xbc7cc1ce} },
+/**/ {{0x68881898, 0x3fea3c42} },
+/**/ {{0xe5c3bd97, 0x3c8f907f} },
+/**/ {{0x8d38076d, 0xbfd42a37} },
+/**/ {{0x7e19d62d, 0xbc6b8354} },
+/**/ {{0x5a36f1bd, 0xbfb006f4} },
+/**/ {{0xca398c09, 0xbc41701e} },
+/**/ {{0xf7221a2a, 0x3fc526de} },
+/**/ {{0x8041247e, 0xbc211868} },
+/**/ {{0x67b0229a, 0xbfb220d2} },
+/**/ {{0xc74d0c66, 0xbfa7056d} },
+/**/ {{0x0ff472e2, 0x3fb2330d} },
+/**/ {{0x9cb74216, 0xbf94a5e9} },
+/**/ {{0x992b9e1f, 0xbfa02821} } },
+/**/ {{{0x00000000, 0x3fde4000} },
+/**/ {{0x1ff11eb7, 0x3fdc4219} },
+/**/ {{0x434b3eee, 0xbc7b17df} },
+/**/ {{0x437ac09e, 0x3fea2812} },
+/**/ {{0xf9618c21, 0xbc540368} },
+/**/ {{0x7d5ba406, 0xbfd435fd} },
+/**/ {{0x5e0a732a, 0x3c75605b} },
+/**/ {{0x1ce0c104, 0xbfaebce7} },
+/**/ {{0xd4eb3297, 0xbc446d02} },
+/**/ {{0xd289f60b, 0x3fc4f937} },
+/**/ {{0xe736fa8b, 0x3c5b88b7} },
+/**/ {{0xa5f78db4, 0xbfb26465} },
+/**/ {{0x61a972db, 0xbfa607c9} },
+/**/ {{0x9e13b088, 0x3fb208a2} },
+/**/ {{0x06c33653, 0xbf95c26f} },
+/**/ {{0x346237b1, 0xbf9eea1c} } },
+/**/ {{{0x00000000, 0x3fde8000} },
+/**/ {{0x0aad71f9, 0x3fdc7655} },
+/**/ {{0xff7043e4, 0xbc774b8b} },
+/**/ {{0x977fc070, 0x3fea13d6} },
+/**/ {{0xd9440881, 0xbc86c451} },
+/**/ {{0x9682eee2, 0xbfd44145} },
+/**/ {{0xb13901b4, 0x3c74156f} },
+/**/ {{0x2b58de73, 0xbfad6ec5} },
+/**/ {{0xdf653988, 0x3c2ced26} },
+/**/ {{0x720eb232, 0x3fc4caeb} },
+/**/ {{0x92f3f809, 0x3c614246} },
+/**/ {{0x812caa81, 0xbfb2a503} },
+/**/ {{0x22dc20a7, 0xbfa50c86} },
+/**/ {{0xb35de59d, 0x3fb1dc0b} },
+/**/ {{0x4adc8c38, 0xbf96d265} },
+/**/ {{0x35444e0c, 0xbf9d85db} } },
+/**/ {{{0x00000000, 0x3fdec000} },
+/**/ {{0x72f3631b, 0x3fdcaa68} },
+/**/ {{0x81636f48, 0x3c295067} },
+/**/ {{0xe1e381db, 0x3fe9ff8f} },
+/**/ {{0x00701e1c, 0xbc6fffe6} },
+/**/ {{0xee747cac, 0xbfd44c10} },
+/**/ {{0xced401ad, 0xbc7a7f22} },
+/**/ {{0xf898de26, 0xbfac238c} },
+/**/ {{0xdaa7d32f, 0x3c1eb191} },
+/**/ {{0x32160e42, 0x3fc49c01} },
+/**/ {{0x03d0023c, 0x3c649f02} },
+/**/ {{0x49ba4fb7, 0xbfb2e2b3} },
+/**/ {{0xca00d6c7, 0xbfa413c1} },
+/**/ {{0x5bc495cf, 0x3fb1ad61} },
+/**/ {{0x63d0ff69, 0xbf97d5df} },
+/**/ {{0x27af7010, 0xbf9c23eb} } },
+/**/ {{{0x00000000, 0x3fdf0000} },
+/**/ {{0x432c1351, 0x3fdcde53} },
+/**/ {{0x4418f1ad, 0xbc7a2cfa} },
+/**/ {{0x9edacacc, 0x3fe9eb3e} },
+/**/ {{0x87d23ca5, 0xbc8942c5} },
+/**/ {{0x9eaa285d, 0xbfd45660} },
+/**/ {{0x52cf85b4, 0x3c4fe8e6} },
+/**/ {{0x28319af3, 0xbfaadb48} },
+/**/ {{0x31b456b0, 0xbc207b46} },
+/**/ {{0x5c4ee7c2, 0x3fc46c80} },
+/**/ {{0xb4443c76, 0x3c4bdfc1} },
+/**/ {{0xa73bc33f, 0xbfb31d7c} },
+/**/ {{0xb8a731f5, 0xbfa31d98} },
+/**/ {{0x798f7481, 0x3fb17cbc} },
+/**/ {{0xf977e9ca, 0xbf98ccf3} },
+/**/ {{0x36ea1578, 0xbf9ac4b2} } },
+/**/ {{{0x00000000, 0x3fdf4000} },
+/**/ {{0x66b7f2ad, 0x3fdd1215} },
+/**/ {{0x35886c30, 0x3c7be678} },
+/**/ {{0x497f1fed, 0x3fe9d6e3} },
+/**/ {{0x9a35c454, 0xbc8ec056} },
+/**/ {{0xc4255988, 0xbfd46035} },
+/**/ {{0x7144427c, 0x3c7ddb7b} },
+/**/ {{0xe9b44acd, 0xbfa995ff} },
+/**/ {{0xb529cf65, 0x3c3c9d56} },
+/**/ {{0x26dc5cda, 0x3fc43c70} },
+/**/ {{0xfde6cd82, 0x3c6d6ee6} },
+/**/ {{0x9467b39a, 0xbfb35567} },
+/**/ {{0xf54ca1ba, 0xbfa22a25} },
+/**/ {{0xbe2d5d2d, 0x3fb14a35} },
+/**/ {{0x35a34e74, 0xbf99b7bd} },
+/**/ {{0xc4948489, 0xbf996891} } },
+/**/ {{{0x00000000, 0x3fdf8000} },
+/**/ {{0xc9ec862b, 0x3fdd45ae} },
+/**/ {{0x163ef92d, 0x3c689421} },
+/**/ {{0x5bcb52c7, 0x3fe9c27e} },
+/**/ {{0xf148a350, 0xbc892d91} },
+/**/ {{0x7f43bff0, 0xbfd46991} },
+/**/ {{0x8da13c27, 0xbc738b23} },
+/**/ {{0xf9f19dcd, 0xbfa853bc} },
+/**/ {{0x2433c5cf, 0x3c2ea7a9} },
+/**/ {{0xb38b19e0, 0x3fc40bd7} },
+/**/ {{0x1c2a2863, 0xbc5d466e} },
+/**/ {{0x5b0333a7, 0xbfb38a7c} },
+/**/ {{0x2e3896d7, 0xbfa13983} },
+/**/ {{0xa35b7545, 0x3fb115e5} },
+/**/ {{0x99098556, 0xbf9a9658} },
+/**/ {{0x693ac59e, 0xbf980fe6} } },
+/**/ {{{0x00000000, 0x3fdfc000} },
+/**/ {{0x5a1226f5, 0x3fdd791f} },
+/**/ {{0xa5b64a76, 0xbc64017e} },
+/**/ {{0x4e983ae9, 0x3fe9ae10} },
+/**/ {{0x52b783d7, 0xbc8d45ed} },
+/**/ {{0xf394891f, 0xbfd47274} },
+/**/ {{0x22e08713, 0xbc7cd478} },
+/**/ {{0xa445379d, 0xbfa71487} },
+/**/ {{0x831d87b7, 0x3c1569aa} },
+/**/ {{0x0f10bc36, 0x3fc3dabe} },
+/**/ {{0x1cb9bbe6, 0x3bd8df2b} },
+/**/ {{0x8fddd862, 0xbfb3bcc3} },
+/**/ {{0xbcb632d9, 0xbfa04bc8} },
+/**/ {{0x64a26d77, 0x3fb0dfe4} },
+/**/ {{0xd04027d1, 0xbf9b68e6} },
+/**/ {{0xf792c5d9, 0xbf96bb07} } },
+/**/ {{{0x00000000, 0x3fe00000} },
+/**/ {{0x0561bb4f, 0x3fddac67} },
+/**/ {{0x222f65e2, 0x3c7a2b7f} },
+/**/ {{0x9999999a, 0x3fe99999} },
+/**/ {{0x9999999a, 0xbc899999} },
+/**/ {{0x47ae147b, 0xbfd47ae1} },
+/**/ {{0xeb851eb8, 0x3c5eb851} },
+/**/ {{0xc3ece2a5, 0xbfa5d867} },
+/**/ {{0xd7b900af, 0xbc3a485c} },
+/**/ {{0x30553261, 0x3fc3a92a} },
+/**/ {{0x94467382, 0x3c6f06f6} },
+/**/ {{0x0ed80a18, 0xbfb3ec46} },
+/**/ {{0x514d88d8, 0xbf9ec21b} },
+/**/ {{0xf929a833, 0x3fb0a849} },
+/**/ {{0x88dfb80c, 0xbf9c2f8b} },
+/**/ {{0x8245bf09, 0xbf956a49} } },
+/**/ {{{0x00000000, 0x3fe02000} },
+/**/ {{0xbb026974, 0x3fdddf85} },
+/**/ {{0x0c0a1226, 0x3c643bbb} },
+/**/ {{0xb35b2797, 0x3fe9851a} },
+/**/ {{0x18a8fead, 0x3c89cd14} },
+/**/ {{0xa5042a2d, 0xbfd482d7} },
+/**/ {{0xa8224d16, 0x3c0dbc04} },
+/**/ {{0xc56ade02, 0xbfa49f64} },
+/**/ {{0x47da7eea, 0x3c451e52} },
+/**/ {{0xf7c5fe7d, 0x3fc37722} },
+/**/ {{0xd22c4b5c, 0xbc5165be} },
+/**/ {{0xf6f48c5d, 0xbfb4190c} },
+/**/ {{0x58d0c132, 0xbf9cf2cf} },
+/**/ {{0x0ddfdd74, 0x3fb06f2e} },
+/**/ {{0x46e65336, 0xbf9cea6d} },
+/**/ {{0x6423af3b, 0xbf941df9} } },
+/**/ {{{0x00000000, 0x3fe04000} },
+/**/ {{0x6b0744b0, 0x3fde127b} },
+/**/ {{0x6398d4ab, 0xbc52b098} },
+/**/ {{0x113dcc5a, 0x3fe97094} },
+/**/ {{0x4de8c575, 0xbc842780} },
+/**/ {{0x37beb8e5, 0xbfd48a59} },
+/**/ {{0x9dc7541e, 0xbc601dd2} },
+/**/ {{0xa7f2a8fe, 0xbfa36985} },
+/**/ {{0x7437d42d, 0xbc45e414} },
+/**/ {{0x2eb33dd6, 0x3fc344af} },
+/**/ {{0xe3a3193c, 0xbc6d66e9} },
+/**/ {{0xa6763232, 0xbfb44321} },
+/**/ {{0x7217dfc9, 0xbf9b29d6} },
+/**/ {{0xfff8a866, 0x3fb034a7} },
+/**/ {{0x3a6e931d, 0xbf9d99b5} },
+/**/ {{0x4a9f7e19, 0xbf92d661} } },
+/**/ {{{0x00000000, 0x3fe06000} },
+/**/ {{0x066cf51a, 0x3fde4548} },
+/**/ {{0x12ce98f2, 0x3c43a3aa} },
+/**/ {{0x2774fe53, 0x3fe95c06} },
+/**/ {{0x3b851412, 0x3c810dfd} },
+/**/ {{0x2e911e43, 0xbfd49167} },
+/**/ {{0x09466fcd, 0xbc7f6506} },
+/**/ {{0xfedfb0c1, 0xbfa236d0} },
+/**/ {{0x79cb63a9, 0xbc3f6870} },
+/**/ {{0x86b6561c, 0x3fc311d5} },
+/**/ {{0x9543fc9a, 0x3c561982} },
+/**/ {{0xb70aa5a7, 0xbfb46a8d} },
+/**/ {{0xf5ac1efc, 0xbf996756} },
+/**/ {{0xaf7c84b3, 0x3faff19d} },
+/**/ {{0x15ce96b8, 0xbf9e3d8f} },
+/**/ {{0x42726021, 0xbf9193c6} } },
+/**/ {{{0x00000000, 0x3fe08000} },
+/**/ {{0x7f175a34, 0x3fde77eb} },
+/**/ {{0xc1bf3435, 0x3c70e53d} },
+/**/ {{0x69044ba4, 0x3fe94771} },
+/**/ {{0x92d5fbc1, 0xbc7d53e2} },
+/**/ {{0xba91fd89, 0xbfd49802} },
+/**/ {{0xc3c8c4f3, 0x3c71963e} },
+/**/ {{0xf33546d5, 0xbfa1074c} },
+/**/ {{0xc71ad288, 0x3c4bc296} },
+/**/ {{0x99222665, 0x3fc2de9c} },
+/**/ {{0x28dadb64, 0x3c6e4a10} },
+/**/ {{0xfa031cb1, 0xbfb48f5a} },
+/**/ {{0xbc0c6420, 0xbf97ab74} },
+/**/ {{0x876d0f75, 0x3faf7772} },
+/**/ {{0xe431fc96, 0xbf9ed628} },
+/**/ {{0xc64515ec, 0xbf905668} } },
+/**/ {{{0x00000000, 0x3fe0a000} },
+/**/ {{0xc7cf28c4, 0x3fdeaa65} },
+/**/ {{0xeca3bf05, 0x3c62fb2c} },
+/**/ {{0x47bd0aaa, 0x3fe932d6} },
+/**/ {{0x697b6e3c, 0x3c6bdfec} },
+/**/ {{0x0f13a7e8, 0xbfd49e2d} },
+/**/ {{0x20412940, 0x3c6198c5} },
+/**/ {{0x8a4e92df, 0xbf9fb5fe} },
+/**/ {{0x6309a51a, 0xbc3cbb58} },
+/**/ {{0xe67c9829, 0x3fc2ab0a} },
+/**/ {{0x06a4c4ef, 0xbc647643} },
+/**/ {{0x749bc711, 0xbfb4b193} },
+/**/ {{0x27bef265, 0xbf95f651} },
+/**/ {{0x28347ebf, 0x3faefafb} },
+/**/ {{0xe0c06e2f, 0xbf9f63b2} },
+/**/ {{0x9e7b9dd7, 0xbf8e3d09} } },
+/**/ {{{0x00000000, 0x3fe0c000} },
+/**/ {{0xd43f8435, 0x3fdedcb6} },
+/**/ {{0x330884e4, 0xbc5fc976} },
+/**/ {{0x343c31e5, 0x3fe91e35} },
+/**/ {{0x9bb96799, 0xbc8fd46f} },
+/**/ {{0x617d19a1, 0xbfd4a3e7} },
+/**/ {{0xea58b250, 0xbc7d7303} },
+/**/ {{0x9b55d156, 0xbf9d63da} },
+/**/ {{0xd5b4cc6c, 0xbc14bf72} },
+/**/ {{0xd6016a7c, 0x3fc27726} },
+/**/ {{0x435ec4b4, 0x3c4eba22} },
+/**/ {{0x5c52b3c6, 0xbfb4d141} },
+/**/ {{0x2fdd9fbd, 0xbf94480b} },
+/**/ {{0x6d3af4b6, 0x3fae7c63} },
+/**/ {{0x4e61315b, 0xbf9fe65f} },
+/**/ {{0xcea37283, 0xbf8bd8a3} } },
+/**/ {{{0x00000000, 0x3fe0e000} },
+/**/ {{0x98f393d0, 0x3fdf0ede} },
+/**/ {{0x87cb1894, 0xbc72f40a} },
+/**/ {{0x9de85688, 0x3fe9098e} },
+/**/ {{0xa3791e64, 0xbc7c2de1} },
+/**/ {{0xe9238ed7, 0xbfd4a932} },
+/**/ {{0x28864386, 0xbc67a1bb} },
+/**/ {{0x001dec68, 0xbf9b1838} },
+/**/ {{0x8f0ffbdd, 0xbc33ee0e} },
+/**/ {{0xb52e1005, 0x3fc242f6} },
+/**/ {{0x371fd2c1, 0xbc5476eb} },
+/**/ {{0x134edf2d, 0xbfb4ee6f} },
+/**/ {{0x6b13becc, 0xbf92a0bf} },
+/**/ {{0x650f859c, 0x3fadfbd6} },
+/**/ {{0x281586f4, 0xbfa02f31} },
+/**/ {{0x7a73449e, 0xbf898006} } },
+/**/ {{{0x00000000, 0x3fe10000} },
+/**/ {{0x0b541418, 0x3fdf40dd} },
+/**/ {{0xdc382a23, 0xbc6a3992} },
+/**/ {{0xf2efd135, 0x3fe8f4e2} },
+/**/ {{0xd4218911, 0xbc74c3c0} },
+/**/ {{0xdf24b2d1, 0xbfd4ae10} },
+/**/ {{0x79d0ac37, 0x3c713b12} },
+/**/ {{0xd7365f3f, 0xbf98d31f} },
+/**/ {{0x62531dc5, 0xbc18bf3b} },
+/**/ {{0xb7567664, 0x3fc20e80} },
+/**/ {{0xd450197f, 0xbc54a699} },
+/**/ {{0x24d80ddd, 0xbfb50927} },
+/**/ {{0x1b0516ab, 0xbf910088} },
+/**/ {{0x4a356567, 0x3fad797e} },
+/**/ {{0xe14758ed, 0xbfa065f8} },
+/**/ {{0x73d2f6bb, 0xbf87338f} } },
+/**/ {{{0x00000000, 0x3fe12000} },
+/**/ {{0x21a4e495, 0x3fdf72b2} },
+/**/ {{0x0f7eb740, 0x3c5489c2} },
+/**/ {{0xa0470831, 0x3fe8e032} },
+/**/ {{0xe75570cd, 0xbc8c154a} },
+/**/ {{0x7e416c35, 0xbfd4b282} },
+/**/ {{0x60646afd, 0xbc7f1837} },
+/**/ {{0x7a6bec27, 0xbf96949a} },
+/**/ {{0xe6b77ba9, 0x3c38238f} },
+/**/ {{0xf5428c61, 0x3fc1d9ca} },
+/**/ {{0xcd7881aa, 0x3c6a968d} },
+/**/ {{0x41e00b6e, 0xbfb52174} },
+/**/ {{0x702ad3de, 0xbf8ecefa} },
+/**/ {{0x7c8ae0dc, 0x3facf584} },
+/**/ {{0x8aa44fa8, 0xbfa097a2} },
+/**/ {{0x2ed63408, 0xbf84f394} } },
+/**/ {{{0x00000000, 0x3fe14000} },
+/**/ {{0xd3029259, 0x3fdfa45d} },
+/**/ {{0xdc28d8b5, 0xbc7ca563} },
+/**/ {{0x11a6de80, 0x3fe8cb7e} },
+/**/ {{0xac22b8f8, 0x3c610be6} },
+/**/ {{0x02b9488a, 0xbfd4b689} },
+/**/ {{0xaf91d442, 0x3c5ea0bd} },
+/**/ {{0x821fd17e, 0xbf945caf} },
+/**/ {{0x0e51a049, 0x3c38e464} },
+/**/ {{0x6cd45aad, 0x3fc1a4db} },
+/**/ {{0xf4200d5e, 0x3c2288e0} },
+/**/ {{0x3d9dd7c4, 0xbfb53761} },
+/**/ {{0xfb107457, 0xbf8bab68} },
+/**/ {{0x7b46ebd1, 0x3fac7011} },
+/**/ {{0x93134a8f, 0xbfa0c44a} },
+/**/ {{0xf1fa4589, 0xbf82c061} } },
+/**/ {{{0x00000000, 0x3fe16000} },
+/**/ {{0x175fdf83, 0x3fdfd5e0} },
+/**/ {{0x1ec49b15, 0x3c63a87b} },
+/**/ {{0xb18b4749, 0x3fe8b6c5} },
+/**/ {{0xb7d58c0a, 0xbc5fabb8} },
+/**/ {{0xaa26890c, 0xbfd4ba25} },
+/**/ {{0x0ef9b688, 0x3c50e395} },
+/**/ {{0xc8a9b4c0, 0xbf922b65} },
+/**/ {{0xd319146f, 0x3c2835ee} },
+/**/ {{0x00b681bd, 0x3fc16fb8} },
+/**/ {{0x279133b0, 0x3c1df633} },
+/**/ {{0x0a3b410c, 0xbfb54af9} },
+/**/ {{0xebe14682, 0xbf889682} },
+/**/ {{0xdf89e086, 0x3fabe94c} },
+/**/ {{0x0e55a6f8, 0xbfa0ec0e} },
+/**/ {{0x08af68f3, 0xbf809a3e} } },
+/**/ {{{0x00000000, 0x3fe18000} },
+/**/ {{0x73c1a40c, 0x3fe0039c} },
+/**/ {{0x49c9d593, 0xbc8b32c9} },
+/**/ {{0xe931fcd3, 0x3fe8a209} },
+/**/ {{0x8e68c94c, 0x3c6cb8f0} },
+/**/ {{0xb35ad2d8, 0xbfd4bd59} },
+/**/ {{0xcaa606b4, 0xbc61ac1a} },
+/**/ {{0x6dc339ef, 0xbf9000c3} },
+/**/ {{0xaeaeaa73, 0x3c2c62e2} },
+/**/ {{0x7812ee2d, 0x3fc13a66} },
+/**/ {{0x948ffe5b, 0x3c6a8cc2} },
+/**/ {{0xb5955c9c, 0xbfb55c46} },
+/**/ {{0x0fd2b503, 0xbf85906b} },
+/**/ {{0x577de2da, 0x3fab615d} },
+/**/ {{0xa34d31ec, 0xbfa10f0a} },
+/**/ {{0xefe48ad0, 0xbf7d02cb} } },
+/**/ {{{0x00000000, 0x3fe1a000} },
+/**/ {{0x1e82422d, 0x3fe01c34} },
+/**/ {{0xfcca90ee, 0x3c83db44} },
+/**/ {{0x20995a88, 0x3fe88d4b} },
+/**/ {{0x1e42e681, 0x3c802777} },
+/**/ {{0x5e3c840f, 0xbfd4c026} },
+/**/ {{0x3800420d, 0x3c7d7c65} },
+/**/ {{0xb3f88703, 0xbf8bb99b} },
+/**/ {{0x4bf63e82, 0x3c1f62ec} },
+/**/ {{0x7e5193ee, 0x3fc104ec} },
+/**/ {{0xbae4e07d, 0xbc27771e} },
+/**/ {{0x66104515, 0xbfb56b55} },
+/**/ {{0x061a20d1, 0xbf829940} },
+/**/ {{0xa20334d9, 0x3faad868} },
+/**/ {{0x7aba8ee6, 0xbfa12d5e} },
+/**/ {{0x69774b8d, 0xbf78ec1f} } },
+/**/ {{{0x00000000, 0x3fe1c000} },
+/**/ {{0x09250488, 0x3fe034b7} },
+/**/ {{0x8d855410, 0x3c78f9b3} },
+/**/ {{0xbe7f594b, 0x3fe87889} },
+/**/ {{0xc826e7a3, 0xbc7530e1} },
+/**/ {{0xeba4af80, 0xbfd4c28c} },
+/**/ {{0xe6a95faa, 0x3c7104a9} },
+/**/ {{0x846dba10, 0xbf877f13} },
+/**/ {{0x4abd0010, 0x3c2bc924} },
+/**/ {{0xa2deff9f, 0x3fc0cf4f} },
+/**/ {{0xa013c015, 0xbc67d17e} },
+/**/ {{0x577e7899, 0xbfb57830} },
+/**/ {{0xb49ea16d, 0xbf7f6238} },
+/**/ {{0x8ae4a926, 0x3faa4e93} },
+/**/ {{0x2e77f633, 0xbfa14728} },
+/**/ {{0xb81c893e, 0xbf74f0d3} } },
+/**/ {{{0x00000000, 0x3fe1e000} },
+/**/ {{0x314342e6, 0x3fe04d25} },
+/**/ {{0x6442c767, 0xbc81c863} },
+/**/ {{0x2860ad7e, 0x3fe863c6} },
+/**/ {{0x137a2d8f, 0xbc81dcb2} },
+/**/ {{0x9d3dc03a, 0xbfd4c48e} },
+/**/ {{0x197b1db9, 0xbc7d92af} },
+/**/ {{0x5653b1a7, 0xbf8351f6} },
+/**/ {{0x2127dea7, 0xbbe368b4} },
+/**/ {{0x58fa8ca4, 0x3fc09995} },
+/**/ {{0x530429e5, 0xbc446391} },
+/**/ {{0xd81c26eb, 0xbfb582e2} },
+/**/ {{0x3e63c109, 0xbf79b02d} },
+/**/ {{0xe7904294, 0x3fa9c401} },
+/**/ {{0xb933b0f3, 0xbfa15c86} },
+/**/ {{0xd8d860e1, 0xbf711137} } },
+/**/ {{{0x00000000, 0x3fe20000} },
+/**/ {{0x94db30d0, 0x3fe0657e} },
+/**/ {{0x5f6349e6, 0xbc7d5b49} },
+/**/ {{0xc2780614, 0x3fe84f00} },
+/**/ {{0xff3d87fa, 0xbc7fe7b0} },
+/**/ {{0xb562c625, 0xbfd4c62c} },
+/**/ {{0xa78e848c, 0x3c77b2c3} },
+/**/ {{0xb3a4bcb7, 0xbf7e6495} },
+/**/ {{0xe3f2b0a5, 0x3c14eb89} },
+/**/ {{0xf78c0dc4, 0x3fc063c2} },
+/**/ {{0x7539dc13, 0xbc6badf0} },
+/**/ {{0x459eb443, 0xbfb58b78} },
+/**/ {{0x1386e6b4, 0xbf741c83} },
+/**/ {{0x944ff706, 0x3fa938d6} },
+/**/ {{0x66ad4037, 0xbfa16d99} },
+/**/ {{0x01fc736a, 0xbf6a9b1a} } },
+/**/ {{{0x00000000, 0x3fe22000} },
+/**/ {{0x324e9b38, 0x3fe07dc3} },
+/**/ {{0xe04450ac, 0x3c7b70c9} },
+/**/ {{0xefbd6bfe, 0x3fe83a39} },
+/**/ {{0x21f5de26, 0xbc7b2885} },
+/**/ {{0x76ff6c9e, 0xbfd4c768} },
+/**/ {{0xdebc1603, 0x3c56a2c0} },
+/**/ {{0xd9cccfd7, 0xbf76402c} },
+/**/ {{0x4e9786c1, 0xbc1b39c0} },
+/**/ {{0xb900b57a, 0x3fc02ddd} },
+/**/ {{0xea88a215, 0x3c45d916} },
+/**/ {{0x0a58ab40, 0xbfb591fc} },
+/**/ {{0x32a37ac9, 0xbf6d4eb0} },
+/**/ {{0x71fe75f8, 0x3fa8ad33} },
+/**/ {{0xc477a855, 0xbfa17a7f} },
+/**/ {{0x2b035011, 0xbf634c0e} } },
+/**/ {{{0x00000000, 0x3fe24000} },
+/**/ {{0x0861a590, 0x3fe095f3} },
+/**/ {{0x0a15a9f3, 0xbc7121b2} },
+/**/ {{0x11e5c14d, 0x3fe82572} },
+/**/ {{0xacd80b09, 0xbc7df9fc} },
+/**/ {{0x25709bff, 0xbfd4c843} },
+/**/ {{0x1790f484, 0x3c7a9ef6} },
+/**/ {{0x8a0def34, 0xbf6c6d74} },
+/**/ {{0x2a8142d7, 0xbc051e57} },
+/**/ {{0x765e156b, 0x3fbfefd5} },
+/**/ {{0xf0e29c9e, 0xbc3e6048} },
+/**/ {{0x9a724e28, 0xbfb59679} },
+/**/ {{0xcf13e192, 0xbf62a185} },
+/**/ {{0x6433c13f, 0x3fa82139} },
+/**/ {{0x9342e95d, 0xbfa18359} },
+/**/ {{0x8f974107, 0xbf586b34} } },
+/**/ {{{0x00000000, 0x3fe26000} },
+/**/ {{0x1639866c, 0x3fe0ae0e} },
+/**/ {{0xf2de445a, 0x3c7075ab} },
+/**/ {{0x89625f5d, 0x3fe810a9} },
+/**/ {{0x0fcf7262, 0xbc8e4bea} },
+/**/ {{0x0465c69b, 0xbfd4c8be} },
+/**/ {{0xd7f7f89c, 0x3c462ef4} },
+/**/ {{0x4de612d5, 0xbf59210e} },
+/**/ {{0xba53898d, 0xbbf43659} },
+/**/ {{0xfe836c69, 0x3fbf83dd} },
+/**/ {{0x27f5499a, 0xbc36cb56} },
+/**/ {{0x7136edda, 0xbfb598fc} },
+/**/ {{0x00013fb7, 0xbf50634c} },
+/**/ {{0x4fe557c2, 0x3fa79508} },
+/**/ {{0xb8ae41dc, 0xbfa18846} },
+/**/ {{0xe36bd239, 0xbf455fce} } },
+/**/ {{{0x00000000, 0x3fe28000} },
+/**/ {{0x5b5b43da, 0x3fe0c614} },
+/**/ {{0x13b5404f, 0x3c5974fa} },
+/**/ {{0xb560d35c, 0x3fe7fbe0} },
+/**/ {{0xae5a0887, 0xbc84f066} },
+/**/ {{0x57c2e1cb, 0xbfd4c8da} },
+/**/ {{0xe0a3774c, 0x3c73de0e} },
+/**/ {{0x61c69f3c, 0x3f38b341} },
+/**/ {{0x7b200371, 0x3bd7b2e2} },
+/**/ {{0xd351e8ed, 0x3fbf17de} },
+/**/ {{0x650c5a9c, 0x3c5bce38} },
+/**/ {{0x0e77234c, 0xbfb59990} },
+/**/ {{0x99f594ee, 0x3f3006ef} },
+/**/ {{0x1a75a6cc, 0x3fa708bf} },
+/**/ {{0x31a471d5, 0xbfa18967} },
+/**/ {{0x59bf0521, 0x3f24cc7e} } },
+/**/ {{{0x00000000, 0x3fe2a000} },
+/**/ {{0xd7aa6f7d, 0x3fe0de05} },
+/**/ {{0xb1c529ab, 0xbc783684} },
+/**/ {{0xf3cab884, 0x3fe7e717} },
+/**/ {{0x3b1fa4c7, 0x3c7e1b21} },
+/**/ {{0x63830b4b, 0xbfd4c899} },
+/**/ {{0xae3ffeff, 0xbc7b6e32} },
+/**/ {{0xfc06cc4f, 0x3f628757} },
+/**/ {{0x56f01f66, 0xbbb4c155} },
+/**/ {{0x8424efd8, 0x3fbeabe1} },
+/**/ {{0x6e5604ea, 0x3bdf5129} },
+/**/ {{0xf3ffff64, 0xbfb5983f} },
+/**/ {{0x1f564189, 0x3f57ec04} },
+/**/ {{0xa92e6e68, 0x3fa67c7b} },
+/**/ {{0x0542d0ff, 0xbfa186db} },
+/**/ {{0x11a37bde, 0x3f4ee247} } },
+/**/ {{{0x00000000, 0x3fe2c000} },
+/**/ {{0x8b67e295, 0x3fe0f5e2} },
+/**/ {{0x7ec990d0, 0x3be311b1} },
+/**/ {{0xa145af59, 0x3fe7d24f} },
+/**/ {{0xabdb623b, 0xbc83c6d1} },
+/**/ {{0x6b9bdb30, 0xbfd4c7fc} },
+/**/ {{0xd3bbb84b, 0x3c7c2fae} },
+/**/ {{0xc729b366, 0x3f70e125} },
+/**/ {{0x7a19993c, 0x3c1291fb} },
+/**/ {{0x66cf0dd8, 0x3fbe3fef} },
+/**/ {{0xcd5e7640, 0xbc5428b7} },
+/**/ {{0xa3273c21, 0xbfb59517} },
+/**/ {{0x36891acb, 0x3f65adcf} },
+/**/ {{0xe121c017, 0x3fa5f05a} },
+/**/ {{0x384bad65, 0xbfa180c2} },
+/**/ {{0xd31e02a7, 0x3f5bd6f1} } },
+/**/ {{{0x00000000, 0x3fe2e000} },
+/**/ {{0x77307a0d, 0x3fe10daa} },
+/**/ {{0xd44c7b05, 0x3c869c33} },
+/**/ {{0x19337139, 0x3fe7bd88} },
+/**/ {{0x00e777ef, 0xbc7fd248} },
+/**/ {{0xb3e16264, 0xbfd4c704} },
+/**/ {{0xd46ed4e3, 0xbc7ed720} },
+/**/ {{0x62c1daf7, 0x3f7863a5} },
+/**/ {{0x30cc82d1, 0x3c155e73} },
+/**/ {{0x97a241da, 0x3fbdd411} },
+/**/ {{0x9ac44edd, 0x3c27a15a} },
+/**/ {{0x9a6c71a6, 0xbfb59022} },
+/**/ {{0xb5534ebe, 0x3f6f285a} },
+/**/ {{0xa76d3cf7, 0x3fa56478} },
+/**/ {{0xc1240db6, 0xbfa1773c} },
+/**/ {{0x3891a70c, 0x3f63e5a1} } },
+/**/ {{{0x00000000, 0x3fe30000} },
+/**/ {{0x9bfbd2a9, 0x3fe1255d} },
+/**/ {{0xe1c0ee35, 0xbc52bdae} },
+/**/ {{0xb5b1ffa1, 0x3fe7a8c1} },
+/**/ {{0x4e005ea3, 0x3c873e4a} },
+/**/ {{0x7fead5b8, 0xbfd4c5b3} },
+/**/ {{0x55abc25a, 0x3c77958e} },
+/**/ {{0x01e4c970, 0x3f7fcb31} },
+/**/ {{0xc5337fda, 0xbc1ad968} },
+/**/ {{0xf983ecf1, 0x3fbd6850} },
+/**/ {{0x02ed6910, 0xbc3e45e6} },
+/**/ {{0x532f49b6, 0xbfb5896c} },
+/**/ {{0xeaefcf7f, 0x3f7432e2} },
+/**/ {{0xe1db38f0, 0x3fa4d8ef} },
+/**/ {{0x7c5c9def, 0xbfa16a6a} },
+/**/ {{0x7b6fe5d0, 0x3f69a742} } },
+/**/ {{{0x00000000, 0x3fe32000} },
+/**/ {{0xfb1b056e, 0x3fe13cfb} },
+/**/ {{0x6fc3ed38, 0x3c83110e} },
+/**/ {{0xcf9bee6c, 0x3fe793fc} },
+/**/ {{0xd8d91b6c, 0xbc8dc7d2} },
+/**/ {{0x12f7e51f, 0xbfd4c40a} },
+/**/ {{0x0d5d686d, 0x3c7d1e10} },
+/**/ {{0x839d28fa, 0x3f838be8} },
+/**/ {{0x52131640, 0x3c13427a} },
+/**/ {{0x360bfed5, 0x3fbcfcb6} },
+/**/ {{0xa36f599f, 0xbc5e3cb4} },
+/**/ {{0x3f7aa463, 0xbfb58100} },
+/**/ {{0xb76f2bc0, 0x3f78b31e} },
+/**/ {{0x77dd6b80, 0x3fa44dda} },
+/**/ {{0x21c53ca9, 0xbfa15a6b} },
+/**/ {{0x6cd99ed4, 0x3f6f30a7} } },
+/**/ {{{0x00000000, 0x3fe34000} },
+/**/ {{0x9637646a, 0x3fe15485} },
+/**/ {{0x548bf3c3, 0xbc84ba7c} },
+/**/ {{0xbe88c85e, 0x3fe77f39} },
+/**/ {{0x9b6750c8, 0xbc6a983f} },
+/**/ {{0xafd6bee5, 0xbfd4c209} },
+/**/ {{0x5e73e93a, 0x3c7d21ef} },
+/**/ {{0xfc556ca7, 0x3f8724c7} },
+/**/ {{0x42e5673e, 0xbc23cef2} },
+/**/ {{0xbdaef67d, 0x3fbc9149} },
+/**/ {{0x3f04fcdc, 0xbc1e549c} },
+/**/ {{0xc7e4996a, 0xbfb576e9} },
+/**/ {{0xba6ceedb, 0x3f7d14fc} },
+/**/ {{0x53dcdc4a, 0x3fa3c351} },
+/**/ {{0x3a0a53a1, 0xbfa1475e} },
+/**/ {{0x62102619, 0x3f724116} } },
+/**/ {{{0x00000000, 0x3fe36000} },
+/**/ {{0x6f5137e1, 0x3fe16bfa} },
+/**/ {{0xe141bd35, 0x3c79606f} },
+/**/ {{0xd8cd8d65, 0x3fe76a78} },
+/**/ {{0xddf1f71f, 0x3c854a99} },
+/**/ {{0x98cabe40, 0xbfd4bfb3} },
+/**/ {{0x9ef99598, 0xbc61e24d} },
+/**/ {{0x388e6864, 0x3f8ab03d} },
+/**/ {{0xc340d113, 0x3c210541} },
+/**/ {{0xc7f24ec4, 0x3fbc2613} },
+/**/ {{0x0a59af31, 0x3c54042a} },
+/**/ {{0x49833ac1, 0xbfb56b34} },
+/**/ {{0x22f6cd28, 0x3f80ac4f} },
+/**/ {{0x64dac153, 0x3fa3396c} },
+/**/ {{0x14dadf32, 0xbfa13163} },
+/**/ {{0x21aeee27, 0x3f74ce20} } },
+/**/ {{{0x00000000, 0x3fe38000} },
+/**/ {{0x88be7c13, 0x3fe1835a} },
+/**/ {{0xec00c301, 0x3c8c621c} },
+/**/ {{0x737d49ca, 0x3fe755ba} },
+/**/ {{0xd4cb44c6, 0xbc8abaf3} },
+/**/ {{0x0f73c4b3, 0xbfd4bd09} },
+/**/ {{0xa9936e0b, 0x3c3e9ebf} },
+/**/ {{0x8920477f, 0x3f8e2e4f} },
+/**/ {{0x0360e009, 0xbc0889e3} },
+/**/ {{0x53aaefa0, 0x3fbbbb1c} },
+/**/ {{0xa1007b7f, 0xbc5edb26} },
+/**/ {{0x13f5f619, 0xbfb55deb} },
+/**/ {{0xe675741e, 0x3f82bf14} },
+/**/ {{0xa05e0ebf, 0x3fa2b042} },
+/**/ {{0xbf95c5c1, 0xbfa11898} },
+/**/ {{0xe421ee51, 0x3f773faf} } },
+/**/ {{{0x00000000, 0x3fe3a000} },
+/**/ {{0xe5299f9a, 0x3fe19aa5} },
+/**/ {{0x2c58f835, 0xbc8a606c} },
+/**/ {{0xe269c5b3, 0x3fe740fe} },
+/**/ {{0x4c82509c, 0x3c873eff} },
+/**/ {{0x54b63d79, 0xbfd4ba0b} },
+/**/ {{0x75bceeff, 0xbc51d68a} },
+/**/ {{0x9d9b3eb0, 0x3f90cf83} },
+/**/ {{0x68a7ca2f, 0xbc107399} },
+/**/ {{0x27453d35, 0x3fbb506b} },
+/**/ {{0x00bdfedd, 0x3c326b36} },
+/**/ {{0x67836cef, 0xbfb54f19} },
+/**/ {{0x567ed6e8, 0x3f84c2e5} },
+/**/ {{0x04a983e8, 0x3fa227ea} },
+/**/ {{0xfc7ce22f, 0xbfa0fd1d} },
+/**/ {{0x2ffea71d, 0x3f79960c} } },
+/**/ {{{0x00000000, 0x3fe3c000} },
+/**/ {{0x87904285, 0x3fe1b1dc} },
+/**/ {{0x8aef8f29, 0xbc621e8c} },
+/**/ {{0x78244c5a, 0x3fe72c46} },
+/**/ {{0xe664f3a2, 0x3c888c36} },
+/**/ {{0xa8a3ca2f, 0xbfd4b6bb} },
+/**/ {{0x1e1f3e19, 0xbc778793} },
+/**/ {{0xc8a3d8bb, 0x3f928136} },
+/**/ {{0x140daf1c, 0x3c3dc4d8} },
+/**/ {{0xd1165ef3, 0x3fbae607} },
+/**/ {{0x6305876c, 0xbc5fbfaa} },
+/**/ {{0x734b94bd, 0xbfb53eca} },
+/**/ {{0x7c458eb1, 0x3f86b7d8} },
+/**/ {{0x9b360f57, 0x3fa1a077} },
+/**/ {{0x3a6beabd, 0xbfa0df11} },
+/**/ {{0xaf42dc87, 0x3f7bd182} } },
+/**/ {{{0x00000000, 0x3fe3e000} },
+/**/ {{0x7341f64f, 0x3fe1c8fe} },
+/**/ {{0x9d5e792a, 0x3c728bbc} },
+/**/ {{0x85fe8a32, 0x3fe71791} },
+/**/ {{0xe8bbb0d0, 0x3c8f15bd} },
+/**/ {{0x4a6497be, 0xbfd4b31b} },
+/**/ {{0x782968f7, 0x3c737223} },
+/**/ {{0x5e0c3122, 0x3f942c46} },
+/**/ {{0x86422b13, 0xbc33e26a} },
+/**/ {{0xa7b659b8, 0x3fba7bf9} },
+/**/ {{0x25381986, 0xbc3cdf63} },
+/**/ {{0x538deb45, 0xbfb52d09} },
+/**/ {{0xa0c1f425, 0x3f889e08} },
+/**/ {{0x7b6d72e6, 0x3fa119ff} },
+/**/ {{0x8d11287b, 0xbfa0be90} },
+/**/ {{0xbce83ad4, 0x3f7df267} } },
+/**/ {{{0x00000000, 0x3fe40000} },
+/**/ {{0xabdefeb4, 0x3fe1e00b} },
+/**/ {{0x287a668f, 0xbc5928df} },
+/**/ {{0x5c0b8170, 0x3fe702e0} },
+/**/ {{0x5c0b8170, 0x3c7702e0} },
+/**/ {{0x78215a76, 0xbfd4af2b} },
+/**/ {{0xab3a13d8, 0xbc581c2e} },
+/**/ {{0xe9e4a9d0, 0x3f95d0b7} },
+/**/ {{0xebf91fc7, 0xbc3aa02a} },
+/**/ {{0xca629942, 0x3fba1247} },
+/**/ {{0xc245db83, 0xbc46961a} },
+/**/ {{0x100385b4, 0xbfb519e1} },
+/**/ {{0x32616ed8, 0x3f8a7592} },
+/**/ {{0xcda1223a, 0x3fa09494} },
+/**/ {{0xa5a5c251, 0xbfa09bb9} },
+/**/ {{0xf489d8ba, 0x3f7ff915} } },
+/**/ {{{0x00000000, 0x3fe42000} },
+/**/ {{0x3557138a, 0x3fe1f704} },
+/**/ {{0xf6d7dd47, 0x3c76c659} },
+/**/ {{0x4920943e, 0x3fe6ee33} },
+/**/ {{0x61a3a541, 0xbc62723e} },
+/**/ {{0x6eedf042, 0xbfd4aaed} },
+/**/ {{0xe7561ed4, 0x3c5b337a} },
+/**/ {{0x68796803, 0x3f976e91} },
+/**/ {{0x44d1db93, 0xbc0e806f} },
+/**/ {{0x21688625, 0x3fb9a8f9} },
+/**/ {{0xb1ec0554, 0x3c540185} },
+/**/ {{0x9a4cbc61, 0xbfb5055c} },
+/**/ {{0xab0be204, 0x3f8c3e93} },
+/**/ {{0xce3968a1, 0x3fa01049} },
+/**/ {{0xcc2331ba, 0xbfa076a9} },
+/**/ {{0xe220db7e, 0x3f80f2f6} } },
+/**/ {{{0x00000000, 0x3fe44000} },
+/**/ {{0x13e823b2, 0x3fe20de8} },
+/**/ {{0x53ebb744, 0xbc8791d7} },
+/**/ {{0x9ad6a3fd, 0x3fe6d98a} },
+/**/ {{0xc4e69862, 0xbc808110} },
+/**/ {{0x6ab4a79d, 0xbfd4a662} },
+/**/ {{0x9fc1cc2b, 0x3c52ed25} },
+/**/ {{0x42e6dc28, 0x3f9905d9} },
+/**/ {{0xe39b7707, 0xbc228c79} },
+/**/ {{0x5e97c6f4, 0x3fb94014} },
+/**/ {{0xf8779202, 0xbc52b822} },
+/**/ {{0xcc723054, 0xbfb4ef86} },
+/**/ {{0x76852811, 0x3f8df92d} },
+/**/ {{0xa231ee3f, 0x3f9f1a5f} },
+/**/ {{0xd8f34e77, 0xbfa04f7d} },
+/**/ {{0x80706a34, 0x3f81dcaa} } },
+/**/ {{{0x00000000, 0x3fe46000} },
+/**/ {{0x4c1d192a, 0x3fe224b7} },
+/**/ {{0xf88a60c4, 0x3c8d6d3d} },
+/**/ {{0x9d8b44ec, 0x3fe6c4e6} },
+/**/ {{0x4ed04ec2, 0xbc589d5c} },
+/**/ {{0xa6222a08, 0xbfd4a18b} },
+/**/ {{0xd3867dbd, 0xbc66c919} },
+/**/ {{0x4bb5a8a0, 0x3f9a9696} },
+/**/ {{0x927bb5bd, 0x3c36698e} },
+/**/ {{0xfdbbcc76, 0x3fb8d79f} },
+/**/ {{0x4efb71a1, 0x3c2578bd} },
+/**/ {{0x6778e363, 0xbfb4d86a} },
+/**/ {{0xd930230d, 0x3f8fa581} },
+/**/ {{0x8a6221aa, 0x3f9e16ae} },
+/**/ {{0x2f183972, 0xbfa02652} },
+/**/ {{0x3e507f4f, 0x3f82b9db} } },
+/**/ {{{0x00000000, 0x3fe48000} },
+/**/ {{0xe2cc9e6a, 0x3fe23b71} },
+/**/ {{0x9f38224e, 0x3c6c421c} },
+/**/ {{0x9c620595, 0x3fe6b047} },
+/**/ {{0x07d7f0c2, 0x3c8867df} },
+/**/ {{0x5a920887, 0xbfd49c6a} },
+/**/ {{0x37bcc433, 0xbc764547} },
+/**/ {{0xbb7e5931, 0x3f9c20cf} },
+/**/ {{0x4db6bef2, 0xbc3d86f5} },
+/**/ {{0x451c4a5d, 0x3fb86fa2} },
+/**/ {{0x15afb52c, 0xbc475142} },
+/**/ {{0x120917da, 0xbfb4c012} },
+/**/ {{0x6b9c3fad, 0x3f90a1da} },
+/**/ {{0x708543e5, 0x3f9d159f} },
+/**/ {{0x6d929bce, 0xbf9ff685} },
+/**/ {{0xd0361a66, 0x3f838ac0} } },
+/**/ {{{0x00000000, 0x3fe4a000} },
+/**/ {{0xdd17e501, 0x3fe25217} },
+/**/ {{0x8c1b679c, 0x3c856aa8} },
+/**/ {{0xe145c95d, 0x3fe69bad} },
+/**/ {{0x5605046d, 0xbc873257} },
+/**/ {{0xbffbe8a8, 0xbfd496ff} },
+/**/ {{0xc7b45e6f, 0x3c36a5c5} },
+/**/ {{0x2d9556eb, 0x3f9da48d} },
+/**/ {{0x1871a19d, 0x3c3ff0e8} },
+/**/ {{0x46043f42, 0x3fb80821} },
+/**/ {{0xe660cfa1, 0x3c550eec} },
+/**/ {{0x5727a8cb, 0xbfb4a688} },
+/**/ {{0x0e13efbc, 0x3f9169f6} },
+/**/ {{0xb59149dd, 0x3f9c174f} },
+/**/ {{0xb10444dd, 0xbf9f9cd5} },
+/**/ {{0x03e91dd9, 0x3f844f95} } },
+/**/ {{{0x00000000, 0x3fe4c000} },
+/**/ {{0x40696da6, 0x3fe268a9} },
+/**/ {{0xa04c73cc, 0x3c5d1348} },
+/**/ {{0xb4ea3592, 0x3fe68719} },
+/**/ {{0x088ed284, 0xbc7ecf86} },
+/**/ {{0x0ce1507d, 0xbfd4914d} },
+/**/ {{0x4dff2946, 0xbc6410ef} },
+/**/ {{0x9cbf7eb7, 0x3f9f21d6} },
+/**/ {{0xeaaad7e2, 0x3c39bc22} },
+/**/ {{0xdd4f3070, 0x3fb7a122} },
+/**/ {{0x1cfe44af, 0x3c50d950} },
+/**/ {{0xa50188df, 0xbfb48bd7} },
+/**/ {{0x71756204, 0x3f922b27} },
+/**/ {{0x0810a33a, 0x3f9b1bdb} },
+/**/ {{0xf1011313, 0xbf9f3fca} },
+/**/ {{0x8fe0f49b, 0x3f850893} } },
+/**/ {{{0x00000000, 0x3fe4e000} },
+/**/ {{0x1273d1b3, 0x3fe27f26} },
+/**/ {{0x6151dd9f, 0x3c843bf3} },
+/**/ {{0x5ecd3069, 0x3fe6728b} },
+/**/ {{0x539f23ff, 0x3c67417b} },
+/**/ {{0x763c0fe8, 0xbfd48b53} },
+/**/ {{0x6027975c, 0xbc677a1a} },
+/**/ {{0x2ff7dd6a, 0x3fa04c5a} },
+/**/ {{0x496202e8, 0xbc40808e} },
+/**/ {{0xb3fc3f7c, 0x3fb73aac} },
+/**/ {{0x86b114ff, 0x3c4b58cb} },
+/**/ {{0x4bc91249, 0xbfb4700a} },
+/**/ {{0xef2490f8, 0x3f92e582} },
+/**/ {{0x6c875580, 0x3f9a235b} },
+/**/ {{0xe55cd596, 0xbf9edf99} },
+/**/ {{0xe40c5a18, 0x3f85b5f9} } },
+/**/ {{{0x00000000, 0x3fe50000} },
+/**/ {{0x59308e31, 0x3fe2958e} },
+/**/ {{0xb0c6c087, 0xbc709e73} },
+/**/ {{0x2538713c, 0x3fe65e03} },
+/**/ {{0x42c09163, 0xbc601392} },
+/**/ {{0x2f6d4575, 0xbfd48514} },
+/**/ {{0x4568af3f, 0xbc356341} },
+/**/ {{0x9386fd1d, 0x3fa10497} },
+/**/ {{0x230a452f, 0xbc4a756a} },
+/**/ {{0x3fc6c180, 0x3fb6d4c4} },
+/**/ {{0xdb3fe137, 0x3c5ab2b9} },
+/**/ {{0x7ca4cfd0, 0xbfb4532a} },
+/**/ {{0x90eb1d30, 0x3f93991d} },
+/**/ {{0x46163051, 0x3f992de9} },
+/**/ {{0x2de874ff, 0xbf9e7c76} },
+/**/ {{0xfc0c1cb2, 0x3f865806} } },
+/**/ {{{0x00000000, 0x3fe52000} },
+/**/ {{0x1aded073, 0x3fe2abe2} },
+/**/ {{0x01ad022e, 0x3c8c28c0} },
+/**/ {{0x4d432177, 0x3fe64981} },
+/**/ {{0x055e240c, 0x3c83f41b} },
+/**/ {{0x6a2cfd01, 0xbfd47e90} },
+/**/ {{0xf152d080, 0x3c628585} },
+/**/ {{0xfbe3ed9e, 0x3fa1b9a7} },
+/**/ {{0xf259fe04, 0xbc18a085} },
+/**/ {{0xc3c40175, 0x3fb66f6e} },
+/**/ {{0xb0fda762, 0x3c41d80a} },
+/**/ {{0x48af643a, 0xbfb43542} },
+/**/ {{0x05ad7652, 0x3f94460d} },
+/**/ {{0x5f55ab26, 0x3f983b9b} },
+/**/ {{0x4be18b23, 0xbf9e1692} },
+/**/ {{0x32e755a3, 0x3f86eefb} } },
+/**/ {{{0x00000000, 0x3fe54000} },
+/**/ {{0x5e024466, 0x3fe2c221} },
+/**/ {{0xda3a4be1, 0xbc44b810} },
+/**/ {{0x1ad38da0, 0x3fe63506} },
+/**/ {{0x94ec14b0, 0xbc67f12a} },
+/**/ {{0x567a6652, 0xbfd477c9} },
+/**/ {{0xbbb9df88, 0x3c7be71c} },
+/**/ {{0x1535acb9, 0x3fa26b90} },
+/**/ {{0xff041454, 0xbc30ff6c} },
+/**/ {{0x5105d8fa, 0x3fb60ab1} },
+/**/ {{0x3f2d6492, 0x3c535a89} },
+/**/ {{0xa0083319, 0xbfb4165b} },
+/**/ {{0x965eb0a7, 0x3f94ec67} },
+/**/ {{0xf36231e5, 0x3f974c86} },
+/**/ {{0x9c25f4a4, 0xbf9dae1f} },
+/**/ {{0x183e42dc, 0x3f877b18} } },
+/**/ {{{0x00000000, 0x3fe56000} },
+/**/ {{0x2961e48c, 0x3fe2d84c} },
+/**/ {{0x0a36e506, 0xbc7f2542} },
+/**/ {{0xd0a0e5d4, 0x3fe62091} },
+/**/ {{0xcccb008e, 0x3c82a27d} },
+/**/ {{0x228ca1b6, 0xbfd470c0} },
+/**/ {{0x32884415, 0xbc788e9b} },
+/**/ {{0xb365e4d9, 0x3fa31a54} },
+/**/ {{0xda0f99ae, 0x3c3e6e70} },
+/**/ {{0xc741ccb7, 0x3fb5a690} },
+/**/ {{0x6508ffe1, 0xbc383905} },
+/**/ {{0x50f46c17, 0xbfb3f680} },
+/**/ {{0x1b344c30, 0x3f958c44} },
+/**/ {{0xb713db8a, 0x3f9660bf} },
+/**/ {{0x5224992a, 0xbf9d434e} },
+/**/ {{0x46ffb16e, 0x3f87fca0} } },
+/**/ {{{0x00000000, 0x3fe58000} },
+/**/ {{0x8406cbca, 0x3fe2ee62} },
+/**/ {{0x9ff0cf8d, 0x3c8c5d5e} },
+/**/ {{0xb0350d38, 0x3fe60c24} },
+/**/ {{0xf3db4fcb, 0x3c81ffe9} },
+/**/ {{0xfac420bd, 0xbfd46975} },
+/**/ {{0x850528a0, 0x3c7e6994} },
+/**/ {{0xd098b4ee, 0x3fa3c5fa} },
+/**/ {{0xaa6a6874, 0x3c353c41} },
+/**/ {{0xd57c5b53, 0x3fb54311} },
+/**/ {{0x72d146e0, 0x3c50d02e} },
+/**/ {{0x071017e0, 0xbfb3d5ba} },
+/**/ {{0xf11b08a7, 0x3f9625b9} },
+/**/ {{0xe25bbc6f, 0x3f957857} },
+/**/ {{0x7384981f, 0xbf9cd64d} },
+/**/ {{0x3da3b8d5, 0x3f8873d7} } },
+/**/ {{{0x00000000, 0x3fe5a000} },
+/**/ {{0x753b090b, 0x3fe30464} },
+/**/ {{0x61da18f3, 0xbc73e712} },
+/**/ {{0xf9ee77b6, 0x3fe5f7be} },
+/**/ {{0x854f9928, 0x3c8949f7} },
+/**/ {{0x099c98f6, 0xbfd461ec} },
+/**/ {{0x3eafe889, 0x3c5da491} },
+/**/ {{0x8ba9e286, 0x3fa46e87} },
+/**/ {{0x5377a1a9, 0x3c42573a} },
+/**/ {{0xfab82ffb, 0x3fb4e038} },
+/**/ {{0x402ef939, 0xbc414e45} },
+/**/ {{0x4a8ec478, 0xbfb3b412} },
+/**/ {{0xef6dba07, 0x3f96b8e0} },
+/**/ {{0x39c13c6e, 0x3f949360} },
+/**/ {{0xd47bfddb, 0xbf9c674a} },
+/**/ {{0x37ed6935, 0x3f88e101} } },
+/**/ {{{0x00000000, 0x3fe5c000} },
+/**/ {{0x048874be, 0x3fe31a52} },
+/**/ {{0x87a7ac24, 0x3c840cab} },
+/**/ {{0xed021586, 0x3fe5e360} },
+/**/ {{0xb32ab7e4, 0x3c86a444} },
+/**/ {{0x779f86c4, 0xbfd45a23} },
+/**/ {{0x6b782501, 0xbc75b9dc} },
+/**/ {{0x26af940c, 0x3fa51400} },
+/**/ {{0xf9ce64e2, 0x3c4f700e} },
+/**/ {{0x86a8eb42, 0x3fb47e0a} },
+/**/ {{0x36377584, 0xbc5a4df9} },
+/**/ {{0x7f8b6d42, 0xbfb39192} },
+/**/ {{0x5deeeabc, 0x3f9745d1} },
+/**/ {{0x17fa1033, 0x3f93b1e8} },
+/**/ {{0x14cf2061, 0xbf9bf673} },
+/**/ {{0x0a340016, 0x3f894463} } },
+/**/ {{{0x00000000, 0x3fe5e000} },
+/**/ {{0x39b78856, 0x3fe3302b} },
+/**/ {{0xd87ba82b, 0x3c85dd2e} },
+/**/ {{0xc77d4bea, 0x3fe5cf0a} },
+/**/ {{0x0d42ab66, 0xbc8684ab} },
+/**/ {{0x6b573e11, 0xbfd4521d} },
+/**/ {{0xb90c9c27, 0xbc7601b9} },
+/**/ {{0x0582aeaa, 0x3fa5b66a} },
+/**/ {{0x8cc985ad, 0x3c281575} },
+/**/ {{0x9a69373d, 0x3fb41c8a} },
+/**/ {{0x25ea8f67, 0xbc33df07} },
+/**/ {{0xe5673a18, 0xbfb36e43} },
+/**/ {{0xeb05f3bc, 0x3f97cca3} },
+/**/ {{0x7797abe9, 0x3f92d3fd} },
+/**/ {{0x9d71c254, 0xbf9b83f1} },
+/**/ {{0xfe333861, 0x3f899e41} } },
+/**/ {{{0x00000000, 0x3fe60000} },
+/**/ {{0x1cce37bb, 0x3fe345f0} },
+/**/ {{0x37c71102, 0x3c810211} },
+/**/ {{0xc647fa91, 0x3fe5babc} },
+/**/ {{0x8056eaf3, 0x3c84339b} },
+/**/ {{0x094286d0, 0xbfd449db} },
+/**/ {{0x512b1c7b, 0x3c75e178} },
+/**/ {{0xac4cf102, 0x3fa655ca} },
+/**/ {{0x61e8206a, 0xbc27a1e4} },
+/**/ {{0x2933dd9c, 0x3fb3bbbd} },
+/**/ {{0xbd42c006, 0xbc517633} },
+/**/ {{0x9636afc9, 0xbfb34a2f} },
+/**/ {{0xa2400f6f, 0x3f984d71} },
+/**/ {{0xfcc53cab, 0x3f91f9ac} },
+/**/ {{0x9ec31ef1, 0xbf9b0ff0} },
+/**/ {{0xb1615b05, 0x3f89eee3} } },
+/**/ {{{0x00000000, 0x3fe62000} },
+/**/ {{0xb60eccce, 0x3fe35ba0} },
+/**/ {{0x9b9368b9, 0x3c8e3ba1} },
+/**/ {{0x25268d22, 0x3fe5a677} },
+/**/ {{0xaf72cee6, 0x3c7bc76e} },
+/**/ {{0x73c8c31c, 0xbfd4415d} },
+/**/ {{0xe00e5645, 0xbc3e5b3c} },
+/**/ {{0xbe1ce1b6, 0x3fa6f227} },
+/**/ {{0xe699fcac, 0xbc04a922} },
+/**/ {{0xf91f9885, 0x3fb35ba5} },
+/**/ {{0x418827b3, 0xbc43f8be} },
+/**/ {{0x863cebc9, 0xbfb3255e} },
+/**/ {{0xe315ca66, 0x3f98c853} },
+/**/ {{0xff116cac, 0x3f912301} },
+/**/ {{0x0f5e09c2, 0xbf9a9a99} },
+/**/ {{0xf4c8d587, 0x3f8a368d} } },
+/**/ {{{0x00000000, 0x3fe64000} },
+/**/ {{0x0df6c504, 0x3fe3713d} },
+/**/ {{0xe031606d, 0xbc54f789} },
+/**/ {{0x1ebc184f, 0x3fe5923a} },
+/**/ {{0xbe5956dd, 0x3c829fe8} },
+/**/ {{0xcb2e9cc9, 0xbfd438a5} },
+/**/ {{0x7d6ce3eb, 0xbc7c1839} },
+/**/ {{0xfb7fa678, 0x3fa78b86} },
+/**/ {{0xd082025e, 0x3befb53e} },
+/**/ {{0xa3dd5905, 0x3fb2fc48} },
+/**/ {{0x06b78682, 0x3c5fd567} },
+/**/ {{0x8374843c, 0xbfb2ffd9} },
+/**/ {{0x57f51471, 0x3f993d64} },
+/**/ {{0x933f6cc5, 0x3f905006} },
+/**/ {{0xab7658df, 0xbf9a2412} },
+/**/ {{0xae624ab4, 0x3f8a7586} } },
+/**/ {{{0x00000000, 0x3fe66000} },
+/**/ {{0x2d3db11f, 0x3fe386c5} },
+/**/ {{0xcbebe6a0, 0xbc8b78e1} },
+/**/ {{0xec8c8203, 0x3fe57e05} },
+/**/ {{0x5e7f92dc, 0x3c8ea585} },
+/**/ {{0x2d8b381e, 0xbfd42fb5} },
+/**/ {{0x5cff451e, 0xbc63afe6} },
+/**/ {{0x4120d643, 0x3fa821ee} },
+/**/ {{0xcbc4d2dc, 0xbc3e664f} },
+/**/ {{0x9778bfdb, 0x3fb29da8} },
+/**/ {{0x7c2057a5, 0x3c3760dd} },
+/**/ {{0x3525a55a, 0xbfb2d9a9} },
+/**/ {{0xed9015c8, 0x3f99acbc} },
+/**/ {{0x2a35e7d2, 0x3f8f0187} },
+/**/ {{0xf4bcdfc7, 0xbf99ac83} },
+/**/ {{0xbbeb4f11, 0x3f8aac13} } },
+/**/ {{{0x00000000, 0x3fe68000} },
+/**/ {{0x1cd4171a, 0x3fe39c39} },
+/**/ {{0x31d8bf46, 0xbc823043} },
+/**/ {{0xc6feb417, 0x3fe569da} },
+/**/ {{0x0625e450, 0x3c803ce5} },
+/**/ {{0xb6bde980, 0xbfd4268c} },
+/**/ {{0xe8258561, 0xbc6e8f76} },
+/**/ {{0x86705749, 0x3fa8b563} },
+/**/ {{0xe6172281, 0x3c418e14} },
+/**/ {{0x171a8768, 0x3fb23fc9} },
+/**/ {{0x3225d825, 0xbc562184} },
+/**/ {{0x1b8904fd, 0xbfb2b2d6} },
+/**/ {{0xca70ce88, 0x3f9a1677} },
+/**/ {{0x62963581, 0x3f8d6a81} },
+/**/ {{0x32c353bb, 0xbf993412} },
+/**/ {{0xd7354ec0, 0x3f8ada7a} } },
+/**/ {{{0x00000000, 0x3fe6a000} },
+/**/ {{0xe5e2564b, 0x3fe3b198} },
+/**/ {{0x1f0752ac, 0xbc72f922} },
+/**/ {{0xe55ed910, 0x3fe555b8} },
+/**/ {{0x656f2eb2, 0xbc5615bc} },
+/**/ {{0x80646bca, 0xbfd41d2d} },
+/**/ {{0x1ff3506f, 0xbc75d1d6} },
+/**/ {{0xdc4e5727, 0x3fa945ec} },
+/**/ {{0x18968922, 0x3c213c8e} },
+/**/ {{0x3bcc9fa4, 0x3fb1e2ad} },
+/**/ {{0x0a43c591, 0x3c2b899c} },
+/**/ {{0x8f774533, 0xbfb28b68} },
+/**/ {{0x46d16acc, 0x3f9a7aaf} },
+/**/ {{0xde405cc6, 0x3f8bdb08} },
+/**/ {{0x73d9884b, 0xbf98bae1} },
+/**/ {{0x7be7742a, 0x3f8b0101} } },
+/**/ {{{0x00000000, 0x3fe6c000} },
+/**/ {{0x91c78dc5, 0x3fe3c6e4} },
+/**/ {{0x94fd0ba7, 0xbc8e1450} },
+/**/ {{0x7de0a269, 0x3fe541a0} },
+/**/ {{0x163b639c, 0x3c8b9072} },
+/**/ {{0xa1d194fc, 0xbfd41398} },
+/**/ {{0x8629402d, 0xbc7ef191} },
+/**/ {{0x6bbd69eb, 0x3fa9d390} },
+/**/ {{0xd2c4a6a5, 0x3c488aec} },
+/**/ {{0xf53fbee6, 0x3fb18657} },
+/**/ {{0x0104d1dd, 0x3c54e6aa} },
+/**/ {{0xc2245ee6, 0xbfb26368} },
+/**/ {{0xe4b91b16, 0x3f9ad97d} },
+/**/ {{0x74b192c7, 0x3f8a5328} },
+/**/ {{0x8e5d8b31, 0xbf984114} },
+/**/ {{0xceadce82, 0x3f8b1fec} } },
+/**/ {{{0x00000000, 0x3fe6e000} },
+/**/ {{0x2a188504, 0x3fe3dc1c} },
+/**/ {{0x70f4e971, 0x3c82ce63} },
+/**/ {{0xc5a197ed, 0x3fe52d91} },
+/**/ {{0x1baab820, 0xbc804b92} },
+/**/ {{0x300486f8, 0xbfd409cf} },
+/**/ {{0xae804189, 0xbc6d3bb8} },
+/**/ {{0x749adab8, 0x3faa5e54} },
+/**/ {{0xc631cfd3, 0x3c20b0d5} },
+/**/ {{0x0a922c54, 0x3fb12acc} },
+/**/ {{0x7cbc4417, 0x3c521a06} },
+/**/ {{0xbce6ae05, 0xbfb23ade} },
+/**/ {{0x485d279b, 0x3f9b32fe} },
+/**/ {{0xd9b56b96, 0x3f88d2e8} },
+/**/ {{0x227841f4, 0xbf97c6cd} },
+/**/ {{0x85cf6ba0, 0x3f8b3781} } },
+/**/ {{{0x00000000, 0x3fe70000} },
+/**/ {{0xb89e96f4, 0x3fe3f13f} },
+/**/ {{0x492644f0, 0x3c7ecf8b} },
+/**/ {{0xf0ab6f99, 0x3fe5198c} },
+/**/ {{0x5e1ffaba, 0x3c71b875} },
+/**/ {{0x3da059f4, 0xbfd3ffd2} },
+/**/ {{0x77eee53d, 0x3c5bba8e} },
+/**/ {{0x4c5d36dc, 0x3faae63f} },
+/**/ {{0x2a3994d6, 0xbc4e6e4e} },
+/**/ {{0x1b178ada, 0x3fb0d00c} },
+/**/ {{0xb3e710cc, 0x3c4b94c3} },
+/**/ {{0x61093929, 0xbfb211d2} },
+/**/ {{0x30c5dd59, 0x3f9b874b} },
+/**/ {{0xb0b899ed, 0x3f875a50} },
+/**/ {{0x9c404912, 0xbf974c2b} },
+/**/ {{0xd3249a4d, 0x3f8b4803} } },
+/**/ {{{0x00000000, 0x3fe72000} },
+/**/ {{0x47569f49, 0x3fe4064f} },
+/**/ {{0xf91bf2b2, 0xbc8aad88} },
+/**/ {{0x31f66da7, 0x3fe50592} },
+/**/ {{0x134b7507, 0xbc8837f1} },
+/**/ {{0xdae43e4d, 0xbfd3f5a2} },
+/**/ {{0xdc59e382, 0xbc7f29b0} },
+/**/ {{0x5cd91a8c, 0x3fab6b57} },
+/**/ {{0xd6ab0dfc, 0xbc225bf7} },
+/**/ {{0x9f216d7a, 0x3fb0761a} },
+/**/ {{0xe546203e, 0x3c577818} },
+/**/ {{0x67a8cf31, 0xbfb1e84b} },
+/**/ {{0x70b6dd6f, 0x3f9bd67f} },
+/**/ {{0x9ff677e5, 0x3f85e964} },
+/**/ {{0x363cf426, 0xbf96d14f} },
+/**/ {{0x4f6617de, 0x3f8b51b7} } },
+/**/ {{{0x00000000, 0x3fe74000} },
+/**/ {{0xe06fea41, 0x3fe41b4a} },
+/**/ {{0x53277652, 0x3c63d60a} },
+/**/ {{0xbb6bcc2c, 0x3fe4f1a1} },
+/**/ {{0x7c81f558, 0x3c5c8d69} },
+/**/ {{0x15a41364, 0xbfd3eb42} },
+/**/ {{0x617c316a, 0x3c728a9c} },
+/**/ {{0x230c44b8, 0x3fabeda3} },
+/**/ {{0x50d9e9da, 0x3c41fa15} },
+/**/ {{0xe8c87fc3, 0x3fb01cf9} },
+/**/ {{0xa175df34, 0x3c410990} },
+/**/ {{0x619b963c, 0xbfb1be51} },
+/**/ {{0xe7da421c, 0x3f9c20b5} },
+/**/ {{0x637b86b0, 0x3f848027} },
+/**/ {{0xfc436ff1, 0xbf965655} },
+/**/ {{0xe6cd859f, 0x3f8b54de} } },
+/**/ {{{0x00000000, 0x3fe76000} },
+/**/ {{0x8e4b26d6, 0x3fe43032} },
+/**/ {{0x1070b99f, 0xbc813159} },
+/**/ {{0xbde829f5, 0x3fe4ddbb} },
+/**/ {{0xb6d17615, 0xbc735ff2} },
+/**/ {{0xf941711a, 0xbfd3e0b0} },
+/**/ {{0xe9027227, 0x3c7d3454} },
+/**/ {{0x2deef5c2, 0x3fac6d29} },
+/**/ {{0x0ba13bb6, 0x3c476533} },
+/**/ {{0x496c1e5e, 0x3faf8958} },
+/**/ {{0xe1abdf2f, 0x3c49ebf2} },
+/**/ {{0xb762a82c, 0xbfb193eb} },
+/**/ {{0x7c2df93f, 0x3f9c6609} },
+/**/ {{0xdff7724a, 0x3f831e99} },
+/**/ {{0xcea82a5a, 0xbf95db5c} },
+/**/ {{0xc6ff27bb, 0x3f8b51bc} } },
+/**/ {{{0x00000000, 0x3fe78000} },
+/**/ {{0x5b795b56, 0x3fe44506} },
+/**/ {{0x163f79c8, 0xbc7f76d0} },
+/**/ {{0x693e0015, 0x3fe4c9e0} },
+/**/ {{0x60fff59b, 0xbc7b0fcb} },
+/**/ {{0x8ea521a8, 0xbfd3d5f0} },
+/**/ {{0xb5bcc402, 0x3c561573} },
+/**/ {{0x1d4b9b62, 0x3face9f0} },
+/**/ {{0xf2c93cfb, 0x3c481226} },
+/**/ {{0xb5db8847, 0x3faeda66} },
+/**/ {{0x3a386670, 0xbc44ec99} },
+/**/ {{0xa92559e3, 0xbfb16921} },
+/**/ {{0x13b2a17d, 0x3f9ca695} },
+/**/ {{0x355982b3, 0x3f81c4bb} },
+/**/ {{0x65bec936, 0xbf95607f} },
+/**/ {{0x4e349f67, 0x3f8b4892} } },
+/**/ {{{0x00000000, 0x3fe7a000} },
+/**/ {{0x52badc7f, 0x3fe459c6} },
+/**/ {{0x8e8e135c, 0x3c819969} },
+/**/ {{0xec381dcb, 0x3fe4b60f} },
+/**/ {{0x4724e4f2, 0xbc6b9874} },
+/**/ {{0xdc390960, 0xbfd3cb01} },
+/**/ {{0x7ba1320c, 0xbc7243b1} },
+/**/ {{0xa09cca72, 0x3fad63fe} },
+/**/ {{0xe5ab8d04, 0x3c48308c} },
+/**/ {{0xdf2eb652, 0x3fae2d22} },
+/**/ {{0x4eb29ad3, 0xbc4988a3} },
+/**/ {{0x4eb5cb96, 0xbfb13dfa} },
+/**/ {{0x8e5b2657, 0x3f9ce273} },
+/**/ {{0xd132be74, 0x3f807288} },
+/**/ {{0x55a31e9e, 0xbf94e5d8} },
+/**/ {{0xfba00cb2, 0x3f8b399f} } },
+/**/ {{{0x00000000, 0x3fe7c000} },
+/**/ {{0x7efe4716, 0x3fe46e72} },
+/**/ {{0x1b844cc9, 0xbc639b9b} },
+/**/ {{0x749c2a47, 0x3fe4a24a} },
+/**/ {{0x82d8a2e5, 0xbc8f9d05} },
+/**/ {{0xe5e27a03, 0xbfd3bfe5} },
+/**/ {{0xb30f6d58, 0xbc5047da} },
+/**/ {{0x75f185ec, 0x3faddb5b} },
+/**/ {{0x23d5084a, 0x3c43b680} },
+/**/ {{0x479061d2, 0x3fad8190} },
+/**/ {{0x602d3547, 0xbbf4565c} },
+/**/ {{0x979e619e, 0xbfb1127c} },
+/**/ {{0xc03c4720, 0x3f9d19bf} },
+/**/ {{0x01b2b45f, 0x3f7e4ffd} },
+/**/ {{0x1245b0bb, 0xbf946b81} },
+/**/ {{0x60fec8ec, 0x3f8b2525} } },
+/**/ {{{0x00000000, 0x3fe7e000} },
+/**/ {{0xeb5f7bfe, 0x3fe4830a} },
+/**/ {{0x66764a73, 0xbc5a2656} },
+/**/ {{0x2f2d2be4, 0x3fe48e90} },
+/**/ {{0x969bba3b, 0x3c810a8e} },
+/**/ {{0xacfcef4d, 0xbfd3b49d} },
+/**/ {{0xb7a61548, 0xbc6a4f98} },
+/**/ {{0x68d7d101, 0x3fae500d} },
+/**/ {{0x04860c21, 0xbc305c3e} },
+/**/ {{0x2c98ea9c, 0x3facd7b2} },
+/**/ {{0xd46adca0, 0x3c48692b} },
+/**/ {{0x4b37c6a5, 0xbfb0e6af} },
+/**/ {{0x6bfb2662, 0x3f9d4c94} },
+/**/ {{0x0692cc75, 0x3f7bca2d} },
+/**/ {{0xf3b69312, 0xbf93f191} },
+/**/ {{0x1552b8ee, 0x3f8b0b61} } },
+/**/ {{{0x00000000, 0x3fe80000} },
+/**/ {{0xa3269ee1, 0x3fe4978f} },
+/**/ {{0x87f2a458, 0x3c72419a} },
+/**/ {{0x47ae147b, 0x3fe47ae1} },
+/**/ {{0xeb851eb8, 0xbc6eb851} },
+/**/ {{0x30553261, 0xbfd3a92a} },
+/**/ {{0x94467382, 0xbc7f06f6} },
+/**/ {{0x514d88d8, 0x3faec21b} },
+/**/ {{0xf45873a6, 0x3c3cd061} },
+/**/ {{0x88dfb80c, 0x3fac2f8b} },
+/**/ {{0x53add20b, 0xbc14fcbc} },
+/**/ {{0x08c71945, 0xbfb0ba99} },
+/**/ {{0x3d79f13f, 0x3f9d7b0c} },
+/**/ {{0x357dfc67, 0x3f795393} },
+/**/ {{0x3aa97829, 0xbf937822} },
+/**/ {{0xa8b90db0, 0x3f8aec90} } },
+/**/ {{{0x00000000, 0x3fe82000} },
+/**/ {{0xb1c71762, 0x3fe4ac00} },
+/**/ {{0x2382b900, 0x3c8b20e7} },
+/**/ {{0xe8e45252, 0x3fe4673d} },
+/**/ {{0x67458f9c, 0x3c57d208} },
+/**/ {{0x6c24e1b3, 0xbfd39d8c} },
+/**/ {{0x973c6d15, 0xbc7830c5} },
+/**/ {{0x12b78147, 0x3faf318c} },
+/**/ {{0xd318184c, 0xbc4fa440} },
+/**/ {{0x158b44e7, 0x3fab891f} },
+/**/ {{0x45d7f1f3, 0x3c4d5f9f} },
+/**/ {{0x47a3e8ba, 0xbfb08e40} },
+/**/ {{0xc4c1a21a, 0x3f9da541} },
+/**/ {{0x3c0d1d71, 0x3f76ec1e} },
+/**/ {{0x152e0bfc, 0xbf92ff48} },
+/**/ {{0x9955298f, 0x3f8ac8f0} } },
+/**/ {{{0x00000000, 0x3fe84000} },
+/**/ {{0x22de94e5, 0x3fe4c05e} },
+/**/ {{0xf09f2edf, 0xbc8c0ac1} },
+/**/ {{0x3c9a6560, 0x3fe453a6} },
+/**/ {{0x828bba02, 0x3c77a95f} },
+/**/ {{0x5a0e5b1c, 0xbfd391c5} },
+/**/ {{0xcd3f76d2, 0x3c7d553d} },
+/**/ {{0x9adede86, 0x3faf9e66} },
+/**/ {{0xd6d2bac0, 0xbc225e54} },
+/**/ {{0x4bdf89d7, 0x3faae46f} },
+/**/ {{0x2b25b8d9, 0x3c39c98c} },
+/**/ {{0x5765a5c1, 0xbfb061ab} },
+/**/ {{0x7127d649, 0x3f9dcb4f} },
+/**/ {{0x13002646, 0x3f7493ba} },
+/**/ {{0xa397d1a6, 0xbf928718} },
+/**/ {{0x494648b5, 0x3f8aa0bc} } },
+/**/ {{{0x00000000, 0x3fe86000} },
+/**/ {{0x023414e8, 0x3fe4d4a8} },
+/**/ {{0x1daa88b0, 0x3c6e3a89} },
+/**/ {{0x6ba2786e, 0x3fe4401a} },
+/**/ {{0xe3b5f317, 0xbc4b8213} },
+/**/ {{0xf11905c0, 0xbfd385d5} },
+/**/ {{0xa2f42dd1, 0xbc72a1e9} },
+/**/ {{0xf07a526f, 0x3fb00458} },
+/**/ {{0xac5fd817, 0xbc14f965} },
+/**/ {{0x66ca7da2, 0x3faa417e} },
+/**/ {{0xa050b433, 0x3c4b1e1a} },
+/**/ {{0x60182e4f, 0xbfb034e0} },
+/**/ {{0x8cafa41b, 0x3f9ded4f} },
+/**/ {{0x1fa4f037, 0x3f724a50} },
+/**/ {{0xfd90e915, 0xbf920fa7} },
+/**/ {{0xf59e7acf, 0x3f8a742d} } },
+/**/ {{{0x00000000, 0x3fe88000} },
+/**/ {{0x5bb6ec04, 0x3fe4e8de} },
+/**/ {{0xbeb3796c, 0x3c84a33d} },
+/**/ {{0x9dd8fdc1, 0x3fe42c9a} },
+/**/ {{0xaf80050b, 0x3c5192da} },
+/**/ {{0x25adf97f, 0xbfd379bf} },
+/**/ {{0x20cd3651, 0xbc774019} },
+/**/ {{0x724dbb01, 0x3fb0383a} },
+/**/ {{0xeb93e538, 0x3c5c4e67} },
+/**/ {{0x646e65df, 0x3fa9a04e} },
+/**/ {{0x894a6b77, 0x3c21a7cb} },
+/**/ {{0x62771c79, 0xbfb007e5} },
+/**/ {{0x37a45544, 0x3f9e0b5c} },
+/**/ {{0x54993092, 0x3f700fc7} },
+/**/ {{0x37534c25, 0xbf919909} },
+/**/ {{0xae51732a, 0x3f8a437e} } },
+/**/ {{{0x00000000, 0x3fe8a000} },
+/**/ {{0x3b7dd17e, 0x3fe4fd01} },
+/**/ {{0x3e7c24b5, 0x3c7d513f} },
+/**/ {{0xfa274ef1, 0x3fe41926} },
+/**/ {{0x4d72ecb3, 0x3c8ad830} },
+/**/ {{0xe995018a, 0xbfd36d81} },
+/**/ {{0x6fd6094d, 0x3c7e7ec5} },
+/**/ {{0x567bb975, 0x3fb06adb} },
+/**/ {{0xf0d7364f, 0x3c5212c1} },
+/**/ {{0x07a9b624, 0x3fa900e1} },
+/**/ {{0xc16bcc85, 0xbc4e5b5b} },
+/**/ {{0x705f052b, 0xbfafb580} },
+/**/ {{0x646ce12e, 0x3f9e258f} },
+/**/ {{0xa3c63841, 0x3f6bc808} },
+/**/ {{0x67043d41, 0xbf91234e} },
+/**/ {{0x4f11b221, 0x3f8a0ee6} } },
+/**/ {{{0x00000000, 0x3fe8c000} },
+/**/ {{0xadc5ed81, 0x3fe51110} },
+/**/ {{0x6832a63e, 0x3c723dcd} },
+/**/ {{0xa6864f90, 0x3fe405bf} },
+/**/ {{0x662cd5df, 0xbc7419c5} },
+/**/ {{0x2bf1f7e4, 0xbfd3611f} },
+/**/ {{0x65483b78, 0xbc6e94dd} },
+/**/ {{0x23e21be9, 0x3fb09c3f} },
+/**/ {{0xcaca858d, 0x3c22db63} },
+/**/ {{0xd99c3f1d, 0x3fa86337} },
+/**/ {{0xdc0a6dfc, 0x3c034382} },
+/**/ {{0x284f8093, 0xbfaf5aed} },
+/**/ {{0xd396fb43, 0x3f9e3c02} },
+/**/ {{0x08b96150, 0x3f678dd3} },
+/**/ {{0xaa2dcc3a, 0xbf90ae88} },
+/**/ {{0x79128ee7, 0x3f89d69b} } },
+/**/ {{{0x00000000, 0x3fe8e000} },
+/**/ {{0xbef1e9fb, 0x3fe5250c} },
+/**/ {{0xa3228870, 0xbc5539b7} },
+/**/ {{0xc8011245, 0x3fe3f264} },
+/**/ {{0x44cc720b, 0xbc6641f1} },
+/**/ {{0xd942778a, 0xbfd35497} },
+/**/ {{0x9bd7dbd6, 0x3c750a5a} },
+/**/ {{0x6438739e, 0x3fb0cc69} },
+/**/ {{0x435f798d, 0x3bf5d933} },
+/**/ {{0x2b29722f, 0x3fa7c754} },
+/**/ {{0x5b3af27b, 0xbbe736fe} },
+/**/ {{0x059a3c24, 0xbfaf001c} },
+/**/ {{0x101882b0, 0x3f9e4ed0} },
+/**/ {{0x88dc4269, 0x3f6370ae} },
+/**/ {{0x2b5280b6, 0xbf903ac8} },
+/**/ {{0x8da5b2ad, 0x3f899ad3} } },
+/**/ {{{0x00000000, 0x3fe90000} },
+/**/ {{0x7b89061f, 0x3fe538f5} },
+/**/ {{0xabda520c, 0xbc81bb74} },
+/**/ {{0x82b78014, 0x3fe3df16} },
+/**/ {{0xa43ff610, 0xbc7074be} },
+/**/ {{0xdb5be2e4, 0xbfd347ec} },
+/**/ {{0x8a0e9303, 0x3c7848c8} },
+/**/ {{0xa3a11be4, 0x3fb0fb5d} },
+/**/ {{0x09dd0d69, 0x3c3d68f2} },
+/**/ {{0x16778170, 0x3fa72d37} },
+/**/ {{0x2200d1d4, 0xbc4ea85d} },
+/**/ {{0xd4cdbd49, 0xbfaea517} },
+/**/ {{0x6bc61b6f, 0x3f9e5e10} },
+/**/ {{0xd0517524, 0x3f5ee0af} },
+/**/ {{0x4f2ec799, 0xbf8f9038} },
+/**/ {{0xa9aaa5bb, 0x3f895bc2} } },
+/**/ {{{0x00000000, 0x3fe92000} },
+/**/ {{0xf0362c8f, 0x3fe54cca} },
+/**/ {{0x7f8f43c1, 0x3c88a324} },
+/**/ {{0xf9e1016e, 0x3fe3cbd4} },
+/**/ {{0x431b67e7, 0xbc88dea6} },
+/**/ {{0x1969bc63, 0xbfd33b1f} },
+/**/ {{0x5f3d8fd8, 0x3c6ef16e} },
+/**/ {{0x703d3bf6, 0x3fb1291f} },
+/**/ {{0xb04e0672, 0xbc566e82} },
+/**/ {{0x806b26f2, 0x3fa694e1} },
+/**/ {{0xafcee740, 0x3c302819} },
+/**/ {{0x16dcee96, 0xbfae49eb} },
+/**/ {{0xfbfdb35f, 0x3f9e69dc} },
+/**/ {{0x70c48510, 0x3f571910} },
+/**/ {{0xe90198c8, 0xbf8ead25} },
+/**/ {{0xa1c723cb, 0x3f89199b} } },
+/**/ {{{0x00000000, 0x3fe94000} },
+/**/ {{0x29c70c34, 0x3fe5608d} },
+/**/ {{0xf0de8088, 0x3c89939c} },
+/**/ {{0x4fcf28c3, 0x3fe3b8a0} },
+/**/ {{0xcb80013c, 0xbc469c2b} },
+/**/ {{0x77ec4ef9, 0xbfd32e2f} },
+/**/ {{0xc61f7341, 0x3c7f9d06} },
+/**/ {{0x59c3bcdf, 0x3fb155b2} },
+/**/ {{0x3583c01b, 0xbc2d692e} },
+/**/ {{0x1a1fe15d, 0x3fa5fe54} },
+/**/ {{0x5d9bad81, 0x3c430dc5} },
+/**/ {{0x01d944a8, 0xbfadeea0} },
+/**/ {{0x9683b244, 0x3f9e724e} },
+/**/ {{0x491379ef, 0x3f4f13d4} },
+/**/ {{0x0b7cf74b, 0xbf8dcc74} },
+/**/ {{0xff5f0625, 0x3f88d48f} } },
+/**/ {{{0x00000000, 0x3fe96000} },
+/**/ {{0x352b33ba, 0x3fe5743c} },
+/**/ {{0x34c87ea6, 0xbc8ea00d} },
+/**/ {{0xa5f05e48, 0x3fe3a578} },
+/**/ {{0x00e4639b, 0xbc8ba1ec} },
+/**/ {{0xd8b7a43f, 0xbfd3211e} },
+/**/ {{0x676e23a8, 0xbc6d4b54} },
+/**/ {{0xf11b2c2d, 0x3fb18119} },
+/**/ {{0x3a3bf5fa, 0x3c34855b} },
+/**/ {{0x625c76bf, 0x3fa5698f} },
+/**/ {{0xbedb0264, 0xbc2f758a} },
+/**/ {{0x81b60103, 0xbfad9340} },
+/**/ {{0xce91900f, 0x3f9e777d} },
+/**/ {{0x34fddb2f, 0x3f406543} },
+/**/ {{0xe6077f81, 0xbf8cee3b} },
+/**/ {{0xfe42afde, 0x3f888ccf} } },
+/**/ {{{0x00000000, 0x3fe98000} },
+/**/ {{0x1f732fbb, 0x3fe587d8} },
+/**/ {{0xd8c5a950, 0xbc75e5c9} },
+/**/ {{0x1cd28c98, 0x3fe3925e} },
+/**/ {{0x1ffec6da, 0x3c8c8443} },
+/**/ {{0x1af2c622, 0xbfd313ee} },
+/**/ {{0xbc3f7ac8, 0x3c0a0e9b} },
+/**/ {{0xc7f683c3, 0x3fb1ab59} },
+/**/ {{0x12c04500, 0x3c5eaf17} },
+/**/ {{0xa7039179, 0x3fa4d693} },
+/**/ {{0xa4ce58a2, 0xbc4c8d74} },
+/**/ {{0x391400b3, 0xbfad37d6} },
+/**/ {{0xf2148a36, 0x3f9e7982} },
+/**/ {{0xb6df63ca, 0x3f112956} },
+/**/ {{0xfbd0f7ee, 0xbf8c1294} },
+/**/ {{0x8b0b0a0e, 0x3f88428a} } },
+/**/ {{{0x00000000, 0x3fe9a000} },
+/**/ {{0xf5cfab9e, 0x3fe59b60} },
+/**/ {{0x41026bc5, 0xbc81b04c} },
+/**/ {{0xd425cdfc, 0x3fe37f50} },
+/**/ {{0x518aef64, 0x3c865633} },
+/**/ {{0x1b1749db, 0xbfd3069e} },
+/**/ {{0xa119d9bc, 0xbc311c20} },
+/**/ {{0x7074cee3, 0x3fb1d475} },
+/**/ {{0x4ff61e2c, 0xbc5102e0} },
+/**/ {{0x06804def, 0x3fa44561} },
+/**/ {{0xc3865804, 0x3c4e829f} },
+/**/ {{0x82158836, 0xbfacdc6a} },
+/**/ {{0x071b2eec, 0x3f9e7876} },
+/**/ {{0xf17c4beb, 0xbf375b85} },
+/**/ {{0x2fa03971, 0xbf8b3995} },
+/**/ {{0x421a433b, 0x3f87f5ed} } },
+/**/ {{{0x00000000, 0x3fe9c000} },
+/**/ {{0xc5909517, 0x3fe5aed6} },
+/**/ {{0x714a9436, 0x3c87312f} },
+/**/ {{0xeabf19f5, 0x3fe36c50} },
+/**/ {{0x52485cca, 0x3c70d1dc} },
+/**/ {{0xb2f12226, 0xbfd2f92f} },
+/**/ {{0x3e5d3d61, 0x3c5400ba} },
+/**/ {{0x7cc3a41b, 0x3fb1fc70} },
+/**/ {{0x8819ff5b, 0x3c4b58e7} },
+/**/ {{0x712e9269, 0x3fa3b5f7} },
+/**/ {{0x7879d8ab, 0xbc4e436a} },
+/**/ {{0x6f398221, 0xbfac8106} },
+/**/ {{0xc97073c7, 0x3f9e746e} },
+/**/ {{0xecfc2d6a, 0xbf4914de} },
+/**/ {{0xcfa74bd5, 0xbf8a6350} },
+/**/ {{0x6f38ad9e, 0x3f87a724} } },
+/**/ {{{0x00000000, 0x3fe9e000} },
+/**/ {{0x9c244261, 0x3fe5c239} },
+/**/ {{0xe9e56b35, 0xbc831bd4} },
+/**/ {{0x7e9af2dc, 0x3fe3595e} },
+/**/ {{0x9dc90e6a, 0x3c81ef2d} },
+/**/ {{0xb99eb689, 0xbfd2eba3} },
+/**/ {{0x6a2f2701, 0xbc7b12ef} },
+/**/ {{0x7ec46b9b, 0x3fb2234e} },
+/**/ {{0x8d415d66, 0x3c59f30c} },
+/**/ {{0xaabf0d26, 0x3fa32856} },
+/**/ {{0x3f33d7ea, 0xbc122571} },
+/**/ {{0xcc3da9ce, 0xbfac25b2} },
+/**/ {{0xa8630cad, 0x3f9e6d84} },
+/**/ {{0xbeba707a, 0xbf5308c5} },
+/**/ {{0xa1585fd1, 0xbf898fda} },
+/**/ {{0x0dc54356, 0x3f87565b} } },
+/**/ {{{0x00000000, 0x3fea0000} },
+/**/ {{0x87169b18, 0x3fe5d589} },
+/**/ {{0x4bc5e7ca, 0x3c60028e} },
+/**/ {{0xace01346, 0x3fe34679} },
+/**/ {{0x04d19e6b, 0x3c8e6b38} },
+/**/ {{0x03913da2, 0xbfd2ddfb} },
+/**/ {{0x9a19adbd, 0xbc763ec8} },
+/**/ {{0x07b46905, 0x3fb24913} },
+/**/ {{0xd6f0307f, 0xbc4e7be8} },
+/**/ {{0x4b96b773, 0x3fa29c7e} },
+/**/ {{0x9182d783, 0xbc24c2cd} },
+/**/ {{0x1f071f44, 0xbfabca78} },
+/**/ {{0xc4b7b7c4, 0x3f9e63ce} },
+/**/ {{0x125f35b0, 0xbf59529a} },
+/**/ {{0xed369b2b, 0xbf88bf43} },
+/**/ {{0xc97185cd, 0x3f8703ba} } },
+/**/ {{{0x00000000, 0x3fea2000} },
+/**/ {{0x941043d0, 0x3fe5e8c6} },
+/**/ {{0xbe451e70, 0xbc70bf75} },
+/**/ {{0x91e21aec, 0x3fe333a2} },
+/**/ {{0x7acfc84f, 0x3c7ae035} },
+/**/ {{0x628d5861, 0xbfd2d036} },
+/**/ {{0xe463d006, 0x3c67c5fb} },
+/**/ {{0xa7d77fb2, 0x3fb26dc1} },
+/**/ {{0xc47ba861, 0xbc5432bd} },
+/**/ {{0xc229bece, 0x3fa2126d} },
+/**/ {{0x1da8ed9e, 0xbc4be1bf} },
+/**/ {{0xa890e568, 0xbfab6f5e} },
+/**/ {{0xeec5339a, 0x3f9e5763} },
+/**/ {{0x5274aa52, 0xbf5f68a6} },
+/**/ {{0x8a9df558, 0xbf87f19c} },
+/**/ {{0xff809dc5, 0x3f86af6b} } },
+/**/ {{{0x00000000, 0x3fea4000} },
+/**/ {{0xd0d5cc4a, 0x3fe5fbf0} },
+/**/ {{0x000b7158, 0xbc5b4cfd} },
+/**/ {{0x49243ad8, 0x3fe320d9} },
+/**/ {{0x433f7be5, 0xbc8ce5e0} },
+/**/ {{0xa5abec2f, 0xbfd2c256} },
+/**/ {{0x04494dc1, 0xbc68785b} },
+/**/ {{0xee25a81c, 0x3fb2915d} },
+/**/ {{0x68b37e8b, 0x3c3e7045} },
+/**/ {{0x5451b7d2, 0x3fa18a24} },
+/**/ {{0x79d21dd5, 0xbc3b2d29} },
+/**/ {{0x65dfcf66, 0xbfab146e} },
+/**/ {{0xa4b895b9, 0x3f9e485a} },
+/**/ {{0x14770b65, 0xbf62a5d4} },
+/**/ {{0xeb7dab0f, 0xbf8726f2} },
+/**/ {{0xc081d40d, 0x3f865995} } },
+/**/ {{{0x00000000, 0x3fea6000} },
+/**/ {{0x4b46e05f, 0x3fe60f08} },
+/**/ {{0x99945193, 0xbc8dbb86} },
+/**/ {{0xed5be099, 0x3fe30e1d} },
+/**/ {{0x373fae45, 0x3c6c6e78} },
+/**/ {{0x995b3a02, 0xbfd2b45c} },
+/**/ {{0xe7cea2ad, 0x3c7cb97b} },
+/**/ {{0x67fb0cde, 0x3fb2b3eb} },
+/**/ {{0x4920d50b, 0xbc402927} },
+/**/ {{0x209f00e4, 0x3fa103a1} },
+/**/ {{0xecac275a, 0xbc36fb57} },
+/**/ {{0x10fb6629, 0xbfaab9af} },
+/**/ {{0x1100b94a, 0x3f9e36c9} },
+/**/ {{0x58620e6c, 0xbf657e30} },
+/**/ {{0x2801158e, 0xbf865f54} },
+/**/ {{0xd27eaf07, 0x3f86025d} } },
+/**/ {{{0x00000000, 0x3fea8000} },
+/**/ {{0x115d7b8e, 0x3fe6220d} },
+/**/ {{0x350ee8c1, 0xbc62b785} },
+/**/ {{0x98736048, 0x3fe2fb70} },
+/**/ {{0x4df7c4fa, 0x3c87a751} },
+/**/ {{0x07603054, 0xbfd2a649} },
+/**/ {{0xf564247c, 0x3c7c41eb} },
+/**/ {{0xa0cac592, 0x3fb2d56d} },
+/**/ {{0x4e757ddf, 0x3c333138} },
+/**/ {{0x1fa53ce5, 0x3fa07ee3} },
+/**/ {{0x28113a76, 0xbc41bd0c} },
+/**/ {{0x21eb5271, 0xbfaa5f28} },
+/**/ {{0x08df7f4f, 0x3f9e22c5} },
+/**/ {{0x107b528f, 0xbf683dca} },
+/**/ {{0x0a22f693, 0xbf859acc} },
+/**/ {{0xb39536ba, 0x3f85a9e8} } },
+/**/ {{{0x00000000, 0x3feaa000} },
+/**/ {{0x312d1f3b, 0x3fe634ff} },
+/**/ {{0x15f2b598, 0x3c89d2f3} },
+/**/ {{0x638c9d15, 0x3fe2e8d1} },
+/**/ {{0xfe1a437d, 0x3c831ae5} },
+/**/ {{0xb6d7f622, 0xbfd2981c} },
+/**/ {{0x86e9fe4d, 0xbc53da87} },
+/**/ {{0x21d425b2, 0x3fb2f5e8} },
+/**/ {{0xae2616cb, 0xbc186482} },
+/**/ {{0x4a85a0e4, 0x3f9ff7d2} },
+/**/ {{0xe2d9205b, 0xbc294288} },
+/**/ {{0xcfb8dc09, 0xbfaa04e0} },
+/**/ {{0x0b1f9c73, 0x3f9e0c64} },
+/**/ {{0xbd3845d8, 0xbf6ae504} },
+/**/ {{0x19278cae, 0xbf84d965} },
+/**/ {{0x9cf7183b, 0x3f855059} } },
+/**/ {{{0x00000000, 0x3feac000} },
+/**/ {{0xb8e20b90, 0x3fe647de} },
+/**/ {{0x023a51cf, 0xbc5eca04} },
+/**/ {{0x6703b033, 0x3fe2d640} },
+/**/ {{0x38039b02, 0x3c870ae6} },
+/**/ {{0x6c39acf5, 0xbfd289d8} },
+/**/ {{0x0238a7ee, 0xbc71f038} },
+/**/ {{0x71da955f, 0x3fb3155e} },
+/**/ {{0xd41f84df, 0xbc5faa02} },
+/**/ {{0xc3c69caa, 0x3f9ef563} },
+/**/ {{0x75403dbd, 0x3c331d29} },
+/**/ {{0x1174124f, 0xbfa9aae0} },
+/**/ {{0x3eedb30b, 0x3f9df3bb} },
+/**/ {{0x1c632765, 0xbf6d7445} },
+/**/ {{0xa4fa03e7, 0xbf841b28} },
+/**/ {{0x8646990d, 0x3f84f5d2} } },
+/**/ {{{0x00000000, 0x3feae000} },
+/**/ {{0xb6c07b03, 0x3fe65aab} },
+/**/ {{0x3af32729, 0xbc67939b} },
+/**/ {{0xba718de8, 0x3fe2c3bd} },
+/**/ {{0xc4990a2b, 0xbc82d2fc} },
+/**/ {{0xe9586818, 0xbfd27b7c} },
+/**/ {{0x880839ca, 0x3c780d5e} },
+/**/ {{0x14dfe9e3, 0x3fb333d4} },
+/**/ {{0xbce74cae, 0x3c536469} },
+/**/ {{0xc77983b8, 0x3f9df677} },
+/**/ {{0xb42f53aa, 0x3c373272} },
+/**/ {{0x9f3c360e, 0xbfa9512c} },
+/**/ {{0x72d37b24, 0x3f9dd8df} },
+/**/ {{0x02e417f5, 0xbf6febf1} },
+/**/ {{0xd16a1579, 0xbf83601e} },
+/**/ {{0x294a83e4, 0x3f849a74} } },
+/**/ {{{0x00000000, 0x3feb0000} },
+/**/ {{0x3923e087, 0x3fe66d66} },
+/**/ {{0xebe8bbba, 0xbc76ea6f} },
+/**/ {{0x74aea886, 0x3fe2b149} },
+/**/ {{0xa9d6d16a, 0x3c868ffd} },
+/**/ {{0xed65571e, 0xbfd26d0a} },
+/**/ {{0x476fb5f2, 0x3c6cf972} },
+/**/ {{0x8be1339f, 0x3fb3514c} },
+/**/ {{0x3f722216, 0x3c5c8c0f} },
+/**/ {{0x300f8f9b, 0x3f9cfb0b} },
+/**/ {{0x38d1c932, 0xbc0edd81} },
+/**/ {{0xf34b004f, 0xbfa8f7cc} },
+/**/ {{0x1bd3bde0, 0x3f9dbbe5} },
+/**/ {{0x9bf7dceb, 0xbf712637} },
+/**/ {{0xa146e5b2, 0xbf82a84e} },
+/**/ {{0x05f2718e, 0x3f843e5e} } },
+/**/ {{{0x00000000, 0x3feb2000} },
+/**/ {{0x4e7e2858, 0x3fe6800e} },
+/**/ {{0x1b3e90f0, 0xbc58ea6a} },
+/**/ {{0xabd5912c, 0x3fe29ee3} },
+/**/ {{0xb17c28e3, 0xbc61b3cd} },
+/**/ {{0x34f221eb, 0xbfd25e83} },
+/**/ {{0xfa300585, 0xbc74c483} },
+/**/ {{0x5495f6e3, 0x3fb36dcb} },
+/**/ {{0x311973fe, 0x3c59b55b} },
+/**/ {{0x9864d139, 0x3f9c031a} },
+/**/ {{0xbd00e171, 0x3c28fdf3} },
+/**/ {{0x4b026585, 0xbfa89ec7} },
+/**/ {{0x54a5ed3d, 0x3f9d9ce0} },
+/**/ {{0xa8cb6dfc, 0xbf724b13} },
+/**/ {{0x015469a9, 0xbf81f3be} },
+/**/ {{0x66a50a89, 0x3f83e1ae} } },
+/**/ {{{0x00000000, 0x3feb4000} },
+/**/ {{0x0556fb6a, 0x3fe692a4} },
+/**/ {{0x5a8ea2cc, 0x3c8d94b9} },
+/**/ {{0x75459603, 0x3fe28c8c} },
+/**/ {{0x2945fc08, 0x3c8b1c3b} },
+/**/ {{0x79f37468, 0xbfd24fe6} },
+/**/ {{0x0ec1ef94, 0xbc4e3751} },
+/**/ {{0xe931c53b, 0x3fb38953} },
+/**/ {{0x16d80688, 0xbc3b108d} },
+/**/ {{0x5e1b50b5, 0x3f9b0ea2} },
+/**/ {{0x63fd1067, 0x3c0074c0} },
+/**/ {{0xa7fc7800, 0xbfa84621} },
+/**/ {{0xdd10256e, 0x3f9d7be4} },
+/**/ {{0xc9592c5e, 0xbf7364c0} },
+/**/ {{0xd318d707, 0xbf814271} },
+/**/ {{0x64d217b8, 0x3f838482} } },
+/**/ {{{0x00000000, 0x3feb6000} },
+/**/ {{0x6c4b0576, 0x3fe6a527} },
+/**/ {{0x9c46a69e, 0xbc8f6b65} },
+/**/ {{0xe5a55de9, 0x3fe27a43} },
+/**/ {{0xedc25d49, 0x3c66846e} },
+/**/ {{0x73c3b821, 0xbfd24135} },
+/**/ {{0x56ab5808, 0xbc79202a} },
+/**/ {{0xc0282c84, 0x3fb3a3e9} },
+/**/ {{0x03d25dab, 0x3c4057ca} },
+/**/ {{0xa3eb854d, 0x3f9a1d9e} },
+/**/ {{0xf03e2fb1, 0xbc3775ed} },
+/**/ {{0xd11d1043, 0xbfa7ede1} },
+/**/ {{0x195e6961, 0x3f9d5906} },
+/**/ {{0x65130256, 0xbf747373} },
+/**/ {{0xf77fd664, 0xbf80946d} },
+/**/ {{0xedc272c2, 0x3f8326f5} } },
+/**/ {{{0x00000000, 0x3feb8000} },
+/**/ {{0x920b3d99, 0x3fe6b798} },
+/**/ {{0x6188c50e, 0xbc8a8038} },
+/**/ {{0x10e5813e, 0x3fe2680a} },
+/**/ {{0x2242a6bc, 0xbc8f5497} },
+/**/ {{0xd725fa1c, 0xbfd23270} },
+/**/ {{0x5c781b14, 0x3c757282} },
+/**/ {{0x4bf2f124, 0x3fb3bd90} },
+/**/ {{0x6a14ed74, 0x3c31ae9c} },
+/**/ {{0x53ea1533, 0x3f99300b} },
+/**/ {{0x68f98d7e, 0x3c2a8d88} },
+/**/ {{0x53a4e537, 0xbfa7960d} },
+/**/ {{0x11f5f086, 0x3f9d3457} },
+/**/ {{0x19baa1da, 0xbf757760} },
+/**/ {{0xb2a2ca7e, 0xbf7fd36a} },
+/**/ {{0xc7a02081, 0x3f82c923} } },
+/**/ {{{0x00000000, 0x3feba000} },
+/**/ {{0x855c3198, 0x3fe6c9f7} },
+/**/ {{0x29bd280d, 0x3c7c09de} },
+/**/ {{0x0a431fbd, 0x3fe255df} },
+/**/ {{0xf09a745d, 0x3c8d9866} },
+/**/ {{0x5648fb1f, 0xbfd22399} },
+/**/ {{0xb4df0b3e, 0x3c412100} },
+/**/ {{0xfada8899, 0x3fb3d64a} },
+/**/ {{0x659c4346, 0x3c3dd891} },
+/**/ {{0x21c2d0a1, 0x3f9845e4} },
+/**/ {{0xf397827c, 0x3c28c6b1} },
+/**/ {{0x8445c1cc, 0xbfa73ea9} },
+/**/ {{0x730360f8, 0x3f9d0dea} },
+/**/ {{0xac51ce30, 0xbf7670bb} },
+/**/ {{0xeef50deb, 0xbf7e8493} },
+/**/ {{0x96b119a9, 0x3f826b25} } },
+/**/ {{{0x00000000, 0x3febc000} },
+/**/ {{0x551553af, 0x3fe6dc44} },
+/**/ {{0x3573828e, 0xbc5bf886} },
+/**/ {{0xe44a7335, 0x3fe243c2} },
+/**/ {{0x65d1ffd7, 0xbc667287} },
+/**/ {{0xa0ca68d3, 0xbfd214af} },
+/**/ {{0x88820895, 0xbc71296c} },
+/**/ {{0x36c0c9a2, 0x3fb3ee1d} },
+/**/ {{0x831dfabe, 0x3c540bf6} },
+/**/ {{0x8ce8de84, 0x3f975f24} },
+/**/ {{0x43eb5853, 0xbc125368} },
+/**/ {{0x803788f8, 0xbfa6e7bb} },
+/**/ {{0x8c42d5f9, 0x3f9ce5d2} },
+/**/ {{0xfaadb3ab, 0xbf775fba} },
+/**/ {{0xde4c28da, 0xbf7d3c59} },
+/**/ {{0xe2bf7ef5, 0x3f820d13} } },
+/**/ {{{0x00000000, 0x3febe000} },
+/**/ {{0x10204aef, 0x3fe6ee7f} },
+/**/ {{0xa3066272, 0x3c8692ee} },
+/**/ {{0xb0d95ee5, 0x3fe231b5} },
+/**/ {{0x1eb505b6, 0x3c7aae7e} },
+/**/ {{0x63ba3e08, 0xbfd205b4} },
+/**/ {{0xb975517d, 0x3c71c6d1} },
+/**/ {{0x64edc729, 0x3fb4050a} },
+/**/ {{0x715db809, 0x3c4960ed} },
+/**/ {{0xe2bc143b, 0x3f967bc7} },
+/**/ {{0xf0823143, 0xbc2cbf17} },
+/**/ {{0x2e4dbc47, 0xbfa69148} },
+/**/ {{0x50e0982e, 0x3f9cbc21} },
+/**/ {{0xedaa432a, 0xbf784492} },
+/**/ {{0x0b4850f3, 0xbf7bfabd} },
+/**/ {{0x1caa2f2c, 0x3f81af06} } },
+/**/ {{{0x00000000, 0x3fec0000} },
+/**/ {{0xc5784634, 0x3fe700a7} },
+/**/ {{0x25aadef6, 0xbc78c34d} },
+/**/ {{0x8121fb78, 0x3fe21fb7} },
+/**/ {{0x8121fb78, 0x3c621fb7} },
+/**/ {{0x499e4889, 0xbfd1f6a8} },
+/**/ {{0x6d4e0249, 0xbc60e934} },
+/**/ {{0xe5decb17, 0x3fb41b15} },
+/**/ {{0xab3541e6, 0x3c5194f4} },
+/**/ {{0x40a374b5, 0x3f959bc9} },
+/**/ {{0x54be0e10, 0xbc39dc6e} },
+/**/ {{0x400d3c9a, 0xbfa63b54} },
+/**/ {{0x57717232, 0x3f9c90e8} },
+/**/ {{0x6bfa704e, 0xbf791f78} },
+/**/ {{0x643da6dd, 0xbf7abfbc} },
+/**/ {{0xa418ed31, 0x3f815112} } },
+/**/ {{{0x00000000, 0x3fec2000} },
+/**/ {{0x84295198, 0x3fe712be} },
+/**/ {{0x337d8881, 0x3c85cd90} },
+/**/ {{0x65ad1f5b, 0x3fe20dc8} },
+/**/ {{0xd7b50d48, 0xbc88102a} },
+/**/ {{0xfa75d2f4, 0xbfd1e78b} },
+/**/ {{0x619624d2, 0x3c723734} },
+/**/ {{0x1517663e, 0x3fb43043} },
+/**/ {{0xe5e1ddf1, 0xbc4af8a4} },
+/**/ {{0x961cd605, 0x3f94bf23} },
+/**/ {{0x5ca14507, 0xbc26e86e} },
+/**/ {{0x32c1ffd7, 0xbfa5e5e4} },
+/**/ {{0xda0191cd, 0x3f9c6438} },
+/**/ {{0x4d921d2b, 0xbf79f0a0} },
+/**/ {{0x4e35d54e, 0xbf798b55} },
+/**/ {{0xcd4f7bfd, 0x3f80f34e} } },
+/**/ {{{0x00000000, 0x3fec4000} },
+/**/ {{0x5b4fae7b, 0x3fe724c3} },
+/**/ {{0x2db3499b, 0x3c5948b3} },
+/**/ {{0x6e5ce35d, 0x3fe1fbe8} },
+/**/ {{0x561e27a3, 0x3c8101d1} },
+/**/ {{0x1bbd70f4, 0xbfd1d860} },
+/**/ {{0xfa32c4d1, 0xbc7b4c97} },
+/**/ {{0x48f48a77, 0x3fb44495} },
+/**/ {{0xb47fdf89, 0xbc2ccfed} },
+/**/ {{0xa6c1af2c, 0x3f93e5d1} },
+/**/ {{0xc3b5a19b, 0xbc14af58} },
+/**/ {{0x5094795f, 0xbfa590fc} },
+/**/ {{0xb638ebc2, 0x3f9c3623} },
+/**/ {{0x4fa66d0e, 0xbf7ab83f} },
+/**/ {{0xb787e297, 0xbf785d83} },
+/**/ {{0xe71b4cea, 0x3f8095ce} } },
+/**/ {{{0x00000000, 0x3fec6000} },
+/**/ {{0x5a172dff, 0x3fe736b6} },
+/**/ {{0x06a892d1, 0x3c7775fd} },
+/**/ {{0xaa6f2377, 0x3fe1ea17} },
+/**/ {{0xcb44ec07, 0xbc8395a8} },
+/**/ {{0x5072ec76, 0xbfd1c925} },
+/**/ {{0xf650d5de, 0xbc6e11b3} },
+/**/ {{0xd281a42b, 0x3fb4580f} },
+/**/ {{0xf63226cb, 0xbc55bbce} },
+/**/ {{0x0c411254, 0x3f930fce} },
+/**/ {{0xc9852726, 0x3c3a4412} },
+/**/ {{0xb19e766e, 0xbfa53ca0} },
+/**/ {{0x6d941dd5, 0x3f9c06b9} },
+/**/ {{0x094128b2, 0xbf7b768a} },
+/**/ {{0x2a047c42, 0xbf773642} },
+/**/ {{0x40d7925f, 0x3f8038a6} } },
+/**/ {{{0x00000000, 0x3fec8000} },
+/**/ {{0x8fba8e0f, 0x3fe74897} },
+/**/ {{0x165884a1, 0x3c47b2a6} },
+/**/ {{0x287ffb8a, 0x3fe1d856} },
+/**/ {{0xfee27a9d, 0xbc658a1f} },
+/**/ {{0x39195240, 0xbfd1b9dc} },
+/**/ {{0x551dc6bf, 0x3c604646} },
+/**/ {{0xfd4fa866, 0x3fb46ab5} },
+/**/ {{0xc2febe43, 0x3c5f62a7} },
+/**/ {{0x384eda2c, 0x3f923d13} },
+/**/ {{0x1dfd9f34, 0x3c3b9a7c} },
+/**/ {{0x3cff324c, 0xbfa4e8d5} },
+/**/ {{0x25b0d0ad, 0x3f9bd60a} },
+/**/ {{0xe063d1e6, 0xbf7c2bb4} },
+/**/ {{0xdcb54dd5, 0xbf761589} },
+/**/ {{0x61077b85, 0x3f7fb7ce} } },
+/**/ {{{0x00000000, 0x3feca000} },
+/**/ {{0x0b82d8d8, 0x3fe75a67} },
+/**/ {{0x4c729087, 0x3c8ee4ac} },
+/**/ {{0xf68c4011, 0x3fe1c6a3} },
+/**/ {{0x32671c29, 0xbc8e54e4} },
+/**/ {{0x73bd1c8f, 0xbfd1aa85} },
+/**/ {{0x41d7bd80, 0x3c7525ad} },
+/**/ {{0x0f4e0cc0, 0x3fb47c8b} },
+/**/ {{0xd854875c, 0x3c2efdd1} },
+/**/ {{0x7688134d, 0x3f916d9b} },
+/**/ {{0x42a6f922, 0xbc1abef6} },
+/**/ {{0xa9ee694e, 0xbfa4959d} },
+/**/ {{0xa8aca118, 0x3f9ba425} },
+/**/ {{0xffb6fa1f, 0xbf7cd7f3} },
+/**/ {{0xc52e395a, 0xbf74fb52} },
+/**/ {{0x31d14661, 0x3f7eff46} } },
+/**/ {{{0x00000000, 0x3fecc000} },
+/**/ {{0xdcc6c6c0, 0x3fe76c24} },
+/**/ {{0x51adc83d, 0x3c819525} },
+/**/ {{0x21f3f28c, 0x3fe1b501} },
+/**/ {{0x5f1d67b6, 0xbc45712f} },
+/**/ {{0x9bf87a43, 0xbfd19b21} },
+/**/ {{0xb2071e48, 0xbc64520a} },
+/**/ {{0x48a59e43, 0x3fb48d92} },
+/**/ {{0x42014b8b, 0x3c5f8e56} },
+/**/ {{0xee4caccb, 0x3f90a160} },
+/**/ {{0x7b6daa67, 0x3c2bd92b} },
+/**/ {{0x80ce3489, 0xbfa442fd} },
+/**/ {{0x65959e45, 0x3f9b711b} },
+/**/ {{0x4cc2673a, 0xbf7d7b7b} },
+/**/ {{0xa86f8a8e, 0xbf73e793} },
+/**/ {{0xdf91602d, 0x3f7e47d4} } },
+/**/ {{{0x00000000, 0x3fece000} },
+/**/ {{0x12ea22c7, 0x3fe77dd1} },
+/**/ {{0x8fc10d3d, 0x3c873260} },
+/**/ {{0xb77cb1a2, 0x3fe1a36d} },
+/**/ {{0x6e625be9, 0xbc42c20d} },
+/**/ {{0x4af7b13c, 0xbfd18bb1} },
+/**/ {{0xbc063e5a, 0xbc68446b} },
+/**/ {{0xe3952cbb, 0x3fb49dce} },
+/**/ {{0x58cf9123, 0x3c588e60} },
+/**/ {{0x491cfa44, 0x3f8fb0bb} },
+/**/ {{0x0e3f2a43, 0x3c1534fc} },
+/**/ {{0x1c3b7aca, 0xbfa3f0f8} },
+/**/ {{0x70eb708a, 0x3f9b3cfa} },
+/**/ {{0x5eaa8b7f, 0xbf7e167e} },
+/**/ {{0x2b587c04, 0xbf72da42} },
+/**/ {{0x882fa65b, 0x3f7d9199} } },
+/**/ {{{0x00000000, 0x3fed0000} },
+/**/ {{0xbd5d315e, 0x3fe78f6b} },
+/**/ {{0x89803740, 0x3c8406a0} },
+/**/ {{0xc35424ca, 0x3fe191e9} },
+/**/ {{0xf4be863f, 0xbc8fa3c1} },
+/**/ {{0x177d9a85, 0xbfd17c35} },
+/**/ {{0x6a99d546, 0xbc717b81} },
+/**/ {{0x144fffae, 0x3fb4ad44} },
+/**/ {{0xdccca2a3, 0x3c3538b3} },
+/**/ {{0xfb2b5523, 0x3f8e2516} },
+/**/ {{0x60181bd9, 0x3c0f7c11} },
+/**/ {{0xaa1cc641, 0xbfa39f90} },
+/**/ {{0x85304289, 0x3f9b07d1} },
+/**/ {{0x756fd193, 0xbf7ea930} },
+/**/ {{0xe2a9a0de, 0xbf71d352} },
+/**/ {{0x886fc912, 0x3f7cdcb1} } },
+/**/ {{{0x00000000, 0x3fed2000} },
+/**/ {{0xeb9c19a2, 0x3fe7a0f4} },
+/**/ {{0xcd815f57, 0x3c613c67} },
+/**/ {{0x5112636f, 0x3fe18075} },
+/**/ {{0x7a335b20, 0x3c80a172} },
+/**/ {{0x95e83705, 0xbfd16cad} },
+/**/ {{0x7b21d5e1, 0x3c62a94b} },
+/**/ {{0x08de0a7c, 0x3fb4bbf5} },
+/**/ {{0x057457a0, 0x3c3570d0} },
+/**/ {{0x7d750fdf, 0x3f8c9fc8} },
+/**/ {{0xfe4cff3c, 0x3c2900a7} },
+/**/ {{0x2caf50ea, 0xbfa34eca} },
+/**/ {{0x03888c77, 0x3f9ad1af} },
+/**/ {{0x71ac3a86, 0xbf7f33c4} },
+/**/ {{0x6296fd58, 0xbf70d2b9} },
+/**/ {{0x886d16b8, 0x3f7c2938} } },
+/**/ {{{0x00000000, 0x3fed4000} },
+/**/ {{0xad2e50fe, 0x3fe7b26c} },
+/**/ {{0xf30411fb, 0xbc8ce80d} },
+/**/ {{0x6bbc577a, 0x3fe16f10} },
+/**/ {{0xbd8abf47, 0xbc7d0db6} },
+/**/ {{0x58355b5f, 0xbfd15d1b} },
+/**/ {{0xbcc70038, 0xbc5b5457} },
+/**/ {{0xe8fdd51d, 0x3fb4c9e4} },
+/**/ {{0x28ac9383, 0x3c462959} },
+/**/ {{0x2029f143, 0x3f8b20c3} },
+/**/ {{0x2b420400, 0xbc2f8a44} },
+/**/ {{0x7b921c49, 0xbfa2fea7} },
+/**/ {{0xf468e79e, 0x3f9a9aa0} },
+/**/ {{0xcccbcb4f, 0xbf7fb66c} },
+/**/ {{0x9bd39a5f, 0xbf6fb0d0} },
+/**/ {{0x8813998f, 0x3f7b7748} } },
+/**/ {{{0x00000000, 0x3fed6000} },
+/**/ {{0x11a6092b, 0x3fe7c3d3} },
+/**/ {{0x2d303288, 0x3c8bb3cb} },
+/**/ {{0x1dc61b17, 0x3fe15dbb} },
+/**/ {{0xbb77dc56, 0xbc8f0487} },
+/**/ {{0xee0771ca, 0xbfd14d7e} },
+/**/ {{0xdc2fcbd0, 0x3c72d38b} },
+/**/ {{0xd6080f0e, 0x3fb4d716} },
+/**/ {{0xa9fbc2c3, 0xbc5cb5bc} },
+/**/ {{0xfc42e02f, 0x3f89a7f9} },
+/**/ {{0x857be8a4, 0xbc201eec} },
+/**/ {{0x44ceebb3, 0xbfa2af2b} },
+/**/ {{0x08511639, 0x3f9a62b5} },
+/**/ {{0xc8de23de, 0xbf8018ad} },
+/**/ {{0xc964501a, 0xbf6dc8a2} },
+/**/ {{0xeb913697, 0x3f7ac6f9} } },
+/**/ {{{0x00000000, 0x3fed8000} },
+/**/ {{0x289fa093, 0x3fe7d528} },
+/**/ {{0x1e2f3aa9, 0x3c856082} },
+/**/ {{0x711551bb, 0x3fe14c75} },
+/**/ {{0x71970f2c, 0xbc80c88e} },
+/**/ {{0xe4aa5095, 0xbfd13dd8} },
+/**/ {{0xb4b7ae12, 0x3c66dd31} },
+/**/ {{0xead4c211, 0x3fb4e38d} },
+/**/ {{0xe392a31e, 0x3c513fb0} },
+/**/ {{0xf6b74576, 0x3f88355f} },
+/**/ {{0xf3561ab7, 0x3ba8cb44} },
+/**/ {{0x0de0faaa, 0xbfa26058} },
+/**/ {{0x989371f0, 0x3f9a29f8} },
+/**/ {{0x2b085d9a, 0xbf805261} },
+/**/ {{0x2511c555, 0xbf6beccb} },
+/**/ {{0x87b9d333, 0x3f7a1863} } },
+/**/ {{{0x00000000, 0x3feda000} },
+/**/ {{0x01c114fe, 0x3fe7e66c} },
+/**/ {{0x8b760b8d, 0xbc8c82b8} },
+/**/ {{0x6f037c44, 0x3fe13b3f} },
+/**/ {{0x8562c8c0, 0xbc635393} },
+/**/ {{0xc7182435, 0xbfd12e29} },
+/**/ {{0x0d0fda95, 0xbc73da80} },
+/**/ {{0x3ba21a8b, 0x3fb4ef4d} },
+/**/ {{0x9aa41146, 0xbc17c450} },
+/**/ {{0xc39dff46, 0x3f86c8e7} },
+/**/ {{0x800ba9ae, 0x3c1ddd70} },
+/**/ {{0x34b94b56, 0xbfa21230} },
+/**/ {{0xa827f95a, 0x3f99f078} },
+/**/ {{0x19caa997, 0xbf808869} },
+/**/ {{0xf8c46d26, 0xbf6a1d29} },
+/**/ {{0xae59da17, 0x3f796b9a} } },
+/**/ {{{0x00000000, 0x3fedc000} },
+/**/ {{0xacb97898, 0x3fe7f79e} },
+/**/ {{0x80ead221, 0x3c8fd5ca} },
+/**/ {{0x20604825, 0x3fe12a19} },
+/**/ {{0xa18970f8, 0xbc5cc7d6} },
+/**/ {{0x1dfe6ba4, 0xbfd11e72} },
+/**/ {{0x9d653d1c, 0x3c706717} },
+/**/ {{0xd5fcbb3b, 0x3fb4fa57} },
+/**/ {{0x5f50bc06, 0x3c1922c8} },
+/**/ {{0xe93a179f, 0x3f856283} },
+/**/ {{0x5ea7135a, 0xbc01c2ec} },
+/**/ {{0xf0c06b4f, 0xbfa1c4b5} },
+/**/ {{0xe48a3b04, 0x3f99b641} },
+/**/ {{0xe1280a21, 0xbf80badd} },
+/**/ {{0x1be3c5dd, 0xbf68599e} },
+/**/ {{0x3a72c8e6, 0x3f78c0b3} } },
+/**/ {{{0x00000000, 0x3fede000} },
+/**/ {{0x3940694b, 0x3fe808c0} },
+/**/ {{0x7715f6a5, 0xbc800f32} },
+/**/ {{0x8d73d98e, 0x3fe11902} },
+/**/ {{0x30f8e290, 0x3c71d158} },
+/**/ {{0x6fc305eb, 0xbfd10eb2} },
+/**/ {{0x3858c4b7, 0xbc7fd2e3} },
+/**/ {{0xc0a99255, 0x3fb504b0} },
+/**/ {{0x142e134f, 0x3c55c054} },
+/**/ {{0xc2f371cf, 0x3f840226} },
+/**/ {{0xfc7d6225, 0xbbfc85b0} },
+/**/ {{0x53d58f53, 0xbfa177eb} },
+/**/ {{0xa6a1627d, 0x3f997b60} },
+/**/ {{0x89757c78, 0xbf80e9d7} },
+/**/ {{0x0d433cd6, 0xbf66a205} },
+/**/ {{0x9c5dbd9f, 0x3f7817bf} } },
+/**/ {{{0x00000000, 0x3fee0000} },
+/**/ {{0xb7158a4d, 0x3fe819d0} },
+/**/ {{0x29d3b917, 0xbc7bf762} },
+/**/ {{0xbe011080, 0x3fe107fb} },
+/**/ {{0xbe011080, 0xbc8107fb} },
+/**/ {{0x40894fcd, 0xbfd0feeb} },
+/**/ {{0xc155af9a, 0x3c76fbb9} },
+/**/ {{0xfb9125f7, 0x3fb50e5a} },
+/**/ {{0x2f3313b0, 0x3c357762} },
+/**/ {{0x843ba55a, 0x3f82a7c2} },
+/**/ {{0x3fc197b7, 0x3c1f4994} },
+/**/ {{0x4b4ae875, 0xbfa12bd2} },
+/**/ {{0xf3b1b1ee, 0x3f993fe0} },
+/**/ {{0xd4c2083b, 0xbf81156d} },
+/**/ {{0x0c35aa9c, 0xbf64f63b} },
+/**/ {{0xe5d0462f, 0x3f7770d0} } },
+/**/ {{{0x00000000, 0x3fee2000} },
+/**/ {{0x36000005, 0x3fe82ad0} },
+/**/ {{0xce924d24, 0x3c74592f} },
+/**/ {{0xb947c8b7, 0x3fe0f704} },
+/**/ {{0x48a651b3, 0x3c436cd7} },
+/**/ {{0x1237505b, 0xbfd0ef1d} },
+/**/ {{0x1b86b9d1, 0x3c69239b} },
+/**/ {{0x7fac4e21, 0x3fb51759} },
+/**/ {{0xbfce0e36, 0xbc42a8cc} },
+/**/ {{0x3b5f3edd, 0x3f815349} },
+/**/ {{0x88c702d9, 0xbc25e1f1} },
+/**/ {{0xa0df17a9, 0xbfa0e06c} },
+/**/ {{0x7e56b8b1, 0x3f9903ce} },
+/**/ {{0x3c701e30, 0xbf813db8} },
+/**/ {{0x30c99e47, 0xbf63561b} },
+/**/ {{0xd5bffce0, 0x3f76cbf6} } },
+/**/ {{{0x00000000, 0x3fee4000} },
+/**/ {{0xc5cdee22, 0x3fe83bbe} },
+/**/ {{0x04ffc6c3, 0x3c631071} },
+/**/ {{0x86071468, 0x3fe0e61d} },
+/**/ {{0x59be09c9, 0xbc70ccc4} },
+/**/ {{0x647af38b, 0xbfd0df48} },
+/**/ {{0x427c295b, 0x3c7dd47c} },
+/**/ {{0x3ef25277, 0x3fb51faf} },
+/**/ {{0xa81026a7, 0x3bdf056a} },
+/**/ {{0xd443a18b, 0x3f8004ac} },
+/**/ {{0x8178f329, 0x3c027610} },
+/**/ {{0xfbb3a658, 0xbfa095bb} },
+/**/ {{0xa7859d46, 0x3f98c734} },
+/**/ {{0xeefe9a81, 0xbf8162cd} },
+/**/ {{0x8330eac0, 0xbf61c17f} },
+/**/ {{0xe421c20a, 0x3f76293f} } },
+/**/ {{{0x00000000, 0x3fee6000} },
+/**/ {{0x7653f7eb, 0x3fe84c9c} },
+/**/ {{0xfe0a3e8f, 0xbc383611} },
+/**/ {{0x2a7f71b5, 0x3fe0d546} },
+/**/ {{0x596848c6, 0x3c757061} },
+/**/ {{0xb4cf51a6, 0xbfd0cf6d} },
+/**/ {{0x5b18bb8c, 0x3c4c99ab} },
+/**/ {{0x24486227, 0x3fb5275f} },
+/**/ {{0xbb1f4f56, 0x3c5b4a59} },
+/**/ {{0x36238bb2, 0x3f7d77be} },
+/**/ {{0xcaec6ba2, 0x3c1ddbd1} },
+/**/ {{0xe1406cd0, 0xbfa04bc1} },
+/**/ {{0x7f96d6ca, 0x3f988a1e} },
+/**/ {{0xcdffc380, 0xbf8184c5} },
+/**/ {{0x12561f8b, 0xbf603841} },
+/**/ {{0x4d81a668, 0x3f7588b9} } },
+/**/ {{{0x00000000, 0x3fee8000} },
+/**/ {{0x576cc2c5, 0x3fe85d69} },
+/**/ {{0x7fc8b8c3, 0x3c66b66e} },
+/**/ {{0xac74fadc, 0x3fe0c47e} },
+/**/ {{0x77bb1887, 0xbc8035f8} },
+/**/ {{0x7e8202a9, 0xbfd0bf8d} },
+/**/ {{0x1f4d2357, 0x3c798048} },
+/**/ {{0x13725c73, 0x3fb52e6c} },
+/**/ {{0xf5b19ded, 0xbc34c3af} },
+/**/ {{0x7d9c2711, 0x3f7af1a3} },
+/**/ {{0x1af1098d, 0x3bea7ec7} },
+/**/ {{0xb643d11f, 0xbfa0027f} },
+/**/ {{0xc756b7d7, 0x3f984c96} },
+/**/ {{0x6c3ca3ae, 0xbf81a3b6} },
+/**/ {{0x13459246, 0xbf5d7470} },
+/**/ {{0x1e70d9a4, 0x3f74ea6f} } },
+/**/ {{{0x00000000, 0x3feea000} },
+/**/ {{0x78f87ae5, 0x3fe86e25} },
+/**/ {{0x375cfe34, 0x3c8022b1} },
+/**/ {{0x11319104, 0x3fe0b3c7} },
+/**/ {{0x25152519, 0x3c8ac394} },
+/**/ {{0x3ab87c8a, 0xbfd0afa8} },
+/**/ {{0x27b31384, 0x3c724f26} },
+/**/ {{0xe904e078, 0x3fb534d8} },
+/**/ {{0xf8948323, 0xbc55bfde} },
+/**/ {{0xa7bb2dfb, 0x3f7876ec} },
+/**/ {{0x8a87be50, 0xbc197116} },
+/**/ {{0x7f5f95b4, 0xbf9f73ed} },
+/**/ {{0xf11c3266, 0x3f980ea7} },
+/**/ {{0x0c032389, 0xbf81bfb6} },
+/**/ {{0x8bf305a1, 0xbf5a8e77} },
+/**/ {{0x3ec72e6d, 0x3f744e6c} } },
+/**/ {{{0x00000000, 0x3feec000} },
+/**/ {{0xeadc5a2a, 0x3fe87ed0} },
+/**/ {{0xd957f4bc, 0x3c70af5a} },
+/**/ {{0x5d8701b3, 0x3fe0a31f} },
+/**/ {{0x263ce937, 0xbc869b25} },
+/**/ {{0x60757b83, 0xbfd09fbe} },
+/**/ {{0xa96db9ef, 0x3c767aff} },
+/**/ {{0x7a589afb, 0x3fb53aa8} },
+/**/ {{0x0844ff86, 0xbc4b7e8e} },
+/**/ {{0xacf1a65c, 0x3f76077c} },
+/**/ {{0xb13331a9, 0xbc19a3b2} },
+/**/ {{0x472733eb, 0xbf9ee450} },
+/**/ {{0x21e541d7, 0x3f97d05c} },
+/**/ {{0x9d9d4dfc, 0xbf81d8da} },
+/**/ {{0xd3ce1b4a, 0xbf57be45} },
+/**/ {{0x7cb60047, 0x3f73b4ba} } },
+/**/ {{{0x00000000, 0x3feee000} },
+/**/ {{0xbd023119, 0x3fe88f6b} },
+/**/ {{0x25aba660, 0xbc532d1d} },
+/**/ {{0x95d126c6, 0x3fe09287} },
+/**/ {{0xeccc37a6, 0x3c85aad3} },
+/**/ {{0x649e7367, 0xbfd08fd0} },
+/**/ {{0xed21a127, 0x3c71e96c} },
+/**/ {{0x957ec910, 0x3fb53fdd} },
+/**/ {{0xaf97a601, 0xbc339c23} },
+/**/ {{0x5a18e5a2, 0x3f73a336} },
+/**/ {{0x477571de, 0xbc1f7225} },
+/**/ {{0xd4044135, 0xbf9e5629} },
+/**/ {{0x32786dc4, 0x3f9791bd} },
+/**/ {{0xbdf030c4, 0xbf81ef39} },
+/**/ {{0xe21b8bcb, 0xbf550386} },
+/**/ {{0x97aa7fb2, 0x3f731d62} } },
+/**/ {{{0x00000000, 0x3fef0000} },
+/**/ {{0xff57f1f8, 0x3fe89ff5} },
+/**/ {{0x5e177a1b, 0xbc855b9a} },
+/**/ {{0xbdf80108, 0x3fe081ff} },
+/**/ {{0x80108200, 0x3c6ffbdf} },
+/**/ {{0xba010928, 0xbfd07fde} },
+/**/ {{0x7bae0295, 0x3c38d37f} },
+/**/ {{0x0136e69f, 0x3fb5447b} },
+/**/ {{0x0dda278d, 0x3c50316a} },
+/**/ {{0x55103947, 0x3f7149fc} },
+/**/ {{0x849e505f, 0x3c176e96} },
+/**/ {{0xfbe9a2ee, 0xbf9dc97b} },
+/**/ {{0xb08adda9, 0x3f9752d4} },
+/**/ {{0xb540d106, 0xbf8202e8} },
+/**/ {{0x859de3e9, 0xbf525de5} },
+/**/ {{0x4afd9f21, 0x3f72886c} } },
+/**/ {{{0x00000000, 0x3fef2000} },
+/**/ {{0xc1cf3dff, 0x3fe8b06f} },
+/**/ {{0x2656db6d, 0xbc80fb31} },
+/**/ {{0xd971cd38, 0x3fe07187} },
+/**/ {{0x202c20ac, 0x3c89baa4} },
+/**/ {{0xd15893ab, 0xbfd06fe9} },
+/**/ {{0xdc0cb586, 0xbc7a864b} },
+/**/ {{0x7ce57fed, 0x3fb54883} },
+/**/ {{0x294f4b18, 0xbc49498e} },
+/**/ {{0x426ebecc, 0x3f6df762} },
+/**/ {{0xf28644c0, 0xbc022f08} },
+/**/ {{0x5c564b44, 0xbf9d3e48} },
+/**/ {{0xdfea7acf, 0x3f9713ab} },
+/**/ {{0x761db35c, 0xbf8213fc} },
+/**/ {{0x10d60f49, 0xbf4f9a17} },
+/**/ {{0x58700e9b, 0x3f71f5de} } },
+/**/ {{{0x00000000, 0x3fef4000} },
+/**/ {{0x145cf49d, 0x3fe8c0d9} },
+/**/ {{0x76dc4333, 0x3c8bea40} },
+/**/ {{0xeb45139a, 0x3fe0611f} },
+/**/ {{0x65aadb1f, 0x3c7e4998} },
+/**/ {{0x1953a316, 0xbfd05ff2} },
+/**/ {{0xa1b67b0f, 0x3c759922} },
+/**/ {{0xc08c1d66, 0x3fb54bf9} },
+/**/ {{0xd220330c, 0x3c5b9353} },
+/**/ {{0x478cb604, 0x3f69706e} },
+/**/ {{0xa22fd45a, 0xbbfdb6d3} },
+/**/ {{0x5c0d1d38, 0xbf9cb490} },
+/**/ {{0xbbaba2f2, 0x3f96d44b} },
+/**/ {{0x9c6b7de1, 0xbf822289} },
+/**/ {{0xa49803b6, 0xbf4aa143} },
+/**/ {{0x9270e49e, 0x3f7165be} } },
+/**/ {{{0x00000000, 0x3fef6000} },
+/**/ {{0x06f8c4cb, 0x3fe8d132} },
+/**/ {{0xbaa89a8b, 0xbc7b018c} },
+/**/ {{0xf60ab1f4, 0x3fe050c7} },
+/**/ {{0xc6cf5796, 0x3c63f8e2} },
+/**/ {{0xfe998dc0, 0xbfd04ff7} },
+/**/ {{0x7dc56419, 0x3c77873c} },
+/**/ {{0x7cc24121, 0x3fb54ee0} },
+/**/ {{0x8e5c84c5, 0x3c313117} },
+/**/ {{0x50066301, 0x3f64fee1} },
+/**/ {{0x017261a1, 0x3c043698} },
+/**/ {{0x2cc5b4f1, 0xbf9c2c55} },
+/**/ {{0xf759f369, 0x3f9694bc} },
+/**/ {{0x6c93426a, 0xbf822ea4} },
+/**/ {{0x135d6c51, 0xbf45d0a1} },
+/**/ {{0xe62dc18f, 0x3f70d811} } },
+/**/ {{{0x00000000, 0x3fef8000} },
+/**/ {{0xa99cc05e, 0x3fe8e17a} },
+/**/ {{0xab042f61, 0xbc7ec182} },
+/**/ {{0xfbefe001, 0x3fe0407f} },
+/**/ {{0xfbf80041, 0x3c401ffe} },
+/**/ {{0xebd00209, 0xbfd03ffb} },
+/**/ {{0xb9004112, 0xbc53ff3c} },
+/**/ {{0x5aaf6d91, 0x3fb5513a} },
+/**/ {{0xc0516ddb, 0x3c54a20d} },
+/**/ {{0xc6ac4038, 0x3f60a27f} },
+/**/ {{0x2a340912, 0x3bf06bee} },
+/**/ {{0xccd6032a, 0xbf9ba597} },
+/**/ {{0x002bb974, 0x3f965508} },
+/**/ {{0xd2d1068b, 0xbf823860} },
+/**/ {{0x666265bc, 0xbf41277e} },
+/**/ {{0x656b66ea, 0x3f704cdc} } },
+/**/ {{{0x00000000, 0x3fefa000} },
+/**/ {{0x0c44f167, 0x3fe8f1b3} },
+/**/ {{0xb93933fd, 0x3c6dd1ca} },
+/**/ {{0xfeb82e4e, 0x3fe03047} },
+/**/ {{0x5272e5ac, 0x3c69ee56} },
+/**/ {{0x49a09c45, 0xbfd02ffe} },
+/**/ {{0xb26267bb, 0xbc700a59} },
+/**/ {{0xfc062d2f, 0x3fb55309} },
+/**/ {{0xb11938e0, 0x3c5dba48} },
+/**/ {{0xe4f365be, 0x3f58b61b} },
+/**/ {{0xa79ad31a, 0x3bf8b585} },
+/**/ {{0x08d4ad17, 0xbf9b2059} },
+/**/ {{0xfe379940, 0x3f961534} },
+/**/ {{0x62a1270e, 0xbf823fd2} },
+/**/ {{0x3f3a0aec, 0xbf394a53} },
+/**/ {{0xa04bcae2, 0x3f6f8842} } },
+/**/ {{{0x00000000, 0x3fefc000} },
+/**/ {{0x3eeef187, 0x3fe901db} },
+/**/ {{0xe5603c8f, 0x3c868665} },
+/**/ {{0xffbf7f80, 0x3fe0201f} },
+/**/ {{0xffbf7f80, 0x3c20201f} },
+/**/ {{0x7ebe8004, 0xbfd01fff} },
+/**/ {{0xcf979001, 0xbc4213ff} },
+/**/ {{0xfb0012db, 0x3fb55451} },
+/**/ {{0xf73aa59f, 0xbc395606} },
+/**/ {{0xfc757100, 0x3f50509f} },
+/**/ {{0xfee554d0, 0x3bebc7da} },
+/**/ {{0x7d3424d0, 0xbf9a9c99} },
+/**/ {{0xd5ac0217, 0x3f95d54b} },
+/**/ {{0x564b3c49, 0xbf82450c} },
+/**/ {{0xe6d3e986, 0xbf3091df} },
+/**/ {{0x3bef5a22, 0x3f6e7bc6} } },
+/**/ {{{0x00000000, 0x3fefe000} },
+/**/ {{0x5199833b, 0x3fe911f3} },
+/**/ {{0x0edbf522, 0x3c63ae8a} },
+/**/ {{0xfffbfbfe, 0x3fe01007} },
+/**/ {{0xfffbfbfe, 0x3ba01007} },
+/**/ {{0xefebf400, 0xbfd00fff} },
+/**/ {{0xfff9f97d, 0xbc401209} },
+/**/ {{0xea5aaaf6, 0x3fb55514} },
+/**/ {{0xb5b7b240, 0xbc529baa} },
+/**/ {{0xffc7abc4, 0x3f402827} },
+/**/ {{0xbfee6ab3, 0x3b5ba3d6} },
+/**/ {{0x97d67093, 0xbf9a1a59} },
+/**/ {{0x28080aaf, 0x3f959554} },
+/**/ {{0x8e892ce2, 0xbf824821} },
+/**/ {{0xfe70a2a6, 0xbf204877} },
+/**/ {{0x0e8ddd67, 0x3f6d7447} } },
+/**/ {{{0x00000000, 0x3feff800} },
+/**/ {{0xd439826e, 0x3fe91dfa} },
+/**/ {{0x6df48d55, 0xbc786a19} },
+/**/ {{0x7ffffbff, 0x3fe00400} },
+/**/ {{0xffbff800, 0xbbeffffe} },
+/**/ {{0xffbfebfd, 0xbfd003ff} },
+/**/ {{0x9ffff9fe, 0xbb600480} },
+/**/ {{0x53aa5aab, 0x3fb55551} },
+/**/ {{0x9baaab5b, 0xbc542a4a} },
+/**/ {{0x7fffc7eb, 0x3f200a02} },
+/**/ {{0x4770e940, 0xbb7dfffe} },
+/**/ {{0x9997d8d0, 0xbf99b9a5} },
+/**/ {{0x50a80a03, 0x3f956555} },
+/**/ {{0x86456493, 0xbf824914} },
+/**/ {{0x7ffe7329, 0xbf001207} },
+/**/ {{0x1c63fe2a, 0x3f6cb1ef} } },
+ };
+
+#endif
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/uexp.h b/libc/sysdeps/ieee754/dbl-64/uexp.h
new file mode 100644
index 000000000..de6f4f8ce
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/uexp.h
@@ -0,0 +1,70 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/******************************************************************/
+/* */
+/* MODULE_NAME:uexp.h */
+/* */
+/* common data and variables prototype and definition */
+/******************************************************************/
+
+#ifndef UEXP_H
+#define UEXP_H
+
+#include "mydefs.h"
+
+const static double one = 1.0, zero = 0.0, hhuge = 1.0e300, tiny = 1.0e-300,
+err_0 = 1.000014, err_1 = 0.000016;
+const static int4 bigint = 0x40862002,
+ badint = 0x40876000,smallint = 0x3C8fffff;
+const static int4 hugeint = 0x7FFFFFFF, infint = 0x7ff00000;
+
+#ifdef BIG_ENDI
+const static mynumber inf = {{0x7FF00000, 0}}; /* inf */
+const static mynumber t256 = {{0x4ff00000, 0}}; /* 2^256 */
+
+const static mynumber ln_two1 = {{0x3FE62E42, 0xFEFA3800}};/*0.69314718055989033 */
+const static mynumber ln_two2 = {{0x3D2EF357, 0x93C76730}};/*5.4979230187083712e-14*/
+const static mynumber log2e = {{0x3FF71547, 0x652B82FE}};/* 1.4426950408889634 */
+
+const static mynumber p2 = {{0x3FE00000, 0x000004DC}};/* 0.50000000000013811 */
+const static mynumber p3 = {{0x3FC55555, 0x55555A0F}};/* 0.16666666666670024 */
+
+const static mynumber three33 = {{0x42180000, 0}}; /* 25769803776 */
+const static mynumber three51 = {{0x43380000, 0}}; /* 6755399441055744 */
+
+#else
+#ifdef LITTLE_ENDI
+ const static mynumber inf = {{0, 0x7FF00000}}; /* inf */
+ const static mynumber t256 = {{0, 0x4ff00000}}; /* 2^256 */
+
+ const static mynumber ln_two1 = {{0xFEFA3800, 0x3FE62E42}};/*0.69314718055989033 */
+ const static mynumber ln_two2 = {{0x93C76730, 0x3D2EF357}};/*5.4979230187083712e-14*/
+ const static mynumber log2e = {{0x652B82FE, 0x3FF71547}};/* 1.4426950408889634 */
+
+ const static mynumber p2 = {{0x000004DC, 0x3FE00000}};/* 0.50000000000013811 */
+ const static mynumber p3 = {{0x55555A0F, 0x3FC55555}};/* 0.16666666666670024 */
+
+ const static mynumber three33 = {{0, 0x42180000}}; /* 25769803776 */
+ const static mynumber three51 = {{0, 0x43380000}}; /* 6755399441055744 */
+
+#endif
+#endif
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/uexp.tbl b/libc/sysdeps/ieee754/dbl-64/uexp.tbl
new file mode 100644
index 000000000..f2e8e8f55
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/uexp.tbl
@@ -0,0 +1,1787 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/****************************************************************/
+/* TABLES FOR THE ulog() FUNCTION */
+/****************************************************************/
+
+#ifdef BIG_ENDI
+
+static const union {
+ int i[1424];
+ double x[712];
+} coar = { .i = {
+ 0x3FE69A59, 0xC8000000, 0x3DF22D4D, 0x6079C9F7,
+ 0x3FE6A5A9, 0xC8000000, 0x3E19882D, 0x25AF6823,
+ 0x3FE6B0FF, 0x74000000, 0xBE221476, 0x31DABF59,
+ 0x3FE6BC5A, 0xC8000000, 0x3E2312AC, 0x99A2DC0A,
+ 0x3FE6C7BB, 0xD0000000, 0xBE265926, 0xCE9F9355,
+ 0x3FE6D322, 0x84000000, 0x3E2F2C26, 0x2D298DED,
+ 0x3FE6DE8E, 0xF4000000, 0xBE2EC28E, 0x1E748D2F,
+ 0x3FE6EA01, 0x14000000, 0x3E2D8C6D, 0xC68CB7E5,
+ 0x3FE6F578, 0xF4000000, 0x3DEE1A9E, 0x419FE2F0,
+ 0x3FE700F6, 0x90000000, 0xBDFF1AFD, 0xDEAEAE34,
+ 0x3FE70C79, 0xEC000000, 0xBE0730FE, 0x558B7122,
+ 0x3FE71803, 0x0C000000, 0xBE25CB85, 0x2D280C3B,
+ 0x3FE72391, 0xF0000000, 0xBE06F2CE, 0x337B7B54,
+ 0x3FE72F26, 0x9C000000, 0x3E289BCA, 0x45C02B72,
+ 0x3FE73AC1, 0x18000000, 0xBE18DEA6, 0x5039F1CA,
+ 0x3FE74661, 0x60000000, 0xBE09D090, 0x86CE0538,
+ 0x3FE75207, 0x78000000, 0x3E290E79, 0xCFCE5DDB,
+ 0x3FE75DB3, 0x68000000, 0x3DD61DF0, 0xB249A17C,
+ 0x3FE76965, 0x2C000000, 0x3E2F22F7, 0xE13445F7,
+ 0x3FE7751C, 0xD0000000, 0xBE2CD454, 0x874E75CE,
+ 0x3FE780DA, 0x4C000000, 0xBE0159CE, 0xDF43E3BC,
+ 0x3FE78C9D, 0xA8000000, 0x3E279291, 0x699A1332,
+ 0x3FE79866, 0xEC000000, 0xBE2A0BCD, 0x2DD98C6C,
+ 0x3FE7A436, 0x10000000, 0x3E25F375, 0x15AC979E,
+ 0x3FE7B00B, 0x20000000, 0x3E26CCF5, 0x2FEAFCF6,
+ 0x3FE7BBE6, 0x1C000000, 0x3E27D4F4, 0x53ADAD67,
+ 0x3FE7C7C7, 0x08000000, 0x3E10EEC7, 0x7FBD9566,
+ 0x3FE7D3AD, 0xE4000000, 0x3E2837F0, 0x9A831D86,
+ 0x3FE7DF9A, 0xB8000000, 0xBE129BE0, 0x5CB4C35B,
+ 0x3FE7EB8D, 0x80000000, 0x3E23990A, 0x0234F04D,
+ 0x3FE7F786, 0x44000000, 0x3E2EB807, 0x64D5C842,
+ 0x3FE80385, 0x08000000, 0x3E0FC86F, 0x02B4E9E8,
+ 0x3FE80F89, 0xCC000000, 0xBDD7B5B3, 0x7B4274BF,
+ 0x3FE81B94, 0x94000000, 0xBE16888B, 0xB899B00F,
+ 0x3FE827A5, 0x60000000, 0x3E288971, 0x5E94D155,
+ 0x3FE833BC, 0x38000000, 0x3E2AEEB2, 0x099F3E5E,
+ 0x3FE83FD9, 0x20000000, 0xBE23B922, 0x3FF60B7C,
+ 0x3FE84BFC, 0x14000000, 0xBDF7D3B1, 0x2DBD8012,
+ 0x3FE85825, 0x1C000000, 0xBDF24BA3, 0xA8872BEB,
+ 0x3FE86454, 0x38000000, 0x3E2EFE04, 0x01AA18A7,
+ 0x3FE87089, 0x70000000, 0x3E21986C, 0x944496A2,
+ 0x3FE87CC4, 0xC4000000, 0x3E096A8B, 0xB71FFAFF,
+ 0x3FE88906, 0x38000000, 0xBE21CE0A, 0xBC4C7AC5,
+ 0x3FE8954D, 0xCC000000, 0xBE076F45, 0xBAC02491,
+ 0x3FE8A19B, 0x84000000, 0x3E2B4FA2, 0xD922B925,
+ 0x3FE8ADEF, 0x68000000, 0x3DF759DB, 0x641863AF,
+ 0x3FE8BA49, 0x78000000, 0xBE2DB97C, 0xC6AB5E04,
+ 0x3FE8C6A9, 0xB4000000, 0xBE25364C, 0xE2156713,
+ 0x3FE8D310, 0x20000000, 0x3E1BEB7C, 0x862BEFF7,
+ 0x3FE8DF7C, 0xC4000000, 0xBDF4DD0C, 0x1CEA33A5,
+ 0x3FE8EBEF, 0xA0000000, 0xBE2537DF, 0x51797D47,
+ 0x3FE8F868, 0xB4000000, 0x3E0FB1C4, 0xF0107B28,
+ 0x3FE904E8, 0x08000000, 0x3E0AD6A1, 0xE01B68BD,
+ 0x3FE9116D, 0x9C000000, 0x3E292117, 0x1F78D9D9,
+ 0x3FE91DF9, 0x78000000, 0xBE1D75DA, 0x4F50E5CF,
+ 0x3FE92A8B, 0x98000000, 0x3DE5102B, 0x74959E58,
+ 0x3FE93724, 0x04000000, 0xBE01CA50, 0xD2216C35,
+ 0x3FE943C2, 0xBC000000, 0x3E225BFD, 0xB0B05884,
+ 0x3FE95067, 0xC8000000, 0xBE0F2183, 0x60B7C5C1,
+ 0x3FE95D13, 0x24000000, 0x3E2FB47A, 0xB5860441,
+ 0x3FE969C4, 0xDC000000, 0xBE01FFD2, 0xE2D4059E,
+ 0x3FE9767C, 0xEC000000, 0xBDE9ED72, 0x12BB6A8D,
+ 0x3FE9833B, 0x58000000, 0x3E2B3815, 0x43BFFB24,
+ 0x3FE99000, 0x28000000, 0x3E03FA22, 0xEE9EAD1E,
+ 0x3FE99CCB, 0x5C000000, 0xBE213841, 0x377138F7,
+ 0x3FE9A99C, 0xF4000000, 0x3E178105, 0xDB636C94,
+ 0x3FE9B674, 0xF8000000, 0x3E1E5E7A, 0xF5720122,
+ 0x3FE9C353, 0x6C000000, 0xBE238BFF, 0xA2AC5AAE,
+ 0x3FE9D038, 0x4C000000, 0x3E270893, 0xF93BDBD8,
+ 0x3FE9DD23, 0xA4000000, 0x3DF40420, 0x354B86CF,
+ 0x3FE9EA15, 0x74000000, 0xBE2D76D3, 0x88CB06B7,
+ 0x3FE9F70D, 0xBC000000, 0xBE251639, 0x9ED0EC60,
+ 0x3FEA040C, 0x80000000, 0x3E1F06E9, 0xE2DDE506,
+ 0x3FEA1111, 0xC8000000, 0x3E014549, 0x8E6DB477,
+ 0x3FEA1E1D, 0x94000000, 0xBDF4BC17, 0xF8716509,
+ 0x3FEA2B2F, 0xE8000000, 0xBE2107DB, 0xDA723A49,
+ 0x3FEA3848, 0xC4000000, 0x3E1A932A, 0x986AA369,
+ 0x3FEA4568, 0x30000000, 0x3E198092, 0x41592CDB,
+ 0x3FEA528E, 0x30000000, 0xBE2E260F, 0x676BCAB8,
+ 0x3FEA5FBA, 0xC0000000, 0x3DE2E821, 0x2D5D5610,
+ 0x3FEA6CED, 0xE8000000, 0x3E2F7046, 0x7DA20167,
+ 0x3FEA7A27, 0xB0000000, 0xBE1D2832, 0xF9FAAD30,
+ 0x3FEA8768, 0x14000000, 0xBE23F788, 0x43FA6C45,
+ 0x3FEA94AF, 0x18000000, 0x3E011E27, 0xAA082732,
+ 0x3FEAA1FC, 0xC4000000, 0xBE20BACB, 0xC682F0BF,
+ 0x3FEAAF51, 0x18000000, 0xBE2DC7DD, 0x7BD08C78,
+ 0x3FEABCAC, 0x14000000, 0x3E2271A2, 0xA3B10F9A,
+ 0x3FEACA0D, 0xC4000000, 0xBE15449C, 0x7966F94C,
+ 0x3FEAD776, 0x24000000, 0x3DD06137, 0x6FD8F3EE,
+ 0x3FEAE4E5, 0x3C000000, 0xBE267CD1, 0x8C5A144A,
+ 0x3FEAF25B, 0x0C000000, 0xBE29E584, 0xB59DA94B,
+ 0x3FEAFFD7, 0x98000000, 0xBE23DFCF, 0x7B52192F,
+ 0x3FEB0D5A, 0xE4000000, 0xBE1CF2FE, 0x78A76B45,
+ 0x3FEB1AE4, 0xF4000000, 0xBE23A561, 0x7EC80FF6,
+ 0x3FEB2875, 0xC8000000, 0x3E22C4C9, 0x932EED68,
+ 0x3FEB360D, 0x68000000, 0x3E2B085C, 0xB5833C97,
+ 0x3FEB43AB, 0xD8000000, 0xBE01F093, 0x93B9319A,
+ 0x3FEB5151, 0x18000000, 0xBE254F01, 0xFABCE670,
+ 0x3FEB5EFD, 0x28000000, 0x3E2F24C2, 0x627ABFB0,
+ 0x3FEB6CB0, 0x14000000, 0x3E1F1EEC, 0xE6AC0B48,
+ 0x3FEB7A69, 0xDC000000, 0xBE1A8671, 0x127F9ABC,
+ 0x3FEB882A, 0x80000000, 0xBDCB0C28, 0xC87C73B3,
+ 0x3FEB95F2, 0x08000000, 0xBE22E8DD, 0x7F2B5A97,
+ 0x3FEBA3C0, 0x74000000, 0xBE1B3645, 0x2D22A9D5,
+ 0x3FEBB195, 0xC8000000, 0x3E0ADACA, 0x428F8B88,
+ 0x3FEBBF72, 0x0C000000, 0xBE2E9E07, 0xCDF9F681,
+ 0x3FEBCD55, 0x3C000000, 0xBE08A127, 0x7FA54ACF,
+ 0x3FEBDB3F, 0x60000000, 0x3E0E92CE, 0x8225B385,
+ 0x3FEBE930, 0x7C000000, 0x3DF38C2A, 0x7BB09485,
+ 0x3FEBF728, 0x94000000, 0xBE2DFD64, 0xF681FA5F,
+ 0x3FEC0527, 0xA4000000, 0x3E2E384D, 0xDCE88BD2,
+ 0x3FEC132D, 0xBC000000, 0xBE20F111, 0xFE46A893,
+ 0x3FEC213A, 0xD4000000, 0x3E193DA1, 0xB189BFDA,
+ 0x3FEC2F4E, 0xF8000000, 0xBE20E3A1, 0x0E39FB00,
+ 0x3FEC3D6A, 0x24000000, 0x3E1DB044, 0x30F0FAC5,
+ 0x3FEC4B8C, 0x64000000, 0xBE2BC12C, 0x97446B17,
+ 0x3FEC59B5, 0xB4000000, 0xBE282696, 0x963F4150,
+ 0x3FEC67E6, 0x18000000, 0x3E224D26, 0x3049824B,
+ 0x3FEC761D, 0x98000000, 0x3E2C5BA5, 0x87F84C7D,
+ 0x3FEC845C, 0x38000000, 0xBDE1D14D, 0xC4852339,
+ 0x3FEC92A1, 0xF8000000, 0xBE1A451E, 0x5588D9E1,
+ 0x3FECA0EE, 0xDC000000, 0xBE1D3B96, 0x68BFF457,
+ 0x3FECAF42, 0xE8000000, 0xBE18B670, 0x4DADF774,
+ 0x3FECBD9E, 0x20000000, 0xBE1A1548, 0x7FB1FC01,
+ 0x3FECCC00, 0x88000000, 0xBE273F2E, 0x78FC5AF0,
+ 0x3FECDA6A, 0x20000000, 0x3E1D218F, 0xA6F4A841,
+ 0x3FECE8DA, 0xF0000000, 0x3E2E0BA9, 0x4D002CA0,
+ 0x3FECF752, 0xFC000000, 0x3E20F4BB, 0x065EF979,
+ 0x3FED05D2, 0x48000000, 0xBE2ED3D5, 0x11793B33,
+ 0x3FED1458, 0xD0000000, 0x3E115E3C, 0x913341B3,
+ 0x3FED22E6, 0xA0000000, 0x3DE97C02, 0xB3546109,
+ 0x3FED317B, 0xB8000000, 0x3E087540, 0x1BF898EF,
+ 0x3FED4018, 0x1C000000, 0x3E209430, 0x346F9641,
+ 0x3FED4EBB, 0xD0000000, 0x3E2B6DF4, 0x88F4B20B,
+ 0x3FED5D66, 0xDC000000, 0xBE2EC68F, 0x0CB26035,
+ 0x3FED6C19, 0x38000000, 0x3E2CA2C8, 0x1F44D9C3,
+ 0x3FED7AD2, 0xF4000000, 0x3E10E6F4, 0x41704EE0,
+ 0x3FED8994, 0x0C000000, 0x3E2F9273, 0x25F8F0E2,
+ 0x3FED985C, 0x88000000, 0x3E2D041A, 0x318798DE,
+ 0x3FEDA72C, 0x6C000000, 0xBE005680, 0x9349CF58,
+ 0x3FEDB603, 0xB8000000, 0xBE10F665, 0xCF0C934D,
+ 0x3FEDC4E2, 0x70000000, 0x3E166124, 0x19461C64,
+ 0x3FEDD3C8, 0x9C000000, 0xBE1B2ED6, 0x405624C8,
+ 0x3FEDE2B6, 0x3C000000, 0xBE273A7F, 0x62171501,
+ 0x3FEDF1AB, 0x54000000, 0xBE26022B, 0xE36E1450,
+ 0x3FEE00A7, 0xE8000000, 0xBE1C341E, 0x2E07AE15,
+ 0x3FEE0FAB, 0xFC000000, 0xBDFC7EAE, 0x18D0E701,
+ 0x3FEE1EB7, 0x94000000, 0x3E06B34F, 0xECD1FF8B,
+ 0x3FEE2DCA, 0xB4000000, 0x3E1394A3, 0x6813A649,
+ 0x3FEE3CE5, 0x60000000, 0x3E045496, 0xC1754D14,
+ 0x3FEE4C07, 0x9C000000, 0xBE180FFF, 0xF5C6087C,
+ 0x3FEE5B31, 0x68000000, 0x3E22FBCD, 0xADD9A300,
+ 0x3FEE6A62, 0xCC000000, 0x3E2EC7C7, 0xAF0289E5,
+ 0x3FEE799B, 0xCC000000, 0x3E242182, 0x3FB3EDD4,
+ 0x3FEE88DC, 0x6C000000, 0xBE201304, 0x04E39885,
+ 0x3FEE9824, 0xAC000000, 0xBE20D352, 0xE6831D31,
+ 0x3FEEA774, 0x90000000, 0x3E1E032D, 0x618DFCEB,
+ 0x3FEEB6CC, 0x20000000, 0x3E1956A3, 0xF9BB457E,
+ 0x3FEEC62B, 0x60000000, 0xBE2A77E0, 0x50845DB2,
+ 0x3FEED592, 0x4C000000, 0x3E2714F7, 0x47C43858,
+ 0x3FEEE500, 0xF0000000, 0x3E2EED96, 0x71813A66,
+ 0x3FEEF477, 0x50000000, 0xBE04CDBE, 0x4FB4AA34,
+ 0x3FEF03F5, 0x6C000000, 0xBE2774A2, 0x86EB4FF5,
+ 0x3FEF137B, 0x48000000, 0xBE29DD95, 0xAD43B2D2,
+ 0x3FEF2308, 0xE8000000, 0xBE1CADB0, 0xAC16E506,
+ 0x3FEF329E, 0x50000000, 0x3E12AC33, 0x58745C7B,
+ 0x3FEF423B, 0x88000000, 0xBE248118, 0x6EC2D854,
+ 0x3FEF51E0, 0x8C000000, 0x3E26986B, 0x304ACE08,
+ 0x3FEF618D, 0x68000000, 0x3E126D81, 0x3B09354E,
+ 0x3FEF7142, 0x1C000000, 0x3DF06AAE, 0x773C23B3,
+ 0x3FEF80FE, 0xAC000000, 0xBDA105B6, 0xD82EF423,
+ 0x3FEF90C3, 0x1C000000, 0x3DECDEED, 0x465499B8,
+ 0x3FEFA08F, 0x70000000, 0x3E0AEFD4, 0xE2EF03AE,
+ 0x3FEFB063, 0xAC000000, 0x3E1BD4C0, 0x0567B2E7,
+ 0x3FEFC03F, 0xD4000000, 0x3E26AA22, 0x4F97FCBF,
+ 0x3FEFD023, 0xF0000000, 0xBE2F9420, 0x5E4E88D1,
+ 0x3FEFE00F, 0xFC000000, 0xBE254004, 0x438E52E2,
+ 0x3FEFF004, 0x00000000, 0xBE1552AA, 0xEEE93EFC,
+ 0x3FF00000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3FF00802, 0x00000000, 0x3E155800, 0x4449F507,
+ 0x3FF01008, 0x04000000, 0xBE354AA8, 0x882D75D6,
+ 0x3FF01812, 0x08000000, 0x3E303610, 0x3740DE56,
+ 0x3FF02020, 0x14000000, 0x3E360044, 0x5B0C3264,
+ 0x3FF02832, 0x28000000, 0x3E3C4C26, 0x0197EDC3,
+ 0x3FF03048, 0x48000000, 0x3E0B103B, 0x5046CA09,
+ 0x3FF03862, 0x74000000, 0xBE34659C, 0xF9A62624,
+ 0x3FF04080, 0xAC000000, 0xBE254438, 0xDD0A8F37,
+ 0x3FF048A2, 0xF4000000, 0x3DF256C2, 0x97AFB6E2,
+ 0x3FF050C9, 0x50000000, 0xBE3085DF, 0x923D25E1,
+ 0x3FF058F3, 0xC0000000, 0xBE3F0A93, 0x5EA3B091,
+ 0x3FF06122, 0x44000000, 0xBE237DE4, 0x5D63534C,
+ 0x3FF06954, 0xE0000000, 0x3E301719, 0xFF0C58B7,
+ 0x3FF0718B, 0x98000000, 0x3E2E8410, 0x9DF7B665,
+ 0x3FF079C6, 0x6C000000, 0x3E349CB9, 0x3B127222,
+ 0x3FF08205, 0x60000000, 0x3DF127EC, 0x98E0BD08,
+ 0x3FF08A48, 0x74000000, 0xBE24C1B6, 0x706CC41F,
+ 0x3FF0928F, 0xA8000000, 0x3E334EF9, 0x093044EF,
+ 0x3FF09ADB, 0x04000000, 0xBE1304B1, 0x56BC6C83,
+ 0x3FF0A32A, 0x84000000, 0x3E2D383E, 0xB028B984,
+ 0x3FF0AB7E, 0x30000000, 0xBE315B1E, 0x64E7A202,
+ 0x3FF0B3D6, 0x04000000, 0xBE0AC1E6, 0xC678291E,
+ 0x3FF0BC32, 0x04000000, 0x3E3A0418, 0x2F12FFE2,
+ 0x3FF0C492, 0x38000000, 0xBE37D617, 0x43D6D302,
+ 0x3FF0CCF6, 0x98000000, 0x3E2133F2, 0x152CC8FA,
+ 0x3FF0D55F, 0x2C000000, 0x3E3CE5D1, 0xE966E6B7,
+ 0x3FF0DDCB, 0xF8000000, 0x3E1ABF24, 0x7BCACA64,
+ 0x3FF0E63C, 0xFC000000, 0xBE3854F6, 0x2E8CDBED,
+ 0x3FF0EEB2, 0x38000000, 0xBE3E6463, 0x0C32156B,
+ 0x3FF0F72B, 0xAC000000, 0x3E365671, 0xB69772CC,
+ 0x3FF0FFA9, 0x64000000, 0xBE383E9A, 0x02B1201A,
+ 0x3FF1082B, 0x58000000, 0xBE205962, 0x50549CC0,
+ 0x3FF110B1, 0x90000000, 0xBE376BFE, 0xFFDACA72,
+ 0x3FF1193C, 0x08000000, 0x3E3C1C59, 0x5C43E2F3,
+ 0x3FF121CA, 0xCC000000, 0xBE26D374, 0xF7067C8B,
+ 0x3FF12A5D, 0xD4000000, 0x3E343CCC, 0x4DDAFE1D,
+ 0x3FF132F5, 0x28000000, 0x3E3D5C16, 0x58EBCB7F,
+ 0x3FF13B90, 0xCC000000, 0xBE2B5D12, 0xB66E8B53,
+ 0x3FF14430, 0xBC000000, 0xBE24E919, 0xB326B482,
+ 0x3FF14CD4, 0xFC000000, 0x3E23139A, 0xC8AABD43,
+ 0x3FF1557D, 0x90000000, 0x3E30DD8B, 0x16743B55,
+ 0x3FF15E2A, 0x7C000000, 0xBE31D701, 0x35904C50,
+ 0x3FF166DB, 0xBC000000, 0x3E107F42, 0x30E0CA83,
+ 0x3FF16F91, 0x58000000, 0xBE24F1F2, 0xDA1B7123,
+ 0x3FF1784B, 0x50000000, 0xBE3ACAF2, 0x0DC79E23,
+ 0x3FF18109, 0xA4000000, 0xBE23DC79, 0x609374EE,
+ 0x3FF189CC, 0x58000000, 0x3E262CF7, 0x3A40C3B7,
+ 0x3FF19293, 0x70000000, 0x3E1D3833, 0x5A24F463,
+ 0x3FF19B5E, 0xEC000000, 0x3E2BA9AD, 0x8A2E4440,
+ 0x3FF1A42E, 0xD0000000, 0x3DFD8CBC, 0x61C41828,
+ 0x3FF1AD03, 0x1C000000, 0x3E1A65E6, 0x5A4DDF0D,
+ 0x3FF1B5DB, 0xD4000000, 0xBDE2FDBB, 0x9F828DB5,
+ 0x3FF1BEB8, 0xF8000000, 0x3E2F4EE8, 0xB79B700F,
+ 0x3FF1C79A, 0x8C000000, 0x3E3ACC35, 0x0DE1D7E8,
+ 0x3FF1D080, 0x94000000, 0x3E11729E, 0xFF9E20A0,
+ 0x3FF1D96B, 0x10000000, 0xBE300F18, 0x6C2EA70B,
+ 0x3FF1E25A, 0x00000000, 0x3DF32E02, 0xCE425A35,
+ 0x3FF1EB4D, 0x68000000, 0x3E3BDE56, 0x9A322D12,
+ 0x3FF1F445, 0x50000000, 0xBE3C3F0D, 0xBA737AEF,
+ 0x3FF1FD41, 0xB0000000, 0xBE0A2DD0, 0xC896DB7A,
+ 0x3FF20642, 0x90000000, 0x3E2577B0, 0xF8B782F6,
+ 0x3FF20F47, 0xF4000000, 0xBE2C6DA3, 0x73607FC8,
+ 0x3FF21851, 0xD8000000, 0x3E35F7D1, 0xC8917348,
+ 0x3FF22160, 0x44000000, 0x3E3B6F5C, 0xCF9CED69,
+ 0x3FF22A73, 0x3C000000, 0xBE39967E, 0x85775C2E,
+ 0x3FF2338A, 0xB8000000, 0x3E3B3213, 0x497226D4,
+ 0x3FF23CA6, 0xC4000000, 0x3E3E2710, 0x30733227,
+ 0x3FF245C7, 0x60000000, 0x3E33B8A9, 0xAF215A72,
+ 0x3FF24EEC, 0x90000000, 0xBE3F96B2, 0x1365623F,
+ 0x3FF25816, 0x50000000, 0xBE37324F, 0x27DEE202,
+ 0x3FF26144, 0xA4000000, 0x3E318CD5, 0x4E484D87,
+ 0x3FF26A77, 0x94000000, 0xBDE3FD37, 0xA94519E8,
+ 0x3FF273AF, 0x1C000000, 0x3E37132F, 0xEE788C29,
+ 0x3FF27CEB, 0x44000000, 0xBE03DDB7, 0xE842E5C0,
+ 0x3FF2862C, 0x08000000, 0x3E37A3FB, 0xE17C9693,
+ 0x3FF28F71, 0x70000000, 0x3E24EABF, 0xAEB3D9A0,
+ 0x3FF298BB, 0x7C000000, 0xBE13C7B6, 0x853B0733,
+ 0x3FF2A20A, 0x2C000000, 0x3E2D2C80, 0xC7B588B5,
+ 0x3FF2AB5D, 0x88000000, 0xBE35B750, 0x708F3912,
+ 0x3FF2B4B5, 0x8C000000, 0xBE291A70, 0xD5FD9130,
+ 0x3FF2BE12, 0x3C000000, 0x3E2EE937, 0x0CCF9F73,
+ 0x3FF2C773, 0xA0000000, 0xBE3C3F0C, 0xD42CF76C,
+ 0x3FF2D0D9, 0xB0000000, 0x3E35DD54, 0x60763D61,
+ 0x3FF2DA44, 0x78000000, 0x3E26C418, 0xE7D6AA3B,
+ 0x3FF2E3B3, 0xF8000000, 0xBE3605C6, 0x6FB9B7A8,
+ 0x3FF2ED28, 0x2C000000, 0x3E3763D4, 0x24DCDDF5,
+ 0x3FF2F6A1, 0x20000000, 0xBE1A411E, 0xA8EC1AA8,
+ 0x3FF3001E, 0xD0000000, 0xBE23FCA1, 0x1FE8546F,
+ 0x3FF309A1, 0x40000000, 0xBE29DF0D, 0x3AAEE75E,
+ 0x3FF31328, 0x70000000, 0x3E36A5D6, 0x3C2C4206,
+ 0x3FF31CB4, 0x68000000, 0x3E1B7A3E, 0xB4C979B0,
+ 0x3FF32645, 0x28000000, 0xBE36157D, 0x706CD593,
+ 0x3FF32FDA, 0xB0000000, 0xBE39F357, 0x8DA4C646,
+ 0x3FF33975, 0x04000000, 0xBE3E64DE, 0xD575FE6F,
+ 0x3FF34314, 0x24000000, 0x3E07F9E3, 0x44D008E0,
+ 0x3FF34CB8, 0x18000000, 0xBE2E94F9, 0x5A563E77,
+ 0x3FF35660, 0xDC000000, 0x3E314DC2, 0x2475EF19,
+ 0x3FF3600E, 0x78000000, 0x3E26D623, 0xA33AC606,
+ 0x3FF369C0, 0xEC000000, 0x3E170F86, 0xC05B3160,
+ 0x3FF37378, 0x3C000000, 0xBE38DDFE, 0xDB0AE31A,
+ 0x3FF37D34, 0x64000000, 0x3E3662A9, 0x5706B570,
+ 0x3FF386F5, 0x70000000, 0xBE1625E4, 0x6770731E,
+ 0x3FF390BB, 0x5C000000, 0xBE1678F1, 0x62971091,
+ 0x3FF39A86, 0x2C000000, 0xBE061F7C, 0xD045CB0C,
+ 0x3FF3A455, 0xE4000000, 0xBE35CF51, 0x568B1CA2,
+ 0x3FF3AE2A, 0x84000000, 0xBE378185, 0x7FB61F58,
+ 0x3FF3B804, 0x0C000000, 0x3E3F77F4, 0x4FA133AF,
+ 0x3FF3C1E2, 0x88000000, 0xBE22F96A, 0xB00B73FE,
+ 0x3FF3CBC5, 0xF0000000, 0x3E351A64, 0x1EB4CE2F,
+ 0x3FF3D5AE, 0x50000000, 0xBE3D3516, 0xD3755639,
+ 0x3FF3DF9B, 0xA0000000, 0x3E1CD938, 0x43E8C10E,
+ 0x3FF3E98D, 0xEC000000, 0xBE35EE23, 0x455C8842,
+ 0x3FF3F385, 0x30000000, 0xBE29B282, 0x96C9F4ED,
+ 0x3FF3FD81, 0x70000000, 0x3E24A40E, 0x3168CC0B,
+ 0x3FF40782, 0xB0000000, 0x3E3784BC, 0x86C72839,
+ 0x3FF41188, 0xF4000000, 0x3E061F19, 0x0785D847,
+ 0x3FF41B94, 0x3C000000, 0xBE27AEF2, 0xE654A9C9,
+ 0x3FF425A4, 0x88000000, 0x3E33DFC3, 0xF9E4C1BA,
+ 0x3FF42FB9, 0xE0000000, 0x3E2455A8, 0x593D0C75,
+ 0x3FF439D4, 0x44000000, 0xBDE41D4E, 0x238B65D1,
+ 0x3FF443F3, 0xB4000000, 0x3E3BE616, 0x454CBECB,
+ 0x3FF44E18, 0x38000000, 0x3E207B3C, 0x931C5332,
+ 0x3FF45841, 0xD0000000, 0xBE330846, 0x7615DCC9,
+ 0x3FF46270, 0x7C000000, 0xBE2A8A7B, 0xE497F84E,
+ 0x3FF46CA4, 0x40000000, 0x3E020B50, 0xF737AF78,
+ 0x3FF476DD, 0x20000000, 0x3E116B19, 0xE34AFBD3,
+ 0x3FF4811B, 0x20000000, 0xBE3E15A7, 0x841EDB52,
+ 0x3FF48B5E, 0x3C000000, 0x3E0F40C3, 0x33B3DE1E,
+ 0x3FF495A6, 0x7C000000, 0x3E33607F, 0x92EFEE02,
+ 0x3FF49FF3, 0xE4000000, 0xBE1A2DB5, 0x14F7E168,
+ 0x3FF4AA46, 0x70000000, 0x3E3F59EC, 0x3EBA1C94,
+ 0x3FF4B49E, 0x2C000000, 0xBE31A539, 0x8B9AE885,
+ 0x3FF4BEFB, 0x10000000, 0x3E2FAC0B, 0xF13C8C95,
+ 0x3FF4C95D, 0x28000000, 0xBE32C0BB, 0xF8B74775,
+ 0x3FF4D3C4, 0x70000000, 0xBE2FC24E, 0x4F9474BB,
+ 0x3FF4DE30, 0xEC000000, 0x3E008F30, 0x09DA911F,
+ 0x3FF4E8A2, 0xA0000000, 0x3E2994C1, 0xBAF8D98B,
+ 0x3FF4F319, 0x90000000, 0xBE17C38C, 0x18648D0A,
+ 0x3FF4FD95, 0xBC000000, 0xBE288852, 0xF22F8698,
+ 0x3FF50817, 0x28000000, 0xBE3C3EC3, 0x30A2C153,
+ 0x3FF5129D, 0xD4000000, 0xBE27B606, 0x968492AA,
+ 0x3FF51D29, 0xC4000000, 0x3E2E0396, 0x61101629,
+ 0x3FF527BA, 0xFC000000, 0x3E3E876F, 0xDAEEAB38,
+ 0x3FF53251, 0x80000000, 0x3E29F59E, 0xED945B30,
+ 0x3FF53CED, 0x50000000, 0x3E12D7DA, 0x0B4AE3F1,
+ 0x3FF5478E, 0x70000000, 0xBE2FAFB8, 0x5FB946D0,
+ 0x3FF55234, 0xE0000000, 0xBE18A8B3, 0x87D80C66,
+ 0x3FF55CE0, 0xA4000000, 0x3E28B18F, 0x764CF85C,
+ 0x3FF56791, 0xC0000000, 0x3E326017, 0x2BDBC6F4,
+ 0x3FF57248, 0x38000000, 0xBE229F98, 0x53D523FE,
+ 0x3FF57D04, 0x0C000000, 0xBE3BDD08, 0x4D9B8720,
+ 0x3FF587C5, 0x3C000000, 0x3E169EBC, 0x09D8749E,
+ 0x3FF5928B, 0xD0000000, 0x3E190C8C, 0x339C2080,
+ 0x3FF59D57, 0xC8000000, 0x3E310FA4, 0xDE75E9CA,
+ 0x3FF5A829, 0x28000000, 0x3E313D18, 0x1097F186,
+ 0x3FF5B2FF, 0xF4000000, 0xBE2BDE04, 0xD51C23F6,
+ 0x3FF5BDDC, 0x28000000, 0x3E3EE67E, 0x8938C386,
+ 0x3FF5C8BD, 0xD0000000, 0x3E0973B8, 0x47DF6575,
+ 0x3FF5D3A4, 0xE8000000, 0x3E24DF02, 0x1DB97781,
+ 0x3FF5DE91, 0x78000000, 0xBE3FBA00, 0xAC4AECDC,
+ 0x3FF5E983, 0x7C000000, 0xBE2F37AF, 0x939F646A,
+ 0x3FF5F47A, 0xFC000000, 0xBE396DEF, 0x58A6EEE9,
+ 0x3FF5FF77, 0xF8000000, 0xBE315248, 0xE3613C7B,
+ 0x3FF60A7A, 0x74000000, 0xBE26A9E2, 0xF1553706,
+ 0x3FF61582, 0x74000000, 0xBE3B6BF6, 0xAE4D7CB6,
+ 0x3FF6208F, 0xF8000000, 0xBE35775B, 0x9EB5EBA5,
+ 0x3FF62BA3, 0x04000000, 0xBE2A821B, 0xC1E43506,
+ 0x3FF636BB, 0x9C000000, 0xBE367CDA, 0x7B2D8CF4,
+ 0x3FF641D9, 0xC0000000, 0xBE13218B, 0x3E907A1D,
+ 0x3FF64CFD, 0x74000000, 0x3E3454EE, 0x7BF5DFE4,
+ 0x3FF65826, 0xC0000000, 0xBE3E960F, 0x6366C5FD,
+ 0x3FF66355, 0x9C000000, 0x3E2E378F, 0x8B43C17E,
+ 0x3FF66E8A, 0x14000000, 0x3E244BE0, 0xA4306535,
+ 0x3FF679C4, 0x28000000, 0xBDE4B6C1, 0x8DF63D6E,
+ 0x3FF68503, 0xD8000000, 0x3E3BA122, 0xE6A239CF,
+ 0x3FF69049, 0x2C000000, 0x3E27F286, 0x59FB5F30,
+ 0x3FF69B94, 0x24000000, 0xBE044041, 0x971D3970 } };
+
+static const union {
+ int4 i[2048];
+ double x[1024];
+} fine = { .i = {
+ 0x3FF00000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3FF00004, 0x00000000, 0x3DA00001, 0x55556AAB,
+ 0x3FF00008, 0x00000000, 0x3DC00002, 0xAAAB0000,
+ 0x3FF0000C, 0x00000000, 0x3DD20004, 0x8000D800,
+ 0x3FF00010, 0x00000000, 0x3DE00005, 0x5556AAAB,
+ 0x3FF00014, 0x00000000, 0x3DE9000A, 0x6AADEC01,
+ 0x3FF00018, 0x00000000, 0x3DF20009, 0x00036001,
+ 0x3FF0001C, 0x00000000, 0x3DF8800E, 0x4AB0EB58,
+ 0x3FF00020, 0x00000000, 0x3E00000A, 0xAAB00002,
+ 0x3FF00024, 0x00000000, 0x3E04400F, 0x30088B04,
+ 0x3FF00028, 0x00000000, 0x3E090014, 0xD5625AB1,
+ 0x3FF0002C, 0x00000000, 0x3E0E401B, 0xBABDBB0A,
+ 0x3FF00030, 0x00000000, 0x3E120012, 0x000D8008,
+ 0x3FF00034, 0x00000000, 0x3E152016, 0xE2BD42E1,
+ 0x3FF00038, 0x00000000, 0x3E18801C, 0x956E5812,
+ 0x3FF0003C, 0x00000000, 0x3E1C2023, 0x2820F599,
+ 0x3FF00040, 0x00000000, 0x3E200015, 0x556AAABC,
+ 0x3FF00044, 0x00000000, 0x3E221019, 0x96C5DAD7,
+ 0x3FF00048, 0x00000000, 0x3E24401E, 0x60222C1F,
+ 0x3FF0004C, 0x00000000, 0x3E269023, 0xB97FC193,
+ 0x3FF00050, 0x00000000, 0x3E290029, 0xAADEC034,
+ 0x3FF00054, 0x00000000, 0x3E2B9030, 0x3C3F4F02,
+ 0x3FF00058, 0x00000000, 0x3E2E4037, 0x75A196FF,
+ 0x3FF0005C, 0x00000000, 0x3E30881F, 0xAF82E194,
+ 0x3FF00060, 0x00000000, 0x3E320024, 0x00360041,
+ 0x3FF00064, 0x00000000, 0x3E338828, 0xB0EA3F05,
+ 0x3FF00068, 0x00000000, 0x3E35202D, 0xC59FB661,
+ 0x3FF0006C, 0x00000000, 0x3E36C833, 0x42567FD5,
+ 0x3FF00070, 0x00000000, 0x3E388039, 0x2B0EB5E1,
+ 0x3FF00074, 0x00000000, 0x3E3A483F, 0x83C87407,
+ 0x3FF00078, 0x00000000, 0x3E3C2046, 0x5083D6C6,
+ 0x3FF0007C, 0x00000000, 0x3E3E084D, 0x9540FB9E,
+ 0x3FF00080, 0x04000000, 0xBE3FFFAA, 0xA9FFFEEF,
+ 0x3FF00084, 0x04000000, 0xBE3DF7A2, 0x693EF962,
+ 0x3FF00088, 0x04000000, 0xBE3BDF99, 0xA47BD339,
+ 0x3FF0008C, 0x04000000, 0xBE39B790, 0x57B66AF5,
+ 0x3FF00090, 0x04000000, 0xBE377F86, 0x7EEE9E14,
+ 0x3FF00094, 0x04000000, 0xBE35377C, 0x16244916,
+ 0x3FF00098, 0x04000000, 0xBE32DF71, 0x1957477B,
+ 0x3FF0009C, 0x04000000, 0xBE307765, 0x848773C2,
+ 0x3FF000A0, 0x04000000, 0xBE2BFEB2, 0xA7694ED3,
+ 0x3FF000A4, 0x04000000, 0xBE26EE99, 0x05BD75E2,
+ 0x3FF000A8, 0x04000000, 0xBE21BE7E, 0x1C0B0BB1,
+ 0x3FF000AC, 0x04000000, 0xBE18DCC3, 0xC4A37A79,
+ 0x3FF000B0, 0x04000000, 0xBE0BF911, 0x4244D60F,
+ 0x3FF000B4, 0x04000000, 0xBDE6E255, 0xEC91D848,
+ 0x3FF000B8, 0x04000000, 0x3E0107EB, 0xEC1B8F0C,
+ 0x3FF000BC, 0x04000000, 0x3E142439, 0x89BE52AA,
+ 0x3FF000C0, 0x04000000, 0x3E200240, 0x06C01033,
+ 0x3FF000C4, 0x04000000, 0x3E261264, 0xC8A9F760,
+ 0x3FF000C8, 0x04000000, 0x3E2C428B, 0x129D3FDE,
+ 0x3FF000CC, 0x04000000, 0x3E314959, 0x764D2658,
+ 0x3FF000D0, 0x04000000, 0x3E34816E, 0x2F50C16C,
+ 0x3FF000D4, 0x04000000, 0x3E37C983, 0xB859A4AB,
+ 0x3FF000D8, 0x04000000, 0x3E3B219A, 0x15680499,
+ 0x3FF000DC, 0x04000000, 0x3E3E89B1, 0x4A7C16B5,
+ 0x3FF000E0, 0x08000000, 0xBE3DFE36, 0xA469EE7E,
+ 0x3FF000E4, 0x08000000, 0xBE3A761D, 0xB349D37F,
+ 0x3FF000E8, 0x08000000, 0xBE36DE03, 0xDE235FCD,
+ 0x3FF000EC, 0x08000000, 0xBE3335E9, 0x20F659E6,
+ 0x3FF000F0, 0x08000000, 0xBE2EFB9A, 0xEF850E8F,
+ 0x3FF000F4, 0x08000000, 0xBE276B61, 0xBD0F58E2,
+ 0x3FF000F8, 0x08000000, 0xBE1F764D, 0x45163381,
+ 0x3FF000FC, 0x08000000, 0xBE0FABA6, 0x5FDF589A,
+ 0x3FF00100, 0x08000000, 0x3D8555AA, 0xABBBBE94,
+ 0x3FF00104, 0x08000000, 0x3E102B2C, 0xDABB690B,
+ 0x3FF00108, 0x08000000, 0x3E2045D9, 0x7820FBA0,
+ 0x3FF0010C, 0x08000000, 0x3E28961E, 0x92F54742,
+ 0x3FF00110, 0x08000000, 0x3E308332, 0xE2ED8E39,
+ 0x3FF00114, 0x08000000, 0x3E34CB57, 0x8C698119,
+ 0x3FF00118, 0x08000000, 0x3E39237D, 0x49EEC0C4,
+ 0x3FF0011C, 0x08000000, 0x3E3D8BA4, 0x1F7D92BC,
+ 0x3FF00120, 0x0C000000, 0xBE3DFC33, 0xEEE9C27D,
+ 0x3FF00124, 0x0C000000, 0xBE39740A, 0xDD46F763,
+ 0x3FF00128, 0x0C000000, 0xBE34DBE0, 0xA799C375,
+ 0x3FF0012C, 0x0C000000, 0xBE3033B5, 0x49E1DD2F,
+ 0x3FF00130, 0x0C000000, 0xBE26F711, 0x803DF41F,
+ 0x3FF00134, 0x0C000000, 0xBE1ACD6C, 0x19433A4C,
+ 0x3FF00138, 0x0C000000, 0xBDFDB2C1, 0x8770E36F,
+ 0x3FF0013C, 0x0C000000, 0x3E086820, 0x6B74A43E,
+ 0x3FF00140, 0x0C000000, 0x3E200A6A, 0xDEC0D058,
+ 0x3FF00144, 0x0C000000, 0x3E2A1AD0, 0x22BD7872,
+ 0x3FF00148, 0x0C000000, 0x3E32259B, 0xF769E132,
+ 0x3FF0014C, 0x0C000000, 0x3E374DD1, 0x2582289A,
+ 0x3FF00150, 0x0C000000, 0x3E3C8607, 0x9FA7E4F4,
+ 0x3FF00154, 0x10000000, 0xBE3E31C0, 0x9624963C,
+ 0x3FF00158, 0x10000000, 0xBE38D987, 0x77E2F472,
+ 0x3FF0015C, 0x10000000, 0xBE33714D, 0x0192E02C,
+ 0x3FF00160, 0x10000000, 0xBE2BF222, 0x5E6805CB,
+ 0x3FF00164, 0x10000000, 0xBE20E1A7, 0xF98C0A34,
+ 0x3FF00168, 0x10000000, 0xBE06C4AB, 0x32447238,
+ 0x3FF0016C, 0x10000000, 0x3E067D54, 0xC225D8C1,
+ 0x3FF00170, 0x10000000, 0x3E210FD8, 0x05C4630F,
+ 0x3FF00174, 0x10000000, 0x3E2CA05D, 0xBB206115,
+ 0x3FF00178, 0x10000000, 0x3E342873, 0x2C4F14A6,
+ 0x3FF0017C, 0x10000000, 0x3E3A10B8, 0xF31F3B5E,
+ 0x3FF00180, 0x14000000, 0xBE3FF6FF, 0xC9FEFCC9,
+ 0x3FF00184, 0x14000000, 0xBE39EEB7, 0x070B344A,
+ 0x3FF00188, 0x14000000, 0xBE33D66C, 0xC0050AA2,
+ 0x3FF0018C, 0x14000000, 0xBE2B5C41, 0xE1D83C97,
+ 0x3FF00190, 0x14000000, 0xBE1DD74E, 0x57003305,
+ 0x3FF00194, 0x14000000, 0xBDF2D84A, 0xA80727F1,
+ 0x3FF00198, 0x14000000, 0x3E14AB2F, 0x534C5401,
+ 0x3FF0019C, 0x14000000, 0x3E27263B, 0xD875DE83,
+ 0x3FF001A0, 0x14000000, 0x3E320B71, 0x9FB782CA,
+ 0x3FF001A4, 0x14000000, 0x3E3893C6, 0xF349371F,
+ 0x3FF001A8, 0x14000000, 0x3E3F2C1D, 0xEAF074C6,
+ 0x3FF001AC, 0x18000000, 0xBE3A2B89, 0x75525ABC,
+ 0x3FF001B0, 0x18000000, 0xBE33732F, 0x297ECCE2,
+ 0x3FF001B4, 0x18000000, 0xBE2955A6, 0x5B28EC49,
+ 0x3FF001B8, 0x18000000, 0xBE1749D5, 0xF64BA7FD,
+ 0x3FF001BC, 0x18000000, 0x3DF15E9E, 0xA8645141,
+ 0x3FF001C0, 0x18000000, 0x3E201C96, 0x1D6F0B37,
+ 0x3FF001C4, 0x18000000, 0x3E2E2D5B, 0xE6028E39,
+ 0x3FF001C8, 0x18000000, 0x3E362F12, 0x9B63FA1E,
+ 0x3FF001CC, 0x18000000, 0x3E3D5779, 0x0BE01026,
+ 0x3FF001D0, 0x1C000000, 0xBE3B701E, 0xB78A0445,
+ 0x3FF001D4, 0x1C000000, 0xBE3427B4, 0xAAD9CF9D,
+ 0x3FF001D8, 0x1C000000, 0xBE299E91, 0x941DBAB5,
+ 0x3FF001DC, 0x1C000000, 0xBE159B6C, 0x44A2DFDD,
+ 0x3FF001E0, 0x1C000000, 0x3E008CA4, 0x1EC8B89C,
+ 0x3FF001E4, 0x1C000000, 0x3E23340B, 0xF1EE0E9A,
+ 0x3FF001E8, 0x1C000000, 0x3E313279, 0x5231913C,
+ 0x3FF001EC, 0x1C000000, 0x3E38DAEE, 0x93892E68,
+ 0x3FF001F0, 0x20000000, 0xBE3F6C9A, 0x3F01A6A8,
+ 0x3FF001F4, 0x20000000, 0xBE37A421, 0x216E726C,
+ 0x3FF001F8, 0x20000000, 0xBE2F974C, 0x1F7970B9,
+ 0x3FF001FC, 0x20000000, 0xBE1F8CA4, 0x17AFEBC8,
+ 0x3FF00200, 0x20000000, 0x3DB55600, 0x04445B06,
+ 0x3FF00204, 0x20000000, 0x3E203BAE, 0x0C290A26,
+ 0x3FF00208, 0x20000000, 0x3E30365A, 0x104547BD,
+ 0x3FF0020C, 0x20000000, 0x3E385EDF, 0x22970DE3,
+ 0x3FF00210, 0x24000000, 0xBE3F6899, 0xBEF5A5F4,
+ 0x3FF00214, 0x24000000, 0xBE372010, 0x90605040,
+ 0x3FF00218, 0x24000000, 0xBE2D8F0A, 0x9B50D8EE,
+ 0x3FF0021C, 0x24000000, 0xBE197BDF, 0xCB35D444,
+ 0x3FF00220, 0x24000000, 0x3E00CCBC, 0x2188E3D5,
+ 0x3FF00224, 0x24000000, 0x3E254452, 0x36A79F6A,
+ 0x3FF00228, 0x24000000, 0x3E333ABC, 0xD69B2D28,
+ 0x3FF0022C, 0x24000000, 0x3E3BE352, 0xBA07BE5B,
+ 0x3FF00230, 0x28000000, 0xBE3B6415, 0x3665F227,
+ 0x3FF00234, 0x28000000, 0xBE329B7A, 0xF6AD58D5,
+ 0x3FF00238, 0x28000000, 0xBE2385BD, 0x059BD24A,
+ 0x3FF0023C, 0x28000000, 0xBDEB47FA, 0xD8E2B1B4,
+ 0x3FF00240, 0x28000000, 0x3E203CC2, 0x22CF60F6,
+ 0x3FF00244, 0x28000000, 0x3E312704, 0x39BEF87F,
+ 0x3FF00248, 0x28000000, 0x3E3A3FA9, 0xA63F5309,
+ 0x3FF0024C, 0x2C000000, 0xBE3C97AE, 0xA516AE5E,
+ 0x3FF00250, 0x2C000000, 0xBE335F04, 0xA442792A,
+ 0x3FF00254, 0x2C000000, 0xBE242CB0, 0xA686F3A2,
+ 0x3FF00258, 0x2C000000, 0xBDE7B535, 0xC3237903,
+ 0x3FF0025C, 0x2C000000, 0x3E21560E, 0x9E7A6CF7,
+ 0x3FF00260, 0x2C000000, 0x3E3223BA, 0xA8C01385,
+ 0x3FF00264, 0x2C000000, 0x3E3BAC70, 0x627012DF,
+ 0x3FF00268, 0x30000000, 0xBE3ABAD7, 0x7FB232EA,
+ 0x3FF0026C, 0x30000000, 0xBE31121C, 0xF9A6244B,
+ 0x3FF00270, 0x30000000, 0xBE1D6580, 0x1DAC9AE4,
+ 0x3FF00274, 0x30000000, 0x3E037AFA, 0xD7FB0AC3,
+ 0x3FF00278, 0x30000000, 0x3E289042, 0x633420EB,
+ 0x3FF0027C, 0x30000000, 0x3E3630E5, 0x8065842A,
+ 0x3FF00280, 0x34000000, 0xBE3FD653, 0xB49DA4FF,
+ 0x3FF00284, 0x34000000, 0xBE35CD8A, 0x696ECB76,
+ 0x3FF00288, 0x34000000, 0xBE27697D, 0x341A9D63,
+ 0x3FF0028C, 0x34000000, 0xBDF8BF04, 0x2788D238,
+ 0x3FF00290, 0x34000000, 0x3E2159C1, 0x42A03782,
+ 0x3FF00294, 0x34000000, 0x3E32F5B4, 0x154D4F89,
+ 0x3FF00298, 0x34000000, 0x3E3D4E8A, 0x1D7FB2C1,
+ 0x3FF0029C, 0x38000000, 0xBE38489D, 0x42181508,
+ 0x3FF002A0, 0x38000000, 0xBE2B9F84, 0x0AF2C28C,
+ 0x3FF002A4, 0x38000000, 0xBE0A3721, 0x451C5357,
+ 0x3FF002A8, 0x38000000, 0x3E1D47F1, 0x61A8605E,
+ 0x3FF002AC, 0x38000000, 0x3E31FADF, 0x81B02FCF,
+ 0x3FF002B0, 0x38000000, 0x3E3CB3C5, 0x572F674A,
+ 0x3FF002B4, 0x3C000000, 0xBE388352, 0x231795EA,
+ 0x3FF002B8, 0x3C000000, 0xBE2B54CD, 0xD248367A,
+ 0x3FF002BC, 0x3C000000, 0xBE060BC7, 0xB7ABD90D,
+ 0x3FF002C0, 0x3C000000, 0x3E206EEF, 0x6EE9F1EF,
+ 0x3FF002C4, 0x3C000000, 0x3E33406B, 0x261BF09E,
+ 0x3FF002C8, 0x3C000000, 0x3E3E5961, 0x59001C60,
+ 0x3FF002CC, 0x40000000, 0xBE367DA5, 0xABDDD232,
+ 0x3FF002D0, 0x40000000, 0xBE268953, 0xC8FA5113,
+ 0x3FF002D4, 0x40000000, 0x3D9152CC, 0x8B33A701,
+ 0x3FF002D8, 0x40000000, 0x3E26BAAC, 0x3E058570,
+ 0x3FF002DC, 0x40000000, 0x3E36C65A, 0x63236E71,
+ 0x3FF002E0, 0x44000000, 0xBE3DC09E, 0x7C7A795C,
+ 0x3FF002E4, 0x44000000, 0xBE323794, 0x7BD63D1D,
+ 0x3FF002E8, 0x44000000, 0xBE1A7A1E, 0x5BBC9105,
+ 0x3FF002EC, 0x44000000, 0x3E142A20, 0xD8EE2B1B,
+ 0x3FF002F0, 0x44000000, 0x3E30C39A, 0xEFAA8A8D,
+ 0x3FF002F4, 0x44000000, 0x3E3C8CB0, 0x995E96A2,
+ 0x3FF002F8, 0x48000000, 0xBE379A36, 0xC8A79469,
+ 0x3FF002FC, 0x48000000, 0xBE276236, 0x64CE7203,
+ 0x3FF00300, 0x48000000, 0x3DD200D8, 0x0819DA68,
+ 0x3FF00304, 0x48000000, 0x3E28A249, 0xE5E018D4,
+ 0x3FF00308, 0x48000000, 0x3E386A49, 0x8A087692,
+ 0x3FF0030C, 0x4C000000, 0xBE3B6C8E, 0xD695988B,
+ 0x3FF00310, 0x4C000000, 0xBE2E66C8, 0x55D2BCBA,
+ 0x3FF00314, 0x4C000000, 0xBE0751B3, 0x7790BA7A,
+ 0x3FF00318, 0x4C000000, 0x3E22DDF4, 0xC2A20261,
+ 0x3FF0031C, 0x4C000000, 0x3E35D82E, 0x49E0B0B5,
+ 0x3FF00320, 0x50000000, 0xBE3DAE9A, 0xB142422E,
+ 0x3FF00324, 0x50000000, 0xBE312560, 0x8C170FE6,
+ 0x3FF00328, 0x50000000, 0xBE12308D, 0x0A73BF77,
+ 0x3FF0032C, 0x50000000, 0x3E203A3A, 0x5E59CEFA,
+ 0x3FF00330, 0x50000000, 0x3E34D660, 0xCD4740BF,
+ 0x3FF00334, 0x54000000, 0xBE3E6058, 0x644D1883,
+ 0x3FF00338, 0x54000000, 0xBE31870E, 0x618F57B6,
+ 0x3FF0033C, 0x54000000, 0xBE127704, 0x99FABD0F,
+ 0x3FF00340, 0x54000000, 0x3E20B71E, 0xA1CB5ECF,
+ 0x3FF00344, 0x54000000, 0x3E3564E3, 0x089E93E1,
+ 0x3FF00348, 0x58000000, 0xBE3D81C5, 0xFB533142,
+ 0x3FF0034C, 0x58000000, 0xBE30586B, 0xB6EECE6C,
+ 0x3FF00350, 0x58000000, 0xBE08F871, 0x319B883E,
+ 0x3FF00354, 0x58000000, 0x3E2454A5, 0x75BF7503,
+ 0x3FF00358, 0x58000000, 0x3E3783B6, 0xF04B88C5,
+ 0x3FF0035C, 0x5C000000, 0xBE3B12E1, 0x81EF30A7,
+ 0x3FF00360, 0x5C000000, 0xBE2B32ED, 0x2F9F3657,
+ 0x3FF00364, 0x5C000000, 0xBDB0084D, 0x54DF31BC,
+ 0x3FF00368, 0x5C000000, 0x3E2B12D2, 0xC303B7B9,
+ 0x3FF0036C, 0x5C000000, 0x3E3B32DE, 0x78B56F97,
+ 0x3FF00370, 0x60000000, 0xBE3713A9, 0x03B9496C,
+ 0x3FF00374, 0x60000000, 0xBE22945A, 0x1F92E726,
+ 0x3FF00378, 0x60000000, 0x3E123D49, 0x621736DF,
+ 0x3FF0037C, 0x60000000, 0x3E3278D5, 0x3935580D,
+ 0x3FF00380, 0x64000000, 0xBE3F8DA4, 0x69B9F5FB,
+ 0x3FF00384, 0x64000000, 0xBE31841A, 0x8C473CC8,
+ 0x3FF00388, 0x64000000, 0xBE0B5469, 0x538CDE07,
+ 0x3FF0038C, 0x64000000, 0x3E257E07, 0x7F8F9D65,
+ 0x3FF00390, 0x64000000, 0x3E38F898, 0x3665E52B,
+ 0x3FF00394, 0x68000000, 0xBE38BDCF, 0xC29674BD,
+ 0x3FF00398, 0x68000000, 0xBE24C868, 0x4E58B4D9,
+ 0x3FF0039C, 0x68000000, 0x3E1015AC, 0x329466D7,
+ 0x3FF003A0, 0x68000000, 0x3E327F0D, 0xDCDECE44,
+ 0x3FF003A4, 0x6C000000, 0xBE3EF74B, 0xB27E5528,
+ 0x3FF003A8, 0x6C000000, 0xBE305DA1, 0x9D7167F2,
+ 0x3FF003AC, 0x6C000000, 0xBDFB3F3D, 0xFF980820,
+ 0x3FF003B0, 0x6C000000, 0x3E2A0B7B, 0x13D49789,
+ 0x3FF003B4, 0x6C000000, 0x3E3BCF72, 0xA43AE87C,
+ 0x3FF003B8, 0x70000000, 0xBE3556D4, 0x8D06BDC0,
+ 0x3FF003BC, 0x70000000, 0xBE19B460, 0x1766E54D,
+ 0x3FF003C0, 0x70000000, 0x3E211950, 0x7B85C8BA,
+ 0x3FF003C4, 0x70000000, 0x3E37966C, 0x41D00AED,
+ 0x3FF003C8, 0x74000000, 0xBE394FCB, 0xF5B15507,
+ 0x3FF003CC, 0x74000000, 0xBE244C00, 0xC98093C4,
+ 0x3FF003D0, 0x74000000, 0x3E144F3B, 0xE2907BDF,
+ 0x3FF003D4, 0x74000000, 0x3E345DA2, 0x267CD924,
+ 0x3FF003D8, 0x78000000, 0xBE3C4886, 0xD73526C0,
+ 0x3FF003DC, 0x78000000, 0xBE29BD57, 0xF8E1D62E,
+ 0x3FF003E0, 0x78000000, 0x3E04D995, 0xD65415E1,
+ 0x3FF003E4, 0x78000000, 0x3E322515, 0x527E1A58,
+ 0x3FF003E8, 0x7C000000, 0xBE3E4104, 0x31552BA5,
+ 0x3FF003EC, 0x7C000000, 0xBE2D2E33, 0x995CAB3B,
+ 0x3FF003F0, 0x7C000000, 0x3DF22D48, 0x473970DC,
+ 0x3FF003F4, 0x7C000000, 0x3E30ECC6, 0xC61195FC,
+ 0x3FF003F8, 0x80000000, 0xBE3F3943, 0x03D35C34,
+ 0x3FF003FC, 0x80000000, 0xBE2E9E91, 0xAA7483C7,
+ 0x3FF00400, 0x80000000, 0x3DE556AA, 0xBBBC71CE,
+ 0x3FF00404, 0x80000000, 0x3E30B4B7, 0x817613C1,
+ 0x3FF00408, 0x84000000, 0xBE3F3142, 0x4E70B0AC,
+ 0x3FF0040C, 0x84000000, 0xBE2E0E70, 0x2BAAD02F,
+ 0x3FF00410, 0x84000000, 0x3DF32D62, 0xF48F01F2,
+ 0x3FF00414, 0x84000000, 0x3E317CE8, 0x84EB5B98,
+ 0x3FF00418, 0x88000000, 0xBE3E2901, 0x10ED210B,
+ 0x3FF0041C, 0x88000000, 0xBE2B7DCD, 0x1C7F0051,
+ 0x3FF00420, 0x88000000, 0x3E05D9C0, 0x87AA2706,
+ 0x3FF00424, 0x88000000, 0x3E33455A, 0xD0B235B3,
+ 0x3FF00428, 0x8C000000, 0xBE3C207E, 0x4B07A510,
+ 0x3FF0042C, 0x8C000000, 0xBE26ECA6, 0x7C6E838B,
+ 0x3FF00430, 0x8C000000, 0x3E150F6F, 0xEC91A8D5,
+ 0x3FF00434, 0x8C000000, 0x3E360E0F, 0x650C6A83,
+ 0x3FF00438, 0x90000000, 0xBE3917B8, 0xFC7E3439,
+ 0x3FF0043C, 0x90000000, 0xBE205AFA, 0x4AF4C8B6,
+ 0x3FF00440, 0x90000000, 0x3E219985, 0xDC31D181,
+ 0x3FF00444, 0x90000000, 0x3E39D707, 0x423CC2BE,
+ 0x3FF00448, 0x94000000, 0xBE350EB0, 0x250DC5BF,
+ 0x3FF0044C, 0x94000000, 0xBE0F231A, 0x1E2CF893,
+ 0x3FF00450, 0x94000000, 0x3E2AABDB, 0xD42C92D4,
+ 0x3FF00454, 0x94000000, 0x3E3EA043, 0x6887075B,
+ 0x3FF00458, 0x98000000, 0xBE300562, 0xC472509B,
+ 0x3FF0045C, 0x98000000, 0x3DF64FB6, 0x72B572E0,
+ 0x3FF00460, 0x98000000, 0x3E32DF5D, 0xEF61155C,
+ 0x3FF00464, 0x9C000000, 0xBE3B963B, 0x27CFFE6A,
+ 0x3FF00468, 0x9C000000, 0xBE23F79F, 0xB4CD96FE,
+ 0x3FF0046C, 0x9C000000, 0x3E1EBA7F, 0x6E771F13,
+ 0x3FF00470, 0x9C000000, 0x3E396913, 0xFE3ED608,
+ 0x3FF00474, 0xA0000000, 0xBE34CC73, 0x6E82850F,
+ 0x3FF00478, 0xA0000000, 0xBE078FB3, 0x352966B7,
+ 0x3FF0047C, 0xA0000000, 0x3E2DF116, 0x33AFF8AE,
+ 0x3FF00480, 0xA4000000, 0xBE3F0CEE, 0xE909EADD,
+ 0x3FF00484, 0xA4000000, 0xBE2A04C8, 0xD6938597,
+ 0x3FF00488, 0xA4000000, 0x3E1460AA, 0x5C6654D8,
+ 0x3FF0048C, 0xA4000000, 0x3E3742BE, 0x22213ECF,
+ 0x3FF00490, 0xA8000000, 0xBE3682A9, 0xC631A356,
+ 0x3FF00494, 0xA8000000, 0xBE10E034, 0x7777B644,
+ 0x3FF00498, 0xA8000000, 0x3E2C4528, 0x3E3B0991,
+ 0x3FF0049C, 0xAC000000, 0xBE3F72C6, 0x0B3E269F,
+ 0x3FF004A0, 0xAC000000, 0xBE29F037, 0x31DF923B,
+ 0x3FF004A4, 0xAC000000, 0x3E164A4D, 0xE82713DE,
+ 0x3FF004A8, 0xAC000000, 0x3E382D47, 0x31AFAC4B,
+ 0x3FF004AC, 0xB0000000, 0xBE352800, 0x6DFCE978,
+ 0x3FF004B0, 0xB0000000, 0xBE036A1B, 0x07D68D27,
+ 0x3FF004B4, 0xB0000000, 0x3E305D7E, 0x5CB71F6F,
+ 0x3FF004B8, 0xB4000000, 0xBE3CC7BB, 0x30E5E990,
+ 0x3FF004BC, 0xB4000000, 0xBE23B9E0, 0x0BA17DEA,
+ 0x3FF004C0, 0xB4000000, 0x3E223BBF, 0xC3EF9BD8,
+ 0x3FF004C4, 0xB4000000, 0x3E3C28B4, 0x8A74ECC0,
+ 0x3FF004C8, 0xB8000000, 0xBE30BC72, 0x085831CA,
+ 0x3FF004CC, 0xB8000000, 0x3E037361, 0x6C8D1FC8,
+ 0x3FF004D0, 0xB8000000, 0x3E35A94F, 0x3033A0B8,
+ 0x3FF004D4, 0xBC000000, 0xBE370BC8, 0xFC7107DE,
+ 0x3FF004D8, 0xBC000000, 0xBE0D86E2, 0xA2D908DA,
+ 0x3FF004DC, 0xBC000000, 0x3E2F742A, 0x58ED155E,
+ 0x3FF004E0, 0xC0000000, 0xBE3CCAF4, 0x75FACDD0,
+ 0x3FF004E4, 0xC0000000, 0xBE227FF2, 0x6F5BE5D3,
+ 0x3FF004E8, 0xC0000000, 0x3E24B60D, 0xD6BCA827,
+ 0x3FF004EC, 0xC0000000, 0x3E3E060B, 0xF72B40D6,
+ 0x3FF004F0, 0xC4000000, 0xBE2C7DD4, 0x208BE3E3,
+ 0x3FF004F4, 0xC4000000, 0x3E163093, 0x642FDDB8,
+ 0x3FF004F8, 0xC4000000, 0x3E396738, 0xB72239A5,
+ 0x3FF004FC, 0xC8000000, 0xBE32ADAE, 0x7201ED9B,
+ 0x3FF00500, 0xC8000000, 0x3DF4D6F6, 0x1A0C05F3,
+ 0x3FF00504, 0xC8000000, 0x3E355892, 0x360B8346,
+ 0x3FF00508, 0xCC000000, 0xBE368C45, 0xF0C06435,
+ 0x3FF0050C, 0xCC000000, 0xBE0308C8, 0x760DA2F6,
+ 0x3FF00510, 0xCC000000, 0x3E31DA18, 0xE008D57B,
+ 0x3FF00514, 0xD0000000, 0xBE39DAB0, 0x205F82F4,
+ 0x3FF00518, 0xD0000000, 0xBE15FDD0, 0x2FE5E3E3,
+ 0x3FF0051C, 0xD0000000, 0x3E2DD79A, 0x42787241,
+ 0x3FF00520, 0xD4000000, 0xBE3C98EC, 0x94BD25F4,
+ 0x3FF00524, 0xD4000000, 0xBE201B42, 0x53C89D03,
+ 0x3FF00528, 0xD4000000, 0x3E291B5E, 0xCB901057,
+ 0x3FF0052C, 0xD8000000, 0xBE3EC6FA, 0xE1B6D837,
+ 0x3FF00530, 0xD8000000, 0xBE24173F, 0xF8BF49E7,
+ 0x3FF00534, 0xD8000000, 0x3E257F80, 0x339DDB57,
+ 0x3FF00538, 0xD8000000, 0x3E3F9B25, 0x64D62C5C,
+ 0x3FF0053C, 0xDC000000, 0xBE26F2E0, 0x2E913659,
+ 0x3FF00540, 0xDC000000, 0x3E2303FF, 0x52E7CB93,
+ 0x3FF00544, 0xDC000000, 0x3E3E8D74, 0xAB0CFEF5,
+ 0x3FF00548, 0xE0000000, 0xBE28AE22, 0x1CF7FDE6,
+ 0x3FF0054C, 0xE0000000, 0x3E21A8DD, 0x01B47B93,
+ 0x3FF00550, 0xE0000000, 0x3E3E0FF3, 0x5D1107E2,
+ 0x3FF00554, 0xE4000000, 0xBE294904, 0xEBAC99E1,
+ 0x3FF00558, 0xE4000000, 0x3E216E1A, 0x184B2814,
+ 0x3FF0055C, 0xE4000000, 0x3E3E22A1, 0xE706008B,
+ 0x3FF00560, 0xE8000000, 0xBE28C387, 0xC267616A,
+ 0x3FF00564, 0xE8000000, 0x3E2253B7, 0x6EF3B008,
+ 0x3FF00568, 0xE8000000, 0x3E3EC580, 0xB50FF371,
+ 0x3FF0056C, 0xEC000000, 0xBE271DA9, 0xC8E0096B,
+ 0x3FF00570, 0xEC000000, 0x3E2459B5, 0xDDF69498,
+ 0x3FF00574, 0xEC000000, 0x3E3FF890, 0x33533C31,
+ 0x3FF00578, 0xF0000000, 0xBE24576A, 0x26CDA497,
+ 0x3FF0057C, 0xF0000000, 0x3E278016, 0x3D9CF923,
+ 0x3FF00580, 0xF4000000, 0xBE3E442F, 0x320B787B,
+ 0x3FF00584, 0xF4000000, 0xBE2070C8, 0x03E6A36B,
+ 0x3FF00588, 0xF4000000, 0x3E2BC6D9, 0x6630A33F,
+ 0x3FF0058C, 0xF8000000, 0xBE3BF0BD, 0x0EE72CBF,
+ 0x3FF00590, 0xF8000000, 0xBE16D385, 0x0FC1A853,
+ 0x3FF00594, 0xF8000000, 0x3E309700, 0x17FDFD5D,
+ 0x3FF00598, 0xFC000000, 0xBE390D18, 0xF71A91AC,
+ 0x3FF0059C, 0xFC000000, 0xBE050963, 0x69C58B86,
+ 0x3FF005A0, 0xFC000000, 0x3E33DAC5, 0xB9A504CD,
+ 0x3FF005A5, 0x00000000, 0xBE359942, 0x7E800734,
+ 0x3FF005A9, 0x00000000, 0x3DF02BAE, 0xE59934CD,
+ 0x3FF005AD, 0x00000000, 0x3E37AEBE, 0x04333E0E,
+ 0x3FF005B1, 0x04000000, 0xBE319539, 0x38F19C2F,
+ 0x3FF005B5, 0x04000000, 0x3E14DB54, 0xEBB1C157,
+ 0x3FF005B9, 0x04000000, 0x3E3C12E9, 0x63CED05D,
+ 0x3FF005BD, 0x08000000, 0xBE2A01F9, 0x74921CAF,
+ 0x3FF005C1, 0x08000000, 0x3E23F645, 0xC94C85F2,
+ 0x3FF005C5, 0x0C000000, 0xBE3EF8B7, 0xBB61CBEE,
+ 0x3FF005C9, 0x0C000000, 0xBE1F7232, 0x597F2931,
+ 0x3FF005CD, 0x0C000000, 0x3E2E9F48, 0xAF5B7345,
+ 0x3FF005D1, 0x10000000, 0xBE397424, 0xED37CD5F,
+ 0x3FF005D5, 0x10000000, 0xBE013F43, 0x08775C6B,
+ 0x3FF005D9, 0x10000000, 0x3E35345A, 0x0029D3DB,
+ 0x3FF005DD, 0x14000000, 0xBE335F5D, 0xC58C1962,
+ 0x3FF005E1, 0x14000000, 0x3E1073C1, 0x47430E04,
+ 0x3FF005E5, 0x14000000, 0x3E3BA944, 0x4A41E248,
+ 0x3FF005E9, 0x18000000, 0xBE2974C3, 0xB06E888E,
+ 0x3FF005ED, 0x18000000, 0x3E25E3FB, 0xDCCD9333,
+ 0x3FF005F1, 0x1C000000, 0xBE3D519C, 0x5DE27951,
+ 0x3FF005F5, 0x1C000000, 0xBE1614C2, 0xE4464502,
+ 0x3FF005F9, 0x1C000000, 0x3E325740, 0xE0DAFE93,
+ 0x3FF005FD, 0x20000000, 0xBE35BC47, 0x8C1B4C10,
+ 0x3FF00601, 0x20000000, 0x3E0201B0, 0x20686CE9,
+ 0x3FF00605, 0x20000000, 0x3E3A4CB9, 0x95558B63,
+ 0x3FF00609, 0x24000000, 0xBE2B2D79, 0xA880A3EB,
+ 0x3FF0060D, 0x24000000, 0x3E252BA5, 0x9699EEB7,
+ 0x3FF00611, 0x28000000, 0xBE3D2D97, 0x880115E1,
+ 0x3FF00615, 0x28000000, 0xBE1383EF, 0x28A3D788,
+ 0x3FF00619, 0x28000000, 0x3E337BA6, 0x08D6DC23,
+ 0x3FF0061D, 0x2C000000, 0xBE3417B2, 0x0B001A08,
+ 0x3FF00621, 0x2C000000, 0x3E1193EF, 0xF94EB99A,
+ 0x3FF00625, 0x2C000000, 0x3E3CF1B0, 0x28D3BD3B,
+ 0x3FF00629, 0x30000000, 0xBE24E32B, 0x0EFCC982,
+ 0x3FF0062D, 0x30000000, 0x3E2C7655, 0xE2BDA47F,
+ 0x3FF00631, 0x34000000, 0xBE39080E, 0x689312F8,
+ 0x3FF00635, 0x34000000, 0xBDCDA0C8, 0xA9444DB4,
+ 0x3FF00639, 0x34000000, 0x3E38A191, 0x7B21FE23,
+ 0x3FF0063D, 0x38000000, 0xBE2CE32A, 0x7E67E1E1,
+ 0x3FF00641, 0x38000000, 0x3E251694, 0x875A71F0,
+ 0x3FF00645, 0x3C000000, 0xBE3C67CF, 0xF838F455,
+ 0x3FF00649, 0x3C000000, 0xBE0A571F, 0x77274052,
+ 0x3FF0064D, 0x3C000000, 0x3E35E20E, 0x63AAEFA8,
+ 0x3FF00651, 0x40000000, 0xBE30E0F8, 0xFC87DA70,
+ 0x3FF00655, 0x40000000, 0x3E20D80B, 0xE9089AFD,
+ 0x3FF00659, 0x44000000, 0xBE3E36F4, 0xC52F03BD,
+ 0x3FF0065D, 0x44000000, 0xBE1327A4, 0x9680E14E,
+ 0x3FF00661, 0x44000000, 0x3E34B328, 0xD732468D,
+ 0x3FF00665, 0x48000000, 0xBE31BFBE, 0xCAB5EF4A,
+ 0x3FF00669, 0x48000000, 0x3E1F757F, 0xE2A2FBE1,
+ 0x3FF0066D, 0x4C000000, 0xBE3E757A, 0xDAB014DA,
+ 0x3FF00671, 0x4C000000, 0xBE12E13D, 0x02FB3FBB,
+ 0x3FF00675, 0x4C000000, 0x3E3514E2, 0xCA7E298D,
+ 0x3FF00679, 0x50000000, 0xBE310DE4, 0xB4F78B94,
+ 0x3FF0067D, 0x50000000, 0x3E21BEB4, 0x89C35D05,
+ 0x3FF00681, 0x54000000, 0xBE3D2360, 0x43F4895C,
+ 0x3FF00685, 0x54000000, 0xBE08B0A2, 0x5BC49ADF,
+ 0x3FF00689, 0x54000000, 0x3E37073E, 0x32573159,
+ 0x3FF0068D, 0x58000000, 0xBE2D96D1, 0x8D0732D2,
+ 0x3FF00691, 0x58000000, 0x3E26E3ED, 0x9BF15E67,
+ 0x3FF00695, 0x5C000000, 0xBE3A40A3, 0x0C3250FB,
+ 0x3FF00699, 0x5C000000, 0x3DBCC9AE, 0xFD0AE214,
+ 0x3FF0069D, 0x5C000000, 0x3E3A8A3D, 0x038868A1,
+ 0x3FF006A1, 0x60000000, 0xBE25F092, 0x151D21CE,
+ 0x3FF006A5, 0x60000000, 0x3E2F2A6F, 0x11738C43,
+ 0x3FF006A9, 0x64000000, 0xBE35CD41, 0x3E9CE96D,
+ 0x3FF006AD, 0x64000000, 0x3E138132, 0x8DBC2918,
+ 0x3FF006B1, 0x64000000, 0x3E3F9DE1, 0x32DF4C13,
+ 0x3FF006B5, 0x68000000, 0xBE16520E, 0x3129E0B2,
+ 0x3FF006B9, 0x68000000, 0x3E35491E, 0x69F36A61,
+ 0x3FF006BD, 0x6C000000, 0xBE2F9271, 0xCCCABCD4,
+ 0x3FF006C1, 0x6C000000, 0x3E2668ED, 0x0D59B899,
+ 0x3FF006C5, 0x70000000, 0xBE39BDD3, 0x4AD435A0,
+ 0x3FF006C9, 0x70000000, 0x3DF5FE9A, 0x9191CABB,
+ 0x3FF006CD, 0x70000000, 0x3E3C8DAD, 0x6676850B,
+ 0x3FF006D1, 0x74000000, 0xBE206910, 0x1D74934A,
+ 0x3FF006D5, 0x74000000, 0x3E331949, 0x4D886478,
+ 0x3FF006D9, 0x78000000, 0xBE3188DE, 0x80BFBBC2,
+ 0x3FF006DD, 0x78000000, 0x3E23CA01, 0x14DE1719,
+ 0x3FF006E1, 0x7C000000, 0xBE3A9D19, 0x8CE98EC0,
+ 0x3FF006E5, 0x7C000000, 0x3DEE1A67, 0xA705A6E7,
+ 0x3FF006E9, 0x7C000000, 0x3E3C8EC6, 0xECD5F851,
+ 0x3FF006ED, 0x80000000, 0xBE1F0CF9, 0xE839CE4D,
+ 0x3FF006F1, 0x80000000, 0x3E33FAC3, 0x0C8CA46A,
+ 0x3FF006F5, 0x84000000, 0xBE303734, 0x7B5703D8,
+ 0x3FF006F9, 0x84000000, 0x3E274DB5, 0xE490A112,
+ 0x3FF006FD, 0x88000000, 0xBE386B0E, 0xA693A093,
+ 0x3FF00701, 0x88000000, 0x3E0C9875, 0xF0B73DAA,
+ 0x3FF00705, 0x88000000, 0x3E3FA133, 0x2449A944,
+ 0x3FF00709, 0x8C000000, 0xBE110285, 0xBFE66C14,
+ 0x3FF0070D, 0x8C000000, 0x3E37ED91, 0x054EDCBD,
+ 0x3FF00711, 0x90000000, 0xBE27A86A, 0xEFB65924,
+ 0x3FF00715, 0x90000000, 0x3E307A0B, 0x1C8A0CF1,
+ 0x3FF00719, 0x94000000, 0xBE3327AD, 0x397FB1D6,
+ 0x3FF0071D, 0x94000000, 0x3E228D43, 0x1412B9FB,
+ 0x3FF00721, 0x98000000, 0xBE3A3B08, 0x94D8FFB0,
+ 0x3FF00725, 0x98000000, 0x3E029AA3, 0x6ED80040,
+ 0x3FF00729, 0x98000000, 0x3E3EF1B8, 0x9627250A,
+ 0x3FF0072D, 0x9C000000, 0xBE117F70, 0x5FCB1B09,
+ 0x3FF00731, 0x9C000000, 0x3E385E96, 0x678F0789,
+ 0x3FF00735, 0xA0000000, 0xBE25A5DF, 0xCEA3485B,
+ 0x3FF00739, 0xA0000000, 0x3E320B90, 0xFF6D0303,
+ 0x3FF0073D, 0xA4000000, 0xBE3105E6, 0xE03334FF,
+ 0x3FF00741, 0xA4000000, 0x3E27F150, 0xFB9F056D,
+ 0x3FF00745, 0xA8000000, 0xBE36F8C0, 0xE28905F4,
+ 0x3FF00749, 0xA8000000, 0x3E189774, 0x0B1407AA,
+ 0x3FF0074D, 0xAC000000, 0xBE3CAB7D, 0xCE4493C4,
+ 0x3FF00751, 0xAC000000, 0x3DE265D5, 0xCB817D78,
+ 0x3FF00755, 0xAC000000, 0x3E3DE1E2, 0x7CA8B4E3,
+ 0x3FF00759, 0xB0000000, 0xBE12FD89, 0x7D730FC6,
+ 0x3FF0075D, 0xB0000000, 0x3E38AF60, 0x1E4D7759,
+ 0x3FF00761, 0xB4000000, 0xBE23A3AC, 0x0CAD84A2,
+ 0x3FF00765, 0xB4000000, 0x3E33BCFB, 0x36B866FD,
+ 0x3FF00769, 0xB8000000, 0xBE2D4858, 0x4D0667A1,
+ 0x3FF0076D, 0xB8000000, 0x3E2E1567, 0xCBF08E6A,
+ 0x3FF00771, 0xBC000000, 0xBE333664, 0x9FD34D05,
+ 0x3FF00775, 0xBC000000, 0x3E253114, 0x9837D6E0,
+ 0x3FF00779, 0xC0000000, 0xBE37887F, 0x5238327D,
+ 0x3FF0077D, 0xC0000000, 0x3E1999FA, 0x24C8DC90,
+ 0x3FF00781, 0xC4000000, 0xBE3B9A7C, 0x1DA2F8BE,
+ 0x3FF00785, 0xC4000000, 0x3E03A485, 0xEA50EE6A,
+ 0x3FF00789, 0xC8000000, 0xBE3F6C5A, 0xE204A449,
+ 0x3FF0078D, 0xC8000000, 0xBDF3D3EF, 0x78D5D0F3,
+ 0x3FF00791, 0xC8000000, 0x3E3D01E4, 0x80B1D66C,
+ 0x3FF00795, 0xCC000000, 0xBE12BBC1, 0xD5149796,
+ 0x3FF00799, 0xCC000000, 0x3E39B042, 0x2A8F92F0,
+ 0x3FF0079D, 0xD0000000, 0xBE1F820E, 0x6F386487,
+ 0x3FF007A1, 0xD0000000, 0x3E369EBE, 0x3BA3BCDA,
+ 0x3FF007A5, 0xD4000000, 0xBE25A3F0, 0x96320652,
+ 0x3FF007A9, 0xD4000000, 0x3E33CD58, 0xD3FD8FCA,
+ 0x3FF007AD, 0xD8000000, 0xBE2B069C, 0xC62D40B1,
+ 0x3FF007B1, 0xD8000000, 0x3E313C12, 0x13AC5766,
+ 0x3FF007B5, 0xDC000000, 0xBE2FE90B, 0x876F3A0B,
+ 0x3FF007B9, 0xDC000000, 0x3E2DD5D4, 0x357EDEB8,
+ 0x3FF007BD, 0xE0000000, 0xBE32259E, 0x4CEC957E,
+ 0x3FF007C1, 0xE0000000, 0x3E29B3C2, 0x128C86C6,
+ 0x3FF007C5, 0xE4000000, 0xBE341697, 0xDEA61608,
+ 0x3FF007C9, 0xE4000000, 0x3E2611ED, 0xFEA09E70,
+ 0x3FF007CD, 0xE8000000, 0xBE35C772, 0x58D49AE3,
+ 0x3FF007D1, 0xE8000000, 0x3E22F058, 0x39DA3D42,
+ 0x3FF007D5, 0xEC000000, 0xBE37382D, 0x9B689043,
+ 0x3FF007D9, 0xEC000000, 0x3E204F01, 0x04589AD6,
+ 0x3FF007DD, 0xF0000000, 0xBE3868C9, 0x86525259,
+ 0x3FF007E1, 0xF0000000, 0x3E1C5BD1, 0x3C761DAC,
+ 0x3FF007E5, 0xF4000000, 0xBE395945, 0xF9822D4C,
+ 0x3FF007E9, 0xF4000000, 0x3E191A1E, 0x8F4221F9,
+ 0x3FF007ED, 0xF8000000, 0xBE3A09A2, 0xD4E85D3A,
+ 0x3FF007F1, 0xF8000000, 0x3E16D8EA, 0x81547225,
+ 0x3FF007F5, 0xFC000000, 0xBE3A79DF, 0xF8750E3B,
+ 0x3FF007F9, 0xFC000000, 0x3E159835, 0x92EC7DE3,
+ 0x3FF007FE, 0x00000000, 0xBE3AA9FD, 0x44185C5D } };
+
+#else
+#ifdef LITTLE_ENDI
+
+static const union {
+ int i[1424];
+ double x[712];
+} coar = { .i = {
+ 0xC8000000, 0x3FE69A59, 0x6079C9F7, 0x3DF22D4D,
+ 0xC8000000, 0x3FE6A5A9, 0x25AF6823, 0x3E19882D,
+ 0x74000000, 0x3FE6B0FF, 0x31DABF59, 0xBE221476,
+ 0xC8000000, 0x3FE6BC5A, 0x99A2DC0A, 0x3E2312AC,
+ 0xD0000000, 0x3FE6C7BB, 0xCE9F9355, 0xBE265926,
+ 0x84000000, 0x3FE6D322, 0x2D298DED, 0x3E2F2C26,
+ 0xF4000000, 0x3FE6DE8E, 0x1E748D2F, 0xBE2EC28E,
+ 0x14000000, 0x3FE6EA01, 0xC68CB7E5, 0x3E2D8C6D,
+ 0xF4000000, 0x3FE6F578, 0x419FE2F0, 0x3DEE1A9E,
+ 0x90000000, 0x3FE700F6, 0xDEAEAE34, 0xBDFF1AFD,
+ 0xEC000000, 0x3FE70C79, 0x558B7122, 0xBE0730FE,
+ 0x0C000000, 0x3FE71803, 0x2D280C3B, 0xBE25CB85,
+ 0xF0000000, 0x3FE72391, 0x337B7B54, 0xBE06F2CE,
+ 0x9C000000, 0x3FE72F26, 0x45C02B72, 0x3E289BCA,
+ 0x18000000, 0x3FE73AC1, 0x5039F1CA, 0xBE18DEA6,
+ 0x60000000, 0x3FE74661, 0x86CE0538, 0xBE09D090,
+ 0x78000000, 0x3FE75207, 0xCFCE5DDB, 0x3E290E79,
+ 0x68000000, 0x3FE75DB3, 0xB249A17C, 0x3DD61DF0,
+ 0x2C000000, 0x3FE76965, 0xE13445F7, 0x3E2F22F7,
+ 0xD0000000, 0x3FE7751C, 0x874E75CE, 0xBE2CD454,
+ 0x4C000000, 0x3FE780DA, 0xDF43E3BC, 0xBE0159CE,
+ 0xA8000000, 0x3FE78C9D, 0x699A1332, 0x3E279291,
+ 0xEC000000, 0x3FE79866, 0x2DD98C6C, 0xBE2A0BCD,
+ 0x10000000, 0x3FE7A436, 0x15AC979E, 0x3E25F375,
+ 0x20000000, 0x3FE7B00B, 0x2FEAFCF6, 0x3E26CCF5,
+ 0x1C000000, 0x3FE7BBE6, 0x53ADAD67, 0x3E27D4F4,
+ 0x08000000, 0x3FE7C7C7, 0x7FBD9566, 0x3E10EEC7,
+ 0xE4000000, 0x3FE7D3AD, 0x9A831D86, 0x3E2837F0,
+ 0xB8000000, 0x3FE7DF9A, 0x5CB4C35B, 0xBE129BE0,
+ 0x80000000, 0x3FE7EB8D, 0x0234F04D, 0x3E23990A,
+ 0x44000000, 0x3FE7F786, 0x64D5C842, 0x3E2EB807,
+ 0x08000000, 0x3FE80385, 0x02B4E9E8, 0x3E0FC86F,
+ 0xCC000000, 0x3FE80F89, 0x7B4274BF, 0xBDD7B5B3,
+ 0x94000000, 0x3FE81B94, 0xB899B00F, 0xBE16888B,
+ 0x60000000, 0x3FE827A5, 0x5E94D155, 0x3E288971,
+ 0x38000000, 0x3FE833BC, 0x099F3E5E, 0x3E2AEEB2,
+ 0x20000000, 0x3FE83FD9, 0x3FF60B7C, 0xBE23B922,
+ 0x14000000, 0x3FE84BFC, 0x2DBD8012, 0xBDF7D3B1,
+ 0x1C000000, 0x3FE85825, 0xA8872BEB, 0xBDF24BA3,
+ 0x38000000, 0x3FE86454, 0x01AA18A7, 0x3E2EFE04,
+ 0x70000000, 0x3FE87089, 0x944496A2, 0x3E21986C,
+ 0xC4000000, 0x3FE87CC4, 0xB71FFAFF, 0x3E096A8B,
+ 0x38000000, 0x3FE88906, 0xBC4C7AC5, 0xBE21CE0A,
+ 0xCC000000, 0x3FE8954D, 0xBAC02491, 0xBE076F45,
+ 0x84000000, 0x3FE8A19B, 0xD922B925, 0x3E2B4FA2,
+ 0x68000000, 0x3FE8ADEF, 0x641863AF, 0x3DF759DB,
+ 0x78000000, 0x3FE8BA49, 0xC6AB5E04, 0xBE2DB97C,
+ 0xB4000000, 0x3FE8C6A9, 0xE2156713, 0xBE25364C,
+ 0x20000000, 0x3FE8D310, 0x862BEFF7, 0x3E1BEB7C,
+ 0xC4000000, 0x3FE8DF7C, 0x1CEA33A5, 0xBDF4DD0C,
+ 0xA0000000, 0x3FE8EBEF, 0x51797D47, 0xBE2537DF,
+ 0xB4000000, 0x3FE8F868, 0xF0107B28, 0x3E0FB1C4,
+ 0x08000000, 0x3FE904E8, 0xE01B68BD, 0x3E0AD6A1,
+ 0x9C000000, 0x3FE9116D, 0x1F78D9D9, 0x3E292117,
+ 0x78000000, 0x3FE91DF9, 0x4F50E5CF, 0xBE1D75DA,
+ 0x98000000, 0x3FE92A8B, 0x74959E58, 0x3DE5102B,
+ 0x04000000, 0x3FE93724, 0xD2216C35, 0xBE01CA50,
+ 0xBC000000, 0x3FE943C2, 0xB0B05884, 0x3E225BFD,
+ 0xC8000000, 0x3FE95067, 0x60B7C5C1, 0xBE0F2183,
+ 0x24000000, 0x3FE95D13, 0xB5860441, 0x3E2FB47A,
+ 0xDC000000, 0x3FE969C4, 0xE2D4059E, 0xBE01FFD2,
+ 0xEC000000, 0x3FE9767C, 0x12BB6A8D, 0xBDE9ED72,
+ 0x58000000, 0x3FE9833B, 0x43BFFB24, 0x3E2B3815,
+ 0x28000000, 0x3FE99000, 0xEE9EAD1E, 0x3E03FA22,
+ 0x5C000000, 0x3FE99CCB, 0x377138F7, 0xBE213841,
+ 0xF4000000, 0x3FE9A99C, 0xDB636C94, 0x3E178105,
+ 0xF8000000, 0x3FE9B674, 0xF5720122, 0x3E1E5E7A,
+ 0x6C000000, 0x3FE9C353, 0xA2AC5AAE, 0xBE238BFF,
+ 0x4C000000, 0x3FE9D038, 0xF93BDBD8, 0x3E270893,
+ 0xA4000000, 0x3FE9DD23, 0x354B86CF, 0x3DF40420,
+ 0x74000000, 0x3FE9EA15, 0x88CB06B7, 0xBE2D76D3,
+ 0xBC000000, 0x3FE9F70D, 0x9ED0EC60, 0xBE251639,
+ 0x80000000, 0x3FEA040C, 0xE2DDE506, 0x3E1F06E9,
+ 0xC8000000, 0x3FEA1111, 0x8E6DB477, 0x3E014549,
+ 0x94000000, 0x3FEA1E1D, 0xF8716509, 0xBDF4BC17,
+ 0xE8000000, 0x3FEA2B2F, 0xDA723A49, 0xBE2107DB,
+ 0xC4000000, 0x3FEA3848, 0x986AA369, 0x3E1A932A,
+ 0x30000000, 0x3FEA4568, 0x41592CDB, 0x3E198092,
+ 0x30000000, 0x3FEA528E, 0x676BCAB8, 0xBE2E260F,
+ 0xC0000000, 0x3FEA5FBA, 0x2D5D5610, 0x3DE2E821,
+ 0xE8000000, 0x3FEA6CED, 0x7DA20167, 0x3E2F7046,
+ 0xB0000000, 0x3FEA7A27, 0xF9FAAD30, 0xBE1D2832,
+ 0x14000000, 0x3FEA8768, 0x43FA6C45, 0xBE23F788,
+ 0x18000000, 0x3FEA94AF, 0xAA082732, 0x3E011E27,
+ 0xC4000000, 0x3FEAA1FC, 0xC682F0BF, 0xBE20BACB,
+ 0x18000000, 0x3FEAAF51, 0x7BD08C78, 0xBE2DC7DD,
+ 0x14000000, 0x3FEABCAC, 0xA3B10F9A, 0x3E2271A2,
+ 0xC4000000, 0x3FEACA0D, 0x7966F94C, 0xBE15449C,
+ 0x24000000, 0x3FEAD776, 0x6FD8F3EE, 0x3DD06137,
+ 0x3C000000, 0x3FEAE4E5, 0x8C5A144A, 0xBE267CD1,
+ 0x0C000000, 0x3FEAF25B, 0xB59DA94B, 0xBE29E584,
+ 0x98000000, 0x3FEAFFD7, 0x7B52192F, 0xBE23DFCF,
+ 0xE4000000, 0x3FEB0D5A, 0x78A76B45, 0xBE1CF2FE,
+ 0xF4000000, 0x3FEB1AE4, 0x7EC80FF6, 0xBE23A561,
+ 0xC8000000, 0x3FEB2875, 0x932EED68, 0x3E22C4C9,
+ 0x68000000, 0x3FEB360D, 0xB5833C97, 0x3E2B085C,
+ 0xD8000000, 0x3FEB43AB, 0x93B9319A, 0xBE01F093,
+ 0x18000000, 0x3FEB5151, 0xFABCE670, 0xBE254F01,
+ 0x28000000, 0x3FEB5EFD, 0x627ABFB0, 0x3E2F24C2,
+ 0x14000000, 0x3FEB6CB0, 0xE6AC0B48, 0x3E1F1EEC,
+ 0xDC000000, 0x3FEB7A69, 0x127F9ABC, 0xBE1A8671,
+ 0x80000000, 0x3FEB882A, 0xC87C73B3, 0xBDCB0C28,
+ 0x08000000, 0x3FEB95F2, 0x7F2B5A97, 0xBE22E8DD,
+ 0x74000000, 0x3FEBA3C0, 0x2D22A9D5, 0xBE1B3645,
+ 0xC8000000, 0x3FEBB195, 0x428F8B88, 0x3E0ADACA,
+ 0x0C000000, 0x3FEBBF72, 0xCDF9F681, 0xBE2E9E07,
+ 0x3C000000, 0x3FEBCD55, 0x7FA54ACF, 0xBE08A127,
+ 0x60000000, 0x3FEBDB3F, 0x8225B385, 0x3E0E92CE,
+ 0x7C000000, 0x3FEBE930, 0x7BB09485, 0x3DF38C2A,
+ 0x94000000, 0x3FEBF728, 0xF681FA5F, 0xBE2DFD64,
+ 0xA4000000, 0x3FEC0527, 0xDCE88BD2, 0x3E2E384D,
+ 0xBC000000, 0x3FEC132D, 0xFE46A893, 0xBE20F111,
+ 0xD4000000, 0x3FEC213A, 0xB189BFDA, 0x3E193DA1,
+ 0xF8000000, 0x3FEC2F4E, 0x0E39FB00, 0xBE20E3A1,
+ 0x24000000, 0x3FEC3D6A, 0x30F0FAC5, 0x3E1DB044,
+ 0x64000000, 0x3FEC4B8C, 0x97446B17, 0xBE2BC12C,
+ 0xB4000000, 0x3FEC59B5, 0x963F4150, 0xBE282696,
+ 0x18000000, 0x3FEC67E6, 0x3049824B, 0x3E224D26,
+ 0x98000000, 0x3FEC761D, 0x87F84C7D, 0x3E2C5BA5,
+ 0x38000000, 0x3FEC845C, 0xC4852339, 0xBDE1D14D,
+ 0xF8000000, 0x3FEC92A1, 0x5588D9E1, 0xBE1A451E,
+ 0xDC000000, 0x3FECA0EE, 0x68BFF457, 0xBE1D3B96,
+ 0xE8000000, 0x3FECAF42, 0x4DADF774, 0xBE18B670,
+ 0x20000000, 0x3FECBD9E, 0x7FB1FC01, 0xBE1A1548,
+ 0x88000000, 0x3FECCC00, 0x78FC5AF0, 0xBE273F2E,
+ 0x20000000, 0x3FECDA6A, 0xA6F4A841, 0x3E1D218F,
+ 0xF0000000, 0x3FECE8DA, 0x4D002CA0, 0x3E2E0BA9,
+ 0xFC000000, 0x3FECF752, 0x065EF979, 0x3E20F4BB,
+ 0x48000000, 0x3FED05D2, 0x11793B33, 0xBE2ED3D5,
+ 0xD0000000, 0x3FED1458, 0x913341B3, 0x3E115E3C,
+ 0xA0000000, 0x3FED22E6, 0xB3546109, 0x3DE97C02,
+ 0xB8000000, 0x3FED317B, 0x1BF898EF, 0x3E087540,
+ 0x1C000000, 0x3FED4018, 0x346F9641, 0x3E209430,
+ 0xD0000000, 0x3FED4EBB, 0x88F4B20B, 0x3E2B6DF4,
+ 0xDC000000, 0x3FED5D66, 0x0CB26035, 0xBE2EC68F,
+ 0x38000000, 0x3FED6C19, 0x1F44D9C3, 0x3E2CA2C8,
+ 0xF4000000, 0x3FED7AD2, 0x41704EE0, 0x3E10E6F4,
+ 0x0C000000, 0x3FED8994, 0x25F8F0E2, 0x3E2F9273,
+ 0x88000000, 0x3FED985C, 0x318798DE, 0x3E2D041A,
+ 0x6C000000, 0x3FEDA72C, 0x9349CF58, 0xBE005680,
+ 0xB8000000, 0x3FEDB603, 0xCF0C934D, 0xBE10F665,
+ 0x70000000, 0x3FEDC4E2, 0x19461C64, 0x3E166124,
+ 0x9C000000, 0x3FEDD3C8, 0x405624C8, 0xBE1B2ED6,
+ 0x3C000000, 0x3FEDE2B6, 0x62171501, 0xBE273A7F,
+ 0x54000000, 0x3FEDF1AB, 0xE36E1450, 0xBE26022B,
+ 0xE8000000, 0x3FEE00A7, 0x2E07AE15, 0xBE1C341E,
+ 0xFC000000, 0x3FEE0FAB, 0x18D0E701, 0xBDFC7EAE,
+ 0x94000000, 0x3FEE1EB7, 0xECD1FF8B, 0x3E06B34F,
+ 0xB4000000, 0x3FEE2DCA, 0x6813A649, 0x3E1394A3,
+ 0x60000000, 0x3FEE3CE5, 0xC1754D14, 0x3E045496,
+ 0x9C000000, 0x3FEE4C07, 0xF5C6087C, 0xBE180FFF,
+ 0x68000000, 0x3FEE5B31, 0xADD9A300, 0x3E22FBCD,
+ 0xCC000000, 0x3FEE6A62, 0xAF0289E5, 0x3E2EC7C7,
+ 0xCC000000, 0x3FEE799B, 0x3FB3EDD4, 0x3E242182,
+ 0x6C000000, 0x3FEE88DC, 0x04E39885, 0xBE201304,
+ 0xAC000000, 0x3FEE9824, 0xE6831D31, 0xBE20D352,
+ 0x90000000, 0x3FEEA774, 0x618DFCEB, 0x3E1E032D,
+ 0x20000000, 0x3FEEB6CC, 0xF9BB457E, 0x3E1956A3,
+ 0x60000000, 0x3FEEC62B, 0x50845DB2, 0xBE2A77E0,
+ 0x4C000000, 0x3FEED592, 0x47C43858, 0x3E2714F7,
+ 0xF0000000, 0x3FEEE500, 0x71813A66, 0x3E2EED96,
+ 0x50000000, 0x3FEEF477, 0x4FB4AA34, 0xBE04CDBE,
+ 0x6C000000, 0x3FEF03F5, 0x86EB4FF5, 0xBE2774A2,
+ 0x48000000, 0x3FEF137B, 0xAD43B2D2, 0xBE29DD95,
+ 0xE8000000, 0x3FEF2308, 0xAC16E506, 0xBE1CADB0,
+ 0x50000000, 0x3FEF329E, 0x58745C7B, 0x3E12AC33,
+ 0x88000000, 0x3FEF423B, 0x6EC2D854, 0xBE248118,
+ 0x8C000000, 0x3FEF51E0, 0x304ACE08, 0x3E26986B,
+ 0x68000000, 0x3FEF618D, 0x3B09354E, 0x3E126D81,
+ 0x1C000000, 0x3FEF7142, 0x773C23B3, 0x3DF06AAE,
+ 0xAC000000, 0x3FEF80FE, 0xD82EF423, 0xBDA105B6,
+ 0x1C000000, 0x3FEF90C3, 0x465499B8, 0x3DECDEED,
+ 0x70000000, 0x3FEFA08F, 0xE2EF03AE, 0x3E0AEFD4,
+ 0xAC000000, 0x3FEFB063, 0x0567B2E7, 0x3E1BD4C0,
+ 0xD4000000, 0x3FEFC03F, 0x4F97FCBF, 0x3E26AA22,
+ 0xF0000000, 0x3FEFD023, 0x5E4E88D1, 0xBE2F9420,
+ 0xFC000000, 0x3FEFE00F, 0x438E52E2, 0xBE254004,
+ 0x00000000, 0x3FEFF004, 0xEEE93EFC, 0xBE1552AA,
+ 0x00000000, 0x3FF00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3FF00802, 0x4449F507, 0x3E155800,
+ 0x04000000, 0x3FF01008, 0x882D75D6, 0xBE354AA8,
+ 0x08000000, 0x3FF01812, 0x3740DE56, 0x3E303610,
+ 0x14000000, 0x3FF02020, 0x5B0C3264, 0x3E360044,
+ 0x28000000, 0x3FF02832, 0x0197EDC3, 0x3E3C4C26,
+ 0x48000000, 0x3FF03048, 0x5046CA09, 0x3E0B103B,
+ 0x74000000, 0x3FF03862, 0xF9A62624, 0xBE34659C,
+ 0xAC000000, 0x3FF04080, 0xDD0A8F37, 0xBE254438,
+ 0xF4000000, 0x3FF048A2, 0x97AFB6E2, 0x3DF256C2,
+ 0x50000000, 0x3FF050C9, 0x923D25E1, 0xBE3085DF,
+ 0xC0000000, 0x3FF058F3, 0x5EA3B091, 0xBE3F0A93,
+ 0x44000000, 0x3FF06122, 0x5D63534C, 0xBE237DE4,
+ 0xE0000000, 0x3FF06954, 0xFF0C58B7, 0x3E301719,
+ 0x98000000, 0x3FF0718B, 0x9DF7B665, 0x3E2E8410,
+ 0x6C000000, 0x3FF079C6, 0x3B127222, 0x3E349CB9,
+ 0x60000000, 0x3FF08205, 0x98E0BD08, 0x3DF127EC,
+ 0x74000000, 0x3FF08A48, 0x706CC41F, 0xBE24C1B6,
+ 0xA8000000, 0x3FF0928F, 0x093044EF, 0x3E334EF9,
+ 0x04000000, 0x3FF09ADB, 0x56BC6C83, 0xBE1304B1,
+ 0x84000000, 0x3FF0A32A, 0xB028B984, 0x3E2D383E,
+ 0x30000000, 0x3FF0AB7E, 0x64E7A202, 0xBE315B1E,
+ 0x04000000, 0x3FF0B3D6, 0xC678291E, 0xBE0AC1E6,
+ 0x04000000, 0x3FF0BC32, 0x2F12FFE2, 0x3E3A0418,
+ 0x38000000, 0x3FF0C492, 0x43D6D302, 0xBE37D617,
+ 0x98000000, 0x3FF0CCF6, 0x152CC8FA, 0x3E2133F2,
+ 0x2C000000, 0x3FF0D55F, 0xE966E6B7, 0x3E3CE5D1,
+ 0xF8000000, 0x3FF0DDCB, 0x7BCACA64, 0x3E1ABF24,
+ 0xFC000000, 0x3FF0E63C, 0x2E8CDBED, 0xBE3854F6,
+ 0x38000000, 0x3FF0EEB2, 0x0C32156B, 0xBE3E6463,
+ 0xAC000000, 0x3FF0F72B, 0xB69772CC, 0x3E365671,
+ 0x64000000, 0x3FF0FFA9, 0x02B1201A, 0xBE383E9A,
+ 0x58000000, 0x3FF1082B, 0x50549CC0, 0xBE205962,
+ 0x90000000, 0x3FF110B1, 0xFFDACA72, 0xBE376BFE,
+ 0x08000000, 0x3FF1193C, 0x5C43E2F3, 0x3E3C1C59,
+ 0xCC000000, 0x3FF121CA, 0xF7067C8B, 0xBE26D374,
+ 0xD4000000, 0x3FF12A5D, 0x4DDAFE1D, 0x3E343CCC,
+ 0x28000000, 0x3FF132F5, 0x58EBCB7F, 0x3E3D5C16,
+ 0xCC000000, 0x3FF13B90, 0xB66E8B53, 0xBE2B5D12,
+ 0xBC000000, 0x3FF14430, 0xB326B482, 0xBE24E919,
+ 0xFC000000, 0x3FF14CD4, 0xC8AABD43, 0x3E23139A,
+ 0x90000000, 0x3FF1557D, 0x16743B55, 0x3E30DD8B,
+ 0x7C000000, 0x3FF15E2A, 0x35904C50, 0xBE31D701,
+ 0xBC000000, 0x3FF166DB, 0x30E0CA83, 0x3E107F42,
+ 0x58000000, 0x3FF16F91, 0xDA1B7123, 0xBE24F1F2,
+ 0x50000000, 0x3FF1784B, 0x0DC79E23, 0xBE3ACAF2,
+ 0xA4000000, 0x3FF18109, 0x609374EE, 0xBE23DC79,
+ 0x58000000, 0x3FF189CC, 0x3A40C3B7, 0x3E262CF7,
+ 0x70000000, 0x3FF19293, 0x5A24F463, 0x3E1D3833,
+ 0xEC000000, 0x3FF19B5E, 0x8A2E4440, 0x3E2BA9AD,
+ 0xD0000000, 0x3FF1A42E, 0x61C41828, 0x3DFD8CBC,
+ 0x1C000000, 0x3FF1AD03, 0x5A4DDF0D, 0x3E1A65E6,
+ 0xD4000000, 0x3FF1B5DB, 0x9F828DB5, 0xBDE2FDBB,
+ 0xF8000000, 0x3FF1BEB8, 0xB79B700F, 0x3E2F4EE8,
+ 0x8C000000, 0x3FF1C79A, 0x0DE1D7E8, 0x3E3ACC35,
+ 0x94000000, 0x3FF1D080, 0xFF9E20A0, 0x3E11729E,
+ 0x10000000, 0x3FF1D96B, 0x6C2EA70B, 0xBE300F18,
+ 0x00000000, 0x3FF1E25A, 0xCE425A35, 0x3DF32E02,
+ 0x68000000, 0x3FF1EB4D, 0x9A322D12, 0x3E3BDE56,
+ 0x50000000, 0x3FF1F445, 0xBA737AEF, 0xBE3C3F0D,
+ 0xB0000000, 0x3FF1FD41, 0xC896DB7A, 0xBE0A2DD0,
+ 0x90000000, 0x3FF20642, 0xF8B782F6, 0x3E2577B0,
+ 0xF4000000, 0x3FF20F47, 0x73607FC8, 0xBE2C6DA3,
+ 0xD8000000, 0x3FF21851, 0xC8917348, 0x3E35F7D1,
+ 0x44000000, 0x3FF22160, 0xCF9CED69, 0x3E3B6F5C,
+ 0x3C000000, 0x3FF22A73, 0x85775C2E, 0xBE39967E,
+ 0xB8000000, 0x3FF2338A, 0x497226D4, 0x3E3B3213,
+ 0xC4000000, 0x3FF23CA6, 0x30733227, 0x3E3E2710,
+ 0x60000000, 0x3FF245C7, 0xAF215A72, 0x3E33B8A9,
+ 0x90000000, 0x3FF24EEC, 0x1365623F, 0xBE3F96B2,
+ 0x50000000, 0x3FF25816, 0x27DEE202, 0xBE37324F,
+ 0xA4000000, 0x3FF26144, 0x4E484D87, 0x3E318CD5,
+ 0x94000000, 0x3FF26A77, 0xA94519E8, 0xBDE3FD37,
+ 0x1C000000, 0x3FF273AF, 0xEE788C29, 0x3E37132F,
+ 0x44000000, 0x3FF27CEB, 0xE842E5C0, 0xBE03DDB7,
+ 0x08000000, 0x3FF2862C, 0xE17C9693, 0x3E37A3FB,
+ 0x70000000, 0x3FF28F71, 0xAEB3D9A0, 0x3E24EABF,
+ 0x7C000000, 0x3FF298BB, 0x853B0733, 0xBE13C7B6,
+ 0x2C000000, 0x3FF2A20A, 0xC7B588B5, 0x3E2D2C80,
+ 0x88000000, 0x3FF2AB5D, 0x708F3912, 0xBE35B750,
+ 0x8C000000, 0x3FF2B4B5, 0xD5FD9130, 0xBE291A70,
+ 0x3C000000, 0x3FF2BE12, 0x0CCF9F73, 0x3E2EE937,
+ 0xA0000000, 0x3FF2C773, 0xD42CF76C, 0xBE3C3F0C,
+ 0xB0000000, 0x3FF2D0D9, 0x60763D61, 0x3E35DD54,
+ 0x78000000, 0x3FF2DA44, 0xE7D6AA3B, 0x3E26C418,
+ 0xF8000000, 0x3FF2E3B3, 0x6FB9B7A8, 0xBE3605C6,
+ 0x2C000000, 0x3FF2ED28, 0x24DCDDF5, 0x3E3763D4,
+ 0x20000000, 0x3FF2F6A1, 0xA8EC1AA8, 0xBE1A411E,
+ 0xD0000000, 0x3FF3001E, 0x1FE8546F, 0xBE23FCA1,
+ 0x40000000, 0x3FF309A1, 0x3AAEE75E, 0xBE29DF0D,
+ 0x70000000, 0x3FF31328, 0x3C2C4206, 0x3E36A5D6,
+ 0x68000000, 0x3FF31CB4, 0xB4C979B0, 0x3E1B7A3E,
+ 0x28000000, 0x3FF32645, 0x706CD593, 0xBE36157D,
+ 0xB0000000, 0x3FF32FDA, 0x8DA4C646, 0xBE39F357,
+ 0x04000000, 0x3FF33975, 0xD575FE6F, 0xBE3E64DE,
+ 0x24000000, 0x3FF34314, 0x44D008E0, 0x3E07F9E3,
+ 0x18000000, 0x3FF34CB8, 0x5A563E77, 0xBE2E94F9,
+ 0xDC000000, 0x3FF35660, 0x2475EF19, 0x3E314DC2,
+ 0x78000000, 0x3FF3600E, 0xA33AC606, 0x3E26D623,
+ 0xEC000000, 0x3FF369C0, 0xC05B3160, 0x3E170F86,
+ 0x3C000000, 0x3FF37378, 0xDB0AE31A, 0xBE38DDFE,
+ 0x64000000, 0x3FF37D34, 0x5706B570, 0x3E3662A9,
+ 0x70000000, 0x3FF386F5, 0x6770731E, 0xBE1625E4,
+ 0x5C000000, 0x3FF390BB, 0x62971091, 0xBE1678F1,
+ 0x2C000000, 0x3FF39A86, 0xD045CB0C, 0xBE061F7C,
+ 0xE4000000, 0x3FF3A455, 0x568B1CA2, 0xBE35CF51,
+ 0x84000000, 0x3FF3AE2A, 0x7FB61F58, 0xBE378185,
+ 0x0C000000, 0x3FF3B804, 0x4FA133AF, 0x3E3F77F4,
+ 0x88000000, 0x3FF3C1E2, 0xB00B73FE, 0xBE22F96A,
+ 0xF0000000, 0x3FF3CBC5, 0x1EB4CE2F, 0x3E351A64,
+ 0x50000000, 0x3FF3D5AE, 0xD3755639, 0xBE3D3516,
+ 0xA0000000, 0x3FF3DF9B, 0x43E8C10E, 0x3E1CD938,
+ 0xEC000000, 0x3FF3E98D, 0x455C8842, 0xBE35EE23,
+ 0x30000000, 0x3FF3F385, 0x96C9F4ED, 0xBE29B282,
+ 0x70000000, 0x3FF3FD81, 0x3168CC0B, 0x3E24A40E,
+ 0xB0000000, 0x3FF40782, 0x86C72839, 0x3E3784BC,
+ 0xF4000000, 0x3FF41188, 0x0785D847, 0x3E061F19,
+ 0x3C000000, 0x3FF41B94, 0xE654A9C9, 0xBE27AEF2,
+ 0x88000000, 0x3FF425A4, 0xF9E4C1BA, 0x3E33DFC3,
+ 0xE0000000, 0x3FF42FB9, 0x593D0C75, 0x3E2455A8,
+ 0x44000000, 0x3FF439D4, 0x238B65D1, 0xBDE41D4E,
+ 0xB4000000, 0x3FF443F3, 0x454CBECB, 0x3E3BE616,
+ 0x38000000, 0x3FF44E18, 0x931C5332, 0x3E207B3C,
+ 0xD0000000, 0x3FF45841, 0x7615DCC9, 0xBE330846,
+ 0x7C000000, 0x3FF46270, 0xE497F84E, 0xBE2A8A7B,
+ 0x40000000, 0x3FF46CA4, 0xF737AF78, 0x3E020B50,
+ 0x20000000, 0x3FF476DD, 0xE34AFBD3, 0x3E116B19,
+ 0x20000000, 0x3FF4811B, 0x841EDB52, 0xBE3E15A7,
+ 0x3C000000, 0x3FF48B5E, 0x33B3DE1E, 0x3E0F40C3,
+ 0x7C000000, 0x3FF495A6, 0x92EFEE02, 0x3E33607F,
+ 0xE4000000, 0x3FF49FF3, 0x14F7E168, 0xBE1A2DB5,
+ 0x70000000, 0x3FF4AA46, 0x3EBA1C94, 0x3E3F59EC,
+ 0x2C000000, 0x3FF4B49E, 0x8B9AE885, 0xBE31A539,
+ 0x10000000, 0x3FF4BEFB, 0xF13C8C95, 0x3E2FAC0B,
+ 0x28000000, 0x3FF4C95D, 0xF8B74775, 0xBE32C0BB,
+ 0x70000000, 0x3FF4D3C4, 0x4F9474BB, 0xBE2FC24E,
+ 0xEC000000, 0x3FF4DE30, 0x09DA911F, 0x3E008F30,
+ 0xA0000000, 0x3FF4E8A2, 0xBAF8D98B, 0x3E2994C1,
+ 0x90000000, 0x3FF4F319, 0x18648D0A, 0xBE17C38C,
+ 0xBC000000, 0x3FF4FD95, 0xF22F8698, 0xBE288852,
+ 0x28000000, 0x3FF50817, 0x30A2C153, 0xBE3C3EC3,
+ 0xD4000000, 0x3FF5129D, 0x968492AA, 0xBE27B606,
+ 0xC4000000, 0x3FF51D29, 0x61101629, 0x3E2E0396,
+ 0xFC000000, 0x3FF527BA, 0xDAEEAB38, 0x3E3E876F,
+ 0x80000000, 0x3FF53251, 0xED945B30, 0x3E29F59E,
+ 0x50000000, 0x3FF53CED, 0x0B4AE3F1, 0x3E12D7DA,
+ 0x70000000, 0x3FF5478E, 0x5FB946D0, 0xBE2FAFB8,
+ 0xE0000000, 0x3FF55234, 0x87D80C66, 0xBE18A8B3,
+ 0xA4000000, 0x3FF55CE0, 0x764CF85C, 0x3E28B18F,
+ 0xC0000000, 0x3FF56791, 0x2BDBC6F4, 0x3E326017,
+ 0x38000000, 0x3FF57248, 0x53D523FE, 0xBE229F98,
+ 0x0C000000, 0x3FF57D04, 0x4D9B8720, 0xBE3BDD08,
+ 0x3C000000, 0x3FF587C5, 0x09D8749E, 0x3E169EBC,
+ 0xD0000000, 0x3FF5928B, 0x339C2080, 0x3E190C8C,
+ 0xC8000000, 0x3FF59D57, 0xDE75E9CA, 0x3E310FA4,
+ 0x28000000, 0x3FF5A829, 0x1097F186, 0x3E313D18,
+ 0xF4000000, 0x3FF5B2FF, 0xD51C23F6, 0xBE2BDE04,
+ 0x28000000, 0x3FF5BDDC, 0x8938C386, 0x3E3EE67E,
+ 0xD0000000, 0x3FF5C8BD, 0x47DF6575, 0x3E0973B8,
+ 0xE8000000, 0x3FF5D3A4, 0x1DB97781, 0x3E24DF02,
+ 0x78000000, 0x3FF5DE91, 0xAC4AECDC, 0xBE3FBA00,
+ 0x7C000000, 0x3FF5E983, 0x939F646A, 0xBE2F37AF,
+ 0xFC000000, 0x3FF5F47A, 0x58A6EEE9, 0xBE396DEF,
+ 0xF8000000, 0x3FF5FF77, 0xE3613C7B, 0xBE315248,
+ 0x74000000, 0x3FF60A7A, 0xF1553706, 0xBE26A9E2,
+ 0x74000000, 0x3FF61582, 0xAE4D7CB6, 0xBE3B6BF6,
+ 0xF8000000, 0x3FF6208F, 0x9EB5EBA5, 0xBE35775B,
+ 0x04000000, 0x3FF62BA3, 0xC1E43506, 0xBE2A821B,
+ 0x9C000000, 0x3FF636BB, 0x7B2D8CF4, 0xBE367CDA,
+ 0xC0000000, 0x3FF641D9, 0x3E907A1D, 0xBE13218B,
+ 0x74000000, 0x3FF64CFD, 0x7BF5DFE4, 0x3E3454EE,
+ 0xC0000000, 0x3FF65826, 0x6366C5FD, 0xBE3E960F,
+ 0x9C000000, 0x3FF66355, 0x8B43C17E, 0x3E2E378F,
+ 0x14000000, 0x3FF66E8A, 0xA4306535, 0x3E244BE0,
+ 0x28000000, 0x3FF679C4, 0x8DF63D6E, 0xBDE4B6C1,
+ 0xD8000000, 0x3FF68503, 0xE6A239CF, 0x3E3BA122,
+ 0x2C000000, 0x3FF69049, 0x59FB5F30, 0x3E27F286,
+ 0x24000000, 0x3FF69B94, 0x971D3970, 0xBE044041 } };
+
+static const union {
+ int4 i[2048];
+ double x[1024];
+} fine = { .i = {
+ 0x00000000, 0x3FF00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3FF00004, 0x55556AAB, 0x3DA00001,
+ 0x00000000, 0x3FF00008, 0xAAAB0000, 0x3DC00002,
+ 0x00000000, 0x3FF0000C, 0x8000D800, 0x3DD20004,
+ 0x00000000, 0x3FF00010, 0x5556AAAB, 0x3DE00005,
+ 0x00000000, 0x3FF00014, 0x6AADEC01, 0x3DE9000A,
+ 0x00000000, 0x3FF00018, 0x00036001, 0x3DF20009,
+ 0x00000000, 0x3FF0001C, 0x4AB0EB58, 0x3DF8800E,
+ 0x00000000, 0x3FF00020, 0xAAB00002, 0x3E00000A,
+ 0x00000000, 0x3FF00024, 0x30088B04, 0x3E04400F,
+ 0x00000000, 0x3FF00028, 0xD5625AB1, 0x3E090014,
+ 0x00000000, 0x3FF0002C, 0xBABDBB0A, 0x3E0E401B,
+ 0x00000000, 0x3FF00030, 0x000D8008, 0x3E120012,
+ 0x00000000, 0x3FF00034, 0xE2BD42E1, 0x3E152016,
+ 0x00000000, 0x3FF00038, 0x956E5812, 0x3E18801C,
+ 0x00000000, 0x3FF0003C, 0x2820F599, 0x3E1C2023,
+ 0x00000000, 0x3FF00040, 0x556AAABC, 0x3E200015,
+ 0x00000000, 0x3FF00044, 0x96C5DAD7, 0x3E221019,
+ 0x00000000, 0x3FF00048, 0x60222C1F, 0x3E24401E,
+ 0x00000000, 0x3FF0004C, 0xB97FC193, 0x3E269023,
+ 0x00000000, 0x3FF00050, 0xAADEC034, 0x3E290029,
+ 0x00000000, 0x3FF00054, 0x3C3F4F02, 0x3E2B9030,
+ 0x00000000, 0x3FF00058, 0x75A196FF, 0x3E2E4037,
+ 0x00000000, 0x3FF0005C, 0xAF82E194, 0x3E30881F,
+ 0x00000000, 0x3FF00060, 0x00360041, 0x3E320024,
+ 0x00000000, 0x3FF00064, 0xB0EA3F05, 0x3E338828,
+ 0x00000000, 0x3FF00068, 0xC59FB661, 0x3E35202D,
+ 0x00000000, 0x3FF0006C, 0x42567FD5, 0x3E36C833,
+ 0x00000000, 0x3FF00070, 0x2B0EB5E1, 0x3E388039,
+ 0x00000000, 0x3FF00074, 0x83C87407, 0x3E3A483F,
+ 0x00000000, 0x3FF00078, 0x5083D6C6, 0x3E3C2046,
+ 0x00000000, 0x3FF0007C, 0x9540FB9E, 0x3E3E084D,
+ 0x04000000, 0x3FF00080, 0xA9FFFEEF, 0xBE3FFFAA,
+ 0x04000000, 0x3FF00084, 0x693EF962, 0xBE3DF7A2,
+ 0x04000000, 0x3FF00088, 0xA47BD339, 0xBE3BDF99,
+ 0x04000000, 0x3FF0008C, 0x57B66AF5, 0xBE39B790,
+ 0x04000000, 0x3FF00090, 0x7EEE9E14, 0xBE377F86,
+ 0x04000000, 0x3FF00094, 0x16244916, 0xBE35377C,
+ 0x04000000, 0x3FF00098, 0x1957477B, 0xBE32DF71,
+ 0x04000000, 0x3FF0009C, 0x848773C2, 0xBE307765,
+ 0x04000000, 0x3FF000A0, 0xA7694ED3, 0xBE2BFEB2,
+ 0x04000000, 0x3FF000A4, 0x05BD75E2, 0xBE26EE99,
+ 0x04000000, 0x3FF000A8, 0x1C0B0BB1, 0xBE21BE7E,
+ 0x04000000, 0x3FF000AC, 0xC4A37A79, 0xBE18DCC3,
+ 0x04000000, 0x3FF000B0, 0x4244D60F, 0xBE0BF911,
+ 0x04000000, 0x3FF000B4, 0xEC91D848, 0xBDE6E255,
+ 0x04000000, 0x3FF000B8, 0xEC1B8F0C, 0x3E0107EB,
+ 0x04000000, 0x3FF000BC, 0x89BE52AA, 0x3E142439,
+ 0x04000000, 0x3FF000C0, 0x06C01033, 0x3E200240,
+ 0x04000000, 0x3FF000C4, 0xC8A9F760, 0x3E261264,
+ 0x04000000, 0x3FF000C8, 0x129D3FDE, 0x3E2C428B,
+ 0x04000000, 0x3FF000CC, 0x764D2658, 0x3E314959,
+ 0x04000000, 0x3FF000D0, 0x2F50C16C, 0x3E34816E,
+ 0x04000000, 0x3FF000D4, 0xB859A4AB, 0x3E37C983,
+ 0x04000000, 0x3FF000D8, 0x15680499, 0x3E3B219A,
+ 0x04000000, 0x3FF000DC, 0x4A7C16B5, 0x3E3E89B1,
+ 0x08000000, 0x3FF000E0, 0xA469EE7E, 0xBE3DFE36,
+ 0x08000000, 0x3FF000E4, 0xB349D37F, 0xBE3A761D,
+ 0x08000000, 0x3FF000E8, 0xDE235FCD, 0xBE36DE03,
+ 0x08000000, 0x3FF000EC, 0x20F659E6, 0xBE3335E9,
+ 0x08000000, 0x3FF000F0, 0xEF850E8F, 0xBE2EFB9A,
+ 0x08000000, 0x3FF000F4, 0xBD0F58E2, 0xBE276B61,
+ 0x08000000, 0x3FF000F8, 0x45163381, 0xBE1F764D,
+ 0x08000000, 0x3FF000FC, 0x5FDF589A, 0xBE0FABA6,
+ 0x08000000, 0x3FF00100, 0xABBBBE94, 0x3D8555AA,
+ 0x08000000, 0x3FF00104, 0xDABB690B, 0x3E102B2C,
+ 0x08000000, 0x3FF00108, 0x7820FBA0, 0x3E2045D9,
+ 0x08000000, 0x3FF0010C, 0x92F54742, 0x3E28961E,
+ 0x08000000, 0x3FF00110, 0xE2ED8E39, 0x3E308332,
+ 0x08000000, 0x3FF00114, 0x8C698119, 0x3E34CB57,
+ 0x08000000, 0x3FF00118, 0x49EEC0C4, 0x3E39237D,
+ 0x08000000, 0x3FF0011C, 0x1F7D92BC, 0x3E3D8BA4,
+ 0x0C000000, 0x3FF00120, 0xEEE9C27D, 0xBE3DFC33,
+ 0x0C000000, 0x3FF00124, 0xDD46F763, 0xBE39740A,
+ 0x0C000000, 0x3FF00128, 0xA799C375, 0xBE34DBE0,
+ 0x0C000000, 0x3FF0012C, 0x49E1DD2F, 0xBE3033B5,
+ 0x0C000000, 0x3FF00130, 0x803DF41F, 0xBE26F711,
+ 0x0C000000, 0x3FF00134, 0x19433A4C, 0xBE1ACD6C,
+ 0x0C000000, 0x3FF00138, 0x8770E36F, 0xBDFDB2C1,
+ 0x0C000000, 0x3FF0013C, 0x6B74A43E, 0x3E086820,
+ 0x0C000000, 0x3FF00140, 0xDEC0D058, 0x3E200A6A,
+ 0x0C000000, 0x3FF00144, 0x22BD7872, 0x3E2A1AD0,
+ 0x0C000000, 0x3FF00148, 0xF769E132, 0x3E32259B,
+ 0x0C000000, 0x3FF0014C, 0x2582289A, 0x3E374DD1,
+ 0x0C000000, 0x3FF00150, 0x9FA7E4F4, 0x3E3C8607,
+ 0x10000000, 0x3FF00154, 0x9624963C, 0xBE3E31C0,
+ 0x10000000, 0x3FF00158, 0x77E2F472, 0xBE38D987,
+ 0x10000000, 0x3FF0015C, 0x0192E02C, 0xBE33714D,
+ 0x10000000, 0x3FF00160, 0x5E6805CB, 0xBE2BF222,
+ 0x10000000, 0x3FF00164, 0xF98C0A34, 0xBE20E1A7,
+ 0x10000000, 0x3FF00168, 0x32447238, 0xBE06C4AB,
+ 0x10000000, 0x3FF0016C, 0xC225D8C1, 0x3E067D54,
+ 0x10000000, 0x3FF00170, 0x05C4630F, 0x3E210FD8,
+ 0x10000000, 0x3FF00174, 0xBB206115, 0x3E2CA05D,
+ 0x10000000, 0x3FF00178, 0x2C4F14A6, 0x3E342873,
+ 0x10000000, 0x3FF0017C, 0xF31F3B5E, 0x3E3A10B8,
+ 0x14000000, 0x3FF00180, 0xC9FEFCC9, 0xBE3FF6FF,
+ 0x14000000, 0x3FF00184, 0x070B344A, 0xBE39EEB7,
+ 0x14000000, 0x3FF00188, 0xC0050AA2, 0xBE33D66C,
+ 0x14000000, 0x3FF0018C, 0xE1D83C97, 0xBE2B5C41,
+ 0x14000000, 0x3FF00190, 0x57003305, 0xBE1DD74E,
+ 0x14000000, 0x3FF00194, 0xA80727F1, 0xBDF2D84A,
+ 0x14000000, 0x3FF00198, 0x534C5401, 0x3E14AB2F,
+ 0x14000000, 0x3FF0019C, 0xD875DE83, 0x3E27263B,
+ 0x14000000, 0x3FF001A0, 0x9FB782CA, 0x3E320B71,
+ 0x14000000, 0x3FF001A4, 0xF349371F, 0x3E3893C6,
+ 0x14000000, 0x3FF001A8, 0xEAF074C6, 0x3E3F2C1D,
+ 0x18000000, 0x3FF001AC, 0x75525ABC, 0xBE3A2B89,
+ 0x18000000, 0x3FF001B0, 0x297ECCE2, 0xBE33732F,
+ 0x18000000, 0x3FF001B4, 0x5B28EC49, 0xBE2955A6,
+ 0x18000000, 0x3FF001B8, 0xF64BA7FD, 0xBE1749D5,
+ 0x18000000, 0x3FF001BC, 0xA8645141, 0x3DF15E9E,
+ 0x18000000, 0x3FF001C0, 0x1D6F0B37, 0x3E201C96,
+ 0x18000000, 0x3FF001C4, 0xE6028E39, 0x3E2E2D5B,
+ 0x18000000, 0x3FF001C8, 0x9B63FA1E, 0x3E362F12,
+ 0x18000000, 0x3FF001CC, 0x0BE01026, 0x3E3D5779,
+ 0x1C000000, 0x3FF001D0, 0xB78A0445, 0xBE3B701E,
+ 0x1C000000, 0x3FF001D4, 0xAAD9CF9D, 0xBE3427B4,
+ 0x1C000000, 0x3FF001D8, 0x941DBAB5, 0xBE299E91,
+ 0x1C000000, 0x3FF001DC, 0x44A2DFDD, 0xBE159B6C,
+ 0x1C000000, 0x3FF001E0, 0x1EC8B89C, 0x3E008CA4,
+ 0x1C000000, 0x3FF001E4, 0xF1EE0E9A, 0x3E23340B,
+ 0x1C000000, 0x3FF001E8, 0x5231913C, 0x3E313279,
+ 0x1C000000, 0x3FF001EC, 0x93892E68, 0x3E38DAEE,
+ 0x20000000, 0x3FF001F0, 0x3F01A6A8, 0xBE3F6C9A,
+ 0x20000000, 0x3FF001F4, 0x216E726C, 0xBE37A421,
+ 0x20000000, 0x3FF001F8, 0x1F7970B9, 0xBE2F974C,
+ 0x20000000, 0x3FF001FC, 0x17AFEBC8, 0xBE1F8CA4,
+ 0x20000000, 0x3FF00200, 0x04445B06, 0x3DB55600,
+ 0x20000000, 0x3FF00204, 0x0C290A26, 0x3E203BAE,
+ 0x20000000, 0x3FF00208, 0x104547BD, 0x3E30365A,
+ 0x20000000, 0x3FF0020C, 0x22970DE3, 0x3E385EDF,
+ 0x24000000, 0x3FF00210, 0xBEF5A5F4, 0xBE3F6899,
+ 0x24000000, 0x3FF00214, 0x90605040, 0xBE372010,
+ 0x24000000, 0x3FF00218, 0x9B50D8EE, 0xBE2D8F0A,
+ 0x24000000, 0x3FF0021C, 0xCB35D444, 0xBE197BDF,
+ 0x24000000, 0x3FF00220, 0x2188E3D5, 0x3E00CCBC,
+ 0x24000000, 0x3FF00224, 0x36A79F6A, 0x3E254452,
+ 0x24000000, 0x3FF00228, 0xD69B2D28, 0x3E333ABC,
+ 0x24000000, 0x3FF0022C, 0xBA07BE5B, 0x3E3BE352,
+ 0x28000000, 0x3FF00230, 0x3665F227, 0xBE3B6415,
+ 0x28000000, 0x3FF00234, 0xF6AD58D5, 0xBE329B7A,
+ 0x28000000, 0x3FF00238, 0x059BD24A, 0xBE2385BD,
+ 0x28000000, 0x3FF0023C, 0xD8E2B1B4, 0xBDEB47FA,
+ 0x28000000, 0x3FF00240, 0x22CF60F6, 0x3E203CC2,
+ 0x28000000, 0x3FF00244, 0x39BEF87F, 0x3E312704,
+ 0x28000000, 0x3FF00248, 0xA63F5309, 0x3E3A3FA9,
+ 0x2C000000, 0x3FF0024C, 0xA516AE5E, 0xBE3C97AE,
+ 0x2C000000, 0x3FF00250, 0xA442792A, 0xBE335F04,
+ 0x2C000000, 0x3FF00254, 0xA686F3A2, 0xBE242CB0,
+ 0x2C000000, 0x3FF00258, 0xC3237903, 0xBDE7B535,
+ 0x2C000000, 0x3FF0025C, 0x9E7A6CF7, 0x3E21560E,
+ 0x2C000000, 0x3FF00260, 0xA8C01385, 0x3E3223BA,
+ 0x2C000000, 0x3FF00264, 0x627012DF, 0x3E3BAC70,
+ 0x30000000, 0x3FF00268, 0x7FB232EA, 0xBE3ABAD7,
+ 0x30000000, 0x3FF0026C, 0xF9A6244B, 0xBE31121C,
+ 0x30000000, 0x3FF00270, 0x1DAC9AE4, 0xBE1D6580,
+ 0x30000000, 0x3FF00274, 0xD7FB0AC3, 0x3E037AFA,
+ 0x30000000, 0x3FF00278, 0x633420EB, 0x3E289042,
+ 0x30000000, 0x3FF0027C, 0x8065842A, 0x3E3630E5,
+ 0x34000000, 0x3FF00280, 0xB49DA4FF, 0xBE3FD653,
+ 0x34000000, 0x3FF00284, 0x696ECB76, 0xBE35CD8A,
+ 0x34000000, 0x3FF00288, 0x341A9D63, 0xBE27697D,
+ 0x34000000, 0x3FF0028C, 0x2788D238, 0xBDF8BF04,
+ 0x34000000, 0x3FF00290, 0x42A03782, 0x3E2159C1,
+ 0x34000000, 0x3FF00294, 0x154D4F89, 0x3E32F5B4,
+ 0x34000000, 0x3FF00298, 0x1D7FB2C1, 0x3E3D4E8A,
+ 0x38000000, 0x3FF0029C, 0x42181508, 0xBE38489D,
+ 0x38000000, 0x3FF002A0, 0x0AF2C28C, 0xBE2B9F84,
+ 0x38000000, 0x3FF002A4, 0x451C5357, 0xBE0A3721,
+ 0x38000000, 0x3FF002A8, 0x61A8605E, 0x3E1D47F1,
+ 0x38000000, 0x3FF002AC, 0x81B02FCF, 0x3E31FADF,
+ 0x38000000, 0x3FF002B0, 0x572F674A, 0x3E3CB3C5,
+ 0x3C000000, 0x3FF002B4, 0x231795EA, 0xBE388352,
+ 0x3C000000, 0x3FF002B8, 0xD248367A, 0xBE2B54CD,
+ 0x3C000000, 0x3FF002BC, 0xB7ABD90D, 0xBE060BC7,
+ 0x3C000000, 0x3FF002C0, 0x6EE9F1EF, 0x3E206EEF,
+ 0x3C000000, 0x3FF002C4, 0x261BF09E, 0x3E33406B,
+ 0x3C000000, 0x3FF002C8, 0x59001C60, 0x3E3E5961,
+ 0x40000000, 0x3FF002CC, 0xABDDD232, 0xBE367DA5,
+ 0x40000000, 0x3FF002D0, 0xC8FA5113, 0xBE268953,
+ 0x40000000, 0x3FF002D4, 0x8B33A701, 0x3D9152CC,
+ 0x40000000, 0x3FF002D8, 0x3E058570, 0x3E26BAAC,
+ 0x40000000, 0x3FF002DC, 0x63236E71, 0x3E36C65A,
+ 0x44000000, 0x3FF002E0, 0x7C7A795C, 0xBE3DC09E,
+ 0x44000000, 0x3FF002E4, 0x7BD63D1D, 0xBE323794,
+ 0x44000000, 0x3FF002E8, 0x5BBC9105, 0xBE1A7A1E,
+ 0x44000000, 0x3FF002EC, 0xD8EE2B1B, 0x3E142A20,
+ 0x44000000, 0x3FF002F0, 0xEFAA8A8D, 0x3E30C39A,
+ 0x44000000, 0x3FF002F4, 0x995E96A2, 0x3E3C8CB0,
+ 0x48000000, 0x3FF002F8, 0xC8A79469, 0xBE379A36,
+ 0x48000000, 0x3FF002FC, 0x64CE7203, 0xBE276236,
+ 0x48000000, 0x3FF00300, 0x0819DA68, 0x3DD200D8,
+ 0x48000000, 0x3FF00304, 0xE5E018D4, 0x3E28A249,
+ 0x48000000, 0x3FF00308, 0x8A087692, 0x3E386A49,
+ 0x4C000000, 0x3FF0030C, 0xD695988B, 0xBE3B6C8E,
+ 0x4C000000, 0x3FF00310, 0x55D2BCBA, 0xBE2E66C8,
+ 0x4C000000, 0x3FF00314, 0x7790BA7A, 0xBE0751B3,
+ 0x4C000000, 0x3FF00318, 0xC2A20261, 0x3E22DDF4,
+ 0x4C000000, 0x3FF0031C, 0x49E0B0B5, 0x3E35D82E,
+ 0x50000000, 0x3FF00320, 0xB142422E, 0xBE3DAE9A,
+ 0x50000000, 0x3FF00324, 0x8C170FE6, 0xBE312560,
+ 0x50000000, 0x3FF00328, 0x0A73BF77, 0xBE12308D,
+ 0x50000000, 0x3FF0032C, 0x5E59CEFA, 0x3E203A3A,
+ 0x50000000, 0x3FF00330, 0xCD4740BF, 0x3E34D660,
+ 0x54000000, 0x3FF00334, 0x644D1883, 0xBE3E6058,
+ 0x54000000, 0x3FF00338, 0x618F57B6, 0xBE31870E,
+ 0x54000000, 0x3FF0033C, 0x99FABD0F, 0xBE127704,
+ 0x54000000, 0x3FF00340, 0xA1CB5ECF, 0x3E20B71E,
+ 0x54000000, 0x3FF00344, 0x089E93E1, 0x3E3564E3,
+ 0x58000000, 0x3FF00348, 0xFB533142, 0xBE3D81C5,
+ 0x58000000, 0x3FF0034C, 0xB6EECE6C, 0xBE30586B,
+ 0x58000000, 0x3FF00350, 0x319B883E, 0xBE08F871,
+ 0x58000000, 0x3FF00354, 0x75BF7503, 0x3E2454A5,
+ 0x58000000, 0x3FF00358, 0xF04B88C5, 0x3E3783B6,
+ 0x5C000000, 0x3FF0035C, 0x81EF30A7, 0xBE3B12E1,
+ 0x5C000000, 0x3FF00360, 0x2F9F3657, 0xBE2B32ED,
+ 0x5C000000, 0x3FF00364, 0x54DF31BC, 0xBDB0084D,
+ 0x5C000000, 0x3FF00368, 0xC303B7B9, 0x3E2B12D2,
+ 0x5C000000, 0x3FF0036C, 0x78B56F97, 0x3E3B32DE,
+ 0x60000000, 0x3FF00370, 0x03B9496C, 0xBE3713A9,
+ 0x60000000, 0x3FF00374, 0x1F92E726, 0xBE22945A,
+ 0x60000000, 0x3FF00378, 0x621736DF, 0x3E123D49,
+ 0x60000000, 0x3FF0037C, 0x3935580D, 0x3E3278D5,
+ 0x64000000, 0x3FF00380, 0x69B9F5FB, 0xBE3F8DA4,
+ 0x64000000, 0x3FF00384, 0x8C473CC8, 0xBE31841A,
+ 0x64000000, 0x3FF00388, 0x538CDE07, 0xBE0B5469,
+ 0x64000000, 0x3FF0038C, 0x7F8F9D65, 0x3E257E07,
+ 0x64000000, 0x3FF00390, 0x3665E52B, 0x3E38F898,
+ 0x68000000, 0x3FF00394, 0xC29674BD, 0xBE38BDCF,
+ 0x68000000, 0x3FF00398, 0x4E58B4D9, 0xBE24C868,
+ 0x68000000, 0x3FF0039C, 0x329466D7, 0x3E1015AC,
+ 0x68000000, 0x3FF003A0, 0xDCDECE44, 0x3E327F0D,
+ 0x6C000000, 0x3FF003A4, 0xB27E5528, 0xBE3EF74B,
+ 0x6C000000, 0x3FF003A8, 0x9D7167F2, 0xBE305DA1,
+ 0x6C000000, 0x3FF003AC, 0xFF980820, 0xBDFB3F3D,
+ 0x6C000000, 0x3FF003B0, 0x13D49789, 0x3E2A0B7B,
+ 0x6C000000, 0x3FF003B4, 0xA43AE87C, 0x3E3BCF72,
+ 0x70000000, 0x3FF003B8, 0x8D06BDC0, 0xBE3556D4,
+ 0x70000000, 0x3FF003BC, 0x1766E54D, 0xBE19B460,
+ 0x70000000, 0x3FF003C0, 0x7B85C8BA, 0x3E211950,
+ 0x70000000, 0x3FF003C4, 0x41D00AED, 0x3E37966C,
+ 0x74000000, 0x3FF003C8, 0xF5B15507, 0xBE394FCB,
+ 0x74000000, 0x3FF003CC, 0xC98093C4, 0xBE244C00,
+ 0x74000000, 0x3FF003D0, 0xE2907BDF, 0x3E144F3B,
+ 0x74000000, 0x3FF003D4, 0x267CD924, 0x3E345DA2,
+ 0x78000000, 0x3FF003D8, 0xD73526C0, 0xBE3C4886,
+ 0x78000000, 0x3FF003DC, 0xF8E1D62E, 0xBE29BD57,
+ 0x78000000, 0x3FF003E0, 0xD65415E1, 0x3E04D995,
+ 0x78000000, 0x3FF003E4, 0x527E1A58, 0x3E322515,
+ 0x7C000000, 0x3FF003E8, 0x31552BA5, 0xBE3E4104,
+ 0x7C000000, 0x3FF003EC, 0x995CAB3B, 0xBE2D2E33,
+ 0x7C000000, 0x3FF003F0, 0x473970DC, 0x3DF22D48,
+ 0x7C000000, 0x3FF003F4, 0xC61195FC, 0x3E30ECC6,
+ 0x80000000, 0x3FF003F8, 0x03D35C34, 0xBE3F3943,
+ 0x80000000, 0x3FF003FC, 0xAA7483C7, 0xBE2E9E91,
+ 0x80000000, 0x3FF00400, 0xBBBC71CE, 0x3DE556AA,
+ 0x80000000, 0x3FF00404, 0x817613C1, 0x3E30B4B7,
+ 0x84000000, 0x3FF00408, 0x4E70B0AC, 0xBE3F3142,
+ 0x84000000, 0x3FF0040C, 0x2BAAD02F, 0xBE2E0E70,
+ 0x84000000, 0x3FF00410, 0xF48F01F2, 0x3DF32D62,
+ 0x84000000, 0x3FF00414, 0x84EB5B98, 0x3E317CE8,
+ 0x88000000, 0x3FF00418, 0x10ED210B, 0xBE3E2901,
+ 0x88000000, 0x3FF0041C, 0x1C7F0051, 0xBE2B7DCD,
+ 0x88000000, 0x3FF00420, 0x87AA2706, 0x3E05D9C0,
+ 0x88000000, 0x3FF00424, 0xD0B235B3, 0x3E33455A,
+ 0x8C000000, 0x3FF00428, 0x4B07A510, 0xBE3C207E,
+ 0x8C000000, 0x3FF0042C, 0x7C6E838B, 0xBE26ECA6,
+ 0x8C000000, 0x3FF00430, 0xEC91A8D5, 0x3E150F6F,
+ 0x8C000000, 0x3FF00434, 0x650C6A83, 0x3E360E0F,
+ 0x90000000, 0x3FF00438, 0xFC7E3439, 0xBE3917B8,
+ 0x90000000, 0x3FF0043C, 0x4AF4C8B6, 0xBE205AFA,
+ 0x90000000, 0x3FF00440, 0xDC31D181, 0x3E219985,
+ 0x90000000, 0x3FF00444, 0x423CC2BE, 0x3E39D707,
+ 0x94000000, 0x3FF00448, 0x250DC5BF, 0xBE350EB0,
+ 0x94000000, 0x3FF0044C, 0x1E2CF893, 0xBE0F231A,
+ 0x94000000, 0x3FF00450, 0xD42C92D4, 0x3E2AABDB,
+ 0x94000000, 0x3FF00454, 0x6887075B, 0x3E3EA043,
+ 0x98000000, 0x3FF00458, 0xC472509B, 0xBE300562,
+ 0x98000000, 0x3FF0045C, 0x72B572E0, 0x3DF64FB6,
+ 0x98000000, 0x3FF00460, 0xEF61155C, 0x3E32DF5D,
+ 0x9C000000, 0x3FF00464, 0x27CFFE6A, 0xBE3B963B,
+ 0x9C000000, 0x3FF00468, 0xB4CD96FE, 0xBE23F79F,
+ 0x9C000000, 0x3FF0046C, 0x6E771F13, 0x3E1EBA7F,
+ 0x9C000000, 0x3FF00470, 0xFE3ED608, 0x3E396913,
+ 0xA0000000, 0x3FF00474, 0x6E82850F, 0xBE34CC73,
+ 0xA0000000, 0x3FF00478, 0x352966B7, 0xBE078FB3,
+ 0xA0000000, 0x3FF0047C, 0x33AFF8AE, 0x3E2DF116,
+ 0xA4000000, 0x3FF00480, 0xE909EADD, 0xBE3F0CEE,
+ 0xA4000000, 0x3FF00484, 0xD6938597, 0xBE2A04C8,
+ 0xA4000000, 0x3FF00488, 0x5C6654D8, 0x3E1460AA,
+ 0xA4000000, 0x3FF0048C, 0x22213ECF, 0x3E3742BE,
+ 0xA8000000, 0x3FF00490, 0xC631A356, 0xBE3682A9,
+ 0xA8000000, 0x3FF00494, 0x7777B644, 0xBE10E034,
+ 0xA8000000, 0x3FF00498, 0x3E3B0991, 0x3E2C4528,
+ 0xAC000000, 0x3FF0049C, 0x0B3E269F, 0xBE3F72C6,
+ 0xAC000000, 0x3FF004A0, 0x31DF923B, 0xBE29F037,
+ 0xAC000000, 0x3FF004A4, 0xE82713DE, 0x3E164A4D,
+ 0xAC000000, 0x3FF004A8, 0x31AFAC4B, 0x3E382D47,
+ 0xB0000000, 0x3FF004AC, 0x6DFCE978, 0xBE352800,
+ 0xB0000000, 0x3FF004B0, 0x07D68D27, 0xBE036A1B,
+ 0xB0000000, 0x3FF004B4, 0x5CB71F6F, 0x3E305D7E,
+ 0xB4000000, 0x3FF004B8, 0x30E5E990, 0xBE3CC7BB,
+ 0xB4000000, 0x3FF004BC, 0x0BA17DEA, 0xBE23B9E0,
+ 0xB4000000, 0x3FF004C0, 0xC3EF9BD8, 0x3E223BBF,
+ 0xB4000000, 0x3FF004C4, 0x8A74ECC0, 0x3E3C28B4,
+ 0xB8000000, 0x3FF004C8, 0x085831CA, 0xBE30BC72,
+ 0xB8000000, 0x3FF004CC, 0x6C8D1FC8, 0x3E037361,
+ 0xB8000000, 0x3FF004D0, 0x3033A0B8, 0x3E35A94F,
+ 0xBC000000, 0x3FF004D4, 0xFC7107DE, 0xBE370BC8,
+ 0xBC000000, 0x3FF004D8, 0xA2D908DA, 0xBE0D86E2,
+ 0xBC000000, 0x3FF004DC, 0x58ED155E, 0x3E2F742A,
+ 0xC0000000, 0x3FF004E0, 0x75FACDD0, 0xBE3CCAF4,
+ 0xC0000000, 0x3FF004E4, 0x6F5BE5D3, 0xBE227FF2,
+ 0xC0000000, 0x3FF004E8, 0xD6BCA827, 0x3E24B60D,
+ 0xC0000000, 0x3FF004EC, 0xF72B40D6, 0x3E3E060B,
+ 0xC4000000, 0x3FF004F0, 0x208BE3E3, 0xBE2C7DD4,
+ 0xC4000000, 0x3FF004F4, 0x642FDDB8, 0x3E163093,
+ 0xC4000000, 0x3FF004F8, 0xB72239A5, 0x3E396738,
+ 0xC8000000, 0x3FF004FC, 0x7201ED9B, 0xBE32ADAE,
+ 0xC8000000, 0x3FF00500, 0x1A0C05F3, 0x3DF4D6F6,
+ 0xC8000000, 0x3FF00504, 0x360B8346, 0x3E355892,
+ 0xCC000000, 0x3FF00508, 0xF0C06435, 0xBE368C45,
+ 0xCC000000, 0x3FF0050C, 0x760DA2F6, 0xBE0308C8,
+ 0xCC000000, 0x3FF00510, 0xE008D57B, 0x3E31DA18,
+ 0xD0000000, 0x3FF00514, 0x205F82F4, 0xBE39DAB0,
+ 0xD0000000, 0x3FF00518, 0x2FE5E3E3, 0xBE15FDD0,
+ 0xD0000000, 0x3FF0051C, 0x42787241, 0x3E2DD79A,
+ 0xD4000000, 0x3FF00520, 0x94BD25F4, 0xBE3C98EC,
+ 0xD4000000, 0x3FF00524, 0x53C89D03, 0xBE201B42,
+ 0xD4000000, 0x3FF00528, 0xCB901057, 0x3E291B5E,
+ 0xD8000000, 0x3FF0052C, 0xE1B6D837, 0xBE3EC6FA,
+ 0xD8000000, 0x3FF00530, 0xF8BF49E7, 0xBE24173F,
+ 0xD8000000, 0x3FF00534, 0x339DDB57, 0x3E257F80,
+ 0xD8000000, 0x3FF00538, 0x64D62C5C, 0x3E3F9B25,
+ 0xDC000000, 0x3FF0053C, 0x2E913659, 0xBE26F2E0,
+ 0xDC000000, 0x3FF00540, 0x52E7CB93, 0x3E2303FF,
+ 0xDC000000, 0x3FF00544, 0xAB0CFEF5, 0x3E3E8D74,
+ 0xE0000000, 0x3FF00548, 0x1CF7FDE6, 0xBE28AE22,
+ 0xE0000000, 0x3FF0054C, 0x01B47B93, 0x3E21A8DD,
+ 0xE0000000, 0x3FF00550, 0x5D1107E2, 0x3E3E0FF3,
+ 0xE4000000, 0x3FF00554, 0xEBAC99E1, 0xBE294904,
+ 0xE4000000, 0x3FF00558, 0x184B2814, 0x3E216E1A,
+ 0xE4000000, 0x3FF0055C, 0xE706008B, 0x3E3E22A1,
+ 0xE8000000, 0x3FF00560, 0xC267616A, 0xBE28C387,
+ 0xE8000000, 0x3FF00564, 0x6EF3B008, 0x3E2253B7,
+ 0xE8000000, 0x3FF00568, 0xB50FF371, 0x3E3EC580,
+ 0xEC000000, 0x3FF0056C, 0xC8E0096B, 0xBE271DA9,
+ 0xEC000000, 0x3FF00570, 0xDDF69498, 0x3E2459B5,
+ 0xEC000000, 0x3FF00574, 0x33533C31, 0x3E3FF890,
+ 0xF0000000, 0x3FF00578, 0x26CDA497, 0xBE24576A,
+ 0xF0000000, 0x3FF0057C, 0x3D9CF923, 0x3E278016,
+ 0xF4000000, 0x3FF00580, 0x320B787B, 0xBE3E442F,
+ 0xF4000000, 0x3FF00584, 0x03E6A36B, 0xBE2070C8,
+ 0xF4000000, 0x3FF00588, 0x6630A33F, 0x3E2BC6D9,
+ 0xF8000000, 0x3FF0058C, 0x0EE72CBF, 0xBE3BF0BD,
+ 0xF8000000, 0x3FF00590, 0x0FC1A853, 0xBE16D385,
+ 0xF8000000, 0x3FF00594, 0x17FDFD5D, 0x3E309700,
+ 0xFC000000, 0x3FF00598, 0xF71A91AC, 0xBE390D18,
+ 0xFC000000, 0x3FF0059C, 0x69C58B86, 0xBE050963,
+ 0xFC000000, 0x3FF005A0, 0xB9A504CD, 0x3E33DAC5,
+ 0x00000000, 0x3FF005A5, 0x7E800734, 0xBE359942,
+ 0x00000000, 0x3FF005A9, 0xE59934CD, 0x3DF02BAE,
+ 0x00000000, 0x3FF005AD, 0x04333E0E, 0x3E37AEBE,
+ 0x04000000, 0x3FF005B1, 0x38F19C2F, 0xBE319539,
+ 0x04000000, 0x3FF005B5, 0xEBB1C157, 0x3E14DB54,
+ 0x04000000, 0x3FF005B9, 0x63CED05D, 0x3E3C12E9,
+ 0x08000000, 0x3FF005BD, 0x74921CAF, 0xBE2A01F9,
+ 0x08000000, 0x3FF005C1, 0xC94C85F2, 0x3E23F645,
+ 0x0C000000, 0x3FF005C5, 0xBB61CBEE, 0xBE3EF8B7,
+ 0x0C000000, 0x3FF005C9, 0x597F2931, 0xBE1F7232,
+ 0x0C000000, 0x3FF005CD, 0xAF5B7345, 0x3E2E9F48,
+ 0x10000000, 0x3FF005D1, 0xED37CD5F, 0xBE397424,
+ 0x10000000, 0x3FF005D5, 0x08775C6B, 0xBE013F43,
+ 0x10000000, 0x3FF005D9, 0x0029D3DB, 0x3E35345A,
+ 0x14000000, 0x3FF005DD, 0xC58C1962, 0xBE335F5D,
+ 0x14000000, 0x3FF005E1, 0x47430E04, 0x3E1073C1,
+ 0x14000000, 0x3FF005E5, 0x4A41E248, 0x3E3BA944,
+ 0x18000000, 0x3FF005E9, 0xB06E888E, 0xBE2974C3,
+ 0x18000000, 0x3FF005ED, 0xDCCD9333, 0x3E25E3FB,
+ 0x1C000000, 0x3FF005F1, 0x5DE27951, 0xBE3D519C,
+ 0x1C000000, 0x3FF005F5, 0xE4464502, 0xBE1614C2,
+ 0x1C000000, 0x3FF005F9, 0xE0DAFE93, 0x3E325740,
+ 0x20000000, 0x3FF005FD, 0x8C1B4C10, 0xBE35BC47,
+ 0x20000000, 0x3FF00601, 0x20686CE9, 0x3E0201B0,
+ 0x20000000, 0x3FF00605, 0x95558B63, 0x3E3A4CB9,
+ 0x24000000, 0x3FF00609, 0xA880A3EB, 0xBE2B2D79,
+ 0x24000000, 0x3FF0060D, 0x9699EEB7, 0x3E252BA5,
+ 0x28000000, 0x3FF00611, 0x880115E1, 0xBE3D2D97,
+ 0x28000000, 0x3FF00615, 0x28A3D788, 0xBE1383EF,
+ 0x28000000, 0x3FF00619, 0x08D6DC23, 0x3E337BA6,
+ 0x2C000000, 0x3FF0061D, 0x0B001A08, 0xBE3417B2,
+ 0x2C000000, 0x3FF00621, 0xF94EB99A, 0x3E1193EF,
+ 0x2C000000, 0x3FF00625, 0x28D3BD3B, 0x3E3CF1B0,
+ 0x30000000, 0x3FF00629, 0x0EFCC982, 0xBE24E32B,
+ 0x30000000, 0x3FF0062D, 0xE2BDA47F, 0x3E2C7655,
+ 0x34000000, 0x3FF00631, 0x689312F8, 0xBE39080E,
+ 0x34000000, 0x3FF00635, 0xA9444DB4, 0xBDCDA0C8,
+ 0x34000000, 0x3FF00639, 0x7B21FE23, 0x3E38A191,
+ 0x38000000, 0x3FF0063D, 0x7E67E1E1, 0xBE2CE32A,
+ 0x38000000, 0x3FF00641, 0x875A71F0, 0x3E251694,
+ 0x3C000000, 0x3FF00645, 0xF838F455, 0xBE3C67CF,
+ 0x3C000000, 0x3FF00649, 0x77274052, 0xBE0A571F,
+ 0x3C000000, 0x3FF0064D, 0x63AAEFA8, 0x3E35E20E,
+ 0x40000000, 0x3FF00651, 0xFC87DA70, 0xBE30E0F8,
+ 0x40000000, 0x3FF00655, 0xE9089AFD, 0x3E20D80B,
+ 0x44000000, 0x3FF00659, 0xC52F03BD, 0xBE3E36F4,
+ 0x44000000, 0x3FF0065D, 0x9680E14E, 0xBE1327A4,
+ 0x44000000, 0x3FF00661, 0xD732468D, 0x3E34B328,
+ 0x48000000, 0x3FF00665, 0xCAB5EF4A, 0xBE31BFBE,
+ 0x48000000, 0x3FF00669, 0xE2A2FBE1, 0x3E1F757F,
+ 0x4C000000, 0x3FF0066D, 0xDAB014DA, 0xBE3E757A,
+ 0x4C000000, 0x3FF00671, 0x02FB3FBB, 0xBE12E13D,
+ 0x4C000000, 0x3FF00675, 0xCA7E298D, 0x3E3514E2,
+ 0x50000000, 0x3FF00679, 0xB4F78B94, 0xBE310DE4,
+ 0x50000000, 0x3FF0067D, 0x89C35D05, 0x3E21BEB4,
+ 0x54000000, 0x3FF00681, 0x43F4895C, 0xBE3D2360,
+ 0x54000000, 0x3FF00685, 0x5BC49ADF, 0xBE08B0A2,
+ 0x54000000, 0x3FF00689, 0x32573159, 0x3E37073E,
+ 0x58000000, 0x3FF0068D, 0x8D0732D2, 0xBE2D96D1,
+ 0x58000000, 0x3FF00691, 0x9BF15E67, 0x3E26E3ED,
+ 0x5C000000, 0x3FF00695, 0x0C3250FB, 0xBE3A40A3,
+ 0x5C000000, 0x3FF00699, 0xFD0AE214, 0x3DBCC9AE,
+ 0x5C000000, 0x3FF0069D, 0x038868A1, 0x3E3A8A3D,
+ 0x60000000, 0x3FF006A1, 0x151D21CE, 0xBE25F092,
+ 0x60000000, 0x3FF006A5, 0x11738C43, 0x3E2F2A6F,
+ 0x64000000, 0x3FF006A9, 0x3E9CE96D, 0xBE35CD41,
+ 0x64000000, 0x3FF006AD, 0x8DBC2918, 0x3E138132,
+ 0x64000000, 0x3FF006B1, 0x32DF4C13, 0x3E3F9DE1,
+ 0x68000000, 0x3FF006B5, 0x3129E0B2, 0xBE16520E,
+ 0x68000000, 0x3FF006B9, 0x69F36A61, 0x3E35491E,
+ 0x6C000000, 0x3FF006BD, 0xCCCABCD4, 0xBE2F9271,
+ 0x6C000000, 0x3FF006C1, 0x0D59B899, 0x3E2668ED,
+ 0x70000000, 0x3FF006C5, 0x4AD435A0, 0xBE39BDD3,
+ 0x70000000, 0x3FF006C9, 0x9191CABB, 0x3DF5FE9A,
+ 0x70000000, 0x3FF006CD, 0x6676850B, 0x3E3C8DAD,
+ 0x74000000, 0x3FF006D1, 0x1D74934A, 0xBE206910,
+ 0x74000000, 0x3FF006D5, 0x4D886478, 0x3E331949,
+ 0x78000000, 0x3FF006D9, 0x80BFBBC2, 0xBE3188DE,
+ 0x78000000, 0x3FF006DD, 0x14DE1719, 0x3E23CA01,
+ 0x7C000000, 0x3FF006E1, 0x8CE98EC0, 0xBE3A9D19,
+ 0x7C000000, 0x3FF006E5, 0xA705A6E7, 0x3DEE1A67,
+ 0x7C000000, 0x3FF006E9, 0xECD5F851, 0x3E3C8EC6,
+ 0x80000000, 0x3FF006ED, 0xE839CE4D, 0xBE1F0CF9,
+ 0x80000000, 0x3FF006F1, 0x0C8CA46A, 0x3E33FAC3,
+ 0x84000000, 0x3FF006F5, 0x7B5703D8, 0xBE303734,
+ 0x84000000, 0x3FF006F9, 0xE490A112, 0x3E274DB5,
+ 0x88000000, 0x3FF006FD, 0xA693A093, 0xBE386B0E,
+ 0x88000000, 0x3FF00701, 0xF0B73DAA, 0x3E0C9875,
+ 0x88000000, 0x3FF00705, 0x2449A944, 0x3E3FA133,
+ 0x8C000000, 0x3FF00709, 0xBFE66C14, 0xBE110285,
+ 0x8C000000, 0x3FF0070D, 0x054EDCBD, 0x3E37ED91,
+ 0x90000000, 0x3FF00711, 0xEFB65924, 0xBE27A86A,
+ 0x90000000, 0x3FF00715, 0x1C8A0CF1, 0x3E307A0B,
+ 0x94000000, 0x3FF00719, 0x397FB1D6, 0xBE3327AD,
+ 0x94000000, 0x3FF0071D, 0x1412B9FB, 0x3E228D43,
+ 0x98000000, 0x3FF00721, 0x94D8FFB0, 0xBE3A3B08,
+ 0x98000000, 0x3FF00725, 0x6ED80040, 0x3E029AA3,
+ 0x98000000, 0x3FF00729, 0x9627250A, 0x3E3EF1B8,
+ 0x9C000000, 0x3FF0072D, 0x5FCB1B09, 0xBE117F70,
+ 0x9C000000, 0x3FF00731, 0x678F0789, 0x3E385E96,
+ 0xA0000000, 0x3FF00735, 0xCEA3485B, 0xBE25A5DF,
+ 0xA0000000, 0x3FF00739, 0xFF6D0303, 0x3E320B90,
+ 0xA4000000, 0x3FF0073D, 0xE03334FF, 0xBE3105E6,
+ 0xA4000000, 0x3FF00741, 0xFB9F056D, 0x3E27F150,
+ 0xA8000000, 0x3FF00745, 0xE28905F4, 0xBE36F8C0,
+ 0xA8000000, 0x3FF00749, 0x0B1407AA, 0x3E189774,
+ 0xAC000000, 0x3FF0074D, 0xCE4493C4, 0xBE3CAB7D,
+ 0xAC000000, 0x3FF00751, 0xCB817D78, 0x3DE265D5,
+ 0xAC000000, 0x3FF00755, 0x7CA8B4E3, 0x3E3DE1E2,
+ 0xB0000000, 0x3FF00759, 0x7D730FC6, 0xBE12FD89,
+ 0xB0000000, 0x3FF0075D, 0x1E4D7759, 0x3E38AF60,
+ 0xB4000000, 0x3FF00761, 0x0CAD84A2, 0xBE23A3AC,
+ 0xB4000000, 0x3FF00765, 0x36B866FD, 0x3E33BCFB,
+ 0xB8000000, 0x3FF00769, 0x4D0667A1, 0xBE2D4858,
+ 0xB8000000, 0x3FF0076D, 0xCBF08E6A, 0x3E2E1567,
+ 0xBC000000, 0x3FF00771, 0x9FD34D05, 0xBE333664,
+ 0xBC000000, 0x3FF00775, 0x9837D6E0, 0x3E253114,
+ 0xC0000000, 0x3FF00779, 0x5238327D, 0xBE37887F,
+ 0xC0000000, 0x3FF0077D, 0x24C8DC90, 0x3E1999FA,
+ 0xC4000000, 0x3FF00781, 0x1DA2F8BE, 0xBE3B9A7C,
+ 0xC4000000, 0x3FF00785, 0xEA50EE6A, 0x3E03A485,
+ 0xC8000000, 0x3FF00789, 0xE204A449, 0xBE3F6C5A,
+ 0xC8000000, 0x3FF0078D, 0x78D5D0F3, 0xBDF3D3EF,
+ 0xC8000000, 0x3FF00791, 0x80B1D66C, 0x3E3D01E4,
+ 0xCC000000, 0x3FF00795, 0xD5149796, 0xBE12BBC1,
+ 0xCC000000, 0x3FF00799, 0x2A8F92F0, 0x3E39B042,
+ 0xD0000000, 0x3FF0079D, 0x6F386487, 0xBE1F820E,
+ 0xD0000000, 0x3FF007A1, 0x3BA3BCDA, 0x3E369EBE,
+ 0xD4000000, 0x3FF007A5, 0x96320652, 0xBE25A3F0,
+ 0xD4000000, 0x3FF007A9, 0xD3FD8FCA, 0x3E33CD58,
+ 0xD8000000, 0x3FF007AD, 0xC62D40B1, 0xBE2B069C,
+ 0xD8000000, 0x3FF007B1, 0x13AC5766, 0x3E313C12,
+ 0xDC000000, 0x3FF007B5, 0x876F3A0B, 0xBE2FE90B,
+ 0xDC000000, 0x3FF007B9, 0x357EDEB8, 0x3E2DD5D4,
+ 0xE0000000, 0x3FF007BD, 0x4CEC957E, 0xBE32259E,
+ 0xE0000000, 0x3FF007C1, 0x128C86C6, 0x3E29B3C2,
+ 0xE4000000, 0x3FF007C5, 0xDEA61608, 0xBE341697,
+ 0xE4000000, 0x3FF007C9, 0xFEA09E70, 0x3E2611ED,
+ 0xE8000000, 0x3FF007CD, 0x58D49AE3, 0xBE35C772,
+ 0xE8000000, 0x3FF007D1, 0x39DA3D42, 0x3E22F058,
+ 0xEC000000, 0x3FF007D5, 0x9B689043, 0xBE37382D,
+ 0xEC000000, 0x3FF007D9, 0x04589AD6, 0x3E204F01,
+ 0xF0000000, 0x3FF007DD, 0x86525259, 0xBE3868C9,
+ 0xF0000000, 0x3FF007E1, 0x3C761DAC, 0x3E1C5BD1,
+ 0xF4000000, 0x3FF007E5, 0xF9822D4C, 0xBE395945,
+ 0xF4000000, 0x3FF007E9, 0x8F4221F9, 0x3E191A1E,
+ 0xF8000000, 0x3FF007ED, 0xD4E85D3A, 0xBE3A09A2,
+ 0xF8000000, 0x3FF007F1, 0x81547225, 0x3E16D8EA,
+ 0xFC000000, 0x3FF007F5, 0xF8750E3B, 0xBE3A79DF,
+ 0xFC000000, 0x3FF007F9, 0x92EC7DE3, 0x3E159835,
+ 0x00000000, 0x3FF007FE, 0x44185C5D, 0xBE3AA9FD } };
+
+#endif
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/ulog.h b/libc/sysdeps/ieee754/dbl-64/ulog.h
new file mode 100644
index 000000000..0ba6b7bb5
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/ulog.h
@@ -0,0 +1,200 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/******************************************************************/
+/* */
+/* MODULE_NAME:ulog.h */
+/* */
+/* common data and variables prototype and definition */
+/******************************************************************/
+
+#ifndef ULOG_H
+#define ULOG_H
+
+#ifdef BIG_ENDI
+ static const number
+ /* polynomial I */
+/**/ a2 = {{0xbfe00000, 0x0001aa8f} }, /* -0.500... */
+/**/ a3 = {{0x3fd55555, 0x55588d2e} }, /* 0.333... */
+ /* polynomial II */
+/**/ b0 = {{0x3fd55555, 0x55555555} }, /* 0.333... */
+/**/ b1 = {{0xbfcfffff, 0xffffffbb} }, /* -0.249... */
+/**/ b2 = {{0x3fc99999, 0x9999992f} }, /* 0.199... */
+/**/ b3 = {{0xbfc55555, 0x556503fd} }, /* -0.166... */
+/**/ b4 = {{0x3fc24924, 0x925b3d62} }, /* 0.142... */
+/**/ b5 = {{0xbfbffffe, 0x160472fc} }, /* -0.124... */
+/**/ b6 = {{0x3fbc71c5, 0x25db58ac} }, /* 0.111... */
+/**/ b7 = {{0xbfb9a4ac, 0x11a2a61c} }, /* -0.100... */
+/**/ b8 = {{0x3fb75077, 0x0df2b591} }, /* 0.091... */
+ /* polynomial III */
+#if 0
+/**/ c1 = {{0x3ff00000, 0x00000000} }, /* 1 */
+#endif
+/**/ c2 = {{0xbfe00000, 0x00000000} }, /* -1/2 */
+/**/ c3 = {{0x3fd55555, 0x55555555} }, /* 1/3 */
+/**/ c4 = {{0xbfd00000, 0x00000000} }, /* -1/4 */
+/**/ c5 = {{0x3fc99999, 0x9999999a} }, /* 1/5 */
+ /* polynomial IV */
+/**/ d2 = {{0xbfe00000, 0x00000000} }, /* -1/2 */
+/**/ dd2 = {{0x00000000, 0x00000000} }, /* -1/2-d2 */
+/**/ d3 = {{0x3fd55555, 0x55555555} }, /* 1/3 */
+/**/ dd3 = {{0x3c755555, 0x55555555} }, /* 1/3-d3 */
+/**/ d4 = {{0xbfd00000, 0x00000000} }, /* -1/4 */
+/**/ dd4 = {{0x00000000, 0x00000000} }, /* -1/4-d4 */
+/**/ d5 = {{0x3fc99999, 0x9999999a} }, /* 1/5 */
+/**/ dd5 = {{0xbc699999, 0x9999999a} }, /* 1/5-d5 */
+/**/ d6 = {{0xbfc55555, 0x55555555} }, /* -1/6 */
+/**/ dd6 = {{0xbc655555, 0x55555555} }, /* -1/6-d6 */
+/**/ d7 = {{0x3fc24924, 0x92492492} }, /* 1/7 */
+/**/ dd7 = {{0x3c624924, 0x92492492} }, /* 1/7-d7 */
+/**/ d8 = {{0xbfc00000, 0x00000000} }, /* -1/8 */
+/**/ dd8 = {{0x00000000, 0x00000000} }, /* -1/8-d8 */
+/**/ d9 = {{0x3fbc71c7, 0x1c71c71c} }, /* 1/9 */
+/**/ dd9 = {{0x3c5c71c7, 0x1c71c71c} }, /* 1/9-d9 */
+/**/ d10 = {{0xbfb99999, 0x9999999a} }, /* -1/10 */
+/**/ dd10 = {{0x3c599999, 0x9999999a} }, /* -1/10-d10 */
+/**/ d11 = {{0x3fb745d1, 0x745d1746} }, /* 1/11 */
+/**/ d12 = {{0xbfb55555, 0x55555555} }, /* -1/12 */
+/**/ d13 = {{0x3fb3b13b, 0x13b13b14} }, /* 1/13 */
+/**/ d14 = {{0xbfb24924, 0x92492492} }, /* -1/14 */
+/**/ d15 = {{0x3fb11111, 0x11111111} }, /* 1/15 */
+/**/ d16 = {{0xbfb00000, 0x00000000} }, /* -1/16 */
+/**/ d17 = {{0x3fae1e1e, 0x1e1e1e1e} }, /* 1/17 */
+/**/ d18 = {{0xbfac71c7, 0x1c71c71c} }, /* -1/18 */
+/**/ d19 = {{0x3faaf286, 0xbca1af28} }, /* 1/19 */
+/**/ d20 = {{0xbfa99999, 0x9999999a} }, /* -1/20 */
+ /* constants */
+/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */
+/**/ one = {{0x3ff00000, 0x00000000} }, /* 1 */
+/**/ half = {{0x3fe00000, 0x00000000} }, /* 1/2 */
+/**/ mhalf = {{0xbfe00000, 0x00000000} }, /* -1/2 */
+/**/ sqrt_2 = {{0x3ff6a09e, 0x667f3bcc} }, /* sqrt(2) */
+/**/ h1 = {{0x3fd2e000, 0x00000000} }, /* 151/2**9 */
+/**/ h2 = {{0x3f669000, 0x00000000} }, /* 361/2**17 */
+/**/ delu = {{0x3f700000, 0x00000000} }, /* 1/2**8 */
+/**/ delv = {{0x3ef00000, 0x00000000} }, /* 1/2**16 */
+/**/ ln2a = {{0x3fe62e42, 0xfefa3800} }, /* ln(2) 43 bits */
+/**/ ln2b = {{0x3d2ef357, 0x93c76730} }, /* ln(2)-ln2a */
+/**/ e1 = {{0x3bbcc868, 0x00000000} }, /* 6.095e-21 */
+/**/ e2 = {{0x3c1138ce, 0x00000000} }, /* 2.334e-19 */
+/**/ e3 = {{0x3aa1565d, 0x00000000} }, /* 2.801e-26 */
+/**/ e4 = {{0x39809d88, 0x00000000} }, /* 1.024e-31 */
+/**/ e[M] ={{{0x37da223a, 0x00000000} }, /* 1.2e-39 */
+/**/ {{0x35c851c4, 0x00000000} }, /* 1.3e-49 */
+/**/ {{0x2ab85e51, 0x00000000} }, /* 6.8e-103 */
+/**/ {{0x17383827, 0x00000000} }},/* 8.1e-197 */
+/**/ two54 = {{0x43500000, 0x00000000} }, /* 2**54 */
+/**/ u03 = {{0x3f9eb851, 0xeb851eb8} }; /* 0.03 */
+
+#else
+#ifdef LITTLE_ENDI
+ static const number
+ /* polynomial I */
+/**/ a2 = {{0x0001aa8f, 0xbfe00000} }, /* -0.500... */
+/**/ a3 = {{0x55588d2e, 0x3fd55555} }, /* 0.333... */
+ /* polynomial II */
+/**/ b0 = {{0x55555555, 0x3fd55555} }, /* 0.333... */
+/**/ b1 = {{0xffffffbb, 0xbfcfffff} }, /* -0.249... */
+/**/ b2 = {{0x9999992f, 0x3fc99999} }, /* 0.199... */
+/**/ b3 = {{0x556503fd, 0xbfc55555} }, /* -0.166... */
+/**/ b4 = {{0x925b3d62, 0x3fc24924} }, /* 0.142... */
+/**/ b5 = {{0x160472fc, 0xbfbffffe} }, /* -0.124... */
+/**/ b6 = {{0x25db58ac, 0x3fbc71c5} }, /* 0.111... */
+/**/ b7 = {{0x11a2a61c, 0xbfb9a4ac} }, /* -0.100... */
+/**/ b8 = {{0x0df2b591, 0x3fb75077} }, /* 0.091... */
+ /* polynomial III */
+#if 0
+/**/ c1 = {{0x00000000, 0x3ff00000} }, /* 1 */
+#endif
+/**/ c2 = {{0x00000000, 0xbfe00000} }, /* -1/2 */
+/**/ c3 = {{0x55555555, 0x3fd55555} }, /* 1/3 */
+/**/ c4 = {{0x00000000, 0xbfd00000} }, /* -1/4 */
+/**/ c5 = {{0x9999999a, 0x3fc99999} }, /* 1/5 */
+ /* polynomial IV */
+/**/ d2 = {{0x00000000, 0xbfe00000} }, /* -1/2 */
+/**/ dd2 = {{0x00000000, 0x00000000} }, /* -1/2-d2 */
+/**/ d3 = {{0x55555555, 0x3fd55555} }, /* 1/3 */
+/**/ dd3 = {{0x55555555, 0x3c755555} }, /* 1/3-d3 */
+/**/ d4 = {{0x00000000, 0xbfd00000} }, /* -1/4 */
+/**/ dd4 = {{0x00000000, 0x00000000} }, /* -1/4-d4 */
+/**/ d5 = {{0x9999999a, 0x3fc99999} }, /* 1/5 */
+/**/ dd5 = {{0x9999999a, 0xbc699999} }, /* 1/5-d5 */
+/**/ d6 = {{0x55555555, 0xbfc55555} }, /* -1/6 */
+/**/ dd6 = {{0x55555555, 0xbc655555} }, /* -1/6-d6 */
+/**/ d7 = {{0x92492492, 0x3fc24924} }, /* 1/7 */
+/**/ dd7 = {{0x92492492, 0x3c624924} }, /* 1/7-d7 */
+/**/ d8 = {{0x00000000, 0xbfc00000} }, /* -1/8 */
+/**/ dd8 = {{0x00000000, 0x00000000} }, /* -1/8-d8 */
+/**/ d9 = {{0x1c71c71c, 0x3fbc71c7} }, /* 1/9 */
+/**/ dd9 = {{0x1c71c71c, 0x3c5c71c7} }, /* 1/9-d9 */
+/**/ d10 = {{0x9999999a, 0xbfb99999} }, /* -1/10 */
+/**/ dd10 = {{0x9999999a, 0x3c599999} }, /* -1/10-d10 */
+/**/ d11 = {{0x745d1746, 0x3fb745d1} }, /* 1/11 */
+/**/ d12 = {{0x55555555, 0xbfb55555} }, /* -1/12 */
+/**/ d13 = {{0x13b13b14, 0x3fb3b13b} }, /* 1/13 */
+/**/ d14 = {{0x92492492, 0xbfb24924} }, /* -1/14 */
+/**/ d15 = {{0x11111111, 0x3fb11111} }, /* 1/15 */
+/**/ d16 = {{0x00000000, 0xbfb00000} }, /* -1/16 */
+/**/ d17 = {{0x1e1e1e1e, 0x3fae1e1e} }, /* 1/17 */
+/**/ d18 = {{0x1c71c71c, 0xbfac71c7} }, /* -1/18 */
+/**/ d19 = {{0xbca1af28, 0x3faaf286} }, /* 1/19 */
+/**/ d20 = {{0x9999999a, 0xbfa99999} }, /* -1/20 */
+ /* constants */
+/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */
+/**/ one = {{0x00000000, 0x3ff00000} }, /* 1 */
+/**/ half = {{0x00000000, 0x3fe00000} }, /* 1/2 */
+/**/ mhalf = {{0x00000000, 0xbfe00000} }, /* -1/2 */
+/**/ sqrt_2 = {{0x667f3bcc, 0x3ff6a09e} }, /* sqrt(2) */
+/**/ h1 = {{0x00000000, 0x3fd2e000} }, /* 151/2**9 */
+/**/ h2 = {{0x00000000, 0x3f669000} }, /* 361/2**17 */
+/**/ delu = {{0x00000000, 0x3f700000} }, /* 1/2**8 */
+/**/ delv = {{0x00000000, 0x3ef00000} }, /* 1/2**16 */
+/**/ ln2a = {{0xfefa3800, 0x3fe62e42} }, /* ln(2) 43 bits */
+/**/ ln2b = {{0x93c76730, 0x3d2ef357} }, /* ln(2)-ln2a */
+/**/ e1 = {{0x00000000, 0x3bbcc868} }, /* 6.095e-21 */
+/**/ e2 = {{0x00000000, 0x3c1138ce} }, /* 2.334e-19 */
+/**/ e3 = {{0x00000000, 0x3aa1565d} }, /* 2.801e-26 */
+/**/ e4 = {{0x00000000, 0x39809d88} }, /* 1.024e-31 */
+/**/ e[M] ={{{0x00000000, 0x37da223a} }, /* 1.2e-39 */
+/**/ {{0x00000000, 0x35c851c4} }, /* 1.3e-49 */
+/**/ {{0x00000000, 0x2ab85e51} }, /* 6.8e-103 */
+/**/ {{0x00000000, 0x17383827} }},/* 8.1e-197 */
+/**/ two54 = {{0x00000000, 0x43500000} }, /* 2**54 */
+/**/ u03 = {{0xeb851eb8, 0x3f9eb851} }; /* 0.03 */
+
+#endif
+#endif
+
+#define ZERO zero.d
+#define ONE one.d
+#define HALF half.d
+#define MHALF mhalf.d
+#define SQRT_2 sqrt_2.d
+#define DEL_U delu.d
+#define DEL_V delv.d
+#define LN2A ln2a.d
+#define LN2B ln2b.d
+#define E1 e1.d
+#define E2 e2.d
+#define E3 e3.d
+#define E4 e4.d
+#define U03 u03.d
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/ulog.tbl b/libc/sysdeps/ieee754/dbl-64/ulog.tbl
new file mode 100644
index 000000000..41aed931f
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/ulog.tbl
@@ -0,0 +1,3327 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/****************************************************************/
+/* TABLES FOR THE ulog() FUNCTION */
+/****************************************************************/
+
+#ifdef BIG_ENDI
+ static const number
+ Iu[182] = { /* 1/ui */
+/**/ {{0x3ff6a13c, 0xd1537290} },
+/**/ {{0x3ff68168, 0x16816817} },
+/**/ {{0x3ff661ec, 0x6a5122f9} },
+/**/ {{0x3ff642c8, 0x590b2164} },
+/**/ {{0x3ff623fa, 0x77016240} },
+/**/ {{0x3ff60581, 0x60581606} },
+/**/ {{0x3ff5e75b, 0xb8d015e7} },
+/**/ {{0x3ff5c988, 0x2b931057} },
+/**/ {{0x3ff5ac05, 0x6b015ac0} },
+/**/ {{0x3ff58ed2, 0x308158ed} },
+/**/ {{0x3ff571ed, 0x3c506b3a} },
+/**/ {{0x3ff55555, 0x55555555} },
+/**/ {{0x3ff53909, 0x48f40feb} },
+/**/ {{0x3ff51d07, 0xeae2f815} },
+/**/ {{0x3ff50150, 0x15015015} },
+/**/ {{0x3ff4e5e0, 0xa72f0539} },
+/**/ {{0x3ff4cab8, 0x8725af6e} },
+/**/ {{0x3ff4afd6, 0xa052bf5b} },
+/**/ {{0x3ff49539, 0xe3b2d067} },
+/**/ {{0x3ff47ae1, 0x47ae147b} },
+/**/ {{0x3ff460cb, 0xc7f5cf9a} },
+/**/ {{0x3ff446f8, 0x6562d9fb} },
+/**/ {{0x3ff42d66, 0x25d51f87} },
+/**/ {{0x3ff41414, 0x14141414} },
+/**/ {{0x3ff3fb01, 0x3fb013fb} },
+/**/ {{0x3ff3e22c, 0xbce4a902} },
+/**/ {{0x3ff3c995, 0xa47babe7} },
+/**/ {{0x3ff3b13b, 0x13b13b14} },
+/**/ {{0x3ff3991c, 0x2c187f63} },
+/**/ {{0x3ff38138, 0x13813814} },
+/**/ {{0x3ff3698d, 0xf3de0748} },
+/**/ {{0x3ff3521c, 0xfb2b78c1} },
+/**/ {{0x3ff33ae4, 0x5b57bcb2} },
+/**/ {{0x3ff323e3, 0x4a2b10bf} },
+/**/ {{0x3ff30d19, 0x0130d190} },
+/**/ {{0x3ff2f684, 0xbda12f68} },
+/**/ {{0x3ff2e025, 0xc04b8097} },
+/**/ {{0x3ff2c9fb, 0x4d812ca0} },
+/**/ {{0x3ff2b404, 0xad012b40} },
+/**/ {{0x3ff29e41, 0x29e4129e} },
+/**/ {{0x3ff288b0, 0x1288b013} },
+/**/ {{0x3ff27350, 0xb8812735} },
+/**/ {{0x3ff25e22, 0x708092f1} },
+/**/ {{0x3ff24924, 0x92492492} },
+/**/ {{0x3ff23456, 0x789abcdf} },
+/**/ {{0x3ff21fb7, 0x8121fb78} },
+/**/ {{0x3ff20b47, 0x0c67c0d9} },
+/**/ {{0x3ff1f704, 0x7dc11f70} },
+/**/ {{0x3ff1e2ef, 0x3b3fb874} },
+/**/ {{0x3ff1cf06, 0xada2811d} },
+/**/ {{0x3ff1bb4a, 0x4046ed29} },
+/**/ {{0x3ff1a7b9, 0x611a7b96} },
+/**/ {{0x3ff19453, 0x808ca29c} },
+/**/ {{0x3ff18118, 0x11811812} },
+/**/ {{0x3ff16e06, 0x89427379} },
+/**/ {{0x3ff15b1e, 0x5f75270d} },
+/**/ {{0x3ff1485f, 0x0e0acd3b} },
+/**/ {{0x3ff135c8, 0x1135c811} },
+/**/ {{0x3ff12358, 0xe75d3033} },
+/**/ {{0x3ff11111, 0x11111111} },
+/**/ {{0x3ff0fef0, 0x10fef011} },
+/**/ {{0x3ff0ecf5, 0x6be69c90} },
+/**/ {{0x3ff0db20, 0xa88f4696} },
+/**/ {{0x3ff0c971, 0x4fbcda3b} },
+/**/ {{0x3ff0b7e6, 0xec259dc8} },
+/**/ {{0x3ff0a681, 0x0a6810a7} },
+/**/ {{0x3ff0953f, 0x39010954} },
+/**/ {{0x3ff08421, 0x08421084} },
+/**/ {{0x3ff07326, 0x0a47f7c6} },
+/**/ {{0x3ff0624d, 0xd2f1a9fc} },
+/**/ {{0x3ff05197, 0xf7d73404} },
+/**/ {{0x3ff04104, 0x10410410} },
+/**/ {{0x3ff03091, 0xb51f5e1a} },
+/**/ {{0x3ff02040, 0x81020408} },
+/**/ {{0x3ff01010, 0x10101010} },
+/**/ {{0x3ff00000, 0x00000000} },
+/**/ {{0x3fefe01f, 0xe01fe020} },
+/**/ {{0x3fefc07f, 0x01fc07f0} },
+/**/ {{0x3fefa11c, 0xaa01fa12} },
+/**/ {{0x3fef81f8, 0x1f81f820} },
+/**/ {{0x3fef6310, 0xaca0dbb5} },
+/**/ {{0x3fef4465, 0x9e4a4271} },
+/**/ {{0x3fef25f6, 0x44230ab5} },
+/**/ {{0x3fef07c1, 0xf07c1f08} },
+/**/ {{0x3feee9c7, 0xf8458e02} },
+/**/ {{0x3feecc07, 0xb301ecc0} },
+/**/ {{0x3feeae80, 0x7aba01eb} },
+/**/ {{0x3fee9131, 0xabf0b767} },
+/**/ {{0x3fee741a, 0xa59750e4} },
+/**/ {{0x3fee573a, 0xc901e574} },
+/**/ {{0x3fee3a91, 0x79dc1a73} },
+/**/ {{0x3fee1e1e, 0x1e1e1e1e} },
+/**/ {{0x3fee01e0, 0x1e01e01e} },
+/**/ {{0x3fede5d6, 0xe3f8868a} },
+/**/ {{0x3fedca01, 0xdca01dca} },
+/**/ {{0x3fedae60, 0x76b981db} },
+/**/ {{0x3fed92f2, 0x231e7f8a} },
+/**/ {{0x3fed77b6, 0x54b82c34} },
+/**/ {{0x3fed5cac, 0x807572b2} },
+/**/ {{0x3fed41d4, 0x1d41d41d} },
+/**/ {{0x3fed272c, 0xa3fc5b1a} },
+/**/ {{0x3fed0cb5, 0x8f6ec074} },
+/**/ {{0x3fecf26e, 0x5c44bfc6} },
+/**/ {{0x3fecd856, 0x89039b0b} },
+/**/ {{0x3fecbe6d, 0x9601cbe7} },
+/**/ {{0x3feca4b3, 0x055ee191} },
+/**/ {{0x3fec8b26, 0x5afb8a42} },
+/**/ {{0x3fec71c7, 0x1c71c71c} },
+/**/ {{0x3fec5894, 0xd10d4986} },
+/**/ {{0x3fec3f8f, 0x01c3f8f0} },
+/**/ {{0x3fec26b5, 0x392ea01c} },
+/**/ {{0x3fec0e07, 0x0381c0e0} },
+/**/ {{0x3febf583, 0xee868d8b} },
+/**/ {{0x3febdd2b, 0x899406f7} },
+/**/ {{0x3febc4fd, 0x65883e7b} },
+/**/ {{0x3febacf9, 0x14c1bad0} },
+/**/ {{0x3feb951e, 0x2b18ff23} },
+/**/ {{0x3feb7d6c, 0x3dda338b} },
+/**/ {{0x3feb65e2, 0xe3beee05} },
+/**/ {{0x3feb4e81, 0xb4e81b4f} },
+/**/ {{0x3feb3748, 0x4ad806ce} },
+/**/ {{0x3feb2036, 0x406c80d9} },
+/**/ {{0x3feb094b, 0x31d922a4} },
+/**/ {{0x3feaf286, 0xbca1af28} },
+/**/ {{0x3feadbe8, 0x7f94905e} },
+/**/ {{0x3feac570, 0x1ac5701b} },
+/**/ {{0x3feaaf1d, 0x2f87ebfd} },
+/**/ {{0x3fea98ef, 0x606a63be} },
+/**/ {{0x3fea82e6, 0x5130e159} },
+/**/ {{0x3fea6d01, 0xa6d01a6d} },
+/**/ {{0x3fea5741, 0x07688a4a} },
+/**/ {{0x3fea41a4, 0x1a41a41a} },
+/**/ {{0x3fea2c2a, 0x87c51ca0} },
+/**/ {{0x3fea16d3, 0xf97a4b02} },
+/**/ {{0x3fea01a0, 0x1a01a01a} },
+/**/ {{0x3fe9ec8e, 0x951033d9} },
+/**/ {{0x3fe9d79f, 0x176b682d} },
+/**/ {{0x3fe9c2d1, 0x4ee4a102} },
+/**/ {{0x3fe9ae24, 0xea5510da} },
+/**/ {{0x3fe99999, 0x9999999a} },
+/**/ {{0x3fe9852f, 0x0d8ec0ff} },
+/**/ {{0x3fe970e4, 0xf80cb872} },
+/**/ {{0x3fe95cbb, 0x0be377ae} },
+/**/ {{0x3fe948b0, 0xfcd6e9e0} },
+/**/ {{0x3fe934c6, 0x7f9b2ce6} },
+/**/ {{0x3fe920fb, 0x49d0e229} },
+/**/ {{0x3fe90d4f, 0x120190d5} },
+/**/ {{0x3fe8f9c1, 0x8f9c18fa} },
+/**/ {{0x3fe8e652, 0x7af1373f} },
+/**/ {{0x3fe8d301, 0x8d3018d3} },
+/**/ {{0x3fe8bfce, 0x8062ff3a} },
+/**/ {{0x3fe8acb9, 0x0f6bf3aa} },
+/**/ {{0x3fe899c0, 0xf601899c} },
+/**/ {{0x3fe886e5, 0xf0abb04a} },
+/**/ {{0x3fe87427, 0xbcc092b9} },
+/**/ {{0x3fe86186, 0x18618618} },
+/**/ {{0x3fe84f00, 0xc2780614} },
+/**/ {{0x3fe83c97, 0x7ab2bedd} },
+/**/ {{0x3fe82a4a, 0x0182a4a0} },
+/**/ {{0x3fe81818, 0x18181818} },
+/**/ {{0x3fe80601, 0x80601806} },
+/**/ {{0x3fe7f405, 0xfd017f40} },
+/**/ {{0x3fe7e225, 0x515a4f1d} },
+/**/ {{0x3fe7d05f, 0x417d05f4} },
+/**/ {{0x3fe7beb3, 0x922e017c} },
+/**/ {{0x3fe7ad22, 0x08e0ecc3} },
+/**/ {{0x3fe79baa, 0x6bb6398b} },
+/**/ {{0x3fe78a4c, 0x8178a4c8} },
+/**/ {{0x3fe77908, 0x119ac60d} },
+/**/ {{0x3fe767dc, 0xe434a9b1} },
+/**/ {{0x3fe756ca, 0xc201756d} },
+/**/ {{0x3fe745d1, 0x745d1746} },
+/**/ {{0x3fe734f0, 0xc541fe8d} },
+/**/ {{0x3fe72428, 0x7f46debc} },
+/**/ {{0x3fe71378, 0x6d9c7c09} },
+/**/ {{0x3fe702e0, 0x5c0b8170} },
+/**/ {{0x3fe6f260, 0x16f26017} },
+/**/ {{0x3fe6e1f7, 0x6b4337c7} },
+/**/ {{0x3fe6d1a6, 0x2681c861} },
+/**/ {{0x3fe6c16c, 0x16c16c17} },
+/**/ {{0x3fe6b149, 0x0aa31a3d} },
+/**/ {{0x3fe6a13c, 0xd1537290} },
+ };
+
+ static const number
+ Iv[362] = { /* 1/vj */
+/**/ {{0x3ff00b47, 0xee93bfe3} },
+/**/ {{0x3ff00b37, 0xd80c106f} },
+/**/ {{0x3ff00b27, 0xc1a4a47a} },
+/**/ {{0x3ff00b17, 0xab5d7ba2} },
+/**/ {{0x3ff00b07, 0x95369587} },
+/**/ {{0x3ff00af7, 0x7f2ff1c6} },
+/**/ {{0x3ff00ae7, 0x69499000} },
+/**/ {{0x3ff00ad7, 0x53836fd3} },
+/**/ {{0x3ff00ac7, 0x3ddd90dd} },
+/**/ {{0x3ff00ab7, 0x2857f2bf} },
+/**/ {{0x3ff00aa7, 0x12f29517} },
+/**/ {{0x3ff00a96, 0xfdad7784} },
+/**/ {{0x3ff00a86, 0xe88899a5} },
+/**/ {{0x3ff00a76, 0xd383fb19} },
+/**/ {{0x3ff00a66, 0xbe9f9b7f} },
+/**/ {{0x3ff00a56, 0xa9db7a76} },
+/**/ {{0x3ff00a46, 0x9537979d} },
+/**/ {{0x3ff00a36, 0x80b3f293} },
+/**/ {{0x3ff00a26, 0x6c508af8} },
+/**/ {{0x3ff00a16, 0x580d606a} },
+/**/ {{0x3ff00a06, 0x43ea7288} },
+/**/ {{0x3ff009f6, 0x2fe7c0f1} },
+/**/ {{0x3ff009e6, 0x1c054b44} },
+/**/ {{0x3ff009d6, 0x08431122} },
+/**/ {{0x3ff009c5, 0xf4a11227} },
+/**/ {{0x3ff009b5, 0xe11f4df4} },
+/**/ {{0x3ff009a5, 0xcdbdc428} },
+/**/ {{0x3ff00995, 0xba7c7462} },
+/**/ {{0x3ff00985, 0xa75b5e40} },
+/**/ {{0x3ff00975, 0x945a8162} },
+/**/ {{0x3ff00965, 0x8179dd68} },
+/**/ {{0x3ff00955, 0x6eb971ef} },
+/**/ {{0x3ff00945, 0x5c193e98} },
+/**/ {{0x3ff00935, 0x49994301} },
+/**/ {{0x3ff00925, 0x37397eca} },
+/**/ {{0x3ff00915, 0x24f9f192} },
+/**/ {{0x3ff00905, 0x12da9af7} },
+/**/ {{0x3ff008f5, 0x00db7a99} },
+/**/ {{0x3ff008e4, 0xeefc9018} },
+/**/ {{0x3ff008d4, 0xdd3ddb12} },
+/**/ {{0x3ff008c4, 0xcb9f5b26} },
+/**/ {{0x3ff008b4, 0xba210ff4} },
+/**/ {{0x3ff008a4, 0xa8c2f91a} },
+/**/ {{0x3ff00894, 0x97851639} },
+/**/ {{0x3ff00884, 0x866766ef} },
+/**/ {{0x3ff00874, 0x7569eadb} },
+/**/ {{0x3ff00864, 0x648ca19d} },
+/**/ {{0x3ff00854, 0x53cf8ad3} },
+/**/ {{0x3ff00844, 0x4332a61e} },
+/**/ {{0x3ff00834, 0x32b5f31b} },
+/**/ {{0x3ff00824, 0x2259716c} },
+/**/ {{0x3ff00814, 0x121d20ad} },
+/**/ {{0x3ff00804, 0x02010080} },
+/**/ {{0x3ff007f3, 0xf2051083} },
+/**/ {{0x3ff007e3, 0xe2295056} },
+/**/ {{0x3ff007d3, 0xd26dbf97} },
+/**/ {{0x3ff007c3, 0xc2d25de5} },
+/**/ {{0x3ff007b3, 0xb3572ae2} },
+/**/ {{0x3ff007a3, 0xa3fc262a} },
+/**/ {{0x3ff00793, 0x94c14f5f} },
+/**/ {{0x3ff00783, 0x85a6a61e} },
+/**/ {{0x3ff00773, 0x76ac2a08} },
+/**/ {{0x3ff00763, 0x67d1dabb} },
+/**/ {{0x3ff00753, 0x5917b7d7} },
+/**/ {{0x3ff00743, 0x4a7dc0fb} },
+/**/ {{0x3ff00733, 0x3c03f5c7} },
+/**/ {{0x3ff00723, 0x2daa55da} },
+/**/ {{0x3ff00713, 0x1f70e0d3} },
+/**/ {{0x3ff00703, 0x11579652} },
+/**/ {{0x3ff006f3, 0x035e75f5} },
+/**/ {{0x3ff006e2, 0xf5857f5d} },
+/**/ {{0x3ff006d2, 0xe7ccb228} },
+/**/ {{0x3ff006c2, 0xda340df6} },
+/**/ {{0x3ff006b2, 0xccbb9266} },
+/**/ {{0x3ff006a2, 0xbf633f18} },
+/**/ {{0x3ff00692, 0xb22b13ab} },
+/**/ {{0x3ff00682, 0xa5130fbe} },
+/**/ {{0x3ff00672, 0x981b32f1} },
+/**/ {{0x3ff00662, 0x8b437ce4} },
+/**/ {{0x3ff00652, 0x7e8bed35} },
+/**/ {{0x3ff00642, 0x71f48383} },
+/**/ {{0x3ff00632, 0x657d3f70} },
+/**/ {{0x3ff00622, 0x59262098} },
+/**/ {{0x3ff00612, 0x4cef269e} },
+/**/ {{0x3ff00602, 0x40d8511e} },
+/**/ {{0x3ff005f2, 0x34e19fba} },
+/**/ {{0x3ff005e2, 0x290b1211} },
+/**/ {{0x3ff005d2, 0x1d54a7c1} },
+/**/ {{0x3ff005c2, 0x11be606b} },
+/**/ {{0x3ff005b2, 0x06483bad} },
+/**/ {{0x3ff005a1, 0xfaf23928} },
+/**/ {{0x3ff00591, 0xefbc587b} },
+/**/ {{0x3ff00581, 0xe4a69945} },
+/**/ {{0x3ff00571, 0xd9b0fb25} },
+/**/ {{0x3ff00561, 0xcedb7dbc} },
+/**/ {{0x3ff00551, 0xc42620a9} },
+/**/ {{0x3ff00541, 0xb990e38b} },
+/**/ {{0x3ff00531, 0xaf1bc601} },
+/**/ {{0x3ff00521, 0xa4c6c7ac} },
+/**/ {{0x3ff00511, 0x9a91e82a} },
+/**/ {{0x3ff00501, 0x907d271c} },
+/**/ {{0x3ff004f1, 0x86888421} },
+/**/ {{0x3ff004e1, 0x7cb3fed8} },
+/**/ {{0x3ff004d1, 0x72ff96e0} },
+/**/ {{0x3ff004c1, 0x696b4bdb} },
+/**/ {{0x3ff004b1, 0x5ff71d66} },
+/**/ {{0x3ff004a1, 0x56a30b21} },
+/**/ {{0x3ff00491, 0x4d6f14ad} },
+/**/ {{0x3ff00481, 0x445b39a8} },
+/**/ {{0x3ff00471, 0x3b6779b3} },
+/**/ {{0x3ff00461, 0x3293d46c} },
+/**/ {{0x3ff00451, 0x29e04974} },
+/**/ {{0x3ff00441, 0x214cd869} },
+/**/ {{0x3ff00431, 0x18d980ed} },
+/**/ {{0x3ff00421, 0x1086429d} },
+/**/ {{0x3ff00411, 0x08531d1a} },
+/**/ {{0x3ff00401, 0x00401004} },
+/**/ {{0x3ff003f0, 0xf84d1afa} },
+/**/ {{0x3ff003e0, 0xf07a3d9b} },
+/**/ {{0x3ff003d0, 0xe8c77787} },
+/**/ {{0x3ff003c0, 0xe134c85f} },
+/**/ {{0x3ff003b0, 0xd9c22fc1} },
+/**/ {{0x3ff003a0, 0xd26fad4d} },
+/**/ {{0x3ff00390, 0xcb3d40a3} },
+/**/ {{0x3ff00380, 0xc42ae963} },
+/**/ {{0x3ff00370, 0xbd38a72c} },
+/**/ {{0x3ff00360, 0xb666799e} },
+/**/ {{0x3ff00350, 0xafb46058} },
+/**/ {{0x3ff00340, 0xa9225afa} },
+/**/ {{0x3ff00330, 0xa2b06925} },
+/**/ {{0x3ff00320, 0x9c5e8a77} },
+/**/ {{0x3ff00310, 0x962cbe90} },
+/**/ {{0x3ff00300, 0x901b0511} },
+/**/ {{0x3ff002f0, 0x8a295d98} },
+/**/ {{0x3ff002e0, 0x8457c7c6} },
+/**/ {{0x3ff002d0, 0x7ea6433a} },
+/**/ {{0x3ff002c0, 0x7914cf94} },
+/**/ {{0x3ff002b0, 0x73a36c73} },
+/**/ {{0x3ff002a0, 0x6e521978} },
+/**/ {{0x3ff00290, 0x6920d642} },
+/**/ {{0x3ff00280, 0x640fa271} },
+/**/ {{0x3ff00270, 0x5f1e7da5} },
+/**/ {{0x3ff00260, 0x5a4d677d} },
+/**/ {{0x3ff00250, 0x559c5f9a} },
+/**/ {{0x3ff00240, 0x510b659a} },
+/**/ {{0x3ff00230, 0x4c9a791f} },
+/**/ {{0x3ff00220, 0x484999c6} },
+/**/ {{0x3ff00210, 0x4418c732} },
+/**/ {{0x3ff00200, 0x40080100} },
+/**/ {{0x3ff001f0, 0x3c1746d2} },
+/**/ {{0x3ff001e0, 0x38469846} },
+/**/ {{0x3ff001d0, 0x3495f4fd} },
+/**/ {{0x3ff001c0, 0x31055c96} },
+/**/ {{0x3ff001b0, 0x2d94ceb2} },
+/**/ {{0x3ff001a0, 0x2a444af0} },
+/**/ {{0x3ff00190, 0x2713d0ef} },
+/**/ {{0x3ff00180, 0x24036051} },
+/**/ {{0x3ff00170, 0x2112f8b4} },
+/**/ {{0x3ff00160, 0x1e4299b9} },
+/**/ {{0x3ff00150, 0x1b9242ff} },
+/**/ {{0x3ff00140, 0x1901f427} },
+/**/ {{0x3ff00130, 0x1691acd0} },
+/**/ {{0x3ff00120, 0x14416c9a} },
+/**/ {{0x3ff00110, 0x12113324} },
+/**/ {{0x3ff00100, 0x10010010} },
+/**/ {{0x3ff000f0, 0x0e10d2fc} },
+/**/ {{0x3ff000e0, 0x0c40ab89} },
+/**/ {{0x3ff000d0, 0x0a908957} },
+/**/ {{0x3ff000c0, 0x09006c05} },
+/**/ {{0x3ff000b0, 0x07905334} },
+/**/ {{0x3ff000a0, 0x06403e82} },
+/**/ {{0x3ff00090, 0x05102d92} },
+/**/ {{0x3ff00080, 0x04002001} },
+/**/ {{0x3ff00070, 0x03101571} },
+/**/ {{0x3ff00060, 0x02400d80} },
+/**/ {{0x3ff00050, 0x019007d0} },
+/**/ {{0x3ff00040, 0x01000400} },
+/**/ {{0x3ff00030, 0x009001b0} },
+/**/ {{0x3ff00020, 0x00400080} },
+/**/ {{0x3ff00010, 0x00100010} },
+/**/ {{0x3ff00000, 0x00000000} },
+/**/ {{0x3fefffe0, 0x001fffe0} },
+/**/ {{0x3fefffc0, 0x007fff00} },
+/**/ {{0x3fefffa0, 0x011ffca0} },
+/**/ {{0x3fefff80, 0x01fff800} },
+/**/ {{0x3fefff60, 0x031ff060} },
+/**/ {{0x3fefff40, 0x047fe501} },
+/**/ {{0x3fefff20, 0x061fd521} },
+/**/ {{0x3fefff00, 0x07ffc002} },
+/**/ {{0x3feffee0, 0x0a1fa4e3} },
+/**/ {{0x3feffec0, 0x0c7f8305} },
+/**/ {{0x3feffea0, 0x0f1f59a7} },
+/**/ {{0x3feffe80, 0x11ff280a} },
+/**/ {{0x3feffe60, 0x151eed6e} },
+/**/ {{0x3feffe40, 0x187ea913} },
+/**/ {{0x3feffe20, 0x1c1e5a39} },
+/**/ {{0x3feffe00, 0x1ffe0020} },
+/**/ {{0x3feffde0, 0x241d9a09} },
+/**/ {{0x3feffdc0, 0x287d2733} },
+/**/ {{0x3feffda0, 0x2d1ca6e0} },
+/**/ {{0x3feffd80, 0x31fc184e} },
+/**/ {{0x3feffd60, 0x371b7abf} },
+/**/ {{0x3feffd40, 0x3c7acd72} },
+/**/ {{0x3feffd20, 0x421a0fa9} },
+/**/ {{0x3feffd00, 0x47f940a2} },
+/**/ {{0x3feffce0, 0x4e185f9f} },
+/**/ {{0x3feffcc0, 0x54776bdf} },
+/**/ {{0x3feffca0, 0x5b1664a3} },
+/**/ {{0x3feffc80, 0x61f5492c} },
+/**/ {{0x3feffc60, 0x691418b9} },
+/**/ {{0x3feffc40, 0x7072d28b} },
+/**/ {{0x3feffc20, 0x781175e3} },
+/**/ {{0x3feffc00, 0x7ff00200} },
+/**/ {{0x3feffbe0, 0x880e7623} },
+/**/ {{0x3feffbc0, 0x906cd18c} },
+/**/ {{0x3feffba0, 0x990b137c} },
+/**/ {{0x3feffb80, 0xa1e93b34} },
+/**/ {{0x3feffb60, 0xab0747f3} },
+/**/ {{0x3feffb40, 0xb46538fa} },
+/**/ {{0x3feffb20, 0xbe030d89} },
+/**/ {{0x3feffb00, 0xc7e0c4e1} },
+/**/ {{0x3feffae0, 0xd1fe5e43} },
+/**/ {{0x3feffac0, 0xdc5bd8ee} },
+/**/ {{0x3feffaa0, 0xe6f93424} },
+/**/ {{0x3feffa80, 0xf1d66f25} },
+/**/ {{0x3feffa60, 0xfcf38931} },
+/**/ {{0x3feffa41, 0x08508189} },
+/**/ {{0x3feffa21, 0x13ed576d} },
+/**/ {{0x3feffa01, 0x1fca0a1e} },
+/**/ {{0x3feff9e1, 0x2be698dd} },
+/**/ {{0x3feff9c1, 0x384302e9} },
+/**/ {{0x3feff9a1, 0x44df4785} },
+/**/ {{0x3feff981, 0x51bb65ef} },
+/**/ {{0x3feff961, 0x5ed75d6a} },
+/**/ {{0x3feff941, 0x6c332d34} },
+/**/ {{0x3feff921, 0x79ced490} },
+/**/ {{0x3feff901, 0x87aa52be} },
+/**/ {{0x3feff8e1, 0x95c5a6fe} },
+/**/ {{0x3feff8c1, 0xa420d091} },
+/**/ {{0x3feff8a1, 0xb2bbceb7} },
+/**/ {{0x3feff881, 0xc196a0b2} },
+/**/ {{0x3feff861, 0xd0b145c2} },
+/**/ {{0x3feff841, 0xe00bbd28} },
+/**/ {{0x3feff821, 0xefa60624} },
+/**/ {{0x3feff801, 0xff801ff8} },
+/**/ {{0x3feff7e2, 0x0f9a09e3} },
+/**/ {{0x3feff7c2, 0x1ff3c328} },
+/**/ {{0x3feff7a2, 0x308d4b05} },
+/**/ {{0x3feff782, 0x4166a0bd} },
+/**/ {{0x3feff762, 0x527fc390} },
+/**/ {{0x3feff742, 0x63d8b2bf} },
+/**/ {{0x3feff722, 0x75716d8b} },
+/**/ {{0x3feff702, 0x8749f334} },
+/**/ {{0x3feff6e2, 0x996242fb} },
+/**/ {{0x3feff6c2, 0xabba5c21} },
+/**/ {{0x3feff6a2, 0xbe523de8} },
+/**/ {{0x3feff682, 0xd129e78f} },
+/**/ {{0x3feff662, 0xe4415858} },
+/**/ {{0x3feff642, 0xf7988f84} },
+/**/ {{0x3feff623, 0x0b2f8c54} },
+/**/ {{0x3feff603, 0x1f064e08} },
+/**/ {{0x3feff5e3, 0x331cd3e1} },
+/**/ {{0x3feff5c3, 0x47731d21} },
+/**/ {{0x3feff5a3, 0x5c092908} },
+/**/ {{0x3feff583, 0x70def6d7} },
+/**/ {{0x3feff563, 0x85f485d0} },
+/**/ {{0x3feff543, 0x9b49d532} },
+/**/ {{0x3feff523, 0xb0dee440} },
+/**/ {{0x3feff503, 0xc6b3b23b} },
+/**/ {{0x3feff4e3, 0xdcc83e62} },
+/**/ {{0x3feff4c3, 0xf31c87f8} },
+/**/ {{0x3feff4a4, 0x09b08e3d} },
+/**/ {{0x3feff484, 0x20845073} },
+/**/ {{0x3feff464, 0x3797cdda} },
+/**/ {{0x3feff444, 0x4eeb05b4} },
+/**/ {{0x3feff424, 0x667df741} },
+/**/ {{0x3feff404, 0x7e50a1c3} },
+/**/ {{0x3feff3e4, 0x9663047b} },
+/**/ {{0x3feff3c4, 0xaeb51eaa} },
+/**/ {{0x3feff3a4, 0xc746ef91} },
+/**/ {{0x3feff384, 0xe0187672} },
+/**/ {{0x3feff364, 0xf929b28d} },
+/**/ {{0x3feff345, 0x127aa323} },
+/**/ {{0x3feff325, 0x2c0b4776} },
+/**/ {{0x3feff305, 0x45db9ec7} },
+/**/ {{0x3feff2e5, 0x5feba858} },
+/**/ {{0x3feff2c5, 0x7a3b6369} },
+/**/ {{0x3feff2a5, 0x94cacf3b} },
+/**/ {{0x3feff285, 0xaf99eb11} },
+/**/ {{0x3feff265, 0xcaa8b62a} },
+/**/ {{0x3feff245, 0xe5f72fc9} },
+/**/ {{0x3feff226, 0x0185572f} },
+/**/ {{0x3feff206, 0x1d532b9d} },
+/**/ {{0x3feff1e6, 0x3960ac54} },
+/**/ {{0x3feff1c6, 0x55add896} },
+/**/ {{0x3feff1a6, 0x723aafa3} },
+/**/ {{0x3feff186, 0x8f0730be} },
+/**/ {{0x3feff166, 0xac135b27} },
+/**/ {{0x3feff146, 0xc95f2e21} },
+/**/ {{0x3feff126, 0xe6eaa8eb} },
+/**/ {{0x3feff107, 0x04b5cac9} },
+/**/ {{0x3feff0e7, 0x22c092fb} },
+/**/ {{0x3feff0c7, 0x410b00c2} },
+/**/ {{0x3feff0a7, 0x5f951360} },
+/**/ {{0x3feff087, 0x7e5eca16} },
+/**/ {{0x3feff067, 0x9d682426} },
+/**/ {{0x3feff047, 0xbcb120d2} },
+/**/ {{0x3feff027, 0xdc39bf5a} },
+/**/ {{0x3feff007, 0xfc01ff00} },
+/**/ {{0x3fefefe8, 0x1c09df07} },
+/**/ {{0x3fefefc8, 0x3c515eae} },
+/**/ {{0x3fefefa8, 0x5cd87d38} },
+/**/ {{0x3fefef88, 0x7d9f39e6} },
+/**/ {{0x3fefef68, 0x9ea593fa} },
+/**/ {{0x3fefef48, 0xbfeb8ab5} },
+/**/ {{0x3fefef28, 0xe1711d5a} },
+/**/ {{0x3fefef09, 0x03364b28} },
+/**/ {{0x3fefeee9, 0x253b1363} },
+/**/ {{0x3fefeec9, 0x477f754b} },
+/**/ {{0x3fefeea9, 0x6a037022} },
+/**/ {{0x3fefee89, 0x8cc7032a} },
+/**/ {{0x3fefee69, 0xafca2da5} },
+/**/ {{0x3fefee49, 0xd30ceed4} },
+/**/ {{0x3fefee29, 0xf68f45f8} },
+/**/ {{0x3fefee0a, 0x1a513254} },
+/**/ {{0x3fefedea, 0x3e52b329} },
+/**/ {{0x3fefedca, 0x6293c7b8} },
+/**/ {{0x3fefedaa, 0x87146f44} },
+/**/ {{0x3fefed8a, 0xabd4a90e} },
+/**/ {{0x3fefed6a, 0xd0d47458} },
+/**/ {{0x3fefed4a, 0xf613d064} },
+/**/ {{0x3fefed2b, 0x1b92bc73} },
+/**/ {{0x3fefed0b, 0x415137c7} },
+/**/ {{0x3fefeceb, 0x674f41a2} },
+/**/ {{0x3fefeccb, 0x8d8cd945} },
+/**/ {{0x3fefecab, 0xb409fdf3} },
+/**/ {{0x3fefec8b, 0xdac6aeed} },
+/**/ {{0x3fefec6c, 0x01c2eb76} },
+/**/ {{0x3fefec4c, 0x28feb2ce} },
+/**/ {{0x3fefec2c, 0x507a0437} },
+/**/ {{0x3fefec0c, 0x7834def5} },
+/**/ {{0x3fefebec, 0xa02f4247} },
+/**/ {{0x3fefebcc, 0xc8692d71} },
+/**/ {{0x3fefebac, 0xf0e29fb4} },
+/**/ {{0x3fefeb8d, 0x199b9852} },
+/**/ {{0x3fefeb6d, 0x4294168d} },
+/**/ {{0x3fefeb4d, 0x6bcc19a7} },
+/**/ {{0x3fefeb2d, 0x9543a0e2} },
+/**/ {{0x3fefeb0d, 0xbefaab7f} },
+/**/ {{0x3fefeaed, 0xe8f138c2} },
+/**/ {{0x3fefeace, 0x132747ea} },
+/**/ {{0x3fefeaae, 0x3d9cd83c} },
+/**/ {{0x3fefea8e, 0x6851e8f7} },
+/**/ {{0x3fefea6e, 0x93467960} },
+/**/ {{0x3fefea4e, 0xbe7a88b7} },
+/**/ {{0x3fefea2e, 0xe9ee163f} },
+/**/ {{0x3fefea0f, 0x15a12139} },
+/**/ {{0x3fefe9ef, 0x4193a8e8} },
+/**/ {{0x3fefe9cf, 0x6dc5ac8e} },
+/**/ {{0x3fefe9af, 0x9a372b6d} },
+/**/ {{0x3fefe98f, 0xc6e824c6} },
+/**/ {{0x3fefe96f, 0xf3d897dd} },
+ };
+
+ static const number
+ Lu[182][2] = { /* log(ui) */
+/**/ {{{0xbfd63003, 0x0b3aac49} },
+/**/ {{0xbc6dc18c, 0xe51fff99} },},
+/**/ {{{0xbfd5d5bd, 0xdf595f30} },
+/**/ {{0x3c765411, 0x48cbb8a2} },},
+/**/ {{{0xbfd57bf7, 0x53c8d1fb} },
+/**/ {{0x3c60908d, 0x15f88b63} },},
+/**/ {{{0xbfd522ae, 0x0738a3d8} },
+/**/ {{0x3c68f7e9, 0xb38a6979} },},
+/**/ {{{0xbfd4c9e0, 0x9e172c3c} },
+/**/ {{0x3c512361, 0x5b147a5d} },},
+/**/ {{{0xbfd4718d, 0xc271c41b} },
+/**/ {{0xbc38fb4c, 0x14c56eef} },},
+/**/ {{{0xbfd419b4, 0x23d5e8c7} },
+/**/ {{0xbc60dbb2, 0x43827392} },},
+/**/ {{{0xbfd3c252, 0x77333184} },
+/**/ {{0x3c72ad27, 0xe50a8ec6} },},
+/**/ {{{0xbfd36b67, 0x76be1117} },
+/**/ {{0x3c5324f0, 0xe883858e} },},
+/**/ {{{0xbfd314f1, 0xe1d35ce4} },
+/**/ {{0x3c73d699, 0x09e5c3dc} },},
+/**/ {{{0xbfd2bef0, 0x7cdc9354} },
+/**/ {{0x3c782dad, 0x7fd86088} },},
+/**/ {{{0xbfd26962, 0x1134db92} },
+/**/ {{0xbc7e0efa, 0xdd9db02b} },},
+/**/ {{{0xbfd21445, 0x6d0eb8d4} },
+/**/ {{0xbc6f7ae9, 0x1aeba60a} },},
+/**/ {{{0xbfd1bf99, 0x635a6b95} },
+/**/ {{0x3c612aeb, 0x84249223} },},
+/**/ {{{0xbfd16b5c, 0xcbacfb73} },
+/**/ {{0xbc766fbd, 0x28b40935} },},
+/**/ {{{0xbfd1178e, 0x8227e47c} },
+/**/ {{0x3c60e63a, 0x5f01c691} },},
+/**/ {{{0xbfd0c42d, 0x676162e3} },
+/**/ {{0xbc5162c7, 0x9d5d11ee} },},
+/**/ {{{0xbfd07138, 0x604d5862} },
+/**/ {{0xbc7cdb16, 0xed4e9138} },},
+/**/ {{{0xbfd01eae, 0x5626c691} },
+/**/ {{0x3c418290, 0xbd2932e2} },},
+/**/ {{{0xbfcf991c, 0x6cb3b379} },
+/**/ {{0xbc6f6650, 0x66f980a2} },},
+/**/ {{{0xbfcef5ad, 0xe4dcffe6} },
+/**/ {{0x3c508ab2, 0xddc708a0} },},
+/**/ {{{0xbfce530e, 0xffe71012} },
+/**/ {{0xbc422760, 0x41f43042} },},
+/**/ {{{0xbfcdb13d, 0xb0d48940} },
+/**/ {{0xbc5aa11d, 0x49f96cb9} },},
+/**/ {{{0xbfcd1037, 0xf2655e7b} },
+/**/ {{0xbc660629, 0x242471a2} },},
+/**/ {{{0xbfcc6ffb, 0xc6f00f71} },
+/**/ {{0x3c68e58b, 0x2c57a4a5} },},
+/**/ {{{0xbfcbd087, 0x383bd8ad} },
+/**/ {{0xbc3dd355, 0xf6a516d7} },},
+/**/ {{{0xbfcb31d8, 0x575bce3d} },
+/**/ {{0x3c66353a, 0xb386a94d} },},
+/**/ {{{0xbfca93ed, 0x3c8ad9e3} },
+/**/ {{0xbc6bcafa, 0x9de97203} },},
+/**/ {{{0xbfc9f6c4, 0x07089664} },
+/**/ {{0xbc435a19, 0x605e67ef} },},
+/**/ {{{0xbfc95a5a, 0xdcf7017f} },
+/**/ {{0xbc5142c5, 0x07fb7a3d} },},
+/**/ {{{0xbfc8beaf, 0xeb38fe8c} },
+/**/ {{0xbc555aa8, 0xb6997a40} },},
+/**/ {{{0xbfc823c1, 0x6551a3c2} },
+/**/ {{0x3c61232c, 0xe70be781} },},
+/**/ {{{0xbfc7898d, 0x85444c73} },
+/**/ {{0xbc5ef8f6, 0xebcfb201} },},
+/**/ {{{0xbfc6f012, 0x8b756abc} },
+/**/ {{0x3c68de59, 0xc21e166c} },},
+/**/ {{{0xbfc6574e, 0xbe8c133a} },
+/**/ {{0x3c3d34f0, 0xf4621bed} },},
+/**/ {{{0xbfc5bf40, 0x6b543db2} },
+/**/ {{0x3c21f5b4, 0x4c0df7e7} },},
+/**/ {{{0xbfc527e5, 0xe4a1b58d} },
+/**/ {{0x3c271a96, 0x82395bfd} },},
+/**/ {{{0xbfc4913d, 0x8333b561} },
+/**/ {{0x3c50d560, 0x4930f135} },},
+/**/ {{{0xbfc3fb45, 0xa59928cc} },
+/**/ {{0x3c6d87e6, 0xa354d056} },},
+/**/ {{{0xbfc365fc, 0xb0159016} },
+/**/ {{0xbc57d411, 0xa5b944ad} },},
+/**/ {{{0xbfc2d161, 0x0c86813a} },
+/**/ {{0x3c5499a3, 0xf25af95f} },},
+/**/ {{{0xbfc23d71, 0x2a49c202} },
+/**/ {{0x3c66e381, 0x61051d69} },},
+/**/ {{{0xbfc1aa2b, 0x7e23f72a} },
+/**/ {{0x3c4c6ef1, 0xd9b2ef7e} },},
+/**/ {{{0xbfc1178e, 0x8227e47c} },
+/**/ {{0x3c50e63a, 0x5f01c691} },},
+/**/ {{{0xbfc08598, 0xb59e3a07} },
+/**/ {{0x3c6dd700, 0x9902bf32} },},
+/**/ {{{0xbfbfe891, 0x39dbd566} },
+/**/ {{0x3c5ac9f4, 0x215f9393} },},
+/**/ {{{0xbfbec739, 0x830a1120} },
+/**/ {{0x3c4a2bf9, 0x91780d3f} },},
+/**/ {{{0xbfbda727, 0x638446a2} },
+/**/ {{0xbc5401fa, 0x71733019} },},
+/**/ {{{0xbfbc8858, 0x01bc4b23} },
+/**/ {{0xbc5a38cb, 0x559a6706} },},
+/**/ {{{0xbfbb6ac8, 0x8dad5b1c} },
+/**/ {{0x3c40057e, 0xed1ca59f} },},
+/**/ {{{0xbfba4e76, 0x40b1bc38} },
+/**/ {{0x3c55b5ca, 0x203e4259} },},
+/**/ {{{0xbfb9335e, 0x5d594989} },
+/**/ {{0x3c5478a8, 0x5704ccb7} },},
+/**/ {{{0xbfb8197e, 0x2f40e3f0} },
+/**/ {{0xbc3b9f2d, 0xffbeed43} },},
+/**/ {{{0xbfb700d3, 0x0aeac0e1} },
+/**/ {{0x3c272566, 0x212cdd05} },},
+/**/ {{{0xbfb5e95a, 0x4d9791cb} },
+/**/ {{0xbc5f3874, 0x5c5c450a} },},
+/**/ {{{0xbfb4d311, 0x5d207eac} },
+/**/ {{0xbc5769f4, 0x2c7842cc} },},
+/**/ {{{0xbfb3bdf5, 0xa7d1ee64} },
+/**/ {{0xbc47a976, 0xd3b5b45f} },},
+/**/ {{{0xbfb2aa04, 0xa44717a5} },
+/**/ {{0x3c5d15d3, 0x8d2fa3f7} },},
+/**/ {{{0xbfb1973b, 0xd1465567} },
+/**/ {{0x3c475583, 0x67a6acf6} },},
+/**/ {{{0xbfb08598, 0xb59e3a07} },
+/**/ {{0x3c5dd700, 0x9902bf32} },},
+/**/ {{{0xbfaeea31, 0xc006b87c} },
+/**/ {{0x3c43e4fc, 0x93b7b66c} },},
+/**/ {{{0xbfaccb73, 0xcdddb2cc} },
+/**/ {{0x3c4e48fb, 0x0500efd4} },},
+/**/ {{{0xbfaaaef2, 0xd0fb10fc} },
+/**/ {{0xbc2a353b, 0xb42e0add} },},
+/**/ {{{0xbfa894aa, 0x149fb343} },
+/**/ {{0xbc3a8be9, 0x7660a23d} },},
+/**/ {{{0xbfa67c94, 0xf2d4bb58} },
+/**/ {{0xbc40413e, 0x6505e603} },},
+/**/ {{{0xbfa466ae, 0xd42de3ea} },
+/**/ {{0x3c4cdd6f, 0x7f4a137e} },},
+/**/ {{{0xbfa252f3, 0x2f8d183f} },
+/**/ {{0x3c4947f7, 0x92615916} },},
+/**/ {{{0xbfa0415d, 0x89e74444} },
+/**/ {{0xbc4c05cf, 0x1d753622} },},
+/**/ {{{0xbf9c63d2, 0xec14aaf2} },
+/**/ {{0x3c3ce030, 0xa686bd86} },},
+/**/ {{{0xbf984925, 0x28c8cabf} },
+/**/ {{0x3c3d192d, 0x0619fa67} },},
+/**/ {{{0xbf9432a9, 0x25980cc1} },
+/**/ {{0x3c38cdaf, 0x39004192} },},
+/**/ {{{0xbf902056, 0x58935847} },
+/**/ {{0xbc327c8e, 0x8416e71f} },},
+/**/ {{{0xbf882448, 0xa388a2aa} },
+/**/ {{0xbc104b16, 0x137f09a0} },},
+/**/ {{{0xbf801015, 0x7588de71} },
+/**/ {{0xbc146662, 0xd417ced0} },},
+/**/ {{{0xbf700805, 0x59588b35} },
+/**/ {{0xbc1f9663, 0x8cf63677} },},
+/**/ {{{0x00000000, 0x00000000} },
+/**/ {{0x00000000, 0x00000000} },},
+/**/ {{{0x3f6ff00a, 0xa2b10bc0} },
+/**/ {{0x3c02821a, 0xd5a6d353} },},
+/**/ {{{0x3f7fe02a, 0x6b106789} },
+/**/ {{0xbbce44b7, 0xe3711ebf} },},
+/**/ {{{0x3f87dc47, 0x5f810a77} },
+/**/ {{0xbc116d76, 0x87d3df21} },},
+/**/ {{{0x3f8fc0a8, 0xb0fc03e4} },
+/**/ {{0xbc183092, 0xc59642a1} },},
+/**/ {{{0x3f93cea4, 0x4346a575} },
+/**/ {{0xbc10cb5a, 0x902b3a1c} },},
+/**/ {{{0x3f97b91b, 0x07d5b11b} },
+/**/ {{0xbc35b602, 0xace3a510} },},
+/**/ {{{0x3f9b9fc0, 0x27af9198} },
+/**/ {{0xbbf0ae69, 0x229dc868} },},
+/**/ {{{0x3f9f829b, 0x0e783300} },
+/**/ {{0x3c333e3f, 0x04f1ef23} },},
+/**/ {{{0x3fa1b0d9, 0x8923d980} },
+/**/ {{0xbc3e9ae8, 0x89bac481} },},
+/**/ {{{0x3fa39e87, 0xb9febd60} },
+/**/ {{0xbc45bfa9, 0x37f551bb} },},
+/**/ {{{0x3fa58a5b, 0xafc8e4d5} },
+/**/ {{0xbc4ce55c, 0x2b4e2b72} },},
+/**/ {{{0x3fa77458, 0xf632dcfc} },
+/**/ {{0x3c418d3c, 0xa87b9296} },},
+/**/ {{{0x3fa95c83, 0x0ec8e3eb} },
+/**/ {{0x3c4f5a0e, 0x80520bf2} },},
+/**/ {{{0x3fab42dd, 0x711971bf} },
+/**/ {{0xbc3eb975, 0x9c130499} },},
+/**/ {{{0x3fad276b, 0x8adb0b52} },
+/**/ {{0x3c21e3c5, 0x3257fd47} },},
+/**/ {{{0x3faf0a30, 0xc01162a6} },
+/**/ {{0x3c485f32, 0x5c5bbacd} },},
+/**/ {{{0x3fb07598, 0x3598e471} },
+/**/ {{0x3c480da5, 0x333c45b8} },},
+/**/ {{{0x3fb16536, 0xeea37ae1} },
+/**/ {{0xbc379da3, 0xe8c22cda} },},
+/**/ {{{0x3fb253f6, 0x2f0a1417} },
+/**/ {{0xbc1c1259, 0x63fc4cfd} },},
+/**/ {{{0x3fb341d7, 0x961bd1d1} },
+/**/ {{0xbc5b599f, 0x227becbb} },},
+/**/ {{{0x3fb42edc, 0xbea646f0} },
+/**/ {{0x3c4ddd4f, 0x935996c9} },},
+/**/ {{{0x3fb51b07, 0x3f06183f} },
+/**/ {{0x3c5a49e3, 0x9a1a8be4} },},
+/**/ {{{0x3fb60658, 0xa93750c4} },
+/**/ {{0xbc538845, 0x8ec21b6a} },},
+/**/ {{{0x3fb6f0d2, 0x8ae56b4c} },
+/**/ {{0xbc5906d9, 0x9184b992} },},
+/**/ {{{0x3fb7da76, 0x6d7b12cd} },
+/**/ {{0xbc5eeedf, 0xcdd94131} },},
+/**/ {{{0x3fb8c345, 0xd6319b21} },
+/**/ {{0xbc24a697, 0xab3424a9} },},
+/**/ {{{0x3fb9ab42, 0x462033ad} },
+/**/ {{0xbc42099e, 0x1c184e8e} },},
+/**/ {{{0x3fba926d, 0x3a4ad563} },
+/**/ {{0x3c5942f4, 0x8aa70ea9} },},
+/**/ {{{0x3fbb78c8, 0x2bb0eda1} },
+/**/ {{0x3c20878c, 0xf0327e21} },},
+/**/ {{{0x3fbc5e54, 0x8f5bc743} },
+/**/ {{0x3c35d617, 0xef8161b1} },},
+/**/ {{{0x3fbd4313, 0xd66cb35d} },
+/**/ {{0x3c5790dd, 0x951d90fa} },},
+/**/ {{{0x3fbe2707, 0x6e2af2e6} },
+/**/ {{0xbc361578, 0x001e0162} },},
+/**/ {{{0x3fbf0a30, 0xc01162a6} },
+/**/ {{0x3c585f32, 0x5c5bbacd} },},
+/**/ {{{0x3fbfec91, 0x31dbeabb} },
+/**/ {{0xbc55746b, 0x9981b36c} },},
+/**/ {{{0x3fc06715, 0x12ca596e} },
+/**/ {{0x3c550c64, 0x7eb86499} },},
+/**/ {{{0x3fc0d77e, 0x7cd08e59} },
+/**/ {{0x3c69a5dc, 0x5e9030ac} },},
+/**/ {{{0x3fc14785, 0x846742ac} },
+/**/ {{0x3c6a2881, 0x3e3a7f07} },},
+/**/ {{{0x3fc1b72a, 0xd52f67a0} },
+/**/ {{0x3c548302, 0x3472cd74} },},
+/**/ {{{0x3fc2266f, 0x190a5acb} },
+/**/ {{0x3c6f547b, 0xf1809e88} },},
+/**/ {{{0x3fc29552, 0xf81ff523} },
+/**/ {{0x3c630177, 0x1c407dbf} },},
+/**/ {{{0x3fc303d7, 0x18e47fd3} },
+/**/ {{0xbc06b9c7, 0xd96091fa} },},
+/**/ {{{0x3fc371fc, 0x201e8f74} },
+/**/ {{0x3c5de6cb, 0x62af18a0} },},
+/**/ {{{0x3fc3dfc2, 0xb0ecc62a} },
+/**/ {{0xbc5ab3a8, 0xe7d81017} },},
+/**/ {{{0x3fc44d2b, 0x6ccb7d1e} },
+/**/ {{0x3c69f4f6, 0x543e1f88} },},
+/**/ {{{0x3fc4ba36, 0xf39a55e5} },
+/**/ {{0x3c668981, 0xbcc36756} },},
+/**/ {{{0x3fc526e5, 0xe3a1b438} },
+/**/ {{0xbc6746ff, 0x8a470d3a} },},
+/**/ {{{0x3fc59338, 0xd9982086} },
+/**/ {{0xbc565d22, 0xaa8ad7cf} },},
+/**/ {{{0x3fc5ff30, 0x70a793d4} },
+/**/ {{0xbc5bc60e, 0xfafc6f6e} },},
+/**/ {{{0x3fc66acd, 0x4272ad51} },
+/**/ {{0xbc50900e, 0x4e1ea8b2} },},
+/**/ {{{0x3fc6d60f, 0xe719d21d} },
+/**/ {{0xbc6caae2, 0x68ecd179} },},
+/**/ {{{0x3fc740f8, 0xf54037a5} },
+/**/ {{0xbc5b2640, 0x62a84cdb} },},
+/**/ {{{0x3fc7ab89, 0x0210d909} },
+/**/ {{0x3c4be36b, 0x2d6a0608} },},
+/**/ {{{0x3fc815c0, 0xa14357eb} },
+/**/ {{0xbc54be48, 0x073a0564} },},
+/**/ {{{0x3fc87fa0, 0x6520c911} },
+/**/ {{0xbc6bf7fd, 0xbfa08d9a} },},
+/**/ {{{0x3fc8e928, 0xde886d41} },
+/**/ {{0xbc6569d8, 0x51a56770} },},
+/**/ {{{0x3fc9525a, 0x9cf456b4} },
+/**/ {{0x3c6d904c, 0x1d4e2e26} },},
+/**/ {{{0x3fc9bb36, 0x2e7dfb83} },
+/**/ {{0x3c6575e3, 0x1f003e0c} },},
+/**/ {{{0x3fca23bc, 0x1fe2b563} },
+/**/ {{0x3c493711, 0xb07a998c} },},
+/**/ {{{0x3fca8bec, 0xfc882f19} },
+/**/ {{0xbc5e8c37, 0x918c39eb} },},
+/**/ {{{0x3fcaf3c9, 0x4e80bff3} },
+/**/ {{0xbc5398cf, 0xf3641985} },},
+/**/ {{{0x3fcb5b51, 0x9e8fb5a4} },
+/**/ {{0x3c6ba27f, 0xdc19e1a0} },},
+/**/ {{{0x3fcbc286, 0x742d8cd6} },
+/**/ {{0x3c54fce7, 0x44870f55} },},
+/**/ {{{0x3fcc2968, 0x558c18c1} },
+/**/ {{0xbc673dee, 0x38a3fb6b} },},
+/**/ {{{0x3fcc8ff7, 0xc79a9a22} },
+/**/ {{0xbc64f689, 0xf8434012} },},
+/**/ {{{0x3fccf635, 0x4e09c5dc} },
+/**/ {{0x3c6239a0, 0x7d55b695} },},
+/**/ {{{0x3fcd5c21, 0x6b4fbb91} },
+/**/ {{0x3c66e443, 0x597e4d40} },},
+/**/ {{{0x3fcdc1bc, 0xa0abec7d} },
+/**/ {{0x3c6834c5, 0x1998b6fc} },},
+/**/ {{{0x3fce2707, 0x6e2af2e6} },
+/**/ {{0xbc461578, 0x001e0162} },},
+/**/ {{{0x3fce8c02, 0x52aa5a60} },
+/**/ {{0xbc46e03a, 0x39bfc89b} },},
+/**/ {{{0x3fcef0ad, 0xcbdc5936} },
+/**/ {{0x3c648637, 0x950dc20d} },},
+/**/ {{{0x3fcf550a, 0x564b7b37} },
+/**/ {{0x3c2c5f6d, 0xfd018c37} },},
+/**/ {{{0x3fcfb918, 0x6d5e3e2b} },
+/**/ {{0xbc6caaae, 0x64f21acb} },},
+/**/ {{{0x3fd00e6c, 0x45ad501d} },
+/**/ {{0xbc6cb956, 0x8ff6fead} },},
+/**/ {{{0x3fd04025, 0x94b4d041} },
+/**/ {{0xbc628ec2, 0x17a5022d} },},
+/**/ {{{0x3fd071b8, 0x5fcd590d} },
+/**/ {{0x3c5d1707, 0xf97bde80} },},
+/**/ {{{0x3fd0a324, 0xe27390e3} },
+/**/ {{0x3c77dcfd, 0xe8061c03} },},
+/**/ {{{0x3fd0d46b, 0x579ab74b} },
+/**/ {{0x3c603ec8, 0x1c3cbd92} },},
+/**/ {{{0x3fd1058b, 0xf9ae4ad5} },
+/**/ {{0x3c589fa0, 0xab4cb31d} },},
+/**/ {{{0x3fd13687, 0x0293a8b0} },
+/**/ {{0x3c77b662, 0x98edd24a} },},
+/**/ {{{0x3fd1675c, 0xababa60e} },
+/**/ {{0x3c2ce63e, 0xab883717} },},
+/**/ {{{0x3fd1980d, 0x2dd4236f} },
+/**/ {{0x3c79d3d1, 0xb0e4d147} },},
+/**/ {{{0x3fd1c898, 0xc16999fb} },
+/**/ {{0xbc30e5c6, 0x2aff1c44} },},
+/**/ {{{0x3fd1f8ff, 0x9e48a2f3} },
+/**/ {{0xbc7c9fdf, 0x9a0c4b07} },},
+/**/ {{{0x3fd22941, 0xfbcf7966} },
+/**/ {{0xbc776f5e, 0xb09628af} },},
+/**/ {{{0x3fd25960, 0x10df763a} },
+/**/ {{0xbc50f76c, 0x57075e9e} },},
+/**/ {{{0x3fd2895a, 0x13de86a3} },
+/**/ {{0x3c77ad24, 0xc13f040e} },},
+/**/ {{{0x3fd2b930, 0x3ab89d25} },
+/**/ {{0xbc7896b5, 0xfd852ad4} },},
+/**/ {{{0x3fd2e8e2, 0xbae11d31} },
+/**/ {{0xbc78f4cd, 0xb95ebdf9} },},
+/**/ {{{0x3fd31871, 0xc9544185} },
+/**/ {{0xbc351acc, 0x4c09b379} },},
+/**/ {{{0x3fd347dd, 0x9a987d55} },
+/**/ {{0xbc64dd4c, 0x580919f8} },},
+/**/ {{{0x3fd37726, 0x62bfd85b} },
+/**/ {{0xbc4b5629, 0xd8117de7} },},
+/**/ {{{0x3fd3a64c, 0x556945ea} },
+/**/ {{0xbc6c6865, 0x1945f97c} },},
+/**/ {{{0x3fd3d54f, 0xa5c1f710} },
+/**/ {{0xbc7e3265, 0xc6a1c98d} },},
+/**/ {{{0x3fd40430, 0x8686a7e4} },
+/**/ {{0xbc70bcfb, 0x6082ce6d} },},
+/**/ {{{0x3fd432ef, 0x2a04e814} },
+/**/ {{0xbc729931, 0x715ac903} },},
+/**/ {{{0x3fd4618b, 0xc21c5ec2} },
+/**/ {{0x3c7f42de, 0xcdeccf1d} },},
+/**/ {{{0x3fd49006, 0x804009d1} },
+/**/ {{0xbc69ffc3, 0x41f177dc} },},
+/**/ {{{0x3fd4be5f, 0x957778a1} },
+/**/ {{0xbc6259b3, 0x5b04813d} },},
+/**/ {{{0x3fd4ec97, 0x3260026a} },
+/**/ {{0xbc742a87, 0xd977dc5e} },},
+/**/ {{{0x3fd51aad, 0x872df82d} },
+/**/ {{0x3c43927a, 0xc19f55e3} },},
+/**/ {{{0x3fd548a2, 0xc3add263} },
+/**/ {{0xbc6819cf, 0x7e308ddb} },},
+/**/ {{{0x3fd57677, 0x17455a6c} },
+/**/ {{0x3c7526ad, 0xb283660c} },},
+/**/ {{{0x3fd5a42a, 0xb0f4cfe2} },
+/**/ {{0xbc78ebcb, 0x7dee9a3d} },},
+/**/ {{{0x3fd5d1bd, 0xbf5809ca} },
+/**/ {{0x3c742363, 0x83dc7fe1} },},
+/**/ {{{0x3fd5ff30, 0x70a793d4} },
+/**/ {{0xbc6bc60e, 0xfafc6f6e} },},
+/**/ {{{0x3fd62c82, 0xf2b9c795} },
+/**/ {{0x3c67b7af, 0x915300e5} },},
+ };
+
+ static const number
+ Lv[362][2] = { /* log(vj) */
+
+/**/ {{{0xbf6687ec, 0xb72daabf} },
+/**/ {{0x3c052c69, 0x0f13318f} },},
+/**/ {{{0xbf6667d6, 0x3767104f} },
+/**/ {{0x3bd3efa3, 0xd27a7bac} },},
+/**/ {{{0xbf6647bf, 0xd7cd64fb} },
+/**/ {{0x3c09b725, 0x55a89c36} },},
+/**/ {{{0xbf6627a9, 0x9860683b} },
+/**/ {{0x3bcbae22, 0xfebc844a} },},
+/**/ {{{0xbf660793, 0x791fd98a} },
+/**/ {{0xbbfe34af, 0x78fa1cb5} },},
+/**/ {{{0xbf65e77d, 0x7a0b7863} },
+/**/ {{0xbc02f1b1, 0xea78fdd0} },},
+/**/ {{{0xbf65c767, 0x9b230442} },
+/**/ {{0x3bf70d8c, 0x2202b2ca} },},
+/**/ {{{0xbf65a751, 0xdc663ca2} },
+/**/ {{0xbbfdc63d, 0xc3444e64} },},
+/**/ {{{0xbf65873c, 0x3dd4e102} },
+/**/ {{0x3c021b11, 0x370d69c3} },},
+/**/ {{{0xbf656726, 0xbf6eb0de} },
+/**/ {{0xbbfb6da8, 0x154dd8d8} },},
+/**/ {{{0xbf654711, 0x61336bb6} },
+/**/ {{0xbc0b12d2, 0xdf9a4709} },},
+/**/ {{{0xbf6526fc, 0x2322d10a} },
+/**/ {{0x3bf997f2, 0x68d1274f} },},
+/**/ {{{0xbf6506e7, 0x053ca059} },
+/**/ {{0x3c0c2a1f, 0xe70c852a} },},
+/**/ {{{0xbf64e6d2, 0x07809924} },
+/**/ {{0x3c04cc9e, 0xa808538f} },},
+/**/ {{{0xbf64c6bd, 0x29ee7aed} },
+/**/ {{0x3befe68c, 0x7797a4bd} },},
+/**/ {{{0xbf64a6a8, 0x6c860537} },
+/**/ {{0x3c06794d, 0x9efaae3d} },},
+/**/ {{{0xbf648693, 0xcf46f784} },
+/**/ {{0xbbfed318, 0xb2ddd9d1} },},
+/**/ {{{0xbf64667f, 0x5231115a} },
+/**/ {{0x3c061f62, 0x4643624b} },},
+/**/ {{{0xbf64466a, 0xf544123c} },
+/**/ {{0x3c0666a0, 0x9387f11e} },},
+/**/ {{{0xbf642656, 0xb87fb9b0} },
+/**/ {{0x3c0043b2, 0x116ec598} },},
+/**/ {{{0xbf640642, 0x9be3c73c} },
+/**/ {{0xbbfbd84d, 0xd2de6e3e} },},
+/**/ {{{0xbf63e62e, 0x9f6ffa68} },
+/**/ {{0xbbe9149b, 0x433d8c65} },},
+/**/ {{{0xbf63c61a, 0xc32412bb} },
+/**/ {{0xbbf6b88d, 0x08e5a7bb} },},
+/**/ {{{0xbf63a607, 0x06ffcfbe} },
+/**/ {{0xbb9f3c7a, 0xccfac9e2} },},
+/**/ {{{0xbf6385f3, 0x6b02f0fa} },
+/**/ {{0x3bee405c, 0xbec6f6e4} },},
+/**/ {{{0xbf6365df, 0xef2d35f9} },
+/**/ {{0x3bf02993, 0xaf0c0b4c} },},
+/**/ {{{0xbf6345cc, 0x937e5e46} },
+/**/ {{0x3bf9be97, 0xaa64716f} },},
+/**/ {{{0xbf6325b9, 0x57f6296c} },
+/**/ {{0xbbfdeb4d, 0xa2e863ae} },},
+/**/ {{{0xbf6305a6, 0x3c9456f9} },
+/**/ {{0x3c0f3c7f, 0x636d2b2c} },},
+/**/ {{{0xbf62e593, 0x4158a678} },
+/**/ {{0x3c01a8df, 0xb166ca7f} },},
+/**/ {{{0xbf62c580, 0x6642d778} },
+/**/ {{0x3c020ff1, 0x53a2d534} },},
+/**/ {{{0xbf62a56d, 0xab52a987} },
+/**/ {{0xbbe8fef1, 0x0412f1e7} },},
+/**/ {{{0xbf62855b, 0x1087dc35} },
+/**/ {{0xbbfcd17e, 0x4b7ac6c6} },},
+/**/ {{{0xbf626548, 0x95e22f12} },
+/**/ {{0xbbfbfc21, 0x9a8127bf} },},
+/**/ {{{0xbf624536, 0x3b6161af} },
+/**/ {{0x3bd7eda1, 0x66d42390} },},
+/**/ {{{0xbf622524, 0x0105339d} },
+/**/ {{0xbbdf374e, 0x77fedcad} },},
+/**/ {{{0xbf620511, 0xe6cd646f} },
+/**/ {{0x3be1d1fb, 0x52d05dea} },},
+/**/ {{{0xbf61e4ff, 0xecb9b3b8} },
+/**/ {{0x3c02c2fc, 0xffd8e706} },},
+/**/ {{{0xbf61c4ee, 0x12c9e10b} },
+/**/ {{0xbc02b4f8, 0xf1d5cc2c} },},
+/**/ {{{0xbf61a4dc, 0x58fdabfe} },
+/**/ {{0xbc0618c3, 0x1315b191} },},
+/**/ {{{0xbf6184ca, 0xbf54d426} },
+/**/ {{0xbc01f8d5, 0xcb3cdab0} },},
+/**/ {{{0xbf6164b9, 0x45cf1919} },
+/**/ {{0xbc014ff7, 0xc025605a} },},
+/**/ {{{0xbf6144a7, 0xec6c3a6e} },
+/**/ {{0xbbff04ff, 0x87cb08cd} },},
+/**/ {{{0xbf612496, 0xb32bf7bd} },
+/**/ {{0x3bee89b4, 0xe6af1b84} },},
+/**/ {{{0xbf610485, 0x9a0e109e} },
+/**/ {{0x3c07e99e, 0x35a60879} },},
+/**/ {{{0xbf60e474, 0xa11244aa} },
+/**/ {{0x3c04b698, 0x20f2325a} },},
+/**/ {{{0xbf60c463, 0xc838537b} },
+/**/ {{0x3bc0657e, 0x3617200d} },},
+/**/ {{{0xbf60a453, 0x0f7ffcac} },
+/**/ {{0xbc008feb, 0xa5080961} },},
+/**/ {{{0xbf608442, 0x76e8ffd9} },
+/**/ {{0x3bd13002, 0xbb5e1df7} },},
+/**/ {{{0xbf606431, 0xfe731c9d} },
+/**/ {{0xbc0509f3, 0x6e2858c0} },},
+/**/ {{{0xbf604421, 0xa61e1296} },
+/**/ {{0xbc04b556, 0x5f5d9695} },},
+/**/ {{{0xbf602411, 0x6de9a162} },
+/**/ {{0x3c042b89, 0xe79a4e00} },},
+/**/ {{{0xbf600401, 0x55d5889e} },
+/**/ {{0x3be8f98e, 0x1113f403} },},
+/**/ {{{0xbf5fc7e2, 0xbbc30fd4} },
+/**/ {{0xbbfc709b, 0x93382bc9} },},
+/**/ {{{0xbf5f87c3, 0x0c1abdcd} },
+/**/ {{0xbbf2a90d, 0x76a55d1c} },},
+/**/ {{{0xbf5f47a3, 0x9cb19a68} },
+/**/ {{0x3be1b815, 0x76e7826b} },},
+/**/ {{{0xbf5f0784, 0x6d8724e7} },
+/**/ {{0xbbe72d46, 0x2b63756d} },},
+/**/ {{{0xbf5ec765, 0x7e9adc90} },
+/**/ {{0x3beb1a66, 0x73bb17c5} },},
+/**/ {{{0xbf5e8746, 0xcfec40a8} },
+/**/ {{0x3bf11af5, 0xb5e5a553} },},
+/**/ {{{0xbf5e4728, 0x617ad077} },
+/**/ {{0x3bfb2cad, 0xf57dd14f} },},
+/**/ {{{0xbf5e070a, 0x33460b45} },
+/**/ {{0xbbf8db75, 0x4902c8d5} },},
+/**/ {{{0xbf5dc6ec, 0x454d705f} },
+/**/ {{0x3bef5cc6, 0xe8a41057} },},
+/**/ {{{0xbf5d86ce, 0x97907f0f} },
+/**/ {{0x3bed8277, 0xdf8672ef} },},
+/**/ {{{0xbf5d46b1, 0x2a0eb6a3} },
+/**/ {{0xbbc2f9c2, 0x3717e5ee} },},
+/**/ {{{0xbf5d0693, 0xfcc7966b} },
+/**/ {{0x3bf4deed, 0xab4852c6} },},
+/**/ {{{0xbf5cc677, 0x0fba9db6} },
+/**/ {{0xbbf3a2b4, 0x9db2a368} },},
+/**/ {{{0xbf5c865a, 0x62e74bd8} },
+/**/ {{0xbbd2c51d, 0x58fa0c24} },},
+/**/ {{{0xbf5c463d, 0xf64d2024} },
+/**/ {{0x3bf838ca, 0xe3a09391} },},
+/**/ {{{0xbf5c0621, 0xc9eb99ee} },
+/**/ {{0xbbdc2a9e, 0x61b7de71} },},
+/**/ {{{0xbf5bc605, 0xddc2388e} },
+/**/ {{0xbbea9808, 0x4accb195} },},
+/**/ {{{0xbf5b85ea, 0x31d07b5c} },
+/**/ {{0xbbd811a2, 0x032e030b} },},
+/**/ {{{0xbf5b45ce, 0xc615e1b1} },
+/**/ {{0xbbfd5427, 0x821e0b81} },},
+/**/ {{{0xbf5b05b3, 0x9a91eaea} },
+/**/ {{0x3bfffeba, 0x2619306b} },},
+/**/ {{{0xbf5ac598, 0xaf441661} },
+/**/ {{0x3bd22824, 0x9eac7d15} },},
+/**/ {{{0xbf5a857e, 0x042be376} },
+/**/ {{0x3bc20736, 0x24893f0e} },},
+/**/ {{{0xbf5a4563, 0x9948d188} },
+/**/ {{0xbbf58ab4, 0x04d734cd} },},
+/**/ {{{0xbf5a0549, 0x6e9a5ff9} },
+/**/ {{0xbbf22673, 0x5723a6c3} },},
+/**/ {{{0xbf59c52f, 0x84200e2c} },
+/**/ {{0x3bfc81da, 0xa538e8e1} },},
+/**/ {{{0xbf598515, 0xd9d95b83} },
+/**/ {{0xbbfa1a37, 0x2a8e3feb} },},
+/**/ {{{0xbf5944fc, 0x6fc5c767} },
+/**/ {{0x3bf8e1ce, 0x385159f9} },},
+/**/ {{{0xbf5904e3, 0x45e4d13c} },
+/**/ {{0xbbfc4737, 0x1567c7a7} },},
+/**/ {{{0xbf58c4ca, 0x5c35f86e} },
+/**/ {{0x3bf41581, 0x23c9ae0c} },},
+/**/ {{{0xbf5884b1, 0xb2b8bc65} },
+/**/ {{0x3bf70c2c, 0x2b66cfb6} },},
+/**/ {{{0xbf584499, 0x496c9c8d} },
+/**/ {{0xbbdb9042, 0xe5a11e3e} },},
+/**/ {{{0xbf580481, 0x20511854} },
+/**/ {{0xbbf9cf9d, 0x61bcb040} },},
+/**/ {{{0xbf57c469, 0x3765af29} },
+/**/ {{0xbbf65ceb, 0xe26a419b} },},
+/**/ {{{0xbf578451, 0x8ea9e07c} },
+/**/ {{0xbbf1c2f5, 0xb70a4088} },},
+/**/ {{{0xbf57443a, 0x261d2bbf} },
+/**/ {{0xbbbc7b8f, 0x29704ba7} },},
+/**/ {{{0xbf570422, 0xfdbf1065} },
+/**/ {{0x3bca0a54, 0x433ccb3b} },},
+/**/ {{{0xbf56c40c, 0x158f0de3} },
+/**/ {{0x3bd9e257, 0x207cde2d} },},
+/**/ {{{0xbf5683f5, 0x6d8ca3af} },
+/**/ {{0xbbef17a4, 0xf7b51b49} },},
+/**/ {{{0xbf5643df, 0x05b75142} },
+/**/ {{0x3be28239, 0x9d345bf8} },},
+/**/ {{{0xbf5603c8, 0xde0e9614} },
+/**/ {{0xbbde6c21, 0x0918d1bf} },},
+/**/ {{{0xbf55c3b2, 0xf691f1a1} },
+/**/ {{0x3bd37d78, 0x377de4c8} },},
+/**/ {{{0xbf55839d, 0x4f40e365} },
+/**/ {{0x3bf52b7d, 0xbbf7c9d1} },},
+/**/ {{{0xbf554387, 0xe81aeadd} },
+/**/ {{0xbbf0be6a, 0x679c3d9a} },},
+/**/ {{{0xbf550372, 0xc11f878a} },
+/**/ {{0xbbdd9e20, 0xb6cdd88e} },},
+/**/ {{{0xbf54c35d, 0xda4e38ec} },
+/**/ {{0xbbe3b1e7, 0x09302da0} },},
+/**/ {{{0xbf548349, 0x33a67e86} },
+/**/ {{0x3be8cba8, 0x085b922d} },},
+/**/ {{{0xbf544334, 0xcd27d7db} },
+/**/ {{0xbba5f2c9, 0xf024ab43} },},
+/**/ {{{0xbf540320, 0xa6d1c471} },
+/**/ {{0xbbeb31f3, 0xf686cf3d} },},
+/**/ {{{0xbf53c30c, 0xc0a3c3cf} },
+/**/ {{0xbbf74ffe, 0xd4ad32f6} },},
+/**/ {{{0xbf5382f9, 0x1a9d557e} },
+/**/ {{0x3bd2e555, 0x4acb368f} },},
+/**/ {{{0xbf5342e5, 0xb4bdf907} },
+/**/ {{0x3be13442, 0x07812806} },},
+/**/ {{{0xbf5302d2, 0x8f052df6} },
+/**/ {{0x3bf5f429, 0x70b1e756} },},
+/**/ {{{0xbf52c2bf, 0xa97273d7} },
+/**/ {{0xbbf20aa3, 0x43a03fff} },},
+/**/ {{{0xbf5282ad, 0x04054a3a} },
+/**/ {{0xbbed4d57, 0x8bebd7ad} },},
+/**/ {{{0xbf52429a, 0x9ebd30ae} },
+/**/ {{0xbbff9529, 0x5a71c5a4} },},
+/**/ {{{0xbf520288, 0x7999a6c6} },
+/**/ {{0x3bfb055a, 0x54100f9e} },},
+/**/ {{{0xbf51c276, 0x949a2c12} },
+/**/ {{0xbbff6978, 0xa2e9f1b4} },},
+/**/ {{{0xbf518264, 0xefbe402a} },
+/**/ {{0x3bf01fb9, 0xbc188323} },},
+/**/ {{{0xbf514253, 0x8b0562a1} },
+/**/ {{0xbbf7c87c, 0x957bf23a} },},
+/**/ {{{0xbf510242, 0x666f1311} },
+/**/ {{0x3bdc2cb9, 0xc8be6880} },},
+/**/ {{{0xbf50c231, 0x81fad111} },
+/**/ {{0xbbf59fc1, 0x07ba000d} },},
+/**/ {{{0xbf508220, 0xdda81c3d} },
+/**/ {{0xbbf06a0a, 0xbf5c8a0b} },},
+/**/ {{{0xbf504210, 0x79767431} },
+/**/ {{0x3bf3a6cf, 0xa9a705bc} },},
+/**/ {{{0xbf500200, 0x55655889} },
+/**/ {{0xbbe9abe6, 0xbf0fa436} },},
+/**/ {{{0xbf4f83e0, 0xe2e891cc} },
+/**/ {{0x3be4aa59, 0x1b81bf62} },},
+/**/ {{{0xbf4f03c1, 0x9b4589ce} },
+/**/ {{0xbbe60518, 0x8a47f50a} },},
+/**/ {{{0xbf4e83a2, 0xd3e0985f} },
+/**/ {{0x3bed32d8, 0x5ef17e96} },},
+/**/ {{{0xbf4e0384, 0x8cb8bcc3} },
+/**/ {{0xbbeb7b30, 0xf09afa4d} },},
+/**/ {{{0xbf4d8366, 0xc5ccf647} },
+/**/ {{0xbbd527fc, 0xf586cec2} },},
+/**/ {{{0xbf4d0349, 0x7f1c4437} },
+/**/ {{0x3bc2bcf0, 0x4a686886} },},
+/**/ {{{0xbf4c832c, 0xb8a5a5e3} },
+/**/ {{0x3bc98f93, 0x721c2ebe} },},
+/**/ {{{0xbf4c0310, 0x72681a9e} },
+/**/ {{0xbbe20f00, 0xb5308d22} },},
+/**/ {{{0xbf4b82f4, 0xac62a1bf} },
+/**/ {{0xbbe1edd0, 0x9737b561} },},
+/**/ {{{0xbf4b02d9, 0x66943a9f} },
+/**/ {{0xbbcc950b, 0x23f894a1} },},
+/**/ {{{0xbf4a82be, 0xa0fbe49a} },
+/**/ {{0xbb81da04, 0x866bc982} },},
+/**/ {{{0xbf4a02a4, 0x5b989f0f} },
+/**/ {{0xbbd9114d, 0x9d76196e} },},
+/**/ {{{0xbf49828a, 0x96696961} },
+/**/ {{0x3bc10d20, 0xd3292fd6} },},
+/**/ {{{0xbf490271, 0x516d42f4} },
+/**/ {{0xbbee53a3, 0x2e9a5dd5} },},
+/**/ {{{0xbf488258, 0x8ca32b32} },
+/**/ {{0xbbc55af5, 0xd18f8004} },},
+/**/ {{{0xbf480240, 0x480a2185} },
+/**/ {{0xbbb32d23, 0xa9b0178a} },},
+/**/ {{{0xbf478228, 0x83a1255c} },
+/**/ {{0x3be84cc3, 0x8152093a} },},
+/**/ {{{0xbf470211, 0x3f673627} },
+/**/ {{0xbbd0055a, 0xf4881c71} },},
+/**/ {{{0xbf4681fa, 0x7b5b535c} },
+/**/ {{0x3bd2b73f, 0xb98336ea} },},
+/**/ {{{0xbf4601e4, 0x377c7c71} },
+/**/ {{0xbbcdcbed, 0x2ed05089} },},
+/**/ {{{0xbf4581ce, 0x73c9b0e1} },
+/**/ {{0xbbdda0c2, 0x61414697} },},
+/**/ {{{0xbf4501b9, 0x3041f02a} },
+/**/ {{0x3bee5d53, 0x22f8b33c} },},
+/**/ {{{0xbf4481a4, 0x6ce439ca} },
+/**/ {{0xbbe5512f, 0x9c25c999} },},
+/**/ {{{0xbf440190, 0x29af8d47} },
+/**/ {{0x3b7f48c2, 0xa4df0dfd} },},
+/**/ {{{0xbf43817c, 0x66a2ea26} },
+/**/ {{0x3bd157c0, 0x517febd8} },},
+/**/ {{{0xbf430169, 0x23bd4ff0} },
+/**/ {{0xbbe2e229, 0x0176d244} },},
+/**/ {{{0xbf428156, 0x60fdbe33} },
+/**/ {{0x3be64664, 0x175812b3} },},
+/**/ {{{0xbf420144, 0x1e63347c} },
+/**/ {{0xbbe39ab4, 0xd9355524} },},
+/**/ {{{0xbf418132, 0x5becb260} },
+/**/ {{0x3be74b27, 0xb6e1edc9} },},
+/**/ {{{0xbf410121, 0x19993772} },
+/**/ {{0xbbaa390b, 0x393ab56a} },},
+/**/ {{{0xbf408110, 0x5767c34c} },
+/**/ {{0x3bd128e6, 0xf8c7783b} },},
+/**/ {{{0xbf400100, 0x15575589} },
+/**/ {{0x3bec8863, 0xf23ef222} },},
+/**/ {{{0xbf3f01e0, 0xa6cddb8d} },
+/**/ {{0x3b8a9419, 0xcdd29c3f} },},
+/**/ {{{0xbf3e01c2, 0x232b174e} },
+/**/ {{0xbbc7cf55, 0xd5f5b191} },},
+/**/ {{{0xbf3d01a4, 0x9fc45d9e} },
+/**/ {{0x3bddc58f, 0xb5038e7e} },},
+/**/ {{{0xbf3c0188, 0x1c97adca} },
+/**/ {{0x3bc0238d, 0xbb933e41} },},
+/**/ {{{0xbf3b016c, 0x99a30728} },
+/**/ {{0xbbabde04, 0xc3c43664} },},
+/**/ {{{0xbf3a0152, 0x16e46913} },
+/**/ {{0x3bafe081, 0x5adc3673} },},
+/**/ {{{0xbf390138, 0x9459d2eb} },
+/**/ {{0xbbd949da, 0xc2a33d26} },},
+/**/ {{{0xbf380120, 0x12014418} },
+/**/ {{0xbbd3acbc, 0xf76e0326} },},
+/**/ {{{0xbf370108, 0x8fd8bc07} },
+/**/ {{0x3bdbde09, 0x4cd6ce34} },},
+/**/ {{{0xbf3600f2, 0x0dde3a29} },
+/**/ {{0xbbb0bc28, 0x05442a35} },},
+/**/ {{{0xbf3500dc, 0x8c0fbdf9} },
+/**/ {{0x3bd21c68, 0x0908cbf7} },},
+/**/ {{{0xbf3400c8, 0x0a6b46f4} },
+/**/ {{0xbbdbd35e, 0x0f107564} },},
+/**/ {{{0xbf3300b4, 0x88eed4a1} },
+/**/ {{0xbbc22067, 0x49a3dcb8} },},
+/**/ {{{0xbf3200a2, 0x0798668a} },
+/**/ {{0x3bcdb7f0, 0xe7c5d0e5} },},
+/**/ {{{0xbf310090, 0x8665fc3f} },
+/**/ {{0xbbd00add, 0xc7f9d69c} },},
+/**/ {{{0xbf300080, 0x05559559} },
+/**/ {{0x3bddd332, 0xa0e20e2f} },},
+/**/ {{{0xbf2e00e1, 0x08ca62e5} },
+/**/ {{0xbbb15ff9, 0x3a04bb77} },},
+/**/ {{{0xbf2c00c4, 0x0725a061} },
+/**/ {{0x3bc88ab0, 0xcc052f3e} },},
+/**/ {{{0xbf2a00a9, 0x05b8e275} },
+/**/ {{0xbbcbba1a, 0xf5f3cbcf} },},
+/**/ {{{0xbf280090, 0x04802882} },
+/**/ {{0x3bcec900, 0xa5bd7bd0} },},
+/**/ {{{0xbf260079, 0x037771ef} },
+/**/ {{0x3bb77ea0, 0x9b7b54fa} },},
+/**/ {{{0xbf240064, 0x029abe33} },
+/**/ {{0xbbc1bbf0, 0x3ae68d18} },},
+/**/ {{{0xbf220051, 0x01e60cd1} },
+/**/ {{0x3bb1dcd9, 0x2b45cfcd} },},
+/**/ {{{0xbf200040, 0x01555d56} },
+/**/ {{0x3bcddd88, 0x863f53f6} },},
+/**/ {{{0xbf1c0062, 0x01c95eb7} },
+/**/ {{0x3bbd88f7, 0xaa4dfd9a} },},
+/**/ {{{0xbf180048, 0x01200510} },
+/**/ {{0xbb984d46, 0x4f3db50b} },},
+/**/ {{{0xbf140032, 0x00a6ad1c} },
+/**/ {{0x3bb2e44b, 0x28ff1135} },},
+/**/ {{{0xbf100020, 0x00555655} },
+/**/ {{0xbbb62224, 0xccd5f17f} },},
+/**/ {{{0xbf080024, 0x004800a2} },
+/**/ {{0xbb484d09, 0x8d690542} },},
+/**/ {{{0xbf000010, 0x00155575} },
+/**/ {{0xbba56222, 0x37779c0a} },},
+/**/ {{{0xbef00008, 0x00055559} },
+/**/ {{0xbb955622, 0x22cccd5f} },},
+/**/ {{{0x00000000, 0x00000000} },
+/**/ {{0x00000000, 0x00000000} },},
+/**/ {{{0x3eeffff0, 0x000aaaa3} },
+/**/ {{0xbb8553bb, 0xbd110fec} },},
+/**/ {{{0x3effffe0, 0x002aaa6b} },
+/**/ {{0xbb953bbb, 0xe6661d42} },},
+/**/ {{{0x3f07ffdc, 0x0047ff5e} },
+/**/ {{0x3b484c90, 0x0d69020e} },},
+/**/ {{{0x3f0fffc0, 0x00aaa8ab} },
+/**/ {{0xbba3bbc1, 0x10fec82c} },},
+/**/ {{{0x3f13ffce, 0x00a6a83a} },
+/**/ {{0xbbb2e45f, 0x81546808} },},
+/**/ {{{0x3f17ffb8, 0x011ffaf0} },
+/**/ {{0x3b984c53, 0x4f3d9b6a} },},
+/**/ {{{0x3f1bff9e, 0x01c94bf5} },
+/**/ {{0xbbbd8990, 0xdaa368ee} },},
+/**/ {{{0x3f1fff80, 0x02aa9aab} },
+/**/ {{0x3b910e66, 0x78af0afc} },},
+/**/ {{{0x3f21ffaf, 0x01e5f330} },
+/**/ {{0xbbb1df8d, 0x26467402} },},
+/**/ {{{0x3f23ff9c, 0x029a9723} },
+/**/ {{0x3bc1b965, 0x303b23b1} },},
+/**/ {{{0x3f25ff87, 0x037738be} },
+/**/ {{0xbbb787a3, 0x53d3dc06} },},
+/**/ {{{0x3f27ff70, 0x047fd782} },
+/**/ {{0xbbced098, 0xa5c0aff0} },},
+/**/ {{{0x3f29ff57, 0x05b872e4} },
+/**/ {{0x3bcbadd4, 0x81c30d42} },},
+/**/ {{{0x3f2bff3c, 0x07250a51} },
+/**/ {{0xbbc89dd6, 0xd6bad8c1} },},
+/**/ {{{0x3f2dff1f, 0x08c99d24} },
+/**/ {{0x3bb12609, 0xaede8ad0} },},
+/**/ {{{0x3f2fff00, 0x0aaa2ab1} },
+/**/ {{0x3ba0bbc0, 0x4dc4e3dc} },},
+/**/ {{{0x3f30ff6f, 0x8665591f} },
+/**/ {{0xbbd013d3, 0x80357b54} },},
+/**/ {{{0x3f31ff5e, 0x07979982} },
+/**/ {{0xbbce0e70, 0x4817ebcd} },},
+/**/ {{{0x3f32ff4b, 0x88edd619} },
+/**/ {{0xbbd72b9e, 0xc582abc3} },},
+/**/ {{{0x3f33ff38, 0x0a6a0e74} },
+/**/ {{0x3bdb81fc, 0xb95bc1fe} },},
+/**/ {{{0x3f34ff23, 0x8c0e4220} },
+/**/ {{0x3bcaed12, 0x9b549aae} },},
+/**/ {{{0x3f35ff0e, 0x0ddc70a1} },
+/**/ {{0x3bacf6f3, 0xd97a3c05} },},
+/**/ {{{0x3f36fef7, 0x8fd69976} },
+/**/ {{0x3bab2dcf, 0x6f810a3c} },},
+/**/ {{{0x3f37fee0, 0x11febc18} },
+/**/ {{0x3bd2b9bc, 0xf5d3f323} },},
+/**/ {{{0x3f38fec7, 0x9456d7fb} },
+/**/ {{0xbbbfb258, 0x6eaa1d6a} },},
+/**/ {{{0x3f39feae, 0x16e0ec8b} },
+/**/ {{0xbbb6137a, 0xceeb34b1} },},
+/**/ {{{0x3f3afe93, 0x999ef930} },
+/**/ {{0xbbde70e0, 0xdc639b08} },},
+/**/ {{{0x3f3bfe78, 0x1c92fd4a} },
+/**/ {{0xbbc4ed10, 0x713cc126} },},
+/**/ {{{0x3f3cfe5b, 0x9fbef835} },
+/**/ {{0xbb873d63, 0xcc0e81bd} },},
+/**/ {{{0x3f3dfe3e, 0x2324e946} },
+/**/ {{0x3bc09164, 0x62dd5deb} },},
+/**/ {{{0x3f3efe1f, 0xa6c6cfcc} },
+/**/ {{0x3bdac2da, 0x3512d15c} },},
+/**/ {{{0x3f3ffe00, 0x2aa6ab11} },
+/**/ {{0x3b999e2b, 0x62cc632d} },},
+/**/ {{{0x3f407eef, 0xd7633d2c} },
+/**/ {{0xbbebc98b, 0x63ff6024} },},
+/**/ {{{0x3f40fedf, 0x19941e6e} },
+/**/ {{0xbbb194c2, 0xe0aa6338} },},
+/**/ {{{0x3f417ecd, 0xdbe6f8eb} },
+/**/ {{0x3be4241b, 0x57b0f571} },},
+/**/ {{{0x3f41febc, 0x1e5ccc3c} },
+/**/ {{0x3bdc657d, 0x895d3592} },},
+/**/ {{{0x3f427ea9, 0xe0f697f6} },
+/**/ {{0x3be35a5d, 0x1c0ec17c} },},
+/**/ {{{0x3f42fe97, 0x23b55bac} },
+/**/ {{0x3bd6cfb7, 0x3e538464} },},
+/**/ {{{0x3f437e83, 0xe69a16ed} },
+/**/ {{0x3bee96f7, 0x7cef2478} },},
+/**/ {{{0x3f43fe70, 0x29a5c947} },
+/**/ {{0xbbd4d578, 0xbf46e36a} },},
+/**/ {{{0x3f447e5b, 0xecd97242} },
+/**/ {{0xbbc9eb66, 0x3ff7dd44} },},
+/**/ {{{0x3f44fe47, 0x30361165} },
+/**/ {{0x3be400d7, 0x7e93f2fd} },},
+/**/ {{{0x3f457e31, 0xf3bca635} },
+/**/ {{0xbbe0e2a2, 0xd375017f} },},
+/**/ {{{0x3f45fe1c, 0x376e3031} },
+/**/ {{0xbbd524eb, 0x8a5ae7f6} },},
+/**/ {{{0x3f467e05, 0xfb4baed7} },
+/**/ {{0x3be204fb, 0x4e85c4e9} },},
+/**/ {{{0x3f46fdef, 0x3f5621a3} },
+/**/ {{0xbbdf09d7, 0x34886d52} },},
+/**/ {{{0x3f477dd8, 0x038e880b} },
+/**/ {{0xbbb8900e, 0x14e596a3} },},
+/**/ {{{0x3f47fdc0, 0x47f5e185} },
+/**/ {{0xbbebfa5c, 0x57d202d3} },},
+/**/ {{{0x3f487da8, 0x0c8d2d81} },
+/**/ {{0x3be2f6ae, 0xd68c0614} },},
+/**/ {{{0x3f48fd8f, 0x51556b70} },
+/**/ {{0xbbd0f4f2, 0xe08fd201} },},
+/**/ {{{0x3f497d76, 0x164f9abc} },
+/**/ {{0x3b5296b7, 0xa871af60} },},
+/**/ {{{0x3f49fd5c, 0x5b7cbace} },
+/**/ {{0x3beb6ed4, 0x9f17d42d} },},
+/**/ {{{0x3f4a7d42, 0x20ddcb0d} },
+/**/ {{0xbbcb1149, 0x67c30397} },},
+/**/ {{{0x3f4afd27, 0x6673cada} },
+/**/ {{0x3bd32225, 0x45da594f} },},
+/**/ {{{0x3f4b7d0c, 0x2c3fb996} },
+/**/ {{0xbbb68893, 0x208d4630} },},
+/**/ {{{0x3f4bfcf0, 0x7242969d} },
+/**/ {{0x3bc5db4d, 0x2b3efe1c} },},
+/**/ {{{0x3f4c7cd4, 0x387d6149} },
+/**/ {{0x3be46eff, 0xed57d98a} },},
+/**/ {{{0x3f4cfcb7, 0x7ef118f1} },
+/**/ {{0x3becc554, 0x06f300fb} },},
+/**/ {{{0x3f4d7c9a, 0x459ebce9} },
+/**/ {{0x3be1d251, 0x13638eb6} },},
+/**/ {{{0x3f4dfc7c, 0x8c874c82} },
+/**/ {{0xbbe863e9, 0xd57a176f} },},
+/**/ {{{0x3f4e7c5e, 0x53abc708} },
+/**/ {{0x3be2d95c, 0x9528e50d} },},
+/**/ {{{0x3f4efc3f, 0x9b0d2bc8} },
+/**/ {{0x3bd1e8e8, 0xa5f5b8b7} },},
+/**/ {{{0x3f4f7c20, 0x62ac7a09} },
+/**/ {{0x3b5c8123, 0x17802a46} },},
+/**/ {{{0x3f4ffc00, 0xaa8ab110} },
+/**/ {{0xbbe0fecb, 0xeb9b6cdb} },},
+/**/ {{{0x3f503df0, 0x3954680f} },
+/**/ {{0x3bdac89b, 0x1c693678} },},
+/**/ {{{0x3f507ddf, 0xdd83eb3a} },
+/**/ {{0xbbf638f6, 0x0a75ad5f} },},
+/**/ {{{0x3f50bdcf, 0x41d461a5} },
+/**/ {{0x3bfd4bc9, 0x45f05b10} },},
+/**/ {{{0x3f50fdbe, 0x66464aef} },
+/**/ {{0xbbbd0554, 0x6abbf59c} },},
+/**/ {{{0x3f513dad, 0x4ada26b1} },
+/**/ {{0x3be38c65, 0x6036fe6f} },},
+/**/ {{{0x3f517d9b, 0xef907485} },
+/**/ {{0x3bfdc8a1, 0xf158bbc3} },},
+/**/ {{{0x3f51bd8a, 0x5469b404} },
+/**/ {{0xbbdea231, 0x55632e3f} },},
+/**/ {{{0x3f51fd78, 0x796664c3} },
+/**/ {{0xbbe00849, 0x2edb73c2} },},
+/**/ {{{0x3f523d66, 0x5e870657} },
+/**/ {{0x3bfba943, 0x0789343e} },},
+/**/ {{{0x3f527d54, 0x03cc1855} },
+/**/ {{0x3bc5f644, 0xeafafc52} },},
+/**/ {{{0x3f52bd41, 0x69361a4e} },
+/**/ {{0xbbf2f743, 0xa4a6e79f} },},
+/**/ {{{0x3f52fd2e, 0x8ec58bd2} },
+/**/ {{0xbbd4f786, 0x5ceb1abf} },},
+/**/ {{{0x3f533d1b, 0x747aec71} },
+/**/ {{0xbbf369e3, 0x49dc497d} },},
+/**/ {{{0x3f537d08, 0x1a56bbb8} },
+/**/ {{0xbbfc5e6f, 0x3726b14a} },},
+/**/ {{{0x3f53bcf4, 0x80597933} },
+/**/ {{0xbbfe8b82, 0x808f75a7} },},
+/**/ {{{0x3f53fce0, 0xa683a46c} },
+/**/ {{0x3be02719, 0x9cd06ae6} },},
+/**/ {{{0x3f543ccc, 0x8cd5bced} },
+/**/ {{0x3bf9f98d, 0x758f80f8} },},
+/**/ {{{0x3f547cb8, 0x3350423e} },
+/**/ {{0xbbd79c3d, 0x48401f45} },},
+/**/ {{{0x3f54bca3, 0x99f3b3e4} },
+/**/ {{0xbbf422b8, 0x2fba8948} },},
+/**/ {{{0x3f54fc8e, 0xc0c09163} },
+/**/ {{0x3bf32cc1, 0xf4044be8} },},
+/**/ {{{0x3f553c79, 0xa7b75a40} },
+/**/ {{0xbbe72cac, 0xf2249008} },},
+/**/ {{{0x3f557c64, 0x4ed88dfb} },
+/**/ {{0xbbe7183c, 0x459a204f} },},
+/**/ {{{0x3f55bc4e, 0xb624ac14} },
+/**/ {{0x3bf8aa64, 0xba26d3d7} },},
+/**/ {{{0x3f55fc38, 0xdd9c340b} },
+/**/ {{0x3bdbb2ff, 0x45fa193c} },},
+/**/ {{{0x3f563c22, 0xc53fa55c} },
+/**/ {{0x3bd67249, 0x0484397b} },},
+/**/ {{{0x3f567c0c, 0x6d0f7f83} },
+/**/ {{0xbbd183d7, 0xf1e73188} },},
+/**/ {{{0x3f56bbf5, 0xd50c41fa} },
+/**/ {{0xbbef433d, 0x4ab68187} },},
+/**/ {{{0x3f56fbde, 0xfd366c39} },
+/**/ {{0x3be796b8, 0x66e09e58} },},
+/**/ {{{0x3f573bc7, 0xe58e7db8} },
+/**/ {{0x3bf65ec5, 0x81e6e7e6} },},
+/**/ {{{0x3f577bb0, 0x8e14f5ed} },
+/**/ {{0xbbdb944d, 0xa9463a9c} },},
+/**/ {{{0x3f57bb98, 0xf6ca544b} },
+/**/ {{0xbbc396ec, 0xc5eda344} },},
+/**/ {{{0x3f57fb81, 0x1faf1845} },
+/**/ {{0x3beb9e6d, 0xbb624f97} },},
+/**/ {{{0x3f583b69, 0x08c3c14d} },
+/**/ {{0xbbe6ee13, 0xe6295bf2} },},
+/**/ {{{0x3f587b50, 0xb208ced1} },
+/**/ {{0x3bfcf1a5, 0x6ca19875} },},
+/**/ {{{0x3f58bb38, 0x1b7ec041} },
+/**/ {{0x3bf2d181, 0x07b4fc7e} },},
+/**/ {{{0x3f58fb1f, 0x45261509} },
+/**/ {{0x3bc419c5, 0x21bad336} },},
+/**/ {{{0x3f593b06, 0x2eff4c94} },
+/**/ {{0xbbdc2a4c, 0x700b305b} },},
+/**/ {{{0x3f597aec, 0xd90ae64c} },
+/**/ {{0xbbfc53d3, 0xa23f359c} },},
+/**/ {{{0x3f59bad3, 0x43496198} },
+/**/ {{0x3bf0c270, 0xaed6b50f} },},
+/**/ {{{0x3f59fab9, 0x6dbb3de1} },
+/**/ {{0xbbf11464, 0x7a8be031} },},
+/**/ {{{0x3f5a3a9f, 0x5860fa8a} },
+/**/ {{0x3beae9e7, 0x470dbe32} },},
+/**/ {{{0x3f5a7a85, 0x033b16f8} },
+/**/ {{0x3bfc4721, 0xda1f8579} },},
+/**/ {{{0x3f5aba6a, 0x6e4a128e} },
+/**/ {{0xbbf41852, 0x029258ce} },},
+/**/ {{{0x3f5afa4f, 0x998e6cab} },
+/**/ {{0xbbf28584, 0x2eb18782} },},
+/**/ {{{0x3f5b3a34, 0x8508a4af} },
+/**/ {{0xbbea7970, 0x23241a2c} },},
+/**/ {{{0x3f5b7a19, 0x30b939f8} },
+/**/ {{0xbbf1d8db, 0x600551b6} },},
+/**/ {{{0x3f5bb9fd, 0x9ca0abe2} },
+/**/ {{0xbbeaa412, 0x8c26cc71} },},
+/**/ {{{0x3f5bf9e1, 0xc8bf79c8} },
+/**/ {{0xbbe7f81b, 0x30427cfc} },},
+/**/ {{{0x3f5c39c5, 0xb5162303} },
+/**/ {{0x3bd9ec5f, 0xd1f134e1} },},
+/**/ {{{0x3f5c79a9, 0x61a526eb} },
+/**/ {{0x3bff0cb0, 0x8980e47d} },},
+/**/ {{{0x3f5cb98c, 0xce6d04d7} },
+/**/ {{0x3bf35aca, 0xe84ca4e2} },},
+/**/ {{{0x3f5cf96f, 0xfb6e3c1b} },
+/**/ {{0x3bf9b1b8, 0x1b0bd69f} },},
+/**/ {{{0x3f5d3952, 0xe8a94c0b} },
+/**/ {{0x3be21310, 0x3ce51832} },},
+/**/ {{{0x3f5d7935, 0x961eb3f8} },
+/**/ {{0x3bf90786, 0x840c58ce} },},
+/**/ {{{0x3f5db918, 0x03cef334} },
+/**/ {{0xbbfe0048, 0xf2dfb3f4} },},
+/**/ {{{0x3f5df8fa, 0x31ba890b} },
+/**/ {{0x3bfcf652, 0x3e295bec} },},
+/**/ {{{0x3f5e38dc, 0x1fe1f4ce} },
+/**/ {{0xbbfc5ebe, 0x151c9300} },},
+/**/ {{{0x3f5e78bd, 0xce45b5c6} },
+/**/ {{0xbbef2cc4, 0x8a25b9c7} },},
+/**/ {{{0x3f5eb89f, 0x3ce64b3e} },
+/**/ {{0x3bfe6d27, 0xa6fea7bd} },},
+/**/ {{{0x3f5ef880, 0x6bc43481} },
+/**/ {{0xbbf68037, 0x914a6dab} },},
+/**/ {{{0x3f5f3861, 0x5adff0d4} },
+/**/ {{0xbbf1d2f3, 0xf909e0e6} },},
+/**/ {{{0x3f5f7842, 0x0a39ff7e} },
+/**/ {{0xbbf64661, 0xff1e1f71} },},
+/**/ {{{0x3f5fb822, 0x79d2dfc3} },
+/**/ {{0xbbd76ce8, 0x5a6f9e9a} },},
+/**/ {{{0x3f5ff802, 0xa9ab10e6} },
+/**/ {{0x3bfe29e3, 0xa153e3b2} },},
+/**/ {{{0x3f601bf1, 0x4ce18915} },
+/**/ {{0xbbe57c28, 0xa3a73044} },},
+/**/ {{{0x3f603be1, 0x250db166} },
+/**/ {{0x3c0fd271, 0xc1ad9590} },},
+/**/ {{{0x3f605bd0, 0xdd5a4107} },
+/**/ {{0x3bfe4b5d, 0xc424c676} },},
+/**/ {{{0x3f607bc0, 0x75c77796} },
+/**/ {{0xbc068804, 0xc0eff1ba} },},
+/**/ {{{0x3f609baf, 0xee5594b0} },
+/**/ {{0xbc0ff798, 0x51dbded5} },},
+/**/ {{{0x3f60bb9f, 0x4704d7f2} },
+/**/ {{0xbbf70ef4, 0x2d5aba70} },},
+/**/ {{{0x3f60db8e, 0x7fd580f9} },
+/**/ {{0xbbeccb65, 0x7ae804b5} },},
+/**/ {{{0x3f60fb7d, 0x98c7cf60} },
+/**/ {{0x3bfede2f, 0x1775134d} },},
+/**/ {{{0x3f611b6c, 0x91dc02c3} },
+/**/ {{0xbc04d41e, 0x91ca4a67} },},
+/**/ {{{0x3f613b5b, 0x6b125aba} },
+/**/ {{0x3bfe6d0c, 0x4a12201d} },},
+/**/ {{{0x3f615b4a, 0x246b16e0} },
+/**/ {{0x3bfe507d, 0x4d4238d3} },},
+/**/ {{{0x3f617b38, 0xbde676cd} },
+/**/ {{0x3bfe0272, 0x0640462a} },},
+/**/ {{{0x3f619b27, 0x3784ba19} },
+/**/ {{0x3bd94ab3, 0x02285659} },},
+/**/ {{{0x3f61bb15, 0x9146205b} },
+/**/ {{0xbbff1e2e, 0x1cc35b7b} },},
+/**/ {{{0x3f61db03, 0xcb2ae929} },
+/**/ {{0xbc03ee8e, 0x12f6bf8d} },},
+/**/ {{{0x3f61faf1, 0xe5335418} },
+/**/ {{0x3c0bae5f, 0x7b7d619b} },},
+/**/ {{{0x3f621adf, 0xdf5fa0bf} },
+/**/ {{0xbbf5546a, 0xb3b731b0} },},
+/**/ {{{0x3f623acd, 0xb9b00eb0} },
+/**/ {{0xbbafb2b0, 0x105fd253} },},
+/**/ {{{0x3f625abb, 0x7424dd7f} },
+/**/ {{0x3c011647, 0xca53444b} },},
+/**/ {{{0x3f627aa9, 0x0ebe4cbf} },
+/**/ {{0x3c01678f, 0x592f3be8} },},
+/**/ {{{0x3f629a96, 0x897c9c02} },
+/**/ {{0xbbef2b12, 0x4347451d} },},
+/**/ {{{0x3f62ba83, 0xe4600ad8} },
+/**/ {{0x3bfb5bb7, 0xb2a477bc} },},
+/**/ {{{0x3f62da71, 0x1f68d8d3} },
+/**/ {{0xbc0590e1, 0x7a5822e4} },},
+/**/ {{{0x3f62fa5e, 0x3a974581} },
+/**/ {{0xbbf0f2e5, 0x53123101} },},
+/**/ {{{0x3f631a4b, 0x35eb9072} },
+/**/ {{0xbc018db4, 0x0e3f5fde} },},
+/**/ {{{0x3f633a38, 0x1165f933} },
+/**/ {{0x3c0921d5, 0x8d0afb38} },},
+/**/ {{{0x3f635a24, 0xcd06bf53} },
+/**/ {{0x3c01f6ba, 0xb5791b80} },},
+/**/ {{{0x3f637a11, 0x68ce225e} },
+/**/ {{0x3bde2af8, 0xa1894236} },},
+/**/ {{{0x3f6399fd, 0xe4bc61e0} },
+/**/ {{0xbc062a48, 0xd0f06ff3} },},
+/**/ {{{0x3f63b9ea, 0x40d1bd63} },
+/**/ {{0x3bffc80c, 0x4b4f9c11} },},
+/**/ {{{0x3f63d9d6, 0x7d0e7473} },
+/**/ {{0x3c02219b, 0x6a92c891} },},
+/**/ {{{0x3f63f9c2, 0x9972c699} },
+/**/ {{0x3c0d3590, 0x790ade9e} },},
+/**/ {{{0x3f6419ae, 0x95fef35f} },
+/**/ {{0xbc01c279, 0x792a458c} },},
+/**/ {{{0x3f64399a, 0x72b33a4b} },
+/**/ {{0x3c02ce64, 0x327bffae} },},
+/**/ {{{0x3f645986, 0x2f8fdae7} },
+/**/ {{0xbc070aec, 0xd231155c} },},
+/**/ {{{0x3f647971, 0xcc9514b7} },
+/**/ {{0x3c0f373d, 0xe4bbf776} },},
+/**/ {{{0x3f64995d, 0x49c32744} },
+/**/ {{0xbbf6d7e5, 0xbf22b2a7} },},
+/**/ {{{0x3f64b948, 0xa71a5211} },
+/**/ {{0xbbedec69, 0x64fe2936} },},
+/**/ {{{0x3f64d933, 0xe49ad4a3} },
+/**/ {{0x3bf5fc4b, 0xabee4257} },},
+/**/ {{{0x3f64f91f, 0x0244ee7e} },
+/**/ {{0x3c0c6fe3, 0x3cd1474f} },},
+/**/ {{{0x3f65190a, 0x0018df26} },
+/**/ {{0xbc023957, 0xd11e7fa5} },},
+/**/ {{{0x3f6538f4, 0xde16e61b} },
+/**/ {{0x3c006c31, 0x55380346} },},
+/**/ {{{0x3f6558df, 0x9c3f42e1} },
+/**/ {{0xbc09b7d4, 0xc4a5134c} },},
+/**/ {{{0x3f6578ca, 0x3a9234f7} },
+/**/ {{0xbc0e3f10, 0x2772c19c} },},
+/**/ {{{0x3f6598b4, 0xb90ffbdd} },
+/**/ {{0x3be6f110, 0x5592b468} },},
+/**/ {{{0x3f65b89f, 0x17b8d714} },
+/**/ {{0xbc0a5fea, 0xb251ace2} },},
+/**/ {{{0x3f65d889, 0x568d0619} },
+/**/ {{0xbc0aacc9, 0x315da285} },},
+/**/ {{{0x3f65f873, 0x758cc86a} },
+/**/ {{0xbbeb0782, 0xba64d81a} },},
+/**/ {{{0x3f66185d, 0x74b85d85} },
+/**/ {{0xbc09b459, 0x8e1eb3fa} },},
+/**/ {{{0x3f663847, 0x541004e5} },
+/**/ {{0x3bce9c22, 0x1d86e863} },},
+/**/ {{{0x3f665831, 0x1393fe07} },
+/**/ {{0xbbfbeb77, 0xcf37ee90} },},
+/**/ {{{0x3f66781a, 0xb3448865} },
+/**/ {{0xbc02dc68, 0xc252e3c9} },},
+/**/ {{{0x3f669804, 0x3321e379} },
+/**/ {{0xbbe73a0b, 0xb40b3741} },},
+ };
+
+#else
+#ifdef LITTLE_ENDI
+ static const number
+ Iu[182] = { /* 1/ui */
+/**/ {{0xd1537290, 0x3ff6a13c} },
+/**/ {{0x16816817, 0x3ff68168} },
+/**/ {{0x6a5122f9, 0x3ff661ec} },
+/**/ {{0x590b2164, 0x3ff642c8} },
+/**/ {{0x77016240, 0x3ff623fa} },
+/**/ {{0x60581606, 0x3ff60581} },
+/**/ {{0xb8d015e7, 0x3ff5e75b} },
+/**/ {{0x2b931057, 0x3ff5c988} },
+/**/ {{0x6b015ac0, 0x3ff5ac05} },
+/**/ {{0x308158ed, 0x3ff58ed2} },
+/**/ {{0x3c506b3a, 0x3ff571ed} },
+/**/ {{0x55555555, 0x3ff55555} },
+/**/ {{0x48f40feb, 0x3ff53909} },
+/**/ {{0xeae2f815, 0x3ff51d07} },
+/**/ {{0x15015015, 0x3ff50150} },
+/**/ {{0xa72f0539, 0x3ff4e5e0} },
+/**/ {{0x8725af6e, 0x3ff4cab8} },
+/**/ {{0xa052bf5b, 0x3ff4afd6} },
+/**/ {{0xe3b2d067, 0x3ff49539} },
+/**/ {{0x47ae147b, 0x3ff47ae1} },
+/**/ {{0xc7f5cf9a, 0x3ff460cb} },
+/**/ {{0x6562d9fb, 0x3ff446f8} },
+/**/ {{0x25d51f87, 0x3ff42d66} },
+/**/ {{0x14141414, 0x3ff41414} },
+/**/ {{0x3fb013fb, 0x3ff3fb01} },
+/**/ {{0xbce4a902, 0x3ff3e22c} },
+/**/ {{0xa47babe7, 0x3ff3c995} },
+/**/ {{0x13b13b14, 0x3ff3b13b} },
+/**/ {{0x2c187f63, 0x3ff3991c} },
+/**/ {{0x13813814, 0x3ff38138} },
+/**/ {{0xf3de0748, 0x3ff3698d} },
+/**/ {{0xfb2b78c1, 0x3ff3521c} },
+/**/ {{0x5b57bcb2, 0x3ff33ae4} },
+/**/ {{0x4a2b10bf, 0x3ff323e3} },
+/**/ {{0x0130d190, 0x3ff30d19} },
+/**/ {{0xbda12f68, 0x3ff2f684} },
+/**/ {{0xc04b8097, 0x3ff2e025} },
+/**/ {{0x4d812ca0, 0x3ff2c9fb} },
+/**/ {{0xad012b40, 0x3ff2b404} },
+/**/ {{0x29e4129e, 0x3ff29e41} },
+/**/ {{0x1288b013, 0x3ff288b0} },
+/**/ {{0xb8812735, 0x3ff27350} },
+/**/ {{0x708092f1, 0x3ff25e22} },
+/**/ {{0x92492492, 0x3ff24924} },
+/**/ {{0x789abcdf, 0x3ff23456} },
+/**/ {{0x8121fb78, 0x3ff21fb7} },
+/**/ {{0x0c67c0d9, 0x3ff20b47} },
+/**/ {{0x7dc11f70, 0x3ff1f704} },
+/**/ {{0x3b3fb874, 0x3ff1e2ef} },
+/**/ {{0xada2811d, 0x3ff1cf06} },
+/**/ {{0x4046ed29, 0x3ff1bb4a} },
+/**/ {{0x611a7b96, 0x3ff1a7b9} },
+/**/ {{0x808ca29c, 0x3ff19453} },
+/**/ {{0x11811812, 0x3ff18118} },
+/**/ {{0x89427379, 0x3ff16e06} },
+/**/ {{0x5f75270d, 0x3ff15b1e} },
+/**/ {{0x0e0acd3b, 0x3ff1485f} },
+/**/ {{0x1135c811, 0x3ff135c8} },
+/**/ {{0xe75d3033, 0x3ff12358} },
+/**/ {{0x11111111, 0x3ff11111} },
+/**/ {{0x10fef011, 0x3ff0fef0} },
+/**/ {{0x6be69c90, 0x3ff0ecf5} },
+/**/ {{0xa88f4696, 0x3ff0db20} },
+/**/ {{0x4fbcda3b, 0x3ff0c971} },
+/**/ {{0xec259dc8, 0x3ff0b7e6} },
+/**/ {{0x0a6810a7, 0x3ff0a681} },
+/**/ {{0x39010954, 0x3ff0953f} },
+/**/ {{0x08421084, 0x3ff08421} },
+/**/ {{0x0a47f7c6, 0x3ff07326} },
+/**/ {{0xd2f1a9fc, 0x3ff0624d} },
+/**/ {{0xf7d73404, 0x3ff05197} },
+/**/ {{0x10410410, 0x3ff04104} },
+/**/ {{0xb51f5e1a, 0x3ff03091} },
+/**/ {{0x81020408, 0x3ff02040} },
+/**/ {{0x10101010, 0x3ff01010} },
+/**/ {{0x00000000, 0x3ff00000} },
+/**/ {{0xe01fe020, 0x3fefe01f} },
+/**/ {{0x01fc07f0, 0x3fefc07f} },
+/**/ {{0xaa01fa12, 0x3fefa11c} },
+/**/ {{0x1f81f820, 0x3fef81f8} },
+/**/ {{0xaca0dbb5, 0x3fef6310} },
+/**/ {{0x9e4a4271, 0x3fef4465} },
+/**/ {{0x44230ab5, 0x3fef25f6} },
+/**/ {{0xf07c1f08, 0x3fef07c1} },
+/**/ {{0xf8458e02, 0x3feee9c7} },
+/**/ {{0xb301ecc0, 0x3feecc07} },
+/**/ {{0x7aba01eb, 0x3feeae80} },
+/**/ {{0xabf0b767, 0x3fee9131} },
+/**/ {{0xa59750e4, 0x3fee741a} },
+/**/ {{0xc901e574, 0x3fee573a} },
+/**/ {{0x79dc1a73, 0x3fee3a91} },
+/**/ {{0x1e1e1e1e, 0x3fee1e1e} },
+/**/ {{0x1e01e01e, 0x3fee01e0} },
+/**/ {{0xe3f8868a, 0x3fede5d6} },
+/**/ {{0xdca01dca, 0x3fedca01} },
+/**/ {{0x76b981db, 0x3fedae60} },
+/**/ {{0x231e7f8a, 0x3fed92f2} },
+/**/ {{0x54b82c34, 0x3fed77b6} },
+/**/ {{0x807572b2, 0x3fed5cac} },
+/**/ {{0x1d41d41d, 0x3fed41d4} },
+/**/ {{0xa3fc5b1a, 0x3fed272c} },
+/**/ {{0x8f6ec074, 0x3fed0cb5} },
+/**/ {{0x5c44bfc6, 0x3fecf26e} },
+/**/ {{0x89039b0b, 0x3fecd856} },
+/**/ {{0x9601cbe7, 0x3fecbe6d} },
+/**/ {{0x055ee191, 0x3feca4b3} },
+/**/ {{0x5afb8a42, 0x3fec8b26} },
+/**/ {{0x1c71c71c, 0x3fec71c7} },
+/**/ {{0xd10d4986, 0x3fec5894} },
+/**/ {{0x01c3f8f0, 0x3fec3f8f} },
+/**/ {{0x392ea01c, 0x3fec26b5} },
+/**/ {{0x0381c0e0, 0x3fec0e07} },
+/**/ {{0xee868d8b, 0x3febf583} },
+/**/ {{0x899406f7, 0x3febdd2b} },
+/**/ {{0x65883e7b, 0x3febc4fd} },
+/**/ {{0x14c1bad0, 0x3febacf9} },
+/**/ {{0x2b18ff23, 0x3feb951e} },
+/**/ {{0x3dda338b, 0x3feb7d6c} },
+/**/ {{0xe3beee05, 0x3feb65e2} },
+/**/ {{0xb4e81b4f, 0x3feb4e81} },
+/**/ {{0x4ad806ce, 0x3feb3748} },
+/**/ {{0x406c80d9, 0x3feb2036} },
+/**/ {{0x31d922a4, 0x3feb094b} },
+/**/ {{0xbca1af28, 0x3feaf286} },
+/**/ {{0x7f94905e, 0x3feadbe8} },
+/**/ {{0x1ac5701b, 0x3feac570} },
+/**/ {{0x2f87ebfd, 0x3feaaf1d} },
+/**/ {{0x606a63be, 0x3fea98ef} },
+/**/ {{0x5130e159, 0x3fea82e6} },
+/**/ {{0xa6d01a6d, 0x3fea6d01} },
+/**/ {{0x07688a4a, 0x3fea5741} },
+/**/ {{0x1a41a41a, 0x3fea41a4} },
+/**/ {{0x87c51ca0, 0x3fea2c2a} },
+/**/ {{0xf97a4b02, 0x3fea16d3} },
+/**/ {{0x1a01a01a, 0x3fea01a0} },
+/**/ {{0x951033d9, 0x3fe9ec8e} },
+/**/ {{0x176b682d, 0x3fe9d79f} },
+/**/ {{0x4ee4a102, 0x3fe9c2d1} },
+/**/ {{0xea5510da, 0x3fe9ae24} },
+/**/ {{0x9999999a, 0x3fe99999} },
+/**/ {{0x0d8ec0ff, 0x3fe9852f} },
+/**/ {{0xf80cb872, 0x3fe970e4} },
+/**/ {{0x0be377ae, 0x3fe95cbb} },
+/**/ {{0xfcd6e9e0, 0x3fe948b0} },
+/**/ {{0x7f9b2ce6, 0x3fe934c6} },
+/**/ {{0x49d0e229, 0x3fe920fb} },
+/**/ {{0x120190d5, 0x3fe90d4f} },
+/**/ {{0x8f9c18fa, 0x3fe8f9c1} },
+/**/ {{0x7af1373f, 0x3fe8e652} },
+/**/ {{0x8d3018d3, 0x3fe8d301} },
+/**/ {{0x8062ff3a, 0x3fe8bfce} },
+/**/ {{0x0f6bf3aa, 0x3fe8acb9} },
+/**/ {{0xf601899c, 0x3fe899c0} },
+/**/ {{0xf0abb04a, 0x3fe886e5} },
+/**/ {{0xbcc092b9, 0x3fe87427} },
+/**/ {{0x18618618, 0x3fe86186} },
+/**/ {{0xc2780614, 0x3fe84f00} },
+/**/ {{0x7ab2bedd, 0x3fe83c97} },
+/**/ {{0x0182a4a0, 0x3fe82a4a} },
+/**/ {{0x18181818, 0x3fe81818} },
+/**/ {{0x80601806, 0x3fe80601} },
+/**/ {{0xfd017f40, 0x3fe7f405} },
+/**/ {{0x515a4f1d, 0x3fe7e225} },
+/**/ {{0x417d05f4, 0x3fe7d05f} },
+/**/ {{0x922e017c, 0x3fe7beb3} },
+/**/ {{0x08e0ecc3, 0x3fe7ad22} },
+/**/ {{0x6bb6398b, 0x3fe79baa} },
+/**/ {{0x8178a4c8, 0x3fe78a4c} },
+/**/ {{0x119ac60d, 0x3fe77908} },
+/**/ {{0xe434a9b1, 0x3fe767dc} },
+/**/ {{0xc201756d, 0x3fe756ca} },
+/**/ {{0x745d1746, 0x3fe745d1} },
+/**/ {{0xc541fe8d, 0x3fe734f0} },
+/**/ {{0x7f46debc, 0x3fe72428} },
+/**/ {{0x6d9c7c09, 0x3fe71378} },
+/**/ {{0x5c0b8170, 0x3fe702e0} },
+/**/ {{0x16f26017, 0x3fe6f260} },
+/**/ {{0x6b4337c7, 0x3fe6e1f7} },
+/**/ {{0x2681c861, 0x3fe6d1a6} },
+/**/ {{0x16c16c17, 0x3fe6c16c} },
+/**/ {{0x0aa31a3d, 0x3fe6b149} },
+/**/ {{0xd1537290, 0x3fe6a13c} },
+ };
+
+ static const number
+ Iv[362] = { /* 1/vj */
+/**/ {{0xee93bfe3, 0x3ff00b47} },
+/**/ {{0xd80c106f, 0x3ff00b37} },
+/**/ {{0xc1a4a47a, 0x3ff00b27} },
+/**/ {{0xab5d7ba2, 0x3ff00b17} },
+/**/ {{0x95369587, 0x3ff00b07} },
+/**/ {{0x7f2ff1c6, 0x3ff00af7} },
+/**/ {{0x69499000, 0x3ff00ae7} },
+/**/ {{0x53836fd3, 0x3ff00ad7} },
+/**/ {{0x3ddd90dd, 0x3ff00ac7} },
+/**/ {{0x2857f2bf, 0x3ff00ab7} },
+/**/ {{0x12f29517, 0x3ff00aa7} },
+/**/ {{0xfdad7784, 0x3ff00a96} },
+/**/ {{0xe88899a5, 0x3ff00a86} },
+/**/ {{0xd383fb19, 0x3ff00a76} },
+/**/ {{0xbe9f9b7f, 0x3ff00a66} },
+/**/ {{0xa9db7a76, 0x3ff00a56} },
+/**/ {{0x9537979d, 0x3ff00a46} },
+/**/ {{0x80b3f293, 0x3ff00a36} },
+/**/ {{0x6c508af8, 0x3ff00a26} },
+/**/ {{0x580d606a, 0x3ff00a16} },
+/**/ {{0x43ea7288, 0x3ff00a06} },
+/**/ {{0x2fe7c0f1, 0x3ff009f6} },
+/**/ {{0x1c054b44, 0x3ff009e6} },
+/**/ {{0x08431122, 0x3ff009d6} },
+/**/ {{0xf4a11227, 0x3ff009c5} },
+/**/ {{0xe11f4df4, 0x3ff009b5} },
+/**/ {{0xcdbdc428, 0x3ff009a5} },
+/**/ {{0xba7c7462, 0x3ff00995} },
+/**/ {{0xa75b5e40, 0x3ff00985} },
+/**/ {{0x945a8162, 0x3ff00975} },
+/**/ {{0x8179dd68, 0x3ff00965} },
+/**/ {{0x6eb971ef, 0x3ff00955} },
+/**/ {{0x5c193e98, 0x3ff00945} },
+/**/ {{0x49994301, 0x3ff00935} },
+/**/ {{0x37397eca, 0x3ff00925} },
+/**/ {{0x24f9f192, 0x3ff00915} },
+/**/ {{0x12da9af7, 0x3ff00905} },
+/**/ {{0x00db7a99, 0x3ff008f5} },
+/**/ {{0xeefc9018, 0x3ff008e4} },
+/**/ {{0xdd3ddb12, 0x3ff008d4} },
+/**/ {{0xcb9f5b26, 0x3ff008c4} },
+/**/ {{0xba210ff4, 0x3ff008b4} },
+/**/ {{0xa8c2f91a, 0x3ff008a4} },
+/**/ {{0x97851639, 0x3ff00894} },
+/**/ {{0x866766ef, 0x3ff00884} },
+/**/ {{0x7569eadb, 0x3ff00874} },
+/**/ {{0x648ca19d, 0x3ff00864} },
+/**/ {{0x53cf8ad3, 0x3ff00854} },
+/**/ {{0x4332a61e, 0x3ff00844} },
+/**/ {{0x32b5f31b, 0x3ff00834} },
+/**/ {{0x2259716c, 0x3ff00824} },
+/**/ {{0x121d20ad, 0x3ff00814} },
+/**/ {{0x02010080, 0x3ff00804} },
+/**/ {{0xf2051083, 0x3ff007f3} },
+/**/ {{0xe2295056, 0x3ff007e3} },
+/**/ {{0xd26dbf97, 0x3ff007d3} },
+/**/ {{0xc2d25de5, 0x3ff007c3} },
+/**/ {{0xb3572ae2, 0x3ff007b3} },
+/**/ {{0xa3fc262a, 0x3ff007a3} },
+/**/ {{0x94c14f5f, 0x3ff00793} },
+/**/ {{0x85a6a61e, 0x3ff00783} },
+/**/ {{0x76ac2a08, 0x3ff00773} },
+/**/ {{0x67d1dabb, 0x3ff00763} },
+/**/ {{0x5917b7d7, 0x3ff00753} },
+/**/ {{0x4a7dc0fb, 0x3ff00743} },
+/**/ {{0x3c03f5c7, 0x3ff00733} },
+/**/ {{0x2daa55da, 0x3ff00723} },
+/**/ {{0x1f70e0d3, 0x3ff00713} },
+/**/ {{0x11579652, 0x3ff00703} },
+/**/ {{0x035e75f5, 0x3ff006f3} },
+/**/ {{0xf5857f5d, 0x3ff006e2} },
+/**/ {{0xe7ccb228, 0x3ff006d2} },
+/**/ {{0xda340df6, 0x3ff006c2} },
+/**/ {{0xccbb9266, 0x3ff006b2} },
+/**/ {{0xbf633f18, 0x3ff006a2} },
+/**/ {{0xb22b13ab, 0x3ff00692} },
+/**/ {{0xa5130fbe, 0x3ff00682} },
+/**/ {{0x981b32f1, 0x3ff00672} },
+/**/ {{0x8b437ce4, 0x3ff00662} },
+/**/ {{0x7e8bed35, 0x3ff00652} },
+/**/ {{0x71f48383, 0x3ff00642} },
+/**/ {{0x657d3f70, 0x3ff00632} },
+/**/ {{0x59262098, 0x3ff00622} },
+/**/ {{0x4cef269e, 0x3ff00612} },
+/**/ {{0x40d8511e, 0x3ff00602} },
+/**/ {{0x34e19fba, 0x3ff005f2} },
+/**/ {{0x290b1211, 0x3ff005e2} },
+/**/ {{0x1d54a7c1, 0x3ff005d2} },
+/**/ {{0x11be606b, 0x3ff005c2} },
+/**/ {{0x06483bad, 0x3ff005b2} },
+/**/ {{0xfaf23928, 0x3ff005a1} },
+/**/ {{0xefbc587b, 0x3ff00591} },
+/**/ {{0xe4a69945, 0x3ff00581} },
+/**/ {{0xd9b0fb25, 0x3ff00571} },
+/**/ {{0xcedb7dbc, 0x3ff00561} },
+/**/ {{0xc42620a9, 0x3ff00551} },
+/**/ {{0xb990e38b, 0x3ff00541} },
+/**/ {{0xaf1bc601, 0x3ff00531} },
+/**/ {{0xa4c6c7ac, 0x3ff00521} },
+/**/ {{0x9a91e82a, 0x3ff00511} },
+/**/ {{0x907d271c, 0x3ff00501} },
+/**/ {{0x86888421, 0x3ff004f1} },
+/**/ {{0x7cb3fed8, 0x3ff004e1} },
+/**/ {{0x72ff96e0, 0x3ff004d1} },
+/**/ {{0x696b4bdb, 0x3ff004c1} },
+/**/ {{0x5ff71d66, 0x3ff004b1} },
+/**/ {{0x56a30b21, 0x3ff004a1} },
+/**/ {{0x4d6f14ad, 0x3ff00491} },
+/**/ {{0x445b39a8, 0x3ff00481} },
+/**/ {{0x3b6779b3, 0x3ff00471} },
+/**/ {{0x3293d46c, 0x3ff00461} },
+/**/ {{0x29e04974, 0x3ff00451} },
+/**/ {{0x214cd869, 0x3ff00441} },
+/**/ {{0x18d980ed, 0x3ff00431} },
+/**/ {{0x1086429d, 0x3ff00421} },
+/**/ {{0x08531d1a, 0x3ff00411} },
+/**/ {{0x00401004, 0x3ff00401} },
+/**/ {{0xf84d1afa, 0x3ff003f0} },
+/**/ {{0xf07a3d9b, 0x3ff003e0} },
+/**/ {{0xe8c77787, 0x3ff003d0} },
+/**/ {{0xe134c85f, 0x3ff003c0} },
+/**/ {{0xd9c22fc1, 0x3ff003b0} },
+/**/ {{0xd26fad4d, 0x3ff003a0} },
+/**/ {{0xcb3d40a3, 0x3ff00390} },
+/**/ {{0xc42ae963, 0x3ff00380} },
+/**/ {{0xbd38a72c, 0x3ff00370} },
+/**/ {{0xb666799e, 0x3ff00360} },
+/**/ {{0xafb46058, 0x3ff00350} },
+/**/ {{0xa9225afa, 0x3ff00340} },
+/**/ {{0xa2b06925, 0x3ff00330} },
+/**/ {{0x9c5e8a77, 0x3ff00320} },
+/**/ {{0x962cbe90, 0x3ff00310} },
+/**/ {{0x901b0511, 0x3ff00300} },
+/**/ {{0x8a295d98, 0x3ff002f0} },
+/**/ {{0x8457c7c6, 0x3ff002e0} },
+/**/ {{0x7ea6433a, 0x3ff002d0} },
+/**/ {{0x7914cf94, 0x3ff002c0} },
+/**/ {{0x73a36c73, 0x3ff002b0} },
+/**/ {{0x6e521978, 0x3ff002a0} },
+/**/ {{0x6920d642, 0x3ff00290} },
+/**/ {{0x640fa271, 0x3ff00280} },
+/**/ {{0x5f1e7da5, 0x3ff00270} },
+/**/ {{0x5a4d677d, 0x3ff00260} },
+/**/ {{0x559c5f9a, 0x3ff00250} },
+/**/ {{0x510b659a, 0x3ff00240} },
+/**/ {{0x4c9a791f, 0x3ff00230} },
+/**/ {{0x484999c6, 0x3ff00220} },
+/**/ {{0x4418c732, 0x3ff00210} },
+/**/ {{0x40080100, 0x3ff00200} },
+/**/ {{0x3c1746d2, 0x3ff001f0} },
+/**/ {{0x38469846, 0x3ff001e0} },
+/**/ {{0x3495f4fd, 0x3ff001d0} },
+/**/ {{0x31055c96, 0x3ff001c0} },
+/**/ {{0x2d94ceb2, 0x3ff001b0} },
+/**/ {{0x2a444af0, 0x3ff001a0} },
+/**/ {{0x2713d0ef, 0x3ff00190} },
+/**/ {{0x24036051, 0x3ff00180} },
+/**/ {{0x2112f8b4, 0x3ff00170} },
+/**/ {{0x1e4299b9, 0x3ff00160} },
+/**/ {{0x1b9242ff, 0x3ff00150} },
+/**/ {{0x1901f427, 0x3ff00140} },
+/**/ {{0x1691acd0, 0x3ff00130} },
+/**/ {{0x14416c9a, 0x3ff00120} },
+/**/ {{0x12113324, 0x3ff00110} },
+/**/ {{0x10010010, 0x3ff00100} },
+/**/ {{0x0e10d2fc, 0x3ff000f0} },
+/**/ {{0x0c40ab89, 0x3ff000e0} },
+/**/ {{0x0a908957, 0x3ff000d0} },
+/**/ {{0x09006c05, 0x3ff000c0} },
+/**/ {{0x07905334, 0x3ff000b0} },
+/**/ {{0x06403e82, 0x3ff000a0} },
+/**/ {{0x05102d92, 0x3ff00090} },
+/**/ {{0x04002001, 0x3ff00080} },
+/**/ {{0x03101571, 0x3ff00070} },
+/**/ {{0x02400d80, 0x3ff00060} },
+/**/ {{0x019007d0, 0x3ff00050} },
+/**/ {{0x01000400, 0x3ff00040} },
+/**/ {{0x009001b0, 0x3ff00030} },
+/**/ {{0x00400080, 0x3ff00020} },
+/**/ {{0x00100010, 0x3ff00010} },
+/**/ {{0x00000000, 0x3ff00000} },
+/**/ {{0x001fffe0, 0x3fefffe0} },
+/**/ {{0x007fff00, 0x3fefffc0} },
+/**/ {{0x011ffca0, 0x3fefffa0} },
+/**/ {{0x01fff800, 0x3fefff80} },
+/**/ {{0x031ff060, 0x3fefff60} },
+/**/ {{0x047fe501, 0x3fefff40} },
+/**/ {{0x061fd521, 0x3fefff20} },
+/**/ {{0x07ffc002, 0x3fefff00} },
+/**/ {{0x0a1fa4e3, 0x3feffee0} },
+/**/ {{0x0c7f8305, 0x3feffec0} },
+/**/ {{0x0f1f59a7, 0x3feffea0} },
+/**/ {{0x11ff280a, 0x3feffe80} },
+/**/ {{0x151eed6e, 0x3feffe60} },
+/**/ {{0x187ea913, 0x3feffe40} },
+/**/ {{0x1c1e5a39, 0x3feffe20} },
+/**/ {{0x1ffe0020, 0x3feffe00} },
+/**/ {{0x241d9a09, 0x3feffde0} },
+/**/ {{0x287d2733, 0x3feffdc0} },
+/**/ {{0x2d1ca6e0, 0x3feffda0} },
+/**/ {{0x31fc184e, 0x3feffd80} },
+/**/ {{0x371b7abf, 0x3feffd60} },
+/**/ {{0x3c7acd72, 0x3feffd40} },
+/**/ {{0x421a0fa9, 0x3feffd20} },
+/**/ {{0x47f940a2, 0x3feffd00} },
+/**/ {{0x4e185f9f, 0x3feffce0} },
+/**/ {{0x54776bdf, 0x3feffcc0} },
+/**/ {{0x5b1664a3, 0x3feffca0} },
+/**/ {{0x61f5492c, 0x3feffc80} },
+/**/ {{0x691418b9, 0x3feffc60} },
+/**/ {{0x7072d28b, 0x3feffc40} },
+/**/ {{0x781175e3, 0x3feffc20} },
+/**/ {{0x7ff00200, 0x3feffc00} },
+/**/ {{0x880e7623, 0x3feffbe0} },
+/**/ {{0x906cd18c, 0x3feffbc0} },
+/**/ {{0x990b137c, 0x3feffba0} },
+/**/ {{0xa1e93b34, 0x3feffb80} },
+/**/ {{0xab0747f3, 0x3feffb60} },
+/**/ {{0xb46538fa, 0x3feffb40} },
+/**/ {{0xbe030d89, 0x3feffb20} },
+/**/ {{0xc7e0c4e1, 0x3feffb00} },
+/**/ {{0xd1fe5e43, 0x3feffae0} },
+/**/ {{0xdc5bd8ee, 0x3feffac0} },
+/**/ {{0xe6f93424, 0x3feffaa0} },
+/**/ {{0xf1d66f25, 0x3feffa80} },
+/**/ {{0xfcf38931, 0x3feffa60} },
+/**/ {{0x08508189, 0x3feffa41} },
+/**/ {{0x13ed576d, 0x3feffa21} },
+/**/ {{0x1fca0a1e, 0x3feffa01} },
+/**/ {{0x2be698dd, 0x3feff9e1} },
+/**/ {{0x384302e9, 0x3feff9c1} },
+/**/ {{0x44df4785, 0x3feff9a1} },
+/**/ {{0x51bb65ef, 0x3feff981} },
+/**/ {{0x5ed75d6a, 0x3feff961} },
+/**/ {{0x6c332d34, 0x3feff941} },
+/**/ {{0x79ced490, 0x3feff921} },
+/**/ {{0x87aa52be, 0x3feff901} },
+/**/ {{0x95c5a6fe, 0x3feff8e1} },
+/**/ {{0xa420d091, 0x3feff8c1} },
+/**/ {{0xb2bbceb7, 0x3feff8a1} },
+/**/ {{0xc196a0b2, 0x3feff881} },
+/**/ {{0xd0b145c2, 0x3feff861} },
+/**/ {{0xe00bbd28, 0x3feff841} },
+/**/ {{0xefa60624, 0x3feff821} },
+/**/ {{0xff801ff8, 0x3feff801} },
+/**/ {{0x0f9a09e3, 0x3feff7e2} },
+/**/ {{0x1ff3c328, 0x3feff7c2} },
+/**/ {{0x308d4b05, 0x3feff7a2} },
+/**/ {{0x4166a0bd, 0x3feff782} },
+/**/ {{0x527fc390, 0x3feff762} },
+/**/ {{0x63d8b2bf, 0x3feff742} },
+/**/ {{0x75716d8b, 0x3feff722} },
+/**/ {{0x8749f334, 0x3feff702} },
+/**/ {{0x996242fb, 0x3feff6e2} },
+/**/ {{0xabba5c21, 0x3feff6c2} },
+/**/ {{0xbe523de8, 0x3feff6a2} },
+/**/ {{0xd129e78f, 0x3feff682} },
+/**/ {{0xe4415858, 0x3feff662} },
+/**/ {{0xf7988f84, 0x3feff642} },
+/**/ {{0x0b2f8c54, 0x3feff623} },
+/**/ {{0x1f064e08, 0x3feff603} },
+/**/ {{0x331cd3e1, 0x3feff5e3} },
+/**/ {{0x47731d21, 0x3feff5c3} },
+/**/ {{0x5c092908, 0x3feff5a3} },
+/**/ {{0x70def6d7, 0x3feff583} },
+/**/ {{0x85f485d0, 0x3feff563} },
+/**/ {{0x9b49d532, 0x3feff543} },
+/**/ {{0xb0dee440, 0x3feff523} },
+/**/ {{0xc6b3b23b, 0x3feff503} },
+/**/ {{0xdcc83e62, 0x3feff4e3} },
+/**/ {{0xf31c87f8, 0x3feff4c3} },
+/**/ {{0x09b08e3d, 0x3feff4a4} },
+/**/ {{0x20845073, 0x3feff484} },
+/**/ {{0x3797cdda, 0x3feff464} },
+/**/ {{0x4eeb05b4, 0x3feff444} },
+/**/ {{0x667df741, 0x3feff424} },
+/**/ {{0x7e50a1c3, 0x3feff404} },
+/**/ {{0x9663047b, 0x3feff3e4} },
+/**/ {{0xaeb51eaa, 0x3feff3c4} },
+/**/ {{0xc746ef91, 0x3feff3a4} },
+/**/ {{0xe0187672, 0x3feff384} },
+/**/ {{0xf929b28d, 0x3feff364} },
+/**/ {{0x127aa323, 0x3feff345} },
+/**/ {{0x2c0b4776, 0x3feff325} },
+/**/ {{0x45db9ec7, 0x3feff305} },
+/**/ {{0x5feba858, 0x3feff2e5} },
+/**/ {{0x7a3b6369, 0x3feff2c5} },
+/**/ {{0x94cacf3b, 0x3feff2a5} },
+/**/ {{0xaf99eb11, 0x3feff285} },
+/**/ {{0xcaa8b62a, 0x3feff265} },
+/**/ {{0xe5f72fc9, 0x3feff245} },
+/**/ {{0x0185572f, 0x3feff226} },
+/**/ {{0x1d532b9d, 0x3feff206} },
+/**/ {{0x3960ac54, 0x3feff1e6} },
+/**/ {{0x55add896, 0x3feff1c6} },
+/**/ {{0x723aafa3, 0x3feff1a6} },
+/**/ {{0x8f0730be, 0x3feff186} },
+/**/ {{0xac135b27, 0x3feff166} },
+/**/ {{0xc95f2e21, 0x3feff146} },
+/**/ {{0xe6eaa8eb, 0x3feff126} },
+/**/ {{0x04b5cac9, 0x3feff107} },
+/**/ {{0x22c092fb, 0x3feff0e7} },
+/**/ {{0x410b00c2, 0x3feff0c7} },
+/**/ {{0x5f951360, 0x3feff0a7} },
+/**/ {{0x7e5eca16, 0x3feff087} },
+/**/ {{0x9d682426, 0x3feff067} },
+/**/ {{0xbcb120d2, 0x3feff047} },
+/**/ {{0xdc39bf5a, 0x3feff027} },
+/**/ {{0xfc01ff00, 0x3feff007} },
+/**/ {{0x1c09df07, 0x3fefefe8} },
+/**/ {{0x3c515eae, 0x3fefefc8} },
+/**/ {{0x5cd87d38, 0x3fefefa8} },
+/**/ {{0x7d9f39e6, 0x3fefef88} },
+/**/ {{0x9ea593fa, 0x3fefef68} },
+/**/ {{0xbfeb8ab5, 0x3fefef48} },
+/**/ {{0xe1711d5a, 0x3fefef28} },
+/**/ {{0x03364b28, 0x3fefef09} },
+/**/ {{0x253b1363, 0x3fefeee9} },
+/**/ {{0x477f754b, 0x3fefeec9} },
+/**/ {{0x6a037022, 0x3fefeea9} },
+/**/ {{0x8cc7032a, 0x3fefee89} },
+/**/ {{0xafca2da5, 0x3fefee69} },
+/**/ {{0xd30ceed4, 0x3fefee49} },
+/**/ {{0xf68f45f8, 0x3fefee29} },
+/**/ {{0x1a513254, 0x3fefee0a} },
+/**/ {{0x3e52b329, 0x3fefedea} },
+/**/ {{0x6293c7b8, 0x3fefedca} },
+/**/ {{0x87146f44, 0x3fefedaa} },
+/**/ {{0xabd4a90e, 0x3fefed8a} },
+/**/ {{0xd0d47458, 0x3fefed6a} },
+/**/ {{0xf613d064, 0x3fefed4a} },
+/**/ {{0x1b92bc73, 0x3fefed2b} },
+/**/ {{0x415137c7, 0x3fefed0b} },
+/**/ {{0x674f41a2, 0x3fefeceb} },
+/**/ {{0x8d8cd945, 0x3fefeccb} },
+/**/ {{0xb409fdf3, 0x3fefecab} },
+/**/ {{0xdac6aeed, 0x3fefec8b} },
+/**/ {{0x01c2eb76, 0x3fefec6c} },
+/**/ {{0x28feb2ce, 0x3fefec4c} },
+/**/ {{0x507a0437, 0x3fefec2c} },
+/**/ {{0x7834def5, 0x3fefec0c} },
+/**/ {{0xa02f4247, 0x3fefebec} },
+/**/ {{0xc8692d71, 0x3fefebcc} },
+/**/ {{0xf0e29fb4, 0x3fefebac} },
+/**/ {{0x199b9852, 0x3fefeb8d} },
+/**/ {{0x4294168d, 0x3fefeb6d} },
+/**/ {{0x6bcc19a7, 0x3fefeb4d} },
+/**/ {{0x9543a0e2, 0x3fefeb2d} },
+/**/ {{0xbefaab7f, 0x3fefeb0d} },
+/**/ {{0xe8f138c2, 0x3fefeaed} },
+/**/ {{0x132747ea, 0x3fefeace} },
+/**/ {{0x3d9cd83c, 0x3fefeaae} },
+/**/ {{0x6851e8f7, 0x3fefea8e} },
+/**/ {{0x93467960, 0x3fefea6e} },
+/**/ {{0xbe7a88b7, 0x3fefea4e} },
+/**/ {{0xe9ee163f, 0x3fefea2e} },
+/**/ {{0x15a12139, 0x3fefea0f} },
+/**/ {{0x4193a8e8, 0x3fefe9ef} },
+/**/ {{0x6dc5ac8e, 0x3fefe9cf} },
+/**/ {{0x9a372b6d, 0x3fefe9af} },
+/**/ {{0xc6e824c6, 0x3fefe98f} },
+/**/ {{0xf3d897dd, 0x3fefe96f} },
+ };
+
+ static const number
+ Lu[182][2] = { /* log(ui) */
+/**/ {{{0x0b3aac49, 0xbfd63003} },
+/**/ {{0xe51fff99, 0xbc6dc18c} },},
+/**/ {{{0xdf595f30, 0xbfd5d5bd} },
+/**/ {{0x48cbb8a2, 0x3c765411} },},
+/**/ {{{0x53c8d1fb, 0xbfd57bf7} },
+/**/ {{0x15f88b63, 0x3c60908d} },},
+/**/ {{{0x0738a3d8, 0xbfd522ae} },
+/**/ {{0xb38a6979, 0x3c68f7e9} },},
+/**/ {{{0x9e172c3c, 0xbfd4c9e0} },
+/**/ {{0x5b147a5d, 0x3c512361} },},
+/**/ {{{0xc271c41b, 0xbfd4718d} },
+/**/ {{0x14c56eef, 0xbc38fb4c} },},
+/**/ {{{0x23d5e8c7, 0xbfd419b4} },
+/**/ {{0x43827392, 0xbc60dbb2} },},
+/**/ {{{0x77333184, 0xbfd3c252} },
+/**/ {{0xe50a8ec6, 0x3c72ad27} },},
+/**/ {{{0x76be1117, 0xbfd36b67} },
+/**/ {{0xe883858e, 0x3c5324f0} },},
+/**/ {{{0xe1d35ce4, 0xbfd314f1} },
+/**/ {{0x09e5c3dc, 0x3c73d699} },},
+/**/ {{{0x7cdc9354, 0xbfd2bef0} },
+/**/ {{0x7fd86088, 0x3c782dad} },},
+/**/ {{{0x1134db92, 0xbfd26962} },
+/**/ {{0xdd9db02b, 0xbc7e0efa} },},
+/**/ {{{0x6d0eb8d4, 0xbfd21445} },
+/**/ {{0x1aeba60a, 0xbc6f7ae9} },},
+/**/ {{{0x635a6b95, 0xbfd1bf99} },
+/**/ {{0x84249223, 0x3c612aeb} },},
+/**/ {{{0xcbacfb73, 0xbfd16b5c} },
+/**/ {{0x28b40935, 0xbc766fbd} },},
+/**/ {{{0x8227e47c, 0xbfd1178e} },
+/**/ {{0x5f01c691, 0x3c60e63a} },},
+/**/ {{{0x676162e3, 0xbfd0c42d} },
+/**/ {{0x9d5d11ee, 0xbc5162c7} },},
+/**/ {{{0x604d5862, 0xbfd07138} },
+/**/ {{0xed4e9138, 0xbc7cdb16} },},
+/**/ {{{0x5626c691, 0xbfd01eae} },
+/**/ {{0xbd2932e2, 0x3c418290} },},
+/**/ {{{0x6cb3b379, 0xbfcf991c} },
+/**/ {{0x66f980a2, 0xbc6f6650} },},
+/**/ {{{0xe4dcffe6, 0xbfcef5ad} },
+/**/ {{0xddc708a0, 0x3c508ab2} },},
+/**/ {{{0xffe71012, 0xbfce530e} },
+/**/ {{0x41f43042, 0xbc422760} },},
+/**/ {{{0xb0d48940, 0xbfcdb13d} },
+/**/ {{0x49f96cb9, 0xbc5aa11d} },},
+/**/ {{{0xf2655e7b, 0xbfcd1037} },
+/**/ {{0x242471a2, 0xbc660629} },},
+/**/ {{{0xc6f00f71, 0xbfcc6ffb} },
+/**/ {{0x2c57a4a5, 0x3c68e58b} },},
+/**/ {{{0x383bd8ad, 0xbfcbd087} },
+/**/ {{0xf6a516d7, 0xbc3dd355} },},
+/**/ {{{0x575bce3d, 0xbfcb31d8} },
+/**/ {{0xb386a94d, 0x3c66353a} },},
+/**/ {{{0x3c8ad9e3, 0xbfca93ed} },
+/**/ {{0x9de97203, 0xbc6bcafa} },},
+/**/ {{{0x07089664, 0xbfc9f6c4} },
+/**/ {{0x605e67ef, 0xbc435a19} },},
+/**/ {{{0xdcf7017f, 0xbfc95a5a} },
+/**/ {{0x07fb7a3d, 0xbc5142c5} },},
+/**/ {{{0xeb38fe8c, 0xbfc8beaf} },
+/**/ {{0xb6997a40, 0xbc555aa8} },},
+/**/ {{{0x6551a3c2, 0xbfc823c1} },
+/**/ {{0xe70be781, 0x3c61232c} },},
+/**/ {{{0x85444c73, 0xbfc7898d} },
+/**/ {{0xebcfb201, 0xbc5ef8f6} },},
+/**/ {{{0x8b756abc, 0xbfc6f012} },
+/**/ {{0xc21e166c, 0x3c68de59} },},
+/**/ {{{0xbe8c133a, 0xbfc6574e} },
+/**/ {{0xf4621bed, 0x3c3d34f0} },},
+/**/ {{{0x6b543db2, 0xbfc5bf40} },
+/**/ {{0x4c0df7e7, 0x3c21f5b4} },},
+/**/ {{{0xe4a1b58d, 0xbfc527e5} },
+/**/ {{0x82395bfd, 0x3c271a96} },},
+/**/ {{{0x8333b561, 0xbfc4913d} },
+/**/ {{0x4930f135, 0x3c50d560} },},
+/**/ {{{0xa59928cc, 0xbfc3fb45} },
+/**/ {{0xa354d056, 0x3c6d87e6} },},
+/**/ {{{0xb0159016, 0xbfc365fc} },
+/**/ {{0xa5b944ad, 0xbc57d411} },},
+/**/ {{{0x0c86813a, 0xbfc2d161} },
+/**/ {{0xf25af95f, 0x3c5499a3} },},
+/**/ {{{0x2a49c202, 0xbfc23d71} },
+/**/ {{0x61051d69, 0x3c66e381} },},
+/**/ {{{0x7e23f72a, 0xbfc1aa2b} },
+/**/ {{0xd9b2ef7e, 0x3c4c6ef1} },},
+/**/ {{{0x8227e47c, 0xbfc1178e} },
+/**/ {{0x5f01c691, 0x3c50e63a} },},
+/**/ {{{0xb59e3a07, 0xbfc08598} },
+/**/ {{0x9902bf32, 0x3c6dd700} },},
+/**/ {{{0x39dbd566, 0xbfbfe891} },
+/**/ {{0x215f9393, 0x3c5ac9f4} },},
+/**/ {{{0x830a1120, 0xbfbec739} },
+/**/ {{0x91780d3f, 0x3c4a2bf9} },},
+/**/ {{{0x638446a2, 0xbfbda727} },
+/**/ {{0x71733019, 0xbc5401fa} },},
+/**/ {{{0x01bc4b23, 0xbfbc8858} },
+/**/ {{0x559a6706, 0xbc5a38cb} },},
+/**/ {{{0x8dad5b1c, 0xbfbb6ac8} },
+/**/ {{0xed1ca59f, 0x3c40057e} },},
+/**/ {{{0x40b1bc38, 0xbfba4e76} },
+/**/ {{0x203e4259, 0x3c55b5ca} },},
+/**/ {{{0x5d594989, 0xbfb9335e} },
+/**/ {{0x5704ccb7, 0x3c5478a8} },},
+/**/ {{{0x2f40e3f0, 0xbfb8197e} },
+/**/ {{0xffbeed43, 0xbc3b9f2d} },},
+/**/ {{{0x0aeac0e1, 0xbfb700d3} },
+/**/ {{0x212cdd05, 0x3c272566} },},
+/**/ {{{0x4d9791cb, 0xbfb5e95a} },
+/**/ {{0x5c5c450a, 0xbc5f3874} },},
+/**/ {{{0x5d207eac, 0xbfb4d311} },
+/**/ {{0x2c7842cc, 0xbc5769f4} },},
+/**/ {{{0xa7d1ee64, 0xbfb3bdf5} },
+/**/ {{0xd3b5b45f, 0xbc47a976} },},
+/**/ {{{0xa44717a5, 0xbfb2aa04} },
+/**/ {{0x8d2fa3f7, 0x3c5d15d3} },},
+/**/ {{{0xd1465567, 0xbfb1973b} },
+/**/ {{0x67a6acf6, 0x3c475583} },},
+/**/ {{{0xb59e3a07, 0xbfb08598} },
+/**/ {{0x9902bf32, 0x3c5dd700} },},
+/**/ {{{0xc006b87c, 0xbfaeea31} },
+/**/ {{0x93b7b66c, 0x3c43e4fc} },},
+/**/ {{{0xcdddb2cc, 0xbfaccb73} },
+/**/ {{0x0500efd4, 0x3c4e48fb} },},
+/**/ {{{0xd0fb10fc, 0xbfaaaef2} },
+/**/ {{0xb42e0add, 0xbc2a353b} },},
+/**/ {{{0x149fb343, 0xbfa894aa} },
+/**/ {{0x7660a23d, 0xbc3a8be9} },},
+/**/ {{{0xf2d4bb58, 0xbfa67c94} },
+/**/ {{0x6505e603, 0xbc40413e} },},
+/**/ {{{0xd42de3ea, 0xbfa466ae} },
+/**/ {{0x7f4a137e, 0x3c4cdd6f} },},
+/**/ {{{0x2f8d183f, 0xbfa252f3} },
+/**/ {{0x92615916, 0x3c4947f7} },},
+/**/ {{{0x89e74444, 0xbfa0415d} },
+/**/ {{0x1d753622, 0xbc4c05cf} },},
+/**/ {{{0xec14aaf2, 0xbf9c63d2} },
+/**/ {{0xa686bd86, 0x3c3ce030} },},
+/**/ {{{0x28c8cabf, 0xbf984925} },
+/**/ {{0x0619fa67, 0x3c3d192d} },},
+/**/ {{{0x25980cc1, 0xbf9432a9} },
+/**/ {{0x39004192, 0x3c38cdaf} },},
+/**/ {{{0x58935847, 0xbf902056} },
+/**/ {{0x8416e71f, 0xbc327c8e} },},
+/**/ {{{0xa388a2aa, 0xbf882448} },
+/**/ {{0x137f09a0, 0xbc104b16} },},
+/**/ {{{0x7588de71, 0xbf801015} },
+/**/ {{0xd417ced0, 0xbc146662} },},
+/**/ {{{0x59588b35, 0xbf700805} },
+/**/ {{0x8cf63677, 0xbc1f9663} },},
+/**/ {{{0x00000000, 0x00000000} },
+/**/ {{0x00000000, 0x00000000} },},
+/**/ {{{0xa2b10bc0, 0x3f6ff00a} },
+/**/ {{0xd5a6d353, 0x3c02821a} },},
+/**/ {{{0x6b106789, 0x3f7fe02a} },
+/**/ {{0xe3711ebf, 0xbbce44b7} },},
+/**/ {{{0x5f810a77, 0x3f87dc47} },
+/**/ {{0x87d3df21, 0xbc116d76} },},
+/**/ {{{0xb0fc03e4, 0x3f8fc0a8} },
+/**/ {{0xc59642a1, 0xbc183092} },},
+/**/ {{{0x4346a575, 0x3f93cea4} },
+/**/ {{0x902b3a1c, 0xbc10cb5a} },},
+/**/ {{{0x07d5b11b, 0x3f97b91b} },
+/**/ {{0xace3a510, 0xbc35b602} },},
+/**/ {{{0x27af9198, 0x3f9b9fc0} },
+/**/ {{0x229dc868, 0xbbf0ae69} },},
+/**/ {{{0x0e783300, 0x3f9f829b} },
+/**/ {{0x04f1ef23, 0x3c333e3f} },},
+/**/ {{{0x8923d980, 0x3fa1b0d9} },
+/**/ {{0x89bac481, 0xbc3e9ae8} },},
+/**/ {{{0xb9febd60, 0x3fa39e87} },
+/**/ {{0x37f551bb, 0xbc45bfa9} },},
+/**/ {{{0xafc8e4d5, 0x3fa58a5b} },
+/**/ {{0x2b4e2b72, 0xbc4ce55c} },},
+/**/ {{{0xf632dcfc, 0x3fa77458} },
+/**/ {{0xa87b9296, 0x3c418d3c} },},
+/**/ {{{0x0ec8e3eb, 0x3fa95c83} },
+/**/ {{0x80520bf2, 0x3c4f5a0e} },},
+/**/ {{{0x711971bf, 0x3fab42dd} },
+/**/ {{0x9c130499, 0xbc3eb975} },},
+/**/ {{{0x8adb0b52, 0x3fad276b} },
+/**/ {{0x3257fd47, 0x3c21e3c5} },},
+/**/ {{{0xc01162a6, 0x3faf0a30} },
+/**/ {{0x5c5bbacd, 0x3c485f32} },},
+/**/ {{{0x3598e471, 0x3fb07598} },
+/**/ {{0x333c45b8, 0x3c480da5} },},
+/**/ {{{0xeea37ae1, 0x3fb16536} },
+/**/ {{0xe8c22cda, 0xbc379da3} },},
+/**/ {{{0x2f0a1417, 0x3fb253f6} },
+/**/ {{0x63fc4cfd, 0xbc1c1259} },},
+/**/ {{{0x961bd1d1, 0x3fb341d7} },
+/**/ {{0x227becbb, 0xbc5b599f} },},
+/**/ {{{0xbea646f0, 0x3fb42edc} },
+/**/ {{0x935996c9, 0x3c4ddd4f} },},
+/**/ {{{0x3f06183f, 0x3fb51b07} },
+/**/ {{0x9a1a8be4, 0x3c5a49e3} },},
+/**/ {{{0xa93750c4, 0x3fb60658} },
+/**/ {{0x8ec21b6a, 0xbc538845} },},
+/**/ {{{0x8ae56b4c, 0x3fb6f0d2} },
+/**/ {{0x9184b992, 0xbc5906d9} },},
+/**/ {{{0x6d7b12cd, 0x3fb7da76} },
+/**/ {{0xcdd94131, 0xbc5eeedf} },},
+/**/ {{{0xd6319b21, 0x3fb8c345} },
+/**/ {{0xab3424a9, 0xbc24a697} },},
+/**/ {{{0x462033ad, 0x3fb9ab42} },
+/**/ {{0x1c184e8e, 0xbc42099e} },},
+/**/ {{{0x3a4ad563, 0x3fba926d} },
+/**/ {{0x8aa70ea9, 0x3c5942f4} },},
+/**/ {{{0x2bb0eda1, 0x3fbb78c8} },
+/**/ {{0xf0327e21, 0x3c20878c} },},
+/**/ {{{0x8f5bc743, 0x3fbc5e54} },
+/**/ {{0xef8161b1, 0x3c35d617} },},
+/**/ {{{0xd66cb35d, 0x3fbd4313} },
+/**/ {{0x951d90fa, 0x3c5790dd} },},
+/**/ {{{0x6e2af2e6, 0x3fbe2707} },
+/**/ {{0x001e0162, 0xbc361578} },},
+/**/ {{{0xc01162a6, 0x3fbf0a30} },
+/**/ {{0x5c5bbacd, 0x3c585f32} },},
+/**/ {{{0x31dbeabb, 0x3fbfec91} },
+/**/ {{0x9981b36c, 0xbc55746b} },},
+/**/ {{{0x12ca596e, 0x3fc06715} },
+/**/ {{0x7eb86499, 0x3c550c64} },},
+/**/ {{{0x7cd08e59, 0x3fc0d77e} },
+/**/ {{0x5e9030ac, 0x3c69a5dc} },},
+/**/ {{{0x846742ac, 0x3fc14785} },
+/**/ {{0x3e3a7f07, 0x3c6a2881} },},
+/**/ {{{0xd52f67a0, 0x3fc1b72a} },
+/**/ {{0x3472cd74, 0x3c548302} },},
+/**/ {{{0x190a5acb, 0x3fc2266f} },
+/**/ {{0xf1809e88, 0x3c6f547b} },},
+/**/ {{{0xf81ff523, 0x3fc29552} },
+/**/ {{0x1c407dbf, 0x3c630177} },},
+/**/ {{{0x18e47fd3, 0x3fc303d7} },
+/**/ {{0xd96091fa, 0xbc06b9c7} },},
+/**/ {{{0x201e8f74, 0x3fc371fc} },
+/**/ {{0x62af18a0, 0x3c5de6cb} },},
+/**/ {{{0xb0ecc62a, 0x3fc3dfc2} },
+/**/ {{0xe7d81017, 0xbc5ab3a8} },},
+/**/ {{{0x6ccb7d1e, 0x3fc44d2b} },
+/**/ {{0x543e1f88, 0x3c69f4f6} },},
+/**/ {{{0xf39a55e5, 0x3fc4ba36} },
+/**/ {{0xbcc36756, 0x3c668981} },},
+/**/ {{{0xe3a1b438, 0x3fc526e5} },
+/**/ {{0x8a470d3a, 0xbc6746ff} },},
+/**/ {{{0xd9982086, 0x3fc59338} },
+/**/ {{0xaa8ad7cf, 0xbc565d22} },},
+/**/ {{{0x70a793d4, 0x3fc5ff30} },
+/**/ {{0xfafc6f6e, 0xbc5bc60e} },},
+/**/ {{{0x4272ad51, 0x3fc66acd} },
+/**/ {{0x4e1ea8b2, 0xbc50900e} },},
+/**/ {{{0xe719d21d, 0x3fc6d60f} },
+/**/ {{0x68ecd179, 0xbc6caae2} },},
+/**/ {{{0xf54037a5, 0x3fc740f8} },
+/**/ {{0x62a84cdb, 0xbc5b2640} },},
+/**/ {{{0x0210d909, 0x3fc7ab89} },
+/**/ {{0x2d6a0608, 0x3c4be36b} },},
+/**/ {{{0xa14357eb, 0x3fc815c0} },
+/**/ {{0x073a0564, 0xbc54be48} },},
+/**/ {{{0x6520c911, 0x3fc87fa0} },
+/**/ {{0xbfa08d9a, 0xbc6bf7fd} },},
+/**/ {{{0xde886d41, 0x3fc8e928} },
+/**/ {{0x51a56770, 0xbc6569d8} },},
+/**/ {{{0x9cf456b4, 0x3fc9525a} },
+/**/ {{0x1d4e2e26, 0x3c6d904c} },},
+/**/ {{{0x2e7dfb83, 0x3fc9bb36} },
+/**/ {{0x1f003e0c, 0x3c6575e3} },},
+/**/ {{{0x1fe2b563, 0x3fca23bc} },
+/**/ {{0xb07a998c, 0x3c493711} },},
+/**/ {{{0xfc882f19, 0x3fca8bec} },
+/**/ {{0x918c39eb, 0xbc5e8c37} },},
+/**/ {{{0x4e80bff3, 0x3fcaf3c9} },
+/**/ {{0xf3641985, 0xbc5398cf} },},
+/**/ {{{0x9e8fb5a4, 0x3fcb5b51} },
+/**/ {{0xdc19e1a0, 0x3c6ba27f} },},
+/**/ {{{0x742d8cd6, 0x3fcbc286} },
+/**/ {{0x44870f55, 0x3c54fce7} },},
+/**/ {{{0x558c18c1, 0x3fcc2968} },
+/**/ {{0x38a3fb6b, 0xbc673dee} },},
+/**/ {{{0xc79a9a22, 0x3fcc8ff7} },
+/**/ {{0xf8434012, 0xbc64f689} },},
+/**/ {{{0x4e09c5dc, 0x3fccf635} },
+/**/ {{0x7d55b695, 0x3c6239a0} },},
+/**/ {{{0x6b4fbb91, 0x3fcd5c21} },
+/**/ {{0x597e4d40, 0x3c66e443} },},
+/**/ {{{0xa0abec7d, 0x3fcdc1bc} },
+/**/ {{0x1998b6fc, 0x3c6834c5} },},
+/**/ {{{0x6e2af2e6, 0x3fce2707} },
+/**/ {{0x001e0162, 0xbc461578} },},
+/**/ {{{0x52aa5a60, 0x3fce8c02} },
+/**/ {{0x39bfc89b, 0xbc46e03a} },},
+/**/ {{{0xcbdc5936, 0x3fcef0ad} },
+/**/ {{0x950dc20d, 0x3c648637} },},
+/**/ {{{0x564b7b37, 0x3fcf550a} },
+/**/ {{0xfd018c37, 0x3c2c5f6d} },},
+/**/ {{{0x6d5e3e2b, 0x3fcfb918} },
+/**/ {{0x64f21acb, 0xbc6caaae} },},
+/**/ {{{0x45ad501d, 0x3fd00e6c} },
+/**/ {{0x8ff6fead, 0xbc6cb956} },},
+/**/ {{{0x94b4d041, 0x3fd04025} },
+/**/ {{0x17a5022d, 0xbc628ec2} },},
+/**/ {{{0x5fcd590d, 0x3fd071b8} },
+/**/ {{0xf97bde80, 0x3c5d1707} },},
+/**/ {{{0xe27390e3, 0x3fd0a324} },
+/**/ {{0xe8061c03, 0x3c77dcfd} },},
+/**/ {{{0x579ab74b, 0x3fd0d46b} },
+/**/ {{0x1c3cbd92, 0x3c603ec8} },},
+/**/ {{{0xf9ae4ad5, 0x3fd1058b} },
+/**/ {{0xab4cb31d, 0x3c589fa0} },},
+/**/ {{{0x0293a8b0, 0x3fd13687} },
+/**/ {{0x98edd24a, 0x3c77b662} },},
+/**/ {{{0xababa60e, 0x3fd1675c} },
+/**/ {{0xab883717, 0x3c2ce63e} },},
+/**/ {{{0x2dd4236f, 0x3fd1980d} },
+/**/ {{0xb0e4d147, 0x3c79d3d1} },},
+/**/ {{{0xc16999fb, 0x3fd1c898} },
+/**/ {{0x2aff1c44, 0xbc30e5c6} },},
+/**/ {{{0x9e48a2f3, 0x3fd1f8ff} },
+/**/ {{0x9a0c4b07, 0xbc7c9fdf} },},
+/**/ {{{0xfbcf7966, 0x3fd22941} },
+/**/ {{0xb09628af, 0xbc776f5e} },},
+/**/ {{{0x10df763a, 0x3fd25960} },
+/**/ {{0x57075e9e, 0xbc50f76c} },},
+/**/ {{{0x13de86a3, 0x3fd2895a} },
+/**/ {{0xc13f040e, 0x3c77ad24} },},
+/**/ {{{0x3ab89d25, 0x3fd2b930} },
+/**/ {{0xfd852ad4, 0xbc7896b5} },},
+/**/ {{{0xbae11d31, 0x3fd2e8e2} },
+/**/ {{0xb95ebdf9, 0xbc78f4cd} },},
+/**/ {{{0xc9544185, 0x3fd31871} },
+/**/ {{0x4c09b379, 0xbc351acc} },},
+/**/ {{{0x9a987d55, 0x3fd347dd} },
+/**/ {{0x580919f8, 0xbc64dd4c} },},
+/**/ {{{0x62bfd85b, 0x3fd37726} },
+/**/ {{0xd8117de7, 0xbc4b5629} },},
+/**/ {{{0x556945ea, 0x3fd3a64c} },
+/**/ {{0x1945f97c, 0xbc6c6865} },},
+/**/ {{{0xa5c1f710, 0x3fd3d54f} },
+/**/ {{0xc6a1c98d, 0xbc7e3265} },},
+/**/ {{{0x8686a7e4, 0x3fd40430} },
+/**/ {{0x6082ce6d, 0xbc70bcfb} },},
+/**/ {{{0x2a04e814, 0x3fd432ef} },
+/**/ {{0x715ac903, 0xbc729931} },},
+/**/ {{{0xc21c5ec2, 0x3fd4618b} },
+/**/ {{0xcdeccf1d, 0x3c7f42de} },},
+/**/ {{{0x804009d1, 0x3fd49006} },
+/**/ {{0x41f177dc, 0xbc69ffc3} },},
+/**/ {{{0x957778a1, 0x3fd4be5f} },
+/**/ {{0x5b04813d, 0xbc6259b3} },},
+/**/ {{{0x3260026a, 0x3fd4ec97} },
+/**/ {{0xd977dc5e, 0xbc742a87} },},
+/**/ {{{0x872df82d, 0x3fd51aad} },
+/**/ {{0xc19f55e3, 0x3c43927a} },},
+/**/ {{{0xc3add263, 0x3fd548a2} },
+/**/ {{0x7e308ddb, 0xbc6819cf} },},
+/**/ {{{0x17455a6c, 0x3fd57677} },
+/**/ {{0xb283660c, 0x3c7526ad} },},
+/**/ {{{0xb0f4cfe2, 0x3fd5a42a} },
+/**/ {{0x7dee9a3d, 0xbc78ebcb} },},
+/**/ {{{0xbf5809ca, 0x3fd5d1bd} },
+/**/ {{0x83dc7fe1, 0x3c742363} },},
+/**/ {{{0x70a793d4, 0x3fd5ff30} },
+/**/ {{0xfafc6f6e, 0xbc6bc60e} },},
+/**/ {{{0xf2b9c795, 0x3fd62c82} },
+/**/ {{0x915300e5, 0x3c67b7af} },},
+ };
+
+ static const number
+ Lv[362][2] = { /* log(vj) */
+
+/**/ {{{0xb72daabf, 0xbf6687ec} },
+/**/ {{0x0f13318f, 0x3c052c69} },},
+/**/ {{{0x3767104f, 0xbf6667d6} },
+/**/ {{0xd27a7bac, 0x3bd3efa3} },},
+/**/ {{{0xd7cd64fb, 0xbf6647bf} },
+/**/ {{0x55a89c36, 0x3c09b725} },},
+/**/ {{{0x9860683b, 0xbf6627a9} },
+/**/ {{0xfebc844a, 0x3bcbae22} },},
+/**/ {{{0x791fd98a, 0xbf660793} },
+/**/ {{0x78fa1cb5, 0xbbfe34af} },},
+/**/ {{{0x7a0b7863, 0xbf65e77d} },
+/**/ {{0xea78fdd0, 0xbc02f1b1} },},
+/**/ {{{0x9b230442, 0xbf65c767} },
+/**/ {{0x2202b2ca, 0x3bf70d8c} },},
+/**/ {{{0xdc663ca2, 0xbf65a751} },
+/**/ {{0xc3444e64, 0xbbfdc63d} },},
+/**/ {{{0x3dd4e102, 0xbf65873c} },
+/**/ {{0x370d69c3, 0x3c021b11} },},
+/**/ {{{0xbf6eb0de, 0xbf656726} },
+/**/ {{0x154dd8d8, 0xbbfb6da8} },},
+/**/ {{{0x61336bb6, 0xbf654711} },
+/**/ {{0xdf9a4709, 0xbc0b12d2} },},
+/**/ {{{0x2322d10a, 0xbf6526fc} },
+/**/ {{0x68d1274f, 0x3bf997f2} },},
+/**/ {{{0x053ca059, 0xbf6506e7} },
+/**/ {{0xe70c852a, 0x3c0c2a1f} },},
+/**/ {{{0x07809924, 0xbf64e6d2} },
+/**/ {{0xa808538f, 0x3c04cc9e} },},
+/**/ {{{0x29ee7aed, 0xbf64c6bd} },
+/**/ {{0x7797a4bd, 0x3befe68c} },},
+/**/ {{{0x6c860537, 0xbf64a6a8} },
+/**/ {{0x9efaae3d, 0x3c06794d} },},
+/**/ {{{0xcf46f784, 0xbf648693} },
+/**/ {{0xb2ddd9d1, 0xbbfed318} },},
+/**/ {{{0x5231115a, 0xbf64667f} },
+/**/ {{0x4643624b, 0x3c061f62} },},
+/**/ {{{0xf544123c, 0xbf64466a} },
+/**/ {{0x9387f11e, 0x3c0666a0} },},
+/**/ {{{0xb87fb9b0, 0xbf642656} },
+/**/ {{0x116ec598, 0x3c0043b2} },},
+/**/ {{{0x9be3c73c, 0xbf640642} },
+/**/ {{0xd2de6e3e, 0xbbfbd84d} },},
+/**/ {{{0x9f6ffa68, 0xbf63e62e} },
+/**/ {{0x433d8c65, 0xbbe9149b} },},
+/**/ {{{0xc32412bb, 0xbf63c61a} },
+/**/ {{0x08e5a7bb, 0xbbf6b88d} },},
+/**/ {{{0x06ffcfbe, 0xbf63a607} },
+/**/ {{0xccfac9e2, 0xbb9f3c7a} },},
+/**/ {{{0x6b02f0fa, 0xbf6385f3} },
+/**/ {{0xbec6f6e4, 0x3bee405c} },},
+/**/ {{{0xef2d35f9, 0xbf6365df} },
+/**/ {{0xaf0c0b4c, 0x3bf02993} },},
+/**/ {{{0x937e5e46, 0xbf6345cc} },
+/**/ {{0xaa64716f, 0x3bf9be97} },},
+/**/ {{{0x57f6296c, 0xbf6325b9} },
+/**/ {{0xa2e863ae, 0xbbfdeb4d} },},
+/**/ {{{0x3c9456f9, 0xbf6305a6} },
+/**/ {{0x636d2b2c, 0x3c0f3c7f} },},
+/**/ {{{0x4158a678, 0xbf62e593} },
+/**/ {{0xb166ca7f, 0x3c01a8df} },},
+/**/ {{{0x6642d778, 0xbf62c580} },
+/**/ {{0x53a2d534, 0x3c020ff1} },},
+/**/ {{{0xab52a987, 0xbf62a56d} },
+/**/ {{0x0412f1e7, 0xbbe8fef1} },},
+/**/ {{{0x1087dc35, 0xbf62855b} },
+/**/ {{0x4b7ac6c6, 0xbbfcd17e} },},
+/**/ {{{0x95e22f12, 0xbf626548} },
+/**/ {{0x9a8127bf, 0xbbfbfc21} },},
+/**/ {{{0x3b6161af, 0xbf624536} },
+/**/ {{0x66d42390, 0x3bd7eda1} },},
+/**/ {{{0x0105339d, 0xbf622524} },
+/**/ {{0x77fedcad, 0xbbdf374e} },},
+/**/ {{{0xe6cd646f, 0xbf620511} },
+/**/ {{0x52d05dea, 0x3be1d1fb} },},
+/**/ {{{0xecb9b3b8, 0xbf61e4ff} },
+/**/ {{0xffd8e706, 0x3c02c2fc} },},
+/**/ {{{0x12c9e10b, 0xbf61c4ee} },
+/**/ {{0xf1d5cc2c, 0xbc02b4f8} },},
+/**/ {{{0x58fdabfe, 0xbf61a4dc} },
+/**/ {{0x1315b191, 0xbc0618c3} },},
+/**/ {{{0xbf54d426, 0xbf6184ca} },
+/**/ {{0xcb3cdab0, 0xbc01f8d5} },},
+/**/ {{{0x45cf1919, 0xbf6164b9} },
+/**/ {{0xc025605a, 0xbc014ff7} },},
+/**/ {{{0xec6c3a6e, 0xbf6144a7} },
+/**/ {{0x87cb08cd, 0xbbff04ff} },},
+/**/ {{{0xb32bf7bd, 0xbf612496} },
+/**/ {{0xe6af1b84, 0x3bee89b4} },},
+/**/ {{{0x9a0e109e, 0xbf610485} },
+/**/ {{0x35a60879, 0x3c07e99e} },},
+/**/ {{{0xa11244aa, 0xbf60e474} },
+/**/ {{0x20f2325a, 0x3c04b698} },},
+/**/ {{{0xc838537b, 0xbf60c463} },
+/**/ {{0x3617200d, 0x3bc0657e} },},
+/**/ {{{0x0f7ffcac, 0xbf60a453} },
+/**/ {{0xa5080961, 0xbc008feb} },},
+/**/ {{{0x76e8ffd9, 0xbf608442} },
+/**/ {{0xbb5e1df7, 0x3bd13002} },},
+/**/ {{{0xfe731c9d, 0xbf606431} },
+/**/ {{0x6e2858c0, 0xbc0509f3} },},
+/**/ {{{0xa61e1296, 0xbf604421} },
+/**/ {{0x5f5d9695, 0xbc04b556} },},
+/**/ {{{0x6de9a162, 0xbf602411} },
+/**/ {{0xe79a4e00, 0x3c042b89} },},
+/**/ {{{0x55d5889e, 0xbf600401} },
+/**/ {{0x1113f403, 0x3be8f98e} },},
+/**/ {{{0xbbc30fd4, 0xbf5fc7e2} },
+/**/ {{0x93382bc9, 0xbbfc709b} },},
+/**/ {{{0x0c1abdcd, 0xbf5f87c3} },
+/**/ {{0x76a55d1c, 0xbbf2a90d} },},
+/**/ {{{0x9cb19a68, 0xbf5f47a3} },
+/**/ {{0x76e7826b, 0x3be1b815} },},
+/**/ {{{0x6d8724e7, 0xbf5f0784} },
+/**/ {{0x2b63756d, 0xbbe72d46} },},
+/**/ {{{0x7e9adc90, 0xbf5ec765} },
+/**/ {{0x73bb17c5, 0x3beb1a66} },},
+/**/ {{{0xcfec40a8, 0xbf5e8746} },
+/**/ {{0xb5e5a553, 0x3bf11af5} },},
+/**/ {{{0x617ad077, 0xbf5e4728} },
+/**/ {{0xf57dd14f, 0x3bfb2cad} },},
+/**/ {{{0x33460b45, 0xbf5e070a} },
+/**/ {{0x4902c8d5, 0xbbf8db75} },},
+/**/ {{{0x454d705f, 0xbf5dc6ec} },
+/**/ {{0xe8a41057, 0x3bef5cc6} },},
+/**/ {{{0x97907f0f, 0xbf5d86ce} },
+/**/ {{0xdf8672ef, 0x3bed8277} },},
+/**/ {{{0x2a0eb6a3, 0xbf5d46b1} },
+/**/ {{0x3717e5ee, 0xbbc2f9c2} },},
+/**/ {{{0xfcc7966b, 0xbf5d0693} },
+/**/ {{0xab4852c6, 0x3bf4deed} },},
+/**/ {{{0x0fba9db6, 0xbf5cc677} },
+/**/ {{0x9db2a368, 0xbbf3a2b4} },},
+/**/ {{{0x62e74bd8, 0xbf5c865a} },
+/**/ {{0x58fa0c24, 0xbbd2c51d} },},
+/**/ {{{0xf64d2024, 0xbf5c463d} },
+/**/ {{0xe3a09391, 0x3bf838ca} },},
+/**/ {{{0xc9eb99ee, 0xbf5c0621} },
+/**/ {{0x61b7de71, 0xbbdc2a9e} },},
+/**/ {{{0xddc2388e, 0xbf5bc605} },
+/**/ {{0x4accb195, 0xbbea9808} },},
+/**/ {{{0x31d07b5c, 0xbf5b85ea} },
+/**/ {{0x032e030b, 0xbbd811a2} },},
+/**/ {{{0xc615e1b1, 0xbf5b45ce} },
+/**/ {{0x821e0b81, 0xbbfd5427} },},
+/**/ {{{0x9a91eaea, 0xbf5b05b3} },
+/**/ {{0x2619306b, 0x3bfffeba} },},
+/**/ {{{0xaf441661, 0xbf5ac598} },
+/**/ {{0x9eac7d15, 0x3bd22824} },},
+/**/ {{{0x042be376, 0xbf5a857e} },
+/**/ {{0x24893f0e, 0x3bc20736} },},
+/**/ {{{0x9948d188, 0xbf5a4563} },
+/**/ {{0x04d734cd, 0xbbf58ab4} },},
+/**/ {{{0x6e9a5ff9, 0xbf5a0549} },
+/**/ {{0x5723a6c3, 0xbbf22673} },},
+/**/ {{{0x84200e2c, 0xbf59c52f} },
+/**/ {{0xa538e8e1, 0x3bfc81da} },},
+/**/ {{{0xd9d95b83, 0xbf598515} },
+/**/ {{0x2a8e3feb, 0xbbfa1a37} },},
+/**/ {{{0x6fc5c767, 0xbf5944fc} },
+/**/ {{0x385159f9, 0x3bf8e1ce} },},
+/**/ {{{0x45e4d13c, 0xbf5904e3} },
+/**/ {{0x1567c7a7, 0xbbfc4737} },},
+/**/ {{{0x5c35f86e, 0xbf58c4ca} },
+/**/ {{0x23c9ae0c, 0x3bf41581} },},
+/**/ {{{0xb2b8bc65, 0xbf5884b1} },
+/**/ {{0x2b66cfb6, 0x3bf70c2c} },},
+/**/ {{{0x496c9c8d, 0xbf584499} },
+/**/ {{0xe5a11e3e, 0xbbdb9042} },},
+/**/ {{{0x20511854, 0xbf580481} },
+/**/ {{0x61bcb040, 0xbbf9cf9d} },},
+/**/ {{{0x3765af29, 0xbf57c469} },
+/**/ {{0xe26a419b, 0xbbf65ceb} },},
+/**/ {{{0x8ea9e07c, 0xbf578451} },
+/**/ {{0xb70a4088, 0xbbf1c2f5} },},
+/**/ {{{0x261d2bbf, 0xbf57443a} },
+/**/ {{0x29704ba7, 0xbbbc7b8f} },},
+/**/ {{{0xfdbf1065, 0xbf570422} },
+/**/ {{0x433ccb3b, 0x3bca0a54} },},
+/**/ {{{0x158f0de3, 0xbf56c40c} },
+/**/ {{0x207cde2d, 0x3bd9e257} },},
+/**/ {{{0x6d8ca3af, 0xbf5683f5} },
+/**/ {{0xf7b51b49, 0xbbef17a4} },},
+/**/ {{{0x05b75142, 0xbf5643df} },
+/**/ {{0x9d345bf8, 0x3be28239} },},
+/**/ {{{0xde0e9614, 0xbf5603c8} },
+/**/ {{0x0918d1bf, 0xbbde6c21} },},
+/**/ {{{0xf691f1a1, 0xbf55c3b2} },
+/**/ {{0x377de4c8, 0x3bd37d78} },},
+/**/ {{{0x4f40e365, 0xbf55839d} },
+/**/ {{0xbbf7c9d1, 0x3bf52b7d} },},
+/**/ {{{0xe81aeadd, 0xbf554387} },
+/**/ {{0x679c3d9a, 0xbbf0be6a} },},
+/**/ {{{0xc11f878a, 0xbf550372} },
+/**/ {{0xb6cdd88e, 0xbbdd9e20} },},
+/**/ {{{0xda4e38ec, 0xbf54c35d} },
+/**/ {{0x09302da0, 0xbbe3b1e7} },},
+/**/ {{{0x33a67e86, 0xbf548349} },
+/**/ {{0x085b922d, 0x3be8cba8} },},
+/**/ {{{0xcd27d7db, 0xbf544334} },
+/**/ {{0xf024ab43, 0xbba5f2c9} },},
+/**/ {{{0xa6d1c471, 0xbf540320} },
+/**/ {{0xf686cf3d, 0xbbeb31f3} },},
+/**/ {{{0xc0a3c3cf, 0xbf53c30c} },
+/**/ {{0xd4ad32f6, 0xbbf74ffe} },},
+/**/ {{{0x1a9d557e, 0xbf5382f9} },
+/**/ {{0x4acb368f, 0x3bd2e555} },},
+/**/ {{{0xb4bdf907, 0xbf5342e5} },
+/**/ {{0x07812806, 0x3be13442} },},
+/**/ {{{0x8f052df6, 0xbf5302d2} },
+/**/ {{0x70b1e756, 0x3bf5f429} },},
+/**/ {{{0xa97273d7, 0xbf52c2bf} },
+/**/ {{0x43a03fff, 0xbbf20aa3} },},
+/**/ {{{0x04054a3a, 0xbf5282ad} },
+/**/ {{0x8bebd7ad, 0xbbed4d57} },},
+/**/ {{{0x9ebd30ae, 0xbf52429a} },
+/**/ {{0x5a71c5a4, 0xbbff9529} },},
+/**/ {{{0x7999a6c6, 0xbf520288} },
+/**/ {{0x54100f9e, 0x3bfb055a} },},
+/**/ {{{0x949a2c12, 0xbf51c276} },
+/**/ {{0xa2e9f1b4, 0xbbff6978} },},
+/**/ {{{0xefbe402a, 0xbf518264} },
+/**/ {{0xbc188323, 0x3bf01fb9} },},
+/**/ {{{0x8b0562a1, 0xbf514253} },
+/**/ {{0x957bf23a, 0xbbf7c87c} },},
+/**/ {{{0x666f1311, 0xbf510242} },
+/**/ {{0xc8be6880, 0x3bdc2cb9} },},
+/**/ {{{0x81fad111, 0xbf50c231} },
+/**/ {{0x07ba000d, 0xbbf59fc1} },},
+/**/ {{{0xdda81c3d, 0xbf508220} },
+/**/ {{0xbf5c8a0b, 0xbbf06a0a} },},
+/**/ {{{0x79767431, 0xbf504210} },
+/**/ {{0xa9a705bc, 0x3bf3a6cf} },},
+/**/ {{{0x55655889, 0xbf500200} },
+/**/ {{0xbf0fa436, 0xbbe9abe6} },},
+/**/ {{{0xe2e891cc, 0xbf4f83e0} },
+/**/ {{0x1b81bf62, 0x3be4aa59} },},
+/**/ {{{0x9b4589ce, 0xbf4f03c1} },
+/**/ {{0x8a47f50a, 0xbbe60518} },},
+/**/ {{{0xd3e0985f, 0xbf4e83a2} },
+/**/ {{0x5ef17e96, 0x3bed32d8} },},
+/**/ {{{0x8cb8bcc3, 0xbf4e0384} },
+/**/ {{0xf09afa4d, 0xbbeb7b30} },},
+/**/ {{{0xc5ccf647, 0xbf4d8366} },
+/**/ {{0xf586cec2, 0xbbd527fc} },},
+/**/ {{{0x7f1c4437, 0xbf4d0349} },
+/**/ {{0x4a686886, 0x3bc2bcf0} },},
+/**/ {{{0xb8a5a5e3, 0xbf4c832c} },
+/**/ {{0x721c2ebe, 0x3bc98f93} },},
+/**/ {{{0x72681a9e, 0xbf4c0310} },
+/**/ {{0xb5308d22, 0xbbe20f00} },},
+/**/ {{{0xac62a1bf, 0xbf4b82f4} },
+/**/ {{0x9737b561, 0xbbe1edd0} },},
+/**/ {{{0x66943a9f, 0xbf4b02d9} },
+/**/ {{0x23f894a1, 0xbbcc950b} },},
+/**/ {{{0xa0fbe49a, 0xbf4a82be} },
+/**/ {{0x866bc982, 0xbb81da04} },},
+/**/ {{{0x5b989f0f, 0xbf4a02a4} },
+/**/ {{0x9d76196e, 0xbbd9114d} },},
+/**/ {{{0x96696961, 0xbf49828a} },
+/**/ {{0xd3292fd6, 0x3bc10d20} },},
+/**/ {{{0x516d42f4, 0xbf490271} },
+/**/ {{0x2e9a5dd5, 0xbbee53a3} },},
+/**/ {{{0x8ca32b32, 0xbf488258} },
+/**/ {{0xd18f8004, 0xbbc55af5} },},
+/**/ {{{0x480a2185, 0xbf480240} },
+/**/ {{0xa9b0178a, 0xbbb32d23} },},
+/**/ {{{0x83a1255c, 0xbf478228} },
+/**/ {{0x8152093a, 0x3be84cc3} },},
+/**/ {{{0x3f673627, 0xbf470211} },
+/**/ {{0xf4881c71, 0xbbd0055a} },},
+/**/ {{{0x7b5b535c, 0xbf4681fa} },
+/**/ {{0xb98336ea, 0x3bd2b73f} },},
+/**/ {{{0x377c7c71, 0xbf4601e4} },
+/**/ {{0x2ed05089, 0xbbcdcbed} },},
+/**/ {{{0x73c9b0e1, 0xbf4581ce} },
+/**/ {{0x61414697, 0xbbdda0c2} },},
+/**/ {{{0x3041f02a, 0xbf4501b9} },
+/**/ {{0x22f8b33c, 0x3bee5d53} },},
+/**/ {{{0x6ce439ca, 0xbf4481a4} },
+/**/ {{0x9c25c999, 0xbbe5512f} },},
+/**/ {{{0x29af8d47, 0xbf440190} },
+/**/ {{0xa4df0dfd, 0x3b7f48c2} },},
+/**/ {{{0x66a2ea26, 0xbf43817c} },
+/**/ {{0x517febd8, 0x3bd157c0} },},
+/**/ {{{0x23bd4ff0, 0xbf430169} },
+/**/ {{0x0176d244, 0xbbe2e229} },},
+/**/ {{{0x60fdbe33, 0xbf428156} },
+/**/ {{0x175812b3, 0x3be64664} },},
+/**/ {{{0x1e63347c, 0xbf420144} },
+/**/ {{0xd9355524, 0xbbe39ab4} },},
+/**/ {{{0x5becb260, 0xbf418132} },
+/**/ {{0xb6e1edc9, 0x3be74b27} },},
+/**/ {{{0x19993772, 0xbf410121} },
+/**/ {{0x393ab56a, 0xbbaa390b} },},
+/**/ {{{0x5767c34c, 0xbf408110} },
+/**/ {{0xf8c7783b, 0x3bd128e6} },},
+/**/ {{{0x15575589, 0xbf400100} },
+/**/ {{0xf23ef222, 0x3bec8863} },},
+/**/ {{{0xa6cddb8d, 0xbf3f01e0} },
+/**/ {{0xcdd29c3f, 0x3b8a9419} },},
+/**/ {{{0x232b174e, 0xbf3e01c2} },
+/**/ {{0xd5f5b191, 0xbbc7cf55} },},
+/**/ {{{0x9fc45d9e, 0xbf3d01a4} },
+/**/ {{0xb5038e7e, 0x3bddc58f} },},
+/**/ {{{0x1c97adca, 0xbf3c0188} },
+/**/ {{0xbb933e41, 0x3bc0238d} },},
+/**/ {{{0x99a30728, 0xbf3b016c} },
+/**/ {{0xc3c43664, 0xbbabde04} },},
+/**/ {{{0x16e46913, 0xbf3a0152} },
+/**/ {{0x5adc3673, 0x3bafe081} },},
+/**/ {{{0x9459d2eb, 0xbf390138} },
+/**/ {{0xc2a33d26, 0xbbd949da} },},
+/**/ {{{0x12014418, 0xbf380120} },
+/**/ {{0xf76e0326, 0xbbd3acbc} },},
+/**/ {{{0x8fd8bc07, 0xbf370108} },
+/**/ {{0x4cd6ce34, 0x3bdbde09} },},
+/**/ {{{0x0dde3a29, 0xbf3600f2} },
+/**/ {{0x05442a35, 0xbbb0bc28} },},
+/**/ {{{0x8c0fbdf9, 0xbf3500dc} },
+/**/ {{0x0908cbf7, 0x3bd21c68} },},
+/**/ {{{0x0a6b46f4, 0xbf3400c8} },
+/**/ {{0x0f107564, 0xbbdbd35e} },},
+/**/ {{{0x88eed4a1, 0xbf3300b4} },
+/**/ {{0x49a3dcb8, 0xbbc22067} },},
+/**/ {{{0x0798668a, 0xbf3200a2} },
+/**/ {{0xe7c5d0e5, 0x3bcdb7f0} },},
+/**/ {{{0x8665fc3f, 0xbf310090} },
+/**/ {{0xc7f9d69c, 0xbbd00add} },},
+/**/ {{{0x05559559, 0xbf300080} },
+/**/ {{0xa0e20e2f, 0x3bddd332} },},
+/**/ {{{0x08ca62e5, 0xbf2e00e1} },
+/**/ {{0x3a04bb77, 0xbbb15ff9} },},
+/**/ {{{0x0725a061, 0xbf2c00c4} },
+/**/ {{0xcc052f3e, 0x3bc88ab0} },},
+/**/ {{{0x05b8e275, 0xbf2a00a9} },
+/**/ {{0xf5f3cbcf, 0xbbcbba1a} },},
+/**/ {{{0x04802882, 0xbf280090} },
+/**/ {{0xa5bd7bd0, 0x3bcec900} },},
+/**/ {{{0x037771ef, 0xbf260079} },
+/**/ {{0x9b7b54fa, 0x3bb77ea0} },},
+/**/ {{{0x029abe33, 0xbf240064} },
+/**/ {{0x3ae68d18, 0xbbc1bbf0} },},
+/**/ {{{0x01e60cd1, 0xbf220051} },
+/**/ {{0x2b45cfcd, 0x3bb1dcd9} },},
+/**/ {{{0x01555d56, 0xbf200040} },
+/**/ {{0x863f53f6, 0x3bcddd88} },},
+/**/ {{{0x01c95eb7, 0xbf1c0062} },
+/**/ {{0xaa4dfd9a, 0x3bbd88f7} },},
+/**/ {{{0x01200510, 0xbf180048} },
+/**/ {{0x4f3db50b, 0xbb984d46} },},
+/**/ {{{0x00a6ad1c, 0xbf140032} },
+/**/ {{0x28ff1135, 0x3bb2e44b} },},
+/**/ {{{0x00555655, 0xbf100020} },
+/**/ {{0xccd5f17f, 0xbbb62224} },},
+/**/ {{{0x004800a2, 0xbf080024} },
+/**/ {{0x8d690542, 0xbb484d09} },},
+/**/ {{{0x00155575, 0xbf000010} },
+/**/ {{0x37779c0a, 0xbba56222} },},
+/**/ {{{0x00055559, 0xbef00008} },
+/**/ {{0x22cccd5f, 0xbb955622} },},
+/**/ {{{0x00000000, 0x00000000} },
+/**/ {{0x00000000, 0x00000000} },},
+/**/ {{{0x000aaaa3, 0x3eeffff0} },
+/**/ {{0xbd110fec, 0xbb8553bb} },},
+/**/ {{{0x002aaa6b, 0x3effffe0} },
+/**/ {{0xe6661d42, 0xbb953bbb} },},
+/**/ {{{0x0047ff5e, 0x3f07ffdc} },
+/**/ {{0x0d69020e, 0x3b484c90} },},
+/**/ {{{0x00aaa8ab, 0x3f0fffc0} },
+/**/ {{0x10fec82c, 0xbba3bbc1} },},
+/**/ {{{0x00a6a83a, 0x3f13ffce} },
+/**/ {{0x81546808, 0xbbb2e45f} },},
+/**/ {{{0x011ffaf0, 0x3f17ffb8} },
+/**/ {{0x4f3d9b6a, 0x3b984c53} },},
+/**/ {{{0x01c94bf5, 0x3f1bff9e} },
+/**/ {{0xdaa368ee, 0xbbbd8990} },},
+/**/ {{{0x02aa9aab, 0x3f1fff80} },
+/**/ {{0x78af0afc, 0x3b910e66} },},
+/**/ {{{0x01e5f330, 0x3f21ffaf} },
+/**/ {{0x26467402, 0xbbb1df8d} },},
+/**/ {{{0x029a9723, 0x3f23ff9c} },
+/**/ {{0x303b23b1, 0x3bc1b965} },},
+/**/ {{{0x037738be, 0x3f25ff87} },
+/**/ {{0x53d3dc06, 0xbbb787a3} },},
+/**/ {{{0x047fd782, 0x3f27ff70} },
+/**/ {{0xa5c0aff0, 0xbbced098} },},
+/**/ {{{0x05b872e4, 0x3f29ff57} },
+/**/ {{0x81c30d42, 0x3bcbadd4} },},
+/**/ {{{0x07250a51, 0x3f2bff3c} },
+/**/ {{0xd6bad8c1, 0xbbc89dd6} },},
+/**/ {{{0x08c99d24, 0x3f2dff1f} },
+/**/ {{0xaede8ad0, 0x3bb12609} },},
+/**/ {{{0x0aaa2ab1, 0x3f2fff00} },
+/**/ {{0x4dc4e3dc, 0x3ba0bbc0} },},
+/**/ {{{0x8665591f, 0x3f30ff6f} },
+/**/ {{0x80357b54, 0xbbd013d3} },},
+/**/ {{{0x07979982, 0x3f31ff5e} },
+/**/ {{0x4817ebcd, 0xbbce0e70} },},
+/**/ {{{0x88edd619, 0x3f32ff4b} },
+/**/ {{0xc582abc3, 0xbbd72b9e} },},
+/**/ {{{0x0a6a0e74, 0x3f33ff38} },
+/**/ {{0xb95bc1fe, 0x3bdb81fc} },},
+/**/ {{{0x8c0e4220, 0x3f34ff23} },
+/**/ {{0x9b549aae, 0x3bcaed12} },},
+/**/ {{{0x0ddc70a1, 0x3f35ff0e} },
+/**/ {{0xd97a3c05, 0x3bacf6f3} },},
+/**/ {{{0x8fd69976, 0x3f36fef7} },
+/**/ {{0x6f810a3c, 0x3bab2dcf} },},
+/**/ {{{0x11febc18, 0x3f37fee0} },
+/**/ {{0xf5d3f323, 0x3bd2b9bc} },},
+/**/ {{{0x9456d7fb, 0x3f38fec7} },
+/**/ {{0x6eaa1d6a, 0xbbbfb258} },},
+/**/ {{{0x16e0ec8b, 0x3f39feae} },
+/**/ {{0xceeb34b1, 0xbbb6137a} },},
+/**/ {{{0x999ef930, 0x3f3afe93} },
+/**/ {{0xdc639b08, 0xbbde70e0} },},
+/**/ {{{0x1c92fd4a, 0x3f3bfe78} },
+/**/ {{0x713cc126, 0xbbc4ed10} },},
+/**/ {{{0x9fbef835, 0x3f3cfe5b} },
+/**/ {{0xcc0e81bd, 0xbb873d63} },},
+/**/ {{{0x2324e946, 0x3f3dfe3e} },
+/**/ {{0x62dd5deb, 0x3bc09164} },},
+/**/ {{{0xa6c6cfcc, 0x3f3efe1f} },
+/**/ {{0x3512d15c, 0x3bdac2da} },},
+/**/ {{{0x2aa6ab11, 0x3f3ffe00} },
+/**/ {{0x62cc632d, 0x3b999e2b} },},
+/**/ {{{0xd7633d2c, 0x3f407eef} },
+/**/ {{0x63ff6024, 0xbbebc98b} },},
+/**/ {{{0x19941e6e, 0x3f40fedf} },
+/**/ {{0xe0aa6338, 0xbbb194c2} },},
+/**/ {{{0xdbe6f8eb, 0x3f417ecd} },
+/**/ {{0x57b0f571, 0x3be4241b} },},
+/**/ {{{0x1e5ccc3c, 0x3f41febc} },
+/**/ {{0x895d3592, 0x3bdc657d} },},
+/**/ {{{0xe0f697f6, 0x3f427ea9} },
+/**/ {{0x1c0ec17c, 0x3be35a5d} },},
+/**/ {{{0x23b55bac, 0x3f42fe97} },
+/**/ {{0x3e538464, 0x3bd6cfb7} },},
+/**/ {{{0xe69a16ed, 0x3f437e83} },
+/**/ {{0x7cef2478, 0x3bee96f7} },},
+/**/ {{{0x29a5c947, 0x3f43fe70} },
+/**/ {{0xbf46e36a, 0xbbd4d578} },},
+/**/ {{{0xecd97242, 0x3f447e5b} },
+/**/ {{0x3ff7dd44, 0xbbc9eb66} },},
+/**/ {{{0x30361165, 0x3f44fe47} },
+/**/ {{0x7e93f2fd, 0x3be400d7} },},
+/**/ {{{0xf3bca635, 0x3f457e31} },
+/**/ {{0xd375017f, 0xbbe0e2a2} },},
+/**/ {{{0x376e3031, 0x3f45fe1c} },
+/**/ {{0x8a5ae7f6, 0xbbd524eb} },},
+/**/ {{{0xfb4baed7, 0x3f467e05} },
+/**/ {{0x4e85c4e9, 0x3be204fb} },},
+/**/ {{{0x3f5621a3, 0x3f46fdef} },
+/**/ {{0x34886d52, 0xbbdf09d7} },},
+/**/ {{{0x038e880b, 0x3f477dd8} },
+/**/ {{0x14e596a3, 0xbbb8900e} },},
+/**/ {{{0x47f5e185, 0x3f47fdc0} },
+/**/ {{0x57d202d3, 0xbbebfa5c} },},
+/**/ {{{0x0c8d2d81, 0x3f487da8} },
+/**/ {{0xd68c0614, 0x3be2f6ae} },},
+/**/ {{{0x51556b70, 0x3f48fd8f} },
+/**/ {{0xe08fd201, 0xbbd0f4f2} },},
+/**/ {{{0x164f9abc, 0x3f497d76} },
+/**/ {{0xa871af60, 0x3b5296b7} },},
+/**/ {{{0x5b7cbace, 0x3f49fd5c} },
+/**/ {{0x9f17d42d, 0x3beb6ed4} },},
+/**/ {{{0x20ddcb0d, 0x3f4a7d42} },
+/**/ {{0x67c30397, 0xbbcb1149} },},
+/**/ {{{0x6673cada, 0x3f4afd27} },
+/**/ {{0x45da594f, 0x3bd32225} },},
+/**/ {{{0x2c3fb996, 0x3f4b7d0c} },
+/**/ {{0x208d4630, 0xbbb68893} },},
+/**/ {{{0x7242969d, 0x3f4bfcf0} },
+/**/ {{0x2b3efe1c, 0x3bc5db4d} },},
+/**/ {{{0x387d6149, 0x3f4c7cd4} },
+/**/ {{0xed57d98a, 0x3be46eff} },},
+/**/ {{{0x7ef118f1, 0x3f4cfcb7} },
+/**/ {{0x06f300fb, 0x3becc554} },},
+/**/ {{{0x459ebce9, 0x3f4d7c9a} },
+/**/ {{0x13638eb6, 0x3be1d251} },},
+/**/ {{{0x8c874c82, 0x3f4dfc7c} },
+/**/ {{0xd57a176f, 0xbbe863e9} },},
+/**/ {{{0x53abc708, 0x3f4e7c5e} },
+/**/ {{0x9528e50d, 0x3be2d95c} },},
+/**/ {{{0x9b0d2bc8, 0x3f4efc3f} },
+/**/ {{0xa5f5b8b7, 0x3bd1e8e8} },},
+/**/ {{{0x62ac7a09, 0x3f4f7c20} },
+/**/ {{0x17802a46, 0x3b5c8123} },},
+/**/ {{{0xaa8ab110, 0x3f4ffc00} },
+/**/ {{0xeb9b6cdb, 0xbbe0fecb} },},
+/**/ {{{0x3954680f, 0x3f503df0} },
+/**/ {{0x1c693678, 0x3bdac89b} },},
+/**/ {{{0xdd83eb3a, 0x3f507ddf} },
+/**/ {{0x0a75ad5f, 0xbbf638f6} },},
+/**/ {{{0x41d461a5, 0x3f50bdcf} },
+/**/ {{0x45f05b10, 0x3bfd4bc9} },},
+/**/ {{{0x66464aef, 0x3f50fdbe} },
+/**/ {{0x6abbf59c, 0xbbbd0554} },},
+/**/ {{{0x4ada26b1, 0x3f513dad} },
+/**/ {{0x6036fe6f, 0x3be38c65} },},
+/**/ {{{0xef907485, 0x3f517d9b} },
+/**/ {{0xf158bbc3, 0x3bfdc8a1} },},
+/**/ {{{0x5469b404, 0x3f51bd8a} },
+/**/ {{0x55632e3f, 0xbbdea231} },},
+/**/ {{{0x796664c3, 0x3f51fd78} },
+/**/ {{0x2edb73c2, 0xbbe00849} },},
+/**/ {{{0x5e870657, 0x3f523d66} },
+/**/ {{0x0789343e, 0x3bfba943} },},
+/**/ {{{0x03cc1855, 0x3f527d54} },
+/**/ {{0xeafafc52, 0x3bc5f644} },},
+/**/ {{{0x69361a4e, 0x3f52bd41} },
+/**/ {{0xa4a6e79f, 0xbbf2f743} },},
+/**/ {{{0x8ec58bd2, 0x3f52fd2e} },
+/**/ {{0x5ceb1abf, 0xbbd4f786} },},
+/**/ {{{0x747aec71, 0x3f533d1b} },
+/**/ {{0x49dc497d, 0xbbf369e3} },},
+/**/ {{{0x1a56bbb8, 0x3f537d08} },
+/**/ {{0x3726b14a, 0xbbfc5e6f} },},
+/**/ {{{0x80597933, 0x3f53bcf4} },
+/**/ {{0x808f75a7, 0xbbfe8b82} },},
+/**/ {{{0xa683a46c, 0x3f53fce0} },
+/**/ {{0x9cd06ae6, 0x3be02719} },},
+/**/ {{{0x8cd5bced, 0x3f543ccc} },
+/**/ {{0x758f80f8, 0x3bf9f98d} },},
+/**/ {{{0x3350423e, 0x3f547cb8} },
+/**/ {{0x48401f45, 0xbbd79c3d} },},
+/**/ {{{0x99f3b3e4, 0x3f54bca3} },
+/**/ {{0x2fba8948, 0xbbf422b8} },},
+/**/ {{{0xc0c09163, 0x3f54fc8e} },
+/**/ {{0xf4044be8, 0x3bf32cc1} },},
+/**/ {{{0xa7b75a40, 0x3f553c79} },
+/**/ {{0xf2249008, 0xbbe72cac} },},
+/**/ {{{0x4ed88dfb, 0x3f557c64} },
+/**/ {{0x459a204f, 0xbbe7183c} },},
+/**/ {{{0xb624ac14, 0x3f55bc4e} },
+/**/ {{0xba26d3d7, 0x3bf8aa64} },},
+/**/ {{{0xdd9c340b, 0x3f55fc38} },
+/**/ {{0x45fa193c, 0x3bdbb2ff} },},
+/**/ {{{0xc53fa55c, 0x3f563c22} },
+/**/ {{0x0484397b, 0x3bd67249} },},
+/**/ {{{0x6d0f7f83, 0x3f567c0c} },
+/**/ {{0xf1e73188, 0xbbd183d7} },},
+/**/ {{{0xd50c41fa, 0x3f56bbf5} },
+/**/ {{0x4ab68187, 0xbbef433d} },},
+/**/ {{{0xfd366c39, 0x3f56fbde} },
+/**/ {{0x66e09e58, 0x3be796b8} },},
+/**/ {{{0xe58e7db8, 0x3f573bc7} },
+/**/ {{0x81e6e7e6, 0x3bf65ec5} },},
+/**/ {{{0x8e14f5ed, 0x3f577bb0} },
+/**/ {{0xa9463a9c, 0xbbdb944d} },},
+/**/ {{{0xf6ca544b, 0x3f57bb98} },
+/**/ {{0xc5eda344, 0xbbc396ec} },},
+/**/ {{{0x1faf1845, 0x3f57fb81} },
+/**/ {{0xbb624f97, 0x3beb9e6d} },},
+/**/ {{{0x08c3c14d, 0x3f583b69} },
+/**/ {{0xe6295bf2, 0xbbe6ee13} },},
+/**/ {{{0xb208ced1, 0x3f587b50} },
+/**/ {{0x6ca19875, 0x3bfcf1a5} },},
+/**/ {{{0x1b7ec041, 0x3f58bb38} },
+/**/ {{0x07b4fc7e, 0x3bf2d181} },},
+/**/ {{{0x45261509, 0x3f58fb1f} },
+/**/ {{0x21bad336, 0x3bc419c5} },},
+/**/ {{{0x2eff4c94, 0x3f593b06} },
+/**/ {{0x700b305b, 0xbbdc2a4c} },},
+/**/ {{{0xd90ae64c, 0x3f597aec} },
+/**/ {{0xa23f359c, 0xbbfc53d3} },},
+/**/ {{{0x43496198, 0x3f59bad3} },
+/**/ {{0xaed6b50f, 0x3bf0c270} },},
+/**/ {{{0x6dbb3de1, 0x3f59fab9} },
+/**/ {{0x7a8be031, 0xbbf11464} },},
+/**/ {{{0x5860fa8a, 0x3f5a3a9f} },
+/**/ {{0x470dbe32, 0x3beae9e7} },},
+/**/ {{{0x033b16f8, 0x3f5a7a85} },
+/**/ {{0xda1f8579, 0x3bfc4721} },},
+/**/ {{{0x6e4a128e, 0x3f5aba6a} },
+/**/ {{0x029258ce, 0xbbf41852} },},
+/**/ {{{0x998e6cab, 0x3f5afa4f} },
+/**/ {{0x2eb18782, 0xbbf28584} },},
+/**/ {{{0x8508a4af, 0x3f5b3a34} },
+/**/ {{0x23241a2c, 0xbbea7970} },},
+/**/ {{{0x30b939f8, 0x3f5b7a19} },
+/**/ {{0x600551b6, 0xbbf1d8db} },},
+/**/ {{{0x9ca0abe2, 0x3f5bb9fd} },
+/**/ {{0x8c26cc71, 0xbbeaa412} },},
+/**/ {{{0xc8bf79c8, 0x3f5bf9e1} },
+/**/ {{0x30427cfc, 0xbbe7f81b} },},
+/**/ {{{0xb5162303, 0x3f5c39c5} },
+/**/ {{0xd1f134e1, 0x3bd9ec5f} },},
+/**/ {{{0x61a526eb, 0x3f5c79a9} },
+/**/ {{0x8980e47d, 0x3bff0cb0} },},
+/**/ {{{0xce6d04d7, 0x3f5cb98c} },
+/**/ {{0xe84ca4e2, 0x3bf35aca} },},
+/**/ {{{0xfb6e3c1b, 0x3f5cf96f} },
+/**/ {{0x1b0bd69f, 0x3bf9b1b8} },},
+/**/ {{{0xe8a94c0b, 0x3f5d3952} },
+/**/ {{0x3ce51832, 0x3be21310} },},
+/**/ {{{0x961eb3f8, 0x3f5d7935} },
+/**/ {{0x840c58ce, 0x3bf90786} },},
+/**/ {{{0x03cef334, 0x3f5db918} },
+/**/ {{0xf2dfb3f4, 0xbbfe0048} },},
+/**/ {{{0x31ba890b, 0x3f5df8fa} },
+/**/ {{0x3e295bec, 0x3bfcf652} },},
+/**/ {{{0x1fe1f4ce, 0x3f5e38dc} },
+/**/ {{0x151c9300, 0xbbfc5ebe} },},
+/**/ {{{0xce45b5c6, 0x3f5e78bd} },
+/**/ {{0x8a25b9c7, 0xbbef2cc4} },},
+/**/ {{{0x3ce64b3e, 0x3f5eb89f} },
+/**/ {{0xa6fea7bd, 0x3bfe6d27} },},
+/**/ {{{0x6bc43481, 0x3f5ef880} },
+/**/ {{0x914a6dab, 0xbbf68037} },},
+/**/ {{{0x5adff0d4, 0x3f5f3861} },
+/**/ {{0xf909e0e6, 0xbbf1d2f3} },},
+/**/ {{{0x0a39ff7e, 0x3f5f7842} },
+/**/ {{0xff1e1f71, 0xbbf64661} },},
+/**/ {{{0x79d2dfc3, 0x3f5fb822} },
+/**/ {{0x5a6f9e9a, 0xbbd76ce8} },},
+/**/ {{{0xa9ab10e6, 0x3f5ff802} },
+/**/ {{0xa153e3b2, 0x3bfe29e3} },},
+/**/ {{{0x4ce18915, 0x3f601bf1} },
+/**/ {{0xa3a73044, 0xbbe57c28} },},
+/**/ {{{0x250db166, 0x3f603be1} },
+/**/ {{0xc1ad9590, 0x3c0fd271} },},
+/**/ {{{0xdd5a4107, 0x3f605bd0} },
+/**/ {{0xc424c676, 0x3bfe4b5d} },},
+/**/ {{{0x75c77796, 0x3f607bc0} },
+/**/ {{0xc0eff1ba, 0xbc068804} },},
+/**/ {{{0xee5594b0, 0x3f609baf} },
+/**/ {{0x51dbded5, 0xbc0ff798} },},
+/**/ {{{0x4704d7f2, 0x3f60bb9f} },
+/**/ {{0x2d5aba70, 0xbbf70ef4} },},
+/**/ {{{0x7fd580f9, 0x3f60db8e} },
+/**/ {{0x7ae804b5, 0xbbeccb65} },},
+/**/ {{{0x98c7cf60, 0x3f60fb7d} },
+/**/ {{0x1775134d, 0x3bfede2f} },},
+/**/ {{{0x91dc02c3, 0x3f611b6c} },
+/**/ {{0x91ca4a67, 0xbc04d41e} },},
+/**/ {{{0x6b125aba, 0x3f613b5b} },
+/**/ {{0x4a12201d, 0x3bfe6d0c} },},
+/**/ {{{0x246b16e0, 0x3f615b4a} },
+/**/ {{0x4d4238d3, 0x3bfe507d} },},
+/**/ {{{0xbde676cd, 0x3f617b38} },
+/**/ {{0x0640462a, 0x3bfe0272} },},
+/**/ {{{0x3784ba19, 0x3f619b27} },
+/**/ {{0x02285659, 0x3bd94ab3} },},
+/**/ {{{0x9146205b, 0x3f61bb15} },
+/**/ {{0x1cc35b7b, 0xbbff1e2e} },},
+/**/ {{{0xcb2ae929, 0x3f61db03} },
+/**/ {{0x12f6bf8d, 0xbc03ee8e} },},
+/**/ {{{0xe5335418, 0x3f61faf1} },
+/**/ {{0x7b7d619b, 0x3c0bae5f} },},
+/**/ {{{0xdf5fa0bf, 0x3f621adf} },
+/**/ {{0xb3b731b0, 0xbbf5546a} },},
+/**/ {{{0xb9b00eb0, 0x3f623acd} },
+/**/ {{0x105fd253, 0xbbafb2b0} },},
+/**/ {{{0x7424dd7f, 0x3f625abb} },
+/**/ {{0xca53444b, 0x3c011647} },},
+/**/ {{{0x0ebe4cbf, 0x3f627aa9} },
+/**/ {{0x592f3be8, 0x3c01678f} },},
+/**/ {{{0x897c9c02, 0x3f629a96} },
+/**/ {{0x4347451d, 0xbbef2b12} },},
+/**/ {{{0xe4600ad8, 0x3f62ba83} },
+/**/ {{0xb2a477bc, 0x3bfb5bb7} },},
+/**/ {{{0x1f68d8d3, 0x3f62da71} },
+/**/ {{0x7a5822e4, 0xbc0590e1} },},
+/**/ {{{0x3a974581, 0x3f62fa5e} },
+/**/ {{0x53123101, 0xbbf0f2e5} },},
+/**/ {{{0x35eb9072, 0x3f631a4b} },
+/**/ {{0x0e3f5fde, 0xbc018db4} },},
+/**/ {{{0x1165f933, 0x3f633a38} },
+/**/ {{0x8d0afb38, 0x3c0921d5} },},
+/**/ {{{0xcd06bf53, 0x3f635a24} },
+/**/ {{0xb5791b80, 0x3c01f6ba} },},
+/**/ {{{0x68ce225e, 0x3f637a11} },
+/**/ {{0xa1894236, 0x3bde2af8} },},
+/**/ {{{0xe4bc61e0, 0x3f6399fd} },
+/**/ {{0xd0f06ff3, 0xbc062a48} },},
+/**/ {{{0x40d1bd63, 0x3f63b9ea} },
+/**/ {{0x4b4f9c11, 0x3bffc80c} },},
+/**/ {{{0x7d0e7473, 0x3f63d9d6} },
+/**/ {{0x6a92c891, 0x3c02219b} },},
+/**/ {{{0x9972c699, 0x3f63f9c2} },
+/**/ {{0x790ade9e, 0x3c0d3590} },},
+/**/ {{{0x95fef35f, 0x3f6419ae} },
+/**/ {{0x792a458c, 0xbc01c279} },},
+/**/ {{{0x72b33a4b, 0x3f64399a} },
+/**/ {{0x327bffae, 0x3c02ce64} },},
+/**/ {{{0x2f8fdae7, 0x3f645986} },
+/**/ {{0xd231155c, 0xbc070aec} },},
+/**/ {{{0xcc9514b7, 0x3f647971} },
+/**/ {{0xe4bbf776, 0x3c0f373d} },},
+/**/ {{{0x49c32744, 0x3f64995d} },
+/**/ {{0xbf22b2a7, 0xbbf6d7e5} },},
+/**/ {{{0xa71a5211, 0x3f64b948} },
+/**/ {{0x64fe2936, 0xbbedec69} },},
+/**/ {{{0xe49ad4a3, 0x3f64d933} },
+/**/ {{0xabee4257, 0x3bf5fc4b} },},
+/**/ {{{0x0244ee7e, 0x3f64f91f} },
+/**/ {{0x3cd1474f, 0x3c0c6fe3} },},
+/**/ {{{0x0018df26, 0x3f65190a} },
+/**/ {{0xd11e7fa5, 0xbc023957} },},
+/**/ {{{0xde16e61b, 0x3f6538f4} },
+/**/ {{0x55380346, 0x3c006c31} },},
+/**/ {{{0x9c3f42e1, 0x3f6558df} },
+/**/ {{0xc4a5134c, 0xbc09b7d4} },},
+/**/ {{{0x3a9234f7, 0x3f6578ca} },
+/**/ {{0x2772c19c, 0xbc0e3f10} },},
+/**/ {{{0xb90ffbdd, 0x3f6598b4} },
+/**/ {{0x5592b468, 0x3be6f110} },},
+/**/ {{{0x17b8d714, 0x3f65b89f} },
+/**/ {{0xb251ace2, 0xbc0a5fea} },},
+/**/ {{{0x568d0619, 0x3f65d889} },
+/**/ {{0x315da285, 0xbc0aacc9} },},
+/**/ {{{0x758cc86a, 0x3f65f873} },
+/**/ {{0xba64d81a, 0xbbeb0782} },},
+/**/ {{{0x74b85d85, 0x3f66185d} },
+/**/ {{0x8e1eb3fa, 0xbc09b459} },},
+/**/ {{{0x541004e5, 0x3f663847} },
+/**/ {{0x1d86e863, 0x3bce9c22} },},
+/**/ {{{0x1393fe07, 0x3f665831} },
+/**/ {{0xcf37ee90, 0xbbfbeb77} },},
+/**/ {{{0xb3448865, 0x3f66781a} },
+/**/ {{0xc252e3c9, 0xbc02dc68} },},
+/**/ {{{0x3321e379, 0x3f669804} },
+/**/ {{0xb40b3741, 0xbbe73a0b} },},
+ };
+
+#endif
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/upow.h b/libc/sysdeps/ieee754/dbl-64/upow.h
new file mode 100644
index 000000000..1db748319
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/upow.h
@@ -0,0 +1,81 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/******************************************************************/
+/* */
+/* MODULE_NAME:upow.h */
+/* */
+/* common data and variables prototype and definition */
+/******************************************************************/
+
+#ifndef UPOW_H
+#define UPOW_H
+
+#include "mydefs.h"
+
+#ifdef BIG_ENDI
+ const static mynumber
+/**/ nZERO = {{0x80000000, 0}}, /* -0.0 */
+/**/ INF = {{0x7ff00000, 0x00000000}}, /* INF */
+/**/ nINF = {{0xfff00000, 0x00000000}}, /* -INF */
+/**/ NaNQ = {{0x7ff80000, 0x00000000}}, /* NaNQ */
+/**/ sqrt_2 = {{0x3ff6a09e, 0x667f3bcc}}, /* sqrt(2) */
+/**/ ln2a = {{0x3fe62e42, 0xfefa3800}}, /* ln(2) 43 bits */
+/**/ ln2b = {{0x3d2ef357, 0x93c76730}}, /* ln(2)-ln2a */
+/**/ bigu = {{0x4297ffff, 0xfffffd2c}}, /* 1.5*2**42 -724*2**-10 */
+/**/ bigv = {{0x4207ffff, 0xfff8016a}}, /* 1.5*2**33-1+362*2**-19 */
+/**/ t52 = {{0x43300000, 0x00000000}}, /* 2**52 */
+/**/ two52e = {{0x43300000, 0x000003ff}}; /* 2**52' */
+
+#else
+#ifdef LITTLE_ENDI
+ const static mynumber
+/**/ nZERO = {{0, 0x80000000}}, /* -0.0 */
+/**/ INF = {{0x00000000, 0x7ff00000}}, /* INF */
+/**/ nINF = {{0x00000000, 0xfff00000}}, /* -INF */
+/**/ NaNQ = {{0x00000000, 0x7ff80000}}, /* NaNQ */
+/**/ sqrt_2 = {{0x667f3bcc, 0x3ff6a09e}}, /* sqrt(2) */
+/**/ ln2a = {{0xfefa3800, 0x3fe62e42}}, /* ln(2) 43 bits */
+/**/ ln2b = {{0x93c76730, 0x3d2ef357}}, /* ln(2)-ln2a */
+/**/ bigu = {{0xfffffd2c, 0x4297ffff}}, /* 1.5*2**42 -724*2**-10 */
+/**/ bigv = {{0xfff8016a, 0x4207ffff}}, /* 1.5*2**33-1+362*2**-19 */
+/**/ t52 = {{0x00000000, 0x43300000}}, /* 2**52 */
+/**/ two52e = {{0x000003ff, 0x43300000}}; /* 2**52' */
+
+#endif
+#endif
+
+const static double p2=-0.5, p3 = 3.3333333333333333333e-1, p4 = -0.25,
+ q2 = -0.5, q3 = 3.3333333333331404e-01, q4 = -2.4999999999996436e-01,
+ q5 = 2.0000010500004459e-01, q6 = -1.6666678916688004e-01,
+ r3 = 3.33333333333333333372884096563030E-01,
+ r4 = -2.50000000000000000213574153875908E-01,
+ r5 = 1.99999999999683593814072199830603E-01,
+ r6 = -1.66666666666065494878165510225378E-01,
+ r7 = 1.42857517857114380606360005067609E-01,
+ r8 = -1.25000449999974370683775964001702E-01,
+ s3 = 0.333251953125000000e0,
+ ss3 = 8.138020833333333333e-05,
+ s4 = -2.500000000000000000e-01,
+ s5 = 1.999999999999960937e-01,
+ s6 = -1.666666666666592447e-01,
+ s7 = 1.428571845238194705e-01,
+ s8 = -1.250000500000149097e-01;
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/upow.tbl b/libc/sysdeps/ieee754/dbl-64/upow.tbl
new file mode 100644
index 000000000..acad6bcc8
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/upow.tbl
@@ -0,0 +1,10189 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/****************************************************************/
+/* TABLES FOR THE upow() FUNCTION */
+/****************************************************************/
+
+
+
+#ifdef BIG_ENDI
+static const union {int4 i[5800]; double x[2900];} ui = { .i = {
+/**/ 0x3FF6A000, 0x00000000,
+/**/ 0x3F33CD15, 0x3729043E,
+/**/ 0xBFD63003, 0x0B3AB000,
+/**/ 0x3D2DB623, 0xE731AE00,
+/**/ 0x3FF69800, 0x00000000,
+/**/ 0x3F33F349, 0xCC7267D0,
+/**/ 0xBFD61965, 0xCDB03000,
+/**/ 0x3D2F08AD, 0x603C488E,
+/**/ 0x3FF69000, 0x00000000,
+/**/ 0x3F3473A8, 0x8D0BFD2E,
+/**/ 0xBFD602D0, 0x8AF09000,
+/**/ 0xBD1EBE91, 0x76DF3F65,
+/**/ 0x3FF68800, 0x00000000,
+/**/ 0x3F354DD2, 0x390B9ED0,
+/**/ 0xBFD5EC43, 0x3D5C3000,
+/**/ 0xBD36B71A, 0x1229D17F,
+/**/ 0x3FF68000, 0x00000000,
+/**/ 0x3F368168, 0x16816817,
+/**/ 0xBFD5D5BD, 0xDF596000,
+/**/ 0x3D0A0B2A, 0x08A465DC,
+/**/ 0x3FF67800, 0x00000000,
+/**/ 0x3F380E0B, 0xF08C7765,
+/**/ 0xBFD5BF40, 0x6B544000,
+/**/ 0x3D227023, 0xEB68981C,
+/**/ 0x3FF67000, 0x00000000,
+/**/ 0x3F39F360, 0x16719F36,
+/**/ 0xBFD5A8CA, 0xDBBEE000,
+/**/ 0x3CF7C79B, 0x0AF7ECF8,
+/**/ 0x3FF66800, 0x00000000,
+/**/ 0x3F3C3107, 0x5AB40167,
+/**/ 0xBFD5925D, 0x2B113000,
+/**/ 0x3D369BF5, 0xA7A56F34,
+/**/ 0x3FF66000, 0x00000000,
+/**/ 0x3F3EC6A5, 0x122F9016,
+/**/ 0xBFD57BF7, 0x53C8D000,
+/**/ 0xBD1FADED, 0xEE5D40EF,
+/**/ 0x3FF65C00, 0x00000000,
+/**/ 0xBF3E4C22, 0xECCA9097,
+/**/ 0xBFD56599, 0x50695000,
+/**/ 0xBD14C5FD, 0x2BADC774,
+/**/ 0x3FF65400, 0x00000000,
+/**/ 0xBF3B07AC, 0x4B55CC62,
+/**/ 0xBFD54F43, 0x1B7BE000,
+/**/ 0xBD1A8954, 0xC0910952,
+/**/ 0x3FF64C00, 0x00000000,
+/**/ 0xBF376C52, 0x32DA090E,
+/**/ 0xBFD538F4, 0xAF8F7000,
+/**/ 0xBD27EC02, 0xE45547CE,
+/**/ 0x3FF64400, 0x00000000,
+/**/ 0xBF337A6F, 0x4DE9BD38,
+/**/ 0xBFD522AE, 0x0738A000,
+/**/ 0xBD2EBE70, 0x8164C759,
+/**/ 0x3FF63C00, 0x00000000,
+/**/ 0xBF2E64BB, 0x923C708B,
+/**/ 0xBFD50C6F, 0x1D11C000,
+/**/ 0x3D3A0E6B, 0x7E827C2C,
+/**/ 0x3FF63400, 0x00000000,
+/**/ 0xBF2528EE, 0xA7E43FD4,
+/**/ 0xBFD4F637, 0xEBBAA000,
+/**/ 0x3D3FC158, 0xCB3124B9,
+/**/ 0x3FF62C00, 0x00000000,
+/**/ 0xBF168454, 0x86689DF7,
+/**/ 0xBFD4E008, 0x6DD8C000,
+/**/ 0x3D34D692, 0xA1E44788,
+/**/ 0x3FF62400, 0x00000000,
+/**/ 0xBED623FA, 0x77016240,
+/**/ 0xBFD4C9E0, 0x9E173000,
+/**/ 0x3D2E2089, 0x1B0AD8A4,
+/**/ 0x3FF61C00, 0x00000000,
+/**/ 0x3F151300, 0x58715130,
+/**/ 0xBFD4B3C0, 0x77268000,
+/**/ 0x3D165B46, 0x81052B9F,
+/**/ 0x3FF61400, 0x00000000,
+/**/ 0x3F266D06, 0x35D2754E,
+/**/ 0xBFD49DA7, 0xF3BCC000,
+/**/ 0xBD307B33, 0x4DAF4B9A,
+/**/ 0x3FF60C00, 0x00000000,
+/**/ 0x3F317C61, 0xDA197F23,
+/**/ 0xBFD48797, 0x0E958000,
+/**/ 0xBD3DC1B8, 0x465CF25F,
+/**/ 0x3FF60400, 0x00000000,
+/**/ 0x3F381605, 0x81605816,
+/**/ 0xBFD4718D, 0xC271C000,
+/**/ 0xBD306C18, 0xFB4C14C5,
+/**/ 0x3FF5FC00, 0x00000000,
+/**/ 0x3F3F0317, 0xB5C6F559,
+/**/ 0xBFD45B8C, 0x0A17E000,
+/**/ 0x3D0D9120, 0xE7D0A853,
+/**/ 0x3FF5F800, 0x00000000,
+/**/ 0xBF39BCBD, 0x6D2041E3,
+/**/ 0xBFD44591, 0xE053A000,
+/**/ 0x3D06E958, 0x92923D88,
+/**/ 0x3FF5F000, 0x00000000,
+/**/ 0xBF3229CF, 0x5604CC40,
+/**/ 0xBFD42F9F, 0x3FF62000,
+/**/ 0xBD390644, 0x0F7D3354,
+/**/ 0x3FF5E800, 0x00000000,
+/**/ 0xBF2488E5, 0xFD431489,
+/**/ 0xBFD419B4, 0x23D5F000,
+/**/ 0x3D3CE379, 0x226DE3EC,
+/**/ 0x3FF5E000, 0x00000000,
+/**/ 0xBF0067E7, 0x6424E9C9,
+/**/ 0xBFD403D0, 0x86CEA000,
+/**/ 0xBD3E6EF5, 0x74487308,
+/**/ 0x3FF5D800, 0x00000000,
+/**/ 0x3F19F0FB, 0x38A94D24,
+/**/ 0xBFD3EDF4, 0x63C17000,
+/**/ 0x3D3F067C, 0x297F2C3F,
+/**/ 0x3FF5D000, 0x00000000,
+/**/ 0x3F2EADD9, 0x23CAD2AA,
+/**/ 0xBFD3D81F, 0xB5947000,
+/**/ 0x3D222C7C, 0x2A9D37A4,
+/**/ 0x3FF5C800, 0x00000000,
+/**/ 0x3F3882B9, 0x31057262,
+/**/ 0xBFD3C252, 0x77333000,
+/**/ 0xBD183B54, 0xB606BD5C,
+/**/ 0x3FF5C400, 0x00000000,
+/**/ 0xBF3E00AE, 0x10FFA8F8,
+/**/ 0xBFD3AC8C, 0xA38E6000,
+/**/ 0x3D2D0BEF, 0xBC02BE4A,
+/**/ 0x3FF5BC00, 0x00000000,
+/**/ 0xBF34339B, 0x8056EAF3,
+/**/ 0xBFD396CE, 0x359BC000,
+/**/ 0x3D05839C, 0x5663663D,
+/**/ 0x3FF5B400, 0x00000000,
+/**/ 0xBF242CC1, 0xF31D7FD5,
+/**/ 0xBFD38117, 0x28565000,
+/**/ 0x3D2A71E4, 0x93A0702B,
+/**/ 0x3FF5AC00, 0x00000000,
+/**/ 0x3ED5AC05, 0x6B015AC0,
+/**/ 0xBFD36B67, 0x76BE1000,
+/**/ 0xBD116ECD, 0xB0F177C8,
+/**/ 0x3FF5A400, 0x00000000,
+/**/ 0x3F26268D, 0x5BA55E5A,
+/**/ 0xBFD355BF, 0x1BD83000,
+/**/ 0x3D2BA99B, 0x8964F0E8,
+/**/ 0x3FF59C00, 0x00000000,
+/**/ 0x3F361F12, 0x3CCAA376,
+/**/ 0xBFD3401E, 0x12AED000,
+/**/ 0x3D317C73, 0x556E291D,
+/**/ 0x3FF59800, 0x00000000,
+/**/ 0xBF3E863D, 0x62D32417,
+/**/ 0xBFD32A84, 0x56512000,
+/**/ 0xBD04F928, 0x139AF5D6,
+/**/ 0x3FF59000, 0x00000000,
+/**/ 0xBF32DCF7, 0xEA712DCF,
+/**/ 0xBFD314F1, 0xE1D36000,
+/**/ 0x3D28E27A, 0xD3213CB8,
+/**/ 0x3FF58800, 0x00000000,
+/**/ 0xBF1B95B2, 0xA0CC87E8,
+/**/ 0xBFD2FF66, 0xB04EB000,
+/**/ 0x3D38AED2, 0x541E6E2E,
+/**/ 0x3FF58000, 0x00000000,
+/**/ 0x3F158056, 0x01580560,
+/**/ 0xBFD2E9E2, 0xBCE12000,
+/**/ 0xBD24300C, 0x128D1DC2,
+/**/ 0x3FF57800, 0x00000000,
+/**/ 0x3F31F340, 0x15791F34,
+/**/ 0xBFD2D466, 0x02ADD000,
+/**/ 0x3D288D0D, 0xDCD54196,
+/**/ 0x3FF57000, 0x00000000,
+/**/ 0x3F3ED3C5, 0x06B39A23,
+/**/ 0xBFD2BEF0, 0x7CDC9000,
+/**/ 0xBD2A9CFA, 0x4A5004F4,
+/**/ 0x3FF56C00, 0x00000000,
+/**/ 0xBF33FEA9, 0x53FEA954,
+/**/ 0xBFD2A982, 0x269A4000,
+/**/ 0x3D22058E, 0x557285CF,
+/**/ 0x3FF56400, 0x00000000,
+/**/ 0xBF1A1160, 0xEB478503,
+/**/ 0xBFD2941A, 0xFB187000,
+/**/ 0x3D3210C2, 0xB730E28B,
+/**/ 0x3FF55C00, 0x00000000,
+/**/ 0x3F1D09AD, 0xE4A18B2E,
+/**/ 0xBFD27EBA, 0xF58D9000,
+/**/ 0x3D2B1988, 0x00B4BDA7,
+/**/ 0x3FF55400, 0x00000000,
+/**/ 0x3F355555, 0x55555555,
+/**/ 0xBFD26962, 0x1134E000,
+/**/ 0x3D31B61F, 0x10522625,
+/**/ 0x3FF55000, 0x00000000,
+/**/ 0xBF3C4BE6, 0xB319A21F,
+/**/ 0xBFD25410, 0x494E5000,
+/**/ 0xBD3B1D7A, 0xC0EF77F2,
+/**/ 0x3FF54800, 0x00000000,
+/**/ 0xBF2B4328, 0x8FA03FD5,
+/**/ 0xBFD23EC5, 0x991EC000,
+/**/ 0x3D36DBE4, 0x48A2E522,
+/**/ 0x3FF54000, 0x00000000,
+/**/ 0x3EF54015, 0x40154015,
+/**/ 0xBFD22981, 0xFBEF8000,
+/**/ 0x3D3A1421, 0x609580DA,
+/**/ 0x3FF53800, 0x00000000,
+/**/ 0x3F30948F, 0x40FEAC6F,
+/**/ 0xBFD21445, 0x6D0EC000,
+/**/ 0x3D3CAF04, 0x28B728A3,
+/**/ 0x3FF53400, 0x00000000,
+/**/ 0xBF3FE034, 0xFD04F7B8,
+/**/ 0xBFD1FF0F, 0xE7CF4000,
+/**/ 0xBD3E9D5B, 0x513FF0C1,
+/**/ 0x3FF52C00, 0x00000000,
+/**/ 0xBF300A95, 0x7FAB5403,
+/**/ 0xBFD1E9E1, 0x6788A000,
+/**/ 0x3D382EAE, 0xD3C8B65E,
+/**/ 0x3FF52400, 0x00000000,
+/**/ 0x3EB52401, 0x52401524,
+/**/ 0xBFD1D4B9, 0xE796C000,
+/**/ 0xBD222A66, 0x7C42E56D,
+/**/ 0x3FF51C00, 0x00000000,
+/**/ 0x3F307EAE, 0x2F8151D0,
+/**/ 0xBFD1BF99, 0x635A7000,
+/**/ 0x3D31AC89, 0x575C2125,
+/**/ 0x3FF51800, 0x00000000,
+/**/ 0xBF3ECE3F, 0xEAE9ECE4,
+/**/ 0xBFD1AA7F, 0xD638D000,
+/**/ 0xBD29F60A, 0x9616F7A0,
+/**/ 0x3FF51000, 0x00000000,
+/**/ 0xBF2BA3DD, 0xC7675243,
+/**/ 0xBFD1956D, 0x3B9BC000,
+/**/ 0xBD27D2F7, 0x3AD1AA14,
+/**/ 0x3FF50800, 0x00000000,
+/**/ 0x3F0B9AC8, 0x764E368D,
+/**/ 0xBFD18061, 0x8EF19000,
+/**/ 0x3D3482FF, 0xC86D38E5,
+/**/ 0x3FF50000, 0x00000000,
+/**/ 0x3F350150, 0x15015015,
+/**/ 0xBFD16B5C, 0xCBAD0000,
+/**/ 0x3D323299, 0x042D74BF,
+/**/ 0x3FF4FC00, 0x00000000,
+/**/ 0xBF392851, 0x4A683C50,
+/**/ 0xBFD1565E, 0xED456000,
+/**/ 0x3CEE75AD, 0xFB6ABA25,
+/**/ 0x3FF4F400, 0x00000000,
+/**/ 0xBF1C2748, 0xACD95EF0,
+/**/ 0xBFD14167, 0xEF367000,
+/**/ 0xBD3E0C07, 0x824DAAF5,
+/**/ 0x3FF4EC00, 0x00000000,
+/**/ 0x3F26B90D, 0x67A47465,
+/**/ 0xBFD12C77, 0xCD007000,
+/**/ 0xBD13B294, 0x8A11F797,
+/**/ 0x3FF4E400, 0x00000000,
+/**/ 0x3F3E0A72, 0xF0539783,
+/**/ 0xBFD1178E, 0x8227E000,
+/**/ 0xBD31EF78, 0xCE2D07F2,
+/**/ 0x3FF4E000, 0x00000000,
+/**/ 0xBF2E00A6, 0xF87FD642,
+/**/ 0xBFD102AC, 0x0A35D000,
+/**/ 0x3D2F1FBD, 0xDFDFD686,
+/**/ 0x3FF4D800, 0x00000000,
+/**/ 0x3F10EFB7, 0x0B12E3FD,
+/**/ 0xBFD0EDD0, 0x60B78000,
+/**/ 0xBD0019B5, 0x2D8435F5,
+/**/ 0x3FF4D000, 0x00000000,
+/**/ 0x3F37BEF1, 0x5CB4DBE5,
+/**/ 0xBFD0D8FB, 0x813EB000,
+/**/ 0xBD1EE8C8, 0x8753FA35,
+/**/ 0x3FF4CC00, 0x00000000,
+/**/ 0xBF34778D, 0xA50918B1,
+/**/ 0xBFD0C42D, 0x67616000,
+/**/ 0xBD27188B, 0x163CEAE9,
+/**/ 0x3FF4C400, 0x00000000,
+/**/ 0xBED9F4F7, 0xE37288EC,
+/**/ 0xBFD0AF66, 0x0EB9E000,
+/**/ 0xBD23C7C3, 0xF528D80A,
+/**/ 0x3FF4BC00, 0x00000000,
+/**/ 0x3F33EDDA, 0x68FE0E42,
+/**/ 0xBFD09AA5, 0x72E6C000,
+/**/ 0xBD3B50A1, 0xE1734342,
+/**/ 0x3FF4B800, 0x00000000,
+/**/ 0xBF3776C6, 0xB72E47D9,
+/**/ 0xBFD085EB, 0x8F8AE000,
+/**/ 0xBD3E5D51, 0x3F45FE7B,
+/**/ 0x3FF4B000, 0x00000000,
+/**/ 0xBF04AFD6, 0xA052BF5B,
+/**/ 0xBFD07138, 0x604D6000,
+/**/ 0x3D3E7632, 0x4E912B17,
+/**/ 0x3FF4A800, 0x00000000,
+/**/ 0x3F328FFA, 0xD5B5C015,
+/**/ 0xBFD05C8B, 0xE0D96000,
+/**/ 0xBD2AD0F1, 0xC77CCB58,
+/**/ 0x3FF4A400, 0x00000000,
+/**/ 0xBF380528, 0x9FEB5D80,
+/**/ 0xBFD047E6, 0x0CDE8000,
+/**/ 0xBD2DBDF1, 0x0D397F3C,
+/**/ 0x3FF49C00, 0x00000000,
+/**/ 0xBF02AD3E, 0x25FF5B21,
+/**/ 0xBFD03346, 0xE0106000,
+/**/ 0xBCF89FF8, 0xA966395C,
+/**/ 0x3FF49400, 0x00000000,
+/**/ 0x3F339E3B, 0x2D066EA2,
+/**/ 0xBFD01EAE, 0x5626C000,
+/**/ 0xBD3A43DC, 0xFADE85AE,
+/**/ 0x3FF49000, 0x00000000,
+/**/ 0xBF3629C1, 0xAFB2E932,
+/**/ 0xBFD00A1C, 0x6ADDA000,
+/**/ 0xBD31CD8D, 0x688B9E18,
+/**/ 0x3FF48800, 0x00000000,
+/**/ 0x3ED48805, 0x22014880,
+/**/ 0xBFCFEB22, 0x33EA0000,
+/**/ 0xBD2F3418, 0xDE00938B,
+/**/ 0x3FF48000, 0x00000000,
+/**/ 0x3F37119F, 0x3D324D89,
+/**/ 0xBFCFC218, 0xBE620000,
+/**/ 0xBD34BBA4, 0x6F1CF6A0,
+/**/ 0x3FF47C00, 0x00000000,
+/**/ 0xBF31EB85, 0x1EB851EC,
+/**/ 0xBFCF991C, 0x6CB3C000,
+/**/ 0x3D390D04, 0xCD7CC834,
+/**/ 0x3FF47400, 0x00000000,
+/**/ 0x3F1569C9, 0xAAFC7C01,
+/**/ 0xBFCF702D, 0x36778000,
+/**/ 0x3D108195, 0x16673E23,
+/**/ 0x3FF46C00, 0x00000000,
+/**/ 0x3F3CE345, 0x96066250,
+/**/ 0xBFCF474B, 0x134E0000,
+/**/ 0x3D3BAE49, 0xF1DF7B5E,
+/**/ 0x3FF46800, 0x00000000,
+/**/ 0xBF26A297, 0x1D02DE87,
+/**/ 0xBFCF1E75, 0xFADFA000,
+/**/ 0x3D20862B, 0x25D83F6D,
+/**/ 0x3FF46000, 0x00000000,
+/**/ 0x3F2978FE, 0xB9F34381,
+/**/ 0xBFCEF5AD, 0xE4DD0000,
+/**/ 0x3CCA2115, 0x65BB8E11,
+/**/ 0x3FF45C00, 0x00000000,
+/**/ 0xBF3AF398, 0xF6C71366,
+/**/ 0xBFCECCF2, 0xC8FEA000,
+/**/ 0x3D3BEC63, 0xA3E75640,
+/**/ 0x3FF45400, 0x00000000,
+/**/ 0xBF030E9C, 0x449AFF5D,
+/**/ 0xBFCEA444, 0x9F04A000,
+/**/ 0xBD35E916, 0x63732A36,
+/**/ 0x3FF44C00, 0x00000000,
+/**/ 0x3F367190, 0xF8B42EF3,
+/**/ 0xBFCE7BA3, 0x5EB78000,
+/**/ 0x3D0D5EEE, 0x23793649,
+/**/ 0x3FF44800, 0x00000000,
+/**/ 0xBF3079A9, 0xD260511C,
+/**/ 0xBFCE530E, 0xFFE72000,
+/**/ 0x3D3FDBDB, 0xB13F7C18,
+/**/ 0x3FF44000, 0x00000000,
+/**/ 0x3F21B87C, 0x0B644FBE,
+/**/ 0xBFCE2A87, 0x7A6B2000,
+/**/ 0xBD382381, 0x7787081A,
+/**/ 0x3FF43C00, 0x00000000,
+/**/ 0xBF3D8CF5, 0x411B2E25,
+/**/ 0xBFCE020C, 0xC6236000,
+/**/ 0x3D252B00, 0xADB91424,
+/**/ 0x3FF43400, 0x00000000,
+/**/ 0xBF0DAC08, 0xD6A60978,
+/**/ 0xBFCDD99E, 0xDAF6E000,
+/**/ 0x3D302EC6, 0x69C756EB,
+/**/ 0x3FF42C00, 0x00000000,
+/**/ 0x3F36625D, 0x51F86EFA,
+/**/ 0xBFCDB13D, 0xB0D48000,
+/**/ 0xBD32806A, 0x847527E6,
+/**/ 0x3FF42800, 0x00000000,
+/**/ 0xBF2E8B2D, 0xA8766564,
+/**/ 0xBFCD88E9, 0x3FB30000,
+/**/ 0x3D375F28, 0x0234BF51,
+/**/ 0x3FF42000, 0x00000000,
+/**/ 0x3F26A4CB, 0xCB2A247B,
+/**/ 0xBFCD60A1, 0x7F904000,
+/**/ 0x3D35D6E0, 0x6FC20D39,
+/**/ 0x3FF41C00, 0x00000000,
+/**/ 0xBF39D5E8, 0xC17DF552,
+/**/ 0xBFCD3866, 0x68720000,
+/**/ 0x3D373650, 0xB38932BC,
+/**/ 0x3FF41400, 0x00000000,
+/**/ 0x3EF41414, 0x14141414,
+/**/ 0xBFCD1037, 0xF2656000,
+/**/ 0x3D084A7E, 0x75B6F6E4,
+/**/ 0x3FF40C00, 0x00000000,
+/**/ 0x3F3C97A8, 0x43AE87FD,
+/**/ 0xBFCCE816, 0x157F2000,
+/**/ 0x3D29E0AB, 0xA2099515,
+/**/ 0x3FF40800, 0x00000000,
+/**/ 0xBF1F4BBC, 0x66A67E6F,
+/**/ 0xBFCCC000, 0xC9DB4000,
+/**/ 0x3D1D6D58, 0x5D57AFF9,
+/**/ 0x3FF40000, 0x00000000,
+/**/ 0x3F340140, 0x14014014,
+/**/ 0xBFCC97F8, 0x079D4000,
+/**/ 0xBD23B161, 0xA8C6E6C5,
+/**/ 0x3FF3FC00, 0x00000000,
+/**/ 0xBF2FD809, 0xFD809FD8,
+/**/ 0xBFCC6FFB, 0xC6F00000,
+/**/ 0xBD3EE138, 0xD3A69D43,
+/**/ 0x3FF3F400, 0x00000000,
+/**/ 0x3F28CA0E, 0x57EE89D2,
+/**/ 0xBFCC480C, 0x0005C000,
+/**/ 0xBD39A294, 0xD5E44E76,
+/**/ 0x3FF3F000, 0x00000000,
+/**/ 0xBF370BD5, 0xA50F9260,
+/**/ 0xBFCC2028, 0xAB180000,
+/**/ 0x3D292E0E, 0xE55C7AC6,
+/**/ 0x3FF3E800, 0x00000000,
+/**/ 0x3F1704AA, 0x75945FCE,
+/**/ 0xBFCBF851, 0xC0676000,
+/**/ 0x3D35420E, 0x4C0854AD,
+/**/ 0x3FF3E400, 0x00000000,
+/**/ 0xBF3D3431, 0xB56FD83C,
+/**/ 0xBFCBD087, 0x383BE000,
+/**/ 0x3D2D4BC4, 0x595412B6,
+/**/ 0x3FF3DC00, 0x00000000,
+/**/ 0x3EB3DC01, 0x3DC013DC,
+/**/ 0xBFCBA8C9, 0x0AE4A000,
+/**/ 0xBD3A32E7, 0xF44432DA,
+/**/ 0x3FF3D400, 0x00000000,
+/**/ 0x3F3D991A, 0xA75C5BBD,
+/**/ 0xBFCB8117, 0x30B82000,
+/**/ 0xBD1E9068, 0x3B9CD768,
+/**/ 0x3FF3D000, 0x00000000,
+/**/ 0xBF1292BA, 0x59C52F5D,
+/**/ 0xBFCB5971, 0xA213A000,
+/**/ 0xBD39B50E, 0x83AA91DF,
+/**/ 0x3FF3C800, 0x00000000,
+/**/ 0x3F395A47, 0xBABE7440,
+/**/ 0xBFCB31D8, 0x575BC000,
+/**/ 0xBD3C794E, 0x562A63CB,
+/**/ 0x3FF3C400, 0x00000000,
+/**/ 0xBF20D475, 0x58A0943A,
+/**/ 0xBFCB0A4B, 0x48FC2000,
+/**/ 0x3D22E72D, 0x5C3998ED,
+/**/ 0x3FF3BC00, 0x00000000,
+/**/ 0x3F360D92, 0x3295482C,
+/**/ 0xBFCAE2CA, 0x6F672000,
+/**/ 0xBD37A8D5, 0xAE54F550,
+/**/ 0x3FF3B800, 0x00000000,
+/**/ 0xBF267D12, 0xCAB48651,
+/**/ 0xBFCABB55, 0xC316A000,
+/**/ 0x3D38A65A, 0xCAF14CD8,
+/**/ 0x3FF3B000, 0x00000000,
+/**/ 0x3F33B13B, 0x13B13B14,
+/**/ 0xBFCA93ED, 0x3C8AE000,
+/**/ 0x3D287243, 0x50562169,
+/**/ 0x3FF3AC00, 0x00000000,
+/**/ 0xBF2A46AF, 0x2C8FD3BF,
+/**/ 0xBFCA6C90, 0xD44B8000,
+/**/ 0x3D3F63B7, 0xF037B0C6,
+/**/ 0x3FF3A400, 0x00000000,
+/**/ 0x3F324387, 0xAC822610,
+/**/ 0xBFCA4540, 0x82E6A000,
+/**/ 0xBD360A77, 0xC81F7171,
+/**/ 0x3FF3A000, 0x00000000,
+/**/ 0xBF2C34BB, 0xA1923DEE,
+/**/ 0xBFCA1DFC, 0x40F1C000,
+/**/ 0x3D301E0F, 0x004F3781,
+/**/ 0x3FF39800, 0x00000000,
+/**/ 0x3F31C2C1, 0x87F63372,
+/**/ 0xBFC9F6C4, 0x0708A000,
+/**/ 0x3D3337D9, 0x4BCD3F43,
+/**/ 0x3FF39400, 0x00000000,
+/**/ 0xBF2C4AA0, 0xE11BD52E,
+/**/ 0xBFC9CF97, 0xCDCE0000,
+/**/ 0xBD3D862F, 0x10C414E3,
+/**/ 0x3FF38C00, 0x00000000,
+/**/ 0x3F322D36, 0x6088DBF4,
+/**/ 0xBFC9A877, 0x8DEBA000,
+/**/ 0xBD3470FA, 0x3EFEC390,
+/**/ 0x3FF38800, 0x00000000,
+/**/ 0xBF2A8BBF, 0x503F774E,
+/**/ 0xBFC98163, 0x4011A000,
+/**/ 0xBD34EADD, 0x9E9045E2,
+/**/ 0x3FF38000, 0x00000000,
+/**/ 0x3F338138, 0x13813814,
+/**/ 0xBFC95A5A, 0xDCF70000,
+/**/ 0xBD07F228, 0x58A0FF6F,
+/**/ 0x3FF37C00, 0x00000000,
+/**/ 0xBF26FB6F, 0x1B177053,
+/**/ 0xBFC9335E, 0x5D594000,
+/**/ 0xBD33115C, 0x3ABD47DA,
+/**/ 0x3FF37400, 0x00000000,
+/**/ 0x3F35BD1C, 0x945EDC20,
+/**/ 0xBFC90C6D, 0xB9FCC000,
+/**/ 0x3D1935F5, 0x7718D7CA,
+/**/ 0x3FF37000, 0x00000000,
+/**/ 0xBF219D00, 0x4DBDCC60,
+/**/ 0xBFC8E588, 0xEBAC2000,
+/**/ 0xBD3B7D5C, 0xAB2D1140,
+/**/ 0x3FF36800, 0x00000000,
+/**/ 0x3F38DF3D, 0xE0747954,
+/**/ 0xBFC8BEAF, 0xEB390000,
+/**/ 0x3D073D54, 0xAAE92CD1,
+/**/ 0x3FF36400, 0x00000000,
+/**/ 0xBF14E775, 0xD9D3C49F,
+/**/ 0xBFC897E2, 0xB17B2000,
+/**/ 0x3D296B37, 0x380CBE9E,
+/**/ 0x3FF35C00, 0x00000000,
+/**/ 0x3F3CE5F9, 0xF2AF821E,
+/**/ 0xBFC87121, 0x3750E000,
+/**/ 0xBD3328EB, 0x42F9AF75,
+/**/ 0x3FF35800, 0x00000000,
+/**/ 0xBEE82DF0, 0xE34971F2,
+/**/ 0xBFC84A6B, 0x759F6000,
+/**/ 0x3D3DA280, 0x2ADF8609,
+/**/ 0x3FF35400, 0x00000000,
+/**/ 0xBF3E304D, 0x4873ECAE,
+/**/ 0xBFC823C1, 0x6551A000,
+/**/ 0xBD1E0DDB, 0x9A631E83,
+/**/ 0x3FF34C00, 0x00000000,
+/**/ 0x3F1264B6, 0x1FF659DB,
+/**/ 0xBFC7FD22, 0xFF59A000,
+/**/ 0x3D158BEB, 0xF457B7D2,
+/**/ 0x3FF34800, 0x00000000,
+/**/ 0xBF386531, 0xFECB9865,
+/**/ 0xBFC7D690, 0x3CAF6000,
+/**/ 0x3D24C06B, 0x17C301D7,
+/**/ 0x3FF34000, 0x00000000,
+/**/ 0x3F25A8C2, 0xEEDA65AE,
+/**/ 0xBFC7B009, 0x16516000,
+/**/ 0x3D3AE75F, 0xCB067E57,
+/**/ 0x3FF33C00, 0x00000000,
+/**/ 0xBF31BA4A, 0x8434E1F4,
+/**/ 0xBFC7898D, 0x85444000,
+/**/ 0xBD38E67B, 0xE3DBAF3F,
+/**/ 0x3FF33400, 0x00000000,
+/**/ 0x3F31EE97, 0xDBFC660A,
+/**/ 0xBFC7631D, 0x82936000,
+/**/ 0x3D25E77D, 0xC7C5F3E1,
+/**/ 0x3FF33000, 0x00000000,
+/**/ 0xBF246252, 0xBC40BFDA,
+/**/ 0xBFC73CB9, 0x074FE000,
+/**/ 0x3D3D66A9, 0x0D0005A6,
+/**/ 0x3FF32800, 0x00000000,
+/**/ 0x3F39E640, 0x13299E64,
+/**/ 0xBFC71660, 0x0C914000,
+/**/ 0xBCE51B15, 0x7CEC3838,
+/**/ 0x3FF32400, 0x00000000,
+/**/ 0xBEFCB5D4, 0xEF40991F,
+/**/ 0xBFC6F012, 0x8B756000,
+/**/ 0xBD357739, 0x0D31EF0F,
+/**/ 0x3FF32000, 0x00000000,
+/**/ 0xBF3D4632, 0xC823D892,
+/**/ 0xBFC6C9D0, 0x7D204000,
+/**/ 0x3CDC73FA, 0xFD9B2DCA,
+/**/ 0x3FF31800, 0x00000000,
+/**/ 0x3F1DD63A, 0x7AED804C,
+/**/ 0xBFC6A399, 0xDABBE000,
+/**/ 0x3D38F934, 0xE66A15A6,
+/**/ 0x3FF31400, 0x00000000,
+/**/ 0xBF339849, 0xE8C11E1A,
+/**/ 0xBFC67D6E, 0x9D786000,
+/**/ 0x3D311E88, 0x30A706D3,
+/**/ 0x3FF30C00, 0x00000000,
+/**/ 0x3F319013, 0x0D190131,
+/**/ 0xBFC6574E, 0xBE8C2000,
+/**/ 0x3D398C1D, 0x34F0F462,
+/**/ 0x3FF30800, 0x00000000,
+/**/ 0xBF222315, 0xB47A7FDA,
+/**/ 0xBFC6313A, 0x37336000,
+/**/ 0x3D144DF5, 0x4F21EA6D,
+/**/ 0x3FF30000, 0x00000000,
+/**/ 0x3F3C82AC, 0x40260390,
+/**/ 0xBFC60B31, 0x00B0A000,
+/**/ 0x3D371456, 0xC988F814,
+/**/ 0x3FF2FC00, 0x00000000,
+/**/ 0x3F026443, 0xA2430A62,
+/**/ 0xBFC5E533, 0x144C2000,
+/**/ 0x3D31CE0B, 0xF3B290EA,
+/**/ 0x3FF2F800, 0x00000000,
+/**/ 0xBF37B425, 0xED097B42,
+/**/ 0xBFC5BF40, 0x6B544000,
+/**/ 0x3D127023, 0xEB68981C,
+/**/ 0x3FF2F000, 0x00000000,
+/**/ 0x3F2D00E3, 0x4AE0553C,
+/**/ 0xBFC59958, 0xFF1D6000,
+/**/ 0x3D3A1D05, 0x9769CA05,
+/**/ 0x3FF2EC00, 0x00000000,
+/**/ 0xBF262BC0, 0x25D69D44,
+/**/ 0xBFC5737C, 0xC9018000,
+/**/ 0xBD39BAA7, 0xA6B887F6,
+/**/ 0x3FF2E400, 0x00000000,
+/**/ 0x3F3B88B5, 0xE3103D6B,
+/**/ 0xBFC54DAB, 0xC2610000,
+/**/ 0xBD2746FE, 0xE5C8D0D8,
+/**/ 0x3FF2E000, 0x00000000,
+/**/ 0x3F02E025, 0xC04B8097,
+/**/ 0xBFC527E5, 0xE4A1C000,
+/**/ 0x3D34E60B, 0x8D4B411D,
+/**/ 0x3FF2DC00, 0x00000000,
+/**/ 0xBF369C22, 0x2C305021,
+/**/ 0xBFC5022B, 0x292F6000,
+/**/ 0xBD348A05, 0xFF36A25B,
+/**/ 0x3FF2D400, 0x00000000,
+/**/ 0x3F30A012, 0xD50A012D,
+/**/ 0xBFC4DC7B, 0x897BC000,
+/**/ 0xBD0C79B6, 0x0AE1FF0F,
+/**/ 0x3FF2D000, 0x00000000,
+/**/ 0xBF1FBE29, 0xBC66484E,
+/**/ 0xBFC4B6D6, 0xFEFE2000,
+/**/ 0xBD1522EC, 0xF56E7952,
+/**/ 0x3FF2C800, 0x00000000,
+/**/ 0x3F3FB4D8, 0x12C9FB4E,
+/**/ 0xBFC4913D, 0x8333C000,
+/**/ 0x3D353E43, 0x558124C4,
+/**/ 0x3FF2C400, 0x00000000,
+/**/ 0x3F1E3432, 0x7004B11E,
+/**/ 0xBFC46BAF, 0x0F9F6000,
+/**/ 0x3D1249CD, 0x0790841A,
+/**/ 0x3FF2C000, 0x00000000,
+/**/ 0xBF30671A, 0x5C8EF02F,
+/**/ 0xBFC4462B, 0x9DC9C000,
+/**/ 0x3D384858, 0xA711B062,
+/**/ 0x3FF2B800, 0x00000000,
+/**/ 0x3F37D835, 0xD548D9AC,
+/**/ 0xBFC420B3, 0x27410000,
+/**/ 0x3D116282, 0xC85A0884,
+/**/ 0x3FF2B400, 0x00000000,
+/**/ 0x3ED2B404, 0xAD012B40,
+/**/ 0xBFC3FB45, 0xA5992000,
+/**/ 0xBD319713, 0xC0CAE559,
+/**/ 0x3FF2B000, 0x00000000,
+/**/ 0xBF370F78, 0x8E7302A1,
+/**/ 0xBFC3D5E3, 0x126BC000,
+/**/ 0xBD13FB2F, 0x85096C4B,
+/**/ 0x3FF2A800, 0x00000000,
+/**/ 0x3F31C92F, 0x3C1053F9,
+/**/ 0xBFC3B08B, 0x67580000,
+/**/ 0x3D3AADE8, 0xF29320FB,
+/**/ 0x3FF2A400, 0x00000000,
+/**/ 0xBF14AD94, 0x3DBE2E04,
+/**/ 0xBFC38B3E, 0x9E028000,
+/**/ 0x3D370EF0, 0x545C17F9,
+/**/ 0x3FF2A000, 0x00000000,
+/**/ 0xBF3BED61, 0xBED61BED,
+/**/ 0xBFC365FC, 0xB015A000,
+/**/ 0x3D3FD3A0, 0xAFB9691B,
+/**/ 0x3FF29800, 0x00000000,
+/**/ 0x3F2B061A, 0x26F004A6,
+/**/ 0xBFC340C5, 0x97412000,
+/**/ 0x3D37A3DC, 0xF7D9D386,
+/**/ 0x3FF29400, 0x00000000,
+/**/ 0xBF21B488, 0xFF6B646D,
+/**/ 0xBFC31B99, 0x4D3A4000,
+/**/ 0xBD3F098E, 0xE3A50810,
+/**/ 0x3FF29000, 0x00000000,
+/**/ 0xBF3F0582, 0x2CA5D5AC,
+/**/ 0xBFC2F677, 0xCBBC0000,
+/**/ 0xBD352B30, 0x2160F40D,
+/**/ 0x3FF28800, 0x00000000,
+/**/ 0x3F260251, 0x16025116,
+/**/ 0xBFC2D161, 0x0C868000,
+/**/ 0xBD039D6C, 0xCB81B4A1,
+/**/ 0x3FF28400, 0x00000000,
+/**/ 0xBF258CDF, 0x502065D2,
+/**/ 0xBFC2AC55, 0x095F6000,
+/**/ 0x3D1D3466, 0xD0C6C8A8,
+/**/ 0x3FF27C00, 0x00000000,
+/**/ 0x3F3FA38A, 0x1CE4D6F8,
+/**/ 0xBFC28753, 0xBC11A000,
+/**/ 0xBD37494E, 0x359302E6,
+/**/ 0x3FF27800, 0x00000000,
+/**/ 0x3F247DD5, 0xDCCA0781,
+/**/ 0xBFC2625D, 0x1E6DE000,
+/**/ 0x3CF52962, 0xF09E3D82,
+/**/ 0x3FF27400, 0x00000000,
+/**/ 0xBF25E8EF, 0xDB195E8F,
+/**/ 0xBFC23D71, 0x2A49C000,
+/**/ 0xBD100D23, 0x8FD3DF5C,
+/**/ 0x3FF27000, 0x00000000,
+/**/ 0xBF3FF6C8, 0xFFB647FE,
+/**/ 0xBFC2188F, 0xD9808000,
+/**/ 0x3D3B3A1E, 0x7F50C701,
+/**/ 0x3FF26800, 0x00000000,
+/**/ 0x3F266F9A, 0xC024D167,
+/**/ 0xBFC1F3B9, 0x25F26000,
+/**/ 0x3D15F74E, 0x9B083633,
+/**/ 0x3FF26400, 0x00000000,
+/**/ 0xBF22D1BD, 0xEABD0E14,
+/**/ 0xBFC1CEED, 0x09854000,
+/**/ 0x3D315C1C, 0x39192AF9,
+/**/ 0x3FF26000, 0x00000000,
+/**/ 0xBF3DD8F7, 0xF6D0EEC8,
+/**/ 0xBFC1AA2B, 0x7E240000,
+/**/ 0x3D31AC38, 0xDDE3B366,
+/**/ 0x3FF25800, 0x00000000,
+/**/ 0x3F2BCEB1, 0x2A241EF6,
+/**/ 0xBFC18574, 0x7DBEC000,
+/**/ 0xBD3E6744, 0x45BD9B49,
+/**/ 0x3FF25400, 0x00000000,
+/**/ 0xBF18A05B, 0xA21378D7,
+/**/ 0xBFC160C8, 0x024B2000,
+/**/ 0xBD2EC2D2, 0xA9009E3D,
+/**/ 0x3FF25000, 0x00000000,
+/**/ 0xBF3A076F, 0xD6CFA90C,
+/**/ 0xBFC13C26, 0x05C3A000,
+/**/ 0x3D2CF5FD, 0xD94F6509,
+/**/ 0x3FF24800, 0x00000000,
+/**/ 0x3F324924, 0x92492492,
+/**/ 0xBFC1178E, 0x8227E000,
+/**/ 0xBD21EF78, 0xCE2D07F2,
+/**/ 0x3FF24400, 0x00000000,
+/**/ 0xBEF3682B, 0x6151E899,
+/**/ 0xBFC0F301, 0x717D0000,
+/**/ 0x3D3E09B4, 0x41AE86C5,
+/**/ 0x3FF24000, 0x00000000,
+/**/ 0xBF34868E, 0x89FA4C67,
+/**/ 0xBFC0CE7E, 0xCDCCC000,
+/**/ 0xBD14652D, 0xABFF5447,
+/**/ 0x3FF23800, 0x00000000,
+/**/ 0x3F3858D8, 0x6B11F09F,
+/**/ 0xBFC0AA06, 0x91268000,
+/**/ 0x3D345519, 0xD7032129,
+/**/ 0x3FF23400, 0x00000000,
+/**/ 0x3F159E26, 0xAF37C049,
+/**/ 0xBFC08598, 0xB59E4000,
+/**/ 0x3D27E5DD, 0x7009902C,
+/**/ 0x3FF23000, 0x00000000,
+/**/ 0xBF2AB546, 0x2E076329,
+/**/ 0xBFC06135, 0x354D4000,
+/**/ 0xBD363046, 0x28340EE9,
+/**/ 0x3FF22C00, 0x00000000,
+/**/ 0xBF3FEDD5, 0xFEDD5FEE,
+/**/ 0xBFC03CDC, 0x0A51E000,
+/**/ 0xBD381A9C, 0xF169FC5C,
+/**/ 0x3FF22400, 0x00000000,
+/**/ 0x3F2B5B92, 0x009126D7,
+/**/ 0xBFC0188D, 0x2ECF6000,
+/**/ 0xBD03F965, 0x1CFF9DFE,
+/**/ 0x3FF22000, 0x00000000,
+/**/ 0xBF121FB7, 0x8121FB78,
+/**/ 0xBFBFE891, 0x39DBC000,
+/**/ 0xBD356594, 0xD82F7A82,
+/**/ 0x3FF21C00, 0x00000000,
+/**/ 0xBF368F22, 0x3A459635,
+/**/ 0xBFBFA01C, 0x9DB58000,
+/**/ 0x3D08F351, 0xFA48A730,
+/**/ 0x3FF21400, 0x00000000,
+/**/ 0x3F379804, 0x855E6012,
+/**/ 0xBFBF57BC, 0x7D900000,
+/**/ 0xBD176A6C, 0x9EA8B04E,
+/**/ 0x3FF21000, 0x00000000,
+/**/ 0x3F17B57C, 0x78CD7A37,
+/**/ 0xBFBF0F70, 0xCDD98000,
+/**/ 0xBD32E31F, 0x6C272C1E,
+/**/ 0x3FF20C00, 0x00000000,
+/**/ 0xBF271E73, 0x07E4EF15,
+/**/ 0xBFBEC739, 0x830A0000,
+/**/ 0xBD311FCB, 0xA80CDD10,
+/**/ 0x3FF20800, 0x00000000,
+/**/ 0xBF3CDDEC, 0x49392BA7,
+/**/ 0xBFBE7F16, 0x91A34000,
+/**/ 0x3D32C1C5, 0x9BC77BFA,
+/**/ 0x3FF20000, 0x00000000,
+/**/ 0x3F320120, 0x12012012,
+/**/ 0xBFBE3707, 0xEE304000,
+/**/ 0xBD20F684, 0xE6766ABD,
+/**/ 0x3FF1FC00, 0x00000000,
+/**/ 0x3EF0DC4F, 0xCE8AD1A2,
+/**/ 0xBFBDEF0D, 0x8D468000,
+/**/ 0x3D324750, 0x412E9A74,
+/**/ 0x3FF1F800, 0x00000000,
+/**/ 0xBF2F7047, 0xDC11F704,
+/**/ 0xBFBDA727, 0x63844000,
+/**/ 0xBD1A8940, 0x1FA71733,
+/**/ 0x3FF1F000, 0x00000000,
+/**/ 0x3F3FAF3F, 0x16B6419D,
+/**/ 0xBFBD5F55, 0x65920000,
+/**/ 0xBD30E239, 0xCC185469,
+/**/ 0x3FF1EC00, 0x00000000,
+/**/ 0x3F2E878F, 0xF70985E2,
+/**/ 0xBFBD1797, 0x88218000,
+/**/ 0xBD336433, 0xB5EFBEED,
+/**/ 0x3FF1E800, 0x00000000,
+/**/ 0xBEEF55E4, 0x94D7FDC3,
+/**/ 0xBFBCCFED, 0xBFEE0000,
+/**/ 0xBD33A823, 0x2FE71256,
+/**/ 0x3FF1E400, 0x00000000,
+/**/ 0xBF310C4C, 0x0478BBCF,
+/**/ 0xBFBC8858, 0x01BC4000,
+/**/ 0xBD2646D1, 0xC65AACD3,
+/**/ 0x3FF1DC00, 0x00000000,
+/**/ 0x3F3F0ECB, 0xCB840C49,
+/**/ 0xBFBC40D6, 0x425A4000,
+/**/ 0xBD3CB112, 0x1D1930DD,
+/**/ 0x3FF1D800, 0x00000000,
+/**/ 0x3F2EACE5, 0xC9579074,
+/**/ 0xBFBBF968, 0x769FC000,
+/**/ 0xBD24218C, 0x8D824283,
+/**/ 0x3FF1D400, 0x00000000,
+/**/ 0xBECABDFA, 0xFC60F0AE,
+/**/ 0xBFBBB20E, 0x936D8000,
+/**/ 0x3D368BA8, 0x35459B8E,
+/**/ 0x3FF1D000, 0x00000000,
+/**/ 0xBF2F2A4B, 0xAFDC61F3,
+/**/ 0xBFBB6AC8, 0x8DAD4000,
+/**/ 0xBD3B1BDF, 0xF50225C7,
+/**/ 0x3FF1CC00, 0x00000000,
+/**/ 0xBF3EC8AF, 0xAB802394,
+/**/ 0xBFBB2396, 0x5A530000,
+/**/ 0x3CEFF64E, 0xEA137079,
+/**/ 0x3FF1C400, 0x00000000,
+/**/ 0x3F322FC1, 0xCE058D9B,
+/**/ 0xBFBADC77, 0xEE5B0000,
+/**/ 0x3D3573B2, 0x09C31904,
+/**/ 0x3FF1C000, 0x00000000,
+/**/ 0x3F0AA04F, 0xE0EFA2CF,
+/**/ 0xBFBA956D, 0x3ECAC000,
+/**/ 0xBD3E6379, 0x4C02C4AF,
+/**/ 0x3FF1BC00, 0x00000000,
+/**/ 0xBF26B7F7, 0x225ADFDD,
+/**/ 0xBFBA4E76, 0x40B1C000,
+/**/ 0x3D0E42B6, 0xB94407C8,
+/**/ 0x3FF1B800, 0x00000000,
+/**/ 0xBF39E073, 0x217CD13A,
+/**/ 0xBFBA0792, 0xE9278000,
+/**/ 0x3D0A9CE6, 0xC9AD51BF,
+/**/ 0x3FF1B000, 0x00000000,
+/**/ 0x3F37C67F, 0x2BAE2B21,
+/**/ 0xBFB9C0C3, 0x2D4D4000,
+/**/ 0x3D3AB7C0, 0x9E838668,
+/**/ 0x3FF1AC00, 0x00000000,
+/**/ 0x3F23316E, 0xBD720DCF,
+/**/ 0xBFB97A07, 0x024CC000,
+/**/ 0x3CF8BCC1, 0x732093CE,
+/**/ 0x3FF1A800, 0x00000000,
+/**/ 0xBF11A7B9, 0x611A7B96,
+/**/ 0xBFB9335E, 0x5D594000,
+/**/ 0xBD23115C, 0x3ABD47DA,
+/**/ 0x3FF1A400, 0x00000000,
+/**/ 0xBF324195, 0xA1C1B8E7,
+/**/ 0xBFB8ECC9, 0x33AEC000,
+/**/ 0x3D222F39, 0xBE67F7AA,
+/**/ 0x3FF1A000, 0x00000000,
+/**/ 0xBF3FEE61, 0xFEE61FEE,
+/**/ 0xBFB8A647, 0x7A91C000,
+/**/ 0xBD3C28C0, 0xAF9BD6DF,
+/**/ 0x3FF19800, 0x00000000,
+/**/ 0x3F328F89, 0x362B721D,
+/**/ 0xBFB85FD9, 0x27508000,
+/**/ 0x3D35B818, 0x19970C1C,
+/**/ 0x3FF19400, 0x00000000,
+/**/ 0x3F14E023, 0x28A70119,
+/**/ 0xBFB8197E, 0x2F410000,
+/**/ 0x3D3C0FE4, 0x60D20041,
+/**/ 0x3FF19000, 0x00000000,
+/**/ 0xBF1FD419, 0x3E48FC6F,
+/**/ 0xBFB7D336, 0x87C28000,
+/**/ 0xBD33C88C, 0x3E706706,
+/**/ 0x3FF18C00, 0x00000000,
+/**/ 0xBF34F7C6, 0xFD42546B,
+/**/ 0xBFB78D02, 0x263D8000,
+/**/ 0xBD069B57, 0x94B69FB7,
+/**/ 0x3FF18400, 0x00000000,
+/**/ 0x3F3E2FA4, 0x01185E30,
+/**/ 0xBFB746E1, 0x00228000,
+/**/ 0x3D3126D1, 0x6E1E21D2,
+/**/ 0x3FF18000, 0x00000000,
+/**/ 0x3F318118, 0x11811812,
+/**/ 0xBFB700D3, 0x0AEAC000,
+/**/ 0xBCEC1E8D, 0xA99DED32,
+/**/ 0x3FF17C00, 0x00000000,
+/**/ 0x3F13F1CA, 0xFF2E2C43,
+/**/ 0xBFB6BAD8, 0x3C188000,
+/**/ 0xBD0DAF3C, 0xC08926AE,
+/**/ 0x3FF17800, 0x00000000,
+/**/ 0xBF1D79B9, 0x0A5EF9FF,
+/**/ 0xBFB674F0, 0x89364000,
+/**/ 0xBD3A7999, 0x4C9D3302,
+/**/ 0x3FF17400, 0x00000000,
+/**/ 0xBF338FAD, 0x1ECEA765,
+/**/ 0xBFB62F1B, 0xE7D78000,
+/**/ 0x3D217995, 0x7ED63C4E,
+/**/ 0x3FF17000, 0x00000000,
+/**/ 0xBF3F976B, 0xD8C8714B,
+/**/ 0xBFB5E95A, 0x4D978000,
+/**/ 0xBD31CB7C, 0xE1D17171,
+/**/ 0x3FF16800, 0x00000000,
+/**/ 0x3F348A33, 0xB08FA497,
+/**/ 0xBFB5A3AB, 0xB01AC000,
+/**/ 0xBD3E2574, 0x9E6AFA18,
+/**/ 0x3FF16400, 0x00000000,
+/**/ 0x3F21AA1F, 0x864022C9,
+/**/ 0xBFB55E10, 0x050E0000,
+/**/ 0xBD0C1D74, 0x0C53C72E,
+/**/ 0x3FF16000, 0x00000000,
+/**/ 0xBF05B7C9, 0xB487BCAD,
+/**/ 0xBFB51887, 0x42260000,
+/**/ 0xBD330A1D, 0x96258B3E,
+/**/ 0x3FF15C00, 0x00000000,
+/**/ 0xBF2C3411, 0x5B1E5F75,
+/**/ 0xBFB4D311, 0x5D208000,
+/**/ 0x3CF53A25, 0x82F4E1EF,
+/**/ 0x3FF15800, 0x00000000,
+/**/ 0xBF39543F, 0xEEA99544,
+/**/ 0xBFB48DAE, 0x4BC30000,
+/**/ 0xBD30185B, 0x208C200C,
+/**/ 0x3FF15000, 0x00000000,
+/**/ 0x3F3B9A3F, 0xDD5C8CB8,
+/**/ 0xBFB4485E, 0x03DBC000,
+/**/ 0xBD3FAD46, 0xE8D26AB7,
+/**/ 0x3FF14C00, 0x00000000,
+/**/ 0x3F30B155, 0xB19AE5C7,
+/**/ 0xBFB40320, 0x7B414000,
+/**/ 0xBD26FD84, 0xAA8157C0,
+/**/ 0x3FF14800, 0x00000000,
+/**/ 0x3F17C382, 0xB34EDA32,
+/**/ 0xBFB3BDF5, 0xA7D20000,
+/**/ 0x3D319BD0, 0xAD125895,
+/**/ 0x3FF14400, 0x00000000,
+/**/ 0xBF129CFF, 0xBAF129D0,
+/**/ 0xBFB378DD, 0x7F748000,
+/**/ 0xBD371411, 0x28F1FACA,
+/**/ 0x3FF14000, 0x00000000,
+/**/ 0xBF2E2E59, 0x771B7C7F,
+/**/ 0xBFB333D7, 0xF8184000,
+/**/ 0x3CE692B6, 0xA81B8848,
+/**/ 0x3FF13C00, 0x00000000,
+/**/ 0xBF395F06, 0x30FE1D9C,
+/**/ 0xBFB2EEE5, 0x07B40000,
+/**/ 0xBD08081E, 0xDD77C860,
+/**/ 0x3FF13400, 0x00000000,
+/**/ 0x3F3C8113, 0x5C81135D,
+/**/ 0xBFB2AA04, 0xA4470000,
+/**/ 0xBD37A48B, 0xA8B1CB41,
+/**/ 0x3FF13000, 0x00000000,
+/**/ 0x3F3288FF, 0xBB3B5DC0,
+/**/ 0xBFB26536, 0xC3D8C000,
+/**/ 0xBD0B4BAC, 0x097C5BA3,
+/**/ 0x3FF12C00, 0x00000000,
+/**/ 0x3F21713D, 0xB81577AE,
+/**/ 0xBFB2207B, 0x5C784000,
+/**/ 0xBD349D8C, 0xFC10C7BF,
+/**/ 0x3FF12800, 0x00000000,
+/**/ 0xBEEE05E5, 0xBAD6FC84,
+/**/ 0xBFB1DBD2, 0x643D0000,
+/**/ 0xBD390B24, 0xD977C494,
+/**/ 0x3FF12400, 0x00000000,
+/**/ 0xBF24E314, 0x59F992BF,
+/**/ 0xBFB1973B, 0xD1464000,
+/**/ 0xBD3566D1, 0x54F930B3,
+/**/ 0x3FF12000, 0x00000000,
+/**/ 0xBF33CB91, 0xC9F6E7A8,
+/**/ 0xBFB152B7, 0x99BB4000,
+/**/ 0x3D09BB29, 0x07030829,
+/**/ 0x3FF11C00, 0x00000000,
+/**/ 0xBF3CFE65, 0x8B7D9851,
+/**/ 0xBFB10E45, 0xB3CB0000,
+/**/ 0x3D37CF69, 0x284A3465,
+/**/ 0x3FF11400, 0x00000000,
+/**/ 0x3F39F5DB, 0x29605DF7,
+/**/ 0xBFB0C9E6, 0x15AC4000,
+/**/ 0xBD2C2DA8, 0x0974D976,
+/**/ 0x3FF11000, 0x00000000,
+/**/ 0x3F311111, 0x11111111,
+/**/ 0xBFB08598, 0xB59E4000,
+/**/ 0x3D17E5DD, 0x7009902C,
+/**/ 0x3FF10C00, 0x00000000,
+/**/ 0x3F20A63A, 0x12A5B1AE,
+/**/ 0xBFB0415D, 0x89E74000,
+/**/ 0xBD1111C0, 0x5CF1D753,
+/**/ 0x3FF10800, 0x00000000,
+/**/ 0xBED107FB, 0xBE011080,
+/**/ 0xBFAFFA69, 0x11AB8000,
+/**/ 0xBD23008C, 0x98381A8F,
+/**/ 0x3FF10400, 0x00000000,
+/**/ 0xBF216989, 0x6FEABBAE,
+/**/ 0xBFAF723B, 0x51800000,
+/**/ 0x3D3D6EB0, 0xDD5610D3,
+/**/ 0x3FF10000, 0x00000000,
+/**/ 0xBF30FEF0, 0x10FEF011,
+/**/ 0xBFAEEA31, 0xC0068000,
+/**/ 0xBD3C3DD8, 0x3606D891,
+/**/ 0x3FF0FC00, 0x00000000,
+/**/ 0xBF3922C0, 0x98CDDC74,
+/**/ 0xBFAE624C, 0x4A0B8000,
+/**/ 0x3D30F25C, 0x74676689,
+/**/ 0x3FF0F400, 0x00000000,
+/**/ 0x3F3EDFAB, 0x325A1A80,
+/**/ 0xBFADDA8A, 0xDC680000,
+/**/ 0x3D21B1AC, 0x64D9E42F,
+/**/ 0x3FF0F000, 0x00000000,
+/**/ 0x3F370834, 0xF27F9A57,
+/**/ 0xBFAD52ED, 0x64060000,
+/**/ 0x3D33C85D, 0x2A29BBD6,
+/**/ 0x3FF0EC00, 0x00000000,
+/**/ 0x3F2EAD7C, 0xD391FBC5,
+/**/ 0xBFACCB73, 0xCDDD8000,
+/**/ 0xBD3965C3, 0x6E09F5FE,
+/**/ 0x3FF0E800, 0x00000000,
+/**/ 0x3F1F2CA5, 0xE9479870,
+/**/ 0xBFAC441E, 0x06F70000,
+/**/ 0xBD354F1F, 0x49850D15,
+/**/ 0x3FF0E400, 0x00000000,
+/**/ 0x3ED95609, 0x80439019,
+/**/ 0xBFABBCEB, 0xFC690000,
+/**/ 0x3D17BF86, 0x8C317C2A,
+/**/ 0x3FF0E000, 0x00000000,
+/**/ 0xBF1B6B4D, 0xC6867596,
+/**/ 0xBFAB35DD, 0x9B588000,
+/**/ 0xBD3D5674, 0xD6CF558E,
+/**/ 0x3FF0DC00, 0x00000000,
+/**/ 0xBF2BEAEE, 0x172D4CE8,
+/**/ 0xBFAAAEF2, 0xD0FB0000,
+/**/ 0xBD20FC1A, 0x353BB42E,
+/**/ 0x3FF0D800, 0x00000000,
+/**/ 0xBF34EAB0, 0x479071A9,
+/**/ 0xBFAA282B, 0x8A938000,
+/**/ 0x3D2E8F59, 0x80EFC8E3,
+/**/ 0x3FF0D400, 0x00000000,
+/**/ 0xBF3BBA9C, 0xA61C62D3,
+/**/ 0xBFA9A187, 0xB5740000,
+/**/ 0x3D30C22E, 0x4EC4D90D,
+/**/ 0x3FF0CC00, 0x00000000,
+/**/ 0x3F3D9AA6, 0x77344011,
+/**/ 0xBFA91B07, 0x3EFD8000,
+/**/ 0x3D19D7C5, 0x3F76CA96,
+/**/ 0x3FF0C800, 0x00000000,
+/**/ 0x3F3714FB, 0xCDA3AC11,
+/**/ 0xBFA894AA, 0x149F8000,
+/**/ 0xBD39A19A, 0x8BE97661,
+/**/ 0x3FF0C400, 0x00000000,
+/**/ 0x3F30B446, 0x391F2E61,
+/**/ 0xBFA80E70, 0x23D90000,
+/**/ 0x3D399DC1, 0x6F28BF45,
+/**/ 0x3FF0C000, 0x00000000,
+/**/ 0x3F24F0D1, 0x682E11CD,
+/**/ 0xBFA78859, 0x5A358000,
+/**/ 0x3D108B0D, 0x083B3A4C,
+/**/ 0x3FF0BC00, 0x00000000,
+/**/ 0x3F118519, 0x5D5A36EA,
+/**/ 0xBFA70265, 0xA5510000,
+/**/ 0x3D2888DF, 0x11FD5CE7,
+/**/ 0x3FF0B800, 0x00000000,
+/**/ 0xBEF913DA, 0x62386CAB,
+/**/ 0xBFA67C94, 0xF2D48000,
+/**/ 0xBD3DAC20, 0x827CCA0C,
+/**/ 0x3FF0B400, 0x00000000,
+/**/ 0xBF1D7CFF, 0xBD31D7D0,
+/**/ 0xBFA5F6E7, 0x30790000,
+/**/ 0x3D20485A, 0x8012494C,
+/**/ 0x3FF0B000, 0x00000000,
+/**/ 0xBF2A11BA, 0x226951DC,
+/**/ 0xBFA5715C, 0x4C040000,
+/**/ 0x3D38888D, 0xDFC47628,
+/**/ 0x3FF0AC00, 0x00000000,
+/**/ 0xBF328E31, 0x7B2E9DD2,
+/**/ 0xBFA4EBF4, 0x334A0000,
+/**/ 0x3D2D9150, 0xF73BE773,
+/**/ 0x3FF0A800, 0x00000000,
+/**/ 0xBF37EF59, 0x7EF597EF,
+/**/ 0xBFA466AE, 0xD42E0000,
+/**/ 0x3D2C1673, 0x75BDFD28,
+/**/ 0x3FF0A400, 0x00000000,
+/**/ 0xBF3D2C71, 0x50D413C1,
+/**/ 0xBFA3E18C, 0x1CA08000,
+/**/ 0xBD3748ED, 0x3F6E378E,
+/**/ 0x3FF09C00, 0x00000000,
+/**/ 0x3F3DBA6A, 0xF836010A,
+/**/ 0xBFA35C8B, 0xFAA10000,
+/**/ 0xBD38357D, 0x5EF9EB35,
+/**/ 0x3FF09800, 0x00000000,
+/**/ 0x3F38C51F, 0x624D4AF5,
+/**/ 0xBFA2D7AE, 0x5C3C8000,
+/**/ 0x3D322939, 0x459DA66D,
+/**/ 0x3FF09400, 0x00000000,
+/**/ 0x3F33F390, 0x10953F39,
+/**/ 0xBFA252F3, 0x2F8D0000,
+/**/ 0xBD283E9A, 0xE021B67B,
+/**/ 0x3FF09000, 0x00000000,
+/**/ 0x3F2E8B42, 0x861539B9,
+/**/ 0xBFA1CE5A, 0x62BC0000,
+/**/ 0xBD3A9CC7, 0x8D8DF999,
+/**/ 0x3FF08C00, 0x00000000,
+/**/ 0x3F25766E, 0xACBC4021,
+/**/ 0xBFA149E3, 0xE4008000,
+/**/ 0x3D32B98A, 0x9A4168FD,
+/**/ 0x3FF08800, 0x00000000,
+/**/ 0x3F1950DB, 0x0F3DBD5A,
+/**/ 0xBFA0C58F, 0xA19E0000,
+/**/ 0x3D0559D1, 0x58B17913,
+/**/ 0x3FF08400, 0x00000000,
+/**/ 0x3F008421, 0x08421084,
+/**/ 0xBFA0415D, 0x89E78000,
+/**/ 0x3D3DDDC7, 0xF461C516,
+/**/ 0x3FF08000, 0x00000000,
+/**/ 0xBF007FDF, 0x0041FF7C,
+/**/ 0xBF9F7A9B, 0x16780000,
+/**/ 0xBD242AD9, 0x271BE7D7,
+/**/ 0x3FF07C00, 0x00000000,
+/**/ 0xBF183591, 0xC54798FB,
+/**/ 0xBF9E72BF, 0x28140000,
+/**/ 0x3D28D751, 0x49774D47,
+/**/ 0x3FF07800, 0x00000000,
+/**/ 0xBF23CFA1, 0x518F4EFD,
+/**/ 0xBF9D6B27, 0x25980000,
+/**/ 0x3D39FF7B, 0x50D1B838,
+/**/ 0x3FF07400, 0x00000000,
+/**/ 0xBF2B3EB7, 0x01073261,
+/**/ 0xBF9C63D2, 0xEC150000,
+/**/ 0x3D35439C, 0xE030A687,
+/**/ 0x3FF07000, 0x00000000,
+/**/ 0xBF31341F, 0xD6EAB025,
+/**/ 0xBF9B5CC2, 0x58B70000,
+/**/ 0xBD18E611, 0xB8AFBFE8,
+/**/ 0x3FF06C00, 0x00000000,
+/**/ 0xBF34A638, 0x6ED049E0,
+/**/ 0xBF9A55F5, 0x48C60000,
+/**/ 0x3D2DE070, 0x9F2D03C9,
+/**/ 0x3FF06800, 0x00000000,
+/**/ 0xBF37F5BF, 0xEF997F5C,
+/**/ 0xBF994F6B, 0x99A20000,
+/**/ 0xBD311D5E, 0xF96CF7F5,
+/**/ 0x3FF06400, 0x00000000,
+/**/ 0xBF3B22D0, 0xE5604189,
+/**/ 0xBF984925, 0x28C90000,
+/**/ 0x3D2AA0BA, 0x325A0C34,
+/**/ 0x3FF06000, 0x00000000,
+/**/ 0xBF3E2D85, 0xC1163FF0,
+/**/ 0xBF974321, 0xD3D00000,
+/**/ 0xBCFB4A69, 0x0FE94778,
+/**/ 0x3FF05800, 0x00000000,
+/**/ 0x3F3EEA07, 0x27586632,
+/**/ 0xBF963D61, 0x78690000,
+/**/ 0xBD07ABF3, 0x89596542,
+/**/ 0x3FF05400, 0x00000000,
+/**/ 0x3F3C23BB, 0x98E2A5E7,
+/**/ 0xBF9537E3, 0xF45F0000,
+/**/ 0xBD2AB259, 0xD2D7F253,
+/**/ 0x3FF05000, 0x00000000,
+/**/ 0x3F397F7D, 0x73404146,
+/**/ 0xBF9432A9, 0x25980000,
+/**/ 0xBD098139, 0x928637FE,
+/**/ 0x3FF04C00, 0x00000000,
+/**/ 0x3F36FD32, 0xB0C7B49A,
+/**/ 0xBF932DB0, 0xEA130000,
+/**/ 0xBD2710CB, 0x130895FC,
+/**/ 0x3FF04800, 0x00000000,
+/**/ 0x3F349CC1, 0x664C578A,
+/**/ 0xBF9228FB, 0x1FEA0000,
+/**/ 0xBD2713E3, 0x284991FE,
+/**/ 0x3FF04400, 0x00000000,
+/**/ 0x3F325E0F, 0xC2FCB1F4,
+/**/ 0xBF912487, 0xA5500000,
+/**/ 0xBD3FDBE5, 0xFED4B393,
+/**/ 0x3FF04000, 0x00000000,
+/**/ 0x3F304104, 0x10410410,
+/**/ 0xBF902056, 0x58930000,
+/**/ 0xBD3611D2, 0x7C8E8417,
+/**/ 0x3FF03C00, 0x00000000,
+/**/ 0x3F2C8B09, 0x6334030B,
+/**/ 0xBF8E38CE, 0x30340000,
+/**/ 0x3D39DE88, 0xA3DA281A,
+/**/ 0x3FF03800, 0x00000000,
+/**/ 0x3F28D6F0, 0x48FF7E3A,
+/**/ 0xBF8C3173, 0x84C80000,
+/**/ 0x3D341F33, 0xFCEFB9FE,
+/**/ 0x3FF03400, 0x00000000,
+/**/ 0x3F25658A, 0x0081A559,
+/**/ 0xBF8A2A9C, 0x6C180000,
+/**/ 0x3D3F73BC, 0x4D6D3472,
+/**/ 0x3FF03000, 0x00000000,
+/**/ 0x3F2236A3, 0xEBC349DE,
+/**/ 0xBF882448, 0xA3880000,
+/**/ 0xBD345544, 0x12C584E0,
+/**/ 0x3FF02C00, 0x00000000,
+/**/ 0x3F1E9417, 0x3FEFD386,
+/**/ 0xBF861E77, 0xE8B60000,
+/**/ 0x3D38073E, 0xEAF8EAF3,
+/**/ 0x3FF02800, 0x00000000,
+/**/ 0x3F193F1D, 0xCA7A317C,
+/**/ 0xBF841929, 0xF9680000,
+/**/ 0xBD1977C7, 0x55D01368,
+/**/ 0x3FF02400, 0x00000000,
+/**/ 0x3F146DF7, 0x6CB49652,
+/**/ 0xBF82145E, 0x939E0000,
+/**/ 0xBD3E3D12, 0x38C4EA00,
+/**/ 0x3FF02000, 0x00000000,
+/**/ 0x3F102040, 0x81020408,
+/**/ 0xBF801015, 0x75880000,
+/**/ 0xBD3BCE25, 0x1998B506,
+/**/ 0x3FF01C00, 0x00000000,
+/**/ 0x3F08AB2B, 0x8C355D63,
+/**/ 0xBF7C189C, 0xBB100000,
+/**/ 0x3D3D8055, 0x12588560,
+/**/ 0x3FF01800, 0x00000000,
+/**/ 0x3F021B28, 0xBD1BA97E,
+/**/ 0xBF781212, 0x14580000,
+/**/ 0xBD1AD503, 0x82973F27,
+/**/ 0x3FF01400, 0x00000000,
+/**/ 0x3EF91F67, 0x411155AB,
+/**/ 0xBF740C8A, 0x74780000,
+/**/ 0xBD1E3871, 0xDF070002,
+/**/ 0x3FF01000, 0x00000000,
+/**/ 0x3EF01010, 0x10101010,
+/**/ 0xBF700805, 0x59580000,
+/**/ 0xBD2166AF, 0xCB31C67B,
+/**/ 0x3FF00C00, 0x00000000,
+/**/ 0x3EE20D8A, 0x279DB649,
+/**/ 0xBF680904, 0x82880000,
+/**/ 0xBD285C06, 0x96A70C0C,
+/**/ 0x3FF00800, 0x00000000,
+/**/ 0x3ED00804, 0x02010080,
+/**/ 0xBF600401, 0x55D80000,
+/**/ 0x3D33BB10, 0xC7CC7089,
+/**/ 0x3FF00400, 0x00000000,
+/**/ 0x3EB00401, 0x00401004,
+/**/ 0xBF500200, 0x55600000,
+/**/ 0xBD356224, 0xCD5F35F8,
+/**/ 0x3FF00000, 0x00000000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x3FEFF800, 0x00000000,
+/**/ 0x3EAFF801, 0xFF801FF8,
+/**/ 0x3F4FFC00, 0xAA800000,
+/**/ 0x3D35621F, 0x7809A0A3,
+/**/ 0x3FEFF000, 0x00000000,
+/**/ 0x3ECFF007, 0xFC01FF00,
+/**/ 0x3F5FF802, 0xA9B00000,
+/**/ 0xBD33BC66, 0x1D61C5EB,
+/**/ 0x3FEFE800, 0x00000000,
+/**/ 0x3EE1F28A, 0x186DADBE,
+/**/ 0x3F67F704, 0x7D780000,
+/**/ 0x3D283DA6, 0x89D68648,
+/**/ 0x3FEFE000, 0x00000000,
+/**/ 0x3EEFE01F, 0xE01FE020,
+/**/ 0x3F6FF00A, 0xA2B00000,
+/**/ 0x3D20BC04, 0xA086B56A,
+/**/ 0x3FEFD800, 0x00000000,
+/**/ 0x3EF8E0E6, 0xDF68BD14,
+/**/ 0x3F73F38A, 0x60F00000,
+/**/ 0x3D192256, 0x93C93749,
+/**/ 0x3FEFD000, 0x00000000,
+/**/ 0x3F01E528, 0x439A981C,
+/**/ 0x3F77EE11, 0xEBD80000,
+/**/ 0x3D0749D3, 0xC2D23A07,
+/**/ 0x3FEFC800, 0x00000000,
+/**/ 0x3F08556A, 0x8596391C,
+/**/ 0x3F7BE79C, 0x70040000,
+/**/ 0x3D38EC8F, 0x9A6C0404,
+/**/ 0x3FEFC000, 0x00000000,
+/**/ 0x3F0FC07F, 0x01FC07F0,
+/**/ 0x3F7FE02A, 0x6B100000,
+/**/ 0x3D19E23F, 0x0DDA40E4,
+/**/ 0x3FEFB800, 0x00000000,
+/**/ 0x3F1412D5, 0x9F5976B5,
+/**/ 0x3F81EBDE, 0x2D1A0000,
+/**/ 0xBD2A0683, 0xFF48DC36,
+/**/ 0x3FEFB000, 0x00000000,
+/**/ 0x3F18C21A, 0xBD271E34,
+/**/ 0x3F83E729, 0x5D260000,
+/**/ 0xBD2609C1, 0xFF29A114,
+/**/ 0x3FEFA800, 0x00000000,
+/**/ 0x3F1DEDB2, 0x5594A734,
+/**/ 0x3F85E1F7, 0x03EC0000,
+/**/ 0x3D37CA09, 0xF585DA1B,
+/**/ 0x3FEFA000, 0x00000000,
+/**/ 0x3F21CAA0, 0x1FA11CAA,
+/**/ 0x3F87DC47, 0x5F820000,
+/**/ 0xBD3EB124, 0x5B5DA1F5,
+/**/ 0x3FEF9800, 0x00000000,
+/**/ 0x3F24DC34, 0x55E8CB6B,
+/**/ 0x3F89D61A, 0xADC60000,
+/**/ 0x3D37B196, 0x327B4257,
+/**/ 0x3FEF9000, 0x00000000,
+/**/ 0x3F282B68, 0x13BAF1B2,
+/**/ 0x3F8BCF71, 0x2C740000,
+/**/ 0x3D1C25E0, 0x97BD9771,
+/**/ 0x3FEF8800, 0x00000000,
+/**/ 0x3F2BB80D, 0xCC420861,
+/**/ 0x3F8DC84B, 0x19120000,
+/**/ 0x3D1C0A54, 0x1E3A5B30,
+/**/ 0x3FEF8000, 0x00000000,
+/**/ 0x3F2F81F8, 0x1F81F820,
+/**/ 0x3F8FC0A8, 0xB0FC0000,
+/**/ 0x3CDF1E7C, 0xF6D3A69C,
+/**/ 0x3FEF7800, 0x00000000,
+/**/ 0x3F31C47C, 0xED1079FA,
+/**/ 0x3F90DC45, 0x18B00000,
+/**/ 0xBD29BC2F, 0x380313FC,
+/**/ 0x3FEF7000, 0x00000000,
+/**/ 0x3F33E672, 0xFA98528D,
+/**/ 0x3F91D7F7, 0xEB9F0000,
+/**/ 0xBD14193A, 0x83FCC7A6,
+/**/ 0x3FEF6800, 0x00000000,
+/**/ 0x3F3626C7, 0xCAFBD3D2,
+/**/ 0x3F92D36C, 0xEFB50000,
+/**/ 0x3D35F0BB, 0x341706C3,
+/**/ 0x3FEF6000, 0x00000000,
+/**/ 0x3F388565, 0x06DDABA6,
+/**/ 0x3F93CEA4, 0x43470000,
+/**/ 0xBD36A2C4, 0x32D6A40B,
+/**/ 0x3FEF5800, 0x00000000,
+/**/ 0x3F3B0234, 0x6CC4F5F5,
+/**/ 0x3F94C99E, 0x04900000,
+/**/ 0x3D1DECC6, 0x5DF5F4A5,
+/**/ 0x3FEF5000, 0x00000000,
+/**/ 0x3F3D9D1F, 0xD102728A,
+/**/ 0x3F95C45A, 0x51B90000,
+/**/ 0xBD263BB6, 0x216D87D8,
+/**/ 0x3FEF5000, 0x00000000,
+/**/ 0xBF3FA9EE, 0xE26A1DD4,
+/**/ 0x3F96BED9, 0x48D20000,
+/**/ 0xBD320BC4, 0x160A43F8,
+/**/ 0x3FEF4800, 0x00000000,
+/**/ 0xBF3CD30D, 0xADEC7540,
+/**/ 0x3F97B91B, 0x07D60000,
+/**/ 0xBD33B955, 0xB602ACE4,
+/**/ 0x3FEF4000, 0x00000000,
+/**/ 0xBF39DE52, 0x7C761DC6,
+/**/ 0x3F98B31F, 0xACAA0000,
+/**/ 0xBD33FC78, 0xA96E4964,
+/**/ 0x3FEF3800, 0x00000000,
+/**/ 0xBF36CBD3, 0x23989FF0,
+/**/ 0x3F99ACE7, 0x551D0000,
+/**/ 0xBD2D75D9, 0x7EC7C410,
+/**/ 0x3FEF3000, 0x00000000,
+/**/ 0xBF339BA5, 0x639F8B15,
+/**/ 0x3F9AA672, 0x1EE80000,
+/**/ 0x3D2AD4EB, 0x5C5AF494,
+/**/ 0x3FEF2800, 0x00000000,
+/**/ 0xBF304DDE, 0xE7AA579B,
+/**/ 0x3F9B9FC0, 0x27B00000,
+/**/ 0xBD3B9A01, 0x0AE6922A,
+/**/ 0x3FEF2000, 0x00000000,
+/**/ 0xBF29C52A, 0x8B8C46FD,
+/**/ 0x3F9C98D1, 0x8D010000,
+/**/ 0xBD2BF615, 0x0589DF0F,
+/**/ 0x3FEF1800, 0x00000000,
+/**/ 0xBF22B3BB, 0xFE0E92B4,
+/**/ 0x3F9D91A6, 0x6C540000,
+/**/ 0x3D2E61F1, 0x658CFB9A,
+/**/ 0x3FEF1000, 0x00000000,
+/**/ 0xBF16CF39, 0xFE8B488E,
+/**/ 0x3F9E8A3E, 0xE30D0000,
+/**/ 0xBD21A9FA, 0x3DE53900,
+/**/ 0x3FEF0800, 0x00000000,
+/**/ 0xBEFF07C1, 0xF07C1F08,
+/**/ 0x3F9F829B, 0x0E780000,
+/**/ 0x3D298026, 0x7C7E09E4,
+/**/ 0x3FEF0000, 0x00000000,
+/**/ 0x3EFF003E, 0x007C00F8,
+/**/ 0x3FA03D5D, 0x85E70000,
+/**/ 0x3D3F7789, 0x60ED29CF,
+/**/ 0x3FEEF800, 0x00000000,
+/**/ 0x3F17B671, 0x3D759870,
+/**/ 0x3FA0B94F, 0x7C198000,
+/**/ 0xBD2E8989, 0x6F022783,
+/**/ 0x3FEEF000, 0x00000000,
+/**/ 0x3F241070, 0x2A8BB96A,
+/**/ 0x3FA13523, 0x78598000,
+/**/ 0xBD1C1AC3, 0xB71FA59B,
+/**/ 0x3FEEE800, 0x00000000,
+/**/ 0x3F2C7F84, 0x58E01EEA,
+/**/ 0x3FA1B0D9, 0x89240000,
+/**/ 0xBD33401E, 0x9AE889BB,
+/**/ 0x3FEEE000, 0x00000000,
+/**/ 0x3F329425, 0xA3D491BC,
+/**/ 0x3FA22C71, 0xBCEA8000,
+/**/ 0x3CFD2818, 0xF87F888F,
+/**/ 0x3FEED800, 0x00000000,
+/**/ 0x3F37054D, 0x9E9D2AE8,
+/**/ 0x3FA2A7EC, 0x22150000,
+/**/ 0xBD278CE7, 0x7A9163FE,
+/**/ 0x3FEED000, 0x00000000,
+/**/ 0x3F3B9325, 0x540C85E6,
+/**/ 0x3FA32348, 0xC7000000,
+/**/ 0x3D2696DB, 0x90B1E49F,
+/**/ 0x3FEED000, 0x00000000,
+/**/ 0xBF3FC267, 0xF099FC26,
+/**/ 0x3FA39E87, 0xB9FE8000,
+/**/ 0x3D3EAFD4, 0x80AD9015,
+/**/ 0x3FEEC800, 0x00000000,
+/**/ 0xBF3AFB6E, 0xD02A4E5D,
+/**/ 0x3FA419A9, 0x09590000,
+/**/ 0x3D3B5CDC, 0x67D48EA7,
+/**/ 0x3FEEC000, 0x00000000,
+/**/ 0xBF361803, 0xD7A79FF1,
+/**/ 0x3FA494AC, 0xC34D8000,
+/**/ 0x3D211C78, 0xA56FD247,
+/**/ 0x3FEEB800, 0x00000000,
+/**/ 0xBF31183B, 0x805C2197,
+/**/ 0x3FA50F92, 0xF60F8000,
+/**/ 0x3D296CFB, 0x0A91FFE3,
+/**/ 0x3FEEB000, 0x00000000,
+/**/ 0xBF27F854, 0x5FE15180,
+/**/ 0x3FA58A5B, 0xAFC90000,
+/**/ 0xBD2B2B73, 0x9570AD39,
+/**/ 0x3FEEA800, 0x00000000,
+/**/ 0xBF1B0F90, 0xE210C36A,
+/**/ 0x3FA60506, 0xFE990000,
+/**/ 0xBD32BA40, 0x8194E036,
+/**/ 0x3FEEA000, 0x00000000,
+/**/ 0xBEF6F7DD, 0x8C33ADB2,
+/**/ 0x3FA67F94, 0xF0948000,
+/**/ 0x3D3ECC1F, 0x3E7E4ED7,
+/**/ 0x3FEE9800, 0x00000000,
+/**/ 0x3F1003D3, 0x1003D310,
+/**/ 0x3FA6FA05, 0x93C78000,
+/**/ 0x3D3B415E, 0x41D634A1,
+/**/ 0x3FEE9000, 0x00000000,
+/**/ 0x3F231ABF, 0x0B7672A0,
+/**/ 0x3FA77458, 0xF6330000,
+/**/ 0xBD3181DC, 0xE586AF09,
+/**/ 0x3FEE8800, 0x00000000,
+/**/ 0x3F2E6B5C, 0xCF172481,
+/**/ 0x3FA7EE8F, 0x25CD8000,
+/**/ 0xBD3F4216, 0x11A5C1E9,
+/**/ 0x3FEE8000, 0x00000000,
+/**/ 0x3F34F9CD, 0x77A84876,
+/**/ 0x3FA868A8, 0x30840000,
+/**/ 0xBD12623A, 0x134AC693,
+/**/ 0x3FEE7800, 0x00000000,
+/**/ 0x3F3AD9A8, 0xD7473427,
+/**/ 0x3FA8E2A4, 0x243A0000,
+/**/ 0x3D2B9EEB, 0x01426490,
+/**/ 0x3FEE7800, 0x00000000,
+/**/ 0xBF3F2AD3, 0x4578DCCA,
+/**/ 0x3FA95C83, 0x0EC90000,
+/**/ 0xBD2C1482, 0x97C5FEB8,
+/**/ 0x3FEE7000, 0x00000000,
+/**/ 0xBF3913BA, 0x97A6A035,
+/**/ 0x3FA9D644, 0xFDFF8000,
+/**/ 0x3D313C90, 0x539A473B,
+/**/ 0x3FEE6800, 0x00000000,
+/**/ 0xBF32E120, 0xC594A915,
+/**/ 0x3FAA4FE9, 0xFFA40000,
+/**/ 0xBD36E584, 0xA0402925,
+/**/ 0x3FEE6000, 0x00000000,
+/**/ 0xBF292632, 0xC5DF4232,
+/**/ 0x3FAAC972, 0x21710000,
+/**/ 0x3D2F8D3E, 0xF013222C,
+/**/ 0x3FEE5800, 0x00000000,
+/**/ 0xBF18A6DF, 0xC3518A6E,
+/**/ 0x3FAB42DD, 0x71198000,
+/**/ 0xBD1C827A, 0xE5D6704C,
+/**/ 0x3FEE5000, 0x00000000,
+/**/ 0x3ED6BC08, 0x86833271,
+/**/ 0x3FABBC2B, 0xFC450000,
+/**/ 0xBD17D186, 0x91417DAF,
+/**/ 0x3FEE4800, 0x00000000,
+/**/ 0x3F1BEB2D, 0xE672838D,
+/**/ 0x3FAC355D, 0xD0920000,
+/**/ 0x3D2F2CCC, 0x9ABF8388,
+/**/ 0x3FEE4000, 0x00000000,
+/**/ 0x3F2B6B8D, 0x9785150A,
+/**/ 0x3FACAE72, 0xFB960000,
+/**/ 0xBD3EFABF, 0x2025B1BE,
+/**/ 0x3FEE3800, 0x00000000,
+/**/ 0x3F348BCE, 0xE0D399FA,
+/**/ 0x3FAD276B, 0x8ADB0000,
+/**/ 0x3D16A423, 0xC78A64B0,
+/**/ 0x3FEE3000, 0x00000000,
+/**/ 0x3F3B7CD0, 0x933AC00F,
+/**/ 0x3FADA047, 0x8BE38000,
+/**/ 0x3D2252C7, 0xB1F6FE05,
+/**/ 0x3FEE3000, 0x00000000,
+/**/ 0xBF3D7747, 0x308F5281,
+/**/ 0x3FAE1907, 0x0C278000,
+/**/ 0xBD2FEA46, 0x64629E86,
+/**/ 0x3FEE2800, 0x00000000,
+/**/ 0xBF36508B, 0x6C196F66,
+/**/ 0x3FAE91AA, 0x19150000,
+/**/ 0xBD0E82A0, 0x1DCC6A76,
+/**/ 0x3FEE2000, 0x00000000,
+/**/ 0xBF2E1E1E, 0x1E1E1E1E,
+/**/ 0x3FAF0A30, 0xC0118000,
+/**/ 0xBD2D599E, 0x83368E91,
+/**/ 0x3FEE1800, 0x00000000,
+/**/ 0xBF1ECB93, 0xDD355CDB,
+/**/ 0x3FAF829B, 0x0E780000,
+/**/ 0x3D398026, 0x7C7E09E4,
+/**/ 0x3FEE1000, 0x00000000,
+/**/ 0xBECE0FF8, 0x7C01E100,
+/**/ 0x3FAFFAE9, 0x119B8000,
+/**/ 0x3D230337, 0x4262C554,
+/**/ 0x3FEE0800, 0x00000000,
+/**/ 0x3F1D54B5, 0x25C73724,
+/**/ 0x3FB0398D, 0x6B624000,
+/**/ 0xBD3AB14D, 0xFCBFCD00,
+/**/ 0x3FEE0000, 0x00000000,
+/**/ 0x3F2E01E0, 0x1E01E01E,
+/**/ 0x3FB07598, 0x35990000,
+/**/ 0xBD3B8ECF, 0xE4B59987,
+/**/ 0x3FEDF800, 0x00000000,
+/**/ 0x3F36C715, 0xC84194BA,
+/**/ 0x3FB0B194, 0xEE0D0000,
+/**/ 0x3D3666EA, 0x4F69EDCC,
+/**/ 0x3FEDF000, 0x00000000,
+/**/ 0x3F3EA78B, 0xEF26D838,
+/**/ 0x3FB0ED83, 0x9B554000,
+/**/ 0xBD3901F4, 0x6D48ABB4,
+/**/ 0x3FEDF000, 0x00000000,
+/**/ 0xBF395DBF, 0xF10995DC,
+/**/ 0x3FB12964, 0x44030000,
+/**/ 0xBD3D53BB, 0x751AA773,
+/**/ 0x3FEDE800, 0x00000000,
+/**/ 0xBF3148E0, 0x3BCBADC8,
+/**/ 0x3FB16536, 0xEEA38000,
+/**/ 0xBD147C5E, 0x768FA309,
+/**/ 0x3FEDE000, 0x00000000,
+/**/ 0xBF2233CE, 0x86E25CE1,
+/**/ 0x3FB1A0FB, 0xA1BF8000,
+/**/ 0x3D24A3FC, 0xC319D6DC,
+/**/ 0x3FEDD800, 0x00000000,
+/**/ 0xBEEA1CE9, 0x26B3FE23,
+/**/ 0x3FB1DCB2, 0x63DB0000,
+/**/ 0x3D39444F, 0x5E9E8981,
+/**/ 0x3FEDD000, 0x00000000,
+/**/ 0x3F1E4836, 0x0AB71710,
+/**/ 0x3FB2185B, 0x3B75C000,
+/**/ 0xBD3E3189, 0xF8F32304,
+/**/ 0x3FEDC800, 0x00000000,
+/**/ 0x3F300EE5, 0x00EE500F,
+/**/ 0x3FB253F6, 0x2F0A0000,
+/**/ 0x3D3416F8, 0xFB69A701,
+/**/ 0x3FEDC000, 0x00000000,
+/**/ 0x3F38A58D, 0x231C226A,
+/**/ 0x3FB28F83, 0x450EC000,
+/**/ 0x3D3A8D75, 0xAA119769,
+/**/ 0x3FEDC000, 0x00000000,
+/**/ 0xBF3EAA0C, 0x14715D63,
+/**/ 0x3FB2CB02, 0x83F5C000,
+/**/ 0x3D3E1EE2, 0xCA657021,
+/**/ 0x3FEDB800, 0x00000000,
+/**/ 0xBF35DFF8, 0x92AEFFC5,
+/**/ 0x3FB30673, 0xF22C8000,
+/**/ 0x3D24C9E2, 0x9DCF0BA5,
+/**/ 0x3FEDB000, 0x00000000,
+/**/ 0xBF29F894, 0x67E251A0,
+/**/ 0x3FB341D7, 0x961BC000,
+/**/ 0x3D31D092, 0x99837610,
+/**/ 0x3FEDA800, 0x00000000,
+/**/ 0xBF0FF896, 0x1FF89620,
+/**/ 0x3FB37D2D, 0x76284000,
+/**/ 0xBD2C60AA, 0x9B7FF15C,
+/**/ 0x3FEDA000, 0x00000000,
+/**/ 0x3F145E70, 0x076828BD,
+/**/ 0x3FB3B875, 0x98B1C000,
+/**/ 0xBD222415, 0x94ACA313,
+/**/ 0x3FED9800, 0x00000000,
+/**/ 0x3F2C8F60, 0xE567D573,
+/**/ 0x3FB3F3B0, 0x04140000,
+/**/ 0x3CEE2474, 0xACDFCEC5,
+/**/ 0x3FED9000, 0x00000000,
+/**/ 0x3F379118, 0xF3FC4DA2,
+/**/ 0x3FB42EDC, 0xBEA64000,
+/**/ 0x3D1BC0EE, 0xEA7C9ACD,
+/**/ 0x3FED9000, 0x00000000,
+/**/ 0xBF3F0C3C, 0x049DE4C3,
+/**/ 0x3FB469FB, 0xCEBB4000,
+/**/ 0x3D3B663C, 0x4F257194,
+/**/ 0x3FED8800, 0x00000000,
+/**/ 0xBF35905F, 0xF13D5906,
+/**/ 0x3FB4A50D, 0x3AA1C000,
+/**/ 0xBD2F7FE1, 0x308973E2,
+/**/ 0x3FED8000, 0x00000000,
+/**/ 0xBF27F6C8, 0x77D1EA57,
+/**/ 0x3FB4E011, 0x08A34000,
+/**/ 0x3D3AE5CF, 0xDF2C5AE5,
+/**/ 0x3FED7800, 0x00000000,
+/**/ 0xBF026AD1, 0xF4F31BA0,
+/**/ 0x3FB51B07, 0x3F060000,
+/**/ 0x3D383F69, 0x278E686A,
+/**/ 0x3FED7000, 0x00000000,
+/**/ 0x3F1DE6B2, 0xF26DF1BD,
+/**/ 0x3FB555EF, 0xE40B4000,
+/**/ 0x3D30B497, 0x8C868E23,
+/**/ 0x3FED6800, 0x00000000,
+/**/ 0x3F31599F, 0x7BA23D96,
+/**/ 0x3FB590CA, 0xFDF00000,
+/**/ 0x3D3C284F, 0x5722ABAA,
+/**/ 0x3FED6000, 0x00000000,
+/**/ 0x3F3B526C, 0xD425A760,
+/**/ 0x3FB5CB98, 0x92ED4000,
+/**/ 0x3D17BE44, 0xA64FC52F,
+/**/ 0x3FED6000, 0x00000000,
+/**/ 0xBF3A9BFC, 0x546A6FF1,
+/**/ 0x3FB60658, 0xA9374000,
+/**/ 0x3D30C3B1, 0xDEE9C4F8,
+/**/ 0x3FED5800, 0x00000000,
+/**/ 0xBF3071AD, 0x08F02FAC,
+/**/ 0x3FB6410B, 0x46FE8000,
+/**/ 0xBD153F8F, 0x3CBD8D14,
+/**/ 0x3FED5000, 0x00000000,
+/**/ 0xBF18BAD9, 0x12C6C142,
+/**/ 0x3FB67BB0, 0x726EC000,
+/**/ 0x3CEF724B, 0x69EF5912,
+/**/ 0x3FED4800, 0x00000000,
+/**/ 0x3F10B35C, 0x3254A5A2,
+/**/ 0x3FB6B648, 0x31B00000,
+/**/ 0xBD3BF30A, 0x1377DE92,
+/**/ 0x3FED4000, 0x00000000,
+/**/ 0x3F2D41D4, 0x1D41D41D,
+/**/ 0x3FB6F0D2, 0x8AE58000,
+/**/ 0xBD34B464, 0x1B664613,
+/**/ 0x3FED3800, 0x00000000,
+/**/ 0x3F392D71, 0xF494E548,
+/**/ 0x3FB72B4F, 0x842EC000,
+/**/ 0xBD3704CC, 0xC00C9DD3,
+/**/ 0x3FED3800, 0x00000000,
+/**/ 0xBF3C2DA1, 0xFF165C2E,
+/**/ 0x3FB765BF, 0x23A6C000,
+/**/ 0xBCFECBC0, 0x35C4256A,
+/**/ 0x3FED3000, 0x00000000,
+/**/ 0xBF317062, 0x7AA49674,
+/**/ 0x3FB7A021, 0x6F648000,
+/**/ 0x3D3E124C, 0xA18418FF,
+/**/ 0x3FED2800, 0x00000000,
+/**/ 0xBF1A6B80, 0x749CB290,
+/**/ 0x3FB7DA76, 0x6D7B0000,
+/**/ 0x3D32CC84, 0x4480C89B,
+/**/ 0x3FED2000, 0x00000000,
+/**/ 0x3F114B52, 0x25C6336D,
+/**/ 0x3FB814BE, 0x23F8C000,
+/**/ 0x3CCB2381, 0xDA82FDFD,
+/**/ 0x3FED1800, 0x00000000,
+/**/ 0x3F2EB155, 0xF08A3B1D,
+/**/ 0x3FB84EF8, 0x98E84000,
+/**/ 0xBD37D5CD, 0x246977C9,
+/**/ 0x3FED1000, 0x00000000,
+/**/ 0x3F3A7692, 0xBD71CD93,
+/**/ 0x3FB88925, 0xD24FC000,
+/**/ 0xBD31D505, 0x44FBB806,
+/**/ 0x3FED1000, 0x00000000,
+/**/ 0xBF3A5384, 0x89FC5E69,
+/**/ 0x3FB8C345, 0xD6318000,
+/**/ 0x3D3B20F5, 0xACB42A66,
+/**/ 0x3FED0800, 0x00000000,
+/**/ 0xBF2E0B56, 0x6439240E,
+/**/ 0x3FB8FD58, 0xAA8C4000,
+/**/ 0xBD3EEC90, 0x1BCB725B,
+/**/ 0x3FED0000, 0x00000000,
+/**/ 0xBF0CFF8C, 0x01CFF8C0,
+/**/ 0x3FB9375E, 0x55594000,
+/**/ 0x3D3EDDC3, 0x7380C364,
+/**/ 0x3FECF800, 0x00000000,
+/**/ 0x3F1F7661, 0x546D8D78,
+/**/ 0x3FB97156, 0xDC8F8000,
+/**/ 0xBD3C1FC1, 0x9AFDB97B,
+/**/ 0x3FECF000, 0x00000000,
+/**/ 0x3F3372E2, 0x25FE30D9,
+/**/ 0x3FB9AB42, 0x46204000,
+/**/ 0xBD28A648, 0x26787061,
+/**/ 0x3FECE800, 0x00000000,
+/**/ 0x3F3F1FDB, 0xD92305A6,
+/**/ 0x3FB9E520, 0x97F9C000,
+/**/ 0x3D235FAC, 0xB52DD050,
+/**/ 0x3FECE800, 0x00000000,
+/**/ 0xBF351B8A, 0x9C37FC63,
+/**/ 0x3FBA1EF1, 0xD8060000,
+/**/ 0x3D3CD417, 0x6DF97BCB,
+/**/ 0x3FECE000, 0x00000000,
+/**/ 0xBF227EC2, 0x6CB725AB,
+/**/ 0x3FBA58B6, 0x0C2B4000,
+/**/ 0xBD3CDC73, 0x5C5C9F2A,
+/**/ 0x3FECD800, 0x00000000,
+/**/ 0x3F05A240, 0xE6C2B448,
+/**/ 0x3FBA926D, 0x3A4AC000,
+/**/ 0x3D356365, 0x0BD22A9C,
+/**/ 0x3FECD000, 0x00000000,
+/**/ 0x3F2D7EC2, 0xFBB8D9F3,
+/**/ 0x3FBACC17, 0x68434000,
+/**/ 0xBD2AA783, 0xA0B7FA4C,
+/**/ 0x3FECC800, 0x00000000,
+/**/ 0x3F3AE1DB, 0x1B71D3E9,
+/**/ 0x3FBB05B4, 0x9BEE4000,
+/**/ 0x3D0FF22C, 0x18F84A5E,
+/**/ 0x3FECC800, 0x00000000,
+/**/ 0xBF38E45A, 0xCD6DE82D,
+/**/ 0x3FBB3F44, 0xDB220000,
+/**/ 0x3D3FD153, 0xD8DE09AF,
+/**/ 0x3FECC000, 0x00000000,
+/**/ 0xBF29269F, 0xE341926A,
+/**/ 0x3FBB78C8, 0x2BB10000,
+/**/ 0xBD325EF7, 0xBC3987E7,
+/**/ 0x3FECB800, 0x00000000,
+/**/ 0xBEC589FB, 0xF620C1DA,
+/**/ 0x3FBBB23E, 0x93690000,
+/**/ 0xBD368B18, 0x3559DB8B,
+/**/ 0x3FECB000, 0x00000000,
+/**/ 0x3F28A893, 0x0DE5FF1A,
+/**/ 0x3FBBEBA8, 0x18148000,
+/**/ 0xBD389B78, 0xB6DF1F57,
+/**/ 0x3FECA800, 0x00000000,
+/**/ 0x3F38EAB9, 0x0039563B,
+/**/ 0x3FBC2504, 0xBF79C000,
+/**/ 0x3D3717C4, 0xD0EF4ADC,
+/**/ 0x3FECA800, 0x00000000,
+/**/ 0xBF3A67D5, 0x08F377F2,
+/**/ 0x3FBC5E54, 0x8F5BC000,
+/**/ 0x3D1D0C57, 0x585FBE06,
+/**/ 0x3FECA000, 0x00000000,
+/**/ 0xBF2B46E0, 0x072792E4,
+/**/ 0x3FBC9797, 0x8D790000,
+/**/ 0xBD36E010, 0x977D1884,
+/**/ 0x3FEC9800, 0x00000000,
+/**/ 0xBEE904EA, 0x1BB327C3,
+/**/ 0x3FBCD0CD, 0xBF8C0000,
+/**/ 0x3D33E14D, 0xB50DD743,
+/**/ 0x3FEC9000, 0x00000000,
+/**/ 0x3F2853EB, 0x77683AEC,
+/**/ 0x3FBD09F7, 0x2B4C4000,
+/**/ 0x3D2048C0, 0x00354E33,
+/**/ 0x3FEC8800, 0x00000000,
+/**/ 0x3F3932D7, 0xDC52100E,
+/**/ 0x3FBD4313, 0xD66CC000,
+/**/ 0xBD294543, 0x79135713,
+/**/ 0x3FEC8800, 0x00000000,
+/**/ 0xBF39AD90, 0x2736962B,
+/**/ 0x3FBD7C23, 0xC69CC000,
+/**/ 0xBD297EE4, 0xDD328771,
+/**/ 0x3FEC8000, 0x00000000,
+/**/ 0xBF28EEA2, 0xF316B4C2,
+/**/ 0x3FBDB527, 0x0187C000,
+/**/ 0x3D392778, 0x56AE181F,
+/**/ 0x3FEC7800, 0x00000000,
+/**/ 0x3EEAB099, 0x058F7536,
+/**/ 0x3FBDEE1D, 0x8CD60000,
+/**/ 0xBD328DA0, 0x729EFF89,
+/**/ 0x3FEC7000, 0x00000000,
+/**/ 0x3F2C71C7, 0x1C71C71C,
+/**/ 0x3FBE2707, 0x6E2B0000,
+/**/ 0xBD2A342C, 0x2AF0003C,
+/**/ 0x3FEC6800, 0x00000000,
+/**/ 0x3F3BB2BB, 0xD6422A30,
+/**/ 0x3FBE5FE4, 0xAB274000,
+/**/ 0xBD35FAE9, 0xF74FFE4D,
+/**/ 0x3FEC6800, 0x00000000,
+/**/ 0xBF36BD01, 0x54BDE47E,
+/**/ 0x3FBE98B5, 0x49670000,
+/**/ 0x3D346774, 0x89C50E97,
+/**/ 0x3FEC6000, 0x00000000,
+/**/ 0xBF222CC5, 0xB5157FE4,
+/**/ 0x3FBED179, 0x4E838000,
+/**/ 0xBD1FD143, 0x749D0484,
+/**/ 0x3FEC5800, 0x00000000,
+/**/ 0x3F129A21, 0xA930B840,
+/**/ 0x3FBF0A30, 0xC0118000,
+/**/ 0xBD3D599E, 0x83368E91,
+/**/ 0x3FEC5000, 0x00000000,
+/**/ 0x3F3279B1, 0xAC5CEE14,
+/**/ 0x3FBF42DB, 0xA3A24000,
+/**/ 0xBD3312B7, 0x32DF6C0D,
+/**/ 0x3FEC5000, 0x00000000,
+/**/ 0xBF3F9CF5, 0xD4AB8D0B,
+/**/ 0x3FBF7B79, 0xFEC38000,
+/**/ 0xBD010987, 0xE897ED01,
+/**/ 0x3FEC4800, 0x00000000,
+/**/ 0xBF319D7C, 0xCC17DAE4,
+/**/ 0x3FBFB40B, 0xD6FF4000,
+/**/ 0x3D2C0BEC, 0xB7B53B5B,
+/**/ 0x3FEC4000, 0x00000000,
+/**/ 0xBF0C3F8F, 0x01C3F8F0,
+/**/ 0x3FBFEC91, 0x31DC0000,
+/**/ 0xBD354555, 0xD1AE6607,
+/**/ 0x3FEC3800, 0x00000000,
+/**/ 0x3F254738, 0xAB1B8FFC,
+/**/ 0x3FC01285, 0x0A6E0000,
+/**/ 0xBD1A8619, 0x4805BF94,
+/**/ 0x3FEC3000, 0x00000000,
+/**/ 0x3F38E51F, 0x48B3C5D7,
+/**/ 0x3FC02EBB, 0x42BF4000,
+/**/ 0xBD15A8FA, 0x5CE00E5D,
+/**/ 0x3FEC3000, 0x00000000,
+/**/ 0xBF38C377, 0x867E595E,
+/**/ 0x3FC04AEB, 0x449F6000,
+/**/ 0x3D2AFA90, 0x65CCD35C,
+/**/ 0x3FEC2800, 0x00000000,
+/**/ 0xBF24AC6D, 0x15FE3D95,
+/**/ 0x3FC06715, 0x12CA6000,
+/**/ 0xBD2A4757, 0x9CDC0A3D,
+/**/ 0x3FEC2000, 0x00000000,
+/**/ 0x3F10B34F, 0x53B8CDAE,
+/**/ 0x3FC08338, 0xAFFA2000,
+/**/ 0x3D30533C, 0xAC823E27,
+/**/ 0x3FEC1800, 0x00000000,
+/**/ 0x3F32C599, 0x3FABB0F6,
+/**/ 0x3FC09F56, 0x1EE72000,
+/**/ 0xBD28F305, 0x7157D1A8,
+/**/ 0x3FEC1800, 0x00000000,
+/**/ 0xBF3E8BF4, 0x97CD1B6C,
+/**/ 0x3FC0BB6D, 0x6247A000,
+/**/ 0x3D35464F, 0x3CCD04B3,
+/**/ 0x3FEC1000, 0x00000000,
+/**/ 0xBF2F8FC7, 0xE3F1F8FC,
+/**/ 0x3FC0D77E, 0x7CD08000,
+/**/ 0x3D3CB2CD, 0x2EE2F482,
+/**/ 0x3FEC0800, 0x00000000,
+/**/ 0xBEEDC860, 0x5B199F35,
+/**/ 0x3FC0F389, 0x7134C000,
+/**/ 0xBD3DA359, 0xE893D6C6,
+/**/ 0x3FEC0000, 0x00000000,
+/**/ 0x3F2C01C0, 0x1C01C01C,
+/**/ 0x3FC10F8E, 0x42254000,
+/**/ 0xBD293B38, 0x43396307,
+/**/ 0x3FEBF800, 0x00000000,
+/**/ 0x3F3D0577, 0x256228AA,
+/**/ 0x3FC12B8C, 0xF2518000,
+/**/ 0x3D348A4A, 0x13C0A0FC,
+/**/ 0x3FEBF800, 0x00000000,
+/**/ 0xBF33E08B, 0xCB93A8A1,
+/**/ 0x3FC14785, 0x84674000,
+/**/ 0x3D156345, 0x1027C750,
+/**/ 0x3FEBF000, 0x00000000,
+/**/ 0xBF12C4DB, 0x1DE63F4A,
+/**/ 0x3FC16377, 0xFB124000,
+/**/ 0x3D091E1A, 0xBF41763E,
+/**/ 0x3FEBE800, 0x00000000,
+/**/ 0x3F2526D0, 0x769F9E4F,
+/**/ 0x3FC17F64, 0x58FCA000,
+/**/ 0x3D2843FA, 0xD093C8DC,
+/**/ 0x3FEBE000, 0x00000000,
+/**/ 0x3F39ED43, 0x5292D891,
+/**/ 0x3FC19B4A, 0xA0CEE000,
+/**/ 0xBD3D8824, 0x9621338B,
+/**/ 0x3FEBE000, 0x00000000,
+/**/ 0xBF36A3B3, 0x5FC845A9,
+/**/ 0x3FC1B72A, 0xD52F6000,
+/**/ 0x3D2E80A4, 0x1811A396,
+/**/ 0x3FEBD800, 0x00000000,
+/**/ 0xBF1C7E26, 0xB7230491,
+/**/ 0x3FC1D304, 0xF8C36000,
+/**/ 0xBD3A6D44, 0xDF451042,
+/**/ 0x3FEBD000, 0x00000000,
+/**/ 0x3F20F365, 0x451B61CB,
+/**/ 0x3FC1EED9, 0x0E2DC000,
+/**/ 0x3D161563, 0x7097648F,
+/**/ 0x3FEBC800, 0x00000000,
+/**/ 0x3F3827F3, 0xD72DD0AA,
+/**/ 0x3FC20AA7, 0x18102000,
+/**/ 0x3D3F2C94, 0x348552FE,
+/**/ 0x3FEBC800, 0x00000000,
+/**/ 0xBF3814D3, 0xBE0C262F,
+/**/ 0x3FC2266F, 0x190A6000,
+/**/ 0xBD24D20A, 0xB840E7F6,
+/**/ 0x3FEBC000, 0x00000000,
+/**/ 0xBF207963, 0x7ECECB53,
+/**/ 0x3FC24231, 0x13BA6000,
+/**/ 0xBD3E3A00, 0x78EE9D9C,
+/**/ 0x3FEBB800, 0x00000000,
+/**/ 0x3F1EC130, 0xF29268D3,
+/**/ 0x3FC25DED, 0x0ABC6000,
+/**/ 0x3D35A385, 0x4F176449,
+/**/ 0x3FEBB000, 0x00000000,
+/**/ 0x3F37B218, 0xAB6353BF,
+/**/ 0x3FC279A3, 0x00AB4000,
+/**/ 0x3D3EF432, 0xB3235108,
+/**/ 0x3FEBB000, 0x00000000,
+/**/ 0xBF383759, 0xF2298376,
+/**/ 0x3FC29552, 0xF8200000,
+/**/ 0xBD35B967, 0xF4471DFC,
+/**/ 0x3FEBA800, 0x00000000,
+/**/ 0xBF201832, 0x1EAD4253,
+/**/ 0x3FC2B0FC, 0xF3B1A000,
+/**/ 0x3D177CA3, 0xE30A59EA,
+/**/ 0x3FEBA000, 0x00000000,
+/**/ 0x3F20679B, 0xD84886B1,
+/**/ 0x3FC2CCA0, 0xF5F60000,
+/**/ 0xBD3B5EF1, 0x91AFF120,
+/**/ 0x3FEB9800, 0x00000000,
+/**/ 0x3F38884D, 0xA41FEB4C,
+/**/ 0x3FC2E83F, 0x0180E000,
+/**/ 0xBD3F0C2A, 0xC284E1CE,
+/**/ 0x3FEB9800, 0x00000000,
+/**/ 0xBF370EA7, 0x3806E548,
+/**/ 0x3FC303D7, 0x18E48000,
+/**/ 0xBCD680B5, 0xCE3ECB05,
+/**/ 0x3FEB9000, 0x00000000,
+/**/ 0xBF1A4477, 0xB5EF34C0,
+/**/ 0x3FC31F69, 0x3EB1A000,
+/**/ 0xBD2A6726, 0xE5A396FB,
+/**/ 0x3FEB8800, 0x00000000,
+/**/ 0x3F2401B8, 0x9401B894,
+/**/ 0x3FC33AF5, 0x75770000,
+/**/ 0x3D3C9ECC, 0xA2FE72A5,
+/**/ 0x3FEB8000, 0x00000000,
+/**/ 0x3F3AA73A, 0x400DC1AA,
+/**/ 0x3FC3567B, 0xBFC22000,
+/**/ 0x3D3250D2, 0x53991A1F,
+/**/ 0x3FEB8000, 0x00000000,
+/**/ 0xBF349E11, 0x2E63A6A8,
+/**/ 0x3FC371FC, 0x201E8000,
+/**/ 0x3D3EE877, 0x9B2D8ABC,
+/**/ 0x3FEB7800, 0x00000000,
+/**/ 0xBF0E7898, 0xC8DA04B9,
+/**/ 0x3FC38D76, 0x99164000,
+/**/ 0x3D1844A5, 0x9E39BB70,
+/**/ 0x3FEB7000, 0x00000000,
+/**/ 0x3F2A284E, 0xE6B33E2D,
+/**/ 0x3FC3A8EB, 0x2D31A000,
+/**/ 0x3D1BAFB7, 0x7D5D503E,
+/**/ 0x3FEB6800, 0x00000000,
+/**/ 0x3F3E0B91, 0x759C2BB4,
+/**/ 0x3FC3C459, 0xDEF76000,
+/**/ 0x3D3EDC86, 0xF6B70D33,
+/**/ 0x3FEB6800, 0x00000000,
+/**/ 0xBF30E8E2, 0x088FD6E7,
+/**/ 0x3FC3DFC2, 0xB0ECC000,
+/**/ 0x3D28A72A, 0x62B8C13F,
+/**/ 0x3FEB6000, 0x00000000,
+/**/ 0x3ECB6006, 0xD801B600,
+/**/ 0x3FC3FB25, 0xA5952000,
+/**/ 0x3D3195BE, 0x6B358FF7,
+/**/ 0x3FEB5800, 0x00000000,
+/**/ 0x3F316A6A, 0xD840F62C,
+/**/ 0x3FC41682, 0xBF728000,
+/**/ 0xBD210047, 0x081F849D,
+/**/ 0x3FEB5800, 0x00000000,
+/**/ 0xBF3D4DEE, 0x7DF8BD99,
+/**/ 0x3FC431DA, 0x01050000,
+/**/ 0x3D304837, 0x836E0391,
+/**/ 0x3FEB5000, 0x00000000,
+/**/ 0xBF27E4B1, 0x7E4B17E5,
+/**/ 0x3FC44D2B, 0x6CCB8000,
+/**/ 0xBD170CC1, 0x6135783C,
+/**/ 0x3FEB4800, 0x00000000,
+/**/ 0x3F15F47D, 0x55E6D8FE,
+/**/ 0x3FC46877, 0x05430000,
+/**/ 0xBD3D8145, 0xF8D5087E,
+/**/ 0x3FEB4000, 0x00000000,
+/**/ 0x3F37006D, 0x0B803686,
+/**/ 0x3FC483BC, 0xCCE6E000,
+/**/ 0x3D1EEA52, 0x723F6369,
+/**/ 0x3FEB4000, 0x00000000,
+/**/ 0xBF37687C, 0x46A66920,
+/**/ 0x3FC49EFC, 0xC6314000,
+/**/ 0xBD090F59, 0x9F55572B,
+/**/ 0x3FEB3800, 0x00000000,
+/**/ 0xBF16F6A4, 0xFF2645BE,
+/**/ 0x3FC4BA36, 0xF39A6000,
+/**/ 0xBD34354B, 0xB3F219E5,
+/**/ 0x3FEB3000, 0x00000000,
+/**/ 0x3F2801B3, 0x1801B318,
+/**/ 0x3FC4D56B, 0x5798E000,
+/**/ 0x3D380580, 0x15A96555,
+/**/ 0x3FEB2800, 0x00000000,
+/**/ 0x3F3DD2FF, 0x93511680,
+/**/ 0x3FC4F099, 0xF4A24000,
+/**/ 0xBD3E9BF2, 0xFAFEAF27,
+/**/ 0x3FEB2800, 0x00000000,
+/**/ 0xBF304743, 0xA89DCCAC,
+/**/ 0x3FC50BC2, 0xCD29C000,
+/**/ 0x3D1ADA57, 0x28DB8D4F,
+/**/ 0x3FEB2000, 0x00000000,
+/**/ 0x3EFB2036, 0x406C80D9,
+/**/ 0x3FC526E5, 0xE3A1C000,
+/**/ 0xBD3790BA, 0x37FC5238,
+/**/ 0x3FEB1800, 0x00000000,
+/**/ 0x3F33BEC8, 0x4F9DC00E,
+/**/ 0x3FC54203, 0x3A7A8000,
+/**/ 0x3D268D68, 0xED855F0E,
+/**/ 0x3FEB1800, 0x00000000,
+/**/ 0xBF3A2101, 0x44F8CE7E,
+/**/ 0x3FC55D1A, 0xD4232000,
+/**/ 0x3D3ADD94, 0xDDA647E8,
+/**/ 0x3FEB1000, 0x00000000,
+/**/ 0xBF1FB596, 0xB99AF3F3,
+/**/ 0x3FC5782C, 0xB3092000,
+/**/ 0xBD33A463, 0x51794442,
+/**/ 0x3FEB0800, 0x00000000,
+/**/ 0x3F24B31D, 0x922A3E85,
+/**/ 0x3FC59338, 0xD9982000,
+/**/ 0x3CF0BA68, 0xB7555D4A,
+/**/ 0x3FEB0000, 0x00000000,
+/**/ 0x3F3CB3CF, 0xE19BF6B7,
+/**/ 0x3FC5AE3F, 0x4A3AA000,
+/**/ 0x3D21EA25, 0xF012A8B9,
+/**/ 0x3FEB0000, 0x00000000,
+/**/ 0xBF30DEAE, 0x9A5BF0D1,
+/**/ 0x3FC5C940, 0x07598000,
+/**/ 0xBD3A8D94, 0x8CD23322,
+/**/ 0x3FEAF800, 0x00000000,
+/**/ 0x3EFA2072, 0x9EDE13CE,
+/**/ 0x3FC5E43B, 0x135BE000,
+/**/ 0xBD343AB4, 0xCEED9C31,
+/**/ 0x3FEAF000, 0x00000000,
+/**/ 0x3F3435E5, 0x0D79435E,
+/**/ 0x3FC5FF30, 0x70A7A000,
+/**/ 0xBD38586F, 0x183BEBF2,
+/**/ 0x3FEAF000, 0x00000000,
+/**/ 0xBF392321, 0x06855D30,
+/**/ 0x3FC61A20, 0x21A0E000,
+/**/ 0x3D3DD9DD, 0x1BDF3CDD,
+/**/ 0x3FEAE800, 0x00000000,
+/**/ 0xBF19A45C, 0x7ABED811,
+/**/ 0x3FC6350A, 0x28AAA000,
+/**/ 0x3D2D5EC0, 0xAB8163AF,
+/**/ 0x3FEAE000, 0x00000000,
+/**/ 0x3F28C7ED, 0x84EF68CB,
+/**/ 0x3FC64FEE, 0x88260000,
+/**/ 0xBD1DA40D, 0x759DDED6,
+/**/ 0x3FEAD800, 0x00000000,
+/**/ 0x3F3F43FC, 0xA482F00D,
+/**/ 0x3FC66ACD, 0x4272A000,
+/**/ 0x3D3AA1BD, 0xBFC6C785,
+/**/ 0x3FEAD800, 0x00000000,
+/**/ 0xBF2B9222, 0xCDE3E7AE,
+/**/ 0x3FC685A6, 0x59EF0000,
+/**/ 0xBD21F2A9, 0x6C103214,
+/**/ 0x3FEAD000, 0x00000000,
+/**/ 0x3F14F302, 0xEED254A3,
+/**/ 0x3FC6A079, 0xD0F7A000,
+/**/ 0x3D35A3F8, 0x448D14F5,
+/**/ 0x3FEAC800, 0x00000000,
+/**/ 0x3F385567, 0x32071DEF,
+/**/ 0x3FC6BB47, 0xA9E80000,
+/**/ 0x3D19F64D, 0x23EA3296,
+/**/ 0x3FEAC800, 0x00000000,
+/**/ 0xBF347F29, 0xD47F29D4,
+/**/ 0x3FC6D60F, 0xE719E000,
+/**/ 0xBD3BC6E5, 0x57134767,
+/**/ 0x3FEAC000, 0x00000000,
+/**/ 0xBEF40FE1, 0xE82D23BC,
+/**/ 0x3FC6F0D2, 0x8AE56000,
+/**/ 0x3D369737, 0xC93373DA,
+/**/ 0x3FEAB800, 0x00000000,
+/**/ 0x3F320FDE, 0x972D8538,
+/**/ 0x3FC70B8F, 0x97A1A000,
+/**/ 0x3D34EA64, 0xF6A95BEF,
+/**/ 0x3FEAB800, 0x00000000,
+/**/ 0xBF3A8C9F, 0x66711513,
+/**/ 0x3FC72647, 0x0FA40000,
+/**/ 0xBD3774DF, 0x0E743A45,
+/**/ 0x3FEAB000, 0x00000000,
+/**/ 0xBF1C5A0F, 0x02806ABC,
+/**/ 0x3FC740F8, 0xF5404000,
+/**/ 0xBD30B66C, 0x99018AA1,
+/**/ 0x3FEAA800, 0x00000000,
+/**/ 0x3F28E44B, 0xD22C937A,
+/**/ 0x3FC75BA5, 0x4AC8E000,
+/**/ 0x3D3DDCA5, 0x8BC4A7C0,
+/**/ 0x3FEAA800, 0x00000000,
+/**/ 0xBF3FF2AD, 0xFF2ADFF3,
+/**/ 0x3FC7764C, 0x128F2000,
+/**/ 0x3D027490, 0x3479E3D1,
+/**/ 0x3FEAA000, 0x00000000,
+/**/ 0xBF288A16, 0x0B3ADA5C,
+/**/ 0x3FC790ED, 0x4EE26000,
+/**/ 0x3D199BBD, 0x4E7746F6,
+/**/ 0x3FEA9800, 0x00000000,
+/**/ 0x3F1DEC0D, 0x4C77B035,
+/**/ 0x3FC7AB89, 0x0210E000,
+/**/ 0xBD2BDB90, 0x72534A58,
+/**/ 0x3FEA9000, 0x00000000,
+/**/ 0x3F3B4D71, 0x91F59E6B,
+/**/ 0x3FC7C61F, 0x2E674000,
+/**/ 0xBD32392D, 0xB31BE8E0,
+/**/ 0x3FEA9000, 0x00000000,
+/**/ 0xBF30CDCB, 0xB8A2A522,
+/**/ 0x3FC7E0AF, 0xD630C000,
+/**/ 0x3D139E7C, 0x1D8F1034,
+/**/ 0x3FEA8800, 0x00000000,
+/**/ 0x3F094A00, 0x6A2194A0,
+/**/ 0x3FC7FB3A, 0xFBB76000,
+/**/ 0xBD37DBF5, 0x24609D57,
+/**/ 0x3FEA8000, 0x00000000,
+/**/ 0x3F373289, 0x870AC52E,
+/**/ 0x3FC815C0, 0xA1436000,
+/**/ 0xBD302A52, 0xF9201CE8,
+/**/ 0x3FEA8000, 0x00000000,
+/**/ 0xBF34B1FA, 0x9E8684DD,
+/**/ 0x3FC83040, 0xC91BC000,
+/**/ 0x3D3E5B71, 0xC6E66F32,
+/**/ 0x3FEA7800, 0x00000000,
+/**/ 0xBEE08AF5, 0xA9267648,
+/**/ 0x3FC84ABB, 0x75866000,
+/**/ 0xBD3D8DAA, 0xDF4E2BD2,
+/**/ 0x3FEA7000, 0x00000000,
+/**/ 0x3F33BB67, 0x1A3D927E,
+/**/ 0x3FC86530, 0xA8C70000,
+/**/ 0x3D398BB0, 0xCB4EA3E3,
+/**/ 0x3FEA7000, 0x00000000,
+/**/ 0xBF37F2C9, 0x7F2C97F3,
+/**/ 0x3FC87FA0, 0x6520C000,
+/**/ 0x3D322120, 0x401202FC,
+/**/ 0x3FEA6800, 0x00000000,
+/**/ 0xBF0C77A5, 0x3C076D20,
+/**/ 0x3FC89A0A, 0xACD4E000,
+/**/ 0x3D2C0BFB, 0xDA8F5A72,
+/**/ 0x3FEA6000, 0x00000000,
+/**/ 0x3F30E6DA, 0x7C7EF82B,
+/**/ 0x3FC8B46F, 0x82236000,
+/**/ 0x3D12D9F2, 0x102DD7C9,
+/**/ 0x3FEA6000, 0x00000000,
+/**/ 0xBF3A9167, 0x2EC05C44,
+/**/ 0x3FC8CECE, 0xE74AE000,
+/**/ 0xBD3A5BA0, 0xAA429BB5,
+/**/ 0x3FEA5800, 0x00000000,
+/**/ 0xBF17DF12, 0xEEB6BD53,
+/**/ 0x3FC8E928, 0xDE886000,
+/**/ 0x3D3A8154, 0xB13D72D5,
+/**/ 0x3FEA5000, 0x00000000,
+/**/ 0x3F2D676D, 0x98C70AE6,
+/**/ 0x3FC9037D, 0x6A180000,
+/**/ 0x3D230DEA, 0x57C1C8D9,
+/**/ 0x3FEA5000, 0x00000000,
+/**/ 0xBF3C8EFF, 0x96CE4780,
+/**/ 0x3FC91DCC, 0x8C340000,
+/**/ 0x3D37BC6A, 0xBDDEFF46,
+/**/ 0x3FEA4800, 0x00000000,
+/**/ 0xBF1EFFCB, 0x71EFFCB7,
+/**/ 0x3FC93816, 0x4715A000,
+/**/ 0xBD34C63D, 0x6A3A39D9,
+/**/ 0x3FEA4000, 0x00000000,
+/**/ 0x3F2A41A4, 0x1A41A41A,
+/**/ 0x3FC9525A, 0x9CF46000,
+/**/ 0xBD329713, 0x7D9F158F,
+/**/ 0x3FEA4000, 0x00000000,
+/**/ 0xBF3DECBB, 0xBF3B3C0E,
+/**/ 0x3FC96C99, 0x9006A000,
+/**/ 0x3D2A88D5, 0x9CBB452C,
+/**/ 0x3FEA3800, 0x00000000,
+/**/ 0xBF21D14E, 0x3BCD35A8,
+/**/ 0x3FC986D3, 0x22818000,
+/**/ 0x3CF93B56, 0x4DD44000,
+/**/ 0x3FEA3000, 0x00000000,
+/**/ 0x3F285A0A, 0x3B5832C0,
+/**/ 0x3FC9A107, 0x56988000,
+/**/ 0x3D264AA6, 0x242CD098,
+/**/ 0x3FEA3000, 0x00000000,
+/**/ 0xBF3EABC1, 0xD71AFD8C,
+/**/ 0x3FC9BB36, 0x2E7E0000,
+/**/ 0xBD21F2A8, 0xA1CE0FFC,
+/**/ 0x3FEA2800, 0x00000000,
+/**/ 0xBF22E60D, 0x7C041611,
+/**/ 0x3FC9D55F, 0xAC62E000,
+/**/ 0xBD3F4669, 0xFC3B5BC3,
+/**/ 0x3FEA2000, 0x00000000,
+/**/ 0x3F27AE57, 0x5FF2EF43,
+/**/ 0x3FC9EF83, 0xD276A000,
+/**/ 0xBD2730B7, 0xB3F9CE00,
+/**/ 0x3FEA2000, 0x00000000,
+/**/ 0xBF3ECD35, 0x3D66322E,
+/**/ 0x3FCA09A2, 0xA2E7A000,
+/**/ 0xBD2DD99D, 0xCD411233,
+/**/ 0x3FEA1800, 0x00000000,
+/**/ 0xBF22C068, 0x5B4FE5E9,
+/**/ 0x3FCA23BC, 0x1FE2C000,
+/**/ 0xBD3539CD, 0x91DC9F0B,
+/**/ 0x3FEA1000, 0x00000000,
+/**/ 0x3F283C48, 0x80B67A9A,
+/**/ 0x3FCA3DD0, 0x4B938000,
+/**/ 0x3D297DA1, 0x366E2C5A,
+/**/ 0x3FEA1000, 0x00000000,
+/**/ 0xBF3E5236, 0x89907BBA,
+/**/ 0x3FCA57DF, 0x28244000,
+/**/ 0x3D3B99C8, 0xCA1D9ABB,
+/**/ 0x3FEA0800, 0x00000000,
+/**/ 0xBF21629E, 0x32054967,
+/**/ 0x3FCA71E8, 0xB7BE0000,
+/**/ 0xBD210ACA, 0x6EF05323,
+/**/ 0x3FEA0000, 0x00000000,
+/**/ 0x3F2A01A0, 0x1A01A01A,
+/**/ 0x3FCA8BEC, 0xFC882000,
+/**/ 0x3D3E3185, 0xCF21B9CF,
+/**/ 0x3FEA0000, 0x00000000,
+/**/ 0xBF3D3BE3, 0x93FF301D,
+/**/ 0x3FCAA5EB, 0xF8A94000,
+/**/ 0xBD32A0A9, 0x36951A8F,
+/**/ 0x3FE9F800, 0x00000000,
+/**/ 0xBF1D9DD1, 0xBFE608ED,
+/**/ 0x3FCABFE5, 0xAE462000,
+/**/ 0xBD3B68F5, 0x395F139D,
+/**/ 0x3FE9F000, 0x00000000,
+/**/ 0x3F2CFC26, 0x1B29257F,
+/**/ 0x3FCAD9DA, 0x1F828000,
+/**/ 0xBD3882B7, 0xC803F050,
+/**/ 0x3FE9F000, 0x00000000,
+/**/ 0xBF3B8B57, 0x7E613717,
+/**/ 0x3FCAF3C9, 0x4E80C000,
+/**/ 0xBCBA4E63, 0x3FCD9066,
+/**/ 0x3FE9E800, 0x00000000,
+/**/ 0xBF160EF9, 0xB9FABD04,
+/**/ 0x3FCB0DB3, 0x3D620000,
+/**/ 0x3D3FEE14, 0x38EAB906,
+/**/ 0x3FE9E000, 0x00000000,
+/**/ 0x3F3094D3, 0xEAF850E2,
+/**/ 0x3FCB2797, 0xEE464000,
+/**/ 0xBD3BE88A, 0x906D00A9,
+/**/ 0x3FE9E000, 0x00000000,
+/**/ 0xBF3941AA, 0xBBE88FDC,
+/**/ 0x3FCB4177, 0x634BA000,
+/**/ 0x3D355D01, 0x5666069F,
+/**/ 0x3FE9D800, 0x00000000,
+/**/ 0xBF083A25, 0x25F4B1AA,
+/**/ 0x3FCB5B51, 0x9E8FC000,
+/**/ 0xBD34B722, 0xEC011F31,
+/**/ 0x3FE9D000, 0x00000000,
+/**/ 0x3F3343FB, 0xF71FAC14,
+/**/ 0x3FCB7526, 0xA22E4000,
+/**/ 0x3D2C0DBF, 0x2E785490,
+/**/ 0x3FE9D000, 0x00000000,
+/**/ 0xBF365FF3, 0x1965FF32,
+/**/ 0x3FCB8EF6, 0x70420000,
+/**/ 0x3D387533, 0x321788E0,
+/**/ 0x3FE9C800, 0x00000000,
+/**/ 0x3EA9C801, 0x9C8019C8,
+/**/ 0x3FCBA8C1, 0x0AE46000,
+/**/ 0x3D3A32E2, 0x9EEE9D85,
+/**/ 0x3FE9C000, 0x00000000,
+/**/ 0x3F368A77, 0x25080CE1,
+/**/ 0x3FCBC286, 0x742D8000,
+/**/ 0x3D39AC53, 0xF39D121C,
+/**/ 0x3FE9C000, 0x00000000,
+/**/ 0xBF32E743, 0xC54763F2,
+/**/ 0x3FCBDC46, 0xAE344000,
+/**/ 0x3D3625B4, 0x023D6505,
+/**/ 0x3FE9B800, 0x00000000,
+/**/ 0x3F0DBD49, 0x8B7424F9,
+/**/ 0x3FCBF601, 0xBB0E4000,
+/**/ 0x3D2386A9, 0x47C378B5,
+/**/ 0x3FE9B000, 0x00000000,
+/**/ 0x3F3A6734, 0x00CD9A67,
+/**/ 0x3FCC0FB7, 0x9CCFE000,
+/**/ 0xBD346FFF, 0x99E8A558,
+/**/ 0x3FE9B000, 0x00000000,
+/**/ 0xBF2DB15A, 0xAEF25B7C,
+/**/ 0x3FCC2968, 0x558C2000,
+/**/ 0xBD2CFD73, 0xDEE38A40,
+/**/ 0x3FE9A800, 0x00000000,
+/**/ 0x3F1FDFEC, 0xC140C073,
+/**/ 0x3FCC4313, 0xE754E000,
+/**/ 0x3D3279BE, 0x74CAD7D6,
+/**/ 0x3FE9A000, 0x00000000,
+/**/ 0x3F3ED923, 0xA7DCBEB3,
+/**/ 0x3FCC5CBA, 0x543AE000,
+/**/ 0x3D20929D, 0xECB454FC,
+/**/ 0x3FE9A000, 0x00000000,
+/**/ 0xBF246A7B, 0xB256DE2C,
+/**/ 0x3FCC765B, 0x9E4D6000,
+/**/ 0x3D31AB6B, 0x36976F6C,
+/**/ 0x3FE99800, 0x00000000,
+/**/ 0x3F299999, 0x9999999A,
+/**/ 0x3FCC8FF7, 0xC79AA000,
+/**/ 0xBD27794F, 0x689F8434,
+/**/ 0x3FE99800, 0x00000000,
+/**/ 0xBF3C20C6, 0x3EC03FF3,
+/**/ 0x3FCCA98E, 0xD22F6000,
+/**/ 0xBCF698C1, 0x8CA209C8,
+/**/ 0x3FE99000, 0x00000000,
+/**/ 0xBF13F803, 0x31EC07FD,
+/**/ 0x3FCCC320, 0xC0176000,
+/**/ 0x3D240903, 0x9A653794,
+/**/ 0x3FE98800, 0x00000000,
+/**/ 0x3F323513, 0x5AC98715,
+/**/ 0x3FCCDCAD, 0x935D2000,
+/**/ 0xBD0A0FF0, 0x34C9A447,
+/**/ 0x3FE98800, 0x00000000,
+/**/ 0xBF368793, 0x89F80661,
+/**/ 0x3FCCF635, 0x4E09C000,
+/**/ 0x3D277123, 0x9A07D55B,
+/**/ 0x3FE98000, 0x00000000,
+/**/ 0x3EE98019, 0x8019801A,
+/**/ 0x3FCD0FB7, 0xF2256000,
+/**/ 0xBD0AF52B, 0x20633B29,
+/**/ 0x3FE97800, 0x00000000,
+/**/ 0x3F382FC6, 0xAB329020,
+/**/ 0x3FCD2935, 0x81B6C000,
+/**/ 0xBD383270, 0x128AAA5F,
+/**/ 0x3FE97800, 0x00000000,
+/**/ 0xBF305C4B, 0x962DBFF3,
+/**/ 0x3FCD42AD, 0xFEC36000,
+/**/ 0xBD175C00, 0xFD804272,
+/**/ 0x3FE97000, 0x00000000,
+/**/ 0x3F1C9F01, 0x970E4F81,
+/**/ 0x3FCD5C21, 0x6B4FC000,
+/**/ 0xBD21BA91, 0xBBCA681B,
+/**/ 0x3FE96800, 0x00000000,
+/**/ 0x3F3EBBE1, 0x049160B8,
+/**/ 0x3FCD758F, 0xC95F0000,
+/**/ 0xBD15A10A, 0x8B4162AA,
+/**/ 0x3FE96800, 0x00000000,
+/**/ 0xBF233FE6, 0x9933FE6A,
+/**/ 0x3FCD8EF9, 0x1AF32000,
+/**/ 0xBD15105F, 0xC364C784,
+/**/ 0x3FE96000, 0x00000000,
+/**/ 0x3F2C2873, 0xCE078906,
+/**/ 0x3FCDA85D, 0x620CE000,
+/**/ 0x3D240194, 0xC16CC7EC,
+/**/ 0x3FE96000, 0x00000000,
+/**/ 0xBF3A27A0, 0xE442936B,
+/**/ 0x3FCDC1BC, 0xA0ABE000,
+/**/ 0x3D38FAC1, 0xA628CCC6,
+/**/ 0x3FE95800, 0x00000000,
+/**/ 0xBF029C69, 0x548A97A9,
+/**/ 0x3FCDDB16, 0xD8CEA000,
+/**/ 0xBD1EEF79, 0x7104B8BC,
+/**/ 0x3FE95000, 0x00000000,
+/**/ 0x3F35906B, 0x9F74B92D,
+/**/ 0x3FCDF46C, 0x0C722000,
+/**/ 0x3D3A5E82, 0xB0B79039,
+/**/ 0x3FE95000, 0x00000000,
+/**/ 0xBF327BBF, 0xF35927BC,
+/**/ 0x3FCE0DBC, 0x3D92A000,
+/**/ 0x3D359233, 0xF0529BF1,
+/**/ 0x3FE94800, 0x00000000,
+/**/ 0x3F161F9A, 0xDD3C0CA4,
+/**/ 0x3FCE2707, 0x6E2B0000,
+/**/ 0xBD3A342C, 0x2AF0003C,
+/**/ 0x3FE94000, 0x00000000,
+/**/ 0x3F3D9B56, 0x41228A8F,
+/**/ 0x3FCE404D, 0xA034C000,
+/**/ 0xBD3187EE, 0xE09A2799,
+/**/ 0x3FE94000, 0x00000000,
+/**/ 0xBF2482F5, 0x598A73F8,
+/**/ 0x3FCE598E, 0xD5A88000,
+/**/ 0xBD0D134B, 0xCF1E98A1,
+/**/ 0x3FE93800, 0x00000000,
+/**/ 0x3F2BE2D5, 0x3C1B9728,
+/**/ 0x3FCE72CB, 0x107DA000,
+/**/ 0x3D1DD48C, 0xCDF5471C,
+/**/ 0x3FE93800, 0x00000000,
+/**/ 0xBF39CC03, 0x2698CFF3,
+/**/ 0x3FCE8C02, 0x52AA6000,
+/**/ 0xBD26805B, 0x80E8E6FF,
+/**/ 0x3FE93000, 0x00000000,
+/**/ 0xBEF79CD3, 0xB9F30358,
+/**/ 0x3FCEA534, 0x9E23A000,
+/**/ 0x3D381B93, 0x4C73CCB5,
+/**/ 0x3FE92800, 0x00000000,
+/**/ 0x3F36E803, 0x255BA00D,
+/**/ 0x3FCEBE61, 0xF4DD8000,
+/**/ 0xBD23D453, 0x30FDCA4D,
+/**/ 0x3FE92800, 0x00000000,
+/**/ 0xBF30A69B, 0x36077742,
+/**/ 0x3FCED78A, 0x58CA8000,
+/**/ 0x3D16F1B5, 0x3793387E,
+/**/ 0x3FE92000, 0x00000000,
+/**/ 0x3F1F693A, 0x1C451AB3,
+/**/ 0x3FCEF0AD, 0xCBDC6000,
+/**/ 0xBD2B26B7, 0x9C86AF24,
+/**/ 0x3FE92000, 0x00000000,
+/**/ 0xBF3F9548, 0xC74EA9E2,
+/**/ 0x3FCF09CC, 0x50036000,
+/**/ 0x3D3DA094, 0x18D999DB,
+/**/ 0x3FE91800, 0x00000000,
+/**/ 0xBF1BD5A8, 0xF7C46911,
+/**/ 0x3FCF22E5, 0xE72F2000,
+/**/ 0xBD3F454F, 0x1417E41F,
+/**/ 0x3FE91000, 0x00000000,
+/**/ 0x3F31B9E1, 0x0D83D1C6,
+/**/ 0x3FCF3BFA, 0x934D6000,
+/**/ 0x3D2D9F2A, 0x937B903B,
+/**/ 0x3FE91000, 0x00000000,
+/**/ 0xBF35876F, 0xF3795877,
+/**/ 0x3FCF550A, 0x564B8000,
+/**/ 0xBD2323E3, 0xA09202FE,
+/**/ 0x3FE90800, 0x00000000,
+/**/ 0x3F0A34CD, 0xBD1D87EC,
+/**/ 0x3FCF6E15, 0x32154000,
+/**/ 0xBD3C9A97, 0x7AC4EC74,
+/**/ 0x3FE90000, 0x00000000,
+/**/ 0x3F3C23F5, 0x0E760899,
+/**/ 0x3FCF871B, 0x28956000,
+/**/ 0xBD3F75FD, 0x6A526EFE,
+/**/ 0x3FE90000, 0x00000000,
+/**/ 0xBF25DECD, 0xD0BE9594,
+/**/ 0x3FCFA01C, 0x3BB58000,
+/**/ 0xBD1A1F71, 0xFAE1D786,
+/**/ 0x3FE8F800, 0x00000000,
+/**/ 0x3F2C18F9, 0xC18F9C19,
+/**/ 0x3FCFB918, 0x6D5E4000,
+/**/ 0xBD0D572A, 0xAB993C87,
+/**/ 0x3FE8F800, 0x00000000,
+/**/ 0xBF38E868, 0x8176594C,
+/**/ 0x3FCFD20F, 0xBF770000,
+/**/ 0xBD11C55B, 0x72C6FE70,
+/**/ 0x3FE8F000, 0x00000000,
+/**/ 0x3EC8F006, 0x3C018F00,
+/**/ 0x3FCFEB02, 0x33E60000,
+/**/ 0x3D2F316E, 0x32D5E8C7,
+/**/ 0x3FE8E800, 0x00000000,
+/**/ 0x3F395B4D, 0xAD115384,
+/**/ 0x3FD001F7, 0xE6484000,
+/**/ 0x3D38A957, 0x40C9ABBC,
+/**/ 0x3FE8E800, 0x00000000,
+/**/ 0xBF2AD850, 0xEC8C0F90,
+/**/ 0x3FD00E6C, 0x45AD5000,
+/**/ 0x3CDCC68D, 0x52E01203,
+/**/ 0x3FE8E000, 0x00000000,
+/**/ 0x3F27B6E9, 0xA56B1AA1,
+/**/ 0x3FD01ADE, 0x3913A000,
+/**/ 0xBD108930, 0xCCDC1521,
+/**/ 0x3FE8E000, 0x00000000,
+/**/ 0xBF3ACDE3, 0x40DFC1D8,
+/**/ 0x3FD0274D, 0xC16C2000,
+/**/ 0x3D2979E8, 0x9CF835C2,
+/**/ 0x3FE8D800, 0x00000000,
+/**/ 0xBEF68397, 0x317DF64C,
+/**/ 0x3FD033BA, 0xDFA74000,
+/**/ 0x3D0C30BC, 0x1485BDFF,
+/**/ 0x3FE8D000, 0x00000000,
+/**/ 0x3F380C69, 0x80C6980C,
+/**/ 0x3FD04025, 0x94B4D000,
+/**/ 0x3CF036B8, 0x9EF42D7F,
+/**/ 0x3FE8D000, 0x00000000,
+/**/ 0xBF2CE006, 0x338C7FE7,
+/**/ 0x3FD04C8D, 0xE1842000,
+/**/ 0xBD1FE6BA, 0x512CEB86,
+/**/ 0x3FE8C800, 0x00000000,
+/**/ 0x3F2644F0, 0x1EFBBD63,
+/**/ 0x3FD058F3, 0xC703F000,
+/**/ 0xBD30E866, 0xBCD236AD,
+/**/ 0x3FE8C800, 0x00000000,
+/**/ 0xBF3B3C2D, 0xAA79217A,
+/**/ 0x3FD06557, 0x46227000,
+/**/ 0x3D0131DF, 0xB4868D6A,
+/**/ 0x3FE8C000, 0x00000000,
+/**/ 0xBEF8BFCE, 0x8062FF3A,
+/**/ 0x3FD071B8, 0x5FCD6000,
+/**/ 0xBD3BCB8B, 0xA3E01A11,
+/**/ 0x3FE8B800, 0x00000000,
+/**/ 0x3F383301, 0xBD2672C4,
+/**/ 0x3FD07E17, 0x14F1D000,
+/**/ 0xBD3EFCC6, 0x4F384BD5,
+/**/ 0x3FE8B800, 0x00000000,
+/**/ 0xBF2BFE74, 0x9BFE749C,
+/**/ 0x3FD08A73, 0x667C5000,
+/**/ 0x3D3EBC1D, 0x40C5A329,
+/**/ 0x3FE8B000, 0x00000000,
+/**/ 0x3F27BA8C, 0xD4353EB3,
+/**/ 0x3FD096CD, 0x55591000,
+/**/ 0x3D3F998D, 0x20550A31,
+/**/ 0x3FE8B000, 0x00000000,
+/**/ 0xBF3A3784, 0xA062B2E4,
+/**/ 0x3FD0A324, 0xE2739000,
+/**/ 0x3D0C6BEE, 0x7EF4030E,
+/**/ 0x3FE8A800, 0x00000000,
+/**/ 0xBECED1F6, 0x5E630281,
+/**/ 0x3FD0AF7A, 0x0EB6C000,
+/**/ 0x3D23CCF9, 0x4945ADAD,
+/**/ 0x3FE8A000, 0x00000000,
+/**/ 0x3F39CAE0, 0x0C519CAE,
+/**/ 0x3FD0BBCC, 0xDB0D2000,
+/**/ 0x3D32F32C, 0xCC5DCDFB,
+/**/ 0x3FE8A000, 0x00000000,
+/**/ 0xBF283C02, 0x4EDBA5FD,
+/**/ 0x3FD0C81D, 0x4860B000,
+/**/ 0xBD3E5BCF, 0x401D1731,
+/**/ 0x3FE89800, 0x00000000,
+/**/ 0x3F2C0F60, 0x1899C0F6,
+/**/ 0x3FD0D46B, 0x579AB000,
+/**/ 0x3D3D2C81, 0xF640E1E6,
+/**/ 0x3FE89800, 0x00000000,
+/**/ 0xBF37C414, 0xBDBE51D0,
+/**/ 0x3FD0E0B7, 0x09A43000,
+/**/ 0x3D32A038, 0xA7862F2A,
+/**/ 0x3FE89000, 0x00000000,
+/**/ 0x3F03F540, 0xDD12CE7D,
+/**/ 0x3FD0ED00, 0x5F658000,
+/**/ 0xBD22DC75, 0x285AA803,
+/**/ 0x3FE88800, 0x00000000,
+/**/ 0x3F3CCFDE, 0x400C45CD,
+/**/ 0x3FD0F947, 0x59C67000,
+/**/ 0xBD395261, 0x7F0818B6,
+/**/ 0x3FE88800, 0x00000000,
+/**/ 0xBF21A0F5, 0x44FB66B5,
+/**/ 0x3FD1058B, 0xF9AE5000,
+/**/ 0xBD34AB9D, 0x817D52CD,
+/**/ 0x3FE88000, 0x00000000,
+/**/ 0x3F319D95, 0x2866A138,
+/**/ 0x3FD111CE, 0x4003F000,
+/**/ 0xBD1B3237, 0x096B4B6B,
+/**/ 0x3FE88000, 0x00000000,
+/**/ 0xBF33E5FA, 0xA48B49DA,
+/**/ 0x3FD11E0E, 0x2DADA000,
+/**/ 0xBD2A47F8, 0x8FCCE5BA,
+/**/ 0x3FE87800, 0x00000000,
+/**/ 0x3F1A9336, 0xDEECB0A8,
+/**/ 0x3FD12A4B, 0xC3912000,
+/**/ 0xBD35A750, 0x61473259,
+/**/ 0x3FE87800, 0x00000000,
+/**/ 0xBF3EC219, 0xFB6A388D,
+/**/ 0x3FD13687, 0x0293B000,
+/**/ 0xBD3D3E84, 0x99D67123,
+/**/ 0x3FE87000, 0x00000000,
+/**/ 0xBF106AE7, 0xC1625090,
+/**/ 0x3FD142BF, 0xEB9A0000,
+/**/ 0x3D31CE61, 0x85B58A9E,
+/**/ 0x3FE86800, 0x00000000,
+/**/ 0x3F369AE5, 0xACD4200C,
+/**/ 0x3FD14EF6, 0x7F887000,
+/**/ 0xBD3E97A6, 0x5DFC9794,
+/**/ 0x3FE86800, 0x00000000,
+/**/ 0xBF2D4286, 0x9389D11C,
+/**/ 0x3FD15B2A, 0xBF429000,
+/**/ 0xBD2D8E3B, 0x49B629B2,
+/**/ 0x3FE86000, 0x00000000,
+/**/ 0x3F286186, 0x18618618,
+/**/ 0x3FD1675C, 0xABABA000,
+/**/ 0x3D38380E, 0x731F55C4,
+/**/ 0x3FE86000, 0x00000000,
+/**/ 0xBF38EF0F, 0x6AC71708,
+/**/ 0x3FD1738C, 0x45A67000,
+/**/ 0xBD39C6E9, 0x0032C176,
+/**/ 0x3FE85800, 0x00000000,
+/**/ 0x3EFFF3D3, 0xE00C2C20,
+/**/ 0x3FD17FB9, 0x8E151000,
+/**/ 0xBD3A8A8B, 0xA74A2684,
+/**/ 0x3FE85000, 0x00000000,
+/**/ 0x3F3CFBA0, 0xF9592266,
+/**/ 0x3FD18BE4, 0x85D93000,
+/**/ 0x3D3C167F, 0x6F3604AB,
+/**/ 0x3FE85000, 0x00000000,
+/**/ 0xBF1FE7B0, 0xFF3D87FA,
+/**/ 0x3FD1980D, 0x2DD42000,
+/**/ 0x3D2B7B3A, 0x7A361C9A,
+/**/ 0x3FE84800, 0x00000000,
+/**/ 0x3F331E8D, 0x918DC223,
+/**/ 0x3FD1A433, 0x86E68000,
+/**/ 0xBD07A850, 0x634E0AAC,
+/**/ 0x3FE84800, 0x00000000,
+/**/ 0xBF31BAF9, 0x8D76B549,
+/**/ 0x3FD1B057, 0x91F08000,
+/**/ 0xBD32DD46, 0x6DC55E2D,
+/**/ 0x3FE84000, 0x00000000,
+/**/ 0x3F22F2EC, 0xDC90C512,
+/**/ 0x3FD1BC79, 0x4FD1D000,
+/**/ 0xBD3CCF0C, 0x747BA7BE,
+/**/ 0x3FE84000, 0x00000000,
+/**/ 0xBF3B442A, 0x6A0916B9,
+/**/ 0x3FD1C898, 0xC169A000,
+/**/ 0xBD381410, 0xE5C62AFF,
+/**/ 0x3FE83800, 0x00000000,
+/**/ 0x3EA83801, 0x83801838,
+/**/ 0x3FD1D4B5, 0xE796A000,
+/**/ 0x3D222A5B, 0xD197BAC2,
+/**/ 0x3FE83000, 0x00000000,
+/**/ 0x3F3B6A41, 0xCBD11C5C,
+/**/ 0x3FD1E0D0, 0xC3371000,
+/**/ 0x3D3AF8F2, 0xA9B0D4A0,
+/**/ 0x3FE83000, 0x00000000,
+/**/ 0xBF225381, 0xCB7A3CD6,
+/**/ 0x3FD1ECE9, 0x5528B000,
+/**/ 0xBD184E7B, 0x09B4A3B8,
+/**/ 0x3FE82800, 0x00000000,
+/**/ 0x3F32500C, 0x152500C1,
+/**/ 0x3FD1F8FF, 0x9E48A000,
+/**/ 0x3D27946C, 0x040CBE77,
+/**/ 0x3FE82800, 0x00000000,
+/**/ 0xBF32285F, 0x14902134,
+/**/ 0x3FD20513, 0x9F73B000,
+/**/ 0x3CF6E15E, 0x1609E0A4,
+/**/ 0x3FE82000, 0x00000000,
+/**/ 0x3F22D9EB, 0xA4018213,
+/**/ 0x3FD21125, 0x59861000,
+/**/ 0x3D382E78, 0xBA2950C4,
+/**/ 0x3FE82000, 0x00000000,
+/**/ 0xBF3AEFFC, 0xFC6BBFF4,
+/**/ 0x3FD21D34, 0xCD5B9000,
+/**/ 0x3D3B552F, 0xB28BADAA,
+/**/ 0x3FE81800, 0x00000000,
+/**/ 0x3EE81818, 0x18181818,
+/**/ 0x3FD22941, 0xFBCF8000,
+/**/ 0xBD3A6976, 0xF5EB0963,
+/**/ 0x3FE81000, 0x00000000,
+/**/ 0x3F3C7F27, 0x4FF0F3C6,
+/**/ 0x3FD2354C, 0xE5BC9000,
+/**/ 0xBD3D78ED, 0x0602A663,
+/**/ 0x3FE81000, 0x00000000,
+/**/ 0xBF1ED344, 0x0A86941D,
+/**/ 0x3FD24155, 0x8BFD1000,
+/**/ 0x3D300FFF, 0x3228FCAD,
+/**/ 0x3FE80800, 0x00000000,
+/**/ 0x3F3424D0, 0x1B0BD52D,
+/**/ 0x3FD24D5B, 0xEF6AF000,
+/**/ 0xBCBDD780, 0xFC9FABDD,
+/**/ 0x3FE80800, 0x00000000,
+/**/ 0xBF2FE7F9, 0xFE7F9FE8,
+/**/ 0x3FD25960, 0x10DF7000,
+/**/ 0x3D38E7BC, 0x224EA3E3,
+/**/ 0x3FE80000, 0x00000000,
+/**/ 0x3F280180, 0x18018018,
+/**/ 0x3FD26561, 0xF1338000,
+/**/ 0x3D38B488, 0x66FAA45F,
+/**/ 0x3FE80000, 0x00000000,
+/**/ 0xBF37FD00, 0x5FF40180,
+/**/ 0x3FD27161, 0x913F8000,
+/**/ 0x3D34F4F1, 0xF61564B4,
+/**/ 0x3FE7F800, 0x00000000,
+/**/ 0x3F104AE8, 0x9750B6C7,
+/**/ 0x3FD27D5E, 0xF1DB6000,
+/**/ 0xBD092374, 0x78CAC9F4,
+/**/ 0x3FE7F800, 0x00000000,
+/**/ 0xBF3FD017, 0xF405FD01,
+/**/ 0x3FD2895A, 0x13DE8000,
+/**/ 0x3D3A8D7A, 0xD24C13F0,
+/**/ 0x3FE7F000, 0x00000000,
+/**/ 0xBF0D2BF1, 0xC9C5485E,
+/**/ 0x3FD29552, 0xF81FF000,
+/**/ 0x3D348D30, 0x1771C408,
+/**/ 0x3FE7E800, 0x00000000,
+/**/ 0x3F38927F, 0xD029DB60,
+/**/ 0x3FD2A149, 0x9F763000,
+/**/ 0xBD30DBBF, 0x51F3AADC,
+/**/ 0x3FE7E800, 0x00000000,
+/**/ 0xBF26504A, 0xB0A45169,
+/**/ 0x3FD2AD3E, 0x0AB73000,
+/**/ 0x3D2B972E, 0x488C359F,
+/**/ 0x3FE7E000, 0x00000000,
+/**/ 0x3F312A8A, 0xD278E8DD,
+/**/ 0x3FD2B930, 0x3AB8A000,
+/**/ 0xBD26DB12, 0xD6BFB0A5,
+/**/ 0x3FE7E000, 0x00000000,
+/**/ 0xBF327577, 0x24BB32E7,
+/**/ 0x3FD2C520, 0x304F8000,
+/**/ 0x3D230852, 0x8C342F39,
+/**/ 0x3FE7D800, 0x00000000,
+/**/ 0x3F23EF9A, 0xA4B45AEC,
+/**/ 0x3FD2D10D, 0xEC508000,
+/**/ 0x3D360C61, 0xF7088353,
+/**/ 0x3FE7D800, 0x00000000,
+/**/ 0xBF398DAF, 0x32748CC1,
+/**/ 0x3FD2DCF9, 0x6F8FD000,
+/**/ 0x3D20B4A2, 0x8E33C9CE,
+/**/ 0x3FE7D000, 0x00000000,
+/**/ 0x3F07D05F, 0x417D05F4,
+/**/ 0x3FD2E8E2, 0xBAE12000,
+/**/ 0xBD267B1E, 0x99B72BD8,
+/**/ 0x3FE7C800, 0x00000000,
+/**/ 0x3F3F8EF7, 0x431D3027,
+/**/ 0x3FD2F4C9, 0xCF17A000,
+/**/ 0x3D371F04, 0x9374B87B,
+/**/ 0x3FE7C800, 0x00000000,
+/**/ 0xBF0E77A3, 0xDAD83E6C,
+/**/ 0x3FD300AE, 0xAD063000,
+/**/ 0x3D342F56, 0x8B75FCAC,
+/**/ 0x3FE7C000, 0x00000000,
+/**/ 0x3F38E041, 0x588D1676,
+/**/ 0x3FD30C91, 0x557F2000,
+/**/ 0xBD142958, 0xA1451755,
+/**/ 0x3FE7C000, 0x00000000,
+/**/ 0xBF24C6DD, 0x1FE8414C,
+/**/ 0x3FD31871, 0xC9544000,
+/**/ 0x3D184FAB, 0x94CECFD9,
+/**/ 0x3FE7B800, 0x00000000,
+/**/ 0x3F3265F4, 0x81C2D3B2,
+/**/ 0x3FD32450, 0x09570000,
+/**/ 0x3D3D271B, 0x9BDAE59D,
+/**/ 0x3FE7B800, 0x00000000,
+/**/ 0xBF30C39C, 0xB6466407,
+/**/ 0x3FD3302C, 0x16586000,
+/**/ 0x3D36217D, 0xC2A3E08B,
+/**/ 0x3FE7B000, 0x00000000,
+/**/ 0x3F283FAD, 0x12B21224,
+/**/ 0x3FD33C05, 0xF128E000,
+/**/ 0xBD22B906, 0x380E1A7D,
+/**/ 0x3FE7B000, 0x00000000,
+/**/ 0xBF36EFB8, 0xF899E55D,
+/**/ 0x3FD347DD, 0x9A988000,
+/**/ 0xBD25594D, 0xD4C58092,
+/**/ 0x3FE7A800, 0x00000000,
+/**/ 0x3F1836B6, 0x3FF42B9F,
+/**/ 0x3FD353B3, 0x1376E000,
+/**/ 0xBD1331AF, 0xE6C26D9B,
+/**/ 0x3FE7A800, 0x00000000,
+/**/ 0xBF3CE7FD, 0x0B739FF4,
+/**/ 0x3FD35F86, 0x5C933000,
+/**/ 0xBD3B07DE, 0x4EA1A54A,
+/**/ 0x3FE7A000, 0x00000000,
+/**/ 0x3EC7A005, 0xE8017A00,
+/**/ 0x3FD36B57, 0x76BC1000,
+/**/ 0x3D116978, 0x5A9C223F,
+/**/ 0x3FE79800, 0x00000000,
+/**/ 0x3F3D535D, 0xB1CC5B7B,
+/**/ 0x3FD37726, 0x62BFE000,
+/**/ 0xBD3E9436, 0xAC53B023,
+/**/ 0x3FE79800, 0x00000000,
+/**/ 0xBF15EEAC, 0xE0DA37A9,
+/**/ 0x3FD382F3, 0x216C5000,
+/**/ 0xBD1061D2, 0x1D1A7F6D,
+/**/ 0x3FE79000, 0x00000000,
+/**/ 0x3F37C21E, 0x344E16D6,
+/**/ 0x3FD38EBD, 0xB38ED000,
+/**/ 0x3D290582, 0xE67D4CA0,
+/**/ 0x3FE79000, 0x00000000,
+/**/ 0xBF25E69A, 0x39C9E465,
+/**/ 0x3FD39A86, 0x19F45000,
+/**/ 0x3D18EE51, 0x937354F5,
+/**/ 0x3FE78800, 0x00000000,
+/**/ 0x3F32640B, 0xC52640BC,
+/**/ 0x3FD3A64C, 0x55694000,
+/**/ 0x3D37A71C, 0xBCD735D0,
+/**/ 0x3FE78800, 0x00000000,
+/**/ 0xBF3037DE, 0x2F6A09ED,
+/**/ 0x3FD3B210, 0x66B9C000,
+/**/ 0xBD33C1ED, 0x9811560E,
+/**/ 0x3FE78000, 0x00000000,
+/**/ 0x3F2A71DC, 0x01781A72,
+/**/ 0x3FD3BDD2, 0x4EB15000,
+/**/ 0xBD3257B4, 0x970E6ED9,
+/**/ 0x3FE78000, 0x00000000,
+/**/ 0xBF354996, 0xA9EEBFF4,
+/**/ 0x3FD3C992, 0x0E1B2000,
+/**/ 0x3D141C28, 0xAA680B76,
+/**/ 0x3FE77800, 0x00000000,
+/**/ 0x3F208119, 0xAC60D341,
+/**/ 0x3FD3D54F, 0xA5C1F000,
+/**/ 0x3D3C3E1C, 0xD9A395E3,
+/**/ 0x3FE77800, 0x00000000,
+/**/ 0xBF3A28AE, 0x742E2DD0,
+/**/ 0x3FD3E10B, 0x16701000,
+/**/ 0x3D3F3BCF, 0x145429C7,
+/**/ 0x3FE77000, 0x00000000,
+/**/ 0x3F0BD584, 0x36340177,
+/**/ 0x3FD3ECC4, 0x60EF6000,
+/**/ 0xBD060286, 0x27C1300F,
+/**/ 0x3FE77000, 0x00000000,
+/**/ 0xBF3ED55D, 0x240C7174,
+/**/ 0x3FD3F87B, 0x86094000,
+/**/ 0xBD35DFD7, 0x54589889,
+/**/ 0x3FE76800, 0x00000000,
+/**/ 0xBEF18DE5, 0xAB277F45,
+/**/ 0x3FD40430, 0x8686A000,
+/**/ 0x3D3F8EF4, 0x3049F7D3,
+/**/ 0x3FE76000, 0x00000000,
+/**/ 0x3F3CB026, 0x01D3C7B8,
+/**/ 0x3FD40FE3, 0x63303000,
+/**/ 0x3D3E5C5F, 0xE79F05C6,
+/**/ 0x3FE76000, 0x00000000,
+/**/ 0xBF15E95B, 0xA9D08664,
+/**/ 0x3FD41B94, 0x1CCE1000,
+/**/ 0xBD304690, 0x13E43FC9,
+/**/ 0x3FE75800, 0x00000000,
+/**/ 0x3F3867A4, 0x097CFD43,
+/**/ 0x3FD42742, 0xB427E000,
+/**/ 0xBD398727, 0x02B82675,
+/**/ 0x3FE75800, 0x00000000,
+/**/ 0xBF2353DF, 0xE8A9353E,
+/**/ 0x3FD432EF, 0x2A04F000,
+/**/ 0xBD3FB129, 0x931715AD,
+/**/ 0x3FE75000, 0x00000000,
+/**/ 0x3F3450E6, 0x4F13DC4A,
+/**/ 0x3FD43E99, 0x7F2C1000,
+/**/ 0x3D1C3F72, 0x40C41A04,
+/**/ 0x3FE75000, 0x00000000,
+/**/ 0xBF2B4FBF, 0xE8B1B4FC,
+/**/ 0x3FD44A41, 0xB463C000,
+/**/ 0x3D31EE28, 0xF37CF612,
+/**/ 0x3FE74800, 0x00000000,
+/**/ 0x3F306BB6, 0x7E458100,
+/**/ 0x3FD455E7, 0xCA720000,
+/**/ 0x3D1AD8C6, 0x36629AED,
+/**/ 0x3FE74800, 0x00000000,
+/**/ 0xBF31745D, 0x1745D174,
+/**/ 0x3FD4618B, 0xC21C6000,
+/**/ 0xBD13D82F, 0x484C84CC,
+/**/ 0x3FE74000, 0x00000000,
+/**/ 0x3F296FBD, 0x236DEC04,
+/**/ 0x3FD46D2D, 0x9C280000,
+/**/ 0x3D359B27, 0x5F67F75A,
+/**/ 0x3FE74000, 0x00000000,
+/**/ 0xBF350F9D, 0x3B304B87,
+/**/ 0x3FD478CD, 0x5959B000,
+/**/ 0x3D2EC89B, 0xF0C8D098,
+/**/ 0x3FE73800, 0x00000000,
+/**/ 0x3F226A51, 0xA4EBDC70,
+/**/ 0x3FD4846A, 0xFA75C000,
+/**/ 0xBD263EA2, 0xE3798DCE,
+/**/ 0x3FE73800, 0x00000000,
+/**/ 0xBF3879D5, 0xF00B9A78,
+/**/ 0x3FD49006, 0x80401000,
+/**/ 0xBD38BCCF, 0xFE1A0F8C,
+/**/ 0x3FE73000, 0x00000000,
+/**/ 0x3F178D7F, 0x5DAAD90C,
+/**/ 0x3FD49B9F, 0xEB7C1000,
+/**/ 0x3D3DAC1C, 0x58AB60D7,
+/**/ 0x3FE73000, 0x00000000,
+/**/ 0xBF3BB33C, 0x783709C7,
+/**/ 0x3FD4A737, 0x3CED0000,
+/**/ 0xBD39A234, 0xEBF35449,
+/**/ 0x3FE72800, 0x00000000,
+/**/ 0x3F061274, 0x265AD23A,
+/**/ 0x3FD4B2CC, 0x75556000,
+/**/ 0xBD380FCB, 0xC78BFA4B,
+/**/ 0x3FE72800, 0x00000000,
+/**/ 0xBF3EBC05, 0xC90A1FD2,
+/**/ 0x3FD4BE5F, 0x95778000,
+/**/ 0xBD3D7C92, 0xCD9AD824,
+/**/ 0x3FE72000, 0x00000000,
+/**/ 0xBEC71FFA, 0x38017200,
+/**/ 0x3FD4C9F0, 0x9E153000,
+/**/ 0xBD2E1DDE, 0x70E02DE0,
+/**/ 0x3FE71800, 0x00000000,
+/**/ 0x3F3E6B99, 0x74A050E1,
+/**/ 0x3FD4D57F, 0x8FEFE000,
+/**/ 0x3D23F926, 0x7FD06868,
+/**/ 0x3FE71800, 0x00000000,
+/**/ 0xBF077400, 0xB8BD1180,
+/**/ 0x3FD4E10C, 0x6BC8A000,
+/**/ 0x3CF8283F, 0x1636F061,
+/**/ 0x3FE71000, 0x00000000,
+/**/ 0x3F3BC36C, 0xE3E0453A,
+/**/ 0x3FD4EC97, 0x32600000,
+/**/ 0x3D234D7A, 0xAF04D104,
+/**/ 0x3FE71000, 0x00000000,
+/**/ 0xBF15FA98, 0x6935DDC5,
+/**/ 0x3FD4F81F, 0xE4764000,
+/**/ 0xBD27FCF6, 0x434FF08D,
+/**/ 0x3FE70800, 0x00000000,
+/**/ 0x3F394B40, 0x7337CF08,
+/**/ 0x3FD503A6, 0x82CB2000,
+/**/ 0xBD2A68C8, 0xF16F9B5D,
+/**/ 0x3FE70800, 0x00000000,
+/**/ 0xBF1F7B97, 0xA835403A,
+/**/ 0x3FD50F2B, 0x0E1E0000,
+/**/ 0x3D3A0940, 0x8C47B8D8,
+/**/ 0x3FE70000, 0x00000000,
+/**/ 0x3F3702E0, 0x5C0B8170,
+/**/ 0x3FD51AAD, 0x872E0000,
+/**/ 0xBD3F4BD8, 0xDB0A7CC1,
+/**/ 0x3FE70000, 0x00000000,
+/**/ 0xBF241EE6, 0x4F67A855,
+/**/ 0x3FD5262D, 0xEEB99000,
+/**/ 0xBD3E1B9F, 0x70894A01,
+/**/ 0x3FE6F800, 0x00000000,
+/**/ 0x3F34EA19, 0x221C0170,
+/**/ 0x3FD531AC, 0x457EE000,
+/**/ 0x3D3DF83B, 0x7D931501,
+/**/ 0x3FE6F800, 0x00000000,
+/**/ 0xBF282102, 0x5508CA5C,
+/**/ 0x3FD53D28, 0x8C3BE000,
+/**/ 0xBD111397, 0xEB6DFAC5,
+/**/ 0x3FE6F000, 0x00000000,
+/**/ 0x3F3300B7, 0x9300B793,
+/**/ 0x3FD548A2, 0xC3ADD000,
+/**/ 0x3D23167E, 0x63081CF7,
+/**/ 0x3FE6F000, 0x00000000,
+/**/ 0xBF2BC486, 0x005BB90F,
+/**/ 0x3FD5541A, 0xEC91C000,
+/**/ 0xBCF816AA, 0xDC72EEBA,
+/**/ 0x3FE6E800, 0x00000000,
+/**/ 0x3F314688, 0xC5A3A00B,
+/**/ 0x3FD55F91, 0x07A44000,
+/**/ 0xBD11E647, 0x78DF4A62,
+/**/ 0x3FE6E800, 0x00000000,
+/**/ 0xBF2F09D6, 0xDA9C5AE1,
+/**/ 0x3FD56B05, 0x15A18000,
+/**/ 0x3D29247B, 0xBC4A23FC,
+/**/ 0x3FE6E000, 0x00000000,
+/**/ 0x3F2F76B4, 0x337C6CB1,
+/**/ 0x3FD57677, 0x17456000,
+/**/ 0xBD364EAD, 0x9524D7CA,
+/**/ 0x3FE6E000, 0x00000000,
+/**/ 0xBF30F8AC, 0xEDF4EC87,
+/**/ 0x3FD581E7, 0x0D4B3000,
+/**/ 0xBD1F31E1, 0xB12D8F1D,
+/**/ 0x3FE6D800, 0x00000000,
+/**/ 0x3F2CBDF2, 0x6EAEF381,
+/**/ 0x3FD58D54, 0xF86E0000,
+/**/ 0x3D2791F3, 0x0A795215,
+/**/ 0x3FE6D800, 0x00000000,
+/**/ 0xBF323DB9, 0xB624BFF5,
+/**/ 0x3FD598C0, 0xD9688000,
+/**/ 0xBD385F49, 0x70D96DA4,
+/**/ 0x3FE6D000, 0x00000000,
+/**/ 0x3F2A6268, 0x1C860FB0,
+/**/ 0x3FD5A42A, 0xB0F4D000,
+/**/ 0xBCDE63AF, 0x2DF7BA69,
+/**/ 0x3FE6D000, 0x00000000,
+/**/ 0xBF335443, 0xB253BAE1,
+/**/ 0x3FD5AF92, 0x7FCCE000,
+/**/ 0xBD1C032F, 0xF5FFC77A,
+/**/ 0x3FE6C800, 0x00000000,
+/**/ 0x3F2863B1, 0xAB4294D4,
+/**/ 0x3FD5BAF8, 0x46AA2000,
+/**/ 0xBD339AE8, 0xF873FA41,
+/**/ 0x3FE6C800, 0x00000000,
+/**/ 0xBF343C7C, 0x87EAA6DF,
+/**/ 0x3FD5C65C, 0x0645A000,
+/**/ 0xBD39FE06, 0x0180EE65,
+/**/ 0x3FE6C000, 0x00000000,
+/**/ 0x3F26C16C, 0x16C16C17,
+/**/ 0x3FD5D1BD, 0xBF581000,
+/**/ 0xBD38D6BD, 0xC9C7C238,
+/**/ 0x3FE6C000, 0x00000000,
+/**/ 0xBF34F695, 0x95C33E00,
+/**/ 0x3FD5DD1D, 0x7299C000,
+/**/ 0xBD38AF61, 0x8815CE17,
+/**/ 0x3FE6B800, 0x00000000,
+/**/ 0x3F257B34, 0xE7802D73,
+/**/ 0x3FD5E87B, 0x20C29000,
+/**/ 0x3D3527D1, 0x8F7738FA,
+/**/ 0x3FE6B800, 0x00000000,
+/**/ 0xBF3582BF, 0xF4A5582C,
+/**/ 0x3FD5F3D6, 0xCA8A2000,
+/**/ 0x3D37AF84, 0x8E19CC75,
+/**/ 0x3FE6B000, 0x00000000,
+/**/ 0x3F2490AA, 0x31A3CFC7,
+/**/ 0x3FD5FF30, 0x70A79000,
+/**/ 0x3D2E9E43, 0x9F105039,
+/**/ 0x3FE6B000, 0x00000000,
+/**/ 0xBF35E12C, 0x77C30E5A,
+/**/ 0x3FD60A88, 0x13D1A000,
+/**/ 0x3D36E9B9, 0xC879AF55,
+/**/ 0x3FE6A800, 0x00000000,
+/**/ 0x3F24016A, 0x94016A94,
+/**/ 0x3FD615DD, 0xB4BEC000,
+/**/ 0x3D13C7CA, 0x90BC04B2,
+/**/ 0x3FE6A800, 0x00000000,
+/**/ 0xBF36120B, 0xAD33D63F,
+/**/ 0x3FD62131, 0x5424F000,
+/**/ 0xBD3382FC, 0x4AA68669,
+/**/ 0x3FE6A000, 0x00000000,
+/**/ 0x3F23CD15, 0x3729043E,
+/**/ 0x3FD62C82, 0xF2B9C000,
+/**/ 0x3D3E54BD, 0xBD7C8A98 } };
+
+static const union {int4 i[4350]; double x[2175]; } vj = { .i = {
+/**/ 0x3F46A400, 0x7D161C28,
+/**/ 0xBF46A200, 0x20600000,
+/**/ 0x3D27DC4E, 0xAA7623D9,
+/**/ 0x3F4693FA, 0xD596E639,
+/**/ 0xBF4691FD, 0x4CE00000,
+/**/ 0x3D26B0CF, 0x29C3F0AD,
+/**/ 0x3F4683F5, 0x3219CE89,
+/**/ 0xBF4681FA, 0x7B600000,
+/**/ 0x3D22B290, 0x95B9FDCC,
+/**/ 0x3F4673EF, 0x929ED397,
+/**/ 0xBF4671F7, 0xABE00000,
+/**/ 0x3D17C727, 0xFA2F2D87,
+/**/ 0x3F4663E9, 0xF725F3E2,
+/**/ 0xBF4661F4, 0xDE600000,
+/**/ 0x3CF22ED3, 0x6EDBFF1C,
+/**/ 0x3F4653E4, 0x5FAF2DE9,
+/**/ 0xBF4651F2, 0x12E00000,
+/**/ 0xBD144936, 0x157812BB,
+/**/ 0x3F4643DE, 0xCC3A802B,
+/**/ 0xBF4641EF, 0x49600000,
+/**/ 0xBD2959CB, 0x60314E05,
+/**/ 0x3F4633D9, 0x3CC7E927,
+/**/ 0xBF4631EC, 0x81E00000,
+/**/ 0xBD35ABDA, 0xC3638E99,
+/**/ 0x3F4623D3, 0xB157675C,
+/**/ 0xBF4621E9, 0xBC800000,
+/**/ 0x3D3FF1D3, 0xC63F9A21,
+/**/ 0x3F4613CE, 0x29E8F948,
+/**/ 0xBF4611E6, 0xF9000000,
+/**/ 0x3D342D26, 0x71EEE611,
+/**/ 0x3F4603C8, 0xA67C9D6B,
+/**/ 0xBF4601E4, 0x37800000,
+/**/ 0x3D1C1C77, 0x11A09689,
+/**/ 0x3F45F3C3, 0x27125244,
+/**/ 0xBF45F1E1, 0x78000000,
+/**/ 0xBD1DFD16, 0xF7DC643C,
+/**/ 0x3F45E3BD, 0xABAA1651,
+/**/ 0xBF45E1DE, 0xBA800000,
+/**/ 0xBD376503, 0x91318A02,
+/**/ 0x3F45D3B8, 0x3443E812,
+/**/ 0xBF45D1DB, 0xFF200000,
+/**/ 0x3D3756E4, 0xCE55DCDD,
+/**/ 0x3F45C3B2, 0xC0DFC606,
+/**/ 0xBF45C1D9, 0x45A00000,
+/**/ 0x3D12D5CF, 0x8F6F8FA0,
+/**/ 0x3F45B3AD, 0x517DAEAB,
+/**/ 0xBF45B1D6, 0x8E200000,
+/**/ 0xBD2E90AB, 0x9B85DC2C,
+/**/ 0x3F45A3A7, 0xE61DA081,
+/**/ 0xBF45A1D3, 0xD8C00000,
+/**/ 0x3D3B5E88, 0x3BF5AC54,
+/**/ 0x3F4593A2, 0x7EBF9A07,
+/**/ 0xBF4591D1, 0x25400000,
+/**/ 0x3D12AC3A, 0x0C86DDB1,
+/**/ 0x3F45839D, 0x1B6399BB,
+/**/ 0xBF4581CE, 0x73C00000,
+/**/ 0xBD3361C2, 0x76830985,
+/**/ 0x3F457397, 0xBC099E1C,
+/**/ 0xBF4571CB, 0xC4600000,
+/**/ 0x3D333915, 0xD062EBFF,
+/**/ 0x3F456392, 0x60B1A5AA,
+/**/ 0xBF4561C9, 0x16E00000,
+/**/ 0xBD1E0DA0, 0x9CC4988F,
+/**/ 0x3F45538D, 0x095BAEE4,
+/**/ 0xBF4551C6, 0x6B800000,
+/**/ 0x3D3C69C4, 0x235BC18A,
+/**/ 0x3F454387, 0xB607B848,
+/**/ 0xBF4541C3, 0xC2000000,
+/**/ 0xBCEFCC99, 0xF7737723,
+/**/ 0x3F453382, 0x66B5C056,
+/**/ 0xBF4531C1, 0x1A800000,
+/**/ 0xBD3FBAE2, 0x809CBCBB,
+/**/ 0x3F45237D, 0x1B65C58C,
+/**/ 0xBF4521BE, 0x75200000,
+/**/ 0x3CCAA5C8, 0x194FEE63,
+/**/ 0x3F451377, 0xD417C66A,
+/**/ 0xBF4511BB, 0xD1C00000,
+/**/ 0x3D3ED325, 0xE1CC7BBC,
+/**/ 0x3F450372, 0x90CBC16E,
+/**/ 0xBF4501B9, 0x30400000,
+/**/ 0xBD0F0298, 0x68AB3742,
+/**/ 0x3F44F36D, 0x5181B517,
+/**/ 0xBF44F1B6, 0x90E00000,
+/**/ 0x3D381BE1, 0x41E67AD9,
+/**/ 0x3F44E368, 0x16399FE6,
+/**/ 0xBF44E1B3, 0xF3600000,
+/**/ 0xBD2A6E79, 0x668D3662,
+/**/ 0x3F44D362, 0xDEF38058,
+/**/ 0xBF44D1B1, 0x58000000,
+/**/ 0x3D284EA7, 0x21F8B7C2,
+/**/ 0x3F44C35D, 0xABAF54EC,
+/**/ 0xBF44C1AE, 0xBE800000,
+/**/ 0xBD3BC76D, 0x7417D9C5,
+/**/ 0x3F44B358, 0x7C6D1C22,
+/**/ 0xBF44B1AC, 0x27200000,
+/**/ 0xBD1409FD, 0x16AAD1FC,
+/**/ 0x3F44A353, 0x512CD479,
+/**/ 0xBF44A1A9, 0x91C00000,
+/**/ 0x3D30771E, 0x98BC14FD,
+/**/ 0x3F44934E, 0x29EE7C70,
+/**/ 0xBF4491A6, 0xFE400000,
+/**/ 0xBD3B5993, 0x5CCB7232,
+/**/ 0x3F448349, 0x06B21285,
+/**/ 0xBF4481A4, 0x6CE00000,
+/**/ 0xBD20E729, 0x5512F9C2,
+/**/ 0x3F447343, 0xE7779538,
+/**/ 0xBF4471A1, 0xDD800000,
+/**/ 0x3D225436, 0x55B30899,
+/**/ 0x3F44633E, 0xCC3F0308,
+/**/ 0xBF44619F, 0x50200000,
+/**/ 0x3D39807C, 0x9E54E31F,
+/**/ 0x3F445339, 0xB5085A73,
+/**/ 0xBF44519C, 0xC4A00000,
+/**/ 0xBD376F6F, 0xD5804C0E,
+/**/ 0x3F444334, 0xA1D399FA,
+/**/ 0xBF44419A, 0x3B400000,
+/**/ 0xBD234953, 0x6CDE6425,
+/**/ 0x3F44332F, 0x92A0C01A,
+/**/ 0xBF443197, 0xB3E00000,
+/**/ 0x3D070E7B, 0xAAF6596F,
+/**/ 0x3F44232A, 0x876FCB54,
+/**/ 0xBF442195, 0x2E800000,
+/**/ 0x3D2C49F8, 0x4EC011F1,
+/**/ 0x3F441325, 0x8040BA25,
+/**/ 0xBF441192, 0xAB200000,
+/**/ 0x3D3825DC, 0xD8AAA7EB,
+/**/ 0x3F440320, 0x7D138B0E,
+/**/ 0xBF440190, 0x29A00000,
+/**/ 0xBD3F1A8D, 0xFE0B73D6,
+/**/ 0x3F43F31B, 0x7DE83C8C,
+/**/ 0xBF43F18D, 0xAA400000,
+/**/ 0xBD379B43, 0xE46CA26B,
+/**/ 0x3F43E316, 0x82BECD20,
+/**/ 0xBF43E18B, 0x2CE00000,
+/**/ 0xBD315B44, 0x6283780D,
+/**/ 0x3F43D311, 0x8B973B49,
+/**/ 0xBF43D188, 0xB1800000,
+/**/ 0xBD28B31E, 0x017589BE,
+/**/ 0x3F43C30C, 0x98718584,
+/**/ 0xBF43C186, 0x38200000,
+/**/ 0xBD212A46, 0x8FBB296E,
+/**/ 0x3F43B307, 0xA94DAA52,
+/**/ 0xBF43B183, 0xC0C00000,
+/**/ 0xBD183403, 0x045CBBD2,
+/**/ 0x3F43A302, 0xBE2BA832,
+/**/ 0xBF43A181, 0x4B600000,
+/**/ 0xBD13009B, 0xD7CC5936,
+/**/ 0x3F4392FD, 0xD70B7DA2,
+/**/ 0xBF43917E, 0xD8000000,
+/**/ 0xBD12B655, 0xC1742279,
+/**/ 0x3F4382F8, 0xF3ED2921,
+/**/ 0xBF43817C, 0x66A00000,
+/**/ 0xBD17512E, 0xEA83FAE8,
+/**/ 0x3F4372F4, 0x14D0A930,
+/**/ 0xBF437179, 0xF7400000,
+/**/ 0xBD206692, 0xBED65875,
+/**/ 0x3F4362EF, 0x39B5FC4C,
+/**/ 0xBF436177, 0x89E00000,
+/**/ 0xBD27931B, 0xD38FFE9E,
+/**/ 0x3F4352EA, 0x629D20F5,
+/**/ 0xBF435175, 0x1E800000,
+/**/ 0xBD309618, 0xE524208F,
+/**/ 0x3F4342E5, 0x8F8615AA,
+/**/ 0xBF434172, 0xB5200000,
+/**/ 0xBD3697E9, 0xDD4C72C5,
+/**/ 0x3F4332E0, 0xC070D8EB,
+/**/ 0xBF433170, 0x4DC00000,
+/**/ 0xBD3DCE00, 0x5E6E12C3,
+/**/ 0x3F4322DB, 0xF55D6935,
+/**/ 0xBF43216D, 0xE8800000,
+/**/ 0x3D39C8A4, 0x0AE9A8CE,
+/**/ 0x3F4312D7, 0x2E4BC509,
+/**/ 0xBF43116B, 0x85200000,
+/**/ 0x3D302D03, 0xD1CD2FA1,
+/**/ 0x3F4302D2, 0x6B3BEAE5,
+/**/ 0xBF430169, 0x23C00000,
+/**/ 0x3D15807D, 0xA3BADFD1,
+/**/ 0x3F42F2CD, 0xAC2DD949,
+/**/ 0xBF42F166, 0xC4600000,
+/**/ 0xBD1A7422, 0xF57F0504,
+/**/ 0x3F42E2C8, 0xF1218EB3,
+/**/ 0xBF42E164, 0x67000000,
+/**/ 0xBD33C974, 0x2F2C781C,
+/**/ 0x3F42D2C4, 0x3A1709A3,
+/**/ 0xBF42D162, 0x0BC00000,
+/**/ 0x3D3DDBDD, 0x851A1E61,
+/**/ 0x3F42C2BF, 0x870E4898,
+/**/ 0xBF42C15F, 0xB2600000,
+/**/ 0x3D2CA7D9, 0xA14AA8FD,
+/**/ 0x3F42B2BA, 0xD8074A10,
+/**/ 0xBF42B15D, 0x5B000000,
+/**/ 0xBD03022E, 0xDDCDDFF5,
+/**/ 0x3F42A2B6, 0x2D020C8C,
+/**/ 0xBF42A15B, 0x05A00000,
+/**/ 0xBD343FBA, 0x0F9231A8,
+/**/ 0x3F4292B1, 0x85FE8E8A,
+/**/ 0xBF429158, 0xB2600000,
+/**/ 0x3D38B690, 0xA52C9CCF,
+/**/ 0x3F4282AC, 0xE2FCCE8A,
+/**/ 0xBF428156, 0x61000000,
+/**/ 0x3D120E6A, 0xC8CC82EB,
+/**/ 0x3F4272A8, 0x43FCCB0A,
+/**/ 0xBF427154, 0x11A00000,
+/**/ 0xBD30D79B, 0x792E6C51,
+/**/ 0x3F4262A3, 0xA8FE8289,
+/**/ 0xBF426151, 0xC4600000,
+/**/ 0x3D38A5EE, 0x91F7F7AA,
+/**/ 0x3F42529F, 0x1201F387,
+/**/ 0xBF42514F, 0x79000000,
+/**/ 0x3CEFA728, 0x46C2E8BA,
+/**/ 0x3F42429A, 0x7F071C84,
+/**/ 0xBF42414D, 0x2FA00000,
+/**/ 0xBD37D0BA, 0xFA447A17,
+/**/ 0x3F423295, 0xF00DFBFD,
+/**/ 0xBF42314A, 0xE8600000,
+/**/ 0x3D2C7A24, 0x94AF3FED,
+/**/ 0x3F422291, 0x65169072,
+/**/ 0xBF422148, 0xA3000000,
+/**/ 0xBD29B0BD, 0x050CEA04,
+/**/ 0x3F42128C, 0xDE20D863,
+/**/ 0xBF421146, 0x5FC00000,
+/**/ 0x3D36EFF3, 0x0C3035EB,
+/**/ 0x3F420288, 0x5B2CD24E,
+/**/ 0xBF420144, 0x1E600000,
+/**/ 0xBD19A3E2, 0x73569B27,
+/**/ 0x3F41F283, 0xDC3A7CB2,
+/**/ 0xBF41F141, 0xDF200000,
+/**/ 0x3D3B1DDE, 0xEEB67715,
+/**/ 0x3F41E27F, 0x6149D610,
+/**/ 0xBF41E13F, 0xA1C00000,
+/**/ 0xBD11EA17, 0x94F49154,
+/**/ 0x3F41D27A, 0xEA5ADCE5,
+/**/ 0xBF41D13D, 0x66800000,
+/**/ 0x3D3ACED9, 0x52DD9D37,
+/**/ 0x3F41C276, 0x776D8FB1,
+/**/ 0xBF41C13B, 0x2D200000,
+/**/ 0xBD1C140B, 0xF72D8EEB,
+/**/ 0x3F41B272, 0x0881ECF4,
+/**/ 0xBF41B138, 0xF5E00000,
+/**/ 0x3D360AE5, 0x939583E1,
+/**/ 0x3F41A26D, 0x9D97F32C,
+/**/ 0xBF41A136, 0xC0800000,
+/**/ 0xBD2C00D9, 0x1D246C7C,
+/**/ 0x3F419269, 0x36AFA0D9,
+/**/ 0xBF419134, 0x8D400000,
+/**/ 0x3D29B40E, 0x0B955CFB,
+/**/ 0x3F418264, 0xD3C8F479,
+/**/ 0xBF418132, 0x5BE00000,
+/**/ 0xBD3964BF, 0x45A6C249,
+/**/ 0x3F417260, 0x74E3EC8D,
+/**/ 0xBF417130, 0x2CA00000,
+/**/ 0xBCE777E0, 0xF3363612,
+/**/ 0x3F41625C, 0x1A008792,
+/**/ 0xBF41612D, 0xFF600000,
+/**/ 0x3D36D608, 0x28DE8296,
+/**/ 0x3F415257, 0xC31EC409,
+/**/ 0xBF41512B, 0xD4000000,
+/**/ 0xBD32AE69, 0x4BB1B788,
+/**/ 0x3F414253, 0x703EA071,
+/**/ 0xBF414129, 0xAAC00000,
+/**/ 0x3D05BF68, 0x170ECD8C,
+/**/ 0x3F41324F, 0x21601B48,
+/**/ 0xBF413127, 0x83800000,
+/**/ 0x3D370A0B, 0x7C653BFC,
+/**/ 0x3F41224A, 0xD683330E,
+/**/ 0xBF412125, 0x5E200000,
+/**/ 0xBD35B70D, 0x77BBBEBF,
+/**/ 0x3F411246, 0x8FA7E642,
+/**/ 0xBF411123, 0x3AE00000,
+/**/ 0xBD0C52EB, 0x93ABC1CD,
+/**/ 0x3F410242, 0x4CCE3363,
+/**/ 0xBF410121, 0x19A00000,
+/**/ 0x3D2B2237, 0xE5C6F4C7,
+/**/ 0x3F40F23E, 0x0DF618F1,
+/**/ 0xBF40F11E, 0xFA600000,
+/**/ 0x3D3D9C5F, 0x1E9A50AD,
+/**/ 0x3F40E239, 0xD31F956A,
+/**/ 0xBF40E11C, 0xDD000000,
+/**/ 0xBD336793, 0x8965F0DA,
+/**/ 0x3F40D235, 0x9C4AA74E,
+/**/ 0xBF40D11A, 0xC1C00000,
+/**/ 0xBD15E6EE, 0x7E49E231,
+/**/ 0x3F40C231, 0x69774D1D,
+/**/ 0xBF40C118, 0xA8800000,
+/**/ 0x3D1D9B9D, 0x04FD621C,
+/**/ 0x3F40B22D, 0x3AA58554,
+/**/ 0xBF40B116, 0x91400000,
+/**/ 0x3D333B55, 0x7DD9EED3,
+/**/ 0x3F40A229, 0x0FD54E74,
+/**/ 0xBF40A114, 0x7C000000,
+/**/ 0x3D3E048F, 0x7AA78478,
+/**/ 0x3F409224, 0xE906A6FC,
+/**/ 0xBF409112, 0x68A00000,
+/**/ 0xBD383C6A, 0x644DDE88,
+/**/ 0x3F408220, 0xC6398D6B,
+/**/ 0xBF408110, 0x57600000,
+/**/ 0xBD2F0D2F, 0x76B8C83A,
+/**/ 0x3F40721C, 0xA76E0040,
+/**/ 0xBF40710E, 0x48200000,
+/**/ 0xBD1F63E0, 0x9CE99FD3,
+/**/ 0x3F406218, 0x8CA3FDFB,
+/**/ 0xBF40610C, 0x3AE00000,
+/**/ 0xBCF328B4, 0x4FE774F2,
+/**/ 0x3F405214, 0x75DB851A,
+/**/ 0xBF40510A, 0x2FA00000,
+/**/ 0x3D11B6BD, 0x3782BCD4,
+/**/ 0x3F404210, 0x6314941D,
+/**/ 0xBF404108, 0x26600000,
+/**/ 0x3D22116F, 0xE7183792,
+/**/ 0x3F40320C, 0x544F2983,
+/**/ 0xBF403106, 0x1F200000,
+/**/ 0x3D293F1E, 0x1B995B3D,
+/**/ 0x3F402208, 0x498B43CB,
+/**/ 0xBF402104, 0x19E00000,
+/**/ 0x3D2E6669, 0xFC162630,
+/**/ 0x3F401204, 0x42C8E175,
+/**/ 0xBF401102, 0x16A00000,
+/**/ 0x3D30C4AA, 0x254FC9F8,
+/**/ 0x3F400200, 0x40080100,
+/**/ 0xBF400100, 0x15600000,
+/**/ 0x3D3154EE, 0xE4431F92,
+/**/ 0x3F3FE3F8, 0x829141D6,
+/**/ 0xBF3FE1FC, 0x2C400000,
+/**/ 0x3D30E503, 0x9B2D30FB,
+/**/ 0x3F3FC3F0, 0x8D157F6B,
+/**/ 0xBF3FC1F8, 0x31C00000,
+/**/ 0x3D2EEBD1, 0x53EBD670,
+/**/ 0x3F3FA3E8, 0x9F9CB7BC,
+/**/ 0xBF3FA1F4, 0x3B400000,
+/**/ 0x3D2A113C, 0xE04A16E0,
+/**/ 0x3F3F83E0, 0xBA26E7CA,
+/**/ 0xBF3F81F0, 0x48C00000,
+/**/ 0x3D233C4A, 0x99C43E34,
+/**/ 0x3F3F63D8, 0xDCB40C91,
+/**/ 0xBF3F61EC, 0x5A400000,
+/**/ 0x3D14DDF6, 0x7BD210C1,
+/**/ 0x3F3F43D1, 0x07442311,
+/**/ 0xBF3F41E8, 0x6FC00000,
+/**/ 0xBCC52C1D, 0x9E4B51C8,
+/**/ 0x3F3F23C9, 0x39D72849,
+/**/ 0xBF3F21E4, 0x89400000,
+/**/ 0xBD1A196F, 0x8EA8C754,
+/**/ 0x3F3F03C1, 0x746D1936,
+/**/ 0xBF3F01E0, 0xA6C00000,
+/**/ 0xBD2BB719, 0xF95AF98D,
+/**/ 0x3F3EE3B9, 0xB705F2D8,
+/**/ 0xBF3EE1DC, 0xC8400000,
+/**/ 0xBD3628EB, 0x28FFD598,
+/**/ 0x3F3EC3B2, 0x01A1B22C,
+/**/ 0xBF3EC1D8, 0xEDC00000,
+/**/ 0xBD3F6D76, 0x0BBAC8F8,
+/**/ 0x3F3EA3AA, 0x54405432,
+/**/ 0xBF3EA1D5, 0x17800000,
+/**/ 0x3D3657D2, 0xB7A7EE0D,
+/**/ 0x3F3E83A2, 0xAEE1D5E8,
+/**/ 0xBF3E81D1, 0x45000000,
+/**/ 0x3D264FDE, 0xFA9CCC78,
+/**/ 0x3F3E639B, 0x1186344C,
+/**/ 0xBF3E61CD, 0x76800000,
+/**/ 0xBCEF83EB, 0xE02EF455,
+/**/ 0x3F3E4393, 0x7C2D6C5E,
+/**/ 0xBF3E41C9, 0xAC000000,
+/**/ 0xBD2C26B3, 0x03C3E129,
+/**/ 0x3F3E238B, 0xEED77B1B,
+/**/ 0xBF3E21C5, 0xE5800000,
+/**/ 0xBD3C1CBE, 0x904D773D,
+/**/ 0x3F3E0384, 0x69845D83,
+/**/ 0xBF3E01C2, 0x23400000,
+/**/ 0x3D34E8B1, 0xD0615454,
+/**/ 0x3F3DE37C, 0xEC341093,
+/**/ 0xBF3DE1BE, 0x64C00000,
+/**/ 0x3D13F7DF, 0xE9BE933E,
+/**/ 0x3F3DC375, 0x76E6914B,
+/**/ 0xBF3DC1BA, 0xAA400000,
+/**/ 0xBD27B7D7, 0x707B004A,
+/**/ 0x3F3DA36E, 0x099BDCA9,
+/**/ 0xBF3DA1B6, 0xF3C00000,
+/**/ 0xBD3DA3F8, 0xEE2141C3,
+/**/ 0x3F3D8366, 0xA453EFAC,
+/**/ 0xBF3D81B3, 0x41800000,
+/**/ 0x3D2F4DA1, 0x63D21825,
+/**/ 0x3F3D635F, 0x470EC752,
+/**/ 0xBF3D61AF, 0x93000000,
+/**/ 0xBD0FD473, 0xFAD0B844,
+/**/ 0x3F3D4357, 0xF1CC609A,
+/**/ 0xBF3D41AB, 0xE8800000,
+/**/ 0xBD388716, 0x298657C2,
+/**/ 0x3F3D2350, 0xA48CB882,
+/**/ 0xBF3D21A8, 0x42400000,
+/**/ 0x3D32023A, 0x0B68711A,
+/**/ 0x3F3D0349, 0x5F4FCC0A,
+/**/ 0xBF3D01A4, 0x9FC00000,
+/**/ 0xBD117676, 0x23A704B0,
+/**/ 0x3F3CE342, 0x22159830,
+/**/ 0xBF3CE1A1, 0x01400000,
+/**/ 0xBD3BA59C, 0x8F391F09,
+/**/ 0x3F3CC33A, 0xECDE19F1,
+/**/ 0xBF3CC19D, 0x67000000,
+/**/ 0x3D28567A, 0x9EBBF706,
+/**/ 0x3F3CA333, 0xBFA94E4E,
+/**/ 0xBF3CA199, 0xD0800000,
+/**/ 0xBD29D41F, 0x2D41F1CC,
+/**/ 0x3F3C832C, 0x9A773245,
+/**/ 0xBF3C8196, 0x3E400000,
+/**/ 0x3D391B7D, 0x14ED5134,
+/**/ 0x3F3C6325, 0x7D47C2D4,
+/**/ 0xBF3C6192, 0xAFC00000,
+/**/ 0xBCFC31C5, 0x83403B5B,
+/**/ 0x3F3C431E, 0x681AFCFA,
+/**/ 0xBF3C418F, 0x25400000,
+/**/ 0xBD3D84DB, 0x88A1FFF3,
+/**/ 0x3F3C2317, 0x5AF0DDB6,
+/**/ 0xBF3C218B, 0x9F000000,
+/**/ 0x3D175CFF, 0x6298A63B,
+/**/ 0x3F3C0310, 0x55C96207,
+/**/ 0xBF3C0188, 0x1C800000,
+/**/ 0xBD37ADC9, 0xDFB8E489,
+/**/ 0x3F3BE309, 0x58A486EA,
+/**/ 0xBF3BE184, 0x9E400000,
+/**/ 0x3D23DA0F, 0x45069C64,
+/**/ 0x3F3BC302, 0x6382495F,
+/**/ 0xBF3BC181, 0x23C00000,
+/**/ 0xBD35574B, 0x4CC2EFE0,
+/**/ 0x3F3BA2FB, 0x7662A665,
+/**/ 0xBF3BA17D, 0xAD800000,
+/**/ 0x3D250C7B, 0x4BED0B89,
+/**/ 0x3F3B82F4, 0x91459AFA,
+/**/ 0xBF3B817A, 0x3B000000,
+/**/ 0xBD36795D, 0x322E5605,
+/**/ 0x3F3B62ED, 0xB42B241D,
+/**/ 0xBF3B6176, 0xCCC00000,
+/**/ 0x3D1EAB91, 0xF6413886,
+/**/ 0x3F3B42E6, 0xDF133ECC,
+/**/ 0xBF3B4173, 0x62400000,
+/**/ 0xBD3B0BFC, 0xF86BE5B5,
+/**/ 0x3F3B22E0, 0x11FDE807,
+/**/ 0xBF3B216F, 0xFC000000,
+/**/ 0x3CF62FEB, 0xDDE8D701,
+/**/ 0x3F3B02D9, 0x4CEB1CCC,
+/**/ 0xBF3B016C, 0x99C00000,
+/**/ 0x3D3CF8D7, 0xF210FD9E,
+/**/ 0x3F3AE2D2, 0x8FDADA1A,
+/**/ 0xBF3AE169, 0x3B400000,
+/**/ 0xBD2092E2, 0x1526CFB0,
+/**/ 0x3F3AC2CB, 0xDACD1CEF,
+/**/ 0xBF3AC165, 0xE1000000,
+/**/ 0x3D319D24, 0x18D261D5,
+/**/ 0x3F3AA2C5, 0x2DC1E24A,
+/**/ 0xBF3AA162, 0x8A800000,
+/**/ 0xBD355268, 0x533CC8EC,
+/**/ 0x3F3A82BE, 0x88B9272B,
+/**/ 0xBF3A815F, 0x38400000,
+/**/ 0x3D074750, 0x0AFE6139,
+/**/ 0x3F3A62B7, 0xEBB2E88F,
+/**/ 0xBF3A615B, 0xEA000000,
+/**/ 0x3D3A501B, 0x6668AD57,
+/**/ 0x3F3A42B1, 0x56AF2375,
+/**/ 0xBF3A4158, 0x9F800000,
+/**/ 0xBD2E37A7, 0xA98381BD,
+/**/ 0x3F3A22AA, 0xC9ADD4DD,
+/**/ 0xBF3A2155, 0x59400000,
+/**/ 0x3D1A9872, 0x7B82F9AC,
+/**/ 0x3F3A02A4, 0x44AEF9C5,
+/**/ 0xBF3A0152, 0x17000000,
+/**/ 0x3D3B96ED, 0x0FF040AD,
+/**/ 0x3F39E29D, 0xC7B28F2C,
+/**/ 0xBF39E14E, 0xD8800000,
+/**/ 0xBD304862, 0x33534BD7,
+/**/ 0x3F39C297, 0x52B89211,
+/**/ 0xBF39C14B, 0x9E400000,
+/**/ 0x3D084979, 0x17AF009B,
+/**/ 0x3F39A290, 0xE5C0FF72,
+/**/ 0xBF39A148, 0x68000000,
+/**/ 0x3D358CA1, 0x604B64C9,
+/**/ 0x3F39828A, 0x80CBD44E,
+/**/ 0xBF398145, 0x35800000,
+/**/ 0xBD38BD0B, 0x2E334404,
+/**/ 0x3F396284, 0x23D90DA4,
+/**/ 0xBF396142, 0x07400000,
+/**/ 0xBD1F4B58, 0xEF1B1C68,
+/**/ 0x3F39427D, 0xCEE8A873,
+/**/ 0xBF39413E, 0xDD000000,
+/**/ 0x3D209881, 0x07E010EC,
+/**/ 0x3F392277, 0x81FAA1B9,
+/**/ 0xBF39213B, 0xB6C00000,
+/**/ 0x3D37A139, 0x5CF03181,
+/**/ 0x3F390271, 0x3D0EF676,
+/**/ 0xBF390138, 0x94400000,
+/**/ 0xBD39D2EB, 0x65276B0B,
+/**/ 0x3F38E26B, 0x0025A3A8,
+/**/ 0xBF38E135, 0x76000000,
+/**/ 0xBD281E5A, 0xEE3023F6,
+/**/ 0x3F38C264, 0xCB3EA64F,
+/**/ 0xBF38C132, 0x5BC00000,
+/**/ 0x3CEDAE6E, 0x3F9A4B53,
+/**/ 0x3F38A25E, 0x9E59FB68,
+/**/ 0xBF38A12F, 0x45800000,
+/**/ 0x3D2A47EF, 0x412B648E,
+/**/ 0x3F388258, 0x79779FF3,
+/**/ 0xBF38812C, 0x33400000,
+/**/ 0x3D38955F, 0x5ED0D8F2,
+/**/ 0x3F386252, 0x5C9790EE,
+/**/ 0xBF386129, 0x24C00000,
+/**/ 0xBD3CBD55, 0x09939374,
+/**/ 0x3F38424C, 0x47B9CB5A,
+/**/ 0xBF384126, 0x1A800000,
+/**/ 0xBD32D325, 0x4F399186,
+/**/ 0x3F382246, 0x3ADE4C33,
+/**/ 0xBF382123, 0x14400000,
+/**/ 0xBD235622, 0x524688EB,
+/**/ 0x3F380240, 0x3605107A,
+/**/ 0xBF380120, 0x12000000,
+/**/ 0xBCF44184, 0xEB2F3DDC,
+/**/ 0x3F37E23A, 0x392E152C,
+/**/ 0xBF37E11D, 0x13C00000,
+/**/ 0x3D198B16, 0x2153D1B8,
+/**/ 0x3F37C234, 0x4459574A,
+/**/ 0xBF37C11A, 0x19800000,
+/**/ 0x3D2A9511, 0x47A3C923,
+/**/ 0x3F37A22E, 0x5786D3D1,
+/**/ 0xBF37A117, 0x23400000,
+/**/ 0x3D337431, 0x4B4128D9,
+/**/ 0x3F378228, 0x72B687C1,
+/**/ 0xBF378114, 0x31000000,
+/**/ 0x3D38E0BF, 0xC5BFE9E8,
+/**/ 0x3F376222, 0x95E87019,
+/**/ 0xBF376111, 0x42C00000,
+/**/ 0x3D3D9134, 0x5A0B2CE9,
+/**/ 0x3F37421C, 0xC11C89D8,
+/**/ 0xBF37410E, 0x58400000,
+/**/ 0xBD3E7970, 0xB1802C40,
+/**/ 0x3F372216, 0xF452D1FB,
+/**/ 0xBF37210B, 0x72000000,
+/**/ 0xBD3B3E2F, 0x16E562C9,
+/**/ 0x3F370211, 0x2F8B4583,
+/**/ 0xBF370108, 0x8FC00000,
+/**/ 0xBD38BC06, 0x9087DACD,
+/**/ 0x3F36E20B, 0x72C5E16F,
+/**/ 0xBF36E105, 0xB1800000,
+/**/ 0xBD36F1F6, 0xD92B1B21,
+/**/ 0x3F36C205, 0xBE02A2BC,
+/**/ 0xBF36C102, 0xD7400000,
+/**/ 0xBD35DEFF, 0xABF2CD23,
+/**/ 0x3F36A200, 0x1141866B,
+/**/ 0xBF36A100, 0x01000000,
+/**/ 0xBD358220, 0xC462BC85,
+/**/ 0x3F3681FA, 0x6C828979,
+/**/ 0xBF3680FD, 0x2EC00000,
+/**/ 0xBD35DA59, 0xDE5ED723,
+/**/ 0x3F3661F4, 0xCFC5A8E7,
+/**/ 0xBF3660FA, 0x60800000,
+/**/ 0xBD36E6AA, 0xB62B2CD1,
+/**/ 0x3F3641EF, 0x3B0AE1B2,
+/**/ 0xBF3640F7, 0x96400000,
+/**/ 0xBD38A613, 0x086BEF29,
+/**/ 0x3F3621E9, 0xAE5230DA,
+/**/ 0xBF3620F4, 0xD0000000,
+/**/ 0xBD3B1792, 0x9225715D,
+/**/ 0x3F3601E4, 0x299B935F,
+/**/ 0xBF3600F2, 0x0DC00000,
+/**/ 0xBD3E3A29, 0x10BC2805,
+/**/ 0x3F35E1DE, 0xACE7063E,
+/**/ 0xBF35E0EF, 0x4FC00000,
+/**/ 0x3D3DF329, 0xBE0B570D,
+/**/ 0x3F35C1D9, 0x38348676,
+/**/ 0xBF35C0EC, 0x95800000,
+/**/ 0x3D397166, 0x1C0C5502,
+/**/ 0x3F35A1D3, 0xCB841108,
+/**/ 0xBF35A0E9, 0xDF400000,
+/**/ 0x3D34418C, 0x4AC1FA2D,
+/**/ 0x3F3581CE, 0x66D5A2F1,
+/**/ 0xBF3580E7, 0x2D000000,
+/**/ 0x3D2CC939, 0x168E9C6E,
+/**/ 0x3F3561C9, 0x0A293931,
+/**/ 0xBF3560E4, 0x7EC00000,
+/**/ 0x3D1F6E5C, 0x795CE154,
+/**/ 0x3F3541C3, 0xB57ED0C7,
+/**/ 0xBF3540E1, 0xD4800000,
+/**/ 0x3CE4EF88, 0x898FEE67,
+/**/ 0x3F3521BE, 0x68D666B1,
+/**/ 0xBF3520DF, 0x2E400000,
+/**/ 0xBD1CDACF, 0x0B78D65E,
+/**/ 0x3F3501B9, 0x242FF7EF,
+/**/ 0xBF3500DC, 0x8C000000,
+/**/ 0xBD2F7BF1, 0x6F1CBFB8,
+/**/ 0x3F34E1B3, 0xE78B8180,
+/**/ 0xBF34E0D9, 0xEDC00000,
+/**/ 0xBD38ED52, 0x5A899820,
+/**/ 0x3F34C1AE, 0xB2E90063,
+/**/ 0xBF34C0D7, 0x53C00000,
+/**/ 0x3D3D3C3F, 0x930A694E,
+/**/ 0x3F34A1A9, 0x86487196,
+/**/ 0xBF34A0D4, 0xBD800000,
+/**/ 0x3D32BFBD, 0x4FA7CCCB,
+/**/ 0x3F3481A4, 0x61A9D219,
+/**/ 0xBF3480D2, 0x2B400000,
+/**/ 0x3D1E789C, 0x65A26E32,
+/**/ 0x3F34619F, 0x450D1EEB,
+/**/ 0xBF3460CF, 0x9D000000,
+/**/ 0xBD109E0B, 0x47E500B5,
+/**/ 0x3F34419A, 0x3072550B,
+/**/ 0xBF3440CD, 0x12C00000,
+/**/ 0xBD309040, 0x3523FAE9,
+/**/ 0x3F342195, 0x23D97178,
+/**/ 0xBF3420CA, 0x8C800000,
+/**/ 0xBD3D9B10, 0xD31DE7C2,
+/**/ 0x3F340190, 0x1F427131,
+/**/ 0xBF3400C8, 0x0A800000,
+/**/ 0x3D34B90B, 0x90B287C4,
+/**/ 0x3F33E18B, 0x22AD5135,
+/**/ 0xBF33E0C5, 0x8C400000,
+/**/ 0x3D19B454, 0xCA1B0FC2,
+/**/ 0x3F33C186, 0x2E1A0E83,
+/**/ 0xBF33C0C3, 0x12000000,
+/**/ 0xBD20FBE7, 0x638FC1F4,
+/**/ 0x3F33A181, 0x4188A61A,
+/**/ 0xBF33A0C0, 0x9BC00000,
+/**/ 0xBD38070E, 0xE0C03290,
+/**/ 0x3F33817C, 0x5CF914F9,
+/**/ 0xBF3380BE, 0x29C00000,
+/**/ 0x3D37D2C3, 0xE0B6E5F5,
+/**/ 0x3F336177, 0x806B5820,
+/**/ 0xBF3360BB, 0xBB800000,
+/**/ 0x3D1C4213, 0x35598794,
+/**/ 0x3F334172, 0xABDF6C8D,
+/**/ 0xBF3340B9, 0x51400000,
+/**/ 0xBD249997, 0xC111C569,
+/**/ 0x3F33216D, 0xDF554F40,
+/**/ 0xBF3320B6, 0xEB000000,
+/**/ 0xBD3C442D, 0xEEEE28E2,
+/**/ 0x3F330169, 0x1ACCFD37,
+/**/ 0xBF3300B4, 0x89000000,
+/**/ 0x3D312B5E, 0xDBBF316D,
+/**/ 0x3F32E164, 0x5E467372,
+/**/ 0xBF32E0B2, 0x2AC00000,
+/**/ 0xBCFFD254, 0x7484E6E1,
+/**/ 0x3F32C15F, 0xA9C1AEF0,
+/**/ 0xBF32C0AF, 0xD0800000,
+/**/ 0xBD35BCBA, 0x1F2C3F9D,
+/**/ 0x3F32A15A, 0xFD3EACAF,
+/**/ 0xBF32A0AD, 0x7A800000,
+/**/ 0x3D35EDA0, 0x8C8BAA61,
+/**/ 0x3F328156, 0x58BD69B0,
+/**/ 0xBF3280AB, 0x28400000,
+/**/ 0x3CF02EAF, 0x3F79FE5E,
+/**/ 0x3F326151, 0xBC3DE2F1,
+/**/ 0xBF3260A8, 0xDA000000,
+/**/ 0xBD347BDA, 0xB1304AA8,
+/**/ 0x3F32414D, 0x27C01572,
+/**/ 0xBF3240A6, 0x90000000,
+/**/ 0x3D35724F, 0xD46BE359,
+/**/ 0x3F322148, 0x9B43FE30,
+/**/ 0xBF3220A4, 0x49C00000,
+/**/ 0xBCF31954, 0x43BF90C9,
+/**/ 0x3F320144, 0x16C99A2D,
+/**/ 0xBF3200A2, 0x07800000,
+/**/ 0xBD386689, 0xC4901E30,
+/**/ 0x3F31E13F, 0x9A50E666,
+/**/ 0xBF31E09F, 0xC9800000,
+/**/ 0x3D2FA8E5, 0x134E34BF,
+/**/ 0x3F31C13B, 0x25D9DFDB,
+/**/ 0xBF31C09D, 0x8F400000,
+/**/ 0xBD20FF40, 0x477D87DF,
+/**/ 0x3F31A136, 0xB964838C,
+/**/ 0xBF31A09B, 0x59400000,
+/**/ 0x3D3E9E3E, 0x68B5B77B,
+/**/ 0x3F318132, 0x54F0CE76,
+/**/ 0xBF318099, 0x27000000,
+/**/ 0x3D14BC39, 0x906F8A53,
+/**/ 0x3F31612D, 0xF87EBD9A,
+/**/ 0xBF316096, 0xF8C00000,
+/**/ 0xBD34CC2F, 0xFCD50724,
+/**/ 0x3F314129, 0xA40E4DF7,
+/**/ 0xBF314094, 0xCEC00000,
+/**/ 0x3D30AD83, 0x7A3A1B8D,
+/**/ 0x3F312125, 0x579F7C8B,
+/**/ 0xBF312092, 0xA8800000,
+/**/ 0xBD24C5AE, 0x057F5C66,
+/**/ 0x3F310121, 0x13324657,
+/**/ 0xBF310090, 0x86800000,
+/**/ 0x3D3A03C0, 0xBFD488E0,
+/**/ 0x3F30E11C, 0xD6C6A858,
+/**/ 0xBF30E08E, 0x68400000,
+/**/ 0xBD00EDA8, 0x56935D63,
+/**/ 0x3F30C118, 0xA25C9F8F,
+/**/ 0xBF30C08C, 0x4E000000,
+/**/ 0xBD3EC638, 0x2FDDD1CE,
+/**/ 0x3F30A114, 0x75F428FB,
+/**/ 0xBF30A08A, 0x38000000,
+/**/ 0x3D102CDE, 0x0CA3DCBE,
+/**/ 0x3F308110, 0x518D419B,
+/**/ 0xBF308088, 0x25C00000,
+/**/ 0xBD39A865, 0xBFA78921,
+/**/ 0x3F30610C, 0x3527E66D,
+/**/ 0xBF306086, 0x17C00000,
+/**/ 0x3D203FE0, 0x72CE37BD,
+/**/ 0x3F304108, 0x20C41472,
+/**/ 0xBF304084, 0x0D800000,
+/**/ 0xBD369AC6, 0x6054C3FA,
+/**/ 0x3F302104, 0x1461C8A9,
+/**/ 0xBF302082, 0x07800000,
+/**/ 0x3D2450ED, 0x4836293A,
+/**/ 0x3F300100, 0x10010010,
+/**/ 0xBF300080, 0x05400000,
+/**/ 0xBD359558, 0x88B3357C,
+/**/ 0x3F2FC1F8, 0x27436F4F,
+/**/ 0xBF2FC0FC, 0x0E800000,
+/**/ 0x3D245998, 0x92ECD4D1,
+/**/ 0x3F2F81F0, 0x3E87D8DC,
+/**/ 0xBF2F80F8, 0x1A000000,
+/**/ 0xBD36901A, 0xB592170A,
+/**/ 0x3F2F41E8, 0x65CF36C6,
+/**/ 0xBF2F40F4, 0x2E000000,
+/**/ 0x3D2069E5, 0x53524603,
+/**/ 0x3F2F01E0, 0x9D19830B,
+/**/ 0xBF2F00F0, 0x49800000,
+/**/ 0xBD39830B, 0x69C22240,
+/**/ 0x3F2EC1D8, 0xE466B7AB,
+/**/ 0xBF2EC0EC, 0x6D800000,
+/**/ 0x3D1123AC, 0xFB871BBA,
+/**/ 0x3F2E81D1, 0x3BB6CEA4,
+/**/ 0xBF2E80E8, 0x99000000,
+/**/ 0xBD3E6629, 0x2E158AF6,
+/**/ 0x3F2E41C9, 0xA309C1F4,
+/**/ 0xBF2E40E4, 0xCD000000,
+/**/ 0xBCF8F488, 0x2B29884E,
+/**/ 0x3F2E01C2, 0x1A5F8B99,
+/**/ 0xBF2E00E1, 0x09000000,
+/**/ 0x3D3ACE8D, 0x6EA006C6,
+/**/ 0x3F2DC1BA, 0xA1B82593,
+/**/ 0xBF2DC0DD, 0x4C800000,
+/**/ 0xBD22974E, 0x59D0B687,
+/**/ 0x3F2D81B3, 0x391389E0,
+/**/ 0xBF2D80D9, 0x98800000,
+/**/ 0x3D322319, 0xD7897CAD,
+/**/ 0x3F2D41AB, 0xE071B27F,
+/**/ 0xBF2D40D5, 0xEC000000,
+/**/ 0xBD32E42F, 0x57954C6E,
+/**/ 0x3F2D01A4, 0x97D2996E,
+/**/ 0xBF2D00D2, 0x48000000,
+/**/ 0x3D1E7DF5, 0xC741610E,
+/**/ 0x3F2CC19D, 0x5F3638AB,
+/**/ 0xBF2CC0CE, 0xAB800000,
+/**/ 0xBD3E50DF, 0xA0909C5A,
+/**/ 0x3F2C8196, 0x369C8A37,
+/**/ 0xBF2C80CB, 0x17800000,
+/**/ 0xBD12D119, 0x8D8D1C8F,
+/**/ 0x3F2C418F, 0x1E05880E,
+/**/ 0xBF2C40C7, 0x8B800000,
+/**/ 0x3D347649, 0x544D2574,
+/**/ 0x3F2C0188, 0x15712C30,
+/**/ 0xBF2C00C4, 0x07000000,
+/**/ 0xBD32D030, 0x4EEA9E68,
+/**/ 0x3F2BC181, 0x1CDF709C,
+/**/ 0xBF2BC0C0, 0x8B000000,
+/**/ 0x3D15E533, 0x74A84109,
+/**/ 0x3F2B817A, 0x34504F50,
+/**/ 0xBF2B80BD, 0x17000000,
+/**/ 0x3D3D53C1, 0x025FBF68,
+/**/ 0x3F2B4173, 0x5BC3C24B,
+/**/ 0xBF2B40B9, 0xAA800000,
+/**/ 0xBD267FA7, 0x6BAA2FA8,
+/**/ 0x3F2B016C, 0x9339C38C,
+/**/ 0xBF2B00B6, 0x46800000,
+/**/ 0x3D277F1D, 0xBB3FDE1E,
+/**/ 0x3F2AC165, 0xDAB24D11,
+/**/ 0xBF2AC0B2, 0xEA000000,
+/**/ 0xBD3DAD17, 0x1A8CDBE2,
+/**/ 0x3F2A815F, 0x322D58D9,
+/**/ 0xBF2A80AF, 0x96000000,
+/**/ 0xBD1E1315, 0xD81CF36E,
+/**/ 0x3F2A4158, 0x99AAE0E3,
+/**/ 0xBF2A40AC, 0x4A000000,
+/**/ 0x3D2C7307, 0xE649E7B4,
+/**/ 0x3F2A0152, 0x112ADF2D,
+/**/ 0xBF2A00A9, 0x05800000,
+/**/ 0xBD3C713A, 0xB77435EC,
+/**/ 0x3F29C14B, 0x98AD4DB7,
+/**/ 0xBF29C0A5, 0xC9800000,
+/**/ 0xBD1E1005, 0x3A7AE827,
+/**/ 0x3F298145, 0x3032267F,
+/**/ 0xBF2980A2, 0x95800000,
+/**/ 0x3D2A0460, 0xA8F2A842,
+/**/ 0x3F29413E, 0xD7B96385,
+/**/ 0xBF29409F, 0x69000000,
+/**/ 0xBD3EDDA5, 0xA7B8321E,
+/**/ 0x3F290138, 0x8F42FEC5,
+/**/ 0xBF29009C, 0x45000000,
+/**/ 0xBD264506, 0x3A3F0D33,
+/**/ 0x3F28C132, 0x56CEF241,
+/**/ 0xBF28C099, 0x29000000,
+/**/ 0x3D206930, 0x33EE13CD,
+/**/ 0x3F28812C, 0x2E5D37F6,
+/**/ 0xBF288096, 0x15000000,
+/**/ 0x3D3B28AC, 0x22DF1FDA,
+/**/ 0x3F284126, 0x15EDC9E3,
+/**/ 0xBF284093, 0x08800000,
+/**/ 0xBD324546, 0xDD73B6DB,
+/**/ 0x3F280120, 0x0D80A208,
+/**/ 0xBF280090, 0x04800000,
+/**/ 0xBCB440C2, 0x6DFEB485,
+/**/ 0x3F27C11A, 0x1515BA62,
+/**/ 0xBF27C08D, 0x08800000,
+/**/ 0x3D31BCBE, 0x9823B19D,
+/**/ 0x3F278114, 0x2CAD0CF1,
+/**/ 0xBF27808A, 0x14000000,
+/**/ 0xBD3CD148, 0xA9EB4E97,
+/**/ 0x3F27410E, 0x544693B4,
+/**/ 0xBF274087, 0x28000000,
+/**/ 0xBD277AAC, 0xCA4F73AA,
+/**/ 0x3F270108, 0x8BE248AA,
+/**/ 0xBF270084, 0x44000000,
+/**/ 0x3D13E656, 0x26068EF7,
+/**/ 0x3F26C102, 0xD38025D2,
+/**/ 0xBF26C081, 0x68000000,
+/**/ 0x3D35547B, 0x44C3EC8A,
+/**/ 0x3F2680FD, 0x2B20252A,
+/**/ 0xBF26807E, 0x93800000,
+/**/ 0xBD3AABA5, 0x110DCE4B,
+/**/ 0x3F2640F7, 0x92C240B1,
+/**/ 0xBF26407B, 0xC7800000,
+/**/ 0xBD260B96, 0xAC011956,
+/**/ 0x3F2600F2, 0x0A667267,
+/**/ 0xBF260079, 0x03800000,
+/**/ 0x3D111C22, 0x5DFA826E,
+/**/ 0x3F25C0EC, 0x920CB44A,
+/**/ 0xBF25C076, 0x47800000,
+/**/ 0x3D333BD6, 0xD8A2980A,
+/**/ 0x3F2580E7, 0x29B5005A,
+/**/ 0xBF258073, 0x93000000,
+/**/ 0xBD3E2660, 0x71C1D861,
+/**/ 0x3F2540E1, 0xD15F5095,
+/**/ 0xBF254070, 0xE7000000,
+/**/ 0xBD2FBD3A, 0x4E77E5EE,
+/**/ 0x3F2500DC, 0x890B9EFA,
+/**/ 0xBF25006E, 0x43000000,
+/**/ 0xBCFEBDF2, 0x7B90A2D9,
+/**/ 0x3F24C0D7, 0x50B9E589,
+/**/ 0xBF24C06B, 0xA7000000,
+/**/ 0x3D2765B3, 0x58F2FF2C,
+/**/ 0x3F2480D2, 0x286A1E40,
+/**/ 0xBF248069, 0x13000000,
+/**/ 0x3D38FE8D, 0x74AE382C,
+/**/ 0x3F2440CD, 0x101C431E,
+/**/ 0xBF244066, 0x86800000,
+/**/ 0xBD3A07C3, 0xB0286224,
+/**/ 0x3F2400C8, 0x07D04E23,
+/**/ 0xBF240064, 0x02800000,
+/**/ 0xBD2ABE33, 0x46EFC0EC,
+/**/ 0x3F23C0C3, 0x0F86394D,
+/**/ 0xBF23C061, 0x86800000,
+/**/ 0xBCF06744, 0x70DE3151,
+/**/ 0x3F2380BE, 0x273DFE9C,
+/**/ 0xBF23805F, 0x12800000,
+/**/ 0x3D260659, 0x05CFCD61,
+/**/ 0x3F2340B9, 0x4EF7980F,
+/**/ 0xBF23405C, 0xA6800000,
+/**/ 0x3D36BEC8, 0xD7DBBEBC,
+/**/ 0x3F2300B4, 0x86B2FFA4,
+/**/ 0xBF23005A, 0x42000000,
+/**/ 0xBD3DD29F, 0x2B2027B4,
+/**/ 0x3F22C0AF, 0xCE702F5C,
+/**/ 0xBF22C057, 0xE6000000,
+/**/ 0xBD32B00B, 0x6959A7D0,
+/**/ 0x3F2280AB, 0x262F2134,
+/**/ 0xBF228055, 0x92000000,
+/**/ 0xBD1F61EF, 0x19FAAC2D,
+/**/ 0x3F2240A6, 0x8DEFCF2C,
+/**/ 0xBF224053, 0x46000000,
+/**/ 0x3D05A87E, 0xCB16B8A8,
+/**/ 0x3F2200A2, 0x05B23344,
+/**/ 0xBF220051, 0x02000000,
+/**/ 0x3D29F32F, 0x23B9B257,
+/**/ 0x3F21C09D, 0x8D76477A,
+/**/ 0xBF21C04E, 0xC6000000,
+/**/ 0x3D36F61B, 0x7E214821,
+/**/ 0x3F218099, 0x253C05CD,
+/**/ 0xBF21804C, 0x91800000,
+/**/ 0xBD3F5464, 0x46FDFCA2,
+/**/ 0x3F214094, 0xCD03683D,
+/**/ 0xBF21404A, 0x65800000,
+/**/ 0xBD35E4E7, 0xA30F2308,
+/**/ 0x3F210090, 0x84CC68C9,
+/**/ 0xBF210048, 0x41800000,
+/**/ 0xBD2974DC, 0xF800CC34,
+/**/ 0x3F20C08C, 0x4C970171,
+/**/ 0xBF20C046, 0x25800000,
+/**/ 0xBD0E9FC5, 0xC1006E9D,
+/**/ 0x3F208088, 0x24632C32,
+/**/ 0xBF208044, 0x11800000,
+/**/ 0x3D133DE7, 0x078E4438,
+/**/ 0x3F204084, 0x0C30E30D,
+/**/ 0xBF204042, 0x05800000,
+/**/ 0x3D2A61D2, 0x15F82A7B,
+/**/ 0x3F200080, 0x04002001,
+/**/ 0xBF200040, 0x01800000,
+/**/ 0x3D355155, 0x3BBB110C,
+/**/ 0x3F1F80F8, 0x17A1BA1A,
+/**/ 0xBF1F807C, 0x0B000000,
+/**/ 0x3D3D31BE, 0x6C520A9B,
+/**/ 0x3F1F00F0, 0x47462860,
+/**/ 0xBF1F0078, 0x22000000,
+/**/ 0xBD3B2CDB, 0x4B6D83F6,
+/**/ 0x3F1E80E8, 0x96ED7ED3,
+/**/ 0xBF1E8074, 0x4A000000,
+/**/ 0xBD33C977, 0xD4122C5A,
+/**/ 0x3F1E00E1, 0x0697B172,
+/**/ 0xBF1E0070, 0x82000000,
+/**/ 0xBD29462E, 0x2D1517C4,
+/**/ 0x3F1D80D9, 0x9644B43B,
+/**/ 0xBF1D806C, 0xCA000000,
+/**/ 0xBD16E2E3, 0xF0952D45,
+/**/ 0x3F1D00D2, 0x45F47B2C,
+/**/ 0xBF1D0069, 0x22000000,
+/**/ 0x3CEED452, 0x2DDC2A8D,
+/**/ 0x3F1C80CB, 0x15A6FA46,
+/**/ 0xBF1C8065, 0x8A000000,
+/**/ 0x3D1DAFEE, 0xA08CEBE8,
+/**/ 0x3F1C00C4, 0x055C2585,
+/**/ 0xBF1C0062, 0x02000000,
+/**/ 0x3D2B50A4, 0xBB11EF55,
+/**/ 0x3F1B80BD, 0x1513F0E9,
+/**/ 0xBF1B805E, 0x8A000000,
+/**/ 0x3D33ACA6, 0xC6D142BF,
+/**/ 0x3F1B00B6, 0x44CE5071,
+/**/ 0xBF1B005B, 0x22000000,
+/**/ 0x3D3979F8, 0xF8CD3D11,
+/**/ 0x3F1A80AF, 0x948B381A,
+/**/ 0xBF1A8057, 0xCA000000,
+/**/ 0x3D3F1149, 0x07EDFD29,
+/**/ 0x3F1A00A9, 0x044A9BE5,
+/**/ 0xBF1A0054, 0x81000000,
+/**/ 0xBD3B8C68, 0xF7BB7092,
+/**/ 0x3F1980A2, 0x940C6FCF,
+/**/ 0xBF198051, 0x49000000,
+/**/ 0xBD365E1C, 0xF27E09A9,
+/**/ 0x3F19009C, 0x43D0A7D8,
+/**/ 0xBF19004E, 0x21000000,
+/**/ 0xBD3162D2, 0xD508D564,
+/**/ 0x3F188096, 0x139737FE,
+/**/ 0xBF18804B, 0x09000000,
+/**/ 0xBD293315, 0x18D5C93E,
+/**/ 0x3F180090, 0x03601440,
+/**/ 0xBF180048, 0x01000000,
+/**/ 0xBD200288, 0x0C26A328,
+/**/ 0x3F17808A, 0x132B309E,
+/**/ 0xBF178045, 0x09000000,
+/**/ 0xBD0CC7F9, 0x7E89FD6F,
+/**/ 0x3F170084, 0x42F88115,
+/**/ 0xBF170042, 0x21000000,
+/**/ 0x3CE40881, 0x058494DC,
+/**/ 0x3F16807E, 0x92C7F9A5,
+/**/ 0xBF16803F, 0x49000000,
+/**/ 0x3D12AE16, 0xCD5698B9,
+/**/ 0x3F160079, 0x02998E4D,
+/**/ 0xBF16003C, 0x81000000,
+/**/ 0x3D21138B, 0xC5780E17,
+/**/ 0x3F158073, 0x926D330B,
+/**/ 0xBF158039, 0xC9000000,
+/**/ 0x3D287809, 0x4E2001E2,
+/**/ 0x3F15006E, 0x4242DBDF,
+/**/ 0xBF150037, 0x21000000,
+/**/ 0x3D2F8684, 0x21448AA2,
+/**/ 0x3F148069, 0x121A7CC8,
+/**/ 0xBF148034, 0x89000000,
+/**/ 0x3D33207E, 0x2F637D8E,
+/**/ 0x3F140064, 0x01F409C4,
+/**/ 0xBF140032, 0x01000000,
+/**/ 0x3D3654B9, 0x12E44B29,
+/**/ 0x3F13805F, 0x11CF76D3,
+/**/ 0xBF13802F, 0x89000000,
+/**/ 0x3D3960F2, 0xCA5547F3,
+/**/ 0x3F13005A, 0x41ACB7F4,
+/**/ 0xBF13002D, 0x21000000,
+/**/ 0x3D3C462B, 0x6487063D,
+/**/ 0x3F128055, 0x918BC126,
+/**/ 0xBF12802A, 0xC9000000,
+/**/ 0x3D3F0562, 0xEFEA1107,
+/**/ 0x3F120051, 0x016C8668,
+/**/ 0xBF120028, 0x80000000,
+/**/ 0xBD3E6066, 0x857113CE,
+/**/ 0x3F11804C, 0x914EFBBA,
+/**/ 0xBF118026, 0x48000000,
+/**/ 0xBD3BEA30, 0xEDD9EB54,
+/**/ 0x3F110048, 0x41331519,
+/**/ 0xBF110024, 0x20000000,
+/**/ 0xBD3996FC, 0x3BFFFF5A,
+/**/ 0x3F108044, 0x1118C686,
+/**/ 0xBF108022, 0x08000000,
+/**/ 0xBD3765C8, 0x62F2E042,
+/**/ 0x3F100040, 0x01000400,
+/**/ 0xBF100020, 0x00000000,
+/**/ 0xBD355595, 0x562224CD,
+/**/ 0x3F0F0078, 0x21D1830C,
+/**/ 0xBF0F003C, 0x10000000,
+/**/ 0xBD336563, 0x095D69EB,
+/**/ 0x3F0E0070, 0x81A5E62E,
+/**/ 0xBF0E0038, 0x40000000,
+/**/ 0xBD319431, 0x70D45290,
+/**/ 0x3F0D0069, 0x217D1965,
+/**/ 0xBF0D0034, 0x90000000,
+/**/ 0xBD2FC201, 0x022D0EF6,
+/**/ 0x3F0C0062, 0x015704B1,
+/**/ 0xBF0C0031, 0x00000000,
+/**/ 0xBD2C95A0, 0x5E276E21,
+/**/ 0x3F0B005B, 0x2133900E,
+/**/ 0xBF0B002D, 0x90000000,
+/**/ 0xBD29A140, 0xE0372A42,
+/**/ 0x3F0A0054, 0x8112A37D,
+/**/ 0xBF0A002A, 0x40000000,
+/**/ 0xBD26E2E2, 0x73BBB580,
+/**/ 0x3F09004E, 0x20F426FB,
+/**/ 0xBF090027, 0x10000000,
+/**/ 0xBD245885, 0x04D48C20,
+/**/ 0x3F080048, 0x00D80288,
+/**/ 0xBF080024, 0x00000000,
+/**/ 0xBD220028, 0x80613426,
+/**/ 0x3F070042, 0x20BE1E23,
+/**/ 0xBF070021, 0x10000000,
+/**/ 0xBD1FAF99, 0xA80279F3,
+/**/ 0x3F06003C, 0x80A661CA,
+/**/ 0xBF06001E, 0x40000000,
+/**/ 0xBD1BBAE3, 0xDC287DFE,
+/**/ 0x3F050037, 0x2090B57C,
+/**/ 0xBF05001B, 0x90000000,
+/**/ 0xBD181E2F, 0x7B73B67C,
+/**/ 0x3F040032, 0x007D0139,
+/**/ 0xBF040019, 0x00000000,
+/**/ 0xBD14D57C, 0x65A375F8,
+/**/ 0x3F03002D, 0x206B2CFF,
+/**/ 0xBF030016, 0x90000000,
+/**/ 0xBD11DCCA, 0x7BF71EC1,
+/**/ 0x3F020028, 0x805B20CD,
+/**/ 0xBF020014, 0x40000000,
+/**/ 0xBD0E6033, 0x425C4447,
+/**/ 0x3F010024, 0x204CC4A3,
+/**/ 0xBF010012, 0x10000000,
+/**/ 0xBD0996D3, 0x730FFF5C,
+/**/ 0x3F000020, 0x00400080,
+/**/ 0xBF000010, 0x00000000,
+/**/ 0xBD055575, 0x558888DE,
+/**/ 0x3EFE0038, 0x406978C6,
+/**/ 0xBEFE001C, 0x20000000,
+/**/ 0xBD019418, 0xB845146A,
+/**/ 0x3EFC0031, 0x0055C096,
+/**/ 0xBEFC0018, 0x80000000,
+/**/ 0xBCFC957A, 0xD989DB3C,
+/**/ 0x3EFA002A, 0x4044A870,
+/**/ 0xBEFA0015, 0x20000000,
+/**/ 0xBCF6E2C6, 0x8F0EED2F,
+/**/ 0x3EF80024, 0x00360051,
+/**/ 0xBEF80012, 0x00000000,
+/**/ 0xBCF20014, 0x40184CEB,
+/**/ 0x3EF6001E, 0x40299839,
+/**/ 0xBEF6000F, 0x20000000,
+/**/ 0xBCEBBAC7, 0x434A1F5C,
+/**/ 0x3EF40019, 0x001F4027,
+/**/ 0xBEF4000C, 0x80000000,
+/**/ 0xBCE4D568, 0xDD68DD6A,
+/**/ 0x3EF20014, 0x4016C81A,
+/**/ 0xBEF2000A, 0x20000000,
+/**/ 0xBCDE6019, 0xA11710FC,
+/**/ 0x3EF00010, 0x00100010,
+/**/ 0xBEF00008, 0x00000000,
+/**/ 0xBCD55565, 0x5562222D,
+/**/ 0x3EEC0018, 0x80157013,
+/**/ 0xBEEC000C, 0x40000000,
+/**/ 0xBCCC9568, 0x176276C5,
+/**/ 0x3EE80012, 0x000D800A,
+/**/ 0xBEE80009, 0x00000000,
+/**/ 0xBCC2000A, 0x20061337,
+/**/ 0x3EE4000C, 0x8007D005,
+/**/ 0xBEE40006, 0x40000000,
+/**/ 0xBCB4D55F, 0x195A3758,
+/**/ 0x3EE00008, 0x00040002,
+/**/ 0xBEE00004, 0x00000000,
+/**/ 0xBCA5555D, 0x5558888A,
+/**/ 0x3ED80009, 0x00036001,
+/**/ 0xBED80004, 0x80000000,
+/**/ 0xBC920005, 0x100184CD,
+/**/ 0x3ED00004, 0x00010000,
+/**/ 0xBED00002, 0x00000000,
+/**/ 0xBC755559, 0x55562222,
+/**/ 0x3EC00002, 0x00004000,
+/**/ 0xBEC00001, 0x00000000,
+/**/ 0xBC455557, 0x55558889,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0xBEBFFFFC, 0x00008000,
+/**/ 0x3EBFFFFE, 0x00000000,
+/**/ 0x3C455553, 0x55558889,
+/**/ 0xBECFFFF8, 0x00020000,
+/**/ 0x3ECFFFFC, 0x00000000,
+/**/ 0x3C755551, 0x55562222,
+/**/ 0xBED7FFF7, 0x00035FFF,
+/**/ 0x3ED7FFFB, 0x80000000,
+/**/ 0x3C91FFFA, 0xF00184CC,
+/**/ 0xBEDFFFF0, 0x0007FFFC,
+/**/ 0x3EDFFFF8, 0x00000000,
+/**/ 0x3CA5554D, 0x55588887,
+/**/ 0xBEE3FFF3, 0x8007CFFB,
+/**/ 0x3EE3FFF9, 0xC0000000,
+/**/ 0x3CB4D54B, 0x915A3753,
+/**/ 0xBEE7FFEE, 0x000D7FF6,
+/**/ 0x3EE7FFF7, 0x00000000,
+/**/ 0x3CC1FFF5, 0xE006132F,
+/**/ 0xBEEBFFE7, 0x80156FED,
+/**/ 0x3EEBFFF3, 0xC0000000,
+/**/ 0x3CCC9542, 0x936276B2,
+/**/ 0xBEEFFFE0, 0x001FFFE0,
+/**/ 0x3EEFFFF0, 0x00000000,
+/**/ 0x3CD55545, 0x55622217,
+/**/ 0xBEF1FFEB, 0xC016C7E6,
+/**/ 0x3EF1FFF5, 0xE0000000,
+/**/ 0x3CDE5FE6, 0x5F1710D1,
+/**/ 0xBEF3FFE7, 0x001F3FD9,
+/**/ 0x3EF3FFF3, 0x80000000,
+/**/ 0x3CE4D541, 0xCD68DD41,
+/**/ 0xBEF5FFE1, 0xC02997C7,
+/**/ 0x3EF5FFF0, 0xE0000000,
+/**/ 0x3CEBBA8E, 0x124A1F13,
+/**/ 0xBEF7FFDC, 0x0035FFAF,
+/**/ 0x3EF7FFEE, 0x00000000,
+/**/ 0x3CF1FFEB, 0xC0184CAE,
+/**/ 0xBEF9FFD5, 0xC044A790,
+/**/ 0x3EF9FFEA, 0xE0000000,
+/**/ 0x3CF6E28E, 0xC68EECCD,
+/**/ 0xBEFBFFCF, 0x0055BF6A,
+/**/ 0x3EFBFFE7, 0x80000000,
+/**/ 0x3CFC952F, 0xD189DAA2,
+/**/ 0xBEFDFFC7, 0xC069773A,
+/**/ 0x3EFDFFE3, 0xE0000000,
+/**/ 0x3D0193E7, 0x480513F6,
+/**/ 0xBEFFFFC0, 0x007FFF00,
+/**/ 0x3EFFFFE0, 0x00000000,
+/**/ 0x3D055535, 0x55888833,
+/**/ 0xBF00FFDB, 0xE04CC35D,
+/**/ 0x3F00FFED, 0xF0000000,
+/**/ 0x3D099681, 0xE2CFFE66,
+/**/ 0xBF01FFD7, 0x805B1F33,
+/**/ 0x3F01FFEB, 0xC0000000,
+/**/ 0x3D0E5FCC, 0xBE5C42ED,
+/**/ 0xBF02FFD2, 0xE06B2B01,
+/**/ 0x3F02FFE9, 0x70000000,
+/**/ 0x3D11DC8A, 0xD9D71DD1,
+/**/ 0xBF03FFCE, 0x007CFEC8,
+/**/ 0x3F03FFE7, 0x00000000,
+/**/ 0x3D14D52E, 0x45A374B3,
+/**/ 0xBF04FFC8, 0xE090B284,
+/**/ 0x3F04FFE4, 0x70000000,
+/**/ 0x3D181DD0, 0x8553B4C7,
+/**/ 0xBF05FFC3, 0x80A65E36,
+/**/ 0x3F05FFE1, 0xC0000000,
+/**/ 0x3D1BBA71, 0x7A287BBE,
+/**/ 0xBF06FFBD, 0xE0BE19DD,
+/**/ 0x3F06FFDE, 0xF0000000,
+/**/ 0x3D1FAF11, 0x03E27702,
+/**/ 0xBF07FFB8, 0x00D7FD78,
+/**/ 0x3F07FFDC, 0x00000000,
+/**/ 0x3D21FFD7, 0x80613240,
+/**/ 0xBF08FFB1, 0xE0F42105,
+/**/ 0x3F08FFD8, 0xF0000000,
+/**/ 0x3D245825, 0xA6C489B3,
+/**/ 0xBF09FFAB, 0x81129C84,
+/**/ 0x3F09FFD5, 0xC0000000,
+/**/ 0x3D26E272, 0xE2BBB26F,
+/**/ 0xBF0AFFA4, 0xE13387F2,
+/**/ 0x3F0AFFD2, 0x70000000,
+/**/ 0x3D29A0BF, 0x21272669,
+/**/ 0xBF0BFF9E, 0x0156FB50,
+/**/ 0x3F0BFFCF, 0x00000000,
+/**/ 0x3D2C950A, 0x4E276957,
+/**/ 0xBF0CFF96, 0xE17D0E9B,
+/**/ 0x3F0CFFCB, 0x70000000,
+/**/ 0x3D2FC154, 0x551D090E,
+/**/ 0xBF0DFF8F, 0x81A5D9D2,
+/**/ 0x3F0DFFC7, 0xC0000000,
+/**/ 0x3D3193CE, 0x90544EF1,
+/**/ 0xBF0EFF87, 0xE1D174F4,
+/**/ 0x3F0EFFC3, 0xF0000000,
+/**/ 0x3D3364F2, 0x4D556583,
+/**/ 0xBF0FFF80, 0x01FFF800,
+/**/ 0x3F0FFFC0, 0x00000000,
+/**/ 0x3D355515, 0x56221F78,
+/**/ 0xBF107FBB, 0xF118BD7A,
+/**/ 0x3F107FDD, 0xF8000000,
+/**/ 0x3D376537, 0x9EEAD9D8,
+/**/ 0xBF10FFB7, 0xC1330AE7,
+/**/ 0x3F10FFDB, 0xE0000000,
+/**/ 0x3D399659, 0x1B7FF7AE,
+/**/ 0xBF117FB3, 0x714EF047,
+/**/ 0x3F117FD9, 0xB8000000,
+/**/ 0x3D3BE979, 0xBF51E233,
+/**/ 0xBF11FFAF, 0x016C7998,
+/**/ 0x3F11FFD7, 0x80000000,
+/**/ 0x3D3E5F99, 0x7D7108FF,
+/**/ 0xBF127FAA, 0x718BB2DA,
+/**/ 0x3F127FD5, 0x39000000,
+/**/ 0xBD3F0647, 0xB7721DC6,
+/**/ 0xBF12FFA5, 0xC1ACA80C,
+/**/ 0x3F12FFD2, 0xE1000000,
+/**/ 0xBD3C4729, 0xED071532,
+/**/ 0xBF137FA0, 0xF1CF652D,
+/**/ 0x3F137FD0, 0x79000000,
+/**/ 0xBD39620D, 0x315D596D,
+/**/ 0xBF13FF9C, 0x01F3F63C,
+/**/ 0x3F13FFCE, 0x01000000,
+/**/ 0xBD3655F1, 0x92E45F81,
+/**/ 0xBF147F96, 0xF21A6739,
+/**/ 0x3F147FCB, 0x79000000,
+/**/ 0xBD3321D7, 0x206B9526,
+/**/ 0xBF14FF91, 0xC242C421,
+/**/ 0x3F14FFC8, 0xE1000000,
+/**/ 0xBD2F897B, 0xD244C12A,
+/**/ 0xBF157F8C, 0x726D18F6,
+/**/ 0x3F157FC6, 0x39000000,
+/**/ 0xBD287B4B, 0xF93040AE,
+/**/ 0xBF15FF87, 0x029971B4,
+/**/ 0x3F15FFC3, 0x81000000,
+/**/ 0xBD21171E, 0xD578562C,
+/**/ 0xBF167F81, 0x72C7DA5C,
+/**/ 0x3F167FC0, 0xB9000000,
+/**/ 0xBD12B5E9, 0x0F773DB4,
+/**/ 0xBF16FF7B, 0xC2F85EEC,
+/**/ 0x3F16FFBD, 0xE1000000,
+/**/ 0xBCE44CD3, 0x158A76C2,
+/**/ 0xBF177F75, 0xF32B0B63,
+/**/ 0x3F177FBA, 0xF9000000,
+/**/ 0x3D0CB55C, 0x2E48511B,
+/**/ 0xBF17FF70, 0x035FEBC0,
+/**/ 0x3F17FFB8, 0x01000000,
+/**/ 0x3D1FFAF0, 0x184C534F,
+/**/ 0xBF187F69, 0xF3970C03,
+/**/ 0x3F187FB4, 0xF9000000,
+/**/ 0x3D292D95, 0xACC53FBE,
+/**/ 0xBF18FF63, 0xC3D07829,
+/**/ 0x3F18FFB1, 0xE1000000,
+/**/ 0x3D315FD7, 0xE48887C8,
+/**/ 0xBF197F5D, 0x740C3C32,
+/**/ 0x3F197FAE, 0xB9000000,
+/**/ 0x3D365AE3, 0x1DF5B242,
+/**/ 0xBF19FF57, 0x044A641C,
+/**/ 0x3F19FFAB, 0x81000000,
+/**/ 0x3D3B88EC, 0x6FBB0E5F,
+/**/ 0xBF1A7F50, 0x748AFBE7,
+/**/ 0x3F1A7FA8, 0x3A000000,
+/**/ 0xBD3F150C, 0x39766B40,
+/**/ 0xBF1AFF49, 0xC4CE0F91,
+/**/ 0x3F1AFFA4, 0xE2000000,
+/**/ 0xBD397E06, 0xF14DB839,
+/**/ 0xBF1B7F42, 0xF513AB19,
+/**/ 0x3F1B7FA1, 0x7A000000,
+/**/ 0xBD33B103, 0xCBD9CC3D,
+/**/ 0xBF1BFF3C, 0x055BDA7D,
+/**/ 0x3F1BFF9E, 0x02000000,
+/**/ 0xBD2B5A05, 0xBB1321B5,
+/**/ 0xBF1C7F34, 0xF5A6A9BD,
+/**/ 0x3F1C7F9A, 0x7A000000,
+/**/ 0xBD1DC410, 0xECAF9551,
+/**/ 0xBF1CFF2D, 0xC5F424D6,
+/**/ 0x3F1CFF96, 0xE2000000,
+/**/ 0xBCEF80FF, 0x3DF3CD68,
+/**/ 0xBF1D7F26, 0x764457C8,
+/**/ 0x3F1D7F93, 0x3A000000,
+/**/ 0x3D16CBC7, 0x4271E737,
+/**/ 0xBF1DFF1F, 0x06974E91,
+/**/ 0x3F1DFF8F, 0x82000000,
+/**/ 0x3D2939D2, 0x1D134848,
+/**/ 0xBF1E7F17, 0x76ED1530,
+/**/ 0x3F1E7F8B, 0xBA000000,
+/**/ 0x3D33C2DD, 0xA9892C73,
+/**/ 0xBF1EFF0F, 0xC745B7A4,
+/**/ 0x3F1EFF87, 0xE2000000,
+/**/ 0x3D3B25CF, 0x8AEC69D5,
+/**/ 0xBF1F7F07, 0xF7A141EA,
+/**/ 0x3F1F7F83, 0xFB000000,
+/**/ 0xBD3D3941, 0x645B412A,
+/**/ 0xBF1FFF00, 0x07FFC002,
+/**/ 0x3F1FFF80, 0x03000000,
+/**/ 0xBD355955, 0x3BBC6662,
+/**/ 0xBF203F7B, 0xFC309EF5,
+/**/ 0x3F203FBD, 0xFD800000,
+/**/ 0xBD2A72D8, 0x260B17B3,
+/**/ 0xBF207F77, 0xE462E3D0,
+/**/ 0x3F207FBB, 0xF1800000,
+/**/ 0xBD136218, 0x0994AE68,
+/**/ 0xBF20BF73, 0xBC96B492,
+/**/ 0x3F20BFB9, 0xDD800000,
+/**/ 0x3D0E52E6, 0xECB2641F,
+/**/ 0xBF20FF6F, 0x84CC1739,
+/**/ 0x3F20FFB7, 0xC1800000,
+/**/ 0x3D296078, 0xE7FCF60B,
+/**/ 0xBF213F6B, 0x3D0311C6,
+/**/ 0x3F213FB5, 0x9D800000,
+/**/ 0x3D35DA18, 0xA7850AFF,
+/**/ 0xBF217F66, 0xE53BAA36,
+/**/ 0x3F217FB3, 0x71800000,
+/**/ 0x3D3F48F1, 0x5E7BB444,
+/**/ 0xBF21BF62, 0x7D75E68A,
+/**/ 0x3F21BFB1, 0x3E000000,
+/**/ 0xBD370239, 0x812BC469,
+/**/ 0xBF21FF5E, 0x05B1CCC0,
+/**/ 0x3F21FFAF, 0x02000000,
+/**/ 0xBD2A0CD0, 0x23BF1A4D,
+/**/ 0xBF223F59, 0x7DEF62D8,
+/**/ 0x3F223FAC, 0xBE000000,
+/**/ 0xBD0614D3, 0x736E3623,
+/**/ 0xBF227F54, 0xE62EAED0,
+/**/ 0x3F227FAA, 0x72000000,
+/**/ 0x3D1F28BD, 0x37EDEDB0,
+/**/ 0xBF22BF50, 0x3E6FB6A9,
+/**/ 0x3F22BFA8, 0x1E000000,
+/**/ 0x3D32A0F5, 0x07CE33C8,
+/**/ 0xBF22FF4B, 0x86B28060,
+/**/ 0x3F22FFA5, 0xC2000000,
+/**/ 0x3D3DC2B6, 0xA31C6A8D,
+/**/ 0xBF233F46, 0xBEF711F6,
+/**/ 0x3F233FA3, 0x5E800000,
+/**/ 0xBD36CF8B, 0xFC67C9FB,
+/**/ 0xBF237F41, 0xE73D7169,
+/**/ 0x3F237FA0, 0xF2800000,
+/**/ 0xBD2629A5, 0xE6D88A89,
+/**/ 0xBF23BF3C, 0xFF85A4B8,
+/**/ 0x3F23BF9E, 0x7E800000,
+/**/ 0x3CEE7C34, 0x202574EC,
+/**/ 0xBF23FF38, 0x07CFB1E3,
+/**/ 0x3F23FF9C, 0x02800000,
+/**/ 0x3D2A9723, 0x46E594C1,
+/**/ 0xBF243F33, 0x001B9EE8,
+/**/ 0x3F243F99, 0x7E800000,
+/**/ 0x3D39F33C, 0xF61AE74C,
+/**/ 0xBF247F2D, 0xE86971C7,
+/**/ 0x3F247F96, 0xF3000000,
+/**/ 0xBD39141C, 0x85341E31,
+/**/ 0xBF24BF28, 0xC0B9307F,
+/**/ 0x3F24BF94, 0x5F000000,
+/**/ 0xBD2792F5, 0xDA0FAF09,
+/**/ 0xBF24FF23, 0x890AE10E,
+/**/ 0x3F24FF91, 0xC3000000,
+/**/ 0x3CFD4219, 0xFB239430,
+/**/ 0xBF253F1E, 0x415E8974,
+/**/ 0x3F253F8F, 0x1F000000,
+/**/ 0x3D2F8B72, 0x0359434A,
+/**/ 0xBF257F18, 0xE9B42FAF,
+/**/ 0x3F257F8C, 0x73000000,
+/**/ 0x3D3E0C4B, 0x1939FEDF,
+/**/ 0xBF25BF13, 0x820BD9BF,
+/**/ 0x3F25BF89, 0xBF800000,
+/**/ 0xBD335728, 0x39B301E2,
+/**/ 0xBF25FF0E, 0x0A658DA3,
+/**/ 0x3F25FF87, 0x03800000,
+/**/ 0xBD118E84, 0x5E1E8D4F,
+/**/ 0xBF263F08, 0x82C15159,
+/**/ 0x3F263F84, 0x3F800000,
+/**/ 0x3D25CFC0, 0xBDDDD045,
+/**/ 0xBF267F02, 0xEB1F2AE1,
+/**/ 0x3F267F81, 0x73800000,
+/**/ 0x3D3A8C5C, 0x08837E99,
+/**/ 0xBF26BEFD, 0x437F203A,
+/**/ 0x3F26BF7E, 0xA0000000,
+/**/ 0xBD35752E, 0x3C56F12D,
+/**/ 0xBF26FEF7, 0x8BE13762,
+/**/ 0x3F26FF7B, 0xC4000000,
+/**/ 0xBD146EFA, 0x46359E28,
+/**/ 0xBF273EF1, 0xC4457659,
+/**/ 0x3F273F78, 0xE0000000,
+/**/ 0x3D273355, 0xCD265865,
+/**/ 0xBF277EEB, 0xECABE31C,
+/**/ 0x3F277F75, 0xF4000000,
+/**/ 0x3D3CAC0E, 0x095DEBF8,
+/**/ 0xBF27BEE6, 0x051483AC,
+/**/ 0x3F27BF73, 0x00800000,
+/**/ 0xBD31E395, 0x4C39F4DB,
+/**/ 0xBF27FEE0, 0x0D7F5E08,
+/**/ 0x3F27FF70, 0x04800000,
+/**/ 0xBCB43F3D, 0xA1314B81,
+/**/ 0xBF283EDA, 0x05EC782D,
+/**/ 0x3F283F6D, 0x00800000,
+/**/ 0x3D321B10, 0x115B8D70,
+/**/ 0xBF287ED3, 0xEE5BD81B,
+/**/ 0x3F287F69, 0xF5000000,
+/**/ 0xBD3B54A7, 0x83704FE1,
+/**/ 0xBF28BECD, 0xC6CD83D1,
+/**/ 0x3F28BF66, 0xE1000000,
+/**/ 0xBD20C4CC, 0x41229C91,
+/**/ 0xBF28FEC7, 0x8F41814D,
+/**/ 0x3F28FF63, 0xC5000000,
+/**/ 0x3D25E5A8, 0x2A183F17,
+/**/ 0xBF293EC1, 0x47B7D68F,
+/**/ 0x3F293F60, 0xA1000000,
+/**/ 0x3D3EAC06, 0xF81B997D,
+/**/ 0xBF297EBA, 0xF0308995,
+/**/ 0x3F297F5D, 0x75800000,
+/**/ 0xBD2A6B9B, 0x3A1E5BAD,
+/**/ 0xBF29BEB4, 0x88ABA05E,
+/**/ 0x3F29BF5A, 0x41800000,
+/**/ 0x3D1D3958, 0xBDFE3C77,
+/**/ 0xBF29FEAE, 0x112920E9,
+/**/ 0x3F29FF57, 0x05800000,
+/**/ 0x3D3C3972, 0x375BA904,
+/**/ 0xBF2A3EA7, 0x89A91135,
+/**/ 0x3F2A3F53, 0xC2000000,
+/**/ 0xBD2CE6F3, 0x588DE85B,
+/**/ 0xBF2A7EA0, 0xF22B7740,
+/**/ 0x3F2A7F50, 0x76000000,
+/**/ 0x3D1D2249, 0x75AEDBFD,
+/**/ 0xBF2ABE9A, 0x4AB05909,
+/**/ 0x3F2ABF4D, 0x22000000,
+/**/ 0x3D3D6E96, 0x2CE7BDAC,
+/**/ 0xBF2AFE93, 0x9337BC90,
+/**/ 0x3F2AFF49, 0xC6800000,
+/**/ 0xBD2800DC, 0xCB7D724C,
+/**/ 0xBF2B3E8C, 0xCBC1A7D1,
+/**/ 0x3F2B3F46, 0x62800000,
+/**/ 0x3D25F908, 0xFA591B29,
+/**/ 0xBF2B7E85, 0xF44E20CE,
+/**/ 0x3F2B7F42, 0xF7000000,
+/**/ 0xBD3D9991, 0x53021ED8,
+/**/ 0xBF2BBE7F, 0x0CDD2D83,
+/**/ 0x3F2BBF3F, 0x83000000,
+/**/ 0xBD1706BF, 0xFD596AD6,
+/**/ 0xBF2BFE78, 0x156ED3F0,
+/**/ 0x3F2BFF3C, 0x07000000,
+/**/ 0x3D328528, 0x4EC45253,
+/**/ 0xBF2C3E71, 0x0E031A14,
+/**/ 0x3F2C3F38, 0x83800000,
+/**/ 0xBD34C408, 0x927D8A9E,
+/**/ 0xBF2C7E69, 0xF69A05ED,
+/**/ 0x3F2C7F34, 0xF7800000,
+/**/ 0x3D118EF4, 0xCAE2C25F,
+/**/ 0xBF2CBE62, 0xCF339D7A,
+/**/ 0x3F2CBF31, 0x63800000,
+/**/ 0x3D3DFD79, 0x73DBBB41,
+/**/ 0xBF2CFE5B, 0x97CFE6B9,
+/**/ 0x3F2CFF2D, 0xC8000000,
+/**/ 0xBD1FD74F, 0xE7FE77E6,
+/**/ 0xBF2D3E54, 0x506EE7AA,
+/**/ 0x3F2D3F2A, 0x24000000,
+/**/ 0x3D328AD4, 0xBDDB871F,
+/**/ 0xBF2D7E4C, 0xF910A64A,
+/**/ 0x3F2D7F26, 0x78800000,
+/**/ 0xBD327F8C, 0x903DDD81,
+/**/ 0xBF2DBE45, 0x91B52899,
+/**/ 0x3F2DBF22, 0xC4800000,
+/**/ 0x3D21D80F, 0xDF52840A,
+/**/ 0xBF2DFE3E, 0x1A5C7495,
+/**/ 0x3F2DFF1F, 0x09000000,
+/**/ 0xBD3B316D, 0xEED9F651,
+/**/ 0xBF2E3E36, 0x9306903D,
+/**/ 0x3F2E3F1B, 0x45000000,
+/**/ 0x3CF2911A, 0x76DB3C6B,
+/**/ 0xBF2E7E2E, 0xFBB3818F,
+/**/ 0x3F2E7F17, 0x79000000,
+/**/ 0x3D3DFC86, 0x85559113,
+/**/ 0xBF2EBE27, 0x54634E89,
+/**/ 0x3F2EBF13, 0xA5800000,
+/**/ 0xBD12D83E, 0x0AB3DBE7,
+/**/ 0xBF2EFE1F, 0x9D15FD2B,
+/**/ 0x3F2EFF0F, 0xC9800000,
+/**/ 0x3D39124F, 0x617B99F1,
+/**/ 0xBF2F3E17, 0xD5CB9373,
+/**/ 0x3F2F3F0B, 0xE6000000,
+/**/ 0xBD2152B9, 0xF8F64DA1,
+/**/ 0xBF2F7E0F, 0xFE841760,
+/**/ 0x3F2F7F07, 0xFA000000,
+/**/ 0x3D3617EB, 0x34C4735B,
+/**/ 0xBF2FBE08, 0x173F8EEF,
+/**/ 0x3F2FBF04, 0x06800000,
+/**/ 0xBD2551B0, 0x739FA712,
+/**/ 0xBF2FFE00, 0x1FFE0020,
+/**/ 0x3F2FFF00, 0x0A800000,
+/**/ 0x3D351558, 0x885DE027,
+/**/ 0xBF301EFC, 0x0C5FB879,
+/**/ 0x3F301F7E, 0x03800000,
+/**/ 0xBD255905, 0x68F8FC50,
+/**/ 0xBF303EF8, 0x00C1F3B0,
+/**/ 0x3F303F7B, 0xFD800000,
+/**/ 0x3D361295, 0xDF771CF4,
+/**/ 0xBF305EF3, 0xED25B4B7,
+/**/ 0x3F305F79, 0xF3C00000,
+/**/ 0xBD2158BB, 0xD8A255DB,
+/**/ 0xBF307EEF, 0xD18AFE8B,
+/**/ 0x3F307F77, 0xE5C00000,
+/**/ 0x3D3917A1, 0xB740E625,
+/**/ 0xBF309EEB, 0xADF1D42C,
+/**/ 0x3F309F75, 0xD4000000,
+/**/ 0xBD1281AD, 0x9C716D59,
+/**/ 0xBF30BEE7, 0x825A3899,
+/**/ 0x3F30BF73, 0xBE000000,
+/**/ 0x3D3E2C7A, 0x86ED7DDC,
+/**/ 0xBF30DEE3, 0x4EC42ED1,
+/**/ 0x3F30DF71, 0xA4400000,
+/**/ 0x3CF7F534, 0xF54F7E28,
+/**/ 0xBF30FEDF, 0x132FB9D5,
+/**/ 0x3F30FF6F, 0x86800000,
+/**/ 0xBD3AA6E1, 0x404F4E01,
+/**/ 0xBF311EDA, 0xCF9CDCA2,
+/**/ 0x3F311F6D, 0x64800000,
+/**/ 0x3D2375B9, 0x4A6EC981,
+/**/ 0xBF313ED6, 0x840B9A38,
+/**/ 0x3F313F6B, 0x3EC00000,
+/**/ 0xBD315A73, 0x33401DD0,
+/**/ 0xBF315ED2, 0x307BF596,
+/**/ 0x3F315F69, 0x14C00000,
+/**/ 0x3D341A2F, 0x02C11605,
+/**/ 0xBF317ECD, 0xD4EDF1BC,
+/**/ 0x3F317F66, 0xE7000000,
+/**/ 0xBD1798F3, 0xB2B7E8C5,
+/**/ 0xBF319EC9, 0x716191A8,
+/**/ 0x3F319F64, 0xB5400000,
+/**/ 0xBD3F5AB7, 0x35D62ED5,
+/**/ 0xBF31BEC5, 0x05D6D85A,
+/**/ 0x3F31BF62, 0x7F400000,
+/**/ 0x3D1EF6FF, 0xCA7EC7CD,
+/**/ 0xBF31DEC0, 0x924DC8D2,
+/**/ 0x3F31DF60, 0x45800000,
+/**/ 0xBD309BD7, 0xA8550396,
+/**/ 0xBF31FEBC, 0x16C6660D,
+/**/ 0x3F31FF5E, 0x07800000,
+/**/ 0x3D379981, 0xC3E31F70,
+/**/ 0xBF321EB7, 0x9340B30B,
+/**/ 0x3F321F5B, 0xC5C00000,
+/**/ 0x3CD7B300, 0x5FE92B94,
+/**/ 0xBF323EB3, 0x07BCB2CC,
+/**/ 0x3F323F59, 0x80000000,
+/**/ 0xBD364AF9, 0x25A7CF34,
+/**/ 0xBF325EAE, 0x743A684F,
+/**/ 0x3F325F57, 0x36000000,
+/**/ 0x3D339D32, 0x17E48399,
+/**/ 0xBF327EA9, 0xD8B9D692,
+/**/ 0x3F327F54, 0xE8400000,
+/**/ 0xBCFE7B27, 0xCC387BD1,
+/**/ 0xBF329EA5, 0x353B0095,
+/**/ 0x3F329F52, 0x96800000,
+/**/ 0xBD36D8A7, 0x1AE7FA80,
+/**/ 0xBF32BEA0, 0x89BDE957,
+/**/ 0x3F32BF50, 0x40800000,
+/**/ 0x3D34CB54, 0x05CF3DC3,
+/**/ 0xBF32DE9B, 0xD64293D7,
+/**/ 0x3F32DF4D, 0xE6C00000,
+/**/ 0x3CF053EA, 0xD5A4F691,
+/**/ 0xBF32FE97, 0x1AC90315,
+/**/ 0x3F32FF4B, 0x89000000,
+/**/ 0xBD3229E7, 0x5CAE7B16,
+/**/ 0xBF331E92, 0x57513A0F,
+/**/ 0x3F331F49, 0x27000000,
+/**/ 0x3D3B3EE1, 0xAEED4509,
+/**/ 0xBF333E8D, 0x8BDB3BC4,
+/**/ 0x3F333F46, 0xC1400000,
+/**/ 0x3D228133, 0x2E0C2605,
+/**/ 0xBF335E88, 0xB8670B34,
+/**/ 0x3F335F44, 0x57800000,
+/**/ 0xBD20477F, 0xBBD6E280,
+/**/ 0xBF337E83, 0xDCF4AB5D,
+/**/ 0x3F337F41, 0xE9C00000,
+/**/ 0xBD38ED2A, 0xE9CE8AFC,
+/**/ 0xBF339E7E, 0xF9841F3F,
+/**/ 0x3F339F3F, 0x77C00000,
+/**/ 0x3D36E558, 0x39159F9B,
+/**/ 0xBF33BE7A, 0x0E1569D9,
+/**/ 0x3F33BF3D, 0x02000000,
+/**/ 0x3D1D5325, 0x40681634,
+/**/ 0xBF33DE75, 0x1AA88E2A,
+/**/ 0x3F33DF3A, 0x88400000,
+/**/ 0xBD1E775F, 0x7F2112CE,
+/**/ 0xBF33FE70, 0x1F3D8F31,
+/**/ 0x3F33FF38, 0x0A800000,
+/**/ 0xBD35F18B, 0x91F80D1B,
+/**/ 0xBF341E6B, 0x1BD46FED,
+/**/ 0x3F341F35, 0x88800000,
+/**/ 0x3D3C5AAD, 0xFDC3FC2F,
+/**/ 0xBF343E66, 0x106D335D,
+/**/ 0x3F343F33, 0x02C00000,
+/**/ 0x3D2E8FA9, 0x268A89F1,
+/**/ 0xBF345E60, 0xFD07DC80,
+/**/ 0x3F345F30, 0x79000000,
+/**/ 0x3D06B73F, 0x902AC9EE,
+/**/ 0xBF347E5B, 0xE1A46E55,
+/**/ 0x3F347F2D, 0xEB400000,
+/**/ 0xBD21EE30, 0x45C43959,
+/**/ 0xBF349E56, 0xBE42EBDC,
+/**/ 0x3F349F2B, 0x59800000,
+/**/ 0xBD34212B, 0xE8B753E8,
+/**/ 0xBF34BE51, 0x92E35813,
+/**/ 0x3F34BF28, 0xC3C00000,
+/**/ 0xBD3EA653, 0x9D2064DB,
+/**/ 0xBF34DE4C, 0x5F85B5F9,
+/**/ 0x3F34DF26, 0x29C00000,
+/**/ 0x3D377A70, 0x81DCB6FB,
+/**/ 0xBF34FE47, 0x242A088D,
+/**/ 0x3F34FF23, 0x8C000000,
+/**/ 0x3D2C8440, 0x6BB44A6D,
+/**/ 0xBF351E41, 0xE0D052CF,
+/**/ 0x3F351F20, 0xEA400000,
+/**/ 0x3D16C6ED, 0x0048AAF8,
+/**/ 0xBF353E3C, 0x957897BD,
+/**/ 0x3F353F1E, 0x44800000,
+/**/ 0xBD01ADF4, 0xF506A07E,
+/**/ 0xBF355E37, 0x4222DA57,
+/**/ 0x3F355F1B, 0x9AC00000,
+/**/ 0xBD22E69B, 0x4B88A655,
+/**/ 0xBF357E31, 0xE6CF1D9B,
+/**/ 0x3F357F18, 0xED000000,
+/**/ 0xBD3005F2, 0x153DAEB0,
+/**/ 0xBF359E2C, 0x837D6488,
+/**/ 0x3F359F16, 0x3B400000,
+/**/ 0xBD35ECAC, 0x2D5222B4,
+/**/ 0xBF35BE27, 0x182DB21E,
+/**/ 0x3F35BF13, 0x85800000,
+/**/ 0xBD3B267C, 0x2EA6CB14,
+/**/ 0xBF35DE21, 0xA4E0095B,
+/**/ 0x3F35DF10, 0xCBC00000,
+/**/ 0xBD3FB262, 0x5A40A340,
+/**/ 0xBF35FE1C, 0x29946D3F,
+/**/ 0x3F35FF0E, 0x0DC00000,
+/**/ 0x3D3C70A1, 0x0E7B79ED,
+/**/ 0xBF361E16, 0xA64AE0C7,
+/**/ 0x3F361F0B, 0x4C000000,
+/**/ 0x3D39438D, 0xC9C8D263,
+/**/ 0xBF363E11, 0x1B0366F4,
+/**/ 0x3F363F08, 0x86400000,
+/**/ 0x3D36C763, 0x9582CD0C,
+/**/ 0xBF365E0B, 0x87BE02C5,
+/**/ 0x3F365F05, 0xBC800000,
+/**/ 0x3D34FD22, 0x2F24F1F9,
+/**/ 0xBF367E05, 0xEC7AB737,
+/**/ 0x3F367F02, 0xEEC00000,
+/**/ 0x3D33E5C9, 0x53CAEA94,
+/**/ 0xBF369E00, 0x4939874A,
+/**/ 0x3F369F00, 0x1D000000,
+/**/ 0x3D338258, 0xC03081D0,
+/**/ 0xBF36BDFA, 0x9DFA75FE,
+/**/ 0x3F36BEFD, 0x47400000,
+/**/ 0x3D33D3D0, 0x30B1A458,
+/**/ 0xBF36DDF4, 0xEABD8651,
+/**/ 0x3F36DEFA, 0x6D800000,
+/**/ 0x3D34DB2F, 0x614A60C1,
+/**/ 0xBF36FDEF, 0x2F82BB41,
+/**/ 0x3F36FEF7, 0x8FC00000,
+/**/ 0x3D369976, 0x0D96E7B8,
+/**/ 0xBF371DE9, 0x6C4A17CF,
+/**/ 0x3F371EF4, 0xAE000000,
+/**/ 0x3D390FA3, 0xF0D38C30,
+/**/ 0xBF373DE3, 0xA1139EF8,
+/**/ 0x3F373EF1, 0xC8400000,
+/**/ 0x3D3C3EB8, 0xC5DCC397,
+/**/ 0xBF375DDD, 0xCDDF53BC,
+/**/ 0x3F375EEE, 0xDEC00000,
+/**/ 0xBD3FD84B, 0xB8D0D9FD,
+/**/ 0xBF377DD7, 0xF2AD3919,
+/**/ 0x3F377EEB, 0xF1000000,
+/**/ 0xBD3B3469, 0xD11891A0,
+/**/ 0xBF379DD2, 0x0F7D520F,
+/**/ 0x3F379EE8, 0xFF400000,
+/**/ 0xBD35D4A1, 0xC93D855B,
+/**/ 0xBF37BDCC, 0x244FA19D,
+/**/ 0x3F37BEE6, 0x09800000,
+/**/ 0xBD2F6FE7, 0xCFC56806,
+/**/ 0xBF37DDC6, 0x31242AC1,
+/**/ 0x3F37DEE3, 0x0FC00000,
+/**/ 0xBD21BAC0, 0xE815F202,
+/**/ 0xBF37FDC0, 0x35FAF079,
+/**/ 0x3F37FEE0, 0x12000000,
+/**/ 0xBCF43E7B, 0x5190C28B,
+/**/ 0xBF381DBA, 0x32D3F5C6,
+/**/ 0x3F381EDD, 0x10400000,
+/**/ 0x3D1C55D8, 0x34C1F9E9,
+/**/ 0xBF383DB4, 0x27AF3DA6,
+/**/ 0x3F383EDA, 0x0A800000,
+/**/ 0x3D302FB8, 0x8AAF36D4,
+/**/ 0xBF385DAE, 0x148CCB18,
+/**/ 0x3F385ED7, 0x00C00000,
+/**/ 0x3D3A0BDF, 0x7AE0D0F8,
+/**/ 0xBF387DA7, 0xF96CA11B,
+/**/ 0x3F387ED3, 0xF3400000,
+/**/ 0xBD3B5515, 0x6B1CDAAF,
+/**/ 0xBF389DA1, 0xD64EC2AD,
+/**/ 0x3F389ED0, 0xE1800000,
+/**/ 0xBD2FE44C, 0xE1179E5E,
+/**/ 0xBF38BD9B, 0xAB3332CD,
+/**/ 0x3F38BECD, 0xCBC00000,
+/**/ 0xBD0E529E, 0xF86F56EC,
+/**/ 0xBF38DD95, 0x7819F47A,
+/**/ 0x3F38DECA, 0xB2000000,
+/**/ 0x3D2246C3, 0xFEB631AB,
+/**/ 0xBF38FD8F, 0x3D030AB4,
+/**/ 0x3F38FEC7, 0x94400000,
+/**/ 0x3D36D7FA, 0xE04DA791,
+/**/ 0xBF391D88, 0xF9EE7878,
+/**/ 0x3F391EC4, 0x72C00000,
+/**/ 0xBD3AAB89, 0x86F7ADBB,
+/**/ 0xBF393D82, 0xAEDC40C7,
+/**/ 0x3F393EC1, 0x4D000000,
+/**/ 0xBD26CC57, 0x032C6155,
+/**/ 0xBF395D7C, 0x5BCC669D,
+/**/ 0x3F395EBE, 0x23400000,
+/**/ 0x3D12A452, 0x93C3EB3D,
+/**/ 0xBF397D76, 0x00BEECFB,
+/**/ 0x3F397EBA, 0xF5800000,
+/**/ 0x3D358336, 0xA0BCD695,
+/**/ 0xBF399D6F, 0x9DB3D6E0,
+/**/ 0x3F399EB7, 0xC4000000,
+/**/ 0xBD38D6C5, 0xDA737570,
+/**/ 0xBF39BD69, 0x32AB2749,
+/**/ 0x3F39BEB4, 0x8E400000,
+/**/ 0xBD198F84, 0x65026C7D,
+/**/ 0xBF39DD62, 0xBFA4E136,
+/**/ 0x3F39DEB1, 0x54800000,
+/**/ 0x3D29B9C9, 0x2EA9B41A,
+/**/ 0xBF39FD5C, 0x44A107A5,
+/**/ 0x3F39FEAE, 0x17000000,
+/**/ 0xBD3F1375, 0x16137ACF,
+/**/ 0xBF3A1D55, 0xC19F9D96,
+/**/ 0x3F3A1EAA, 0xD5400000,
+/**/ 0xBD2467DC, 0xDE73AFA0,
+/**/ 0xBF3A3D4F, 0x36A0A607,
+/**/ 0x3F3A3EA7, 0x8F800000,
+/**/ 0x3D26F8F0, 0x7B8357C6,
+/**/ 0xBF3A5D48, 0xA3A423F7,
+/**/ 0x3F3A5EA4, 0x46000000,
+/**/ 0xBD3E0141, 0x5DA0DFB7,
+/**/ 0xBF3A7D42, 0x08AA1A64,
+/**/ 0x3F3A7EA0, 0xF8400000,
+/**/ 0xBD1AB06E, 0x41050D29,
+/**/ 0xBF3A9D3B, 0x65B28C4E,
+/**/ 0x3F3A9E9D, 0xA6800000,
+/**/ 0x3D317CE9, 0x56A0E005,
+/**/ 0xBF3ABD34, 0xBABD7CB3,
+/**/ 0x3F3ABE9A, 0x51000000,
+/**/ 0xBD358532, 0xF899EF39,
+/**/ 0xBF3ADD2E, 0x07CAEE92,
+/**/ 0x3F3ADE96, 0xF7400000,
+/**/ 0x3D113A3C, 0xC83BF5C2,
+/**/ 0xBF3AFD27, 0x4CDAE4EA,
+/**/ 0x3F3AFE93, 0x99800000,
+/**/ 0x3D3EF92F, 0x863C7C8E,
+/**/ 0xBF3B1D20, 0x89ED62B9,
+/**/ 0x3F3B1E90, 0x38000000,
+/**/ 0xBD161149, 0x3341CC3C,
+/**/ 0xBF3B3D19, 0xBF026AFE,
+/**/ 0x3F3B3E8C, 0xD2400000,
+/**/ 0x3D36D709, 0x67C955DF,
+/**/ 0xBF3B5D12, 0xEC1A00B8,
+/**/ 0x3F3B5E89, 0x68C00000,
+/**/ 0xBD27E77B, 0x5AE9B17A,
+/**/ 0xBF3B7D0C, 0x113426E6,
+/**/ 0x3F3B7E85, 0xFB000000,
+/**/ 0x3D321C58, 0x219679DE,
+/**/ 0xBF3B9D05, 0x2E50E086,
+/**/ 0x3F3B9E82, 0x89800000,
+/**/ 0xBD2DEF6A, 0xFAA62113,
+/**/ 0xBF3BBCFE, 0x43703097,
+/**/ 0x3F3BBE7F, 0x13C00000,
+/**/ 0x3D30D119, 0x23305306,
+/**/ 0xBF3BDCF7, 0x50921A17,
+/**/ 0x3F3BDE7B, 0x9A400000,
+/**/ 0xBD2D1078, 0x9FBACE27,
+/**/ 0xBF3BFCF0, 0x55B6A006,
+/**/ 0x3F3BFE78, 0x1C800000,
+/**/ 0x3D32FD49, 0xD625DF1E,
+/**/ 0xBF3C1CE9, 0x52DDC563,
+/**/ 0x3F3C1E74, 0x9B000000,
+/**/ 0xBD253AA9, 0x7D07255B,
+/**/ 0xBF3C3CE2, 0x48078D2B,
+/**/ 0x3F3C3E71, 0x15400000,
+/**/ 0x3D38A8E7, 0x9E08B538,
+/**/ 0xBF3C5CDB, 0x3533FA5D,
+/**/ 0x3F3C5E6D, 0x8BC00000,
+/**/ 0xBD09780B, 0x45956AFC,
+/**/ 0xBF3C7CD4, 0x1A630FF9,
+/**/ 0x3F3C7E69, 0xFE400000,
+/**/ 0xBD3E2410, 0x2792F44E,
+/**/ 0xBF3C9CCC, 0xF794D0FC,
+/**/ 0x3F3C9E66, 0x6C800000,
+/**/ 0x3D1F2AEC, 0x30AB4456,
+/**/ 0xBF3CBCC5, 0xCCC94066,
+/**/ 0x3F3CBE62, 0xD7000000,
+/**/ 0xBD3161A0, 0x231641D5,
+/**/ 0xBF3CDCBE, 0x9A006135,
+/**/ 0x3F3CDE5F, 0x3D400000,
+/**/ 0x3D3657DD, 0xF4AD1934,
+/**/ 0xBF3CFCB7, 0x5F3A3668,
+/**/ 0x3F3CFE5B, 0x9FC00000,
+/**/ 0xBCF07CB0, 0x2E7AC798,
+/**/ 0xBF3D1CB0, 0x1C76C2FD,
+/**/ 0x3F3D1E57, 0xFE400000,
+/**/ 0xBD377F9B, 0x6090F643,
+/**/ 0xBF3D3CA8, 0xD1B609F3,
+/**/ 0x3F3D3E54, 0x58800000,
+/**/ 0x3D32F16C, 0x849503E6,
+/**/ 0xBF3D5CA1, 0x7EF80E49,
+/**/ 0x3F3D5E50, 0xAF000000,
+/**/ 0xBCFB3B3A, 0xAF1CA4EA,
+/**/ 0xBF3D7C9A, 0x243CD2FE,
+/**/ 0x3F3D7E4D, 0x01800000,
+/**/ 0xBD356DFC, 0x4701415B,
+/**/ 0xBF3D9C92, 0xC1845B0F,
+/**/ 0x3F3D9E49, 0x4FC00000,
+/**/ 0x3D37C392, 0x582AEA48,
+/**/ 0xBF3DBC8B, 0x56CEA97C,
+/**/ 0x3F3DBE45, 0x9A400000,
+/**/ 0x3D1787DF, 0x67DCC15E,
+/**/ 0xBF3DDC83, 0xE41BC143,
+/**/ 0x3F3DDE41, 0xE0C00000,
+/**/ 0xBD262398, 0x352F961F,
+/**/ 0xBF3DFC7C, 0x696BA563,
+/**/ 0x3F3DFE3E, 0x23400000,
+/**/ 0xBD3B16B9, 0xDEDD373A,
+/**/ 0xBF3E1C74, 0xE6BE58DA,
+/**/ 0x3F3E1E3A, 0x61800000,
+/**/ 0x3D35D42E, 0x336BE94B,
+/**/ 0xBF3E3C6D, 0x5C13DEA7,
+/**/ 0x3F3E3E36, 0x9C000000,
+/**/ 0x3D1EBFAF, 0x08A303A2,
+/**/ 0xBF3E5C65, 0xC96C39C9,
+/**/ 0x3F3E5E32, 0xD2800000,
+/**/ 0xBD160A06, 0x34856362,
+/**/ 0xBF3E7C5E, 0x2EC76D3D,
+/**/ 0x3F3E7E2F, 0x05000000,
+/**/ 0xBD31C21A, 0x154CDF1A,
+/**/ 0xBF3E9C56, 0x8C257C04,
+/**/ 0x3F3E9E2B, 0x33800000,
+/**/ 0xBD3D0DDE, 0x31941F7F,
+/**/ 0xBF3EBC4E, 0xE186691B,
+/**/ 0x3F3EBE27, 0x5DC00000,
+/**/ 0x3D389B31, 0xC26EC60D,
+/**/ 0xBF3EDC47, 0x2EEA3781,
+/**/ 0x3F3EDE23, 0x84400000,
+/**/ 0x3D2E742A, 0xD583BEF8,
+/**/ 0xBF3EFC3F, 0x7450EA34,
+/**/ 0x3F3EFE1F, 0xA6C00000,
+/**/ 0x3D1B3F31, 0xAC2DA351,
+/**/ 0xBF3F1C37, 0xB1BA8433,
+/**/ 0x3F3F1E1B, 0xC5400000,
+/**/ 0xBCE45533, 0x2DC67430,
+/**/ 0xBF3F3C2F, 0xE727087C,
+/**/ 0x3F3F3E17, 0xDFC00000,
+/**/ 0xBD1C7133, 0xFF1174AE,
+/**/ 0xBF3F5C28, 0x14967A0F,
+/**/ 0x3F3F5E13, 0xF6400000,
+/**/ 0xBD29383C, 0x4AE098DC,
+/**/ 0xBF3F7C20, 0x3A08DBE9,
+/**/ 0x3F3F7E10, 0x08C00000,
+/**/ 0xBD31211D, 0x684B0B3B,
+/**/ 0xBF3F9C18, 0x577E3109,
+/**/ 0x3F3F9E0C, 0x17400000,
+/**/ 0xBD34AA4B, 0x268D7464,
+/**/ 0xBF3FBC10, 0x6CF67C6E,
+/**/ 0x3F3FBE08, 0x21C00000,
+/**/ 0xBD3736A7, 0xBED03388,
+/**/ 0xBF3FDC08, 0x7A71C116,
+/**/ 0x3F3FDE04, 0x28400000,
+/**/ 0xBD38C533, 0x900BC4E5,
+/**/ 0xBF3FFC00, 0x7FF00200,
+/**/ 0x3F3FFE00, 0x2AC00000,
+/**/ 0xBD3954EE, 0xF9987527,
+/**/ 0xBF400DFC, 0x3EB8A115,
+/**/ 0x3F400EFE, 0x14A00000,
+/**/ 0xBD38E4DA, 0x5B2E613B,
+/**/ 0xBF401DF8, 0x397AC249,
+/**/ 0x3F401EFC, 0x11E00000,
+/**/ 0xBD3773F6, 0x14E5761B,
+/**/ 0xBF402DF4, 0x303E661C,
+/**/ 0x3F402EFA, 0x0D200000,
+/**/ 0xBD350142, 0x873570A0,
+/**/ 0xBF403DF0, 0x23038E0C,
+/**/ 0x3F403EF8, 0x06600000,
+/**/ 0xBD318BC0, 0x12F5DD53,
+/**/ 0xBF404DEC, 0x11CA3B9A,
+/**/ 0x3F404EF5, 0xFDA00000,
+/**/ 0xBD2A24DE, 0x32BC307C,
+/**/ 0xBF405DE7, 0xFC927044,
+/**/ 0x3F405EF3, 0xF2E00000,
+/**/ 0xBD1E513F, 0xF01532DA,
+/**/ 0xBF406DE3, 0xE35C2D8A,
+/**/ 0x3F406EF1, 0xE6200000,
+/**/ 0xBCF10631, 0xCE27534E,
+/**/ 0xBF407DDF, 0xC62774EA,
+/**/ 0x3F407EEF, 0xD7600000,
+/**/ 0x3D19E95C, 0x86CE9380,
+/**/ 0xBF408DDB, 0xA4F447E4,
+/**/ 0x3F408EED, 0xC6A00000,
+/**/ 0x3D2E19BC, 0xBA0CD2C3,
+/**/ 0xBF409DD7, 0x7FC2A7F8,
+/**/ 0x3F409EEB, 0xB3E00000,
+/**/ 0x3D38A832, 0x31FF7199,
+/**/ 0xBF40ADD3, 0x569296A4,
+/**/ 0x3F40AEE9, 0x9F400000,
+/**/ 0xBD3CB2AD, 0xC2D77791,
+/**/ 0xBF40BDCF, 0x29641567,
+/**/ 0x3F40BEE7, 0x88800000,
+/**/ 0xBD3102C1, 0xE5545563,
+/**/ 0xBF40CDCA, 0xF83725C2,
+/**/ 0x3F40CEE5, 0x6FC00000,
+/**/ 0xBD111C2A, 0x66B3E48D,
+/**/ 0xBF40DDC6, 0xC30BC932,
+/**/ 0x3F40DEE3, 0x55000000,
+/**/ 0x3D2302EF, 0x7711FC2A,
+/**/ 0xBF40EDC2, 0x89E20138,
+/**/ 0x3F40EEE1, 0x38400000,
+/**/ 0x3D3857C4, 0xB558238E,
+/**/ 0xBF40FDBE, 0x4CB9CF52,
+/**/ 0x3F40FEDF, 0x19A00000,
+/**/ 0xBD37C324, 0x1194C2E1,
+/**/ 0xBF410DBA, 0x0B933501,
+/**/ 0x3F410EDC, 0xF8E00000,
+/**/ 0xBD1B390B, 0xFBCAF285,
+/**/ 0xBF411DB5, 0xC66E33C2,
+/**/ 0x3F411EDA, 0xD6200000,
+/**/ 0x3D266ECF, 0x0E52C3A4,
+/**/ 0xBF412DB1, 0x7D4ACD15,
+/**/ 0x3F412ED8, 0xB1600000,
+/**/ 0x3D3E4EDB, 0x1A4AF71D,
+/**/ 0xBF413DAD, 0x30290279,
+/**/ 0x3F413ED6, 0x8AC00000,
+/**/ 0xBD2B0DD1, 0x58C4D599,
+/**/ 0xBF414DA8, 0xDF08D56E,
+/**/ 0x3F414ED4, 0x62000000,
+/**/ 0x3D1EDC6F, 0x2FB4061D,
+/**/ 0xBF415DA4, 0x89EA4773,
+/**/ 0x3F415ED2, 0x37400000,
+/**/ 0x3D3E09E8, 0x1BA53538,
+/**/ 0xBF416DA0, 0x30CD5A06,
+/**/ 0x3F416ED0, 0x0AA00000,
+/**/ 0xBD251B08, 0x4A5B4574,
+/**/ 0xBF417D9B, 0xD3B20EA8,
+/**/ 0x3F417ECD, 0xDBE00000,
+/**/ 0x3D2BE3AD, 0x4241B57B,
+/**/ 0xBF418D97, 0x729866D7,
+/**/ 0x3F418ECB, 0xAB400000,
+/**/ 0xBD387707, 0xFA22BD16,
+/**/ 0xBF419D93, 0x0D806412,
+/**/ 0x3F419EC9, 0x78800000,
+/**/ 0x3D01C6FC, 0xFFA2FC2F,
+/**/ 0xBF41AD8E, 0xA46A07D9,
+/**/ 0x3F41AEC7, 0x43C00000,
+/**/ 0x3D3E028D, 0x05F32EE8,
+/**/ 0xBF41BD8A, 0x375553AB,
+/**/ 0x3F41BEC5, 0x0D200000,
+/**/ 0xBD146400, 0xC7E46F2B,
+/**/ 0xBF41CD85, 0xC6424907,
+/**/ 0x3F41CEC2, 0xD4600000,
+/**/ 0x3D38E737, 0x8DFCE791,
+/**/ 0xBF41DD81, 0x5130E96B,
+/**/ 0x3F41DEC0, 0x99C00000,
+/**/ 0xBD1FEF30, 0x92F4A6CE,
+/**/ 0xBF41ED7C, 0xD8213659,
+/**/ 0x3F41EEBE, 0x5D000000,
+/**/ 0x3D383EF4, 0x4AE68315,
+/**/ 0xBF41FD78, 0x5B13314D,
+/**/ 0x3F41FEBC, 0x1E600000,
+/**/ 0xBD199E1E, 0x39A8276A,
+/**/ 0xBF420D73, 0xDA06DBC8,
+/**/ 0x3F420EB9, 0xDDA00000,
+/**/ 0x3D3C11BF, 0xE39F6D77,
+/**/ 0xBF421D6F, 0x54FC3749,
+/**/ 0x3F421EB7, 0x9B000000,
+/**/ 0xBCD50D72, 0xC3A8C440,
+/**/ 0xBF422D6A, 0xCBF3454F,
+/**/ 0x3F422EB5, 0x56600000,
+/**/ 0xBD3B9869, 0x06E59170,
+/**/ 0xBF423D66, 0x3EEC0759,
+/**/ 0x3F423EB3, 0x0FA00000,
+/**/ 0x3D248C4B, 0x86930551,
+/**/ 0xBF424D61, 0xADE67EE6,
+/**/ 0x3F424EB0, 0xC7000000,
+/**/ 0xBD2D6F13, 0xB3649FF7,
+/**/ 0xBF425D5D, 0x18E2AD76,
+/**/ 0x3F425EAE, 0x7C400000,
+/**/ 0x3D396F87, 0xB496441D,
+/**/ 0xBF426D58, 0x7FE09487,
+/**/ 0x3F426EAC, 0x2FA00000,
+/**/ 0x3D05E2D0, 0x01961A2F,
+/**/ 0xBF427D53, 0xE2E03598,
+/**/ 0x3F427EA9, 0xE1000000,
+/**/ 0xBD32D013, 0x652D1720,
+/**/ 0xBF428D4F, 0x41E1922A,
+/**/ 0x3F428EA7, 0x90400000,
+/**/ 0x3D38CB3F, 0x15C6A78A,
+/**/ 0xBF429D4A, 0x9CE4ABBA,
+/**/ 0x3F429EA5, 0x3DA00000,
+/**/ 0x3D163D44, 0x07F8A52A,
+/**/ 0xBF42AD45, 0xF3E983C8,
+/**/ 0x3F42AEA2, 0xE9000000,
+/**/ 0xBD2905BC, 0x1FEC6070,
+/**/ 0xBF42BD41, 0x46F01BD4,
+/**/ 0x3F42BEA0, 0x92600000,
+/**/ 0xBD3D6A4E, 0x8FE5CB8E,
+/**/ 0xBF42CD3C, 0x95F8755C,
+/**/ 0x3F42CE9E, 0x39A00000,
+/**/ 0x3D32D9FF, 0x120028B6,
+/**/ 0xBF42DD37, 0xE10291DF,
+/**/ 0x3F42DE9B, 0xDF000000,
+/**/ 0x3D112C29, 0x94B2D8A6,
+/**/ 0xBF42ED33, 0x280E72DD,
+/**/ 0x3F42EE99, 0x82600000,
+/**/ 0xBD222C5A, 0x0E9DC27F,
+/**/ 0xBF42FD2E, 0x6B1C19D4,
+/**/ 0x3F42FE97, 0x23C00000,
+/**/ 0xBD3548A7, 0xA4C12307,
+/**/ 0xBF430D29, 0xAA2B8844,
+/**/ 0x3F430E94, 0xC3000000,
+/**/ 0x3D3FB49A, 0x1B27A40C,
+/**/ 0xBF431D24, 0xE53CBFAC,
+/**/ 0x3F431E92, 0x60600000,
+/**/ 0x3D35E297, 0xC65D601D,
+/**/ 0xBF432D20, 0x1C4FC18B,
+/**/ 0x3F432E8F, 0xFBC00000,
+/**/ 0x3D2A84A1, 0xD4E46CD5,
+/**/ 0xBF433D1B, 0x4F648F60,
+/**/ 0x3F433E8D, 0x95200000,
+/**/ 0x3D175314, 0x526215F8,
+/**/ 0xBF434D16, 0x7E7B2AAB,
+/**/ 0x3F434E8B, 0x2C800000,
+/**/ 0xBCD9430B, 0x9746A94C,
+/**/ 0xBF435D11, 0xA99394E9,
+/**/ 0x3F435E88, 0xC1E00000,
+/**/ 0xBD15A88D, 0x47EF6144,
+/**/ 0xBF436D0C, 0xD0ADCF9B,
+/**/ 0x3F436E86, 0x55400000,
+/**/ 0xBD227301, 0x94614FFB,
+/**/ 0xBF437D07, 0xF3C9DC3F,
+/**/ 0x3F437E83, 0xE6A00000,
+/**/ 0xBD27A44A, 0x16908831,
+/**/ 0xBF438D03, 0x12E7BC55,
+/**/ 0x3F438E81, 0x76000000,
+/**/ 0xBD2A6621, 0x13DE59AC,
+/**/ 0xBF439CFE, 0x2E07715C,
+/**/ 0x3F439E7F, 0x03600000,
+/**/ 0xBD2AB687, 0x76635000,
+/**/ 0xBF43ACF9, 0x4528FCD2,
+/**/ 0x3F43AE7C, 0x8EC00000,
+/**/ 0xBD28937E, 0x28F7818F,
+/**/ 0xBF43BCF4, 0x584C6037,
+/**/ 0x3F43BE7A, 0x18200000,
+/**/ 0xBD23FB06, 0x17328F27,
+/**/ 0xBF43CCEF, 0x67719D0A,
+/**/ 0x3F43CE77, 0x9F800000,
+/**/ 0xBD19D640, 0x5AD74747,
+/**/ 0xBF43DCEA, 0x7298B4CA,
+/**/ 0x3F43DE75, 0x24E00000,
+/**/ 0xBCFB0E6A, 0xC5CB9C74,
+/**/ 0xBF43ECE5, 0x79C1A8F6,
+/**/ 0x3F43EE72, 0xA8400000,
+/**/ 0x3D1145E2, 0xF21B8682,
+/**/ 0xBF43FCE0, 0x7CEC7B0D,
+/**/ 0x3F43FE70, 0x29A00000,
+/**/ 0x3D27251B, 0x59543A06,
+/**/ 0xBF440CDB, 0x7C192C8E,
+/**/ 0x3F440E6D, 0xA9000000,
+/**/ 0x3D341357, 0xAC6250B6,
+/**/ 0xBF441CD6, 0x7747BEF8,
+/**/ 0x3F441E6B, 0x26600000,
+/**/ 0x3D3DD4D6, 0x43A510F7,
+/**/ 0xBF442CD1, 0x6E7833CB,
+/**/ 0x3F442E68, 0xA1E00000,
+/**/ 0xBD3727F7, 0x05F7D1E1,
+/**/ 0xBF443CCC, 0x61AA8C85,
+/**/ 0x3F443E66, 0x1B400000,
+/**/ 0xBD25C421, 0x527C9668,
+/**/ 0xBF444CC7, 0x50DECAA5,
+/**/ 0x3F444E63, 0x92A00000,
+/**/ 0x3D053C47, 0x053F70AC,
+/**/ 0xBF445CC2, 0x3C14EFAB,
+/**/ 0x3F445E61, 0x08000000,
+/**/ 0x3D3175D5, 0x1E315FBB,
+/**/ 0xBF446CBD, 0x234CFD15,
+/**/ 0x3F446E5E, 0x7B800000,
+/**/ 0xBD3E762C, 0x6A8B33AC,
+/**/ 0xBF447CB8, 0x0686F463,
+/**/ 0x3F447E5B, 0xECE00000,
+/**/ 0xBD2A36F8, 0x67AD9900,
+/**/ 0xBF448CB2, 0xE5C2D713,
+/**/ 0x3F448E59, 0x5C400000,
+/**/ 0x3D161B95, 0x1E974853,
+/**/ 0xBF449CAD, 0xC100A6A5,
+/**/ 0x3F449E56, 0xC9A00000,
+/**/ 0x3D3971F7, 0x8CE22250,
+/**/ 0xBF44ACA8, 0x98406498,
+/**/ 0x3F44AE54, 0x35200000,
+/**/ 0xBD315945, 0xDF8A23F8,
+/**/ 0xBF44BCA3, 0x6B82126A,
+/**/ 0x3F44BE51, 0x9E800000,
+/**/ 0x3D1498B2, 0x1A63D360,
+/**/ 0xBF44CC9E, 0x3AC5B19B,
+/**/ 0x3F44CE4F, 0x05E00000,
+/**/ 0x3D3CF14E, 0x4323A054,
+/**/ 0xBF44DC99, 0x060B43AA,
+/**/ 0x3F44DE4C, 0x6B600000,
+/**/ 0xBD23EDC2, 0x4CE35F94,
+/**/ 0xBF44EC93, 0xCD52CA15,
+/**/ 0x3F44EE49, 0xCEC00000,
+/**/ 0x3D306E9D, 0xCCF1B48E,
+/**/ 0xBF44FC8E, 0x909C465C,
+/**/ 0x3F44FE47, 0x30400000,
+/**/ 0xBD33DD35, 0x5FF9440B,
+/**/ 0xBF450C89, 0x4FE7B9FF,
+/**/ 0x3F450E44, 0x8FA00000,
+/**/ 0x3D224D49, 0xAA4D276D,
+/**/ 0xBF451C84, 0x0B35267A,
+/**/ 0x3F451E41, 0xED200000,
+/**/ 0xBD3884D4, 0x11B557F9,
+/**/ 0xBF452C7E, 0xC2848D4F,
+/**/ 0x3F452E3F, 0x48800000,
+/**/ 0x3D1C857D, 0xB43290C4,
+/**/ 0xBF453C79, 0x75D5EFFC,
+/**/ 0x3F453E3C, 0xA2000000,
+/**/ 0xBD37E5C1, 0x2D598D3C,
+/**/ 0xBF454C74, 0x25294FFF,
+/**/ 0x3F454E39, 0xF9600000,
+/**/ 0x3D24CD93, 0x3FE47B89,
+/**/ 0xBF455C6E, 0xD07EAED8,
+/**/ 0x3F455E37, 0x4EE00000,
+/**/ 0xBD31F800, 0xAA959122,
+/**/ 0xBF456C69, 0x77D60E06,
+/**/ 0x3F456E34, 0xA2400000,
+/**/ 0x3D32FEDF, 0x7329AF92,
+/**/ 0xBF457C64, 0x1B2F6F08,
+/**/ 0x3F457E31, 0xF3C00000,
+/**/ 0xBD1ACE5A, 0x1C545A6F,
+/**/ 0xBF458C5E, 0xBA8AD35D,
+/**/ 0x3F458E2F, 0x43400000,
+/**/ 0xBD3F0E63, 0x19F6B9EF,
+/**/ 0xBF459C59, 0x55E83C84,
+/**/ 0x3F459E2C, 0x90A00000,
+/**/ 0x3D23DEF2, 0x73005F6F,
+/**/ 0xBF45AC53, 0xED47ABFB,
+/**/ 0x3F45AE29, 0xDC200000,
+/**/ 0xBD277204, 0x1C295DE7,
+/**/ 0xBF45BC4E, 0x80A92343,
+/**/ 0x3F45BE27, 0x25800000,
+/**/ 0x3D3FF92A, 0x8D869589,
+/**/ 0xBF45CC49, 0x100CA3D9,
+/**/ 0x3F45CE24, 0x6D000000,
+/**/ 0x3D2A0DFD, 0x145C5335,
+/**/ 0xBF45DC43, 0x9B722F3C,
+/**/ 0x3F45DE21, 0xB2800000,
+/**/ 0xBD123A1A, 0x6A8614B3,
+/**/ 0xBF45EC3E, 0x22D9C6ED,
+/**/ 0x3F45EE1E, 0xF6000000,
+/**/ 0xBD34C665, 0x63CBC7E7,
+/**/ 0xBF45FC38, 0xA6436C69,
+/**/ 0x3F45FE1C, 0x37600000,
+/**/ 0x3D3C6061, 0xAB6C51D7,
+/**/ 0xBF460C33, 0x25AF2130,
+/**/ 0x3F460E19, 0x76E00000,
+/**/ 0x3D2DCD9C, 0x1EC7F453,
+/**/ 0xBF461C2D, 0xA11CE6C1,
+/**/ 0x3F461E16, 0xB4600000,
+/**/ 0x3D066EFA, 0x20C52899,
+/**/ 0xBF462C28, 0x188CBE9A,
+/**/ 0x3F462E13, 0xEFE00000,
+/**/ 0xBD1FA5AC, 0xEB5FDD5C,
+/**/ 0xBF463C22, 0x8BFEAA3B,
+/**/ 0x3F463E11, 0x29600000,
+/**/ 0xBD313E11, 0xF22FE2BC,
+/**/ 0xBF464C1C, 0xFB72AB23,
+/**/ 0x3F464E0E, 0x60E00000,
+/**/ 0xBD392F15, 0x6710E251,
+/**/ 0xBF465C17, 0x66E8C2D0,
+/**/ 0x3F465E0B, 0x96600000,
+/**/ 0xBD3FBB76, 0x1EFC78A7,
+/**/ 0xBF466C11, 0xCE60F2C1,
+/**/ 0x3F466E08, 0xC9C00000,
+/**/ 0x3D3B1DCB, 0x602C1A84,
+/**/ 0xBF467C0C, 0x31DB3C76,
+/**/ 0x3F467E05, 0xFB400000,
+/**/ 0x3D375DAE, 0x9027DA74,
+/**/ 0xBF468C06, 0x9157A16E,
+/**/ 0x3F468E03, 0x2AC00000,
+/**/ 0x3D350532, 0xEA560DA0,
+/**/ 0xBF469C00, 0xECD62326,
+/**/ 0x3F469E00, 0x58400000,
+/**/ 0x3D341557, 0xE7B63DE2 } };
+
+#else
+#ifdef LITTLE_ENDI
+static const union {int4 i[5800]; double x[2900];} ui = { .i = {
+/**/ 0x00000000, 0x3FF6A000,
+/**/ 0x3729043E, 0x3F33CD15,
+/**/ 0x0B3AB000, 0xBFD63003,
+/**/ 0xE731AE00, 0x3D2DB623,
+/**/ 0x00000000, 0x3FF69800,
+/**/ 0xCC7267D0, 0x3F33F349,
+/**/ 0xCDB03000, 0xBFD61965,
+/**/ 0x603C488E, 0x3D2F08AD,
+/**/ 0x00000000, 0x3FF69000,
+/**/ 0x8D0BFD2E, 0x3F3473A8,
+/**/ 0x8AF09000, 0xBFD602D0,
+/**/ 0x76DF3F65, 0xBD1EBE91,
+/**/ 0x00000000, 0x3FF68800,
+/**/ 0x390B9ED0, 0x3F354DD2,
+/**/ 0x3D5C3000, 0xBFD5EC43,
+/**/ 0x1229D17F, 0xBD36B71A,
+/**/ 0x00000000, 0x3FF68000,
+/**/ 0x16816817, 0x3F368168,
+/**/ 0xDF596000, 0xBFD5D5BD,
+/**/ 0x08A465DC, 0x3D0A0B2A,
+/**/ 0x00000000, 0x3FF67800,
+/**/ 0xF08C7765, 0x3F380E0B,
+/**/ 0x6B544000, 0xBFD5BF40,
+/**/ 0xEB68981C, 0x3D227023,
+/**/ 0x00000000, 0x3FF67000,
+/**/ 0x16719F36, 0x3F39F360,
+/**/ 0xDBBEE000, 0xBFD5A8CA,
+/**/ 0x0AF7ECF8, 0x3CF7C79B,
+/**/ 0x00000000, 0x3FF66800,
+/**/ 0x5AB40167, 0x3F3C3107,
+/**/ 0x2B113000, 0xBFD5925D,
+/**/ 0xA7A56F34, 0x3D369BF5,
+/**/ 0x00000000, 0x3FF66000,
+/**/ 0x122F9016, 0x3F3EC6A5,
+/**/ 0x53C8D000, 0xBFD57BF7,
+/**/ 0xEE5D40EF, 0xBD1FADED,
+/**/ 0x00000000, 0x3FF65C00,
+/**/ 0xECCA9097, 0xBF3E4C22,
+/**/ 0x50695000, 0xBFD56599,
+/**/ 0x2BADC774, 0xBD14C5FD,
+/**/ 0x00000000, 0x3FF65400,
+/**/ 0x4B55CC62, 0xBF3B07AC,
+/**/ 0x1B7BE000, 0xBFD54F43,
+/**/ 0xC0910952, 0xBD1A8954,
+/**/ 0x00000000, 0x3FF64C00,
+/**/ 0x32DA090E, 0xBF376C52,
+/**/ 0xAF8F7000, 0xBFD538F4,
+/**/ 0xE45547CE, 0xBD27EC02,
+/**/ 0x00000000, 0x3FF64400,
+/**/ 0x4DE9BD38, 0xBF337A6F,
+/**/ 0x0738A000, 0xBFD522AE,
+/**/ 0x8164C759, 0xBD2EBE70,
+/**/ 0x00000000, 0x3FF63C00,
+/**/ 0x923C708B, 0xBF2E64BB,
+/**/ 0x1D11C000, 0xBFD50C6F,
+/**/ 0x7E827C2C, 0x3D3A0E6B,
+/**/ 0x00000000, 0x3FF63400,
+/**/ 0xA7E43FD4, 0xBF2528EE,
+/**/ 0xEBBAA000, 0xBFD4F637,
+/**/ 0xCB3124B9, 0x3D3FC158,
+/**/ 0x00000000, 0x3FF62C00,
+/**/ 0x86689DF7, 0xBF168454,
+/**/ 0x6DD8C000, 0xBFD4E008,
+/**/ 0xA1E44788, 0x3D34D692,
+/**/ 0x00000000, 0x3FF62400,
+/**/ 0x77016240, 0xBED623FA,
+/**/ 0x9E173000, 0xBFD4C9E0,
+/**/ 0x1B0AD8A4, 0x3D2E2089,
+/**/ 0x00000000, 0x3FF61C00,
+/**/ 0x58715130, 0x3F151300,
+/**/ 0x77268000, 0xBFD4B3C0,
+/**/ 0x81052B9F, 0x3D165B46,
+/**/ 0x00000000, 0x3FF61400,
+/**/ 0x35D2754E, 0x3F266D06,
+/**/ 0xF3BCC000, 0xBFD49DA7,
+/**/ 0x4DAF4B9A, 0xBD307B33,
+/**/ 0x00000000, 0x3FF60C00,
+/**/ 0xDA197F23, 0x3F317C61,
+/**/ 0x0E958000, 0xBFD48797,
+/**/ 0x465CF25F, 0xBD3DC1B8,
+/**/ 0x00000000, 0x3FF60400,
+/**/ 0x81605816, 0x3F381605,
+/**/ 0xC271C000, 0xBFD4718D,
+/**/ 0xFB4C14C5, 0xBD306C18,
+/**/ 0x00000000, 0x3FF5FC00,
+/**/ 0xB5C6F559, 0x3F3F0317,
+/**/ 0x0A17E000, 0xBFD45B8C,
+/**/ 0xE7D0A853, 0x3D0D9120,
+/**/ 0x00000000, 0x3FF5F800,
+/**/ 0x6D2041E3, 0xBF39BCBD,
+/**/ 0xE053A000, 0xBFD44591,
+/**/ 0x92923D88, 0x3D06E958,
+/**/ 0x00000000, 0x3FF5F000,
+/**/ 0x5604CC40, 0xBF3229CF,
+/**/ 0x3FF62000, 0xBFD42F9F,
+/**/ 0x0F7D3354, 0xBD390644,
+/**/ 0x00000000, 0x3FF5E800,
+/**/ 0xFD431489, 0xBF2488E5,
+/**/ 0x23D5F000, 0xBFD419B4,
+/**/ 0x226DE3EC, 0x3D3CE379,
+/**/ 0x00000000, 0x3FF5E000,
+/**/ 0x6424E9C9, 0xBF0067E7,
+/**/ 0x86CEA000, 0xBFD403D0,
+/**/ 0x74487308, 0xBD3E6EF5,
+/**/ 0x00000000, 0x3FF5D800,
+/**/ 0x38A94D24, 0x3F19F0FB,
+/**/ 0x63C17000, 0xBFD3EDF4,
+/**/ 0x297F2C3F, 0x3D3F067C,
+/**/ 0x00000000, 0x3FF5D000,
+/**/ 0x23CAD2AA, 0x3F2EADD9,
+/**/ 0xB5947000, 0xBFD3D81F,
+/**/ 0x2A9D37A4, 0x3D222C7C,
+/**/ 0x00000000, 0x3FF5C800,
+/**/ 0x31057262, 0x3F3882B9,
+/**/ 0x77333000, 0xBFD3C252,
+/**/ 0xB606BD5C, 0xBD183B54,
+/**/ 0x00000000, 0x3FF5C400,
+/**/ 0x10FFA8F8, 0xBF3E00AE,
+/**/ 0xA38E6000, 0xBFD3AC8C,
+/**/ 0xBC02BE4A, 0x3D2D0BEF,
+/**/ 0x00000000, 0x3FF5BC00,
+/**/ 0x8056EAF3, 0xBF34339B,
+/**/ 0x359BC000, 0xBFD396CE,
+/**/ 0x5663663D, 0x3D05839C,
+/**/ 0x00000000, 0x3FF5B400,
+/**/ 0xF31D7FD5, 0xBF242CC1,
+/**/ 0x28565000, 0xBFD38117,
+/**/ 0x93A0702B, 0x3D2A71E4,
+/**/ 0x00000000, 0x3FF5AC00,
+/**/ 0x6B015AC0, 0x3ED5AC05,
+/**/ 0x76BE1000, 0xBFD36B67,
+/**/ 0xB0F177C8, 0xBD116ECD,
+/**/ 0x00000000, 0x3FF5A400,
+/**/ 0x5BA55E5A, 0x3F26268D,
+/**/ 0x1BD83000, 0xBFD355BF,
+/**/ 0x8964F0E8, 0x3D2BA99B,
+/**/ 0x00000000, 0x3FF59C00,
+/**/ 0x3CCAA376, 0x3F361F12,
+/**/ 0x12AED000, 0xBFD3401E,
+/**/ 0x556E291D, 0x3D317C73,
+/**/ 0x00000000, 0x3FF59800,
+/**/ 0x62D32417, 0xBF3E863D,
+/**/ 0x56512000, 0xBFD32A84,
+/**/ 0x139AF5D6, 0xBD04F928,
+/**/ 0x00000000, 0x3FF59000,
+/**/ 0xEA712DCF, 0xBF32DCF7,
+/**/ 0xE1D36000, 0xBFD314F1,
+/**/ 0xD3213CB8, 0x3D28E27A,
+/**/ 0x00000000, 0x3FF58800,
+/**/ 0xA0CC87E8, 0xBF1B95B2,
+/**/ 0xB04EB000, 0xBFD2FF66,
+/**/ 0x541E6E2E, 0x3D38AED2,
+/**/ 0x00000000, 0x3FF58000,
+/**/ 0x01580560, 0x3F158056,
+/**/ 0xBCE12000, 0xBFD2E9E2,
+/**/ 0x128D1DC2, 0xBD24300C,
+/**/ 0x00000000, 0x3FF57800,
+/**/ 0x15791F34, 0x3F31F340,
+/**/ 0x02ADD000, 0xBFD2D466,
+/**/ 0xDCD54196, 0x3D288D0D,
+/**/ 0x00000000, 0x3FF57000,
+/**/ 0x06B39A23, 0x3F3ED3C5,
+/**/ 0x7CDC9000, 0xBFD2BEF0,
+/**/ 0x4A5004F4, 0xBD2A9CFA,
+/**/ 0x00000000, 0x3FF56C00,
+/**/ 0x53FEA954, 0xBF33FEA9,
+/**/ 0x269A4000, 0xBFD2A982,
+/**/ 0x557285CF, 0x3D22058E,
+/**/ 0x00000000, 0x3FF56400,
+/**/ 0xEB478503, 0xBF1A1160,
+/**/ 0xFB187000, 0xBFD2941A,
+/**/ 0xB730E28B, 0x3D3210C2,
+/**/ 0x00000000, 0x3FF55C00,
+/**/ 0xE4A18B2E, 0x3F1D09AD,
+/**/ 0xF58D9000, 0xBFD27EBA,
+/**/ 0x00B4BDA7, 0x3D2B1988,
+/**/ 0x00000000, 0x3FF55400,
+/**/ 0x55555555, 0x3F355555,
+/**/ 0x1134E000, 0xBFD26962,
+/**/ 0x10522625, 0x3D31B61F,
+/**/ 0x00000000, 0x3FF55000,
+/**/ 0xB319A21F, 0xBF3C4BE6,
+/**/ 0x494E5000, 0xBFD25410,
+/**/ 0xC0EF77F2, 0xBD3B1D7A,
+/**/ 0x00000000, 0x3FF54800,
+/**/ 0x8FA03FD5, 0xBF2B4328,
+/**/ 0x991EC000, 0xBFD23EC5,
+/**/ 0x48A2E522, 0x3D36DBE4,
+/**/ 0x00000000, 0x3FF54000,
+/**/ 0x40154015, 0x3EF54015,
+/**/ 0xFBEF8000, 0xBFD22981,
+/**/ 0x609580DA, 0x3D3A1421,
+/**/ 0x00000000, 0x3FF53800,
+/**/ 0x40FEAC6F, 0x3F30948F,
+/**/ 0x6D0EC000, 0xBFD21445,
+/**/ 0x28B728A3, 0x3D3CAF04,
+/**/ 0x00000000, 0x3FF53400,
+/**/ 0xFD04F7B8, 0xBF3FE034,
+/**/ 0xE7CF4000, 0xBFD1FF0F,
+/**/ 0x513FF0C1, 0xBD3E9D5B,
+/**/ 0x00000000, 0x3FF52C00,
+/**/ 0x7FAB5403, 0xBF300A95,
+/**/ 0x6788A000, 0xBFD1E9E1,
+/**/ 0xD3C8B65E, 0x3D382EAE,
+/**/ 0x00000000, 0x3FF52400,
+/**/ 0x52401524, 0x3EB52401,
+/**/ 0xE796C000, 0xBFD1D4B9,
+/**/ 0x7C42E56D, 0xBD222A66,
+/**/ 0x00000000, 0x3FF51C00,
+/**/ 0x2F8151D0, 0x3F307EAE,
+/**/ 0x635A7000, 0xBFD1BF99,
+/**/ 0x575C2125, 0x3D31AC89,
+/**/ 0x00000000, 0x3FF51800,
+/**/ 0xEAE9ECE4, 0xBF3ECE3F,
+/**/ 0xD638D000, 0xBFD1AA7F,
+/**/ 0x9616F7A0, 0xBD29F60A,
+/**/ 0x00000000, 0x3FF51000,
+/**/ 0xC7675243, 0xBF2BA3DD,
+/**/ 0x3B9BC000, 0xBFD1956D,
+/**/ 0x3AD1AA14, 0xBD27D2F7,
+/**/ 0x00000000, 0x3FF50800,
+/**/ 0x764E368D, 0x3F0B9AC8,
+/**/ 0x8EF19000, 0xBFD18061,
+/**/ 0xC86D38E5, 0x3D3482FF,
+/**/ 0x00000000, 0x3FF50000,
+/**/ 0x15015015, 0x3F350150,
+/**/ 0xCBAD0000, 0xBFD16B5C,
+/**/ 0x042D74BF, 0x3D323299,
+/**/ 0x00000000, 0x3FF4FC00,
+/**/ 0x4A683C50, 0xBF392851,
+/**/ 0xED456000, 0xBFD1565E,
+/**/ 0xFB6ABA25, 0x3CEE75AD,
+/**/ 0x00000000, 0x3FF4F400,
+/**/ 0xACD95EF0, 0xBF1C2748,
+/**/ 0xEF367000, 0xBFD14167,
+/**/ 0x824DAAF5, 0xBD3E0C07,
+/**/ 0x00000000, 0x3FF4EC00,
+/**/ 0x67A47465, 0x3F26B90D,
+/**/ 0xCD007000, 0xBFD12C77,
+/**/ 0x8A11F797, 0xBD13B294,
+/**/ 0x00000000, 0x3FF4E400,
+/**/ 0xF0539783, 0x3F3E0A72,
+/**/ 0x8227E000, 0xBFD1178E,
+/**/ 0xCE2D07F2, 0xBD31EF78,
+/**/ 0x00000000, 0x3FF4E000,
+/**/ 0xF87FD642, 0xBF2E00A6,
+/**/ 0x0A35D000, 0xBFD102AC,
+/**/ 0xDFDFD686, 0x3D2F1FBD,
+/**/ 0x00000000, 0x3FF4D800,
+/**/ 0x0B12E3FD, 0x3F10EFB7,
+/**/ 0x60B78000, 0xBFD0EDD0,
+/**/ 0x2D8435F5, 0xBD0019B5,
+/**/ 0x00000000, 0x3FF4D000,
+/**/ 0x5CB4DBE5, 0x3F37BEF1,
+/**/ 0x813EB000, 0xBFD0D8FB,
+/**/ 0x8753FA35, 0xBD1EE8C8,
+/**/ 0x00000000, 0x3FF4CC00,
+/**/ 0xA50918B1, 0xBF34778D,
+/**/ 0x67616000, 0xBFD0C42D,
+/**/ 0x163CEAE9, 0xBD27188B,
+/**/ 0x00000000, 0x3FF4C400,
+/**/ 0xE37288EC, 0xBED9F4F7,
+/**/ 0x0EB9E000, 0xBFD0AF66,
+/**/ 0xF528D80A, 0xBD23C7C3,
+/**/ 0x00000000, 0x3FF4BC00,
+/**/ 0x68FE0E42, 0x3F33EDDA,
+/**/ 0x72E6C000, 0xBFD09AA5,
+/**/ 0xE1734342, 0xBD3B50A1,
+/**/ 0x00000000, 0x3FF4B800,
+/**/ 0xB72E47D9, 0xBF3776C6,
+/**/ 0x8F8AE000, 0xBFD085EB,
+/**/ 0x3F45FE7B, 0xBD3E5D51,
+/**/ 0x00000000, 0x3FF4B000,
+/**/ 0xA052BF5B, 0xBF04AFD6,
+/**/ 0x604D6000, 0xBFD07138,
+/**/ 0x4E912B17, 0x3D3E7632,
+/**/ 0x00000000, 0x3FF4A800,
+/**/ 0xD5B5C015, 0x3F328FFA,
+/**/ 0xE0D96000, 0xBFD05C8B,
+/**/ 0xC77CCB58, 0xBD2AD0F1,
+/**/ 0x00000000, 0x3FF4A400,
+/**/ 0x9FEB5D80, 0xBF380528,
+/**/ 0x0CDE8000, 0xBFD047E6,
+/**/ 0x0D397F3C, 0xBD2DBDF1,
+/**/ 0x00000000, 0x3FF49C00,
+/**/ 0x25FF5B21, 0xBF02AD3E,
+/**/ 0xE0106000, 0xBFD03346,
+/**/ 0xA966395C, 0xBCF89FF8,
+/**/ 0x00000000, 0x3FF49400,
+/**/ 0x2D066EA2, 0x3F339E3B,
+/**/ 0x5626C000, 0xBFD01EAE,
+/**/ 0xFADE85AE, 0xBD3A43DC,
+/**/ 0x00000000, 0x3FF49000,
+/**/ 0xAFB2E932, 0xBF3629C1,
+/**/ 0x6ADDA000, 0xBFD00A1C,
+/**/ 0x688B9E18, 0xBD31CD8D,
+/**/ 0x00000000, 0x3FF48800,
+/**/ 0x22014880, 0x3ED48805,
+/**/ 0x33EA0000, 0xBFCFEB22,
+/**/ 0xDE00938B, 0xBD2F3418,
+/**/ 0x00000000, 0x3FF48000,
+/**/ 0x3D324D89, 0x3F37119F,
+/**/ 0xBE620000, 0xBFCFC218,
+/**/ 0x6F1CF6A0, 0xBD34BBA4,
+/**/ 0x00000000, 0x3FF47C00,
+/**/ 0x1EB851EC, 0xBF31EB85,
+/**/ 0x6CB3C000, 0xBFCF991C,
+/**/ 0xCD7CC834, 0x3D390D04,
+/**/ 0x00000000, 0x3FF47400,
+/**/ 0xAAFC7C01, 0x3F1569C9,
+/**/ 0x36778000, 0xBFCF702D,
+/**/ 0x16673E23, 0x3D108195,
+/**/ 0x00000000, 0x3FF46C00,
+/**/ 0x96066250, 0x3F3CE345,
+/**/ 0x134E0000, 0xBFCF474B,
+/**/ 0xF1DF7B5E, 0x3D3BAE49,
+/**/ 0x00000000, 0x3FF46800,
+/**/ 0x1D02DE87, 0xBF26A297,
+/**/ 0xFADFA000, 0xBFCF1E75,
+/**/ 0x25D83F6D, 0x3D20862B,
+/**/ 0x00000000, 0x3FF46000,
+/**/ 0xB9F34381, 0x3F2978FE,
+/**/ 0xE4DD0000, 0xBFCEF5AD,
+/**/ 0x65BB8E11, 0x3CCA2115,
+/**/ 0x00000000, 0x3FF45C00,
+/**/ 0xF6C71366, 0xBF3AF398,
+/**/ 0xC8FEA000, 0xBFCECCF2,
+/**/ 0xA3E75640, 0x3D3BEC63,
+/**/ 0x00000000, 0x3FF45400,
+/**/ 0x449AFF5D, 0xBF030E9C,
+/**/ 0x9F04A000, 0xBFCEA444,
+/**/ 0x63732A36, 0xBD35E916,
+/**/ 0x00000000, 0x3FF44C00,
+/**/ 0xF8B42EF3, 0x3F367190,
+/**/ 0x5EB78000, 0xBFCE7BA3,
+/**/ 0x23793649, 0x3D0D5EEE,
+/**/ 0x00000000, 0x3FF44800,
+/**/ 0xD260511C, 0xBF3079A9,
+/**/ 0xFFE72000, 0xBFCE530E,
+/**/ 0xB13F7C18, 0x3D3FDBDB,
+/**/ 0x00000000, 0x3FF44000,
+/**/ 0x0B644FBE, 0x3F21B87C,
+/**/ 0x7A6B2000, 0xBFCE2A87,
+/**/ 0x7787081A, 0xBD382381,
+/**/ 0x00000000, 0x3FF43C00,
+/**/ 0x411B2E25, 0xBF3D8CF5,
+/**/ 0xC6236000, 0xBFCE020C,
+/**/ 0xADB91424, 0x3D252B00,
+/**/ 0x00000000, 0x3FF43400,
+/**/ 0xD6A60978, 0xBF0DAC08,
+/**/ 0xDAF6E000, 0xBFCDD99E,
+/**/ 0x69C756EB, 0x3D302EC6,
+/**/ 0x00000000, 0x3FF42C00,
+/**/ 0x51F86EFA, 0x3F36625D,
+/**/ 0xB0D48000, 0xBFCDB13D,
+/**/ 0x847527E6, 0xBD32806A,
+/**/ 0x00000000, 0x3FF42800,
+/**/ 0xA8766564, 0xBF2E8B2D,
+/**/ 0x3FB30000, 0xBFCD88E9,
+/**/ 0x0234BF51, 0x3D375F28,
+/**/ 0x00000000, 0x3FF42000,
+/**/ 0xCB2A247B, 0x3F26A4CB,
+/**/ 0x7F904000, 0xBFCD60A1,
+/**/ 0x6FC20D39, 0x3D35D6E0,
+/**/ 0x00000000, 0x3FF41C00,
+/**/ 0xC17DF552, 0xBF39D5E8,
+/**/ 0x68720000, 0xBFCD3866,
+/**/ 0xB38932BC, 0x3D373650,
+/**/ 0x00000000, 0x3FF41400,
+/**/ 0x14141414, 0x3EF41414,
+/**/ 0xF2656000, 0xBFCD1037,
+/**/ 0x75B6F6E4, 0x3D084A7E,
+/**/ 0x00000000, 0x3FF40C00,
+/**/ 0x43AE87FD, 0x3F3C97A8,
+/**/ 0x157F2000, 0xBFCCE816,
+/**/ 0xA2099515, 0x3D29E0AB,
+/**/ 0x00000000, 0x3FF40800,
+/**/ 0x66A67E6F, 0xBF1F4BBC,
+/**/ 0xC9DB4000, 0xBFCCC000,
+/**/ 0x5D57AFF9, 0x3D1D6D58,
+/**/ 0x00000000, 0x3FF40000,
+/**/ 0x14014014, 0x3F340140,
+/**/ 0x079D4000, 0xBFCC97F8,
+/**/ 0xA8C6E6C5, 0xBD23B161,
+/**/ 0x00000000, 0x3FF3FC00,
+/**/ 0xFD809FD8, 0xBF2FD809,
+/**/ 0xC6F00000, 0xBFCC6FFB,
+/**/ 0xD3A69D43, 0xBD3EE138,
+/**/ 0x00000000, 0x3FF3F400,
+/**/ 0x57EE89D2, 0x3F28CA0E,
+/**/ 0x0005C000, 0xBFCC480C,
+/**/ 0xD5E44E76, 0xBD39A294,
+/**/ 0x00000000, 0x3FF3F000,
+/**/ 0xA50F9260, 0xBF370BD5,
+/**/ 0xAB180000, 0xBFCC2028,
+/**/ 0xE55C7AC6, 0x3D292E0E,
+/**/ 0x00000000, 0x3FF3E800,
+/**/ 0x75945FCE, 0x3F1704AA,
+/**/ 0xC0676000, 0xBFCBF851,
+/**/ 0x4C0854AD, 0x3D35420E,
+/**/ 0x00000000, 0x3FF3E400,
+/**/ 0xB56FD83C, 0xBF3D3431,
+/**/ 0x383BE000, 0xBFCBD087,
+/**/ 0x595412B6, 0x3D2D4BC4,
+/**/ 0x00000000, 0x3FF3DC00,
+/**/ 0x3DC013DC, 0x3EB3DC01,
+/**/ 0x0AE4A000, 0xBFCBA8C9,
+/**/ 0xF44432DA, 0xBD3A32E7,
+/**/ 0x00000000, 0x3FF3D400,
+/**/ 0xA75C5BBD, 0x3F3D991A,
+/**/ 0x30B82000, 0xBFCB8117,
+/**/ 0x3B9CD768, 0xBD1E9068,
+/**/ 0x00000000, 0x3FF3D000,
+/**/ 0x59C52F5D, 0xBF1292BA,
+/**/ 0xA213A000, 0xBFCB5971,
+/**/ 0x83AA91DF, 0xBD39B50E,
+/**/ 0x00000000, 0x3FF3C800,
+/**/ 0xBABE7440, 0x3F395A47,
+/**/ 0x575BC000, 0xBFCB31D8,
+/**/ 0x562A63CB, 0xBD3C794E,
+/**/ 0x00000000, 0x3FF3C400,
+/**/ 0x58A0943A, 0xBF20D475,
+/**/ 0x48FC2000, 0xBFCB0A4B,
+/**/ 0x5C3998ED, 0x3D22E72D,
+/**/ 0x00000000, 0x3FF3BC00,
+/**/ 0x3295482C, 0x3F360D92,
+/**/ 0x6F672000, 0xBFCAE2CA,
+/**/ 0xAE54F550, 0xBD37A8D5,
+/**/ 0x00000000, 0x3FF3B800,
+/**/ 0xCAB48651, 0xBF267D12,
+/**/ 0xC316A000, 0xBFCABB55,
+/**/ 0xCAF14CD8, 0x3D38A65A,
+/**/ 0x00000000, 0x3FF3B000,
+/**/ 0x13B13B14, 0x3F33B13B,
+/**/ 0x3C8AE000, 0xBFCA93ED,
+/**/ 0x50562169, 0x3D287243,
+/**/ 0x00000000, 0x3FF3AC00,
+/**/ 0x2C8FD3BF, 0xBF2A46AF,
+/**/ 0xD44B8000, 0xBFCA6C90,
+/**/ 0xF037B0C6, 0x3D3F63B7,
+/**/ 0x00000000, 0x3FF3A400,
+/**/ 0xAC822610, 0x3F324387,
+/**/ 0x82E6A000, 0xBFCA4540,
+/**/ 0xC81F7171, 0xBD360A77,
+/**/ 0x00000000, 0x3FF3A000,
+/**/ 0xA1923DEE, 0xBF2C34BB,
+/**/ 0x40F1C000, 0xBFCA1DFC,
+/**/ 0x004F3781, 0x3D301E0F,
+/**/ 0x00000000, 0x3FF39800,
+/**/ 0x87F63372, 0x3F31C2C1,
+/**/ 0x0708A000, 0xBFC9F6C4,
+/**/ 0x4BCD3F43, 0x3D3337D9,
+/**/ 0x00000000, 0x3FF39400,
+/**/ 0xE11BD52E, 0xBF2C4AA0,
+/**/ 0xCDCE0000, 0xBFC9CF97,
+/**/ 0x10C414E3, 0xBD3D862F,
+/**/ 0x00000000, 0x3FF38C00,
+/**/ 0x6088DBF4, 0x3F322D36,
+/**/ 0x8DEBA000, 0xBFC9A877,
+/**/ 0x3EFEC390, 0xBD3470FA,
+/**/ 0x00000000, 0x3FF38800,
+/**/ 0x503F774E, 0xBF2A8BBF,
+/**/ 0x4011A000, 0xBFC98163,
+/**/ 0x9E9045E2, 0xBD34EADD,
+/**/ 0x00000000, 0x3FF38000,
+/**/ 0x13813814, 0x3F338138,
+/**/ 0xDCF70000, 0xBFC95A5A,
+/**/ 0x58A0FF6F, 0xBD07F228,
+/**/ 0x00000000, 0x3FF37C00,
+/**/ 0x1B177053, 0xBF26FB6F,
+/**/ 0x5D594000, 0xBFC9335E,
+/**/ 0x3ABD47DA, 0xBD33115C,
+/**/ 0x00000000, 0x3FF37400,
+/**/ 0x945EDC20, 0x3F35BD1C,
+/**/ 0xB9FCC000, 0xBFC90C6D,
+/**/ 0x7718D7CA, 0x3D1935F5,
+/**/ 0x00000000, 0x3FF37000,
+/**/ 0x4DBDCC60, 0xBF219D00,
+/**/ 0xEBAC2000, 0xBFC8E588,
+/**/ 0xAB2D1140, 0xBD3B7D5C,
+/**/ 0x00000000, 0x3FF36800,
+/**/ 0xE0747954, 0x3F38DF3D,
+/**/ 0xEB390000, 0xBFC8BEAF,
+/**/ 0xAAE92CD1, 0x3D073D54,
+/**/ 0x00000000, 0x3FF36400,
+/**/ 0xD9D3C49F, 0xBF14E775,
+/**/ 0xB17B2000, 0xBFC897E2,
+/**/ 0x380CBE9E, 0x3D296B37,
+/**/ 0x00000000, 0x3FF35C00,
+/**/ 0xF2AF821E, 0x3F3CE5F9,
+/**/ 0x3750E000, 0xBFC87121,
+/**/ 0x42F9AF75, 0xBD3328EB,
+/**/ 0x00000000, 0x3FF35800,
+/**/ 0xE34971F2, 0xBEE82DF0,
+/**/ 0x759F6000, 0xBFC84A6B,
+/**/ 0x2ADF8609, 0x3D3DA280,
+/**/ 0x00000000, 0x3FF35400,
+/**/ 0x4873ECAE, 0xBF3E304D,
+/**/ 0x6551A000, 0xBFC823C1,
+/**/ 0x9A631E83, 0xBD1E0DDB,
+/**/ 0x00000000, 0x3FF34C00,
+/**/ 0x1FF659DB, 0x3F1264B6,
+/**/ 0xFF59A000, 0xBFC7FD22,
+/**/ 0xF457B7D2, 0x3D158BEB,
+/**/ 0x00000000, 0x3FF34800,
+/**/ 0xFECB9865, 0xBF386531,
+/**/ 0x3CAF6000, 0xBFC7D690,
+/**/ 0x17C301D7, 0x3D24C06B,
+/**/ 0x00000000, 0x3FF34000,
+/**/ 0xEEDA65AE, 0x3F25A8C2,
+/**/ 0x16516000, 0xBFC7B009,
+/**/ 0xCB067E57, 0x3D3AE75F,
+/**/ 0x00000000, 0x3FF33C00,
+/**/ 0x8434E1F4, 0xBF31BA4A,
+/**/ 0x85444000, 0xBFC7898D,
+/**/ 0xE3DBAF3F, 0xBD38E67B,
+/**/ 0x00000000, 0x3FF33400,
+/**/ 0xDBFC660A, 0x3F31EE97,
+/**/ 0x82936000, 0xBFC7631D,
+/**/ 0xC7C5F3E1, 0x3D25E77D,
+/**/ 0x00000000, 0x3FF33000,
+/**/ 0xBC40BFDA, 0xBF246252,
+/**/ 0x074FE000, 0xBFC73CB9,
+/**/ 0x0D0005A6, 0x3D3D66A9,
+/**/ 0x00000000, 0x3FF32800,
+/**/ 0x13299E64, 0x3F39E640,
+/**/ 0x0C914000, 0xBFC71660,
+/**/ 0x7CEC3838, 0xBCE51B15,
+/**/ 0x00000000, 0x3FF32400,
+/**/ 0xEF40991F, 0xBEFCB5D4,
+/**/ 0x8B756000, 0xBFC6F012,
+/**/ 0x0D31EF0F, 0xBD357739,
+/**/ 0x00000000, 0x3FF32000,
+/**/ 0xC823D892, 0xBF3D4632,
+/**/ 0x7D204000, 0xBFC6C9D0,
+/**/ 0xFD9B2DCA, 0x3CDC73FA,
+/**/ 0x00000000, 0x3FF31800,
+/**/ 0x7AED804C, 0x3F1DD63A,
+/**/ 0xDABBE000, 0xBFC6A399,
+/**/ 0xE66A15A6, 0x3D38F934,
+/**/ 0x00000000, 0x3FF31400,
+/**/ 0xE8C11E1A, 0xBF339849,
+/**/ 0x9D786000, 0xBFC67D6E,
+/**/ 0x30A706D3, 0x3D311E88,
+/**/ 0x00000000, 0x3FF30C00,
+/**/ 0x0D190131, 0x3F319013,
+/**/ 0xBE8C2000, 0xBFC6574E,
+/**/ 0x34F0F462, 0x3D398C1D,
+/**/ 0x00000000, 0x3FF30800,
+/**/ 0xB47A7FDA, 0xBF222315,
+/**/ 0x37336000, 0xBFC6313A,
+/**/ 0x4F21EA6D, 0x3D144DF5,
+/**/ 0x00000000, 0x3FF30000,
+/**/ 0x40260390, 0x3F3C82AC,
+/**/ 0x00B0A000, 0xBFC60B31,
+/**/ 0xC988F814, 0x3D371456,
+/**/ 0x00000000, 0x3FF2FC00,
+/**/ 0xA2430A62, 0x3F026443,
+/**/ 0x144C2000, 0xBFC5E533,
+/**/ 0xF3B290EA, 0x3D31CE0B,
+/**/ 0x00000000, 0x3FF2F800,
+/**/ 0xED097B42, 0xBF37B425,
+/**/ 0x6B544000, 0xBFC5BF40,
+/**/ 0xEB68981C, 0x3D127023,
+/**/ 0x00000000, 0x3FF2F000,
+/**/ 0x4AE0553C, 0x3F2D00E3,
+/**/ 0xFF1D6000, 0xBFC59958,
+/**/ 0x9769CA05, 0x3D3A1D05,
+/**/ 0x00000000, 0x3FF2EC00,
+/**/ 0x25D69D44, 0xBF262BC0,
+/**/ 0xC9018000, 0xBFC5737C,
+/**/ 0xA6B887F6, 0xBD39BAA7,
+/**/ 0x00000000, 0x3FF2E400,
+/**/ 0xE3103D6B, 0x3F3B88B5,
+/**/ 0xC2610000, 0xBFC54DAB,
+/**/ 0xE5C8D0D8, 0xBD2746FE,
+/**/ 0x00000000, 0x3FF2E000,
+/**/ 0xC04B8097, 0x3F02E025,
+/**/ 0xE4A1C000, 0xBFC527E5,
+/**/ 0x8D4B411D, 0x3D34E60B,
+/**/ 0x00000000, 0x3FF2DC00,
+/**/ 0x2C305021, 0xBF369C22,
+/**/ 0x292F6000, 0xBFC5022B,
+/**/ 0xFF36A25B, 0xBD348A05,
+/**/ 0x00000000, 0x3FF2D400,
+/**/ 0xD50A012D, 0x3F30A012,
+/**/ 0x897BC000, 0xBFC4DC7B,
+/**/ 0x0AE1FF0F, 0xBD0C79B6,
+/**/ 0x00000000, 0x3FF2D000,
+/**/ 0xBC66484E, 0xBF1FBE29,
+/**/ 0xFEFE2000, 0xBFC4B6D6,
+/**/ 0xF56E7952, 0xBD1522EC,
+/**/ 0x00000000, 0x3FF2C800,
+/**/ 0x12C9FB4E, 0x3F3FB4D8,
+/**/ 0x8333C000, 0xBFC4913D,
+/**/ 0x558124C4, 0x3D353E43,
+/**/ 0x00000000, 0x3FF2C400,
+/**/ 0x7004B11E, 0x3F1E3432,
+/**/ 0x0F9F6000, 0xBFC46BAF,
+/**/ 0x0790841A, 0x3D1249CD,
+/**/ 0x00000000, 0x3FF2C000,
+/**/ 0x5C8EF02F, 0xBF30671A,
+/**/ 0x9DC9C000, 0xBFC4462B,
+/**/ 0xA711B062, 0x3D384858,
+/**/ 0x00000000, 0x3FF2B800,
+/**/ 0xD548D9AC, 0x3F37D835,
+/**/ 0x27410000, 0xBFC420B3,
+/**/ 0xC85A0884, 0x3D116282,
+/**/ 0x00000000, 0x3FF2B400,
+/**/ 0xAD012B40, 0x3ED2B404,
+/**/ 0xA5992000, 0xBFC3FB45,
+/**/ 0xC0CAE559, 0xBD319713,
+/**/ 0x00000000, 0x3FF2B000,
+/**/ 0x8E7302A1, 0xBF370F78,
+/**/ 0x126BC000, 0xBFC3D5E3,
+/**/ 0x85096C4B, 0xBD13FB2F,
+/**/ 0x00000000, 0x3FF2A800,
+/**/ 0x3C1053F9, 0x3F31C92F,
+/**/ 0x67580000, 0xBFC3B08B,
+/**/ 0xF29320FB, 0x3D3AADE8,
+/**/ 0x00000000, 0x3FF2A400,
+/**/ 0x3DBE2E04, 0xBF14AD94,
+/**/ 0x9E028000, 0xBFC38B3E,
+/**/ 0x545C17F9, 0x3D370EF0,
+/**/ 0x00000000, 0x3FF2A000,
+/**/ 0xBED61BED, 0xBF3BED61,
+/**/ 0xB015A000, 0xBFC365FC,
+/**/ 0xAFB9691B, 0x3D3FD3A0,
+/**/ 0x00000000, 0x3FF29800,
+/**/ 0x26F004A6, 0x3F2B061A,
+/**/ 0x97412000, 0xBFC340C5,
+/**/ 0xF7D9D386, 0x3D37A3DC,
+/**/ 0x00000000, 0x3FF29400,
+/**/ 0xFF6B646D, 0xBF21B488,
+/**/ 0x4D3A4000, 0xBFC31B99,
+/**/ 0xE3A50810, 0xBD3F098E,
+/**/ 0x00000000, 0x3FF29000,
+/**/ 0x2CA5D5AC, 0xBF3F0582,
+/**/ 0xCBBC0000, 0xBFC2F677,
+/**/ 0x2160F40D, 0xBD352B30,
+/**/ 0x00000000, 0x3FF28800,
+/**/ 0x16025116, 0x3F260251,
+/**/ 0x0C868000, 0xBFC2D161,
+/**/ 0xCB81B4A1, 0xBD039D6C,
+/**/ 0x00000000, 0x3FF28400,
+/**/ 0x502065D2, 0xBF258CDF,
+/**/ 0x095F6000, 0xBFC2AC55,
+/**/ 0xD0C6C8A8, 0x3D1D3466,
+/**/ 0x00000000, 0x3FF27C00,
+/**/ 0x1CE4D6F8, 0x3F3FA38A,
+/**/ 0xBC11A000, 0xBFC28753,
+/**/ 0x359302E6, 0xBD37494E,
+/**/ 0x00000000, 0x3FF27800,
+/**/ 0xDCCA0781, 0x3F247DD5,
+/**/ 0x1E6DE000, 0xBFC2625D,
+/**/ 0xF09E3D82, 0x3CF52962,
+/**/ 0x00000000, 0x3FF27400,
+/**/ 0xDB195E8F, 0xBF25E8EF,
+/**/ 0x2A49C000, 0xBFC23D71,
+/**/ 0x8FD3DF5C, 0xBD100D23,
+/**/ 0x00000000, 0x3FF27000,
+/**/ 0xFFB647FE, 0xBF3FF6C8,
+/**/ 0xD9808000, 0xBFC2188F,
+/**/ 0x7F50C701, 0x3D3B3A1E,
+/**/ 0x00000000, 0x3FF26800,
+/**/ 0xC024D167, 0x3F266F9A,
+/**/ 0x25F26000, 0xBFC1F3B9,
+/**/ 0x9B083633, 0x3D15F74E,
+/**/ 0x00000000, 0x3FF26400,
+/**/ 0xEABD0E14, 0xBF22D1BD,
+/**/ 0x09854000, 0xBFC1CEED,
+/**/ 0x39192AF9, 0x3D315C1C,
+/**/ 0x00000000, 0x3FF26000,
+/**/ 0xF6D0EEC8, 0xBF3DD8F7,
+/**/ 0x7E240000, 0xBFC1AA2B,
+/**/ 0xDDE3B366, 0x3D31AC38,
+/**/ 0x00000000, 0x3FF25800,
+/**/ 0x2A241EF6, 0x3F2BCEB1,
+/**/ 0x7DBEC000, 0xBFC18574,
+/**/ 0x45BD9B49, 0xBD3E6744,
+/**/ 0x00000000, 0x3FF25400,
+/**/ 0xA21378D7, 0xBF18A05B,
+/**/ 0x024B2000, 0xBFC160C8,
+/**/ 0xA9009E3D, 0xBD2EC2D2,
+/**/ 0x00000000, 0x3FF25000,
+/**/ 0xD6CFA90C, 0xBF3A076F,
+/**/ 0x05C3A000, 0xBFC13C26,
+/**/ 0xD94F6509, 0x3D2CF5FD,
+/**/ 0x00000000, 0x3FF24800,
+/**/ 0x92492492, 0x3F324924,
+/**/ 0x8227E000, 0xBFC1178E,
+/**/ 0xCE2D07F2, 0xBD21EF78,
+/**/ 0x00000000, 0x3FF24400,
+/**/ 0x6151E899, 0xBEF3682B,
+/**/ 0x717D0000, 0xBFC0F301,
+/**/ 0x41AE86C5, 0x3D3E09B4,
+/**/ 0x00000000, 0x3FF24000,
+/**/ 0x89FA4C67, 0xBF34868E,
+/**/ 0xCDCCC000, 0xBFC0CE7E,
+/**/ 0xABFF5447, 0xBD14652D,
+/**/ 0x00000000, 0x3FF23800,
+/**/ 0x6B11F09F, 0x3F3858D8,
+/**/ 0x91268000, 0xBFC0AA06,
+/**/ 0xD7032129, 0x3D345519,
+/**/ 0x00000000, 0x3FF23400,
+/**/ 0xAF37C049, 0x3F159E26,
+/**/ 0xB59E4000, 0xBFC08598,
+/**/ 0x7009902C, 0x3D27E5DD,
+/**/ 0x00000000, 0x3FF23000,
+/**/ 0x2E076329, 0xBF2AB546,
+/**/ 0x354D4000, 0xBFC06135,
+/**/ 0x28340EE9, 0xBD363046,
+/**/ 0x00000000, 0x3FF22C00,
+/**/ 0xFEDD5FEE, 0xBF3FEDD5,
+/**/ 0x0A51E000, 0xBFC03CDC,
+/**/ 0xF169FC5C, 0xBD381A9C,
+/**/ 0x00000000, 0x3FF22400,
+/**/ 0x009126D7, 0x3F2B5B92,
+/**/ 0x2ECF6000, 0xBFC0188D,
+/**/ 0x1CFF9DFE, 0xBD03F965,
+/**/ 0x00000000, 0x3FF22000,
+/**/ 0x8121FB78, 0xBF121FB7,
+/**/ 0x39DBC000, 0xBFBFE891,
+/**/ 0xD82F7A82, 0xBD356594,
+/**/ 0x00000000, 0x3FF21C00,
+/**/ 0x3A459635, 0xBF368F22,
+/**/ 0x9DB58000, 0xBFBFA01C,
+/**/ 0xFA48A730, 0x3D08F351,
+/**/ 0x00000000, 0x3FF21400,
+/**/ 0x855E6012, 0x3F379804,
+/**/ 0x7D900000, 0xBFBF57BC,
+/**/ 0x9EA8B04E, 0xBD176A6C,
+/**/ 0x00000000, 0x3FF21000,
+/**/ 0x78CD7A37, 0x3F17B57C,
+/**/ 0xCDD98000, 0xBFBF0F70,
+/**/ 0x6C272C1E, 0xBD32E31F,
+/**/ 0x00000000, 0x3FF20C00,
+/**/ 0x07E4EF15, 0xBF271E73,
+/**/ 0x830A0000, 0xBFBEC739,
+/**/ 0xA80CDD10, 0xBD311FCB,
+/**/ 0x00000000, 0x3FF20800,
+/**/ 0x49392BA7, 0xBF3CDDEC,
+/**/ 0x91A34000, 0xBFBE7F16,
+/**/ 0x9BC77BFA, 0x3D32C1C5,
+/**/ 0x00000000, 0x3FF20000,
+/**/ 0x12012012, 0x3F320120,
+/**/ 0xEE304000, 0xBFBE3707,
+/**/ 0xE6766ABD, 0xBD20F684,
+/**/ 0x00000000, 0x3FF1FC00,
+/**/ 0xCE8AD1A2, 0x3EF0DC4F,
+/**/ 0x8D468000, 0xBFBDEF0D,
+/**/ 0x412E9A74, 0x3D324750,
+/**/ 0x00000000, 0x3FF1F800,
+/**/ 0xDC11F704, 0xBF2F7047,
+/**/ 0x63844000, 0xBFBDA727,
+/**/ 0x1FA71733, 0xBD1A8940,
+/**/ 0x00000000, 0x3FF1F000,
+/**/ 0x16B6419D, 0x3F3FAF3F,
+/**/ 0x65920000, 0xBFBD5F55,
+/**/ 0xCC185469, 0xBD30E239,
+/**/ 0x00000000, 0x3FF1EC00,
+/**/ 0xF70985E2, 0x3F2E878F,
+/**/ 0x88218000, 0xBFBD1797,
+/**/ 0xB5EFBEED, 0xBD336433,
+/**/ 0x00000000, 0x3FF1E800,
+/**/ 0x94D7FDC3, 0xBEEF55E4,
+/**/ 0xBFEE0000, 0xBFBCCFED,
+/**/ 0x2FE71256, 0xBD33A823,
+/**/ 0x00000000, 0x3FF1E400,
+/**/ 0x0478BBCF, 0xBF310C4C,
+/**/ 0x01BC4000, 0xBFBC8858,
+/**/ 0xC65AACD3, 0xBD2646D1,
+/**/ 0x00000000, 0x3FF1DC00,
+/**/ 0xCB840C49, 0x3F3F0ECB,
+/**/ 0x425A4000, 0xBFBC40D6,
+/**/ 0x1D1930DD, 0xBD3CB112,
+/**/ 0x00000000, 0x3FF1D800,
+/**/ 0xC9579074, 0x3F2EACE5,
+/**/ 0x769FC000, 0xBFBBF968,
+/**/ 0x8D824283, 0xBD24218C,
+/**/ 0x00000000, 0x3FF1D400,
+/**/ 0xFC60F0AE, 0xBECABDFA,
+/**/ 0x936D8000, 0xBFBBB20E,
+/**/ 0x35459B8E, 0x3D368BA8,
+/**/ 0x00000000, 0x3FF1D000,
+/**/ 0xAFDC61F3, 0xBF2F2A4B,
+/**/ 0x8DAD4000, 0xBFBB6AC8,
+/**/ 0xF50225C7, 0xBD3B1BDF,
+/**/ 0x00000000, 0x3FF1CC00,
+/**/ 0xAB802394, 0xBF3EC8AF,
+/**/ 0x5A530000, 0xBFBB2396,
+/**/ 0xEA137079, 0x3CEFF64E,
+/**/ 0x00000000, 0x3FF1C400,
+/**/ 0xCE058D9B, 0x3F322FC1,
+/**/ 0xEE5B0000, 0xBFBADC77,
+/**/ 0x09C31904, 0x3D3573B2,
+/**/ 0x00000000, 0x3FF1C000,
+/**/ 0xE0EFA2CF, 0x3F0AA04F,
+/**/ 0x3ECAC000, 0xBFBA956D,
+/**/ 0x4C02C4AF, 0xBD3E6379,
+/**/ 0x00000000, 0x3FF1BC00,
+/**/ 0x225ADFDD, 0xBF26B7F7,
+/**/ 0x40B1C000, 0xBFBA4E76,
+/**/ 0xB94407C8, 0x3D0E42B6,
+/**/ 0x00000000, 0x3FF1B800,
+/**/ 0x217CD13A, 0xBF39E073,
+/**/ 0xE9278000, 0xBFBA0792,
+/**/ 0xC9AD51BF, 0x3D0A9CE6,
+/**/ 0x00000000, 0x3FF1B000,
+/**/ 0x2BAE2B21, 0x3F37C67F,
+/**/ 0x2D4D4000, 0xBFB9C0C3,
+/**/ 0x9E838668, 0x3D3AB7C0,
+/**/ 0x00000000, 0x3FF1AC00,
+/**/ 0xBD720DCF, 0x3F23316E,
+/**/ 0x024CC000, 0xBFB97A07,
+/**/ 0x732093CE, 0x3CF8BCC1,
+/**/ 0x00000000, 0x3FF1A800,
+/**/ 0x611A7B96, 0xBF11A7B9,
+/**/ 0x5D594000, 0xBFB9335E,
+/**/ 0x3ABD47DA, 0xBD23115C,
+/**/ 0x00000000, 0x3FF1A400,
+/**/ 0xA1C1B8E7, 0xBF324195,
+/**/ 0x33AEC000, 0xBFB8ECC9,
+/**/ 0xBE67F7AA, 0x3D222F39,
+/**/ 0x00000000, 0x3FF1A000,
+/**/ 0xFEE61FEE, 0xBF3FEE61,
+/**/ 0x7A91C000, 0xBFB8A647,
+/**/ 0xAF9BD6DF, 0xBD3C28C0,
+/**/ 0x00000000, 0x3FF19800,
+/**/ 0x362B721D, 0x3F328F89,
+/**/ 0x27508000, 0xBFB85FD9,
+/**/ 0x19970C1C, 0x3D35B818,
+/**/ 0x00000000, 0x3FF19400,
+/**/ 0x28A70119, 0x3F14E023,
+/**/ 0x2F410000, 0xBFB8197E,
+/**/ 0x60D20041, 0x3D3C0FE4,
+/**/ 0x00000000, 0x3FF19000,
+/**/ 0x3E48FC6F, 0xBF1FD419,
+/**/ 0x87C28000, 0xBFB7D336,
+/**/ 0x3E706706, 0xBD33C88C,
+/**/ 0x00000000, 0x3FF18C00,
+/**/ 0xFD42546B, 0xBF34F7C6,
+/**/ 0x263D8000, 0xBFB78D02,
+/**/ 0x94B69FB7, 0xBD069B57,
+/**/ 0x00000000, 0x3FF18400,
+/**/ 0x01185E30, 0x3F3E2FA4,
+/**/ 0x00228000, 0xBFB746E1,
+/**/ 0x6E1E21D2, 0x3D3126D1,
+/**/ 0x00000000, 0x3FF18000,
+/**/ 0x11811812, 0x3F318118,
+/**/ 0x0AEAC000, 0xBFB700D3,
+/**/ 0xA99DED32, 0xBCEC1E8D,
+/**/ 0x00000000, 0x3FF17C00,
+/**/ 0xFF2E2C43, 0x3F13F1CA,
+/**/ 0x3C188000, 0xBFB6BAD8,
+/**/ 0xC08926AE, 0xBD0DAF3C,
+/**/ 0x00000000, 0x3FF17800,
+/**/ 0x0A5EF9FF, 0xBF1D79B9,
+/**/ 0x89364000, 0xBFB674F0,
+/**/ 0x4C9D3302, 0xBD3A7999,
+/**/ 0x00000000, 0x3FF17400,
+/**/ 0x1ECEA765, 0xBF338FAD,
+/**/ 0xE7D78000, 0xBFB62F1B,
+/**/ 0x7ED63C4E, 0x3D217995,
+/**/ 0x00000000, 0x3FF17000,
+/**/ 0xD8C8714B, 0xBF3F976B,
+/**/ 0x4D978000, 0xBFB5E95A,
+/**/ 0xE1D17171, 0xBD31CB7C,
+/**/ 0x00000000, 0x3FF16800,
+/**/ 0xB08FA497, 0x3F348A33,
+/**/ 0xB01AC000, 0xBFB5A3AB,
+/**/ 0x9E6AFA18, 0xBD3E2574,
+/**/ 0x00000000, 0x3FF16400,
+/**/ 0x864022C9, 0x3F21AA1F,
+/**/ 0x050E0000, 0xBFB55E10,
+/**/ 0x0C53C72E, 0xBD0C1D74,
+/**/ 0x00000000, 0x3FF16000,
+/**/ 0xB487BCAD, 0xBF05B7C9,
+/**/ 0x42260000, 0xBFB51887,
+/**/ 0x96258B3E, 0xBD330A1D,
+/**/ 0x00000000, 0x3FF15C00,
+/**/ 0x5B1E5F75, 0xBF2C3411,
+/**/ 0x5D208000, 0xBFB4D311,
+/**/ 0x82F4E1EF, 0x3CF53A25,
+/**/ 0x00000000, 0x3FF15800,
+/**/ 0xEEA99544, 0xBF39543F,
+/**/ 0x4BC30000, 0xBFB48DAE,
+/**/ 0x208C200C, 0xBD30185B,
+/**/ 0x00000000, 0x3FF15000,
+/**/ 0xDD5C8CB8, 0x3F3B9A3F,
+/**/ 0x03DBC000, 0xBFB4485E,
+/**/ 0xE8D26AB7, 0xBD3FAD46,
+/**/ 0x00000000, 0x3FF14C00,
+/**/ 0xB19AE5C7, 0x3F30B155,
+/**/ 0x7B414000, 0xBFB40320,
+/**/ 0xAA8157C0, 0xBD26FD84,
+/**/ 0x00000000, 0x3FF14800,
+/**/ 0xB34EDA32, 0x3F17C382,
+/**/ 0xA7D20000, 0xBFB3BDF5,
+/**/ 0xAD125895, 0x3D319BD0,
+/**/ 0x00000000, 0x3FF14400,
+/**/ 0xBAF129D0, 0xBF129CFF,
+/**/ 0x7F748000, 0xBFB378DD,
+/**/ 0x28F1FACA, 0xBD371411,
+/**/ 0x00000000, 0x3FF14000,
+/**/ 0x771B7C7F, 0xBF2E2E59,
+/**/ 0xF8184000, 0xBFB333D7,
+/**/ 0xA81B8848, 0x3CE692B6,
+/**/ 0x00000000, 0x3FF13C00,
+/**/ 0x30FE1D9C, 0xBF395F06,
+/**/ 0x07B40000, 0xBFB2EEE5,
+/**/ 0xDD77C860, 0xBD08081E,
+/**/ 0x00000000, 0x3FF13400,
+/**/ 0x5C81135D, 0x3F3C8113,
+/**/ 0xA4470000, 0xBFB2AA04,
+/**/ 0xA8B1CB41, 0xBD37A48B,
+/**/ 0x00000000, 0x3FF13000,
+/**/ 0xBB3B5DC0, 0x3F3288FF,
+/**/ 0xC3D8C000, 0xBFB26536,
+/**/ 0x097C5BA3, 0xBD0B4BAC,
+/**/ 0x00000000, 0x3FF12C00,
+/**/ 0xB81577AE, 0x3F21713D,
+/**/ 0x5C784000, 0xBFB2207B,
+/**/ 0xFC10C7BF, 0xBD349D8C,
+/**/ 0x00000000, 0x3FF12800,
+/**/ 0xBAD6FC84, 0xBEEE05E5,
+/**/ 0x643D0000, 0xBFB1DBD2,
+/**/ 0xD977C494, 0xBD390B24,
+/**/ 0x00000000, 0x3FF12400,
+/**/ 0x59F992BF, 0xBF24E314,
+/**/ 0xD1464000, 0xBFB1973B,
+/**/ 0x54F930B3, 0xBD3566D1,
+/**/ 0x00000000, 0x3FF12000,
+/**/ 0xC9F6E7A8, 0xBF33CB91,
+/**/ 0x99BB4000, 0xBFB152B7,
+/**/ 0x07030829, 0x3D09BB29,
+/**/ 0x00000000, 0x3FF11C00,
+/**/ 0x8B7D9851, 0xBF3CFE65,
+/**/ 0xB3CB0000, 0xBFB10E45,
+/**/ 0x284A3465, 0x3D37CF69,
+/**/ 0x00000000, 0x3FF11400,
+/**/ 0x29605DF7, 0x3F39F5DB,
+/**/ 0x15AC4000, 0xBFB0C9E6,
+/**/ 0x0974D976, 0xBD2C2DA8,
+/**/ 0x00000000, 0x3FF11000,
+/**/ 0x11111111, 0x3F311111,
+/**/ 0xB59E4000, 0xBFB08598,
+/**/ 0x7009902C, 0x3D17E5DD,
+/**/ 0x00000000, 0x3FF10C00,
+/**/ 0x12A5B1AE, 0x3F20A63A,
+/**/ 0x89E74000, 0xBFB0415D,
+/**/ 0x5CF1D753, 0xBD1111C0,
+/**/ 0x00000000, 0x3FF10800,
+/**/ 0xBE011080, 0xBED107FB,
+/**/ 0x11AB8000, 0xBFAFFA69,
+/**/ 0x98381A8F, 0xBD23008C,
+/**/ 0x00000000, 0x3FF10400,
+/**/ 0x6FEABBAE, 0xBF216989,
+/**/ 0x51800000, 0xBFAF723B,
+/**/ 0xDD5610D3, 0x3D3D6EB0,
+/**/ 0x00000000, 0x3FF10000,
+/**/ 0x10FEF011, 0xBF30FEF0,
+/**/ 0xC0068000, 0xBFAEEA31,
+/**/ 0x3606D891, 0xBD3C3DD8,
+/**/ 0x00000000, 0x3FF0FC00,
+/**/ 0x98CDDC74, 0xBF3922C0,
+/**/ 0x4A0B8000, 0xBFAE624C,
+/**/ 0x74676689, 0x3D30F25C,
+/**/ 0x00000000, 0x3FF0F400,
+/**/ 0x325A1A80, 0x3F3EDFAB,
+/**/ 0xDC680000, 0xBFADDA8A,
+/**/ 0x64D9E42F, 0x3D21B1AC,
+/**/ 0x00000000, 0x3FF0F000,
+/**/ 0xF27F9A57, 0x3F370834,
+/**/ 0x64060000, 0xBFAD52ED,
+/**/ 0x2A29BBD6, 0x3D33C85D,
+/**/ 0x00000000, 0x3FF0EC00,
+/**/ 0xD391FBC5, 0x3F2EAD7C,
+/**/ 0xCDDD8000, 0xBFACCB73,
+/**/ 0x6E09F5FE, 0xBD3965C3,
+/**/ 0x00000000, 0x3FF0E800,
+/**/ 0xE9479870, 0x3F1F2CA5,
+/**/ 0x06F70000, 0xBFAC441E,
+/**/ 0x49850D15, 0xBD354F1F,
+/**/ 0x00000000, 0x3FF0E400,
+/**/ 0x80439019, 0x3ED95609,
+/**/ 0xFC690000, 0xBFABBCEB,
+/**/ 0x8C317C2A, 0x3D17BF86,
+/**/ 0x00000000, 0x3FF0E000,
+/**/ 0xC6867596, 0xBF1B6B4D,
+/**/ 0x9B588000, 0xBFAB35DD,
+/**/ 0xD6CF558E, 0xBD3D5674,
+/**/ 0x00000000, 0x3FF0DC00,
+/**/ 0x172D4CE8, 0xBF2BEAEE,
+/**/ 0xD0FB0000, 0xBFAAAEF2,
+/**/ 0x353BB42E, 0xBD20FC1A,
+/**/ 0x00000000, 0x3FF0D800,
+/**/ 0x479071A9, 0xBF34EAB0,
+/**/ 0x8A938000, 0xBFAA282B,
+/**/ 0x80EFC8E3, 0x3D2E8F59,
+/**/ 0x00000000, 0x3FF0D400,
+/**/ 0xA61C62D3, 0xBF3BBA9C,
+/**/ 0xB5740000, 0xBFA9A187,
+/**/ 0x4EC4D90D, 0x3D30C22E,
+/**/ 0x00000000, 0x3FF0CC00,
+/**/ 0x77344011, 0x3F3D9AA6,
+/**/ 0x3EFD8000, 0xBFA91B07,
+/**/ 0x3F76CA96, 0x3D19D7C5,
+/**/ 0x00000000, 0x3FF0C800,
+/**/ 0xCDA3AC11, 0x3F3714FB,
+/**/ 0x149F8000, 0xBFA894AA,
+/**/ 0x8BE97661, 0xBD39A19A,
+/**/ 0x00000000, 0x3FF0C400,
+/**/ 0x391F2E61, 0x3F30B446,
+/**/ 0x23D90000, 0xBFA80E70,
+/**/ 0x6F28BF45, 0x3D399DC1,
+/**/ 0x00000000, 0x3FF0C000,
+/**/ 0x682E11CD, 0x3F24F0D1,
+/**/ 0x5A358000, 0xBFA78859,
+/**/ 0x083B3A4C, 0x3D108B0D,
+/**/ 0x00000000, 0x3FF0BC00,
+/**/ 0x5D5A36EA, 0x3F118519,
+/**/ 0xA5510000, 0xBFA70265,
+/**/ 0x11FD5CE7, 0x3D2888DF,
+/**/ 0x00000000, 0x3FF0B800,
+/**/ 0x62386CAB, 0xBEF913DA,
+/**/ 0xF2D48000, 0xBFA67C94,
+/**/ 0x827CCA0C, 0xBD3DAC20,
+/**/ 0x00000000, 0x3FF0B400,
+/**/ 0xBD31D7D0, 0xBF1D7CFF,
+/**/ 0x30790000, 0xBFA5F6E7,
+/**/ 0x8012494C, 0x3D20485A,
+/**/ 0x00000000, 0x3FF0B000,
+/**/ 0x226951DC, 0xBF2A11BA,
+/**/ 0x4C040000, 0xBFA5715C,
+/**/ 0xDFC47628, 0x3D38888D,
+/**/ 0x00000000, 0x3FF0AC00,
+/**/ 0x7B2E9DD2, 0xBF328E31,
+/**/ 0x334A0000, 0xBFA4EBF4,
+/**/ 0xF73BE773, 0x3D2D9150,
+/**/ 0x00000000, 0x3FF0A800,
+/**/ 0x7EF597EF, 0xBF37EF59,
+/**/ 0xD42E0000, 0xBFA466AE,
+/**/ 0x75BDFD28, 0x3D2C1673,
+/**/ 0x00000000, 0x3FF0A400,
+/**/ 0x50D413C1, 0xBF3D2C71,
+/**/ 0x1CA08000, 0xBFA3E18C,
+/**/ 0x3F6E378E, 0xBD3748ED,
+/**/ 0x00000000, 0x3FF09C00,
+/**/ 0xF836010A, 0x3F3DBA6A,
+/**/ 0xFAA10000, 0xBFA35C8B,
+/**/ 0x5EF9EB35, 0xBD38357D,
+/**/ 0x00000000, 0x3FF09800,
+/**/ 0x624D4AF5, 0x3F38C51F,
+/**/ 0x5C3C8000, 0xBFA2D7AE,
+/**/ 0x459DA66D, 0x3D322939,
+/**/ 0x00000000, 0x3FF09400,
+/**/ 0x10953F39, 0x3F33F390,
+/**/ 0x2F8D0000, 0xBFA252F3,
+/**/ 0xE021B67B, 0xBD283E9A,
+/**/ 0x00000000, 0x3FF09000,
+/**/ 0x861539B9, 0x3F2E8B42,
+/**/ 0x62BC0000, 0xBFA1CE5A,
+/**/ 0x8D8DF999, 0xBD3A9CC7,
+/**/ 0x00000000, 0x3FF08C00,
+/**/ 0xACBC4021, 0x3F25766E,
+/**/ 0xE4008000, 0xBFA149E3,
+/**/ 0x9A4168FD, 0x3D32B98A,
+/**/ 0x00000000, 0x3FF08800,
+/**/ 0x0F3DBD5A, 0x3F1950DB,
+/**/ 0xA19E0000, 0xBFA0C58F,
+/**/ 0x58B17913, 0x3D0559D1,
+/**/ 0x00000000, 0x3FF08400,
+/**/ 0x08421084, 0x3F008421,
+/**/ 0x89E78000, 0xBFA0415D,
+/**/ 0xF461C516, 0x3D3DDDC7,
+/**/ 0x00000000, 0x3FF08000,
+/**/ 0x0041FF7C, 0xBF007FDF,
+/**/ 0x16780000, 0xBF9F7A9B,
+/**/ 0x271BE7D7, 0xBD242AD9,
+/**/ 0x00000000, 0x3FF07C00,
+/**/ 0xC54798FB, 0xBF183591,
+/**/ 0x28140000, 0xBF9E72BF,
+/**/ 0x49774D47, 0x3D28D751,
+/**/ 0x00000000, 0x3FF07800,
+/**/ 0x518F4EFD, 0xBF23CFA1,
+/**/ 0x25980000, 0xBF9D6B27,
+/**/ 0x50D1B838, 0x3D39FF7B,
+/**/ 0x00000000, 0x3FF07400,
+/**/ 0x01073261, 0xBF2B3EB7,
+/**/ 0xEC150000, 0xBF9C63D2,
+/**/ 0xE030A687, 0x3D35439C,
+/**/ 0x00000000, 0x3FF07000,
+/**/ 0xD6EAB025, 0xBF31341F,
+/**/ 0x58B70000, 0xBF9B5CC2,
+/**/ 0xB8AFBFE8, 0xBD18E611,
+/**/ 0x00000000, 0x3FF06C00,
+/**/ 0x6ED049E0, 0xBF34A638,
+/**/ 0x48C60000, 0xBF9A55F5,
+/**/ 0x9F2D03C9, 0x3D2DE070,
+/**/ 0x00000000, 0x3FF06800,
+/**/ 0xEF997F5C, 0xBF37F5BF,
+/**/ 0x99A20000, 0xBF994F6B,
+/**/ 0xF96CF7F5, 0xBD311D5E,
+/**/ 0x00000000, 0x3FF06400,
+/**/ 0xE5604189, 0xBF3B22D0,
+/**/ 0x28C90000, 0xBF984925,
+/**/ 0x325A0C34, 0x3D2AA0BA,
+/**/ 0x00000000, 0x3FF06000,
+/**/ 0xC1163FF0, 0xBF3E2D85,
+/**/ 0xD3D00000, 0xBF974321,
+/**/ 0x0FE94778, 0xBCFB4A69,
+/**/ 0x00000000, 0x3FF05800,
+/**/ 0x27586632, 0x3F3EEA07,
+/**/ 0x78690000, 0xBF963D61,
+/**/ 0x89596542, 0xBD07ABF3,
+/**/ 0x00000000, 0x3FF05400,
+/**/ 0x98E2A5E7, 0x3F3C23BB,
+/**/ 0xF45F0000, 0xBF9537E3,
+/**/ 0xD2D7F253, 0xBD2AB259,
+/**/ 0x00000000, 0x3FF05000,
+/**/ 0x73404146, 0x3F397F7D,
+/**/ 0x25980000, 0xBF9432A9,
+/**/ 0x928637FE, 0xBD098139,
+/**/ 0x00000000, 0x3FF04C00,
+/**/ 0xB0C7B49A, 0x3F36FD32,
+/**/ 0xEA130000, 0xBF932DB0,
+/**/ 0x130895FC, 0xBD2710CB,
+/**/ 0x00000000, 0x3FF04800,
+/**/ 0x664C578A, 0x3F349CC1,
+/**/ 0x1FEA0000, 0xBF9228FB,
+/**/ 0x284991FE, 0xBD2713E3,
+/**/ 0x00000000, 0x3FF04400,
+/**/ 0xC2FCB1F4, 0x3F325E0F,
+/**/ 0xA5500000, 0xBF912487,
+/**/ 0xFED4B393, 0xBD3FDBE5,
+/**/ 0x00000000, 0x3FF04000,
+/**/ 0x10410410, 0x3F304104,
+/**/ 0x58930000, 0xBF902056,
+/**/ 0x7C8E8417, 0xBD3611D2,
+/**/ 0x00000000, 0x3FF03C00,
+/**/ 0x6334030B, 0x3F2C8B09,
+/**/ 0x30340000, 0xBF8E38CE,
+/**/ 0xA3DA281A, 0x3D39DE88,
+/**/ 0x00000000, 0x3FF03800,
+/**/ 0x48FF7E3A, 0x3F28D6F0,
+/**/ 0x84C80000, 0xBF8C3173,
+/**/ 0xFCEFB9FE, 0x3D341F33,
+/**/ 0x00000000, 0x3FF03400,
+/**/ 0x0081A559, 0x3F25658A,
+/**/ 0x6C180000, 0xBF8A2A9C,
+/**/ 0x4D6D3472, 0x3D3F73BC,
+/**/ 0x00000000, 0x3FF03000,
+/**/ 0xEBC349DE, 0x3F2236A3,
+/**/ 0xA3880000, 0xBF882448,
+/**/ 0x12C584E0, 0xBD345544,
+/**/ 0x00000000, 0x3FF02C00,
+/**/ 0x3FEFD386, 0x3F1E9417,
+/**/ 0xE8B60000, 0xBF861E77,
+/**/ 0xEAF8EAF3, 0x3D38073E,
+/**/ 0x00000000, 0x3FF02800,
+/**/ 0xCA7A317C, 0x3F193F1D,
+/**/ 0xF9680000, 0xBF841929,
+/**/ 0x55D01368, 0xBD1977C7,
+/**/ 0x00000000, 0x3FF02400,
+/**/ 0x6CB49652, 0x3F146DF7,
+/**/ 0x939E0000, 0xBF82145E,
+/**/ 0x38C4EA00, 0xBD3E3D12,
+/**/ 0x00000000, 0x3FF02000,
+/**/ 0x81020408, 0x3F102040,
+/**/ 0x75880000, 0xBF801015,
+/**/ 0x1998B506, 0xBD3BCE25,
+/**/ 0x00000000, 0x3FF01C00,
+/**/ 0x8C355D63, 0x3F08AB2B,
+/**/ 0xBB100000, 0xBF7C189C,
+/**/ 0x12588560, 0x3D3D8055,
+/**/ 0x00000000, 0x3FF01800,
+/**/ 0xBD1BA97E, 0x3F021B28,
+/**/ 0x14580000, 0xBF781212,
+/**/ 0x82973F27, 0xBD1AD503,
+/**/ 0x00000000, 0x3FF01400,
+/**/ 0x411155AB, 0x3EF91F67,
+/**/ 0x74780000, 0xBF740C8A,
+/**/ 0xDF070002, 0xBD1E3871,
+/**/ 0x00000000, 0x3FF01000,
+/**/ 0x10101010, 0x3EF01010,
+/**/ 0x59580000, 0xBF700805,
+/**/ 0xCB31C67B, 0xBD2166AF,
+/**/ 0x00000000, 0x3FF00C00,
+/**/ 0x279DB649, 0x3EE20D8A,
+/**/ 0x82880000, 0xBF680904,
+/**/ 0x96A70C0C, 0xBD285C06,
+/**/ 0x00000000, 0x3FF00800,
+/**/ 0x02010080, 0x3ED00804,
+/**/ 0x55D80000, 0xBF600401,
+/**/ 0xC7CC7089, 0x3D33BB10,
+/**/ 0x00000000, 0x3FF00400,
+/**/ 0x00401004, 0x3EB00401,
+/**/ 0x55600000, 0xBF500200,
+/**/ 0xCD5F35F8, 0xBD356224,
+/**/ 0x00000000, 0x3FF00000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00000000, 0x3FEFF800,
+/**/ 0xFF801FF8, 0x3EAFF801,
+/**/ 0xAA800000, 0x3F4FFC00,
+/**/ 0x7809A0A3, 0x3D35621F,
+/**/ 0x00000000, 0x3FEFF000,
+/**/ 0xFC01FF00, 0x3ECFF007,
+/**/ 0xA9B00000, 0x3F5FF802,
+/**/ 0x1D61C5EB, 0xBD33BC66,
+/**/ 0x00000000, 0x3FEFE800,
+/**/ 0x186DADBE, 0x3EE1F28A,
+/**/ 0x7D780000, 0x3F67F704,
+/**/ 0x89D68648, 0x3D283DA6,
+/**/ 0x00000000, 0x3FEFE000,
+/**/ 0xE01FE020, 0x3EEFE01F,
+/**/ 0xA2B00000, 0x3F6FF00A,
+/**/ 0xA086B56A, 0x3D20BC04,
+/**/ 0x00000000, 0x3FEFD800,
+/**/ 0xDF68BD14, 0x3EF8E0E6,
+/**/ 0x60F00000, 0x3F73F38A,
+/**/ 0x93C93749, 0x3D192256,
+/**/ 0x00000000, 0x3FEFD000,
+/**/ 0x439A981C, 0x3F01E528,
+/**/ 0xEBD80000, 0x3F77EE11,
+/**/ 0xC2D23A07, 0x3D0749D3,
+/**/ 0x00000000, 0x3FEFC800,
+/**/ 0x8596391C, 0x3F08556A,
+/**/ 0x70040000, 0x3F7BE79C,
+/**/ 0x9A6C0404, 0x3D38EC8F,
+/**/ 0x00000000, 0x3FEFC000,
+/**/ 0x01FC07F0, 0x3F0FC07F,
+/**/ 0x6B100000, 0x3F7FE02A,
+/**/ 0x0DDA40E4, 0x3D19E23F,
+/**/ 0x00000000, 0x3FEFB800,
+/**/ 0x9F5976B5, 0x3F1412D5,
+/**/ 0x2D1A0000, 0x3F81EBDE,
+/**/ 0xFF48DC36, 0xBD2A0683,
+/**/ 0x00000000, 0x3FEFB000,
+/**/ 0xBD271E34, 0x3F18C21A,
+/**/ 0x5D260000, 0x3F83E729,
+/**/ 0xFF29A114, 0xBD2609C1,
+/**/ 0x00000000, 0x3FEFA800,
+/**/ 0x5594A734, 0x3F1DEDB2,
+/**/ 0x03EC0000, 0x3F85E1F7,
+/**/ 0xF585DA1B, 0x3D37CA09,
+/**/ 0x00000000, 0x3FEFA000,
+/**/ 0x1FA11CAA, 0x3F21CAA0,
+/**/ 0x5F820000, 0x3F87DC47,
+/**/ 0x5B5DA1F5, 0xBD3EB124,
+/**/ 0x00000000, 0x3FEF9800,
+/**/ 0x55E8CB6B, 0x3F24DC34,
+/**/ 0xADC60000, 0x3F89D61A,
+/**/ 0x327B4257, 0x3D37B196,
+/**/ 0x00000000, 0x3FEF9000,
+/**/ 0x13BAF1B2, 0x3F282B68,
+/**/ 0x2C740000, 0x3F8BCF71,
+/**/ 0x97BD9771, 0x3D1C25E0,
+/**/ 0x00000000, 0x3FEF8800,
+/**/ 0xCC420861, 0x3F2BB80D,
+/**/ 0x19120000, 0x3F8DC84B,
+/**/ 0x1E3A5B30, 0x3D1C0A54,
+/**/ 0x00000000, 0x3FEF8000,
+/**/ 0x1F81F820, 0x3F2F81F8,
+/**/ 0xB0FC0000, 0x3F8FC0A8,
+/**/ 0xF6D3A69C, 0x3CDF1E7C,
+/**/ 0x00000000, 0x3FEF7800,
+/**/ 0xED1079FA, 0x3F31C47C,
+/**/ 0x18B00000, 0x3F90DC45,
+/**/ 0x380313FC, 0xBD29BC2F,
+/**/ 0x00000000, 0x3FEF7000,
+/**/ 0xFA98528D, 0x3F33E672,
+/**/ 0xEB9F0000, 0x3F91D7F7,
+/**/ 0x83FCC7A6, 0xBD14193A,
+/**/ 0x00000000, 0x3FEF6800,
+/**/ 0xCAFBD3D2, 0x3F3626C7,
+/**/ 0xEFB50000, 0x3F92D36C,
+/**/ 0x341706C3, 0x3D35F0BB,
+/**/ 0x00000000, 0x3FEF6000,
+/**/ 0x06DDABA6, 0x3F388565,
+/**/ 0x43470000, 0x3F93CEA4,
+/**/ 0x32D6A40B, 0xBD36A2C4,
+/**/ 0x00000000, 0x3FEF5800,
+/**/ 0x6CC4F5F5, 0x3F3B0234,
+/**/ 0x04900000, 0x3F94C99E,
+/**/ 0x5DF5F4A5, 0x3D1DECC6,
+/**/ 0x00000000, 0x3FEF5000,
+/**/ 0xD102728A, 0x3F3D9D1F,
+/**/ 0x51B90000, 0x3F95C45A,
+/**/ 0x216D87D8, 0xBD263BB6,
+/**/ 0x00000000, 0x3FEF5000,
+/**/ 0xE26A1DD4, 0xBF3FA9EE,
+/**/ 0x48D20000, 0x3F96BED9,
+/**/ 0x160A43F8, 0xBD320BC4,
+/**/ 0x00000000, 0x3FEF4800,
+/**/ 0xADEC7540, 0xBF3CD30D,
+/**/ 0x07D60000, 0x3F97B91B,
+/**/ 0xB602ACE4, 0xBD33B955,
+/**/ 0x00000000, 0x3FEF4000,
+/**/ 0x7C761DC6, 0xBF39DE52,
+/**/ 0xACAA0000, 0x3F98B31F,
+/**/ 0xA96E4964, 0xBD33FC78,
+/**/ 0x00000000, 0x3FEF3800,
+/**/ 0x23989FF0, 0xBF36CBD3,
+/**/ 0x551D0000, 0x3F99ACE7,
+/**/ 0x7EC7C410, 0xBD2D75D9,
+/**/ 0x00000000, 0x3FEF3000,
+/**/ 0x639F8B15, 0xBF339BA5,
+/**/ 0x1EE80000, 0x3F9AA672,
+/**/ 0x5C5AF494, 0x3D2AD4EB,
+/**/ 0x00000000, 0x3FEF2800,
+/**/ 0xE7AA579B, 0xBF304DDE,
+/**/ 0x27B00000, 0x3F9B9FC0,
+/**/ 0x0AE6922A, 0xBD3B9A01,
+/**/ 0x00000000, 0x3FEF2000,
+/**/ 0x8B8C46FD, 0xBF29C52A,
+/**/ 0x8D010000, 0x3F9C98D1,
+/**/ 0x0589DF0F, 0xBD2BF615,
+/**/ 0x00000000, 0x3FEF1800,
+/**/ 0xFE0E92B4, 0xBF22B3BB,
+/**/ 0x6C540000, 0x3F9D91A6,
+/**/ 0x658CFB9A, 0x3D2E61F1,
+/**/ 0x00000000, 0x3FEF1000,
+/**/ 0xFE8B488E, 0xBF16CF39,
+/**/ 0xE30D0000, 0x3F9E8A3E,
+/**/ 0x3DE53900, 0xBD21A9FA,
+/**/ 0x00000000, 0x3FEF0800,
+/**/ 0xF07C1F08, 0xBEFF07C1,
+/**/ 0x0E780000, 0x3F9F829B,
+/**/ 0x7C7E09E4, 0x3D298026,
+/**/ 0x00000000, 0x3FEF0000,
+/**/ 0x007C00F8, 0x3EFF003E,
+/**/ 0x85E70000, 0x3FA03D5D,
+/**/ 0x60ED29CF, 0x3D3F7789,
+/**/ 0x00000000, 0x3FEEF800,
+/**/ 0x3D759870, 0x3F17B671,
+/**/ 0x7C198000, 0x3FA0B94F,
+/**/ 0x6F022783, 0xBD2E8989,
+/**/ 0x00000000, 0x3FEEF000,
+/**/ 0x2A8BB96A, 0x3F241070,
+/**/ 0x78598000, 0x3FA13523,
+/**/ 0xB71FA59B, 0xBD1C1AC3,
+/**/ 0x00000000, 0x3FEEE800,
+/**/ 0x58E01EEA, 0x3F2C7F84,
+/**/ 0x89240000, 0x3FA1B0D9,
+/**/ 0x9AE889BB, 0xBD33401E,
+/**/ 0x00000000, 0x3FEEE000,
+/**/ 0xA3D491BC, 0x3F329425,
+/**/ 0xBCEA8000, 0x3FA22C71,
+/**/ 0xF87F888F, 0x3CFD2818,
+/**/ 0x00000000, 0x3FEED800,
+/**/ 0x9E9D2AE8, 0x3F37054D,
+/**/ 0x22150000, 0x3FA2A7EC,
+/**/ 0x7A9163FE, 0xBD278CE7,
+/**/ 0x00000000, 0x3FEED000,
+/**/ 0x540C85E6, 0x3F3B9325,
+/**/ 0xC7000000, 0x3FA32348,
+/**/ 0x90B1E49F, 0x3D2696DB,
+/**/ 0x00000000, 0x3FEED000,
+/**/ 0xF099FC26, 0xBF3FC267,
+/**/ 0xB9FE8000, 0x3FA39E87,
+/**/ 0x80AD9015, 0x3D3EAFD4,
+/**/ 0x00000000, 0x3FEEC800,
+/**/ 0xD02A4E5D, 0xBF3AFB6E,
+/**/ 0x09590000, 0x3FA419A9,
+/**/ 0x67D48EA7, 0x3D3B5CDC,
+/**/ 0x00000000, 0x3FEEC000,
+/**/ 0xD7A79FF1, 0xBF361803,
+/**/ 0xC34D8000, 0x3FA494AC,
+/**/ 0xA56FD247, 0x3D211C78,
+/**/ 0x00000000, 0x3FEEB800,
+/**/ 0x805C2197, 0xBF31183B,
+/**/ 0xF60F8000, 0x3FA50F92,
+/**/ 0x0A91FFE3, 0x3D296CFB,
+/**/ 0x00000000, 0x3FEEB000,
+/**/ 0x5FE15180, 0xBF27F854,
+/**/ 0xAFC90000, 0x3FA58A5B,
+/**/ 0x9570AD39, 0xBD2B2B73,
+/**/ 0x00000000, 0x3FEEA800,
+/**/ 0xE210C36A, 0xBF1B0F90,
+/**/ 0xFE990000, 0x3FA60506,
+/**/ 0x8194E036, 0xBD32BA40,
+/**/ 0x00000000, 0x3FEEA000,
+/**/ 0x8C33ADB2, 0xBEF6F7DD,
+/**/ 0xF0948000, 0x3FA67F94,
+/**/ 0x3E7E4ED7, 0x3D3ECC1F,
+/**/ 0x00000000, 0x3FEE9800,
+/**/ 0x1003D310, 0x3F1003D3,
+/**/ 0x93C78000, 0x3FA6FA05,
+/**/ 0x41D634A1, 0x3D3B415E,
+/**/ 0x00000000, 0x3FEE9000,
+/**/ 0x0B7672A0, 0x3F231ABF,
+/**/ 0xF6330000, 0x3FA77458,
+/**/ 0xE586AF09, 0xBD3181DC,
+/**/ 0x00000000, 0x3FEE8800,
+/**/ 0xCF172481, 0x3F2E6B5C,
+/**/ 0x25CD8000, 0x3FA7EE8F,
+/**/ 0x11A5C1E9, 0xBD3F4216,
+/**/ 0x00000000, 0x3FEE8000,
+/**/ 0x77A84876, 0x3F34F9CD,
+/**/ 0x30840000, 0x3FA868A8,
+/**/ 0x134AC693, 0xBD12623A,
+/**/ 0x00000000, 0x3FEE7800,
+/**/ 0xD7473427, 0x3F3AD9A8,
+/**/ 0x243A0000, 0x3FA8E2A4,
+/**/ 0x01426490, 0x3D2B9EEB,
+/**/ 0x00000000, 0x3FEE7800,
+/**/ 0x4578DCCA, 0xBF3F2AD3,
+/**/ 0x0EC90000, 0x3FA95C83,
+/**/ 0x97C5FEB8, 0xBD2C1482,
+/**/ 0x00000000, 0x3FEE7000,
+/**/ 0x97A6A035, 0xBF3913BA,
+/**/ 0xFDFF8000, 0x3FA9D644,
+/**/ 0x539A473B, 0x3D313C90,
+/**/ 0x00000000, 0x3FEE6800,
+/**/ 0xC594A915, 0xBF32E120,
+/**/ 0xFFA40000, 0x3FAA4FE9,
+/**/ 0xA0402925, 0xBD36E584,
+/**/ 0x00000000, 0x3FEE6000,
+/**/ 0xC5DF4232, 0xBF292632,
+/**/ 0x21710000, 0x3FAAC972,
+/**/ 0xF013222C, 0x3D2F8D3E,
+/**/ 0x00000000, 0x3FEE5800,
+/**/ 0xC3518A6E, 0xBF18A6DF,
+/**/ 0x71198000, 0x3FAB42DD,
+/**/ 0xE5D6704C, 0xBD1C827A,
+/**/ 0x00000000, 0x3FEE5000,
+/**/ 0x86833271, 0x3ED6BC08,
+/**/ 0xFC450000, 0x3FABBC2B,
+/**/ 0x91417DAF, 0xBD17D186,
+/**/ 0x00000000, 0x3FEE4800,
+/**/ 0xE672838D, 0x3F1BEB2D,
+/**/ 0xD0920000, 0x3FAC355D,
+/**/ 0x9ABF8388, 0x3D2F2CCC,
+/**/ 0x00000000, 0x3FEE4000,
+/**/ 0x9785150A, 0x3F2B6B8D,
+/**/ 0xFB960000, 0x3FACAE72,
+/**/ 0x2025B1BE, 0xBD3EFABF,
+/**/ 0x00000000, 0x3FEE3800,
+/**/ 0xE0D399FA, 0x3F348BCE,
+/**/ 0x8ADB0000, 0x3FAD276B,
+/**/ 0xC78A64B0, 0x3D16A423,
+/**/ 0x00000000, 0x3FEE3000,
+/**/ 0x933AC00F, 0x3F3B7CD0,
+/**/ 0x8BE38000, 0x3FADA047,
+/**/ 0xB1F6FE05, 0x3D2252C7,
+/**/ 0x00000000, 0x3FEE3000,
+/**/ 0x308F5281, 0xBF3D7747,
+/**/ 0x0C278000, 0x3FAE1907,
+/**/ 0x64629E86, 0xBD2FEA46,
+/**/ 0x00000000, 0x3FEE2800,
+/**/ 0x6C196F66, 0xBF36508B,
+/**/ 0x19150000, 0x3FAE91AA,
+/**/ 0x1DCC6A76, 0xBD0E82A0,
+/**/ 0x00000000, 0x3FEE2000,
+/**/ 0x1E1E1E1E, 0xBF2E1E1E,
+/**/ 0xC0118000, 0x3FAF0A30,
+/**/ 0x83368E91, 0xBD2D599E,
+/**/ 0x00000000, 0x3FEE1800,
+/**/ 0xDD355CDB, 0xBF1ECB93,
+/**/ 0x0E780000, 0x3FAF829B,
+/**/ 0x7C7E09E4, 0x3D398026,
+/**/ 0x00000000, 0x3FEE1000,
+/**/ 0x7C01E100, 0xBECE0FF8,
+/**/ 0x119B8000, 0x3FAFFAE9,
+/**/ 0x4262C554, 0x3D230337,
+/**/ 0x00000000, 0x3FEE0800,
+/**/ 0x25C73724, 0x3F1D54B5,
+/**/ 0x6B624000, 0x3FB0398D,
+/**/ 0xFCBFCD00, 0xBD3AB14D,
+/**/ 0x00000000, 0x3FEE0000,
+/**/ 0x1E01E01E, 0x3F2E01E0,
+/**/ 0x35990000, 0x3FB07598,
+/**/ 0xE4B59987, 0xBD3B8ECF,
+/**/ 0x00000000, 0x3FEDF800,
+/**/ 0xC84194BA, 0x3F36C715,
+/**/ 0xEE0D0000, 0x3FB0B194,
+/**/ 0x4F69EDCC, 0x3D3666EA,
+/**/ 0x00000000, 0x3FEDF000,
+/**/ 0xEF26D838, 0x3F3EA78B,
+/**/ 0x9B554000, 0x3FB0ED83,
+/**/ 0x6D48ABB4, 0xBD3901F4,
+/**/ 0x00000000, 0x3FEDF000,
+/**/ 0xF10995DC, 0xBF395DBF,
+/**/ 0x44030000, 0x3FB12964,
+/**/ 0x751AA773, 0xBD3D53BB,
+/**/ 0x00000000, 0x3FEDE800,
+/**/ 0x3BCBADC8, 0xBF3148E0,
+/**/ 0xEEA38000, 0x3FB16536,
+/**/ 0x768FA309, 0xBD147C5E,
+/**/ 0x00000000, 0x3FEDE000,
+/**/ 0x86E25CE1, 0xBF2233CE,
+/**/ 0xA1BF8000, 0x3FB1A0FB,
+/**/ 0xC319D6DC, 0x3D24A3FC,
+/**/ 0x00000000, 0x3FEDD800,
+/**/ 0x26B3FE23, 0xBEEA1CE9,
+/**/ 0x63DB0000, 0x3FB1DCB2,
+/**/ 0x5E9E8981, 0x3D39444F,
+/**/ 0x00000000, 0x3FEDD000,
+/**/ 0x0AB71710, 0x3F1E4836,
+/**/ 0x3B75C000, 0x3FB2185B,
+/**/ 0xF8F32304, 0xBD3E3189,
+/**/ 0x00000000, 0x3FEDC800,
+/**/ 0x00EE500F, 0x3F300EE5,
+/**/ 0x2F0A0000, 0x3FB253F6,
+/**/ 0xFB69A701, 0x3D3416F8,
+/**/ 0x00000000, 0x3FEDC000,
+/**/ 0x231C226A, 0x3F38A58D,
+/**/ 0x450EC000, 0x3FB28F83,
+/**/ 0xAA119769, 0x3D3A8D75,
+/**/ 0x00000000, 0x3FEDC000,
+/**/ 0x14715D63, 0xBF3EAA0C,
+/**/ 0x83F5C000, 0x3FB2CB02,
+/**/ 0xCA657021, 0x3D3E1EE2,
+/**/ 0x00000000, 0x3FEDB800,
+/**/ 0x92AEFFC5, 0xBF35DFF8,
+/**/ 0xF22C8000, 0x3FB30673,
+/**/ 0x9DCF0BA5, 0x3D24C9E2,
+/**/ 0x00000000, 0x3FEDB000,
+/**/ 0x67E251A0, 0xBF29F894,
+/**/ 0x961BC000, 0x3FB341D7,
+/**/ 0x99837610, 0x3D31D092,
+/**/ 0x00000000, 0x3FEDA800,
+/**/ 0x1FF89620, 0xBF0FF896,
+/**/ 0x76284000, 0x3FB37D2D,
+/**/ 0x9B7FF15C, 0xBD2C60AA,
+/**/ 0x00000000, 0x3FEDA000,
+/**/ 0x076828BD, 0x3F145E70,
+/**/ 0x98B1C000, 0x3FB3B875,
+/**/ 0x94ACA313, 0xBD222415,
+/**/ 0x00000000, 0x3FED9800,
+/**/ 0xE567D573, 0x3F2C8F60,
+/**/ 0x04140000, 0x3FB3F3B0,
+/**/ 0xACDFCEC5, 0x3CEE2474,
+/**/ 0x00000000, 0x3FED9000,
+/**/ 0xF3FC4DA2, 0x3F379118,
+/**/ 0xBEA64000, 0x3FB42EDC,
+/**/ 0xEA7C9ACD, 0x3D1BC0EE,
+/**/ 0x00000000, 0x3FED9000,
+/**/ 0x049DE4C3, 0xBF3F0C3C,
+/**/ 0xCEBB4000, 0x3FB469FB,
+/**/ 0x4F257194, 0x3D3B663C,
+/**/ 0x00000000, 0x3FED8800,
+/**/ 0xF13D5906, 0xBF35905F,
+/**/ 0x3AA1C000, 0x3FB4A50D,
+/**/ 0x308973E2, 0xBD2F7FE1,
+/**/ 0x00000000, 0x3FED8000,
+/**/ 0x77D1EA57, 0xBF27F6C8,
+/**/ 0x08A34000, 0x3FB4E011,
+/**/ 0xDF2C5AE5, 0x3D3AE5CF,
+/**/ 0x00000000, 0x3FED7800,
+/**/ 0xF4F31BA0, 0xBF026AD1,
+/**/ 0x3F060000, 0x3FB51B07,
+/**/ 0x278E686A, 0x3D383F69,
+/**/ 0x00000000, 0x3FED7000,
+/**/ 0xF26DF1BD, 0x3F1DE6B2,
+/**/ 0xE40B4000, 0x3FB555EF,
+/**/ 0x8C868E23, 0x3D30B497,
+/**/ 0x00000000, 0x3FED6800,
+/**/ 0x7BA23D96, 0x3F31599F,
+/**/ 0xFDF00000, 0x3FB590CA,
+/**/ 0x5722ABAA, 0x3D3C284F,
+/**/ 0x00000000, 0x3FED6000,
+/**/ 0xD425A760, 0x3F3B526C,
+/**/ 0x92ED4000, 0x3FB5CB98,
+/**/ 0xA64FC52F, 0x3D17BE44,
+/**/ 0x00000000, 0x3FED6000,
+/**/ 0x546A6FF1, 0xBF3A9BFC,
+/**/ 0xA9374000, 0x3FB60658,
+/**/ 0xDEE9C4F8, 0x3D30C3B1,
+/**/ 0x00000000, 0x3FED5800,
+/**/ 0x08F02FAC, 0xBF3071AD,
+/**/ 0x46FE8000, 0x3FB6410B,
+/**/ 0x3CBD8D14, 0xBD153F8F,
+/**/ 0x00000000, 0x3FED5000,
+/**/ 0x12C6C142, 0xBF18BAD9,
+/**/ 0x726EC000, 0x3FB67BB0,
+/**/ 0x69EF5912, 0x3CEF724B,
+/**/ 0x00000000, 0x3FED4800,
+/**/ 0x3254A5A2, 0x3F10B35C,
+/**/ 0x31B00000, 0x3FB6B648,
+/**/ 0x1377DE92, 0xBD3BF30A,
+/**/ 0x00000000, 0x3FED4000,
+/**/ 0x1D41D41D, 0x3F2D41D4,
+/**/ 0x8AE58000, 0x3FB6F0D2,
+/**/ 0x1B664613, 0xBD34B464,
+/**/ 0x00000000, 0x3FED3800,
+/**/ 0xF494E548, 0x3F392D71,
+/**/ 0x842EC000, 0x3FB72B4F,
+/**/ 0xC00C9DD3, 0xBD3704CC,
+/**/ 0x00000000, 0x3FED3800,
+/**/ 0xFF165C2E, 0xBF3C2DA1,
+/**/ 0x23A6C000, 0x3FB765BF,
+/**/ 0x35C4256A, 0xBCFECBC0,
+/**/ 0x00000000, 0x3FED3000,
+/**/ 0x7AA49674, 0xBF317062,
+/**/ 0x6F648000, 0x3FB7A021,
+/**/ 0xA18418FF, 0x3D3E124C,
+/**/ 0x00000000, 0x3FED2800,
+/**/ 0x749CB290, 0xBF1A6B80,
+/**/ 0x6D7B0000, 0x3FB7DA76,
+/**/ 0x4480C89B, 0x3D32CC84,
+/**/ 0x00000000, 0x3FED2000,
+/**/ 0x25C6336D, 0x3F114B52,
+/**/ 0x23F8C000, 0x3FB814BE,
+/**/ 0xDA82FDFD, 0x3CCB2381,
+/**/ 0x00000000, 0x3FED1800,
+/**/ 0xF08A3B1D, 0x3F2EB155,
+/**/ 0x98E84000, 0x3FB84EF8,
+/**/ 0x246977C9, 0xBD37D5CD,
+/**/ 0x00000000, 0x3FED1000,
+/**/ 0xBD71CD93, 0x3F3A7692,
+/**/ 0xD24FC000, 0x3FB88925,
+/**/ 0x44FBB806, 0xBD31D505,
+/**/ 0x00000000, 0x3FED1000,
+/**/ 0x89FC5E69, 0xBF3A5384,
+/**/ 0xD6318000, 0x3FB8C345,
+/**/ 0xACB42A66, 0x3D3B20F5,
+/**/ 0x00000000, 0x3FED0800,
+/**/ 0x6439240E, 0xBF2E0B56,
+/**/ 0xAA8C4000, 0x3FB8FD58,
+/**/ 0x1BCB725B, 0xBD3EEC90,
+/**/ 0x00000000, 0x3FED0000,
+/**/ 0x01CFF8C0, 0xBF0CFF8C,
+/**/ 0x55594000, 0x3FB9375E,
+/**/ 0x7380C364, 0x3D3EDDC3,
+/**/ 0x00000000, 0x3FECF800,
+/**/ 0x546D8D78, 0x3F1F7661,
+/**/ 0xDC8F8000, 0x3FB97156,
+/**/ 0x9AFDB97B, 0xBD3C1FC1,
+/**/ 0x00000000, 0x3FECF000,
+/**/ 0x25FE30D9, 0x3F3372E2,
+/**/ 0x46204000, 0x3FB9AB42,
+/**/ 0x26787061, 0xBD28A648,
+/**/ 0x00000000, 0x3FECE800,
+/**/ 0xD92305A6, 0x3F3F1FDB,
+/**/ 0x97F9C000, 0x3FB9E520,
+/**/ 0xB52DD050, 0x3D235FAC,
+/**/ 0x00000000, 0x3FECE800,
+/**/ 0x9C37FC63, 0xBF351B8A,
+/**/ 0xD8060000, 0x3FBA1EF1,
+/**/ 0x6DF97BCB, 0x3D3CD417,
+/**/ 0x00000000, 0x3FECE000,
+/**/ 0x6CB725AB, 0xBF227EC2,
+/**/ 0x0C2B4000, 0x3FBA58B6,
+/**/ 0x5C5C9F2A, 0xBD3CDC73,
+/**/ 0x00000000, 0x3FECD800,
+/**/ 0xE6C2B448, 0x3F05A240,
+/**/ 0x3A4AC000, 0x3FBA926D,
+/**/ 0x0BD22A9C, 0x3D356365,
+/**/ 0x00000000, 0x3FECD000,
+/**/ 0xFBB8D9F3, 0x3F2D7EC2,
+/**/ 0x68434000, 0x3FBACC17,
+/**/ 0xA0B7FA4C, 0xBD2AA783,
+/**/ 0x00000000, 0x3FECC800,
+/**/ 0x1B71D3E9, 0x3F3AE1DB,
+/**/ 0x9BEE4000, 0x3FBB05B4,
+/**/ 0x18F84A5E, 0x3D0FF22C,
+/**/ 0x00000000, 0x3FECC800,
+/**/ 0xCD6DE82D, 0xBF38E45A,
+/**/ 0xDB220000, 0x3FBB3F44,
+/**/ 0xD8DE09AF, 0x3D3FD153,
+/**/ 0x00000000, 0x3FECC000,
+/**/ 0xE341926A, 0xBF29269F,
+/**/ 0x2BB10000, 0x3FBB78C8,
+/**/ 0xBC3987E7, 0xBD325EF7,
+/**/ 0x00000000, 0x3FECB800,
+/**/ 0xF620C1DA, 0xBEC589FB,
+/**/ 0x93690000, 0x3FBBB23E,
+/**/ 0x3559DB8B, 0xBD368B18,
+/**/ 0x00000000, 0x3FECB000,
+/**/ 0x0DE5FF1A, 0x3F28A893,
+/**/ 0x18148000, 0x3FBBEBA8,
+/**/ 0xB6DF1F57, 0xBD389B78,
+/**/ 0x00000000, 0x3FECA800,
+/**/ 0x0039563B, 0x3F38EAB9,
+/**/ 0xBF79C000, 0x3FBC2504,
+/**/ 0xD0EF4ADC, 0x3D3717C4,
+/**/ 0x00000000, 0x3FECA800,
+/**/ 0x08F377F2, 0xBF3A67D5,
+/**/ 0x8F5BC000, 0x3FBC5E54,
+/**/ 0x585FBE06, 0x3D1D0C57,
+/**/ 0x00000000, 0x3FECA000,
+/**/ 0x072792E4, 0xBF2B46E0,
+/**/ 0x8D790000, 0x3FBC9797,
+/**/ 0x977D1884, 0xBD36E010,
+/**/ 0x00000000, 0x3FEC9800,
+/**/ 0x1BB327C3, 0xBEE904EA,
+/**/ 0xBF8C0000, 0x3FBCD0CD,
+/**/ 0xB50DD743, 0x3D33E14D,
+/**/ 0x00000000, 0x3FEC9000,
+/**/ 0x77683AEC, 0x3F2853EB,
+/**/ 0x2B4C4000, 0x3FBD09F7,
+/**/ 0x00354E33, 0x3D2048C0,
+/**/ 0x00000000, 0x3FEC8800,
+/**/ 0xDC52100E, 0x3F3932D7,
+/**/ 0xD66CC000, 0x3FBD4313,
+/**/ 0x79135713, 0xBD294543,
+/**/ 0x00000000, 0x3FEC8800,
+/**/ 0x2736962B, 0xBF39AD90,
+/**/ 0xC69CC000, 0x3FBD7C23,
+/**/ 0xDD328771, 0xBD297EE4,
+/**/ 0x00000000, 0x3FEC8000,
+/**/ 0xF316B4C2, 0xBF28EEA2,
+/**/ 0x0187C000, 0x3FBDB527,
+/**/ 0x56AE181F, 0x3D392778,
+/**/ 0x00000000, 0x3FEC7800,
+/**/ 0x058F7536, 0x3EEAB099,
+/**/ 0x8CD60000, 0x3FBDEE1D,
+/**/ 0x729EFF89, 0xBD328DA0,
+/**/ 0x00000000, 0x3FEC7000,
+/**/ 0x1C71C71C, 0x3F2C71C7,
+/**/ 0x6E2B0000, 0x3FBE2707,
+/**/ 0x2AF0003C, 0xBD2A342C,
+/**/ 0x00000000, 0x3FEC6800,
+/**/ 0xD6422A30, 0x3F3BB2BB,
+/**/ 0xAB274000, 0x3FBE5FE4,
+/**/ 0xF74FFE4D, 0xBD35FAE9,
+/**/ 0x00000000, 0x3FEC6800,
+/**/ 0x54BDE47E, 0xBF36BD01,
+/**/ 0x49670000, 0x3FBE98B5,
+/**/ 0x89C50E97, 0x3D346774,
+/**/ 0x00000000, 0x3FEC6000,
+/**/ 0xB5157FE4, 0xBF222CC5,
+/**/ 0x4E838000, 0x3FBED179,
+/**/ 0x749D0484, 0xBD1FD143,
+/**/ 0x00000000, 0x3FEC5800,
+/**/ 0xA930B840, 0x3F129A21,
+/**/ 0xC0118000, 0x3FBF0A30,
+/**/ 0x83368E91, 0xBD3D599E,
+/**/ 0x00000000, 0x3FEC5000,
+/**/ 0xAC5CEE14, 0x3F3279B1,
+/**/ 0xA3A24000, 0x3FBF42DB,
+/**/ 0x32DF6C0D, 0xBD3312B7,
+/**/ 0x00000000, 0x3FEC5000,
+/**/ 0xD4AB8D0B, 0xBF3F9CF5,
+/**/ 0xFEC38000, 0x3FBF7B79,
+/**/ 0xE897ED01, 0xBD010987,
+/**/ 0x00000000, 0x3FEC4800,
+/**/ 0xCC17DAE4, 0xBF319D7C,
+/**/ 0xD6FF4000, 0x3FBFB40B,
+/**/ 0xB7B53B5B, 0x3D2C0BEC,
+/**/ 0x00000000, 0x3FEC4000,
+/**/ 0x01C3F8F0, 0xBF0C3F8F,
+/**/ 0x31DC0000, 0x3FBFEC91,
+/**/ 0xD1AE6607, 0xBD354555,
+/**/ 0x00000000, 0x3FEC3800,
+/**/ 0xAB1B8FFC, 0x3F254738,
+/**/ 0x0A6E0000, 0x3FC01285,
+/**/ 0x4805BF94, 0xBD1A8619,
+/**/ 0x00000000, 0x3FEC3000,
+/**/ 0x48B3C5D7, 0x3F38E51F,
+/**/ 0x42BF4000, 0x3FC02EBB,
+/**/ 0x5CE00E5D, 0xBD15A8FA,
+/**/ 0x00000000, 0x3FEC3000,
+/**/ 0x867E595E, 0xBF38C377,
+/**/ 0x449F6000, 0x3FC04AEB,
+/**/ 0x65CCD35C, 0x3D2AFA90,
+/**/ 0x00000000, 0x3FEC2800,
+/**/ 0x15FE3D95, 0xBF24AC6D,
+/**/ 0x12CA6000, 0x3FC06715,
+/**/ 0x9CDC0A3D, 0xBD2A4757,
+/**/ 0x00000000, 0x3FEC2000,
+/**/ 0x53B8CDAE, 0x3F10B34F,
+/**/ 0xAFFA2000, 0x3FC08338,
+/**/ 0xAC823E27, 0x3D30533C,
+/**/ 0x00000000, 0x3FEC1800,
+/**/ 0x3FABB0F6, 0x3F32C599,
+/**/ 0x1EE72000, 0x3FC09F56,
+/**/ 0x7157D1A8, 0xBD28F305,
+/**/ 0x00000000, 0x3FEC1800,
+/**/ 0x97CD1B6C, 0xBF3E8BF4,
+/**/ 0x6247A000, 0x3FC0BB6D,
+/**/ 0x3CCD04B3, 0x3D35464F,
+/**/ 0x00000000, 0x3FEC1000,
+/**/ 0xE3F1F8FC, 0xBF2F8FC7,
+/**/ 0x7CD08000, 0x3FC0D77E,
+/**/ 0x2EE2F482, 0x3D3CB2CD,
+/**/ 0x00000000, 0x3FEC0800,
+/**/ 0x5B199F35, 0xBEEDC860,
+/**/ 0x7134C000, 0x3FC0F389,
+/**/ 0xE893D6C6, 0xBD3DA359,
+/**/ 0x00000000, 0x3FEC0000,
+/**/ 0x1C01C01C, 0x3F2C01C0,
+/**/ 0x42254000, 0x3FC10F8E,
+/**/ 0x43396307, 0xBD293B38,
+/**/ 0x00000000, 0x3FEBF800,
+/**/ 0x256228AA, 0x3F3D0577,
+/**/ 0xF2518000, 0x3FC12B8C,
+/**/ 0x13C0A0FC, 0x3D348A4A,
+/**/ 0x00000000, 0x3FEBF800,
+/**/ 0xCB93A8A1, 0xBF33E08B,
+/**/ 0x84674000, 0x3FC14785,
+/**/ 0x1027C750, 0x3D156345,
+/**/ 0x00000000, 0x3FEBF000,
+/**/ 0x1DE63F4A, 0xBF12C4DB,
+/**/ 0xFB124000, 0x3FC16377,
+/**/ 0xBF41763E, 0x3D091E1A,
+/**/ 0x00000000, 0x3FEBE800,
+/**/ 0x769F9E4F, 0x3F2526D0,
+/**/ 0x58FCA000, 0x3FC17F64,
+/**/ 0xD093C8DC, 0x3D2843FA,
+/**/ 0x00000000, 0x3FEBE000,
+/**/ 0x5292D891, 0x3F39ED43,
+/**/ 0xA0CEE000, 0x3FC19B4A,
+/**/ 0x9621338B, 0xBD3D8824,
+/**/ 0x00000000, 0x3FEBE000,
+/**/ 0x5FC845A9, 0xBF36A3B3,
+/**/ 0xD52F6000, 0x3FC1B72A,
+/**/ 0x1811A396, 0x3D2E80A4,
+/**/ 0x00000000, 0x3FEBD800,
+/**/ 0xB7230491, 0xBF1C7E26,
+/**/ 0xF8C36000, 0x3FC1D304,
+/**/ 0xDF451042, 0xBD3A6D44,
+/**/ 0x00000000, 0x3FEBD000,
+/**/ 0x451B61CB, 0x3F20F365,
+/**/ 0x0E2DC000, 0x3FC1EED9,
+/**/ 0x7097648F, 0x3D161563,
+/**/ 0x00000000, 0x3FEBC800,
+/**/ 0xD72DD0AA, 0x3F3827F3,
+/**/ 0x18102000, 0x3FC20AA7,
+/**/ 0x348552FE, 0x3D3F2C94,
+/**/ 0x00000000, 0x3FEBC800,
+/**/ 0xBE0C262F, 0xBF3814D3,
+/**/ 0x190A6000, 0x3FC2266F,
+/**/ 0xB840E7F6, 0xBD24D20A,
+/**/ 0x00000000, 0x3FEBC000,
+/**/ 0x7ECECB53, 0xBF207963,
+/**/ 0x13BA6000, 0x3FC24231,
+/**/ 0x78EE9D9C, 0xBD3E3A00,
+/**/ 0x00000000, 0x3FEBB800,
+/**/ 0xF29268D3, 0x3F1EC130,
+/**/ 0x0ABC6000, 0x3FC25DED,
+/**/ 0x4F176449, 0x3D35A385,
+/**/ 0x00000000, 0x3FEBB000,
+/**/ 0xAB6353BF, 0x3F37B218,
+/**/ 0x00AB4000, 0x3FC279A3,
+/**/ 0xB3235108, 0x3D3EF432,
+/**/ 0x00000000, 0x3FEBB000,
+/**/ 0xF2298376, 0xBF383759,
+/**/ 0xF8200000, 0x3FC29552,
+/**/ 0xF4471DFC, 0xBD35B967,
+/**/ 0x00000000, 0x3FEBA800,
+/**/ 0x1EAD4253, 0xBF201832,
+/**/ 0xF3B1A000, 0x3FC2B0FC,
+/**/ 0xE30A59EA, 0x3D177CA3,
+/**/ 0x00000000, 0x3FEBA000,
+/**/ 0xD84886B1, 0x3F20679B,
+/**/ 0xF5F60000, 0x3FC2CCA0,
+/**/ 0x91AFF120, 0xBD3B5EF1,
+/**/ 0x00000000, 0x3FEB9800,
+/**/ 0xA41FEB4C, 0x3F38884D,
+/**/ 0x0180E000, 0x3FC2E83F,
+/**/ 0xC284E1CE, 0xBD3F0C2A,
+/**/ 0x00000000, 0x3FEB9800,
+/**/ 0x3806E548, 0xBF370EA7,
+/**/ 0x18E48000, 0x3FC303D7,
+/**/ 0xCE3ECB05, 0xBCD680B5,
+/**/ 0x00000000, 0x3FEB9000,
+/**/ 0xB5EF34C0, 0xBF1A4477,
+/**/ 0x3EB1A000, 0x3FC31F69,
+/**/ 0xE5A396FB, 0xBD2A6726,
+/**/ 0x00000000, 0x3FEB8800,
+/**/ 0x9401B894, 0x3F2401B8,
+/**/ 0x75770000, 0x3FC33AF5,
+/**/ 0xA2FE72A5, 0x3D3C9ECC,
+/**/ 0x00000000, 0x3FEB8000,
+/**/ 0x400DC1AA, 0x3F3AA73A,
+/**/ 0xBFC22000, 0x3FC3567B,
+/**/ 0x53991A1F, 0x3D3250D2,
+/**/ 0x00000000, 0x3FEB8000,
+/**/ 0x2E63A6A8, 0xBF349E11,
+/**/ 0x201E8000, 0x3FC371FC,
+/**/ 0x9B2D8ABC, 0x3D3EE877,
+/**/ 0x00000000, 0x3FEB7800,
+/**/ 0xC8DA04B9, 0xBF0E7898,
+/**/ 0x99164000, 0x3FC38D76,
+/**/ 0x9E39BB70, 0x3D1844A5,
+/**/ 0x00000000, 0x3FEB7000,
+/**/ 0xE6B33E2D, 0x3F2A284E,
+/**/ 0x2D31A000, 0x3FC3A8EB,
+/**/ 0x7D5D503E, 0x3D1BAFB7,
+/**/ 0x00000000, 0x3FEB6800,
+/**/ 0x759C2BB4, 0x3F3E0B91,
+/**/ 0xDEF76000, 0x3FC3C459,
+/**/ 0xF6B70D33, 0x3D3EDC86,
+/**/ 0x00000000, 0x3FEB6800,
+/**/ 0x088FD6E7, 0xBF30E8E2,
+/**/ 0xB0ECC000, 0x3FC3DFC2,
+/**/ 0x62B8C13F, 0x3D28A72A,
+/**/ 0x00000000, 0x3FEB6000,
+/**/ 0xD801B600, 0x3ECB6006,
+/**/ 0xA5952000, 0x3FC3FB25,
+/**/ 0x6B358FF7, 0x3D3195BE,
+/**/ 0x00000000, 0x3FEB5800,
+/**/ 0xD840F62C, 0x3F316A6A,
+/**/ 0xBF728000, 0x3FC41682,
+/**/ 0x081F849D, 0xBD210047,
+/**/ 0x00000000, 0x3FEB5800,
+/**/ 0x7DF8BD99, 0xBF3D4DEE,
+/**/ 0x01050000, 0x3FC431DA,
+/**/ 0x836E0391, 0x3D304837,
+/**/ 0x00000000, 0x3FEB5000,
+/**/ 0x7E4B17E5, 0xBF27E4B1,
+/**/ 0x6CCB8000, 0x3FC44D2B,
+/**/ 0x6135783C, 0xBD170CC1,
+/**/ 0x00000000, 0x3FEB4800,
+/**/ 0x55E6D8FE, 0x3F15F47D,
+/**/ 0x05430000, 0x3FC46877,
+/**/ 0xF8D5087E, 0xBD3D8145,
+/**/ 0x00000000, 0x3FEB4000,
+/**/ 0x0B803686, 0x3F37006D,
+/**/ 0xCCE6E000, 0x3FC483BC,
+/**/ 0x723F6369, 0x3D1EEA52,
+/**/ 0x00000000, 0x3FEB4000,
+/**/ 0x46A66920, 0xBF37687C,
+/**/ 0xC6314000, 0x3FC49EFC,
+/**/ 0x9F55572B, 0xBD090F59,
+/**/ 0x00000000, 0x3FEB3800,
+/**/ 0xFF2645BE, 0xBF16F6A4,
+/**/ 0xF39A6000, 0x3FC4BA36,
+/**/ 0xB3F219E5, 0xBD34354B,
+/**/ 0x00000000, 0x3FEB3000,
+/**/ 0x1801B318, 0x3F2801B3,
+/**/ 0x5798E000, 0x3FC4D56B,
+/**/ 0x15A96555, 0x3D380580,
+/**/ 0x00000000, 0x3FEB2800,
+/**/ 0x93511680, 0x3F3DD2FF,
+/**/ 0xF4A24000, 0x3FC4F099,
+/**/ 0xFAFEAF27, 0xBD3E9BF2,
+/**/ 0x00000000, 0x3FEB2800,
+/**/ 0xA89DCCAC, 0xBF304743,
+/**/ 0xCD29C000, 0x3FC50BC2,
+/**/ 0x28DB8D4F, 0x3D1ADA57,
+/**/ 0x00000000, 0x3FEB2000,
+/**/ 0x406C80D9, 0x3EFB2036,
+/**/ 0xE3A1C000, 0x3FC526E5,
+/**/ 0x37FC5238, 0xBD3790BA,
+/**/ 0x00000000, 0x3FEB1800,
+/**/ 0x4F9DC00E, 0x3F33BEC8,
+/**/ 0x3A7A8000, 0x3FC54203,
+/**/ 0xED855F0E, 0x3D268D68,
+/**/ 0x00000000, 0x3FEB1800,
+/**/ 0x44F8CE7E, 0xBF3A2101,
+/**/ 0xD4232000, 0x3FC55D1A,
+/**/ 0xDDA647E8, 0x3D3ADD94,
+/**/ 0x00000000, 0x3FEB1000,
+/**/ 0xB99AF3F3, 0xBF1FB596,
+/**/ 0xB3092000, 0x3FC5782C,
+/**/ 0x51794442, 0xBD33A463,
+/**/ 0x00000000, 0x3FEB0800,
+/**/ 0x922A3E85, 0x3F24B31D,
+/**/ 0xD9982000, 0x3FC59338,
+/**/ 0xB7555D4A, 0x3CF0BA68,
+/**/ 0x00000000, 0x3FEB0000,
+/**/ 0xE19BF6B7, 0x3F3CB3CF,
+/**/ 0x4A3AA000, 0x3FC5AE3F,
+/**/ 0xF012A8B9, 0x3D21EA25,
+/**/ 0x00000000, 0x3FEB0000,
+/**/ 0x9A5BF0D1, 0xBF30DEAE,
+/**/ 0x07598000, 0x3FC5C940,
+/**/ 0x8CD23322, 0xBD3A8D94,
+/**/ 0x00000000, 0x3FEAF800,
+/**/ 0x9EDE13CE, 0x3EFA2072,
+/**/ 0x135BE000, 0x3FC5E43B,
+/**/ 0xCEED9C31, 0xBD343AB4,
+/**/ 0x00000000, 0x3FEAF000,
+/**/ 0x0D79435E, 0x3F3435E5,
+/**/ 0x70A7A000, 0x3FC5FF30,
+/**/ 0x183BEBF2, 0xBD38586F,
+/**/ 0x00000000, 0x3FEAF000,
+/**/ 0x06855D30, 0xBF392321,
+/**/ 0x21A0E000, 0x3FC61A20,
+/**/ 0x1BDF3CDD, 0x3D3DD9DD,
+/**/ 0x00000000, 0x3FEAE800,
+/**/ 0x7ABED811, 0xBF19A45C,
+/**/ 0x28AAA000, 0x3FC6350A,
+/**/ 0xAB8163AF, 0x3D2D5EC0,
+/**/ 0x00000000, 0x3FEAE000,
+/**/ 0x84EF68CB, 0x3F28C7ED,
+/**/ 0x88260000, 0x3FC64FEE,
+/**/ 0x759DDED6, 0xBD1DA40D,
+/**/ 0x00000000, 0x3FEAD800,
+/**/ 0xA482F00D, 0x3F3F43FC,
+/**/ 0x4272A000, 0x3FC66ACD,
+/**/ 0xBFC6C785, 0x3D3AA1BD,
+/**/ 0x00000000, 0x3FEAD800,
+/**/ 0xCDE3E7AE, 0xBF2B9222,
+/**/ 0x59EF0000, 0x3FC685A6,
+/**/ 0x6C103214, 0xBD21F2A9,
+/**/ 0x00000000, 0x3FEAD000,
+/**/ 0xEED254A3, 0x3F14F302,
+/**/ 0xD0F7A000, 0x3FC6A079,
+/**/ 0x448D14F5, 0x3D35A3F8,
+/**/ 0x00000000, 0x3FEAC800,
+/**/ 0x32071DEF, 0x3F385567,
+/**/ 0xA9E80000, 0x3FC6BB47,
+/**/ 0x23EA3296, 0x3D19F64D,
+/**/ 0x00000000, 0x3FEAC800,
+/**/ 0xD47F29D4, 0xBF347F29,
+/**/ 0xE719E000, 0x3FC6D60F,
+/**/ 0x57134767, 0xBD3BC6E5,
+/**/ 0x00000000, 0x3FEAC000,
+/**/ 0xE82D23BC, 0xBEF40FE1,
+/**/ 0x8AE56000, 0x3FC6F0D2,
+/**/ 0xC93373DA, 0x3D369737,
+/**/ 0x00000000, 0x3FEAB800,
+/**/ 0x972D8538, 0x3F320FDE,
+/**/ 0x97A1A000, 0x3FC70B8F,
+/**/ 0xF6A95BEF, 0x3D34EA64,
+/**/ 0x00000000, 0x3FEAB800,
+/**/ 0x66711513, 0xBF3A8C9F,
+/**/ 0x0FA40000, 0x3FC72647,
+/**/ 0x0E743A45, 0xBD3774DF,
+/**/ 0x00000000, 0x3FEAB000,
+/**/ 0x02806ABC, 0xBF1C5A0F,
+/**/ 0xF5404000, 0x3FC740F8,
+/**/ 0x99018AA1, 0xBD30B66C,
+/**/ 0x00000000, 0x3FEAA800,
+/**/ 0xD22C937A, 0x3F28E44B,
+/**/ 0x4AC8E000, 0x3FC75BA5,
+/**/ 0x8BC4A7C0, 0x3D3DDCA5,
+/**/ 0x00000000, 0x3FEAA800,
+/**/ 0xFF2ADFF3, 0xBF3FF2AD,
+/**/ 0x128F2000, 0x3FC7764C,
+/**/ 0x3479E3D1, 0x3D027490,
+/**/ 0x00000000, 0x3FEAA000,
+/**/ 0x0B3ADA5C, 0xBF288A16,
+/**/ 0x4EE26000, 0x3FC790ED,
+/**/ 0x4E7746F6, 0x3D199BBD,
+/**/ 0x00000000, 0x3FEA9800,
+/**/ 0x4C77B035, 0x3F1DEC0D,
+/**/ 0x0210E000, 0x3FC7AB89,
+/**/ 0x72534A58, 0xBD2BDB90,
+/**/ 0x00000000, 0x3FEA9000,
+/**/ 0x91F59E6B, 0x3F3B4D71,
+/**/ 0x2E674000, 0x3FC7C61F,
+/**/ 0xB31BE8E0, 0xBD32392D,
+/**/ 0x00000000, 0x3FEA9000,
+/**/ 0xB8A2A522, 0xBF30CDCB,
+/**/ 0xD630C000, 0x3FC7E0AF,
+/**/ 0x1D8F1034, 0x3D139E7C,
+/**/ 0x00000000, 0x3FEA8800,
+/**/ 0x6A2194A0, 0x3F094A00,
+/**/ 0xFBB76000, 0x3FC7FB3A,
+/**/ 0x24609D57, 0xBD37DBF5,
+/**/ 0x00000000, 0x3FEA8000,
+/**/ 0x870AC52E, 0x3F373289,
+/**/ 0xA1436000, 0x3FC815C0,
+/**/ 0xF9201CE8, 0xBD302A52,
+/**/ 0x00000000, 0x3FEA8000,
+/**/ 0x9E8684DD, 0xBF34B1FA,
+/**/ 0xC91BC000, 0x3FC83040,
+/**/ 0xC6E66F32, 0x3D3E5B71,
+/**/ 0x00000000, 0x3FEA7800,
+/**/ 0xA9267648, 0xBEE08AF5,
+/**/ 0x75866000, 0x3FC84ABB,
+/**/ 0xDF4E2BD2, 0xBD3D8DAA,
+/**/ 0x00000000, 0x3FEA7000,
+/**/ 0x1A3D927E, 0x3F33BB67,
+/**/ 0xA8C70000, 0x3FC86530,
+/**/ 0xCB4EA3E3, 0x3D398BB0,
+/**/ 0x00000000, 0x3FEA7000,
+/**/ 0x7F2C97F3, 0xBF37F2C9,
+/**/ 0x6520C000, 0x3FC87FA0,
+/**/ 0x401202FC, 0x3D322120,
+/**/ 0x00000000, 0x3FEA6800,
+/**/ 0x3C076D20, 0xBF0C77A5,
+/**/ 0xACD4E000, 0x3FC89A0A,
+/**/ 0xDA8F5A72, 0x3D2C0BFB,
+/**/ 0x00000000, 0x3FEA6000,
+/**/ 0x7C7EF82B, 0x3F30E6DA,
+/**/ 0x82236000, 0x3FC8B46F,
+/**/ 0x102DD7C9, 0x3D12D9F2,
+/**/ 0x00000000, 0x3FEA6000,
+/**/ 0x2EC05C44, 0xBF3A9167,
+/**/ 0xE74AE000, 0x3FC8CECE,
+/**/ 0xAA429BB5, 0xBD3A5BA0,
+/**/ 0x00000000, 0x3FEA5800,
+/**/ 0xEEB6BD53, 0xBF17DF12,
+/**/ 0xDE886000, 0x3FC8E928,
+/**/ 0xB13D72D5, 0x3D3A8154,
+/**/ 0x00000000, 0x3FEA5000,
+/**/ 0x98C70AE6, 0x3F2D676D,
+/**/ 0x6A180000, 0x3FC9037D,
+/**/ 0x57C1C8D9, 0x3D230DEA,
+/**/ 0x00000000, 0x3FEA5000,
+/**/ 0x96CE4780, 0xBF3C8EFF,
+/**/ 0x8C340000, 0x3FC91DCC,
+/**/ 0xBDDEFF46, 0x3D37BC6A,
+/**/ 0x00000000, 0x3FEA4800,
+/**/ 0x71EFFCB7, 0xBF1EFFCB,
+/**/ 0x4715A000, 0x3FC93816,
+/**/ 0x6A3A39D9, 0xBD34C63D,
+/**/ 0x00000000, 0x3FEA4000,
+/**/ 0x1A41A41A, 0x3F2A41A4,
+/**/ 0x9CF46000, 0x3FC9525A,
+/**/ 0x7D9F158F, 0xBD329713,
+/**/ 0x00000000, 0x3FEA4000,
+/**/ 0xBF3B3C0E, 0xBF3DECBB,
+/**/ 0x9006A000, 0x3FC96C99,
+/**/ 0x9CBB452C, 0x3D2A88D5,
+/**/ 0x00000000, 0x3FEA3800,
+/**/ 0x3BCD35A8, 0xBF21D14E,
+/**/ 0x22818000, 0x3FC986D3,
+/**/ 0x4DD44000, 0x3CF93B56,
+/**/ 0x00000000, 0x3FEA3000,
+/**/ 0x3B5832C0, 0x3F285A0A,
+/**/ 0x56988000, 0x3FC9A107,
+/**/ 0x242CD098, 0x3D264AA6,
+/**/ 0x00000000, 0x3FEA3000,
+/**/ 0xD71AFD8C, 0xBF3EABC1,
+/**/ 0x2E7E0000, 0x3FC9BB36,
+/**/ 0xA1CE0FFC, 0xBD21F2A8,
+/**/ 0x00000000, 0x3FEA2800,
+/**/ 0x7C041611, 0xBF22E60D,
+/**/ 0xAC62E000, 0x3FC9D55F,
+/**/ 0xFC3B5BC3, 0xBD3F4669,
+/**/ 0x00000000, 0x3FEA2000,
+/**/ 0x5FF2EF43, 0x3F27AE57,
+/**/ 0xD276A000, 0x3FC9EF83,
+/**/ 0xB3F9CE00, 0xBD2730B7,
+/**/ 0x00000000, 0x3FEA2000,
+/**/ 0x3D66322E, 0xBF3ECD35,
+/**/ 0xA2E7A000, 0x3FCA09A2,
+/**/ 0xCD411233, 0xBD2DD99D,
+/**/ 0x00000000, 0x3FEA1800,
+/**/ 0x5B4FE5E9, 0xBF22C068,
+/**/ 0x1FE2C000, 0x3FCA23BC,
+/**/ 0x91DC9F0B, 0xBD3539CD,
+/**/ 0x00000000, 0x3FEA1000,
+/**/ 0x80B67A9A, 0x3F283C48,
+/**/ 0x4B938000, 0x3FCA3DD0,
+/**/ 0x366E2C5A, 0x3D297DA1,
+/**/ 0x00000000, 0x3FEA1000,
+/**/ 0x89907BBA, 0xBF3E5236,
+/**/ 0x28244000, 0x3FCA57DF,
+/**/ 0xCA1D9ABB, 0x3D3B99C8,
+/**/ 0x00000000, 0x3FEA0800,
+/**/ 0x32054967, 0xBF21629E,
+/**/ 0xB7BE0000, 0x3FCA71E8,
+/**/ 0x6EF05323, 0xBD210ACA,
+/**/ 0x00000000, 0x3FEA0000,
+/**/ 0x1A01A01A, 0x3F2A01A0,
+/**/ 0xFC882000, 0x3FCA8BEC,
+/**/ 0xCF21B9CF, 0x3D3E3185,
+/**/ 0x00000000, 0x3FEA0000,
+/**/ 0x93FF301D, 0xBF3D3BE3,
+/**/ 0xF8A94000, 0x3FCAA5EB,
+/**/ 0x36951A8F, 0xBD32A0A9,
+/**/ 0x00000000, 0x3FE9F800,
+/**/ 0xBFE608ED, 0xBF1D9DD1,
+/**/ 0xAE462000, 0x3FCABFE5,
+/**/ 0x395F139D, 0xBD3B68F5,
+/**/ 0x00000000, 0x3FE9F000,
+/**/ 0x1B29257F, 0x3F2CFC26,
+/**/ 0x1F828000, 0x3FCAD9DA,
+/**/ 0xC803F050, 0xBD3882B7,
+/**/ 0x00000000, 0x3FE9F000,
+/**/ 0x7E613717, 0xBF3B8B57,
+/**/ 0x4E80C000, 0x3FCAF3C9,
+/**/ 0x3FCD9066, 0xBCBA4E63,
+/**/ 0x00000000, 0x3FE9E800,
+/**/ 0xB9FABD04, 0xBF160EF9,
+/**/ 0x3D620000, 0x3FCB0DB3,
+/**/ 0x38EAB906, 0x3D3FEE14,
+/**/ 0x00000000, 0x3FE9E000,
+/**/ 0xEAF850E2, 0x3F3094D3,
+/**/ 0xEE464000, 0x3FCB2797,
+/**/ 0x906D00A9, 0xBD3BE88A,
+/**/ 0x00000000, 0x3FE9E000,
+/**/ 0xBBE88FDC, 0xBF3941AA,
+/**/ 0x634BA000, 0x3FCB4177,
+/**/ 0x5666069F, 0x3D355D01,
+/**/ 0x00000000, 0x3FE9D800,
+/**/ 0x25F4B1AA, 0xBF083A25,
+/**/ 0x9E8FC000, 0x3FCB5B51,
+/**/ 0xEC011F31, 0xBD34B722,
+/**/ 0x00000000, 0x3FE9D000,
+/**/ 0xF71FAC14, 0x3F3343FB,
+/**/ 0xA22E4000, 0x3FCB7526,
+/**/ 0x2E785490, 0x3D2C0DBF,
+/**/ 0x00000000, 0x3FE9D000,
+/**/ 0x1965FF32, 0xBF365FF3,
+/**/ 0x70420000, 0x3FCB8EF6,
+/**/ 0x321788E0, 0x3D387533,
+/**/ 0x00000000, 0x3FE9C800,
+/**/ 0x9C8019C8, 0x3EA9C801,
+/**/ 0x0AE46000, 0x3FCBA8C1,
+/**/ 0x9EEE9D85, 0x3D3A32E2,
+/**/ 0x00000000, 0x3FE9C000,
+/**/ 0x25080CE1, 0x3F368A77,
+/**/ 0x742D8000, 0x3FCBC286,
+/**/ 0xF39D121C, 0x3D39AC53,
+/**/ 0x00000000, 0x3FE9C000,
+/**/ 0xC54763F2, 0xBF32E743,
+/**/ 0xAE344000, 0x3FCBDC46,
+/**/ 0x023D6505, 0x3D3625B4,
+/**/ 0x00000000, 0x3FE9B800,
+/**/ 0x8B7424F9, 0x3F0DBD49,
+/**/ 0xBB0E4000, 0x3FCBF601,
+/**/ 0x47C378B5, 0x3D2386A9,
+/**/ 0x00000000, 0x3FE9B000,
+/**/ 0x00CD9A67, 0x3F3A6734,
+/**/ 0x9CCFE000, 0x3FCC0FB7,
+/**/ 0x99E8A558, 0xBD346FFF,
+/**/ 0x00000000, 0x3FE9B000,
+/**/ 0xAEF25B7C, 0xBF2DB15A,
+/**/ 0x558C2000, 0x3FCC2968,
+/**/ 0xDEE38A40, 0xBD2CFD73,
+/**/ 0x00000000, 0x3FE9A800,
+/**/ 0xC140C073, 0x3F1FDFEC,
+/**/ 0xE754E000, 0x3FCC4313,
+/**/ 0x74CAD7D6, 0x3D3279BE,
+/**/ 0x00000000, 0x3FE9A000,
+/**/ 0xA7DCBEB3, 0x3F3ED923,
+/**/ 0x543AE000, 0x3FCC5CBA,
+/**/ 0xECB454FC, 0x3D20929D,
+/**/ 0x00000000, 0x3FE9A000,
+/**/ 0xB256DE2C, 0xBF246A7B,
+/**/ 0x9E4D6000, 0x3FCC765B,
+/**/ 0x36976F6C, 0x3D31AB6B,
+/**/ 0x00000000, 0x3FE99800,
+/**/ 0x9999999A, 0x3F299999,
+/**/ 0xC79AA000, 0x3FCC8FF7,
+/**/ 0x689F8434, 0xBD27794F,
+/**/ 0x00000000, 0x3FE99800,
+/**/ 0x3EC03FF3, 0xBF3C20C6,
+/**/ 0xD22F6000, 0x3FCCA98E,
+/**/ 0x8CA209C8, 0xBCF698C1,
+/**/ 0x00000000, 0x3FE99000,
+/**/ 0x31EC07FD, 0xBF13F803,
+/**/ 0xC0176000, 0x3FCCC320,
+/**/ 0x9A653794, 0x3D240903,
+/**/ 0x00000000, 0x3FE98800,
+/**/ 0x5AC98715, 0x3F323513,
+/**/ 0x935D2000, 0x3FCCDCAD,
+/**/ 0x34C9A447, 0xBD0A0FF0,
+/**/ 0x00000000, 0x3FE98800,
+/**/ 0x89F80661, 0xBF368793,
+/**/ 0x4E09C000, 0x3FCCF635,
+/**/ 0x9A07D55B, 0x3D277123,
+/**/ 0x00000000, 0x3FE98000,
+/**/ 0x8019801A, 0x3EE98019,
+/**/ 0xF2256000, 0x3FCD0FB7,
+/**/ 0x20633B29, 0xBD0AF52B,
+/**/ 0x00000000, 0x3FE97800,
+/**/ 0xAB329020, 0x3F382FC6,
+/**/ 0x81B6C000, 0x3FCD2935,
+/**/ 0x128AAA5F, 0xBD383270,
+/**/ 0x00000000, 0x3FE97800,
+/**/ 0x962DBFF3, 0xBF305C4B,
+/**/ 0xFEC36000, 0x3FCD42AD,
+/**/ 0xFD804272, 0xBD175C00,
+/**/ 0x00000000, 0x3FE97000,
+/**/ 0x970E4F81, 0x3F1C9F01,
+/**/ 0x6B4FC000, 0x3FCD5C21,
+/**/ 0xBBCA681B, 0xBD21BA91,
+/**/ 0x00000000, 0x3FE96800,
+/**/ 0x049160B8, 0x3F3EBBE1,
+/**/ 0xC95F0000, 0x3FCD758F,
+/**/ 0x8B4162AA, 0xBD15A10A,
+/**/ 0x00000000, 0x3FE96800,
+/**/ 0x9933FE6A, 0xBF233FE6,
+/**/ 0x1AF32000, 0x3FCD8EF9,
+/**/ 0xC364C784, 0xBD15105F,
+/**/ 0x00000000, 0x3FE96000,
+/**/ 0xCE078906, 0x3F2C2873,
+/**/ 0x620CE000, 0x3FCDA85D,
+/**/ 0xC16CC7EC, 0x3D240194,
+/**/ 0x00000000, 0x3FE96000,
+/**/ 0xE442936B, 0xBF3A27A0,
+/**/ 0xA0ABE000, 0x3FCDC1BC,
+/**/ 0xA628CCC6, 0x3D38FAC1,
+/**/ 0x00000000, 0x3FE95800,
+/**/ 0x548A97A9, 0xBF029C69,
+/**/ 0xD8CEA000, 0x3FCDDB16,
+/**/ 0x7104B8BC, 0xBD1EEF79,
+/**/ 0x00000000, 0x3FE95000,
+/**/ 0x9F74B92D, 0x3F35906B,
+/**/ 0x0C722000, 0x3FCDF46C,
+/**/ 0xB0B79039, 0x3D3A5E82,
+/**/ 0x00000000, 0x3FE95000,
+/**/ 0xF35927BC, 0xBF327BBF,
+/**/ 0x3D92A000, 0x3FCE0DBC,
+/**/ 0xF0529BF1, 0x3D359233,
+/**/ 0x00000000, 0x3FE94800,
+/**/ 0xDD3C0CA4, 0x3F161F9A,
+/**/ 0x6E2B0000, 0x3FCE2707,
+/**/ 0x2AF0003C, 0xBD3A342C,
+/**/ 0x00000000, 0x3FE94000,
+/**/ 0x41228A8F, 0x3F3D9B56,
+/**/ 0xA034C000, 0x3FCE404D,
+/**/ 0xE09A2799, 0xBD3187EE,
+/**/ 0x00000000, 0x3FE94000,
+/**/ 0x598A73F8, 0xBF2482F5,
+/**/ 0xD5A88000, 0x3FCE598E,
+/**/ 0xCF1E98A1, 0xBD0D134B,
+/**/ 0x00000000, 0x3FE93800,
+/**/ 0x3C1B9728, 0x3F2BE2D5,
+/**/ 0x107DA000, 0x3FCE72CB,
+/**/ 0xCDF5471C, 0x3D1DD48C,
+/**/ 0x00000000, 0x3FE93800,
+/**/ 0x2698CFF3, 0xBF39CC03,
+/**/ 0x52AA6000, 0x3FCE8C02,
+/**/ 0x80E8E6FF, 0xBD26805B,
+/**/ 0x00000000, 0x3FE93000,
+/**/ 0xB9F30358, 0xBEF79CD3,
+/**/ 0x9E23A000, 0x3FCEA534,
+/**/ 0x4C73CCB5, 0x3D381B93,
+/**/ 0x00000000, 0x3FE92800,
+/**/ 0x255BA00D, 0x3F36E803,
+/**/ 0xF4DD8000, 0x3FCEBE61,
+/**/ 0x30FDCA4D, 0xBD23D453,
+/**/ 0x00000000, 0x3FE92800,
+/**/ 0x36077742, 0xBF30A69B,
+/**/ 0x58CA8000, 0x3FCED78A,
+/**/ 0x3793387E, 0x3D16F1B5,
+/**/ 0x00000000, 0x3FE92000,
+/**/ 0x1C451AB3, 0x3F1F693A,
+/**/ 0xCBDC6000, 0x3FCEF0AD,
+/**/ 0x9C86AF24, 0xBD2B26B7,
+/**/ 0x00000000, 0x3FE92000,
+/**/ 0xC74EA9E2, 0xBF3F9548,
+/**/ 0x50036000, 0x3FCF09CC,
+/**/ 0x18D999DB, 0x3D3DA094,
+/**/ 0x00000000, 0x3FE91800,
+/**/ 0xF7C46911, 0xBF1BD5A8,
+/**/ 0xE72F2000, 0x3FCF22E5,
+/**/ 0x1417E41F, 0xBD3F454F,
+/**/ 0x00000000, 0x3FE91000,
+/**/ 0x0D83D1C6, 0x3F31B9E1,
+/**/ 0x934D6000, 0x3FCF3BFA,
+/**/ 0x937B903B, 0x3D2D9F2A,
+/**/ 0x00000000, 0x3FE91000,
+/**/ 0xF3795877, 0xBF35876F,
+/**/ 0x564B8000, 0x3FCF550A,
+/**/ 0xA09202FE, 0xBD2323E3,
+/**/ 0x00000000, 0x3FE90800,
+/**/ 0xBD1D87EC, 0x3F0A34CD,
+/**/ 0x32154000, 0x3FCF6E15,
+/**/ 0x7AC4EC74, 0xBD3C9A97,
+/**/ 0x00000000, 0x3FE90000,
+/**/ 0x0E760899, 0x3F3C23F5,
+/**/ 0x28956000, 0x3FCF871B,
+/**/ 0x6A526EFE, 0xBD3F75FD,
+/**/ 0x00000000, 0x3FE90000,
+/**/ 0xD0BE9594, 0xBF25DECD,
+/**/ 0x3BB58000, 0x3FCFA01C,
+/**/ 0xFAE1D786, 0xBD1A1F71,
+/**/ 0x00000000, 0x3FE8F800,
+/**/ 0xC18F9C19, 0x3F2C18F9,
+/**/ 0x6D5E4000, 0x3FCFB918,
+/**/ 0xAB993C87, 0xBD0D572A,
+/**/ 0x00000000, 0x3FE8F800,
+/**/ 0x8176594C, 0xBF38E868,
+/**/ 0xBF770000, 0x3FCFD20F,
+/**/ 0x72C6FE70, 0xBD11C55B,
+/**/ 0x00000000, 0x3FE8F000,
+/**/ 0x3C018F00, 0x3EC8F006,
+/**/ 0x33E60000, 0x3FCFEB02,
+/**/ 0x32D5E8C7, 0x3D2F316E,
+/**/ 0x00000000, 0x3FE8E800,
+/**/ 0xAD115384, 0x3F395B4D,
+/**/ 0xE6484000, 0x3FD001F7,
+/**/ 0x40C9ABBC, 0x3D38A957,
+/**/ 0x00000000, 0x3FE8E800,
+/**/ 0xEC8C0F90, 0xBF2AD850,
+/**/ 0x45AD5000, 0x3FD00E6C,
+/**/ 0x52E01203, 0x3CDCC68D,
+/**/ 0x00000000, 0x3FE8E000,
+/**/ 0xA56B1AA1, 0x3F27B6E9,
+/**/ 0x3913A000, 0x3FD01ADE,
+/**/ 0xCCDC1521, 0xBD108930,
+/**/ 0x00000000, 0x3FE8E000,
+/**/ 0x40DFC1D8, 0xBF3ACDE3,
+/**/ 0xC16C2000, 0x3FD0274D,
+/**/ 0x9CF835C2, 0x3D2979E8,
+/**/ 0x00000000, 0x3FE8D800,
+/**/ 0x317DF64C, 0xBEF68397,
+/**/ 0xDFA74000, 0x3FD033BA,
+/**/ 0x1485BDFF, 0x3D0C30BC,
+/**/ 0x00000000, 0x3FE8D000,
+/**/ 0x80C6980C, 0x3F380C69,
+/**/ 0x94B4D000, 0x3FD04025,
+/**/ 0x9EF42D7F, 0x3CF036B8,
+/**/ 0x00000000, 0x3FE8D000,
+/**/ 0x338C7FE7, 0xBF2CE006,
+/**/ 0xE1842000, 0x3FD04C8D,
+/**/ 0x512CEB86, 0xBD1FE6BA,
+/**/ 0x00000000, 0x3FE8C800,
+/**/ 0x1EFBBD63, 0x3F2644F0,
+/**/ 0xC703F000, 0x3FD058F3,
+/**/ 0xBCD236AD, 0xBD30E866,
+/**/ 0x00000000, 0x3FE8C800,
+/**/ 0xAA79217A, 0xBF3B3C2D,
+/**/ 0x46227000, 0x3FD06557,
+/**/ 0xB4868D6A, 0x3D0131DF,
+/**/ 0x00000000, 0x3FE8C000,
+/**/ 0x8062FF3A, 0xBEF8BFCE,
+/**/ 0x5FCD6000, 0x3FD071B8,
+/**/ 0xA3E01A11, 0xBD3BCB8B,
+/**/ 0x00000000, 0x3FE8B800,
+/**/ 0xBD2672C4, 0x3F383301,
+/**/ 0x14F1D000, 0x3FD07E17,
+/**/ 0x4F384BD5, 0xBD3EFCC6,
+/**/ 0x00000000, 0x3FE8B800,
+/**/ 0x9BFE749C, 0xBF2BFE74,
+/**/ 0x667C5000, 0x3FD08A73,
+/**/ 0x40C5A329, 0x3D3EBC1D,
+/**/ 0x00000000, 0x3FE8B000,
+/**/ 0xD4353EB3, 0x3F27BA8C,
+/**/ 0x55591000, 0x3FD096CD,
+/**/ 0x20550A31, 0x3D3F998D,
+/**/ 0x00000000, 0x3FE8B000,
+/**/ 0xA062B2E4, 0xBF3A3784,
+/**/ 0xE2739000, 0x3FD0A324,
+/**/ 0x7EF4030E, 0x3D0C6BEE,
+/**/ 0x00000000, 0x3FE8A800,
+/**/ 0x5E630281, 0xBECED1F6,
+/**/ 0x0EB6C000, 0x3FD0AF7A,
+/**/ 0x4945ADAD, 0x3D23CCF9,
+/**/ 0x00000000, 0x3FE8A000,
+/**/ 0x0C519CAE, 0x3F39CAE0,
+/**/ 0xDB0D2000, 0x3FD0BBCC,
+/**/ 0xCC5DCDFB, 0x3D32F32C,
+/**/ 0x00000000, 0x3FE8A000,
+/**/ 0x4EDBA5FD, 0xBF283C02,
+/**/ 0x4860B000, 0x3FD0C81D,
+/**/ 0x401D1731, 0xBD3E5BCF,
+/**/ 0x00000000, 0x3FE89800,
+/**/ 0x1899C0F6, 0x3F2C0F60,
+/**/ 0x579AB000, 0x3FD0D46B,
+/**/ 0xF640E1E6, 0x3D3D2C81,
+/**/ 0x00000000, 0x3FE89800,
+/**/ 0xBDBE51D0, 0xBF37C414,
+/**/ 0x09A43000, 0x3FD0E0B7,
+/**/ 0xA7862F2A, 0x3D32A038,
+/**/ 0x00000000, 0x3FE89000,
+/**/ 0xDD12CE7D, 0x3F03F540,
+/**/ 0x5F658000, 0x3FD0ED00,
+/**/ 0x285AA803, 0xBD22DC75,
+/**/ 0x00000000, 0x3FE88800,
+/**/ 0x400C45CD, 0x3F3CCFDE,
+/**/ 0x59C67000, 0x3FD0F947,
+/**/ 0x7F0818B6, 0xBD395261,
+/**/ 0x00000000, 0x3FE88800,
+/**/ 0x44FB66B5, 0xBF21A0F5,
+/**/ 0xF9AE5000, 0x3FD1058B,
+/**/ 0x817D52CD, 0xBD34AB9D,
+/**/ 0x00000000, 0x3FE88000,
+/**/ 0x2866A138, 0x3F319D95,
+/**/ 0x4003F000, 0x3FD111CE,
+/**/ 0x096B4B6B, 0xBD1B3237,
+/**/ 0x00000000, 0x3FE88000,
+/**/ 0xA48B49DA, 0xBF33E5FA,
+/**/ 0x2DADA000, 0x3FD11E0E,
+/**/ 0x8FCCE5BA, 0xBD2A47F8,
+/**/ 0x00000000, 0x3FE87800,
+/**/ 0xDEECB0A8, 0x3F1A9336,
+/**/ 0xC3912000, 0x3FD12A4B,
+/**/ 0x61473259, 0xBD35A750,
+/**/ 0x00000000, 0x3FE87800,
+/**/ 0xFB6A388D, 0xBF3EC219,
+/**/ 0x0293B000, 0x3FD13687,
+/**/ 0x99D67123, 0xBD3D3E84,
+/**/ 0x00000000, 0x3FE87000,
+/**/ 0xC1625090, 0xBF106AE7,
+/**/ 0xEB9A0000, 0x3FD142BF,
+/**/ 0x85B58A9E, 0x3D31CE61,
+/**/ 0x00000000, 0x3FE86800,
+/**/ 0xACD4200C, 0x3F369AE5,
+/**/ 0x7F887000, 0x3FD14EF6,
+/**/ 0x5DFC9794, 0xBD3E97A6,
+/**/ 0x00000000, 0x3FE86800,
+/**/ 0x9389D11C, 0xBF2D4286,
+/**/ 0xBF429000, 0x3FD15B2A,
+/**/ 0x49B629B2, 0xBD2D8E3B,
+/**/ 0x00000000, 0x3FE86000,
+/**/ 0x18618618, 0x3F286186,
+/**/ 0xABABA000, 0x3FD1675C,
+/**/ 0x731F55C4, 0x3D38380E,
+/**/ 0x00000000, 0x3FE86000,
+/**/ 0x6AC71708, 0xBF38EF0F,
+/**/ 0x45A67000, 0x3FD1738C,
+/**/ 0x0032C176, 0xBD39C6E9,
+/**/ 0x00000000, 0x3FE85800,
+/**/ 0xE00C2C20, 0x3EFFF3D3,
+/**/ 0x8E151000, 0x3FD17FB9,
+/**/ 0xA74A2684, 0xBD3A8A8B,
+/**/ 0x00000000, 0x3FE85000,
+/**/ 0xF9592266, 0x3F3CFBA0,
+/**/ 0x85D93000, 0x3FD18BE4,
+/**/ 0x6F3604AB, 0x3D3C167F,
+/**/ 0x00000000, 0x3FE85000,
+/**/ 0xFF3D87FA, 0xBF1FE7B0,
+/**/ 0x2DD42000, 0x3FD1980D,
+/**/ 0x7A361C9A, 0x3D2B7B3A,
+/**/ 0x00000000, 0x3FE84800,
+/**/ 0x918DC223, 0x3F331E8D,
+/**/ 0x86E68000, 0x3FD1A433,
+/**/ 0x634E0AAC, 0xBD07A850,
+/**/ 0x00000000, 0x3FE84800,
+/**/ 0x8D76B549, 0xBF31BAF9,
+/**/ 0x91F08000, 0x3FD1B057,
+/**/ 0x6DC55E2D, 0xBD32DD46,
+/**/ 0x00000000, 0x3FE84000,
+/**/ 0xDC90C512, 0x3F22F2EC,
+/**/ 0x4FD1D000, 0x3FD1BC79,
+/**/ 0x747BA7BE, 0xBD3CCF0C,
+/**/ 0x00000000, 0x3FE84000,
+/**/ 0x6A0916B9, 0xBF3B442A,
+/**/ 0xC169A000, 0x3FD1C898,
+/**/ 0xE5C62AFF, 0xBD381410,
+/**/ 0x00000000, 0x3FE83800,
+/**/ 0x83801838, 0x3EA83801,
+/**/ 0xE796A000, 0x3FD1D4B5,
+/**/ 0xD197BAC2, 0x3D222A5B,
+/**/ 0x00000000, 0x3FE83000,
+/**/ 0xCBD11C5C, 0x3F3B6A41,
+/**/ 0xC3371000, 0x3FD1E0D0,
+/**/ 0xA9B0D4A0, 0x3D3AF8F2,
+/**/ 0x00000000, 0x3FE83000,
+/**/ 0xCB7A3CD6, 0xBF225381,
+/**/ 0x5528B000, 0x3FD1ECE9,
+/**/ 0x09B4A3B8, 0xBD184E7B,
+/**/ 0x00000000, 0x3FE82800,
+/**/ 0x152500C1, 0x3F32500C,
+/**/ 0x9E48A000, 0x3FD1F8FF,
+/**/ 0x040CBE77, 0x3D27946C,
+/**/ 0x00000000, 0x3FE82800,
+/**/ 0x14902134, 0xBF32285F,
+/**/ 0x9F73B000, 0x3FD20513,
+/**/ 0x1609E0A4, 0x3CF6E15E,
+/**/ 0x00000000, 0x3FE82000,
+/**/ 0xA4018213, 0x3F22D9EB,
+/**/ 0x59861000, 0x3FD21125,
+/**/ 0xBA2950C4, 0x3D382E78,
+/**/ 0x00000000, 0x3FE82000,
+/**/ 0xFC6BBFF4, 0xBF3AEFFC,
+/**/ 0xCD5B9000, 0x3FD21D34,
+/**/ 0xB28BADAA, 0x3D3B552F,
+/**/ 0x00000000, 0x3FE81800,
+/**/ 0x18181818, 0x3EE81818,
+/**/ 0xFBCF8000, 0x3FD22941,
+/**/ 0xF5EB0963, 0xBD3A6976,
+/**/ 0x00000000, 0x3FE81000,
+/**/ 0x4FF0F3C6, 0x3F3C7F27,
+/**/ 0xE5BC9000, 0x3FD2354C,
+/**/ 0x0602A663, 0xBD3D78ED,
+/**/ 0x00000000, 0x3FE81000,
+/**/ 0x0A86941D, 0xBF1ED344,
+/**/ 0x8BFD1000, 0x3FD24155,
+/**/ 0x3228FCAD, 0x3D300FFF,
+/**/ 0x00000000, 0x3FE80800,
+/**/ 0x1B0BD52D, 0x3F3424D0,
+/**/ 0xEF6AF000, 0x3FD24D5B,
+/**/ 0xFC9FABDD, 0xBCBDD780,
+/**/ 0x00000000, 0x3FE80800,
+/**/ 0xFE7F9FE8, 0xBF2FE7F9,
+/**/ 0x10DF7000, 0x3FD25960,
+/**/ 0x224EA3E3, 0x3D38E7BC,
+/**/ 0x00000000, 0x3FE80000,
+/**/ 0x18018018, 0x3F280180,
+/**/ 0xF1338000, 0x3FD26561,
+/**/ 0x66FAA45F, 0x3D38B488,
+/**/ 0x00000000, 0x3FE80000,
+/**/ 0x5FF40180, 0xBF37FD00,
+/**/ 0x913F8000, 0x3FD27161,
+/**/ 0xF61564B4, 0x3D34F4F1,
+/**/ 0x00000000, 0x3FE7F800,
+/**/ 0x9750B6C7, 0x3F104AE8,
+/**/ 0xF1DB6000, 0x3FD27D5E,
+/**/ 0x78CAC9F4, 0xBD092374,
+/**/ 0x00000000, 0x3FE7F800,
+/**/ 0xF405FD01, 0xBF3FD017,
+/**/ 0x13DE8000, 0x3FD2895A,
+/**/ 0xD24C13F0, 0x3D3A8D7A,
+/**/ 0x00000000, 0x3FE7F000,
+/**/ 0xC9C5485E, 0xBF0D2BF1,
+/**/ 0xF81FF000, 0x3FD29552,
+/**/ 0x1771C408, 0x3D348D30,
+/**/ 0x00000000, 0x3FE7E800,
+/**/ 0xD029DB60, 0x3F38927F,
+/**/ 0x9F763000, 0x3FD2A149,
+/**/ 0x51F3AADC, 0xBD30DBBF,
+/**/ 0x00000000, 0x3FE7E800,
+/**/ 0xB0A45169, 0xBF26504A,
+/**/ 0x0AB73000, 0x3FD2AD3E,
+/**/ 0x488C359F, 0x3D2B972E,
+/**/ 0x00000000, 0x3FE7E000,
+/**/ 0xD278E8DD, 0x3F312A8A,
+/**/ 0x3AB8A000, 0x3FD2B930,
+/**/ 0xD6BFB0A5, 0xBD26DB12,
+/**/ 0x00000000, 0x3FE7E000,
+/**/ 0x24BB32E7, 0xBF327577,
+/**/ 0x304F8000, 0x3FD2C520,
+/**/ 0x8C342F39, 0x3D230852,
+/**/ 0x00000000, 0x3FE7D800,
+/**/ 0xA4B45AEC, 0x3F23EF9A,
+/**/ 0xEC508000, 0x3FD2D10D,
+/**/ 0xF7088353, 0x3D360C61,
+/**/ 0x00000000, 0x3FE7D800,
+/**/ 0x32748CC1, 0xBF398DAF,
+/**/ 0x6F8FD000, 0x3FD2DCF9,
+/**/ 0x8E33C9CE, 0x3D20B4A2,
+/**/ 0x00000000, 0x3FE7D000,
+/**/ 0x417D05F4, 0x3F07D05F,
+/**/ 0xBAE12000, 0x3FD2E8E2,
+/**/ 0x99B72BD8, 0xBD267B1E,
+/**/ 0x00000000, 0x3FE7C800,
+/**/ 0x431D3027, 0x3F3F8EF7,
+/**/ 0xCF17A000, 0x3FD2F4C9,
+/**/ 0x9374B87B, 0x3D371F04,
+/**/ 0x00000000, 0x3FE7C800,
+/**/ 0xDAD83E6C, 0xBF0E77A3,
+/**/ 0xAD063000, 0x3FD300AE,
+/**/ 0x8B75FCAC, 0x3D342F56,
+/**/ 0x00000000, 0x3FE7C000,
+/**/ 0x588D1676, 0x3F38E041,
+/**/ 0x557F2000, 0x3FD30C91,
+/**/ 0xA1451755, 0xBD142958,
+/**/ 0x00000000, 0x3FE7C000,
+/**/ 0x1FE8414C, 0xBF24C6DD,
+/**/ 0xC9544000, 0x3FD31871,
+/**/ 0x94CECFD9, 0x3D184FAB,
+/**/ 0x00000000, 0x3FE7B800,
+/**/ 0x81C2D3B2, 0x3F3265F4,
+/**/ 0x09570000, 0x3FD32450,
+/**/ 0x9BDAE59D, 0x3D3D271B,
+/**/ 0x00000000, 0x3FE7B800,
+/**/ 0xB6466407, 0xBF30C39C,
+/**/ 0x16586000, 0x3FD3302C,
+/**/ 0xC2A3E08B, 0x3D36217D,
+/**/ 0x00000000, 0x3FE7B000,
+/**/ 0x12B21224, 0x3F283FAD,
+/**/ 0xF128E000, 0x3FD33C05,
+/**/ 0x380E1A7D, 0xBD22B906,
+/**/ 0x00000000, 0x3FE7B000,
+/**/ 0xF899E55D, 0xBF36EFB8,
+/**/ 0x9A988000, 0x3FD347DD,
+/**/ 0xD4C58092, 0xBD25594D,
+/**/ 0x00000000, 0x3FE7A800,
+/**/ 0x3FF42B9F, 0x3F1836B6,
+/**/ 0x1376E000, 0x3FD353B3,
+/**/ 0xE6C26D9B, 0xBD1331AF,
+/**/ 0x00000000, 0x3FE7A800,
+/**/ 0x0B739FF4, 0xBF3CE7FD,
+/**/ 0x5C933000, 0x3FD35F86,
+/**/ 0x4EA1A54A, 0xBD3B07DE,
+/**/ 0x00000000, 0x3FE7A000,
+/**/ 0xE8017A00, 0x3EC7A005,
+/**/ 0x76BC1000, 0x3FD36B57,
+/**/ 0x5A9C223F, 0x3D116978,
+/**/ 0x00000000, 0x3FE79800,
+/**/ 0xB1CC5B7B, 0x3F3D535D,
+/**/ 0x62BFE000, 0x3FD37726,
+/**/ 0xAC53B023, 0xBD3E9436,
+/**/ 0x00000000, 0x3FE79800,
+/**/ 0xE0DA37A9, 0xBF15EEAC,
+/**/ 0x216C5000, 0x3FD382F3,
+/**/ 0x1D1A7F6D, 0xBD1061D2,
+/**/ 0x00000000, 0x3FE79000,
+/**/ 0x344E16D6, 0x3F37C21E,
+/**/ 0xB38ED000, 0x3FD38EBD,
+/**/ 0xE67D4CA0, 0x3D290582,
+/**/ 0x00000000, 0x3FE79000,
+/**/ 0x39C9E465, 0xBF25E69A,
+/**/ 0x19F45000, 0x3FD39A86,
+/**/ 0x937354F5, 0x3D18EE51,
+/**/ 0x00000000, 0x3FE78800,
+/**/ 0xC52640BC, 0x3F32640B,
+/**/ 0x55694000, 0x3FD3A64C,
+/**/ 0xBCD735D0, 0x3D37A71C,
+/**/ 0x00000000, 0x3FE78800,
+/**/ 0x2F6A09ED, 0xBF3037DE,
+/**/ 0x66B9C000, 0x3FD3B210,
+/**/ 0x9811560E, 0xBD33C1ED,
+/**/ 0x00000000, 0x3FE78000,
+/**/ 0x01781A72, 0x3F2A71DC,
+/**/ 0x4EB15000, 0x3FD3BDD2,
+/**/ 0x970E6ED9, 0xBD3257B4,
+/**/ 0x00000000, 0x3FE78000,
+/**/ 0xA9EEBFF4, 0xBF354996,
+/**/ 0x0E1B2000, 0x3FD3C992,
+/**/ 0xAA680B76, 0x3D141C28,
+/**/ 0x00000000, 0x3FE77800,
+/**/ 0xAC60D341, 0x3F208119,
+/**/ 0xA5C1F000, 0x3FD3D54F,
+/**/ 0xD9A395E3, 0x3D3C3E1C,
+/**/ 0x00000000, 0x3FE77800,
+/**/ 0x742E2DD0, 0xBF3A28AE,
+/**/ 0x16701000, 0x3FD3E10B,
+/**/ 0x145429C7, 0x3D3F3BCF,
+/**/ 0x00000000, 0x3FE77000,
+/**/ 0x36340177, 0x3F0BD584,
+/**/ 0x60EF6000, 0x3FD3ECC4,
+/**/ 0x27C1300F, 0xBD060286,
+/**/ 0x00000000, 0x3FE77000,
+/**/ 0x240C7174, 0xBF3ED55D,
+/**/ 0x86094000, 0x3FD3F87B,
+/**/ 0x54589889, 0xBD35DFD7,
+/**/ 0x00000000, 0x3FE76800,
+/**/ 0xAB277F45, 0xBEF18DE5,
+/**/ 0x8686A000, 0x3FD40430,
+/**/ 0x3049F7D3, 0x3D3F8EF4,
+/**/ 0x00000000, 0x3FE76000,
+/**/ 0x01D3C7B8, 0x3F3CB026,
+/**/ 0x63303000, 0x3FD40FE3,
+/**/ 0xE79F05C6, 0x3D3E5C5F,
+/**/ 0x00000000, 0x3FE76000,
+/**/ 0xA9D08664, 0xBF15E95B,
+/**/ 0x1CCE1000, 0x3FD41B94,
+/**/ 0x13E43FC9, 0xBD304690,
+/**/ 0x00000000, 0x3FE75800,
+/**/ 0x097CFD43, 0x3F3867A4,
+/**/ 0xB427E000, 0x3FD42742,
+/**/ 0x02B82675, 0xBD398727,
+/**/ 0x00000000, 0x3FE75800,
+/**/ 0xE8A9353E, 0xBF2353DF,
+/**/ 0x2A04F000, 0x3FD432EF,
+/**/ 0x931715AD, 0xBD3FB129,
+/**/ 0x00000000, 0x3FE75000,
+/**/ 0x4F13DC4A, 0x3F3450E6,
+/**/ 0x7F2C1000, 0x3FD43E99,
+/**/ 0x40C41A04, 0x3D1C3F72,
+/**/ 0x00000000, 0x3FE75000,
+/**/ 0xE8B1B4FC, 0xBF2B4FBF,
+/**/ 0xB463C000, 0x3FD44A41,
+/**/ 0xF37CF612, 0x3D31EE28,
+/**/ 0x00000000, 0x3FE74800,
+/**/ 0x7E458100, 0x3F306BB6,
+/**/ 0xCA720000, 0x3FD455E7,
+/**/ 0x36629AED, 0x3D1AD8C6,
+/**/ 0x00000000, 0x3FE74800,
+/**/ 0x1745D174, 0xBF31745D,
+/**/ 0xC21C6000, 0x3FD4618B,
+/**/ 0x484C84CC, 0xBD13D82F,
+/**/ 0x00000000, 0x3FE74000,
+/**/ 0x236DEC04, 0x3F296FBD,
+/**/ 0x9C280000, 0x3FD46D2D,
+/**/ 0x5F67F75A, 0x3D359B27,
+/**/ 0x00000000, 0x3FE74000,
+/**/ 0x3B304B87, 0xBF350F9D,
+/**/ 0x5959B000, 0x3FD478CD,
+/**/ 0xF0C8D098, 0x3D2EC89B,
+/**/ 0x00000000, 0x3FE73800,
+/**/ 0xA4EBDC70, 0x3F226A51,
+/**/ 0xFA75C000, 0x3FD4846A,
+/**/ 0xE3798DCE, 0xBD263EA2,
+/**/ 0x00000000, 0x3FE73800,
+/**/ 0xF00B9A78, 0xBF3879D5,
+/**/ 0x80401000, 0x3FD49006,
+/**/ 0xFE1A0F8C, 0xBD38BCCF,
+/**/ 0x00000000, 0x3FE73000,
+/**/ 0x5DAAD90C, 0x3F178D7F,
+/**/ 0xEB7C1000, 0x3FD49B9F,
+/**/ 0x58AB60D7, 0x3D3DAC1C,
+/**/ 0x00000000, 0x3FE73000,
+/**/ 0x783709C7, 0xBF3BB33C,
+/**/ 0x3CED0000, 0x3FD4A737,
+/**/ 0xEBF35449, 0xBD39A234,
+/**/ 0x00000000, 0x3FE72800,
+/**/ 0x265AD23A, 0x3F061274,
+/**/ 0x75556000, 0x3FD4B2CC,
+/**/ 0xC78BFA4B, 0xBD380FCB,
+/**/ 0x00000000, 0x3FE72800,
+/**/ 0xC90A1FD2, 0xBF3EBC05,
+/**/ 0x95778000, 0x3FD4BE5F,
+/**/ 0xCD9AD824, 0xBD3D7C92,
+/**/ 0x00000000, 0x3FE72000,
+/**/ 0x38017200, 0xBEC71FFA,
+/**/ 0x9E153000, 0x3FD4C9F0,
+/**/ 0x70E02DE0, 0xBD2E1DDE,
+/**/ 0x00000000, 0x3FE71800,
+/**/ 0x74A050E1, 0x3F3E6B99,
+/**/ 0x8FEFE000, 0x3FD4D57F,
+/**/ 0x7FD06868, 0x3D23F926,
+/**/ 0x00000000, 0x3FE71800,
+/**/ 0xB8BD1180, 0xBF077400,
+/**/ 0x6BC8A000, 0x3FD4E10C,
+/**/ 0x1636F061, 0x3CF8283F,
+/**/ 0x00000000, 0x3FE71000,
+/**/ 0xE3E0453A, 0x3F3BC36C,
+/**/ 0x32600000, 0x3FD4EC97,
+/**/ 0xAF04D104, 0x3D234D7A,
+/**/ 0x00000000, 0x3FE71000,
+/**/ 0x6935DDC5, 0xBF15FA98,
+/**/ 0xE4764000, 0x3FD4F81F,
+/**/ 0x434FF08D, 0xBD27FCF6,
+/**/ 0x00000000, 0x3FE70800,
+/**/ 0x7337CF08, 0x3F394B40,
+/**/ 0x82CB2000, 0x3FD503A6,
+/**/ 0xF16F9B5D, 0xBD2A68C8,
+/**/ 0x00000000, 0x3FE70800,
+/**/ 0xA835403A, 0xBF1F7B97,
+/**/ 0x0E1E0000, 0x3FD50F2B,
+/**/ 0x8C47B8D8, 0x3D3A0940,
+/**/ 0x00000000, 0x3FE70000,
+/**/ 0x5C0B8170, 0x3F3702E0,
+/**/ 0x872E0000, 0x3FD51AAD,
+/**/ 0xDB0A7CC1, 0xBD3F4BD8,
+/**/ 0x00000000, 0x3FE70000,
+/**/ 0x4F67A855, 0xBF241EE6,
+/**/ 0xEEB99000, 0x3FD5262D,
+/**/ 0x70894A01, 0xBD3E1B9F,
+/**/ 0x00000000, 0x3FE6F800,
+/**/ 0x221C0170, 0x3F34EA19,
+/**/ 0x457EE000, 0x3FD531AC,
+/**/ 0x7D931501, 0x3D3DF83B,
+/**/ 0x00000000, 0x3FE6F800,
+/**/ 0x5508CA5C, 0xBF282102,
+/**/ 0x8C3BE000, 0x3FD53D28,
+/**/ 0xEB6DFAC5, 0xBD111397,
+/**/ 0x00000000, 0x3FE6F000,
+/**/ 0x9300B793, 0x3F3300B7,
+/**/ 0xC3ADD000, 0x3FD548A2,
+/**/ 0x63081CF7, 0x3D23167E,
+/**/ 0x00000000, 0x3FE6F000,
+/**/ 0x005BB90F, 0xBF2BC486,
+/**/ 0xEC91C000, 0x3FD5541A,
+/**/ 0xDC72EEBA, 0xBCF816AA,
+/**/ 0x00000000, 0x3FE6E800,
+/**/ 0xC5A3A00B, 0x3F314688,
+/**/ 0x07A44000, 0x3FD55F91,
+/**/ 0x78DF4A62, 0xBD11E647,
+/**/ 0x00000000, 0x3FE6E800,
+/**/ 0xDA9C5AE1, 0xBF2F09D6,
+/**/ 0x15A18000, 0x3FD56B05,
+/**/ 0xBC4A23FC, 0x3D29247B,
+/**/ 0x00000000, 0x3FE6E000,
+/**/ 0x337C6CB1, 0x3F2F76B4,
+/**/ 0x17456000, 0x3FD57677,
+/**/ 0x9524D7CA, 0xBD364EAD,
+/**/ 0x00000000, 0x3FE6E000,
+/**/ 0xEDF4EC87, 0xBF30F8AC,
+/**/ 0x0D4B3000, 0x3FD581E7,
+/**/ 0xB12D8F1D, 0xBD1F31E1,
+/**/ 0x00000000, 0x3FE6D800,
+/**/ 0x6EAEF381, 0x3F2CBDF2,
+/**/ 0xF86E0000, 0x3FD58D54,
+/**/ 0x0A795215, 0x3D2791F3,
+/**/ 0x00000000, 0x3FE6D800,
+/**/ 0xB624BFF5, 0xBF323DB9,
+/**/ 0xD9688000, 0x3FD598C0,
+/**/ 0x70D96DA4, 0xBD385F49,
+/**/ 0x00000000, 0x3FE6D000,
+/**/ 0x1C860FB0, 0x3F2A6268,
+/**/ 0xB0F4D000, 0x3FD5A42A,
+/**/ 0x2DF7BA69, 0xBCDE63AF,
+/**/ 0x00000000, 0x3FE6D000,
+/**/ 0xB253BAE1, 0xBF335443,
+/**/ 0x7FCCE000, 0x3FD5AF92,
+/**/ 0xF5FFC77A, 0xBD1C032F,
+/**/ 0x00000000, 0x3FE6C800,
+/**/ 0xAB4294D4, 0x3F2863B1,
+/**/ 0x46AA2000, 0x3FD5BAF8,
+/**/ 0xF873FA41, 0xBD339AE8,
+/**/ 0x00000000, 0x3FE6C800,
+/**/ 0x87EAA6DF, 0xBF343C7C,
+/**/ 0x0645A000, 0x3FD5C65C,
+/**/ 0x0180EE65, 0xBD39FE06,
+/**/ 0x00000000, 0x3FE6C000,
+/**/ 0x16C16C17, 0x3F26C16C,
+/**/ 0xBF581000, 0x3FD5D1BD,
+/**/ 0xC9C7C238, 0xBD38D6BD,
+/**/ 0x00000000, 0x3FE6C000,
+/**/ 0x95C33E00, 0xBF34F695,
+/**/ 0x7299C000, 0x3FD5DD1D,
+/**/ 0x8815CE17, 0xBD38AF61,
+/**/ 0x00000000, 0x3FE6B800,
+/**/ 0xE7802D73, 0x3F257B34,
+/**/ 0x20C29000, 0x3FD5E87B,
+/**/ 0x8F7738FA, 0x3D3527D1,
+/**/ 0x00000000, 0x3FE6B800,
+/**/ 0xF4A5582C, 0xBF3582BF,
+/**/ 0xCA8A2000, 0x3FD5F3D6,
+/**/ 0x8E19CC75, 0x3D37AF84,
+/**/ 0x00000000, 0x3FE6B000,
+/**/ 0x31A3CFC7, 0x3F2490AA,
+/**/ 0x70A79000, 0x3FD5FF30,
+/**/ 0x9F105039, 0x3D2E9E43,
+/**/ 0x00000000, 0x3FE6B000,
+/**/ 0x77C30E5A, 0xBF35E12C,
+/**/ 0x13D1A000, 0x3FD60A88,
+/**/ 0xC879AF55, 0x3D36E9B9,
+/**/ 0x00000000, 0x3FE6A800,
+/**/ 0x94016A94, 0x3F24016A,
+/**/ 0xB4BEC000, 0x3FD615DD,
+/**/ 0x90BC04B2, 0x3D13C7CA,
+/**/ 0x00000000, 0x3FE6A800,
+/**/ 0xAD33D63F, 0xBF36120B,
+/**/ 0x5424F000, 0x3FD62131,
+/**/ 0x4AA68669, 0xBD3382FC,
+/**/ 0x00000000, 0x3FE6A000,
+/**/ 0x3729043E, 0x3F23CD15,
+/**/ 0xF2B9C000, 0x3FD62C82,
+/**/ 0xBD7C8A98, 0x3D3E54BD } };
+
+static const union {int4 i[4350]; double x[2175]; } vj = { .i = {
+/**/ 0x7D161C28, 0x3F46A400,
+/**/ 0x20600000, 0xBF46A200,
+/**/ 0xAA7623D9, 0x3D27DC4E,
+/**/ 0xD596E639, 0x3F4693FA,
+/**/ 0x4CE00000, 0xBF4691FD,
+/**/ 0x29C3F0AD, 0x3D26B0CF,
+/**/ 0x3219CE89, 0x3F4683F5,
+/**/ 0x7B600000, 0xBF4681FA,
+/**/ 0x95B9FDCC, 0x3D22B290,
+/**/ 0x929ED397, 0x3F4673EF,
+/**/ 0xABE00000, 0xBF4671F7,
+/**/ 0xFA2F2D87, 0x3D17C727,
+/**/ 0xF725F3E2, 0x3F4663E9,
+/**/ 0xDE600000, 0xBF4661F4,
+/**/ 0x6EDBFF1C, 0x3CF22ED3,
+/**/ 0x5FAF2DE9, 0x3F4653E4,
+/**/ 0x12E00000, 0xBF4651F2,
+/**/ 0x157812BB, 0xBD144936,
+/**/ 0xCC3A802B, 0x3F4643DE,
+/**/ 0x49600000, 0xBF4641EF,
+/**/ 0x60314E05, 0xBD2959CB,
+/**/ 0x3CC7E927, 0x3F4633D9,
+/**/ 0x81E00000, 0xBF4631EC,
+/**/ 0xC3638E99, 0xBD35ABDA,
+/**/ 0xB157675C, 0x3F4623D3,
+/**/ 0xBC800000, 0xBF4621E9,
+/**/ 0xC63F9A21, 0x3D3FF1D3,
+/**/ 0x29E8F948, 0x3F4613CE,
+/**/ 0xF9000000, 0xBF4611E6,
+/**/ 0x71EEE611, 0x3D342D26,
+/**/ 0xA67C9D6B, 0x3F4603C8,
+/**/ 0x37800000, 0xBF4601E4,
+/**/ 0x11A09689, 0x3D1C1C77,
+/**/ 0x27125244, 0x3F45F3C3,
+/**/ 0x78000000, 0xBF45F1E1,
+/**/ 0xF7DC643C, 0xBD1DFD16,
+/**/ 0xABAA1651, 0x3F45E3BD,
+/**/ 0xBA800000, 0xBF45E1DE,
+/**/ 0x91318A02, 0xBD376503,
+/**/ 0x3443E812, 0x3F45D3B8,
+/**/ 0xFF200000, 0xBF45D1DB,
+/**/ 0xCE55DCDD, 0x3D3756E4,
+/**/ 0xC0DFC606, 0x3F45C3B2,
+/**/ 0x45A00000, 0xBF45C1D9,
+/**/ 0x8F6F8FA0, 0x3D12D5CF,
+/**/ 0x517DAEAB, 0x3F45B3AD,
+/**/ 0x8E200000, 0xBF45B1D6,
+/**/ 0x9B85DC2C, 0xBD2E90AB,
+/**/ 0xE61DA081, 0x3F45A3A7,
+/**/ 0xD8C00000, 0xBF45A1D3,
+/**/ 0x3BF5AC54, 0x3D3B5E88,
+/**/ 0x7EBF9A07, 0x3F4593A2,
+/**/ 0x25400000, 0xBF4591D1,
+/**/ 0x0C86DDB1, 0x3D12AC3A,
+/**/ 0x1B6399BB, 0x3F45839D,
+/**/ 0x73C00000, 0xBF4581CE,
+/**/ 0x76830985, 0xBD3361C2,
+/**/ 0xBC099E1C, 0x3F457397,
+/**/ 0xC4600000, 0xBF4571CB,
+/**/ 0xD062EBFF, 0x3D333915,
+/**/ 0x60B1A5AA, 0x3F456392,
+/**/ 0x16E00000, 0xBF4561C9,
+/**/ 0x9CC4988F, 0xBD1E0DA0,
+/**/ 0x095BAEE4, 0x3F45538D,
+/**/ 0x6B800000, 0xBF4551C6,
+/**/ 0x235BC18A, 0x3D3C69C4,
+/**/ 0xB607B848, 0x3F454387,
+/**/ 0xC2000000, 0xBF4541C3,
+/**/ 0xF7737723, 0xBCEFCC99,
+/**/ 0x66B5C056, 0x3F453382,
+/**/ 0x1A800000, 0xBF4531C1,
+/**/ 0x809CBCBB, 0xBD3FBAE2,
+/**/ 0x1B65C58C, 0x3F45237D,
+/**/ 0x75200000, 0xBF4521BE,
+/**/ 0x194FEE63, 0x3CCAA5C8,
+/**/ 0xD417C66A, 0x3F451377,
+/**/ 0xD1C00000, 0xBF4511BB,
+/**/ 0xE1CC7BBC, 0x3D3ED325,
+/**/ 0x90CBC16E, 0x3F450372,
+/**/ 0x30400000, 0xBF4501B9,
+/**/ 0x68AB3742, 0xBD0F0298,
+/**/ 0x5181B517, 0x3F44F36D,
+/**/ 0x90E00000, 0xBF44F1B6,
+/**/ 0x41E67AD9, 0x3D381BE1,
+/**/ 0x16399FE6, 0x3F44E368,
+/**/ 0xF3600000, 0xBF44E1B3,
+/**/ 0x668D3662, 0xBD2A6E79,
+/**/ 0xDEF38058, 0x3F44D362,
+/**/ 0x58000000, 0xBF44D1B1,
+/**/ 0x21F8B7C2, 0x3D284EA7,
+/**/ 0xABAF54EC, 0x3F44C35D,
+/**/ 0xBE800000, 0xBF44C1AE,
+/**/ 0x7417D9C5, 0xBD3BC76D,
+/**/ 0x7C6D1C22, 0x3F44B358,
+/**/ 0x27200000, 0xBF44B1AC,
+/**/ 0x16AAD1FC, 0xBD1409FD,
+/**/ 0x512CD479, 0x3F44A353,
+/**/ 0x91C00000, 0xBF44A1A9,
+/**/ 0x98BC14FD, 0x3D30771E,
+/**/ 0x29EE7C70, 0x3F44934E,
+/**/ 0xFE400000, 0xBF4491A6,
+/**/ 0x5CCB7232, 0xBD3B5993,
+/**/ 0x06B21285, 0x3F448349,
+/**/ 0x6CE00000, 0xBF4481A4,
+/**/ 0x5512F9C2, 0xBD20E729,
+/**/ 0xE7779538, 0x3F447343,
+/**/ 0xDD800000, 0xBF4471A1,
+/**/ 0x55B30899, 0x3D225436,
+/**/ 0xCC3F0308, 0x3F44633E,
+/**/ 0x50200000, 0xBF44619F,
+/**/ 0x9E54E31F, 0x3D39807C,
+/**/ 0xB5085A73, 0x3F445339,
+/**/ 0xC4A00000, 0xBF44519C,
+/**/ 0xD5804C0E, 0xBD376F6F,
+/**/ 0xA1D399FA, 0x3F444334,
+/**/ 0x3B400000, 0xBF44419A,
+/**/ 0x6CDE6425, 0xBD234953,
+/**/ 0x92A0C01A, 0x3F44332F,
+/**/ 0xB3E00000, 0xBF443197,
+/**/ 0xAAF6596F, 0x3D070E7B,
+/**/ 0x876FCB54, 0x3F44232A,
+/**/ 0x2E800000, 0xBF442195,
+/**/ 0x4EC011F1, 0x3D2C49F8,
+/**/ 0x8040BA25, 0x3F441325,
+/**/ 0xAB200000, 0xBF441192,
+/**/ 0xD8AAA7EB, 0x3D3825DC,
+/**/ 0x7D138B0E, 0x3F440320,
+/**/ 0x29A00000, 0xBF440190,
+/**/ 0xFE0B73D6, 0xBD3F1A8D,
+/**/ 0x7DE83C8C, 0x3F43F31B,
+/**/ 0xAA400000, 0xBF43F18D,
+/**/ 0xE46CA26B, 0xBD379B43,
+/**/ 0x82BECD20, 0x3F43E316,
+/**/ 0x2CE00000, 0xBF43E18B,
+/**/ 0x6283780D, 0xBD315B44,
+/**/ 0x8B973B49, 0x3F43D311,
+/**/ 0xB1800000, 0xBF43D188,
+/**/ 0x017589BE, 0xBD28B31E,
+/**/ 0x98718584, 0x3F43C30C,
+/**/ 0x38200000, 0xBF43C186,
+/**/ 0x8FBB296E, 0xBD212A46,
+/**/ 0xA94DAA52, 0x3F43B307,
+/**/ 0xC0C00000, 0xBF43B183,
+/**/ 0x045CBBD2, 0xBD183403,
+/**/ 0xBE2BA832, 0x3F43A302,
+/**/ 0x4B600000, 0xBF43A181,
+/**/ 0xD7CC5936, 0xBD13009B,
+/**/ 0xD70B7DA2, 0x3F4392FD,
+/**/ 0xD8000000, 0xBF43917E,
+/**/ 0xC1742279, 0xBD12B655,
+/**/ 0xF3ED2921, 0x3F4382F8,
+/**/ 0x66A00000, 0xBF43817C,
+/**/ 0xEA83FAE8, 0xBD17512E,
+/**/ 0x14D0A930, 0x3F4372F4,
+/**/ 0xF7400000, 0xBF437179,
+/**/ 0xBED65875, 0xBD206692,
+/**/ 0x39B5FC4C, 0x3F4362EF,
+/**/ 0x89E00000, 0xBF436177,
+/**/ 0xD38FFE9E, 0xBD27931B,
+/**/ 0x629D20F5, 0x3F4352EA,
+/**/ 0x1E800000, 0xBF435175,
+/**/ 0xE524208F, 0xBD309618,
+/**/ 0x8F8615AA, 0x3F4342E5,
+/**/ 0xB5200000, 0xBF434172,
+/**/ 0xDD4C72C5, 0xBD3697E9,
+/**/ 0xC070D8EB, 0x3F4332E0,
+/**/ 0x4DC00000, 0xBF433170,
+/**/ 0x5E6E12C3, 0xBD3DCE00,
+/**/ 0xF55D6935, 0x3F4322DB,
+/**/ 0xE8800000, 0xBF43216D,
+/**/ 0x0AE9A8CE, 0x3D39C8A4,
+/**/ 0x2E4BC509, 0x3F4312D7,
+/**/ 0x85200000, 0xBF43116B,
+/**/ 0xD1CD2FA1, 0x3D302D03,
+/**/ 0x6B3BEAE5, 0x3F4302D2,
+/**/ 0x23C00000, 0xBF430169,
+/**/ 0xA3BADFD1, 0x3D15807D,
+/**/ 0xAC2DD949, 0x3F42F2CD,
+/**/ 0xC4600000, 0xBF42F166,
+/**/ 0xF57F0504, 0xBD1A7422,
+/**/ 0xF1218EB3, 0x3F42E2C8,
+/**/ 0x67000000, 0xBF42E164,
+/**/ 0x2F2C781C, 0xBD33C974,
+/**/ 0x3A1709A3, 0x3F42D2C4,
+/**/ 0x0BC00000, 0xBF42D162,
+/**/ 0x851A1E61, 0x3D3DDBDD,
+/**/ 0x870E4898, 0x3F42C2BF,
+/**/ 0xB2600000, 0xBF42C15F,
+/**/ 0xA14AA8FD, 0x3D2CA7D9,
+/**/ 0xD8074A10, 0x3F42B2BA,
+/**/ 0x5B000000, 0xBF42B15D,
+/**/ 0xDDCDDFF5, 0xBD03022E,
+/**/ 0x2D020C8C, 0x3F42A2B6,
+/**/ 0x05A00000, 0xBF42A15B,
+/**/ 0x0F9231A8, 0xBD343FBA,
+/**/ 0x85FE8E8A, 0x3F4292B1,
+/**/ 0xB2600000, 0xBF429158,
+/**/ 0xA52C9CCF, 0x3D38B690,
+/**/ 0xE2FCCE8A, 0x3F4282AC,
+/**/ 0x61000000, 0xBF428156,
+/**/ 0xC8CC82EB, 0x3D120E6A,
+/**/ 0x43FCCB0A, 0x3F4272A8,
+/**/ 0x11A00000, 0xBF427154,
+/**/ 0x792E6C51, 0xBD30D79B,
+/**/ 0xA8FE8289, 0x3F4262A3,
+/**/ 0xC4600000, 0xBF426151,
+/**/ 0x91F7F7AA, 0x3D38A5EE,
+/**/ 0x1201F387, 0x3F42529F,
+/**/ 0x79000000, 0xBF42514F,
+/**/ 0x46C2E8BA, 0x3CEFA728,
+/**/ 0x7F071C84, 0x3F42429A,
+/**/ 0x2FA00000, 0xBF42414D,
+/**/ 0xFA447A17, 0xBD37D0BA,
+/**/ 0xF00DFBFD, 0x3F423295,
+/**/ 0xE8600000, 0xBF42314A,
+/**/ 0x94AF3FED, 0x3D2C7A24,
+/**/ 0x65169072, 0x3F422291,
+/**/ 0xA3000000, 0xBF422148,
+/**/ 0x050CEA04, 0xBD29B0BD,
+/**/ 0xDE20D863, 0x3F42128C,
+/**/ 0x5FC00000, 0xBF421146,
+/**/ 0x0C3035EB, 0x3D36EFF3,
+/**/ 0x5B2CD24E, 0x3F420288,
+/**/ 0x1E600000, 0xBF420144,
+/**/ 0x73569B27, 0xBD19A3E2,
+/**/ 0xDC3A7CB2, 0x3F41F283,
+/**/ 0xDF200000, 0xBF41F141,
+/**/ 0xEEB67715, 0x3D3B1DDE,
+/**/ 0x6149D610, 0x3F41E27F,
+/**/ 0xA1C00000, 0xBF41E13F,
+/**/ 0x94F49154, 0xBD11EA17,
+/**/ 0xEA5ADCE5, 0x3F41D27A,
+/**/ 0x66800000, 0xBF41D13D,
+/**/ 0x52DD9D37, 0x3D3ACED9,
+/**/ 0x776D8FB1, 0x3F41C276,
+/**/ 0x2D200000, 0xBF41C13B,
+/**/ 0xF72D8EEB, 0xBD1C140B,
+/**/ 0x0881ECF4, 0x3F41B272,
+/**/ 0xF5E00000, 0xBF41B138,
+/**/ 0x939583E1, 0x3D360AE5,
+/**/ 0x9D97F32C, 0x3F41A26D,
+/**/ 0xC0800000, 0xBF41A136,
+/**/ 0x1D246C7C, 0xBD2C00D9,
+/**/ 0x36AFA0D9, 0x3F419269,
+/**/ 0x8D400000, 0xBF419134,
+/**/ 0x0B955CFB, 0x3D29B40E,
+/**/ 0xD3C8F479, 0x3F418264,
+/**/ 0x5BE00000, 0xBF418132,
+/**/ 0x45A6C249, 0xBD3964BF,
+/**/ 0x74E3EC8D, 0x3F417260,
+/**/ 0x2CA00000, 0xBF417130,
+/**/ 0xF3363612, 0xBCE777E0,
+/**/ 0x1A008792, 0x3F41625C,
+/**/ 0xFF600000, 0xBF41612D,
+/**/ 0x28DE8296, 0x3D36D608,
+/**/ 0xC31EC409, 0x3F415257,
+/**/ 0xD4000000, 0xBF41512B,
+/**/ 0x4BB1B788, 0xBD32AE69,
+/**/ 0x703EA071, 0x3F414253,
+/**/ 0xAAC00000, 0xBF414129,
+/**/ 0x170ECD8C, 0x3D05BF68,
+/**/ 0x21601B48, 0x3F41324F,
+/**/ 0x83800000, 0xBF413127,
+/**/ 0x7C653BFC, 0x3D370A0B,
+/**/ 0xD683330E, 0x3F41224A,
+/**/ 0x5E200000, 0xBF412125,
+/**/ 0x77BBBEBF, 0xBD35B70D,
+/**/ 0x8FA7E642, 0x3F411246,
+/**/ 0x3AE00000, 0xBF411123,
+/**/ 0x93ABC1CD, 0xBD0C52EB,
+/**/ 0x4CCE3363, 0x3F410242,
+/**/ 0x19A00000, 0xBF410121,
+/**/ 0xE5C6F4C7, 0x3D2B2237,
+/**/ 0x0DF618F1, 0x3F40F23E,
+/**/ 0xFA600000, 0xBF40F11E,
+/**/ 0x1E9A50AD, 0x3D3D9C5F,
+/**/ 0xD31F956A, 0x3F40E239,
+/**/ 0xDD000000, 0xBF40E11C,
+/**/ 0x8965F0DA, 0xBD336793,
+/**/ 0x9C4AA74E, 0x3F40D235,
+/**/ 0xC1C00000, 0xBF40D11A,
+/**/ 0x7E49E231, 0xBD15E6EE,
+/**/ 0x69774D1D, 0x3F40C231,
+/**/ 0xA8800000, 0xBF40C118,
+/**/ 0x04FD621C, 0x3D1D9B9D,
+/**/ 0x3AA58554, 0x3F40B22D,
+/**/ 0x91400000, 0xBF40B116,
+/**/ 0x7DD9EED3, 0x3D333B55,
+/**/ 0x0FD54E74, 0x3F40A229,
+/**/ 0x7C000000, 0xBF40A114,
+/**/ 0x7AA78478, 0x3D3E048F,
+/**/ 0xE906A6FC, 0x3F409224,
+/**/ 0x68A00000, 0xBF409112,
+/**/ 0x644DDE88, 0xBD383C6A,
+/**/ 0xC6398D6B, 0x3F408220,
+/**/ 0x57600000, 0xBF408110,
+/**/ 0x76B8C83A, 0xBD2F0D2F,
+/**/ 0xA76E0040, 0x3F40721C,
+/**/ 0x48200000, 0xBF40710E,
+/**/ 0x9CE99FD3, 0xBD1F63E0,
+/**/ 0x8CA3FDFB, 0x3F406218,
+/**/ 0x3AE00000, 0xBF40610C,
+/**/ 0x4FE774F2, 0xBCF328B4,
+/**/ 0x75DB851A, 0x3F405214,
+/**/ 0x2FA00000, 0xBF40510A,
+/**/ 0x3782BCD4, 0x3D11B6BD,
+/**/ 0x6314941D, 0x3F404210,
+/**/ 0x26600000, 0xBF404108,
+/**/ 0xE7183792, 0x3D22116F,
+/**/ 0x544F2983, 0x3F40320C,
+/**/ 0x1F200000, 0xBF403106,
+/**/ 0x1B995B3D, 0x3D293F1E,
+/**/ 0x498B43CB, 0x3F402208,
+/**/ 0x19E00000, 0xBF402104,
+/**/ 0xFC162630, 0x3D2E6669,
+/**/ 0x42C8E175, 0x3F401204,
+/**/ 0x16A00000, 0xBF401102,
+/**/ 0x254FC9F8, 0x3D30C4AA,
+/**/ 0x40080100, 0x3F400200,
+/**/ 0x15600000, 0xBF400100,
+/**/ 0xE4431F92, 0x3D3154EE,
+/**/ 0x829141D6, 0x3F3FE3F8,
+/**/ 0x2C400000, 0xBF3FE1FC,
+/**/ 0x9B2D30FB, 0x3D30E503,
+/**/ 0x8D157F6B, 0x3F3FC3F0,
+/**/ 0x31C00000, 0xBF3FC1F8,
+/**/ 0x53EBD670, 0x3D2EEBD1,
+/**/ 0x9F9CB7BC, 0x3F3FA3E8,
+/**/ 0x3B400000, 0xBF3FA1F4,
+/**/ 0xE04A16E0, 0x3D2A113C,
+/**/ 0xBA26E7CA, 0x3F3F83E0,
+/**/ 0x48C00000, 0xBF3F81F0,
+/**/ 0x99C43E34, 0x3D233C4A,
+/**/ 0xDCB40C91, 0x3F3F63D8,
+/**/ 0x5A400000, 0xBF3F61EC,
+/**/ 0x7BD210C1, 0x3D14DDF6,
+/**/ 0x07442311, 0x3F3F43D1,
+/**/ 0x6FC00000, 0xBF3F41E8,
+/**/ 0x9E4B51C8, 0xBCC52C1D,
+/**/ 0x39D72849, 0x3F3F23C9,
+/**/ 0x89400000, 0xBF3F21E4,
+/**/ 0x8EA8C754, 0xBD1A196F,
+/**/ 0x746D1936, 0x3F3F03C1,
+/**/ 0xA6C00000, 0xBF3F01E0,
+/**/ 0xF95AF98D, 0xBD2BB719,
+/**/ 0xB705F2D8, 0x3F3EE3B9,
+/**/ 0xC8400000, 0xBF3EE1DC,
+/**/ 0x28FFD598, 0xBD3628EB,
+/**/ 0x01A1B22C, 0x3F3EC3B2,
+/**/ 0xEDC00000, 0xBF3EC1D8,
+/**/ 0x0BBAC8F8, 0xBD3F6D76,
+/**/ 0x54405432, 0x3F3EA3AA,
+/**/ 0x17800000, 0xBF3EA1D5,
+/**/ 0xB7A7EE0D, 0x3D3657D2,
+/**/ 0xAEE1D5E8, 0x3F3E83A2,
+/**/ 0x45000000, 0xBF3E81D1,
+/**/ 0xFA9CCC78, 0x3D264FDE,
+/**/ 0x1186344C, 0x3F3E639B,
+/**/ 0x76800000, 0xBF3E61CD,
+/**/ 0xE02EF455, 0xBCEF83EB,
+/**/ 0x7C2D6C5E, 0x3F3E4393,
+/**/ 0xAC000000, 0xBF3E41C9,
+/**/ 0x03C3E129, 0xBD2C26B3,
+/**/ 0xEED77B1B, 0x3F3E238B,
+/**/ 0xE5800000, 0xBF3E21C5,
+/**/ 0x904D773D, 0xBD3C1CBE,
+/**/ 0x69845D83, 0x3F3E0384,
+/**/ 0x23400000, 0xBF3E01C2,
+/**/ 0xD0615454, 0x3D34E8B1,
+/**/ 0xEC341093, 0x3F3DE37C,
+/**/ 0x64C00000, 0xBF3DE1BE,
+/**/ 0xE9BE933E, 0x3D13F7DF,
+/**/ 0x76E6914B, 0x3F3DC375,
+/**/ 0xAA400000, 0xBF3DC1BA,
+/**/ 0x707B004A, 0xBD27B7D7,
+/**/ 0x099BDCA9, 0x3F3DA36E,
+/**/ 0xF3C00000, 0xBF3DA1B6,
+/**/ 0xEE2141C3, 0xBD3DA3F8,
+/**/ 0xA453EFAC, 0x3F3D8366,
+/**/ 0x41800000, 0xBF3D81B3,
+/**/ 0x63D21825, 0x3D2F4DA1,
+/**/ 0x470EC752, 0x3F3D635F,
+/**/ 0x93000000, 0xBF3D61AF,
+/**/ 0xFAD0B844, 0xBD0FD473,
+/**/ 0xF1CC609A, 0x3F3D4357,
+/**/ 0xE8800000, 0xBF3D41AB,
+/**/ 0x298657C2, 0xBD388716,
+/**/ 0xA48CB882, 0x3F3D2350,
+/**/ 0x42400000, 0xBF3D21A8,
+/**/ 0x0B68711A, 0x3D32023A,
+/**/ 0x5F4FCC0A, 0x3F3D0349,
+/**/ 0x9FC00000, 0xBF3D01A4,
+/**/ 0x23A704B0, 0xBD117676,
+/**/ 0x22159830, 0x3F3CE342,
+/**/ 0x01400000, 0xBF3CE1A1,
+/**/ 0x8F391F09, 0xBD3BA59C,
+/**/ 0xECDE19F1, 0x3F3CC33A,
+/**/ 0x67000000, 0xBF3CC19D,
+/**/ 0x9EBBF706, 0x3D28567A,
+/**/ 0xBFA94E4E, 0x3F3CA333,
+/**/ 0xD0800000, 0xBF3CA199,
+/**/ 0x2D41F1CC, 0xBD29D41F,
+/**/ 0x9A773245, 0x3F3C832C,
+/**/ 0x3E400000, 0xBF3C8196,
+/**/ 0x14ED5134, 0x3D391B7D,
+/**/ 0x7D47C2D4, 0x3F3C6325,
+/**/ 0xAFC00000, 0xBF3C6192,
+/**/ 0x83403B5B, 0xBCFC31C5,
+/**/ 0x681AFCFA, 0x3F3C431E,
+/**/ 0x25400000, 0xBF3C418F,
+/**/ 0x88A1FFF3, 0xBD3D84DB,
+/**/ 0x5AF0DDB6, 0x3F3C2317,
+/**/ 0x9F000000, 0xBF3C218B,
+/**/ 0x6298A63B, 0x3D175CFF,
+/**/ 0x55C96207, 0x3F3C0310,
+/**/ 0x1C800000, 0xBF3C0188,
+/**/ 0xDFB8E489, 0xBD37ADC9,
+/**/ 0x58A486EA, 0x3F3BE309,
+/**/ 0x9E400000, 0xBF3BE184,
+/**/ 0x45069C64, 0x3D23DA0F,
+/**/ 0x6382495F, 0x3F3BC302,
+/**/ 0x23C00000, 0xBF3BC181,
+/**/ 0x4CC2EFE0, 0xBD35574B,
+/**/ 0x7662A665, 0x3F3BA2FB,
+/**/ 0xAD800000, 0xBF3BA17D,
+/**/ 0x4BED0B89, 0x3D250C7B,
+/**/ 0x91459AFA, 0x3F3B82F4,
+/**/ 0x3B000000, 0xBF3B817A,
+/**/ 0x322E5605, 0xBD36795D,
+/**/ 0xB42B241D, 0x3F3B62ED,
+/**/ 0xCCC00000, 0xBF3B6176,
+/**/ 0xF6413886, 0x3D1EAB91,
+/**/ 0xDF133ECC, 0x3F3B42E6,
+/**/ 0x62400000, 0xBF3B4173,
+/**/ 0xF86BE5B5, 0xBD3B0BFC,
+/**/ 0x11FDE807, 0x3F3B22E0,
+/**/ 0xFC000000, 0xBF3B216F,
+/**/ 0xDDE8D701, 0x3CF62FEB,
+/**/ 0x4CEB1CCC, 0x3F3B02D9,
+/**/ 0x99C00000, 0xBF3B016C,
+/**/ 0xF210FD9E, 0x3D3CF8D7,
+/**/ 0x8FDADA1A, 0x3F3AE2D2,
+/**/ 0x3B400000, 0xBF3AE169,
+/**/ 0x1526CFB0, 0xBD2092E2,
+/**/ 0xDACD1CEF, 0x3F3AC2CB,
+/**/ 0xE1000000, 0xBF3AC165,
+/**/ 0x18D261D5, 0x3D319D24,
+/**/ 0x2DC1E24A, 0x3F3AA2C5,
+/**/ 0x8A800000, 0xBF3AA162,
+/**/ 0x533CC8EC, 0xBD355268,
+/**/ 0x88B9272B, 0x3F3A82BE,
+/**/ 0x38400000, 0xBF3A815F,
+/**/ 0x0AFE6139, 0x3D074750,
+/**/ 0xEBB2E88F, 0x3F3A62B7,
+/**/ 0xEA000000, 0xBF3A615B,
+/**/ 0x6668AD57, 0x3D3A501B,
+/**/ 0x56AF2375, 0x3F3A42B1,
+/**/ 0x9F800000, 0xBF3A4158,
+/**/ 0xA98381BD, 0xBD2E37A7,
+/**/ 0xC9ADD4DD, 0x3F3A22AA,
+/**/ 0x59400000, 0xBF3A2155,
+/**/ 0x7B82F9AC, 0x3D1A9872,
+/**/ 0x44AEF9C5, 0x3F3A02A4,
+/**/ 0x17000000, 0xBF3A0152,
+/**/ 0x0FF040AD, 0x3D3B96ED,
+/**/ 0xC7B28F2C, 0x3F39E29D,
+/**/ 0xD8800000, 0xBF39E14E,
+/**/ 0x33534BD7, 0xBD304862,
+/**/ 0x52B89211, 0x3F39C297,
+/**/ 0x9E400000, 0xBF39C14B,
+/**/ 0x17AF009B, 0x3D084979,
+/**/ 0xE5C0FF72, 0x3F39A290,
+/**/ 0x68000000, 0xBF39A148,
+/**/ 0x604B64C9, 0x3D358CA1,
+/**/ 0x80CBD44E, 0x3F39828A,
+/**/ 0x35800000, 0xBF398145,
+/**/ 0x2E334404, 0xBD38BD0B,
+/**/ 0x23D90DA4, 0x3F396284,
+/**/ 0x07400000, 0xBF396142,
+/**/ 0xEF1B1C68, 0xBD1F4B58,
+/**/ 0xCEE8A873, 0x3F39427D,
+/**/ 0xDD000000, 0xBF39413E,
+/**/ 0x07E010EC, 0x3D209881,
+/**/ 0x81FAA1B9, 0x3F392277,
+/**/ 0xB6C00000, 0xBF39213B,
+/**/ 0x5CF03181, 0x3D37A139,
+/**/ 0x3D0EF676, 0x3F390271,
+/**/ 0x94400000, 0xBF390138,
+/**/ 0x65276B0B, 0xBD39D2EB,
+/**/ 0x0025A3A8, 0x3F38E26B,
+/**/ 0x76000000, 0xBF38E135,
+/**/ 0xEE3023F6, 0xBD281E5A,
+/**/ 0xCB3EA64F, 0x3F38C264,
+/**/ 0x5BC00000, 0xBF38C132,
+/**/ 0x3F9A4B53, 0x3CEDAE6E,
+/**/ 0x9E59FB68, 0x3F38A25E,
+/**/ 0x45800000, 0xBF38A12F,
+/**/ 0x412B648E, 0x3D2A47EF,
+/**/ 0x79779FF3, 0x3F388258,
+/**/ 0x33400000, 0xBF38812C,
+/**/ 0x5ED0D8F2, 0x3D38955F,
+/**/ 0x5C9790EE, 0x3F386252,
+/**/ 0x24C00000, 0xBF386129,
+/**/ 0x09939374, 0xBD3CBD55,
+/**/ 0x47B9CB5A, 0x3F38424C,
+/**/ 0x1A800000, 0xBF384126,
+/**/ 0x4F399186, 0xBD32D325,
+/**/ 0x3ADE4C33, 0x3F382246,
+/**/ 0x14400000, 0xBF382123,
+/**/ 0x524688EB, 0xBD235622,
+/**/ 0x3605107A, 0x3F380240,
+/**/ 0x12000000, 0xBF380120,
+/**/ 0xEB2F3DDC, 0xBCF44184,
+/**/ 0x392E152C, 0x3F37E23A,
+/**/ 0x13C00000, 0xBF37E11D,
+/**/ 0x2153D1B8, 0x3D198B16,
+/**/ 0x4459574A, 0x3F37C234,
+/**/ 0x19800000, 0xBF37C11A,
+/**/ 0x47A3C923, 0x3D2A9511,
+/**/ 0x5786D3D1, 0x3F37A22E,
+/**/ 0x23400000, 0xBF37A117,
+/**/ 0x4B4128D9, 0x3D337431,
+/**/ 0x72B687C1, 0x3F378228,
+/**/ 0x31000000, 0xBF378114,
+/**/ 0xC5BFE9E8, 0x3D38E0BF,
+/**/ 0x95E87019, 0x3F376222,
+/**/ 0x42C00000, 0xBF376111,
+/**/ 0x5A0B2CE9, 0x3D3D9134,
+/**/ 0xC11C89D8, 0x3F37421C,
+/**/ 0x58400000, 0xBF37410E,
+/**/ 0xB1802C40, 0xBD3E7970,
+/**/ 0xF452D1FB, 0x3F372216,
+/**/ 0x72000000, 0xBF37210B,
+/**/ 0x16E562C9, 0xBD3B3E2F,
+/**/ 0x2F8B4583, 0x3F370211,
+/**/ 0x8FC00000, 0xBF370108,
+/**/ 0x9087DACD, 0xBD38BC06,
+/**/ 0x72C5E16F, 0x3F36E20B,
+/**/ 0xB1800000, 0xBF36E105,
+/**/ 0xD92B1B21, 0xBD36F1F6,
+/**/ 0xBE02A2BC, 0x3F36C205,
+/**/ 0xD7400000, 0xBF36C102,
+/**/ 0xABF2CD23, 0xBD35DEFF,
+/**/ 0x1141866B, 0x3F36A200,
+/**/ 0x01000000, 0xBF36A100,
+/**/ 0xC462BC85, 0xBD358220,
+/**/ 0x6C828979, 0x3F3681FA,
+/**/ 0x2EC00000, 0xBF3680FD,
+/**/ 0xDE5ED723, 0xBD35DA59,
+/**/ 0xCFC5A8E7, 0x3F3661F4,
+/**/ 0x60800000, 0xBF3660FA,
+/**/ 0xB62B2CD1, 0xBD36E6AA,
+/**/ 0x3B0AE1B2, 0x3F3641EF,
+/**/ 0x96400000, 0xBF3640F7,
+/**/ 0x086BEF29, 0xBD38A613,
+/**/ 0xAE5230DA, 0x3F3621E9,
+/**/ 0xD0000000, 0xBF3620F4,
+/**/ 0x9225715D, 0xBD3B1792,
+/**/ 0x299B935F, 0x3F3601E4,
+/**/ 0x0DC00000, 0xBF3600F2,
+/**/ 0x10BC2805, 0xBD3E3A29,
+/**/ 0xACE7063E, 0x3F35E1DE,
+/**/ 0x4FC00000, 0xBF35E0EF,
+/**/ 0xBE0B570D, 0x3D3DF329,
+/**/ 0x38348676, 0x3F35C1D9,
+/**/ 0x95800000, 0xBF35C0EC,
+/**/ 0x1C0C5502, 0x3D397166,
+/**/ 0xCB841108, 0x3F35A1D3,
+/**/ 0xDF400000, 0xBF35A0E9,
+/**/ 0x4AC1FA2D, 0x3D34418C,
+/**/ 0x66D5A2F1, 0x3F3581CE,
+/**/ 0x2D000000, 0xBF3580E7,
+/**/ 0x168E9C6E, 0x3D2CC939,
+/**/ 0x0A293931, 0x3F3561C9,
+/**/ 0x7EC00000, 0xBF3560E4,
+/**/ 0x795CE154, 0x3D1F6E5C,
+/**/ 0xB57ED0C7, 0x3F3541C3,
+/**/ 0xD4800000, 0xBF3540E1,
+/**/ 0x898FEE67, 0x3CE4EF88,
+/**/ 0x68D666B1, 0x3F3521BE,
+/**/ 0x2E400000, 0xBF3520DF,
+/**/ 0x0B78D65E, 0xBD1CDACF,
+/**/ 0x242FF7EF, 0x3F3501B9,
+/**/ 0x8C000000, 0xBF3500DC,
+/**/ 0x6F1CBFB8, 0xBD2F7BF1,
+/**/ 0xE78B8180, 0x3F34E1B3,
+/**/ 0xEDC00000, 0xBF34E0D9,
+/**/ 0x5A899820, 0xBD38ED52,
+/**/ 0xB2E90063, 0x3F34C1AE,
+/**/ 0x53C00000, 0xBF34C0D7,
+/**/ 0x930A694E, 0x3D3D3C3F,
+/**/ 0x86487196, 0x3F34A1A9,
+/**/ 0xBD800000, 0xBF34A0D4,
+/**/ 0x4FA7CCCB, 0x3D32BFBD,
+/**/ 0x61A9D219, 0x3F3481A4,
+/**/ 0x2B400000, 0xBF3480D2,
+/**/ 0x65A26E32, 0x3D1E789C,
+/**/ 0x450D1EEB, 0x3F34619F,
+/**/ 0x9D000000, 0xBF3460CF,
+/**/ 0x47E500B5, 0xBD109E0B,
+/**/ 0x3072550B, 0x3F34419A,
+/**/ 0x12C00000, 0xBF3440CD,
+/**/ 0x3523FAE9, 0xBD309040,
+/**/ 0x23D97178, 0x3F342195,
+/**/ 0x8C800000, 0xBF3420CA,
+/**/ 0xD31DE7C2, 0xBD3D9B10,
+/**/ 0x1F427131, 0x3F340190,
+/**/ 0x0A800000, 0xBF3400C8,
+/**/ 0x90B287C4, 0x3D34B90B,
+/**/ 0x22AD5135, 0x3F33E18B,
+/**/ 0x8C400000, 0xBF33E0C5,
+/**/ 0xCA1B0FC2, 0x3D19B454,
+/**/ 0x2E1A0E83, 0x3F33C186,
+/**/ 0x12000000, 0xBF33C0C3,
+/**/ 0x638FC1F4, 0xBD20FBE7,
+/**/ 0x4188A61A, 0x3F33A181,
+/**/ 0x9BC00000, 0xBF33A0C0,
+/**/ 0xE0C03290, 0xBD38070E,
+/**/ 0x5CF914F9, 0x3F33817C,
+/**/ 0x29C00000, 0xBF3380BE,
+/**/ 0xE0B6E5F5, 0x3D37D2C3,
+/**/ 0x806B5820, 0x3F336177,
+/**/ 0xBB800000, 0xBF3360BB,
+/**/ 0x35598794, 0x3D1C4213,
+/**/ 0xABDF6C8D, 0x3F334172,
+/**/ 0x51400000, 0xBF3340B9,
+/**/ 0xC111C569, 0xBD249997,
+/**/ 0xDF554F40, 0x3F33216D,
+/**/ 0xEB000000, 0xBF3320B6,
+/**/ 0xEEEE28E2, 0xBD3C442D,
+/**/ 0x1ACCFD37, 0x3F330169,
+/**/ 0x89000000, 0xBF3300B4,
+/**/ 0xDBBF316D, 0x3D312B5E,
+/**/ 0x5E467372, 0x3F32E164,
+/**/ 0x2AC00000, 0xBF32E0B2,
+/**/ 0x7484E6E1, 0xBCFFD254,
+/**/ 0xA9C1AEF0, 0x3F32C15F,
+/**/ 0xD0800000, 0xBF32C0AF,
+/**/ 0x1F2C3F9D, 0xBD35BCBA,
+/**/ 0xFD3EACAF, 0x3F32A15A,
+/**/ 0x7A800000, 0xBF32A0AD,
+/**/ 0x8C8BAA61, 0x3D35EDA0,
+/**/ 0x58BD69B0, 0x3F328156,
+/**/ 0x28400000, 0xBF3280AB,
+/**/ 0x3F79FE5E, 0x3CF02EAF,
+/**/ 0xBC3DE2F1, 0x3F326151,
+/**/ 0xDA000000, 0xBF3260A8,
+/**/ 0xB1304AA8, 0xBD347BDA,
+/**/ 0x27C01572, 0x3F32414D,
+/**/ 0x90000000, 0xBF3240A6,
+/**/ 0xD46BE359, 0x3D35724F,
+/**/ 0x9B43FE30, 0x3F322148,
+/**/ 0x49C00000, 0xBF3220A4,
+/**/ 0x43BF90C9, 0xBCF31954,
+/**/ 0x16C99A2D, 0x3F320144,
+/**/ 0x07800000, 0xBF3200A2,
+/**/ 0xC4901E30, 0xBD386689,
+/**/ 0x9A50E666, 0x3F31E13F,
+/**/ 0xC9800000, 0xBF31E09F,
+/**/ 0x134E34BF, 0x3D2FA8E5,
+/**/ 0x25D9DFDB, 0x3F31C13B,
+/**/ 0x8F400000, 0xBF31C09D,
+/**/ 0x477D87DF, 0xBD20FF40,
+/**/ 0xB964838C, 0x3F31A136,
+/**/ 0x59400000, 0xBF31A09B,
+/**/ 0x68B5B77B, 0x3D3E9E3E,
+/**/ 0x54F0CE76, 0x3F318132,
+/**/ 0x27000000, 0xBF318099,
+/**/ 0x906F8A53, 0x3D14BC39,
+/**/ 0xF87EBD9A, 0x3F31612D,
+/**/ 0xF8C00000, 0xBF316096,
+/**/ 0xFCD50724, 0xBD34CC2F,
+/**/ 0xA40E4DF7, 0x3F314129,
+/**/ 0xCEC00000, 0xBF314094,
+/**/ 0x7A3A1B8D, 0x3D30AD83,
+/**/ 0x579F7C8B, 0x3F312125,
+/**/ 0xA8800000, 0xBF312092,
+/**/ 0x057F5C66, 0xBD24C5AE,
+/**/ 0x13324657, 0x3F310121,
+/**/ 0x86800000, 0xBF310090,
+/**/ 0xBFD488E0, 0x3D3A03C0,
+/**/ 0xD6C6A858, 0x3F30E11C,
+/**/ 0x68400000, 0xBF30E08E,
+/**/ 0x56935D63, 0xBD00EDA8,
+/**/ 0xA25C9F8F, 0x3F30C118,
+/**/ 0x4E000000, 0xBF30C08C,
+/**/ 0x2FDDD1CE, 0xBD3EC638,
+/**/ 0x75F428FB, 0x3F30A114,
+/**/ 0x38000000, 0xBF30A08A,
+/**/ 0x0CA3DCBE, 0x3D102CDE,
+/**/ 0x518D419B, 0x3F308110,
+/**/ 0x25C00000, 0xBF308088,
+/**/ 0xBFA78921, 0xBD39A865,
+/**/ 0x3527E66D, 0x3F30610C,
+/**/ 0x17C00000, 0xBF306086,
+/**/ 0x72CE37BD, 0x3D203FE0,
+/**/ 0x20C41472, 0x3F304108,
+/**/ 0x0D800000, 0xBF304084,
+/**/ 0x6054C3FA, 0xBD369AC6,
+/**/ 0x1461C8A9, 0x3F302104,
+/**/ 0x07800000, 0xBF302082,
+/**/ 0x4836293A, 0x3D2450ED,
+/**/ 0x10010010, 0x3F300100,
+/**/ 0x05400000, 0xBF300080,
+/**/ 0x88B3357C, 0xBD359558,
+/**/ 0x27436F4F, 0x3F2FC1F8,
+/**/ 0x0E800000, 0xBF2FC0FC,
+/**/ 0x92ECD4D1, 0x3D245998,
+/**/ 0x3E87D8DC, 0x3F2F81F0,
+/**/ 0x1A000000, 0xBF2F80F8,
+/**/ 0xB592170A, 0xBD36901A,
+/**/ 0x65CF36C6, 0x3F2F41E8,
+/**/ 0x2E000000, 0xBF2F40F4,
+/**/ 0x53524603, 0x3D2069E5,
+/**/ 0x9D19830B, 0x3F2F01E0,
+/**/ 0x49800000, 0xBF2F00F0,
+/**/ 0x69C22240, 0xBD39830B,
+/**/ 0xE466B7AB, 0x3F2EC1D8,
+/**/ 0x6D800000, 0xBF2EC0EC,
+/**/ 0xFB871BBA, 0x3D1123AC,
+/**/ 0x3BB6CEA4, 0x3F2E81D1,
+/**/ 0x99000000, 0xBF2E80E8,
+/**/ 0x2E158AF6, 0xBD3E6629,
+/**/ 0xA309C1F4, 0x3F2E41C9,
+/**/ 0xCD000000, 0xBF2E40E4,
+/**/ 0x2B29884E, 0xBCF8F488,
+/**/ 0x1A5F8B99, 0x3F2E01C2,
+/**/ 0x09000000, 0xBF2E00E1,
+/**/ 0x6EA006C6, 0x3D3ACE8D,
+/**/ 0xA1B82593, 0x3F2DC1BA,
+/**/ 0x4C800000, 0xBF2DC0DD,
+/**/ 0x59D0B687, 0xBD22974E,
+/**/ 0x391389E0, 0x3F2D81B3,
+/**/ 0x98800000, 0xBF2D80D9,
+/**/ 0xD7897CAD, 0x3D322319,
+/**/ 0xE071B27F, 0x3F2D41AB,
+/**/ 0xEC000000, 0xBF2D40D5,
+/**/ 0x57954C6E, 0xBD32E42F,
+/**/ 0x97D2996E, 0x3F2D01A4,
+/**/ 0x48000000, 0xBF2D00D2,
+/**/ 0xC741610E, 0x3D1E7DF5,
+/**/ 0x5F3638AB, 0x3F2CC19D,
+/**/ 0xAB800000, 0xBF2CC0CE,
+/**/ 0xA0909C5A, 0xBD3E50DF,
+/**/ 0x369C8A37, 0x3F2C8196,
+/**/ 0x17800000, 0xBF2C80CB,
+/**/ 0x8D8D1C8F, 0xBD12D119,
+/**/ 0x1E05880E, 0x3F2C418F,
+/**/ 0x8B800000, 0xBF2C40C7,
+/**/ 0x544D2574, 0x3D347649,
+/**/ 0x15712C30, 0x3F2C0188,
+/**/ 0x07000000, 0xBF2C00C4,
+/**/ 0x4EEA9E68, 0xBD32D030,
+/**/ 0x1CDF709C, 0x3F2BC181,
+/**/ 0x8B000000, 0xBF2BC0C0,
+/**/ 0x74A84109, 0x3D15E533,
+/**/ 0x34504F50, 0x3F2B817A,
+/**/ 0x17000000, 0xBF2B80BD,
+/**/ 0x025FBF68, 0x3D3D53C1,
+/**/ 0x5BC3C24B, 0x3F2B4173,
+/**/ 0xAA800000, 0xBF2B40B9,
+/**/ 0x6BAA2FA8, 0xBD267FA7,
+/**/ 0x9339C38C, 0x3F2B016C,
+/**/ 0x46800000, 0xBF2B00B6,
+/**/ 0xBB3FDE1E, 0x3D277F1D,
+/**/ 0xDAB24D11, 0x3F2AC165,
+/**/ 0xEA000000, 0xBF2AC0B2,
+/**/ 0x1A8CDBE2, 0xBD3DAD17,
+/**/ 0x322D58D9, 0x3F2A815F,
+/**/ 0x96000000, 0xBF2A80AF,
+/**/ 0xD81CF36E, 0xBD1E1315,
+/**/ 0x99AAE0E3, 0x3F2A4158,
+/**/ 0x4A000000, 0xBF2A40AC,
+/**/ 0xE649E7B4, 0x3D2C7307,
+/**/ 0x112ADF2D, 0x3F2A0152,
+/**/ 0x05800000, 0xBF2A00A9,
+/**/ 0xB77435EC, 0xBD3C713A,
+/**/ 0x98AD4DB7, 0x3F29C14B,
+/**/ 0xC9800000, 0xBF29C0A5,
+/**/ 0x3A7AE827, 0xBD1E1005,
+/**/ 0x3032267F, 0x3F298145,
+/**/ 0x95800000, 0xBF2980A2,
+/**/ 0xA8F2A842, 0x3D2A0460,
+/**/ 0xD7B96385, 0x3F29413E,
+/**/ 0x69000000, 0xBF29409F,
+/**/ 0xA7B8321E, 0xBD3EDDA5,
+/**/ 0x8F42FEC5, 0x3F290138,
+/**/ 0x45000000, 0xBF29009C,
+/**/ 0x3A3F0D33, 0xBD264506,
+/**/ 0x56CEF241, 0x3F28C132,
+/**/ 0x29000000, 0xBF28C099,
+/**/ 0x33EE13CD, 0x3D206930,
+/**/ 0x2E5D37F6, 0x3F28812C,
+/**/ 0x15000000, 0xBF288096,
+/**/ 0x22DF1FDA, 0x3D3B28AC,
+/**/ 0x15EDC9E3, 0x3F284126,
+/**/ 0x08800000, 0xBF284093,
+/**/ 0xDD73B6DB, 0xBD324546,
+/**/ 0x0D80A208, 0x3F280120,
+/**/ 0x04800000, 0xBF280090,
+/**/ 0x6DFEB485, 0xBCB440C2,
+/**/ 0x1515BA62, 0x3F27C11A,
+/**/ 0x08800000, 0xBF27C08D,
+/**/ 0x9823B19D, 0x3D31BCBE,
+/**/ 0x2CAD0CF1, 0x3F278114,
+/**/ 0x14000000, 0xBF27808A,
+/**/ 0xA9EB4E97, 0xBD3CD148,
+/**/ 0x544693B4, 0x3F27410E,
+/**/ 0x28000000, 0xBF274087,
+/**/ 0xCA4F73AA, 0xBD277AAC,
+/**/ 0x8BE248AA, 0x3F270108,
+/**/ 0x44000000, 0xBF270084,
+/**/ 0x26068EF7, 0x3D13E656,
+/**/ 0xD38025D2, 0x3F26C102,
+/**/ 0x68000000, 0xBF26C081,
+/**/ 0x44C3EC8A, 0x3D35547B,
+/**/ 0x2B20252A, 0x3F2680FD,
+/**/ 0x93800000, 0xBF26807E,
+/**/ 0x110DCE4B, 0xBD3AABA5,
+/**/ 0x92C240B1, 0x3F2640F7,
+/**/ 0xC7800000, 0xBF26407B,
+/**/ 0xAC011956, 0xBD260B96,
+/**/ 0x0A667267, 0x3F2600F2,
+/**/ 0x03800000, 0xBF260079,
+/**/ 0x5DFA826E, 0x3D111C22,
+/**/ 0x920CB44A, 0x3F25C0EC,
+/**/ 0x47800000, 0xBF25C076,
+/**/ 0xD8A2980A, 0x3D333BD6,
+/**/ 0x29B5005A, 0x3F2580E7,
+/**/ 0x93000000, 0xBF258073,
+/**/ 0x71C1D861, 0xBD3E2660,
+/**/ 0xD15F5095, 0x3F2540E1,
+/**/ 0xE7000000, 0xBF254070,
+/**/ 0x4E77E5EE, 0xBD2FBD3A,
+/**/ 0x890B9EFA, 0x3F2500DC,
+/**/ 0x43000000, 0xBF25006E,
+/**/ 0x7B90A2D9, 0xBCFEBDF2,
+/**/ 0x50B9E589, 0x3F24C0D7,
+/**/ 0xA7000000, 0xBF24C06B,
+/**/ 0x58F2FF2C, 0x3D2765B3,
+/**/ 0x286A1E40, 0x3F2480D2,
+/**/ 0x13000000, 0xBF248069,
+/**/ 0x74AE382C, 0x3D38FE8D,
+/**/ 0x101C431E, 0x3F2440CD,
+/**/ 0x86800000, 0xBF244066,
+/**/ 0xB0286224, 0xBD3A07C3,
+/**/ 0x07D04E23, 0x3F2400C8,
+/**/ 0x02800000, 0xBF240064,
+/**/ 0x46EFC0EC, 0xBD2ABE33,
+/**/ 0x0F86394D, 0x3F23C0C3,
+/**/ 0x86800000, 0xBF23C061,
+/**/ 0x70DE3151, 0xBCF06744,
+/**/ 0x273DFE9C, 0x3F2380BE,
+/**/ 0x12800000, 0xBF23805F,
+/**/ 0x05CFCD61, 0x3D260659,
+/**/ 0x4EF7980F, 0x3F2340B9,
+/**/ 0xA6800000, 0xBF23405C,
+/**/ 0xD7DBBEBC, 0x3D36BEC8,
+/**/ 0x86B2FFA4, 0x3F2300B4,
+/**/ 0x42000000, 0xBF23005A,
+/**/ 0x2B2027B4, 0xBD3DD29F,
+/**/ 0xCE702F5C, 0x3F22C0AF,
+/**/ 0xE6000000, 0xBF22C057,
+/**/ 0x6959A7D0, 0xBD32B00B,
+/**/ 0x262F2134, 0x3F2280AB,
+/**/ 0x92000000, 0xBF228055,
+/**/ 0x19FAAC2D, 0xBD1F61EF,
+/**/ 0x8DEFCF2C, 0x3F2240A6,
+/**/ 0x46000000, 0xBF224053,
+/**/ 0xCB16B8A8, 0x3D05A87E,
+/**/ 0x05B23344, 0x3F2200A2,
+/**/ 0x02000000, 0xBF220051,
+/**/ 0x23B9B257, 0x3D29F32F,
+/**/ 0x8D76477A, 0x3F21C09D,
+/**/ 0xC6000000, 0xBF21C04E,
+/**/ 0x7E214821, 0x3D36F61B,
+/**/ 0x253C05CD, 0x3F218099,
+/**/ 0x91800000, 0xBF21804C,
+/**/ 0x46FDFCA2, 0xBD3F5464,
+/**/ 0xCD03683D, 0x3F214094,
+/**/ 0x65800000, 0xBF21404A,
+/**/ 0xA30F2308, 0xBD35E4E7,
+/**/ 0x84CC68C9, 0x3F210090,
+/**/ 0x41800000, 0xBF210048,
+/**/ 0xF800CC34, 0xBD2974DC,
+/**/ 0x4C970171, 0x3F20C08C,
+/**/ 0x25800000, 0xBF20C046,
+/**/ 0xC1006E9D, 0xBD0E9FC5,
+/**/ 0x24632C32, 0x3F208088,
+/**/ 0x11800000, 0xBF208044,
+/**/ 0x078E4438, 0x3D133DE7,
+/**/ 0x0C30E30D, 0x3F204084,
+/**/ 0x05800000, 0xBF204042,
+/**/ 0x15F82A7B, 0x3D2A61D2,
+/**/ 0x04002001, 0x3F200080,
+/**/ 0x01800000, 0xBF200040,
+/**/ 0x3BBB110C, 0x3D355155,
+/**/ 0x17A1BA1A, 0x3F1F80F8,
+/**/ 0x0B000000, 0xBF1F807C,
+/**/ 0x6C520A9B, 0x3D3D31BE,
+/**/ 0x47462860, 0x3F1F00F0,
+/**/ 0x22000000, 0xBF1F0078,
+/**/ 0x4B6D83F6, 0xBD3B2CDB,
+/**/ 0x96ED7ED3, 0x3F1E80E8,
+/**/ 0x4A000000, 0xBF1E8074,
+/**/ 0xD4122C5A, 0xBD33C977,
+/**/ 0x0697B172, 0x3F1E00E1,
+/**/ 0x82000000, 0xBF1E0070,
+/**/ 0x2D1517C4, 0xBD29462E,
+/**/ 0x9644B43B, 0x3F1D80D9,
+/**/ 0xCA000000, 0xBF1D806C,
+/**/ 0xF0952D45, 0xBD16E2E3,
+/**/ 0x45F47B2C, 0x3F1D00D2,
+/**/ 0x22000000, 0xBF1D0069,
+/**/ 0x2DDC2A8D, 0x3CEED452,
+/**/ 0x15A6FA46, 0x3F1C80CB,
+/**/ 0x8A000000, 0xBF1C8065,
+/**/ 0xA08CEBE8, 0x3D1DAFEE,
+/**/ 0x055C2585, 0x3F1C00C4,
+/**/ 0x02000000, 0xBF1C0062,
+/**/ 0xBB11EF55, 0x3D2B50A4,
+/**/ 0x1513F0E9, 0x3F1B80BD,
+/**/ 0x8A000000, 0xBF1B805E,
+/**/ 0xC6D142BF, 0x3D33ACA6,
+/**/ 0x44CE5071, 0x3F1B00B6,
+/**/ 0x22000000, 0xBF1B005B,
+/**/ 0xF8CD3D11, 0x3D3979F8,
+/**/ 0x948B381A, 0x3F1A80AF,
+/**/ 0xCA000000, 0xBF1A8057,
+/**/ 0x07EDFD29, 0x3D3F1149,
+/**/ 0x044A9BE5, 0x3F1A00A9,
+/**/ 0x81000000, 0xBF1A0054,
+/**/ 0xF7BB7092, 0xBD3B8C68,
+/**/ 0x940C6FCF, 0x3F1980A2,
+/**/ 0x49000000, 0xBF198051,
+/**/ 0xF27E09A9, 0xBD365E1C,
+/**/ 0x43D0A7D8, 0x3F19009C,
+/**/ 0x21000000, 0xBF19004E,
+/**/ 0xD508D564, 0xBD3162D2,
+/**/ 0x139737FE, 0x3F188096,
+/**/ 0x09000000, 0xBF18804B,
+/**/ 0x18D5C93E, 0xBD293315,
+/**/ 0x03601440, 0x3F180090,
+/**/ 0x01000000, 0xBF180048,
+/**/ 0x0C26A328, 0xBD200288,
+/**/ 0x132B309E, 0x3F17808A,
+/**/ 0x09000000, 0xBF178045,
+/**/ 0x7E89FD6F, 0xBD0CC7F9,
+/**/ 0x42F88115, 0x3F170084,
+/**/ 0x21000000, 0xBF170042,
+/**/ 0x058494DC, 0x3CE40881,
+/**/ 0x92C7F9A5, 0x3F16807E,
+/**/ 0x49000000, 0xBF16803F,
+/**/ 0xCD5698B9, 0x3D12AE16,
+/**/ 0x02998E4D, 0x3F160079,
+/**/ 0x81000000, 0xBF16003C,
+/**/ 0xC5780E17, 0x3D21138B,
+/**/ 0x926D330B, 0x3F158073,
+/**/ 0xC9000000, 0xBF158039,
+/**/ 0x4E2001E2, 0x3D287809,
+/**/ 0x4242DBDF, 0x3F15006E,
+/**/ 0x21000000, 0xBF150037,
+/**/ 0x21448AA2, 0x3D2F8684,
+/**/ 0x121A7CC8, 0x3F148069,
+/**/ 0x89000000, 0xBF148034,
+/**/ 0x2F637D8E, 0x3D33207E,
+/**/ 0x01F409C4, 0x3F140064,
+/**/ 0x01000000, 0xBF140032,
+/**/ 0x12E44B29, 0x3D3654B9,
+/**/ 0x11CF76D3, 0x3F13805F,
+/**/ 0x89000000, 0xBF13802F,
+/**/ 0xCA5547F3, 0x3D3960F2,
+/**/ 0x41ACB7F4, 0x3F13005A,
+/**/ 0x21000000, 0xBF13002D,
+/**/ 0x6487063D, 0x3D3C462B,
+/**/ 0x918BC126, 0x3F128055,
+/**/ 0xC9000000, 0xBF12802A,
+/**/ 0xEFEA1107, 0x3D3F0562,
+/**/ 0x016C8668, 0x3F120051,
+/**/ 0x80000000, 0xBF120028,
+/**/ 0x857113CE, 0xBD3E6066,
+/**/ 0x914EFBBA, 0x3F11804C,
+/**/ 0x48000000, 0xBF118026,
+/**/ 0xEDD9EB54, 0xBD3BEA30,
+/**/ 0x41331519, 0x3F110048,
+/**/ 0x20000000, 0xBF110024,
+/**/ 0x3BFFFF5A, 0xBD3996FC,
+/**/ 0x1118C686, 0x3F108044,
+/**/ 0x08000000, 0xBF108022,
+/**/ 0x62F2E042, 0xBD3765C8,
+/**/ 0x01000400, 0x3F100040,
+/**/ 0x00000000, 0xBF100020,
+/**/ 0x562224CD, 0xBD355595,
+/**/ 0x21D1830C, 0x3F0F0078,
+/**/ 0x10000000, 0xBF0F003C,
+/**/ 0x095D69EB, 0xBD336563,
+/**/ 0x81A5E62E, 0x3F0E0070,
+/**/ 0x40000000, 0xBF0E0038,
+/**/ 0x70D45290, 0xBD319431,
+/**/ 0x217D1965, 0x3F0D0069,
+/**/ 0x90000000, 0xBF0D0034,
+/**/ 0x022D0EF6, 0xBD2FC201,
+/**/ 0x015704B1, 0x3F0C0062,
+/**/ 0x00000000, 0xBF0C0031,
+/**/ 0x5E276E21, 0xBD2C95A0,
+/**/ 0x2133900E, 0x3F0B005B,
+/**/ 0x90000000, 0xBF0B002D,
+/**/ 0xE0372A42, 0xBD29A140,
+/**/ 0x8112A37D, 0x3F0A0054,
+/**/ 0x40000000, 0xBF0A002A,
+/**/ 0x73BBB580, 0xBD26E2E2,
+/**/ 0x20F426FB, 0x3F09004E,
+/**/ 0x10000000, 0xBF090027,
+/**/ 0x04D48C20, 0xBD245885,
+/**/ 0x00D80288, 0x3F080048,
+/**/ 0x00000000, 0xBF080024,
+/**/ 0x80613426, 0xBD220028,
+/**/ 0x20BE1E23, 0x3F070042,
+/**/ 0x10000000, 0xBF070021,
+/**/ 0xA80279F3, 0xBD1FAF99,
+/**/ 0x80A661CA, 0x3F06003C,
+/**/ 0x40000000, 0xBF06001E,
+/**/ 0xDC287DFE, 0xBD1BBAE3,
+/**/ 0x2090B57C, 0x3F050037,
+/**/ 0x90000000, 0xBF05001B,
+/**/ 0x7B73B67C, 0xBD181E2F,
+/**/ 0x007D0139, 0x3F040032,
+/**/ 0x00000000, 0xBF040019,
+/**/ 0x65A375F8, 0xBD14D57C,
+/**/ 0x206B2CFF, 0x3F03002D,
+/**/ 0x90000000, 0xBF030016,
+/**/ 0x7BF71EC1, 0xBD11DCCA,
+/**/ 0x805B20CD, 0x3F020028,
+/**/ 0x40000000, 0xBF020014,
+/**/ 0x425C4447, 0xBD0E6033,
+/**/ 0x204CC4A3, 0x3F010024,
+/**/ 0x10000000, 0xBF010012,
+/**/ 0x730FFF5C, 0xBD0996D3,
+/**/ 0x00400080, 0x3F000020,
+/**/ 0x00000000, 0xBF000010,
+/**/ 0x558888DE, 0xBD055575,
+/**/ 0x406978C6, 0x3EFE0038,
+/**/ 0x20000000, 0xBEFE001C,
+/**/ 0xB845146A, 0xBD019418,
+/**/ 0x0055C096, 0x3EFC0031,
+/**/ 0x80000000, 0xBEFC0018,
+/**/ 0xD989DB3C, 0xBCFC957A,
+/**/ 0x4044A870, 0x3EFA002A,
+/**/ 0x20000000, 0xBEFA0015,
+/**/ 0x8F0EED2F, 0xBCF6E2C6,
+/**/ 0x00360051, 0x3EF80024,
+/**/ 0x00000000, 0xBEF80012,
+/**/ 0x40184CEB, 0xBCF20014,
+/**/ 0x40299839, 0x3EF6001E,
+/**/ 0x20000000, 0xBEF6000F,
+/**/ 0x434A1F5C, 0xBCEBBAC7,
+/**/ 0x001F4027, 0x3EF40019,
+/**/ 0x80000000, 0xBEF4000C,
+/**/ 0xDD68DD6A, 0xBCE4D568,
+/**/ 0x4016C81A, 0x3EF20014,
+/**/ 0x20000000, 0xBEF2000A,
+/**/ 0xA11710FC, 0xBCDE6019,
+/**/ 0x00100010, 0x3EF00010,
+/**/ 0x00000000, 0xBEF00008,
+/**/ 0x5562222D, 0xBCD55565,
+/**/ 0x80157013, 0x3EEC0018,
+/**/ 0x40000000, 0xBEEC000C,
+/**/ 0x176276C5, 0xBCCC9568,
+/**/ 0x000D800A, 0x3EE80012,
+/**/ 0x00000000, 0xBEE80009,
+/**/ 0x20061337, 0xBCC2000A,
+/**/ 0x8007D005, 0x3EE4000C,
+/**/ 0x40000000, 0xBEE40006,
+/**/ 0x195A3758, 0xBCB4D55F,
+/**/ 0x00040002, 0x3EE00008,
+/**/ 0x00000000, 0xBEE00004,
+/**/ 0x5558888A, 0xBCA5555D,
+/**/ 0x00036001, 0x3ED80009,
+/**/ 0x80000000, 0xBED80004,
+/**/ 0x100184CD, 0xBC920005,
+/**/ 0x00010000, 0x3ED00004,
+/**/ 0x00000000, 0xBED00002,
+/**/ 0x55562222, 0xBC755559,
+/**/ 0x00004000, 0x3EC00002,
+/**/ 0x00000000, 0xBEC00001,
+/**/ 0x55558889, 0xBC455557,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00000000, 0x00000000,
+/**/ 0x00008000, 0xBEBFFFFC,
+/**/ 0x00000000, 0x3EBFFFFE,
+/**/ 0x55558889, 0x3C455553,
+/**/ 0x00020000, 0xBECFFFF8,
+/**/ 0x00000000, 0x3ECFFFFC,
+/**/ 0x55562222, 0x3C755551,
+/**/ 0x00035FFF, 0xBED7FFF7,
+/**/ 0x80000000, 0x3ED7FFFB,
+/**/ 0xF00184CC, 0x3C91FFFA,
+/**/ 0x0007FFFC, 0xBEDFFFF0,
+/**/ 0x00000000, 0x3EDFFFF8,
+/**/ 0x55588887, 0x3CA5554D,
+/**/ 0x8007CFFB, 0xBEE3FFF3,
+/**/ 0xC0000000, 0x3EE3FFF9,
+/**/ 0x915A3753, 0x3CB4D54B,
+/**/ 0x000D7FF6, 0xBEE7FFEE,
+/**/ 0x00000000, 0x3EE7FFF7,
+/**/ 0xE006132F, 0x3CC1FFF5,
+/**/ 0x80156FED, 0xBEEBFFE7,
+/**/ 0xC0000000, 0x3EEBFFF3,
+/**/ 0x936276B2, 0x3CCC9542,
+/**/ 0x001FFFE0, 0xBEEFFFE0,
+/**/ 0x00000000, 0x3EEFFFF0,
+/**/ 0x55622217, 0x3CD55545,
+/**/ 0xC016C7E6, 0xBEF1FFEB,
+/**/ 0xE0000000, 0x3EF1FFF5,
+/**/ 0x5F1710D1, 0x3CDE5FE6,
+/**/ 0x001F3FD9, 0xBEF3FFE7,
+/**/ 0x80000000, 0x3EF3FFF3,
+/**/ 0xCD68DD41, 0x3CE4D541,
+/**/ 0xC02997C7, 0xBEF5FFE1,
+/**/ 0xE0000000, 0x3EF5FFF0,
+/**/ 0x124A1F13, 0x3CEBBA8E,
+/**/ 0x0035FFAF, 0xBEF7FFDC,
+/**/ 0x00000000, 0x3EF7FFEE,
+/**/ 0xC0184CAE, 0x3CF1FFEB,
+/**/ 0xC044A790, 0xBEF9FFD5,
+/**/ 0xE0000000, 0x3EF9FFEA,
+/**/ 0xC68EECCD, 0x3CF6E28E,
+/**/ 0x0055BF6A, 0xBEFBFFCF,
+/**/ 0x80000000, 0x3EFBFFE7,
+/**/ 0xD189DAA2, 0x3CFC952F,
+/**/ 0xC069773A, 0xBEFDFFC7,
+/**/ 0xE0000000, 0x3EFDFFE3,
+/**/ 0x480513F6, 0x3D0193E7,
+/**/ 0x007FFF00, 0xBEFFFFC0,
+/**/ 0x00000000, 0x3EFFFFE0,
+/**/ 0x55888833, 0x3D055535,
+/**/ 0xE04CC35D, 0xBF00FFDB,
+/**/ 0xF0000000, 0x3F00FFED,
+/**/ 0xE2CFFE66, 0x3D099681,
+/**/ 0x805B1F33, 0xBF01FFD7,
+/**/ 0xC0000000, 0x3F01FFEB,
+/**/ 0xBE5C42ED, 0x3D0E5FCC,
+/**/ 0xE06B2B01, 0xBF02FFD2,
+/**/ 0x70000000, 0x3F02FFE9,
+/**/ 0xD9D71DD1, 0x3D11DC8A,
+/**/ 0x007CFEC8, 0xBF03FFCE,
+/**/ 0x00000000, 0x3F03FFE7,
+/**/ 0x45A374B3, 0x3D14D52E,
+/**/ 0xE090B284, 0xBF04FFC8,
+/**/ 0x70000000, 0x3F04FFE4,
+/**/ 0x8553B4C7, 0x3D181DD0,
+/**/ 0x80A65E36, 0xBF05FFC3,
+/**/ 0xC0000000, 0x3F05FFE1,
+/**/ 0x7A287BBE, 0x3D1BBA71,
+/**/ 0xE0BE19DD, 0xBF06FFBD,
+/**/ 0xF0000000, 0x3F06FFDE,
+/**/ 0x03E27702, 0x3D1FAF11,
+/**/ 0x00D7FD78, 0xBF07FFB8,
+/**/ 0x00000000, 0x3F07FFDC,
+/**/ 0x80613240, 0x3D21FFD7,
+/**/ 0xE0F42105, 0xBF08FFB1,
+/**/ 0xF0000000, 0x3F08FFD8,
+/**/ 0xA6C489B3, 0x3D245825,
+/**/ 0x81129C84, 0xBF09FFAB,
+/**/ 0xC0000000, 0x3F09FFD5,
+/**/ 0xE2BBB26F, 0x3D26E272,
+/**/ 0xE13387F2, 0xBF0AFFA4,
+/**/ 0x70000000, 0x3F0AFFD2,
+/**/ 0x21272669, 0x3D29A0BF,
+/**/ 0x0156FB50, 0xBF0BFF9E,
+/**/ 0x00000000, 0x3F0BFFCF,
+/**/ 0x4E276957, 0x3D2C950A,
+/**/ 0xE17D0E9B, 0xBF0CFF96,
+/**/ 0x70000000, 0x3F0CFFCB,
+/**/ 0x551D090E, 0x3D2FC154,
+/**/ 0x81A5D9D2, 0xBF0DFF8F,
+/**/ 0xC0000000, 0x3F0DFFC7,
+/**/ 0x90544EF1, 0x3D3193CE,
+/**/ 0xE1D174F4, 0xBF0EFF87,
+/**/ 0xF0000000, 0x3F0EFFC3,
+/**/ 0x4D556583, 0x3D3364F2,
+/**/ 0x01FFF800, 0xBF0FFF80,
+/**/ 0x00000000, 0x3F0FFFC0,
+/**/ 0x56221F78, 0x3D355515,
+/**/ 0xF118BD7A, 0xBF107FBB,
+/**/ 0xF8000000, 0x3F107FDD,
+/**/ 0x9EEAD9D8, 0x3D376537,
+/**/ 0xC1330AE7, 0xBF10FFB7,
+/**/ 0xE0000000, 0x3F10FFDB,
+/**/ 0x1B7FF7AE, 0x3D399659,
+/**/ 0x714EF047, 0xBF117FB3,
+/**/ 0xB8000000, 0x3F117FD9,
+/**/ 0xBF51E233, 0x3D3BE979,
+/**/ 0x016C7998, 0xBF11FFAF,
+/**/ 0x80000000, 0x3F11FFD7,
+/**/ 0x7D7108FF, 0x3D3E5F99,
+/**/ 0x718BB2DA, 0xBF127FAA,
+/**/ 0x39000000, 0x3F127FD5,
+/**/ 0xB7721DC6, 0xBD3F0647,
+/**/ 0xC1ACA80C, 0xBF12FFA5,
+/**/ 0xE1000000, 0x3F12FFD2,
+/**/ 0xED071532, 0xBD3C4729,
+/**/ 0xF1CF652D, 0xBF137FA0,
+/**/ 0x79000000, 0x3F137FD0,
+/**/ 0x315D596D, 0xBD39620D,
+/**/ 0x01F3F63C, 0xBF13FF9C,
+/**/ 0x01000000, 0x3F13FFCE,
+/**/ 0x92E45F81, 0xBD3655F1,
+/**/ 0xF21A6739, 0xBF147F96,
+/**/ 0x79000000, 0x3F147FCB,
+/**/ 0x206B9526, 0xBD3321D7,
+/**/ 0xC242C421, 0xBF14FF91,
+/**/ 0xE1000000, 0x3F14FFC8,
+/**/ 0xD244C12A, 0xBD2F897B,
+/**/ 0x726D18F6, 0xBF157F8C,
+/**/ 0x39000000, 0x3F157FC6,
+/**/ 0xF93040AE, 0xBD287B4B,
+/**/ 0x029971B4, 0xBF15FF87,
+/**/ 0x81000000, 0x3F15FFC3,
+/**/ 0xD578562C, 0xBD21171E,
+/**/ 0x72C7DA5C, 0xBF167F81,
+/**/ 0xB9000000, 0x3F167FC0,
+/**/ 0x0F773DB4, 0xBD12B5E9,
+/**/ 0xC2F85EEC, 0xBF16FF7B,
+/**/ 0xE1000000, 0x3F16FFBD,
+/**/ 0x158A76C2, 0xBCE44CD3,
+/**/ 0xF32B0B63, 0xBF177F75,
+/**/ 0xF9000000, 0x3F177FBA,
+/**/ 0x2E48511B, 0x3D0CB55C,
+/**/ 0x035FEBC0, 0xBF17FF70,
+/**/ 0x01000000, 0x3F17FFB8,
+/**/ 0x184C534F, 0x3D1FFAF0,
+/**/ 0xF3970C03, 0xBF187F69,
+/**/ 0xF9000000, 0x3F187FB4,
+/**/ 0xACC53FBE, 0x3D292D95,
+/**/ 0xC3D07829, 0xBF18FF63,
+/**/ 0xE1000000, 0x3F18FFB1,
+/**/ 0xE48887C8, 0x3D315FD7,
+/**/ 0x740C3C32, 0xBF197F5D,
+/**/ 0xB9000000, 0x3F197FAE,
+/**/ 0x1DF5B242, 0x3D365AE3,
+/**/ 0x044A641C, 0xBF19FF57,
+/**/ 0x81000000, 0x3F19FFAB,
+/**/ 0x6FBB0E5F, 0x3D3B88EC,
+/**/ 0x748AFBE7, 0xBF1A7F50,
+/**/ 0x3A000000, 0x3F1A7FA8,
+/**/ 0x39766B40, 0xBD3F150C,
+/**/ 0xC4CE0F91, 0xBF1AFF49,
+/**/ 0xE2000000, 0x3F1AFFA4,
+/**/ 0xF14DB839, 0xBD397E06,
+/**/ 0xF513AB19, 0xBF1B7F42,
+/**/ 0x7A000000, 0x3F1B7FA1,
+/**/ 0xCBD9CC3D, 0xBD33B103,
+/**/ 0x055BDA7D, 0xBF1BFF3C,
+/**/ 0x02000000, 0x3F1BFF9E,
+/**/ 0xBB1321B5, 0xBD2B5A05,
+/**/ 0xF5A6A9BD, 0xBF1C7F34,
+/**/ 0x7A000000, 0x3F1C7F9A,
+/**/ 0xECAF9551, 0xBD1DC410,
+/**/ 0xC5F424D6, 0xBF1CFF2D,
+/**/ 0xE2000000, 0x3F1CFF96,
+/**/ 0x3DF3CD68, 0xBCEF80FF,
+/**/ 0x764457C8, 0xBF1D7F26,
+/**/ 0x3A000000, 0x3F1D7F93,
+/**/ 0x4271E737, 0x3D16CBC7,
+/**/ 0x06974E91, 0xBF1DFF1F,
+/**/ 0x82000000, 0x3F1DFF8F,
+/**/ 0x1D134848, 0x3D2939D2,
+/**/ 0x76ED1530, 0xBF1E7F17,
+/**/ 0xBA000000, 0x3F1E7F8B,
+/**/ 0xA9892C73, 0x3D33C2DD,
+/**/ 0xC745B7A4, 0xBF1EFF0F,
+/**/ 0xE2000000, 0x3F1EFF87,
+/**/ 0x8AEC69D5, 0x3D3B25CF,
+/**/ 0xF7A141EA, 0xBF1F7F07,
+/**/ 0xFB000000, 0x3F1F7F83,
+/**/ 0x645B412A, 0xBD3D3941,
+/**/ 0x07FFC002, 0xBF1FFF00,
+/**/ 0x03000000, 0x3F1FFF80,
+/**/ 0x3BBC6662, 0xBD355955,
+/**/ 0xFC309EF5, 0xBF203F7B,
+/**/ 0xFD800000, 0x3F203FBD,
+/**/ 0x260B17B3, 0xBD2A72D8,
+/**/ 0xE462E3D0, 0xBF207F77,
+/**/ 0xF1800000, 0x3F207FBB,
+/**/ 0x0994AE68, 0xBD136218,
+/**/ 0xBC96B492, 0xBF20BF73,
+/**/ 0xDD800000, 0x3F20BFB9,
+/**/ 0xECB2641F, 0x3D0E52E6,
+/**/ 0x84CC1739, 0xBF20FF6F,
+/**/ 0xC1800000, 0x3F20FFB7,
+/**/ 0xE7FCF60B, 0x3D296078,
+/**/ 0x3D0311C6, 0xBF213F6B,
+/**/ 0x9D800000, 0x3F213FB5,
+/**/ 0xA7850AFF, 0x3D35DA18,
+/**/ 0xE53BAA36, 0xBF217F66,
+/**/ 0x71800000, 0x3F217FB3,
+/**/ 0x5E7BB444, 0x3D3F48F1,
+/**/ 0x7D75E68A, 0xBF21BF62,
+/**/ 0x3E000000, 0x3F21BFB1,
+/**/ 0x812BC469, 0xBD370239,
+/**/ 0x05B1CCC0, 0xBF21FF5E,
+/**/ 0x02000000, 0x3F21FFAF,
+/**/ 0x23BF1A4D, 0xBD2A0CD0,
+/**/ 0x7DEF62D8, 0xBF223F59,
+/**/ 0xBE000000, 0x3F223FAC,
+/**/ 0x736E3623, 0xBD0614D3,
+/**/ 0xE62EAED0, 0xBF227F54,
+/**/ 0x72000000, 0x3F227FAA,
+/**/ 0x37EDEDB0, 0x3D1F28BD,
+/**/ 0x3E6FB6A9, 0xBF22BF50,
+/**/ 0x1E000000, 0x3F22BFA8,
+/**/ 0x07CE33C8, 0x3D32A0F5,
+/**/ 0x86B28060, 0xBF22FF4B,
+/**/ 0xC2000000, 0x3F22FFA5,
+/**/ 0xA31C6A8D, 0x3D3DC2B6,
+/**/ 0xBEF711F6, 0xBF233F46,
+/**/ 0x5E800000, 0x3F233FA3,
+/**/ 0xFC67C9FB, 0xBD36CF8B,
+/**/ 0xE73D7169, 0xBF237F41,
+/**/ 0xF2800000, 0x3F237FA0,
+/**/ 0xE6D88A89, 0xBD2629A5,
+/**/ 0xFF85A4B8, 0xBF23BF3C,
+/**/ 0x7E800000, 0x3F23BF9E,
+/**/ 0x202574EC, 0x3CEE7C34,
+/**/ 0x07CFB1E3, 0xBF23FF38,
+/**/ 0x02800000, 0x3F23FF9C,
+/**/ 0x46E594C1, 0x3D2A9723,
+/**/ 0x001B9EE8, 0xBF243F33,
+/**/ 0x7E800000, 0x3F243F99,
+/**/ 0xF61AE74C, 0x3D39F33C,
+/**/ 0xE86971C7, 0xBF247F2D,
+/**/ 0xF3000000, 0x3F247F96,
+/**/ 0x85341E31, 0xBD39141C,
+/**/ 0xC0B9307F, 0xBF24BF28,
+/**/ 0x5F000000, 0x3F24BF94,
+/**/ 0xDA0FAF09, 0xBD2792F5,
+/**/ 0x890AE10E, 0xBF24FF23,
+/**/ 0xC3000000, 0x3F24FF91,
+/**/ 0xFB239430, 0x3CFD4219,
+/**/ 0x415E8974, 0xBF253F1E,
+/**/ 0x1F000000, 0x3F253F8F,
+/**/ 0x0359434A, 0x3D2F8B72,
+/**/ 0xE9B42FAF, 0xBF257F18,
+/**/ 0x73000000, 0x3F257F8C,
+/**/ 0x1939FEDF, 0x3D3E0C4B,
+/**/ 0x820BD9BF, 0xBF25BF13,
+/**/ 0xBF800000, 0x3F25BF89,
+/**/ 0x39B301E2, 0xBD335728,
+/**/ 0x0A658DA3, 0xBF25FF0E,
+/**/ 0x03800000, 0x3F25FF87,
+/**/ 0x5E1E8D4F, 0xBD118E84,
+/**/ 0x82C15159, 0xBF263F08,
+/**/ 0x3F800000, 0x3F263F84,
+/**/ 0xBDDDD045, 0x3D25CFC0,
+/**/ 0xEB1F2AE1, 0xBF267F02,
+/**/ 0x73800000, 0x3F267F81,
+/**/ 0x08837E99, 0x3D3A8C5C,
+/**/ 0x437F203A, 0xBF26BEFD,
+/**/ 0xA0000000, 0x3F26BF7E,
+/**/ 0x3C56F12D, 0xBD35752E,
+/**/ 0x8BE13762, 0xBF26FEF7,
+/**/ 0xC4000000, 0x3F26FF7B,
+/**/ 0x46359E28, 0xBD146EFA,
+/**/ 0xC4457659, 0xBF273EF1,
+/**/ 0xE0000000, 0x3F273F78,
+/**/ 0xCD265865, 0x3D273355,
+/**/ 0xECABE31C, 0xBF277EEB,
+/**/ 0xF4000000, 0x3F277F75,
+/**/ 0x095DEBF8, 0x3D3CAC0E,
+/**/ 0x051483AC, 0xBF27BEE6,
+/**/ 0x00800000, 0x3F27BF73,
+/**/ 0x4C39F4DB, 0xBD31E395,
+/**/ 0x0D7F5E08, 0xBF27FEE0,
+/**/ 0x04800000, 0x3F27FF70,
+/**/ 0xA1314B81, 0xBCB43F3D,
+/**/ 0x05EC782D, 0xBF283EDA,
+/**/ 0x00800000, 0x3F283F6D,
+/**/ 0x115B8D70, 0x3D321B10,
+/**/ 0xEE5BD81B, 0xBF287ED3,
+/**/ 0xF5000000, 0x3F287F69,
+/**/ 0x83704FE1, 0xBD3B54A7,
+/**/ 0xC6CD83D1, 0xBF28BECD,
+/**/ 0xE1000000, 0x3F28BF66,
+/**/ 0x41229C91, 0xBD20C4CC,
+/**/ 0x8F41814D, 0xBF28FEC7,
+/**/ 0xC5000000, 0x3F28FF63,
+/**/ 0x2A183F17, 0x3D25E5A8,
+/**/ 0x47B7D68F, 0xBF293EC1,
+/**/ 0xA1000000, 0x3F293F60,
+/**/ 0xF81B997D, 0x3D3EAC06,
+/**/ 0xF0308995, 0xBF297EBA,
+/**/ 0x75800000, 0x3F297F5D,
+/**/ 0x3A1E5BAD, 0xBD2A6B9B,
+/**/ 0x88ABA05E, 0xBF29BEB4,
+/**/ 0x41800000, 0x3F29BF5A,
+/**/ 0xBDFE3C77, 0x3D1D3958,
+/**/ 0x112920E9, 0xBF29FEAE,
+/**/ 0x05800000, 0x3F29FF57,
+/**/ 0x375BA904, 0x3D3C3972,
+/**/ 0x89A91135, 0xBF2A3EA7,
+/**/ 0xC2000000, 0x3F2A3F53,
+/**/ 0x588DE85B, 0xBD2CE6F3,
+/**/ 0xF22B7740, 0xBF2A7EA0,
+/**/ 0x76000000, 0x3F2A7F50,
+/**/ 0x75AEDBFD, 0x3D1D2249,
+/**/ 0x4AB05909, 0xBF2ABE9A,
+/**/ 0x22000000, 0x3F2ABF4D,
+/**/ 0x2CE7BDAC, 0x3D3D6E96,
+/**/ 0x9337BC90, 0xBF2AFE93,
+/**/ 0xC6800000, 0x3F2AFF49,
+/**/ 0xCB7D724C, 0xBD2800DC,
+/**/ 0xCBC1A7D1, 0xBF2B3E8C,
+/**/ 0x62800000, 0x3F2B3F46,
+/**/ 0xFA591B29, 0x3D25F908,
+/**/ 0xF44E20CE, 0xBF2B7E85,
+/**/ 0xF7000000, 0x3F2B7F42,
+/**/ 0x53021ED8, 0xBD3D9991,
+/**/ 0x0CDD2D83, 0xBF2BBE7F,
+/**/ 0x83000000, 0x3F2BBF3F,
+/**/ 0xFD596AD6, 0xBD1706BF,
+/**/ 0x156ED3F0, 0xBF2BFE78,
+/**/ 0x07000000, 0x3F2BFF3C,
+/**/ 0x4EC45253, 0x3D328528,
+/**/ 0x0E031A14, 0xBF2C3E71,
+/**/ 0x83800000, 0x3F2C3F38,
+/**/ 0x927D8A9E, 0xBD34C408,
+/**/ 0xF69A05ED, 0xBF2C7E69,
+/**/ 0xF7800000, 0x3F2C7F34,
+/**/ 0xCAE2C25F, 0x3D118EF4,
+/**/ 0xCF339D7A, 0xBF2CBE62,
+/**/ 0x63800000, 0x3F2CBF31,
+/**/ 0x73DBBB41, 0x3D3DFD79,
+/**/ 0x97CFE6B9, 0xBF2CFE5B,
+/**/ 0xC8000000, 0x3F2CFF2D,
+/**/ 0xE7FE77E6, 0xBD1FD74F,
+/**/ 0x506EE7AA, 0xBF2D3E54,
+/**/ 0x24000000, 0x3F2D3F2A,
+/**/ 0xBDDB871F, 0x3D328AD4,
+/**/ 0xF910A64A, 0xBF2D7E4C,
+/**/ 0x78800000, 0x3F2D7F26,
+/**/ 0x903DDD81, 0xBD327F8C,
+/**/ 0x91B52899, 0xBF2DBE45,
+/**/ 0xC4800000, 0x3F2DBF22,
+/**/ 0xDF52840A, 0x3D21D80F,
+/**/ 0x1A5C7495, 0xBF2DFE3E,
+/**/ 0x09000000, 0x3F2DFF1F,
+/**/ 0xEED9F651, 0xBD3B316D,
+/**/ 0x9306903D, 0xBF2E3E36,
+/**/ 0x45000000, 0x3F2E3F1B,
+/**/ 0x76DB3C6B, 0x3CF2911A,
+/**/ 0xFBB3818F, 0xBF2E7E2E,
+/**/ 0x79000000, 0x3F2E7F17,
+/**/ 0x85559113, 0x3D3DFC86,
+/**/ 0x54634E89, 0xBF2EBE27,
+/**/ 0xA5800000, 0x3F2EBF13,
+/**/ 0x0AB3DBE7, 0xBD12D83E,
+/**/ 0x9D15FD2B, 0xBF2EFE1F,
+/**/ 0xC9800000, 0x3F2EFF0F,
+/**/ 0x617B99F1, 0x3D39124F,
+/**/ 0xD5CB9373, 0xBF2F3E17,
+/**/ 0xE6000000, 0x3F2F3F0B,
+/**/ 0xF8F64DA1, 0xBD2152B9,
+/**/ 0xFE841760, 0xBF2F7E0F,
+/**/ 0xFA000000, 0x3F2F7F07,
+/**/ 0x34C4735B, 0x3D3617EB,
+/**/ 0x173F8EEF, 0xBF2FBE08,
+/**/ 0x06800000, 0x3F2FBF04,
+/**/ 0x739FA712, 0xBD2551B0,
+/**/ 0x1FFE0020, 0xBF2FFE00,
+/**/ 0x0A800000, 0x3F2FFF00,
+/**/ 0x885DE027, 0x3D351558,
+/**/ 0x0C5FB879, 0xBF301EFC,
+/**/ 0x03800000, 0x3F301F7E,
+/**/ 0x68F8FC50, 0xBD255905,
+/**/ 0x00C1F3B0, 0xBF303EF8,
+/**/ 0xFD800000, 0x3F303F7B,
+/**/ 0xDF771CF4, 0x3D361295,
+/**/ 0xED25B4B7, 0xBF305EF3,
+/**/ 0xF3C00000, 0x3F305F79,
+/**/ 0xD8A255DB, 0xBD2158BB,
+/**/ 0xD18AFE8B, 0xBF307EEF,
+/**/ 0xE5C00000, 0x3F307F77,
+/**/ 0xB740E625, 0x3D3917A1,
+/**/ 0xADF1D42C, 0xBF309EEB,
+/**/ 0xD4000000, 0x3F309F75,
+/**/ 0x9C716D59, 0xBD1281AD,
+/**/ 0x825A3899, 0xBF30BEE7,
+/**/ 0xBE000000, 0x3F30BF73,
+/**/ 0x86ED7DDC, 0x3D3E2C7A,
+/**/ 0x4EC42ED1, 0xBF30DEE3,
+/**/ 0xA4400000, 0x3F30DF71,
+/**/ 0xF54F7E28, 0x3CF7F534,
+/**/ 0x132FB9D5, 0xBF30FEDF,
+/**/ 0x86800000, 0x3F30FF6F,
+/**/ 0x404F4E01, 0xBD3AA6E1,
+/**/ 0xCF9CDCA2, 0xBF311EDA,
+/**/ 0x64800000, 0x3F311F6D,
+/**/ 0x4A6EC981, 0x3D2375B9,
+/**/ 0x840B9A38, 0xBF313ED6,
+/**/ 0x3EC00000, 0x3F313F6B,
+/**/ 0x33401DD0, 0xBD315A73,
+/**/ 0x307BF596, 0xBF315ED2,
+/**/ 0x14C00000, 0x3F315F69,
+/**/ 0x02C11605, 0x3D341A2F,
+/**/ 0xD4EDF1BC, 0xBF317ECD,
+/**/ 0xE7000000, 0x3F317F66,
+/**/ 0xB2B7E8C5, 0xBD1798F3,
+/**/ 0x716191A8, 0xBF319EC9,
+/**/ 0xB5400000, 0x3F319F64,
+/**/ 0x35D62ED5, 0xBD3F5AB7,
+/**/ 0x05D6D85A, 0xBF31BEC5,
+/**/ 0x7F400000, 0x3F31BF62,
+/**/ 0xCA7EC7CD, 0x3D1EF6FF,
+/**/ 0x924DC8D2, 0xBF31DEC0,
+/**/ 0x45800000, 0x3F31DF60,
+/**/ 0xA8550396, 0xBD309BD7,
+/**/ 0x16C6660D, 0xBF31FEBC,
+/**/ 0x07800000, 0x3F31FF5E,
+/**/ 0xC3E31F70, 0x3D379981,
+/**/ 0x9340B30B, 0xBF321EB7,
+/**/ 0xC5C00000, 0x3F321F5B,
+/**/ 0x5FE92B94, 0x3CD7B300,
+/**/ 0x07BCB2CC, 0xBF323EB3,
+/**/ 0x80000000, 0x3F323F59,
+/**/ 0x25A7CF34, 0xBD364AF9,
+/**/ 0x743A684F, 0xBF325EAE,
+/**/ 0x36000000, 0x3F325F57,
+/**/ 0x17E48399, 0x3D339D32,
+/**/ 0xD8B9D692, 0xBF327EA9,
+/**/ 0xE8400000, 0x3F327F54,
+/**/ 0xCC387BD1, 0xBCFE7B27,
+/**/ 0x353B0095, 0xBF329EA5,
+/**/ 0x96800000, 0x3F329F52,
+/**/ 0x1AE7FA80, 0xBD36D8A7,
+/**/ 0x89BDE957, 0xBF32BEA0,
+/**/ 0x40800000, 0x3F32BF50,
+/**/ 0x05CF3DC3, 0x3D34CB54,
+/**/ 0xD64293D7, 0xBF32DE9B,
+/**/ 0xE6C00000, 0x3F32DF4D,
+/**/ 0xD5A4F691, 0x3CF053EA,
+/**/ 0x1AC90315, 0xBF32FE97,
+/**/ 0x89000000, 0x3F32FF4B,
+/**/ 0x5CAE7B16, 0xBD3229E7,
+/**/ 0x57513A0F, 0xBF331E92,
+/**/ 0x27000000, 0x3F331F49,
+/**/ 0xAEED4509, 0x3D3B3EE1,
+/**/ 0x8BDB3BC4, 0xBF333E8D,
+/**/ 0xC1400000, 0x3F333F46,
+/**/ 0x2E0C2605, 0x3D228133,
+/**/ 0xB8670B34, 0xBF335E88,
+/**/ 0x57800000, 0x3F335F44,
+/**/ 0xBBD6E280, 0xBD20477F,
+/**/ 0xDCF4AB5D, 0xBF337E83,
+/**/ 0xE9C00000, 0x3F337F41,
+/**/ 0xE9CE8AFC, 0xBD38ED2A,
+/**/ 0xF9841F3F, 0xBF339E7E,
+/**/ 0x77C00000, 0x3F339F3F,
+/**/ 0x39159F9B, 0x3D36E558,
+/**/ 0x0E1569D9, 0xBF33BE7A,
+/**/ 0x02000000, 0x3F33BF3D,
+/**/ 0x40681634, 0x3D1D5325,
+/**/ 0x1AA88E2A, 0xBF33DE75,
+/**/ 0x88400000, 0x3F33DF3A,
+/**/ 0x7F2112CE, 0xBD1E775F,
+/**/ 0x1F3D8F31, 0xBF33FE70,
+/**/ 0x0A800000, 0x3F33FF38,
+/**/ 0x91F80D1B, 0xBD35F18B,
+/**/ 0x1BD46FED, 0xBF341E6B,
+/**/ 0x88800000, 0x3F341F35,
+/**/ 0xFDC3FC2F, 0x3D3C5AAD,
+/**/ 0x106D335D, 0xBF343E66,
+/**/ 0x02C00000, 0x3F343F33,
+/**/ 0x268A89F1, 0x3D2E8FA9,
+/**/ 0xFD07DC80, 0xBF345E60,
+/**/ 0x79000000, 0x3F345F30,
+/**/ 0x902AC9EE, 0x3D06B73F,
+/**/ 0xE1A46E55, 0xBF347E5B,
+/**/ 0xEB400000, 0x3F347F2D,
+/**/ 0x45C43959, 0xBD21EE30,
+/**/ 0xBE42EBDC, 0xBF349E56,
+/**/ 0x59800000, 0x3F349F2B,
+/**/ 0xE8B753E8, 0xBD34212B,
+/**/ 0x92E35813, 0xBF34BE51,
+/**/ 0xC3C00000, 0x3F34BF28,
+/**/ 0x9D2064DB, 0xBD3EA653,
+/**/ 0x5F85B5F9, 0xBF34DE4C,
+/**/ 0x29C00000, 0x3F34DF26,
+/**/ 0x81DCB6FB, 0x3D377A70,
+/**/ 0x242A088D, 0xBF34FE47,
+/**/ 0x8C000000, 0x3F34FF23,
+/**/ 0x6BB44A6D, 0x3D2C8440,
+/**/ 0xE0D052CF, 0xBF351E41,
+/**/ 0xEA400000, 0x3F351F20,
+/**/ 0x0048AAF8, 0x3D16C6ED,
+/**/ 0x957897BD, 0xBF353E3C,
+/**/ 0x44800000, 0x3F353F1E,
+/**/ 0xF506A07E, 0xBD01ADF4,
+/**/ 0x4222DA57, 0xBF355E37,
+/**/ 0x9AC00000, 0x3F355F1B,
+/**/ 0x4B88A655, 0xBD22E69B,
+/**/ 0xE6CF1D9B, 0xBF357E31,
+/**/ 0xED000000, 0x3F357F18,
+/**/ 0x153DAEB0, 0xBD3005F2,
+/**/ 0x837D6488, 0xBF359E2C,
+/**/ 0x3B400000, 0x3F359F16,
+/**/ 0x2D5222B4, 0xBD35ECAC,
+/**/ 0x182DB21E, 0xBF35BE27,
+/**/ 0x85800000, 0x3F35BF13,
+/**/ 0x2EA6CB14, 0xBD3B267C,
+/**/ 0xA4E0095B, 0xBF35DE21,
+/**/ 0xCBC00000, 0x3F35DF10,
+/**/ 0x5A40A340, 0xBD3FB262,
+/**/ 0x29946D3F, 0xBF35FE1C,
+/**/ 0x0DC00000, 0x3F35FF0E,
+/**/ 0x0E7B79ED, 0x3D3C70A1,
+/**/ 0xA64AE0C7, 0xBF361E16,
+/**/ 0x4C000000, 0x3F361F0B,
+/**/ 0xC9C8D263, 0x3D39438D,
+/**/ 0x1B0366F4, 0xBF363E11,
+/**/ 0x86400000, 0x3F363F08,
+/**/ 0x9582CD0C, 0x3D36C763,
+/**/ 0x87BE02C5, 0xBF365E0B,
+/**/ 0xBC800000, 0x3F365F05,
+/**/ 0x2F24F1F9, 0x3D34FD22,
+/**/ 0xEC7AB737, 0xBF367E05,
+/**/ 0xEEC00000, 0x3F367F02,
+/**/ 0x53CAEA94, 0x3D33E5C9,
+/**/ 0x4939874A, 0xBF369E00,
+/**/ 0x1D000000, 0x3F369F00,
+/**/ 0xC03081D0, 0x3D338258,
+/**/ 0x9DFA75FE, 0xBF36BDFA,
+/**/ 0x47400000, 0x3F36BEFD,
+/**/ 0x30B1A458, 0x3D33D3D0,
+/**/ 0xEABD8651, 0xBF36DDF4,
+/**/ 0x6D800000, 0x3F36DEFA,
+/**/ 0x614A60C1, 0x3D34DB2F,
+/**/ 0x2F82BB41, 0xBF36FDEF,
+/**/ 0x8FC00000, 0x3F36FEF7,
+/**/ 0x0D96E7B8, 0x3D369976,
+/**/ 0x6C4A17CF, 0xBF371DE9,
+/**/ 0xAE000000, 0x3F371EF4,
+/**/ 0xF0D38C30, 0x3D390FA3,
+/**/ 0xA1139EF8, 0xBF373DE3,
+/**/ 0xC8400000, 0x3F373EF1,
+/**/ 0xC5DCC397, 0x3D3C3EB8,
+/**/ 0xCDDF53BC, 0xBF375DDD,
+/**/ 0xDEC00000, 0x3F375EEE,
+/**/ 0xB8D0D9FD, 0xBD3FD84B,
+/**/ 0xF2AD3919, 0xBF377DD7,
+/**/ 0xF1000000, 0x3F377EEB,
+/**/ 0xD11891A0, 0xBD3B3469,
+/**/ 0x0F7D520F, 0xBF379DD2,
+/**/ 0xFF400000, 0x3F379EE8,
+/**/ 0xC93D855B, 0xBD35D4A1,
+/**/ 0x244FA19D, 0xBF37BDCC,
+/**/ 0x09800000, 0x3F37BEE6,
+/**/ 0xCFC56806, 0xBD2F6FE7,
+/**/ 0x31242AC1, 0xBF37DDC6,
+/**/ 0x0FC00000, 0x3F37DEE3,
+/**/ 0xE815F202, 0xBD21BAC0,
+/**/ 0x35FAF079, 0xBF37FDC0,
+/**/ 0x12000000, 0x3F37FEE0,
+/**/ 0x5190C28B, 0xBCF43E7B,
+/**/ 0x32D3F5C6, 0xBF381DBA,
+/**/ 0x10400000, 0x3F381EDD,
+/**/ 0x34C1F9E9, 0x3D1C55D8,
+/**/ 0x27AF3DA6, 0xBF383DB4,
+/**/ 0x0A800000, 0x3F383EDA,
+/**/ 0x8AAF36D4, 0x3D302FB8,
+/**/ 0x148CCB18, 0xBF385DAE,
+/**/ 0x00C00000, 0x3F385ED7,
+/**/ 0x7AE0D0F8, 0x3D3A0BDF,
+/**/ 0xF96CA11B, 0xBF387DA7,
+/**/ 0xF3400000, 0x3F387ED3,
+/**/ 0x6B1CDAAF, 0xBD3B5515,
+/**/ 0xD64EC2AD, 0xBF389DA1,
+/**/ 0xE1800000, 0x3F389ED0,
+/**/ 0xE1179E5E, 0xBD2FE44C,
+/**/ 0xAB3332CD, 0xBF38BD9B,
+/**/ 0xCBC00000, 0x3F38BECD,
+/**/ 0xF86F56EC, 0xBD0E529E,
+/**/ 0x7819F47A, 0xBF38DD95,
+/**/ 0xB2000000, 0x3F38DECA,
+/**/ 0xFEB631AB, 0x3D2246C3,
+/**/ 0x3D030AB4, 0xBF38FD8F,
+/**/ 0x94400000, 0x3F38FEC7,
+/**/ 0xE04DA791, 0x3D36D7FA,
+/**/ 0xF9EE7878, 0xBF391D88,
+/**/ 0x72C00000, 0x3F391EC4,
+/**/ 0x86F7ADBB, 0xBD3AAB89,
+/**/ 0xAEDC40C7, 0xBF393D82,
+/**/ 0x4D000000, 0x3F393EC1,
+/**/ 0x032C6155, 0xBD26CC57,
+/**/ 0x5BCC669D, 0xBF395D7C,
+/**/ 0x23400000, 0x3F395EBE,
+/**/ 0x93C3EB3D, 0x3D12A452,
+/**/ 0x00BEECFB, 0xBF397D76,
+/**/ 0xF5800000, 0x3F397EBA,
+/**/ 0xA0BCD695, 0x3D358336,
+/**/ 0x9DB3D6E0, 0xBF399D6F,
+/**/ 0xC4000000, 0x3F399EB7,
+/**/ 0xDA737570, 0xBD38D6C5,
+/**/ 0x32AB2749, 0xBF39BD69,
+/**/ 0x8E400000, 0x3F39BEB4,
+/**/ 0x65026C7D, 0xBD198F84,
+/**/ 0xBFA4E136, 0xBF39DD62,
+/**/ 0x54800000, 0x3F39DEB1,
+/**/ 0x2EA9B41A, 0x3D29B9C9,
+/**/ 0x44A107A5, 0xBF39FD5C,
+/**/ 0x17000000, 0x3F39FEAE,
+/**/ 0x16137ACF, 0xBD3F1375,
+/**/ 0xC19F9D96, 0xBF3A1D55,
+/**/ 0xD5400000, 0x3F3A1EAA,
+/**/ 0xDE73AFA0, 0xBD2467DC,
+/**/ 0x36A0A607, 0xBF3A3D4F,
+/**/ 0x8F800000, 0x3F3A3EA7,
+/**/ 0x7B8357C6, 0x3D26F8F0,
+/**/ 0xA3A423F7, 0xBF3A5D48,
+/**/ 0x46000000, 0x3F3A5EA4,
+/**/ 0x5DA0DFB7, 0xBD3E0141,
+/**/ 0x08AA1A64, 0xBF3A7D42,
+/**/ 0xF8400000, 0x3F3A7EA0,
+/**/ 0x41050D29, 0xBD1AB06E,
+/**/ 0x65B28C4E, 0xBF3A9D3B,
+/**/ 0xA6800000, 0x3F3A9E9D,
+/**/ 0x56A0E005, 0x3D317CE9,
+/**/ 0xBABD7CB3, 0xBF3ABD34,
+/**/ 0x51000000, 0x3F3ABE9A,
+/**/ 0xF899EF39, 0xBD358532,
+/**/ 0x07CAEE92, 0xBF3ADD2E,
+/**/ 0xF7400000, 0x3F3ADE96,
+/**/ 0xC83BF5C2, 0x3D113A3C,
+/**/ 0x4CDAE4EA, 0xBF3AFD27,
+/**/ 0x99800000, 0x3F3AFE93,
+/**/ 0x863C7C8E, 0x3D3EF92F,
+/**/ 0x89ED62B9, 0xBF3B1D20,
+/**/ 0x38000000, 0x3F3B1E90,
+/**/ 0x3341CC3C, 0xBD161149,
+/**/ 0xBF026AFE, 0xBF3B3D19,
+/**/ 0xD2400000, 0x3F3B3E8C,
+/**/ 0x67C955DF, 0x3D36D709,
+/**/ 0xEC1A00B8, 0xBF3B5D12,
+/**/ 0x68C00000, 0x3F3B5E89,
+/**/ 0x5AE9B17A, 0xBD27E77B,
+/**/ 0x113426E6, 0xBF3B7D0C,
+/**/ 0xFB000000, 0x3F3B7E85,
+/**/ 0x219679DE, 0x3D321C58,
+/**/ 0x2E50E086, 0xBF3B9D05,
+/**/ 0x89800000, 0x3F3B9E82,
+/**/ 0xFAA62113, 0xBD2DEF6A,
+/**/ 0x43703097, 0xBF3BBCFE,
+/**/ 0x13C00000, 0x3F3BBE7F,
+/**/ 0x23305306, 0x3D30D119,
+/**/ 0x50921A17, 0xBF3BDCF7,
+/**/ 0x9A400000, 0x3F3BDE7B,
+/**/ 0x9FBACE27, 0xBD2D1078,
+/**/ 0x55B6A006, 0xBF3BFCF0,
+/**/ 0x1C800000, 0x3F3BFE78,
+/**/ 0xD625DF1E, 0x3D32FD49,
+/**/ 0x52DDC563, 0xBF3C1CE9,
+/**/ 0x9B000000, 0x3F3C1E74,
+/**/ 0x7D07255B, 0xBD253AA9,
+/**/ 0x48078D2B, 0xBF3C3CE2,
+/**/ 0x15400000, 0x3F3C3E71,
+/**/ 0x9E08B538, 0x3D38A8E7,
+/**/ 0x3533FA5D, 0xBF3C5CDB,
+/**/ 0x8BC00000, 0x3F3C5E6D,
+/**/ 0x45956AFC, 0xBD09780B,
+/**/ 0x1A630FF9, 0xBF3C7CD4,
+/**/ 0xFE400000, 0x3F3C7E69,
+/**/ 0x2792F44E, 0xBD3E2410,
+/**/ 0xF794D0FC, 0xBF3C9CCC,
+/**/ 0x6C800000, 0x3F3C9E66,
+/**/ 0x30AB4456, 0x3D1F2AEC,
+/**/ 0xCCC94066, 0xBF3CBCC5,
+/**/ 0xD7000000, 0x3F3CBE62,
+/**/ 0x231641D5, 0xBD3161A0,
+/**/ 0x9A006135, 0xBF3CDCBE,
+/**/ 0x3D400000, 0x3F3CDE5F,
+/**/ 0xF4AD1934, 0x3D3657DD,
+/**/ 0x5F3A3668, 0xBF3CFCB7,
+/**/ 0x9FC00000, 0x3F3CFE5B,
+/**/ 0x2E7AC798, 0xBCF07CB0,
+/**/ 0x1C76C2FD, 0xBF3D1CB0,
+/**/ 0xFE400000, 0x3F3D1E57,
+/**/ 0x6090F643, 0xBD377F9B,
+/**/ 0xD1B609F3, 0xBF3D3CA8,
+/**/ 0x58800000, 0x3F3D3E54,
+/**/ 0x849503E6, 0x3D32F16C,
+/**/ 0x7EF80E49, 0xBF3D5CA1,
+/**/ 0xAF000000, 0x3F3D5E50,
+/**/ 0xAF1CA4EA, 0xBCFB3B3A,
+/**/ 0x243CD2FE, 0xBF3D7C9A,
+/**/ 0x01800000, 0x3F3D7E4D,
+/**/ 0x4701415B, 0xBD356DFC,
+/**/ 0xC1845B0F, 0xBF3D9C92,
+/**/ 0x4FC00000, 0x3F3D9E49,
+/**/ 0x582AEA48, 0x3D37C392,
+/**/ 0x56CEA97C, 0xBF3DBC8B,
+/**/ 0x9A400000, 0x3F3DBE45,
+/**/ 0x67DCC15E, 0x3D1787DF,
+/**/ 0xE41BC143, 0xBF3DDC83,
+/**/ 0xE0C00000, 0x3F3DDE41,
+/**/ 0x352F961F, 0xBD262398,
+/**/ 0x696BA563, 0xBF3DFC7C,
+/**/ 0x23400000, 0x3F3DFE3E,
+/**/ 0xDEDD373A, 0xBD3B16B9,
+/**/ 0xE6BE58DA, 0xBF3E1C74,
+/**/ 0x61800000, 0x3F3E1E3A,
+/**/ 0x336BE94B, 0x3D35D42E,
+/**/ 0x5C13DEA7, 0xBF3E3C6D,
+/**/ 0x9C000000, 0x3F3E3E36,
+/**/ 0x08A303A2, 0x3D1EBFAF,
+/**/ 0xC96C39C9, 0xBF3E5C65,
+/**/ 0xD2800000, 0x3F3E5E32,
+/**/ 0x34856362, 0xBD160A06,
+/**/ 0x2EC76D3D, 0xBF3E7C5E,
+/**/ 0x05000000, 0x3F3E7E2F,
+/**/ 0x154CDF1A, 0xBD31C21A,
+/**/ 0x8C257C04, 0xBF3E9C56,
+/**/ 0x33800000, 0x3F3E9E2B,
+/**/ 0x31941F7F, 0xBD3D0DDE,
+/**/ 0xE186691B, 0xBF3EBC4E,
+/**/ 0x5DC00000, 0x3F3EBE27,
+/**/ 0xC26EC60D, 0x3D389B31,
+/**/ 0x2EEA3781, 0xBF3EDC47,
+/**/ 0x84400000, 0x3F3EDE23,
+/**/ 0xD583BEF8, 0x3D2E742A,
+/**/ 0x7450EA34, 0xBF3EFC3F,
+/**/ 0xA6C00000, 0x3F3EFE1F,
+/**/ 0xAC2DA351, 0x3D1B3F31,
+/**/ 0xB1BA8433, 0xBF3F1C37,
+/**/ 0xC5400000, 0x3F3F1E1B,
+/**/ 0x2DC67430, 0xBCE45533,
+/**/ 0xE727087C, 0xBF3F3C2F,
+/**/ 0xDFC00000, 0x3F3F3E17,
+/**/ 0xFF1174AE, 0xBD1C7133,
+/**/ 0x14967A0F, 0xBF3F5C28,
+/**/ 0xF6400000, 0x3F3F5E13,
+/**/ 0x4AE098DC, 0xBD29383C,
+/**/ 0x3A08DBE9, 0xBF3F7C20,
+/**/ 0x08C00000, 0x3F3F7E10,
+/**/ 0x684B0B3B, 0xBD31211D,
+/**/ 0x577E3109, 0xBF3F9C18,
+/**/ 0x17400000, 0x3F3F9E0C,
+/**/ 0x268D7464, 0xBD34AA4B,
+/**/ 0x6CF67C6E, 0xBF3FBC10,
+/**/ 0x21C00000, 0x3F3FBE08,
+/**/ 0xBED03388, 0xBD3736A7,
+/**/ 0x7A71C116, 0xBF3FDC08,
+/**/ 0x28400000, 0x3F3FDE04,
+/**/ 0x900BC4E5, 0xBD38C533,
+/**/ 0x7FF00200, 0xBF3FFC00,
+/**/ 0x2AC00000, 0x3F3FFE00,
+/**/ 0xF9987527, 0xBD3954EE,
+/**/ 0x3EB8A115, 0xBF400DFC,
+/**/ 0x14A00000, 0x3F400EFE,
+/**/ 0x5B2E613B, 0xBD38E4DA,
+/**/ 0x397AC249, 0xBF401DF8,
+/**/ 0x11E00000, 0x3F401EFC,
+/**/ 0x14E5761B, 0xBD3773F6,
+/**/ 0x303E661C, 0xBF402DF4,
+/**/ 0x0D200000, 0x3F402EFA,
+/**/ 0x873570A0, 0xBD350142,
+/**/ 0x23038E0C, 0xBF403DF0,
+/**/ 0x06600000, 0x3F403EF8,
+/**/ 0x12F5DD53, 0xBD318BC0,
+/**/ 0x11CA3B9A, 0xBF404DEC,
+/**/ 0xFDA00000, 0x3F404EF5,
+/**/ 0x32BC307C, 0xBD2A24DE,
+/**/ 0xFC927044, 0xBF405DE7,
+/**/ 0xF2E00000, 0x3F405EF3,
+/**/ 0xF01532DA, 0xBD1E513F,
+/**/ 0xE35C2D8A, 0xBF406DE3,
+/**/ 0xE6200000, 0x3F406EF1,
+/**/ 0xCE27534E, 0xBCF10631,
+/**/ 0xC62774EA, 0xBF407DDF,
+/**/ 0xD7600000, 0x3F407EEF,
+/**/ 0x86CE9380, 0x3D19E95C,
+/**/ 0xA4F447E4, 0xBF408DDB,
+/**/ 0xC6A00000, 0x3F408EED,
+/**/ 0xBA0CD2C3, 0x3D2E19BC,
+/**/ 0x7FC2A7F8, 0xBF409DD7,
+/**/ 0xB3E00000, 0x3F409EEB,
+/**/ 0x31FF7199, 0x3D38A832,
+/**/ 0x569296A4, 0xBF40ADD3,
+/**/ 0x9F400000, 0x3F40AEE9,
+/**/ 0xC2D77791, 0xBD3CB2AD,
+/**/ 0x29641567, 0xBF40BDCF,
+/**/ 0x88800000, 0x3F40BEE7,
+/**/ 0xE5545563, 0xBD3102C1,
+/**/ 0xF83725C2, 0xBF40CDCA,
+/**/ 0x6FC00000, 0x3F40CEE5,
+/**/ 0x66B3E48D, 0xBD111C2A,
+/**/ 0xC30BC932, 0xBF40DDC6,
+/**/ 0x55000000, 0x3F40DEE3,
+/**/ 0x7711FC2A, 0x3D2302EF,
+/**/ 0x89E20138, 0xBF40EDC2,
+/**/ 0x38400000, 0x3F40EEE1,
+/**/ 0xB558238E, 0x3D3857C4,
+/**/ 0x4CB9CF52, 0xBF40FDBE,
+/**/ 0x19A00000, 0x3F40FEDF,
+/**/ 0x1194C2E1, 0xBD37C324,
+/**/ 0x0B933501, 0xBF410DBA,
+/**/ 0xF8E00000, 0x3F410EDC,
+/**/ 0xFBCAF285, 0xBD1B390B,
+/**/ 0xC66E33C2, 0xBF411DB5,
+/**/ 0xD6200000, 0x3F411EDA,
+/**/ 0x0E52C3A4, 0x3D266ECF,
+/**/ 0x7D4ACD15, 0xBF412DB1,
+/**/ 0xB1600000, 0x3F412ED8,
+/**/ 0x1A4AF71D, 0x3D3E4EDB,
+/**/ 0x30290279, 0xBF413DAD,
+/**/ 0x8AC00000, 0x3F413ED6,
+/**/ 0x58C4D599, 0xBD2B0DD1,
+/**/ 0xDF08D56E, 0xBF414DA8,
+/**/ 0x62000000, 0x3F414ED4,
+/**/ 0x2FB4061D, 0x3D1EDC6F,
+/**/ 0x89EA4773, 0xBF415DA4,
+/**/ 0x37400000, 0x3F415ED2,
+/**/ 0x1BA53538, 0x3D3E09E8,
+/**/ 0x30CD5A06, 0xBF416DA0,
+/**/ 0x0AA00000, 0x3F416ED0,
+/**/ 0x4A5B4574, 0xBD251B08,
+/**/ 0xD3B20EA8, 0xBF417D9B,
+/**/ 0xDBE00000, 0x3F417ECD,
+/**/ 0x4241B57B, 0x3D2BE3AD,
+/**/ 0x729866D7, 0xBF418D97,
+/**/ 0xAB400000, 0x3F418ECB,
+/**/ 0xFA22BD16, 0xBD387707,
+/**/ 0x0D806412, 0xBF419D93,
+/**/ 0x78800000, 0x3F419EC9,
+/**/ 0xFFA2FC2F, 0x3D01C6FC,
+/**/ 0xA46A07D9, 0xBF41AD8E,
+/**/ 0x43C00000, 0x3F41AEC7,
+/**/ 0x05F32EE8, 0x3D3E028D,
+/**/ 0x375553AB, 0xBF41BD8A,
+/**/ 0x0D200000, 0x3F41BEC5,
+/**/ 0xC7E46F2B, 0xBD146400,
+/**/ 0xC6424907, 0xBF41CD85,
+/**/ 0xD4600000, 0x3F41CEC2,
+/**/ 0x8DFCE791, 0x3D38E737,
+/**/ 0x5130E96B, 0xBF41DD81,
+/**/ 0x99C00000, 0x3F41DEC0,
+/**/ 0x92F4A6CE, 0xBD1FEF30,
+/**/ 0xD8213659, 0xBF41ED7C,
+/**/ 0x5D000000, 0x3F41EEBE,
+/**/ 0x4AE68315, 0x3D383EF4,
+/**/ 0x5B13314D, 0xBF41FD78,
+/**/ 0x1E600000, 0x3F41FEBC,
+/**/ 0x39A8276A, 0xBD199E1E,
+/**/ 0xDA06DBC8, 0xBF420D73,
+/**/ 0xDDA00000, 0x3F420EB9,
+/**/ 0xE39F6D77, 0x3D3C11BF,
+/**/ 0x54FC3749, 0xBF421D6F,
+/**/ 0x9B000000, 0x3F421EB7,
+/**/ 0xC3A8C440, 0xBCD50D72,
+/**/ 0xCBF3454F, 0xBF422D6A,
+/**/ 0x56600000, 0x3F422EB5,
+/**/ 0x06E59170, 0xBD3B9869,
+/**/ 0x3EEC0759, 0xBF423D66,
+/**/ 0x0FA00000, 0x3F423EB3,
+/**/ 0x86930551, 0x3D248C4B,
+/**/ 0xADE67EE6, 0xBF424D61,
+/**/ 0xC7000000, 0x3F424EB0,
+/**/ 0xB3649FF7, 0xBD2D6F13,
+/**/ 0x18E2AD76, 0xBF425D5D,
+/**/ 0x7C400000, 0x3F425EAE,
+/**/ 0xB496441D, 0x3D396F87,
+/**/ 0x7FE09487, 0xBF426D58,
+/**/ 0x2FA00000, 0x3F426EAC,
+/**/ 0x01961A2F, 0x3D05E2D0,
+/**/ 0xE2E03598, 0xBF427D53,
+/**/ 0xE1000000, 0x3F427EA9,
+/**/ 0x652D1720, 0xBD32D013,
+/**/ 0x41E1922A, 0xBF428D4F,
+/**/ 0x90400000, 0x3F428EA7,
+/**/ 0x15C6A78A, 0x3D38CB3F,
+/**/ 0x9CE4ABBA, 0xBF429D4A,
+/**/ 0x3DA00000, 0x3F429EA5,
+/**/ 0x07F8A52A, 0x3D163D44,
+/**/ 0xF3E983C8, 0xBF42AD45,
+/**/ 0xE9000000, 0x3F42AEA2,
+/**/ 0x1FEC6070, 0xBD2905BC,
+/**/ 0x46F01BD4, 0xBF42BD41,
+/**/ 0x92600000, 0x3F42BEA0,
+/**/ 0x8FE5CB8E, 0xBD3D6A4E,
+/**/ 0x95F8755C, 0xBF42CD3C,
+/**/ 0x39A00000, 0x3F42CE9E,
+/**/ 0x120028B6, 0x3D32D9FF,
+/**/ 0xE10291DF, 0xBF42DD37,
+/**/ 0xDF000000, 0x3F42DE9B,
+/**/ 0x94B2D8A6, 0x3D112C29,
+/**/ 0x280E72DD, 0xBF42ED33,
+/**/ 0x82600000, 0x3F42EE99,
+/**/ 0x0E9DC27F, 0xBD222C5A,
+/**/ 0x6B1C19D4, 0xBF42FD2E,
+/**/ 0x23C00000, 0x3F42FE97,
+/**/ 0xA4C12307, 0xBD3548A7,
+/**/ 0xAA2B8844, 0xBF430D29,
+/**/ 0xC3000000, 0x3F430E94,
+/**/ 0x1B27A40C, 0x3D3FB49A,
+/**/ 0xE53CBFAC, 0xBF431D24,
+/**/ 0x60600000, 0x3F431E92,
+/**/ 0xC65D601D, 0x3D35E297,
+/**/ 0x1C4FC18B, 0xBF432D20,
+/**/ 0xFBC00000, 0x3F432E8F,
+/**/ 0xD4E46CD5, 0x3D2A84A1,
+/**/ 0x4F648F60, 0xBF433D1B,
+/**/ 0x95200000, 0x3F433E8D,
+/**/ 0x526215F8, 0x3D175314,
+/**/ 0x7E7B2AAB, 0xBF434D16,
+/**/ 0x2C800000, 0x3F434E8B,
+/**/ 0x9746A94C, 0xBCD9430B,
+/**/ 0xA99394E9, 0xBF435D11,
+/**/ 0xC1E00000, 0x3F435E88,
+/**/ 0x47EF6144, 0xBD15A88D,
+/**/ 0xD0ADCF9B, 0xBF436D0C,
+/**/ 0x55400000, 0x3F436E86,
+/**/ 0x94614FFB, 0xBD227301,
+/**/ 0xF3C9DC3F, 0xBF437D07,
+/**/ 0xE6A00000, 0x3F437E83,
+/**/ 0x16908831, 0xBD27A44A,
+/**/ 0x12E7BC55, 0xBF438D03,
+/**/ 0x76000000, 0x3F438E81,
+/**/ 0x13DE59AC, 0xBD2A6621,
+/**/ 0x2E07715C, 0xBF439CFE,
+/**/ 0x03600000, 0x3F439E7F,
+/**/ 0x76635000, 0xBD2AB687,
+/**/ 0x4528FCD2, 0xBF43ACF9,
+/**/ 0x8EC00000, 0x3F43AE7C,
+/**/ 0x28F7818F, 0xBD28937E,
+/**/ 0x584C6037, 0xBF43BCF4,
+/**/ 0x18200000, 0x3F43BE7A,
+/**/ 0x17328F27, 0xBD23FB06,
+/**/ 0x67719D0A, 0xBF43CCEF,
+/**/ 0x9F800000, 0x3F43CE77,
+/**/ 0x5AD74747, 0xBD19D640,
+/**/ 0x7298B4CA, 0xBF43DCEA,
+/**/ 0x24E00000, 0x3F43DE75,
+/**/ 0xC5CB9C74, 0xBCFB0E6A,
+/**/ 0x79C1A8F6, 0xBF43ECE5,
+/**/ 0xA8400000, 0x3F43EE72,
+/**/ 0xF21B8682, 0x3D1145E2,
+/**/ 0x7CEC7B0D, 0xBF43FCE0,
+/**/ 0x29A00000, 0x3F43FE70,
+/**/ 0x59543A06, 0x3D27251B,
+/**/ 0x7C192C8E, 0xBF440CDB,
+/**/ 0xA9000000, 0x3F440E6D,
+/**/ 0xAC6250B6, 0x3D341357,
+/**/ 0x7747BEF8, 0xBF441CD6,
+/**/ 0x26600000, 0x3F441E6B,
+/**/ 0x43A510F7, 0x3D3DD4D6,
+/**/ 0x6E7833CB, 0xBF442CD1,
+/**/ 0xA1E00000, 0x3F442E68,
+/**/ 0x05F7D1E1, 0xBD3727F7,
+/**/ 0x61AA8C85, 0xBF443CCC,
+/**/ 0x1B400000, 0x3F443E66,
+/**/ 0x527C9668, 0xBD25C421,
+/**/ 0x50DECAA5, 0xBF444CC7,
+/**/ 0x92A00000, 0x3F444E63,
+/**/ 0x053F70AC, 0x3D053C47,
+/**/ 0x3C14EFAB, 0xBF445CC2,
+/**/ 0x08000000, 0x3F445E61,
+/**/ 0x1E315FBB, 0x3D3175D5,
+/**/ 0x234CFD15, 0xBF446CBD,
+/**/ 0x7B800000, 0x3F446E5E,
+/**/ 0x6A8B33AC, 0xBD3E762C,
+/**/ 0x0686F463, 0xBF447CB8,
+/**/ 0xECE00000, 0x3F447E5B,
+/**/ 0x67AD9900, 0xBD2A36F8,
+/**/ 0xE5C2D713, 0xBF448CB2,
+/**/ 0x5C400000, 0x3F448E59,
+/**/ 0x1E974853, 0x3D161B95,
+/**/ 0xC100A6A5, 0xBF449CAD,
+/**/ 0xC9A00000, 0x3F449E56,
+/**/ 0x8CE22250, 0x3D3971F7,
+/**/ 0x98406498, 0xBF44ACA8,
+/**/ 0x35200000, 0x3F44AE54,
+/**/ 0xDF8A23F8, 0xBD315945,
+/**/ 0x6B82126A, 0xBF44BCA3,
+/**/ 0x9E800000, 0x3F44BE51,
+/**/ 0x1A63D360, 0x3D1498B2,
+/**/ 0x3AC5B19B, 0xBF44CC9E,
+/**/ 0x05E00000, 0x3F44CE4F,
+/**/ 0x4323A054, 0x3D3CF14E,
+/**/ 0x060B43AA, 0xBF44DC99,
+/**/ 0x6B600000, 0x3F44DE4C,
+/**/ 0x4CE35F94, 0xBD23EDC2,
+/**/ 0xCD52CA15, 0xBF44EC93,
+/**/ 0xCEC00000, 0x3F44EE49,
+/**/ 0xCCF1B48E, 0x3D306E9D,
+/**/ 0x909C465C, 0xBF44FC8E,
+/**/ 0x30400000, 0x3F44FE47,
+/**/ 0x5FF9440B, 0xBD33DD35,
+/**/ 0x4FE7B9FF, 0xBF450C89,
+/**/ 0x8FA00000, 0x3F450E44,
+/**/ 0xAA4D276D, 0x3D224D49,
+/**/ 0x0B35267A, 0xBF451C84,
+/**/ 0xED200000, 0x3F451E41,
+/**/ 0x11B557F9, 0xBD3884D4,
+/**/ 0xC2848D4F, 0xBF452C7E,
+/**/ 0x48800000, 0x3F452E3F,
+/**/ 0xB43290C4, 0x3D1C857D,
+/**/ 0x75D5EFFC, 0xBF453C79,
+/**/ 0xA2000000, 0x3F453E3C,
+/**/ 0x2D598D3C, 0xBD37E5C1,
+/**/ 0x25294FFF, 0xBF454C74,
+/**/ 0xF9600000, 0x3F454E39,
+/**/ 0x3FE47B89, 0x3D24CD93,
+/**/ 0xD07EAED8, 0xBF455C6E,
+/**/ 0x4EE00000, 0x3F455E37,
+/**/ 0xAA959122, 0xBD31F800,
+/**/ 0x77D60E06, 0xBF456C69,
+/**/ 0xA2400000, 0x3F456E34,
+/**/ 0x7329AF92, 0x3D32FEDF,
+/**/ 0x1B2F6F08, 0xBF457C64,
+/**/ 0xF3C00000, 0x3F457E31,
+/**/ 0x1C545A6F, 0xBD1ACE5A,
+/**/ 0xBA8AD35D, 0xBF458C5E,
+/**/ 0x43400000, 0x3F458E2F,
+/**/ 0x19F6B9EF, 0xBD3F0E63,
+/**/ 0x55E83C84, 0xBF459C59,
+/**/ 0x90A00000, 0x3F459E2C,
+/**/ 0x73005F6F, 0x3D23DEF2,
+/**/ 0xED47ABFB, 0xBF45AC53,
+/**/ 0xDC200000, 0x3F45AE29,
+/**/ 0x1C295DE7, 0xBD277204,
+/**/ 0x80A92343, 0xBF45BC4E,
+/**/ 0x25800000, 0x3F45BE27,
+/**/ 0x8D869589, 0x3D3FF92A,
+/**/ 0x100CA3D9, 0xBF45CC49,
+/**/ 0x6D000000, 0x3F45CE24,
+/**/ 0x145C5335, 0x3D2A0DFD,
+/**/ 0x9B722F3C, 0xBF45DC43,
+/**/ 0xB2800000, 0x3F45DE21,
+/**/ 0x6A8614B3, 0xBD123A1A,
+/**/ 0x22D9C6ED, 0xBF45EC3E,
+/**/ 0xF6000000, 0x3F45EE1E,
+/**/ 0x63CBC7E7, 0xBD34C665,
+/**/ 0xA6436C69, 0xBF45FC38,
+/**/ 0x37600000, 0x3F45FE1C,
+/**/ 0xAB6C51D7, 0x3D3C6061,
+/**/ 0x25AF2130, 0xBF460C33,
+/**/ 0x76E00000, 0x3F460E19,
+/**/ 0x1EC7F453, 0x3D2DCD9C,
+/**/ 0xA11CE6C1, 0xBF461C2D,
+/**/ 0xB4600000, 0x3F461E16,
+/**/ 0x20C52899, 0x3D066EFA,
+/**/ 0x188CBE9A, 0xBF462C28,
+/**/ 0xEFE00000, 0x3F462E13,
+/**/ 0xEB5FDD5C, 0xBD1FA5AC,
+/**/ 0x8BFEAA3B, 0xBF463C22,
+/**/ 0x29600000, 0x3F463E11,
+/**/ 0xF22FE2BC, 0xBD313E11,
+/**/ 0xFB72AB23, 0xBF464C1C,
+/**/ 0x60E00000, 0x3F464E0E,
+/**/ 0x6710E251, 0xBD392F15,
+/**/ 0x66E8C2D0, 0xBF465C17,
+/**/ 0x96600000, 0x3F465E0B,
+/**/ 0x1EFC78A7, 0xBD3FBB76,
+/**/ 0xCE60F2C1, 0xBF466C11,
+/**/ 0xC9C00000, 0x3F466E08,
+/**/ 0x602C1A84, 0x3D3B1DCB,
+/**/ 0x31DB3C76, 0xBF467C0C,
+/**/ 0xFB400000, 0x3F467E05,
+/**/ 0x9027DA74, 0x3D375DAE,
+/**/ 0x9157A16E, 0xBF468C06,
+/**/ 0x2AC00000, 0x3F468E03,
+/**/ 0xEA560DA0, 0x3D350532,
+/**/ 0xECD62326, 0xBF469C00,
+/**/ 0x58400000, 0x3F469E00,
+/**/ 0xE7B63DE2, 0x3D341557 } };
+
+#endif
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/urem.h b/libc/sysdeps/ieee754/dbl-64/urem.h
new file mode 100644
index 000000000..3713dd90d
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/urem.h
@@ -0,0 +1,51 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/************************************************************************/
+/* MODULE_NAME: urem.h */
+/* */
+/* */
+/* common data and variables definition for BIG or LITTLE ENDIAN */
+/************************************************************************/
+
+#ifndef UREM_H
+#define UREM_H
+
+#ifdef BIG_ENDI
+static const mynumber big = {{0x43380000, 0}}, /* 6755399441055744 */
+ t128 = {{0x47f00000, 0}}, /* 2^ 128 */
+ tm128 = {{0x37f00000, 0}}, /* 2^-128 */
+ ZERO = {{0, 0}}, /* 0.0 */
+ nZERO = {{0x80000000, 0}}, /* -0.0 */
+ NAN = {{0x7ff80000, 0}}, /* NaN */
+ nNAN = {{0xfff80000, 0}}; /* -NaN */
+#else
+#ifdef LITTLE_ENDI
+static const mynumber big = {{0, 0x43380000}}, /* 6755399441055744 */
+ t128 = {{0, 0x47f00000}}, /* 2^ 128 */
+ tm128 = {{0, 0x37f00000}}, /* 2^-128 */
+ ZERO = {{0, 0}}, /* 0.0 */
+ nZERO = {{0, 0x80000000}}, /* -0.0 */
+ NAN = {{0, 0x7ff80000}}, /* NaN */
+ nNAN = {{0, 0xfff80000}}; /* -NaN */
+#endif
+#endif
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/uroot.h b/libc/sysdeps/ieee754/dbl-64/uroot.h
new file mode 100644
index 000000000..02b74cb26
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/uroot.h
@@ -0,0 +1,44 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/******************************************************************/
+/* */
+/* MODULE_NAME:uroot.h */
+/* */
+/* common data and variables prototype and definition */
+/******************************************************************/
+
+#ifndef UROOT_H
+#define UROOT_H
+
+#ifdef BIG_ENDI
+ static const mynumber
+/**/ t512 = {{0x5ff00000, 0x00000000 }}, /* 2^512 */
+/**/ tm256 = {{0x2ff00000, 0x00000000 }}; /* 2^-256 */
+
+#else
+#ifdef LITTLE_ENDI
+ static const mynumber
+/**/ t512 = {{0x00000000, 0x5ff00000 }}, /* 2^512 */
+/**/ tm256 = {{0x00000000, 0x2ff00000 }}; /* 2^-256 */
+#endif
+#endif
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/usncs.h b/libc/sysdeps/ieee754/dbl-64/usncs.h
new file mode 100644
index 000000000..6c80f0cf9
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/usncs.h
@@ -0,0 +1,80 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/************************************************************************/
+/* MODULE_NAME: dosincos.h */
+/* */
+/* */
+/* common data and variables definition for BIG or LITTLE ENDIAN */
+/************************************************************************/
+
+#ifndef USNCS_H
+#define USNCS_H
+
+#ifdef BIG_ENDI
+static const mynumber
+
+/**/ NAN = {{0x7ff80000, 0x00000000 }}, /* NaN */
+/**/ s1 = {{0xBFC55555, 0x55555555 }}, /* -0.16666666666666666 */
+/**/ s2 = {{0x3F811111, 0x11110ECE }}, /* 0.0083333333333323288 */
+/**/ s3 = {{0xBF2A01A0, 0x19DB08B8 }}, /* -0.00019841269834414642 */
+/**/ s4 = {{0x3EC71DE2, 0x7B9A7ED9 }}, /* 2.755729806860771e-06 */
+/**/ s5 = {{0xBE5ADDFF, 0xC2FCDF59 }}, /* -2.5022014848318398e-08 */
+/**/ aa = {{0xBFC55580, 0x00000000 }}, /* -0.1666717529296875 */
+/**/ bb = {{0x3ED55555, 0x55556E24 }}, /* 5.0862630208387126e-06 */
+/**/ big = {{0x42c80000, 0x00000000 }}, /* 52776558133248 */
+/**/ hp0 = {{0x3FF921FB, 0x54442D18 }}, /* 1.5707963267948966 */
+/**/ hp1 = {{0x3C91A626, 0x33145C07 }}, /* 6.123233995736766e-17 */
+/**/ mp1 = {{0x3FF921FB, 0x58000000 }}, /* 1.5707963407039642 */
+/**/ mp2 = {{0xBE4DDE97, 0x3C000000 }}, /* -1.3909067564377153e-08 */
+/**/ mp3 = {{0xBC8CB3B3, 0x99D747F2 }}, /* -4.9789962505147994e-17 */
+/**/ pp3 = {{0xBC8CB3B3, 0x98000000 }}, /* -4.9789962314799099e-17 */
+/**/ pp4 = {{0xbacd747f, 0x23e32ed7 }}, /* -1.9034889620193266e-25 */
+/**/ hpinv = {{0x3FE45F30, 0x6DC9C883 }}, /* 0.63661977236758138 */
+/**/ toint = {{0x43380000, 0x00000000 }}; /* 6755399441055744 */
+
+#else
+#ifdef LITTLE_ENDI
+static const mynumber
+
+/**/ NAN = {{0x00000000, 0x7ff80000 }},/* NaN */
+/**/ s1 = {{0x55555555, 0xBFC55555 }},/* -0.16666666666666666 */
+/**/ s2 = {{0x11110ECE, 0x3F811111 }},/* 0.0083333333333323288 */
+/**/ s3 = {{0x19DB08B8, 0xBF2A01A0 }},/* -0.00019841269834414642 */
+/**/ s4 = {{0x7B9A7ED9, 0x3EC71DE2 }},/* 2.755729806860771e-06 */
+/**/ s5 = {{0xC2FCDF59, 0xBE5ADDFF }},/* -2.5022014848318398e-08 */
+/**/ aa = {{0x00000000, 0xBFC55580 }},/* -0.1666717529296875 */
+/**/ bb = {{0x55556E24, 0x3ED55555 }},/* 5.0862630208387126e-06 */
+/**/ big = {{0x00000000, 0x42c80000 }},/* 52776558133248 */
+/**/ hp0 = {{0x54442D18, 0x3FF921FB }},/* 1.5707963267948966 */
+/**/ hp1 = {{0x33145C07, 0x3C91A626 }},/* 6.123233995736766e-17 */
+/**/ mp1 = {{0x58000000, 0x3FF921FB }},/* 1.5707963407039642 */
+/**/ mp2 = {{0x3C000000, 0xBE4DDE97 }},/* -1.3909067564377153e-08 */
+/**/ mp3 = {{0x99D747F2, 0xBC8CB3B3 }},/* -4.9789962505147994e-17 */
+/**/ pp3 = {{0x98000000, 0xBC8CB3B3 }},/* -4.9789962314799099e-17 */
+/**/ pp4 = {{0x23e32ed7, 0xbacd747f }},/* -1.9034889620193266e-25 */
+/**/ hpinv = {{0x6DC9C883, 0x3FE45F30 }},/* 0.63661977236758138 */
+/**/ toint = {{0x00000000, 0x43380000 }};/* 6755399441055744 */
+
+
+#endif
+#endif
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/utan.h b/libc/sysdeps/ieee754/dbl-64/utan.h
new file mode 100644
index 000000000..c866e88ed
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/utan.h
@@ -0,0 +1,280 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/******************************************************************/
+/* */
+/* MODULE_NAME:utan.h */
+/* */
+/* common data and variables prototype and definition */
+/******************************************************************/
+
+#ifndef UTAN_H
+#define UTAN_H
+
+#ifdef BIG_ENDI
+ static const number
+ /* polynomial I */
+/**/ d3 = {{0x3FD55555, 0x55555555} }, /* 0.333... */
+/**/ d5 = {{0x3FC11111, 0x111107C6} }, /* 0.133... */
+/**/ d7 = {{0x3FABA1BA, 0x1CDB8745} }, /* . */
+/**/ d9 = {{0x3F9664ED, 0x49CFC666} }, /* . */
+/**/ d11 = {{0x3F82385A, 0x3CF2E4EA} }, /* . */
+ /* polynomial II */
+/**/ a3 = {{0x3fd55555, 0x55555555} }, /* 1/3 */
+/**/ aa3 = {{0x3c755555, 0x55555555} }, /* 1/3-a3 */
+/**/ a5 = {{0x3fc11111, 0x11111111} }, /* 2/15 */
+/**/ aa5 = {{0x3c411111, 0x11111111} }, /* 2/15-a5 */
+/**/ a7 = {{0x3faba1ba, 0x1ba1ba1c} }, /* 17/315 */
+/**/ aa7 = {{0xbc479179, 0x17917918} }, /* ()-a7 */
+/**/ a9 = {{0x3f9664f4, 0x882c10fa} }, /* 62/2835 */
+/**/ aa9 = {{0xbc09a528, 0x8b6c44fd} }, /* ()-a9 */
+/**/ a11 = {{0x3f8226e3, 0x55e6c23d} }, /* . */
+/**/ aa11 = {{0xbc2c292b, 0x8f1a2c13} }, /* . */
+/**/ a13 = {{0x3f6d6d3d, 0x0e157de0} }, /* . */
+/**/ aa13 = {{0xbc0280cf, 0xc968d971} }, /* . */
+/**/ a15 = {{0x3f57da36, 0x452b75e3} }, /* . */
+#if 0
+/**/ aa15 = {{0xbbf25789, 0xb285d2ed} }, /* . */
+#endif
+/**/ a17 = {{0x3f435582, 0x48036744} }, /* . */
+#if 0
+/**/ aa17 = {{0x3be488d9, 0x563f1f23} }, /* . */
+#endif
+/**/ a19 = {{0x3f2f57d7, 0x734d1664} }, /* . */
+#if 0
+/**/ aa19 = {{0x3bb0d55a, 0x913ccb50} }, /* . */
+#endif
+/**/ a21 = {{0x3f1967e1, 0x8afcafad} }, /* . */
+#if 0
+/**/ aa21 = {{0xbbbd7614, 0xa42d44e6} }, /* . */
+#endif
+/**/ a23 = {{0x3f0497d8, 0xeea25259} }, /* . */
+#if 0
+/**/ aa23 = {{0x3b99f2d0, 0x2e4d2863} }, /* . */
+#endif
+/**/ a25 = {{0x3ef0b132, 0xd39a6050} }, /* . */
+#if 0
+/**/ aa25 = {{0x3b93b274, 0xc2c19614} }, /* . */
+#endif
+/**/ a27 = {{0x3edb0f72, 0xd3ee24e9} }, /* . */
+#if 0
+/**/ aa27 = {{0x3b61688d, 0xdd595609} }, /* . */
+#endif
+ /* polynomial III */
+/**/ e0 = {{0x3FD55555, 0x55554DBD} }, /* . */
+/**/ e1 = {{0x3FC11112, 0xE0A6B45F} }, /* . */
+
+ /* constants */
+/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */
+/**/ one = {{0x3ff00000, 0x00000000} }, /* 1 */
+/**/ mone = {{0xbff00000, 0x00000000} }, /*-1 */
+/**/ mfftnhf = {{0xc02f0000, 0x00000000} }, /*-15.5 */
+/**/ two8 = {{0x40700000, 0x00000000} }, /* 256 */
+
+/**/ g1 = {{0x3e4b096c, 0x00000000} }, /* 1.259e-8 */
+/**/ g2 = {{0x3faf212d, 0x00000000} }, /* 0.0608 */
+/**/ g3 = {{0x3fe92f1a, 0x00000000} }, /* 0.787 */
+/**/ g4 = {{0x40390000, 0x00000000} }, /* 25.0 */
+/**/ g5 = {{0x4197d784, 0x00000000} }, /* 1e8 */
+/**/ gy1 = {{0x3e7ad7f2, 0x9abcaf48} }, /* 1e-7 */
+/**/ gy2 = {{0x3faf212d, 0x00000000} }, /* 0.0608 */
+
+/**/ u1 = {{0x3cc8c33a, 0x00000000} }, /* 6.873e-16 */
+/**/ u2 = {{0x3983dc4d, 0x00000000} }, /* 1.224e-31 */
+/**/ u3 = {{0x3c78e14b, 0x00000000} }, /* 2.158e-17 */
+/**/ ua3 = {{0x3bfd8b58, 0x00000000} }, /* 1.001e-19 */
+/**/ ub3 = {{0x3cc81898, 0x00000000} }, /* 6.688e-16 */
+/**/ u4 = {{0x399856c2, 0x00000000} }, /* 3e-31 */
+/**/ u5 = {{0x3c39d80a, 0x00000000} }, /* 1.401e-18 */
+/**/ u6 = {{0x3c374c5a, 0x00000000} }, /* 1.263e-18 */
+/**/ u7 = {{0x39903beb, 0x00000000} }, /* 2.001e-31 */
+/**/ u8 = {{0x399c56ae, 0x00000000} }, /* 3.493e-31 */
+/**/ u9 = {{0x3c7d0ac7, 0x00000000} }, /* 2.519e-17 */
+/**/ ua9 = {{0x3bfd8b58, 0x00000000} }, /* 1.001e-19 */
+/**/ ub9 = {{0x3ccc2375, 0x00000000} }, /* 7.810e-16 */
+/**/ u10 = {{0x3c7e40af, 0x00000000} }, /* 2.624e-17 */
+/**/ ua10 = {{0x3bfd8b58, 0x00000000} }, /* 1.001e-19 */
+/**/ ub10 = {{0x3ccc6405, 0x00000000} }, /* 7.880e-16 */
+/**/ u11 = {{0x39e509b6, 0x00000000} }, /* 8.298e-30 */
+/**/ u12 = {{0x39e509b6, 0x00000000} }, /* 8.298e-30 */
+/**/ u13 = {{0x3c39d80a, 0x00000000} }, /* 1.401e-18 */
+/**/ u14 = {{0x3c374c5a, 0x00000000} }, /* 1.263e-18 */
+/**/ u15 = {{0x3ab5767a, 0x00000000} }, /* 6.935e-26 */
+/**/ u16 = {{0x3ab57744, 0x00000000} }, /* 6.936e-26 */
+/**/ u17 = {{0x3c7d0ac7, 0x00000000} }, /* 2.519e-17 */
+/**/ ua17 = {{0x3bfdb11f, 0x00000000} }, /* 1.006e-19 */
+/**/ ub17 = {{0x3ccc2375, 0x00000000} }, /* 7.810e-16 */
+/**/ u18 = {{0x3c7e40af, 0x00000000} }, /* 2.624e-17 */
+/**/ ua18 = {{0x3bfdb11f, 0x00000000} }, /* 1.006e-19 */
+/**/ ub18 = {{0x3ccc6405, 0x00000000} }, /* 7.880e-16 */
+/**/ u19 = {{0x39a13b61, 0x00000000} }, /* 4.248e-31 */
+/**/ u20 = {{0x39a13b61, 0x00000000} }, /* 4.248e-31 */
+/**/ u21 = {{0x3c3bb9b8, 0x00000000} }, /* 1.503e-18 */
+/**/ u22 = {{0x3c392e08, 0x00000000} }, /* 1.365e-18 */
+/**/ u23 = {{0x3a0ce706, 0x00000000} }, /* 4.560e-29 */
+/**/ u24 = {{0x3a0cff5d, 0x00000000} }, /* 4.575e-29 */
+/**/ u25 = {{0x3c7d0ac7, 0x00000000} }, /* 2.519e-17 */
+/**/ ua25 = {{0x3bfd8b58, 0x00000000} }, /* 1.001e-19 */
+/**/ ub25 = {{0x3ccc2375, 0x00000000} }, /* 7.810e-16 */
+/**/ u26 = {{0x3c7e40af, 0x00000000} }, /* 2.624e-17 */
+/**/ ua26 = {{0x3bfd8b58, 0x00000000} }, /* 1.001e-19 */
+/**/ ub26 = {{0x3ccc6405, 0x00000000} }, /* 7.880e-16 */
+/**/ u27 = {{0x3ad421cb, 0x00000000} }, /* 2.602e-25 */
+/**/ u28 = {{0x3ad421cb, 0x00000000} }, /* 2.602e-25 */
+
+/**/ mp1 = {{0x3FF921FB, 0x58000000} },
+/**/ mp2 = {{0xBE4DDE97, 0x3C000000} },
+/**/ mp3 = {{0xBC8CB3B3, 0x99D747F2} },
+/**/ pp3 = {{0xBC8CB3B3, 0x98000000} },
+/**/ pp4 = {{0xbacd747f, 0x23e32ed7} },
+/**/ hpinv = {{0x3FE45F30, 0x6DC9C883} },
+/**/ toint = {{0x43380000, 0x00000000} };
+
+#else
+#ifdef LITTLE_ENDI
+
+ static const number
+ /* polynomial I */
+/**/ d3 = {{0x55555555, 0x3FD55555} }, /* 0.333... */
+/**/ d5 = {{0x111107C6, 0x3FC11111} }, /* 0.133... */
+/**/ d7 = {{0x1CDB8745, 0x3FABA1BA} }, /* . */
+/**/ d9 = {{0x49CFC666, 0x3F9664ED} }, /* . */
+/**/ d11 = {{0x3CF2E4EA, 0x3F82385A} }, /* . */
+ /* polynomial II */
+/**/ a3 = {{0x55555555, 0x3fd55555} }, /* 1/3 */
+/**/ aa3 = {{0x55555555, 0x3c755555} }, /* 1/3-a3 */
+/**/ a5 = {{0x11111111, 0x3fc11111} }, /* 2/15 */
+/**/ aa5 = {{0x11111111, 0x3c411111} }, /* 2/15-a5 */
+/**/ a7 = {{0x1ba1ba1c, 0x3faba1ba} }, /* 17/315 */
+/**/ aa7 = {{0x17917918, 0xbc479179} }, /* ()-a7 */
+/**/ a9 = {{0x882c10fa, 0x3f9664f4} }, /* 62/2835 */
+/**/ aa9 = {{0x8b6c44fd, 0xbc09a528} }, /* ()-a9 */
+/**/ a11 = {{0x55e6c23d, 0x3f8226e3} }, /* . */
+/**/ aa11 = {{0x8f1a2c13, 0xbc2c292b} }, /* . */
+/**/ a13 = {{0x0e157de0, 0x3f6d6d3d} }, /* . */
+/**/ aa13 = {{0xc968d971, 0xbc0280cf} }, /* . */
+/**/ a15 = {{0x452b75e3, 0x3f57da36} }, /* . */
+#if 0
+/**/ aa15 = {{0xb285d2ed, 0xbbf25789} }, /* . */
+#endif
+/**/ a17 = {{0x48036744, 0x3f435582} }, /* . */
+#if 0
+/**/ aa17 = {{0x563f1f23, 0x3be488d9} }, /* . */
+#endif
+/**/ a19 = {{0x734d1664, 0x3f2f57d7} }, /* . */
+#if 0
+/**/ aa19 = {{0x913ccb50, 0x3bb0d55a} }, /* . */
+#endif
+/**/ a21 = {{0x8afcafad, 0x3f1967e1} }, /* . */
+#if 0
+/**/ aa21 = {{0xa42d44e6, 0xbbbd7614} }, /* . */
+#endif
+/**/ a23 = {{0xeea25259, 0x3f0497d8} }, /* . */
+#if 0
+/**/ aa23 = {{0x2e4d2863, 0x3b99f2d0} }, /* . */
+#endif
+/**/ a25 = {{0xd39a6050, 0x3ef0b132} }, /* . */
+#if 0
+/**/ aa25 = {{0xc2c19614, 0x3b93b274} }, /* . */
+#endif
+/**/ a27 = {{0xd3ee24e9, 0x3edb0f72} }, /* . */
+#if 0
+/**/ aa27 = {{0xdd595609, 0x3b61688d} }, /* . */
+#endif
+ /* polynomial III */
+/**/ e0 = {{0x55554DBD, 0x3FD55555} }, /* . */
+/**/ e1 = {{0xE0A6B45F, 0x3FC11112} }, /* . */
+
+ /* constants */
+/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */
+/**/ one = {{0x00000000, 0x3ff00000} }, /* 1 */
+/**/ mone = {{0x00000000, 0xbff00000} }, /*-1 */
+/**/ mfftnhf = {{0x00000000, 0xc02f0000} }, /*-15.5 */
+/**/ two8 = {{0x00000000, 0x40700000} }, /* 256 */
+
+/**/ g1 = {{0x00000000, 0x3e4b096c} }, /* 1.259e-8 */
+/**/ g2 = {{0x00000000, 0x3faf212d} }, /* 0.0608 */
+/**/ g3 = {{0x00000000, 0x3fe92f1a} }, /* 0.787 */
+/**/ g4 = {{0x00000000, 0x40390000} }, /* 25.0 */
+/**/ g5 = {{0x00000000, 0x4197d784} }, /* 1e8 */
+/**/ gy1 = {{0x9abcaf48, 0x3e7ad7f2} }, /* 1e-7 */
+/**/ gy2 = {{0x00000000, 0x3faf212d} }, /* 0.0608 */
+
+/**/ u1 = {{0x00000000, 0x3cc8c33a} }, /* 6.873e-16 */
+/**/ u2 = {{0x00000000, 0x3983dc4d} }, /* 1.224e-31 */
+/**/ u3 = {{0x00000000, 0x3c78e14b} }, /* 2.158e-17 */
+/**/ ua3 = {{0x00000000, 0x3bfd8b58} }, /* 1.001e-19 */
+/**/ ub3 = {{0x00000000, 0x3cc81898} }, /* 6.688e-16 */
+/**/ u4 = {{0x00000000, 0x399856c2} }, /* 3e-31 */
+/**/ u5 = {{0x00000000, 0x3c39d80a} }, /* 1.401e-18 */
+/**/ u6 = {{0x00000000, 0x3c374c5a} }, /* 1.263e-18 */
+/**/ u7 = {{0x00000000, 0x39903beb} }, /* 2.001e-31 */
+/**/ u8 = {{0x00000000, 0x399c56ae} }, /* 3.493e-31 */
+/**/ u9 = {{0x00000000, 0x3c7d0ac7} }, /* 2.519e-17 */
+/**/ ua9 = {{0x00000000, 0x3bfd8b58} }, /* 1.001e-19 */
+/**/ ub9 = {{0x00000000, 0x3ccc2375} }, /* 7.810e-16 */
+/**/ u10 = {{0x00000000, 0x3c7e40af} }, /* 2.624e-17 */
+/**/ ua10 = {{0x00000000, 0x3bfd8b58} }, /* 1.001e-19 */
+/**/ ub10 = {{0x00000000, 0x3ccc6405} }, /* 7.880e-16 */
+/**/ u11 = {{0x00000000, 0x39e509b6} }, /* 8.298e-30 */
+/**/ u12 = {{0x00000000, 0x39e509b6} }, /* 8.298e-30 */
+/**/ u13 = {{0x00000000, 0x3c39d80a} }, /* 1.401e-18 */
+/**/ u14 = {{0x00000000, 0x3c374c5a} }, /* 1.263e-18 */
+/**/ u15 = {{0x00000000, 0x3ab5767a} }, /* 6.935e-26 */
+/**/ u16 = {{0x00000000, 0x3ab57744} }, /* 6.936e-26 */
+/**/ u17 = {{0x00000000, 0x3c7d0ac7} }, /* 2.519e-17 */
+/**/ ua17 = {{0x00000000, 0x3bfdb11f} }, /* 1.006e-19 */
+/**/ ub17 = {{0x00000000, 0x3ccc2375} }, /* 7.810e-16 */
+/**/ u18 = {{0x00000000, 0x3c7e40af} }, /* 2.624e-17 */
+/**/ ua18 = {{0x00000000, 0x3bfdb11f} }, /* 1.006e-19 */
+/**/ ub18 = {{0x00000000, 0x3ccc6405} }, /* 7.880e-16 */
+/**/ u19 = {{0x00000000, 0x39a13b61} }, /* 4.248e-31 */
+/**/ u20 = {{0x00000000, 0x39a13b61} }, /* 4.248e-31 */
+/**/ u21 = {{0x00000000, 0x3c3bb9b8} }, /* 1.503e-18 */
+/**/ u22 = {{0x00000000, 0x3c392e08} }, /* 1.365e-18 */
+/**/ u23 = {{0x00000000, 0x3a0ce706} }, /* 4.560e-29 */
+/**/ u24 = {{0x00000000, 0x3a0cff5d} }, /* 4.575e-29 */
+/**/ u25 = {{0x00000000, 0x3c7d0ac7} }, /* 2.519e-17 */
+/**/ ua25 = {{0x00000000, 0x3bfd8b58} }, /* 1.001e-19 */
+/**/ ub25 = {{0x00000000, 0x3ccc2375} }, /* 7.810e-16 */
+/**/ u26 = {{0x00000000, 0x3c7e40af} }, /* 2.624e-17 */
+/**/ ua26 = {{0x00000000, 0x3bfd8b58} }, /* 1.001e-19 */
+/**/ ub26 = {{0x00000000, 0x3ccc6405} }, /* 7.880e-16 */
+/**/ u27 = {{0x00000000, 0x3ad421cb} }, /* 2.602e-25 */
+/**/ u28 = {{0x00000000, 0x3ad421cb} }, /* 2.602e-25 */
+
+/**/ mp1 = {{0x58000000, 0x3FF921FB} },
+/**/ mp2 = {{0x3C000000, 0xBE4DDE97} },
+/**/ mp3 = {{0x99D747F2, 0xBC8CB3B3} },
+/**/ pp3 = {{0x98000000, 0xBC8CB3B3} },
+/**/ pp4 = {{0x23e32ed7, 0xbacd747f} },
+/**/ hpinv = {{0x6DC9C883, 0x3FE45F30} },
+/**/ toint = {{0x00000000, 0x43380000} };
+
+#endif
+#endif
+
+
+#define ZERO zero.d
+#define ONE one.d
+#define MONE mone.d
+#define TWO8 two8.d
+
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/utan.tbl b/libc/sysdeps/ieee754/dbl-64/utan.tbl
new file mode 100644
index 000000000..eb248bada
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/utan.tbl
@@ -0,0 +1,1526 @@
+/*
+ * IBM Accurate Mathematical Library
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/****************************************************************/
+/* TABLES FOR THE utan() FUNCTION */
+/****************************************************************/
+
+
+#ifdef BIG_ENDI
+static const number
+ xfg[186][4] = { /* xi,Fi,Gi,FFi, i=16..201 */
+/**/ {{{0x3fb00000, 0x1e519d60} },
+/**/ {{0x3fb00557, 0x96c4e240} },
+/**/ {{0x402ff554, 0x628127b7} },
+/**/ {{0xbb9a1dee, 0x9e355b06} },},
+/**/ {{{0x3fb10000, 0x1b1a7010} },
+/**/ {{0x3fb10668, 0xaab892b7} },
+/**/ {{0x402e12c7, 0xbe3fdf74} },
+/**/ {{0x3ba89234, 0x037da741} },},
+/**/ {{{0x3fb20000, 0x2505e350} },
+/**/ {{0x3fb2079b, 0xff547824} },
+/**/ {{0x402c65c5, 0xde853633} },
+/**/ {{0x3bb7486e, 0xe9614250} },},
+/**/ {{{0x3fb2ffff, 0xfcdc4252} },
+/**/ {{0x3fb308f3, 0x5eb16c68} },
+/**/ {{0x402ae5da, 0xe56be74f} },
+/**/ {{0xbb82c726, 0x91a23034} },},
+/**/ {{{0x3fb3ffff, 0xe3ff849f} },
+/**/ {{0x3fb40a71, 0x154999cc} },
+/**/ {{0x40298c43, 0x046b7352} },
+/**/ {{0x3b9aceaf, 0x3843738f} },},
+/**/ {{{0x3fb4ffff, 0xedc9590f} },
+/**/ {{0x3fb50c17, 0x429bdd80} },
+/**/ {{0x40285384, 0x91b5d674} },
+/**/ {{0xbbc1d02d, 0xb4403d22} },},
+/**/ {{{0x3fb60000, 0x00ee83f7} },
+/**/ {{0x3fb60de7, 0xda80cc21} },
+/**/ {{0x40273724, 0xef21a2a7} },
+/**/ {{0xbb95e53c, 0x72523ffd} },},
+/**/ {{{0x3fb6ffff, 0xeb05ea41} },
+/**/ {{0x3fb70fe4, 0xb8c51bea} },
+/**/ {{0x40263370, 0xfae562ff} },
+/**/ {{0xbb99ad0e, 0x8ffe0626} },},
+/**/ {{{0x3fb7ffff, 0xdc0515f7} },
+/**/ {{0x3fb81210, 0x1db54498} },
+/**/ {{0x40254553, 0x0e7eab5c} },
+/**/ {{0xbb914c87, 0xd62ed686} },},
+/**/ {{{0x3fb8ffff, 0xe384d7ab} },
+/**/ {{0x3fb9146c, 0x2a8d3727} },
+/**/ {{0x40246a33, 0xfd57f3fd} },
+/**/ {{0xbbbbda8d, 0x5381e06d} },},
+/**/ {{{0x3fb9ffff, 0xe4832347} },
+/**/ {{0x3fba16fa, 0xd50e1050} },
+/**/ {{0x40239fe2, 0xc5537a96} },
+/**/ {{0x3bc7f695, 0xc111eabb} },},
+/**/ {{{0x3fbb0000, 0x274540e3} },
+/**/ {{0x3fbb19be, 0x7ae68517} },
+/**/ {{0x4022e481, 0x3637e946} },
+/**/ {{0x3bc307f8, 0x8dbd9d93} },},
+/**/ {{{0x3fbbffff, 0xfebf2e9b} },
+/**/ {{0x3fbc1cb8, 0x8369cd19} },
+/**/ {{0x40223676, 0x17aef223} },
+/**/ {{0x3bc50038, 0x424a9cf3} },},
+/**/ {{{0x3fbd0000, 0x23529045} },
+/**/ {{0x3fbd1feb, 0xc11d7ef7} },
+/**/ {{0x4021945f, 0xb8e43d4e} },
+/**/ {{0x3b812007, 0x52a6f224} },},
+/**/ {{{0x3fbdffff, 0xd872a829} },
+/**/ {{0x3fbe2359, 0x8ee4d6b7} },
+/**/ {{0x4020fd0c, 0x76195d5f} },
+/**/ {{0xbbb4d9ab, 0x85fdca85} },},
+/**/ {{{0x3fbeffff, 0xff323b84} },
+/**/ {{0x3fbf2704, 0xec9073e5} },
+/**/ {{0x40206f71, 0x3020200f} },
+/**/ {{0x3bb77aa2, 0x12836992} },},
+/**/ {{{0x3fc00000, 0x0ce79195} },
+/**/ {{0x3fc01577, 0xbc30cc61} },
+/**/ {{0x401fd549, 0xd6564a88} },
+/**/ {{0xbbc8926f, 0x965c0ad0} },},
+/**/ {{{0x3fc07fff, 0xee40e918} },
+/**/ {{0x3fc0978d, 0x8279ac01} },
+/**/ {{0x401edbb5, 0x9294bc03} },
+/**/ {{0xbb80a533, 0x4aae45d6} },},
+/**/ {{{0x3fc10000, 0x0cc091fd} },
+/**/ {{0x3fc119c5, 0x44dfb2f7} },
+/**/ {{0x401df0bb, 0x067d8e18} },
+/**/ {{0xbbcc2c18, 0x4ff642a4} },},
+/**/ {{{0x3fc18000, 0x0d9936a1} },
+/**/ {{0x3fc19c1f, 0xb9085a4b} },
+/**/ {{0x401d131a, 0x71ce3629} },
+/**/ {{0xbbc36553, 0x0669355b} },},
+/**/ {{{0x3fc1ffff, 0xed5f3188} },
+/**/ {{0x3fc21e9d, 0xee74bf2d} },
+/**/ {{0x401c41b6, 0xff0cd655} },
+/**/ {{0x3b8867f5, 0x478ecfc5} },},
+/**/ {{{0x3fc28000, 0x05f06a51} },
+/**/ {{0x3fc2a141, 0x550b313f} },
+/**/ {{0x401b7b92, 0x1702e6d2} },
+/**/ {{0xbbadab51, 0x380131fe} },},
+/**/ {{{0x3fc2ffff, 0xfe3d339e} },
+/**/ {{0x3fc3240a, 0xa75f76df} },
+/**/ {{0x401abfc8, 0xfcb6409d} },
+/**/ {{0x3bc60bcf, 0x0d291d83} },},
+/**/ {{{0x3fc37fff, 0xed888d6f} },
+/**/ {{0x3fc3a6fb, 0x13cc5db7} },
+/**/ {{0x401a0d8f, 0x8ed5320d} },
+/**/ {{0x3bb8a48e, 0x4eef03ab} },},
+/**/ {{{0x3fc40000, 0x02ca050d} },
+/**/ {{0x3fc42a13, 0xe25776bb} },
+/**/ {{0x4019642d, 0xfa84c2bc} },
+/**/ {{0xbbd0bd5d, 0xcc56516f} },},
+/**/ {{{0x3fc47fff, 0xf2531f5c} },
+/**/ {{0x3fc4ad55, 0xdeb73404} },
+/**/ {{0x4018c2fe, 0xf86e9035} },
+/**/ {{0x3b9cffe7, 0x5aa287c8} },},
+/**/ {{{0x3fc50000, 0x13774992} },
+/**/ {{0x3fc530c2, 0x7d0ee307} },
+/**/ {{0x4018296c, 0x370caf35} },
+/**/ {{0xbbcf75d1, 0xf91d6532} },},
+/**/ {{{0x3fc57fff, 0xedddcb2d} },
+/**/ {{0x3fc5b45a, 0x5db4347d} },
+/**/ {{0x401796ee, 0x52190c0e} },
+/**/ {{0x3b88a25f, 0x17d5d076} },},
+/**/ {{{0x3fc5ffff, 0xf41949a0} },
+/**/ {{0x3fc6381f, 0x13bf986a} },
+/**/ {{0x40170b09, 0x2d2255fd} },
+/**/ {{0xbb9bfb23, 0xb1bcd5e7} },},
+/**/ {{{0x3fc67fff, 0xf834d3a1} },
+/**/ {{0x3fc6bc11, 0x8ec85952} },
+/**/ {{0x4016854c, 0x62cf2268} },
+/**/ {{0x3b9ee53b, 0x82e39e04} },},
+/**/ {{{0x3fc6ffff, 0xfd9106ea} },
+/**/ {{0x3fc74032, 0xf298f6f7} },
+/**/ {{0x40160551, 0x1f4f84a9} },
+/**/ {{0xbbb59c4a, 0x112634b8} },},
+/**/ {{{0x3fc78000, 0x0f649a4f} },
+/**/ {{0x3fc7c484, 0x6ca53abc} },
+/**/ {{0x40158ab9, 0x4809d175} },
+/**/ {{0x3bc91c75, 0x73d3cd2e} },},
+/**/ {{{0x3fc7ffff, 0xef06bbd8} },
+/**/ {{0x3fc84906, 0xdf7d76ad} },
+/**/ {{0x4015152e, 0xdd2b30a6} },
+/**/ {{0xbbbfa2da, 0x084c3eef} },},
+/**/ {{{0x3fc88000, 0x021c6334} },
+/**/ {{0x3fc8cdbb, 0xd965f986} },
+/**/ {{0x4014a462, 0x51b74296} },
+/**/ {{0xbb9ec02e, 0x74dcfe0b} },},
+/**/ {{{0x3fc8ffff, 0xf38d0756} },
+/**/ {{0x3fc952a4, 0x28e173c7} },
+/**/ {{0x4014380b, 0x17b59ebd} },
+/**/ {{0xbbcd0f1c, 0xb77589f0} },},
+/**/ {{{0x3fc98000, 0x104efca1} },
+/**/ {{0x3fc9d7c1, 0x4644d23c} },
+/**/ {{0x4013cfe5, 0xcb1eabd5} },
+/**/ {{0xbbd5d6f7, 0xea188d9e} },},
+/**/ {{{0x3fca0000, 0x09417b30} },
+/**/ {{0x3fca5d14, 0x096d76aa} },
+/**/ {{0x40136bb4, 0xb3723db0} },
+/**/ {{0x3bbe3e0d, 0xfbf3979c} },},
+/**/ {{{0x3fca7fff, 0xeb1c23ec} },
+/**/ {{0x3fcae29d, 0xab60288d} },
+/**/ {{0x40130b3e, 0x783071d7} },
+/**/ {{0xbbc7dd82, 0x3d5384bf} },},
+/**/ {{{0x3fcaffff, 0xfb171c13} },
+/**/ {{0x3fcb685f, 0xa221a96b} },
+/**/ {{0x4012ae4d, 0xd8c0747d} },
+/**/ {{0x3bd4644b, 0xd5554972} },},
+/**/ {{{0x3fcb8000, 0x0aba44be} },
+/**/ {{0x3fcbee5a, 0xecdf241f} },
+/**/ {{0x401254b1, 0xc6fad63b} },
+/**/ {{0x3ba41916, 0xd092b85a} },},
+/**/ {{{0x3fcc0000, 0x113d2a3e} },
+/**/ {{0x3fcc7490, 0xb3e92543} },
+/**/ {{0x4011fe3c, 0x9a62c035} },
+/**/ {{0xbba3cc39, 0x41a03739} },},
+/**/ {{{0x3fcc7fff, 0xf49e00ce} },
+/**/ {{0x3fccfb02, 0x0f59eab0} },
+/**/ {{0x4011aac3, 0xe956a631} },
+/**/ {{0xbbb7a383, 0xbfa8cb5b} },},
+/**/ {{{0x3fcd0000, 0x05f611ab} },
+/**/ {{0x3fcd81b0, 0x89e6844e} },
+/**/ {{0x40115a1f, 0xf391268d} },
+/**/ {{0x3bd39b5c, 0xb2dc91f3} },},
+/**/ {{{0x3fcd8000, 0x14764ceb} },
+/**/ {{0x3fce089d, 0x27debf0d} },
+/**/ {{0x40110c2b, 0xfbc84740} },
+/**/ {{0x3bc14d4d, 0x84712510} },},
+/**/ {{{0x3fce0000, 0x14bcea76} },
+/**/ {{0x3fce8fc9, 0x16dbc820} },
+/**/ {{0x4010c0c5, 0xa00ca48e} },
+/**/ {{0xbbd33788, 0x640f1b9e} },},
+/**/ {{{0x3fce7fff, 0xfd7995bd} },
+/**/ {{0x3fcf1735, 0x88b50424} },
+/**/ {{0x401077cc, 0xbe02169a} },
+/**/ {{0xbbb61fee, 0x221fdf77} },},
+/**/ {{{0x3fcf0000, 0x0cc35436} },
+/**/ {{0x3fcf9ee3, 0xfd21a40b} },
+/**/ {{0x40103123, 0x1ee7ffe8} },
+/**/ {{0x3bd427e3, 0xc79ff5c1} },},
+/**/ {{{0x3fcf8000, 0x01d1da33} },
+/**/ {{0x3fd0136a, 0xb7dbe15c} },
+/**/ {{0x400fd959, 0x77d559e5} },
+/**/ {{0x3bb0c6a1, 0xd67948d7} },},
+/**/ {{{0x3fd00000, 0x060c13b2} },
+/**/ {{0x3fd05785, 0xaaad4f18} },
+/**/ {{0x400f549e, 0x2675d182} },
+/**/ {{0xbbc15208, 0x18f0dd10} },},
+/**/ {{{0x3fd04000, 0x03885492} },
+/**/ {{0x3fd09bc3, 0x660542d7} },
+/**/ {{0x400ed3e2, 0xdf3f5fec} },
+/**/ {{0xbbd95657, 0xb883ae62} },},
+/**/ {{{0x3fd08000, 0x052f5a13} },
+/**/ {{0x3fd0e024, 0x9a195045} },
+/**/ {{0x400e56f8, 0xfa68f2c8} },
+/**/ {{0x3bded7ba, 0x5a543e8e} },},
+/**/ {{{0x3fd0c000, 0x02ba1af5} },
+/**/ {{0x3fd124a9, 0xe2e7f24b} },
+/**/ {{0x400dddb4, 0xbffe633f} },
+/**/ {{0xbbdcba86, 0x0c60278f} },},
+/**/ {{{0x3fd0ffff, 0xf76642c1} },
+/**/ {{0x3fd16953, 0xe162ffe6} },
+/**/ {{0x400d67ed, 0x0311d5d5} },
+/**/ {{0x3b7b1f4a, 0xe40c5f9e} },},
+/**/ {{{0x3fd14000, 0x033602f0} },
+/**/ {{0x3fd1ae23, 0x5f49508e} },
+/**/ {{0x400cf57a, 0xb8708266} },
+/**/ {{0xbbd6a6c2, 0x8620f301} },},
+/**/ {{{0x3fd17fff, 0xfefd1a13} },
+/**/ {{0x3fd1f318, 0xdb2a9ba1} },
+/**/ {{0x400c8639, 0x8d11009e} },
+/**/ {{0x3bd3a9c6, 0x69b21d3b} },},
+/**/ {{{0x3fd1bfff, 0xf718365d} },
+/**/ {{0x3fd23835, 0x0c41e3ac} },
+/**/ {{0x400c1a06, 0xe02be47c} },
+/**/ {{0x3bdb961a, 0x129e8cd1} },},
+/**/ {{{0x3fd1ffff, 0xff001e00} },
+/**/ {{0x3fd27d78, 0xb2f6395e} },
+/**/ {{0x400bb0c1, 0xf2fe9a85} },
+/**/ {{0x3be074a9, 0xe68fd7d8} },},
+/**/ {{{0x3fd23fff, 0xfe425a6a} },
+/**/ {{0x3fd2c2e4, 0x618faabe} },
+/**/ {{0x400b4a4c, 0x190b18df} },
+/**/ {{0xbbdf0d1f, 0xf615aad1} },},
+/**/ {{{0x3fd28000, 0x059ec1db} },
+/**/ {{0x3fd30878, 0xd8583884} },
+/**/ {{0x400ae688, 0x0cd82bc2} },
+/**/ {{0xbbd563c3, 0x141c1f8d} },},
+/**/ {{{0x3fd2c000, 0x000dd081} },
+/**/ {{0x3fd34e36, 0xaffdb6d8} },
+/**/ {{0x400a855a, 0x5270fc15} },
+/**/ {{0xbbc6d88d, 0x9f2cdafd} },},
+/**/ {{{0x3fd2ffff, 0xfc1dcd2b} },
+/**/ {{0x3fd3941e, 0xa95875bc} },
+/**/ {{0x400a26a8, 0xaa9502b6} },
+/**/ {{0xbbe13cad, 0x8389b15c} },},
+/**/ {{{0x3fd33fff, 0xf6c0d4a0} },
+/**/ {{0x3fd3da31, 0x739845f5} },
+/**/ {{0x4009ca5a, 0x4d2573a0} },
+/**/ {{0xbbc71636, 0xacaee379} },},
+/**/ {{{0x3fd38000, 0x06b16793} },
+/**/ {{0x3fd4206f, 0xdbc088f0} },
+/**/ {{0x40097057, 0x9344e33a} },
+/**/ {{0xbbc2c052, 0x1d7a4f81} },},
+/**/ {{{0x3fd3c000, 0x07358fa3} },
+/**/ {{0x3fd466da, 0x6f23311d} },
+/**/ {{0x4009188a, 0x5aa612ea} },
+/**/ {{0x3b8653a5, 0x685e8edc} },},
+/**/ {{{0x3fd3ffff, 0xfc3b18cf} },
+/**/ {{0x3fd4ad71, 0xe9282e6b} },
+/**/ {{0x4008c2dd, 0x641e643d} },
+/**/ {{0x3b95f0ef, 0x3f567c64} },},
+/**/ {{{0x3fd44000, 0x000dd2a8} },
+/**/ {{0x3fd4f437, 0x1fa3f2d1} },
+/**/ {{0x40086f3c, 0x6072f821} },
+/**/ {{0x3bb68efa, 0x95ff68b5} },},
+/**/ {{{0x3fd47fff, 0xfbb43713} },
+/**/ {{0x3fd53b2a, 0xb3ac333c} },
+/**/ {{0x40081d94, 0x3da56692} },
+/**/ {{0xbbbf4d7f, 0x2985fd3f} },},
+/**/ {{{0x3fd4bfff, 0xfb113bf4} },
+/**/ {{0x3fd5824d, 0x6e8ed9c2} },
+/**/ {{0x4007cdd2, 0xa8add00f} },
+/**/ {{0x3bcf478a, 0x1c9b3657} },},
+/**/ {{{0x3fd4ffff, 0xf7f087c9} },
+/**/ {{0x3fd5c9a0, 0x07446496} },
+/**/ {{0x40077fe6, 0x444588eb} },
+/**/ {{0xbbc177dc, 0xa4eabb0c} },},
+/**/ {{{0x3fd54000, 0x088b3814} },
+/**/ {{0x3fd61123, 0x564125f9} },
+/**/ {{0x400733be, 0x6281a765} },
+/**/ {{0xbbc2c52c, 0xf57051c4} },},
+/**/ {{{0x3fd57fff, 0xf7d55966} },
+/**/ {{0x3fd658d7, 0xe194a5d5} },
+/**/ {{0x4006e94b, 0x73b47d1f} },
+/**/ {{0x3bda2fcf, 0xf9996dc6} },},
+/**/ {{{0x3fd5c000, 0x08bf2490} },
+/**/ {{0x3fd6a0be, 0xb775b28d} },
+/**/ {{0x4006a07e, 0x15b6ec28} },
+/**/ {{0xbbe0ca90, 0xaa5285b8} },},
+/**/ {{{0x3fd60000, 0x09fa853f} },
+/**/ {{0x3fd6e8d8, 0x65a66cfd} },
+/**/ {{0x40065948, 0x1c701269} },
+/**/ {{0x3bd9ea95, 0x8591e13a} },},
+/**/ {{{0x3fd64000, 0x07595fca} },
+/**/ {{0x3fd73125, 0xc0556a7c} },
+/**/ {{0x4006139b, 0xbaae9d02} },
+/**/ {{0x3bd88aff, 0x40152b83} },},
+/**/ {{{0x3fd68000, 0x031687da} },
+/**/ {{0x3fd779a7, 0x92e2cfd0} },
+/**/ {{0x4005cf6b, 0xcae0882b} },
+/**/ {{0xbbd8a4a2, 0x9f439451} },},
+/**/ {{{0x3fd6bfff, 0xf5c8cfe2} },
+/**/ {{0x3fd7c25e, 0x9fb452ed} },
+/**/ {{0x40058cab, 0xc561f1cd} },
+/**/ {{0xbbe371a6, 0xf6a37d74} },},
+/**/ {{{0x3fd6ffff, 0xf81df231} },
+/**/ {{0x3fd80b4b, 0xcfb4dab5} },
+/**/ {{0x40054b4f, 0x8d3ca5d3} },
+/**/ {{0x3bcb4686, 0x679dc99f} },},
+/**/ {{{0x3fd73fff, 0xfa71385e} },
+/**/ {{0x3fd8546f, 0xe007a9b6} },
+/**/ {{0x40050b4b, 0xb3b22176} },
+/**/ {{0xbbcd1540, 0xa5c73477} },},
+/**/ {{{0x3fd78000, 0x024a9c2b} },
+/**/ {{0x3fd89dcb, 0xa7fcf5cf} },
+/**/ {{0x4004cc95, 0x3159cbe1} },
+/**/ {{0xbbdc25ea, 0xd58a6ad0} },},
+/**/ {{{0x3fd7c000, 0x02eb62b8} },
+/**/ {{0x3fd8e75f, 0xec0ba5cf} },
+/**/ {{0x40048f21, 0x8731eeea} },
+/**/ {{0xbbc1cb73, 0xcc1adafb} },},
+/**/ {{{0x3fd80000, 0x054a52d1} },
+/**/ {{0x3fd9312d, 0x8bb822e9} },
+/**/ {{0x400452e6, 0x9170a729} },
+/**/ {{0xbbd8bb17, 0xeac002ee} },},
+/**/ {{{0x3fd83fff, 0xf93a00a3} },
+/**/ {{0x3fd97b35, 0x4bb9ad2a} },
+/**/ {{0x400417da, 0xae924e7f} },
+/**/ {{0x3bd4b800, 0x9a378cc7} },},
+/**/ {{{0x3fd87fff, 0xfbdc91c1} },
+/**/ {{0x3fd9c578, 0x2771b601} },
+/**/ {{0x4003ddf4, 0x78855799} },
+/**/ {{0x3bd9077d, 0xa00445d9} },},
+/**/ {{{0x3fd8bfff, 0xf6d215e6} },
+/**/ {{0x3fda0ff6, 0xe0ea4a0b} },
+/**/ {{0x4003a52b, 0x189a0989} },
+/**/ {{0xbbda6831, 0x89c0613d} },},
+/**/ {{{0x3fd90000, 0x02f734ef} },
+/**/ {{0x3fda5ab2, 0x736bf579} },
+/**/ {{0x40036d75, 0xe9244ca6} },
+/**/ {{0x3be3a6d8, 0x4b722377} },},
+/**/ {{{0x3fd94000, 0x04eef8b4} },
+/**/ {{0x3fdaa5ab, 0x9fb6e3d0} },
+/**/ {{0x400336cc, 0xc9089cb7} },
+/**/ {{0x3b9f6963, 0x22cc00bb} },},
+/**/ {{{0x3fd98000, 0x041ec76a} },
+/**/ {{0x3fdaf0e3, 0x5176c7e4} },
+/**/ {{0x40030127, 0xcb0b9506} },
+/**/ {{0x3bb1ffdb, 0x5385a849} },},
+/**/ {{{0x3fd9c000, 0x08044e47} },
+/**/ {{0x3fdb3c5a, 0x77071224} },
+/**/ {{0x4002cc7f, 0x50d75ec7} },
+/**/ {{0xbbb0fade, 0x78effc8a} },},
+/**/ {{{0x3fda0000, 0x01f8235b} },
+/**/ {{0x3fdb8811, 0xe725782e} },
+/**/ {{0x400298cc, 0x18fbfb37} },
+/**/ {{0xbbe55ed3, 0x3b50e71b} },},
+/**/ {{{0x3fda3fff, 0xfb8c6f08} },
+/**/ {{0x3fdbd40a, 0x97b086f3} },
+/**/ {{0x40026607, 0x154de04b} },
+/**/ {{0xbbdec65e, 0x455faae3} },},
+/**/ {{{0x3fda7fff, 0xfb3d63e1} },
+/**/ {{0x3fdc2045, 0x7d9a3b8a} },
+/**/ {{0x40023429, 0x7e60bfbb} },
+/**/ {{0x3be3001c, 0x154ebd33} },},
+/**/ {{{0x3fdabfff, 0xf5f45c48} },
+/**/ {{0x3fdc6cc3, 0x7b8d45e6} },
+/**/ {{0x4002032c, 0xdb1ace69} },
+/**/ {{0xbbe5ebf8, 0x3ed33616} },},
+/**/ {{{0x3fdb0000, 0x0508b34c} },
+/**/ {{0x3fdcb985, 0xa27e8d37} },
+/**/ {{0x4001d30a, 0xd4459a2b} },
+/**/ {{0xbbd01432, 0xae61e2d1} },},
+/**/ {{{0x3fdb4000, 0x0a84710c} },
+/**/ {{0x3fdd068c, 0xc3e50155} },
+/**/ {{0x4001a3bd, 0x775034dd} },
+/**/ {{0xbbe80b1e, 0x58e0e228} },},
+/**/ {{{0x3fdb7fff, 0xf692e9d8} },
+/**/ {{0x3fdd53d9, 0xc49d6627} },
+/**/ {{0x4001753e, 0xfe18066a} },
+/**/ {{0xbbb004c8, 0xf760d33e} },},
+/**/ {{{0x3fdbc000, 0x0280f14d} },
+/**/ {{0x3fdda16d, 0xe4e81013} },
+/**/ {{0x40014789, 0xa38ea052} },
+/**/ {{0x3be848bc, 0x27c9c4ea} },},
+/**/ {{{0x3fdc0000, 0x001121d1} },
+/**/ {{0x3fddef49, 0xeac018f0} },
+/**/ {{0x40011a98, 0x20b8be0c} },
+/**/ {{0xbbe1527e, 0xd0d6010e} },},
+/**/ {{{0x3fdc3fff, 0xfef662aa} },
+/**/ {{0x3fde3d6e, 0xea0c7070} },
+/**/ {{0x4000ee65, 0x32f46ccd} },
+/**/ {{0x3be8d241, 0x189a000d} },},
+/**/ {{{0x3fdc8000, 0x09845818} },
+/**/ {{0x3fde8bdd, 0xf36a8b1b} },
+/**/ {{0x4000c2eb, 0xcac73476} },
+/**/ {{0x3bd221f7, 0x12bed284} },},
+/**/ {{{0x3fdcbfff, 0xfb0493bf} },
+/**/ {{0x3fdeda97, 0xe0c60d10} },
+/**/ {{0x40009827, 0x251c7836} },
+/**/ {{0xbbe0bd54, 0x6eec41b7} },},
+/**/ {{{0x3fdcffff, 0xfd52961f} },
+/**/ {{0x3fdf299d, 0xefb3e44b} },
+/**/ {{0x40006e12, 0x74e459f5} },
+/**/ {{0xbbd93f77, 0xe969c82f} },},
+/**/ {{{0x3fdd3fff, 0xfe2319a4} },
+/**/ {{0x3fdf78f1, 0x17139490} },
+/**/ {{0x400044a9, 0x3e737e94} },
+/**/ {{0xbb91e7cc, 0x49594b7a} },},
+/**/ {{{0x3fdd7fff, 0xfa4de596} },
+/**/ {{0x3fdfc892, 0x638f49e8} },
+/**/ {{0x40001be7, 0x231057a5} },
+/**/ {{0x3bd482b0, 0xf5af9f5f} },},
+/**/ {{{0x3fddbfff, 0xfe729a69} },
+/**/ {{0x3fe00c41, 0x7c6ab019} },
+/**/ {{0x3fffe78f, 0xbf612660} },
+/**/ {{0x3bea5cda, 0x00da681e} },},
+/**/ {{{0x3fde0000, 0x09d66802} },
+/**/ {{0x3fe03461, 0xf6b883cf} },
+/**/ {{0x3fff988e, 0xbc05a87c} },
+/**/ {{0xbbe06c33, 0xf2372669} },},
+/**/ {{{0x3fde3fff, 0xfb211657} },
+/**/ {{0x3fe05cab, 0x191db8e8} },
+/**/ {{0x3fff4ac3, 0x7bcfe6be} },
+/**/ {{0xbbd5d51f, 0x5ed8d35b} },},
+/**/ {{{0x3fde8000, 0x0a3f068a} },
+/**/ {{0x3fe0851d, 0x95fb54f0} },
+/**/ {{0x3ffefe26, 0x144ca408} },
+/**/ {{0xbbc7c894, 0xa2c169c5} },},
+/**/ {{{0x3fdec000, 0x01adb060} },
+/**/ {{0x3fe0adb9, 0xdc7b54f9} },
+/**/ {{0x3ffeb2af, 0x5ebe52a7} },
+/**/ {{0x3bd4e740, 0x312c5ffd} },},
+/**/ {{{0x3fdeffff, 0xff5c0d01} },
+/**/ {{0x3fe0d680, 0x92550a8d} },
+/**/ {{0x3ffe6858, 0x0d71fdf0} },
+/**/ {{0x3bddd8a6, 0x96b35499} },},
+/**/ {{{0x3fdf3fff, 0xf93d5fcc} },
+/**/ {{0x3fe0ff72, 0x45cb4374} },
+/**/ {{0x3ffe1f19, 0x3cce5040} },
+/**/ {{0xbbc9f0ec, 0x7c1efab4} },},
+/**/ {{{0x3fdf7fff, 0xfa0dd18f} },
+/**/ {{0x3fe1288f, 0x944dd508} },
+/**/ {{0x3ffdd6ec, 0x298b874d} },
+/**/ {{0x3bea6ebd, 0x9642a0a6} },},
+/**/ {{{0x3fdfbfff, 0xfd3a9f1a} },
+/**/ {{0x3fe151d9, 0x13750f3e} },
+/**/ {{0x3ffd8fca, 0x5806a27e} },
+/**/ {{0x3bda2a03, 0xfc65ac7a} },},
+/**/ {{{0x3fdfffff, 0xfc481400} },
+/**/ {{0x3fe17b4f, 0x598944ca} },
+/**/ {{0x3ffd49ad, 0x82532170} },
+/**/ {{0x3bc4412e, 0x3d236dc3} },},
+/**/ {{{0x3fe01fff, 0xff53786c} },
+/**/ {{0x3fe1a4f3, 0x07d83d47} },
+/**/ {{0x3ffd048f, 0x851bffeb} },
+/**/ {{0x3bd1589d, 0x29f81b14} },},
+/**/ {{{0x3fe03fff, 0xfee301b7} },
+/**/ {{0x3fe1cec4, 0xb8a6a382} },
+/**/ {{0x3ffcc06a, 0x7c519db6} },
+/**/ {{0x3bd370e6, 0x5b24d6b2} },},
+/**/ {{{0x3fe06000, 0x006e36bf} },
+/**/ {{0x3fe1f8c5, 0x114eb8be} },
+/**/ {{0x3ffc7d38, 0xa34d6786} },
+/**/ {{0xbbea92de, 0x4b98c1d4} },},
+/**/ {{{0x3fe07fff, 0xfd60aa43} },
+/**/ {{0x3fe222f4, 0xabeccecb} },
+/**/ {{0x3ffc3af4, 0x77342ac4} },
+/**/ {{0xbbdd47f6, 0x03a5c2c2} },},
+/**/ {{{0x3fe0a000, 0x037762e8} },
+/**/ {{0x3fe24d54, 0x3f99efe8} },
+/**/ {{0x3ffbf998, 0x75f54fab} },
+/**/ {{0x3bedf7f4, 0x15771a46} },},
+/**/ {{{0x3fe0bfff, 0xff1c6921} },
+/**/ {{0x3fe277e4, 0x598e35d0} },
+/**/ {{0x3ffbb91f, 0x8addd186} },
+/**/ {{0x3be0f16c, 0x5e0e5a73} },},
+/**/ {{{0x3fe0dfff, 0xff07154b} },
+/**/ {{0x3fe2a2a5, 0xb6bc3986} },
+/**/ {{0x3ffb7984, 0x8301646d} },
+/**/ {{0xbbf02dd0, 0xbbaa5310} },},
+/**/ {{{0x3fe10000, 0x02fcdda4} },
+/**/ {{0x3fe2cd99, 0x02a59f1e} },
+/**/ {{0x3ffb3ac2, 0x705219bf} },
+/**/ {{0xbbe59357, 0x112fa616} },},
+/**/ {{{0x3fe12000, 0x01ce1140} },
+/**/ {{0x3fe2f8be, 0xdf0a67c2} },
+/**/ {{0x3ffafcd4, 0x9ab8ae2a} },
+/**/ {{0x3be2c542, 0x9303f346} },},
+/**/ {{{0x3fe14000, 0x04d0f355} },
+/**/ {{0x3fe32418, 0x08fcc7bf} },
+/**/ {{0x3ffabfb6, 0x497b9a36} },
+/**/ {{0x3bebc044, 0xb5a59234} },},
+/**/ {{{0x3fe16000, 0x00fb0c8a} },
+/**/ {{0x3fe34fa5, 0x2471618b} },
+/**/ {{0x3ffa8363, 0x0d26d117} },
+/**/ {{0xbbdbfbb2, 0x3f7bb7c9} },},
+/**/ {{{0x3fe18000, 0x026f10b3} },
+/**/ {{0x3fe37b66, 0xf7579056} },
+/**/ {{0x3ffa47d6, 0x6b4cf4b1} },
+/**/ {{0x3bf0f6b4, 0xaf0b5de9} },},
+/**/ {{{0x3fe19fff, 0xfd0978f8} },
+/**/ {{0x3fe3a75e, 0x290cc78c} },
+/**/ {{0x3ffa0d0c, 0x36c21315} },
+/**/ {{0x3beb2129, 0xa296b262} },},
+/**/ {{{0x3fe1bfff, 0xfd94840b} },
+/**/ {{0x3fe3d38b, 0x85b4e4a4} },
+/**/ {{0x3ff9d300, 0x32f2ecef} },
+/**/ {{0xbbdbab1a, 0xb9bb7d74} },},
+/**/ {{{0x3fe1dfff, 0xfbda1ea1} },
+/**/ {{0x3fe3ffef, 0xbf3cee2f} },
+/**/ {{0x3ff999ae, 0x6770fed8} },
+/**/ {{0x3bda0bdc, 0xb4ace9a4} },},
+/**/ {{{0x3fe1ffff, 0xfc989533} },
+/**/ {{0x3fe42c8b, 0x9c27900c} },
+/**/ {{0x3ff96112, 0xe0d9f1ac} },
+/**/ {{0xbbee19eb, 0x2fa2d81a} },},
+/**/ {{{0x3fe22000, 0x012b8d26} },
+/**/ {{0x3fe4595f, 0xe11975ca} },
+/**/ {{0x3ff92929, 0xcdaa4e80} },
+/**/ {{0x3bf23382, 0xacc82d4b} },},
+/**/ {{{0x3fe24000, 0x04f4d6af} },
+/**/ {{0x3fe4866d, 0x4d224131} },
+/**/ {{0x3ff8f1ef, 0x815c34e8} },
+/**/ {{0xbbd0c6ff, 0x3b740a99} },},
+/**/ {{{0x3fe25fff, 0xfcc07bda} },
+/**/ {{0x3fe4b3b4, 0x98b7d010} },
+/**/ {{0x3ff8bb60, 0x73e7ffa1} },
+/**/ {{0x3bebc31b, 0x1ad7a9c2} },},
+/**/ {{{0x3fe28000, 0x042d9639} },
+/**/ {{0x3fe4e136, 0xb64540d1} },
+/**/ {{0x3ff88578, 0xf4374938} },
+/**/ {{0x3be36de9, 0x1b85e901} },},
+/**/ {{{0x3fe2a000, 0x03be29a0} },
+/**/ {{0x3fe50ef4, 0x52bffd96} },
+/**/ {{0x3ff85035, 0xc0042c06} },
+/**/ {{0x3be15d01, 0x76f5efbd} },},
+/**/ {{{0x3fe2bfff, 0xfaa91f12} },
+/**/ {{0x3fe53cee, 0x3e2f4e0d} },
+/**/ {{0x3ff81b93, 0x8542df07} },
+/**/ {{0x3be555cd, 0x17662a2b} },},
+/**/ {{{0x3fe2dfff, 0xfe884891} },
+/**/ {{0x3fe56b25, 0x6c1a2470} },
+/**/ {{0x3ff7e78e, 0xe422ea70} },
+/**/ {{0x3bf03504, 0xbd030c11} },},
+/**/ {{{0x3fe2ffff, 0xfe87152b} },
+/**/ {{0x3fe5999a, 0x9beaaaa1} },
+/**/ {{0x3ff7b424, 0xd18fe9b3} },
+/**/ {{0xbb649a5f, 0x773e0e64} },},
+/**/ {{{0x3fe31fff, 0xffc1a721} },
+/**/ {{0x3fe5c84e, 0xafe0e564} },
+/**/ {{0x3ff78152, 0x338db8d4} },
+/**/ {{0x3beaf428, 0x5da8e935} },},
+/**/ {{{0x3fe33fff, 0xff70a372} },
+/**/ {{0x3fe5f742, 0x82191d64} },
+/**/ {{0x3ff74f14, 0x1122bcae} },
+/**/ {{0x3bdb1c4b, 0xdee4bfaf} },},
+/**/ {{{0x3fe36000, 0x0436e836} },
+/**/ {{0x3fe62676, 0xfde6ccff} },
+/**/ {{0x3ff71d67, 0x7644252c} },
+/**/ {{0xbbec3d10, 0xe08c3afb} },},
+/**/ {{{0x3fe37fff, 0xfcbe9641} },
+/**/ {{0x3fe655ec, 0xee9ffdaf} },
+/**/ {{0x3ff6ec49, 0xa6fc0515} },
+/**/ {{0x3bdda453, 0x2ed29567} },},
+/**/ {{{0x3fe39fff, 0xffb6d6ca} },
+/**/ {{0x3fe685a5, 0x5e67a1e1} },
+/**/ {{0x3ff6bbb7, 0xbc2ae969} },
+/**/ {{0x3becbf7b, 0x2ef43882} },},
+/**/ {{{0x3fe3c000, 0x04934fec} },
+/**/ {{0x3fe6b5a1, 0x2cc07d75} },
+/**/ {{0x3ff68baf, 0x10b02ef8} },
+/**/ {{0xbbe7c8fb, 0xfeb7cabd} },},
+/**/ {{{0x3fe3e000, 0x03f5cf7f} },
+/**/ {{0x3fe6e5e1, 0x3e59def6} },
+/**/ {{0x3ff65c2d, 0x0e61500f} },
+/**/ {{0xbbe30ba4, 0x035f7845} },},
+/**/ {{{0x3fe40000, 0x05280ad9} },
+/**/ {{0x3fe71666, 0x91ab4c3e} },
+/**/ {{0x3ff62d2f, 0x19f01c90} },
+/**/ {{0xbbf1e9f5, 0xffe95f6a} },},
+/**/ {{{0x3fe42000, 0x049efb65} },
+/**/ {{0x3fe74732, 0x18af3b9d} },
+/**/ {{0x3ff5feb2, 0xb86465e4} },
+/**/ {{0x3bc4cad7, 0x280d591e} },},
+/**/ {{{0x3fe44000, 0x0035ccb6} },
+/**/ {{0x3fe77844, 0xcb4ff1e5} },
+/**/ {{0x3ff5d0b5, 0x7c455428} },
+/**/ {{0x3bed8c18, 0x7ba5617c} },},
+/**/ {{{0x3fe46000, 0x03346717} },
+/**/ {{0x3fe7a99f, 0xba258778} },
+/**/ {{0x3ff5a334, 0xf4392254} },
+/**/ {{0xbbefd14a, 0xfc84a570} },},
+/**/ {{{0x3fe48000, 0x03002575} },
+/**/ {{0x3fe7db43, 0xd836768f} },
+/**/ {{0x3ff5762e, 0xdcf97e0c} },
+/**/ {{0xbbdd7eba, 0x5f5df49e} },},
+/**/ {{{0x3fe4a000, 0x055bf381} },
+/**/ {{0x3fe80d32, 0x35edeefa} },
+/**/ {{0x3ff549a0, 0xea46e31f} },
+/**/ {{0xbbdba522, 0x76823eac} },},
+/**/ {{{0x3fe4c000, 0x04ce10e3} },
+/**/ {{0x3fe83f6b, 0xd67dc1a8} },
+/**/ {{0x3ff51d88, 0xed82bcc4} },
+/**/ {{0xbbeae92d, 0x077d29ea} },},
+/**/ {{{0x3fe4e000, 0x016c60e1} },
+/**/ {{0x3fe871f1, 0xca0aaf31} },
+/**/ {{0x3ff4f1e4, 0xbdacbf16} },
+/**/ {{0x3be82958, 0x46ee425e} },},
+/**/ {{{0x3fe4ffff, 0xff966f0a} },
+/**/ {{0x3fe8a4c5, 0x2bff2dae} },
+/**/ {{0x3ff4c6b2, 0x3917657e} },
+/**/ {{0xbbf127c2, 0x5c86c705} },},
+/**/ {{{0x3fe52000, 0x0076e6eb} },
+/**/ {{0x3fe8d7e7, 0x175651e8} },
+/**/ {{0x3ff49bef, 0x4f459b05} },
+/**/ {{0xbbb1e9d1, 0x4181bbfc} },},
+/**/ {{{0x3fe54000, 0x03d12d3b} },
+/**/ {{0x3fe90b58, 0xa976ed56} },
+/**/ {{0x3ff47199, 0xfdf24af4} },
+/**/ {{0x3be38c17, 0xc30decaf} },},
+/**/ {{{0x3fe55fff, 0xfce7fa8d} },
+/**/ {{0x3fe93f1a, 0xf03a3a09} },
+/**/ {{0x3ff447b0, 0x5f13234b} },
+/**/ {{0x3bf1b8b2, 0x70df7e20} },},
+/**/ {{{0x3fe58000, 0x0331b46a} },
+/**/ {{0x3fe9732f, 0x38e83134} },
+/**/ {{0x3ff41e30, 0x68d8b41b} },
+/**/ {{0xbbee24d8, 0xb90bc28b} },},
+/**/ {{{0x3fe59fff, 0xfc14848e} },
+/**/ {{0x3fe9a796, 0x8471b489} },
+/**/ {{0x3ff3f518, 0x5de3aa73} },
+/**/ {{0xbbecacd9, 0xe0761536} },},
+/**/ {{{0x3fe5bfff, 0xfb7cd395} },
+/**/ {{0x3fe9dc52, 0x24a8b955} },
+/**/ {{0x3ff3cc66, 0x4f8fff15} },
+/**/ {{0xbbf67c97, 0x82045611} },},
+/**/ {{{0x3fe5e000, 0x000dcc40} },
+/**/ {{0x3fea1163, 0x4df5b93e} },
+/**/ {{0x3ff3a418, 0x75853228} },
+/**/ {{0xbbf585da, 0xd481f350} },},
+/**/ {{{0x3fe60000, 0x02efd2fc} },
+/**/ {{0x3fea46cb, 0x30d16323} },
+/**/ {{0x3ff37c2d, 0x187962ae} },
+/**/ {{0x3bf004c3, 0xa5f77bb0} },},
+/**/ {{{0x3fe61fff, 0xfeb8088a} },
+/**/ {{0x3fea7c8b, 0x053920c0} },
+/**/ {{0x3ff354a2, 0x891769a9} },
+/**/ {{0x3bbc6b30, 0x3fee3029} },},
+/**/ {{{0x3fe64000, 0x00f3ca06} },
+/**/ {{0x3feab2a4, 0x28a1911a} },
+/**/ {{0x3ff32d77, 0x0a6f0a4a} },
+/**/ {{0x3bf2a6f8, 0xfac5081a} },},
+/**/ {{{0x3fe65fff, 0xfe9ec2f4} },
+/**/ {{0x3feae917, 0xd4ce7239} },
+/**/ {{0x3ff306a9, 0x0751a948} },
+/**/ {{0xbbe950b5, 0x51ab9dbd} },},
+/**/ {{{0x3fe68000, 0x03d43966} },
+/**/ {{0x3feb1fe7, 0x708b998a} },
+/**/ {{0x3ff2e036, 0xd7a153c7} },
+/**/ {{0x3bdd36e2, 0xa1e4a14e} },},
+/**/ {{{0x3fe69fff, 0xfab67783} },
+/**/ {{0x3feb5714, 0x2e575464} },
+/**/ {{0x3ff2ba1f, 0x05006cb6} },
+/**/ {{0x3bea9a4a, 0x473c2e31} },},
+/**/ {{{0x3fe6bfff, 0xfcb65f89} },
+/**/ {{0x3feb8e9f, 0x981efd2f} },
+/**/ {{0x3ff2945f, 0xe948d9f7} },
+/**/ {{0xbbca5294, 0xe802df72} },},
+/**/ {{{0x3fe6dfff, 0xfc5609a9} },
+/**/ {{0x3febc68a, 0xfaed6ff1} },
+/**/ {{0x3ff26ef8, 0x1533411e} },
+/**/ {{0xbbf89153, 0xf51bc566} },},
+/**/ {{{0x3fe6ffff, 0xfc4eef86} },
+/**/ {{0x3febfed7, 0xc62205fe} },
+/**/ {{0x3ff249e6, 0x0e70978c} },
+/**/ {{0x3bc39021, 0xa2b9ff56} },},
+/**/ {{{0x3fe72000, 0x004d98b3} },
+/**/ {{0x3fec3787, 0x716968ad} },
+/**/ {{0x3ff22528, 0x61be7751} },
+/**/ {{0x3befc9c5, 0x74ee2211} },},
+/**/ {{{0x3fe73fff, 0xfc155075} },
+/**/ {{0x3fec709b, 0x5ec6fd4e} },
+/**/ {{0x3ff200bd, 0xb5d53311} },
+/**/ {{0x3be28a4d, 0xa269ae63} },},
+/**/ {{{0x3fe76000, 0x0498c203} },
+/**/ {{0x3fecaa15, 0x323d08c1} },
+/**/ {{0x3ff1dca4, 0x93433f65} },
+/**/ {{0x3bf8cae4, 0x14a28fb7} },},
+/**/ {{{0x3fe77fff, 0xff1e5636} },
+/**/ {{0x3fece3f6, 0x4147c12c} },
+/**/ {{0x3ff1b8db, 0xbfe294a8} },
+/**/ {{0xbbe7e19c, 0x4b56a744} },},
+/**/ {{{0x3fe7a000, 0x0226d45a} },
+/**/ {{0x3fed1e40, 0x4120eb7f} },
+/**/ {{0x3ff19561, 0xd15f8278} },
+/**/ {{0x3be64b28, 0x032c5d4c} },},
+/**/ {{{0x3fe7c000, 0x0250a5aa} },
+/**/ {{0x3fed58f4, 0xb112a1e1} },
+/**/ {{0x3ff17235, 0x8a59d565} },
+/**/ {{0xbbe716de, 0xb8dc7867} },},
+/**/ {{{0x3fe7e000, 0x0482f82e} },
+/**/ {{0x3fed9415, 0x3576bdf0} },
+/**/ {{0x3ff14f55, 0xa22a1c5b} },
+/**/ {{0x3bf207e1, 0xe1305604} },},
+/**/ {{{0x3fe80000, 0x0205003e} },
+/**/ {{0x3fedcfa3, 0x64d69ff7} },
+/**/ {{0x3ff12cc0, 0xe37eb26f} },
+/**/ {{0xbbd52ec6, 0xe32395f8} },},
+/**/ {{{0x3fe81fff, 0xfbf99411} },
+/**/ {{0x3fee0ba0, 0xebf98f51} },
+/**/ {{0x3ff10a76, 0x16ddd5d6} },
+/**/ {{0xbbece0d6, 0x59866045} },},
+/**/ {{{0x3fe84000, 0x0248e3a3} },
+/**/ {{0x3fee480f, 0x9bb7f565} },
+/**/ {{0x3ff0e873, 0xfb84e05c} },
+/**/ {{0x3bf4e5e8, 0x1595df92} },},
+/**/ {{{0x3fe86000, 0x0145c157} },
+/**/ {{0x3fee84f1, 0x0a10b3ab} },
+/**/ {{0x3ff0c6b9, 0x7cbd7b1e} },
+/**/ {{0xbbe19de6, 0xd5f121d0} },},
+/**/ {{{0x3fe88000, 0x022631b9} },
+/**/ {{0x3feec247, 0x0be1f047} },
+/**/ {{0x3ff0a545, 0x6d0b3ee6} },
+/**/ {{0xbbc272b1, 0xa3ba2c6f} },},
+/**/ {{{0x3fe8a000, 0x045f7828} },
+/**/ {{0x3fef0013, 0x6c45ba1c} },
+/**/ {{0x3ff08416, 0xaf2a0f09} },
+/**/ {{0x3be82b56, 0x5b63c799} },},
+/**/ {{{0x3fe8bfff, 0xffc686cf} },
+/**/ {{0x3fef3e57, 0xf03c824b} },
+/**/ {{0x3ff0632c, 0x33502220} },
+/**/ {{0xbbd039ad, 0x2dbeeb25} },},
+/**/ {{{0x3fe8dfff, 0xfd8644c6} },
+/**/ {{0x3fef7d16, 0x8774261d} },
+/**/ {{0x3ff04284, 0xdd5b3019} },
+/**/ {{0x3bd79f33, 0xe1eba933} },},
+/**/ {{{0x3fe8ffff, 0xfe4e7937} },
+/**/ {{0x3fefbc51, 0x1a99a641} },
+/**/ {{0x3ff0221f, 0x9f69840b} },
+/**/ {{0xbbea9e84, 0x7beee018} },},
+/**/ {{{0x3fe92000, 0x0435251f} },
+/**/ {{0x3feffc09, 0x9eb22390} },
+/**/ {{0x3ff001fb, 0x6f7c51e8} },
+/**/ {{0xbb5a12e7, 0x31032e0a} },},
+ };
+
+#else
+#ifdef LITTLE_ENDI
+static const number
+ xfg[186][4] = { /* xi,Fi,Gi,FFi, i=16..201 */
+/**/ {{{0x1e519d60, 0x3fb00000} },
+/**/ {{0x96c4e240, 0x3fb00557} },
+/**/ {{0x628127b7, 0x402ff554} },
+/**/ {{0x9e355b06, 0xbb9a1dee} },},
+/**/ {{{0x1b1a7010, 0x3fb10000} },
+/**/ {{0xaab892b7, 0x3fb10668} },
+/**/ {{0xbe3fdf74, 0x402e12c7} },
+/**/ {{0x037da741, 0x3ba89234} },},
+/**/ {{{0x2505e350, 0x3fb20000} },
+/**/ {{0xff547824, 0x3fb2079b} },
+/**/ {{0xde853633, 0x402c65c5} },
+/**/ {{0xe9614250, 0x3bb7486e} },},
+/**/ {{{0xfcdc4252, 0x3fb2ffff} },
+/**/ {{0x5eb16c68, 0x3fb308f3} },
+/**/ {{0xe56be74f, 0x402ae5da} },
+/**/ {{0x91a23034, 0xbb82c726} },},
+/**/ {{{0xe3ff849f, 0x3fb3ffff} },
+/**/ {{0x154999cc, 0x3fb40a71} },
+/**/ {{0x046b7352, 0x40298c43} },
+/**/ {{0x3843738f, 0x3b9aceaf} },},
+/**/ {{{0xedc9590f, 0x3fb4ffff} },
+/**/ {{0x429bdd80, 0x3fb50c17} },
+/**/ {{0x91b5d674, 0x40285384} },
+/**/ {{0xb4403d22, 0xbbc1d02d} },},
+/**/ {{{0x00ee83f7, 0x3fb60000} },
+/**/ {{0xda80cc21, 0x3fb60de7} },
+/**/ {{0xef21a2a7, 0x40273724} },
+/**/ {{0x72523ffd, 0xbb95e53c} },},
+/**/ {{{0xeb05ea41, 0x3fb6ffff} },
+/**/ {{0xb8c51bea, 0x3fb70fe4} },
+/**/ {{0xfae562ff, 0x40263370} },
+/**/ {{0x8ffe0626, 0xbb99ad0e} },},
+/**/ {{{0xdc0515f7, 0x3fb7ffff} },
+/**/ {{0x1db54498, 0x3fb81210} },
+/**/ {{0x0e7eab5c, 0x40254553} },
+/**/ {{0xd62ed686, 0xbb914c87} },},
+/**/ {{{0xe384d7ab, 0x3fb8ffff} },
+/**/ {{0x2a8d3727, 0x3fb9146c} },
+/**/ {{0xfd57f3fd, 0x40246a33} },
+/**/ {{0x5381e06d, 0xbbbbda8d} },},
+/**/ {{{0xe4832347, 0x3fb9ffff} },
+/**/ {{0xd50e1050, 0x3fba16fa} },
+/**/ {{0xc5537a96, 0x40239fe2} },
+/**/ {{0xc111eabb, 0x3bc7f695} },},
+/**/ {{{0x274540e3, 0x3fbb0000} },
+/**/ {{0x7ae68517, 0x3fbb19be} },
+/**/ {{0x3637e946, 0x4022e481} },
+/**/ {{0x8dbd9d93, 0x3bc307f8} },},
+/**/ {{{0xfebf2e9b, 0x3fbbffff} },
+/**/ {{0x8369cd19, 0x3fbc1cb8} },
+/**/ {{0x17aef223, 0x40223676} },
+/**/ {{0x424a9cf3, 0x3bc50038} },},
+/**/ {{{0x23529045, 0x3fbd0000} },
+/**/ {{0xc11d7ef7, 0x3fbd1feb} },
+/**/ {{0xb8e43d4e, 0x4021945f} },
+/**/ {{0x52a6f224, 0x3b812007} },},
+/**/ {{{0xd872a829, 0x3fbdffff} },
+/**/ {{0x8ee4d6b7, 0x3fbe2359} },
+/**/ {{0x76195d5f, 0x4020fd0c} },
+/**/ {{0x85fdca85, 0xbbb4d9ab} },},
+/**/ {{{0xff323b84, 0x3fbeffff} },
+/**/ {{0xec9073e5, 0x3fbf2704} },
+/**/ {{0x3020200f, 0x40206f71} },
+/**/ {{0x12836992, 0x3bb77aa2} },},
+/**/ {{{0x0ce79195, 0x3fc00000} },
+/**/ {{0xbc30cc61, 0x3fc01577} },
+/**/ {{0xd6564a88, 0x401fd549} },
+/**/ {{0x965c0ad0, 0xbbc8926f} },},
+/**/ {{{0xee40e918, 0x3fc07fff} },
+/**/ {{0x8279ac01, 0x3fc0978d} },
+/**/ {{0x9294bc03, 0x401edbb5} },
+/**/ {{0x4aae45d6, 0xbb80a533} },},
+/**/ {{{0x0cc091fd, 0x3fc10000} },
+/**/ {{0x44dfb2f7, 0x3fc119c5} },
+/**/ {{0x067d8e18, 0x401df0bb} },
+/**/ {{0x4ff642a4, 0xbbcc2c18} },},
+/**/ {{{0x0d9936a1, 0x3fc18000} },
+/**/ {{0xb9085a4b, 0x3fc19c1f} },
+/**/ {{0x71ce3629, 0x401d131a} },
+/**/ {{0x0669355b, 0xbbc36553} },},
+/**/ {{{0xed5f3188, 0x3fc1ffff} },
+/**/ {{0xee74bf2d, 0x3fc21e9d} },
+/**/ {{0xff0cd655, 0x401c41b6} },
+/**/ {{0x478ecfc5, 0x3b8867f5} },},
+/**/ {{{0x05f06a51, 0x3fc28000} },
+/**/ {{0x550b313f, 0x3fc2a141} },
+/**/ {{0x1702e6d2, 0x401b7b92} },
+/**/ {{0x380131fe, 0xbbadab51} },},
+/**/ {{{0xfe3d339e, 0x3fc2ffff} },
+/**/ {{0xa75f76df, 0x3fc3240a} },
+/**/ {{0xfcb6409d, 0x401abfc8} },
+/**/ {{0x0d291d83, 0x3bc60bcf} },},
+/**/ {{{0xed888d6f, 0x3fc37fff} },
+/**/ {{0x13cc5db7, 0x3fc3a6fb} },
+/**/ {{0x8ed5320d, 0x401a0d8f} },
+/**/ {{0x4eef03ab, 0x3bb8a48e} },},
+/**/ {{{0x02ca050d, 0x3fc40000} },
+/**/ {{0xe25776bb, 0x3fc42a13} },
+/**/ {{0xfa84c2bc, 0x4019642d} },
+/**/ {{0xcc56516f, 0xbbd0bd5d} },},
+/**/ {{{0xf2531f5c, 0x3fc47fff} },
+/**/ {{0xdeb73404, 0x3fc4ad55} },
+/**/ {{0xf86e9035, 0x4018c2fe} },
+/**/ {{0x5aa287c8, 0x3b9cffe7} },},
+/**/ {{{0x13774992, 0x3fc50000} },
+/**/ {{0x7d0ee307, 0x3fc530c2} },
+/**/ {{0x370caf35, 0x4018296c} },
+/**/ {{0xf91d6532, 0xbbcf75d1} },},
+/**/ {{{0xedddcb2d, 0x3fc57fff} },
+/**/ {{0x5db4347d, 0x3fc5b45a} },
+/**/ {{0x52190c0e, 0x401796ee} },
+/**/ {{0x17d5d076, 0x3b88a25f} },},
+/**/ {{{0xf41949a0, 0x3fc5ffff} },
+/**/ {{0x13bf986a, 0x3fc6381f} },
+/**/ {{0x2d2255fd, 0x40170b09} },
+/**/ {{0xb1bcd5e7, 0xbb9bfb23} },},
+/**/ {{{0xf834d3a1, 0x3fc67fff} },
+/**/ {{0x8ec85952, 0x3fc6bc11} },
+/**/ {{0x62cf2268, 0x4016854c} },
+/**/ {{0x82e39e04, 0x3b9ee53b} },},
+/**/ {{{0xfd9106ea, 0x3fc6ffff} },
+/**/ {{0xf298f6f7, 0x3fc74032} },
+/**/ {{0x1f4f84a9, 0x40160551} },
+/**/ {{0x112634b8, 0xbbb59c4a} },},
+/**/ {{{0x0f649a4f, 0x3fc78000} },
+/**/ {{0x6ca53abc, 0x3fc7c484} },
+/**/ {{0x4809d175, 0x40158ab9} },
+/**/ {{0x73d3cd2e, 0x3bc91c75} },},
+/**/ {{{0xef06bbd8, 0x3fc7ffff} },
+/**/ {{0xdf7d76ad, 0x3fc84906} },
+/**/ {{0xdd2b30a6, 0x4015152e} },
+/**/ {{0x084c3eef, 0xbbbfa2da} },},
+/**/ {{{0x021c6334, 0x3fc88000} },
+/**/ {{0xd965f986, 0x3fc8cdbb} },
+/**/ {{0x51b74296, 0x4014a462} },
+/**/ {{0x74dcfe0b, 0xbb9ec02e} },},
+/**/ {{{0xf38d0756, 0x3fc8ffff} },
+/**/ {{0x28e173c7, 0x3fc952a4} },
+/**/ {{0x17b59ebd, 0x4014380b} },
+/**/ {{0xb77589f0, 0xbbcd0f1c} },},
+/**/ {{{0x104efca1, 0x3fc98000} },
+/**/ {{0x4644d23c, 0x3fc9d7c1} },
+/**/ {{0xcb1eabd5, 0x4013cfe5} },
+/**/ {{0xea188d9e, 0xbbd5d6f7} },},
+/**/ {{{0x09417b30, 0x3fca0000} },
+/**/ {{0x096d76aa, 0x3fca5d14} },
+/**/ {{0xb3723db0, 0x40136bb4} },
+/**/ {{0xfbf3979c, 0x3bbe3e0d} },},
+/**/ {{{0xeb1c23ec, 0x3fca7fff} },
+/**/ {{0xab60288d, 0x3fcae29d} },
+/**/ {{0x783071d7, 0x40130b3e} },
+/**/ {{0x3d5384bf, 0xbbc7dd82} },},
+/**/ {{{0xfb171c13, 0x3fcaffff} },
+/**/ {{0xa221a96b, 0x3fcb685f} },
+/**/ {{0xd8c0747d, 0x4012ae4d} },
+/**/ {{0xd5554972, 0x3bd4644b} },},
+/**/ {{{0x0aba44be, 0x3fcb8000} },
+/**/ {{0xecdf241f, 0x3fcbee5a} },
+/**/ {{0xc6fad63b, 0x401254b1} },
+/**/ {{0xd092b85a, 0x3ba41916} },},
+/**/ {{{0x113d2a3e, 0x3fcc0000} },
+/**/ {{0xb3e92543, 0x3fcc7490} },
+/**/ {{0x9a62c035, 0x4011fe3c} },
+/**/ {{0x41a03739, 0xbba3cc39} },},
+/**/ {{{0xf49e00ce, 0x3fcc7fff} },
+/**/ {{0x0f59eab0, 0x3fccfb02} },
+/**/ {{0xe956a631, 0x4011aac3} },
+/**/ {{0xbfa8cb5b, 0xbbb7a383} },},
+/**/ {{{0x05f611ab, 0x3fcd0000} },
+/**/ {{0x89e6844e, 0x3fcd81b0} },
+/**/ {{0xf391268d, 0x40115a1f} },
+/**/ {{0xb2dc91f3, 0x3bd39b5c} },},
+/**/ {{{0x14764ceb, 0x3fcd8000} },
+/**/ {{0x27debf0d, 0x3fce089d} },
+/**/ {{0xfbc84740, 0x40110c2b} },
+/**/ {{0x84712510, 0x3bc14d4d} },},
+/**/ {{{0x14bcea76, 0x3fce0000} },
+/**/ {{0x16dbc820, 0x3fce8fc9} },
+/**/ {{0xa00ca48e, 0x4010c0c5} },
+/**/ {{0x640f1b9e, 0xbbd33788} },},
+/**/ {{{0xfd7995bd, 0x3fce7fff} },
+/**/ {{0x88b50424, 0x3fcf1735} },
+/**/ {{0xbe02169a, 0x401077cc} },
+/**/ {{0x221fdf77, 0xbbb61fee} },},
+/**/ {{{0x0cc35436, 0x3fcf0000} },
+/**/ {{0xfd21a40b, 0x3fcf9ee3} },
+/**/ {{0x1ee7ffe8, 0x40103123} },
+/**/ {{0xc79ff5c1, 0x3bd427e3} },},
+/**/ {{{0x01d1da33, 0x3fcf8000} },
+/**/ {{0xb7dbe15c, 0x3fd0136a} },
+/**/ {{0x77d559e5, 0x400fd959} },
+/**/ {{0xd67948d7, 0x3bb0c6a1} },},
+/**/ {{{0x060c13b2, 0x3fd00000} },
+/**/ {{0xaaad4f18, 0x3fd05785} },
+/**/ {{0x2675d182, 0x400f549e} },
+/**/ {{0x18f0dd10, 0xbbc15208} },},
+/**/ {{{0x03885492, 0x3fd04000} },
+/**/ {{0x660542d7, 0x3fd09bc3} },
+/**/ {{0xdf3f5fec, 0x400ed3e2} },
+/**/ {{0xb883ae62, 0xbbd95657} },},
+/**/ {{{0x052f5a13, 0x3fd08000} },
+/**/ {{0x9a195045, 0x3fd0e024} },
+/**/ {{0xfa68f2c8, 0x400e56f8} },
+/**/ {{0x5a543e8e, 0x3bded7ba} },},
+/**/ {{{0x02ba1af5, 0x3fd0c000} },
+/**/ {{0xe2e7f24b, 0x3fd124a9} },
+/**/ {{0xbffe633f, 0x400dddb4} },
+/**/ {{0x0c60278f, 0xbbdcba86} },},
+/**/ {{{0xf76642c1, 0x3fd0ffff} },
+/**/ {{0xe162ffe6, 0x3fd16953} },
+/**/ {{0x0311d5d5, 0x400d67ed} },
+/**/ {{0xe40c5f9e, 0x3b7b1f4a} },},
+/**/ {{{0x033602f0, 0x3fd14000} },
+/**/ {{0x5f49508e, 0x3fd1ae23} },
+/**/ {{0xb8708266, 0x400cf57a} },
+/**/ {{0x8620f301, 0xbbd6a6c2} },},
+/**/ {{{0xfefd1a13, 0x3fd17fff} },
+/**/ {{0xdb2a9ba1, 0x3fd1f318} },
+/**/ {{0x8d11009e, 0x400c8639} },
+/**/ {{0x69b21d3b, 0x3bd3a9c6} },},
+/**/ {{{0xf718365d, 0x3fd1bfff} },
+/**/ {{0x0c41e3ac, 0x3fd23835} },
+/**/ {{0xe02be47c, 0x400c1a06} },
+/**/ {{0x129e8cd1, 0x3bdb961a} },},
+/**/ {{{0xff001e00, 0x3fd1ffff} },
+/**/ {{0xb2f6395e, 0x3fd27d78} },
+/**/ {{0xf2fe9a85, 0x400bb0c1} },
+/**/ {{0xe68fd7d8, 0x3be074a9} },},
+/**/ {{{0xfe425a6a, 0x3fd23fff} },
+/**/ {{0x618faabe, 0x3fd2c2e4} },
+/**/ {{0x190b18df, 0x400b4a4c} },
+/**/ {{0xf615aad1, 0xbbdf0d1f} },},
+/**/ {{{0x059ec1db, 0x3fd28000} },
+/**/ {{0xd8583884, 0x3fd30878} },
+/**/ {{0x0cd82bc2, 0x400ae688} },
+/**/ {{0x141c1f8d, 0xbbd563c3} },},
+/**/ {{{0x000dd081, 0x3fd2c000} },
+/**/ {{0xaffdb6d8, 0x3fd34e36} },
+/**/ {{0x5270fc15, 0x400a855a} },
+/**/ {{0x9f2cdafd, 0xbbc6d88d} },},
+/**/ {{{0xfc1dcd2b, 0x3fd2ffff} },
+/**/ {{0xa95875bc, 0x3fd3941e} },
+/**/ {{0xaa9502b6, 0x400a26a8} },
+/**/ {{0x8389b15c, 0xbbe13cad} },},
+/**/ {{{0xf6c0d4a0, 0x3fd33fff} },
+/**/ {{0x739845f5, 0x3fd3da31} },
+/**/ {{0x4d2573a0, 0x4009ca5a} },
+/**/ {{0xacaee379, 0xbbc71636} },},
+/**/ {{{0x06b16793, 0x3fd38000} },
+/**/ {{0xdbc088f0, 0x3fd4206f} },
+/**/ {{0x9344e33a, 0x40097057} },
+/**/ {{0x1d7a4f81, 0xbbc2c052} },},
+/**/ {{{0x07358fa3, 0x3fd3c000} },
+/**/ {{0x6f23311d, 0x3fd466da} },
+/**/ {{0x5aa612ea, 0x4009188a} },
+/**/ {{0x685e8edc, 0x3b8653a5} },},
+/**/ {{{0xfc3b18cf, 0x3fd3ffff} },
+/**/ {{0xe9282e6b, 0x3fd4ad71} },
+/**/ {{0x641e643d, 0x4008c2dd} },
+/**/ {{0x3f567c64, 0x3b95f0ef} },},
+/**/ {{{0x000dd2a8, 0x3fd44000} },
+/**/ {{0x1fa3f2d1, 0x3fd4f437} },
+/**/ {{0x6072f821, 0x40086f3c} },
+/**/ {{0x95ff68b5, 0x3bb68efa} },},
+/**/ {{{0xfbb43713, 0x3fd47fff} },
+/**/ {{0xb3ac333c, 0x3fd53b2a} },
+/**/ {{0x3da56692, 0x40081d94} },
+/**/ {{0x2985fd3f, 0xbbbf4d7f} },},
+/**/ {{{0xfb113bf4, 0x3fd4bfff} },
+/**/ {{0x6e8ed9c2, 0x3fd5824d} },
+/**/ {{0xa8add00f, 0x4007cdd2} },
+/**/ {{0x1c9b3657, 0x3bcf478a} },},
+/**/ {{{0xf7f087c9, 0x3fd4ffff} },
+/**/ {{0x07446496, 0x3fd5c9a0} },
+/**/ {{0x444588eb, 0x40077fe6} },
+/**/ {{0xa4eabb0c, 0xbbc177dc} },},
+/**/ {{{0x088b3814, 0x3fd54000} },
+/**/ {{0x564125f9, 0x3fd61123} },
+/**/ {{0x6281a765, 0x400733be} },
+/**/ {{0xf57051c4, 0xbbc2c52c} },},
+/**/ {{{0xf7d55966, 0x3fd57fff} },
+/**/ {{0xe194a5d5, 0x3fd658d7} },
+/**/ {{0x73b47d1f, 0x4006e94b} },
+/**/ {{0xf9996dc6, 0x3bda2fcf} },},
+/**/ {{{0x08bf2490, 0x3fd5c000} },
+/**/ {{0xb775b28d, 0x3fd6a0be} },
+/**/ {{0x15b6ec28, 0x4006a07e} },
+/**/ {{0xaa5285b8, 0xbbe0ca90} },},
+/**/ {{{0x09fa853f, 0x3fd60000} },
+/**/ {{0x65a66cfd, 0x3fd6e8d8} },
+/**/ {{0x1c701269, 0x40065948} },
+/**/ {{0x8591e13a, 0x3bd9ea95} },},
+/**/ {{{0x07595fca, 0x3fd64000} },
+/**/ {{0xc0556a7c, 0x3fd73125} },
+/**/ {{0xbaae9d02, 0x4006139b} },
+/**/ {{0x40152b83, 0x3bd88aff} },},
+/**/ {{{0x031687da, 0x3fd68000} },
+/**/ {{0x92e2cfd0, 0x3fd779a7} },
+/**/ {{0xcae0882b, 0x4005cf6b} },
+/**/ {{0x9f439451, 0xbbd8a4a2} },},
+/**/ {{{0xf5c8cfe2, 0x3fd6bfff} },
+/**/ {{0x9fb452ed, 0x3fd7c25e} },
+/**/ {{0xc561f1cd, 0x40058cab} },
+/**/ {{0xf6a37d74, 0xbbe371a6} },},
+/**/ {{{0xf81df231, 0x3fd6ffff} },
+/**/ {{0xcfb4dab5, 0x3fd80b4b} },
+/**/ {{0x8d3ca5d3, 0x40054b4f} },
+/**/ {{0x679dc99f, 0x3bcb4686} },},
+/**/ {{{0xfa71385e, 0x3fd73fff} },
+/**/ {{0xe007a9b6, 0x3fd8546f} },
+/**/ {{0xb3b22176, 0x40050b4b} },
+/**/ {{0xa5c73477, 0xbbcd1540} },},
+/**/ {{{0x024a9c2b, 0x3fd78000} },
+/**/ {{0xa7fcf5cf, 0x3fd89dcb} },
+/**/ {{0x3159cbe1, 0x4004cc95} },
+/**/ {{0xd58a6ad0, 0xbbdc25ea} },},
+/**/ {{{0x02eb62b8, 0x3fd7c000} },
+/**/ {{0xec0ba5cf, 0x3fd8e75f} },
+/**/ {{0x8731eeea, 0x40048f21} },
+/**/ {{0xcc1adafb, 0xbbc1cb73} },},
+/**/ {{{0x054a52d1, 0x3fd80000} },
+/**/ {{0x8bb822e9, 0x3fd9312d} },
+/**/ {{0x9170a729, 0x400452e6} },
+/**/ {{0xeac002ee, 0xbbd8bb17} },},
+/**/ {{{0xf93a00a3, 0x3fd83fff} },
+/**/ {{0x4bb9ad2a, 0x3fd97b35} },
+/**/ {{0xae924e7f, 0x400417da} },
+/**/ {{0x9a378cc7, 0x3bd4b800} },},
+/**/ {{{0xfbdc91c1, 0x3fd87fff} },
+/**/ {{0x2771b601, 0x3fd9c578} },
+/**/ {{0x78855799, 0x4003ddf4} },
+/**/ {{0xa00445d9, 0x3bd9077d} },},
+/**/ {{{0xf6d215e6, 0x3fd8bfff} },
+/**/ {{0xe0ea4a0b, 0x3fda0ff6} },
+/**/ {{0x189a0989, 0x4003a52b} },
+/**/ {{0x89c0613d, 0xbbda6831} },},
+/**/ {{{0x02f734ef, 0x3fd90000} },
+/**/ {{0x736bf579, 0x3fda5ab2} },
+/**/ {{0xe9244ca6, 0x40036d75} },
+/**/ {{0x4b722377, 0x3be3a6d8} },},
+/**/ {{{0x04eef8b4, 0x3fd94000} },
+/**/ {{0x9fb6e3d0, 0x3fdaa5ab} },
+/**/ {{0xc9089cb7, 0x400336cc} },
+/**/ {{0x22cc00bb, 0x3b9f6963} },},
+/**/ {{{0x041ec76a, 0x3fd98000} },
+/**/ {{0x5176c7e4, 0x3fdaf0e3} },
+/**/ {{0xcb0b9506, 0x40030127} },
+/**/ {{0x5385a849, 0x3bb1ffdb} },},
+/**/ {{{0x08044e47, 0x3fd9c000} },
+/**/ {{0x77071224, 0x3fdb3c5a} },
+/**/ {{0x50d75ec7, 0x4002cc7f} },
+/**/ {{0x78effc8a, 0xbbb0fade} },},
+/**/ {{{0x01f8235b, 0x3fda0000} },
+/**/ {{0xe725782e, 0x3fdb8811} },
+/**/ {{0x18fbfb37, 0x400298cc} },
+/**/ {{0x3b50e71b, 0xbbe55ed3} },},
+/**/ {{{0xfb8c6f08, 0x3fda3fff} },
+/**/ {{0x97b086f3, 0x3fdbd40a} },
+/**/ {{0x154de04b, 0x40026607} },
+/**/ {{0x455faae3, 0xbbdec65e} },},
+/**/ {{{0xfb3d63e1, 0x3fda7fff} },
+/**/ {{0x7d9a3b8a, 0x3fdc2045} },
+/**/ {{0x7e60bfbb, 0x40023429} },
+/**/ {{0x154ebd33, 0x3be3001c} },},
+/**/ {{{0xf5f45c48, 0x3fdabfff} },
+/**/ {{0x7b8d45e6, 0x3fdc6cc3} },
+/**/ {{0xdb1ace69, 0x4002032c} },
+/**/ {{0x3ed33616, 0xbbe5ebf8} },},
+/**/ {{{0x0508b34c, 0x3fdb0000} },
+/**/ {{0xa27e8d37, 0x3fdcb985} },
+/**/ {{0xd4459a2b, 0x4001d30a} },
+/**/ {{0xae61e2d1, 0xbbd01432} },},
+/**/ {{{0x0a84710c, 0x3fdb4000} },
+/**/ {{0xc3e50155, 0x3fdd068c} },
+/**/ {{0x775034dd, 0x4001a3bd} },
+/**/ {{0x58e0e228, 0xbbe80b1e} },},
+/**/ {{{0xf692e9d8, 0x3fdb7fff} },
+/**/ {{0xc49d6627, 0x3fdd53d9} },
+/**/ {{0xfe18066a, 0x4001753e} },
+/**/ {{0xf760d33e, 0xbbb004c8} },},
+/**/ {{{0x0280f14d, 0x3fdbc000} },
+/**/ {{0xe4e81013, 0x3fdda16d} },
+/**/ {{0xa38ea052, 0x40014789} },
+/**/ {{0x27c9c4ea, 0x3be848bc} },},
+/**/ {{{0x001121d1, 0x3fdc0000} },
+/**/ {{0xeac018f0, 0x3fddef49} },
+/**/ {{0x20b8be0c, 0x40011a98} },
+/**/ {{0xd0d6010e, 0xbbe1527e} },},
+/**/ {{{0xfef662aa, 0x3fdc3fff} },
+/**/ {{0xea0c7070, 0x3fde3d6e} },
+/**/ {{0x32f46ccd, 0x4000ee65} },
+/**/ {{0x189a000d, 0x3be8d241} },},
+/**/ {{{0x09845818, 0x3fdc8000} },
+/**/ {{0xf36a8b1b, 0x3fde8bdd} },
+/**/ {{0xcac73476, 0x4000c2eb} },
+/**/ {{0x12bed284, 0x3bd221f7} },},
+/**/ {{{0xfb0493bf, 0x3fdcbfff} },
+/**/ {{0xe0c60d10, 0x3fdeda97} },
+/**/ {{0x251c7836, 0x40009827} },
+/**/ {{0x6eec41b7, 0xbbe0bd54} },},
+/**/ {{{0xfd52961f, 0x3fdcffff} },
+/**/ {{0xefb3e44b, 0x3fdf299d} },
+/**/ {{0x74e459f5, 0x40006e12} },
+/**/ {{0xe969c82f, 0xbbd93f77} },},
+/**/ {{{0xfe2319a4, 0x3fdd3fff} },
+/**/ {{0x17139490, 0x3fdf78f1} },
+/**/ {{0x3e737e94, 0x400044a9} },
+/**/ {{0x49594b7a, 0xbb91e7cc} },},
+/**/ {{{0xfa4de596, 0x3fdd7fff} },
+/**/ {{0x638f49e8, 0x3fdfc892} },
+/**/ {{0x231057a5, 0x40001be7} },
+/**/ {{0xf5af9f5f, 0x3bd482b0} },},
+/**/ {{{0xfe729a69, 0x3fddbfff} },
+/**/ {{0x7c6ab019, 0x3fe00c41} },
+/**/ {{0xbf612660, 0x3fffe78f} },
+/**/ {{0x00da681e, 0x3bea5cda} },},
+/**/ {{{0x09d66802, 0x3fde0000} },
+/**/ {{0xf6b883cf, 0x3fe03461} },
+/**/ {{0xbc05a87c, 0x3fff988e} },
+/**/ {{0xf2372669, 0xbbe06c33} },},
+/**/ {{{0xfb211657, 0x3fde3fff} },
+/**/ {{0x191db8e8, 0x3fe05cab} },
+/**/ {{0x7bcfe6be, 0x3fff4ac3} },
+/**/ {{0x5ed8d35b, 0xbbd5d51f} },},
+/**/ {{{0x0a3f068a, 0x3fde8000} },
+/**/ {{0x95fb54f0, 0x3fe0851d} },
+/**/ {{0x144ca408, 0x3ffefe26} },
+/**/ {{0xa2c169c5, 0xbbc7c894} },},
+/**/ {{{0x01adb060, 0x3fdec000} },
+/**/ {{0xdc7b54f9, 0x3fe0adb9} },
+/**/ {{0x5ebe52a7, 0x3ffeb2af} },
+/**/ {{0x312c5ffd, 0x3bd4e740} },},
+/**/ {{{0xff5c0d01, 0x3fdeffff} },
+/**/ {{0x92550a8d, 0x3fe0d680} },
+/**/ {{0x0d71fdf0, 0x3ffe6858} },
+/**/ {{0x96b35499, 0x3bddd8a6} },},
+/**/ {{{0xf93d5fcc, 0x3fdf3fff} },
+/**/ {{0x45cb4374, 0x3fe0ff72} },
+/**/ {{0x3cce5040, 0x3ffe1f19} },
+/**/ {{0x7c1efab4, 0xbbc9f0ec} },},
+/**/ {{{0xfa0dd18f, 0x3fdf7fff} },
+/**/ {{0x944dd508, 0x3fe1288f} },
+/**/ {{0x298b874d, 0x3ffdd6ec} },
+/**/ {{0x9642a0a6, 0x3bea6ebd} },},
+/**/ {{{0xfd3a9f1a, 0x3fdfbfff} },
+/**/ {{0x13750f3e, 0x3fe151d9} },
+/**/ {{0x5806a27e, 0x3ffd8fca} },
+/**/ {{0xfc65ac7a, 0x3bda2a03} },},
+/**/ {{{0xfc481400, 0x3fdfffff} },
+/**/ {{0x598944ca, 0x3fe17b4f} },
+/**/ {{0x82532170, 0x3ffd49ad} },
+/**/ {{0x3d236dc3, 0x3bc4412e} },},
+/**/ {{{0xff53786c, 0x3fe01fff} },
+/**/ {{0x07d83d47, 0x3fe1a4f3} },
+/**/ {{0x851bffeb, 0x3ffd048f} },
+/**/ {{0x29f81b14, 0x3bd1589d} },},
+/**/ {{{0xfee301b7, 0x3fe03fff} },
+/**/ {{0xb8a6a382, 0x3fe1cec4} },
+/**/ {{0x7c519db6, 0x3ffcc06a} },
+/**/ {{0x5b24d6b2, 0x3bd370e6} },},
+/**/ {{{0x006e36bf, 0x3fe06000} },
+/**/ {{0x114eb8be, 0x3fe1f8c5} },
+/**/ {{0xa34d6786, 0x3ffc7d38} },
+/**/ {{0x4b98c1d4, 0xbbea92de} },},
+/**/ {{{0xfd60aa43, 0x3fe07fff} },
+/**/ {{0xabeccecb, 0x3fe222f4} },
+/**/ {{0x77342ac4, 0x3ffc3af4} },
+/**/ {{0x03a5c2c2, 0xbbdd47f6} },},
+/**/ {{{0x037762e8, 0x3fe0a000} },
+/**/ {{0x3f99efe8, 0x3fe24d54} },
+/**/ {{0x75f54fab, 0x3ffbf998} },
+/**/ {{0x15771a46, 0x3bedf7f4} },},
+/**/ {{{0xff1c6921, 0x3fe0bfff} },
+/**/ {{0x598e35d0, 0x3fe277e4} },
+/**/ {{0x8addd186, 0x3ffbb91f} },
+/**/ {{0x5e0e5a73, 0x3be0f16c} },},
+/**/ {{{0xff07154b, 0x3fe0dfff} },
+/**/ {{0xb6bc3986, 0x3fe2a2a5} },
+/**/ {{0x8301646d, 0x3ffb7984} },
+/**/ {{0xbbaa5310, 0xbbf02dd0} },},
+/**/ {{{0x02fcdda4, 0x3fe10000} },
+/**/ {{0x02a59f1e, 0x3fe2cd99} },
+/**/ {{0x705219bf, 0x3ffb3ac2} },
+/**/ {{0x112fa616, 0xbbe59357} },},
+/**/ {{{0x01ce1140, 0x3fe12000} },
+/**/ {{0xdf0a67c2, 0x3fe2f8be} },
+/**/ {{0x9ab8ae2a, 0x3ffafcd4} },
+/**/ {{0x9303f346, 0x3be2c542} },},
+/**/ {{{0x04d0f355, 0x3fe14000} },
+/**/ {{0x08fcc7bf, 0x3fe32418} },
+/**/ {{0x497b9a36, 0x3ffabfb6} },
+/**/ {{0xb5a59234, 0x3bebc044} },},
+/**/ {{{0x00fb0c8a, 0x3fe16000} },
+/**/ {{0x2471618b, 0x3fe34fa5} },
+/**/ {{0x0d26d117, 0x3ffa8363} },
+/**/ {{0x3f7bb7c9, 0xbbdbfbb2} },},
+/**/ {{{0x026f10b3, 0x3fe18000} },
+/**/ {{0xf7579056, 0x3fe37b66} },
+/**/ {{0x6b4cf4b1, 0x3ffa47d6} },
+/**/ {{0xaf0b5de9, 0x3bf0f6b4} },},
+/**/ {{{0xfd0978f8, 0x3fe19fff} },
+/**/ {{0x290cc78c, 0x3fe3a75e} },
+/**/ {{0x36c21315, 0x3ffa0d0c} },
+/**/ {{0xa296b262, 0x3beb2129} },},
+/**/ {{{0xfd94840b, 0x3fe1bfff} },
+/**/ {{0x85b4e4a4, 0x3fe3d38b} },
+/**/ {{0x32f2ecef, 0x3ff9d300} },
+/**/ {{0xb9bb7d74, 0xbbdbab1a} },},
+/**/ {{{0xfbda1ea1, 0x3fe1dfff} },
+/**/ {{0xbf3cee2f, 0x3fe3ffef} },
+/**/ {{0x6770fed8, 0x3ff999ae} },
+/**/ {{0xb4ace9a4, 0x3bda0bdc} },},
+/**/ {{{0xfc989533, 0x3fe1ffff} },
+/**/ {{0x9c27900c, 0x3fe42c8b} },
+/**/ {{0xe0d9f1ac, 0x3ff96112} },
+/**/ {{0x2fa2d81a, 0xbbee19eb} },},
+/**/ {{{0x012b8d26, 0x3fe22000} },
+/**/ {{0xe11975ca, 0x3fe4595f} },
+/**/ {{0xcdaa4e80, 0x3ff92929} },
+/**/ {{0xacc82d4b, 0x3bf23382} },},
+/**/ {{{0x04f4d6af, 0x3fe24000} },
+/**/ {{0x4d224131, 0x3fe4866d} },
+/**/ {{0x815c34e8, 0x3ff8f1ef} },
+/**/ {{0x3b740a99, 0xbbd0c6ff} },},
+/**/ {{{0xfcc07bda, 0x3fe25fff} },
+/**/ {{0x98b7d010, 0x3fe4b3b4} },
+/**/ {{0x73e7ffa1, 0x3ff8bb60} },
+/**/ {{0x1ad7a9c2, 0x3bebc31b} },},
+/**/ {{{0x042d9639, 0x3fe28000} },
+/**/ {{0xb64540d1, 0x3fe4e136} },
+/**/ {{0xf4374938, 0x3ff88578} },
+/**/ {{0x1b85e901, 0x3be36de9} },},
+/**/ {{{0x03be29a0, 0x3fe2a000} },
+/**/ {{0x52bffd96, 0x3fe50ef4} },
+/**/ {{0xc0042c06, 0x3ff85035} },
+/**/ {{0x76f5efbd, 0x3be15d01} },},
+/**/ {{{0xfaa91f12, 0x3fe2bfff} },
+/**/ {{0x3e2f4e0d, 0x3fe53cee} },
+/**/ {{0x8542df07, 0x3ff81b93} },
+/**/ {{0x17662a2b, 0x3be555cd} },},
+/**/ {{{0xfe884891, 0x3fe2dfff} },
+/**/ {{0x6c1a2470, 0x3fe56b25} },
+/**/ {{0xe422ea70, 0x3ff7e78e} },
+/**/ {{0xbd030c11, 0x3bf03504} },},
+/**/ {{{0xfe87152b, 0x3fe2ffff} },
+/**/ {{0x9beaaaa1, 0x3fe5999a} },
+/**/ {{0xd18fe9b3, 0x3ff7b424} },
+/**/ {{0x773e0e64, 0xbb649a5f} },},
+/**/ {{{0xffc1a721, 0x3fe31fff} },
+/**/ {{0xafe0e564, 0x3fe5c84e} },
+/**/ {{0x338db8d4, 0x3ff78152} },
+/**/ {{0x5da8e935, 0x3beaf428} },},
+/**/ {{{0xff70a372, 0x3fe33fff} },
+/**/ {{0x82191d64, 0x3fe5f742} },
+/**/ {{0x1122bcae, 0x3ff74f14} },
+/**/ {{0xdee4bfaf, 0x3bdb1c4b} },},
+/**/ {{{0x0436e836, 0x3fe36000} },
+/**/ {{0xfde6ccff, 0x3fe62676} },
+/**/ {{0x7644252c, 0x3ff71d67} },
+/**/ {{0xe08c3afb, 0xbbec3d10} },},
+/**/ {{{0xfcbe9641, 0x3fe37fff} },
+/**/ {{0xee9ffdaf, 0x3fe655ec} },
+/**/ {{0xa6fc0515, 0x3ff6ec49} },
+/**/ {{0x2ed29567, 0x3bdda453} },},
+/**/ {{{0xffb6d6ca, 0x3fe39fff} },
+/**/ {{0x5e67a1e1, 0x3fe685a5} },
+/**/ {{0xbc2ae969, 0x3ff6bbb7} },
+/**/ {{0x2ef43882, 0x3becbf7b} },},
+/**/ {{{0x04934fec, 0x3fe3c000} },
+/**/ {{0x2cc07d75, 0x3fe6b5a1} },
+/**/ {{0x10b02ef8, 0x3ff68baf} },
+/**/ {{0xfeb7cabd, 0xbbe7c8fb} },},
+/**/ {{{0x03f5cf7f, 0x3fe3e000} },
+/**/ {{0x3e59def6, 0x3fe6e5e1} },
+/**/ {{0x0e61500f, 0x3ff65c2d} },
+/**/ {{0x035f7845, 0xbbe30ba4} },},
+/**/ {{{0x05280ad9, 0x3fe40000} },
+/**/ {{0x91ab4c3e, 0x3fe71666} },
+/**/ {{0x19f01c90, 0x3ff62d2f} },
+/**/ {{0xffe95f6a, 0xbbf1e9f5} },},
+/**/ {{{0x049efb65, 0x3fe42000} },
+/**/ {{0x18af3b9d, 0x3fe74732} },
+/**/ {{0xb86465e4, 0x3ff5feb2} },
+/**/ {{0x280d591e, 0x3bc4cad7} },},
+/**/ {{{0x0035ccb6, 0x3fe44000} },
+/**/ {{0xcb4ff1e5, 0x3fe77844} },
+/**/ {{0x7c455428, 0x3ff5d0b5} },
+/**/ {{0x7ba5617c, 0x3bed8c18} },},
+/**/ {{{0x03346717, 0x3fe46000} },
+/**/ {{0xba258778, 0x3fe7a99f} },
+/**/ {{0xf4392254, 0x3ff5a334} },
+/**/ {{0xfc84a570, 0xbbefd14a} },},
+/**/ {{{0x03002575, 0x3fe48000} },
+/**/ {{0xd836768f, 0x3fe7db43} },
+/**/ {{0xdcf97e0c, 0x3ff5762e} },
+/**/ {{0x5f5df49e, 0xbbdd7eba} },},
+/**/ {{{0x055bf381, 0x3fe4a000} },
+/**/ {{0x35edeefa, 0x3fe80d32} },
+/**/ {{0xea46e31f, 0x3ff549a0} },
+/**/ {{0x76823eac, 0xbbdba522} },},
+/**/ {{{0x04ce10e3, 0x3fe4c000} },
+/**/ {{0xd67dc1a8, 0x3fe83f6b} },
+/**/ {{0xed82bcc4, 0x3ff51d88} },
+/**/ {{0x077d29ea, 0xbbeae92d} },},
+/**/ {{{0x016c60e1, 0x3fe4e000} },
+/**/ {{0xca0aaf31, 0x3fe871f1} },
+/**/ {{0xbdacbf16, 0x3ff4f1e4} },
+/**/ {{0x46ee425e, 0x3be82958} },},
+/**/ {{{0xff966f0a, 0x3fe4ffff} },
+/**/ {{0x2bff2dae, 0x3fe8a4c5} },
+/**/ {{0x3917657e, 0x3ff4c6b2} },
+/**/ {{0x5c86c705, 0xbbf127c2} },},
+/**/ {{{0x0076e6eb, 0x3fe52000} },
+/**/ {{0x175651e8, 0x3fe8d7e7} },
+/**/ {{0x4f459b05, 0x3ff49bef} },
+/**/ {{0x4181bbfc, 0xbbb1e9d1} },},
+/**/ {{{0x03d12d3b, 0x3fe54000} },
+/**/ {{0xa976ed56, 0x3fe90b58} },
+/**/ {{0xfdf24af4, 0x3ff47199} },
+/**/ {{0xc30decaf, 0x3be38c17} },},
+/**/ {{{0xfce7fa8d, 0x3fe55fff} },
+/**/ {{0xf03a3a09, 0x3fe93f1a} },
+/**/ {{0x5f13234b, 0x3ff447b0} },
+/**/ {{0x70df7e20, 0x3bf1b8b2} },},
+/**/ {{{0x0331b46a, 0x3fe58000} },
+/**/ {{0x38e83134, 0x3fe9732f} },
+/**/ {{0x68d8b41b, 0x3ff41e30} },
+/**/ {{0xb90bc28b, 0xbbee24d8} },},
+/**/ {{{0xfc14848e, 0x3fe59fff} },
+/**/ {{0x8471b489, 0x3fe9a796} },
+/**/ {{0x5de3aa73, 0x3ff3f518} },
+/**/ {{0xe0761536, 0xbbecacd9} },},
+/**/ {{{0xfb7cd395, 0x3fe5bfff} },
+/**/ {{0x24a8b955, 0x3fe9dc52} },
+/**/ {{0x4f8fff15, 0x3ff3cc66} },
+/**/ {{0x82045611, 0xbbf67c97} },},
+/**/ {{{0x000dcc40, 0x3fe5e000} },
+/**/ {{0x4df5b93e, 0x3fea1163} },
+/**/ {{0x75853228, 0x3ff3a418} },
+/**/ {{0xd481f350, 0xbbf585da} },},
+/**/ {{{0x02efd2fc, 0x3fe60000} },
+/**/ {{0x30d16323, 0x3fea46cb} },
+/**/ {{0x187962ae, 0x3ff37c2d} },
+/**/ {{0xa5f77bb0, 0x3bf004c3} },},
+/**/ {{{0xfeb8088a, 0x3fe61fff} },
+/**/ {{0x053920c0, 0x3fea7c8b} },
+/**/ {{0x891769a9, 0x3ff354a2} },
+/**/ {{0x3fee3029, 0x3bbc6b30} },},
+/**/ {{{0x00f3ca06, 0x3fe64000} },
+/**/ {{0x28a1911a, 0x3feab2a4} },
+/**/ {{0x0a6f0a4a, 0x3ff32d77} },
+/**/ {{0xfac5081a, 0x3bf2a6f8} },},
+/**/ {{{0xfe9ec2f4, 0x3fe65fff} },
+/**/ {{0xd4ce7239, 0x3feae917} },
+/**/ {{0x0751a948, 0x3ff306a9} },
+/**/ {{0x51ab9dbd, 0xbbe950b5} },},
+/**/ {{{0x03d43966, 0x3fe68000} },
+/**/ {{0x708b998a, 0x3feb1fe7} },
+/**/ {{0xd7a153c7, 0x3ff2e036} },
+/**/ {{0xa1e4a14e, 0x3bdd36e2} },},
+/**/ {{{0xfab67783, 0x3fe69fff} },
+/**/ {{0x2e575464, 0x3feb5714} },
+/**/ {{0x05006cb6, 0x3ff2ba1f} },
+/**/ {{0x473c2e31, 0x3bea9a4a} },},
+/**/ {{{0xfcb65f89, 0x3fe6bfff} },
+/**/ {{0x981efd2f, 0x3feb8e9f} },
+/**/ {{0xe948d9f7, 0x3ff2945f} },
+/**/ {{0xe802df72, 0xbbca5294} },},
+/**/ {{{0xfc5609a9, 0x3fe6dfff} },
+/**/ {{0xfaed6ff1, 0x3febc68a} },
+/**/ {{0x1533411e, 0x3ff26ef8} },
+/**/ {{0xf51bc566, 0xbbf89153} },},
+/**/ {{{0xfc4eef86, 0x3fe6ffff} },
+/**/ {{0xc62205fe, 0x3febfed7} },
+/**/ {{0x0e70978c, 0x3ff249e6} },
+/**/ {{0xa2b9ff56, 0x3bc39021} },},
+/**/ {{{0x004d98b3, 0x3fe72000} },
+/**/ {{0x716968ad, 0x3fec3787} },
+/**/ {{0x61be7751, 0x3ff22528} },
+/**/ {{0x74ee2211, 0x3befc9c5} },},
+/**/ {{{0xfc155075, 0x3fe73fff} },
+/**/ {{0x5ec6fd4e, 0x3fec709b} },
+/**/ {{0xb5d53311, 0x3ff200bd} },
+/**/ {{0xa269ae63, 0x3be28a4d} },},
+/**/ {{{0x0498c203, 0x3fe76000} },
+/**/ {{0x323d08c1, 0x3fecaa15} },
+/**/ {{0x93433f65, 0x3ff1dca4} },
+/**/ {{0x14a28fb7, 0x3bf8cae4} },},
+/**/ {{{0xff1e5636, 0x3fe77fff} },
+/**/ {{0x4147c12c, 0x3fece3f6} },
+/**/ {{0xbfe294a8, 0x3ff1b8db} },
+/**/ {{0x4b56a744, 0xbbe7e19c} },},
+/**/ {{{0x0226d45a, 0x3fe7a000} },
+/**/ {{0x4120eb7f, 0x3fed1e40} },
+/**/ {{0xd15f8278, 0x3ff19561} },
+/**/ {{0x032c5d4c, 0x3be64b28} },},
+/**/ {{{0x0250a5aa, 0x3fe7c000} },
+/**/ {{0xb112a1e1, 0x3fed58f4} },
+/**/ {{0x8a59d565, 0x3ff17235} },
+/**/ {{0xb8dc7867, 0xbbe716de} },},
+/**/ {{{0x0482f82e, 0x3fe7e000} },
+/**/ {{0x3576bdf0, 0x3fed9415} },
+/**/ {{0xa22a1c5b, 0x3ff14f55} },
+/**/ {{0xe1305604, 0x3bf207e1} },},
+/**/ {{{0x0205003e, 0x3fe80000} },
+/**/ {{0x64d69ff7, 0x3fedcfa3} },
+/**/ {{0xe37eb26f, 0x3ff12cc0} },
+/**/ {{0xe32395f8, 0xbbd52ec6} },},
+/**/ {{{0xfbf99411, 0x3fe81fff} },
+/**/ {{0xebf98f51, 0x3fee0ba0} },
+/**/ {{0x16ddd5d6, 0x3ff10a76} },
+/**/ {{0x59866045, 0xbbece0d6} },},
+/**/ {{{0x0248e3a3, 0x3fe84000} },
+/**/ {{0x9bb7f565, 0x3fee480f} },
+/**/ {{0xfb84e05c, 0x3ff0e873} },
+/**/ {{0x1595df92, 0x3bf4e5e8} },},
+/**/ {{{0x0145c157, 0x3fe86000} },
+/**/ {{0x0a10b3ab, 0x3fee84f1} },
+/**/ {{0x7cbd7b1e, 0x3ff0c6b9} },
+/**/ {{0xd5f121d0, 0xbbe19de6} },},
+/**/ {{{0x022631b9, 0x3fe88000} },
+/**/ {{0x0be1f047, 0x3feec247} },
+/**/ {{0x6d0b3ee6, 0x3ff0a545} },
+/**/ {{0xa3ba2c6f, 0xbbc272b1} },},
+/**/ {{{0x045f7828, 0x3fe8a000} },
+/**/ {{0x6c45ba1c, 0x3fef0013} },
+/**/ {{0xaf2a0f09, 0x3ff08416} },
+/**/ {{0x5b63c799, 0x3be82b56} },},
+/**/ {{{0xffc686cf, 0x3fe8bfff} },
+/**/ {{0xf03c824b, 0x3fef3e57} },
+/**/ {{0x33502220, 0x3ff0632c} },
+/**/ {{0x2dbeeb25, 0xbbd039ad} },},
+/**/ {{{0xfd8644c6, 0x3fe8dfff} },
+/**/ {{0x8774261d, 0x3fef7d16} },
+/**/ {{0xdd5b3019, 0x3ff04284} },
+/**/ {{0xe1eba933, 0x3bd79f33} },},
+/**/ {{{0xfe4e7937, 0x3fe8ffff} },
+/**/ {{0x1a99a641, 0x3fefbc51} },
+/**/ {{0x9f69840b, 0x3ff0221f} },
+/**/ {{0x7beee018, 0xbbea9e84} },},
+/**/ {{{0x0435251f, 0x3fe92000} },
+/**/ {{0x9eb22390, 0x3feffc09} },
+/**/ {{0x6f7c51e8, 0x3ff001fb} },
+/**/ {{0x31032e0a, 0xbb5a12e7} },},
+ };
+
+#endif
+#endif
diff --git a/libc/sysdeps/ieee754/dbl-64/w_exp.c b/libc/sysdeps/ieee754/dbl-64/w_exp.c
new file mode 100644
index 000000000..445c5788d
--- /dev/null
+++ b/libc/sysdeps/ieee754/dbl-64/w_exp.c
@@ -0,0 +1,58 @@
+/* @(#)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"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
+u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */
+
+#ifdef __STDC__
+ double __exp(double x) /* wrapper exp */
+#else
+ double __exp(x) /* wrapper exp */
+ double x;
+#endif
+{
+#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
+}
+weak_alias (__exp, exp)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__exp, __expl)
+weak_alias (__exp, expl)
+#endif
diff --git a/libc/sysdeps/ieee754/flt-32/e_acosf.c b/libc/sysdeps/ieee754/flt-32/e_acosf.c
new file mode 100644
index 000000000..0d85c4210
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_acosf.c
@@ -0,0 +1,89 @@
+/* e_acosf.c -- float version of e_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: e_acosf.c,v 1.5 1995/05/12 04:57:16 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0000000000e+00, /* 0x3F800000 */
+pi = 3.1415925026e+00, /* 0x40490fda */
+pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */
+pio2_lo = 7.5497894159e-08, /* 0x33a22168 */
+pS0 = 1.6666667163e-01, /* 0x3e2aaaab */
+pS1 = -3.2556581497e-01, /* 0xbea6b090 */
+pS2 = 2.0121252537e-01, /* 0x3e4e0aa8 */
+pS3 = -4.0055535734e-02, /* 0xbd241146 */
+pS4 = 7.9153501429e-04, /* 0x3a4f7f04 */
+pS5 = 3.4793309169e-05, /* 0x3811ef08 */
+qS1 = -2.4033949375e+00, /* 0xc019d139 */
+qS2 = 2.0209457874e+00, /* 0x4001572d */
+qS3 = -6.8828397989e-01, /* 0xbf303361 */
+qS4 = 7.7038154006e-02; /* 0x3d9dc62e */
+
+#ifdef __STDC__
+ float __ieee754_acosf(float x)
+#else
+ float __ieee754_acosf(x)
+ float x;
+#endif
+{
+ float z,p,q,r,w,s,c,df;
+ int32_t hx,ix;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix==0x3f800000) { /* |x|==1 */
+ if(hx>0) return 0.0; /* acos(1) = 0 */
+ else return pi+(float)2.0*pio2_lo; /* acos(-1)= pi */
+ } else if(ix>0x3f800000) { /* |x| >= 1 */
+ return (x-x)/(x-x); /* acos(|x|>1) is NaN */
+ }
+ if(ix<0x3f000000) { /* |x| < 0.5 */
+ if(ix<=0x23000000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
+ z = x*x;
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ r = p/q;
+ return pio2_hi - (x - (pio2_lo-x*r));
+ } else if (hx<0) { /* x < -0.5 */
+ 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);
+ 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);
+ df = s;
+ GET_FLOAT_WORD(idf,df);
+ SET_FLOAT_WORD(df,idf&0xfffff000);
+ c = (z-df*df)/(s+df);
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ r = p/q;
+ w = r*s+c;
+ return (float)2.0*(df+w);
+ }
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_acoshf.c b/libc/sysdeps/ieee754/flt-32/e_acoshf.c
new file mode 100644
index 000000000..c607f7211
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_acoshf.c
@@ -0,0 +1,57 @@
+/* e_acoshf.c -- float version of e_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: e_acoshf.c,v 1.5 1995/05/12 04:57:20 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0,
+ln2 = 6.9314718246e-01; /* 0x3f317218 */
+
+#ifdef __STDC__
+ float __ieee754_acoshf(float x)
+#else
+ float __ieee754_acoshf(x)
+ float x;
+#endif
+{
+ float t;
+ int32_t hx;
+ GET_FLOAT_WORD(hx,x);
+ if(hx<0x3f800000) { /* x < 1 */
+ return (x-x)/(x-x);
+ } else if(hx >=0x4d800000) { /* x > 2**28 */
+ if(hx >=0x7f800000) { /* x is inf of NaN */
+ return x+x;
+ } else
+ return __ieee754_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)));
+ } else { /* 1<x<2 */
+ t = x-one;
+ return __log1pf(t+__sqrtf((float)2.0*t+t*t));
+ }
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_asinf.c b/libc/sysdeps/ieee754/flt-32/e_asinf.c
new file mode 100644
index 000000000..b0c835c83
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_asinf.c
@@ -0,0 +1,110 @@
+/* e_asinf.c -- float version of e_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.
+ * ====================================================
+ */
+
+/*
+ Modifications for single precision expansion are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: e_asinf.c,v 1.5 1995/05/12 04:57:25 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0000000000e+00, /* 0x3F800000 */
+huge = 1.000e+30,
+
+pio2_hi = 1.57079637050628662109375f,
+pio2_lo = -4.37113900018624283e-8f,
+pio4_hi = 0.785398185253143310546875f,
+
+/* asin x = x + x^3 p(x^2)
+ -0.5 <= x <= 0.5;
+ Peak relative error 4.8e-9 */
+p0 = 1.666675248e-1f,
+p1 = 7.495297643e-2f,
+p2 = 4.547037598e-2f,
+p3 = 2.417951451e-2f,
+p4 = 4.216630880e-2f;
+
+#ifdef __STDC__
+ float __ieee754_asinf(float x)
+#else
+ float __ieee754_asinf(x)
+ float x;
+#endif
+{
+ float t,w,p,q,c,r,s;
+ int32_t hx,ix;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix==0x3f800000) {
+ /* asin(1)=+-pi/2 with inexact */
+ return x*pio2_hi+x*pio2_lo;
+ } else if(ix> 0x3f800000) { /* |x|>= 1 */
+ return (x-x)/(x-x); /* asin(|x|>1) is NaN */
+ } else if (ix<0x3f000000) { /* |x|<0.5 */
+ if(ix<0x32000000) { /* if |x| < 2**-27 */
+ if(huge+x>one) return x;/* return x with inexact if x!=0*/
+ } else {
+ t = x*x;
+ w = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4))));
+ return x+x*w;
+ }
+ }
+ /* 1> |x|>= 0.5 */
+ w = one-fabsf(x);
+ t = w*0.5f;
+ p = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4))));
+ s = __ieee754_sqrtf(t);
+ if(ix>=0x3F79999A) { /* if |x| > 0.975 */
+ t = pio2_hi-(2.0f*(s+s*p)-pio2_lo);
+ } else {
+ int32_t iw;
+ w = s;
+ GET_FLOAT_WORD(iw,w);
+ SET_FLOAT_WORD(w,iw&0xfffff000);
+ c = (t-w*w)/(s+w);
+ r = p;
+ p = 2.0f*s*r-(pio2_lo-2.0f*c);
+ q = pio4_hi-2.0f*w;
+ t = pio4_hi-(p-q);
+ }
+ if(hx>0) return t; else return -t;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_atan2f.c b/libc/sysdeps/ieee754/flt-32/e_atan2f.c
new file mode 100644
index 000000000..c0cafb16b
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_atan2f.c
@@ -0,0 +1,105 @@
+/* e_atan2f.c -- float version of e_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: e_atan2f.c,v 1.4 1995/05/10 20:44:53 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+tiny = 1.0e-30,
+zero = 0.0,
+pi_o_4 = 7.8539818525e-01, /* 0x3f490fdb */
+pi_o_2 = 1.5707963705e+00, /* 0x3fc90fdb */
+pi = 3.1415927410e+00, /* 0x40490fdb */
+pi_lo = -8.7422776573e-08; /* 0xb3bbbd2e */
+
+#ifdef __STDC__
+ float __ieee754_atan2f(float y, float x)
+#else
+ float __ieee754_atan2f(y,x)
+ float y,x;
+#endif
+{
+ float z;
+ int32_t k,m,hx,hy,ix,iy;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ GET_FLOAT_WORD(hy,y);
+ iy = hy&0x7fffffff;
+ if((ix>0x7f800000)||
+ (iy>0x7f800000)) /* x or y is NaN */
+ return x+y;
+ if(hx==0x3f800000) return __atanf(y); /* x=1.0 */
+ m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */
+
+ /* when y = 0 */
+ if(iy==0) {
+ switch(m) {
+ case 0:
+ case 1: return y; /* atan(+-0,+anything)=+-0 */
+ case 2: return pi+tiny;/* atan(+0,-anything) = pi */
+ case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
+ }
+ }
+ /* when x = 0 */
+ if(ix==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* when x is INF */
+ if(ix==0x7f800000) {
+ if(iy==0x7f800000) {
+ switch(m) {
+ case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
+ case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
+ case 2: return (float)3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
+ case 3: return (float)-3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
+ }
+ } else {
+ switch(m) {
+ case 0: return zero ; /* atan(+...,+INF) */
+ case 1: return -zero ; /* atan(-...,+INF) */
+ case 2: return pi+tiny ; /* atan(+...,-INF) */
+ case 3: return -pi-tiny ; /* atan(-...,-INF) */
+ }
+ }
+ }
+ /* when y is INF */
+ if(iy==0x7f800000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* compute y/x */
+ k = (iy-ix)>>23;
+ if(k > 60) z=pi_o_2+(float)0.5*pi_lo; /* |y/x| > 2**60 */
+ else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */
+ else z=__atanf(fabsf(y/x)); /* safe to do y/x */
+ switch (m) {
+ case 0: return z ; /* atan(+,+) */
+ case 1: {
+ u_int32_t zh;
+ GET_FLOAT_WORD(zh,z);
+ SET_FLOAT_WORD(z,zh ^ 0x80000000);
+ }
+ return z ; /* atan(-,+) */
+ case 2: return pi-(z-pi_lo);/* atan(+,-) */
+ default: /* case 3 */
+ return (z-pi_lo)-pi;/* atan(-,-) */
+ }
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_atanhf.c b/libc/sysdeps/ieee754/flt-32/e_atanhf.c
new file mode 100644
index 000000000..f26a15bbc
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_atanhf.c
@@ -0,0 +1,58 @@
+/* e_atanhf.c -- float version of e_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: e_atanhf.c,v 1.4 1995/05/10 20:44:56 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one = 1.0, huge = 1e30;
+#else
+static float one = 1.0, huge = 1e30;
+#endif
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_atanhf(float x)
+#else
+ float __ieee754_atanhf(x)
+ float x;
+#endif
+{
+ float t;
+ int32_t hx,ix;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if (ix>0x3f800000) /* |x|>1 */
+ return (x-x)/(x-x);
+ if(ix==0x3f800000)
+ return x/zero;
+ if(ix<0x31800000&&(huge+x)>zero) return x; /* x<2**-28 */
+ SET_FLOAT_WORD(x,ix);
+ if(ix<0x3f000000) { /* x < 0.5 */
+ t = x+x;
+ t = (float)0.5*__log1pf(t+t*x/(one-x));
+ } else
+ t = (float)0.5*__log1pf((x+x)/(one-x));
+ if(hx>=0) return t; else return -t;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_coshf.c b/libc/sysdeps/ieee754/flt-32/e_coshf.c
new file mode 100644
index 000000000..223fbeea2
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_coshf.c
@@ -0,0 +1,72 @@
+/* e_coshf.c -- float version of e_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: e_coshf.c,v 1.6 1996/04/08 15:43:41 phil Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float huge = 1.0e30;
+static const float one = 1.0, half=0.5;
+#else
+static float one = 1.0, half=0.5, huge = 1.0e30;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_coshf(float x)
+#else
+ float __ieee754_coshf(x)
+ float x;
+#endif
+{
+ float t,w;
+ int32_t ix;
+
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7f800000) return x*x;
+
+ /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
+ if(ix<0x3eb17218) {
+ t = __expm1f(fabsf(x));
+ w = one+t;
+ if (ix<0x24000000) return w; /* cosh(tiny) = 1 */
+ return one+(t*t)/(w+w);
+ }
+
+ /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
+ if (ix < 0x41b00000) {
+ t = __ieee754_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));
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ if (ix<=0x42b2d4fc) {
+ w = __ieee754_expf(half*fabsf(x));
+ t = half*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, cosh(x) overflow */
+ return huge*huge;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_exp2f.c b/libc/sysdeps/ieee754/flt-32/e_exp2f.c
new file mode 100644
index 000000000..194222a0c
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_exp2f.c
@@ -0,0 +1,128 @@
+/* Single-precision floating point 2^x.
+ Copyright (C) 1997,1998,2000,2001,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Geoffrey Keating <geoffk@ozemail.com.au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The basic design here is from
+ Shmuel Gal and Boris Bachelis, "An Accurate Elementary Mathematical
+ Library for the IEEE Floating Point Standard", ACM Trans. Math. Soft.,
+ 17 (1), March 1991, pp. 26-45.
+ It has been slightly modified to compute 2^x instead of e^x, and for
+ single-precision.
+ */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+#include <stdlib.h>
+#include <float.h>
+#include <ieee754.h>
+#include <math.h>
+#include <fenv.h>
+#include <inttypes.h>
+#include <math_private.h>
+
+#include "t_exp2f.h"
+
+static const volatile float TWOM100 = 7.88860905e-31;
+static const volatile float TWO127 = 1.7014118346e+38;
+
+float
+__ieee754_exp2f (float x)
+{
+ static const float himark = (float) FLT_MAX_EXP;
+ static const float lomark = (float) (FLT_MIN_EXP - FLT_MANT_DIG - 1);
+
+ /* Check for usual case. */
+ if (isless (x, himark) && isgreaterequal (x, lomark))
+ {
+ static const float THREEp14 = 49152.0;
+ int tval, unsafe;
+ float rx, x22, result;
+ union ieee754_float ex2_u, scale_u;
+ fenv_t oldenv;
+
+ feholdexcept (&oldenv);
+#ifdef FE_TONEAREST
+ /* If we don't have this, it's too bad. */
+ fesetround (FE_TONEAREST);
+#endif
+
+ /* 1. Argument reduction.
+ Choose integers ex, -128 <= t < 128, and some real
+ -1/512 <= x1 <= 1/512 so that
+ x = ex + t/512 + x1.
+
+ First, calculate rx = ex + t/256. */
+ rx = x + THREEp14;
+ rx -= THREEp14;
+ x -= rx; /* Compute x=x1. */
+ /* Compute tval = (ex*256 + t)+128.
+ Now, t = (tval mod 256)-128 and ex=tval/256 [that's mod, NOT %; and
+ /-round-to-nearest not the usual c integer /]. */
+ tval = (int) (rx * 256.0f + 128.0f);
+
+ /* 2. Adjust for accurate table entry.
+ Find e so that
+ x = ex + t/256 + e + x2
+ where -7e-4 < e < 7e-4, and
+ (float)(2^(t/256+e))
+ is accurate to one part in 2^-64. */
+
+ /* 'tval & 255' is the same as 'tval%256' except that it's always
+ positive.
+ Compute x = x2. */
+ x -= __exp2f_deltatable[tval & 255];
+
+ /* 3. Compute ex2 = 2^(t/255+e+ex). */
+ ex2_u.f = __exp2f_atable[tval & 255];
+ tval >>= 8;
+ unsafe = abs(tval) >= -FLT_MIN_EXP - 1;
+ ex2_u.ieee.exponent += tval >> unsafe;
+ scale_u.f = 1.0;
+ scale_u.ieee.exponent += tval - (tval >> unsafe);
+
+ /* 4. Approximate 2^x2 - 1, using a second-degree polynomial,
+ with maximum error in [-2^-9 - 2^-14, 2^-9 + 2^-14]
+ less than 1.3e-10. */
+
+ x22 = (.24022656679f * x + .69314736128f) * ex2_u.f;
+
+ /* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex). */
+ fesetenv (&oldenv);
+
+ result = x22 * x + ex2_u.f;
+
+ if (!unsafe)
+ return result;
+ else
+ return result * scale_u.f;
+ }
+ /* Exceptional cases: */
+ else if (isless (x, himark))
+ {
+ if (__isinff (x))
+ /* e^-inf == 0, with no error. */
+ return 0;
+ else
+ /* Underflow */
+ return TWOM100 * TWOM100;
+ }
+ else
+ /* Return x, if x is a NaN or Inf; or overflow, otherwise. */
+ return TWO127*x;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_expf.c b/libc/sysdeps/ieee754/flt-32/e_expf.c
new file mode 100644
index 000000000..b9cd53c03
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_expf.c
@@ -0,0 +1,140 @@
+/* Single-precision floating point e^x.
+ Copyright (C) 1997, 1998, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Geoffrey Keating <geoffk@ozemail.com.au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* How this works:
+
+ The input value, x, is written as
+
+ x = n * ln(2) + t/512 + delta[t] + x;
+
+ where:
+ - n is an integer, 127 >= n >= -150;
+ - t is an integer, 177 >= t >= -177
+ - delta is based on a table entry, delta[t] < 2^-28
+ - x is whatever is left, |x| < 2^-10
+
+ Then e^x is approximated as
+
+ e^x = 2^n ( e^(t/512 + delta[t])
+ + ( e^(t/512 + delta[t])
+ * ( p(x + delta[t] + n * ln(2)) - delta ) ) )
+
+ where
+ - p(x) is a polynomial approximating e(x)-1;
+ - e^(t/512 + delta[t]) is obtained from a table.
+
+ The table used is the same one as for the double precision version;
+ since we have the table, we might as well use it.
+
+ It turns out to be faster to do calculations in double precision than
+ to perform an 'accurate table method' expf, because of the range reduction
+ overhead (compare exp2f).
+ */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <float.h>
+#include <ieee754.h>
+#include <math.h>
+#include <fenv.h>
+#include <inttypes.h>
+#include <math_private.h>
+
+extern const float __exp_deltatable[178];
+extern const double __exp_atable[355] /* __attribute__((mode(DF))) */;
+
+static const volatile float TWOM100 = 7.88860905e-31;
+static const volatile float TWO127 = 1.7014118346e+38;
+
+float
+__ieee754_expf (float x)
+{
+ static const float himark = 88.72283935546875;
+ static const float lomark = -103.972084045410;
+ /* Check for usual case. */
+ if (isless (x, himark) && isgreater (x, lomark))
+ {
+ static const float THREEp42 = 13194139533312.0;
+ static const float THREEp22 = 12582912.0;
+ /* 1/ln(2). */
+#undef M_1_LN2
+ static const float M_1_LN2 = 1.44269502163f;
+ /* ln(2) */
+#undef M_LN2
+ static const double M_LN2 = .6931471805599452862;
+
+ int tval;
+ double x22, t, result, dx;
+ float n, delta;
+ union ieee754_double ex2_u;
+ fenv_t oldenv;
+
+ feholdexcept (&oldenv);
+#ifdef FE_TONEAREST
+ fesetround (FE_TONEAREST);
+#endif
+
+ /* Calculate n. */
+ n = x * M_1_LN2 + THREEp22;
+ n -= THREEp22;
+ dx = x - n*M_LN2;
+
+ /* Calculate t/512. */
+ t = dx + THREEp42;
+ t -= THREEp42;
+ dx -= t;
+
+ /* Compute tval = t. */
+ tval = (int) (t * 512.0);
+
+ if (t >= 0)
+ delta = - __exp_deltatable[tval];
+ else
+ delta = __exp_deltatable[-tval];
+
+ /* Compute ex2 = 2^n e^(t/512+delta[t]). */
+ ex2_u.d = __exp_atable[tval+177];
+ ex2_u.ieee.exponent += (int) n;
+
+ /* Approximate e^(dx+delta) - 1, using a second-degree polynomial,
+ with maximum error in [-2^-10-2^-28,2^-10+2^-28]
+ less than 5e-11. */
+ x22 = (0.5000000496709180453 * dx + 1.0000001192102037084) * dx + delta;
+
+ /* Return result. */
+ fesetenv (&oldenv);
+
+ result = x22 * ex2_u.d + ex2_u.d;
+ return (float) result;
+ }
+ /* Exceptional cases: */
+ else if (isless (x, himark))
+ {
+ if (__isinff (x))
+ /* e^-inf == 0, with no error. */
+ return 0;
+ else
+ /* Underflow */
+ return TWOM100 * TWOM100;
+ }
+ else
+ /* Return x, if x is a NaN or Inf; or overflow, otherwise. */
+ return TWO127*x;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_fmodf.c b/libc/sysdeps/ieee754/flt-32/e_fmodf.c
new file mode 100644
index 000000000..47b312392
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_fmodf.c
@@ -0,0 +1,113 @@
+/* e_fmodf.c -- float version of e_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: e_fmodf.c,v 1.4 1995/05/10 20:45:10 jtc Exp $";
+#endif
+
+/*
+ * __ieee754_fmodf(x,y)
+ * Return x mod y in exact arithmetic
+ * Method: shift and subtract
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one = 1.0, Zero[] = {0.0, -0.0,};
+#else
+static float one = 1.0, Zero[] = {0.0, -0.0,};
+#endif
+
+#ifdef __STDC__
+ float __ieee754_fmodf(float x, float y)
+#else
+ float __ieee754_fmodf(x,y)
+ float x,y ;
+#endif
+{
+ int32_t n,hx,hy,hz,ix,iy,sx,i;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_FLOAT_WORD(hy,y);
+ sx = hx&0x80000000; /* sign of x */
+ hx ^=sx; /* |x| */
+ hy &= 0x7fffffff; /* |y| */
+
+ /* purge off exception values */
+ if(hy==0||(hx>=0x7f800000)|| /* y=0,or x not finite */
+ (hy>0x7f800000)) /* or y is NaN */
+ return (x*y)/(x*y);
+ if(hx<hy) return x; /* |x|<|y| return x */
+ if(hx==hy)
+ return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/
+
+ /* determine ix = ilogb(x) */
+ if(hx<0x00800000) { /* subnormal x */
+ for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1;
+ } else ix = (hx>>23)-127;
+
+ /* determine iy = ilogb(y) */
+ if(hy<0x00800000) { /* subnormal y */
+ for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1;
+ } else iy = (hy>>23)-127;
+
+ /* set up {hx,lx}, {hy,ly} and align y to x */
+ if(ix >= -126)
+ hx = 0x00800000|(0x007fffff&hx);
+ else { /* subnormal x, shift x to normal */
+ n = -126-ix;
+ hx = hx<<n;
+ }
+ if(iy >= -126)
+ hy = 0x00800000|(0x007fffff&hy);
+ else { /* subnormal y, shift y to normal */
+ n = -126-iy;
+ hy = hy<<n;
+ }
+
+ /* fix point fmod */
+ n = ix - iy;
+ while(n--) {
+ hz=hx-hy;
+ if(hz<0){hx = hx+hx;}
+ else {
+ if(hz==0) /* return sign(x)*0 */
+ return Zero[(u_int32_t)sx>>31];
+ hx = hz+hz;
+ }
+ }
+ hz=hx-hy;
+ if(hz>=0) {hx=hz;}
+
+ /* convert back to floating value and restore the sign */
+ if(hx==0) /* return sign(x)*0 */
+ return Zero[(u_int32_t)sx>>31];
+ while(hx<0x00800000) { /* normalize x */
+ hx = hx+hx;
+ iy -= 1;
+ }
+ if(iy>= -126) { /* normalize output */
+ hx = ((hx-0x00800000)|((iy+127)<<23));
+ SET_FLOAT_WORD(x,hx|sx);
+ } else { /* subnormal output */
+ n = -126 - iy;
+ hx >>= n;
+ SET_FLOAT_WORD(x,hx|sx);
+ x *= one; /* create necessary signal */
+ }
+ return x; /* exact output */
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_gammaf_r.c b/libc/sysdeps/ieee754/flt-32/e_gammaf_r.c
new file mode 100644
index 000000000..926c84f36
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_gammaf_r.c
@@ -0,0 +1,56 @@
+/* Implementation of gamma function according to ISO C.
+ Copyright (C) 1997, 1999, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_private.h>
+
+
+float
+__ieee754_gammaf_r (float x, int *signgamp)
+{
+ /* We don't have a real gamma implementation now. We'll use lgamma
+ and the exp function. But due to the required boundary
+ conditions we must check some values separately. */
+ int32_t hx;
+
+ GET_FLOAT_WORD (hx, x);
+
+ if ((hx & 0x7fffffff) == 0)
+ {
+ /* Return value for x == 0 is Inf with divide by zero exception. */
+ *signgamp = 0;
+ return 1.0 / x;
+ }
+ if (hx < 0 && (u_int32_t) hx < 0xff800000 && __rintf (x) == x)
+ {
+ /* Return value for integer x < 0 is NaN with invalid exception. */
+ *signgamp = 0;
+ return (x - x) / (x - x);
+ }
+ if (hx == 0xff800000)
+ {
+ /* x == -Inf. According to ISO this is NaN. */
+ *signgamp = 0;
+ return x - x;
+ }
+
+ /* XXX FIXME. */
+ return __ieee754_expf (__ieee754_lgammaf_r (x, signgamp));
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_hypotf.c b/libc/sysdeps/ieee754/flt-32/e_hypotf.c
new file mode 100644
index 000000000..a8e1a52d2
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_hypotf.c
@@ -0,0 +1,87 @@
+/* e_hypotf.c -- float version of e_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: e_hypotf.c,v 1.5 1995/05/12 04:57:30 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float __ieee754_hypotf(float x, float y)
+#else
+ float __ieee754_hypotf(x,y)
+ float x, y;
+#endif
+{
+ float a,b,t1,t2,y1,y2,w;
+ int32_t j,k,ha,hb;
+
+ GET_FLOAT_WORD(ha,x);
+ ha &= 0x7fffffff;
+ GET_FLOAT_WORD(hb,y);
+ hb &= 0x7fffffff;
+ if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
+ SET_FLOAT_WORD(a,ha); /* a <- |a| */
+ SET_FLOAT_WORD(b,hb); /* b <- |b| */
+ if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */
+ k=0;
+ if(ha > 0x58800000) { /* a>2**50 */
+ if(ha >= 0x7f800000) { /* Inf or NaN */
+ w = a+b; /* for sNaN */
+ if(ha == 0x7f800000) w = a;
+ if(hb == 0x7f800000) w = b;
+ return w;
+ }
+ /* scale a and b by 2**-60 */
+ ha -= 0x1e000000; hb -= 0x1e000000; k += 60;
+ SET_FLOAT_WORD(a,ha);
+ SET_FLOAT_WORD(b,hb);
+ }
+ if(hb < 0x26800000) { /* b < 2**-50 */
+ if(hb <= 0x007fffff) { /* subnormal b or 0 */
+ if(hb==0) return a;
+ SET_FLOAT_WORD(t1,0x7e800000); /* t1=2^126 */
+ b *= t1;
+ a *= t1;
+ k -= 126;
+ } else { /* scale a and b by 2^60 */
+ ha += 0x1e000000; /* a *= 2^60 */
+ hb += 0x1e000000; /* b *= 2^60 */
+ k -= 60;
+ SET_FLOAT_WORD(a,ha);
+ SET_FLOAT_WORD(b,hb);
+ }
+ }
+ /* medium size a and b */
+ w = a-b;
+ if (w>b) {
+ SET_FLOAT_WORD(t1,ha&0xfffff000);
+ t2 = a-t1;
+ w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
+ } else {
+ a = a+a;
+ SET_FLOAT_WORD(y1,hb&0xfffff000);
+ y2 = b - y1;
+ SET_FLOAT_WORD(t1,ha+0x00800000);
+ t2 = a - t1;
+ w = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
+ }
+ if(k!=0) {
+ SET_FLOAT_WORD(t1,0x3f800000+(k<<23));
+ return t1*w;
+ } else return w;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_j0f.c b/libc/sysdeps/ieee754/flt-32/e_j0f.c
new file mode 100644
index 000000000..8c499e614
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_j0f.c
@@ -0,0 +1,442 @@
+/* e_j0f.c -- float version of e_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: e_j0f.c,v 1.4 1995/05/10 20:45:25 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static float pzerof(float), qzerof(float);
+#else
+static float pzerof(), qzerof();
+#endif
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+huge = 1e30,
+one = 1.0,
+invsqrtpi= 5.6418961287e-01, /* 0x3f106ebb */
+tpi = 6.3661974669e-01, /* 0x3f22f983 */
+ /* R0/S0 on [0, 2.00] */
+R02 = 1.5625000000e-02, /* 0x3c800000 */
+R03 = -1.8997929874e-04, /* 0xb947352e */
+R04 = 1.8295404516e-06, /* 0x35f58e88 */
+R05 = -4.6183270541e-09, /* 0xb19eaf3c */
+S01 = 1.5619102865e-02, /* 0x3c7fe744 */
+S02 = 1.1692678527e-04, /* 0x38f53697 */
+S03 = 5.1354652442e-07, /* 0x3509daa6 */
+S04 = 1.1661400734e-09; /* 0x30a045e8 */
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_j0f(float x)
+#else
+ float __ieee754_j0f(x)
+ float x;
+#endif
+{
+ float z, s,c,ss,cc,r,u,v;
+ int32_t hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7f800000) return one/(x*x);
+ x = fabsf(x);
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ __sincosf (x, &s, &c);
+ ss = s-c;
+ cc = s+c;
+ if(ix<0x7f000000) { /* make sure x+x not overflow */
+ z = -__cosf(x+x);
+ if ((s*c)<zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /*
+ * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+ * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+ */
+ if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrtf(x);
+ else {
+ u = pzerof(x); v = qzerof(x);
+ z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrtf(x);
+ }
+ return z;
+ }
+ if(ix<0x39000000) { /* |x| < 2**-13 */
+ if(huge+x>one) { /* raise inexact if x != 0 */
+ if(ix<0x32000000) return one; /* |x|<2**-27 */
+ else return one - (float)0.25*x*x;
+ }
+ }
+ z = x*x;
+ r = z*(R02+z*(R03+z*(R04+z*R05)));
+ s = one+z*(S01+z*(S02+z*(S03+z*S04)));
+ if(ix < 0x3F800000) { /* |x| < 1.00 */
+ return one + z*((float)-0.25+(r/s));
+ } else {
+ u = (float)0.5*x;
+ return((one+u)*(one-u)+z*(r/s));
+ }
+}
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+u00 = -7.3804296553e-02, /* 0xbd9726b5 */
+u01 = 1.7666645348e-01, /* 0x3e34e80d */
+u02 = -1.3818567619e-02, /* 0xbc626746 */
+u03 = 3.4745343146e-04, /* 0x39b62a69 */
+u04 = -3.8140706238e-06, /* 0xb67ff53c */
+u05 = 1.9559013964e-08, /* 0x32a802ba */
+u06 = -3.9820518410e-11, /* 0xae2f21eb */
+v01 = 1.2730483897e-02, /* 0x3c509385 */
+v02 = 7.6006865129e-05, /* 0x389f65e0 */
+v03 = 2.5915085189e-07, /* 0x348b216c */
+v04 = 4.4111031494e-10; /* 0x2ff280c2 */
+
+#ifdef __STDC__
+ float __ieee754_y0f(float x)
+#else
+ float __ieee754_y0f(x)
+ float x;
+#endif
+{
+ float z, s,c,ss,cc,u,v;
+ int32_t hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = 0x7fffffff&hx;
+ /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0, y0(0) is -inf. */
+ if(ix>=0x7f800000) return one/(x+x*x);
+ if(ix==0) return -HUGE_VALF+x; /* -inf and overflow exception. */
+ if(hx<0) return zero/(zero*x);
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
+ * where x0 = x-pi/4
+ * Better formula:
+ * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+ * = 1/sqrt(2) * (sin(x) + cos(x))
+ * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.
+ */
+ __sincosf (x, &s, &c);
+ ss = s-c;
+ cc = s+c;
+ /*
+ * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+ * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+ */
+ if(ix<0x7f000000) { /* make sure x+x not overflow */
+ z = -__cosf(x+x);
+ if ((s*c)<zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrtf(x);
+ else {
+ u = pzerof(x); v = qzerof(x);
+ z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrtf(x);
+ }
+ return z;
+ }
+ if(ix<=0x32000000) { /* x < 2**-27 */
+ return(u00 + tpi*__ieee754_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)));
+}
+
+/* The asymptotic expansions of pzero is
+ * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x.
+ * For x >= 2, We approximate pzero by
+ * pzero(x) = 1 + (R/S)
+ * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10
+ * S = 1 + pS0*s^2 + ... + pS4*s^10
+ * and
+ * | pzero(x)-1-R/S | <= 2 ** ( -60.26)
+ */
+#ifdef __STDC__
+static const float pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static float pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.0000000000e+00, /* 0x00000000 */
+ -7.0312500000e-02, /* 0xbd900000 */
+ -8.0816707611e+00, /* 0xc1014e86 */
+ -2.5706311035e+02, /* 0xc3808814 */
+ -2.4852163086e+03, /* 0xc51b5376 */
+ -5.2530439453e+03, /* 0xc5a4285a */
+};
+#ifdef __STDC__
+static const float pS8[5] = {
+#else
+static float pS8[5] = {
+#endif
+ 1.1653436279e+02, /* 0x42e91198 */
+ 3.8337448730e+03, /* 0x456f9beb */
+ 4.0597855469e+04, /* 0x471e95db */
+ 1.1675296875e+05, /* 0x47e4087c */
+ 4.7627726562e+04, /* 0x473a0bba */
+};
+#ifdef __STDC__
+static const float pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static float pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ -1.1412546255e-11, /* 0xad48c58a */
+ -7.0312492549e-02, /* 0xbd8fffff */
+ -4.1596107483e+00, /* 0xc0851b88 */
+ -6.7674766541e+01, /* 0xc287597b */
+ -3.3123129272e+02, /* 0xc3a59d9b */
+ -3.4643338013e+02, /* 0xc3ad3779 */
+};
+#ifdef __STDC__
+static const float pS5[5] = {
+#else
+static float pS5[5] = {
+#endif
+ 6.0753936768e+01, /* 0x42730408 */
+ 1.0512523193e+03, /* 0x44836813 */
+ 5.9789707031e+03, /* 0x45bad7c4 */
+ 9.6254453125e+03, /* 0x461665c8 */
+ 2.4060581055e+03, /* 0x451660ee */
+};
+
+#ifdef __STDC__
+static const float pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#else
+static float pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ -2.5470459075e-09, /* 0xb12f081b */
+ -7.0311963558e-02, /* 0xbd8fffb8 */
+ -2.4090321064e+00, /* 0xc01a2d95 */
+ -2.1965976715e+01, /* 0xc1afba52 */
+ -5.8079170227e+01, /* 0xc2685112 */
+ -3.1447946548e+01, /* 0xc1fb9565 */
+};
+#ifdef __STDC__
+static const float pS3[5] = {
+#else
+static float pS3[5] = {
+#endif
+ 3.5856033325e+01, /* 0x420f6c94 */
+ 3.6151397705e+02, /* 0x43b4c1ca */
+ 1.1936077881e+03, /* 0x44953373 */
+ 1.1279968262e+03, /* 0x448cffe6 */
+ 1.7358093262e+02, /* 0x432d94b8 */
+};
+
+#ifdef __STDC__
+static const float pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static float pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ -8.8753431271e-08, /* 0xb3be98b7 */
+ -7.0303097367e-02, /* 0xbd8ffb12 */
+ -1.4507384300e+00, /* 0xbfb9b1cc */
+ -7.6356959343e+00, /* 0xc0f4579f */
+ -1.1193166733e+01, /* 0xc1331736 */
+ -3.2336456776e+00, /* 0xc04ef40d */
+};
+#ifdef __STDC__
+static const float pS2[5] = {
+#else
+static float pS2[5] = {
+#endif
+ 2.2220300674e+01, /* 0x41b1c32d */
+ 1.3620678711e+02, /* 0x430834f0 */
+ 2.7047027588e+02, /* 0x43873c32 */
+ 1.5387539673e+02, /* 0x4319e01a */
+ 1.4657617569e+01, /* 0x416a859a */
+};
+
+#ifdef __STDC__
+ static float pzerof(float x)
+#else
+ static float pzerof(x)
+ float x;
+#endif
+{
+#ifdef __STDC__
+ const float *p,*q;
+#else
+ float *p,*q;
+#endif
+ float z,r,s;
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x41000000) {p = pR8; q= pS8;}
+ else if(ix>=0x40f71c58){p = pR5; q= pS5;}
+ else if(ix>=0x4036db68){p = pR3; q= pS3;}
+ else if(ix>=0x40000000){p = pR2; q= pS2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+ return one+ r/s;
+}
+
+
+/* For x >= 8, the asymptotic expansions of qzero is
+ * -1/8 s + 75/1024 s^3 - ..., where s = 1/x.
+ * We approximate pzero by
+ * qzero(x) = s*(-1.25 + (R/S))
+ * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10
+ * S = 1 + qS0*s^2 + ... + qS5*s^12
+ * and
+ * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22)
+ */
+#ifdef __STDC__
+static const float qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static float qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.0000000000e+00, /* 0x00000000 */
+ 7.3242187500e-02, /* 0x3d960000 */
+ 1.1768206596e+01, /* 0x413c4a93 */
+ 5.5767340088e+02, /* 0x440b6b19 */
+ 8.8591972656e+03, /* 0x460a6cca */
+ 3.7014625000e+04, /* 0x471096a0 */
+};
+#ifdef __STDC__
+static const float qS8[6] = {
+#else
+static float qS8[6] = {
+#endif
+ 1.6377603149e+02, /* 0x4323c6aa */
+ 8.0983447266e+03, /* 0x45fd12c2 */
+ 1.4253829688e+05, /* 0x480b3293 */
+ 8.0330925000e+05, /* 0x49441ed4 */
+ 8.4050156250e+05, /* 0x494d3359 */
+ -3.4389928125e+05, /* 0xc8a7eb69 */
+};
+
+#ifdef __STDC__
+static const float qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static float qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ 1.8408595828e-11, /* 0x2da1ec79 */
+ 7.3242180049e-02, /* 0x3d95ffff */
+ 5.8356351852e+00, /* 0x40babd86 */
+ 1.3511157227e+02, /* 0x43071c90 */
+ 1.0272437744e+03, /* 0x448067cd */
+ 1.9899779053e+03, /* 0x44f8bf4b */
+};
+#ifdef __STDC__
+static const float qS5[6] = {
+#else
+static float qS5[6] = {
+#endif
+ 8.2776611328e+01, /* 0x42a58da0 */
+ 2.0778142090e+03, /* 0x4501dd07 */
+ 1.8847289062e+04, /* 0x46933e94 */
+ 5.6751113281e+04, /* 0x475daf1d */
+ 3.5976753906e+04, /* 0x470c88c1 */
+ -5.3543427734e+03, /* 0xc5a752be */
+};
+
+#ifdef __STDC__
+static const float qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#else
+static float qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ 4.3774099900e-09, /* 0x3196681b */
+ 7.3241114616e-02, /* 0x3d95ff70 */
+ 3.3442313671e+00, /* 0x405607e3 */
+ 4.2621845245e+01, /* 0x422a7cc5 */
+ 1.7080809021e+02, /* 0x432acedf */
+ 1.6673394775e+02, /* 0x4326bbe4 */
+};
+#ifdef __STDC__
+static const float qS3[6] = {
+#else
+static float qS3[6] = {
+#endif
+ 4.8758872986e+01, /* 0x42430916 */
+ 7.0968920898e+02, /* 0x44316c1c */
+ 3.7041481934e+03, /* 0x4567825f */
+ 6.4604252930e+03, /* 0x45c9e367 */
+ 2.5163337402e+03, /* 0x451d4557 */
+ -1.4924745178e+02, /* 0xc3153f59 */
+};
+
+#ifdef __STDC__
+static const float qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static float qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ 1.5044444979e-07, /* 0x342189db */
+ 7.3223426938e-02, /* 0x3d95f62a */
+ 1.9981917143e+00, /* 0x3fffc4bf */
+ 1.4495602608e+01, /* 0x4167edfd */
+ 3.1666231155e+01, /* 0x41fd5471 */
+ 1.6252708435e+01, /* 0x4182058c */
+};
+#ifdef __STDC__
+static const float qS2[6] = {
+#else
+static float qS2[6] = {
+#endif
+ 3.0365585327e+01, /* 0x41f2ecb8 */
+ 2.6934811401e+02, /* 0x4386ac8f */
+ 8.4478375244e+02, /* 0x44533229 */
+ 8.8293585205e+02, /* 0x445cbbe5 */
+ 2.1266638184e+02, /* 0x4354aa98 */
+ -5.3109550476e+00, /* 0xc0a9f358 */
+};
+
+#ifdef __STDC__
+ static float qzerof(float x)
+#else
+ static float qzerof(x)
+ float x;
+#endif
+{
+#ifdef __STDC__
+ const float *p,*q;
+#else
+ float *p,*q;
+#endif
+ float s,r,z;
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x41000000) {p = qR8; q= qS8;}
+ else if(ix>=0x40f71c58){p = qR5; q= qS5;}
+ else if(ix>=0x4036db68){p = qR3; q= qS3;}
+ else if(ix>=0x40000000){p = qR2; q= qS2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+ return (-(float).125 + r/s)/x;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_j1f.c b/libc/sysdeps/ieee754/flt-32/e_j1f.c
new file mode 100644
index 000000000..71bb2515a
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_j1f.c
@@ -0,0 +1,442 @@
+/* e_j1f.c -- float version of e_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: e_j1f.c,v 1.4 1995/05/10 20:45:31 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static float ponef(float), qonef(float);
+#else
+static float ponef(), qonef();
+#endif
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+huge = 1e30,
+one = 1.0,
+invsqrtpi= 5.6418961287e-01, /* 0x3f106ebb */
+tpi = 6.3661974669e-01, /* 0x3f22f983 */
+ /* R0/S0 on [0,2] */
+r00 = -6.2500000000e-02, /* 0xbd800000 */
+r01 = 1.4070566976e-03, /* 0x3ab86cfd */
+r02 = -1.5995563444e-05, /* 0xb7862e36 */
+r03 = 4.9672799207e-08, /* 0x335557d2 */
+s01 = 1.9153760746e-02, /* 0x3c9ce859 */
+s02 = 1.8594678841e-04, /* 0x3942fab6 */
+s03 = 1.1771846857e-06, /* 0x359dffc2 */
+s04 = 5.0463624390e-09, /* 0x31ad6446 */
+s05 = 1.2354227016e-11; /* 0x2d59567e */
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_j1f(float x)
+#else
+ float __ieee754_j1f(x)
+ float x;
+#endif
+{
+ float z, s,c,ss,cc,r,u,v,y;
+ int32_t hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7f800000) return one/x;
+ y = fabsf(x);
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ __sincosf (y, &s, &c);
+ ss = -s-c;
+ cc = s-c;
+ if(ix<0x7f000000) { /* make sure y+y not overflow */
+ z = __cosf(y+y);
+ if ((s*c)>zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /*
+ * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
+ * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
+ */
+ if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrtf(y);
+ else {
+ u = ponef(y); v = qonef(y);
+ z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrtf(y);
+ }
+ if(hx<0) return -z;
+ else return z;
+ }
+ if(ix<0x32000000) { /* |x|<2**-27 */
+ if(huge+x>one) return (float)0.5*x;/* inexact if x!=0 necessary */
+ }
+ z = x*x;
+ r = z*(r00+z*(r01+z*(r02+z*r03)));
+ s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
+ r *= x;
+ return(x*(float)0.5+r/s);
+}
+
+#ifdef __STDC__
+static const float U0[5] = {
+#else
+static float U0[5] = {
+#endif
+ -1.9605709612e-01, /* 0xbe48c331 */
+ 5.0443872809e-02, /* 0x3d4e9e3c */
+ -1.9125689287e-03, /* 0xbafaaf2a */
+ 2.3525259166e-05, /* 0x37c5581c */
+ -9.1909917899e-08, /* 0xb3c56003 */
+};
+#ifdef __STDC__
+static const float V0[5] = {
+#else
+static float V0[5] = {
+#endif
+ 1.9916731864e-02, /* 0x3ca3286a */
+ 2.0255257550e-04, /* 0x3954644b */
+ 1.3560879779e-06, /* 0x35b602d4 */
+ 6.2274145840e-09, /* 0x31d5f8eb */
+ 1.6655924903e-11, /* 0x2d9281cf */
+};
+
+#ifdef __STDC__
+ float __ieee754_y1f(float x)
+#else
+ float __ieee754_y1f(x)
+ float x;
+#endif
+{
+ float z, s,c,ss,cc,u,v;
+ int32_t hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = 0x7fffffff&hx;
+ /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
+ if(ix>=0x7f800000) return one/(x+x*x);
+ if(ix==0) return -HUGE_VALF+x; /* -inf and overflow exception. */
+ if(hx<0) return zero/(zero*x);
+ if(ix >= 0x40000000) { /* |x| >= 2.0 */
+ __sincosf (x, &s, &c);
+ ss = -s-c;
+ cc = s-c;
+ if(ix<0x7f000000) { /* make sure x+x not overflow */
+ z = __cosf(x+x);
+ if ((s*c)>zero) cc = z/ss;
+ else ss = z/cc;
+ }
+ /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0))
+ * where x0 = x-3pi/4
+ * Better formula:
+ * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = -1/sqrt(2) * (cos(x) + sin(x))
+ * To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.
+ */
+ if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrtf(x);
+ else {
+ u = ponef(x); v = qonef(x);
+ z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrtf(x);
+ }
+ return z;
+ }
+ if(ix<=0x24800000) { /* x < 2**-54 */
+ return(-tpi/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));
+}
+
+/* For x >= 8, the asymptotic expansions of pone is
+ * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x.
+ * We approximate pone by
+ * pone(x) = 1 + (R/S)
+ * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10
+ * S = 1 + ps0*s^2 + ... + ps4*s^10
+ * and
+ * | pone(x)-1-R/S | <= 2 ** ( -60.06)
+ */
+
+#ifdef __STDC__
+static const float pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static float pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.0000000000e+00, /* 0x00000000 */
+ 1.1718750000e-01, /* 0x3df00000 */
+ 1.3239480972e+01, /* 0x4153d4ea */
+ 4.1205184937e+02, /* 0x43ce06a3 */
+ 3.8747453613e+03, /* 0x45722bed */
+ 7.9144794922e+03, /* 0x45f753d6 */
+};
+#ifdef __STDC__
+static const float ps8[5] = {
+#else
+static float ps8[5] = {
+#endif
+ 1.1420736694e+02, /* 0x42e46a2c */
+ 3.6509309082e+03, /* 0x45642ee5 */
+ 3.6956207031e+04, /* 0x47105c35 */
+ 9.7602796875e+04, /* 0x47bea166 */
+ 3.0804271484e+04, /* 0x46f0a88b */
+};
+
+#ifdef __STDC__
+static const float pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static float pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ 1.3199052094e-11, /* 0x2d68333f */
+ 1.1718749255e-01, /* 0x3defffff */
+ 6.8027510643e+00, /* 0x40d9b023 */
+ 1.0830818176e+02, /* 0x42d89dca */
+ 5.1763616943e+02, /* 0x440168b7 */
+ 5.2871520996e+02, /* 0x44042dc6 */
+};
+#ifdef __STDC__
+static const float ps5[5] = {
+#else
+static float ps5[5] = {
+#endif
+ 5.9280597687e+01, /* 0x426d1f55 */
+ 9.9140142822e+02, /* 0x4477d9b1 */
+ 5.3532670898e+03, /* 0x45a74a23 */
+ 7.8446904297e+03, /* 0x45f52586 */
+ 1.5040468750e+03, /* 0x44bc0180 */
+};
+
+#ifdef __STDC__
+static const float pr3[6] = {
+#else
+static float pr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ 3.0250391081e-09, /* 0x314fe10d */
+ 1.1718686670e-01, /* 0x3defffab */
+ 3.9329774380e+00, /* 0x407bb5e7 */
+ 3.5119403839e+01, /* 0x420c7a45 */
+ 9.1055007935e+01, /* 0x42b61c2a */
+ 4.8559066772e+01, /* 0x42423c7c */
+};
+#ifdef __STDC__
+static const float ps3[5] = {
+#else
+static float ps3[5] = {
+#endif
+ 3.4791309357e+01, /* 0x420b2a4d */
+ 3.3676245117e+02, /* 0x43a86198 */
+ 1.0468714600e+03, /* 0x4482dbe3 */
+ 8.9081134033e+02, /* 0x445eb3ed */
+ 1.0378793335e+02, /* 0x42cf936c */
+};
+
+#ifdef __STDC__
+static const float pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static float pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ 1.0771083225e-07, /* 0x33e74ea8 */
+ 1.1717621982e-01, /* 0x3deffa16 */
+ 2.3685150146e+00, /* 0x401795c0 */
+ 1.2242610931e+01, /* 0x4143e1bc */
+ 1.7693971634e+01, /* 0x418d8d41 */
+ 5.0735230446e+00, /* 0x40a25a4d */
+};
+#ifdef __STDC__
+static const float ps2[5] = {
+#else
+static float ps2[5] = {
+#endif
+ 2.1436485291e+01, /* 0x41ab7dec */
+ 1.2529022980e+02, /* 0x42fa9499 */
+ 2.3227647400e+02, /* 0x436846c7 */
+ 1.1767937469e+02, /* 0x42eb5bd7 */
+ 8.3646392822e+00, /* 0x4105d590 */
+};
+
+#ifdef __STDC__
+ static float ponef(float x)
+#else
+ static float ponef(x)
+ float x;
+#endif
+{
+#ifdef __STDC__
+ const float *p,*q;
+#else
+ float *p,*q;
+#endif
+ float z,r,s;
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x41000000) {p = pr8; q= ps8;}
+ else if(ix>=0x40f71c58){p = pr5; q= ps5;}
+ else if(ix>=0x4036db68){p = pr3; q= ps3;}
+ else if(ix>=0x40000000){p = pr2; q= ps2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+ return one+ r/s;
+}
+
+
+/* For x >= 8, the asymptotic expansions of qone is
+ * 3/8 s - 105/1024 s^3 - ..., where s = 1/x.
+ * We approximate pone by
+ * qone(x) = s*(0.375 + (R/S))
+ * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10
+ * S = 1 + qs1*s^2 + ... + qs6*s^12
+ * and
+ * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13)
+ */
+
+#ifdef __STDC__
+static const float qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static float qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+ 0.0000000000e+00, /* 0x00000000 */
+ -1.0253906250e-01, /* 0xbdd20000 */
+ -1.6271753311e+01, /* 0xc1822c8d */
+ -7.5960174561e+02, /* 0xc43de683 */
+ -1.1849806641e+04, /* 0xc639273a */
+ -4.8438511719e+04, /* 0xc73d3683 */
+};
+#ifdef __STDC__
+static const float qs8[6] = {
+#else
+static float qs8[6] = {
+#endif
+ 1.6139537048e+02, /* 0x43216537 */
+ 7.8253862305e+03, /* 0x45f48b17 */
+ 1.3387534375e+05, /* 0x4802bcd6 */
+ 7.1965775000e+05, /* 0x492fb29c */
+ 6.6660125000e+05, /* 0x4922be94 */
+ -2.9449025000e+05, /* 0xc88fcb48 */
+};
+
+#ifdef __STDC__
+static const float qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static float qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ -2.0897993405e-11, /* 0xadb7d219 */
+ -1.0253904760e-01, /* 0xbdd1fffe */
+ -8.0564479828e+00, /* 0xc100e736 */
+ -1.8366960144e+02, /* 0xc337ab6b */
+ -1.3731937256e+03, /* 0xc4aba633 */
+ -2.6124443359e+03, /* 0xc523471c */
+};
+#ifdef __STDC__
+static const float qs5[6] = {
+#else
+static float qs5[6] = {
+#endif
+ 8.1276550293e+01, /* 0x42a28d98 */
+ 1.9917987061e+03, /* 0x44f8f98f */
+ 1.7468484375e+04, /* 0x468878f8 */
+ 4.9851425781e+04, /* 0x4742bb6d */
+ 2.7948074219e+04, /* 0x46da5826 */
+ -4.7191835938e+03, /* 0xc5937978 */
+};
+
+#ifdef __STDC__
+static const float qr3[6] = {
+#else
+static float qr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ -5.0783124372e-09, /* 0xb1ae7d4f */
+ -1.0253783315e-01, /* 0xbdd1ff5b */
+ -4.6101160049e+00, /* 0xc0938612 */
+ -5.7847221375e+01, /* 0xc267638e */
+ -2.2824453735e+02, /* 0xc3643e9a */
+ -2.1921012878e+02, /* 0xc35b35cb */
+};
+#ifdef __STDC__
+static const float qs3[6] = {
+#else
+static float qs3[6] = {
+#endif
+ 4.7665153503e+01, /* 0x423ea91e */
+ 6.7386511230e+02, /* 0x4428775e */
+ 3.3801528320e+03, /* 0x45534272 */
+ 5.5477290039e+03, /* 0x45ad5dd5 */
+ 1.9031191406e+03, /* 0x44ede3d0 */
+ -1.3520118713e+02, /* 0xc3073381 */
+};
+
+#ifdef __STDC__
+static const float qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static float qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ -1.7838172539e-07, /* 0xb43f8932 */
+ -1.0251704603e-01, /* 0xbdd1f475 */
+ -2.7522056103e+00, /* 0xc0302423 */
+ -1.9663616180e+01, /* 0xc19d4f16 */
+ -4.2325313568e+01, /* 0xc2294d1f */
+ -2.1371921539e+01, /* 0xc1aaf9b2 */
+};
+#ifdef __STDC__
+static const float qs2[6] = {
+#else
+static float qs2[6] = {
+#endif
+ 2.9533363342e+01, /* 0x41ec4454 */
+ 2.5298155212e+02, /* 0x437cfb47 */
+ 7.5750280762e+02, /* 0x443d602e */
+ 7.3939318848e+02, /* 0x4438d92a */
+ 1.5594900513e+02, /* 0x431bf2f2 */
+ -4.9594988823e+00, /* 0xc09eb437 */
+};
+
+#ifdef __STDC__
+ static float qonef(float x)
+#else
+ static float qonef(x)
+ float x;
+#endif
+{
+#ifdef __STDC__
+ const float *p,*q;
+#else
+ float *p,*q;
+#endif
+ float s,r,z;
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+ if(ix>=0x40200000) {p = qr8; q= qs8;}
+ else if(ix>=0x40f71c58){p = qr5; q= qs5;}
+ else if(ix>=0x4036db68){p = qr3; q= qs3;}
+ else if(ix>=0x40000000){p = qr2; q= qs2;}
+ z = one/(x*x);
+ r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+ s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+ return ((float).375 + r/s)/x;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_jnf.c b/libc/sysdeps/ieee754/flt-32/e_jnf.c
new file mode 100644
index 000000000..de2e53de8
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_jnf.c
@@ -0,0 +1,212 @@
+/* e_jnf.c -- float version of e_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: e_jnf.c,v 1.5 1995/05/10 20:45:37 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+two = 2.0000000000e+00, /* 0x40000000 */
+one = 1.0000000000e+00; /* 0x3F800000 */
+
+#ifdef __STDC__
+static const float zero = 0.0000000000e+00;
+#else
+static float zero = 0.0000000000e+00;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_jnf(int n, float x)
+#else
+ float __ieee754_jnf(n,x)
+ int n; float x;
+#endif
+{
+ int32_t i,hx,ix, sgn;
+ float a, b, temp, di;
+ float z, w;
+
+ /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
+ * Thus, J(-n,x) = J(n,-x)
+ */
+ GET_FLOAT_WORD(hx,x);
+ ix = 0x7fffffff&hx;
+ /* if J(n,NaN) is NaN */
+ if(ix>0x7f800000) return x+x;
+ if(n<0){
+ n = -n;
+ x = -x;
+ hx ^= 0x80000000;
+ }
+ if(n==0) return(__ieee754_j0f(x));
+ if(n==1) return(__ieee754_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);
+ for(i=1;i<n;i++){
+ temp = b;
+ b = b*((float)(i+i)/x) - a; /* avoid underflow */
+ a = temp;
+ }
+ } else {
+ if(ix<0x30800000) { /* x < 2**-29 */
+ /* x is tiny, return the first Taylor expansion of J(n,x)
+ * J(n,x) = 1/n!*(x/2)^n - ...
+ */
+ if(n>33) /* underflow */
+ b = zero;
+ else {
+ temp = x*(float)0.5; b = temp;
+ for (a=one,i=2;i<=n;i++) {
+ a *= (float)i; /* a = n! */
+ b *= temp; /* b = (x/2)^n */
+ }
+ b = b/a;
+ }
+ } else {
+ /* use backward recurrence */
+ /* x x^2 x^2
+ * J(n,x)/J(n-1,x) = ---- ------ ------ .....
+ * 2n - 2(n+1) - 2(n+2)
+ *
+ * 1 1 1
+ * (for large x) = ---- ------ ------ .....
+ * 2n 2(n+1) 2(n+2)
+ * -- - ------ - ------ -
+ * x x x
+ *
+ * Let w = 2n/x and h=2/x, then the above quotient
+ * is equal to the continued fraction:
+ * 1
+ * = -----------------------
+ * 1
+ * w - -----------------
+ * 1
+ * w+h - ---------
+ * w+2h - ...
+ *
+ * To determine how many terms needed, let
+ * Q(0) = w, Q(1) = w(w+h) - 1,
+ * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
+ * When Q(k) > 1e4 good for single
+ * When Q(k) > 1e9 good for double
+ * When Q(k) > 1e17 good for quadruple
+ */
+ /* determine k */
+ float t,v;
+ float q0,q1,h,tmp; int32_t k,m;
+ w = (n+n)/(float)x; h = (float)2.0/(float)x;
+ q0 = w; z = w+h; q1 = w*z - (float)1.0; k=1;
+ while(q1<(float)1.0e9) {
+ k += 1; z += h;
+ tmp = z*q1 - q0;
+ q0 = q1;
+ q1 = tmp;
+ }
+ m = n+n;
+ for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t);
+ a = t;
+ b = one;
+ /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
+ * Hence, if n*(log(2n/x)) > ...
+ * single 8.8722839355e+01
+ * double 7.09782712893383973096e+02
+ * long double 1.1356523406294143949491931077970765006170e+04
+ * then recurrent value may overflow and the result is
+ * likely underflow to zero
+ */
+ tmp = n;
+ v = two/x;
+ tmp = tmp*__ieee754_logf(fabsf(v*tmp));
+ if(tmp<(float)8.8721679688e+01) {
+ for(i=n-1,di=(float)(i+i);i>0;i--){
+ temp = b;
+ b *= di;
+ b = b/x - a;
+ a = temp;
+ di -= two;
+ }
+ } else {
+ for(i=n-1,di=(float)(i+i);i>0;i--){
+ temp = b;
+ b *= di;
+ b = b/x - a;
+ a = temp;
+ di -= two;
+ /* scale b to avoid spurious overflow */
+ if(b>(float)1e10) {
+ a /= b;
+ t /= b;
+ b = one;
+ }
+ }
+ }
+ b = (t*__ieee754_j0f(x)/b);
+ }
+ }
+ if(sgn==1) return -b; else return b;
+}
+
+#ifdef __STDC__
+ float __ieee754_ynf(int n, float x)
+#else
+ float __ieee754_ynf(n,x)
+ int n; float x;
+#endif
+{
+ int32_t i,hx,ix;
+ u_int32_t ib;
+ int32_t sign;
+ float a, b, temp;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = 0x7fffffff&hx;
+ /* if Y(n,NaN) is NaN */
+ if(ix>0x7f800000) return x+x;
+ if(ix==0) return -HUGE_VALF+x; /* -inf and overflow exception. */
+ if(hx<0) return zero/(zero*x);
+ sign = 1;
+ if(n<0){
+ n = -n;
+ sign = 1 - ((n&1)<<1);
+ }
+ if(n==0) return(__ieee754_y0f(x));
+ if(n==1) return(sign*__ieee754_y1f(x));
+ if(ix==0x7f800000) return zero;
+
+ a = __ieee754_y0f(x);
+ b = __ieee754_y1f(x);
+ /* quit if b is -inf */
+ GET_FLOAT_WORD(ib,b);
+ for(i=1;i<n&&ib!=0xff800000;i++){
+ temp = b;
+ b = ((float)(i+i)/x)*b - a;
+ GET_FLOAT_WORD(ib,b);
+ a = temp;
+ }
+ if(sign>0) return b; else return -b;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_lgammaf_r.c b/libc/sysdeps/ieee754/flt-32/e_lgammaf_r.c
new file mode 100644
index 000000000..5ebebb77a
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_lgammaf_r.c
@@ -0,0 +1,248 @@
+/* e_lgammaf_r.c -- float version of e_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: e_lgammaf_r.c,v 1.3 1995/05/10 20:45:47 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+two23= 8.3886080000e+06, /* 0x4b000000 */
+half= 5.0000000000e-01, /* 0x3f000000 */
+one = 1.0000000000e+00, /* 0x3f800000 */
+pi = 3.1415927410e+00, /* 0x40490fdb */
+a0 = 7.7215664089e-02, /* 0x3d9e233f */
+a1 = 3.2246702909e-01, /* 0x3ea51a66 */
+a2 = 6.7352302372e-02, /* 0x3d89f001 */
+a3 = 2.0580807701e-02, /* 0x3ca89915 */
+a4 = 7.3855509982e-03, /* 0x3bf2027e */
+a5 = 2.8905137442e-03, /* 0x3b3d6ec6 */
+a6 = 1.1927076848e-03, /* 0x3a9c54a1 */
+a7 = 5.1006977446e-04, /* 0x3a05b634 */
+a8 = 2.2086278477e-04, /* 0x39679767 */
+a9 = 1.0801156895e-04, /* 0x38e28445 */
+a10 = 2.5214456400e-05, /* 0x37d383a2 */
+a11 = 4.4864096708e-05, /* 0x383c2c75 */
+tc = 1.4616321325e+00, /* 0x3fbb16c3 */
+tf = -1.2148628384e-01, /* 0xbdf8cdcd */
+/* tt = -(tail of tf) */
+tt = 6.6971006518e-09, /* 0x31e61c52 */
+t0 = 4.8383611441e-01, /* 0x3ef7b95e */
+t1 = -1.4758771658e-01, /* 0xbe17213c */
+t2 = 6.4624942839e-02, /* 0x3d845a15 */
+t3 = -3.2788541168e-02, /* 0xbd064d47 */
+t4 = 1.7970675603e-02, /* 0x3c93373d */
+t5 = -1.0314224288e-02, /* 0xbc28fcfe */
+t6 = 6.1005386524e-03, /* 0x3bc7e707 */
+t7 = -3.6845202558e-03, /* 0xbb7177fe */
+t8 = 2.2596477065e-03, /* 0x3b141699 */
+t9 = -1.4034647029e-03, /* 0xbab7f476 */
+t10 = 8.8108185446e-04, /* 0x3a66f867 */
+t11 = -5.3859531181e-04, /* 0xba0d3085 */
+t12 = 3.1563205994e-04, /* 0x39a57b6b */
+t13 = -3.1275415677e-04, /* 0xb9a3f927 */
+t14 = 3.3552918467e-04, /* 0x39afe9f7 */
+u0 = -7.7215664089e-02, /* 0xbd9e233f */
+u1 = 6.3282704353e-01, /* 0x3f2200f4 */
+u2 = 1.4549225569e+00, /* 0x3fba3ae7 */
+u3 = 9.7771751881e-01, /* 0x3f7a4bb2 */
+u4 = 2.2896373272e-01, /* 0x3e6a7578 */
+u5 = 1.3381091878e-02, /* 0x3c5b3c5e */
+v1 = 2.4559779167e+00, /* 0x401d2ebe */
+v2 = 2.1284897327e+00, /* 0x4008392d */
+v3 = 7.6928514242e-01, /* 0x3f44efdf */
+v4 = 1.0422264785e-01, /* 0x3dd572af */
+v5 = 3.2170924824e-03, /* 0x3b52d5db */
+s0 = -7.7215664089e-02, /* 0xbd9e233f */
+s1 = 2.1498242021e-01, /* 0x3e5c245a */
+s2 = 3.2577878237e-01, /* 0x3ea6cc7a */
+s3 = 1.4635047317e-01, /* 0x3e15dce6 */
+s4 = 2.6642270386e-02, /* 0x3cda40e4 */
+s5 = 1.8402845599e-03, /* 0x3af135b4 */
+s6 = 3.1947532989e-05, /* 0x3805ff67 */
+r1 = 1.3920053244e+00, /* 0x3fb22d3b */
+r2 = 7.2193557024e-01, /* 0x3f38d0c5 */
+r3 = 1.7193385959e-01, /* 0x3e300f6e */
+r4 = 1.8645919859e-02, /* 0x3c98bf54 */
+r5 = 7.7794247773e-04, /* 0x3a4beed6 */
+r6 = 7.3266842264e-06, /* 0x36f5d7bd */
+w0 = 4.1893854737e-01, /* 0x3ed67f1d */
+w1 = 8.3333335817e-02, /* 0x3daaaaab */
+w2 = -2.7777778450e-03, /* 0xbb360b61 */
+w3 = 7.9365057172e-04, /* 0x3a500cfd */
+w4 = -5.9518753551e-04, /* 0xba1c065c */
+w5 = 8.3633989561e-04, /* 0x3a5b3dd2 */
+w6 = -1.6309292987e-03; /* 0xbad5c4e8 */
+
+#ifdef __STDC__
+static const float zero= 0.0000000000e+00;
+#else
+static float zero= 0.0000000000e+00;
+#endif
+
+#ifdef __STDC__
+ static float sin_pif(float x)
+#else
+ static float sin_pif(x)
+ float x;
+#endif
+{
+ float y,z;
+ int n,ix;
+
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+
+ if(ix<0x3e800000) return __kernel_sinf(pi*x,zero,0);
+ y = -x; /* x is assume negative */
+
+ /*
+ * argument reduction, make sure inexact flag not raised if input
+ * is an integer
+ */
+ z = __floorf(y);
+ if(z!=y) { /* inexact anyway */
+ y *= (float)0.5;
+ y = (float)2.0*(y - __floorf(y)); /* y = |x| mod 2.0 */
+ n = (int) (y*(float)4.0);
+ } else {
+ if(ix>=0x4b800000) {
+ y = zero; n = 0; /* y must be even */
+ } else {
+ if(ix<0x4b000000) z = y+two23; /* exact */
+ GET_FLOAT_WORD(n,z);
+ n &= 1;
+ y = n;
+ n<<= 2;
+ }
+ }
+ switch (n) {
+ case 0: y = __kernel_sinf(pi*y,zero,0); break;
+ case 1:
+ case 2: y = __kernel_cosf(pi*((float)0.5-y),zero); break;
+ case 3:
+ case 4: y = __kernel_sinf(pi*(one-y),zero,0); break;
+ case 5:
+ case 6: y = -__kernel_cosf(pi*(y-(float)1.5),zero); break;
+ default: y = __kernel_sinf(pi*(y-(float)2.0),zero,0); break;
+ }
+ return -y;
+}
+
+
+#ifdef __STDC__
+ float __ieee754_lgammaf_r(float x, int *signgamp)
+#else
+ float __ieee754_lgammaf_r(x,signgamp)
+ float x; int *signgamp;
+#endif
+{
+ float t,y,z,nadj,p,p1,p2,p3,q,r,w;
+ int i,hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+
+ /* purge off +-inf, NaN, +-0, and negative arguments */
+ *signgamp = 1;
+ ix = hx&0x7fffffff;
+ if(ix>=0x7f800000) return x*x;
+ if(ix==0) return one/fabsf(x);
+ if(ix<0x1c800000) { /* |x|<2**-70, return -log(|x|) */
+ if(hx<0) {
+ *signgamp = -1;
+ return -__ieee754_logf(-x);
+ } else return -__ieee754_logf(x);
+ }
+ if(hx<0) {
+ if(ix>=0x4b000000) /* |x|>=2**23, must be -integer */
+ return x/zero;
+ t = sin_pif(x);
+ if(t==zero) return one/fabsf(t); /* -integer */
+ nadj = __ieee754_logf(pi/fabsf(t*x));
+ if(t<zero) *signgamp = -1;
+ x = -x;
+ }
+
+ /* purge off 1 and 2 */
+ if (ix==0x3f800000||ix==0x40000000) r = 0;
+ /* for x < 2.0 */
+ else if(ix<0x40000000) {
+ if(ix<=0x3f666666) { /* lgamma(x) = lgamma(x+1)-log(x) */
+ r = -__ieee754_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;}
+ } else {
+ r = zero;
+ if(ix>=0x3fdda618) {y=(float)2.0-x;i=0;} /* [1.7316,2] */
+ else if(ix>=0x3F9da620) {y=x-tc;i=1;} /* [1.23,1.73] */
+ else {y=x-one;i=2;}
+ }
+ switch(i) {
+ case 0:
+ z = y*y;
+ p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
+ p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
+ p = y*p1+p2;
+ r += (p-(float)0.5*y); break;
+ case 1:
+ z = y*y;
+ w = z*y;
+ p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */
+ p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
+ p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
+ p = z*p1-(tt-w*(p2+y*p3));
+ r += (tf + p); break;
+ case 2:
+ p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
+ p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
+ r += (-(float)0.5*y + p1/p2);
+ }
+ }
+ else if(ix<0x41000000) { /* x < 8.0 */
+ i = (int)x;
+ t = zero;
+ y = x-(float)i;
+ p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
+ q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
+ r = half*y+p/q;
+ z = one; /* lgamma(1+s) = log(s) + lgamma(s) */
+ switch(i) {
+ case 7: z *= (y+(float)6.0); /* FALLTHRU */
+ case 6: z *= (y+(float)5.0); /* FALLTHRU */
+ 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;
+ }
+ /* 8.0 <= x < 2**58 */
+ } else if (ix < 0x5c800000) {
+ t = __ieee754_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);
+ if(hx<0) r = nadj - r;
+ return r;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_log10f.c b/libc/sysdeps/ieee754/flt-32/e_log10f.c
new file mode 100644
index 000000000..cea3d9156
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_log10f.c
@@ -0,0 +1,67 @@
+/* e_log10f.c -- float version of e_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: e_log10f.c,v 1.5 1995/05/10 20:45:53 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+two25 = 3.3554432000e+07, /* 0x4c000000 */
+ivln10 = 4.3429449201e-01, /* 0x3ede5bd9 */
+log10_2hi = 3.0102920532e-01, /* 0x3e9a2080 */
+log10_2lo = 7.9034151668e-07; /* 0x355427db */
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_log10f(float x)
+#else
+ float __ieee754_log10f(x)
+ float x;
+#endif
+{
+ float y,z;
+ int32_t i,k,hx;
+
+ GET_FLOAT_WORD(hx,x);
+
+ k=0;
+ if (hx < 0x00800000) { /* x < 2**-126 */
+ if ((hx&0x7fffffff)==0)
+ return -two25/(x-x); /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/(x-x); /* log(-#) = NaN */
+ k -= 25; x *= two25; /* subnormal number, scale up x */
+ GET_FLOAT_WORD(hx,x);
+ }
+ if (hx >= 0x7f800000) return x+x;
+ k += (hx>>23)-127;
+ i = ((u_int32_t)k&0x80000000)>>31;
+ hx = (hx&0x007fffff)|((0x7f-i)<<23);
+ y = (float)(k+i);
+ SET_FLOAT_WORD(x,hx);
+ z = y*log10_2lo + ivln10*__ieee754_logf(x);
+ return z+y*log10_2hi;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_log2f.c b/libc/sysdeps/ieee754/flt-32/e_log2f.c
new file mode 100644
index 000000000..af3c6eadf
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_log2f.c
@@ -0,0 +1,90 @@
+/* e_logf.c -- float version of e_log.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * adapted for log2 by Ulrich Drepper <drepper@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"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+ln2 = 0.69314718055994530942,
+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 */
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_log2f(float x)
+#else
+ float __ieee754_log2f(x)
+ float x;
+#endif
+{
+ 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/(x-x); /* log(+-0)=-inf */
+ if (ix<0) return (x-x)/(x-x); /* 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/libc/sysdeps/ieee754/flt-32/e_logf.c b/libc/sysdeps/ieee754/flt-32/e_logf.c
new file mode 100644
index 000000000..de8f869df
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_logf.c
@@ -0,0 +1,99 @@
+/* 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.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: e_logf.c,v 1.4 1995/05/10 20:45:54 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
+ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
+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 */
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_logf(float x)
+#else
+ float __ieee754_logf(x)
+ float x;
+#endif
+{
+ 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/(x-x); /* log(+-0)=-inf */
+ if (ix<0) return (x-x)/(x-x); /* 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);
+ f = x-(float)1.0;
+ if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */
+ if(f==zero) {
+ if(k==0) return zero; else {dk=(float)k;
+ return dk*ln2_hi+dk*ln2_lo;}
+ }
+ R = f*f*((float)0.5-(float)0.33333333333333333*f);
+ if(k==0) return f-R; else {dk=(float)k;
+ return dk*ln2_hi-((R-dk*ln2_lo)-f);}
+ }
+ s = f/((float)2.0+f);
+ dk = (float)k;
+ 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;
+ if(k==0) return f-(hfsq-s*(hfsq+R)); else
+ return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
+ } else {
+ if(k==0) return f-s*(f-R); else
+ return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
+ }
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_powf.c b/libc/sysdeps/ieee754/flt-32/e_powf.c
new file mode 100644
index 000000000..9f520804a
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_powf.c
@@ -0,0 +1,257 @@
+/* e_powf.c -- float version of e_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: e_powf.c,v 1.7 1996/04/08 15:43:44 phil Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+static const float huge = 1.0e+30, tiny = 1.0e-30;
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+bp[] = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */
+dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */
+zero = 0.0,
+one = 1.0,
+two = 2.0,
+two24 = 16777216.0, /* 0x4b800000 */
+ /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1 = 6.0000002384e-01, /* 0x3f19999a */
+L2 = 4.2857143283e-01, /* 0x3edb6db7 */
+L3 = 3.3333334327e-01, /* 0x3eaaaaab */
+L4 = 2.7272811532e-01, /* 0x3e8ba305 */
+L5 = 2.3066075146e-01, /* 0x3e6c3255 */
+L6 = 2.0697501302e-01, /* 0x3e53f142 */
+P1 = 1.6666667163e-01, /* 0x3e2aaaab */
+P2 = -2.7777778450e-03, /* 0xbb360b61 */
+P3 = 6.6137559770e-05, /* 0x388ab355 */
+P4 = -1.6533901999e-06, /* 0xb5ddea0e */
+P5 = 4.1381369442e-08, /* 0x3331bb4c */
+lg2 = 6.9314718246e-01, /* 0x3f317218 */
+lg2_h = 6.93145752e-01, /* 0x3f317200 */
+lg2_l = 1.42860654e-06, /* 0x35bfbe8c */
+ovt = 4.2995665694e-08, /* -(128-log2(ovfl+.5ulp)) */
+cp = 9.6179670095e-01, /* 0x3f76384f =2/(3ln2) */
+cp_h = 9.6179199219e-01, /* 0x3f763800 =head of cp */
+cp_l = 4.7017383622e-06, /* 0x369dc3a0 =tail of cp_h */
+ivln2 = 1.4426950216e+00, /* 0x3fb8aa3b =1/ln2 */
+ivln2_h = 1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/
+ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
+
+#ifdef __STDC__
+ float __ieee754_powf(float x, float y)
+#else
+ float __ieee754_powf(x,y)
+ float x, y;
+#endif
+{
+ float z,ax,z_h,z_l,p_h,p_l;
+ float y1,t1,t2,r,s,t,u,v,w;
+ int32_t i,j,k,yisint,n;
+ int32_t hx,hy,ix,iy,is;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_FLOAT_WORD(hy,y);
+ ix = hx&0x7fffffff; iy = hy&0x7fffffff;
+
+ /* y==zero: x**0 = 1 */
+ if(iy==0) return one;
+
+ /* x==+-1 */
+ if(x == 1.0) return one;
+ if(x == -1.0 && isinf(y)) return one;
+
+ /* +-NaN return x+y */
+ if(ix > 0x7f800000 ||
+ iy > 0x7f800000)
+ return x+y;
+
+ /* determine if y is an odd int when x < 0
+ * yisint = 0 ... y is not an integer
+ * yisint = 1 ... y is an odd int
+ * yisint = 2 ... y is an even int
+ */
+ yisint = 0;
+ if(hx<0) {
+ if(iy>=0x4b800000) yisint = 2; /* even integer y */
+ else if(iy>=0x3f800000) {
+ k = (iy>>23)-0x7f; /* exponent */
+ j = iy>>(23-k);
+ if((j<<(23-k))==iy) yisint = 2-(j&1);
+ }
+ }
+
+ /* special value of y */
+ if (iy==0x7f800000) { /* y is +-inf */
+ if (ix==0x3f800000)
+ return y - y; /* inf**+-1 is NaN */
+ else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */
+ return (hy>=0)? y: zero;
+ else /* (|x|<1)**-,+inf = inf,0 */
+ return (hy<0)?-y: zero;
+ }
+ if(iy==0x3f800000) { /* y is +-1 */
+ if(hy<0) return one/x; else return x;
+ }
+ 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);
+ }
+
+ ax = fabsf(x);
+ /* special value of x */
+ if(ix==0x7f800000||ix==0||ix==0x3f800000){
+ z = ax; /*x is +-0,+-inf,+-1*/
+ if(hy<0) z = one/z; /* z = (1/|x|) */
+ if(hx<0) {
+ if(((ix-0x3f800000)|yisint)==0) {
+ z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+ } else if(yisint==1)
+ z = -z; /* (x<0)**odd = -(|x|**odd) */
+ }
+ return z;
+ }
+
+ /* (x<0)**(non-int) is NaN */
+ if(((((u_int32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x);
+
+ /* |y| is huge */
+ if(iy>0x4d000000) { /* if |y| > 2**27 */
+ /* over/underflow if x is not close to one */
+ if(ix<0x3f7ffff8) return (hy<0)? huge*huge:tiny*tiny;
+ if(ix>0x3f800007) return (hy>0)? huge*huge:tiny*tiny;
+ /* now |1-x| is tiny <= 2**-20, suffice to compute
+ log(x) by x-x^2/2+x^3/3-x^4/4 */
+ t = x-1; /* t has 20 trailing zeros */
+ w = (t*t)*((float)0.5-t*((float)0.333333333333-t*(float)0.25));
+ u = ivln2_h*t; /* ivln2_h has 16 sig. bits */
+ v = t*ivln2_l-w*ivln2;
+ t1 = u+v;
+ GET_FLOAT_WORD(is,t1);
+ SET_FLOAT_WORD(t1,is&0xfffff000);
+ t2 = v-(t1-u);
+ } else {
+ float s2,s_h,s_l,t_h,t_l;
+ n = 0;
+ /* take care subnormal number */
+ if(ix<0x00800000)
+ {ax *= two24; n -= 24; GET_FLOAT_WORD(ix,ax); }
+ n += ((ix)>>23)-0x7f;
+ j = ix&0x007fffff;
+ /* determine interval */
+ ix = j|0x3f800000; /* normalize ix */
+ if(j<=0x1cc471) k=0; /* |x|<sqrt(3/2) */
+ else if(j<0x5db3d7) k=1; /* |x|<sqrt(3) */
+ else {k=0;n+=1;ix -= 0x00800000;}
+ SET_FLOAT_WORD(ax,ix);
+
+ /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+ u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
+ v = one/(ax+bp[k]);
+ s = u*v;
+ s_h = s;
+ GET_FLOAT_WORD(is,s_h);
+ SET_FLOAT_WORD(s_h,is&0xfffff000);
+ /* t_h=ax+bp[k] High */
+ SET_FLOAT_WORD(t_h,((ix>>1)|0x20000000)+0x0040000+(k<<21));
+ t_l = ax - (t_h-bp[k]);
+ s_l = v*((u-s_h*t_h)-s_h*t_l);
+ /* compute log(ax) */
+ s2 = s*s;
+ r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+ r += s_l*(s_h+s);
+ s2 = s_h*s_h;
+ t_h = (float)3.0+s2+r;
+ GET_FLOAT_WORD(is,t_h);
+ SET_FLOAT_WORD(t_h,is&0xfffff000);
+ t_l = r-((t_h-(float)3.0)-s2);
+ /* u+v = s*(1+...) */
+ u = s_h*t_h;
+ v = s_l*t_h+t_l*s;
+ /* 2/(3log2)*(s+...) */
+ p_h = u+v;
+ GET_FLOAT_WORD(is,p_h);
+ SET_FLOAT_WORD(p_h,is&0xfffff000);
+ p_l = v-(p_h-u);
+ z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
+ z_l = cp_l*p_h+p_l*cp+dp_l[k];
+ /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+ t = (float)n;
+ t1 = (((z_h+z_l)+dp_h[k])+t);
+ GET_FLOAT_WORD(is,t1);
+ SET_FLOAT_WORD(t1,is&0xfffff000);
+ t2 = z_l-(((t1-t)-dp_h[k])-z_h);
+ }
+
+ s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
+ if(((((u_int32_t)hx>>31)-1)|(yisint-1))==0)
+ s = -one; /* (-ve)**(odd int) */
+
+ /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+ GET_FLOAT_WORD(is,y);
+ SET_FLOAT_WORD(y1,is&0xfffff000);
+ p_l = (y-y1)*t1+y*t2;
+ p_h = y1*t1;
+ z = p_l+p_h;
+ GET_FLOAT_WORD(j,z);
+ if (j>0x43000000) /* if z > 128 */
+ return s*huge*huge; /* overflow */
+ else if (j==0x43000000) { /* if z == 128 */
+ if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */
+ }
+ else if ((j&0x7fffffff)>0x43160000) /* z <= -150 */
+ return s*tiny*tiny; /* underflow */
+ else if ((u_int32_t) j==0xc3160000){ /* z == -150 */
+ if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */
+ }
+ /*
+ * compute 2**(p_h+p_l)
+ */
+ i = j&0x7fffffff;
+ k = (i>>23)-0x7f;
+ n = 0;
+ if(i>0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */
+ n = j+(0x00800000>>(k+1));
+ k = ((n&0x7fffffff)>>23)-0x7f; /* new k for n */
+ SET_FLOAT_WORD(t,n&~(0x007fffff>>k));
+ n = ((n&0x007fffff)|0x00800000)>>(23-k);
+ if(j<0) n = -n;
+ p_h -= t;
+ }
+ t = p_l+p_h;
+ GET_FLOAT_WORD(is,t);
+ SET_FLOAT_WORD(t,is&0xfffff000);
+ u = t*lg2_h;
+ v = (p_l-(t-p_h))*lg2+t*lg2_l;
+ z = u+v;
+ w = v-(z-u);
+ t = z*z;
+ t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+ r = (z*t1)/(t1-two)-(w+z*w);
+ z = one-(r-z);
+ GET_FLOAT_WORD(j,z);
+ j += (n<<23);
+ if((j>>23)<=0) z = __scalbnf(z,n); /* subnormal output */
+ else SET_FLOAT_WORD(z,j);
+ return s*z;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_rem_pio2f.c b/libc/sysdeps/ieee754/flt-32/e_rem_pio2f.c
new file mode 100644
index 000000000..4b8c4466b
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_rem_pio2f.c
@@ -0,0 +1,196 @@
+/* e_rem_pio2f.c -- float version of e_rem_pio2.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: e_rem_pio2f.c,v 1.5 1995/05/10 20:46:03 jtc Exp $";
+#endif
+
+/* __ieee754_rem_pio2f(x,y)
+ *
+ * return the remainder of x rem pi/2 in y[0]+y[1]
+ * use __kernel_rem_pio2f()
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+/*
+ * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
+ */
+#ifdef __STDC__
+static const int32_t two_over_pi[] = {
+#else
+static int32_t two_over_pi[] = {
+#endif
+0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC,
+0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62,
+0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63,
+0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A,
+0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09,
+0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29,
+0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44,
+0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41,
+0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C,
+0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8,
+0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11,
+0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF,
+0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E,
+0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5,
+0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92,
+0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08,
+0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0,
+0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3,
+0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85,
+0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80,
+0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA,
+0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B,
+};
+
+/* This array is like the one in e_rem_pio2.c, but the numbers are
+ single precision and the last 8 bits are forced to 0. */
+#ifdef __STDC__
+static const int32_t npio2_hw[] = {
+#else
+static int32_t npio2_hw[] = {
+#endif
+0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
+0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
+0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
+0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
+0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
+0x4242c700, 0x42490f00
+};
+
+/*
+ * invpio2: 24 bits of 2/pi
+ * pio2_1: first 17 bit of pi/2
+ * pio2_1t: pi/2 - pio2_1
+ * pio2_2: second 17 bit of pi/2
+ * pio2_2t: pi/2 - (pio2_1+pio2_2)
+ * pio2_3: third 17 bit of pi/2
+ * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
+ */
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+zero = 0.0000000000e+00, /* 0x00000000 */
+half = 5.0000000000e-01, /* 0x3f000000 */
+two8 = 2.5600000000e+02, /* 0x43800000 */
+invpio2 = 6.3661980629e-01, /* 0x3f22f984 */
+pio2_1 = 1.5707855225e+00, /* 0x3fc90f80 */
+pio2_1t = 1.0804334124e-05, /* 0x37354443 */
+pio2_2 = 1.0804273188e-05, /* 0x37354400 */
+pio2_2t = 6.0770999344e-11, /* 0x2e85a308 */
+pio2_3 = 6.0770943833e-11, /* 0x2e85a300 */
+pio2_3t = 6.1232342629e-17; /* 0x248d3132 */
+
+#ifdef __STDC__
+ int32_t __ieee754_rem_pio2f(float x, float *y)
+#else
+ int32_t __ieee754_rem_pio2f(x,y)
+ float x,y[];
+#endif
+{
+ float z,w,t,r,fn;
+ float tx[3];
+ int32_t e0,i,j,nx,n,ix,hx;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */
+ {y[0] = x; y[1] = 0; return 0;}
+ if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */
+ if(hx>0) {
+ z = x - pio2_1;
+ if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
+ y[0] = z - pio2_1t;
+ y[1] = (z-y[0])-pio2_1t;
+ } else { /* near pi/2, use 24+24+24 bit pi */
+ z -= pio2_2;
+ y[0] = z - pio2_2t;
+ y[1] = (z-y[0])-pio2_2t;
+ }
+ return 1;
+ } else { /* negative x */
+ z = x + pio2_1;
+ if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
+ y[0] = z + pio2_1t;
+ y[1] = (z-y[0])+pio2_1t;
+ } else { /* near pi/2, use 24+24+24 bit pi */
+ z += pio2_2;
+ y[0] = z + pio2_2t;
+ y[1] = (z-y[0])+pio2_2t;
+ }
+ return -1;
+ }
+ }
+ if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */
+ t = fabsf(x);
+ n = (int32_t) (t*invpio2+half);
+ fn = (float)n;
+ r = t-fn*pio2_1;
+ w = fn*pio2_1t; /* 1st round good to 40 bit */
+ if(n<32&&(int32_t)(ix&0xffffff00)!=npio2_hw[n-1]) {
+ y[0] = r-w; /* quick check no cancellation */
+ } else {
+ u_int32_t high;
+ j = ix>>23;
+ y[0] = r-w;
+ GET_FLOAT_WORD(high,y[0]);
+ i = j-((high>>23)&0xff);
+ if(i>8) { /* 2nd iteration needed, good to 57 */
+ t = r;
+ w = fn*pio2_2;
+ r = t-w;
+ w = fn*pio2_2t-((t-r)-w);
+ y[0] = r-w;
+ GET_FLOAT_WORD(high,y[0]);
+ i = j-((high>>23)&0xff);
+ if(i>25) { /* 3rd iteration need, 74 bits acc */
+ t = r; /* will cover all possible cases */
+ w = fn*pio2_3;
+ r = t-w;
+ w = fn*pio2_3t-((t-r)-w);
+ y[0] = r-w;
+ }
+ }
+ }
+ y[1] = (r-y[0])-w;
+ if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+ else return n;
+ }
+ /*
+ * all other (large) arguments
+ */
+ if(ix>=0x7f800000) { /* x is inf or NaN */
+ y[0]=y[1]=x-x; return 0;
+ }
+ /* set z = scalbn(|x|,ilogb(x)-7) */
+ e0 = (ix>>23)-134; /* e0 = ilogb(z)-7; */
+ SET_FLOAT_WORD(z, ix - ((int32_t)(e0<<23)));
+ for(i=0;i<2;i++) {
+ tx[i] = (float)((int32_t)(z));
+ z = (z-tx[i])*two8;
+ }
+ tx[2] = z;
+ nx = 3;
+ while(tx[nx-1]==zero) nx--; /* skip zero term */
+ n = __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi);
+ if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+ return n;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_remainderf.c b/libc/sysdeps/ieee754/flt-32/e_remainderf.c
new file mode 100644
index 000000000..90d0d366d
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_remainderf.c
@@ -0,0 +1,73 @@
+/* e_remainderf.c -- float version of e_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: e_remainderf.c,v 1.4 1995/05/10 20:46:08 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+
+#ifdef __STDC__
+ float __ieee754_remainderf(float x, float p)
+#else
+ float __ieee754_remainderf(x,p)
+ float x,p;
+#endif
+{
+ int32_t hx,hp;
+ u_int32_t sx;
+ float p_half;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_FLOAT_WORD(hp,p);
+ sx = hx&0x80000000;
+ hp &= 0x7fffffff;
+ hx &= 0x7fffffff;
+
+ /* purge off exception values */
+ if(hp==0) return (x*p)/(x*p); /* p = 0 */
+ if((hx>=0x7f800000)|| /* x not finite */
+ ((hp>0x7f800000))) /* p is NaN */
+ return (x*p)/(x*p);
+
+
+ if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p); /* now x < 2p */
+ if ((hx-hp)==0) return zero*x;
+ x = fabsf(x);
+ p = fabsf(p);
+ if (hp<0x01000000) {
+ if(x+x>p) {
+ x-=p;
+ if(x+x>=p) x -= p;
+ }
+ } else {
+ p_half = (float)0.5*p;
+ if(x>p_half) {
+ x-=p;
+ if(x>=p_half) x -= p;
+ }
+ }
+ GET_FLOAT_WORD(hx,x);
+ SET_FLOAT_WORD(x,hx^sx);
+ return x;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_sinhf.c b/libc/sysdeps/ieee754/flt-32/e_sinhf.c
new file mode 100644
index 000000000..045f6f121
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_sinhf.c
@@ -0,0 +1,68 @@
+/* e_sinhf.c -- float version of e_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: e_sinhf.c,v 1.4 1995/05/10 20:46:15 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one = 1.0, shuge = 1.0e37;
+#else
+static float one = 1.0, shuge = 1.0e37;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_sinhf(float x)
+#else
+ float __ieee754_sinhf(x)
+ float x;
+#endif
+{
+ float t,w,h;
+ int32_t ix,jx;
+
+ GET_FLOAT_WORD(jx,x);
+ ix = jx&0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7f800000) return x+x;
+
+ h = 0.5;
+ if (jx<0) h = -h;
+ /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
+ if (ix < 0x41b00000) { /* |x|<22 */
+ if (ix<0x31800000) /* |x|<2**-28 */
+ if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
+ t = __expm1f(fabsf(x));
+ if(ix<0x3f800000) return h*((float)2.0*t-t*t/(t+one));
+ return h*(t+t/(t+one));
+ }
+
+ /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
+ if (ix < 0x42b17180) return h*__ieee754_expf(fabsf(x));
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ if (ix<=0x42b2d4fc) {
+ w = __ieee754_expf((float)0.5*fabsf(x));
+ t = h*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, sinh(x) overflow */
+ return x*shuge;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/e_sqrtf.c b/libc/sysdeps/ieee754/flt-32/e_sqrtf.c
new file mode 100644
index 000000000..7648ef4bc
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/e_sqrtf.c
@@ -0,0 +1,97 @@
+/* e_sqrtf.c -- float version of e_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: e_sqrtf.c,v 1.4 1995/05/10 20:46:19 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one = 1.0, tiny=1.0e-30;
+#else
+static float one = 1.0, tiny=1.0e-30;
+#endif
+
+#ifdef __STDC__
+ float __ieee754_sqrtf(float x)
+#else
+ float __ieee754_sqrtf(x)
+ float x;
+#endif
+{
+ float z;
+ int32_t sign = (int)0x80000000;
+ int32_t ix,s,q,m,t,i;
+ u_int32_t r;
+
+ GET_FLOAT_WORD(ix,x);
+
+ /* take care of Inf and NaN */
+ if((ix&0x7f800000)==0x7f800000) {
+ return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
+ sqrt(-inf)=sNaN */
+ }
+ /* take care of zero */
+ if(ix<=0) {
+ if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */
+ else if(ix<0)
+ return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
+ }
+ /* normalize x */
+ m = (ix>>23);
+ if(m==0) { /* subnormal x */
+ for(i=0;(ix&0x00800000)==0;i++) ix<<=1;
+ m -= i-1;
+ }
+ m -= 127; /* unbias exponent */
+ ix = (ix&0x007fffff)|0x00800000;
+ if(m&1) /* odd m, double x to make it even */
+ ix += ix;
+ m >>= 1; /* m = [m/2] */
+
+ /* generate sqrt(x) bit by bit */
+ ix += ix;
+ q = s = 0; /* q = sqrt(x) */
+ r = 0x01000000; /* r = moving bit from right to left */
+
+ while(r!=0) {
+ t = s+r;
+ if(t<=ix) {
+ s = t+r;
+ ix -= t;
+ q += r;
+ }
+ ix += ix;
+ r>>=1;
+ }
+
+ /* use floating add to find out rounding direction */
+ if(ix!=0) {
+ z = one-tiny; /* trigger inexact flag */
+ if (z>=one) {
+ z = one+tiny;
+ if (z>one)
+ q += 2;
+ else
+ q += (q&1);
+ }
+ }
+ ix = (q>>1)+0x3f000000;
+ ix += (m <<23);
+ SET_FLOAT_WORD(z,ix);
+ return z;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/k_cosf.c b/libc/sysdeps/ieee754/flt-32/k_cosf.c
new file mode 100644
index 000000000..b232cab11
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/k_cosf.c
@@ -0,0 +1,64 @@
+/* k_cosf.c -- float version of k_cos.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: k_cosf.c,v 1.4 1995/05/10 20:46:23 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0000000000e+00, /* 0x3f800000 */
+C1 = 4.1666667908e-02, /* 0x3d2aaaab */
+C2 = -1.3888889225e-03, /* 0xbab60b61 */
+C3 = 2.4801587642e-05, /* 0x37d00d01 */
+C4 = -2.7557314297e-07, /* 0xb493f27c */
+C5 = 2.0875723372e-09, /* 0x310f74f6 */
+C6 = -1.1359647598e-11; /* 0xad47d74e */
+
+#ifdef __STDC__
+ float __kernel_cosf(float x, float y)
+#else
+ float __kernel_cosf(x, y)
+ float x,y;
+#endif
+{
+ float a,hz,z,r,qx;
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff; /* ix = |x|'s high word*/
+ if(ix<0x32000000) { /* if x < 2**27 */
+ if(((int)x)==0) return one; /* generate inexact */
+ }
+ z = x*x;
+ r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
+ if(ix < 0x3e99999a) /* if |x| < 0.3 */
+ return one - ((float)0.5*z - (z*r - x*y));
+ else {
+ if(ix > 0x3f480000) { /* x > 0.78125 */
+ qx = (float)0.28125;
+ } else {
+ SET_FLOAT_WORD(qx,ix-0x01000000); /* x/4 */
+ }
+ hz = (float)0.5*z-qx;
+ a = one-qx;
+ return a - (hz - (z*r-x*y));
+ }
+}
diff --git a/libc/sysdeps/ieee754/flt-32/k_rem_pio2f.c b/libc/sysdeps/ieee754/flt-32/k_rem_pio2f.c
new file mode 100644
index 000000000..2783480fc
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/k_rem_pio2f.c
@@ -0,0 +1,213 @@
+/* k_rem_pio2f.c -- float version of k_rem_pio2.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: k_rem_pio2f.c,v 1.4 1995/05/10 20:46:28 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+/* In the float version, the input parameter x contains 8 bit
+ integers, not 24 bit integers. 113 bit precision is not supported. */
+
+#ifdef __STDC__
+static const int init_jk[] = {4,7,9}; /* initial value for jk */
+#else
+static int init_jk[] = {4,7,9};
+#endif
+
+#ifdef __STDC__
+static const float PIo2[] = {
+#else
+static float PIo2[] = {
+#endif
+ 1.5703125000e+00, /* 0x3fc90000 */
+ 4.5776367188e-04, /* 0x39f00000 */
+ 2.5987625122e-05, /* 0x37da0000 */
+ 7.5437128544e-08, /* 0x33a20000 */
+ 6.0026650317e-11, /* 0x2e840000 */
+ 7.3896444519e-13, /* 0x2b500000 */
+ 5.3845816694e-15, /* 0x27c20000 */
+ 5.6378512969e-18, /* 0x22d00000 */
+ 8.3009228831e-20, /* 0x1fc40000 */
+ 3.2756352257e-22, /* 0x1bc60000 */
+ 6.3331015649e-25, /* 0x17440000 */
+};
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+zero = 0.0,
+one = 1.0,
+two8 = 2.5600000000e+02, /* 0x43800000 */
+twon8 = 3.9062500000e-03; /* 0x3b800000 */
+
+#ifdef __STDC__
+ int __kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const int32_t *ipio2)
+#else
+ int __kernel_rem_pio2f(x,y,e0,nx,prec,ipio2)
+ float x[], y[]; int e0,nx,prec; int32_t ipio2[];
+#endif
+{
+ int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
+ float z,fw,f[20],fq[20],q[20];
+
+ /* initialize jk*/
+ jk = init_jk[prec];
+ jp = jk;
+
+ /* determine jx,jv,q0, note that 3>q0 */
+ jx = nx-1;
+ jv = (e0-3)/8; if(jv<0) jv=0;
+ q0 = e0-8*(jv+1);
+
+ /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
+ j = jv-jx; m = jx+jk;
+ for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (float) ipio2[j];
+
+ /* compute q[0],q[1],...q[jk] */
+ for (i=0;i<=jk;i++) {
+ for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
+ }
+
+ jz = jk;
+recompute:
+ /* distill q[] into iq[] reversingly */
+ for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
+ fw = (float)((int32_t)(twon8* z));
+ iq[i] = (int32_t)(z-two8*fw);
+ z = q[j-1]+fw;
+ }
+
+ /* compute n */
+ z = __scalbnf(z,q0); /* actual value of z */
+ z -= (float)8.0*__floorf(z*(float)0.125); /* trim off integer >= 8 */
+ n = (int32_t) z;
+ z -= (float)n;
+ ih = 0;
+ if(q0>0) { /* need iq[jz-1] to determine n */
+ i = (iq[jz-1]>>(8-q0)); n += i;
+ iq[jz-1] -= i<<(8-q0);
+ ih = iq[jz-1]>>(7-q0);
+ }
+ else if(q0==0) ih = iq[jz-1]>>8;
+ else if(z>=(float)0.5) ih=2;
+
+ if(ih>0) { /* q > 0.5 */
+ n += 1; carry = 0;
+ for(i=0;i<jz ;i++) { /* compute 1-q */
+ j = iq[i];
+ if(carry==0) {
+ if(j!=0) {
+ carry = 1; iq[i] = 0x100- j;
+ }
+ } else iq[i] = 0xff - j;
+ }
+ if(q0>0) { /* rare case: chance is 1 in 12 */
+ switch(q0) {
+ case 1:
+ iq[jz-1] &= 0x7f; break;
+ case 2:
+ iq[jz-1] &= 0x3f; break;
+ }
+ }
+ if(ih==2) {
+ z = one - z;
+ if(carry!=0) z -= __scalbnf(one,q0);
+ }
+ }
+
+ /* check if recomputation is needed */
+ if(z==zero) {
+ j = 0;
+ for (i=jz-1;i>=jk;i--) j |= iq[i];
+ if(j==0) { /* need recomputation */
+ for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */
+
+ for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */
+ f[jx+i] = (float) ipio2[jv+i];
+ for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
+ q[i] = fw;
+ }
+ jz += k;
+ goto recompute;
+ }
+ }
+
+ /* chop off zero terms */
+ if(z==(float)0.0) {
+ jz -= 1; q0 -= 8;
+ while(iq[jz]==0) { jz--; q0-=8;}
+ } else { /* break z into 8-bit if necessary */
+ z = __scalbnf(z,-q0);
+ if(z>=two8) {
+ fw = (float)((int32_t)(twon8*z));
+ iq[jz] = (int32_t)(z-two8*fw);
+ jz += 1; q0 += 8;
+ iq[jz] = (int32_t) fw;
+ } else iq[jz] = (int32_t) z ;
+ }
+
+ /* convert integer "bit" chunk to floating-point value */
+ fw = __scalbnf(one,q0);
+ for(i=jz;i>=0;i--) {
+ q[i] = fw*(float)iq[i]; fw*=twon8;
+ }
+
+ /* compute PIo2[0,...,jp]*q[jz,...,0] */
+ for(i=jz;i>=0;i--) {
+ for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
+ fq[jz-i] = fw;
+ }
+
+ /* compress fq[] into y[] */
+ switch(prec) {
+ case 0:
+ fw = 0.0;
+ for (i=jz;i>=0;i--) fw += fq[i];
+ y[0] = (ih==0)? fw: -fw;
+ break;
+ case 1:
+ case 2:
+ fw = 0.0;
+ for (i=jz;i>=0;i--) fw += fq[i];
+ y[0] = (ih==0)? fw: -fw;
+ fw = fq[0]-fw;
+ for (i=1;i<=jz;i++) fw += fq[i];
+ y[1] = (ih==0)? fw: -fw;
+ break;
+ case 3: /* painful */
+ for (i=jz;i>0;i--) {
+ fw = fq[i-1]+fq[i];
+ fq[i] += fq[i-1]-fw;
+ fq[i-1] = fw;
+ }
+ for (i=jz;i>1;i--) {
+ fw = fq[i-1]+fq[i];
+ fq[i] += fq[i-1]-fw;
+ fq[i-1] = fw;
+ }
+ for (fw=0.0,i=jz;i>=2;i--) fw += fq[i];
+ if(ih==0) {
+ y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
+ } else {
+ y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
+ }
+ }
+ return n&7;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/k_sinf.c b/libc/sysdeps/ieee754/flt-32/k_sinf.c
new file mode 100644
index 000000000..4fec15e83
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/k_sinf.c
@@ -0,0 +1,54 @@
+/* k_sinf.c -- float version of k_sin.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: k_sinf.c,v 1.4 1995/05/10 20:46:33 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+half = 5.0000000000e-01,/* 0x3f000000 */
+S1 = -1.6666667163e-01, /* 0xbe2aaaab */
+S2 = 8.3333337680e-03, /* 0x3c088889 */
+S3 = -1.9841270114e-04, /* 0xb9500d01 */
+S4 = 2.7557314297e-06, /* 0x3638ef1b */
+S5 = -2.5050759689e-08, /* 0xb2d72f34 */
+S6 = 1.5896910177e-10; /* 0x2f2ec9d3 */
+
+#ifdef __STDC__
+ float __kernel_sinf(float x, float y, int iy)
+#else
+ float __kernel_sinf(x, y, iy)
+ float x,y; int iy; /* iy=0 if y is zero */
+#endif
+{
+ float z,r,v;
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff; /* high word of x */
+ if(ix<0x32000000) /* |x| < 2**-27 */
+ {if((int)x==0) return x;} /* generate inexact */
+ z = x*x;
+ v = z*x;
+ r = S2+z*(S3+z*(S4+z*(S5+z*S6)));
+ if(iy==0) return x+v*(S1+z*r);
+ else return x-((z*(half*y-v*r)-y)-v*S1);
+}
diff --git a/libc/sysdeps/ieee754/flt-32/k_tanf.c b/libc/sysdeps/ieee754/flt-32/k_tanf.c
new file mode 100644
index 000000000..eb1a67093
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/k_tanf.c
@@ -0,0 +1,101 @@
+/* k_tanf.c -- float version of k_tan.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: k_tanf.c,v 1.4 1995/05/10 20:46:39 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0000000000e+00, /* 0x3f800000 */
+pio4 = 7.8539812565e-01, /* 0x3f490fda */
+pio4lo= 3.7748947079e-08, /* 0x33222168 */
+T[] = {
+ 3.3333334327e-01, /* 0x3eaaaaab */
+ 1.3333334029e-01, /* 0x3e088889 */
+ 5.3968254477e-02, /* 0x3d5d0dd1 */
+ 2.1869488060e-02, /* 0x3cb327a4 */
+ 8.8632395491e-03, /* 0x3c11371f */
+ 3.5920790397e-03, /* 0x3b6b6916 */
+ 1.4562094584e-03, /* 0x3abede48 */
+ 5.8804126456e-04, /* 0x3a1a26c8 */
+ 2.4646313977e-04, /* 0x398137b9 */
+ 7.8179444245e-05, /* 0x38a3f445 */
+ 7.1407252108e-05, /* 0x3895c07a */
+ -1.8558637748e-05, /* 0xb79bae5f */
+ 2.5907305826e-05, /* 0x37d95384 */
+};
+
+#ifdef __STDC__
+ float __kernel_tanf(float x, float y, int iy)
+#else
+ float __kernel_tanf(x, y, iy)
+ float x,y; int iy;
+#endif
+{
+ float z,r,v,w,s;
+ int32_t ix,hx;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff; /* high word of |x| */
+ if(ix<0x31800000) /* x < 2**-28 */
+ {if((int)x==0) { /* generate inexact */
+ if((ix|(iy+1))==0) return one/fabsf(x);
+ else return (iy==1)? x: -one/x;
+ }
+ }
+ if(ix>=0x3f2ca140) { /* |x|>=0.6744 */
+ if(hx<0) {x = -x; y = -y;}
+ z = pio4-x;
+ w = pio4lo-y;
+ x = z+w; y = 0.0;
+ }
+ z = x*x;
+ w = z*z;
+ /* Break x^5*(T[1]+x^2*T[2]+...) into
+ * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
+ * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
+ */
+ r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11]))));
+ v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12])))));
+ s = z*x;
+ r = y + z*(s*(r+v)+y);
+ r += T[0]*s;
+ w = x+r;
+ if(ix>=0x3f2ca140) {
+ v = (float)iy;
+ return (float)(1-((hx>>30)&2))*(v-(float)2.0*(x-(w*w/(w+v)-r)));
+ }
+ if(iy==1) return w;
+ else { /* if allow error up to 2 ulp,
+ simply return -1.0/(x+r) here */
+ /* compute -1.0/(x+r) accurately */
+ float a,t;
+ int32_t i;
+ z = w;
+ GET_FLOAT_WORD(i,z);
+ SET_FLOAT_WORD(z,i&0xfffff000);
+ v = r-(z - x); /* z+v = r+x */
+ t = a = -(float)1.0/w; /* a = -1.0/w */
+ GET_FLOAT_WORD(i,t);
+ SET_FLOAT_WORD(t,i&0xfffff000);
+ s = (float)1.0+t*z;
+ return t+a*(s+t*v);
+ }
+}
diff --git a/libc/sysdeps/ieee754/flt-32/mpn2flt.c b/libc/sysdeps/ieee754/flt-32/mpn2flt.c
new file mode 100644
index 000000000..9532770c0
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/mpn2flt.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1995,1997,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include <ieee754.h>
+#include <float.h>
+
+/* Convert a multi-precision integer of the needed number of bits (24 for
+ float) and an integral power of two to a `float' in IEEE754 single-
+ precision format. */
+
+float
+__mpn_construct_float (mp_srcptr frac_ptr, int expt, int sign)
+{
+ union ieee754_float u;
+
+ u.ieee.negative = sign;
+ u.ieee.exponent = expt + IEEE754_FLOAT_BIAS;
+#if BITS_PER_MP_LIMB > FLT_MANT_DIG
+ u.ieee.mantissa = frac_ptr[0] & (((mp_limb_t) 1 << FLT_MANT_DIG) - 1);
+#else
+ #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+
+ return u.f;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/s_asinhf.c b/libc/sysdeps/ieee754/flt-32/s_asinhf.c
new file mode 100644
index 000000000..fac256d37
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_asinhf.c
@@ -0,0 +1,58 @@
+/* s_asinhf.c -- float version of s_asinh.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: s_asinhf.c,v 1.5 1995/05/12 04:57:39 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0000000000e+00, /* 0x3F800000 */
+ln2 = 6.9314718246e-01, /* 0x3f317218 */
+huge= 1.0000000000e+30;
+
+#ifdef __STDC__
+ float __asinhf(float x)
+#else
+ float __asinhf(x)
+ float x;
+#endif
+{
+ float t,w;
+ int32_t hx,ix;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7f800000) return x+x; /* x is inf or NaN */
+ if(ix< 0x38000000) { /* |x|<2**-14 */
+ if(huge+x>one) return x; /* return x inexact except 0 */
+ }
+ if(ix>0x47000000) { /* |x| > 2**14 */
+ w = __ieee754_logf(fabsf(x))+ln2;
+ } else if (ix>0x40000000) { /* 2**14 > |x| > 2.0 */
+ t = fabsf(x);
+ w = __ieee754_logf((float)2.0*t+one/(__ieee754_sqrtf(x*x+one)+t));
+ } else { /* 2.0 > |x| > 2**-14 */
+ t = x*x;
+ w =__log1pf(fabsf(x)+t/(one+__ieee754_sqrtf(one+t)));
+ }
+ if(hx>0) return w; else return -w;
+}
+weak_alias (__asinhf, asinhf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_atanf.c b/libc/sysdeps/ieee754/flt-32/s_atanf.c
new file mode 100644
index 000000000..a68933fa6
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_atanf.c
@@ -0,0 +1,120 @@
+/* s_atanf.c -- float version of s_atan.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: s_atanf.c,v 1.4 1995/05/10 20:46:47 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float atanhi[] = {
+#else
+static float atanhi[] = {
+#endif
+ 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */
+ 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */
+ 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */
+ 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */
+};
+
+#ifdef __STDC__
+static const float atanlo[] = {
+#else
+static float atanlo[] = {
+#endif
+ 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */
+ 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */
+ 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */
+ 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */
+};
+
+#ifdef __STDC__
+static const float aT[] = {
+#else
+static float aT[] = {
+#endif
+ 3.3333334327e-01, /* 0x3eaaaaaa */
+ -2.0000000298e-01, /* 0xbe4ccccd */
+ 1.4285714924e-01, /* 0x3e124925 */
+ -1.1111110449e-01, /* 0xbde38e38 */
+ 9.0908870101e-02, /* 0x3dba2e6e */
+ -7.6918758452e-02, /* 0xbd9d8795 */
+ 6.6610731184e-02, /* 0x3d886b35 */
+ -5.8335702866e-02, /* 0xbd6ef16b */
+ 4.9768779427e-02, /* 0x3d4bda59 */
+ -3.6531571299e-02, /* 0xbd15a221 */
+ 1.6285819933e-02, /* 0x3c8569d7 */
+};
+
+#ifdef __STDC__
+ static const float
+#else
+ static float
+#endif
+one = 1.0,
+huge = 1.0e30;
+
+#ifdef __STDC__
+ float __atanf(float x)
+#else
+ float __atanf(x)
+ float x;
+#endif
+{
+ float w,s1,s2,z;
+ int32_t ix,hx,id;
+
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x50800000) { /* if |x| >= 2^34 */
+ if(ix>0x7f800000)
+ return x+x; /* NaN */
+ if(hx>0) return atanhi[3]+atanlo[3];
+ else return -atanhi[3]-atanlo[3];
+ } if (ix < 0x3ee00000) { /* |x| < 0.4375 */
+ if (ix < 0x31000000) { /* |x| < 2^-29 */
+ if(huge+x>one) return x; /* raise inexact */
+ }
+ id = -1;
+ } else {
+ x = fabsf(x);
+ if (ix < 0x3f980000) { /* |x| < 1.1875 */
+ if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */
+ id = 0; x = ((float)2.0*x-one)/((float)2.0+x);
+ } else { /* 11/16<=|x|< 19/16 */
+ id = 1; x = (x-one)/(x+one);
+ }
+ } else {
+ if (ix < 0x401c0000) { /* |x| < 2.4375 */
+ id = 2; x = (x-(float)1.5)/(one+(float)1.5*x);
+ } else { /* 2.4375 <= |x| < 2^66 */
+ id = 3; x = -(float)1.0/x;
+ }
+ }}
+ /* end of argument reduction */
+ z = x*x;
+ w = z*z;
+ /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
+ s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
+ s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
+ if (id<0) return x - x*(s1+s2);
+ else {
+ z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+ return (hx<0)? -z:z;
+ }
+}
+weak_alias (__atanf, atanf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_cbrtf.c b/libc/sysdeps/ieee754/flt-32/s_cbrtf.c
new file mode 100644
index 000000000..4220de14c
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_cbrtf.c
@@ -0,0 +1,64 @@
+/* Compute cubic root of float value.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
+ Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#define CBRT2 1.2599210498948731648 /* 2^(1/3) */
+#define SQR_CBRT2 1.5874010519681994748 /* 2^(2/3) */
+
+static const double factor[5] =
+{
+ 1.0 / SQR_CBRT2,
+ 1.0 / CBRT2,
+ 1.0,
+ CBRT2,
+ SQR_CBRT2
+};
+
+
+float
+__cbrtf (float x)
+{
+ float xm, ym, u, t2;
+ int xe;
+
+ /* Reduce X. XM now is an range 1.0 to 0.5. */
+ xm = __frexpf (fabsf (x), &xe);
+
+ /* If X is not finite or is null return it (with raising exceptions
+ if necessary.
+ Note: *Our* version of `frexp' sets XE to zero if the argument is
+ Inf or NaN. This is not portable but faster. */
+ if (xe == 0 && fpclassify (x) <= FP_ZERO)
+ return x + x;
+
+ u = (0.492659620528969547 + (0.697570460207922770
+ - 0.191502161678719066 * xm) * xm);
+
+ t2 = u * u * u;
+
+ ym = u * (t2 + 2.0 * xm) / (2.0 * t2 + xm) * factor[2 + xe % 3];
+
+ return __ldexpf (x > 0.0 ? ym : -ym, xe / 3);
+}
+weak_alias (__cbrtf, cbrtf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_ceilf.c b/libc/sysdeps/ieee754/flt-32/s_ceilf.c
new file mode 100644
index 000000000..29ccadb04
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_ceilf.c
@@ -0,0 +1,62 @@
+/* s_ceilf.c -- float version of s_ceil.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: s_ceilf.c,v 1.4 1995/05/10 20:46:55 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float huge = 1.0e30;
+#else
+static float huge = 1.0e30;
+#endif
+
+#ifdef __STDC__
+ float __ceilf(float x)
+#else
+ float __ceilf(x)
+ float x;
+#endif
+{
+ int32_t i0,j0;
+ u_int32_t i;
+
+ GET_FLOAT_WORD(i0,x);
+ j0 = ((i0>>23)&0xff)-0x7f;
+ if(j0<23) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0<0) {i0=0x80000000;}
+ else if(i0!=0) { i0=0x3f800000;}
+ }
+ } else {
+ i = (0x007fffff)>>j0;
+ if((i0&i)==0) return x; /* x is integral */
+ if(huge+x>(float)0.0) { /* raise inexact flag */
+ if(i0>0) i0 += (0x00800000)>>j0;
+ i0 &= (~i);
+ }
+ }
+ } else {
+ if(j0==0x80) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ }
+ SET_FLOAT_WORD(x,i0);
+ return x;
+}
+weak_alias (__ceilf, ceilf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_copysignf.c b/libc/sysdeps/ieee754/flt-32/s_copysignf.c
new file mode 100644
index 000000000..a4e84e539
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_copysignf.c
@@ -0,0 +1,42 @@
+/* s_copysignf.c -- float version of s_copysign.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: s_copysignf.c,v 1.4 1995/05/10 20:46:59 jtc Exp $";
+#endif
+
+/*
+ * copysignf(float x, float y)
+ * copysignf(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float __copysignf(float x, float y)
+#else
+ float __copysignf(x,y)
+ float x,y;
+#endif
+{
+ u_int32_t ix,iy;
+ GET_FLOAT_WORD(ix,x);
+ GET_FLOAT_WORD(iy,y);
+ SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000));
+ return x;
+}
+weak_alias (__copysignf, copysignf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_cosf.c b/libc/sysdeps/ieee754/flt-32/s_cosf.c
new file mode 100644
index 000000000..86c59d440
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_cosf.c
@@ -0,0 +1,60 @@
+/* s_cosf.c -- float version of s_cos.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: s_cosf.c,v 1.4 1995/05/10 20:47:03 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one=1.0;
+#else
+static float one=1.0;
+#endif
+
+#ifdef __STDC__
+ float __cosf(float x)
+#else
+ float __cosf(x)
+ float x;
+#endif
+{
+ float y[2],z=0.0;
+ int32_t n,ix;
+
+ GET_FLOAT_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3f490fd8) return __kernel_cosf(x,z);
+
+ /* cos(Inf or NaN) is NaN */
+ else if (ix>=0x7f800000) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2f(x,y);
+ switch(n&3) {
+ case 0: return __kernel_cosf(y[0],y[1]);
+ case 1: return -__kernel_sinf(y[0],y[1],1);
+ case 2: return -__kernel_cosf(y[0],y[1]);
+ default:
+ return __kernel_sinf(y[0],y[1],1);
+ }
+ }
+}
+weak_alias (__cosf, cosf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_erff.c b/libc/sysdeps/ieee754/flt-32/s_erff.c
new file mode 100644
index 000000000..774714cfd
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_erff.c
@@ -0,0 +1,225 @@
+/* s_erff.c -- float version of s_erf.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: s_erff.c,v 1.4 1995/05/10 20:47:07 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+tiny = 1e-30,
+half= 5.0000000000e-01, /* 0x3F000000 */
+one = 1.0000000000e+00, /* 0x3F800000 */
+two = 2.0000000000e+00, /* 0x40000000 */
+ /* c = (subfloat)0.84506291151 */
+erx = 8.4506291151e-01, /* 0x3f58560b */
+/*
+ * Coefficients for approximation to erf on [0,0.84375]
+ */
+efx = 1.2837916613e-01, /* 0x3e0375d4 */
+efx8= 1.0270333290e+00, /* 0x3f8375d4 */
+pp0 = 1.2837916613e-01, /* 0x3e0375d4 */
+pp1 = -3.2504209876e-01, /* 0xbea66beb */
+pp2 = -2.8481749818e-02, /* 0xbce9528f */
+pp3 = -5.7702702470e-03, /* 0xbbbd1489 */
+pp4 = -2.3763017452e-05, /* 0xb7c756b1 */
+qq1 = 3.9791721106e-01, /* 0x3ecbbbce */
+qq2 = 6.5022252500e-02, /* 0x3d852a63 */
+qq3 = 5.0813062117e-03, /* 0x3ba68116 */
+qq4 = 1.3249473704e-04, /* 0x390aee49 */
+qq5 = -3.9602282413e-06, /* 0xb684e21a */
+/*
+ * Coefficients for approximation to erf in [0.84375,1.25]
+ */
+pa0 = -2.3621185683e-03, /* 0xbb1acdc6 */
+pa1 = 4.1485610604e-01, /* 0x3ed46805 */
+pa2 = -3.7220788002e-01, /* 0xbebe9208 */
+pa3 = 3.1834661961e-01, /* 0x3ea2fe54 */
+pa4 = -1.1089469492e-01, /* 0xbde31cc2 */
+pa5 = 3.5478305072e-02, /* 0x3d1151b3 */
+pa6 = -2.1663755178e-03, /* 0xbb0df9c0 */
+qa1 = 1.0642088205e-01, /* 0x3dd9f331 */
+qa2 = 5.4039794207e-01, /* 0x3f0a5785 */
+qa3 = 7.1828655899e-02, /* 0x3d931ae7 */
+qa4 = 1.2617121637e-01, /* 0x3e013307 */
+qa5 = 1.3637083583e-02, /* 0x3c5f6e13 */
+qa6 = 1.1984500103e-02, /* 0x3c445aa3 */
+/*
+ * Coefficients for approximation to erfc in [1.25,1/0.35]
+ */
+ra0 = -9.8649440333e-03, /* 0xbc21a093 */
+ra1 = -6.9385856390e-01, /* 0xbf31a0b7 */
+ra2 = -1.0558626175e+01, /* 0xc128f022 */
+ra3 = -6.2375331879e+01, /* 0xc2798057 */
+ra4 = -1.6239666748e+02, /* 0xc322658c */
+ra5 = -1.8460508728e+02, /* 0xc3389ae7 */
+ra6 = -8.1287437439e+01, /* 0xc2a2932b */
+ra7 = -9.8143291473e+00, /* 0xc11d077e */
+sa1 = 1.9651271820e+01, /* 0x419d35ce */
+sa2 = 1.3765776062e+02, /* 0x4309a863 */
+sa3 = 4.3456588745e+02, /* 0x43d9486f */
+sa4 = 6.4538726807e+02, /* 0x442158c9 */
+sa5 = 4.2900814819e+02, /* 0x43d6810b */
+sa6 = 1.0863500214e+02, /* 0x42d9451f */
+sa7 = 6.5702495575e+00, /* 0x40d23f7c */
+sa8 = -6.0424413532e-02, /* 0xbd777f97 */
+/*
+ * Coefficients for approximation to erfc in [1/.35,28]
+ */
+rb0 = -9.8649431020e-03, /* 0xbc21a092 */
+rb1 = -7.9928326607e-01, /* 0xbf4c9dd4 */
+rb2 = -1.7757955551e+01, /* 0xc18e104b */
+rb3 = -1.6063638306e+02, /* 0xc320a2ea */
+rb4 = -6.3756646729e+02, /* 0xc41f6441 */
+rb5 = -1.0250950928e+03, /* 0xc480230b */
+rb6 = -4.8351919556e+02, /* 0xc3f1c275 */
+sb1 = 3.0338060379e+01, /* 0x41f2b459 */
+sb2 = 3.2579251099e+02, /* 0x43a2e571 */
+sb3 = 1.5367296143e+03, /* 0x44c01759 */
+sb4 = 3.1998581543e+03, /* 0x4547fdbb */
+sb5 = 2.5530502930e+03, /* 0x451f90ce */
+sb6 = 4.7452853394e+02, /* 0x43ed43a7 */
+sb7 = -2.2440952301e+01; /* 0xc1b38712 */
+
+#ifdef __STDC__
+ float __erff(float x)
+#else
+ float __erff(x)
+ float x;
+#endif
+{
+ int32_t hx,ix,i;
+ float R,S,P,Q,s,y,z,r;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7f800000) { /* erf(nan)=nan */
+ i = ((u_int32_t)hx>>31)<<1;
+ return (float)(1-i)+one/x; /* erf(+-inf)=+-1 */
+ }
+
+ if(ix < 0x3f580000) { /* |x|<0.84375 */
+ if(ix < 0x31800000) { /* |x|<2**-28 */
+ if (ix < 0x04000000)
+ /*avoid underflow */
+ return (float)0.125*((float)8.0*x+efx8*x);
+ return x + efx*x;
+ }
+ z = x*x;
+ r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+ s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+ y = r/s;
+ return x + x*y;
+ }
+ if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */
+ s = fabsf(x)-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+ if(hx>=0) return erx + P/Q; else return -erx - P/Q;
+ }
+ if (ix >= 0x40c00000) { /* inf>|x|>=6 */
+ if(hx>=0) return one-tiny; else return tiny-one;
+ }
+ x = fabsf(x);
+ s = one/(x*x);
+ if(ix< 0x4036DB6E) { /* |x| < 1/0.35 */
+ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+ ra5+s*(ra6+s*ra7))))));
+ S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+ sa5+s*(sa6+s*(sa7+s*sa8)))))));
+ } else { /* |x| >= 1/0.35 */
+ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+ rb5+s*rb6)))));
+ S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+ sb5+s*(sb6+s*sb7))))));
+ }
+ 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);
+ if(hx>=0) return one-r/x; else return r/x-one;
+}
+weak_alias (__erff, erff)
+
+#ifdef __STDC__
+ float __erfcf(float x)
+#else
+ float __erfcf(x)
+ float x;
+#endif
+{
+ int32_t hx,ix;
+ float R,S,P,Q,s,y,z,r;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7f800000) { /* erfc(nan)=nan */
+ /* erfc(+-inf)=0,2 */
+ return (float)(((u_int32_t)hx>>31)<<1)+one/x;
+ }
+
+ if(ix < 0x3f580000) { /* |x|<0.84375 */
+ if(ix < 0x23800000) /* |x|<2**-56 */
+ return one-x;
+ z = x*x;
+ r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+ s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+ y = r/s;
+ if(hx < 0x3e800000) { /* x<1/4 */
+ return one-(x+x*y);
+ } else {
+ r = x*y;
+ r += (x-half);
+ return half - r ;
+ }
+ }
+ if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */
+ s = fabsf(x)-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+ if(hx>=0) {
+ z = one-erx; return z - P/Q;
+ } else {
+ z = erx+P/Q; return one+z;
+ }
+ }
+ if (ix < 0x41e00000) { /* |x|<28 */
+ x = fabsf(x);
+ s = one/(x*x);
+ if(ix< 0x4036DB6D) { /* |x| < 1/.35 ~ 2.857143*/
+ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+ ra5+s*(ra6+s*ra7))))));
+ S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+ sa5+s*(sa6+s*(sa7+s*sa8)))))));
+ } else { /* |x| >= 1/.35 ~ 2.857143 */
+ if(hx<0&&ix>=0x40c00000) return two-tiny;/* x < -6 */
+ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+ rb5+s*rb6)))));
+ S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+ sb5+s*(sb6+s*sb7))))));
+ }
+ 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);
+ if(hx>0) return r/x; else return two-r/x;
+ } else {
+ if(hx>0) return tiny*tiny; else return two-tiny;
+ }
+}
+weak_alias (__erfcf, erfcf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_expm1f.c b/libc/sysdeps/ieee754/flt-32/s_expm1f.c
new file mode 100644
index 000000000..1f032be25
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_expm1f.c
@@ -0,0 +1,136 @@
+/* s_expm1f.c -- float version of s_expm1.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: s_expm1f.c,v 1.5 1995/05/10 20:47:11 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+static const volatile float huge = 1.0e+30;
+static const volatile float tiny = 1.0e-30;
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+one = 1.0,
+o_threshold = 8.8721679688e+01,/* 0x42b17180 */
+ln2_hi = 6.9313812256e-01,/* 0x3f317180 */
+ln2_lo = 9.0580006145e-06,/* 0x3717f7d1 */
+invln2 = 1.4426950216e+00,/* 0x3fb8aa3b */
+ /* scaled coefficients related to expm1 */
+Q1 = -3.3333335072e-02, /* 0xbd088889 */
+Q2 = 1.5873016091e-03, /* 0x3ad00d01 */
+Q3 = -7.9365076090e-05, /* 0xb8a670cd */
+Q4 = 4.0082177293e-06, /* 0x36867e54 */
+Q5 = -2.0109921195e-07; /* 0xb457edbb */
+
+#ifdef __STDC__
+ float __expm1f(float x)
+#else
+ float __expm1f(x)
+ float x;
+#endif
+{
+ float y,hi,lo,c,t,e,hxs,hfx,r1;
+ int32_t k,xsb;
+ u_int32_t hx;
+
+ GET_FLOAT_WORD(hx,x);
+ xsb = hx&0x80000000; /* sign bit of x */
+ if(xsb==0) y=x; else y= -x; /* y = |x| */
+ hx &= 0x7fffffff; /* high word of |x| */
+
+ /* filter out huge and non-finite argument */
+ if(hx >= 0x4195b844) { /* if |x|>=27*ln2 */
+ if(hx >= 0x42b17218) { /* if |x|>=88.721... */
+ if(hx>0x7f800000)
+ return x+x; /* NaN */
+ if(hx==0x7f800000)
+ return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
+ if(x > o_threshold) return huge*huge; /* overflow */
+ }
+ if(xsb!=0) { /* x < -27*ln2, return -1.0 with inexact */
+ if(x+tiny<(float)0.0) /* raise inexact */
+ return tiny-one; /* return -1 */
+ }
+ }
+
+ /* argument reduction */
+ if(hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
+ if(hx < 0x3F851592) { /* and |x| < 1.5 ln2 */
+ if(xsb==0)
+ {hi = x - ln2_hi; lo = ln2_lo; k = 1;}
+ else
+ {hi = x + ln2_hi; lo = -ln2_lo; k = -1;}
+ } else {
+ k = invln2*x+((xsb==0)?(float)0.5:(float)-0.5);
+ t = k;
+ hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
+ lo = t*ln2_lo;
+ }
+ x = hi - lo;
+ c = (hi-x)-lo;
+ }
+ else if(hx < 0x33000000) { /* when |x|<2**-25, return x */
+ t = huge+x; /* return x with inexact flags when x!=0 */
+ return x - (t-(huge+x));
+ }
+ else k = 0;
+
+ /* x is now in primary range */
+ hfx = (float)0.5*x;
+ hxs = x*hfx;
+ r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
+ t = (float)3.0-r1*hfx;
+ e = hxs*((r1-t)/((float)6.0 - x*t));
+ if(k==0) return x - (x*e-hxs); /* c is 0 */
+ else {
+ e = (x*(e-c)-c);
+ e -= hxs;
+ if(k== -1) return (float)0.5*(x-e)-(float)0.5;
+ if(k==1) {
+ if(x < (float)-0.25) return -(float)2.0*(e-(x+(float)0.5));
+ else return one+(float)2.0*(x-e);
+ }
+ if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */
+ int32_t i;
+ y = one-(e-x);
+ GET_FLOAT_WORD(i,y);
+ SET_FLOAT_WORD(y,i+(k<<23)); /* add k to y's exponent */
+ return y-one;
+ }
+ t = one;
+ if(k<23) {
+ int32_t i;
+ SET_FLOAT_WORD(t,0x3f800000 - (0x1000000>>k)); /* t=1-2^-k */
+ y = t-(e-x);
+ GET_FLOAT_WORD(i,y);
+ SET_FLOAT_WORD(y,i+(k<<23)); /* add k to y's exponent */
+ } else {
+ int32_t i;
+ SET_FLOAT_WORD(t,((0x7f-k)<<23)); /* 2^-k */
+ y = x-(e+t);
+ y += one;
+ GET_FLOAT_WORD(i,y);
+ SET_FLOAT_WORD(y,i+(k<<23)); /* add k to y's exponent */
+ }
+ }
+ return y;
+}
+weak_alias (__expm1f, expm1f)
diff --git a/libc/sysdeps/ieee754/flt-32/s_fabsf.c b/libc/sysdeps/ieee754/flt-32/s_fabsf.c
new file mode 100644
index 000000000..6b1451379
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_fabsf.c
@@ -0,0 +1,39 @@
+/* s_fabsf.c -- float version of s_fabs.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: s_fabsf.c,v 1.4 1995/05/10 20:47:15 jtc Exp $";
+#endif
+
+/*
+ * fabsf(x) returns the absolute value of x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float __fabsf(float x)
+#else
+ float __fabsf(x)
+ float x;
+#endif
+{
+ u_int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ SET_FLOAT_WORD(x,ix&0x7fffffff);
+ return x;
+}
+weak_alias (__fabsf, fabsf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_finitef.c b/libc/sysdeps/ieee754/flt-32/s_finitef.c
new file mode 100644
index 000000000..65767f8f9
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_finitef.c
@@ -0,0 +1,40 @@
+/* s_finitef.c -- float version of s_finite.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: s_finitef.c,v 1.4 1995/05/10 20:47:18 jtc Exp $";
+#endif
+
+/*
+ * finitef(x) returns 1 is x is finite, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __finitef(float x)
+#else
+ int __finitef(x)
+ float x;
+#endif
+{
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ return (int)((u_int32_t)((ix&0x7fffffff)-0x7f800000)>>31);
+}
+hidden_def (__finitef)
+weak_alias (__finitef, finitef)
diff --git a/libc/sysdeps/ieee754/flt-32/s_floorf.c b/libc/sysdeps/ieee754/flt-32/s_floorf.c
new file mode 100644
index 000000000..e8822b088
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_floorf.c
@@ -0,0 +1,71 @@
+/* s_floorf.c -- float version of s_floor.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: s_floorf.c,v 1.4 1995/05/10 20:47:22 jtc Exp $";
+#endif
+
+/*
+ * floorf(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to floorf(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float huge = 1.0e30;
+#else
+static float huge = 1.0e30;
+#endif
+
+#ifdef __STDC__
+ float __floorf(float x)
+#else
+ float __floorf(x)
+ float x;
+#endif
+{
+ int32_t i0,j0;
+ u_int32_t i;
+ GET_FLOAT_WORD(i0,x);
+ j0 = ((i0>>23)&0xff)-0x7f;
+ if(j0<23) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0>=0) {i0=0;}
+ else if((i0&0x7fffffff)!=0)
+ { i0=0xbf800000;}
+ }
+ } else {
+ i = (0x007fffff)>>j0;
+ if((i0&i)==0) return x; /* x is integral */
+ if(huge+x>(float)0.0) { /* raise inexact flag */
+ if(i0<0) i0 += (0x00800000)>>j0;
+ i0 &= (~i);
+ }
+ }
+ } else {
+ if(j0==0x80) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ }
+ SET_FLOAT_WORD(x,i0);
+ return x;
+}
+weak_alias (__floorf, floorf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_fpclassifyf.c b/libc/sysdeps/ieee754/flt-32/s_fpclassifyf.c
new file mode 100644
index 000000000..709bc2b01
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_fpclassifyf.c
@@ -0,0 +1,43 @@
+/* Return classification value corresponding to argument.
+ Copyright (C) 1997, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+int
+__fpclassifyf (float x)
+{
+ u_int32_t wx;
+ int retval = FP_NORMAL;
+
+ GET_FLOAT_WORD (wx, x);
+ wx &= 0x7fffffff;
+ if (wx == 0)
+ retval = FP_ZERO;
+ else if (wx < 0x800000)
+ retval = FP_SUBNORMAL;
+ else if (wx >= 0x7f800000)
+ retval = wx > 0x7f800000 ? FP_NAN : FP_INFINITE;
+
+ return retval;
+}
+libm_hidden_def (__fpclassifyf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_frexpf.c b/libc/sysdeps/ieee754/flt-32/s_frexpf.c
new file mode 100644
index 000000000..7a4eb4cca
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_frexpf.c
@@ -0,0 +1,53 @@
+/* s_frexpf.c -- float version of s_frexp.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: s_frexpf.c,v 1.5 1995/05/10 20:47:26 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+two25 = 3.3554432000e+07; /* 0x4c000000 */
+
+#ifdef __STDC__
+ float __frexpf(float x, int *eptr)
+#else
+ float __frexpf(x, eptr)
+ float x; int *eptr;
+#endif
+{
+ int32_t hx,ix;
+ GET_FLOAT_WORD(hx,x);
+ ix = 0x7fffffff&hx;
+ *eptr = 0;
+ if(ix>=0x7f800000||(ix==0)) return x; /* 0,inf,nan */
+ if (ix<0x00800000) { /* subnormal */
+ x *= two25;
+ GET_FLOAT_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ *eptr = -25;
+ }
+ *eptr += (ix>>23)-126;
+ hx = (hx&0x807fffff)|0x3f000000;
+ SET_FLOAT_WORD(x,hx);
+ return x;
+}
+weak_alias (__frexpf, frexpf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_ilogbf.c b/libc/sysdeps/ieee754/flt-32/s_ilogbf.c
new file mode 100644
index 000000000..ea3dc13bc
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_ilogbf.c
@@ -0,0 +1,50 @@
+/* s_ilogbf.c -- float version of s_ilogb.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: s_ilogbf.c,v 1.4 1995/05/10 20:47:31 jtc Exp $";
+#endif
+
+#include <limits.h>
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __ilogbf(float x)
+#else
+ int __ilogbf(x)
+ float x;
+#endif
+{
+ int32_t hx,ix;
+
+ GET_FLOAT_WORD(hx,x);
+ hx &= 0x7fffffff;
+ if(hx<0x00800000) {
+ if(hx==0)
+ return FP_ILOGB0; /* ilogb(0) = FP_ILOGB0 */
+ else /* subnormal x */
+ for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1;
+ return ix;
+ }
+ else if (hx<0x7f800000) return (hx>>23)-127;
+ else if (FP_ILOGBNAN != INT_MAX) {
+ /* ISO C99 requires ilogbf(+-Inf) == INT_MAX. */
+ if (hx==0x7f800000)
+ return INT_MAX;
+ }
+ return FP_ILOGBNAN;
+}
+weak_alias (__ilogbf, ilogbf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_isinff.c b/libc/sysdeps/ieee754/flt-32/s_isinff.c
new file mode 100644
index 000000000..03a95fcc0
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_isinff.c
@@ -0,0 +1,29 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: s_isinff.c,v 1.3 1995/05/11 23:20:21 jtc Exp $";
+#endif
+
+/*
+ * isinff(x) returns 1 if x is inf, -1 if x is -inf, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+int
+__isinff (float x)
+{
+ int32_t ix,t;
+ GET_FLOAT_WORD(ix,x);
+ t = ix & 0x7fffffff;
+ t ^= 0x7f800000;
+ t |= -t;
+ return ~(t >> 31) & (ix >> 30);
+}
+hidden_def (__isinff)
+weak_alias (__isinff, isinff)
diff --git a/libc/sysdeps/ieee754/flt-32/s_isnanf.c b/libc/sysdeps/ieee754/flt-32/s_isnanf.c
new file mode 100644
index 000000000..4ac16c2b5
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_isnanf.c
@@ -0,0 +1,42 @@
+/* s_isnanf.c -- float version of s_isnan.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: s_isnanf.c,v 1.4 1995/05/10 20:47:38 jtc Exp $";
+#endif
+
+/*
+ * isnanf(x) returns 1 is x is nan, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __isnanf(float x)
+#else
+ int __isnanf(x)
+ float x;
+#endif
+{
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff;
+ ix = 0x7f800000 - ix;
+ return (int)(((u_int32_t)(ix))>>31);
+}
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_llrintf.c b/libc/sysdeps/ieee754/flt-32/s_llrintf.c
new file mode 100644
index 000000000..3b9a484a8
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_llrintf.c
@@ -0,0 +1,78 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+static const double two23[2] =
+{
+ 8.3886080000e+06, /* 0x4B000000 */
+ -8.3886080000e+06, /* 0xCB000000 */
+};
+
+
+long long int
+__llrintf (float x)
+{
+ int32_t j0;
+ u_int32_t i0;
+ volatile float w;
+ float t;
+ long long int result;
+ int sx;
+
+ GET_FLOAT_WORD (i0, x);
+
+ sx = i0 >> 31;
+ j0 = ((i0 >> 23) & 0xff) - 0x7f;
+ i0 &= 0x7fffff;
+ i0 |= 0x800000;
+
+ if (j0 < (int32_t) (sizeof (long long int) * 8) - 1)
+ {
+ if (j0 < -1)
+ return 0;
+ else if (j0 >= 23)
+ result = (long long int) i0 << (j0 - 23);
+ else
+ {
+ w = two23[sx] + x;
+ t = w - two23[sx];
+ GET_FLOAT_WORD (i0, t);
+ j0 = ((i0 >> 23) & 0xff) - 0x7f;
+ i0 &= 0x7fffff;
+ i0 |= 0x800000;
+
+ result = i0 >> (23 - j0);
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long long int) x;
+ }
+
+ return sx ? -result : result;
+}
+
+weak_alias (__llrintf, llrintf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_llroundf.c b/libc/sysdeps/ieee754/flt-32/s_llroundf.c
new file mode 100644
index 000000000..d1822fe5c
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_llroundf.c
@@ -0,0 +1,63 @@
+/* Round float value to long long int.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+long long int
+__llroundf (float x)
+{
+ int32_t j0;
+ u_int32_t i;
+ long long int result;
+ int sign;
+
+ GET_FLOAT_WORD (i, x);
+ j0 = ((i >> 23) & 0xff) - 0x7f;
+ sign = (i & 0x80000000) != 0 ? -1 : 1;
+ i &= 0x7fffff;
+ i |= 0x800000;
+
+ if (j0 < (int32_t) (8 * sizeof (long long int)) - 1)
+ {
+ if (j0 < 0)
+ return j0 < -1 ? 0 : sign;
+ else if (j0 >= 23)
+ result = (long long int) i << (j0 - 23);
+ else
+ {
+ i += 0x400000 >> j0;
+
+ result = i >> (23 - j0);
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long long int) x;
+ }
+
+ return sign * result;
+}
+
+weak_alias (__llroundf, llroundf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_log1pf.c b/libc/sysdeps/ieee754/flt-32/s_log1pf.c
new file mode 100644
index 000000000..bd3d57635
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_log1pf.c
@@ -0,0 +1,115 @@
+/* s_log1pf.c -- float version of s_log1p.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: s_log1pf.c,v 1.4 1995/05/10 20:47:48 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
+ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
+two25 = 3.355443200e+07, /* 0x4c000000 */
+Lp1 = 6.6666668653e-01, /* 3F2AAAAB */
+Lp2 = 4.0000000596e-01, /* 3ECCCCCD */
+Lp3 = 2.8571429849e-01, /* 3E924925 */
+Lp4 = 2.2222198546e-01, /* 3E638E29 */
+Lp5 = 1.8183572590e-01, /* 3E3A3325 */
+Lp6 = 1.5313838422e-01, /* 3E1CD04F */
+Lp7 = 1.4798198640e-01; /* 3E178897 */
+
+#ifdef __STDC__
+static const float zero = 0.0;
+#else
+static float zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ float __log1pf(float x)
+#else
+ float __log1pf(x)
+ float x;
+#endif
+{
+ float hfsq,f,c,s,z,R,u;
+ int32_t k,hx,hu,ax;
+
+ GET_FLOAT_WORD(hx,x);
+ ax = hx&0x7fffffff;
+
+ k = 1;
+ if (hx < 0x3ed413d7) { /* x < 0.41422 */
+ if(ax>=0x3f800000) { /* x <= -1.0 */
+ if(x==(float)-1.0) return -two25/(x-x); /* log1p(-1)=+inf */
+ else return (x-x)/(x-x); /* log1p(x<-1)=NaN */
+ }
+ if(ax<0x31000000) { /* |x| < 2**-29 */
+ if(two25+x>zero /* raise inexact */
+ &&ax<0x24800000) /* |x| < 2**-54 */
+ return x;
+ else
+ return x - x*x*(float)0.5;
+ }
+ if(hx>0||hx<=((int32_t)0xbe95f61f)) {
+ k=0;f=x;hu=1;} /* -0.2929<x<0.41422 */
+ }
+ if (hx >= 0x7f800000) return x+x;
+ if(k!=0) {
+ if(hx<0x5a000000) {
+ u = (float)1.0+x;
+ GET_FLOAT_WORD(hu,u);
+ k = (hu>>23)-127;
+ /* correction term */
+ c = (k>0)? (float)1.0-(u-x):x-(u-(float)1.0);
+ c /= u;
+ } else {
+ u = x;
+ GET_FLOAT_WORD(hu,u);
+ k = (hu>>23)-127;
+ c = 0;
+ }
+ hu &= 0x007fffff;
+ if(hu<0x3504f7) {
+ SET_FLOAT_WORD(u,hu|0x3f800000);/* normalize u */
+ } else {
+ k += 1;
+ SET_FLOAT_WORD(u,hu|0x3f000000); /* normalize u/2 */
+ hu = (0x00800000-hu)>>2;
+ }
+ f = u-(float)1.0;
+ }
+ hfsq=(float)0.5*f*f;
+ if(hu==0) { /* |f| < 2**-20 */
+ if(f==zero) {
+ if(k==0) return zero;
+ else {c += k*ln2_lo; return k*ln2_hi+c;}
+ }
+ R = hfsq*((float)1.0-(float)0.66666666666666666*f);
+ if(k==0) return f-R; else
+ return k*ln2_hi-((R-(k*ln2_lo+c))-f);
+ }
+ s = f/((float)2.0+f);
+ z = s*s;
+ R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7))))));
+ if(k==0) return f-(hfsq-s*(hfsq+R)); else
+ return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f);
+}
+weak_alias (__log1pf, log1pf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_logbf.c b/libc/sysdeps/ieee754/flt-32/s_logbf.c
new file mode 100644
index 000000000..ade892a8f
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_logbf.c
@@ -0,0 +1,40 @@
+/* s_logbf.c -- float version of s_logb.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: s_logbf.c,v 1.4 1995/05/10 20:47:51 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float __logbf(float x)
+#else
+ float __logbf(x)
+ float x;
+#endif
+{
+ int32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ ix &= 0x7fffffff; /* high |x| */
+ if(ix==0) return (float)-1.0/fabsf(x);
+ if(ix>=0x7f800000) return x*x;
+ if((ix>>=23)==0) /* IEEE 754 logb */
+ return -126.0;
+ else
+ return (float) (ix-127);
+}
+weak_alias (__logbf, logbf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_lrintf.c b/libc/sysdeps/ieee754/flt-32/s_lrintf.c
new file mode 100644
index 000000000..2a156f7ce
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_lrintf.c
@@ -0,0 +1,78 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+static const double two23[2] =
+{
+ 8.3886080000e+06, /* 0x4B000000 */
+ -8.3886080000e+06, /* 0xCB000000 */
+};
+
+
+long int
+__lrintf (float x)
+{
+ int32_t j0;
+ u_int32_t i0;
+ volatile float w;
+ float t;
+ long int result;
+ int sx;
+
+ GET_FLOAT_WORD (i0, x);
+
+ sx = i0 >> 31;
+ j0 = ((i0 >> 23) & 0xff) - 0x7f;
+ i0 &= 0x7fffff;
+ i0 |= 0x800000;
+
+ if (j0 < (int32_t) (sizeof (long int) * 8) - 1)
+ {
+ if (j0 < -1)
+ return 0;
+ else if (j0 >= 23)
+ result = (long int) i0 << (j0 - 23);
+ else
+ {
+ w = two23[sx] + x;
+ t = w - two23[sx];
+ GET_FLOAT_WORD (i0, t);
+ j0 = ((i0 >> 23) & 0xff) - 0x7f;
+ i0 &= 0x7fffff;
+ i0 |= 0x800000;
+
+ result = i0 >> (23 - j0);
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long int) x;
+ }
+
+ return sx ? -result : result;
+}
+
+weak_alias (__lrintf, lrintf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_lroundf.c b/libc/sysdeps/ieee754/flt-32/s_lroundf.c
new file mode 100644
index 000000000..b7601bd3b
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_lroundf.c
@@ -0,0 +1,63 @@
+/* Round float value to long int.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+long int
+__lroundf (float x)
+{
+ int32_t j0;
+ u_int32_t i;
+ long int result;
+ int sign;
+
+ GET_FLOAT_WORD (i, x);
+ j0 = ((i >> 23) & 0xff) - 0x7f;
+ sign = (i & 0x80000000) != 0 ? -1 : 1;
+ i &= 0x7fffff;
+ i |= 0x800000;
+
+ if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
+ {
+ if (j0 < 0)
+ return j0 < -1 ? 0 : sign;
+ else if (j0 >= 23)
+ result = (long int) i << (j0 - 23);
+ else
+ {
+ i += 0x400000 >> j0;
+
+ result = i >> (23 - j0);
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long int) x;
+ }
+
+ return sign * result;
+}
+
+weak_alias (__lroundf, lroundf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_modff.c b/libc/sysdeps/ieee754/flt-32/s_modff.c
new file mode 100644
index 000000000..e6c22b2ad
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_modff.c
@@ -0,0 +1,66 @@
+/* s_modff.c -- float version of s_modf.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: s_modff.c,v 1.4 1995/05/10 20:47:56 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one = 1.0;
+#else
+static float one = 1.0;
+#endif
+
+#ifdef __STDC__
+ float __modff(float x, float *iptr)
+#else
+ float __modff(x, iptr)
+ float x,*iptr;
+#endif
+{
+ int32_t i0,j0;
+ u_int32_t i;
+ GET_FLOAT_WORD(i0,x);
+ j0 = ((i0>>23)&0xff)-0x7f; /* exponent of x */
+ if(j0<23) { /* integer part in x */
+ if(j0<0) { /* |x|<1 */
+ SET_FLOAT_WORD(*iptr,i0&0x80000000); /* *iptr = +-0 */
+ return x;
+ } else {
+ i = (0x007fffff)>>j0;
+ if((i0&i)==0) { /* x is integral */
+ u_int32_t ix;
+ *iptr = x;
+ GET_FLOAT_WORD(ix,x);
+ SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */
+ return x;
+ } else {
+ SET_FLOAT_WORD(*iptr,i0&(~i));
+ return x - *iptr;
+ }
+ }
+ } else { /* no fraction part */
+ *iptr = x*one;
+ /* We must handle NaNs separately. */
+ if (j0 == 0x80 && (i0 & 0x7fffff))
+ return x*one;
+ SET_FLOAT_WORD(x,i0&0x80000000); /* return +-0 */
+ return x;
+ }
+}
+weak_alias (__modff, modff)
diff --git a/libc/sysdeps/ieee754/flt-32/s_nearbyintf.c b/libc/sysdeps/ieee754/flt-32/s_nearbyintf.c
new file mode 100644
index 000000000..7d6f262f5
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_nearbyintf.c
@@ -0,0 +1,77 @@
+/* s_rintf.c -- float version of s_rint.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/* Adapted for use as nearbyint by Ulrich Drepper <drepper@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 <fenv.h>
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+TWO23[2]={
+ 8.3886080000e+06, /* 0x4b000000 */
+ -8.3886080000e+06, /* 0xcb000000 */
+};
+
+#ifdef __STDC__
+ float __nearbyintf(float x)
+#else
+ float __nearbyintf(x)
+ float x;
+#endif
+{
+ fenv_t env;
+ int32_t i0,j0,sx;
+ u_int32_t i,i1;
+ float w,t;
+ GET_FLOAT_WORD(i0,x);
+ sx = (i0>>31)&1;
+ j0 = ((i0>>23)&0xff)-0x7f;
+ if(j0<23) {
+ if(j0<0) {
+ if((i0&0x7fffffff)==0) return x;
+ i1 = (i0&0x07fffff);
+ i0 &= 0xfff00000;
+ i0 |= ((i1|-i1)>>9)&0x400000;
+ SET_FLOAT_WORD(x,i0);
+ feholdexcept (&env);
+ w = TWO23[sx]+x;
+ t = w-TWO23[sx];
+ fesetenv (&env);
+ GET_FLOAT_WORD(i0,t);
+ SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
+ return t;
+ } else {
+ i = (0x007fffff)>>j0;
+ if((i0&i)==0) return x; /* x is integral */
+ i>>=1;
+ if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
+ }
+ } else {
+ if(j0==0x80) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ }
+ SET_FLOAT_WORD(x,i0);
+ feholdexcept (&env);
+ w = TWO23[sx]+x;
+ t = w-TWO23[sx];
+ fesetenv (&env);
+ return t;
+}
+weak_alias (__nearbyintf, nearbyintf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_nextafterf.c b/libc/sysdeps/ieee754/flt-32/s_nextafterf.c
new file mode 100644
index 000000000..e1568e24c
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_nextafterf.c
@@ -0,0 +1,77 @@
+/* s_nextafterf.c -- float version of s_nextafter.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: s_nextafterf.c,v 1.4 1995/05/10 20:48:01 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+#include <float.h>
+
+#ifdef __STDC__
+ float __nextafterf(float x, float y)
+#else
+ float __nextafterf(x,y)
+ float x,y;
+#endif
+{
+ int32_t hx,hy,ix,iy;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_FLOAT_WORD(hy,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = hy&0x7fffffff; /* |y| */
+
+ if((ix>0x7f800000) || /* x is nan */
+ (iy>0x7f800000)) /* y is nan */
+ return x+y;
+ if(x==y) return y; /* x=y, return y */
+ if(ix==0) { /* x == 0 */
+ SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */
+ y = x*x;
+ if(y==x) return y; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if(hx>hy) { /* x > y, x -= ulp */
+ hx -= 1;
+ } else { /* x < y, x += ulp */
+ hx += 1;
+ }
+ } else { /* x < 0 */
+ if(hy>=0||hx>hy){ /* x < y, x -= ulp */
+ hx -= 1;
+ } else { /* x > y, x += ulp */
+ hx += 1;
+ }
+ }
+ hy = hx&0x7f800000;
+ if(hy>=0x7f800000) {
+ x = x+x; /* overflow */
+ if (FLT_EVAL_METHOD != 0)
+ asm ("" : "=m"(x) : "m"(x));
+ return x; /* overflow */
+ }
+ if(hy<0x00800000) { /* underflow */
+ y = x*x;
+ if(y!=x) { /* raise underflow flag */
+ SET_FLOAT_WORD(y,hx);
+ return y;
+ }
+ }
+ SET_FLOAT_WORD(x,hx);
+ return x;
+}
+weak_alias (__nextafterf, nextafterf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_remquof.c b/libc/sysdeps/ieee754/flt-32/s_remquof.c
new file mode 100644
index 000000000..0d184ad52
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_remquof.c
@@ -0,0 +1,108 @@
+/* Compute remainder and a congruent to the quotient.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+static const float zero = 0.0;
+
+
+float
+__remquof (float x, float y, int *quo)
+{
+ int32_t hx,hy;
+ u_int32_t sx;
+ int cquo, qs;
+
+ GET_FLOAT_WORD (hx, x);
+ GET_FLOAT_WORD (hy, y);
+ sx = hx & 0x80000000;
+ qs = sx ^ (hy & 0x80000000);
+ hy &= 0x7fffffff;
+ hx &= 0x7fffffff;
+
+ /* Purge off exception values. */
+ if (hy == 0)
+ return (x * y) / (x * y); /* y = 0 */
+ if ((hx >= 0x7f800000) /* x not finite */
+ || (hy > 0x7f800000)) /* y is NaN */
+ return (x * y) / (x * y);
+
+ if (hy <= 0x7dffffff)
+ x = __ieee754_fmodf (x, 8 * y); /* now x < 8y */
+
+ if ((hx - hy) == 0)
+ {
+ *quo = qs ? -1 : 1;
+ return zero * x;
+ }
+
+ x = fabsf (x);
+ y = fabsf (y);
+ cquo = 0;
+
+ if (x >= 4 * y)
+ {
+ x -= 4 * y;
+ cquo += 4;
+ }
+ if (x >= 2 * y)
+ {
+ x -= 2 * y;
+ cquo += 2;
+ }
+
+ if (hy < 0x01000000)
+ {
+ if (x + x > y)
+ {
+ x -= y;
+ ++cquo;
+ if (x + x >= y)
+ {
+ x -= y;
+ ++cquo;
+ }
+ }
+ }
+ else
+ {
+ float y_half = 0.5 * y;
+ if (x > y_half)
+ {
+ x -= y;
+ ++cquo;
+ if (x >= y_half)
+ {
+ x -= y;
+ ++cquo;
+ }
+ }
+ }
+
+ *quo = qs ? -cquo : cquo;
+
+ if (sx)
+ x = -x;
+ return x;
+}
+weak_alias (__remquof, remquof)
diff --git a/libc/sysdeps/ieee754/flt-32/s_rintf.c b/libc/sysdeps/ieee754/flt-32/s_rintf.c
new file mode 100644
index 000000000..4e5b409b2
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_rintf.c
@@ -0,0 +1,72 @@
+/* s_rintf.c -- float version of s_rint.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: s_rintf.c,v 1.4 1995/05/10 20:48:06 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+TWO23[2]={
+ 8.3886080000e+06, /* 0x4b000000 */
+ -8.3886080000e+06, /* 0xcb000000 */
+};
+
+#ifdef __STDC__
+ float __rintf(float x)
+#else
+ float __rintf(x)
+ float x;
+#endif
+{
+ int32_t i0,j0,sx;
+ u_int32_t i,i1;
+ float w,t;
+ GET_FLOAT_WORD(i0,x);
+ sx = (i0>>31)&1;
+ j0 = ((i0>>23)&0xff)-0x7f;
+ if(j0<23) {
+ if(j0<0) {
+ if((i0&0x7fffffff)==0) return x;
+ i1 = (i0&0x07fffff);
+ i0 &= 0xfff00000;
+ i0 |= ((i1|-i1)>>9)&0x400000;
+ SET_FLOAT_WORD(x,i0);
+ w = TWO23[sx]+x;
+ t = w-TWO23[sx];
+ GET_FLOAT_WORD(i0,t);
+ SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
+ return t;
+ } else {
+ i = (0x007fffff)>>j0;
+ if((i0&i)==0) return x; /* x is integral */
+ i>>=1;
+ if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
+ }
+ } else {
+ if(j0==0x80) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ }
+ SET_FLOAT_WORD(x,i0);
+ w = TWO23[sx]+x;
+ return w-TWO23[sx];
+}
+weak_alias (__rintf, rintf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_roundf.c b/libc/sysdeps/ieee754/flt-32/s_roundf.c
new file mode 100644
index 000000000..0b2498779
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_roundf.c
@@ -0,0 +1,73 @@
+/* Round float to integer away from zero.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+static const float huge = 1.0e30;
+
+
+float
+__roundf (float x)
+{
+ int32_t i0, j0;
+
+ GET_FLOAT_WORD (i0, x);
+ j0 = ((i0 >> 23) & 0xff) - 0x7f;
+ if (j0 < 23)
+ {
+ if (j0 < 0)
+ {
+ if (huge + x > 0.0F)
+ {
+ i0 &= 0x80000000;
+ if (j0 == -1)
+ i0 |= 0x3f800000;
+ }
+ }
+ else
+ {
+ u_int32_t i = 0x007fffff >> j0;
+ if ((i0 & i) == 0)
+ /* X is integral. */
+ return x;
+ if (huge + x > 0.0F)
+ {
+ /* Raise inexact if x != 0. */
+ i0 += 0x00400000 >> j0;
+ i0 &= ~i;
+ }
+ }
+ }
+ else
+ {
+ if (j0 == 0x80)
+ /* Inf or NaN. */
+ return x + x;
+ else
+ return x;
+ }
+
+ SET_FLOAT_WORD (x, i0);
+ return x;
+}
+weak_alias (__roundf, roundf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_scalblnf.c b/libc/sysdeps/ieee754/flt-32/s_scalblnf.c
new file mode 100644
index 000000000..4ed48733c
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_scalblnf.c
@@ -0,0 +1,63 @@
+/* s_scalbnf.c -- float version of s_scalbn.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: s_scalbnf.c,v 1.4 1995/05/10 20:48:10 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+two25 = 3.355443200e+07, /* 0x4c000000 */
+twom25 = 2.9802322388e-08, /* 0x33000000 */
+huge = 1.0e+30,
+tiny = 1.0e-30;
+
+#ifdef __STDC__
+ float __scalblnf (float x, long int n)
+#else
+ float __scalblnf (x,n)
+ float x; long int n;
+#endif
+{
+ int32_t k,ix;
+ GET_FLOAT_WORD(ix,x);
+ k = (ix&0x7f800000)>>23; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((ix&0x7fffffff)==0) return x; /* +-0 */
+ x *= two25;
+ GET_FLOAT_WORD(ix,x);
+ k = ((ix&0x7f800000)>>23) - 25;
+ }
+ if (k==0xff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (n> 50000 || k > 0xfe)
+ return huge*copysignf(huge,x); /* overflow */
+ if (n< -50000)
+ return tiny*copysignf(tiny,x); /*underflow*/
+ if (k > 0) /* normal result */
+ {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
+ if (k <= -25)
+ return tiny*copysignf(tiny,x); /*underflow*/
+ k += 25; /* subnormal result */
+ SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
+ return x*twom25;
+}
+weak_alias (__scalblnf, scalblnf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_scalbnf.c b/libc/sysdeps/ieee754/flt-32/s_scalbnf.c
new file mode 100644
index 000000000..407cf607c
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_scalbnf.c
@@ -0,0 +1,63 @@
+/* s_scalbnf.c -- float version of s_scalbn.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: s_scalbnf.c,v 1.4 1995/05/10 20:48:10 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+two25 = 3.355443200e+07, /* 0x4c000000 */
+twom25 = 2.9802322388e-08, /* 0x33000000 */
+huge = 1.0e+30,
+tiny = 1.0e-30;
+
+#ifdef __STDC__
+ float __scalbnf (float x, int n)
+#else
+ float __scalbnf (x,n)
+ float x; int n;
+#endif
+{
+ int32_t k,ix;
+ GET_FLOAT_WORD(ix,x);
+ k = (ix&0x7f800000)>>23; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((ix&0x7fffffff)==0) return x; /* +-0 */
+ x *= two25;
+ GET_FLOAT_WORD(ix,x);
+ k = ((ix&0x7f800000)>>23) - 25;
+ }
+ if (k==0xff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (n> 50000 || k > 0xfe)
+ return huge*__copysignf(huge,x); /* overflow */
+ if (n< -50000)
+ return tiny*__copysignf(tiny,x); /*underflow*/
+ if (k > 0) /* normal result */
+ {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
+ if (k <= -25)
+ return tiny*__copysignf(tiny,x); /*underflow*/
+ k += 25; /* subnormal result */
+ SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
+ return x*twom25;
+}
+weak_alias (__scalbnf, scalbnf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_signbitf.c b/libc/sysdeps/ieee754/flt-32/s_signbitf.c
new file mode 100644
index 000000000..5bf984dc5
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_signbitf.c
@@ -0,0 +1,32 @@
+/* Return nonzero value if number is negative.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+int
+__signbitf (float x)
+{
+ int32_t hx;
+
+ GET_FLOAT_WORD (hx, x);
+ return hx & 0x80000000;
+}
diff --git a/libc/sysdeps/ieee754/flt-32/s_sincosf.c b/libc/sysdeps/ieee754/flt-32/s_sincosf.c
new file mode 100644
index 000000000..0311473b7
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_sincosf.c
@@ -0,0 +1,74 @@
+/* Compute sine and cosine of argument.
+ Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+void
+__sincosf (float x, float *sinx, float *cosx)
+{
+ int32_t ix;
+
+ /* High word of x. */
+ GET_FLOAT_WORD (ix, x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if (ix <= 0x3f490fd8)
+ {
+ *sinx = __kernel_sinf (x, 0.0, 0);
+ *cosx = __kernel_cosf (x, 0.0);
+ }
+ else if (ix>=0x7f800000)
+ {
+ /* sin(Inf or NaN) is NaN */
+ *sinx = *cosx = x - x;
+ }
+ else
+ {
+ /* Argument reduction needed. */
+ float y[2];
+ int n;
+
+ n = __ieee754_rem_pio2f (x, y);
+ switch (n & 3)
+ {
+ case 0:
+ *sinx = __kernel_sinf (y[0], y[1], 1);
+ *cosx = __kernel_cosf (y[0], y[1]);
+ break;
+ case 1:
+ *sinx = __kernel_cosf (y[0], y[1]);
+ *cosx = -__kernel_sinf (y[0], y[1], 1);
+ break;
+ case 2:
+ *sinx = -__kernel_sinf (y[0], y[1], 1);
+ *cosx = -__kernel_cosf (y[0], y[1]);
+ break;
+ default:
+ *sinx = -__kernel_cosf (y[0], y[1]);
+ *cosx = __kernel_sinf (y[0], y[1], 1);
+ break;
+ }
+ }
+}
+weak_alias (__sincosf, sincosf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_sinf.c b/libc/sysdeps/ieee754/flt-32/s_sinf.c
new file mode 100644
index 000000000..76a7c21fc
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_sinf.c
@@ -0,0 +1,54 @@
+/* s_sinf.c -- float version of s_sin.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: s_sinf.c,v 1.4 1995/05/10 20:48:16 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float __sinf(float x)
+#else
+ float __sinf(x)
+ float x;
+#endif
+{
+ float y[2],z=0.0;
+ int32_t n, ix;
+
+ GET_FLOAT_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3f490fd8) return __kernel_sinf(x,z,0);
+
+ /* sin(Inf or NaN) is NaN */
+ else if (ix>=0x7f800000) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2f(x,y);
+ switch(n&3) {
+ case 0: return __kernel_sinf(y[0],y[1],1);
+ case 1: return __kernel_cosf(y[0],y[1]);
+ case 2: return -__kernel_sinf(y[0],y[1],1);
+ default:
+ return -__kernel_cosf(y[0],y[1]);
+ }
+ }
+}
+weak_alias (__sinf, sinf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_tanf.c b/libc/sysdeps/ieee754/flt-32/s_tanf.c
new file mode 100644
index 000000000..e8f6016c3
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_tanf.c
@@ -0,0 +1,49 @@
+/* s_tanf.c -- float version of s_tan.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: s_tanf.c,v 1.4 1995/05/10 20:48:20 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float __tanf(float x)
+#else
+ float __tanf(x)
+ float x;
+#endif
+{
+ float y[2],z=0.0;
+ int32_t n, ix;
+
+ GET_FLOAT_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3f490fda) return __kernel_tanf(x,z,1);
+
+ /* tan(Inf or NaN) is NaN */
+ else if (ix>=0x7f800000) return x-x; /* NaN */
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2f(x,y);
+ return __kernel_tanf(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even
+ -1 -- n odd */
+ }
+}
+weak_alias (__tanf, tanf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_tanhf.c b/libc/sysdeps/ieee754/flt-32/s_tanhf.c
new file mode 100644
index 000000000..2a0ca9f3d
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_tanhf.c
@@ -0,0 +1,67 @@
+/* s_tanhf.c -- float version of s_tanh.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: s_tanhf.c,v 1.4 1995/05/10 20:48:24 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const float one=1.0, two=2.0, tiny = 1.0e-30;
+#else
+static float one=1.0, two=2.0, tiny = 1.0e-30;
+#endif
+
+#ifdef __STDC__
+ float __tanhf(float x)
+#else
+ float __tanhf(x)
+ float x;
+#endif
+{
+ float t,z;
+ int32_t jx,ix;
+
+ GET_FLOAT_WORD(jx,x);
+ ix = jx&0x7fffffff;
+
+ /* x is INF or NaN */
+ if(ix>=0x7f800000) {
+ if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */
+ else return one/x-one; /* tanh(NaN) = NaN */
+ }
+
+ /* |x| < 22 */
+ if (ix < 0x41b00000) { /* |x|<22 */
+ if (ix == 0)
+ return x; /* x == +-0 */
+ if (ix<0x24000000) /* |x|<2**-55 */
+ return x*(one+x); /* tanh(small) = small */
+ if (ix>=0x3f800000) { /* |x|>=1 */
+ t = __expm1f(two*fabsf(x));
+ z = one - two/(t+two);
+ } else {
+ t = __expm1f(-two*fabsf(x));
+ z= -t/(t+two);
+ }
+ /* |x| > 22, return +-1 */
+ } else {
+ z = one - tiny; /* raised inexact flag */
+ }
+ return (jx>=0)? z: -z;
+}
+weak_alias (__tanhf, tanhf)
diff --git a/libc/sysdeps/ieee754/flt-32/s_truncf.c b/libc/sysdeps/ieee754/flt-32/s_truncf.c
new file mode 100644
index 000000000..136f77a56
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/s_truncf.c
@@ -0,0 +1,52 @@
+/* Truncate argument to nearest integral value not larger than the argument.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+float
+__truncf (float x)
+{
+ int32_t i0, j0;
+ int sx;
+
+ GET_FLOAT_WORD (i0, x);
+ sx = i0 & 0x80000000;
+ j0 = ((i0 >> 23) & 0xff) - 0x7f;
+ if (j0 < 23)
+ {
+ if (j0 < 0)
+ /* The magnitude of the number is < 1 so the result is +-0. */
+ SET_FLOAT_WORD (x, sx);
+ else
+ SET_FLOAT_WORD (x, sx | (i0 & ~(0x007fffff >> j0)));
+ }
+ else
+ {
+ if (j0 == 0x80)
+ /* x is inf or NaN. */
+ return x + x;
+ }
+
+ return x;
+}
+weak_alias (__truncf, truncf)
diff --git a/libc/sysdeps/ieee754/flt-32/t_exp2f.h b/libc/sysdeps/ieee754/flt-32/t_exp2f.h
new file mode 100644
index 000000000..f4b94b049
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/t_exp2f.h
@@ -0,0 +1,352 @@
+/* Accurate tables for exp2f().
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Geoffrey Keating <geoffk@ozemail.com.au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This table has the property that, for all integers -128 <= i <= 127,
+ exp(i/256.0 + __exp2f_deltatable[i-128]) == __exp2f_atable[i+128] + r
+ for some -2^-35 < r < 2^-35 (abs(r) < 2^-36 if i <= 0); and that
+ __exp2f_deltatable[i+128] == t * 2^-30
+ for integer t so that abs(t) <= 43447 * 2^0. */
+
+#define W30 (9.31322575e-10)
+static const float __exp2f_deltatable[256] = {
+ -810*W30, 283*W30, -1514*W30, 1304*W30,
+ -1148*W30, -98*W30, -744*W30, -156*W30,
+ -419*W30, -155*W30, 474*W30, 167*W30,
+ -1984*W30, -826*W30, 692*W30, 781*W30,
+ -578*W30, -411*W30, -129*W30, -1500*W30,
+ 654*W30, -141*W30, -816*W30, -53*W30,
+ 148*W30, 493*W30, -2214*W30, 760*W30,
+ 260*W30, 750*W30, -1300*W30, 1424*W30,
+ -1445*W30, -339*W30, -680*W30, -349*W30,
+ -922*W30, 531*W30, 193*W30, -2892*W30,
+ 290*W30, -2145*W30, -276*W30, 485*W30,
+ -695*W30, 215*W30, -7093*W30, 412*W30,
+ -4596*W30, 367*W30, 592*W30, -615*W30,
+ -97*W30, -1066*W30, 972*W30, -226*W30,
+ -625*W30, -374*W30, -5647*W30, -180*W30,
+ 20349*W30, -447*W30, 111*W30, -4164*W30,
+ -87*W30, -21*W30, -251*W30, 66*W30,
+ -517*W30, 2093*W30, -263*W30, 182*W30,
+ -601*W30, 475*W30, -483*W30, -1251*W30,
+ -373*W30, 1471*W30, -92*W30, -215*W30,
+ -97*W30, -190*W30, 0*W30, -290*W30,
+ -2647*W30, 1940*W30, -582*W30, 28*W30,
+ 833*W30, 1493*W30, 34*W30, 321*W30,
+ 3327*W30, -35*W30, 177*W30, -135*W30,
+ -796*W30, -428*W30, 129*W30, 9332*W30,
+ -12*W30, -69*W30, -1743*W30, 6508*W30,
+ -60*W30, 359*W30, 43447*W30, 15*W30,
+ -23*W30, -305*W30, -375*W30, -652*W30,
+ 667*W30, 269*W30, -1575*W30, 185*W30,
+ -329*W30, 200*W30, 6002*W30, 163*W30,
+ -647*W30, 19*W30, -603*W30, -755*W30,
+ 742*W30, -438*W30, 3587*W30, 2560*W30,
+ 0*W30, -520*W30, -241*W30, -299*W30,
+ -1270*W30, -991*W30, -1138*W30, 255*W30,
+ -1192*W30, 1722*W30, 1023*W30, 3700*W30,
+ -1388*W30, -1551*W30, -2549*W30, 27*W30,
+ 282*W30, 673*W30, 113*W30, 1561*W30,
+ 72*W30, 873*W30, 87*W30, -395*W30,
+ -433*W30, 629*W30, 3440*W30, -284*W30,
+ -592*W30, -103*W30, -46*W30, -3844*W30,
+ 1712*W30, 303*W30, 1555*W30, -631*W30,
+ -1400*W30, -961*W30, -854*W30, -276*W30,
+ 407*W30, 833*W30, -345*W30, -1501*W30,
+ 121*W30, -1581*W30, 400*W30, 150*W30,
+ 1224*W30, -139*W30, -563*W30, 879*W30,
+ 933*W30, 2939*W30, 788*W30, 211*W30,
+ 530*W30, -192*W30, 706*W30, -13347*W30,
+ 1065*W30, 3*W30, 111*W30, -208*W30,
+ -360*W30, -532*W30, -291*W30, 483*W30,
+ 987*W30, -33*W30, -1373*W30, -166*W30,
+ -1174*W30, -3955*W30, 1601*W30, -280*W30,
+ 1405*W30, 600*W30, -1659*W30, -23*W30,
+ 390*W30, 449*W30, 570*W30, -13143*W30,
+ -9*W30, -1646*W30, 1201*W30, 294*W30,
+ 2181*W30, -1173*W30, 1388*W30, -4504*W30,
+ 190*W30, -2304*W30, 211*W30, 239*W30,
+ 48*W30, -817*W30, 1018*W30, 1828*W30,
+ -663*W30, 1408*W30, 408*W30, -36*W30,
+ 1295*W30, -230*W30, 1341*W30, 9*W30,
+ 40*W30, 705*W30, 186*W30, 376*W30,
+ 557*W30, 5866*W30, 363*W30, -1558*W30,
+ 718*W30, 669*W30, 1369*W30, -2972*W30,
+ -468*W30, -121*W30, -219*W30, 667*W30,
+ 29954*W30, 366*W30, 48*W30, -203*W30
+};
+
+static const float __exp2f_atable[256] /* __attribute__((mode(SF))) */ = {
+ 0.707106411447, /* 0x0.b504ecfff */
+ 0.709024071690, /* 0x0.b58299fff */
+ 0.710945606239, /* 0x0.b60088000 */
+ 0.712874472142, /* 0x0.b67ef1000 */
+ 0.714806139464, /* 0x0.b6fd88fff */
+ 0.716744661340, /* 0x0.b77c94000 */
+ 0.718687653549, /* 0x0.b7fbea000 */
+ 0.720636486992, /* 0x0.b87ba1fff */
+ 0.722590208040, /* 0x0.b8fbabfff */
+ 0.724549472323, /* 0x0.b97c12fff */
+ 0.726514220228, /* 0x0.b9fcd5fff */
+ 0.728483855735, /* 0x0.ba7deb000 */
+ 0.730457961549, /* 0x0.baff4afff */
+ 0.732438981522, /* 0x0.bb811efff */
+ 0.734425544748, /* 0x0.bc0350000 */
+ 0.736416816713, /* 0x0.bc85d0000 */
+ 0.738412797450, /* 0x0.bd089efff */
+ 0.740414917465, /* 0x0.bd8bd4fff */
+ 0.742422521111, /* 0x0.be0f66fff */
+ 0.744434773914, /* 0x0.be9346fff */
+ 0.746454179287, /* 0x0.bf179f000 */
+ 0.748477637755, /* 0x0.bf9c3afff */
+ 0.750506639473, /* 0x0.c02133fff */
+ 0.752541840064, /* 0x0.c0a694fff */
+ 0.754582285889, /* 0x0.c12c4e000 */
+ 0.756628334525, /* 0x0.c1b265000 */
+ 0.758678436269, /* 0x0.c238bffff */
+ 0.760736882681, /* 0x0.c2bfa6fff */
+ 0.762799203401, /* 0x0.c346cf000 */
+ 0.764867603790, /* 0x0.c3ce5d000 */
+ 0.766940355298, /* 0x0.c45633fff */
+ 0.769021093841, /* 0x0.c4de90fff */
+ 0.771104693409, /* 0x0.c5671dfff */
+ 0.773195922364, /* 0x0.c5f02afff */
+ 0.775292098512, /* 0x0.c6798afff */
+ 0.777394294745, /* 0x0.c70350000 */
+ 0.779501736166, /* 0x0.c78d6d000 */
+ 0.781615912910, /* 0x0.c817fafff */
+ 0.783734917628, /* 0x0.c8a2d9fff */
+ 0.785858273516, /* 0x0.c92e02000 */
+ 0.787990570071, /* 0x0.c9b9c0000 */
+ 0.790125787245, /* 0x0.ca45aefff */
+ 0.792268991467, /* 0x0.cad223fff */
+ 0.794417440881, /* 0x0.cb5ef0fff */
+ 0.796570718287, /* 0x0.cbec0efff */
+ 0.798730909811, /* 0x0.cc79a0fff */
+ 0.800892710672, /* 0x0.cd074dfff */
+ 0.803068041795, /* 0x0.cd95ddfff */
+ 0.805242776881, /* 0x0.ce2464000 */
+ 0.807428598393, /* 0x0.ceb3a3fff */
+ 0.809617877002, /* 0x0.cf431dfff */
+ 0.811812341211, /* 0x0.cfd2eefff */
+ 0.814013659956, /* 0x0.d06333000 */
+ 0.816220164311, /* 0x0.d0f3ce000 */
+ 0.818434238424, /* 0x0.d184e7fff */
+ 0.820652604094, /* 0x0.d21649fff */
+ 0.822877407074, /* 0x0.d2a818000 */
+ 0.825108587751, /* 0x0.d33a51000 */
+ 0.827342867839, /* 0x0.d3ccbdfff */
+ 0.829588949684, /* 0x0.d45ff1000 */
+ 0.831849217401, /* 0x0.d4f411fff */
+ 0.834093391880, /* 0x0.d58724fff */
+ 0.836355149750, /* 0x0.d61b5f000 */
+ 0.838620424257, /* 0x0.d6afd3fff */
+ 0.840896368027, /* 0x0.d744fc000 */
+ 0.843176305293, /* 0x0.d7da66fff */
+ 0.845462262643, /* 0x0.d87037000 */
+ 0.847754716864, /* 0x0.d90673fff */
+ 0.850052893157, /* 0x0.d99d10fff */
+ 0.852359056469, /* 0x0.da3433fff */
+ 0.854668736446, /* 0x0.dacb91fff */
+ 0.856986224651, /* 0x0.db6373000 */
+ 0.859309315673, /* 0x0.dbfbb1fff */
+ 0.861639738080, /* 0x0.dc946bfff */
+ 0.863975346095, /* 0x0.dd2d7d000 */
+ 0.866317391394, /* 0x0.ddc6f9fff */
+ 0.868666708472, /* 0x0.de60f1000 */
+ 0.871022939695, /* 0x0.defb5c000 */
+ 0.873383641229, /* 0x0.df9611fff */
+ 0.875751554968, /* 0x0.e03141000 */
+ 0.878126025200, /* 0x0.e0ccde000 */
+ 0.880506813521, /* 0x0.e168e4fff */
+ 0.882894217966, /* 0x0.e2055afff */
+ 0.885287821299, /* 0x0.e2a239000 */
+ 0.887686729423, /* 0x0.e33f6ffff */
+ 0.890096127973, /* 0x0.e3dd56fff */
+ 0.892507970338, /* 0x0.e47b67000 */
+ 0.894928157336, /* 0x0.e51a03000 */
+ 0.897355020043, /* 0x0.e5b90efff */
+ 0.899788379682, /* 0x0.e65888000 */
+ 0.902227103705, /* 0x0.e6f85afff */
+ 0.904673457151, /* 0x0.e798ae000 */
+ 0.907128036008, /* 0x0.e8398afff */
+ 0.909585535528, /* 0x0.e8da99000 */
+ 0.912051796915, /* 0x0.e97c3a000 */
+ 0.914524436003, /* 0x0.ea1e46000 */
+ 0.917003571999, /* 0x0.eac0bf000 */
+ 0.919490039339, /* 0x0.eb63b2fff */
+ 0.921983361257, /* 0x0.ec071a000 */
+ 0.924488604054, /* 0x0.ecab48fff */
+ 0.926989555360, /* 0x0.ed4f30000 */
+ 0.929502844812, /* 0x0.edf3e6000 */
+ 0.932021975503, /* 0x0.ee98fdfff */
+ 0.934553921208, /* 0x0.ef3eecfff */
+ 0.937083780759, /* 0x0.efe4b8fff */
+ 0.939624726786, /* 0x0.f08b3f000 */
+ 0.942198514924, /* 0x0.f133ebfff */
+ 0.944726586343, /* 0x0.f1d99a000 */
+ 0.947287976728, /* 0x0.f28176fff */
+ 0.949856162070, /* 0x0.f329c5fff */
+ 0.952431440345, /* 0x0.f3d28bfff */
+ 0.955013573175, /* 0x0.f47bc5000 */
+ 0.957603693021, /* 0x0.f52584000 */
+ 0.960199773321, /* 0x0.f5cfa7000 */
+ 0.962801992906, /* 0x0.f67a31000 */
+ 0.965413510788, /* 0x0.f72556fff */
+ 0.968030691152, /* 0x0.f7d0dc000 */
+ 0.970655620084, /* 0x0.f87ce2fff */
+ 0.973290979849, /* 0x0.f92998fff */
+ 0.975926160805, /* 0x0.f9d64bfff */
+ 0.978571653370, /* 0x0.fa83ac000 */
+ 0.981225252139, /* 0x0.fb3193fff */
+ 0.983885228626, /* 0x0.fbdfe6fff */
+ 0.986552715296, /* 0x0.fc8eb7fff */
+ 0.989228487027, /* 0x0.fd3e14000 */
+ 0.991909801964, /* 0x0.fdedcd000 */
+ 0.994601726545, /* 0x0.fe9e38000 */
+ 0.997297704209, /* 0x0.ff4ee6fff */
+ 1.000000000000, /* 0x1.000000000 */
+ 1.002710938457, /* 0x1.00b1aa000 */
+ 1.005429744692, /* 0x1.0163d7ffe */
+ 1.008155703526, /* 0x1.02167dffe */
+ 1.010888457284, /* 0x1.02c995fff */
+ 1.013629436498, /* 0x1.037d38000 */
+ 1.016377568250, /* 0x1.043152000 */
+ 1.019134163841, /* 0x1.04e5f9ffe */
+ 1.021896362316, /* 0x1.059b00000 */
+ 1.024668931945, /* 0x1.0650b3ffe */
+ 1.027446627635, /* 0x1.0706be001 */
+ 1.030234098408, /* 0x1.07bd6bffe */
+ 1.033023953416, /* 0x1.087441ffe */
+ 1.035824656494, /* 0x1.092bce000 */
+ 1.038632392900, /* 0x1.09e3d0001 */
+ 1.041450142840, /* 0x1.0a9c79ffe */
+ 1.044273972530, /* 0x1.0b558a001 */
+ 1.047105550795, /* 0x1.0c0f1c001 */
+ 1.049944162390, /* 0x1.0cc924001 */
+ 1.052791833895, /* 0x1.0d83c4001 */
+ 1.055645227426, /* 0x1.0e3ec3fff */
+ 1.058507919326, /* 0x1.0efa60001 */
+ 1.061377286898, /* 0x1.0fb66bfff */
+ 1.064254641510, /* 0x1.1072fdffe */
+ 1.067140102389, /* 0x1.113018000 */
+ 1.070034146304, /* 0x1.11edc1fff */
+ 1.072937250162, /* 0x1.12ac04001 */
+ 1.075843691823, /* 0x1.136a7dfff */
+ 1.078760385496, /* 0x1.1429a3ffe */
+ 1.081685543070, /* 0x1.14e958000 */
+ 1.084618330005, /* 0x1.15a98c000 */
+ 1.087556362176, /* 0x1.166a18001 */
+ 1.090508937863, /* 0x1.172b98001 */
+ 1.093464612954, /* 0x1.17ed4bfff */
+ 1.096430182434, /* 0x1.18afa5ffe */
+ 1.099401354802, /* 0x1.19725e000 */
+ 1.102381587017, /* 0x1.1a35adfff */
+ 1.105370759965, /* 0x1.1af994000 */
+ 1.108367800686, /* 0x1.1bbdfdffe */
+ 1.111373305331, /* 0x1.1c82f6000 */
+ 1.114387035385, /* 0x1.1d4878001 */
+ 1.117408752440, /* 0x1.1e0e7ffff */
+ 1.120437502874, /* 0x1.1ed4fe000 */
+ 1.123474478729, /* 0x1.1f9c06000 */
+ 1.126521706601, /* 0x1.2063ba001 */
+ 1.129574775716, /* 0x1.212bd0001 */
+ 1.132638812065, /* 0x1.21f49e000 */
+ 1.135709524130, /* 0x1.22bddbffe */
+ 1.138789534565, /* 0x1.2387b5fff */
+ 1.141876101508, /* 0x1.2451fe000 */
+ 1.144971728301, /* 0x1.251cddffe */
+ 1.148077130296, /* 0x1.25e861ffe */
+ 1.151189923305, /* 0x1.26b462001 */
+ 1.154312610610, /* 0x1.278107ffe */
+ 1.157440662410, /* 0x1.284e08001 */
+ 1.160578370109, /* 0x1.291baa001 */
+ 1.163725256932, /* 0x1.29e9e6000 */
+ 1.166879892324, /* 0x1.2ab8a3ffe */
+ 1.170044302935, /* 0x1.2b8805fff */
+ 1.173205971694, /* 0x1.2c5739ffe */
+ 1.176397800428, /* 0x1.2d2867ffe */
+ 1.179586529747, /* 0x1.2df962001 */
+ 1.182784795737, /* 0x1.2ecafbffe */
+ 1.185991406414, /* 0x1.2f9d21ffe */
+ 1.189206838636, /* 0x1.306fdc001 */
+ 1.192430973067, /* 0x1.314328000 */
+ 1.195664167430, /* 0x1.32170c001 */
+ 1.198906540890, /* 0x1.32eb8a001 */
+ 1.202157497408, /* 0x1.33c098000 */
+ 1.205416083326, /* 0x1.349625fff */
+ 1.208683252332, /* 0x1.356c43fff */
+ 1.211961269402, /* 0x1.364318001 */
+ 1.215246438983, /* 0x1.371a64000 */
+ 1.218539118740, /* 0x1.37f22dffe */
+ 1.221847295770, /* 0x1.38cafc000 */
+ 1.225158572187, /* 0x1.39a3fdfff */
+ 1.228481650325, /* 0x1.3a7dc5ffe */
+ 1.231811761846, /* 0x1.3b5803fff */
+ 1.235149741144, /* 0x1.3c32c5ffe */
+ 1.238499879811, /* 0x1.3d0e53ffe */
+ 1.241858124726, /* 0x1.3dea69fff */
+ 1.245225191102, /* 0x1.3ec713fff */
+ 1.248601436624, /* 0x1.3fa458000 */
+ 1.251975655584, /* 0x1.40817a001 */
+ 1.255380749731, /* 0x1.4160a2001 */
+ 1.258783102010, /* 0x1.423f9bffe */
+ 1.262198328973, /* 0x1.431f6e000 */
+ 1.265619754780, /* 0x1.43ffa7fff */
+ 1.269052743928, /* 0x1.44e0a4001 */
+ 1.272490739830, /* 0x1.45c1f4000 */
+ 1.275942921659, /* 0x1.46a432001 */
+ 1.279397487615, /* 0x1.478697ffe */
+ 1.282870173427, /* 0x1.486a2dffe */
+ 1.286346316319, /* 0x1.494dfdffe */
+ 1.289836049094, /* 0x1.4a32b2001 */
+ 1.293333172770, /* 0x1.4b17e1ffe */
+ 1.296839594835, /* 0x1.4bfdadfff */
+ 1.300354957560, /* 0x1.4ce40fffe */
+ 1.303882122055, /* 0x1.4dcb38001 */
+ 1.307417988757, /* 0x1.4eb2f1ffe */
+ 1.310960650439, /* 0x1.4f9b1dfff */
+ 1.314516782746, /* 0x1.50842bfff */
+ 1.318079948424, /* 0x1.516daffff */
+ 1.321653246888, /* 0x1.5257de000 */
+ 1.325237751030, /* 0x1.5342c8001 */
+ 1.328829526907, /* 0x1.542e2c000 */
+ 1.332433700535, /* 0x1.551a5fffe */
+ 1.336045145966, /* 0x1.56070dffe */
+ 1.339667558645, /* 0x1.56f473ffe */
+ 1.343300342533, /* 0x1.57e287ffe */
+ 1.346941947961, /* 0x1.58d130001 */
+ 1.350594043714, /* 0x1.59c087ffe */
+ 1.354256033883, /* 0x1.5ab085fff */
+ 1.357932448365, /* 0x1.5ba175ffe */
+ 1.361609339707, /* 0x1.5c926dfff */
+ 1.365299344044, /* 0x1.5d8441ffe */
+ 1.369003057507, /* 0x1.5e76fc001 */
+ 1.372714757920, /* 0x1.5f6a3c000 */
+ 1.376437187179, /* 0x1.605e2fffe */
+ 1.380165219333, /* 0x1.615282001 */
+ 1.383909463864, /* 0x1.6247e3ffe */
+ 1.387661933907, /* 0x1.633dd0000 */
+ 1.391424179060, /* 0x1.64345fffe */
+ 1.395197510706, /* 0x1.652ba9fff */
+ 1.399006724329, /* 0x1.66254dffe */
+ 1.402773022651, /* 0x1.671c22000 */
+ 1.406576037403, /* 0x1.68155dfff */
+ 1.410389423392, /* 0x1.690f48001 */
+};
diff --git a/libc/sysdeps/ieee754/flt-32/w_expf.c b/libc/sysdeps/ieee754/flt-32/w_expf.c
new file mode 100644
index 000000000..ad38fac0f
--- /dev/null
+++ b/libc/sysdeps/ieee754/flt-32/w_expf.c
@@ -0,0 +1,59 @@
+/* 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"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+o_threshold= 8.8721679688e+01, /* 0x42b17180 */
+u_threshold= -1.0397208405e+02; /* 0xc2cff1b5 */
+
+#ifdef __STDC__
+ float __expf(float x) /* wrapper expf */
+#else
+ float __expf(x) /* wrapper expf */
+ float x;
+#endif
+{
+#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
+}
+weak_alias (__expf, expf)
diff --git a/libc/sysdeps/ieee754/ieee754.h b/libc/sysdeps/ieee754/ieee754.h
new file mode 100644
index 000000000..7131e5de6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ieee754.h
@@ -0,0 +1,199 @@
+/* Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _IEEE754_H
+
+#define _IEEE754_H 1
+#include <features.h>
+
+#include <endian.h>
+
+__BEGIN_DECLS
+
+union ieee754_float
+ {
+ float f;
+
+ /* This is the IEEE 754 single-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int mantissa:23;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int mantissa:23;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int quiet_nan:1;
+ unsigned int mantissa:22;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int mantissa:22;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee_nan;
+ };
+
+#define IEEE754_FLOAT_BIAS 0x7f /* Added to exponent. */
+
+
+union ieee754_double
+ {
+ double d;
+
+ /* This is the IEEE 754 double-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:20;
+ unsigned int mantissa1:32;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# if __FLOAT_WORD_ORDER == BIG_ENDIAN
+ unsigned int mantissa0:20;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+ unsigned int mantissa1:32;
+# else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:20;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+# endif
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ unsigned int quiet_nan:1;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:19;
+ unsigned int mantissa1:32;
+#else
+# if __FLOAT_WORD_ORDER == BIG_ENDIAN
+ unsigned int mantissa0:19;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+ unsigned int mantissa1:32;
+# else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:19;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+# endif
+#endif
+ } ieee_nan;
+ };
+
+#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */
+
+
+union ieee854_long_double
+ {
+ long double d;
+
+ /* This is the IEEE 854 double-extended-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:15;
+ unsigned int empty:16;
+ unsigned int mantissa0:32;
+ unsigned int mantissa1:32;
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# if __FLOAT_WORD_ORDER == BIG_ENDIAN
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty:16;
+ unsigned int mantissa0:32;
+ unsigned int mantissa1:32;
+# else
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:32;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty:16;
+# endif
+#endif
+ } ieee;
+
+ /* This is for NaNs in the IEEE 854 double-extended-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:15;
+ unsigned int empty:16;
+ unsigned int one:1;
+ unsigned int quiet_nan:1;
+ unsigned int mantissa0:30;
+ unsigned int mantissa1:32;
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# if __FLOAT_WORD_ORDER == BIG_ENDIAN
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty:16;
+ unsigned int mantissa0:30;
+ unsigned int quiet_nan:1;
+ unsigned int one:1;
+ unsigned int mantissa1:32;
+# else
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:30;
+ unsigned int quiet_nan:1;
+ unsigned int one:1;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty:16;
+# endif
+#endif
+ } ieee_nan;
+ };
+
+#define IEEE854_LONG_DOUBLE_BIAS 0x3fff
+
+__END_DECLS
+
+#endif /* ieee754.h */
diff --git a/libc/sysdeps/ieee754/k_standard.c b/libc/sysdeps/ieee754/k_standard.c
new file mode 100644
index 000000000..d8fa2a449
--- /dev/null
+++ b/libc/sysdeps/ieee754/k_standard.c
@@ -0,0 +1,997 @@
+/* @(#)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 <assert.h>
+
+#ifndef _USE_WRITE
+#include <stdio.h> /* fputs(), stderr */
+#define WRITE2(u,v) fputs(u, stderr)
+#else /* !defined(_USE_WRITE) */
+#include <unistd.h> /* write */
+#define WRITE2(u,v) write(2, u, v)
+#undef fflush
+#endif /* !defined(_USE_WRITE) */
+
+/* XXX gcc versions until now don't delay the 0.0/0.0 division until
+ runtime but produce NaN at copile time. This is wrong since the
+ exceptions are not set correctly. */
+#if 0 && defined __STDC__
+static const double zero = 0.0; /* used as const */
+#else
+static double zero = 0.0; /* used as const */
+#endif
+
+/*
+ * 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-- tgamma(finite) overflow
+ * 41-- tgamma(-integer)
+ * 42-- pow(NaN,0.0)
+ * 43-- +0**neg
+ * 44-- exp2 overflow
+ * 45-- exp2 underflow
+ * 46-- exp10 overflow
+ * 47-- exp10 underflow
+ * 48-- log2(0)
+ * 49-- log2(x<0)
+ * 50-- tgamma(+-0)
+ */
+
+
+#ifdef __STDC__
+ double __kernel_standard(double x, double y, int type)
+#else
+ double __kernel_standard(x,y,type)
+ double x,y; int type;
+#endif
+{
+ 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:
+ case 201:
+ /* acos(|x|>1) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "acos" : (type < 200
+ ? "acosf" : "acosl");;
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = NAN;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if(_LIB_VERSION == _SVID_) {
+ (void) WRITE2("acos: DOMAIN error\n", 19);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 2:
+ case 102:
+ case 202:
+ /* asin(|x|>1) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "asin" : (type < 200
+ ? "asinf" : "asinl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = NAN;
+ if(_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if(_LIB_VERSION == _SVID_) {
+ (void) WRITE2("asin: DOMAIN error\n", 19);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 3:
+ case 103:
+ case 203:
+ /* atan2(+-0,+-0) */
+ exc.arg1 = y;
+ exc.arg2 = x;
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "atan2" : (type < 200
+ ? "atan2f" : "atan2l");
+ assert (_LIB_VERSION == _SVID_);
+ exc.retval = HUGE;
+ if(_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if(_LIB_VERSION == _SVID_) {
+ (void) WRITE2("atan2: DOMAIN error\n", 20);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 4:
+ case 104:
+ case 204:
+ /* hypot(finite,finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "hypot" : (type < 200
+ ? "hypotf" : "hypotl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 5:
+ case 105:
+ case 205:
+ /* cosh(finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "cosh" : (type < 200
+ ? "coshf" : "coshl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 6:
+ case 106:
+ case 206:
+ /* exp(finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "exp" : (type < 200
+ ? "expf" : "expl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 7:
+ case 107:
+ case 207:
+ /* exp(finite) underflow */
+ exc.type = UNDERFLOW;
+ exc.name = type < 100 ? "exp" : (type < 200
+ ? "expf" : "expl");
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 8:
+ case 108:
+ case 208:
+ /* y0(0) = -inf */
+ exc.type = DOMAIN; /* should be SING for IEEE */
+ exc.name = type < 100 ? "y0" : (type < 200 ? "y0f" : "y0l");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("y0: DOMAIN error\n", 17);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 9:
+ case 109:
+ case 209:
+ /* y0(x<0) = NaN */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "y0" : (type < 200 ? "y0f" : "y0l");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("y0: DOMAIN error\n", 17);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 10:
+ case 110:
+ case 210:
+ /* y1(0) = -inf */
+ exc.type = DOMAIN; /* should be SING for IEEE */
+ exc.name = type < 100 ? "y1" : (type < 200 ? "y1f" : "y1l");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("y1: DOMAIN error\n", 17);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 11:
+ case 111:
+ case 211:
+ /* y1(x<0) = NaN */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "y1" : (type < 200 ? "y1f" : "y1l");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("y1: DOMAIN error\n", 17);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 12:
+ case 112:
+ case 212:
+ /* yn(n,0) = -inf */
+ exc.type = DOMAIN; /* should be SING for IEEE */
+ exc.name = type < 100 ? "yn" : (type < 200 ? "ynf" : "ynl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("yn: DOMAIN error\n", 17);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 13:
+ case 113:
+ case 213:
+ /* yn(x<0) = NaN */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "yn" : (type < 200 ? "ynf" : "ynl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("yn: DOMAIN error\n", 17);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 14:
+ case 114:
+ case 214:
+ /* lgamma(finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "lgamma" : (type < 200
+ ? "lgammaf" : "lgammal");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 15:
+ case 115:
+ case 215:
+ /* lgamma(-integer) or lgamma(0) */
+ exc.type = SING;
+ exc.name = type < 100 ? "lgamma" : (type < 200
+ ? "lgammaf" : "lgammal");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("lgamma: SING error\n", 19);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 16:
+ case 116:
+ case 216:
+ /* log(0) */
+ exc.type = SING;
+ exc.name = type < 100 ? "log" : (type < 200 ? "logf" : "logl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("log: SING error\n", 16);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 17:
+ case 117:
+ case 217:
+ /* log(x<0) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "log" : (type < 200 ? "logf" : "logl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = NAN;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("log: DOMAIN error\n", 18);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 18:
+ case 118:
+ case 218:
+ /* log10(0) */
+ exc.type = SING;
+ exc.name = type < 100 ? "log10" : (type < 200
+ ? "log10f" : "log10l");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("log10: SING error\n", 18);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 19:
+ case 119:
+ case 219:
+ /* log10(x<0) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "log10" : (type < 200
+ ? "log10f" : "log10l");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = NAN;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("log10: DOMAIN error\n", 20);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 20:
+ case 120:
+ case 220:
+ /* pow(0.0,0.0) */
+ /* error only if _LIB_VERSION == _SVID_ */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
+ exc.retval = zero;
+ if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
+ else if (!matherr(&exc)) {
+ (void) WRITE2("pow(0,0): DOMAIN error\n", 23);
+ __set_errno (EDOM);
+ }
+ break;
+ case 21:
+ case 121:
+ case 221:
+ /* pow(x,y) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
+ 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_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 22:
+ case 122:
+ case 222:
+ /* pow(x,y) underflow */
+ exc.type = UNDERFLOW;
+ exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 23:
+ case 123:
+ case 223:
+ /* -0**neg */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = zero;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 43:
+ case 143:
+ case 243:
+ /* +0**neg */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = zero;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 24:
+ case 124:
+ case 224:
+ /* neg**non-integral */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = zero;
+ else
+ exc.retval = zero/zero; /* X/Open allow NaN */
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 25:
+ case 125:
+ case 225:
+ /* sinh(finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "sinh" : (type < 200
+ ? "sinhf" : "sinhl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = ( (x>zero) ? HUGE : -HUGE);
+ else
+ exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 26:
+ case 126:
+ case 226:
+ /* sqrt(x<0) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "sqrt" : (type < 200
+ ? "sqrtf" : "sqrtl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = zero;
+ else
+ exc.retval = zero/zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("sqrt: DOMAIN error\n", 19);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 27:
+ case 127:
+ case 227:
+ /* fmod(x,0) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "fmod" : (type < 200
+ ? "fmodf" : "fmodl");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = x;
+ else
+ exc.retval = zero/zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("fmod: DOMAIN error\n", 20);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 28:
+ case 128:
+ case 228:
+ /* remainder(x,0) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "remainder" : (type < 200
+ ? "remainderf"
+ : "remainderl");
+ exc.retval = zero/zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("remainder: DOMAIN error\n", 24);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 29:
+ case 129:
+ case 229:
+ /* acosh(x<1) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "acosh" : (type < 200
+ ? "acoshf" : "acoshl");
+ exc.retval = zero/zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("acosh: DOMAIN error\n", 20);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 30:
+ case 130:
+ case 230:
+ /* atanh(|x|>1) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "atanh" : (type < 200
+ ? "atanhf" : "atanhl");
+ exc.retval = zero/zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("atanh: DOMAIN error\n", 20);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 31:
+ case 131:
+ case 231:
+ /* atanh(|x|=1) */
+ exc.type = SING;
+ exc.name = type < 100 ? "atanh" : (type < 200
+ ? "atanhf" : "atanhl");
+ exc.retval = x/zero; /* sign(x)*inf */
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("atanh: SING error\n", 18);
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 32:
+ case 132:
+ case 232:
+ /* scalb overflow; SVID also returns +-HUGE_VAL */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "scalb" : (type < 200
+ ? "scalbf" : "scalbl");
+ exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 33:
+ case 133:
+ case 233:
+ /* scalb underflow */
+ exc.type = UNDERFLOW;
+ exc.name = type < 100 ? "scalb" : (type < 200
+ ? "scalbf" : "scalbl");
+ exc.retval = __copysign(zero,x);
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 34:
+ case 134:
+ case 234:
+ /* j0(|x|>X_TLOSS) */
+ exc.type = TLOSS;
+ exc.name = type < 100 ? "j0" : (type < 200 ? "j0f" : "j0l");
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2(exc.name, 2);
+ (void) WRITE2(": TLOSS error\n", 14);
+ }
+ __set_errno (ERANGE);
+ }
+ break;
+ case 35:
+ case 135:
+ case 235:
+ /* y0(x>X_TLOSS) */
+ exc.type = TLOSS;
+ exc.name = type < 100 ? "y0" : (type < 200 ? "y0f" : "y0l");
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2(exc.name, 2);
+ (void) WRITE2(": TLOSS error\n", 14);
+ }
+ __set_errno (ERANGE);
+ }
+ break;
+ case 36:
+ case 136:
+ case 236:
+ /* j1(|x|>X_TLOSS) */
+ exc.type = TLOSS;
+ exc.name = type < 100 ? "j1" : (type < 200 ? "j1f" : "j1l");
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2(exc.name, 2);
+ (void) WRITE2(": TLOSS error\n", 14);
+ }
+ __set_errno (ERANGE);
+ }
+ break;
+ case 37:
+ case 137:
+ case 237:
+ /* y1(x>X_TLOSS) */
+ exc.type = TLOSS;
+ exc.name = type < 100 ? "y1" : (type < 200 ? "y1f" : "y1l");
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2(exc.name, 2);
+ (void) WRITE2(": TLOSS error\n", 14);
+ }
+ __set_errno (ERANGE);
+ }
+ break;
+ case 38:
+ case 138:
+ case 238:
+ /* jn(|x|>X_TLOSS) */
+ exc.type = TLOSS;
+ exc.name = type < 100 ? "jn" : (type < 200 ? "jnf" : "jnl");
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2(exc.name, 2);
+ (void) WRITE2(": TLOSS error\n", 14);
+ }
+ __set_errno (ERANGE);
+ }
+ break;
+ case 39:
+ case 139:
+ case 239:
+ /* yn(x>X_TLOSS) */
+ exc.type = TLOSS;
+ exc.name = type < 100 ? "yn" : (type < 200 ? "ynf" : "ynl");
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2(exc.name, 2);
+ (void) WRITE2(": TLOSS error\n", 14);
+ }
+ __set_errno (ERANGE);
+ }
+ break;
+ case 40:
+ case 140:
+ case 240:
+ /* tgamma(finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "tgamma" : (type < 200
+ ? "tgammaf" : "tgammal");
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 41:
+ case 141:
+ case 241:
+ /* tgamma(-integer) */
+ exc.type = SING;
+ exc.name = type < 100 ? "tgamma" : (type < 200
+ ? "tgammaf" : "tgammal");
+ exc.retval = NAN;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_) {
+ (void) WRITE2("tgamma: SING error\n", 18);
+ exc.retval = HUGE_VAL;
+ }
+ __set_errno (EDOM);
+ }
+ break;
+ case 42:
+ case 142:
+ case 242:
+ /* pow(NaN,0.0) */
+ /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
+ exc.retval = x;
+ if (_LIB_VERSION == _IEEE_ ||
+ _LIB_VERSION == _POSIX_) exc.retval = 1.0;
+ else if (!matherr(&exc)) {
+ __set_errno (EDOM);
+ }
+ break;
+
+ case 44:
+ case 144:
+ case 244:
+ /* exp(finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "exp2" : (type < 200
+ ? "exp2f" : "exp2l");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 45:
+ case 145:
+ case 245:
+ /* exp(finite) underflow */
+ exc.type = UNDERFLOW;
+ exc.name = type < 100 ? "exp2" : (type < 200
+ ? "exp2f" : "exp2l");
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+
+ case 46:
+ case 146:
+ case 246:
+ /* exp(finite) overflow */
+ exc.type = OVERFLOW;
+ exc.name = type < 100 ? "exp10" : (type < 200
+ ? "exp10f" : "exp10l");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 47:
+ case 147:
+ case 247:
+ /* exp(finite) underflow */
+ exc.type = UNDERFLOW;
+ exc.name = type < 100 ? "exp10" : (type < 200
+ ? "exp10f" : "exp10l");
+ exc.retval = zero;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (ERANGE);
+ }
+ break;
+ case 48:
+ case 148:
+ case 248:
+ /* log2(0) */
+ exc.type = SING;
+ exc.name = type < 100 ? "log2" : (type < 200
+ ? "log2f" : "log2l");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ __set_errno (EDOM);
+ }
+ break;
+ case 49:
+ case 149:
+ case 249:
+ /* log2(x<0) */
+ exc.type = DOMAIN;
+ exc.name = type < 100 ? "log2" : (type < 200
+ ? "log2f" : "log2l");
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = NAN;
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (EDOM);
+ else if (!matherr(&exc)) {
+ __set_errno (EDOM);
+ }
+ break;
+ case 50:
+ case 150:
+ case 250:
+ /* tgamma(+-0) */
+ exc.type = SING;
+ exc.name = type < 100 ? "tgamma" : (type < 200
+ ? "tgammaf" : "tgammal");
+ exc.retval = __copysign (HUGE_VAL, x);
+ if (_LIB_VERSION == _POSIX_)
+ __set_errno (ERANGE);
+ else if (!matherr(&exc)) {
+ if (_LIB_VERSION == _SVID_)
+ (void) WRITE2("tgamma: SING error\n", 18);
+ __set_errno (ERANGE);
+ }
+ break;
+
+ /* #### Last used is 50/150/250 ### */
+ }
+ return exc.retval;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/bits/huge_vall.h b/libc/sysdeps/ieee754/ldbl-128/bits/huge_vall.h
new file mode 100644
index 000000000..7042a211f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/bits/huge_vall.h
@@ -0,0 +1,51 @@
+/* `HUGE_VALL' constant for IEEE 754 machines (where it is infinity).
+ Used by <stdlib.h> and <math.h> functions for overflow.
+ Copyright (C) 1992, 1995, 1996, 1997, 1999, 2000, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/huge_vall.h> directly; include <math.h> instead."
+#endif
+
+/* IEEE positive infinity (-HUGE_VAL is negative infinity). */
+
+#if __GNUC_PREREQ(3,3)
+# define HUGE_VALL (__builtin_huge_vall())
+#elif __GNUC_PREREQ(2,96)
+# define HUGE_VALL (__extension__ 0x1.0p32767L)
+#else
+# include <endian.h>
+
+typedef union { unsigned char __c[16]; long double __ld; } __huge_vall_t;
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define __HUGE_VALL_bytes { 0x7f, 0xff, 0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+# endif
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define __HUGE_VALL_bytes { 0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0xff, 0x7f }
+# endif
+
+# ifdef __GNUC__
+# define HUGE_VALL (__extension__ \
+ ((__huge_vall_t) { __c : __HUGE_VALL_bytes }).__ld)
+# else
+static __huge_vall_t __huge_vall = { __HUGE_VALL_bytes };
+# define HUGE_VALL (__huge_vall.__ld)
+# endif
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_acoshl.c b/libc/sysdeps/ieee754/ldbl-128/e_acoshl.c
new file mode 100644
index 000000000..62170d4c2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_acoshl.c
@@ -0,0 +1,68 @@
+/* e_acoshl.c -- long double version of e_acosh.c.
+ * Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* __ieee754_acoshl(x)
+ * Method :
+ * Based on
+ * acoshl(x) = logl [ x + sqrtl(x*x-1) ]
+ * we have
+ * acoshl(x) := logl(x)+ln2, if x is large; else
+ * acoshl(x) := logl(2x-1/(sqrtl(x*x-1)+x)) if x>2; else
+ * acoshl(x) := log1pl(t+sqrtl(2.0*t+t*t)); where t=x-1.
+ *
+ * Special cases:
+ * acoshl(x) is NaN with signal if x<1.
+ * acoshl(NaN) is NaN without signal.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+one = 1.0,
+ln2 = 0.6931471805599453094172321214581766L;
+
+#ifdef __STDC__
+ long double __ieee754_acoshl(long double x)
+#else
+ long double __ieee754_acoshl(x)
+ long double x;
+#endif
+{
+ long double t;
+ u_int64_t lx;
+ int64_t hx;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ if(hx<0x3fff000000000000LL) { /* x < 1 */
+ return (x-x)/(x-x);
+ } else if(hx >=0x4035000000000000LL) { /* x > 2**54 */
+ if(hx >=0x7fff000000000000LL) { /* x is inf of NaN */
+ return x+x;
+ } else
+ return __ieee754_logl(x)+ln2; /* acoshl(huge)=logl(2x) */
+ } else if(((hx-0x3fff000000000000LL)|lx)==0) {
+ return 0.0L; /* acosh(1) = 0 */
+ } else if (hx > 0x4000000000000000LL) { /* 2**28 > x > 2 */
+ t=x*x;
+ return __ieee754_logl(2.0L*x-one/(x+__ieee754_sqrtl(t-one)));
+ } else { /* 1<x<2 */
+ t = x-one;
+ return __log1pl(t+__sqrtl(2.0L*t+t*t));
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_acosl.c b/libc/sysdeps/ieee754/ldbl-128/e_acosl.c
new file mode 100644
index 000000000..284e86a52
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_acosl.c
@@ -0,0 +1,328 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/*
+ Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __ieee754_acosl(x)
+ * Method :
+ * acos(x) = pi/2 - asin(x)
+ * acos(-x) = pi/2 + asin(x)
+ * For |x| <= 0.375
+ * acos(x) = pi/2 - asin(x)
+ * Between .375 and .5 the approximation is
+ * acos(0.4375 + x) = acos(0.4375) + x P(x) / Q(x)
+ * Between .5 and .625 the approximation is
+ * acos(0.5625 + x) = acos(0.5625) + x rS(x) / sS(x)
+ * For x > 0.625,
+ * acos(x) = 2 asin(sqrt((1-x)/2))
+ * computed with an extended precision square root in the leading term.
+ * For x < -0.625
+ * acos(x) = pi - 2 asin(sqrt((1-|x|)/2))
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ * Functions needed: __ieee754_sqrtl.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ one = 1.0L,
+ pio2_hi = 1.5707963267948966192313216916397514420986L,
+ pio2_lo = 4.3359050650618905123985220130216759843812E-35L,
+
+ /* acos(0.5625 + x) = acos(0.5625) + x rS(x) / sS(x)
+ -0.0625 <= x <= 0.0625
+ peak relative error 3.3e-35 */
+
+ rS0 = 5.619049346208901520945464704848780243887E0L,
+ rS1 = -4.460504162777731472539175700169871920352E1L,
+ rS2 = 1.317669505315409261479577040530751477488E2L,
+ rS3 = -1.626532582423661989632442410808596009227E2L,
+ rS4 = 3.144806644195158614904369445440583873264E1L,
+ rS5 = 9.806674443470740708765165604769099559553E1L,
+ rS6 = -5.708468492052010816555762842394927806920E1L,
+ rS7 = -1.396540499232262112248553357962639431922E1L,
+ rS8 = 1.126243289311910363001762058295832610344E1L,
+ rS9 = 4.956179821329901954211277873774472383512E-1L,
+ rS10 = -3.313227657082367169241333738391762525780E-1L,
+
+ sS0 = -4.645814742084009935700221277307007679325E0L,
+ sS1 = 3.879074822457694323970438316317961918430E1L,
+ sS2 = -1.221986588013474694623973554726201001066E2L,
+ sS3 = 1.658821150347718105012079876756201905822E2L,
+ sS4 = -4.804379630977558197953176474426239748977E1L,
+ sS5 = -1.004296417397316948114344573811562952793E2L,
+ sS6 = 7.530281592861320234941101403870010111138E1L,
+ sS7 = 1.270735595411673647119592092304357226607E1L,
+ sS8 = -1.815144839646376500705105967064792930282E1L,
+ sS9 = -7.821597334910963922204235247786840828217E-2L,
+ /* 1.000000000000000000000000000000000000000E0 */
+
+ acosr5625 = 9.7338991014954640492751132535550279812151E-1L,
+ pimacosr5625 = 2.1682027434402468335351320579240000860757E0L,
+
+ /* acos(0.4375 + x) = acos(0.4375) + x rS(x) / sS(x)
+ -0.0625 <= x <= 0.0625
+ peak relative error 2.1e-35 */
+
+ P0 = 2.177690192235413635229046633751390484892E0L,
+ P1 = -2.848698225706605746657192566166142909573E1L,
+ P2 = 1.040076477655245590871244795403659880304E2L,
+ P3 = -1.400087608918906358323551402881238180553E2L,
+ P4 = 2.221047917671449176051896400503615543757E1L,
+ P5 = 9.643714856395587663736110523917499638702E1L,
+ P6 = -5.158406639829833829027457284942389079196E1L,
+ P7 = -1.578651828337585944715290382181219741813E1L,
+ P8 = 1.093632715903802870546857764647931045906E1L,
+ P9 = 5.448925479898460003048760932274085300103E-1L,
+ P10 = -3.315886001095605268470690485170092986337E-1L,
+ Q0 = -1.958219113487162405143608843774587557016E0L,
+ Q1 = 2.614577866876185080678907676023269360520E1L,
+ Q2 = -9.990858606464150981009763389881793660938E1L,
+ Q3 = 1.443958741356995763628660823395334281596E2L,
+ Q4 = -3.206441012484232867657763518369723873129E1L,
+ Q5 = -1.048560885341833443564920145642588991492E2L,
+ Q6 = 6.745883931909770880159915641984874746358E1L,
+ Q7 = 1.806809656342804436118449982647641392951E1L,
+ Q8 = -1.770150690652438294290020775359580915464E1L,
+ Q9 = -5.659156469628629327045433069052560211164E-1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+
+ acosr4375 = 1.1179797320499710475919903296900511518755E0L,
+ pimacosr4375 = 2.0236129215398221908706530535894517323217E0L,
+
+ /* asin(x) = x + x^3 pS(x^2) / qS(x^2)
+ 0 <= x <= 0.5
+ peak relative error 1.9e-35 */
+ pS0 = -8.358099012470680544198472400254596543711E2L,
+ pS1 = 3.674973957689619490312782828051860366493E3L,
+ pS2 = -6.730729094812979665807581609853656623219E3L,
+ pS3 = 6.643843795209060298375552684423454077633E3L,
+ pS4 = -3.817341990928606692235481812252049415993E3L,
+ pS5 = 1.284635388402653715636722822195716476156E3L,
+ pS6 = -2.410736125231549204856567737329112037867E2L,
+ pS7 = 2.219191969382402856557594215833622156220E1L,
+ pS8 = -7.249056260830627156600112195061001036533E-1L,
+ pS9 = 1.055923570937755300061509030361395604448E-3L,
+
+ qS0 = -5.014859407482408326519083440151745519205E3L,
+ qS1 = 2.430653047950480068881028451580393430537E4L,
+ qS2 = -4.997904737193653607449250593976069726962E4L,
+ qS3 = 5.675712336110456923807959930107347511086E4L,
+ qS4 = -3.881523118339661268482937768522572588022E4L,
+ qS5 = 1.634202194895541569749717032234510811216E4L,
+ qS6 = -4.151452662440709301601820849901296953752E3L,
+ qS7 = 5.956050864057192019085175976175695342168E2L,
+ qS8 = -4.175375777334867025769346564600396877176E1L;
+ /* 1.000000000000000000000000000000000000000E0 */
+
+#ifdef __STDC__
+long double
+__ieee754_acosl (long double x)
+#else
+long double
+__ieee754_acosl (x)
+ long double x;
+#endif
+{
+ long double z, r, w, p, q, s, t, f2;
+ int32_t ix, sign;
+ ieee854_long_double_shape_type u;
+
+ u.value = x;
+ sign = u.parts32.w0;
+ ix = sign & 0x7fffffff;
+ u.parts32.w0 = ix; /* |x| */
+ if (ix >= 0x3fff0000) /* |x| >= 1 */
+ {
+ if (ix == 0x3fff0000
+ && (u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0)
+ { /* |x| == 1 */
+ if ((sign & 0x80000000) == 0)
+ return 0.0; /* acos(1) = 0 */
+ else
+ return (2.0 * pio2_hi) + (2.0 * pio2_lo); /* acos(-1)= pi */
+ }
+ return (x - x) / (x - x); /* acos(|x| > 1) is NaN */
+ }
+ else if (ix < 0x3ffe0000) /* |x| < 0.5 */
+ {
+ if (ix < 0x3fc60000) /* |x| < 2**-57 */
+ return pio2_hi + pio2_lo;
+ if (ix < 0x3ffde000) /* |x| < .4375 */
+ {
+ /* Arcsine of x. */
+ z = x * x;
+ p = (((((((((pS9 * z
+ + pS8) * z
+ + pS7) * z
+ + pS6) * z
+ + pS5) * z
+ + pS4) * z
+ + pS3) * z
+ + pS2) * z
+ + pS1) * z
+ + pS0) * z;
+ q = (((((((( z
+ + qS8) * z
+ + qS7) * z
+ + qS6) * z
+ + qS5) * z
+ + qS4) * z
+ + qS3) * z
+ + qS2) * z
+ + qS1) * z
+ + qS0;
+ r = x + x * p / q;
+ z = pio2_hi - (r - pio2_lo);
+ return z;
+ }
+ /* .4375 <= |x| < .5 */
+ t = u.value - 0.4375L;
+ p = ((((((((((P10 * t
+ + P9) * t
+ + P8) * t
+ + P7) * t
+ + P6) * t
+ + P5) * t
+ + P4) * t
+ + P3) * t
+ + P2) * t
+ + P1) * t
+ + P0) * t;
+
+ q = (((((((((t
+ + Q9) * t
+ + Q8) * t
+ + Q7) * t
+ + Q6) * t
+ + Q5) * t
+ + Q4) * t
+ + Q3) * t
+ + Q2) * t
+ + Q1) * t
+ + Q0;
+ r = p / q;
+ if (sign & 0x80000000)
+ r = pimacosr4375 - r;
+ else
+ r = acosr4375 + r;
+ return r;
+ }
+ else if (ix < 0x3ffe4000) /* |x| < 0.625 */
+ {
+ t = u.value - 0.5625L;
+ p = ((((((((((rS10 * t
+ + rS9) * t
+ + rS8) * t
+ + rS7) * t
+ + rS6) * t
+ + rS5) * t
+ + rS4) * t
+ + rS3) * t
+ + rS2) * t
+ + rS1) * t
+ + rS0) * t;
+
+ q = (((((((((t
+ + sS9) * t
+ + sS8) * t
+ + sS7) * t
+ + sS6) * t
+ + sS5) * t
+ + sS4) * t
+ + sS3) * t
+ + sS2) * t
+ + sS1) * t
+ + sS0;
+ if (sign & 0x80000000)
+ r = pimacosr5625 - p / q;
+ else
+ r = acosr5625 + p / q;
+ return r;
+ }
+ else
+ { /* |x| >= .625 */
+ z = (one - u.value) * 0.5;
+ s = __ieee754_sqrtl (z);
+ /* Compute an extended precision square root from
+ the Newton iteration s -> 0.5 * (s + z / s).
+ The change w from s to the improved value is
+ w = 0.5 * (s + z / s) - s = (s^2 + z)/2s - s = (z - s^2)/2s.
+ Express s = f1 + f2 where f1 * f1 is exactly representable.
+ w = (z - s^2)/2s = (z - f1^2 - 2 f1 f2 - f2^2)/2s .
+ s + w has extended precision. */
+ u.value = s;
+ u.parts32.w2 = 0;
+ u.parts32.w3 = 0;
+ f2 = s - u.value;
+ w = z - u.value * u.value;
+ w = w - 2.0 * u.value * f2;
+ w = w - f2 * f2;
+ w = w / (2.0 * s);
+ /* Arcsine of s. */
+ p = (((((((((pS9 * z
+ + pS8) * z
+ + pS7) * z
+ + pS6) * z
+ + pS5) * z
+ + pS4) * z
+ + pS3) * z
+ + pS2) * z
+ + pS1) * z
+ + pS0) * z;
+ q = (((((((( z
+ + qS8) * z
+ + qS7) * z
+ + qS6) * z
+ + qS5) * z
+ + qS4) * z
+ + qS3) * z
+ + qS2) * z
+ + qS1) * z
+ + qS0;
+ r = s + (w + s * p / q);
+
+ if (sign & 0x80000000)
+ w = pio2_hi + (pio2_lo - r);
+ else
+ w = r;
+ return 2.0 * w;
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_asinl.c b/libc/sysdeps/ieee754/ldbl-128/e_asinl.c
new file mode 100644
index 000000000..89f5d7958
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_asinl.c
@@ -0,0 +1,265 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/*
+ Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under the
+ following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __ieee754_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
+ * asin(x) = x + x*x^2*R(x^2)
+ * Between .5 and .625 the approximation is
+ * asin(0.5625 + x) = asin(0.5625) + x rS(x) / sS(x)
+ * For x in [0.625,1]
+ * asin(x) = pi/2-2*asin(sqrt((1-x)/2))
+ * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
+ * then for x>0.98
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
+ * For x<=0.98, let pio4_hi = pio2_hi/2, then
+ * f = hi part of s;
+ * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
+ * and
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
+ * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ */
+
+
+#include "math.h"
+#include "math_private.h"
+long double sqrtl (long double);
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ one = 1.0L,
+ huge = 1.0e+4932L,
+ pio2_hi = 1.5707963267948966192313216916397514420986L,
+ pio2_lo = 4.3359050650618905123985220130216759843812E-35L,
+ pio4_hi = 7.8539816339744830961566084581987569936977E-1L,
+
+ /* coefficient for R(x^2) */
+
+ /* asin(x) = x + x^3 pS(x^2) / qS(x^2)
+ 0 <= x <= 0.5
+ peak relative error 1.9e-35 */
+ pS0 = -8.358099012470680544198472400254596543711E2L,
+ pS1 = 3.674973957689619490312782828051860366493E3L,
+ pS2 = -6.730729094812979665807581609853656623219E3L,
+ pS3 = 6.643843795209060298375552684423454077633E3L,
+ pS4 = -3.817341990928606692235481812252049415993E3L,
+ pS5 = 1.284635388402653715636722822195716476156E3L,
+ pS6 = -2.410736125231549204856567737329112037867E2L,
+ pS7 = 2.219191969382402856557594215833622156220E1L,
+ pS8 = -7.249056260830627156600112195061001036533E-1L,
+ pS9 = 1.055923570937755300061509030361395604448E-3L,
+
+ qS0 = -5.014859407482408326519083440151745519205E3L,
+ qS1 = 2.430653047950480068881028451580393430537E4L,
+ qS2 = -4.997904737193653607449250593976069726962E4L,
+ qS3 = 5.675712336110456923807959930107347511086E4L,
+ qS4 = -3.881523118339661268482937768522572588022E4L,
+ qS5 = 1.634202194895541569749717032234510811216E4L,
+ qS6 = -4.151452662440709301601820849901296953752E3L,
+ qS7 = 5.956050864057192019085175976175695342168E2L,
+ qS8 = -4.175375777334867025769346564600396877176E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+
+ /* asin(0.5625 + x) = asin(0.5625) + x rS(x) / sS(x)
+ -0.0625 <= x <= 0.0625
+ peak relative error 3.3e-35 */
+ rS0 = -5.619049346208901520945464704848780243887E0L,
+ rS1 = 4.460504162777731472539175700169871920352E1L,
+ rS2 = -1.317669505315409261479577040530751477488E2L,
+ rS3 = 1.626532582423661989632442410808596009227E2L,
+ rS4 = -3.144806644195158614904369445440583873264E1L,
+ rS5 = -9.806674443470740708765165604769099559553E1L,
+ rS6 = 5.708468492052010816555762842394927806920E1L,
+ rS7 = 1.396540499232262112248553357962639431922E1L,
+ rS8 = -1.126243289311910363001762058295832610344E1L,
+ rS9 = -4.956179821329901954211277873774472383512E-1L,
+ rS10 = 3.313227657082367169241333738391762525780E-1L,
+
+ sS0 = -4.645814742084009935700221277307007679325E0L,
+ sS1 = 3.879074822457694323970438316317961918430E1L,
+ sS2 = -1.221986588013474694623973554726201001066E2L,
+ sS3 = 1.658821150347718105012079876756201905822E2L,
+ sS4 = -4.804379630977558197953176474426239748977E1L,
+ sS5 = -1.004296417397316948114344573811562952793E2L,
+ sS6 = 7.530281592861320234941101403870010111138E1L,
+ sS7 = 1.270735595411673647119592092304357226607E1L,
+ sS8 = -1.815144839646376500705105967064792930282E1L,
+ sS9 = -7.821597334910963922204235247786840828217E-2L,
+ /* 1.000000000000000000000000000000000000000E0 */
+
+ asinr5625 = 5.9740641664535021430381036628424864397707E-1L;
+
+
+
+#ifdef __STDC__
+long double
+__ieee754_asinl (long double x)
+#else
+double
+__ieee754_asinl (x)
+ long double x;
+#endif
+{
+ long double t, w, p, q, c, r, s;
+ int32_t ix, sign, flag;
+ ieee854_long_double_shape_type u;
+
+ flag = 0;
+ u.value = x;
+ sign = u.parts32.w0;
+ ix = sign & 0x7fffffff;
+ u.parts32.w0 = ix; /* |x| */
+ if (ix >= 0x3fff0000) /* |x|>= 1 */
+ {
+ if (ix == 0x3fff0000
+ && (u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0)
+ /* asin(1)=+-pi/2 with inexact */
+ return x * pio2_hi + x * pio2_lo;
+ return (x - x) / (x - x); /* asin(|x|>1) is NaN */
+ }
+ else if (ix < 0x3ffe0000) /* |x| < 0.5 */
+ {
+ if (ix < 0x3fc60000) /* |x| < 2**-57 */
+ {
+ if (huge + x > one)
+ return x; /* return x with inexact if x!=0 */
+ }
+ else
+ {
+ t = x * x;
+ /* Mark to use pS, qS later on. */
+ flag = 1;
+ }
+ }
+ else if (ix < 0x3ffe4000) /* 0.625 */
+ {
+ t = u.value - 0.5625;
+ p = ((((((((((rS10 * t
+ + rS9) * t
+ + rS8) * t
+ + rS7) * t
+ + rS6) * t
+ + rS5) * t
+ + rS4) * t
+ + rS3) * t
+ + rS2) * t
+ + rS1) * t
+ + rS0) * t;
+
+ q = ((((((((( t
+ + sS9) * t
+ + sS8) * t
+ + sS7) * t
+ + sS6) * t
+ + sS5) * t
+ + sS4) * t
+ + sS3) * t
+ + sS2) * t
+ + sS1) * t
+ + sS0;
+ t = asinr5625 + p / q;
+ if ((sign & 0x80000000) == 0)
+ return t;
+ else
+ return -t;
+ }
+ else
+ {
+ /* 1 > |x| >= 0.625 */
+ w = one - u.value;
+ t = w * 0.5;
+ }
+
+ p = (((((((((pS9 * t
+ + pS8) * t
+ + pS7) * t
+ + pS6) * t
+ + pS5) * t
+ + pS4) * t
+ + pS3) * t
+ + pS2) * t
+ + pS1) * t
+ + pS0) * t;
+
+ q = (((((((( t
+ + qS8) * t
+ + qS7) * t
+ + qS6) * t
+ + qS5) * t
+ + qS4) * t
+ + qS3) * t
+ + qS2) * t
+ + qS1) * t
+ + qS0;
+
+ if (flag) /* 2^-57 < |x| < 0.5 */
+ {
+ w = p / q;
+ return x + x * w;
+ }
+
+ s = __ieee754_sqrtl (t);
+ if (ix >= 0x3ffef333) /* |x| > 0.975 */
+ {
+ w = p / q;
+ t = pio2_hi - (2.0 * (s + s * w) - pio2_lo);
+ }
+ else
+ {
+ u.value = s;
+ u.parts32.w3 = 0;
+ u.parts32.w2 = 0;
+ w = u.value;
+ c = (t - w * w) / (s + w);
+ r = p / q;
+ p = 2.0 * s * r - (pio2_lo - 2.0 * c);
+ q = pio4_hi - 2.0 * w;
+ t = pio4_hi - (p - q);
+ }
+
+ if ((sign & 0x80000000) == 0)
+ return t;
+ else
+ return -t;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_atan2l.c b/libc/sysdeps/ieee754/ldbl-128/e_atan2l.c
new file mode 100644
index 000000000..2bbb3b8f4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_atan2l.c
@@ -0,0 +1,129 @@
+/* e_atan2l.c -- long double version of e_atan2.c.
+ * Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* __ieee754_atan2l(y,x)
+ * Method :
+ * 1. Reduce y to positive by atan2l(y,x)=-atan2l(-y,x).
+ * 2. Reduce x to positive by (if x and y are unexceptional):
+ * ARG (x+iy) = arctan(y/x) ... if x > 0,
+ * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
+ *
+ * Special cases:
+ *
+ * ATAN2((anything), NaN ) is NaN;
+ * ATAN2(NAN , (anything) ) is NaN;
+ * ATAN2(+-0, +(anything but NaN)) is +-0 ;
+ * ATAN2(+-0, -(anything but NaN)) is +-pi ;
+ * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
+ * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
+ * ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
+ * ATAN2(+-INF,+INF ) is +-pi/4 ;
+ * ATAN2(+-INF,-INF ) is +-3pi/4;
+ * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+tiny = 1.0e-4900L,
+zero = 0.0,
+pi_o_4 = 7.85398163397448309615660845819875699e-01L, /* 3ffe921fb54442d18469898cc51701b8 */
+pi_o_2 = 1.57079632679489661923132169163975140e+00L, /* 3fff921fb54442d18469898cc51701b8 */
+pi = 3.14159265358979323846264338327950280e+00L, /* 4000921fb54442d18469898cc51701b8 */
+pi_lo = 8.67181013012378102479704402604335225e-35L; /* 3f8dcd129024e088a67cc74020bbea64 */
+
+#ifdef __STDC__
+ long double __ieee754_atan2l(long double y, long double x)
+#else
+ long double __ieee754_atan2l(y,x)
+ long double y,x;
+#endif
+{
+ long double z;
+ int64_t k,m,hx,hy,ix,iy;
+ u_int64_t lx,ly;
+
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ ix = hx&0x7fffffffffffffffLL;
+ GET_LDOUBLE_WORDS64(hy,ly,y);
+ iy = hy&0x7fffffffffffffffLL;
+ if(((ix|((lx|-lx)>>63))>0x7fff000000000000LL)||
+ ((iy|((ly|-ly)>>63))>0x7fff000000000000LL)) /* x or y is NaN */
+ return x+y;
+ if(((hx-0x3fff000000000000LL)|lx)==0) return __atanl(y); /* x=1.0L */
+ m = ((hy>>63)&1)|((hx>>62)&2); /* 2*sign(x)+sign(y) */
+
+ /* when y = 0 */
+ if((iy|ly)==0) {
+ switch(m) {
+ case 0:
+ case 1: return y; /* atan(+-0,+anything)=+-0 */
+ case 2: return pi+tiny;/* atan(+0,-anything) = pi */
+ case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
+ }
+ }
+ /* when x = 0 */
+ if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* when x is INF */
+ if(ix==0x7fff000000000000LL) {
+ if(iy==0x7fff000000000000LL) {
+ switch(m) {
+ case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
+ case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
+ case 2: return 3.0L*pi_o_4+tiny;/*atan(+INF,-INF)*/
+ case 3: return -3.0L*pi_o_4-tiny;/*atan(-INF,-INF)*/
+ }
+ } else {
+ switch(m) {
+ case 0: return zero ; /* atan(+...,+INF) */
+ case 1: return -zero ; /* atan(-...,+INF) */
+ case 2: return pi+tiny ; /* atan(+...,-INF) */
+ case 3: return -pi-tiny ; /* atan(-...,-INF) */
+ }
+ }
+ }
+ /* when y is INF */
+ if(iy==0x7fff000000000000LL) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* compute y/x */
+ k = (iy-ix)>>48;
+ if(k > 120) z=pi_o_2+0.5L*pi_lo; /* |y/x| > 2**120 */
+ else if(hx<0&&k<-120) z=0.0L; /* |y|/x < -2**120 */
+ else z=__atanl(fabsl(y/x)); /* safe to do y/x */
+ switch (m) {
+ case 0: return z ; /* atan(+,+) */
+ case 1: {
+ u_int64_t zh;
+ GET_LDOUBLE_MSW64(zh,z);
+ SET_LDOUBLE_MSW64(z,zh ^ 0x8000000000000000ULL);
+ }
+ return z ; /* atan(-,+) */
+ case 2: return pi-(z-pi_lo);/* atan(+,-) */
+ default: /* case 3 */
+ return (z-pi_lo)-pi;/* atan(-,-) */
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_atanhl.c b/libc/sysdeps/ieee754/ldbl-128/e_atanhl.c
new file mode 100644
index 000000000..dd681c847
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_atanhl.c
@@ -0,0 +1,84 @@
+/* s_atanhl.c -- long double version of s_atan.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* __ieee754_atanhl(x)
+ * Method :
+ * 1.Reduced x to positive by atanh(-x) = -atanh(x)
+ * 2.For x>=0.5
+ * 1 2x x
+ * atanhl(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
+ * 2 1 - x 1 - x
+ *
+ * For x<0.5
+ * atanhl(x) = 0.5*log1pl(2x+2x*x/(1-x))
+ *
+ * Special cases:
+ * atanhl(x) is NaN if |x| > 1 with signal;
+ * atanhl(NaN) is that NaN with no signal;
+ * atanhl(+-1) is +-INF with signal.
+ *
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0L, huge = 1e4900L;
+#else
+static long double one = 1.0L, huge = 1e4900L;
+#endif
+
+#ifdef __STDC__
+static const long double zero = 0.0L;
+#else
+static double long zero = 0.0L;
+#endif
+
+#ifdef __STDC__
+ long double __ieee754_atanhl(long double x)
+#else
+ long double __ieee754_atanhl(x)
+ long double x;
+#endif
+{
+ long double t;
+ u_int32_t jx, ix;
+ ieee854_long_double_shape_type u;
+
+ u.value = x;
+ jx = u.parts32.w0;
+ ix = jx & 0x7fffffff;
+ u.parts32.w0 = ix;
+ if (ix >= 0x3fff0000) /* |x| >= 1.0 or infinity or NaN */
+ {
+ if (u.value == one)
+ return x/zero;
+ else
+ return (x-x)/(x-x);
+ }
+ if(ix<0x3fc60000 && (huge+x)>zero) return x; /* x < 2^-57 */
+
+ if(ix<0x3ffe0000) { /* x < 0.5 */
+ t = u.value+u.value;
+ t = 0.5*__log1pl(t+t*u.value/(one-u.value));
+ } else
+ t = 0.5*__log1pl((u.value+u.value)/(one-u.value));
+ if(jx & 0x80000000) return -t; else return t;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_coshl.c b/libc/sysdeps/ieee754/ldbl-128/e_coshl.c
new file mode 100644
index 000000000..3913e3479
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_coshl.c
@@ -0,0 +1,120 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* Changes for 128-bit long double are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __ieee754_coshl(x)
+ * Method :
+ * mathematically coshl(x) if defined to be (exp(x)+exp(-x))/2
+ * 1. Replace x by |x| (coshl(x) = coshl(-x)).
+ * 2.
+ * [ exp(x) - 1 ]^2
+ * 0 <= x <= ln2/2 : coshl(x) := 1 + -------------------
+ * 2*exp(x)
+ *
+ * exp(x) + 1/exp(x)
+ * ln2/2 <= x <= 22 : coshl(x) := -------------------
+ * 2
+ * 22 <= x <= lnovft : coshl(x) := expl(x)/2
+ * lnovft <= x <= ln2ovft: coshl(x) := expl(x/2)/2 * expl(x/2)
+ * ln2ovft < x : coshl(x) := huge*huge (overflow)
+ *
+ * Special cases:
+ * coshl(x) is |x| if x is +INF, -INF, or NaN.
+ * only coshl(0)=1 is exact for finite x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0, half = 0.5, huge = 1.0e4900L,
+ovf_thresh = 1.1357216553474703894801348310092223067821E4L;
+#else
+static long double one = 1.0, half = 0.5, huge = 1.0e4900L,
+ovf_thresh = 1.1357216553474703894801348310092223067821E4L;
+#endif
+
+#ifdef __STDC__
+long double
+__ieee754_coshl (long double x)
+#else
+long double
+__ieee754_coshl (x)
+ long double x;
+#endif
+{
+ long double t, w;
+ int32_t ex;
+ ieee854_long_double_shape_type u;
+
+ u.value = x;
+ ex = u.parts32.w0 & 0x7fffffff;
+
+ /* Absolute value of x. */
+ u.parts32.w0 = ex;
+
+ /* x is INF or NaN */
+ if (ex >= 0x7fff0000)
+ return x * x;
+
+ /* |x| in [0,0.5*ln2], return 1+expm1l(|x|)^2/(2*expl(|x|)) */
+ if (ex < 0x3ffd62e4) /* 0.3465728759765625 */
+ {
+ t = __expm1l (u.value);
+ w = one + t;
+ if (ex < 0x3fb80000) /* |x| < 2^-116 */
+ return w; /* cosh(tiny) = 1 */
+
+ return one + (t * t) / (w + w);
+ }
+
+ /* |x| in [0.5*ln2,40], return (exp(|x|)+1/exp(|x|)/2; */
+ if (ex < 0x40044000)
+ {
+ t = __ieee754_expl (u.value);
+ return half * t + half / t;
+ }
+
+ /* |x| in [22, ln(maxdouble)] return half*exp(|x|) */
+ if (ex <= 0x400c62e3) /* 11356.375 */
+ return half * __ieee754_expl (u.value);
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ if (u.value <= ovf_thresh)
+ {
+ w = __ieee754_expl (half * u.value);
+ t = half * w;
+ return t * w;
+ }
+
+ /* |x| > overflowthresold, cosh(x) overflow */
+ return huge * huge;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_expl.c b/libc/sysdeps/ieee754/ldbl-128/e_expl.c
new file mode 100644
index 000000000..31ff16f8c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_expl.c
@@ -0,0 +1,249 @@
+/* Quad-precision floating point e^x.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+ Partly based on double-precision code
+ by Geoffrey Keating <geoffk@ozemail.com.au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The basic design here is from
+ Abraham Ziv, "Fast Evaluation of Elementary Mathematical Functions with
+ Correctly Rounded Last Bit", ACM Trans. Math. Soft., 17 (3), September 1991,
+ pp. 410-423.
+
+ We work with number pairs where the first number is the high part and
+ the second one is the low part. Arithmetic with the high part numbers must
+ be exact, without any roundoff errors.
+
+ The input value, X, is written as
+ X = n * ln(2)_0 + arg1[t1]_0 + arg2[t2]_0 + x
+ - n * ln(2)_1 + arg1[t1]_1 + arg2[t2]_1 + xl
+
+ where:
+ - n is an integer, 16384 >= n >= -16495;
+ - ln(2)_0 is the first 93 bits of ln(2), and |ln(2)_0-ln(2)-ln(2)_1| < 2^-205
+ - t1 is an integer, 89 >= t1 >= -89
+ - t2 is an integer, 65 >= t2 >= -65
+ - |arg1[t1]-t1/256.0| < 2^-53
+ - |arg2[t2]-t2/32768.0| < 2^-53
+ - x + xl is whatever is left, |x + xl| < 2^-16 + 2^-53
+
+ Then e^x is approximated as
+
+ e^x = 2^n_1 ( 2^n_0 e^(arg1[t1]_0 + arg1[t1]_1) e^(arg2[t2]_0 + arg2[t2]_1)
+ + 2^n_0 e^(arg1[t1]_0 + arg1[t1]_1) e^(arg2[t2]_0 + arg2[t2]_1)
+ * p (x + xl + n * ln(2)_1))
+ where:
+ - p(x) is a polynomial approximating e(x)-1
+ - e^(arg1[t1]_0 + arg1[t1]_1) is obtained from a table
+ - e^(arg2[t2]_0 + arg2[t2]_1) likewise
+ - n_1 + n_0 = n, so that |n_0| < -LDBL_MIN_EXP-1.
+
+ If it happens that n_1 == 0 (this is the usual case), that multiplication
+ is omitted.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <float.h>
+#include <ieee754.h>
+#include <math.h>
+#include <fenv.h>
+#include <inttypes.h>
+#include <math_private.h>
+#include <stdlib.h>
+#include "t_expl.h"
+
+static const long double C[] = {
+/* Smallest integer x for which e^x overflows. */
+#define himark C[0]
+ 11356.523406294143949491931077970765L,
+
+/* Largest integer x for which e^x underflows. */
+#define lomark C[1]
+-11433.4627433362978788372438434526231L,
+
+/* 3x2^96 */
+#define THREEp96 C[2]
+ 59421121885698253195157962752.0L,
+
+/* 3x2^103 */
+#define THREEp103 C[3]
+ 30423614405477505635920876929024.0L,
+
+/* 3x2^111 */
+#define THREEp111 C[4]
+ 7788445287802241442795744493830144.0L,
+
+/* 1/ln(2) */
+#define M_1_LN2 C[5]
+ 1.44269504088896340735992468100189204L,
+
+/* first 93 bits of ln(2) */
+#define M_LN2_0 C[6]
+ 0.693147180559945309417232121457981864L,
+
+/* ln2_0 - ln(2) */
+#define M_LN2_1 C[7]
+-1.94704509238074995158795957333327386E-31L,
+
+/* very small number */
+#define TINY C[8]
+ 1.0e-4900L,
+
+/* 2^16383 */
+#define TWO16383 C[9]
+ 5.94865747678615882542879663314003565E+4931L,
+
+/* 256 */
+#define TWO8 C[10]
+ 256.0L,
+
+/* 32768 */
+#define TWO15 C[11]
+ 32768.0L,
+
+/* Chebyshev polynom coeficients for (exp(x)-1)/x */
+#define P1 C[12]
+#define P2 C[13]
+#define P3 C[14]
+#define P4 C[15]
+#define P5 C[16]
+#define P6 C[17]
+ 0.5L,
+ 1.66666666666666666666666666666666683E-01L,
+ 4.16666666666666666666654902320001674E-02L,
+ 8.33333333333333333333314659767198461E-03L,
+ 1.38888888889899438565058018857254025E-03L,
+ 1.98412698413981650382436541785404286E-04L,
+};
+
+long double
+__ieee754_expl (long double x)
+{
+ /* Check for usual case. */
+ if (isless (x, himark) && isgreater (x, lomark))
+ {
+ int tval1, tval2, unsafe, n_i;
+ long double x22, n, t, result, xl;
+ union ieee854_long_double ex2_u, scale_u;
+ fenv_t oldenv;
+
+ feholdexcept (&oldenv);
+#ifdef FE_TONEAREST
+ fesetround (FE_TONEAREST);
+#endif
+
+ /* Calculate n. */
+ n = x * M_1_LN2 + THREEp111;
+ n -= THREEp111;
+ x = x - n * M_LN2_0;
+ xl = n * M_LN2_1;
+
+ /* Calculate t/256. */
+ t = x + THREEp103;
+ t -= THREEp103;
+
+ /* Compute tval1 = t. */
+ tval1 = (int) (t * TWO8);
+
+ x -= __expl_table[T_EXPL_ARG1+2*tval1];
+ xl -= __expl_table[T_EXPL_ARG1+2*tval1+1];
+
+ /* Calculate t/32768. */
+ t = x + THREEp96;
+ t -= THREEp96;
+
+ /* Compute tval2 = t. */
+ tval2 = (int) (t * TWO15);
+
+ x -= __expl_table[T_EXPL_ARG2+2*tval2];
+ xl -= __expl_table[T_EXPL_ARG2+2*tval2+1];
+
+ x = x + xl;
+
+ /* Compute ex2 = 2^n_0 e^(argtable[tval1]) e^(argtable[tval2]). */
+ ex2_u.d = __expl_table[T_EXPL_RES1 + tval1]
+ * __expl_table[T_EXPL_RES2 + tval2];
+ n_i = (int)n;
+ /* 'unsafe' is 1 iff n_1 != 0. */
+ unsafe = abs(n_i) >= -LDBL_MIN_EXP - 1;
+ ex2_u.ieee.exponent += n_i >> unsafe;
+
+ /* Compute scale = 2^n_1. */
+ scale_u.d = 1.0L;
+ scale_u.ieee.exponent += n_i - (n_i >> unsafe);
+
+ /* Approximate e^x2 - 1, using a seventh-degree polynomial,
+ with maximum error in [-2^-16-2^-53,2^-16+2^-53]
+ less than 4.8e-39. */
+ x22 = x + x*x*(P1+x*(P2+x*(P3+x*(P4+x*(P5+x*P6)))));
+
+ /* Return result. */
+ fesetenv (&oldenv);
+
+ result = x22 * ex2_u.d + ex2_u.d;
+
+ /* Now we can test whether the result is ultimate or if we are unsure.
+ In the later case we should probably call a mpn based routine to give
+ the ultimate result.
+ Empirically, this routine is already ultimate in about 99.9986% of
+ cases, the test below for the round to nearest case will be false
+ in ~ 99.9963% of cases.
+ Without proc2 routine maximum error which has been seen is
+ 0.5000262 ulp.
+
+ union ieee854_long_double ex3_u;
+
+ #ifdef FE_TONEAREST
+ fesetround (FE_TONEAREST);
+ #endif
+ ex3_u.d = (result - ex2_u.d) - x22 * ex2_u.d;
+ ex2_u.d = result;
+ ex3_u.ieee.exponent += LDBL_MANT_DIG + 15 + IEEE854_LONG_DOUBLE_BIAS
+ - ex2_u.ieee.exponent;
+ n_i = abs (ex3_u.d);
+ n_i = (n_i + 1) / 2;
+ fesetenv (&oldenv);
+ #ifdef FE_TONEAREST
+ if (fegetround () == FE_TONEAREST)
+ n_i -= 0x4000;
+ #endif
+ if (!n_i) {
+ return __ieee754_expl_proc2 (origx);
+ }
+ */
+ if (!unsafe)
+ return result;
+ else
+ return result * scale_u.d;
+ }
+ /* Exceptional cases: */
+ else if (isless (x, himark))
+ {
+ if (__isinfl (x))
+ /* e^-inf == 0, with no error. */
+ return 0;
+ else
+ /* Underflow */
+ return TINY * TINY;
+ }
+ else
+ /* Return x, if x is a NaN or Inf; or overflow, otherwise. */
+ return TWO16383*x;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_fmodl.c b/libc/sysdeps/ieee754/ldbl-128/e_fmodl.c
new file mode 100644
index 000000000..1043f69cb
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_fmodl.c
@@ -0,0 +1,138 @@
+/* e_fmodl.c -- long double version of e_fmod.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/*
+ * __ieee754_fmodl(x,y)
+ * Return x mod y in exact arithmetic
+ * Method: shift and subtract
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0, Zero[] = {0.0, -0.0,};
+#else
+static long double one = 1.0, Zero[] = {0.0, -0.0,};
+#endif
+
+#ifdef __STDC__
+ long double __ieee754_fmodl(long double x, long double y)
+#else
+ long double __ieee754_fmodl(x,y)
+ long double x,y;
+#endif
+{
+ int64_t n,hx,hy,hz,ix,iy,sx,i;
+ u_int64_t lx,ly,lz;
+
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ GET_LDOUBLE_WORDS64(hy,ly,y);
+ sx = hx&0x8000000000000000ULL; /* sign of x */
+ hx ^=sx; /* |x| */
+ hy &= 0x7fffffffffffffffLL; /* |y| */
+
+ /* purge off exception values */
+ if((hy|ly)==0||(hx>=0x7fff000000000000LL)|| /* y=0,or x not finite */
+ ((hy|((ly|-ly)>>63))>0x7fff000000000000LL)) /* or y is NaN */
+ return (x*y)/(x*y);
+ if(hx<=hy) {
+ if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
+ if(lx==ly)
+ return Zero[(u_int64_t)sx>>63]; /* |x|=|y| return x*0*/
+ }
+
+ /* determine ix = ilogb(x) */
+ if(hx<0x0001000000000000LL) { /* subnormal x */
+ if(hx==0) {
+ for (ix = -16431, i=lx; i>0; i<<=1) ix -=1;
+ } else {
+ for (ix = -16382, i=hx<<15; i>0; i<<=1) ix -=1;
+ }
+ } else ix = (hx>>48)-0x3fff;
+
+ /* determine iy = ilogb(y) */
+ if(hy<0x0001000000000000LL) { /* subnormal y */
+ if(hy==0) {
+ for (iy = -16431, i=ly; i>0; i<<=1) iy -=1;
+ } else {
+ for (iy = -16382, i=hy<<15; i>0; i<<=1) iy -=1;
+ }
+ } else iy = (hy>>48)-0x3fff;
+
+ /* set up {hx,lx}, {hy,ly} and align y to x */
+ if(ix >= -16382)
+ hx = 0x0001000000000000LL|(0x0000ffffffffffffLL&hx);
+ else { /* subnormal x, shift x to normal */
+ n = -16382-ix;
+ if(n<=63) {
+ hx = (hx<<n)|(lx>>(64-n));
+ lx <<= n;
+ } else {
+ hx = lx<<(n-64);
+ lx = 0;
+ }
+ }
+ if(iy >= -16382)
+ hy = 0x0001000000000000LL|(0x0000ffffffffffffLL&hy);
+ else { /* subnormal y, shift y to normal */
+ n = -16382-iy;
+ if(n<=63) {
+ hy = (hy<<n)|(ly>>(64-n));
+ ly <<= n;
+ } else {
+ hy = ly<<(n-64);
+ ly = 0;
+ }
+ }
+
+ /* fix point fmod */
+ n = ix - iy;
+ while(n--) {
+ hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ if(hz<0){hx = hx+hx+(lx>>63); lx = lx+lx;}
+ else {
+ if((hz|lz)==0) /* return sign(x)*0 */
+ return Zero[(u_int64_t)sx>>63];
+ hx = hz+hz+(lz>>63); lx = lz+lz;
+ }
+ }
+ hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ if(hz>=0) {hx=hz;lx=lz;}
+
+ /* convert back to floating value and restore the sign */
+ if((hx|lx)==0) /* return sign(x)*0 */
+ return Zero[(u_int64_t)sx>>63];
+ while(hx<0x0001000000000000LL) { /* normalize x */
+ hx = hx+hx+(lx>>63); lx = lx+lx;
+ iy -= 1;
+ }
+ if(iy>= -16382) { /* normalize output */
+ hx = ((hx-0x0001000000000000LL)|((iy+16383)<<48));
+ SET_LDOUBLE_WORDS64(x,hx|sx,lx);
+ } else { /* subnormal output */
+ n = -16382 - iy;
+ if(n<=48) {
+ lx = (lx>>n)|((u_int64_t)hx<<(64-n));
+ hx >>= n;
+ } else if (n<=63) {
+ lx = (hx<<(64-n))|(lx>>n); hx = sx;
+ } else {
+ lx = hx>>(n-64); hx = sx;
+ }
+ SET_LDOUBLE_WORDS64(x,hx|sx,lx);
+ x *= one; /* create necessary signal */
+ }
+ return x; /* exact output */
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_gammal_r.c b/libc/sysdeps/ieee754/ldbl-128/e_gammal_r.c
new file mode 100644
index 000000000..36f5d4588
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_gammal_r.c
@@ -0,0 +1,58 @@
+/* Implementation of gamma function according to ISO C.
+ Copyright (C) 1997, 1999, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_private.h>
+
+
+long double
+__ieee754_gammal_r (long double x, int *signgamp)
+{
+ /* We don't have a real gamma implementation now. We'll use lgamma
+ and the exp function. But due to the required boundary
+ conditions we must check some values separately. */
+ int64_t hx;
+ u_int64_t lx;
+
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+
+ if (((hx & 0x7fffffffffffffffLL) | lx) == 0)
+ {
+ /* Return value for x == 0 is Inf with divide by zero exception. */
+ *signgamp = 0;
+ return 1.0 / x;
+ }
+ if (hx < 0 && (u_int64_t) hx < 0xffff000000000000ULL && __rintl (x) == x)
+ {
+ /* Return value for integer x < 0 is NaN with invalid exception. */
+ *signgamp = 0;
+ return (x - x) / (x - x);
+ }
+ if (hx == 0xffff000000000000ULL && lx == 0)
+ {
+ /* x == -Inf. According to ISO this is NaN. */
+ *signgamp = 0;
+ return x - x;
+ }
+
+ /* XXX FIXME. */
+ return __ieee754_expl (__ieee754_lgammal_r (x, signgamp));
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_hypotl.c b/libc/sysdeps/ieee754/ldbl-128/e_hypotl.c
new file mode 100644
index 000000000..6834eac59
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_hypotl.c
@@ -0,0 +1,132 @@
+/* e_hypotl.c -- long double version of e_hypot.c.
+ * Conversion to long double by Jakub Jelinek, jakub@redhat.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: e_hypotl.c,v 1.9 1995/05/12 04:57:27 jtc Exp $";
+#endif
+
+/* __ieee754_hypotl(x,y)
+ *
+ * Method :
+ * If (assume round-to-nearest) z=x*x+y*y
+ * has error less than sqrtl(2)/2 ulp, than
+ * sqrtl(z) has error less than 1 ulp (exercise).
+ *
+ * So, compute sqrtl(x*x+y*y) with some care as
+ * follows to get the error below 1 ulp:
+ *
+ * Assume x>y>0;
+ * (if possible, set rounding to round-to-nearest)
+ * 1. if x > 2y use
+ * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
+ * where x1 = x with lower 64 bits cleared, x2 = x-x1; else
+ * 2. if x <= 2y use
+ * t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
+ * where t1 = 2x with lower 64 bits cleared, t2 = 2x-t1,
+ * y1= y with lower 64 bits chopped, y2 = y-y1.
+ *
+ * NOTE: scaling may be necessary if some argument is too
+ * large or too tiny
+ *
+ * Special cases:
+ * hypotl(x,y) is INF if x or y is +INF or -INF; else
+ * hypotl(x,y) is NAN if x or y is NAN.
+ *
+ * Accuracy:
+ * hypotl(x,y) returns sqrtl(x^2+y^2) with error less
+ * than 1 ulps (units in the last place)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __ieee754_hypotl(long double x, long double y)
+#else
+ long double __ieee754_hypotl(x,y)
+ long double x, y;
+#endif
+{
+ long double a,b,t1,t2,y1,y2,w;
+ int64_t j,k,ha,hb;
+
+ GET_LDOUBLE_MSW64(ha,x);
+ ha &= 0x7fffffffffffffffLL;
+ GET_LDOUBLE_MSW64(hb,y);
+ hb &= 0x7fffffffffffffffLL;
+ if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
+ SET_LDOUBLE_MSW64(a,ha); /* a <- |a| */
+ SET_LDOUBLE_MSW64(b,hb); /* b <- |b| */
+ if((ha-hb)>0x78000000000000LL) {return a+b;} /* x/y > 2**120 */
+ k=0;
+ if(ha > 0x5f3f000000000000LL) { /* a>2**8000 */
+ if(ha >= 0x7fff000000000000LL) { /* Inf or NaN */
+ u_int64_t low;
+ w = a+b; /* for sNaN */
+ GET_LDOUBLE_LSW64(low,a);
+ if(((ha&0xffffffffffffLL)|low)==0) w = a;
+ GET_LDOUBLE_LSW64(low,b);
+ if(((hb^0x7fff000000000000LL)|low)==0) w = b;
+ return w;
+ }
+ /* scale a and b by 2**-9600 */
+ ha -= 0x2580000000000000LL;
+ hb -= 0x2580000000000000LL; k += 9600;
+ SET_LDOUBLE_MSW64(a,ha);
+ SET_LDOUBLE_MSW64(b,hb);
+ }
+ if(hb < 0x20bf000000000000LL) { /* b < 2**-8000 */
+ if(hb <= 0x0000ffffffffffffLL) { /* subnormal b or 0 */
+ u_int64_t low;
+ GET_LDOUBLE_LSW64(low,b);
+ if((hb|low)==0) return a;
+ t1=0;
+ SET_LDOUBLE_MSW64(t1,0x7ffd000000000000LL); /* t1=2^16382 */
+ b *= t1;
+ a *= t1;
+ k -= 16382;
+ } else { /* scale a and b by 2^9600 */
+ ha += 0x2580000000000000LL; /* a *= 2^9600 */
+ hb += 0x2580000000000000LL; /* b *= 2^9600 */
+ k -= 9600;
+ SET_LDOUBLE_MSW64(a,ha);
+ SET_LDOUBLE_MSW64(b,hb);
+ }
+ }
+ /* medium size a and b */
+ w = a-b;
+ if (w>b) {
+ t1 = 0;
+ SET_LDOUBLE_MSW64(t1,ha);
+ t2 = a-t1;
+ w = __ieee754_sqrtl(t1*t1-(b*(-b)-t2*(a+t1)));
+ } else {
+ a = a+a;
+ y1 = 0;
+ SET_LDOUBLE_MSW64(y1,hb);
+ y2 = b - y1;
+ t1 = 0;
+ SET_LDOUBLE_MSW64(t1,ha+0x0001000000000000LL);
+ t2 = a - t1;
+ w = __ieee754_sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b)));
+ }
+ if(k!=0) {
+ u_int64_t high;
+ t1 = 1.0L;
+ GET_LDOUBLE_MSW64(high,t1);
+ SET_LDOUBLE_MSW64(t1,high+(k<<48));
+ return t1*w;
+ } else return w;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_j0l.c b/libc/sysdeps/ieee754/ldbl-128/e_j0l.c
new file mode 100644
index 000000000..67ef37115
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_j0l.c
@@ -0,0 +1,922 @@
+/* j0l.c
+ *
+ * Bessel function of order zero
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, j0l();
+ *
+ * y = j0l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns Bessel function of first kind, order zero of the argument.
+ *
+ * The domain is divided into two major intervals [0, 2] and
+ * (2, infinity). In the first interval the rational approximation
+ * is J0(x) = 1 - x^2 / 4 + x^4 R(x^2)
+ * The second interval is further partitioned into eight equal segments
+ * of 1/x.
+ *
+ * J0(x) = sqrt(2/(pi x)) (P0(x) cos(X) - Q0(x) sin(X)),
+ * X = x - pi/4,
+ *
+ * and the auxiliary functions are given by
+ *
+ * J0(x)cos(X) + Y0(x)sin(X) = sqrt( 2/(pi x)) P0(x),
+ * P0(x) = 1 + 1/x^2 R(1/x^2)
+ *
+ * Y0(x)cos(X) - J0(x)sin(X) = sqrt( 2/(pi x)) Q0(x),
+ * Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Absolute error:
+ * arithmetic domain # trials peak rms
+ * IEEE 0, 30 100000 1.7e-34 2.4e-35
+ *
+ *
+ */
+
+/* y0l.c
+ *
+ * Bessel function of the second kind, order zero
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double x, y, y0l();
+ *
+ * y = y0l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns Bessel function of the second kind, of order
+ * zero, of the argument.
+ *
+ * The approximation is the same as for J0(x), and
+ * Y0(x) = sqrt(2/(pi x)) (P0(x) sin(X) + Q0(x) cos(X)).
+ *
+ * ACCURACY:
+ *
+ * Absolute error, when y0(x) < 1; else relative error:
+ *
+ * arithmetic domain # trials peak rms
+ * IEEE 0, 30 100000 3.0e-34 2.7e-35
+ *
+ */
+
+/* Copyright 2001 by Stephen L. Moshier (moshier@na-net.ornl.gov).
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "math.h"
+#include "math_private.h"
+
+/* 1 / sqrt(pi) */
+static const long double ONEOSQPI = 5.6418958354775628694807945156077258584405E-1L;
+/* 2 / pi */
+static const long double TWOOPI = 6.3661977236758134307553505349005744813784E-1L;
+static const long double zero = 0.0L;
+
+/* J0(x) = 1 - x^2/4 + x^2 x^2 R(x^2)
+ Peak relative error 3.4e-37
+ 0 <= x <= 2 */
+#define NJ0_2N 6
+static const long double J0_2N[NJ0_2N + 1] = {
+ 3.133239376997663645548490085151484674892E16L,
+ -5.479944965767990821079467311839107722107E14L,
+ 6.290828903904724265980249871997551894090E12L,
+ -3.633750176832769659849028554429106299915E10L,
+ 1.207743757532429576399485415069244807022E8L,
+ -2.107485999925074577174305650549367415465E5L,
+ 1.562826808020631846245296572935547005859E2L,
+};
+#define NJ0_2D 6
+static const long double J0_2D[NJ0_2D + 1] = {
+ 2.005273201278504733151033654496928968261E18L,
+ 2.063038558793221244373123294054149790864E16L,
+ 1.053350447931127971406896594022010524994E14L,
+ 3.496556557558702583143527876385508882310E11L,
+ 8.249114511878616075860654484367133976306E8L,
+ 1.402965782449571800199759247964242790589E6L,
+ 1.619910762853439600957801751815074787351E3L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2),
+ 0 <= 1/x <= .0625
+ Peak relative error 3.3e-36 */
+#define NP16_IN 9
+static const long double P16_IN[NP16_IN + 1] = {
+ -1.901689868258117463979611259731176301065E-16L,
+ -1.798743043824071514483008340803573980931E-13L,
+ -6.481746687115262291873324132944647438959E-11L,
+ -1.150651553745409037257197798528294248012E-8L,
+ -1.088408467297401082271185599507222695995E-6L,
+ -5.551996725183495852661022587879817546508E-5L,
+ -1.477286941214245433866838787454880214736E-3L,
+ -1.882877976157714592017345347609200402472E-2L,
+ -9.620983176855405325086530374317855880515E-2L,
+ -1.271468546258855781530458854476627766233E-1L,
+};
+#define NP16_ID 9
+static const long double P16_ID[NP16_ID + 1] = {
+ 2.704625590411544837659891569420764475007E-15L,
+ 2.562526347676857624104306349421985403573E-12L,
+ 9.259137589952741054108665570122085036246E-10L,
+ 1.651044705794378365237454962653430805272E-7L,
+ 1.573561544138733044977714063100859136660E-5L,
+ 8.134482112334882274688298469629884804056E-4L,
+ 2.219259239404080863919375103673593571689E-2L,
+ 2.976990606226596289580242451096393862792E-1L,
+ 1.713895630454693931742734911930937246254E0L,
+ 3.231552290717904041465898249160757368855E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ 0.0625 <= 1/x <= 0.125
+ Peak relative error 2.4e-35 */
+#define NP8_16N 10
+static const long double P8_16N[NP8_16N + 1] = {
+ -2.335166846111159458466553806683579003632E-15L,
+ -1.382763674252402720401020004169367089975E-12L,
+ -3.192160804534716696058987967592784857907E-10L,
+ -3.744199606283752333686144670572632116899E-8L,
+ -2.439161236879511162078619292571922772224E-6L,
+ -9.068436986859420951664151060267045346549E-5L,
+ -1.905407090637058116299757292660002697359E-3L,
+ -2.164456143936718388053842376884252978872E-2L,
+ -1.212178415116411222341491717748696499966E-1L,
+ -2.782433626588541494473277445959593334494E-1L,
+ -1.670703190068873186016102289227646035035E-1L,
+};
+#define NP8_16D 10
+static const long double P8_16D[NP8_16D + 1] = {
+ 3.321126181135871232648331450082662856743E-14L,
+ 1.971894594837650840586859228510007703641E-11L,
+ 4.571144364787008285981633719513897281690E-9L,
+ 5.396419143536287457142904742849052402103E-7L,
+ 3.551548222385845912370226756036899901549E-5L,
+ 1.342353874566932014705609788054598013516E-3L,
+ 2.899133293006771317589357444614157734385E-2L,
+ 3.455374978185770197704507681491574261545E-1L,
+ 2.116616964297512311314454834712634820514E0L,
+ 5.850768316827915470087758636881584174432E0L,
+ 5.655273858938766830855753983631132928968E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ 0.125 <= 1/x <= 0.1875
+ Peak relative error 2.7e-35 */
+#define NP5_8N 10
+static const long double P5_8N[NP5_8N + 1] = {
+ -1.270478335089770355749591358934012019596E-12L,
+ -4.007588712145412921057254992155810347245E-10L,
+ -4.815187822989597568124520080486652009281E-8L,
+ -2.867070063972764880024598300408284868021E-6L,
+ -9.218742195161302204046454768106063638006E-5L,
+ -1.635746821447052827526320629828043529997E-3L,
+ -1.570376886640308408247709616497261011707E-2L,
+ -7.656484795303305596941813361786219477807E-2L,
+ -1.659371030767513274944805479908858628053E-1L,
+ -1.185340550030955660015841796219919804915E-1L,
+ -8.920026499909994671248893388013790366712E-3L,
+};
+#define NP5_8D 9
+static const long double P5_8D[NP5_8D + 1] = {
+ 1.806902521016705225778045904631543990314E-11L,
+ 5.728502760243502431663549179135868966031E-9L,
+ 6.938168504826004255287618819550667978450E-7L,
+ 4.183769964807453250763325026573037785902E-5L,
+ 1.372660678476925468014882230851637878587E-3L,
+ 2.516452105242920335873286419212708961771E-2L,
+ 2.550502712902647803796267951846557316182E-1L,
+ 1.365861559418983216913629123778747617072E0L,
+ 3.523825618308783966723472468855042541407E0L,
+ 3.656365803506136165615111349150536282434E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ Peak relative error 3.5e-35
+ 0.1875 <= 1/x <= 0.25 */
+#define NP4_5N 9
+static const long double P4_5N[NP4_5N + 1] = {
+ -9.791405771694098960254468859195175708252E-10L,
+ -1.917193059944531970421626610188102836352E-7L,
+ -1.393597539508855262243816152893982002084E-5L,
+ -4.881863490846771259880606911667479860077E-4L,
+ -8.946571245022470127331892085881699269853E-3L,
+ -8.707474232568097513415336886103899434251E-2L,
+ -4.362042697474650737898551272505525973766E-1L,
+ -1.032712171267523975431451359962375617386E0L,
+ -9.630502683169895107062182070514713702346E-1L,
+ -2.251804386252969656586810309252357233320E-1L,
+};
+#define NP4_5D 9
+static const long double P4_5D[NP4_5D + 1] = {
+ 1.392555487577717669739688337895791213139E-8L,
+ 2.748886559120659027172816051276451376854E-6L,
+ 2.024717710644378047477189849678576659290E-4L,
+ 7.244868609350416002930624752604670292469E-3L,
+ 1.373631762292244371102989739300382152416E-1L,
+ 1.412298581400224267910294815260613240668E0L,
+ 7.742495637843445079276397723849017617210E0L,
+ 2.138429269198406512028307045259503811861E1L,
+ 2.651547684548423476506826951831712762610E1L,
+ 1.167499382465291931571685222882909166935E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ Peak relative error 2.3e-36
+ 0.25 <= 1/x <= 0.3125 */
+#define NP3r2_4N 9
+static const long double P3r2_4N[NP3r2_4N + 1] = {
+ -2.589155123706348361249809342508270121788E-8L,
+ -3.746254369796115441118148490849195516593E-6L,
+ -1.985595497390808544622893738135529701062E-4L,
+ -5.008253705202932091290132760394976551426E-3L,
+ -6.529469780539591572179155511840853077232E-2L,
+ -4.468736064761814602927408833818990271514E-1L,
+ -1.556391252586395038089729428444444823380E0L,
+ -2.533135309840530224072920725976994981638E0L,
+ -1.605509621731068453869408718565392869560E0L,
+ -2.518966692256192789269859830255724429375E-1L,
+};
+#define NP3r2_4D 9
+static const long double P3r2_4D[NP3r2_4D + 1] = {
+ 3.682353957237979993646169732962573930237E-7L,
+ 5.386741661883067824698973455566332102029E-5L,
+ 2.906881154171822780345134853794241037053E-3L,
+ 7.545832595801289519475806339863492074126E-2L,
+ 1.029405357245594877344360389469584526654E0L,
+ 7.565706120589873131187989560509757626725E0L,
+ 2.951172890699569545357692207898667665796E1L,
+ 5.785723537170311456298467310529815457536E1L,
+ 5.095621464598267889126015412522773474467E1L,
+ 1.602958484169953109437547474953308401442E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ Peak relative error 1.0e-35
+ 0.3125 <= 1/x <= 0.375 */
+#define NP2r7_3r2N 9
+static const long double P2r7_3r2N[NP2r7_3r2N + 1] = {
+ -1.917322340814391131073820537027234322550E-7L,
+ -1.966595744473227183846019639723259011906E-5L,
+ -7.177081163619679403212623526632690465290E-4L,
+ -1.206467373860974695661544653741899755695E-2L,
+ -1.008656452188539812154551482286328107316E-1L,
+ -4.216016116408810856620947307438823892707E-1L,
+ -8.378631013025721741744285026537009814161E-1L,
+ -6.973895635309960850033762745957946272579E-1L,
+ -1.797864718878320770670740413285763554812E-1L,
+ -4.098025357743657347681137871388402849581E-3L,
+};
+#define NP2r7_3r2D 8
+static const long double P2r7_3r2D[NP2r7_3r2D + 1] = {
+ 2.726858489303036441686496086962545034018E-6L,
+ 2.840430827557109238386808968234848081424E-4L,
+ 1.063826772041781947891481054529454088832E-2L,
+ 1.864775537138364773178044431045514405468E-1L,
+ 1.665660052857205170440952607701728254211E0L,
+ 7.723745889544331153080842168958348568395E0L,
+ 1.810726427571829798856428548102077799835E1L,
+ 1.986460672157794440666187503833545388527E1L,
+ 8.645503204552282306364296517220055815488E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ Peak relative error 1.3e-36
+ 0.3125 <= 1/x <= 0.4375 */
+#define NP2r3_2r7N 9
+static const long double P2r3_2r7N[NP2r3_2r7N + 1] = {
+ -1.594642785584856746358609622003310312622E-6L,
+ -1.323238196302221554194031733595194539794E-4L,
+ -3.856087818696874802689922536987100372345E-3L,
+ -5.113241710697777193011470733601522047399E-2L,
+ -3.334229537209911914449990372942022350558E-1L,
+ -1.075703518198127096179198549659283422832E0L,
+ -1.634174803414062725476343124267110981807E0L,
+ -1.030133247434119595616826842367268304880E0L,
+ -1.989811539080358501229347481000707289391E-1L,
+ -3.246859189246653459359775001466924610236E-3L,
+};
+#define NP2r3_2r7D 8
+static const long double P2r3_2r7D[NP2r3_2r7D + 1] = {
+ 2.267936634217251403663034189684284173018E-5L,
+ 1.918112982168673386858072491437971732237E-3L,
+ 5.771704085468423159125856786653868219522E-2L,
+ 8.056124451167969333717642810661498890507E-1L,
+ 5.687897967531010276788680634413789328776E0L,
+ 2.072596760717695491085444438270778394421E1L,
+ 3.801722099819929988585197088613160496684E1L,
+ 3.254620235902912339534998592085115836829E1L,
+ 1.104847772130720331801884344645060675036E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J0(x)cosX + Y0(x)sinX = sqrt( 2/(pi x)) P0(x), P0(x) = 1 + 1/x^2 R(1/x^2)
+ Peak relative error 1.2e-35
+ 0.4375 <= 1/x <= 0.5 */
+#define NP2_2r3N 8
+static const long double P2_2r3N[NP2_2r3N + 1] = {
+ -1.001042324337684297465071506097365389123E-4L,
+ -6.289034524673365824853547252689991418981E-3L,
+ -1.346527918018624234373664526930736205806E-1L,
+ -1.268808313614288355444506172560463315102E0L,
+ -5.654126123607146048354132115649177406163E0L,
+ -1.186649511267312652171775803270911971693E1L,
+ -1.094032424931998612551588246779200724257E1L,
+ -3.728792136814520055025256353193674625267E0L,
+ -3.000348318524471807839934764596331810608E-1L,
+};
+#define NP2_2r3D 8
+static const long double P2_2r3D[NP2_2r3D + 1] = {
+ 1.423705538269770974803901422532055612980E-3L,
+ 9.171476630091439978533535167485230575894E-2L,
+ 2.049776318166637248868444600215942828537E0L,
+ 2.068970329743769804547326701946144899583E1L,
+ 1.025103500560831035592731539565060347709E2L,
+ 2.528088049697570728252145557167066708284E2L,
+ 2.992160327587558573740271294804830114205E2L,
+ 1.540193761146551025832707739468679973036E2L,
+ 2.779516701986912132637672140709452502650E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 2.2e-35
+ 0 <= 1/x <= .0625 */
+#define NQ16_IN 10
+static const long double Q16_IN[NQ16_IN + 1] = {
+ 2.343640834407975740545326632205999437469E-18L,
+ 2.667978112927811452221176781536278257448E-15L,
+ 1.178415018484555397390098879501969116536E-12L,
+ 2.622049767502719728905924701288614016597E-10L,
+ 3.196908059607618864801313380896308968673E-8L,
+ 2.179466154171673958770030655199434798494E-6L,
+ 8.139959091628545225221976413795645177291E-5L,
+ 1.563900725721039825236927137885747138654E-3L,
+ 1.355172364265825167113562519307194840307E-2L,
+ 3.928058355906967977269780046844768588532E-2L,
+ 1.107891967702173292405380993183694932208E-2L,
+};
+#define NQ16_ID 9
+static const long double Q16_ID[NQ16_ID + 1] = {
+ 3.199850952578356211091219295199301766718E-17L,
+ 3.652601488020654842194486058637953363918E-14L,
+ 1.620179741394865258354608590461839031281E-11L,
+ 3.629359209474609630056463248923684371426E-9L,
+ 4.473680923894354600193264347733477363305E-7L,
+ 3.106368086644715743265603656011050476736E-5L,
+ 1.198239259946770604954664925153424252622E-3L,
+ 2.446041004004283102372887804475767568272E-2L,
+ 2.403235525011860603014707768815113698768E-1L,
+ 9.491006790682158612266270665136910927149E-1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+ };
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 5.1e-36
+ 0.0625 <= 1/x <= 0.125 */
+#define NQ8_16N 11
+static const long double Q8_16N[NQ8_16N + 1] = {
+ 1.001954266485599464105669390693597125904E-17L,
+ 7.545499865295034556206475956620160007849E-15L,
+ 2.267838684785673931024792538193202559922E-12L,
+ 3.561909705814420373609574999542459912419E-10L,
+ 3.216201422768092505214730633842924944671E-8L,
+ 1.731194793857907454569364622452058554314E-6L,
+ 5.576944613034537050396518509871004586039E-5L,
+ 1.051787760316848982655967052985391418146E-3L,
+ 1.102852974036687441600678598019883746959E-2L,
+ 5.834647019292460494254225988766702933571E-2L,
+ 1.290281921604364618912425380717127576529E-1L,
+ 7.598886310387075708640370806458926458301E-2L,
+};
+#define NQ8_16D 11
+static const long double Q8_16D[NQ8_16D + 1] = {
+ 1.368001558508338469503329967729951830843E-16L,
+ 1.034454121857542147020549303317348297289E-13L,
+ 3.128109209247090744354764050629381674436E-11L,
+ 4.957795214328501986562102573522064468671E-9L,
+ 4.537872468606711261992676606899273588899E-7L,
+ 2.493639207101727713192687060517509774182E-5L,
+ 8.294957278145328349785532236663051405805E-4L,
+ 1.646471258966713577374948205279380115839E-2L,
+ 1.878910092770966718491814497982191447073E-1L,
+ 1.152641605706170353727903052525652504075E0L,
+ 3.383550240669773485412333679367792932235E0L,
+ 3.823875252882035706910024716609908473970E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 3.9e-35
+ 0.125 <= 1/x <= 0.1875 */
+#define NQ5_8N 10
+static const long double Q5_8N[NQ5_8N + 1] = {
+ 1.750399094021293722243426623211733898747E-13L,
+ 6.483426211748008735242909236490115050294E-11L,
+ 9.279430665656575457141747875716899958373E-9L,
+ 6.696634968526907231258534757736576340266E-7L,
+ 2.666560823798895649685231292142838188061E-5L,
+ 6.025087697259436271271562769707550594540E-4L,
+ 7.652807734168613251901945778921336353485E-3L,
+ 5.226269002589406461622551452343519078905E-2L,
+ 1.748390159751117658969324896330142895079E-1L,
+ 2.378188719097006494782174902213083589660E-1L,
+ 8.383984859679804095463699702165659216831E-2L,
+};
+#define NQ5_8D 10
+static const long double Q5_8D[NQ5_8D + 1] = {
+ 2.389878229704327939008104855942987615715E-12L,
+ 8.926142817142546018703814194987786425099E-10L,
+ 1.294065862406745901206588525833274399038E-7L,
+ 9.524139899457666250828752185212769682191E-6L,
+ 3.908332488377770886091936221573123353489E-4L,
+ 9.250427033957236609624199884089916836748E-3L,
+ 1.263420066165922645975830877751588421451E-1L,
+ 9.692527053860420229711317379861733180654E-1L,
+ 3.937813834630430172221329298841520707954E0L,
+ 7.603126427436356534498908111445191312181E0L,
+ 5.670677653334105479259958485084550934305E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 3.2e-35
+ 0.1875 <= 1/x <= 0.25 */
+#define NQ4_5N 10
+static const long double Q4_5N[NQ4_5N + 1] = {
+ 2.233870042925895644234072357400122854086E-11L,
+ 5.146223225761993222808463878999151699792E-9L,
+ 4.459114531468296461688753521109797474523E-7L,
+ 1.891397692931537975547242165291668056276E-5L,
+ 4.279519145911541776938964806470674565504E-4L,
+ 5.275239415656560634702073291768904783989E-3L,
+ 3.468698403240744801278238473898432608887E-2L,
+ 1.138773146337708415188856882915457888274E-1L,
+ 1.622717518946443013587108598334636458955E-1L,
+ 7.249040006390586123760992346453034628227E-2L,
+ 1.941595365256460232175236758506411486667E-3L,
+};
+#define NQ4_5D 9
+static const long double Q4_5D[NQ4_5D + 1] = {
+ 3.049977232266999249626430127217988047453E-10L,
+ 7.120883230531035857746096928889676144099E-8L,
+ 6.301786064753734446784637919554359588859E-6L,
+ 2.762010530095069598480766869426308077192E-4L,
+ 6.572163250572867859316828886203406361251E-3L,
+ 8.752566114841221958200215255461843397776E-2L,
+ 6.487654992874805093499285311075289932664E-1L,
+ 2.576550017826654579451615283022812801435E0L,
+ 5.056392229924022835364779562707348096036E0L,
+ 4.179770081068251464907531367859072157773E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 1.4e-36
+ 0.25 <= 1/x <= 0.3125 */
+#define NQ3r2_4N 10
+static const long double Q3r2_4N[NQ3r2_4N + 1] = {
+ 6.126167301024815034423262653066023684411E-10L,
+ 1.043969327113173261820028225053598975128E-7L,
+ 6.592927270288697027757438170153763220190E-6L,
+ 2.009103660938497963095652951912071336730E-4L,
+ 3.220543385492643525985862356352195896964E-3L,
+ 2.774405975730545157543417650436941650990E-2L,
+ 1.258114008023826384487378016636555041129E-1L,
+ 2.811724258266902502344701449984698323860E-1L,
+ 2.691837665193548059322831687432415014067E-1L,
+ 7.949087384900985370683770525312735605034E-2L,
+ 1.229509543620976530030153018986910810747E-3L,
+};
+#define NQ3r2_4D 9
+static const long double Q3r2_4D[NQ3r2_4D + 1] = {
+ 8.364260446128475461539941389210166156568E-9L,
+ 1.451301850638956578622154585560759862764E-6L,
+ 9.431830010924603664244578867057141839463E-5L,
+ 3.004105101667433434196388593004526182741E-3L,
+ 5.148157397848271739710011717102773780221E-2L,
+ 4.901089301726939576055285374953887874895E-1L,
+ 2.581760991981709901216967665934142240346E0L,
+ 7.257105880775059281391729708630912791847E0L,
+ 1.006014717326362868007913423810737369312E1L,
+ 5.879416600465399514404064187445293212470E0L,
+ /* 1.000000000000000000000000000000000000000E0*/
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 3.8e-36
+ 0.3125 <= 1/x <= 0.375 */
+#define NQ2r7_3r2N 9
+static const long double Q2r7_3r2N[NQ2r7_3r2N + 1] = {
+ 7.584861620402450302063691901886141875454E-8L,
+ 9.300939338814216296064659459966041794591E-6L,
+ 4.112108906197521696032158235392604947895E-4L,
+ 8.515168851578898791897038357239630654431E-3L,
+ 8.971286321017307400142720556749573229058E-2L,
+ 4.885856732902956303343015636331874194498E-1L,
+ 1.334506268733103291656253500506406045846E0L,
+ 1.681207956863028164179042145803851824654E0L,
+ 8.165042692571721959157677701625853772271E-1L,
+ 9.805848115375053300608712721986235900715E-2L,
+};
+#define NQ2r7_3r2D 9
+static const long double Q2r7_3r2D[NQ2r7_3r2D + 1] = {
+ 1.035586492113036586458163971239438078160E-6L,
+ 1.301999337731768381683593636500979713689E-4L,
+ 5.993695702564527062553071126719088859654E-3L,
+ 1.321184892887881883489141186815457808785E-1L,
+ 1.528766555485015021144963194165165083312E0L,
+ 9.561463309176490874525827051566494939295E0L,
+ 3.203719484883967351729513662089163356911E1L,
+ 5.497294687660930446641539152123568668447E1L,
+ 4.391158169390578768508675452986948391118E1L,
+ 1.347836630730048077907818943625789418378E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 2.2e-35
+ 0.375 <= 1/x <= 0.4375 */
+#define NQ2r3_2r7N 9
+static const long double Q2r3_2r7N[NQ2r3_2r7N + 1] = {
+ 4.455027774980750211349941766420190722088E-7L,
+ 4.031998274578520170631601850866780366466E-5L,
+ 1.273987274325947007856695677491340636339E-3L,
+ 1.818754543377448509897226554179659122873E-2L,
+ 1.266748858326568264126353051352269875352E-1L,
+ 4.327578594728723821137731555139472880414E-1L,
+ 6.892532471436503074928194969154192615359E-1L,
+ 4.490775818438716873422163588640262036506E-1L,
+ 8.649615949297322440032000346117031581572E-2L,
+ 7.261345286655345047417257611469066147561E-4L,
+};
+#define NQ2r3_2r7D 8
+static const long double Q2r3_2r7D[NQ2r3_2r7D + 1] = {
+ 6.082600739680555266312417978064954793142E-6L,
+ 5.693622538165494742945717226571441747567E-4L,
+ 1.901625907009092204458328768129666975975E-2L,
+ 2.958689532697857335456896889409923371570E-1L,
+ 2.343124711045660081603809437993368799568E0L,
+ 9.665894032187458293568704885528192804376E0L,
+ 2.035273104990617136065743426322454881353E1L,
+ 2.044102010478792896815088858740075165531E1L,
+ 8.445937177863155827844146643468706599304E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y0(x)cosX - J0(x)sinX = sqrt( 2/(pi x)) Q0(x),
+ Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
+ Peak relative error 3.1e-36
+ 0.4375 <= 1/x <= 0.5 */
+#define NQ2_2r3N 9
+static const long double Q2_2r3N[NQ2_2r3N + 1] = {
+ 2.817566786579768804844367382809101929314E-6L,
+ 2.122772176396691634147024348373539744935E-4L,
+ 5.501378031780457828919593905395747517585E-3L,
+ 6.355374424341762686099147452020466524659E-2L,
+ 3.539652320122661637429658698954748337223E-1L,
+ 9.571721066119617436343740541777014319695E-1L,
+ 1.196258777828426399432550698612171955305E0L,
+ 6.069388659458926158392384709893753793967E-1L,
+ 9.026746127269713176512359976978248763621E-2L,
+ 5.317668723070450235320878117210807236375E-4L,
+};
+#define NQ2_2r3D 8
+static const long double Q2_2r3D[NQ2_2r3D + 1] = {
+ 3.846924354014260866793741072933159380158E-5L,
+ 3.017562820057704325510067178327449946763E-3L,
+ 8.356305620686867949798885808540444210935E-2L,
+ 1.068314930499906838814019619594424586273E0L,
+ 6.900279623894821067017966573640732685233E0L,
+ 2.307667390886377924509090271780839563141E1L,
+ 3.921043465412723970791036825401273528513E1L,
+ 3.167569478939719383241775717095729233436E1L,
+ 1.051023841699200920276198346301543665909E1L,
+ /* 1.000000000000000000000000000000000000000E0*/
+};
+
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+neval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+deval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Bessel function of the first kind, order zero. */
+
+long double
+__ieee754_j0l (long double x)
+{
+ long double xx, xinv, z, p, q, c, s, cc, ss;
+
+ if (! finitel (x))
+ {
+ if (x != x)
+ return x;
+ else
+ return 0.0L;
+ }
+ if (x == 0.0L)
+ return 1.0L;
+
+ xx = fabsl (x);
+ if (xx <= 2.0L)
+ {
+ /* 0 <= x <= 2 */
+ z = xx * xx;
+ p = z * z * neval (z, J0_2N, NJ0_2N) / deval (z, J0_2D, NJ0_2D);
+ p -= 0.25L * z;
+ p += 1.0L;
+ return p;
+ }
+
+ xinv = 1.0L / xx;
+ z = xinv * xinv;
+ if (xinv <= 0.25)
+ {
+ if (xinv <= 0.125)
+ {
+ if (xinv <= 0.0625)
+ {
+ p = neval (z, P16_IN, NP16_IN) / deval (z, P16_ID, NP16_ID);
+ q = neval (z, Q16_IN, NQ16_IN) / deval (z, Q16_ID, NQ16_ID);
+ }
+ else
+ {
+ p = neval (z, P8_16N, NP8_16N) / deval (z, P8_16D, NP8_16D);
+ q = neval (z, Q8_16N, NQ8_16N) / deval (z, Q8_16D, NQ8_16D);
+ }
+ }
+ else if (xinv <= 0.1875)
+ {
+ p = neval (z, P5_8N, NP5_8N) / deval (z, P5_8D, NP5_8D);
+ q = neval (z, Q5_8N, NQ5_8N) / deval (z, Q5_8D, NQ5_8D);
+ }
+ else
+ {
+ p = neval (z, P4_5N, NP4_5N) / deval (z, P4_5D, NP4_5D);
+ q = neval (z, Q4_5N, NQ4_5N) / deval (z, Q4_5D, NQ4_5D);
+ }
+ } /* .25 */
+ else /* if (xinv <= 0.5) */
+ {
+ if (xinv <= 0.375)
+ {
+ if (xinv <= 0.3125)
+ {
+ p = neval (z, P3r2_4N, NP3r2_4N) / deval (z, P3r2_4D, NP3r2_4D);
+ q = neval (z, Q3r2_4N, NQ3r2_4N) / deval (z, Q3r2_4D, NQ3r2_4D);
+ }
+ else
+ {
+ p = neval (z, P2r7_3r2N, NP2r7_3r2N)
+ / deval (z, P2r7_3r2D, NP2r7_3r2D);
+ q = neval (z, Q2r7_3r2N, NQ2r7_3r2N)
+ / deval (z, Q2r7_3r2D, NQ2r7_3r2D);
+ }
+ }
+ else if (xinv <= 0.4375)
+ {
+ p = neval (z, P2r3_2r7N, NP2r3_2r7N)
+ / deval (z, P2r3_2r7D, NP2r3_2r7D);
+ q = neval (z, Q2r3_2r7N, NQ2r3_2r7N)
+ / deval (z, Q2r3_2r7D, NQ2r3_2r7D);
+ }
+ else
+ {
+ p = neval (z, P2_2r3N, NP2_2r3N) / deval (z, P2_2r3D, NP2_2r3D);
+ q = neval (z, Q2_2r3N, NQ2_2r3N) / deval (z, Q2_2r3D, NQ2_2r3D);
+ }
+ }
+ p = 1.0L + z * p;
+ q = z * xinv * q;
+ q = q - 0.125L * xinv;
+ /* X = x - pi/4
+ cos(X) = cos(x) cos(pi/4) + sin(x) sin(pi/4)
+ = 1/sqrt(2) * (cos(x) + sin(x))
+ sin(X) = sin(x) cos(pi/4) - cos(x) sin(pi/4)
+ = 1/sqrt(2) * (sin(x) - cos(x))
+ sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ cf. Fdlibm. */
+ c = cosl (xx);
+ s = sinl (xx);
+ ss = s - c;
+ cc = s + c;
+ z = -cosl (xx + xx);
+ if ((s * c) < 0)
+ cc = z / ss;
+ else
+ ss = z / cc;
+ z = ONEOSQPI * (p * cc - q * ss) / sqrtl (xx);
+ return z;
+}
+
+
+/* Y0(x) = 2/pi * log(x) * J0(x) + R(x^2)
+ Peak absolute error 1.7e-36 (relative where Y0 > 1)
+ 0 <= x <= 2 */
+#define NY0_2N 7
+static long double Y0_2N[NY0_2N + 1] = {
+ -1.062023609591350692692296993537002558155E19L,
+ 2.542000883190248639104127452714966858866E19L,
+ -1.984190771278515324281415820316054696545E18L,
+ 4.982586044371592942465373274440222033891E16L,
+ -5.529326354780295177243773419090123407550E14L,
+ 3.013431465522152289279088265336861140391E12L,
+ -7.959436160727126750732203098982718347785E9L,
+ 8.230845651379566339707130644134372793322E6L,
+};
+#define NY0_2D 7
+static long double Y0_2D[NY0_2D + 1] = {
+ 1.438972634353286978700329883122253752192E20L,
+ 1.856409101981569254247700169486907405500E18L,
+ 1.219693352678218589553725579802986255614E16L,
+ 5.389428943282838648918475915779958097958E13L,
+ 1.774125762108874864433872173544743051653E11L,
+ 4.522104832545149534808218252434693007036E8L,
+ 8.872187401232943927082914504125234454930E5L,
+ 1.251945613186787532055610876304669413955E3L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+
+/* Bessel function of the second kind, order zero. */
+
+long double
+ __ieee754_y0l(long double x)
+{
+ long double xx, xinv, z, p, q, c, s, cc, ss;
+
+ if (! finitel (x))
+ {
+ if (x != x)
+ return x;
+ else
+ return 0.0L;
+ }
+ if (x <= 0.0L)
+ {
+ if (x < 0.0L)
+ return (zero / (zero * x));
+ return -HUGE_VALL + x;
+ }
+ xx = fabsl (x);
+ if (xx <= 2.0L)
+ {
+ /* 0 <= x <= 2 */
+ z = xx * xx;
+ p = neval (z, Y0_2N, NY0_2N) / deval (z, Y0_2D, NY0_2D);
+ p = TWOOPI * logl(x) * __ieee754_j0l(x) + p;
+ return p;
+ }
+
+ xinv = 1.0L / xx;
+ z = xinv * xinv;
+ if (xinv <= 0.25)
+ {
+ if (xinv <= 0.125)
+ {
+ if (xinv <= 0.0625)
+ {
+ p = neval (z, P16_IN, NP16_IN) / deval (z, P16_ID, NP16_ID);
+ q = neval (z, Q16_IN, NQ16_IN) / deval (z, Q16_ID, NQ16_ID);
+ }
+ else
+ {
+ p = neval (z, P8_16N, NP8_16N) / deval (z, P8_16D, NP8_16D);
+ q = neval (z, Q8_16N, NQ8_16N) / deval (z, Q8_16D, NQ8_16D);
+ }
+ }
+ else if (xinv <= 0.1875)
+ {
+ p = neval (z, P5_8N, NP5_8N) / deval (z, P5_8D, NP5_8D);
+ q = neval (z, Q5_8N, NQ5_8N) / deval (z, Q5_8D, NQ5_8D);
+ }
+ else
+ {
+ p = neval (z, P4_5N, NP4_5N) / deval (z, P4_5D, NP4_5D);
+ q = neval (z, Q4_5N, NQ4_5N) / deval (z, Q4_5D, NQ4_5D);
+ }
+ } /* .25 */
+ else /* if (xinv <= 0.5) */
+ {
+ if (xinv <= 0.375)
+ {
+ if (xinv <= 0.3125)
+ {
+ p = neval (z, P3r2_4N, NP3r2_4N) / deval (z, P3r2_4D, NP3r2_4D);
+ q = neval (z, Q3r2_4N, NQ3r2_4N) / deval (z, Q3r2_4D, NQ3r2_4D);
+ }
+ else
+ {
+ p = neval (z, P2r7_3r2N, NP2r7_3r2N)
+ / deval (z, P2r7_3r2D, NP2r7_3r2D);
+ q = neval (z, Q2r7_3r2N, NQ2r7_3r2N)
+ / deval (z, Q2r7_3r2D, NQ2r7_3r2D);
+ }
+ }
+ else if (xinv <= 0.4375)
+ {
+ p = neval (z, P2r3_2r7N, NP2r3_2r7N)
+ / deval (z, P2r3_2r7D, NP2r3_2r7D);
+ q = neval (z, Q2r3_2r7N, NQ2r3_2r7N)
+ / deval (z, Q2r3_2r7D, NQ2r3_2r7D);
+ }
+ else
+ {
+ p = neval (z, P2_2r3N, NP2_2r3N) / deval (z, P2_2r3D, NP2_2r3D);
+ q = neval (z, Q2_2r3N, NQ2_2r3N) / deval (z, Q2_2r3D, NQ2_2r3D);
+ }
+ }
+ p = 1.0L + z * p;
+ q = z * xinv * q;
+ q = q - 0.125L * xinv;
+ /* X = x - pi/4
+ cos(X) = cos(x) cos(pi/4) + sin(x) sin(pi/4)
+ = 1/sqrt(2) * (cos(x) + sin(x))
+ sin(X) = sin(x) cos(pi/4) - cos(x) sin(pi/4)
+ = 1/sqrt(2) * (sin(x) - cos(x))
+ sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ cf. Fdlibm. */
+ c = cosl (x);
+ s = sinl (x);
+ ss = s - c;
+ cc = s + c;
+ z = -cosl (x + x);
+ if ((s * c) < 0)
+ cc = z / ss;
+ else
+ ss = z / cc;
+ z = ONEOSQPI * (p * ss + q * cc) / sqrtl (x);
+ return z;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_j1l.c b/libc/sysdeps/ieee754/ldbl-128/e_j1l.c
new file mode 100644
index 000000000..3a977c2a8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_j1l.c
@@ -0,0 +1,929 @@
+/* j1l.c
+ *
+ * Bessel function of order one
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, j1l();
+ *
+ * y = j1l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns Bessel function of first kind, order one of the argument.
+ *
+ * The domain is divided into two major intervals [0, 2] and
+ * (2, infinity). In the first interval the rational approximation is
+ * J1(x) = .5x + x x^2 R(x^2)
+ *
+ * The second interval is further partitioned into eight equal segments
+ * of 1/x.
+ * J1(x) = sqrt(2/(pi x)) (P1(x) cos(X) - Q1(x) sin(X)),
+ * X = x - 3 pi / 4,
+ *
+ * and the auxiliary functions are given by
+ *
+ * J1(x)cos(X) + Y1(x)sin(X) = sqrt( 2/(pi x)) P1(x),
+ * P1(x) = 1 + 1/x^2 R(1/x^2)
+ *
+ * Y1(x)cos(X) - J1(x)sin(X) = sqrt( 2/(pi x)) Q1(x),
+ * Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)).
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Absolute error:
+ * arithmetic domain # trials peak rms
+ * IEEE 0, 30 100000 2.8e-34 2.7e-35
+ *
+ *
+ */
+
+/* y1l.c
+ *
+ * Bessel function of the second kind, order one
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double x, y, y1l();
+ *
+ * y = y1l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns Bessel function of the second kind, of order
+ * one, of the argument.
+ *
+ * The domain is divided into two major intervals [0, 2] and
+ * (2, infinity). In the first interval the rational approximation is
+ * Y1(x) = 2/pi * (log(x) * J1(x) - 1/x) + x R(x^2) .
+ * In the second interval the approximation is the same as for J1(x), and
+ * Y1(x) = sqrt(2/(pi x)) (P1(x) sin(X) + Q1(x) cos(X)),
+ * X = x - 3 pi / 4.
+ *
+ * ACCURACY:
+ *
+ * Absolute error, when y0(x) < 1; else relative error:
+ *
+ * arithmetic domain # trials peak rms
+ * IEEE 0, 30 100000 2.7e-34 2.9e-35
+ *
+ */
+
+/* Copyright 2001 by Stephen L. Moshier (moshier@na-net.onrl.gov).
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "math.h"
+#include "math_private.h"
+
+/* 1 / sqrt(pi) */
+static const long double ONEOSQPI = 5.6418958354775628694807945156077258584405E-1L;
+/* 2 / pi */
+static const long double TWOOPI = 6.3661977236758134307553505349005744813784E-1L;
+static const long double zero = 0.0L;
+
+/* J1(x) = .5x + x x^2 R(x^2)
+ Peak relative error 1.9e-35
+ 0 <= x <= 2 */
+#define NJ0_2N 6
+static const long double J0_2N[NJ0_2N + 1] = {
+ -5.943799577386942855938508697619735179660E16L,
+ 1.812087021305009192259946997014044074711E15L,
+ -2.761698314264509665075127515729146460895E13L,
+ 2.091089497823600978949389109350658815972E11L,
+ -8.546413231387036372945453565654130054307E8L,
+ 1.797229225249742247475464052741320612261E6L,
+ -1.559552840946694171346552770008812083969E3L
+};
+#define NJ0_2D 6
+static const long double J0_2D[NJ0_2D + 1] = {
+ 9.510079323819108569501613916191477479397E17L,
+ 1.063193817503280529676423936545854693915E16L,
+ 5.934143516050192600795972192791775226920E13L,
+ 2.168000911950620999091479265214368352883E11L,
+ 5.673775894803172808323058205986256928794E8L,
+ 1.080329960080981204840966206372671147224E6L,
+ 1.411951256636576283942477881535283304912E3L,
+ /* 1.000000000000000000000000000000000000000E0L */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ 0 <= 1/x <= .0625
+ Peak relative error 3.6e-36 */
+#define NP16_IN 9
+static const long double P16_IN[NP16_IN + 1] = {
+ 5.143674369359646114999545149085139822905E-16L,
+ 4.836645664124562546056389268546233577376E-13L,
+ 1.730945562285804805325011561498453013673E-10L,
+ 3.047976856147077889834905908605310585810E-8L,
+ 2.855227609107969710407464739188141162386E-6L,
+ 1.439362407936705484122143713643023998457E-4L,
+ 3.774489768532936551500999699815873422073E-3L,
+ 4.723962172984642566142399678920790598426E-2L,
+ 2.359289678988743939925017240478818248735E-1L,
+ 3.032580002220628812728954785118117124520E-1L,
+};
+#define NP16_ID 9
+static const long double P16_ID[NP16_ID + 1] = {
+ 4.389268795186898018132945193912677177553E-15L,
+ 4.132671824807454334388868363256830961655E-12L,
+ 1.482133328179508835835963635130894413136E-9L,
+ 2.618941412861122118906353737117067376236E-7L,
+ 2.467854246740858470815714426201888034270E-5L,
+ 1.257192927368839847825938545925340230490E-3L,
+ 3.362739031941574274949719324644120720341E-2L,
+ 4.384458231338934105875343439265370178858E-1L,
+ 2.412830809841095249170909628197264854651E0L,
+ 4.176078204111348059102962617368214856874E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ 0.0625 <= 1/x <= 0.125
+ Peak relative error 1.9e-36 */
+#define NP8_16N 11
+static const long double P8_16N[NP8_16N + 1] = {
+ 2.984612480763362345647303274082071598135E-16L,
+ 1.923651877544126103941232173085475682334E-13L,
+ 4.881258879388869396043760693256024307743E-11L,
+ 6.368866572475045408480898921866869811889E-9L,
+ 4.684818344104910450523906967821090796737E-7L,
+ 2.005177298271593587095982211091300382796E-5L,
+ 4.979808067163957634120681477207147536182E-4L,
+ 6.946005761642579085284689047091173581127E-3L,
+ 5.074601112955765012750207555985299026204E-2L,
+ 1.698599455896180893191766195194231825379E-1L,
+ 1.957536905259237627737222775573623779638E-1L,
+ 2.991314703282528370270179989044994319374E-2L,
+};
+#define NP8_16D 10
+static const long double P8_16D[NP8_16D + 1] = {
+ 2.546869316918069202079580939942463010937E-15L,
+ 1.644650111942455804019788382157745229955E-12L,
+ 4.185430770291694079925607420808011147173E-10L,
+ 5.485331966975218025368698195861074143153E-8L,
+ 4.062884421686912042335466327098932678905E-6L,
+ 1.758139661060905948870523641319556816772E-4L,
+ 4.445143889306356207566032244985607493096E-3L,
+ 6.391901016293512632765621532571159071158E-2L,
+ 4.933040207519900471177016015718145795434E-1L,
+ 1.839144086168947712971630337250761842976E0L,
+ 2.715120873995490920415616716916149586579E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ 0.125 <= 1/x <= 0.1875
+ Peak relative error 1.3e-36 */
+#define NP5_8N 10
+static const long double P5_8N[NP5_8N + 1] = {
+ 2.837678373978003452653763806968237227234E-12L,
+ 9.726641165590364928442128579282742354806E-10L,
+ 1.284408003604131382028112171490633956539E-7L,
+ 8.524624695868291291250573339272194285008E-6L,
+ 3.111516908953172249853673787748841282846E-4L,
+ 6.423175156126364104172801983096596409176E-3L,
+ 7.430220589989104581004416356260692450652E-2L,
+ 4.608315409833682489016656279567605536619E-1L,
+ 1.396870223510964882676225042258855977512E0L,
+ 1.718500293904122365894630460672081526236E0L,
+ 5.465927698800862172307352821870223855365E-1L
+};
+#define NP5_8D 10
+static const long double P5_8D[NP5_8D + 1] = {
+ 2.421485545794616609951168511612060482715E-11L,
+ 8.329862750896452929030058039752327232310E-9L,
+ 1.106137992233383429630592081375289010720E-6L,
+ 7.405786153760681090127497796448503306939E-5L,
+ 2.740364785433195322492093333127633465227E-3L,
+ 5.781246470403095224872243564165254652198E-2L,
+ 6.927711353039742469918754111511109983546E-1L,
+ 4.558679283460430281188304515922826156690E0L,
+ 1.534468499844879487013168065728837900009E1L,
+ 2.313927430889218597919624843161569422745E1L,
+ 1.194506341319498844336768473218382828637E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ Peak relative error 1.4e-36
+ 0.1875 <= 1/x <= 0.25 */
+#define NP4_5N 10
+static const long double P4_5N[NP4_5N + 1] = {
+ 1.846029078268368685834261260420933914621E-10L,
+ 3.916295939611376119377869680335444207768E-8L,
+ 3.122158792018920627984597530935323997312E-6L,
+ 1.218073444893078303994045653603392272450E-4L,
+ 2.536420827983485448140477159977981844883E-3L,
+ 2.883011322006690823959367922241169171315E-2L,
+ 1.755255190734902907438042414495469810830E-1L,
+ 5.379317079922628599870898285488723736599E-1L,
+ 7.284904050194300773890303361501726561938E-1L,
+ 3.270110346613085348094396323925000362813E-1L,
+ 1.804473805689725610052078464951722064757E-2L,
+};
+#define NP4_5D 9
+static const long double P4_5D[NP4_5D + 1] = {
+ 1.575278146806816970152174364308980863569E-9L,
+ 3.361289173657099516191331123405675054321E-7L,
+ 2.704692281550877810424745289838790693708E-5L,
+ 1.070854930483999749316546199273521063543E-3L,
+ 2.282373093495295842598097265627962125411E-2L,
+ 2.692025460665354148328762368240343249830E-1L,
+ 1.739892942593664447220951225734811133759E0L,
+ 5.890727576752230385342377570386657229324E0L,
+ 9.517442287057841500750256954117735128153E0L,
+ 6.100616353935338240775363403030137736013E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ Peak relative error 3.0e-36
+ 0.25 <= 1/x <= 0.3125 */
+#define NP3r2_4N 9
+static const long double P3r2_4N[NP3r2_4N + 1] = {
+ 8.240803130988044478595580300846665863782E-8L,
+ 1.179418958381961224222969866406483744580E-5L,
+ 6.179787320956386624336959112503824397755E-4L,
+ 1.540270833608687596420595830747166658383E-2L,
+ 1.983904219491512618376375619598837355076E-1L,
+ 1.341465722692038870390470651608301155565E0L,
+ 4.617865326696612898792238245990854646057E0L,
+ 7.435574801812346424460233180412308000587E0L,
+ 4.671327027414635292514599201278557680420E0L,
+ 7.299530852495776936690976966995187714739E-1L,
+};
+#define NP3r2_4D 9
+static const long double P3r2_4D[NP3r2_4D + 1] = {
+ 7.032152009675729604487575753279187576521E-7L,
+ 1.015090352324577615777511269928856742848E-4L,
+ 5.394262184808448484302067955186308730620E-3L,
+ 1.375291438480256110455809354836988584325E-1L,
+ 1.836247144461106304788160919310404376670E0L,
+ 1.314378564254376655001094503090935880349E1L,
+ 4.957184590465712006934452500894672343488E1L,
+ 9.287394244300647738855415178790263465398E1L,
+ 7.652563275535900609085229286020552768399E1L,
+ 2.147042473003074533150718117770093209096E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ Peak relative error 1.0e-35
+ 0.3125 <= 1/x <= 0.375 */
+#define NP2r7_3r2N 9
+static const long double P2r7_3r2N[NP2r7_3r2N + 1] = {
+ 4.599033469240421554219816935160627085991E-7L,
+ 4.665724440345003914596647144630893997284E-5L,
+ 1.684348845667764271596142716944374892756E-3L,
+ 2.802446446884455707845985913454440176223E-2L,
+ 2.321937586453963310008279956042545173930E-1L,
+ 9.640277413988055668692438709376437553804E-1L,
+ 1.911021064710270904508663334033003246028E0L,
+ 1.600811610164341450262992138893970224971E0L,
+ 4.266299218652587901171386591543457861138E-1L,
+ 1.316470424456061252962568223251247207325E-2L,
+};
+#define NP2r7_3r2D 8
+static const long double P2r7_3r2D[NP2r7_3r2D + 1] = {
+ 3.924508608545520758883457108453520099610E-6L,
+ 4.029707889408829273226495756222078039823E-4L,
+ 1.484629715787703260797886463307469600219E-2L,
+ 2.553136379967180865331706538897231588685E-1L,
+ 2.229457223891676394409880026887106228740E0L,
+ 1.005708903856384091956550845198392117318E1L,
+ 2.277082659664386953166629360352385889558E1L,
+ 2.384726835193630788249826630376533988245E1L,
+ 9.700989749041320895890113781610939632410E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ Peak relative error 1.7e-36
+ 0.3125 <= 1/x <= 0.4375 */
+#define NP2r3_2r7N 9
+static const long double P2r3_2r7N[NP2r3_2r7N + 1] = {
+ 3.916766777108274628543759603786857387402E-6L,
+ 3.212176636756546217390661984304645137013E-4L,
+ 9.255768488524816445220126081207248947118E-3L,
+ 1.214853146369078277453080641911700735354E-1L,
+ 7.855163309847214136198449861311404633665E-1L,
+ 2.520058073282978403655488662066019816540E0L,
+ 3.825136484837545257209234285382183711466E0L,
+ 2.432569427554248006229715163865569506873E0L,
+ 4.877934835018231178495030117729800489743E-1L,
+ 1.109902737860249670981355149101343427885E-2L,
+};
+#define NP2r3_2r7D 8
+static const long double P2r3_2r7D[NP2r3_2r7D + 1] = {
+ 3.342307880794065640312646341190547184461E-5L,
+ 2.782182891138893201544978009012096558265E-3L,
+ 8.221304931614200702142049236141249929207E-2L,
+ 1.123728246291165812392918571987858010949E0L,
+ 7.740482453652715577233858317133423434590E0L,
+ 2.737624677567945952953322566311201919139E1L,
+ 4.837181477096062403118304137851260715475E1L,
+ 3.941098643468580791437772701093795299274E1L,
+ 1.245821247166544627558323920382547533630E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* J1(x)cosX + Y1(x)sinX = sqrt( 2/(pi x)) P1(x), P1(x) = 1 + 1/x^2 R(1/x^2),
+ Peak relative error 1.7e-35
+ 0.4375 <= 1/x <= 0.5 */
+#define NP2_2r3N 8
+static const long double P2_2r3N[NP2_2r3N + 1] = {
+ 3.397930802851248553545191160608731940751E-4L,
+ 2.104020902735482418784312825637833698217E-2L,
+ 4.442291771608095963935342749477836181939E-1L,
+ 4.131797328716583282869183304291833754967E0L,
+ 1.819920169779026500146134832455189917589E1L,
+ 3.781779616522937565300309684282401791291E1L,
+ 3.459605449728864218972931220783543410347E1L,
+ 1.173594248397603882049066603238568316561E1L,
+ 9.455702270242780642835086549285560316461E-1L,
+};
+#define NP2_2r3D 8
+static const long double P2_2r3D[NP2_2r3D + 1] = {
+ 2.899568897241432883079888249845707400614E-3L,
+ 1.831107138190848460767699919531132426356E-1L,
+ 3.999350044057883839080258832758908825165E0L,
+ 3.929041535867957938340569419874195303712E1L,
+ 1.884245613422523323068802689915538908291E2L,
+ 4.461469948819229734353852978424629815929E2L,
+ 5.004998753999796821224085972610636347903E2L,
+ 2.386342520092608513170837883757163414100E2L,
+ 3.791322528149347975999851588922424189957E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 8.0e-36
+ 0 <= 1/x <= .0625 */
+#define NQ16_IN 10
+static const long double Q16_IN[NQ16_IN + 1] = {
+ -3.917420835712508001321875734030357393421E-18L,
+ -4.440311387483014485304387406538069930457E-15L,
+ -1.951635424076926487780929645954007139616E-12L,
+ -4.318256438421012555040546775651612810513E-10L,
+ -5.231244131926180765270446557146989238020E-8L,
+ -3.540072702902043752460711989234732357653E-6L,
+ -1.311017536555269966928228052917534882984E-4L,
+ -2.495184669674631806622008769674827575088E-3L,
+ -2.141868222987209028118086708697998506716E-2L,
+ -6.184031415202148901863605871197272650090E-2L,
+ -1.922298704033332356899546792898156493887E-2L,
+};
+#define NQ16_ID 9
+static const long double Q16_ID[NQ16_ID + 1] = {
+ 3.820418034066293517479619763498400162314E-17L,
+ 4.340702810799239909648911373329149354911E-14L,
+ 1.914985356383416140706179933075303538524E-11L,
+ 4.262333682610888819476498617261895474330E-9L,
+ 5.213481314722233980346462747902942182792E-7L,
+ 3.585741697694069399299005316809954590558E-5L,
+ 1.366513429642842006385029778105539457546E-3L,
+ 2.745282599850704662726337474371355160594E-2L,
+ 2.637644521611867647651200098449903330074E-1L,
+ 1.006953426110765984590782655598680488746E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+ };
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 1.9e-36
+ 0.0625 <= 1/x <= 0.125 */
+#define NQ8_16N 11
+static const long double Q8_16N[NQ8_16N + 1] = {
+ -2.028630366670228670781362543615221542291E-17L,
+ -1.519634620380959966438130374006858864624E-14L,
+ -4.540596528116104986388796594639405114524E-12L,
+ -7.085151756671466559280490913558388648274E-10L,
+ -6.351062671323970823761883833531546885452E-8L,
+ -3.390817171111032905297982523519503522491E-6L,
+ -1.082340897018886970282138836861233213972E-4L,
+ -2.020120801187226444822977006648252379508E-3L,
+ -2.093169910981725694937457070649605557555E-2L,
+ -1.092176538874275712359269481414448063393E-1L,
+ -2.374790947854765809203590474789108718733E-1L,
+ -1.365364204556573800719985118029601401323E-1L,
+};
+#define NQ8_16D 11
+static const long double Q8_16D[NQ8_16D + 1] = {
+ 1.978397614733632533581207058069628242280E-16L,
+ 1.487361156806202736877009608336766720560E-13L,
+ 4.468041406888412086042576067133365913456E-11L,
+ 7.027822074821007443672290507210594648877E-9L,
+ 6.375740580686101224127290062867976007374E-7L,
+ 3.466887658320002225888644977076410421940E-5L,
+ 1.138625640905289601186353909213719596986E-3L,
+ 2.224470799470414663443449818235008486439E-2L,
+ 2.487052928527244907490589787691478482358E-1L,
+ 1.483927406564349124649083853892380899217E0L,
+ 4.182773513276056975777258788903489507705E0L,
+ 4.419665392573449746043880892524360870944E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 1.5e-35
+ 0.125 <= 1/x <= 0.1875 */
+#define NQ5_8N 10
+static const long double Q5_8N[NQ5_8N + 1] = {
+ -3.656082407740970534915918390488336879763E-13L,
+ -1.344660308497244804752334556734121771023E-10L,
+ -1.909765035234071738548629788698150760791E-8L,
+ -1.366668038160120210269389551283666716453E-6L,
+ -5.392327355984269366895210704976314135683E-5L,
+ -1.206268245713024564674432357634540343884E-3L,
+ -1.515456784370354374066417703736088291287E-2L,
+ -1.022454301137286306933217746545237098518E-1L,
+ -3.373438906472495080504907858424251082240E-1L,
+ -4.510782522110845697262323973549178453405E-1L,
+ -1.549000892545288676809660828213589804884E-1L,
+};
+#define NQ5_8D 10
+static const long double Q5_8D[NQ5_8D + 1] = {
+ 3.565550843359501079050699598913828460036E-12L,
+ 1.321016015556560621591847454285330528045E-9L,
+ 1.897542728662346479999969679234270605975E-7L,
+ 1.381720283068706710298734234287456219474E-5L,
+ 5.599248147286524662305325795203422873725E-4L,
+ 1.305442352653121436697064782499122164843E-2L,
+ 1.750234079626943298160445750078631894985E-1L,
+ 1.311420542073436520965439883806946678491E0L,
+ 5.162757689856842406744504211089724926650E0L,
+ 9.527760296384704425618556332087850581308E0L,
+ 6.604648207463236667912921642545100248584E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 1.3e-35
+ 0.1875 <= 1/x <= 0.25 */
+#define NQ4_5N 10
+static const long double Q4_5N[NQ4_5N + 1] = {
+ -4.079513568708891749424783046520200903755E-11L,
+ -9.326548104106791766891812583019664893311E-9L,
+ -8.016795121318423066292906123815687003356E-7L,
+ -3.372350544043594415609295225664186750995E-5L,
+ -7.566238665947967882207277686375417983917E-4L,
+ -9.248861580055565402130441618521591282617E-3L,
+ -6.033106131055851432267702948850231270338E-2L,
+ -1.966908754799996793730369265431584303447E-1L,
+ -2.791062741179964150755788226623462207560E-1L,
+ -1.255478605849190549914610121863534191666E-1L,
+ -4.320429862021265463213168186061696944062E-3L,
+};
+#define NQ4_5D 9
+static const long double Q4_5D[NQ4_5D + 1] = {
+ 3.978497042580921479003851216297330701056E-10L,
+ 9.203304163828145809278568906420772246666E-8L,
+ 8.059685467088175644915010485174545743798E-6L,
+ 3.490187375993956409171098277561669167446E-4L,
+ 8.189109654456872150100501732073810028829E-3L,
+ 1.072572867311023640958725265762483033769E-1L,
+ 7.790606862409960053675717185714576937994E-1L,
+ 3.016049768232011196434185423512777656328E0L,
+ 5.722963851442769787733717162314477949360E0L,
+ 4.510527838428473279647251350931380867663E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 2.1e-35
+ 0.25 <= 1/x <= 0.3125 */
+#define NQ3r2_4N 9
+static const long double Q3r2_4N[NQ3r2_4N + 1] = {
+ -1.087480809271383885936921889040388133627E-8L,
+ -1.690067828697463740906962973479310170932E-6L,
+ -9.608064416995105532790745641974762550982E-5L,
+ -2.594198839156517191858208513873961837410E-3L,
+ -3.610954144421543968160459863048062977822E-2L,
+ -2.629866798251843212210482269563961685666E-1L,
+ -9.709186825881775885917984975685752956660E-1L,
+ -1.667521829918185121727268867619982417317E0L,
+ -1.109255082925540057138766105229900943501E0L,
+ -1.812932453006641348145049323713469043328E-1L,
+};
+#define NQ3r2_4D 9
+static const long double Q3r2_4D[NQ3r2_4D + 1] = {
+ 1.060552717496912381388763753841473407026E-7L,
+ 1.676928002024920520786883649102388708024E-5L,
+ 9.803481712245420839301400601140812255737E-4L,
+ 2.765559874262309494758505158089249012930E-2L,
+ 4.117921827792571791298862613287549140706E-1L,
+ 3.323769515244751267093378361930279161413E0L,
+ 1.436602494405814164724810151689705353670E1L,
+ 3.163087869617098638064881410646782408297E1L,
+ 3.198181264977021649489103980298349589419E1L,
+ 1.203649258862068431199471076202897823272E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 1.6e-36
+ 0.3125 <= 1/x <= 0.375 */
+#define NQ2r7_3r2N 9
+static const long double Q2r7_3r2N[NQ2r7_3r2N + 1] = {
+ -1.723405393982209853244278760171643219530E-7L,
+ -2.090508758514655456365709712333460087442E-5L,
+ -9.140104013370974823232873472192719263019E-4L,
+ -1.871349499990714843332742160292474780128E-2L,
+ -1.948930738119938669637865956162512983416E-1L,
+ -1.048764684978978127908439526343174139788E0L,
+ -2.827714929925679500237476105843643064698E0L,
+ -3.508761569156476114276988181329773987314E0L,
+ -1.669332202790211090973255098624488308989E0L,
+ -1.930796319299022954013840684651016077770E-1L,
+};
+#define NQ2r7_3r2D 9
+static const long double Q2r7_3r2D[NQ2r7_3r2D + 1] = {
+ 1.680730662300831976234547482334347983474E-6L,
+ 2.084241442440551016475972218719621841120E-4L,
+ 9.445316642108367479043541702688736295579E-3L,
+ 2.044637889456631896650179477133252184672E-1L,
+ 2.316091982244297350829522534435350078205E0L,
+ 1.412031891783015085196708811890448488865E1L,
+ 4.583830154673223384837091077279595496149E1L,
+ 7.549520609270909439885998474045974122261E1L,
+ 5.697605832808113367197494052388203310638E1L,
+ 1.601496240876192444526383314589371686234E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 9.5e-36
+ 0.375 <= 1/x <= 0.4375 */
+#define NQ2r3_2r7N 9
+static const long double Q2r3_2r7N[NQ2r3_2r7N + 1] = {
+ -8.603042076329122085722385914954878953775E-7L,
+ -7.701746260451647874214968882605186675720E-5L,
+ -2.407932004380727587382493696877569654271E-3L,
+ -3.403434217607634279028110636919987224188E-2L,
+ -2.348707332185238159192422084985713102877E-1L,
+ -7.957498841538254916147095255700637463207E-1L,
+ -1.258469078442635106431098063707934348577E0L,
+ -8.162415474676345812459353639449971369890E-1L,
+ -1.581783890269379690141513949609572806898E-1L,
+ -1.890595651683552228232308756569450822905E-3L,
+};
+#define NQ2r3_2r7D 8
+static const long double Q2r3_2r7D[NQ2r3_2r7D + 1] = {
+ 8.390017524798316921170710533381568175665E-6L,
+ 7.738148683730826286477254659973968763659E-4L,
+ 2.541480810958665794368759558791634341779E-2L,
+ 3.878879789711276799058486068562386244873E-1L,
+ 3.003783779325811292142957336802456109333E0L,
+ 1.206480374773322029883039064575464497400E1L,
+ 2.458414064785315978408974662900438351782E1L,
+ 2.367237826273668567199042088835448715228E1L,
+ 9.231451197519171090875569102116321676763E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = 1/x (.375 + 1/x^2 R(1/x^2)),
+ Peak relative error 1.4e-36
+ 0.4375 <= 1/x <= 0.5 */
+#define NQ2_2r3N 9
+static const long double Q2_2r3N[NQ2_2r3N + 1] = {
+ -5.552507516089087822166822364590806076174E-6L,
+ -4.135067659799500521040944087433752970297E-4L,
+ -1.059928728869218962607068840646564457980E-2L,
+ -1.212070036005832342565792241385459023801E-1L,
+ -6.688350110633603958684302153362735625156E-1L,
+ -1.793587878197360221340277951304429821582E0L,
+ -2.225407682237197485644647380483725045326E0L,
+ -1.123402135458940189438898496348239744403E0L,
+ -1.679187241566347077204805190763597299805E-1L,
+ -1.458550613639093752909985189067233504148E-3L,
+};
+#define NQ2_2r3D 8
+static const long double Q2_2r3D[NQ2_2r3D + 1] = {
+ 5.415024336507980465169023996403597916115E-5L,
+ 4.179246497380453022046357404266022870788E-3L,
+ 1.136306384261959483095442402929502368598E-1L,
+ 1.422640343719842213484515445393284072830E0L,
+ 8.968786703393158374728850922289204805764E0L,
+ 2.914542473339246127533384118781216495934E1L,
+ 4.781605421020380669870197378210457054685E1L,
+ 3.693865837171883152382820584714795072937E1L,
+ 1.153220502744204904763115556224395893076E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+neval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+deval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Bessel function of the first kind, order one. */
+
+long double
+__ieee754_j1l (long double x)
+{
+ long double xx, xinv, z, p, q, c, s, cc, ss;
+
+ if (! finitel (x))
+ {
+ if (x != x)
+ return x;
+ else
+ return 0.0L;
+ }
+ if (x == 0.0L)
+ return x;
+ xx = fabsl (x);
+ if (xx <= 2.0L)
+ {
+ /* 0 <= x <= 2 */
+ z = xx * xx;
+ p = xx * z * neval (z, J0_2N, NJ0_2N) / deval (z, J0_2D, NJ0_2D);
+ p += 0.5L * xx;
+ if (x < 0)
+ p = -p;
+ return p;
+ }
+
+ xinv = 1.0L / xx;
+ z = xinv * xinv;
+ if (xinv <= 0.25)
+ {
+ if (xinv <= 0.125)
+ {
+ if (xinv <= 0.0625)
+ {
+ p = neval (z, P16_IN, NP16_IN) / deval (z, P16_ID, NP16_ID);
+ q = neval (z, Q16_IN, NQ16_IN) / deval (z, Q16_ID, NQ16_ID);
+ }
+ else
+ {
+ p = neval (z, P8_16N, NP8_16N) / deval (z, P8_16D, NP8_16D);
+ q = neval (z, Q8_16N, NQ8_16N) / deval (z, Q8_16D, NQ8_16D);
+ }
+ }
+ else if (xinv <= 0.1875)
+ {
+ p = neval (z, P5_8N, NP5_8N) / deval (z, P5_8D, NP5_8D);
+ q = neval (z, Q5_8N, NQ5_8N) / deval (z, Q5_8D, NQ5_8D);
+ }
+ else
+ {
+ p = neval (z, P4_5N, NP4_5N) / deval (z, P4_5D, NP4_5D);
+ q = neval (z, Q4_5N, NQ4_5N) / deval (z, Q4_5D, NQ4_5D);
+ }
+ } /* .25 */
+ else /* if (xinv <= 0.5) */
+ {
+ if (xinv <= 0.375)
+ {
+ if (xinv <= 0.3125)
+ {
+ p = neval (z, P3r2_4N, NP3r2_4N) / deval (z, P3r2_4D, NP3r2_4D);
+ q = neval (z, Q3r2_4N, NQ3r2_4N) / deval (z, Q3r2_4D, NQ3r2_4D);
+ }
+ else
+ {
+ p = neval (z, P2r7_3r2N, NP2r7_3r2N)
+ / deval (z, P2r7_3r2D, NP2r7_3r2D);
+ q = neval (z, Q2r7_3r2N, NQ2r7_3r2N)
+ / deval (z, Q2r7_3r2D, NQ2r7_3r2D);
+ }
+ }
+ else if (xinv <= 0.4375)
+ {
+ p = neval (z, P2r3_2r7N, NP2r3_2r7N)
+ / deval (z, P2r3_2r7D, NP2r3_2r7D);
+ q = neval (z, Q2r3_2r7N, NQ2r3_2r7N)
+ / deval (z, Q2r3_2r7D, NQ2r3_2r7D);
+ }
+ else
+ {
+ p = neval (z, P2_2r3N, NP2_2r3N) / deval (z, P2_2r3D, NP2_2r3D);
+ q = neval (z, Q2_2r3N, NQ2_2r3N) / deval (z, Q2_2r3D, NQ2_2r3D);
+ }
+ }
+ p = 1.0L + z * p;
+ q = z * q;
+ q = q * xinv + 0.375L * xinv;
+ /* X = x - 3 pi/4
+ cos(X) = cos(x) cos(3 pi/4) + sin(x) sin(3 pi/4)
+ = 1/sqrt(2) * (-cos(x) + sin(x))
+ sin(X) = sin(x) cos(3 pi/4) - cos(x) sin(3 pi/4)
+ = -1/sqrt(2) * (sin(x) + cos(x))
+ cf. Fdlibm. */
+ c = cosl (xx);
+ s = sinl (xx);
+ ss = -s - c;
+ cc = s - c;
+ z = cosl (xx + xx);
+ if ((s * c) > 0)
+ cc = z / ss;
+ else
+ ss = z / cc;
+ z = ONEOSQPI * (p * cc - q * ss) / sqrtl (xx);
+ if (x < 0)
+ z = -z;
+ return z;
+}
+
+
+/* Y1(x) = 2/pi * (log(x) * J1(x) - 1/x) + x R(x^2)
+ Peak relative error 6.2e-38
+ 0 <= x <= 2 */
+#define NY0_2N 7
+static long double Y0_2N[NY0_2N + 1] = {
+ -6.804415404830253804408698161694720833249E19L,
+ 1.805450517967019908027153056150465849237E19L,
+ -8.065747497063694098810419456383006737312E17L,
+ 1.401336667383028259295830955439028236299E16L,
+ -1.171654432898137585000399489686629680230E14L,
+ 5.061267920943853732895341125243428129150E11L,
+ -1.096677850566094204586208610960870217970E9L,
+ 9.541172044989995856117187515882879304461E5L,
+};
+#define NY0_2D 7
+static long double Y0_2D[NY0_2D + 1] = {
+ 3.470629591820267059538637461549677594549E20L,
+ 4.120796439009916326855848107545425217219E18L,
+ 2.477653371652018249749350657387030814542E16L,
+ 9.954678543353888958177169349272167762797E13L,
+ 2.957927997613630118216218290262851197754E11L,
+ 6.748421382188864486018861197614025972118E8L,
+ 1.173453425218010888004562071020305709319E6L,
+ 1.450335662961034949894009554536003377187E3L,
+ /* 1.000000000000000000000000000000000000000E0 */
+};
+
+
+/* Bessel function of the second kind, order one. */
+
+long double
+__ieee754_y1l (long double x)
+{
+ long double xx, xinv, z, p, q, c, s, cc, ss;
+
+ if (! finitel (x))
+ {
+ if (x != x)
+ return x;
+ else
+ return 0.0L;
+ }
+ if (x <= 0.0L)
+ {
+ if (x < 0.0L)
+ return (zero / (zero * x));
+ return -HUGE_VALL + x;
+ }
+ xx = fabsl (x);
+ if (xx <= 2.0L)
+ {
+ /* 0 <= x <= 2 */
+ z = xx * xx;
+ p = xx * neval (z, Y0_2N, NY0_2N) / deval (z, Y0_2D, NY0_2D);
+ p = -TWOOPI / xx + p;
+ p = TWOOPI * logl(x) * __ieee754_j1l (x) + p;
+ return p;
+ }
+
+ xinv = 1.0L / xx;
+ z = xinv * xinv;
+ if (xinv <= 0.25)
+ {
+ if (xinv <= 0.125)
+ {
+ if (xinv <= 0.0625)
+ {
+ p = neval (z, P16_IN, NP16_IN) / deval (z, P16_ID, NP16_ID);
+ q = neval (z, Q16_IN, NQ16_IN) / deval (z, Q16_ID, NQ16_ID);
+ }
+ else
+ {
+ p = neval (z, P8_16N, NP8_16N) / deval (z, P8_16D, NP8_16D);
+ q = neval (z, Q8_16N, NQ8_16N) / deval (z, Q8_16D, NQ8_16D);
+ }
+ }
+ else if (xinv <= 0.1875)
+ {
+ p = neval (z, P5_8N, NP5_8N) / deval (z, P5_8D, NP5_8D);
+ q = neval (z, Q5_8N, NQ5_8N) / deval (z, Q5_8D, NQ5_8D);
+ }
+ else
+ {
+ p = neval (z, P4_5N, NP4_5N) / deval (z, P4_5D, NP4_5D);
+ q = neval (z, Q4_5N, NQ4_5N) / deval (z, Q4_5D, NQ4_5D);
+ }
+ } /* .25 */
+ else /* if (xinv <= 0.5) */
+ {
+ if (xinv <= 0.375)
+ {
+ if (xinv <= 0.3125)
+ {
+ p = neval (z, P3r2_4N, NP3r2_4N) / deval (z, P3r2_4D, NP3r2_4D);
+ q = neval (z, Q3r2_4N, NQ3r2_4N) / deval (z, Q3r2_4D, NQ3r2_4D);
+ }
+ else
+ {
+ p = neval (z, P2r7_3r2N, NP2r7_3r2N)
+ / deval (z, P2r7_3r2D, NP2r7_3r2D);
+ q = neval (z, Q2r7_3r2N, NQ2r7_3r2N)
+ / deval (z, Q2r7_3r2D, NQ2r7_3r2D);
+ }
+ }
+ else if (xinv <= 0.4375)
+ {
+ p = neval (z, P2r3_2r7N, NP2r3_2r7N)
+ / deval (z, P2r3_2r7D, NP2r3_2r7D);
+ q = neval (z, Q2r3_2r7N, NQ2r3_2r7N)
+ / deval (z, Q2r3_2r7D, NQ2r3_2r7D);
+ }
+ else
+ {
+ p = neval (z, P2_2r3N, NP2_2r3N) / deval (z, P2_2r3D, NP2_2r3D);
+ q = neval (z, Q2_2r3N, NQ2_2r3N) / deval (z, Q2_2r3D, NQ2_2r3D);
+ }
+ }
+ p = 1.0L + z * p;
+ q = z * q;
+ q = q * xinv + 0.375L * xinv;
+ /* X = x - 3 pi/4
+ cos(X) = cos(x) cos(3 pi/4) + sin(x) sin(3 pi/4)
+ = 1/sqrt(2) * (-cos(x) + sin(x))
+ sin(X) = sin(x) cos(3 pi/4) - cos(x) sin(3 pi/4)
+ = -1/sqrt(2) * (sin(x) + cos(x))
+ cf. Fdlibm. */
+ c = cosl (xx);
+ s = sinl (xx);
+ ss = -s - c;
+ cc = s - c;
+ z = cosl (xx + xx);
+ if ((s * c) > 0)
+ cc = z / ss;
+ else
+ ss = z / cc;
+ z = ONEOSQPI * (p * ss + q * cc) / sqrtl (xx);
+ return z;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_jnl.c b/libc/sysdeps/ieee754/ldbl-128/e_jnl.c
new file mode 100644
index 000000000..a4a4e24cf
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_jnl.c
@@ -0,0 +1,400 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* Modifications for 128-bit long double are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ * __ieee754_jn(n, x), __ieee754_yn(n, 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"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ invsqrtpi = 5.6418958354775628694807945156077258584405E-1L,
+ two = 2.0e0L,
+ one = 1.0e0L,
+ zero = 0.0L;
+
+
+#ifdef __STDC__
+long double
+__ieee754_jnl (int n, long double x)
+#else
+long double
+__ieee754_jnl (n, x)
+ int n;
+ long double x;
+#endif
+{
+ u_int32_t se;
+ int32_t i, ix, sgn;
+ long double a, b, temp, di;
+ long double z, w;
+ ieee854_long_double_shape_type u;
+
+
+ /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
+ * Thus, J(-n,x) = J(n,-x)
+ */
+
+ u.value = x;
+ se = u.parts32.w0;
+ ix = se & 0x7fffffff;
+
+ /* if J(n,NaN) is NaN */
+ if (ix >= 0x7fff0000)
+ {
+ if ((u.parts32.w0 & 0xffff) | u.parts32.w1 | u.parts32.w2 | u.parts32.w3)
+ return x + x;
+ }
+
+ if (n < 0)
+ {
+ n = -n;
+ x = -x;
+ se ^= 0x80000000;
+ }
+ if (n == 0)
+ return (__ieee754_j0l (x));
+ if (n == 1)
+ return (__ieee754_j1l (x));
+ sgn = (n & 1) & (se >> 31); /* even n -- 0, odd n -- sign(x) */
+ x = fabsl (x);
+
+ if (x == 0.0L || ix >= 0x7fff0000) /* if x is 0 or inf */
+ b = zero;
+ else if ((long double) n <= x)
+ {
+ /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
+ if (ix >= 0x412D0000)
+ { /* x > 2**302 */
+
+ /* ??? Could use an expansion for large x here. */
+
+ /* (x >> n**2)
+ * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Let s=sin(x), c=cos(x),
+ * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+ *
+ * n sin(xn)*sqt2 cos(xn)*sqt2
+ * ----------------------------------
+ * 0 s-c c+s
+ * 1 -s-c -c+s
+ * 2 -s+c -c-s
+ * 3 s+c c-s
+ */
+ long double s;
+ long double c;
+ __sincosl (x, &s, &c);
+ switch (n & 3)
+ {
+ case 0:
+ temp = c + s;
+ break;
+ case 1:
+ temp = -c + s;
+ break;
+ case 2:
+ temp = -c - s;
+ break;
+ case 3:
+ temp = c - s;
+ break;
+ }
+ b = invsqrtpi * temp / __ieee754_sqrtl (x);
+ }
+ else
+ {
+ a = __ieee754_j0l (x);
+ b = __ieee754_j1l (x);
+ for (i = 1; i < n; i++)
+ {
+ temp = b;
+ b = b * ((long double) (i + i) / x) - a; /* avoid underflow */
+ a = temp;
+ }
+ }
+ }
+ else
+ {
+ if (ix < 0x3fc60000)
+ { /* x < 2**-57 */
+ /* x is tiny, return the first Taylor expansion of J(n,x)
+ * J(n,x) = 1/n!*(x/2)^n - ...
+ */
+ if (n >= 400) /* underflow, result < 10^-4952 */
+ b = zero;
+ else
+ {
+ temp = x * 0.5;
+ b = temp;
+ for (a = one, i = 2; i <= n; i++)
+ {
+ a *= (long double) i; /* a = n! */
+ b *= temp; /* b = (x/2)^n */
+ }
+ b = b / a;
+ }
+ }
+ else
+ {
+ /* use backward recurrence */
+ /* x x^2 x^2
+ * J(n,x)/J(n-1,x) = ---- ------ ------ .....
+ * 2n - 2(n+1) - 2(n+2)
+ *
+ * 1 1 1
+ * (for large x) = ---- ------ ------ .....
+ * 2n 2(n+1) 2(n+2)
+ * -- - ------ - ------ -
+ * x x x
+ *
+ * Let w = 2n/x and h=2/x, then the above quotient
+ * is equal to the continued fraction:
+ * 1
+ * = -----------------------
+ * 1
+ * w - -----------------
+ * 1
+ * w+h - ---------
+ * w+2h - ...
+ *
+ * To determine how many terms needed, let
+ * Q(0) = w, Q(1) = w(w+h) - 1,
+ * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
+ * When Q(k) > 1e4 good for single
+ * When Q(k) > 1e9 good for double
+ * When Q(k) > 1e17 good for quadruple
+ */
+ /* determine k */
+ long double t, v;
+ long double q0, q1, h, tmp;
+ int32_t k, m;
+ w = (n + n) / (long double) x;
+ h = 2.0L / (long double) x;
+ q0 = w;
+ z = w + h;
+ q1 = w * z - 1.0L;
+ k = 1;
+ while (q1 < 1.0e17L)
+ {
+ k += 1;
+ z += h;
+ tmp = z * q1 - q0;
+ q0 = q1;
+ q1 = tmp;
+ }
+ m = n + n;
+ for (t = zero, i = 2 * (n + k); i >= m; i -= 2)
+ t = one / (i / x - t);
+ a = t;
+ b = one;
+ /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
+ * Hence, if n*(log(2n/x)) > ...
+ * single 8.8722839355e+01
+ * double 7.09782712893383973096e+02
+ * long double 1.1356523406294143949491931077970765006170e+04
+ * then recurrent value may overflow and the result is
+ * likely underflow to zero
+ */
+ tmp = n;
+ v = two / x;
+ tmp = tmp * __ieee754_logl (fabsl (v * tmp));
+
+ if (tmp < 1.1356523406294143949491931077970765006170e+04L)
+ {
+ for (i = n - 1, di = (long double) (i + i); i > 0; i--)
+ {
+ temp = b;
+ b *= di;
+ b = b / x - a;
+ a = temp;
+ di -= two;
+ }
+ }
+ else
+ {
+ for (i = n - 1, di = (long double) (i + i); i > 0; i--)
+ {
+ temp = b;
+ b *= di;
+ b = b / x - a;
+ a = temp;
+ di -= two;
+ /* scale b to avoid spurious overflow */
+ if (b > 1e100L)
+ {
+ a /= b;
+ t /= b;
+ b = one;
+ }
+ }
+ }
+ b = (t * __ieee754_j0l (x) / b);
+ }
+ }
+ if (sgn == 1)
+ return -b;
+ else
+ return b;
+}
+
+#ifdef __STDC__
+long double
+__ieee754_ynl (int n, long double x)
+#else
+long double
+__ieee754_ynl (n, x)
+ int n;
+ long double x;
+#endif
+{
+ u_int32_t se;
+ int32_t i, ix;
+ int32_t sign;
+ long double a, b, temp;
+ ieee854_long_double_shape_type u;
+
+ u.value = x;
+ se = u.parts32.w0;
+ ix = se & 0x7fffffff;
+
+ /* if Y(n,NaN) is NaN */
+ if (ix >= 0x7fff0000)
+ {
+ if ((u.parts32.w0 & 0xffff) | u.parts32.w1 | u.parts32.w2 | u.parts32.w3)
+ return x + x;
+ }
+ if (x <= 0.0L)
+ {
+ if (x == 0.0L)
+ return -HUGE_VALL + x;
+ if (se & 0x80000000)
+ return zero / (zero * x);
+ }
+ sign = 1;
+ if (n < 0)
+ {
+ n = -n;
+ sign = 1 - ((n & 1) << 1);
+ }
+ if (n == 0)
+ return (__ieee754_y0l (x));
+ if (n == 1)
+ return (sign * __ieee754_y1l (x));
+ if (ix >= 0x7fff0000)
+ return zero;
+ if (ix >= 0x412D0000)
+ { /* x > 2**302 */
+
+ /* ??? See comment above on the possible futility of this. */
+
+ /* (x >> n**2)
+ * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Let s=sin(x), c=cos(x),
+ * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+ *
+ * n sin(xn)*sqt2 cos(xn)*sqt2
+ * ----------------------------------
+ * 0 s-c c+s
+ * 1 -s-c -c+s
+ * 2 -s+c -c-s
+ * 3 s+c c-s
+ */
+ long double s;
+ long double c;
+ __sincosl (x, &s, &c);
+ switch (n & 3)
+ {
+ case 0:
+ temp = s - c;
+ break;
+ case 1:
+ temp = -s - c;
+ break;
+ case 2:
+ temp = -s + c;
+ break;
+ case 3:
+ temp = s + c;
+ break;
+ }
+ b = invsqrtpi * temp / __ieee754_sqrtl (x);
+ }
+ else
+ {
+ a = __ieee754_y0l (x);
+ b = __ieee754_y1l (x);
+ /* quit if b is -inf */
+ u.value = b;
+ se = u.parts32.w0 & 0xffff0000;
+ for (i = 1; i < n && se != 0xffff0000; i++)
+ {
+ temp = b;
+ b = ((long double) (i + i) / x) * b - a;
+ u.value = b;
+ se = u.parts32.w0 & 0xffff0000;
+ a = temp;
+ }
+ }
+ if (sign > 0)
+ return b;
+ else
+ return -b;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_lgammal_r.c b/libc/sysdeps/ieee754/ldbl-128/e_lgammal_r.c
new file mode 100644
index 000000000..b9302974c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_lgammal_r.c
@@ -0,0 +1,1036 @@
+/* lgammal
+ *
+ * Natural logarithm of gamma function
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, lgammal();
+ * extern int sgngam;
+ *
+ * y = lgammal(x);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base e (2.718...) logarithm of the absolute
+ * value of the gamma function of the argument.
+ * The sign (+1 or -1) of the gamma function is returned in a
+ * global (extern) variable named sgngam.
+ *
+ * The positive domain is partitioned into numerous segments for approximation.
+ * For x > 10,
+ * log gamma(x) = (x - 0.5) log(x) - x + log sqrt(2 pi) + 1/x R(1/x^2)
+ * Near the minimum at x = x0 = 1.46... the approximation is
+ * log gamma(x0 + z) = log gamma(x0) + z^2 P(z)/Q(z)
+ * for small z.
+ * Elsewhere between 0 and 10,
+ * log gamma(n + z) = log gamma(n) + z P(z)/Q(z)
+ * for various selected n and small z.
+ *
+ * The cosecant reflection formula is employed for negative arguments.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ *
+ * arithmetic domain # trials peak rms
+ * Relative error:
+ * IEEE 10, 30 100000 3.9e-34 9.8e-35
+ * IEEE 0, 10 100000 3.8e-34 5.3e-35
+ * Absolute error:
+ * IEEE -10, 0 100000 8.0e-34 8.0e-35
+ * IEEE -30, -10 100000 4.4e-34 1.0e-34
+ * IEEE -100, 100 100000 1.0e-34
+ *
+ * The absolute error criterion is the same as relative error
+ * when the function magnitude is greater than one but it is absolute
+ * when the magnitude is less than one.
+ *
+ */
+
+/* Copyright 2001 by Stephen L. Moshier <moshier@na-net.ornl.gov>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "math.h"
+#include "math_private.h"
+
+static const long double PIL = 3.1415926535897932384626433832795028841972E0L;
+static const long double MAXLGM = 1.0485738685148938358098967157129705071571E4928L;
+static const long double one = 1.0L;
+static const long double zero = 0.0L;
+static const long double huge = 1.0e4000L;
+
+/* log gamma(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x P(1/x^2)
+ 1/x <= 0.0741 (x >= 13.495...)
+ Peak relative error 1.5e-36 */
+static const long double ls2pi = 9.1893853320467274178032973640561763986140E-1L;
+#define NRASY 12
+static const long double RASY[NRASY + 1] =
+{
+ 8.333333333333333333333333333310437112111E-2L,
+ -2.777777777777777777777774789556228296902E-3L,
+ 7.936507936507936507795933938448586499183E-4L,
+ -5.952380952380952041799269756378148574045E-4L,
+ 8.417508417507928904209891117498524452523E-4L,
+ -1.917526917481263997778542329739806086290E-3L,
+ 6.410256381217852504446848671499409919280E-3L,
+ -2.955064066900961649768101034477363301626E-2L,
+ 1.796402955865634243663453415388336954675E-1L,
+ -1.391522089007758553455753477688592767741E0L,
+ 1.326130089598399157988112385013829305510E1L,
+ -1.420412699593782497803472576479997819149E2L,
+ 1.218058922427762808938869872528846787020E3L
+};
+
+
+/* log gamma(x+13) = log gamma(13) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 12.5 <= x+13 <= 13.5
+ Peak relative error 1.1e-36 */
+static const long double lgam13a = 1.9987213134765625E1L;
+static const long double lgam13b = 1.3608962611495173623870550785125024484248E-6L;
+#define NRN13 7
+static const long double RN13[NRN13 + 1] =
+{
+ 8.591478354823578150238226576156275285700E11L,
+ 2.347931159756482741018258864137297157668E11L,
+ 2.555408396679352028680662433943000804616E10L,
+ 1.408581709264464345480765758902967123937E9L,
+ 4.126759849752613822953004114044451046321E7L,
+ 6.133298899622688505854211579222889943778E5L,
+ 3.929248056293651597987893340755876578072E3L,
+ 6.850783280018706668924952057996075215223E0L
+};
+#define NRD13 6
+static const long double RD13[NRD13 + 1] =
+{
+ 3.401225382297342302296607039352935541669E11L,
+ 8.756765276918037910363513243563234551784E10L,
+ 8.873913342866613213078554180987647243903E9L,
+ 4.483797255342763263361893016049310017973E8L,
+ 1.178186288833066430952276702931512870676E7L,
+ 1.519928623743264797939103740132278337476E5L,
+ 7.989298844938119228411117593338850892311E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+12) = log gamma(12) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 11.5 <= x+12 <= 12.5
+ Peak relative error 4.1e-36 */
+static const long double lgam12a = 1.75023040771484375E1L;
+static const long double lgam12b = 3.7687254483392876529072161996717039575982E-6L;
+#define NRN12 7
+static const long double RN12[NRN12 + 1] =
+{
+ 4.709859662695606986110997348630997559137E11L,
+ 1.398713878079497115037857470168777995230E11L,
+ 1.654654931821564315970930093932954900867E10L,
+ 9.916279414876676861193649489207282144036E8L,
+ 3.159604070526036074112008954113411389879E7L,
+ 5.109099197547205212294747623977502492861E5L,
+ 3.563054878276102790183396740969279826988E3L,
+ 6.769610657004672719224614163196946862747E0L
+};
+#define NRD12 6
+static const long double RD12[NRD12 + 1] =
+{
+ 1.928167007860968063912467318985802726613E11L,
+ 5.383198282277806237247492369072266389233E10L,
+ 5.915693215338294477444809323037871058363E9L,
+ 3.241438287570196713148310560147925781342E8L,
+ 9.236680081763754597872713592701048455890E6L,
+ 1.292246897881650919242713651166596478850E5L,
+ 7.366532445427159272584194816076600211171E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+11) = log gamma(11) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 10.5 <= x+11 <= 11.5
+ Peak relative error 1.8e-35 */
+static const long double lgam11a = 1.5104400634765625E1L;
+static const long double lgam11b = 1.1938309890295225709329251070371882250744E-5L;
+#define NRN11 7
+static const long double RN11[NRN11 + 1] =
+{
+ 2.446960438029415837384622675816736622795E11L,
+ 7.955444974446413315803799763901729640350E10L,
+ 1.030555327949159293591618473447420338444E10L,
+ 6.765022131195302709153994345470493334946E8L,
+ 2.361892792609204855279723576041468347494E7L,
+ 4.186623629779479136428005806072176490125E5L,
+ 3.202506022088912768601325534149383594049E3L,
+ 6.681356101133728289358838690666225691363E0L
+};
+#define NRD11 6
+static const long double RD11[NRD11 + 1] =
+{
+ 1.040483786179428590683912396379079477432E11L,
+ 3.172251138489229497223696648369823779729E10L,
+ 3.806961885984850433709295832245848084614E9L,
+ 2.278070344022934913730015420611609620171E8L,
+ 7.089478198662651683977290023829391596481E6L,
+ 1.083246385105903533237139380509590158658E5L,
+ 6.744420991491385145885727942219463243597E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+10) = log gamma(10) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 9.5 <= x+10 <= 10.5
+ Peak relative error 5.4e-37 */
+static const long double lgam10a = 1.280181884765625E1L;
+static const long double lgam10b = 8.6324252196112077178745667061642811492557E-6L;
+#define NRN10 7
+static const long double RN10[NRN10 + 1] =
+{
+ -1.239059737177249934158597996648808363783E14L,
+ -4.725899566371458992365624673357356908719E13L,
+ -7.283906268647083312042059082837754850808E12L,
+ -5.802855515464011422171165179767478794637E11L,
+ -2.532349691157548788382820303182745897298E10L,
+ -5.884260178023777312587193693477072061820E8L,
+ -6.437774864512125749845840472131829114906E6L,
+ -2.350975266781548931856017239843273049384E4L
+};
+#define NRD10 7
+static const long double RD10[NRD10 + 1] =
+{
+ -5.502645997581822567468347817182347679552E13L,
+ -1.970266640239849804162284805400136473801E13L,
+ -2.819677689615038489384974042561531409392E12L,
+ -2.056105863694742752589691183194061265094E11L,
+ -8.053670086493258693186307810815819662078E9L,
+ -1.632090155573373286153427982504851867131E8L,
+ -1.483575879240631280658077826889223634921E6L,
+ -4.002806669713232271615885826373550502510E3L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+9) = log gamma(9) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 8.5 <= x+9 <= 9.5
+ Peak relative error 3.6e-36 */
+static const long double lgam9a = 1.06045989990234375E1L;
+static const long double lgam9b = 3.9037218127284172274007216547549861681400E-6L;
+#define NRN9 7
+static const long double RN9[NRN9 + 1] =
+{
+ -4.936332264202687973364500998984608306189E13L,
+ -2.101372682623700967335206138517766274855E13L,
+ -3.615893404644823888655732817505129444195E12L,
+ -3.217104993800878891194322691860075472926E11L,
+ -1.568465330337375725685439173603032921399E10L,
+ -4.073317518162025744377629219101510217761E8L,
+ -4.983232096406156139324846656819246974500E6L,
+ -2.036280038903695980912289722995505277253E4L
+};
+#define NRD9 7
+static const long double RD9[NRD9 + 1] =
+{
+ -2.306006080437656357167128541231915480393E13L,
+ -9.183606842453274924895648863832233799950E12L,
+ -1.461857965935942962087907301194381010380E12L,
+ -1.185728254682789754150068652663124298303E11L,
+ -5.166285094703468567389566085480783070037E9L,
+ -1.164573656694603024184768200787835094317E8L,
+ -1.177343939483908678474886454113163527909E6L,
+ -3.529391059783109732159524500029157638736E3L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+8) = log gamma(8) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 7.5 <= x+8 <= 8.5
+ Peak relative error 2.4e-37 */
+static const long double lgam8a = 8.525146484375E0L;
+static const long double lgam8b = 1.4876690414300165531036347125050759667737E-5L;
+#define NRN8 8
+static const long double RN8[NRN8 + 1] =
+{
+ 6.600775438203423546565361176829139703289E11L,
+ 3.406361267593790705240802723914281025800E11L,
+ 7.222460928505293914746983300555538432830E10L,
+ 8.102984106025088123058747466840656458342E9L,
+ 5.157620015986282905232150979772409345927E8L,
+ 1.851445288272645829028129389609068641517E7L,
+ 3.489261702223124354745894067468953756656E5L,
+ 2.892095396706665774434217489775617756014E3L,
+ 6.596977510622195827183948478627058738034E0L
+};
+#define NRD8 7
+static const long double RD8[NRD8 + 1] =
+{
+ 3.274776546520735414638114828622673016920E11L,
+ 1.581811207929065544043963828487733970107E11L,
+ 3.108725655667825188135393076860104546416E10L,
+ 3.193055010502912617128480163681842165730E9L,
+ 1.830871482669835106357529710116211541839E8L,
+ 5.790862854275238129848491555068073485086E6L,
+ 9.305213264307921522842678835618803553589E4L,
+ 6.216974105861848386918949336819572333622E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+7) = log gamma(7) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 6.5 <= x+7 <= 7.5
+ Peak relative error 3.2e-36 */
+static const long double lgam7a = 6.5792388916015625E0L;
+static const long double lgam7b = 1.2320408538495060178292903945321122583007E-5L;
+#define NRN7 8
+static const long double RN7[NRN7 + 1] =
+{
+ 2.065019306969459407636744543358209942213E11L,
+ 1.226919919023736909889724951708796532847E11L,
+ 2.996157990374348596472241776917953749106E10L,
+ 3.873001919306801037344727168434909521030E9L,
+ 2.841575255593761593270885753992732145094E8L,
+ 1.176342515359431913664715324652399565551E7L,
+ 2.558097039684188723597519300356028511547E5L,
+ 2.448525238332609439023786244782810774702E3L,
+ 6.460280377802030953041566617300902020435E0L
+};
+#define NRD7 7
+static const long double RD7[NRD7 + 1] =
+{
+ 1.102646614598516998880874785339049304483E11L,
+ 6.099297512712715445879759589407189290040E10L,
+ 1.372898136289611312713283201112060238351E10L,
+ 1.615306270420293159907951633566635172343E9L,
+ 1.061114435798489135996614242842561967459E8L,
+ 3.845638971184305248268608902030718674691E6L,
+ 7.081730675423444975703917836972720495507E4L,
+ 5.423122582741398226693137276201344096370E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+6) = log gamma(6) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 5.5 <= x+6 <= 6.5
+ Peak relative error 6.2e-37 */
+static const long double lgam6a = 4.7874908447265625E0L;
+static const long double lgam6b = 8.9805548349424770093452324304839959231517E-7L;
+#define NRN6 8
+static const long double RN6[NRN6 + 1] =
+{
+ -3.538412754670746879119162116819571823643E13L,
+ -2.613432593406849155765698121483394257148E13L,
+ -8.020670732770461579558867891923784753062E12L,
+ -1.322227822931250045347591780332435433420E12L,
+ -1.262809382777272476572558806855377129513E11L,
+ -7.015006277027660872284922325741197022467E9L,
+ -2.149320689089020841076532186783055727299E8L,
+ -3.167210585700002703820077565539658995316E6L,
+ -1.576834867378554185210279285358586385266E4L
+};
+#define NRD6 8
+static const long double RD6[NRD6 + 1] =
+{
+ -2.073955870771283609792355579558899389085E13L,
+ -1.421592856111673959642750863283919318175E13L,
+ -4.012134994918353924219048850264207074949E12L,
+ -6.013361045800992316498238470888523722431E11L,
+ -5.145382510136622274784240527039643430628E10L,
+ -2.510575820013409711678540476918249524123E9L,
+ -6.564058379709759600836745035871373240904E7L,
+ -7.861511116647120540275354855221373571536E5L,
+ -2.821943442729620524365661338459579270561E3L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+5) = log gamma(5) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 4.5 <= x+5 <= 5.5
+ Peak relative error 3.4e-37 */
+static const long double lgam5a = 3.17803955078125E0L;
+static const long double lgam5b = 1.4279566695619646941601297055408873990961E-5L;
+#define NRN5 9
+static const long double RN5[NRN5 + 1] =
+{
+ 2.010952885441805899580403215533972172098E11L,
+ 1.916132681242540921354921906708215338584E11L,
+ 7.679102403710581712903937970163206882492E10L,
+ 1.680514903671382470108010973615268125169E10L,
+ 2.181011222911537259440775283277711588410E9L,
+ 1.705361119398837808244780667539728356096E8L,
+ 7.792391565652481864976147945997033946360E6L,
+ 1.910741381027985291688667214472560023819E5L,
+ 2.088138241893612679762260077783794329559E3L,
+ 6.330318119566998299106803922739066556550E0L
+};
+#define NRD5 8
+static const long double RD5[NRD5 + 1] =
+{
+ 1.335189758138651840605141370223112376176E11L,
+ 1.174130445739492885895466097516530211283E11L,
+ 4.308006619274572338118732154886328519910E10L,
+ 8.547402888692578655814445003283720677468E9L,
+ 9.934628078575618309542580800421370730906E8L,
+ 6.847107420092173812998096295422311820672E7L,
+ 2.698552646016599923609773122139463150403E6L,
+ 5.526516251532464176412113632726150253215E4L,
+ 4.772343321713697385780533022595450486932E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+4) = log gamma(4) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 3.5 <= x+4 <= 4.5
+ Peak relative error 6.7e-37 */
+static const long double lgam4a = 1.791748046875E0L;
+static const long double lgam4b = 1.1422353055000812477358380702272722990692E-5L;
+#define NRN4 9
+static const long double RN4[NRN4 + 1] =
+{
+ -1.026583408246155508572442242188887829208E13L,
+ -1.306476685384622809290193031208776258809E13L,
+ -7.051088602207062164232806511992978915508E12L,
+ -2.100849457735620004967624442027793656108E12L,
+ -3.767473790774546963588549871673843260569E11L,
+ -4.156387497364909963498394522336575984206E10L,
+ -2.764021460668011732047778992419118757746E9L,
+ -1.036617204107109779944986471142938641399E8L,
+ -1.895730886640349026257780896972598305443E6L,
+ -1.180509051468390914200720003907727988201E4L
+};
+#define NRD4 9
+static const long double RD4[NRD4 + 1] =
+{
+ -8.172669122056002077809119378047536240889E12L,
+ -9.477592426087986751343695251801814226960E12L,
+ -4.629448850139318158743900253637212801682E12L,
+ -1.237965465892012573255370078308035272942E12L,
+ -1.971624313506929845158062177061297598956E11L,
+ -1.905434843346570533229942397763361493610E10L,
+ -1.089409357680461419743730978512856675984E9L,
+ -3.416703082301143192939774401370222822430E7L,
+ -4.981791914177103793218433195857635265295E5L,
+ -2.192507743896742751483055798411231453733E3L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+3) = log gamma(3) + x P(x)/Q(x)
+ -0.25 <= x <= 0.5
+ 2.75 <= x+3 <= 3.5
+ Peak relative error 6.0e-37 */
+static const long double lgam3a = 6.93145751953125E-1L;
+static const long double lgam3b = 1.4286068203094172321214581765680755001344E-6L;
+
+#define NRN3 9
+static const long double RN3[NRN3 + 1] =
+{
+ -4.813901815114776281494823863935820876670E11L,
+ -8.425592975288250400493910291066881992620E11L,
+ -6.228685507402467503655405482985516909157E11L,
+ -2.531972054436786351403749276956707260499E11L,
+ -6.170200796658926701311867484296426831687E10L,
+ -9.211477458528156048231908798456365081135E9L,
+ -8.251806236175037114064561038908691305583E8L,
+ -4.147886355917831049939930101151160447495E7L,
+ -1.010851868928346082547075956946476932162E6L,
+ -8.333374463411801009783402800801201603736E3L
+};
+#define NRD3 9
+static const long double RD3[NRD3 + 1] =
+{
+ -5.216713843111675050627304523368029262450E11L,
+ -8.014292925418308759369583419234079164391E11L,
+ -5.180106858220030014546267824392678611990E11L,
+ -1.830406975497439003897734969120997840011E11L,
+ -3.845274631904879621945745960119924118925E10L,
+ -4.891033385370523863288908070309417710903E9L,
+ -3.670172254411328640353855768698287474282E8L,
+ -1.505316381525727713026364396635522516989E7L,
+ -2.856327162923716881454613540575964890347E5L,
+ -1.622140448015769906847567212766206894547E3L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+2.5) = log gamma(2.5) + x P(x)/Q(x)
+ -0.125 <= x <= 0.25
+ 2.375 <= x+2.5 <= 2.75 */
+static const long double lgam2r5a = 2.8466796875E-1L;
+static const long double lgam2r5b = 1.4901722919159632494669682701924320137696E-5L;
+#define NRN2r5 8
+static const long double RN2r5[NRN2r5 + 1] =
+{
+ -4.676454313888335499356699817678862233205E9L,
+ -9.361888347911187924389905984624216340639E9L,
+ -7.695353600835685037920815799526540237703E9L,
+ -3.364370100981509060441853085968900734521E9L,
+ -8.449902011848163568670361316804900559863E8L,
+ -1.225249050950801905108001246436783022179E8L,
+ -9.732972931077110161639900388121650470926E6L,
+ -3.695711763932153505623248207576425983573E5L,
+ -4.717341584067827676530426007495274711306E3L
+};
+#define NRD2r5 8
+static const long double RD2r5[NRD2r5 + 1] =
+{
+ -6.650657966618993679456019224416926875619E9L,
+ -1.099511409330635807899718829033488771623E10L,
+ -7.482546968307837168164311101447116903148E9L,
+ -2.702967190056506495988922973755870557217E9L,
+ -5.570008176482922704972943389590409280950E8L,
+ -6.536934032192792470926310043166993233231E7L,
+ -4.101991193844953082400035444146067511725E6L,
+ -1.174082735875715802334430481065526664020E5L,
+ -9.932840389994157592102947657277692978511E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+2) = x P(x)/Q(x)
+ -0.125 <= x <= +0.375
+ 1.875 <= x+2 <= 2.375
+ Peak relative error 4.6e-36 */
+#define NRN2 9
+static const long double RN2[NRN2 + 1] =
+{
+ -3.716661929737318153526921358113793421524E9L,
+ -1.138816715030710406922819131397532331321E10L,
+ -1.421017419363526524544402598734013569950E10L,
+ -9.510432842542519665483662502132010331451E9L,
+ -3.747528562099410197957514973274474767329E9L,
+ -8.923565763363912474488712255317033616626E8L,
+ -1.261396653700237624185350402781338231697E8L,
+ -9.918402520255661797735331317081425749014E6L,
+ -3.753996255897143855113273724233104768831E5L,
+ -4.778761333044147141559311805999540765612E3L
+};
+#define NRD2 9
+static const long double RD2[NRD2 + 1] =
+{
+ -8.790916836764308497770359421351673950111E9L,
+ -2.023108608053212516399197678553737477486E10L,
+ -1.958067901852022239294231785363504458367E10L,
+ -1.035515043621003101254252481625188704529E10L,
+ -3.253884432621336737640841276619272224476E9L,
+ -6.186383531162456814954947669274235815544E8L,
+ -6.932557847749518463038934953605969951466E7L,
+ -4.240731768287359608773351626528479703758E6L,
+ -1.197343995089189188078944689846348116630E5L,
+ -1.004622911670588064824904487064114090920E3L
+/* 1.0E0 */
+};
+
+
+/* log gamma(x+1.75) = log gamma(1.75) + x P(x)/Q(x)
+ -0.125 <= x <= +0.125
+ 1.625 <= x+1.75 <= 1.875
+ Peak relative error 9.2e-37 */
+static const long double lgam1r75a = -8.441162109375E-2L;
+static const long double lgam1r75b = 1.0500073264444042213965868602268256157604E-5L;
+#define NRN1r75 8
+static const long double RN1r75[NRN1r75 + 1] =
+{
+ -5.221061693929833937710891646275798251513E7L,
+ -2.052466337474314812817883030472496436993E8L,
+ -2.952718275974940270675670705084125640069E8L,
+ -2.132294039648116684922965964126389017840E8L,
+ -8.554103077186505960591321962207519908489E7L,
+ -1.940250901348870867323943119132071960050E7L,
+ -2.379394147112756860769336400290402208435E6L,
+ -1.384060879999526222029386539622255797389E5L,
+ -2.698453601378319296159355612094598695530E3L
+};
+#define NRD1r75 8
+static const long double RD1r75[NRD1r75 + 1] =
+{
+ -2.109754689501705828789976311354395393605E8L,
+ -5.036651829232895725959911504899241062286E8L,
+ -4.954234699418689764943486770327295098084E8L,
+ -2.589558042412676610775157783898195339410E8L,
+ -7.731476117252958268044969614034776883031E7L,
+ -1.316721702252481296030801191240867486965E7L,
+ -1.201296501404876774861190604303728810836E6L,
+ -5.007966406976106636109459072523610273928E4L,
+ -6.155817990560743422008969155276229018209E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+x0) = y0 + x^2 P(x)/Q(x)
+ -0.0867 <= x <= +0.1634
+ 1.374932... <= x+x0 <= 1.625032...
+ Peak relative error 4.0e-36 */
+static const long double x0a = 1.4616241455078125L;
+static const long double x0b = 7.9994605498412626595423257213002588621246E-6L;
+static const long double y0a = -1.21490478515625E-1L;
+static const long double y0b = 4.1879797753919044854428223084178486438269E-6L;
+#define NRN1r5 8
+static const long double RN1r5[NRN1r5 + 1] =
+{
+ 6.827103657233705798067415468881313128066E5L,
+ 1.910041815932269464714909706705242148108E6L,
+ 2.194344176925978377083808566251427771951E6L,
+ 1.332921400100891472195055269688876427962E6L,
+ 4.589080973377307211815655093824787123508E5L,
+ 8.900334161263456942727083580232613796141E4L,
+ 9.053840838306019753209127312097612455236E3L,
+ 4.053367147553353374151852319743594873771E2L,
+ 5.040631576303952022968949605613514584950E0L
+};
+#define NRD1r5 8
+static const long double RD1r5[NRD1r5 + 1] =
+{
+ 1.411036368843183477558773688484699813355E6L,
+ 4.378121767236251950226362443134306184849E6L,
+ 5.682322855631723455425929877581697918168E6L,
+ 3.999065731556977782435009349967042222375E6L,
+ 1.653651390456781293163585493620758410333E6L,
+ 4.067774359067489605179546964969435858311E5L,
+ 5.741463295366557346748361781768833633256E4L,
+ 4.226404539738182992856094681115746692030E3L,
+ 1.316980975410327975566999780608618774469E2L,
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x+1.25) = log gamma(1.25) + x P(x)/Q(x)
+ -.125 <= x <= +.125
+ 1.125 <= x+1.25 <= 1.375
+ Peak relative error = 4.9e-36 */
+static const long double lgam1r25a = -9.82818603515625E-2L;
+static const long double lgam1r25b = 1.0023929749338536146197303364159774377296E-5L;
+#define NRN1r25 9
+static const long double RN1r25[NRN1r25 + 1] =
+{
+ -9.054787275312026472896002240379580536760E4L,
+ -8.685076892989927640126560802094680794471E4L,
+ 2.797898965448019916967849727279076547109E5L,
+ 6.175520827134342734546868356396008898299E5L,
+ 5.179626599589134831538516906517372619641E5L,
+ 2.253076616239043944538380039205558242161E5L,
+ 5.312653119599957228630544772499197307195E4L,
+ 6.434329437514083776052669599834938898255E3L,
+ 3.385414416983114598582554037612347549220E2L,
+ 4.907821957946273805080625052510832015792E0L
+};
+#define NRD1r25 8
+static const long double RD1r25[NRD1r25 + 1] =
+{
+ 3.980939377333448005389084785896660309000E5L,
+ 1.429634893085231519692365775184490465542E6L,
+ 2.145438946455476062850151428438668234336E6L,
+ 1.743786661358280837020848127465970357893E6L,
+ 8.316364251289743923178092656080441655273E5L,
+ 2.355732939106812496699621491135458324294E5L,
+ 3.822267399625696880571810137601310855419E4L,
+ 3.228463206479133236028576845538387620856E3L,
+ 1.152133170470059555646301189220117965514E2L
+ /* 1.0E0L */
+};
+
+
+/* log gamma(x + 1) = x P(x)/Q(x)
+ 0.0 <= x <= +0.125
+ 1.0 <= x+1 <= 1.125
+ Peak relative error 1.1e-35 */
+#define NRN1 8
+static const long double RN1[NRN1 + 1] =
+{
+ -9.987560186094800756471055681088744738818E3L,
+ -2.506039379419574361949680225279376329742E4L,
+ -1.386770737662176516403363873617457652991E4L,
+ 1.439445846078103202928677244188837130744E4L,
+ 2.159612048879650471489449668295139990693E4L,
+ 1.047439813638144485276023138173676047079E4L,
+ 2.250316398054332592560412486630769139961E3L,
+ 1.958510425467720733041971651126443864041E2L,
+ 4.516830313569454663374271993200291219855E0L
+};
+#define NRD1 7
+static const long double RD1[NRD1 + 1] =
+{
+ 1.730299573175751778863269333703788214547E4L,
+ 6.807080914851328611903744668028014678148E4L,
+ 1.090071629101496938655806063184092302439E5L,
+ 9.124354356415154289343303999616003884080E4L,
+ 4.262071638655772404431164427024003253954E4L,
+ 1.096981664067373953673982635805821283581E4L,
+ 1.431229503796575892151252708527595787588E3L,
+ 7.734110684303689320830401788262295992921E1L
+ /* 1.0E0 */
+};
+
+
+/* log gamma(x + 1) = x P(x)/Q(x)
+ -0.125 <= x <= 0
+ 0.875 <= x+1 <= 1.0
+ Peak relative error 7.0e-37 */
+#define NRNr9 8
+static const long double RNr9[NRNr9 + 1] =
+{
+ 4.441379198241760069548832023257571176884E5L,
+ 1.273072988367176540909122090089580368732E6L,
+ 9.732422305818501557502584486510048387724E5L,
+ -5.040539994443998275271644292272870348684E5L,
+ -1.208719055525609446357448132109723786736E6L,
+ -7.434275365370936547146540554419058907156E5L,
+ -2.075642969983377738209203358199008185741E5L,
+ -2.565534860781128618589288075109372218042E4L,
+ -1.032901669542994124131223797515913955938E3L,
+};
+#define NRDr9 8
+static const long double RDr9[NRDr9 + 1] =
+{
+ -7.694488331323118759486182246005193998007E5L,
+ -3.301918855321234414232308938454112213751E6L,
+ -5.856830900232338906742924836032279404702E6L,
+ -5.540672519616151584486240871424021377540E6L,
+ -3.006530901041386626148342989181721176919E6L,
+ -9.350378280513062139466966374330795935163E5L,
+ -1.566179100031063346901755685375732739511E5L,
+ -1.205016539620260779274902967231510804992E4L,
+ -2.724583156305709733221564484006088794284E2L
+/* 1.0E0 */
+};
+
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+neval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+deval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+#ifdef __STDC__
+long double
+__ieee754_lgammal_r (long double x, int *signgamp)
+#else
+long double
+__ieee754_lgammal_r (x, signgamp)
+ long double x;
+ int *signgamp;
+#endif
+{
+ long double p, q, w, z, nx;
+ int i, nn;
+
+ *signgamp = 1;
+
+ if (! __finitel (x))
+ return x * x;
+
+ if (x < 0.0L)
+ {
+ q = -x;
+ p = __floorl (q);
+ if (p == q)
+ return (one / (p - p));
+ i = p;
+ if ((i & 1) == 0)
+ *signgamp = -1;
+ else
+ *signgamp = 1;
+ z = q - p;
+ if (z > 0.5L)
+ {
+ p += 1.0L;
+ z = p - q;
+ }
+ z = q * __sinl (PIL * z);
+ if (z == 0.0L)
+ return (*signgamp * huge * huge);
+ w = __ieee754_lgammal_r (q, &i);
+ z = __logl (PIL / z) - w;
+ return (z);
+ }
+
+ if (x < 13.5L)
+ {
+ p = 0.0L;
+ nx = __floorl (x + 0.5L);
+ nn = nx;
+ switch (nn)
+ {
+ case 0:
+ /* log gamma (x + 1) = log(x) + log gamma(x) */
+ if (x <= 0.125)
+ {
+ p = x * neval (x, RN1, NRN1) / deval (x, RD1, NRD1);
+ }
+ else if (x <= 0.375)
+ {
+ z = x - 0.25L;
+ p = z * neval (z, RN1r25, NRN1r25) / deval (z, RD1r25, NRD1r25);
+ p += lgam1r25b;
+ p += lgam1r25a;
+ }
+ else if (x <= 0.625)
+ {
+ z = x + (1.0L - x0a);
+ z = z - x0b;
+ p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5);
+ p = p * z * z;
+ p = p + y0b;
+ p = p + y0a;
+ }
+ else if (x <= 0.875)
+ {
+ z = x - 0.75L;
+ p = z * neval (z, RN1r75, NRN1r75) / deval (z, RD1r75, NRD1r75);
+ p += lgam1r75b;
+ p += lgam1r75a;
+ }
+ else
+ {
+ z = x - 1.0L;
+ p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2);
+ }
+ p = p - __logl (x);
+ break;
+
+ case 1:
+ if (x < 0.875L)
+ {
+ if (x <= 0.625)
+ {
+ z = x + (1.0L - x0a);
+ z = z - x0b;
+ p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5);
+ p = p * z * z;
+ p = p + y0b;
+ p = p + y0a;
+ }
+ else if (x <= 0.875)
+ {
+ z = x - 0.75L;
+ p = z * neval (z, RN1r75, NRN1r75)
+ / deval (z, RD1r75, NRD1r75);
+ p += lgam1r75b;
+ p += lgam1r75a;
+ }
+ else
+ {
+ z = x - 1.0L;
+ p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2);
+ }
+ p = p - __logl (x);
+ }
+ else if (x < 1.0L)
+ {
+ z = x - 1.0L;
+ p = z * neval (z, RNr9, NRNr9) / deval (z, RDr9, NRDr9);
+ }
+ else if (x == 1.0L)
+ p = 0.0L;
+ else if (x <= 1.125L)
+ {
+ z = x - 1.0L;
+ p = z * neval (z, RN1, NRN1) / deval (z, RD1, NRD1);
+ }
+ else if (x <= 1.375)
+ {
+ z = x - 1.25L;
+ p = z * neval (z, RN1r25, NRN1r25) / deval (z, RD1r25, NRD1r25);
+ p += lgam1r25b;
+ p += lgam1r25a;
+ }
+ else
+ {
+ /* 1.375 <= x+x0 <= 1.625 */
+ z = x - x0a;
+ z = z - x0b;
+ p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5);
+ p = p * z * z;
+ p = p + y0b;
+ p = p + y0a;
+ }
+ break;
+
+ case 2:
+ if (x < 1.625L)
+ {
+ z = x - x0a;
+ z = z - x0b;
+ p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5);
+ p = p * z * z;
+ p = p + y0b;
+ p = p + y0a;
+ }
+ else if (x < 1.875L)
+ {
+ z = x - 1.75L;
+ p = z * neval (z, RN1r75, NRN1r75) / deval (z, RD1r75, NRD1r75);
+ p += lgam1r75b;
+ p += lgam1r75a;
+ }
+ else if (x == 2.0L)
+ p = 0.0L;
+ else if (x < 2.375L)
+ {
+ z = x - 2.0L;
+ p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2);
+ }
+ else
+ {
+ z = x - 2.5L;
+ p = z * neval (z, RN2r5, NRN2r5) / deval (z, RD2r5, NRD2r5);
+ p += lgam2r5b;
+ p += lgam2r5a;
+ }
+ break;
+
+ case 3:
+ if (x < 2.75)
+ {
+ z = x - 2.5L;
+ p = z * neval (z, RN2r5, NRN2r5) / deval (z, RD2r5, NRD2r5);
+ p += lgam2r5b;
+ p += lgam2r5a;
+ }
+ else
+ {
+ z = x - 3.0L;
+ p = z * neval (z, RN3, NRN3) / deval (z, RD3, NRD3);
+ p += lgam3b;
+ p += lgam3a;
+ }
+ break;
+
+ case 4:
+ z = x - 4.0L;
+ p = z * neval (z, RN4, NRN4) / deval (z, RD4, NRD4);
+ p += lgam4b;
+ p += lgam4a;
+ break;
+
+ case 5:
+ z = x - 5.0L;
+ p = z * neval (z, RN5, NRN5) / deval (z, RD5, NRD5);
+ p += lgam5b;
+ p += lgam5a;
+ break;
+
+ case 6:
+ z = x - 6.0L;
+ p = z * neval (z, RN6, NRN6) / deval (z, RD6, NRD6);
+ p += lgam6b;
+ p += lgam6a;
+ break;
+
+ case 7:
+ z = x - 7.0L;
+ p = z * neval (z, RN7, NRN7) / deval (z, RD7, NRD7);
+ p += lgam7b;
+ p += lgam7a;
+ break;
+
+ case 8:
+ z = x - 8.0L;
+ p = z * neval (z, RN8, NRN8) / deval (z, RD8, NRD8);
+ p += lgam8b;
+ p += lgam8a;
+ break;
+
+ case 9:
+ z = x - 9.0L;
+ p = z * neval (z, RN9, NRN9) / deval (z, RD9, NRD9);
+ p += lgam9b;
+ p += lgam9a;
+ break;
+
+ case 10:
+ z = x - 10.0L;
+ p = z * neval (z, RN10, NRN10) / deval (z, RD10, NRD10);
+ p += lgam10b;
+ p += lgam10a;
+ break;
+
+ case 11:
+ z = x - 11.0L;
+ p = z * neval (z, RN11, NRN11) / deval (z, RD11, NRD11);
+ p += lgam11b;
+ p += lgam11a;
+ break;
+
+ case 12:
+ z = x - 12.0L;
+ p = z * neval (z, RN12, NRN12) / deval (z, RD12, NRD12);
+ p += lgam12b;
+ p += lgam12a;
+ break;
+
+ case 13:
+ z = x - 13.0L;
+ p = z * neval (z, RN13, NRN13) / deval (z, RD13, NRD13);
+ p += lgam13b;
+ p += lgam13a;
+ break;
+ }
+ return p;
+ }
+
+ if (x > MAXLGM)
+ return (*signgamp * huge * huge);
+
+ q = ls2pi - x;
+ q = (x - 0.5L) * __logl (x) + q;
+ if (x > 1.0e18L)
+ return (q);
+
+ p = 1.0L / (x * x);
+ q += neval (p, RASY, NRASY) / x;
+ return (q);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_log10l.c b/libc/sysdeps/ieee754/ldbl-128/e_log10l.c
new file mode 100644
index 000000000..1213177a8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_log10l.c
@@ -0,0 +1,258 @@
+/* log10l.c
+ *
+ * Common logarithm, 128-bit long double precision
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, log10l();
+ *
+ * y = log10l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base 10 logarithm of x.
+ *
+ * The argument is separated into its exponent and fractional
+ * parts. If the exponent is between -1 and +1, the logarithm
+ * of the fraction is approximated by
+ *
+ * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x).
+ *
+ * Otherwise, setting z = 2(x-1)/x+1),
+ *
+ * log(x) = z + z^3 P(z)/Q(z).
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE 0.5, 2.0 30000 2.3e-34 4.9e-35
+ * IEEE exp(+-10000) 30000 1.0e-34 4.1e-35
+ *
+ * In the tests over the interval exp(+-10000), the logarithms
+ * of the random arguments were uniformly distributed over
+ * [-10000, +10000].
+ *
+ */
+
+/*
+ Cephes Math Library Release 2.2: January, 1991
+ Copyright 1984, 1991 by Stephen L. Moshier
+ Adapted for glibc November, 2001
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 5.3e-37,
+ * relative peak error spread = 2.3e-14
+ */
+static const long double P[13] =
+{
+ 1.313572404063446165910279910527789794488E4L,
+ 7.771154681358524243729929227226708890930E4L,
+ 2.014652742082537582487669938141683759923E5L,
+ 3.007007295140399532324943111654767187848E5L,
+ 2.854829159639697837788887080758954924001E5L,
+ 1.797628303815655343403735250238293741397E5L,
+ 7.594356839258970405033155585486712125861E4L,
+ 2.128857716871515081352991964243375186031E4L,
+ 3.824952356185897735160588078446136783779E3L,
+ 4.114517881637811823002128927449878962058E2L,
+ 2.321125933898420063925789532045674660756E1L,
+ 4.998469661968096229986658302195402690910E-1L,
+ 1.538612243596254322971797716843006400388E-6L
+};
+static const long double Q[12] =
+{
+ 3.940717212190338497730839731583397586124E4L,
+ 2.626900195321832660448791748036714883242E5L,
+ 7.777690340007566932935753241556479363645E5L,
+ 1.347518538384329112529391120390701166528E6L,
+ 1.514882452993549494932585972882995548426E6L,
+ 1.158019977462989115839826904108208787040E6L,
+ 6.132189329546557743179177159925690841200E5L,
+ 2.248234257620569139969141618556349415120E5L,
+ 5.605842085972455027590989944010492125825E4L,
+ 9.147150349299596453976674231612674085381E3L,
+ 9.104928120962988414618126155557301584078E2L,
+ 4.839208193348159620282142911143429644326E1L
+/* 1.000000000000000000000000000000000000000E0L, */
+};
+
+/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
+ * where z = 2(x-1)/(x+1)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 1.1e-35,
+ * relative peak error spread 1.1e-9
+ */
+static const long double R[6] =
+{
+ 1.418134209872192732479751274970992665513E5L,
+ -8.977257995689735303686582344659576526998E4L,
+ 2.048819892795278657810231591630928516206E4L,
+ -2.024301798136027039250415126250455056397E3L,
+ 8.057002716646055371965756206836056074715E1L,
+ -8.828896441624934385266096344596648080902E-1L
+};
+static const long double S[6] =
+{
+ 1.701761051846631278975701529965589676574E6L,
+ -1.332535117259762928288745111081235577029E6L,
+ 4.001557694070773974936904547424676279307E5L,
+ -5.748542087379434595104154610899551484314E4L,
+ 3.998526750980007367835804959888064681098E3L,
+ -1.186359407982897997337150403816839480438E2L
+/* 1.000000000000000000000000000000000000000E0L, */
+};
+
+static const long double
+/* log10(2) */
+L102A = 0.3125L,
+L102B = -1.14700043360188047862611052755069732318101185E-2L,
+/* log10(e) */
+L10EA = 0.5L,
+L10EB = -6.570551809674817234887108108339491770560299E-2L,
+/* sqrt(2)/2 */
+SQRTH = 7.071067811865475244008443621048490392848359E-1L;
+
+
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+neval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+deval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+
+long double
+__ieee754_log10l (x)
+ long double x;
+{
+ long double z;
+ long double y;
+ int e;
+ int64_t hx, lx;
+
+/* Test for domain */
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+ if (((hx & 0x7fffffffffffffffLL) | lx) == 0)
+ return (-1.0L / (x - x));
+ if (hx < 0)
+ return (x - x) / (x - x);
+ if (hx >= 0x7fff000000000000LL)
+ return (x + x);
+
+/* separate mantissa from exponent */
+
+/* Note, frexp is used so that denormal numbers
+ * will be handled properly.
+ */
+ x = __frexpl (x, &e);
+
+
+/* logarithm using log(x) = z + z**3 P(z)/Q(z),
+ * where z = 2(x-1)/x+1)
+ */
+ if ((e > 2) || (e < -2))
+ {
+ if (x < SQRTH)
+ { /* 2( 2x-1 )/( 2x+1 ) */
+ e -= 1;
+ z = x - 0.5L;
+ y = 0.5L * z + 0.5L;
+ }
+ else
+ { /* 2 (x-1)/(x+1) */
+ z = x - 0.5L;
+ z -= 0.5L;
+ y = 0.5L * x + 0.5L;
+ }
+ x = z / y;
+ z = x * x;
+ y = x * (z * neval (z, R, 5) / deval (z, S, 5));
+ goto done;
+ }
+
+
+/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
+
+ if (x < SQRTH)
+ {
+ e -= 1;
+ x = 2.0 * x - 1.0L; /* 2x - 1 */
+ }
+ else
+ {
+ x = x - 1.0L;
+ }
+ z = x * x;
+ y = x * (z * neval (x, P, 12) / deval (x, Q, 11));
+ y = y - 0.5 * z;
+
+done:
+
+ /* Multiply log of fraction by log10(e)
+ * and base 2 exponent by log10(2).
+ */
+ z = y * L10EB;
+ z += x * L10EB;
+ z += e * L102B;
+ z += y * L10EA;
+ z += x * L10EA;
+ z += e * L102A;
+ return (z);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_log2l.c b/libc/sysdeps/ieee754/ldbl-128/e_log2l.c
new file mode 100644
index 000000000..8663d78b3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_log2l.c
@@ -0,0 +1,250 @@
+/* log2l.c
+ * Base 2 logarithm, 128-bit long double precision
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, log2l();
+ *
+ * y = log2l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base 2 logarithm of x.
+ *
+ * The argument is separated into its exponent and fractional
+ * parts. If the exponent is between -1 and +1, the (natural)
+ * logarithm of the fraction is approximated by
+ *
+ * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x).
+ *
+ * Otherwise, setting z = 2(x-1)/x+1),
+ *
+ * log(x) = z + z^3 P(z)/Q(z).
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE 0.5, 2.0 100,000 2.6e-34 4.9e-35
+ * IEEE exp(+-10000) 100,000 9.6e-35 4.0e-35
+ *
+ * In the tests over the interval exp(+-10000), the logarithms
+ * of the random arguments were uniformly distributed over
+ * [-10000, +10000].
+ *
+ */
+
+/*
+ Cephes Math Library Release 2.2: January, 1991
+ Copyright 1984, 1991 by Stephen L. Moshier
+ Adapted for glibc November, 2001
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 5.3e-37,
+ * relative peak error spread = 2.3e-14
+ */
+static const long double P[13] =
+{
+ 1.313572404063446165910279910527789794488E4L,
+ 7.771154681358524243729929227226708890930E4L,
+ 2.014652742082537582487669938141683759923E5L,
+ 3.007007295140399532324943111654767187848E5L,
+ 2.854829159639697837788887080758954924001E5L,
+ 1.797628303815655343403735250238293741397E5L,
+ 7.594356839258970405033155585486712125861E4L,
+ 2.128857716871515081352991964243375186031E4L,
+ 3.824952356185897735160588078446136783779E3L,
+ 4.114517881637811823002128927449878962058E2L,
+ 2.321125933898420063925789532045674660756E1L,
+ 4.998469661968096229986658302195402690910E-1L,
+ 1.538612243596254322971797716843006400388E-6L
+};
+static const long double Q[12] =
+{
+ 3.940717212190338497730839731583397586124E4L,
+ 2.626900195321832660448791748036714883242E5L,
+ 7.777690340007566932935753241556479363645E5L,
+ 1.347518538384329112529391120390701166528E6L,
+ 1.514882452993549494932585972882995548426E6L,
+ 1.158019977462989115839826904108208787040E6L,
+ 6.132189329546557743179177159925690841200E5L,
+ 2.248234257620569139969141618556349415120E5L,
+ 5.605842085972455027590989944010492125825E4L,
+ 9.147150349299596453976674231612674085381E3L,
+ 9.104928120962988414618126155557301584078E2L,
+ 4.839208193348159620282142911143429644326E1L
+/* 1.000000000000000000000000000000000000000E0L, */
+};
+
+/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
+ * where z = 2(x-1)/(x+1)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 1.1e-35,
+ * relative peak error spread 1.1e-9
+ */
+static const long double R[6] =
+{
+ 1.418134209872192732479751274970992665513E5L,
+ -8.977257995689735303686582344659576526998E4L,
+ 2.048819892795278657810231591630928516206E4L,
+ -2.024301798136027039250415126250455056397E3L,
+ 8.057002716646055371965756206836056074715E1L,
+ -8.828896441624934385266096344596648080902E-1L
+};
+static const long double S[6] =
+{
+ 1.701761051846631278975701529965589676574E6L,
+ -1.332535117259762928288745111081235577029E6L,
+ 4.001557694070773974936904547424676279307E5L,
+ -5.748542087379434595104154610899551484314E4L,
+ 3.998526750980007367835804959888064681098E3L,
+ -1.186359407982897997337150403816839480438E2L
+/* 1.000000000000000000000000000000000000000E0L, */
+};
+
+static const long double
+/* log2(e) - 1 */
+LOG2EA = 4.4269504088896340735992468100189213742664595E-1L,
+/* sqrt(2)/2 */
+SQRTH = 7.071067811865475244008443621048490392848359E-1L;
+
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+neval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+deval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+
+long double
+__ieee754_log2l (x)
+ long double x;
+{
+ long double z;
+ long double y;
+ int e;
+ int64_t hx, lx;
+
+/* Test for domain */
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+ if (((hx & 0x7fffffffffffffffLL) | lx) == 0)
+ return (-1.0L / (x - x));
+ if (hx < 0)
+ return (x - x) / (x - x);
+ if (hx >= 0x7fff000000000000LL)
+ return (x + x);
+
+/* separate mantissa from exponent */
+
+/* Note, frexp is used so that denormal numbers
+ * will be handled properly.
+ */
+ x = __frexpl (x, &e);
+
+
+/* logarithm using log(x) = z + z**3 P(z)/Q(z),
+ * where z = 2(x-1)/x+1)
+ */
+ if ((e > 2) || (e < -2))
+ {
+ if (x < SQRTH)
+ { /* 2( 2x-1 )/( 2x+1 ) */
+ e -= 1;
+ z = x - 0.5L;
+ y = 0.5L * z + 0.5L;
+ }
+ else
+ { /* 2 (x-1)/(x+1) */
+ z = x - 0.5L;
+ z -= 0.5L;
+ y = 0.5L * x + 0.5L;
+ }
+ x = z / y;
+ z = x * x;
+ y = x * (z * neval (z, R, 5) / deval (z, S, 5));
+ goto done;
+ }
+
+
+/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
+
+ if (x < SQRTH)
+ {
+ e -= 1;
+ x = 2.0 * x - 1.0L; /* 2x - 1 */
+ }
+ else
+ {
+ x = x - 1.0L;
+ }
+ z = x * x;
+ y = x * (z * neval (x, P, 12) / deval (x, Q, 11));
+ y = y - 0.5 * z;
+
+done:
+
+/* Multiply log of fraction by log2(e)
+ * and base 2 exponent by 1
+ */
+ z = y * LOG2EA;
+ z += x * LOG2EA;
+ z += y;
+ z += x;
+ z += e;
+ return (z);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_logl.c b/libc/sysdeps/ieee754/ldbl-128/e_logl.c
new file mode 100644
index 000000000..b9e17f8f9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_logl.c
@@ -0,0 +1,279 @@
+/* logll.c
+ *
+ * Natural logarithm for 128-bit long double precision.
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, logl();
+ *
+ * y = logl( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base e (2.718...) logarithm of x.
+ *
+ * The argument is separated into its exponent and fractional
+ * parts. Use of a lookup table increases the speed of the routine.
+ * The program uses logarithms tabulated at intervals of 1/128 to
+ * cover the domain from approximately 0.7 to 1.4.
+ *
+ * On the interval [-1/128, +1/128] the logarithm of 1+x is approximated by
+ * log(1+x) = x - 0.5 x^2 + x^3 P(x) .
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE 0.875, 1.125 100000 1.2e-34 4.1e-35
+ * IEEE 0.125, 8 100000 1.2e-34 4.1e-35
+ *
+ *
+ * WARNING:
+ *
+ * This program uses integer operations on bit fields of floating-point
+ * numbers. It does not work with data structures other than the
+ * structure assumed.
+ *
+ */
+
+/* Copyright 2001 by Stephen L. Moshier <moshier@na-net.ornl.gov>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "math_private.h"
+
+/* log(1+x) = x - .5 x^2 + x^3 l(x)
+ -.0078125 <= x <= +.0078125
+ peak relative error 1.2e-37 */
+static const long double
+l3 = 3.333333333333333333333333333333336096926E-1L,
+l4 = -2.499999999999999999999999999486853077002E-1L,
+l5 = 1.999999999999999999999999998515277861905E-1L,
+l6 = -1.666666666666666666666798448356171665678E-1L,
+l7 = 1.428571428571428571428808945895490721564E-1L,
+l8 = -1.249999999999999987884655626377588149000E-1L,
+l9 = 1.111111111111111093947834982832456459186E-1L,
+l10 = -1.000000000000532974938900317952530453248E-1L,
+l11 = 9.090909090915566247008015301349979892689E-2L,
+l12 = -8.333333211818065121250921925397567745734E-2L,
+l13 = 7.692307559897661630807048686258659316091E-2L,
+l14 = -7.144242754190814657241902218399056829264E-2L,
+l15 = 6.668057591071739754844678883223432347481E-2L;
+
+/* Lookup table of ln(t) - (t-1)
+ t = 0.5 + (k+26)/128)
+ k = 0, ..., 91 */
+static const long double logtbl[92] = {
+-5.5345593589352099112142921677820359632418E-2L,
+-5.2108257402767124761784665198737642086148E-2L,
+-4.8991686870576856279407775480686721935120E-2L,
+-4.5993270766361228596215288742353061431071E-2L,
+-4.3110481649613269682442058976885699556950E-2L,
+-4.0340872319076331310838085093194799765520E-2L,
+-3.7682072451780927439219005993827431503510E-2L,
+-3.5131785416234343803903228503274262719586E-2L,
+-3.2687785249045246292687241862699949178831E-2L,
+-3.0347913785027239068190798397055267411813E-2L,
+-2.8110077931525797884641940838507561326298E-2L,
+-2.5972247078357715036426583294246819637618E-2L,
+-2.3932450635346084858612873953407168217307E-2L,
+-2.1988775689981395152022535153795155900240E-2L,
+-2.0139364778244501615441044267387667496733E-2L,
+-1.8382413762093794819267536615342902718324E-2L,
+-1.6716169807550022358923589720001638093023E-2L,
+-1.5138929457710992616226033183958974965355E-2L,
+-1.3649036795397472900424896523305726435029E-2L,
+-1.2244881690473465543308397998034325468152E-2L,
+-1.0924898127200937840689817557742469105693E-2L,
+-9.6875626072830301572839422532631079809328E-3L,
+-8.5313926245226231463436209313499745894157E-3L,
+-7.4549452072765973384933565912143044991706E-3L,
+-6.4568155251217050991200599386801665681310E-3L,
+-5.5356355563671005131126851708522185605193E-3L,
+-4.6900728132525199028885749289712348829878E-3L,
+-3.9188291218610470766469347968659624282519E-3L,
+-3.2206394539524058873423550293617843896540E-3L,
+-2.5942708080877805657374888909297113032132E-3L,
+-2.0385211375711716729239156839929281289086E-3L,
+-1.5522183228760777967376942769773768850872E-3L,
+-1.1342191863606077520036253234446621373191E-3L,
+-7.8340854719967065861624024730268350459991E-4L,
+-4.9869831458030115699628274852562992756174E-4L,
+-2.7902661731604211834685052867305795169688E-4L,
+-1.2335696813916860754951146082826952093496E-4L,
+-3.0677461025892873184042490943581654591817E-5L,
+#define ZERO logtbl[38]
+ 0.0000000000000000000000000000000000000000E0L,
+-3.0359557945051052537099938863236321874198E-5L,
+-1.2081346403474584914595395755316412213151E-4L,
+-2.7044071846562177120083903771008342059094E-4L,
+-4.7834133324631162897179240322783590830326E-4L,
+-7.4363569786340080624467487620270965403695E-4L,
+-1.0654639687057968333207323853366578860679E-3L,
+-1.4429854811877171341298062134712230604279E-3L,
+-1.8753781835651574193938679595797367137975E-3L,
+-2.3618380914922506054347222273705859653658E-3L,
+-2.9015787624124743013946600163375853631299E-3L,
+-3.4938307889254087318399313316921940859043E-3L,
+-4.1378413103128673800485306215154712148146E-3L,
+-4.8328735414488877044289435125365629849599E-3L,
+-5.5782063183564351739381962360253116934243E-3L,
+-6.3731336597098858051938306767880719015261E-3L,
+-7.2169643436165454612058905294782949315193E-3L,
+-8.1090214990427641365934846191367315083867E-3L,
+-9.0486422112807274112838713105168375482480E-3L,
+-1.0035177140880864314674126398350812606841E-2L,
+-1.1067990155502102718064936259435676477423E-2L,
+-1.2146457974158024928196575103115488672416E-2L,
+-1.3269969823361415906628825374158424754308E-2L,
+-1.4437927104692837124388550722759686270765E-2L,
+-1.5649743073340777659901053944852735064621E-2L,
+-1.6904842527181702880599758489058031645317E-2L,
+-1.8202661505988007336096407340750378994209E-2L,
+-1.9542647000370545390701192438691126552961E-2L,
+-2.0924256670080119637427928803038530924742E-2L,
+-2.2346958571309108496179613803760727786257E-2L,
+-2.3810230892650362330447187267648486279460E-2L,
+-2.5313561699385640380910474255652501521033E-2L,
+-2.6856448685790244233704909690165496625399E-2L,
+-2.8438398935154170008519274953860128449036E-2L,
+-3.0058928687233090922411781058956589863039E-2L,
+-3.1717563112854831855692484086486099896614E-2L,
+-3.3413836095418743219397234253475252001090E-2L,
+-3.5147290019036555862676702093393332533702E-2L,
+-3.6917475563073933027920505457688955423688E-2L,
+-3.8723951502862058660874073462456610731178E-2L,
+-4.0566284516358241168330505467000838017425E-2L,
+-4.2444048996543693813649967076598766917965E-2L,
+-4.4356826869355401653098777649745233339196E-2L,
+-4.6304207416957323121106944474331029996141E-2L,
+-4.8285787106164123613318093945035804818364E-2L,
+-5.0301169421838218987124461766244507342648E-2L,
+-5.2349964705088137924875459464622098310997E-2L,
+-5.4431789996103111613753440311680967840214E-2L,
+-5.6546268881465384189752786409400404404794E-2L,
+-5.8693031345788023909329239565012647817664E-2L,
+-6.0871713627532018185577188079210189048340E-2L,
+-6.3081958078862169742820420185833800925568E-2L,
+-6.5323413029406789694910800219643791556918E-2L,
+-6.7595732653791419081537811574227049288168E-2L
+};
+
+/* ln(2) = ln2a + ln2b with extended precision. */
+static const long double
+ ln2a = 6.93145751953125e-1L,
+ ln2b = 1.4286068203094172321214581765680755001344E-6L;
+
+long double
+__ieee754_logl(long double x)
+{
+ long double z, y, w;
+ ieee854_long_double_shape_type u, t;
+ unsigned int m;
+ int k, e;
+
+ u.value = x;
+ m = u.parts32.w0;
+
+ /* Check for IEEE special cases. */
+ k = m & 0x7fffffff;
+ /* log(0) = -infinity. */
+ if ((k | u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0)
+ {
+ return -0.5L / ZERO;
+ }
+ /* log ( x < 0 ) = NaN */
+ if (m & 0x80000000)
+ {
+ return (x - x) / ZERO;
+ }
+ /* log (infinity or NaN) */
+ if (k >= 0x7fff0000)
+ {
+ return x + x;
+ }
+
+ /* Extract exponent and reduce domain to 0.703125 <= u < 1.40625 */
+ e = (int) (m >> 16) - (int) 0x3ffe;
+ m &= 0xffff;
+ u.parts32.w0 = m | 0x3ffe0000;
+ m |= 0x10000;
+ /* Find lookup table index k from high order bits of the significand. */
+ if (m < 0x16800)
+ {
+ k = (m - 0xff00) >> 9;
+ /* t is the argument 0.5 + (k+26)/128
+ of the nearest item to u in the lookup table. */
+ t.parts32.w0 = 0x3fff0000 + (k << 9);
+ t.parts32.w1 = 0;
+ t.parts32.w2 = 0;
+ t.parts32.w3 = 0;
+ u.parts32.w0 += 0x10000;
+ e -= 1;
+ k += 64;
+ }
+ else
+ {
+ k = (m - 0xfe00) >> 10;
+ t.parts32.w0 = 0x3ffe0000 + (k << 10);
+ t.parts32.w1 = 0;
+ t.parts32.w2 = 0;
+ t.parts32.w3 = 0;
+ }
+ /* On this interval the table is not used due to cancellation error. */
+ if ((x <= 1.0078125L) && (x >= 0.9921875L))
+ {
+ z = x - 1.0L;
+ k = 64;
+ t.value = 1.0L;
+ e = 0;
+ }
+ else
+ {
+ /* log(u) = log( t u/t ) = log(t) + log(u/t)
+ log(t) is tabulated in the lookup table.
+ Express log(u/t) = log(1+z), where z = u/t - 1 = (u-t)/t.
+ cf. Cody & Waite. */
+ z = (u.value - t.value) / t.value;
+ }
+ /* Series expansion of log(1+z). */
+ w = z * z;
+ y = ((((((((((((l15 * z
+ + l14) * z
+ + l13) * z
+ + l12) * z
+ + l11) * z
+ + l10) * z
+ + l9) * z
+ + l8) * z
+ + l7) * z
+ + l6) * z
+ + l5) * z
+ + l4) * z
+ + l3) * z * w;
+ y -= 0.5 * w;
+ y += e * ln2b; /* Base 2 exponent offset times ln(2). */
+ y += z;
+ y += logtbl[k-26]; /* log(t) - (t-1) */
+ y += (t.value - 1.0L);
+ y += e * ln2a;
+ return y;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_powl.c b/libc/sysdeps/ieee754/ldbl-128/e_powl.c
new file mode 100644
index 000000000..ba7e27b7d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_powl.c
@@ -0,0 +1,447 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* Expansions and modifications for 128-bit long double are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __ieee754_powl(x,y) return x**y
+ *
+ * n
+ * Method: Let x = 2 * (1+f)
+ * 1. Compute and return log2(x) in two pieces:
+ * log2(x) = w1 + w2,
+ * where w1 has 113-53 = 60 bit trailing zeros.
+ * 2. Perform y*log2(x) = n+y' by simulating muti-precision
+ * arithmetic, where |y'|<=0.5.
+ * 3. Return x**y = 2**n*exp(y'*log2)
+ *
+ * Special cases:
+ * 1. (anything) ** 0 is 1
+ * 2. (anything) ** 1 is itself
+ * 3. (anything) ** NAN is NAN
+ * 4. NAN ** (anything except 0) is NAN
+ * 5. +-(|x| > 1) ** +INF is +INF
+ * 6. +-(|x| > 1) ** -INF is +0
+ * 7. +-(|x| < 1) ** +INF is +0
+ * 8. +-(|x| < 1) ** -INF is +INF
+ * 9. +-1 ** +-INF is NAN
+ * 10. +0 ** (+anything except 0, NAN) is +0
+ * 11. -0 ** (+anything except 0, NAN, odd integer) is +0
+ * 12. +0 ** (-anything except 0, NAN) is +INF
+ * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
+ * 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
+ * 15. +INF ** (+anything except 0,NAN) is +INF
+ * 16. +INF ** (-anything except 0,NAN) is +0
+ * 17. -INF ** (anything) = -0 ** (-anything)
+ * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
+ * 19. (-anything except 0 and inf) ** (non-integer) is NAN
+ *
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const long double bp[] = {
+ 1.0L,
+ 1.5L,
+};
+
+/* log_2(1.5) */
+static const long double dp_h[] = {
+ 0.0,
+ 5.8496250072115607565592654282227158546448E-1L
+};
+
+/* Low part of log_2(1.5) */
+static const long double dp_l[] = {
+ 0.0,
+ 1.0579781240112554492329533686862998106046E-16L
+};
+
+static const long double zero = 0.0L,
+ one = 1.0L,
+ two = 2.0L,
+ two113 = 1.0384593717069655257060992658440192E34L,
+ huge = 1.0e3000L,
+ tiny = 1.0e-3000L;
+
+/* 3/2 log x = 3 z + z^3 + z^3 (z^2 R(z^2))
+ z = (x-1)/(x+1)
+ 1 <= x <= 1.25
+ Peak relative error 2.3e-37 */
+static const long double LN[] =
+{
+ -3.0779177200290054398792536829702930623200E1L,
+ 6.5135778082209159921251824580292116201640E1L,
+ -4.6312921812152436921591152809994014413540E1L,
+ 1.2510208195629420304615674658258363295208E1L,
+ -9.9266909031921425609179910128531667336670E-1L
+};
+static const long double LD[] =
+{
+ -5.129862866715009066465422805058933131960E1L,
+ 1.452015077564081884387441590064272782044E2L,
+ -1.524043275549860505277434040464085593165E2L,
+ 7.236063513651544224319663428634139768808E1L,
+ -1.494198912340228235853027849917095580053E1L
+ /* 1.0E0 */
+};
+
+/* exp(x) = 1 + x - x / (1 - 2 / (x - x^2 R(x^2)))
+ 0 <= x <= 0.5
+ Peak relative error 5.7e-38 */
+static const long double PN[] =
+{
+ 5.081801691915377692446852383385968225675E8L,
+ 9.360895299872484512023336636427675327355E6L,
+ 4.213701282274196030811629773097579432957E4L,
+ 5.201006511142748908655720086041570288182E1L,
+ 9.088368420359444263703202925095675982530E-3L,
+};
+static const long double PD[] =
+{
+ 3.049081015149226615468111430031590411682E9L,
+ 1.069833887183886839966085436512368982758E8L,
+ 8.259257717868875207333991924545445705394E5L,
+ 1.872583833284143212651746812884298360922E3L,
+ /* 1.0E0 */
+};
+
+static const long double
+ /* ln 2 */
+ lg2 = 6.9314718055994530941723212145817656807550E-1L,
+ lg2_h = 6.9314718055994528622676398299518041312695E-1L,
+ lg2_l = 2.3190468138462996154948554638754786504121E-17L,
+ ovt = 8.0085662595372944372e-0017L,
+ /* 2/(3*log(2)) */
+ cp = 9.6179669392597560490661645400126142495110E-1L,
+ cp_h = 9.6179669392597555432899980587535537779331E-1L,
+ cp_l = 5.0577616648125906047157785230014751039424E-17L;
+
+#ifdef __STDC__
+long double
+__ieee754_powl (long double x, long double y)
+#else
+long double
+__ieee754_powl (x, y)
+ long double x, y;
+#endif
+{
+ long double z, ax, z_h, z_l, p_h, p_l;
+ long double y1, t1, t2, r, s, t, u, v, w;
+ long double s2, s_h, s_l, t_h, t_l;
+ int32_t i, j, k, yisint, n;
+ u_int32_t ix, iy;
+ int32_t hx, hy;
+ ieee854_long_double_shape_type o, p, q;
+
+ p.value = x;
+ hx = p.parts32.w0;
+ ix = hx & 0x7fffffff;
+
+ q.value = y;
+ hy = q.parts32.w0;
+ iy = hy & 0x7fffffff;
+
+
+ /* y==zero: x**0 = 1 */
+ if ((iy | q.parts32.w1 | q.parts32.w2 | q.parts32.w3) == 0)
+ return one;
+
+ /* 1.0**y = 1; -1.0**+-Inf = 1 */
+ if (x == one)
+ return one;
+ if (x == -1.0L && iy == 0x7fff0000
+ && (q.parts32.w1 | q.parts32.w2 | q.parts32.w3) == 0)
+ return one;
+
+ /* +-NaN return x+y */
+ if ((ix > 0x7fff0000)
+ || ((ix == 0x7fff0000)
+ && ((p.parts32.w1 | p.parts32.w2 | p.parts32.w3) != 0))
+ || (iy > 0x7fff0000)
+ || ((iy == 0x7fff0000)
+ && ((q.parts32.w1 | q.parts32.w2 | q.parts32.w3) != 0)))
+ return x + y;
+
+ /* determine if y is an odd int when x < 0
+ * yisint = 0 ... y is not an integer
+ * yisint = 1 ... y is an odd int
+ * yisint = 2 ... y is an even int
+ */
+ yisint = 0;
+ if (hx < 0)
+ {
+ if (iy >= 0x40700000) /* 2^113 */
+ yisint = 2; /* even integer y */
+ else if (iy >= 0x3fff0000) /* 1.0 */
+ {
+ if (__floorl (y) == y)
+ {
+ z = 0.5 * y;
+ if (__floorl (z) == z)
+ yisint = 2;
+ else
+ yisint = 1;
+ }
+ }
+ }
+
+ /* special value of y */
+ if ((q.parts32.w1 | q.parts32.w2 | q.parts32.w3) == 0)
+ {
+ if (iy == 0x7fff0000) /* y is +-inf */
+ {
+ if (((ix - 0x3fff0000) | p.parts32.w1 | p.parts32.w2 | p.parts32.w3)
+ == 0)
+ return y - y; /* +-1**inf is NaN */
+ else if (ix >= 0x3fff0000) /* (|x|>1)**+-inf = inf,0 */
+ return (hy >= 0) ? y : zero;
+ else /* (|x|<1)**-,+inf = inf,0 */
+ return (hy < 0) ? -y : zero;
+ }
+ if (iy == 0x3fff0000)
+ { /* y is +-1 */
+ if (hy < 0)
+ return one / x;
+ else
+ return x;
+ }
+ if (hy == 0x40000000)
+ return x * x; /* y is 2 */
+ if (hy == 0x3ffe0000)
+ { /* y is 0.5 */
+ if (hx >= 0) /* x >= +0 */
+ return __ieee754_sqrtl (x);
+ }
+ }
+
+ ax = fabsl (x);
+ /* special value of x */
+ if ((p.parts32.w1 | p.parts32.w2 | p.parts32.w3) == 0)
+ {
+ if (ix == 0x7fff0000 || ix == 0 || ix == 0x3fff0000)
+ {
+ z = ax; /*x is +-0,+-inf,+-1 */
+ if (hy < 0)
+ z = one / z; /* z = (1/|x|) */
+ if (hx < 0)
+ {
+ if (((ix - 0x3fff0000) | yisint) == 0)
+ {
+ z = (z - z) / (z - z); /* (-1)**non-int is NaN */
+ }
+ else if (yisint == 1)
+ z = -z; /* (x<0)**odd = -(|x|**odd) */
+ }
+ return z;
+ }
+ }
+
+ /* (x<0)**(non-int) is NaN */
+ if (((((u_int32_t) hx >> 31) - 1) | yisint) == 0)
+ return (x - x) / (x - x);
+
+ /* |y| is huge.
+ 2^-16495 = 1/2 of smallest representable value.
+ If (1 - 1/131072)^y underflows, y > 1.4986e9 */
+ if (iy > 0x401d654b)
+ {
+ /* if (1 - 2^-113)^y underflows, y > 1.1873e38 */
+ if (iy > 0x407d654b)
+ {
+ if (ix <= 0x3ffeffff)
+ return (hy < 0) ? huge * huge : tiny * tiny;
+ if (ix >= 0x3fff0000)
+ return (hy > 0) ? huge * huge : tiny * tiny;
+ }
+ /* over/underflow if x is not close to one */
+ if (ix < 0x3ffeffff)
+ return (hy < 0) ? huge * huge : tiny * tiny;
+ if (ix > 0x3fff0000)
+ return (hy > 0) ? huge * huge : tiny * tiny;
+ }
+
+ n = 0;
+ /* take care subnormal number */
+ if (ix < 0x00010000)
+ {
+ ax *= two113;
+ n -= 113;
+ o.value = ax;
+ ix = o.parts32.w0;
+ }
+ n += ((ix) >> 16) - 0x3fff;
+ j = ix & 0x0000ffff;
+ /* determine interval */
+ ix = j | 0x3fff0000; /* normalize ix */
+ if (j <= 0x3988)
+ k = 0; /* |x|<sqrt(3/2) */
+ else if (j < 0xbb67)
+ k = 1; /* |x|<sqrt(3) */
+ else
+ {
+ k = 0;
+ n += 1;
+ ix -= 0x00010000;
+ }
+
+ o.value = ax;
+ o.parts32.w0 = ix;
+ ax = o.value;
+
+ /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+ u = ax - bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
+ v = one / (ax + bp[k]);
+ s = u * v;
+ s_h = s;
+
+ o.value = s_h;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xf8000000;
+ s_h = o.value;
+ /* t_h=ax+bp[k] High */
+ t_h = ax + bp[k];
+ o.value = t_h;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xf8000000;
+ t_h = o.value;
+ t_l = ax - (t_h - bp[k]);
+ s_l = v * ((u - s_h * t_h) - s_h * t_l);
+ /* compute log(ax) */
+ s2 = s * s;
+ u = LN[0] + s2 * (LN[1] + s2 * (LN[2] + s2 * (LN[3] + s2 * LN[4])));
+ v = LD[0] + s2 * (LD[1] + s2 * (LD[2] + s2 * (LD[3] + s2 * (LD[4] + s2))));
+ r = s2 * s2 * u / v;
+ r += s_l * (s_h + s);
+ s2 = s_h * s_h;
+ t_h = 3.0 + s2 + r;
+ o.value = t_h;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xf8000000;
+ t_h = o.value;
+ t_l = r - ((t_h - 3.0) - s2);
+ /* u+v = s*(1+...) */
+ u = s_h * t_h;
+ v = s_l * t_h + t_l * s;
+ /* 2/(3log2)*(s+...) */
+ p_h = u + v;
+ o.value = p_h;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xf8000000;
+ p_h = o.value;
+ p_l = v - (p_h - u);
+ z_h = cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */
+ z_l = cp_l * p_h + p_l * cp + dp_l[k];
+ /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+ t = (long double) n;
+ t1 = (((z_h + z_l) + dp_h[k]) + t);
+ o.value = t1;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xf8000000;
+ t1 = o.value;
+ t2 = z_l - (((t1 - t) - dp_h[k]) - z_h);
+
+ /* s (sign of result -ve**odd) = -1 else = 1 */
+ s = one;
+ if (((((u_int32_t) hx >> 31) - 1) | (yisint - 1)) == 0)
+ s = -one; /* (-ve)**(odd int) */
+
+ /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+ y1 = y;
+ o.value = y1;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xf8000000;
+ y1 = o.value;
+ p_l = (y - y1) * t1 + y * t2;
+ p_h = y1 * t1;
+ z = p_l + p_h;
+ o.value = z;
+ j = o.parts32.w0;
+ if (j >= 0x400d0000) /* z >= 16384 */
+ {
+ /* if z > 16384 */
+ if (((j - 0x400d0000) | o.parts32.w1 | o.parts32.w2 | o.parts32.w3) != 0)
+ return s * huge * huge; /* overflow */
+ else
+ {
+ if (p_l + ovt > z - p_h)
+ return s * huge * huge; /* overflow */
+ }
+ }
+ else if ((j & 0x7fffffff) >= 0x400d01b9) /* z <= -16495 */
+ {
+ /* z < -16495 */
+ if (((j - 0xc00d01bc) | o.parts32.w1 | o.parts32.w2 | o.parts32.w3)
+ != 0)
+ return s * tiny * tiny; /* underflow */
+ else
+ {
+ if (p_l <= z - p_h)
+ return s * tiny * tiny; /* underflow */
+ }
+ }
+ /* compute 2**(p_h+p_l) */
+ i = j & 0x7fffffff;
+ k = (i >> 16) - 0x3fff;
+ n = 0;
+ if (i > 0x3ffe0000)
+ { /* if |z| > 0.5, set n = [z+0.5] */
+ n = __floorl (z + 0.5L);
+ t = n;
+ p_h -= t;
+ }
+ t = p_l + p_h;
+ o.value = t;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xf8000000;
+ t = o.value;
+ u = t * lg2_h;
+ v = (p_l - (t - p_h)) * lg2 + t * lg2_l;
+ z = u + v;
+ w = v - (z - u);
+ /* exp(z) */
+ t = z * z;
+ u = PN[0] + t * (PN[1] + t * (PN[2] + t * (PN[3] + t * PN[4])));
+ v = PD[0] + t * (PD[1] + t * (PD[2] + t * (PD[3] + t)));
+ t1 = z - t * u / v;
+ r = (z * t1) / (t1 - two) - (w + z * w);
+ z = one - (r - z);
+ o.value = z;
+ j = o.parts32.w0;
+ j += (n << 16);
+ if ((j >> 16) <= 0)
+ z = __scalbnl (z, n); /* subnormal output */
+ else
+ {
+ o.parts32.w0 = j;
+ z = o.value;
+ }
+ return s * z;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_rem_pio2l.c b/libc/sysdeps/ieee754/ldbl-128/e_rem_pio2l.c
new file mode 100644
index 000000000..091e19e7b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_rem_pio2l.c
@@ -0,0 +1,274 @@
+/* Quad-precision floating point argument reduction.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+
+/*
+ * Table of constants for 2/pi, 5628 hexadecimal digits of 2/pi
+ */
+static const int32_t two_over_pi[] = {
+0xa2f983, 0x6e4e44, 0x1529fc, 0x2757d1, 0xf534dd, 0xc0db62,
+0x95993c, 0x439041, 0xfe5163, 0xabdebb, 0xc561b7, 0x246e3a,
+0x424dd2, 0xe00649, 0x2eea09, 0xd1921c, 0xfe1deb, 0x1cb129,
+0xa73ee8, 0x8235f5, 0x2ebb44, 0x84e99c, 0x7026b4, 0x5f7e41,
+0x3991d6, 0x398353, 0x39f49c, 0x845f8b, 0xbdf928, 0x3b1ff8,
+0x97ffde, 0x05980f, 0xef2f11, 0x8b5a0a, 0x6d1f6d, 0x367ecf,
+0x27cb09, 0xb74f46, 0x3f669e, 0x5fea2d, 0x7527ba, 0xc7ebe5,
+0xf17b3d, 0x0739f7, 0x8a5292, 0xea6bfb, 0x5fb11f, 0x8d5d08,
+0x560330, 0x46fc7b, 0x6babf0, 0xcfbc20, 0x9af436, 0x1da9e3,
+0x91615e, 0xe61b08, 0x659985, 0x5f14a0, 0x68408d, 0xffd880,
+0x4d7327, 0x310606, 0x1556ca, 0x73a8c9, 0x60e27b, 0xc08c6b,
+0x47c419, 0xc367cd, 0xdce809, 0x2a8359, 0xc4768b, 0x961ca6,
+0xddaf44, 0xd15719, 0x053ea5, 0xff0705, 0x3f7e33, 0xe832c2,
+0xde4f98, 0x327dbb, 0xc33d26, 0xef6b1e, 0x5ef89f, 0x3a1f35,
+0xcaf27f, 0x1d87f1, 0x21907c, 0x7c246a, 0xfa6ed5, 0x772d30,
+0x433b15, 0xc614b5, 0x9d19c3, 0xc2c4ad, 0x414d2c, 0x5d000c,
+0x467d86, 0x2d71e3, 0x9ac69b, 0x006233, 0x7cd2b4, 0x97a7b4,
+0xd55537, 0xf63ed7, 0x1810a3, 0xfc764d, 0x2a9d64, 0xabd770,
+0xf87c63, 0x57b07a, 0xe71517, 0x5649c0, 0xd9d63b, 0x3884a7,
+0xcb2324, 0x778ad6, 0x23545a, 0xb91f00, 0x1b0af1, 0xdfce19,
+0xff319f, 0x6a1e66, 0x615799, 0x47fbac, 0xd87f7e, 0xb76522,
+0x89e832, 0x60bfe6, 0xcdc4ef, 0x09366c, 0xd43f5d, 0xd7de16,
+0xde3b58, 0x929bde, 0x2822d2, 0xe88628, 0x4d58e2, 0x32cac6,
+0x16e308, 0xcb7de0, 0x50c017, 0xa71df3, 0x5be018, 0x34132e,
+0x621283, 0x014883, 0x5b8ef5, 0x7fb0ad, 0xf2e91e, 0x434a48,
+0xd36710, 0xd8ddaa, 0x425fae, 0xce616a, 0xa4280a, 0xb499d3,
+0xf2a606, 0x7f775c, 0x83c2a3, 0x883c61, 0x78738a, 0x5a8caf,
+0xbdd76f, 0x63a62d, 0xcbbff4, 0xef818d, 0x67c126, 0x45ca55,
+0x36d9ca, 0xd2a828, 0x8d61c2, 0x77c912, 0x142604, 0x9b4612,
+0xc459c4, 0x44c5c8, 0x91b24d, 0xf31700, 0xad43d4, 0xe54929,
+0x10d5fd, 0xfcbe00, 0xcc941e, 0xeece70, 0xf53e13, 0x80f1ec,
+0xc3e7b3, 0x28f8c7, 0x940593, 0x3e71c1, 0xb3092e, 0xf3450b,
+0x9c1288, 0x7b20ab, 0x9fb52e, 0xc29247, 0x2f327b, 0x6d550c,
+0x90a772, 0x1fe76b, 0x96cb31, 0x4a1679, 0xe27941, 0x89dff4,
+0x9794e8, 0x84e6e2, 0x973199, 0x6bed88, 0x365f5f, 0x0efdbb,
+0xb49a48, 0x6ca467, 0x427271, 0x325d8d, 0xb8159f, 0x09e5bc,
+0x25318d, 0x3974f7, 0x1c0530, 0x010c0d, 0x68084b, 0x58ee2c,
+0x90aa47, 0x02e774, 0x24d6bd, 0xa67df7, 0x72486e, 0xef169f,
+0xa6948e, 0xf691b4, 0x5153d1, 0xf20acf, 0x339820, 0x7e4bf5,
+0x6863b2, 0x5f3edd, 0x035d40, 0x7f8985, 0x295255, 0xc06437,
+0x10d86d, 0x324832, 0x754c5b, 0xd4714e, 0x6e5445, 0xc1090b,
+0x69f52a, 0xd56614, 0x9d0727, 0x50045d, 0xdb3bb4, 0xc576ea,
+0x17f987, 0x7d6b49, 0xba271d, 0x296996, 0xacccc6, 0x5414ad,
+0x6ae290, 0x89d988, 0x50722c, 0xbea404, 0x940777, 0x7030f3,
+0x27fc00, 0xa871ea, 0x49c266, 0x3de064, 0x83dd97, 0x973fa3,
+0xfd9443, 0x8c860d, 0xde4131, 0x9d3992, 0x8c70dd, 0xe7b717,
+0x3bdf08, 0x2b3715, 0xa0805c, 0x93805a, 0x921110, 0xd8e80f,
+0xaf806c, 0x4bffdb, 0x0f9038, 0x761859, 0x15a562, 0xbbcb61,
+0xb989c7, 0xbd4010, 0x04f2d2, 0x277549, 0xf6b6eb, 0xbb22db,
+0xaa140a, 0x2f2689, 0x768364, 0x333b09, 0x1a940e, 0xaa3a51,
+0xc2a31d, 0xaeedaf, 0x12265c, 0x4dc26d, 0x9c7a2d, 0x9756c0,
+0x833f03, 0xf6f009, 0x8c402b, 0x99316d, 0x07b439, 0x15200c,
+0x5bc3d8, 0xc492f5, 0x4badc6, 0xa5ca4e, 0xcd37a7, 0x36a9e6,
+0x9492ab, 0x6842dd, 0xde6319, 0xef8c76, 0x528b68, 0x37dbfc,
+0xaba1ae, 0x3115df, 0xa1ae00, 0xdafb0c, 0x664d64, 0xb705ed,
+0x306529, 0xbf5657, 0x3aff47, 0xb9f96a, 0xf3be75, 0xdf9328,
+0x3080ab, 0xf68c66, 0x15cb04, 0x0622fa, 0x1de4d9, 0xa4b33d,
+0x8f1b57, 0x09cd36, 0xe9424e, 0xa4be13, 0xb52333, 0x1aaaf0,
+0xa8654f, 0xa5c1d2, 0x0f3f0b, 0xcd785b, 0x76f923, 0x048b7b,
+0x721789, 0x53a6c6, 0xe26e6f, 0x00ebef, 0x584a9b, 0xb7dac4,
+0xba66aa, 0xcfcf76, 0x1d02d1, 0x2df1b1, 0xc1998c, 0x77adc3,
+0xda4886, 0xa05df7, 0xf480c6, 0x2ff0ac, 0x9aecdd, 0xbc5c3f,
+0x6dded0, 0x1fc790, 0xb6db2a, 0x3a25a3, 0x9aaf00, 0x9353ad,
+0x0457b6, 0xb42d29, 0x7e804b, 0xa707da, 0x0eaa76, 0xa1597b,
+0x2a1216, 0x2db7dc, 0xfde5fa, 0xfedb89, 0xfdbe89, 0x6c76e4,
+0xfca906, 0x70803e, 0x156e85, 0xff87fd, 0x073e28, 0x336761,
+0x86182a, 0xeabd4d, 0xafe7b3, 0x6e6d8f, 0x396795, 0x5bbf31,
+0x48d784, 0x16df30, 0x432dc7, 0x356125, 0xce70c9, 0xb8cb30,
+0xfd6cbf, 0xa200a4, 0xe46c05, 0xa0dd5a, 0x476f21, 0xd21262,
+0x845cb9, 0x496170, 0xe0566b, 0x015299, 0x375550, 0xb7d51e,
+0xc4f133, 0x5f6e13, 0xe4305d, 0xa92e85, 0xc3b21d, 0x3632a1,
+0xa4b708, 0xd4b1ea, 0x21f716, 0xe4698f, 0x77ff27, 0x80030c,
+0x2d408d, 0xa0cd4f, 0x99a520, 0xd3a2b3, 0x0a5d2f, 0x42f9b4,
+0xcbda11, 0xd0be7d, 0xc1db9b, 0xbd17ab, 0x81a2ca, 0x5c6a08,
+0x17552e, 0x550027, 0xf0147f, 0x8607e1, 0x640b14, 0x8d4196,
+0xdebe87, 0x2afdda, 0xb6256b, 0x34897b, 0xfef305, 0x9ebfb9,
+0x4f6a68, 0xa82a4a, 0x5ac44f, 0xbcf82d, 0x985ad7, 0x95c7f4,
+0x8d4d0d, 0xa63a20, 0x5f57a4, 0xb13f14, 0x953880, 0x0120cc,
+0x86dd71, 0xb6dec9, 0xf560bf, 0x11654d, 0x6b0701, 0xacb08c,
+0xd0c0b2, 0x485551, 0x0efb1e, 0xc37295, 0x3b06a3, 0x3540c0,
+0x7bdc06, 0xcc45e0, 0xfa294e, 0xc8cad6, 0x41f3e8, 0xde647c,
+0xd8649b, 0x31bed9, 0xc397a4, 0xd45877, 0xc5e369, 0x13daf0,
+0x3c3aba, 0x461846, 0x5f7555, 0xf5bdd2, 0xc6926e, 0x5d2eac,
+0xed440e, 0x423e1c, 0x87c461, 0xe9fd29, 0xf3d6e7, 0xca7c22,
+0x35916f, 0xc5e008, 0x8dd7ff, 0xe26a6e, 0xc6fdb0, 0xc10893,
+0x745d7c, 0xb2ad6b, 0x9d6ecd, 0x7b723e, 0x6a11c6, 0xa9cff7,
+0xdf7329, 0xbac9b5, 0x5100b7, 0x0db2e2, 0x24ba74, 0x607de5,
+0x8ad874, 0x2c150d, 0x0c1881, 0x94667e, 0x162901, 0x767a9f,
+0xbefdfd, 0xef4556, 0x367ed9, 0x13d9ec, 0xb9ba8b, 0xfc97c4,
+0x27a831, 0xc36ef1, 0x36c594, 0x56a8d8, 0xb5a8b4, 0x0ecccf,
+0x2d8912, 0x34576f, 0x89562c, 0xe3ce99, 0xb920d6, 0xaa5e6b,
+0x9c2a3e, 0xcc5f11, 0x4a0bfd, 0xfbf4e1, 0x6d3b8e, 0x2c86e2,
+0x84d4e9, 0xa9b4fc, 0xd1eeef, 0xc9352e, 0x61392f, 0x442138,
+0xc8d91b, 0x0afc81, 0x6a4afb, 0xd81c2f, 0x84b453, 0x8c994e,
+0xcc2254, 0xdc552a, 0xd6c6c0, 0x96190b, 0xb8701a, 0x649569,
+0x605a26, 0xee523f, 0x0f117f, 0x11b5f4, 0xf5cbfc, 0x2dbc34,
+0xeebc34, 0xcc5de8, 0x605edd, 0x9b8e67, 0xef3392, 0xb817c9,
+0x9b5861, 0xbc57e1, 0xc68351, 0x103ed8, 0x4871dd, 0xdd1c2d,
+0xa118af, 0x462c21, 0xd7f359, 0x987ad9, 0xc0549e, 0xfa864f,
+0xfc0656, 0xae79e5, 0x362289, 0x22ad38, 0xdc9367, 0xaae855,
+0x382682, 0x9be7ca, 0xa40d51, 0xb13399, 0x0ed7a9, 0x480569,
+0xf0b265, 0xa7887f, 0x974c88, 0x36d1f9, 0xb39221, 0x4a827b,
+0x21cf98, 0xdc9f40, 0x5547dc, 0x3a74e1, 0x42eb67, 0xdf9dfe,
+0x5fd45e, 0xa4677b, 0x7aacba, 0xa2f655, 0x23882b, 0x55ba41,
+0x086e59, 0x862a21, 0x834739, 0xe6e389, 0xd49ee5, 0x40fb49,
+0xe956ff, 0xca0f1c, 0x8a59c5, 0x2bfa94, 0xc5c1d3, 0xcfc50f,
+0xae5adb, 0x86c547, 0x624385, 0x3b8621, 0x94792c, 0x876110,
+0x7b4c2a, 0x1a2c80, 0x12bf43, 0x902688, 0x893c78, 0xe4c4a8,
+0x7bdbe5, 0xc23ac4, 0xeaf426, 0x8a67f7, 0xbf920d, 0x2ba365,
+0xb1933d, 0x0b7cbd, 0xdc51a4, 0x63dd27, 0xdde169, 0x19949a,
+0x9529a8, 0x28ce68, 0xb4ed09, 0x209f44, 0xca984e, 0x638270,
+0x237c7e, 0x32b90f, 0x8ef5a7, 0xe75614, 0x08f121, 0x2a9db5,
+0x4d7e6f, 0x5119a5, 0xabf9b5, 0xd6df82, 0x61dd96, 0x023616,
+0x9f3ac4, 0xa1a283, 0x6ded72, 0x7a8d39, 0xa9b882, 0x5c326b,
+0x5b2746, 0xed3400, 0x7700d2, 0x55f4fc, 0x4d5901, 0x8071e0,
+0xe13f89, 0xb295f3, 0x64a8f1, 0xaea74b, 0x38fc4c, 0xeab2bb,
+0x47270b, 0xabc3a7, 0x34ba60, 0x52dd34, 0xf8563a, 0xeb7e8a,
+0x31bb36, 0x5895b7, 0x47f7a9, 0x94c3aa, 0xd39225, 0x1e7f3e,
+0xd8974e, 0xbba94f, 0xd8ae01, 0xe661b4, 0x393d8e, 0xa523aa,
+0x33068e, 0x1633b5, 0x3bb188, 0x1d3a9d, 0x4013d0, 0xcc1be5,
+0xf862e7, 0x3bf28f, 0x39b5bf, 0x0bc235, 0x22747e, 0xa247c0,
+0xd52d1f, 0x19add3, 0x9094df, 0x9311d0, 0xb42b25, 0x496db2,
+0xe264b2, 0x5ef135, 0x3bc6a4, 0x1a4ad0, 0xaac92e, 0x64e886,
+0x573091, 0x982cfb, 0x311b1a, 0x08728b, 0xbdcee1, 0x60e142,
+0xeb641d, 0xd0bba3, 0xe559d4, 0x597b8c, 0x2a4483, 0xf332ba,
+0xf84867, 0x2c8d1b, 0x2fa9b0, 0x50f3dd, 0xf9f573, 0xdb61b4,
+0xfe233e, 0x6c41a6, 0xeea318, 0x775a26, 0xbc5e5c, 0xcea708,
+0x94dc57, 0xe20196, 0xf1e839, 0xbe4851, 0x5d2d2f, 0x4e9555,
+0xd96ec2, 0xe7d755, 0x6304e0, 0xc02e0e, 0xfc40a0, 0xbbf9b3,
+0x7125a7, 0x222dfb, 0xf619d8, 0x838c1c, 0x6619e6, 0xb20d55,
+0xbb5137, 0x79e809, 0xaf9149, 0x0d73de, 0x0b0da5, 0xce7f58,
+0xac1934, 0x724667, 0x7a1a13, 0x9e26bc, 0x4555e7, 0x585cb5,
+0x711d14, 0x486991, 0x480d60, 0x56adab, 0xd62f64, 0x96ee0c,
+0x212ff3, 0x5d6d88, 0xa67684, 0x95651e, 0xab9e0a, 0x4ddefe,
+0x571010, 0x836a39, 0xf8ea31, 0x9e381d, 0xeac8b1, 0xcac96b,
+0x37f21e, 0xd505e9, 0x984743, 0x9fc56c, 0x0331b7, 0x3b8bf8,
+0x86e56a, 0x8dc343, 0x6230e7, 0x93cfd5, 0x6a8f2d, 0x733005,
+0x1af021, 0xa09fcb, 0x7415a1, 0xd56b23, 0x6ff725, 0x2f4bc7,
+0xb8a591, 0x7fac59, 0x5c55de, 0x212c38, 0xb13296, 0x5cff50,
+0x366262, 0xfa7b16, 0xf4d9a6, 0x2acfe7, 0xf07403, 0xd4d604,
+0x6fd916, 0x31b1bf, 0xcbb450, 0x5bd7c8, 0x0ce194, 0x6bd643,
+0x4fd91c, 0xdf4543, 0x5f3453, 0xe2b5aa, 0xc9aec8, 0x131485,
+0xf9d2bf, 0xbadb9e, 0x76f5b9, 0xaf15cf, 0xca3182, 0x14b56d,
+0xe9fe4d, 0x50fc35, 0xf5aed5, 0xa2d0c1, 0xc96057, 0x192eb6,
+0xe91d92, 0x07d144, 0xaea3c6, 0x343566, 0x26d5b4, 0x3161e2,
+0x37f1a2, 0x209eff, 0x958e23, 0x493798, 0x35f4a6, 0x4bdc02,
+0xc2be13, 0xbe80a0, 0x0b72a3, 0x115c5f, 0x1e1bd1, 0x0db4d3,
+0x869e85, 0x96976b, 0x2ac91f, 0x8a26c2, 0x3070f0, 0x041412,
+0xfc9fa5, 0xf72a38, 0x9c6878, 0xe2aa76, 0x50cfe1, 0x559274,
+0x934e38, 0x0a92f7, 0x5533f0, 0xa63db4, 0x399971, 0xe2b755,
+0xa98a7c, 0x008f19, 0xac54d2, 0x2ea0b4, 0xf5f3e0, 0x60c849,
+0xffd269, 0xae52ce, 0x7a5fdd, 0xe9ce06, 0xfb0ae8, 0xa50cce,
+0xea9d3e, 0x3766dd, 0xb834f5, 0x0da090, 0x846f88, 0x4ae3d5,
+0x099a03, 0x2eae2d, 0xfcb40a, 0xfb9b33, 0xe281dd, 0x1b16ba,
+0xd8c0af, 0xd96b97, 0xb52dc9, 0x9c277f, 0x5951d5, 0x21ccd6,
+0xb6496b, 0x584562, 0xb3baf2, 0xa1a5c4, 0x7ca2cf, 0xa9b93d,
+0x7b7b89, 0x483d38,
+};
+
+static const long double c[] = {
+/* 93 bits of pi/2 */
+#define PI_2_1 c[0]
+ 1.57079632679489661923132169155131424e+00L, /* 3fff921fb54442d18469898cc5100000 */
+
+/* pi/2 - PI_2_1 */
+#define PI_2_1t c[1]
+ 8.84372056613570112025531863263659260e-29L, /* 3fa1c06e0e68948127044533e63a0106 */
+};
+
+int32_t __ieee754_rem_pio2l(long double x, long double *y)
+{
+ long double z, w, t;
+ double tx[8];
+ int64_t exp, n, ix, hx;
+ u_int64_t lx;
+
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+ ix = hx & 0x7fffffffffffffffLL;
+ if (ix <= 0x3ffe921fb54442d1LL) /* x in <-pi/4, pi/4> */
+ {
+ y[0] = x;
+ y[1] = 0;
+ return 0;
+ }
+
+ if (ix < 0x40002d97c7f3321dLL) /* |x| in <pi/4, 3pi/4) */
+ {
+ if (hx > 0)
+ {
+ /* 113 + 93 bit PI is ok */
+ z = x - PI_2_1;
+ y[0] = z - PI_2_1t;
+ y[1] = (z - y[0]) - PI_2_1t;
+ return 1;
+ }
+ else
+ {
+ /* 113 + 93 bit PI is ok */
+ z = x + PI_2_1;
+ y[0] = z + PI_2_1t;
+ y[1] = (z - y[0]) + PI_2_1t;
+ return -1;
+ }
+ }
+
+ if (ix >= 0x7fff000000000000LL) /* x is +=oo or NaN */
+ {
+ y[0] = x - x;
+ y[1] = y[0];
+ return 0;
+ }
+
+ /* Handle large arguments.
+ We split the 113 bits of the mantissa into 5 24bit integers
+ stored in a double array. */
+ exp = (ix >> 48) - 16383 - 23;
+
+ /* This is faster than doing this in floating point, because we
+ have to convert it to integers anyway and like this we can keep
+ both integer and floating point units busy. */
+ tx [0] = (double)(((ix >> 25) & 0x7fffff) | 0x800000);
+ tx [1] = (double)((ix >> 1) & 0xffffff);
+ tx [2] = (double)(((ix << 23) | (lx >> 41)) & 0xffffff);
+ tx [3] = (double)((lx >> 17) & 0xffffff);
+ tx [4] = (double)((lx << 7) & 0xffffff);
+
+ n = __kernel_rem_pio2 (tx, tx + 5, exp, ((lx << 7) & 0xffffff) ? 5 : 4,
+ 3, two_over_pi);
+
+ /* The result is now stored in 3 double values, we need to convert it into
+ two long double values. */
+ t = (long double) tx [6] + (long double) tx [7];
+ w = (long double) tx [5];
+
+ if (hx >= 0)
+ {
+ y[0] = w + t;
+ y[1] = t - (y[0] - w);
+ return n;
+ }
+ else
+ {
+ y[0] = -(w + t);
+ y[1] = -t - (y[0] + w);
+ return -n;
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_remainderl.c b/libc/sysdeps/ieee754/ldbl-128/e_remainderl.c
new file mode 100644
index 000000000..81af247b3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_remainderl.c
@@ -0,0 +1,78 @@
+/* e_fmodl.c -- long double version of e_fmod.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* __ieee754_remainderl(x,p)
+ * Return :
+ * returns x REM p = x - [x/p]*p as if in infinite
+ * precise arithmetic, where [x/p] is the (infinite bit)
+ * integer nearest x/p (in half way case choose the even one).
+ * Method :
+ * Based on fmodl() return x-[x/p]chopped*p exactlp.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double zero = 0.0L;
+#else
+static long double zero = 0.0L;
+#endif
+
+
+#ifdef __STDC__
+ long double __ieee754_remainderl(long double x, long double p)
+#else
+ long double __ieee754_remainderl(x,p)
+ long double x,p;
+#endif
+{
+ int64_t hx,hp;
+ u_int64_t sx,lx,lp;
+ long double p_half;
+
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ GET_LDOUBLE_WORDS64(hp,lp,p);
+ sx = hx&0x8000000000000000ULL;
+ hp &= 0x7fffffffffffffffLL;
+ hx &= 0x7fffffffffffffffLL;
+
+ /* purge off exception values */
+ if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */
+ if((hx>=0x7fff000000000000LL)|| /* x not finite */
+ ((hp>=0x7fff000000000000LL)&& /* p is NaN */
+ (((hp-0x7fff000000000000LL)|lp)!=0)))
+ return (x*p)/(x*p);
+
+
+ if (hp<=0x7ffdffffffffffffLL) x = __ieee754_fmodl(x,p+p); /* now x < 2p */
+ if (((hx-hp)|(lx-lp))==0) return zero*x;
+ x = fabsl(x);
+ p = fabsl(p);
+ if (hp<0x0002000000000000LL) {
+ if(x+x>p) {
+ x-=p;
+ if(x+x>=p) x -= p;
+ }
+ } else {
+ p_half = 0.5L*p;
+ if(x>p_half) {
+ x-=p;
+ if(x>=p_half) x -= p;
+ }
+ }
+ GET_LDOUBLE_MSW64(hx,x);
+ SET_LDOUBLE_MSW64(x,hx^sx);
+ return x;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/e_sinhl.c b/libc/sysdeps/ieee754/ldbl-128/e_sinhl.c
new file mode 100644
index 000000000..93f4179c6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/e_sinhl.c
@@ -0,0 +1,123 @@
+/* e_sinhl.c -- long double version of e_sinh.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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.
+ * ====================================================
+ */
+
+/* Changes for 128-bit long double are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __ieee754_sinhl(x)
+ * Method :
+ * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+ * 1. Replace x by |x| (sinhl(-x) = -sinhl(x)).
+ * 2.
+ * E + E/(E+1)
+ * 0 <= x <= 25 : sinhl(x) := --------------, E=expm1l(x)
+ * 2
+ *
+ * 25 <= x <= lnovft : sinhl(x) := expl(x)/2
+ * lnovft <= x <= ln2ovft: sinhl(x) := expl(x/2)/2 * expl(x/2)
+ * ln2ovft < x : sinhl(x) := x*shuge (overflow)
+ *
+ * Special cases:
+ * sinhl(x) is |x| if x is +INF, -INF, or NaN.
+ * only sinhl(0)=0 is exact for finite x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0, shuge = 1.0e4931L,
+ovf_thresh = 1.1357216553474703894801348310092223067821E4L;
+#else
+static long double one = 1.0, shuge = 1.0e4931L,
+ovf_thresh = 1.1357216553474703894801348310092223067821E4L;
+#endif
+
+#ifdef __STDC__
+long double
+__ieee754_sinhl (long double x)
+#else
+long double
+__ieee754_sinhl (x)
+ long double x;
+#endif
+{
+ long double t, w, h;
+ u_int32_t jx, ix;
+ ieee854_long_double_shape_type u;
+
+ /* Words of |x|. */
+ u.value = x;
+ jx = u.parts32.w0;
+ ix = jx & 0x7fffffff;
+
+ /* x is INF or NaN */
+ if (ix >= 0x7fff0000)
+ return x + x;
+
+ h = 0.5;
+ if (jx & 0x80000000)
+ h = -h;
+
+ /* Absolute value of x. */
+ u.parts32.w0 = ix;
+
+ /* |x| in [0,40], return sign(x)*0.5*(E+E/(E+1))) */
+ if (ix <= 0x40044000)
+ {
+ if (ix < 0x3fc60000) /* |x| < 2^-57 */
+ if (shuge + x > one)
+ return x; /* sinh(tiny) = tiny with inexact */
+ t = __expm1l (u.value);
+ if (ix < 0x3fff0000)
+ return h * (2.0 * t - t * t / (t + one));
+ return h * (t + t / (t + one));
+ }
+
+ /* |x| in [40, log(maxdouble)] return 0.5*exp(|x|) */
+ if (ix <= 0x400c62e3) /* 11356.375 */
+ return h * __ieee754_expl (u.value);
+
+ /* |x| in [log(maxdouble), overflowthreshold]
+ Overflow threshold is log(2 * maxdouble). */
+ if (u.value <= ovf_thresh)
+ {
+ w = __ieee754_expl (0.5 * u.value);
+ t = h * w;
+ return t * w;
+ }
+
+ /* |x| > overflowthreshold, sinhl(x) overflow */
+ return x * shuge;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/ieee754.h b/libc/sysdeps/ieee754/ldbl-128/ieee754.h
new file mode 100644
index 000000000..126025e7a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/ieee754.h
@@ -0,0 +1,171 @@
+/* Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _IEEE754_H
+
+#define _IEEE754_H 1
+#include <features.h>
+
+#include <endian.h>
+
+__BEGIN_DECLS
+
+union ieee754_float
+ {
+ float f;
+
+ /* This is the IEEE 754 single-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int mantissa:23;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int mantissa:23;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int quiet_nan:1;
+ unsigned int mantissa:22;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int mantissa:22;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee_nan;
+ };
+
+#define IEEE754_FLOAT_BIAS 0x7f /* Added to exponent. */
+
+
+union ieee754_double
+ {
+ double d;
+
+ /* This is the IEEE 754 double-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:20;
+ unsigned int mantissa1:32;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:20;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ unsigned int quiet_nan:1;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:19;
+ unsigned int mantissa1:32;
+#else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:19;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+#endif
+ } ieee_nan;
+ };
+
+#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */
+
+
+union ieee854_long_double
+ {
+ long double d;
+
+ /* This is the IEEE 854 quad-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:15;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:16;
+ unsigned int mantissa1:32;
+ unsigned int mantissa2:32;
+ unsigned int mantissa3:32;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa3:32;
+ unsigned int mantissa2:32;
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:16;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:15;
+ unsigned int quiet_nan:1;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:15;
+ unsigned int mantissa1:32;
+ unsigned int mantissa2:32;
+ unsigned int mantissa3:32;
+#else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa3:32;
+ unsigned int mantissa2:32;
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:15;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+#endif
+ } ieee_nan;
+ };
+
+#define IEEE854_LONG_DOUBLE_BIAS 0x3fff /* Added to exponent. */
+
+__END_DECLS
+
+#endif /* ieee754.h */
diff --git a/libc/sysdeps/ieee754/ldbl-128/k_cosl.c b/libc/sysdeps/ieee754/ldbl-128/k_cosl.c
new file mode 100644
index 000000000..06f7ada6a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/k_cosl.c
@@ -0,0 +1,128 @@
+/* Quad-precision floating point cosine on <-pi/4,pi/4>.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+
+static const long double c[] = {
+#define ONE c[0]
+ 1.00000000000000000000000000000000000E+00L, /* 3fff0000000000000000000000000000 */
+
+/* cos x ~ ONE + x^2 ( SCOS1 + SCOS2 * x^2 + ... + SCOS4 * x^6 + SCOS5 * x^8 )
+ x in <0,1/256> */
+#define SCOS1 c[1]
+#define SCOS2 c[2]
+#define SCOS3 c[3]
+#define SCOS4 c[4]
+#define SCOS5 c[5]
+-5.00000000000000000000000000000000000E-01L, /* bffe0000000000000000000000000000 */
+ 4.16666666666666666666666666556146073E-02L, /* 3ffa5555555555555555555555395023 */
+-1.38888888888888888888309442601939728E-03L, /* bff56c16c16c16c16c16a566e42c0375 */
+ 2.48015873015862382987049502531095061E-05L, /* 3fefa01a01a019ee02dcf7da2d6d5444 */
+-2.75573112601362126593516899592158083E-07L, /* bfe927e4f5dce637cb0b54908754bde0 */
+
+/* cos x ~ ONE + x^2 ( COS1 + COS2 * x^2 + ... + COS7 * x^12 + COS8 * x^14 )
+ x in <0,0.1484375> */
+#define COS1 c[6]
+#define COS2 c[7]
+#define COS3 c[8]
+#define COS4 c[9]
+#define COS5 c[10]
+#define COS6 c[11]
+#define COS7 c[12]
+#define COS8 c[13]
+-4.99999999999999999999999999999999759E-01L, /* bffdfffffffffffffffffffffffffffb */
+ 4.16666666666666666666666666651287795E-02L, /* 3ffa5555555555555555555555516f30 */
+-1.38888888888888888888888742314300284E-03L, /* bff56c16c16c16c16c16c16a463dfd0d */
+ 2.48015873015873015867694002851118210E-05L, /* 3fefa01a01a01a01a0195cebe6f3d3a5 */
+-2.75573192239858811636614709689300351E-07L, /* bfe927e4fb7789f5aa8142a22044b51f */
+ 2.08767569877762248667431926878073669E-09L, /* 3fe21eed8eff881d1e9262d7adff4373 */
+-1.14707451049343817400420280514614892E-11L, /* bfda9397496922a9601ed3d4ca48944b */
+ 4.77810092804389587579843296923533297E-14L, /* 3fd2ae5f8197cbcdcaf7c3fb4523414c */
+
+/* sin x ~ ONE * x + x^3 ( SSIN1 + SSIN2 * x^2 + ... + SSIN4 * x^6 + SSIN5 * x^8 )
+ x in <0,1/256> */
+#define SSIN1 c[14]
+#define SSIN2 c[15]
+#define SSIN3 c[16]
+#define SSIN4 c[17]
+#define SSIN5 c[18]
+-1.66666666666666666666666666666666659E-01L, /* bffc5555555555555555555555555555 */
+ 8.33333333333333333333333333146298442E-03L, /* 3ff81111111111111111111110fe195d */
+-1.98412698412698412697726277416810661E-04L, /* bff2a01a01a01a01a019e7121e080d88 */
+ 2.75573192239848624174178393552189149E-06L, /* 3fec71de3a556c640c6aaa51aa02ab41 */
+-2.50521016467996193495359189395805639E-08L, /* bfe5ae644ee90c47dc71839de75b2787 */
+};
+
+#define SINCOSL_COS_HI 0
+#define SINCOSL_COS_LO 1
+#define SINCOSL_SIN_HI 2
+#define SINCOSL_SIN_LO 3
+extern const long double __sincosl_table[];
+
+long double
+__kernel_cosl(long double x, long double y)
+{
+ long double h, l, z, sin_l, cos_l_m1;
+ int64_t ix;
+ u_int32_t tix, hix, index;
+ GET_LDOUBLE_MSW64 (ix, x);
+ tix = ((u_int64_t)ix) >> 32;
+ tix &= ~0x80000000; /* tix = |x|'s high 32 bits */
+ if (tix < 0x3ffc3000) /* |x| < 0.1484375 */
+ {
+ /* Argument is small enough to approximate it by a Chebyshev
+ polynomial of degree 16. */
+ if (tix < 0x3fc60000) /* |x| < 2^-57 */
+ if (!((int)x)) return ONE; /* generate inexact */
+ z = x * x;
+ return ONE + (z*(COS1+z*(COS2+z*(COS3+z*(COS4+
+ z*(COS5+z*(COS6+z*(COS7+z*COS8))))))));
+ }
+ else
+ {
+ /* So that we don't have to use too large polynomial, we find
+ l and h such that x = l + h, where fabsl(l) <= 1.0/256 with 83
+ possible values for h. We look up cosl(h) and sinl(h) in
+ pre-computed tables, compute cosl(l) and sinl(l) using a
+ Chebyshev polynomial of degree 10(11) and compute
+ cosl(h+l) = cosl(h)cosl(l) - sinl(h)sinl(l). */
+ index = 0x3ffe - (tix >> 16);
+ hix = (tix + (0x200 << index)) & (0xfffffc00 << index);
+ x = fabsl (x);
+ switch (index)
+ {
+ case 0: index = ((45 << 10) + hix - 0x3ffe0000) >> 8; break;
+ case 1: index = ((13 << 11) + hix - 0x3ffd0000) >> 9; break;
+ default:
+ case 2: index = (hix - 0x3ffc3000) >> 10; break;
+ }
+
+ SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0);
+ l = y - (h - x);
+ z = l * l;
+ sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5)))));
+ cos_l_m1 = z*(SCOS1+z*(SCOS2+z*(SCOS3+z*(SCOS4+z*SCOS5))));
+ return __sincosl_table [index + SINCOSL_COS_HI]
+ + (__sincosl_table [index + SINCOSL_COS_LO]
+ - (__sincosl_table [index + SINCOSL_SIN_HI] * sin_l
+ - __sincosl_table [index + SINCOSL_COS_HI] * cos_l_m1));
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/k_sincosl.c b/libc/sysdeps/ieee754/ldbl-128/k_sincosl.c
new file mode 100644
index 000000000..85f9c90df
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/k_sincosl.c
@@ -0,0 +1,163 @@
+/* Quad-precision floating point sine and cosine on <-pi/4,pi/4>.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+
+static const long double c[] = {
+#define ONE c[0]
+ 1.00000000000000000000000000000000000E+00L, /* 3fff0000000000000000000000000000 */
+
+/* cos x ~ ONE + x^2 ( SCOS1 + SCOS2 * x^2 + ... + SCOS4 * x^6 + SCOS5 * x^8 )
+ x in <0,1/256> */
+#define SCOS1 c[1]
+#define SCOS2 c[2]
+#define SCOS3 c[3]
+#define SCOS4 c[4]
+#define SCOS5 c[5]
+-5.00000000000000000000000000000000000E-01L, /* bffe0000000000000000000000000000 */
+ 4.16666666666666666666666666556146073E-02L, /* 3ffa5555555555555555555555395023 */
+-1.38888888888888888888309442601939728E-03L, /* bff56c16c16c16c16c16a566e42c0375 */
+ 2.48015873015862382987049502531095061E-05L, /* 3fefa01a01a019ee02dcf7da2d6d5444 */
+-2.75573112601362126593516899592158083E-07L, /* bfe927e4f5dce637cb0b54908754bde0 */
+
+/* cos x ~ ONE + x^2 ( COS1 + COS2 * x^2 + ... + COS7 * x^12 + COS8 * x^14 )
+ x in <0,0.1484375> */
+#define COS1 c[6]
+#define COS2 c[7]
+#define COS3 c[8]
+#define COS4 c[9]
+#define COS5 c[10]
+#define COS6 c[11]
+#define COS7 c[12]
+#define COS8 c[13]
+-4.99999999999999999999999999999999759E-01L, /* bffdfffffffffffffffffffffffffffb */
+ 4.16666666666666666666666666651287795E-02L, /* 3ffa5555555555555555555555516f30 */
+-1.38888888888888888888888742314300284E-03L, /* bff56c16c16c16c16c16c16a463dfd0d */
+ 2.48015873015873015867694002851118210E-05L, /* 3fefa01a01a01a01a0195cebe6f3d3a5 */
+-2.75573192239858811636614709689300351E-07L, /* bfe927e4fb7789f5aa8142a22044b51f */
+ 2.08767569877762248667431926878073669E-09L, /* 3fe21eed8eff881d1e9262d7adff4373 */
+-1.14707451049343817400420280514614892E-11L, /* bfda9397496922a9601ed3d4ca48944b */
+ 4.77810092804389587579843296923533297E-14L, /* 3fd2ae5f8197cbcdcaf7c3fb4523414c */
+
+/* sin x ~ ONE * x + x^3 ( SSIN1 + SSIN2 * x^2 + ... + SSIN4 * x^6 + SSIN5 * x^8 )
+ x in <0,1/256> */
+#define SSIN1 c[14]
+#define SSIN2 c[15]
+#define SSIN3 c[16]
+#define SSIN4 c[17]
+#define SSIN5 c[18]
+-1.66666666666666666666666666666666659E-01L, /* bffc5555555555555555555555555555 */
+ 8.33333333333333333333333333146298442E-03L, /* 3ff81111111111111111111110fe195d */
+-1.98412698412698412697726277416810661E-04L, /* bff2a01a01a01a01a019e7121e080d88 */
+ 2.75573192239848624174178393552189149E-06L, /* 3fec71de3a556c640c6aaa51aa02ab41 */
+-2.50521016467996193495359189395805639E-08L, /* bfe5ae644ee90c47dc71839de75b2787 */
+
+/* sin x ~ ONE * x + x^3 ( SIN1 + SIN2 * x^2 + ... + SIN7 * x^12 + SIN8 * x^14 )
+ x in <0,0.1484375> */
+#define SIN1 c[19]
+#define SIN2 c[20]
+#define SIN3 c[21]
+#define SIN4 c[22]
+#define SIN5 c[23]
+#define SIN6 c[24]
+#define SIN7 c[25]
+#define SIN8 c[26]
+-1.66666666666666666666666666666666538e-01L, /* bffc5555555555555555555555555550 */
+ 8.33333333333333333333333333307532934e-03L, /* 3ff811111111111111111111110e7340 */
+-1.98412698412698412698412534478712057e-04L, /* bff2a01a01a01a01a01a019e7a626296 */
+ 2.75573192239858906520896496653095890e-06L, /* 3fec71de3a556c7338fa38527474b8f5 */
+-2.50521083854417116999224301266655662e-08L, /* bfe5ae64567f544e16c7de65c2ea551f */
+ 1.60590438367608957516841576404938118e-10L, /* 3fde6124613a811480538a9a41957115 */
+-7.64716343504264506714019494041582610e-13L, /* bfd6ae7f3d5aef30c7bc660b060ef365 */
+ 2.81068754939739570236322404393398135e-15L, /* 3fce9510115aabf87aceb2022a9a9180 */
+};
+
+#define SINCOSL_COS_HI 0
+#define SINCOSL_COS_LO 1
+#define SINCOSL_SIN_HI 2
+#define SINCOSL_SIN_LO 3
+extern const long double __sincosl_table[];
+
+void
+__kernel_sincosl(long double x, long double y, long double *sinx, long double *cosx, int iy)
+{
+ long double h, l, z, sin_l, cos_l_m1;
+ int64_t ix;
+ u_int32_t tix, hix, index;
+ GET_LDOUBLE_MSW64 (ix, x);
+ tix = ((u_int64_t)ix) >> 32;
+ tix &= ~0x80000000; /* tix = |x|'s high 32 bits */
+ if (tix < 0x3ffc3000) /* |x| < 0.1484375 */
+ {
+ /* Argument is small enough to approximate it by a Chebyshev
+ polynomial of degree 16(17). */
+ if (tix < 0x3fc60000) /* |x| < 2^-57 */
+ if (!((int)x)) /* generate inexact */
+ {
+ *sinx = x;
+ *cosx = ONE;
+ return;
+ }
+ z = x * x;
+ *sinx = x + (x * (z*(SIN1+z*(SIN2+z*(SIN3+z*(SIN4+
+ z*(SIN5+z*(SIN6+z*(SIN7+z*SIN8)))))))));
+ *cosx = ONE + (z*(COS1+z*(COS2+z*(COS3+z*(COS4+
+ z*(COS5+z*(COS6+z*(COS7+z*COS8))))))));
+ }
+ else
+ {
+ /* So that we don't have to use too large polynomial, we find
+ l and h such that x = l + h, where fabsl(l) <= 1.0/256 with 83
+ possible values for h. We look up cosl(h) and sinl(h) in
+ pre-computed tables, compute cosl(l) and sinl(l) using a
+ Chebyshev polynomial of degree 10(11) and compute
+ sinl(h+l) = sinl(h)cosl(l) + cosl(h)sinl(l) and
+ cosl(h+l) = cosl(h)cosl(l) - sinl(h)sinl(l). */
+ index = 0x3ffe - (tix >> 16);
+ hix = (tix + (0x200 << index)) & (0xfffffc00 << index);
+ x = fabsl (x);
+ switch (index)
+ {
+ case 0: index = ((45 << 10) + hix - 0x3ffe0000) >> 8; break;
+ case 1: index = ((13 << 11) + hix - 0x3ffd0000) >> 9; break;
+ default:
+ case 2: index = (hix - 0x3ffc3000) >> 10; break;
+ }
+
+ SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0);
+ if (iy)
+ l = y - (h - x);
+ else
+ l = x - h;
+ z = l * l;
+ sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5)))));
+ cos_l_m1 = z*(SCOS1+z*(SCOS2+z*(SCOS3+z*(SCOS4+z*SCOS5))));
+ z = __sincosl_table [index + SINCOSL_SIN_HI]
+ + (__sincosl_table [index + SINCOSL_SIN_LO]
+ + (__sincosl_table [index + SINCOSL_SIN_HI] * cos_l_m1)
+ + (__sincosl_table [index + SINCOSL_COS_HI] * sin_l));
+ *sinx = (ix < 0) ? -z : z;
+ *cosx = __sincosl_table [index + SINCOSL_COS_HI]
+ + (__sincosl_table [index + SINCOSL_COS_LO]
+ - (__sincosl_table [index + SINCOSL_SIN_HI] * sin_l
+ - __sincosl_table [index + SINCOSL_COS_HI] * cos_l_m1));
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/k_sinl.c b/libc/sysdeps/ieee754/ldbl-128/k_sinl.c
new file mode 100644
index 000000000..b0eaef00c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/k_sinl.c
@@ -0,0 +1,132 @@
+/* Quad-precision floating point sine on <-pi/4,pi/4>.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+
+static const long double c[] = {
+#define ONE c[0]
+ 1.00000000000000000000000000000000000E+00L, /* 3fff0000000000000000000000000000 */
+
+/* cos x ~ ONE + x^2 ( SCOS1 + SCOS2 * x^2 + ... + SCOS4 * x^6 + SCOS5 * x^8 )
+ x in <0,1/256> */
+#define SCOS1 c[1]
+#define SCOS2 c[2]
+#define SCOS3 c[3]
+#define SCOS4 c[4]
+#define SCOS5 c[5]
+-5.00000000000000000000000000000000000E-01L, /* bffe0000000000000000000000000000 */
+ 4.16666666666666666666666666556146073E-02L, /* 3ffa5555555555555555555555395023 */
+-1.38888888888888888888309442601939728E-03L, /* bff56c16c16c16c16c16a566e42c0375 */
+ 2.48015873015862382987049502531095061E-05L, /* 3fefa01a01a019ee02dcf7da2d6d5444 */
+-2.75573112601362126593516899592158083E-07L, /* bfe927e4f5dce637cb0b54908754bde0 */
+
+/* sin x ~ ONE * x + x^3 ( SIN1 + SIN2 * x^2 + ... + SIN7 * x^12 + SIN8 * x^14 )
+ x in <0,0.1484375> */
+#define SIN1 c[6]
+#define SIN2 c[7]
+#define SIN3 c[8]
+#define SIN4 c[9]
+#define SIN5 c[10]
+#define SIN6 c[11]
+#define SIN7 c[12]
+#define SIN8 c[13]
+-1.66666666666666666666666666666666538e-01L, /* bffc5555555555555555555555555550 */
+ 8.33333333333333333333333333307532934e-03L, /* 3ff811111111111111111111110e7340 */
+-1.98412698412698412698412534478712057e-04L, /* bff2a01a01a01a01a01a019e7a626296 */
+ 2.75573192239858906520896496653095890e-06L, /* 3fec71de3a556c7338fa38527474b8f5 */
+-2.50521083854417116999224301266655662e-08L, /* bfe5ae64567f544e16c7de65c2ea551f */
+ 1.60590438367608957516841576404938118e-10L, /* 3fde6124613a811480538a9a41957115 */
+-7.64716343504264506714019494041582610e-13L, /* bfd6ae7f3d5aef30c7bc660b060ef365 */
+ 2.81068754939739570236322404393398135e-15L, /* 3fce9510115aabf87aceb2022a9a9180 */
+
+/* sin x ~ ONE * x + x^3 ( SSIN1 + SSIN2 * x^2 + ... + SSIN4 * x^6 + SSIN5 * x^8 )
+ x in <0,1/256> */
+#define SSIN1 c[14]
+#define SSIN2 c[15]
+#define SSIN3 c[16]
+#define SSIN4 c[17]
+#define SSIN5 c[18]
+-1.66666666666666666666666666666666659E-01L, /* bffc5555555555555555555555555555 */
+ 8.33333333333333333333333333146298442E-03L, /* 3ff81111111111111111111110fe195d */
+-1.98412698412698412697726277416810661E-04L, /* bff2a01a01a01a01a019e7121e080d88 */
+ 2.75573192239848624174178393552189149E-06L, /* 3fec71de3a556c640c6aaa51aa02ab41 */
+-2.50521016467996193495359189395805639E-08L, /* bfe5ae644ee90c47dc71839de75b2787 */
+};
+
+#define SINCOSL_COS_HI 0
+#define SINCOSL_COS_LO 1
+#define SINCOSL_SIN_HI 2
+#define SINCOSL_SIN_LO 3
+extern const long double __sincosl_table[];
+
+long double
+__kernel_sinl(long double x, long double y, int iy)
+{
+ long double h, l, z, sin_l, cos_l_m1;
+ int64_t ix;
+ u_int32_t tix, hix, index;
+ GET_LDOUBLE_MSW64 (ix, x);
+ tix = ((u_int64_t)ix) >> 32;
+ tix &= ~0x80000000; /* tix = |x|'s high 32 bits */
+ if (tix < 0x3ffc3000) /* |x| < 0.1484375 */
+ {
+ /* Argument is small enough to approximate it by a Chebyshev
+ polynomial of degree 17. */
+ if (tix < 0x3fc60000) /* |x| < 2^-57 */
+ if (!((int)x)) return x; /* generate inexact */
+ z = x * x;
+ return x + (x * (z*(SIN1+z*(SIN2+z*(SIN3+z*(SIN4+
+ z*(SIN5+z*(SIN6+z*(SIN7+z*SIN8)))))))));
+ }
+ else
+ {
+ /* So that we don't have to use too large polynomial, we find
+ l and h such that x = l + h, where fabsl(l) <= 1.0/256 with 83
+ possible values for h. We look up cosl(h) and sinl(h) in
+ pre-computed tables, compute cosl(l) and sinl(l) using a
+ Chebyshev polynomial of degree 10(11) and compute
+ sinl(h+l) = sinl(h)cosl(l) + cosl(h)sinl(l). */
+ index = 0x3ffe - (tix >> 16);
+ hix = (tix + (0x200 << index)) & (0xfffffc00 << index);
+ x = fabsl (x);
+ switch (index)
+ {
+ case 0: index = ((45 << 10) + hix - 0x3ffe0000) >> 8; break;
+ case 1: index = ((13 << 11) + hix - 0x3ffd0000) >> 9; break;
+ default:
+ case 2: index = (hix - 0x3ffc3000) >> 10; break;
+ }
+
+ SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0);
+ if (iy)
+ l = y - (h - x);
+ else
+ l = x - h;
+ z = l * l;
+ sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5)))));
+ cos_l_m1 = z*(SCOS1+z*(SCOS2+z*(SCOS3+z*(SCOS4+z*SCOS5))));
+ z = __sincosl_table [index + SINCOSL_SIN_HI]
+ + (__sincosl_table [index + SINCOSL_SIN_LO]
+ + (__sincosl_table [index + SINCOSL_SIN_HI] * cos_l_m1)
+ + (__sincosl_table [index + SINCOSL_COS_HI] * sin_l));
+ return (ix < 0) ? -z : z;
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/k_tanl.c b/libc/sysdeps/ieee754/ldbl-128/k_tanl.c
new file mode 100644
index 000000000..3cb8ae309
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/k_tanl.c
@@ -0,0 +1,164 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/*
+ Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __kernel_tanl( x, y, k )
+ * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input k indicates whether tan (if k=1) or
+ * -1/tan (if k= -1) is returned.
+ *
+ * Algorithm
+ * 1. Since tan(-x) = -tan(x), we need only to consider positive x.
+ * 2. if x < 2^-57, return x with inexact if x!=0.
+ * 3. tan(x) is approximated by a rational form x + x^3 / 3 + x^5 R(x^2)
+ * on [0,0.67433].
+ *
+ * Note: tan(x+y) = tan(x) + tan'(x)*y
+ * ~ tan(x) + (1+x*x)*y
+ * Therefore, for better accuracy in computing tan(x+y), let
+ * r = x^3 * R(x^2)
+ * then
+ * tan(x+y) = x + (x^3 / 3 + (x^2 *(r+y)+y))
+ *
+ * 4. For x in [0.67433,pi/4], let y = pi/4 - x, then
+ * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
+ * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
+ */
+
+#include "math.h"
+#include "math_private.h"
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ one = 1.0L,
+ pio4hi = 7.8539816339744830961566084581987569936977E-1L,
+ pio4lo = 2.1679525325309452561992610065108379921906E-35L,
+
+ /* tan x = x + x^3 / 3 + x^5 T(x^2)/U(x^2)
+ 0 <= x <= 0.6743316650390625
+ Peak relative error 8.0e-36 */
+ TH = 3.333333333333333333333333333333333333333E-1L,
+ T0 = -1.813014711743583437742363284336855889393E7L,
+ T1 = 1.320767960008972224312740075083259247618E6L,
+ T2 = -2.626775478255838182468651821863299023956E4L,
+ T3 = 1.764573356488504935415411383687150199315E2L,
+ T4 = -3.333267763822178690794678978979803526092E-1L,
+
+ U0 = -1.359761033807687578306772463253710042010E8L,
+ U1 = 6.494370630656893175666729313065113194784E7L,
+ U2 = -4.180787672237927475505536849168729386782E6L,
+ U3 = 8.031643765106170040139966622980914621521E4L,
+ U4 = -5.323131271912475695157127875560667378597E2L;
+ /* 1.000000000000000000000000000000000000000E0 */
+
+
+#ifdef __STDC__
+long double
+__kernel_tanl (long double x, long double y, int iy)
+#else
+long double
+__kernel_tanl (x, y, iy)
+ long double x, y;
+ int iy;
+#endif
+{
+ long double z, r, v, w, s;
+ int32_t ix, sign;
+ ieee854_long_double_shape_type u, u1;
+
+ u.value = x;
+ ix = u.parts32.w0 & 0x7fffffff;
+ if (ix < 0x3fc60000) /* x < 2**-57 */
+ {
+ if ((int) x == 0)
+ { /* generate inexact */
+ if ((ix | u.parts32.w1 | u.parts32.w2 | u.parts32.w3
+ | (iy + 1)) == 0)
+ return one / fabs (x);
+ else
+ return (iy == 1) ? x : -one / x;
+ }
+ }
+ if (ix >= 0x3ffe5942) /* |x| >= 0.6743316650390625 */
+ {
+ if ((u.parts32.w0 & 0x80000000) != 0)
+ {
+ x = -x;
+ y = -y;
+ sign = -1;
+ }
+ else
+ sign = 1;
+ z = pio4hi - x;
+ w = pio4lo - y;
+ x = z + w;
+ y = 0.0;
+ }
+ z = x * x;
+ r = T0 + z * (T1 + z * (T2 + z * (T3 + z * T4)));
+ v = U0 + z * (U1 + z * (U2 + z * (U3 + z * (U4 + z))));
+ r = r / v;
+
+ s = z * x;
+ r = y + z * (s * r + y);
+ r += TH * s;
+ w = x + r;
+ if (ix >= 0x3ffe5942)
+ {
+ v = (long double) iy;
+ w = (v - 2.0 * (x - (w * w / (w + v) - r)));
+ if (sign < 0)
+ w = -w;
+ return w;
+ }
+ if (iy == 1)
+ return w;
+ else
+ { /* if allow error up to 2 ulp,
+ simply return -1.0/(x+r) here */
+ /* compute -1.0/(x+r) accurately */
+ u1.value = w;
+ u1.parts32.w2 = 0;
+ u1.parts32.w3 = 0;
+ v = r - (u1.value - x); /* u1+v = r+x */
+ z = -1.0 / w;
+ u.value = z;
+ u.parts32.w2 = 0;
+ u.parts32.w3 = 0;
+ s = 1.0 + u.value * u1.value;
+ return u.value + z * (s + u.value * v);
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/ldbl2mpn.c b/libc/sysdeps/ieee754/ldbl-128/ldbl2mpn.c
new file mode 100644
index 000000000..a49fac674
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/ldbl2mpn.c
@@ -0,0 +1,141 @@
+/* Copyright (C) 1995,1996,1997,1998,1999,2002,2003
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include <ieee754.h>
+#include <float.h>
+#include <math.h>
+#include <stdlib.h>
+
+/* Convert a `long double' in IEEE854 quad-precision format to a
+ multi-precision integer representing the significand scaled up by its
+ number of bits (113 for long double) and an integral power of two
+ (MPN frexpl). */
+
+mp_size_t
+__mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
+ int *expt, int *is_neg,
+ long double value)
+{
+ union ieee854_long_double u;
+ u.d = value;
+
+ *is_neg = u.ieee.negative;
+ *expt = (int) u.ieee.exponent - IEEE854_LONG_DOUBLE_BIAS;
+
+#if BITS_PER_MP_LIMB == 32
+ res_ptr[0] = u.ieee.mantissa3; /* Low-order 32 bits of fraction. */
+ res_ptr[1] = u.ieee.mantissa2;
+ res_ptr[2] = u.ieee.mantissa1;
+ res_ptr[3] = u.ieee.mantissa0; /* High-order 32 bits. */
+ #define N 4
+#elif BITS_PER_MP_LIMB == 64
+ /* Hopefully the compiler will combine the two bitfield extracts
+ and this composition into just the original quadword extract. */
+ res_ptr[0] = ((mp_limb_t) u.ieee.mantissa2 << 32) | u.ieee.mantissa3;
+ res_ptr[1] = ((mp_limb_t) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
+ #define N 2
+#else
+ #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+/* The format does not fill the last limb. There are some zeros. */
+#define NUM_LEADING_ZEROS (BITS_PER_MP_LIMB \
+ - (LDBL_MANT_DIG - ((N - 1) * BITS_PER_MP_LIMB)))
+
+ if (u.ieee.exponent == 0)
+ {
+ /* A biased exponent of zero is a special case.
+ Either it is a zero or it is a denormal number. */
+ if (res_ptr[0] == 0 && res_ptr[1] == 0
+ && res_ptr[N - 2] == 0 && res_ptr[N - 1] == 0) /* Assumes N<=4. */
+ /* It's zero. */
+ *expt = 0;
+ else
+ {
+ /* It is a denormal number, meaning it has no implicit leading
+ one bit, and its exponent is in fact the format minimum. */
+ int cnt;
+
+#if N == 2
+ if (res_ptr[N - 1] != 0)
+ {
+ count_leading_zeros (cnt, res_ptr[N - 1]);
+ cnt -= NUM_LEADING_ZEROS;
+ res_ptr[N - 1] = res_ptr[N - 1] << cnt
+ | (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt));
+ res_ptr[0] <<= cnt;
+ *expt = LDBL_MIN_EXP - 1 - cnt;
+ }
+ else
+ {
+ count_leading_zeros (cnt, res_ptr[0]);
+ if (cnt >= NUM_LEADING_ZEROS)
+ {
+ res_ptr[N - 1] = res_ptr[0] << (cnt - NUM_LEADING_ZEROS);
+ res_ptr[0] = 0;
+ }
+ else
+ {
+ res_ptr[N - 1] = res_ptr[0] >> (NUM_LEADING_ZEROS - cnt);
+ res_ptr[0] <<= BITS_PER_MP_LIMB - (NUM_LEADING_ZEROS - cnt);
+ }
+ *expt = LDBL_MIN_EXP - 1
+ - (BITS_PER_MP_LIMB - NUM_LEADING_ZEROS) - cnt;
+ }
+#else
+ int j, k, l;
+
+ for (j = N - 1; j > 0; j--)
+ if (res_ptr[j] != 0)
+ break;
+
+ count_leading_zeros (cnt, res_ptr[j]);
+ cnt -= NUM_LEADING_ZEROS;
+ l = N - 1 - j;
+ if (cnt < 0)
+ {
+ cnt += BITS_PER_MP_LIMB;
+ l--;
+ }
+ if (!cnt)
+ for (k = N - 1; k >= l; k--)
+ res_ptr[k] = res_ptr[k-l];
+ else
+ {
+ for (k = N - 1; k > l; k--)
+ res_ptr[k] = res_ptr[k-l] << cnt
+ | res_ptr[k-l-1] >> (BITS_PER_MP_LIMB - cnt);
+ res_ptr[k--] = res_ptr[0] << cnt;
+ }
+
+ for (; k >= 0; k--)
+ res_ptr[k] = 0;
+ *expt = LDBL_MIN_EXP - 1 - l * BITS_PER_MP_LIMB - cnt;
+#endif
+ }
+ }
+ else
+ /* Add the implicit leading one bit for a normalized number. */
+ res_ptr[N - 1] |= (mp_limb_t) 1 << (LDBL_MANT_DIG - 1
+ - ((N - 1) * BITS_PER_MP_LIMB));
+
+ return N;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/math_ldbl.h b/libc/sysdeps/ieee754/ldbl-128/math_ldbl.h
new file mode 100644
index 000000000..b3faa0484
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/math_ldbl.h
@@ -0,0 +1,90 @@
+#ifndef _MATH_PRIVATE_H_
+#error "Never use <math_ldbl.h> directly; include <math_private.h> instead."
+#endif
+
+/* A union which permits us to convert between a long double and
+ four 32 bit ints or two 64 bit ints. */
+
+#if __FLOAT_WORD_ORDER == BIG_ENDIAN
+
+typedef union
+{
+ long double value;
+ struct
+ {
+ u_int64_t msw;
+ u_int64_t lsw;
+ } parts64;
+ struct
+ {
+ u_int32_t w0, w1, w2, w3;
+ } parts32;
+} ieee854_long_double_shape_type;
+
+#endif
+
+#if __FLOAT_WORD_ORDER == LITTLE_ENDIAN
+
+typedef union
+{
+ long double value;
+ struct
+ {
+ u_int64_t lsw;
+ u_int64_t msw;
+ } parts64;
+ struct
+ {
+ u_int32_t w3, w2, w1, w0;
+ } parts32;
+} ieee854_long_double_shape_type;
+
+#endif
+
+/* Get two 64 bit ints from a long double. */
+
+#define GET_LDOUBLE_WORDS64(ix0,ix1,d) \
+do { \
+ ieee854_long_double_shape_type qw_u; \
+ qw_u.value = (d); \
+ (ix0) = qw_u.parts64.msw; \
+ (ix1) = qw_u.parts64.lsw; \
+} while (0)
+
+/* Set a long double from two 64 bit ints. */
+
+#define SET_LDOUBLE_WORDS64(d,ix0,ix1) \
+do { \
+ ieee854_long_double_shape_type qw_u; \
+ qw_u.parts64.msw = (ix0); \
+ qw_u.parts64.lsw = (ix1); \
+ (d) = qw_u.value; \
+} while (0)
+
+/* Get the more significant 64 bits of a long double mantissa. */
+
+#define GET_LDOUBLE_MSW64(v,d) \
+do { \
+ ieee854_long_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ (v) = sh_u.parts64.msw; \
+} while (0)
+
+/* Set the more significant 64 bits of a long double mantissa from an int. */
+
+#define SET_LDOUBLE_MSW64(d,v) \
+do { \
+ ieee854_long_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ sh_u.parts64.msw = (v); \
+ (d) = sh_u.value; \
+} while (0)
+
+/* Get the least significant 64 bits of a long double mantissa. */
+
+#define GET_LDOUBLE_LSW64(v,d) \
+do { \
+ ieee854_long_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ (v) = sh_u.parts64.lsw; \
+} while (0)
diff --git a/libc/sysdeps/ieee754/ldbl-128/mpn2ldbl.c b/libc/sysdeps/ieee754/ldbl-128/mpn2ldbl.c
new file mode 100644
index 000000000..37e2817db
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/mpn2ldbl.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1995,1996,1997,1998,1999,2002,2003
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include <ieee754.h>
+#include <float.h>
+#include <math.h>
+
+/* Convert a multi-precision integer of the needed number of bits (113 for
+ long double) and an integral power of two to a `long double' in IEEE854
+ quad-precision format. */
+
+long double
+__mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign)
+{
+ union ieee854_long_double u;
+
+ u.ieee.negative = sign;
+ u.ieee.exponent = expt + IEEE854_LONG_DOUBLE_BIAS;
+#if BITS_PER_MP_LIMB == 32
+ u.ieee.mantissa3 = frac_ptr[0];
+ u.ieee.mantissa2 = frac_ptr[1];
+ u.ieee.mantissa1 = frac_ptr[2];
+ u.ieee.mantissa0 = frac_ptr[3] & (((mp_limb_t) 1
+ << (LDBL_MANT_DIG - 96)) - 1);
+#elif BITS_PER_MP_LIMB == 64
+ u.ieee.mantissa3 = frac_ptr[0] & (((mp_limb_t) 1 << 32) - 1);
+ u.ieee.mantissa2 = frac_ptr[0] >> 32;
+ u.ieee.mantissa1 = frac_ptr[1] & (((mp_limb_t) 1 << 32) - 1);
+ u.ieee.mantissa0 = (frac_ptr[1] >> 32) & (((mp_limb_t) 1
+ << (LDBL_MANT_DIG - 96)) - 1);
+#else
+ #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+
+ return u.d;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/printf_fphex.c b/libc/sysdeps/ieee754/ldbl-128/printf_fphex.c
new file mode 100644
index 000000000..361a9baa0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/printf_fphex.c
@@ -0,0 +1,106 @@
+/* Print floating point number in hexadecimal notation according to
+ ISO C99.
+ Copyright (C) 1997, 1998, 1999, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define PRINT_FPHEX_LONG_DOUBLE \
+do { \
+ /* We have 112 bits of mantissa plus one implicit digit. Since \
+ 112 bits are representable without rest using hexadecimal \
+ digits we use only the implicit digits for the number before \
+ the decimal point. */ \
+ unsigned long long int num0, num1; \
+ \
+ assert (sizeof (long double) == 16); \
+ \
+ num0 = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \
+ | fpnum.ldbl.ieee.mantissa1); \
+ num1 = (((unsigned long long int) fpnum.ldbl.ieee.mantissa2) << 32 \
+ | fpnum.ldbl.ieee.mantissa3); \
+ \
+ zero_mantissa = (num0|num1) == 0; \
+ \
+ if (sizeof (unsigned long int) > 6) \
+ { \
+ numstr = _itoa_word (num1, numbuf + sizeof numbuf, 16, \
+ info->spec == 'A'); \
+ wnumstr = _itowa_word (num1, \
+ wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),\
+ 16, info->spec == 'A'); \
+ } \
+ else \
+ { \
+ numstr = _itoa (num1, numbuf + sizeof numbuf, 16, \
+ info->spec == 'A'); \
+ wnumstr = _itowa (num1, \
+ wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t), \
+ 16, info->spec == 'A'); \
+ } \
+ \
+ while (numstr > numbuf + (sizeof numbuf - 64 / 4)) \
+ { \
+ *--numstr = '0'; \
+ *--wnumstr = L'0'; \
+ } \
+ \
+ if (sizeof (unsigned long int) > 6) \
+ { \
+ numstr = _itoa_word (num0, numstr, 16, info->spec == 'A'); \
+ wnumstr = _itowa_word (num0, wnumstr, 16, info->spec == 'A'); \
+ } \
+ else \
+ { \
+ numstr = _itoa (num0, numstr, 16, info->spec == 'A'); \
+ wnumstr = _itowa (num0, wnumstr, 16, info->spec == 'A'); \
+ } \
+ \
+ /* Fill with zeroes. */ \
+ while (numstr > numbuf + (sizeof numbuf - 112 / 4)) \
+ { \
+ *--numstr = '0'; \
+ *--wnumstr = L'0'; \
+ } \
+ \
+ leading = fpnum.ldbl.ieee.exponent == 0 ? '0' : '1'; \
+ \
+ exponent = fpnum.ldbl.ieee.exponent; \
+ \
+ if (exponent == 0) \
+ { \
+ if (zero_mantissa) \
+ expnegative = 0; \
+ else \
+ { \
+ /* This is a denormalized number. */ \
+ expnegative = 1; \
+ exponent = IEEE854_LONG_DOUBLE_BIAS - 1; \
+ } \
+ } \
+ else if (exponent >= IEEE854_LONG_DOUBLE_BIAS) \
+ { \
+ expnegative = 0; \
+ exponent -= IEEE854_LONG_DOUBLE_BIAS; \
+ } \
+ else \
+ { \
+ expnegative = 1; \
+ exponent = -(exponent - IEEE854_LONG_DOUBLE_BIAS); \
+ } \
+} while (0)
+
+#include <stdio-common/printf_fphex.c>
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_asinhl.c b/libc/sysdeps/ieee754/ldbl-128/s_asinhl.c
new file mode 100644
index 000000000..98ad83040
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_asinhl.c
@@ -0,0 +1,87 @@
+/* s_asinhl.c -- long double version of s_asinh.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* asinhl(x)
+ * Method :
+ * Based on
+ * asinhl(x) = signl(x) * logl [ |x| + sqrtl(x*x+1) ]
+ * we have
+ * asinhl(x) := x if 1+x*x=1,
+ * := signl(x)*(logl(x)+ln2)) for large |x|, else
+ * := signl(x)*logl(2|x|+1/(|x|+sqrtl(x*x+1))) if|x|>2, else
+ * := signl(x)*log1pl(|x| + x^2/(1 + sqrtl(1+x^2)))
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ one = 1.0L,
+ ln2 = 6.931471805599453094172321214581765681e-1L,
+ huge = 1.0e+4900L;
+
+#ifdef __STDC__
+long double
+__asinhl (long double x)
+#else
+long double
+__asinhl (x)
+ long double x;
+#endif
+{
+ long double t, w;
+ int32_t ix, sign;
+ ieee854_long_double_shape_type u;
+
+ u.value = x;
+ sign = u.parts32.w0;
+ ix = sign & 0x7fffffff;
+ if (ix == 0x7fff0000)
+ return x + x; /* x is inf or NaN */
+ if (ix < 0x3fc70000)
+ { /* |x| < 2^ -56 */
+ if (huge + x > one)
+ return x; /* return x inexact except 0 */
+ }
+ u.parts32.w0 = ix;
+ if (ix > 0x40350000)
+ { /* |x| > 2 ^ 54 */
+ w = __ieee754_logl (u.value) + ln2;
+ }
+ else if (ix >0x40000000)
+ { /* 2^ 54 > |x| > 2.0 */
+ t = u.value;
+ w = __ieee754_logl (2.0 * t + one / (__ieee754_sqrtl (x * x + one) + t));
+ }
+ else
+ { /* 2.0 > |x| > 2 ^ -56 */
+ t = x * x;
+ w = __log1pl (u.value + t / (one + __ieee754_sqrtl (one + t)));
+ }
+ if (sign & 0x80000000)
+ return -w;
+ else
+ return w;
+}
+weak_alias (__asinhl, asinhl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_atanl.c b/libc/sysdeps/ieee754/ldbl-128/s_atanl.c
new file mode 100644
index 000000000..a69669608
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_atanl.c
@@ -0,0 +1,233 @@
+/* s_atanl.c
+ *
+ * Inverse circular tangent for 128-bit long double precision
+ * (arctangent)
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, atanl();
+ *
+ * y = atanl( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns radian angle between -pi/2 and +pi/2 whose tangent is x.
+ *
+ * The function uses a rational approximation of the form
+ * t + t^3 P(t^2)/Q(t^2), optimized for |t| < 0.09375.
+ *
+ * The argument is reduced using the identity
+ * arctan x - arctan u = arctan ((x-u)/(1 + ux))
+ * and an 83-entry lookup table for arctan u, with u = 0, 1/8, ..., 10.25.
+ * Use of the table improves the execution speed of the routine.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -19, 19 4e5 1.7e-34 5.4e-35
+ *
+ *
+ * WARNING:
+ *
+ * This program uses integer operations on bit fields of floating-point
+ * numbers. It does not work with data structures other than the
+ * structure assumed.
+ *
+ */
+
+/* Copyright 2001 by Stephen L. Moshier <moshier@na-net.ornl.gov>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+#include "math_private.h"
+
+/* arctan(k/8), k = 0, ..., 82 */
+static const long double atantbl[84] = {
+ 0.0000000000000000000000000000000000000000E0L,
+ 1.2435499454676143503135484916387102557317E-1L, /* arctan(0.125) */
+ 2.4497866312686415417208248121127581091414E-1L,
+ 3.5877067027057222039592006392646049977698E-1L,
+ 4.6364760900080611621425623146121440202854E-1L,
+ 5.5859931534356243597150821640166127034645E-1L,
+ 6.4350110879328438680280922871732263804151E-1L,
+ 7.1882999962162450541701415152590465395142E-1L,
+ 7.8539816339744830961566084581987572104929E-1L,
+ 8.4415398611317100251784414827164750652594E-1L,
+ 8.9605538457134395617480071802993782702458E-1L,
+ 9.4200004037946366473793717053459358607166E-1L,
+ 9.8279372324732906798571061101466601449688E-1L,
+ 1.0191413442663497346383429170230636487744E0L,
+ 1.0516502125483736674598673120862998296302E0L,
+ 1.0808390005411683108871567292171998202703E0L,
+ 1.1071487177940905030170654601785370400700E0L,
+ 1.1309537439791604464709335155363278047493E0L,
+ 1.1525719972156675180401498626127513797495E0L,
+ 1.1722738811284763866005949441337046149712E0L,
+ 1.1902899496825317329277337748293183376012E0L,
+ 1.2068173702852525303955115800565576303133E0L,
+ 1.2220253232109896370417417439225704908830E0L,
+ 1.2360594894780819419094519711090786987027E0L,
+ 1.2490457723982544258299170772810901230778E0L,
+ 1.2610933822524404193139408812473357720101E0L,
+ 1.2722973952087173412961937498224804940684E0L,
+ 1.2827408797442707473628852511364955306249E0L,
+ 1.2924966677897852679030914214070816845853E0L,
+ 1.3016288340091961438047858503666855921414E0L,
+ 1.3101939350475556342564376891719053122733E0L,
+ 1.3182420510168370498593302023271362531155E0L,
+ 1.3258176636680324650592392104284756311844E0L,
+ 1.3329603993374458675538498697331558093700E0L,
+ 1.3397056595989995393283037525895557411039E0L,
+ 1.3460851583802539310489409282517796256512E0L,
+ 1.3521273809209546571891479413898128509842E0L,
+ 1.3578579772154994751124898859640585287459E0L,
+ 1.3633001003596939542892985278250991189943E0L,
+ 1.3684746984165928776366381936948529556191E0L,
+ 1.3734007669450158608612719264449611486510E0L,
+ 1.3780955681325110444536609641291551522494E0L,
+ 1.3825748214901258580599674177685685125566E0L,
+ 1.3868528702577214543289381097042486034883E0L,
+ 1.3909428270024183486427686943836432060856E0L,
+ 1.3948567013423687823948122092044222644895E0L,
+ 1.3986055122719575950126700816114282335732E0L,
+ 1.4021993871854670105330304794336492676944E0L,
+ 1.4056476493802697809521934019958079881002E0L,
+ 1.4089588955564736949699075250792569287156E0L,
+ 1.4121410646084952153676136718584891599630E0L,
+ 1.4152014988178669079462550975833894394929E0L,
+ 1.4181469983996314594038603039700989523716E0L,
+ 1.4209838702219992566633046424614466661176E0L,
+ 1.4237179714064941189018190466107297503086E0L,
+ 1.4263547484202526397918060597281265695725E0L,
+ 1.4288992721907326964184700745371983590908E0L,
+ 1.4313562697035588982240194668401779312122E0L,
+ 1.4337301524847089866404719096698873648610E0L,
+ 1.4360250423171655234964275337155008780675E0L,
+ 1.4382447944982225979614042479354815855386E0L,
+ 1.4403930189057632173997301031392126865694E0L,
+ 1.4424730991091018200252920599377292525125E0L,
+ 1.4444882097316563655148453598508037025938E0L,
+ 1.4464413322481351841999668424758804165254E0L,
+ 1.4483352693775551917970437843145232637695E0L,
+ 1.4501726582147939000905940595923466567576E0L,
+ 1.4519559822271314199339700039142990228105E0L,
+ 1.4536875822280323362423034480994649820285E0L,
+ 1.4553696664279718992423082296859928222270E0L,
+ 1.4570043196511885530074841089245667532358E0L,
+ 1.4585935117976422128825857356750737658039E0L,
+ 1.4601391056210009726721818194296893361233E0L,
+ 1.4616428638860188872060496086383008594310E0L,
+ 1.4631064559620759326975975316301202111560E0L,
+ 1.4645314639038178118428450961503371619177E0L,
+ 1.4659193880646627234129855241049975398470E0L,
+ 1.4672716522843522691530527207287398276197E0L,
+ 1.4685896086876430842559640450619880951144E0L,
+ 1.4698745421276027686510391411132998919794E0L,
+ 1.4711276743037345918528755717617308518553E0L,
+ 1.4723501675822635384916444186631899205983E0L,
+ 1.4735431285433308455179928682541563973416E0L, /* arctan(10.25) */
+ 1.5707963267948966192313216916397514420986E0L /* pi/2 */
+};
+
+
+/* arctan t = t + t^3 p(t^2) / q(t^2)
+ |t| <= 0.09375
+ peak relative error 5.3e-37 */
+
+static const long double
+ p0 = -4.283708356338736809269381409828726405572E1L,
+ p1 = -8.636132499244548540964557273544599863825E1L,
+ p2 = -5.713554848244551350855604111031839613216E1L,
+ p3 = -1.371405711877433266573835355036413750118E1L,
+ p4 = -8.638214309119210906997318946650189640184E-1L,
+ q0 = 1.285112506901621042780814422948906537959E2L,
+ q1 = 3.361907253914337187957855834229672347089E2L,
+ q2 = 3.180448303864130128268191635189365331680E2L,
+ q3 = 1.307244136980865800160844625025280344686E2L,
+ q4 = 2.173623741810414221251136181221172551416E1L;
+ /* q5 = 1.000000000000000000000000000000000000000E0 */
+
+
+long double
+__atanl (long double x)
+{
+ int k, sign;
+ long double t, u, p, q;
+ ieee854_long_double_shape_type s;
+
+ s.value = x;
+ k = s.parts32.w0;
+ if (k & 0x80000000)
+ sign = 1;
+ else
+ sign = 0;
+
+ /* Check for IEEE special cases. */
+ k &= 0x7fffffff;
+ if (k >= 0x7fff0000)
+ {
+ /* NaN. */
+ if ((k & 0xffff) | s.parts32.w1 | s.parts32.w2 | s.parts32.w3)
+ return (x + x);
+
+ /* Infinity. */
+ if (sign)
+ return -atantbl[83];
+ else
+ return atantbl[83];
+ }
+
+ if (sign)
+ x = -x;
+
+ if (k >= 0x40024800) /* 10.25 */
+ {
+ k = 83;
+ t = -1.0/x;
+ }
+ else
+ {
+ /* Index of nearest table element.
+ Roundoff to integer is asymmetrical to avoid cancellation when t < 0
+ (cf. fdlibm). */
+ k = 8.0 * x + 0.25;
+ u = 0.125 * k;
+ /* Small arctan argument. */
+ t = (x - u) / (1.0 + x * u);
+ }
+
+ /* Arctan of small argument t. */
+ u = t * t;
+ p = ((((p4 * u) + p3) * u + p2) * u + p1) * u + p0;
+ q = ((((u + q4) * u + q3) * u + q2) * u + q1) * u + q0;
+ u = t * u * p / q + t;
+
+ /* arctan x = arctan u + arctan t */
+ u = atantbl[k] + u;
+ if (sign)
+ return (-u);
+ else
+ return u;
+}
+
+weak_alias (__atanl, atanl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_cbrtl.c b/libc/sysdeps/ieee754/ldbl-128/s_cbrtl.c
new file mode 100644
index 000000000..96e09a187
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_cbrtl.c
@@ -0,0 +1,135 @@
+/* cbrtl.c
+ *
+ * Cube root, long double precision
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, cbrtl();
+ *
+ * y = cbrtl( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the cube root of the argument, which may be negative.
+ *
+ * Range reduction involves determining the power of 2 of
+ * the argument. A polynomial of degree 2 applied to the
+ * mantissa, and multiplication by the cube root of 1, 2, or 4
+ * approximates the root to within about 0.1%. Then Newton's
+ * iteration is used three times to converge to an accurate
+ * result.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -8,8 100000 1.3e-34 3.9e-35
+ * IEEE exp(+-707) 100000 1.3e-34 4.3e-35
+ *
+ */
+
+/*
+Cephes Math Library Release 2.2: January, 1991
+Copyright 1984, 1991 by Stephen L. Moshier
+Adapted for glibc October, 2001.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+#include "math.h"
+#include "math_private.h"
+
+static const long double CBRT2 = 1.259921049894873164767210607278228350570251L;
+static const long double CBRT4 = 1.587401051968199474751705639272308260391493L;
+static const long double CBRT2I = 0.7937005259840997373758528196361541301957467L;
+static const long double CBRT4I = 0.6299605249474365823836053036391141752851257L;
+
+
+long double
+__cbrtl (long double x)
+{
+ int e, rem, sign;
+ long double z;
+
+ if (!__finitel (x))
+ return x + x;
+
+ if (x == 0)
+ return (x);
+
+ if (x > 0)
+ sign = 1;
+ else
+ {
+ sign = -1;
+ x = -x;
+ }
+
+ z = x;
+ /* extract power of 2, leaving mantissa between 0.5 and 1 */
+ x = __frexpl (x, &e);
+
+ /* Approximate cube root of number between .5 and 1,
+ peak relative error = 1.2e-6 */
+ x = ((((1.3584464340920900529734e-1L * x
+ - 6.3986917220457538402318e-1L) * x
+ + 1.2875551670318751538055e0L) * x
+ - 1.4897083391357284957891e0L) * x
+ + 1.3304961236013647092521e0L) * x + 3.7568280825958912391243e-1L;
+
+ /* exponent divided by 3 */
+ if (e >= 0)
+ {
+ rem = e;
+ e /= 3;
+ rem -= 3 * e;
+ if (rem == 1)
+ x *= CBRT2;
+ else if (rem == 2)
+ x *= CBRT4;
+ }
+ else
+ { /* argument less than 1 */
+ e = -e;
+ rem = e;
+ e /= 3;
+ rem -= 3 * e;
+ if (rem == 1)
+ x *= CBRT2I;
+ else if (rem == 2)
+ x *= CBRT4I;
+ e = -e;
+ }
+
+ /* multiply by power of 2 */
+ x = __ldexpl (x, e);
+
+ /* Newton iteration */
+ x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333L;
+ x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333L;
+ x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333L;
+
+ if (sign < 0)
+ x = -x;
+ return (x);
+}
+
+weak_alias (__cbrtl, cbrtl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_ceill.c b/libc/sysdeps/ieee754/ldbl-128/s_ceill.c
new file mode 100644
index 000000000..76bda9fc0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_ceill.c
@@ -0,0 +1,84 @@
+/* s_ceill.c -- long double version of s_ceil.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * ceill(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to ceil(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double huge = 1.0e4930;
+#else
+static long double huge = 1.0e4930;
+#endif
+
+#ifdef __STDC__
+ long double __ceill(long double x)
+#else
+ long double __ceill(x)
+ long double x;
+#endif
+{
+ int64_t i0,i1,j0;
+ u_int64_t i,j;
+ GET_LDOUBLE_WORDS64(i0,i1,x);
+ j0 = ((i0>>48)&0x7fff)-0x3fff;
+ if(j0<48) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0<0) {i0=0x8000000000000000ULL;i1=0;}
+ else if((i0|i1)!=0) { i0=0x3fff000000000000ULL;i1=0;}
+ }
+ } else {
+ i = (0x0000ffffffffffffULL)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0>0) i0 += (0x0001000000000000LL)>>j0;
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>111) {
+ if(j0==0x4000) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = -1ULL>>(j0-48);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0>0) {
+ if(j0==48) i0+=1;
+ else {
+ j = i1+(1LL<<(112-j0));
+ if(j<i1) i0 +=1 ; /* got a carry */
+ i1=j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ SET_LDOUBLE_WORDS64(x,i0,i1);
+ return x;
+}
+weak_alias (__ceill, ceill)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_copysignl.c b/libc/sysdeps/ieee754/ldbl-128/s_copysignl.c
new file mode 100644
index 000000000..cece4f249
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_copysignl.c
@@ -0,0 +1,43 @@
+/* s_copysignl.c -- long double version of s_copysign.c.
+ * Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * copysignl(long double x, long double y)
+ * copysignl(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __copysignl(long double x, long double y)
+#else
+ long double __copysignl(x,y)
+ long double x,y;
+#endif
+{
+ u_int64_t hx,hy;
+ GET_LDOUBLE_MSW64(hx,x);
+ GET_LDOUBLE_MSW64(hy,y);
+ SET_LDOUBLE_MSW64(x,(hx&0x7fffffffffffffffULL)
+ |(hy&0x8000000000000000ULL));
+ return x;
+}
+weak_alias (__copysignl, copysignl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_cosl.c b/libc/sysdeps/ieee754/ldbl-128/s_cosl.c
new file mode 100644
index 000000000..d1258b2cf
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_cosl.c
@@ -0,0 +1,83 @@
+/* s_cosl.c -- long double version of s_cos.c.
+ * Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* cosl(x)
+ * Return cosine function of x.
+ *
+ * kernel function:
+ * __kernel_sinl ... sine function on [-pi/4,pi/4]
+ * __kernel_cosl ... cosine function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2l ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __cosl(long double x)
+#else
+ long double __cosl(x)
+ long double x;
+#endif
+{
+ long double y[2],z=0.0L;
+ int64_t n, ix;
+
+ /* High word of x. */
+ GET_LDOUBLE_MSW64(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffffffffffffLL;
+ if(ix <= 0x3ffe921fb54442d1LL)
+ return __kernel_cosl(x,z);
+
+ /* cos(Inf or NaN) is NaN */
+ else if (ix>=0x7fff000000000000LL) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2l(x,y);
+ switch(n&3) {
+ case 0: return __kernel_cosl(y[0],y[1]);
+ case 1: return -__kernel_sinl(y[0],y[1],1);
+ case 2: return -__kernel_cosl(y[0],y[1]);
+ default:
+ return __kernel_sinl(y[0],y[1],1);
+ }
+ }
+}
+weak_alias (__cosl, cosl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_erfl.c b/libc/sysdeps/ieee754/ldbl-128/s_erfl.c
new file mode 100644
index 000000000..e6983ec3f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_erfl.c
@@ -0,0 +1,951 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* Modifications and expansions for 128-bit long double are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* double erf(double x)
+ * double erfc(double x)
+ * x
+ * 2 |\
+ * erf(x) = --------- | exp(-t*t)dt
+ * sqrt(pi) \|
+ * 0
+ *
+ * erfc(x) = 1-erf(x)
+ * Note that
+ * erf(-x) = -erf(x)
+ * erfc(-x) = 2 - erfc(x)
+ *
+ * Method:
+ * 1. erf(x) = x + x*R(x^2) for |x| in [0, 7/8]
+ * Remark. The formula is derived by noting
+ * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ * and that
+ * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ * is close to one.
+ *
+ * 1a. erf(x) = 1 - erfc(x), for |x| > 1.0
+ * erfc(x) = 1 - erf(x) if |x| < 1/4
+ *
+ * 2. For |x| in [7/8, 1], let s = |x| - 1, and
+ * c = 0.84506291151 rounded to single (24 bits)
+ * erf(s + c) = sign(x) * (c + P1(s)/Q1(s))
+ * Remark: here we use the taylor series expansion at x=1.
+ * erf(1+s) = erf(1) + s*Poly(s)
+ * = 0.845.. + P1(s)/Q1(s)
+ * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ *
+ * 3. For x in [1/4, 5/4],
+ * erfc(s + const) = erfc(const) + s P1(s)/Q1(s)
+ * for const = 1/4, 3/8, ..., 9/8
+ * and 0 <= s <= 1/8 .
+ *
+ * 4. For x in [5/4, 107],
+ * erfc(x) = (1/x)*exp(-x*x-0.5625 + R(z))
+ * z=1/x^2
+ * The interval is partitioned into several segments
+ * of width 1/8 in 1/x.
+ *
+ * Note1:
+ * To compute exp(-x*x-0.5625+R/S), let s be a single
+ * precision number and s := x; then
+ * -x*x = -s*s + (s-x)*(s+x)
+ * exp(-x*x-0.5626+R/S) =
+ * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
+ * Note2:
+ * Here 4 and 5 make use of the asymptotic series
+ * exp(-x*x)
+ * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
+ * x*sqrt(pi)
+ *
+ * 5. For inf > x >= 107
+ * erf(x) = sign(x) *(1 - tiny) (raise inexact)
+ * erfc(x) = tiny*tiny (raise underflow) if x > 0
+ * = 2 - tiny if x<0
+ *
+ * 7. Special case:
+ * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
+ * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
+ * erfc/erf(NaN) is NaN
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+neval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+deval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+tiny = 1e-4931L,
+ half = 0.5L,
+ one = 1.0L,
+ two = 2.0L,
+ /* 2/sqrt(pi) - 1 */
+ efx = 1.2837916709551257389615890312154517168810E-1L,
+ /* 8 * (2/sqrt(pi) - 1) */
+ efx8 = 1.0270333367641005911692712249723613735048E0L;
+
+
+/* erf(x) = x + x R(x^2)
+ 0 <= x <= 7/8
+ Peak relative error 1.8e-35 */
+#define NTN1 8
+static const long double TN1[NTN1 + 1] =
+{
+ -3.858252324254637124543172907442106422373E10L,
+ 9.580319248590464682316366876952214879858E10L,
+ 1.302170519734879977595901236693040544854E10L,
+ 2.922956950426397417800321486727032845006E9L,
+ 1.764317520783319397868923218385468729799E8L,
+ 1.573436014601118630105796794840834145120E7L,
+ 4.028077380105721388745632295157816229289E5L,
+ 1.644056806467289066852135096352853491530E4L,
+ 3.390868480059991640235675479463287886081E1L
+};
+#define NTD1 8
+static const long double TD1[NTD1 + 1] =
+{
+ -3.005357030696532927149885530689529032152E11L,
+ -1.342602283126282827411658673839982164042E11L,
+ -2.777153893355340961288511024443668743399E10L,
+ -3.483826391033531996955620074072768276974E9L,
+ -2.906321047071299585682722511260895227921E8L,
+ -1.653347985722154162439387878512427542691E7L,
+ -6.245520581562848778466500301865173123136E5L,
+ -1.402124304177498828590239373389110545142E4L,
+ -1.209368072473510674493129989468348633579E2L
+/* 1.0E0 */
+};
+
+
+/* erf(z+1) = erf_const + P(z)/Q(z)
+ -.125 <= z <= 0
+ Peak relative error 7.3e-36 */
+static const long double erf_const = 0.845062911510467529296875L;
+#define NTN2 8
+static const long double TN2[NTN2 + 1] =
+{
+ -4.088889697077485301010486931817357000235E1L,
+ 7.157046430681808553842307502826960051036E3L,
+ -2.191561912574409865550015485451373731780E3L,
+ 2.180174916555316874988981177654057337219E3L,
+ 2.848578658049670668231333682379720943455E2L,
+ 1.630362490952512836762810462174798925274E2L,
+ 6.317712353961866974143739396865293596895E0L,
+ 2.450441034183492434655586496522857578066E1L,
+ 5.127662277706787664956025545897050896203E-1L
+};
+#define NTD2 8
+static const long double TD2[NTD2 + 1] =
+{
+ 1.731026445926834008273768924015161048885E4L,
+ 1.209682239007990370796112604286048173750E4L,
+ 1.160950290217993641320602282462976163857E4L,
+ 5.394294645127126577825507169061355698157E3L,
+ 2.791239340533632669442158497532521776093E3L,
+ 8.989365571337319032943005387378993827684E2L,
+ 2.974016493766349409725385710897298069677E2L,
+ 6.148192754590376378740261072533527271947E1L,
+ 1.178502892490738445655468927408440847480E1L
+ /* 1.0E0 */
+};
+
+
+/* erfc(x + 0.25) = erfc(0.25) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 1.4e-35 */
+#define NRNr13 8
+static const long double RNr13[NRNr13 + 1] =
+{
+ -2.353707097641280550282633036456457014829E3L,
+ 3.871159656228743599994116143079870279866E2L,
+ -3.888105134258266192210485617504098426679E2L,
+ -2.129998539120061668038806696199343094971E1L,
+ -8.125462263594034672468446317145384108734E1L,
+ 8.151549093983505810118308635926270319660E0L,
+ -5.033362032729207310462422357772568553670E0L,
+ -4.253956621135136090295893547735851168471E-2L,
+ -8.098602878463854789780108161581050357814E-2L
+};
+#define NRDr13 7
+static const long double RDr13[NRDr13 + 1] =
+{
+ 2.220448796306693503549505450626652881752E3L,
+ 1.899133258779578688791041599040951431383E2L,
+ 1.061906712284961110196427571557149268454E3L,
+ 7.497086072306967965180978101974566760042E1L,
+ 2.146796115662672795876463568170441327274E2L,
+ 1.120156008362573736664338015952284925592E1L,
+ 2.211014952075052616409845051695042741074E1L,
+ 6.469655675326150785692908453094054988938E-1L
+ /* 1.0E0 */
+};
+/* erfc(0.25) = C13a + C13b to extra precision. */
+static const long double C13a = 0.723663330078125L;
+static const long double C13b = 1.0279753638067014931732235184287934646022E-5L;
+
+
+/* erfc(x + 0.375) = erfc(0.375) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 1.2e-35 */
+#define NRNr14 8
+static const long double RNr14[NRNr14 + 1] =
+{
+ -2.446164016404426277577283038988918202456E3L,
+ 6.718753324496563913392217011618096698140E2L,
+ -4.581631138049836157425391886957389240794E2L,
+ -2.382844088987092233033215402335026078208E1L,
+ -7.119237852400600507927038680970936336458E1L,
+ 1.313609646108420136332418282286454287146E1L,
+ -6.188608702082264389155862490056401365834E0L,
+ -2.787116601106678287277373011101132659279E-2L,
+ -2.230395570574153963203348263549700967918E-2L
+};
+#define NRDr14 7
+static const long double RDr14[NRDr14 + 1] =
+{
+ 2.495187439241869732696223349840963702875E3L,
+ 2.503549449872925580011284635695738412162E2L,
+ 1.159033560988895481698051531263861842461E3L,
+ 9.493751466542304491261487998684383688622E1L,
+ 2.276214929562354328261422263078480321204E2L,
+ 1.367697521219069280358984081407807931847E1L,
+ 2.276988395995528495055594829206582732682E1L,
+ 7.647745753648996559837591812375456641163E-1L
+ /* 1.0E0 */
+};
+/* erfc(0.375) = C14a + C14b to extra precision. */
+static const long double C14a = 0.5958709716796875L;
+static const long double C14b = 1.2118885490201676174914080878232469565953E-5L;
+
+/* erfc(x + 0.5) = erfc(0.5) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 4.7e-36 */
+#define NRNr15 8
+static const long double RNr15[NRNr15 + 1] =
+{
+ -2.624212418011181487924855581955853461925E3L,
+ 8.473828904647825181073831556439301342756E2L,
+ -5.286207458628380765099405359607331669027E2L,
+ -3.895781234155315729088407259045269652318E1L,
+ -6.200857908065163618041240848728398496256E1L,
+ 1.469324610346924001393137895116129204737E1L,
+ -6.961356525370658572800674953305625578903E0L,
+ 5.145724386641163809595512876629030548495E-3L,
+ 1.990253655948179713415957791776180406812E-2L
+};
+#define NRDr15 7
+static const long double RDr15[NRDr15 + 1] =
+{
+ 2.986190760847974943034021764693341524962E3L,
+ 5.288262758961073066335410218650047725985E2L,
+ 1.363649178071006978355113026427856008978E3L,
+ 1.921707975649915894241864988942255320833E2L,
+ 2.588651100651029023069013885900085533226E2L,
+ 2.628752920321455606558942309396855629459E1L,
+ 2.455649035885114308978333741080991380610E1L,
+ 1.378826653595128464383127836412100939126E0L
+ /* 1.0E0 */
+};
+/* erfc(0.5) = C15a + C15b to extra precision. */
+static const long double C15a = 0.4794921875L;
+static const long double C15b = 7.9346869534623172533461080354712635484242E-6L;
+
+/* erfc(x + 0.625) = erfc(0.625) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 5.1e-36 */
+#define NRNr16 8
+static const long double RNr16[NRNr16 + 1] =
+{
+ -2.347887943200680563784690094002722906820E3L,
+ 8.008590660692105004780722726421020136482E2L,
+ -5.257363310384119728760181252132311447963E2L,
+ -4.471737717857801230450290232600243795637E1L,
+ -4.849540386452573306708795324759300320304E1L,
+ 1.140885264677134679275986782978655952843E1L,
+ -6.731591085460269447926746876983786152300E0L,
+ 1.370831653033047440345050025876085121231E-1L,
+ 2.022958279982138755020825717073966576670E-2L,
+};
+#define NRDr16 7
+static const long double RDr16[NRDr16 + 1] =
+{
+ 3.075166170024837215399323264868308087281E3L,
+ 8.730468942160798031608053127270430036627E2L,
+ 1.458472799166340479742581949088453244767E3L,
+ 3.230423687568019709453130785873540386217E2L,
+ 2.804009872719893612081109617983169474655E2L,
+ 4.465334221323222943418085830026979293091E1L,
+ 2.612723259683205928103787842214809134746E1L,
+ 2.341526751185244109722204018543276124997E0L,
+ /* 1.0E0 */
+};
+/* erfc(0.625) = C16a + C16b to extra precision. */
+static const long double C16a = 0.3767547607421875L;
+static const long double C16b = 4.3570693945275513594941232097252997287766E-6L;
+
+/* erfc(x + 0.75) = erfc(0.75) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 1.7e-35 */
+#define NRNr17 8
+static const long double RNr17[NRNr17 + 1] =
+{
+ -1.767068734220277728233364375724380366826E3L,
+ 6.693746645665242832426891888805363898707E2L,
+ -4.746224241837275958126060307406616817753E2L,
+ -2.274160637728782675145666064841883803196E1L,
+ -3.541232266140939050094370552538987982637E1L,
+ 6.988950514747052676394491563585179503865E0L,
+ -5.807687216836540830881352383529281215100E0L,
+ 3.631915988567346438830283503729569443642E-1L,
+ -1.488945487149634820537348176770282391202E-2L
+};
+#define NRDr17 7
+static const long double RDr17[NRDr17 + 1] =
+{
+ 2.748457523498150741964464942246913394647E3L,
+ 1.020213390713477686776037331757871252652E3L,
+ 1.388857635935432621972601695296561952738E3L,
+ 3.903363681143817750895999579637315491087E2L,
+ 2.784568344378139499217928969529219886578E2L,
+ 5.555800830216764702779238020065345401144E1L,
+ 2.646215470959050279430447295801291168941E1L,
+ 2.984905282103517497081766758550112011265E0L,
+ /* 1.0E0 */
+};
+/* erfc(0.75) = C17a + C17b to extra precision. */
+static const long double C17a = 0.2888336181640625L;
+static const long double C17b = 1.0748182422368401062165408589222625794046E-5L;
+
+
+/* erfc(x + 0.875) = erfc(0.875) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 2.2e-35 */
+#define NRNr18 8
+static const long double RNr18[NRNr18 + 1] =
+{
+ -1.342044899087593397419622771847219619588E3L,
+ 6.127221294229172997509252330961641850598E2L,
+ -4.519821356522291185621206350470820610727E2L,
+ 1.223275177825128732497510264197915160235E1L,
+ -2.730789571382971355625020710543532867692E1L,
+ 4.045181204921538886880171727755445395862E0L,
+ -4.925146477876592723401384464691452700539E0L,
+ 5.933878036611279244654299924101068088582E-1L,
+ -5.557645435858916025452563379795159124753E-2L
+};
+#define NRDr18 7
+static const long double RDr18[NRDr18 + 1] =
+{
+ 2.557518000661700588758505116291983092951E3L,
+ 1.070171433382888994954602511991940418588E3L,
+ 1.344842834423493081054489613250688918709E3L,
+ 4.161144478449381901208660598266288188426E2L,
+ 2.763670252219855198052378138756906980422E2L,
+ 5.998153487868943708236273854747564557632E1L,
+ 2.657695108438628847733050476209037025318E1L,
+ 3.252140524394421868923289114410336976512E0L,
+ /* 1.0E0 */
+};
+/* erfc(0.875) = C18a + C18b to extra precision. */
+static const long double C18a = 0.215911865234375L;
+static const long double C18b = 1.3073705765341685464282101150637224028267E-5L;
+
+/* erfc(x + 1.0) = erfc(1.0) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 1.6e-35 */
+#define NRNr19 8
+static const long double RNr19[NRNr19 + 1] =
+{
+ -1.139180936454157193495882956565663294826E3L,
+ 6.134903129086899737514712477207945973616E2L,
+ -4.628909024715329562325555164720732868263E2L,
+ 4.165702387210732352564932347500364010833E1L,
+ -2.286979913515229747204101330405771801610E1L,
+ 1.870695256449872743066783202326943667722E0L,
+ -4.177486601273105752879868187237000032364E0L,
+ 7.533980372789646140112424811291782526263E-1L,
+ -8.629945436917752003058064731308767664446E-2L
+};
+#define NRDr19 7
+static const long double RDr19[NRDr19 + 1] =
+{
+ 2.744303447981132701432716278363418643778E3L,
+ 1.266396359526187065222528050591302171471E3L,
+ 1.466739461422073351497972255511919814273E3L,
+ 4.868710570759693955597496520298058147162E2L,
+ 2.993694301559756046478189634131722579643E2L,
+ 6.868976819510254139741559102693828237440E1L,
+ 2.801505816247677193480190483913753613630E1L,
+ 3.604439909194350263552750347742663954481E0L,
+ /* 1.0E0 */
+};
+/* erfc(1.0) = C19a + C19b to extra precision. */
+static const long double C19a = 0.15728759765625L;
+static const long double C19b = 1.1609394035130658779364917390740703933002E-5L;
+
+/* erfc(x + 1.125) = erfc(1.125) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 3.6e-36 */
+#define NRNr20 8
+static const long double RNr20[NRNr20 + 1] =
+{
+ -9.652706916457973956366721379612508047640E2L,
+ 5.577066396050932776683469951773643880634E2L,
+ -4.406335508848496713572223098693575485978E2L,
+ 5.202893466490242733570232680736966655434E1L,
+ -1.931311847665757913322495948705563937159E1L,
+ -9.364318268748287664267341457164918090611E-2L,
+ -3.306390351286352764891355375882586201069E0L,
+ 7.573806045289044647727613003096916516475E-1L,
+ -9.611744011489092894027478899545635991213E-2L
+};
+#define NRDr20 7
+static const long double RDr20[NRDr20 + 1] =
+{
+ 3.032829629520142564106649167182428189014E3L,
+ 1.659648470721967719961167083684972196891E3L,
+ 1.703545128657284619402511356932569292535E3L,
+ 6.393465677731598872500200253155257708763E2L,
+ 3.489131397281030947405287112726059221934E2L,
+ 8.848641738570783406484348434387611713070E1L,
+ 3.132269062552392974833215844236160958502E1L,
+ 4.430131663290563523933419966185230513168E0L
+ /* 1.0E0 */
+};
+/* erfc(1.125) = C20a + C20b to extra precision. */
+static const long double C20a = 0.111602783203125L;
+static const long double C20b = 8.9850951672359304215530728365232161564636E-6L;
+
+/* erfc(1/x) = 1/x exp (-1/x^2 - 0.5625 + R(1/x^2))
+ 7/8 <= 1/x < 1
+ Peak relative error 1.4e-35 */
+#define NRNr8 9
+static const long double RNr8[NRNr8 + 1] =
+{
+ 3.587451489255356250759834295199296936784E1L,
+ 5.406249749087340431871378009874875889602E2L,
+ 2.931301290625250886238822286506381194157E3L,
+ 7.359254185241795584113047248898753470923E3L,
+ 9.201031849810636104112101947312492532314E3L,
+ 5.749697096193191467751650366613289284777E3L,
+ 1.710415234419860825710780802678697889231E3L,
+ 2.150753982543378580859546706243022719599E2L,
+ 8.740953582272147335100537849981160931197E0L,
+ 4.876422978828717219629814794707963640913E-2L
+};
+#define NRDr8 8
+static const long double RDr8[NRDr8 + 1] =
+{
+ 6.358593134096908350929496535931630140282E1L,
+ 9.900253816552450073757174323424051765523E2L,
+ 5.642928777856801020545245437089490805186E3L,
+ 1.524195375199570868195152698617273739609E4L,
+ 2.113829644500006749947332935305800887345E4L,
+ 1.526438562626465706267943737310282977138E4L,
+ 5.561370922149241457131421914140039411782E3L,
+ 9.394035530179705051609070428036834496942E2L,
+ 6.147019596150394577984175188032707343615E1L
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp (-1/x^2 - 0.5625 + R(1/x^2))
+ 0.75 <= 1/x <= 0.875
+ Peak relative error 2.0e-36 */
+#define NRNr7 9
+static const long double RNr7[NRNr7 + 1] =
+{
+ 1.686222193385987690785945787708644476545E1L,
+ 1.178224543567604215602418571310612066594E3L,
+ 1.764550584290149466653899886088166091093E4L,
+ 1.073758321890334822002849369898232811561E5L,
+ 3.132840749205943137619839114451290324371E5L,
+ 4.607864939974100224615527007793867585915E5L,
+ 3.389781820105852303125270837910972384510E5L,
+ 1.174042187110565202875011358512564753399E5L,
+ 1.660013606011167144046604892622504338313E4L,
+ 6.700393957480661937695573729183733234400E2L
+};
+#define NRDr7 9
+static const long double RDr7[NRDr7 + 1] =
+{
+-1.709305024718358874701575813642933561169E3L,
+-3.280033887481333199580464617020514788369E4L,
+-2.345284228022521885093072363418750835214E5L,
+-8.086758123097763971926711729242327554917E5L,
+-1.456900414510108718402423999575992450138E6L,
+-1.391654264881255068392389037292702041855E6L,
+-6.842360801869939983674527468509852583855E5L,
+-1.597430214446573566179675395199807533371E5L,
+-1.488876130609876681421645314851760773480E4L,
+-3.511762950935060301403599443436465645703E2L
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 5/8 <= 1/x < 3/4
+ Peak relative error 1.9e-35 */
+#define NRNr6 9
+static const long double RNr6[NRNr6 + 1] =
+{
+ 1.642076876176834390623842732352935761108E0L,
+ 1.207150003611117689000664385596211076662E2L,
+ 2.119260779316389904742873816462800103939E3L,
+ 1.562942227734663441801452930916044224174E4L,
+ 5.656779189549710079988084081145693580479E4L,
+ 1.052166241021481691922831746350942786299E5L,
+ 9.949798524786000595621602790068349165758E4L,
+ 4.491790734080265043407035220188849562856E4L,
+ 8.377074098301530326270432059434791287601E3L,
+ 4.506934806567986810091824791963991057083E2L
+};
+#define NRDr6 9
+static const long double RDr6[NRDr6 + 1] =
+{
+-1.664557643928263091879301304019826629067E2L,
+-3.800035902507656624590531122291160668452E3L,
+-3.277028191591734928360050685359277076056E4L,
+-1.381359471502885446400589109566587443987E5L,
+-3.082204287382581873532528989283748656546E5L,
+-3.691071488256738343008271448234631037095E5L,
+-2.300482443038349815750714219117566715043E5L,
+-6.873955300927636236692803579555752171530E4L,
+-8.262158817978334142081581542749986845399E3L,
+-2.517122254384430859629423488157361983661E2L
+ /* 1.00 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 1/2 <= 1/x < 5/8
+ Peak relative error 4.6e-36 */
+#define NRNr5 10
+static const long double RNr5[NRNr5 + 1] =
+{
+-3.332258927455285458355550878136506961608E-3L,
+-2.697100758900280402659586595884478660721E-1L,
+-6.083328551139621521416618424949137195536E0L,
+-6.119863528983308012970821226810162441263E1L,
+-3.176535282475593173248810678636522589861E2L,
+-8.933395175080560925809992467187963260693E2L,
+-1.360019508488475978060917477620199499560E3L,
+-1.075075579828188621541398761300910213280E3L,
+-4.017346561586014822824459436695197089916E2L,
+-5.857581368145266249509589726077645791341E1L,
+-2.077715925587834606379119585995758954399E0L
+};
+#define NRDr5 9
+static const long double RDr5[NRDr5 + 1] =
+{
+ 3.377879570417399341550710467744693125385E-1L,
+ 1.021963322742390735430008860602594456187E1L,
+ 1.200847646592942095192766255154827011939E2L,
+ 7.118915528142927104078182863387116942836E2L,
+ 2.318159380062066469386544552429625026238E3L,
+ 4.238729853534009221025582008928765281620E3L,
+ 4.279114907284825886266493994833515580782E3L,
+ 2.257277186663261531053293222591851737504E3L,
+ 5.570475501285054293371908382916063822957E2L,
+ 5.142189243856288981145786492585432443560E1L
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 3/8 <= 1/x < 1/2
+ Peak relative error 2.0e-36 */
+#define NRNr4 10
+static const long double RNr4[NRNr4 + 1] =
+{
+ 3.258530712024527835089319075288494524465E-3L,
+ 2.987056016877277929720231688689431056567E-1L,
+ 8.738729089340199750734409156830371528862E0L,
+ 1.207211160148647782396337792426311125923E2L,
+ 8.997558632489032902250523945248208224445E2L,
+ 3.798025197699757225978410230530640879762E3L,
+ 9.113203668683080975637043118209210146846E3L,
+ 1.203285891339933238608683715194034900149E4L,
+ 8.100647057919140328536743641735339740855E3L,
+ 2.383888249907144945837976899822927411769E3L,
+ 2.127493573166454249221983582495245662319E2L
+};
+#define NRDr4 10
+static const long double RDr4[NRDr4 + 1] =
+{
+-3.303141981514540274165450687270180479586E-1L,
+-1.353768629363605300707949368917687066724E1L,
+-2.206127630303621521950193783894598987033E2L,
+-1.861800338758066696514480386180875607204E3L,
+-8.889048775872605708249140016201753255599E3L,
+-2.465888106627948210478692168261494857089E4L,
+-3.934642211710774494879042116768390014289E4L,
+-3.455077258242252974937480623730228841003E4L,
+-1.524083977439690284820586063729912653196E4L,
+-2.810541887397984804237552337349093953857E3L,
+-1.343929553541159933824901621702567066156E2L
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 1/4 <= 1/x < 3/8
+ Peak relative error 8.4e-37 */
+#define NRNr3 11
+static const long double RNr3[NRNr3 + 1] =
+{
+-1.952401126551202208698629992497306292987E-6L,
+-2.130881743066372952515162564941682716125E-4L,
+-8.376493958090190943737529486107282224387E-3L,
+-1.650592646560987700661598877522831234791E-1L,
+-1.839290818933317338111364667708678163199E0L,
+-1.216278715570882422410442318517814388470E1L,
+-4.818759344462360427612133632533779091386E1L,
+-1.120994661297476876804405329172164436784E2L,
+-1.452850765662319264191141091859300126931E2L,
+-9.485207851128957108648038238656777241333E1L,
+-2.563663855025796641216191848818620020073E1L,
+-1.787995944187565676837847610706317833247E0L
+};
+#define NRDr3 10
+static const long double RDr3[NRDr3 + 1] =
+{
+ 1.979130686770349481460559711878399476903E-4L,
+ 1.156941716128488266238105813374635099057E-2L,
+ 2.752657634309886336431266395637285974292E-1L,
+ 3.482245457248318787349778336603569327521E0L,
+ 2.569347069372696358578399521203959253162E1L,
+ 1.142279000180457419740314694631879921561E2L,
+ 3.056503977190564294341422623108332700840E2L,
+ 4.780844020923794821656358157128719184422E2L,
+ 4.105972727212554277496256802312730410518E2L,
+ 1.724072188063746970865027817017067646246E2L,
+ 2.815939183464818198705278118326590370435E1L
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 1/8 <= 1/x < 1/4
+ Peak relative error 1.5e-36 */
+#define NRNr2 11
+static const long double RNr2[NRNr2 + 1] =
+{
+-2.638914383420287212401687401284326363787E-8L,
+-3.479198370260633977258201271399116766619E-6L,
+-1.783985295335697686382487087502222519983E-4L,
+-4.777876933122576014266349277217559356276E-3L,
+-7.450634738987325004070761301045014986520E-2L,
+-7.068318854874733315971973707247467326619E-1L,
+-4.113919921935944795764071670806867038732E0L,
+-1.440447573226906222417767283691888875082E1L,
+-2.883484031530718428417168042141288943905E1L,
+-2.990886974328476387277797361464279931446E1L,
+-1.325283914915104866248279787536128997331E1L,
+-1.572436106228070195510230310658206154374E0L
+};
+#define NRDr2 10
+static const long double RDr2[NRDr2 + 1] =
+{
+ 2.675042728136731923554119302571867799673E-6L,
+ 2.170997868451812708585443282998329996268E-4L,
+ 7.249969752687540289422684951196241427445E-3L,
+ 1.302040375859768674620410563307838448508E-1L,
+ 1.380202483082910888897654537144485285549E0L,
+ 8.926594113174165352623847870299170069350E0L,
+ 3.521089584782616472372909095331572607185E1L,
+ 8.233547427533181375185259050330809105570E1L,
+ 1.072971579885803033079469639073292840135E2L,
+ 6.943803113337964469736022094105143158033E1L,
+ 1.775695341031607738233608307835017282662E1L
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 1/128 <= 1/x < 1/8
+ Peak relative error 2.2e-36 */
+#define NRNr1 9
+static const long double RNr1[NRNr1 + 1] =
+{
+-4.250780883202361946697751475473042685782E-8L,
+-5.375777053288612282487696975623206383019E-6L,
+-2.573645949220896816208565944117382460452E-4L,
+-6.199032928113542080263152610799113086319E-3L,
+-8.262721198693404060380104048479916247786E-2L,
+-6.242615227257324746371284637695778043982E-1L,
+-2.609874739199595400225113299437099626386E0L,
+-5.581967563336676737146358534602770006970E0L,
+-5.124398923356022609707490956634280573882E0L,
+-1.290865243944292370661544030414667556649E0L
+};
+#define NRDr1 8
+static const long double RDr1[NRDr1 + 1] =
+{
+ 4.308976661749509034845251315983612976224E-6L,
+ 3.265390126432780184125233455960049294580E-4L,
+ 9.811328839187040701901866531796570418691E-3L,
+ 1.511222515036021033410078631914783519649E-1L,
+ 1.289264341917429958858379585970225092274E0L,
+ 6.147640356182230769548007536914983522270E0L,
+ 1.573966871337739784518246317003956180750E1L,
+ 1.955534123435095067199574045529218238263E1L,
+ 9.472613121363135472247929109615785855865E0L
+ /* 1.0E0 */
+};
+
+
+#ifdef __STDC__
+long double
+__erfl (long double x)
+#else
+double
+__erfl (x)
+ long double x;
+#endif
+{
+ long double a, y, z;
+ int32_t i, ix, sign;
+ ieee854_long_double_shape_type u;
+
+ u.value = x;
+ sign = u.parts32.w0;
+ ix = sign & 0x7fffffff;
+
+ if (ix >= 0x7fff0000)
+ { /* erf(nan)=nan */
+ i = ((sign & 0xffff0000) >> 31) << 1;
+ return (long double) (1 - i) + one / x; /* erf(+-inf)=+-1 */
+ }
+
+ if (ix >= 0x3fff0000) /* |x| >= 1.0 */
+ {
+ y = __erfcl (x);
+ return (one - y);
+ /* return (one - __erfcl (x)); */
+ }
+ u.parts32.w0 = ix;
+ a = u.value;
+ z = x * x;
+ if (ix < 0x3ffec000) /* a < 0.875 */
+ {
+ if (ix < 0x3fc60000) /* |x|<2**-57 */
+ {
+ if (ix < 0x00080000)
+ return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */
+ return x + efx * x;
+ }
+ y = a + a * neval (z, TN1, NTN1) / deval (z, TD1, NTD1);
+ }
+ else
+ {
+ a = a - one;
+ y = erf_const + neval (a, TN2, NTN2) / deval (a, TD2, NTD2);
+ }
+
+ if (sign & 0x80000000) /* x < 0 */
+ y = -y;
+ return( y );
+}
+
+weak_alias (__erfl, erfl)
+#ifdef __STDC__
+ long double
+ __erfcl (long double x)
+#else
+ long double
+ __erfcl (x)
+ double
+ x;
+#endif
+{
+ long double y, z, p, r;
+ int32_t i, ix, sign;
+ ieee854_long_double_shape_type u;
+
+ u.value = x;
+ sign = u.parts32.w0;
+ ix = sign & 0x7fffffff;
+ u.parts32.w0 = ix;
+
+ if (ix >= 0x7fff0000)
+ { /* erfc(nan)=nan */
+ /* erfc(+-inf)=0,2 */
+ return (long double) (((u_int32_t) sign >> 31) << 1) + one / x;
+ }
+
+ if (ix < 0x3ffd0000) /* |x| <1/4 */
+ {
+ if (ix < 0x3f8d0000) /* |x|<2**-114 */
+ return one - x;
+ return one - __erfl (x);
+ }
+ if (ix < 0x3fff4000) /* 1.25 */
+ {
+ x = u.value;
+ i = 8.0 * x;
+ switch (i)
+ {
+ case 2:
+ z = x - 0.25L;
+ y = C13b + z * neval (z, RNr13, NRNr13) / deval (z, RDr13, NRDr13);
+ y += C13a;
+ break;
+ case 3:
+ z = x - 0.375L;
+ y = C14b + z * neval (z, RNr14, NRNr14) / deval (z, RDr14, NRDr14);
+ y += C14a;
+ break;
+ case 4:
+ z = x - 0.5L;
+ y = C15b + z * neval (z, RNr15, NRNr15) / deval (z, RDr15, NRDr15);
+ y += C15a;
+ break;
+ case 5:
+ z = x - 0.625L;
+ y = C16b + z * neval (z, RNr16, NRNr16) / deval (z, RDr16, NRDr16);
+ y += C16a;
+ break;
+ case 6:
+ z = x - 0.75L;
+ y = C17b + z * neval (z, RNr17, NRNr17) / deval (z, RDr17, NRDr17);
+ y += C17a;
+ break;
+ case 7:
+ z = x - 0.875L;
+ y = C18b + z * neval (z, RNr18, NRNr18) / deval (z, RDr18, NRDr18);
+ y += C18a;
+ break;
+ case 8:
+ z = x - 1.0L;
+ y = C19b + z * neval (z, RNr19, NRNr19) / deval (z, RDr19, NRDr19);
+ y += C19a;
+ break;
+ case 9:
+ z = x - 1.125L;
+ y = C20b + z * neval (z, RNr20, NRNr20) / deval (z, RDr20, NRDr20);
+ y += C20a;
+ break;
+ }
+ if (sign & 0x80000000)
+ y = 2.0L - y;
+ return y;
+ }
+ /* 1.25 < |x| < 107 */
+ if (ix < 0x4005ac00)
+ {
+ /* x < -9 */
+ if ((ix >= 0x40022000) && (sign & 0x80000000))
+ return two - tiny;
+
+ x = fabsl (x);
+ z = one / (x * x);
+ i = 8.0 / x;
+ switch (i)
+ {
+ default:
+ case 0:
+ p = neval (z, RNr1, NRNr1) / deval (z, RDr1, NRDr1);
+ break;
+ case 1:
+ p = neval (z, RNr2, NRNr2) / deval (z, RDr2, NRDr2);
+ break;
+ case 2:
+ p = neval (z, RNr3, NRNr3) / deval (z, RDr3, NRDr3);
+ break;
+ case 3:
+ p = neval (z, RNr4, NRNr4) / deval (z, RDr4, NRDr4);
+ break;
+ case 4:
+ p = neval (z, RNr5, NRNr5) / deval (z, RDr5, NRDr5);
+ break;
+ case 5:
+ p = neval (z, RNr6, NRNr6) / deval (z, RDr6, NRDr6);
+ break;
+ case 6:
+ p = neval (z, RNr7, NRNr7) / deval (z, RDr7, NRDr7);
+ break;
+ case 7:
+ p = neval (z, RNr8, NRNr8) / deval (z, RDr8, NRDr8);
+ break;
+ }
+ u.value = x;
+ u.parts32.w3 = 0;
+ u.parts32.w2 &= 0xfe000000;
+ z = u.value;
+ r = __ieee754_expl (-z * z - 0.5625) *
+ __ieee754_expl ((z - x) * (z + x) + p);
+ if ((sign & 0x80000000) == 0)
+ return r / x;
+ else
+ return two - r / x;
+ }
+ else
+ {
+ if ((sign & 0x80000000) == 0)
+ return tiny * tiny;
+ else
+ return two - tiny;
+ }
+}
+
+weak_alias (__erfcl, erfcl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_expm1l.c b/libc/sysdeps/ieee754/ldbl-128/s_expm1l.c
new file mode 100644
index 000000000..f373e1e6a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_expm1l.c
@@ -0,0 +1,161 @@
+/* expm1l.c
+ *
+ * Exponential function, minus 1
+ * 128-bit long double precision
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, expm1l();
+ *
+ * y = expm1l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns e (2.71828...) raised to the x power, minus one.
+ *
+ * Range reduction is accomplished by separating the argument
+ * into an integer k and fraction f such that
+ *
+ * x k f
+ * e = 2 e.
+ *
+ * An expansion x + .5 x^2 + x^3 R(x) approximates exp(f) - 1
+ * in the basic range [-0.5 ln 2, 0.5 ln 2].
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -79,+MAXLOG 100,000 1.7e-34 4.5e-35
+ *
+ */
+
+/* Copyright 2001 by Stephen L. Moshier
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+
+#include "math.h"
+#include "math_private.h"
+
+/* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x)
+ -.5 ln 2 < x < .5 ln 2
+ Theoretical peak relative error = 8.1e-36 */
+
+static const long double
+ P0 = 2.943520915569954073888921213330863757240E8L,
+ P1 = -5.722847283900608941516165725053359168840E7L,
+ P2 = 8.944630806357575461578107295909719817253E6L,
+ P3 = -7.212432713558031519943281748462837065308E5L,
+ P4 = 4.578962475841642634225390068461943438441E4L,
+ P5 = -1.716772506388927649032068540558788106762E3L,
+ P6 = 4.401308817383362136048032038528753151144E1L,
+ P7 = -4.888737542888633647784737721812546636240E-1L,
+ Q0 = 1.766112549341972444333352727998584753865E9L,
+ Q1 = -7.848989743695296475743081255027098295771E8L,
+ Q2 = 1.615869009634292424463780387327037251069E8L,
+ Q3 = -2.019684072836541751428967854947019415698E7L,
+ Q4 = 1.682912729190313538934190635536631941751E6L,
+ Q5 = -9.615511549171441430850103489315371768998E4L,
+ Q6 = 3.697714952261803935521187272204485251835E3L,
+ Q7 = -8.802340681794263968892934703309274564037E1L,
+ /* Q8 = 1.000000000000000000000000000000000000000E0 */
+/* C1 + C2 = ln 2 */
+
+ C1 = 6.93145751953125E-1L,
+ C2 = 1.428606820309417232121458176568075500134E-6L,
+/* ln (2^16384 * (1 - 2^-113)) */
+ maxlog = 1.1356523406294143949491931077970764891253E4L,
+/* ln 2^-114 */
+ minarg = -7.9018778583833765273564461846232128760607E1L, big = 2e4932L;
+
+
+long double
+__expm1l (long double x)
+{
+ long double px, qx, xx;
+ int32_t ix, sign;
+ ieee854_long_double_shape_type u;
+ int k;
+
+ /* Detect infinity and NaN. */
+ u.value = x;
+ ix = u.parts32.w0;
+ sign = ix & 0x80000000;
+ ix &= 0x7fffffff;
+ if (ix >= 0x7fff0000)
+ {
+ /* Infinity. */
+ if (((ix & 0xffff) | u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0)
+ {
+ if (sign)
+ return -1.0L;
+ else
+ return x;
+ }
+ /* NaN. No invalid exception. */
+ return x;
+ }
+
+ /* expm1(+- 0) = +- 0. */
+ if ((ix == 0) && (u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0)
+ return x;
+
+ /* Overflow. */
+ if (x > maxlog)
+ return (big * big);
+
+ /* Minimum value. */
+ if (x < minarg)
+ return (4.0/big - 1.0L);
+
+ /* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */
+ xx = C1 + C2; /* ln 2. */
+ px = __floorl (0.5 + x / xx);
+ k = px;
+ /* remainder times ln 2 */
+ x -= px * C1;
+ x -= px * C2;
+
+ /* Approximate exp(remainder ln 2). */
+ px = (((((((P7 * x
+ + P6) * x
+ + P5) * x + P4) * x + P3) * x + P2) * x + P1) * x + P0) * x;
+
+ qx = (((((((x
+ + Q7) * x
+ + Q6) * x + Q5) * x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0;
+
+ xx = x * x;
+ qx = x + (0.5 * xx + xx * px / qx);
+
+ /* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2).
+
+ We have qx = exp(remainder ln 2) - 1, so
+ exp(x) - 1 = 2^k (qx + 1) - 1
+ = 2^k qx + 2^k - 1. */
+
+ px = ldexpl (1.0L, k);
+ x = px * qx + (px - 1.0);
+ return x;
+}
+libm_hidden_def (__expm1l)
+weak_alias (__expm1l, expm1l)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_fabsl.c b/libc/sysdeps/ieee754/ldbl-128/s_fabsl.c
new file mode 100644
index 000000000..c0fd05af6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_fabsl.c
@@ -0,0 +1,39 @@
+/* s_fabsl.c -- long double version of s_fabs.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * fabsl(x) returns the absolute value of x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __fabsl(long double x)
+#else
+ long double __fabsl(x)
+ long double x;
+#endif
+{
+ u_int64_t hx;
+ GET_LDOUBLE_MSW64(hx,x);
+ SET_LDOUBLE_MSW64(x,hx&0x7fffffffffffffffLL);
+ return x;
+}
+weak_alias (__fabsl, fabsl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_finitel.c b/libc/sysdeps/ieee754/ldbl-128/s_finitel.c
new file mode 100644
index 000000000..e3b0a2b99
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_finitel.c
@@ -0,0 +1,41 @@
+/* s_finitel.c -- long double version of s_finite.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * finitel(x) returns 1 is x is finite, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __finitel(long double x)
+#else
+ int __finitel(x)
+ long double x;
+#endif
+{
+ int64_t hx;
+ GET_LDOUBLE_MSW64(hx,x);
+ return (int)((u_int64_t)((hx&0x7fffffffffffffffLL)
+ -0x7fff000000000000LL)>>63);
+}
+hidden_def (__finitel)
+weak_alias (__finitel, finitel)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_floorl.c b/libc/sysdeps/ieee754/ldbl-128/s_floorl.c
new file mode 100644
index 000000000..ff5b98da9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_floorl.c
@@ -0,0 +1,85 @@
+/* s_floorl.c -- long double version of s_floor.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * floorl(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to floor(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double huge = 1.0e4930;
+#else
+static long double huge = 1.0e4930;
+#endif
+
+#ifdef __STDC__
+ long double __floorl(long double x)
+#else
+ long double __floorl(x)
+ long double x;
+#endif
+{
+ int64_t i0,i1,j0;
+ u_int64_t i,j;
+ GET_LDOUBLE_WORDS64(i0,i1,x);
+ j0 = ((i0>>48)&0x7fff)-0x3fff;
+ if(j0<48) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0>=0) {i0=i1=0;}
+ else if(((i0&0x7fffffffffffffffLL)|i1)!=0)
+ { i0=0xbfff000000000000ULL;i1=0;}
+ }
+ } else {
+ i = (0x0000ffffffffffffULL)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0<0) i0 += (0x0001000000000000LL)>>j0;
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>111) {
+ if(j0==0x4000) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = -1ULL>>(j0-48);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0<0) {
+ if(j0==48) i0+=1;
+ else {
+ j = i1+(1LL<<(112-j0));
+ if(j<i1) i0 +=1 ; /* got a carry */
+ i1=j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ SET_LDOUBLE_WORDS64(x,i0,i1);
+ return x;
+}
+weak_alias (__floorl, floorl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_fpclassifyl.c b/libc/sysdeps/ieee754/ldbl-128/s_fpclassifyl.c
new file mode 100644
index 000000000..c66a2cb02
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_fpclassifyl.c
@@ -0,0 +1,45 @@
+/* Return classification value corresponding to argument.
+ Copyright (C) 1997, 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+int
+__fpclassifyl (long double x)
+{
+ u_int64_t hx, lx;
+ int retval = FP_NORMAL;
+
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+ lx |= (hx & 0x0000ffffffffffffLL);
+ hx &= 0x7fff000000000000LL;
+ if ((hx | lx) == 0)
+ retval = FP_ZERO;
+ else if (hx == 0)
+ retval = FP_SUBNORMAL;
+ else if (hx == 0x7fff000000000000LL)
+ retval = lx != 0 ? FP_NAN : FP_INFINITE;
+
+ return retval;
+}
+libm_hidden_def (__fpclassifyl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_frexpl.c b/libc/sysdeps/ieee754/ldbl-128/s_frexpl.c
new file mode 100644
index 000000000..6dbb60ece
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_frexpl.c
@@ -0,0 +1,63 @@
+/* s_frexpl.c -- long double version of s_frexp.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * for non-zero x
+ * x = frexpl(arg,&exp);
+ * return a long double fp quantity x such that 0.5 <= |x| <1.0
+ * and the corresponding binary exponent "exp". That is
+ * arg = x*2^exp.
+ * If arg is inf, 0.0, or NaN, then frexpl(arg,&exp) returns arg
+ * with *exp=0.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+two114 = 2.0769187434139310514121985316880384E+34L; /* 0x4071000000000000, 0 */
+
+#ifdef __STDC__
+ long double __frexpl(long double x, int *eptr)
+#else
+ long double __frexpl(x, eptr)
+ long double x; int *eptr;
+#endif
+{
+ u_int64_t hx, lx, ix;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ ix = 0x7fffffffffffffffULL&hx;
+ *eptr = 0;
+ if(ix>=0x7fff000000000000ULL||((ix|lx)==0)) return x; /* 0,inf,nan */
+ if (ix<0x0001000000000000ULL) { /* subnormal */
+ x *= two114;
+ GET_LDOUBLE_MSW64(hx,x);
+ ix = hx&0x7fffffffffffffffULL;
+ *eptr = -114;
+ }
+ *eptr += (ix>>48)-16382;
+ hx = (hx&0x8000ffffffffffffULL) | 0x3ffe000000000000ULL;
+ SET_LDOUBLE_MSW64(x,hx);
+ return x;
+}
+weak_alias (__frexpl, frexpl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_ilogbl.c b/libc/sysdeps/ieee754/ldbl-128/s_ilogbl.c
new file mode 100644
index 000000000..fe14395ad
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_ilogbl.c
@@ -0,0 +1,62 @@
+/* s_ilogbl.c -- long double version of s_ilogb.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/* ilogbl(long double x)
+ * return the binary exponent of non-zero x
+ * ilogbl(0) = FP_ILOGB0
+ * ilogbl(NaN) = FP_ILOGBNAN (no signal is raised)
+ * ilogbl(+-Inf) = INT_MAX (no signal is raised)
+ */
+
+#include <limits.h>
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __ilogbl(long double x)
+#else
+ int __ilogbl(x)
+ long double x;
+#endif
+{
+ int64_t hx,lx;
+ int ix;
+
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ hx &= 0x7fffffffffffffffLL;
+ if(hx <= 0x0001000000000000LL) {
+ if((hx|lx)==0)
+ return FP_ILOGB0; /* ilogbl(0) = FP_ILOGB0 */
+ else /* subnormal x */
+ if(hx==0) {
+ for (ix = -16431; lx>0; lx<<=1) ix -=1;
+ } else {
+ for (ix = -16382, hx<<=15; hx>0; hx<<=1) ix -=1;
+ }
+ return ix;
+ }
+ else if (hx<0x7fff000000000000LL) return (hx>>48)-0x3fff;
+ else if (FP_ILOGBNAN != INT_MAX) {
+ /* ISO C99 requires ilogbl(+-Inf) == INT_MAX. */
+ if (((hx^0x7fff000000000000LL)|lx) == 0)
+ return INT_MAX;
+ }
+ return FP_ILOGBNAN;
+}
+weak_alias (__ilogbl, ilogbl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_isinfl.c b/libc/sysdeps/ieee754/ldbl-128/s_isinfl.c
new file mode 100644
index 000000000..0b3526bd7
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_isinfl.c
@@ -0,0 +1,29 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Change for long double by Jakub Jelinek <jj@ultra.linux.cz>
+ * Public domain.
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/*
+ * isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+int
+__isinfl (long double x)
+{
+ int64_t hx,lx;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ lx |= (hx & 0x7fffffffffffffffLL) ^ 0x7fff000000000000LL;
+ lx |= -lx;
+ return ~(lx >> 63) & (hx >> 62);
+}
+hidden_def (__isinfl)
+weak_alias (__isinfl, isinfl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_isnanl.c b/libc/sysdeps/ieee754/ldbl-128/s_isnanl.c
new file mode 100644
index 000000000..267ec8d0a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_isnanl.c
@@ -0,0 +1,43 @@
+/* s_isnanl.c -- long double version of s_isnan.c.
+ * Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * isnanl(x) returns 1 is x is nan, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __isnanl(long double x)
+#else
+ int __isnanl(x)
+ long double x;
+#endif
+{
+ int64_t hx,lx;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ hx &= 0x7fffffffffffffffLL;
+ hx |= (u_int64_t)(lx|(-lx))>>63;
+ hx = 0x7fff000000000000LL - hx;
+ return (int)((u_int64_t)hx>>63);
+}
+hidden_def (__isnanl)
+weak_alias (__isnanl, isnanl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_llrintl.c b/libc/sysdeps/ieee754/ldbl-128/s_llrintl.c
new file mode 100644
index 000000000..ee66454e2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_llrintl.c
@@ -0,0 +1,75 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+static const long double two112[2] =
+{
+ 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */
+ -5.19229685853482762853049632922009600E+33L /* 0xC06F000000000000, 0 */
+};
+
+long long int
+__llrintl (long double x)
+{
+ int32_t j0;
+ u_int64_t i0,i1;
+ volatile long double w;
+ long double t;
+ long long int result;
+ int sx;
+
+ GET_LDOUBLE_WORDS64 (i0, i1, x);
+ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
+ sx = i0 >> 63;
+ i0 &= 0x0000ffffffffffffLL;
+ i0 |= 0x0001000000000000LL;
+
+ if (j0 < (int32_t) (8 * sizeof (long long int)) - 1)
+ {
+ if (j0 < -1)
+ return 0;
+ w = two112[sx] + x;
+ t = w - two112[sx];
+ GET_LDOUBLE_WORDS64 (i0, i1, t);
+ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
+ i0 &= 0x0000ffffffffffffLL;
+ i0 |= 0x0001000000000000LL;
+
+ if (j0 <= 48)
+ result = i0 >> (48 - j0);
+ else
+ result = ((long long int) i0 << (j0 - 48)) | (i1 >> (112 - j0));
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long long int) x;
+ }
+
+ return sx ? -result : result;
+}
+
+weak_alias (__llrintl, llrintl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_llroundl.c b/libc/sysdeps/ieee754/ldbl-128/s_llroundl.c
new file mode 100644
index 000000000..b4609cdfd
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_llroundl.c
@@ -0,0 +1,77 @@
+/* Round long double value to long long int.
+ Copyright (C) 1997, 1999, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+long long int
+__llroundl (long double x)
+{
+ int64_t j0;
+ u_int64_t i1, i0;
+ long long int result;
+ int sign;
+
+ GET_LDOUBLE_WORDS64 (i0, i1, x);
+ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
+ sign = (i0 & 0x8000000000000000ULL) != 0 ? -1 : 1;
+ i0 &= 0x0000ffffffffffffLL;
+ i0 |= 0x0001000000000000LL;
+
+ if (j0 < 48)
+ {
+ if (j0 < 0)
+ return j0 < -1 ? 0 : sign;
+ else
+ {
+ i0 += 0x0000800000000000LL >> j0;
+ result = i0 >> (48 - j0);
+ }
+ }
+ else if (j0 < (int32_t) (8 * sizeof (long long int)) - 1)
+ {
+ if (j0 >= 112)
+ result = ((long long int) i0 << (j0 - 48)) | (i1 << (j0 - 112));
+ else
+ {
+ u_int64_t j = i1 + (0x8000000000000000ULL >> (j0 - 48));
+ if (j < i1)
+ ++i0;
+
+ if (j0 == 48)
+ result = (long long int) i0;
+ else
+ result = ((long long int) i0 << (j0 - 48)) | (j >> (112 - j0));
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long long int) x;
+ }
+
+ return sign * result;
+}
+
+weak_alias (__llroundl, llroundl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_log1pl.c b/libc/sysdeps/ieee754/ldbl-128/s_log1pl.c
new file mode 100644
index 000000000..64d514613
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_log1pl.c
@@ -0,0 +1,256 @@
+/* log1pl.c
+ *
+ * Relative error logarithm
+ * Natural logarithm of 1+x, 128-bit long double precision
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, log1pl();
+ *
+ * y = log1pl( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base e (2.718...) logarithm of 1+x.
+ *
+ * The argument 1+x is separated into its exponent and fractional
+ * parts. If the exponent is between -1 and +1, the logarithm
+ * of the fraction is approximated by
+ *
+ * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x).
+ *
+ * Otherwise, setting z = 2(w-1)/(w+1),
+ *
+ * log(w) = z + z^3 P(z)/Q(z).
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -1, 8 100000 1.9e-34 4.3e-35
+ */
+
+/* Copyright 2001 by Stephen L. Moshier
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+#include "math.h"
+#include "math_private.h"
+
+/* Coefficients for log(1+x) = x - x^2 / 2 + x^3 P(x)/Q(x)
+ * 1/sqrt(2) <= 1+x < sqrt(2)
+ * Theoretical peak relative error = 5.3e-37,
+ * relative peak error spread = 2.3e-14
+ */
+static const long double
+ P12 = 1.538612243596254322971797716843006400388E-6L,
+ P11 = 4.998469661968096229986658302195402690910E-1L,
+ P10 = 2.321125933898420063925789532045674660756E1L,
+ P9 = 4.114517881637811823002128927449878962058E2L,
+ P8 = 3.824952356185897735160588078446136783779E3L,
+ P7 = 2.128857716871515081352991964243375186031E4L,
+ P6 = 7.594356839258970405033155585486712125861E4L,
+ P5 = 1.797628303815655343403735250238293741397E5L,
+ P4 = 2.854829159639697837788887080758954924001E5L,
+ P3 = 3.007007295140399532324943111654767187848E5L,
+ P2 = 2.014652742082537582487669938141683759923E5L,
+ P1 = 7.771154681358524243729929227226708890930E4L,
+ P0 = 1.313572404063446165910279910527789794488E4L,
+ /* Q12 = 1.000000000000000000000000000000000000000E0L, */
+ Q11 = 4.839208193348159620282142911143429644326E1L,
+ Q10 = 9.104928120962988414618126155557301584078E2L,
+ Q9 = 9.147150349299596453976674231612674085381E3L,
+ Q8 = 5.605842085972455027590989944010492125825E4L,
+ Q7 = 2.248234257620569139969141618556349415120E5L,
+ Q6 = 6.132189329546557743179177159925690841200E5L,
+ Q5 = 1.158019977462989115839826904108208787040E6L,
+ Q4 = 1.514882452993549494932585972882995548426E6L,
+ Q3 = 1.347518538384329112529391120390701166528E6L,
+ Q2 = 7.777690340007566932935753241556479363645E5L,
+ Q1 = 2.626900195321832660448791748036714883242E5L,
+ Q0 = 3.940717212190338497730839731583397586124E4L;
+
+/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
+ * where z = 2(x-1)/(x+1)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 1.1e-35,
+ * relative peak error spread 1.1e-9
+ */
+static const long double
+ R5 = -8.828896441624934385266096344596648080902E-1L,
+ R4 = 8.057002716646055371965756206836056074715E1L,
+ R3 = -2.024301798136027039250415126250455056397E3L,
+ R2 = 2.048819892795278657810231591630928516206E4L,
+ R1 = -8.977257995689735303686582344659576526998E4L,
+ R0 = 1.418134209872192732479751274970992665513E5L,
+ /* S6 = 1.000000000000000000000000000000000000000E0L, */
+ S5 = -1.186359407982897997337150403816839480438E2L,
+ S4 = 3.998526750980007367835804959888064681098E3L,
+ S3 = -5.748542087379434595104154610899551484314E4L,
+ S2 = 4.001557694070773974936904547424676279307E5L,
+ S1 = -1.332535117259762928288745111081235577029E6L,
+ S0 = 1.701761051846631278975701529965589676574E6L;
+
+/* C1 + C2 = ln 2 */
+static const long double C1 = 6.93145751953125E-1L;
+static const long double C2 = 1.428606820309417232121458176568075500134E-6L;
+
+static const long double sqrth = 0.7071067811865475244008443621048490392848L;
+/* ln (2^16384 * (1 - 2^-113)) */
+static const long double maxlog = 1.1356523406294143949491931077970764891253E4L;
+static const long double big = 2e4932L;
+static const long double zero = 0.0L;
+
+#if 1
+/* Make sure these are prototyped. */
+long double frexpl (long double, int *);
+long double ldexpl (long double, int);
+#endif
+
+
+long double
+__log1pl (long double xm1)
+{
+ long double x, y, z, r, s;
+ ieee854_long_double_shape_type u;
+ int32_t hx;
+ int e;
+
+ /* Test for NaN or infinity input. */
+ u.value = xm1;
+ hx = u.parts32.w0;
+ if (hx >= 0x7fff0000)
+ return xm1;
+
+ /* log1p(+- 0) = +- 0. */
+ if (((hx & 0x7fffffff) == 0)
+ && (u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0)
+ return xm1;
+
+ x = xm1 + 1.0L;
+
+ /* log1p(-1) = -inf */
+ if (x <= 0.0L)
+ {
+ if (x == 0.0L)
+ return (-1.0L / (x - x));
+ else
+ return (zero / (x - x));
+ }
+
+ /* Separate mantissa from exponent. */
+
+ /* Use frexp used so that denormal numbers will be handled properly. */
+ x = frexpl (x, &e);
+
+ /* Logarithm using log(x) = z + z^3 P(z^2)/Q(z^2),
+ where z = 2(x-1)/x+1). */
+ if ((e > 2) || (e < -2))
+ {
+ if (x < sqrth)
+ { /* 2( 2x-1 )/( 2x+1 ) */
+ e -= 1;
+ z = x - 0.5L;
+ y = 0.5L * z + 0.5L;
+ }
+ else
+ { /* 2 (x-1)/(x+1) */
+ z = x - 0.5L;
+ z -= 0.5L;
+ y = 0.5L * x + 0.5L;
+ }
+ x = z / y;
+ z = x * x;
+ r = ((((R5 * z
+ + R4) * z
+ + R3) * z
+ + R2) * z
+ + R1) * z
+ + R0;
+ s = (((((z
+ + S5) * z
+ + S4) * z
+ + S3) * z
+ + S2) * z
+ + S1) * z
+ + S0;
+ z = x * (z * r / s);
+ z = z + e * C2;
+ z = z + x;
+ z = z + e * C1;
+ return (z);
+ }
+
+
+ /* Logarithm using log(1+x) = x - .5x^2 + x^3 P(x)/Q(x). */
+
+ if (x < sqrth)
+ {
+ e -= 1;
+ if (e != 0)
+ x = 2.0L * x - 1.0L; /* 2x - 1 */
+ else
+ x = xm1;
+ }
+ else
+ {
+ if (e != 0)
+ x = x - 1.0L;
+ else
+ x = xm1;
+ }
+ z = x * x;
+ r = (((((((((((P12 * x
+ + P11) * x
+ + P10) * x
+ + P9) * x
+ + P8) * x
+ + P7) * x
+ + P6) * x
+ + P5) * x
+ + P4) * x
+ + P3) * x
+ + P2) * x
+ + P1) * x
+ + P0;
+ s = (((((((((((x
+ + Q11) * x
+ + Q10) * x
+ + Q9) * x
+ + Q8) * x
+ + Q7) * x
+ + Q6) * x
+ + Q5) * x
+ + Q4) * x
+ + Q3) * x
+ + Q2) * x
+ + Q1) * x
+ + Q0;
+ y = x * (z * r / s);
+ y = y + e * C2;
+ z = y - 0.5L * z;
+ z = z + x;
+ z = z + e * C1;
+ return (z);
+}
+
+weak_alias (__log1pl, log1pl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_logbl.c b/libc/sysdeps/ieee754/ldbl-128/s_logbl.c
new file mode 100644
index 000000000..1fda28931
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_logbl.c
@@ -0,0 +1,46 @@
+/* s_logbl.c -- long double version of s_logb.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * long double logbl(x)
+ * IEEE 754 logb. Included to pass IEEE test suite. Not recommend.
+ * Use ilogb instead.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __logbl(long double x)
+#else
+ long double __logbl(x)
+ long double x;
+#endif
+{
+ int64_t lx,hx;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ hx &= 0x7fffffffffffffffLL; /* high |x| */
+ if((hx|lx)==0) return -1.0/fabs(x);
+ if(hx>=0x7fff000000000000LL) return x*x;
+ if((hx>>=48)==0) /* IEEE 754 logb */
+ return -16382.0;
+ else
+ return (long double) (hx-0x3fff);
+}
+weak_alias (__logbl, logbl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_lrintl.c b/libc/sysdeps/ieee754/ldbl-128/s_lrintl.c
new file mode 100644
index 000000000..66f9a429f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_lrintl.c
@@ -0,0 +1,94 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 1999, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+static const long double two112[2] =
+{
+ 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */
+ -5.19229685853482762853049632922009600E+33L /* 0xC06F000000000000, 0 */
+};
+
+long int
+__lrintl (long double x)
+{
+ int32_t j0;
+ u_int64_t i0,i1;
+ volatile long double w;
+ long double t;
+ long int result;
+ int sx;
+
+ GET_LDOUBLE_WORDS64 (i0, i1, x);
+ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
+ sx = i0 >> 63;
+ i0 &= 0x0000ffffffffffffLL;
+ i0 |= 0x0001000000000000LL;
+
+ if (j0 < 48)
+ {
+ if (j0 < -1)
+ return 0;
+ else
+ {
+ w = two112[sx] + x;
+ t = w - two112[sx];
+ GET_LDOUBLE_WORDS64 (i0, i1, x);
+ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
+ i0 &= 0x0000ffffffffffffLL;
+ i0 |= 0x0001000000000000LL;
+
+ result = i0 >> (48 - j0);
+ }
+ }
+ else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
+ {
+ if (j0 >= 112)
+ result = ((long int) i0 << (j0 - 48)) | (i1 << (j0 - 112));
+ else
+ {
+ w = two112[sx] + x;
+ t = w - two112[sx];
+ GET_LDOUBLE_WORDS64 (i0, i1, x);
+ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
+ i0 &= 0x0000ffffffffffffLL;
+ i0 |= 0x0001000000000000LL;
+
+ if (j0 == 48)
+ result = (long int) i0;
+ else
+ result = ((long int) i0 << (j0 - 48)) | (i1 >> (112 - j0));
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long int) x;
+ }
+
+ return sx ? -result : result;
+}
+
+weak_alias (__lrintl, lrintl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_lroundl.c b/libc/sysdeps/ieee754/ldbl-128/s_lroundl.c
new file mode 100644
index 000000000..1346a0461
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_lroundl.c
@@ -0,0 +1,77 @@
+/* Round long double value to long int.
+ Copyright (C) 1997, 1999, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+long int
+__lroundl (long double x)
+{
+ int64_t j0;
+ u_int64_t i1, i0;
+ long int result;
+ int sign;
+
+ GET_LDOUBLE_WORDS64 (i0, i1, x);
+ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
+ sign = (i0 & 0x8000000000000000ULL) != 0 ? -1 : 1;
+ i0 &= 0x0000ffffffffffffLL;
+ i0 |= 0x0001000000000000LL;
+
+ if (j0 < 48)
+ {
+ if (j0 < 0)
+ return j0 < -1 ? 0 : sign;
+ else
+ {
+ i0 += 0x0000800000000000LL >> j0;
+ result = i0 >> (48 - j0);
+ }
+ }
+ else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
+ {
+ if (j0 >= 112)
+ result = ((long int) i0 << (j0 - 48)) | (i1 << (j0 - 112));
+ else
+ {
+ u_int64_t j = i1 + (0x8000000000000000ULL >> (j0 - 48));
+ if (j < i1)
+ ++i0;
+
+ if (j0 == 48)
+ result = (long int) i0;
+ else
+ result = ((long int) i0 << (j0 - 48)) | (j >> (112 - j0));
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long int) x;
+ }
+
+ return sign * result;
+}
+
+weak_alias (__lroundl, lroundl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_modfl.c b/libc/sysdeps/ieee754/ldbl-128/s_modfl.c
new file mode 100644
index 000000000..63d66e711
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_modfl.c
@@ -0,0 +1,88 @@
+/* s_modfl.c -- long double version of s_modf.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * modfl(long double x, long double *iptr)
+ * return fraction part of x, and return x's integral part in *iptr.
+ * Method:
+ * Bit twiddling.
+ *
+ * Exception:
+ * No exception.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0;
+#else
+static long double one = 1.0;
+#endif
+
+#ifdef __STDC__
+ long double __modfl(long double x, long double *iptr)
+#else
+ long double __modfl(x, iptr)
+ long double x,*iptr;
+#endif
+{
+ int64_t i0,i1,j0;
+ u_int64_t i;
+ GET_LDOUBLE_WORDS64(i0,i1,x);
+ j0 = ((i0>>48)&0x7fff)-0x3fff; /* exponent of x */
+ if(j0<48) { /* integer part in high x */
+ if(j0<0) { /* |x|<1 */
+ /* *iptr = +-0 */
+ SET_LDOUBLE_WORDS64(*iptr,i0&0x8000000000000000ULL,0);
+ return x;
+ } else {
+ i = (0x0000ffffffffffffLL)>>j0;
+ if(((i0&i)|i1)==0) { /* x is integral */
+ *iptr = x;
+ /* return +-0 */
+ SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0);
+ return x;
+ } else {
+ SET_LDOUBLE_WORDS64(*iptr,i0&(~i),0);
+ return x - *iptr;
+ }
+ }
+ } else if (j0>111) { /* no fraction part */
+ *iptr = x*one;
+ /* We must handle NaNs separately. */
+ if (j0 == 0x4000 && ((i0 & 0x0000ffffffffffffLL) | i1))
+ return x*one;
+ /* return +-0 */
+ SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0);
+ return x;
+ } else { /* fraction part in low x */
+ i = -1ULL>>(j0-48);
+ if((i1&i)==0) { /* x is integral */
+ *iptr = x;
+ /* return +-0 */
+ SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0);
+ return x;
+ } else {
+ SET_LDOUBLE_WORDS64(*iptr,i0,i1&(~i));
+ return x - *iptr;
+ }
+ }
+}
+weak_alias (__modfl, modfl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_nearbyintl.c b/libc/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
new file mode 100644
index 000000000..bea3183d3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
@@ -0,0 +1,93 @@
+/* s_nearbyintl.c -- long double version of s_nearbyint.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/*
+ * nearbyintl(x)
+ * Return x rounded to integral value according to the prevailing
+ * rounding mode.
+ * Method:
+ * Using floating addition.
+ * Exception:
+ * Inexact flag raised if x not equal to rintl(x).
+ */
+
+#include <fenv.h>
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+TWO112[2]={
+ 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */
+ -5.19229685853482762853049632922009600E+33L /* 0xC06F000000000000, 0 */
+};
+
+#ifdef __STDC__
+ long double __nearbyintl(long double x)
+#else
+ long double __nearbyintl(x)
+ long double x;
+#endif
+{
+ fenv_t env;
+ int64_t i0,j0,sx;
+ u_int64_t i,i1;
+ long double w,t;
+ GET_LDOUBLE_WORDS64(i0,i1,x);
+ sx = (((u_int64_t)i0)>>63);
+ j0 = ((i0>>48)&0x7fff)-0x3fff;
+ if(j0<48) {
+ if(j0<0) {
+ if(((i0&0x7fffffffffffffffLL)|i1)==0) return x;
+ i1 |= (i0&0x0000ffffffffffffLL);
+ i0 &= 0xffffe00000000000ULL;
+ i0 |= ((i1|-i1)>>16)&0x0000800000000000LL;
+ SET_LDOUBLE_MSW64(x,i0);
+ feholdexcept (&env);
+ w = TWO112[sx]+x;
+ t = w-TWO112[sx];
+ fesetenv (&env);
+ GET_LDOUBLE_MSW64(i0,t);
+ SET_LDOUBLE_MSW64(t,(i0&0x7fffffffffffffffLL)|(sx<<63));
+ return t;
+ } else {
+ i = (0x0000ffffffffffffLL)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ i>>=1;
+ if(((i0&i)|i1)!=0) {
+ if(j0==47) i1 = 0x4000000000000000ULL; else
+ i0 = (i0&(~i))|((0x0000200000000000LL)>>j0);
+ }
+ }
+ } else if (j0>111) {
+ if(j0==0x4000) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = -1ULL>>(j0-48);
+ if((i1&i)==0) return x; /* x is integral */
+ i>>=1;
+ if((i1&i)!=0) i1 = (i1&(~i))|((0x4000000000000000LL)>>(j0-48));
+ }
+ SET_LDOUBLE_WORDS64(x,i0,i1);
+ feholdexcept (&env);
+ w = TWO112[sx]+x;
+ t = w-TWO112[sx];
+ fesetenv (&env);
+ return t;
+}
+weak_alias (__nearbyintl, nearbyintl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_nextafterl.c b/libc/sysdeps/ieee754/ldbl-128/s_nextafterl.c
new file mode 100644
index 000000000..d3df66817
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_nextafterl.c
@@ -0,0 +1,85 @@
+/* s_nextafterl.c -- long double version of s_nextafter.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/* IEEE functions
+ * nextafterl(x,y)
+ * return the next machine floating-point number of x in the
+ * direction toward y.
+ * Special cases:
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __nextafterl(long double x, long double y)
+#else
+ long double __nextafterl(x,y)
+ long double x,y;
+#endif
+{
+ int64_t hx,hy,ix,iy;
+ u_int64_t lx,ly;
+
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ GET_LDOUBLE_WORDS64(hy,ly,y);
+ ix = hx&0x7fffffffffffffffLL; /* |x| */
+ iy = hy&0x7fffffffffffffffLL; /* |y| */
+
+ if(((ix>=0x7fff000000000000LL)&&((ix-0x7fff000000000000LL)|lx)!=0) || /* x is nan */
+ ((iy>=0x7fff000000000000LL)&&((iy-0x7fff000000000000LL)|ly)!=0)) /* y is nan */
+ return x+y;
+ if(x==y) return y; /* x=y, return y */
+ if((ix|lx)==0) { /* x == 0 */
+ SET_LDOUBLE_WORDS64(x,hy&0x8000000000000000ULL,1);/* return +-minsubnormal */
+ y = x*x;
+ if(y==x) return y; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */
+ if(lx==0) hx--;
+ lx--;
+ } else { /* x < y, x += ulp */
+ lx++;
+ if(lx==0) hx++;
+ }
+ } else { /* x < 0 */
+ if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
+ if(lx==0) hx--;
+ lx--;
+ } else { /* x > y, x += ulp */
+ lx++;
+ if(lx==0) hx++;
+ }
+ }
+ hy = hx&0x7fff000000000000LL;
+ if(hy==0x7fff000000000000LL) return x+x;/* overflow */
+ if(hy==0) { /* underflow */
+ y = x*x;
+ if(y!=x) { /* raise underflow flag */
+ SET_LDOUBLE_WORDS64(y,hx,lx);
+ return y;
+ }
+ }
+ SET_LDOUBLE_WORDS64(x,hx,lx);
+ return x;
+}
+weak_alias (__nextafterl, nextafterl)
+strong_alias (__nextafterl, __nexttowardl)
+weak_alias (__nextafterl, nexttowardl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_nexttoward.c b/libc/sysdeps/ieee754/ldbl-128/s_nexttoward.c
new file mode 100644
index 000000000..553e40197
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_nexttoward.c
@@ -0,0 +1,104 @@
+/* s_nexttoward.c
+ * Conversion from s_nextafter.c by Ulrich Drepper, Cygnus Support,
+ * drepper@cygnus.com and Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/* IEEE functions
+ * nexttoward(x,y)
+ * return the next machine floating-point number of x in the
+ * direction toward y.
+ * Special cases:
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <float.h>
+
+#ifdef __STDC__
+ double __nexttoward(double x, long double y)
+#else
+ double __nexttoward(x,y)
+ double x;
+ long double y;
+#endif
+{
+ int32_t hx,ix;
+ int64_t hy,iy;
+ u_int32_t lx;
+ u_int64_t ly;
+
+ EXTRACT_WORDS(hx,lx,x);
+ GET_LDOUBLE_WORDS64(hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = hy&0x7fffffffffffffffLL; /* |y| */
+
+ if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */
+ ((iy>=0x7fff000000000000LL)&&((iy-0x7fff000000000000LL)|ly)!=0))
+ /* y is nan */
+ return x+y;
+ if((long double) x==y) return y; /* x=y, return y */
+ if((ix|lx)==0) { /* x == 0 */
+ double x2;
+ INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */
+ x2 = x*x;
+ if(x2==x) return x2; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if (hy<0||(ix>>20)>(iy>>48)-0x3c00
+ || ((ix>>20)==(iy>>48)-0x3c00
+ && (((((int64_t)hx)<<28)|(lx>>4))>(hy&0x0000ffffffffffffLL)
+ || (((((int64_t)hx)<<28)|(lx>>4))==(hy&0x0000ffffffffffffLL)
+ && (lx&0xf)>(ly>>60))))) { /* x > y, x -= ulp */
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { /* x < y, x += ulp */
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ } else { /* x < 0 */
+ if (hy>=0||(ix>>20)>(iy>>48)-0x3c00
+ || ((ix>>20)==(iy>>48)-0x3c00
+ && (((((int64_t)hx)<<28)|(lx>>4))>(hy&0x0000ffffffffffffLL)
+ || (((((int64_t)hx)<<28)|(lx>>4))==(hy&0x0000ffffffffffffLL)
+ && (lx&0xf)>(ly>>60))))) { /* x < y, x -= ulp */
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { /* x > y, x += ulp */
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ }
+ hy = hx&0x7ff00000;
+ if(hy>=0x7ff00000) {
+ x = x+x; /* overflow */
+ if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
+ /* Force conversion to float. */
+ asm ("" : "=m"(x) : "m"(x));
+ return x;
+ }
+ if(hy<0x00100000) { /* underflow */
+ double x2 = x*x;
+ if(x2!=x) { /* raise underflow flag */
+ INSERT_WORDS(x2,hx,lx);
+ return x2;
+ }
+ }
+ INSERT_WORDS(x,hx,lx);
+ return x;
+}
+weak_alias (__nexttoward, nexttoward)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_nexttowardf.c b/libc/sysdeps/ieee754/ldbl-128/s_nexttowardf.c
new file mode 100644
index 000000000..1a22e0102
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_nexttowardf.c
@@ -0,0 +1,81 @@
+/* s_nexttowardf.c -- float version of s_nextafter.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com
+ * and Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float __nexttowardf(float x, long double y)
+#else
+ float __nexttowardf(x,y)
+ float x;
+ long double y;
+#endif
+{
+ int32_t hx,ix;
+ int64_t hy,iy;
+ u_int64_t ly;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_LDOUBLE_WORDS64(hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = hy&0x7fffffffffffffffLL; /* |y| */
+
+ if((ix>0x7f800000) || /* x is nan */
+ ((iy>=0x7fff000000000000LL)&&((iy-0x7fff000000000000LL)|ly)!=0))
+ /* y is nan */
+ return x+y;
+ if((long double) x==y) return y; /* x=y, return y */
+ if(ix==0) { /* x == 0 */
+ float x2;
+ SET_FLOAT_WORD(x,(u_int32_t)((hy>>32)&0x80000000)|1);/* return +-minsub*/
+ x2 = x*x;
+ if(x2==x) return x2; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if(hy<0||(ix>>23)>(iy>>48)-0x3f80
+ || ((ix>>23)==(iy>>48)-0x3f80
+ && (ix&0x7fffff)>((hy>>25)&0x7fffff))) {/* x > y, x -= ulp */
+ hx -= 1;
+ } else { /* x < y, x += ulp */
+ hx += 1;
+ }
+ } else { /* x < 0 */
+ if(hy>=0||(ix>>23)>(iy>>48)-0x3f80
+ || ((ix>>23)==(iy>>48)-0x3f80
+ && (ix&0x7fffff)>((hy>>25)&0x7fffff))) {/* x < y, x -= ulp */
+ hx -= 1;
+ } else { /* x > y, x += ulp */
+ hx += 1;
+ }
+ }
+ hy = hx&0x7f800000;
+ if(hy>=0x7f800000) return x+x; /* overflow */
+ if(hy<0x00800000) { /* underflow */
+ float x2 = x*x;
+ if(x2!=x) { /* raise underflow flag */
+ SET_FLOAT_WORD(x2,hx);
+ return x2;
+ }
+ }
+ SET_FLOAT_WORD(x,hx);
+ return x;
+}
+weak_alias (__nexttowardf, nexttowardf)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_remquol.c b/libc/sysdeps/ieee754/ldbl-128/s_remquol.c
new file mode 100644
index 000000000..ae896c807
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_remquol.c
@@ -0,0 +1,110 @@
+/* Compute remainder and a congruent to the quotient.
+ Copyright (C) 1997, 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+static const long double zero = 0.0;
+
+
+long double
+__remquol (long double x, long double y, int *quo)
+{
+ int64_t hx,hy;
+ u_int64_t sx,lx,ly,qs;
+ int cquo;
+
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+ GET_LDOUBLE_WORDS64 (hy, ly, y);
+ sx = hx & 0x8000000000000000ULL;
+ qs = sx ^ (hy & 0x8000000000000000ULL);
+ hy &= 0x7fffffffffffffffLL;
+ hx &= 0x7fffffffffffffffLL;
+
+ /* Purge off exception values. */
+ if ((hy | ly) == 0)
+ return (x * y) / (x * y); /* y = 0 */
+ if ((hx >= 0x7fff000000000000LL) /* x not finite */
+ || ((hy >= 0x7fff000000000000LL) /* y is NaN */
+ && (((hy - 0x7fff000000000000LL) | ly) != 0)))
+ return (x * y) / (x * y);
+
+ if (hy <= 0x7ffbffffffffffffLL)
+ x = __ieee754_fmodl (x, 8 * y); /* now x < 8y */
+
+ if (((hx - hy) | (lx - ly)) == 0)
+ {
+ *quo = qs ? -1 : 1;
+ return zero * x;
+ }
+
+ x = fabsl (x);
+ y = fabsl (y);
+ cquo = 0;
+
+ if (x >= 4 * y)
+ {
+ x -= 4 * y;
+ cquo += 4;
+ }
+ if (x >= 2 * y)
+ {
+ x -= 2 * y;
+ cquo += 2;
+ }
+
+ if (hy < 0x0002000000000000LL)
+ {
+ if (x + x > y)
+ {
+ x -= y;
+ ++cquo;
+ if (x + x >= y)
+ {
+ x -= y;
+ ++cquo;
+ }
+ }
+ }
+ else
+ {
+ long double y_half = 0.5L * y;
+ if (x > y_half)
+ {
+ x -= y;
+ ++cquo;
+ if (x >= y_half)
+ {
+ x -= y;
+ ++cquo;
+ }
+ }
+ }
+
+ *quo = qs ? -cquo : cquo;
+
+ if (sx)
+ x = -x;
+ return x;
+}
+weak_alias (__remquol, remquol)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_rintl.c b/libc/sysdeps/ieee754/ldbl-128/s_rintl.c
new file mode 100644
index 000000000..c3fc3ba19
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_rintl.c
@@ -0,0 +1,90 @@
+/* s_rintl.c -- long double version of s_rint.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * rintl(x)
+ * Return x rounded to integral value according to the prevailing
+ * rounding mode.
+ * Method:
+ * Using floating addition.
+ * Exception:
+ * Inexact flag raised if x not equal to rintl(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+TWO112[2]={
+ 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */
+ -5.19229685853482762853049632922009600E+33L /* 0xC06F000000000000, 0 */
+};
+
+#ifdef __STDC__
+ long double __rintl(long double x)
+#else
+ long double __rintl(x)
+ long double x;
+#endif
+{
+ int64_t i0,j0,sx;
+ u_int64_t i,i1;
+ long double w,t;
+ GET_LDOUBLE_WORDS64(i0,i1,x);
+ sx = (((u_int64_t)i0)>>63);
+ j0 = ((i0>>48)&0x7fff)-0x3fff;
+ if(j0<48) {
+ if(j0<0) {
+ if(((i0&0x7fffffffffffffffLL)|i1)==0) return x;
+ i1 |= (i0&0x0000ffffffffffffLL);
+ i0 &= 0xffffe00000000000ULL;
+ i0 |= ((i1|-i1)>>16)&0x0000800000000000LL;
+ SET_LDOUBLE_MSW64(x,i0);
+ w = TWO112[sx]+x;
+ t = w-TWO112[sx];
+ GET_LDOUBLE_MSW64(i0,t);
+ SET_LDOUBLE_MSW64(t,(i0&0x7fffffffffffffffLL)|(sx<<63));
+ return t;
+ } else {
+ i = (0x0000ffffffffffffLL)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ i>>=1;
+ if(((i0&i)|i1)!=0) {
+ if(j0==47) i1 = 0x4000000000000000ULL; else
+ i0 = (i0&(~i))|((0x0000200000000000LL)>>j0);
+ }
+ }
+ } else if (j0>111) {
+ if(j0==0x4000) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = -1ULL>>(j0-48);
+ if((i1&i)==0) return x; /* x is integral */
+ i>>=1;
+ if((i1&i)!=0) i1 = (i1&(~i))|((0x4000000000000000LL)>>(j0-48));
+ }
+ SET_LDOUBLE_WORDS64(x,i0,i1);
+ w = TWO112[sx]+x;
+ return w-TWO112[sx];
+}
+weak_alias (__rintl, rintl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_roundl.c b/libc/sysdeps/ieee754/ldbl-128/s_roundl.c
new file mode 100644
index 000000000..b68aeabab
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_roundl.c
@@ -0,0 +1,94 @@
+/* Round long double to integer away from zero.
+ Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+static const long double huge = 1.0E4930L;
+
+
+long double
+__roundl (long double x)
+{
+ int32_t j0;
+ u_int64_t i1, i0;
+
+ GET_LDOUBLE_WORDS64 (i0, i1, x);
+ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
+ if (j0 < 31)
+ {
+ if (j0 < 0)
+ {
+ if (huge + x > 0.0)
+ {
+ i0 &= 0x8000000000000000ULL;
+ if (j0 == -1)
+ i0 |= 0x3fff000000000000LL;
+ i1 = 0;
+ }
+ }
+ else
+ {
+ u_int64_t i = 0x0000ffffffffffffLL >> j0;
+ if (((i0 & i) | i1) == 0)
+ /* X is integral. */
+ return x;
+ if (huge + x > 0.0)
+ {
+ /* Raise inexact if x != 0. */
+ i0 += 0x0000800000000000LL >> j0;
+ i0 &= ~i;
+ i1 = 0;
+ }
+ }
+ }
+ else if (j0 > 111)
+ {
+ if (j0 == 0x4000)
+ /* Inf or NaN. */
+ return x + x;
+ else
+ return x;
+ }
+ else
+ {
+ u_int64_t i = -1ULL >> (j0 - 48);
+ if ((i1 & i) == 0)
+ /* X is integral. */
+ return x;
+
+ if (huge + x > 0.0)
+ {
+ /* Raise inexact if x != 0. */
+ u_int64_t j = i1 + (1LL << (111 - j0));
+ if (j < i1)
+ i0 += 1;
+ i1 = j;
+ }
+ i1 &= ~i;
+ }
+
+ SET_LDOUBLE_WORDS64 (x, i0, i1);
+ return x;
+}
+weak_alias (__roundl, roundl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_scalblnl.c b/libc/sysdeps/ieee754/ldbl-128/s_scalblnl.c
new file mode 100644
index 000000000..5e8b58b73
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_scalblnl.c
@@ -0,0 +1,70 @@
+/* s_scalblnl.c -- long double version of s_scalbn.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/* @(#)s_scalbn.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: $";
+#endif
+
+/*
+ * scalblnl (long double x, long int n)
+ * scalblnl(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+two114 = 2.0769187434139310514121985316880384E+34L, /* 0x4071000000000000, 0 */
+twom114 = 4.8148248609680896326399448564623183E-35L, /* 0x3F8D000000000000, 0 */
+huge = 1.0E+4900L,
+tiny = 1.0E-4900L;
+
+#ifdef __STDC__
+ long double __scalblnl (long double x, long int n)
+#else
+ long double __scalblnl (x,n)
+ long double x; long int n;
+#endif
+{
+ int64_t k,hx,lx;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ k = (hx>>48)&0x7fff; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((lx|(hx&0x7fffffffffffffffULL))==0) return x; /* +-0 */
+ x *= two114;
+ GET_LDOUBLE_MSW64(hx,x);
+ k = ((hx>>48)&0x7fff) - 114;
+ }
+ if (k==0x7fff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (n> 50000 || k > 0x7ffe)
+ return huge*__copysignl(huge,x); /* overflow */
+ if (n< -50000) return tiny*__copysignl(tiny,x); /*underflow*/
+ if (k > 0) /* normal result */
+ {SET_LDOUBLE_MSW64(x,(hx&0x8000ffffffffffffULL)|(k<<48)); return x;}
+ if (k <= -114)
+ return tiny*__copysignl(tiny,x); /*underflow*/
+ k += 114; /* subnormal result */
+ SET_LDOUBLE_MSW64(x,(hx&0x8000ffffffffffffULL)|(k<<48));
+ return x*twom114;
+}
+weak_alias (__scalblnl, scalblnl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_scalbnl.c b/libc/sysdeps/ieee754/ldbl-128/s_scalbnl.c
new file mode 100644
index 000000000..c54f064c0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_scalbnl.c
@@ -0,0 +1,70 @@
+/* s_scalbnl.c -- long double version of s_scalbn.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/* @(#)s_scalbn.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: $";
+#endif
+
+/*
+ * scalbnl (long double x, int n)
+ * scalbnl(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+two114 = 2.0769187434139310514121985316880384E+34L, /* 0x4071000000000000, 0 */
+twom114 = 4.8148248609680896326399448564623183E-35L, /* 0x3F8D000000000000, 0 */
+huge = 1.0E+4900L,
+tiny = 1.0E-4900L;
+
+#ifdef __STDC__
+ long double __scalbnl (long double x, int n)
+#else
+ long double __scalbnl (x,n)
+ long double x; int n;
+#endif
+{
+ int64_t k,hx,lx;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ k = (hx>>48)&0x7fff; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((lx|(hx&0x7fffffffffffffffULL))==0) return x; /* +-0 */
+ x *= two114;
+ GET_LDOUBLE_MSW64(hx,x);
+ k = ((hx>>48)&0x7fff) - 114;
+ }
+ if (k==0x7fff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (n> 50000 || k > 0x7ffe)
+ return huge*__copysignl(huge,x); /* overflow */
+ if (n< -50000) return tiny*__copysignl(tiny,x); /*underflow*/
+ if (k > 0) /* normal result */
+ {SET_LDOUBLE_MSW64(x,(hx&0x8000ffffffffffffULL)|(k<<48)); return x;}
+ if (k <= -114)
+ return tiny*__copysignl(tiny,x); /*underflow*/
+ k += 114; /* subnormal result */
+ SET_LDOUBLE_MSW64(x,(hx&0x8000ffffffffffffULL)|(k<<48));
+ return x*twom114;
+}
+weak_alias (__scalbnl, scalbnl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_signbitl.c b/libc/sysdeps/ieee754/ldbl-128/s_signbitl.c
new file mode 100644
index 000000000..68be5e8db
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_signbitl.c
@@ -0,0 +1,32 @@
+/* Return nonzero value if number is negative.
+ Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+int
+__signbitl (long double x)
+{
+ int64_t e;
+
+ GET_LDOUBLE_MSW64 (e, x);
+ return e < 0;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_sincosl.c b/libc/sysdeps/ieee754/ldbl-128/s_sincosl.c
new file mode 100644
index 000000000..82fcf0426
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_sincosl.c
@@ -0,0 +1,71 @@
+/* Compute sine and cosine of argument.
+ Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+void
+__sincosl (long double x, long double *sinx, long double *cosx)
+{
+ int64_t ix;
+
+ /* High word of x. */
+ GET_LDOUBLE_MSW64 (ix, x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffffffffffffLL;
+ if (ix <= 0x3ffe921fb54442d1LL)
+ __kernel_sincosl (x, 0.0L, sinx, cosx, 0);
+ else if (ix >= 0x7fff000000000000LL)
+ {
+ /* sin(Inf or NaN) is NaN */
+ *sinx = *cosx = x - x;
+ }
+ else
+ {
+ /* Argument reduction needed. */
+ long double y[2];
+ int n;
+
+ n = __ieee754_rem_pio2l (x, y);
+ switch (n & 3)
+ {
+ case 0:
+ __kernel_sincosl (y[0], y[1], sinx, cosx, 1);
+ break;
+ case 1:
+ __kernel_sincosl (y[0], y[1], cosx, sinx, 1);
+ *cosx = -*cosx;
+ break;
+ case 2:
+ __kernel_sincosl (y[0], y[1], sinx, cosx, 1);
+ *sinx = -*sinx;
+ *cosx = -*cosx;
+ break;
+ default:
+ __kernel_sincosl (y[0], y[1], cosx, sinx, 1);
+ *sinx = -*sinx;
+ break;
+ }
+ }
+}
+weak_alias (__sincosl, sincosl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_sinl.c b/libc/sysdeps/ieee754/ldbl-128/s_sinl.c
new file mode 100644
index 000000000..446a75f12
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_sinl.c
@@ -0,0 +1,83 @@
+/* s_sinl.c -- long double version of s_sin.c.
+ * Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* sinl(x)
+ * Return sine function of x.
+ *
+ * kernel function:
+ * __kernel_sinl ... sine function on [-pi/4,pi/4]
+ * __kernel_cosl ... cose function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2l ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __sinl(long double x)
+#else
+ long double __sinl(x)
+ long double x;
+#endif
+{
+ long double y[2],z=0.0L;
+ int64_t n, ix;
+
+ /* High word of x. */
+ GET_LDOUBLE_MSW64(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffffffffffffLL;
+ if(ix <= 0x3ffe921fb54442d1LL)
+ return __kernel_sinl(x,z,0);
+
+ /* sin(Inf or NaN) is NaN */
+ else if (ix>=0x7fff000000000000LL) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2l(x,y);
+ switch(n&3) {
+ case 0: return __kernel_sinl(y[0],y[1],1);
+ case 1: return __kernel_cosl(y[0],y[1]);
+ case 2: return -__kernel_sinl(y[0],y[1],1);
+ default:
+ return -__kernel_cosl(y[0],y[1]);
+ }
+ }
+}
+weak_alias (__sinl, sinl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_tanhl.c b/libc/sysdeps/ieee754/ldbl-128/s_tanhl.c
new file mode 100644
index 000000000..fcbf300a1
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_tanhl.c
@@ -0,0 +1,106 @@
+/* s_tanhl.c -- long double version of s_tanh.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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.
+ * ====================================================
+ */
+
+/* Changes for 128-bit long double contributed by
+ Stephen L. Moshier <moshier@na-net.ornl.gov> */
+
+/* tanhl(x)
+ * Return the Hyperbolic Tangent of x
+ *
+ * Method :
+ * x -x
+ * e - e
+ * 0. tanhl(x) is defined to be -----------
+ * x -x
+ * e + e
+ * 1. reduce x to non-negative by tanhl(-x) = -tanhl(x).
+ * 2. 0 <= x <= 2**-57 : tanhl(x) := x*(one+x)
+ * -t
+ * 2**-57 < x <= 1 : tanhl(x) := -----; t = expm1l(-2x)
+ * t + 2
+ * 2
+ * 1 <= x <= 40.0 : tanhl(x) := 1- ----- ; t=expm1l(2x)
+ * t + 2
+ * 40.0 < x <= INF : tanhl(x) := 1.
+ *
+ * Special cases:
+ * tanhl(NaN) is NaN;
+ * only tanhl(0)=0 is exact for finite argument.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0, two = 2.0, tiny = 1.0e-4900L;
+#else
+static long double one = 1.0, two = 2.0, tiny = 1.0e-4900L;
+#endif
+
+#ifdef __STDC__
+long double
+__tanhl (long double x)
+#else
+long double
+__tanhl (x)
+ long double x;
+#endif
+{
+ long double t, z;
+ u_int32_t jx, ix;
+ ieee854_long_double_shape_type u;
+
+ /* Words of |x|. */
+ u.value = x;
+ jx = u.parts32.w0;
+ ix = jx & 0x7fffffff;
+ /* x is INF or NaN */
+ if (ix >= 0x7fff0000)
+ {
+ /* for NaN it's not important which branch: tanhl(NaN) = NaN */
+ if (jx & 0x80000000)
+ return one / x - one; /* tanhl(-inf)= -1; */
+ else
+ return one / x + one; /* tanhl(+inf)=+1 */
+ }
+
+ /* |x| < 40 */
+ if (ix < 0x40044000)
+ {
+ if (u.value == 0)
+ return x; /* x == +- 0 */
+ if (ix < 0x3fc60000) /* |x| < 2^-57 */
+ return x * (one + tiny); /* tanh(small) = small */
+ u.parts32.w0 = ix; /* Absolute value of x. */
+ if (ix >= 0x3fff0000)
+ { /* |x| >= 1 */
+ t = __expm1l (two * u.value);
+ z = one - two / (t + two);
+ }
+ else
+ {
+ t = __expm1l (-two * u.value);
+ z = -t / (t + two);
+ }
+ /* |x| > 40, return +-1 */
+ }
+ else
+ {
+ z = one - tiny; /* raised inexact flag */
+ }
+ return (jx & 0x80000000) ? -z : z;
+}
+weak_alias (__tanhl, tanhl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_tanl.c b/libc/sysdeps/ieee754/ldbl-128/s_tanl.c
new file mode 100644
index 000000000..ea9d053d9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_tanl.c
@@ -0,0 +1,77 @@
+/* s_tanl.c -- long double version of s_tan.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/* @(#)s_tan.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.
+ * ====================================================
+ */
+
+/* tanl(x)
+ * Return tangent function of x.
+ *
+ * kernel function:
+ * __kernel_tanl ... tangent function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2l ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __tanl(long double x)
+#else
+ long double __tanl(x)
+ long double x;
+#endif
+{
+ long double y[2],z=0.0L;
+ int64_t n, ix;
+
+ /* High word of x. */
+ GET_LDOUBLE_MSW64(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffffffffffffLL;
+ if(ix <= 0x3ffe921fb54442d1LL) return __kernel_tanl(x,z,1);
+
+ /* tanl(Inf or NaN) is NaN */
+ else if (ix>=0x7fff000000000000LL) return x-x; /* NaN */
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2l(x,y);
+ return __kernel_tanl(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even
+ -1 -- n odd */
+ }
+}
+weak_alias (__tanl, tanl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/s_truncl.c b/libc/sysdeps/ieee754/ldbl-128/s_truncl.c
new file mode 100644
index 000000000..abd303045
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/s_truncl.c
@@ -0,0 +1,57 @@
+/* Truncate argument to nearest integral value not larger than the argument.
+ Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+long double
+__truncl (long double x)
+{
+ int32_t j0;
+ u_int64_t i0, i1, sx;
+
+ GET_LDOUBLE_WORDS64 (i0, i1, x);
+ sx = i0 & 0x8000000000000000ULL;
+ j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
+ if (j0 < 48)
+ {
+ if (j0 < 0)
+ /* The magnitude of the number is < 1 so the result is +-0. */
+ SET_LDOUBLE_WORDS64 (x, sx, 0);
+ else
+ SET_LDOUBLE_WORDS64 (x, i0 & ~(0x0000ffffffffffffLL >> j0), 0);
+ }
+ else if (j0 > 111)
+ {
+ if (j0 == 0x4000)
+ /* x is inf or NaN. */
+ return x + x;
+ }
+ else
+ {
+ SET_LDOUBLE_WORDS64 (x, i0, i1 & ~(0xffffffffffffffffULL >> (j0 - 48)));
+ }
+
+ return x;
+}
+weak_alias (__truncl, truncl)
diff --git a/libc/sysdeps/ieee754/ldbl-128/strtold_l.c b/libc/sysdeps/ieee754/ldbl-128/strtold_l.c
new file mode 100644
index 000000000..eb227fce6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/strtold_l.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1999, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+/* The actual implementation for all floating point sizes is in strtod.c.
+ These macros tell it to produce the `long double' version, `strtold'. */
+
+#define FLOAT long double
+#define FLT LDBL
+#ifdef USE_WIDE_CHAR
+# define STRTOF wcstold_l
+# define __STRTOF __wcstold_l
+#else
+# define STRTOF strtold_l
+# define __STRTOF __strtold_l
+#endif
+#define MPN2FLOAT __mpn_construct_long_double
+#define FLOAT_HUGE_VAL HUGE_VALL
+#define SET_MANTISSA(flt, mant) \
+ do { union ieee854_long_double u; \
+ u.d = (flt); \
+ u.ieee.mantissa0 = 0x8000; \
+ u.ieee.mantissa1 = 0; \
+ u.ieee.mantissa2 = ((mant) >> 32); \
+ u.ieee.mantissa3 = (mant) & 0xffffffff; \
+ (flt) = u.d; \
+ } while (0)
+
+#include <strtod_l.c>
diff --git a/libc/sysdeps/ieee754/ldbl-128/t_expl.h b/libc/sysdeps/ieee754/ldbl-128/t_expl.h
new file mode 100644
index 000000000..a72bfd0a6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/t_expl.h
@@ -0,0 +1,971 @@
+/* Accurate table for expl().
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* __expl_table basically consists of four tables, T_EXPL_ARG{1,2} and
+ T_EXPL_RES{1,2}. All tables use positive and negative indexes, the 0 points
+ are marked by T_EXPL_* defines.
+ For ARG1 and RES1 tables lets B be 89 and S 256.0, for ARG2 and RES2 B is 65
+ and S 32768.0.
+ These table have the property that, for all integers -B <= i <= B
+ expl(__expl_table[T_EXPL_ARGN+2*i]+__expl_table[T_EXPL_ARGN+2*i+1]+r) ==
+ __expl_table[T_EXPL_RESN+i], __expl_table[T_EXPL_RESN+i] is some exact number
+ with the low 58 bits of the mantissa 0,
+ __expl_table[T_EXPL_ARGN+2*i] == i/S+s
+ where absl(s) <= 2^-54 and absl(r) <= 2^-212. */
+
+static const long double __expl_table [] = {
+ -3.47656250000000000584188889839535373E-01L, /* bffd640000000000002b1b04213cf000 */
+ 6.90417668990715641167244540876988960E-32L, /* 3f97667c3fdb588a6ae1af8748357a17 */
+ -3.43749999999999981853132895957607418E-01L, /* bffd5ffffffffffffac4ff5f4050b000 */
+ -7.16021898043268093462818380603370350E-33L, /* bf94296c8219427edc1431ac2498583e */
+ -3.39843750000000013418643523138766329E-01L, /* bffd5c000000000003de1f027a30e000 */
+ 8.16920774283317801641347327589583265E-32L, /* 3f97a82b65774bdca1b4440d749ed8d3 */
+ -3.35937500000000014998092453039303051E-01L, /* bffd5800000000000452a9f4d8857000 */
+ -6.55865578425428447938248396879359670E-32L, /* bf97548b7d240f3d034b395e6eecfac8 */
+ -3.32031250000000000981984049529998541E-01L, /* bffd540000000000004875277cda5000 */
+ 6.91213046334032232108944519541512737E-32L, /* 3f9766e5f925338a19045c94443b66e1 */
+ -3.28124999999999986646017645350399708E-01L, /* bffd4ffffffffffffc26a667bf44d000 */
+ -6.16281060996110316602421505683742661E-32L, /* bf973ffdcdcffb6fbffc86b2b8d42f5d */
+ -3.24218749999999991645717430645867963E-01L, /* bffd4bfffffffffffd97901063e48000 */
+ -7.90797211087760527593856542417304137E-32L, /* bf979a9afaaca1ada6a8ed1c80584d60 */
+ -3.20312499999999998918211610690789652E-01L, /* bffd47ffffffffffffb02d9856d71000 */
+ 8.64024799457616856987630373786503376E-32L, /* 3f97c0a098623f95579d5d9b2b67342d */
+ -3.16406249999999998153974811017181883E-01L, /* bffd43ffffffffffff77c991f1076000 */
+ -2.73176610180696076418536105483668404E-32L, /* bf961baeccb32f9b1fcbb8e60468e95a */
+ -3.12500000000000011420976192575972779E-01L, /* bffd400000000000034ab8240483d000 */
+ 7.16573502812389453744433792609989420E-32L, /* 3f977410f4c2cfc4335f28446c0fb363 */
+ -3.08593750000000001735496343854851414E-01L, /* bffd3c000000000000800e995c176000 */
+ -1.56292999645122272621237565671593071E-32L, /* bf95449b9cbdaff6ac1246adb2c826ac */
+ -3.04687499999999982592401295899221626E-01L, /* bffd37fffffffffffafb8bc1e061a000 */
+ 6.48993208584888904958594509625158417E-32L, /* 3f9750f9fe8366d82d77afa0031a92e1 */
+ -3.00781249999999999230616898937763959E-01L, /* bffd33ffffffffffffc73ac39da54000 */
+ 6.57082437496961397305801409357792029E-32L, /* 3f97552d3cb598ea80135cf3feb27ec4 */
+ -2.96874999999999998788769281703245722E-01L, /* bffd2fffffffffffffa6a07fa5021000 */
+ -3.26588297198283968096426564544269170E-32L, /* bf9653260fc1802f46b629aee171809b */
+ -2.92968750000000015318089182805941695E-01L, /* bffd2c0000000000046a468614bd6000 */
+ -1.73291974845198589684358727559290718E-32L, /* bf9567e9d158f52e483c8d8dcb5961dd */
+ -2.89062500000000007736778942676309681E-01L, /* bffd280000000000023adf9f4c3d3000 */
+ -6.83629745986675744404029225571026236E-32L, /* bf9762f5face6281c1daf1c6aedbdb45 */
+ -2.85156250000000001367091555763661937E-01L, /* bffd2400000000000064dfa11e3fb000 */
+ -5.44898442619766878281110054067026237E-32L, /* bf971aed6d2db9f542986a785edae072 */
+ -2.81249999999999986958718100227029406E-01L, /* bffd1ffffffffffffc3db9265ca9d000 */
+ 1.13007318374506125723591889451107046E-32L, /* 3f94d569fe387f456a97902907ac3856 */
+ -2.77343750000000000356078829380495179E-01L, /* bffd1c0000000000001a462390083000 */
+ -4.98979365468978332358409063436543102E-32L, /* bf970315bbf3e0d14b5c94c900702d4c */
+ -2.73437499999999990276993957508540484E-01L, /* bffd17fffffffffffd32919bcdc94000 */
+ -8.79390484115892344533724650295100871E-32L, /* bf97c89b0b89cc19c3ab2b60da9bbbc3 */
+ -2.69531250000000002434203866460082225E-01L, /* bffd14000000000000b39ccf9e130000 */
+ 9.44060754687026590886751809927191596E-32L, /* 3f97ea2f32cfecca5c64a26137a9210f */
+ -2.65624999999999997296320716986257179E-01L, /* bffd0fffffffffffff3880f13a2bc000 */
+ 2.07142664067265697791007875348396921E-32L, /* 3f95ae37ee685b9122fbe377bd205ee4 */
+ -2.61718750000000010237478733739017956E-01L, /* bffd0c000000000002f3648179d40000 */
+ -6.10552936159265665298996309192680256E-32L, /* bf973d0467d31e407515a3cca0f3b4e2 */
+ -2.57812500000000011948220522778370303E-01L, /* bffd08000000000003719f81275bd000 */
+ 6.72477169058908902499239631466443836E-32L, /* 3f975d2b8c475d3160cf72d227d8e6f9 */
+ -2.53906249999999991822993360536596860E-01L, /* bffd03fffffffffffda4a4b62f818000 */
+ -2.44868296623215865054704392917190994E-32L, /* bf95fc92516c6d057d29fc2528855976 */
+ -2.49999999999999986862019457428548084E-01L, /* bffcfffffffffffff86d2d20d5ff4000 */
+ -3.85302898949105073614122724961613078E-32L, /* bf96901f147cb7d643af71b6129ce929 */
+ -2.46093750000000000237554160737318435E-01L, /* bffcf8000000000000230e8ade26b000 */
+ -1.52823675242678363494345369284988589E-32L, /* bf953d6700c5f3fc303f79d0ec8c680a */
+ -2.42187500000000003023380963205457065E-01L, /* bffcf0000000000001be2c1a78bb0000 */
+ -7.78402037952209709489481182714311699E-34L, /* bf9102ab1f3998e887f0ee4cf940faa5 */
+ -2.38281249999999995309623303145485725E-01L, /* bffce7fffffffffffd4bd2940f43f000 */
+ -3.54307216794236899443913216397197696E-32L, /* bf966fef03ab69c3f289436205b21d02 */
+ -2.34374999999999998425804947623207526E-01L, /* bffcdfffffffffffff17b097a6092000 */
+ -2.86038428948386602859761879407549696E-32L, /* bf96290a0eba0131efe3a05fe188f2e3 */
+ -2.30468749999999993822207406785200832E-01L, /* bffcd7fffffffffffc70519834eae000 */
+ -2.54339521031747516806893838749365762E-32L, /* bf96081f0ad7f9107ae6cddb32c178ab */
+ -2.26562499999999997823524030344489884E-01L, /* bffccffffffffffffebecf10093df000 */
+ 4.31904611473158635644635628922959401E-32L, /* 3f96c083f0b1faa7c4c686193e38d67c */
+ -2.22656250000000004835132405125162742E-01L, /* bffcc8000000000002c98a233f19f000 */
+ 2.54709791629335691650310168420597566E-33L, /* 3f92a735903f5eed07a716ab931e20d9 */
+ -2.18749999999999988969454021829236626E-01L, /* bffcbffffffffffff9a42dc14ce36000 */
+ -3.77236096429336082213752014054909454E-32L, /* bf9687be8e5b2fca54d3e81157eac660 */
+ -2.14843750000000010613256919115758495E-01L, /* bffcb80000000000061e3d828ecac000 */
+ -4.55194148712216691177097854305964738E-32L, /* bf96d8b35c776aa3e1a4768271380503 */
+ -2.10937499999999993204656148110447201E-01L, /* bffcaffffffffffffc152f2aea118000 */
+ -2.95044199165561453749332254271716417E-32L, /* bf96326433b00b2439094d9bef22ddd1 */
+ -2.07031250000000012233944895423355677E-01L, /* bffca80000000000070d695ee0e94000 */
+ 1.93146788688385419095981415411012357E-32L, /* 3f959126729135a5e390d4bb802a0bde */
+ -2.03125000000000008030983633336321863E-01L, /* bffca0000000000004a129fbc51af000 */
+ 2.37361904671826193563212931215900137E-32L, /* 3f95ecfb3c4ba1b97ea3ad45cbb1e68a */
+ -1.99218750000000001763815712796132779E-01L, /* bffc98000000000001044b12d9950000 */
+ -3.63171243370923753295192486732883239E-33L, /* bf932db5fb3f27c38e0fa7bbcfc64f55 */
+ -1.95312500000000004883660234506677272E-01L, /* bffc90000000000002d0b3779d1f9000 */
+ -3.19989507343607877747980892249711601E-33L, /* bf9309d63de96bb3ef744c865f22f1bd */
+ -1.91406250000000013720152363227519348E-01L, /* bffc88000000000007e8bcb387121000 */
+ -1.89295754093147174148371614722178860E-32L, /* bf958926e2e67dfe812c508290add2e7 */
+ -1.87500000000000000182342082774432620E-01L, /* bffc800000000000001ae8b06a39f000 */
+ -2.96812835183184815200854214892983927E-32L, /* bf96343a62d156bbe71f55d14ca4b6e5 */
+ -1.83593750000000012410147185883290345E-01L, /* bffc78000000000007276a1adda8d000 */
+ -2.02191931237489669058466239995304587E-32L, /* bf95a3efab92d26ec2df90df036a117f */
+ -1.79687499999999997439177363346082917E-01L, /* bffc6ffffffffffffe8616db2927d000 */
+ -9.92752326937775530007399526834009465E-33L, /* bf949c5f88ed17041e1a3f1829d543cd */
+ -1.75781249999999995824373974504785174E-01L, /* bffc67fffffffffffd97c94f13ea3000 */
+ 1.44184772065335613487885714828816178E-32L, /* 3f952b75c63476e7fcc2f5841c27bcce */
+ -1.71874999999999986685050259043077809E-01L, /* bffc5ffffffffffff8530f6bc531a000 */
+ -3.49007014971241147689894940544402482E-32L, /* bf966a6dfaa012aea8ffe6d90b02330f */
+ -1.67968749999999997316058782350439701E-01L, /* bffc57fffffffffffe73eb914f2aa000 */
+ 3.34025733574205019081305778794376391E-32L, /* 3f965adf4572561fd5456a6c13d8babf */
+ -1.64062499999999993322730602128318480E-01L, /* bffc4ffffffffffffc269be4f68f3000 */
+ -1.83345916769684984022099095506340635E-32L, /* bf957ccb69026cb2f6024c211576d5f4 */
+ -1.60156249999999992419000744447607979E-01L, /* bffc47fffffffffffba13df21784a000 */
+ 2.73442789798110494773517431626534726E-32L, /* 3f961bf58ff22c9b30f1e2b39f26d7d5 */
+ -1.56249999999999987665010524130393080E-01L, /* bffc3ffffffffffff8e3ad45e7508000 */
+ 2.02695576464836145806428118889332191E-32L, /* 3f95a4fb7435a4a2f71de81eb8ae75d1 */
+ -1.52343749999999989905291167951491803E-01L, /* bffc37fffffffffffa2e48aecfc24000 */
+ -3.61436631548815190395331054871041524E-32L, /* bf967756567ebd108075ae527cc2e7f0 */
+ -1.48437500000000006686107754967759751E-01L, /* bffc30000000000003dab20261b3c000 */
+ -2.15524270159131591469319477922198390E-32L, /* bf95bfa05b82ef3a708c4f0395e9fcf6 */
+ -1.44531250000000005132889939177166485E-01L, /* bffc28000000000002f57b1969e7b000 */
+ 2.74741116529653547935086189244019604E-32L, /* 3f961d4eb77c1185d34fe1b04a3f3cf5 */
+ -1.40625000000000000707469094533647325E-01L, /* bffc2000000000000068676d3d5c4000 */
+ 4.40607097220049957013547629906723266E-33L, /* 3f936e0ac425daf795b42913cf0ef881 */
+ -1.36718749999999995713752139187543306E-01L, /* bffc17fffffffffffd87762255991000 */
+ -3.73751317180116492404578048203389108E-32L, /* bf9684202491e9cbb7ceb67d9ff7e0c9 */
+ -1.32812500000000007198453630478482191E-01L, /* bffc10000000000004264de3a4379000 */
+ -3.97050085179660203884930593717220728E-32L, /* bf969c52048de14be3c9c1971e50869c */
+ -1.28906250000000006070486371645733082E-01L, /* bffc080000000000037fd87db2cb0000 */
+ 3.59610068058504988294019521946586131E-32L, /* 3f967570c10687cb8e9ebd0b280abf5a */
+ -1.25000000000000003700729208608337966E-01L, /* bffc00000000000002222198bbc74000 */
+ 3.23464851393124362331846965931995969E-33L, /* 3f930cb95da3bfc847e593716c91d57a */
+ -1.21093750000000013729038501177102555E-01L, /* bffbf000000000000fd418d1f5fda000 */
+ 2.45242487730722066611358741283977619E-32L, /* 3f95fd5945ad86a464292e26ac192a84 */
+ -1.17187499999999999765305306880205578E-01L, /* bffbdfffffffffffffbabaf869845000 */
+ -1.14557520298960389903199646350205537E-32L, /* bf94dbda735322179d9bcf392e1dd06d */
+ -1.13281250000000009579647893740755690E-01L, /* bffbd000000000000b0b69bae7ab9000 */
+ 2.37873962873837390105423621772752350E-32L, /* 3f95ee0b7e0bd5ac1f6fab1e2a71abc3 */
+ -1.09375000000000008981153004560108539E-01L, /* bffbc000000000000a5ac4bc1d2c3000 */
+ 1.53152444860014076105003555837231015E-32L, /* 3f953e15ce931e12ef9a152522e32bdd */
+ -1.05468749999999992399063850363228723E-01L, /* bffbaffffffffffff73c998091408000 */
+ -8.75920903597804862471749360196688834E-33L, /* bf946bd7e310a01bae5687ebdc47fcc5 */
+ -1.01562500000000007685885179918350550E-01L, /* bffba0000000000008dc7910a648c000 */
+ -4.63820993797174451904075397785059501E-33L, /* bf938153d0e54001a472da180fb5e8aa */
+ -9.76562499999999887262211517861331814E-02L, /* bffb8ffffffffffff300915aa6fd6000 */
+ -2.63767025974952608658936466715705903E-33L, /* bf92b64215bb8d520be5404620d38088 */
+ -9.37499999999999939650246024457439795E-02L, /* bffb7ffffffffffff90aca26bd0fc000 */
+ -1.72047822349322956713582039121348377E-32L, /* bf9565545015c5b9b56d02cfefca2c7d */
+ -8.98437500000000033088896383977486369E-02L, /* bffb70000000000003d09ca1e3cbe000 */
+ 3.04831994420989436248526129869697270E-33L, /* 3f92fa7d30d2ed90e7ebbd6231fd08b1 */
+ -8.59374999999999947312400115121319225E-02L, /* bffb5ffffffffffff9ecefc03376e000 */
+ 1.50416954438393392150792422537312281E-32L, /* 3f9538675ee99bd722fad0023c09c915 */
+ -8.20312500000000054182280847004695514E-02L, /* bffb500000000000063f2dbd40200000 */
+ 2.68399664523430004488075638997207289E-33L, /* 3f92bdf49766629882c49a3da88928ed */
+ -7.81250000000000114767533968079748798E-02L, /* bffb4000000000000d3b56f81ba70000 */
+ 1.72318124201659121296305402819694281E-32L, /* 3f9565e407aaabfb359e8a567d760de3 */
+ -7.42187500000000035531829472486812869E-02L, /* bffb3000000000000418b6e9b5388000 */
+ 2.09401756478514117051383998628099655E-32L, /* 3f95b2e91221fcd74be0a86d8ad658d2 */
+ -7.03124999999999987474933134860732535E-02L, /* bffb1ffffffffffffe8e53453d2ac000 */
+ 2.28515798224350800271565551341211666E-32L, /* 3f95da9bd6adf00894f05b5cc5530125 */
+ -6.64062500000000042267533361089054159E-02L, /* bffb10000000000004df8473dbcf2000 */
+ 1.97576478800281368377376002585430031E-32L, /* 3f959a59acbddb2f53bd3096b66370e9 */
+ -6.25000000000000066329769382774201686E-02L, /* bffb00000000000007a5b5914e336000 */
+ -1.46422615813786836245343723048221678E-33L, /* bf91e69295f069fc0c4a9db181ea25a3 */
+ -5.85937500000000002823707957982406053E-02L, /* bffae0000000000000a6aeab10592000 */
+ 9.25637741701318872896718218457555829E-33L, /* 3f94807eb021f1f40a37d4015b1eb76b */
+ -5.46875000000000081586888005226044448E-02L, /* bffac0000000000012d00a3171e3a000 */
+ -4.87144542459404765480424673678105050E-33L, /* bf9394b42faba6b7036fe7b36269daf3 */
+ -5.07812499999999927720348253140567013E-02L, /* bffa9fffffffffffef555cc8dd914000 */
+ -3.01901021987395945826043649523451725E-33L, /* bf92f59e7e3025691f290f8f67277faf */
+ -4.68749999999999935349476738962633103E-02L, /* bffa7ffffffffffff117b4ea2b876000 */
+ 1.21521638219189777347767475937119750E-32L, /* 3f94f8c7f88c5b56674b94d984ac8ecb */
+ -4.29687500000000056305562847814228219E-02L, /* bffa6000000000000cfbb19be30c0000 */
+ -1.18643699217679276275559592978275214E-32L, /* bf94ecd39f0833a876550e83eb012b99 */
+ -3.90624999999999962692914526031373542E-02L, /* bffa3ffffffffffff765c743922f9000 */
+ -4.91277156857520035712509544689973679E-33L, /* bf939823189996193872e58ac0dececb */
+ -3.51562500000000108152468207687602886E-02L, /* bffa20000000000018f031e41177f000 */
+ 1.18599806302656253755207072755609820E-32L, /* 3f94eca4f23e787fab73ce8f6b9b8d64 */
+ -3.12500000000000077376981036742289578E-02L, /* bffa00000000000011d787e0b386f000 */
+ 9.97730386477005171963635210799577079E-33L, /* 3f949e70e498c46a0173ac0d46c699fc */
+ -2.73437500000000139436129596418623235E-02L, /* bff9c00000000000404db66e70a08000 */
+ 2.25755321633070123579875157841633859E-33L, /* 3f927719b1a93074bdf9f3c2cb784785 */
+ -2.34375000000000088003629211828324876E-02L, /* bff98000000000002895a27d45feb000 */
+ 2.84374279216848803102126617873942975E-33L, /* 3f92d87f70e749d6da6c260b68dc210b */
+ -1.95312500000000107408831063404855424E-02L, /* bff9400000000000318898ba69f71000 */
+ 2.47348089686935458989103979140011912E-33L, /* 3f929afa3de45086fe909fdddb41edce */
+ -1.56250000000000081443917555362290635E-02L, /* bff9000000000000258f335e9cdd6000 */
+ -2.43379314483517422161458863218426254E-33L, /* bf9294621c8a9ccacf2b020ec19cad27 */
+ -1.17187500000000051490597418161403184E-02L, /* bff88000000000002f7ddfa26221f000 */
+ 1.83405297208145390679150568810924707E-33L, /* 3f9230bbfc5d5fe1b534fbcda0465bb9 */
+ -7.81249999999999715861805208310174953E-03L, /* bff7ffffffffffffcb95f3fff157d000 */
+ 3.51548384878710915171654413641872451E-34L, /* 3f8fd349b76c22966f77a39fc37ed704 */
+ -3.90625000000000309326013918295097128E-03L, /* bff7000000000000390f820c8e153000 */
+ 6.38058004651791109324060099097251911E-36L, /* 3f8a0f665d3ac25a1ac94d688273dbcd */
+#define T_EXPL_ARG1 (2*89)
+ 0.00000000000000000000000000000000000E+00L, /* 00000000000000000000000000000000 */
+ 0.00000000000000000000000000000000000E+00L, /* 00000000000000000000000000000000 */
+ 3.90625000000000245479958859972588985E-03L, /* 3ff70000000000002d48769ac9874000 */
+ -6.58439598384342854976169982902779828E-36L, /* bf8a1811b923e6c626b07ef29761482a */
+ 7.81250000000001311374391093664996358E-03L, /* 3ff800000000000078f3f3cd89111000 */
+ 2.60265650555493781464273319671555602E-33L, /* 3f92b070c3b635b87af426735a71fc87 */
+ 1.17187500000000269581156218247101912E-02L, /* 3ff8800000000000f8a50d02fe20d000 */
+ 1.00961747974945520631836275894919326E-33L, /* 3f914f80c1a4f8042044fe3b757b030b */
+ 1.56249999999999797878275270751825475E-02L, /* 3ff8ffffffffffff45935b69da62e000 */
+ 2.03174577741375590087897353146748580E-33L, /* 3f925194e863496e0f6e91cbf6b22e26 */
+ 1.95312499999999760319884511789111533E-02L, /* 3ff93fffffffffff917790ff9a8f4000 */
+ 4.62788519658803722282100289809515007E-33L, /* 3f9380783ba81295feeb3e4879d7d52d */
+ 2.34374999999999822953909016349145918E-02L, /* 3ff97fffffffffffae5a163bd3cd5000 */
+ -3.19499956304699705390404384504876533E-33L, /* bf93096e2037ced8194cf344c692f8d6 */
+ 2.73437500000000137220327275871555682E-02L, /* 3ff9c000000000003f481dea5dd51000 */
+ -2.25757776523031994464630107442723424E-33L, /* bf92771abcf988a02b414bf2614e3734 */
+ 3.12499999999999790857640618332718621E-02L, /* 3ff9ffffffffffff9f8cd40b51509000 */
+ -4.22479470489989916319395454536511458E-33L, /* bf935efb7245612f371deca17cb7b30c */
+ 3.51562499999999840753382405747597346E-02L, /* 3ffa1fffffffffffdb47bd275f722000 */
+ 1.08459658374118041980976756063083500E-34L, /* 3f8e2055d18b7117c9db1c318b1e889b */
+ 3.90624999999999989384433621470426757E-02L, /* 3ffa3ffffffffffffd8d5e18b042e000 */
+ -7.41674226146122000759491297811091830E-33L, /* bf94341454e48029e5b0205d91baffdc */
+ 4.29687500000000107505739500500200462E-02L, /* 3ffa60000000000018ca04cd9085c000 */
+ -4.74689012756713017494437969420919847E-34L, /* bf903b7c268103c6f7fbaaa24142e287 */
+ 4.68749999999999978700749928325717352E-02L, /* 3ffa7ffffffffffffb16b6d5479e3000 */
+ -1.06208165308448830117773486334902917E-32L, /* bf94b92be4b3b5b5a596a0a5187cc955 */
+ 5.07812499999999815072625435955786253E-02L, /* 3ffa9fffffffffffd55bd086d5cbc000 */
+ -9.37038897148383660401929567549111394E-33L, /* bf94853b111b0175b491c80d00419416 */
+ 5.46874999999999809511553152189867394E-02L, /* 3ffabfffffffffffd4138bfa74a61000 */
+ 1.06642963074562437340498606682822123E-32L, /* 3f94bafa3fe991b39255d563dfa05d89 */
+ 5.85937500000000184331996330905145551E-02L, /* 3ffae000000000002a810a5f2f8bf000 */
+ -1.76639977694797200820296641773791945E-34L, /* bf8ed596f07ce4408f1705c8ec16864c */
+ 6.25000000000000021544696744852045001E-02L, /* 3ffb000000000000027be32045e2b000 */
+ 1.68616371995798354366633034788947149E-32L, /* 3f955e33d7440794d8a1b25233d086ab */
+ 6.64062499999999965563110718495802889E-02L, /* 3ffb0ffffffffffffc079a38a3fed000 */
+ -1.82463217667830160048872113565316215E-32L, /* bf957af6163bcdb97cefab44a942482a */
+ 7.03124999999999759989183341261898222E-02L, /* 3ffb1fffffffffffe454218acea05000 */
+ -1.07843770101525495515646940862541503E-32L, /* bf94bff72aada26d94e76e71c07e0580 */
+ 7.42187499999999898968873730710101412E-02L, /* 3ffb2ffffffffffff45a166496dc1000 */
+ 1.28629441689592874462780757154138223E-32L, /* 3f950b2724597b8b93ce1e9d1cf4d035 */
+ 7.81249999999999957198938523510804668E-02L, /* 3ffb3ffffffffffffb10bc52adbc5000 */
+ 1.13297573459968118467100063135856856E-33L, /* 3f91787eea895b3c245899cf34ad0abd */
+ 8.20312500000000199911640621145851159E-02L, /* 3ffb500000000000170c59a661a89000 */
+ -1.51161335208135146756554123073528707E-32L, /* bf9539f326c5ca84e7db5401566f3775 */
+ 8.59375000000000134175373433347670743E-02L, /* 3ffb6000000000000f78287547af0000 */
+ 1.09763629458404270323909815379924900E-32L, /* 3f94c7f0b61b6e3e27d44b9f5bbc7e9d */
+ 8.98437500000000036533922600308306335E-02L, /* 3ffb70000000000004364a83b7a14000 */
+ 3.11459653680110433194288029777718358E-33L, /* 3f9302c0248136d65cebeab69488d949 */
+ 9.37500000000000184977946245216914691E-02L, /* 3ffb800000000000155395d870b17000 */
+ -4.66656154468277949130395786965043927E-33L, /* bf9383aec9b993b6db492b1ede786d8a */
+ 9.76562500000000237839723100419376084E-02L, /* 3ffb9000000000001b6bca237f6c4000 */
+ -1.03028043424658760249140747856831301E-32L, /* bf94abf6352e3d2bb398e47919a343fb */
+ 1.01562500000000012345545575236836572E-01L, /* 3ffba000000000000e3bc30cd9a1f000 */
+ 2.15755372310795701322789783729456319E-32L, /* 3f95c01b3b819edd9d07548fafd61550 */
+ 1.05468749999999976493840484471911438E-01L, /* 3ffbafffffffffffe4e634cd77985000 */
+ 1.78771847038773333029677216592309083E-32L, /* 3f95734b6ae650f33dd43c49a1df9fc0 */
+ 1.09375000000000002267015055992785402E-01L, /* 3ffbc00000000000029d1ad08de7b000 */
+ 6.23263106693943817730045115112427717E-33L, /* 3f9402e4b39ce2198a45e1d045868cd6 */
+ 1.13281250000000022354208618429577398E-01L, /* 3ffbd0000000000019c5cc3f9d2b5000 */
+ 5.40514416644786448581426756221178868E-33L, /* 3f93c10ab4021472c662f69435de9269 */
+ 1.17187500000000013252367133076817603E-01L, /* 3ffbe000000000000f47688cc561b000 */
+ -7.12412585457324989451327215568641325E-33L, /* bf9427ecb343a8d1758990565fcfbf45 */
+ 1.21093750000000020759863992944300792E-01L, /* 3ffbf0000000000017ef3af97bf04000 */
+ 6.26591408357572503875647872077266444E-33L, /* 3f940446a09a2da771b45fc075514d12 */
+ 1.25000000000000004739659392396765618E-01L, /* 3ffc00000000000002bb7344ecd89000 */
+ -1.55611398459729463981000080101758830E-32L, /* bf95433135febefa9e6aa4db39e263d2 */
+ 1.28906249999999982360888081057894783E-01L, /* 3ffc07fffffffffff5d4ed3154361000 */
+ -1.77531518652835570781208599686606474E-32L, /* bf9570b7f225ea076f97f418d11359c1 */
+ 1.32812500000000010568583998727400436E-01L, /* 3ffc1000000000000617a5d09526a000 */
+ 2.12104021624990594668286391598300893E-32L, /* 3f95b885d767a1048d93055927a27adc */
+ 1.36718749999999998434125157367005292E-01L, /* 3ffc17ffffffffffff18eaebc7970000 */
+ 2.50454798592543203967309921276955297E-32L, /* 3f9604164e5598528a76faff26cd1c97 */
+ 1.40625000000000015550032422969330356E-01L, /* 3ffc20000000000008f6c79d8928c000 */
+ 7.80972982879849783680252962992639832E-33L, /* 3f9444674acf2b3225c7647e0d95edf3 */
+ 1.44531250000000012402535562111122522E-01L, /* 3ffc28000000000007264a8bc1ff1000 */
+ 2.79662468716455159585514763921671876E-32L, /* 3f96226b095bd78aa650faf95a221993 */
+ 1.48437500000000007761020440087419948E-01L, /* 3ffc3000000000000479530ff8fe3000 */
+ 2.15518492972728435680556239996258527E-32L, /* 3f95bf9d49295e73a957906a029768cb */
+ 1.52343750000000001733189947520484032E-01L, /* 3ffc38000000000000ffc6109f71f000 */
+ 8.34032236093545825619420380704500188E-33L, /* 3f945a71851226a1d0ce5e656693153e */
+ 1.56249999999999988073295321246958484E-01L, /* 3ffc3ffffffffffff91fedd62ae0f000 */
+ 2.44119337150624789345260194989620908E-32L, /* 3f95fb041a57bc1c1280680ac1620bea */
+ 1.60156250000000002076894210913572460E-01L, /* 3ffc48000000000001327ed84a199000 */
+ -7.36124501128859978061216696286151753E-33L, /* bf9431c62f01e59d2c1e00f195a0037f */
+ 1.64062500000000000950861276373482172E-01L, /* 3ffc500000000000008c5285fba85000 */
+ -4.80566184447001164583855800470217373E-33L, /* bf938f3d1fcafd390f22f80e6c19421f */
+ 1.67968749999999989878071706155265999E-01L, /* 3ffc57fffffffffffa2a445c548c5000 */
+ -4.42154428718618459799673088733365064E-32L, /* bf96cb28cf1c1b28006d53ffe633b22a */
+ 1.71874999999999999459734108403218175E-01L, /* 3ffc5fffffffffffffb04554e9dd4000 */
+ -3.29736288190321377985697972236270628E-32L, /* bf96566af0ebc852e84be12859b24a31 */
+ 1.75781249999999997987525759778901845E-01L, /* 3ffc67fffffffffffed702df6ffff000 */
+ -1.28800728638468399687523924685844352E-32L, /* bf950b8236b88ca0c1b739dc91a7e3fc */
+ 1.79687500000000004929565820437175783E-01L, /* 3ffc70000000000002d779bb32d2e000 */
+ 1.60624461317978482424582320675174225E-32L, /* 3f954d9a9cc0c963fd081f3dc922d04e */
+ 1.83593750000000016873727045739708856E-01L, /* 3ffc78000000000009ba1f6263c9a000 */
+ -3.83390389582056606880506003118452558E-32L, /* bf968e22a5d826f77f19ee788474df22 */
+ 1.87500000000000013443068740761666872E-01L, /* 3ffc80000000000007bfd8c72a1bf000 */
+ -2.74141662712926256150154726565203091E-32L, /* bf961caf5ac59c7f941f928e324c2cc1 */
+ 1.91406249999999981494101786848611970E-01L, /* 3ffc87fffffffffff55502eeae001000 */
+ 3.68992437075565165346469517256118001E-32L, /* 3f967f2f03f9096793372a27b92ad79d */
+ 1.95312499999999989069921848800501648E-01L, /* 3ffc8ffffffffffff9b3015280394000 */
+ 3.69712249337856518452988332367785220E-32L, /* 3f967fee5fdb5bd501ff93516999faa0 */
+ 1.99218750000000021148042946919300804E-01L, /* 3ffc9800000000000c30e67939095000 */
+ 2.50142536781142175091322844848566649E-32L, /* 3f9603c34ae58e10b300b07137ee618a */
+ 2.03124999999999977732559198825437141E-01L, /* 3ffc9ffffffffffff329e7df079e4000 */
+ -2.41951877287895024779300892731537816E-32L, /* bf95f683aefe6965f080df8f59dd34a1 */
+ 2.07031249999999996744030653771913124E-01L, /* 3ffca7fffffffffffe1f80f4b73ca000 */
+ -1.94346475904454000031592792989765585E-32L, /* bf9593a44f87870a3d100d498501ecc7 */
+ 2.10937500000000000251399259834392298E-01L, /* 3ffcb000000000000025199873310000 */
+ -1.33528748788094249098998693871759411E-33L, /* bf91bbb9b25c813668d6103d08acac35 */
+ 2.14843749999999993936323609611875097E-01L, /* 3ffcb7fffffffffffc8128c866236000 */
+ 1.14839877977014974625242788556545292E-32L, /* 3f94dd06b4655c9b83a1305b240e7a42 */
+ 2.18750000000000015181732784749663837E-01L, /* 3ffcc0000000000008c06da5fff24000 */
+ 1.42689085313142539755499441881408391E-32L, /* 3f95285a87dfa7ea7dad5b3be8c669f4 */
+ 2.22656249999999992172647770539596569E-01L, /* 3ffcc7fffffffffffb7ce2fe531f6000 */
+ -3.34421462850496887359128610229650547E-32L, /* bf965b487962b5c2d9056ca6ac0c2e5c */
+ 2.26562499999999989595607223847082419E-01L, /* 3ffccffffffffffffa0095277be5c000 */
+ -3.08983588107248752517344356508205569E-32L, /* bf9640dded57157f8eded311213bdbcd */
+ 2.30468749999999979130462438434567117E-01L, /* 3ffcd7fffffffffff3f8332996560000 */
+ -3.01407539802851697849105682795217019E-32L, /* bf9638ffde35dbdfe1a1ffe45185de5d */
+ 2.34375000000000012194252337217891971E-01L, /* 3ffce0000000000007078dd402c86000 */
+ -8.46879710915628592284714319904522657E-33L, /* bf945fc7b29a2ac6c9eff9eb258a510f */
+ 2.38281249999999982991877076137149870E-01L, /* 3ffce7fffffffffff6320b486eece000 */
+ -2.93563878880439245627127095245798544E-32L, /* bf9630daaa4f40ff05caf29ace2ea7d4 */
+ 2.42187499999999981447559841442773990E-01L, /* 3ffceffffffffffff54e24a09a8d5000 */
+ -4.56766746558806021264215486909850481E-32L, /* bf96da556dee11f3113e5a3467b908e6 */
+ 2.46093749999999991067720539980207318E-01L, /* 3ffcf7fffffffffffad9d405dcb5d000 */
+ 2.14033004219908074003010247652128251E-32L, /* 3f95bc8776e8f9ae098884aa664cc3df */
+ 2.50000000000000016613825838126835953E-01L, /* 3ffd00000000000004c9e24c12bb3000 */
+ 2.57617532593749185996714235009382870E-32L, /* 3f960b867cc01178c0ec68226c6cb47d */
+ 2.53906250000000013372004437827044321E-01L, /* 3ffd04000000000003daae05b3168000 */
+ 7.20177123439204414298152646284640101E-32L, /* 3f9775eff59ddad7e7530b83934af87f */
+ 2.57812499999999995765234725413886085E-01L, /* 3ffd07fffffffffffec7878bad9d5000 */
+ 6.51253187532920882777046064603770602E-32L, /* 3f975226659ca241402e71c2011583b0 */
+ 2.61718750000000007647689994011222248E-01L, /* 3ffd0c000000000002344cc793a0f000 */
+ 3.02370610028725823590045201871491395E-32L, /* 3f9639ffe55fa2fa011674448b4e5b96 */
+ 2.65624999999999986893899042596554269E-01L, /* 3ffd0ffffffffffffc38f0c0a1e9f000 */
+ -2.07683715950724761146070082510569258E-32L, /* bf95af579a92e872fef81abfdf06bae8 */
+ 2.69531249999999979842788204900639327E-01L, /* 3ffd13fffffffffffa30a908d67db000 */
+ 8.71465252506557329027658736641075706E-32L, /* 3f97c47d99e19830447a42b1c0ffac61 */
+ 2.73437500000000006712165837793818271E-01L, /* 3ffd18000000000001ef453a58edb000 */
+ -6.62704045767568912140550474455810301E-32L, /* bf9758187a204dcb06ece46588aeeaba */
+ 2.77343749999999994411329302988535617E-01L, /* 3ffd1bfffffffffffe63a0fec9c9e000 */
+ -4.87273466291944117406493607771338767E-32L, /* bf96fa0381b0844a0be46bac2d673f0c */
+ 2.81250000000000012677892447379453135E-01L, /* 3ffd20000000000003a7769e125d6000 */
+ -8.55871796664700790726282049552906783E-32L, /* bf97bc64e01332cf7616b0091b8dff2c */
+ 2.85156249999999998558643013736363981E-01L, /* 3ffd23ffffffffffff95a5894bccf000 */
+ -1.33068334720606220176455289635046875E-32L, /* bf95145f43290ecf5b7adcb24697bc73 */
+ 2.89062500000000008831431235621753924E-01L, /* 3ffd280000000000028ba504fac59000 */
+ -9.34157398616814623985483776710704237E-32L, /* bf97e50ad1115b941fcb5f0c88a428f7 */
+ 2.92968750000000019840235286110877063E-01L, /* 3ffd2c000000000005b7f372d184f000 */
+ 4.99302093775173155906059132992249671E-33L, /* 3f939ecdcfb97bad3f8dbec5df5ec67d */
+ 2.96875000000000015867911730971630513E-01L, /* 3ffd3000000000000492d860c79db000 */
+ 7.86107787827057767235127454590866211E-33L, /* 3f944689517ee8f16cdb97d6a6938f32 */
+ 3.00781250000000015814100002286124758E-01L, /* 3ffd340000000000048edfe73a17d000 */
+ -1.65419431293024229981937172317171504E-32L, /* bf9557900e3efca16c89646b57f68dc0 */
+ 3.04687499999999985213157159965287195E-01L, /* 3ffd37fffffffffffbbcec6f99b36000 */
+ 9.68753602893894024018934325652944198E-32L, /* 3f97f70170e5458660c33a7e8d43d049 */
+ 3.08593749999999989969324338045156215E-01L, /* 3ffd3bfffffffffffd1bdde4d0fb1000 */
+ 7.10268609610294706092252562643261106E-32L, /* 3f9770cae45cdf615010401a4b37d8d4 */
+ 3.12500000000000002971606591018488854E-01L, /* 3ffd40000000000000db440fbc06b000 */
+ 6.38924218802905979887732294952782964E-32L, /* 3f974bbf988bb5622bd8fbaa46e8b811 */
+ 3.16406250000000006594921047402056305E-01L, /* 3ffd44000000000001e69e8954814000 */
+ 3.96079878754651470094149874444850097E-32L, /* 3f969b5017b9fa7a1e86975258c73d3d */
+ 3.20312500000000006713799366908329147E-01L, /* 3ffd48000000000001ef64159c065000 */
+ -1.86401314975634286055150437995880517E-32L, /* bf958323f0434911794e5fb8bfe136ba */
+ 3.24218749999999987061246567584951210E-01L, /* 3ffd4bfffffffffffc4549db9b928000 */
+ -3.18643523744758601387071062700407431E-32L, /* bf964ae5fa7e26c2c3981bed12e14372 */
+ 3.28124999999999991782776266707412953E-01L, /* 3ffd4ffffffffffffda1ad0840ca8000 */
+ -4.46964199751314296839915534813144652E-32L, /* bf96d0277729ffd74727150df6d15547 */
+ 3.32031250000000000393816557756032682E-01L, /* 3ffd540000000000001d0efc04fad000 */
+ -9.03246333902065439930373230002688649E-33L, /* bf947731a008748cc6dee948839ef7ae */
+ 3.35937499999999983810482995064392173E-01L, /* 3ffd57fffffffffffb556cab8ae61000 */
+ 5.27742727066129518825981597650621794E-32L, /* 3f9712050a6ddbf1cabf1b971f4b5d0b */
+ 3.39843750000000004310441349760912471E-01L, /* 3ffd5c0000000000013e0def5ddc4000 */
+ -3.85927263474732591932884416445586106E-32L, /* bf9690c51088ef3db9ca000829c450c2 */
+ 3.43749999999999990248130003997484364E-01L, /* 3ffd5ffffffffffffd3070624a0af000 */
+ 9.62005170171527308106468341512327487E-34L, /* 3f913fae595cea84432eb01430817fca */
+ 3.47656250000000004085726414568625697E-01L, /* 3ffd640000000000012d79309e291000 */
+ -6.59664093705705297250259434519072507E-32L, /* bf97568465eafb0e662e64a5dbfaf35f */
+
+ -1.98364257812501251077851763965418372E-03L, /* bff6040000000001cd90f658cf0b1000 */
+ -3.71984513103117734260309047540278737E-34L, /* bf8fee73c54483194782aac4a6154d11 */
+ -1.95312500000000378520649630233891879E-03L, /* bff60000000000008ba643bb5e2e8000 */
+ -1.12194202736719050440745599339855038E-34L, /* bf8e2a436aeff7bc529873354f47a3f5 */
+ -1.92260742187499397430259771221991482E-03L, /* bff5f7fffffffffe4361cb51170da000 */
+ -2.30068299876822157331268484824540848E-34L, /* bf8f31d02f85cfe8c0cc02276ce0f437 */
+ -1.89208984375001137424603270262074989E-03L, /* bff5f0000000000347456ed490c23000 */
+ -1.15012507244426243338260435466985403E-34L, /* bf8e31c174d5677a937a34ad8d2a70b4 */
+ -1.86157226562500172319250342061336738E-03L, /* bff5e800000000007f262fa3617b4000 */
+ -3.12438344643346437509767736937785561E-34L, /* bf8f9f4d426a2457c273d34ef7d9bde9 */
+ -1.83105468749999505256246872355430379E-03L, /* bff5dffffffffffe92f18c1c2b6fa000 */
+ -5.91130415288336591179087455220308942E-35L, /* bf8d3a4c80b42dc036bae446c9807f78 */
+ -1.80053710937499445182387245573120522E-03L, /* bff5d7fffffffffe669dea82b4a4c000 */
+ -1.92396289352411531324908916321392100E-34L, /* bf8eff7a2123fb573ba9778550d669bd */
+ -1.77001953125000387737631542516323906E-03L, /* bff5d000000000011e19915c3ddb7000 */
+ 7.91101758977203355387806553469731354E-36L, /* 3f8a507f5a70faaccf469e3461873dea */
+ -1.73950195312500034854670281415554486E-03L, /* bff5c8000000000019b7dc6ef97bd000 */
+ 1.55906551582436824067407021178835755E-34L, /* 3f8e9e7880333e34955aebcde3cfb053 */
+ -1.70898437499998955782591472611429852E-03L, /* bff5bffffffffffcfd80e88aa6b96000 */
+ 8.22951661962611381718215899498500357E-35L, /* 3f8db58e6031a779b59f6ece191de7cc */
+ -1.67846679687500586652037711131708544E-03L, /* bff5b80000000001b0df6fd21c133000 */
+ -8.96642618848426299713145894522897419E-35L, /* bf8ddcbcab46d531801bfae4121f2f8a */
+ -1.64794921875000109499161354039904782E-03L, /* bff5b0000000000050cbce8915575000 */
+ -2.88077905394253859590587789680486639E-34L, /* bf8f7eebd4dd860ef73b674d5e707959 */
+ -1.61743164062501133830507079150388351E-03L, /* bff5a80000000003449e8700c3e82000 */
+ -3.68271725851639066312899986829350273E-34L, /* bf8fe9845fe20a5fe74059e0cae185d6 */
+ -1.58691406249999015546015764131101956E-03L, /* bff59ffffffffffd2999e668cdd28000 */
+ 8.48197657099957029953716507898788812E-35L, /* 3f8dc2faaebb97392e451b07b28c4b12 */
+ -1.55639648437500317366570219290722587E-03L, /* bff5980000000000ea2cd9a40d256000 */
+ -3.45156704719737676412949957712570373E-36L, /* bf8925a079505516c8e317ac1ff53255 */
+ -1.52587890625000568759013197767046039E-03L, /* bff5900000000001a3ab8a3f6b698000 */
+ -1.01902948542497496574967177677556729E-34L, /* bf8e0ee78d94d9b5ad3d63ae35c9b554 */
+ -1.49536132812500945889014955936485340E-03L, /* bff5880000000002b9f1621b57743000 */
+ -3.32264697086631598830366079048117140E-34L, /* bf8fb9a7d14c32289204fbb0c9eb20e0 */
+ -1.46484374999999931883259902869504725E-03L, /* bff57fffffffffffcdbd1c90e1b4a000 */
+ -1.76487524793892929381101031660811433E-34L, /* bf8ed52f2f724bc1ae870b18356337b4 */
+ -1.43432617187498876325946983333888768E-03L, /* bff577fffffffffcc2dff8faa5570000 */
+ -3.54550084538495708816233114576143814E-34L, /* bf8fd74724576915868c1e8ce9f430f1 */
+ -1.40380859374999215367421282192718062E-03L, /* bff56ffffffffffdbd0b18aac65ed000 */
+ -1.90585907028351204486765167064669639E-34L, /* bf8efaaa0c0e23e50c11b2120348054f */
+ -1.37329101562499692341771212945644892E-03L, /* bff567ffffffffff1cfd00f1b0577000 */
+ -3.59631150411372589637918252836880320E-34L, /* bf8fde08239ac74942a46298ea4fb715 */
+ -1.34277343749999137467356674296739172E-03L, /* bff55ffffffffffd839030b05d53d000 */
+ -1.49571076125940368185068762485268117E-35L, /* bf8b3e1a3d5c684b27a9f835b1d8d3c9 */
+ -1.31225585937499247038404301859788734E-03L, /* bff557fffffffffdd469936e691e3000 */
+ 3.10375845385355395586146533282311300E-34L, /* 3f8f9c8f6d63b7a4145716ffd92491fb */
+ -1.28173828124999024755581675764821898E-03L, /* bff54ffffffffffd306589b0ab21d000 */
+ -1.98541096105909793397376077900810019E-34L, /* bf8f07e808bbb1e35106c294ffbb9687 */
+ -1.25122070312500340204619591143332523E-03L, /* bff5480000000000fb06d5f16ad2c000 */
+ 3.62884195935761446237911443317457521E-34L, /* 3f8fe25b17d623178a386a6fa6c5afb2 */
+ -1.22070312499999591578388993012071279E-03L, /* bff53ffffffffffed2a356c440074000 */
+ -2.96756662615653130862526710937493307E-35L, /* bf8c3b90d8ff2a991e5bd16718fb0645 */
+ -1.19018554687498821966212632349422735E-03L, /* bff537fffffffffc9ac3b585dda89000 */
+ 1.44659971891167323357060028901142644E-34L, /* 3f8e809279ab249edf1dad9fe13fb0bf */
+ -1.15966796875000160938908064907298384E-03L, /* bff530000000000076c0800db9639000 */
+ 2.50088010538742402346270685365928513E-34L, /* 3f8f4c6c8a483b60201d30c1a83c3cb7 */
+ -1.12915039062500267151512523291939657E-03L, /* bff5280000000000c51f7e7315137000 */
+ 7.56402096465615210500092443924888831E-35L, /* 3f8d922c1e485d99aea2668ed32b55a6 */
+ -1.09863281249998665006360103291051571E-03L, /* bff51ffffffffffc26f2d4c9ce2ba000 */
+ 1.43982174467233642713619821353592061E-34L, /* 3f8e7ec530b3d92b6303bec1c81214d1 */
+ -1.06811523437500522742248711752028025E-03L, /* bff518000000000181b7380f10446000 */
+ 5.41265133745862349181293024531133174E-35L, /* 3f8d1fc9313d018b30e790e06b6be723 */
+ -1.03759765624999980942114138999770552E-03L, /* bff50ffffffffffff1f01130490e1000 */
+ 1.21525139612685854366189534669623436E-34L, /* 3f8e4311b96b6fcde412caf3f0d86fb9 */
+ -1.00708007812499602697537601515759439E-03L, /* bff507fffffffffedad7afcce7051000 */
+ 1.00020246351201558505328236381833392E-34L, /* 3f8e09e640992512b1300744a7e984ed */
+ -9.76562499999992592487302113340463694E-04L, /* bff4fffffffffffbbad8151f8adf6000 */
+ -1.64984406575162932060422892046851002E-34L, /* bf8eb69a919986e8054b86fc34300f24 */
+ -9.46044921874989085824996924138179594E-04L, /* bff4effffffffff9b55a204fd9792000 */
+ -9.29539174108308550334255350011347171E-35L, /* bf8dee3a50ed896b4656fa577a1df3d7 */
+ -9.15527343750013735214860599791540029E-04L, /* bff4e00000000007eaf5bf103f82d000 */
+ 3.07557018309280519949818825519490586E-35L, /* 3f8c470cfbef77d32c74cb8042f6ee81 */
+ -8.85009765625012292294986105781516428E-04L, /* bff4d000000000071605c65403b97000 */
+ 4.77499983783821950338363358545463558E-35L, /* 3f8cfbc3dc18884c4c4f9e07d90d7bd3 */
+ -8.54492187499986941239470706817188192E-04L, /* bff4bffffffffff878ddf9cab264a000 */
+ -1.60128240346239526958630011447901568E-34L, /* bf8ea9b1a21e19e2d5bd84b0fbffcf95 */
+ -8.23974609374996290174598690241743810E-04L, /* bff4affffffffffddc86c249ebe06000 */
+ 1.61677540391961912631535763471935882E-34L, /* 3f8eadd00841366b0dc2bc262c2c8c36 */
+ -7.93457031249988696952538334288757473E-04L, /* bff49ffffffffff97bf6f0aa85a5f000 */
+ 1.22318577008381887076634753347515709E-34L, /* 3f8e452db5b5d250878f71040da06d14 */
+ -7.62939453124996723316499040007097041E-04L, /* bff48ffffffffffe1c7265b431108000 */
+ -1.03845161748762410745671891558398468E-34L, /* bf8e14115ad884c96d1a820c73647220 */
+ -7.32421874999998242520117923997325794E-04L, /* bff47ffffffffffefca4498b7aa8a000 */
+ 5.64005211953031009549514026639438083E-35L, /* 3f8d2be06950f68f1a6d8ff829a6928e */
+ -7.01904296874999772890934814265622012E-04L, /* bff46fffffffffffde7c0fe5d8041000 */
+ 5.90245467325173644235991233229525762E-35L, /* 3f8d39d40cc49002189243c194b1db0e */
+ -6.71386718750008699269643939210658742E-04L, /* bff460000000000503c91d798b60c000 */
+ -5.20515801723324452151498579012322191E-35L, /* bf8d14c0f08a6a9285b32b8bda003eb5 */
+ -6.40869140625005499535275057463709988E-04L, /* bff45000000000032b969184e9751000 */
+ -6.69469163285461870099846471658294534E-35L, /* bf8d63f36bab7b24d936c9380e3d3fa6 */
+ -6.10351562499999293780097329596079841E-04L, /* bff43fffffffffff97c7c433e35ed000 */
+ -1.16941808547394177991845382085515086E-34L, /* bf8e36e27886f10b234a7dd8fc588bf0 */
+ -5.79833984375000068291972326409994795E-04L, /* bff43000000000000a13ff6dcf2bf000 */
+ 1.17885044988246219185041488459766001E-34L, /* 3f8e3964677e001a00412aab52790842 */
+ -5.49316406249990904622170867910987793E-04L, /* bff41ffffffffffac1c25739c716b000 */
+ -3.31875702128137033065075734368960972E-35L, /* bf8c60e928d8982c3c99aef4f885a121 */
+ -5.18798828125011293653756992177727236E-04L, /* bff410000000000682a62cff36775000 */
+ -5.69971237642088463334239430962628187E-35L, /* bf8d2f0c76f8757d61cd1abc7ea7d066 */
+ -4.88281249999990512232251384917893121E-04L, /* bff3fffffffffff50fb48992320df000 */
+ 1.02144616714408655325510171265051108E-35L, /* 3f8ab279a3626612710b9b3ac71734ac */
+ -4.57763671874997554564967307956493434E-04L, /* bff3dffffffffffd2e3c272e3cca9000 */
+ -8.25484058867957231164162481843653503E-35L, /* bf8db6e71158e7bf93e2e683f07aa841 */
+ -4.27246093749991203999790346349633286E-04L, /* bff3bffffffffff5dbe103cba0eb2000 */
+ -3.51191203319375193921924105905691755E-35L, /* bf8c757356d0f3dd7fbefc0dd419ab50 */
+ -3.96728515624986649402960638705483281E-04L, /* bff39ffffffffff09b996882706ec000 */
+ -5.51925962073095883016589497244931171E-36L, /* bf89d586d49f22289cfc860bebb99056 */
+ -3.66210937499999945095511981300980754E-04L, /* bff37fffffffffffefcb88bfc7df6000 */
+ -2.11696465278144529364423332249588595E-35L, /* bf8bc23a84d28e5496c874ef9833be25 */
+ -3.35693359374992480958458008559640163E-04L, /* bff35ffffffffff754c548a8798f2000 */
+ -8.58941791799705081104736787493668352E-35L, /* bf8dc8b1192fb7c3662826d43acb7c68 */
+ -3.05175781250009811036303273640122156E-04L, /* bff340000000000b4fb4f1aad1c76000 */
+ -8.61173897858769926480551302277426632E-35L, /* bf8dc9e0eabb1c0b33051011b64769fa */
+ -2.74658203124987298321920308390303850E-04L, /* bff31ffffffffff15b2056ac252fd000 */
+ 3.35152809454778381053519808988046631E-37L, /* 3f85c82fb59ff8d7c80d44e635420ab1 */
+ -2.44140624999999992770514819575735516E-04L, /* bff2fffffffffffffbbb82d6a7636000 */
+ 3.54445837111124472730013879165516908E-35L, /* 3f8c78e955b01378be647b1c92aa9a77 */
+ -2.13623046875012756463165168672749438E-04L, /* bff2c0000000001d6a1635fea6bbf000 */
+ 1.50050816288650121729916777279129473E-35L, /* 3f8b3f1f6f616a61129a58e131cbd31d */
+ -1.83105468749991323078784464300306893E-04L, /* bff27fffffffffebfe0cbd0c82399000 */
+ -9.14919506501448661140572099029756008E-37L, /* bf873754bacaa9d9513b6127e791eb47 */
+ -1.52587890625013337032336300236461546E-04L, /* bff240000000001ec0cb57f2cc995000 */
+ 2.84906084373176180870418394956384516E-35L, /* 3f8c2ef6d03a7e6ab087c4f099e4de89 */
+ -1.22070312499990746786116828458007518E-04L, /* bff1ffffffffffd553bbb49f35a34000 */
+ 6.71618008964968339584520728412444537E-36L, /* 3f8a1dacb99c60071fc9cd2349495bf0 */
+ -9.15527343750029275602791047595142231E-05L, /* bff180000000000d8040cd6ecde28000 */
+ -1.95753652091078750312541716951402172E-35L, /* bf8ba0526cfb24d8d59122f1c7a09a14 */
+ -6.10351562499913258461494008080572701E-05L, /* bff0ffffffffffaffebbb92d7f6a9000 */
+ 5.69868489273961111703398456218119973E-36L, /* 3f89e4ca5df09ef4a4386dd5b3bf0331 */
+ -3.05175781250092882818419203884960853E-05L, /* bff0000000000055ab55de88fac1d000 */
+ 9.03341100018476837609128961872915953E-36L, /* 3f8a803d229fa3a0e834a63abb06662b */
+#define T_EXPL_ARG2 (2*T_EXPL_ARG1 + 2 + 2*65)
+ 0.00000000000000000000000000000000000E+00L, /* 00000000000000000000000000000000 */
+ 0.00000000000000000000000000000000000E+00L, /* 00000000000000000000000000000000 */
+ 3.05175781249814607084128277672749162E-05L, /* 3feffffffffffeaa02abb9102f499000 */
+ 1.00271855391179733380665816525889949E-36L, /* 3f8755351afa042ac3f58114824d4c10 */
+ 6.10351562500179243748093427073421439E-05L, /* 3ff1000000000052a95de07a4c26d000 */
+ 1.67231624299180373502350811501181670E-36L, /* 3f881c87a53691cae9d77f4e40d66616 */
+ 9.15527343749970728685313252158399200E-05L, /* 3ff17ffffffffff28040cc2acde28000 */
+ 2.43665747834893104318707597514407880E-36L, /* 3f889e9366c7c6c6a2ecb78dc9b0509e */
+ 1.22070312500027751961838150070880064E-04L, /* 3ff200000000003ffddde6c153b53000 */
+ -1.73322146370624186623546452226755405E-35L, /* bf8b709d8d658ed5dbbe943de56ee84e */
+ 1.52587890624995916105682628143179430E-04L, /* 3ff23ffffffffff6954b56e285d23000 */
+ 1.23580432650945898349135528000443828E-35L, /* 3f8b06d396601dde16de7d7bc27346e6 */
+ 1.83105468750008670314358488289621794E-04L, /* 3ff2800000000013fe0cdc8c823b7000 */
+ 4.30446229148833293310207915930740796E-35L, /* 3f8cc9ba9bfe554a4f7f2fece291eb23 */
+ 2.13623046875005741337455947623248132E-04L, /* 3ff2c0000000000d3d1662de21a3f000 */
+ -3.96110759869520786681660669615255057E-35L, /* bf8ca5379b04ff4a31aab0ceacc917e6 */
+ 2.44140624999981493573336463433440506E-04L, /* 3ff2ffffffffffd553bbdf48e0534000 */
+ -1.39617373942387888957350179316792928E-35L, /* bf8b28eeedc286015802b63f96b8c5cd */
+ 2.74658203124984920706309918754626834E-04L, /* 3ff31fffffffffee9d60c8439ec1d000 */
+ -3.16168080483901830349738314447356223E-36L, /* bf890cf74f81c77a611abc1243812444 */
+ 3.05175781250008648918265055410966055E-04L, /* 3ff3400000000009f8b5c9a346636000 */
+ 8.54421306185008998867856704677221443E-35L, /* 3f8dc649cd40922fc08adc6b6b20ead0 */
+ 3.35693359374988945462612499316774515E-04L, /* 3ff35ffffffffff34146c540f15b2000 */
+ 7.96443137431639500475160850431097078E-35L, /* 3f8da77638ed3148fc4d99d1c9e13446 */
+ 3.66210937500027690542093987739604535E-04L, /* 3ff380000000001fecce34bea89c4000 */
+ 2.14507323877752361258862577769090367E-35L, /* 3f8bc834e554d38894cf91957b0253d3 */
+ 3.96728515625003928083564943615052121E-04L, /* 3ff3a00000000004875d9a4acf6ab000 */
+ 4.88358523466632050664019922448605508E-35L, /* 3f8d03a7eaeef1a9f78c71a12c44dd28 */
+ 4.27246093750017799227172345607351585E-04L, /* 3ff3c00000000014856794c3ee850000 */
+ 6.66520494592631402182216588784828935E-35L, /* 3f8d6262118fcdb59b8f16108f5f1a6c */
+ 4.57763671875002108342364320152138181E-04L, /* 3ff3e000000000026e45d855410b9000 */
+ 7.21799615960261390920033272189522298E-35L, /* 3f8d7fc645cff8879462296af975c9fd */
+ 4.88281249999999768797631616370963356E-04L, /* 3ff3ffffffffffffbbc2d7cc004df000 */
+ -5.30564629906905979452258114088325361E-35L, /* bf8d1a18b71929a30d67a217a27ae851 */
+ 5.18798828124997339054881383202487041E-04L, /* 3ff40ffffffffffe775055eea5851000 */
+ -4.03682911253647925867848180522846377E-35L, /* bf8cad44f0f3e5199d8a589d9332acad */
+ 5.49316406249980511907933706754958501E-04L, /* 3ff41ffffffffff4c410b29bb62fb000 */
+ -2.08166843948323917121806956728438051E-35L, /* bf8bbab8cf691403249fe5b699e25143 */
+ 5.79833984374989593561576568548497165E-04L, /* 3ff42ffffffffffa0047df328d817000 */
+ -1.72745033420153042445343706432627539E-34L, /* bf8ecb3c2d7d3a9e6e960576be901fdf */
+ 6.10351562500008540711511259540838154E-04L, /* 3ff4400000000004ec62f54f8c271000 */
+ 7.41889382604319545724663095428976499E-35L, /* 3f8d8a74c002c81a47c93b8e05d15f8e */
+ 6.40869140625020444702875407535884986E-04L, /* 3ff450000000000bc91b09718515d000 */
+ -4.47321009727305792048065440180490107E-35L, /* bf8cdbac5c8fe70822081d8993eb5cb6 */
+ 6.71386718750007531635964622352684074E-04L, /* 3ff460000000000457792973db05c000 */
+ 5.13698959677949336513874456684462092E-35L, /* 3f8d112114436949c5ef38d8049004ab */
+ 7.01904296875006634673332887754430334E-04L, /* 3ff4700000000003d31adf2cb8b1d000 */
+ -8.25665755717729437292989870760751482E-35L, /* bf8db6ffcc8ef71f8e648e3a8b160f5a */
+ 7.32421874999998244664170215504673504E-04L, /* 3ff47ffffffffffefcf5498bd5c8a000 */
+ -5.64005234937832153139057628112753364E-35L, /* bf8d2be06a1dfe90e7bf90fba7c12a98 */
+ 7.62939453125017456345986752604096408E-04L, /* 3ff490000000000a101a1b093d4a8000 */
+ -1.11084094120417622468550608896588329E-34L, /* bf8e274feabd2d94f6694507a46accb1 */
+ 7.93457031249987558617598988993908016E-04L, /* 3ff49ffffffffff8d3f9dcab74bbf000 */
+ -1.22966480225449015129079129940978828E-34L, /* bf8e46e6a65eef8fa9e42eddf3da305e */
+ 8.23974609374997378723747633335135819E-04L, /* 3ff4affffffffffe7d2afbaa55b26000 */
+ -1.62270010016794279091906973366704963E-34L, /* bf8eaf633f057ebdb664a34566401c4e */
+ 8.54492187500023938282350821569920958E-04L, /* 3ff4c0000000000dccaabce399e59000 */
+ -1.39076361712838158775374263169606160E-34L, /* bf8e71ba779364b3bbdba7841f2c4ca1 */
+ 8.85009765624987932362186815286691297E-04L, /* 3ff4cffffffffff90b218886edc2a000 */
+ 4.07328275060905585228261577392403980E-35L, /* 3f8cb1254dbb6ea4b8cfa5ed4cf28d24 */
+ 9.15527343749975579461305518559161974E-04L, /* 3ff4dffffffffff1ec2a21f25df33000 */
+ 1.16855112459192484947855553716334015E-35L, /* 3f8af10bf319e9f5270cf249eeffbe5c */
+ 9.46044921875016761584725882821122521E-04L, /* 3ff4f00000000009a992c46c16d71000 */
+ 9.51660680007524262741115611071680436E-35L, /* 3f8df9fd56e81f8edf133843910ee831 */
+ 9.76562499999974118878133088548272636E-04L, /* 3ff4fffffffffff1149edc46a6df6000 */
+ -5.65271128977550656964071208289181661E-36L, /* bf89e0e12689dd721aa2314c81eb6429 */
+ 1.00708007812498671732140389760347830E-03L, /* 3ff507fffffffffc2be94b90ed091000 */
+ -1.43355074891483635310132767255371379E-34L, /* bf8e7d1a688c247b16022daab1316d55 */
+ 1.03759765625002637786192745235343007E-03L, /* 3ff51000000000079a57b966bc158000 */
+ 2.95905815240957629366749917020106928E-34L, /* 3f8f895387fc73bb38f8a1b254c01a60 */
+ 1.06811523437500860568717813047520763E-03L, /* 3ff51800000000027afcd5b35f5e6000 */
+ -5.98328495358586628195372356742878314E-35L, /* bf8d3e204130013bf6328f1b70ff8c76 */
+ 1.09863281250001439958487251556220070E-03L, /* 3ff5200000000004268077c6c66bd000 */
+ 2.41371837889426603334113000868144760E-34L, /* 3f8f40d6948edf864054ccf151f9815e */
+ 1.12915039062501298413451613770002366E-03L, /* 3ff5280000000003be0f5dd8fe81b000 */
+ -1.28815268997394164973472617519705703E-34L, /* bf8e567321172ea089dce4bc8354ecb7 */
+ 1.15966796874997272036339054191407232E-03L, /* 3ff52ffffffffff8231e3bcfff1e8000 */
+ 1.02996064554316248496839462594377804E-34L, /* 3f8e11cf7d402789244f68e2d4f985b1 */
+ 1.19018554687502744121802585360546796E-03L, /* 3ff5380000000007e8cdf3f8f6c20000 */
+ -1.43453217726255628994625761307322163E-34L, /* bf8e7d5d3370d85a374f5f4802fc517a */
+ 1.22070312499997743541996266398850614E-03L, /* 3ff53ffffffffff97f0722561f454000 */
+ -1.41086259180534339713692694428211646E-34L, /* bf8e77125519ff76244dfec5fbd58402 */
+ 1.25122070312501024092560690174507039E-03L, /* 3ff5480000000002f3a59d8820691000 */
+ 3.84102646020099293168698506729765213E-34L, /* 3f8ffe8f5b86f9c3569c8f26e19b1f50 */
+ 1.28173828124997986521442660131425390E-03L, /* 3ff54ffffffffffa3250a764439d9000 */
+ 1.44644589735033114377952806106652650E-34L, /* 3f8e808801b80dcf38323cdbfdca2549 */
+ 1.31225585937501665804856968749058137E-03L, /* 3ff5580000000004cd25a414c6d62000 */
+ 1.67474574742200577294563576414361377E-34L, /* 3f8ebd394a151dbda4f81d5d83c0f1e9 */
+ 1.34277343749997290265837386401818888E-03L, /* 3ff55ffffffffff83091b042cfd59000 */
+ -1.55650565030381326742591837551559103E-34L, /* bf8e9dca490d7fecfadba9625ffb91c5 */
+ 1.37329101562497720784949380297774268E-03L, /* 3ff567fffffffff96e3c7312f5ccf000 */
+ 1.65279335325630026116581677369221748E-34L, /* 3f8eb763496f5bd7404f2298b402074f */
+ 1.40380859374999099958354100336136647E-03L, /* 3ff56ffffffffffd67e2f09f2a381000 */
+ 1.89919944388961890195706641264717076E-34L, /* 3f8ef8e4d0ffdfeba982aa8829501389 */
+ 1.43432617187497484122173130998160625E-03L, /* 3ff577fffffffff8bf9c1d71af8a8000 */
+ 2.57638517142061429772064578590009568E-34L, /* 3f8f5675d82c1cc4ada70fd3a957b89a */
+ 1.46484374999999929342158925502052945E-03L, /* 3ff57fffffffffffcbdd1c7671b46000 */
+ 1.76487201934184070490166772482073801E-34L, /* 3f8ed52ef732458f6e4c5c07504f33cc */
+ 1.49536132812502318451070466256902933E-03L, /* 3ff5880000000006aeb7066c8ad43000 */
+ 2.38068367275295804321313550609246656E-34L, /* 3f8f3c7277ae6fc390ace5e06c0b025b */
+ 1.52587890625000448053340248672949543E-03L, /* 3ff59000000000014a9ae2104b3bc000 */
+ 1.01174455568392813258454590274740959E-34L, /* 3f8e0cf7c434762991bb38e12acee215 */
+ 1.55639648437501113499837053523090913E-03L, /* 3ff5980000000003359e2c204355e000 */
+ -2.82398418808099749023517211651363693E-35L, /* bf8c2c4c2971d88caa95e15fb1ccb1a1 */
+ 1.58691406249999937955142588308171026E-03L, /* 3ff59fffffffffffd2380ecbc87c2000 */
+ -1.27361695572422741562701199136538047E-34L, /* bf8e5295e0e206dfb0f0266c07225448 */
+ 1.61743164062498000531048954475329309E-03L, /* 3ff5a7fffffffffa3ca6fe61ed94c000 */
+ -1.22606548862580061633942923016222044E-34L, /* bf8e45f1b17bb61039d21a351bb207b8 */
+ 1.64794921875001835451453858682255576E-03L, /* 3ff5b000000000054a52fa20f6565000 */
+ 1.39132339594152335892305491425264583E-34L, /* 3f8e71e0904c5449b414ee49b191cef2 */
+ 1.67846679687501263995029340691547953E-03L, /* 3ff5b80000000003a4a9e912c910b000 */
+ 6.67245854693585315412242764786197029E-35L, /* 3f8d62c4ccac1e7511a617d469468ccd */
+ 1.70898437500002646861403514115369655E-03L, /* 3ff5c00000000007a109fbaa7e015000 */
+ 6.87367172354719289559624829652240928E-36L, /* 3f8a245fa835eceb42bae8128d9336db */
+ 1.73950195312501174308226096992992128E-03L, /* 3ff5c80000000003627c8d637a005000 */
+ -2.20824271875474985927385878948759352E-34L, /* bf8f25869b1cbefb25e735992f232f57 */
+ 1.77001953124997491747605207736194513E-03L, /* 3ff5cffffffffff8c53c84b6883b8000 */
+ 3.43123048533596296514343180408963705E-34L, /* 3f8fc816b91d173ddadbbf09b1287906 */
+ 1.80053710937497698911127570705069398E-03L, /* 3ff5d7fffffffff95e1899f4a8430000 */
+ 3.99231237340890073475077494556136100E-35L, /* 3f8ca889148f62fa854da5674df41279 */
+ 1.83105468750002267094899598630423914E-03L, /* 3ff5e0000000000688d21e62ba674000 */
+ -3.22274595655810623999007524769365273E-34L, /* bf8fac605cb9ae01eb719675ced25560 */
+ 1.86157226562500499224728040579690330E-03L, /* 3ff5e80000000001705ce28a6d89e000 */
+ 3.07094985075881613489605622068441083E-34L, /* 3f8f98330225ec7e2c8f3c0d1c432b91 */
+ 1.89208984374998234666824993196980949E-03L, /* 3ff5effffffffffae969fdc7cd8cf000 */
+ -3.06287628722973914692165056776495733E-34L, /* bf8f9720477d9cfa10e464df7f91020c */
+ 1.92260742187501225343755557292811682E-03L, /* 3ff5f800000000038824e428ed49a000 */
+ 6.30049124729794620592961282769623368E-35L, /* 3f8d4efdd7cd4336d88a6aa49e1e96bc */
+ 1.95312499999998514894032051116231258E-03L, /* 3ff5fffffffffffbb82f6a04f1ae0000 */
+ -6.14610057507500948543216998736262902E-35L, /* bf8d46c862d39255370e7974d48daa7e */
+ 1.98364257812501222021119324146882732E-03L, /* 3ff6040000000001c2d8a1aa5188d000 */
+ 3.71942298418113774118754986159801984E-34L, /* 3f8fee6567d9940495519ffe62cbc9a4 */
+
+ 7.06341639425619532977052017486130353E-01L, /* 3ffe69a59c8245a9ac00000000000000 */
+ 7.09106182437398424589503065362805501E-01L, /* 3ffe6b0ff72deb89d000000000000000 */
+ 7.11881545564596485142772053222870454E-01L, /* 3ffe6c7bbce9a6d93000000000000000 */
+ 7.14667771155948150507697391731198877E-01L, /* 3ffe6de8ef213d71e000000000000000 */
+ 7.17464901725936049503573599395167548E-01L, /* 3ffe6f578f41e1a9e400000000000000 */
+ 7.20272979955439790478166628417966422E-01L, /* 3ffe70c79eba33c06c00000000000000 */
+ 7.23092048692387218133958981525211129E-01L, /* 3ffe72391efa434c7400000000000000 */
+ 7.25922150952408251622927082280511968E-01L, /* 3ffe73ac117390acd800000000000000 */
+ 7.28763329919491220643124052003258839E-01L, /* 3ffe752077990e79d000000000000000 */
+ 7.31615628946641782803794740175362676E-01L, /* 3ffe769652df22f7e000000000000000 */
+ 7.34479091556544505525749855223693885E-01L, /* 3ffe780da4bba98c4800000000000000 */
+ 7.37353761442226890432394270646909717E-01L, /* 3ffe79866ea5f432d400000000000000 */
+ 7.40239682467726090031590047146892175E-01L, /* 3ffe7b00b216ccf53000000000000000 */
+ 7.43136898668758316688354170764796436E-01L, /* 3ffe7c7c70887763c000000000000000 */
+ 7.46045454253390638577059235103661194E-01L, /* 3ffe7df9ab76b20fd000000000000000 */
+ 7.48965393602715662213498148958024103E-01L, /* 3ffe7f78645eb8076400000000000000 */
+ 7.51896761271528629722027403659012634E-01L, /* 3ffe80f89cbf42526400000000000000 */
+ 7.54839601989007347171423134568613023E-01L, /* 3ffe827a561889716000000000000000 */
+ 7.57793960659394638668118204805068672E-01L, /* 3ffe83fd91ec46ddc000000000000000 */
+ 7.60759882362683631518152083117456641E-01L, /* 3ffe858251bdb68b8c00000000000000 */
+ 7.63737412355305483879774897104653064E-01L, /* 3ffe87089711986c9400000000000000 */
+ 7.66726596070820082262642358728044201E-01L, /* 3ffe8890636e31f54400000000000000 */
+ 7.69727479120609181517664865168626420E-01L, /* 3ffe8a19b85b4fa2d800000000000000 */
+ 7.72740107294572486917871856348938309E-01L, /* 3ffe8ba4976246833800000000000000 */
+ 7.75764526561826289752232810315035749E-01L, /* 3ffe8d31020df5be4400000000000000 */
+ 7.78800783071404878477039801509818062E-01L, /* 3ffe8ebef9eac820b000000000000000 */
+ 7.81848923152964780936002853195532225E-01L, /* 3ffe904e8086b5a87800000000000000 */
+ 7.84908993317491698871180005880887620E-01L, /* 3ffe91df97714512d800000000000000 */
+ 7.87981040258010162480317717381694820E-01L, /* 3ffe9372403b8d6bcc00000000000000 */
+ 7.91065110850296016042904057030682452E-01L, /* 3ffe95067c78379f2800000000000000 */
+ 7.94161252153591734614934694036492147E-01L, /* 3ffe969c4dbb800b4800000000000000 */
+ 7.97269511411324433014513601847284008E-01L, /* 3ffe9833b59b38154400000000000000 */
+ 8.00389936051826789142893403550260700E-01L, /* 3ffe99ccb5aec7bec800000000000000 */
+ 8.03522573689060742863077280162542593E-01L, /* 3ffe9b674f8f2f3d7c00000000000000 */
+ 8.06667472123343942680406826184480451E-01L, /* 3ffe9d0384d70893f800000000000000 */
+ 8.09824679342079301047618855591281317E-01L, /* 3ffe9ea15722892c7800000000000000 */
+ 8.12994243520486992160556383169023320E-01L, /* 3ffea040c80f8374f000000000000000 */
+ 8.16176213022339780422953481320291758E-01L, /* 3ffea1e1d93d687d0000000000000000 */
+ 8.19370636400700819157449927843117621E-01L, /* 3ffea3848c4d49954c00000000000000 */
+ 8.22577562398664585696650419777142815E-01L, /* 3ffea528e2e1d9f09800000000000000 */
+ 8.25797039950100647542896581398963463E-01L, /* 3ffea6cede9f70467c00000000000000 */
+ 8.29029118180400342863478613253391813E-01L, /* 3ffea876812c0877bc00000000000000 */
+ 8.32273846407226292054559735333896242E-01L, /* 3ffeaa1fcc2f45343800000000000000 */
+ 8.35531274141265073440720811959181447E-01L, /* 3ffeabcac15271a2a400000000000000 */
+ 8.38801451086982535754188461396552157E-01L, /* 3ffead7762408309bc00000000000000 */
+ 8.42084427143382358016410194068157580E-01L, /* 3ffeaf25b0a61a7b4c00000000000000 */
+ 8.45380252404767357221615498019673396E-01L, /* 3ffeb0d5ae318680c400000000000000 */
+ 8.48688977161503960155997106085123960E-01L, /* 3ffeb2875c92c4c99400000000000000 */
+ 8.52010651900789478530029441571969073E-01L, /* 3ffeb43abd7b83db1c00000000000000 */
+ 8.55345327307422548246407245642330963E-01L, /* 3ffeb5efd29f24c26400000000000000 */
+ 8.58693054264576483003423845730139874E-01L, /* 3ffeb7a69db2bcc77800000000000000 */
+ 8.62053883854575708767242758767679334E-01L, /* 3ffeb95f206d17228000000000000000 */
+ 8.65427867359675251357487013592617586E-01L, /* 3ffebb195c86b6b29000000000000000 */
+ 8.68815056262843166123843730019871145E-01L, /* 3ffebcd553b9d7b62000000000000000 */
+ 8.72215502248546159513864495238522068E-01L, /* 3ffebe9307c271855000000000000000 */
+ 8.75629257203538208242932228131394368E-01L, /* 3ffec0527a5e384ddc00000000000000 */
+ 8.79056373217652342599848225290770642E-01L, /* 3ffec213ad4c9ed0d800000000000000 */
+ 8.82496902584595399599010079327854328E-01L, /* 3ffec3d6a24ed8221800000000000000 */
+ 8.85950897802745995779361010136199184E-01L, /* 3ffec59b5b27d9696800000000000000 */
+ 8.89418411575955636383383762222365476E-01L, /* 3ffec761d99c5ba58800000000000000 */
+ 8.92899496814352794382685374330321793E-01L, /* 3ffec92a1f72dd70d400000000000000 */
+ 8.96394206635150403439382671422208659E-01L, /* 3ffecaf42e73a4c7d800000000000000 */
+ 8.99902594363456265202927397695020773E-01L, /* 3ffeccc00868c0d18800000000000000 */
+ 9.03424713533086704009278378180169966E-01L, /* 3ffece8daf1e0ba94c00000000000000 */
+ 9.06960617887383580004723171441582963E-01L, /* 3ffed05d24612c2af000000000000000 */
+ 9.10510361380034133338412516422977205E-01L, /* 3ffed22e6a0197c02c00000000000000 */
+ 9.14073998175894436579724811053893063E-01L, /* 3ffed40181d094303400000000000000 */
+ 9.17651582651815816982221463149471674E-01L, /* 3ffed5d66da13970f400000000000000 */
+ 9.21243169397474526149949269893113524E-01L, /* 3ffed7ad2f48737a2000000000000000 */
+ 9.24848813216204823639543519675498828E-01L, /* 3ffed985c89d041a3000000000000000 */
+ 9.28468569125835141431224428743007593E-01L, /* 3ffedb603b7784cd1800000000000000 */
+ 9.32102492359527579068867453315760940E-01L, /* 3ffedd3c89b26894e000000000000000 */
+ 9.35750638366620729469147477175283711E-01L, /* 3ffedf1ab529fdd41c00000000000000 */
+ 9.39413062813475779888605643463961314E-01L, /* 3ffee0fabfbc702a3c00000000000000 */
+ 9.43089821584325888048638830696290825E-01L, /* 3ffee2dcab49ca51b400000000000000 */
+ 9.46780970782128888929563004239753354E-01L, /* 3ffee4c079b3f8000400000000000000 */
+ 9.50486566729423443256052905780961737E-01L, /* 3ffee6a62cdec7c7b000000000000000 */
+ 9.54206665969188322362626308859034907E-01L, /* 3ffee88dc6afecfbfc00000000000000 */
+ 9.57941325265705301283958306157728657E-01L, /* 3ffeea77490f0196b000000000000000 */
+ 9.61690601605425299247542625380447134E-01L, /* 3ffeec62b5e5881fb000000000000000 */
+ 9.65454552197837823079851204965962097E-01L, /* 3ffeee500f1eed967000000000000000 */
+ 9.69233234476344074348475032820715569E-01L, /* 3ffef03f56a88b5d7800000000000000 */
+ 9.73026706099133165128733935489435680E-01L, /* 3ffef2308e71a927a800000000000000 */
+ 9.76835024950062025261843245971249416E-01L, /* 3ffef423b86b7ee79000000000000000 */
+ 9.80658249139538557015427500118676107E-01L, /* 3ffef618d68936c09c00000000000000 */
+ 9.84496437005408397968864164795377292E-01L, /* 3ffef80feabfeefa4800000000000000 */
+ 9.88349647113845042323276857132441364E-01L, /* 3ffefa08f706bbf53800000000000000 */
+ 9.92217938260243514925207364285597578E-01L, /* 3ffefc03fd56aa225000000000000000 */
+ 9.96101369470117486981664001177705359E-01L, /* 3ffefe00ffaabffbbc00000000000000 */
+#define T_EXPL_RES1 (T_EXPL_ARG2 + 2 + 2*65 + 89)
+ 1.00000000000000000000000000000000000E+00L, /* 3fff0000000000000000000000000000 */
+ 1.00391388933834757590801700644078664E+00L, /* 3fff0100802ab5577800000000000000 */
+ 1.00784309720644799091004983893071767E+00L, /* 3fff0202015600445c00000000000000 */
+ 1.01178768355933151879000320150225889E+00L, /* 3fff0304848362076c00000000000000 */
+ 1.01574770858668572692806719715008512E+00L, /* 3fff04080ab55de39000000000000000 */
+ 1.01972323271377413034244341361045372E+00L, /* 3fff050c94ef7a206c00000000000000 */
+ 1.02371431660235789884438872832106426E+00L, /* 3fff06122436410dd000000000000000 */
+ 1.02772102115162167201845022646011785E+00L, /* 3fff0718b98f42085000000000000000 */
+ 1.03174340749910264936062276319717057E+00L, /* 3fff08205601127ec800000000000000 */
+ 1.03578153702162378824169763902318664E+00L, /* 3fff0928fa934ef90800000000000000 */
+ 1.03983547133622999947277776300325058E+00L, /* 3fff0a32a84e9c1f5800000000000000 */
+ 1.04390527230112850620713516036630608E+00L, /* 3fff0b3d603ca7c32800000000000000 */
+ 1.04799100201663270004459604933799710E+00L, /* 3fff0c49236829e8bc00000000000000 */
+ 1.05209272282610977189420964350574650E+00L, /* 3fff0d55f2dce5d1e800000000000000 */
+ 1.05621049731693195106174698594259098E+00L, /* 3fff0e63cfa7ab09d000000000000000 */
+ 1.06034438832143151909548350886325352E+00L, /* 3fff0f72bad65671b800000000000000 */
+ 1.06449445891785943185681162503897212E+00L, /* 3fff1082b577d34ed800000000000000 */
+ 1.06866077243134810492719566354935523E+00L, /* 3fff1193c09c1c595c00000000000000 */
+ 1.07284339243487741866189821848820429E+00L, /* 3fff12a5dd543ccc4c00000000000000 */
+ 1.07704238275024494209120007326419000E+00L, /* 3fff13b90cb25176a400000000000000 */
+ 1.08125780744903959851299646288680378E+00L, /* 3fff14cd4fc989cd6400000000000000 */
+ 1.08548973085361949442173568058933597E+00L, /* 3fff15e2a7ae28fecc00000000000000 */
+ 1.08973821753809324563988525369495619E+00L, /* 3fff16f9157587069400000000000000 */
+ 1.09400333232930546678574046381982043E+00L, /* 3fff18109a3611c35000000000000000 */
+ 1.09828514030782586896606289883493446E+00L, /* 3fff192937074e0cd800000000000000 */
+ 1.10258370680894224324930519287590869E+00L, /* 3fff1a42ed01d8cbc800000000000000 */
+ 1.10689909742365749645287564817408565E+00L, /* 3fff1b5dbd3f68122400000000000000 */
+ 1.11123137799969046168868658241990488E+00L, /* 3fff1c79a8dacc350c00000000000000 */
+ 1.11558061464248076122274255794764031E+00L, /* 3fff1d96b0eff0e79400000000000000 */
+ 1.11994687371619722204840741142106708E+00L, /* 3fff1eb4d69bde569c00000000000000 */
+ 1.12433022184475073235176978414529003E+00L, /* 3fff1fd41afcba45e800000000000000 */
+ 1.12873072591281087273529237791080959E+00L, /* 3fff20f47f31c92e4800000000000000 */
+ 1.13314845306682632219974493636982515E+00L, /* 3fff2216045b6f5cd000000000000000 */
+ 1.13758347071604959399593326452304609E+00L, /* 3fff2338ab9b32134800000000000000 */
+ 1.14203584653356560174586320499656722E+00L, /* 3fff245c7613b8a9b000000000000000 */
+ 1.14650564845732405583333957110880874E+00L, /* 3fff258164e8cdb0d800000000000000 */
+ 1.15099294469117646722011727433709893E+00L, /* 3fff26a7793f60164400000000000000 */
+ 1.15549780370591653744227755851170514E+00L, /* 3fff27ceb43d84490400000000000000 */
+ 1.16002029424032515603215642840950750E+00L, /* 3fff28f7170a755fd800000000000000 */
+ 1.16456048530221917269855680387991015E+00L, /* 3fff2a20a2ce96406400000000000000 */
+ 1.16911844616950438835445424956560601E+00L, /* 3fff2b4b58b372c79400000000000000 */
+ 1.17369424639123270948104504896036815E+00L, /* 3fff2c7739e3c0f32c00000000000000 */
+ 1.17828795578866324378353169777255971E+00L, /* 3fff2da4478b620c7400000000000000 */
+ 1.18289964445632783673900689791480545E+00L, /* 3fff2ed282d763d42400000000000000 */
+ 1.18752938276310060494722620205720887E+00L, /* 3fff3001ecf601af7000000000000000 */
+ 1.19217724135327157730657177125976887E+00L, /* 3fff31328716a5d63c00000000000000 */
+ 1.19684329114762477708211463323095813E+00L, /* 3fff32645269ea829000000000000000 */
+ 1.20152760334452030077656559114984702E+00L, /* 3fff339750219b212c00000000000000 */
+ 1.20623024942098072687102217059873510E+00L, /* 3fff34cb8170b5835400000000000000 */
+ 1.21095130113378179892436037334846333E+00L, /* 3fff3600e78b6b11d000000000000000 */
+ 1.21569083052054743854242246925423387E+00L, /* 3fff373783a722012400000000000000 */
+ 1.22044890990084875515009343871497549E+00L, /* 3fff386f56fa7686e800000000000000 */
+ 1.22522561187730755216662714701669756E+00L, /* 3fff39a862bd3c106400000000000000 */
+ 1.23002100933670455162882717559114099E+00L, /* 3fff3ae2a8287e7a8000000000000000 */
+ 1.23483517545109100499445276000187732E+00L, /* 3fff3c1e2876834aa800000000000000 */
+ 1.23966818367890557750499169742397498E+00L, /* 3fff3d5ae4e2cae92c00000000000000 */
+ 1.24452010776609517384017067342938390E+00L, /* 3fff3e98deaa11dcbc00000000000000 */
+ 1.24939102174724003813111039562500082E+00L, /* 3fff3fd8170a52071800000000000000 */
+ 1.25428099994668373895478907797951251E+00L, /* 3fff41188f42c3e32000000000000000 */
+ 1.25919011697966698459794088194030337E+00L, /* 3fff425a4893dfc3f800000000000000 */
+ 1.26411844775346637881341393949696794E+00L, /* 3fff439d443f5f159000000000000000 */
+ 1.26906606746853711786826579555054195E+00L, /* 3fff44e183883d9e4800000000000000 */
+ 1.27403305161966090564007458851847332E+00L, /* 3fff462707b2bac20c00000000000000 */
+ 1.27901947599709753244923149395617656E+00L, /* 3fff476dd2045ac67800000000000000 */
+ 1.28402541668774150540599521264084615E+00L, /* 3fff48b5e3c3e8186800000000000000 */
+ 1.28905095007628295311619126550795045E+00L, /* 3fff49ff3e397492bc00000000000000 */
+ 1.29409615284637330434591717676084954E+00L, /* 3fff4b49e2ae5ac67400000000000000 */
+ 1.29916110198179535206719492634874769E+00L, /* 3fff4c95d26d3f440800000000000000 */
+ 1.30424587476763775839572190307080746E+00L, /* 3fff4de30ec211e60000000000000000 */
+ 1.30935054879147461104338390214252286E+00L, /* 3fff4f3198fa0f1cf800000000000000 */
+ 1.31447520194454914310711046709911898E+00L, /* 3fff50817263c13cd000000000000000 */
+ 1.31961991242296217130558488861424848E+00L, /* 3fff51d29c4f01cb3000000000000000 */
+ 1.32478475872886558573071624778094701E+00L, /* 3fff5325180cfacf7800000000000000 */
+ 1.32996981967165983640200010995613411E+00L, /* 3fff5478e6f02823d000000000000000 */
+ 1.33517517436919680440254865061433520E+00L, /* 3fff55ce0a4c58c7bc00000000000000 */
+ 1.34040090224898678084031189428060316E+00L, /* 3fff57248376b033d800000000000000 */
+ 1.34564708304941055283521222918352578E+00L, /* 3fff587c53c5a7af0400000000000000 */
+ 1.35091379682093615244298234756570309E+00L, /* 3fff59d57c910fa4e000000000000000 */
+ 1.35620112392734021300455538039386738E+00L, /* 3fff5b2fff3210fd9400000000000000 */
+ 1.36150914504693443252136830778908916E+00L, /* 3fff5c8bdd032e770800000000000000 */
+ 1.36683794117379636690046140756749082E+00L, /* 3fff5de9176045ff5400000000000000 */
+ 1.37218759361900544124779344201670028E+00L, /* 3fff5f47afa69210a800000000000000 */
+ 1.37755818401188367960941150158760138E+00L, /* 3fff60a7a734ab0e8800000000000000 */
+ 1.38294979430124120867162673675920814E+00L, /* 3fff6208ff6a88a46000000000000000 */
+ 1.38836250675662681297595213436579797E+00L, /* 3fff636bb9a983258400000000000000 */
+ 1.39379640396958309755959248832368758E+00L, /* 3fff64cfd75454ee7c00000000000000 */
+ 1.39925156885490681313299887733592186E+00L, /* 3fff663559cf1bc7c400000000000000 */
+ 1.40472808465191417726103395580139477E+00L, /* 3fff679c427f5a49f400000000000000 */
+ 1.41022603492571069194738697660795879E+00L, /* 3fff690492cbf9432c00000000000000 */
+ 1.41574550356846662335641440222389065E+00L, /* 3fff6a6e4c1d491e1800000000000000 */
+
+ 9.98018323540573404351050612604012713E-01L, /* 3ffefefc41f8d4bdb000000000000000 */
+ 9.98048781107475468932221929208026268E-01L, /* 3ffeff003ff556aa8800000000000000 */
+ 9.98079239603882895082165305211674422E-01L, /* 3ffeff043df9d4986000000000000000 */
+ 9.98109699029824021243584297735651489E-01L, /* 3ffeff083c064e972c00000000000000 */
+ 9.98140159385327269125909310787392315E-01L, /* 3ffeff0c3a1ac4b6ec00000000000000 */
+ 9.98170620670420977171843901487591211E-01L, /* 3ffeff10383737079400000000000000 */
+ 9.98201082885133511579667242585856002E-01L, /* 3ffeff14365ba5991c00000000000000 */
+ 9.98231546029493238547658506831794512E-01L, /* 3ffeff183488107b7c00000000000000 */
+ 9.98262010103528552029672482603928074E-01L, /* 3ffeff1c32bc77beb000000000000000 */
+ 9.98292475107267818223988342651864514E-01L, /* 3ffeff2030f8db72b000000000000000 */
+ 9.98322941040739375573309644096298143E-01L, /* 3ffeff242f3d3ba77000000000000000 */
+ 9.98353407903971645787066790944663808E-01L, /* 3ffeff282d89986cf000000000000000 */
+ 9.98383875696992967307963340317655820E-01L, /* 3ffeff2c2bddf1d32400000000000000 */
+ 9.98414344419831761845429696222709026E-01L, /* 3ffeff302a3a47ea0c00000000000000 */
+ 9.98444814072516340086593800151604228E-01L, /* 3ffeff34289e9ac19800000000000000 */
+ 9.98475284655075123740886056111776270E-01L, /* 3ffeff38270aea69c800000000000000 */
+ 9.98505756167536479006585636852832977E-01L, /* 3ffeff3c257f36f29400000000000000 */
+ 9.98536228609928799837547330753295682E-01L, /* 3ffeff4023fb806bf800000000000000 */
+ 9.98566701982280452432050310562772211E-01L, /* 3ffeff44227fc6e5ec00000000000000 */
+ 9.98597176284619802988373749030870385E-01L, /* 3ffeff48210c0a706800000000000000 */
+ 9.98627651516975245460372434536111541E-01L, /* 3ffeff4c1fa04b1b6800000000000000 */
+ 9.98658127679375173801901155457017012E-01L, /* 3ffeff501e3c88f6e800000000000000 */
+ 9.98688604771847954211239084543194622E-01L, /* 3ffeff541ce0c412e000000000000000 */
+ 9.98719082794421980642241010173165705E-01L, /* 3ffeff581b8cfc7f4c00000000000000 */
+ 9.98749561747125619293186105096538085E-01L, /* 3ffeff5c1a41324c2400000000000000 */
+ 9.98780041629987291873504773320746608E-01L, /* 3ffeff6018fd65896800000000000000 */
+ 9.98810522443035364581476187595399097E-01L, /* 3ffeff6417c196471000000000000000 */
+ 9.98841004186298203615379520670103375E-01L, /* 3ffeff68168dc4951400000000000000 */
+ 9.98871486859804230684645176552294288E-01L, /* 3ffeff6c1561f0837400000000000000 */
+ 9.98901970463581839743127943620493170E-01L, /* 3ffeff70143e1a222c00000000000000 */
+ 9.98932454997659369233531378995394334E-01L, /* 3ffeff74132241813000000000000000 */
+ 9.98962940462065268620861502313346136E-01L, /* 3ffeff78120e66b08400000000000000 */
+ 9.98993426856827904103397486323956400E-01L, /* 3ffeff7c110289c02000000000000000 */
+ 9.99023914181975669634994119405746460E-01L, /* 3ffeff800ffeaac00000000000000000 */
+ 9.99054402437536959169506189937237650E-01L, /* 3ffeff840f02c9c02000000000000000 */
+ 9.99084891623540138905212870668037795E-01L, /* 3ffeff880e0ee6d07800000000000000 */
+ 9.99115381740013658307120181234495249E-01L, /* 3ffeff8c0d2302010c00000000000000 */
+ 9.99145872786985911329082910015131347E-01L, /* 3ffeff900c3f1b61d800000000000000 */
+ 9.99176364764485236413804614130640402E-01L, /* 3ffeff940b633302d000000000000000 */
+ 9.99206857672540083026291313217370771E-01L, /* 3ffeff980a8f48f3f800000000000000 */
+ 9.99237351511178817364822180024930276E-01L, /* 3ffeff9c09c35d454800000000000000 */
+ 9.99267846280429861138827618560753763E-01L, /* 3ffeffa008ff7006c000000000000000 */
+ 9.99298341980321608302162417203362565E-01L, /* 3ffeffa4084381485c00000000000000 */
+ 9.99328838610882452808681364331278019E-01L, /* 3ffeffa8078f911a1800000000000000 */
+ 9.99359336172140816367814863951934967E-01L, /* 3ffeffac06e39f8bf400000000000000 */
+ 9.99389834664125092933417704443854745E-01L, /* 3ffeffb0063facadec00000000000000 */
+ 9.99420334086863676459344674185558688E-01L, /* 3ffeffb405a3b88ffc00000000000000 */
+ 9.99450834440384988655026177184481639E-01L, /* 3ffeffb8050fc3422400000000000000 */
+ 9.99481335724717395718741386190231424E-01L, /* 3ffeffbc0483ccd45c00000000000000 */
+ 9.99511837939889374871071936468069907E-01L, /* 3ffeffc003ffd556ac00000000000000 */
+ 9.99542341085929264554721385138691403E-01L, /* 3ffeffc40383dcd90800000000000000 */
+ 9.99572845162865514234695751838444266E-01L, /* 3ffeffc8030fe36b7400000000000000 */
+ 9.99603350170726517864849824945849832E-01L, /* 3ffeffcc02a3e91dec00000000000000 */
+ 9.99633856109540669399038392839429434E-01L, /* 3ffeffd0023fee006c00000000000000 */
+ 9.99664362979336418302267475155531429E-01L, /* 3ffeffd401e3f222f800000000000000 */
+ 9.99694870780142130772816244643763639E-01L, /* 3ffeffd8018ff5958800000000000000 */
+ 9.99725379511986284031266336569387931E-01L, /* 3ffeffdc0143f8682400000000000000 */
+ 9.99755889174897216520321308053098619E-01L, /* 3ffeffe000fffaaac000000000000000 */
+ 9.99786399768903377704987178731244057E-01L, /* 3ffeffe400c3fc6d6000000000000000 */
+ 9.99816911294033217050269968240172602E-01L, /* 3ffeffe8008ffdc00800000000000000 */
+ 9.99847423750315072998873233700578567E-01L, /* 3ffeffec0063feb2ac00000000000000 */
+ 9.99877937137777450526954226006637327E-01L, /* 3ffefff0003fff555800000000000000 */
+ 9.99908451456448688077216502279043198E-01L, /* 3ffefff40023ffb80000000000000000 */
+ 9.99938966706357262870241697783058044E-01L, /* 3ffefff8000fffeaac00000000000000 */
+ 9.99969482887531541104308985268289689E-01L, /* 3ffefffc0003fffd5400000000000000 */
+#define T_EXPL_RES2 (T_EXPL_RES1 + 1 + 89 + 65)
+ 1.00000000000000000000000000000000000E+00L, /* 3fff0000000000000000000000000000 */
+ 1.00003051804379100575559391472779680E+00L, /* 3fff0002000200015400000000000000 */
+ 1.00006103701893306334724798034585547E+00L, /* 3fff00040008000aac00000000000000 */
+ 1.00009155692545448346209013834595680E+00L, /* 3fff0006001200240000000000000000 */
+ 1.00012207776338379883185325525118969E+00L, /* 3fff0008002000555800000000000000 */
+ 1.00015259953274932014366527255333494E+00L, /* 3fff000a003200a6ac00000000000000 */
+ 1.00018312223357958012925905677548144E+00L, /* 3fff000c004801200400000000000000 */
+ 1.00021364586590294498691378066723701E+00L, /* 3fff000e006201c95c00000000000000 */
+ 1.00024417042974783642605984823603649E+00L, /* 3fff0010008002aab400000000000000 */
+ 1.00027469592514273166727889474714175E+00L, /* 3fff001200a203cc1000000000000000 */
+ 1.00030522235211605242000132420798764E+00L, /* 3fff001400c805357000000000000000 */
+ 1.00033574971069616488250630936818197E+00L, /* 3fff001600f206eed000000000000000 */
+ 1.00036627800091160178652671675081365E+00L, /* 3fff0018012009003800000000000000 */
+ 1.00039680722279067381919048784766346E+00L, /* 3fff001a01520b71a000000000000000 */
+ 1.00042733737636191371223048918182030E+00L, /* 3fff001c01880e4b1000000000000000 */
+ 1.00045786846165368766392589350289200E+00L, /* 3fff001e01c211948400000000000000 */
+ 1.00048840047869447289485833607614040E+00L, /* 3fff0020020015560000000000000000 */
+ 1.00051893342751269111445822090900037E+00L, /* 3fff0022024219978400000000000000 */
+ 1.00054946730813676403215595200890675E+00L, /* 3fff002402881e611000000000000000 */
+ 1.00058000212059516886853316464112140E+00L, /* 3fff002602d223baa800000000000000 */
+ 1.00061053786491632733302026281307917E+00L, /* 3fff0028032029ac4c00000000000000 */
+ 1.00064107454112866113504765053221490E+00L, /* 3fff002a0372303dfc00000000000000 */
+ 1.00067161214926059198404573180596344E+00L, /* 3fff002c03c83777b800000000000000 */
+ 1.00070215068934059710059614189958666E+00L, /* 3fff002e04223f618400000000000000 */
+ 1.00073269016139709819412928482051939E+00L, /* 3fff0030048048036000000000000000 */
+ 1.00076323056545857248522679583402351E+00L, /* 3fff003204e251655000000000000000 */
+ 1.00079377190155338617216784768970683E+00L, /* 3fff003405485b8f5000000000000000 */
+ 1.00082431416971007198668530691065826E+00L, /* 3fff003605b266896800000000000000 */
+ 1.00085485736995705163820957750431262E+00L, /* 3fff00380620725b9800000000000000 */
+ 1.00088540150232269132501983222027775E+00L, /* 3fff003a06927f0ddc00000000000000 */
+ 1.00091594656683552377884893758164253E+00L, /* 3fff003c07088ca83c00000000000000 */
+ 1.00094649256352402622027852885366883E+00L, /* 3fff003e07829b32bc00000000000000 */
+ 1.00097703949241650933643654752813745E+00L, /* 3fff00400800aab55400000000000000 */
+ 1.00100758735354156137020709138596430E+00L, /* 3fff00420882bb381000000000000000 */
+ 1.00103813614692760403102056443458423E+00L, /* 3fff00440908ccc2f000000000000000 */
+ 1.00106868587260300351715613942360505E+00L, /* 3fff00460992df5df000000000000000 */
+ 1.00109923653059629256034668287611566E+00L, /* 3fff00480a20f3111800000000000000 */
+ 1.00112978812093589287002259879955091E+00L, /* 3fff004a0ab307e46800000000000000 */
+ 1.00116034064365022615561429120134562E+00L, /* 3fff004c0b491ddfe000000000000000 */
+ 1.00119089409876788066000585786241572E+00L, /* 3fff004e0be3350b8c00000000000000 */
+ 1.00122144848631711155917400901671499E+00L, /* 3fff00500c814d6f6000000000000000 */
+ 1.00125200380632656260715407370298635E+00L, /* 3fff00520d2367136c00000000000000 */
+ 1.00128256005882454449107399341301061E+00L, /* 3fff00540dc981ffa800000000000000 */
+ 1.00131311724383964545381786592770368E+00L, /* 3fff00560e739e3c2000000000000000 */
+ 1.00134367536140017618251363273884635E+00L, /* 3fff00580f21bbd0cc00000000000000 */
+ 1.00137423441153472492004539162735455E+00L, /* 3fff005a0fd3dac5b800000000000000 */
+ 1.00140479439427171337584354660066310E+00L, /* 3fff005c1089fb22e400000000000000 */
+ 1.00143535530963956325933850166620687E+00L, /* 3fff005e11441cf05000000000000000 */
+ 1.00146591715766680730226312334707472E+00L, /* 3fff0060120240360400000000000000 */
+ 1.00149647993838186721404781565070152E+00L, /* 3fff006212c464fc0000000000000000 */
+ 1.00152704365181316470412298258452211E+00L, /* 3fff0064138a8b4a4400000000000000 */
+ 1.00155760829798923250422149067162536E+00L, /* 3fff00661454b328d800000000000000 */
+ 1.00158817387693849232377374391944613E+00L, /* 3fff00681522dc9fbc00000000000000 */
+ 1.00161874038868942138336137759324629E+00L, /* 3fff006a15f507b6f400000000000000 */
+ 1.00164930783327055241471725821611471E+00L, /* 3fff006c16cb34768800000000000000 */
+ 1.00167987621071025161612055853765924E+00L, /* 3fff006e17a562e67400000000000000 */
+ 1.00171044552103705171930414508096874E+00L, /* 3fff00701883930ec000000000000000 */
+ 1.00174101576427937443369842185347807E+00L, /* 3fff00721965c4f76c00000000000000 */
+ 1.00177158694046569697988502412044909E+00L, /* 3fff00741a4bf8a87c00000000000000 */
+ 1.00180215904962455208959681840497069E+00L, /* 3fff00761b362e29f800000000000000 */
+ 1.00183273209178441698341543997230474E+00L, /* 3fff00781c246583e400000000000000 */
+ 1.00186330606697365785962006157205906E+00L, /* 3fff007a1d169ebe3c00000000000000 */
+ 1.00189388097522080744994354972732253E+00L, /* 3fff007c1e0cd9e10800000000000000 */
+ 1.00192445681655439848611877096118405E+00L, /* 3fff007e1f0716f45000000000000000 */
+ 1.00195503359100279716642489802325144E+00L, /* 3fff0080200556001000000000000000 */
+ 1.00198561129859459173374602869444061E+00L, /* 3fff00822107970c5400000000000000 */
+};
diff --git a/libc/sysdeps/ieee754/ldbl-128/t_sincosl.c b/libc/sysdeps/ieee754/ldbl-128/t_sincosl.c
new file mode 100644
index 000000000..c750fe9a7
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/t_sincosl.c
@@ -0,0 +1,694 @@
+/* Quad-precision floating point sine and cosine tables.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* For 0.1484375 + n/128.0, n=0..82 this table contains
+ first 113 bits of cosine, then at least 113 additional
+ bits and the same for sine.
+ 0.1484375+82.0/128.0 is the smallest number among above defined numbers
+ larger than pi/4.
+ Computed using gmp.
+ */
+
+const long double __sincosl_table[] = {
+
+/* x = 1.48437500000000000000000000000000000e-01L 3ffc3000000000000000000000000000 */
+/* cos(x) = 0.fd2f5320e1b790209b4dda2f98f79caaa7b873aff1014b0fbc5243766d03cb006bc837c4358 */
+ 9.89003367927322909016887196069562069e-01L, /* 3ffefa5ea641c36f2041369bb45f31ef */
+ 2.15663692029265697782289400027743703e-35L, /* 3f8bcaaa7b873aff1014b0fbc5243767 */
+/* sin(x) = 0.25dc50bc95711d0d9787d108fd438cf5959ee0bfb7a1e36e8b1a112968f356657420e9cc9ea */
+ 1.47892995873409608580026675734609314e-01L, /* 3ffc2ee285e4ab88e86cbc3e8847ea1c */
+ 9.74950446464233268291647449768590886e-36L, /* 3f8a9eb2b3dc17f6f43c6dd16342252d */
+
+/* x = 1.56250000000000000000000000000000000e-01 3ffc4000000000000000000000000000 */
+/* cos(x) = 0.fce1a053e621438b6d60c76e8c45bf0a9dc71aa16f922acc10e95144ec796a249813c9cb649 */
+ 9.87817783816471944100503034363211317e-01L, /* 3ffef9c340a7cc428716dac18edd188b */
+ 4.74271307836705897892468107620526395e-35L, /* 3f8cf854ee38d50b7c915660874a8a27 */
+/* sin(x) = 0.27d66258bacd96a3eb335b365c87d59438c5142bb56a489e9b8db9d36234ffdebb6bdc22d8e */
+ 1.55614992773556041209920643203516258e-01L, /* 3ffc3eb312c5d66cb51f599ad9b2e43f */
+-7.83989563419287980121718050629497270e-36L, /* bf8a4d78e75d7a8952b6ec2c8e48c594 */
+
+/* x = 1.64062500000000000000000000000000000e-01 3ffc5000000000000000000000000000 */
+/* cos(x) = 0.fc8ffa01ba6807417e05962b0d9fdf1fddb0cc4c07d22e19e08019bffa50a6c7acdb40307a3 */
+ 9.86571908399497588757337407495308409e-01L, /* 3ffef91ff40374d00e82fc0b2c561b40 */
+-2.47327949936985362476252401212720725e-35L, /* bf8c070112799d9fc16e8f30fbff3200 */
+/* sin(x) = 0.29cfd49b8be4f665276cab01cbf0426934906c3dd105473b226e410b1450f62e53ff7c6cce1 */
+ 1.63327491736612850846866172454354370e-01L, /* 3ffc4e7ea4dc5f27b3293b65580e5f82 */
+ 1.81380344301155485770367902300754350e-36L, /* 3f88349a48361ee882a39d913720858a */
+
+/* x = 1.71875000000000000000000000000000000e-01 3ffc6000000000000000000000000000 */
+/* cos(x) = 0.fc3a6170f767ac735d63d99a9d439e1db5e59d3ef153a4265d5855850ed82b536bf361b80e3 */
+ 9.85265817718213816204294709759578994e-01L, /* 3ffef874c2e1eecf58e6bac7b3353a87 */
+ 2.26568029505818066141517497778527952e-35L, /* 3f8be1db5e59d3ef153a4265d5855851 */
+/* sin(x) = 0.2bc89f9f424de5485de7ce03b2514952b9faf5648c3244d4736feb95dbb9da49f3b58a9253b */
+ 1.71030022031395019281347969239834331e-01L, /* 3ffc5e44fcfa126f2a42ef3e701d928a */
+ 7.01395875187487608875416030203241317e-36L, /* 3f8a2a573f5eac9186489a8e6dfd72bb */
+
+/* x = 1.79687500000000000000000000000000000e-01 3ffc7000000000000000000000000000 */
+/* cos(x) = 0.fbe0d7f7fef11e70aa43b8abf4f6a457cea20c8f3f676b47781f9821bbe9ce04b3c7b981c0b */
+ 9.83899591489663972178309351416487245e-01L, /* 3ffef7c1afeffde23ce154877157e9ed */
+ 2.73414318948066207810486330723761265e-35L, /* 3f8c22be75106479fb3b5a3bc0fcc10e */
+/* sin(x) = 0.2dc0bb80b49a97ffb34e8dd1f8db9df7af47ed2dcf58b12c8e7827e048cae929da02c04ecac */
+ 1.78722113535153659375356241864180724e-01L, /* 3ffc6e05dc05a4d4bffd9a746e8fc6dd */
+-1.52906926517265103202547561260594148e-36L, /* bf8804285c09691853a769b8c3ec0fdc */
+
+/* x = 1.87500000000000000000000000000000000e-01 3ffc8000000000000000000000000000 */
+/* cos(x) = 0.fb835efcf670dd2ce6fe7924697eea13ea358867e9cdb3899b783f4f9f43aa5626e8b67b3bc */
+ 9.82473313101255257487327683243622495e-01L, /* 3ffef706bdf9ece1ba59cdfcf248d2fe */
+-1.64924358891557584625463868014230342e-35L, /* bf8b5ec15ca779816324c766487c0b06 */
+/* sin(x) = 0.2fb8205f75e56a2b56a1c4792f856258769af396e0189ef72c05e4df59a6b00e4b44a6ea515 */
+ 1.86403296762269884552379983103205261e-01L, /* 3ffc7dc102fbaf2b515ab50e23c97c2b */
+ 1.76460304806826780010586715975331753e-36L, /* 3f882c3b4d79cb700c4f7b9602f26fad */
+
+/* x = 1.95312500000000000000000000000000000e-01 3ffc9000000000000000000000000000 */
+/* cos(x) = 0.fb21f7f5c156696b00ac1fe28ac5fd76674a92b4df80d9c8a46c684399005deccc41386257c */
+ 9.80987069605669190469329896435309665e-01L, /* 3ffef643efeb82acd2d601583fc5158c */
+-1.90899259410096419886996331536278461e-36L, /* bf8844cc5ab6a5903f931badc9cbde34 */
+/* sin(x) = 0.31aec65df552876f82ece9a2356713246eba6799983d7011b0b3698d6e1da919c15d57c30c1 */
+ 1.94073102892909791156055200214145404e-01L, /* 3ffc8d7632efaa943b7c17674d11ab39 */
+-9.67304741051998267208945242944928999e-36L, /* bf8a9b7228b30cccf851fdc9e992ce52 */
+
+/* x = 2.03125000000000000000000000000000000e-01 3ffca000000000000000000000000000 */
+/* cos(x) = 0.fabca467fb3cb8f1d069f01d8ea33ade5bfd68296ecd1cc9f7b7609bbcf3676e726c3301334 */
+ 9.79440951715548359998530954502987493e-01L, /* 3ffef57948cff67971e3a0d3e03b1d46 */
+ 4.42878056591560757066844797290067990e-35L, /* 3f8cd6f2dfeb414b7668e64fbdbb04de */
+/* sin(x) = 0.33a4a5a19d86246710f602c44df4fa513f4639ce938477aeeabb82e8e0a7ed583a188879fd4 */
+ 2.01731063801638804725038151164000971e-01L, /* 3ffc9d252d0cec31233887b016226fa8 */
+-4.27513434754966978435151290617384120e-36L, /* bf896bb02e718c5b1ee21445511f45c8 */
+
+/* x = 2.10937500000000000000000000000000000e-01 3ffcb000000000000000000000000000 */
+/* cos(x) = 0.fa5365e8f1d3ca27be1db5d76ae64d983d7470a4ab0f4ccf65a2b8c67a380df949953a09bc1 */
+ 9.77835053797959793331971572944454549e-01L, /* 3ffef4a6cbd1e3a7944f7c3b6baed5cd */
+-3.79207422905180416937210853779192702e-35L, /* bf8c933e145c7adaa7859984d2ea39cc */
+/* sin(x) = 0.3599b652f40ec999df12a0a4c8561de159c98d4e54555de518b97f48886f715d8df5f4f093e */
+ 2.09376712085993643711890752724881652e-01L, /* 3ffcaccdb297a0764ccef895052642b1 */
+-1.59470287344329449965314638482515925e-36L, /* bf880f531b3958d5d5510d73a3405bbc */
+
+/* x = 2.18750000000000000000000000000000000e-01 3ffcc000000000000000000000000000 */
+/* cos(x) = 0.f9e63e1d9e8b6f6f2e296bae5b5ed9c11fd7fa2fe11e09fc7bde901abed24b6365e72f7db4e */
+ 9.76169473868635276723989035435135534e-01L, /* 3ffef3cc7c3b3d16dede5c52d75cb6be */
+-2.87727974249481583047944860626985460e-35L, /* bf8c31f701402e80f70fb01c210b7f2a */
+/* sin(x) = 0.378df09db8c332ce0d2b53d865582e4526ea336c768f68c32b496c6d11c1cd241bb9f1da523 */
+ 2.17009581095010156760578095826055396e-01L, /* 3ffcbc6f84edc6199670695a9ec32ac1 */
+ 1.07356488794216831812829549198201194e-35L, /* 3f8ac8a4dd466d8ed1ed1865692d8da2 */
+
+/* x = 2.26562500000000000000000000000000000e-01 3ffcd000000000000000000000000000 */
+/* cos(x) = 0.f9752eba9fff6b98842beadab054a932fb0f8d5b875ae63d6b2288d09b148921aeb6e52f61b */
+ 9.74444313585988980349711056045434344e-01L, /* 3ffef2ea5d753ffed7310857d5b560a9 */
+ 3.09947905955053419304514538592548333e-35L, /* 3f8c4997d87c6adc3ad731eb59144685 */
+/* sin(x) = 0.39814cb10513453cb97b21bc1ca6a337b150c21a675ab85503bc09a436a10ab1473934e20c8 */
+ 2.24629204957705292350428549796424820e-01L, /* 3ffccc0a6588289a29e5cbd90de0e535 */
+ 2.42061510849297469844695751870058679e-36L, /* 3f889bd8a8610d33ad5c2a81de04d21b */
+
+/* x = 2.34375000000000000000000000000000000e-01 3ffce000000000000000000000000000 */
+/* cos(x) = 0.f90039843324f9b940416c1984b6cbed1fc733d97354d4265788a86150493ce657cae032674 */
+ 9.72659678244912752670913058267565260e-01L, /* 3ffef20073086649f3728082d833096e */
+-3.91759231819314904966076958560252735e-35L, /* bf8ca09701c6613465595ecd43babcf5 */
+/* sin(x) = 0.3b73c2bf6b4b9f668ef9499c81f0d965087f1753fa64b086e58cb8470515c18c1412f8c2e02 */
+ 2.32235118611511462413930877746235872e-01L, /* 3ffcdb9e15fb5a5cfb3477ca4ce40f87 */
+-4.96930483364191020075024624332928910e-36L, /* bf89a6bde03a2b0166d3de469cd1ee3f */
+
+/* x = 2.42187500000000000000000000000000000e-01 3ffcf000000000000000000000000000 */
+/* cos(x) = 0.f887604e2c39dbb20e4ec5825059a789ffc95b275ad9954078ba8a28d3fcfe9cc2c1d49697b */
+ 9.70815676770349462947490545785046027e-01L, /* 3ffef10ec09c5873b7641c9d8b04a0b3 */
+ 2.97458820972393859125277682021202860e-35L, /* 3f8c3c4ffe4ad93ad6ccaa03c5d45147 */
+/* sin(x) = 0.3d654aff15cb457a0fca854698aba33039a8a40626609204472d9d40309b626eccc6dff0ffa */
+ 2.39826857830661564441369251810886574e-01L, /* 3ffceb2a57f8ae5a2bd07e542a34c55d */
+ 2.39867036569896287240938444445071448e-36L, /* 3f88981cd45203133049022396cea018 */
+
+/* x = 2.50000000000000000000000000000000000e-01 3ffd0000000000000000000000000000 */
+/* cos(x) = 0.f80aa4fbef750ba783d33cb95f94f8a41426dbe79edc4a023ef9ec13c944551c0795b84fee1 */
+ 9.68912421710644784144595449494189205e-01L, /* 3ffef01549f7deea174f07a67972bf2a */
+-5.53634706113461989398873287749326500e-36L, /* bf89d6faf649061848ed7f704184fb0e */
+/* sin(x) = 0.3f55dda9e62aed7513bd7b8e6a3d1635dd5676648d7db525898d7086af9330f03c7f285442a */
+ 2.47403959254522929596848704849389203e-01L, /* 3ffcfaaeed4f31576ba89debdc7351e9 */
+-7.36487001108599532943597115275811618e-36L, /* bf8a39445531336e50495b4ece51ef2a */
+
+/* x = 2.57812500000000000000000000000000000e-01 3ffd0800000000000000000000000000 */
+/* cos(x) = 0.f78a098069792daabc9ee42591b7c5a68cb1ab822aeb446b3311b4ba5371b8970e2c1547ad7 */
+ 9.66950029230677822008341623610531503e-01L, /* 3ffeef141300d2f25b55793dc84b2370 */
+-4.38972214432792412062088059990480514e-35L, /* bf8cd2cb9a72a3eea8a5dca667725a2d */
+/* sin(x) = 0.414572fd94556e6473d620271388dd47c0ba050cdb5270112e3e370e8c4705ae006426fb5d5 */
+ 2.54965960415878467487556574864872628e-01L, /* 3ffd0515cbf65155b991cf58809c4e23 */
+ 2.20280377918534721005071688328074154e-35L, /* 3f8bd47c0ba050cdb5270112e3e370e9 */
+
+/* x = 2.65625000000000000000000000000000000e-01 3ffd1000000000000000000000000000 */
+/* cos(x) = 0.f7058fde0788dfc805b8fe88789e4f4253e3c50afe8b22f41159620ab5940ff7df9557c0d1f */
+ 9.64928619104771009581074665315748371e-01L, /* 3ffeee0b1fbc0f11bf900b71fd10f13d */
+-3.66685832670820775002475545602761113e-35L, /* bf8c85ed60e1d7a80ba6e85f7534efaa */
+/* sin(x) = 0.4334033bcd90d6604f5f36c1d4b84451a87150438275b77470b50e5b968fa7962b5ffb379b7 */
+ 2.62512399769153281450949626395692931e-01L, /* 3ffd0cd00cef364359813d7cdb0752e1 */
+ 3.24923677072031064673177178571821843e-36L, /* 3f89146a1c5410e09d6ddd1c2d4396e6 */
+
+/* x = 2.73437500000000000000000000000000000e-01 3ffd1800000000000000000000000000 */
+/* cos(x) = 0.f67d3a26af7d07aa4bd6d42af8c0067fefb96d5b46c031eff53627f215ea3242edc3f2e13eb */
+ 9.62848314709379699899701093480214365e-01L, /* 3ffeecfa744d5efa0f5497ada855f180 */
+ 4.88986966383343450799422013051821394e-36L, /* 3f899ffbee5b56d1b00c7bfd4d89fc85 */
+/* sin(x) = 0.452186aa5377ab20bbf2524f52e3a06a969f47166ab88cf88c111ad12c55941021ef3317a1a */
+ 2.70042816718585031552755063618827102e-01L, /* 3ffd14861aa94ddeac82efc9493d4b8f */
+-2.37608892440611310321138680065803162e-35L, /* bf8bf956960b8e99547730773eee52ed */
+
+/* x = 2.81250000000000000000000000000000000e-01 3ffd2000000000000000000000000000 */
+/* cos(x) = 0.f5f10a7bb77d3dfa0c1da8b57842783280d01ce3c0f82bae3b9d623c168d2e7c29977994451 */
+ 9.60709243015561903066659350581313472e-01L, /* 3ffeebe214f76efa7bf4183b516af085 */
+-5.87011558231583960712013351601221840e-36L, /* bf89f35fcbf8c70fc1f5147118a770fa */
+/* sin(x) = 0.470df5931ae1d946076fe0dcff47fe31bb2ede618ebc607821f8462b639e1f4298b5ae87fd3 */
+ 2.77556751646336325922023446828128568e-01L, /* 3ffd1c37d64c6b8765181dbf8373fd20 */
+-1.35848595468998128214344668770082997e-36L, /* bf87ce44d1219e71439f87de07b9d49c */
+
+/* x = 2.89062500000000000000000000000000000e-01 3ffd2800000000000000000000000000 */
+/* cos(x) = 0.f561030ddd7a78960ea9f4a32c6521554995667f5547bafee9ec48b3155cdb0f7fd00509713 */
+ 9.58511534581228627301969408154919822e-01L, /* 3ffeeac2061bbaf4f12c1d53e94658ca */
+ 2.50770779371636481145735089393154404e-35L, /* 3f8c0aaa4cab33faaa3dd7f74f624599 */
+/* sin(x) = 0.48f948446abcd6b0f7fccb100e7a1b26eccad880b0d24b59948c7cdd49514d44b933e6985c2 */
+ 2.85053745940547424587763033323252561e-01L, /* 3ffd23e52111aaf35ac3dff32c4039e8 */
+ 2.04269325885902918802700123680403749e-35L, /* 3f8bb26eccad880b0d24b59948c7cdd5 */
+
+/* x = 2.96875000000000000000000000000000000e-01 3ffd3000000000000000000000000000 */
+/* cos(x) = 0.f4cd261d3e6c15bb369c8758630d2ac00b7ace2a51c0631bfeb39ed158ba924cc91e259c195 */
+ 9.56255323543175296975599942263028361e-01L, /* 3ffee99a4c3a7cd82b766d390eb0c61a */
+ 3.21616572190865997051103645135837207e-35L, /* 3f8c56005bd671528e0318dff59cf68b */
+/* sin(x) = 0.4ae37710fad27c8aa9c4cf96c03519b9ce07dc08a1471775499f05c29f86190aaebaeb9716e */
+ 2.92533342023327543624702326493913423e-01L, /* 3ffd2b8ddc43eb49f22aa7133e5b00d4 */
+ 1.93539408668704450308003687950685128e-35L, /* 3f8b9b9ce07dc08a1471775499f05c2a */
+
+/* x = 3.04687500000000000000000000000000000e-01 3ffd3800000000000000000000000000 */
+/* cos(x) = 0.f43575f94d4f6b272f5fb76b14d2a64ab52df1ee8ddf7c651034e5b2889305a9ea9015d758a */
+ 9.53940747608894733981324795987611623e-01L, /* 3ffee86aebf29a9ed64e5ebf6ed629a5 */
+ 2.88075689052478602008395972924657164e-35L, /* 3f8c3255a96f8f746efbe32881a72d94 */
+/* sin(x) = 0.4ccc7a50127e1de0cb6b40c302c651f7bded4f9e7702b0471ae0288d091a37391950907202f */
+ 2.99995083378683051163248282011699944e-01L, /* 3ffd3331e94049f877832dad030c0b19 */
+ 1.35174265535697850139283361475571050e-35L, /* 3f8b1f7bded4f9e7702b0471ae0288d1 */
+
+/* x = 3.12500000000000000000000000000000000e-01 3ffd4000000000000000000000000000 */
+/* cos(x) = 0.f399f500c9e9fd37ae9957263dab8877102beb569f101ee4495350868e5847d181d50d3cca2 */
+ 9.51567948048172202145488217364270962e-01L, /* 3ffee733ea0193d3fa6f5d32ae4c7b57 */
+ 6.36842628598115658308749288799884606e-36L, /* 3f8a0ee2057d6ad3e203dc892a6a10d2 */
+/* sin(x) = 0.4eb44a5da74f600207aaa090f0734e288603ffadb3eb2542a46977b105f8547128036dcf7f0 */
+ 3.07438514580380850670502958201982091e-01L, /* 3ffd3ad129769d3d80081eaa8243c1cd */
+ 1.06515172423204645839241099453417152e-35L, /* 3f8ac510c07ff5b67d64a8548d2ef621 */
+
+/* x = 3.20312500000000000000000000000000000e-01 3ffd4800000000000000000000000000 */
+/* cos(x) = 0.f2faa5a1b74e82fd61fa05f9177380e8e69b7b15a945e8e5ae1124bf3d12b0617e03af4fab5 */
+ 9.49137069684463027665847421762105623e-01L, /* 3ffee5f54b436e9d05fac3f40bf22ee7 */
+ 6.84433965991637152250309190468859701e-37L, /* 3f86d1cd36f62b528bd1cb5c22497e7a */
+/* sin(x) = 0.509adf9a7b9a5a0f638a8fa3a60a199418859f18b37169a644fdb986c21ecb00133853bc35b */
+ 3.14863181319745250865036315126939016e-01L, /* 3ffd426b7e69ee69683d8e2a3e8e9828 */
+ 1.92431240212432926993057705062834160e-35L, /* 3f8b99418859f18b37169a644fdb986c */
+
+/* x = 3.28125000000000000000000000000000000e-01 3ffd5000000000000000000000000000 */
+/* cos(x) = 0.f2578a595224dd2e6bfa2eb2f99cc674f5ea6f479eae2eb580186897ae3f893df1113ca06b8 */
+ 9.46648260886053321846099507295532976e-01L, /* 3ffee4af14b2a449ba5cd7f45d65f33a */
+-4.32906339663000890941529420498824645e-35L, /* bf8ccc5850ac85c30a8e8a53ff3cbb43 */
+/* sin(x) = 0.5280326c3cf481823ba6bb08eac82c2093f2bce3c4eb4ee3dec7df41c92c8a4226098616075 */
+ 3.22268630433386625687745919893188031e-01L, /* 3ffd4a00c9b0f3d20608ee9aec23ab21 */
+-1.49505897804759263483853908335500228e-35L, /* bf8b3df6c0d431c3b14b11c213820be3 */
+
+/* x = 3.35937500000000000000000000000000000e-01 3ffd5800000000000000000000000000 */
+/* cos(x) = 0.f1b0a5b406b526d886c55feadc8d0dcc8eb9ae2ac707051771b48e05b25b000009660bdb3e3 */
+ 9.44101673557004345630017691253124860e-01L, /* 3ffee3614b680d6a4db10d8abfd5b91a */
+ 1.03812535240120229609822461172145584e-35L, /* 3f8ab991d735c558e0e0a2ee3691c0b6 */
+/* sin(x) = 0.54643b3da29de9b357155eef0f332fb3e66c83bf4dddd9491c5eb8e103ccd92d6175220ed51 */
+ 3.29654409930860171914317725126463176e-01L, /* 3ffd5190ecf68a77a6cd5c557bbc3ccd */
+-1.22606996784743214973082192294232854e-35L, /* bf8b04c19937c40b22226b6e3a1471f0 */
+
+/* x = 3.43750000000000000000000000000000000e-01 3ffd6000000000000000000000000000 */
+/* cos(x) = 0.f105fa4d66b607a67d44e042725204435142ac8ad54dfb0907a4f6b56b06d98ee60f19e557a */
+ 9.41497463127881068644511236053670815e-01L, /* 3ffee20bf49acd6c0f4cfa89c084e4a4 */
+ 3.20709366603165602071590241054884900e-36L, /* 3f8910d450ab22b5537ec241e93dad5b */
+/* sin(x) = 0.5646f27e8bd65cbe3a5d61ff06572290ee826d9674a00246b05ae26753cdfc90d9ce81a7d02 */
+ 3.37020069022253076261281754173810024e-01L, /* 3ffd591bc9fa2f5972f8e97587fc195d */
+-2.21435756148839473677777545049890664e-35L, /* bf8bd6f117d92698b5ffdb94fa51d98b */
+
+/* x = 3.51562500000000000000000000000000000e-01 3ffd6800000000000000000000000000 */
+/* cos(x) = 0.f0578ad01ede707fa39c09dc6b984afef74f3dc8d0efb0f4c5a6b13771145b3e0446fe33887 */
+ 9.38835788546265488632578305984712554e-01L, /* 3ffee0af15a03dbce0ff473813b8d731 */
+-3.98758068773974031348585072752245458e-35L, /* bf8ca808458611b978827859d2ca7644 */
+/* sin(x) = 0.582850a41e1dd46c7f602ea244cdbbbfcdfa8f3189be794dda427ce090b5f85164f1f80ac13 */
+ 3.44365158145698408207172046472223747e-01L, /* 3ffd60a14290787751b1fd80ba891337 */
+-3.19791885005480924937758467594051927e-36L, /* bf89100c815c339d9061ac896f60c7dc */
+
+/* x = 3.59375000000000000000000000000000000e-01 3ffd7000000000000000000000000000 */
+/* cos(x) = 0.efa559f5ec3aec3a4eb03319278a2d41fcf9189462261125fe6147b078f1daa0b06750a1654 */
+ 9.36116812267055290294237411019508588e-01L, /* 3ffedf4ab3ebd875d8749d6066324f14 */
+ 3.40481591236710658435409862439032162e-35L, /* 3f8c6a0fe7c8c4a31130892ff30a3d84 */
+/* sin(x) = 0.5a084e28e35fda2776dfdbbb5531d74ced2b5d17c0b1afc4647529d50c295e36d8ceec126c1 */
+ 3.51689228994814059222584896955547016e-01L, /* 3ffd682138a38d7f689ddb7f6eed54c7 */
+ 1.75293433418270210567525412802083294e-35L, /* 3f8b74ced2b5d17c0b1afc4647529d51 */
+
+/* x = 3.67187500000000000000000000000000000e-01 3ffd7800000000000000000000000000 */
+/* cos(x) = 0.eeef6a879146af0bf9b95ea2ea0ac0d3e2e4d7e15d93f48cbd41bf8e4fded40bef69e19eafa */
+ 9.33340700242548435655299229469995527e-01L, /* 3ffeddded50f228d5e17f372bd45d416 */
+-4.75255707251679831124800898831382223e-35L, /* bf8cf960e8d940f513605b9a15f2038e */
+/* sin(x) = 0.5be6e38ce8095542bc14ee9da0d36483e6734bcab2e07624188af5653f114eeb46738fa899d */
+ 3.58991834546065053677710299152868941e-01L, /* 3ffd6f9b8e33a025550af053ba76834e */
+-2.06772389262723368139416970257112089e-35L, /* bf8bb7c198cb4354d1f89dbe7750a9ac */
+
+/* x = 3.75000000000000000000000000000000000e-01 3ffd8000000000000000000000000000 */
+/* cos(x) = 0.ee35bf5ccac89052cd91ddb734d3a47e262e3b609db604e217053803be0091e76daf28a89b7 */
+ 9.30507621912314291149476792229555481e-01L, /* 3ffedc6b7eb9959120a59b23bb6e69a7 */
+ 2.74541088551732982573335285685416092e-35L, /* 3f8c23f13171db04edb02710b829c01e */
+/* sin(x) = 0.5dc40955d9084f48a94675a2498de5d851320ff5528a6afb3f2e24de240fce6cbed1ba0ccd6 */
+ 3.66272529086047561372909351716264177e-01L, /* 3ffd7710255764213d22a519d6892638 */
+-1.96768433534936592675897818253108989e-35L, /* bf8ba27aecdf00aad759504c0d1db21e */
+
+/* x = 3.82812500000000000000000000000000000e-01 3ffd8800000000000000000000000000 */
+/* cos(x) = 0.ed785b5c44741b4493c56bcb9d338a151c6f6b85d8f8aca658b28572c162b199680eb9304da */
+ 9.27617750192851909628030798799961350e-01L, /* 3ffedaf0b6b888e83689278ad7973a67 */
+ 7.58520371916345756281201167126854712e-36L, /* 3f8a42a38ded70bb1f1594cb1650ae58 */
+/* sin(x) = 0.5f9fb80f21b53649c432540a50e22c53057ff42ae0fdf1307760dc0093f99c8efeb2fbd7073 */
+ 3.73530868238692946416839752660848112e-01L, /* 3ffd7e7ee03c86d4d92710c950294389 */
+-1.48023494778986556048879113411517128e-35L, /* bf8b3acfa800bd51f020ecf889f23ff7 */
+
+/* x = 3.90625000000000000000000000000000000e-01 3ffd9000000000000000000000000000 */
+/* cos(x) = 0.ecb7417b8d4ee3fec37aba4073aa48f1f14666006fb431d9671303c8100d10190ec8179c41d */
+ 9.24671261467036098502113014560138771e-01L, /* 3ffed96e82f71a9dc7fd86f57480e755 */
+-4.14187124860031825108649347251175815e-35L, /* bf8cb87075cccffc825e7134c767e1bf */
+/* sin(x) = 0.6179e84a09a5258a40e9b5face03e525f8b5753cd0105d93fe6298010c3458e84d75fe420e9 */
+ 3.80766408992390192057200703388896675e-01L, /* 3ffd85e7a1282694962903a6d7eb3810 */
+-2.02009541175208636336924533372496107e-35L, /* bf8bada074a8ac32fefa26c019d67fef */
+
+/* x = 3.98437500000000000000000000000000000e-01 3ffd9800000000000000000000000000 */
+/* cos(x) = 0.ebf274bf0bda4f62447e56a093626798d3013b5942b1abfd155aacc9dc5c6d0806a20d6b9c1 */
+ 9.21668335573351918175411368202712714e-01L, /* 3ffed7e4e97e17b49ec488fcad4126c5 */
+-1.83587995433957622948710263541479322e-35L, /* bf8b8672cfec4a6bd4e5402eaa553362 */
+/* sin(x) = 0.6352929dd264bd44a02ea766325d8aa8bd9695fc8def3caefba5b94c9a3c873f7b2d3776ead */
+ 3.87978709727025046051079690813741960e-01L, /* 3ffd8d4a4a774992f51280ba9d98c976 */
+ 8.01904783870935075844443278617586301e-36L, /* 3f8a5517b2d2bf91bde795df74b72993 */
+
+/* x = 4.06250000000000000000000000000000000e-01 3ffda000000000000000000000000000 */
+/* cos(x) = 0.eb29f839f201fd13b93796827916a78f15c85230a4e8ea4b21558265a14367e1abb4c30695a */
+ 9.18609155794918267837824977718549863e-01L, /* 3ffed653f073e403fa27726f2d04f22d */
+ 2.97608282778274433460057745798409849e-35L, /* 3f8c3c78ae429185274752590aac132d */
+/* sin(x) = 0.6529afa7d51b129631ec197c0a840a11d7dc5368b0a47956feb285caa8371c4637ef17ef01b */
+ 3.95167330240934236244832640419653657e-01L, /* 3ffd94a6be9f546c4a58c7b065f02a10 */
+ 7.57560031388312550940040194042627704e-36L, /* 3f8a423afb8a6d16148f2adfd650b955 */
+
+/* x = 4.14062500000000000000000000000000000e-01 3ffda800000000000000000000000000 */
+/* cos(x) = 0.ea5dcf0e30cf03e6976ef0b1ec26515fba47383855c3b4055a99b5e86824b2cd1a691fdca7b */
+ 9.15493908848301228563917732180221882e-01L, /* 3ffed4bb9e1c619e07cd2edde163d84d */
+-3.50775517955306954815090901168305659e-35L, /* bf8c75022dc63e3d51e25fd52b3250bd */
+/* sin(x) = 0.66ff380ba0144109e39a320b0a3fa5fd65ea0585bcbf9b1a769a9b0334576c658139e1a1cbe */
+ 4.02331831777773111217105598880982387e-01L, /* 3ffd9bfce02e805104278e68c82c28ff */
+-1.95678722882848174723569916504871563e-35L, /* bf8ba029a15fa7a434064e5896564fcd */
+
+/* x = 4.21875000000000000000000000000000000e-01 3ffdb000000000000000000000000000 */
+/* cos(x) = 0.e98dfc6c6be031e60dd3089cbdd18a75b1f6b2c1e97f79225202f03dbea45b07a5ec4efc062 */
+ 9.12322784872117846492029542047341734e-01L, /* 3ffed31bf8d8d7c063cc1ba611397ba3 */
+ 7.86903886556373674267948132178845568e-36L, /* 3f8a4eb63ed6583d2fef244a405e07b8 */
+/* sin(x) = 0.68d32473143327973bc712bcc4ccddc47630d755850c0655243b205934dc49ffed8eb76adcb */
+ 4.09471777053295066122694027011452236e-01L, /* 3ffda34c91cc50cc9e5cef1c4af31333 */
+ 2.23945241468457597921655785729821354e-35L, /* 3f8bdc47630d755850c0655243b20593 */
+
+/* x = 4.29687500000000000000000000000000000e-01 3ffdb800000000000000000000000000 */
+/* cos(x) = 0.e8ba8393eca7821aa563d83491b6101189b3b101c3677f73d7bad7c10f9ee02b7ab4009739a */
+ 9.09095977415431051650381735684476417e-01L, /* 3ffed1750727d94f04354ac7b069236c */
+ 1.20886014028444155733776025085677953e-35L, /* 3f8b01189b3b101c3677f73d7bad7c11 */
+/* sin(x) = 0.6aa56d8e8249db4eb60a761fe3f9e559be456b9e13349ca99b0bfb787f22b95db3b70179615 */
+ 4.16586730282041119259112448831069657e-01L, /* 3ffdaa95b63a09276d3ad829d87f8fe8 */
+-2.00488106831998813675438269796963612e-35L, /* bf8baa641ba9461eccb635664f404878 */
+
+/* x = 4.37500000000000000000000000000000000e-01 3ffdc000000000000000000000000000 */
+/* cos(x) = 0.e7e367d2956cfb16b6aa11e5419cd0057f5c132a6455bf064297e6a76fe2b72bb630d6d50ff */
+ 9.05813683425936420744516660652700258e-01L, /* 3ffecfc6cfa52ad9f62d6d5423ca833a */
+-3.60950307605941169775676563004467163e-35L, /* bf8c7fd4051f66acdd5207cdeb40cac5 */
+/* sin(x) = 0.6c760c14c8585a51dbd34660ae6c52ac7036a0b40887a0b63724f8b4414348c3063a637f457 */
+ 4.23676257203938010361683988031102480e-01L, /* 3ffdb1d83053216169476f4d1982b9b1 */
+ 1.40484456388654470329473096579312595e-35L, /* 3f8b2ac7036a0b40887a0b63724f8b44 */
+
+/* x = 4.45312500000000000000000000000000000e-01 3ffdc800000000000000000000000000 */
+/* cos(x) = 0.e708ac84d4172a3e2737662213429e14021074d7e702e77d72a8f1101a7e70410df8273e9aa */
+ 9.02476103237941504925183272675895999e-01L, /* 3ffece115909a82e547c4e6ecc442685 */
+ 2.26282899501344419018306295680210602e-35L, /* 3f8be14021074d7e702e77d72a8f1102 */
+/* sin(x) = 0.6e44f8c36eb10a1c752d093c00f4d47ba446ac4c215d26b0316442f168459e677d06e7249e3 */
+ 4.30739925110803197216321517850849190e-01L, /* 3ffdb913e30dbac42871d4b424f003d3 */
+ 1.54096780001629398850891218396761548e-35L, /* 3f8b47ba446ac4c215d26b0316442f17 */
+
+/* x = 4.53125000000000000000000000000000000e-01 3ffdd000000000000000000000000000 */
+/* cos(x) = 0.e62a551594b970a770b15d41d4c0e483e47aca550111df6966f9e7ac3a94ae49e6a71eb031e */
+ 8.99083440560138456216544929209379307e-01L, /* 3ffecc54aa2b2972e14ee162ba83a982 */
+-2.06772615490904370666670275154751976e-35L, /* bf8bb7c1b8535aafeee209699061853c */
+/* sin(x) = 0.70122c5ec5028c8cff33abf4fd340ccc382e038379b09cf04f9a52692b10b72586060cbb001 */
+ 4.37777302872755132861618974702796680e-01L, /* 3ffdc048b17b140a3233fcceafd3f4d0 */
+ 9.62794364503442612477117426033922467e-36L, /* 3f8a998705c0706f36139e09f34a4d25 */
+
+/* x = 4.60937500000000000000000000000000000e-01 3ffdd800000000000000000000000000 */
+/* cos(x) = 0.e54864fe33e8575cabf5bd0e5cf1b1a8bc7c0d5f61702450fa6b6539735820dd2603ae355d5 */
+ 8.95635902463170698900570000446256350e-01L, /* 3ffeca90c9fc67d0aeb957eb7a1cb9e3 */
+ 3.73593741659866883088620495542311808e-35L, /* 3f8c8d45e3e06afb0b812287d35b29cc */
+/* sin(x) = 0.71dd9fb1ff4677853acb970a9f6729c6e3aac247b1c57cea66c77413f1f98e8b9e98e49d851 */
+ 4.44787960964527211433056012529525211e-01L, /* 3ffdc7767ec7fd19de14eb2e5c2a7d9d */
+-1.67187936511493678007508371613954899e-35L, /* bf8b6391c553db84e3a831599388bec1 */
+
+/* x = 4.68750000000000000000000000000000000e-01 3ffde000000000000000000000000000 */
+/* cos(x) = 0.e462dfc670d421ab3d1a15901228f146a0547011202bf5ab01f914431859aef577966bc4fa4 */
+ 8.92133699366994404723900253723788575e-01L, /* 3ffec8c5bf8ce1a843567a342b202452 */
+-1.10771937602567314732693079264692504e-35L, /* bf8ad72bf571fddbfa814a9fc0dd779d */
+/* sin(x) = 0.73a74b8f52947b681baf6928eb3fb021769bf4779bad0e3aa9b1cdb75ec60aad9fc63ff19d5 */
+ 4.51771471491683776581688750134062870e-01L, /* 3ffdce9d2e3d4a51eda06ebda4a3acff */
+-1.19387223016472295893794387275284505e-35L, /* bf8afbd12c81710c8a5e38aac9c64914 */
+
+/* x = 4.76562500000000000000000000000000000e-01 3ffde800000000000000000000000000 */
+/* cos(x) = 0.e379c9045f29d517c4808aa497c2057b2b3d109e76c0dc302d4d0698b36e3f0bdbf33d8e952 */
+ 8.88577045028035543317609023116020980e-01L, /* 3ffec6f39208be53aa2f890115492f84 */
+ 4.12354278954664731443813655177022170e-36L, /* 3f895ecacf44279db0370c0b5341a62d */
+/* sin(x) = 0.756f28d011d98528a44a75fc29c779bd734ecdfb582fdb74b68a4c4c4be54cfd0b2d3ad292f */
+ 4.58727408216736592377295028972874773e-01L, /* 3ffdd5bca340476614a29129d7f0a71e */
+-4.70946994194182908929251719575431779e-36L, /* bf8990a32c4c8129f40922d25d6ceced */
+
+/* x = 4.84375000000000000000000000000000000e-01 3ffdf000000000000000000000000000 */
+/* cos(x) = 0.e28d245c58baef72225e232abc003c4366acd9eb4fc2808c2ab7fe7676cf512ac7f945ae5fb */
+ 8.84966156526143291697296536966647926e-01L, /* 3ffec51a48b8b175dee444bc46557800 */
+ 4.53370570288325630442037826313462165e-35L, /* 3f8ce21b3566cf5a7e14046155bff3b4 */
+/* sin(x) = 0.77353054ca72690d4c6e171fd99e6b39fa8e1ede5f052fd2964534c75340970a3a9cd3c5c32 */
+ 4.65655346585160182681199512507546779e-01L, /* 3ffddcd4c15329c9a43531b85c7f667a */
+-1.56282598978971872478619772155305961e-35L, /* bf8b4c60571e121a0fad02d69bacb38b */
+
+/* x = 4.92187500000000000000000000000000000e-01 3ffdf800000000000000000000000000 */
+/* cos(x) = 0.e19cf580eeec046aa1422fa74807ecefb2a1911c94e7b5f20a00f70022d940193691e5bd790 */
+ 8.81301254251340599140161908298100173e-01L, /* 3ffec339eb01ddd808d542845f4e9010 */
+-1.43419192312116687783945619009629445e-35L, /* bf8b3104d5e6ee36b184a0df5ff08ffe */
+/* sin(x) = 0.78f95b0560a9a3bd6df7bd981dc38c61224d08bc20631ea932e605e53b579e9e0767dfcbbcb */
+ 4.72554863751304451146551317808516942e-01L, /* 3ffde3e56c1582a68ef5b7def660770e */
+ 9.31324774957768018850224267625371204e-36L, /* 3f8a8c2449a117840c63d5265cc0bca7 */
+
+/* x = 5.00000000000000000000000000000000000e-01 3ffe0000000000000000000000000000 */
+/* cos(x) = 0.e0a94032dbea7cedbddd9da2fafad98556566b3a89f43eabd72350af3e8b19e801204d8fe2e */
+ 8.77582561890372716116281582603829681e-01L, /* 3ffec1528065b7d4f9db7bbb3b45f5f6 */
+-2.89484960181363924855192538540698851e-35L, /* bf8c33d54d4ca62bb05e0aa146e57a86 */
+/* sin(x) = 0.7abba1d12c17bfa1d92f0d93f60ded9992f45b4fcaf13cd58b303693d2a0db47db35ae8a3a9 */
+ 4.79425538604203000273287935215571402e-01L, /* 3ffdeaee8744b05efe8764bc364fd838 */
+-1.38426977616718318950175848639381926e-35L, /* bf8b2666d0ba4b0350ec32a74cfc96c3 */
+
+/* x = 5.07812500000000000000000000000000000e-01 3ffe0400000000000000000000000000 */
+/* cos(x) = 0.dfb20840f3a9b36f7ae2c515342890b5ec583b8366cc2b55029e95094d31112383f2553498b */
+ 8.73810306413054508282556837071377159e-01L, /* 3ffebf641081e75366def5c58a2a6851 */
+ 1.25716864497849302237218128599994785e-35L, /* 3f8b0b5ec583b8366cc2b55029e95095 */
+/* sin(x) = 0.7c7bfdaf13e5ed17212f8a7525bfb113aba6c0741b5362bb8d59282a850b63716bca0c910f0 */
+ 4.86266951793275574311011306895834993e-01L, /* 3ffdf1eff6bc4f97b45c84be29d496ff */
+-1.12269393250914752644352376448094271e-35L, /* bf8add8a8b27f17c9593a88e54dafaaf */
+
+/* x = 5.15625000000000000000000000000000000e-01 3ffe0800000000000000000000000000 */
+/* cos(x) = 0.deb7518814a7a931bbcc88c109cd41c50bf8bb48f20ae8c36628d1d3d57574f7dc58f27d91c */
+ 8.69984718058417388828915599901466243e-01L, /* 3ffebd6ea310294f526377991182139b */
+-4.68168638300575626782741319792183837e-35L, /* bf8cf1d7a03a25b86fa8b9e4ceb97161 */
+/* sin(x) = 0.7e3a679daaf25c676542bcb4028d0964172961c921823a4ef0c3a9070d886dbd073f6283699 */
+ 4.93078685753923057265136552753487121e-01L, /* 3ffdf8e99e76abc9719d950af2d00a34 */
+ 7.06498693112535056352301101088624950e-36L, /* 3f8a2c82e52c3924304749de187520e2 */
+
+/* x = 5.23437500000000000000000000000000000e-01 3ffe0c00000000000000000000000000 */
+/* cos(x) = 0.ddb91ff318799172bd2452d0a3889f5169c64a0094bcf0b8aa7dcf0d7640a2eba68955a80be */
+ 8.66106030320656714696616831654267220e-01L, /* 3ffebb723fe630f322e57a48a5a14711 */
+ 2.35610597588322493119667003904687628e-35L, /* 3f8bf5169c64a0094bcf0b8aa7dcf0d7 */
+/* sin(x) = 0.7ff6d8a34bd5e8fa54c97482db5159df1f24e8038419c0b448b9eea8939b5d4dfcf40900257 */
+ 4.99860324733013463819556536946425724e-01L, /* 3ffdffdb628d2f57a3e95325d20b6d45 */
+ 1.94636052312235297538564591686645139e-35L, /* 3f8b9df1f24e8038419c0b448b9eea89 */
+
+/* x = 5.31250000000000000000000000000000000e-01 3ffe1000000000000000000000000000 */
+/* cos(x) = 0.dcb7777ac420705168f31e3eb780ce9c939ecada62843b54522f5407eb7f21e556059fcd734 */
+ 8.62174479934880504367162510253324274e-01L, /* 3ffeb96eeef58840e0a2d1e63c7d6f02 */
+-3.71556818317533582234562471835771823e-35L, /* bf8c8b1b6309a92cebde255d6e855fc1 */
+/* sin(x) = 0.81b149ce34caa5a4e650f8d09fd4d6aa74206c32ca951a93074c83b2d294d25dbb0f7fdfad2 */
+ 5.06611454814257367642296000893867192e-01L, /* 3ffe0362939c69954b49cca1f1a13faa */
+-3.10963699824274155702706043065967062e-35L, /* bf8c4aac5efc9e69ab572b67c59be269 */
+
+/* x = 5.39062500000000000000000000000000000e-01 3ffe1400000000000000000000000000 */
+/* cos(x) = 0.dbb25c25b8260c14f6e7bc98ec991b70c65335198b0ab628bad20cc7b229d4dd62183cfa055 */
+ 8.58190306862660347046629564970494649e-01L, /* 3ffeb764b84b704c1829edcf7931d932 */
+ 2.06439574601190798155563653000684861e-35L, /* 3f8bb70c65335198b0ab628bad20cc7b */
+/* sin(x) = 0.8369b434a372da7eb5c8a71fe36ce1e0b2b493f6f5cb2e38bcaec2a556b3678c401940d1c3c */
+ 5.13331663943471218288801270215706878e-01L, /* 3ffe06d3686946e5b4fd6b914e3fc6da */
+-2.26614796466671970772244932848067224e-35L, /* bf8be1f4d4b6c090a34d1c743513d5ab */
+
+/* x = 5.46875000000000000000000000000000000e-01 3ffe1800000000000000000000000000 */
+/* cos(x) = 0.daa9d20860827063fde51c09e855e9932e1b17143e7244fd267a899d41ae1f3bc6a0ec42e27 */
+ 8.54153754277385385143451785105103176e-01L, /* 3ffeb553a410c104e0c7fbca3813d0ac */
+-1.68707534013095152873222061722573172e-35L, /* bf8b66cd1e4e8ebc18dbb02d9857662c */
+/* sin(x) = 0.852010f4f0800521378bd8dd614753d080c2e9e0775ffc609947b9132f5357404f464f06a58 */
+ 5.20020541953727004760213699874674730e-01L, /* 3ffe0a4021e9e1000a426f17b1bac28f */
+-3.32415021330884924833711842866896734e-35L, /* bf8c617bf9e8b0fc45001cfb35c23767 */
+
+/* x = 5.54687500000000000000000000000000000e-01 3ffe1c00000000000000000000000000 */
+/* cos(x) = 0.d99ddd44e44a43d4d4a3a3ed95204106fd54d78e8c7684545c0da0b7c2c72be7a89b7c182ad */
+ 8.50065068549420263957072899177793617e-01L, /* 3ffeb33bba89c89487a9a94747db2a41 */
+-4.73753917078785974356016104842568442e-35L, /* bf8cf7c81559438b9c4bdd5d1f92fa42 */
+/* sin(x) = 0.86d45935ab396cb4e421e822dee54f3562dfcefeaa782184c23401d231f5ad981a1cc195b18 */
+ 5.26677680590386730710789410624833901e-01L, /* 3ffe0da8b26b5672d969c843d045bdcb */
+-3.67066148195515214077582496518566735e-35L, /* bf8c8654e901880aac3ef3d9ee5ff16e */
+
+/* x = 5.62500000000000000000000000000000000e-01 3ffe2000000000000000000000000000 */
+/* cos(x) = 0.d88e820b1526311dd561efbc0c1a9a5375eb26f65d246c5744b13ca26a7e0fd42556da843c8 */
+ 8.45924499231067954459723078597493262e-01L, /* 3ffeb11d04162a4c623baac3df781835 */
+ 1.98054947141989878179164342925274053e-35L, /* 3f8ba5375eb26f65d246c5744b13ca27 */
+/* sin(x) = 0.88868625b4e1dbb2313310133022527200c143a5cb16637cb7daf8ade82459ff2e98511f40f */
+ 5.33302673536020173329131103308161529e-01L, /* 3ffe110d0c4b69c3b764626620266045 */
+-3.42715291319551615996993795226755157e-35L, /* bf8c6c6ff9f5e2d1a74ce41a41283a91 */
+
+/* x = 5.70312500000000000000000000000000000e-01 3ffe2400000000000000000000000000 */
+/* cos(x) = 0.d77bc4985e93a607c9d868b906bbc6bbe3a04258814acb0358468b826fc91bd4d814827f65e */
+ 8.41732299041338366963111794309701085e-01L, /* 3ffeaef78930bd274c0f93b0d1720d78 */
+-4.30821936750410026005408345400225948e-35L, /* bf8cca20e2fded3bf5a9a7e53dcba3ed */
+/* sin(x) = 0.8a3690fc5bfc11bf9535e2739a8512f448a41251514bbed7fc18d530f9b4650fcbb2861b0aa */
+ 5.39895116435204405041660709903993340e-01L, /* 3ffe146d21f8b7f8237f2a6bc4e7350a */
+ 1.42595803521626714477253741404712093e-35L, /* 3f8b2f448a41251514bbed7fc18d5310 */
+
+/* x = 5.78125000000000000000000000000000000e-01 3ffe2800000000000000000000000000 */
+/* cos(x) = 0.d665a937b4ef2b1f6d51bad6d988a4419c1d7051faf31a9efa151d7631117efac03713f950a */
+ 8.37488723850523685315353348917240617e-01L, /* 3ffeaccb526f69de563edaa375adb311 */
+ 2.72761997872084533045777718677326179e-35L, /* 3f8c220ce0eb828fd798d4f7d0a8ebb2 */
+/* sin(x) = 0.8be472f9776d809af2b88171243d63d66dfceeeb739cc894e023fbc165a0e3f26ff729c5d57 */
+ 5.46454606919203564403349553749411001e-01L, /* 3ffe17c8e5f2eedb0135e57102e2487b */
+-2.11870230730160315420936523771864858e-35L, /* bf8bc29920311148c63376b1fdc043ea */
+
+/* x = 5.85937500000000000000000000000000000e-01 3ffe2c00000000000000000000000000 */
+/* cos(x) = 0.d54c3441844897fc8f853f0655f1ba695eba9fbfd7439dbb1171d862d9d9146ca5136f825ac */
+ 8.33194032664581363070224042208032321e-01L, /* 3ffeaa98688308912ff91f0a7e0cabe3 */
+ 4.39440050052045486567668031751259899e-35L, /* 3f8cd34af5d4fdfeba1cedd88b8ec317 */
+/* sin(x) = 0.8d902565817ee7839bce3cd128060119492cd36d42d82ada30d7f8bde91324808377ddbf5d4 */
+ 5.52980744630527369849695082681623667e-01L, /* 3ffe1b204acb02fdcf07379c79a2500c */
+ 8.26624790417342895897164123189984127e-37L, /* 3f8719492cd36d42d82ada30d7f8bde9 */
+
+/* x = 5.93750000000000000000000000000000000e-01 3ffe3000000000000000000000000000 */
+/* cos(x) = 0.d42f6a1b9f0168cdf031c2f63c8d9304d86f8d34cb1d5fccb68ca0f2241427fc18d1fd5bbdf */
+ 8.28848487609325734810171790119116638e-01L, /* 3ffea85ed4373e02d19be06385ec791b */
+ 1.43082508100496581719048175506239770e-35L, /* 3f8b304d86f8d34cb1d5fccb68ca0f22 */
+/* sin(x) = 0.8f39a191b2ba6122a3fa4f41d5a3ffd421417d46f19a22230a14f7fcc8fce5c75b4b28b29d1 */
+ 5.59473131247366877384844006003116688e-01L, /* 3ffe1e7343236574c24547f49e83ab48 */
+-1.28922620524163922306886952100992796e-37L, /* bf845ef5f415c8732eeee7af584019b8 */
+
+/* x = 6.01562500000000000000000000000000000e-01 3ffe3400000000000000000000000000 */
+/* cos(x) = 0.d30f4f392c357ab0661c5fa8a7d9b26627846fef214b1d19a22379ff9eddba087cf410eb097 */
+ 8.24452353914429207485643598212356053e-01L, /* 3ffea61e9e72586af560cc38bf514fb3 */
+ 3.79160239225080026987031418939026741e-35L, /* 3f8c93313c237f790a58e8cd111bcffd */
+/* sin(x) = 0.90e0e0d81ca678796cc92c8ea8c2815bc72ca78abe571bfa8576aacc571e096a33237e0e830 */
+ 5.65931370507905990773159095689276114e-01L, /* 3ffe21c1c1b0394cf0f2d992591d5185 */
+ 1.02202775968053982310991962521535027e-36L, /* 3f875bc72ca78abe571bfa8576aacc57 */
+
+/* x = 6.09375000000000000000000000000000000e-01 3ffe3800000000000000000000000000 */
+/* cos(x) = 0.d1ebe81a95ee752e48a26bcd32d6e922d7eb44b8ad2232f6930795e84b56317269b9dd1dfa6 */
+ 8.20005899897234008255550633876556043e-01L, /* 3ffea3d7d0352bdcea5c9144d79a65ae */
+-1.72008811955230823416724332297991247e-35L, /* bf8b6dd2814bb4752ddcd096cf86a17b */
+/* sin(x) = 0.9285dc9bc45dd9ea3d02457bcce59c4175aab6ff7929a8d287195525fdace200dba032874fb */
+ 5.72355068234507240384953706824503608e-01L, /* 3ffe250bb93788bbb3d47a048af799cb */
+ 2.12572273479933123944580199464514529e-35L, /* 3f8bc4175aab6ff7929a8d2871955260 */
+
+/* x = 6.17187500000000000000000000000000000e-01 3ffe3c00000000000000000000000000 */
+/* cos(x) = 0.d0c5394d772228195e25736c03574707de0af1ca344b13bd3914bfe27518e9e426f5deff1e1 */
+ 8.15509396946375476876345384201386217e-01L, /* 3ffea18a729aee445032bc4ae6d806af */
+-4.28589138410712954051679139949341961e-35L, /* bf8cc7c10fa871ae5da76216375a00ec */
+/* sin(x) = 0.94288e48bd0335fc41c4cbd2920497a8f5d1d8185c99fa0081f90c27e2a53ffdd208a0dbe69 */
+ 5.78743832357770354521111378581385347e-01L, /* 3ffe28511c917a066bf8838997a52409 */
+ 1.77998063432551282609698670002456093e-35L, /* 3f8b7a8f5d1d8185c99fa0081f90c27e */
+
+/* x = 6.25000000000000000000000000000000000e-01 3ffe4000000000000000000000000000 */
+/* cos(x) = 0.cf9b476c897c25c5bfe750dd3f308eaf7bcc1ed00179a256870f4200445043dcdb1974b5878 */
+ 8.10963119505217902189534803941080724e-01L, /* 3ffe9f368ed912f84b8b7fcea1ba7e61 */
+ 1.10481292856794436426051402418804358e-35L, /* 3f8ad5ef7983da002f344ad0e1e84009 */
+/* sin(x) = 0.95c8ef544210ec0b91c49bd2aa09e8515fa61a156ebb10f5f8c232a6445b61ebf3c2ec268f9 */
+ 5.85097272940462154805399314150080459e-01L, /* 3ffe2b91dea88421d817238937a55414 */
+-1.78164576278056195136525335403380464e-35L, /* bf8b7aea059e5ea9144ef0a073dcd59c */
+
+/* x = 6.32812500000000000000000000000000000e-01 3ffe4400000000000000000000000000 */
+/* cos(x) = 0.ce6e171f92f2e27f32225327ec440ddaefae248413efc0e58ceee1ae369aabe73f88c87ed1a */
+ 8.06367345055103913698795406077297399e-01L, /* 3ffe9cdc2e3f25e5c4fe6444a64fd888 */
+ 1.04235088143133625463876245029180850e-35L, /* 3f8abb5df5c490827df81cb19ddc35c7 */
+/* sin(x) = 0.9766f93cd18413a6aafc1cfc6fc28abb6817bf94ce349901ae3f48c3215d3eb60acc5f78903 */
+ 5.91415002201316315087000225758031236e-01L, /* 3ffe2ecdf279a308274d55f839f8df85 */
+ 8.07390238063560077355762466502569603e-36L, /* 3f8a576d02f7f299c6932035c7e91864 */
+
+/* x = 6.40625000000000000000000000000000000e-01 3ffe4800000000000000000000000000 */
+/* cos(x) = 0.cd3dad1b5328a2e459f993f4f5108819faccbc4eeba9604e81c7adad51cc8a2561631a06826 */
+ 8.01722354098418450607492605652964208e-01L, /* 3ffe9a7b5a36a65145c8b3f327e9ea21 */
+ 6.09487851305233089325627939458963741e-36L, /* 3f8a033f599789dd752c09d038f5b5aa */
+/* sin(x) = 0.9902a58a45e27bed68412b426b675ed503f54d14c8172e0d373f42cadf04daf67319a7f94be */
+ 5.97696634538701531238647618967334337e-01L, /* 3ffe32054b148bc4f7dad0825684d6cf */
+-2.49527608940873714527427941350461554e-35L, /* bf8c0957e0559759bf468f964605e9a9 */
+
+/* x = 6.48437500000000000000000000000000000e-01 3ffe4c00000000000000000000000000 */
+/* cos(x) = 0.cc0a0e21709883a3ff00911e11a07ee3bd7ea2b04e081be99be0264791170761ae64b8b744a */
+ 7.97028430141468342004642741431945296e-01L, /* 3ffe98141c42e1310747fe01223c2341 */
+-8.35364432831812599727083251866305534e-37L, /* bf871c42815d4fb1f7e416641fd9b86f */
+/* sin(x) = 0.9a9bedcdf01b38d993f3d7820781de292033ead73b89e28f39313dbe3a6e463f845b5fa8490 */
+ 6.03941786554156657267270287527367726e-01L, /* 3ffe3537db9be03671b327e7af040f04 */
+-2.54578992328947177770363936132309779e-35L, /* bf8c0eb6fe60a94623b0eb863676120e */
+
+/* x = 6.56250000000000000000000000000000000e-01 3ffe5000000000000000000000000000 */
+/* cos(x) = 0.cad33f00658fe5e8204bbc0f3a66a0e6a773f87987a780b243d7be83b3db1448ca0e0e62787 */
+ 7.92285859677178543141501323781709399e-01L, /* 3ffe95a67e00cb1fcbd04097781e74cd */
+ 2.47519558228473167879248891673807645e-35L, /* 3f8c07353b9fc3cc3d3c05921ebdf41e */
+/* sin(x) = 0.9c32cba2b14156ef05256c4f857991ca6a547cd7ceb1ac8a8e62a282bd7b9183648a462bd04 */
+ 6.10150077075791371273742393566183220e-01L, /* 3ffe386597456282adde0a4ad89f0af3 */
+ 1.33842237929938963780969418369150532e-35L, /* 3f8b1ca6a547cd7ceb1ac8a8e62a282c */
+
+/* x = 6.64062500000000000000000000000000000e-01 3ffe5400000000000000000000000000 */
+/* cos(x) = 0.c99944936cf48c8911ff93fe64b3ddb7981e414bdaf6aae1203577de44878c62bc3bc9cf7b9 */
+ 7.87494932167606083931328295965533034e-01L, /* 3ffe93328926d9e9191223ff27fcc968 */
+-2.57915385618070637156514241185180920e-35L, /* bf8c12433f0df5a1284aa8f6fe54410e */
+/* sin(x) = 0.9dc738ad14204e689ac582d0f85826590feece34886cfefe2e08cf2bb8488d55424dc9d3525 */
+ 6.16321127181550943005700433761731837e-01L, /* 3ffe3b8e715a28409cd1358b05a1f0b0 */
+ 2.88497530050197716298085892460478666e-35L, /* 3f8c32c87f7671a44367f7f17046795e */
+
+/* x = 6.71875000000000000000000000000000000e-01 3ffe5800000000000000000000000000 */
+/* cos(x) = 0.c85c23c26ed7b6f014ef546c47929682122876bfbf157de0aff3c4247d820c746e32cd4174f */
+ 7.82655940026272796930787447428139026e-01L, /* 3ffe90b84784ddaf6de029dea8d88f25 */
+ 1.69332045679237919427807771288506254e-35L, /* 3f8b682122876bfbf157de0aff3c4248 */
+/* sin(x) = 0.9f592e9b66a9cf906a3c7aa3c10199849040c45ec3f0a747597311038101780c5f266059dbf */
+ 6.22454560222343683041926705090443330e-01L, /* 3ffe3eb25d36cd539f20d478f5478203 */
+ 1.91974786921147072717621236192269859e-35L, /* 3f8b9849040c45ec3f0a747597311038 */
+
+/* x = 6.79687500000000000000000000000000000e-01 3ffe5c00000000000000000000000000 */
+/* cos(x) = 0.c71be181ecd6875ce2da5615a03cca207d9adcb9dfb0a1d6c40a4f0056437f1a59ccddd06ee */
+ 7.77769178600317903122203513685412863e-01L, /* 3ffe8e37c303d9ad0eb9c5b4ac2b407a */
+-4.05296033424632846931240580239929672e-35L, /* bf8caefc13291a31027af149dfad87fd */
+/* sin(x) = 0.a0e8a725d33c828c11fa50fd9e9a15ffecfad43f3e534358076b9b0f6865694842b1e8c67dc */
+ 6.28550001845029662028004327939032867e-01L, /* 3ffe41d14e4ba679051823f4a1fb3d34 */
+ 1.65507421184028099672784511397428852e-35L, /* 3f8b5ffecfad43f3e534358076b9b0f7 */
+
+/* x = 6.87500000000000000000000000000000000e-01 3ffe6000000000000000000000000000 */
+/* cos(x) = 0.c5d882d2ee48030c7c07d28e981e34804f82ed4cf93655d2365389b716de6ad44676a1cc5da */
+ 7.72834946152471544810851845913425178e-01L, /* 3ffe8bb105a5dc900618f80fa51d303c */
+ 3.94975229341211664237241534741146939e-35L, /* 3f8ca4027c176a67c9b2ae91b29c4db9 */
+/* sin(x) = 0.a2759c0e79c35582527c32b55f5405c182c66160cb1d9eb7bb0b7cdf4ad66f317bda4332914 */
+ 6.34607080015269296850309914203671436e-01L, /* 3ffe44eb381cf386ab04a4f8656abea8 */
+ 4.33025916939968369326060156455927002e-36L, /* 3f897060b1985832c767adeec2df37d3 */
+
+/* x = 6.95312500000000000000000000000000000e-01 3ffe6400000000000000000000000000 */
+/* cos(x) = 0.c4920cc2ec38fb891b38827db08884fc66371ac4c2052ca8885b981bbcfd3bb7b093ee31515 */
+ 7.67853543842850365879920759114193964e-01L, /* 3ffe89241985d871f712367104fb6111 */
+ 3.75100035267325597157244776081706979e-36L, /* 3f893f198dc6b130814b2a2216e606ef */
+/* sin(x) = 0.a400072188acf49cd6b173825e038346f105e1301afe642bcc364cea455e21e506e3e927ed8 */
+ 6.40625425040230409188409779413961021e-01L, /* 3ffe48000e431159e939ad62e704bc07 */
+ 2.46542747294664049615806500747173281e-36L, /* 3f88a37882f0980d7f3215e61b267523 */
+
+/* x = 7.03125000000000000000000000000000000e-01 3ffe6800000000000000000000000000 */
+/* cos(x) = 0.c348846bbd3631338ffe2bfe9dd1381a35b4e9c0c51b4c13fe376bad1bf5caacc4542be0aa9 */
+ 7.62825275710576250507098753625429792e-01L, /* 3ffe869108d77a6c62671ffc57fd3ba2 */
+ 4.22067411888601505004748939382325080e-35L, /* 3f8cc0d1ada74e0628da609ff1bb5d69 */
+/* sin(x) = 0.a587e23555bb08086d02b9c662cdd29316c3e9bd08d93793634a21b1810cce73bdb97a99b9e */
+ 6.46604669591152370524042159882800763e-01L, /* 3ffe4b0fc46aab761010da05738cc59c */
+-3.41742981816219412415674365946079826e-35L, /* bf8c6b6749e0b217b9364364e5aef274 */
+
+/* x = 7.10937500000000000000000000000000000e-01 3ffe6c00000000000000000000000000 */
+/* cos(x) = 0.c1fbeef380e4ffdd5a613ec8722f643ffe814ec2343e53adb549627224fdc9f2a7b77d3d69f */
+ 7.57750448655219342240234832230493361e-01L, /* 3ffe83f7dde701c9ffbab4c27d90e45f */
+-2.08767968311222650582659938787920125e-35L, /* bf8bbc0017eb13dcbc1ac524ab69d8de */
+/* sin(x) = 0.a70d272a76a8d4b6da0ec90712bb748b96dabf88c3079246f3db7eea6e58ead4ed0e2843303 */
+ 6.52544448725765956407573982284767763e-01L, /* 3ffe4e1a4e54ed51a96db41d920e2577 */
+-8.61758060284379660697102362141557170e-36L, /* bf8a6e8d24a80ee79f0db721849022b2 */
+
+/* x = 7.18750000000000000000000000000000000e-01 3ffe7000000000000000000000000000 */
+/* cos(x) = 0.c0ac518c8b6ae710ba37a3eeb90cb15aebcb8bed4356fb507a48a6e97de9aa6d9660116b436 */
+ 7.52629372418066476054541324847143116e-01L, /* 3ffe8158a31916d5ce21746f47dd7219 */
+ 3.71306958657663189665450864311104571e-35L, /* 3f8c8ad75e5c5f6a1ab7da83d245374c */
+/* sin(x) = 0.a88fcfebd9a8dd47e2f3c76ef9e2439920f7e7fbe735f8bcc985491ec6f12a2d4214f8cfa99 */
+ 6.58444399910567541589583954884041989e-01L, /* 3ffe511f9fd7b351ba8fc5e78eddf3c5 */
+-4.54412944084300330523721391865787219e-35L, /* bf8ce336f840c020c6503a19b3d5b70a */
+
+/* x = 7.26562500000000000000000000000000000e-01 3ffe7400000000000000000000000000 */
+/* cos(x) = 0.bf59b17550a4406875969296567cf3e3b4e483061877c02811c6cae85fad5a6c3da58f49292 */
+ 7.47462359563216166669700384714767552e-01L, /* 3ffe7eb362eaa14880d0eb2d252cacfa */
+-9.11094340926220027288083639048016945e-36L, /* bf8a8389636f9f3cf107fafdc726a2f4 */
+/* sin(x) = 0.aa0fd66eddb921232c28520d3911b8a03193b47f187f1471ac216fbcd5bb81029294d3a73f1 */
+ 6.64304163042946276515506587432846246e-01L, /* 3ffe541facddbb7242465850a41a7223 */
+ 4.26004843895378210155889028714676019e-35L, /* 3f8cc5018c9da3f8c3f8a38d610b7de7 */
+
+/* x = 7.34375000000000000000000000000000000e-01 3ffe7800000000000000000000000000 */
+/* cos(x) = 0.be0413f84f2a771c614946a88cbf4da1d75a5560243de8f2283fefa0ea4a48468a52d51d8b3 */
+ 7.42249725458501306991347253449610537e-01L, /* 3ffe7c0827f09e54ee38c2928d51197f */
+-3.78925270049800913539923473871287550e-35L, /* bf8c92f1452d54fede10b86ebe0082f9 */
+/* sin(x) = 0.ab8d34b36acd987210ed343ec65d7e3adc2e7109fce43d55c8d57dfdf55b9e01d2cc1f1b9ec */
+ 6.70123380473162894654531583500648495e-01L, /* 3ffe571a6966d59b30e421da687d8cbb */
+-1.33165852952743729897634069393684656e-36L, /* bf87c523d18ef6031bc2aa372a82020b */
+
+/* x = 7.42187500000000000000000000000000000e-01 3ffe7c00000000000000000000000000 */
+/* cos(x) = 0.bcab7e6bfb2a14a9b122c574a376bec98ab14808c64a4e731b34047e217611013ac99c0f25d */
+ 7.36991788256240741057089385586450844e-01L, /* 3ffe7956fcd7f654295362458ae946ed */
+ 4.72358938637974850573747497460125519e-35L, /* 3f8cf64c558a404632527398d9a023f1 */
+/* sin(x) = 0.ad07e4c409d08c4fa3a9057bb0ac24b8636e74e76f51e09bd6b2319707cbd9f5e254643897a */
+ 6.75901697026178809189642203142423973e-01L, /* 3ffe5a0fc98813a1189f47520af76158 */
+ 2.76252586616364878801928456702948857e-35L, /* 3f8c25c31b73a73b7a8f04deb5918cb8 */
+
+/* x = 7.50000000000000000000000000000000000e-01 3ffe8000000000000000000000000000 */
+/* cos(x) = 0.bb4ff632a908f73ec151839cb9d993b4e0bfb8f20e7e44e6e4aee845e35575c3106dbe6fd06 */
+ 7.31688868873820886311838753000084529e-01L, /* 3ffe769fec655211ee7d82a3073973b3 */
+ 1.48255637548931697184991710293198620e-35L, /* 3f8b3b4e0bfb8f20e7e44e6e4aee845e */
+/* sin(x) = 0.ae7fe0b5fc786b2d966e1d6af140a488476747c2646425fc7533f532cd044cb10a971a49a6a */
+ 6.81638760023334166733241952779893908e-01L, /* 3ffe5cffc16bf8f0d65b2cdc3ad5e281 */
+ 2.74838775935027549024224114338667371e-35L, /* 3f8c24423b3a3e1323212fe3a99fa996 */
+
+/* x = 7.57812500000000000000000000000000000e-01 3ffe8400000000000000000000000000 */
+/* cos(x) = 0.b9f180ba77dd0751628e135a9508299012230f14becacdd14c3f8862d122de5b56d55b53360 */
+ 7.26341290974108590410147630237598973e-01L, /* 3ffe73e30174efba0ea2c51c26b52a10 */
+ 3.12683579338351123545814364980658990e-35L, /* 3f8c4c80911878a5f6566e8a61fc4317 */
+/* sin(x) = 0.aff522a954f2ba16d9defdc416e33f5e9a5dfd5a6c228e0abc4d521327ff6e2517a7b3851dd */
+ 6.87334219303873534951703613035647220e-01L, /* 3ffe5fea4552a9e5742db3bdfb882dc6 */
+ 4.76739454455410744997012795035529128e-35L, /* 3f8cfaf4d2efead361147055e26a9099 */
+
+/* x = 7.65625000000000000000000000000000000e-01 3ffe8800000000000000000000000000 */
+/* cos(x) = 0.b890237d3bb3c284b614a0539016bfa1053730bbdf940fa895e185f8e58884d3dda15e63371 */
+ 7.20949380945696418043812784148447688e-01L, /* 3ffe712046fa776785096c2940a7202d */
+ 4.78691285733673379499536326050811832e-35L, /* 3f8cfd0829b985defca07d44af0c2fc7 */
+/* sin(x) = 0.b167a4c90d63c4244cf5493b7cc23bd3c3c1225e078baa0c53d6d400b926281f537a1a260e6 */
+ 6.92987727246317910281815490823048210e-01L, /* 3ffe62cf49921ac7884899ea9276f984 */
+ 4.50089871077663557180849219529189918e-35L, /* 3f8cde9e1e0912f03c5d50629eb6a006 */
+
+/* x = 7.73437500000000000000000000000000000e-01 3ffe8c00000000000000000000000000 */
+/* cos(x) = 0.b72be40067aaf2c050dbdb7a14c3d7d4f203f6b3f0224a4afe55d6ec8e92b508fd5c5984b3b */
+ 7.15513467882981573520620561289896903e-01L, /* 3ffe6e57c800cf55e580a1b7b6f42988 */
+-3.02191815581445336509438104625489192e-35L, /* bf8c41586fe04a607eedada80d51489c */
+/* sin(x) = 0.b2d7614b1f3aaa24df2d6e20a77e1ca3e6d838c03e29c1bcb026e6733324815fadc9eb89674 */
+ 6.98598938789681741301929277107891591e-01L, /* 3ffe65aec2963e755449be5adc414efc */
+ 2.15465226809256290914423429408722521e-35L, /* 3f8bca3e6d838c03e29c1bcb026e6733 */
+
+/* x = 7.81250000000000000000000000000000000e-01 3ffe9000000000000000000000000000 */
+/* cos(x) = 0.b5c4c7d4f7dae915ac786ccf4b1a498d3e73b6e5e74fe7519d9c53ee6d6b90e881bddfc33e1 */
+ 7.10033883566079674974121643959490219e-01L, /* 3ffe6b898fa9efb5d22b58f0d99e9635 */
+-4.09623224763692443220896752907902465e-35L, /* bf8cb3960c6248d0c580c573131d608d */
+/* sin(x) = 0.b44452709a59752905913765434a59d111f0433eb2b133f7d103207e2aeb4aae111ddc385b3 */
+ 7.04167511454533672780059509973942844e-01L, /* 3ffe6888a4e134b2ea520b226eca8695 */
+-2.87259372740393348676633610275598640e-35L, /* bf8c3177707de60a6a76604177e6fc0f */
+
+/* x = 7.89062500000000000000000000000000000e-01 3ffe9400000000000000000000000000 */
+/* cos(x) = 0.b45ad4975b1294cadca4cf40ec8f22a68cd14b175835239a37e63acb85e8e9505215df18140 */
+ 7.04510962440574606164129481545916976e-01L, /* 3ffe68b5a92eb6252995b9499e81d91e */
+ 2.60682037357042658395360726992048803e-35L, /* 3f8c1534668a58bac1a91cd1bf31d65c */
+/* sin(x) = 0.b5ae7285bc10cf515753847e8f8b7a30e0a580d929d770103509880680f7b8b0e8ad23b65d8 */
+ 7.09693105363899724959669028139035515e-01L, /* 3ffe6b5ce50b78219ea2aea708fd1f17 */
+-4.37026016974122945368562319136420097e-36L, /* bf8973c7d69fc9b58a23fbf2bd9dfe60 */
+};
diff --git a/libc/sysdeps/ieee754/ldbl-128/w_expl.c b/libc/sysdeps/ieee754/ldbl-128/w_expl.c
new file mode 100644
index 000000000..816ce3caa
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128/w_expl.c
@@ -0,0 +1,58 @@
+/* w_expl.c -- long double version of w_exp.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * wrapper expl(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+o_threshold= 1.1356523406294143949491931077970763428449E4L,
+u_threshold= -1.1433462743336297878837243843452621503410E4;
+
+#ifdef __STDC__
+ long double __expl(long double x) /* wrapper exp */
+#else
+ long double __expl(x) /* wrapper exp */
+ long double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_expl(x);
+#else
+ long double z;
+ z = __ieee754_expl(x);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if(__finitel(x)) {
+ if(x>o_threshold)
+ return __kernel_standard(x,x,206); /* exp overflow */
+ else if(x<u_threshold)
+ return __kernel_standard(x,x,207); /* exp underflow */
+ }
+ return z;
+#endif
+}
+weak_alias (__expl, expl)
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/Makefile b/libc/sysdeps/ieee754/ldbl-128ibm/Makefile
new file mode 100644
index 000000000..8e1e2e6ae
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/Makefile
@@ -0,0 +1,5 @@
+# The`long double' type is a distinct type we support if
+# -mlong-double-128 option is used (or when it becomes a default
+# when -mlong-double-64 is not used).
+long-double-fcts = yes
+sysdep-CFLAGS += -mlong-double-128
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c
new file mode 100644
index 000000000..00576c76c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c
@@ -0,0 +1,69 @@
+/* @(#)e_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: e_acosh.c,v 1.9 1995/05/12 04:57:18 jtc Exp $";
+#endif
+
+/* __ieee754_acosh(x)
+ * Method :
+ * Based on
+ * acosh(x) = log [ x + sqrt(x*x-1) ]
+ * we have
+ * acosh(x) := log(x)+ln2, if x is large; else
+ * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
+ * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
+ *
+ * Special cases:
+ * acosh(x) is NaN with signal if x<1.
+ * acosh(NaN) is NaN without signal.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+one = 1.0L,
+ln2 = 6.93147180559945286227e-01L; /* 0x3FE62E42, 0xFEFA39EF */
+
+#ifdef __STDC__
+ long double __ieee754_acoshl(long double x)
+#else
+ long double __ieee754_acoshl(x)
+ long double x;
+#endif
+{
+ long double t;
+ int64_t hx;
+ u_int64_t lx;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ if(hx<0x3ff0000000000000LL) { /* x < 1 */
+ return (x-x)/(x-x);
+ } else if(hx >=0x41b0000000000000LL) { /* x > 2**28 */
+ if(hx >=0x7ff0000000000000LL) { /* x is inf of NaN */
+ return x+x;
+ } else
+ return __ieee754_logl(x)+ln2; /* acosh(huge)=log(2x) */
+ } else if (((hx-0x3ff0000000000000LL)|(lx&0x7fffffffffffffffLL))==0) {
+ return 0.0; /* acosh(1) = 0 */
+ } else if (hx > 0x4000000000000000LL) { /* 2**28 > x > 2 */
+ t=x*x;
+ return __ieee754_logl(2.0*x-one/(x+__ieee754_sqrtl(t-one)));
+ } else { /* 1<x<2 */
+ t = x-one;
+ return __log1p(t+__sqrtl(2.0*t+t*t));
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_acosl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_acosl.c
new file mode 100644
index 000000000..8823fd69b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_acosl.c
@@ -0,0 +1,328 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/*
+ Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __ieee754_acosl(x)
+ * Method :
+ * acos(x) = pi/2 - asin(x)
+ * acos(-x) = pi/2 + asin(x)
+ * For |x| <= 0.375
+ * acos(x) = pi/2 - asin(x)
+ * Between .375 and .5 the approximation is
+ * acos(0.4375 + x) = acos(0.4375) + x P(x) / Q(x)
+ * Between .5 and .625 the approximation is
+ * acos(0.5625 + x) = acos(0.5625) + x rS(x) / sS(x)
+ * For x > 0.625,
+ * acos(x) = 2 asin(sqrt((1-x)/2))
+ * computed with an extended precision square root in the leading term.
+ * For x < -0.625
+ * acos(x) = pi - 2 asin(sqrt((1-|x|)/2))
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ * Functions needed: __ieee754_sqrtl.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ one = 1.0L,
+ pio2_hi = 1.5707963267948966192313216916397514420986L,
+ pio2_lo = 4.3359050650618905123985220130216759843812E-35L,
+
+ /* acos(0.5625 + x) = acos(0.5625) + x rS(x) / sS(x)
+ -0.0625 <= x <= 0.0625
+ peak relative error 3.3e-35 */
+
+ rS0 = 5.619049346208901520945464704848780243887E0L,
+ rS1 = -4.460504162777731472539175700169871920352E1L,
+ rS2 = 1.317669505315409261479577040530751477488E2L,
+ rS3 = -1.626532582423661989632442410808596009227E2L,
+ rS4 = 3.144806644195158614904369445440583873264E1L,
+ rS5 = 9.806674443470740708765165604769099559553E1L,
+ rS6 = -5.708468492052010816555762842394927806920E1L,
+ rS7 = -1.396540499232262112248553357962639431922E1L,
+ rS8 = 1.126243289311910363001762058295832610344E1L,
+ rS9 = 4.956179821329901954211277873774472383512E-1L,
+ rS10 = -3.313227657082367169241333738391762525780E-1L,
+
+ sS0 = -4.645814742084009935700221277307007679325E0L,
+ sS1 = 3.879074822457694323970438316317961918430E1L,
+ sS2 = -1.221986588013474694623973554726201001066E2L,
+ sS3 = 1.658821150347718105012079876756201905822E2L,
+ sS4 = -4.804379630977558197953176474426239748977E1L,
+ sS5 = -1.004296417397316948114344573811562952793E2L,
+ sS6 = 7.530281592861320234941101403870010111138E1L,
+ sS7 = 1.270735595411673647119592092304357226607E1L,
+ sS8 = -1.815144839646376500705105967064792930282E1L,
+ sS9 = -7.821597334910963922204235247786840828217E-2L,
+ /* 1.000000000000000000000000000000000000000E0 */
+
+ acosr5625 = 9.7338991014954640492751132535550279812151E-1L,
+ pimacosr5625 = 2.1682027434402468335351320579240000860757E0L,
+
+ /* acos(0.4375 + x) = acos(0.4375) + x rS(x) / sS(x)
+ -0.0625 <= x <= 0.0625
+ peak relative error 2.1e-35 */
+
+ P0 = 2.177690192235413635229046633751390484892E0L,
+ P1 = -2.848698225706605746657192566166142909573E1L,
+ P2 = 1.040076477655245590871244795403659880304E2L,
+ P3 = -1.400087608918906358323551402881238180553E2L,
+ P4 = 2.221047917671449176051896400503615543757E1L,
+ P5 = 9.643714856395587663736110523917499638702E1L,
+ P6 = -5.158406639829833829027457284942389079196E1L,
+ P7 = -1.578651828337585944715290382181219741813E1L,
+ P8 = 1.093632715903802870546857764647931045906E1L,
+ P9 = 5.448925479898460003048760932274085300103E-1L,
+ P10 = -3.315886001095605268470690485170092986337E-1L,
+ Q0 = -1.958219113487162405143608843774587557016E0L,
+ Q1 = 2.614577866876185080678907676023269360520E1L,
+ Q2 = -9.990858606464150981009763389881793660938E1L,
+ Q3 = 1.443958741356995763628660823395334281596E2L,
+ Q4 = -3.206441012484232867657763518369723873129E1L,
+ Q5 = -1.048560885341833443564920145642588991492E2L,
+ Q6 = 6.745883931909770880159915641984874746358E1L,
+ Q7 = 1.806809656342804436118449982647641392951E1L,
+ Q8 = -1.770150690652438294290020775359580915464E1L,
+ Q9 = -5.659156469628629327045433069052560211164E-1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+
+ acosr4375 = 1.1179797320499710475919903296900511518755E0L,
+ pimacosr4375 = 2.0236129215398221908706530535894517323217E0L,
+
+ /* asin(x) = x + x^3 pS(x^2) / qS(x^2)
+ 0 <= x <= 0.5
+ peak relative error 1.9e-35 */
+ pS0 = -8.358099012470680544198472400254596543711E2L,
+ pS1 = 3.674973957689619490312782828051860366493E3L,
+ pS2 = -6.730729094812979665807581609853656623219E3L,
+ pS3 = 6.643843795209060298375552684423454077633E3L,
+ pS4 = -3.817341990928606692235481812252049415993E3L,
+ pS5 = 1.284635388402653715636722822195716476156E3L,
+ pS6 = -2.410736125231549204856567737329112037867E2L,
+ pS7 = 2.219191969382402856557594215833622156220E1L,
+ pS8 = -7.249056260830627156600112195061001036533E-1L,
+ pS9 = 1.055923570937755300061509030361395604448E-3L,
+
+ qS0 = -5.014859407482408326519083440151745519205E3L,
+ qS1 = 2.430653047950480068881028451580393430537E4L,
+ qS2 = -4.997904737193653607449250593976069726962E4L,
+ qS3 = 5.675712336110456923807959930107347511086E4L,
+ qS4 = -3.881523118339661268482937768522572588022E4L,
+ qS5 = 1.634202194895541569749717032234510811216E4L,
+ qS6 = -4.151452662440709301601820849901296953752E3L,
+ qS7 = 5.956050864057192019085175976175695342168E2L,
+ qS8 = -4.175375777334867025769346564600396877176E1L;
+ /* 1.000000000000000000000000000000000000000E0 */
+
+#ifdef __STDC__
+long double
+__ieee754_acosl (long double x)
+#else
+long double
+__ieee754_acosl (x)
+ long double x;
+#endif
+{
+ long double z, r, w, p, q, s, t, f2;
+ int32_t ix, sign;
+ ieee854_long_double_shape_type u;
+
+ u.value = x;
+ sign = u.parts32.w0;
+ ix = sign & 0x7fffffff;
+ u.parts32.w0 = ix; /* |x| */
+ if (ix >= 0x3ff00000) /* |x| >= 1 */
+ {
+ if (ix == 0x3ff00000
+ && (u.parts32.w1 | (u.parts32.w2&0x7fffffff) | u.parts32.w3) == 0)
+ { /* |x| == 1 */
+ if ((sign & 0x80000000) == 0)
+ return 0.0; /* acos(1) = 0 */
+ else
+ return (2.0 * pio2_hi) + (2.0 * pio2_lo); /* acos(-1)= pi */
+ }
+ return (x - x) / (x - x); /* acos(|x| > 1) is NaN */
+ }
+ else if (ix < 0x3fe00000) /* |x| < 0.5 */
+ {
+ if (ix < 0x3c600000) /* |x| < 2**-57 */
+ return pio2_hi + pio2_lo;
+ if (ix < 0x3fde0000) /* |x| < .4375 */
+ {
+ /* Arcsine of x. */
+ z = x * x;
+ p = (((((((((pS9 * z
+ + pS8) * z
+ + pS7) * z
+ + pS6) * z
+ + pS5) * z
+ + pS4) * z
+ + pS3) * z
+ + pS2) * z
+ + pS1) * z
+ + pS0) * z;
+ q = (((((((( z
+ + qS8) * z
+ + qS7) * z
+ + qS6) * z
+ + qS5) * z
+ + qS4) * z
+ + qS3) * z
+ + qS2) * z
+ + qS1) * z
+ + qS0;
+ r = x + x * p / q;
+ z = pio2_hi - (r - pio2_lo);
+ return z;
+ }
+ /* .4375 <= |x| < .5 */
+ t = u.value - 0.4375L;
+ p = ((((((((((P10 * t
+ + P9) * t
+ + P8) * t
+ + P7) * t
+ + P6) * t
+ + P5) * t
+ + P4) * t
+ + P3) * t
+ + P2) * t
+ + P1) * t
+ + P0) * t;
+
+ q = (((((((((t
+ + Q9) * t
+ + Q8) * t
+ + Q7) * t
+ + Q6) * t
+ + Q5) * t
+ + Q4) * t
+ + Q3) * t
+ + Q2) * t
+ + Q1) * t
+ + Q0;
+ r = p / q;
+ if (sign & 0x80000000)
+ r = pimacosr4375 - r;
+ else
+ r = acosr4375 + r;
+ return r;
+ }
+ else if (ix < 0x3fe40000) /* |x| < 0.625 */
+ {
+ t = u.value - 0.5625L;
+ p = ((((((((((rS10 * t
+ + rS9) * t
+ + rS8) * t
+ + rS7) * t
+ + rS6) * t
+ + rS5) * t
+ + rS4) * t
+ + rS3) * t
+ + rS2) * t
+ + rS1) * t
+ + rS0) * t;
+
+ q = (((((((((t
+ + sS9) * t
+ + sS8) * t
+ + sS7) * t
+ + sS6) * t
+ + sS5) * t
+ + sS4) * t
+ + sS3) * t
+ + sS2) * t
+ + sS1) * t
+ + sS0;
+ if (sign & 0x80000000)
+ r = pimacosr5625 - p / q;
+ else
+ r = acosr5625 + p / q;
+ return r;
+ }
+ else
+ { /* |x| >= .625 */
+ z = (one - u.value) * 0.5;
+ s = __ieee754_sqrtl (z);
+ /* Compute an extended precision square root from
+ the Newton iteration s -> 0.5 * (s + z / s).
+ The change w from s to the improved value is
+ w = 0.5 * (s + z / s) - s = (s^2 + z)/2s - s = (z - s^2)/2s.
+ Express s = f1 + f2 where f1 * f1 is exactly representable.
+ w = (z - s^2)/2s = (z - f1^2 - 2 f1 f2 - f2^2)/2s .
+ s + w has extended precision. */
+ u.value = s;
+ u.parts32.w2 = 0;
+ u.parts32.w3 = 0;
+ f2 = s - u.value;
+ w = z - u.value * u.value;
+ w = w - 2.0 * u.value * f2;
+ w = w - f2 * f2;
+ w = w / (2.0 * s);
+ /* Arcsine of s. */
+ p = (((((((((pS9 * z
+ + pS8) * z
+ + pS7) * z
+ + pS6) * z
+ + pS5) * z
+ + pS4) * z
+ + pS3) * z
+ + pS2) * z
+ + pS1) * z
+ + pS0) * z;
+ q = (((((((( z
+ + qS8) * z
+ + qS7) * z
+ + qS6) * z
+ + qS5) * z
+ + qS4) * z
+ + qS3) * z
+ + qS2) * z
+ + qS1) * z
+ + qS0;
+ r = s + (w + s * p / q);
+
+ if (sign & 0x80000000)
+ w = pio2_hi + (pio2_lo - r);
+ else
+ w = r;
+ return 2.0 * w;
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_asinl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_asinl.c
new file mode 100644
index 000000000..3696694f7
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_asinl.c
@@ -0,0 +1,265 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/*
+ Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under the
+ following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __ieee754_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
+ * asin(x) = x + x*x^2*R(x^2)
+ * Between .5 and .625 the approximation is
+ * asin(0.5625 + x) = asin(0.5625) + x rS(x) / sS(x)
+ * For x in [0.625,1]
+ * asin(x) = pi/2-2*asin(sqrt((1-x)/2))
+ * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
+ * then for x>0.98
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
+ * For x<=0.98, let pio4_hi = pio2_hi/2, then
+ * f = hi part of s;
+ * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
+ * and
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
+ * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ */
+
+
+#include "math.h"
+#include "math_private.h"
+long double sqrtl (long double);
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ one = 1.0L,
+ huge = 1.0e+300L,
+ pio2_hi = 1.5707963267948966192313216916397514420986L,
+ pio2_lo = 4.3359050650618905123985220130216759843812E-35L,
+ pio4_hi = 7.8539816339744830961566084581987569936977E-1L,
+
+ /* coefficient for R(x^2) */
+
+ /* asin(x) = x + x^3 pS(x^2) / qS(x^2)
+ 0 <= x <= 0.5
+ peak relative error 1.9e-35 */
+ pS0 = -8.358099012470680544198472400254596543711E2L,
+ pS1 = 3.674973957689619490312782828051860366493E3L,
+ pS2 = -6.730729094812979665807581609853656623219E3L,
+ pS3 = 6.643843795209060298375552684423454077633E3L,
+ pS4 = -3.817341990928606692235481812252049415993E3L,
+ pS5 = 1.284635388402653715636722822195716476156E3L,
+ pS6 = -2.410736125231549204856567737329112037867E2L,
+ pS7 = 2.219191969382402856557594215833622156220E1L,
+ pS8 = -7.249056260830627156600112195061001036533E-1L,
+ pS9 = 1.055923570937755300061509030361395604448E-3L,
+
+ qS0 = -5.014859407482408326519083440151745519205E3L,
+ qS1 = 2.430653047950480068881028451580393430537E4L,
+ qS2 = -4.997904737193653607449250593976069726962E4L,
+ qS3 = 5.675712336110456923807959930107347511086E4L,
+ qS4 = -3.881523118339661268482937768522572588022E4L,
+ qS5 = 1.634202194895541569749717032234510811216E4L,
+ qS6 = -4.151452662440709301601820849901296953752E3L,
+ qS7 = 5.956050864057192019085175976175695342168E2L,
+ qS8 = -4.175375777334867025769346564600396877176E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+
+ /* asin(0.5625 + x) = asin(0.5625) + x rS(x) / sS(x)
+ -0.0625 <= x <= 0.0625
+ peak relative error 3.3e-35 */
+ rS0 = -5.619049346208901520945464704848780243887E0L,
+ rS1 = 4.460504162777731472539175700169871920352E1L,
+ rS2 = -1.317669505315409261479577040530751477488E2L,
+ rS3 = 1.626532582423661989632442410808596009227E2L,
+ rS4 = -3.144806644195158614904369445440583873264E1L,
+ rS5 = -9.806674443470740708765165604769099559553E1L,
+ rS6 = 5.708468492052010816555762842394927806920E1L,
+ rS7 = 1.396540499232262112248553357962639431922E1L,
+ rS8 = -1.126243289311910363001762058295832610344E1L,
+ rS9 = -4.956179821329901954211277873774472383512E-1L,
+ rS10 = 3.313227657082367169241333738391762525780E-1L,
+
+ sS0 = -4.645814742084009935700221277307007679325E0L,
+ sS1 = 3.879074822457694323970438316317961918430E1L,
+ sS2 = -1.221986588013474694623973554726201001066E2L,
+ sS3 = 1.658821150347718105012079876756201905822E2L,
+ sS4 = -4.804379630977558197953176474426239748977E1L,
+ sS5 = -1.004296417397316948114344573811562952793E2L,
+ sS6 = 7.530281592861320234941101403870010111138E1L,
+ sS7 = 1.270735595411673647119592092304357226607E1L,
+ sS8 = -1.815144839646376500705105967064792930282E1L,
+ sS9 = -7.821597334910963922204235247786840828217E-2L,
+ /* 1.000000000000000000000000000000000000000E0 */
+
+ asinr5625 = 5.9740641664535021430381036628424864397707E-1L;
+
+
+
+#ifdef __STDC__
+long double
+__ieee754_asinl (long double x)
+#else
+double
+__ieee754_asinl (x)
+ long double x;
+#endif
+{
+ long double t, w, p, q, c, r, s;
+ int32_t ix, sign, flag;
+ ieee854_long_double_shape_type u;
+
+ flag = 0;
+ u.value = x;
+ sign = u.parts32.w0;
+ ix = sign & 0x7fffffff;
+ u.parts32.w0 = ix; /* |x| */
+ if (ix >= 0x3ff00000) /* |x|>= 1 */
+ {
+ if (ix == 0x3ff00000
+ && (u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) == 0)
+ /* asin(1)=+-pi/2 with inexact */
+ return x * pio2_hi + x * pio2_lo;
+ return (x - x) / (x - x); /* asin(|x|>1) is NaN */
+ }
+ else if (ix < 0x3fe00000) /* |x| < 0.5 */
+ {
+ if (ix < 0x3c600000) /* |x| < 2**-57 */
+ {
+ if (huge + x > one)
+ return x; /* return x with inexact if x!=0 */
+ }
+ else
+ {
+ t = x * x;
+ /* Mark to use pS, qS later on. */
+ flag = 1;
+ }
+ }
+ else if (ix < 0x3fe40000) /* 0.625 */
+ {
+ t = u.value - 0.5625;
+ p = ((((((((((rS10 * t
+ + rS9) * t
+ + rS8) * t
+ + rS7) * t
+ + rS6) * t
+ + rS5) * t
+ + rS4) * t
+ + rS3) * t
+ + rS2) * t
+ + rS1) * t
+ + rS0) * t;
+
+ q = ((((((((( t
+ + sS9) * t
+ + sS8) * t
+ + sS7) * t
+ + sS6) * t
+ + sS5) * t
+ + sS4) * t
+ + sS3) * t
+ + sS2) * t
+ + sS1) * t
+ + sS0;
+ t = asinr5625 + p / q;
+ if ((sign & 0x80000000) == 0)
+ return t;
+ else
+ return -t;
+ }
+ else
+ {
+ /* 1 > |x| >= 0.625 */
+ w = one - u.value;
+ t = w * 0.5;
+ }
+
+ p = (((((((((pS9 * t
+ + pS8) * t
+ + pS7) * t
+ + pS6) * t
+ + pS5) * t
+ + pS4) * t
+ + pS3) * t
+ + pS2) * t
+ + pS1) * t
+ + pS0) * t;
+
+ q = (((((((( t
+ + qS8) * t
+ + qS7) * t
+ + qS6) * t
+ + qS5) * t
+ + qS4) * t
+ + qS3) * t
+ + qS2) * t
+ + qS1) * t
+ + qS0;
+
+ if (flag) /* 2^-57 < |x| < 0.5 */
+ {
+ w = p / q;
+ return x + x * w;
+ }
+
+ s = __ieee754_sqrtl (t);
+ if (ix >= 0x3fef3333) /* |x| > 0.975 */
+ {
+ w = p / q;
+ t = pio2_hi - (2.0 * (s + s * w) - pio2_lo);
+ }
+ else
+ {
+ u.value = s;
+ u.parts32.w3 = 0;
+ u.parts32.w2 = 0;
+ w = u.value;
+ c = (t - w * w) / (s + w);
+ r = p / q;
+ p = 2.0 * s * r - (pio2_lo - 2.0 * c);
+ q = pio4_hi - 2.0 * w;
+ t = pio4_hi - (p - q);
+ }
+
+ if ((sign & 0x80000000) == 0)
+ return t;
+ else
+ return -t;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c
new file mode 100644
index 000000000..a4bb53df0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c
@@ -0,0 +1,124 @@
+/* e_atan2l.c -- long double version of e_atan2.c.
+ * Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* __ieee754_atan2l(y,x)
+ * Method :
+ * 1. Reduce y to positive by atan2l(y,x)=-atan2l(-y,x).
+ * 2. Reduce x to positive by (if x and y are unexceptional):
+ * ARG (x+iy) = arctan(y/x) ... if x > 0,
+ * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
+ *
+ * Special cases:
+ *
+ * ATAN2((anything), NaN ) is NaN;
+ * ATAN2(NAN , (anything) ) is NaN;
+ * ATAN2(+-0, +(anything but NaN)) is +-0 ;
+ * ATAN2(+-0, -(anything but NaN)) is +-pi ;
+ * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
+ * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
+ * ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
+ * ATAN2(+-INF,+INF ) is +-pi/4 ;
+ * ATAN2(+-INF,-INF ) is +-3pi/4;
+ * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+tiny = 1.0e-300L,
+zero = 0.0,
+pi_o_4 = 7.85398163397448309615660845819875699e-01L, /* 3ffe921fb54442d18469898cc51701b8 */
+pi_o_2 = 1.57079632679489661923132169163975140e+00L, /* 3fff921fb54442d18469898cc51701b8 */
+pi = 3.14159265358979323846264338327950280e+00L, /* 4000921fb54442d18469898cc51701b8 */
+pi_lo = 8.67181013012378102479704402604335225e-35L; /* 3f8dcd129024e088a67cc74020bbea64 */
+
+#ifdef __STDC__
+ long double __ieee754_atan2l(long double y, long double x)
+#else
+ long double __ieee754_atan2l(y,x)
+ long double y,x;
+#endif
+{
+ long double z;
+ int64_t k,m,hx,hy,ix,iy;
+ u_int64_t lx,ly;
+
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ ix = hx&0x7fffffffffffffffLL;
+ GET_LDOUBLE_WORDS64(hy,ly,y);
+ iy = hy&0x7fffffffffffffffLL;
+ if(((ix)>0x7ff0000000000000LL)||
+ ((iy)>0x7ff0000000000000LL)) /* x or y is NaN */
+ return x+y;
+ if(((hx-0x3ff0000000000000LL))==0) return __atanl(y); /* x=1.0L */
+ m = ((hy>>63)&1)|((hx>>62)&2); /* 2*sign(x)+sign(y) */
+
+ /* when y = 0 */
+ if((iy|(ly&0x7fffffffffffffffLL))==0) {
+ switch(m) {
+ case 0:
+ case 1: return y; /* atan(+-0,+anything)=+-0 */
+ case 2: return pi+tiny;/* atan(+0,-anything) = pi */
+ case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
+ }
+ }
+ /* when x = 0 */
+ if((ix|(lx&0x7fffffffffffffff))==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* when x is INF */
+ if(ix==0x7ff0000000000000LL) {
+ if(iy==0x7ff0000000000000LL) {
+ switch(m) {
+ case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
+ case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
+ case 2: return 3.0L*pi_o_4+tiny;/*atan(+INF,-INF)*/
+ case 3: return -3.0L*pi_o_4-tiny;/*atan(-INF,-INF)*/
+ }
+ } else {
+ switch(m) {
+ case 0: return zero ; /* atan(+...,+INF) */
+ case 1: return -zero ; /* atan(-...,+INF) */
+ case 2: return pi+tiny ; /* atan(+...,-INF) */
+ case 3: return -pi-tiny ; /* atan(-...,-INF) */
+ }
+ }
+ }
+ /* when y is INF */
+ if(iy==0x7ff0000000000000LL) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* compute y/x */
+ k = (iy-ix)>>52;
+ if(k > 120) z=pi_o_2+0.5L*pi_lo; /* |y/x| > 2**120 */
+ else if(hx<0&&k<-120) z=0.0L; /* |y|/x < -2**120 */
+ else z=__atanl(fabsl(y/x)); /* safe to do y/x */
+ switch (m) {
+ case 0: return z ; /* atan(+,+) */
+ case 1: return -z ; /* atan(-,+) */
+ case 2: return pi-(z-pi_lo);/* atan(+,-) */
+ default: /* case 3 */
+ return (z-pi_lo)-pi;/* atan(-,-) */
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c
new file mode 100644
index 000000000..a801bd6f7
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c
@@ -0,0 +1,79 @@
+/* @(#)e_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: e_atanh.c,v 1.8 1995/05/10 20:44:55 jtc Exp $";
+#endif
+
+/* __ieee754_atanh(x)
+ * Method :
+ * 1.Reduced x to positive by atanh(-x) = -atanh(x)
+ * 2.For x>=0.5
+ * 1 2x x
+ * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
+ * 2 1 - x 1 - x
+ *
+ * For x<0.5
+ * atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
+ *
+ * Special cases:
+ * atanh(x) is NaN if |x| > 1 with signal;
+ * atanh(NaN) is that NaN with no signal;
+ * atanh(+-1) is +-INF with signal.
+ *
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0L, huge = 1e300L;
+#else
+static long double one = 1.0L, huge = 1e300L;
+#endif
+
+#ifdef __STDC__
+static const long double zero = 0.0L;
+#else
+static long double zero = 0.0L;
+#endif
+
+#ifdef __STDC__
+ long double __ieee754_atanhl(long double x)
+#else
+ long double __ieee754_atanhl(x)
+ long double x;
+#endif
+{
+ long double t;
+ int64_t hx,ix;
+ u_int64_t lx;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ ix = hx&0x7fffffffffffffffLL;
+ if (ix >= 0x3ff0000000000000LL) { /* |x|>=1 */
+ if (ix > 0x3ff0000000000000LL)
+ return (x-x)/(x-x);
+ t = fabsl (x);
+ if (t > one)
+ return (x-x)/(x-x);
+ if (t == one)
+ return x/zero;
+ }
+ if(ix<0x3e20000000000000LL&&(huge+x)>zero) return x; /* x<2**-29 */
+ x = fabsl (x);
+ if(ix<0x3fe0000000000000LL) { /* x < 0.5 */
+ t = x+x;
+ t = 0.5*__log1pl(t+t*x/(one-x));
+ } else
+ t = 0.5*__log1pl((x+x)/(one-x));
+ if(hx>=0) return t; else return -t;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_coshl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_coshl.c
new file mode 100644
index 000000000..73cb47892
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_coshl.c
@@ -0,0 +1,90 @@
+/* @(#)e_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: e_cosh.c,v 1.7 1995/05/10 20:44:58 jtc Exp $";
+#endif
+
+/* __ieee754_cosh(x)
+ * Method :
+ * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
+ * 1. Replace x by |x| (cosh(x) = cosh(-x)).
+ * 2.
+ * [ exp(x) - 1 ]^2
+ * 0 <= x <= ln2/2 : cosh(x) := 1 + -------------------
+ * 2*exp(x)
+ *
+ * exp(x) + 1/exp(x)
+ * ln2/2 <= x <= 22 : cosh(x) := -------------------
+ * 2
+ * 22 <= x <= lnovft : cosh(x) := exp(x)/2
+ * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2)
+ * ln2ovft < x : cosh(x) := huge*huge (overflow)
+ *
+ * Special cases:
+ * cosh(x) is |x| if x is +INF, -INF, or NaN.
+ * only cosh(0)=1 is exact for finite x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0L, half=0.5L, huge = 1.0e300L;
+#else
+static long double one = 1.0L, half=0.5L, huge = 1.0e300L;
+#endif
+
+#ifdef __STDC__
+ long double __ieee754_coshl(long double x)
+#else
+ long double __ieee754_coshl(x)
+ long double x;
+#endif
+{
+ long double t,w;
+ int64_t ix;
+
+ /* High word of |x|. */
+ GET_LDOUBLE_MSW64(ix,x);
+ ix &= 0x7fffffffffffffffLL;
+
+ /* x is INF or NaN */
+ if(ix>=0x7ff0000000000000LL) return x*x;
+
+ /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
+ if(ix<0x3fd62e42fefa39efLL) {
+ t = __expm1l(fabsl(x));
+ w = one+t;
+ if (ix<0x3c80000000000000LL) return w; /* cosh(tiny) = 1 */
+ return one+(t*t)/(w+w);
+ }
+
+ /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
+ if (ix < 0x4036000000000000LL) {
+ t = __ieee754_expl(fabsl(x));
+ return half*t+half/t;
+ }
+
+ /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
+ if (ix < 0x40862e42fefa39efLL) return half*__ieee754_expl(fabsl(x));
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ if (ix < 0x408633ce8fb9f87dLL) {
+ w = __ieee754_expl(half*fabsl(x));
+ t = half*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, cosh(x) overflow */
+ return huge*huge;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_expl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_expl.c
new file mode 100644
index 000000000..3c4088f75
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_expl.c
@@ -0,0 +1,257 @@
+/* Quad-precision floating point e^x.
+ Copyright (C) 1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+ Partly based on double-precision code
+ by Geoffrey Keating <geoffk@ozemail.com.au>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The basic design here is from
+ Abraham Ziv, "Fast Evaluation of Elementary Mathematical Functions with
+ Correctly Rounded Last Bit", ACM Trans. Math. Soft., 17 (3), September 1991,
+ pp. 410-423.
+
+ We work with number pairs where the first number is the high part and
+ the second one is the low part. Arithmetic with the high part numbers must
+ be exact, without any roundoff errors.
+
+ The input value, X, is written as
+ X = n * ln(2)_0 + arg1[t1]_0 + arg2[t2]_0 + x
+ - n * ln(2)_1 + arg1[t1]_1 + arg2[t2]_1 + xl
+
+ where:
+ - n is an integer, 16384 >= n >= -16495;
+ - ln(2)_0 is the first 93 bits of ln(2), and |ln(2)_0-ln(2)-ln(2)_1| < 2^-205
+ - t1 is an integer, 89 >= t1 >= -89
+ - t2 is an integer, 65 >= t2 >= -65
+ - |arg1[t1]-t1/256.0| < 2^-53
+ - |arg2[t2]-t2/32768.0| < 2^-53
+ - x + xl is whatever is left, |x + xl| < 2^-16 + 2^-53
+
+ Then e^x is approximated as
+
+ e^x = 2^n_1 ( 2^n_0 e^(arg1[t1]_0 + arg1[t1]_1) e^(arg2[t2]_0 + arg2[t2]_1)
+ + 2^n_0 e^(arg1[t1]_0 + arg1[t1]_1) e^(arg2[t2]_0 + arg2[t2]_1)
+ * p (x + xl + n * ln(2)_1))
+ where:
+ - p(x) is a polynomial approximating e(x)-1
+ - e^(arg1[t1]_0 + arg1[t1]_1) is obtained from a table
+ - e^(arg2[t2]_0 + arg2[t2]_1) likewise
+ - n_1 + n_0 = n, so that |n_0| < -LDBL_MIN_EXP-1.
+
+ If it happens that n_1 == 0 (this is the usual case), that multiplication
+ is omitted.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <float.h>
+#include <ieee754.h>
+#include <math.h>
+#include <fenv.h>
+#include <inttypes.h>
+#include <math_private.h>
+#include <sysdeps/ieee754/ldbl-128/t_expl.h>
+
+static const long double C[] = {
+/* Smallest integer x for which e^x overflows. */
+#define himark C[0]
+ 709.08956571282405153382846025171462914L,
+
+/* Largest integer x for which e^x underflows. */
+#define lomark C[1]
+-709.08956571282405153382846025171462914L,
+
+/* 3x2^96 */
+#define THREEp96 C[2]
+ 59421121885698253195157962752.0L,
+
+/* 3x2^103 */
+#define THREEp103 C[3]
+ 30423614405477505635920876929024.0L,
+
+/* 3x2^111 */
+#define THREEp111 C[4]
+ 7788445287802241442795744493830144.0L,
+
+/* 1/ln(2) */
+#define M_1_LN2 C[5]
+ 1.44269504088896340735992468100189204L,
+
+/* first 93 bits of ln(2) */
+#define M_LN2_0 C[6]
+ 0.693147180559945309417232121457981864L,
+
+/* ln2_0 - ln(2) */
+#define M_LN2_1 C[7]
+-1.94704509238074995158795957333327386E-31L,
+
+/* very small number */
+#define TINY C[8]
+ 1.0e-308L,
+
+/* 2^16383 */
+#define TWO1023 C[9]
+ 8.988465674311579538646525953945123668E+307L,
+
+/* 256 */
+#define TWO8 C[10]
+ 256.0L,
+
+/* 32768 */
+#define TWO15 C[11]
+ 32768.0L,
+
+/* Chebyshev polynom coeficients for (exp(x)-1)/x */
+#define P1 C[12]
+#define P2 C[13]
+#define P3 C[14]
+#define P4 C[15]
+#define P5 C[16]
+#define P6 C[17]
+ 0.5L,
+ 1.66666666666666666666666666666666683E-01L,
+ 4.16666666666666666666654902320001674E-02L,
+ 8.33333333333333333333314659767198461E-03L,
+ 1.38888888889899438565058018857254025E-03L,
+ 1.98412698413981650382436541785404286E-04L,
+};
+
+long double
+__ieee754_expl (long double x)
+{
+ /* Check for usual case. */
+ if (isless (x, himark) && isgreater (x, lomark))
+ {
+ int tval1, tval2, unsafe, n_i, exponent2;
+ long double x22, n, result, xl;
+ union ibm_extended_long_double ex2_u, scale_u;
+ fenv_t oldenv;
+
+ feholdexcept (&oldenv);
+#ifdef FE_TONEAREST
+ fesetround (FE_TONEAREST);
+#endif
+
+ n = roundl(x*M_1_LN2);
+ x = x-n*M_LN2_0;
+ xl = n*M_LN2_1;
+
+ tval1 = roundl(x*TWO8);
+ x -= __expl_table[T_EXPL_ARG1+2*tval1];
+ xl -= __expl_table[T_EXPL_ARG1+2*tval1+1];
+
+ tval2 = roundl(x*TWO15);
+ x -= __expl_table[T_EXPL_ARG2+2*tval2];
+ xl -= __expl_table[T_EXPL_ARG2+2*tval2+1];
+
+ x = x + xl;
+
+ /* Compute ex2 = 2^n_0 e^(argtable[tval1]) e^(argtable[tval2]). */
+ ex2_u.d = __expl_table[T_EXPL_RES1 + tval1]
+ * __expl_table[T_EXPL_RES2 + tval2];
+ n_i = (int)n;
+ /* 'unsafe' is 1 iff n_1 != 0. */
+ unsafe = fabsl(n_i) >= -LDBL_MIN_EXP - 1;
+ ex2_u.ieee.exponent += n_i >> unsafe;
+ /* Fortunately, there are no subnormal lowpart doubles in
+ __expl_table, only normal values and zeros.
+ But after scaling it can be subnormal. */
+ exponent2 = ex2_u.ieee.exponent2 + (n_i >> unsafe);
+ if (ex2_u.ieee.exponent2 == 0)
+ /* assert ((ex2_u.ieee.mantissa2|ex2_u.ieee.mantissa3) == 0) */;
+ else if (exponent2 > 0)
+ ex2_u.ieee.exponent2 = exponent2;
+ else if (exponent2 <= -54)
+ {
+ ex2_u.ieee.exponent2 = 0;
+ ex2_u.ieee.mantissa2 = 0;
+ ex2_u.ieee.mantissa3 = 0;
+ }
+ else
+ {
+ static const double
+ two54 = 1.80143985094819840000e+16, /* 4350000000000000 */
+ twom54 = 5.55111512312578270212e-17; /* 3C90000000000000 */
+ ex2_u.dd[1] *= two54;
+ ex2_u.ieee.exponent2 += n_i >> unsafe;
+ ex2_u.dd[1] *= twom54;
+ }
+
+ /* Compute scale = 2^n_1. */
+ scale_u.d = 1.0L;
+ scale_u.ieee.exponent += n_i - (n_i >> unsafe);
+
+ /* Approximate e^x2 - 1, using a seventh-degree polynomial,
+ with maximum error in [-2^-16-2^-53,2^-16+2^-53]
+ less than 4.8e-39. */
+ x22 = x + x*x*(P1+x*(P2+x*(P3+x*(P4+x*(P5+x*P6)))));
+
+ /* Return result. */
+ fesetenv (&oldenv);
+
+ result = x22 * ex2_u.d + ex2_u.d;
+
+ /* Now we can test whether the result is ultimate or if we are unsure.
+ In the later case we should probably call a mpn based routine to give
+ the ultimate result.
+ Empirically, this routine is already ultimate in about 99.9986% of
+ cases, the test below for the round to nearest case will be false
+ in ~ 99.9963% of cases.
+ Without proc2 routine maximum error which has been seen is
+ 0.5000262 ulp.
+
+ union ieee854_long_double ex3_u;
+
+ #ifdef FE_TONEAREST
+ fesetround (FE_TONEAREST);
+ #endif
+ ex3_u.d = (result - ex2_u.d) - x22 * ex2_u.d;
+ ex2_u.d = result;
+ ex3_u.ieee.exponent += LDBL_MANT_DIG + 15 + IEEE854_LONG_DOUBLE_BIAS
+ - ex2_u.ieee.exponent;
+ n_i = abs (ex3_u.d);
+ n_i = (n_i + 1) / 2;
+ fesetenv (&oldenv);
+ #ifdef FE_TONEAREST
+ if (fegetround () == FE_TONEAREST)
+ n_i -= 0x4000;
+ #endif
+ if (!n_i) {
+ return __ieee754_expl_proc2 (origx);
+ }
+ */
+ if (!unsafe)
+ return result;
+ else
+ return result * scale_u.d;
+ }
+ /* Exceptional cases: */
+ else if (isless (x, himark))
+ {
+ if (__isinfl (x))
+ /* e^-inf == 0, with no error. */
+ return 0;
+ else
+ /* Underflow */
+ return TINY * TINY;
+ }
+ else
+ /* Return x, if x is a NaN or Inf; or overflow, otherwise. */
+ return TWO1023*x;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c
new file mode 100644
index 000000000..e99b0bac3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c
@@ -0,0 +1,145 @@
+/* e_fmodl.c -- long double version of e_fmod.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/*
+ * __ieee754_fmodl(x,y)
+ * Return x mod y in exact arithmetic
+ * Method: shift and subtract
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <ieee754.h>
+
+#ifdef __STDC__
+static const long double one = 1.0, Zero[] = {0.0, -0.0,};
+#else
+static long double one = 1.0, Zero[] = {0.0, -0.0,};
+#endif
+
+#ifdef __STDC__
+ long double __ieee754_fmodl(long double x, long double y)
+#else
+ long double __ieee754_fmodl(x,y)
+ long double x,y;
+#endif
+{
+ int64_t n,hx,hy,hz,ix,iy,sx,i;
+ u_int64_t lx,ly,lz;
+ int temp;
+
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ GET_LDOUBLE_WORDS64(hy,ly,y);
+ sx = hx&0x8000000000000000ULL; /* sign of x */
+ hx ^=sx; /* |x| */
+ hy &= 0x7fffffffffffffffLL; /* |y| */
+
+ /* purge off exception values */
+ if((hy|(ly&0x7fffffffffffffff))==0||(hx>=0x7ff0000000000000LL)|| /* y=0,or x not finite */
+ (hy>0x7ff0000000000000LL)) /* or y is NaN */
+ return (x*y)/(x*y);
+ if(hx<=hy) {
+ if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
+ if(lx==ly)
+ return Zero[(u_int64_t)sx>>63]; /* |x|=|y| return x*0*/
+ }
+
+ /* determine ix = ilogb(x) */
+ if(hx<0x0010000000000000LL) { /* subnormal x */
+ if(hx==0) {
+ for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
+ } else {
+ for (ix = -1022, i=hx<<19; i>0; i<<=1) ix -=1;
+ }
+ } else ix = (hx>>52)-0x3ff;
+
+ /* determine iy = ilogb(y) */
+ if(hy<0x0010000000000000LL) { /* subnormal y */
+ if(hy==0) {
+ for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
+ } else {
+ for (iy = -1022, i=hy<<19; i>0; i<<=1) iy -=1;
+ }
+ } else iy = (hy>>52)-0x3ff;
+
+ /* Make the IBM extended format 105 bit mantissa look like the ieee854 112
+ bit mantissa so the following operatations will give the correct
+ result. */
+ ldbl_extract_mantissa(&hx, &lx, &temp, x);
+ ldbl_extract_mantissa(&hy, &ly, &temp, y);
+
+ /* set up {hx,lx}, {hy,ly} and align y to x */
+ if(ix >= -1022)
+ hx = 0x0001000000000000LL|(0x0000ffffffffffffLL&hx);
+ else { /* subnormal x, shift x to normal */
+ n = -1022-ix;
+ if(n<=63) {
+ hx = (hx<<n)|(lx>>(64-n));
+ lx <<= n;
+ } else {
+ hx = lx<<(n-64);
+ lx = 0;
+ }
+ }
+ if(iy >= -1022)
+ hy = 0x0001000000000000LL|(0x0000ffffffffffffLL&hy);
+ else { /* subnormal y, shift y to normal */
+ n = -1022-iy;
+ if(n<=63) {
+ hy = (hy<<n)|(ly>>(64-n));
+ ly <<= n;
+ } else {
+ hy = ly<<(n-64);
+ ly = 0;
+ }
+ }
+
+ /* fix point fmod */
+ n = ix - iy;
+ while(n--) {
+ hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ if(hz<0){hx = hx+hx+(lx>>63); lx = lx+lx;}
+ else {
+ if((hz|(lz&0x7fffffffffffffff))==0) /* return sign(x)*0 */
+ return Zero[(u_int64_t)sx>>63];
+ hx = hz+hz+(lz>>63); lx = lz+lz;
+ }
+ }
+ hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ if(hz>=0) {hx=hz;lx=lz;}
+
+ /* convert back to floating value and restore the sign */
+ if((hx|(lx&0x7fffffffffffffff))==0) /* return sign(x)*0 */
+ return Zero[(u_int64_t)sx>>63];
+ while(hx<0x0001000000000000LL) { /* normalize x */
+ hx = hx+hx+(lx>>63); lx = lx+lx;
+ iy -= 1;
+ }
+ if(iy>= -1022) { /* normalize output */
+ x = ldbl_insert_mantissa((sx>>63), iy, hx, lx);
+ } else { /* subnormal output */
+ n = -1022 - iy;
+ if(n<=48) {
+ lx = (lx>>n)|((u_int64_t)hx<<(64-n));
+ hx >>= n;
+ } else if (n<=63) {
+ lx = (hx<<(64-n))|(lx>>n); hx = sx;
+ } else {
+ lx = hx>>(n-64); hx = sx;
+ }
+ x = ldbl_insert_mantissa((sx>>63), iy, hx, lx);
+ x *= one; /* create necessary signal */
+ }
+ return x; /* exact output */
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c
new file mode 100644
index 000000000..03bcb2129
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c
@@ -0,0 +1,58 @@
+/* Implementation of gamma function according to ISO C.
+ Copyright (C) 1997,1999,2002,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_private.h>
+
+
+long double
+__ieee754_gammal_r (long double x, int *signgamp)
+{
+ /* We don't have a real gamma implementation now. We'll use lgamma
+ and the exp function. But due to the required boundary
+ conditions we must check some values separately. */
+ int64_t hx;
+ u_int64_t lx;
+
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+
+ if (((hx | lx) & 0x7fffffffffffffffLL) == 0)
+ {
+ /* Return value for x == 0 is Inf with divide by zero exception. */
+ *signgamp = 0;
+ return 1.0 / x;
+ }
+ if (hx < 0 && (u_int64_t) hx < 0xfff0000000000000ULL && __rintl (x) == x)
+ {
+ /* Return value for integer x < 0 is NaN with invalid exception. */
+ *signgamp = 0;
+ return (x - x) / (x - x);
+ }
+ if (hx == 0xfff0000000000000ULL)
+ {
+ /* x == -Inf. According to ISO this is NaN. */
+ *signgamp = 0;
+ return x - x;
+ }
+
+ /* XXX FIXME. */
+ return __ieee754_expl (__ieee754_lgammal_r (x, signgamp));
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c
new file mode 100644
index 000000000..4330f28b9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c
@@ -0,0 +1,131 @@
+/* @(#)e_hypotl.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: e_hypotl.c,v 1.9 1995/05/12 04:57:27 jtc Exp $";
+#endif
+
+/* __ieee754_hypotl(x,y)
+ *
+ * Method :
+ * If (assume round-to-nearest) z=x*x+y*y
+ * has error less than sqrtl(2)/2 ulp, than
+ * sqrtl(z) has error less than 1 ulp (exercise).
+ *
+ * So, compute sqrtl(x*x+y*y) with some care as
+ * follows to get the error below 1 ulp:
+ *
+ * Assume x>y>0;
+ * (if possible, set rounding to round-to-nearest)
+ * 1. if x > 2y use
+ * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
+ * where x1 = x with lower 53 bits cleared, x2 = x-x1; else
+ * 2. if x <= 2y use
+ * t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
+ * where t1 = 2x with lower 53 bits cleared, t2 = 2x-t1,
+ * y1= y with lower 53 bits chopped, y2 = y-y1.
+ *
+ * NOTE: scaling may be necessary if some argument is too
+ * large or too tiny
+ *
+ * Special cases:
+ * hypotl(x,y) is INF if x or y is +INF or -INF; else
+ * hypotl(x,y) is NAN if x or y is NAN.
+ *
+ * Accuracy:
+ * hypotl(x,y) returns sqrtl(x^2+y^2) with error less
+ * than 1 ulps (units in the last place)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const long double two600 = 0x1.0p+600L;
+static const long double two1022 = 0x1.0p+1022L;
+
+#ifdef __STDC__
+ long double __ieee754_hypotl(long double x, long double y)
+#else
+ long double __ieee754_hypotl(x,y)
+ long double x, y;
+#endif
+{
+ long double a,b,t1,t2,y1,y2,w,kld;
+ int64_t j,k,ha,hb;
+
+ GET_LDOUBLE_MSW64(ha,x);
+ ha &= 0x7fffffffffffffffLL;
+ GET_LDOUBLE_MSW64(hb,y);
+ hb &= 0x7fffffffffffffffLL;
+ if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
+ a = fabsl(a); /* a <- |a| */
+ b = fabsl(b); /* b <- |b| */
+ if((ha-hb)>0x3c0000000000000LL) {return a+b;} /* x/y > 2**60 */
+ k=0;
+ kld = 1.0L;
+ if(ha > 0x5f30000000000000LL) { /* a>2**500 */
+ if(ha >= 0x7ff0000000000000LL) { /* Inf or NaN */
+ u_int64_t low;
+ w = a+b; /* for sNaN */
+ GET_LDOUBLE_LSW64(low,a);
+ if(((ha&0xfffffffffffffLL)|(low&0x7fffffffffffffffLL))==0)
+ w = a;
+ GET_LDOUBLE_LSW64(low,b);
+ if(((hb^0x7ff0000000000000LL)|(low&0x7fffffffffffffffLL))==0)
+ w = b;
+ return w;
+ }
+ /* scale a and b by 2**-600 */
+ ha -= 0x2580000000000000LL; hb -= 0x2580000000000000LL; k += 600;
+ a /= two600;
+ b /= two600;
+ k += 600;
+ kld = two600;
+ }
+ if(hb < 0x20b0000000000000LL) { /* b < 2**-500 */
+ if(hb <= 0x000fffffffffffffLL) { /* subnormal b or 0 */
+ u_int64_t low;
+ GET_LDOUBLE_LSW64(low,b);
+ if((hb|(low&0x7fffffffffffffffLL))==0) return a;
+ t1=two1022; /* t1=2^1022 */
+ b *= t1;
+ a *= t1;
+ k -= 1022;
+ kld = kld / two1022;
+ } else { /* scale a and b by 2^600 */
+ ha += 0x2580000000000000LL; /* a *= 2^600 */
+ hb += 0x2580000000000000LL; /* b *= 2^600 */
+ k -= 600;
+ a *= two600;
+ b *= two600;
+ kld = kld / two600;
+ }
+ }
+ /* medium size a and b */
+ w = a-b;
+ if (w>b) {
+ SET_LDOUBLE_WORDS64(t1,ha,0);
+ t2 = a-t1;
+ w = __ieee754_sqrtl(t1*t1-(b*(-b)-t2*(a+t1)));
+ } else {
+ a = a+a;
+ SET_LDOUBLE_WORDS64(y1,hb,0);
+ y2 = b - y1;
+ SET_LDOUBLE_WORDS64(t1,ha+0x0010000000000000LL,0);
+ t2 = a - t1;
+ w = __ieee754_sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b)));
+ }
+ if(k!=0)
+ return w*kld;
+ else
+ return w;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_j0l.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_j0l.c
new file mode 100644
index 000000000..39a238aa9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_j0l.c
@@ -0,0 +1,3 @@
+/* Looks like we can use ieee854 e_j0l.c as is for IBM extended format. */
+#include <sysdeps/ieee754/ldbl-128/e_j0l.c>
+
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_j1l.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_j1l.c
new file mode 100644
index 000000000..c86e24f7c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_j1l.c
@@ -0,0 +1,2 @@
+/* Looks like we can use ieee854 e_j1l.c as is for IBM extended format. */
+#include <sysdeps/ieee754/ldbl-128/e_j1l.c>
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_jnl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_jnl.c
new file mode 100644
index 000000000..0eea74567
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_jnl.c
@@ -0,0 +1,402 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* Modifications for 128-bit long double are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ * __ieee754_jn(n, x), __ieee754_yn(n, 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"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ invsqrtpi = 5.6418958354775628694807945156077258584405E-1L,
+ two = 2.0e0L,
+ one = 1.0e0L,
+ zero = 0.0L;
+
+
+#ifdef __STDC__
+long double
+__ieee754_jnl (int n, long double x)
+#else
+long double
+__ieee754_jnl (n, x)
+ int n;
+ long double x;
+#endif
+{
+ u_int32_t se;
+ int32_t i, ix, sgn;
+ long double a, b, temp, di;
+ long double z, w;
+ ieee854_long_double_shape_type u;
+
+
+ /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
+ * Thus, J(-n,x) = J(n,-x)
+ */
+
+ u.value = x;
+ se = u.parts32.w0;
+ ix = se & 0x7fffffff;
+
+ /* if J(n,NaN) is NaN */
+ if (ix >= 0x7ff00000)
+ {
+ if ((u.parts32.w0 & 0xfffff) | u.parts32.w1
+ | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3)
+ return x + x;
+ }
+
+ if (n < 0)
+ {
+ n = -n;
+ x = -x;
+ se ^= 0x80000000;
+ }
+ if (n == 0)
+ return (__ieee754_j0l (x));
+ if (n == 1)
+ return (__ieee754_j1l (x));
+ sgn = (n & 1) & (se >> 31); /* even n -- 0, odd n -- sign(x) */
+ x = fabsl (x);
+
+ if (x == 0.0L || ix >= 0x7ff00000) /* if x is 0 or inf */
+ b = zero;
+ else if ((long double) n <= x)
+ {
+ /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
+ if (ix >= 0x52d00000)
+ { /* x > 2**302 */
+
+ /* ??? Could use an expansion for large x here. */
+
+ /* (x >> n**2)
+ * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Let s=sin(x), c=cos(x),
+ * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+ *
+ * n sin(xn)*sqt2 cos(xn)*sqt2
+ * ----------------------------------
+ * 0 s-c c+s
+ * 1 -s-c -c+s
+ * 2 -s+c -c-s
+ * 3 s+c c-s
+ */
+ long double s;
+ long double c;
+ __sincosl (x, &s, &c);
+ switch (n & 3)
+ {
+ case 0:
+ temp = c + s;
+ break;
+ case 1:
+ temp = -c + s;
+ break;
+ case 2:
+ temp = -c - s;
+ break;
+ case 3:
+ temp = c - s;
+ break;
+ }
+ b = invsqrtpi * temp / __ieee754_sqrtl (x);
+ }
+ else
+ {
+ a = __ieee754_j0l (x);
+ b = __ieee754_j1l (x);
+ for (i = 1; i < n; i++)
+ {
+ temp = b;
+ b = b * ((long double) (i + i) / x) - a; /* avoid underflow */
+ a = temp;
+ }
+ }
+ }
+ else
+ {
+ if (ix < 0x3e100000)
+ { /* x < 2**-29 */
+ /* x is tiny, return the first Taylor expansion of J(n,x)
+ * J(n,x) = 1/n!*(x/2)^n - ...
+ */
+ if (n >= 33) /* underflow, result < 10^-300 */
+ b = zero;
+ else
+ {
+ temp = x * 0.5;
+ b = temp;
+ for (a = one, i = 2; i <= n; i++)
+ {
+ a *= (long double) i; /* a = n! */
+ b *= temp; /* b = (x/2)^n */
+ }
+ b = b / a;
+ }
+ }
+ else
+ {
+ /* use backward recurrence */
+ /* x x^2 x^2
+ * J(n,x)/J(n-1,x) = ---- ------ ------ .....
+ * 2n - 2(n+1) - 2(n+2)
+ *
+ * 1 1 1
+ * (for large x) = ---- ------ ------ .....
+ * 2n 2(n+1) 2(n+2)
+ * -- - ------ - ------ -
+ * x x x
+ *
+ * Let w = 2n/x and h=2/x, then the above quotient
+ * is equal to the continued fraction:
+ * 1
+ * = -----------------------
+ * 1
+ * w - -----------------
+ * 1
+ * w+h - ---------
+ * w+2h - ...
+ *
+ * To determine how many terms needed, let
+ * Q(0) = w, Q(1) = w(w+h) - 1,
+ * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
+ * When Q(k) > 1e4 good for single
+ * When Q(k) > 1e9 good for double
+ * When Q(k) > 1e17 good for quadruple
+ */
+ /* determine k */
+ long double t, v;
+ long double q0, q1, h, tmp;
+ int32_t k, m;
+ w = (n + n) / (long double) x;
+ h = 2.0L / (long double) x;
+ q0 = w;
+ z = w + h;
+ q1 = w * z - 1.0L;
+ k = 1;
+ while (q1 < 1.0e17L)
+ {
+ k += 1;
+ z += h;
+ tmp = z * q1 - q0;
+ q0 = q1;
+ q1 = tmp;
+ }
+ m = n + n;
+ for (t = zero, i = 2 * (n + k); i >= m; i -= 2)
+ t = one / (i / x - t);
+ a = t;
+ b = one;
+ /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
+ * Hence, if n*(log(2n/x)) > ...
+ * single 8.8722839355e+01
+ * double 7.09782712893383973096e+02
+ * long double 1.1356523406294143949491931077970765006170e+04
+ * then recurrent value may overflow and the result is
+ * likely underflow to zero
+ */
+ tmp = n;
+ v = two / x;
+ tmp = tmp * __ieee754_logl (fabsl (v * tmp));
+
+ if (tmp < 1.1356523406294143949491931077970765006170e+04L)
+ {
+ for (i = n - 1, di = (long double) (i + i); i > 0; i--)
+ {
+ temp = b;
+ b *= di;
+ b = b / x - a;
+ a = temp;
+ di -= two;
+ }
+ }
+ else
+ {
+ for (i = n - 1, di = (long double) (i + i); i > 0; i--)
+ {
+ temp = b;
+ b *= di;
+ b = b / x - a;
+ a = temp;
+ di -= two;
+ /* scale b to avoid spurious overflow */
+ if (b > 1e100L)
+ {
+ a /= b;
+ t /= b;
+ b = one;
+ }
+ }
+ }
+ b = (t * __ieee754_j0l (x) / b);
+ }
+ }
+ if (sgn == 1)
+ return -b;
+ else
+ return b;
+}
+
+#ifdef __STDC__
+long double
+__ieee754_ynl (int n, long double x)
+#else
+long double
+__ieee754_ynl (n, x)
+ int n;
+ long double x;
+#endif
+{
+ u_int32_t se;
+ int32_t i, ix;
+ int32_t sign;
+ long double a, b, temp;
+ ieee854_long_double_shape_type u;
+
+ u.value = x;
+ se = u.parts32.w0;
+ ix = se & 0x7fffffff;
+
+ /* if Y(n,NaN) is NaN */
+ if (ix >= 0x7ff00000)
+ {
+ if ((u.parts32.w0 & 0xfffff) | u.parts32.w1
+ | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3)
+ return x + x;
+ }
+ if (x <= 0.0L)
+ {
+ if (x == 0.0L)
+ return -HUGE_VALL + x;
+ if (se & 0x80000000)
+ return zero / (zero * x);
+ }
+ sign = 1;
+ if (n < 0)
+ {
+ n = -n;
+ sign = 1 - ((n & 1) << 1);
+ }
+ if (n == 0)
+ return (__ieee754_y0l (x));
+ if (n == 1)
+ return (sign * __ieee754_y1l (x));
+ if (ix >= 0x7ff00000)
+ return zero;
+ if (ix >= 0x52D00000)
+ { /* x > 2**302 */
+
+ /* ??? See comment above on the possible futility of this. */
+
+ /* (x >> n**2)
+ * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Let s=sin(x), c=cos(x),
+ * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+ *
+ * n sin(xn)*sqt2 cos(xn)*sqt2
+ * ----------------------------------
+ * 0 s-c c+s
+ * 1 -s-c -c+s
+ * 2 -s+c -c-s
+ * 3 s+c c-s
+ */
+ long double s;
+ long double c;
+ __sincosl (x, &s, &c);
+ switch (n & 3)
+ {
+ case 0:
+ temp = s - c;
+ break;
+ case 1:
+ temp = -s - c;
+ break;
+ case 2:
+ temp = -s + c;
+ break;
+ case 3:
+ temp = s + c;
+ break;
+ }
+ b = invsqrtpi * temp / __ieee754_sqrtl (x);
+ }
+ else
+ {
+ a = __ieee754_y0l (x);
+ b = __ieee754_y1l (x);
+ /* quit if b is -inf */
+ u.value = b;
+ se = u.parts32.w0 & 0xfff00000;
+ for (i = 1; i < n && se != 0xfff00000; i++)
+ {
+ temp = b;
+ b = ((long double) (i + i) / x) * b - a;
+ u.value = b;
+ se = u.parts32.w0 & 0xfff00000;
+ a = temp;
+ }
+ }
+ if (sign > 0)
+ return b;
+ else
+ return -b;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c
new file mode 100644
index 000000000..9bcaaf765
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c
@@ -0,0 +1,3 @@
+/* Looks like we can use ieee854 e_lgammal_r.c as is for IBM extended format. */
+#include <sysdeps/ieee754/ldbl-128/e_lgammal_r.c>
+
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_log10l.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_log10l.c
new file mode 100644
index 000000000..27e2c71b8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_log10l.c
@@ -0,0 +1,258 @@
+/* log10l.c
+ *
+ * Common logarithm, 128-bit long double precision
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, log10l();
+ *
+ * y = log10l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base 10 logarithm of x.
+ *
+ * The argument is separated into its exponent and fractional
+ * parts. If the exponent is between -1 and +1, the logarithm
+ * of the fraction is approximated by
+ *
+ * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x).
+ *
+ * Otherwise, setting z = 2(x-1)/x+1),
+ *
+ * log(x) = z + z^3 P(z)/Q(z).
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE 0.5, 2.0 30000 2.3e-34 4.9e-35
+ * IEEE exp(+-10000) 30000 1.0e-34 4.1e-35
+ *
+ * In the tests over the interval exp(+-10000), the logarithms
+ * of the random arguments were uniformly distributed over
+ * [-10000, +10000].
+ *
+ */
+
+/*
+ Cephes Math Library Release 2.2: January, 1991
+ Copyright 1984, 1991 by Stephen L. Moshier
+ Adapted for glibc November, 2001
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 5.3e-37,
+ * relative peak error spread = 2.3e-14
+ */
+static const long double P[13] =
+{
+ 1.313572404063446165910279910527789794488E4L,
+ 7.771154681358524243729929227226708890930E4L,
+ 2.014652742082537582487669938141683759923E5L,
+ 3.007007295140399532324943111654767187848E5L,
+ 2.854829159639697837788887080758954924001E5L,
+ 1.797628303815655343403735250238293741397E5L,
+ 7.594356839258970405033155585486712125861E4L,
+ 2.128857716871515081352991964243375186031E4L,
+ 3.824952356185897735160588078446136783779E3L,
+ 4.114517881637811823002128927449878962058E2L,
+ 2.321125933898420063925789532045674660756E1L,
+ 4.998469661968096229986658302195402690910E-1L,
+ 1.538612243596254322971797716843006400388E-6L
+};
+static const long double Q[12] =
+{
+ 3.940717212190338497730839731583397586124E4L,
+ 2.626900195321832660448791748036714883242E5L,
+ 7.777690340007566932935753241556479363645E5L,
+ 1.347518538384329112529391120390701166528E6L,
+ 1.514882452993549494932585972882995548426E6L,
+ 1.158019977462989115839826904108208787040E6L,
+ 6.132189329546557743179177159925690841200E5L,
+ 2.248234257620569139969141618556349415120E5L,
+ 5.605842085972455027590989944010492125825E4L,
+ 9.147150349299596453976674231612674085381E3L,
+ 9.104928120962988414618126155557301584078E2L,
+ 4.839208193348159620282142911143429644326E1L
+/* 1.000000000000000000000000000000000000000E0L, */
+};
+
+/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
+ * where z = 2(x-1)/(x+1)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 1.1e-35,
+ * relative peak error spread 1.1e-9
+ */
+static const long double R[6] =
+{
+ 1.418134209872192732479751274970992665513E5L,
+ -8.977257995689735303686582344659576526998E4L,
+ 2.048819892795278657810231591630928516206E4L,
+ -2.024301798136027039250415126250455056397E3L,
+ 8.057002716646055371965756206836056074715E1L,
+ -8.828896441624934385266096344596648080902E-1L
+};
+static const long double S[6] =
+{
+ 1.701761051846631278975701529965589676574E6L,
+ -1.332535117259762928288745111081235577029E6L,
+ 4.001557694070773974936904547424676279307E5L,
+ -5.748542087379434595104154610899551484314E4L,
+ 3.998526750980007367835804959888064681098E3L,
+ -1.186359407982897997337150403816839480438E2L
+/* 1.000000000000000000000000000000000000000E0L, */
+};
+
+static const long double
+/* log10(2) */
+L102A = 0.3125L,
+L102B = -1.14700043360188047862611052755069732318101185E-2L,
+/* log10(e) */
+L10EA = 0.5L,
+L10EB = -6.570551809674817234887108108339491770560299E-2L,
+/* sqrt(2)/2 */
+SQRTH = 7.071067811865475244008443621048490392848359E-1L;
+
+
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+neval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+deval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+
+long double
+__ieee754_log10l (x)
+ long double x;
+{
+ long double z;
+ long double y;
+ int e;
+ int64_t hx, lx;
+
+/* Test for domain */
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+ if (((hx & 0x7fffffffffffffffLL) | (lx & 0x7fffffffffffffffLL)) == 0)
+ return (-1.0L / (x - x));
+ if (hx < 0)
+ return (x - x) / (x - x);
+ if (hx >= 0x7ff0000000000000LL)
+ return (x + x);
+
+/* separate mantissa from exponent */
+
+/* Note, frexp is used so that denormal numbers
+ * will be handled properly.
+ */
+ x = __frexpl (x, &e);
+
+
+/* logarithm using log(x) = z + z**3 P(z)/Q(z),
+ * where z = 2(x-1)/x+1)
+ */
+ if ((e > 2) || (e < -2))
+ {
+ if (x < SQRTH)
+ { /* 2( 2x-1 )/( 2x+1 ) */
+ e -= 1;
+ z = x - 0.5L;
+ y = 0.5L * z + 0.5L;
+ }
+ else
+ { /* 2 (x-1)/(x+1) */
+ z = x - 0.5L;
+ z -= 0.5L;
+ y = 0.5L * x + 0.5L;
+ }
+ x = z / y;
+ z = x * x;
+ y = x * (z * neval (z, R, 5) / deval (z, S, 5));
+ goto done;
+ }
+
+
+/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
+
+ if (x < SQRTH)
+ {
+ e -= 1;
+ x = 2.0 * x - 1.0L; /* 2x - 1 */
+ }
+ else
+ {
+ x = x - 1.0L;
+ }
+ z = x * x;
+ y = x * (z * neval (x, P, 12) / deval (x, Q, 11));
+ y = y - 0.5 * z;
+
+done:
+
+ /* Multiply log of fraction by log10(e)
+ * and base 2 exponent by log10(2).
+ */
+ z = y * L10EB;
+ z += x * L10EB;
+ z += e * L102B;
+ z += y * L10EA;
+ z += x * L10EA;
+ z += e * L102A;
+ return (z);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_log2l.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_log2l.c
new file mode 100644
index 000000000..fe8a8e1d6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_log2l.c
@@ -0,0 +1,250 @@
+/* log2l.c
+ * Base 2 logarithm, 128-bit long double precision
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, log2l();
+ *
+ * y = log2l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base 2 logarithm of x.
+ *
+ * The argument is separated into its exponent and fractional
+ * parts. If the exponent is between -1 and +1, the (natural)
+ * logarithm of the fraction is approximated by
+ *
+ * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x).
+ *
+ * Otherwise, setting z = 2(x-1)/x+1),
+ *
+ * log(x) = z + z^3 P(z)/Q(z).
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE 0.5, 2.0 100,000 2.6e-34 4.9e-35
+ * IEEE exp(+-10000) 100,000 9.6e-35 4.0e-35
+ *
+ * In the tests over the interval exp(+-10000), the logarithms
+ * of the random arguments were uniformly distributed over
+ * [-10000, +10000].
+ *
+ */
+
+/*
+ Cephes Math Library Release 2.2: January, 1991
+ Copyright 1984, 1991 by Stephen L. Moshier
+ Adapted for glibc November, 2001
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 5.3e-37,
+ * relative peak error spread = 2.3e-14
+ */
+static const long double P[13] =
+{
+ 1.313572404063446165910279910527789794488E4L,
+ 7.771154681358524243729929227226708890930E4L,
+ 2.014652742082537582487669938141683759923E5L,
+ 3.007007295140399532324943111654767187848E5L,
+ 2.854829159639697837788887080758954924001E5L,
+ 1.797628303815655343403735250238293741397E5L,
+ 7.594356839258970405033155585486712125861E4L,
+ 2.128857716871515081352991964243375186031E4L,
+ 3.824952356185897735160588078446136783779E3L,
+ 4.114517881637811823002128927449878962058E2L,
+ 2.321125933898420063925789532045674660756E1L,
+ 4.998469661968096229986658302195402690910E-1L,
+ 1.538612243596254322971797716843006400388E-6L
+};
+static const long double Q[12] =
+{
+ 3.940717212190338497730839731583397586124E4L,
+ 2.626900195321832660448791748036714883242E5L,
+ 7.777690340007566932935753241556479363645E5L,
+ 1.347518538384329112529391120390701166528E6L,
+ 1.514882452993549494932585972882995548426E6L,
+ 1.158019977462989115839826904108208787040E6L,
+ 6.132189329546557743179177159925690841200E5L,
+ 2.248234257620569139969141618556349415120E5L,
+ 5.605842085972455027590989944010492125825E4L,
+ 9.147150349299596453976674231612674085381E3L,
+ 9.104928120962988414618126155557301584078E2L,
+ 4.839208193348159620282142911143429644326E1L
+/* 1.000000000000000000000000000000000000000E0L, */
+};
+
+/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
+ * where z = 2(x-1)/(x+1)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 1.1e-35,
+ * relative peak error spread 1.1e-9
+ */
+static const long double R[6] =
+{
+ 1.418134209872192732479751274970992665513E5L,
+ -8.977257995689735303686582344659576526998E4L,
+ 2.048819892795278657810231591630928516206E4L,
+ -2.024301798136027039250415126250455056397E3L,
+ 8.057002716646055371965756206836056074715E1L,
+ -8.828896441624934385266096344596648080902E-1L
+};
+static const long double S[6] =
+{
+ 1.701761051846631278975701529965589676574E6L,
+ -1.332535117259762928288745111081235577029E6L,
+ 4.001557694070773974936904547424676279307E5L,
+ -5.748542087379434595104154610899551484314E4L,
+ 3.998526750980007367835804959888064681098E3L,
+ -1.186359407982897997337150403816839480438E2L
+/* 1.000000000000000000000000000000000000000E0L, */
+};
+
+static const long double
+/* log2(e) - 1 */
+LOG2EA = 4.4269504088896340735992468100189213742664595E-1L,
+/* sqrt(2)/2 */
+SQRTH = 7.071067811865475244008443621048490392848359E-1L;
+
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+neval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+deval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+
+long double
+__ieee754_log2l (x)
+ long double x;
+{
+ long double z;
+ long double y;
+ int e;
+ int64_t hx, lx;
+
+/* Test for domain */
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+ if (((hx & 0x7fffffffffffffffLL) | (lx & 0x7fffffffffffffffLL)) == 0)
+ return (-1.0L / (x - x));
+ if (hx < 0)
+ return (x - x) / (x - x);
+ if (hx >= 0x7ff0000000000000LL)
+ return (x + x);
+
+/* separate mantissa from exponent */
+
+/* Note, frexp is used so that denormal numbers
+ * will be handled properly.
+ */
+ x = __frexpl (x, &e);
+
+
+/* logarithm using log(x) = z + z**3 P(z)/Q(z),
+ * where z = 2(x-1)/x+1)
+ */
+ if ((e > 2) || (e < -2))
+ {
+ if (x < SQRTH)
+ { /* 2( 2x-1 )/( 2x+1 ) */
+ e -= 1;
+ z = x - 0.5L;
+ y = 0.5L * z + 0.5L;
+ }
+ else
+ { /* 2 (x-1)/(x+1) */
+ z = x - 0.5L;
+ z -= 0.5L;
+ y = 0.5L * x + 0.5L;
+ }
+ x = z / y;
+ z = x * x;
+ y = x * (z * neval (z, R, 5) / deval (z, S, 5));
+ goto done;
+ }
+
+
+/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
+
+ if (x < SQRTH)
+ {
+ e -= 1;
+ x = 2.0 * x - 1.0L; /* 2x - 1 */
+ }
+ else
+ {
+ x = x - 1.0L;
+ }
+ z = x * x;
+ y = x * (z * neval (x, P, 12) / deval (x, Q, 11));
+ y = y - 0.5 * z;
+
+done:
+
+/* Multiply log of fraction by log2(e)
+ * and base 2 exponent by 1
+ */
+ z = y * LOG2EA;
+ z += x * LOG2EA;
+ z += y;
+ z += x;
+ z += e;
+ return (z);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_logl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_logl.c
new file mode 100644
index 000000000..aa5fc3740
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_logl.c
@@ -0,0 +1,281 @@
+/* logll.c
+ *
+ * Natural logarithm for 128-bit long double precision.
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, logl();
+ *
+ * y = logl( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base e (2.718...) logarithm of x.
+ *
+ * The argument is separated into its exponent and fractional
+ * parts. Use of a lookup table increases the speed of the routine.
+ * The program uses logarithms tabulated at intervals of 1/128 to
+ * cover the domain from approximately 0.7 to 1.4.
+ *
+ * On the interval [-1/128, +1/128] the logarithm of 1+x is approximated by
+ * log(1+x) = x - 0.5 x^2 + x^3 P(x) .
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE 0.875, 1.125 100000 1.2e-34 4.1e-35
+ * IEEE 0.125, 8 100000 1.2e-34 4.1e-35
+ *
+ *
+ * WARNING:
+ *
+ * This program uses integer operations on bit fields of floating-point
+ * numbers. It does not work with data structures other than the
+ * structure assumed.
+ *
+ */
+
+/* Copyright 2001 by Stephen L. Moshier <moshier@na-net.ornl.gov>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "math_private.h"
+
+/* log(1+x) = x - .5 x^2 + x^3 l(x)
+ -.0078125 <= x <= +.0078125
+ peak relative error 1.2e-37 */
+static const long double
+l3 = 3.333333333333333333333333333333336096926E-1L,
+l4 = -2.499999999999999999999999999486853077002E-1L,
+l5 = 1.999999999999999999999999998515277861905E-1L,
+l6 = -1.666666666666666666666798448356171665678E-1L,
+l7 = 1.428571428571428571428808945895490721564E-1L,
+l8 = -1.249999999999999987884655626377588149000E-1L,
+l9 = 1.111111111111111093947834982832456459186E-1L,
+l10 = -1.000000000000532974938900317952530453248E-1L,
+l11 = 9.090909090915566247008015301349979892689E-2L,
+l12 = -8.333333211818065121250921925397567745734E-2L,
+l13 = 7.692307559897661630807048686258659316091E-2L,
+l14 = -7.144242754190814657241902218399056829264E-2L,
+l15 = 6.668057591071739754844678883223432347481E-2L;
+
+/* Lookup table of ln(t) - (t-1)
+ t = 0.5 + (k+26)/128)
+ k = 0, ..., 91 */
+static const long double logtbl[92] = {
+-5.5345593589352099112142921677820359632418E-2L,
+-5.2108257402767124761784665198737642086148E-2L,
+-4.8991686870576856279407775480686721935120E-2L,
+-4.5993270766361228596215288742353061431071E-2L,
+-4.3110481649613269682442058976885699556950E-2L,
+-4.0340872319076331310838085093194799765520E-2L,
+-3.7682072451780927439219005993827431503510E-2L,
+-3.5131785416234343803903228503274262719586E-2L,
+-3.2687785249045246292687241862699949178831E-2L,
+-3.0347913785027239068190798397055267411813E-2L,
+-2.8110077931525797884641940838507561326298E-2L,
+-2.5972247078357715036426583294246819637618E-2L,
+-2.3932450635346084858612873953407168217307E-2L,
+-2.1988775689981395152022535153795155900240E-2L,
+-2.0139364778244501615441044267387667496733E-2L,
+-1.8382413762093794819267536615342902718324E-2L,
+-1.6716169807550022358923589720001638093023E-2L,
+-1.5138929457710992616226033183958974965355E-2L,
+-1.3649036795397472900424896523305726435029E-2L,
+-1.2244881690473465543308397998034325468152E-2L,
+-1.0924898127200937840689817557742469105693E-2L,
+-9.6875626072830301572839422532631079809328E-3L,
+-8.5313926245226231463436209313499745894157E-3L,
+-7.4549452072765973384933565912143044991706E-3L,
+-6.4568155251217050991200599386801665681310E-3L,
+-5.5356355563671005131126851708522185605193E-3L,
+-4.6900728132525199028885749289712348829878E-3L,
+-3.9188291218610470766469347968659624282519E-3L,
+-3.2206394539524058873423550293617843896540E-3L,
+-2.5942708080877805657374888909297113032132E-3L,
+-2.0385211375711716729239156839929281289086E-3L,
+-1.5522183228760777967376942769773768850872E-3L,
+-1.1342191863606077520036253234446621373191E-3L,
+-7.8340854719967065861624024730268350459991E-4L,
+-4.9869831458030115699628274852562992756174E-4L,
+-2.7902661731604211834685052867305795169688E-4L,
+-1.2335696813916860754951146082826952093496E-4L,
+-3.0677461025892873184042490943581654591817E-5L,
+#define ZERO logtbl[38]
+ 0.0000000000000000000000000000000000000000E0L,
+-3.0359557945051052537099938863236321874198E-5L,
+-1.2081346403474584914595395755316412213151E-4L,
+-2.7044071846562177120083903771008342059094E-4L,
+-4.7834133324631162897179240322783590830326E-4L,
+-7.4363569786340080624467487620270965403695E-4L,
+-1.0654639687057968333207323853366578860679E-3L,
+-1.4429854811877171341298062134712230604279E-3L,
+-1.8753781835651574193938679595797367137975E-3L,
+-2.3618380914922506054347222273705859653658E-3L,
+-2.9015787624124743013946600163375853631299E-3L,
+-3.4938307889254087318399313316921940859043E-3L,
+-4.1378413103128673800485306215154712148146E-3L,
+-4.8328735414488877044289435125365629849599E-3L,
+-5.5782063183564351739381962360253116934243E-3L,
+-6.3731336597098858051938306767880719015261E-3L,
+-7.2169643436165454612058905294782949315193E-3L,
+-8.1090214990427641365934846191367315083867E-3L,
+-9.0486422112807274112838713105168375482480E-3L,
+-1.0035177140880864314674126398350812606841E-2L,
+-1.1067990155502102718064936259435676477423E-2L,
+-1.2146457974158024928196575103115488672416E-2L,
+-1.3269969823361415906628825374158424754308E-2L,
+-1.4437927104692837124388550722759686270765E-2L,
+-1.5649743073340777659901053944852735064621E-2L,
+-1.6904842527181702880599758489058031645317E-2L,
+-1.8202661505988007336096407340750378994209E-2L,
+-1.9542647000370545390701192438691126552961E-2L,
+-2.0924256670080119637427928803038530924742E-2L,
+-2.2346958571309108496179613803760727786257E-2L,
+-2.3810230892650362330447187267648486279460E-2L,
+-2.5313561699385640380910474255652501521033E-2L,
+-2.6856448685790244233704909690165496625399E-2L,
+-2.8438398935154170008519274953860128449036E-2L,
+-3.0058928687233090922411781058956589863039E-2L,
+-3.1717563112854831855692484086486099896614E-2L,
+-3.3413836095418743219397234253475252001090E-2L,
+-3.5147290019036555862676702093393332533702E-2L,
+-3.6917475563073933027920505457688955423688E-2L,
+-3.8723951502862058660874073462456610731178E-2L,
+-4.0566284516358241168330505467000838017425E-2L,
+-4.2444048996543693813649967076598766917965E-2L,
+-4.4356826869355401653098777649745233339196E-2L,
+-4.6304207416957323121106944474331029996141E-2L,
+-4.8285787106164123613318093945035804818364E-2L,
+-5.0301169421838218987124461766244507342648E-2L,
+-5.2349964705088137924875459464622098310997E-2L,
+-5.4431789996103111613753440311680967840214E-2L,
+-5.6546268881465384189752786409400404404794E-2L,
+-5.8693031345788023909329239565012647817664E-2L,
+-6.0871713627532018185577188079210189048340E-2L,
+-6.3081958078862169742820420185833800925568E-2L,
+-6.5323413029406789694910800219643791556918E-2L,
+-6.7595732653791419081537811574227049288168E-2L
+};
+
+/* ln(2) = ln2a + ln2b with extended precision. */
+static const long double
+ ln2a = 6.93145751953125e-1L,
+ ln2b = 1.4286068203094172321214581765680755001344E-6L;
+
+long double
+__ieee754_logl(long double x)
+{
+ long double z, y, w;
+ ieee854_long_double_shape_type u, t;
+ unsigned int m;
+ int k, e;
+
+ u.value = x;
+ m = u.parts32.w0;
+
+ /* Check for IEEE special cases. */
+ k = m & 0x7fffffff;
+ /* log(0) = -infinity. */
+ if ((k | u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) == 0)
+ {
+ return -0.5L / ZERO;
+ }
+ /* log ( x < 0 ) = NaN */
+ if (m & 0x80000000)
+ {
+ return (x - x) / ZERO;
+ }
+ /* log (infinity or NaN) */
+ if (k >= 0x7ff00000)
+ {
+ return x + x;
+ }
+
+ /* On this interval the table is not used due to cancellation error. */
+ if ((x <= 1.0078125L) && (x >= 0.9921875L))
+ {
+ z = x - 1.0L;
+ k = 64;
+ t.value = 1.0L;
+ e = 0;
+ }
+ else
+ {
+ /* Extract exponent and reduce domain to 0.703125 <= u < 1.40625 */
+ unsigned int w0;
+ e = (int) (m >> 20) - (int) 0x3fe;
+ m &= 0xfffff;
+ w0 = m | 0x3fe00000;
+ m |= 0x100000;
+ /* Find lookup table index k from high order bits of the significand. */
+ if (m < 0x168000)
+ {
+ k = (m - 0xff000) >> 13;
+ /* t is the argument 0.5 + (k+26)/128
+ of the nearest item to u in the lookup table. */
+ t.parts32.w0 = 0x3ff00000 + (k << 13);
+ t.parts32.w1 = 0;
+ t.parts32.w2 = 0;
+ t.parts32.w3 = 0;
+ w0 += 0x100000;
+ e -= 1;
+ k += 64;
+ }
+ else
+ {
+ k = (m - 0xfe000) >> 14;
+ t.parts32.w0 = 0x3fe00000 + (k << 14);
+ t.parts32.w1 = 0;
+ t.parts32.w2 = 0;
+ t.parts32.w3 = 0;
+ }
+ u.value = __scalbnl (u.value, ((int) ((w0 - u.parts32.w0) * 2)) >> 21);
+ /* log(u) = log( t u/t ) = log(t) + log(u/t)
+ log(t) is tabulated in the lookup table.
+ Express log(u/t) = log(1+z), where z = u/t - 1 = (u-t)/t.
+ cf. Cody & Waite. */
+ z = (u.value - t.value) / t.value;
+ }
+ /* Series expansion of log(1+z). */
+ w = z * z;
+ y = ((((((((((((l15 * z
+ + l14) * z
+ + l13) * z
+ + l12) * z
+ + l11) * z
+ + l10) * z
+ + l9) * z
+ + l8) * z
+ + l7) * z
+ + l6) * z
+ + l5) * z
+ + l4) * z
+ + l3) * z * w;
+ y -= 0.5 * w;
+ y += e * ln2b; /* Base 2 exponent offset times ln(2). */
+ y += z;
+ y += logtbl[k-26]; /* log(t) - (t-1) */
+ y += (t.value - 1.0L);
+ y += e * ln2a;
+ return y;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_powl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_powl.c
new file mode 100644
index 000000000..feeaa8ce2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_powl.c
@@ -0,0 +1,441 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* Expansions and modifications for 128-bit long double are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __ieee754_powl(x,y) return x**y
+ *
+ * n
+ * Method: Let x = 2 * (1+f)
+ * 1. Compute and return log2(x) in two pieces:
+ * log2(x) = w1 + w2,
+ * where w1 has 113-53 = 60 bit trailing zeros.
+ * 2. Perform y*log2(x) = n+y' by simulating muti-precision
+ * arithmetic, where |y'|<=0.5.
+ * 3. Return x**y = 2**n*exp(y'*log2)
+ *
+ * Special cases:
+ * 1. (anything) ** 0 is 1
+ * 2. (anything) ** 1 is itself
+ * 3. (anything) ** NAN is NAN
+ * 4. NAN ** (anything except 0) is NAN
+ * 5. +-(|x| > 1) ** +INF is +INF
+ * 6. +-(|x| > 1) ** -INF is +0
+ * 7. +-(|x| < 1) ** +INF is +0
+ * 8. +-(|x| < 1) ** -INF is +INF
+ * 9. +-1 ** +-INF is NAN
+ * 10. +0 ** (+anything except 0, NAN) is +0
+ * 11. -0 ** (+anything except 0, NAN, odd integer) is +0
+ * 12. +0 ** (-anything except 0, NAN) is +INF
+ * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
+ * 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
+ * 15. +INF ** (+anything except 0,NAN) is +INF
+ * 16. +INF ** (-anything except 0,NAN) is +0
+ * 17. -INF ** (anything) = -0 ** (-anything)
+ * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
+ * 19. (-anything except 0 and inf) ** (non-integer) is NAN
+ *
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+static const long double bp[] = {
+ 1.0L,
+ 1.5L,
+};
+
+/* log_2(1.5) */
+static const long double dp_h[] = {
+ 0.0,
+ 5.8496250072115607565592654282227158546448E-1L
+};
+
+/* Low part of log_2(1.5) */
+static const long double dp_l[] = {
+ 0.0,
+ 1.0579781240112554492329533686862998106046E-16L
+};
+
+static const long double zero = 0.0L,
+ one = 1.0L,
+ two = 2.0L,
+ two113 = 1.0384593717069655257060992658440192E34L,
+ huge = 1.0e3000L,
+ tiny = 1.0e-3000L;
+
+/* 3/2 log x = 3 z + z^3 + z^3 (z^2 R(z^2))
+ z = (x-1)/(x+1)
+ 1 <= x <= 1.25
+ Peak relative error 2.3e-37 */
+static const long double LN[] =
+{
+ -3.0779177200290054398792536829702930623200E1L,
+ 6.5135778082209159921251824580292116201640E1L,
+ -4.6312921812152436921591152809994014413540E1L,
+ 1.2510208195629420304615674658258363295208E1L,
+ -9.9266909031921425609179910128531667336670E-1L
+};
+static const long double LD[] =
+{
+ -5.129862866715009066465422805058933131960E1L,
+ 1.452015077564081884387441590064272782044E2L,
+ -1.524043275549860505277434040464085593165E2L,
+ 7.236063513651544224319663428634139768808E1L,
+ -1.494198912340228235853027849917095580053E1L
+ /* 1.0E0 */
+};
+
+/* exp(x) = 1 + x - x / (1 - 2 / (x - x^2 R(x^2)))
+ 0 <= x <= 0.5
+ Peak relative error 5.7e-38 */
+static const long double PN[] =
+{
+ 5.081801691915377692446852383385968225675E8L,
+ 9.360895299872484512023336636427675327355E6L,
+ 4.213701282274196030811629773097579432957E4L,
+ 5.201006511142748908655720086041570288182E1L,
+ 9.088368420359444263703202925095675982530E-3L,
+};
+static const long double PD[] =
+{
+ 3.049081015149226615468111430031590411682E9L,
+ 1.069833887183886839966085436512368982758E8L,
+ 8.259257717868875207333991924545445705394E5L,
+ 1.872583833284143212651746812884298360922E3L,
+ /* 1.0E0 */
+};
+
+static const long double
+ /* ln 2 */
+ lg2 = 6.9314718055994530941723212145817656807550E-1L,
+ lg2_h = 6.9314718055994528622676398299518041312695E-1L,
+ lg2_l = 2.3190468138462996154948554638754786504121E-17L,
+ ovt = 8.0085662595372944372e-0017L,
+ /* 2/(3*log(2)) */
+ cp = 9.6179669392597560490661645400126142495110E-1L,
+ cp_h = 9.6179669392597555432899980587535537779331E-1L,
+ cp_l = 5.0577616648125906047157785230014751039424E-17L;
+
+#ifdef __STDC__
+long double
+__ieee754_powl (long double x, long double y)
+#else
+long double
+__ieee754_powl (x, y)
+ long double x, y;
+#endif
+{
+ long double z, ax, z_h, z_l, p_h, p_l;
+ long double y1, t1, t2, r, s, t, u, v, w;
+ long double s2, s_h, s_l, t_h, t_l;
+ int32_t i, j, k, yisint, n;
+ u_int32_t ix, iy;
+ int32_t hx, hy;
+ ieee854_long_double_shape_type o, p, q;
+
+ p.value = x;
+ hx = p.parts32.w0;
+ ix = hx & 0x7fffffff;
+
+ q.value = y;
+ hy = q.parts32.w0;
+ iy = hy & 0x7fffffff;
+
+
+ /* y==zero: x**0 = 1 */
+ if ((iy | q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) == 0)
+ return one;
+
+ /* 1.0**y = 1; -1.0**+-Inf = 1 */
+ if (x == one)
+ return one;
+ if (x == -1.0L && iy == 0x7ff00000
+ && (q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) == 0)
+ return one;
+
+ /* +-NaN return x+y */
+ if ((ix > 0x7ff00000)
+ || ((ix == 0x7ff00000)
+ && ((p.parts32.w1 | (p.parts32.w2 & 0x7fffffff) | p.parts32.w3) != 0))
+ || (iy > 0x7ff00000)
+ || ((iy == 0x7ff00000)
+ && ((q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) != 0)))
+ return x + y;
+
+ /* determine if y is an odd int when x < 0
+ * yisint = 0 ... y is not an integer
+ * yisint = 1 ... y is an odd int
+ * yisint = 2 ... y is an even int
+ */
+ yisint = 0;
+ if (hx < 0)
+ {
+ if ((q.parts32.w2 & 0x7fffffff) >= 0x43400000) /* Low part >= 2^53 */
+ yisint = 2; /* even integer y */
+ else if (iy >= 0x3ff00000) /* 1.0 */
+ {
+ if (__floorl (y) == y)
+ {
+ z = 0.5 * y;
+ if (__floorl (z) == z)
+ yisint = 2;
+ else
+ yisint = 1;
+ }
+ }
+ }
+
+ /* special value of y */
+ if ((q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) == 0)
+ {
+ if (iy == 0x7ff00000 && q.parts32.w1 == 0) /* y is +-inf */
+ {
+ if (((ix - 0x3ff00000) | p.parts32.w1
+ | (p.parts32.w2 & 0x7fffffff) | p.parts32.w3) == 0)
+ return y - y; /* inf**+-1 is NaN */
+ else if (ix > 0x3ff00000 || fabsl (x) > 1.0L)
+ /* (|x|>1)**+-inf = inf,0 */
+ return (hy >= 0) ? y : zero;
+ else
+ /* (|x|<1)**-,+inf = inf,0 */
+ return (hy < 0) ? -y : zero;
+ }
+ if (iy == 0x3ff00000)
+ { /* y is +-1 */
+ if (hy < 0)
+ return one / x;
+ else
+ return x;
+ }
+ if (hy == 0x40000000)
+ return x * x; /* y is 2 */
+ if (hy == 0x3fe00000)
+ { /* y is 0.5 */
+ if (hx >= 0) /* x >= +0 */
+ return __ieee754_sqrtl (x);
+ }
+ }
+
+ ax = fabsl (x);
+ /* special value of x */
+ if ((p.parts32.w1 | (p.parts32.w2 & 0x7fffffff) | p.parts32.w3) == 0)
+ {
+ if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000)
+ {
+ z = ax; /*x is +-0,+-inf,+-1 */
+ if (hy < 0)
+ z = one / z; /* z = (1/|x|) */
+ if (hx < 0)
+ {
+ if (((ix - 0x3ff00000) | yisint) == 0)
+ {
+ z = (z - z) / (z - z); /* (-1)**non-int is NaN */
+ }
+ else if (yisint == 1)
+ z = -z; /* (x<0)**odd = -(|x|**odd) */
+ }
+ return z;
+ }
+ }
+
+ /* (x<0)**(non-int) is NaN */
+ if (((((u_int32_t) hx >> 31) - 1) | yisint) == 0)
+ return (x - x) / (x - x);
+
+ /* |y| is huge.
+ 2^-16495 = 1/2 of smallest representable value.
+ If (1 - 1/131072)^y underflows, y > 1.4986e9 */
+ if (iy > 0x41d654b0)
+ {
+ /* if (1 - 2^-113)^y underflows, y > 1.1873e38 */
+ if (iy > 0x47d654b0)
+ {
+ if (ix <= 0x3fefffff)
+ return (hy < 0) ? huge * huge : tiny * tiny;
+ if (ix >= 0x3ff00000)
+ return (hy > 0) ? huge * huge : tiny * tiny;
+ }
+ /* over/underflow if x is not close to one */
+ if (ix < 0x3fefffff)
+ return (hy < 0) ? huge * huge : tiny * tiny;
+ if (ix > 0x3ff00000)
+ return (hy > 0) ? huge * huge : tiny * tiny;
+ }
+
+ n = 0;
+ /* take care subnormal number */
+ if (ix < 0x00100000)
+ {
+ ax *= two113;
+ n -= 113;
+ o.value = ax;
+ ix = o.parts32.w0;
+ }
+ n += ((ix) >> 20) - 0x3ff;
+ j = ix & 0x000fffff;
+ /* determine interval */
+ ix = j | 0x3ff00000; /* normalize ix */
+ if (j <= 0x39880)
+ k = 0; /* |x|<sqrt(3/2) */
+ else if (j < 0xbb670)
+ k = 1; /* |x|<sqrt(3) */
+ else
+ {
+ k = 0;
+ n += 1;
+ ix -= 0x00100000;
+ }
+
+ o.value = ax;
+ o.value = __scalbnl (o.value, ((int) ((ix - o.parts32.w0) * 2)) >> 21);
+ ax = o.value;
+
+ /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+ u = ax - bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
+ v = one / (ax + bp[k]);
+ s = u * v;
+ s_h = s;
+
+ o.value = s_h;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xffff8000;
+ s_h = o.value;
+ /* t_h=ax+bp[k] High */
+ t_h = ax + bp[k];
+ o.value = t_h;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xffff8000;
+ t_h = o.value;
+ t_l = ax - (t_h - bp[k]);
+ s_l = v * ((u - s_h * t_h) - s_h * t_l);
+ /* compute log(ax) */
+ s2 = s * s;
+ u = LN[0] + s2 * (LN[1] + s2 * (LN[2] + s2 * (LN[3] + s2 * LN[4])));
+ v = LD[0] + s2 * (LD[1] + s2 * (LD[2] + s2 * (LD[3] + s2 * (LD[4] + s2))));
+ r = s2 * s2 * u / v;
+ r += s_l * (s_h + s);
+ s2 = s_h * s_h;
+ t_h = 3.0 + s2 + r;
+ o.value = t_h;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xffff8000;
+ t_h = o.value;
+ t_l = r - ((t_h - 3.0) - s2);
+ /* u+v = s*(1+...) */
+ u = s_h * t_h;
+ v = s_l * t_h + t_l * s;
+ /* 2/(3log2)*(s+...) */
+ p_h = u + v;
+ o.value = p_h;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xffff8000;
+ p_h = o.value;
+ p_l = v - (p_h - u);
+ z_h = cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */
+ z_l = cp_l * p_h + p_l * cp + dp_l[k];
+ /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+ t = (long double) n;
+ t1 = (((z_h + z_l) + dp_h[k]) + t);
+ o.value = t1;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xffff8000;
+ t1 = o.value;
+ t2 = z_l - (((t1 - t) - dp_h[k]) - z_h);
+
+ /* s (sign of result -ve**odd) = -1 else = 1 */
+ s = one;
+ if (((((u_int32_t) hx >> 31) - 1) | (yisint - 1)) == 0)
+ s = -one; /* (-ve)**(odd int) */
+
+ /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+ y1 = y;
+ o.value = y1;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xffff8000;
+ y1 = o.value;
+ p_l = (y - y1) * t1 + y * t2;
+ p_h = y1 * t1;
+ z = p_l + p_h;
+ o.value = z;
+ j = o.parts32.w0;
+ if (j >= 0x40d00000) /* z >= 16384 */
+ {
+ /* if z > 16384 */
+ if (((j - 0x40d00000) | o.parts32.w1
+ | (o.parts32.w2 & 0x7fffffff) | o.parts32.w3) != 0)
+ return s * huge * huge; /* overflow */
+ else
+ {
+ if (p_l + ovt > z - p_h)
+ return s * huge * huge; /* overflow */
+ }
+ }
+ else if ((j & 0x7fffffff) >= 0x40d01b90) /* z <= -16495 */
+ {
+ /* z < -16495 */
+ if (((j - 0xc0d01bc0) | o.parts32.w1
+ | (o.parts32.w2 & 0x7fffffff) | o.parts32.w3) != 0)
+ return s * tiny * tiny; /* underflow */
+ else
+ {
+ if (p_l <= z - p_h)
+ return s * tiny * tiny; /* underflow */
+ }
+ }
+ /* compute 2**(p_h+p_l) */
+ i = j & 0x7fffffff;
+ k = (i >> 20) - 0x3ff;
+ n = 0;
+ if (i > 0x3fe00000)
+ { /* if |z| > 0.5, set n = [z+0.5] */
+ n = __floorl (z + 0.5L);
+ t = n;
+ p_h -= t;
+ }
+ t = p_l + p_h;
+ o.value = t;
+ o.parts32.w3 = 0;
+ o.parts32.w2 &= 0xffff8000;
+ t = o.value;
+ u = t * lg2_h;
+ v = (p_l - (t - p_h)) * lg2 + t * lg2_l;
+ z = u + v;
+ w = v - (z - u);
+ /* exp(z) */
+ t = z * z;
+ u = PN[0] + t * (PN[1] + t * (PN[2] + t * (PN[3] + t * PN[4])));
+ v = PD[0] + t * (PD[1] + t * (PD[2] + t * (PD[3] + t)));
+ t1 = z - t * u / v;
+ r = (z * t1) / (t1 - two) - (w + z * w);
+ z = one - (r - z);
+ z = __scalbnl (z, n);
+ return s * z;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c
new file mode 100644
index 000000000..8b1c976f3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c
@@ -0,0 +1,278 @@
+/* Quad-precision floating point argument reduction.
+ Copyright (C) 1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+#include <ieee754.h>
+
+/*
+ * Table of constants for 2/pi, 5628 hexadecimal digits of 2/pi
+ */
+static const int32_t two_over_pi[] = {
+0xa2f983, 0x6e4e44, 0x1529fc, 0x2757d1, 0xf534dd, 0xc0db62,
+0x95993c, 0x439041, 0xfe5163, 0xabdebb, 0xc561b7, 0x246e3a,
+0x424dd2, 0xe00649, 0x2eea09, 0xd1921c, 0xfe1deb, 0x1cb129,
+0xa73ee8, 0x8235f5, 0x2ebb44, 0x84e99c, 0x7026b4, 0x5f7e41,
+0x3991d6, 0x398353, 0x39f49c, 0x845f8b, 0xbdf928, 0x3b1ff8,
+0x97ffde, 0x05980f, 0xef2f11, 0x8b5a0a, 0x6d1f6d, 0x367ecf,
+0x27cb09, 0xb74f46, 0x3f669e, 0x5fea2d, 0x7527ba, 0xc7ebe5,
+0xf17b3d, 0x0739f7, 0x8a5292, 0xea6bfb, 0x5fb11f, 0x8d5d08,
+0x560330, 0x46fc7b, 0x6babf0, 0xcfbc20, 0x9af436, 0x1da9e3,
+0x91615e, 0xe61b08, 0x659985, 0x5f14a0, 0x68408d, 0xffd880,
+0x4d7327, 0x310606, 0x1556ca, 0x73a8c9, 0x60e27b, 0xc08c6b,
+0x47c419, 0xc367cd, 0xdce809, 0x2a8359, 0xc4768b, 0x961ca6,
+0xddaf44, 0xd15719, 0x053ea5, 0xff0705, 0x3f7e33, 0xe832c2,
+0xde4f98, 0x327dbb, 0xc33d26, 0xef6b1e, 0x5ef89f, 0x3a1f35,
+0xcaf27f, 0x1d87f1, 0x21907c, 0x7c246a, 0xfa6ed5, 0x772d30,
+0x433b15, 0xc614b5, 0x9d19c3, 0xc2c4ad, 0x414d2c, 0x5d000c,
+0x467d86, 0x2d71e3, 0x9ac69b, 0x006233, 0x7cd2b4, 0x97a7b4,
+0xd55537, 0xf63ed7, 0x1810a3, 0xfc764d, 0x2a9d64, 0xabd770,
+0xf87c63, 0x57b07a, 0xe71517, 0x5649c0, 0xd9d63b, 0x3884a7,
+0xcb2324, 0x778ad6, 0x23545a, 0xb91f00, 0x1b0af1, 0xdfce19,
+0xff319f, 0x6a1e66, 0x615799, 0x47fbac, 0xd87f7e, 0xb76522,
+0x89e832, 0x60bfe6, 0xcdc4ef, 0x09366c, 0xd43f5d, 0xd7de16,
+0xde3b58, 0x929bde, 0x2822d2, 0xe88628, 0x4d58e2, 0x32cac6,
+0x16e308, 0xcb7de0, 0x50c017, 0xa71df3, 0x5be018, 0x34132e,
+0x621283, 0x014883, 0x5b8ef5, 0x7fb0ad, 0xf2e91e, 0x434a48,
+0xd36710, 0xd8ddaa, 0x425fae, 0xce616a, 0xa4280a, 0xb499d3,
+0xf2a606, 0x7f775c, 0x83c2a3, 0x883c61, 0x78738a, 0x5a8caf,
+0xbdd76f, 0x63a62d, 0xcbbff4, 0xef818d, 0x67c126, 0x45ca55,
+0x36d9ca, 0xd2a828, 0x8d61c2, 0x77c912, 0x142604, 0x9b4612,
+0xc459c4, 0x44c5c8, 0x91b24d, 0xf31700, 0xad43d4, 0xe54929,
+0x10d5fd, 0xfcbe00, 0xcc941e, 0xeece70, 0xf53e13, 0x80f1ec,
+0xc3e7b3, 0x28f8c7, 0x940593, 0x3e71c1, 0xb3092e, 0xf3450b,
+0x9c1288, 0x7b20ab, 0x9fb52e, 0xc29247, 0x2f327b, 0x6d550c,
+0x90a772, 0x1fe76b, 0x96cb31, 0x4a1679, 0xe27941, 0x89dff4,
+0x9794e8, 0x84e6e2, 0x973199, 0x6bed88, 0x365f5f, 0x0efdbb,
+0xb49a48, 0x6ca467, 0x427271, 0x325d8d, 0xb8159f, 0x09e5bc,
+0x25318d, 0x3974f7, 0x1c0530, 0x010c0d, 0x68084b, 0x58ee2c,
+0x90aa47, 0x02e774, 0x24d6bd, 0xa67df7, 0x72486e, 0xef169f,
+0xa6948e, 0xf691b4, 0x5153d1, 0xf20acf, 0x339820, 0x7e4bf5,
+0x6863b2, 0x5f3edd, 0x035d40, 0x7f8985, 0x295255, 0xc06437,
+0x10d86d, 0x324832, 0x754c5b, 0xd4714e, 0x6e5445, 0xc1090b,
+0x69f52a, 0xd56614, 0x9d0727, 0x50045d, 0xdb3bb4, 0xc576ea,
+0x17f987, 0x7d6b49, 0xba271d, 0x296996, 0xacccc6, 0x5414ad,
+0x6ae290, 0x89d988, 0x50722c, 0xbea404, 0x940777, 0x7030f3,
+0x27fc00, 0xa871ea, 0x49c266, 0x3de064, 0x83dd97, 0x973fa3,
+0xfd9443, 0x8c860d, 0xde4131, 0x9d3992, 0x8c70dd, 0xe7b717,
+0x3bdf08, 0x2b3715, 0xa0805c, 0x93805a, 0x921110, 0xd8e80f,
+0xaf806c, 0x4bffdb, 0x0f9038, 0x761859, 0x15a562, 0xbbcb61,
+0xb989c7, 0xbd4010, 0x04f2d2, 0x277549, 0xf6b6eb, 0xbb22db,
+0xaa140a, 0x2f2689, 0x768364, 0x333b09, 0x1a940e, 0xaa3a51,
+0xc2a31d, 0xaeedaf, 0x12265c, 0x4dc26d, 0x9c7a2d, 0x9756c0,
+0x833f03, 0xf6f009, 0x8c402b, 0x99316d, 0x07b439, 0x15200c,
+0x5bc3d8, 0xc492f5, 0x4badc6, 0xa5ca4e, 0xcd37a7, 0x36a9e6,
+0x9492ab, 0x6842dd, 0xde6319, 0xef8c76, 0x528b68, 0x37dbfc,
+0xaba1ae, 0x3115df, 0xa1ae00, 0xdafb0c, 0x664d64, 0xb705ed,
+0x306529, 0xbf5657, 0x3aff47, 0xb9f96a, 0xf3be75, 0xdf9328,
+0x3080ab, 0xf68c66, 0x15cb04, 0x0622fa, 0x1de4d9, 0xa4b33d,
+0x8f1b57, 0x09cd36, 0xe9424e, 0xa4be13, 0xb52333, 0x1aaaf0,
+0xa8654f, 0xa5c1d2, 0x0f3f0b, 0xcd785b, 0x76f923, 0x048b7b,
+0x721789, 0x53a6c6, 0xe26e6f, 0x00ebef, 0x584a9b, 0xb7dac4,
+0xba66aa, 0xcfcf76, 0x1d02d1, 0x2df1b1, 0xc1998c, 0x77adc3,
+0xda4886, 0xa05df7, 0xf480c6, 0x2ff0ac, 0x9aecdd, 0xbc5c3f,
+0x6dded0, 0x1fc790, 0xb6db2a, 0x3a25a3, 0x9aaf00, 0x9353ad,
+0x0457b6, 0xb42d29, 0x7e804b, 0xa707da, 0x0eaa76, 0xa1597b,
+0x2a1216, 0x2db7dc, 0xfde5fa, 0xfedb89, 0xfdbe89, 0x6c76e4,
+0xfca906, 0x70803e, 0x156e85, 0xff87fd, 0x073e28, 0x336761,
+0x86182a, 0xeabd4d, 0xafe7b3, 0x6e6d8f, 0x396795, 0x5bbf31,
+0x48d784, 0x16df30, 0x432dc7, 0x356125, 0xce70c9, 0xb8cb30,
+0xfd6cbf, 0xa200a4, 0xe46c05, 0xa0dd5a, 0x476f21, 0xd21262,
+0x845cb9, 0x496170, 0xe0566b, 0x015299, 0x375550, 0xb7d51e,
+0xc4f133, 0x5f6e13, 0xe4305d, 0xa92e85, 0xc3b21d, 0x3632a1,
+0xa4b708, 0xd4b1ea, 0x21f716, 0xe4698f, 0x77ff27, 0x80030c,
+0x2d408d, 0xa0cd4f, 0x99a520, 0xd3a2b3, 0x0a5d2f, 0x42f9b4,
+0xcbda11, 0xd0be7d, 0xc1db9b, 0xbd17ab, 0x81a2ca, 0x5c6a08,
+0x17552e, 0x550027, 0xf0147f, 0x8607e1, 0x640b14, 0x8d4196,
+0xdebe87, 0x2afdda, 0xb6256b, 0x34897b, 0xfef305, 0x9ebfb9,
+0x4f6a68, 0xa82a4a, 0x5ac44f, 0xbcf82d, 0x985ad7, 0x95c7f4,
+0x8d4d0d, 0xa63a20, 0x5f57a4, 0xb13f14, 0x953880, 0x0120cc,
+0x86dd71, 0xb6dec9, 0xf560bf, 0x11654d, 0x6b0701, 0xacb08c,
+0xd0c0b2, 0x485551, 0x0efb1e, 0xc37295, 0x3b06a3, 0x3540c0,
+0x7bdc06, 0xcc45e0, 0xfa294e, 0xc8cad6, 0x41f3e8, 0xde647c,
+0xd8649b, 0x31bed9, 0xc397a4, 0xd45877, 0xc5e369, 0x13daf0,
+0x3c3aba, 0x461846, 0x5f7555, 0xf5bdd2, 0xc6926e, 0x5d2eac,
+0xed440e, 0x423e1c, 0x87c461, 0xe9fd29, 0xf3d6e7, 0xca7c22,
+0x35916f, 0xc5e008, 0x8dd7ff, 0xe26a6e, 0xc6fdb0, 0xc10893,
+0x745d7c, 0xb2ad6b, 0x9d6ecd, 0x7b723e, 0x6a11c6, 0xa9cff7,
+0xdf7329, 0xbac9b5, 0x5100b7, 0x0db2e2, 0x24ba74, 0x607de5,
+0x8ad874, 0x2c150d, 0x0c1881, 0x94667e, 0x162901, 0x767a9f,
+0xbefdfd, 0xef4556, 0x367ed9, 0x13d9ec, 0xb9ba8b, 0xfc97c4,
+0x27a831, 0xc36ef1, 0x36c594, 0x56a8d8, 0xb5a8b4, 0x0ecccf,
+0x2d8912, 0x34576f, 0x89562c, 0xe3ce99, 0xb920d6, 0xaa5e6b,
+0x9c2a3e, 0xcc5f11, 0x4a0bfd, 0xfbf4e1, 0x6d3b8e, 0x2c86e2,
+0x84d4e9, 0xa9b4fc, 0xd1eeef, 0xc9352e, 0x61392f, 0x442138,
+0xc8d91b, 0x0afc81, 0x6a4afb, 0xd81c2f, 0x84b453, 0x8c994e,
+0xcc2254, 0xdc552a, 0xd6c6c0, 0x96190b, 0xb8701a, 0x649569,
+0x605a26, 0xee523f, 0x0f117f, 0x11b5f4, 0xf5cbfc, 0x2dbc34,
+0xeebc34, 0xcc5de8, 0x605edd, 0x9b8e67, 0xef3392, 0xb817c9,
+0x9b5861, 0xbc57e1, 0xc68351, 0x103ed8, 0x4871dd, 0xdd1c2d,
+0xa118af, 0x462c21, 0xd7f359, 0x987ad9, 0xc0549e, 0xfa864f,
+0xfc0656, 0xae79e5, 0x362289, 0x22ad38, 0xdc9367, 0xaae855,
+0x382682, 0x9be7ca, 0xa40d51, 0xb13399, 0x0ed7a9, 0x480569,
+0xf0b265, 0xa7887f, 0x974c88, 0x36d1f9, 0xb39221, 0x4a827b,
+0x21cf98, 0xdc9f40, 0x5547dc, 0x3a74e1, 0x42eb67, 0xdf9dfe,
+0x5fd45e, 0xa4677b, 0x7aacba, 0xa2f655, 0x23882b, 0x55ba41,
+0x086e59, 0x862a21, 0x834739, 0xe6e389, 0xd49ee5, 0x40fb49,
+0xe956ff, 0xca0f1c, 0x8a59c5, 0x2bfa94, 0xc5c1d3, 0xcfc50f,
+0xae5adb, 0x86c547, 0x624385, 0x3b8621, 0x94792c, 0x876110,
+0x7b4c2a, 0x1a2c80, 0x12bf43, 0x902688, 0x893c78, 0xe4c4a8,
+0x7bdbe5, 0xc23ac4, 0xeaf426, 0x8a67f7, 0xbf920d, 0x2ba365,
+0xb1933d, 0x0b7cbd, 0xdc51a4, 0x63dd27, 0xdde169, 0x19949a,
+0x9529a8, 0x28ce68, 0xb4ed09, 0x209f44, 0xca984e, 0x638270,
+0x237c7e, 0x32b90f, 0x8ef5a7, 0xe75614, 0x08f121, 0x2a9db5,
+0x4d7e6f, 0x5119a5, 0xabf9b5, 0xd6df82, 0x61dd96, 0x023616,
+0x9f3ac4, 0xa1a283, 0x6ded72, 0x7a8d39, 0xa9b882, 0x5c326b,
+0x5b2746, 0xed3400, 0x7700d2, 0x55f4fc, 0x4d5901, 0x8071e0,
+0xe13f89, 0xb295f3, 0x64a8f1, 0xaea74b, 0x38fc4c, 0xeab2bb,
+0x47270b, 0xabc3a7, 0x34ba60, 0x52dd34, 0xf8563a, 0xeb7e8a,
+0x31bb36, 0x5895b7, 0x47f7a9, 0x94c3aa, 0xd39225, 0x1e7f3e,
+0xd8974e, 0xbba94f, 0xd8ae01, 0xe661b4, 0x393d8e, 0xa523aa,
+0x33068e, 0x1633b5, 0x3bb188, 0x1d3a9d, 0x4013d0, 0xcc1be5,
+0xf862e7, 0x3bf28f, 0x39b5bf, 0x0bc235, 0x22747e, 0xa247c0,
+0xd52d1f, 0x19add3, 0x9094df, 0x9311d0, 0xb42b25, 0x496db2,
+0xe264b2, 0x5ef135, 0x3bc6a4, 0x1a4ad0, 0xaac92e, 0x64e886,
+0x573091, 0x982cfb, 0x311b1a, 0x08728b, 0xbdcee1, 0x60e142,
+0xeb641d, 0xd0bba3, 0xe559d4, 0x597b8c, 0x2a4483, 0xf332ba,
+0xf84867, 0x2c8d1b, 0x2fa9b0, 0x50f3dd, 0xf9f573, 0xdb61b4,
+0xfe233e, 0x6c41a6, 0xeea318, 0x775a26, 0xbc5e5c, 0xcea708,
+0x94dc57, 0xe20196, 0xf1e839, 0xbe4851, 0x5d2d2f, 0x4e9555,
+0xd96ec2, 0xe7d755, 0x6304e0, 0xc02e0e, 0xfc40a0, 0xbbf9b3,
+0x7125a7, 0x222dfb, 0xf619d8, 0x838c1c, 0x6619e6, 0xb20d55,
+0xbb5137, 0x79e809, 0xaf9149, 0x0d73de, 0x0b0da5, 0xce7f58,
+0xac1934, 0x724667, 0x7a1a13, 0x9e26bc, 0x4555e7, 0x585cb5,
+0x711d14, 0x486991, 0x480d60, 0x56adab, 0xd62f64, 0x96ee0c,
+0x212ff3, 0x5d6d88, 0xa67684, 0x95651e, 0xab9e0a, 0x4ddefe,
+0x571010, 0x836a39, 0xf8ea31, 0x9e381d, 0xeac8b1, 0xcac96b,
+0x37f21e, 0xd505e9, 0x984743, 0x9fc56c, 0x0331b7, 0x3b8bf8,
+0x86e56a, 0x8dc343, 0x6230e7, 0x93cfd5, 0x6a8f2d, 0x733005,
+0x1af021, 0xa09fcb, 0x7415a1, 0xd56b23, 0x6ff725, 0x2f4bc7,
+0xb8a591, 0x7fac59, 0x5c55de, 0x212c38, 0xb13296, 0x5cff50,
+0x366262, 0xfa7b16, 0xf4d9a6, 0x2acfe7, 0xf07403, 0xd4d604,
+0x6fd916, 0x31b1bf, 0xcbb450, 0x5bd7c8, 0x0ce194, 0x6bd643,
+0x4fd91c, 0xdf4543, 0x5f3453, 0xe2b5aa, 0xc9aec8, 0x131485,
+0xf9d2bf, 0xbadb9e, 0x76f5b9, 0xaf15cf, 0xca3182, 0x14b56d,
+0xe9fe4d, 0x50fc35, 0xf5aed5, 0xa2d0c1, 0xc96057, 0x192eb6,
+0xe91d92, 0x07d144, 0xaea3c6, 0x343566, 0x26d5b4, 0x3161e2,
+0x37f1a2, 0x209eff, 0x958e23, 0x493798, 0x35f4a6, 0x4bdc02,
+0xc2be13, 0xbe80a0, 0x0b72a3, 0x115c5f, 0x1e1bd1, 0x0db4d3,
+0x869e85, 0x96976b, 0x2ac91f, 0x8a26c2, 0x3070f0, 0x041412,
+0xfc9fa5, 0xf72a38, 0x9c6878, 0xe2aa76, 0x50cfe1, 0x559274,
+0x934e38, 0x0a92f7, 0x5533f0, 0xa63db4, 0x399971, 0xe2b755,
+0xa98a7c, 0x008f19, 0xac54d2, 0x2ea0b4, 0xf5f3e0, 0x60c849,
+0xffd269, 0xae52ce, 0x7a5fdd, 0xe9ce06, 0xfb0ae8, 0xa50cce,
+0xea9d3e, 0x3766dd, 0xb834f5, 0x0da090, 0x846f88, 0x4ae3d5,
+0x099a03, 0x2eae2d, 0xfcb40a, 0xfb9b33, 0xe281dd, 0x1b16ba,
+0xd8c0af, 0xd96b97, 0xb52dc9, 0x9c277f, 0x5951d5, 0x21ccd6,
+0xb6496b, 0x584562, 0xb3baf2, 0xa1a5c4, 0x7ca2cf, 0xa9b93d,
+0x7b7b89, 0x483d38,
+};
+
+static const long double c[] = {
+/* 93 bits of pi/2 */
+#define PI_2_1 c[0]
+ 1.57079632679489661923132169155131424e+00L, /* 3fff921fb54442d18469898cc5100000 */
+
+/* pi/2 - PI_2_1 */
+#define PI_2_1t c[1]
+ 8.84372056613570112025531863263659260e-29L, /* 3fa1c06e0e68948127044533e63a0106 */
+};
+
+int32_t __ieee754_rem_pio2l(long double x, long double *y)
+{
+ long double z, w, t;
+ double tx[8];
+ int exp;
+ int64_t n, ix, hx, ixd;
+ u_int64_t lx, lxd;
+
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+ ix = hx & 0x7fffffffffffffffLL;
+ if (ix <= 0x3fe921fb54442d10LL) /* x in <-pi/4, pi/4> */
+ {
+ y[0] = x;
+ y[1] = 0;
+ return 0;
+ }
+
+ if (ix < 0x4002d97c7f3321d0LL) /* |x| in <pi/4, 3pi/4) */
+ {
+ if (hx > 0)
+ {
+ /* 113 + 93 bit PI is ok */
+ z = x - PI_2_1;
+ y[0] = z - PI_2_1t;
+ y[1] = (z - y[0]) - PI_2_1t;
+ return 1;
+ }
+ else
+ {
+ /* 113 + 93 bit PI is ok */
+ z = x + PI_2_1;
+ y[0] = z + PI_2_1t;
+ y[1] = (z - y[0]) + PI_2_1t;
+ return -1;
+ }
+ }
+
+ if (ix >= 0x7ff0000000000000LL) /* x is +=oo or NaN */
+ {
+ y[0] = x - x;
+ y[1] = y[0];
+ return 0;
+ }
+
+ /* Handle large arguments.
+ We split the 113 bits of the mantissa into 5 24bit integers
+ stored in a double array. */
+ /* Make the IBM extended format 105 bit mantissa look like the ieee854 112
+ bit mantissa so the next operatation will give the correct result. */
+ ldbl_extract_mantissa (&ixd, &lxd, &exp, x);
+ exp = exp - 23;
+ /* This is faster than doing this in floating point, because we
+ have to convert it to integers anyway and like this we can keep
+ both integer and floating point units busy. */
+ tx [0] = (double)(((ixd >> 25) & 0x7fffff) | 0x800000);
+ tx [1] = (double)((ixd >> 1) & 0xffffff);
+ tx [2] = (double)(((ixd << 23) | (lxd >> 41)) & 0xffffff);
+ tx [3] = (double)((lxd >> 17) & 0xffffff);
+ tx [4] = (double)((lxd << 7) & 0xffffff);
+
+ n = __kernel_rem_pio2 (tx, tx + 5, exp, ((lxd << 7) & 0xffffff) ? 5 : 4,
+ 3, two_over_pi);
+
+ /* The result is now stored in 3 double values, we need to convert it into
+ two long double values. */
+ t = (long double) tx [6] + (long double) tx [7];
+ w = (long double) tx [5];
+
+ if (hx >= 0)
+ {
+ y[0] = w + t;
+ y[1] = t - (y[0] - w);
+ return n;
+ }
+ else
+ {
+ y[0] = -(w + t);
+ y[1] = -t - (y[0] + w);
+ return -n;
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c
new file mode 100644
index 000000000..b7fa68f32
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c
@@ -0,0 +1,78 @@
+/* e_fmodl.c -- long double version of e_fmod.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* __ieee754_remainderl(x,p)
+ * Return :
+ * returns x REM p = x - [x/p]*p as if in infinite
+ * precise arithmetic, where [x/p] is the (infinite bit)
+ * integer nearest x/p (in half way case choose the even one).
+ * Method :
+ * Based on fmodl() return x-[x/p]chopped*p exactlp.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double zero = 0.0L;
+#else
+static long double zero = 0.0L;
+#endif
+
+
+#ifdef __STDC__
+ long double __ieee754_remainderl(long double x, long double p)
+#else
+ long double __ieee754_remainderl(x,p)
+ long double x,p;
+#endif
+{
+ int64_t hx,hp;
+ u_int64_t sx,lx,lp;
+ long double p_half;
+
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ GET_LDOUBLE_WORDS64(hp,lp,p);
+ sx = hx&0x8000000000000000ULL;
+ hp &= 0x7fffffffffffffffLL;
+ hx &= 0x7fffffffffffffffLL;
+
+ /* purge off exception values */
+ if((hp|(lp&0x7fffffffffffffff))==0) return (x*p)/(x*p); /* p = 0 */
+ if((hx>=0x7ff0000000000000LL)|| /* x not finite */
+ ((hp>=0x7ff0000000000000LL)&& /* p is NaN */
+ (((hp-0x7ff0000000000000LL)|lp)!=0)))
+ return (x*p)/(x*p);
+
+
+ if (hp<=0x7fdfffffffffffffLL) x = __ieee754_fmodl(x,p+p); /* now x < 2p */
+ if (((hx-hp)|(lx-lp))==0) return zero*x;
+ x = fabsl(x);
+ p = fabsl(p);
+ if (hp<0x0020000000000000LL) {
+ if(x+x>p) {
+ x-=p;
+ if(x+x>=p) x -= p;
+ }
+ } else {
+ p_half = 0.5L*p;
+ if(x>p_half) {
+ x-=p;
+ if(x>=p_half) x -= p;
+ }
+ }
+ GET_LDOUBLE_MSW64(hx,x);
+ SET_LDOUBLE_MSW64(x,hx^sx);
+ return x;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c
new file mode 100644
index 000000000..38ae71d4b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c
@@ -0,0 +1,84 @@
+/*
+ * ====================================================
+ * 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: e_sinh.c,v 1.7 1995/05/10 20:46:13 jtc Exp $";
+#endif
+
+/* __ieee754_sinh(x)
+ * Method :
+ * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+ * 1. Replace x by |x| (sinh(-x) = -sinh(x)).
+ * 2.
+ * E + E/(E+1)
+ * 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x)
+ * 2
+ *
+ * 22 <= x <= lnovft : sinh(x) := exp(x)/2
+ * lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2)
+ * ln2ovft < x : sinh(x) := x*shuge (overflow)
+ *
+ * Special cases:
+ * sinh(x) is |x| if x is +INF, -INF, or NaN.
+ * only sinh(0)=0 is exact for finite x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0, shuge = 1.0e307;
+#else
+static long double one = 1.0, shuge = 1.0e307;
+#endif
+
+#ifdef __STDC__
+ long double __ieee754_sinhl(long double x)
+#else
+ long double __ieee754_sinhl(x)
+ long double x;
+#endif
+{
+ long double t,w,h;
+ int64_t ix,jx;
+
+ /* High word of |x|. */
+ GET_LDOUBLE_MSW64(jx,x);
+ ix = jx&0x7fffffffffffffffLL;
+
+ /* x is INF or NaN */
+ if(ix>=0x7ff0000000000000LL) return x+x;
+
+ h = 0.5;
+ if (jx<0) h = -h;
+ /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
+ if (ix < 0x4036000000000000LL) { /* |x|<22 */
+ if (ix<0x3e20000000000000LL) /* |x|<2**-29 */
+ if(shuge+x>one) return x;/* sinhl(tiny) = tiny with inexact */
+ t = __expm1l(fabsl(x));
+ if(ix<0x3ff0000000000000LL) return h*(2.0*t-t*t/(t+one));
+ return h*(t+t/(t+one));
+ }
+
+ /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
+ if (ix < 0x40862e42fefa39efLL) return h*__ieee754_expl(fabsl(x));
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ if (ix <= 0x408633ce8fb9f87dLL) {
+ w = __ieee754_expl(0.5*fabsl(x));
+ t = h*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, sinh(x) overflow */
+ return x*shuge;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c b/libc/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c
new file mode 100644
index 000000000..1f533cae4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c
@@ -0,0 +1,109 @@
+/*
+ * IBM Accurate Mathematical Library
+ * written by International Business Machines Corp.
+ * Copyright (C) 2001, 2004, 2006 Free Software Foundation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*********************************************************************/
+/* MODULE_NAME: uroot.c */
+/* */
+/* FUNCTION: usqrt */
+/* */
+/* FILES NEEDED: dla.h endian.h mydefs.h uroot.h */
+/* uroot.tbl */
+/* */
+/* An ultimate sqrt routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of square */
+/* root of x. */
+/* Assumption: Machine arithmetic operations are performed in */
+/* round to nearest mode of IEEE 754 standard. */
+/* */
+/*********************************************************************/
+
+#include <math_private.h>
+
+typedef unsigned int int4;
+typedef union {int4 i[4]; long double x; double d[2]; } mynumber;
+
+static const mynumber
+ t512 = {{0x5ff00000, 0x00000000, 0x00000000, 0x00000000 }}, /* 2^512 */
+ tm256 = {{0x2ff00000, 0x00000000, 0x00000000, 0x00000000 }}; /* 2^-256 */
+static const double
+two54 = 1.80143985094819840000e+16, /* 0x4350000000000000 */
+twom54 = 5.55111512312578270212e-17; /* 0x3C90000000000000 */
+
+/*********************************************************************/
+/* An ultimate sqrt routine. Given an IEEE double machine number x */
+/* it computes the correctly rounded (to nearest) value of square */
+/* root of x. */
+/*********************************************************************/
+long double __ieee754_sqrtl(long double x)
+{
+ static const long double big = 134217728.0, big1 = 134217729.0;
+ long double t,s,i;
+ mynumber a,c;
+ int4 k, l, m;
+ int n;
+ double d;
+
+ a.x=x;
+ k=a.i[0] & 0x7fffffff;
+ /*----------------- 2^-1022 <= | x |< 2^1024 -----------------*/
+ if (k>0x000fffff && k<0x7ff00000) {
+ if (x < 0) return (big1-big1)/(big-big);
+ l = (k&0x001fffff)|0x3fe00000;
+ if (((a.i[2] & 0x7fffffff) | a.i[3]) != 0) {
+ n = (int) ((l - k) * 2) >> 21;
+ m = (a.i[2] >> 20) & 0x7ff;
+ if (m == 0) {
+ a.d[1] *= two54;
+ m = ((a.i[2] >> 20) & 0x7ff) - 54;
+ }
+ m += n;
+ if (m > 0)
+ a.i[2] = (a.i[2] & 0x800fffff) | (m << 20);
+ else if (m <= -54) {
+ a.i[2] &= 0x80000000;
+ a.i[3] = 0;
+ } else {
+ m += 54;
+ a.i[2] = (a.i[2] & 0x800fffff) | (m << 20);
+ a.d[1] *= twom54;
+ }
+ }
+ a.i[0] = l;
+ s = a.x;
+ d = __ieee754_sqrt (a.d[0]);
+ c.i[0] = 0x20000000+((k&0x7fe00000)>>1);
+ c.i[1] = 0;
+ c.i[2] = 0;
+ c.i[3] = 0;
+ i = d;
+ t = 0.5L * (i + s / i);
+ i = 0.5L * (t + s / t);
+ return c.x * i;
+ }
+ else {
+ if (k>=0x7ff00000) {
+ if (a.i[0] == 0xfff00000 && a.i[1] == 0)
+ return (big1-big1)/(big-big); /* sqrt (-Inf) = NaN. */
+ return x; /* sqrt (NaN) = NaN, sqrt (+Inf) = +Inf. */
+ }
+ if (x == 0) return x;
+ if (x < 0) return (big1-big1)/(big-big);
+ return tm256.x*__ieee754_sqrtl(x*t512.x);
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/ieee754.h b/libc/sysdeps/ieee754/ldbl-128ibm/ieee754.h
new file mode 100644
index 000000000..94a2091c8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/ieee754.h
@@ -0,0 +1,210 @@
+/* Copyright (C) 1992, 1995, 1996, 1999, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _IEEE754_H
+
+#define _IEEE754_H 1
+#include <features.h>
+
+#include <endian.h>
+
+__BEGIN_DECLS
+
+union ieee754_float
+ {
+ float f;
+
+ /* This is the IEEE 754 single-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int mantissa:23;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int mantissa:23;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int quiet_nan:1;
+ unsigned int mantissa:22;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int mantissa:22;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee_nan;
+ };
+
+#define IEEE754_FLOAT_BIAS 0x7f /* Added to exponent. */
+
+
+union ieee754_double
+ {
+ double d;
+
+ /* This is the IEEE 754 double-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:20;
+ unsigned int mantissa1:32;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:20;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ unsigned int quiet_nan:1;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:19;
+ unsigned int mantissa1:32;
+#else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:19;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+#endif
+ } ieee_nan;
+ };
+
+#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */
+
+
+union ieee854_long_double
+ {
+ long double d;
+
+ /* This is the IEEE 854 quad-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:15;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:16;
+ unsigned int mantissa1:32;
+ unsigned int mantissa2:32;
+ unsigned int mantissa3:32;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa3:32;
+ unsigned int mantissa2:32;
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:16;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:15;
+ unsigned int quiet_nan:1;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:15;
+ unsigned int mantissa1:32;
+ unsigned int mantissa2:32;
+ unsigned int mantissa3:32;
+#else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa3:32;
+ unsigned int mantissa2:32;
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:15;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+#endif
+ } ieee_nan;
+ };
+
+#define IEEE854_LONG_DOUBLE_BIAS 0x3fff /* Added to exponent. */
+
+
+/* IBM extended format for long double.
+
+ Each long double is made up of two IEEE doubles. The value of the
+ long double is the sum of the values of the two parts. The most
+ significant part is required to be the value of the long double
+ rounded to the nearest double, as specified by IEEE. For Inf
+ values, the least significant part is required to be one of +0.0 or
+ -0.0. No other requirements are made; so, for example, 1.0 may be
+ represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a
+ NaN is don't-care. */
+
+union ibm_extended_long_double
+ {
+ long double d;
+ double dd[2];
+
+ /* This is the IBM extended format long double. */
+ struct
+ { /* Big endian. There is no other. */
+
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ /* Together Mantissa0-3 comprise the mantissa. */
+ unsigned int mantissa0:20;
+ unsigned int mantissa1:32;
+
+ unsigned int negative2:1;
+ unsigned int exponent2:11;
+ /* There is an implied 1 here? */
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa2:20;
+ unsigned int mantissa3:32;
+ } ieee;
+ };
+
+#define IBM_EXTENDED_LONG_DOUBLE_BIAS 0x3ff /* Added to exponent. */
+
+__END_DECLS
+
+#endif /* ieee754.h */
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/k_cosl.c b/libc/sysdeps/ieee754/ldbl-128ibm/k_cosl.c
new file mode 100644
index 000000000..b442582b3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/k_cosl.c
@@ -0,0 +1,146 @@
+/* Quad-precision floating point cosine on <-pi/4,pi/4>.
+ Copyright (C) 1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+
+static const long double c[] = {
+#define ONE c[0]
+ 1.00000000000000000000000000000000000E+00L, /* 3fff0000000000000000000000000000 */
+
+/* cos x ~ ONE + x^2 ( SCOS1 + SCOS2 * x^2 + ... + SCOS4 * x^6 + SCOS5 * x^8 )
+ x in <0,1/256> */
+#define SCOS1 c[1]
+#define SCOS2 c[2]
+#define SCOS3 c[3]
+#define SCOS4 c[4]
+#define SCOS5 c[5]
+-5.00000000000000000000000000000000000E-01L, /* bffe0000000000000000000000000000 */
+ 4.16666666666666666666666666556146073E-02L, /* 3ffa5555555555555555555555395023 */
+-1.38888888888888888888309442601939728E-03L, /* bff56c16c16c16c16c16a566e42c0375 */
+ 2.48015873015862382987049502531095061E-05L, /* 3fefa01a01a019ee02dcf7da2d6d5444 */
+-2.75573112601362126593516899592158083E-07L, /* bfe927e4f5dce637cb0b54908754bde0 */
+
+/* cos x ~ ONE + x^2 ( COS1 + COS2 * x^2 + ... + COS7 * x^12 + COS8 * x^14 )
+ x in <0,0.1484375> */
+#define COS1 c[6]
+#define COS2 c[7]
+#define COS3 c[8]
+#define COS4 c[9]
+#define COS5 c[10]
+#define COS6 c[11]
+#define COS7 c[12]
+#define COS8 c[13]
+-4.99999999999999999999999999999999759E-01L, /* bffdfffffffffffffffffffffffffffb */
+ 4.16666666666666666666666666651287795E-02L, /* 3ffa5555555555555555555555516f30 */
+-1.38888888888888888888888742314300284E-03L, /* bff56c16c16c16c16c16c16a463dfd0d */
+ 2.48015873015873015867694002851118210E-05L, /* 3fefa01a01a01a01a0195cebe6f3d3a5 */
+-2.75573192239858811636614709689300351E-07L, /* bfe927e4fb7789f5aa8142a22044b51f */
+ 2.08767569877762248667431926878073669E-09L, /* 3fe21eed8eff881d1e9262d7adff4373 */
+-1.14707451049343817400420280514614892E-11L, /* bfda9397496922a9601ed3d4ca48944b */
+ 4.77810092804389587579843296923533297E-14L, /* 3fd2ae5f8197cbcdcaf7c3fb4523414c */
+
+/* sin x ~ ONE * x + x^3 ( SSIN1 + SSIN2 * x^2 + ... + SSIN4 * x^6 + SSIN5 * x^8 )
+ x in <0,1/256> */
+#define SSIN1 c[14]
+#define SSIN2 c[15]
+#define SSIN3 c[16]
+#define SSIN4 c[17]
+#define SSIN5 c[18]
+-1.66666666666666666666666666666666659E-01L, /* bffc5555555555555555555555555555 */
+ 8.33333333333333333333333333146298442E-03L, /* 3ff81111111111111111111110fe195d */
+-1.98412698412698412697726277416810661E-04L, /* bff2a01a01a01a01a019e7121e080d88 */
+ 2.75573192239848624174178393552189149E-06L, /* 3fec71de3a556c640c6aaa51aa02ab41 */
+-2.50521016467996193495359189395805639E-08L, /* bfe5ae644ee90c47dc71839de75b2787 */
+};
+
+#define SINCOSL_COS_HI 0
+#define SINCOSL_COS_LO 1
+#define SINCOSL_SIN_HI 2
+#define SINCOSL_SIN_LO 3
+extern const long double __sincosl_table[];
+
+long double
+__kernel_cosl(long double x, long double y)
+{
+ long double h, l, z, sin_l, cos_l_m1;
+ int64_t ix;
+ u_int32_t tix, hix, index;
+ GET_LDOUBLE_MSW64 (ix, x);
+ tix = ((u_int64_t)ix) >> 32;
+ tix &= ~0x80000000; /* tix = |x|'s high 32 bits */
+ if (tix < 0x3fc30000) /* |x| < 0.1484375 */
+ {
+ /* Argument is small enough to approximate it by a Chebyshev
+ polynomial of degree 16. */
+ if (tix < 0x3c600000) /* |x| < 2^-57 */
+ if (!((int)x)) return ONE; /* generate inexact */
+ z = x * x;
+ return ONE + (z*(COS1+z*(COS2+z*(COS3+z*(COS4+
+ z*(COS5+z*(COS6+z*(COS7+z*COS8))))))));
+ }
+ else
+ {
+ /* So that we don't have to use too large polynomial, we find
+ l and h such that x = l + h, where fabsl(l) <= 1.0/256 with 83
+ possible values for h. We look up cosl(h) and sinl(h) in
+ pre-computed tables, compute cosl(l) and sinl(l) using a
+ Chebyshev polynomial of degree 10(11) and compute
+ cosl(h+l) = cosl(h)cosl(l) - sinl(h)sinl(l). */
+ int six = tix;
+ tix = ((six - 0x3ff00000) >> 4) + 0x3fff0000;
+ index = 0x3ffe - (tix >> 16);
+ hix = (tix + (0x200 << index)) & (0xfffffc00 << index);
+ x = fabsl (x);
+ switch (index)
+ {
+ case 0: index = ((45 << 10) + hix - 0x3ffe0000) >> 8; break;
+ case 1: index = ((13 << 11) + hix - 0x3ffd0000) >> 9; break;
+ default:
+ case 2: index = (hix - 0x3ffc3000) >> 10; break;
+ }
+ hix = (hix << 4) & 0x3fffffff;
+/*
+ The following should work for double but generates the wrong index.
+ For now the code above converts double to ieee extended to compute
+ the index back to double for the h value.
+
+ index = 0x3fe - (tix >> 20);
+ hix = (tix + (0x200 << index)) & (0xfffffc00 << index);
+ x = fabsl (x);
+ switch (index)
+ {
+ case 0: index = ((45 << 14) + hix - 0x3fe00000) >> 12; break;
+ case 1: index = ((13 << 15) + hix - 0x3fd00000) >> 13; break;
+ default:
+ case 2: index = (hix - 0x3fc30000) >> 14; break;
+ }
+*/
+ SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0);
+ l = y - (h - x);
+ z = l * l;
+ sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5)))));
+ cos_l_m1 = z*(SCOS1+z*(SCOS2+z*(SCOS3+z*(SCOS4+z*SCOS5))));
+ return __sincosl_table [index + SINCOSL_COS_HI]
+ + (__sincosl_table [index + SINCOSL_COS_LO]
+ - (__sincosl_table [index + SINCOSL_SIN_HI] * sin_l
+ - __sincosl_table [index + SINCOSL_COS_HI] * cos_l_m1));
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c b/libc/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c
new file mode 100644
index 000000000..cd2ce7ad1
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c
@@ -0,0 +1,182 @@
+/* Quad-precision floating point sine and cosine on <-pi/4,pi/4>.
+ Copyright (C) 1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+
+static const long double c[] = {
+#define ONE c[0]
+ 1.00000000000000000000000000000000000E+00L, /* 3fff0000000000000000000000000000 */
+
+/* cos x ~ ONE + x^2 ( SCOS1 + SCOS2 * x^2 + ... + SCOS4 * x^6 + SCOS5 * x^8 )
+ x in <0,1/256> */
+#define SCOS1 c[1]
+#define SCOS2 c[2]
+#define SCOS3 c[3]
+#define SCOS4 c[4]
+#define SCOS5 c[5]
+-5.00000000000000000000000000000000000E-01L, /* bffe0000000000000000000000000000 */
+ 4.16666666666666666666666666556146073E-02L, /* 3ffa5555555555555555555555395023 */
+-1.38888888888888888888309442601939728E-03L, /* bff56c16c16c16c16c16a566e42c0375 */
+ 2.48015873015862382987049502531095061E-05L, /* 3fefa01a01a019ee02dcf7da2d6d5444 */
+-2.75573112601362126593516899592158083E-07L, /* bfe927e4f5dce637cb0b54908754bde0 */
+
+/* cos x ~ ONE + x^2 ( COS1 + COS2 * x^2 + ... + COS7 * x^12 + COS8 * x^14 )
+ x in <0,0.1484375> */
+#define COS1 c[6]
+#define COS2 c[7]
+#define COS3 c[8]
+#define COS4 c[9]
+#define COS5 c[10]
+#define COS6 c[11]
+#define COS7 c[12]
+#define COS8 c[13]
+-4.99999999999999999999999999999999759E-01L, /* bffdfffffffffffffffffffffffffffb */
+ 4.16666666666666666666666666651287795E-02L, /* 3ffa5555555555555555555555516f30 */
+-1.38888888888888888888888742314300284E-03L, /* bff56c16c16c16c16c16c16a463dfd0d */
+ 2.48015873015873015867694002851118210E-05L, /* 3fefa01a01a01a01a0195cebe6f3d3a5 */
+-2.75573192239858811636614709689300351E-07L, /* bfe927e4fb7789f5aa8142a22044b51f */
+ 2.08767569877762248667431926878073669E-09L, /* 3fe21eed8eff881d1e9262d7adff4373 */
+-1.14707451049343817400420280514614892E-11L, /* bfda9397496922a9601ed3d4ca48944b */
+ 4.77810092804389587579843296923533297E-14L, /* 3fd2ae5f8197cbcdcaf7c3fb4523414c */
+
+/* sin x ~ ONE * x + x^3 ( SSIN1 + SSIN2 * x^2 + ... + SSIN4 * x^6 + SSIN5 * x^8 )
+ x in <0,1/256> */
+#define SSIN1 c[14]
+#define SSIN2 c[15]
+#define SSIN3 c[16]
+#define SSIN4 c[17]
+#define SSIN5 c[18]
+-1.66666666666666666666666666666666659E-01L, /* bffc5555555555555555555555555555 */
+ 8.33333333333333333333333333146298442E-03L, /* 3ff81111111111111111111110fe195d */
+-1.98412698412698412697726277416810661E-04L, /* bff2a01a01a01a01a019e7121e080d88 */
+ 2.75573192239848624174178393552189149E-06L, /* 3fec71de3a556c640c6aaa51aa02ab41 */
+-2.50521016467996193495359189395805639E-08L, /* bfe5ae644ee90c47dc71839de75b2787 */
+
+/* sin x ~ ONE * x + x^3 ( SIN1 + SIN2 * x^2 + ... + SIN7 * x^12 + SIN8 * x^14 )
+ x in <0,0.1484375> */
+#define SIN1 c[19]
+#define SIN2 c[20]
+#define SIN3 c[21]
+#define SIN4 c[22]
+#define SIN5 c[23]
+#define SIN6 c[24]
+#define SIN7 c[25]
+#define SIN8 c[26]
+-1.66666666666666666666666666666666538e-01L, /* bffc5555555555555555555555555550 */
+ 8.33333333333333333333333333307532934e-03L, /* 3ff811111111111111111111110e7340 */
+-1.98412698412698412698412534478712057e-04L, /* bff2a01a01a01a01a01a019e7a626296 */
+ 2.75573192239858906520896496653095890e-06L, /* 3fec71de3a556c7338fa38527474b8f5 */
+-2.50521083854417116999224301266655662e-08L, /* bfe5ae64567f544e16c7de65c2ea551f */
+ 1.60590438367608957516841576404938118e-10L, /* 3fde6124613a811480538a9a41957115 */
+-7.64716343504264506714019494041582610e-13L, /* bfd6ae7f3d5aef30c7bc660b060ef365 */
+ 2.81068754939739570236322404393398135e-15L, /* 3fce9510115aabf87aceb2022a9a9180 */
+};
+
+#define SINCOSL_COS_HI 0
+#define SINCOSL_COS_LO 1
+#define SINCOSL_SIN_HI 2
+#define SINCOSL_SIN_LO 3
+extern const long double __sincosl_table[];
+
+void
+__kernel_sincosl(long double x, long double y, long double *sinx, long double *cosx, int iy)
+{
+ long double h, l, z, sin_l, cos_l_m1;
+ int64_t ix;
+ u_int32_t tix, hix, index;
+ GET_LDOUBLE_MSW64 (ix, x);
+ tix = ((u_int64_t)ix) >> 32;
+ tix &= ~0x80000000; /* tix = |x|'s high 32 bits */
+ if (tix < 0x3fc30000) /* |x| < 0.1484375 */
+ {
+ /* Argument is small enough to approximate it by a Chebyshev
+ polynomial of degree 16(17). */
+ if (tix < 0x3c600000) /* |x| < 2^-57 */
+ if (!((int)x)) /* generate inexact */
+ {
+ *sinx = x;
+ *cosx = ONE;
+ return;
+ }
+ z = x * x;
+ *sinx = x + (x * (z*(SIN1+z*(SIN2+z*(SIN3+z*(SIN4+
+ z*(SIN5+z*(SIN6+z*(SIN7+z*SIN8)))))))));
+ *cosx = ONE + (z*(COS1+z*(COS2+z*(COS3+z*(COS4+
+ z*(COS5+z*(COS6+z*(COS7+z*COS8))))))));
+ }
+ else
+ {
+ /* So that we don't have to use too large polynomial, we find
+ l and h such that x = l + h, where fabsl(l) <= 1.0/256 with 83
+ possible values for h. We look up cosl(h) and sinl(h) in
+ pre-computed tables, compute cosl(l) and sinl(l) using a
+ Chebyshev polynomial of degree 10(11) and compute
+ sinl(h+l) = sinl(h)cosl(l) + cosl(h)sinl(l) and
+ cosl(h+l) = cosl(h)cosl(l) - sinl(h)sinl(l). */
+ int six = tix;
+ tix = ((six - 0x3ff00000) >> 4) + 0x3fff0000;
+ index = 0x3ffe - (tix >> 16);
+ hix = (tix + (0x200 << index)) & (0xfffffc00 << index);
+ x = fabsl (x);
+ switch (index)
+ {
+ case 0: index = ((45 << 10) + hix - 0x3ffe0000) >> 8; break;
+ case 1: index = ((13 << 11) + hix - 0x3ffd0000) >> 9; break;
+ default:
+ case 2: index = (hix - 0x3ffc3000) >> 10; break;
+ }
+ hix = (hix << 4) & 0x3fffffff;
+/*
+ The following should work for double but generates the wrong index.
+ For now the code above converts double to ieee extended to compute
+ the index back to double for the h value.
+
+
+ index = 0x3fe - (tix >> 20);
+ hix = (tix + (0x2000 << index)) & (0xffffc000 << index);
+ x = fabsl (x);
+ switch (index)
+ {
+ case 0: index = ((45 << 14) + hix - 0x3fe00000) >> 12; break;
+ case 1: index = ((13 << 15) + hix - 0x3fd00000) >> 13; break;
+ default:
+ case 2: index = (hix - 0x3fc30000) >> 14; break;
+ }
+*/
+ SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0);
+ if (iy)
+ l = y - (h - x);
+ else
+ l = x - h;
+ z = l * l;
+ sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5)))));
+ cos_l_m1 = z*(SCOS1+z*(SCOS2+z*(SCOS3+z*(SCOS4+z*SCOS5))));
+ z = __sincosl_table [index + SINCOSL_SIN_HI]
+ + (__sincosl_table [index + SINCOSL_SIN_LO]
+ + (__sincosl_table [index + SINCOSL_SIN_HI] * cos_l_m1)
+ + (__sincosl_table [index + SINCOSL_COS_HI] * sin_l));
+ *sinx = (ix < 0) ? -z : z;
+ *cosx = __sincosl_table [index + SINCOSL_COS_HI]
+ + (__sincosl_table [index + SINCOSL_COS_LO]
+ - (__sincosl_table [index + SINCOSL_SIN_HI] * sin_l
+ - __sincosl_table [index + SINCOSL_COS_HI] * cos_l_m1));
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/k_sinl.c b/libc/sysdeps/ieee754/ldbl-128ibm/k_sinl.c
new file mode 100644
index 000000000..24cb551b6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/k_sinl.c
@@ -0,0 +1,150 @@
+/* Quad-precision floating point sine on <-pi/4,pi/4>.
+ Copyright (C) 1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+
+static const long double c[] = {
+#define ONE c[0]
+ 1.00000000000000000000000000000000000E+00L, /* 3fff0000000000000000000000000000 */
+
+/* cos x ~ ONE + x^2 ( SCOS1 + SCOS2 * x^2 + ... + SCOS4 * x^6 + SCOS5 * x^8 )
+ x in <0,1/256> */
+#define SCOS1 c[1]
+#define SCOS2 c[2]
+#define SCOS3 c[3]
+#define SCOS4 c[4]
+#define SCOS5 c[5]
+-5.00000000000000000000000000000000000E-01L, /* bffe0000000000000000000000000000 */
+ 4.16666666666666666666666666556146073E-02L, /* 3ffa5555555555555555555555395023 */
+-1.38888888888888888888309442601939728E-03L, /* bff56c16c16c16c16c16a566e42c0375 */
+ 2.48015873015862382987049502531095061E-05L, /* 3fefa01a01a019ee02dcf7da2d6d5444 */
+-2.75573112601362126593516899592158083E-07L, /* bfe927e4f5dce637cb0b54908754bde0 */
+
+/* sin x ~ ONE * x + x^3 ( SIN1 + SIN2 * x^2 + ... + SIN7 * x^12 + SIN8 * x^14 )
+ x in <0,0.1484375> */
+#define SIN1 c[6]
+#define SIN2 c[7]
+#define SIN3 c[8]
+#define SIN4 c[9]
+#define SIN5 c[10]
+#define SIN6 c[11]
+#define SIN7 c[12]
+#define SIN8 c[13]
+-1.66666666666666666666666666666666538e-01L, /* bffc5555555555555555555555555550 */
+ 8.33333333333333333333333333307532934e-03L, /* 3ff811111111111111111111110e7340 */
+-1.98412698412698412698412534478712057e-04L, /* bff2a01a01a01a01a01a019e7a626296 */
+ 2.75573192239858906520896496653095890e-06L, /* 3fec71de3a556c7338fa38527474b8f5 */
+-2.50521083854417116999224301266655662e-08L, /* bfe5ae64567f544e16c7de65c2ea551f */
+ 1.60590438367608957516841576404938118e-10L, /* 3fde6124613a811480538a9a41957115 */
+-7.64716343504264506714019494041582610e-13L, /* bfd6ae7f3d5aef30c7bc660b060ef365 */
+ 2.81068754939739570236322404393398135e-15L, /* 3fce9510115aabf87aceb2022a9a9180 */
+
+/* sin x ~ ONE * x + x^3 ( SSIN1 + SSIN2 * x^2 + ... + SSIN4 * x^6 + SSIN5 * x^8 )
+ x in <0,1/256> */
+#define SSIN1 c[14]
+#define SSIN2 c[15]
+#define SSIN3 c[16]
+#define SSIN4 c[17]
+#define SSIN5 c[18]
+-1.66666666666666666666666666666666659E-01L, /* bffc5555555555555555555555555555 */
+ 8.33333333333333333333333333146298442E-03L, /* 3ff81111111111111111111110fe195d */
+-1.98412698412698412697726277416810661E-04L, /* bff2a01a01a01a01a019e7121e080d88 */
+ 2.75573192239848624174178393552189149E-06L, /* 3fec71de3a556c640c6aaa51aa02ab41 */
+-2.50521016467996193495359189395805639E-08L, /* bfe5ae644ee90c47dc71839de75b2787 */
+};
+
+#define SINCOSL_COS_HI 0
+#define SINCOSL_COS_LO 1
+#define SINCOSL_SIN_HI 2
+#define SINCOSL_SIN_LO 3
+extern const long double __sincosl_table[];
+
+long double
+__kernel_sinl(long double x, long double y, int iy)
+{
+ long double h, l, z, sin_l, cos_l_m1;
+ int64_t ix;
+ u_int32_t tix, hix, index;
+ GET_LDOUBLE_MSW64 (ix, x);
+ tix = ((u_int64_t)ix) >> 32;
+ tix &= ~0x80000000; /* tix = |x|'s high 32 bits */
+ if (tix < 0x3fc30000) /* |x| < 0.1484375 */
+ {
+ /* Argument is small enough to approximate it by a Chebyshev
+ polynomial of degree 17. */
+ if (tix < 0x3c600000) /* |x| < 2^-57 */
+ if (!((int)x)) return x; /* generate inexact */
+ z = x * x;
+ return x + (x * (z*(SIN1+z*(SIN2+z*(SIN3+z*(SIN4+
+ z*(SIN5+z*(SIN6+z*(SIN7+z*SIN8)))))))));
+ }
+ else
+ {
+ /* So that we don't have to use too large polynomial, we find
+ l and h such that x = l + h, where fabsl(l) <= 1.0/256 with 83
+ possible values for h. We look up cosl(h) and sinl(h) in
+ pre-computed tables, compute cosl(l) and sinl(l) using a
+ Chebyshev polynomial of degree 10(11) and compute
+ sinl(h+l) = sinl(h)cosl(l) + cosl(h)sinl(l). */
+ int six = tix;
+ tix = ((six - 0x3ff00000) >> 4) + 0x3fff0000;
+ index = 0x3ffe - (tix >> 16);
+ hix = (tix + (0x200 << index)) & (0xfffffc00 << index);
+ x = fabsl (x);
+ switch (index)
+ {
+ case 0: index = ((45 << 10) + hix - 0x3ffe0000) >> 8; break;
+ case 1: index = ((13 << 11) + hix - 0x3ffd0000) >> 9; break;
+ default:
+ case 2: index = (hix - 0x3ffc3000) >> 10; break;
+ }
+ hix = (hix << 4) & 0x3fffffff;
+/*
+ The following should work for double but generates the wrong index.
+ For now the code above converts double to ieee extended to compute
+ the index back to double for the h value.
+
+ index = 0x3fe - (tix >> 20);
+ hix = (tix + (0x2000 << index)) & (0xffffc000 << index);
+ x = fabsl (x);
+ switch (index)
+ {
+ case 0: index = ((45 << 14) + hix - 0x3fe00000) >> 12; break;
+ case 1: index = ((13 << 15) + hix - 0x3fd00000) >> 13; break;
+ default:
+ case 2: index = (hix - 0x3fc30000) >> 14; break;
+ }
+*/
+ SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0);
+ if (iy)
+ l = y - (h - x);
+ else
+ l = x - h;
+ z = l * l;
+ sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5)))));
+ cos_l_m1 = z*(SCOS1+z*(SCOS2+z*(SCOS3+z*(SCOS4+z*SCOS5))));
+ z = __sincosl_table [index + SINCOSL_SIN_HI]
+ + (__sincosl_table [index + SINCOSL_SIN_LO]
+ + (__sincosl_table [index + SINCOSL_SIN_HI] * cos_l_m1)
+ + (__sincosl_table [index + SINCOSL_COS_HI] * sin_l));
+ return (ix < 0) ? -z : z;
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/k_tanl.c b/libc/sysdeps/ieee754/ldbl-128ibm/k_tanl.c
new file mode 100644
index 000000000..6c45b2fc4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/k_tanl.c
@@ -0,0 +1,164 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/*
+ Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __kernel_tanl( x, y, k )
+ * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input k indicates whether tan (if k=1) or
+ * -1/tan (if k= -1) is returned.
+ *
+ * Algorithm
+ * 1. Since tan(-x) = -tan(x), we need only to consider positive x.
+ * 2. if x < 2^-57, return x with inexact if x!=0.
+ * 3. tan(x) is approximated by a rational form x + x^3 / 3 + x^5 R(x^2)
+ * on [0,0.67433].
+ *
+ * Note: tan(x+y) = tan(x) + tan'(x)*y
+ * ~ tan(x) + (1+x*x)*y
+ * Therefore, for better accuracy in computing tan(x+y), let
+ * r = x^3 * R(x^2)
+ * then
+ * tan(x+y) = x + (x^3 / 3 + (x^2 *(r+y)+y))
+ *
+ * 4. For x in [0.67433,pi/4], let y = pi/4 - x, then
+ * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
+ * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
+ */
+
+#include "math.h"
+#include "math_private.h"
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ one = 1.0L,
+ pio4hi = 7.8539816339744830961566084581987569936977E-1L,
+ pio4lo = 2.1679525325309452561992610065108379921906E-35L,
+
+ /* tan x = x + x^3 / 3 + x^5 T(x^2)/U(x^2)
+ 0 <= x <= 0.6743316650390625
+ Peak relative error 8.0e-36 */
+ TH = 3.333333333333333333333333333333333333333E-1L,
+ T0 = -1.813014711743583437742363284336855889393E7L,
+ T1 = 1.320767960008972224312740075083259247618E6L,
+ T2 = -2.626775478255838182468651821863299023956E4L,
+ T3 = 1.764573356488504935415411383687150199315E2L,
+ T4 = -3.333267763822178690794678978979803526092E-1L,
+
+ U0 = -1.359761033807687578306772463253710042010E8L,
+ U1 = 6.494370630656893175666729313065113194784E7L,
+ U2 = -4.180787672237927475505536849168729386782E6L,
+ U3 = 8.031643765106170040139966622980914621521E4L,
+ U4 = -5.323131271912475695157127875560667378597E2L;
+ /* 1.000000000000000000000000000000000000000E0 */
+
+
+#ifdef __STDC__
+long double
+__kernel_tanl (long double x, long double y, int iy)
+#else
+long double
+__kernel_tanl (x, y, iy)
+ long double x, y;
+ int iy;
+#endif
+{
+ long double z, r, v, w, s;
+ int32_t ix, sign;
+ ieee854_long_double_shape_type u, u1;
+
+ u.value = x;
+ ix = u.parts32.w0 & 0x7fffffff;
+ if (ix < 0x3c600000) /* x < 2**-57 */
+ {
+ if ((int) x == 0)
+ { /* generate inexact */
+ if ((ix | u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3
+ | (iy + 1)) == 0)
+ return one / fabs (x);
+ else
+ return (iy == 1) ? x : -one / x;
+ }
+ }
+ if (ix >= 0x3fe59420) /* |x| >= 0.6743316650390625 */
+ {
+ if ((u.parts32.w0 & 0x80000000) != 0)
+ {
+ x = -x;
+ y = -y;
+ sign = -1;
+ }
+ else
+ sign = 1;
+ z = pio4hi - x;
+ w = pio4lo - y;
+ x = z + w;
+ y = 0.0;
+ }
+ z = x * x;
+ r = T0 + z * (T1 + z * (T2 + z * (T3 + z * T4)));
+ v = U0 + z * (U1 + z * (U2 + z * (U3 + z * (U4 + z))));
+ r = r / v;
+
+ s = z * x;
+ r = y + z * (s * r + y);
+ r += TH * s;
+ w = x + r;
+ if (ix >= 0x3fe59420)
+ {
+ v = (long double) iy;
+ w = (v - 2.0 * (x - (w * w / (w + v) - r)));
+ if (sign < 0)
+ w = -w;
+ return w;
+ }
+ if (iy == 1)
+ return w;
+ else
+ { /* if allow error up to 2 ulp,
+ simply return -1.0/(x+r) here */
+ /* compute -1.0/(x+r) accurately */
+ u1.value = w;
+ u1.parts32.w2 = 0;
+ u1.parts32.w3 = 0;
+ v = r - (u1.value - x); /* u1+v = r+x */
+ z = -1.0 / w;
+ u.value = z;
+ u.parts32.w2 = 0;
+ u.parts32.w3 = 0;
+ s = 1.0 + u.value * u1.value;
+ return u.value + z * (s + u.value * v);
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c b/libc/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c
new file mode 100644
index 000000000..18a2e671a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c
@@ -0,0 +1,175 @@
+/* Copyright (C) 1995,1996,1997,1998,1999,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include <ieee754.h>
+#include <float.h>
+#include <math.h>
+#include <stdlib.h>
+
+/* Convert a `long double' in IBM extended format to a multi-precision
+ integer representing the significand scaled up by its number of
+ bits (106 for long double) and an integral power of two (MPN
+ frexpl). */
+
+mp_size_t
+__mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
+ int *expt, int *is_neg,
+ long double value)
+{
+ union ibm_extended_long_double u;
+ unsigned long long hi, lo;
+ int ediff;
+ u.d = value;
+
+ *is_neg = u.ieee.negative;
+ *expt = (int) u.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS;
+
+ lo = ((long long) u.ieee.mantissa2 << 32) | u.ieee.mantissa3;
+ hi = ((long long) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
+ /* If the lower double is not a denomal or zero then set the hidden
+ 53rd bit. */
+ if (u.ieee.exponent2 > 0)
+ {
+ lo |= 1LL << 52;
+
+ /* The lower double is normalized separately from the upper. We may
+ need to adjust the lower manitissa to reflect this. */
+ ediff = u.ieee.exponent - u.ieee.exponent2;
+ if (ediff > 53)
+ lo = lo >> (ediff-53);
+ }
+ /* The high double may be rounded and the low double reflects the
+ difference between the long double and the rounded high double
+ value. This is indicated by a differnce between the signs of the
+ high and low doubles. */
+ if ((u.ieee.negative != u.ieee.negative2)
+ && ((u.ieee.exponent2 != 0) && (lo != 0L)))
+ {
+ lo = (1ULL << 53) - lo;
+ if (hi == 0LL)
+ {
+ /* we have a borrow from the hidden bit, so shift left 1. */
+ hi = 0x0ffffffffffffeLL | (lo >> 51);
+ lo = 0x1fffffffffffffLL & (lo << 1);
+ (*expt)--;
+ }
+ else
+ hi--;
+ }
+#if BITS_PER_MP_LIMB == 32
+ /* Combine the mantissas to be contiguous. */
+ res_ptr[0] = lo;
+ res_ptr[1] = (hi << (53 - 32)) | (lo >> 32);
+ res_ptr[2] = hi >> 11;
+ res_ptr[3] = hi >> (32 + 11);
+ #define N 4
+#elif BITS_PER_MP_LIMB == 64
+ /* Combine the two mantissas to be contiguous. */
+ res_ptr[0] = (hi << 53) | lo;
+ res_ptr[1] = hi >> 11;
+ #define N 2
+#else
+ #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+/* The format does not fill the last limb. There are some zeros. */
+#define NUM_LEADING_ZEROS (BITS_PER_MP_LIMB \
+ - (LDBL_MANT_DIG - ((N - 1) * BITS_PER_MP_LIMB)))
+
+ if (u.ieee.exponent == 0)
+ {
+ /* A biased exponent of zero is a special case.
+ Either it is a zero or it is a denormal number. */
+ if (res_ptr[0] == 0 && res_ptr[1] == 0
+ && res_ptr[N - 2] == 0 && res_ptr[N - 1] == 0) /* Assumes N<=4. */
+ /* It's zero. */
+ *expt = 0;
+ else
+ {
+ /* It is a denormal number, meaning it has no implicit leading
+ one bit, and its exponent is in fact the format minimum. */
+ int cnt;
+
+#if N == 2
+ if (res_ptr[N - 1] != 0)
+ {
+ count_leading_zeros (cnt, res_ptr[N - 1]);
+ cnt -= NUM_LEADING_ZEROS;
+ res_ptr[N - 1] = res_ptr[N - 1] << cnt
+ | (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt));
+ res_ptr[0] <<= cnt;
+ *expt = LDBL_MIN_EXP - 1 - cnt;
+ }
+ else
+ {
+ count_leading_zeros (cnt, res_ptr[0]);
+ if (cnt >= NUM_LEADING_ZEROS)
+ {
+ res_ptr[N - 1] = res_ptr[0] << (cnt - NUM_LEADING_ZEROS);
+ res_ptr[0] = 0;
+ }
+ else
+ {
+ res_ptr[N - 1] = res_ptr[0] >> (NUM_LEADING_ZEROS - cnt);
+ res_ptr[0] <<= BITS_PER_MP_LIMB - (NUM_LEADING_ZEROS - cnt);
+ }
+ *expt = LDBL_MIN_EXP - 1
+ - (BITS_PER_MP_LIMB - NUM_LEADING_ZEROS) - cnt;
+ }
+#else
+ int j, k, l;
+
+ for (j = N - 1; j > 0; j--)
+ if (res_ptr[j] != 0)
+ break;
+
+ count_leading_zeros (cnt, res_ptr[j]);
+ cnt -= NUM_LEADING_ZEROS;
+ l = N - 1 - j;
+ if (cnt < 0)
+ {
+ cnt += BITS_PER_MP_LIMB;
+ l--;
+ }
+ if (!cnt)
+ for (k = N - 1; k >= l; k--)
+ res_ptr[k] = res_ptr[k-l];
+ else
+ {
+ for (k = N - 1; k > l; k--)
+ res_ptr[k] = res_ptr[k-l] << cnt
+ | res_ptr[k-l-1] >> (BITS_PER_MP_LIMB - cnt);
+ res_ptr[k--] = res_ptr[0] << cnt;
+ }
+
+ for (; k >= 0; k--)
+ res_ptr[k] = 0;
+ *expt = LDBL_MIN_EXP - 1 - l * BITS_PER_MP_LIMB - cnt;
+#endif
+ }
+ }
+ else
+ /* Add the implicit leading one bit for a normalized number. */
+ res_ptr[N - 1] |= (mp_limb_t) 1 << (LDBL_MANT_DIG - 1
+ - ((N - 1) * BITS_PER_MP_LIMB));
+
+ return N;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h b/libc/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
new file mode 100644
index 000000000..d055d6597
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
@@ -0,0 +1,181 @@
+#ifndef _MATH_PRIVATE_H_
+#error "Never use <math_ldbl.h> directly; include <math_private.h> instead."
+#endif
+
+#include <sysdeps/ieee754/ldbl-128/math_ldbl.h>
+#include <ieee754.h>
+
+static inline void
+ldbl_extract_mantissa (int64_t *hi64, u_int64_t *lo64, int *exp, long double x)
+{
+ /* We have 105 bits of mantissa plus one implicit digit. Since
+ 106 bits are representable we use the first implicit digit for
+ the number before the decimal point and the second implicit bit
+ as bit 53 of the mantissa. */
+ unsigned long long hi, lo;
+ int ediff;
+ union ibm_extended_long_double eldbl;
+ eldbl.d = x;
+ *exp = eldbl.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS;
+
+ lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3;
+ hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1;
+ /* If the lower double is not a denomal or zero then set the hidden
+ 53rd bit. */
+ if (eldbl.ieee.exponent2 > 0x001)
+ {
+ lo |= (1ULL << 52);
+ lo = lo << 7; /* pre-shift lo to match ieee854. */
+ /* The lower double is normalized separately from the upper. We
+ may need to adjust the lower manitissa to reflect this. */
+ ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2;
+ if (ediff > 53)
+ lo = lo >> (ediff-53);
+ }
+ hi |= (1ULL << 52);
+
+ if ((eldbl.ieee.negative != eldbl.ieee.negative2)
+ && ((eldbl.ieee.exponent2 != 0) && (lo != 0LL)))
+ {
+ hi--;
+ lo = (1ULL << 60) - lo;
+ if (hi < (1ULL << 52))
+ {
+ /* we have a borrow from the hidden bit, so shift left 1. */
+ hi = (hi << 1) | (lo >> 59);
+ lo = 0xfffffffffffffffLL & (lo << 1);
+ *exp = *exp - 1;
+ }
+ }
+ *lo64 = (hi << 60) | lo;
+ *hi64 = hi >> 4;
+}
+
+static inline long double
+ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64)
+{
+ union ibm_extended_long_double u;
+ unsigned long hidden2, lzcount;
+ unsigned long long hi, lo;
+
+ u.ieee.negative = sign;
+ u.ieee.negative2 = sign;
+ u.ieee.exponent = exp + IBM_EXTENDED_LONG_DOUBLE_BIAS;
+ u.ieee.exponent2 = exp-53 + IBM_EXTENDED_LONG_DOUBLE_BIAS;
+ /* Expect 113 bits (112 bits + hidden) right justified in two longs.
+ The low order 53 bits (52 + hidden) go into the lower double */
+ lo = (lo64 >> 7)& ((1ULL << 53) - 1);
+ hidden2 = (lo64 >> 59) & 1ULL;
+ /* The high order 53 bits (52 + hidden) go into the upper double */
+ hi = (lo64 >> 60) & ((1ULL << 11) - 1);
+ hi |= (hi64 << 4);
+
+ if (lo != 0LL)
+ {
+ /* hidden2 bit of low double controls rounding of the high double.
+ If hidden2 is '1' then round up hi and adjust lo (2nd mantissa)
+ plus change the sign of the low double to compensate. */
+ if (hidden2)
+ {
+ hi++;
+ u.ieee.negative2 = !sign;
+ lo = (1ULL << 53) - lo;
+ }
+ /* The hidden bit of the lo mantissa is zero so we need to
+ normalize the it for the low double. Shift it left until the
+ hidden bit is '1' then adjust the 2nd exponent accordingly. */
+
+ if (sizeof (lo) == sizeof (long))
+ lzcount = __builtin_clzl (lo);
+ else if ((lo >> 32) != 0)
+ lzcount = __builtin_clzl ((long) (lo >> 32));
+ else
+ lzcount = __builtin_clzl ((long) lo) + 32;
+ lzcount = lzcount - 11;
+ if (lzcount > 0)
+ {
+ int expnt2 = u.ieee.exponent2 - lzcount;
+ if (expnt2 >= 1)
+ {
+ /* Not denormal. Normalize and set low exponent. */
+ lo = lo << lzcount;
+ u.ieee.exponent2 = expnt2;
+ }
+ else
+ {
+ /* Is denormal. */
+ lo = lo << (lzcount + expnt2);
+ u.ieee.exponent2 = 0;
+ }
+ }
+ }
+ else
+ {
+ u.ieee.negative2 = 0;
+ u.ieee.exponent2 = 0;
+ }
+
+ u.ieee.mantissa3 = lo & ((1ULL << 32) - 1);
+ u.ieee.mantissa2 = (lo >> 32) & ((1ULL << 20) - 1);
+ u.ieee.mantissa1 = hi & ((1ULL << 32) - 1);
+ u.ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1);
+ return u.d;
+}
+
+/* Handy utility functions to pack/unpack/cononicalize and find the nearbyint
+ of long double implemented as double double. */
+static inline long double
+ldbl_pack (double a, double aa)
+{
+ union ibm_extended_long_double u;
+ u.dd[0] = a;
+ u.dd[1] = aa;
+ return u.d;
+}
+
+static inline void
+ldbl_unpack (long double l, double *a, double *aa)
+{
+ union ibm_extended_long_double u;
+ u.d = l;
+ *a = u.dd[0];
+ *aa = u.dd[1];
+}
+
+
+/* Convert a finite long double to canonical form.
+ Does not handle +/-Inf properly. */
+static inline void
+ldbl_canonicalize (double *a, double *aa)
+{
+ double xh, xl;
+
+ xh = *a + *aa;
+ xl = (*a - xh) + *aa;
+ *a = xh;
+ *aa = xl;
+}
+
+/* Simple inline nearbyint (double) function .
+ Only works in the default rounding mode
+ but is useful in long double rounding functions. */
+static inline double
+ldbl_nearbyint (double a)
+{
+ double two52 = 0x10000000000000LL;
+
+ if (__builtin_expect ((__builtin_fabs (a) < two52), 1))
+ {
+ if (__builtin_expect ((a > 0.0), 1))
+ {
+ a += two52;
+ a -= two52;
+ }
+ else if (__builtin_expect ((a < 0.0), 1))
+ {
+ a = two52 - a;
+ a = -(a - two52);
+ }
+ }
+ return a;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c b/libc/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
new file mode 100644
index 000000000..8a2d45e2d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
@@ -0,0 +1,103 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include <ieee754.h>
+#include <float.h>
+#include <math.h>
+
+/* Convert a multi-precision integer of the needed number of bits (106
+ for long double) and an integral power of two to a `long double' in
+ IBM extended format. */
+
+long double
+__mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign)
+{
+ union ibm_extended_long_double u;
+ unsigned long hidden2, lzcount;
+ unsigned long long hi, lo;
+
+ u.ieee.negative = sign;
+ u.ieee.negative2 = sign;
+ u.ieee.exponent = expt + IBM_EXTENDED_LONG_DOUBLE_BIAS;
+ u.ieee.exponent2 = expt - 53 + IBM_EXTENDED_LONG_DOUBLE_BIAS;
+
+#if BITS_PER_MP_LIMB == 32
+ /* The low order 53 bits (52 + hidden) go into the lower double */
+ lo = frac_ptr[0];
+ lo |= (frac_ptr[1] & ((1LL << (53 - 32)) - 1)) << 32;
+ hidden2 = (frac_ptr[1] >> (52 - 32)) & ((mp_limb_t) 1);
+ /* The high order 53 bits (52 + hidden) go into the upper double */
+ hi = (frac_ptr[1] >> (53 - 32)) & ((1 << 11) - 1);
+ hi |= ((unsigned long long) frac_ptr[2]) << 11;
+ hi |= ((unsigned long long) frac_ptr[3]) << (32 + 11);
+#elif BITS_PER_MP_LIMB == 64
+ /* The low order 53 bits (52 + hidden) go into the lower double */
+ lo = frac_ptr[0] & (((mp_limb_t) 1 << 53) - 1);
+ hidden2 = (frac_ptr[0] >> 52) & ((mp_limb_t) 1);
+ /* The high order 53 bits (52 + hidden) go into the upper double */
+ hi = (frac_ptr[0] >> 53) & (((mp_limb_t) 1 << 11) - 1);
+ hi |= (frac_ptr[1] << 11);
+#else
+ #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+
+ if (lo != 0L)
+ {
+ /* hidden2 bit of low double controls rounding of the high double.
+ If hidden2 is '1' then round up hi and adjust lo (2nd mantissa)
+ plus change the sign of the low double to compensate. */
+ if (hidden2)
+ {
+ hi++;
+ u.ieee.negative2 = !sign;
+ lo = (1LL << 53) - lo;
+ }
+
+ /* The hidden bit of the lo mantissa is zero so we need to normalize
+ it for the low double. Shift it left until the hidden bit is '1'
+ then adjust the 2nd exponent accordingly. */
+
+ if (sizeof (lo) == sizeof (long))
+ lzcount = __builtin_clzl (lo);
+ else if ((lo >> 32) != 0)
+ lzcount = __builtin_clzl ((long) (lo >> 32));
+ else
+ lzcount = __builtin_clzl ((long) lo) + 32;
+ lzcount = lzcount - 11;
+ if (lzcount > 0)
+ {
+ lo = lo << lzcount;
+ u.ieee.exponent2 = u.ieee.exponent2 - lzcount;
+ }
+ }
+ else
+ {
+ u.ieee.negative2 = 0;
+ u.ieee.exponent2 = 0;
+ }
+
+ u.ieee.mantissa3 = lo & 0xffffffffLL;
+ u.ieee.mantissa2 = (lo >> 32) & 0xffffff;
+ u.ieee.mantissa1 = hi & 0xffffffffLL;
+ u.ieee.mantissa0 = (hi >> 32) & ((1LL << (LDBL_MANT_DIG - 86)) - 1);
+
+ return u.d;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c b/libc/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
new file mode 100644
index 000000000..2a7b70fab
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
@@ -0,0 +1,138 @@
+/* Print floating point number in hexadecimal notation according to ISO C99.
+ Copyright (C) 1997,1998,1999,2000,2001,2002,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define PRINT_FPHEX_LONG_DOUBLE \
+do { \
+ /* We have 105 bits of mantissa plus one implicit digit. Since \
+ 106 bits are representable without rest using hexadecimal \
+ digits we use only the implicit digits for the number before \
+ the decimal point. */ \
+ unsigned long long int num0, num1; \
+ unsigned long long hi, lo; \
+ int ediff; \
+ union ibm_extended_long_double eldbl; \
+ eldbl.d = fpnum.ldbl.d; \
+ \
+ assert (sizeof (long double) == 16); \
+ \
+ lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; \
+ hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; \
+ /* If the lower double is not a denomal or zero then set the hidden \
+ 53rd bit. */ \
+ if (eldbl.ieee.exponent2 > 0x001) \
+ { \
+ lo |= (1ULL << 52); \
+ lo = lo << 7; /* pre-shift lo to match ieee854. */ \
+ /* The lower double is normalized separately from the upper. We \
+ may need to adjust the lower manitissa to reflect this. */ \
+ ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; \
+ if (ediff > 53) \
+ lo = lo >> (ediff-53); \
+ } \
+ \
+ if ((eldbl.ieee.negative != eldbl.ieee.negative2) \
+ && ((eldbl.ieee.exponent2 != 0) && (lo != 0L))) \
+ { \
+ lo = (1ULL << 60) - lo; \
+ if (hi == 0L) \
+ { \
+ /* we have a borrow from the hidden bit, so shift left 1. */ \
+ hi = 0xffffffffffffeLL | (lo >> 59); \
+ lo = 0xfffffffffffffffLL & (lo << 1); \
+ eldbl.ieee.exponent--; \
+ } \
+ else \
+ hi--; \
+ } \
+ num1 = (hi << 60) | lo; \
+ num0 = hi >> 4; \
+ \
+ zero_mantissa = (num0|num1) == 0; \
+ \
+ if (sizeof (unsigned long int) > 6) \
+ { \
+ numstr = _itoa_word (num1, numbuf + sizeof numbuf, 16, \
+ info->spec == 'A'); \
+ wnumstr = _itowa_word (num1, \
+ wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),\
+ 16, info->spec == 'A'); \
+ } \
+ else \
+ { \
+ numstr = _itoa (num1, numbuf + sizeof numbuf, 16, \
+ info->spec == 'A'); \
+ wnumstr = _itowa (num1, \
+ wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t), \
+ 16, info->spec == 'A'); \
+ } \
+ \
+ while (numstr > numbuf + (sizeof numbuf - 64 / 4)) \
+ { \
+ *--numstr = '0'; \
+ *--wnumstr = L'0'; \
+ } \
+ \
+ if (sizeof (unsigned long int) > 6) \
+ { \
+ numstr = _itoa_word (num0, numstr, 16, info->spec == 'A'); \
+ wnumstr = _itowa_word (num0, wnumstr, 16, info->spec == 'A'); \
+ } \
+ else \
+ { \
+ numstr = _itoa (num0, numstr, 16, info->spec == 'A'); \
+ wnumstr = _itowa (num0, wnumstr, 16, info->spec == 'A'); \
+ } \
+ \
+ /* Fill with zeroes. */ \
+ while (numstr > numbuf + (sizeof numbuf - 112 / 4)) \
+ { \
+ *--numstr = '0'; \
+ *--wnumstr = L'0'; \
+ } \
+ \
+ leading = eldbl.ieee.exponent == 0 ? '0' : '1'; \
+ \
+ exponent = eldbl.ieee.exponent; \
+ \
+ if (exponent == 0) \
+ { \
+ if (zero_mantissa) \
+ expnegative = 0; \
+ else \
+ { \
+ /* This is a denormalized number. */ \
+ expnegative = 1; \
+ exponent = IBM_EXTENDED_LONG_DOUBLE_BIAS - 1; \
+ } \
+ } \
+ else if (exponent >= IBM_EXTENDED_LONG_DOUBLE_BIAS) \
+ { \
+ expnegative = 0; \
+ exponent -= IBM_EXTENDED_LONG_DOUBLE_BIAS; \
+ } \
+ else \
+ { \
+ expnegative = 1; \
+ exponent = -(exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS); \
+ } \
+} while (0)
+
+#include <stdio-common/printf_fphex.c>
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c
new file mode 100644
index 000000000..d1b63bb90
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c
@@ -0,0 +1,67 @@
+/* @(#)s_asinh.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_asinh.c,v 1.9 1995/05/12 04:57:37 jtc Exp $";
+#endif
+
+/* asinh(x)
+ * Method :
+ * Based on
+ * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
+ * we have
+ * asinh(x) := x if 1+x*x=1,
+ * := sign(x)*(log(x)+ln2)) for large |x|, else
+ * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
+ * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+one = 1.00000000000000000000e+00L, /* 0x3ff0000000000000, 0 */
+ln2 = 0.6931471805599453094172321214581766L, /* 0x3fe62e42fefa39ef, 0x3c7abc9e3b398040 */
+huge= 1.00000000000000000000e+300L;
+
+#ifdef __STDC__
+ long double __asinhl(long double x)
+#else
+ long double __asinhl(x)
+ long double x;
+#endif
+{
+ long double t,w;
+ int64_t hx,ix;
+ GET_LDOUBLE_MSW64(hx,x);
+ ix = hx&0x7fffffffffffffffLL;
+ if(ix>=0x7ff0000000000000LL) return x+x; /* x is inf or NaN */
+ if(ix< 0x3e20000000000000LL) { /* |x|<2**-29 */
+ if(huge+x>one) return x; /* return x inexact except 0 */
+ }
+ if(ix>0x41b0000000000000LL) { /* |x| > 2**28 */
+ w = __ieee754_logl(fabs(x))+ln2;
+ } else if (ix>0x4000000000000000LL) { /* 2**28 > |x| > 2.0 */
+ t = fabs(x);
+ w = __ieee754_logl(2.0*t+one/(__ieee754_sqrtl(x*x+one)+t));
+ } else { /* 2.0 > |x| > 2**-29 */
+ t = x*x;
+ w =__log1pl(fabsl(x)+t/(one+__ieee754_sqrtl(one+t)));
+ }
+ if(hx>0) return w; else return -w;
+}
+long_double_symbol (libm, __asinhl, asinhl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_atanl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_atanl.c
new file mode 100644
index 000000000..b6195f10b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_atanl.c
@@ -0,0 +1,234 @@
+/* s_atanl.c
+ *
+ * Inverse circular tangent for 128-bit long double precision
+ * (arctangent)
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, atanl();
+ *
+ * y = atanl( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns radian angle between -pi/2 and +pi/2 whose tangent is x.
+ *
+ * The function uses a rational approximation of the form
+ * t + t^3 P(t^2)/Q(t^2), optimized for |t| < 0.09375.
+ *
+ * The argument is reduced using the identity
+ * arctan x - arctan u = arctan ((x-u)/(1 + ux))
+ * and an 83-entry lookup table for arctan u, with u = 0, 1/8, ..., 10.25.
+ * Use of the table improves the execution speed of the routine.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -19, 19 4e5 1.7e-34 5.4e-35
+ *
+ *
+ * WARNING:
+ *
+ * This program uses integer operations on bit fields of floating-point
+ * numbers. It does not work with data structures other than the
+ * structure assumed.
+ *
+ */
+
+/* Copyright 2001 by Stephen L. Moshier <moshier@na-net.ornl.gov>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+/* arctan(k/8), k = 0, ..., 82 */
+static const long double atantbl[84] = {
+ 0.0000000000000000000000000000000000000000E0L,
+ 1.2435499454676143503135484916387102557317E-1L, /* arctan(0.125) */
+ 2.4497866312686415417208248121127581091414E-1L,
+ 3.5877067027057222039592006392646049977698E-1L,
+ 4.6364760900080611621425623146121440202854E-1L,
+ 5.5859931534356243597150821640166127034645E-1L,
+ 6.4350110879328438680280922871732263804151E-1L,
+ 7.1882999962162450541701415152590465395142E-1L,
+ 7.8539816339744830961566084581987572104929E-1L,
+ 8.4415398611317100251784414827164750652594E-1L,
+ 8.9605538457134395617480071802993782702458E-1L,
+ 9.4200004037946366473793717053459358607166E-1L,
+ 9.8279372324732906798571061101466601449688E-1L,
+ 1.0191413442663497346383429170230636487744E0L,
+ 1.0516502125483736674598673120862998296302E0L,
+ 1.0808390005411683108871567292171998202703E0L,
+ 1.1071487177940905030170654601785370400700E0L,
+ 1.1309537439791604464709335155363278047493E0L,
+ 1.1525719972156675180401498626127513797495E0L,
+ 1.1722738811284763866005949441337046149712E0L,
+ 1.1902899496825317329277337748293183376012E0L,
+ 1.2068173702852525303955115800565576303133E0L,
+ 1.2220253232109896370417417439225704908830E0L,
+ 1.2360594894780819419094519711090786987027E0L,
+ 1.2490457723982544258299170772810901230778E0L,
+ 1.2610933822524404193139408812473357720101E0L,
+ 1.2722973952087173412961937498224804940684E0L,
+ 1.2827408797442707473628852511364955306249E0L,
+ 1.2924966677897852679030914214070816845853E0L,
+ 1.3016288340091961438047858503666855921414E0L,
+ 1.3101939350475556342564376891719053122733E0L,
+ 1.3182420510168370498593302023271362531155E0L,
+ 1.3258176636680324650592392104284756311844E0L,
+ 1.3329603993374458675538498697331558093700E0L,
+ 1.3397056595989995393283037525895557411039E0L,
+ 1.3460851583802539310489409282517796256512E0L,
+ 1.3521273809209546571891479413898128509842E0L,
+ 1.3578579772154994751124898859640585287459E0L,
+ 1.3633001003596939542892985278250991189943E0L,
+ 1.3684746984165928776366381936948529556191E0L,
+ 1.3734007669450158608612719264449611486510E0L,
+ 1.3780955681325110444536609641291551522494E0L,
+ 1.3825748214901258580599674177685685125566E0L,
+ 1.3868528702577214543289381097042486034883E0L,
+ 1.3909428270024183486427686943836432060856E0L,
+ 1.3948567013423687823948122092044222644895E0L,
+ 1.3986055122719575950126700816114282335732E0L,
+ 1.4021993871854670105330304794336492676944E0L,
+ 1.4056476493802697809521934019958079881002E0L,
+ 1.4089588955564736949699075250792569287156E0L,
+ 1.4121410646084952153676136718584891599630E0L,
+ 1.4152014988178669079462550975833894394929E0L,
+ 1.4181469983996314594038603039700989523716E0L,
+ 1.4209838702219992566633046424614466661176E0L,
+ 1.4237179714064941189018190466107297503086E0L,
+ 1.4263547484202526397918060597281265695725E0L,
+ 1.4288992721907326964184700745371983590908E0L,
+ 1.4313562697035588982240194668401779312122E0L,
+ 1.4337301524847089866404719096698873648610E0L,
+ 1.4360250423171655234964275337155008780675E0L,
+ 1.4382447944982225979614042479354815855386E0L,
+ 1.4403930189057632173997301031392126865694E0L,
+ 1.4424730991091018200252920599377292525125E0L,
+ 1.4444882097316563655148453598508037025938E0L,
+ 1.4464413322481351841999668424758804165254E0L,
+ 1.4483352693775551917970437843145232637695E0L,
+ 1.4501726582147939000905940595923466567576E0L,
+ 1.4519559822271314199339700039142990228105E0L,
+ 1.4536875822280323362423034480994649820285E0L,
+ 1.4553696664279718992423082296859928222270E0L,
+ 1.4570043196511885530074841089245667532358E0L,
+ 1.4585935117976422128825857356750737658039E0L,
+ 1.4601391056210009726721818194296893361233E0L,
+ 1.4616428638860188872060496086383008594310E0L,
+ 1.4631064559620759326975975316301202111560E0L,
+ 1.4645314639038178118428450961503371619177E0L,
+ 1.4659193880646627234129855241049975398470E0L,
+ 1.4672716522843522691530527207287398276197E0L,
+ 1.4685896086876430842559640450619880951144E0L,
+ 1.4698745421276027686510391411132998919794E0L,
+ 1.4711276743037345918528755717617308518553E0L,
+ 1.4723501675822635384916444186631899205983E0L,
+ 1.4735431285433308455179928682541563973416E0L, /* arctan(10.25) */
+ 1.5707963267948966192313216916397514420986E0L /* pi/2 */
+};
+
+
+/* arctan t = t + t^3 p(t^2) / q(t^2)
+ |t| <= 0.09375
+ peak relative error 5.3e-37 */
+
+static const long double
+ p0 = -4.283708356338736809269381409828726405572E1L,
+ p1 = -8.636132499244548540964557273544599863825E1L,
+ p2 = -5.713554848244551350855604111031839613216E1L,
+ p3 = -1.371405711877433266573835355036413750118E1L,
+ p4 = -8.638214309119210906997318946650189640184E-1L,
+ q0 = 1.285112506901621042780814422948906537959E2L,
+ q1 = 3.361907253914337187957855834229672347089E2L,
+ q2 = 3.180448303864130128268191635189365331680E2L,
+ q3 = 1.307244136980865800160844625025280344686E2L,
+ q4 = 2.173623741810414221251136181221172551416E1L;
+ /* q5 = 1.000000000000000000000000000000000000000E0 */
+
+
+long double
+__atanl (long double x)
+{
+ int k, sign;
+ long double t, u, p, q;
+ ieee854_long_double_shape_type s;
+
+ s.value = x;
+ k = s.parts32.w0;
+ if (k & 0x80000000)
+ sign = 1;
+ else
+ sign = 0;
+
+ /* Check for IEEE special cases. */
+ k &= 0x7fffffff;
+ if (k >= 0x7ff00000)
+ {
+ /* NaN. */
+ if ((k & 0xfffff) | s.parts32.w1 )
+ return (x + x);
+
+ /* Infinity. */
+ if (sign)
+ return -atantbl[83];
+ else
+ return atantbl[83];
+ }
+
+ if (sign)
+ x = -x;
+
+ if (k >= 0x40248000) /* 10.25 */
+ {
+ k = 83;
+ t = -1.0/x;
+ }
+ else
+ {
+ /* Index of nearest table element.
+ Roundoff to integer is asymmetrical to avoid cancellation when t < 0
+ (cf. fdlibm). */
+ k = 8.0 * x + 0.25;
+ u = 0.125 * k;
+ /* Small arctan argument. */
+ t = (x - u) / (1.0 + x * u);
+ }
+
+ /* Arctan of small argument t. */
+ u = t * t;
+ p = ((((p4 * u) + p3) * u + p2) * u + p1) * u + p0;
+ q = ((((u + q4) * u + q3) * u + q2) * u + q1) * u + q0;
+ u = t * u * p / q + t;
+
+ /* arctan x = arctan u + arctan t */
+ u = atantbl[k] + u;
+ if (sign)
+ return (-u);
+ else
+ return u;
+}
+
+long_double_symbol (libm, __atanl, atanl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c
new file mode 100644
index 000000000..010a671dc
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c
@@ -0,0 +1,6 @@
+/* Looks like we can use ieee854 s_cbrtl.c as is for IBM extended format. */
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_cbrtl.c>
+long_double_symbol (libm, __cbrtl, cbrtl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_ceill.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_ceill.c
new file mode 100644
index 000000000..035e4f52c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_ceill.c
@@ -0,0 +1,91 @@
+/* Ceil (round to +inf) long double floating-point values.
+ IBM extended format long double version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <fenv_libc.h>
+#include <math_ldbl_opt.h>
+#include <float.h>
+#include <ieee754.h>
+
+
+#ifdef __STDC__
+long double
+__ceill (long double x)
+#else
+long double
+__ceill (x)
+ long double x;
+#endif
+{
+ double xh, xl, hi, lo;
+
+ ldbl_unpack (x, &xh, &xl);
+
+ /* Return Inf, Nan, +/-0 unchanged. */
+ if (__builtin_expect (xh != 0.0
+ && __builtin_isless (__builtin_fabs (xh),
+ __builtin_inf ()), 1))
+ {
+ double orig_xh;
+ int save_round = fegetround ();
+
+ /* Long double arithmetic, including the canonicalisation below,
+ only works in round-to-nearest mode. */
+ fesetround (FE_TONEAREST);
+
+ /* Convert the high double to integer. */
+ orig_xh = xh;
+ hi = ldbl_nearbyint (xh);
+
+ /* Subtract integral high part from the value. */
+ xh -= hi;
+ ldbl_canonicalize (&xh, &xl);
+
+ /* Now convert the low double, adjusted for any remainder from the
+ high double. */
+ lo = ldbl_nearbyint (xh);
+
+ /* Adjust the result when the remainder is non-zero. nearbyint
+ rounds values to the nearest integer, and values halfway
+ between integers to the nearest even integer. ceill must
+ round towards +Inf. */
+ xh -= lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ if (xh > 0.0 || (xh == 0.0 && xl > 0.0))
+ lo += 1.0;
+
+ /* Ensure the final value is canonical. In certain cases,
+ rounding causes hi,lo calculated so far to be non-canonical. */
+ xh = hi;
+ xl = lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ /* Ensure we return -0 rather than +0 when appropriate. */
+ if (orig_xh < 0.0)
+ xh = -__builtin_fabs (xh);
+
+ fesetround (save_round);
+ }
+
+ return ldbl_pack (xh, xl);
+}
+
+long_double_symbol (libm, __ceill, ceill);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_copysignl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_copysignl.c
new file mode 100644
index 000000000..7e7b44168
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_copysignl.c
@@ -0,0 +1,45 @@
+/* s_copysignl.c -- long double version of s_copysign.c.
+ * Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * copysignl(long double x, long double y)
+ * copysignl(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __copysignl(long double x, long double y)
+#else
+ long double __copysignl(x,y)
+ long double x,y;
+#endif
+{
+ if (y < 0.0)
+ {
+ if (x >= 0.0)
+ x = -x;
+ }
+ else if (x < 0.0)
+ x = -x;
+ return x;
+}
+weak_alias (__copysignl, copysignl)
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_cosl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_cosl.c
new file mode 100644
index 000000000..59a819670
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_cosl.c
@@ -0,0 +1,88 @@
+/* s_cosl.c -- long double version of s_cos.c.
+ * Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* cosl(x)
+ * Return cosine function of x.
+ *
+ * kernel function:
+ * __kernel_sinl ... sine function on [-pi/4,pi/4]
+ * __kernel_cosl ... cosine function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2l ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+ long double __cosl(long double x)
+#else
+ long double __cosl(x)
+ long double x;
+#endif
+{
+ long double y[2],z=0.0L;
+ int64_t n, ix;
+
+ /* High word of x. */
+ GET_LDOUBLE_MSW64(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffffffffffffLL;
+ if(ix <= 0x3fe921fb54442d18LL)
+ return __kernel_cosl(x,z);
+
+ /* cos(Inf or NaN) is NaN */
+ else if (ix>=0x7ff0000000000000LL)
+ return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2l(x,y);
+ switch(n&3) {
+ case 0:
+ return __kernel_cosl(y[0],y[1]);
+ case 1:
+ return -__kernel_sinl(y[0],y[1],1);
+ case 2:
+ return -__kernel_cosl(y[0],y[1]);
+ default:
+ return __kernel_sinl(y[0],y[1],1);
+ }
+ }
+}
+long_double_symbol (libm, __cosl, cosl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_cprojl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_cprojl.c
new file mode 100644
index 000000000..2167db3d9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_cprojl.c
@@ -0,0 +1,54 @@
+/* Compute projection of complex long double value to Riemann sphere.
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <complex.h>
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+__complex__ long double
+__cprojl (__complex__ long double x)
+{
+ __complex__ long double res;
+
+ if (isnan (__real__ x) && isnan (__imag__ x))
+ return x;
+ else if (!isfinite (__real__ x) || !isfinite (__imag__ x))
+ {
+ __real__ res = INFINITY;
+ __imag__ res = __copysignl (0.0, __imag__ x);
+ }
+ else
+ {
+ long double den = (__real__ x * __real__ x + __imag__ x * __imag__ x
+ + 1.0);
+
+ __real__ res = (2.0 * __real__ x) / den;
+ __imag__ res = (2.0 * __imag__ x) / den;
+ /* __gcc_qmul does not respect -0.0 so we need the following fixup. */
+ if (__real__ x == 0.0)
+ __real__ res = __real__ x;
+
+ if (__imag__ x == 0.0)
+ __imag__ res = __imag__ x;
+ }
+
+ return res;
+}
+long_double_symbol (libm, __cprojl, cprojl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_ctanhl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_ctanhl.c
new file mode 100644
index 000000000..7d619039c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_ctanhl.c
@@ -0,0 +1,87 @@
+/* Complex hyperbole tangent for long double. IBM extended format version.
+ Copyright (C) 1997,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <complex.h>
+#include <fenv.h>
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+#include "math_private.h"
+
+
+__complex__ long double
+__ctanhl (__complex__ long double x)
+{
+ __complex__ long double res;
+
+ if (!isfinite (__real__ x) || !isfinite (__imag__ x))
+ {
+ if (__isinfl (__real__ x))
+ {
+ __real__ res = __copysignl (1.0, __real__ x);
+ __imag__ res = __copysignl (0.0, __imag__ x);
+ }
+ else if (__imag__ x == 0.0)
+ {
+ res = x;
+ }
+ else
+ {
+ __real__ res = __nanl ("");
+ __imag__ res = __nanl ("");
+
+#ifdef FE_INVALID
+ if (__isinfl (__imag__ x))
+ feraiseexcept (FE_INVALID);
+#endif
+ }
+ }
+ else
+ {
+ long double sin2ix, cos2ix;
+ long double den;
+
+ __sincosl (2.0 * __imag__ x, &sin2ix, &cos2ix);
+
+ den = (__ieee754_coshl (2.0 * __real__ x) + cos2ix);
+
+ if (den == 0.0L)
+ {
+ __complex__ long double ez = __cexpl (x);
+ __complex__ long double emz = __cexpl (-x);
+
+ res = (ez - emz) / (ez + emz);
+ }
+ else
+ {
+ __real__ res = __ieee754_sinhl (2.0 * __real__ x) / den;
+ __imag__ res = sin2ix / den;
+ }
+ /* __gcc_qmul does not respect -0.0 so we need the following fixup. */
+ if ((__real__ res == 0.0) && (__real__ x == 0.0))
+ __real__ res = __real__ x;
+
+ if ((__real__ res == 0.0) && (__imag__ x == 0.0))
+ __imag__ res = __imag__ x;
+ }
+
+ return res;
+}
+long_double_symbol (libm, __ctanhl, ctanhl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_ctanl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_ctanl.c
new file mode 100644
index 000000000..00d2aa6b6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_ctanl.c
@@ -0,0 +1,88 @@
+/* Complex tangent function for long double. IBM extended format version.
+ Copyright (C) 1997,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <complex.h>
+#include <fenv.h>
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+#include "math_private.h"
+
+
+__complex__ long double
+__ctanl (__complex__ long double x)
+{
+ __complex__ long double res;
+
+ if (!isfinite (__real__ x) || !isfinite (__imag__ x))
+ {
+ if (__isinfl (__imag__ x))
+ {
+ __real__ res = __copysignl (0.0, __real__ x);
+ __imag__ res = __copysignl (1.0, __imag__ x);
+ }
+ else if (__real__ x == 0.0)
+ {
+ res = x;
+ }
+ else
+ {
+ __real__ res = __nanl ("");
+ __imag__ res = __nanl ("");
+
+#ifdef FE_INVALID
+ if (__isinfl (__real__ x))
+ feraiseexcept (FE_INVALID);
+#endif
+ }
+ }
+ else
+ {
+ long double sin2rx, cos2rx;
+ long double den;
+
+ __sincosl (2.0 * __real__ x, &sin2rx, &cos2rx);
+
+ den = cos2rx + __ieee754_coshl (2.0 * __imag__ x);
+
+
+ if (den == 0.0)
+ {
+ __complex__ long double ez = __cexpl (1.0i * x);
+ __complex__ long double emz = __cexpl (-1.0i * x);
+
+ res = (ez - emz) / (ez + emz) * -1.0i;
+ }
+ else
+ {
+ __real__ res = sin2rx / den;
+ __imag__ res = __ieee754_sinhl (2.0 * __imag__ x) / den;
+ }
+ /* __gcc_qmul does not respect -0.0 so we need the following fixup. */
+ if ((__real__ res == 0.0) && (__real__ x == 0.0))
+ __real__ res = __real__ x;
+
+ if ((__real__ res == 0.0) && (__imag__ x == 0.0))
+ __imag__ res = __imag__ x;
+ }
+
+ return res;
+}
+long_double_symbol (libm, __ctanl, ctanl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_erfl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_erfl.c
new file mode 100644
index 000000000..02b450efc
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_erfl.c
@@ -0,0 +1,958 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* Modifications and expansions for 128-bit long double are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* double erf(double x)
+ * double erfc(double x)
+ * x
+ * 2 |\
+ * erf(x) = --------- | exp(-t*t)dt
+ * sqrt(pi) \|
+ * 0
+ *
+ * erfc(x) = 1-erf(x)
+ * Note that
+ * erf(-x) = -erf(x)
+ * erfc(-x) = 2 - erfc(x)
+ *
+ * Method:
+ * 1. erf(x) = x + x*R(x^2) for |x| in [0, 7/8]
+ * Remark. The formula is derived by noting
+ * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ * and that
+ * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ * is close to one.
+ *
+ * 1a. erf(x) = 1 - erfc(x), for |x| > 1.0
+ * erfc(x) = 1 - erf(x) if |x| < 1/4
+ *
+ * 2. For |x| in [7/8, 1], let s = |x| - 1, and
+ * c = 0.84506291151 rounded to single (24 bits)
+ * erf(s + c) = sign(x) * (c + P1(s)/Q1(s))
+ * Remark: here we use the taylor series expansion at x=1.
+ * erf(1+s) = erf(1) + s*Poly(s)
+ * = 0.845.. + P1(s)/Q1(s)
+ * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ *
+ * 3. For x in [1/4, 5/4],
+ * erfc(s + const) = erfc(const) + s P1(s)/Q1(s)
+ * for const = 1/4, 3/8, ..., 9/8
+ * and 0 <= s <= 1/8 .
+ *
+ * 4. For x in [5/4, 107],
+ * erfc(x) = (1/x)*exp(-x*x-0.5625 + R(z))
+ * z=1/x^2
+ * The interval is partitioned into several segments
+ * of width 1/8 in 1/x.
+ *
+ * Note1:
+ * To compute exp(-x*x-0.5625+R/S), let s be a single
+ * precision number and s := x; then
+ * -x*x = -s*s + (s-x)*(s+x)
+ * exp(-x*x-0.5626+R/S) =
+ * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
+ * Note2:
+ * Here 4 and 5 make use of the asymptotic series
+ * exp(-x*x)
+ * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
+ * x*sqrt(pi)
+ *
+ * 5. For inf > x >= 107
+ * erf(x) = sign(x) *(1 - tiny) (raise inexact)
+ * erfc(x) = tiny*tiny (raise underflow) if x > 0
+ * = 2 - tiny if x<0
+ *
+ * 7. Special case:
+ * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
+ * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
+ * erfc/erf(NaN) is NaN
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+neval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static long double
+deval (long double x, const long double *p, int n)
+{
+ long double y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+tiny = 1e-300L,
+ half = 0.5L,
+ one = 1.0L,
+ two = 2.0L,
+ /* 2/sqrt(pi) - 1 */
+ efx = 1.2837916709551257389615890312154517168810E-1L,
+ /* 8 * (2/sqrt(pi) - 1) */
+ efx8 = 1.0270333367641005911692712249723613735048E0L;
+
+
+/* erf(x) = x + x R(x^2)
+ 0 <= x <= 7/8
+ Peak relative error 1.8e-35 */
+#define NTN1 8
+static const long double TN1[NTN1 + 1] =
+{
+ -3.858252324254637124543172907442106422373E10L,
+ 9.580319248590464682316366876952214879858E10L,
+ 1.302170519734879977595901236693040544854E10L,
+ 2.922956950426397417800321486727032845006E9L,
+ 1.764317520783319397868923218385468729799E8L,
+ 1.573436014601118630105796794840834145120E7L,
+ 4.028077380105721388745632295157816229289E5L,
+ 1.644056806467289066852135096352853491530E4L,
+ 3.390868480059991640235675479463287886081E1L
+};
+#define NTD1 8
+static const long double TD1[NTD1 + 1] =
+{
+ -3.005357030696532927149885530689529032152E11L,
+ -1.342602283126282827411658673839982164042E11L,
+ -2.777153893355340961288511024443668743399E10L,
+ -3.483826391033531996955620074072768276974E9L,
+ -2.906321047071299585682722511260895227921E8L,
+ -1.653347985722154162439387878512427542691E7L,
+ -6.245520581562848778466500301865173123136E5L,
+ -1.402124304177498828590239373389110545142E4L,
+ -1.209368072473510674493129989468348633579E2L
+/* 1.0E0 */
+};
+
+
+/* erf(z+1) = erf_const + P(z)/Q(z)
+ -.125 <= z <= 0
+ Peak relative error 7.3e-36 */
+static const long double erf_const = 0.845062911510467529296875L;
+#define NTN2 8
+static const long double TN2[NTN2 + 1] =
+{
+ -4.088889697077485301010486931817357000235E1L,
+ 7.157046430681808553842307502826960051036E3L,
+ -2.191561912574409865550015485451373731780E3L,
+ 2.180174916555316874988981177654057337219E3L,
+ 2.848578658049670668231333682379720943455E2L,
+ 1.630362490952512836762810462174798925274E2L,
+ 6.317712353961866974143739396865293596895E0L,
+ 2.450441034183492434655586496522857578066E1L,
+ 5.127662277706787664956025545897050896203E-1L
+};
+#define NTD2 8
+static const long double TD2[NTD2 + 1] =
+{
+ 1.731026445926834008273768924015161048885E4L,
+ 1.209682239007990370796112604286048173750E4L,
+ 1.160950290217993641320602282462976163857E4L,
+ 5.394294645127126577825507169061355698157E3L,
+ 2.791239340533632669442158497532521776093E3L,
+ 8.989365571337319032943005387378993827684E2L,
+ 2.974016493766349409725385710897298069677E2L,
+ 6.148192754590376378740261072533527271947E1L,
+ 1.178502892490738445655468927408440847480E1L
+ /* 1.0E0 */
+};
+
+
+/* erfc(x + 0.25) = erfc(0.25) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 1.4e-35 */
+#define NRNr13 8
+static const long double RNr13[NRNr13 + 1] =
+{
+ -2.353707097641280550282633036456457014829E3L,
+ 3.871159656228743599994116143079870279866E2L,
+ -3.888105134258266192210485617504098426679E2L,
+ -2.129998539120061668038806696199343094971E1L,
+ -8.125462263594034672468446317145384108734E1L,
+ 8.151549093983505810118308635926270319660E0L,
+ -5.033362032729207310462422357772568553670E0L,
+ -4.253956621135136090295893547735851168471E-2L,
+ -8.098602878463854789780108161581050357814E-2L
+};
+#define NRDr13 7
+static const long double RDr13[NRDr13 + 1] =
+{
+ 2.220448796306693503549505450626652881752E3L,
+ 1.899133258779578688791041599040951431383E2L,
+ 1.061906712284961110196427571557149268454E3L,
+ 7.497086072306967965180978101974566760042E1L,
+ 2.146796115662672795876463568170441327274E2L,
+ 1.120156008362573736664338015952284925592E1L,
+ 2.211014952075052616409845051695042741074E1L,
+ 6.469655675326150785692908453094054988938E-1L
+ /* 1.0E0 */
+};
+/* erfc(0.25) = C13a + C13b to extra precision. */
+static const long double C13a = 0.723663330078125L;
+static const long double C13b = 1.0279753638067014931732235184287934646022E-5L;
+
+
+/* erfc(x + 0.375) = erfc(0.375) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 1.2e-35 */
+#define NRNr14 8
+static const long double RNr14[NRNr14 + 1] =
+{
+ -2.446164016404426277577283038988918202456E3L,
+ 6.718753324496563913392217011618096698140E2L,
+ -4.581631138049836157425391886957389240794E2L,
+ -2.382844088987092233033215402335026078208E1L,
+ -7.119237852400600507927038680970936336458E1L,
+ 1.313609646108420136332418282286454287146E1L,
+ -6.188608702082264389155862490056401365834E0L,
+ -2.787116601106678287277373011101132659279E-2L,
+ -2.230395570574153963203348263549700967918E-2L
+};
+#define NRDr14 7
+static const long double RDr14[NRDr14 + 1] =
+{
+ 2.495187439241869732696223349840963702875E3L,
+ 2.503549449872925580011284635695738412162E2L,
+ 1.159033560988895481698051531263861842461E3L,
+ 9.493751466542304491261487998684383688622E1L,
+ 2.276214929562354328261422263078480321204E2L,
+ 1.367697521219069280358984081407807931847E1L,
+ 2.276988395995528495055594829206582732682E1L,
+ 7.647745753648996559837591812375456641163E-1L
+ /* 1.0E0 */
+};
+/* erfc(0.375) = C14a + C14b to extra precision. */
+static const long double C14a = 0.5958709716796875L;
+static const long double C14b = 1.2118885490201676174914080878232469565953E-5L;
+
+/* erfc(x + 0.5) = erfc(0.5) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 4.7e-36 */
+#define NRNr15 8
+static const long double RNr15[NRNr15 + 1] =
+{
+ -2.624212418011181487924855581955853461925E3L,
+ 8.473828904647825181073831556439301342756E2L,
+ -5.286207458628380765099405359607331669027E2L,
+ -3.895781234155315729088407259045269652318E1L,
+ -6.200857908065163618041240848728398496256E1L,
+ 1.469324610346924001393137895116129204737E1L,
+ -6.961356525370658572800674953305625578903E0L,
+ 5.145724386641163809595512876629030548495E-3L,
+ 1.990253655948179713415957791776180406812E-2L
+};
+#define NRDr15 7
+static const long double RDr15[NRDr15 + 1] =
+{
+ 2.986190760847974943034021764693341524962E3L,
+ 5.288262758961073066335410218650047725985E2L,
+ 1.363649178071006978355113026427856008978E3L,
+ 1.921707975649915894241864988942255320833E2L,
+ 2.588651100651029023069013885900085533226E2L,
+ 2.628752920321455606558942309396855629459E1L,
+ 2.455649035885114308978333741080991380610E1L,
+ 1.378826653595128464383127836412100939126E0L
+ /* 1.0E0 */
+};
+/* erfc(0.5) = C15a + C15b to extra precision. */
+static const long double C15a = 0.4794921875L;
+static const long double C15b = 7.9346869534623172533461080354712635484242E-6L;
+
+/* erfc(x + 0.625) = erfc(0.625) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 5.1e-36 */
+#define NRNr16 8
+static const long double RNr16[NRNr16 + 1] =
+{
+ -2.347887943200680563784690094002722906820E3L,
+ 8.008590660692105004780722726421020136482E2L,
+ -5.257363310384119728760181252132311447963E2L,
+ -4.471737717857801230450290232600243795637E1L,
+ -4.849540386452573306708795324759300320304E1L,
+ 1.140885264677134679275986782978655952843E1L,
+ -6.731591085460269447926746876983786152300E0L,
+ 1.370831653033047440345050025876085121231E-1L,
+ 2.022958279982138755020825717073966576670E-2L,
+};
+#define NRDr16 7
+static const long double RDr16[NRDr16 + 1] =
+{
+ 3.075166170024837215399323264868308087281E3L,
+ 8.730468942160798031608053127270430036627E2L,
+ 1.458472799166340479742581949088453244767E3L,
+ 3.230423687568019709453130785873540386217E2L,
+ 2.804009872719893612081109617983169474655E2L,
+ 4.465334221323222943418085830026979293091E1L,
+ 2.612723259683205928103787842214809134746E1L,
+ 2.341526751185244109722204018543276124997E0L,
+ /* 1.0E0 */
+};
+/* erfc(0.625) = C16a + C16b to extra precision. */
+static const long double C16a = 0.3767547607421875L;
+static const long double C16b = 4.3570693945275513594941232097252997287766E-6L;
+
+/* erfc(x + 0.75) = erfc(0.75) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 1.7e-35 */
+#define NRNr17 8
+static const long double RNr17[NRNr17 + 1] =
+{
+ -1.767068734220277728233364375724380366826E3L,
+ 6.693746645665242832426891888805363898707E2L,
+ -4.746224241837275958126060307406616817753E2L,
+ -2.274160637728782675145666064841883803196E1L,
+ -3.541232266140939050094370552538987982637E1L,
+ 6.988950514747052676394491563585179503865E0L,
+ -5.807687216836540830881352383529281215100E0L,
+ 3.631915988567346438830283503729569443642E-1L,
+ -1.488945487149634820537348176770282391202E-2L
+};
+#define NRDr17 7
+static const long double RDr17[NRDr17 + 1] =
+{
+ 2.748457523498150741964464942246913394647E3L,
+ 1.020213390713477686776037331757871252652E3L,
+ 1.388857635935432621972601695296561952738E3L,
+ 3.903363681143817750895999579637315491087E2L,
+ 2.784568344378139499217928969529219886578E2L,
+ 5.555800830216764702779238020065345401144E1L,
+ 2.646215470959050279430447295801291168941E1L,
+ 2.984905282103517497081766758550112011265E0L,
+ /* 1.0E0 */
+};
+/* erfc(0.75) = C17a + C17b to extra precision. */
+static const long double C17a = 0.2888336181640625L;
+static const long double C17b = 1.0748182422368401062165408589222625794046E-5L;
+
+
+/* erfc(x + 0.875) = erfc(0.875) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 2.2e-35 */
+#define NRNr18 8
+static const long double RNr18[NRNr18 + 1] =
+{
+ -1.342044899087593397419622771847219619588E3L,
+ 6.127221294229172997509252330961641850598E2L,
+ -4.519821356522291185621206350470820610727E2L,
+ 1.223275177825128732497510264197915160235E1L,
+ -2.730789571382971355625020710543532867692E1L,
+ 4.045181204921538886880171727755445395862E0L,
+ -4.925146477876592723401384464691452700539E0L,
+ 5.933878036611279244654299924101068088582E-1L,
+ -5.557645435858916025452563379795159124753E-2L
+};
+#define NRDr18 7
+static const long double RDr18[NRDr18 + 1] =
+{
+ 2.557518000661700588758505116291983092951E3L,
+ 1.070171433382888994954602511991940418588E3L,
+ 1.344842834423493081054489613250688918709E3L,
+ 4.161144478449381901208660598266288188426E2L,
+ 2.763670252219855198052378138756906980422E2L,
+ 5.998153487868943708236273854747564557632E1L,
+ 2.657695108438628847733050476209037025318E1L,
+ 3.252140524394421868923289114410336976512E0L,
+ /* 1.0E0 */
+};
+/* erfc(0.875) = C18a + C18b to extra precision. */
+static const long double C18a = 0.215911865234375L;
+static const long double C18b = 1.3073705765341685464282101150637224028267E-5L;
+
+/* erfc(x + 1.0) = erfc(1.0) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 1.6e-35 */
+#define NRNr19 8
+static const long double RNr19[NRNr19 + 1] =
+{
+ -1.139180936454157193495882956565663294826E3L,
+ 6.134903129086899737514712477207945973616E2L,
+ -4.628909024715329562325555164720732868263E2L,
+ 4.165702387210732352564932347500364010833E1L,
+ -2.286979913515229747204101330405771801610E1L,
+ 1.870695256449872743066783202326943667722E0L,
+ -4.177486601273105752879868187237000032364E0L,
+ 7.533980372789646140112424811291782526263E-1L,
+ -8.629945436917752003058064731308767664446E-2L
+};
+#define NRDr19 7
+static const long double RDr19[NRDr19 + 1] =
+{
+ 2.744303447981132701432716278363418643778E3L,
+ 1.266396359526187065222528050591302171471E3L,
+ 1.466739461422073351497972255511919814273E3L,
+ 4.868710570759693955597496520298058147162E2L,
+ 2.993694301559756046478189634131722579643E2L,
+ 6.868976819510254139741559102693828237440E1L,
+ 2.801505816247677193480190483913753613630E1L,
+ 3.604439909194350263552750347742663954481E0L,
+ /* 1.0E0 */
+};
+/* erfc(1.0) = C19a + C19b to extra precision. */
+static const long double C19a = 0.15728759765625L;
+static const long double C19b = 1.1609394035130658779364917390740703933002E-5L;
+
+/* erfc(x + 1.125) = erfc(1.125) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 3.6e-36 */
+#define NRNr20 8
+static const long double RNr20[NRNr20 + 1] =
+{
+ -9.652706916457973956366721379612508047640E2L,
+ 5.577066396050932776683469951773643880634E2L,
+ -4.406335508848496713572223098693575485978E2L,
+ 5.202893466490242733570232680736966655434E1L,
+ -1.931311847665757913322495948705563937159E1L,
+ -9.364318268748287664267341457164918090611E-2L,
+ -3.306390351286352764891355375882586201069E0L,
+ 7.573806045289044647727613003096916516475E-1L,
+ -9.611744011489092894027478899545635991213E-2L
+};
+#define NRDr20 7
+static const long double RDr20[NRDr20 + 1] =
+{
+ 3.032829629520142564106649167182428189014E3L,
+ 1.659648470721967719961167083684972196891E3L,
+ 1.703545128657284619402511356932569292535E3L,
+ 6.393465677731598872500200253155257708763E2L,
+ 3.489131397281030947405287112726059221934E2L,
+ 8.848641738570783406484348434387611713070E1L,
+ 3.132269062552392974833215844236160958502E1L,
+ 4.430131663290563523933419966185230513168E0L
+ /* 1.0E0 */
+};
+/* erfc(1.125) = C20a + C20b to extra precision. */
+static const long double C20a = 0.111602783203125L;
+static const long double C20b = 8.9850951672359304215530728365232161564636E-6L;
+
+/* erfc(1/x) = 1/x exp (-1/x^2 - 0.5625 + R(1/x^2))
+ 7/8 <= 1/x < 1
+ Peak relative error 1.4e-35 */
+#define NRNr8 9
+static const long double RNr8[NRNr8 + 1] =
+{
+ 3.587451489255356250759834295199296936784E1L,
+ 5.406249749087340431871378009874875889602E2L,
+ 2.931301290625250886238822286506381194157E3L,
+ 7.359254185241795584113047248898753470923E3L,
+ 9.201031849810636104112101947312492532314E3L,
+ 5.749697096193191467751650366613289284777E3L,
+ 1.710415234419860825710780802678697889231E3L,
+ 2.150753982543378580859546706243022719599E2L,
+ 8.740953582272147335100537849981160931197E0L,
+ 4.876422978828717219629814794707963640913E-2L
+};
+#define NRDr8 8
+static const long double RDr8[NRDr8 + 1] =
+{
+ 6.358593134096908350929496535931630140282E1L,
+ 9.900253816552450073757174323424051765523E2L,
+ 5.642928777856801020545245437089490805186E3L,
+ 1.524195375199570868195152698617273739609E4L,
+ 2.113829644500006749947332935305800887345E4L,
+ 1.526438562626465706267943737310282977138E4L,
+ 5.561370922149241457131421914140039411782E3L,
+ 9.394035530179705051609070428036834496942E2L,
+ 6.147019596150394577984175188032707343615E1L
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp (-1/x^2 - 0.5625 + R(1/x^2))
+ 0.75 <= 1/x <= 0.875
+ Peak relative error 2.0e-36 */
+#define NRNr7 9
+static const long double RNr7[NRNr7 + 1] =
+{
+ 1.686222193385987690785945787708644476545E1L,
+ 1.178224543567604215602418571310612066594E3L,
+ 1.764550584290149466653899886088166091093E4L,
+ 1.073758321890334822002849369898232811561E5L,
+ 3.132840749205943137619839114451290324371E5L,
+ 4.607864939974100224615527007793867585915E5L,
+ 3.389781820105852303125270837910972384510E5L,
+ 1.174042187110565202875011358512564753399E5L,
+ 1.660013606011167144046604892622504338313E4L,
+ 6.700393957480661937695573729183733234400E2L
+};
+#define NRDr7 9
+static const long double RDr7[NRDr7 + 1] =
+{
+-1.709305024718358874701575813642933561169E3L,
+-3.280033887481333199580464617020514788369E4L,
+-2.345284228022521885093072363418750835214E5L,
+-8.086758123097763971926711729242327554917E5L,
+-1.456900414510108718402423999575992450138E6L,
+-1.391654264881255068392389037292702041855E6L,
+-6.842360801869939983674527468509852583855E5L,
+-1.597430214446573566179675395199807533371E5L,
+-1.488876130609876681421645314851760773480E4L,
+-3.511762950935060301403599443436465645703E2L
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 5/8 <= 1/x < 3/4
+ Peak relative error 1.9e-35 */
+#define NRNr6 9
+static const long double RNr6[NRNr6 + 1] =
+{
+ 1.642076876176834390623842732352935761108E0L,
+ 1.207150003611117689000664385596211076662E2L,
+ 2.119260779316389904742873816462800103939E3L,
+ 1.562942227734663441801452930916044224174E4L,
+ 5.656779189549710079988084081145693580479E4L,
+ 1.052166241021481691922831746350942786299E5L,
+ 9.949798524786000595621602790068349165758E4L,
+ 4.491790734080265043407035220188849562856E4L,
+ 8.377074098301530326270432059434791287601E3L,
+ 4.506934806567986810091824791963991057083E2L
+};
+#define NRDr6 9
+static const long double RDr6[NRDr6 + 1] =
+{
+-1.664557643928263091879301304019826629067E2L,
+-3.800035902507656624590531122291160668452E3L,
+-3.277028191591734928360050685359277076056E4L,
+-1.381359471502885446400589109566587443987E5L,
+-3.082204287382581873532528989283748656546E5L,
+-3.691071488256738343008271448234631037095E5L,
+-2.300482443038349815750714219117566715043E5L,
+-6.873955300927636236692803579555752171530E4L,
+-8.262158817978334142081581542749986845399E3L,
+-2.517122254384430859629423488157361983661E2L
+ /* 1.00 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 1/2 <= 1/x < 5/8
+ Peak relative error 4.6e-36 */
+#define NRNr5 10
+static const long double RNr5[NRNr5 + 1] =
+{
+-3.332258927455285458355550878136506961608E-3L,
+-2.697100758900280402659586595884478660721E-1L,
+-6.083328551139621521416618424949137195536E0L,
+-6.119863528983308012970821226810162441263E1L,
+-3.176535282475593173248810678636522589861E2L,
+-8.933395175080560925809992467187963260693E2L,
+-1.360019508488475978060917477620199499560E3L,
+-1.075075579828188621541398761300910213280E3L,
+-4.017346561586014822824459436695197089916E2L,
+-5.857581368145266249509589726077645791341E1L,
+-2.077715925587834606379119585995758954399E0L
+};
+#define NRDr5 9
+static const long double RDr5[NRDr5 + 1] =
+{
+ 3.377879570417399341550710467744693125385E-1L,
+ 1.021963322742390735430008860602594456187E1L,
+ 1.200847646592942095192766255154827011939E2L,
+ 7.118915528142927104078182863387116942836E2L,
+ 2.318159380062066469386544552429625026238E3L,
+ 4.238729853534009221025582008928765281620E3L,
+ 4.279114907284825886266493994833515580782E3L,
+ 2.257277186663261531053293222591851737504E3L,
+ 5.570475501285054293371908382916063822957E2L,
+ 5.142189243856288981145786492585432443560E1L
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 3/8 <= 1/x < 1/2
+ Peak relative error 2.0e-36 */
+#define NRNr4 10
+static const long double RNr4[NRNr4 + 1] =
+{
+ 3.258530712024527835089319075288494524465E-3L,
+ 2.987056016877277929720231688689431056567E-1L,
+ 8.738729089340199750734409156830371528862E0L,
+ 1.207211160148647782396337792426311125923E2L,
+ 8.997558632489032902250523945248208224445E2L,
+ 3.798025197699757225978410230530640879762E3L,
+ 9.113203668683080975637043118209210146846E3L,
+ 1.203285891339933238608683715194034900149E4L,
+ 8.100647057919140328536743641735339740855E3L,
+ 2.383888249907144945837976899822927411769E3L,
+ 2.127493573166454249221983582495245662319E2L
+};
+#define NRDr4 10
+static const long double RDr4[NRDr4 + 1] =
+{
+-3.303141981514540274165450687270180479586E-1L,
+-1.353768629363605300707949368917687066724E1L,
+-2.206127630303621521950193783894598987033E2L,
+-1.861800338758066696514480386180875607204E3L,
+-8.889048775872605708249140016201753255599E3L,
+-2.465888106627948210478692168261494857089E4L,
+-3.934642211710774494879042116768390014289E4L,
+-3.455077258242252974937480623730228841003E4L,
+-1.524083977439690284820586063729912653196E4L,
+-2.810541887397984804237552337349093953857E3L,
+-1.343929553541159933824901621702567066156E2L
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 1/4 <= 1/x < 3/8
+ Peak relative error 8.4e-37 */
+#define NRNr3 11
+static const long double RNr3[NRNr3 + 1] =
+{
+-1.952401126551202208698629992497306292987E-6L,
+-2.130881743066372952515162564941682716125E-4L,
+-8.376493958090190943737529486107282224387E-3L,
+-1.650592646560987700661598877522831234791E-1L,
+-1.839290818933317338111364667708678163199E0L,
+-1.216278715570882422410442318517814388470E1L,
+-4.818759344462360427612133632533779091386E1L,
+-1.120994661297476876804405329172164436784E2L,
+-1.452850765662319264191141091859300126931E2L,
+-9.485207851128957108648038238656777241333E1L,
+-2.563663855025796641216191848818620020073E1L,
+-1.787995944187565676837847610706317833247E0L
+};
+#define NRDr3 10
+static const long double RDr3[NRDr3 + 1] =
+{
+ 1.979130686770349481460559711878399476903E-4L,
+ 1.156941716128488266238105813374635099057E-2L,
+ 2.752657634309886336431266395637285974292E-1L,
+ 3.482245457248318787349778336603569327521E0L,
+ 2.569347069372696358578399521203959253162E1L,
+ 1.142279000180457419740314694631879921561E2L,
+ 3.056503977190564294341422623108332700840E2L,
+ 4.780844020923794821656358157128719184422E2L,
+ 4.105972727212554277496256802312730410518E2L,
+ 1.724072188063746970865027817017067646246E2L,
+ 2.815939183464818198705278118326590370435E1L
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 1/8 <= 1/x < 1/4
+ Peak relative error 1.5e-36 */
+#define NRNr2 11
+static const long double RNr2[NRNr2 + 1] =
+{
+-2.638914383420287212401687401284326363787E-8L,
+-3.479198370260633977258201271399116766619E-6L,
+-1.783985295335697686382487087502222519983E-4L,
+-4.777876933122576014266349277217559356276E-3L,
+-7.450634738987325004070761301045014986520E-2L,
+-7.068318854874733315971973707247467326619E-1L,
+-4.113919921935944795764071670806867038732E0L,
+-1.440447573226906222417767283691888875082E1L,
+-2.883484031530718428417168042141288943905E1L,
+-2.990886974328476387277797361464279931446E1L,
+-1.325283914915104866248279787536128997331E1L,
+-1.572436106228070195510230310658206154374E0L
+};
+#define NRDr2 10
+static const long double RDr2[NRDr2 + 1] =
+{
+ 2.675042728136731923554119302571867799673E-6L,
+ 2.170997868451812708585443282998329996268E-4L,
+ 7.249969752687540289422684951196241427445E-3L,
+ 1.302040375859768674620410563307838448508E-1L,
+ 1.380202483082910888897654537144485285549E0L,
+ 8.926594113174165352623847870299170069350E0L,
+ 3.521089584782616472372909095331572607185E1L,
+ 8.233547427533181375185259050330809105570E1L,
+ 1.072971579885803033079469639073292840135E2L,
+ 6.943803113337964469736022094105143158033E1L,
+ 1.775695341031607738233608307835017282662E1L
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 1/128 <= 1/x < 1/8
+ Peak relative error 2.2e-36 */
+#define NRNr1 9
+static const long double RNr1[NRNr1 + 1] =
+{
+-4.250780883202361946697751475473042685782E-8L,
+-5.375777053288612282487696975623206383019E-6L,
+-2.573645949220896816208565944117382460452E-4L,
+-6.199032928113542080263152610799113086319E-3L,
+-8.262721198693404060380104048479916247786E-2L,
+-6.242615227257324746371284637695778043982E-1L,
+-2.609874739199595400225113299437099626386E0L,
+-5.581967563336676737146358534602770006970E0L,
+-5.124398923356022609707490956634280573882E0L,
+-1.290865243944292370661544030414667556649E0L
+};
+#define NRDr1 8
+static const long double RDr1[NRDr1 + 1] =
+{
+ 4.308976661749509034845251315983612976224E-6L,
+ 3.265390126432780184125233455960049294580E-4L,
+ 9.811328839187040701901866531796570418691E-3L,
+ 1.511222515036021033410078631914783519649E-1L,
+ 1.289264341917429958858379585970225092274E0L,
+ 6.147640356182230769548007536914983522270E0L,
+ 1.573966871337739784518246317003956180750E1L,
+ 1.955534123435095067199574045529218238263E1L,
+ 9.472613121363135472247929109615785855865E0L
+ /* 1.0E0 */
+};
+
+
+#ifdef __STDC__
+long double
+__erfl (long double x)
+#else
+double
+__erfl (x)
+ long double x;
+#endif
+{
+ long double a, y, z;
+ int32_t i, ix, sign;
+ ieee854_long_double_shape_type u;
+
+ u.value = x;
+ sign = u.parts32.w0;
+ ix = sign & 0x7fffffff;
+
+ if (ix >= 0x7ff00000)
+ { /* erf(nan)=nan */
+ i = ((sign & 0xfff00000) >> 31) << 1;
+ return (long double) (1 - i) + one / x; /* erf(+-inf)=+-1 */
+ }
+
+ if (ix >= 0x3ff00000) /* |x| >= 1.0 */
+ {
+ y = __erfcl (x);
+ return (one - y);
+ /* return (one - __erfcl (x)); */
+ }
+ u.parts32.w0 = ix;
+ a = u.value;
+ z = x * x;
+ if (ix < 0x3fec0000) /* a < 0.875 */
+ {
+ if (ix < 0x3c600000) /* |x|<2**-57 */
+ {
+ if (ix < 0x00800000)
+ {
+ /* erf (-0) = -0. Unfortunately, for IBM extended double
+ 0.125 * (8.0 * x + efx8 * x) for x = -0 evaluates to 0. */
+ if (x == 0)
+ return x;
+ return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */
+ }
+ return x + efx * x;
+ }
+ y = a + a * neval (z, TN1, NTN1) / deval (z, TD1, NTD1);
+ }
+ else
+ {
+ a = a - one;
+ y = erf_const + neval (a, TN2, NTN2) / deval (a, TD2, NTD2);
+ }
+
+ if (sign & 0x80000000) /* x < 0 */
+ y = -y;
+ return( y );
+}
+
+long_double_symbol (libm, __erfl, erfl);
+#ifdef __STDC__
+ long double
+ __erfcl (long double x)
+#else
+ long double
+ __erfcl (x)
+ double
+ x;
+#endif
+{
+ long double y, z, p, r;
+ int32_t i, ix, sign;
+ ieee854_long_double_shape_type u;
+
+ u.value = x;
+ sign = u.parts32.w0;
+ ix = sign & 0x7fffffff;
+ u.parts32.w0 = ix;
+
+ if (ix >= 0x7ff00000)
+ { /* erfc(nan)=nan */
+ /* erfc(+-inf)=0,2 */
+ return (long double) (((u_int32_t) sign >> 31) << 1) + one / x;
+ }
+
+ if (ix < 0x3fd00000) /* |x| <1/4 */
+ {
+ if (ix < 0x38d00000) /* |x|<2**-114 */
+ return one - x;
+ return one - __erfl (x);
+ }
+ if (ix < 0x3ff40000) /* 1.25 */
+ {
+ x = u.value;
+ i = 8.0 * x;
+ switch (i)
+ {
+ case 2:
+ z = x - 0.25L;
+ y = C13b + z * neval (z, RNr13, NRNr13) / deval (z, RDr13, NRDr13);
+ y += C13a;
+ break;
+ case 3:
+ z = x - 0.375L;
+ y = C14b + z * neval (z, RNr14, NRNr14) / deval (z, RDr14, NRDr14);
+ y += C14a;
+ break;
+ case 4:
+ z = x - 0.5L;
+ y = C15b + z * neval (z, RNr15, NRNr15) / deval (z, RDr15, NRDr15);
+ y += C15a;
+ break;
+ case 5:
+ z = x - 0.625L;
+ y = C16b + z * neval (z, RNr16, NRNr16) / deval (z, RDr16, NRDr16);
+ y += C16a;
+ break;
+ case 6:
+ z = x - 0.75L;
+ y = C17b + z * neval (z, RNr17, NRNr17) / deval (z, RDr17, NRDr17);
+ y += C17a;
+ break;
+ case 7:
+ z = x - 0.875L;
+ y = C18b + z * neval (z, RNr18, NRNr18) / deval (z, RDr18, NRDr18);
+ y += C18a;
+ break;
+ case 8:
+ z = x - 1.0L;
+ y = C19b + z * neval (z, RNr19, NRNr19) / deval (z, RDr19, NRDr19);
+ y += C19a;
+ break;
+ case 9:
+ z = x - 1.125L;
+ y = C20b + z * neval (z, RNr20, NRNr20) / deval (z, RDr20, NRDr20);
+ y += C20a;
+ break;
+ }
+ if (sign & 0x80000000)
+ y = 2.0L - y;
+ return y;
+ }
+ /* 1.25 < |x| < 107 */
+ if (ix < 0x405ac000)
+ {
+ /* x < -9 */
+ if ((ix >= 0x40220000) && (sign & 0x80000000))
+ return two - tiny;
+
+ x = fabsl (x);
+ z = one / (x * x);
+ i = 8.0 / x;
+ switch (i)
+ {
+ default:
+ case 0:
+ p = neval (z, RNr1, NRNr1) / deval (z, RDr1, NRDr1);
+ break;
+ case 1:
+ p = neval (z, RNr2, NRNr2) / deval (z, RDr2, NRDr2);
+ break;
+ case 2:
+ p = neval (z, RNr3, NRNr3) / deval (z, RDr3, NRDr3);
+ break;
+ case 3:
+ p = neval (z, RNr4, NRNr4) / deval (z, RDr4, NRDr4);
+ break;
+ case 4:
+ p = neval (z, RNr5, NRNr5) / deval (z, RDr5, NRDr5);
+ break;
+ case 5:
+ p = neval (z, RNr6, NRNr6) / deval (z, RDr6, NRDr6);
+ break;
+ case 6:
+ p = neval (z, RNr7, NRNr7) / deval (z, RDr7, NRDr7);
+ break;
+ case 7:
+ p = neval (z, RNr8, NRNr8) / deval (z, RDr8, NRDr8);
+ break;
+ }
+ u.value = x;
+ u.parts32.w3 = 0;
+ u.parts32.w2 &= 0xffffe000;
+ z = u.value;
+ r = __ieee754_expl (-z * z - 0.5625) *
+ __ieee754_expl ((z - x) * (z + x) + p);
+ if ((sign & 0x80000000) == 0)
+ return r / x;
+ else
+ return two - r / x;
+ }
+ else
+ {
+ if ((sign & 0x80000000) == 0)
+ return tiny * tiny;
+ else
+ return two - tiny;
+ }
+}
+
+long_double_symbol (libm, __erfcl, erfcl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c
new file mode 100644
index 000000000..4908d4e4f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c
@@ -0,0 +1,160 @@
+/* expm1l.c
+ *
+ * Exponential function, minus 1
+ * 128-bit long double precision
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, expm1l();
+ *
+ * y = expm1l( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns e (2.71828...) raised to the x power, minus one.
+ *
+ * Range reduction is accomplished by separating the argument
+ * into an integer k and fraction f such that
+ *
+ * x k f
+ * e = 2 e.
+ *
+ * An expansion x + .5 x^2 + x^3 R(x) approximates exp(f) - 1
+ * in the basic range [-0.5 ln 2, 0.5 ln 2].
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -79,+MAXLOG 100,000 1.7e-34 4.5e-35
+ *
+ */
+
+/* Copyright 2001 by Stephen L. Moshier
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+/* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x)
+ -.5 ln 2 < x < .5 ln 2
+ Theoretical peak relative error = 8.1e-36 */
+
+static const long double
+ P0 = 2.943520915569954073888921213330863757240E8L,
+ P1 = -5.722847283900608941516165725053359168840E7L,
+ P2 = 8.944630806357575461578107295909719817253E6L,
+ P3 = -7.212432713558031519943281748462837065308E5L,
+ P4 = 4.578962475841642634225390068461943438441E4L,
+ P5 = -1.716772506388927649032068540558788106762E3L,
+ P6 = 4.401308817383362136048032038528753151144E1L,
+ P7 = -4.888737542888633647784737721812546636240E-1L,
+ Q0 = 1.766112549341972444333352727998584753865E9L,
+ Q1 = -7.848989743695296475743081255027098295771E8L,
+ Q2 = 1.615869009634292424463780387327037251069E8L,
+ Q3 = -2.019684072836541751428967854947019415698E7L,
+ Q4 = 1.682912729190313538934190635536631941751E6L,
+ Q5 = -9.615511549171441430850103489315371768998E4L,
+ Q6 = 3.697714952261803935521187272204485251835E3L,
+ Q7 = -8.802340681794263968892934703309274564037E1L,
+ /* Q8 = 1.000000000000000000000000000000000000000E0 */
+/* C1 + C2 = ln 2 */
+
+ C1 = 6.93145751953125E-1L,
+ C2 = 1.428606820309417232121458176568075500134E-6L,
+/* ln (2^16384 * (1 - 2^-113)) */
+ maxlog = 1.1356523406294143949491931077970764891253E4L,
+/* ln 2^-114 */
+ minarg = -7.9018778583833765273564461846232128760607E1L, big = 2e307L;
+
+
+long double
+__expm1l (long double x)
+{
+ long double px, qx, xx;
+ int32_t ix, sign;
+ ieee854_long_double_shape_type u;
+ int k;
+
+ /* Detect infinity and NaN. */
+ u.value = x;
+ ix = u.parts32.w0;
+ sign = ix & 0x80000000;
+ ix &= 0x7fffffff;
+ if (ix >= 0x7ff00000)
+ {
+ /* Infinity. */
+ if (((ix & 0xfffff) | u.parts32.w1 | (u.parts32.w2&0x7fffffff) | u.parts32.w3) == 0)
+ {
+ if (sign)
+ return -1.0L;
+ else
+ return x;
+ }
+ /* NaN. No invalid exception. */
+ return x;
+ }
+
+ /* expm1(+- 0) = +- 0. */
+ if ((ix == 0) && (u.parts32.w1 | (u.parts32.w2&0x7fffffff) | u.parts32.w3) == 0)
+ return x;
+
+ /* Overflow. */
+ if (x > maxlog)
+ return (big * big);
+
+ /* Minimum value. */
+ if (x < minarg)
+ return (4.0/big - 1.0L);
+
+ /* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */
+ xx = C1 + C2; /* ln 2. */
+ px = __floorl (0.5 + x / xx);
+ k = px;
+ /* remainder times ln 2 */
+ x -= px * C1;
+ x -= px * C2;
+
+ /* Approximate exp(remainder ln 2). */
+ px = (((((((P7 * x
+ + P6) * x
+ + P5) * x + P4) * x + P3) * x + P2) * x + P1) * x + P0) * x;
+
+ qx = (((((((x
+ + Q7) * x
+ + Q6) * x + Q5) * x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0;
+
+ xx = x * x;
+ qx = x + (0.5 * xx + xx * px / qx);
+
+ /* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2).
+
+ We have qx = exp(remainder ln 2) - 1, so
+ exp(x) - 1 = 2^k (qx + 1) - 1
+ = 2^k qx + 2^k - 1. */
+
+ px = ldexpl (1.0L, k);
+ x = px * qx + (px - 1.0);
+ return x;
+}
+libm_hidden_def (__expm1l)
+long_double_symbol (libm, __expm1l, expm1l);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c
new file mode 100644
index 000000000..62663125e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c
@@ -0,0 +1,43 @@
+/* s_fabsl.c -- long double version of s_fabs.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+
+/*
+ * fabsl(x) returns the absolute value of x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+ long double __fabsl(long double x)
+#else
+ long double __fabsl(x)
+ long double x;
+#endif
+{
+ u_int64_t hx, lx;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ lx = lx ^ ( hx & 0x8000000000000000LL );
+ hx = hx & 0x7fffffffffffffffLL;
+ SET_LDOUBLE_WORDS64(hx,lx,x);
+ return x;
+}
+long_double_symbol (libm, __fabsl, fabsl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_finitel.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_finitel.c
new file mode 100644
index 000000000..49f2c9238
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_finitel.c
@@ -0,0 +1,45 @@
+/* s_finitel.c -- long double version of s_finite.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * finitel(x) returns 1 is x is finite, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+int
+___finitel (long double x)
+{
+ int64_t hx;
+ GET_LDOUBLE_MSW64(hx,x);
+ return (int)((u_int64_t)((hx&0x7fffffffffffffffLL)
+ -0x7ff0000000000000LL)>>63);
+}
+hidden_ver (___finitel, __finitel)
+weak_alias (___finitel, ____finitel)
+#ifdef IS_IN_libm
+long_double_symbol (libm, ____finitel, finitel);
+long_double_symbol (libm, ___finitel, __finitel);
+#else
+long_double_symbol (libc, ____finitel, finitel);
+long_double_symbol (libc, ___finitel, __finitel);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_floorl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_floorl.c
new file mode 100644
index 000000000..4c4ae9b03
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_floorl.c
@@ -0,0 +1,85 @@
+/* Round to int long double floating-point values.
+ IBM extended format long double version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <fenv_libc.h>
+#include <math_ldbl_opt.h>
+#include <float.h>
+#include <ieee754.h>
+
+
+#ifdef __STDC__
+long double
+__floorl (long double x)
+#else
+long double
+__floorl (x)
+ long double x;
+#endif
+{
+ double xh, xl, hi, lo;
+
+ ldbl_unpack (x, &xh, &xl);
+
+ /* Return Inf, Nan, +/-0 unchanged. */
+ if (__builtin_expect (xh != 0.0
+ && __builtin_isless (__builtin_fabs (xh),
+ __builtin_inf ()), 1))
+ {
+ int save_round = fegetround ();
+
+ /* Long double arithmetic, including the canonicalisation below,
+ only works in round-to-nearest mode. */
+ fesetround (FE_TONEAREST);
+
+ /* Convert the high double to integer. */
+ hi = ldbl_nearbyint (xh);
+
+ /* Subtract integral high part from the value. */
+ xh -= hi;
+ ldbl_canonicalize (&xh, &xl);
+
+ /* Now convert the low double, adjusted for any remainder from the
+ high double. */
+ lo = ldbl_nearbyint (xh);
+
+ /* Adjust the result when the remainder is non-zero. nearbyint
+ rounds values to the nearest integer, and values halfway
+ between integers to the nearest even integer. floorl must
+ round towards -Inf. */
+ xh -= lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ if (xh < 0.0 || (xh == 0.0 && xl < 0.0))
+ lo += -1.0;
+
+ /* Ensure the final value is canonical. In certain cases,
+ rounding causes hi,lo calculated so far to be non-canonical. */
+ xh = hi;
+ xl = lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ fesetround (save_round);
+ }
+
+ return ldbl_pack (xh, xl);
+}
+
+long_double_symbol (libm, __floorl, floorl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c
new file mode 100644
index 000000000..3ca178a3c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c
@@ -0,0 +1,82 @@
+/* Return classification value corresponding to argument.
+ Copyright (C) 1997,1999,2002,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+ /*
+ * hx lx
+ * +NaN 7ffn nnnn nnnn nnnn xxxx xxxx xxxx xxxx
+ * -NaN fffn nnnn nnnn nnnn xxxx xxxx xxxx xxxx
+ * +Inf 7ff0 0000 0000 0000 xxxx xxxx xxxx xxxx
+ * -Inf fff0 0000 0000 0000 xxxx xxxx xxxx xxxx
+ * +0 0000 0000 0000 0000
+ * -0 8000 0000 0000 0000
+ * +normal 001n nnnn nnnn nnnn (smallest)
+ * -normal 801n nnnn nnnn nnnn (smallest)
+ * +normal 7fen nnnn nnnn nnnn (largest)
+ * -normal ffen nnnn nnnn nnnn (largest)
+ * +denorm 000n nnnn nnnn nnnn
+ * -denorm 800n nnnn nnnn nnnn
+ */
+
+int
+___fpclassifyl (long double x)
+{
+ u_int64_t hx, lx;
+ int retval = FP_NORMAL;
+
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+ if ((hx & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL) {
+ /* +/-NaN or +/-Inf */
+ if (hx & 0x000fffffffffffffULL) {
+ /* +/-NaN */
+ retval = FP_NAN;
+ } else {
+ retval = FP_INFINITE;
+ }
+ } else {
+ /* +/-zero or +/- normal or +/- denormal */
+ if (hx & 0x7fffffffffffffffULL) {
+ /* +/- normal or +/- denormal */
+ if ((hx & 0x7ff0000000000000ULL) >= 0x0360000000000000ULL) {
+ /* +/- normal */
+ retval = FP_NORMAL;
+ } else {
+ /* +/- denormal */
+ retval = FP_SUBNORMAL;
+ }
+ } else {
+ /* +/- zero */
+ retval = FP_ZERO;
+ }
+ }
+
+ return retval;
+}
+long_double_symbol (libm, ___fpclassifyl, __fpclassifyl);
+#ifdef __LONG_DOUBLE_MATH_OPTIONAL
+libm_hidden_ver (___fpclassifyl, __fpclassifyl)
+#else
+libm_hidden_def (__fpclassifyl)
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c
new file mode 100644
index 000000000..fab566da3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c
@@ -0,0 +1,92 @@
+/* s_frexpl.c -- long double version of s_frexp.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * for non-zero x
+ * x = frexpl(arg,&exp);
+ * return a long double fp quantity x such that 0.5 <= |x| <1.0
+ * and the corresponding binary exponent "exp". That is
+ * arg = x*2^exp.
+ * If arg is inf, 0.0, or NaN, then frexpl(arg,&exp) returns arg
+ * with *exp=0.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+two107 = 162259276829213363391578010288128.0; /* 0x4670000000000000, 0 */
+
+#ifdef __STDC__
+ long double __frexpl(long double x, int *eptr)
+#else
+ long double __frexpl(x, eptr)
+ long double x; int *eptr;
+#endif
+{
+ u_int64_t hx, lx, ix, ixl;
+ int64_t explo;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ ixl = 0x7fffffffffffffffULL&lx;
+ ix = 0x7fffffffffffffffULL&hx;
+ *eptr = 0;
+ if(ix>=0x7ff0000000000000ULL||((ix|ixl)==0)) return x; /* 0,inf,nan */
+ if (ix<0x0010000000000000ULL) { /* subnormal */
+ x *= two107;
+ GET_LDOUBLE_MSW64(hx,x);
+ ix = hx&0x7fffffffffffffffULL;
+ *eptr = -107;
+ }
+ *eptr += (ix>>52)-1022;
+
+ if (ixl != 0ULL) {
+ explo = (ixl>>52) - (ix>>52) + 0x3fe;
+ if ((ixl&0x7ff0000000000000ULL) == 0LL) {
+ /* the lower double is a denomal so we need to correct its
+ mantissa and perhaps its exponent. */
+ int cnt;
+
+ if (sizeof (ixl) == sizeof (long))
+ cnt = __builtin_clzl (ixl);
+ else if ((ixl >> 32) != 0)
+ cnt = __builtin_clzl ((long) (ixl >> 32));
+ else
+ cnt = __builtin_clzl ((long) ixl) + 32;
+ cnt = cnt - 12;
+ lx = (lx&0x8000000000000000ULL) | ((explo-cnt)<<52)
+ | ((ixl<<(cnt+1))&0x000fffffffffffffULL);
+ } else
+ lx = (lx&0x800fffffffffffffULL) | (explo<<52);
+ } else
+ lx = 0ULL;
+
+ hx = (hx&0x800fffffffffffffULL) | 0x3fe0000000000000ULL;
+ SET_LDOUBLE_WORDS64(x,hx,lx);
+ return x;
+}
+#ifdef IS_IN_libm
+long_double_symbol (libm, __frexpl, frexpl);
+#else
+long_double_symbol (libc, __frexpl, frexpl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_ilogbl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_ilogbl.c
new file mode 100644
index 000000000..428854d77
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_ilogbl.c
@@ -0,0 +1,63 @@
+/* s_ilogbl.c -- long double version of s_ilogb.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/* ilogbl(long double x)
+ * return the binary exponent of non-zero x
+ * ilogbl(0) = FP_ILOGB0
+ * ilogbl(NaN) = FP_ILOGBNAN (no signal is raised)
+ * ilogbl(+-Inf) = INT_MAX (no signal is raised)
+ */
+
+#include <limits.h>
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+ int __ilogbl(long double x)
+#else
+ int __ilogbl(x)
+ long double x;
+#endif
+{
+ int64_t hx,lx;
+ int ix;
+
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ hx &= 0x7fffffffffffffffLL;
+ if(hx <= 0x0010000000000000LL) {
+ if((hx|(lx&0x7fffffffffffffffLL))==0)
+ return FP_ILOGB0; /* ilogbl(0) = FP_ILOGB0 */
+ else /* subnormal x */
+ if(hx==0) {
+ for (ix = -1043; lx>0; lx<<=1) ix -=1;
+ } else {
+ for (ix = -1022, hx<<=11; hx>0; hx<<=1) ix -=1;
+ }
+ return ix;
+ }
+ else if (hx<0x7ff0000000000000LL) return (hx>>52)-0x3ff;
+ else if (FP_ILOGBNAN != INT_MAX) {
+ /* ISO C99 requires ilogbl(+-Inf) == INT_MAX. */
+ if (((hx^0x7ff0000000000000LL)|lx) == 0)
+ return INT_MAX;
+ }
+ return FP_ILOGBNAN;
+}
+long_double_symbol (libm, __ilogbl, ilogbl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c
new file mode 100644
index 000000000..717b57466
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c
@@ -0,0 +1,35 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Change for long double by Jakub Jelinek <jj@ultra.linux.cz>
+ * Public domain.
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/*
+ * isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+int
+___isinfl (long double x)
+{
+ int64_t hx,lx;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ lx = (lx & 0x7fffffffffffffffLL);
+ lx |= (hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL;
+ lx |= -lx;
+ return ~(lx >> 63) & (hx >> 62);
+}
+hidden_ver (___isinfl, __isinfl)
+#ifndef IS_IN_libm
+weak_alias (___isinfl, ____isinfl)
+long_double_symbol (libc, ___isinfl, isinfl);
+long_double_symbol (libc, ____isinfl, __isinfl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c
new file mode 100644
index 000000000..ae5ba8e1f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c
@@ -0,0 +1,43 @@
+/* s_isnanl.c -- long double version of s_isnan.c.
+ * Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * isnanl(x) returns 1 is x is nan, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+int
+___isnanl (long double x)
+{
+ int64_t hx,lx;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ hx &= 0x7fffffffffffffffLL;
+ hx = 0x7ff0000000000000LL - hx;
+ return (int)((u_int64_t)hx>>63);
+}
+hidden_ver (___isnanl, __isnanl)
+#ifndef IS_IN_libm
+weak_alias (___isnanl, ____isnanl)
+long_double_symbol (libc, ___isnanl, isnanl);
+long_double_symbol (libc, ____isnanl, __isnanl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c
new file mode 100644
index 000000000..722848909
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c
@@ -0,0 +1,150 @@
+/* Round to int long double floating-point values.
+ IBM extended format long double version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This has been coded in assembler because GCC makes such a mess of it
+ when it's coded in C. */
+
+#include <math.h>
+#include <fenv_libc.h>
+#include <math_ldbl_opt.h>
+#include <float.h>
+#include <ieee754.h>
+
+
+#ifdef __STDC__
+long long
+__llrintl (long double x)
+#else
+long long
+__llrintl (x)
+ long double x;
+#endif
+{
+ double xh, xl;
+ long long res, hi, lo;
+ int save_round;
+
+ ldbl_unpack (x, &xh, &xl);
+
+ /* Limit the range of values handled by the conversion to long long.
+ We do this because we aren't sure whether that conversion properly
+ raises FE_INVALID. */
+ if (__builtin_expect
+ ((__builtin_fabs (xh) <= -(double) (-__LONG_LONG_MAX__ - 1)), 1)
+#if !defined (FE_INVALID)
+ || 1
+#endif
+ )
+ {
+ save_round = fegetround ();
+
+ if (__builtin_expect ((xh == -(double) (-__LONG_LONG_MAX__ - 1)), 0))
+ {
+ /* When XH is 9223372036854775808.0, converting to long long will
+ overflow, resulting in an invalid operation. However, XL might
+ be negative and of sufficient magnitude that the overall long
+ double is in fact in range. Avoid raising an exception. In any
+ case we need to convert this value specially, because
+ the converted value is not exactly represented as a double
+ thus subtracting HI from XH suffers rounding error. */
+ hi = __LONG_LONG_MAX__;
+ xh = 1.0;
+ }
+ else
+ {
+ hi = (long long) xh;
+ xh -= hi;
+ }
+ ldbl_canonicalize (&xh, &xl);
+
+ lo = (long long) xh;
+
+ /* Peg at max/min values, assuming that the above conversions do so.
+ Strictly speaking, we can return anything for values that overflow,
+ but this is more useful. */
+ res = hi + lo;
+
+ /* This is just sign(hi) == sign(lo) && sign(res) != sign(hi). */
+ if (__builtin_expect (((~(hi ^ lo) & (res ^ hi)) < 0), 0))
+ goto overflow;
+
+ xh -= lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ hi = res;
+ switch (save_round)
+ {
+ case FE_TONEAREST:
+ if (fabs (xh) < 0.5
+ || (fabs (xh) == 0.5
+ && ((xh > 0.0 && xl < 0.0)
+ || (xh < 0.0 && xl > 0.0)
+ || (xl == 0.0 && (res & 1) == 0))))
+ return res;
+
+ if (xh < 0.0)
+ res -= 1;
+ else
+ res += 1;
+ break;
+
+ case FE_TOWARDZERO:
+ if (res > 0 && (xh < 0.0 || (xh == 0.0 && xl < 0.0)))
+ res -= 1;
+ else if (res < 0 && (xh > 0.0 || (xh == 0.0 && xl > 0.0)))
+ res += 1;
+ return res;
+ break;
+
+ case FE_UPWARD:
+ if (xh > 0.0 || (xh == 0.0 && xl > 0.0))
+ res += 1;
+ break;
+
+ case FE_DOWNWARD:
+ if (xh < 0.0 || (xh == 0.0 && xl < 0.0))
+ res -= 1;
+ break;
+ }
+
+ if (__builtin_expect (((~(hi ^ (res - hi)) & (res ^ hi)) < 0), 0))
+ goto overflow;
+
+ return res;
+ }
+ else
+ {
+ if (xh > 0.0)
+ hi = __LONG_LONG_MAX__;
+ else if (xh < 0.0)
+ hi = -__LONG_LONG_MAX__ - 1;
+ else
+ /* Nan */
+ hi = 0;
+ }
+
+overflow:
+#ifdef FE_INVALID
+ feraiseexcept (FE_INVALID);
+#endif
+ return hi;
+}
+
+long_double_symbol (libm, __llrintl, llrintl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c
new file mode 100644
index 000000000..103529d5a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c
@@ -0,0 +1,130 @@
+/* Round to long long, long double floating-point values.
+ IBM extended format long double version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This has been coded in assembler because GCC makes such a mess of it
+ when it's coded in C. */
+
+#include <math.h>
+#include <fenv_libc.h>
+#include <math_ldbl_opt.h>
+#include <float.h>
+#include <ieee754.h>
+
+#ifdef __STDC__
+long long
+__llroundl (long double x)
+#else
+long long
+__llroundl (x)
+ long double x;
+#endif
+{
+ double xh, xl;
+ long long res, hi, lo;
+
+ ldbl_unpack (x, &xh, &xl);
+
+ /* Limit the range of values handled by the conversion to long long.
+ We do this because we aren't sure whether that conversion properly
+ raises FE_INVALID. */
+ if (__builtin_expect
+ ((__builtin_fabs (xh) <= -(double) (-__LONG_LONG_MAX__ - 1)), 1)
+#if !defined (FE_INVALID)
+ || 1
+#endif
+ )
+ {
+ if (__builtin_expect ((xh == -(double) (-__LONG_LONG_MAX__ - 1)), 0))
+ {
+ /* When XH is 9223372036854775808.0, converting to long long will
+ overflow, resulting in an invalid operation. However, XL might
+ be negative and of sufficient magnitude that the overall long
+ double is in fact in range. Avoid raising an exception. In any
+ case we need to convert this value specially, because
+ the converted value is not exactly represented as a double
+ thus subtracting HI from XH suffers rounding error. */
+ hi = __LONG_LONG_MAX__;
+ xh = 1.0;
+ }
+ else
+ {
+ hi = (long long) xh;
+ xh -= hi;
+ }
+ ldbl_canonicalize (&xh, &xl);
+
+ lo = (long long) xh;
+
+ /* Peg at max/min values, assuming that the above conversions do so.
+ Strictly speaking, we can return anything for values that overflow,
+ but this is more useful. */
+ res = hi + lo;
+
+ /* This is just sign(hi) == sign(lo) && sign(res) != sign(hi). */
+ if (__builtin_expect (((~(hi ^ lo) & (res ^ hi)) < 0), 0))
+ goto overflow;
+
+ xh -= lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ hi = res;
+ if (xh > 0.5)
+ {
+ res += 1;
+ }
+ else if (xh == 0.5)
+ {
+ if (xl > 0.0 || (xl == 0.0 && res >= 0))
+ res += 1;
+ }
+ else if (-xh > 0.5)
+ {
+ res -= 1;
+ }
+ else if (-xh == 0.5)
+ {
+ if (xl < 0.0 || (xl == 0.0 && res <= 0))
+ res -= 1;
+ }
+
+ if (__builtin_expect (((~(hi ^ (res - hi)) & (res ^ hi)) < 0), 0))
+ goto overflow;
+
+ return res;
+ }
+ else
+ {
+ if (xh > 0.0)
+ hi = __LONG_LONG_MAX__;
+ else if (xh < 0.0)
+ hi = -__LONG_LONG_MAX__ - 1;
+ else
+ /* Nan */
+ hi = 0;
+ }
+
+overflow:
+#ifdef FE_INVALID
+ feraiseexcept (FE_INVALID);
+#endif
+ return hi;
+}
+
+long_double_symbol (libm, __llroundl, llroundl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c
new file mode 100644
index 000000000..f1863fb68
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c
@@ -0,0 +1,257 @@
+/* log1pl.c
+ *
+ * Relative error logarithm
+ * Natural logarithm of 1+x, 128-bit long double precision
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, log1pl();
+ *
+ * y = log1pl( x );
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base e (2.718...) logarithm of 1+x.
+ *
+ * The argument 1+x is separated into its exponent and fractional
+ * parts. If the exponent is between -1 and +1, the logarithm
+ * of the fraction is approximated by
+ *
+ * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x).
+ *
+ * Otherwise, setting z = 2(w-1)/(w+1),
+ *
+ * log(w) = z + z^3 P(z)/Q(z).
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -1, 8 100000 1.9e-34 4.3e-35
+ */
+
+/* Copyright 2001 by Stephen L. Moshier
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+/* Coefficients for log(1+x) = x - x^2 / 2 + x^3 P(x)/Q(x)
+ * 1/sqrt(2) <= 1+x < sqrt(2)
+ * Theoretical peak relative error = 5.3e-37,
+ * relative peak error spread = 2.3e-14
+ */
+static const long double
+ P12 = 1.538612243596254322971797716843006400388E-6L,
+ P11 = 4.998469661968096229986658302195402690910E-1L,
+ P10 = 2.321125933898420063925789532045674660756E1L,
+ P9 = 4.114517881637811823002128927449878962058E2L,
+ P8 = 3.824952356185897735160588078446136783779E3L,
+ P7 = 2.128857716871515081352991964243375186031E4L,
+ P6 = 7.594356839258970405033155585486712125861E4L,
+ P5 = 1.797628303815655343403735250238293741397E5L,
+ P4 = 2.854829159639697837788887080758954924001E5L,
+ P3 = 3.007007295140399532324943111654767187848E5L,
+ P2 = 2.014652742082537582487669938141683759923E5L,
+ P1 = 7.771154681358524243729929227226708890930E4L,
+ P0 = 1.313572404063446165910279910527789794488E4L,
+ /* Q12 = 1.000000000000000000000000000000000000000E0L, */
+ Q11 = 4.839208193348159620282142911143429644326E1L,
+ Q10 = 9.104928120962988414618126155557301584078E2L,
+ Q9 = 9.147150349299596453976674231612674085381E3L,
+ Q8 = 5.605842085972455027590989944010492125825E4L,
+ Q7 = 2.248234257620569139969141618556349415120E5L,
+ Q6 = 6.132189329546557743179177159925690841200E5L,
+ Q5 = 1.158019977462989115839826904108208787040E6L,
+ Q4 = 1.514882452993549494932585972882995548426E6L,
+ Q3 = 1.347518538384329112529391120390701166528E6L,
+ Q2 = 7.777690340007566932935753241556479363645E5L,
+ Q1 = 2.626900195321832660448791748036714883242E5L,
+ Q0 = 3.940717212190338497730839731583397586124E4L;
+
+/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
+ * where z = 2(x-1)/(x+1)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 1.1e-35,
+ * relative peak error spread 1.1e-9
+ */
+static const long double
+ R5 = -8.828896441624934385266096344596648080902E-1L,
+ R4 = 8.057002716646055371965756206836056074715E1L,
+ R3 = -2.024301798136027039250415126250455056397E3L,
+ R2 = 2.048819892795278657810231591630928516206E4L,
+ R1 = -8.977257995689735303686582344659576526998E4L,
+ R0 = 1.418134209872192732479751274970992665513E5L,
+ /* S6 = 1.000000000000000000000000000000000000000E0L, */
+ S5 = -1.186359407982897997337150403816839480438E2L,
+ S4 = 3.998526750980007367835804959888064681098E3L,
+ S3 = -5.748542087379434595104154610899551484314E4L,
+ S2 = 4.001557694070773974936904547424676279307E5L,
+ S1 = -1.332535117259762928288745111081235577029E6L,
+ S0 = 1.701761051846631278975701529965589676574E6L;
+
+/* C1 + C2 = ln 2 */
+static const long double C1 = 6.93145751953125E-1L;
+static const long double C2 = 1.428606820309417232121458176568075500134E-6L;
+
+static const long double sqrth = 0.7071067811865475244008443621048490392848L;
+/* ln (2^16384 * (1 - 2^-113)) */
+static const long double maxlog = 1.1356523406294143949491931077970764891253E4L;
+static const long double big = 2e300L;
+static const long double zero = 0.0L;
+
+#if 1
+/* Make sure these are prototyped. */
+long double frexpl (long double, int *);
+long double ldexpl (long double, int);
+#endif
+
+
+long double
+__log1pl (long double xm1)
+{
+ long double x, y, z, r, s;
+ ieee854_long_double_shape_type u;
+ int32_t hx;
+ int e;
+
+ /* Test for NaN or infinity input. */
+ u.value = xm1;
+ hx = u.parts32.w0;
+ if (hx >= 0x7ff00000)
+ return xm1;
+
+ /* log1p(+- 0) = +- 0. */
+ if (((hx & 0x7fffffff) == 0)
+ && (u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) == 0)
+ return xm1;
+
+ x = xm1 + 1.0L;
+
+ /* log1p(-1) = -inf */
+ if (x <= 0.0L)
+ {
+ if (x == 0.0L)
+ return (-1.0L / (x - x));
+ else
+ return (zero / (x - x));
+ }
+
+ /* Separate mantissa from exponent. */
+
+ /* Use frexp used so that denormal numbers will be handled properly. */
+ x = frexpl (x, &e);
+
+ /* Logarithm using log(x) = z + z^3 P(z^2)/Q(z^2),
+ where z = 2(x-1)/x+1). */
+ if ((e > 2) || (e < -2))
+ {
+ if (x < sqrth)
+ { /* 2( 2x-1 )/( 2x+1 ) */
+ e -= 1;
+ z = x - 0.5L;
+ y = 0.5L * z + 0.5L;
+ }
+ else
+ { /* 2 (x-1)/(x+1) */
+ z = x - 0.5L;
+ z -= 0.5L;
+ y = 0.5L * x + 0.5L;
+ }
+ x = z / y;
+ z = x * x;
+ r = ((((R5 * z
+ + R4) * z
+ + R3) * z
+ + R2) * z
+ + R1) * z
+ + R0;
+ s = (((((z
+ + S5) * z
+ + S4) * z
+ + S3) * z
+ + S2) * z
+ + S1) * z
+ + S0;
+ z = x * (z * r / s);
+ z = z + e * C2;
+ z = z + x;
+ z = z + e * C1;
+ return (z);
+ }
+
+
+ /* Logarithm using log(1+x) = x - .5x^2 + x^3 P(x)/Q(x). */
+
+ if (x < sqrth)
+ {
+ e -= 1;
+ if (e != 0)
+ x = 2.0L * x - 1.0L; /* 2x - 1 */
+ else
+ x = xm1;
+ }
+ else
+ {
+ if (e != 0)
+ x = x - 1.0L;
+ else
+ x = xm1;
+ }
+ z = x * x;
+ r = (((((((((((P12 * x
+ + P11) * x
+ + P10) * x
+ + P9) * x
+ + P8) * x
+ + P7) * x
+ + P6) * x
+ + P5) * x
+ + P4) * x
+ + P3) * x
+ + P2) * x
+ + P1) * x
+ + P0;
+ s = (((((((((((x
+ + Q11) * x
+ + Q10) * x
+ + Q9) * x
+ + Q8) * x
+ + Q7) * x
+ + Q6) * x
+ + Q5) * x
+ + Q4) * x
+ + Q3) * x
+ + Q2) * x
+ + Q1) * x
+ + Q0;
+ y = x * (z * r / s);
+ y = y + e * C2;
+ z = y - 0.5L * z;
+ z = z + x;
+ z = z + e * C1;
+ return (z);
+}
+
+long_double_symbol (libm, __log1pl, log1pl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_logbl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_logbl.c
new file mode 100644
index 000000000..0c61cdae2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_logbl.c
@@ -0,0 +1,47 @@
+/* s_logbl.c -- long double version of s_logb.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * long double logbl(x)
+ * IEEE 754 logb. Included to pass IEEE test suite. Not recommend.
+ * Use ilogb instead.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+ long double __logbl(long double x)
+#else
+ long double __logbl(x)
+ long double x;
+#endif
+{
+ int64_t lx,hx;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ hx &= 0x7fffffffffffffffLL; /* high |x| */
+ if((hx|(lx&0x7fffffffffffffffLL))==0) return -1.0/fabs(x);
+ if(hx>=0x7ff0000000000000LL) return x*x;
+ if((hx>>=52)==0) /* IEEE 754 logb */
+ return -1022.0;
+ else
+ return (long double) (hx-0x3ff);
+}
+long_double_symbol (libm, __logbl, logbl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_lrintl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_lrintl.c
new file mode 100644
index 000000000..029247568
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_lrintl.c
@@ -0,0 +1,9 @@
+/* FIXME */
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+long int __lrintl (long double d)
+{
+ return llrintl (d);
+}
+long_double_symbol (libm, __lrintl, lrintl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_lroundl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_lroundl.c
new file mode 100644
index 000000000..7c5de3618
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_lroundl.c
@@ -0,0 +1,9 @@
+/* FIXME */
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+long int __lroundl (long double d)
+{
+ return llroundl (d);
+}
+long_double_symbol (libm, __lroundl, lroundl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_modfl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_modfl.c
new file mode 100644
index 000000000..f2e65f0c4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_modfl.c
@@ -0,0 +1,94 @@
+/* s_modfl.c -- long double version of s_modf.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/*
+ * modfl(long double x, long double *iptr)
+ * return fraction part of x, and return x's integral part in *iptr.
+ * Method:
+ * Bit twiddling.
+ *
+ * Exception:
+ * No exception.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+static const long double one = 1.0;
+#else
+static long double one = 1.0;
+#endif
+
+#ifdef __STDC__
+ long double __modfl(long double x, long double *iptr)
+#else
+ long double __modfl(x, iptr)
+ long double x,*iptr;
+#endif
+{
+ int64_t i0,i1,j0;
+ u_int64_t i;
+ GET_LDOUBLE_WORDS64(i0,i1,x);
+ i1 &= 0x000fffffffffffffLL;
+ j0 = ((i0>>52)&0x7ff)-0x3ff; /* exponent of x */
+ if(j0<52) { /* integer part in high x */
+ if(j0<0) { /* |x|<1 */
+ /* *iptr = +-0 */
+ SET_LDOUBLE_WORDS64(*iptr,i0&0x8000000000000000ULL,0);
+ return x;
+ } else {
+ i = (0x000fffffffffffffLL)>>j0;
+ if(((i0&i)|(i1&0x7fffffffffffffffLL))==0) { /* x is integral */
+ *iptr = x;
+ /* return +-0 */
+ SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0);
+ return x;
+ } else {
+ SET_LDOUBLE_WORDS64(*iptr,i0&(~i),0);
+ return x - *iptr;
+ }
+ }
+ } else if (j0>103) { /* no fraction part */
+ *iptr = x*one;
+ /* We must handle NaNs separately. */
+ if (j0 == 0x400 && ((i0 & 0x000fffffffffffffLL) | i1))
+ return x*one;
+ /* return +-0 */
+ SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0);
+ return x;
+ } else { /* fraction part in low x */
+ i = -1ULL>>(j0-52);
+ if((i1&i)==0) { /* x is integral */
+ *iptr = x;
+ /* return +-0 */
+ SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0);
+ return x;
+ } else {
+ SET_LDOUBLE_WORDS64(*iptr,i0,i1&(~i));
+ return x - *iptr;
+ }
+ }
+}
+#ifdef IS_IN_libm
+long_double_symbol (libm, __modfl, modfl);
+#else
+long_double_symbol (libc, __modfl, modfl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
new file mode 100644
index 000000000..2561fda32
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
@@ -0,0 +1,125 @@
+/* Round to int long double floating-point values without raising inexact.
+ IBM extended format long double version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This has been coded in assembler because GCC makes such a mess of it
+ when it's coded in C. */
+
+#include <math.h>
+#include <fenv.h>
+#include <math_ldbl_opt.h>
+#include <float.h>
+#include <ieee754.h>
+
+
+#ifdef __STDC__
+long double
+__nearbyintl (long double x)
+#else
+long double
+__nearbyintl (x)
+ long double x;
+#endif
+{
+ fenv_t env;
+ static const long double TWO52 = 4503599627370496.0L;
+ union ibm_extended_long_double u;
+ u.d = x;
+
+ if (fabs (u.dd[0]) < TWO52)
+ {
+ double high = u.dd[0];
+ feholdexcept (&env);
+ if (high > 0.0)
+ {
+ high += TWO52;
+ high -= TWO52;
+ if (high == -0.0) high = 0.0;
+ }
+ else if (high < 0.0)
+ {
+ high -= TWO52;
+ high += TWO52;
+ if (high == 0.0) high = -0.0;
+ }
+ u.dd[0] = high;
+ u.dd[1] = 0.0;
+ fesetenv (&env);
+ }
+ else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0)
+ {
+ double high, low, tau;
+ /* In this case we have to round the low double and handle any
+ adjustment to the high double that may be caused by rounding
+ (up). This is complicated by the fact that the high double
+ may already be rounded and the low double may have the
+ opposite sign to compensate. */
+ feholdexcept (&env);
+ if (u.dd[0] > 0.0)
+ {
+ if (u.dd[1] > 0.0)
+ {
+ /* If the high/low doubles are the same sign then simply
+ round the low double. */
+ high = u.dd[0];
+ low = u.dd[1];
+ }
+ else if (u.dd[1] < 0.0)
+ {
+ /* Else the high double is pre rounded and we need to
+ adjust for that. */
+
+ tau = nextafter (u.dd[0], 0.0);
+ tau = (u.dd[0] - tau) * 2.0;
+ high = u.dd[0] - tau;
+ low = u.dd[1] + tau;
+ }
+ low += TWO52;
+ low -= TWO52;
+ }
+ else if (u.dd[0] < 0.0)
+ {
+ if (u.dd[1] < 0.0)
+ {
+ /* If the high/low doubles are the same sign then simply
+ round the low double. */
+ high = u.dd[0];
+ low = u.dd[1];
+ }
+ else if (u.dd[1] > 0.0)
+ {
+ /* Else the high double is pre rounded and we need to
+ adjust for that. */
+ tau = nextafter (u.dd[0], 0.0);
+ tau = (u.dd[0] - tau) * 2.0;
+ high = u.dd[0] - tau;
+ low = u.dd[1] + tau;
+ }
+ low = TWO52 - low;
+ low = -(low - TWO52);
+ }
+ u.dd[0] = high + low;
+ u.dd[1] = high - u.dd[0] + low;
+ fesetenv (&env);
+ }
+
+ return u.d;
+}
+
+long_double_symbol (libm, __nearbyintl, nearbyintl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
new file mode 100644
index 000000000..e35ce5082
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
@@ -0,0 +1,108 @@
+/* s_nextafterl.c -- long double version of s_nextafter.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/* IEEE functions
+ * nextafterl(x,y)
+ * return the next machine floating-point number of x in the
+ * direction toward y.
+ * Special cases:
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+ long double __nextafterl(long double x, long double y)
+#else
+ long double __nextafterl(x,y)
+ long double x,y;
+#endif
+{
+ int64_t hx,hy,ihx,ihy,ilx,ily;
+ u_int64_t lx,ly;
+
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ GET_LDOUBLE_WORDS64(hy,ly,y);
+ ihx = hx&0x7fffffffffffffffLL; /* |hx| */
+ ilx = lx&0x7fffffffffffffffLL; /* |lx| */
+ ihy = hy&0x7fffffffffffffffLL; /* |hy| */
+ ily = ly&0x7fffffffffffffffLL; /* |ly| */
+
+ if((((ihx&0x7ff0000000000000LL)==0x7ff0000000000000LL)&&
+ ((ihx&0x000fffffffffffffLL)!=0)) || /* x is nan */
+ (((ihy&0x7ff0000000000000LL)==0x7ff0000000000000LL)&&
+ ((ihy&0x000fffffffffffffLL)!=0))) /* y is nan */
+ return x+y; /* signal the nan */
+ if(x==y)
+ return y; /* x=y, return y */
+ if(ihx == 0 && ilx == 0) { /* x == 0 */
+ SET_LDOUBLE_WORDS64(x,hy&0x8000000000000000ULL,1);/* return +-minsubnormal */
+ y = x*x;
+ if(y==x) return y; else return x; /* raise underflow flag */
+ }
+ if(ihx>=0) { /* x > 0 */
+ if(ihx>ihy||((ihx==ihy)&&(ilx>ily))) { /* x > y, x -= ulp */
+
+ if(ilx==0)
+ hx--;
+ else
+ lx--;
+ } else { /* x < y, x += ulp */
+ if((hx==0x7fefffffffffffffLL)&&(lx==0x7c8ffffffffffffeLL))
+ {
+ SET_LDOUBLE_WORDS64(x,0x7ff0000000000000,0x8000000000000000);
+ return x;
+ }
+ else if((hx==0xffefffffffffffffLL)&&(lx==0xfc8ffffffffffffeLL))
+ {
+ SET_LDOUBLE_WORDS64(x,0xfff0000000000000,0x8000000000000000);
+ return x;
+ }
+ else if((lx&0x7fffffffffffffff)==0) hx++;
+ else
+ lx++;
+ }
+ } else { /* x < 0 */
+ if(ihy>=0||ihx>ihy||((ihx==ihy)&&(ilx>ily))){/* x < y, x -= ulp */
+ if((lx&0x7fffffffffffffff)==0)
+ hx--;
+ else
+ lx--;
+ } else { /* x > y, x += ulp */
+ if((lx&0x7fffffffffffffff)==0) hx++;
+ else
+ lx++;
+ }
+ }
+ hy = hx&0x7ff0000000000000LL;
+ if(hy==0x7ff0000000000000LL) return x+x;/* overflow */
+ if(hy==0) { /* underflow */
+ y = x*x;
+ if(y!=x) { /* raise underflow flag */
+ SET_LDOUBLE_WORDS64(y,hx,lx);
+ return y;
+ }
+ }
+ SET_LDOUBLE_WORDS64(x,hx,lx);
+ return x;
+}
+strong_alias (__nextafterl, __nexttowardl)
+long_double_symbol (libm, __nextafterl, nextafterl);
+long_double_symbol (libm, __nexttowardl, nexttowardl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c
new file mode 100644
index 000000000..333510059
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c
@@ -0,0 +1,106 @@
+/* s_nexttoward.c
+ * Conversion from s_nextafter.c by Ulrich Drepper, Cygnus Support,
+ * drepper@cygnus.com and Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+/* IEEE functions
+ * nexttoward(x,y)
+ * return the next machine floating-point number of x in the
+ * direction toward y.
+ * Special cases:
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+#include <float.h>
+
+#ifdef __STDC__
+ double __nexttoward(double x, long double y)
+#else
+ double __nexttoward(x,y)
+ double x;
+ long double y;
+#endif
+{
+ int32_t hx,ix;
+ int64_t hy,iy;
+ u_int32_t lx;
+ u_int64_t ly,uly;
+
+ EXTRACT_WORDS(hx,lx,x);
+ GET_LDOUBLE_WORDS64(hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = hy&0x7fffffffffffffffLL; /* |y| */
+ uly = ly&0x7fffffffffffffffLL; /* |y| */
+
+ if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */
+ ((iy>=0x7ff0000000000000LL)&&((iy-0x7ff0000000000000LL)|uly)!=0))
+ /* y is nan */
+ return x+y;
+ if((long double) x==y) return y; /* x=y, return y */
+ if((ix|lx)==0) { /* x == 0 */
+ double x2;
+ INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */
+ x2 = x*x;
+ if(x2==x) return x2; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if (hy<0||(ix>>20)>(iy>>52)
+ || ((ix>>20)==(iy>>52)
+ && (((((int64_t)hx)<<32)|(lx))>(hy&0x000fffffffffffffLL)
+ || (((((int64_t)hx)<<32)|(lx))==(hy&0x000fffffffffffffLL)
+ )))) { /* x > y, x -= ulp */
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { /* x < y, x += ulp */
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ } else { /* x < 0 */
+ if (hy>=0||(ix>>20)>(iy>>52)
+ || ((ix>>20)==(iy>>52)
+ && (((((int64_t)hx)<<32)|(lx))>(hy&0x000fffffffffffffLL)
+ || (((((int64_t)hx)<<32)|(lx))==(hy&0x000fffffffffffffLL)
+ )))) { /* x < y, x -= ulp */
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { /* x > y, x += ulp */
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ }
+ hy = hx&0x7ff00000;
+ if(hy>=0x7ff00000) {
+ x = x+x; /* overflow */
+ if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
+ /* Force conversion to float. */
+ asm ("" : "=m"(x) : "m"(x));
+ return x;
+ }
+ if(hy<0x00100000) { /* underflow */
+ double x2 = x*x;
+ if(x2!=x) { /* raise underflow flag */
+ INSERT_WORDS(x2,hx,lx);
+ return x2;
+ }
+ }
+ INSERT_WORDS(x,hx,lx);
+ return x;
+}
+long_double_symbol (libm, __nexttoward, nexttoward);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c
new file mode 100644
index 000000000..a9373ff82
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c
@@ -0,0 +1,83 @@
+/* s_nexttowardf.c -- float version of s_nextafter.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com
+ * and Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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: $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+ float __nexttowardf(float x, long double y)
+#else
+ float __nexttowardf(x,y)
+ float x;
+ long double y;
+#endif
+{
+ int32_t hx,ix;
+ int64_t hy,iy;
+ u_int64_t ly, uly;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_LDOUBLE_WORDS64(hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = hy&0x7fffffffffffffffLL; /* |y| */
+ uly = ly&0x7fffffffffffffffLL; /* |y| */
+
+ if((ix>0x7f800000) || /* x is nan */
+ ((iy>=0x7ff0000000000000LL)&&((iy-0x7ff0000000000000LL)|uly)!=0))
+ /* y is nan */
+ return x+y;
+ if((long double) x==y) return y; /* x=y, return y */
+ if(ix==0) { /* x == 0 */
+ float x2;
+ SET_FLOAT_WORD(x,(u_int32_t)((hy>>32)&0x80000000)|1);/* return +-minsub*/
+ x2 = x*x;
+ if(x2==x) return x2; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if(hy<0||(ix>>23)>(iy>>52)-0x380
+ || ((ix>>23)==(iy>>52)-0x380
+ && (ix&0x7fffff)>((hy>>29)&0x7fffff))) {/* x > y, x -= ulp */
+ hx -= 1;
+ } else { /* x < y, x += ulp */
+ hx += 1;
+ }
+ } else { /* x < 0 */
+ if(hy>=0||(ix>>23)>(iy>>52)-0x380
+ || ((ix>>23)==(iy>>52)-0x380
+ && (ix&0x7fffff)>((hy>>29)&0x7fffff))) {/* x < y, x -= ulp */
+ hx -= 1;
+ } else { /* x > y, x += ulp */
+ hx += 1;
+ }
+ }
+ hy = hx&0x7f800000;
+ if(hy>=0x7f800000) return x+x; /* overflow */
+ if(hy<0x00800000) { /* underflow */
+ float x2 = x*x;
+ if(x2!=x) { /* raise underflow flag */
+ SET_FLOAT_WORD(x2,hx);
+ return x2;
+ }
+ }
+ SET_FLOAT_WORD(x,hx);
+ return x;
+}
+long_double_symbol (libm, __nexttowardf, nexttowardf);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_remquol.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_remquol.c
new file mode 100644
index 000000000..ca504a01a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_remquol.c
@@ -0,0 +1,111 @@
+/* Compute remainder and a congruent to the quotient.
+ Copyright (C) 1997,1999,2002,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+
+static const long double zero = 0.0;
+
+
+long double
+__remquol (long double x, long double y, int *quo)
+{
+ int64_t hx,hy;
+ u_int64_t sx,lx,ly,qs;
+ int cquo;
+
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+ GET_LDOUBLE_WORDS64 (hy, ly, y);
+ sx = hx & 0x8000000000000000ULL;
+ qs = sx ^ (hy & 0x8000000000000000ULL);
+ hy &= 0x7fffffffffffffffLL;
+ hx &= 0x7fffffffffffffffLL;
+
+ /* Purge off exception values. */
+ if ((hy | (ly & 0x7fffffffffffffff)) == 0)
+ return (x * y) / (x * y); /* y = 0 */
+ if ((hx >= 0x7ff0000000000000LL) /* x not finite */
+ || ((hy >= 0x7ff0000000000000LL) /* y is NaN */
+ && (((hy - 0x7ff0000000000000LL) | ly) != 0)))
+ return (x * y) / (x * y);
+
+ if (hy <= 0x7fbfffffffffffffLL)
+ x = __ieee754_fmodl (x, 8 * y); /* now x < 8y */
+
+ if (((hx - hy) | (lx - ly)) == 0)
+ {
+ *quo = qs ? -1 : 1;
+ return zero * x;
+ }
+
+ x = fabsl (x);
+ y = fabsl (y);
+ cquo = 0;
+
+ if (x >= 4 * y)
+ {
+ x -= 4 * y;
+ cquo += 4;
+ }
+ if (x >= 2 * y)
+ {
+ x -= 2 * y;
+ cquo += 2;
+ }
+
+ if (hy < 0x0020000000000000LL)
+ {
+ if (x + x > y)
+ {
+ x -= y;
+ ++cquo;
+ if (x + x >= y)
+ {
+ x -= y;
+ ++cquo;
+ }
+ }
+ }
+ else
+ {
+ long double y_half = 0.5L * y;
+ if (x > y_half)
+ {
+ x -= y;
+ ++cquo;
+ if (x >= y_half)
+ {
+ x -= y;
+ ++cquo;
+ }
+ }
+ }
+
+ *quo = qs ? -cquo : cquo;
+
+ if (sx)
+ x = -x;
+ return x;
+}
+long_double_symbol (libm, __remquol, remquol);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_rintl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_rintl.c
new file mode 100644
index 000000000..1f4e33f91
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_rintl.c
@@ -0,0 +1,119 @@
+/* Round to int long double floating-point values.
+ IBM extended format long double version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This has been coded in assembler because GCC makes such a mess of it
+ when it's coded in C. */
+
+#include <math.h>
+#include <fenv_libc.h>
+#include <math_ldbl_opt.h>
+#include <float.h>
+#include <ieee754.h>
+
+
+#ifdef __STDC__
+long double
+__rintl (long double x)
+#else
+long double
+__rintl (x)
+ long double x;
+#endif
+{
+ double xh, xl, hi, lo;
+
+ ldbl_unpack (x, &xh, &xl);
+
+ /* Return Inf, Nan, +/-0 unchanged. */
+ if (__builtin_expect (xh != 0.0
+ && __builtin_isless (__builtin_fabs (xh),
+ __builtin_inf ()), 1))
+ {
+ double orig_xh;
+ int save_round = fegetround ();
+
+ /* Long double arithmetic, including the canonicalisation below,
+ only works in round-to-nearest mode. */
+ fesetround (FE_TONEAREST);
+
+ /* Convert the high double to integer. */
+ orig_xh = xh;
+ hi = ldbl_nearbyint (xh);
+
+ /* Subtract integral high part from the value. If the low double
+ happens to be exactly 0.5 or -0.5, you might think that this
+ subtraction could result in an incorrect conversion. For
+ instance, subtracting an odd number would cause this function
+ to round in the wrong direction. However, if we have a
+ canonical long double with the low double 0.5 or -0.5, then the
+ high double must be even. */
+ xh -= hi;
+ ldbl_canonicalize (&xh, &xl);
+
+ /* Now convert the low double, adjusted for any remainder from the
+ high double. */
+ lo = ldbl_nearbyint (xh);
+
+ xh -= lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ switch (save_round)
+ {
+ case FE_TONEAREST:
+ if (xl > 0.0 && xh == 0.5)
+ lo += 1.0;
+ else if (xl < 0.0 && -xh == 0.5)
+ lo -= 1.0;
+ break;
+
+ case FE_TOWARDZERO:
+ if (orig_xh < 0.0)
+ goto do_up;
+ /* Fall thru */
+
+ case FE_DOWNWARD:
+ if (xh < 0.0 || (xh == 0.0 && xl < 0.0))
+ lo -= 1.0;
+ break;
+
+ case FE_UPWARD:
+ do_up:
+ if (xh > 0.0 || (xh == 0.0 && xl > 0.0))
+ lo += 1.0;
+ break;
+ }
+
+ /* Ensure the final value is canonical. In certain cases,
+ rounding causes hi,lo calculated so far to be non-canonical. */
+ xh = hi;
+ xl = lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ /* Ensure we return -0 rather than +0 when appropriate. */
+ if (orig_xh < 0.0)
+ xh = -__builtin_fabs (xh);
+
+ fesetround (save_round);
+ }
+
+ return ldbl_pack (xh, xl);
+}
+
+long_double_symbol (libm, __rintl, rintl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_roundl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_roundl.c
new file mode 100644
index 000000000..0880e6ee2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_roundl.c
@@ -0,0 +1,98 @@
+/* Round to int long double floating-point values.
+ IBM extended format long double version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This has been coded in assembler because GCC makes such a mess of it
+ when it's coded in C. */
+
+#include <math.h>
+#include <fenv_libc.h>
+#include <math_ldbl_opt.h>
+#include <float.h>
+#include <ieee754.h>
+
+
+#ifdef __STDC__
+long double
+__roundl (long double x)
+#else
+long double
+__roundl (x)
+ long double x;
+#endif
+{
+ double xh, xl, hi, lo;
+
+ ldbl_unpack (x, &xh, &xl);
+
+ /* Return Inf, Nan, +/-0 unchanged. */
+ if (__builtin_expect (xh != 0.0
+ && __builtin_isless (__builtin_fabs (xh),
+ __builtin_inf ()), 1))
+ {
+ double orig_xh;
+ int save_round = fegetround ();
+
+ /* Long double arithmetic, including the canonicalisation below,
+ only works in round-to-nearest mode. */
+ fesetround (FE_TONEAREST);
+
+ /* Convert the high double to integer. */
+ orig_xh = xh;
+ hi = ldbl_nearbyint (xh);
+
+ /* Subtract integral high part from the value. */
+ xh -= hi;
+ ldbl_canonicalize (&xh, &xl);
+
+ /* Now convert the low double, adjusted for any remainder from the
+ high double. */
+ lo = ldbl_nearbyint (xh);
+
+ /* Adjust the result when the remainder is exactly 0.5. nearbyint
+ rounds values halfway between integers to the nearest even
+ integer. roundl must round away from zero.
+ Also correct cases where nearbyint returns an incorrect value
+ for LO. */
+ xh -= lo;
+ ldbl_canonicalize (&xh, &xl);
+ if (xh == 0.5)
+ {
+ if (xl > 0.0 || (xl == 0.0 && orig_xh > 0.0))
+ lo += 1.0;
+ }
+ else if (-xh == 0.5)
+ {
+ if (xl < 0.0 || (xl == 0.0 && orig_xh < 0.0))
+ lo -= 1.0;
+ }
+
+ /* Ensure the final value is canonical. In certain cases,
+ rounding causes hi,lo calculated so far to be non-canonical. */
+ xh = hi;
+ xl = lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ fesetround (save_round);
+ }
+
+ return ldbl_pack (xh, xl);
+}
+
+long_double_symbol (libm, __roundl, roundl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c
new file mode 100644
index 000000000..3a1ba07f2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c
@@ -0,0 +1,105 @@
+/* s_scalblnl.c -- long double version of s_scalbln.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/* @(#)s_scalbln.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: $";
+#endif
+
+/*
+ * scalblnl (long double x, long int n)
+ * scalblnl(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+twolm54 = 5.55111512312578270212e-17, /* 0x3C90000000000000, 0 */
+huge = 1.0E+300L,
+tiny = 1.0E-300L;
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54 = 1.80143985094819840000e+16, /* 0x4350000000000000 */
+twom54 = 5.55111512312578270212e-17; /* 0x3C90000000000000 */
+
+#ifdef __STDC__
+ long double __scalblnl (long double x, long int n)
+#else
+ long double __scalblnl (x,n)
+ long double x; long int n;
+#endif
+{
+ int64_t k,l,hx,lx;
+ union { int64_t i; double d; } u;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ k = (hx>>52)&0x7ff; /* extract exponent */
+ l = (lx>>52)&0x7ff;
+ if (k==0) { /* 0 or subnormal x */
+ if (((hx|lx)&0x7fffffffffffffffULL)==0) return x; /* +-0 */
+ u.i = hx;
+ u.d *= two54;
+ hx = u.i;
+ k = ((hx>>52)&0x7ff) - 54;
+ }
+ else if (k==0x7ff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (n> 50000 || k > 0x7fe)
+ return huge*__copysignl(huge,x); /* overflow */
+ if (n< -50000) return tiny*__copysignl(tiny,x); /*underflow */
+ if (k > 0) { /* normal result */
+ hx = (hx&0x800fffffffffffffULL)|(k<<52);
+ if ((lx & 0x7fffffffffffffffULL) == 0) { /* low part +-0 */
+ SET_LDOUBLE_WORDS64(x,hx,lx);
+ return x;
+ }
+ if (l == 0) { /* low part subnormal */
+ u.i = lx;
+ u.d *= two54;
+ lx = u.i;
+ l = ((lx>>52)&0x7ff) - 54;
+ }
+ l = l + n;
+ if (l > 0)
+ lx = (lx&0x800fffffffffffffULL)|(l<<52);
+ else if (l <= -54)
+ lx = (lx&0x8000000000000000ULL);
+ else {
+ l += 54;
+ u.i = (lx&0x800fffffffffffffULL)|(l<<52);
+ u.d *= twom54;
+ lx = u.i;
+ }
+ SET_LDOUBLE_WORDS64(x,hx,lx);
+ return x;
+ }
+ if (k <= -54)
+ return tiny*__copysignl(tiny,x); /*underflow*/
+ k += 54; /* subnormal result */
+ lx &= 0x8000000000000000ULL;
+ SET_LDOUBLE_WORDS64(x,(hx&0x800fffffffffffffULL)|(k<<52),lx);
+ return x*twolm54;
+}
+long_double_symbol (libm, __scalblnl, scalblnl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c
new file mode 100644
index 000000000..50bd8cb0b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c
@@ -0,0 +1,109 @@
+/* s_scalbnl.c -- long double version of s_scalbn.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/* @(#)s_scalbn.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: $";
+#endif
+
+/*
+ * scalbnl (long double x, int n)
+ * scalbnl(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+twolm54 = 5.55111512312578270212e-17, /* 0x3C90000000000000, 0 */
+huge = 1.0E+300L,
+tiny = 1.0E-300L;
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54 = 1.80143985094819840000e+16, /* 0x4350000000000000 */
+twom54 = 5.55111512312578270212e-17; /* 0x3C90000000000000 */
+
+#ifdef __STDC__
+ long double __scalbnl (long double x, int n)
+#else
+ long double __scalbnl (x,n)
+ long double x; int n;
+#endif
+{
+ int64_t k,l,hx,lx;
+ union { int64_t i; double d; } u;
+ GET_LDOUBLE_WORDS64(hx,lx,x);
+ k = (hx>>52)&0x7ff; /* extract exponent */
+ l = (lx>>52)&0x7ff;
+ if (k==0) { /* 0 or subnormal x */
+ if (((hx|lx)&0x7fffffffffffffffULL)==0) return x; /* +-0 */
+ u.i = hx;
+ u.d *= two54;
+ hx = u.i;
+ k = ((hx>>52)&0x7ff) - 54;
+ }
+ else if (k==0x7ff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (n> 50000 || k > 0x7fe)
+ return huge*__copysignl(huge,x); /* overflow */
+ if (n< -50000) return tiny*__copysignl(tiny,x); /*underflow */
+ if (k > 0) { /* normal result */
+ hx = (hx&0x800fffffffffffffULL)|(k<<52);
+ if ((lx & 0x7fffffffffffffffULL) == 0) { /* low part +-0 */
+ SET_LDOUBLE_WORDS64(x,hx,lx);
+ return x;
+ }
+ if (l == 0) { /* low part subnormal */
+ u.i = lx;
+ u.d *= two54;
+ lx = u.i;
+ l = ((lx>>52)&0x7ff) - 54;
+ }
+ l = l + n;
+ if (l > 0)
+ lx = (lx&0x800fffffffffffffULL)|(l<<52);
+ else if (l <= -54)
+ lx = (lx&0x8000000000000000ULL);
+ else {
+ l += 54;
+ u.i = (lx&0x800fffffffffffffULL)|(l<<52);
+ u.d *= twom54;
+ lx = u.i;
+ }
+ SET_LDOUBLE_WORDS64(x,hx,lx);
+ return x;
+ }
+ if (k <= -54)
+ return tiny*__copysignl(tiny,x); /*underflow*/
+ k += 54; /* subnormal result */
+ lx &= 0x8000000000000000ULL;
+ SET_LDOUBLE_WORDS64(x,(hx&0x800fffffffffffffULL)|(k<<52),lx);
+ return x*twolm54;
+}
+#ifdef IS_IN_libm
+long_double_symbol (libm, __scalbnl, scalbnl);
+#else
+long_double_symbol (libc, __scalbnl, scalbnl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c
new file mode 100644
index 000000000..b4285461b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c
@@ -0,0 +1,37 @@
+/* Return nonzero value if number is negative.
+ Copyright (C) 1997,1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+int
+___signbitl (long double x)
+{
+ int64_t e;
+
+ GET_LDOUBLE_MSW64 (e, x);
+ return e < 0;
+}
+#ifdef IS_IN_libm
+long_double_symbol (libm, ___signbitl, __signbitl);
+#else
+long_double_symbol (libc, ___signbitl, __signbitl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c
new file mode 100644
index 000000000..1d3d7a4d0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c
@@ -0,0 +1,72 @@
+/* Compute sine and cosine of argument.
+ Copyright (C) 1997,1999,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+void
+__sincosl (long double x, long double *sinx, long double *cosx)
+{
+ int64_t ix;
+
+ /* High word of x. */
+ GET_LDOUBLE_MSW64 (ix, x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffffffffffffLL;
+ if (ix <= 0x3fe921fb54442d10LL)
+ __kernel_sincosl (x, 0.0L, sinx, cosx, 0);
+ else if (ix >= 0x7ff0000000000000LL)
+ {
+ /* sin(Inf or NaN) is NaN */
+ *sinx = *cosx = x - x;
+ }
+ else
+ {
+ /* Argument reduction needed. */
+ long double y[2];
+ int n;
+
+ n = __ieee754_rem_pio2l (x, y);
+ switch (n & 3)
+ {
+ case 0:
+ __kernel_sincosl (y[0], y[1], sinx, cosx, 1);
+ break;
+ case 1:
+ __kernel_sincosl (y[0], y[1], cosx, sinx, 1);
+ *cosx = -*cosx;
+ break;
+ case 2:
+ __kernel_sincosl (y[0], y[1], sinx, cosx, 1);
+ *sinx = -*sinx;
+ *cosx = -*cosx;
+ break;
+ default:
+ __kernel_sincosl (y[0], y[1], cosx, sinx, 1);
+ *sinx = -*sinx;
+ break;
+ }
+ }
+}
+long_double_symbol (libm, __sincosl, sincosl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_sinl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_sinl.c
new file mode 100644
index 000000000..8cc592c61
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_sinl.c
@@ -0,0 +1,84 @@
+/* s_sinl.c -- long double version of s_sin.c.
+ * Conversion to long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* sinl(x)
+ * Return sine function of x.
+ *
+ * kernel function:
+ * __kernel_sinl ... sine function on [-pi/4,pi/4]
+ * __kernel_cosl ... cose function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2l ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+ long double __sinl(long double x)
+#else
+ long double __sinl(x)
+ long double x;
+#endif
+{
+ long double y[2],z=0.0L;
+ int64_t n, ix;
+
+ /* High word of x. */
+ GET_LDOUBLE_MSW64(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffffffffffffLL;
+ if(ix <= 0x3fe921fb54442d10LL)
+ return __kernel_sinl(x,z,0);
+
+ /* sin(Inf or NaN) is NaN */
+ else if (ix>=0x7ff0000000000000LL) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2l(x,y);
+ switch(n&3) {
+ case 0: return __kernel_sinl(y[0],y[1],1);
+ case 1: return __kernel_cosl(y[0],y[1]);
+ case 2: return -__kernel_sinl(y[0],y[1],1);
+ default:
+ return -__kernel_cosl(y[0],y[1]);
+ }
+ }
+}
+long_double_symbol (libm, __sinl, sinl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c
new file mode 100644
index 000000000..851ca125f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c
@@ -0,0 +1,90 @@
+/* @(#)s_tanh.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_tanh.c,v 1.7 1995/05/10 20:48:22 jtc Exp $";
+#endif
+
+/* Tanh(x)
+ * Return the Hyperbolic Tangent of x
+ *
+ * Method :
+ * x -x
+ * e - e
+ * 0. tanh(x) is defined to be -----------
+ * x -x
+ * e + e
+ * 1. reduce x to non-negative by tanh(-x) = -tanh(x).
+ * 2. 0 <= x <= 2**-57 : tanh(x) := x*(one+x)
+ * -t
+ * 2**-57 < x <= 1 : tanh(x) := -----; t = expm1(-2x)
+ * t + 2
+ * 2
+ * 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t=expm1(2x)
+ * t + 2
+ * 22.0 < x <= INF : tanh(x) := 1.
+ *
+ * Special cases:
+ * tanh(NaN) is NaN;
+ * only tanh(0)=0 is exact for finite argument.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+static const long double one=1.0L, two=2.0L, tiny = 1.0e-300L;
+#else
+static long double one=1.0L, two=2.0L, tiny = 1.0e-300L;
+#endif
+
+#ifdef __STDC__
+ long double __tanhl(long double x)
+#else
+ long double __tanhl(x)
+ long double x;
+#endif
+{
+ long double t,z;
+ int64_t jx,ix,lx;
+
+ /* High word of |x|. */
+ GET_LDOUBLE_WORDS64(jx,lx,x);
+ ix = jx&0x7fffffffffffffffLL;
+
+ /* x is INF or NaN */
+ if(ix>=0x7ff0000000000000LL) {
+ if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */
+ else return one/x-one; /* tanh(NaN) = NaN */
+ }
+
+ /* |x| < 22 */
+ if (ix < 0x4036000000000000LL) { /* |x|<22 */
+ if ((ix | (lx&0x7fffffffffffffffLL)) == 0)
+ return x; /* x == +-0 */
+ if (ix<0x3c60000000000000LL) /* |x|<2**-57 */
+ return x*(one+x); /* tanh(small) = small */
+ if (ix>=0x3ff0000000000000LL) { /* |x|>=1 */
+ t = __expm1l(two*fabsl(x));
+ z = one - two/(t+two);
+ } else {
+ t = __expm1l(-two*fabsl(x));
+ z= -t/(t+two);
+ }
+ /* |x| > 22, return +-1 */
+ } else {
+ z = one - tiny; /* raised inexact flag */
+ }
+ return (jx>=0)? z: -z;
+}
+long_double_symbol (libm, __tanhl, tanhl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_tanl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_tanl.c
new file mode 100644
index 000000000..ea5a7f0ff
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_tanl.c
@@ -0,0 +1,78 @@
+/* s_tanl.c -- long double version of s_tan.c.
+ * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
+ */
+
+/* @(#)s_tan.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.
+ * ====================================================
+ */
+
+/* tanl(x)
+ * Return tangent function of x.
+ *
+ * kernel function:
+ * __kernel_tanl ... tangent function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2l ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <math_ldbl_opt.h>
+
+#ifdef __STDC__
+ long double __tanl(long double x)
+#else
+ long double __tanl(x)
+ long double x;
+#endif
+{
+ long double y[2],z=0.0L;
+ int64_t n, ix;
+
+ /* High word of x. */
+ GET_LDOUBLE_MSW64(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffffffffffffLL;
+ if(ix <= 0x3fe921fb54442d10LL) return __kernel_tanl(x,z,1);
+
+ /* tanl(Inf or NaN) is NaN */
+ else if (ix>=0x7ff0000000000000LL) return x-x; /* NaN */
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2l(x,y);
+ return __kernel_tanl(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even
+ -1 -- n odd */
+ }
+}
+long_double_symbol (libm, __tanl, tanl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/s_truncl.c b/libc/sysdeps/ieee754/ldbl-128ibm/s_truncl.c
new file mode 100644
index 000000000..d7bc47ee0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/s_truncl.c
@@ -0,0 +1,102 @@
+/* Truncate (toward zero) long double floating-point values.
+ IBM extended format long double version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This has been coded in assembler because GCC makes such a mess of it
+ when it's coded in C. */
+
+#include <math.h>
+#include <fenv_libc.h>
+#include <math_ldbl_opt.h>
+#include <float.h>
+#include <ieee754.h>
+
+
+#ifdef __STDC__
+long double
+__truncl (long double x)
+#else
+long double
+__truncl (x)
+ long double x;
+#endif
+{
+ double xh, xl, hi, lo;
+
+ ldbl_unpack (x, &xh, &xl);
+
+ /* Return Inf, Nan, +/-0 unchanged. */
+ if (__builtin_expect (xh != 0.0
+ && __builtin_isless (__builtin_fabs (xh),
+ __builtin_inf ()), 1))
+ {
+ double orig_xh;
+ int save_round = fegetround ();
+
+ /* Long double arithmetic, including the canonicalisation below,
+ only works in round-to-nearest mode. */
+ fesetround (FE_TONEAREST);
+
+ /* Convert the high double to integer. */
+ orig_xh = xh;
+ hi = ldbl_nearbyint (xh);
+
+ /* Subtract integral high part from the value. */
+ xh -= hi;
+ ldbl_canonicalize (&xh, &xl);
+
+ /* Now convert the low double, adjusted for any remainder from the
+ high double. */
+ lo = ldbl_nearbyint (xh);
+
+ /* Adjust the result when the remainder is non-zero. nearbyint
+ rounds values to the nearest integer, and values halfway
+ between integers to the nearest even integer. floorl must
+ round towards -Inf. */
+ xh -= lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ if (orig_xh < 0.0)
+ {
+ if (xh > 0.0 || (xh == 0.0 && xl > 0.0))
+ lo += 1.0;
+ }
+ else
+ {
+ if (xh < 0.0 || (xh == 0.0 && xl < 0.0))
+ lo -= 1.0;
+ }
+
+ /* Ensure the final value is canonical. In certain cases,
+ rounding causes hi,lo calculated so far to be non-canonical. */
+ xh = hi;
+ xl = lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ /* Ensure we return -0 rather than +0 when appropriate. */
+ if (orig_xh < 0.0)
+ xh = -__builtin_fabs (xh);
+
+ fesetround (save_round);
+ }
+
+ return ldbl_pack (xh, xl);
+}
+
+long_double_symbol (libm, __truncl, truncl);
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/strtold_l.c b/libc/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
new file mode 100644
index 000000000..d558b00d4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <xlocale.h>
+
+/* The actual implementation for all floating point sizes is in strtod.c.
+ These macros tell it to produce the `long double' version, `strtold'. */
+
+#define FLOAT long double
+#define FLT LDBL
+#ifdef USE_WIDE_CHAR
+extern long double ____new_wcstold_l (const wchar_t *, wchar_t **, __locale_t);
+# define STRTOF __new_wcstold_l
+# define __STRTOF ____new_wcstold_l
+# define ____STRTOF_INTERNAL ____wcstold_l_internal
+#else
+extern long double ____new_strtold_l (const char *, char **, __locale_t);
+# define STRTOF __new_strtold_l
+# define __STRTOF ____new_strtold_l
+# define ____STRTOF_INTERNAL ____strtold_l_internal
+#endif
+#define MPN2FLOAT __mpn_construct_long_double
+#define FLOAT_HUGE_VAL HUGE_VALL
+# define SET_MANTISSA(flt, mant) \
+ do { union ibm_extended_long_double u; \
+ u.d = (flt); \
+ if ((mant & 0xfffffffffffffULL) == 0) \
+ mant = 0x8000000000000ULL; \
+ u.ieee.mantissa0 = ((mant) >> 32) & 0xfffff; \
+ u.ieee.mantissa1 = (mant) & 0xffffffff; \
+ (flt) = u.d; \
+ } while (0)
+
+#include <strtod_l.c>
+
+#ifdef __LONG_DOUBLE_MATH_OPTIONAL
+# include <math_ldbl_opt.h>
+# ifdef USE_WIDE_CHAR
+long_double_symbol (libc, __new_wcstold_l, wcstold_l);
+long_double_symbol (libc, ____new_wcstold_l, __wcstold_l);
+# else
+long_double_symbol (libc, __new_strtold_l, strtold_l);
+long_double_symbol (libc, ____new_strtold_l, __strtold_l);
+# endif
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/t_sincosl.c b/libc/sysdeps/ieee754/ldbl-128ibm/t_sincosl.c
new file mode 100644
index 000000000..4c92a0da2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/t_sincosl.c
@@ -0,0 +1,694 @@
+/* Quad-precision floating point sine and cosine tables.
+ Copyright (C) 1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* For 0.1484375 + n/128.0, n=0..82 this table contains
+ first 113 bits of cosine, then at least 113 additional
+ bits and the same for sine.
+ 0.1484375+82.0/128.0 is the smallest number among above defined numbers
+ larger than pi/4.
+ Computed using gmp.
+ */
+
+const long double __sincosl_table[] = {
+
+/* x = 1.48437500000000000000000000000000000e-01L 3ffc3000000000000000000000000000 */
+/* cos(x) = 0.fd2f5320e1b790209b4dda2f98 f79caaa7b873aff1014b0fbc52 43766d03cb006bc837c4358 */
+ 0x0.fd2f5320e1b790209b4dda2f98p0L,
+ 0x0.f79caaa7b873aff1014b0fbc52p-104L,
+/* sin(x) = 0.25dc50bc95711d0d9787d108fd 438cf5959ee0bfb7a1e36e8b1a 112968f356657420e9cc9ea */
+ 0x0.25dc50bc95711d0d9787d108fdp0L,
+ 0x0.438cf5959ee0bfb7a1e36e8b1ap-104L,
+
+/* x = 1.56250000000000000000000000000000000e-01 3ffc4000000000000000000000000000 */
+/* cos(x) = 0.fce1a053e621438b6d60c76e8c 45bf0a9dc71aa16f922acc10e9 5144ec796a249813c9cb649 */
+ 0x0.fce1a053e621438b6d60c76e8cp0L,
+ 0x0.45bf0a9dc71aa16f922acc10e9p-104L,
+/* sin(x) = 0.27d66258bacd96a3eb335b365c 87d59438c5142bb56a489e9b8d b9d36234ffdebb6bdc22d8e */
+ 0x0.27d66258bacd96a3eb335b365cp0L,
+ 0x0.87d59438c5142bb56a489e9b8dp-104L,
+
+/* x = 1.64062500000000000000000000000000000e-01 3ffc5000000000000000000000000000 */
+/* cos(x) = 0.fc8ffa01ba6807417e05962b0d 9fdf1fddb0cc4c07d22e19e080 19bffa50a6c7acdb40307a3 */
+ 0x0.fc8ffa01ba6807417e05962b0dp0L,
+ 0x0.9fdf1fddb0cc4c07d22e19e080p-104L,
+/* sin(x) = 0.29cfd49b8be4f665276cab01cb f0426934906c3dd105473b226e 410b1450f62e53ff7c6cce1 */
+ 0x0.29cfd49b8be4f665276cab01cbp0L,
+ 0x0.f0426934906c3dd105473b226ep-104L,
+
+/* x = 1.71875000000000000000000000000000000e-01 3ffc6000000000000000000000000000 */
+/* cos(x) = 0.fc3a6170f767ac735d63d99a9d 439e1db5e59d3ef153a4265d58 55850ed82b536bf361b80e3 */
+ 0x0.fc3a6170f767ac735d63d99a9dp0L,
+ 0x0.439e1db5e59d3ef153a4265d58p-104L,
+/* sin(x) = 0.2bc89f9f424de5485de7ce03b2 514952b9faf5648c3244d4736f eb95dbb9da49f3b58a9253b */
+ 0x0.2bc89f9f424de5485de7ce03b2p0L,
+ 0x0.514952b9faf5648c3244d4736fp-104L,
+
+/* x = 1.79687500000000000000000000000000000e-01 3ffc7000000000000000000000000000 */
+/* cos(x) = 0.fbe0d7f7fef11e70aa43b8abf4 f6a457cea20c8f3f676b47781f 9821bbe9ce04b3c7b981c0b */
+ 0x0.fbe0d7f7fef11e70aa43b8abf4p0L,
+ 0x0.f6a457cea20c8f3f676b47781fp-104L,
+/* sin(x) = 0.2dc0bb80b49a97ffb34e8dd1f8 db9df7af47ed2dcf58b12c8e78 27e048cae929da02c04ecac */
+ 0x0.2dc0bb80b49a97ffb34e8dd1f8p0L,
+ 0x0.db9df7af47ed2dcf58b12c8e78p-104L,
+
+/* x = 1.87500000000000000000000000000000000e-01 3ffc8000000000000000000000000000 */
+/* cos(x) = 0.fb835efcf670dd2ce6fe792469 7eea13ea358867e9cdb3899b78 3f4f9f43aa5626e8b67b3bc */
+ 0x0.fb835efcf670dd2ce6fe792469p0L,
+ 0x0.7eea13ea358867e9cdb3899b78p-104L,
+/* sin(x) = 0.2fb8205f75e56a2b56a1c4792f 856258769af396e0189ef72c05 e4df59a6b00e4b44a6ea515 */
+ 0x0.2fb8205f75e56a2b56a1c4792fp0L,
+ 0x0.856258769af396e0189ef72c05p-104L,
+
+/* x = 1.95312500000000000000000000000000000e-01 3ffc9000000000000000000000000000 */
+/* cos(x) = 0.fb21f7f5c156696b00ac1fe28a c5fd76674a92b4df80d9c8a46c 684399005deccc41386257c */
+ 0x0.fb21f7f5c156696b00ac1fe28ap0L,
+ 0x0.c5fd76674a92b4df80d9c8a46cp-104L,
+/* sin(x) = 0.31aec65df552876f82ece9a235 6713246eba6799983d7011b0b3 698d6e1da919c15d57c30c1 */
+ 0x0.31aec65df552876f82ece9a235p0L,
+ 0x0.6713246eba6799983d7011b0b3p-104L,
+
+/* x = 2.03125000000000000000000000000000000e-01 3ffca000000000000000000000000000 */
+/* cos(x) = 0.fabca467fb3cb8f1d069f01d8e a33ade5bfd68296ecd1cc9f7b7 609bbcf3676e726c3301334 */
+ 0x0.fabca467fb3cb8f1d069f01d8ep0L,
+ 0x0.a33ade5bfd68296ecd1cc9f7b7p-104L,
+/* sin(x) = 0.33a4a5a19d86246710f602c44d f4fa513f4639ce938477aeeabb 82e8e0a7ed583a188879fd4 */
+ 0x0.33a4a5a19d86246710f602c44dp0L,
+ 0x0.f4fa513f4639ce938477aeeabbp-104L,
+
+/* x = 2.10937500000000000000000000000000000e-01 3ffcb000000000000000000000000000 */
+/* cos(x) = 0.fa5365e8f1d3ca27be1db5d76a e64d983d7470a4ab0f4ccf65a2 b8c67a380df949953a09bc1 */
+ 0x0.fa5365e8f1d3ca27be1db5d76ap0L,
+ 0x0.e64d983d7470a4ab0f4ccf65a2p-104L,
+/* sin(x) = 0.3599b652f40ec999df12a0a4c8 561de159c98d4e54555de518b9 7f48886f715d8df5f4f093e */
+ 0x0.3599b652f40ec999df12a0a4c8p0L,
+ 0x0.561de159c98d4e54555de518b9p-104L,
+
+/* x = 2.18750000000000000000000000000000000e-01 3ffcc000000000000000000000000000 */
+/* cos(x) = 0.f9e63e1d9e8b6f6f2e296bae5b 5ed9c11fd7fa2fe11e09fc7bde 901abed24b6365e72f7db4e */
+ 0x0.f9e63e1d9e8b6f6f2e296bae5bp0L,
+ 0x0.5ed9c11fd7fa2fe11e09fc7bdep-104L,
+/* sin(x) = 0.378df09db8c332ce0d2b53d865 582e4526ea336c768f68c32b49 6c6d11c1cd241bb9f1da523 */
+ 0x0.378df09db8c332ce0d2b53d865p0L,
+ 0x0.582e4526ea336c768f68c32b49p-104L,
+
+/* x = 2.26562500000000000000000000000000000e-01 3ffcd000000000000000000000000000 */
+/* cos(x) = 0.f9752eba9fff6b98842beadab0 54a932fb0f8d5b875ae63d6b22 88d09b148921aeb6e52f61b */
+ 0x0.f9752eba9fff6b98842beadab0p0L,
+ 0x0.54a932fb0f8d5b875ae63d6b22p-104L,
+/* sin(x) = 0.39814cb10513453cb97b21bc1c a6a337b150c21a675ab85503bc 09a436a10ab1473934e20c8 */
+ 0x0.39814cb10513453cb97b21bc1cp0L,
+ 0x0.a6a337b150c21a675ab85503bcp-104L,
+
+/* x = 2.34375000000000000000000000000000000e-01 3ffce000000000000000000000000000 */
+/* cos(x) = 0.f90039843324f9b940416c1984 b6cbed1fc733d97354d4265788 a86150493ce657cae032674 */
+ 0x0.f90039843324f9b940416c1984p0L,
+ 0x0.b6cbed1fc733d97354d4265788p-104L,
+/* sin(x) = 0.3b73c2bf6b4b9f668ef9499c81 f0d965087f1753fa64b086e58c b8470515c18c1412f8c2e02 */
+ 0x0.3b73c2bf6b4b9f668ef9499c81p0L,
+ 0x0.f0d965087f1753fa64b086e58cp-104L,
+
+/* x = 2.42187500000000000000000000000000000e-01 3ffcf000000000000000000000000000 */
+/* cos(x) = 0.f887604e2c39dbb20e4ec58250 59a789ffc95b275ad9954078ba 8a28d3fcfe9cc2c1d49697b */
+ 0x0.f887604e2c39dbb20e4ec58250p0L,
+ 0x0.59a789ffc95b275ad9954078bap-104L,
+/* sin(x) = 0.3d654aff15cb457a0fca854698 aba33039a8a40626609204472d 9d40309b626eccc6dff0ffa */
+ 0x0.3d654aff15cb457a0fca854698p0L,
+ 0x0.aba33039a8a40626609204472dp-104L,
+
+/* x = 2.50000000000000000000000000000000000e-01 3ffd0000000000000000000000000000 */
+/* cos(x) = 0.f80aa4fbef750ba783d33cb95f 94f8a41426dbe79edc4a023ef9 ec13c944551c0795b84fee1 */
+ 0x0.f80aa4fbef750ba783d33cb95fp0L,
+ 0x0.94f8a41426dbe79edc4a023ef9p-104L,
+/* sin(x) = 0.3f55dda9e62aed7513bd7b8e6a 3d1635dd5676648d7db525898d 7086af9330f03c7f285442a */
+ 0x0.3f55dda9e62aed7513bd7b8e6ap0L,
+ 0x0.3d1635dd5676648d7db525898dp-104L,
+
+/* x = 2.57812500000000000000000000000000000e-01 3ffd0800000000000000000000000000 */
+/* cos(x) = 0.f78a098069792daabc9ee42591 b7c5a68cb1ab822aeb446b3311 b4ba5371b8970e2c1547ad7 */
+ 0x0.f78a098069792daabc9ee42591p0L,
+ 0x0.b7c5a68cb1ab822aeb446b3311p-104L,
+/* sin(x) = 0.414572fd94556e6473d6202713 88dd47c0ba050cdb5270112e3e 370e8c4705ae006426fb5d5 */
+ 0x0.414572fd94556e6473d6202713p0L,
+ 0x0.88dd47c0ba050cdb5270112e3ep-104L,
+
+/* x = 2.65625000000000000000000000000000000e-01 3ffd1000000000000000000000000000 */
+/* cos(x) = 0.f7058fde0788dfc805b8fe8878 9e4f4253e3c50afe8b22f41159 620ab5940ff7df9557c0d1f */
+ 0x0.f7058fde0788dfc805b8fe8878p0L,
+ 0x0.9e4f4253e3c50afe8b22f41159p-104L,
+/* sin(x) = 0.4334033bcd90d6604f5f36c1d4 b84451a87150438275b77470b5 0e5b968fa7962b5ffb379b7 */
+ 0x0.4334033bcd90d6604f5f36c1d4p0L,
+ 0x0.b84451a87150438275b77470b5p-104L,
+
+/* x = 2.73437500000000000000000000000000000e-01 3ffd1800000000000000000000000000 */
+/* cos(x) = 0.f67d3a26af7d07aa4bd6d42af8 c0067fefb96d5b46c031eff536 27f215ea3242edc3f2e13eb */
+ 0x0.f67d3a26af7d07aa4bd6d42af8p0L,
+ 0x0.c0067fefb96d5b46c031eff536p-104L,
+/* sin(x) = 0.452186aa5377ab20bbf2524f52 e3a06a969f47166ab88cf88c11 1ad12c55941021ef3317a1a */
+ 0x0.452186aa5377ab20bbf2524f52p0L,
+ 0x0.e3a06a969f47166ab88cf88c11p-104L,
+
+/* x = 2.81250000000000000000000000000000000e-01 3ffd2000000000000000000000000000 */
+/* cos(x) = 0.f5f10a7bb77d3dfa0c1da8b578 42783280d01ce3c0f82bae3b9d 623c168d2e7c29977994451 */
+ 0x0.f5f10a7bb77d3dfa0c1da8b578p0L,
+ 0x0.42783280d01ce3c0f82bae3b9dp-104L,
+/* sin(x) = 0.470df5931ae1d946076fe0dcff 47fe31bb2ede618ebc607821f8 462b639e1f4298b5ae87fd3 */
+ 0x0.470df5931ae1d946076fe0dcffp0L,
+ 0x0.47fe31bb2ede618ebc607821f8p-104L,
+
+/* x = 2.89062500000000000000000000000000000e-01 3ffd2800000000000000000000000000 */
+/* cos(x) = 0.f561030ddd7a78960ea9f4a32c 6521554995667f5547bafee9ec 48b3155cdb0f7fd00509713 */
+ 0x0.f561030ddd7a78960ea9f4a32cp0L,
+ 0x0.6521554995667f5547bafee9ecp-104L,
+/* sin(x) = 0.48f948446abcd6b0f7fccb100e 7a1b26eccad880b0d24b59948c 7cdd49514d44b933e6985c2 */
+ 0x0.48f948446abcd6b0f7fccb100ep0L,
+ 0x0.7a1b26eccad880b0d24b59948cp-104L,
+
+/* x = 2.96875000000000000000000000000000000e-01 3ffd3000000000000000000000000000 */
+/* cos(x) = 0.f4cd261d3e6c15bb369c875863 0d2ac00b7ace2a51c0631bfeb3 9ed158ba924cc91e259c195 */
+ 0x0.f4cd261d3e6c15bb369c875863p0L,
+ 0x0.0d2ac00b7ace2a51c0631bfeb3p-104L,
+/* sin(x) = 0.4ae37710fad27c8aa9c4cf96c0 3519b9ce07dc08a1471775499f 05c29f86190aaebaeb9716e */
+ 0x0.4ae37710fad27c8aa9c4cf96c0p0L,
+ 0x0.3519b9ce07dc08a1471775499fp-104L,
+
+/* x = 3.04687500000000000000000000000000000e-01 3ffd3800000000000000000000000000 */
+/* cos(x) = 0.f43575f94d4f6b272f5fb76b14 d2a64ab52df1ee8ddf7c651034 e5b2889305a9ea9015d758a */
+ 0x0.f43575f94d4f6b272f5fb76b14p0L,
+ 0x0.d2a64ab52df1ee8ddf7c651034p-104L,
+/* sin(x) = 0.4ccc7a50127e1de0cb6b40c302 c651f7bded4f9e7702b0471ae0 288d091a37391950907202f */
+ 0x0.4ccc7a50127e1de0cb6b40c302p0L,
+ 0x0.c651f7bded4f9e7702b0471ae0p-104L,
+
+/* x = 3.12500000000000000000000000000000000e-01 3ffd4000000000000000000000000000 */
+/* cos(x) = 0.f399f500c9e9fd37ae9957263d ab8877102beb569f101ee44953 50868e5847d181d50d3cca2 */
+ 0x0.f399f500c9e9fd37ae9957263dp0L,
+ 0x0.ab8877102beb569f101ee44953p-104L,
+/* sin(x) = 0.4eb44a5da74f600207aaa090f0 734e288603ffadb3eb2542a469 77b105f8547128036dcf7f0 */
+ 0x0.4eb44a5da74f600207aaa090f0p0L,
+ 0x0.734e288603ffadb3eb2542a469p-104L,
+
+/* x = 3.20312500000000000000000000000000000e-01 3ffd4800000000000000000000000000 */
+/* cos(x) = 0.f2faa5a1b74e82fd61fa05f917 7380e8e69b7b15a945e8e5ae11 24bf3d12b0617e03af4fab5 */
+ 0x0.f2faa5a1b74e82fd61fa05f917p0L,
+ 0x0.7380e8e69b7b15a945e8e5ae11p-104L,
+/* sin(x) = 0.509adf9a7b9a5a0f638a8fa3a6 0a199418859f18b37169a644fd b986c21ecb00133853bc35b */
+ 0x0.509adf9a7b9a5a0f638a8fa3a6p0L,
+ 0x0.0a199418859f18b37169a644fdp-104L,
+
+/* x = 3.28125000000000000000000000000000000e-01 3ffd5000000000000000000000000000 */
+/* cos(x) = 0.f2578a595224dd2e6bfa2eb2f9 9cc674f5ea6f479eae2eb58018 6897ae3f893df1113ca06b8 */
+ 0x0.f2578a595224dd2e6bfa2eb2f9p0L,
+ 0x0.9cc674f5ea6f479eae2eb58018p-104L,
+/* sin(x) = 0.5280326c3cf481823ba6bb08ea c82c2093f2bce3c4eb4ee3dec7 df41c92c8a4226098616075 */
+ 0x0.5280326c3cf481823ba6bb08eap0L,
+ 0x0.c82c2093f2bce3c4eb4ee3dec7p-104L,
+
+/* x = 3.35937500000000000000000000000000000e-01 3ffd5800000000000000000000000000 */
+/* cos(x) = 0.f1b0a5b406b526d886c55feadc 8d0dcc8eb9ae2ac707051771b4 8e05b25b000009660bdb3e3 */
+ 0x0.f1b0a5b406b526d886c55feadcp0L,
+ 0x0.8d0dcc8eb9ae2ac707051771b4p-104L,
+/* sin(x) = 0.54643b3da29de9b357155eef0f 332fb3e66c83bf4dddd9491c5e b8e103ccd92d6175220ed51 */
+ 0x0.54643b3da29de9b357155eef0fp0L,
+ 0x0.332fb3e66c83bf4dddd9491c5ep-104L,
+
+/* x = 3.43750000000000000000000000000000000e-01 3ffd6000000000000000000000000000 */
+/* cos(x) = 0.f105fa4d66b607a67d44e04272 5204435142ac8ad54dfb0907a4 f6b56b06d98ee60f19e557a */
+ 0x0.f105fa4d66b607a67d44e04272p0L,
+ 0x0.5204435142ac8ad54dfb0907a4p-104L,
+/* sin(x) = 0.5646f27e8bd65cbe3a5d61ff06 572290ee826d9674a00246b05a e26753cdfc90d9ce81a7d02 */
+ 0x0.5646f27e8bd65cbe3a5d61ff06p0L,
+ 0x0.572290ee826d9674a00246b05ap-104L,
+
+/* x = 3.51562500000000000000000000000000000e-01 3ffd6800000000000000000000000000 */
+/* cos(x) = 0.f0578ad01ede707fa39c09dc6b 984afef74f3dc8d0efb0f4c5a6 b13771145b3e0446fe33887 */
+ 0x0.f0578ad01ede707fa39c09dc6bp0L,
+ 0x0.984afef74f3dc8d0efb0f4c5a6p-104L,
+/* sin(x) = 0.582850a41e1dd46c7f602ea244 cdbbbfcdfa8f3189be794dda42 7ce090b5f85164f1f80ac13 */
+ 0x0.582850a41e1dd46c7f602ea244p0L,
+ 0x0.cdbbbfcdfa8f3189be794dda42p-104L,
+
+/* x = 3.59375000000000000000000000000000000e-01 3ffd7000000000000000000000000000 */
+/* cos(x) = 0.efa559f5ec3aec3a4eb0331927 8a2d41fcf9189462261125fe61 47b078f1daa0b06750a1654 */
+ 0x0.efa559f5ec3aec3a4eb0331927p0L,
+ 0x0.8a2d41fcf9189462261125fe61p-104L,
+/* sin(x) = 0.5a084e28e35fda2776dfdbbb55 31d74ced2b5d17c0b1afc46475 29d50c295e36d8ceec126c1 */
+ 0x0.5a084e28e35fda2776dfdbbb55p0L,
+ 0x0.31d74ced2b5d17c0b1afc46475p-104L,
+
+/* x = 3.67187500000000000000000000000000000e-01 3ffd7800000000000000000000000000 */
+/* cos(x) = 0.eeef6a879146af0bf9b95ea2ea 0ac0d3e2e4d7e15d93f48cbd41 bf8e4fded40bef69e19eafa */
+ 0x0.eeef6a879146af0bf9b95ea2eap0L,
+ 0x0.0ac0d3e2e4d7e15d93f48cbd41p-104L,
+/* sin(x) = 0.5be6e38ce8095542bc14ee9da0 d36483e6734bcab2e07624188a f5653f114eeb46738fa899d */
+ 0x0.5be6e38ce8095542bc14ee9da0p0L,
+ 0x0.d36483e6734bcab2e07624188ap-104L,
+
+/* x = 3.75000000000000000000000000000000000e-01 3ffd8000000000000000000000000000 */
+/* cos(x) = 0.ee35bf5ccac89052cd91ddb734 d3a47e262e3b609db604e21705 3803be0091e76daf28a89b7 */
+ 0x0.ee35bf5ccac89052cd91ddb734p0L,
+ 0x0.d3a47e262e3b609db604e21705p-104L,
+/* sin(x) = 0.5dc40955d9084f48a94675a249 8de5d851320ff5528a6afb3f2e 24de240fce6cbed1ba0ccd6 */
+ 0x0.5dc40955d9084f48a94675a249p0L,
+ 0x0.8de5d851320ff5528a6afb3f2ep-104L,
+
+/* x = 3.82812500000000000000000000000000000e-01 3ffd8800000000000000000000000000 */
+/* cos(x) = 0.ed785b5c44741b4493c56bcb9d 338a151c6f6b85d8f8aca658b2 8572c162b199680eb9304da */
+ 0x0.ed785b5c44741b4493c56bcb9dp0L,
+ 0x0.338a151c6f6b85d8f8aca658b2p-104L,
+/* sin(x) = 0.5f9fb80f21b53649c432540a50 e22c53057ff42ae0fdf1307760 dc0093f99c8efeb2fbd7073 */
+ 0x0.5f9fb80f21b53649c432540a50p0L,
+ 0x0.e22c53057ff42ae0fdf1307760p-104L,
+
+/* x = 3.90625000000000000000000000000000000e-01 3ffd9000000000000000000000000000 */
+/* cos(x) = 0.ecb7417b8d4ee3fec37aba4073 aa48f1f14666006fb431d96713 03c8100d10190ec8179c41d */
+ 0x0.ecb7417b8d4ee3fec37aba4073p0L,
+ 0x0.aa48f1f14666006fb431d96713p-104L,
+/* sin(x) = 0.6179e84a09a5258a40e9b5face 03e525f8b5753cd0105d93fe62 98010c3458e84d75fe420e9 */
+ 0x0.6179e84a09a5258a40e9b5facep0L,
+ 0x0.03e525f8b5753cd0105d93fe62p-104L,
+
+/* x = 3.98437500000000000000000000000000000e-01 3ffd9800000000000000000000000000 */
+/* cos(x) = 0.ebf274bf0bda4f62447e56a093 626798d3013b5942b1abfd155a acc9dc5c6d0806a20d6b9c1 */
+ 0x0.ebf274bf0bda4f62447e56a093p0L,
+ 0x0.626798d3013b5942b1abfd155ap-104L,
+/* sin(x) = 0.6352929dd264bd44a02ea76632 5d8aa8bd9695fc8def3caefba5 b94c9a3c873f7b2d3776ead */
+ 0x0.6352929dd264bd44a02ea76632p0L,
+ 0x0.5d8aa8bd9695fc8def3caefba5p-104L,
+
+/* x = 4.06250000000000000000000000000000000e-01 3ffda000000000000000000000000000 */
+/* cos(x) = 0.eb29f839f201fd13b937968279 16a78f15c85230a4e8ea4b2155 8265a14367e1abb4c30695a */
+ 0x0.eb29f839f201fd13b937968279p0L,
+ 0x0.16a78f15c85230a4e8ea4b2155p-104L,
+/* sin(x) = 0.6529afa7d51b129631ec197c0a 840a11d7dc5368b0a47956feb2 85caa8371c4637ef17ef01b */
+ 0x0.6529afa7d51b129631ec197c0ap0L,
+ 0x0.840a11d7dc5368b0a47956feb2p-104L,
+
+/* x = 4.14062500000000000000000000000000000e-01 3ffda800000000000000000000000000 */
+/* cos(x) = 0.ea5dcf0e30cf03e6976ef0b1ec 26515fba47383855c3b4055a99 b5e86824b2cd1a691fdca7b */
+ 0x0.ea5dcf0e30cf03e6976ef0b1ecp0L,
+ 0x0.26515fba47383855c3b4055a99p-104L,
+/* sin(x) = 0.66ff380ba0144109e39a320b0a 3fa5fd65ea0585bcbf9b1a769a 9b0334576c658139e1a1cbe */
+ 0x0.66ff380ba0144109e39a320b0ap0L,
+ 0x0.3fa5fd65ea0585bcbf9b1a769ap-104L,
+
+/* x = 4.21875000000000000000000000000000000e-01 3ffdb000000000000000000000000000 */
+/* cos(x) = 0.e98dfc6c6be031e60dd3089cbd d18a75b1f6b2c1e97f79225202 f03dbea45b07a5ec4efc062 */
+ 0x0.e98dfc6c6be031e60dd3089cbdp0L,
+ 0x0.d18a75b1f6b2c1e97f79225202p-104L,
+/* sin(x) = 0.68d32473143327973bc712bcc4 ccddc47630d755850c0655243b 205934dc49ffed8eb76adcb */
+ 0x0.68d32473143327973bc712bcc4p0L,
+ 0x0.ccddc47630d755850c0655243bp-104L,
+
+/* x = 4.29687500000000000000000000000000000e-01 3ffdb800000000000000000000000000 */
+/* cos(x) = 0.e8ba8393eca7821aa563d83491 b6101189b3b101c3677f73d7ba d7c10f9ee02b7ab4009739a */
+ 0x0.e8ba8393eca7821aa563d83491p0L,
+ 0x0.b6101189b3b101c3677f73d7bap-104L,
+/* sin(x) = 0.6aa56d8e8249db4eb60a761fe3 f9e559be456b9e13349ca99b0b fb787f22b95db3b70179615 */
+ 0x0.6aa56d8e8249db4eb60a761fe3p0L,
+ 0x0.f9e559be456b9e13349ca99b0bp-104L,
+
+/* x = 4.37500000000000000000000000000000000e-01 3ffdc000000000000000000000000000 */
+/* cos(x) = 0.e7e367d2956cfb16b6aa11e541 9cd0057f5c132a6455bf064297 e6a76fe2b72bb630d6d50ff */
+ 0x0.e7e367d2956cfb16b6aa11e541p0L,
+ 0x0.9cd0057f5c132a6455bf064297p-104L,
+/* sin(x) = 0.6c760c14c8585a51dbd34660ae 6c52ac7036a0b40887a0b63724 f8b4414348c3063a637f457 */
+ 0x0.6c760c14c8585a51dbd34660aep0L,
+ 0x0.6c52ac7036a0b40887a0b63724p-104L,
+
+/* x = 4.45312500000000000000000000000000000e-01 3ffdc800000000000000000000000000 */
+/* cos(x) = 0.e708ac84d4172a3e2737662213 429e14021074d7e702e77d72a8 f1101a7e70410df8273e9aa */
+ 0x0.e708ac84d4172a3e2737662213p0L,
+ 0x0.429e14021074d7e702e77d72a8p-104L,
+/* sin(x) = 0.6e44f8c36eb10a1c752d093c00 f4d47ba446ac4c215d26b03164 42f168459e677d06e7249e3 */
+ 0x0.6e44f8c36eb10a1c752d093c00p0L,
+ 0x0.f4d47ba446ac4c215d26b03164p-104L,
+
+/* x = 4.53125000000000000000000000000000000e-01 3ffdd000000000000000000000000000 */
+/* cos(x) = 0.e62a551594b970a770b15d41d4 c0e483e47aca550111df6966f9 e7ac3a94ae49e6a71eb031e */
+ 0x0.e62a551594b970a770b15d41d4p0L,
+ 0x0.c0e483e47aca550111df6966f9p-104L,
+/* sin(x) = 0.70122c5ec5028c8cff33abf4fd 340ccc382e038379b09cf04f9a 52692b10b72586060cbb001 */
+ 0x0.70122c5ec5028c8cff33abf4fdp0L,
+ 0x0.340ccc382e038379b09cf04f9ap-104L,
+
+/* x = 4.60937500000000000000000000000000000e-01 3ffdd800000000000000000000000000 */
+/* cos(x) = 0.e54864fe33e8575cabf5bd0e5c f1b1a8bc7c0d5f61702450fa6b 6539735820dd2603ae355d5 */
+ 0x0.e54864fe33e8575cabf5bd0e5cp0L,
+ 0x0.f1b1a8bc7c0d5f61702450fa6bp-104L,
+/* sin(x) = 0.71dd9fb1ff4677853acb970a9f 6729c6e3aac247b1c57cea66c7 7413f1f98e8b9e98e49d851 */
+ 0x0.71dd9fb1ff4677853acb970a9fp0L,
+ 0x0.6729c6e3aac247b1c57cea66c7p-104L,
+
+/* x = 4.68750000000000000000000000000000000e-01 3ffde000000000000000000000000000 */
+/* cos(x) = 0.e462dfc670d421ab3d1a159012 28f146a0547011202bf5ab01f9 14431859aef577966bc4fa4 */
+ 0x0.e462dfc670d421ab3d1a159012p0L,
+ 0x0.28f146a0547011202bf5ab01f9p-104L,
+/* sin(x) = 0.73a74b8f52947b681baf6928eb 3fb021769bf4779bad0e3aa9b1 cdb75ec60aad9fc63ff19d5 */
+ 0x0.73a74b8f52947b681baf6928ebp0L,
+ 0x0.3fb021769bf4779bad0e3aa9b1p-104L,
+
+/* x = 4.76562500000000000000000000000000000e-01 3ffde800000000000000000000000000 */
+/* cos(x) = 0.e379c9045f29d517c4808aa497 c2057b2b3d109e76c0dc302d4d 0698b36e3f0bdbf33d8e952 */
+ 0x0.e379c9045f29d517c4808aa497p0L,
+ 0x0.c2057b2b3d109e76c0dc302d4dp-104L,
+/* sin(x) = 0.756f28d011d98528a44a75fc29 c779bd734ecdfb582fdb74b68a 4c4c4be54cfd0b2d3ad292f */
+ 0x0.756f28d011d98528a44a75fc29p0L,
+ 0x0.c779bd734ecdfb582fdb74b68ap-104L,
+
+/* x = 4.84375000000000000000000000000000000e-01 3ffdf000000000000000000000000000 */
+/* cos(x) = 0.e28d245c58baef72225e232abc 003c4366acd9eb4fc2808c2ab7 fe7676cf512ac7f945ae5fb */
+ 0x0.e28d245c58baef72225e232abcp0L,
+ 0x0.003c4366acd9eb4fc2808c2ab7p-104L,
+/* sin(x) = 0.77353054ca72690d4c6e171fd9 9e6b39fa8e1ede5f052fd29645 34c75340970a3a9cd3c5c32 */
+ 0x0.77353054ca72690d4c6e171fd9p0L,
+ 0x0.9e6b39fa8e1ede5f052fd29645p-104L,
+
+/* x = 4.92187500000000000000000000000000000e-01 3ffdf800000000000000000000000000 */
+/* cos(x) = 0.e19cf580eeec046aa1422fa748 07ecefb2a1911c94e7b5f20a00 f70022d940193691e5bd790 */
+ 0x0.e19cf580eeec046aa1422fa748p0L,
+ 0x0.07ecefb2a1911c94e7b5f20a00p-104L,
+/* sin(x) = 0.78f95b0560a9a3bd6df7bd981d c38c61224d08bc20631ea932e6 05e53b579e9e0767dfcbbcb */
+ 0x0.78f95b0560a9a3bd6df7bd981dp0L,
+ 0x0.c38c61224d08bc20631ea932e6p-104L,
+
+/* x = 5.00000000000000000000000000000000000e-01 3ffe0000000000000000000000000000 */
+/* cos(x) = 0.e0a94032dbea7cedbddd9da2fa fad98556566b3a89f43eabd723 50af3e8b19e801204d8fe2e */
+ 0x0.e0a94032dbea7cedbddd9da2fap0L,
+ 0x0.fad98556566b3a89f43eabd723p-104L,
+/* sin(x) = 0.7abba1d12c17bfa1d92f0d93f6 0ded9992f45b4fcaf13cd58b30 3693d2a0db47db35ae8a3a9 */
+ 0x0.7abba1d12c17bfa1d92f0d93f6p0L,
+ 0x0.0ded9992f45b4fcaf13cd58b30p-104L,
+
+/* x = 5.07812500000000000000000000000000000e-01 3ffe0400000000000000000000000000 */
+/* cos(x) = 0.dfb20840f3a9b36f7ae2c51534 2890b5ec583b8366cc2b55029e 95094d31112383f2553498b */
+ 0x0.dfb20840f3a9b36f7ae2c51534p0L,
+ 0x0.2890b5ec583b8366cc2b55029ep-104L,
+/* sin(x) = 0.7c7bfdaf13e5ed17212f8a7525 bfb113aba6c0741b5362bb8d59 282a850b63716bca0c910f0 */
+ 0x0.7c7bfdaf13e5ed17212f8a7525p0L,
+ 0x0.bfb113aba6c0741b5362bb8d59p-104L,
+
+/* x = 5.15625000000000000000000000000000000e-01 3ffe0800000000000000000000000000 */
+/* cos(x) = 0.deb7518814a7a931bbcc88c109 cd41c50bf8bb48f20ae8c36628 d1d3d57574f7dc58f27d91c */
+ 0x0.deb7518814a7a931bbcc88c109p0L,
+ 0x0.cd41c50bf8bb48f20ae8c36628p-104L,
+/* sin(x) = 0.7e3a679daaf25c676542bcb402 8d0964172961c921823a4ef0c3 a9070d886dbd073f6283699 */
+ 0x0.7e3a679daaf25c676542bcb402p0L,
+ 0x0.8d0964172961c921823a4ef0c3p-104L,
+
+/* x = 5.23437500000000000000000000000000000e-01 3ffe0c00000000000000000000000000 */
+/* cos(x) = 0.ddb91ff318799172bd2452d0a3 889f5169c64a0094bcf0b8aa7d cf0d7640a2eba68955a80be */
+ 0x0.ddb91ff318799172bd2452d0a3p0L,
+ 0x0.889f5169c64a0094bcf0b8aa7dp-104L,
+/* sin(x) = 0.7ff6d8a34bd5e8fa54c97482db 5159df1f24e8038419c0b448b9 eea8939b5d4dfcf40900257 */
+ 0x0.7ff6d8a34bd5e8fa54c97482dbp0L,
+ 0x0.5159df1f24e8038419c0b448b9p-104L,
+
+/* x = 5.31250000000000000000000000000000000e-01 3ffe1000000000000000000000000000 */
+/* cos(x) = 0.dcb7777ac420705168f31e3eb7 80ce9c939ecada62843b54522f 5407eb7f21e556059fcd734 */
+ 0x0.dcb7777ac420705168f31e3eb7p0L,
+ 0x0.80ce9c939ecada62843b54522fp-104L,
+/* sin(x) = 0.81b149ce34caa5a4e650f8d09f d4d6aa74206c32ca951a93074c 83b2d294d25dbb0f7fdfad2 */
+ 0x0.81b149ce34caa5a4e650f8d09fp0L,
+ 0x0.d4d6aa74206c32ca951a93074cp-104L,
+
+/* x = 5.39062500000000000000000000000000000e-01 3ffe1400000000000000000000000000 */
+/* cos(x) = 0.dbb25c25b8260c14f6e7bc98ec 991b70c65335198b0ab628bad2 0cc7b229d4dd62183cfa055 */
+ 0x0.dbb25c25b8260c14f6e7bc98ecp0L,
+ 0x0.991b70c65335198b0ab628bad2p-104L,
+/* sin(x) = 0.8369b434a372da7eb5c8a71fe3 6ce1e0b2b493f6f5cb2e38bcae c2a556b3678c401940d1c3c */
+ 0x0.8369b434a372da7eb5c8a71fe3p0L,
+ 0x0.6ce1e0b2b493f6f5cb2e38bcaep-104L,
+
+/* x = 5.46875000000000000000000000000000000e-01 3ffe1800000000000000000000000000 */
+/* cos(x) = 0.daa9d20860827063fde51c09e8 55e9932e1b17143e7244fd267a 899d41ae1f3bc6a0ec42e27 */
+ 0x0.daa9d20860827063fde51c09e8p0L,
+ 0x0.55e9932e1b17143e7244fd267ap-104L,
+/* sin(x) = 0.852010f4f0800521378bd8dd61 4753d080c2e9e0775ffc609947 b9132f5357404f464f06a58 */
+ 0x0.852010f4f0800521378bd8dd61p0L,
+ 0x0.4753d080c2e9e0775ffc609947p-104L,
+
+/* x = 5.54687500000000000000000000000000000e-01 3ffe1c00000000000000000000000000 */
+/* cos(x) = 0.d99ddd44e44a43d4d4a3a3ed95 204106fd54d78e8c7684545c0d a0b7c2c72be7a89b7c182ad */
+ 0x0.d99ddd44e44a43d4d4a3a3ed95p0L,
+ 0x0.204106fd54d78e8c7684545c0dp-104L,
+/* sin(x) = 0.86d45935ab396cb4e421e822de e54f3562dfcefeaa782184c234 01d231f5ad981a1cc195b18 */
+ 0x0.86d45935ab396cb4e421e822dep0L,
+ 0x0.e54f3562dfcefeaa782184c234p-104L,
+
+/* x = 5.62500000000000000000000000000000000e-01 3ffe2000000000000000000000000000 */
+/* cos(x) = 0.d88e820b1526311dd561efbc0c 1a9a5375eb26f65d246c5744b1 3ca26a7e0fd42556da843c8 */
+ 0x0.d88e820b1526311dd561efbc0cp0L,
+ 0x0.1a9a5375eb26f65d246c5744b1p-104L,
+/* sin(x) = 0.88868625b4e1dbb23133101330 22527200c143a5cb16637cb7da f8ade82459ff2e98511f40f */
+ 0x0.88868625b4e1dbb23133101330p0L,
+ 0x0.22527200c143a5cb16637cb7dap-104L,
+
+/* x = 5.70312500000000000000000000000000000e-01 3ffe2400000000000000000000000000 */
+/* cos(x) = 0.d77bc4985e93a607c9d868b906 bbc6bbe3a04258814acb035846 8b826fc91bd4d814827f65e */
+ 0x0.d77bc4985e93a607c9d868b906p0L,
+ 0x0.bbc6bbe3a04258814acb035846p-104L,
+/* sin(x) = 0.8a3690fc5bfc11bf9535e2739a 8512f448a41251514bbed7fc18 d530f9b4650fcbb2861b0aa */
+ 0x0.8a3690fc5bfc11bf9535e2739ap0L,
+ 0x0.8512f448a41251514bbed7fc18p-104L,
+
+/* x = 5.78125000000000000000000000000000000e-01 3ffe2800000000000000000000000000 */
+/* cos(x) = 0.d665a937b4ef2b1f6d51bad6d9 88a4419c1d7051faf31a9efa15 1d7631117efac03713f950a */
+ 0x0.d665a937b4ef2b1f6d51bad6d9p0L,
+ 0x0.88a4419c1d7051faf31a9efa15p-104L,
+/* sin(x) = 0.8be472f9776d809af2b8817124 3d63d66dfceeeb739cc894e023 fbc165a0e3f26ff729c5d57 */
+ 0x0.8be472f9776d809af2b8817124p0L,
+ 0x0.3d63d66dfceeeb739cc894e023p-104L,
+
+/* x = 5.85937500000000000000000000000000000e-01 3ffe2c00000000000000000000000000 */
+/* cos(x) = 0.d54c3441844897fc8f853f0655 f1ba695eba9fbfd7439dbb1171 d862d9d9146ca5136f825ac */
+ 0x0.d54c3441844897fc8f853f0655p0L,
+ 0x0.f1ba695eba9fbfd7439dbb1171p-104L,
+/* sin(x) = 0.8d902565817ee7839bce3cd128 060119492cd36d42d82ada30d7 f8bde91324808377ddbf5d4 */
+ 0x0.8d902565817ee7839bce3cd128p0L,
+ 0x0.060119492cd36d42d82ada30d7p-104L,
+
+/* x = 5.93750000000000000000000000000000000e-01 3ffe3000000000000000000000000000 */
+/* cos(x) = 0.d42f6a1b9f0168cdf031c2f63c 8d9304d86f8d34cb1d5fccb68c a0f2241427fc18d1fd5bbdf */
+ 0x0.d42f6a1b9f0168cdf031c2f63cp0L,
+ 0x0.8d9304d86f8d34cb1d5fccb68cp-104L,
+/* sin(x) = 0.8f39a191b2ba6122a3fa4f41d5 a3ffd421417d46f19a22230a14 f7fcc8fce5c75b4b28b29d1 */
+ 0x0.8f39a191b2ba6122a3fa4f41d5p0L,
+ 0x0.a3ffd421417d46f19a22230a14p-104L,
+
+/* x = 6.01562500000000000000000000000000000e-01 3ffe3400000000000000000000000000 */
+/* cos(x) = 0.d30f4f392c357ab0661c5fa8a7 d9b26627846fef214b1d19a223 79ff9eddba087cf410eb097 */
+ 0x0.d30f4f392c357ab0661c5fa8a7p0L,
+ 0x0.d9b26627846fef214b1d19a223p-104L,
+/* sin(x) = 0.90e0e0d81ca678796cc92c8ea8 c2815bc72ca78abe571bfa8576 aacc571e096a33237e0e830 */
+ 0x0.90e0e0d81ca678796cc92c8ea8p0L,
+ 0x0.c2815bc72ca78abe571bfa8576p-104L,
+
+/* x = 6.09375000000000000000000000000000000e-01 3ffe3800000000000000000000000000 */
+/* cos(x) = 0.d1ebe81a95ee752e48a26bcd32 d6e922d7eb44b8ad2232f69307 95e84b56317269b9dd1dfa6 */
+ 0x0.d1ebe81a95ee752e48a26bcd32p0L,
+ 0x0.d6e922d7eb44b8ad2232f69307p-104L,
+/* sin(x) = 0.9285dc9bc45dd9ea3d02457bcc e59c4175aab6ff7929a8d28719 5525fdace200dba032874fb */
+ 0x0.9285dc9bc45dd9ea3d02457bccp0L,
+ 0x0.e59c4175aab6ff7929a8d28719p-104L,
+
+/* x = 6.17187500000000000000000000000000000e-01 3ffe3c00000000000000000000000000 */
+/* cos(x) = 0.d0c5394d772228195e25736c03 574707de0af1ca344b13bd3914 bfe27518e9e426f5deff1e1 */
+ 0x0.d0c5394d772228195e25736c03p0L,
+ 0x0.574707de0af1ca344b13bd3914p-104L,
+/* sin(x) = 0.94288e48bd0335fc41c4cbd292 0497a8f5d1d8185c99fa0081f9 0c27e2a53ffdd208a0dbe69 */
+ 0x0.94288e48bd0335fc41c4cbd292p0L,
+ 0x0.0497a8f5d1d8185c99fa0081f9p-104L,
+
+/* x = 6.25000000000000000000000000000000000e-01 3ffe4000000000000000000000000000 */
+/* cos(x) = 0.cf9b476c897c25c5bfe750dd3f 308eaf7bcc1ed00179a256870f 4200445043dcdb1974b5878 */
+ 0x0.cf9b476c897c25c5bfe750dd3fp0L,
+ 0x0.308eaf7bcc1ed00179a256870fp-104L,
+/* sin(x) = 0.95c8ef544210ec0b91c49bd2aa 09e8515fa61a156ebb10f5f8c2 32a6445b61ebf3c2ec268f9 */
+ 0x0.95c8ef544210ec0b91c49bd2aap0L,
+ 0x0.09e8515fa61a156ebb10f5f8c2p-104L,
+
+/* x = 6.32812500000000000000000000000000000e-01 3ffe4400000000000000000000000000 */
+/* cos(x) = 0.ce6e171f92f2e27f32225327ec 440ddaefae248413efc0e58cee e1ae369aabe73f88c87ed1a */
+ 0x0.ce6e171f92f2e27f32225327ecp0L,
+ 0x0.440ddaefae248413efc0e58ceep-104L,
+/* sin(x) = 0.9766f93cd18413a6aafc1cfc6f c28abb6817bf94ce349901ae3f 48c3215d3eb60acc5f78903 */
+ 0x0.9766f93cd18413a6aafc1cfc6fp0L,
+ 0x0.c28abb6817bf94ce349901ae3fp-104L,
+
+/* x = 6.40625000000000000000000000000000000e-01 3ffe4800000000000000000000000000 */
+/* cos(x) = 0.cd3dad1b5328a2e459f993f4f5 108819faccbc4eeba9604e81c7 adad51cc8a2561631a06826 */
+ 0x0.cd3dad1b5328a2e459f993f4f5p0L,
+ 0x0.108819faccbc4eeba9604e81c7p-104L,
+/* sin(x) = 0.9902a58a45e27bed68412b426b 675ed503f54d14c8172e0d373f 42cadf04daf67319a7f94be */
+ 0x0.9902a58a45e27bed68412b426bp0L,
+ 0x0.675ed503f54d14c8172e0d373fp-104L,
+
+/* x = 6.48437500000000000000000000000000000e-01 3ffe4c00000000000000000000000000 */
+/* cos(x) = 0.cc0a0e21709883a3ff00911e11 a07ee3bd7ea2b04e081be99be0 264791170761ae64b8b744a */
+ 0x0.cc0a0e21709883a3ff00911e11p0L,
+ 0x0.a07ee3bd7ea2b04e081be99be0p-104L,
+/* sin(x) = 0.9a9bedcdf01b38d993f3d78207 81de292033ead73b89e28f3931 3dbe3a6e463f845b5fa8490 */
+ 0x0.9a9bedcdf01b38d993f3d78207p0L,
+ 0x0.81de292033ead73b89e28f3931p-104L,
+
+/* x = 6.56250000000000000000000000000000000e-01 3ffe5000000000000000000000000000 */
+/* cos(x) = 0.cad33f00658fe5e8204bbc0f3a 66a0e6a773f87987a780b243d7 be83b3db1448ca0e0e62787 */
+ 0x0.cad33f00658fe5e8204bbc0f3ap0L,
+ 0x0.66a0e6a773f87987a780b243d7p-104L,
+/* sin(x) = 0.9c32cba2b14156ef05256c4f85 7991ca6a547cd7ceb1ac8a8e62 a282bd7b9183648a462bd04 */
+ 0x0.9c32cba2b14156ef05256c4f85p0L,
+ 0x0.7991ca6a547cd7ceb1ac8a8e62p-104L,
+
+/* x = 6.64062500000000000000000000000000000e-01 3ffe5400000000000000000000000000 */
+/* cos(x) = 0.c99944936cf48c8911ff93fe64 b3ddb7981e414bdaf6aae12035 77de44878c62bc3bc9cf7b9 */
+ 0x0.c99944936cf48c8911ff93fe64p0L,
+ 0x0.b3ddb7981e414bdaf6aae12035p-104L,
+/* sin(x) = 0.9dc738ad14204e689ac582d0f8 5826590feece34886cfefe2e08 cf2bb8488d55424dc9d3525 */
+ 0x0.9dc738ad14204e689ac582d0f8p0L,
+ 0x0.5826590feece34886cfefe2e08p-104L,
+
+/* x = 6.71875000000000000000000000000000000e-01 3ffe5800000000000000000000000000 */
+/* cos(x) = 0.c85c23c26ed7b6f014ef546c47 929682122876bfbf157de0aff3 c4247d820c746e32cd4174f */
+ 0x0.c85c23c26ed7b6f014ef546c47p0L,
+ 0x0.929682122876bfbf157de0aff3p-104L,
+/* sin(x) = 0.9f592e9b66a9cf906a3c7aa3c1 0199849040c45ec3f0a7475973 11038101780c5f266059dbf */
+ 0x0.9f592e9b66a9cf906a3c7aa3c1p0L,
+ 0x0.0199849040c45ec3f0a7475973p-104L,
+
+/* x = 6.79687500000000000000000000000000000e-01 3ffe5c00000000000000000000000000 */
+/* cos(x) = 0.c71be181ecd6875ce2da5615a0 3cca207d9adcb9dfb0a1d6c40a 4f0056437f1a59ccddd06ee */
+ 0x0.c71be181ecd6875ce2da5615a0p0L,
+ 0x0.3cca207d9adcb9dfb0a1d6c40ap-104L,
+/* sin(x) = 0.a0e8a725d33c828c11fa50fd9e 9a15ffecfad43f3e534358076b 9b0f6865694842b1e8c67dc */
+ 0x0.a0e8a725d33c828c11fa50fd9ep0L,
+ 0x0.9a15ffecfad43f3e534358076bp-104L,
+
+/* x = 6.87500000000000000000000000000000000e-01 3ffe6000000000000000000000000000 */
+/* cos(x) = 0.c5d882d2ee48030c7c07d28e98 1e34804f82ed4cf93655d23653 89b716de6ad44676a1cc5da */
+ 0x0.c5d882d2ee48030c7c07d28e98p0L,
+ 0x0.1e34804f82ed4cf93655d23653p-104L,
+/* sin(x) = 0.a2759c0e79c35582527c32b55f 5405c182c66160cb1d9eb7bb0b 7cdf4ad66f317bda4332914 */
+ 0x0.a2759c0e79c35582527c32b55fp0L,
+ 0x0.5405c182c66160cb1d9eb7bb0bp-104L,
+
+/* x = 6.95312500000000000000000000000000000e-01 3ffe6400000000000000000000000000 */
+/* cos(x) = 0.c4920cc2ec38fb891b38827db0 8884fc66371ac4c2052ca8885b 981bbcfd3bb7b093ee31515 */
+ 0x0.c4920cc2ec38fb891b38827db0p0L,
+ 0x0.8884fc66371ac4c2052ca8885bp-104L,
+/* sin(x) = 0.a400072188acf49cd6b173825e 038346f105e1301afe642bcc36 4cea455e21e506e3e927ed8 */
+ 0x0.a400072188acf49cd6b173825ep0L,
+ 0x0.038346f105e1301afe642bcc36p-104L,
+
+/* x = 7.03125000000000000000000000000000000e-01 3ffe6800000000000000000000000000 */
+/* cos(x) = 0.c348846bbd3631338ffe2bfe9d d1381a35b4e9c0c51b4c13fe37 6bad1bf5caacc4542be0aa9 */
+ 0x0.c348846bbd3631338ffe2bfe9dp0L,
+ 0x0.d1381a35b4e9c0c51b4c13fe37p-104L,
+/* sin(x) = 0.a587e23555bb08086d02b9c662 cdd29316c3e9bd08d93793634a 21b1810cce73bdb97a99b9e */
+ 0x0.a587e23555bb08086d02b9c662p0L,
+ 0x0.cdd29316c3e9bd08d93793634ap-104L,
+
+/* x = 7.10937500000000000000000000000000000e-01 3ffe6c00000000000000000000000000 */
+/* cos(x) = 0.c1fbeef380e4ffdd5a613ec872 2f643ffe814ec2343e53adb549 627224fdc9f2a7b77d3d69f */
+ 0x0.c1fbeef380e4ffdd5a613ec872p0L,
+ 0x0.2f643ffe814ec2343e53adb549p-104L,
+/* sin(x) = 0.a70d272a76a8d4b6da0ec90712 bb748b96dabf88c3079246f3db 7eea6e58ead4ed0e2843303 */
+ 0x0.a70d272a76a8d4b6da0ec90712p0L,
+ 0x0.bb748b96dabf88c3079246f3dbp-104L,
+
+/* x = 7.18750000000000000000000000000000000e-01 3ffe7000000000000000000000000000 */
+/* cos(x) = 0.c0ac518c8b6ae710ba37a3eeb9 0cb15aebcb8bed4356fb507a48 a6e97de9aa6d9660116b436 */
+ 0x0.c0ac518c8b6ae710ba37a3eeb9p0L,
+ 0x0.0cb15aebcb8bed4356fb507a48p-104L,
+/* sin(x) = 0.a88fcfebd9a8dd47e2f3c76ef9 e2439920f7e7fbe735f8bcc985 491ec6f12a2d4214f8cfa99 */
+ 0x0.a88fcfebd9a8dd47e2f3c76ef9p0L,
+ 0x0.e2439920f7e7fbe735f8bcc985p-104L,
+
+/* x = 7.26562500000000000000000000000000000e-01 3ffe7400000000000000000000000000 */
+/* cos(x) = 0.bf59b17550a440687596929656 7cf3e3b4e483061877c02811c6 cae85fad5a6c3da58f49292 */
+ 0x0.bf59b17550a440687596929656p0L,
+ 0x0.7cf3e3b4e483061877c02811c6p-104L,
+/* sin(x) = 0.aa0fd66eddb921232c28520d39 11b8a03193b47f187f1471ac21 6fbcd5bb81029294d3a73f1 */
+ 0x0.aa0fd66eddb921232c28520d39p0L,
+ 0x0.11b8a03193b47f187f1471ac21p-104L,
+
+/* x = 7.34375000000000000000000000000000000e-01 3ffe7800000000000000000000000000 */
+/* cos(x) = 0.be0413f84f2a771c614946a88c bf4da1d75a5560243de8f2283f efa0ea4a48468a52d51d8b3 */
+ 0x0.be0413f84f2a771c614946a88cp0L,
+ 0x0.bf4da1d75a5560243de8f2283fp-104L,
+/* sin(x) = 0.ab8d34b36acd987210ed343ec6 5d7e3adc2e7109fce43d55c8d5 7dfdf55b9e01d2cc1f1b9ec */
+ 0x0.ab8d34b36acd987210ed343ec6p0L,
+ 0x0.5d7e3adc2e7109fce43d55c8d5p-104L,
+
+/* x = 7.42187500000000000000000000000000000e-01 3ffe7c00000000000000000000000000 */
+/* cos(x) = 0.bcab7e6bfb2a14a9b122c574a3 76bec98ab14808c64a4e731b34 047e217611013ac99c0f25d */
+ 0x0.bcab7e6bfb2a14a9b122c574a3p0L,
+ 0x0.76bec98ab14808c64a4e731b34p-104L,
+/* sin(x) = 0.ad07e4c409d08c4fa3a9057bb0 ac24b8636e74e76f51e09bd6b2 319707cbd9f5e254643897a */
+ 0x0.ad07e4c409d08c4fa3a9057bb0p0L,
+ 0x0.ac24b8636e74e76f51e09bd6b2p-104L,
+
+/* x = 7.50000000000000000000000000000000000e-01 3ffe8000000000000000000000000000 */
+/* cos(x) = 0.bb4ff632a908f73ec151839cb9 d993b4e0bfb8f20e7e44e6e4ae e845e35575c3106dbe6fd06 */
+ 0x0.bb4ff632a908f73ec151839cb9p0L,
+ 0x0.d993b4e0bfb8f20e7e44e6e4aep-104L,
+/* sin(x) = 0.ae7fe0b5fc786b2d966e1d6af1 40a488476747c2646425fc7533 f532cd044cb10a971a49a6a */
+ 0x0.ae7fe0b5fc786b2d966e1d6af1p0L,
+ 0x0.40a488476747c2646425fc7533p-104L,
+
+/* x = 7.57812500000000000000000000000000000e-01 3ffe8400000000000000000000000000 */
+/* cos(x) = 0.b9f180ba77dd0751628e135a95 08299012230f14becacdd14c3f 8862d122de5b56d55b53360 */
+ 0x0.b9f180ba77dd0751628e135a95p0L,
+ 0x0.08299012230f14becacdd14c3fp-104L,
+/* sin(x) = 0.aff522a954f2ba16d9defdc416 e33f5e9a5dfd5a6c228e0abc4d 521327ff6e2517a7b3851dd */
+ 0x0.aff522a954f2ba16d9defdc416p0L,
+ 0x0.e33f5e9a5dfd5a6c228e0abc4dp-104L,
+
+/* x = 7.65625000000000000000000000000000000e-01 3ffe8800000000000000000000000000 */
+/* cos(x) = 0.b890237d3bb3c284b614a05390 16bfa1053730bbdf940fa895e1 85f8e58884d3dda15e63371 */
+ 0x0.b890237d3bb3c284b614a05390p0L,
+ 0x0.16bfa1053730bbdf940fa895e1p-104L,
+/* sin(x) = 0.b167a4c90d63c4244cf5493b7c c23bd3c3c1225e078baa0c53d6 d400b926281f537a1a260e6 */
+ 0x0.b167a4c90d63c4244cf5493b7cp0L,
+ 0x0.c23bd3c3c1225e078baa0c53d6p-104L,
+
+/* x = 7.73437500000000000000000000000000000e-01 3ffe8c00000000000000000000000000 */
+/* cos(x) = 0.b72be40067aaf2c050dbdb7a14 c3d7d4f203f6b3f0224a4afe55 d6ec8e92b508fd5c5984b3b */
+ 0x0.b72be40067aaf2c050dbdb7a14p0L,
+ 0x0.c3d7d4f203f6b3f0224a4afe55p-104L,
+/* sin(x) = 0.b2d7614b1f3aaa24df2d6e20a7 7e1ca3e6d838c03e29c1bcb026 e6733324815fadc9eb89674 */
+ 0x0.b2d7614b1f3aaa24df2d6e20a7p0L,
+ 0x0.7e1ca3e6d838c03e29c1bcb026p-104L,
+
+/* x = 7.81250000000000000000000000000000000e-01 3ffe9000000000000000000000000000 */
+/* cos(x) = 0.b5c4c7d4f7dae915ac786ccf4b 1a498d3e73b6e5e74fe7519d9c 53ee6d6b90e881bddfc33e1 */
+ 0x0.b5c4c7d4f7dae915ac786ccf4bp0L,
+ 0x0.1a498d3e73b6e5e74fe7519d9cp-104L,
+/* sin(x) = 0.b44452709a5975290591376543 4a59d111f0433eb2b133f7d103 207e2aeb4aae111ddc385b3 */
+ 0x0.b44452709a5975290591376543p0L,
+ 0x0.4a59d111f0433eb2b133f7d103p-104L,
+
+/* x = 7.89062500000000000000000000000000000e-01 3ffe9400000000000000000000000000 */
+/* cos(x) = 0.b45ad4975b1294cadca4cf40ec 8f22a68cd14b175835239a37e6 3acb85e8e9505215df18140 */
+ 0x0.b45ad4975b1294cadca4cf40ecp0L,
+ 0x0.8f22a68cd14b175835239a37e6p-104L,
+/* sin(x) = 0.b5ae7285bc10cf515753847e8f 8b7a30e0a580d929d770103509 880680f7b8b0e8ad23b65d8 */
+ 0x0.b5ae7285bc10cf515753847e8fp0L,
+ 0x0.8b7a30e0a580d929d770103509p-104L
+};
diff --git a/libc/sysdeps/ieee754/ldbl-128ibm/w_expl.c b/libc/sysdeps/ieee754/ldbl-128ibm/w_expl.c
new file mode 100644
index 000000000..a5e72b217
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-128ibm/w_expl.c
@@ -0,0 +1,6 @@
+/* Looks like we can use ieee854 w_expl.c as is for IBM extended format. */
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/w_expl.c>
+long_double_symbol (libm, __expl, expl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_asinhl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_asinhl.c
new file mode 100644
index 000000000..4e8a54126
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_asinhl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_asinhl.c>
+long_double_symbol (libm, __asinhl, asinhl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_atanl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_atanl.c
new file mode 100644
index 000000000..c23d14aad
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_atanl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_atanl.c>
+long_double_symbol (libm, __atanl, atanl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_cbrtl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_cbrtl.c
new file mode 100644
index 000000000..ace564527
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_cbrtl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_cbrtl.c>
+long_double_symbol (libm, __cbrtl, cbrtl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_ceill.c b/libc/sysdeps/ieee754/ldbl-64-128/s_ceill.c
new file mode 100644
index 000000000..a646494f1
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_ceill.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_ceill.c>
+long_double_symbol (libm, __ceill, ceill);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_copysignl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_copysignl.c
new file mode 100644
index 000000000..1319584a5
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_copysignl.c
@@ -0,0 +1,9 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_copysignl.c>
+#ifdef IS_IN_libm
+long_double_symbol (libm, __copysignl, copysignl);
+#else
+long_double_symbol (libc, __copysignl, copysignl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_cosl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_cosl.c
new file mode 100644
index 000000000..6a7e2e316
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_cosl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_cosl.c>
+long_double_symbol (libm, __cosl, cosl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_erfl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_erfl.c
new file mode 100644
index 000000000..c5f9bb3ac
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_erfl.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_erfl.c>
+long_double_symbol (libm, __erfl, erfl);
+long_double_symbol (libm, __erfcl, erfcl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_expm1l.c b/libc/sysdeps/ieee754/ldbl-64-128/s_expm1l.c
new file mode 100644
index 000000000..4fb186127
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_expm1l.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_expm1l.c>
+long_double_symbol (libm, __expm1l, expm1l);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_fabsl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_fabsl.c
new file mode 100644
index 000000000..93d81d98b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_fabsl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_fabsl.c>
+long_double_symbol (libm, __fabsl, fabsl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_finitel.c b/libc/sysdeps/ieee754/ldbl-64-128/s_finitel.c
new file mode 100644
index 000000000..90717a105
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_finitel.c
@@ -0,0 +1,17 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#undef hidden_def
+#define hidden_def(x)
+#define __finitel(arg) ___finitel(arg)
+#include <sysdeps/ieee754/ldbl-128/s_finitel.c>
+#undef __finitel
+hidden_ver (___finitel, __finitel)
+_weak_alias (___finitel, ____finitel)
+#ifdef IS_IN_libm
+long_double_symbol (libm, ____finitel, finitel);
+long_double_symbol (libm, ___finitel, __finitel);
+#else
+long_double_symbol (libc, ____finitel, finitel);
+long_double_symbol (libc, ___finitel, __finitel);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_floorl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_floorl.c
new file mode 100644
index 000000000..953043035
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_floorl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_floorl.c>
+long_double_symbol (libm, __floorl, floorl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_fpclassifyl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_fpclassifyl.c
new file mode 100644
index 000000000..a10b6c3a1
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_fpclassifyl.c
@@ -0,0 +1,10 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#define __fpclassifyl ___fpclassifyl
+#undef libm_hidden_def
+#define libm_hidden_def(a)
+#include <sysdeps/ieee754/ldbl-128/s_fpclassifyl.c>
+#undef __fpclassifyl
+long_double_symbol (libm, ___fpclassifyl, __fpclassifyl);
+libm_hidden_ver (___fpclassifyl, __fpclassifyl)
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_frexpl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_frexpl.c
new file mode 100644
index 000000000..685bbbab4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_frexpl.c
@@ -0,0 +1,9 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_frexpl.c>
+#ifdef IS_IN_libm
+long_double_symbol (libm, __frexpl, frexpl);
+#else
+long_double_symbol (libc, __frexpl, frexpl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_ilogbl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_ilogbl.c
new file mode 100644
index 000000000..bb8808240
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_ilogbl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_ilogbl.c>
+long_double_symbol (libm, __ilogbl, ilogbl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_isinfl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_isinfl.c
new file mode 100644
index 000000000..e046032b0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_isinfl.c
@@ -0,0 +1,16 @@
+#include <math_ldbl_opt.h>
+#ifndef IS_IN_libm
+# undef weak_alias
+# define weak_alias(n,a)
+# undef hidden_def
+# define hidden_def(x)
+# define __isinfl(arg) ___isinfl(arg)
+#endif
+#include <sysdeps/ieee754/ldbl-128/s_isinfl.c>
+#ifndef IS_IN_libm
+# undef __isinfl
+hidden_ver (___isinfl, __isinfl)
+_weak_alias (___isinfl, ____isinfl)
+long_double_symbol (libc, ____isinfl, isinfl);
+long_double_symbol (libc, ___isinfl, __isinfl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_isnanl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_isnanl.c
new file mode 100644
index 000000000..3673463ae
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_isnanl.c
@@ -0,0 +1,16 @@
+#include <math_ldbl_opt.h>
+#ifndef IS_IN_libm
+# undef weak_alias
+# define weak_alias(n,a)
+# undef hidden_def
+# define hidden_def(x)
+# define __isnanl(arg) ___isnanl(arg)
+#endif
+#include <sysdeps/ieee754/ldbl-128/s_isnanl.c>
+#ifndef IS_IN_libm
+# undef __isnanl
+hidden_ver (___isnanl, __isnanl)
+_weak_alias (___isnanl, ____isnanl)
+long_double_symbol (libc, ____isnanl, isnanl);
+long_double_symbol (libc, ___isnanl, __isnanl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_llrintl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_llrintl.c
new file mode 100644
index 000000000..1515f3abd
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_llrintl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_llrintl.c>
+long_double_symbol (libm, __llrintl, llrintl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_llroundl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_llroundl.c
new file mode 100644
index 000000000..ca35dae49
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_llroundl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_llroundl.c>
+long_double_symbol (libm, __llroundl, llroundl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_log1pl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_log1pl.c
new file mode 100644
index 000000000..eebd63638
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_log1pl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_log1pl.c>
+long_double_symbol (libm, __log1pl, log1pl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_logbl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_logbl.c
new file mode 100644
index 000000000..8ba8179fe
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_logbl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_logbl.c>
+long_double_symbol (libm, __logbl, logbl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_lrintl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_lrintl.c
new file mode 100644
index 000000000..56e69c94f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_lrintl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_lrintl.c>
+long_double_symbol (libm, __lrintl, lrintl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_lroundl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_lroundl.c
new file mode 100644
index 000000000..d5429e238
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_lroundl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_lroundl.c>
+long_double_symbol (libm, __lroundl, lroundl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_modfl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_modfl.c
new file mode 100644
index 000000000..c17d6690a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_modfl.c
@@ -0,0 +1,9 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_modfl.c>
+#ifdef IS_IN_libm
+long_double_symbol (libm, __modfl, modfl);
+#else
+long_double_symbol (libc, __modfl, modfl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_nearbyintl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_nearbyintl.c
new file mode 100644
index 000000000..a6d0a313f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_nearbyintl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_nearbyintl.c>
+long_double_symbol (libm, __nearbyintl, nearbyintl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_nextafterl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_nextafterl.c
new file mode 100644
index 000000000..64c663eda
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_nextafterl.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_nextafterl.c>
+long_double_symbol (libm, __nextafterl, nextafterl);
+long_double_symbol (libm, __nexttowardl, nexttowardl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_nexttoward.c b/libc/sysdeps/ieee754/ldbl-64-128/s_nexttoward.c
new file mode 100644
index 000000000..2968503d2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_nexttoward.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_nexttoward.c>
+long_double_symbol (libm, __nexttoward, nexttoward);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_nexttowardf.c b/libc/sysdeps/ieee754/ldbl-64-128/s_nexttowardf.c
new file mode 100644
index 000000000..64b9c2446
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_nexttowardf.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_nexttowardf.c>
+long_double_symbol (libm, __nexttowardf, nexttowardf);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_remquol.c b/libc/sysdeps/ieee754/ldbl-64-128/s_remquol.c
new file mode 100644
index 000000000..16f0eb16a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_remquol.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_remquol.c>
+long_double_symbol (libm, __remquol, remquol);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_rintl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_rintl.c
new file mode 100644
index 000000000..19af9bbdc
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_rintl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_rintl.c>
+long_double_symbol (libm, __rintl, rintl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_roundl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_roundl.c
new file mode 100644
index 000000000..3fa99d6f2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_roundl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_roundl.c>
+long_double_symbol (libm, __roundl, roundl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_scalblnl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_scalblnl.c
new file mode 100644
index 000000000..3143f18f6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_scalblnl.c
@@ -0,0 +1,9 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_scalblnl.c>
+#ifdef IS_IN_libm
+long_double_symbol (libm, __scalblnl, scalblnl);
+#else
+long_double_symbol (libc, __scalblnl, scalblnl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_scalbnl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_scalbnl.c
new file mode 100644
index 000000000..78520e964
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_scalbnl.c
@@ -0,0 +1,9 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_scalbnl.c>
+#ifdef IS_IN_libm
+long_double_symbol (libm, __scalbnl, scalbnl);
+#else
+long_double_symbol (libc, __scalbnl, scalbnl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_signbitl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_signbitl.c
new file mode 100644
index 000000000..f66db2f65
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_signbitl.c
@@ -0,0 +1,11 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#define __signbitl(arg) ___signbitl(arg)
+#include <sysdeps/ieee754/ldbl-128/s_signbitl.c>
+#undef __signbitl
+#ifdef IS_IN_libm
+long_double_symbol (libm, ___signbitl, __signbitl);
+#else
+long_double_symbol (libc, ___signbitl, __signbitl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_sincosl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_sincosl.c
new file mode 100644
index 000000000..ce0d4e288
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_sincosl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_sincosl.c>
+long_double_symbol (libm, __sincosl, sincosl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_sinl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_sinl.c
new file mode 100644
index 000000000..ebc20affd
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_sinl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_sinl.c>
+long_double_symbol (libm, __sinl, sinl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_tanhl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_tanhl.c
new file mode 100644
index 000000000..ede93930c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_tanhl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_tanhl.c>
+long_double_symbol (libm, __tanhl, tanhl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_tanl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_tanl.c
new file mode 100644
index 000000000..6e635dfdc
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_tanl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_tanl.c>
+long_double_symbol (libm, __tanl, tanl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/s_truncl.c b/libc/sysdeps/ieee754/ldbl-64-128/s_truncl.c
new file mode 100644
index 000000000..6311479d0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/s_truncl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/s_truncl.c>
+long_double_symbol (libm, __truncl, truncl);
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/strtold_l.c b/libc/sysdeps/ieee754/ldbl-64-128/strtold_l.c
new file mode 100644
index 000000000..ef8fe0575
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/strtold_l.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <xlocale.h>
+
+/* The actual implementation for all floating point sizes is in strtod.c.
+ These macros tell it to produce the `long double' version, `strtold'. */
+
+#define FLOAT long double
+#define FLT LDBL
+#ifdef USE_WIDE_CHAR
+extern long double ____new_wcstold_l (const wchar_t *, wchar_t **, __locale_t);
+# define STRTOF __new_wcstold_l
+# define __STRTOF ____new_wcstold_l
+# define ____STRTOF_INTERNAL ____wcstold_l_internal
+#else
+extern long double ____new_strtold_l (const char *, char **, __locale_t);
+# define STRTOF __new_strtold_l
+# define __STRTOF ____new_strtold_l
+# define ____STRTOF_INTERNAL ____strtold_l_internal
+#endif
+#define MPN2FLOAT __mpn_construct_long_double
+#define FLOAT_HUGE_VAL HUGE_VALL
+#define SET_MANTISSA(flt, mant) \
+ do { union ieee854_long_double u; \
+ u.d = (flt); \
+ u.ieee.mantissa0 = 0x8000; \
+ u.ieee.mantissa1 = 0; \
+ u.ieee.mantissa2 = ((mant) >> 32); \
+ u.ieee.mantissa3 = (mant) & 0xffffffff; \
+ (flt) = u.d; \
+ } while (0)
+
+#include <strtod_l.c>
+
+#ifdef __LONG_DOUBLE_MATH_OPTIONAL
+# include <math_ldbl_opt.h>
+# ifdef USE_WIDE_CHAR
+long_double_symbol (libc, __new_wcstold_l, wcstold_l);
+long_double_symbol (libc, ____new_wcstold_l, __wcstold_l);
+# else
+long_double_symbol (libc, __new_strtold_l, strtold_l);
+long_double_symbol (libc, ____new_strtold_l, __strtold_l);
+# endif
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-64-128/w_expl.c b/libc/sysdeps/ieee754/ldbl-64-128/w_expl.c
new file mode 100644
index 000000000..2a402b04c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-64-128/w_expl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <sysdeps/ieee754/ldbl-128/w_expl.c>
+long_double_symbol (libm, __expl, expl);
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_acoshl.c b/libc/sysdeps/ieee754/ldbl-96/e_acoshl.c
new file mode 100644
index 000000000..5d4fa1ded
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_acoshl.c
@@ -0,0 +1,72 @@
+/* e_acoshl.c -- long double version of e_acosh.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* __ieee754_acoshl(x)
+ * Method :
+ * Based on
+ * acoshl(x) = logl [ x + sqrtl(x*x-1) ]
+ * we have
+ * acoshl(x) := logl(x)+ln2, if x is large; else
+ * acoshl(x) := logl(2x-1/(sqrtl(x*x-1)+x)) if x>2; else
+ * acoshl(x) := log1pl(t+sqrtl(2.0*t+t*t)); where t=x-1.
+ *
+ * Special cases:
+ * acoshl(x) is NaN with signal if x<1.
+ * acoshl(NaN) is NaN without signal.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+one = 1.0,
+ln2 = 6.931471805599453094287e-01L; /* 0x3FFE, 0xB17217F7, 0xD1CF79AC */
+
+#ifdef __STDC__
+ long double __ieee754_acoshl(long double x)
+#else
+ long double __ieee754_acoshl(x)
+ long double x;
+#endif
+{
+ long double t;
+ u_int32_t se,i0,i1;
+ GET_LDOUBLE_WORDS(se,i0,i1,x);
+ if(se<0x3fff || se & 0x8000) { /* x < 1 */
+ return (x-x)/(x-x);
+ } else if(se >=0x401d) { /* x > 2**30 */
+ if(se >=0x7fff) { /* x is inf of NaN */
+ return x+x;
+ } else
+ return __ieee754_logl(x)+ln2; /* acoshl(huge)=logl(2x) */
+ } else if(((se-0x3fff)|i0|i1)==0) {
+ return 0.0; /* acosh(1) = 0 */
+ } else if (se > 0x4000) { /* 2**28 > x > 2 */
+ t=x*x;
+ return __ieee754_logl(2.0*x-one/(x+__ieee754_sqrtl(t-one)));
+ } else { /* 1<x<2 */
+ t = x-one;
+ return __log1pl(t+__sqrtl(2.0*t+t*t));
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_asinl.c b/libc/sysdeps/ieee754/ldbl-96/e_asinl.c
new file mode 100644
index 000000000..1cad623d4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_asinl.c
@@ -0,0 +1,161 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/*
+ Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __ieee754_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
+ * asin(x) = x + x*x^2*R(x^2)
+ *
+ * For x in [0.5,1]
+ * asin(x) = pi/2-2*asin(sqrt((1-x)/2))
+ * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
+ * then for x>0.98
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
+ * For x<=0.98, let pio4_hi = pio2_hi/2, then
+ * f = hi part of s;
+ * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
+ * and
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
+ * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ */
+
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ one = 1.0L,
+ huge = 1.0e+4932L,
+ pio2_hi = 1.5707963267948966192021943710788178805159986950457096099853515625L,
+ pio2_lo = 2.9127320560933561582586004641843300502121E-20L,
+ pio4_hi = 7.8539816339744830960109718553940894025800E-1L,
+
+ /* coefficient for R(x^2) */
+
+ /* asin(x) = x + x^3 pS(x^2) / qS(x^2)
+ 0 <= x <= 0.5
+ peak relative error 1.9e-21 */
+ pS0 = -1.008714657938491626019651170502036851607E1L,
+ pS1 = 2.331460313214179572063441834101394865259E1L,
+ pS2 = -1.863169762159016144159202387315381830227E1L,
+ pS3 = 5.930399351579141771077475766877674661747E0L,
+ pS4 = -6.121291917696920296944056882932695185001E-1L,
+ pS5 = 3.776934006243367487161248678019350338383E-3L,
+
+ qS0 = -6.052287947630949712886794360635592886517E1L,
+ qS1 = 1.671229145571899593737596543114258558503E2L,
+ qS2 = -1.707840117062586426144397688315411324388E2L,
+ qS3 = 7.870295154902110425886636075950077640623E1L,
+ qS4 = -1.568433562487314651121702982333303458814E1L;
+ /* 1.000000000000000000000000000000000000000E0 */
+
+#ifdef __STDC__
+long double
+__ieee754_asinl (long double x)
+#else
+double
+__ieee754_asinl (x)
+ long double x;
+#endif
+{
+ long double t, w, p, q, c, r, s;
+ int32_t ix;
+ u_int32_t se, i0, i1, k;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+ ix = (ix << 16) | (i0 >> 16);
+ if (ix >= 0x3fff8000)
+ { /* |x|>= 1 */
+ if (ix == 0x3fff8000 && ((i0 - 0x80000000) | i1) == 0)
+ /* asin(1)=+-pi/2 with inexact */
+ return x * pio2_hi + x * pio2_lo;
+ return (x - x) / (x - x); /* asin(|x|>1) is NaN */
+ }
+ else if (ix < 0x3ffe8000)
+ { /* |x|<0.5 */
+ if (ix < 0x3fde8000)
+ { /* if |x| < 2**-33 */
+ if (huge + x > one)
+ return x; /* return x with inexact if x!=0 */
+ }
+ else
+ {
+ t = x * x;
+ p =
+ t * (pS0 +
+ t * (pS1 + t * (pS2 + t * (pS3 + t * (pS4 + t * pS5)))));
+ q = qS0 + t * (qS1 + t * (qS2 + t * (qS3 + t * (qS4 + t))));
+ w = p / q;
+ return x + x * w;
+ }
+ }
+ /* 1> |x|>= 0.5 */
+ w = one - fabsl (x);
+ t = w * 0.5;
+ p = t * (pS0 + t * (pS1 + t * (pS2 + t * (pS3 + t * (pS4 + t * pS5)))));
+ q = qS0 + t * (qS1 + t * (qS2 + t * (qS3 + t * (qS4 + t))));
+ s = __ieee754_sqrtl (t);
+ if (ix >= 0x3ffef999)
+ { /* if |x| > 0.975 */
+ w = p / q;
+ t = pio2_hi - (2.0 * (s + s * w) - pio2_lo);
+ }
+ else
+ {
+ GET_LDOUBLE_WORDS (k, i0, i1, s);
+ i1 = 0;
+ SET_LDOUBLE_WORDS (w,k,i0,i1);
+ c = (t - w * w) / (s + w);
+ r = p / q;
+ p = 2.0 * s * r - (pio2_lo - 2.0 * c);
+ q = pio4_hi - 2.0 * w;
+ t = pio4_hi - (p - q);
+ }
+ if ((se & 0x8000) == 0)
+ return t;
+ else
+ return -t;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_atan2l.c b/libc/sysdeps/ieee754/ldbl-96/e_atan2l.c
new file mode 100644
index 000000000..0759458c2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_atan2l.c
@@ -0,0 +1,136 @@
+/* e_atan2l.c -- long double version of e_atan2.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* __ieee754_atan2l(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):
+ * ARG (x+iy) = arctan(y/x) ... if x > 0,
+ * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
+ *
+ * Special cases:
+ *
+ * ATAN2((anything), NaN ) is NaN;
+ * ATAN2(NAN , (anything) ) is NaN;
+ * ATAN2(+-0, +(anything but NaN)) is +-0 ;
+ * ATAN2(+-0, -(anything but NaN)) is +-pi ;
+ * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
+ * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
+ * ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
+ * ATAN2(+-INF,+INF ) is +-pi/4 ;
+ * ATAN2(+-INF,-INF ) is +-3pi/4;
+ * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+tiny = 1.0e-4900L,
+zero = 0.0,
+pi_o_4 = 7.85398163397448309628202E-01L, /* 0x3FFE, 0xC90FDAA2, 0x2168C235 */
+pi_o_2 = 1.5707963267948966192564E+00L, /* 0x3FFF, 0xC90FDAA2, 0x2168C235 */
+pi = 3.14159265358979323851281E+00L, /* 0x4000, 0xC90FDAA2, 0x2168C235 */
+pi_lo = -5.01655761266833202345176e-20L;/* 0xBFBE, 0xECE675D1, 0xFC8F8CBB */
+
+#ifdef __STDC__
+ long double __ieee754_atan2l(long double y, long double x)
+#else
+ long double __ieee754_atan2l(y,x)
+ long double y,x;
+#endif
+{
+ long double z;
+ int32_t k,m,hx,hy,ix,iy;
+ u_int32_t sx,sy,lx,ly;
+
+ GET_LDOUBLE_WORDS(sx,hx,lx,x);
+ ix = sx&0x7fff;
+ lx |= hx & 0x7fffffff;
+ GET_LDOUBLE_WORDS(sy,hy,ly,y);
+ iy = sy&0x7fff;
+ ly |= hy & 0x7fffffff;
+ if(((2*ix|((lx|-lx)>>31))>0xfffe)||
+ ((2*iy|((ly|-ly)>>31))>0xfffe)) /* x or y is NaN */
+ return x+y;
+ if(((sx-0x3fff)|lx)==0) return __atanl(y); /* x=1.0 */
+ m = ((sy>>15)&1)|((sx>>14)&2); /* 2*sign(x)+sign(y) */
+
+ /* when y = 0 */
+ if((iy|ly)==0) {
+ switch(m) {
+ case 0:
+ case 1: return y; /* atan(+-0,+anything)=+-0 */
+ case 2: return pi+tiny;/* atan(+0,-anything) = pi */
+ case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
+ }
+ }
+ /* when x = 0 */
+ if((ix|lx)==0) return (sy>=0x8000)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* when x is INF */
+ if(ix==0x7fff) {
+ if(iy==0x7fff) {
+ switch(m) {
+ case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
+ case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
+ case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
+ case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
+ }
+ } else {
+ switch(m) {
+ case 0: return zero ; /* atan(+...,+INF) */
+ case 1: return -zero ; /* atan(-...,+INF) */
+ case 2: return pi+tiny ; /* atan(+...,-INF) */
+ case 3: return -pi-tiny ; /* atan(-...,-INF) */
+ }
+ }
+ }
+ /* when y is INF */
+ if(iy==0x7fff) return (sy>=0x8000)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* compute y/x */
+ k = sy-sx;
+ if(k > 70) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**70 */
+ else if(sx>=0x8000&&k<-70) z=0.0; /* |y|/x < -2**70 */
+ else z=__atanl(fabsl(y/x)); /* safe to do y/x */
+ switch (m) {
+ case 0: return z ; /* atan(+,+) */
+ case 1: {
+ u_int32_t sz;
+ GET_LDOUBLE_EXP(sz,z);
+ SET_LDOUBLE_EXP(z,sz ^ 0x8000);
+ }
+ return z ; /* atan(-,+) */
+ case 2: return pi-(z-pi_lo);/* atan(+,-) */
+ default: /* case 3 */
+ return (z-pi_lo)-pi;/* atan(-,-) */
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_atanhl.c b/libc/sysdeps/ieee754/ldbl-96/e_atanhl.c
new file mode 100644
index 000000000..fdcd1e9fe
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_atanhl.c
@@ -0,0 +1,79 @@
+/* s_atanhl.c -- long double version of s_atan.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* __ieee754_atanhl(x)
+ * Method :
+ * 1.Reduced x to positive by atanh(-x) = -atanh(x)
+ * 2.For x>=0.5
+ * 1 2x x
+ * atanhl(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
+ * 2 1 - x 1 - x
+ *
+ * For x<0.5
+ * atanhl(x) = 0.5*log1pl(2x+2x*x/(1-x))
+ *
+ * Special cases:
+ * atanhl(x) is NaN if |x| > 1 with signal;
+ * atanhl(NaN) is that NaN with no signal;
+ * atanhl(+-1) is +-INF with signal.
+ *
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0, huge = 1e4900L;
+#else
+static long double one = 1.0, huge = 1e4900L;
+#endif
+
+#ifdef __STDC__
+static const long double zero = 0.0;
+#else
+static double long zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ long double __ieee754_atanhl(long double x)
+#else
+ long double __ieee754_atanhl(x)
+ long double x;
+#endif
+{
+ long double t;
+ int32_t ix;
+ u_int32_t se,i0,i1;
+ GET_LDOUBLE_WORDS(se,i0,i1,x);
+ ix = se&0x7fff;
+ if ((ix+((((i0&0x7fffffff)|i1)|(-((i0&0x7fffffff)|i1)))>>31))>0x3fff)
+ /* |x|>1 */
+ return (x-x)/(x-x);
+ if(ix==0x3fff)
+ return x/zero;
+ if(ix<0x3fe3&&(huge+x)>zero) return x; /* x<2**-28 */
+ SET_LDOUBLE_EXP(x,ix);
+ if(ix<0x3ffe) { /* x < 0.5 */
+ t = x+x;
+ t = 0.5*__log1pl(t+t*x/(one-x));
+ } else
+ t = 0.5*__log1pl((x+x)/(one-x));
+ if(se<=0x7fff) return t; else return -t;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_coshl.c b/libc/sysdeps/ieee754/ldbl-96/e_coshl.c
new file mode 100644
index 000000000..8c38fa4da
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_coshl.c
@@ -0,0 +1,93 @@
+/*
+ * ====================================================
+ * 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: e_cosh.c,v 1.7 1995/05/10 20:44:58 jtc Exp $";
+#endif
+
+/* __ieee754_coshl(x)
+ * Method :
+ * mathematically coshl(x) if defined to be (exp(x)+exp(-x))/2
+ * 1. Replace x by |x| (coshl(x) = coshl(-x)).
+ * 2.
+ * [ exp(x) - 1 ]^2
+ * 0 <= x <= ln2/2 : coshl(x) := 1 + -------------------
+ * 2*exp(x)
+ *
+ * exp(x) + 1/exp(x)
+ * ln2/2 <= x <= 22 : coshl(x) := -------------------
+ * 2
+ * 22 <= x <= lnovft : coshl(x) := expl(x)/2
+ * lnovft <= x <= ln2ovft: coshl(x) := expl(x/2)/2 * expl(x/2)
+ * ln2ovft < x : coshl(x) := huge*huge (overflow)
+ *
+ * Special cases:
+ * coshl(x) is |x| if x is +INF, -INF, or NaN.
+ * only coshl(0)=1 is exact for finite x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0, half=0.5, huge = 1.0e4900L;
+#else
+static long double one = 1.0, half=0.5, huge = 1.0e4900L;
+#endif
+
+#ifdef __STDC__
+ long double __ieee754_coshl(long double x)
+#else
+ long double __ieee754_coshl(x)
+ long double x;
+#endif
+{
+ long double t,w;
+ int32_t ex;
+ u_int32_t mx,lx;
+
+ /* High word of |x|. */
+ GET_LDOUBLE_WORDS(ex,mx,lx,x);
+ ex &= 0x7fff;
+
+ /* x is INF or NaN */
+ if(ex==0x7fff) return x*x;
+
+ /* |x| in [0,0.5*ln2], return 1+expm1l(|x|)^2/(2*expl(|x|)) */
+ if(ex < 0x3ffd || (ex == 0x3ffd && mx < 0xb17217f7u)) {
+ t = __expm1l(fabsl(x));
+ w = one+t;
+ if (ex<0x3fbc) return w; /* cosh(tiny) = 1 */
+ return one+(t*t)/(w+w);
+ }
+
+ /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
+ if (ex < 0x4003 || (ex == 0x4003 && mx < 0xb0000000u)) {
+ t = __ieee754_expl(fabsl(x));
+ return half*t+half/t;
+ }
+
+ /* |x| in [22, ln(maxdouble)] return half*exp(|x|) */
+ if (ex < 0x400c || (ex == 0x400c && mx < 0xb1700000u))
+ return half*__ieee754_expl(fabsl(x));
+
+ /* |x| in [log(maxdouble), log(2*maxdouble)) */
+ if (ex == 0x400c && (mx < 0xb174ddc0u
+ || (mx == 0xb174ddc0u && lx < 0x31aec0ebu)))
+ {
+ w = __ieee754_expl(half*fabsl(x));
+ t = half*w;
+ return t*w;
+ }
+
+ /* |x| >= log(2*maxdouble), cosh(x) overflow */
+ return huge*huge;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_gammal_r.c b/libc/sysdeps/ieee754/ldbl-96/e_gammal_r.c
new file mode 100644
index 000000000..dd956fed9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_gammal_r.c
@@ -0,0 +1,62 @@
+/* Implementation of gamma function according to ISO C.
+ Copyright (C) 1997, 1999, 2001, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_private.h>
+
+
+long double
+__ieee754_gammal_r (long double x, int *signgamp)
+{
+ /* We don't have a real gamma implementation now. We'll use lgamma
+ and the exp function. But due to the required boundary
+ conditions we must check some values separately. */
+ u_int32_t es, hx, lx;
+
+ GET_LDOUBLE_WORDS (es, hx, lx, x);
+
+ if (((es & 0x7fff) | hx | lx) == 0)
+ {
+ /* Return value for x == 0 is Inf with divide by zero exception. */
+ *signgamp = 0;
+ return 1.0 / x;
+ }
+ if (es == 0xffffffff && ((hx & 0x7fffffff) | lx) == 0)
+ {
+ /* x == -Inf. According to ISO this is NaN. */
+ *signgamp = 0;
+ return x - x;
+ }
+ if ((es & 0x7fff) == 0x7fff && ((hx & 0x7fffffff) | lx) != 0)
+ {
+ /* NaN, return it. */
+ *signgamp = 0;
+ return x;
+ }
+ if ((es & 0x8000) != 0 && x < 0xffffffff && __rintl (x) == x)
+ {
+ /* Return value for integer x < 0 is NaN with invalid exception. */
+ *signgamp = 0;
+ return (x - x) / (x - x);
+ }
+
+ /* XXX FIXME. */
+ return __ieee754_expl (__ieee754_lgammal_r (x, signgamp));
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_hypotl.c b/libc/sysdeps/ieee754/ldbl-96/e_hypotl.c
new file mode 100644
index 000000000..1a40c556d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_hypotl.c
@@ -0,0 +1,133 @@
+/* e_hypotl.c -- long double version of e_hypot.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* __ieee754_hypotl(x,y)
+ *
+ * Method :
+ * If (assume round-to-nearest) z=x*x+y*y
+ * has error less than sqrt(2)/2 ulp, than
+ * sqrt(z) has error less than 1 ulp (exercise).
+ *
+ * So, compute sqrt(x*x+y*y) with some care as
+ * follows to get the error below 1 ulp:
+ *
+ * Assume x>y>0;
+ * (if possible, set rounding to round-to-nearest)
+ * 1. if x > 2y use
+ * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
+ * where x1 = x with lower 32 bits cleared, x2 = x-x1; else
+ * 2. if x <= 2y use
+ * t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
+ * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
+ * y1= y with lower 32 bits chopped, y2 = y-y1.
+ *
+ * NOTE: scaling may be necessary if some argument is too
+ * large or too tiny
+ *
+ * Special cases:
+ * hypot(x,y) is INF if x or y is +INF or -INF; else
+ * hypot(x,y) is NAN if x or y is NAN.
+ *
+ * Accuracy:
+ * hypot(x,y) returns sqrt(x^2+y^2) with error less
+ * than 1 ulps (units in the last place)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __ieee754_hypotl(long double x, long double y)
+#else
+ long double __ieee754_hypotl(x,y)
+ long double x, y;
+#endif
+{
+ long double a,b,t1,t2,y1,y2,w;
+ u_int32_t j,k,ea,eb;
+
+ GET_LDOUBLE_EXP(ea,x);
+ ea &= 0x7fff;
+ GET_LDOUBLE_EXP(eb,y);
+ eb &= 0x7fff;
+ if(eb > ea) {a=y;b=x;j=ea; ea=eb;eb=j;} else {a=x;b=y;}
+ SET_LDOUBLE_EXP(a,ea); /* a <- |a| */
+ SET_LDOUBLE_EXP(b,eb); /* b <- |b| */
+ if((ea-eb)>0x46) {return a+b;} /* x/y > 2**70 */
+ k=0;
+ if(ea > 0x5f3f) { /* a>2**8000 */
+ if(ea == 0x7fff) { /* Inf or NaN */
+ u_int32_t exp,high,low;
+ w = a+b; /* for sNaN */
+ GET_LDOUBLE_WORDS(exp,high,low,a);
+ if(((high&0x7fffffff)|low)==0) w = a;
+ GET_LDOUBLE_WORDS(exp,high,low,b);
+ if(((eb^0x7fff)|(high&0x7fffffff)|low)==0) w = b;
+ return w;
+ }
+ /* scale a and b by 2**-9600 */
+ ea -= 0x2580; eb -= 0x2580; k += 9600;
+ SET_LDOUBLE_EXP(a,ea);
+ SET_LDOUBLE_EXP(b,eb);
+ }
+ if(eb < 0x20bf) { /* b < 2**-8000 */
+ if(eb == 0) { /* subnormal b or 0 */
+ u_int32_t exp,high,low;
+ GET_LDOUBLE_WORDS(exp,high,low,b);
+ if((high|low)==0) return a;
+ SET_LDOUBLE_WORDS(t1, 0x7ffd, 0, 0); /* t1=2^16382 */
+ b *= t1;
+ a *= t1;
+ k -= 16382;
+ } else { /* scale a and b by 2^9600 */
+ ea += 0x2580; /* a *= 2^9600 */
+ eb += 0x2580; /* b *= 2^9600 */
+ k -= 9600;
+ SET_LDOUBLE_EXP(a,ea);
+ SET_LDOUBLE_EXP(b,eb);
+ }
+ }
+ /* medium size a and b */
+ w = a-b;
+ if (w>b) {
+ u_int32_t high;
+ GET_LDOUBLE_MSW(high,a);
+ SET_LDOUBLE_WORDS(t1,ea,high,0);
+ t2 = a-t1;
+ w = __ieee754_sqrtl(t1*t1-(b*(-b)-t2*(a+t1)));
+ } else {
+ u_int32_t high;
+ GET_LDOUBLE_MSW(high,b);
+ a = a+a;
+ SET_LDOUBLE_WORDS(y1,eb,high,0);
+ y2 = b - y1;
+ GET_LDOUBLE_MSW(high,a);
+ SET_LDOUBLE_WORDS(t1,ea+1,high,0);
+ t2 = a - t1;
+ w = __ieee754_sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b)));
+ }
+ if(k!=0) {
+ u_int32_t exp;
+ t1 = 1.0;
+ GET_LDOUBLE_EXP(exp,t1);
+ SET_LDOUBLE_EXP(t1,exp+k);
+ return t1*w;
+ } else return w;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_j0l.c b/libc/sysdeps/ieee754/ldbl-96/e_j0l.c
new file mode 100644
index 000000000..12c906bcb
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_j0l.c
@@ -0,0 +1,644 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __ieee754_j0(x), __ieee754_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 - ...
+ * 2. Reduce x to |x| since j0(x)=j0(-x), and
+ * for x in (0,2)
+ * j0(x) = 1 - z/4 + z^2*R0/S0, where z = x*x;
+ * for x in (2,inf)
+ * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0))
+ * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
+ * as follow:
+ * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+ * = 1/sqrt(2) * (cos(x) + sin(x))
+ * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * (To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.)
+ *
+ * 3 Special cases
+ * j0(nan)= nan
+ * j0(0) = 1
+ * j0(inf) = 0
+ *
+ * Method -- y0(x):
+ * 1. For x<2.
+ * Since
+ * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...)
+ * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function.
+ * We use the following function to approximate y0,
+ * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2
+ *
+ * Note: For tiny x, U/V = u0 and j0(x)~1, hence
+ * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27)
+ * 2. For x>=2.
+ * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0))
+ * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
+ * by the method mentioned above.
+ * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static long double pzero (long double), qzero (long double);
+#else
+static long double pzero (), qzero ();
+#endif
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ huge = 1e4930L,
+ one = 1.0L,
+ invsqrtpi = 5.6418958354775628694807945156077258584405e-1L,
+ tpi = 6.3661977236758134307553505349005744813784e-1L,
+
+ /* J0(x) = 1 - x^2 / 4 + x^4 R0(x^2) / S0(x^2)
+ 0 <= x <= 2
+ peak relative error 1.41e-22 */
+ R[5] = {
+ 4.287176872744686992880841716723478740566E7L,
+ -6.652058897474241627570911531740907185772E5L,
+ 7.011848381719789863458364584613651091175E3L,
+ -3.168040850193372408702135490809516253693E1L,
+ 6.030778552661102450545394348845599300939E-2L,
+},
+
+ S[4] = {
+ 2.743793198556599677955266341699130654342E9L,
+ 3.364330079384816249840086842058954076201E7L,
+ 1.924119649412510777584684927494642526573E5L,
+ 6.239282256012734914211715620088714856494E2L,
+ /* 1.000000000000000000000000000000000000000E0L,*/
+};
+
+#ifdef __STDC__
+static const long double zero = 0.0;
+#else
+static long double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+long double
+__ieee754_j0l (long double x)
+#else
+long double
+__ieee754_j0l (x)
+ long double x;
+#endif
+{
+ long double z, s, c, ss, cc, r, u, v;
+ int32_t ix;
+ u_int32_t se, i0, i1;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+ if (ix >= 0x7fff)
+ return one / (x * x);
+ x = fabsl (x);
+ if (ix >= 0x4000) /* |x| >= 2.0 */
+ {
+ __sincosl (x, &s, &c);
+ ss = s - c;
+ cc = s + c;
+ if (ix < 0x7ffe)
+ { /* make sure x+x not overflow */
+ z = -__cosl (x + x);
+ if ((s * c) < zero)
+ cc = z / ss;
+ else
+ ss = z / cc;
+ }
+ /*
+ * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+ * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+ */
+ if (ix > 0x4080) /* 2^129 */
+ z = (invsqrtpi * cc) / __ieee754_sqrtl (x);
+ else
+ {
+ u = pzero (x);
+ v = qzero (x);
+ z = invsqrtpi * (u * cc - v * ss) / __ieee754_sqrtl (x);
+ }
+ return z;
+ }
+ if (ix < 0x3fef) /* |x| < 2**-16 */
+ {
+ if (huge + x > one)
+ { /* raise inexact if x != 0 */
+ if (ix < 0x3fde) /* |x| < 2^-33 */
+ return one;
+ else
+ return one - 0.25 * x * x;
+ }
+ }
+ z = x * x;
+ r = z * (R[0] + z * (R[1] + z * (R[2] + z * (R[3] + z * R[4]))));
+ s = S[0] + z * (S[1] + z * (S[2] + z * (S[3] + z)));
+ if (ix < 0x3fff)
+ { /* |x| < 1.00 */
+ return (one - 0.25 * z + z * (r / s));
+ }
+ else
+ {
+ u = 0.5 * x;
+ return ((one + u) * (one - u) + z * (r / s));
+ }
+}
+
+
+/* y0(x) = 2/pi ln(x) J0(x) + U(x^2)/V(x^2)
+ 0 < x <= 2
+ peak relative error 1.7e-21 */
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+U[6] = {
+ -1.054912306975785573710813351985351350861E10L,
+ 2.520192609749295139432773849576523636127E10L,
+ -1.856426071075602001239955451329519093395E9L,
+ 4.079209129698891442683267466276785956784E7L,
+ -3.440684087134286610316661166492641011539E5L,
+ 1.005524356159130626192144663414848383774E3L,
+};
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+V[5] = {
+ 1.429337283720789610137291929228082613676E11L,
+ 2.492593075325119157558811370165695013002E9L,
+ 2.186077620785925464237324417623665138376E7L,
+ 1.238407896366385175196515057064384929222E5L,
+ 4.693924035211032457494368947123233101664E2L,
+ /* 1.000000000000000000000000000000000000000E0L */
+};
+
+#ifdef __STDC__
+long double
+__ieee754_y0l (long double x)
+#else
+long double
+__ieee754_y0l (x)
+ long double x;
+#endif
+{
+ long double z, s, c, ss, cc, u, v;
+ int32_t ix;
+ u_int32_t se, i0, i1;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+ /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */
+ if (se & 0x8000)
+ return zero / (zero * x);
+ if (ix >= 0x7fff)
+ return one / (x + x * x);
+ if ((i0 | i1) == 0)
+ return -HUGE_VALL + x; /* -inf and overflow exception. */
+ if (ix >= 0x4000)
+ { /* |x| >= 2.0 */
+
+ /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
+ * where x0 = x-pi/4
+ * Better formula:
+ * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+ * = 1/sqrt(2) * (sin(x) + cos(x))
+ * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.
+ */
+ __sincosl (x, &s, &c);
+ ss = s - c;
+ cc = s + c;
+ /*
+ * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+ * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+ */
+ if (ix < 0x7ffe)
+ { /* make sure x+x not overflow */
+ z = -__cosl (x + x);
+ if ((s * c) < zero)
+ cc = z / ss;
+ else
+ ss = z / cc;
+ }
+ if (ix > 0x4080) /* 1e39 */
+ z = (invsqrtpi * ss) / __ieee754_sqrtl (x);
+ else
+ {
+ u = pzero (x);
+ v = qzero (x);
+ z = invsqrtpi * (u * ss + v * cc) / __ieee754_sqrtl (x);
+ }
+ return z;
+ }
+ if (ix <= 0x3fde) /* x < 2^-33 */
+ {
+ z = -7.380429510868722527629822444004602747322E-2L
+ + tpi * __ieee754_logl (x);
+ return z;
+ }
+ z = x * x;
+ u = U[0] + z * (U[1] + z * (U[2] + z * (U[3] + z * (U[4] + z * U[5]))));
+ v = V[0] + z * (V[1] + z * (V[2] + z * (V[3] + z * (V[4] + z))));
+ return (u / v + tpi * (__ieee754_j0l (x) * __ieee754_logl (x)));
+}
+
+/* The asymptotic expansions of pzero is
+ * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x.
+ * For x >= 2, We approximate pzero by
+ * pzero(x) = 1 + s^2 R(s^2) / S(s^2)
+ */
+#ifdef __STDC__
+static const long double pR8[7] = {
+#else
+static long double pR8[7] = {
+#endif
+ /* 8 <= x <= inf
+ Peak relative error 4.62 */
+ -4.094398895124198016684337960227780260127E-9L,
+ -8.929643669432412640061946338524096893089E-7L,
+ -6.281267456906136703868258380673108109256E-5L,
+ -1.736902783620362966354814353559382399665E-3L,
+ -1.831506216290984960532230842266070146847E-2L,
+ -5.827178869301452892963280214772398135283E-2L,
+ -2.087563267939546435460286895807046616992E-2L,
+};
+#ifdef __STDC__
+static const long double pS8[6] = {
+#else
+static long double pS8[6] = {
+#endif
+ 5.823145095287749230197031108839653988393E-8L,
+ 1.279281986035060320477759999428992730280E-5L,
+ 9.132668954726626677174825517150228961304E-4L,
+ 2.606019379433060585351880541545146252534E-2L,
+ 2.956262215119520464228467583516287175244E-1L,
+ 1.149498145388256448535563278632697465675E0L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+#ifdef __STDC__
+static const long double pR5[7] = {
+#else
+static long double pR5[7] = {
+#endif
+ /* 4.54541015625 <= x <= 8
+ Peak relative error 6.51E-22 */
+ -2.041226787870240954326915847282179737987E-7L,
+ -2.255373879859413325570636768224534428156E-5L,
+ -7.957485746440825353553537274569102059990E-4L,
+ -1.093205102486816696940149222095559439425E-2L,
+ -5.657957849316537477657603125260701114646E-2L,
+ -8.641175552716402616180994954177818461588E-2L,
+ -1.354654710097134007437166939230619726157E-2L,
+};
+#ifdef __STDC__
+static const long double pS5[6] = {
+#else
+static long double pS5[6] = {
+#endif
+ 2.903078099681108697057258628212823545290E-6L,
+ 3.253948449946735405975737677123673867321E-4L,
+ 1.181269751723085006534147920481582279979E-2L,
+ 1.719212057790143888884745200257619469363E-1L,
+ 1.006306498779212467670654535430694221924E0L,
+ 2.069568808688074324555596301126375951502E0L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+#ifdef __STDC__
+static const long double pR3[7] = {
+#else
+static long double pR3[7] = {
+#endif
+ /* 2.85711669921875 <= x <= 4.54541015625
+ peak relative error 5.25e-21 */
+ -5.755732156848468345557663552240816066802E-6L,
+ -3.703675625855715998827966962258113034767E-4L,
+ -7.390893350679637611641350096842846433236E-3L,
+ -5.571922144490038765024591058478043873253E-2L,
+ -1.531290690378157869291151002472627396088E-1L,
+ -1.193350853469302941921647487062620011042E-1L,
+ -8.567802507331578894302991505331963782905E-3L,
+};
+#ifdef __STDC__
+static const long double pS3[6] = {
+#else
+static long double pS3[6] = {
+#endif
+ 8.185931139070086158103309281525036712419E-5L,
+ 5.398016943778891093520574483111255476787E-3L,
+ 1.130589193590489566669164765853409621081E-1L,
+ 9.358652328786413274673192987670237145071E-1L,
+ 3.091711512598349056276917907005098085273E0L,
+ 3.594602474737921977972586821673124231111E0L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+#ifdef __STDC__
+static const long double pR2[7] = {
+#else
+static long double pR2[7] = {
+#endif
+ /* 2 <= x <= 2.85711669921875
+ peak relative error 2.64e-21 */
+ -1.219525235804532014243621104365384992623E-4L,
+ -4.838597135805578919601088680065298763049E-3L,
+ -5.732223181683569266223306197751407418301E-2L,
+ -2.472947430526425064982909699406646503758E-1L,
+ -3.753373645974077960207588073975976327695E-1L,
+ -1.556241316844728872406672349347137975495E-1L,
+ -5.355423239526452209595316733635519506958E-3L,
+};
+#ifdef __STDC__
+static const long double pS2[6] = {
+#else
+static long double pS2[6] = {
+#endif
+ 1.734442793664291412489066256138894953823E-3L,
+ 7.158111826468626405416300895617986926008E-2L,
+ 9.153839713992138340197264669867993552641E-1L,
+ 4.539209519433011393525841956702487797582E0L,
+ 8.868932430625331650266067101752626253644E0L,
+ 6.067161890196324146320763844772857713502E0L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+#ifdef __STDC__
+static long double
+pzero (long double x)
+#else
+static long double
+pzero (x)
+ long double x;
+#endif
+{
+#ifdef __STDC__
+ const long double *p, *q;
+#else
+ long double *p, *q;
+#endif
+ long double z, r, s;
+ int32_t ix;
+ u_int32_t se, i0, i1;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+ if (ix >= 0x4002)
+ {
+ p = pR8;
+ q = pS8;
+ } /* x >= 8 */
+ else
+ {
+ i1 = (ix << 16) | (i0 >> 16);
+ if (i1 >= 0x40019174) /* x >= 4.54541015625 */
+ {
+ p = pR5;
+ q = pS5;
+ }
+ else if (i1 >= 0x4000b6db) /* x >= 2.85711669921875 */
+ {
+ p = pR3;
+ q = pS3;
+ }
+ else if (ix >= 0x4000) /* x better be >= 2 */
+ {
+ p = pR2;
+ q = pS2;
+ }
+ }
+ z = one / (x * x);
+ r =
+ p[0] + z * (p[1] +
+ z * (p[2] + z * (p[3] + z * (p[4] + z * (p[5] + z * p[6])))));
+ s =
+ q[0] + z * (q[1] + z * (q[2] + z * (q[3] + z * (q[4] + z * (q[5] + z)))));
+ return (one + z * r / s);
+}
+
+
+/* For x >= 8, the asymptotic expansions of qzero is
+ * -1/8 s + 75/1024 s^3 - ..., where s = 1/x.
+ * We approximate qzero by
+ * qzero(x) = s*(-.125 + R(s^2) / S(s^2))
+ */
+#ifdef __STDC__
+static const long double qR8[7] = {
+#else
+static long double qR8[7] = {
+#endif
+ /* 8 <= x <= inf
+ peak relative error 2.23e-21 */
+ 3.001267180483191397885272640777189348008E-10L,
+ 8.693186311430836495238494289942413810121E-8L,
+ 8.496875536711266039522937037850596580686E-6L,
+ 3.482702869915288984296602449543513958409E-4L,
+ 6.036378380706107692863811938221290851352E-3L,
+ 3.881970028476167836382607922840452192636E-2L,
+ 6.132191514516237371140841765561219149638E-2L,
+};
+#ifdef __STDC__
+static const long double qS8[7] = {
+#else
+static long double qS8[7] = {
+#endif
+ 4.097730123753051126914971174076227600212E-9L,
+ 1.199615869122646109596153392152131139306E-6L,
+ 1.196337580514532207793107149088168946451E-4L,
+ 5.099074440112045094341500497767181211104E-3L,
+ 9.577420799632372483249761659674764460583E-2L,
+ 7.385243015344292267061953461563695918646E-1L,
+ 1.917266424391428937962682301561699055943E0L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+#ifdef __STDC__
+static const long double qR5[7] = {
+#else
+static long double qR5[7] = {
+#endif
+ /* 4.54541015625 <= x <= 8
+ peak relative error 1.03e-21 */
+ 3.406256556438974327309660241748106352137E-8L,
+ 4.855492710552705436943630087976121021980E-6L,
+ 2.301011739663737780613356017352912281980E-4L,
+ 4.500470249273129953870234803596619899226E-3L,
+ 3.651376459725695502726921248173637054828E-2L,
+ 1.071578819056574524416060138514508609805E-1L,
+ 7.458950172851611673015774675225656063757E-2L,
+};
+#ifdef __STDC__
+static const long double qS5[7] = {
+#else
+static long double qS5[7] = {
+#endif
+ 4.650675622764245276538207123618745150785E-7L,
+ 6.773573292521412265840260065635377164455E-5L,
+ 3.340711249876192721980146877577806687714E-3L,
+ 7.036218046856839214741678375536970613501E-2L,
+ 6.569599559163872573895171876511377891143E-1L,
+ 2.557525022583599204591036677199171155186E0L,
+ 3.457237396120935674982927714210361269133E0L,
+ /* 1.000000000000000000000000000000000000000E0L,*/
+};
+
+#ifdef __STDC__
+static const long double qR3[7] = {
+#else
+static long double qR3[7] = {
+#endif
+ /* 2.85711669921875 <= x <= 4.54541015625
+ peak relative error 5.24e-21 */
+ 1.749459596550816915639829017724249805242E-6L,
+ 1.446252487543383683621692672078376929437E-4L,
+ 3.842084087362410664036704812125005761859E-3L,
+ 4.066369994699462547896426554180954233581E-2L,
+ 1.721093619117980251295234795188992722447E-1L,
+ 2.538595333972857367655146949093055405072E-1L,
+ 8.560591367256769038905328596020118877936E-2L,
+};
+#ifdef __STDC__
+static const long double qS3[7] = {
+#else
+static long double qS3[7] = {
+#endif
+ 2.388596091707517488372313710647510488042E-5L,
+ 2.048679968058758616370095132104333998147E-3L,
+ 5.824663198201417760864458765259945181513E-2L,
+ 6.953906394693328750931617748038994763958E-1L,
+ 3.638186936390881159685868764832961092476E0L,
+ 7.900169524705757837298990558459547842607E0L,
+ 5.992718532451026507552820701127504582907E0L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+#ifdef __STDC__
+static const long double qR2[7] = {
+#else
+static long double qR2[7] = {
+#endif
+ /* 2 <= x <= 2.85711669921875
+ peak relative error 1.58e-21 */
+ 6.306524405520048545426928892276696949540E-5L,
+ 3.209606155709930950935893996591576624054E-3L,
+ 5.027828775702022732912321378866797059604E-2L,
+ 3.012705561838718956481911477587757845163E-1L,
+ 6.960544893905752937420734884995688523815E-1L,
+ 5.431871999743531634887107835372232030655E-1L,
+ 9.447736151202905471899259026430157211949E-2L,
+};
+#ifdef __STDC__
+static const long double qS2[7] = {
+#else
+static long double qS2[7] = {
+#endif
+ 8.610579901936193494609755345106129102676E-4L,
+ 4.649054352710496997203474853066665869047E-2L,
+ 8.104282924459837407218042945106320388339E-1L,
+ 5.807730930825886427048038146088828206852E0L,
+ 1.795310145936848873627710102199881642939E1L,
+ 2.281313316875375733663657188888110605044E1L,
+ 1.011242067883822301487154844458322200143E1L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+#ifdef __STDC__
+static long double
+qzero (long double x)
+#else
+static long double
+qzero (x)
+ long double x;
+#endif
+{
+#ifdef __STDC__
+ const long double *p, *q;
+#else
+ long double *p, *q;
+#endif
+ long double s, r, z;
+ int32_t ix;
+ u_int32_t se, i0, i1;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+ if (ix >= 0x4002) /* x >= 8 */
+ {
+ p = qR8;
+ q = qS8;
+ }
+ else
+ {
+ i1 = (ix << 16) | (i0 >> 16);
+ if (i1 >= 0x40019174) /* x >= 4.54541015625 */
+ {
+ p = qR5;
+ q = qS5;
+ }
+ else if (i1 >= 0x4000b6db) /* x >= 2.85711669921875 */
+ {
+ p = qR3;
+ q = qS3;
+ }
+ else if (ix >= 0x4000) /* x better be >= 2 */
+ {
+ p = qR2;
+ q = qS2;
+ }
+ }
+ z = one / (x * x);
+ r =
+ p[0] + z * (p[1] +
+ z * (p[2] + z * (p[3] + z * (p[4] + z * (p[5] + z * p[6])))));
+ s =
+ q[0] + z * (q[1] +
+ z * (q[2] +
+ z * (q[3] + z * (q[4] + z * (q[5] + z * (q[6] + z))))));
+ return (-.125 + z * r / s) / x;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_j1l.c b/libc/sysdeps/ieee754/ldbl-96/e_j1l.c
new file mode 100644
index 000000000..62a8ce0cb
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_j1l.c
@@ -0,0 +1,651 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __ieee754_j1(x), __ieee754_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 - ...
+ * 2. Reduce x to |x| since j1(x)=-j1(-x), and
+ * for x in (0,2)
+ * j1(x) = x/2 + x*z*R0/S0, where z = x*x;
+ * for x in (2,inf)
+ * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1))
+ * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
+ * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
+ * as follow:
+ * cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = -1/sqrt(2) * (sin(x) + cos(x))
+ * (To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.)
+ *
+ * 3 Special cases
+ * j1(nan)= nan
+ * j1(0) = 0
+ * j1(inf) = 0
+ *
+ * Method -- y1(x):
+ * 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN
+ * 2. For x<2.
+ * Since
+ * y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...)
+ * therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function.
+ * We use the following function to approximate y1,
+ * y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2
+ * Note: For tiny x, 1/x dominate y1 and hence
+ * y1(tiny) = -2/pi/tiny
+ * 3. For x>=2.
+ * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
+ * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
+ * by method mentioned above.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static long double pone (long double), qone (long double);
+#else
+static long double pone (), qone ();
+#endif
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ huge = 1e4930L,
+ one = 1.0L,
+ invsqrtpi = 5.6418958354775628694807945156077258584405e-1L,
+ tpi = 6.3661977236758134307553505349005744813784e-1L,
+
+ /* J1(x) = .5 x + x x^2 R(x^2) / S(x^2)
+ 0 <= x <= 2
+ Peak relative error 4.5e-21 */
+R[5] = {
+ -9.647406112428107954753770469290757756814E7L,
+ 2.686288565865230690166454005558203955564E6L,
+ -3.689682683905671185891885948692283776081E4L,
+ 2.195031194229176602851429567792676658146E2L,
+ -5.124499848728030297902028238597308971319E-1L,
+},
+
+ S[4] =
+{
+ 1.543584977988497274437410333029029035089E9L,
+ 2.133542369567701244002565983150952549520E7L,
+ 1.394077011298227346483732156167414670520E5L,
+ 5.252401789085732428842871556112108446506E2L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+#ifdef __STDC__
+static const long double zero = 0.0;
+#else
+static long double zero = 0.0;
+#endif
+
+
+#ifdef __STDC__
+long double
+__ieee754_j1l (long double x)
+#else
+long double
+__ieee754_j1l (x)
+ long double x;
+#endif
+{
+ long double z, c, r, s, ss, cc, u, v, y;
+ int32_t ix;
+ u_int32_t se, i0, i1;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+ if (ix >= 0x7fff)
+ return one / x;
+ y = fabsl (x);
+ if (ix >= 0x4000)
+ { /* |x| >= 2.0 */
+ __sincosl (y, &s, &c);
+ ss = -s - c;
+ cc = s - c;
+ if (ix < 0x7ffe)
+ { /* make sure y+y not overflow */
+ z = __cosl (y + y);
+ if ((s * c) > zero)
+ cc = z / ss;
+ else
+ ss = z / cc;
+ }
+ /*
+ * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
+ * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
+ */
+ if (ix > 0x4080)
+ z = (invsqrtpi * cc) / __ieee754_sqrtl (y);
+ else
+ {
+ u = pone (y);
+ v = qone (y);
+ z = invsqrtpi * (u * cc - v * ss) / __ieee754_sqrtl (y);
+ }
+ if (se & 0x8000)
+ return -z;
+ else
+ return z;
+ }
+ if (ix < 0x3fde) /* |x| < 2^-33 */
+ {
+ if (huge + x > one)
+ return 0.5 * x; /* inexact if x!=0 necessary */
+ }
+ z = x * x;
+ r = z * (R[0] + z * (R[1]+ z * (R[2] + z * (R[3] + z * R[4]))));
+ s = S[0] + z * (S[1] + z * (S[2] + z * (S[3] + z)));
+ r *= x;
+ return (x * 0.5 + r / s);
+}
+
+
+/* Y1(x) = 2/pi * (log(x) * j1(x) - 1/x) + x R(x^2)
+ 0 <= x <= 2
+ Peak relative error 2.3e-23 */
+#ifdef __STDC__
+static const long double U0[6] = {
+#else
+static long double U0[6] = {
+#endif
+ -5.908077186259914699178903164682444848615E10L,
+ 1.546219327181478013495975514375773435962E10L,
+ -6.438303331169223128870035584107053228235E8L,
+ 9.708540045657182600665968063824819371216E6L,
+ -6.138043997084355564619377183564196265471E4L,
+ 1.418503228220927321096904291501161800215E2L,
+};
+#ifdef __STDC__
+static const long double V0[5] = {
+#else
+static long double V0[5] = {
+#endif
+ 3.013447341682896694781964795373783679861E11L,
+ 4.669546565705981649470005402243136124523E9L,
+ 3.595056091631351184676890179233695857260E7L,
+ 1.761554028569108722903944659933744317994E5L,
+ 5.668480419646516568875555062047234534863E2L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+
+#ifdef __STDC__
+long double
+__ieee754_y1l (long double x)
+#else
+long double
+__ieee754_y1l (x)
+ long double x;
+#endif
+{
+ long double z, s, c, ss, cc, u, v;
+ int32_t ix;
+ u_int32_t se, i0, i1;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+ /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
+ if (se & 0x8000)
+ return zero / (zero * x);
+ if (ix >= 0x7fff)
+ return one / (x + x * x);
+ if ((i0 | i1) == 0)
+ return -HUGE_VALL + x; /* -inf and overflow exception. */
+ if (ix >= 0x4000)
+ { /* |x| >= 2.0 */
+ __sincosl (x, &s, &c);
+ ss = -s - c;
+ cc = s - c;
+ if (ix < 0x7fe00000)
+ { /* make sure x+x not overflow */
+ z = __cosl (x + x);
+ if ((s * c) > zero)
+ cc = z / ss;
+ else
+ ss = z / cc;
+ }
+ /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0))
+ * where x0 = x-3pi/4
+ * Better formula:
+ * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+ * = 1/sqrt(2) * (sin(x) - cos(x))
+ * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ * = -1/sqrt(2) * (cos(x) + sin(x))
+ * To avoid cancellation, use
+ * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * to compute the worse one.
+ */
+ if (ix > 0x4080)
+ z = (invsqrtpi * ss) / __ieee754_sqrtl (x);
+ else
+ {
+ u = pone (x);
+ v = qone (x);
+ z = invsqrtpi * (u * ss + v * cc) / __ieee754_sqrtl (x);
+ }
+ return z;
+ }
+ if (ix <= 0x3fbe)
+ { /* x < 2**-65 */
+ return (-tpi / x);
+ }
+ z = x * x;
+ u = U0[0] + z * (U0[1] + z * (U0[2] + z * (U0[3] + z * (U0[4] + z * U0[5]))));
+ v = V0[0] + z * (V0[1] + z * (V0[2] + z * (V0[3] + z * (V0[4] + z))));
+ return (x * (u / v) +
+ tpi * (__ieee754_j1l (x) * __ieee754_logl (x) - one / x));
+}
+
+
+/* For x >= 8, the asymptotic expansions of pone is
+ * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x.
+ * We approximate pone by
+ * pone(x) = 1 + (R/S)
+ */
+
+/* J1(x) cosX + Y1(x) sinX = sqrt( 2/(pi x)) P1(x)
+ P1(x) = 1 + z^2 R(z^2), z=1/x
+ 8 <= x <= inf (0 <= z <= 0.125)
+ Peak relative error 5.2e-22 */
+
+#ifdef __STDC__
+static const long double pr8[7] = {
+#else
+static long double pr8[7] = {
+#endif
+ 8.402048819032978959298664869941375143163E-9L,
+ 1.813743245316438056192649247507255996036E-6L,
+ 1.260704554112906152344932388588243836276E-4L,
+ 3.439294839869103014614229832700986965110E-3L,
+ 3.576910849712074184504430254290179501209E-2L,
+ 1.131111483254318243139953003461511308672E-1L,
+ 4.480715825681029711521286449131671880953E-2L,
+};
+#ifdef __STDC__
+static const long double ps8[6] = {
+#else
+static long double ps8[6] = {
+#endif
+ 7.169748325574809484893888315707824924354E-8L,
+ 1.556549720596672576431813934184403614817E-5L,
+ 1.094540125521337139209062035774174565882E-3L,
+ 3.060978962596642798560894375281428805840E-2L,
+ 3.374146536087205506032643098619414507024E-1L,
+ 1.253830208588979001991901126393231302559E0L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+/* J1(x) cosX + Y1(x) sinX = sqrt( 2/(pi x)) P1(x)
+ P1(x) = 1 + z^2 R(z^2), z=1/x
+ 4.54541015625 <= x <= 8
+ Peak relative error 7.7e-22 */
+#ifdef __STDC__
+static const long double pr5[7] = {
+#else
+static long double pr5[7] = {
+#endif
+ 4.318486887948814529950980396300969247900E-7L,
+ 4.715341880798817230333360497524173929315E-5L,
+ 1.642719430496086618401091544113220340094E-3L,
+ 2.228688005300803935928733750456396149104E-2L,
+ 1.142773760804150921573259605730018327162E-1L,
+ 1.755576530055079253910829652698703791957E-1L,
+ 3.218803858282095929559165965353784980613E-2L,
+};
+#ifdef __STDC__
+static const long double ps5[6] = {
+#else
+static long double ps5[6] = {
+#endif
+ 3.685108812227721334719884358034713967557E-6L,
+ 4.069102509511177498808856515005792027639E-4L,
+ 1.449728676496155025507893322405597039816E-2L,
+ 2.058869213229520086582695850441194363103E-1L,
+ 1.164890985918737148968424972072751066553E0L,
+ 2.274776933457009446573027260373361586841E0L,
+ /* 1.000000000000000000000000000000000000000E0L,*/
+};
+
+/* J1(x) cosX + Y1(x) sinX = sqrt( 2/(pi x)) P1(x)
+ P1(x) = 1 + z^2 R(z^2), z=1/x
+ 2.85711669921875 <= x <= 4.54541015625
+ Peak relative error 6.5e-21 */
+#ifdef __STDC__
+static const long double pr3[7] = {
+#else
+static long double pr3[7] = {
+#endif
+ 1.265251153957366716825382654273326407972E-5L,
+ 8.031057269201324914127680782288352574567E-4L,
+ 1.581648121115028333661412169396282881035E-2L,
+ 1.179534658087796321928362981518645033967E-1L,
+ 3.227936912780465219246440724502790727866E-1L,
+ 2.559223765418386621748404398017602935764E-1L,
+ 2.277136933287817911091370397134882441046E-2L,
+};
+#ifdef __STDC__
+static const long double ps3[6] = {
+#else
+static long double ps3[6] = {
+#endif
+ 1.079681071833391818661952793568345057548E-4L,
+ 6.986017817100477138417481463810841529026E-3L,
+ 1.429403701146942509913198539100230540503E-1L,
+ 1.148392024337075609460312658938700765074E0L,
+ 3.643663015091248720208251490291968840882E0L,
+ 3.990702269032018282145100741746633960737E0L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+/* J1(x) cosX + Y1(x) sinX = sqrt( 2/(pi x)) P1(x)
+ P1(x) = 1 + z^2 R(z^2), z=1/x
+ 2 <= x <= 2.85711669921875
+ Peak relative error 3.5e-21 */
+#ifdef __STDC__
+static const long double pr2[7] = {
+#else
+static long double pr2[7] = {
+#endif
+ 2.795623248568412225239401141338714516445E-4L,
+ 1.092578168441856711925254839815430061135E-2L,
+ 1.278024620468953761154963591853679640560E-1L,
+ 5.469680473691500673112904286228351988583E-1L,
+ 8.313769490922351300461498619045639016059E-1L,
+ 3.544176317308370086415403567097130611468E-1L,
+ 1.604142674802373041247957048801599740644E-2L,
+};
+#ifdef __STDC__
+static const long double ps2[6] = {
+#else
+static long double ps2[6] = {
+#endif
+ 2.385605161555183386205027000675875235980E-3L,
+ 9.616778294482695283928617708206967248579E-2L,
+ 1.195215570959693572089824415393951258510E0L,
+ 5.718412857897054829999458736064922974662E0L,
+ 1.065626298505499086386584642761602177568E1L,
+ 6.809140730053382188468983548092322151791E0L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+
+#ifdef __STDC__
+static long double
+pone (long double x)
+#else
+static long double
+pone (x)
+ long double x;
+#endif
+{
+#ifdef __STDC__
+ const long double *p, *q;
+#else
+ long double *p, *q;
+#endif
+ long double z, r, s;
+ int32_t ix;
+ u_int32_t se, i0, i1;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+ if (ix >= 0x4002) /* x >= 8 */
+ {
+ p = pr8;
+ q = ps8;
+ }
+ else
+ {
+ i1 = (ix << 16) | (i0 >> 16);
+ if (i1 >= 0x40019174) /* x >= 4.54541015625 */
+ {
+ p = pr5;
+ q = ps5;
+ }
+ else if (i1 >= 0x4000b6db) /* x >= 2.85711669921875 */
+ {
+ p = pr3;
+ q = ps3;
+ }
+ else if (ix >= 0x4000) /* x better be >= 2 */
+ {
+ p = pr2;
+ q = ps2;
+ }
+ }
+ z = one / (x * x);
+ r = p[0] + z * (p[1] +
+ z * (p[2] + z * (p[3] + z * (p[4] + z * (p[5] + z * p[6])))));
+ s = q[0] + z * (q[1] + z * (q[2] + z * (q[3] + z * (q[4] + z * (q[5] + z)))));
+ return one + z * r / s;
+}
+
+
+/* For x >= 8, the asymptotic expansions of qone is
+ * 3/8 s - 105/1024 s^3 - ..., where s = 1/x.
+ * We approximate pone by
+ * qone(x) = s*(0.375 + (R/S))
+ */
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = z(.375 + z^2 R(z^2)), z=1/x
+ 8 <= x <= inf
+ Peak relative error 8.3e-22 */
+
+#ifdef __STDC__
+static const long double qr8[7] = {
+#else
+static long double qr8[7] = {
+#endif
+ -5.691925079044209246015366919809404457380E-10L,
+ -1.632587664706999307871963065396218379137E-7L,
+ -1.577424682764651970003637263552027114600E-5L,
+ -6.377627959241053914770158336842725291713E-4L,
+ -1.087408516779972735197277149494929568768E-2L,
+ -6.854943629378084419631926076882330494217E-2L,
+ -1.055448290469180032312893377152490183203E-1L,
+};
+#ifdef __STDC__
+static const long double qs8[7] = {
+#else
+static long double qs8[7] = {
+#endif
+ 5.550982172325019811119223916998393907513E-9L,
+ 1.607188366646736068460131091130644192244E-6L,
+ 1.580792530091386496626494138334505893599E-4L,
+ 6.617859900815747303032860443855006056595E-3L,
+ 1.212840547336984859952597488863037659161E-1L,
+ 9.017885953937234900458186716154005541075E-1L,
+ 2.201114489712243262000939120146436167178E0L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = z(.375 + z^2 R(z^2)), z=1/x
+ 4.54541015625 <= x <= 8
+ Peak relative error 4.1e-22 */
+#ifdef __STDC__
+static const long double qr5[7] = {
+#else
+static long double qr5[7] = {
+#endif
+ -6.719134139179190546324213696633564965983E-8L,
+ -9.467871458774950479909851595678622044140E-6L,
+ -4.429341875348286176950914275723051452838E-4L,
+ -8.539898021757342531563866270278505014487E-3L,
+ -6.818691805848737010422337101409276287170E-2L,
+ -1.964432669771684034858848142418228214855E-1L,
+ -1.333896496989238600119596538299938520726E-1L,
+};
+#ifdef __STDC__
+static const long double qs5[7] = {
+#else
+static long double qs5[7] = {
+#endif
+ 6.552755584474634766937589285426911075101E-7L,
+ 9.410814032118155978663509073200494000589E-5L,
+ 4.561677087286518359461609153655021253238E-3L,
+ 9.397742096177905170800336715661091535805E-2L,
+ 8.518538116671013902180962914473967738771E-1L,
+ 3.177729183645800174212539541058292579009E0L,
+ 4.006745668510308096259753538973038902990E0L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = z(.375 + z^2 R(z^2)), z=1/x
+ 2.85711669921875 <= x <= 4.54541015625
+ Peak relative error 2.2e-21 */
+#ifdef __STDC__
+static const long double qr3[7] = {
+#else
+static long double qr3[7] = {
+#endif
+ -3.618746299358445926506719188614570588404E-6L,
+ -2.951146018465419674063882650970344502798E-4L,
+ -7.728518171262562194043409753656506795258E-3L,
+ -8.058010968753999435006488158237984014883E-2L,
+ -3.356232856677966691703904770937143483472E-1L,
+ -4.858192581793118040782557808823460276452E-1L,
+ -1.592399251246473643510898335746432479373E-1L,
+};
+#ifdef __STDC__
+static const long double qs3[7] = {
+#else
+static long double qs3[7] = {
+#endif
+ 3.529139957987837084554591421329876744262E-5L,
+ 2.973602667215766676998703687065066180115E-3L,
+ 8.273534546240864308494062287908662592100E-2L,
+ 9.613359842126507198241321110649974032726E-1L,
+ 4.853923697093974370118387947065402707519E0L,
+ 1.002671608961669247462020977417828796933E1L,
+ 7.028927383922483728931327850683151410267E0L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+/* Y1(x)cosX - J1(x)sinX = sqrt( 2/(pi x)) Q1(x),
+ Q1(x) = z(.375 + z^2 R(z^2)), z=1/x
+ 2 <= x <= 2.85711669921875
+ Peak relative error 6.9e-22 */
+#ifdef __STDC__
+static const long double qr2[7] = {
+#else
+static long double qr2[7] = {
+#endif
+ -1.372751603025230017220666013816502528318E-4L,
+ -6.879190253347766576229143006767218972834E-3L,
+ -1.061253572090925414598304855316280077828E-1L,
+ -6.262164224345471241219408329354943337214E-1L,
+ -1.423149636514768476376254324731437473915E0L,
+ -1.087955310491078933531734062917489870754E0L,
+ -1.826821119773182847861406108689273719137E-1L,
+};
+#ifdef __STDC__
+static const long double qs2[7] = {
+#else
+static long double qs2[7] = {
+#endif
+ 1.338768933634451601814048220627185324007E-3L,
+ 7.071099998918497559736318523932241901810E-2L,
+ 1.200511429784048632105295629933382142221E0L,
+ 8.327301713640367079030141077172031825276E0L,
+ 2.468479301872299311658145549931764426840E1L,
+ 2.961179686096262083509383820557051621644E1L,
+ 1.201402313144305153005639494661767354977E1L,
+ /* 1.000000000000000000000000000000000000000E0L, */
+};
+
+
+#ifdef __STDC__
+static long double
+qone (long double x)
+#else
+static long double
+qone (x)
+ long double x;
+#endif
+{
+#ifdef __STDC__
+ const long double *p, *q;
+#else
+ long double *p, *q;
+#endif
+ static long double s, r, z;
+ int32_t ix;
+ u_int32_t se, i0, i1;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+ if (ix >= 0x4002) /* x >= 8 */
+ {
+ p = qr8;
+ q = qs8;
+ }
+ else
+ {
+ i1 = (ix << 16) | (i0 >> 16);
+ if (i1 >= 0x40019174) /* x >= 4.54541015625 */
+ {
+ p = qr5;
+ q = qs5;
+ }
+ else if (i1 >= 0x4000b6db) /* x >= 2.85711669921875 */
+ {
+ p = qr3;
+ q = qs3;
+ }
+ else if (ix >= 0x4000) /* x better be >= 2 */
+ {
+ p = qr2;
+ q = qs2;
+ }
+ }
+ z = one / (x * x);
+ r =
+ p[0] + z * (p[1] +
+ z * (p[2] + z * (p[3] + z * (p[4] + z * (p[5] + z * p[6])))));
+ s =
+ q[0] + z * (q[1] +
+ z * (q[2] +
+ z * (q[3] + z * (q[4] + z * (q[5] + z * (q[6] + z))))));
+ return (.375 + z * r / s) / x;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_jnl.c b/libc/sysdeps/ieee754/ldbl-96/e_jnl.c
new file mode 100644
index 000000000..3d715d36a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_jnl.c
@@ -0,0 +1,386 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* Modifications for long double are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ * __ieee754_jn(n, x), __ieee754_yn(n, 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 overflow 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"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ invsqrtpi = 5.64189583547756286948079e-1L, two = 2.0e0L, one = 1.0e0L;
+
+#ifdef __STDC__
+static const long double zero = 0.0L;
+#else
+static long double zero = 0.0L;
+#endif
+
+#ifdef __STDC__
+long double
+__ieee754_jnl (int n, long double x)
+#else
+long double
+__ieee754_jnl (n, x)
+ int n;
+ long double x;
+#endif
+{
+ u_int32_t se, i0, i1;
+ int32_t i, ix, sgn;
+ long double a, b, temp, di;
+ long double z, w;
+
+ /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
+ * Thus, J(-n,x) = J(n,-x)
+ */
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+
+ /* if J(n,NaN) is NaN */
+ if ((ix == 0x7fff) && ((i0 & 0x7fffffff) != 0))
+ return x + x;
+ if (n < 0)
+ {
+ n = -n;
+ x = -x;
+ se ^= 0x8000;
+ }
+ if (n == 0)
+ return (__ieee754_j0l (x));
+ if (n == 1)
+ return (__ieee754_j1l (x));
+ sgn = (n & 1) & (se >> 15); /* even n -- 0, odd n -- sign(x) */
+ x = fabsl (x);
+ if ((ix | i0 | i1) == 0 || ix >= 0x7fff) /* if x is 0 or inf */
+ b = zero;
+ else if ((long double) n <= x)
+ {
+ /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
+ if (ix >= 0x412D)
+ { /* x > 2**302 */
+
+ /* ??? This might be a futile gesture.
+ If x exceeds X_TLOSS anyway, the wrapper function
+ will set the result to zero. */
+
+ /* (x >> n**2)
+ * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Let s=sin(x), c=cos(x),
+ * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+ *
+ * n sin(xn)*sqt2 cos(xn)*sqt2
+ * ----------------------------------
+ * 0 s-c c+s
+ * 1 -s-c -c+s
+ * 2 -s+c -c-s
+ * 3 s+c c-s
+ */
+ long double s;
+ long double c;
+ __sincosl (x, &s, &c);
+ switch (n & 3)
+ {
+ case 0:
+ temp = c + s;
+ break;
+ case 1:
+ temp = -c + s;
+ break;
+ case 2:
+ temp = -c - s;
+ break;
+ case 3:
+ temp = c - s;
+ break;
+ }
+ b = invsqrtpi * temp / __ieee754_sqrtl (x);
+ }
+ else
+ {
+ a = __ieee754_j0l (x);
+ b = __ieee754_j1l (x);
+ for (i = 1; i < n; i++)
+ {
+ temp = b;
+ b = b * ((long double) (i + i) / x) - a; /* avoid underflow */
+ a = temp;
+ }
+ }
+ }
+ else
+ {
+ if (ix < 0x3fde)
+ { /* x < 2**-33 */
+ /* x is tiny, return the first Taylor expansion of J(n,x)
+ * J(n,x) = 1/n!*(x/2)^n - ...
+ */
+ if (n >= 400) /* underflow, result < 10^-4952 */
+ b = zero;
+ else
+ {
+ temp = x * 0.5;
+ b = temp;
+ for (a = one, i = 2; i <= n; i++)
+ {
+ a *= (long double) i; /* a = n! */
+ b *= temp; /* b = (x/2)^n */
+ }
+ b = b / a;
+ }
+ }
+ else
+ {
+ /* use backward recurrence */
+ /* x x^2 x^2
+ * J(n,x)/J(n-1,x) = ---- ------ ------ .....
+ * 2n - 2(n+1) - 2(n+2)
+ *
+ * 1 1 1
+ * (for large x) = ---- ------ ------ .....
+ * 2n 2(n+1) 2(n+2)
+ * -- - ------ - ------ -
+ * x x x
+ *
+ * Let w = 2n/x and h=2/x, then the above quotient
+ * is equal to the continued fraction:
+ * 1
+ * = -----------------------
+ * 1
+ * w - -----------------
+ * 1
+ * w+h - ---------
+ * w+2h - ...
+ *
+ * To determine how many terms needed, let
+ * Q(0) = w, Q(1) = w(w+h) - 1,
+ * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
+ * When Q(k) > 1e4 good for single
+ * When Q(k) > 1e9 good for double
+ * When Q(k) > 1e17 good for quadruple
+ */
+ /* determine k */
+ long double t, v;
+ long double q0, q1, h, tmp;
+ int32_t k, m;
+ w = (n + n) / (long double) x;
+ h = 2.0L / (long double) x;
+ q0 = w;
+ z = w + h;
+ q1 = w * z - 1.0L;
+ k = 1;
+ while (q1 < 1.0e11L)
+ {
+ k += 1;
+ z += h;
+ tmp = z * q1 - q0;
+ q0 = q1;
+ q1 = tmp;
+ }
+ m = n + n;
+ for (t = zero, i = 2 * (n + k); i >= m; i -= 2)
+ t = one / (i / x - t);
+ a = t;
+ b = one;
+ /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
+ * Hence, if n*(log(2n/x)) > ...
+ * single 8.8722839355e+01
+ * double 7.09782712893383973096e+02
+ * long double 1.1356523406294143949491931077970765006170e+04
+ * then recurrent value may overflow and the result is
+ * likely underflow to zero
+ */
+ tmp = n;
+ v = two / x;
+ tmp = tmp * __ieee754_logl (fabsl (v * tmp));
+
+ if (tmp < 1.1356523406294143949491931077970765006170e+04L)
+ {
+ for (i = n - 1, di = (long double) (i + i); i > 0; i--)
+ {
+ temp = b;
+ b *= di;
+ b = b / x - a;
+ a = temp;
+ di -= two;
+ }
+ }
+ else
+ {
+ for (i = n - 1, di = (long double) (i + i); i > 0; i--)
+ {
+ temp = b;
+ b *= di;
+ b = b / x - a;
+ a = temp;
+ di -= two;
+ /* scale b to avoid spurious overflow */
+ if (b > 1e100L)
+ {
+ a /= b;
+ t /= b;
+ b = one;
+ }
+ }
+ }
+ b = (t * __ieee754_j0l (x) / b);
+ }
+ }
+ if (sgn == 1)
+ return -b;
+ else
+ return b;
+}
+
+#ifdef __STDC__
+long double
+__ieee754_ynl (int n, long double x)
+#else
+long double
+__ieee754_ynl (n, x)
+ int n;
+ long double x;
+#endif
+{
+ u_int32_t se, i0, i1;
+ int32_t i, ix;
+ int32_t sign;
+ long double a, b, temp;
+
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+ /* if Y(n,NaN) is NaN */
+ if ((ix == 0x7fff) && ((i0 & 0x7fffffff) != 0))
+ return x + x;
+ if ((ix | i0 | i1) == 0)
+ return -HUGE_VALL + x; /* -inf and overflow exception. */
+ if (se & 0x8000)
+ return zero / (zero * x);
+ sign = 1;
+ if (n < 0)
+ {
+ n = -n;
+ sign = 1 - ((n & 1) << 1);
+ }
+ if (n == 0)
+ return (__ieee754_y0l (x));
+ if (n == 1)
+ return (sign * __ieee754_y1l (x));
+ if (ix == 0x7fff)
+ return zero;
+ if (ix >= 0x412D)
+ { /* x > 2**302 */
+
+ /* ??? See comment above on the possible futility of this. */
+
+ /* (x >> n**2)
+ * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+ * Let s=sin(x), c=cos(x),
+ * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+ *
+ * n sin(xn)*sqt2 cos(xn)*sqt2
+ * ----------------------------------
+ * 0 s-c c+s
+ * 1 -s-c -c+s
+ * 2 -s+c -c-s
+ * 3 s+c c-s
+ */
+ long double s;
+ long double c;
+ __sincosl (x, &s, &c);
+ switch (n & 3)
+ {
+ case 0:
+ temp = s - c;
+ break;
+ case 1:
+ temp = -s - c;
+ break;
+ case 2:
+ temp = -s + c;
+ break;
+ case 3:
+ temp = s + c;
+ break;
+ }
+ b = invsqrtpi * temp / __ieee754_sqrtl (x);
+ }
+ else
+ {
+ a = __ieee754_y0l (x);
+ b = __ieee754_y1l (x);
+ /* quit if b is -inf */
+ GET_LDOUBLE_WORDS (se, i0, i1, b);
+ for (i = 1; i < n && se != 0xffff; i++)
+ {
+ temp = b;
+ b = ((long double) (i + i) / x) * b - a;
+ GET_LDOUBLE_WORDS (se, i0, i1, b);
+ a = temp;
+ }
+ }
+ if (sign > 0)
+ return b;
+ else
+ return -b;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_lgammal_r.c b/libc/sysdeps/ieee754/ldbl-96/e_lgammal_r.c
new file mode 100644
index 000000000..fecbee9b2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_lgammal_r.c
@@ -0,0 +1,446 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* __ieee754_lgammal_r(x, signgamp)
+ * Reentrant version of the logarithm of the Gamma function
+ * with user provide pointer for the sign of Gamma(x).
+ *
+ * Method:
+ * 1. Argument Reduction for 0 < x <= 8
+ * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may
+ * reduce x to a number in [1.5,2.5] by
+ * lgamma(1+s) = log(s) + lgamma(s)
+ * for example,
+ * lgamma(7.3) = log(6.3) + lgamma(6.3)
+ * = log(6.3*5.3) + lgamma(5.3)
+ * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
+ * 2. Polynomial approximation of lgamma around its
+ * minimun ymin=1.461632144968362245 to maintain monotonicity.
+ * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
+ * Let z = x-ymin;
+ * lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
+ * 2. Rational approximation in the primary interval [2,3]
+ * We use the following approximation:
+ * s = x-2.0;
+ * lgamma(x) = 0.5*s + s*P(s)/Q(s)
+ * Our algorithms are based on the following observation
+ *
+ * zeta(2)-1 2 zeta(3)-1 3
+ * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ...
+ * 2 3
+ *
+ * where Euler = 0.5771... is the Euler constant, which is very
+ * close to 0.5.
+ *
+ * 3. For x>=8, we have
+ * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....
+ * (better formula:
+ * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)
+ * Let z = 1/x, then we approximation
+ * f(z) = lgamma(x) - (x-0.5)(log(x)-1)
+ * by
+ * 3 5 11
+ * w = w0 + w1*z + w2*z + w3*z + ... + w6*z
+ *
+ * 4. For negative x, since (G is gamma function)
+ * -x*G(-x)*G(x) = pi/sin(pi*x),
+ * we have
+ * G(x) = pi/(sin(pi*x)*(-x)*G(-x))
+ * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0
+ * Hence, for x<0, signgam = sign(sin(pi*x)) and
+ * lgamma(x) = log(|Gamma(x)|)
+ * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);
+ * Note: one should avoid compute pi*(-x) directly in the
+ * computation of sin(pi*(-x)).
+ *
+ * 5. Special Cases
+ * lgamma(2+s) ~ s*(1-Euler) for tiny s
+ * lgamma(1)=lgamma(2)=0
+ * lgamma(x) ~ -log(x) for tiny x
+ * lgamma(0) = lgamma(inf) = inf
+ * lgamma(-integer) = +-inf
+ *
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+ half = 0.5L,
+ one = 1.0L,
+ pi = 3.14159265358979323846264L,
+ two63 = 9.223372036854775808e18L,
+
+ /* lgam(1+x) = 0.5 x + x a(x)/b(x)
+ -0.268402099609375 <= x <= 0
+ peak relative error 6.6e-22 */
+ a0 = -6.343246574721079391729402781192128239938E2L,
+ a1 = 1.856560238672465796768677717168371401378E3L,
+ a2 = 2.404733102163746263689288466865843408429E3L,
+ a3 = 8.804188795790383497379532868917517596322E2L,
+ a4 = 1.135361354097447729740103745999661157426E2L,
+ a5 = 3.766956539107615557608581581190400021285E0L,
+
+ b0 = 8.214973713960928795704317259806842490498E3L,
+ b1 = 1.026343508841367384879065363925870888012E4L,
+ b2 = 4.553337477045763320522762343132210919277E3L,
+ b3 = 8.506975785032585797446253359230031874803E2L,
+ b4 = 6.042447899703295436820744186992189445813E1L,
+ /* b5 = 1.000000000000000000000000000000000000000E0 */
+
+
+ tc = 1.4616321449683623412626595423257213284682E0L,
+ tf = -1.2148629053584961146050602565082954242826E-1,/* double precision */
+/* tt = (tail of tf), i.e. tf + tt has extended precision. */
+ tt = 3.3649914684731379602768989080467587736363E-18L,
+ /* lgam ( 1.4616321449683623412626595423257213284682E0 ) =
+-1.2148629053584960809551455717769158215135617312999903886372437313313530E-1 */
+
+ /* lgam (x + tc) = tf + tt + x g(x)/h(x)
+ - 0.230003726999612341262659542325721328468 <= x
+ <= 0.2699962730003876587373404576742786715318
+ peak relative error 2.1e-21 */
+ g0 = 3.645529916721223331888305293534095553827E-18L,
+ g1 = 5.126654642791082497002594216163574795690E3L,
+ g2 = 8.828603575854624811911631336122070070327E3L,
+ g3 = 5.464186426932117031234820886525701595203E3L,
+ g4 = 1.455427403530884193180776558102868592293E3L,
+ g5 = 1.541735456969245924860307497029155838446E2L,
+ g6 = 4.335498275274822298341872707453445815118E0L,
+
+ h0 = 1.059584930106085509696730443974495979641E4L,
+ h1 = 2.147921653490043010629481226937850618860E4L,
+ h2 = 1.643014770044524804175197151958100656728E4L,
+ h3 = 5.869021995186925517228323497501767586078E3L,
+ h4 = 9.764244777714344488787381271643502742293E2L,
+ h5 = 6.442485441570592541741092969581997002349E1L,
+ /* h6 = 1.000000000000000000000000000000000000000E0 */
+
+
+ /* lgam (x+1) = -0.5 x + x u(x)/v(x)
+ -0.100006103515625 <= x <= 0.231639862060546875
+ peak relative error 1.3e-21 */
+ u0 = -8.886217500092090678492242071879342025627E1L,
+ u1 = 6.840109978129177639438792958320783599310E2L,
+ u2 = 2.042626104514127267855588786511809932433E3L,
+ u3 = 1.911723903442667422201651063009856064275E3L,
+ u4 = 7.447065275665887457628865263491667767695E2L,
+ u5 = 1.132256494121790736268471016493103952637E2L,
+ u6 = 4.484398885516614191003094714505960972894E0L,
+
+ v0 = 1.150830924194461522996462401210374632929E3L,
+ v1 = 3.399692260848747447377972081399737098610E3L,
+ v2 = 3.786631705644460255229513563657226008015E3L,
+ v3 = 1.966450123004478374557778781564114347876E3L,
+ v4 = 4.741359068914069299837355438370682773122E2L,
+ v5 = 4.508989649747184050907206782117647852364E1L,
+ /* v6 = 1.000000000000000000000000000000000000000E0 */
+
+
+ /* lgam (x+2) = .5 x + x s(x)/r(x)
+ 0 <= x <= 1
+ peak relative error 7.2e-22 */
+ s0 = 1.454726263410661942989109455292824853344E6L,
+ s1 = -3.901428390086348447890408306153378922752E6L,
+ s2 = -6.573568698209374121847873064292963089438E6L,
+ s3 = -3.319055881485044417245964508099095984643E6L,
+ s4 = -7.094891568758439227560184618114707107977E5L,
+ s5 = -6.263426646464505837422314539808112478303E4L,
+ s6 = -1.684926520999477529949915657519454051529E3L,
+
+ r0 = -1.883978160734303518163008696712983134698E7L,
+ r1 = -2.815206082812062064902202753264922306830E7L,
+ r2 = -1.600245495251915899081846093343626358398E7L,
+ r3 = -4.310526301881305003489257052083370058799E6L,
+ r4 = -5.563807682263923279438235987186184968542E5L,
+ r5 = -3.027734654434169996032905158145259713083E4L,
+ r6 = -4.501995652861105629217250715790764371267E2L,
+ /* r6 = 1.000000000000000000000000000000000000000E0 */
+
+
+/* lgam(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x w(1/x^2)
+ x >= 8
+ Peak relative error 1.51e-21
+ w0 = LS2PI - 0.5 */
+ w0 = 4.189385332046727417803e-1L,
+ w1 = 8.333333333333331447505E-2L,
+ w2 = -2.777777777750349603440E-3L,
+ w3 = 7.936507795855070755671E-4L,
+ w4 = -5.952345851765688514613E-4L,
+ w5 = 8.412723297322498080632E-4L,
+ w6 = -1.880801938119376907179E-3L,
+ w7 = 4.885026142432270781165E-3L;
+
+#ifdef __STDC__
+static const long double zero = 0.0L;
+#else
+static long double zero = 0.0L;
+#endif
+
+#ifdef __STDC__
+static long double
+sin_pi (long double x)
+#else
+static long double
+sin_pi (x)
+ long double x;
+#endif
+{
+ long double y, z;
+ int n, ix;
+ u_int32_t se, i0, i1;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+ ix = (ix << 16) | (i0 >> 16);
+ if (ix < 0x3ffd8000) /* 0.25 */
+ return __sinl (pi * x);
+ y = -x; /* x is assume negative */
+
+ /*
+ * argument reduction, make sure inexact flag not raised if input
+ * is an integer
+ */
+ z = __floorl (y);
+ if (z != y)
+ { /* inexact anyway */
+ y *= 0.5;
+ y = 2.0*(y - __floorl(y)); /* y = |x| mod 2.0 */
+ n = (int) (y*4.0);
+ }
+ else
+ {
+ if (ix >= 0x403f8000) /* 2^64 */
+ {
+ y = zero; n = 0; /* y must be even */
+ }
+ else
+ {
+ if (ix < 0x403e8000) /* 2^63 */
+ z = y + two63; /* exact */
+ GET_LDOUBLE_WORDS (se, i0, i1, z);
+ n = i1 & 1;
+ y = n;
+ n <<= 2;
+ }
+ }
+
+ switch (n)
+ {
+ case 0:
+ y = __sinl (pi * y);
+ break;
+ case 1:
+ case 2:
+ y = __cosl (pi * (half - y));
+ break;
+ case 3:
+ case 4:
+ y = __sinl (pi * (one - y));
+ break;
+ case 5:
+ case 6:
+ y = -__cosl (pi * (y - 1.5));
+ break;
+ default:
+ y = __sinl (pi * (y - 2.0));
+ break;
+ }
+ return -y;
+}
+
+
+#ifdef __STDC__
+long double
+__ieee754_lgammal_r (long double x, int *signgamp)
+#else
+long double
+__ieee754_lgammal_r (x, signgamp)
+ long double x;
+ int *signgamp;
+#endif
+{
+ long double t, y, z, nadj, p, p1, p2, q, r, w;
+ int i, ix;
+ u_int32_t se, i0, i1;
+
+ *signgamp = 1;
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+
+ if ((ix | i0 | i1) == 0)
+ return one / fabsl (x);
+
+ ix = (ix << 16) | (i0 >> 16);
+
+ /* purge off +-inf, NaN, +-0, and negative arguments */
+ if (ix >= 0x7fff0000)
+ return x * x;
+
+ if (ix < 0x3fc08000) /* 2^-63 */
+ { /* |x|<2**-63, return -log(|x|) */
+ if (se & 0x8000)
+ {
+ *signgamp = -1;
+ return -__ieee754_logl (-x);
+ }
+ else
+ return -__ieee754_logl (x);
+ }
+ if (se & 0x8000)
+ {
+ t = sin_pi (x);
+ if (t == zero)
+ return one / fabsl (t); /* -integer */
+ nadj = __ieee754_logl (pi / fabsl (t * x));
+ if (t < zero)
+ *signgamp = -1;
+ x = -x;
+ }
+
+ /* purge off 1 and 2 */
+ if ((((ix - 0x3fff8000) | i0 | i1) == 0)
+ || (((ix - 0x40008000) | i0 | i1) == 0))
+ r = 0;
+ else if (ix < 0x40008000) /* 2.0 */
+ {
+ /* x < 2.0 */
+ if (ix <= 0x3ffee666) /* 8.99993896484375e-1 */
+ {
+ /* lgamma(x) = lgamma(x+1) - log(x) */
+ r = -__ieee754_logl (x);
+ if (ix >= 0x3ffebb4a) /* 7.31597900390625e-1 */
+ {
+ y = x - one;
+ i = 0;
+ }
+ else if (ix >= 0x3ffced33)/* 2.31639862060546875e-1 */
+ {
+ y = x - (tc - one);
+ i = 1;
+ }
+ else
+ {
+ /* x < 0.23 */
+ y = x;
+ i = 2;
+ }
+ }
+ else
+ {
+ r = zero;
+ if (ix >= 0x3fffdda6) /* 1.73162841796875 */
+ {
+ /* [1.7316,2] */
+ y = x - 2.0;
+ i = 0;
+ }
+ else if (ix >= 0x3fff9da6)/* 1.23162841796875 */
+ {
+ /* [1.23,1.73] */
+ y = x - tc;
+ i = 1;
+ }
+ else
+ {
+ /* [0.9, 1.23] */
+ y = x - one;
+ i = 2;
+ }
+ }
+ switch (i)
+ {
+ case 0:
+ p1 = a0 + y * (a1 + y * (a2 + y * (a3 + y * (a4 + y * a5))));
+ p2 = b0 + y * (b1 + y * (b2 + y * (b3 + y * (b4 + y))));
+ r += half * y + y * p1/p2;
+ break;
+ case 1:
+ p1 = g0 + y * (g1 + y * (g2 + y * (g3 + y * (g4 + y * (g5 + y * g6)))));
+ p2 = h0 + y * (h1 + y * (h2 + y * (h3 + y * (h4 + y * (h5 + y)))));
+ p = tt + y * p1/p2;
+ r += (tf + p);
+ break;
+ case 2:
+ p1 = y * (u0 + y * (u1 + y * (u2 + y * (u3 + y * (u4 + y * (u5 + y * u6))))));
+ p2 = v0 + y * (v1 + y * (v2 + y * (v3 + y * (v4 + y * (v5 + y)))));
+ r += (-half * y + p1 / p2);
+ }
+ }
+ else if (ix < 0x40028000) /* 8.0 */
+ {
+ /* x < 8.0 */
+ i = (int) x;
+ t = zero;
+ y = x - (double) i;
+ p = y *
+ (s0 + y * (s1 + y * (s2 + y * (s3 + y * (s4 + y * (s5 + y * s6))))));
+ q = r0 + y * (r1 + y * (r2 + y * (r3 + y * (r4 + y * (r5 + y * (r6 + y))))));
+ r = half * y + p / q;
+ z = one; /* lgamma(1+s) = log(s) + lgamma(s) */
+ switch (i)
+ {
+ case 7:
+ z *= (y + 6.0); /* FALLTHRU */
+ case 6:
+ z *= (y + 5.0); /* FALLTHRU */
+ case 5:
+ z *= (y + 4.0); /* FALLTHRU */
+ case 4:
+ z *= (y + 3.0); /* FALLTHRU */
+ case 3:
+ z *= (y + 2.0); /* FALLTHRU */
+ r += __ieee754_logl (z);
+ break;
+ }
+ }
+ else if (ix < 0x40418000) /* 2^66 */
+ {
+ /* 8.0 <= x < 2**66 */
+ t = __ieee754_logl (x);
+ z = one / x;
+ y = z * z;
+ w = w0 + z * (w1
+ + y * (w2 + y * (w3 + y * (w4 + y * (w5 + y * (w6 + y * w7))))));
+ r = (x - half) * (t - one) + w;
+ }
+ else
+ /* 2**66 <= x <= inf */
+ r = x * (__ieee754_logl (x) - one);
+ if (se & 0x8000)
+ r = nadj - r;
+ return r;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_remainderl.c b/libc/sysdeps/ieee754/ldbl-96/e_remainderl.c
new file mode 100644
index 000000000..e721a6e8c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_remainderl.c
@@ -0,0 +1,83 @@
+/* e_remainderl.c -- long double version of e_remainder.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* __ieee754_remainderl(x,p)
+ * Return :
+ * returns x REM p = x - [x/p]*p as if in infinite
+ * precise arithmetic, where [x/p] is the (infinite bit)
+ * integer nearest x/p (in half way case choose the even one).
+ * Method :
+ * Based on fmod() return x-[x/p]chopped*p exactlp.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double zero = 0.0;
+#else
+static long double zero = 0.0;
+#endif
+
+
+#ifdef __STDC__
+ long double __ieee754_remainderl(long double x, long double p)
+#else
+ long double __ieee754_remainderl(x,p)
+ long double x,p;
+#endif
+{
+ u_int32_t sx,sex,sep,x0,x1,p0,p1;
+ long double p_half;
+
+ GET_LDOUBLE_WORDS(sex,x0,x1,x);
+ GET_LDOUBLE_WORDS(sep,p0,p1,p);
+ sx = sex&0x8000;
+ sep &= 0x7fff;
+ sex &= 0x7fff;
+
+ /* purge off exception values */
+ if((sep|p0|p1)==0) return (x*p)/(x*p); /* p = 0 */
+ if((sex==0x7fff)|| /* x not finite */
+ ((sep==0x7fff)&& /* p is NaN */
+ ((p0|p1)!=0)))
+ return (x*p)/(x*p);
+
+
+ if (sep<0x7ffe) x = __ieee754_fmodl(x,p+p); /* now x < 2p */
+ if (((sex-sep)|(x0-p0)|(x1-p1))==0) return zero*x;
+ x = fabsl(x);
+ p = fabsl(p);
+ if (sep<0x0002) {
+ if(x+x>p) {
+ x-=p;
+ if(x+x>=p) x -= p;
+ }
+ } else {
+ p_half = 0.5*p;
+ if(x>p_half) {
+ x-=p;
+ if(x>=p_half) x -= p;
+ }
+ }
+ GET_LDOUBLE_EXP(sex,x);
+ SET_LDOUBLE_EXP(x,sex^sx);
+ return x;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/e_sinhl.c b/libc/sysdeps/ieee754/ldbl-96/e_sinhl.c
new file mode 100644
index 000000000..646d4fde8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/e_sinhl.c
@@ -0,0 +1,91 @@
+/* e_asinhl.c -- long double version of e_asinh.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* __ieee754_sinhl(x)
+ * Method :
+ * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+ * 1. Replace x by |x| (sinhl(-x) = -sinhl(x)).
+ * 2.
+ * E + E/(E+1)
+ * 0 <= x <= 25 : sinhl(x) := --------------, E=expm1l(x)
+ * 2
+ *
+ * 25 <= x <= lnovft : sinhl(x) := expl(x)/2
+ * lnovft <= x <= ln2ovft: sinhl(x) := expl(x/2)/2 * expl(x/2)
+ * ln2ovft < x : sinhl(x) := x*shuge (overflow)
+ *
+ * Special cases:
+ * sinhl(x) is |x| if x is +INF, -INF, or NaN.
+ * only sinhl(0)=0 is exact for finite x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0, shuge = 1.0e4931L;
+#else
+static long double one = 1.0, shuge = 1.0e4931L;
+#endif
+
+#ifdef __STDC__
+ long double __ieee754_sinhl(long double x)
+#else
+ long double __ieee754_sinhl(x)
+ long double x;
+#endif
+{
+ long double t,w,h;
+ u_int32_t jx,ix,i0,i1;
+
+ /* Words of |x|. */
+ GET_LDOUBLE_WORDS(jx,i0,i1,x);
+ ix = jx&0x7fff;
+
+ /* x is INF or NaN */
+ if(ix==0x7fff) return x+x;
+
+ h = 0.5;
+ if (jx & 0x8000) h = -h;
+ /* |x| in [0,25], return sign(x)*0.5*(E+E/(E+1))) */
+ if (ix < 0x4003 || (ix == 0x4003 && i0 <= 0xc8000000)) { /* |x|<25 */
+ if (ix<0x3fdf) /* |x|<2**-32 */
+ if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
+ t = __expm1l(fabsl(x));
+ if(ix<0x3fff) return h*(2.0*t-t*t/(t+one));
+ return h*(t+t/(t+one));
+ }
+
+ /* |x| in [25, log(maxdouble)] return 0.5*exp(|x|) */
+ if (ix < 0x400c || (ix == 0x400c && i0 < 0xb17217f7))
+ return h*__ieee754_expl(fabsl(x));
+
+ /* |x| in [log(maxdouble), overflowthreshold] */
+ if (ix<0x400c || (ix == 0x400c && (i0 < 0xb174ddc0
+ || (i0 == 0xb174ddc0
+ && i1 <= 0x31aec0ea)))) {
+ w = __ieee754_expl(0.5*fabsl(x));
+ t = h*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthreshold, sinhl(x) overflow */
+ return x*shuge;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/ldbl2mpn.c b/libc/sysdeps/ieee754/ldbl-96/ldbl2mpn.c
new file mode 100644
index 000000000..3c3a2325c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/ldbl2mpn.c
@@ -0,0 +1,95 @@
+/* Copyright (C) 1995,1996,1997,1998,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include <ieee754.h>
+#include <float.h>
+#include <math.h>
+#include <stdlib.h>
+
+/* Convert a `long double' in IEEE854 standard double-precision format to a
+ multi-precision integer representing the significand scaled up by its
+ number of bits (64 for long double) and an integral power of two
+ (MPN frexpl). */
+
+mp_size_t
+__mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
+ int *expt, int *is_neg,
+ long double value)
+{
+ union ieee854_long_double u;
+ u.d = value;
+
+ *is_neg = u.ieee.negative;
+ *expt = (int) u.ieee.exponent - IEEE854_LONG_DOUBLE_BIAS;
+
+#if BITS_PER_MP_LIMB == 32
+ res_ptr[0] = u.ieee.mantissa1; /* Low-order 32 bits of fraction. */
+ res_ptr[1] = u.ieee.mantissa0; /* High-order 32 bits. */
+ #define N 2
+#elif BITS_PER_MP_LIMB == 64
+ /* Hopefully the compiler will combine the two bitfield extracts
+ and this composition into just the original quadword extract. */
+ res_ptr[0] = ((mp_limb_t) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
+ #define N 1
+#else
+ #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+
+ if (u.ieee.exponent == 0)
+ {
+ /* A biased exponent of zero is a special case.
+ Either it is a zero or it is a denormal number. */
+ if (res_ptr[0] == 0 && res_ptr[N - 1] == 0) /* Assumes N<=2. */
+ /* It's zero. */
+ *expt = 0;
+ else
+ {
+ /* It is a denormal number, meaning it has no implicit leading
+ one bit, and its exponent is in fact the format minimum. */
+ int cnt;
+
+ if (res_ptr[N - 1] != 0)
+ {
+ count_leading_zeros (cnt, res_ptr[N - 1]);
+ if (cnt != 0)
+ {
+#if N == 2
+ res_ptr[N - 1] = res_ptr[N - 1] << cnt
+ | (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt));
+ res_ptr[0] <<= cnt;
+#else
+ res_ptr[N - 1] <<= cnt;
+#endif
+ }
+ *expt = LDBL_MIN_EXP - 1 - cnt;
+ }
+ else
+ {
+ count_leading_zeros (cnt, res_ptr[0]);
+ res_ptr[N - 1] = res_ptr[0] << cnt;
+ res_ptr[0] = 0;
+ *expt = LDBL_MIN_EXP - 1 - BITS_PER_MP_LIMB - cnt;
+ }
+ }
+ }
+
+ return N;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/math_ldbl.h b/libc/sysdeps/ieee754/ldbl-96/math_ldbl.h
new file mode 100644
index 000000000..cca30657c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/math_ldbl.h
@@ -0,0 +1,98 @@
+#ifndef _MATH_PRIVATE_H_
+#error "Never use <math_ldbl.h> directly; include <math_private.h> instead."
+#endif
+
+/* A union which permits us to convert between a long double and
+ three 32 bit ints. */
+
+#if __FLOAT_WORD_ORDER == BIG_ENDIAN
+
+typedef union
+{
+ long double value;
+ struct
+ {
+ int sign_exponent:16;
+ unsigned int empty:16;
+ u_int32_t msw;
+ u_int32_t lsw;
+ } parts;
+} ieee_long_double_shape_type;
+
+#endif
+
+#if __FLOAT_WORD_ORDER == LITTLE_ENDIAN
+
+typedef union
+{
+ long double value;
+ struct
+ {
+ u_int32_t lsw;
+ u_int32_t msw;
+ int sign_exponent:16;
+ unsigned int empty:16;
+ } parts;
+} ieee_long_double_shape_type;
+
+#endif
+
+/* Get three 32 bit ints from a double. */
+
+#define GET_LDOUBLE_WORDS(exp,ix0,ix1,d) \
+do { \
+ ieee_long_double_shape_type ew_u; \
+ ew_u.value = (d); \
+ (exp) = ew_u.parts.sign_exponent; \
+ (ix0) = ew_u.parts.msw; \
+ (ix1) = ew_u.parts.lsw; \
+} while (0)
+
+/* Set a double from two 32 bit ints. */
+
+#define SET_LDOUBLE_WORDS(d,exp,ix0,ix1) \
+do { \
+ ieee_long_double_shape_type iw_u; \
+ iw_u.parts.sign_exponent = (exp); \
+ iw_u.parts.msw = (ix0); \
+ iw_u.parts.lsw = (ix1); \
+ (d) = iw_u.value; \
+} while (0)
+
+/* Get the more significant 32 bits of a long double mantissa. */
+
+#define GET_LDOUBLE_MSW(v,d) \
+do { \
+ ieee_long_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ (v) = sh_u.parts.msw; \
+} while (0)
+
+/* Set the more significant 32 bits of a long double mantissa from an int. */
+
+#define SET_LDOUBLE_MSW(d,v) \
+do { \
+ ieee_long_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ sh_u.parts.msw = (v); \
+ (d) = sh_u.value; \
+} while (0)
+
+/* Get int from the exponent of a long double. */
+
+#define GET_LDOUBLE_EXP(exp,d) \
+do { \
+ ieee_long_double_shape_type ge_u; \
+ ge_u.value = (d); \
+ (exp) = ge_u.parts.sign_exponent; \
+} while (0)
+
+/* Set exponent of a long double from an int. */
+
+#define SET_LDOUBLE_EXP(d,exp) \
+do { \
+ ieee_long_double_shape_type se_u; \
+ se_u.value = (d); \
+ se_u.parts.sign_exponent = (exp); \
+ (d) = se_u.value; \
+} while (0)
diff --git a/libc/sysdeps/ieee754/ldbl-96/mpn2ldbl.c b/libc/sysdeps/ieee754/ldbl-96/mpn2ldbl.c
new file mode 100644
index 000000000..cad4447d3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/mpn2ldbl.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1995,1996,1997,1998,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include <ieee754.h>
+#include <float.h>
+#include <math.h>
+
+/* Convert a multi-precision integer of the needed number of bits (64 for
+ long double) and an integral power of two to a `long double' in IEEE854
+ extended-precision format. */
+
+long double
+__mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign)
+{
+ union ieee854_long_double u;
+
+ u.ieee.negative = sign;
+ u.ieee.exponent = expt + IEEE854_LONG_DOUBLE_BIAS;
+#if BITS_PER_MP_LIMB == 32
+ u.ieee.mantissa1 = frac_ptr[0];
+ u.ieee.mantissa0 = frac_ptr[1];
+#elif BITS_PER_MP_LIMB == 64
+ u.ieee.mantissa1 = frac_ptr[0] & (((mp_limb_t) 1 << 32) - 1);
+ u.ieee.mantissa0 = frac_ptr[0] >> 32;
+#else
+ #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
+#endif
+
+ return u.d;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/printf_fphex.c b/libc/sysdeps/ieee754/ldbl-96/printf_fphex.c
new file mode 100644
index 000000000..ba9f4c296
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/printf_fphex.c
@@ -0,0 +1,93 @@
+/* Print floating point number in hexadecimal notation according to ISO C99.
+ Copyright (C) 1997, 1998, 1999, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef LONG_DOUBLE_DENORM_BIAS
+# define LONG_DOUBLE_DENORM_BIAS (IEEE854_LONG_DOUBLE_BIAS - 1)
+#endif
+
+#define PRINT_FPHEX_LONG_DOUBLE \
+do { \
+ /* The "strange" 80 bit format on ix86 and m68k has an explicit \
+ leading digit in the 64 bit mantissa. */ \
+ unsigned long long int num; \
+ \
+ assert (sizeof (long double) == 12); \
+ \
+ num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \
+ | fpnum.ldbl.ieee.mantissa1); \
+ \
+ zero_mantissa = num == 0; \
+ \
+ if (sizeof (unsigned long int) > 6) \
+ { \
+ numstr = _itoa_word (num, numbuf + sizeof numbuf, 16, \
+ info->spec == 'A'); \
+ wnumstr = _itowa_word (num, \
+ wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),\
+ 16, info->spec == 'A'); \
+ } \
+ else \
+ { \
+ numstr = _itoa (num, numbuf + sizeof numbuf, 16, info->spec == 'A');\
+ wnumstr = _itowa (num, \
+ wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t), \
+ 16, info->spec == 'A'); \
+ } \
+ \
+ /* Fill with zeroes. */ \
+ while (numstr > numbuf + (sizeof numbuf - 64 / 4)) \
+ { \
+ *--numstr = '0'; \
+ *--wnumstr = L'0'; \
+ } \
+ \
+ /* We use a full nibble for the leading digit. */ \
+ leading = *numstr++; \
+ \
+ /* We have 3 bits from the mantissa in the leading nibble. \
+ Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'. */ \
+ exponent = fpnum.ldbl.ieee.exponent; \
+ \
+ if (exponent == 0) \
+ { \
+ if (zero_mantissa) \
+ expnegative = 0; \
+ else \
+ { \
+ /* This is a denormalized number. */ \
+ expnegative = 1; \
+ /* This is a hook for the m68k long double format, where the \
+ exponent bias is the same for normalized and denormalized \
+ numbers. */ \
+ exponent = LONG_DOUBLE_DENORM_BIAS + 3; \
+ } \
+ } \
+ else if (exponent >= IEEE854_LONG_DOUBLE_BIAS + 3) \
+ { \
+ expnegative = 0; \
+ exponent -= IEEE854_LONG_DOUBLE_BIAS + 3; \
+ } \
+ else \
+ { \
+ expnegative = 1; \
+ exponent = -(exponent - (IEEE854_LONG_DOUBLE_BIAS + 3)); \
+ } \
+} while (0)
+
+#include <stdio-common/printf_fphex.c>
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_asinhl.c b/libc/sysdeps/ieee754/ldbl-96/s_asinhl.c
new file mode 100644
index 000000000..6eb434c44
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_asinhl.c
@@ -0,0 +1,70 @@
+/* s_asinhl.c -- long double version of s_asinh.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* asinhl(x)
+ * Method :
+ * Based on
+ * asinhl(x) = signl(x) * logl [ |x| + sqrtl(x*x+1) ]
+ * we have
+ * asinhl(x) := x if 1+x*x=1,
+ * := signl(x)*(logl(x)+ln2)) for large |x|, else
+ * := signl(x)*logl(2|x|+1/(|x|+sqrtl(x*x+1))) if|x|>2, else
+ * := signl(x)*log1pl(|x| + x^2/(1 + sqrtl(1+x^2)))
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+one = 1.000000000000000000000e+00L, /* 0x3FFF, 0x00000000, 0x00000000 */
+ln2 = 6.931471805599453094287e-01L, /* 0x3FFE, 0xB17217F7, 0xD1CF79AC */
+huge= 1.000000000000000000e+4900L;
+
+#ifdef __STDC__
+ long double __asinhl(long double x)
+#else
+ long double __asinhl(x)
+ long double x;
+#endif
+{
+ long double t,w;
+ int32_t hx,ix;
+ GET_LDOUBLE_EXP(hx,x);
+ ix = hx&0x7fff;
+ if(ix==0x7fff) return x+x; /* x is inf or NaN */
+ if(ix< 0x3fde) { /* |x|<2**-34 */
+ if(huge+x>one) return x; /* return x inexact except 0 */
+ }
+ if(ix>0x4020) { /* |x| > 2**34 */
+ w = __ieee754_logl(fabsl(x))+ln2;
+ } else if (ix>0x4000) { /* 2**34 > |x| > 2.0 */
+ t = fabsl(x);
+ w = __ieee754_logl(2.0*t+one/(__ieee754_sqrtl(x*x+one)+t));
+ } else { /* 2.0 > |x| > 2**-28 */
+ t = x*x;
+ w =__log1pl(fabsl(x)+t/(one+__ieee754_sqrtl(one+t)));
+ }
+ if(hx&0x8000) return -w; else return w;
+}
+weak_alias (__asinhl, asinhl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_cbrtl.c b/libc/sysdeps/ieee754/ldbl-96/s_cbrtl.c
new file mode 100644
index 000000000..0f8227a04
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_cbrtl.c
@@ -0,0 +1,71 @@
+/* Compute cubic root of double value.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
+ Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+
+
+#define CBRT2 1.2599210498948731648 /* 2^(1/3) */
+#define SQR_CBRT2 1.5874010519681994748 /* 2^(2/3) */
+
+/* We don't use long double values here since U need not be computed
+ with full precision. */
+static const double factor[5] =
+{
+ 1.0 / SQR_CBRT2,
+ 1.0 / CBRT2,
+ 1.0,
+ CBRT2,
+ SQR_CBRT2
+};
+
+static const long double third = 0.3333333333333333333333333L;
+
+long double
+__cbrtl (long double x)
+{
+ long double xm, u;
+ int xe;
+
+ /* Reduce X. XM now is an range 1.0 to 0.5. */
+ xm = __frexpl (fabs (x), &xe);
+
+ /* If X is not finite or is null return it (with raising exceptions
+ if necessary.
+ Note: *Our* version of `frexp' sets XE to zero if the argument is
+ Inf or NaN. This is not portable but faster. */
+ if (xe == 0 && fpclassify (x) <= FP_ZERO)
+ return x + x;
+
+ u = (((-1.34661104733595206551E-1 * xm
+ + 5.46646013663955245034E-1) * xm
+ - 9.54382247715094465250E-1) * xm
+ + 1.13999833547172932737E0) * xm
+ + 4.02389795645447521269E-1;
+
+ u *= factor[2 + xe % 3];
+ u = __ldexpl (x > 0.0 ? u : -u, xe / 3);
+
+ u -= (u - (x / (u * u))) * third;
+ u -= (u - (x / (u * u))) * third;
+ return u;
+}
+weak_alias (__cbrtl, cbrtl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_ceill.c b/libc/sysdeps/ieee754/ldbl-96/s_ceill.c
new file mode 100644
index 000000000..b99097f81
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_ceill.c
@@ -0,0 +1,94 @@
+/* s_ceill.c -- long double version of s_ceil.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * ceill(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to ceil(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double huge = 1.0e4930;
+#else
+static long double huge = 1.0e4930;
+#endif
+
+#ifdef __STDC__
+ long double __ceill(long double x)
+#else
+ long double __ceill(x)
+ long double x;
+#endif
+{
+ int32_t i1,j0;
+ u_int32_t i,j,se,i0,sx;
+ GET_LDOUBLE_WORDS(se,i0,i1,x);
+ sx = (se>>15)&1;
+ j0 = (se&0x7fff)-0x3fff;
+ if(j0<31) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(sx) {se=0x8000;i0=0;i1=0;}
+ else if((i0|i1)!=0) { se=0x3fff;i0=0;i1=0;}
+ }
+ } else {
+ i = (0x7fffffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(sx==0) {
+ if (j0>0 && (i0+(0x80000000>>j0))>i0)
+ i0+=0x80000000>>j0;
+ else
+ {
+ i = 0x7fffffff;
+ ++se;
+ }
+ }
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>62) {
+ if(j0==0x4000) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-31);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(sx==0) {
+ if(j0==31) i0+=1;
+ else {
+ j = i1 + (1<<(63-j0));
+ if(j<i1) i0+=1; /* got a carry */
+ i1 = j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ SET_LDOUBLE_WORDS(x,se,i0,i1);
+ return x;
+}
+weak_alias (__ceill, ceill)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_copysignl.c b/libc/sysdeps/ieee754/ldbl-96/s_copysignl.c
new file mode 100644
index 000000000..9976575b3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_copysignl.c
@@ -0,0 +1,43 @@
+/* s_copysignl.c -- long double version of s_copysign.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * copysignl(long double x, long double y)
+ * copysignl(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __copysignl(long double x, long double y)
+#else
+ long double __copysignl(x,y)
+ long double x,y;
+#endif
+{
+ u_int32_t es1,es2;
+ GET_LDOUBLE_EXP(es1,x);
+ GET_LDOUBLE_EXP(es2,y);
+ SET_LDOUBLE_EXP(x,(es1&0x7fff)|(es2&0x8000));
+ return x;
+}
+weak_alias (__copysignl, copysignl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_cosl.c b/libc/sysdeps/ieee754/ldbl-96/s_cosl.c
new file mode 100644
index 000000000..9765f7fd4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_cosl.c
@@ -0,0 +1,88 @@
+/* s_cosl.c -- long double version of s_cos.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* cosl(x)
+ * Return cosine function of x.
+ *
+ * kernel function:
+ * __kernel_sinl ... sine function on [-pi/4,pi/4]
+ * __kernel_cosl ... cosine function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2l ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __cosl(long double x)
+#else
+ long double __cosl(x)
+ long double x;
+#endif
+{
+ long double y[2],z=0.0;
+ int32_t n, se, i0, i1;
+
+ /* High word of x. */
+ GET_LDOUBLE_WORDS(se,i0,i1,x);
+
+ /* |x| ~< pi/4 */
+ se &= 0x7fff;
+ if(se < 0x3ffe || (se == 0x3ffe && i0 <= 0xc90fdaa2))
+ return __kernel_cosl(x,z);
+
+ /* cos(Inf or NaN) is NaN */
+ else if (se==0x7fff) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2l(x,y);
+ switch(n&3) {
+ case 0: return __kernel_cosl(y[0],y[1]);
+ case 1: return -__kernel_sinl(y[0],y[1],1);
+ case 2: return -__kernel_cosl(y[0],y[1]);
+ default:
+ return __kernel_sinl(y[0],y[1],1);
+ }
+ }
+}
+weak_alias (__cosl, cosl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_erfl.c b/libc/sysdeps/ieee754/ldbl-96/s_erfl.c
new file mode 100644
index 000000000..7406c3624
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_erfl.c
@@ -0,0 +1,454 @@
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* double erf(double x)
+ * double erfc(double x)
+ * x
+ * 2 |\
+ * erf(x) = --------- | exp(-t*t)dt
+ * sqrt(pi) \|
+ * 0
+ *
+ * erfc(x) = 1-erf(x)
+ * Note that
+ * erf(-x) = -erf(x)
+ * erfc(-x) = 2 - erfc(x)
+ *
+ * Method:
+ * 1. For |x| in [0, 0.84375]
+ * erf(x) = x + x*R(x^2)
+ * erfc(x) = 1 - erf(x) if x in [-.84375,0.25]
+ * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375]
+ * Remark. The formula is derived by noting
+ * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ * and that
+ * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ * is close to one. The interval is chosen because the fix
+ * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
+ * near 0.6174), and by some experiment, 0.84375 is chosen to
+ * guarantee the error is less than one ulp for erf.
+ *
+ * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and
+ * c = 0.84506291151 rounded to single (24 bits)
+ * erf(x) = sign(x) * (c + P1(s)/Q1(s))
+ * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0
+ * 1+(c+P1(s)/Q1(s)) if x < 0
+ * Remark: here we use the taylor series expansion at x=1.
+ * erf(1+s) = erf(1) + s*Poly(s)
+ * = 0.845.. + P1(s)/Q1(s)
+ * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ *
+ * 3. For x in [1.25,1/0.35(~2.857143)],
+ * erfc(x) = (1/x)*exp(-x*x-0.5625+R1(z)/S1(z))
+ * z=1/x^2
+ * erf(x) = 1 - erfc(x)
+ *
+ * 4. For x in [1/0.35,107]
+ * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
+ * = 2.0 - (1/x)*exp(-x*x-0.5625+R2(z)/S2(z))
+ * if -6.666<x<0
+ * = 2.0 - tiny (if x <= -6.666)
+ * z=1/x^2
+ * erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6.666, else
+ * erf(x) = sign(x)*(1.0 - tiny)
+ * Note1:
+ * To compute exp(-x*x-0.5625+R/S), let s be a single
+ * precision number and s := x; then
+ * -x*x = -s*s + (s-x)*(s+x)
+ * exp(-x*x-0.5626+R/S) =
+ * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
+ * Note2:
+ * Here 4 and 5 make use of the asymptotic series
+ * exp(-x*x)
+ * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
+ * x*sqrt(pi)
+ *
+ * 5. For inf > x >= 107
+ * erf(x) = sign(x) *(1 - tiny) (raise inexact)
+ * erfc(x) = tiny*tiny (raise underflow) if x > 0
+ * = 2 - tiny if x<0
+ *
+ * 7. Special case:
+ * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
+ * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
+ * erfc/erf(NaN) is NaN
+ */
+
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+tiny = 1e-4931L,
+ half = 0.5L,
+ one = 1.0L,
+ two = 2.0L,
+ /* c = (float)0.84506291151 */
+ erx = 0.845062911510467529296875L,
+/*
+ * Coefficients for approximation to erf on [0,0.84375]
+ */
+ /* 2/sqrt(pi) - 1 */
+ efx = 1.2837916709551257389615890312154517168810E-1L,
+ /* 8 * (2/sqrt(pi) - 1) */
+ efx8 = 1.0270333367641005911692712249723613735048E0L,
+
+ pp[6] = {
+ 1.122751350964552113068262337278335028553E6L,
+ -2.808533301997696164408397079650699163276E6L,
+ -3.314325479115357458197119660818768924100E5L,
+ -6.848684465326256109712135497895525446398E4L,
+ -2.657817695110739185591505062971929859314E3L,
+ -1.655310302737837556654146291646499062882E2L,
+ },
+
+ qq[6] = {
+ 8.745588372054466262548908189000448124232E6L,
+ 3.746038264792471129367533128637019611485E6L,
+ 7.066358783162407559861156173539693900031E5L,
+ 7.448928604824620999413120955705448117056E4L,
+ 4.511583986730994111992253980546131408924E3L,
+ 1.368902937933296323345610240009071254014E2L,
+ /* 1.000000000000000000000000000000000000000E0 */
+ },
+
+/*
+ * Coefficients for approximation to erf in [0.84375,1.25]
+ */
+/* erf(x+1) = 0.845062911510467529296875 + pa(x)/qa(x)
+ -0.15625 <= x <= +.25
+ Peak relative error 8.5e-22 */
+
+ pa[8] = {
+ -1.076952146179812072156734957705102256059E0L,
+ 1.884814957770385593365179835059971587220E2L,
+ -5.339153975012804282890066622962070115606E1L,
+ 4.435910679869176625928504532109635632618E1L,
+ 1.683219516032328828278557309642929135179E1L,
+ -2.360236618396952560064259585299045804293E0L,
+ 1.852230047861891953244413872297940938041E0L,
+ 9.394994446747752308256773044667843200719E-2L,
+ },
+
+ qa[7] = {
+ 4.559263722294508998149925774781887811255E2L,
+ 3.289248982200800575749795055149780689738E2L,
+ 2.846070965875643009598627918383314457912E2L,
+ 1.398715859064535039433275722017479994465E2L,
+ 6.060190733759793706299079050985358190726E1L,
+ 2.078695677795422351040502569964299664233E1L,
+ 4.641271134150895940966798357442234498546E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+ },
+
+/*
+ * Coefficients for approximation to erfc in [1.25,1/0.35]
+ */
+/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + ra(x^2)/sa(x^2))
+ 1/2.85711669921875 < 1/x < 1/1.25
+ Peak relative error 3.1e-21 */
+
+ ra[] = {
+ 1.363566591833846324191000679620738857234E-1L,
+ 1.018203167219873573808450274314658434507E1L,
+ 1.862359362334248675526472871224778045594E2L,
+ 1.411622588180721285284945138667933330348E3L,
+ 5.088538459741511988784440103218342840478E3L,
+ 8.928251553922176506858267311750789273656E3L,
+ 7.264436000148052545243018622742770549982E3L,
+ 2.387492459664548651671894725748959751119E3L,
+ 2.220916652813908085449221282808458466556E2L,
+ },
+
+ sa[] = {
+ -1.382234625202480685182526402169222331847E1L,
+ -3.315638835627950255832519203687435946482E2L,
+ -2.949124863912936259747237164260785326692E3L,
+ -1.246622099070875940506391433635999693661E4L,
+ -2.673079795851665428695842853070996219632E4L,
+ -2.880269786660559337358397106518918220991E4L,
+ -1.450600228493968044773354186390390823713E4L,
+ -2.874539731125893533960680525192064277816E3L,
+ -1.402241261419067750237395034116942296027E2L,
+ /* 1.000000000000000000000000000000000000000E0 */
+ },
+/*
+ * Coefficients for approximation to erfc in [1/.35,107]
+ */
+/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rb(x^2)/sb(x^2))
+ 1/6.6666259765625 < 1/x < 1/2.85711669921875
+ Peak relative error 4.2e-22 */
+ rb[] = {
+ -4.869587348270494309550558460786501252369E-5L,
+ -4.030199390527997378549161722412466959403E-3L,
+ -9.434425866377037610206443566288917589122E-2L,
+ -9.319032754357658601200655161585539404155E-1L,
+ -4.273788174307459947350256581445442062291E0L,
+ -8.842289940696150508373541814064198259278E0L,
+ -7.069215249419887403187988144752613025255E0L,
+ -1.401228723639514787920274427443330704764E0L,
+ },
+
+ sb[] = {
+ 4.936254964107175160157544545879293019085E-3L,
+ 1.583457624037795744377163924895349412015E-1L,
+ 1.850647991850328356622940552450636420484E0L,
+ 9.927611557279019463768050710008450625415E0L,
+ 2.531667257649436709617165336779212114570E1L,
+ 2.869752886406743386458304052862814690045E1L,
+ 1.182059497870819562441683560749192539345E1L,
+ /* 1.000000000000000000000000000000000000000E0 */
+ },
+/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rc(x^2)/sc(x^2))
+ 1/107 <= 1/x <= 1/6.6666259765625
+ Peak relative error 1.1e-21 */
+ rc[] = {
+ -8.299617545269701963973537248996670806850E-5L,
+ -6.243845685115818513578933902532056244108E-3L,
+ -1.141667210620380223113693474478394397230E-1L,
+ -7.521343797212024245375240432734425789409E-1L,
+ -1.765321928311155824664963633786967602934E0L,
+ -1.029403473103215800456761180695263439188E0L,
+ },
+
+ sc[] = {
+ 8.413244363014929493035952542677768808601E-3L,
+ 2.065114333816877479753334599639158060979E-1L,
+ 1.639064941530797583766364412782135680148E0L,
+ 4.936788463787115555582319302981666347450E0L,
+ 5.005177727208955487404729933261347679090E0L,
+ /* 1.000000000000000000000000000000000000000E0 */
+ };
+
+#ifdef __STDC__
+long double
+__erfl (long double x)
+#else
+long double
+__erfl (x)
+ long double x;
+#endif
+{
+ long double R, S, P, Q, s, y, z, r;
+ int32_t ix, i;
+ u_int32_t se, i0, i1;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+
+ if (ix >= 0x7fff)
+ { /* erf(nan)=nan */
+ i = ((se & 0xffff) >> 15) << 1;
+ return (long double) (1 - i) + one / x; /* erf(+-inf)=+-1 */
+ }
+
+ ix = (ix << 16) | (i0 >> 16);
+ if (ix < 0x3ffed800) /* |x|<0.84375 */
+ {
+ if (ix < 0x3fde8000) /* |x|<2**-33 */
+ {
+ if (ix < 0x00080000)
+ return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */
+ return x + efx * x;
+ }
+ z = x * x;
+ r = pp[0] + z * (pp[1]
+ + z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5]))));
+ s = qq[0] + z * (qq[1]
+ + z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z)))));
+ y = r / s;
+ return x + x * y;
+ }
+ if (ix < 0x3fffa000) /* 1.25 */
+ { /* 0.84375 <= |x| < 1.25 */
+ s = fabsl (x) - one;
+ P = pa[0] + s * (pa[1] + s * (pa[2]
+ + s * (pa[3] + s * (pa[4] + s * (pa[5] + s * (pa[6] + s * pa[7]))))));
+ Q = qa[0] + s * (qa[1] + s * (qa[2]
+ + s * (qa[3] + s * (qa[4] + s * (qa[5] + s * (qa[6] + s))))));
+ if ((se & 0x8000) == 0)
+ return erx + P / Q;
+ else
+ return -erx - P / Q;
+ }
+ if (ix >= 0x4001d555) /* 6.6666259765625 */
+ { /* inf>|x|>=6.666 */
+ if ((se & 0x8000) == 0)
+ return one - tiny;
+ else
+ return tiny - one;
+ }
+ x = fabsl (x);
+ s = one / (x * x);
+ if (ix < 0x4000b6db) /* 2.85711669921875 */
+ {
+ R = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] +
+ s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8])))))));
+ S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] +
+ s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s))))))));
+ }
+ else
+ { /* |x| >= 1/0.35 */
+ R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] +
+ s * (rb[5] + s * (rb[6] + s * rb[7]))))));
+ S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] +
+ s * (sb[5] + s * (sb[6] + s))))));
+ }
+ z = x;
+ GET_LDOUBLE_WORDS (i, i0, i1, z);
+ i1 = 0;
+ SET_LDOUBLE_WORDS (z, i, i0, i1);
+ r =
+ __ieee754_expl (-z * z - 0.5625) * __ieee754_expl ((z - x) * (z + x) +
+ R / S);
+ if ((se & 0x8000) == 0)
+ return one - r / x;
+ else
+ return r / x - one;
+}
+
+weak_alias (__erfl, erfl)
+#ifdef __STDC__
+ long double
+ __erfcl (long double x)
+#else
+ long double
+ __erfcl (x)
+ long double x;
+#endif
+{
+ int32_t hx, ix;
+ long double R, S, P, Q, s, y, z, r;
+ u_int32_t se, i0, i1;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ ix = se & 0x7fff;
+ if (ix >= 0x7fff)
+ { /* erfc(nan)=nan */
+ /* erfc(+-inf)=0,2 */
+ return (long double) (((se & 0xffff) >> 15) << 1) + one / x;
+ }
+
+ ix = (ix << 16) | (i0 >> 16);
+ if (ix < 0x3ffed800) /* |x|<0.84375 */
+ {
+ if (ix < 0x3fbe0000) /* |x|<2**-65 */
+ return one - x;
+ z = x * x;
+ r = pp[0] + z * (pp[1]
+ + z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5]))));
+ s = qq[0] + z * (qq[1]
+ + z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z)))));
+ y = r / s;
+ if (ix < 0x3ffd8000) /* x<1/4 */
+ {
+ return one - (x + x * y);
+ }
+ else
+ {
+ r = x * y;
+ r += (x - half);
+ return half - r;
+ }
+ }
+ if (ix < 0x3fffa000) /* 1.25 */
+ { /* 0.84375 <= |x| < 1.25 */
+ s = fabsl (x) - one;
+ P = pa[0] + s * (pa[1] + s * (pa[2]
+ + s * (pa[3] + s * (pa[4] + s * (pa[5] + s * (pa[6] + s * pa[7]))))));
+ Q = qa[0] + s * (qa[1] + s * (qa[2]
+ + s * (qa[3] + s * (qa[4] + s * (qa[5] + s * (qa[6] + s))))));
+ if ((se & 0x8000) == 0)
+ {
+ z = one - erx;
+ return z - P / Q;
+ }
+ else
+ {
+ z = erx + P / Q;
+ return one + z;
+ }
+ }
+ if (ix < 0x4005d600) /* 107 */
+ { /* |x|<107 */
+ x = fabsl (x);
+ s = one / (x * x);
+ if (ix < 0x4000b6db) /* 2.85711669921875 */
+ { /* |x| < 1/.35 ~ 2.857143 */
+ R = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] +
+ s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8])))))));
+ S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] +
+ s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s))))))));
+ }
+ else if (ix < 0x4001d555) /* 6.6666259765625 */
+ { /* 6.666 > |x| >= 1/.35 ~ 2.857143 */
+ R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] +
+ s * (rb[5] + s * (rb[6] + s * rb[7]))))));
+ S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] +
+ s * (sb[5] + s * (sb[6] + s))))));
+ }
+ else
+ { /* |x| >= 6.666 */
+ if (se & 0x8000)
+ return two - tiny; /* x < -6.666 */
+
+ R = rc[0] + s * (rc[1] + s * (rc[2] + s * (rc[3] +
+ s * (rc[4] + s * rc[5]))));
+ S = sc[0] + s * (sc[1] + s * (sc[2] + s * (sc[3] +
+ s * (sc[4] + s))));
+ }
+ z = x;
+ GET_LDOUBLE_WORDS (hx, i0, i1, z);
+ i1 = 0;
+ i0 &= 0xffffff00;
+ SET_LDOUBLE_WORDS (z, hx, i0, i1);
+ r = __ieee754_expl (-z * z - 0.5625) *
+ __ieee754_expl ((z - x) * (z + x) + R / S);
+ if ((se & 0x8000) == 0)
+ return r / x;
+ else
+ return two - r / x;
+ }
+ else
+ {
+ if ((se & 0x8000) == 0)
+ return tiny * tiny;
+ else
+ return two - tiny;
+ }
+}
+
+weak_alias (__erfcl, erfcl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_fabsl.c b/libc/sysdeps/ieee754/ldbl-96/s_fabsl.c
new file mode 100644
index 000000000..f7170503f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_fabsl.c
@@ -0,0 +1,40 @@
+/* s_fabsl.c -- long double version of s_fabs.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * fabsl(x) returns the absolute value of x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __fabsl(long double x)
+#else
+ long double __fabsl(x)
+ long double x;
+#endif
+{
+ u_int32_t exp;
+ GET_LDOUBLE_EXP(exp,x);
+ SET_LDOUBLE_EXP(x,exp&0x7fff);
+ return x;
+}
+weak_alias (__fabsl, fabsl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_finitel.c b/libc/sysdeps/ieee754/ldbl-96/s_finitel.c
new file mode 100644
index 000000000..437ea87f8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_finitel.c
@@ -0,0 +1,41 @@
+/* s_finitel.c -- long double version of s_finite.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * finitel(x) returns 1 is x is finite, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __finitel(long double x)
+#else
+ int __finitel(x)
+ long double x;
+#endif
+{
+ int32_t exp;
+ GET_LDOUBLE_EXP(exp,x);
+ return (int)((u_int32_t)((exp&0x7fff)-0x7fff)>>31);
+}
+hidden_def (__finitel)
+weak_alias (__finitel, finitel)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_floorl.c b/libc/sysdeps/ieee754/ldbl-96/s_floorl.c
new file mode 100644
index 000000000..7115dbad9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_floorl.c
@@ -0,0 +1,95 @@
+/* s_floorl.c -- long double version of s_floor.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * floorl(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to floor(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double huge = 1.0e4930;
+#else
+static long double huge = 1.0e4930;
+#endif
+
+#ifdef __STDC__
+ long double __floorl(long double x)
+#else
+ long double __floorl(x)
+ long double x;
+#endif
+{
+ int32_t i1,j0;
+ u_int32_t i,j,se,i0,sx;
+ GET_LDOUBLE_WORDS(se,i0,i1,x);
+ sx = (se>>15)&1;
+ j0 = (se&0x7fff)-0x3fff;
+ if(j0<31) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(sx==0) {se=0;i0=i1=0;}
+ else if(((se&0x7fff)|i0|i1)!=0)
+ { se=0xbfff;i0=i1=0;}
+ }
+ } else {
+ i = (0x7fffffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(sx) {
+ if (j0>0 && (i0+(0x80000000>>j0))>i0)
+ i0 += (0x80000000)>>j0;
+ else
+ {
+ i = 0x7fffffff;
+ ++se;
+ }
+ }
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>62) {
+ if(j0==0x4000) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-31);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(sx) {
+ if(j0==31) i0+=1;
+ else {
+ j = i1+(1<<(63-j0));
+ if(j<i1) i0 +=1 ; /* got a carry */
+ i1=j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ SET_LDOUBLE_WORDS(x,se,i0,i1);
+ return x;
+}
+weak_alias (__floorl, floorl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_fpclassifyl.c b/libc/sysdeps/ieee754/ldbl-96/s_fpclassifyl.c
new file mode 100644
index 000000000..7851c9ac7
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_fpclassifyl.c
@@ -0,0 +1,45 @@
+/* Return classification value corresponding to argument.
+ Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+ Fixed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+int
+__fpclassifyl (long double x)
+{
+ u_int32_t ex, hx, lx, m;
+ int retval = FP_NORMAL;
+
+ GET_LDOUBLE_WORDS (ex, hx, lx, x);
+ m = (hx & 0x7fffffff) | lx;
+ ex &= 0x7fff;
+ if ((ex | m) == 0)
+ retval = FP_ZERO;
+ else if (ex == 0 && (hx & 0x80000000) == 0)
+ retval = FP_SUBNORMAL;
+ else if (ex == 0x7fff)
+ retval = m != 0 ? FP_NAN : FP_INFINITE;
+
+ return retval;
+}
+libm_hidden_def (__fpclassifyl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_frexpl.c b/libc/sysdeps/ieee754/ldbl-96/s_frexpl.c
new file mode 100644
index 000000000..0caa90b03
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_frexpl.c
@@ -0,0 +1,70 @@
+/* s_frexpl.c -- long double version of s_frexp.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * for non-zero x
+ * x = frexpl(arg,&exp);
+ * return a long double fp quantity x such that 0.5 <= |x| <1.0
+ * and the corresponding binary exponent "exp". That is
+ * arg = x*2^exp.
+ * If arg is inf, 0.0, or NaN, then frexpl(arg,&exp) returns arg
+ * with *exp=0.
+ */
+
+#include <float.h>
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+#if LDBL_MANT_DIG == 64
+two65 = 3.68934881474191032320e+19L; /* 0x4040, 0x80000000, 0x00000000 */
+#else
+# error "Cannot handle this MANT_DIG"
+#endif
+
+
+#ifdef __STDC__
+ long double __frexpl(long double x, int *eptr)
+#else
+ long double __frexpl(x, eptr)
+ long double x; int *eptr;
+#endif
+{
+ u_int32_t se, hx, ix, lx;
+ GET_LDOUBLE_WORDS(se,hx,lx,x);
+ ix = 0x7fff&se;
+ *eptr = 0;
+ if(ix==0x7fff||((ix|hx|lx)==0)) return x; /* 0,inf,nan */
+ if (ix==0x0000) { /* subnormal */
+ x *= two65;
+ GET_LDOUBLE_EXP(se,x);
+ ix = se&0x7fff;
+ *eptr = -65;
+ }
+ *eptr += ix-16382;
+ se = (se & 0x8000) | 0x3ffe;
+ SET_LDOUBLE_EXP(x,se);
+ return x;
+}
+weak_alias (__frexpl, frexpl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_ilogbl.c b/libc/sysdeps/ieee754/ldbl-96/s_ilogbl.c
new file mode 100644
index 000000000..d11e4c2f2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_ilogbl.c
@@ -0,0 +1,65 @@
+/* s_ilogbl.c -- long double version of s_ilogb.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* ilogbl(long double x)
+ * return the binary exponent of non-zero x
+ * ilogbl(0) = FP_ILOGB0
+ * ilogbl(NaN) = FP_ILOGBNAN (no signal is raised)
+ * ilogbl(+-Inf) = INT_MAX (no signal is raised)
+ */
+
+#include <limits.h>
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __ilogbl(long double x)
+#else
+ int __ilogbl(x)
+ long double x;
+#endif
+{
+ int32_t es,hx,lx,ix;
+
+ GET_LDOUBLE_EXP(es,x);
+ es &= 0x7fff;
+ if(es==0) {
+ GET_LDOUBLE_WORDS(es,hx,lx,x);
+ if((hx|lx)==0)
+ return FP_ILOGB0; /* ilogbl(0) = FP_ILOGB0 */
+ else /* subnormal x */
+ if(hx==0) {
+ for (ix = -16415; lx>0; lx<<=1) ix -=1;
+ } else {
+ for (ix = -16383; hx>0; hx<<=1) ix -=1;
+ }
+ return ix;
+ }
+ else if (es<0x7fff) return es-0x3fff;
+ else if (FP_ILOGBNAN != INT_MAX)
+ {
+ GET_LDOUBLE_WORDS(es,hx,lx,x);
+ if (((hx & 0x7fffffff)|lx) == 0)
+ /* ISO C99 requires ilogbl(+-Inf) == INT_MAX. */
+ return INT_MAX;
+ }
+ return FP_ILOGBNAN;
+}
+weak_alias (__ilogbl, ilogbl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_isinfl.c b/libc/sysdeps/ieee754/ldbl-96/s_isinfl.c
new file mode 100644
index 000000000..9583234ef
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_isinfl.c
@@ -0,0 +1,30 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Change for long double by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/*
+ * isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+int
+__isinfl (long double x)
+{
+ int32_t se,hx,lx;
+ GET_LDOUBLE_WORDS(se,hx,lx,x);
+ lx |= (hx & 0x7fffffff) | ((se & 0x7fff) ^ 0x7fff);
+ lx |= -lx;
+ se &= 0x8000;
+ return ~(lx >> 31) & (1 - (se >> 14));
+}
+hidden_def (__isinfl)
+weak_alias (__isinfl, isinfl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_isnanl.c b/libc/sysdeps/ieee754/ldbl-96/s_isnanl.c
new file mode 100644
index 000000000..5aa94149f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_isnanl.c
@@ -0,0 +1,45 @@
+/* s_isnanl.c -- long double version of s_isnan.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * isnanl(x) returns 1 is x is nan, else 0;
+ * no branching!
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ int __isnanl(long double x)
+#else
+ int __isnanl(x)
+ long double x;
+#endif
+{
+ int32_t se,hx,lx;
+ GET_LDOUBLE_WORDS(se,hx,lx,x);
+ se = (se & 0x7fff) << 1;
+ lx |= hx & 0x7fffffff;
+ se |= (u_int32_t)(lx|(-lx))>>31;
+ se = 0xfffe - se;
+ return (int)(((u_int32_t)(se))>>31);
+}
+hidden_def (__isnanl)
+weak_alias (__isnanl, isnanl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_llrintl.c b/libc/sysdeps/ieee754/ldbl-96/s_llrintl.c
new file mode 100644
index 000000000..e927a8af4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_llrintl.c
@@ -0,0 +1,77 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+static const long double two63[2] =
+{
+ 9.223372036854775808000000e+18, /* 0x403E, 0x00000000, 0x00000000 */
+ -9.223372036854775808000000e+18 /* 0xC03E, 0x00000000, 0x00000000 */
+};
+
+
+long long int
+__llrintl (long double x)
+{
+ int32_t se,j0;
+ u_int32_t i0, i1;
+ long long int result;
+ volatile long double w;
+ long double t;
+ int sx;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+
+ sx = (se >> 15) & 1;
+ j0 = (se & 0x7fff) - 0x3fff;
+
+ if (j0 < (int32_t) (8 * sizeof (long long int)) - 1)
+ {
+ if (j0 < -1)
+ return 0;
+ else if (j0 >= 63)
+ result = (((long long int) i0 << 32) | i1) << (j0 - 63);
+ else
+ {
+ w = two63[sx] + x;
+ t = w - two63[sx];
+ GET_LDOUBLE_WORDS (se, i0, i1, t);
+ j0 = (se & 0x7fff) - 0x3fff;
+
+ if (j0 <= 31)
+ result = i0 >> (31 - j0);
+ else
+ result = ((long long int) i0 << (j0 - 31)) | (i1 >> (63 - j0));
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long long int) x;
+ }
+
+ return sx ? -result : result;
+}
+
+weak_alias (__llrintl, llrintl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_llroundl.c b/libc/sysdeps/ieee754/ldbl-96/s_llroundl.c
new file mode 100644
index 000000000..2fe94994b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_llroundl.c
@@ -0,0 +1,81 @@
+/* Round long double value to long long int.
+ Copyright (C) 1997, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+long long int
+__llroundl (long double x)
+{
+ int32_t j0;
+ u_int32_t se, i1, i0;
+ long long int result;
+ int sign;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ j0 = (se & 0x7fff) - 0x3fff;
+ sign = (se & 0x8000) != 0 ? -1 : 1;
+
+ if (j0 < 31)
+ {
+ if (j0 < 0)
+ return j0 < -1 ? 0 : sign;
+ else
+ {
+ u_int32_t j = i0 + (0x40000000 >> j0);
+ if (j < i0)
+ {
+ j >>= 1;
+ j |= 0x80000000;
+ ++j0;
+ }
+
+ result = j >> (31 - j0);
+ }
+ }
+ else if (j0 < (int32_t) (8 * sizeof (long long int)) - 1)
+ {
+ if (j0 >= 63)
+ result = (((long long int) i0 << 32) | i1) << (j0 - 63);
+ else
+ {
+ u_int32_t j = i1 + (0x80000000 >> (j0 - 31));
+
+ result = (long long int) i0;
+ if (j < i1)
+ ++result;
+
+ if (j0 > 31)
+ result = (result << (j0 - 31)) | (j >> (63 - j0));
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long long int) x;
+ }
+
+ return sign * result;
+}
+
+weak_alias (__llroundl, llroundl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_logbl.c b/libc/sysdeps/ieee754/ldbl-96/s_logbl.c
new file mode 100644
index 000000000..2cd9d105f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_logbl.c
@@ -0,0 +1,47 @@
+/* s_logbl.c -- long double version of s_logb.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * long double logbl(x)
+ * IEEE 754 logb. Included to pass IEEE test suite. Not recommend.
+ * Use ilogb instead.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __logbl(long double x)
+#else
+ long double __logbl(x)
+ long double x;
+#endif
+{
+ int32_t es,lx,ix;
+ GET_LDOUBLE_WORDS(es,ix,lx,x);
+ es &= 0x7fff; /* exponent */
+ if((es|ix|lx)==0) return -1.0/fabs(x);
+ if(es==0x7fff) return x*x;
+ if(es==0) /* IEEE 754 logb */
+ return -16382.0;
+ else
+ return (long double) (es-0x3fff);
+}
+weak_alias (__logbl, logbl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_lrintl.c b/libc/sysdeps/ieee754/ldbl-96/s_lrintl.c
new file mode 100644
index 000000000..421209398
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_lrintl.c
@@ -0,0 +1,89 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+static const long double two63[2] =
+{
+ 9.223372036854775808000000e+18, /* 0x403E, 0x00000000, 0x00000000 */
+ -9.223372036854775808000000e+18 /* 0xC03E, 0x00000000, 0x00000000 */
+};
+
+
+long int
+__lrintl (long double x)
+{
+ int32_t se,j0;
+ u_int32_t i0, i1;
+ long int result;
+ volatile long double w;
+ long double t;
+ int sx;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+
+ sx = (se >> 15) & 1;
+ j0 = (se & 0x7fff) - 0x3fff;
+
+ if (j0 < 31)
+ {
+ if (j0 < -1)
+ return 0;
+ else
+ {
+ w = two63[sx] + x;
+ t = w - two63[sx];
+ GET_LDOUBLE_WORDS (se, i0, i1, t);
+ j0 = (se & 0x7fff) - 0x3fff;
+
+ result = i0 >> (31 - j0);
+ }
+ }
+ else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
+ {
+ if (j0 >= 63)
+ result = ((long int) i0 << (j0 - 31)) | (i1 << (j0 - 63));
+ else
+ {
+ w = two63[sx] + x;
+ t = w - two63[sx];
+ GET_LDOUBLE_WORDS (se, i0, i1, t);
+ j0 = (se & 0x7fff) - 0x3fff;
+
+ if (j0 == 31)
+ result = (long int) i0;
+ else
+ result = ((long int) i0 << (j0 - 31)) | (i1 >> (63 - j0));
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long int) x;
+ }
+
+ return sx ? -result : result;
+}
+
+weak_alias (__lrintl, lrintl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_lroundl.c b/libc/sysdeps/ieee754/ldbl-96/s_lroundl.c
new file mode 100644
index 000000000..217ce1b9e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_lroundl.c
@@ -0,0 +1,81 @@
+/* Round long double value to long int.
+ Copyright (C) 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+long int
+__lroundl (long double x)
+{
+ int32_t j0;
+ u_int32_t se, i1, i0;
+ long int result;
+ int sign;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ j0 = (se & 0x7fff) - 0x3fff;
+ sign = (se & 0x8000) != 0 ? -1 : 1;
+
+ if (j0 < 31)
+ {
+ if (j0 < 0)
+ return j0 < -1 ? 0 : sign;
+ else
+ {
+ u_int32_t j = i0 + (0x40000000 >> j0);
+ if (j < i0)
+ {
+ j >>= 1;
+ j |= 0x80000000;
+ ++j0;
+ }
+
+ result = j >> (31 - j0);
+ }
+ }
+ else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
+ {
+ if (j0 >= 63)
+ result = ((long int) i0 << (j0 - 31)) | (i1 << (j0 - 63));
+ else
+ {
+ u_int32_t j = i1 + (0x80000000 >> (j0 - 31));
+ if (j < i1)
+ ++i0;
+
+ if (j0 == 31)
+ result = (long int) i0;
+ else
+ result = ((long int) i0 << (j0 - 31)) | (j >> (63 - j0));
+ }
+ }
+ else
+ {
+ /* The number is too large. It is left implementation defined
+ what happens. */
+ return (long int) x;
+ }
+
+ return sign * result;
+}
+
+weak_alias (__lroundl, lroundl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_modfl.c b/libc/sysdeps/ieee754/ldbl-96/s_modfl.c
new file mode 100644
index 000000000..99c0752ef
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_modfl.c
@@ -0,0 +1,85 @@
+/* s_modfl.c -- long double version of s_modf.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * modfl(long double x, long double *iptr)
+ * return fraction part of x, and return x's integral part in *iptr.
+ * Method:
+ * Bit twiddling.
+ *
+ * Exception:
+ * No exception.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0;
+#else
+static long double one = 1.0;
+#endif
+
+#ifdef __STDC__
+ long double __modfl(long double x, long double *iptr)
+#else
+ long double __modfl(x, iptr)
+ long double x,*iptr;
+#endif
+{
+ int32_t i0,i1,j0;
+ u_int32_t i,se;
+ GET_LDOUBLE_WORDS(se,i0,i1,x);
+ j0 = (se&0x7fff)-0x3fff; /* exponent of x */
+ if(j0<32) { /* integer part in high x */
+ if(j0<0) { /* |x|<1 */
+ SET_LDOUBLE_WORDS(*iptr,se&0x8000,0,0); /* *iptr = +-0 */
+ return x;
+ } else {
+ i = (0x7fffffff)>>j0;
+ if(((i0&i)|i1)==0) { /* x is integral */
+ *iptr = x;
+ SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */
+ return x;
+ } else {
+ SET_LDOUBLE_WORDS(*iptr,se,i0&(~i),0);
+ return x - *iptr;
+ }
+ }
+ } else if (j0>63) { /* no fraction part */
+ *iptr = x*one;
+ /* We must handle NaNs separately. */
+ if (j0 == 0x4000 && ((i0 & 0x7fffffff) | i1))
+ return x*one;
+ SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */
+ return x;
+ } else { /* fraction part in low x */
+ i = ((u_int32_t)(0x7fffffff))>>(j0-32);
+ if((i1&i)==0) { /* x is integral */
+ *iptr = x;
+ SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */
+ return x;
+ } else {
+ SET_LDOUBLE_WORDS(*iptr,se,i0,i1&(~i));
+ return x - *iptr;
+ }
+ }
+}
+weak_alias (__modfl, modfl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_nearbyintl.c b/libc/sysdeps/ieee754/ldbl-96/s_nearbyintl.c
new file mode 100644
index 000000000..92c3ebf36
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_nearbyintl.c
@@ -0,0 +1,95 @@
+/* s_rintl.c -- long double version of s_rint.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+/* Adapted for use as nearbyint by Ulrich Drepper <drepper@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.
+ * ====================================================
+ */
+
+/*
+ * rintl(x)
+ * Return x rounded to integral value according to the prevailing
+ * rounding mode.
+ * Method:
+ * Using floating addition.
+ * Exception:
+ * Inexact flag raised if x not equal to rintl(x).
+ */
+
+#include <fenv.h>
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+TWO63[2]={
+ 9.223372036854775808000000e+18, /* 0x403E, 0x00000000, 0x00000000 */
+ -9.223372036854775808000000e+18 /* 0xC03E, 0x00000000, 0x00000000 */
+};
+
+#ifdef __STDC__
+ long double __nearbyintl(long double x)
+#else
+ long double __nearbyintl(x)
+ long double x;
+#endif
+{
+ fenv_t env;
+ int32_t se,j0,sx;
+ u_int32_t i,i0,i1;
+ long double w,t;
+ GET_LDOUBLE_WORDS(se,i0,i1,x);
+ sx = (se>>15)&1;
+ j0 = (se&0x7fff)-0x3fff;
+ if(j0<31) {
+ if(j0<0) {
+ if(((se&0x7fff)|i0|i1)==0) return x;
+ i1 |= i0;
+ i0 &= 0xe0000000;
+ i0 |= (i1|-i1)&0x80000000;
+ SET_LDOUBLE_MSW(x,i0);
+ feholdexcept (&env);
+ w = TWO63[sx]+x;
+ t = w-TWO63[sx];
+ fesetenv (&env);
+ GET_LDOUBLE_EXP(i0,t);
+ SET_LDOUBLE_EXP(t,(i0&0x7fff)|(sx<<15));
+ return t;
+ } else {
+ i = (0x7fffffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ i>>=1;
+ if(((i0&i)|i1)!=0) {
+ if (j0==30) i1 = 0x40000000; else
+ i0 = (i0&(~i))|((0x20000000)>>j0);
+ }
+ }
+ } else if (j0>62) {
+ if(j0==0x4000) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-31);
+ if((i1&i)==0) return x; /* x is integral */
+ i>>=1;
+ if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-31));
+ }
+ SET_LDOUBLE_WORDS(x,se,i0,i1);
+ feholdexcept (&env);
+ w = TWO63[sx]+x;
+ t = w-TWO63[sx];
+ fesetenv (&env);
+ return t;
+}
+weak_alias (__nearbyintl, nearbyintl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_nextafterl.c b/libc/sysdeps/ieee754/ldbl-96/s_nextafterl.c
new file mode 100644
index 000000000..1798261b2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_nextafterl.c
@@ -0,0 +1,101 @@
+/* s_nextafterl.c -- long double version of s_nextafter.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* IEEE functions
+ * nextafterl(x,y)
+ * return the next machine floating-point number of x in the
+ * direction toward y.
+ * Special cases:
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __nextafterl(long double x, long double y)
+#else
+ long double __nextafterl(x,y)
+ long double x,y;
+#endif
+{
+ int32_t hx,hy,ix,iy;
+ u_int32_t lx,ly,esx,esy;
+
+ GET_LDOUBLE_WORDS(esx,hx,lx,x);
+ GET_LDOUBLE_WORDS(esy,hy,ly,y);
+ ix = esx&0x7fff; /* |x| */
+ iy = esy&0x7fff; /* |y| */
+
+ if (((ix==0x7fff)&&((hx|lx)!=0)) || /* x is nan */
+ ((iy==0x7fff)&&((hy|ly)!=0))) /* y is nan */
+ return x+y;
+ if(x==y) return y; /* x=y, return y */
+ if((ix|hx|lx)==0) { /* x == 0 */
+ SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */
+ y = x*x;
+ if(y==x) return y; else return x; /* raise underflow flag */
+ }
+ if(esx<0x8000) { /* x > 0 */
+ if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
+ /* x > y, x -= ulp */
+ if(lx==0) {
+ if (hx==0) esx -= 1;
+ hx -= 1;
+ }
+ lx -= 1;
+ } else { /* x < y, x += ulp */
+ lx += 1;
+ if(lx==0) {
+ hx += 1;
+ if (hx==0)
+ esx += 1;
+ }
+ }
+ } else { /* x < 0 */
+ if(esy>=0||(ix>iy||((ix==iy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){
+ /* x < y, x -= ulp */
+ if(lx==0) {
+ if (hx==0) esx -= 1;
+ hx -= 1;
+ }
+ lx -= 1;
+ } else { /* x > y, x += ulp */
+ lx += 1;
+ if(lx==0) {
+ hx += 1;
+ if (hx==0) esx += 1;
+ }
+ }
+ }
+ esy = esx&0x7fff;
+ if(esy==0x7fff) return x+x; /* overflow */
+ if(esy==0) { /* underflow */
+ y = x*x;
+ if(y!=x) { /* raise underflow flag */
+ SET_LDOUBLE_WORDS(y,esx,hx,lx);
+ return y;
+ }
+ }
+ SET_LDOUBLE_WORDS(x,esx,hx,lx);
+ return x;
+}
+weak_alias (__nextafterl, nextafterl)
+strong_alias (__nextafterl, __nexttowardl)
+weak_alias (__nextafterl, nexttowardl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_nexttoward.c b/libc/sysdeps/ieee754/ldbl-96/s_nexttoward.c
new file mode 100644
index 000000000..7945cb5cb
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_nexttoward.c
@@ -0,0 +1,101 @@
+/* s_nexttoward.c
+ * Conversion from s_nextafter.c by Ulrich Drepper, Cygnus Support,
+ * drepper@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: $";
+#endif
+
+/* IEEE functions
+ * nexttoward(x,y)
+ * return the next machine floating-point number of x in the
+ * direction toward y.
+ * Special cases:
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include <float.h>
+
+#ifdef __STDC__
+ double __nexttoward(double x, long double y)
+#else
+ double __nexttoward(x,y)
+ double x;
+ long double y;
+#endif
+{
+ int32_t hx,ix,iy;
+ u_int32_t lx,hy,ly,esy;
+
+ EXTRACT_WORDS(hx,lx,x);
+ GET_LDOUBLE_WORDS(esy,hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = esy&0x7fff; /* |y| */
+
+ if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */
+ ((iy>=0x7fff)&&(hy|ly)!=0)) /* y is nan */
+ return x+y;
+ if((long double) x==y) return y; /* x=y, return y */
+ if((ix|lx)==0) { /* x == 0 */
+ double x2;
+ INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */
+ x2 = x*x;
+ if(x2==x) return x2; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00
+ || (((ix>>20)&0x7ff)==iy-0x3c00
+ && (((hx<<11)|(lx>>21))>(hy&0x7fffffff)
+ || (((hx<<11)|(lx>>21))==(hy&0x7fffffff)
+ && (lx<<11)>ly)))) { /* x > y, x -= ulp */
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { /* x < y, x += ulp */
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ } else { /* x < 0 */
+ if (esy<0x8000||((ix>>20)&0x7ff)>iy-0x3c00
+ || (((ix>>20)&0x7ff)==iy-0x3c00
+ && (((hx<<11)|(lx>>21))>(hy&0x7fffffff)
+ || (((hx<<11)|(lx>>21))==(hy&0x7fffffff)
+ && (lx<<11)>ly)))) {/* x < y, x -= ulp */
+ if(lx==0) hx -= 1;
+ lx -= 1;
+ } else { /* x > y, x += ulp */
+ lx += 1;
+ if(lx==0) hx += 1;
+ }
+ }
+ hy = hx&0x7ff00000;
+ if(hy>=0x7ff00000) {
+ x = x+x; /* overflow */
+ if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
+ /* Force conversion to float. */
+ asm ("" : "=m"(x) : "m"(x));
+ return x;
+ }
+ if(hy<0x00100000) { /* underflow */
+ double x2 = x*x;
+ if(x2!=x) { /* raise underflow flag */
+ INSERT_WORDS(x2,hx,lx);
+ return x2;
+ }
+ }
+ INSERT_WORDS(x,hx,lx);
+ return x;
+}
+weak_alias (__nexttoward, nexttoward)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_nexttowardf.c b/libc/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
new file mode 100644
index 000000000..a1c38b5d4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
@@ -0,0 +1,78 @@
+/* s_nexttowardf.c -- float version of s_nextafter.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: $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ float __nexttowardf(float x, long double y)
+#else
+ float __nexttowardf(x,y)
+ float x;
+ long double y;
+#endif
+{
+ int32_t hx,ix,iy;
+ u_int32_t hy,ly,esy;
+
+ GET_FLOAT_WORD(hx,x);
+ GET_LDOUBLE_WORDS(esy,hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = esy&0x7fff; /* |y| */
+
+ if((ix>0x7f800000) || /* x is nan */
+ (iy>=0x7fff&&((hy|ly)!=0))) /* y is nan */
+ return x+y;
+ if((long double) x==y) return y; /* x=y, return y */
+ if(ix==0) { /* x == 0 */
+ float x2;
+ SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/
+ x2 = x*x;
+ if(x2==x) return x2; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80
+ || (((ix>>23)&0xff)==iy-0x3f80
+ && ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x > y, x -= ulp */
+ hx -= 1;
+ } else { /* x < y, x += ulp */
+ hx += 1;
+ }
+ } else { /* x < 0 */
+ if(esy<0x8000||((ix>>23)&0xff)>iy-0x3f80
+ || (((ix>>23)&0xff)==iy-0x3f80
+ && ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x < y, x -= ulp */
+ hx -= 1;
+ } else { /* x > y, x += ulp */
+ hx += 1;
+ }
+ }
+ hy = hx&0x7f800000;
+ if(hy>=0x7f800000) return x+x; /* overflow */
+ if(hy<0x00800000) { /* underflow */
+ float x2 = x*x;
+ if(x2!=x) { /* raise underflow flag */
+ SET_FLOAT_WORD(x2,hx);
+ return x2;
+ }
+ }
+ SET_FLOAT_WORD(x,hx);
+ return x;
+}
+weak_alias (__nexttowardf, nexttowardf)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_remquol.c b/libc/sysdeps/ieee754/ldbl-96/s_remquol.c
new file mode 100644
index 000000000..5fd8e8847
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_remquol.c
@@ -0,0 +1,109 @@
+/* Compute remainder and a congruent to the quotient.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+static const long double zero = 0.0;
+
+
+long double
+__remquol (long double x, long double p, int *quo)
+{
+ int32_t ex,ep,hx,hp;
+ u_int32_t sx,lx,lp;
+ int cquo,qs;
+
+ GET_LDOUBLE_WORDS (ex, hx, lx, x);
+ GET_LDOUBLE_WORDS (ep, hp, lp, p);
+ sx = ex & 0x8000;
+ qs = (sx ^ (ep & 0x8000)) >> 15;
+ ep &= 0x7fff;
+ ex &= 0x7fff;
+
+ /* Purge off exception values. */
+ if ((ep | hp | lp) == 0)
+ return (x * p) / (x * p); /* p = 0 */
+ if ((ex == 0x7fff) /* x not finite */
+ || ((ep == 0x7fff) /* p is NaN */
+ && ((hp | lp) != 0)))
+ return (x * p) / (x * p);
+
+ if (ep <= 0x7ffb)
+ x = __ieee754_fmodl (x, 8 * p); /* now x < 8p */
+
+ if (((ex - ep) | (hx - hp) | (lx - lp)) == 0)
+ {
+ *quo = qs ? -1 : 1;
+ return zero * x;
+ }
+
+ x = fabsl (x);
+ p = fabsl (p);
+ cquo = 0;
+
+ if (x >= 4 * p)
+ {
+ x -= 4 * p;
+ cquo += 4;
+ }
+ if (x >= 2 * p)
+ {
+ x -= 2 * p;
+ cquo += 2;
+ }
+
+ if (ep < 0x0002)
+ {
+ if (x + x > p)
+ {
+ x -= p;
+ ++cquo;
+ if (x + x >= p)
+ {
+ x -= p;
+ ++cquo;
+ }
+ }
+ }
+ else
+ {
+ long double p_half = 0.5 * p;
+ if (x > p_half)
+ {
+ x -= p;
+ ++cquo;
+ if (x >= p_half)
+ {
+ x -= p;
+ ++cquo;
+ }
+ }
+ }
+
+ *quo = qs ? -cquo : cquo;
+
+ if (sx)
+ x = -x;
+ return x;
+}
+weak_alias (__remquol, remquol)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_rintl.c b/libc/sysdeps/ieee754/ldbl-96/s_rintl.c
new file mode 100644
index 000000000..9d4777dcc
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_rintl.c
@@ -0,0 +1,91 @@
+/* s_rintl.c -- long double version of s_rint.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * rintl(x)
+ * Return x rounded to integral value according to the prevailing
+ * rounding mode.
+ * Method:
+ * Using floating addition.
+ * Exception:
+ * Inexact flag raised if x not equal to rintl(x).
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+TWO63[2]={
+ 9.223372036854775808000000e+18, /* 0x403E, 0x00000000, 0x00000000 */
+ -9.223372036854775808000000e+18 /* 0xC03E, 0x00000000, 0x00000000 */
+};
+
+#ifdef __STDC__
+ long double __rintl(long double x)
+#else
+ long double __rintl(x)
+ long double x;
+#endif
+{
+ int32_t se,j0,sx;
+ u_int32_t i,i0,i1;
+ long double w,t;
+ GET_LDOUBLE_WORDS(se,i0,i1,x);
+ sx = (se>>15)&1;
+ j0 = (se&0x7fff)-0x3fff;
+ if(j0<31) {
+ if(j0<0) {
+ if(((se&0x7fff)|i0|i1)==0) return x;
+ i1 |= i0;
+ i0 &= 0xe0000000;
+ i0 |= (i1|-i1)&0x80000000;
+ SET_LDOUBLE_MSW(x,i0);
+ w = TWO63[sx]+x;
+ t = w-TWO63[sx];
+ GET_LDOUBLE_EXP(i0,t);
+ SET_LDOUBLE_EXP(t,(i0&0x7fff)|(sx<<15));
+ return t;
+ } else {
+ i = (0x7fffffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ i>>=1;
+ if(((i0&i)|i1)!=0) {
+ if(j0==30) i1 = 0x40000000; else
+ i0 = (i0&(~i))|((0x20000000)>>j0);
+ }
+ }
+ } else if (j0>62) {
+ if(j0==0x4000) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((u_int32_t)(0xffffffff))>>(j0-31);
+ if((i1&i)==0) return x; /* x is integral */
+ i>>=1;
+ if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-31));
+ }
+ SET_LDOUBLE_WORDS(x,se,i0,i1);
+ w = TWO63[sx]+x;
+ return w-TWO63[sx];
+}
+weak_alias (__rintl, rintl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_roundl.c b/libc/sysdeps/ieee754/ldbl-96/s_roundl.c
new file mode 100644
index 000000000..672536d35
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_roundl.c
@@ -0,0 +1,106 @@
+/* Round long double to integer away from zero.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+static const long double huge = 1.0e4930;
+
+
+long double
+__roundl (long double x)
+{
+ int32_t j0;
+ u_int32_t se, i1, i0;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ j0 = (se & 0x7fff) - 0x3fff;
+ if (j0 < 31)
+ {
+ if (j0 < 0)
+ {
+ if (huge + x > 0.0)
+ {
+ se &= 0x8000;
+ i0 = i1 = 0;
+ if (j0 == -1)
+ {
+ se |= 0x3fff;
+ i0 = 0x80000000;
+ }
+ }
+ }
+ else
+ {
+ u_int32_t i = 0x7fffffff >> j0;
+ if (((i0 & i) | i1) == 0)
+ /* X is integral. */
+ return x;
+ if (huge + x > 0.0)
+ {
+ /* Raise inexact if x != 0. */
+ u_int32_t j = i0 + (0x40000000 >> j0);
+ if (j < i0)
+ se += 1;
+ i0 = (j & ~i) | 0x80000000;
+ i1 = 0;
+ }
+ }
+ }
+ else if (j0 > 62)
+ {
+ if (j0 == 0x4000)
+ /* Inf or NaN. */
+ return x + x;
+ else
+ return x;
+ }
+ else
+ {
+ u_int32_t i = 0xffffffff >> (j0 - 31);
+ if ((i1 & i) == 0)
+ /* X is integral. */
+ return x;
+
+ if (huge + x > 0.0)
+ {
+ /* Raise inexact if x != 0. */
+ u_int32_t j = i1 + (1 << (62 - j0));
+ if (j < i1)
+ {
+ u_int32_t k = i0 + 1;
+ if (k < i0)
+ {
+ se += 1;
+ k |= 0x80000000;
+ }
+ i0 = k;
+ }
+ i1 = j;
+ }
+ i1 &= ~i;
+ }
+
+ SET_LDOUBLE_WORDS (x, se, i0, i1);
+ return x;
+}
+weak_alias (__roundl, roundl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_scalblnl.c b/libc/sysdeps/ieee754/ldbl-96/s_scalblnl.c
new file mode 100644
index 000000000..8e556fabe
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_scalblnl.c
@@ -0,0 +1,71 @@
+/* s_scalbnl.c -- long double version of s_scalbn.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * scalbnl (long double x, int n)
+ * scalbnl(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+two63 = 4.50359962737049600000e+15,
+twom63 = 1.08420217248550443400e-19,
+huge = 1.0e+4900L,
+tiny = 1.0e-4900L;
+
+#ifdef __STDC__
+ long double __scalblnl (long double x, long int n)
+#else
+ long double __scalblnl (x,n)
+ long double x; long int n;
+#endif
+{
+ int32_t k,es,hx,lx;
+ GET_LDOUBLE_WORDS(es,hx,lx,x);
+ k = es&0x7fff; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+ x *= two63;
+ GET_LDOUBLE_EXP(es,x);
+ k = (hx&0x7fff) - 63;
+ }
+ if (k==0x7fff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (n> 50000 || k > 0x7ffe)
+ return huge*__copysignl(huge,x); /* overflow */
+ if (n< -50000)
+ return tiny*__copysignl(tiny,x);
+ if (k > 0) /* normal result */
+ {SET_LDOUBLE_EXP(x,(es&0x8000)|k); return x;}
+ if (k <= -63)
+ return tiny*__copysignl(tiny,x); /*underflow*/
+ k += 63; /* subnormal result */
+ SET_LDOUBLE_EXP(x,(es&0x8000)|k);
+ return x*twom63;
+}
+weak_alias (__scalblnl, scalblnl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_scalbnl.c b/libc/sysdeps/ieee754/ldbl-96/s_scalbnl.c
new file mode 100644
index 000000000..9f441fd1e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_scalbnl.c
@@ -0,0 +1,71 @@
+/* s_scalbnl.c -- long double version of s_scalbn.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * scalbnl (long double x, int n)
+ * scalbnl(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+two64 = 1.8446744073709551616e19L,
+twom64 = 5.421010862427522170037e-20L,
+huge = 1.0e+4900L,
+tiny = 1.0e-4900L;
+
+#ifdef __STDC__
+ long double __scalbnl (long double x, int n)
+#else
+ long double __scalbnl (x,n)
+ long double x; int n;
+#endif
+{
+ int32_t k,es,hx,lx;
+ GET_LDOUBLE_WORDS(es,hx,lx,x);
+ k = es&0x7fff; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+ x *= two64;
+ GET_LDOUBLE_EXP(hx,x);
+ k = (hx&0x7fff) - 64;
+ }
+ if (k==0x7fff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (n> 50000 || k > 0x7ffe)
+ return huge*__copysignl(huge,x); /* overflow */
+ if (n< -50000)
+ return tiny*__copysignl(tiny,x);
+ if (k > 0) /* normal result */
+ {SET_LDOUBLE_EXP(x,(es&0x8000)|k); return x;}
+ if (k <= -64)
+ return tiny*__copysignl(tiny,x); /*underflow*/
+ k += 64; /* subnormal result */
+ SET_LDOUBLE_EXP(x,(es&0x8000)|k);
+ return x*twom64;
+}
+weak_alias (__scalbnl, scalbnl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_signbitl.c b/libc/sysdeps/ieee754/ldbl-96/s_signbitl.c
new file mode 100644
index 000000000..aa8dc8656
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_signbitl.c
@@ -0,0 +1,32 @@
+/* Return nonzero value if number is negative.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+int
+__signbitl (long double x)
+{
+ int32_t e;
+
+ GET_LDOUBLE_EXP (e, x);
+ return e & 0x8000;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_sincosl.c b/libc/sysdeps/ieee754/ldbl-96/s_sincosl.c
new file mode 100644
index 000000000..531e1a8eb
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_sincosl.c
@@ -0,0 +1,74 @@
+/* Compute sine and cosine of argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+void
+__sincosl (long double x, long double *sinx, long double *cosx)
+{
+ int32_t se, i0, i1;
+
+ /* High word of x. */
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+
+ /* |x| ~< pi/4 */
+ se &= 0x7fff;
+ if (se < 0x3ffe || (se == 0x3ffe && i0 <= 0xc90fdaa2))
+ {
+ *sinx = __kernel_sinl (x, 0.0, 0);
+ *cosx = __kernel_cosl (x, 0.0);
+ }
+ else if (se == 0x7fff)
+ {
+ /* sin(Inf or NaN) is NaN */
+ *sinx = *cosx = x - x;
+ }
+ else
+ {
+ /* Argument reduction needed. */
+ long double y[2];
+ int n;
+
+ n = __ieee754_rem_pio2l (x, y);
+ switch (n & 3)
+ {
+ case 0:
+ *sinx = __kernel_sinl (y[0], y[1], 1);
+ *cosx = __kernel_cosl (y[0], y[1]);
+ break;
+ case 1:
+ *sinx = __kernel_cosl (y[0], y[1]);
+ *cosx = -__kernel_sinl (y[0], y[1], 1);
+ break;
+ case 2:
+ *sinx = -__kernel_sinl (y[0], y[1], 1);
+ *cosx = -__kernel_cosl (y[0], y[1]);
+ break;
+ default:
+ *sinx = -__kernel_cosl (y[0], y[1]);
+ *cosx = __kernel_sinl (y[0], y[1], 1);
+ break;
+ }
+ }
+}
+weak_alias (__sincosl, sincosl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_sinl.c b/libc/sysdeps/ieee754/ldbl-96/s_sinl.c
new file mode 100644
index 000000000..4fd48805b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_sinl.c
@@ -0,0 +1,88 @@
+/* s_sinl.c -- long double version of s_sin.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* sinl(x)
+ * Return sine function of x.
+ *
+ * kernel function:
+ * __kernel_sinl ... sine function on [-pi/4,pi/4]
+ * __kernel_cosl ... cose function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2l ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __sinl(long double x)
+#else
+ long double __sinl(x)
+ long double x;
+#endif
+{
+ long double y[2],z=0.0;
+ int32_t n, se, i0, i1;
+
+ /* High word of x. */
+ GET_LDOUBLE_WORDS(se,i0,i1,x);
+
+ /* |x| ~< pi/4 */
+ se &= 0x7fff;
+ if(se < 0x3ffe || (se == 0x3ffe && i0 <= 0xc90fdaa2))
+ return __kernel_sinl(x,z,0);
+
+ /* sin(Inf or NaN) is NaN */
+ else if (se==0x7fff) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2l(x,y);
+ switch(n&3) {
+ case 0: return __kernel_sinl(y[0],y[1],1);
+ case 1: return __kernel_cosl(y[0],y[1]);
+ case 2: return -__kernel_sinl(y[0],y[1],1);
+ default:
+ return -__kernel_cosl(y[0],y[1]);
+ }
+ }
+}
+weak_alias (__sinl, sinl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_tanhl.c b/libc/sysdeps/ieee754/ldbl-96/s_tanhl.c
new file mode 100644
index 000000000..45cea903e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_tanhl.c
@@ -0,0 +1,95 @@
+/* s_tanhl.c -- long double version of s_tanh.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* tanhl(x)
+ * Return the Hyperbolic Tangent of x
+ *
+ * Method :
+ * x -x
+ * e - e
+ * 0. tanhl(x) is defined to be -----------
+ * x -x
+ * e + e
+ * 1. reduce x to non-negative by tanhl(-x) = -tanhl(x).
+ * 2. 0 <= x <= 2**-55 : tanhl(x) := x*(one+x)
+ * -t
+ * 2**-55 < x <= 1 : tanhl(x) := -----; t = expm1l(-2x)
+ * t + 2
+ * 2
+ * 1 <= x <= 23.0 : tanhl(x) := 1- ----- ; t=expm1l(2x)
+ * t + 2
+ * 23.0 < x <= INF : tanhl(x) := 1.
+ *
+ * Special cases:
+ * tanhl(NaN) is NaN;
+ * only tanhl(0)=0 is exact for finite argument.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one=1.0, two=2.0, tiny = 1.0e-4900L;
+#else
+static long double one=1.0, two=2.0, tiny = 1.0e-4900L;
+#endif
+
+#ifdef __STDC__
+ long double __tanhl(long double x)
+#else
+ long double __tanhl(x)
+ long double x;
+#endif
+{
+ long double t,z;
+ int32_t se;
+ u_int32_t j0,j1,ix;
+
+ /* High word of |x|. */
+ GET_LDOUBLE_WORDS(se,j0,j1,x);
+ ix = se&0x7fff;
+
+ /* x is INF or NaN */
+ if(ix==0x7fff) {
+ /* for NaN it's not important which branch: tanhl(NaN) = NaN */
+ if (se&0x8000) return one/x-one; /* tanhl(-inf)= -1; */
+ else return one/x+one; /* tanhl(+inf)=+1 */
+ }
+
+ /* |x| < 23 */
+ if (ix < 0x4003 || (ix == 0x4003 && j0 < 0xb8000000u)) {/* |x|<23 */
+ if ((ix|j0|j1) == 0)
+ return x; /* x == +- 0 */
+ if (ix<0x3fc8) /* |x|<2**-55 */
+ return x*(one+tiny); /* tanh(small) = small */
+ if (ix>=0x3fff) { /* |x|>=1 */
+ t = __expm1l(two*fabsl(x));
+ z = one - two/(t+two);
+ } else {
+ t = __expm1l(-two*fabsl(x));
+ z= -t/(t+two);
+ }
+ /* |x| > 23, return +-1 */
+ } else {
+ z = one - tiny; /* raised inexact flag */
+ }
+ return (se&0x8000)? -z: z;
+}
+weak_alias (__tanhl, tanhl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_tanl.c b/libc/sysdeps/ieee754/ldbl-96/s_tanl.c
new file mode 100644
index 000000000..97a0b27f3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_tanl.c
@@ -0,0 +1,81 @@
+/* s_tanl.c -- long double version of s_tan.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/* tanl(x)
+ * Return tangent function of x.
+ *
+ * kernel function:
+ * __kernel_tanl ... tangent function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2l ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __tanl(long double x)
+#else
+ long double __tanl(x)
+ long double x;
+#endif
+{
+ long double y[2],z=0.0;
+ int32_t n, se;
+
+ /* High word of x. */
+ GET_LDOUBLE_EXP(se,x);
+
+ /* |x| ~< pi/4 */
+ se &= 0x7fff;
+ if(se <= 0x3ffe) return __kernel_tanl(x,z,1);
+
+ /* tan(Inf or NaN) is NaN */
+ else if (se==0x7fff) return x-x; /* NaN */
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2l(x,y);
+ return __kernel_tanl(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even
+ -1 -- n odd */
+ }
+}
+weak_alias (__tanl, tanl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/s_truncl.c b/libc/sysdeps/ieee754/ldbl-96/s_truncl.c
new file mode 100644
index 000000000..268ccdf78
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/s_truncl.c
@@ -0,0 +1,57 @@
+/* Truncate argument to nearest integral value not larger than the argument.
+ Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+#include "math_private.h"
+
+
+long double
+__truncl (long double x)
+{
+ int32_t i0, j0;
+ u_int32_t se, i1;
+ int sx;
+
+ GET_LDOUBLE_WORDS (se, i0, i1, x);
+ sx = se & 0x8000;
+ j0 = (se & 0x7fff) - 0x3fff;
+ if (j0 < 31)
+ {
+ if (j0 < 0)
+ /* The magnitude of the number is < 1 so the result is +-0. */
+ SET_LDOUBLE_WORDS (x, sx, 0, 0);
+ else
+ SET_LDOUBLE_WORDS (x, se, i0 & ~(0x7fffffff >> j0), 0);
+ }
+ else if (j0 > 63)
+ {
+ if (j0 == 0x4000)
+ /* x is inf or NaN. */
+ return x + x;
+ }
+ else
+ {
+ SET_LDOUBLE_WORDS (x, se, i0, i1 & ~(0xffffffffu >> (j0 - 31)));
+ }
+
+ return x;
+}
+weak_alias (__truncl, truncl)
diff --git a/libc/sysdeps/ieee754/ldbl-96/strtold_l.c b/libc/sysdeps/ieee754/ldbl-96/strtold_l.c
new file mode 100644
index 000000000..52335c227
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/strtold_l.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1999, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+/* The actual implementation for all floating point sizes is in strtod.c.
+ These macros tell it to produce the `long double' version, `strtold'. */
+
+#define FLOAT long double
+#define FLT LDBL
+#ifdef USE_WIDE_CHAR
+# define STRTOF wcstold_l
+# define __STRTOF __wcstold_l
+#else
+# define STRTOF strtold_l
+# define __STRTOF __strtold_l
+#endif
+#define MPN2FLOAT __mpn_construct_long_double
+#define FLOAT_HUGE_VAL HUGE_VALL
+#define SET_MANTISSA(flt, mant) \
+ do { union ieee854_long_double u; \
+ u.d = (flt); \
+ if ((mant & 0x7fffffffffffffffULL) == 0) \
+ mant = 0x4000000000000000ULL; \
+ u.ieee.mantissa0 = (((mant) >> 32) & 0x7fffffff) | 0x80000000; \
+ u.ieee.mantissa1 = (mant) & 0xffffffff; \
+ (flt) = u.d; \
+ } while (0)
+
+#include <stdlib/strtod_l.c>
diff --git a/libc/sysdeps/ieee754/ldbl-96/w_expl.c b/libc/sysdeps/ieee754/ldbl-96/w_expl.c
new file mode 100644
index 000000000..b8152cea6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-96/w_expl.c
@@ -0,0 +1,60 @@
+/* w_expl.c -- long double version of w_exp.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@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: $";
+#endif
+
+/*
+ * wrapper expl(x)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double
+#else
+static long double
+#endif
+o_threshold= 1.135652340629414394949193107797076489134e4,
+ /* 0x400C, 0xB17217F7, 0xD1CF79AC */
+u_threshold= -1.140019167866942050398521670162263001513e4;
+ /* 0x400C, 0xB220C447, 0x69C201E8 */
+
+#ifdef __STDC__
+ long double __expl(long double x) /* wrapper exp */
+#else
+ long double __expl(x) /* wrapper exp */
+ long double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_expl(x);
+#else
+ long double z;
+ z = __ieee754_expl(x);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if(__finitel(x)) {
+ if(x>o_threshold)
+ return __kernel_standard(x,x,206); /* exp overflow */
+ else if(x<u_threshold)
+ return __kernel_standard(x,x,207); /* exp underflow */
+ }
+ return z;
+#endif
+}
+weak_alias (__expl, expl)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/Makefile b/libc/sysdeps/ieee754/ldbl-opt/Makefile
new file mode 100644
index 000000000..7f7bc3ce3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/Makefile
@@ -0,0 +1,43 @@
+# The`long double' type is a distinct type we support if
+# -mlong-double-128 option is used (or when it becomes a default
+# when -mlong-double-64 is not used).
+long-double-fcts = yes
+ifeq (,$(filter -mlong-double-128,$(sysdep-CFLAGS)))
+sysdep-CFLAGS += -mlong-double-128
+endif
+
+ifeq ($(subdir),math)
+libm-routines += s_nexttowardfd
+routines += math_ldbl_opt nldbl-compat
+
+extra-libs += libnldbl
+libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
+ obstack_printf obstack_vprintf printf scanf snprintf \
+ sprintf sscanf swprintf swscanf vasprintf vdprintf vfprintf \
+ vfscanf vfwprintf vfwscanf vprintf vscanf vsnprintf \
+ vsprintf vsscanf vswprintf vswscanf vwprintf vwscanf \
+ wprintf wscanf printf_fp printf_size \
+ fprintf_chk fwprintf_chk printf_chk snprintf_chk sprintf_chk \
+ swprintf_chk vfprintf_chk vfwprintf_chk vprintf_chk \
+ vsnprintf_chk vsprintf_chk vswprintf_chk vwprintf_chk \
+ wprintf_chk \
+ syslog syslog_chk vsyslog vsyslog_chk \
+ strfmon strfmon_l \
+ strtold strtold_l strtoldint wcstold wcstold_l wcstoldint \
+ qecvt qfcvt qgcvt qecvt_r qfcvt_r \
+ isinf isnan finite signbit scalb log2 lgamma_r ceil \
+ significand acos asin atan atan2 cos sin tan cosh sinh \
+ tanh acosh asinh atanh exp log log10 exp10 pow10 expm1 \
+ log1p logb exp2 sqrt cbrt fabs floor j0 j1 y0 y1 erf erfc \
+ lgamma tgamma gamma rint nearbyint round trunc \
+ copysign fdim fmax fmin nextafter pow hypot fmod drem \
+ remainder ldexp scalbn frexp modf scalbln fma nan sincos \
+ jn yn ilogb remquo lrint lround llrint llround nexttowardf \
+ nexttoward conj cacos cacosh casin catan catanh ccos ccosh \
+ casinh cexp clog cproj csin csinh csqrt ctan ctanh cpow \
+ cabs carg cimag creal clog10
+libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
+libnldbl-inhibit-o = $(object-suffixes)
+libnldbl-static-only-routines = $(libnldbl-routines)
+
+endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/Versions b/libc/sysdeps/ieee754/ldbl-opt/Versions
new file mode 100644
index 000000000..d22b18ec8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/Versions
@@ -0,0 +1,87 @@
+%include <nldbl-abi.h>
+%ifndef NLDBL_VERSION
+% error "nldbl-abi.h must define NLDBL_VERSION"
+%endif
+
+libc {
+ NLDBL_VERSION {
+ # IEEE quad long double functions (older symver is for
+ # IEEE double long double).
+ ldexpl; copysignl; finitel; frexpl; isinfl; isnanl; modfl;
+ __isinfl; __isnanl; __finitel; __signbitl;
+ scalbnl;
+ qecvt; qfcvt; qgcvt; qecvt_r; qfcvt_r;
+
+ strtold; __strtold_internal; wcstold; __wcstold_internal;
+ __strtold_l; strtold_l; __wcstold_l; wcstold_l;
+
+ strfmon; __strfmon_l; strfmon_l;
+ __nldbl_strfmon; __nldbl___strfmon_l; __nldbl_strfmon_l;
+ __nldbl___vstrfmon; __nldbl___vstrfmon_l;
+
+ syslog; vsyslog;
+ __nldbl_syslog; __nldbl_vsyslog;
+ __nldbl___syslog_chk; __nldbl___vsyslog_chk;
+
+ # *printf* family, using IEEE quad long double
+ __asprintf; asprintf; dprintf; fprintf; fwprintf; _IO_fprintf;
+ _IO_printf; _IO_sprintf; _IO_vfprintf; _IO_vsprintf; obstack_printf;
+ obstack_vprintf; printf; __printf_fp; printf_size; snprintf; sprintf;
+ swprintf; vasprintf; vdprintf; vfprintf; vfwprintf; vprintf; vsnprintf;
+ __vsnprintf; vsprintf; vswprintf; vwprintf; wprintf;
+
+ # *printf* family, using IEEE double as long double
+ # The standard functions are __REDIRECTed to these if -mlong-double-64
+ __nldbl___asprintf; __nldbl_asprintf; __nldbl_dprintf; __nldbl_fprintf;
+ __nldbl_fwprintf; __nldbl__IO_fprintf; __nldbl__IO_printf;
+ __nldbl__IO_sprintf; __nldbl__IO_vfprintf; __nldbl__IO_vsprintf;
+ __nldbl_obstack_printf; __nldbl_obstack_vprintf; __nldbl_printf;
+ __nldbl___printf_fp; __nldbl_printf_size; __nldbl_snprintf;
+ __nldbl_sprintf; __nldbl_swprintf; __nldbl_vasprintf; __nldbl_vdprintf;
+ __nldbl_vfprintf; __nldbl_vfwprintf; __nldbl_vprintf; __nldbl_vsnprintf;
+ __nldbl___vsnprintf; __nldbl_vsprintf; __nldbl_vswprintf;
+ __nldbl_vwprintf; __nldbl_wprintf;
+
+ # *scanf family, using IEEE quad long double
+ _IO_sscanf; _IO_vfscanf; __vfscanf; __vsscanf; fscanf; fwscanf; scanf;
+ sscanf; swscanf; vfscanf; vfwscanf; vscanf; vsscanf; vswscanf; vwscanf;
+ wscanf;
+
+ # *scanf family, using IEEE double as long double
+ __nldbl__IO_sscanf; __nldbl__IO_vfscanf; __nldbl___vfscanf;
+ __nldbl___vsscanf; __nldbl_fscanf; __nldbl_fwscanf; __nldbl_scanf;
+ __nldbl_sscanf; __nldbl_swscanf; __nldbl_vfscanf; __nldbl_vfwscanf;
+ __nldbl_vscanf; __nldbl_vsscanf; __nldbl_vswscanf; __nldbl_vwscanf;
+ __nldbl_wscanf;
+
+ # checking versions, using IEEE quad long double
+ __sprintf_chk; __vsprintf_chk; __snprintf_chk; __vsnprintf_chk;
+ __printf_chk; __fprintf_chk; __vprintf_chk; __vfprintf_chk;
+
+ # checking versions, using IEEE double as long double
+ __nldbl___sprintf_chk; __nldbl___vsprintf_chk; __nldbl___snprintf_chk;
+ __nldbl___vsnprintf_chk; __nldbl___printf_chk; __nldbl___fprintf_chk;
+ __nldbl___vprintf_chk; __nldbl___vfprintf_chk;
+ __nldbl___swprintf_chk; __nldbl___vswprintf_chk; __nldbl___fwprintf_chk;
+ __nldbl___wprintf_chk; __nldbl___vfwprintf_chk; __nldbl___vwprintf_chk;
+ }
+}
+libm {
+ NLDBL_VERSION {
+ # IEEE quad long double functions (older symver is for
+ # IEEE double as long double).
+ cabsl; cargl; cimagl; conjl; creall; cacosl; cacoshl; casinl;
+ catanl; catanhl; ccosl; ccoshl; casinhl; cexpl; clogl; __clog10l;
+ clog10l; cpowl; cprojl; csinl; csinhl; csqrtl; ctanl; ctanhl;
+ fdiml; fmal; fmaxl; fminl; ldexpl; nanl; nextafterl; nexttowardl;
+ significandl; acosl; acoshl; asinl; atan2l; atanhl; coshl; dreml;
+ exp10l; pow10l; exp2l; fmodl; hypotl; j0l; y0l; j1l; y1l; jnl; ynl;
+ lgammal; gammal; lgammal_r; logl; log10l; log2l; powl; remainderl;
+ scalbl; sinhl; sqrtl; tgammal; asinhl; atanl; cbrtl; ceill; copysignl;
+ erfl; erfcl; expm1l; fabsl; finitel; floorl; frexpl; ilogbl;
+ llrintl; llroundl; log1pl; logbl; lrintl; lroundl; modfl;
+ nearbyintl; remquol; rintl; roundl; scalblnl; scalbnl; sinl; cosl;
+ sincosl; tanl; tanhl; truncl; expl; __finitel; __signbitl;
+ __fpclassifyl; nexttowardf; nexttoward; __nldbl_nexttowardf;
+ }
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/cabs.c b/libc/sysdeps/ieee754/ldbl-opt/cabs.c
new file mode 100644
index 000000000..a181de2fa
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/cabs.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/cabs.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __cabs, cabsl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/cabsl.c b/libc/sysdeps/ieee754/ldbl-opt/cabsl.c
new file mode 100644
index 000000000..b86163354
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/cabsl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/cabsl.c>
+long_double_symbol (libm, __cabsl, cabsl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/carg.c b/libc/sysdeps/ieee754/ldbl-opt/carg.c
new file mode 100644
index 000000000..2ed358113
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/carg.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/carg.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __carg, cargl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/cargl.c b/libc/sysdeps/ieee754/ldbl-opt/cargl.c
new file mode 100644
index 000000000..952dc6066
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/cargl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/cargl.c>
+long_double_symbol (libm, __cargl, cargl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/cimag.c b/libc/sysdeps/ieee754/ldbl-opt/cimag.c
new file mode 100644
index 000000000..f8052581b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/cimag.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/cimag.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __cimag, cimagl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/cimagl.c b/libc/sysdeps/ieee754/ldbl-opt/cimagl.c
new file mode 100644
index 000000000..112365e3a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/cimagl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/cimagl.c>
+long_double_symbol (libm, __cimagl, cimagl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/configure b/libc/sysdeps/ieee754/ldbl-opt/configure
new file mode 100755
index 000000000..dc8136531
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/configure
@@ -0,0 +1,69 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/ieee754/ldbl-opt/.
+
+
+echo "$as_me:$LINENO: checking whether $CC $CFLAGS supports -mlong-double-128" >&5
+echo $ECHO_N "checking whether $CC $CFLAGS supports -mlong-double-128... $ECHO_C" >&6
+if test "${libc_cv_mlong_double_128+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -mlong-double-128"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+#ifndef __LONG_DOUBLE_128__
+# error "compiler did not predefine __LONG_DOUBLE_128__ as expected"
+#endif
+long double foobar (long double x) { return x; }
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_mlong_double_128=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+libc_cv_mlong_double_128=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+CFLAGS="$save_CFLAGS"
+fi
+echo "$as_me:$LINENO: result: $libc_cv_mlong_double_128" >&5
+echo "${ECHO_T}$libc_cv_mlong_double_128" >&6
+if test "$libc_cv_mlong_double_128" = no; then
+ { { echo "$as_me:$LINENO: error: this configuration requires -mlong-double-128 support" >&5
+echo "$as_me: error: this configuration requires -mlong-double-128 support" >&2;}
+ { (exit 1); exit 1; }; }
+fi
diff --git a/libc/sysdeps/ieee754/ldbl-opt/configure.in b/libc/sysdeps/ieee754/ldbl-opt/configure.in
new file mode 100644
index 000000000..a77fadd1c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/configure.in
@@ -0,0 +1,19 @@
+sinclude(./aclocal.m4)dnl Autoconf lossage
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/ieee754/ldbl-opt/.
+
+AC_CACHE_CHECK(whether $CC $CFLAGS supports -mlong-double-128,
+ libc_cv_mlong_double_128, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -mlong-double-128"
+AC_TRY_COMPILE(, [
+#ifndef __LONG_DOUBLE_128__
+# error "compiler did not predefine __LONG_DOUBLE_128__ as expected"
+#endif
+long double foobar (long double x) { return x; }],
+ libc_cv_mlong_double_128=yes,
+ libc_cv_mlong_double_128=no)
+CFLAGS="$save_CFLAGS"])
+if test "$libc_cv_mlong_double_128" = no; then
+ AC_MSG_ERROR([this configuration requires -mlong-double-128 support])
+fi
diff --git a/libc/sysdeps/ieee754/ldbl-opt/conj.c b/libc/sysdeps/ieee754/ldbl-opt/conj.c
new file mode 100644
index 000000000..e4edade05
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/conj.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/conj.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __conj, conjl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/conjl.c b/libc/sysdeps/ieee754/ldbl-opt/conjl.c
new file mode 100644
index 000000000..c98e0ed1c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/conjl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/conjl.c>
+long_double_symbol (libm, __conjl, conjl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/creal.c b/libc/sysdeps/ieee754/ldbl-opt/creal.c
new file mode 100644
index 000000000..0d1c93e64
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/creal.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/creal.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __creal, creall, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/creall.c b/libc/sysdeps/ieee754/ldbl-opt/creall.c
new file mode 100644
index 000000000..68fedd4cc
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/creall.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/creall.c>
+long_double_symbol (libm, __creall, creall);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.c b/libc/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.c
new file mode 100644
index 000000000..49c5c1249
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.c
@@ -0,0 +1,3 @@
+/* Set temporarily to non-zero if long double should be considered
+ the same as double. */
+__thread int __no_long_double attribute_tls_model_ie attribute_hidden;
diff --git a/libc/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h b/libc/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h
new file mode 100644
index 000000000..692b0c53c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h
@@ -0,0 +1,52 @@
+/* -mlong-double-64 compatibility mode macros. */
+
+#include <nldbl-abi.h>
+#ifndef LONG_DOUBLE_COMPAT_VERSION
+# error "nldbl-abi.h must define LONG_DOUBLE_COMPAT_VERSION"
+#endif
+
+#include <shlib-compat.h>
+#define LONG_DOUBLE_COMPAT(lib, introduced) \
+ SHLIB_COMPAT(lib, introduced, LONG_DOUBLE_COMPAT_VERSION)
+#define long_double_symbol(lib, local, symbol) \
+ long_double_symbol_1 (lib, local, symbol, LONG_DOUBLE_COMPAT_VERSION)
+#if defined HAVE_ELF && defined SHARED && defined DO_VERSIONING
+# define ldbl_hidden_def(local, name) libc_hidden_ver (local, name)
+# define ldbl_strong_alias(name, aliasname) \
+ strong_alias (name, __GL_##name##_##aliasname) \
+ long_double_symbol (libc, __GL_##name##_##aliasname, aliasname);
+# define ldbl_weak_alias(name, aliasname) \
+ weak_alias (name, __GL_##name##_##aliasname) \
+ long_double_symbol (libc, __GL_##name##_##aliasname, aliasname);
+# define long_double_symbol_1(lib, local, symbol, version) \
+ versioned_symbol (lib, local, symbol, version)
+#elif defined HAVE_WEAK_SYMBOLS
+# define ldbl_hidden_def(local, name) libc_hidden_def (name)
+# define ldbl_strong_alias(name, aliasname) strong_alias (name, aliasname)
+# define ldbl_weak_alias(name, aliasname) weak_alias (name, aliasname)
+# ifndef __ASSEMBLER__
+/* Note that weak_alias cannot be used - it is defined to nothing
+ in most of the C files. */
+# define long_double_symbol_1(lib, local, symbol, version) \
+ _weak_alias (local, symbol)
+# else
+# define long_double_symbol_1(lib, local, symbol, version) \
+ weak_alias (local, symbol)
+# endif
+#else
+# define ldbl_hidden_def(local, name) libc_hidden_def (name)
+# define ldbl_strong_alias(name, aliasname) strong_alias (name, aliasname)
+# define ldbl_weak_alias(name, aliasname) strong_alias (name, aliasname)
+# define long_double_symbol_1(lib, local, symbol, version) \
+ strong_alias (local, symbol)
+#endif
+
+#ifndef __ASSEMBLER__
+# include <math.h>
+# include <math/math_private.h>
+
+/* Set temporarily to non-zero if long double should be considered
+ the same as double. */
+extern __thread int __no_long_double attribute_tls_model_ie attribute_hidden;
+# define __ldbl_is_dbl __builtin_expect (__no_long_double, 0)
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-acos.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-acos.c
new file mode 100644
index 000000000..813a17e9d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-acos.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+acosl (double x)
+{
+ return acos (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-acosh.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-acosh.c
new file mode 100644
index 000000000..75508e30d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-acosh.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+acoshl (double x)
+{
+ return acosh (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-asin.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-asin.c
new file mode 100644
index 000000000..5bbe6cd99
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-asin.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+asinl (double x)
+{
+ return asin (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-asinh.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-asinh.c
new file mode 100644
index 000000000..512f68519
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-asinh.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+asinhl (double x)
+{
+ return asinh (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-asprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-asprintf.c
new file mode 100644
index 000000000..4be216d61
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-asprintf.c
@@ -0,0 +1,17 @@
+#include "nldbl-compat.h"
+
+attribute_hidden
+int
+__asprintf (char **string_ptr, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vasprintf (string_ptr, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+extern __typeof (__asprintf) asprintf attribute_hidden;
+weak_alias (__asprintf, asprintf)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-atan.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-atan.c
new file mode 100644
index 000000000..2849e48d0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-atan.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+atanl (double x)
+{
+ return atan (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-atan2.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-atan2.c
new file mode 100644
index 000000000..d4e5a9170
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-atan2.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+atan2l (double x, double y)
+{
+ return atan2 (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-atanh.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-atanh.c
new file mode 100644
index 000000000..82b54ca6d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-atanh.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+atanhl (double x)
+{
+ return atanh (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-cabs.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cabs.c
new file mode 100644
index 000000000..837822d2d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cabs.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double
+attribute_hidden
+cabsl (double _Complex x)
+{
+ return cabs (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-cacos.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cacos.c
new file mode 100644
index 000000000..d935b511b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cacos.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+cacosl (double _Complex x)
+{
+ return cacos (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-cacosh.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cacosh.c
new file mode 100644
index 000000000..67f994b84
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cacosh.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+cacoshl (double _Complex x)
+{
+ return cacosh (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-carg.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-carg.c
new file mode 100644
index 000000000..bfff141c1
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-carg.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double
+attribute_hidden
+cargl (double _Complex x)
+{
+ return carg (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-casin.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-casin.c
new file mode 100644
index 000000000..310aa0ac2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-casin.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+casinl (double _Complex x)
+{
+ return casin (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-casinh.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-casinh.c
new file mode 100644
index 000000000..71b466ea2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-casinh.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+casinhl (double _Complex x)
+{
+ return casinh (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-catan.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-catan.c
new file mode 100644
index 000000000..ea5f528ee
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-catan.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+catanl (double _Complex x)
+{
+ return catan (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-catanh.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-catanh.c
new file mode 100644
index 000000000..e6f58aa04
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-catanh.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+catanhl (double _Complex x)
+{
+ return catanh (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-cbrt.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cbrt.c
new file mode 100644
index 000000000..1c353a6e6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cbrt.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+cbrtl (double x)
+{
+ return cbrt (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-ccos.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ccos.c
new file mode 100644
index 000000000..0e1c2e70f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ccos.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+ccosl (double _Complex x)
+{
+ return ccos (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-ccosh.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ccosh.c
new file mode 100644
index 000000000..da2bf580a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ccosh.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+ccoshl (double _Complex x)
+{
+ return ccosh (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-ceil.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ceil.c
new file mode 100644
index 000000000..a8fc3d548
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ceil.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+ceill (double x)
+{
+ return ceil (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-cexp.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cexp.c
new file mode 100644
index 000000000..f1837afc2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cexp.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+cexpl (double _Complex x)
+{
+ return cexp (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-cimag.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cimag.c
new file mode 100644
index 000000000..fffbdd58e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cimag.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double
+attribute_hidden
+cimagl (double _Complex x)
+{
+ return cimag (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-clog.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-clog.c
new file mode 100644
index 000000000..ecbae7ba9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-clog.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+clogl (double _Complex x)
+{
+ return clog (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-clog10.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-clog10.c
new file mode 100644
index 000000000..193f40104
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-clog10.c
@@ -0,0 +1,11 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+clog10l (double _Complex x)
+{
+ return clog10 (x);
+}
+extern __typeof (clog10l) __clog10l attribute_hidden;
+weak_alias (clog10l, __clog10l)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
new file mode 100644
index 000000000..f82c5f60b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
@@ -0,0 +1,852 @@
+/* *printf* family compatibility routines for IEEE double as long double
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@cygnus.com>, 2006.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <libioP.h>
+#include <wchar.h>
+#include <printf.h>
+#include <monetary.h>
+#include <locale/localeinfo.h>
+#include <sys/syslog.h>
+#include <bits/libc-lock.h>
+
+#include "nldbl-compat.h"
+
+libc_hidden_proto (__nldbl_vfprintf)
+libc_hidden_proto (__nldbl_vsscanf)
+libc_hidden_proto (__nldbl_vsprintf)
+libc_hidden_proto (__nldbl_vfscanf)
+libc_hidden_proto (__nldbl_vfwscanf)
+libc_hidden_proto (__nldbl_vdprintf)
+libc_hidden_proto (__nldbl_vswscanf)
+libc_hidden_proto (__nldbl_vfwprintf)
+libc_hidden_proto (__nldbl_vswprintf)
+libc_hidden_proto (__nldbl_vsnprintf)
+libc_hidden_proto (__nldbl_vasprintf)
+libc_hidden_proto (__nldbl_obstack_vprintf)
+libc_hidden_proto (__nldbl___vfwprintf_chk)
+libc_hidden_proto (__nldbl___vsnprintf_chk)
+libc_hidden_proto (__nldbl___vfprintf_chk)
+libc_hidden_proto (__nldbl___vsyslog_chk)
+libc_hidden_proto (__nldbl___vsprintf_chk)
+libc_hidden_proto (__nldbl___vswprintf_chk)
+libc_hidden_proto (__nldbl___vstrfmon)
+libc_hidden_proto (__nldbl___vstrfmon_l)
+
+static void
+__nldbl_cleanup (void *arg)
+{
+ __no_long_double = 0;
+}
+
+#define set_no_long_double() \
+ __libc_cleanup_push (__nldbl_cleanup, NULL); __no_long_double = 1
+#define clear_no_long_double() \
+ __no_long_double = 0; __libc_cleanup_pop (0)
+
+/* Compatibility with IEEE double as long double.
+ IEEE quad long double is used by default for most programs, so
+ we don't need to split this into one file per function for the
+ sake of statically linked programs. */
+
+int
+attribute_compat_text_section
+__nldbl___asprintf (char **string_ptr, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vasprintf (string_ptr, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+weak_alias (__nldbl___asprintf, __nldbl_asprintf)
+
+int
+attribute_compat_text_section
+__nldbl_dprintf (int d, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vdprintf (d, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl_fprintf (FILE *stream, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfprintf (stream, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+weak_alias (__nldbl_fprintf, __nldbl__IO_fprintf)
+
+int
+attribute_compat_text_section weak_function
+__nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfwprintf (stream, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl_printf (const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfprintf (stdout, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+strong_alias (__nldbl_printf, __nldbl__IO_printf)
+
+int
+attribute_compat_text_section
+__nldbl_sprintf (char *s, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vsprintf (s, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+strong_alias (__nldbl_sprintf, __nldbl__IO_sprintf)
+
+int
+attribute_compat_text_section
+__nldbl_vfprintf (FILE *s, const char *fmt, va_list ap)
+{
+ int done;
+ set_no_long_double ();
+ done = INTUSE(_IO_vfprintf) (s, fmt, ap);
+ clear_no_long_double ();
+ return done;
+}
+libc_hidden_def (__nldbl_vfprintf)
+strong_alias (__nldbl_vfprintf, __nldbl__IO_vfprintf)
+
+int
+attribute_compat_text_section
+__nldbl__IO_vsprintf (char *string, const char *fmt, va_list ap)
+{
+ int done;
+ __no_long_double = 1;
+ done = INTUSE(_IO_vsprintf) (string, fmt, ap);
+ __no_long_double = 0;
+ return done;
+}
+weak_alias (__nldbl__IO_vsprintf, __nldbl_vsprintf)
+libc_hidden_def (__nldbl_vsprintf)
+
+int
+attribute_compat_text_section
+__nldbl_obstack_vprintf (struct obstack *obstack, const char *fmt,
+ va_list ap)
+{
+ int done;
+ __no_long_double = 1;
+ done = _IO_obstack_vprintf (obstack, fmt, ap);
+ __no_long_double = 0;
+ return done;
+}
+libc_hidden_def (__nldbl_obstack_vprintf)
+
+int
+attribute_compat_text_section
+__nldbl_obstack_printf (struct obstack *obstack, const char *fmt, ...)
+{
+ int result;
+ va_list ap;
+ va_start (ap, fmt);
+ result = __nldbl_obstack_vprintf (obstack, fmt, ap);
+ va_end (ap);
+ return result;
+}
+
+int
+attribute_compat_text_section weak_function
+__nldbl_snprintf (char *s, size_t maxlen, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vsnprintf (s, maxlen, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vswprintf (s, n, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section weak_function
+__nldbl_vasprintf (char **result_ptr, const char *fmt, va_list ap)
+{
+ int res;
+ __no_long_double = 1;
+ res = _IO_vasprintf (result_ptr, fmt, ap);
+ __no_long_double = 0;
+ return res;
+}
+libc_hidden_def (__nldbl_vasprintf)
+
+int
+attribute_compat_text_section
+__nldbl_vdprintf (int d, const char *fmt, va_list arg)
+{
+ int res;
+ set_no_long_double ();
+ res = _IO_vdprintf (d, fmt, arg);
+ clear_no_long_double ();
+ return res;
+}
+libc_hidden_def (__nldbl_vdprintf)
+
+int
+attribute_compat_text_section weak_function
+__nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap)
+{
+ int res;
+ set_no_long_double ();
+ res = _IO_vfwprintf (s, fmt, ap);
+ clear_no_long_double ();
+ return res;
+}
+libc_hidden_def (__nldbl_vfwprintf)
+
+int
+attribute_compat_text_section
+__nldbl_vprintf (const char *fmt, va_list ap)
+{
+ return __nldbl_vfprintf (stdout, fmt, ap);
+}
+
+int
+attribute_compat_text_section
+__nldbl_vsnprintf (char *string, size_t maxlen, const char *fmt,
+ va_list ap)
+{
+ int res;
+ __no_long_double = 1;
+ res = _IO_vsnprintf (string, maxlen, fmt, ap);
+ __no_long_double = 0;
+ return res;
+}
+libc_hidden_def (__nldbl_vsnprintf)
+weak_alias (__nldbl_vsnprintf, __nldbl___vsnprintf)
+
+int
+attribute_compat_text_section weak_function
+__nldbl_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt,
+ va_list ap)
+{
+ int res;
+ __no_long_double = 1;
+ res = _IO_vswprintf (string, maxlen, fmt, ap);
+ __no_long_double = 0;
+ return res;
+}
+libc_hidden_def (__nldbl_vswprintf)
+
+int
+attribute_compat_text_section
+__nldbl_vwprintf (const wchar_t *fmt, va_list ap)
+{
+ return __nldbl_vfwprintf (stdout, fmt, ap);
+}
+
+int
+attribute_compat_text_section
+__nldbl_wprintf (const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfwprintf (stdout, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl__IO_vfscanf (FILE *s, const char *fmt, _IO_va_list ap,
+ int *errp)
+{
+ int res;
+ set_no_long_double ();
+ res = INTUSE(_IO_vfscanf) (s, fmt, ap, errp);
+ clear_no_long_double ();
+ return res;
+}
+
+int
+attribute_compat_text_section
+__nldbl___vfscanf (FILE *s, const char *fmt, va_list ap)
+{
+ int res;
+ set_no_long_double ();
+ res = INTUSE(_IO_vfscanf) (s, fmt, ap, NULL);
+ clear_no_long_double ();
+ return res;
+}
+weak_alias (__nldbl___vfscanf, __nldbl_vfscanf)
+libc_hidden_def (__nldbl_vfscanf)
+
+int
+attribute_compat_text_section
+__nldbl_sscanf (const char *s, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vsscanf (s, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+strong_alias (__nldbl_sscanf, __nldbl__IO_sscanf)
+
+int
+attribute_compat_text_section
+__nldbl___vsscanf (const char *string, const char *fmt, va_list ap)
+{
+ int res;
+ __no_long_double = 1;
+ res = _IO_vsscanf (string, fmt, ap);
+ __no_long_double = 0;
+ return res;
+}
+weak_alias (__nldbl___vsscanf, __nldbl_vsscanf)
+libc_hidden_def (__nldbl_vsscanf)
+
+int
+attribute_compat_text_section weak_function
+__nldbl_vscanf (const char *fmt, va_list ap)
+{
+ return __nldbl_vfscanf (stdin, fmt, ap);
+}
+
+int
+attribute_compat_text_section
+__nldbl_fscanf (FILE *stream, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfscanf (stream, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl_scanf (const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfscanf (stdin, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
+{
+ int res;
+ set_no_long_double ();
+ res = _IO_vfwscanf (s, fmt, ap, NULL);
+ clear_no_long_double ();
+ return res;
+}
+libc_hidden_def (__nldbl_vfwscanf)
+
+int
+attribute_compat_text_section
+__nldbl_swscanf (const wchar_t *s, const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vswscanf (s, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl_vswscanf (const wchar_t *string, const wchar_t *fmt, va_list ap)
+{
+ int res;
+ __no_long_double = 1;
+ res = vswscanf (string, fmt, ap);
+ __no_long_double = 0;
+ return res;
+}
+libc_hidden_def (__nldbl_vswscanf)
+
+int
+attribute_compat_text_section weak_function
+__nldbl_vwscanf (const wchar_t *fmt, va_list ap)
+{
+ return __nldbl_vfwscanf (stdin, fmt, ap);
+}
+
+int
+attribute_compat_text_section
+__nldbl_fwscanf (FILE *stream, const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfwscanf (stream, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl_wscanf (const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfwscanf (stdin, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl___fprintf_chk (FILE *stream, int flag, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vfprintf_chk (stream, flag, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vfwprintf_chk (stream, flag, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl___printf_chk (int flag, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vfprintf_chk (stdout, flag, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl___snprintf_chk (char *s, size_t maxlen, int flag, size_t slen,
+ const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vsnprintf_chk (s, maxlen, flag, slen, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl___sprintf_chk (char *s, int flag, size_t slen, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vsprintf_chk (s, flag, slen, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen,
+ const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vswprintf_chk (s, n, flag, slen, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+int
+attribute_compat_text_section
+__nldbl___vfprintf_chk (FILE *s, int flag, const char *fmt, va_list ap)
+{
+ int res;
+ set_no_long_double ();
+ res = __vfprintf_chk (s, flag, fmt, ap);
+ clear_no_long_double ();
+ return res;
+}
+libc_hidden_def (__nldbl___vfprintf_chk)
+
+int
+attribute_compat_text_section
+__nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap)
+{
+ int res;
+ set_no_long_double ();
+ res = __vfwprintf_chk (s, flag, fmt, ap);
+ clear_no_long_double ();
+ return res;
+}
+libc_hidden_def (__nldbl___vfwprintf_chk)
+
+int
+attribute_compat_text_section
+__nldbl___vprintf_chk (int flag, const char *fmt, va_list ap)
+{
+ return __nldbl___vfprintf_chk (stdout, flag, fmt, ap);
+}
+
+int
+attribute_compat_text_section
+__nldbl___vsnprintf_chk (char *string, size_t maxlen, int flag, size_t slen,
+ const char *fmt, va_list ap)
+{
+ int res;
+ __no_long_double = 1;
+ res = __vsnprintf_chk (string, maxlen, flag, slen, fmt, ap);
+ __no_long_double = 0;
+ return res;
+}
+libc_hidden_def (__nldbl___vsnprintf_chk)
+
+int
+attribute_compat_text_section
+__nldbl___vsprintf_chk (char *string, int flag, size_t slen, const char *fmt,
+ va_list ap)
+{
+ int res;
+ __no_long_double = 1;
+ res = __vsprintf_chk (string, flag, slen, fmt, ap);
+ __no_long_double = 0;
+ return res;
+}
+libc_hidden_def (__nldbl___vsprintf_chk)
+
+int
+attribute_compat_text_section
+__nldbl___vswprintf_chk (wchar_t *string, size_t maxlen, int flag, size_t slen,
+ const wchar_t *fmt, va_list ap)
+{
+ int res;
+ __no_long_double = 1;
+ res = __vswprintf_chk (string, maxlen, flag, slen, fmt, ap);
+ __no_long_double = 0;
+ return res;
+}
+libc_hidden_def (__nldbl___vswprintf_chk)
+
+int
+attribute_compat_text_section
+__nldbl___vwprintf_chk (int flag, const wchar_t *fmt, va_list ap)
+{
+ return __nldbl___vfwprintf_chk (stdout, flag, fmt, ap);
+}
+
+int
+attribute_compat_text_section
+__nldbl___wprintf_chk (int flag, const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vfwprintf_chk (stdout, flag, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+
+extern __typeof (printf_size) __printf_size;
+
+int
+attribute_compat_text_section
+__nldbl_printf_size (FILE *fp, const struct printf_info *info,
+ const void *const *args)
+{
+ struct printf_info info_no_ldbl = *info;
+
+ info_no_ldbl.is_long_double = 0;
+ return __printf_size (fp, &info_no_ldbl, args);
+}
+
+extern __typeof (__printf_fp) ___printf_fp;
+
+int
+attribute_compat_text_section
+__nldbl___printf_fp (FILE *fp, const struct printf_info *info,
+ const void *const *args)
+{
+ struct printf_info info_no_ldbl = *info;
+
+ info_no_ldbl.is_long_double = 0;
+ return ___printf_fp (fp, &info_no_ldbl, args);
+}
+
+ssize_t
+attribute_compat_text_section
+__nldbl_strfmon (char *s, size_t maxsize, const char *format, ...)
+{
+ va_list ap;
+ ssize_t res;
+
+ va_start (ap, format);
+ res = __nldbl___vstrfmon (s, maxsize, format, ap);
+ va_end (ap);
+ return res;
+}
+
+ssize_t
+attribute_compat_text_section
+__nldbl___strfmon_l (char *s, size_t maxsize, __locale_t loc,
+ const char *format, ...)
+{
+ va_list ap;
+ ssize_t res;
+
+ va_start (ap, format);
+ res = __nldbl___vstrfmon_l (s, maxsize, loc, format, ap);
+ va_end (ap);
+ return res;
+}
+weak_alias (__nldbl___strfmon_l, __nldbl_strfmon_l)
+
+ssize_t
+attribute_compat_text_section
+__nldbl___vstrfmon (char *s, size_t maxsize, const char *format, va_list ap)
+{
+ ssize_t res;
+ __no_long_double = 1;
+ res = __vstrfmon_l (s, maxsize, _NL_CURRENT_LOCALE, format, ap);
+ __no_long_double = 0;
+ va_end (ap);
+ return res;
+}
+libc_hidden_def (__nldbl___vstrfmon)
+
+ssize_t
+attribute_compat_text_section
+__nldbl___vstrfmon_l (char *s, size_t maxsize, __locale_t loc,
+ const char *format, va_list ap)
+{
+ ssize_t res;
+ __no_long_double = 1;
+ res = __vstrfmon_l (s, maxsize, loc, format, ap);
+ __no_long_double = 0;
+ va_end (ap);
+ return res;
+}
+libc_hidden_def (__nldbl___vstrfmon_l)
+
+void
+attribute_compat_text_section
+__nldbl_syslog (int pri, const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ __nldbl___vsyslog_chk (pri, -1, fmt, ap);
+ va_end (ap);
+}
+
+void
+attribute_compat_text_section
+__nldbl___syslog_chk (int pri, int flag, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ __nldbl___vsyslog_chk (pri, flag, fmt, ap);
+ va_end(ap);
+}
+
+void
+attribute_compat_text_section
+__nldbl___vsyslog_chk (int pri, int flag, const char *fmt, va_list ap)
+{
+ set_no_long_double ();
+ __vsyslog_chk (pri, flag, fmt, ap);
+ clear_no_long_double ();
+}
+libc_hidden_def (__nldbl___vsyslog_chk)
+
+void
+attribute_compat_text_section
+__nldbl_vsyslog (int pri, const char *fmt, va_list ap)
+{
+ __nldbl___vsyslog_chk (pri, -1, fmt, ap);
+}
+
+#if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __nldbl__IO_printf, _IO_printf, GLIBC_2_0);
+compat_symbol (libc, __nldbl__IO_sprintf, _IO_sprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl__IO_vfprintf, _IO_vfprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl__IO_vsprintf, _IO_vsprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_dprintf, dprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_fprintf, fprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_printf, printf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_sprintf, sprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_vfprintf, vfprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_vprintf, vprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl__IO_fprintf, _IO_fprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl___vsnprintf, __vsnprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_asprintf, asprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_obstack_printf, obstack_printf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_obstack_vprintf, obstack_vprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_snprintf, snprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_vasprintf, vasprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_vdprintf, vdprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_vsnprintf, vsnprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_vsprintf, vsprintf, GLIBC_2_0);
+compat_symbol (libc, __nldbl__IO_sscanf, _IO_sscanf, GLIBC_2_0);
+compat_symbol (libc, __nldbl__IO_vfscanf, _IO_vfscanf, GLIBC_2_0);
+compat_symbol (libc, __nldbl___vfscanf, __vfscanf, GLIBC_2_0);
+compat_symbol (libc, __nldbl___vsscanf, __vsscanf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_fscanf, fscanf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_scanf, scanf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_sscanf, sscanf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_vfscanf, vfscanf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_vscanf, vscanf, GLIBC_2_0);
+compat_symbol (libc, __nldbl_vsscanf, vsscanf, GLIBC_2_0);
+compat_symbol (libc, __nldbl___printf_fp, __printf_fp, GLIBC_2_0);
+compat_symbol (libc, __nldbl_strfmon, strfmon, GLIBC_2_0);
+compat_symbol (libc, __nldbl_syslog, syslog, GLIBC_2_0);
+compat_symbol (libc, __nldbl_vsyslog, vsyslog, GLIBC_2_0);
+#endif
+#if LONG_DOUBLE_COMPAT(libc, GLIBC_2_1)
+compat_symbol (libc, __nldbl___asprintf, __asprintf, GLIBC_2_1);
+compat_symbol (libc, __nldbl_printf_size, printf_size, GLIBC_2_1);
+compat_symbol (libc, __nldbl___strfmon_l, __strfmon_l, GLIBC_2_1);
+#endif
+#if LONG_DOUBLE_COMPAT(libc, GLIBC_2_2)
+compat_symbol (libc, __nldbl_swprintf, swprintf, GLIBC_2_2);
+compat_symbol (libc, __nldbl_vwprintf, vwprintf, GLIBC_2_2);
+compat_symbol (libc, __nldbl_wprintf, wprintf, GLIBC_2_2);
+compat_symbol (libc, __nldbl_fwprintf, fwprintf, GLIBC_2_2);
+compat_symbol (libc, __nldbl_vfwprintf, vfwprintf, GLIBC_2_2);
+compat_symbol (libc, __nldbl_vswprintf, vswprintf, GLIBC_2_2);
+compat_symbol (libc, __nldbl_fwscanf, fwscanf, GLIBC_2_2);
+compat_symbol (libc, __nldbl_swscanf, swscanf, GLIBC_2_2);
+compat_symbol (libc, __nldbl_vfwscanf, vfwscanf, GLIBC_2_2);
+compat_symbol (libc, __nldbl_vswscanf, vswscanf, GLIBC_2_2);
+compat_symbol (libc, __nldbl_vwscanf, vwscanf, GLIBC_2_2);
+compat_symbol (libc, __nldbl_wscanf, wscanf, GLIBC_2_2);
+#endif
+#if LONG_DOUBLE_COMPAT(libc, GLIBC_2_3)
+compat_symbol (libc, __nldbl_strfmon_l, strfmon_l, GLIBC_2_3);
+#endif
+#if LONG_DOUBLE_COMPAT(libc, GLIBC_2_3_4)
+compat_symbol (libc, __nldbl___sprintf_chk, __sprintf_chk, GLIBC_2_3_4);
+compat_symbol (libc, __nldbl___vsprintf_chk, __vsprintf_chk, GLIBC_2_3_4);
+compat_symbol (libc, __nldbl___snprintf_chk, __snprintf_chk, GLIBC_2_3_4);
+compat_symbol (libc, __nldbl___vsnprintf_chk, __vsnprintf_chk, GLIBC_2_3_4);
+compat_symbol (libc, __nldbl___printf_chk, __printf_chk, GLIBC_2_3_4);
+compat_symbol (libc, __nldbl___fprintf_chk, __fprintf_chk, GLIBC_2_3_4);
+compat_symbol (libc, __nldbl___vprintf_chk, __vprintf_chk, GLIBC_2_3_4);
+compat_symbol (libc, __nldbl___vfprintf_chk, __vfprintf_chk, GLIBC_2_3_4);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-compat.h b/libc/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
new file mode 100644
index 000000000..c0461000f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
@@ -0,0 +1,87 @@
+/* Prototypes for compatibility double == long double entry points.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@cygnus.com>, 2006.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __NLDBL_COMPAT_H
+#define __NLDBL_COMPAT_H 1
+
+/* Avoid long double prototypes. */
+#define __NO_LONG_DOUBLE_MATH 1
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <printf.h>
+#include <wchar.h>
+#include <math.h>
+#include <monetary.h>
+#include <sys/syslog.h>
+
+
+/* Declare the __nldbl_NAME function the wrappers call that's in libc.so. */
+#define NLDBL_DECL(name) extern __typeof (name) __nldbl_##name
+
+NLDBL_DECL (_IO_vfscanf);
+NLDBL_DECL (vfscanf);
+NLDBL_DECL (vfwscanf);
+NLDBL_DECL (obstack_vprintf);
+NLDBL_DECL (vasprintf);
+NLDBL_DECL (dprintf);
+NLDBL_DECL (vdprintf);
+NLDBL_DECL (fprintf);
+NLDBL_DECL (vfprintf);
+NLDBL_DECL (vfwprintf);
+NLDBL_DECL (vsnprintf);
+NLDBL_DECL (vsprintf);
+NLDBL_DECL (vsscanf);
+NLDBL_DECL (vswprintf);
+NLDBL_DECL (vswscanf);
+NLDBL_DECL (__asprintf);
+NLDBL_DECL (asprintf);
+NLDBL_DECL (__printf_fp);
+NLDBL_DECL (printf_size);
+NLDBL_DECL (syslog);
+NLDBL_DECL (vsyslog);
+NLDBL_DECL (qecvt);
+NLDBL_DECL (qfcvt);
+NLDBL_DECL (qgcvt);
+NLDBL_DECL (__vstrfmon_l);
+
+/* This one does not exist in the normal interface, only
+ __nldbl___vstrfmon really exists. */
+extern ssize_t __nldbl___vstrfmon (char *, size_t, const char *, va_list)
+ __THROW;
+
+/* These don't use __typeof because they were not declared by the headers,
+ since we don't compile with _FORTIFY_SOURCE. */
+extern int __nldbl___vfprintf_chk (FILE *__restrict, int,
+ const char *__restrict, _G_va_list);
+extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
+ const wchar_t *__restrict, __gnuc_va_list);
+extern int __nldbl___vsprintf_chk (char *__restrict, int, size_t,
+ const char *__restrict, _G_va_list) __THROW;
+extern int __nldbl___vsnprintf_chk (char *__restrict, size_t, int, size_t,
+ const char *__restrict, _G_va_list)
+ __THROW;
+extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
+ const wchar_t *__restrict, __gnuc_va_list)
+ __THROW;
+extern void __nldbl___vsyslog_chk (int, int, const char *, va_list);
+
+
+#endif /* __NLDBL_COMPAT_H */
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-conj.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-conj.c
new file mode 100644
index 000000000..8927ea996
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-conj.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+conjl (double _Complex x)
+{
+ return conj (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-copysign.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-copysign.c
new file mode 100644
index 000000000..ef23badec
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-copysign.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+copysignl (double x, double y)
+{
+ return copysign (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-cos.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cos.c
new file mode 100644
index 000000000..08738af04
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cos.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+cosl (double x)
+{
+ return cos (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-cosh.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cosh.c
new file mode 100644
index 000000000..0ab834ffd
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cosh.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+coshl (double x)
+{
+ return cosh (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-cpow.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cpow.c
new file mode 100644
index 000000000..709e7d73b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cpow.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+cpowl (double _Complex x, double _Complex y)
+{
+ return cpow (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-cproj.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cproj.c
new file mode 100644
index 000000000..6f88b88bf
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-cproj.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+cprojl (double _Complex x)
+{
+ return cproj (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-creal.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-creal.c
new file mode 100644
index 000000000..b02ce6e5e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-creal.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double
+attribute_hidden
+creall (double _Complex x)
+{
+ return creal (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-csin.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-csin.c
new file mode 100644
index 000000000..b2e2c9c8e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-csin.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+csinl (double _Complex x)
+{
+ return csin (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-csinh.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-csinh.c
new file mode 100644
index 000000000..2bcba920e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-csinh.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+csinhl (double _Complex x)
+{
+ return csinh (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-csqrt.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-csqrt.c
new file mode 100644
index 000000000..ae00a2988
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-csqrt.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+csqrtl (double _Complex x)
+{
+ return csqrt (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-ctan.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ctan.c
new file mode 100644
index 000000000..422c5cce9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ctan.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+ctanl (double _Complex x)
+{
+ return ctan (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-ctanh.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ctanh.c
new file mode 100644
index 000000000..f3842ed26
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ctanh.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+#include <complex.h>
+
+double _Complex
+attribute_hidden
+ctanhl (double _Complex x)
+{
+ return ctanh (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-dprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-dprintf.c
new file mode 100644
index 000000000..6e26db2a2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-dprintf.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+attribute_hidden
+int
+dprintf (int d, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vdprintf (d, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-drem.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-drem.c
new file mode 100644
index 000000000..1e08ce1d2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-drem.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+dreml (double x, double y)
+{
+ return drem (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-erf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-erf.c
new file mode 100644
index 000000000..0032c1feb
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-erf.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+erfl (double x)
+{
+ return erf (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-erfc.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-erfc.c
new file mode 100644
index 000000000..21d09680a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-erfc.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+erfcl (double x)
+{
+ return erfc (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-exp.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-exp.c
new file mode 100644
index 000000000..ad2c89b6d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-exp.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+expl (double x)
+{
+ return exp (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-exp10.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-exp10.c
new file mode 100644
index 000000000..2d0ead686
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-exp10.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+exp10l (double x)
+{
+ return exp10 (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-exp2.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-exp2.c
new file mode 100644
index 000000000..d5fce3970
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-exp2.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+exp2l (double x)
+{
+ return exp2 (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-expm1.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-expm1.c
new file mode 100644
index 000000000..be5c6e51c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-expm1.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+expm1l (double x)
+{
+ return expm1 (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-fabs.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fabs.c
new file mode 100644
index 000000000..10729a6ec
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fabs.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+fabsl (double x)
+{
+ return fabs (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-fdim.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fdim.c
new file mode 100644
index 000000000..72896b63e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fdim.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+fdiml (double x, double y)
+{
+ return fdim (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-finite.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-finite.c
new file mode 100644
index 000000000..000adfb8a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-finite.c
@@ -0,0 +1,10 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__finitel (double x)
+{
+ return __finite (x);
+}
+extern __typeof (__finitel) finitel attribute_hidden;
+weak_alias (__finitel, finitel)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-floor.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-floor.c
new file mode 100644
index 000000000..c7e9f834b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-floor.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+floorl (double x)
+{
+ return floor (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-fma.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fma.c
new file mode 100644
index 000000000..947448367
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fma.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+fmal (double x, double y, double z)
+{
+ return fma (x, y, z);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-fmax.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fmax.c
new file mode 100644
index 000000000..f5a84776e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fmax.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+fmaxl (double x, double y)
+{
+ return fmax (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-fmin.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fmin.c
new file mode 100644
index 000000000..a353cf948
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fmin.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+fminl (double x, double y)
+{
+ return fmin (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-fmod.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fmod.c
new file mode 100644
index 000000000..aa692b9f3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fmod.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+fmodl (double x, double y)
+{
+ return fmod (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-fprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fprintf.c
new file mode 100644
index 000000000..9df4c4bc3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fprintf.c
@@ -0,0 +1,17 @@
+#include "nldbl-compat.h"
+
+attribute_hidden
+int
+fprintf (FILE *stream, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfprintf (stream, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+extern __typeof (fprintf) _IO_fprintf attribute_hidden;
+weak_alias (fprintf, _IO_fprintf)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-fprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fprintf_chk.c
new file mode 100644
index 000000000..43a761818
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fprintf_chk.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__fprintf_chk (FILE *stream, int flag, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vfprintf_chk (stream, flag, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-frexp.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-frexp.c
new file mode 100644
index 000000000..0ec97e10e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-frexp.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+frexpl (double x, int *exponent)
+{
+ return frexp (x, exponent);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c
new file mode 100644
index 000000000..1b768e306
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fscanf.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+fscanf (FILE *stream, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl__IO_vfscanf (stream, fmt, arg, NULL);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-fwprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fwprintf.c
new file mode 100644
index 000000000..18362af01
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fwprintf.c
@@ -0,0 +1,16 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+weak_function
+fwprintf (FILE *stream, const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfwprintf (stream, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-fwprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fwprintf_chk.c
new file mode 100644
index 000000000..09731cf29
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fwprintf_chk.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vfwprintf_chk (stream, flag, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c
new file mode 100644
index 000000000..27fc1a727
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-fwscanf.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+fwscanf (FILE *stream, const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfwscanf (stream, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-gamma.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-gamma.c
new file mode 100644
index 000000000..10dc640b9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-gamma.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+gammal (double x)
+{
+ return gamma (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-hypot.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-hypot.c
new file mode 100644
index 000000000..2105f3eba
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-hypot.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+hypotl (double x, double y)
+{
+ return hypot (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-ilogb.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ilogb.c
new file mode 100644
index 000000000..e840b2a44
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ilogb.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+ilogbl (double x)
+{
+ return ilogb (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c
new file mode 100644
index 000000000..05581c035
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-iovfscanf.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+_IO_vfscanf (FILE *s, const char *fmt, _IO_va_list ap, int *errp)
+{
+ return __nldbl__IO_vfscanf (s, fmt, ap, errp);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-isinf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-isinf.c
new file mode 100644
index 000000000..340d2418c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-isinf.c
@@ -0,0 +1,10 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__isinfl (double x)
+{
+ return __isinf (x);
+}
+extern __typeof (__isinfl) isinfl attribute_hidden;
+weak_alias (__isinfl, isinfl)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-isnan.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-isnan.c
new file mode 100644
index 000000000..e5f0f1b39
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-isnan.c
@@ -0,0 +1,10 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__isnanl (double x)
+{
+ return __isnan (x);
+}
+extern __typeof (__isnanl) isnanl attribute_hidden;
+weak_alias (__isnanl, isnanl)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-j0.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-j0.c
new file mode 100644
index 000000000..9d59f0a01
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-j0.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+j0l (double x)
+{
+ return j0 (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-j1.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-j1.c
new file mode 100644
index 000000000..dba736686
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-j1.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+j1l (double x)
+{
+ return j1 (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-jn.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-jn.c
new file mode 100644
index 000000000..3f19bbb1a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-jn.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+jnl (int n, double x)
+{
+ return jn (n, x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-ldexp.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ldexp.c
new file mode 100644
index 000000000..360f8f0f6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-ldexp.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+ldexpl (double x, int exponent)
+{
+ return ldexp (x, exponent);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-lgamma.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-lgamma.c
new file mode 100644
index 000000000..005521262
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-lgamma.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+lgammal (double x)
+{
+ return lgamma (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-lgamma_r.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-lgamma_r.c
new file mode 100644
index 000000000..e1ab9a1d0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-lgamma_r.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+lgammal_r (double x, int *signgamp)
+{
+ return lgamma_r (x, signgamp);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-llrint.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-llrint.c
new file mode 100644
index 000000000..6dfce89d0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-llrint.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+long long int
+attribute_hidden
+llrintl (double x)
+{
+ return llrint (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-llround.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-llround.c
new file mode 100644
index 000000000..0157a079f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-llround.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+long long int
+attribute_hidden
+llroundl (double x)
+{
+ return llround (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-log.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-log.c
new file mode 100644
index 000000000..a5a1ae7cd
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-log.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+logl (double x)
+{
+ return log (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-log10.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-log10.c
new file mode 100644
index 000000000..1477866dc
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-log10.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+log10l (double x)
+{
+ return log10 (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-log1p.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-log1p.c
new file mode 100644
index 000000000..455b25a9f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-log1p.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+log1pl (double x)
+{
+ return log1p (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-log2.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-log2.c
new file mode 100644
index 000000000..8c1ae344e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-log2.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+log2l (double x)
+{
+ return log2 (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-logb.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-logb.c
new file mode 100644
index 000000000..d9ce8de07
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-logb.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+logbl (double x)
+{
+ return logb (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-lrint.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-lrint.c
new file mode 100644
index 000000000..0acd3d4ae
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-lrint.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+long int
+attribute_hidden
+lrintl (double x)
+{
+ return lrint (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-lround.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-lround.c
new file mode 100644
index 000000000..aadb111f8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-lround.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+long int
+attribute_hidden
+lroundl (double x)
+{
+ return lround (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-modf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-modf.c
new file mode 100644
index 000000000..bcbe6bb43
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-modf.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+modfl (double x, double *iptr)
+{
+ return modf (x, iptr);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-nan.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-nan.c
new file mode 100644
index 000000000..8db157a0e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-nan.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+nanl (const char *tag)
+{
+ return nan (tag);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-nearbyint.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-nearbyint.c
new file mode 100644
index 000000000..fd4a24684
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-nearbyint.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+nearbyintl (double x)
+{
+ return nearbyint (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-nextafter.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-nextafter.c
new file mode 100644
index 000000000..b0bae43f4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-nextafter.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+nextafterl (double x, double y)
+{
+ return nextafter (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-nexttoward.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-nexttoward.c
new file mode 100644
index 000000000..acbd01a0c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-nexttoward.c
@@ -0,0 +1,14 @@
+#define nexttoward nexttoward_XXX
+#define nexttowardl nexttowardl_XXX
+#include "nldbl-compat.h"
+#undef nexttoward
+#undef nexttowardl
+
+double
+attribute_hidden
+nexttoward (double x, double y)
+{
+ return nextafter (x, y);
+}
+extern __typeof (nexttoward) nexttowardl attribute_hidden;
+strong_alias (nexttoward, nexttowardl)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-nexttowardf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-nexttowardf.c
new file mode 100644
index 000000000..350b08d39
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-nexttowardf.c
@@ -0,0 +1,12 @@
+#define nexttowardf nexttowardf_XXX
+#include "nldbl-compat.h"
+#undef nexttowardf
+
+extern float __nldbl_nexttowardf (float x, double y);
+
+float
+attribute_hidden
+nexttowardf (float x, double y)
+{
+ return __nldbl_nexttowardf (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-obstack_printf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-obstack_printf.c
new file mode 100644
index 000000000..4abff2dc0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-obstack_printf.c
@@ -0,0 +1,13 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+obstack_printf (struct obstack *obstack, const char *fmt, ...)
+{
+ int result;
+ va_list ap;
+ va_start (ap, fmt);
+ result = __nldbl_obstack_vprintf (obstack, fmt, ap);
+ va_end (ap);
+ return result;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-obstack_vprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-obstack_vprintf.c
new file mode 100644
index 000000000..228a50726
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-obstack_vprintf.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+obstack_vprintf (struct obstack *obstack, const char *fmt, va_list ap)
+{
+ return __nldbl_obstack_vprintf (obstack, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-pow.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-pow.c
new file mode 100644
index 000000000..a5cc44655
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-pow.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+powl (double x, double y)
+{
+ return pow (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-pow10.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-pow10.c
new file mode 100644
index 000000000..20ebf8d1b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-pow10.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+pow10l (double x)
+{
+ return pow10 (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-printf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-printf.c
new file mode 100644
index 000000000..e4b0fbae0
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-printf.c
@@ -0,0 +1,17 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+printf (const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfprintf (stdout, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+extern __typeof (printf) _IO_printf attribute_hidden;
+strong_alias (printf, _IO_printf)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-printf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-printf_chk.c
new file mode 100644
index 000000000..926db412f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-printf_chk.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__printf_chk (int flag, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vfprintf_chk (stdout, flag, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-printf_fp.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-printf_fp.c
new file mode 100644
index 000000000..057dfe0b8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-printf_fp.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__printf_fp (FILE *fp, const struct printf_info *info,
+ const void *const *args)
+{
+ return __nldbl___printf_fp (fp, info, args);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-printf_size.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-printf_size.c
new file mode 100644
index 000000000..d8b1fc999
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-printf_size.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+printf_size (FILE *__restrict fp, const struct printf_info *info,
+ const void *const *__restrict args)
+{
+ return __nldbl_printf_size (fp, info, args);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-qecvt.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-qecvt.c
new file mode 100644
index 000000000..9f0b0a66a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-qecvt.c
@@ -0,0 +1,10 @@
+#define qecvt qecvt_XXX
+#include "nldbl-compat.h"
+#undef qecvt
+
+attribute_hidden
+char *
+qecvt (double val, int ndigit, int *__restrict decpt, int *__restrict sign)
+{
+ return ecvt (val, ndigit, decpt, sign);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-qecvt_r.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-qecvt_r.c
new file mode 100644
index 000000000..06f99146c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-qecvt_r.c
@@ -0,0 +1,11 @@
+#define qecvt_r qecvt_r_XXX
+#include "nldbl-compat.h"
+#undef qecvt_r
+
+int
+attribute_hidden
+qecvt_r (double val, int ndigit, int *__restrict decpt, int *__restrict sign,
+ char *__restrict buf, size_t len)
+{
+ return ecvt_r (val, ndigit, decpt, sign, buf, len);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-qfcvt.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-qfcvt.c
new file mode 100644
index 000000000..37fa7f046
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-qfcvt.c
@@ -0,0 +1,10 @@
+#define qfcvt qfcvt_XXX
+#include "nldbl-compat.h"
+#undef qfcvt
+
+attribute_hidden
+char *
+qfcvt (double val, int ndigit, int *__restrict decpt, int *__restrict sign)
+{
+ return fcvt (val, ndigit, decpt, sign);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-qfcvt_r.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-qfcvt_r.c
new file mode 100644
index 000000000..03224fefa
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-qfcvt_r.c
@@ -0,0 +1,11 @@
+#define qfcvt_r qfcvt_r_XXX
+#include "nldbl-compat.h"
+#undef qfcvt_r
+
+int
+attribute_hidden
+qfcvt_r (double val, int ndigit, int *__restrict decpt, int *__restrict sign,
+ char *__restrict buf, size_t len)
+{
+ return fcvt_r (val, ndigit, decpt, sign, buf, len);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-qgcvt.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-qgcvt.c
new file mode 100644
index 000000000..b935d0962
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-qgcvt.c
@@ -0,0 +1,10 @@
+#define qgcvt qgcvt_XXX
+#include "nldbl-compat.h"
+#undef qgcvt
+
+attribute_hidden
+char *
+qgcvt (double val, int ndigit, char *buf)
+{
+ return gcvt (val, ndigit, buf);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-remainder.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-remainder.c
new file mode 100644
index 000000000..a8d5bafb5
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-remainder.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+remainderl (double x, double y)
+{
+ return remainder (x, y);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-remquo.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-remquo.c
new file mode 100644
index 000000000..592dadae8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-remquo.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+remquol (double x, double y, int *quo)
+{
+ return remquo (x, y, quo);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-rint.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-rint.c
new file mode 100644
index 000000000..00f942f1a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-rint.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+rintl (double x)
+{
+ return rint (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-round.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-round.c
new file mode 100644
index 000000000..be9bd5112
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-round.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+roundl (double x)
+{
+ return round (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-scalb.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-scalb.c
new file mode 100644
index 000000000..00d3e2e71
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-scalb.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+scalbl (double x, double n)
+{
+ return scalb (x, n);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-scalbln.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-scalbln.c
new file mode 100644
index 000000000..b5bd50125
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-scalbln.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+scalblnl (double x, long int n)
+{
+ return scalbln (x, n);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-scalbn.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-scalbn.c
new file mode 100644
index 000000000..b1914ebf4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-scalbn.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+scalbnl (double x, int n)
+{
+ return scalbn (x, n);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-scanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-scanf.c
new file mode 100644
index 000000000..bbab371cb
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-scanf.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+scanf (const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl__IO_vfscanf (stdin, fmt, arg, NULL);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-signbit.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-signbit.c
new file mode 100644
index 000000000..b62d0ed7f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-signbit.c
@@ -0,0 +1,10 @@
+#define __signbitl __signbitl_XXX
+#include "nldbl-compat.h"
+#undef __signbitl
+
+int
+attribute_hidden
+__signbitl (double x)
+{
+ return __signbit (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-significand.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-significand.c
new file mode 100644
index 000000000..624381dde
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-significand.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+significandl (double x)
+{
+ return significand (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-sin.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sin.c
new file mode 100644
index 000000000..0e76e05e6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sin.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+sinl (double x)
+{
+ return sin (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-sincos.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sincos.c
new file mode 100644
index 000000000..9f2ab2b9f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sincos.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+void
+attribute_hidden
+sincosl (double x, double *sinx, double *cosx)
+{
+ sincos (x, sinx, cosx);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-sinh.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sinh.c
new file mode 100644
index 000000000..99ea62e8d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sinh.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+sinhl (double x)
+{
+ return sinh (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-snprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-snprintf.c
new file mode 100644
index 000000000..ef6fb96a2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-snprintf.c
@@ -0,0 +1,16 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+weak_function
+snprintf (char *s, size_t maxlen, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vsnprintf (s, maxlen, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-snprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-snprintf_chk.c
new file mode 100644
index 000000000..944d3de9d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-snprintf_chk.c
@@ -0,0 +1,16 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__snprintf_chk (char *s, size_t maxlen, int flag, size_t slen,
+ const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vsnprintf_chk (s, maxlen, flag, slen, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-sprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sprintf.c
new file mode 100644
index 000000000..5d37a7e7f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sprintf.c
@@ -0,0 +1,17 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+sprintf (char *s, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vsprintf (s, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+extern __typeof (sprintf) _IO_sprintf attribute_hidden;
+strong_alias (sprintf, _IO_sprintf)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-sprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sprintf_chk.c
new file mode 100644
index 000000000..349b7c5c2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sprintf_chk.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__sprintf_chk (char *s, int flag, size_t slen, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vsprintf_chk (s, flag, slen, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-sqrt.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sqrt.c
new file mode 100644
index 000000000..4ae65665d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sqrt.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+sqrtl (double x)
+{
+ return sqrt (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c
new file mode 100644
index 000000000..a771d4999
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-sscanf.c
@@ -0,0 +1,17 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+sscanf (const char *s, const char *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vsscanf (s, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
+extern __typeof (sscanf) _IO_sscanf attribute_hidden;
+strong_alias (sscanf, _IO_sscanf)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-strfmon.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-strfmon.c
new file mode 100644
index 000000000..38f407127
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-strfmon.c
@@ -0,0 +1,14 @@
+#include "nldbl-compat.h"
+
+ssize_t
+attribute_hidden
+strfmon (char *s, size_t maxsize, const char *format, ...)
+{
+ va_list ap;
+ ssize_t res;
+
+ va_start (ap, format);
+ res = __nldbl___vstrfmon (s, maxsize, format, ap);
+ va_end (ap);
+ return res;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-strfmon_l.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-strfmon_l.c
new file mode 100644
index 000000000..0db0e8c42
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-strfmon_l.c
@@ -0,0 +1,16 @@
+#include "nldbl-compat.h"
+
+ssize_t
+attribute_hidden
+__strfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, ...)
+{
+ va_list ap;
+ ssize_t res;
+
+ va_start (ap, format);
+ res = __nldbl___vstrfmon_l (s, maxsize, loc, format, ap);
+ va_end (ap);
+ return res;
+}
+extern __typeof (__strfmon_l) strfmon_l attribute_hidden;
+weak_alias (__strfmon_l, strfmon_l)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-strtold.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-strtold.c
new file mode 100644
index 000000000..99b907947
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-strtold.c
@@ -0,0 +1,10 @@
+#define strtold strtold_XXX
+#include "nldbl-compat.h"
+#undef strtold
+
+double
+attribute_hidden
+strtold (const char *nptr, char **endptr)
+{
+ return strtod (nptr, endptr);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-strtold_l.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-strtold_l.c
new file mode 100644
index 000000000..422746379
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-strtold_l.c
@@ -0,0 +1,20 @@
+#define strtold_l strtold_l_XXX
+#define __strtold_l __strtold_l_XXX
+#define __strtod_l __strtod_l_XXX
+#include "nldbl-compat.h"
+#undef strtold_l
+#undef __strtold_l
+#undef __strtod_l
+
+extern double
+__strtod_l (__const char *__restrict __nptr, char **__restrict __endptr,
+ __locale_t __loc);
+
+double
+attribute_hidden
+__strtold_l (const char *nptr, char **endptr, __locale_t loc)
+{
+ return __strtod_l (nptr, endptr, loc);
+}
+extern __typeof (__strtold_l) strtold_l attribute_hidden;
+weak_alias (__strtold_l, strtold_l)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-strtoldint.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-strtoldint.c
new file mode 100644
index 000000000..0bafabc6e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-strtoldint.c
@@ -0,0 +1,10 @@
+#define __strtold_internal __strtold_internal_XXX
+#include "nldbl-compat.h"
+#undef __strtold_internal
+
+double
+attribute_hidden
+__strtold_internal (const char *nptr, char **endptr, int group)
+{
+ return __strtod_internal (nptr, endptr, group);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-swprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-swprintf.c
new file mode 100644
index 000000000..7f4f7b04d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-swprintf.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vswprintf (s, n, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-swprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-swprintf_chk.c
new file mode 100644
index 000000000..0373f6ebc
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-swprintf_chk.c
@@ -0,0 +1,16 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen,
+ const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vswprintf_chk (s, n, flag, slen, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c
new file mode 100644
index 000000000..dd058f47a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-swscanf.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+swscanf (const wchar_t *s, const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vswscanf (s, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-syslog.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-syslog.c
new file mode 100644
index 000000000..8687e9f54
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-syslog.c
@@ -0,0 +1,11 @@
+#include "nldbl-compat.h"
+
+void
+attribute_hidden
+syslog (int pri, const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ __nldbl_vsyslog (pri, fmt, ap);
+ va_end (ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-syslog_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-syslog_chk.c
new file mode 100644
index 000000000..31ea6a8b9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-syslog_chk.c
@@ -0,0 +1,12 @@
+#include "nldbl-compat.h"
+
+void
+attribute_hidden
+__syslog_chk (int pri, int flag, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ __nldbl___vsyslog_chk (pri, flag, fmt, ap);
+ va_end(ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-tan.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-tan.c
new file mode 100644
index 000000000..1a27b6fbd
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-tan.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+tanl (double x)
+{
+ return tan (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-tanh.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-tanh.c
new file mode 100644
index 000000000..fc2fd32eb
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-tanh.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+tanhl (double x)
+{
+ return tanh (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-tgamma.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-tgamma.c
new file mode 100644
index 000000000..bbf613abe
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-tgamma.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+tgammal (double x)
+{
+ return tgamma (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-trunc.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-trunc.c
new file mode 100644
index 000000000..d0131e80a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-trunc.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+truncl (double x)
+{
+ return trunc (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vasprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vasprintf.c
new file mode 100644
index 000000000..52fa18cce
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vasprintf.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+weak_function
+vasprintf (char **result_ptr, const char *fmt, va_list ap)
+{
+ return __nldbl_vasprintf (result_ptr, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vdprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vdprintf.c
new file mode 100644
index 000000000..1acbd4062
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vdprintf.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+vdprintf (int d, const char *fmt, va_list arg)
+{
+ return __nldbl_vdprintf (d, fmt, arg);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfprintf.c
new file mode 100644
index 000000000..6ca8437b2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfprintf.c
@@ -0,0 +1,10 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+vfprintf (FILE *s, const char *fmt, va_list ap)
+{
+ return __nldbl_vfprintf (s, fmt, ap);
+}
+extern __typeof (vfprintf) _IO_vfprintf attribute_hidden;
+strong_alias (vfprintf, _IO_vfprintf)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfprintf_chk.c
new file mode 100644
index 000000000..0f6820af6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfprintf_chk.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__vfprintf_chk (FILE *s, int flag, const char *fmt, va_list ap)
+{
+ return __nldbl___vfprintf_chk (s, flag, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c
new file mode 100644
index 000000000..f23465ee9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfscanf.c
@@ -0,0 +1,10 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__vfscanf (FILE *s, const char *fmt, va_list ap)
+{
+ return __nldbl__IO_vfscanf (s, fmt, ap, NULL);
+}
+extern __typeof (__vfscanf) vfscanf attribute_hidden;
+weak_alias (__vfscanf, vfscanf)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfwprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfwprintf.c
new file mode 100644
index 000000000..c3fe76a97
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfwprintf.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+weak_function
+vfwprintf (FILE *s, const wchar_t *fmt, va_list ap)
+{
+ return __nldbl_vfwprintf (s, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfwprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfwprintf_chk.c
new file mode 100644
index 000000000..b3b69f057
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfwprintf_chk.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap)
+{
+ return __nldbl___vfwprintf_chk (s, flag, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c
new file mode 100644
index 000000000..be9febc9a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vfwscanf.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
+{
+ return __nldbl_vfwscanf (s, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vprintf.c
new file mode 100644
index 000000000..ed0d27d9a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vprintf.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+vprintf (const char *fmt, va_list ap)
+{
+ return __nldbl_vfprintf (stdout, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vprintf_chk.c
new file mode 100644
index 000000000..63b3e8f96
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vprintf_chk.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__vprintf_chk (int flag, const char *fmt, va_list ap)
+{
+ return __nldbl___vfprintf_chk (stdout, flag, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c
new file mode 100644
index 000000000..e75907b90
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vscanf.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+weak_function
+vscanf (const char *fmt, va_list ap)
+{
+ return __nldbl__IO_vfscanf (stdin, fmt, ap, NULL);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsnprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsnprintf.c
new file mode 100644
index 000000000..5a9bcbcae
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsnprintf.c
@@ -0,0 +1,10 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+vsnprintf (char *string, size_t maxlen, const char *fmt, va_list ap)
+{
+ return __nldbl_vsnprintf (string, maxlen, fmt, ap);
+}
+extern __typeof (vsnprintf) __vsnprintf attribute_hidden;
+weak_alias (vsnprintf, __vsnprintf)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsnprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsnprintf_chk.c
new file mode 100644
index 000000000..19380291a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsnprintf_chk.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__vsnprintf_chk (char *string, size_t maxlen, int flag, size_t slen,
+ const char *fmt, va_list ap)
+{
+ return __nldbl___vsnprintf_chk (string, maxlen, flag, slen, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsprintf.c
new file mode 100644
index 000000000..04406d0f6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsprintf.c
@@ -0,0 +1,10 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+_IO_vsprintf (char *string, const char *fmt, va_list ap)
+{
+ return __nldbl_vsprintf (string, fmt, ap);
+}
+extern __typeof (_IO_vsprintf) vsprintf attribute_hidden;
+weak_alias (_IO_vsprintf, vsprintf)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsprintf_chk.c
new file mode 100644
index 000000000..9df143fce
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsprintf_chk.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__vsprintf_chk (char *string, int flag, size_t slen, const char *fmt,
+ va_list ap)
+{
+ return __nldbl___vsprintf_chk (string, flag, slen, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c
new file mode 100644
index 000000000..f5594c122
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsscanf.c
@@ -0,0 +1,10 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__vsscanf (const char *string, const char *fmt, va_list ap)
+{
+ return __nldbl_vsscanf (string, fmt, ap);
+}
+extern __typeof (__vsscanf) vsscanf attribute_hidden;
+weak_alias (__vsscanf, vsscanf)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vswprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vswprintf.c
new file mode 100644
index 000000000..ff3415a07
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vswprintf.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+weak_function
+vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt, va_list ap)
+{
+ return __nldbl_vswprintf (string, maxlen, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vswprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vswprintf_chk.c
new file mode 100644
index 000000000..0cd1f96bf
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vswprintf_chk.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__vswprintf_chk (wchar_t *string, size_t maxlen, int flag, size_t slen,
+ const wchar_t *fmt, va_list ap)
+{
+ return __nldbl___vswprintf_chk (string, maxlen, flag, slen, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c
new file mode 100644
index 000000000..bd4bb5131
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vswscanf.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+vswscanf (const wchar_t *string, const wchar_t *fmt, va_list ap)
+{
+ return __nldbl_vswscanf (string, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsyslog.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsyslog.c
new file mode 100644
index 000000000..eed1010ee
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsyslog.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+attribute_hidden
+void
+vsyslog (int pri, const char *fmt, va_list ap)
+{
+ __nldbl_vsyslog (pri, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsyslog_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsyslog_chk.c
new file mode 100644
index 000000000..2221474f9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vsyslog_chk.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+void
+attribute_hidden
+__vsyslog_chk (int pri, int flag, const char *fmt, va_list ap)
+{
+ __nldbl___vsyslog_chk (pri, flag, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vwprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vwprintf.c
new file mode 100644
index 000000000..f46bdb313
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vwprintf.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+vwprintf (const wchar_t *fmt, va_list ap)
+{
+ return __nldbl_vfwprintf (stdout, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vwprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vwprintf_chk.c
new file mode 100644
index 000000000..f7e718597
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vwprintf_chk.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__vwprintf_chk (int flag, const wchar_t *fmt, va_list ap)
+{
+ return __nldbl___vfwprintf_chk (stdout, flag, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c
new file mode 100644
index 000000000..d39578ca4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-vwscanf.c
@@ -0,0 +1,9 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+weak_function
+vwscanf (const wchar_t *fmt, va_list ap)
+{
+ return __nldbl_vfwscanf (stdin, fmt, ap);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-wcstold.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-wcstold.c
new file mode 100644
index 000000000..dbaffaa48
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-wcstold.c
@@ -0,0 +1,10 @@
+#define wcstold wcstold_XXX
+#include "nldbl-compat.h"
+#undef wcstold
+
+double
+attribute_hidden
+wcstold (const wchar_t *nptr, wchar_t **endptr)
+{
+ return wcstod (nptr, endptr);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-wcstold_l.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-wcstold_l.c
new file mode 100644
index 000000000..e32d13a94
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-wcstold_l.c
@@ -0,0 +1,14 @@
+#define wcstold_l wcstold_l_XXX
+#define __wcstold_l __wcstold_l_XXX
+#include "nldbl-compat.h"
+#undef wcstold_l
+#undef __wcstold_l
+
+double
+attribute_hidden
+__wcstold_l (const wchar_t *nptr, wchar_t **endptr, __locale_t loc)
+{
+ return __wcstod_l (nptr, endptr, loc);
+}
+extern __typeof (__wcstold_l) wcstold_l attribute_hidden;
+weak_alias (__wcstold_l, wcstold_l)
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-wcstoldint.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-wcstoldint.c
new file mode 100644
index 000000000..b638a399a
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-wcstoldint.c
@@ -0,0 +1,10 @@
+#define __wcstold_internal __wcstold_internal_XXX
+#include "nldbl-compat.h"
+#undef __wcstold_internal
+
+double
+attribute_hidden
+__wcstold_internal (const wchar_t *nptr, wchar_t **endptr, int group)
+{
+ return __wcstod_internal (nptr, endptr, group);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-wprintf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-wprintf.c
new file mode 100644
index 000000000..2aa1a7475
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-wprintf.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+wprintf (const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfwprintf (stdout, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-wprintf_chk.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-wprintf_chk.c
new file mode 100644
index 000000000..39191e123
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-wprintf_chk.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+__wprintf_chk (int flag, const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl___vfwprintf_chk (stdout, flag, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c
new file mode 100644
index 000000000..4ee3fdc15
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-wscanf.c
@@ -0,0 +1,15 @@
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+wscanf (const wchar_t *fmt, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, fmt);
+ done = __nldbl_vfwscanf (stdin, fmt, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-y0.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-y0.c
new file mode 100644
index 000000000..e35621f60
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-y0.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+y0l (double x)
+{
+ return y0 (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-y1.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-y1.c
new file mode 100644
index 000000000..c47abcd3c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-y1.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+y1l (double x)
+{
+ return y1 (x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/nldbl-yn.c b/libc/sysdeps/ieee754/ldbl-opt/nldbl-yn.c
new file mode 100644
index 000000000..7623d4513
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/nldbl-yn.c
@@ -0,0 +1,8 @@
+#include "nldbl-compat.h"
+
+double
+attribute_hidden
+ynl (int n, double x)
+{
+ return yn (n, x);
+}
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_asinh.c b/libc/sysdeps/ieee754/ldbl-opt/s_asinh.c
new file mode 100644
index 000000000..e9bcfaea6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_asinh.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_asinh.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __asinh, asinhl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_atan.c b/libc/sysdeps/ieee754/ldbl-opt/s_atan.c
new file mode 100644
index 000000000..5fbd5e62d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_atan.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_atan.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, atan, atanl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_cacos.c b/libc/sysdeps/ieee754/ldbl-opt/s_cacos.c
new file mode 100644
index 000000000..db90a9ef1
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_cacos.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_cacos.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __cacos, cacosl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_cacosh.c b/libc/sysdeps/ieee754/ldbl-opt/s_cacosh.c
new file mode 100644
index 000000000..e68049d46
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_cacosh.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_cacosh.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __cacosh, cacoshl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_cacoshl.c b/libc/sysdeps/ieee754/ldbl-opt/s_cacoshl.c
new file mode 100644
index 000000000..ed4a29984
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_cacoshl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_cacoshl.c>
+long_double_symbol (libm, __cacoshl, cacoshl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_cacosl.c b/libc/sysdeps/ieee754/ldbl-opt/s_cacosl.c
new file mode 100644
index 000000000..9b840054e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_cacosl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_cacosl.c>
+long_double_symbol (libm, __cacosl, cacosl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_casin.c b/libc/sysdeps/ieee754/ldbl-opt/s_casin.c
new file mode 100644
index 000000000..04c47ca60
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_casin.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_casin.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __casin, casinl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_casinh.c b/libc/sysdeps/ieee754/ldbl-opt/s_casinh.c
new file mode 100644
index 000000000..19c4fa30f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_casinh.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_casinh.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __casinh, casinhl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_casinhl.c b/libc/sysdeps/ieee754/ldbl-opt/s_casinhl.c
new file mode 100644
index 000000000..976fa8e5b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_casinhl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_casinhl.c>
+long_double_symbol (libm, __casinhl, casinhl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_casinl.c b/libc/sysdeps/ieee754/ldbl-opt/s_casinl.c
new file mode 100644
index 000000000..7afb77cd4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_casinl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_casinl.c>
+long_double_symbol (libm, __casinl, casinl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_catan.c b/libc/sysdeps/ieee754/ldbl-opt/s_catan.c
new file mode 100644
index 000000000..19f61736d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_catan.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_catan.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __catan, catanl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_catanh.c b/libc/sysdeps/ieee754/ldbl-opt/s_catanh.c
new file mode 100644
index 000000000..cff786144
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_catanh.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_catanh.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __catanh, catanhl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_catanhl.c b/libc/sysdeps/ieee754/ldbl-opt/s_catanhl.c
new file mode 100644
index 000000000..e9562825e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_catanhl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_catanhl.c>
+long_double_symbol (libm, __catanhl, catanhl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_catanl.c b/libc/sysdeps/ieee754/ldbl-opt/s_catanl.c
new file mode 100644
index 000000000..ee2fdf5d6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_catanl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_catanl.c>
+long_double_symbol (libm, __catanl, catanl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_cbrt.c b/libc/sysdeps/ieee754/ldbl-opt/s_cbrt.c
new file mode 100644
index 000000000..cdc635771
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_cbrt.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_cbrt.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __cbrt, cbrtl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_ccos.c b/libc/sysdeps/ieee754/ldbl-opt/s_ccos.c
new file mode 100644
index 000000000..2c43c7f39
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_ccos.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_ccos.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __ccos, ccosl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_ccosh.c b/libc/sysdeps/ieee754/ldbl-opt/s_ccosh.c
new file mode 100644
index 000000000..3753cd56b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_ccosh.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_ccosh.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __ccosh, ccoshl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_ccoshl.c b/libc/sysdeps/ieee754/ldbl-opt/s_ccoshl.c
new file mode 100644
index 000000000..9f0c1e1a3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_ccoshl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_ccoshl.c>
+long_double_symbol (libm, __ccoshl, ccoshl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_ccosl.c b/libc/sysdeps/ieee754/ldbl-opt/s_ccosl.c
new file mode 100644
index 000000000..e93e80538
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_ccosl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_ccosl.c>
+long_double_symbol (libm, __ccosl, ccosl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_ceil.c b/libc/sysdeps/ieee754/ldbl-opt/s_ceil.c
new file mode 100644
index 000000000..6e4b70795
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_ceil.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_ceil.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __ceil, ceill, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_cexp.c b/libc/sysdeps/ieee754/ldbl-opt/s_cexp.c
new file mode 100644
index 000000000..d983c96b7
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_cexp.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_cexp.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __cexp, cexpl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_cexpl.c b/libc/sysdeps/ieee754/ldbl-opt/s_cexpl.c
new file mode 100644
index 000000000..d5ae1fc0d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_cexpl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_cexpl.c>
+long_double_symbol (libm, __cexpl, cexpl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_clog.c b/libc/sysdeps/ieee754/ldbl-opt/s_clog.c
new file mode 100644
index 000000000..3e0e90cf8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_clog.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_clog.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __clog, clogl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_clog10.c b/libc/sysdeps/ieee754/ldbl-opt/s_clog10.c
new file mode 100644
index 000000000..ac3f4a3a7
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_clog10.c
@@ -0,0 +1,7 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_clog10.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __clog10, __clog10l, GLIBC_2_1);
+compat_symbol (libm, clog10, clog10l, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_clog10l.c b/libc/sysdeps/ieee754/ldbl-opt/s_clog10l.c
new file mode 100644
index 000000000..954f68095
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_clog10l.c
@@ -0,0 +1,10 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#define __clog10l __clog10l_internal
+#include <math/s_clog10l.c>
+#undef __clog10l
+strong_alias (__clog10l_internal, __clog10l__internal)
+long_double_symbol (libm, __clog10l_internal, __clog10l);
+long_double_symbol (libm, __clog10l__internal, clog10l);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_clogl.c b/libc/sysdeps/ieee754/ldbl-opt/s_clogl.c
new file mode 100644
index 000000000..75126c8b8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_clogl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_clogl.c>
+long_double_symbol (libm, __clogl, clogl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_copysign.c b/libc/sysdeps/ieee754/ldbl-opt/s_copysign.c
new file mode 100644
index 000000000..425e0eadb
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_copysign.c
@@ -0,0 +1,9 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_copysign.c>
+#ifdef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __copysign, copysignl, GLIBC_2_0);
+# endif
+#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __copysign, copysignl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_cpow.c b/libc/sysdeps/ieee754/ldbl-opt/s_cpow.c
new file mode 100644
index 000000000..4801d7cdf
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_cpow.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_cpow.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __cpow, cpowl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_cpowl.c b/libc/sysdeps/ieee754/ldbl-opt/s_cpowl.c
new file mode 100644
index 000000000..61840e338
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_cpowl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_cpowl.c>
+long_double_symbol (libm, __cpowl, cpowl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_cproj.c b/libc/sysdeps/ieee754/ldbl-opt/s_cproj.c
new file mode 100644
index 000000000..f298c3795
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_cproj.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_cproj.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __cproj, cprojl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_cprojl.c b/libc/sysdeps/ieee754/ldbl-opt/s_cprojl.c
new file mode 100644
index 000000000..1cc058007
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_cprojl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_cprojl.c>
+long_double_symbol (libm, __cprojl, cprojl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_csin.c b/libc/sysdeps/ieee754/ldbl-opt/s_csin.c
new file mode 100644
index 000000000..7017c9545
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_csin.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_csin.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __csin, csinl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_csinh.c b/libc/sysdeps/ieee754/ldbl-opt/s_csinh.c
new file mode 100644
index 000000000..a1fa6671d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_csinh.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_csinh.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __csinh, csinhl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_csinhl.c b/libc/sysdeps/ieee754/ldbl-opt/s_csinhl.c
new file mode 100644
index 000000000..484d466ce
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_csinhl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_csinhl.c>
+long_double_symbol (libm, __csinhl, csinhl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_csinl.c b/libc/sysdeps/ieee754/ldbl-opt/s_csinl.c
new file mode 100644
index 000000000..f71642e88
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_csinl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_csinl.c>
+long_double_symbol (libm, __csinl, csinl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_csqrt.c b/libc/sysdeps/ieee754/ldbl-opt/s_csqrt.c
new file mode 100644
index 000000000..2b6dcfe01
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_csqrt.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_csqrt.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __csqrt, csqrtl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_csqrtl.c b/libc/sysdeps/ieee754/ldbl-opt/s_csqrtl.c
new file mode 100644
index 000000000..045ff93e4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_csqrtl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_csqrtl.c>
+long_double_symbol (libm, __csqrtl, csqrtl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_ctan.c b/libc/sysdeps/ieee754/ldbl-opt/s_ctan.c
new file mode 100644
index 000000000..a6a21f9f2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_ctan.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_ctan.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __ctan, ctanl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_ctanh.c b/libc/sysdeps/ieee754/ldbl-opt/s_ctanh.c
new file mode 100644
index 000000000..fd4be129f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_ctanh.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#include <math/s_ctanh.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __ctanh, ctanhl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_ctanhl.c b/libc/sysdeps/ieee754/ldbl-opt/s_ctanhl.c
new file mode 100644
index 000000000..f159373b3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_ctanhl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_ctanhl.c>
+long_double_symbol (libm, __ctanhl, ctanhl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_ctanl.c b/libc/sysdeps/ieee754/ldbl-opt/s_ctanl.c
new file mode 100644
index 000000000..0c2d94cf4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_ctanl.c
@@ -0,0 +1,6 @@
+#include <complex.h>
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_ctanl.c>
+long_double_symbol (libm, __ctanl, ctanl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_erf.c b/libc/sysdeps/ieee754/ldbl-opt/s_erf.c
new file mode 100644
index 000000000..76f1baa5c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_erf.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_erf.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __erf, erfl, GLIBC_2_0);
+compat_symbol (libm, __erfc, erfcl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_expm1.c b/libc/sysdeps/ieee754/ldbl-opt/s_expm1.c
new file mode 100644
index 000000000..ef9b5956d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_expm1.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_expm1.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __expm1, expm1l, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_fabs.c b/libc/sysdeps/ieee754/ldbl-opt/s_fabs.c
new file mode 100644
index 000000000..e7c92187e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_fabs.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_fabs.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __fabs, fabsl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_fdim.c b/libc/sysdeps/ieee754/ldbl-opt/s_fdim.c
new file mode 100644
index 000000000..02c95bfa8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_fdim.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/s_fdim.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fdim, fdiml, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_fdiml.c b/libc/sysdeps/ieee754/ldbl-opt/s_fdiml.c
new file mode 100644
index 000000000..06b760b7b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_fdiml.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_fdiml.c>
+long_double_symbol (libm, __fdiml, fdiml);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_finite.c b/libc/sysdeps/ieee754/ldbl-opt/s_finite.c
new file mode 100644
index 000000000..897dbfd3b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_finite.c
@@ -0,0 +1,18 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_finite.c>
+weak_alias (__finite, ___finite)
+#ifdef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __finite, __finitel, GLIBC_2_1);
+# endif
+# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, ___finite, finitel, GLIBC_2_0);
+# endif
+#else
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libm, __finite, __finitel, GLIBC_2_0);
+# endif
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, ___finite, finitel, GLIBC_2_0);
+# endif
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_floor.c b/libc/sysdeps/ieee754/ldbl-opt/s_floor.c
new file mode 100644
index 000000000..7797944e9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_floor.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_floor.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __floor, floorl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_fma.c b/libc/sysdeps/ieee754/ldbl-opt/s_fma.c
new file mode 100644
index 000000000..2ee721413
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_fma.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/s_fma.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fma, fmal, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_fmal.c b/libc/sysdeps/ieee754/ldbl-opt/s_fmal.c
new file mode 100644
index 000000000..bd12dabcb
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_fmal.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_fmal.c>
+long_double_symbol (libm, __fmal, fmal);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_fmax.c b/libc/sysdeps/ieee754/ldbl-opt/s_fmax.c
new file mode 100644
index 000000000..11e759121
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_fmax.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/s_fmax.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fmax, fmaxl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_fmaxl.c b/libc/sysdeps/ieee754/ldbl-opt/s_fmaxl.c
new file mode 100644
index 000000000..98221b2cd
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_fmaxl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_fmaxl.c>
+long_double_symbol (libm, __fmaxl, fmaxl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_fmin.c b/libc/sysdeps/ieee754/ldbl-opt/s_fmin.c
new file mode 100644
index 000000000..c3fe44d9d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_fmin.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/s_fmin.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fmin, fminl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_fminl.c b/libc/sysdeps/ieee754/ldbl-opt/s_fminl.c
new file mode 100644
index 000000000..9bfdc7ad7
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_fminl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_fminl.c>
+long_double_symbol (libm, __fminl, fminl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_frexp.c b/libc/sysdeps/ieee754/ldbl-opt/s_frexp.c
new file mode 100644
index 000000000..59ce35220
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_frexp.c
@@ -0,0 +1,9 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_frexp.c>
+#ifdef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __frexp, frexpl, GLIBC_2_0);
+# endif
+#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __frexp, frexpl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_ilogb.c b/libc/sysdeps/ieee754/ldbl-opt/s_ilogb.c
new file mode 100644
index 000000000..3a6ccbd09
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_ilogb.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_ilogb.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __ilogb, ilogbl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_isinf.c b/libc/sysdeps/ieee754/ldbl-opt/s_isinf.c
new file mode 100644
index 000000000..401c8b131
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_isinf.c
@@ -0,0 +1,8 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_isinf.c>
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isinf, __isinfl, GLIBC_2_0);
+compat_symbol (libc, isinf, isinfl, GLIBC_2_0);
+# endif
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_isnan.c b/libc/sysdeps/ieee754/ldbl-opt/s_isnan.c
new file mode 100644
index 000000000..164b800b8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_isnan.c
@@ -0,0 +1,8 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_isnan.c>
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
+compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
+# endif
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_ldexp.c b/libc/sysdeps/ieee754/ldbl-opt/s_ldexp.c
new file mode 100644
index 000000000..f0f651989
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_ldexp.c
@@ -0,0 +1,9 @@
+#include <math_ldbl_opt.h>
+#include <math/s_ldexp.c>
+#ifdef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __ldexp, ldexpl, GLIBC_2_0);
+# endif
+#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __ldexp, ldexpl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_ldexpl.c b/libc/sysdeps/ieee754/ldbl-opt/s_ldexpl.c
new file mode 100644
index 000000000..d4636b9cc
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_ldexpl.c
@@ -0,0 +1,9 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_ldexpl.c>
+#ifdef IS_IN_libm
+long_double_symbol (libm, __ldexpl, ldexpl);
+#else
+long_double_symbol (libc, __ldexpl, ldexpl);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_llrint.c b/libc/sysdeps/ieee754/ldbl-opt/s_llrint.c
new file mode 100644
index 000000000..e6311972e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_llrint.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_llrint.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __llrint, llrintl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_llround.c b/libc/sysdeps/ieee754/ldbl-opt/s_llround.c
new file mode 100644
index 000000000..36c7e6eda
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_llround.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_llround.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __llround, llroundl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_log1p.c b/libc/sysdeps/ieee754/ldbl-opt/s_log1p.c
new file mode 100644
index 000000000..495fa32e3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_log1p.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_log1p.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __log1p, log1pl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_logb.c b/libc/sysdeps/ieee754/ldbl-opt/s_logb.c
new file mode 100644
index 000000000..4d7a6db27
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_logb.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_logb.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __logb, logbl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_lrint.c b/libc/sysdeps/ieee754/ldbl-opt/s_lrint.c
new file mode 100644
index 000000000..b7af81284
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_lrint.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_lrint.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __lrint, lrintl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_lround.c b/libc/sysdeps/ieee754/ldbl-opt/s_lround.c
new file mode 100644
index 000000000..f3a27fa9c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_lround.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_lround.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __lround, lroundl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_modf.c b/libc/sysdeps/ieee754/ldbl-opt/s_modf.c
new file mode 100644
index 000000000..2263811e5
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_modf.c
@@ -0,0 +1,9 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_modf.c>
+#ifdef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __modf, modfl, GLIBC_2_0);
+# endif
+#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __modf, modfl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_nan.c b/libc/sysdeps/ieee754/ldbl-opt/s_nan.c
new file mode 100644
index 000000000..418aad207
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_nan.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/s_nan.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __nan, nanl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_nanl.c b/libc/sysdeps/ieee754/ldbl-opt/s_nanl.c
new file mode 100644
index 000000000..9496e0b5c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_nanl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_nanl.c>
+long_double_symbol (libm, __nanl, nanl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_nearbyint.c b/libc/sysdeps/ieee754/ldbl-opt/s_nearbyint.c
new file mode 100644
index 000000000..a8b7973ac
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_nearbyint.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_nearbyint.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __nearbyint, nearbyintl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_nextafter.c b/libc/sysdeps/ieee754/ldbl-opt/s_nextafter.c
new file mode 100644
index 000000000..78e2c0ff3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_nextafter.c
@@ -0,0 +1,12 @@
+#include <math_ldbl_opt.h>
+#include <math/s_nextafter.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __nextafter, nextafterl, GLIBC_2_0);
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+strong_alias (__nextafter, __nexttowardd)
+strong_alias (__nextafter, __nexttowardld)
+#undef nexttoward
+compat_symbol (libm, __nexttowardd, nexttoward, GLIBC_2_1);
+compat_symbol (libm, __nexttowardld, nexttowardl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c b/libc/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c
new file mode 100644
index 000000000..d52526f71
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c
@@ -0,0 +1,77 @@
+/* Single precision version of nexttoward.c.
+ Conversion to IEEE single float by Jakub Jelinek, jj@ultra.linux.cz. */
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+/* IEEE functions
+ * __nexttowardfd(x,y)
+ * return the next machine floating-point number of x in the
+ * direction toward y.
+ * This is for machines which use different binary type for double and
+ * long double conditionally, y is long double equal to double.
+ * Special cases:
+ */
+
+#include <math_ldbl_opt.h>
+
+float __nldbl_nexttowardf(float x, double y);
+
+float __nldbl_nexttowardf(float x, double y)
+{
+ int32_t hx,hy,ix,iy;
+ u_int32_t ly;
+
+ GET_FLOAT_WORD(hx,x);
+ EXTRACT_WORDS(hy,ly,y);
+ ix = hx&0x7fffffff; /* |x| */
+ iy = hy&0x7fffffff; /* |y| */
+
+ if((ix>0x7f800000) || /* x is nan */
+ ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */
+ return x+y;
+ if((double) x==y) return y; /* x=y, return y */
+ if(ix==0) { /* x == 0 */
+ float x2;
+ SET_FLOAT_WORD(x,(u_int32_t)(hy&0x80000000)|1);/* return +-minsub*/
+ x2 = x*x;
+ if(x2==x) return x2; else return x; /* raise underflow flag */
+ }
+ if(hx>=0) { /* x > 0 */
+ if(hy<0||(ix>>23)>(iy>>20)-0x380
+ || ((ix>>23)==(iy>>20)-0x380
+ && (ix&0x7fffff)>(((hy<<3)|(ly>>29))&0x7fffff))) /* x > y, x -= ulp */
+ hx -= 1;
+ else /* x < y, x += ulp */
+ hx += 1;
+ } else { /* x < 0 */
+ if(hy>=0||(ix>>23)>(iy>>20)-0x380
+ || ((ix>>23)==(iy>>20)-0x380
+ && (ix&0x7fffff)>(((hy<<3)|(ly>>29))&0x7fffff))) /* x < y, x -= ulp */
+ hx -= 1;
+ else /* x > y, x += ulp */
+ hx += 1;
+ }
+ hy = hx&0x7f800000;
+ if(hy>=0x7f800000) return x+x; /* overflow */
+ if(hy<0x00800000) { /* underflow */
+ float x2 = x*x;
+ if(x2!=x) { /* raise underflow flag */
+ SET_FLOAT_WORD(x2,hx);
+ return x2;
+ }
+ }
+ SET_FLOAT_WORD(x,hx);
+ return x;
+}
+
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __nldbl_nexttowardf, nexttowardf, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_remquo.c b/libc/sysdeps/ieee754/ldbl-opt/s_remquo.c
new file mode 100644
index 000000000..9f3d7ba36
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_remquo.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_remquo.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __remquo, remquol, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_rint.c b/libc/sysdeps/ieee754/ldbl-opt/s_rint.c
new file mode 100644
index 000000000..d9b156ea2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_rint.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_rint.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __rint, rintl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_round.c b/libc/sysdeps/ieee754/ldbl-opt/s_round.c
new file mode 100644
index 000000000..edff2f017
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_round.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_round.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __round, roundl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_scalbln.c b/libc/sysdeps/ieee754/ldbl-opt/s_scalbln.c
new file mode 100644
index 000000000..2398bba49
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_scalbln.c
@@ -0,0 +1,9 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_scalbln.c>
+#ifdef IS_IN_libm
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __scalbln, scalblnl, GLIBC_2_1);
+#endif
+#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_1)
+compat_symbol (libc, __scalbln, scalblnl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_scalbn.c b/libc/sysdeps/ieee754/ldbl-opt/s_scalbn.c
new file mode 100644
index 000000000..094735ea5
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_scalbn.c
@@ -0,0 +1,9 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_scalbn.c>
+#ifdef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __scalbn, scalbnl, GLIBC_2_0);
+# endif
+#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __scalbn, scalbnl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_significand.c b/libc/sysdeps/ieee754/ldbl-opt/s_significand.c
new file mode 100644
index 000000000..5287c0906
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_significand.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/s_significand.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __significand, significandl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_significandl.c b/libc/sysdeps/ieee754/ldbl-opt/s_significandl.c
new file mode 100644
index 000000000..9339b4780
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_significandl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/s_significandl.c>
+long_double_symbol (libm, __significandl, significandl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_sin.c b/libc/sysdeps/ieee754/ldbl-opt/s_sin.c
new file mode 100644
index 000000000..a11d5a33d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_sin.c
@@ -0,0 +1,10 @@
+/* dbl-64/s_sin.c uses NAN and sincos identifiers internally. */
+#define sincos sincos_disable
+#include <math_ldbl_opt.h>
+#undef NAN
+#undef sincos
+#include <sysdeps/ieee754/dbl-64/s_sin.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __sin, sinl, GLIBC_2_0);
+compat_symbol (libm, __cos, cosl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_sincos.c b/libc/sysdeps/ieee754/ldbl-opt/s_sincos.c
new file mode 100644
index 000000000..6d2a48f25
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_sincos.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_sincos.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __sincos, sincosl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_tan.c b/libc/sysdeps/ieee754/ldbl-opt/s_tan.c
new file mode 100644
index 000000000..6b0fec006
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_tan.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_tan.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, tan, tanl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_tanh.c b/libc/sysdeps/ieee754/ldbl-opt/s_tanh.c
new file mode 100644
index 000000000..e763bbde7
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_tanh.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_tanh.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __tanh, tanhl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/s_trunc.c b/libc/sysdeps/ieee754/ldbl-opt/s_trunc.c
new file mode 100644
index 000000000..9d90a2bd7
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/s_trunc.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/s_trunc.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __trunc, truncl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_acos.c b/libc/sysdeps/ieee754/ldbl-opt/w_acos.c
new file mode 100644
index 000000000..2934041d4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_acos.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_acos.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __acos, acosl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_acosh.c b/libc/sysdeps/ieee754/ldbl-opt/w_acosh.c
new file mode 100644
index 000000000..7f7fa14e2
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_acosh.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_acosh.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __acosh, acoshl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_acoshl.c b/libc/sysdeps/ieee754/ldbl-opt/w_acoshl.c
new file mode 100644
index 000000000..6243c2ac8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_acoshl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_acoshl.c>
+long_double_symbol (libm, __acoshl, acoshl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_acosl.c b/libc/sysdeps/ieee754/ldbl-opt/w_acosl.c
new file mode 100644
index 000000000..8b6e890a5
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_acosl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_acosl.c>
+long_double_symbol (libm, __acosl, acosl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_asin.c b/libc/sysdeps/ieee754/ldbl-opt/w_asin.c
new file mode 100644
index 000000000..5e1d70ff6
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_asin.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_asin.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __asin, asinl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_asinl.c b/libc/sysdeps/ieee754/ldbl-opt/w_asinl.c
new file mode 100644
index 000000000..a58a224a3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_asinl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_asinl.c>
+long_double_symbol (libm, __asinl, asinl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_atan2.c b/libc/sysdeps/ieee754/ldbl-opt/w_atan2.c
new file mode 100644
index 000000000..f1d1501bd
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_atan2.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_atan2.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __atan2, atan2l, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_atan2l.c b/libc/sysdeps/ieee754/ldbl-opt/w_atan2l.c
new file mode 100644
index 000000000..01431eff4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_atan2l.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_atan2l.c>
+long_double_symbol (libm, __atan2l, atan2l);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_atanh.c b/libc/sysdeps/ieee754/ldbl-opt/w_atanh.c
new file mode 100644
index 000000000..b4cab87c3
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_atanh.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_atanh.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __atanh, atanhl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_atanhl.c b/libc/sysdeps/ieee754/ldbl-opt/w_atanhl.c
new file mode 100644
index 000000000..0dbc11448
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_atanhl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_atanhl.c>
+long_double_symbol (libm, __atanhl, atanhl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_cosh.c b/libc/sysdeps/ieee754/ldbl-opt/w_cosh.c
new file mode 100644
index 000000000..a6f56cf4c
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_cosh.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_cosh.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __cosh, coshl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_coshl.c b/libc/sysdeps/ieee754/ldbl-opt/w_coshl.c
new file mode 100644
index 000000000..8c7dccb7f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_coshl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_coshl.c>
+long_double_symbol (libm, __coshl, coshl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_drem.c b/libc/sysdeps/ieee754/ldbl-opt/w_drem.c
new file mode 100644
index 000000000..788a5d29d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_drem.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_drem.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __drem, dreml, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_dreml.c b/libc/sysdeps/ieee754/ldbl-opt/w_dreml.c
new file mode 100644
index 000000000..d14d7e202
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_dreml.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_dreml.c>
+long_double_symbol (libm, __dreml, dreml);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_exp.c b/libc/sysdeps/ieee754/ldbl-opt/w_exp.c
new file mode 100644
index 000000000..61fcfcc9d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_exp.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/ieee754/dbl-64/w_exp.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __exp, expl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_exp10.c b/libc/sysdeps/ieee754/ldbl-opt/w_exp10.c
new file mode 100644
index 000000000..990c48e61
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_exp10.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#include <math/w_exp10.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __exp10, exp10l, GLIBC_2_1);
+compat_symbol (libm, __pow10, pow10l, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_exp10l.c b/libc/sysdeps/ieee754/ldbl-opt/w_exp10l.c
new file mode 100644
index 000000000..e06dfb501
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_exp10l.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_exp10l.c>
+long_double_symbol (libm, __exp10l, exp10l);
+long_double_symbol (libm, __pow10l, pow10l);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_fmod.c b/libc/sysdeps/ieee754/ldbl-opt/w_fmod.c
new file mode 100644
index 000000000..81ad5057f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_fmod.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_fmod.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __fmod, fmodl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_fmodl.c b/libc/sysdeps/ieee754/ldbl-opt/w_fmodl.c
new file mode 100644
index 000000000..2a534a304
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_fmodl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_fmodl.c>
+long_double_symbol (libm, __fmodl, fmodl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_hypot.c b/libc/sysdeps/ieee754/ldbl-opt/w_hypot.c
new file mode 100644
index 000000000..e1cf1ffcf
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_hypot.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_hypot.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __hypot, hypotl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_hypotl.c b/libc/sysdeps/ieee754/ldbl-opt/w_hypotl.c
new file mode 100644
index 000000000..6c46bd4bd
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_hypotl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_hypotl.c>
+long_double_symbol (libm, __hypotl, hypotl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_j0.c b/libc/sysdeps/ieee754/ldbl-opt/w_j0.c
new file mode 100644
index 000000000..5c78aff08
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_j0.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#include <math/w_j0.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, j0, j0l, GLIBC_2_0);
+compat_symbol (libm, y0, y0l, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_j0l.c b/libc/sysdeps/ieee754/ldbl-opt/w_j0l.c
new file mode 100644
index 000000000..767a1bcad
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_j0l.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_j0l.c>
+long_double_symbol (libm, __j0l, j0l);
+long_double_symbol (libm, __y0l, y0l);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_j1.c b/libc/sysdeps/ieee754/ldbl-opt/w_j1.c
new file mode 100644
index 000000000..ed3dbc036
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_j1.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#include <math/w_j1.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, j1, j1l, GLIBC_2_0);
+compat_symbol (libm, y1, y1l, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_j1l.c b/libc/sysdeps/ieee754/ldbl-opt/w_j1l.c
new file mode 100644
index 000000000..946c36467
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_j1l.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_j1l.c>
+long_double_symbol (libm, __j1l, j1l);
+long_double_symbol (libm, __y1l, y1l);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_jn.c b/libc/sysdeps/ieee754/ldbl-opt/w_jn.c
new file mode 100644
index 000000000..7a7e0d434
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_jn.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#include <math/w_jn.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, jn, jnl, GLIBC_2_0);
+compat_symbol (libm, yn, ynl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_jnl.c b/libc/sysdeps/ieee754/ldbl-opt/w_jnl.c
new file mode 100644
index 000000000..5219543a9
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_jnl.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_jnl.c>
+long_double_symbol (libm, __jnl, jnl);
+long_double_symbol (libm, __ynl, ynl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_lgamma.c b/libc/sysdeps/ieee754/ldbl-opt/w_lgamma.c
new file mode 100644
index 000000000..ef801c550
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_lgamma.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#include <math/w_lgamma.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __lgamma, lgammal, GLIBC_2_0);
+compat_symbol (libm, __gamma, gammal, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_lgamma_r.c b/libc/sysdeps/ieee754/ldbl-opt/w_lgamma_r.c
new file mode 100644
index 000000000..eeab6a6b4
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_lgamma_r.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_lgamma_r.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __lgamma_r, lgammal_r, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_lgammal.c b/libc/sysdeps/ieee754/ldbl-opt/w_lgammal.c
new file mode 100644
index 000000000..9de7ec8f7
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_lgammal.c
@@ -0,0 +1,6 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_lgammal.c>
+long_double_symbol (libm, __lgammal, lgammal);
+long_double_symbol (libm, __gammal, gammal);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_lgammal_r.c b/libc/sysdeps/ieee754/ldbl-opt/w_lgammal_r.c
new file mode 100644
index 000000000..25459758d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_lgammal_r.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_lgammal_r.c>
+long_double_symbol (libm, __lgammal_r, lgammal_r);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_log.c b/libc/sysdeps/ieee754/ldbl-opt/w_log.c
new file mode 100644
index 000000000..bde1e31db
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_log.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_log.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __log, logl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_log10.c b/libc/sysdeps/ieee754/ldbl-opt/w_log10.c
new file mode 100644
index 000000000..74e716821
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_log10.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_log10.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __log10, log10l, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_log10l.c b/libc/sysdeps/ieee754/ldbl-opt/w_log10l.c
new file mode 100644
index 000000000..9c936e376
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_log10l.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_log10l.c>
+long_double_symbol (libm, __log10l, log10l);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_log2.c b/libc/sysdeps/ieee754/ldbl-opt/w_log2.c
new file mode 100644
index 000000000..9b9b45b21
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_log2.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_log2.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __log2, log2l, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_log2l.c b/libc/sysdeps/ieee754/ldbl-opt/w_log2l.c
new file mode 100644
index 000000000..c85968213
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_log2l.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_log2l.c>
+long_double_symbol (libm, __log2l, log2l);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_logl.c b/libc/sysdeps/ieee754/ldbl-opt/w_logl.c
new file mode 100644
index 000000000..c2354a02b
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_logl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_logl.c>
+long_double_symbol (libm, __logl, logl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_pow.c b/libc/sysdeps/ieee754/ldbl-opt/w_pow.c
new file mode 100644
index 000000000..2d98fb9be
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_pow.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_pow.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __pow, powl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_powl.c b/libc/sysdeps/ieee754/ldbl-opt/w_powl.c
new file mode 100644
index 000000000..85b892764
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_powl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_powl.c>
+long_double_symbol (libm, __powl, powl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_remainder.c b/libc/sysdeps/ieee754/ldbl-opt/w_remainder.c
new file mode 100644
index 000000000..94d98930f
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_remainder.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_remainder.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __remainder, remainderl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_remainderl.c b/libc/sysdeps/ieee754/ldbl-opt/w_remainderl.c
new file mode 100644
index 000000000..e450a25bb
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_remainderl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_remainderl.c>
+long_double_symbol (libm, __remainderl, remainderl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_scalb.c b/libc/sysdeps/ieee754/ldbl-opt/w_scalb.c
new file mode 100644
index 000000000..e2ac60159
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_scalb.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_scalb.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __scalb, scalbl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_scalbl.c b/libc/sysdeps/ieee754/ldbl-opt/w_scalbl.c
new file mode 100644
index 000000000..f3d3901f8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_scalbl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_scalbl.c>
+long_double_symbol (libm, __scalbl, scalbl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_sinh.c b/libc/sysdeps/ieee754/ldbl-opt/w_sinh.c
new file mode 100644
index 000000000..a5400b5eb
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_sinh.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_sinh.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __sinh, sinhl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_sinhl.c b/libc/sysdeps/ieee754/ldbl-opt/w_sinhl.c
new file mode 100644
index 000000000..b94f4ec84
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_sinhl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_sinhl.c>
+long_double_symbol (libm, __sinhl, sinhl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_sqrt.c b/libc/sysdeps/ieee754/ldbl-opt/w_sqrt.c
new file mode 100644
index 000000000..ca2ba061e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_sqrt.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_sqrt.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __sqrt, sqrtl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_sqrtl.c b/libc/sysdeps/ieee754/ldbl-opt/w_sqrtl.c
new file mode 100644
index 000000000..609f5bf3d
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_sqrtl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_sqrtl.c>
+long_double_symbol (libm, __sqrtl, sqrtl);
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_tgamma.c b/libc/sysdeps/ieee754/ldbl-opt/w_tgamma.c
new file mode 100644
index 000000000..cce9f348e
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_tgamma.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <math/w_tgamma.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __tgamma, tgammal, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/ieee754/ldbl-opt/w_tgammal.c b/libc/sysdeps/ieee754/ldbl-opt/w_tgammal.c
new file mode 100644
index 000000000..c3c511db8
--- /dev/null
+++ b/libc/sysdeps/ieee754/ldbl-opt/w_tgammal.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_tgammal.c>
+long_double_symbol (libm, __tgammal, tgammal);
diff --git a/libc/sysdeps/ieee754/s_lib_version.c b/libc/sysdeps/ieee754/s_lib_version.c
new file mode 100644
index 000000000..121bdaa54
--- /dev/null
+++ b/libc/sysdeps/ieee754/s_lib_version.c
@@ -0,0 +1,40 @@
+/* @(#)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/libc/sysdeps/ieee754/s_matherr.c b/libc/sysdeps/ieee754/s_matherr.c
new file mode 100644
index 000000000..1ad3eb333
--- /dev/null
+++ b/libc/sysdeps/ieee754/s_matherr.c
@@ -0,0 +1,35 @@
+/* @(#)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"
+
+#ifdef __STDC__
+ int
+ weak_function
+ __matherr(struct exception *x)
+#else
+ int
+ weak_function
+ __matherr(x)
+ struct exception *x;
+#endif
+{
+ int n=0;
+ if(x->arg1!=x->arg1) return 0;
+ return n;
+}
+weak_alias (__matherr, matherr)
diff --git a/libc/sysdeps/ieee754/s_signgam.c b/libc/sysdeps/ieee754/s_signgam.c
new file mode 100644
index 000000000..021b0ffca
--- /dev/null
+++ b/libc/sysdeps/ieee754/s_signgam.c
@@ -0,0 +1,3 @@
+#include "math.h"
+#include "math_private.h"
+int signgam;
diff --git a/libc/sysdeps/ieee754/support.c b/libc/sysdeps/ieee754/support.c
new file mode 100644
index 000000000..2651ea8be
--- /dev/null
+++ b/libc/sysdeps/ieee754/support.c
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)support.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * Some IEEE standard 754 recommended functions and remainder and sqrt for
+ * supporting the C elementary functions.
+ ******************************************************************************
+ * WARNING:
+ * These codes are developed (in double) to support the C elementary
+ * functions temporarily. They are not universal, and some of them are very
+ * slow (in particular, drem and sqrt is extremely inefficient). Each
+ * computer system should have its implementation of these functions using
+ * its own assembler.
+ ******************************************************************************
+ *
+ * IEEE 754 required operations:
+ * drem(x,p)
+ * returns x REM y = x - [x/y]*y , where [x/y] is the integer
+ * nearest x/y; in half way case, choose the even one.
+ * sqrt(x)
+ * returns the square root of x correctly rounded according to
+ * the rounding mod.
+ *
+ * IEEE 754 recommended functions:
+ * (a) copysign(x,y)
+ * returns x with the sign of y.
+ * (b) scalb(x,N)
+ * returns x * (2**N), for integer values N.
+ * (c) logb(x)
+ * returns the unbiased exponent of x, a signed integer in
+ * double precision, except that logb(0) is -INF, logb(INF)
+ * is +INF, and logb(NAN) is that NAN.
+ * (d) finite(x)
+ * returns the value TRUE if -INF < x < +INF and returns
+ * FALSE otherwise.
+ *
+ *
+ * CODED IN C BY K.C. NG, 11/25/84;
+ * REVISED BY K.C. NG on 1/22/85, 2/13/85, 3/24/85.
+ */
+
+#include "mathimpl.h"
+
+#if defined(vax)||defined(tahoe) /* VAX D format */
+#include <errno.h>
+ static const unsigned short msign=0x7fff , mexp =0x7f80 ;
+ static const short prep1=57, gap=7, bias=129 ;
+ static const double novf=1.7E38, nunf=3.0E-39, zero=0.0 ;
+#else /* defined(vax)||defined(tahoe) */
+ static const unsigned short msign=0x7fff, mexp =0x7ff0 ;
+ static const short prep1=54, gap=4, bias=1023 ;
+ static const double novf=1.7E308, nunf=3.0E-308,zero=0.0;
+#endif /* defined(vax)||defined(tahoe) */
+
+double scalb(x,N)
+double x; int N;
+{
+ int k;
+
+#ifdef national
+ unsigned short *px=(unsigned short *) &x + 3;
+#else /* national */
+ unsigned short *px=(unsigned short *) &x;
+#endif /* national */
+
+ if( x == zero ) return(x);
+
+#if defined(vax)||defined(tahoe)
+ if( (k= *px & mexp ) != ~msign ) {
+ if (N < -260)
+ return(nunf*nunf);
+ else if (N > 260) {
+ return(copysign(infnan(ERANGE),x));
+ }
+#else /* defined(vax)||defined(tahoe) */
+ if( (k= *px & mexp ) != mexp ) {
+ if( N<-2100) return(nunf*nunf); else if(N>2100) return(novf+novf);
+ if( k == 0 ) {
+ x *= scalb(1.0,(int)prep1); N -= prep1; return(scalb(x,N));}
+#endif /* defined(vax)||defined(tahoe) */
+
+ if((k = (k>>gap)+ N) > 0 )
+ if( k < (mexp>>gap) ) *px = (*px&~mexp) | (k<<gap);
+ else x=novf+novf; /* overflow */
+ else
+ if( k > -prep1 )
+ /* gradual underflow */
+ {*px=(*px&~mexp)|(short)(1<<gap); x *= scalb(1.0,k-1);}
+ else
+ return(nunf*nunf);
+ }
+ return(x);
+}
+
+
+double copysign(x,y)
+double x,y;
+{
+#ifdef national
+ unsigned short *px=(unsigned short *) &x+3,
+ *py=(unsigned short *) &y+3;
+#else /* national */
+ unsigned short *px=(unsigned short *) &x,
+ *py=(unsigned short *) &y;
+#endif /* national */
+
+#if defined(vax)||defined(tahoe)
+ if ( (*px & mexp) == 0 ) return(x);
+#endif /* defined(vax)||defined(tahoe) */
+
+ *px = ( *px & msign ) | ( *py & ~msign );
+ return(x);
+}
+
+double logb(x)
+double x;
+{
+
+#ifdef national
+ short *px=(short *) &x+3, k;
+#else /* national */
+ short *px=(short *) &x, k;
+#endif /* national */
+
+#if defined(vax)||defined(tahoe)
+ return (int)(((*px&mexp)>>gap)-bias);
+#else /* defined(vax)||defined(tahoe) */
+ if( (k= *px & mexp ) != mexp )
+ if ( k != 0 )
+ return ( (k>>gap) - bias );
+ else if( x != zero)
+ return ( -1022.0 );
+ else
+ return(-(1.0/zero));
+ else if(x != x)
+ return(x);
+ else
+ {*px &= msign; return(x);}
+#endif /* defined(vax)||defined(tahoe) */
+}
+
+finite(x)
+double x;
+{
+#if defined(vax)||defined(tahoe)
+ return(1);
+#else /* defined(vax)||defined(tahoe) */
+#ifdef national
+ return( (*((short *) &x+3 ) & mexp ) != mexp );
+#else /* national */
+ return( (*((short *) &x ) & mexp ) != mexp );
+#endif /* national */
+#endif /* defined(vax)||defined(tahoe) */
+}
+
+double drem(x,p)
+double x,p;
+{
+ short sign;
+ double hp,dp,tmp;
+ unsigned short k;
+#ifdef national
+ unsigned short
+ *px=(unsigned short *) &x +3,
+ *pp=(unsigned short *) &p +3,
+ *pd=(unsigned short *) &dp +3,
+ *pt=(unsigned short *) &tmp+3;
+#else /* national */
+ unsigned short
+ *px=(unsigned short *) &x ,
+ *pp=(unsigned short *) &p ,
+ *pd=(unsigned short *) &dp ,
+ *pt=(unsigned short *) &tmp;
+#endif /* national */
+
+ *pp &= msign ;
+
+#if defined(vax)||defined(tahoe)
+ if( ( *px & mexp ) == ~msign ) /* is x a reserved operand? */
+#else /* defined(vax)||defined(tahoe) */
+ if( ( *px & mexp ) == mexp )
+#endif /* defined(vax)||defined(tahoe) */
+ return (x-p)-(x-p); /* create nan if x is inf */
+ if (p == zero) {
+#if defined(vax)||defined(tahoe)
+ return(infnan(EDOM));
+#else /* defined(vax)||defined(tahoe) */
+ return zero/zero;
+#endif /* defined(vax)||defined(tahoe) */
+ }
+
+#if defined(vax)||defined(tahoe)
+ if( ( *pp & mexp ) == ~msign ) /* is p a reserved operand? */
+#else /* defined(vax)||defined(tahoe) */
+ if( ( *pp & mexp ) == mexp )
+#endif /* defined(vax)||defined(tahoe) */
+ { if (p != p) return p; else return x;}
+
+ else if ( ((*pp & mexp)>>gap) <= 1 )
+ /* subnormal p, or almost subnormal p */
+ { double b; b=scalb(1.0,(int)prep1);
+ p *= b; x = drem(x,p); x *= b; return(drem(x,p)/b);}
+ else if ( p >= novf/2)
+ { p /= 2 ; x /= 2; return(drem(x,p)*2);}
+ else
+ {
+ dp=p+p; hp=p/2;
+ sign= *px & ~msign ;
+ *px &= msign ;
+ while ( x > dp )
+ {
+ k=(*px & mexp) - (*pd & mexp) ;
+ tmp = dp ;
+ *pt += k ;
+
+#if defined(vax)||defined(tahoe)
+ if( x < tmp ) *pt -= 128 ;
+#else /* defined(vax)||defined(tahoe) */
+ if( x < tmp ) *pt -= 16 ;
+#endif /* defined(vax)||defined(tahoe) */
+
+ x -= tmp ;
+ }
+ if ( x > hp )
+ { x -= p ; if ( x >= hp ) x -= p ; }
+
+#if defined(vax)||defined(tahoe)
+ if (x)
+#endif /* defined(vax)||defined(tahoe) */
+ *px ^= sign;
+ return( x);
+
+ }
+}
+
+
+double sqrt(x)
+double x;
+{
+ double q,s,b,r;
+ double t;
+ double const zero=0.0;
+ int m,n,i;
+#if defined(vax)||defined(tahoe)
+ int k=54;
+#else /* defined(vax)||defined(tahoe) */
+ int k=51;
+#endif /* defined(vax)||defined(tahoe) */
+
+ /* sqrt(NaN) is NaN, sqrt(+-0) = +-0 */
+ if(x!=x||x==zero) return(x);
+
+ /* sqrt(negative) is invalid */
+ if(x<zero) {
+#if defined(vax)||defined(tahoe)
+ return (infnan(EDOM)); /* NaN */
+#else /* defined(vax)||defined(tahoe) */
+ return(zero/zero);
+#endif /* defined(vax)||defined(tahoe) */
+ }
+
+ /* sqrt(INF) is INF */
+ if(!finite(x)) return(x);
+
+ /* scale x to [1,4) */
+ n=logb(x);
+ x=scalb(x,-n);
+ if((m=logb(x))!=0) x=scalb(x,-m); /* subnormal number */
+ m += n;
+ n = m/2;
+ if((n+n)!=m) {x *= 2; m -=1; n=m/2;}
+
+ /* generate sqrt(x) bit by bit (accumulating in q) */
+ q=1.0; s=4.0; x -= 1.0; r=1;
+ for(i=1;i<=k;i++) {
+ t=s+1; x *= 4; r /= 2;
+ if(t<=x) {
+ s=t+t+2, x -= t; q += r;}
+ else
+ s *= 2;
+ }
+
+ /* generate the last bit and determine the final rounding */
+ r/=2; x *= 4;
+ if(x==zero) goto end; 100+r; /* trigger inexact flag */
+ if(s<x) {
+ q+=r; x -=s; s += 2; s *= 2; x *= 4;
+ t = (x-s)-5;
+ b=1.0+3*r/4; if(b==1.0) goto end; /* b==1 : Round-to-zero */
+ b=1.0+r/4; if(b>1.0) t=1; /* b>1 : Round-to-(+INF) */
+ if(t>=0) q+=r; } /* else: Round-to-nearest */
+ else {
+ s *= 2; x *= 4;
+ t = (x-s)-1;
+ b=1.0+3*r/4; if(b==1.0) goto end;
+ b=1.0+r/4; if(b>1.0) t=1;
+ if(t>=0) q+=r; }
+
+end: return(scalb(q,n));
+}
+
+#if 0
+/* DREM(X,Y)
+ * RETURN X REM Y =X-N*Y, N=[X/Y] ROUNDED (ROUNDED TO EVEN IN THE HALF WAY CASE)
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * INTENDED FOR ASSEMBLY LANGUAGE
+ * CODED IN C BY K.C. NG, 3/23/85, 4/8/85.
+ *
+ * Warning: this code should not get compiled in unless ALL of
+ * the following machine-dependent routines are supplied.
+ *
+ * Required machine dependent functions (not on a VAX):
+ * swapINX(i): save inexact flag and reset it to "i"
+ * swapENI(e): save inexact enable and reset it to "e"
+ */
+
+double drem(x,y)
+double x,y;
+{
+
+#ifdef national /* order of words in floating point number */
+ static const n0=3,n1=2,n2=1,n3=0;
+#else /* VAX, SUN, ZILOG, TAHOE */
+ static const n0=0,n1=1,n2=2,n3=3;
+#endif
+
+ static const unsigned short mexp =0x7ff0, m25 =0x0190, m57 =0x0390;
+ static const double zero=0.0;
+ double hy,y1,t,t1;
+ short k;
+ long n;
+ int i,e;
+ unsigned short xexp,yexp, *px =(unsigned short *) &x ,
+ nx,nf, *py =(unsigned short *) &y ,
+ sign, *pt =(unsigned short *) &t ,
+ *pt1 =(unsigned short *) &t1 ;
+
+ xexp = px[n0] & mexp ; /* exponent of x */
+ yexp = py[n0] & mexp ; /* exponent of y */
+ sign = px[n0] &0x8000; /* sign of x */
+
+/* return NaN if x is NaN, or y is NaN, or x is INF, or y is zero */
+ if(x!=x) return(x); if(y!=y) return(y); /* x or y is NaN */
+ if( xexp == mexp ) return(zero/zero); /* x is INF */
+ if(y==zero) return(y/y);
+
+/* save the inexact flag and inexact enable in i and e respectively
+ * and reset them to zero
+ */
+ i=swapINX(0); e=swapENI(0);
+
+/* subnormal number */
+ nx=0;
+ if(yexp==0) {t=1.0,pt[n0]+=m57; y*=t; nx=m57;}
+
+/* if y is tiny (biased exponent <= 57), scale up y to y*2**57 */
+ if( yexp <= m57 ) {py[n0]+=m57; nx+=m57; yexp+=m57;}
+
+ nf=nx;
+ py[n0] &= 0x7fff;
+ px[n0] &= 0x7fff;
+
+/* mask off the least significant 27 bits of y */
+ t=y; pt[n3]=0; pt[n2]&=0xf800; y1=t;
+
+/* LOOP: argument reduction on x whenever x > y */
+loop:
+ while ( x > y )
+ {
+ t=y;
+ t1=y1;
+ xexp=px[n0]&mexp; /* exponent of x */
+ k=xexp-yexp-m25;
+ if(k>0) /* if x/y >= 2**26, scale up y so that x/y < 2**26 */
+ {pt[n0]+=k;pt1[n0]+=k;}
+ n=x/t; x=(x-n*t1)-n*(t-t1);
+ }
+ /* end while (x > y) */
+
+ if(nx!=0) {t=1.0; pt[n0]+=nx; x*=t; nx=0; goto loop;}
+
+/* final adjustment */
+
+ hy=y/2.0;
+ if(x>hy||((x==hy)&&n%2==1)) x-=y;
+ px[n0] ^= sign;
+ if(nf!=0) { t=1.0; pt[n0]-=nf; x*=t;}
+
+/* restore inexact flag and inexact enable */
+ swapINX(i); swapENI(e);
+
+ return(x);
+}
+#endif
+
+#if 0
+/* SQRT
+ * RETURN CORRECTLY ROUNDED (ACCORDING TO THE ROUNDING MODE) SQRT
+ * FOR IEEE DOUBLE PRECISION ONLY, INTENDED FOR ASSEMBLY LANGUAGE
+ * CODED IN C BY K.C. NG, 3/22/85.
+ *
+ * Warning: this code should not get compiled in unless ALL of
+ * the following machine-dependent routines are supplied.
+ *
+ * Required machine dependent functions:
+ * swapINX(i) ...return the status of INEXACT flag and reset it to "i"
+ * swapRM(r) ...return the current Rounding Mode and reset it to "r"
+ * swapENI(e) ...return the status of inexact enable and reset it to "e"
+ * addc(t) ...perform t=t+1 regarding t as a 64 bit unsigned integer
+ * subc(t) ...perform t=t-1 regarding t as a 64 bit unsigned integer
+ */
+
+static const unsigned long table[] = {
+0, 1204, 3062, 5746, 9193, 13348, 18162, 23592, 29598, 36145, 43202, 50740,
+58733, 67158, 75992, 85215, 83599, 71378, 60428, 50647, 41945, 34246, 27478,
+21581, 16499, 12183, 8588, 5674, 3403, 1742, 661, 130, };
+
+double newsqrt(x)
+double x;
+{
+ double y,z,t,addc(),subc()
+ double const b54=134217728.*134217728.; /* b54=2**54 */
+ long mx,scalx;
+ long const mexp=0x7ff00000;
+ int i,j,r,e,swapINX(),swapRM(),swapENI();
+ unsigned long *py=(unsigned long *) &y ,
+ *pt=(unsigned long *) &t ,
+ *px=(unsigned long *) &x ;
+#ifdef national /* ordering of word in a floating point number */
+ const int n0=1, n1=0;
+#else
+ const int n0=0, n1=1;
+#endif
+/* Rounding Mode: RN ...round-to-nearest
+ * RZ ...round-towards 0
+ * RP ...round-towards +INF
+ * RM ...round-towards -INF
+ */
+ const int RN=0,RZ=1,RP=2,RM=3;
+ /* machine dependent: work on a Zilog Z8070
+ * and a National 32081 & 16081
+ */
+
+/* exceptions */
+ if(x!=x||x==0.0) return(x); /* sqrt(NaN) is NaN, sqrt(+-0) = +-0 */
+ if(x<0) return((x-x)/(x-x)); /* sqrt(negative) is invalid */
+ if((mx=px[n0]&mexp)==mexp) return(x); /* sqrt(+INF) is +INF */
+
+/* save, reset, initialize */
+ e=swapENI(0); /* ...save and reset the inexact enable */
+ i=swapINX(0); /* ...save INEXACT flag */
+ r=swapRM(RN); /* ...save and reset the Rounding Mode to RN */
+ scalx=0;
+
+/* subnormal number, scale up x to x*2**54 */
+ if(mx==0) {x *= b54 ; scalx-=0x01b00000;}
+
+/* scale x to avoid intermediate over/underflow:
+ * if (x > 2**512) x=x/2**512; if (x < 2**-512) x=x*2**512 */
+ if(mx>0x5ff00000) {px[n0] -= 0x20000000; scalx+= 0x10000000;}
+ if(mx<0x1ff00000) {px[n0] += 0x20000000; scalx-= 0x10000000;}
+
+/* magic initial approximation to almost 8 sig. bits */
+ py[n0]=(px[n0]>>1)+0x1ff80000;
+ py[n0]=py[n0]-table[(py[n0]>>15)&31];
+
+/* Heron's rule once with correction to improve y to almost 18 sig. bits */
+ t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0;
+
+/* triple to almost 56 sig. bits; now y approx. sqrt(x) to within 1 ulp */
+ t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y;
+ t=z/(t+x) ; pt[n0]+=0x00100000; y+=t;
+
+/* twiddle last bit to force y correctly rounded */
+ swapRM(RZ); /* ...set Rounding Mode to round-toward-zero */
+ swapINX(0); /* ...clear INEXACT flag */
+ swapENI(e); /* ...restore inexact enable status */
+ t=x/y; /* ...chopped quotient, possibly inexact */
+ j=swapINX(i); /* ...read and restore inexact flag */
+ if(j==0) { if(t==y) goto end; else t=subc(t); } /* ...t=t-ulp */
+ b54+0.1; /* ..trigger inexact flag, sqrt(x) is inexact */
+ if(r==RN) t=addc(t); /* ...t=t+ulp */
+ else if(r==RP) { t=addc(t);y=addc(y);}/* ...t=t+ulp;y=y+ulp; */
+ y=y+t; /* ...chopped sum */
+ py[n0]=py[n0]-0x00100000; /* ...correctly rounded sqrt(x) */
+end: py[n0]=py[n0]+scalx; /* ...scale back y */
+ swapRM(r); /* ...restore Rounding Mode */
+ return(y);
+}
+#endif
diff --git a/libc/sysdeps/mach/Makefile b/libc/sysdeps/mach/Makefile
new file mode 100644
index 000000000..af2c273e4
--- /dev/null
+++ b/libc/sysdeps/mach/Makefile
@@ -0,0 +1,52 @@
+# Copyright (C) 1993,1994,1996,1997,2002,2003 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifdef in-Makerules
+
+# Look for header files in mach/ under the top-level library source directory.
+# Look for generated header files where they get created.
+includes += -I$(..)mach -I$(common-objpfx)mach/
+
+ifneq (mach,$(subdir))
+# Subdirectories other than mach/ might use the generated Mach headers.
+# So make sure we get a chance to run in mach/ to make them before all else.
+
+mach-objpfx = $(common-objpfx)mach/
+else
+mach-objpfx = $(objpfx)
+endif
+
+# These are all the generated files that <mach.h> includes.
+# Actually, it's only some of them. We omit mach_interface.h
+# because it's different in Darwin and the conditional crap is
+# too much trouble. This should suffice for getting the mach/Makefile
+# rules invoked when they need to be.
+mach-before-compile := $(mach-objpfx)mach-shortcuts.h \
+ $(patsubst %,$(mach-objpfx)mach/mach_%.h,\
+ port host)
+
+ifneq (mach,$(subdir))
+# This patsubst generates patterns like `m%h-shortcuts.h', which are damn
+# likely to match just the corresponding particular file we want.
+$(patsubst mach%,m\%h%,$(mach-before-compile)): # Run only if doesn't exist.
+ $(MAKE) -C $(..)mach mach-before-compile no_deps=t generating=t
+
+before-compile += $(mach-before-compile)
+endif
+
+endif # in-Makerules
diff --git a/libc/sysdeps/mach/Subdirs b/libc/sysdeps/mach/Subdirs
new file mode 100644
index 000000000..24fa4a3c9
--- /dev/null
+++ b/libc/sysdeps/mach/Subdirs
@@ -0,0 +1,9 @@
+# This file says that the mach subdirectory should appear before all others.
+# The mach and hurd subdirectories have many generated header files which
+# much of the rest of the library depends on, so it is best to build them
+# first (and mach before hurd, at that). The before-compile additions in
+# sysdeps/{mach,hurd}/Makefile should make it reliably work for these files
+# not to exist when making in other directories, but it will be slower that
+# way with more somewhat expensive `make' invocations.
+
+first mach
diff --git a/libc/sysdeps/mach/_strerror.c b/libc/sysdeps/mach/_strerror.c
new file mode 100644
index 000000000..a67bbb962
--- /dev/null
+++ b/libc/sysdeps/mach/_strerror.c
@@ -0,0 +1,121 @@
+/* Copyright (C) 1993,95,96,97,98,2000,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <libintl.h>
+#include <stdio.h>
+#include <string.h>
+#include <mach/error.h>
+#include <errorlib.h>
+#include <sys/param.h>
+#include <stdio-common/_itoa.h>
+
+/* It is critical here that we always use the `dcgettext' function for
+ the message translation. Since <libintl.h> only defines the macro
+ `dgettext' to use `dcgettext' for optimizing programs this is not
+ always guaranteed. */
+#ifndef dgettext
+# include <locale.h> /* We need LC_MESSAGES. */
+# define dgettext(domainname, msgid) dcgettext (domainname, msgid, LC_MESSAGES)
+#endif
+
+/* Return a string describing the errno code in ERRNUM. */
+char *
+__strerror_r (int errnum, char *buf, size_t buflen)
+{
+ int system;
+ int sub;
+ int code;
+ const struct error_system *es;
+ extern void __mach_error_map_compat (int *);
+
+ __mach_error_map_compat (&errnum);
+
+ system = err_get_system (errnum);
+ sub = err_get_sub (errnum);
+ code = err_get_code (errnum);
+
+ if (system > err_max_system || ! __mach_error_systems[system].bad_sub)
+ {
+ /* Buffer we use to print the number in. For a maximum size for
+ `int' of 8 bytes we never need more than 20 digits. */
+ char numbuf[21];
+ const char *unk = _("Error in unknown error system: ");
+ const size_t unklen = strlen (unk);
+ char *p, *q;
+
+ numbuf[20] = '\0';
+ p = _itoa_word (errnum, &numbuf[20], 16, 1);
+
+ /* Now construct the result while taking care for the destination
+ buffer size. */
+ q = __mempcpy (buf, unk, MIN (unklen, buflen));
+ if (unklen < buflen)
+ memcpy (q, p, MIN (&numbuf[21] - p, buflen - unklen));
+
+ /* Terminate the string in any case. */
+ if (buflen > 0)
+ buf[buflen - 1] = '\0';
+
+ return buf;
+ }
+
+ es = &__mach_error_systems[system];
+
+ if (sub >= es->max_sub)
+ return (char *) es->bad_sub;
+
+ if (code >= es->subsystem[sub].max_code)
+ {
+ /* Buffer we use to print the number in. For a maximum size for
+ `int' of 8 bytes we never need more than 20 digits. */
+ char numbuf[21];
+ const char *unk = _("Unknown error ");
+ const size_t unklen = strlen (unk);
+ char *p, *q;
+ size_t len = strlen (es->subsystem[sub].subsys_name);
+
+ numbuf[20] = '\0';
+ p = _itoa_word (errnum, &numbuf[20], 10, 0);
+
+ /* Now construct the result while taking care for the destination
+ buffer size. */
+ q = __mempcpy (buf, unk, MIN (unklen, buflen));
+ if (unklen < buflen)
+ {
+ q = __mempcpy (q, es->subsystem[sub].subsys_name,
+ MIN (len, buflen - unklen));
+ if (unklen + len < buflen)
+ {
+ *q++ = ' ';
+ if (unklen + len + 1 < buflen)
+ memcpy (q, p,
+ MIN (&numbuf[21] - p, buflen - unklen - len - 1));
+ }
+ }
+
+ /* Terminate the string in any case. */
+ if (buflen > 0)
+ buf[buflen - 1] = '\0';
+
+ return buf;
+ }
+
+ return (char *) _(es->subsystem[sub].codes[code]);
+}
+libc_hidden_def (__strerror_r)
+weak_alias (__strerror_r, strerror_r)
diff --git a/libc/sysdeps/mach/adjtime.c b/libc/sysdeps/mach/adjtime.c
new file mode 100644
index 000000000..612a32043
--- /dev/null
+++ b/libc/sysdeps/mach/adjtime.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/time.h>
+#include <hurd.h>
+
+/* Adjust the current time of day by the amount in DELTA.
+ If OLDDELTA is not NULL, it is filled in with the amount
+ of time adjustment remaining to be done from the last `__adjtime' call.
+ This call is restricted to the super-user. */
+int
+__adjtime (delta, olddelta)
+ const struct timeval *delta;
+ struct timeval *olddelta;
+{
+ error_t err;
+ mach_port_t hostpriv;
+
+ hostpriv = __pid2task (-1);
+ if (hostpriv == MACH_PORT_NULL)
+ return -1;
+ err = __host_adjust_time (hostpriv, delta, olddelta);
+ __mach_port_deallocate (__mach_task_self (), hostpriv);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__adjtime, adjtime)
diff --git a/libc/sysdeps/mach/alpha/machine-lock.h b/libc/sysdeps/mach/alpha/machine-lock.h
new file mode 100644
index 000000000..80f8750c8
--- /dev/null
+++ b/libc/sysdeps/mach/alpha/machine-lock.h
@@ -0,0 +1,80 @@
+/* Machine-specific definition for spin locks. Alpha version.
+ Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MACHINE_LOCK_H
+#define _MACHINE_LOCK_H
+
+/* The type of a spin lock variable. */
+
+typedef __volatile long int __spin_lock_t;
+
+/* Value to initialize `__spin_lock_t' variables to. */
+
+#define __SPIN_LOCK_INITIALIZER 0L
+
+
+#ifndef _EXTERN_INLINE
+#define _EXTERN_INLINE extern __inline
+#endif
+
+/* Unlock LOCK. */
+
+_EXTERN_INLINE void
+__spin_unlock (__spin_lock_t *__lock)
+{
+ __asm__ __volatile__ ("mb; stq $31, %0; mb"
+ : "=m" (__lock));
+}
+
+/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */
+
+_EXTERN_INLINE int
+__spin_try_lock (register __spin_lock_t *__lock)
+{
+ register long int __rtn, __tmp;
+
+ do
+ {
+ __asm__ __volatile__ ("mb; ldq_l %0,%1" /* Load lock value into TMP. */
+ : "=r" (__tmp) : "m" (*__lock));
+ __rtn = 2; /* Load locked value into RTN. */
+ if (__tmp)
+ /* The lock is already taken. */
+ return 0;
+
+ /* The lock is not taken; try to get it now. */
+ __asm__ __volatile__ ("stq_c %0,%1"
+ : "=r" (__rtn), "=m" (*__lock)
+ : "0" (__rtn), "1" (*__lock));
+ /* RTN is clear if stq_c was interrupted; loop to try the lock again. */
+ } while (! __rtn);
+ /* RTN is now nonzero; we have the lock. */
+ return __rtn;
+}
+
+/* Return nonzero if LOCK is locked. */
+
+_EXTERN_INLINE int
+__spin_lock_locked (__spin_lock_t *__lock)
+{
+ return *__lock != 0;
+}
+
+
+#endif /* machine-lock.h */
diff --git a/libc/sysdeps/mach/alpha/machine-sp.h b/libc/sysdeps/mach/alpha/machine-sp.h
new file mode 100644
index 000000000..b73752557
--- /dev/null
+++ b/libc/sysdeps/mach/alpha/machine-sp.h
@@ -0,0 +1,36 @@
+/* Machine-specific function to return the stack pointer. Alpha version.
+ Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MACHINE_SP_H
+#define _MACHINE_SP_H
+
+/* Return the current stack pointer. */
+
+#ifndef _EXTERN_INLINE
+#define _EXTERN_INLINE extern __inline
+#endif
+
+_EXTERN_INLINE void *
+__thread_stack_pointer (void)
+{
+ register void *__sp__ __asm__ ("$30");
+ return __sp__;
+}
+
+#endif /* machine-sp.h */
diff --git a/libc/sysdeps/mach/alpha/setfpucw.c b/libc/sysdeps/mach/alpha/setfpucw.c
new file mode 100644
index 000000000..a2887c8df
--- /dev/null
+++ b/libc/sysdeps/mach/alpha/setfpucw.c
@@ -0,0 +1,69 @@
+/* Set FP exception mask and rounding mode. Mach/Alpha version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fpu_control.h>
+
+
+#define FPCR_DYN_SHIFT 58 /* first dynamic rounding mode bit */
+#define FPCR_DYN_CHOPPED (0x0UL << FPCR_DYN_SHIFT) /* towards 0 */
+#define FPCR_DYN_MINUS (0x1UL << FPCR_DYN_SHIFT) /* towards -INF */
+#define FPCR_DYN_NORMAL (0x2UL << FPCR_DYN_SHIFT) /* towards nearest */
+#define FPCR_DYN_PLUS (0x3UL << FPCR_DYN_SHIFT) /* towards +INF */
+#define FPCR_DYN_MASK (0x3UL << FPCR_DYN_SHIFT)
+
+static inline unsigned long
+rdfpcr (void)
+{
+ unsigned long fpcr;
+ asm ("excb; mf_fpcr %0" : "=f"(fpcr));
+ return fpcr;
+}
+
+static inline void
+wrfpcr (unsigned long fpcr)
+{
+ asm volatile ("mt_fpcr %0; excb" : : "f"(fpcr));
+}
+
+
+void
+__setfpucw (fpu_control_t fpu_control)
+{
+ unsigned long fpcr;
+
+ if (!fpu_control)
+ fpu_control = _FPU_DEFAULT;
+
+ /* first, set dynamic rounding mode: */
+
+ fpcr = rdfpcr();
+ fpcr &= ~FPCR_DYN_MASK;
+ switch (fpu_control & 0xc00)
+ {
+ case _FPU_RC_NEAREST: fpcr |= FPCR_DYN_NORMAL; break;
+ case _FPU_RC_DOWN: fpcr |= FPCR_DYN_MINUS; break;
+ case _FPU_RC_UP: fpcr |= FPCR_DYN_PLUS; break;
+ case _FPU_RC_ZERO: fpcr |= FPCR_DYN_CHOPPED; break;
+ }
+ wrfpcr(fpcr);
+
+ /* XXX trap bits? */
+
+ __fpu_control = fpu_control; /* update global copy */
+}
diff --git a/libc/sysdeps/mach/alpha/syscall.S b/libc/sysdeps/mach/alpha/syscall.S
new file mode 100644
index 000000000..15fc5b75b
--- /dev/null
+++ b/libc/sysdeps/mach/alpha/syscall.S
@@ -0,0 +1,37 @@
+/* Copyright (C) 1994,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY (syscall)
+ mov a0, v0 /* Load system call number from first arg. */
+ mov a1, a0
+ mov a2, a1
+ mov a3, a2
+ mov a4, a3
+ mov a5, a4
+ /* Load the remaining possible args (up to 11) from the stack. */
+ ldq a5,0(sp)
+ ldq t0,8(sp)
+ ldq t1,16(sp)
+ ldq t2,24(sp)
+ ldq t3,32(sp)
+ ldq t4,40(sp)
+ callsys
+ ret
+END (syscall)
diff --git a/libc/sysdeps/mach/alpha/sysdep.h b/libc/sysdeps/mach/alpha/sysdep.h
new file mode 100644
index 000000000..84e21c8d5
--- /dev/null
+++ b/libc/sysdeps/mach/alpha/sysdep.h
@@ -0,0 +1,59 @@
+/* Copyright (C) 1994,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define MOVE(x,y) mov x, y
+
+#define LOSE asm volatile ("call_pal 0") /* halt */
+
+#define START_MACHDEP \
+ asm ("_start: mov $30, $16\n" /* Put initial SP in a0. */ \
+ " br $27, 1f\n" /* Load GP from PC. */ \
+ "1: ldgp $29, 0($27)\n" \
+ " jmp $26, _start0"); /* Jump to _start0; don't return. */
+#define START_ARGS char **sparg
+#define SNARF_ARGS(argc, argv, envp) \
+ (envp = &(argv = &sparg[1])[(argc = *(int *) sparg) + 1])
+
+#define CALL_WITH_SP(fn, sp) \
+ ({ register long int __fn = (long int) fn, __sp = (long int) sp; \
+ asm volatile ("mov %0,$30; jmp $31, (%1); ldgp $29, 0(%1)" \
+ : : "r" (__sp), "r" (__fn)); })
+
+#define STACK_GROWTH_DOWN
+
+#define RETURN_TO(sp, pc, retval) \
+ asm volatile ("mov %0,$30; jmp $31, (%1); mov %2,$0" \
+ : : "r" (sp), "r" (pc), "r" ((long int) (retval)));
+
+#define ALIGN 3
+#include <sysdeps/mach/sysdep.h>
+
+/* Alpha needs the .ent and .frame magic that the generic version lacks. */
+#undef ENTRY
+#define ENTRY(name) \
+ .globl name; \
+ .align 3; \
+ .ent name, 0; \
+ name##: \
+ .frame sp, 0, ra
+
+#include <mach/alpha/asm.h>
+#undef at
+#define at 28
+#define AT $28
+#define fp s6
diff --git a/libc/sysdeps/mach/alpha/thread_state.h b/libc/sysdeps/mach/alpha/thread_state.h
new file mode 100644
index 000000000..0c9527bd2
--- /dev/null
+++ b/libc/sysdeps/mach/alpha/thread_state.h
@@ -0,0 +1,39 @@
+/* Mach thread state definitions for machine-independent code. Alpha version.
+ Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <mach/machine/thread_status.h>
+
+#define MACHINE_THREAD_STATE_FLAVOR ALPHA_THREAD_STATE
+#define MACHINE_THREAD_STATE_COUNT ALPHA_THREAD_STATE_COUNT
+
+#define machine_thread_state alpha_thread_state
+
+#define PC pc
+#define SP r30
+#define SYSRETURN r0
+
+struct machine_thread_all_state
+ {
+ int set; /* Mask of bits (1 << FLAVOR). */
+ struct alpha_thread_state basic;
+ struct alpha_exc_state exc;
+ struct alpha_float_state fpu;
+ };
+
+#include <sysdeps/mach/thread_state.h>
diff --git a/libc/sysdeps/mach/bits/libc-lock.h b/libc/sysdeps/mach/bits/libc-lock.h
new file mode 100644
index 000000000..76bbd02d0
--- /dev/null
+++ b/libc/sysdeps/mach/bits/libc-lock.h
@@ -0,0 +1,144 @@
+/* libc-internal interface for mutex locks. Mach cthreads version.
+ Copyright (C) 1996,97,98,2000,01, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_LIBC_LOCK_H
+#define _BITS_LIBC_LOCK_H 1
+
+#ifdef _LIBC
+#include <cthreads.h>
+#define __libc_lock_t struct mutex
+#else
+typedef struct __libc_lock_opaque__ __libc_lock_t;
+#endif
+
+/* Type for key of thread specific data. */
+typedef cthread_key_t __libc_key_t;
+
+/* Define a lock variable NAME with storage class CLASS. The lock must be
+ initialized with __libc_lock_init before it can be used (or define it
+ with __libc_lock_define_initialized, below). Use `extern' for CLASS to
+ declare a lock defined in another module. In public structure
+ definitions you must use a pointer to the lock structure (i.e., NAME
+ begins with a `*'), because its storage size will not be known outside
+ of libc. */
+#define __libc_lock_define(CLASS,NAME) \
+ CLASS __libc_lock_t NAME;
+
+/* Define an initialized lock variable NAME with storage class CLASS. */
+#define __libc_lock_define_initialized(CLASS,NAME) \
+ CLASS __libc_lock_t NAME = MUTEX_INITIALIZER;
+
+/* Initialize the named lock variable, leaving it in a consistent, unlocked
+ state. */
+#define __libc_lock_init(NAME) __mutex_init (&(NAME))
+
+/* Finalize the named lock variable, which must be locked. It cannot be
+ used again until __libc_lock_init is called again on it. This must be
+ called on a lock variable before the containing storage is reused. */
+#define __libc_lock_fini(NAME) __mutex_unlock (&(NAME))
+
+/* Lock the named lock variable. */
+#define __libc_lock_lock(NAME) __mutex_lock (&(NAME))
+
+/* Lock the named lock variable. */
+#define __libc_lock_trylock(NAME) (!__mutex_trylock (&(NAME)))
+
+/* Unlock the named lock variable. */
+#define __libc_lock_unlock(NAME) __mutex_unlock (&(NAME))
+
+
+/* XXX for now */
+#define __libc_rwlock_define __libc_lock_define
+#define __libc_rwlock_define_initialized __libc_lock_define_initialized
+#define __libc_rwlock_init __libc_lock_init
+#define __libc_rwlock_fini __libc_lock_fini
+#define __libc_rwlock_rdlock __libc_lock_lock
+#define __libc_rwlock_wrlock __libc_lock_lock
+#define __libc_rwlock_tryrdlock __libc_lock_trylock
+#define __libc_rwlock_trywrlock __libc_lock_trylock
+#define __libc_rwlock_unlock __libc_lock_unlock
+
+
+/* Start a critical region with a cleanup function */
+#define __libc_cleanup_region_start(DOIT, FCT, ARG) \
+{ \
+ typeof (***(FCT)) *__save_FCT = (DOIT) ? (FCT) : 0; \
+ typeof (ARG) __save_ARG = ARG; \
+ /* close brace is in __libc_cleanup_region_end below. */
+
+/* End a critical region started with __libc_cleanup_region_start. */
+#define __libc_cleanup_region_end(DOIT) \
+ if ((DOIT) && __save_FCT != 0) \
+ (*__save_FCT)(__save_ARG); \
+}
+
+/* Sometimes we have to exit the block in the middle. */
+#define __libc_cleanup_end(DOIT) \
+ if ((DOIT) && __save_FCT != 0) \
+ (*__save_FCT)(__save_ARG); \
+
+
+/* Use mutexes as once control variables. */
+
+struct __libc_once
+ {
+ __libc_lock_t lock;
+ int done;
+ };
+
+#define __libc_once_define(CLASS,NAME) \
+ CLASS struct __libc_once NAME = { MUTEX_INITIALIZER, 0 }
+
+
+/* Call handler iff the first call. */
+#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
+ do { \
+ __libc_lock_lock (ONCE_CONTROL.lock); \
+ if (!ONCE_CONTROL.done) \
+ (INIT_FUNCTION) (); \
+ ONCE_CONTROL.done = 1; \
+ __libc_lock_unlock (ONCE_CONTROL.lock); \
+ } while (0)
+
+#ifdef _LIBC
+/* We need portable names for some functions. E.g., when they are
+ used as argument to __libc_cleanup_region_start. */
+#define __libc_mutex_unlock __mutex_unlock
+#endif
+
+#define __libc_key_create(KEY,DEST) cthread_keycreate (KEY)
+#define __libc_setspecific(KEY,VAL) cthread_setspecific (KEY, VAL)
+void *__libc_getspecific (__libc_key_t key);
+
+/* XXX until cthreads supports recursive locks */
+#define __libc_lock_define_initialized_recursive __libc_lock_define_initialized
+#define __libc_lock_init_recursive __libc_lock_init
+#define __libc_lock_fini_recursive __libc_lock_fini
+#define __libc_lock_trylock_recursive __libc_lock_trylock
+#define __libc_lock_unlock_recursive __libc_lock_unlock
+#define __libc_lock_lock_recursive __libc_lock_lock
+
+#define __rtld_lock_define_initialized_recursive __libc_lock_define_initialized
+#define __rtld_lock_init_recursive __libc_lock_init
+#define __rtld_lock_fini_recursive __libc_lock_fini
+#define __rtld_lock_trylock_recursive __libc_lock_trylock
+#define __rtld_lock_unlock_recursive __libc_lock_unlock
+#define __rtld_lock_lock_recursive __libc_lock_lock
+
+#endif /* bits/libc-lock.h */
diff --git a/libc/sysdeps/mach/configure b/libc/sysdeps/mach/configure
new file mode 100644
index 000000000..bf4f98d4d
--- /dev/null
+++ b/libc/sysdeps/mach/configure
@@ -0,0 +1,678 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mig", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mig; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_MIG+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$MIG"; then
+ ac_cv_prog_MIG="$MIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MIG="${ac_tool_prefix}mig"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+MIG=$ac_cv_prog_MIG
+if test -n "$MIG"; then
+ echo "$as_me:$LINENO: result: $MIG" >&5
+echo "${ECHO_T}$MIG" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_MIG"; then
+ ac_ct_MIG=$MIG
+ # Extract the first word of "mig", so it can be a program name with args.
+set dummy mig; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_MIG+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_MIG"; then
+ ac_cv_prog_ac_ct_MIG="$ac_ct_MIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MIG="mig"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_MIG" && ac_cv_prog_ac_ct_MIG="MISSING"
+fi
+fi
+ac_ct_MIG=$ac_cv_prog_ac_ct_MIG
+if test -n "$ac_ct_MIG"; then
+ echo "$as_me:$LINENO: result: $ac_ct_MIG" >&5
+echo "${ECHO_T}$ac_ct_MIG" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ MIG=$ac_ct_MIG
+else
+ MIG="$ac_cv_prog_MIG"
+fi
+
+if test "x$MIG" = xMISSING; then
+ { { echo "$as_me:$LINENO: error: cannot find required build tool mig" >&5
+echo "$as_me: error: cannot find required build tool mig" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+### Sanity checks for Mach header installation
+
+
+echo "$as_me:$LINENO: checking for mach/mach_types.h" >&5
+echo $ECHO_N "checking for mach/mach_types.h... $ECHO_C" >&6
+if test "${ac_cv_header_mach_mach_types_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <mach/mach_types.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_cv_header_mach_mach_types_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_mach_mach_types_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_mach_mach_types_h" >&5
+echo "${ECHO_T}$ac_cv_header_mach_mach_types_h" >&6
+if test $ac_cv_header_mach_mach_types_h = yes; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: cannot find Mach headers" >&5
+echo "$as_me: error: cannot find Mach headers" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking for mach/mach_types.defs" >&5
+echo $ECHO_N "checking for mach/mach_types.defs... $ECHO_C" >&6
+if test "${ac_cv_header_mach_mach_types_defs+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <mach/mach_types.defs>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_cv_header_mach_mach_types_defs=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_mach_mach_types_defs=no
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_mach_mach_types_defs" >&5
+echo "${ECHO_T}$ac_cv_header_mach_mach_types_defs" >&6
+if test $ac_cv_header_mach_mach_types_defs = yes; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: cannot find Mach .defs files" >&5
+echo "$as_me: error: cannot find Mach .defs files" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+echo "$as_me:$LINENO: checking for task_t in mach/mach_types.h" >&5
+echo $ECHO_N "checking for task_t in mach/mach_types.h... $ECHO_C" >&6
+if test "${libc_cv_mach_task_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <mach/mach_types.h>
+int
+main ()
+{
+extern task_t foo;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_mach_task_t=task_t
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+libc_cv_mach_task_t=task_port_t
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $libc_cv_mach_task_t" >&5
+echo "${ECHO_T}$libc_cv_mach_task_t" >&6
+if test $libc_cv_mach_task_t != task_t; then
+ DEFINES="$DEFINES -Dtask_t=task_port_t"
+fi
+echo "$as_me:$LINENO: checking for thread_t in mach/mach_types.h" >&5
+echo $ECHO_N "checking for thread_t in mach/mach_types.h... $ECHO_C" >&6
+if test "${libc_cv_mach_thread_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <mach/mach_types.h>
+int
+main ()
+{
+extern thread_t foo;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_mach_thread_t=thread_t
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+libc_cv_mach_thread_t=thread_port_t
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $libc_cv_mach_thread_t" >&5
+echo "${ECHO_T}$libc_cv_mach_thread_t" >&6
+if test $libc_cv_mach_thread_t != thread_t; then
+ DEFINES="$DEFINES -Dthread_t=thread_port_t"
+fi
+
+echo "$as_me:$LINENO: checking for creation_time in task_basic_info" >&5
+echo $ECHO_N "checking for creation_time in task_basic_info... $ECHO_C" >&6
+if test "${libc_cv_mach_task_creation_time+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <mach/task_info.h>
+int
+main ()
+{
+
+extern struct task_basic_info *i;
+long s = i->creation_time.seconds;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_mach_task_creation_time=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+libc_cv_mach_task_creation_time=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $libc_cv_mach_task_creation_time" >&5
+echo "${ECHO_T}$libc_cv_mach_task_creation_time" >&6
+if test $libc_cv_mach_task_creation_time = no; then
+ { { echo "$as_me:$LINENO: error: you need Mach headers supporting task_info.creation_time" >&5
+echo "$as_me: error: you need Mach headers supporting task_info.creation_time" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+mach_interface_list=
+for ifc in mach mach4 \
+ clock clock_priv host_priv host_security ledger lock_set \
+ processor processor_set task thread_act vm_map \
+ memory_object memory_object_default default_pager \
+ i386/mach_i386 \
+ ; do
+ as_ac_Header=`echo "ac_cv_header_mach/${ifc}.defs" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for mach/${ifc}.defs" >&5
+echo $ECHO_N "checking for mach/${ifc}.defs... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <mach/${ifc}.defs>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ mach_interface_list="$mach_interface_list $ifc"
+fi
+
+
+done
+if test "x$mach_interface_list" = x; then
+ { { echo "$as_me:$LINENO: error: what manner of Mach is this?" >&5
+echo "$as_me: error: what manner of Mach is this?" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for host_page_size in mach_host.defs" >&5
+echo $ECHO_N "checking for host_page_size in mach_host.defs... $ECHO_C" >&6
+if test "${libc_cv_mach_host_page_size+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <mach/mach_host.defs>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "host_page_size" >/dev/null 2>&1; then
+ libc_cv_mach_host_page_size=yes
+else
+ libc_cv_mach_host_page_size=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $libc_cv_mach_host_page_size" >&5
+echo "${ECHO_T}$libc_cv_mach_host_page_size" >&6
+if test $libc_cv_mach_host_page_size = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_HOST_PAGE_SIZE 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for mach/machine/ndr_def.h" >&5
+echo $ECHO_N "checking for mach/machine/ndr_def.h... $ECHO_C" >&6
+if test "${ac_cv_header_mach_machine_ndr_def_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <mach/machine/ndr_def.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_cv_header_mach_machine_ndr_def_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_mach_machine_ndr_def_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_mach_machine_ndr_def_h" >&5
+echo "${ECHO_T}$ac_cv_header_mach_machine_ndr_def_h" >&6
+if test $ac_cv_header_mach_machine_ndr_def_h = yes; then
+ DEFINES="$DEFINES -DNDR_DEF_HEADER='<mach/machine/ndr_def.h>'"
+else
+ echo "$as_me:$LINENO: checking for machine/ndr_def.h" >&5
+echo $ECHO_N "checking for machine/ndr_def.h... $ECHO_C" >&6
+if test "${ac_cv_header_machine_ndr_def_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <machine/ndr_def.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_cv_header_machine_ndr_def_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_machine_ndr_def_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_machine_ndr_def_h" >&5
+echo "${ECHO_T}$ac_cv_header_machine_ndr_def_h" >&6
+if test $ac_cv_header_machine_ndr_def_h = yes; then
+ DEFINES="$DEFINES -DNDR_DEF_HEADER='<machine/ndr_def.h>'"
+fi
+
+
+fi
+
+
+
+echo "$as_me:$LINENO: checking for i386_io_perm_modify in mach_i386.defs" >&5
+echo $ECHO_N "checking for i386_io_perm_modify in mach_i386.defs... $ECHO_C" >&6
+if test "${libc_cv_mach_i386_ioports+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <mach/i386/mach_i386.defs>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "i386_io_perm_modify" >/dev/null 2>&1; then
+ libc_cv_mach_i386_ioports=yes
+else
+ libc_cv_mach_i386_ioports=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $libc_cv_mach_i386_ioports" >&5
+echo "${ECHO_T}$libc_cv_mach_i386_ioports" >&6
+if test $libc_cv_mach_i386_ioports = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_I386_IO_PERM_MODIFY 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for i386_set_gdt in mach_i386.defs" >&5
+echo $ECHO_N "checking for i386_set_gdt in mach_i386.defs... $ECHO_C" >&6
+if test "${libc_cv_mach_i386_gdt+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <mach/i386/mach_i386.defs>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "i386_set_gdt" >/dev/null 2>&1; then
+ libc_cv_mach_i386_gdt=yes
+else
+ libc_cv_mach_i386_gdt=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $libc_cv_mach_i386_gdt" >&5
+echo "${ECHO_T}$libc_cv_mach_i386_gdt" >&6
+if test $libc_cv_mach_i386_gdt = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_I386_SET_GDT 1
+_ACEOF
+
+fi
+
+
+
+# See if mig groks `retcode'.
+echo "$as_me:$LINENO: checking whether $MIG supports the retcode keyword" >&5
+echo $ECHO_N "checking whether $MIG supports the retcode keyword... $ECHO_C" >&6
+if test "${hurd_cv_mig_retcode+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.defs <<\EOF
+#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
+subsystem foobar 1000;
+type reply_port_t = polymorphic | MACH_MSG_TYPE_PORT_SEND_ONCE
+ ctype: mach_port_t;
+simpleroutine foobar_reply (
+ reply_port: reply_port_t;
+ err: kern_return_t, RetCode);
+EOF
+if { ac_try='CC="${CC}" ${MIG-false} -n conftest.defs 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ hurd_cv_mig_retcode=yes
+else
+ hurd_cv_mig_retcode=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $hurd_cv_mig_retcode" >&5
+echo "${ECHO_T}$hurd_cv_mig_retcode" >&6
+if test $hurd_cv_mig_retcode = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_MIG_RETCODE 1
+_ACEOF
+
+fi
diff --git a/libc/sysdeps/mach/configure.in b/libc/sysdeps/mach/configure.in
new file mode 100644
index 000000000..2f82c3a87
--- /dev/null
+++ b/libc/sysdeps/mach/configure.in
@@ -0,0 +1,125 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+
+AC_CHECK_TOOL(MIG, mig, MISSING)
+if test "x$MIG" = xMISSING; then
+ AC_MSG_ERROR([cannot find required build tool mig])
+fi
+
+### Sanity checks for Mach header installation
+AC_CHECK_HEADER(mach/mach_types.h,,
+ [AC_MSG_ERROR([cannot find Mach headers])], -)
+AC_CHECK_HEADER(mach/mach_types.defs,, [dnl
+AC_MSG_ERROR([cannot find Mach .defs files])], -)
+
+dnl
+dnl mach_TYPE_CHECK(foo_t, bar_t)
+dnl
+dnl Check if foo_t is defined by <mach/mach_types.h>.
+dnl If not, compile with -Dfoo_t=bar_t.
+dnl
+AC_DEFUN([mach_TYPE_CHECK], [dnl
+AC_CACHE_CHECK(for $1 in mach/mach_types.h, libc_cv_mach_$1,
+AC_TRY_COMPILE([#include <mach/mach_types.h>], [extern $1 foo;],
+libc_cv_mach_$1=$1, libc_cv_mach_$1=$2))
+if test [$]libc_cv_mach_$1 != $1; then
+ DEFINES="$DEFINES -D$1=$2"
+fi])
+
+dnl
+dnl OSF Mach has renamed these typedefs for some reason.
+dnl
+mach_TYPE_CHECK(task_t, task_port_t)
+mach_TYPE_CHECK(thread_t, thread_port_t)
+
+dnl
+dnl The creation_time field is a GNU Mach addition the other variants lack.
+dnl
+AC_CACHE_CHECK(for creation_time in task_basic_info,
+ libc_cv_mach_task_creation_time, [dnl
+AC_TRY_COMPILE([#include <mach/task_info.h>], [
+extern struct task_basic_info *i;
+long s = i->creation_time.seconds;
+], libc_cv_mach_task_creation_time=yes, libc_cv_mach_task_creation_time=no)])
+if test $libc_cv_mach_task_creation_time = no; then
+ AC_MSG_ERROR([you need Mach headers supporting task_info.creation_time])
+fi
+
+dnl
+dnl The Darwin variant no longer has <mach/mach.defs>
+dnl but instead has several constituent .defs files.
+dnl In this scenario we will presume there is a <mach/mach_interface.h>
+dnl that contains an #include for each constituent header file,
+dnl but we don't do a check for that here because in a bare
+dnl environment the compile against those headers will fail.
+dnl
+mach_interface_list=
+for ifc in mach mach4 \
+ clock clock_priv host_priv host_security ledger lock_set \
+ processor processor_set task thread_act vm_map \
+ memory_object memory_object_default default_pager \
+ i386/mach_i386 \
+ ; do
+ AC_CHECK_HEADER(mach/${ifc}.defs, [dnl
+ mach_interface_list="$mach_interface_list $ifc"],, -)
+done
+if test "x$mach_interface_list" = x; then
+ AC_MSG_ERROR([what manner of Mach is this?])
+fi
+
+AC_CACHE_CHECK(for host_page_size in mach_host.defs,
+ libc_cv_mach_host_page_size, [dnl
+AC_EGREP_HEADER(host_page_size, mach/mach_host.defs,
+ libc_cv_mach_host_page_size=yes,
+ libc_cv_mach_host_page_size=no)])
+if test $libc_cv_mach_host_page_size = yes; then
+ AC_DEFINE([HAVE_HOST_PAGE_SIZE])
+fi
+
+AC_CHECK_HEADER(mach/machine/ndr_def.h, [dnl
+ DEFINES="$DEFINES -DNDR_DEF_HEADER='<mach/machine/ndr_def.h>'"], [dnl
+AC_CHECK_HEADER(machine/ndr_def.h, [dnl
+ DEFINES="$DEFINES -DNDR_DEF_HEADER='<machine/ndr_def.h>'"],, -)], -)
+
+AC_CACHE_CHECK(for i386_io_perm_modify in mach_i386.defs,
+ libc_cv_mach_i386_ioports, [dnl
+AC_EGREP_HEADER(i386_io_perm_modify, mach/i386/mach_i386.defs,
+ libc_cv_mach_i386_ioports=yes,
+ libc_cv_mach_i386_ioports=no)])
+if test $libc_cv_mach_i386_ioports = yes; then
+ AC_DEFINE([HAVE_I386_IO_PERM_MODIFY])
+fi
+
+AC_CACHE_CHECK(for i386_set_gdt in mach_i386.defs,
+ libc_cv_mach_i386_gdt, [dnl
+AC_EGREP_HEADER(i386_set_gdt, mach/i386/mach_i386.defs,
+ libc_cv_mach_i386_gdt=yes,
+ libc_cv_mach_i386_gdt=no)])
+if test $libc_cv_mach_i386_gdt = yes; then
+ AC_DEFINE([HAVE_I386_SET_GDT])
+fi
+
+dnl Swiped from hurd/aclocal.m4
+AC_DEFUN([hurd_MIG_RETCODE], [dnl
+# See if mig groks `retcode'.
+AC_CACHE_CHECK(whether $MIG supports the retcode keyword, hurd_cv_mig_retcode,
+[cat > conftest.defs <<\EOF
+#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
+subsystem foobar 1000;
+type reply_port_t = polymorphic | MACH_MSG_TYPE_PORT_SEND_ONCE
+ ctype: mach_port_t;
+simpleroutine foobar_reply (
+ reply_port: reply_port_t;
+ err: kern_return_t, RetCode);
+EOF
+if AC_TRY_COMMAND([CC="${CC}" ${MIG-false} -n conftest.defs 1>&AS_MESSAGE_LOG_FD]); then
+ hurd_cv_mig_retcode=yes
+else
+ hurd_cv_mig_retcode=no
+fi
+rm -f conftest*])
+if test $hurd_cv_mig_retcode = yes; then
+ AC_DEFINE(HAVE_MIG_RETCODE)
+fi])
+
+hurd_MIG_RETCODE
diff --git a/libc/sysdeps/mach/getloadavg.c b/libc/sysdeps/mach/getloadavg.c
new file mode 100644
index 000000000..db3be248b
--- /dev/null
+++ b/libc/sysdeps/mach/getloadavg.c
@@ -0,0 +1,54 @@
+/* Get system load averages. Mach version.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <mach.h>
+#include <mach/host_info.h>
+#include <hurd.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+
+/* Put the 1 minute, 5 minute and 15 minute load averages
+ into the first NELEM elements of LOADAVG.
+ Return the number written (never more than 3, but may be less than NELEM),
+ or -1 if an error occurred. */
+
+int
+getloadavg (double loadavg[], int nelem)
+{
+ host_load_info_data_t info;
+ mach_msg_type_number_t size = HOST_LOAD_INFO_COUNT;
+ error_t err;
+ int i;
+
+ err = __host_info (__mach_host_self (), HOST_LOAD_INFO,
+ (host_info_t) &info, &size);
+ if (err)
+ return __hurd_fail (err);
+ if (size < HOST_LOAD_INFO_COUNT)
+ return __hurd_fail (EGRATUITOUS);
+
+ if (nelem > 3)
+ nelem = 3;
+ for (i = 0; i < nelem; ++i)
+ loadavg[i] = (double) info.avenrun[i] / (double) LOAD_SCALE;
+
+ return i;
+}
diff --git a/libc/sysdeps/mach/getpagesize.c b/libc/sysdeps/mach/getpagesize.c
new file mode 100644
index 000000000..a3140a4ab
--- /dev/null
+++ b/libc/sysdeps/mach/getpagesize.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1991, 1995, 1996, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <mach.h>
+
+/* Return the system page size. */
+int
+__getpagesize ()
+{
+ return __vm_page_size;
+}
+libc_hidden_def (__getpagesize)
+weak_alias (__getpagesize, getpagesize)
diff --git a/libc/sysdeps/mach/getsysstats.c b/libc/sysdeps/mach/getsysstats.c
new file mode 100644
index 000000000..d2bebb621
--- /dev/null
+++ b/libc/sysdeps/mach/getsysstats.c
@@ -0,0 +1,102 @@
+/* System dependent pieces of sysconf; Mach version
+ Copyright (C) 1996,97,99,2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <mach.h>
+#include <hurd.h>
+#include <sys/sysinfo.h>
+
+
+/* Return the number of processors configured on the system. */
+int
+__get_nprocs_conf ()
+{
+ struct host_basic_info hbi;
+ kern_return_t err;
+ mach_msg_type_number_t cnt = HOST_BASIC_INFO_COUNT;
+
+ err = __host_info (__mach_host_self (), HOST_BASIC_INFO,
+ (host_info_t) &hbi, &cnt);
+ if (err)
+ return __hurd_fail (err);
+ else if (cnt != HOST_BASIC_INFO_COUNT)
+ return __hurd_fail (EIEIO);
+
+ return hbi.max_cpus;
+}
+
+/* Return the number of processors currently available on the system. */
+int
+__get_nprocs ()
+{
+ struct host_basic_info hbi;
+ kern_return_t err;
+ mach_msg_type_number_t cnt = HOST_BASIC_INFO_COUNT;
+
+ err = __host_info (__mach_host_self (), HOST_BASIC_INFO,
+ (host_info_t) &hbi, &cnt);
+ if (err)
+ return __hurd_fail (err);
+ else if (cnt != HOST_BASIC_INFO_COUNT)
+ return __hurd_fail (EIEIO);
+
+ return hbi.avail_cpus;
+}
+
+/* Return the number of physical pages on the system. */
+long int
+__get_phys_pages ()
+{
+ struct host_basic_info hbi;
+ kern_return_t err;
+ mach_msg_type_number_t cnt = HOST_BASIC_INFO_COUNT;
+
+ err = __host_info (__mach_host_self (), HOST_BASIC_INFO,
+ (host_info_t) &hbi, &cnt);
+ if (err)
+ return __hurd_fail (err);
+ else if (cnt != HOST_BASIC_INFO_COUNT)
+ return __hurd_fail (EIEIO);
+
+ return hbi.memory_size / __vm_page_size;
+}
+
+/* Return the number of available physical pages */
+long int
+__get_avphys_pages ()
+{
+ vm_statistics_data_t vs;
+ kern_return_t err;
+
+#ifdef HOST_VM_INFO
+ {
+ mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
+ err = __host_info (__mach_host_self (), HOST_VM_INFO,
+ (host_info_t) &vs, &count);
+ if (!err && count < HOST_VM_INFO_COUNT)
+ err = EGRATUITOUS;
+ }
+#else
+ err = __vm_statistics (__mach_task_self (), &vs);
+#endif
+ if (err)
+ return __hurd_fail (err);
+
+ return vs.free_count;
+}
diff --git a/libc/sysdeps/mach/gettimeofday.c b/libc/sysdeps/mach/gettimeofday.c
new file mode 100644
index 000000000..7eb60c4b5
--- /dev/null
+++ b/libc/sysdeps/mach/gettimeofday.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1991,1992,1995-1997,2001,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/time.h>
+#include <mach.h>
+
+#undef __gettimeofday
+
+/* Get the current time of day and timezone information,
+ putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
+ Returns 0 on success, -1 on errors. */
+int
+__gettimeofday (tv, tz)
+ struct timeval *tv;
+ struct timezone *tz;
+{
+ kern_return_t err;
+
+ if (tz != NULL)
+ *tz = (struct timezone){0, 0}; /* XXX */
+
+ if (err = __host_get_time (__mach_host_self (), (time_value_t *) tv))
+ {
+ errno = err;
+ return -1;
+ }
+ return 0;
+}
+
+INTDEF(__gettimeofday)
+weak_alias (__gettimeofday, gettimeofday)
diff --git a/libc/sysdeps/mach/hurd/.cvsignore b/libc/sysdeps/mach/hurd/.cvsignore
new file mode 100644
index 000000000..1f69fd919
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/.cvsignore
@@ -0,0 +1,4 @@
+*.gz *.Z *.tar *.tgz
+=*
+TODO COPYING* AUTHORS copyr-* copying.*
+glibc-*
diff --git a/libc/sysdeps/mach/hurd/Implies b/libc/sysdeps/mach/hurd/Implies
new file mode 100644
index 000000000..b6063463c
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/Implies
@@ -0,0 +1,5 @@
+# The gnu subdirectory exists for things common to both Linux-based and
+# Hurd-based GNU systems.
+gnu
+# The Hurd provides a rough superset of the functionality of 4.4 BSD.
+unix/bsd/bsd4.4
diff --git a/libc/sysdeps/mach/hurd/Makeconfig b/libc/sysdeps/mach/hurd/Makeconfig
new file mode 100644
index 000000000..1b65bb07a
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/Makeconfig
@@ -0,0 +1,4 @@
+# We need special startup code for statically linked binaries.
+# See Makefile in this directory for the rule that builds this.
+# We must define this variable earlier than sysdeps Makefiles are included.
+static-start-installed-name = crt0.o
diff --git a/libc/sysdeps/mach/hurd/Makefile b/libc/sysdeps/mach/hurd/Makefile
new file mode 100644
index 000000000..8677515cd
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/Makefile
@@ -0,0 +1,209 @@
+# Copyright (C) 1993,94,95,96,97,98,99,2000,2001,2002, 2003, 2004
+# Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifdef in-Makerules
+
+# Look for header files in hurd/ under the top-level library source directory.
+# Look for generated header files where they get created.
+includes += -I$(..)hurd -I$(common-objpfx)hurd/
+
+# We use the style `if (err = call(...))' a lot in the Hurd code,
+# where we have a lot of functions that return zero or an errno code.
++cflags += -Wno-parentheses
+
+# Do not use any assembly code from sysdeps/unix (and subdirectories).
+# This bypasses all the system call stubs and uses any existing posix or
+# generic C files instead.
+inhibit-sysdep-asm += unix*
+inhibit-unix-syscalls = yes
+
+# Don't try to generate anything from the installed Unix system and its
+# libraries. That is only of use when building for a Unix system, so as to
+# be compatible with some existing binaries for that system.
+inhibit-glue = yes
+
+ifeq (,$(filter mach hurd,$(subdir)))
+# Subdirectories other than hurd/ might use the generated Hurd headers.
+# So make sure we get a chance to run in hurd/ to make them before all else.
+# (But we don't want to do this in mach/, because hurd/ needs some things
+# there, and we know mach/ doesn't need anything from hurd/.)
+
+hurd-objpfx = $(common-objpfx)hurd/
+
+# These are all the generated headers that <hurd.h> includes.
+before-compile += $(patsubst %,$(hurd-objpfx)hurd/%.h,auth io fs process)
+$(patsubst %,$(hurd-objpfx)hurd/%.%,auth io fs process): \
+ $(common-objpfx)mach/mach-shortcuts.h
+ $(MAKE) -C $(..)hurd before-compile no_deps=t
+endif
+
+# Hurd profil.c includes this file, so give a rule to make it.
+ifeq ($(subdir),gmon)
+$(common-objpfx)hurd/../mach/RPC_task_get_sampled_pcs.c:
+ $(MAKE) -C $(..)mach before-compile no_deps=t
+endif
+
+
+# Generate bits/errno.h from the section of the manual that lists all the errno
+# codes.
+
+errno.texinfo = $(..)manual/errno.texi
+
+hurd = $(..)sysdeps/mach/hurd
+
+define mach-errno-h
+($(foreach h,mach/message.h \
+ mach/kern_return.h \
+ mach/mig_errors.h \
+ device/device_types.h,\
+ echo '#include <$h>';\
+ ))
+endef
+
+# We use the compiler to generate a list of absolute file names for
+# the headers we want to search for Mach error codes, listed above (and
+# incidentally, all other headers those include).
+-include $(common-objpfx)errnos.d
+$(common-objpfx)errnos.d: $(mach-errnos-deps)
+ $(mach-errno-h) | \
+ $(CC) $(CFLAGS) $(CPPFLAGS) -M -x c - | \
+ sed $(sed-remove-objpfx) -e 's,- *:,mach-errnos-deps :=,' \
+ -e 's, \.\./, $(..),g' > $@t
+ mv -f $@t $@
+
+$(hurd)/bits/errno.h: $(common-objpfx)stamp-errnos ;
+$(common-objpfx)stamp-errnos: $(hurd)/errnos.awk $(errno.texinfo) \
+ $(mach-errnos-deps) $(common-objpfx)errnos.d
+ $(AWK) -f $^ > $(hurd)/bits/errno.h-tmp
+# Make it unwritable so noone will edit it by mistake.
+ -chmod a-w $(hurd)/bits/errno.h-tmp
+ $(move-if-change) $(hurd)/bits/errno.h-tmp $(hurd)/bits/errno.h
+ifeq ($(with-cvs),yes)
+ test ! -d $(hurd)/CVS || \
+ (cd $(hurd) && cvs commit -m'Regenerated from $^' bits/errno.h)
+endif
+ touch $@
+
+common-generated += errnos.d stamp-errnos
+
+# We install the real libc.a as libcrt.a and as libc.a we install a linker
+# script which does -( -lcrt -lmachuser -lhurduser -).
+
+libc-name = crt
+
+ifeq (,$(subdir))
+install-others += $(inst_libdir)/libc.a
+$(inst_libdir)/libc.a: $(hurd)/libc-ldscript $(+force); $(do-install)
+ifeq (yes,$(build-profile))
+install-others += $(inst_libdir)/libc_p.a
+$(inst_libdir)/libc_p.a: $(hurd)/libc_p-ldscript $(+force); $(do-install)
+endif
+endif
+
+# Make sure these are used to build the libc.so shared object too. There
+# is a circular dependency between each of these shared objects and libc
+# (many high-level libc functions call stubs, stubs call low-level libc
+# functions like memcpy and mach_msg). This works out fine at run time
+# (all the objects are loaded before resolving their symbols, so these
+# interdependencies are fine). But to create the shared objects we must
+# link them one at a time; since each needs one or both of the others to
+# produce its DT_NEEDED entries and to assign its undefined symbols the
+# right symbol versions, we can't do any of them before the others! To
+# get around this, we link each lib*user.so shared object twice. First,
+# we link an object without reference to libc.so (since we haven't linked
+# libc.so yet), so it lacks a DT_NEEDED record for the libc soname it
+# depends on, and its undefined symbol references lack the symbol version
+# assignments they should have. We will use this shared object solely to
+# link libc.so against it; that gives libc.so the proper DT_NEEDED record,
+# and symbol versions assignments (if the lib*user.so object is using them).
+# Finally we link a second version of the same lib*user.so shared object,
+# this time linked normally against libc so it gets a proper DT_NEEDED
+# record and symbol version set; this one can be installed for run-time use.
+rpcuserlibs := $(common-objpfx)mach/libmachuser.so \
+ $(common-objpfx)hurd/libhurduser.so
+link-rpcuserlibs := $(rpcuserlibs:%user.so=%user-link.so)
+$(common-objpfx)libc.so: $(link-rpcuserlibs)
+rpath-dirs += mach hurd
+
+# Make sure the `lib' pass builds the dummy shared objects so
+# we can link libc against them.
+ifeq (mach,$(subdir))
+lib-noranlib: $(common-objpfx)mach/libmachuser-link.so
+endif
+ifeq (hurd,$(subdir))
+lib-noranlib: $(common-objpfx)hurd/libhurduser-link.so
+endif
+
+$(link-rpcuserlibs): %-link.so: %_pic.a
+# These shared objects are just for the purpose of linking libc,
+# so they don't need abi-note.o linked into them.
+ $(build-shlib-helper) \
+ -nostdlib -o $@ \
+ -Wl,-soname=$(*F).so$($(*F).so-version) \
+ $(build-shlib-objlist)
+libmachuser-link.so-no-z-defs = yes
+libhurduser-link.so-no-z-defs = yes
+
+# And get them into the libc.so ldscript.
+$(inst_libdir)/libc.so: $(rpcuserlibs)
+
+# The RPC stubs from these libraries are needed in building the dynamic
+# linker, too. It must be self-contained, so we link the needed PIC
+# objects directly into the shared object.
+ifeq (elf,$(subdir))
+$(objpfx)librtld.map: $(rpcuserlibs:.so=_pic.a)
+
+CFLAGS-dl-load.c = -DEXTERNAL_MAP_FROM_FD
+endif
+
+# We need these libs to link static programs in the libc source tree, too.
+ifeq (yes,$(build-static))
+link-libc-static := -Wl,-\( \
+ $(patsubst %,$(common-objpfx)%.a,\
+ libc mach/libmachuser hurd/libhurduser) \
+ $(static-gnulib) -Wl,-\)
+else
+ifeq (yes,$(build-shared))
+# We can try to link the programs with lib*_pic.a...
+link-libc-static := $(link-libc) -Wl,-\( \
+ $(patsubst %,$(common-objpfx)%_pic.a,\
+ libc mach/libmachuser hurd/libhurduser) \
+ $(static-gnulib) -Wl,-\)
+endif
+endif
+
+ifeq ($(subdir),csu)
+
+extra-objs += static-start.o
+
+# We need special startup code for statically linked binaries.
+$(objpfx)crt0.o: $(objpfx)static-start.o $(objpfx)abi-note.o $(objpfx)init.o
+ $(link-relocatable)
+
+endif
+
+ifeq (hurd, $(subdir))
+sysdep_routines += cthreads
+endif
+
+ifeq ($(subdir),sunrpc)
+sysdep_headers += nfs/nfs.h
+endif
+
+endif # in-Makerules
diff --git a/libc/sysdeps/mach/hurd/Subdirs b/libc/sysdeps/mach/hurd/Subdirs
new file mode 100644
index 000000000..7a7757582
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/Subdirs
@@ -0,0 +1,9 @@
+# This file says that the hurd subdirectory should appear before all others.
+# The mach and hurd subdirectories have many generated header files which
+# much of the rest of the library depends on, so it is best to build them
+# first (and mach before hurd, at that). The before-compile additions in
+# sysdeps/{mach,hurd}/Makefile should make it reliably work for these files
+# not to exist when making in other directories, but it will be slower that
+# way with more somewhat expensive `make' invocations.
+
+first hurd
diff --git a/libc/sysdeps/mach/hurd/Versions b/libc/sysdeps/mach/hurd/Versions
new file mode 100644
index 000000000..89e19061a
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/Versions
@@ -0,0 +1,37 @@
+libc {
+ GLIBC_2.0 {
+ # functions with a weak definition in the dynamic linker
+ __getcwd; __mmap;
+ }
+ GLIBC_PRIVATE {
+ # Functions shared with the dynamic linker
+ __libc_read; __libc_write; __libc_lseek64;
+
+ _dl_init_first;
+ }
+}
+
+ld {
+ GLIBC_2.0 {
+ # variables that must be shared with libc
+ __hurd_sigthread_stack_base; __hurd_sigthread_stack_end;
+ __hurd_sigthread_variables;
+ __hurd_threadvar_stack_mask; __hurd_threadvar_stack_offset;
+
+ # functions that must be shared with libc
+ __close; __getcwd; __getpid;
+ __mmap; __open; __xstat64; __fxstat64;
+ _exit; _hurd_intr_rpc_mach_msg;
+ abort;
+ }
+ GLIBC_2.2.6 {
+ # this also must be shared with libc.
+ __errno_location;
+ }
+ GLIBC_PRIVATE {
+ _dl_init_first;
+
+ # functions that must be shared with libc
+ __libc_read; __libc_write; __libc_lseek64;
+ }
+}
diff --git a/libc/sysdeps/mach/hurd/_G_config.h b/libc/sysdeps/mach/hurd/_G_config.h
new file mode 100644
index 000000000..b64305923
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/_G_config.h
@@ -0,0 +1,102 @@
+/* This file is needed by libio to define various configuration parameters.
+ These are always the same in the GNU C library. */
+
+#ifndef _G_config_h
+#define _G_config_h 1
+
+/* Define types for libio in terms of the standard internal type names. */
+
+#include <bits/types.h>
+#define __need_size_t
+#define __need_wchar_t
+#define __need_wint_t
+#define __need_NULL
+#include <stddef.h>
+#ifndef _WINT_T
+/* Integral type unchanged by default argument promotions that can
+ hold any value corresponding to members of the extended character
+ set, as well as at least one value that does not correspond to any
+ member of the extended character set. */
+# define _WINT_T
+typedef unsigned int wint_t;
+#endif
+#define __need_mbstate_t
+#include <wchar.h>
+#define _G_size_t size_t
+typedef struct
+{
+ __off_t __pos;
+ __mbstate_t __state;
+} _G_fpos_t;
+typedef struct
+{
+ __off64_t __pos;
+ __mbstate_t __state;
+} _G_fpos64_t;
+#define _G_ssize_t __ssize_t
+#define _G_off_t __off_t
+#define _G_off64_t __off64_t
+#define _G_pid_t __pid_t
+#define _G_uid_t __uid_t
+#define _G_wchar_t wchar_t
+#define _G_wint_t wint_t
+#define _G_stat64 stat64
+#include <gconv.h>
+typedef union
+{
+ struct __gconv_info __cd;
+ struct
+ {
+ struct __gconv_info __cd;
+ struct __gconv_step_data __data;
+ } __combined;
+} _G_iconv_t;
+
+typedef int _G_int16_t __attribute__ ((__mode__ (__HI__)));
+typedef int _G_int32_t __attribute__ ((__mode__ (__SI__)));
+typedef unsigned int _G_uint16_t __attribute__ ((__mode__ (__HI__)));
+typedef unsigned int _G_uint32_t __attribute__ ((__mode__ (__SI__)));
+
+#define _G_HAVE_BOOL 1
+
+
+/* These library features are always available in the GNU C library. */
+#define _G_HAVE_ATEXIT 1
+#define _G_HAVE_SYS_CDEFS 1
+#define _G_HAVE_SYS_WAIT 1
+#define _G_NEED_STDARG_H 1
+#define _G_va_list __gnuc_va_list
+
+#define _G_HAVE_PRINTF_FP 1
+#define _G_HAVE_MMAP 1
+#define _G_HAVE_LONG_DOUBLE_IO 1
+#define _G_HAVE_IO_FILE_OPEN 1
+#define _G_HAVE_IO_GETLINE_INFO 1
+
+#define _G_IO_IO_FILE_VERSION 0x20001
+
+#define _G_OPEN64 __open64
+#define _G_LSEEK64 __lseek64
+#define _G_MMAP64 __mmap64
+#define _G_FSTAT64(fd,buf) __fxstat64 (_STAT_VER, fd, buf)
+
+/* This is defined by <bits/stat.h> if `st_blksize' exists. */
+#define _G_HAVE_ST_BLKSIZE defined (_STATBUF_ST_BLKSIZE)
+
+#define _G_BUFSIZ 8192
+
+/* These are the vtbl details for ELF. */
+#define _G_NAMES_HAVE_UNDERSCORE 0
+#define _G_VTABLE_LABEL_HAS_LENGTH 1
+#define _G_USING_THUNKS 1
+#define _G_VTABLE_LABEL_PREFIX "__vt_"
+#define _G_VTABLE_LABEL_PREFIX_ID __vt_
+
+
+#if defined __cplusplus || defined __STDC__
+# define _G_ARGS(ARGLIST) ARGLIST
+#else
+# define _G_ARGS(ARGLIST) ()
+#endif
+
+#endif /* _G_config.h */
diff --git a/libc/sysdeps/mach/hurd/_exit.c b/libc/sysdeps/mach/hurd/_exit.c
new file mode 100644
index 000000000..af0337b30
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/_exit.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1993,94,95,96,97,99,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <sysdep.h>
+#include <sys/wait.h>
+
+void
+_hurd_exit (int status)
+{
+ /* Give the proc server our exit status. */
+ __USEPORT (PROC, __proc_mark_exit (port, status, 0));
+
+ /* Commit suicide. */
+ __task_terminate (__mach_task_self ());
+
+ /* Perhaps the cached mach_task_self was bogus. */
+ __task_terminate ((__mach_task_self) ());
+
+ /* This sucker really doesn't want to die. */
+ while (1)
+ {
+#ifdef LOSE
+ LOSE;
+#else
+ volatile const int zero = 0, one = 1;
+ volatile int lossage = one / zero;
+#endif
+ }
+}
+
+void
+_exit (status)
+ int status;
+{
+ _hurd_exit (W_EXITCODE (status, 0));
+}
+libc_hidden_def (_exit)
+weak_alias (_exit, _Exit)
diff --git a/libc/sysdeps/mach/hurd/accept.c b/libc/sysdeps/mach/hurd/accept.c
new file mode 100644
index 000000000..362c42c5b
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/accept.c
@@ -0,0 +1,87 @@
+/* Copyright (C) 1992,1993,1994,1997,1999,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+
+/* Await a connection on socket FD.
+ When a connection arrives, open a new socket to communicate with it,
+ set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting
+ peer and *ADDR_LEN to the address's actual length, and return the
+ new socket's descriptor, or -1 for errors. */
+int
+accept (fd, addrarg, addr_len)
+ int fd;
+ __SOCKADDR_ARG addrarg;
+ socklen_t *addr_len;
+{
+ error_t err;
+ socket_t new;
+ addr_port_t aport;
+ struct sockaddr *addr = addrarg.__sockaddr__;
+ char *buf = (char *) addr;
+ mach_msg_type_number_t buflen;
+ int type;
+
+ if (err = HURD_DPORT_USE (fd, __socket_accept (port, &new, &aport)))
+ return __hurd_dfail (fd, err);
+
+ if (addr != NULL)
+ {
+ buflen = *addr_len;
+ err = __socket_whatis_address (aport, &type, &buf, &buflen);
+ if (err == EOPNOTSUPP)
+ /* If the protocol server can't tell us the address, just return a
+ zero-length one. */
+ {
+ buf = (char *)addr;
+ buflen = 0;
+ err = 0;
+ }
+ }
+ __mach_port_deallocate (__mach_task_self (), aport);
+
+ if (err)
+ {
+ __mach_port_deallocate (__mach_task_self (), new);
+ return __hurd_dfail (fd, err);
+ }
+
+ if (addr != NULL)
+ {
+ if (*addr_len > buflen)
+ *addr_len = buflen;
+
+ if (buf != (char *) addr)
+ {
+ memcpy (addr, buf, *addr_len);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+ }
+
+ if (buflen > 0)
+ addr->sa_family = type;
+ }
+
+ return _hurd_intern_fd (new, O_IGNORE_CTTY, 1);
+}
+libc_hidden_def (accept)
diff --git a/libc/sysdeps/mach/hurd/access.c b/libc/sysdeps/mach/hurd/access.c
new file mode 100644
index 000000000..22eb9668b
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/access.c
@@ -0,0 +1,149 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <hurd/id.h>
+#include <hurd/lookup.h>
+#include <fcntl.h>
+
+/* Test for access to FILE by our real user and group IDs. */
+int
+__access (file, type)
+ const char *file;
+ int type;
+{
+ error_t err;
+ file_t rcrdir, rcwdir, io;
+ int flags, allowed;
+
+ error_t reauthenticate (int which, file_t *result)
+ {
+ /* Get a port to our root directory, authenticated with the real IDs. */
+ error_t err;
+ mach_port_t ref;
+ ref = __mach_reply_port ();
+ err = HURD_PORT_USE
+ (&_hurd_ports[which],
+ ({
+ err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
+ if (!err)
+ err = __auth_user_authenticate (_hurd_id.rid_auth,
+ ref, MACH_MSG_TYPE_MAKE_SEND,
+ result);
+ err;
+ }));
+ __mach_port_destroy (__mach_task_self (), ref);
+ return err;
+ }
+
+ error_t init_port (int which, error_t (*operate) (mach_port_t))
+ {
+ switch (which)
+ {
+ case INIT_PORT_AUTH:
+ return (*operate) (_hurd_id.rid_auth);
+ case INIT_PORT_CRDIR:
+ return (reauthenticate (INIT_PORT_CRDIR, &rcrdir) ?:
+ (*operate) (rcrdir));
+ case INIT_PORT_CWDIR:
+ return (reauthenticate (INIT_PORT_CWDIR, &rcwdir) ?:
+ (*operate) (rcwdir));
+ default:
+ return _hurd_ports_use (which, operate);
+ }
+ }
+
+ rcrdir = rcwdir = MACH_PORT_NULL;
+
+ HURD_CRITICAL_BEGIN;
+
+ __mutex_lock (&_hurd_id.lock);
+ /* Get _hurd_id up to date. */
+ if (err = _hurd_check_ids ())
+ goto lose;
+
+ if (_hurd_id.rid_auth == MACH_PORT_NULL)
+ {
+ /* Set up _hurd_id.rid_auth. This is a special auth server port
+ which uses the real uid and gid (the first aux uid and gid) as
+ the only effective uid and gid. */
+
+ if (_hurd_id.aux.nuids < 1 || _hurd_id.aux.ngids < 1)
+ {
+ /* We do not have a real UID and GID. Lose, lose, lose! */
+ err = EGRATUITOUS;
+ goto lose;
+ }
+
+ /* Create a new auth port using our real UID and GID (the first
+ auxiliary UID and GID) as the only effective IDs. */
+ if (err = __USEPORT (AUTH,
+ __auth_makeauth (port,
+ NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ _hurd_id.aux.uids, 1,
+ _hurd_id.aux.uids,
+ _hurd_id.aux.nuids,
+ _hurd_id.aux.gids, 1,
+ _hurd_id.aux.gids,
+ _hurd_id.aux.ngids,
+ &_hurd_id.rid_auth)))
+ goto lose;
+ }
+
+ if (!err)
+ /* Look up the file name using the modified init ports. */
+ err = __hurd_file_name_lookup (&init_port, &__getdport, 0,
+ file, 0, 0, &io);
+
+ /* We are done with _hurd_id.rid_auth now. */
+ lose:
+ __mutex_unlock (&_hurd_id.lock);
+
+ HURD_CRITICAL_END;
+
+ if (rcrdir != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), rcrdir);
+ if (rcwdir != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), rcwdir);
+ if (err)
+ return __hurd_fail (err);
+
+ /* Find out what types of access we are allowed to this file. */
+ err = __file_check_access (io, &allowed);
+ __mach_port_deallocate (__mach_task_self (), io);
+ if (err)
+ return __hurd_fail (err);
+
+ flags = 0;
+ if (type & R_OK)
+ flags |= O_READ;
+ if (type & W_OK)
+ flags |= O_WRITE;
+ if (type & X_OK)
+ flags |= O_EXEC;
+
+ if (flags & ~allowed)
+ /* We are not allowed all the requested types of access. */
+ return __hurd_fail (EACCES);
+
+ return 0;
+}
+
+weak_alias (__access, access)
diff --git a/libc/sysdeps/mach/hurd/adjtime.c b/libc/sysdeps/mach/hurd/adjtime.c
new file mode 100644
index 000000000..cc9cd7d40
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/adjtime.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1991,93,95,97,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/time.h>
+#include <hurd.h>
+
+/* Adjust the current time of day by the amount in DELTA.
+ If OLDDELTA is not NULL, it is filled in with the amount
+ of time adjustment remaining to be done from the last `__adjtime' call.
+ This call is restricted to the super-user. */
+int
+__adjtime (delta, olddelta)
+ const struct timeval *delta;
+ struct timeval *olddelta;
+{
+ error_t err;
+ mach_port_t hostpriv;
+
+ err = __get_privileged_ports (&hostpriv, NULL);
+ if (err)
+ return __hurd_fail (EPERM);
+
+ err = __host_adjust_time (hostpriv,
+ /* `time_value_t' and `struct timeval' are in
+ fact identical with the names changed. */
+ *(time_value_t *) delta,
+ (time_value_t *) olddelta);
+ __mach_port_deallocate (__mach_task_self (), hostpriv);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__adjtime, adjtime)
diff --git a/libc/sysdeps/mach/hurd/alpha/bits/sigcontext.h b/libc/sysdeps/mach/hurd/alpha/bits/sigcontext.h
new file mode 100644
index 000000000..4f13a2c9b
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/alpha/bits/sigcontext.h
@@ -0,0 +1,73 @@
+/* Machine-dependent signal context structure for GNU Hurd. Alpha version.
+ Copyright (C) 1994,97,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
+# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
+#endif
+
+#ifndef sc_alpha_thread_state
+
+/* Signal handlers are actually called:
+ void handler (int sig, int code, struct sigcontext *scp); */
+
+/* State of this thread when the signal was taken. */
+struct sigcontext
+ {
+ /* These first members are machine-independent. */
+
+ long int sc_onstack; /* Nonzero if running on sigstack. */
+ __sigset_t sc_mask; /* Blocked signals to restore. */
+
+ /* MiG reply port this thread is using. */
+ unsigned long int sc_reply_port;
+
+ /* Port this thread is doing an interruptible RPC on. */
+ unsigned long int sc_intr_port;
+
+ /* Error code associated with this signal (interpreted as `error_t'). */
+ int sc_error;
+
+ /* All following members are machine-dependent. The rest of this
+ structure is written to be laid out identically to:
+ {
+ struct alpha_thread_state basic;
+ struct alpha_exc_state exc;
+ struct alpha_float_state fpu;
+ }
+ trampoline.c knows this, so it must be changed if this changes. */
+
+#define sc_alpha_thread_state sc_regs /* Beginning of correspondence. */
+ long int sc_regs[31]; /* General registers $0..$30. */
+ long int sc_pc; /* Program counter. */
+
+ /* struct alpha_exc_state */
+#define sc_alpha_exc_state sc_badvaddr
+ unsigned long int sc_badvaddr;
+ unsigned int sc_cause; /* Machine-level trap code. */
+#define SC_CAUSE_SET_SSTEP 1
+ int sc_used_fpa; /* Nonzero if FPU was used. */
+
+ /* struct alpha_float_state
+ This is only filled in if sc_used_fpa is nonzero. */
+#define sc_alpha_float_state sc_fpregs
+ double sc_fpregs[31]; /* Floating point registers $f0..$f30. */
+ long int sc_fpcsr; /* Floating point control/status register. */
+ };
+
+#endif /* sc_alpha_thread_state */
diff --git a/libc/sysdeps/mach/hurd/alpha/exc2signal.c b/libc/sysdeps/mach/hurd/alpha/exc2signal.c
new file mode 100644
index 000000000..5f3fbbbbb
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/alpha/exc2signal.c
@@ -0,0 +1,75 @@
+/* Translate Mach exception codes into signal numbers. Alpha version.
+ Copyright (C) 1994,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <mach/exception.h>
+
+/* Translate the Mach exception codes, as received in an `exception_raise' RPC,
+ into a signal number and signal subcode. */
+
+void
+_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
+{
+ detail->error = 0;
+
+ switch (detail->exc)
+ {
+ default:
+ *signo = SIGIOT;
+ detail->code = detail->exc;
+ break;
+
+ case EXC_BAD_ACCESS:
+ if (detail->exc_code == KERN_PROTECTION_FAILURE)
+ *signo = SIGSEGV;
+ else
+ *signo = SIGBUS;
+ detail->code = detail->exc_subcode;
+ detail->error = detail->exc_code;
+ break;
+
+ case EXC_BAD_INSTRUCTION:
+ *signo = SIGILL;
+ detail->code = detail->exc_code;
+ break;
+
+ case EXC_ARITHMETIC:
+ *signo = SIGFPE;
+ detail->code = detail->exc_code;
+ break;
+ break;
+
+ case EXC_EMULATION:
+ /* 3.0 doesn't give this one, why, I don't know. */
+ *signo = SIGEMT;
+ detail->code = detail->exc_code;
+ break;
+
+ case EXC_SOFTWARE:
+ *signo = SIGEMT;
+ detail->code = detail->exc_code;
+ break;
+
+ case EXC_BREAKPOINT:
+ *signo = SIGTRAP;
+ detail->code = detail->exc_code;
+ break;
+ }
+}
diff --git a/libc/sysdeps/mach/hurd/alpha/init-first.c b/libc/sysdeps/mach/hurd/alpha/init-first.c
new file mode 100644
index 000000000..6e5522589
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/alpha/init-first.c
@@ -0,0 +1,302 @@
+/* Initialization code run first thing by the ELF startup code. Alpha/Hurd.
+ Copyright (C) 1995,96,97,98,99,2000,01,02,03 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <hurd.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sysdep.h>
+#include <set-hooks.h>
+#include "hurdstartup.h"
+#include "hurdmalloc.h" /* XXX */
+
+extern void __mach_init (void);
+extern void __init_misc (int, char **, char **);
+#ifdef USE_NONOPTION_FLAGS
+extern void __getopt_clean_environment (char **);
+#endif
+#ifndef SHARED
+extern void _dl_non_dynamic_init (void) internal_function;
+#endif
+extern void __libc_global_ctors (void);
+
+unsigned int __hurd_threadvar_max;
+unsigned long int __hurd_threadvar_stack_offset;
+unsigned long int __hurd_threadvar_stack_mask;
+
+#ifndef SHARED
+int __libc_enable_secure;
+#endif
+int __libc_multiple_libcs attribute_hidden = 1;
+
+extern int __libc_argc attribute_hidden;
+extern char **__libc_argv attribute_hidden;
+extern char **_dl_argv;
+
+void *(*_cthread_init_routine) (void); /* Returns new SP to use. */
+void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__));
+
+/* Things that want to be run before _hurd_init or much anything else.
+ Importantly, these are called before anything tries to use malloc. */
+DEFINE_HOOK (_hurd_preinit_hook, (void));
+
+
+/* We call this once the Hurd magic is all set up and we are ready to be a
+ Posixoid program. This does the same things the generic version does. */
+static void
+posixland_init (int argc, char **argv, char **envp)
+{
+ __libc_argc = argc;
+ __libc_argv = argv;
+ __environ = envp;
+
+#ifndef SHARED
+ _dl_non_dynamic_init ();
+#endif
+ __init_misc (argc, argv, envp);
+
+#ifdef USE_NONOPTION_FLAGS
+ /* This is a hack to make the special getopt in GNU libc working. */
+ __getopt_clean_environment (envp);
+#endif
+
+#ifdef SHARED
+ __libc_global_ctors ();
+#endif
+}
+
+
+static void
+init1 (intptr_t *data)
+{
+ int argc = (intptr_t) *data;
+ char **argv = (char **) &data[1];
+ char **envp = &argv[argc + 1];
+ struct hurd_startup_data *d;
+
+ while (*envp)
+ ++envp;
+ d = (void *) ++envp;
+
+ /* If we are the bootstrap task started by the kernel,
+ then after the environment pointers there is no Hurd
+ data block; the argument strings start there. */
+ /* OSF Mach starts the bootstrap task with argc == 0.
+ XXX This fails if a non-bootstrap task gets started
+ with argc == 0. */
+ if (argc && (void *) d != argv[0])
+ {
+ _hurd_init_dtable = d->dtable;
+ _hurd_init_dtablesize = d->dtablesize;
+
+ {
+ /* Check if the stack we are now on is different from
+ the one described by _hurd_stack_{base,size}. */
+
+ char dummy;
+ const vm_address_t newsp = (vm_address_t) &dummy;
+
+ if (d->stack_size != 0 && (newsp < d->stack_base ||
+ newsp - d->stack_base > d->stack_size))
+ /* The new stack pointer does not intersect with the
+ stack the exec server set up for us, so free that stack. */
+ __vm_deallocate (__mach_task_self (), d->stack_base, d->stack_size);
+ }
+ }
+
+ if ((void *) d != argv[0] && (d->portarray || d->intarray))
+ /* Initialize library data structures, start signal processing, etc. */
+ _hurd_init (d->flags, argv,
+ d->portarray, d->portarraysize,
+ d->intarray, d->intarraysize);
+
+#ifndef SHARED
+ __libc_enable_secure = d->flags & EXEC_SECURE;
+#endif
+}
+
+
+static inline void
+init (intptr_t *data)
+{
+ int argc = *data;
+ char **argv = (void *) (data + 1);
+ char **envp = &argv[argc + 1];
+ struct hurd_startup_data *d;
+ unsigned long int threadvars[_HURD_THREADVAR_MAX];
+
+ /* Provide temporary storage for thread-specific variables on the
+ startup stack so the cthreads initialization code can use them
+ for malloc et al, or so we can use malloc below for the real
+ threadvars array. */
+ memset (threadvars, 0, sizeof threadvars);
+ __hurd_threadvar_stack_offset = (unsigned long int) threadvars;
+
+ /* Since the cthreads initialization code uses malloc, and the
+ malloc initialization code needs to get at the environment, make
+ sure we can find it. We'll need to do this again later on since
+ switching stacks changes the location where the environment is
+ stored. */
+ __environ = envp;
+
+ while (*envp)
+ ++envp;
+ d = (void *) ++envp;
+
+ /* The user might have defined a value for this, to get more variables.
+ Otherwise it will be zero on startup. We must make sure it is set
+ properly before before cthreads initialization, so cthreads can know
+ how much space to leave for thread variables. */
+ if (__hurd_threadvar_max < _HURD_THREADVAR_MAX)
+ __hurd_threadvar_max = _HURD_THREADVAR_MAX;
+
+
+ /* After possibly switching stacks, call `init1' (above) with the user
+ code as the return address, and the argument data immediately above
+ that on the stack. */
+
+ if (_cthread_init_routine)
+ {
+ /* Initialize cthreads, which will allocate us a new stack to run on. */
+ void *newsp = (*_cthread_init_routine) ();
+ struct hurd_startup_data *od;
+
+ void switch_stacks (void);
+
+ /* Copy per-thread variables from that temporary
+ area onto the new cthread stack. */
+ memcpy (__hurd_threadvar_location_from_sp (0, newsp),
+ threadvars, sizeof threadvars);
+
+ /* Copy the argdata from the old stack to the new one. */
+ newsp = memcpy (newsp - ((char *) &d[1] - (char *) data), data,
+ (char *) d - (char *) data);
+
+#ifdef SHARED
+ /* And readjust the dynamic linker's idea of where the argument
+ vector lives. */
+ assert (_dl_argv == argv);
+ _dl_argv = (void *) ((int *) newsp + 1);
+#endif
+
+ /* Set up the Hurd startup data block immediately following
+ the argument and environment pointers on the new stack. */
+ od = (newsp + ((char *) d - (char *) data));
+ if ((void *) argv[0] == d)
+ /* We were started up by the kernel with arguments on the stack.
+ There is no Hurd startup data, so zero the block. */
+ memset (od, 0, sizeof *od);
+ else
+ /* Copy the Hurd startup data block to the new stack. */
+ *od = *d;
+
+ /*
+ Force NEWSP into sp and &init1 into pv, then branch to pv (call init1).
+ */
+ asm volatile ("lda $30,0(%0); lda $27,0(%1); jsr $26,($27)"
+ : : "r" (newsp), "r" (&init1));
+ }
+ else
+ {
+ /* We are not using cthreads, so we will have just a single allocated
+ area for the per-thread variables of the main user thread. */
+ unsigned long int *array;
+ unsigned int i;
+
+ array = malloc (__hurd_threadvar_max * sizeof (unsigned long int));
+ if (array == NULL)
+ __libc_fatal ("Can't allocate single-threaded thread variables.");
+
+ /* Copy per-thread variables from the temporary array into the
+ newly malloc'd space. */
+ memcpy (array, threadvars, sizeof threadvars);
+ __hurd_threadvar_stack_offset = (unsigned long int) array;
+ for (i = _HURD_THREADVAR_MAX; i < __hurd_threadvar_max; ++i)
+ array[i] = 0;
+
+ init1 (data);
+ }
+}
+
+
+/* Do the first essential initializations that must precede all else. */
+static inline void
+first_init (void)
+{
+ /* Initialize data structures so we can do RPCs. */
+ __mach_init ();
+
+ RUN_HOOK (_hurd_preinit_hook, ());
+}
+
+#ifdef SHARED
+/* This function is called specially by the dynamic linker to do early
+ initialization of the shared C library before normal initializers
+ expecting a Posixoid environment can run. It gets called with the
+ stack set up just as the user will see it, so it can switch stacks. */
+
+void
+_dl_init_first (intptr_t argc, ...)
+{
+ first_init ();
+
+ init (&argc);
+}
+#endif
+
+
+#ifdef SHARED
+/* The regular posixland initialization is what goes into libc's
+ normal initializer. */
+/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
+ pointer in the dynamic section based solely on that. It is convention
+ for this function to be in the `.init' section, but the symbol name is
+ the only thing that really matters!! */
+strong_alias (posixland_init, _init);
+
+void
+__libc_init_first (int argc, char **argv, char **envp)
+{
+ /* Everything was done in the shared library initializer, _init. */
+}
+#else
+strong_alias (posixland_init, __libc_init_first);
+
+
+void
+_hurd_stack_setup (volatile intptr_t argc, ...)
+{
+ first_init ();
+
+ _hurd_startup ((void **) &argc, &init);
+}
+#endif
+
+
+/* This function is defined here so that if this file ever gets into
+ ld.so we will get a link error. Having this file silently included
+ in ld.so causes disaster, because the _init definition above will
+ cause ld.so to gain an init function, which is not a cool thing. */
+
+void
+_dl_start (void)
+{
+ abort ();
+}
diff --git a/libc/sysdeps/mach/hurd/alpha/intr-msg.h b/libc/sysdeps/mach/hurd/alpha/intr-msg.h
new file mode 100644
index 000000000..4f172124e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/alpha/intr-msg.h
@@ -0,0 +1,100 @@
+/* Machine-dependent details of interruptible RPC messaging. Alpha version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define INTR_MSG_TRAP(msg, option, send_size, rcv_size, rcv_name, timeout, notify) \
+({ \
+ error_t err; \
+ asm (".globl _hurd_intr_rpc_msg_do_trap\n" \
+ ".globl _hurd_intr_rpc_msg_in_trap\n" \
+ " mov %1, $16\n" \
+ " mov %2, $17\n" \
+ " mov %3, $18\n" \
+ " mov %4, $19\n" \
+ " mov %5, $20\n" \
+ " mov %6, $21\n" \
+ " mov %7, $1\n" \
+ " lda $0, -25\n" \
+ "_hurd_intr_rpc_msg_do_trap: callsys\n" \
+ "_hurd_intr_rpc_msg_in_trap: ret\n" \
+ : "=r" (err) \
+ : "r" (msg), "r" (option), "r" (send_size), "r" (rcv_size), \
+ "r" (rcv_name), "r" (timeout), "r" (notify) \
+ : "16", "17", "18", "19", "20", "21", "1", "0"); \
+ err; \
+})
+
+static void inline
+INTR_MSG_BACK_OUT (struct alpha_thread_state *state)
+{
+ return;
+}
+
+#include "hurdfault.h"
+
+/* This cannot be an inline function because it calls setjmp. */
+#define SYSCALL_EXAMINE(state, callno) \
+({ \
+ u_int32_t *p = (void *) ((state)->pc - 4); \
+ int result; \
+ _hurdsig_catch_memory_fault (p) ? 0 : \
+ ({ \
+ result = (*p == 0x00000083); \
+ _hurdsig_end_catch_fault (); \
+ if (result) \
+ /* The PC is just after a `callsys' instruction. \
+ This is a system call in progress; v0 holds the call number. */ \
+ *(callno) = (state)->r0; \
+ result; \
+ }); \
+})
+
+struct mach_msg_trap_args
+ {
+ /* This is the order of arguments to mach_msg_trap. */
+ mach_msg_header_t *msg;
+ mach_msg_option_t option;
+ mach_msg_size_t send_size;
+ mach_msg_size_t rcv_size;
+ mach_port_t rcv_name;
+ mach_msg_timeout_t timeout;
+ mach_port_t notify;
+ };
+
+/* This cannot be an inline function because it calls setjmp. */
+#define MSG_EXAMINE(state, msgid, rcv_name, send_name, option, timeout) \
+({ \
+ mach_msg_header_t *msg = (mach_msg_header_t *) (state)->r16; \
+ *(option) = (mach_msg_option_t) (state)->r17; \
+ *(rcv_name) = (mach_port_t) (state)->r18; \
+ *(timeout) = (mach_msg_timeout_t) (state)->r19; \
+ (msg == 0) ? \
+ ({ \
+ *(send_name) = MACH_PORT_NULL; \
+ *(msgid) = 0; \
+ 0; \
+ }) : \
+ (_hurdsig_catch_memory_fault (msg) ? -1 : \
+ ({ \
+ *(send_name) = msg->msgh_remote_port; \
+ *(msgid) = msg->msgh_id; \
+ _hurdsig_end_catch_fault (); \
+ 0; \
+ }) \
+ ); \
+})
diff --git a/libc/sysdeps/mach/hurd/alpha/longjmp-ts.c b/libc/sysdeps/mach/hurd/alpha/longjmp-ts.c
new file mode 100644
index 000000000..f472dbcb3
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/alpha/longjmp-ts.c
@@ -0,0 +1,49 @@
+/* Perform a `longjmp' on a Mach thread_state. Alpha version.
+ Copyright (C) 2002, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd/signal.h>
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <mach/thread_status.h>
+
+
+/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'. */
+
+void
+_hurd_longjmp_thread_state (void *state, jmp_buf env, int val)
+{
+ struct alpha_thread_state *const ts = state;
+
+ ts->r9 = env[0].__jmpbuf[JB_S0];
+ ts->r10 = env[0].__jmpbuf[JB_S1];
+ ts->r11 = env[0].__jmpbuf[JB_S2];
+ ts->r12 = env[0].__jmpbuf[JB_S3];
+ ts->r13 = env[0].__jmpbuf[JB_S4];
+ ts->r13 = env[0].__jmpbuf[JB_S5];
+ ts->pc = env[0].__jmpbuf[JB_PC];
+ ts->r15 = env[0].__jmpbuf[JB_FP];
+ ts->r30 = env[0].__jmpbuf[JB_SP];
+ ts->r0 = val ?: 1;
+
+ /* XXX
+ To mimic longjmp we ought to restore some fp registers too.
+ But those registers are in struct alpha_float_state.
+ The only use of this is in fork, and it probably won't matter.
+ */
+}
diff --git a/libc/sysdeps/mach/hurd/alpha/sigreturn.c b/libc/sysdeps/mach/hurd/alpha/sigreturn.c
new file mode 100644
index 000000000..182d4cbd8
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/alpha/sigreturn.c
@@ -0,0 +1,211 @@
+/* Return from signal handler in GNU C library for Hurd. Alpha version.
+ Copyright (C) 1994,95,97,98,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/threadvar.h>
+#include <hurd/msg.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+__sigreturn (struct sigcontext *scp)
+{
+ struct hurd_sigstate *ss;
+ mach_port_t *reply_port;
+
+ if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ ss = _hurd_self_sigstate ();
+ __spin_lock (&ss->lock);
+
+ /* Restore the set of blocked signals, and the intr_port slot. */
+ ss->blocked = scp->sc_mask;
+ ss->intr_port = scp->sc_intr_port;
+
+ /* Check for pending signals that were blocked by the old set. */
+ if (ss->pending & ~ss->blocked)
+ {
+ /* There are pending signals that just became unblocked. Wake up the
+ signal thread to deliver them. But first, squirrel away SCP where
+ the signal thread will notice it if it runs another handler, and
+ arrange to have us called over again in the new reality. */
+ ss->context = scp;
+ /* Clear the intr_port slot, since we are not in fact doing
+ an interruptible RPC right now. If SS->intr_port is not null,
+ the SCP context is doing an interruptible RPC, but the signal
+ thread will examine us while we are blocked in the sig_post RPC. */
+ ss->intr_port = MACH_PORT_NULL;
+ __spin_unlock (&ss->lock);
+ __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
+ /* If a pending signal was handled, sig_post never returned. */
+ __spin_lock (&ss->lock);
+ }
+
+ if (scp->sc_onstack)
+ {
+ ss->sigaltstack.ss_flags &= ~SS_ONSTACK; /* XXX threadvars */
+ /* XXX cannot unlock until off sigstack */
+ abort ();
+ }
+ else
+ __spin_unlock (&ss->lock);
+
+ /* Destroy the MiG reply port used by the signal handler, and restore the
+ reply port in use by the thread when interrupted. */
+ reply_port =
+ (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY);
+ if (*reply_port)
+ __mach_port_destroy (__mach_task_self (), *reply_port);
+ *reply_port = scp->sc_reply_port;
+
+ if (scp->sc_used_fpa)
+ {
+ /* Restore FPU state. */
+
+ /* Restore the floating-point control/status register.
+ We must do this first because the compiler will need
+ a temporary FP register for the load. */
+ asm volatile ("mt_fpcr %0" : : "f" (scp->sc_fpcsr));
+
+ /* Restore floating-point registers. */
+#define restore_fpr(n) \
+ asm volatile ("ldt $f" #n ",%0" : : "m" (scp->sc_fpregs[n]))
+ restore_fpr (0);
+ restore_fpr (1);
+ restore_fpr (2);
+ restore_fpr (3);
+ restore_fpr (4);
+ restore_fpr (5);
+ restore_fpr (6);
+ restore_fpr (7);
+ restore_fpr (8);
+ restore_fpr (9);
+ restore_fpr (10);
+ restore_fpr (11);
+ restore_fpr (12);
+ restore_fpr (13);
+ restore_fpr (14);
+ restore_fpr (15);
+ restore_fpr (16);
+ restore_fpr (17);
+ restore_fpr (18);
+ restore_fpr (19);
+ restore_fpr (20);
+ restore_fpr (21);
+ restore_fpr (22);
+ restore_fpr (23);
+ restore_fpr (24);
+ restore_fpr (25);
+ restore_fpr (26);
+ restore_fpr (27);
+ restore_fpr (28);
+ restore_fpr (29);
+ restore_fpr (30);
+ }
+
+ /* Load all the registers from the sigcontext. */
+#define restore_gpr(n) \
+ asm volatile ("ldq $" #n ",%0" : : "m" (scpreg->sc_regs[n]))
+
+ {
+ /* The `rei' PAL pseudo-instruction restores registers $2..$7, the PC
+ and processor status. So we can use these few registers for our
+ working variables. Unfortunately, it finds its data on the stack
+ and merely pops the SP ($30) over the words of state restored,
+ allowing no other option for the new SP value. So we must push the
+ registers and PSW it will to restore, onto the user's stack and let
+ it pop them from there. */
+ register const struct sigcontext *const scpreg asm ("$2") = scp;
+ register integer_t *usp asm ("$3") = (integer_t *) scpreg->sc_regs[30];
+ register integer_t usp_align asm ("$4");
+
+ /* Push an 8-word "trap frame" onto the user stack for `rei':
+ registers $2..$7, the PC, and the PSW. */
+
+ register struct rei_frame
+ {
+ integer_t regs[5], pc, ps;
+ } *rei_frame asm ("$5");
+
+ usp -= 8;
+ /* `rei' demands that the stack be aligned to a 64 byte (8 word)
+ boundary; bits 61..56 of the PSW are OR'd back into the SP value
+ after popping the 8-word trap frame, so we store (sp % 64)
+ there and this restores the original user SP. */
+ usp_align = (integer_t) usp & 63L;
+ rei_frame = (void *) ((integer_t) usp & ~63L);
+
+ /* Copy the registers and PC from the sigcontext. */
+ memcpy (rei_frame->regs, &scpreg->sc_regs[2], sizeof rei_frame->regs);
+ rei_frame->pc = scpreg->sc_pc;
+
+ /* Compute the new PS value to be restored. `rei' adds the value at
+ bits 61..56 to the SP to compensate for the alignment above that
+ cleared the low 6 bits; bits 5..3 are the new mode/privilege level
+ (must be >= current mode; 3 == user mode); bits 2..0 are "software",
+ unused by the processor or kernel (XXX should trampoline save these?
+ How?); in user mode, `rei' demands that all other bits be zero. */
+ rei_frame->ps = (usp_align << 56) | (3 << 3); /* XXX low 3 bits??? */
+
+ /* Restore the other general registers: everything except $2..$7, which
+ are in the `rei' trap frame we set up above, and $30, which is the
+ SP which is popped by `rei'. */
+ restore_gpr (1);
+ restore_gpr (8);
+ restore_gpr (9);
+ restore_gpr (10);
+ restore_gpr (11);
+ restore_gpr (12);
+ restore_gpr (13);
+ restore_gpr (14);
+ restore_gpr (15);
+ restore_gpr (16);
+ restore_gpr (17);
+ restore_gpr (18);
+ restore_gpr (19);
+ restore_gpr (20);
+ restore_gpr (21);
+ restore_gpr (22);
+ restore_gpr (23);
+ restore_gpr (24);
+ restore_gpr (25);
+ restore_gpr (26);
+ restore_gpr (27);
+ restore_gpr (28);
+ restore_gpr (29);
+
+ /* Switch the stack pointer to the trap frame set up on
+ the user stack and do the magical `rei' PAL call. */
+ asm volatile ("mov %0, $30\n"
+ "call_pal %1"
+ : : "r" (rei_frame), "i" (63)); /* PAL_rti */
+ /* Firewall. */
+ asm volatile ("halt");
+ }
+
+ /* NOTREACHED */
+ return -1;
+}
+
+weak_alias (__sigreturn, sigreturn)
diff --git a/libc/sysdeps/mach/hurd/alpha/static-start.S b/libc/sysdeps/mach/hurd/alpha/static-start.S
new file mode 100644
index 000000000..a31d0d097
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/alpha/static-start.S
@@ -0,0 +1,30 @@
+/* Startup code for statically linked Hurd/Alpha binaries.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ .align 3
+ .globl _start
+ .type _start,@function
+_start:
+ jsr ra, _hurd_stack_setup
+
+#define _start _start1
+#include <sysdeps/alpha/elf/start.S>
diff --git a/libc/sysdeps/mach/hurd/alpha/trampoline.c b/libc/sysdeps/mach/hurd/alpha/trampoline.c
new file mode 100644
index 000000000..2360cbb46
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/alpha/trampoline.c
@@ -0,0 +1,249 @@
+/* Set thread_state for sighandler, and sigcontext to recover. Alpha version.
+ Copyright (C) 1994,95,97,98,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd/signal.h>
+#include "thread_state.h"
+#include "hurdfault.h"
+#include <assert.h>
+
+struct mach_msg_trap_args
+ {
+ /* This is the order of arguments to mach_msg_trap. */
+ mach_msg_header_t *msg;
+ mach_msg_option_t option;
+ mach_msg_size_t send_size;
+ mach_msg_size_t rcv_size;
+ mach_port_t rcv_name;
+ mach_msg_timeout_t timeout;
+ mach_port_t notify;
+ };
+
+
+struct sigcontext *
+_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+ int signo, struct hurd_signal_detail *detail,
+ int rpc_wait, struct machine_thread_all_state *state)
+{
+ __label__ trampoline, rpc_wait_trampoline;
+ void *sigsp;
+ struct sigcontext *scp;
+
+ if (ss->context)
+ {
+ /* We have a previous sigcontext that sigreturn was about
+ to restore when another signal arrived. We will just base
+ our setup on that. */
+ if (! _hurdsig_catch_memory_fault (ss->context))
+ {
+ memcpy (&state->basic, &ss->context->sc_alpha_thread_state,
+ sizeof (state->basic));
+ memcpy (&state->exc, &ss->context->sc_alpha_exc_state,
+ sizeof (state->exc));
+ state->set = (1 << ALPHA_THREAD_STATE) | (1 << ALPHA_EXC_STATE);
+ if (state->exc.used_fpa)
+ {
+ memcpy (&state->fpu, &ss->context->sc_alpha_float_state,
+ sizeof (state->fpu));
+ state->set |= (1 << ALPHA_FLOAT_STATE);
+ }
+ assert (! rpc_wait);
+ /* The intr_port slot was cleared before sigreturn sent us the
+ sig_post that made us notice this pending signal, so
+ _hurd_internal_post_signal wouldn't do interrupt_operation.
+ After we return, our caller will set SCP->sc_intr_port (in the
+ new context) from SS->intr_port and clear SS->intr_port. Now
+ that we are restoring this old context recorded by sigreturn,
+ we want to restore its intr_port too; so store it in
+ SS->intr_port now, so it will end up in SCP->sc_intr_port
+ later. */
+ ss->intr_port = ss->context->sc_intr_port;
+ }
+ _hurdsig_end_catch_fault ();
+
+ /* If the sigreturn context was bogus, just ignore it. */
+ ss->context = NULL;
+ }
+ else if (! machine_get_basic_state (ss->thread, state))
+ return NULL;
+
+ if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
+ !(ss->sigaltstack.ss_flags & (SS_DISABLE|SS_ONSTACK)))
+ {
+ sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
+ ss->sigaltstack.ss_flags |= SS_ONSTACK;
+ /* XXX need to set up base of new stack for
+ per-thread variables, cthreads. */
+ }
+ else
+ sigsp = (char *) state->basic.SP;
+
+ /* Set up the sigcontext structure on the stack. This is all the stack
+ needs, since the args are passed in registers (below). */
+ sigsp -= sizeof (*scp);
+ scp = sigsp;
+
+ if (_hurdsig_catch_memory_fault (scp))
+ {
+ /* We got a fault trying to write the stack frame.
+ We cannot set up the signal handler.
+ Returning NULL tells our caller, who will nuke us with a SIGILL. */
+ return NULL;
+ }
+ else
+ {
+ /* Set up the sigcontext from the current state of the thread. */
+
+ scp->sc_onstack = ss->sigaltstack.ss_flags & SS_ONSTACK ? 1 : 0;
+
+ /* struct sigcontext is laid out so that starting at sc_regs
+ mimics a struct alpha_thread_state. */
+ memcpy (&scp->sc_alpha_thread_state,
+ &state->basic, sizeof (state->basic));
+
+ /* struct sigcontext is laid out so that starting at sc_badvaddr
+ mimics a struct mips_exc_state. */
+ if (! machine_get_state (ss->thread, state, ALPHA_EXC_STATE,
+ &state->exc, &scp->sc_alpha_exc_state,
+ sizeof (state->exc)))
+ return NULL;
+
+ if (state->exc.used_fpa &&
+ /* struct sigcontext is laid out so that starting at sc_fpregs
+ mimics a struct alpha_float_state. This state
+ is only meaningful if the coprocessor was used. */
+ ! machine_get_state (ss->thread, state, ALPHA_FLOAT_STATE,
+ &state->fpu,
+ &scp->sc_alpha_float_state,
+ sizeof (state->fpu)))
+ return NULL;
+
+ _hurdsig_end_catch_fault ();
+ }
+
+ /* Modify the thread state to call the trampoline code on the new stack. */
+ if (rpc_wait)
+ {
+ /* The signalee thread was blocked in a mach_msg_trap system call,
+ still waiting for a reply. We will have it run the special
+ trampoline code which retries the message receive before running
+ the signal handler.
+
+ To do this we change the OPTION argument in its registers to
+ enable only message reception, since the request message has
+ already been sent. */
+
+ /* The system call arguments are stored in consecutive registers
+ starting with a0 ($16). */
+ struct mach_msg_trap_args *args = (void *) &state->basic.r16;
+
+ assert (args->option & MACH_RCV_MSG);
+ /* Disable the message-send, since it has already completed. The
+ calls we retry need only wait to receive the reply message. */
+ args->option &= ~MACH_SEND_MSG;
+
+ /* Limit the time to receive the reply message, in case the server
+ claimed that `interrupt_operation' succeeded but in fact the RPC
+ is hung. */
+ args->option |= MACH_RCV_TIMEOUT;
+ args->timeout = _hurd_interrupted_rpc_timeout;
+
+ state->basic.pc = (long int) &&rpc_wait_trampoline;
+ /* After doing the message receive, the trampoline code will need to
+ update the v0 ($0) value to be restored by sigreturn. To simplify
+ the assembly code, we pass the address of its slot in SCP to the
+ trampoline code in at ($28). */
+ state->basic.r28 = (long int) &scp->sc_regs[0];
+ /* We must preserve the mach_msg_trap args in a0..a5 and t0
+ ($16..$21, $1). Pass the handler args to the trampoline code in
+ t8..t10 ($22.$24). */
+ state->basic.r22 = signo;
+ state->basic.r23 = detail->code;
+ state->basic.r24 = (long int) scp;
+ }
+ else
+ {
+ state->basic.pc = (long int) &&trampoline;
+ state->basic.r16 = signo;
+ state->basic.r17 = detail->code;
+ state->basic.r18 = (long int) scp;
+ }
+
+ state->basic.r30 = (long int) sigsp; /* $30 is the stack pointer. */
+
+ /* We pass the handler function to the trampoline code in ra ($26). */
+ state->basic.r26 = (long int) handler;
+ /* In the callee-saved register t12/pv ($27), we store the
+ address of __sigreturn itself, for the trampoline code to use. */
+ state->basic.r27 = (long int) &__sigreturn;
+ /* In the callee-saved register t11/ai ($25), we save the SCP value to pass
+ to __sigreturn after the handler returns. */
+ state->basic.r25 = (long int) scp;
+
+ return scp;
+
+ /* The trampoline code follows. This is not actually executed as part of
+ this function, it is just convenient to write it that way. */
+
+ rpc_wait_trampoline:
+ /* This is the entry point when we have an RPC reply message to receive
+ before running the handler. The MACH_MSG_SEND bit has already been
+ cleared in the OPTION argument in our registers. For our convenience,
+ at ($28) points to the sc_regs[0] member of the sigcontext (saved v0
+ ($0)). */
+ asm volatile
+ (/* Retry the interrupted mach_msg system call. */
+ "lda $0, -25($31)\n" /* mach_msg_trap */
+ "callsys\n" /* Magic system call instruction. */
+ /* When the sigcontext was saved, v0 was MACH_RCV_INTERRUPTED. But
+ now the message receive has completed and the original caller of
+ the RPC (i.e. the code running when the signal arrived) needs to
+ see the final return value of the message receive in v0. So
+ store the new v0 value into the sc_regs[0] member of the sigcontext
+ (whose address is in at to make this code simpler). */
+ "stq $0, 0($28)\n"
+ /* Since the argument registers needed to have the mach_msg_trap
+ arguments, we've stored the arguments to the handler function
+ in registers t8..t10 ($22..$24). */
+ "mov $22, $16\n"
+ "mov $23, $17\n"
+ "mov $24, $18\n");
+
+ trampoline:
+ /* Entry point for running the handler normally. The arguments to the
+ handler function are already in the standard registers:
+
+ a0 SIGNO
+ a1 SIGCODE
+ a2 SCP
+
+ t12 also contains SCP; this value is callee-saved (and so should not get
+ clobbered by running the handler). We use this saved value to pass to
+ __sigreturn, so the handler can clobber the argument registers if it
+ likes. */
+ /* Call the handler function, saving return address in ra ($26). */
+ asm volatile ("jsr $26, ($26)");
+ /* Reset gp ($29) from the return address (here) in ra ($26). */
+ asm volatile ("ldgp $29, 0($26)");
+ asm volatile ("mov $25, $16"); /* Move saved SCP to argument register. */
+ /* Call __sigreturn (SCP); this cannot return. */
+ asm volatile ("jmp $31, ($27)");
+
+ /* NOTREACHED */
+ return NULL;
+}
diff --git a/libc/sysdeps/mach/hurd/bind.c b/libc/sysdeps/mach/hurd/bind.c
new file mode 100644
index 000000000..a42b78ac0
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/bind.c
@@ -0,0 +1,125 @@
+/* Copyright (C) 1992,94,95,96,97,98,2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+#include <hurd/paths.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <hurd/ifsock.h>
+#include <sys/un.h>
+#include <string.h>
+
+/* Give the socket FD the local address ADDR (which is LEN bytes long). */
+int
+__bind (int fd, __CONST_SOCKADDR_ARG addrarg, socklen_t len)
+{
+ addr_port_t aport;
+ error_t err;
+ const struct sockaddr_un *addr = addrarg.__sockaddr_un__;
+
+ if (addr->sun_family == AF_LOCAL)
+ {
+ /* For the local domain, we must create a node in the filesystem
+ using the ifsock translator and then fetch the address from it. */
+ file_t dir, node;
+ char name[len - offsetof (struct sockaddr_un, sun_path) + 1], *n;
+
+ strncpy (name, addr->sun_path, sizeof name - 1);
+ name[sizeof name - 1] = '\0'; /* Make sure */
+
+ dir = __file_name_split (name, &n);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ /* Create a new, unlinked node in the target directory. */
+ err = __dir_mkfile (dir, O_CREAT, 0666 & ~_hurd_umask, &node);
+
+ if (! err)
+ {
+ /* Set the node's translator to make it a local-domain socket. */
+ err = __file_set_translator (node,
+ FS_TRANS_EXCL | FS_TRANS_SET,
+ FS_TRANS_EXCL | FS_TRANS_SET, 0,
+ _HURD_IFSOCK, sizeof _HURD_IFSOCK,
+ MACH_PORT_NULL,
+ MACH_MSG_TYPE_COPY_SEND);
+ if (! err)
+ {
+ /* Link the node, now a socket, into the target directory. */
+ err = __dir_link (dir, node, n, 1);
+ if (err == EEXIST)
+ err = EADDRINUSE;
+ }
+ __mach_port_deallocate (__mach_task_self (), node);
+ if (! err)
+ {
+ /* Get a port to the ifsock translator. */
+ file_t ifsock = __file_name_lookup_under (dir, n, 0, 0);
+ if (ifsock == MACH_PORT_NULL)
+ {
+ err = errno;
+ /* If we failed, get rid of the node we created. */
+ __dir_unlink (dir, n);
+ }
+ else
+ {
+ /* Get the address port. */
+ err = __ifsock_getsockaddr (ifsock, &aport);
+ if (err == MIG_BAD_ID || err == EOPNOTSUPP)
+ /* We are not talking to /hurd/ifsock. Probably
+ someone came in after we linked our node, unlinked
+ it, and replaced it with a different node, before we
+ did our lookup. Treat it as if our link had failed
+ with EEXIST. */
+ err = EADDRINUSE;
+ }
+ __mach_port_deallocate (__mach_task_self (), ifsock);
+ }
+ }
+ __mach_port_deallocate (__mach_task_self (), dir);
+
+ if (err)
+ return __hurd_fail (err);
+ }
+ else
+ err = EIEIO;
+
+ err = HURD_DPORT_USE (fd,
+ ({
+ if (err)
+ err = __socket_create_address (port,
+ addr->sun_family,
+ (char *) addr, len,
+ &aport);
+ if (! err)
+ {
+ err = __socket_bind (port, aport);
+ __mach_port_deallocate (__mach_task_self (),
+ aport);
+ }
+ err;
+ }));
+
+ return err ? __hurd_dfail (fd, err) : 0;
+}
+
+weak_alias (__bind, bind)
diff --git a/libc/sysdeps/mach/hurd/bits/errno.h b/libc/sysdeps/mach/hurd/bits/errno.h
new file mode 100644
index 000000000..a7d57adeb
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/bits/errno.h
@@ -0,0 +1,321 @@
+/* This file generated by errnos.awk. */
+
+/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */
+#ifndef _HURD_ERRNO
+#define _HURD_ERRNO(n) ((0x10 << 26) | ((n) & 0x3fff))
+#endif
+
+#ifdef _ERRNO_H
+
+enum __error_t_codes
+{
+#undef EDOM
+#undef ERANGE
+ EPERM = _HURD_ERRNO (1),
+#define EPERM _HURD_ERRNO (1) /* Operation not permitted */
+ ENOENT = _HURD_ERRNO (2),
+#define ENOENT _HURD_ERRNO (2) /* No such file or directory */
+ ESRCH = _HURD_ERRNO (3),
+#define ESRCH _HURD_ERRNO (3) /* No such process */
+ EINTR = _HURD_ERRNO (4),
+#define EINTR _HURD_ERRNO (4) /* Interrupted system call */
+ EIO = _HURD_ERRNO (5),
+#define EIO _HURD_ERRNO (5) /* Input/output error */
+ ENXIO = _HURD_ERRNO (6),
+#define ENXIO _HURD_ERRNO (6) /* No such device or address */
+ E2BIG = _HURD_ERRNO (7),
+#define E2BIG _HURD_ERRNO (7) /* Argument list too long */
+ ENOEXEC = _HURD_ERRNO (8),
+#define ENOEXEC _HURD_ERRNO (8) /* Exec format error */
+ EBADF = _HURD_ERRNO (9),
+#define EBADF _HURD_ERRNO (9) /* Bad file descriptor */
+ ECHILD = _HURD_ERRNO (10),
+#define ECHILD _HURD_ERRNO (10)/* No child processes */
+ EDEADLK = _HURD_ERRNO (11),
+#define EDEADLK _HURD_ERRNO (11)/* Resource deadlock avoided */
+ ENOMEM = _HURD_ERRNO (12),
+#define ENOMEM _HURD_ERRNO (12)/* Cannot allocate memory */
+ EACCES = _HURD_ERRNO (13),
+#define EACCES _HURD_ERRNO (13)/* Permission denied */
+ EFAULT = _HURD_ERRNO (14),
+#define EFAULT _HURD_ERRNO (14)/* Bad address */
+ ENOTBLK = _HURD_ERRNO (15),
+#define ENOTBLK _HURD_ERRNO (15)/* Block device required */
+ EBUSY = _HURD_ERRNO (16),
+#define EBUSY _HURD_ERRNO (16)/* Device or resource busy */
+ EEXIST = _HURD_ERRNO (17),
+#define EEXIST _HURD_ERRNO (17)/* File exists */
+ EXDEV = _HURD_ERRNO (18),
+#define EXDEV _HURD_ERRNO (18)/* Invalid cross-device link */
+ ENODEV = _HURD_ERRNO (19),
+#define ENODEV _HURD_ERRNO (19)/* No such device */
+ ENOTDIR = _HURD_ERRNO (20),
+#define ENOTDIR _HURD_ERRNO (20)/* Not a directory */
+ EISDIR = _HURD_ERRNO (21),
+#define EISDIR _HURD_ERRNO (21)/* Is a directory */
+ EINVAL = _HURD_ERRNO (22),
+#define EINVAL _HURD_ERRNO (22)/* Invalid argument */
+ EMFILE = _HURD_ERRNO (24),
+#define EMFILE _HURD_ERRNO (24)/* Too many open files */
+ ENFILE = _HURD_ERRNO (23),
+#define ENFILE _HURD_ERRNO (23)/* Too many open files in system */
+ ENOTTY = _HURD_ERRNO (25),
+#define ENOTTY _HURD_ERRNO (25)/* Inappropriate ioctl for device */
+ ETXTBSY = _HURD_ERRNO (26),
+#define ETXTBSY _HURD_ERRNO (26)/* Text file busy */
+ EFBIG = _HURD_ERRNO (27),
+#define EFBIG _HURD_ERRNO (27)/* File too large */
+ ENOSPC = _HURD_ERRNO (28),
+#define ENOSPC _HURD_ERRNO (28)/* No space left on device */
+ ESPIPE = _HURD_ERRNO (29),
+#define ESPIPE _HURD_ERRNO (29)/* Illegal seek */
+ EROFS = _HURD_ERRNO (30),
+#define EROFS _HURD_ERRNO (30)/* Read-only file system */
+ EMLINK = _HURD_ERRNO (31),
+#define EMLINK _HURD_ERRNO (31)/* Too many links */
+ EPIPE = _HURD_ERRNO (32),
+#define EPIPE _HURD_ERRNO (32)/* Broken pipe */
+ EDOM = _HURD_ERRNO (33),
+#define EDOM _HURD_ERRNO (33)/* Numerical argument out of domain */
+ ERANGE = _HURD_ERRNO (34),
+#define ERANGE _HURD_ERRNO (34)/* Numerical result out of range */
+ EAGAIN = _HURD_ERRNO (35),
+#define EAGAIN _HURD_ERRNO (35)/* Resource temporarily unavailable */
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+ EINPROGRESS = _HURD_ERRNO (36),
+#define EINPROGRESS _HURD_ERRNO (36)/* Operation now in progress */
+ EALREADY = _HURD_ERRNO (37),
+#define EALREADY _HURD_ERRNO (37)/* Operation already in progress */
+ ENOTSOCK = _HURD_ERRNO (38),
+#define ENOTSOCK _HURD_ERRNO (38)/* Socket operation on non-socket */
+ EMSGSIZE = _HURD_ERRNO (40),
+#define EMSGSIZE _HURD_ERRNO (40)/* Message too long */
+ EPROTOTYPE = _HURD_ERRNO (41),
+#define EPROTOTYPE _HURD_ERRNO (41)/* Protocol wrong type for socket */
+ ENOPROTOOPT = _HURD_ERRNO (42),
+#define ENOPROTOOPT _HURD_ERRNO (42)/* Protocol not available */
+ EPROTONOSUPPORT = _HURD_ERRNO (43),
+#define EPROTONOSUPPORT _HURD_ERRNO (43)/* Protocol not supported */
+ ESOCKTNOSUPPORT = _HURD_ERRNO (44),
+#define ESOCKTNOSUPPORT _HURD_ERRNO (44)/* Socket type not supported */
+ EOPNOTSUPP = _HURD_ERRNO (45),
+#define EOPNOTSUPP _HURD_ERRNO (45)/* Operation not supported */
+ EPFNOSUPPORT = _HURD_ERRNO (46),
+#define EPFNOSUPPORT _HURD_ERRNO (46)/* Protocol family not supported */
+ EAFNOSUPPORT = _HURD_ERRNO (47),
+#define EAFNOSUPPORT _HURD_ERRNO (47)/* Address family not supported by protocol */
+ EADDRINUSE = _HURD_ERRNO (48),
+#define EADDRINUSE _HURD_ERRNO (48)/* Address already in use */
+ EADDRNOTAVAIL = _HURD_ERRNO (49),
+#define EADDRNOTAVAIL _HURD_ERRNO (49)/* Cannot assign requested address */
+ ENETDOWN = _HURD_ERRNO (50),
+#define ENETDOWN _HURD_ERRNO (50)/* Network is down */
+ ENETUNREACH = _HURD_ERRNO (51),
+#define ENETUNREACH _HURD_ERRNO (51)/* Network is unreachable */
+ ENETRESET = _HURD_ERRNO (52),
+#define ENETRESET _HURD_ERRNO (52)/* Network dropped connection on reset */
+ ECONNABORTED = _HURD_ERRNO (53),
+#define ECONNABORTED _HURD_ERRNO (53)/* Software caused connection abort */
+ ECONNRESET = _HURD_ERRNO (54),
+#define ECONNRESET _HURD_ERRNO (54)/* Connection reset by peer */
+ ENOBUFS = _HURD_ERRNO (55),
+#define ENOBUFS _HURD_ERRNO (55)/* No buffer space available */
+ EISCONN = _HURD_ERRNO (56),
+#define EISCONN _HURD_ERRNO (56)/* Transport endpoint is already connected */
+ ENOTCONN = _HURD_ERRNO (57),
+#define ENOTCONN _HURD_ERRNO (57)/* Transport endpoint is not connected */
+ EDESTADDRREQ = _HURD_ERRNO (39),
+#define EDESTADDRREQ _HURD_ERRNO (39)/* Destination address required */
+ ESHUTDOWN = _HURD_ERRNO (58),
+#define ESHUTDOWN _HURD_ERRNO (58)/* Cannot send after transport endpoint shutdown */
+ ETOOMANYREFS = _HURD_ERRNO (59),
+#define ETOOMANYREFS _HURD_ERRNO (59)/* Too many references: cannot splice */
+ ETIMEDOUT = _HURD_ERRNO (60),
+#define ETIMEDOUT _HURD_ERRNO (60)/* Connection timed out */
+ ECONNREFUSED = _HURD_ERRNO (61),
+#define ECONNREFUSED _HURD_ERRNO (61)/* Connection refused */
+ ELOOP = _HURD_ERRNO (62),
+#define ELOOP _HURD_ERRNO (62)/* Too many levels of symbolic links */
+ ENAMETOOLONG = _HURD_ERRNO (63),
+#define ENAMETOOLONG _HURD_ERRNO (63)/* File name too long */
+ EHOSTDOWN = _HURD_ERRNO (64),
+#define EHOSTDOWN _HURD_ERRNO (64)/* Host is down */
+ EHOSTUNREACH = _HURD_ERRNO (65),
+#define EHOSTUNREACH _HURD_ERRNO (65)/* No route to host */
+ ENOTEMPTY = _HURD_ERRNO (66),
+#define ENOTEMPTY _HURD_ERRNO (66)/* Directory not empty */
+ EPROCLIM = _HURD_ERRNO (67),
+#define EPROCLIM _HURD_ERRNO (67)/* Too many processes */
+ EUSERS = _HURD_ERRNO (68),
+#define EUSERS _HURD_ERRNO (68)/* Too many users */
+ EDQUOT = _HURD_ERRNO (69),
+#define EDQUOT _HURD_ERRNO (69)/* Disk quota exceeded */
+ ESTALE = _HURD_ERRNO (70),
+#define ESTALE _HURD_ERRNO (70)/* Stale NFS file handle */
+ EREMOTE = _HURD_ERRNO (71),
+#define EREMOTE _HURD_ERRNO (71)/* Object is remote */
+ EBADRPC = _HURD_ERRNO (72),
+#define EBADRPC _HURD_ERRNO (72)/* RPC struct is bad */
+ ERPCMISMATCH = _HURD_ERRNO (73),
+#define ERPCMISMATCH _HURD_ERRNO (73)/* RPC version wrong */
+ EPROGUNAVAIL = _HURD_ERRNO (74),
+#define EPROGUNAVAIL _HURD_ERRNO (74)/* RPC program not available */
+ EPROGMISMATCH = _HURD_ERRNO (75),
+#define EPROGMISMATCH _HURD_ERRNO (75)/* RPC program version wrong */
+ EPROCUNAVAIL = _HURD_ERRNO (76),
+#define EPROCUNAVAIL _HURD_ERRNO (76)/* RPC bad procedure for program */
+ ENOLCK = _HURD_ERRNO (77),
+#define ENOLCK _HURD_ERRNO (77)/* No locks available */
+ EFTYPE = _HURD_ERRNO (79),
+#define EFTYPE _HURD_ERRNO (79)/* Inappropriate file type or format */
+ EAUTH = _HURD_ERRNO (80),
+#define EAUTH _HURD_ERRNO (80)/* Authentication error */
+ ENEEDAUTH = _HURD_ERRNO (81),
+#define ENEEDAUTH _HURD_ERRNO (81)/* Need authenticator */
+ ENOSYS = _HURD_ERRNO (78),
+#define ENOSYS _HURD_ERRNO (78)/* Function not implemented */
+ ENOTSUP = _HURD_ERRNO (118),
+#define ENOTSUP _HURD_ERRNO (118)/* Not supported */
+ EILSEQ = _HURD_ERRNO (106),
+#define EILSEQ _HURD_ERRNO (106)/* Invalid or incomplete multibyte or wide character */
+ EBACKGROUND = _HURD_ERRNO (100),
+#define EBACKGROUND _HURD_ERRNO (100)/* Inappropriate operation for background process */
+ EDIED = _HURD_ERRNO (101),
+#define EDIED _HURD_ERRNO (101)/* Translator died */
+ ED = _HURD_ERRNO (102),
+#define ED _HURD_ERRNO (102)/* ? */
+ EGREGIOUS = _HURD_ERRNO (103),
+#define EGREGIOUS _HURD_ERRNO (103)/* You really blew it this time */
+ EIEIO = _HURD_ERRNO (104),
+#define EIEIO _HURD_ERRNO (104)/* Computer bought the farm */
+ EGRATUITOUS = _HURD_ERRNO (105),
+#define EGRATUITOUS _HURD_ERRNO (105)/* Gratuitous error */
+ EBADMSG = _HURD_ERRNO (107),
+#define EBADMSG _HURD_ERRNO (107)/* Bad message */
+ EIDRM = _HURD_ERRNO (108),
+#define EIDRM _HURD_ERRNO (108)/* Identifier removed */
+ EMULTIHOP = _HURD_ERRNO (109),
+#define EMULTIHOP _HURD_ERRNO (109)/* Multihop attempted */
+ ENODATA = _HURD_ERRNO (110),
+#define ENODATA _HURD_ERRNO (110)/* No data available */
+ ENOLINK = _HURD_ERRNO (111),
+#define ENOLINK _HURD_ERRNO (111)/* Link has been severed */
+ ENOMSG = _HURD_ERRNO (112),
+#define ENOMSG _HURD_ERRNO (112)/* No message of desired type */
+ ENOSR = _HURD_ERRNO (113),
+#define ENOSR _HURD_ERRNO (113)/* Out of streams resources */
+ ENOSTR = _HURD_ERRNO (114),
+#define ENOSTR _HURD_ERRNO (114)/* Device not a stream */
+ EOVERFLOW = _HURD_ERRNO (115),
+#define EOVERFLOW _HURD_ERRNO (115)/* Value too large for defined data type */
+ EPROTO = _HURD_ERRNO (116),
+#define EPROTO _HURD_ERRNO (116)/* Protocol error */
+ ETIME = _HURD_ERRNO (117),
+#define ETIME _HURD_ERRNO (117)/* Timer expired */
+ ECANCELED = _HURD_ERRNO (118),
+#define ECANCELED _HURD_ERRNO (118)/* Operation canceled */
+
+ /* Errors from <mach/message.h>. */
+ EMACH_SEND_IN_PROGRESS = 0x10000001,
+ EMACH_SEND_INVALID_DATA = 0x10000002,
+ EMACH_SEND_INVALID_DEST = 0x10000003,
+ EMACH_SEND_TIMED_OUT = 0x10000004,
+ EMACH_SEND_WILL_NOTIFY = 0x10000005,
+ EMACH_SEND_NOTIFY_IN_PROGRESS = 0x10000006,
+ EMACH_SEND_INTERRUPTED = 0x10000007,
+ EMACH_SEND_MSG_TOO_SMALL = 0x10000008,
+ EMACH_SEND_INVALID_REPLY = 0x10000009,
+ EMACH_SEND_INVALID_RIGHT = 0x1000000a,
+ EMACH_SEND_INVALID_NOTIFY = 0x1000000b,
+ EMACH_SEND_INVALID_MEMORY = 0x1000000c,
+ EMACH_SEND_NO_BUFFER = 0x1000000d,
+ EMACH_SEND_NO_NOTIFY = 0x1000000e,
+ EMACH_SEND_INVALID_TYPE = 0x1000000f,
+ EMACH_SEND_INVALID_HEADER = 0x10000010,
+ EMACH_RCV_IN_PROGRESS = 0x10004001,
+ EMACH_RCV_INVALID_NAME = 0x10004002,
+ EMACH_RCV_TIMED_OUT = 0x10004003,
+ EMACH_RCV_TOO_LARGE = 0x10004004,
+ EMACH_RCV_INTERRUPTED = 0x10004005,
+ EMACH_RCV_PORT_CHANGED = 0x10004006,
+ EMACH_RCV_INVALID_NOTIFY = 0x10004007,
+ EMACH_RCV_INVALID_DATA = 0x10004008,
+ EMACH_RCV_PORT_DIED = 0x10004009,
+ EMACH_RCV_IN_SET = 0x1000400a,
+ EMACH_RCV_HEADER_ERROR = 0x1000400b,
+ EMACH_RCV_BODY_ERROR = 0x1000400c,
+
+ /* Errors from <mach/kern_return.h>. */
+ EKERN_INVALID_ADDRESS = 1,
+ EKERN_PROTECTION_FAILURE = 2,
+ EKERN_NO_SPACE = 3,
+ EKERN_INVALID_ARGUMENT = 4,
+ EKERN_FAILURE = 5,
+ EKERN_RESOURCE_SHORTAGE = 6,
+ EKERN_NOT_RECEIVER = 7,
+ EKERN_NO_ACCESS = 8,
+ EKERN_MEMORY_FAILURE = 9,
+ EKERN_MEMORY_ERROR = 10,
+ EKERN_NOT_IN_SET = 12,
+ EKERN_NAME_EXISTS = 13,
+ EKERN_ABORTED = 14,
+ EKERN_INVALID_NAME = 15,
+ EKERN_INVALID_TASK = 16,
+ EKERN_INVALID_RIGHT = 17,
+ EKERN_INVALID_VALUE = 18,
+ EKERN_UREFS_OVERFLOW = 19,
+ EKERN_INVALID_CAPABILITY = 20,
+ EKERN_RIGHT_EXISTS = 21,
+ EKERN_INVALID_HOST = 22,
+ EKERN_MEMORY_PRESENT = 23,
+ EKERN_WRITE_PROTECTION_FAILURE = 24,
+ EKERN_TERMINATED = 26,
+
+ /* Errors from <mach/mig_errors.h>. */
+ EMIG_TYPE_ERROR = -300 /* client type check failure */,
+ EMIG_REPLY_MISMATCH = -301 /* wrong reply message ID */,
+ EMIG_REMOTE_ERROR = -302 /* server detected error */,
+ EMIG_BAD_ID = -303 /* bad request message ID */,
+ EMIG_BAD_ARGUMENTS = -304 /* server type check failure */,
+ EMIG_NO_REPLY = -305 /* no reply should be sent */,
+ EMIG_EXCEPTION = -306 /* server raised exception */,
+ EMIG_ARRAY_TOO_LARGE = -307 /* array not large enough */,
+ EMIG_SERVER_DIED = -308 /* server died */,
+ EMIG_DESTROY_REQUEST = -309 /* destroy request with no reply */,
+
+ /* Errors from <device/device_types.h>. */
+ ED_IO_ERROR = 2500 /* hardware IO error */,
+ ED_WOULD_BLOCK = 2501 /* would block, but D_NOWAIT set */,
+ ED_NO_SUCH_DEVICE = 2502 /* no such device */,
+ ED_ALREADY_OPEN = 2503 /* exclusive-use device already open */,
+ ED_DEVICE_DOWN = 2504 /* device has been shut down */,
+ ED_INVALID_OPERATION = 2505 /* bad operation for device */,
+ ED_INVALID_RECNUM = 2506 /* invalid record (block) number */,
+ ED_INVALID_SIZE = 2507 /* invalid IO size */,
+ ED_NO_MEMORY = 2508 /* memory allocation failure */,
+ ED_READ_ONLY = 2509 /* device cannot be written to */
+
+};
+
+#define _HURD_ERRNOS 119
+
+/* User-visible type of error codes. It is ok to use `int' or
+ `kern_return_t' for these, but with `error_t' the debugger prints
+ symbolic values. */
+#ifdef __USE_GNU
+typedef enum __error_t_codes error_t;
+#define __error_t_defined 1
+#endif
+
+/* Return the current thread's location for `errno'.
+ The syntax of this function allows redeclarations like `int errno'. */
+extern int *__errno_location (void) __THROW __attribute__ ((__const__));
+
+#define errno (*__errno_location ())
+
+#endif /* <errno.h> included. */
+
+#if !defined (_ERRNO_H) && defined (__need_Emath)
+#define EDOM _HURD_ERRNO (33)/* Numerical argument out of domain */
+#define ERANGE _HURD_ERRNO (34)/* Numerical result out of range */
+#endif /* <errno.h> not included and need math error codes. */
diff --git a/libc/sysdeps/mach/hurd/bits/fcntl.h b/libc/sysdeps/mach/hurd/bits/fcntl.h
new file mode 100644
index 000000000..e709cc6fb
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/bits/fcntl.h
@@ -0,0 +1,210 @@
+/* O_*, F_*, FD_* bit values for GNU.
+ Copyright (C) 1993,94,96,97,98,99,2000,01,04 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+/* File access modes. These are understood by io servers; they can be
+ passed in `dir_lookup', and are returned by `io_get_openmodes'.
+ Consequently they can be passed to `open', `hurd_file_name_lookup', and
+ `file_name_lookup'; and are returned by `fcntl' with the F_GETFL
+ command. */
+
+/* In GNU, read and write are bits (unlike BSD). */
+#ifdef __USE_GNU
+# define O_READ O_RDONLY /* Open for reading. */
+# define O_WRITE O_WRONLY /* Open for writing. */
+# define O_EXEC 0x0004 /* Open for execution. */
+# define O_NORW 0 /* Open without R/W access. */
+#endif
+/* POSIX.1 standard names. */
+#define O_RDONLY 0x0001 /* Open read-only. */
+#define O_WRONLY 0x0002 /* Open write-only. */
+#define O_RDWR (O_RDONLY|O_WRONLY) /* Open for reading and writing. */
+#define O_ACCMODE O_RDWR /* Mask for file access modes. */
+
+#define O_LARGEFILE 0
+
+
+/* File name translation flags. These are understood by io servers;
+ they can be passed in `dir_lookup', and consequently to `open',
+ `hurd_file_name_lookup', and `file_name_lookup'. */
+
+#define O_CREAT 0x0010 /* Create file if it doesn't exist. */
+#define O_EXCL 0x0020 /* Fail if file already exists. */
+#ifdef __USE_GNU
+# define O_NOLINK 0x0040 /* No name mappings on final component. */
+# define O_NOTRANS 0x0080 /* No translator on final component. */
+
+# define O_NOFOLLOW 0x00100000 /* Produce ENOENT if file is a symlink. */
+# define O_DIRECTORY 0x00200000 /* Produce ENOTDIR if not a directory. */
+#endif
+
+
+/* I/O operating modes. These are understood by io servers; they can be
+ passed in `dir_lookup' and set or fetched with `io_*_openmodes'.
+ Consequently they can be passed to `open', `hurd_file_name_lookup',
+ `file_name_lookup', and `fcntl' with the F_SETFL command; and are
+ returned by `fcntl' with the F_GETFL command. */
+
+#define O_APPEND 0x0100 /* Writes always append to the file. */
+#define O_ASYNC 0x0200 /* Send SIGIO to owner when data is ready. */
+#define O_FSYNC 0x0400 /* Synchronous writes. */
+#define O_SYNC O_FSYNC
+#ifdef __USE_GNU
+# define O_NOATIME 0x0800 /* Don't set access time on read (owner). */
+#endif
+#ifdef __USE_MISC
+# define O_SHLOCK 0x00020000 /* Open with shared file lock. */
+# define O_EXLOCK 0x00040000 /* Open with exclusive file lock. */
+#endif
+
+/* These are lesser flavors of partial synchronization that are
+ implied by our one flag (O_FSYNC). */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC O_SYNC /* Synchronize data. */
+# define O_RSYNC O_SYNC /* Synchronize read operations. */
+#endif
+
+
+/* The name O_NONBLOCK is unfortunately overloaded; it is both a file name
+ translation flag and an I/O operating mode. O_NDELAY is the deprecated
+ BSD name for the same flag, overloaded in the same way.
+
+ When used in `dir_lookup' (and consequently `open', `hurd_file_name_lookup',
+ or `file_name_lookup'), O_NONBLOCK says the open should return immediately
+ instead of blocking for any significant length of time (e.g., to wait
+ for carrier detect on a serial line). It is also saved as an I/O
+ operating mode, and after open has the following meaning.
+
+ When used in `io_*_openmodes' (and consequently `fcntl' with the F_SETFL
+ command), the O_NONBLOCK flag means to do nonblocking i/o: any i/o
+ operation that would block for any significant length of time will instead
+ fail with EAGAIN. */
+
+#define O_NONBLOCK 0x0008 /* Non-blocking open or non-blocking I/O. */
+#ifdef __USE_BSD
+# define O_NDELAY O_NONBLOCK /* Deprecated. */
+#endif
+
+
+#ifdef __USE_GNU
+/* Mask of bits which are understood by io servers. */
+# define O_HURD (0xffff | O_EXLOCK | O_SHLOCK)
+#endif
+
+
+/* Open-time action flags. These are understood by `hurd_file_name_lookup'
+ and consequently by `open' and `file_name_lookup'. They are not preserved
+ once the file has been opened. */
+
+#define O_TRUNC 0x00010000 /* Truncate file to zero length. */
+
+
+/* Controlling terminal flags. These are understood only by `open',
+ and are not preserved once the file has been opened. */
+
+#ifdef __USE_GNU
+# define O_IGNORE_CTTY 0x00080000 /* Don't do any ctty magic at all. */
+#endif
+/* `open' never assigns a controlling terminal in GNU. */
+#define O_NOCTTY 0 /* Don't assign a controlling terminal. */
+
+
+#ifdef __USE_BSD
+/* Bits in the file status flags returned by F_GETFL. */
+# define FREAD O_RDONLY
+# define FWRITE O_WRONLY
+
+/* Traditional BSD names the O_* bits. */
+# define FASYNC O_ASYNC
+# define FCREAT O_CREAT
+# define FEXCL O_EXCL
+# define FTRUNC O_TRUNC
+# define FNOCTTY O_NOCTTY
+# define FFSYNC O_FSYNC
+# define FSYNC O_SYNC
+# define FAPPEND O_APPEND
+# define FNONBLOCK O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif
+
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#if defined __USE_BSD || defined __USE_UNIX98
+# define F_GETOWN 5 /* Get owner (receiver of SIGIO). */
+# define F_SETOWN 6 /* Set owner (receiver of SIGIO). */
+#endif
+#define F_GETLK 7 /* Get record locking info. */
+#define F_SETLK 8 /* Set record locking info (non-blocking). */
+#define F_SETLKW 9 /* Set record locking info (blocking). */
+
+/* File descriptor flags used with F_GETFD and F_SETFD. */
+#define FD_CLOEXEC 1 /* Close on exec. */
+
+
+#include <bits/types.h>
+
+/* The structure describing an advisory lock. This is the type of the third
+ argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */
+struct flock
+ {
+ int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+#ifndef __USE_FILE_OFFSET64
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+#else
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+#endif
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+#endif
+
+/* Values for the `l_type' field of a `struct flock'. */
+#define F_RDLCK 1 /* Read lock. */
+#define F_WRLCK 2 /* Write lock. */
+#define F_UNLCK 3 /* Remove lock. */
+
+/* Advise to `posix_fadvise'. */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
+# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
+#endif
diff --git a/libc/sysdeps/mach/hurd/bits/ioctls.h b/libc/sysdeps/mach/hurd/bits/ioctls.h
new file mode 100644
index 000000000..06a73df75
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/bits/ioctls.h
@@ -0,0 +1,371 @@
+/* Copyright (C) 1992,93,96,97,98,99,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __BITS_IOCTLS_H
+#define __BITS_IOCTLS_H 1
+
+#if !defined _HURD_IOCTL_H && !defined _SYS_IOCTL_H
+# error "Never use <bits/ioctls.h> directly; include <hurd/ioctl.h> instead."
+#endif
+
+/* These macros are also defined in <bits/termios.h> (with numerically
+ identical values) but this serves to shut up cpp's complaining. */
+#ifdef MDMBUF
+# undef MDMBUF
+#endif
+#ifdef ECHO
+# undef ECHO
+#endif
+#ifdef TOSTOP
+# undef TOSTOP
+#endif
+#ifdef FLUSHO
+# undef FLUSHO
+#endif
+#ifdef PENDIN
+# undef PENDIN
+#endif
+#ifdef NOFLSH
+# undef NOFLSH
+#endif
+
+/* Hurd ioctl request are made up of several fields:
+
+ 10987654321098765432109876543210
+ IOt0t1t2cc0c0cc1c1cc2ggggccccccc
+
+ bits [31,30]: inout direction (enum __ioctl_dir)
+ bits [29,11]: type encoding as follows; zero count indicates omitted datum
+ [29,28]: datum #0 type (enum __ioctl_datum)
+ [27,26]: datum #1 type (enum __ioctl_datum)
+ [24,25]: datum #2 type (enum __ioctl_datum)
+ [23,19]: datum #0 count [0,31]
+ [18,14]: datum #1 count [0,31]
+ [13,11]: datum #2 count [0,3]
+ bits [07,10]: group (letter - 'f': ['f','v'])
+ bits [00,06]: command [0,127]
+
+ The following macros construct and dissect these fields. */
+
+enum __ioctl_dir
+ {
+ IOC_VOID = 0, /* No parameters. */
+ IOC_OUT = 1, /* Data is written into the user's buffer. */
+ IOC_IN = 2, /* Data is read from the user's buffer. */
+ IOC_INOUT = (IOC_IN|IOC_OUT)
+ };
+
+enum __ioctl_datum { IOC_8, IOC_16, IOC_32, IOC_64 };
+
+/* Construct an ioctl from constructed type plus other fields. */
+#define _IOC(inout, group, num, type) \
+ ((num) | ((((group) - 'f') | ((type) | (inout) << 19) << 4) << 7))
+
+/* Dissect an ioctl into its component fields. */
+#define _IOC_INOUT(request) (((unsigned int) (request) >> 30) & IOC_INOUT)
+#define _IOC_GROUP(request) ('f' + (((unsigned int) (request) >> 7) & 0xf))
+#define _IOC_COMMAND(request) ((unsigned int) (request) & 0x7f)
+#define _IOC_TYPE(request) (((unsigned int) (request) >> 11) & 0x7ffff)
+#define _IOC_NOTYPE(request) ((unsigned int) (request) & 0x3ff)
+
+/* Construct a type information field from
+ the broken-out type and count fields. */
+#define _IOT(t0, c0, t1, c1, t2, c2) \
+ ((c2) | (((c1) | ((c0) | ((t2) | ((t1) | (t0) << 2) << 2) << 5) << 5) << 3))
+
+/* Dissect a type information field into the type and count fields. */
+#define _IOT_TYPE0(type) (((unsigned int) (type) >> 17) & 3)
+#define _IOT_TYPE1(type) (((unsigned int) (type) >> 15) & 3)
+#define _IOT_TYPE2(type) (((unsigned int) (type) >> 13) & 3)
+#define _IOT_COUNT0(type) (((unsigned int) (type) >> 8) & 0x1f)
+#define _IOT_COUNT1(type) (((unsigned int) (type) >> 3) & 0x1f)
+#define _IOT_COUNT2(type) (((unsigned int) (type) >> 0) & 7)
+
+/* Construct an ioctl from all the broken-out fields. */
+#define _IOCT(inout, group, num, t0, c0, t1, c1, t2, c2) \
+ _IOC ((inout), (group), (num), _IOT ((t0), (c0), (t1), (c1), (t2), (c2)))
+
+/* Construct an individual type field for TYPE. */
+#define _IOTS(type) \
+ (sizeof (type) == 8 ? IOC_64 : (sizeof (type) >> 1))
+
+/* Construct a type information field for
+ a single argument of the scalar TYPE. */
+#define _IOT_SIMPLE(type) _IOT (_IOTS (type), 1, 0, 0, 0, 0)
+
+/* Basic C types. */
+#define _IOT__IOTBASE_int _IOT_SIMPLE (int)
+#define _IOT__IOTBASE_char _IOT_SIMPLE (char)
+#define _IOT__IOTBASE_short _IOT_SIMPLE (short)
+
+
+/* Standard flavors of ioctls.
+ _IOT_foobar is defined either in this file,
+ or where struct foobar is defined. */
+#define _IO(g, n) _IOC (IOC_VOID, (g), (n), 0)
+#define _IOR(g, n, t) _IOC (IOC_OUT, (g), (n), _IOC_ENCODE_TYPE (t))
+#define _IOW(g, n, t) _IOC (IOC_IN, (g), (n), _IOC_ENCODE_TYPE (t))
+#define _IOWR(g, n, t) _IOC (IOC_INOUT, (g), (n), _IOC_ENCODE_TYPE (t))
+
+/* These macros do some preprocessor gymnastics to turn a TYPESPEC of
+ `struct foobar' into the identifier `_IOT_foobar', which is generally
+ defined using `_IOT' (above) in whatever file defines `struct foobar'.
+ For a TYPESPEC that does not begin with `struct' produces a different
+ identifier: `int' produces `_IOT__IOTBASE_int'. These identifiers
+ are defined for the basic C types above. */
+#define _IOC_ENCODE_TYPE(typespec) _IOC_ENCODE_TYPE_1(_IOTBASE_##typespec)
+#define _IOTBASE_struct
+#define _IOC_ENCODE_TYPE_1(typespec) _IOC_ENCODE_TYPE_2(typespec)
+#define _IOC_ENCODE_TYPE_2(typespec) _IOT_##typespec
+
+
+/* ioctls verbatim from 4.4 <sys/ioctl.h>. */
+
+#define TIOCMODG _IOR('t', 3, int) /* get modem control state */
+#define TIOCMODS _IOW('t', 4, int) /* set modem control state */
+#define TIOCM_LE 0001 /* line enable */
+#define TIOCM_DTR 0002 /* data terminal ready */
+#define TIOCM_RTS 0004 /* request to send */
+#define TIOCM_ST 0010 /* secondary transmit */
+#define TIOCM_SR 0020 /* secondary receive */
+#define TIOCM_CTS 0040 /* clear to send */
+#define TIOCM_CAR 0100 /* carrier detect */
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RNG 0200 /* ring */
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_DSR 0400 /* data set ready */
+ /* 8-10 compat */
+#define TIOCEXCL _IO('t', 13) /* set exclusive use of tty */
+#define TIOCNXCL _IO('t', 14) /* reset exclusive use of tty */
+ /* 15 unused */
+#define TIOCFLUSH _IOW('t', 16, int) /* flush buffers */
+ /* 17-18 compat */
+#define TIOCGETA _IOR('t', 19, struct termios) /* get termios struct */
+#define TIOCSETA _IOW('t', 20, struct termios) /* set termios struct */
+#define TIOCSETAW _IOW('t', 21, struct termios) /* drain output, set */
+#define TIOCSETAF _IOW('t', 22, struct termios) /* drn out, fls in, set */
+#define TIOCGETD _IOR('t', 26, int) /* get line discipline */
+#define TIOCSETD _IOW('t', 27, int) /* set line discipline */
+ /* 127-124 compat */
+#define TIOCSBRK _IO('t', 123) /* set break bit */
+#define TIOCCBRK _IO('t', 122) /* clear break bit */
+#define TIOCSDTR _IO('t', 121) /* set data terminal ready */
+#define TIOCCDTR _IO('t', 120) /* clear data terminal ready */
+#define TIOCGPGRP _IOR('t', 119, int) /* get pgrp of tty */
+#define TIOCSPGRP _IOW('t', 118, int) /* set pgrp of tty */
+ /* 117-116 compat */
+#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
+#define TIOCSTI _IOW('t', 114, char) /* simulate terminal input */
+#define TIOCNOTTY _IO('t', 113) /* void tty association */
+#define TIOCPKT _IOW('t', 112, int) /* pty: set/clear packet mode */
+#define TIOCPKT_DATA 0x00 /* data packet */
+#define TIOCPKT_FLUSHREAD 0x01 /* flush packet */
+#define TIOCPKT_FLUSHWRITE 0x02 /* flush packet */
+#define TIOCPKT_STOP 0x04 /* stop output */
+#define TIOCPKT_START 0x08 /* start output */
+#define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */
+#define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */
+#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */
+#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
+#define TIOCSTART _IO('t', 110) /* start output, like ^Q */
+#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */
+#define TIOCMBIS _IOW('t', 108, int) /* bis modem bits */
+#define TIOCMBIC _IOW('t', 107, int) /* bic modem bits */
+#define TIOCMGET _IOR('t', 106, int) /* get all modem bits */
+#define TIOCREMOTE _IOW('t', 105, int) /* remote input editing */
+#define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */
+#define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */
+#define TIOCUCNTL _IOW('t', 102, int) /* pty: set/clr usr cntl mode */
+#define UIOCCMD(n) _IO('u', n) /* usr cntl op "n" */
+#define TIOCCONS _IOW('t', 98, int) /* become virtual console */
+#define TIOCSCTTY _IO('t', 97) /* become controlling tty */
+#define TIOCEXT _IOW('t', 96, int) /* pty: external processing */
+#define TIOCSIG _IO('t', 95) /* pty: generate signal */
+#define TIOCDRAIN _IO('t', 94) /* wait till output drained */
+
+#define TTYDISC 0 /* termios tty line discipline */
+#define TABLDISC 3 /* tablet discipline */
+#define SLIPDISC 4 /* serial IP discipline */
+
+
+#define FIOCLEX _IO('f', 1) /* set close on exec on fd */
+#define FIONCLEX _IO('f', 2) /* remove close on exec */
+#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */
+#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */
+#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */
+#define FIOSETOWN _IOW('f', 124, int) /* set owner */
+#define FIOGETOWN _IOR('f', 123, int) /* get owner */
+
+/* socket i/o controls */
+#define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */
+#define SIOCGHIWAT _IOR('s', 1, int) /* get high watermark */
+#define SIOCSLOWAT _IOW('s', 2, int) /* set low watermark */
+#define SIOCGLOWAT _IOR('s', 3, int) /* get low watermark */
+#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */
+#define SIOCSPGRP _IOW('s', 8, int) /* set process group */
+#define SIOCGPGRP _IOR('s', 9, int) /* get process group */
+
+#define SIOCADDRT _IOW('r', 10, struct ortentry) /* add route */
+#define SIOCDELRT _IOW('r', 11, struct ortentry) /* delete route */
+
+#define SIOCSIFADDR _IOW('i', 12, struct ifreq) /* set ifnet address */
+#define OSIOCGIFADDR _IOWR('i',13, struct ifreq) /* get ifnet address */
+#define SIOCGIFADDR _IOWR('i',33, struct ifreq) /* get ifnet address */
+#define SIOCGIFHWADDR _IOWR('i',39, struct ifreq) /* get hwaddress */
+#define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) /* set p-p address */
+#define OSIOCGIFDSTADDR _IOWR('i',15, struct ifreq) /* get p-p address */
+#define SIOCGIFDSTADDR _IOWR('i',34, struct ifreq) /* get p-p address */
+#define SIOCSIFFLAGS _IOW('i', 16, struct ifreq_short)/* set ifnet flags */
+#define SIOCGIFFLAGS _IOWR('i',17, struct ifreq_short)/* get ifnet flags */
+#define OSIOCGIFBRDADDR _IOWR('i',18, struct ifreq) /* get broadcast addr */
+#define SIOCGIFBRDADDR _IOWR('i',35, struct ifreq) /* get broadcast addr */
+#define SIOCSIFBRDADDR _IOW('i',19, struct ifreq) /* set broadcast addr */
+#define OSIOCGIFCONF _IOWR('i',20, struct ifconf) /* get ifnet list */
+#define SIOCGIFCONF _IOWR('i',36, struct ifconf) /* get ifnet list */
+#define OSIOCGIFNETMASK _IOWR('i',21, struct ifreq) /* get net addr mask */
+#define SIOCGIFNETMASK _IOWR('i',37, struct ifreq) /* get net addr mask */
+#define SIOCSIFNETMASK _IOW('i',22, struct ifreq) /* set net addr mask */
+#define SIOCGIFMETRIC _IOWR('i',23, struct ifreq_int) /* get IF metric */
+#define SIOCSIFMETRIC _IOW('i',24, struct ifreq_int) /* set IF metric */
+#define SIOCDIFADDR _IOW('i',25, struct ifreq) /* delete IF addr */
+#define SIOCAIFADDR _IOW('i',26, struct ifaliasreq) /* add/chg IF alias */
+
+#define SIOCSARP _IOW('i', 30, struct arpreq) /* set arp entry */
+#define OSIOCGARP _IOWR('i',31, struct arpreq) /* get arp entry */
+#define SIOCGARP _IOWR('i',38, struct arpreq) /* get arp entry */
+#define SIOCDARP _IOW('i', 32, struct arpreq) /* delete arp entry */
+
+#define SIOCGIFMTU _IOWR('i', 51, struct ifreq_int)/* get IF mtu */
+#define SIOCSIFMTU _IOW('i', 52, struct ifreq_int) /* set IF mtu */
+
+#define SIOCGIFINDEX _IOWR('i', 90, struct ifreq_int)/* get IF index */
+#define SIOCGIFNAME _IOWR('i', 91, struct ifreq_int)/* set IF name */
+
+
+/* Compatibility with 4.3 BSD terminal driver.
+ From 4.4 <sys/ioctl_compat.h>. */
+
+#ifdef USE_OLD_TTY
+# undef TIOCGETD
+# define TIOCGETD _IOR('t', 0, int) /* get line discipline */
+# undef TIOCSETD
+# define TIOCSETD _IOW('t', 1, int) /* set line discipline */
+#else
+# define OTIOCGETD _IOR('t', 0, int) /* get line discipline */
+# define OTIOCSETD _IOW('t', 1, int) /* set line discipline */
+#endif
+#define TIOCHPCL _IO('t', 2) /* hang up on last close */
+#define TIOCGETP _IOR('t', 8,struct sgttyb)/* get parameters -- gtty */
+#define TIOCSETP _IOW('t', 9,struct sgttyb)/* set parameters -- stty */
+#define TIOCSETN _IOW('t',10,struct sgttyb)/* as above, but no flushtty*/
+#define TIOCSETC _IOW('t',17,struct tchars)/* set special characters */
+#define TIOCGETC _IOR('t',18,struct tchars)/* get special characters */
+#define TANDEM 0x00000001 /* send stopc on out q full */
+#define CBREAK 0x00000002 /* half-cooked mode */
+#define LCASE 0x00000004 /* simulate lower case */
+#define ECHO 0x00000008 /* echo input */
+#define CRMOD 0x00000010 /* map \r to \r\n on output */
+#define RAW 0x00000020 /* no i/o processing */
+#define ODDP 0x00000040 /* get/send odd parity */
+#define EVENP 0x00000080 /* get/send even parity */
+#define ANYP 0x000000c0 /* get any parity/send none */
+#define NLDELAY 0x00000300 /* \n delay */
+#define NL0 0x00000000
+#define NL1 0x00000100 /* tty 37 */
+#define NL2 0x00000200 /* vt05 */
+#define NL3 0x00000300
+#define TBDELAY 0x00000c00 /* horizontal tab delay */
+#define TAB0 0x00000000
+#define TAB1 0x00000400 /* tty 37 */
+#define TAB2 0x00000800
+#define XTABS 0x00000c00 /* expand tabs on output */
+#define CRDELAY 0x00003000 /* \r delay */
+#define CR0 0x00000000
+#define CR1 0x00001000 /* tn 300 */
+#define CR2 0x00002000 /* tty 37 */
+#define CR3 0x00003000 /* concept 100 */
+#define VTDELAY 0x00004000 /* vertical tab delay */
+#define FF0 0x00000000
+#define FF1 0x00004000 /* tty 37 */
+#define BSDELAY 0x00008000 /* \b delay */
+#define BS0 0x00000000
+#define BS1 0x00008000
+#define ALLDELAY (NLDELAY|TBDELAY|CRDELAY|VTDELAY|BSDELAY)
+#define CRTBS 0x00010000 /* do backspacing for crt */
+#define PRTERA 0x00020000 /* \ ... / erase */
+#define CRTERA 0x00040000 /* " \b " to wipe out char */
+#define TILDE 0x00080000 /* hazeltine tilde kludge */
+#define MDMBUF 0x00100000 /*start/stop output on carrier*/
+#define LITOUT 0x00200000 /* literal output */
+#define TOSTOP 0x00400000 /*SIGSTOP on background output*/
+#define FLUSHO 0x00800000 /* flush output to terminal */
+#define NOHANG 0x01000000 /* (no-op) was no SIGHUP on carrier drop */
+#define L001000 0x02000000
+#define CRTKIL 0x04000000 /* kill line with " \b " */
+#define PASS8 0x08000000
+#define CTLECH 0x10000000 /* echo control chars as ^X */
+#define PENDIN 0x20000000 /* tp->t_rawq needs reread */
+#define DECCTQ 0x40000000 /* only ^Q starts after ^S */
+#define NOFLSH 0x80000000 /* no output flush on signal */
+#define TIOCLBIS _IOW('t', 127, int) /* bis local mode bits */
+#define TIOCLBIC _IOW('t', 126, int) /* bic local mode bits */
+#define TIOCLSET _IOW('t', 125, int) /* set entire local mode word */
+#define TIOCLGET _IOR('t', 124, int) /* get local modes */
+#define LCRTBS (CRTBS>>16)
+#define LPRTERA (PRTERA>>16)
+#define LCRTERA (CRTERA>>16)
+#define LTILDE (TILDE>>16)
+#define LMDMBUF (MDMBUF>>16)
+#define LLITOUT (LITOUT>>16)
+#define LTOSTOP (TOSTOP>>16)
+#define LFLUSHO (FLUSHO>>16)
+#define LNOHANG (NOHANG>>16)
+#define LCRTKIL (CRTKIL>>16)
+#define LPASS8 (PASS8>>16)
+#define LCTLECH (CTLECH>>16)
+#define LPENDIN (PENDIN>>16)
+#define LDECCTQ (DECCTQ>>16)
+#define LNOFLSH (NOFLSH>>16)
+#define TIOCSLTC _IOW('t',117,struct ltchars)/* set local special chars*/
+#define TIOCGLTC _IOR('t',116,struct ltchars)/* get local special chars*/
+#define OTIOCCONS _IO('t', 98) /* for hp300 -- sans int arg */
+#define OTTYDISC 0
+#define NETLDISC 1
+#define NTTYDISC 2
+
+/* From 4.4 <sys/ttydev.h>. */
+#ifdef USE_OLD_TTY
+# define B0 0
+# define B50 1
+# define B75 2
+# define B110 3
+# define B134 4
+# define B150 5
+# define B200 6
+# define B300 7
+# define B600 8
+# define B1200 9
+# define B1800 10
+# define B2400 11
+# define B4800 12
+# define B9600 13
+# define EXTA 14
+# define EXTB 15
+#endif /* USE_OLD_TTY */
+
+#endif /* bits/ioctls.h */
diff --git a/libc/sysdeps/mach/hurd/bits/libc-lock.h b/libc/sysdeps/mach/hurd/bits/libc-lock.h
new file mode 100644
index 000000000..0fa90bcc3
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/bits/libc-lock.h
@@ -0,0 +1,203 @@
+/* libc-internal interface for mutex locks. Hurd version using Mach cthreads.
+ Copyright (C) 1996,97,98,2000,01, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_LIBC_LOCK_H
+#define _BITS_LIBC_LOCK_H 1
+
+#if (_LIBC - 0) || (_CTHREADS_ - 0)
+#include <cthreads.h>
+#include <hurd/threadvar.h>
+
+typedef struct mutex __libc_lock_t;
+typedef struct
+{
+ struct mutex mutex;
+ void *owner;
+ int count;
+} __libc_lock_recursive_t;
+
+#define __libc_lock_owner_self() ((void *) __hurd_threadvar_location (0))
+
+#else
+typedef struct __libc_lock_opaque__ __libc_lock_t;
+typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
+#endif
+
+/* Define a lock variable NAME with storage class CLASS. The lock must be
+ initialized with __libc_lock_init before it can be used (or define it
+ with __libc_lock_define_initialized, below). Use `extern' for CLASS to
+ declare a lock defined in another module. In public structure
+ definitions you must use a pointer to the lock structure (i.e., NAME
+ begins with a `*'), because its storage size will not be known outside
+ of libc. */
+#define __libc_lock_define(CLASS,NAME) \
+ CLASS __libc_lock_t NAME;
+
+/* Define an initialized lock variable NAME with storage class CLASS. */
+#define __libc_lock_define_initialized(CLASS,NAME) \
+ CLASS __libc_lock_t NAME = MUTEX_INITIALIZER;
+
+/* Initialize the named lock variable, leaving it in a consistent, unlocked
+ state. */
+#define __libc_lock_init(NAME) __mutex_init (&(NAME))
+
+/* Finalize the named lock variable, which must be locked. It cannot be
+ used again until __libc_lock_init is called again on it. This must be
+ called on a lock variable before the containing storage is reused. */
+#define __libc_lock_fini(NAME) __mutex_unlock (&(NAME))
+#define __libc_lock_fini_recursive(NAME) __mutex_unlock (&(NAME).mutex)
+#define __rtld_lock_fini_recursive(NAME) __mutex_unlock (&(NAME).mutex)
+
+
+/* Lock the named lock variable. */
+#define __libc_lock_lock(NAME) __mutex_lock (&(NAME))
+
+/* Lock the named lock variable. */
+#define __libc_lock_trylock(NAME) (!__mutex_trylock (&(NAME)))
+
+/* Unlock the named lock variable. */
+#define __libc_lock_unlock(NAME) __mutex_unlock (&(NAME))
+
+
+#define __libc_lock_define_recursive(CLASS,NAME) \
+ CLASS __libc_lock_recursive_t NAME;
+#define _LIBC_LOCK_RECURSIVE_INITIALIZER { MUTEX_INITIALIZER, 0, 0 }
+#define __libc_lock_define_initialized_recursive(CLASS,NAME) \
+ CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER;
+
+#define __rtld_lock_define_recursive(CLASS,NAME) \
+ __libc_lock_define_recursive (CLASS, NAME)
+#define _RTLD_LOCK_RECURSIVE_INITIALIZER \
+ _LIBC_LOCK_RECURSIVE_INITIALIZER
+#define __rtld_lock_define_initialized_recursive(CLASS,NAME) \
+ __libc_lock_define_initialized_recursive (CLASS, NAME)
+
+#define __libc_lock_init_recursive(NAME) \
+ ({ __libc_lock_recursive_t *const __lock = &(NAME); \
+ __lock->owner = 0; mutex_init (&__lock->mutex); })
+
+#define __libc_lock_trylock_recursive(NAME) \
+ ({ __libc_lock_recursive_t *const __lock = &(NAME); \
+ void *__self = __libc_lock_owner_self (); \
+ __mutex_trylock (&__lock->mutex) \
+ ? (__lock->owner = __self, __lock->count = 1, 0) \
+ : __lock->owner == __self ? (++__lock->count, 0) : 1; })
+
+#define __libc_lock_lock_recursive(NAME) \
+ ({ __libc_lock_recursive_t *const __lock = &(NAME); \
+ void *__self = __libc_lock_owner_self (); \
+ if (__mutex_trylock (&__lock->mutex) \
+ || (__lock->owner != __self \
+ && (__mutex_lock (&__lock->mutex), 1))) \
+ __lock->owner = __self, __lock->count = 1; \
+ else \
+ ++__lock->count; \
+ })
+#define __libc_lock_unlock_recursive(NAME) \
+ ({ __libc_lock_recursive_t *const __lock = &(NAME); \
+ if (--__lock->count == 0) \
+ { \
+ __lock->owner = 0; \
+ __mutex_unlock (&__lock->mutex); \
+ } \
+ })
+
+
+#define __rtld_lock_init_recursive(NAME) \
+ __libc_lock_init_recursive (NAME)
+#define __rtld_lock_trylock_recursive(NAME) \
+ __libc_lock_trylock_recursive (NAME)
+#define __rtld_lock_lock_recursive(NAME) \
+ __libc_lock_lock_recursive(NAME)
+#define __rtld_lock_unlock_recursive(NAME) \
+ __libc_lock_unlock_recursive (NAME)
+
+
+/* XXX for now */
+#define __libc_rwlock_define __libc_lock_define
+#define __libc_rwlock_define_initialized __libc_lock_define_initialized
+#define __libc_rwlock_init __libc_lock_init
+#define __libc_rwlock_fini __libc_lock_fini
+#define __libc_rwlock_rdlock __libc_lock_lock
+#define __libc_rwlock_wrlock __libc_lock_lock
+#define __libc_rwlock_tryrdlock __libc_lock_trylock
+#define __libc_rwlock_trywrlock __libc_lock_trylock
+#define __libc_rwlock_unlock __libc_lock_unlock
+
+
+/* Start a critical region with a cleanup function */
+#define __libc_cleanup_region_start(DOIT, FCT, ARG) \
+{ \
+ typeof (***(FCT)) *__save_FCT = (DOIT) ? (FCT) : 0; \
+ typeof (ARG) __save_ARG = ARG; \
+ /* close brace is in __libc_cleanup_region_end below. */
+
+/* End a critical region started with __libc_cleanup_region_start. */
+#define __libc_cleanup_region_end(DOIT) \
+ if ((DOIT) && __save_FCT != 0) \
+ (*__save_FCT)(__save_ARG); \
+}
+
+/* Sometimes we have to exit the block in the middle. */
+#define __libc_cleanup_end(DOIT) \
+ if ((DOIT) && __save_FCT != 0) \
+ (*__save_FCT)(__save_ARG); \
+
+#define __libc_cleanup_push(fct, arg) __libc_cleanup_region_start (1, fct, arg)
+#define __libc_cleanup_pop(execute) __libc_cleanup_region_end (execute)
+
+#if (_CTHREADS_ - 0)
+
+/* Use mutexes as once control variables. */
+
+struct __libc_once
+ {
+ __libc_lock_t lock;
+ int done;
+ };
+
+#define __libc_once_define(CLASS,NAME) \
+ CLASS struct __libc_once NAME = { MUTEX_INITIALIZER, 0 }
+
+/* Call handler iff the first call. */
+#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
+ do { \
+ __libc_lock_lock (ONCE_CONTROL.lock); \
+ if (!ONCE_CONTROL.done) \
+ (INIT_FUNCTION) (); \
+ ONCE_CONTROL.done = 1; \
+ __libc_lock_unlock (ONCE_CONTROL.lock); \
+ } while (0)
+
+#ifdef _LIBC
+/* We need portable names for some functions. E.g., when they are
+ used as argument to __libc_cleanup_region_start. */
+#define __libc_mutex_unlock __mutex_unlock
+#endif
+
+/* Type for key of thread specific data. */
+typedef cthread_key_t __libc_key_t;
+
+#define __libc_key_create(KEY,DEST) cthread_keycreate (KEY)
+#define __libc_setspecific(KEY,VAL) cthread_setspecific (KEY, VAL)
+void *__libc_getspecific (__libc_key_t key);
+
+#endif /* _CTHREADS_ */
+
+#endif /* bits/libc-lock.h */
diff --git a/libc/sysdeps/mach/hurd/bits/libc-tsd.h b/libc/sysdeps/mach/hurd/bits/libc-tsd.h
new file mode 100644
index 000000000..56393e930
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/bits/libc-tsd.h
@@ -0,0 +1,34 @@
+/* libc-internal interface for thread-specific data. Hurd version.
+ Copyright (C) 1998,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_LIBC_TSD_H
+#define _BITS_LIBC_TSD_H 1
+
+#include <hurd/threadvar.h>
+
+#define __libc_tsd_define(CLASS, KEY) /* nothing, always have threadvars */
+
+#define __libc_tsd_address(KEY) \
+ ((void **) __hurd_threadvar_location (_HURD_THREADVAR_##KEY))
+
+#define __libc_tsd_get(KEY) (*__libc_tsd_address (KEY))
+#define __libc_tsd_set(KEY, VALUE) (*__libc_tsd_address (KEY) = (VALUE))
+
+
+#endif /* bits/libc-tsd.h */
diff --git a/libc/sysdeps/mach/hurd/bits/local_lim.h b/libc/sysdeps/mach/hurd/bits/local_lim.h
new file mode 100644
index 000000000..51a2791b1
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/bits/local_lim.h
@@ -0,0 +1,46 @@
+/* Minimum guaranteed maximum values for system limits. Hurd version.
+ Copyright (C) 1993,94,96,98,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* GNU has no arbitrary fixed limits on most of these things, so we
+ don't define the macros. Some things are unlimited. Some are in
+ fact limited but the limit is run-time dependent and fetched with
+ `sysconf' or `pathconf'. */
+
+/* This one value is actually constrained by the `struct dirent'
+ layout, in which the `d_namlen' member is only 8 bits wide. */
+
+#define NAME_MAX 255
+
+/* POSIX.1 requires that we define NGROUPS_MAX (though none of the others
+ is required). GNU allows any number of supplementary groups,
+ dynamically allocated. So we pick a number which seems vaguely
+ suitable, and `sysconf' will return a number at least as large. */
+
+#define NGROUPS_MAX 256
+
+/* The maximum number of symbolic links that are allowed in a single file
+ name resolution. When a further link is encountered, the call returns
+ ELOOP. This name is a GNU extension; POSIX.1 has no such limit, and BSD
+ calls it MAXSYMLINKS in <sys/param.h>. (We define the name under
+ _BSD_SOURCE even without _GNU_SOURCE because our <sys/param.h> uses it
+ to define MAXSYMLINKS.) */
+
+#if defined __USE_GNU || defined __USE_BSD /* 1003.1a defines this */
+#define SYMLOOP_MAX 8
+#endif
diff --git a/libc/sysdeps/mach/hurd/bits/posix_opt.h b/libc/sysdeps/mach/hurd/bits/posix_opt.h
new file mode 100644
index 000000000..6747bc276
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/bits/posix_opt.h
@@ -0,0 +1,165 @@
+/* Define POSIX options for GNU/Hurd.
+ Copyright (C) 1998,2000,2001,2002,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _UNISTD_H
+#error "Never include this file directly; use <unistd.h> instead."
+#endif
+
+#ifndef _BITS_POSIX_OPT_H
+#define _BITS_POSIX_OPT_H 1
+
+
+/* Job control is supported. */
+#define _POSIX_JOB_CONTROL 1
+
+/* Processes have a saved set-user-ID and a saved set-group-ID. */
+#define _POSIX_SAVED_IDS 1
+
+/* Synchronizing file data is supported, but msync is missing. */
+#undef _POSIX_SYNCHRONIZED_IO
+
+/* The fsync function is present. */
+#define _POSIX_FSYNC 200112L
+
+/* Mapping of files to memory is supported. */
+#define _POSIX_MAPPED_FILES 200112L
+
+/* Locking of all memory could be supported in future. */
+#define _POSIX_MEMLOCK 0
+
+/* Locking of ranges of memory is supported. */
+#define _POSIX_MEMLOCK_RANGE 200112L
+
+/* Setting of memory protections is supported. */
+#define _POSIX_MEMORY_PROTECTION 200112L
+
+/* Elements of the `c_cc' member of `struct termios' structure
+ can be disabled by using the value _POSIX_VDISABLE. */
+#define _POSIX_VDISABLE ((unsigned char) -1)
+
+
+/* Different Hurd filesystems might do these differently.
+ You must query the particular file with `pathconf' or `fpathconf'. */
+#undef _POSIX_CHOWN_RESTRICTED /* Only root can change owner of file? */
+#undef _POSIX_NO_TRUNC /* Overlong file names get error? */
+#undef _POSIX_SYNC_IO /* File supports O_SYNC et al? */
+
+
+/* We do not have the POSIX threads interface. */
+#define _POSIX_THREADS -1
+
+/* We have the reentrant functions described in POSIX. */
+#define _POSIX_REENTRANT_FUNCTIONS 1
+#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
+
+/* These are all things that won't be supported when _POSIX_THREADS is not. */
+#define _POSIX_THREAD_PRIORITY_SCHEDULING -1
+#define _POSIX_THREAD_ATTR_STACKSIZE -1
+#define _POSIX_THREAD_ATTR_STACKADDR -1
+#define _POSIX_SEMAPHORES -1
+
+/* Real-time signals are not yet supported. */
+#define _POSIX_REALTIME_SIGNALS -1
+
+/* Asynchronous I/O might supported with the existing ABI. */
+#define _POSIX_ASYNCHRONOUS_IO 0
+/* Alternative name for Unix98. */
+#define _LFS_ASYNCHRONOUS_IO _POSIX_ASYNCHRONOUS_IO
+
+/* The LFS support in asynchronous I/O is also available. */
+#define _LFS64_ASYNCHRONOUS_IO _POSIX_ASYNCHRONOUS_IO
+
+/* The rest of the LFS is also available. */
+#define _LFS_LARGEFILE 1
+#define _LFS64_LARGEFILE 1
+#define _LFS64_STDIO 1
+
+/* POSIX.4 shared memory objects are supported (using regular files). */
+#define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_MAPPED_FILES
+
+/* CPU-time clocks support needs to be checked at runtime. */
+#define _POSIX_CPUTIME 0
+
+/* Clock support in threads must be also checked at runtime. */
+#define _POSIX_THREAD_CPUTIME 0
+
+/* GNU libc provides regular expression handling. */
+#define _POSIX_REGEXP 1
+
+/* Reader/Writer locks are not available. */
+#define _POSIX_READER_WRITER_LOCKS -1
+
+/* We have a POSIX shell. */
+#define _POSIX_SHELL 1
+
+/* We cannot support the Timeouts option without _POSIX_THREADS. */
+#define _POSIX_TIMEOUTS -1
+
+/* The `spawn' function family is supported. */
+#define _POSIX_SPAWN 200112L
+
+/* We do not have POSIX timers, but could in future without ABI change. */
+#define _POSIX_TIMERS 0
+
+/* The barrier functions are not available. */
+#define _POSIX_BARRIERS -1
+
+/* POSIX message queues could be available in future. */
+#define _POSIX_MESSAGE_PASSING 0
+
+/* Thread process-shared synchronization is not supported. */
+#define _POSIX_THREAD_PROCESS_SHARED -1
+
+/* The monotonic clock might be available. */
+#define _POSIX_MONOTONIC_CLOCK 0
+
+/* The clock selection interfaces are available. */
+#define _POSIX_CLOCK_SELECTION 200112L
+
+/* Advisory information interfaces could be available in future. */
+#define _POSIX_ADVISORY_INFO 0
+
+/* IPv6 support is available. */
+#define _POSIX_IPV6 200112L
+
+/* Raw socket support is available. */
+#define _POSIX_RAW_SOCKETS 200112L
+
+/* We have at least one terminal. */
+#define _POSIX2_CHAR_TERM 200112L
+
+/* Neither process nor thread sporadic server interfaces is available. */
+#define _POSIX_SPORADIC_SERVER -1
+#define _POSIX_THREAD_SPORADIC_SERVER -1
+
+/* trace.h is not available. */
+#define _POSIX_TRACE -1
+#define _POSIX_TRACE_EVENT_FILTER -1
+#define _POSIX_TRACE_INHERIT -1
+#define _POSIX_TRACE_LOG -1
+
+/* Typed memory objects are not available. */
+#define _POSIX_TYPED_MEMORY_OBJECTS -1
+
+/* No support for priority inheritance or protection so far. */
+#define _POSIX_THREAD_PRIO_INHERIT -1
+#define _POSIX_THREAD_PRIO_PROTECT -1
+
+
+#endif /* bits/posix_opt.h */
diff --git a/libc/sysdeps/mach/hurd/bits/stat.h b/libc/sysdeps/mach/hurd/bits/stat.h
new file mode 100644
index 000000000..c3f96660c
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/bits/stat.h
@@ -0,0 +1,196 @@
+/* Copyright (C) 1992,93,94,96,97,99,2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* NOTE: The size of this structure (32 ints) is known in
+ <hurd/hurd_types.defs>, since it is used in the `io_stat' RPC. MiG
+ does not cope at all well with the passed C structure not being of
+ the expected size. There are some filler words at the end to allow
+ for future expansion. To increase the size of the structure used
+ in the RPC and retain binary compatibility, we would need to assign
+ a new message number. */
+
+struct stat
+ {
+ int st_fstype; /* File system type. */
+ __fsid_t st_fsid; /* File system ID. */
+#define st_dev st_fsid
+
+#ifndef __USE_FILE_OFFSET64
+ __ino_t st_ino; /* File number. */
+#else
+ __ino64_t st_ino; /* File number. */
+#endif
+ unsigned int st_gen; /* To detect reuse of file numbers. */
+ __dev_t st_rdev; /* Device if special file. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Number of links. */
+
+ __uid_t st_uid; /* Owner. */
+ __gid_t st_gid; /* Owning group. */
+
+#ifndef __USE_FILE_OFFSET64
+ __off_t st_size; /* Size in bytes. */
+#else
+ __off64_t st_size; /* Size in bytes. */
+#endif
+
+ __time_t st_atime; /* Access time, seconds */
+ unsigned long int st_atime_usec; /* and microseconds. */
+ __time_t st_mtime; /* Modification time, seconds */
+ unsigned long int st_mtime_usec; /* and microseconds. */
+ __time_t st_ctime; /* Status change time, seconds */
+ unsigned long int st_ctime_usec; /* and microseconds. */
+
+ __blksize_t st_blksize; /* Optimal size for I/O. */
+
+#ifndef __USE_FILE_OFFSET64
+ __blkcnt_t st_blocks; /* Number of 512-byte blocks allocated.
+ Not related to `st_blksize'. */
+#else
+ __blkcnt64_t st_blocks; /* Number of 512-byte blocks allocated.
+ Not related to `st_blksize'. */
+#endif
+
+ __uid_t st_author; /* File author. */
+
+ unsigned int st_flags; /* User-defined flags.
+ High 16 bits can be set only by root. */
+
+#ifndef __USE_FILE_OFFSET64
+# define _SPARE_SIZE ((sizeof (__fsid_t) == sizeof (int)) ? 12 : 11)
+#else
+# define _SPARE_SIZE ((sizeof (__fsid_t) == sizeof (int)) ? 9 : 8)
+#endif
+ int st_spare[_SPARE_SIZE]; /* Room for future expansion. */
+#undef _SPARE_SIZE
+ };
+
+#ifdef __USE_LARGEFILE64
+struct stat64
+ {
+ int st_fstype; /* File system type. */
+ __fsid_t st_fsid; /* File system ID. */
+# define st_dev st_fsid
+
+ __ino64_t st_ino; /* File number. */
+ unsigned int st_gen; /* To detect reuse of file numbers. */
+ __dev_t st_rdev; /* Device if special file. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Number of links. */
+
+ __uid_t st_uid; /* Owner. */
+ __gid_t st_gid; /* Owning group. */
+
+ __off64_t st_size; /* Size in bytes. */
+
+ __time_t st_atime; /* Access time, seconds */
+ unsigned long int st_atime_usec; /* and microseconds. */
+ __time_t st_mtime; /* Modification time, seconds */
+ unsigned long int st_mtime_usec; /* and microseconds. */
+ __time_t st_ctime; /* Status change time, seconds */
+ unsigned long int st_ctime_usec; /* and microseconds. */
+
+ __blksize_t st_blksize; /* Optimal size for I/O. */
+
+ __blkcnt64_t st_blocks; /* Number of 512-byte blocks allocated.
+ Not related to `st_blksize'. */
+
+ __uid_t st_author; /* File author. */
+
+ unsigned int st_flags; /* User-defined flags.
+ High 16 bits can be set only by root. */
+
+#define _SPARE_SIZE ((sizeof (__fsid_t) == sizeof (int)) ? 9 : 8)
+ int st_spare[_SPARE_SIZE]; /* Room for future expansion. */
+#undef _SPARE_SIZE
+ };
+#endif
+
+#define _STATBUF_ST_BLKSIZE /* Tell code we have this member. */
+
+/* Encoding of the file mode. */
+
+#define __S_IFMT 0170000 /* These bits determine file type. */
+
+/* File types. */
+#define __S_IFDIR 0040000 /* Directory. */
+#define __S_IFCHR 0020000 /* Character device. */
+#define __S_IFBLK 0060000 /* Block device. */
+#define __S_IFREG 0100000 /* Regular file. */
+#define __S_IFLNK 0120000 /* Symbolic link. */
+#define __S_IFSOCK 0140000 /* Socket. */
+#define __S_IFIFO 0010000 /* FIFO. */
+
+/* POSIX.1b objects. */
+#define __S_TYPEISMQ(buf) (0)
+#define __S_TYPEISSEM(buf) (0)
+#define __S_TYPEISSHM(buf) (0)
+
+/* Protection bits. */
+
+#define __S_ISUID 04000 /* Set user ID on execution. */
+#define __S_ISGID 02000 /* Set group ID on execution. */
+#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
+#define __S_IREAD 00400 /* Read by owner. */
+#define __S_IWRITE 00200 /* Write by owner. */
+#define __S_IEXEC 00100 /* Execute by owner. */
+
+
+#ifdef __USE_GNU
+/* If set, there is no benefit in caching the contents of this file. */
+#define S_INOCACHE 000000200000
+
+/* If the S_IUSEUNK bit is set, then the S_IUNKNOWN bits (see below)
+ control access for unknown users. If S_IUSEUNK is clear, then unknown
+ users are treated as "others" for purposes of access control. */
+#define S_IUSEUNK 000000400000
+/* Mask of protection bits for unknown users (no effective IDs at all). */
+#define S_IUNKNOWN 000007000000
+/* Shift S_IREAD, S_IWRITE, S_IEXEC left this many bits to produce the
+ protection bits for unknown users. */
+#define S_IUNKSHIFT 12
+
+/* Read only bits: */
+
+/* There is a passive translator set for this file */
+#define S_IPTRANS 000010000000
+/* There is an active translator running on this file */
+#define S_IATRANS 000020000000
+/* This is the root of a filesystem (or single node translator) */
+#define S_IROOT 000040000000
+/* All the bits relevant to translators */
+#define S_ITRANS 000070000000
+
+/* Definitely no mmaps to this. */
+#define S_IMMAP0 000100000000
+
+/* ALL the unused bits. */
+#define S_ISPARE (~(S_IFMT|S_ITRANS|S_INOCACHE|S_IMMAP0| \
+ S_IUSEUNK|S_IUNKNOWN|07777))
+#endif
+
+/* Default file creation mask (umask). */
+#ifdef __USE_BSD
+#define CMASK 0022
+#endif
diff --git a/libc/sysdeps/mach/hurd/bits/statfs.h b/libc/sysdeps/mach/hurd/bits/statfs.h
new file mode 100644
index 000000000..9183f98c8
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/bits/statfs.h
@@ -0,0 +1,87 @@
+/* Definition of `struct statfs', information about a filesystem.
+ Copyright (C) 1996, 97, 98, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STATFS_H
+# error "Never include <bits/statfs.h> directly; use <sys/statfs.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* GNU Hurd NOTE: The size of this structure (16 ints) is known in
+ <hurd/hurd_types.defs>, since it is used in the `file_statfs' RPC. MiG
+ does not cope at all well with the passed C structure not being of the
+ expected size. There are some filler words at the end to allow for
+ future expansion. To increase the size of the structure used in the RPC
+ and retain binary compatibility, we would need to assign a new message
+ number.
+
+ Note also that `struct statvfs' in <bits/statvfs.h> is laid out
+ identically to `struct statfs', so they can be used interchangeably.
+ Any changes made here must also be made in that file. */
+
+struct statfs
+ {
+ unsigned int f_type;
+ unsigned int f_bsize;
+#ifndef __USE_FILE_OFFSET64
+ __fsblkcnt_t f_blocks;
+ __fsblkcnt_t f_bfree;
+ __fsblkcnt_t f_bavail;
+ __fsblkcnt_t f_files;
+ __fsblkcnt_t f_ffree;
+#else
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsblkcnt64_t f_files;
+ __fsblkcnt64_t f_ffree;
+#endif
+ __fsid_t f_fsid;
+ unsigned int f_namelen;
+#ifndef __USE_FILE_OFFSET64
+ __fsfilcnt_t f_favail;
+#else
+ __fsfilcnt64_t f_favail;
+#endif
+ unsigned int f_frsize;
+ unsigned int f_flag;
+ unsigned int f_spare[3];
+ };
+
+#ifdef __USE_LARGEFILE64
+struct statfs64
+ {
+ unsigned int f_type;
+ unsigned int f_bsize;
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsblkcnt64_t f_files;
+ __fsblkcnt64_t f_ffree;
+ __fsid_t f_fsid;
+ unsigned int f_namelen;
+ __fsfilcnt64_t f_favail;
+ unsigned int f_frsize;
+ unsigned int f_flag;
+ unsigned int f_spare[3];
+ };
+#endif
+
+/* Tell code we have this member. */
+#define _STATFS_F_NAMELEN
diff --git a/libc/sysdeps/mach/hurd/bits/statvfs.h b/libc/sysdeps/mach/hurd/bits/statvfs.h
new file mode 100644
index 000000000..bbaf59a72
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/bits/statvfs.h
@@ -0,0 +1,94 @@
+/* Definition of `struct statvfs', information about a filesystem.
+ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STATVFS_H
+# error "Never include <bits/statvfs.h> directly; use <sys/statvfs.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* GNU Hurd NOTE: This structure is carefully laid out such that we
+ can use the `file_statfs' RPC to implement `statvfs' and
+ `fstatvfs'. Please keep this file in sync with <bits/statfs.h>,
+ and pay attention to the note in that file. */
+
+struct statvfs
+ {
+ unsigned int __f_type;
+ unsigned int f_bsize;
+#ifndef __USE_FILE_OFFSET64
+ __fsblkcnt_t f_blocks;
+ __fsblkcnt_t f_bfree;
+ __fsblkcnt_t f_bavail;
+ __fsfilcnt_t f_files;
+ __fsfilcnt_t f_ffree;
+#else
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsfilcnt64_t f_files;
+ __fsfilcnt64_t f_ffree;
+#endif
+ __fsid_t f_fsid;
+ unsigned int f_namemax; /* NOTE: f_namelen in `struct statfs'. */
+#ifndef __USE_FILE_OFFSET64
+ __fsfilcnt_t f_favail;
+#else
+ __fsfilcnt64_t f_favail;
+#endif
+ unsigned int f_frsize;
+ unsigned int f_flag;
+ unsigned int f_spare[3];
+ };
+
+#ifdef __USE_LARGEFILE64
+struct statvfs64
+ {
+ unsigned int __f_type;
+ unsigned int f_bsize;
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsfilcnt64_t f_files;
+ __fsfilcnt64_t f_ffree;
+ __fsid_t f_fsid;
+ unsigned int f_namemax;
+ __fsfilcnt64_t f_favail;
+ unsigned int f_frsize;
+ unsigned int f_flag;
+ unsigned int f_spare[3];
+ };
+#endif
+
+/* Definitions for the flag in `f_flag'.
+ The values for the non-standard flags come from Linux. */
+enum
+{
+ ST_RDONLY = 1,
+#define ST_RDONLY ST_RDONLY
+ ST_NOSUID = 2
+#define ST_NOSUID ST_NOSUID
+#ifdef __USE_GNU
+ ,
+ ST_NOEXEC = 8,
+# define ST_NOEXEC ST_NOEXEC
+ ST_SYNCHRONOUS = 16
+# define ST_SYNCHRONOUS ST_SYNCHRONOUS
+#endif
+};
diff --git a/libc/sysdeps/mach/hurd/bits/typesizes.h b/libc/sysdeps/mach/hurd/bits/typesizes.h
new file mode 100644
index 000000000..4322617a9
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/bits/typesizes.h
@@ -0,0 +1,66 @@
+/* bits/typesizes.h -- underlying types for *_t. Hurd version.
+ Copyright (C) 2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_TYPES_H
+# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef _BITS_TYPESIZES_H
+#define _BITS_TYPESIZES_H 1
+
+/* See <bits/types.h> for the meaning of these macros. This file exists so
+ that <bits/types.h> need not vary across different GNU platforms. */
+
+#define __DEV_T_TYPE __U32_TYPE
+#define __UID_T_TYPE __U32_TYPE
+#define __GID_T_TYPE __U32_TYPE
+#define __INO_T_TYPE __ULONGWORD_TYPE
+#define __INO64_T_TYPE __UQUAD_TYPE
+#define __MODE_T_TYPE __U32_TYPE
+#define __NLINK_T_TYPE __UWORD_TYPE
+#define __OFF_T_TYPE __SLONGWORD_TYPE
+#define __OFF64_T_TYPE __SQUAD_TYPE
+#define __PID_T_TYPE __S32_TYPE
+#define __RLIM_T_TYPE __ULONGWORD_TYPE
+#define __RLIM64_T_TYPE __UQUAD_TYPE
+#define __BLKCNT_T_TYPE __SLONGWORD_TYPE
+#define __BLKCNT64_T_TYPE __SQUAD_TYPE
+#define __FSBLKCNT_T_TYPE __ULONGWORD_TYPE
+#define __FSBLKCNT64_T_TYPE __UQUAD_TYPE
+#define __FSFILCNT_T_TYPE __ULONGWORD_TYPE
+#define __FSFILCNT64_T_TYPE __UQUAD_TYPE
+#define __ID_T_TYPE __U32_TYPE
+#define __CLOCK_T_TYPE __SLONGWORD_TYPE
+#define __TIME_T_TYPE __SLONGWORD_TYPE
+#define __USECONDS_T_TYPE __U32_TYPE
+#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
+#define __DADDR_T_TYPE __S32_TYPE
+#define __SWBLK_T_TYPE __SLONGWORD_TYPE
+#define __KEY_T_TYPE __S32_TYPE
+#define __CLOCKID_T_TYPE __S32_TYPE
+#define __TIMER_T_TYPE __S32_TYPE
+#define __BLKSIZE_T_TYPE __SLONGWORD_TYPE
+#define __FSID_T_TYPE __UQUAD_TYPE
+#define __SSIZE_T_TYPE __SWORD_TYPE
+
+/* Number of descriptors that can fit in an `fd_set'. */
+#define __FD_SETSIZE 256
+
+
+#endif /* bits/typesizes.h */
diff --git a/libc/sysdeps/mach/hurd/brk.c b/libc/sysdeps/mach/hurd/brk.c
new file mode 100644
index 000000000..931b260b1
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/brk.c
@@ -0,0 +1,153 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,99,2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/resource.h>
+#include <cthreads.h> /* For `struct mutex'. */
+
+
+/* Initial maximum size of the data segment (this is arbitrary). */
+#define DATA_SIZE (128 * 1024 * 1024)
+
+/* Up to the page including this address is allocated from the kernel.
+ This address is the data resource limit. */
+vm_address_t _hurd_data_end;
+
+/* Up to this address is actually available to the user.
+ Pages beyond the one containing this address allow no access. */
+vm_address_t _hurd_brk = 0;
+
+/* This name is used by the Linux crtbeginS.o for reasons you don't even
+ want to think about it. It's just easier to provide some definition for
+ it than even to explain the braindamage involved. */
+weak_alias (_hurd_brk, ___brk_addr)
+
+struct mutex _hurd_brk_lock;
+
+extern int __data_start, _end;
+weak_extern (__data_start)
+static vm_address_t static_data_start;
+
+
+/* Set the end of the process's data space to INADDR.
+ Return 0 if successful, -1 if not. */
+int
+__brk (void *inaddr)
+{
+ int ret;
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_brk_lock);
+ ret = _hurd_set_brk ((vm_address_t) inaddr);
+ __mutex_unlock (&_hurd_brk_lock);
+ HURD_CRITICAL_END;
+ return ret;
+}
+weak_alias (__brk, brk)
+
+
+int
+_hurd_set_brk (vm_address_t addr)
+{
+ error_t err;
+ vm_address_t pagend = round_page (addr);
+ vm_address_t pagebrk = round_page (_hurd_brk);
+ long int rlimit;
+
+ if (pagend <= pagebrk)
+ {
+ if (pagend < pagebrk)
+ {
+ /* XXX wish this were atomic... */
+ /* First deallocate the memory to release its backing space. */
+ __vm_deallocate (__mach_task_self (), pagend, pagebrk - pagend);
+ /* Now reallocate it with no access allowed. */
+ err = __vm_map (__mach_task_self (),
+ &pagend, pagebrk - pagend,
+ 0, 0, MACH_PORT_NULL, 0, 0,
+ 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE,
+ VM_INHERIT_COPY);
+ /* XXX what if error? */
+ }
+ _hurd_brk = addr;
+ return 0;
+ }
+
+ __mutex_lock (&_hurd_rlimit_lock);
+ rlimit = _hurd_rlimits[RLIMIT_DATA].rlim_cur;
+ __mutex_unlock (&_hurd_rlimit_lock);
+
+ if (addr - static_data_start > rlimit)
+ {
+ /* Need to increase the resource limit. */
+ errno = ENOMEM;
+ return -1;
+ }
+
+ if (pagend > _hurd_data_end)
+ {
+ /* We didn't allocate enough space! Hopefully we can get some more! */
+ err = __vm_allocate (__mach_task_self (), &pagebrk, pagend - pagebrk, 0);
+ if (! err)
+ _hurd_data_end = pagend;
+ }
+ else
+ /* Make the memory accessible. */
+ err = __vm_protect (__mach_task_self (), pagebrk, pagend - pagebrk,
+ 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+
+ if (err)
+ return __hurd_fail (err);
+
+ _hurd_brk = addr;
+ return 0;
+}
+
+static void
+init_brk (void)
+{
+ vm_address_t pagend;
+
+ __mutex_init (&_hurd_brk_lock);
+
+ static_data_start = (vm_address_t) (&__data_start ?: &_end);
+
+ /* If _hurd_brk is already set, don't change it. The assumption is that
+ it was set in a previous run before something like Emacs's unexec was
+ called and dumped all the data up to the break at that point. */
+ if (_hurd_brk == 0)
+ _hurd_brk = (vm_address_t) &_end;
+
+ pagend = round_page (_hurd_brk);
+
+ _hurd_data_end = round_page (static_data_start + DATA_SIZE);
+
+ if (pagend < _hurd_data_end)
+ {
+ /* We use vm_map to allocate and change permissions atomically. */
+ if (__vm_map (__mach_task_self (), &pagend, _hurd_data_end - pagend,
+ 0, 0, MACH_PORT_NULL, 0, 0,
+ 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE,
+ VM_INHERIT_COPY))
+ /* Couldn't allocate the memory. The break will be very short. */
+ _hurd_data_end = pagend;
+ }
+
+ (void) &init_brk; /* Avoid ``defined but not used'' warning. */
+}
+text_set_element (_hurd_preinit_hook, init_brk);
diff --git a/libc/sysdeps/mach/hurd/chdir.c b/libc/sysdeps/mach/hurd/chdir.c
new file mode 100644
index 000000000..ee0f3f0f9
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/chdir.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991,92,93,94,95,97,99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <fcntl.h>
+#include <hurd/port.h>
+
+/* Change the current directory to FILE_NAME. */
+int
+__chdir (file_name)
+ const char *file_name;
+{
+ return _hurd_change_directory_port_from_name (&_hurd_ports[INIT_PORT_CWDIR],
+ file_name);
+}
+
+weak_alias (__chdir, chdir)
diff --git a/libc/sysdeps/mach/hurd/check_fds.c b/libc/sysdeps/mach/hurd/check_fds.c
new file mode 100644
index 000000000..c5d85225b
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/check_fds.c
@@ -0,0 +1,108 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fcntl.h>
+#include <paths.h>
+#include <unistd.h>
+
+#include <hurd.h>
+#include <hurd/fd.h>
+
+#include <set-hooks.h>
+
+/* Try to get a machine dependent instruction which will make the
+ program crash. This is used in case everything else fails. */
+#include <abort-instr.h>
+#ifndef ABORT_INSTRUCTION
+/* No such instruction is available. */
+# define ABORT_INSTRUCTION
+#endif
+
+static void
+check_one_fd (int fd, int mode)
+{
+ struct hurd_fd *d;
+
+ d = _hurd_fd_get (fd);
+ if (d == NULL)
+ {
+ /* This descriptor hasn't been opened. We try to allocate the
+ descriptor and open /dev/null on it so that the SUID program
+ we are about to start does not accidently use this
+ descriptor. */
+ d = _hurd_alloc_fd (NULL, fd);
+ if (d != NULL)
+ {
+ mach_port_t port;
+
+ port = __file_name_lookup (_PATH_DEVNULL, mode, 0);
+ if (port)
+ {
+ /* Since /dev/null isn't supposed to be a terminal, we
+ avoid any ctty magic. */
+ d->port.port = port;
+ d->flags = 0;
+
+ __spin_unlock (&d->port.lock);
+ return;
+ }
+ }
+
+ /* We cannot even give an error message here since it would run
+ into the same problems. */
+ while (1)
+ /* Try for ever and ever. */
+ ABORT_INSTRUCTION;
+ }
+}
+
+static void
+check_standard_fds (void)
+{
+ /* Check all three standard file descriptors. */
+ check_one_fd (STDIN_FILENO, O_RDONLY);
+ check_one_fd (STDOUT_FILENO, O_RDWR);
+ check_one_fd (STDERR_FILENO, O_RDWR);
+}
+
+static void
+init_standard_fds (void)
+{
+ /* Now that we have FDs, make sure that, if this is a SUID program,
+ FDs 0, 1 and 2 are allocated. If necessary we'll set them up
+ ourselves. If that's not possible we stop the program. */
+ if (__builtin_expect (__libc_enable_secure, 0))
+ check_standard_fds ();
+
+ (void) &init_standard_fds; /* Avoid "defined but not used" warning. */
+}
+text_set_element (_hurd_fd_subinit, init_standard_fds);
+
+
+#ifndef SHARED
+void
+__libc_check_standard_fds (void)
+{
+ /* We don't check the standard file descriptors here. They will be
+ checked when we initialize the file descriptor table, as part of
+ the _hurd_fd_subinit hook.
+
+ This function is only present to make sure that this module gets
+ linked in when part of the static libc. */
+}
+#endif
diff --git a/libc/sysdeps/mach/hurd/chflags.c b/libc/sysdeps/mach/hurd/chflags.c
new file mode 100644
index 000000000..a0b427ccf
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/chflags.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1991, 92, 93, 94, 97, 98 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Change the flags of FILE to FLAGS. */
+
+/* XXX shouldn't this be __chflags? */
+int
+chflags (const char *file, int flags)
+{
+ error_t err;
+ file_t port = __file_name_lookup (file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_chflags (port, flags);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/chmod.c b/libc/sysdeps/mach/hurd/chmod.c
new file mode 100644
index 000000000..c2edeb310
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/chmod.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1991, 1992, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Change the protections of FILE to MODE. */
+int
+__chmod (file, mode)
+ const char *file;
+ mode_t mode;
+{
+ error_t err;
+ file_t port = __file_name_lookup (file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_chmod (port, mode);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__chmod, chmod)
diff --git a/libc/sysdeps/mach/hurd/chown.c b/libc/sysdeps/mach/hurd/chown.c
new file mode 100644
index 000000000..7cb2ce3b2
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/chown.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991,1992,1994,1995,1997,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Change the owner and group of FILE. */
+int
+__chown (file, owner, group)
+ const char *file;
+ uid_t owner;
+ gid_t group;
+{
+ error_t err;
+ file_t port = __file_name_lookup (file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_chown (port, owner, group);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+libc_hidden_def (__chown)
+weak_alias (__chown, chown)
diff --git a/libc/sysdeps/mach/hurd/chroot.c b/libc/sysdeps/mach/hurd/chroot.c
new file mode 100644
index 000000000..fde016471
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/chroot.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1991,92,93,94,95,97,99,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <unistd.h>
+
+#include <hurd.h>
+#include <hurd/port.h>
+
+/* Make PATH be the root directory (the starting point for absolute
+ paths). Note that while on traditional UNIX systems this call is
+ restricted to the super-user, it isn't on the Hurd. */
+int
+chroot (const char *path)
+{
+ const char *lookup;
+ size_t len;
+ file_t dir, root;
+ error_t err;
+
+ /* Append trailing "/." to directory name to force ENOTDIR if it's not a
+ directory and EACCES if we don't have search permission. */
+ len = strlen (path);
+ if (len >= 2 && path[len - 2] == '/' && path[len - 1] == '.')
+ lookup = path;
+ else
+ {
+ char *n = alloca (len + 3);
+ memcpy (n, path, len);
+ n[len] = '/';
+ n[len + 1] = '.';
+ n[len + 2] = '\0';
+ lookup = n;
+ }
+
+ dir = __file_name_lookup (lookup, 0, 0);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ /* Prevent going through DIR's .. */
+ err = __file_reparent (dir, MACH_PORT_NULL, &root);
+ __mach_port_deallocate (__mach_task_self (), dir);
+ if (err)
+ return __hurd_fail (err);
+
+ _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], root);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/clock.c b/libc/sysdeps/mach/hurd/clock.c
new file mode 100644
index 000000000..d6d4597bc
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/clock.c
@@ -0,0 +1,54 @@
+/* Return the CPU time used by the program so far. Hurd version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <time.h>
+#include <sys/time.h>
+#include <mach.h>
+#include <mach/task_info.h>
+#include <hurd.h>
+
+/* Return the time used by the program so far (user time + system time). */
+clock_t
+clock (void)
+{
+ struct task_basic_info bi;
+ struct task_thread_times_info tti;
+ mach_msg_type_number_t count;
+ clock_t total;
+ error_t err;
+
+ count = TASK_BASIC_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_BASIC_INFO,
+ (task_info_t) &bi, &count);
+ if (err)
+ return __hurd_fail (err);
+
+ count = TASK_THREAD_TIMES_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_THREAD_TIMES_INFO,
+ (task_info_t) &tti, &count);
+ if (err)
+ return __hurd_fail (err);
+
+ total = bi.user_time.seconds * 1000000 + bi.user_time.microseconds;
+ total += tti.user_time.seconds * 1000000 + tti.user_time.microseconds;
+ total += bi.system_time.seconds * 1000000 + bi.system_time.microseconds;
+ total += tti.system_time.seconds * 1000000 + tti.system_time.microseconds;
+
+ return total;
+}
diff --git a/libc/sysdeps/mach/hurd/close.c b/libc/sysdeps/mach/hurd/close.c
new file mode 100644
index 000000000..6e18c0891
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/close.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991,92,93,94,95,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Close the file descriptor FD. */
+int
+__close (int fd)
+{
+ error_t err;
+
+ err = HURD_FD_USE (fd, _hurd_fd_close (descriptor));
+
+ return err ? __hurd_fail (err) : 0;
+}
+libc_hidden_def (__close)
+weak_alias (__close, close)
diff --git a/libc/sysdeps/mach/hurd/closedir.c b/libc/sysdeps/mach/hurd/closedir.c
new file mode 100644
index 000000000..2f08f2465
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/closedir.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include "dirstream.h"
+
+/* Close the directory stream DIRP.
+ Return 0 if successful, -1 if not. */
+int
+__closedir (DIR *dirp)
+{
+ error_t err;
+
+ if (dirp == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ __libc_lock_lock (dirp->__lock);
+ err = __vm_deallocate (__mach_task_self (),
+ (vm_address_t) dirp->__data, dirp->__allocation);
+ dirp->__data = NULL;
+ err = _hurd_fd_close (dirp->__fd);
+
+ if (err)
+ {
+ /* Unlock the DIR. A failing closedir can be repeated (and may fail
+ again, but shouldn't deadlock). */
+ __libc_lock_unlock (dirp->__lock);
+ return __hurd_fail (err);
+ }
+
+ /* Clean up the lock and free the structure. */
+ __libc_lock_fini (dirp->__lock);
+ free (dirp);
+
+ return 0;
+}
+weak_alias (__closedir, closedir)
diff --git a/libc/sysdeps/mach/hurd/configure b/libc/sysdeps/mach/hurd/configure
new file mode 100755
index 000000000..959a779fa
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/configure
@@ -0,0 +1,92 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+
+# GNU libc on the Hurd is always reentrant.
+DEFINES="$DEFINES -D_LIBC_REENTRANT"
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_HIDDEN 1
+_ACEOF
+
+
+# Don't bother trying to generate any glue code to be compatible with the
+# existing system library, because we are the only system library.
+inhibit_glue=yes
+
+if test "x$prefix" != x; then
+ { echo "$as_me:$LINENO: WARNING: --prefix= (empty) is required for GNU/Hurd to work normally" >&5
+echo "$as_me: WARNING: --prefix= (empty) is required for GNU/Hurd to work normally" >&2;}
+fi
+
+case "$machine" in
+ i386*)
+ # The default oldest ABI is 2.2.6.
+ # We only need a "yes" here if the oldest ABI supported will be < 2.2.6.
+ if test "$oldest_abi" != default && test "$oldest_abi" \< "2.2.6"; then
+ libc_cv_gcc_unwind_find_fde=yes
+ fi
+ ;;
+esac
+
+
+echo "$as_me:$LINENO: checking Hurd header version" >&5
+echo $ECHO_N "checking Hurd header version... $ECHO_C" >&6
+if test "${libc_cv_hurd_version+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <hurd/version.h>
+int
+main ()
+{
+
+#define NEED_VERSION 20020609
+#if HURD_INTERFACE_VERSION < NEED_VERSION
+# error Hurd version too old: HURD_INTERFACE_VERSION < NEED_VERSION
+#endif
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_hurd_version=ok
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+libc_cv_hurd_version=bad
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $libc_cv_hurd_version" >&5
+echo "${ECHO_T}$libc_cv_hurd_version" >&6
+if test "x$libc_cv_hurd_version" != xok; then
+ { { echo "$as_me:$LINENO: error: Hurd headers not installed or too old" >&5
+echo "$as_me: error: Hurd headers not installed or too old" >&2;}
+ { (exit 1); exit 1; }; }
+fi
diff --git a/libc/sysdeps/mach/hurd/configure.in b/libc/sysdeps/mach/hurd/configure.in
new file mode 100644
index 000000000..87c07c11d
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/configure.in
@@ -0,0 +1,38 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+
+# GNU libc on the Hurd is always reentrant.
+DEFINES="$DEFINES -D_LIBC_REENTRANT"
+
+dnl We need this setting because of the need for PLT calls in ld.so.
+AC_DEFINE([NO_HIDDEN])
+
+# Don't bother trying to generate any glue code to be compatible with the
+# existing system library, because we are the only system library.
+inhibit_glue=yes
+
+if test "x$prefix" != x; then
+ AC_MSG_WARN([--prefix= (empty) is required for GNU/Hurd to work normally])
+fi
+
+case "$machine" in
+ i386*)
+ # The default oldest ABI is 2.2.6.
+ # We only need a "yes" here if the oldest ABI supported will be < 2.2.6.
+ if test "$oldest_abi" != default && test "$oldest_abi" \< "2.2.6"; then
+ libc_cv_gcc_unwind_find_fde=yes
+ fi
+ ;;
+esac
+
+AC_CACHE_CHECK(Hurd header version, libc_cv_hurd_version, [dnl
+AC_TRY_COMPILE(dnl
+[#include <hurd/version.h>], [
+#define NEED_VERSION 20020609
+#if HURD_INTERFACE_VERSION < NEED_VERSION
+# error Hurd version too old: HURD_INTERFACE_VERSION < NEED_VERSION
+#endif],
+ libc_cv_hurd_version=ok,
+ libc_cv_hurd_version=bad)])
+if test "x$libc_cv_hurd_version" != xok; then
+ AC_MSG_ERROR(Hurd headers not installed or too old)
+fi
diff --git a/libc/sysdeps/mach/hurd/connect.c b/libc/sysdeps/mach/hurd/connect.c
new file mode 100644
index 000000000..30883f65a
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/connect.c
@@ -0,0 +1,78 @@
+/* Copyright (C) 1992,94,95,96,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <sys/socket.h>
+#include <hurd/socket.h>
+#include <sys/un.h>
+#include <hurd/ifsock.h>
+
+#undef __connect
+
+/* Open a connection on socket FD to peer at ADDR (which LEN bytes long).
+ For connectionless socket types, just set the default address to send to
+ and the only address from which to accept transmissions.
+ Return 0 on success, -1 for errors. */
+int
+__connect (int fd, __CONST_SOCKADDR_ARG addrarg, socklen_t len)
+{
+ error_t err;
+ addr_port_t aport;
+ const struct sockaddr_un *addr = addrarg.__sockaddr_un__;
+
+ if (addr->sun_family == AF_LOCAL)
+ {
+ /* For the local domain, we must look up the name as a file and talk
+ to it with the ifsock protocol. */
+ file_t file = __file_name_lookup (addr->sun_path, 0, 0);
+ if (file == MACH_PORT_NULL)
+ return -1;
+ err = __ifsock_getsockaddr (file, &aport);
+ __mach_port_deallocate (__mach_task_self (), file);
+ if (err == MIG_BAD_ID || err == EOPNOTSUPP)
+ /* The file did not grok the ifsock protocol. */
+ err = ENOTSOCK;
+ if (err)
+ return __hurd_fail (err);
+ }
+ else
+ err = EIEIO;
+
+ err = HURD_DPORT_USE (fd,
+ ({
+ if (err)
+ err = __socket_create_address (port,
+ addr->sun_family,
+ (char *) addr, len,
+ &aport);
+ if (! err)
+ {
+ err = __socket_connect (port, aport);
+ __mach_port_deallocate (__mach_task_self (),
+ aport);
+ }
+ err;
+ }));
+
+ return err ? __hurd_dfail (fd, err) : 0;
+}
+
+INTDEF(__connect)
+weak_alias (__connect, connect)
diff --git a/libc/sysdeps/mach/hurd/cthreads.c b/libc/sysdeps/mach/hurd/cthreads.c
new file mode 100644
index 000000000..fcadaddbd
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/cthreads.c
@@ -0,0 +1,66 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <bits/libc-lock.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* Placeholder for key creation routine from Hurd cthreads library. */
+int
+weak_function
+cthread_keycreate (key)
+ cthread_key_t *key;
+{
+ __set_errno (ENOSYS);
+ *key = -1;
+ return -1;
+}
+
+/* Placeholder for key retrieval routine from Hurd cthreads library. */
+int
+weak_function
+cthread_getspecific (key, pval)
+ cthread_key_t key;
+ void **pval;
+{
+ *pval = NULL;
+ __set_errno (ENOSYS);
+ return -1;
+}
+
+/* Placeholder for key setting routine from Hurd cthreads library. */
+int
+weak_function
+cthread_setspecific (key, val)
+ cthread_key_t key;
+ void *val;
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+
+/* Call cthread_getspecific which gets a pointer to the return value instead
+ of just returning it. */
+void *
+__libc_getspecific (key)
+ cthread_key_t key;
+{
+ void *val;
+ cthread_getspecific (key, &val);
+ return val;
+}
diff --git a/libc/sysdeps/mach/hurd/device-nrs.h b/libc/sysdeps/mach/hurd/device-nrs.h
new file mode 100644
index 000000000..ce441a50f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/device-nrs.h
@@ -0,0 +1,28 @@
+/* Device numbers of devices used in the implementation. Hurd version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DEVICE_NRS_H
+#define _DEVICE_NRS_H 1
+
+#include <hurd/hurd_types.h>
+
+/* Check whether a given device is a tty. */
+#define DEV_TTY_P(statp) ((statp)->st_fstype == FSTYPE_TERM)
+
+#endif /* device-nrs.h */
diff --git a/libc/sysdeps/mach/hurd/dirfd.c b/libc/sysdeps/mach/hurd/dirfd.c
new file mode 100644
index 000000000..fde13fae3
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/dirfd.c
@@ -0,0 +1,41 @@
+/* dirfd -- Return the file descriptor used by a DIR stream. Hurd version.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dirent.h>
+#include <dirstream.h>
+#include <hurd/fd.h>
+#include <errno.h>
+
+int
+dirfd (DIR *dirp)
+{
+ int fd;
+ __mutex_lock (&_hurd_dtable_lock);
+ for (fd = 0; fd < _hurd_dtablesize; ++fd)
+ if (_hurd_dtable[fd] == dirp->__fd)
+ break;
+ if (fd == _hurd_dtablesize)
+ {
+ errno = EINVAL;
+ fd = -1;
+ }
+ __mutex_unlock (&_hurd_dtable_lock);
+
+ return fd;
+}
diff --git a/libc/sysdeps/mach/hurd/dirstream.h b/libc/sysdeps/mach/hurd/dirstream.h
new file mode 100644
index 000000000..aab6b897f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/dirstream.h
@@ -0,0 +1,42 @@
+/* Copyright (C) 1993,94,95,96,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DIRSTREAM_H
+
+#define _DIRSTREAM_H 1
+
+#include <bits/libc-lock.h>
+
+/* Directory stream type.
+
+ The Hurd directory format is the same as `struct dirent', so `readdir'
+ returns a pointer into the buffer we read directory data into. */
+
+struct __dirstream
+ {
+ void *__fd; /* `struct hurd_fd' pointer for descriptor. */
+ char *__data; /* Directory block. */
+ int __entry_data; /* Entry number `__data' corresponds to. */
+ char *__ptr; /* Current pointer into the block. */
+ int __entry_ptr; /* Entry number `__ptr' corresponds to. */
+ size_t __allocation; /* Space allocated for the block. */
+ size_t __size; /* Total valid data in the block. */
+ __libc_lock_define (, __lock) /* Mutex lock for this structure. */
+ };
+
+#endif /* dirstream.h */
diff --git a/libc/sysdeps/mach/hurd/dl-cache.c b/libc/sysdeps/mach/hurd/dl-cache.c
new file mode 100644
index 000000000..f7ad3a85d
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/dl-cache.c
@@ -0,0 +1,29 @@
+/* Stubby version of dl-cache; the Hurd doesn't support this "feature".
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+const char *
+_dl_load_cache_lookup (const char *name)
+{
+ return 0;
+}
+
+void
+_dl_unload_cache (void)
+{
+}
diff --git a/libc/sysdeps/mach/hurd/dl-execstack.c b/libc/sysdeps/mach/hurd/dl-execstack.c
new file mode 100644
index 000000000..0e82a3f60
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/dl-execstack.c
@@ -0,0 +1,52 @@
+/* Stack executability handling for GNU dynamic linker. Hurd version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ldsodefs.h>
+#include <hurdstartup.h>
+#include <errno.h>
+
+extern struct hurd_startup_data *_dl_hurd_data attribute_hidden;
+
+/* There is no portable way to know the bounds of the initial thread's stack
+ so as to mprotect it. */
+
+int
+internal_function
+_dl_make_stack_executable (void **stack_endp)
+{
+ /* Challenge the caller. */
+ if (__builtin_expect (*stack_endp != __libc_stack_end, 0))
+ return EPERM;
+ *stack_endp = NULL;
+
+#ifdef IS_IN_rtld
+ if (__mprotect ((void *)_dl_hurd_data->stack_base, _dl_hurd_data->stack_size,
+ PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
+ return errno;
+
+ /* Remember that we changed the permission. */
+ GL(dl_stack_flags) |= PF_X;
+
+ return 0;
+#else
+ /* We don't bother to implement this for static linking. */
+ return ENOSYS;
+#endif
+}
+rtld_hidden_def (_dl_make_stack_executable)
diff --git a/libc/sysdeps/mach/hurd/dl-sysdep.c b/libc/sysdeps/mach/hurd/dl-sysdep.c
new file mode 100644
index 000000000..668aaaf8b
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/dl-sysdep.c
@@ -0,0 +1,669 @@
+/* Operating system support for run-time dynamic linker. Hurd version.
+ Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd.h>
+#include <link.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <ldsodefs.h>
+#include <sys/wait.h>
+#include <assert.h>
+#include <sysdep.h>
+#include <mach/mig_support.h>
+#include "hurdstartup.h"
+#include <hurd/lookup.h>
+#include <hurd/auth.h>
+#include <hurd/term.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+
+#include <entry.h>
+#include <dl-machine.h>
+#include <dl-procinfo.h>
+
+extern void __mach_init (void);
+
+extern int _dl_argc;
+extern char **_dl_argv;
+extern char **_environ;
+
+int __libc_enable_secure = 0;
+INTVARDEF(__libc_enable_secure)
+int __libc_multiple_libcs = 0; /* Defining this here avoids the inclusion
+ of init-first. */
+/* This variable containts the lowest stack address ever used. */
+void *__libc_stack_end;
+
+#if HP_TIMING_AVAIL
+hp_timing_t _dl_cpuclock_offset;
+#endif
+
+
+struct hurd_startup_data *_dl_hurd_data;
+
+/* This is used only within ld.so, via dl-minimal.c's __errno_location. */
+#undef errno
+int errno attribute_hidden;
+
+/* Defining these variables here avoids the inclusion of hurdsig.c. */
+unsigned long int __hurd_sigthread_stack_base;
+unsigned long int __hurd_sigthread_stack_end;
+unsigned long int *__hurd_sigthread_variables;
+
+/* Defining these variables here avoids the inclusion of init-first.c.
+ We need to provide temporary storage for the per-thread variables
+ of the main user thread here, since it is used for storing the
+ `errno' variable. Note that this information is lost once we
+ relocate the dynamic linker. */
+static unsigned long int threadvars[_HURD_THREADVAR_MAX];
+unsigned long int __hurd_threadvar_stack_offset
+ = (unsigned long int) &threadvars;
+unsigned long int __hurd_threadvar_stack_mask;
+
+#define FMH defined(__i386__)
+#if ! FMH
+# define fmh() ((void)0)
+# define unfmh() ((void)0)
+#else
+/* XXX loser kludge for vm_map kernel bug */
+#undef ELF_MACHINE_USER_ADDRESS_MASK
+#define ELF_MACHINE_USER_ADDRESS_MASK 0
+static vm_address_t fmha;
+static vm_size_t fmhs;
+static void unfmh(void){
+__vm_deallocate(__mach_task_self(),fmha,fmhs);}
+static void fmh(void) {
+ error_t err;int x;mach_port_t p;
+ vm_address_t a=0x08000000U,max=VM_MAX_ADDRESS;
+ while (!(err=__vm_region(__mach_task_self(),&a,&fmhs,&x,&x,&x,&x,&p,&x))){
+ __mach_port_deallocate(__mach_task_self(),p);
+ if (a+fmhs>=0x80000000U){
+ max=a; break;}
+ fmha=a+=fmhs;}
+ if (err) assert(err==KERN_NO_SPACE);
+ if (!fmha)fmhs=0;else{
+ fmhs=max-fmha;
+ err = __vm_map (__mach_task_self (),
+ &fmha, fmhs, 0, 0, MACH_PORT_NULL, 0, 1,
+ VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_COPY);
+ assert_perror(err);}
+ }
+/* XXX loser kludge for vm_map kernel bug */
+#endif
+
+
+ElfW(Addr)
+_dl_sysdep_start (void **start_argptr,
+ void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phent,
+ ElfW(Addr) *user_entry))
+{
+ void go (intptr_t *argdata)
+ {
+ extern unsigned int _dl_skip_args; /* rtld.c */
+ char **p;
+
+ /* Cache the information in various global variables. */
+ _dl_argc = *argdata;
+ _dl_argv = 1 + (char **) argdata;
+ _environ = &_dl_argv[_dl_argc + 1];
+ for (p = _environ; *p++;); /* Skip environ pointers and terminator. */
+
+ if ((void *) p == _dl_argv[0])
+ {
+ static struct hurd_startup_data nodata;
+ _dl_hurd_data = &nodata;
+ nodata.user_entry = (vm_address_t) ENTRY_POINT;
+ }
+ else
+ _dl_hurd_data = (void *) p;
+
+ INTUSE(__libc_enable_secure) = _dl_hurd_data->flags & EXEC_SECURE;
+
+ if (_dl_hurd_data->flags & EXEC_STACK_ARGS &&
+ _dl_hurd_data->user_entry == 0)
+ _dl_hurd_data->user_entry = (vm_address_t) ENTRY_POINT;
+
+unfmh(); /* XXX */
+
+#if 0 /* XXX make this work for real someday... */
+ if (_dl_hurd_data->user_entry == (vm_address_t) ENTRY_POINT)
+ /* We were invoked as a command, not as the program interpreter.
+ The generic ld.so code supports this: it will parse the args
+ as "ld.so PROGRAM [ARGS...]". For booting the Hurd, we
+ support an additional special syntax:
+ ld.so [-LIBS...] PROGRAM [ARGS...]
+ Each LIBS word consists of "FILENAME=MEMOBJ";
+ for example "-/lib/libc.so=123" says that the contents of
+ /lib/libc.so are found in a memory object whose port name
+ in our task is 123. */
+ while (_dl_argc > 2 && _dl_argv[1][0] == '-' && _dl_argv[1][1] != '-')
+ {
+ char *lastslash, *memobjname, *p;
+ struct link_map *l;
+ mach_port_t memobj;
+ error_t err;
+
+ ++_dl_skip_args;
+ --_dl_argc;
+ p = _dl_argv++[1] + 1;
+
+ memobjname = strchr (p, '=');
+ if (! memobjname)
+ _dl_sysdep_fatal ("Bogus library spec: ", p, "\n", NULL);
+ *memobjname++ = '\0';
+ memobj = 0;
+ while (*memobjname != '\0')
+ memobj = (memobj * 10) + (*memobjname++ - '0');
+
+ /* Add a user reference on the memory object port, so we will
+ still have one after _dl_map_object_from_fd calls our
+ `close'. */
+ err = __mach_port_mod_refs (__mach_task_self (), memobj,
+ MACH_PORT_RIGHT_SEND, +1);
+ assert_perror (err);
+
+ lastslash = strrchr (p, '/');
+ l = _dl_map_object_from_fd (lastslash ? lastslash + 1 : p,
+ memobj, strdup (p), 0);
+
+ /* Squirrel away the memory object port where it
+ can be retrieved by the program later. */
+ l->l_info[DT_NULL] = (void *) memobj;
+ }
+#endif
+
+ /* Call elf/rtld.c's main program. It will set everything
+ up and leave us to transfer control to USER_ENTRY. */
+ (*dl_main) ((const ElfW(Phdr) *) _dl_hurd_data->phdr,
+ _dl_hurd_data->phdrsz / sizeof (ElfW(Phdr)),
+ &_dl_hurd_data->user_entry);
+
+ /* The call above might screw a few things up.
+
+ First of all, if _dl_skip_args is nonzero, we are ignoring
+ the first few arguments. However, if we have no Hurd startup
+ data, it is the magical convention that ARGV[0] == P. The
+ startup code in init-first.c will get confused if this is not
+ the case, so we must rearrange things to make it so. We'll
+ overwrite the origional ARGV[0] at P with ARGV[_dl_skip_args].
+
+ Secondly, if we need to be secure, it removes some dangerous
+ environment variables. If we have no Hurd startup date this
+ changes P (since that's the location after the terminating
+ NULL in the list of environment variables). We do the same
+ thing as in the first case but make sure we recalculate P.
+ If we do have Hurd startup data, we have to move the data
+ such that it starts just after the terminating NULL in the
+ environment list.
+
+ We use memmove, since the locations might overlap. */
+ if (INTUSE(__libc_enable_secure) || _dl_skip_args)
+ {
+ char **newp;
+
+ for (newp = _environ; *newp++;);
+
+ if (_dl_argv[-_dl_skip_args] == (char *) p)
+ {
+ if ((char *) newp != _dl_argv[0])
+ {
+ assert ((char *) newp < _dl_argv[0]);
+ _dl_argv[0] = memmove ((char *) newp, _dl_argv[0],
+ strlen (_dl_argv[0]) + 1);
+ }
+ }
+ else
+ {
+ if ((void *) newp != _dl_hurd_data)
+ memmove (newp, _dl_hurd_data, sizeof (*_dl_hurd_data));
+ }
+ }
+
+ {
+ extern void _dl_start_user (void);
+ /* Unwind the stack to ARGDATA and simulate a return from _dl_start
+ to the RTLD_START code which will run the user's entry point. */
+ RETURN_TO (argdata, &_dl_start_user, _dl_hurd_data->user_entry);
+ }
+ }
+
+ /* Set up so we can do RPCs. */
+ __mach_init ();
+
+ /* Initialize frequently used global variable. */
+ GLRO(dl_pagesize) = __getpagesize ();
+
+#if HP_TIMING_AVAIL
+ HP_TIMING_NOW (_dl_cpuclock_offset);
+#endif
+
+fmh(); /* XXX */
+
+ /* See hurd/hurdstartup.c; this deals with getting information
+ from the exec server and slicing up the arguments.
+ Then it will call `go', above. */
+ _hurd_startup (start_argptr, &go);
+
+ LOSE;
+ abort ();
+}
+
+void
+internal_function
+_dl_sysdep_start_cleanup (void)
+{
+ /* Deallocate the reply port and task port rights acquired by
+ __mach_init. We are done with them now, and the user will
+ reacquire them for himself when he wants them. */
+ __mig_dealloc_reply_port (MACH_PORT_NULL);
+ __mach_port_deallocate (__mach_task_self (), __mach_task_self_);
+}
+
+/* Minimal open/close/mmap implementation sufficient for initial loading of
+ shared libraries. These are weak definitions so that when the
+ dynamic linker re-relocates itself to be user-visible (for -ldl),
+ it will get the user's definition (i.e. usually libc's). */
+
+/* Open FILE_NAME and return a Hurd I/O for it in *PORT, or return an
+ error. If STAT is non-zero, stat the file into that stat buffer. */
+static error_t
+open_file (const char *file_name, int flags,
+ mach_port_t *port, struct stat64 *stat)
+{
+ enum retry_type doretry;
+ char retryname[1024]; /* XXX string_t LOSES! */
+ file_t startdir;
+ error_t err;
+
+ error_t use_init_port (int which, error_t (*operate) (file_t))
+ {
+ return (which < _dl_hurd_data->portarraysize
+ ? ((*operate) (_dl_hurd_data->portarray[which]))
+ : EGRATUITOUS);
+ }
+ file_t get_dtable_port (int fd)
+ {
+ if ((unsigned int) fd < _dl_hurd_data->dtablesize
+ && _dl_hurd_data->dtable[fd] != MACH_PORT_NULL)
+ {
+ __mach_port_mod_refs (__mach_task_self (), _dl_hurd_data->dtable[fd],
+ MACH_PORT_RIGHT_SEND, +1);
+ return _dl_hurd_data->dtable[fd];
+ }
+ errno = EBADF;
+ return MACH_PORT_NULL;
+ }
+
+ assert (!(flags & ~O_READ));
+
+ startdir = _dl_hurd_data->portarray[file_name[0] == '/' ?
+ INIT_PORT_CRDIR : INIT_PORT_CWDIR];
+
+ while (file_name[0] == '/')
+ file_name++;
+
+ err = __dir_lookup (startdir, (char *)file_name, O_RDONLY, 0,
+ &doretry, retryname, port);
+
+ if (!err)
+ err = __hurd_file_name_lookup_retry (use_init_port, get_dtable_port,
+ __dir_lookup, doretry, retryname,
+ O_RDONLY, 0, port);
+ if (!err && stat)
+ {
+ err = __io_stat (*port, stat);
+ if (err)
+ __mach_port_deallocate (__mach_task_self (), *port);
+ }
+
+ return err;
+}
+
+int weak_function
+__open (const char *file_name, int mode, ...)
+{
+ mach_port_t port;
+ error_t err = open_file (file_name, mode, &port, 0);
+ if (err)
+ return __hurd_fail (err);
+ else
+ return (int)port;
+}
+
+int weak_function
+__close (int fd)
+{
+ if (fd != (int) MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), (mach_port_t) fd);
+ return 0;
+}
+
+__ssize_t weak_function
+__libc_read (int fd, void *buf, size_t nbytes)
+{
+ error_t err;
+ char *data;
+ mach_msg_type_number_t nread;
+
+ data = buf;
+ err = __io_read ((mach_port_t) fd, &data, &nread, -1, nbytes);
+ if (err)
+ return __hurd_fail (err);
+
+ if (data != buf)
+ {
+ memcpy (buf, data, nread);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread);
+ }
+
+ return nread;
+}
+libc_hidden_weak (__libc_read)
+
+__ssize_t weak_function
+__libc_write (int fd, const void *buf, size_t nbytes)
+{
+ error_t err;
+ mach_msg_type_number_t nwrote;
+
+ assert (fd < _hurd_init_dtablesize);
+
+ err = __io_write (_hurd_init_dtable[fd], buf, nbytes, -1, &nwrote);
+ if (err)
+ return __hurd_fail (err);
+
+ return nwrote;
+}
+libc_hidden_weak (__libc_write)
+
+/* This is only used for printing messages (see dl-misc.c). */
+__ssize_t weak_function
+__writev (int fd, const struct iovec *iov, int niov)
+{
+ if (fd >= _hurd_init_dtablesize)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ int i;
+ size_t total = 0;
+ for (i = 0; i < niov; ++i)
+ total += iov[i].iov_len;
+
+ if (total != 0)
+ {
+ char buf[total], *bufp = buf;
+ error_t err;
+ mach_msg_type_number_t nwrote;
+
+ for (i = 0; i < niov; ++i)
+ bufp = (memcpy (bufp, iov[i].iov_base, iov[i].iov_len)
+ + iov[i].iov_len);
+
+ err = __io_write (_hurd_init_dtable[fd], buf, total, -1, &nwrote);
+ if (err)
+ return __hurd_fail (err);
+
+ return nwrote;
+ }
+ return 0;
+}
+
+
+off64_t weak_function
+__libc_lseek64 (int fd, off64_t offset, int whence)
+{
+ error_t err;
+
+ err = __io_seek ((mach_port_t) fd, offset, whence, &offset);
+ if (err)
+ return __hurd_fail (err);
+
+ return offset;
+}
+
+__ptr_t weak_function
+__mmap (__ptr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
+{
+ error_t err;
+ vm_prot_t vmprot;
+ vm_address_t mapaddr;
+ mach_port_t memobj_rd, memobj_wr;
+
+ vmprot = VM_PROT_NONE;
+ if (prot & PROT_READ)
+ vmprot |= VM_PROT_READ;
+ if (prot & PROT_WRITE)
+ vmprot |= VM_PROT_WRITE;
+ if (prot & PROT_EXEC)
+ vmprot |= VM_PROT_EXECUTE;
+
+ if (flags & MAP_ANON)
+ memobj_rd = MACH_PORT_NULL;
+ else
+ {
+ assert (!(flags & MAP_SHARED));
+ err = __io_map ((mach_port_t) fd, &memobj_rd, &memobj_wr);
+ if (err)
+ return __hurd_fail (err), MAP_FAILED;
+ __mach_port_deallocate (__mach_task_self (), memobj_wr);
+ }
+
+ mapaddr = (vm_address_t) addr;
+ err = __vm_map (__mach_task_self (),
+ &mapaddr, (vm_size_t) len, ELF_MACHINE_USER_ADDRESS_MASK,
+ !(flags & MAP_FIXED),
+ memobj_rd,
+ (vm_offset_t) offset,
+ flags & (MAP_COPY|MAP_PRIVATE),
+ vmprot, VM_PROT_ALL,
+ (flags & MAP_SHARED) ? VM_INHERIT_SHARE : VM_INHERIT_COPY);
+ if (err == KERN_NO_SPACE && (flags & MAP_FIXED))
+ {
+ /* XXX this is not atomic as it is in unix! */
+ /* The region is already allocated; deallocate it first. */
+ err = __vm_deallocate (__mach_task_self (), mapaddr, len);
+ if (! err)
+ err = __vm_map (__mach_task_self (),
+ &mapaddr, (vm_size_t) len,
+ ELF_MACHINE_USER_ADDRESS_MASK,
+ !(flags & MAP_FIXED),
+ memobj_rd, (vm_offset_t) offset,
+ flags & (MAP_COPY|MAP_PRIVATE),
+ vmprot, VM_PROT_ALL,
+ (flags & MAP_SHARED)
+ ? VM_INHERIT_SHARE : VM_INHERIT_COPY);
+ }
+
+ if ((flags & MAP_ANON) == 0)
+ __mach_port_deallocate (__mach_task_self (), memobj_rd);
+
+ if (err)
+ return __hurd_fail (err), MAP_FAILED;
+ return (__ptr_t) mapaddr;
+}
+
+int weak_function
+__fxstat64 (int vers, int fd, struct stat64 *buf)
+{
+ error_t err;
+
+ assert (vers == _STAT_VER);
+
+ err = __io_stat ((mach_port_t) fd, buf);
+ if (err)
+ return __hurd_fail (err);
+
+ return 0;
+}
+libc_hidden_def (__fxstat64)
+
+int weak_function
+__xstat64 (int vers, const char *file, struct stat64 *buf)
+{
+ error_t err;
+ mach_port_t port;
+
+ assert (vers == _STAT_VER);
+
+ err = open_file (file, 0, &port, buf);
+ if (err)
+ return __hurd_fail (err);
+
+ __mach_port_deallocate (__mach_task_self (), port);
+
+ return 0;
+}
+libc_hidden_def (__xstat64)
+
+/* This function is called by the dynamic linker (rtld.c) to check
+ whether debugging malloc is allowed even for SUID binaries. This
+ stub will always fail, which means that malloc-debugging is always
+ disabled for SUID binaries. */
+int weak_function
+__access (const char *file, int type)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+pid_t weak_function
+__getpid ()
+{
+ pid_t pid, ppid;
+ int orphaned;
+
+ if (__proc_getpids (_dl_hurd_data->portarray[INIT_PORT_PROC],
+ &pid, &ppid, &orphaned))
+ return -1;
+
+ return pid;
+}
+
+/* This is called only in some strange cases trying to guess a value
+ for $ORIGIN for the executable. The dynamic linker copes with
+ getcwd failing (dl-object.c), and it's too much hassle to include
+ the functionality here. (We could, it just requires duplicating or
+ reusing getcwd.c's code but using our special lookup function as in
+ `open', above.) */
+char *
+weak_function
+__getcwd (char *buf, size_t size)
+{
+ errno = ENOSYS;
+ return NULL;
+}
+
+void weak_function attribute_hidden
+_exit (int status)
+{
+ __proc_mark_exit (_dl_hurd_data->portarray[INIT_PORT_PROC],
+ W_EXITCODE (status, 0), 0);
+ while (__task_terminate (__mach_task_self ()))
+ __mach_task_self_ = (__mach_task_self) ();
+}
+/* We need this alias to satisfy references from libc_pic.a objects
+ that were affected by the libc_hidden_proto declaration for _exit. */
+strong_alias (_exit, __GI__exit)
+
+/* Try to get a machine dependent instruction which will make the
+ program crash. This is used in case everything else fails. */
+#include <abort-instr.h>
+#ifndef ABORT_INSTRUCTION
+/* No such instruction is available. */
+# define ABORT_INSTRUCTION
+#endif
+
+void weak_function
+abort (void)
+{
+ /* Try to abort using the system specific command. */
+ ABORT_INSTRUCTION;
+
+ /* If the abort instruction failed, exit. */
+ _exit (127);
+
+ /* If even this fails, make sure we never return. */
+ while (1)
+ /* Try for ever and ever. */
+ ABORT_INSTRUCTION;
+}
+
+/* We need this alias to satisfy references from libc_pic.a objects
+ that were affected by the libc_hidden_proto declaration for abort. */
+strong_alias (abort, __GI_abort)
+
+/* This function is called by interruptible RPC stubs. For initial
+ dynamic linking, just use the normal mach_msg. Since this defn is
+ weak, the real defn in libc.so will override it if we are linked into
+ the user program (-ldl). */
+
+error_t weak_function
+_hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
+ mach_msg_option_t option,
+ mach_msg_size_t send_size,
+ mach_msg_size_t rcv_size,
+ mach_port_t rcv_name,
+ mach_msg_timeout_t timeout,
+ mach_port_t notify)
+{
+ return __mach_msg (msg, option, send_size, rcv_size, rcv_name,
+ timeout, notify);
+}
+
+
+void
+internal_function
+_dl_show_auxv (void)
+{
+ /* There is nothing to print. Hurd has no auxiliary vector. */
+}
+
+
+/* Return an array of useful/necessary hardware capability names. */
+const struct r_strlenpair *
+internal_function
+_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
+ size_t *max_capstrlen)
+{
+ struct r_strlenpair *result;
+
+ /* Return an empty array. Hurd has no hardware capabilities. */
+ result = (struct r_strlenpair *) malloc (sizeof (*result));
+ if (result == NULL)
+ _dl_signal_error (ENOMEM, NULL, NULL, "cannot create capability list");
+
+ result[0].str = (char *) result; /* Does not really matter. */
+ result[0].len = 0;
+
+ *sz = 1;
+ return result;
+}
+
+void weak_function
+_dl_init_first (int argc, ...)
+{
+ /* This no-op definition only gets used if libc is not linked in. */
+}
diff --git a/libc/sysdeps/mach/hurd/dl-sysdep.h b/libc/sysdeps/mach/hurd/dl-sysdep.h
new file mode 100644
index 000000000..4b21b779e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/dl-sysdep.h
@@ -0,0 +1,31 @@
+/* System-specific settings for dynamic linker code. Hurd version.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The private errno doesn't make sense on the Hurd. errno is always the
+ thread-local slot shared with libc, and it matters to share the cell
+ with libc because after startup we use libc functions that set errno
+ (open, mmap, etc). */
+
+#define RTLD_PRIVATE_ERRNO 0
+
+#ifdef SHARED
+/* _dl_argv cannot be attribute_relro, because the stack-switching
+ libc initializer for using cthreads might write into it. */
+# define DL_ARGV_NOT_RELRO 1
+#endif
diff --git a/libc/sysdeps/mach/hurd/dup2.c b/libc/sysdeps/mach/hurd/dup2.c
new file mode 100644
index 000000000..3abd30cfb
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/dup2.c
@@ -0,0 +1,134 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 97, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Duplicate FD to FD2, closing the old FD2 and making FD2 be
+ open on the same file as FD is. Return FD2 or -1. */
+int
+__dup2 (fd, fd2)
+ int fd;
+ int fd2;
+{
+ struct hurd_fd *d;
+
+ /* Extract the ports and flags from FD. */
+ d = _hurd_fd_get (fd);
+ if (d == NULL)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ HURD_CRITICAL_BEGIN;
+
+ __spin_lock (&d->port.lock);
+ if (d->port.port == MACH_PORT_NULL)
+ {
+ __spin_unlock (&d->port.lock);
+ errno = EBADF;
+ fd2 = -1;
+ }
+ else if (fd2 == fd)
+ /* FD is valid and FD2 is already the same; just return it. */
+ __spin_unlock (&d->port.lock);
+ else
+ {
+ struct hurd_userlink ulink, ctty_ulink;
+ int flags = d->flags;
+ io_t ctty = _hurd_port_get (&d->ctty, &ctty_ulink);
+ io_t port = _hurd_port_locked_get (&d->port, &ulink); /* Unlocks D. */
+
+ if (fd2 < 0)
+ {
+ errno = EBADF;
+ fd2 = -1;
+ }
+ else
+ {
+ /* Get a hold of the destination descriptor. */
+ struct hurd_fd *d2;
+
+ if (fd2 >= _hurd_dtablesize)
+ {
+ /* The table is not large enough to hold the destination
+ descriptor. Enlarge it as necessary to allocate this
+ descriptor. */
+ __mutex_unlock (&_hurd_dtable_lock);
+ /* We still hold FD1's lock, but this is safe because
+ _hurd_alloc_fd will only examine the cells starting
+ at FD2. */
+ d2 = _hurd_alloc_fd (NULL, fd2);
+ if (d2)
+ __spin_unlock (&d2->port.lock);
+ __mutex_lock (&_hurd_dtable_lock);
+ }
+ else
+ {
+ d2 = _hurd_dtable[fd2];
+ if (d2 == NULL)
+ {
+ /* Must allocate a new one. We don't initialize the port
+ cells with this call so that if it fails (out of
+ memory), we will not have already added user
+ references for the ports, which we would then have to
+ deallocate. */
+ d2 = _hurd_dtable[fd2] = _hurd_new_fd (MACH_PORT_NULL,
+ MACH_PORT_NULL);
+ }
+ }
+
+ if (d2 == NULL)
+ {
+ fd2 = -1;
+ if (errno == EINVAL)
+ errno = EBADF; /* POSIX.1-1990 6.2.1.2 ll 54-55. */
+ }
+ else
+ {
+ /* Give the ports each a user ref for the new descriptor. */
+ __mach_port_mod_refs (__mach_task_self (), port,
+ MACH_PORT_RIGHT_SEND, 1);
+ if (ctty != MACH_PORT_NULL)
+ __mach_port_mod_refs (__mach_task_self (), ctty,
+ MACH_PORT_RIGHT_SEND, 1);
+
+ /* Install the ports and flags in the new descriptor slot. */
+ __spin_lock (&d2->port.lock);
+ d2->flags = flags & ~FD_CLOEXEC; /* Dup clears FD_CLOEXEC. */
+ _hurd_port_set (&d2->ctty, ctty);
+ _hurd_port_locked_set (&d2->port, port); /* Unlocks D2. */
+ }
+ }
+ __mutex_unlock (&_hurd_dtable_lock);
+
+ _hurd_port_free (&d->port, &ulink, port);
+ if (ctty != MACH_PORT_NULL)
+ _hurd_port_free (&d->ctty, &ctty_ulink, port);
+ }
+
+ HURD_CRITICAL_END;
+
+ return fd2;
+}
+libc_hidden_def (__dup2)
+weak_alias (__dup2, dup2)
diff --git a/libc/sysdeps/mach/hurd/enbl-secure.c b/libc/sysdeps/mach/hurd/enbl-secure.c
new file mode 100644
index 000000000..19f724ca7
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/enbl-secure.c
@@ -0,0 +1,24 @@
+/* Define and initialize the `__libc_enable_secure' flag. Hurd version.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* There is no need for this file in the Hurd; it is just a placeholder
+ to prevent inclusion of the sysdeps/generic version.
+ In the shared library, the `__libc_enable_secure' variable is defined
+ by the dynamic linker in dl-sysdep.c and set there.
+ In the static library, it is defined in init-first.c and set there. */
diff --git a/libc/sysdeps/mach/hurd/err_hurd.sub b/libc/sysdeps/mach/hurd/err_hurd.sub
new file mode 100644
index 000000000..4a4dee3aa
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/err_hurd.sub
@@ -0,0 +1,12 @@
+/* This file defines the Mach error system for Hurd server errors. */
+
+#include <errno.h>
+
+extern const char *const _hurd_errlist[];
+
+/* Omit `const' because we are included with `static'
+ defined to `static const'. */
+static struct error_subsystem err_hurd_sub[] =
+ {
+ { "(os/hurd)", _HURD_ERRNOS, (const char *const *) _hurd_errlist },
+ };
diff --git a/libc/sysdeps/mach/hurd/errlist.c b/libc/sysdeps/mach/hurd/errlist.c
new file mode 100644
index 000000000..fe5709cf6
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/errlist.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1998,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* sys_errlist cannot have Unix semantics on the Hurd, so it is easier just
+ to rename it. We also need to remap error codes to array indices by
+ taking their subcode. */
+#define _sys_errlist_internal _hurd_errlist
+#define _sys_nerr_internal _hurd_nerr
+#define ERRLIST_NO_COMPAT 1
+
+#include <mach/error.h>
+#define ERR_REMAP(n) (err_get_code (n))
+
+#include <sysdeps/gnu/errlist.c>
diff --git a/libc/sysdeps/mach/hurd/errno-loc.c b/libc/sysdeps/mach/hurd/errno-loc.c
new file mode 100644
index 000000000..9ff09ebb6
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/errno-loc.c
@@ -0,0 +1,29 @@
+/* __errno_location -- helper function for locating per-thread errno value
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <hurd/threadvar.h>
+
+int *
+__errno_location (void)
+{
+ return (int *) __hurd_threadvar_location (_HURD_THREADVAR_ERRNO);
+}
+strong_alias (__errno_location, __hurd_errno_location)
+libc_hidden_def (__errno_location)
diff --git a/libc/sysdeps/mach/hurd/errno.c b/libc/sysdeps/mach/hurd/errno.c
new file mode 100644
index 000000000..a29091b5e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/errno.c
@@ -0,0 +1 @@
+/* No definition of `errno' variable on the Hurd. */
diff --git a/libc/sysdeps/mach/hurd/errnos.awk b/libc/sysdeps/mach/hurd/errnos.awk
new file mode 100644
index 000000000..cefa24f0a
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/errnos.awk
@@ -0,0 +1,169 @@
+# Copyright (C) 1991,92,93,94,95,96,97,2000,01,02
+# Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+# errno.texinfo contains lines like:
+# @comment errno.h
+# @comment POSIX.1: Function not implemented
+# @deftypevr Macro int ENOSYS
+# @comment errno 123
+
+BEGIN {
+ print "/* This file generated by errnos.awk. */";
+ print "";
+ print "/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */";
+ print "#ifndef _HURD_ERRNO";
+ print "#define _HURD_ERRNO(n)\t((0x10 << 26) | ((n) & 0x3fff))";
+ print "#endif";
+ print "";
+ print "#ifdef _ERRNO_H\n";
+ print "enum __error_t_codes\n{";
+ errnoh = 0;
+ maxerrno = 0;
+ in_mach_errors = "";
+ in_math = 0;
+ edom = erange = "";
+ print "#undef EDOM\n#undef ERANGE";
+ lno = 0;
+ }
+
+$1 == "@comment" && $2 == "errno.h" { errnoh=1; next }
+$1 == "@comment" && errnoh == 1 \
+ {
+ ++errnoh;
+ etext = "";
+ for (i = 3; i <= NF; ++i)
+ etext = etext " " $i;
+ next;
+ }
+
+errnoh == 2 && $1 == "@deftypevr" && $2 == "Macro" && $3 == "int" \
+ { ++errnoh; e = $4; next; }
+
+errnoh == 3 && $1 == "@comment" && $2 == "errno" {
+ if (e == "EWOULDBLOCK")
+ {
+ lines[lno++]="#define EWOULDBLOCK EAGAIN /* Operation would block */";
+ next;
+ }
+ errno = $3 + 0;
+ if (errno == 0)
+ next;
+ if (errno > maxerrno) maxerrno = errno;
+ x = sprintf ("%-40s/*%s */", sprintf ("%-24s%s", "#define\t" e,
+ "_HURD_ERRNO (" errno ")"),
+ etext);
+ if (e == "EDOM")
+ edom = x;
+ else if (e == "ERANGE")
+ erange = x;
+ comma[lno] = 1;
+ lines[lno++] = sprintf("\t%-16s= _HURD_ERRNO (%d)", e, errno);
+ lines[lno++] = x;
+ next;
+ }
+{ errnoh=0 }
+
+NF == 3 && $1 == "#define" && $2 == "MACH_SEND_IN_PROGRESS" \
+ {
+ in_mach_errors = FILENAME;
+ lines[lno++] = "\n\t/* Errors from <mach/message.h>. */";
+ }
+NF == 3 && $1 == "#define" && $2 == "KERN_SUCCESS" \
+ {
+ in_mach_errors = FILENAME;
+ lines[lno++] = "\n\t/* Errors from <mach/kern_return.h>. */";
+ next;
+ }
+
+in_mach_errors != "" && $2 == "MACH_IPC_COMPAT" \
+ {
+ in_mach_errors = "";
+ }
+
+in_mach_errors == FILENAME && NF == 3 && $1 == "#define" \
+ {
+ comma[lno] = 1;
+ lines[lno++] = sprintf("\t%-32s= %s", "E" $2, $3);
+ }
+
+$1 == "#define" && $2 == "_MACH_MIG_ERRORS_H_" \
+ {
+ in_mig_errors = 1;
+ lines[lno++] = "\n\t/* Errors from <mach/mig_errors.h>. */";
+ next;
+ }
+in_mig_errors && $1 == "#endif" && $3 == "_MACH_MIG_ERRORS_H_" \
+ {
+ in_mig_errors = 0;
+ }
+
+(in_mig_errors && $1 == "#define" && $3 <= -300) || \
+(in_device_errors && $1 == "#define" && /D_/ && NF > 3) \
+ {
+ comment = "";
+ for (i = 4; i <= NF; ++i)
+ comment = comment " " $i;
+ comma[lno] = 1;
+ lines[lno++] = sprintf("%-32s", sprintf ("\t%-24s= %s", "E" $2, $3)) comment;
+ }
+
+$1 == "#define" && $2 == "D_SUCCESS" \
+ {
+ in_device_errors = 1;
+ lines[lno++] = "\n\t/* Errors from <device/device_types.h>. */";
+ next;
+ }
+in_device_errors && $1 == "#endif" \
+ {
+ in_device_errors = 0;
+ }
+
+
+END \
+ {
+ for (i = 0; i < lno - 1; ++i)
+ printf "%s%s\n", lines[i], (comma[i] ? "," : "");
+ print lines[i];
+ print "";
+ print "};";
+ print "";
+ printf "#define\t_HURD_ERRNOS\t%d\n", maxerrno+1;
+ print "";
+ print "\
+/* User-visible type of error codes. It is ok to use `int' or\n\
+ `kern_return_t' for these, but with `error_t' the debugger prints\n\
+ symbolic values. */";
+ print "#ifdef __USE_GNU";
+ print "typedef enum __error_t_codes error_t;"
+ print "#define __error_t_defined\t1"
+ print "#endif";
+ print "";
+ print "\
+/* Return the current thread's location for `errno'.\n\
+ The syntax of this function allows redeclarations like `int errno'. */\n\
+extern int *__errno_location (void) __THROW __attribute__ ((__const__));\n\
+\n\
+#define errno (*__errno_location ())\n\
+";
+ print "#endif /* <errno.h> included. */";
+ print "";
+ print "#if !defined (_ERRNO_H) && defined (__need_Emath)";
+ print edom; print erange;
+ print "#endif /* <errno.h> not included and need math error codes. */";
+ }
diff --git a/libc/sysdeps/mach/hurd/euidaccess.c b/libc/sysdeps/mach/hurd/euidaccess.c
new file mode 100644
index 000000000..57f2a015c
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/euidaccess.c
@@ -0,0 +1,60 @@
+/* Test for access to FILE using effective UID and GID. Hurd version.
+ Copyright (C) 1991, 1995, 1997, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <hurd.h>
+
+int
+__euidaccess (file, type)
+ const char *file;
+ int type;
+{
+ error_t err;
+ file_t port;
+ int allowed, flags;
+
+ port = __file_name_lookup (file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+
+ /* Find out what types of access we are allowed to this file. */
+ err = __file_check_access (port, &allowed);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+
+ flags = 0;
+ if (type & R_OK)
+ flags |= O_READ;
+ if (type & W_OK)
+ flags |= O_WRITE;
+ if (type & X_OK)
+ flags |= O_EXEC;
+
+ if (flags & ~allowed)
+ /* We are not allowed all the requested types of access. */
+ return __hurd_fail (EACCES);
+
+ return 0;
+}
+weak_alias (__euidaccess, euidaccess)
+weak_alias (__euidaccess, eaccess)
diff --git a/libc/sysdeps/mach/hurd/execve.c b/libc/sysdeps/mach/hurd/execve.c
new file mode 100644
index 000000000..8af8b330b
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/execve.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <fcntl.h>
+
+/* Replace the current process, executing FILE_NAME with arguments ARGV and
+ environment ENVP. ARGV and ENVP are terminated by NULL pointers. */
+int
+__execve (file_name, argv, envp)
+ const char *file_name;
+ char *const argv[];
+ char *const envp[];
+{
+ error_t err;
+ file_t file = __file_name_lookup (file_name, O_EXEC, 0);
+
+ if (file == MACH_PORT_NULL)
+ return -1;
+
+ /* Hopefully this will not return. */
+ err = _hurd_exec (__mach_task_self (), file, argv, envp);
+
+ /* Oh well. Might as well be tidy. */
+ __mach_port_deallocate (__mach_task_self (), file);
+
+ return __hurd_fail (err);
+}
+
+weak_alias (__execve, execve)
diff --git a/libc/sysdeps/mach/hurd/faccessat.c b/libc/sysdeps/mach/hurd/faccessat.c
new file mode 100644
index 000000000..bb3c9fe19
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/faccessat.c
@@ -0,0 +1,70 @@
+/* Test for access to file, relative to open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+int
+faccessat (fd, file, type, flag)
+ int fd;
+ const char *file;
+ int type;
+ int flag;
+{
+ error_t err;
+ file_t port;
+ int allowed, flags;
+
+ if ((flag & AT_EACCESS) == 0)
+ {
+ if (fd == AT_FDCWD || file[0] == '/')
+ return __access (file, type);
+ __set_errno (ENOTSUP); /* XXX later */
+ return -1;
+ }
+
+ port = __file_name_lookup_at (fd, flag &~ AT_EACCESS, file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+
+ /* Find out what types of access we are allowed to this file. */
+ err = __file_check_access (port, &allowed);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+
+ flags = 0;
+ if (type & R_OK)
+ flags |= O_READ;
+ if (type & W_OK)
+ flags |= O_WRITE;
+ if (type & X_OK)
+ flags |= O_EXEC;
+
+ if (flags & ~allowed)
+ /* We are not allowed all the requested types of access. */
+ return __hurd_fail (EACCES);
+
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/fchdir.c b/libc/sysdeps/mach/hurd/fchdir.c
new file mode 100644
index 000000000..d1d4fc38e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fchdir.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <hurd/fd.h>
+
+/* Change the current directory to FD. */
+
+int
+__fchdir (fd)
+ int fd;
+{
+ return _hurd_change_directory_port_from_fd (&_hurd_ports[INIT_PORT_CWDIR],
+ fd);
+}
+weak_alias (__fchdir, fchdir)
diff --git a/libc/sysdeps/mach/hurd/fchflags.c b/libc/sysdeps/mach/hurd/fchflags.c
new file mode 100644
index 000000000..71bcbf0c9
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fchflags.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991, 92, 93, 94, 97, 98 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the flags of the file FD refers to to FLAGS. */
+
+/* XXX should be __fchflags? */
+int
+fchflags (int fd, int flags)
+{
+ error_t err;
+
+ if (err = HURD_DPORT_USE (fd, __file_chflags (port, flags)))
+ return __hurd_dfail (fd, err);
+
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/fchmod.c b/libc/sysdeps/mach/hurd/fchmod.c
new file mode 100644
index 000000000..025b09200
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fchmod.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1991, 1992, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the protections of the file FD refers to to MODE. */
+int
+__fchmod (fd, mode)
+ int fd;
+ mode_t mode;
+{
+ error_t err;
+
+ if (err = HURD_DPORT_USE (fd, __file_chmod (port, mode)))
+ return __hurd_dfail (fd, err);
+
+ return 0;
+}
+
+weak_alias (__fchmod, fchmod)
diff --git a/libc/sysdeps/mach/hurd/fchmodat.c b/libc/sysdeps/mach/hurd/fchmodat.c
new file mode 100644
index 000000000..d27e84527
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fchmodat.c
@@ -0,0 +1,44 @@
+/* Change the protections of file relative to open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+int
+fchmodat (fd, file, mode, flag)
+ int fd;
+ const char *file;
+ mode_t mode;
+ int flag;
+{
+ error_t err;
+ file_t port = __file_name_lookup_at (fd, flag, file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_chmod (port, mode);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/fchown.c b/libc/sysdeps/mach/hurd/fchown.c
new file mode 100644
index 000000000..3286e24bc
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fchown.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the owner and group of the file referred to by FD. */
+int
+__fchown (fd, owner, group)
+ int fd;
+ uid_t owner;
+ gid_t group;
+{
+ error_t err;
+
+ if (err = HURD_DPORT_USE (fd, __file_chown (port, owner, group)))
+ return __hurd_dfail (fd, err);
+
+ return 0;
+}
+
+weak_alias (__fchown, fchown)
diff --git a/libc/sysdeps/mach/hurd/fchownat.c b/libc/sysdeps/mach/hurd/fchownat.c
new file mode 100644
index 000000000..1b99b2927
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fchownat.c
@@ -0,0 +1,46 @@
+/* Change owner and group of a file relative to open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the owner and group of FILE. */
+int
+fchownat (fd, file, owner, group, flag)
+ int fd;
+ const char *file;
+ uid_t owner;
+ gid_t group;
+ int flag;
+{
+ error_t err;
+ file_t port = __file_name_lookup_at (fd, flag, file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_chown (port, owner, group);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/fcntl.c b/libc/sysdeps/mach/hurd/fcntl.c
new file mode 100644
index 000000000..d4e4aa5da
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fcntl.c
@@ -0,0 +1,207 @@
+/* Copyright (C) 1992-1997,1999,2000,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <stdarg.h>
+#include <sys/file.h> /* XXX for LOCK_* */
+
+/* Perform file control operations on FD. */
+int
+__libc_fcntl (int fd, int cmd, ...)
+{
+ va_list ap;
+ struct hurd_fd *d;
+ int result;
+
+ d = _hurd_fd_get (fd);
+
+ if (d == NULL)
+ return __hurd_fail (EBADF);
+
+ va_start (ap, cmd);
+
+ switch (cmd)
+ {
+ error_t err;
+
+ default: /* Bad command. */
+ errno = EINVAL;
+ result = -1;
+ break;
+
+ /* First the descriptor-based commands, which do no RPCs. */
+
+ case F_DUPFD: /* Duplicate the file descriptor. */
+ {
+ struct hurd_fd *new;
+ io_t port, ctty;
+ struct hurd_userlink ulink, ctty_ulink;
+ int flags;
+
+ HURD_CRITICAL_BEGIN;
+
+ /* Extract the ports and flags from the file descriptor. */
+ __spin_lock (&d->port.lock);
+ flags = d->flags;
+ ctty = _hurd_port_get (&d->ctty, &ctty_ulink);
+ port = _hurd_port_locked_get (&d->port, &ulink); /* Unlocks D. */
+
+ /* Get a new file descriptor. The third argument to __fcntl is the
+ minimum file descriptor number for it. */
+ new = _hurd_alloc_fd (&result, va_arg (ap, int));
+ if (new == NULL)
+ /* _hurd_alloc_fd has set errno. */
+ result = -1;
+ else
+ {
+ /* Give the ports each a user ref for the new descriptor. */
+ __mach_port_mod_refs (__mach_task_self (), port,
+ MACH_PORT_RIGHT_SEND, 1);
+ if (ctty != MACH_PORT_NULL)
+ __mach_port_mod_refs (__mach_task_self (), ctty,
+ MACH_PORT_RIGHT_SEND, 1);
+
+ /* Install the ports and flags in the new descriptor. */
+ if (ctty != MACH_PORT_NULL)
+ _hurd_port_set (&new->ctty, ctty);
+ /* Duplication clears the FD_CLOEXEC flag. */
+ new->flags = flags & ~FD_CLOEXEC;
+ _hurd_port_locked_set (&new->port, port); /* Unlocks NEW. */
+ }
+
+ HURD_CRITICAL_END;
+
+ _hurd_port_free (&d->port, &ulink, port);
+ if (ctty != MACH_PORT_NULL)
+ _hurd_port_free (&d->ctty, &ctty_ulink, port);
+
+ break;
+ }
+
+ /* Set RESULT by evaluating EXPR with the descriptor locked.
+ Check for an empty descriptor and return EBADF. */
+#define LOCKED(expr) \
+ HURD_CRITICAL_BEGIN; \
+ __spin_lock (&d->port.lock); \
+ if (d->port.port == MACH_PORT_NULL) \
+ result = __hurd_fail (EBADF); \
+ else \
+ result = (expr); \
+ __spin_unlock (&d->port.lock); \
+ HURD_CRITICAL_END;
+
+ case F_GETFD: /* Get descriptor flags. */
+ LOCKED (d->flags);
+ break;
+
+ case F_SETFD: /* Set descriptor flags. */
+ LOCKED ((d->flags = va_arg (ap, int), 0));
+ break;
+
+
+ /* Now the real io operations, done by RPCs to io servers. */
+
+ case F_GETLK:
+ case F_SETLK:
+ case F_SETLKW:
+ {
+ /* XXX
+ We need new RPCs to support POSIX.1 fcntl file locking!!
+ For the time being we support the whole-file case only,
+ with all kinds of WRONG WRONG WRONG semantics,
+ by using flock. This is definitely the Wrong Thing,
+ but it might be better than nothing (?). */
+ struct flock *fl = va_arg (ap, struct flock *);
+ va_end (ap);
+ switch (cmd)
+ {
+ case F_GETLK:
+ errno = ENOSYS;
+ return -1;
+ case F_SETLK:
+ cmd = LOCK_NB;
+ break;
+ default:
+ cmd = 0;
+ break;
+ }
+ switch (fl->l_type)
+ {
+ case F_RDLCK: cmd |= LOCK_SH; break;
+ case F_WRLCK: cmd |= LOCK_EX; break;
+ case F_UNLCK: cmd |= LOCK_UN; break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ switch (fl->l_whence)
+ {
+ case SEEK_SET:
+ if (fl->l_start == 0 && fl->l_len == 0) /* Whole file request. */
+ break;
+ /* It seems to be common for applications to lock the first
+ byte of the file when they are really doing whole-file locking.
+ So, since it's so wrong already, might as well do that too. */
+ if (fl->l_start == 0 && fl->l_len == 1)
+ break;
+ /* FALLTHROUGH */
+ case SEEK_CUR:
+ case SEEK_END:
+ errno = ENOTSUP;
+ return -1;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ return __flock (fd, cmd);
+ }
+
+ case F_GETFL: /* Get per-open flags. */
+ if (err = HURD_FD_PORT_USE (d, __io_get_openmodes (port, &result)))
+ result = __hurd_dfail (fd, err);
+ break;
+
+ case F_SETFL: /* Set per-open flags. */
+ err = HURD_FD_PORT_USE (d, __io_set_all_openmodes (port,
+ va_arg (ap, int)));
+ result = err ? __hurd_dfail (fd, err) : 0;
+ break;
+
+ case F_GETOWN: /* Get owner. */
+ if (err = HURD_FD_PORT_USE (d, __io_get_owner (port, &result)))
+ result = __hurd_dfail (fd, err);
+ break;
+
+ case F_SETOWN: /* Set owner. */
+ err = HURD_FD_PORT_USE (d, __io_mod_owner (port, va_arg (ap, pid_t)));
+ result = err ? __hurd_dfail (fd, err) : 0;
+ break;
+ }
+
+ va_end (ap);
+
+ return result;
+}
+libc_hidden_def (__libc_fcntl)
+weak_alias (__libc_fcntl, __fcntl)
+libc_hidden_weak (__fcntl)
+weak_alias (__libc_fcntl, fcntl)
diff --git a/libc/sysdeps/mach/hurd/fdatasync.c b/libc/sysdeps/mach/hurd/fdatasync.c
new file mode 100644
index 000000000..4546cb9ed
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fdatasync.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991, 92, 93, 94, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Make all changes done to FD's file data actually appear on disk. */
+int
+fdatasync (int fd)
+{
+ error_t err = HURD_DPORT_USE (fd, __file_sync (port, 1, 1));
+ if (err)
+ return __hurd_dfail (fd, err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/fdopendir.c b/libc/sysdeps/mach/hurd/fdopendir.c
new file mode 100644
index 000000000..016f825f1
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fdopendir.c
@@ -0,0 +1,58 @@
+/* Open a directory stream from a file descriptor. Hurd version.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dirent.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <fcntl.h>
+
+DIR *_hurd_fd_opendir (struct hurd_fd *d); /* opendir.c */
+
+/* Open a directory stream on FD. */
+DIR *
+__fdopendir (int fd)
+{
+ struct hurd_fd *d = _hurd_fd_get (fd);
+
+ if (d == NULL)
+ {
+ errno = EBADF;
+ return NULL;
+ }
+
+ /* Ensure that it's a directory. */
+ error_t err = HURD_FD_PORT_USE
+ (d, ({
+ file_t dir = __file_name_lookup_under (port, "/",
+ O_DIRECTORY | O_NOTRANS, 0);;
+ if (dir != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), dir);
+ dir != MACH_PORT_NULL ? 0 : errno;
+ }));
+
+ if (err)
+ {
+ errno = err;
+ return NULL;
+ }
+
+ return _hurd_fd_opendir (d);
+}
+weak_alias (__fdopendir, fdopendir)
diff --git a/libc/sysdeps/mach/hurd/fexecve.c b/libc/sysdeps/mach/hurd/fexecve.c
new file mode 100644
index 000000000..d6eb7c09a
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fexecve.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <errno.h>
+
+/* Execute the file FD refers to, overlaying the running program image. */
+
+int
+fexecve (int fd, char *const argv[], char *const envp[])
+{
+ error_t err = HURD_DPORT_USE (fd, _hurd_exec (__mach_task_self (), port,
+ argv, envp));
+ if (! err)
+ err = EGRATUITOUS;
+ return __hurd_fail (err);
+}
diff --git a/libc/sysdeps/mach/hurd/fgetxattr.c b/libc/sysdeps/mach/hurd/fgetxattr.c
new file mode 100644
index 000000000..2eb6db06c
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fgetxattr.c
@@ -0,0 +1,34 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <hurd/fd.h>
+
+ssize_t
+fgetxattr (int fd, const char *name, void *value, size_t size)
+{
+ error_t err;
+
+ err = HURD_DPORT_USE (fd, _hurd_xattr_get (port, name, value, &size));
+
+ return err ? __hurd_dfail (fd, err) : size;
+}
diff --git a/libc/sysdeps/mach/hurd/flistxattr.c b/libc/sysdeps/mach/hurd/flistxattr.c
new file mode 100644
index 000000000..a577e4e39
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/flistxattr.c
@@ -0,0 +1,34 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <hurd/fd.h>
+
+ssize_t
+flistxattr (int fd, char *list, size_t size)
+{
+ error_t err;
+
+ err = HURD_DPORT_USE (fd, _hurd_xattr_list (port, list, &size));
+
+ return err ? __hurd_dfail (fd, err) : size;
+}
diff --git a/libc/sysdeps/mach/hurd/flock.c b/libc/sysdeps/mach/hurd/flock.c
new file mode 100644
index 000000000..d3a518a3b
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/flock.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1992, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/file.h>
+#include <hurd/fd.h>
+#include <hurd/fs.h>
+
+/* Apply or remove an advisory lock, according to OPERATION,
+ on the file FD refers to. */
+int
+__flock (fd, operation)
+ int fd;
+ int operation;
+{
+ error_t err;
+
+ if (err = HURD_DPORT_USE (fd, __file_lock (port, operation)))
+ return __hurd_dfail (fd, err);
+
+ return 0;
+}
+
+weak_alias (__flock, flock)
diff --git a/libc/sysdeps/mach/hurd/fork.c b/libc/sysdeps/mach/hurd/fork.c
new file mode 100644
index 000000000..fa7da6020
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fork.c
@@ -0,0 +1,706 @@
+/* Copyright (C) 1994,1995,1996,1997,1999,2001,2002,2004,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <setjmp.h>
+#include <thread_state.h>
+#include <sysdep.h> /* For stack growth direction. */
+#include "set-hooks.h"
+#include <assert.h>
+#include "hurdmalloc.h" /* XXX */
+#include <tls.h>
+
+#undef __fork
+
+
+/* Things that want to be locked while forking. */
+symbol_set_declare (_hurd_fork_locks)
+
+
+/* Things that want to be called before we fork, to prepare the parent for
+ task_create, when the new child task will inherit our address space. */
+DEFINE_HOOK (_hurd_fork_prepare_hook, (void));
+
+/* Things that want to be called when we are forking, with the above all
+ locked. They are passed the task port of the child. The child process
+ is all set up except for doing proc_child, and has no threads yet. */
+DEFINE_HOOK (_hurd_fork_setup_hook, (void));
+
+/* Things to be run in the child fork. */
+DEFINE_HOOK (_hurd_fork_child_hook, (void));
+
+/* Things to be run in the parent fork. */
+DEFINE_HOOK (_hurd_fork_parent_hook, (void));
+
+
+/* Clone the calling process, creating an exact copy.
+ Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+pid_t
+__fork (void)
+{
+ jmp_buf env;
+ pid_t pid;
+ size_t i;
+ error_t err;
+ struct hurd_sigstate *volatile ss;
+
+ ss = _hurd_self_sigstate ();
+ __spin_lock (&ss->critical_section_lock);
+
+#undef LOSE
+#define LOSE do { assert_perror (err); goto lose; } while (0) /* XXX */
+
+ if (! setjmp (env))
+ {
+ process_t newproc;
+ task_t newtask;
+ thread_t thread, sigthread;
+ mach_port_urefs_t thread_refs, sigthread_refs;
+ struct machine_thread_state state;
+ mach_msg_type_number_t statecount;
+ mach_port_t *portnames = NULL;
+ mach_msg_type_number_t nportnames = 0;
+ mach_port_type_t *porttypes = NULL;
+ mach_msg_type_number_t nporttypes = 0;
+ thread_t *threads = NULL;
+ mach_msg_type_number_t nthreads = 0;
+ int ports_locked = 0, stopped = 0;
+
+ void resume_threads (void)
+ {
+ if (! stopped)
+ return;
+
+ assert (threads);
+
+ for (i = 0; i < nthreads; ++i)
+ if (threads[i] != ss->thread)
+ __thread_resume (threads[i]);
+ stopped = 0;
+ }
+
+ /* Run things that prepare for forking before we create the task. */
+ RUN_HOOK (_hurd_fork_prepare_hook, ());
+
+ /* Lock things that want to be locked before we fork. */
+ {
+ void *const *p;
+ for (p = symbol_set_first_element (_hurd_fork_locks);
+ ! symbol_set_end_p (_hurd_fork_locks, p);
+ ++p)
+ __mutex_lock (*p);
+ }
+ __mutex_lock (&_hurd_siglock);
+
+ newtask = MACH_PORT_NULL;
+ thread = sigthread = MACH_PORT_NULL;
+ newproc = MACH_PORT_NULL;
+
+ /* Lock all the port cells for the standard ports while we copy the
+ address space. We want to insert all the send rights into the
+ child with the same names. */
+ for (i = 0; i < _hurd_nports; ++i)
+ __spin_lock (&_hurd_ports[i].lock);
+ ports_locked = 1;
+
+
+ /* Stop all other threads while copying the address space,
+ so nothing changes. */
+ err = __proc_dostop (_hurd_ports[INIT_PORT_PROC].port, ss->thread);
+ if (!err)
+ {
+ stopped = 1;
+
+#define XXX_KERNEL_PAGE_FAULT_BUG /* XXX work around page fault bug in mk */
+
+#ifdef XXX_KERNEL_PAGE_FAULT_BUG
+ /* Gag me with a pitchfork.
+ The bug scenario is this:
+
+ - The page containing __mach_task_self_ is paged out.
+ - The signal thread was faulting on that page when we
+ suspended it via proc_dostop. It holds some lock, or set
+ some busy bit, or somesuch.
+ - Now this thread faults on that same page.
+ - GRATUIOUS DEADLOCK
+
+ We can break the deadlock by aborting the thread that faulted
+ first, which if the bug happened was the signal thread because
+ it is the only other thread and we just suspended it.
+ */
+ __thread_abort (_hurd_msgport_thread);
+#endif
+ /* Create the child task. It will inherit a copy of our memory. */
+ err = __task_create (__mach_task_self (),
+#ifdef KERN_INVALID_LEDGER
+ NULL, 0, /* OSF Mach */
+#endif
+ 1, &newtask);
+ }
+
+ /* Unlock the global signal state lock, so we do not
+ block the signal thread any longer than necessary. */
+ __mutex_unlock (&_hurd_siglock);
+
+ if (err)
+ LOSE;
+
+ /* Fetch the names of all ports used in this task. */
+ if (err = __mach_port_names (__mach_task_self (),
+ &portnames, &nportnames,
+ &porttypes, &nporttypes))
+ LOSE;
+ if (nportnames != nporttypes)
+ {
+ err = EGRATUITOUS;
+ LOSE;
+ }
+
+ /* Get send rights for all the threads in this task.
+ We want to avoid giving these rights to the child. */
+ if (err = __task_threads (__mach_task_self (), &threads, &nthreads))
+ LOSE;
+
+ /* Get the child process's proc server port. We will insert it into
+ the child with the same name as we use for our own proc server
+ port; and we will need it to set the child's message port. */
+ if (err = __proc_task2proc (_hurd_ports[INIT_PORT_PROC].port,
+ newtask, &newproc))
+ LOSE;
+
+ /* Insert all our port rights into the child task. */
+ thread_refs = sigthread_refs = 0;
+ for (i = 0; i < nportnames; ++i)
+ {
+ if (porttypes[i] & MACH_PORT_TYPE_RECEIVE)
+ {
+ /* This is a receive right. We want to give the child task
+ its own new receive right under the same name. */
+ err = __mach_port_allocate_name (newtask,
+ MACH_PORT_RIGHT_RECEIVE,
+ portnames[i]);
+ if (err == KERN_NAME_EXISTS)
+ {
+ /* It already has a right under this name (?!). Well,
+ there is this bizarre old Mach IPC feature (in #ifdef
+ MACH_IPC_COMPAT in the ukernel) which results in new
+ tasks getting a new receive right for task special
+ port number 2. What else might be going on I'm not
+ sure. So let's check. */
+#if !MACH_IPC_COMPAT
+#define TASK_NOTIFY_PORT 2
+#endif
+ assert (({ mach_port_t thisport, notify_port;
+ mach_msg_type_name_t poly;
+ (__task_get_special_port (newtask,
+ TASK_NOTIFY_PORT,
+ &notify_port) == 0 &&
+ __mach_port_extract_right
+ (newtask,
+ portnames[i],
+ MACH_MSG_TYPE_MAKE_SEND,
+ &thisport, &poly) == 0 &&
+ (thisport == notify_port) &&
+ __mach_port_deallocate (__mach_task_self (),
+ thisport) == 0 &&
+ __mach_port_deallocate (__mach_task_self (),
+ notify_port) == 0);
+ }));
+ }
+ else if (err)
+ LOSE;
+ if (porttypes[i] & MACH_PORT_TYPE_SEND)
+ {
+ /* Give the child as many send rights for its receive
+ right as we have for ours. */
+ mach_port_urefs_t refs;
+ mach_port_t port;
+ mach_msg_type_name_t poly;
+ if (err = __mach_port_get_refs (__mach_task_self (),
+ portnames[i],
+ MACH_PORT_RIGHT_SEND,
+ &refs))
+ LOSE;
+ if (err = __mach_port_extract_right (newtask,
+ portnames[i],
+ MACH_MSG_TYPE_MAKE_SEND,
+ &port, &poly))
+ LOSE;
+ if (portnames[i] == _hurd_msgport)
+ {
+ /* We just created a receive right for the child's
+ message port and are about to insert send rights
+ for it. Now, while we happen to have a send right
+ for it, give it to the proc server. */
+ mach_port_t old;
+ if (err = __proc_setmsgport (newproc, port, &old))
+ LOSE;
+ if (old != MACH_PORT_NULL)
+ /* XXX what to do here? */
+ __mach_port_deallocate (__mach_task_self (), old);
+ /* The new task will receive its own exceptions
+ on its message port. */
+ if (err =
+#ifdef TASK_EXCEPTION_PORT
+ __task_set_special_port (newtask,
+ TASK_EXCEPTION_PORT,
+ port)
+#elif defined (EXC_MASK_ALL)
+ __task_set_exception_ports
+ (newtask, EXC_MASK_ALL & ~(EXC_MASK_SYSCALL
+ | EXC_MASK_MACH_SYSCALL
+ | EXC_MASK_RPC_ALERT),
+ port, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE)
+#else
+# error task_set_exception_port?
+#endif
+ )
+ LOSE;
+ }
+ if (err = __mach_port_insert_right (newtask,
+ portnames[i],
+ port,
+ MACH_MSG_TYPE_MOVE_SEND))
+ LOSE;
+ if (refs > 1 &&
+ (err = __mach_port_mod_refs (newtask,
+ portnames[i],
+ MACH_PORT_RIGHT_SEND,
+ refs - 1)))
+ LOSE;
+ }
+ if (porttypes[i] & MACH_PORT_TYPE_SEND_ONCE)
+ {
+ /* Give the child a send-once right for its receive right,
+ since we have one for ours. */
+ mach_port_t port;
+ mach_msg_type_name_t poly;
+ if (err = __mach_port_extract_right
+ (newtask,
+ portnames[i],
+ MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ &port, &poly))
+ LOSE;
+ if (err = __mach_port_insert_right
+ (newtask,
+ portnames[i], port,
+ MACH_MSG_TYPE_MOVE_SEND_ONCE))
+ LOSE;
+ }
+ }
+ else if (porttypes[i] &
+ (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_DEAD_NAME))
+ {
+ /* This is a send right or a dead name.
+ Give the child as many references for it as we have. */
+ mach_port_urefs_t refs, *record_refs = NULL;
+ mach_port_t insert;
+ mach_msg_type_name_t insert_type = MACH_MSG_TYPE_COPY_SEND;
+ if (portnames[i] == newtask || portnames[i] == newproc)
+ /* Skip the name we use for the child's task or proc ports. */
+ continue;
+ if (portnames[i] == __mach_task_self ())
+ /* For the name we use for our own task port,
+ insert the child's task port instead. */
+ insert = newtask;
+ else if (portnames[i] == _hurd_ports[INIT_PORT_PROC].port)
+ {
+ /* Use the proc server port for the new task. */
+ insert = newproc;
+ insert_type = MACH_MSG_TYPE_COPY_SEND;
+ }
+ else if (portnames[i] == ss->thread)
+ {
+ /* For the name we use for our own thread port, we will
+ insert the thread port for the child main user thread
+ after we create it. */
+ insert = MACH_PORT_NULL;
+ record_refs = &thread_refs;
+ /* Allocate a dead name right for this name as a
+ placeholder, so the kernel will not chose this name
+ for any other new port (it might use it for one of the
+ rights created when a thread is created). */
+ if (err = __mach_port_allocate_name
+ (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i]))
+ LOSE;
+ }
+ else if (portnames[i] == _hurd_msgport_thread)
+ /* For the name we use for our signal thread's thread port,
+ we will insert the thread port for the child's signal
+ thread after we create it. */
+ {
+ insert = MACH_PORT_NULL;
+ record_refs = &sigthread_refs;
+ /* Allocate a dead name right as a placeholder. */
+ if (err = __mach_port_allocate_name
+ (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i]))
+ LOSE;
+ }
+ else
+ {
+ /* Skip the name we use for any of our own thread ports. */
+ mach_msg_type_number_t j;
+ for (j = 0; j < nthreads; ++j)
+ if (portnames[i] == threads[j])
+ break;
+ if (j < nthreads)
+ continue;
+
+ /* Copy our own send right. */
+ insert = portnames[i];
+ }
+ /* Find out how many user references we have for
+ the send right with this name. */
+ if (err = __mach_port_get_refs (__mach_task_self (),
+ portnames[i],
+ MACH_PORT_RIGHT_SEND,
+ record_refs ?: &refs))
+ LOSE;
+ if (insert == MACH_PORT_NULL)
+ continue;
+ if (insert == portnames[i] &&
+ (porttypes[i] & MACH_PORT_TYPE_DEAD_NAME))
+ /* This is a dead name; allocate another dead name
+ with the same name in the child. */
+ allocate_dead_name:
+ err = __mach_port_allocate_name (newtask,
+ MACH_PORT_RIGHT_DEAD_NAME,
+ portnames[i]);
+ else
+ /* Insert the chosen send right into the child. */
+ err = __mach_port_insert_right (newtask,
+ portnames[i],
+ insert, insert_type);
+ switch (err)
+ {
+ case KERN_NAME_EXISTS:
+ {
+ /* It already has a send right under this name (?!).
+ Well, it starts out with a send right for its task
+ port, and inherits the bootstrap and exception ports
+ from us. */
+ mach_port_t childport;
+ mach_msg_type_name_t poly;
+ assert (__mach_port_extract_right (newtask, portnames[i],
+ MACH_MSG_TYPE_COPY_SEND,
+ &childport,
+ &poly) == 0 &&
+ childport == insert &&
+ __mach_port_deallocate (__mach_task_self (),
+ childport) == 0);
+ break;
+ }
+
+ case KERN_INVALID_CAPABILITY:
+ /* The port just died. It was a send right,
+ and now it's a dead name. */
+ goto allocate_dead_name;
+
+ default:
+ LOSE;
+ break;
+
+ case KERN_SUCCESS:
+ /* Give the child as many user references as we have. */
+ if (refs > 1 &&
+ (err = __mach_port_mod_refs (newtask,
+ portnames[i],
+ MACH_PORT_RIGHT_SEND,
+ refs - 1)))
+ LOSE;
+ }
+ }
+ }
+
+ /* Unlock the standard port cells. The child must unlock its own
+ copies too. */
+ for (i = 0; i < _hurd_nports; ++i)
+ __spin_unlock (&_hurd_ports[i].lock);
+ ports_locked = 0;
+
+ /* All state has now been copied from the parent. It is safe to
+ resume other parent threads. */
+ resume_threads ();
+
+ /* Create the child main user thread and signal thread. */
+ if ((err = __thread_create (newtask, &thread)) ||
+ (err = __thread_create (newtask, &sigthread)))
+ LOSE;
+
+ /* Insert send rights for those threads. We previously allocated
+ dead name rights with the names we want to give the thread ports
+ in the child as placeholders. Now deallocate them so we can use
+ the names. */
+ if ((err = __mach_port_deallocate (newtask, ss->thread)) ||
+ (err = __mach_port_insert_right (newtask, ss->thread,
+ thread, MACH_MSG_TYPE_COPY_SEND)))
+ LOSE;
+ /* We have one extra user reference created at the beginning of this
+ function, accounted for by mach_port_names (and which will thus be
+ accounted for in the child below). This extra right gets consumed
+ in the child by the store into _hurd_sigthread in the child fork. */
+ if (thread_refs > 1 &&
+ (err = __mach_port_mod_refs (newtask, ss->thread,
+ MACH_PORT_RIGHT_SEND,
+ thread_refs)))
+ LOSE;
+ if ((_hurd_msgport_thread != MACH_PORT_NULL) /* Let user have none. */
+ && ((err = __mach_port_deallocate (newtask, _hurd_msgport_thread)) ||
+ (err = __mach_port_insert_right (newtask, _hurd_msgport_thread,
+ sigthread,
+ MACH_MSG_TYPE_COPY_SEND))))
+ LOSE;
+ if (sigthread_refs > 1 &&
+ (err = __mach_port_mod_refs (newtask, _hurd_msgport_thread,
+ MACH_PORT_RIGHT_SEND,
+ sigthread_refs - 1)))
+ LOSE;
+
+ /* This seems like a convenient juncture to copy the proc server's
+ idea of what addresses our argv and envp are found at from the
+ parent into the child. Since we happen to know that the child
+ shares our memory image, it is we who should do this copying. */
+ {
+ vm_address_t argv, envp;
+ err = (__USEPORT (PROC, __proc_get_arg_locations (port, &argv, &envp))
+ ?: __proc_set_arg_locations (newproc, argv, envp));
+ if (err)
+ LOSE;
+ }
+
+ /* Set the child signal thread up to run the msgport server function
+ using the same signal thread stack copied from our address space.
+ We fetch the state before longjmp'ing it so that miscellaneous
+ registers not affected by longjmp (such as i386 segment registers)
+ are in their normal default state. */
+ statecount = MACHINE_THREAD_STATE_COUNT;
+ if (err = __thread_get_state (_hurd_msgport_thread,
+ MACHINE_THREAD_STATE_FLAVOR,
+ (natural_t *) &state, &statecount))
+ LOSE;
+#if STACK_GROWTH_UP
+#define THREADVAR_SPACE (__hurd_threadvar_max \
+ * sizeof *__hurd_sightread_variables)
+ if (__hurd_sigthread_stack_base == 0)
+ {
+ state.SP &= __hurd_threadvar_stack_mask;
+ state.SP += __hurd_threadvar_stack_offset + THREADVAR_SPACE;
+ }
+ else
+ state.SP = __hurd_sigthread_stack_base;
+#else
+ if (__hurd_sigthread_stack_end == 0)
+ {
+ /* The signal thread has a normal stack assigned by cthreads.
+ The threadvar_stack variables conveniently tell us how
+ to get to the highest address in the stack, just below
+ the per-thread variables. */
+ state.SP &= __hurd_threadvar_stack_mask;
+ state.SP += __hurd_threadvar_stack_offset;
+ }
+ else
+ state.SP = __hurd_sigthread_stack_end;
+#endif
+ MACHINE_THREAD_STATE_SET_PC (&state,
+ (unsigned long int) _hurd_msgport_receive);
+ if (err = __thread_set_state (sigthread, MACHINE_THREAD_STATE_FLAVOR,
+ (natural_t *) &state, statecount))
+ LOSE;
+ /* We do not thread_resume SIGTHREAD here because the child
+ fork needs to do more setup before it can take signals. */
+
+ /* Set the child user thread up to return 1 from the setjmp above. */
+ _hurd_longjmp_thread_state (&state, env, 1);
+
+#if USE_TLS
+ /* Do special thread setup for TLS if needed. */
+ if (err = _hurd_tls_fork (thread, &state))
+ LOSE;
+#endif
+
+ if (err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
+ (natural_t *) &state, statecount))
+ LOSE;
+
+ /* Get the PID of the child from the proc server. We must do this
+ before calling proc_child below, because at that point any
+ authorized POSIX.1 process may kill the child task with SIGKILL. */
+ if (err = __USEPORT (PROC, __proc_task2pid (port, newtask, &pid)))
+ LOSE;
+
+ /* Register the child with the proc server. It is important that
+ this be that last thing we do before starting the child thread
+ running. Once proc_child has been done for the task, it appears
+ as a POSIX.1 process. Any errors we get must be detected before
+ this point, and the child must have a message port so it responds
+ to POSIX.1 signals. */
+ if (err = __USEPORT (PROC, __proc_child (port, newtask)))
+ LOSE;
+
+ /* This must be the absolutely last thing we do; we can't assume that
+ the child will remain alive for even a moment once we do this. We
+ ignore errors because we have committed to the fork and are not
+ allowed to return them after the process becomes visible to
+ POSIX.1 (which happened right above when we called proc_child). */
+ (void) __thread_resume (thread);
+
+ lose:
+ if (ports_locked)
+ for (i = 0; i < _hurd_nports; ++i)
+ __spin_unlock (&_hurd_ports[i].lock);
+
+ resume_threads ();
+
+ if (newtask != MACH_PORT_NULL)
+ {
+ if (err)
+ __task_terminate (newtask);
+ __mach_port_deallocate (__mach_task_self (), newtask);
+ }
+ if (thread != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), thread);
+ if (sigthread != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), sigthread);
+ if (newproc != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), newproc);
+
+ if (portnames)
+ __vm_deallocate (__mach_task_self (),
+ (vm_address_t) portnames,
+ nportnames * sizeof (*portnames));
+ if (porttypes)
+ __vm_deallocate (__mach_task_self (),
+ (vm_address_t) porttypes,
+ nporttypes * sizeof (*porttypes));
+ if (threads)
+ {
+ for (i = 0; i < nthreads; ++i)
+ __mach_port_deallocate (__mach_task_self (), threads[i]);
+ __vm_deallocate (__mach_task_self (),
+ (vm_address_t) threads,
+ nthreads * sizeof (*threads));
+ }
+
+ /* Run things that want to run in the parent to restore it to
+ normality. Usually prepare hooks and parent hooks are
+ symmetrical: the prepare hook arrests state in some way for the
+ fork, and the parent hook restores the state for the parent to
+ continue executing normally. */
+ RUN_HOOK (_hurd_fork_parent_hook, ());
+ }
+ else
+ {
+ struct hurd_sigstate *oldstates;
+
+ /* We are the child task. Unlock the standard port cells, which were
+ locked in the parent when we copied its memory. The parent has
+ inserted send rights with the names that were in the cells then. */
+ for (i = 0; i < _hurd_nports; ++i)
+ __spin_unlock (&_hurd_ports[i].lock);
+
+ /* We are one of the (exactly) two threads in this new task, we
+ will take the task-global signals. */
+ _hurd_sigthread = ss->thread;
+
+ /* Claim our sigstate structure and unchain the rest: the
+ threads existed in the parent task but don't exist in this
+ task (the child process). Delay freeing them until later
+ because some of the further setup and unlocking might be
+ required for free to work. Before we finish cleaning up,
+ we will reclaim the signal thread's sigstate structure (if
+ it had one). */
+ oldstates = _hurd_sigstates;
+ if (oldstates == ss)
+ oldstates = ss->next;
+ else
+ {
+ while (_hurd_sigstates->next != ss)
+ _hurd_sigstates = _hurd_sigstates->next;
+ _hurd_sigstates->next = ss->next;
+ }
+ ss->next = NULL;
+ _hurd_sigstates = ss;
+ __mutex_unlock (&_hurd_siglock);
+
+ /* Fetch our new process IDs from the proc server. No need to
+ refetch our pgrp; it is always inherited from the parent (so
+ _hurd_pgrp is already correct), and the proc server will send us a
+ proc_newids notification when it changes. */
+ err = __USEPORT (PROC, __proc_getpids (port, &_hurd_pid, &_hurd_ppid,
+ &_hurd_orphaned));
+
+ /* Forking clears the trace flag. */
+ __sigemptyset (&_hurdsig_traced);
+
+ /* Run things that want to run in the child task to set up. */
+ RUN_HOOK (_hurd_fork_child_hook, ());
+
+ /* Set up proc server-assisted fault recovery for the signal thread. */
+ _hurdsig_fault_init ();
+
+ /* Start the signal thread listening on the message port. */
+ if (!err)
+ err = __thread_resume (_hurd_msgport_thread);
+
+ /* Reclaim the signal thread's sigstate structure and free the
+ other old sigstate structures. */
+ while (oldstates != NULL)
+ {
+ struct hurd_sigstate *next = oldstates->next;
+
+ if (oldstates->thread == _hurd_msgport_thread)
+ {
+ /* If we have a second signal state structure then we
+ must have been through here before--not good. */
+ assert (_hurd_sigstates->next == 0);
+ _hurd_sigstates->next = oldstates;
+ oldstates->next = 0;
+ }
+ else
+ free (oldstates);
+
+ oldstates = next;
+ }
+
+ /* XXX what to do if we have any errors here? */
+
+ pid = 0;
+ }
+
+ /* Unlock things we locked before creating the child task.
+ They are locked in both the parent and child tasks. */
+ {
+ void *const *p;
+ for (p = symbol_set_first_element (_hurd_fork_locks);
+ ! symbol_set_end_p (_hurd_fork_locks, p);
+ ++p)
+ __mutex_unlock (*p);
+ }
+
+ _hurd_critical_section_unlock (ss);
+
+ return err ? __hurd_fail (err) : pid;
+}
+libc_hidden_def (__fork)
+
+weak_alias (__fork, fork)
diff --git a/libc/sysdeps/mach/hurd/fpathconf.c b/libc/sysdeps/mach/hurd/fpathconf.c
new file mode 100644
index 000000000..ffd50d6eb
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fpathconf.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1991, 92, 94, 95, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Get file-specific information about descriptor FD. */
+long int
+__fpathconf (int fd, int name)
+{
+ error_t err;
+ int value;
+
+ if (err = HURD_DPORT_USE (fd, __io_pathconf (port, name, &value)))
+ return __hurd_dfail (fd, err), -1L;
+
+ return value;
+}
+
+weak_alias (__fpathconf, fpathconf)
diff --git a/libc/sysdeps/mach/hurd/fremovexattr.c b/libc/sysdeps/mach/hurd/fremovexattr.c
new file mode 100644
index 000000000..5d3aca609
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fremovexattr.c
@@ -0,0 +1,34 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <hurd/fd.h>
+
+int
+fremovexattr (int fd, const char *name)
+{
+ error_t err;
+
+ err = HURD_DPORT_USE (fd, _hurd_xattr_remove (port, name));
+
+ return err ? __hurd_dfail (fd, err) : 0;
+}
diff --git a/libc/sysdeps/mach/hurd/fsetxattr.c b/libc/sysdeps/mach/hurd/fsetxattr.c
new file mode 100644
index 000000000..db8b676a0
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fsetxattr.c
@@ -0,0 +1,34 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <hurd/fd.h>
+
+ssize_t
+fsetxattr (int fd, const char *name, const void *value, size_t size, int flags)
+{
+ error_t err;
+
+ err = HURD_DPORT_USE (fd, _hurd_xattr_set (port, name, value, size, flags));
+
+ return err ? __hurd_dfail (fd, err) : 0;
+}
diff --git a/libc/sysdeps/mach/hurd/fstatfs.c b/libc/sysdeps/mach/hurd/fstatfs.c
new file mode 100644
index 000000000..5949b497e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fstatfs.c
@@ -0,0 +1,32 @@
+/* fstatfs -- Return information about the filesystem on which FD resides.
+ Copyright (C) 1996,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/statfs.h>
+
+#include "statfsconv.c"
+
+/* Return information about the filesystem on which FD resides. */
+int
+__fstatfs (int fd, struct statfs *buf)
+{
+ struct statfs64 buf64;
+ return __fstatfs64 (fd, &buf64) ?: statfs64_conv (buf, &buf64);
+}
+
+weak_alias (__fstatfs, fstatfs)
diff --git a/libc/sysdeps/mach/hurd/fstatfs64.c b/libc/sysdeps/mach/hurd/fstatfs64.c
new file mode 100644
index 000000000..d87aa378a
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fstatfs64.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/statfs.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+#include "statfsconv.c"
+
+/* Return information about the filesystem on which FD resides. */
+int
+__fstatfs64 (int fd, struct statfs64 *buf)
+{
+ error_t err;
+
+ if (err = HURD_DPORT_USE (fd, __file_statfs (port, buf)))
+ return __hurd_dfail (fd, err);
+
+ return 0;
+}
+weak_alias (__fstatfs64, fstatfs64)
diff --git a/libc/sysdeps/mach/hurd/fstatvfs.c b/libc/sysdeps/mach/hurd/fstatvfs.c
new file mode 100644
index 000000000..a11abe89f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fstatvfs.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+int
+fstatvfs (int fd, struct statvfs *buf)
+{
+ /* `struct statvfs' is in fact identical to `struct statfs' so we
+ can simply call fstatfs. */
+ return __fstatfs (fd, (struct statfs *)buf);
+}
+libc_hidden_def (fstatvfs)
diff --git a/libc/sysdeps/mach/hurd/fstatvfs64.c b/libc/sysdeps/mach/hurd/fstatvfs64.c
new file mode 100644
index 000000000..ac610daaf
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fstatvfs64.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+int
+fstatvfs64 (int fd, struct statvfs64 *buf)
+{
+ /* `struct statvfs64' is in fact identical to `struct statfs64' so
+ we can simply call fstatfs64. */
+ return __fstatfs64 (fd, (struct statfs64 *)buf);
+}
diff --git a/libc/sysdeps/mach/hurd/fsync.c b/libc/sysdeps/mach/hurd/fsync.c
new file mode 100644
index 000000000..325b01558
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fsync.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991, 92, 93, 94, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Make all changes done to FD actually appear on disk. */
+int
+fsync (fd)
+ int fd;
+{
+ error_t err = HURD_DPORT_USE (fd, __file_sync (port, 1, 0));
+ if (err)
+ return __hurd_dfail (fd, err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/ftruncate.c b/libc/sysdeps/mach/hurd/ftruncate.c
new file mode 100644
index 000000000..404459e6d
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/ftruncate.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 97, 98 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Truncate the file FD refers to to LENGTH bytes. */
+int
+__ftruncate (fd, length)
+ int fd;
+ __off_t length;
+{
+ error_t err;
+ if (err = HURD_DPORT_USE (fd, __file_set_size (port, length)))
+ return __hurd_dfail (fd, err);
+ return 0;
+}
+
+weak_alias (__ftruncate, ftruncate)
diff --git a/libc/sysdeps/mach/hurd/futimes.c b/libc/sysdeps/mach/hurd/futimes.c
new file mode 100644
index 000000000..ca687b8bd
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/futimes.c
@@ -0,0 +1,47 @@
+/* futimes -- change access and modification times of open file. Hurd version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/time.h>
+#include <errno.h>
+#include <stddef.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the access time of FD to TVP[0] and
+ the modification time of FD to TVP[1]. */
+int
+__futimes (int fd, const struct timeval tvp[2])
+{
+ struct timeval timevals[2];
+ error_t err;
+
+ if (tvp == NULL)
+ {
+ /* Setting the number of microseconds to `-1' tells the
+ underlying filesystems to use the current time. */
+ timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1;
+ tvp = timevals;
+ }
+
+ err = HURD_DPORT_USE (fd, __file_utimes (port,
+ *(time_value_t *) &tvp[0],
+ *(time_value_t *) &tvp[1]));
+ return err ? __hurd_dfail (fd, err) : 0;
+}
+weak_alias (__futimes, futimes)
diff --git a/libc/sysdeps/mach/hurd/fxstat.c b/libc/sysdeps/mach/hurd/fxstat.c
new file mode 100644
index 000000000..8a2520c5d
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fxstat.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1992,93,94,95,96,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include "xstatconv.c"
+
+/* Get information about the file descriptor FD in BUF. */
+int
+__fxstat (int vers, int fd, struct stat *buf)
+{
+ struct stat64 buf64;
+ return __fxstat64 (vers, fd, &buf64) ?: xstat64_conv (buf, &buf64);
+}
+hidden_def (__fxstat)
+weak_alias (__fxstat, _fxstat)
diff --git a/libc/sysdeps/mach/hurd/fxstat64.c b/libc/sysdeps/mach/hurd/fxstat64.c
new file mode 100644
index 000000000..c1390d1bb
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fxstat64.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 2000,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef RTLD_STAT64 /* dl-fxstat64.c, but we don't want it. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Get information about the file descriptor FD in BUF. */
+int
+__fxstat64 (int vers, int fd, struct stat64 *buf)
+{
+ error_t err;
+
+ if (vers != _STAT_VER)
+ return __hurd_fail (EINVAL);
+
+ if (err = HURD_DPORT_USE (fd, __io_stat (port, buf)))
+ return __hurd_dfail (fd, err);
+
+ return 0;
+}
+hidden_def (__fxstat64)
+
+#endif
diff --git a/libc/sysdeps/mach/hurd/fxstatat.c b/libc/sysdeps/mach/hurd/fxstatat.c
new file mode 100644
index 000000000..dd9d2796e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fxstatat.c
@@ -0,0 +1,33 @@
+/* Get information about file named relative to open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include "xstatconv.c"
+
+int
+__fxstatat (int vers, int fd, const char *filename, struct stat *buf, int flag)
+{
+ struct stat64 buf64;
+ return (__fxstatat64 (vers, fd, filename, &buf64, flag)
+ ?: xstat64_conv (buf, &buf64));
+}
+libc_hidden_def (__fxstatat)
diff --git a/libc/sysdeps/mach/hurd/fxstatat64.c b/libc/sysdeps/mach/hurd/fxstatat64.c
new file mode 100644
index 000000000..6862e80d5
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/fxstatat64.c
@@ -0,0 +1,46 @@
+/* Get information about file named relative to open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Get information about the file descriptor FD in BUF. */
+int
+__fxstatat64 (int vers, int fd, const char *filename, struct stat64 *buf,
+ int flag)
+{
+ error_t err;
+ io_t port;
+
+ if (vers != _STAT_VER)
+ return __hurd_fail (EINVAL);
+
+ port = __file_name_lookup_at (fd, flag, filename, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+
+ err = __io_stat (port, buf);
+ __mach_port_deallocate (__mach_task_self (), port);
+
+ return __hurd_fail (err);
+}
diff --git a/libc/sysdeps/mach/hurd/getclktck.c b/libc/sysdeps/mach/hurd/getclktck.c
new file mode 100644
index 000000000..9cb46bbca
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getclktck.c
@@ -0,0 +1,37 @@
+/* Return run-time value of CLK_TCK for Hurd.
+ Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <time.h>
+
+/* Return frequency of `times'.
+ Since Mach reports CPU times in microseconds, we always use 1 million. */
+int
+__getclktck ()
+{
+ return 1000000;
+}
+
+/* Before glibc 2.2, the Hurd actually did this differently, so we
+ need to keep a compatibility symbol. */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_2)
+compat_symbol (libc, __getclktck, __libc_clk_tck, GLIBC_2_1_1);
+#endif
diff --git a/libc/sysdeps/mach/hurd/getcwd.c b/libc/sysdeps/mach/hurd/getcwd.c
new file mode 100644
index 000000000..7e07e6b40
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getcwd.c
@@ -0,0 +1,324 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,98,2002,04 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+
+/* Get the canonical absolute name of the given directory port, and put it
+ in SIZE bytes of BUF. Returns NULL if the directory couldn't be
+ determined or SIZE was too small. If successful, returns BUF. In GNU,
+ if BUF is NULL, an array is allocated with `malloc'; the array is SIZE
+ bytes long, unless SIZE <= 0, in which case it is as big as necessary.
+ If our root directory cannot be reached, the result will not begin with
+ a slash to indicate that it is relative to some unknown root directory. */
+
+char *
+_hurd_canonicalize_directory_name_internal (file_t thisdir,
+ char *buf,
+ size_t size)
+{
+ error_t err;
+ mach_port_t rootid, thisid, rootdevid, thisdevid;
+ ino64_t rootino, thisino;
+ char *file_name;
+ register char *file_namep;
+ file_t parent;
+ char *dirbuf = NULL;
+ unsigned int dirbufsize = 0;
+ const size_t orig_size = size;
+
+ inline void cleanup (void)
+ {
+ if (parent != thisdir)
+ __mach_port_deallocate (__mach_task_self (), parent);
+
+ __mach_port_deallocate (__mach_task_self (), thisid);
+ __mach_port_deallocate (__mach_task_self (), thisdevid);
+ __mach_port_deallocate (__mach_task_self (), rootid);
+ __mach_port_deallocate (__mach_task_self (), rootdevid);
+
+ if (dirbuf != NULL)
+ __vm_deallocate (__mach_task_self (),
+ (vm_address_t) dirbuf, dirbufsize);
+ }
+
+
+ if (size <= 0)
+ {
+ if (buf != NULL)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ size = FILENAME_MAX * 4 + 1; /* Good starting guess. */
+ }
+
+ if (buf != NULL)
+ file_name = buf;
+ else
+ {
+ file_name = malloc (size);
+ if (file_name == NULL)
+ return NULL;
+ }
+
+ file_namep = file_name + size;
+ *--file_namep = '\0';
+
+ /* Get a port to our root directory and get its identity. */
+
+ if (err = __USEPORT (CRDIR, __io_identity (port,
+ &rootid, &rootdevid, &rootino)))
+ return __hurd_fail (err), NULL;
+ __mach_port_deallocate (__mach_task_self (), rootdevid);
+
+ /* Stat the port to the directory of interest. */
+
+ if (err = __io_identity (thisdir, &thisid, &thisdevid, &thisino))
+ {
+ __mach_port_deallocate (__mach_task_self (), rootid);
+ return __hurd_fail (err), NULL;
+ }
+
+ parent = thisdir;
+ while (thisid != rootid)
+ {
+ /* PARENT is a port to the directory we are currently on;
+ THISID, THISDEV, and THISINO are its identity.
+ Look in its parent (..) for a file with the same file number. */
+
+ struct dirent64 *d;
+ mach_port_t dotid, dotdevid;
+ ino64_t dotino;
+ int mount_point;
+ file_t newp;
+ char *dirdata;
+ size_t dirdatasize;
+ int direntry, nentries;
+
+
+ /* Look at the parent directory. */
+ newp = __file_name_lookup_under (parent, "..", O_READ, 0);
+ if (newp == MACH_PORT_NULL)
+ goto lose;
+ if (parent != thisdir)
+ __mach_port_deallocate (__mach_task_self (), parent);
+ parent = newp;
+
+ /* Get this directory's identity and figure out if it's a mount
+ point. */
+ if (err = __io_identity (parent, &dotid, &dotdevid, &dotino))
+ goto errlose;
+ mount_point = dotdevid != thisdevid;
+
+ if (thisid == dotid)
+ {
+ /* `..' == `.' but it is not our root directory. */
+ __mach_port_deallocate (__mach_task_self (), dotid);
+ __mach_port_deallocate (__mach_task_self (), dotdevid);
+ break;
+ }
+
+ /* Search for the last directory. */
+ direntry = 0;
+ dirdata = dirbuf;
+ dirdatasize = dirbufsize;
+ while (!(err = __dir_readdir (parent, &dirdata, &dirdatasize,
+ direntry, -1, 0, &nentries)) &&
+ nentries != 0)
+ {
+ /* We have a block of directory entries. */
+
+ unsigned int offset;
+
+ direntry += nentries;
+
+ if (dirdata != dirbuf)
+ {
+ /* The data was passed out of line, so our old buffer is no
+ longer useful. Deallocate the old buffer and reset our
+ information for the new buffer. */
+ __vm_deallocate (__mach_task_self (),
+ (vm_address_t) dirbuf, dirbufsize);
+ dirbuf = dirdata;
+ dirbufsize = round_page (dirdatasize);
+ }
+
+ /* Iterate over the returned directory entries, looking for one
+ whose file number is THISINO. */
+
+ offset = 0;
+ while (offset < dirdatasize)
+ {
+ d = (struct dirent64 *) &dirdata[offset];
+ offset += d->d_reclen;
+
+ /* Ignore `.' and `..'. */
+ if (d->d_name[0] == '.' &&
+ (d->d_namlen == 1 ||
+ (d->d_namlen == 2 && d->d_name[1] == '.')))
+ continue;
+
+ if (mount_point || d->d_ino == thisino)
+ {
+ file_t try = __file_name_lookup_under (parent, d->d_name,
+ O_NOLINK, 0);
+ file_t id, devid;
+ ino64_t fileno;
+ if (try == MACH_PORT_NULL)
+ goto lose;
+ err = __io_identity (try, &id, &devid, &fileno);
+ __mach_port_deallocate (__mach_task_self (), try);
+ if (err)
+ goto inner_errlose;
+ __mach_port_deallocate (__mach_task_self (), id);
+ __mach_port_deallocate (__mach_task_self (), devid);
+ if (id == thisid)
+ goto found;
+ }
+ }
+ }
+
+ if (err)
+ {
+ inner_errlose: /* Goto ERRLOSE: after cleaning up. */
+ __mach_port_deallocate (__mach_task_self (), dotid);
+ __mach_port_deallocate (__mach_task_self (), dotdevid);
+ goto errlose;
+ }
+ else if (nentries == 0)
+ {
+ /* We got to the end of the directory without finding anything!
+ We are in a directory that has been unlinked, or something is
+ broken. */
+ err = ENOENT;
+ goto inner_errlose;
+ }
+ else
+ found:
+ {
+ /* Prepend the directory name just discovered. */
+
+ if (file_namep - file_name < d->d_namlen + 1)
+ {
+ if (orig_size > 0)
+ {
+ errno = ERANGE;
+ return NULL;
+ }
+ else
+ {
+ size *= 2;
+ buf = realloc (file_name, size);
+ if (buf == NULL)
+ {
+ free (file_name);
+ return NULL;
+ }
+ file_namep = &buf[file_namep - file_name + size / 2];
+ file_name = buf;
+ /* Move current contents up to the end of the buffer.
+ This is guaranteed to be non-overlapping. */
+ memcpy (file_namep, file_namep - size / 2,
+ file_name + size - file_namep);
+ }
+ }
+ file_namep -= d->d_namlen;
+ (void) memcpy (file_namep, d->d_name, d->d_namlen);
+ *--file_namep = '/';
+ }
+
+ /* The next iteration will find the name of the directory we
+ just searched through. */
+ __mach_port_deallocate (__mach_task_self (), thisid);
+ __mach_port_deallocate (__mach_task_self (), thisdevid);
+ thisid = dotid;
+ thisdevid = dotdevid;
+ thisino = dotino;
+ }
+
+ if (file_namep == &file_name[size - 1])
+ /* We found nothing and got all the way to the root.
+ So the root is our current directory. */
+ *--file_namep = '/';
+
+ if (thisid != rootid)
+ /* We did not get to our root directory. The returned name should
+ not begin with a slash. */
+ ++file_namep;
+
+ memmove (file_name, file_namep, file_name + size - file_namep);
+ cleanup ();
+ return file_name;
+
+ errlose:
+ /* Set errno. */
+ (void) __hurd_fail (err);
+ lose:
+ cleanup ();
+ return NULL;
+}
+
+char *
+__canonicalize_directory_name_internal (thisdir, buf, size)
+ const char *thisdir;
+ char *buf;
+ size_t size;
+{
+ char *result;
+ file_t port = __file_name_lookup (thisdir, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return NULL;
+ result = _hurd_canonicalize_directory_name_internal (port, buf, size);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return result;
+}
+
+/* Get the pathname of the current working directory, and put it in SIZE
+ bytes of BUF. Returns NULL if the directory couldn't be determined or
+ SIZE was too small. If successful, returns BUF. In GNU, if BUF is
+ NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
+ unless SIZE <= 0, in which case it is as big as necessary. */
+char *
+__getcwd (char *buf, size_t size)
+{
+ char *cwd =
+ __USEPORT (CWDIR,
+ _hurd_canonicalize_directory_name_internal (port,
+ buf, size));
+ if (cwd && cwd[0] != '/')
+ {
+ /* `cwd' is an unknown root directory. */
+ if (buf == NULL)
+ free (cwd);
+ return __hurd_fail (EGRATUITOUS), NULL;
+ }
+ return cwd;
+}
+weak_alias (__getcwd, getcwd)
diff --git a/libc/sysdeps/mach/hurd/getdents.c b/libc/sysdeps/mach/hurd/getdents.c
new file mode 100644
index 000000000..d15be3b8f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getdents.c
@@ -0,0 +1 @@
+#include <dirent/getdents.c>
diff --git a/libc/sysdeps/mach/hurd/getdomain.c b/libc/sysdeps/mach/hurd/getdomain.c
new file mode 100644
index 000000000..04f6e7d1d
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getdomain.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include "hurdhost.h"
+
+/* Put the name of the current NIS domain in no more than LEN bytes of NAME.
+ The result is null-terminated if LEN is large enough for the full
+ name and the terminator. */
+int
+getdomainname (char *name, size_t len)
+{
+ /* The NIS domain name is just the contents of the file /etc/nisdomain. */
+ ssize_t n = _hurd_get_host_config ("/etc/nisdomain", name, len);
+ return n < 0 ? -1 : 0;
+}
+libc_hidden_def (getdomainname)
diff --git a/libc/sysdeps/mach/hurd/getdtsz.c b/libc/sysdeps/mach/hurd/getdtsz.c
new file mode 100644
index 000000000..a740c1ee9
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getdtsz.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1991,92,93,94,95,97,2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/resource.h>
+
+/* Return the maximum number of file descriptors the current process
+ could possibly have (until it raises the resource limit). */
+int
+__getdtablesize ()
+{
+ rlim_t limit;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_rlimit_lock);
+ limit = _hurd_rlimits[RLIMIT_NOFILE].rlim_cur;
+ __mutex_unlock (&_hurd_rlimit_lock);
+ HURD_CRITICAL_END;
+
+ /* RLIM_INFINITY is not meaningful to our caller. -1 is a good choice
+ because `sysconf (_SC_OPEN_MAX)' calls us, and -1 from sysconf means
+ "no determinable limit". */
+ return limit == RLIM_INFINITY ? -1 : (int) limit;
+}
+
+weak_alias (__getdtablesize, getdtablesize)
diff --git a/libc/sysdeps/mach/hurd/getegid.c b/libc/sysdeps/mach/hurd/getegid.c
new file mode 100644
index 000000000..36f1a2274
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getegid.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Get the effective group ID of the calling process. */
+gid_t
+__getegid ()
+{
+ error_t err;
+ gid_t egid;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+
+ if (err = _hurd_check_ids ())
+ {
+ errno = err;
+ egid = -1;
+ }
+ else if (_hurd_id.gen.ngids >= 1)
+ egid = _hurd_id.gen.gids[0];
+ else if (_hurd_id.aux.ngids >= 1)
+ /* We have no effective gids. Return the real gid. */
+ egid = _hurd_id.aux.gids[0];
+ else
+ {
+ /* We do not even have a real gid. */
+ errno = EGRATUITOUS;
+ egid = -1;
+ }
+
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ return egid;
+}
+
+weak_alias (__getegid, getegid)
diff --git a/libc/sysdeps/mach/hurd/geteuid.c b/libc/sysdeps/mach/hurd/geteuid.c
new file mode 100644
index 000000000..a80b9c20d
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/geteuid.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Get the effective user ID of the calling process. */
+uid_t
+__geteuid ()
+{
+ error_t err;
+ uid_t euid;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+
+ if (err = _hurd_check_ids ())
+ {
+ errno = err;
+ euid = -1;
+ }
+ else if (_hurd_id.gen.nuids >= 1)
+ euid = _hurd_id.gen.uids[0];
+ else if (_hurd_id.aux.nuids >= 1)
+ /* We have no effective uids. Return the real uid. */
+ euid = _hurd_id.aux.uids[0];
+ else
+ {
+ /* We do not even have a real uid. */
+ errno = EGRATUITOUS;
+ euid = -1;
+ }
+
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ return euid;
+}
+
+weak_alias (__geteuid, geteuid)
diff --git a/libc/sysdeps/mach/hurd/getgid.c b/libc/sysdeps/mach/hurd/getgid.c
new file mode 100644
index 000000000..b9e24ae4f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getgid.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Get the real group ID of the calling process. */
+gid_t
+__getgid ()
+{
+ error_t err;
+ gid_t gid;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+
+ if (err = _hurd_check_ids ())
+ {
+ errno = err;
+ gid = -1;
+ }
+ else if (_hurd_id.aux.ngids >= 1)
+ gid = _hurd_id.aux.gids[0];
+ else
+ {
+ /* We do not even have a real gid. */
+ errno = EGRATUITOUS;
+ gid = -1;
+ }
+
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ return gid;
+}
+
+weak_alias (__getgid, getgid)
diff --git a/libc/sysdeps/mach/hurd/getgroups.c b/libc/sysdeps/mach/hurd/getgroups.c
new file mode 100644
index 000000000..919336e7f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getgroups.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+#include <string.h>
+
+int
+__getgroups (n, gidset)
+ int n;
+ gid_t *gidset;
+{
+ error_t err;
+ int ngids;
+ void *crit;
+
+ crit = _hurd_critical_section_lock ();
+ __mutex_lock (&_hurd_id.lock);
+
+ if (err = _hurd_check_ids ())
+ {
+ __mutex_unlock (&_hurd_id.lock);
+ _hurd_critical_section_unlock (crit);
+ return __hurd_fail (err);
+ }
+
+ ngids = _hurd_id.gen.ngids;
+
+ if (n != 0)
+ {
+ /* Copy the gids onto stack storage and then release the idlock. */
+ gid_t gids[ngids];
+ memcpy (gids, _hurd_id.gen.gids, sizeof (gids));
+ __mutex_unlock (&_hurd_id.lock);
+ _hurd_critical_section_unlock (crit);
+
+ /* Now that the lock is released, we can safely copy the
+ group set into the user's array, which might fault. */
+ if (ngids > n)
+ ngids = n;
+ memcpy (gidset, gids, ngids * sizeof (gid_t));
+ }
+ else
+ {
+ __mutex_unlock (&_hurd_id.lock);
+ _hurd_critical_section_unlock (crit);
+ }
+
+ return ngids;
+}
+
+weak_alias (__getgroups, getgroups)
diff --git a/libc/sysdeps/mach/hurd/gethostid.c b/libc/sysdeps/mach/hurd/gethostid.c
new file mode 100644
index 000000000..f4f1d4bae
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/gethostid.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 92, 93, 94, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include "hurdhost.h"
+
+/* Return the current machine's Internet number. */
+long int
+gethostid ()
+{
+ /* The hostid is just the contents of the file /etc/hostid,
+ kept as text of hexadecimal digits. */
+ /* XXX this is supposed to come from the hardware serial number */
+ char buf[8];
+ ssize_t n = _hurd_get_host_config ("/etc/hostid", buf, sizeof buf);
+ if (n < 0)
+ return -1;
+ return strtol (buf, NULL, 16);
+}
diff --git a/libc/sysdeps/mach/hurd/gethostname.c b/libc/sysdeps/mach/hurd/gethostname.c
new file mode 100644
index 000000000..f77895da0
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/gethostname.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991-1997, 2000, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include "hurdhost.h"
+
+/* Put the name of the current host in no more than LEN bytes of NAME.
+ The result is null-terminated if LEN is large enough for the full
+ name and the terminator. */
+int
+__gethostname (name, len)
+ char *name;
+ size_t len;
+{
+ /* The host name is just the contents of the file /etc/hostname. */
+ ssize_t n = _hurd_get_host_config ("/etc/hostname", name, len);
+ return n < 0 ? -1 : 0;
+}
+
+weak_alias (__gethostname, gethostname)
diff --git a/libc/sysdeps/mach/hurd/getitimer.c b/libc/sysdeps/mach/hurd/getitimer.c
new file mode 100644
index 000000000..77b355736
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getitimer.c
@@ -0,0 +1,104 @@
+/* Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <hurd.h>
+
+/* XXX Temporary cheezoid implementation; see __setitmr.c. */
+
+/* These are defined in __setitmr.c. */
+extern spin_lock_t _hurd_itimer_lock;
+extern struct itimerval _hurd_itimerval;
+extern struct timeval _hurd_itimer_started;
+
+static inline void
+subtract_timeval (struct timeval *from, const struct timeval *subtract)
+{
+ from->tv_usec -= subtract->tv_usec;
+ from->tv_sec -= subtract->tv_sec;
+ while (from->tv_usec < 0)
+ {
+ --from->tv_sec;
+ from->tv_usec += 1000000;
+ }
+}
+
+/* Set *VALUE to the current setting of timer WHICH.
+ Return 0 on success, -1 on errors. */
+int
+__getitimer (which, value)
+ enum __itimer_which which;
+ struct itimerval *value;
+{
+ struct itimerval val;
+ struct timeval elapsed;
+
+ switch (which)
+ {
+ default:
+ return __hurd_fail (EINVAL);
+
+ case ITIMER_VIRTUAL:
+ case ITIMER_PROF:
+ return __hurd_fail (ENOSYS);
+
+ case ITIMER_REAL:
+ break;
+ }
+
+ /* Get the time now. */
+ if (__gettimeofday (&elapsed, NULL) < 0)
+ return -1;
+
+ /* Extract the current timer setting; and the time it was set, so we can
+ calculate the time elapsed so far. */
+ HURD_CRITICAL_BEGIN;
+ __spin_lock (&_hurd_itimer_lock);
+ val = _hurd_itimerval;
+ subtract_timeval (&elapsed, &_hurd_itimer_started);
+ __spin_unlock (&_hurd_itimer_lock);
+ HURD_CRITICAL_END;
+
+ if ((val.it_value.tv_sec | val.it_value.tv_usec) != 0)
+ {
+ /* There is a pending alarm set. VAL indicates the interval it was
+ set for, relative to the time recorded in _hurd_itimer_started.
+ Now compensate for the time elapsed since to get the user's
+ conception of the current value of the timer (as if the value
+ stored decreased every microsecond). */
+ if (timercmp (&val.it_value, &elapsed, <))
+ {
+ /* Hmm. The timer should have just gone off, but has not been
+ reset. This is a possible timing glitch. The alarm will signal
+ soon, so fabricate a value for how soon. */
+ val.it_value.tv_sec = 0;
+ val.it_value.tv_usec = 10; /* Random. */
+ }
+ else
+ /* Subtract the time elapsed since the timer was set
+ from the current timer value the user sees. */
+ subtract_timeval (&val.it_value, &elapsed);
+ }
+
+ *value = val;
+ return 0;
+}
+
+weak_alias (__getitimer, getitimer)
diff --git a/libc/sysdeps/mach/hurd/getlogin.c b/libc/sysdeps/mach/hurd/getlogin.c
new file mode 100644
index 000000000..248ddb144
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getlogin.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Return the login name of the user, or NULL if it can't be determined.
+ The returned pointer, if not NULL, is good only until the next call. */
+char *
+getlogin ()
+{
+ static char login[1024]; /* XXX */
+ error_t err;
+
+ if (err = __USEPORT (PROC, __proc_getlogin (port, login)))
+ {
+ errno = err;
+ return NULL;
+ }
+
+ return login;
+}
diff --git a/libc/sysdeps/mach/hurd/getlogin_r.c b/libc/sysdeps/mach/hurd/getlogin_r.c
new file mode 100644
index 000000000..f4d5faed7
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getlogin_r.c
@@ -0,0 +1,42 @@
+/* Reentrant function to return the current login name. Hurd version.
+ Copyright (C) 1996, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <string.h>
+
+/* Return at most NAME_LEN characters of the login name of the user in NAME.
+ If it cannot be determined or some other error occurred, return the error
+ code. Otherwise return 0. */
+int
+getlogin_r (name, name_len)
+ char *name;
+ size_t name_len;
+{
+ static char login[1024]; /* XXX */
+ error_t err;
+
+ if (err = __USEPORT (PROC, __proc_getlogin (port, login)))
+ return errno = err;
+
+ strncpy (name, login, name_len);
+ return 0;
+}
+libc_hidden_def (getlogin_r)
diff --git a/libc/sysdeps/mach/hurd/getpeername.c b/libc/sysdeps/mach/hurd/getpeername.c
new file mode 100644
index 000000000..325b6fd75
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getpeername.c
@@ -0,0 +1,70 @@
+/* Copyright (C) 1992,1994,1997,1999,2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+
+/* Put the address of the peer connected to socket FD into *ADDR
+ (which is *LEN bytes long), and its actual length into *LEN. */
+int
+__getpeername (int fd, __SOCKADDR_ARG addrarg, socklen_t *len)
+{
+ error_t err;
+ mach_msg_type_number_t buflen = *len;
+ int type;
+ struct sockaddr *addr = addrarg.__sockaddr__;
+ char *buf = (char *) addr;
+ addr_port_t aport;
+
+ if (err = HURD_DPORT_USE (fd, __socket_peername (port, &aport)))
+ return __hurd_dfail (fd, err);
+
+ err = __socket_whatis_address (aport, &type, &buf, &buflen);
+ __mach_port_deallocate (__mach_task_self (), aport);
+
+ if (err)
+ return __hurd_dfail (fd, err);
+
+ if (*len > buflen)
+ *len = buflen;
+
+ if (buf != (char *) addr)
+ {
+ memcpy (addr, buf, *len);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+ }
+
+ const sa_family_t family = type;
+ if (*len > offsetof (struct sockaddr, sa_family))
+ {
+ if (*len < (char *) (&addr->sa_family + 1) - (char *) addr)
+ memcpy (&addr->sa_family, &family,
+ *len - offsetof (struct sockaddr, sa_family));
+ else
+ addr->sa_family = family;
+ }
+
+ return 0;
+}
+
+weak_alias (__getpeername, getpeername)
diff --git a/libc/sysdeps/mach/hurd/getpgid.c b/libc/sysdeps/mach/hurd/getpgid.c
new file mode 100644
index 000000000..167d748e5
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getpgid.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 97, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+
+/* Get the process group ID of process PID. */
+int
+__getpgid (pid)
+ pid_t pid;
+{
+ error_t err;
+ pid_t pgrp;
+
+ if (pid == 0)
+ {
+ /* Assume atomic word fetch and store, so don't lock _hurd_pid_lock. */
+ pgrp = _hurd_pgrp;
+ err = 0;
+ }
+ else
+ err = __USEPORT (PROC, __proc_getpgrp (port, pid, &pgrp));
+
+ return err ? __hurd_fail (err) : pgrp;
+}
+libc_hidden_def (__getpgid)
+weak_alias (__getpgid, getpgid)
diff --git a/libc/sysdeps/mach/hurd/getpid.c b/libc/sysdeps/mach/hurd/getpid.c
new file mode 100644
index 000000000..a8324f291
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getpid.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991, 1993, 1995, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Get the process ID of the calling process. */
+pid_t
+__getpid ()
+{
+ /* Assumes atomic word fetch and store, so doesn't lock _hurd_pid_lock. */
+ return _hurd_pid;
+}
+libc_hidden_def (__getpid)
+weak_alias (__getpid, getpid)
+libc_hidden_weak (getpid)
diff --git a/libc/sysdeps/mach/hurd/getppid.c b/libc/sysdeps/mach/hurd/getppid.c
new file mode 100644
index 000000000..436cdb2cb
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getppid.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991, 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+
+
+/* Get the parent process ID of the calling process. */
+pid_t
+__getppid ()
+{
+ /* Assumes atomic word fetch and store, so doesn't lock _hurd_pid_lock. */
+ return _hurd_ppid;
+}
+
+weak_alias (__getppid, getppid)
diff --git a/libc/sysdeps/mach/hurd/getpriority.c b/libc/sysdeps/mach/hurd/getpriority.c
new file mode 100644
index 000000000..8f7c3c6d9
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getpriority.c
@@ -0,0 +1,85 @@
+/* Copyright (C) 1994,95,96,97,2000,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <limits.h>
+#include <hurd.h>
+#include <hurd/resource.h>
+
+/* Return the highest priority of any process specified by WHICH and WHO
+ (see <sys/resource.h>); if WHO is zero, the current process, process group,
+ or user (as specified by WHO) is used. A lower priority number means higher
+ priority. Priorities range from PRIO_MIN to PRIO_MAX. */
+int
+getpriority (enum __priority_which which, id_t who)
+{
+ error_t err, onerr;
+ int maxpri = INT_MIN;
+ struct procinfo *pip; /* Just for sizeof. */
+ int pibuf[sizeof *pip + 2 * sizeof (pip->threadinfos[0])], *pi = pibuf;
+ size_t pisize = sizeof pibuf / sizeof pibuf[0];
+
+ error_t getonepriority (pid_t pid, struct procinfo *pip)
+ {
+ if (pip)
+ onerr = 0;
+ else
+ {
+ int *oldpi = pi;
+ size_t oldpisize = pisize;
+ char *tw = 0;
+ size_t twsz = 0;
+ int flags = PI_FETCH_TASKINFO;
+ onerr = __USEPORT (PROC, __proc_getprocinfo (port, pid, &flags,
+ &pi, &pisize,
+ &tw, &twsz));
+ if (twsz)
+ __vm_deallocate (__mach_task_self (), (vm_address_t) tw, twsz);
+ if (pi != oldpi && oldpi != pibuf)
+ /* Old buffer from last call was not reused; free it. */
+ __vm_deallocate (__mach_task_self (),
+ (vm_address_t) oldpi, oldpisize * sizeof pi[0]);
+ pip = (struct procinfo *) pi;
+ }
+#ifdef TASK_SCHED_TIMESHARE_INFO
+ if (!onerr && pip->timeshare_base_info.base_priority > maxpri)
+ maxpri = pip->timeshare_base_info.base_priority;
+#else
+ if (!onerr && pip->taskinfo.base_priority > maxpri)
+ maxpri = pip->taskinfo.base_priority;
+#endif
+ return 0;
+ }
+
+ onerr = 0;
+ err = _hurd_priority_which_map (which, who,
+ getonepriority, PI_FETCH_TASKINFO);
+
+ if (pi != pibuf)
+ __vm_deallocate (__mach_task_self (),
+ (vm_address_t) pi, pisize * sizeof pi[0]);
+
+ if (!err && maxpri == INT_MIN)
+ /* No error, but no pids found. */
+ err = onerr ?: ESRCH;
+
+ if (err)
+ return __hurd_fail (err);
+
+ return MACH_PRIORITY_TO_NICE (maxpri);
+}
+libc_hidden_def (getpriority)
diff --git a/libc/sysdeps/mach/hurd/getresgid.c b/libc/sysdeps/mach/hurd/getresgid.c
new file mode 100644
index 000000000..7847d213c
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getresgid.c
@@ -0,0 +1,62 @@
+/* getresgid -- fetch real group ID, effective group ID, and saved-set group ID
+ Copyright (C) 2002, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Fetch the real group ID, effective group ID, and saved-set group ID,
+ of the calling process. */
+int
+__getresgid (gid_t *rgid, gid_t *egid, gid_t *sgid)
+{
+ error_t err;
+ gid_t real, eff, saved;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+
+ err = _hurd_check_ids ();
+ if (!err)
+ {
+ if (_hurd_id.aux.ngids < 1)
+ /* We do not even have a real GID. */
+ err = EGRATUITOUS;
+ else
+ {
+ real = _hurd_id.aux.gids[0];
+ eff = _hurd_id.gen.ngids < 1 ? real : _hurd_id.gen.gids[0];
+ saved = _hurd_id.aux.ngids < 2 ? real : _hurd_id.aux.gids[1];
+ }
+ }
+
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ *rgid = real;
+ *egid = eff;
+ *sgid = saved;
+ return 0;
+}
+libc_hidden_def (__getresgid)
+weak_alias (__getresgid, getresgid)
diff --git a/libc/sysdeps/mach/hurd/getresuid.c b/libc/sysdeps/mach/hurd/getresuid.c
new file mode 100644
index 000000000..668e463a3
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getresuid.c
@@ -0,0 +1,62 @@
+/* getresuid -- fetch real user ID, effective user ID, and saved-set user ID
+ Copyright (C) 2002, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Fetch the real user ID, effective user ID, and saved-set user ID,
+ of the calling process. */
+int
+__getresuid (uid_t *ruid, uid_t *euid, uid_t *suid)
+{
+ error_t err;
+ uid_t real, eff, saved;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+
+ err = _hurd_check_ids ();
+ if (!err)
+ {
+ if (_hurd_id.aux.nuids < 1)
+ /* We do not even have a real UID. */
+ err = EGRATUITOUS;
+ else
+ {
+ real = _hurd_id.aux.uids[0];
+ eff = _hurd_id.gen.nuids < 1 ? real : _hurd_id.gen.uids[0];
+ saved = _hurd_id.aux.nuids < 2 ? real : _hurd_id.aux.uids[1];
+ }
+ }
+
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ *ruid = real;
+ *euid = eff;
+ *suid = saved;
+ return 0;
+}
+libc_hidden_def (__getresuid)
+weak_alias (__getresuid, getresuid)
diff --git a/libc/sysdeps/mach/hurd/getrlimit.c b/libc/sysdeps/mach/hurd/getrlimit.c
new file mode 100644
index 000000000..4ad8f3c57
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getrlimit.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1991,93,94,96,97,2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/resource.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/resource.h>
+
+/* Put the soft and hard limits for RESOURCE in *RLIMITS.
+ Returns 0 if successful, -1 if not (and sets errno). */
+int
+__getrlimit (enum __rlimit_resource resource, struct rlimit *rlimits)
+{
+ struct rlimit lim;
+
+ if (rlimits == NULL || (unsigned int) resource >= RLIMIT_NLIMITS)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_rlimit_lock);
+ lim = _hurd_rlimits[resource];
+ __mutex_unlock (&_hurd_rlimit_lock);
+ HURD_CRITICAL_END;
+
+ *rlimits = lim;
+
+ return 0;
+}
+weak_alias (__getrlimit, getrlimit)
diff --git a/libc/sysdeps/mach/hurd/getrusage.c b/libc/sysdeps/mach/hurd/getrusage.c
new file mode 100644
index 000000000..373486ffc
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getrusage.c
@@ -0,0 +1,94 @@
+/* getrusage -- Get resource usage information about processes. Hurd version.
+ Copyright (C) 1999,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <mach.h>
+#include <mach/task_info.h>
+#include <hurd.h>
+
+/* Return resource usage information on process indicated by WHO
+ and put it in *USAGE. Returns 0 for success, -1 for failure. */
+int
+__getrusage (who, usage)
+ enum __rusage_who who;
+ struct rusage *usage;
+{
+ struct task_basic_info bi;
+ struct task_events_info ei;
+ struct task_thread_times_info tti;
+ mach_msg_type_number_t count;
+ error_t err;
+
+ switch (who)
+ {
+ case RUSAGE_SELF:
+ count = TASK_BASIC_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_BASIC_INFO,
+ (task_info_t) &bi, &count);
+ if (err)
+ return __hurd_fail (err);
+
+ count = TASK_EVENTS_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_EVENTS_INFO,
+ (task_info_t) &ei, &count);
+ if (err == KERN_INVALID_ARGUMENT) /* microkernel doesn't implement it */
+ memset (&ei, 0, sizeof ei);
+ else if (err)
+ return __hurd_fail (err);
+
+ count = TASK_THREAD_TIMES_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_THREAD_TIMES_INFO,
+ (task_info_t) &tti, &count);
+ if (err)
+ return __hurd_fail (err);
+
+ time_value_add (&bi.user_time, &tti.user_time);
+ time_value_add (&bi.system_time, &tti.system_time);
+
+ memset (usage, 0, sizeof (struct rusage));
+
+ usage->ru_utime.tv_sec = bi.user_time.seconds;
+ usage->ru_utime.tv_usec = bi.user_time.microseconds;
+ usage->ru_stime.tv_sec = bi.system_time.seconds;
+ usage->ru_stime.tv_usec = bi.system_time.microseconds;
+
+ /* These statistics map only approximately. */
+ usage->ru_majflt = ei.pageins;
+ usage->ru_minflt = ei.faults - ei.pageins;
+ usage->ru_msgsnd = ei.messages_sent; /* Mach IPC, not SysV IPC */
+ usage->ru_msgrcv = ei.messages_received; /* Mach IPC, not SysV IPC */
+ break;
+
+ case RUSAGE_CHILDREN:
+ /* XXX Not implemented yet. However, zero out USAGE to be
+ consistent with the wait3 and wait4 functions. */
+ memset (usage, 0, sizeof (struct rusage));
+
+ break;
+
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+weak_alias (__getrusage, getrusage)
diff --git a/libc/sysdeps/mach/hurd/getsid.c b/libc/sysdeps/mach/hurd/getsid.c
new file mode 100644
index 000000000..9dcfa90fd
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getsid.c
@@ -0,0 +1,39 @@
+/* getsid -- Return session ID of a process. Hurd version.
+ Copyright (C) 1995,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <hurd.h>
+
+pid_t
+getsid (pid_t pid)
+{
+ error_t err;
+ pid_t sid;
+
+ if (pid == 0)
+ pid = _hurd_pid;
+
+ err = __USEPORT (PROC, __proc_getsid (port, pid, &sid));
+ if (err)
+ return (pid_t) __hurd_fail (err);
+ return sid;
+}
+libc_hidden_def (getsid)
diff --git a/libc/sysdeps/mach/hurd/getsockname.c b/libc/sysdeps/mach/hurd/getsockname.c
new file mode 100644
index 000000000..dd0dddaed
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getsockname.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1992, 1994, 1997, 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+
+/* Put the local address of FD into *ADDR and its length in *LEN. */
+int
+__getsockname (fd, addrarg, len)
+ int fd;
+ __SOCKADDR_ARG addrarg;
+ socklen_t *len;
+{
+ error_t err;
+ struct sockaddr *addr = addrarg.__sockaddr__;
+ char *buf = (char *) addr;
+ mach_msg_type_number_t buflen = *len;
+ int type;
+ addr_port_t aport;
+
+ if (err = HURD_DPORT_USE (fd, __socket_name (port, &aport)))
+ return __hurd_dfail (fd, err);
+
+ err = __socket_whatis_address (aport, &type, &buf, &buflen);
+ __mach_port_deallocate (__mach_task_self (), aport);
+
+ if (err)
+ return __hurd_dfail (fd, err);
+
+ if (*len > buflen)
+ *len = buflen;
+
+ if (buf != (char *) addr)
+ {
+ memcpy (addr, buf, *len);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+ }
+
+ addr->sa_family = type;
+
+ return 0;
+}
+
+weak_alias (__getsockname, getsockname)
diff --git a/libc/sysdeps/mach/hurd/getsockopt.c b/libc/sysdeps/mach/hurd/getsockopt.c
new file mode 100644
index 000000000..7e35fa502
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getsockopt.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1992,94,97,2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+#include <string.h>
+
+/* Put the current value for socket FD's option OPTNAME at protocol level LEVEL
+ into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's
+ actual length. Returns 0 on success, -1 for errors. */
+
+/* XXX should be __getsockopt ? */
+int
+getsockopt (int fd,
+ int level,
+ int optname,
+ void *optval,
+ socklen_t *optlen)
+{
+ error_t err;
+ char *buf = optval;
+ mach_msg_type_number_t buflen = *optlen;
+
+ if (err = HURD_DPORT_USE (fd, __socket_getopt (port,
+ level, optname,
+ &buf, &buflen)))
+ return __hurd_dfail (fd, err);
+
+ if (*optlen > buflen)
+ *optlen = buflen;
+ if (buf != optval)
+ {
+ memcpy (optval, buf, *optlen);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+ }
+
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/getuid.c b/libc/sysdeps/mach/hurd/getuid.c
new file mode 100644
index 000000000..138b2e6c9
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getuid.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Get the real user ID of the calling process. */
+uid_t
+__getuid ()
+{
+ error_t err;
+ uid_t uid;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+
+ if (err = _hurd_check_ids ())
+ {
+ errno = err;
+ uid = -1;
+ }
+ else if (_hurd_id.aux.nuids >= 1)
+ uid = _hurd_id.aux.uids[0];
+ else
+ {
+ /* We do not even have a real uid. */
+ errno = EGRATUITOUS;
+ uid = -1;
+ }
+
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ return uid;
+}
+
+weak_alias (__getuid, getuid)
diff --git a/libc/sysdeps/mach/hurd/getxattr.c b/libc/sysdeps/mach/hurd/getxattr.c
new file mode 100644
index 000000000..8f688a1d2
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/getxattr.c
@@ -0,0 +1,35 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+
+ssize_t
+getxattr (const char *path, const char *name, void *value, size_t size)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_get (port, name, value, &size);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return err ? __hurd_fail (err) : size;
+}
diff --git a/libc/sysdeps/mach/hurd/group_member.c b/libc/sysdeps/mach/hurd/group_member.c
new file mode 100644
index 000000000..927342ca5
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/group_member.c
@@ -0,0 +1,56 @@
+/* `group_member' -- test if process is in a given group. Hurd version.
+ Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+int
+__group_member (gid)
+ gid_t gid;
+{
+ int member = 0;
+ error_t err;
+ void *crit;
+
+ crit = _hurd_critical_section_lock ();
+ __mutex_lock (&_hurd_id.lock);
+
+ err = _hurd_check_ids ();
+ if (! err)
+ {
+ size_t i;
+ for (i = 0; i < _hurd_id.gen.ngids; ++i)
+ if (_hurd_id.gen.gids[i] == gid)
+ {
+ member = 1;
+ break;
+ }
+ }
+
+ __mutex_unlock (&_hurd_id.lock);
+ _hurd_critical_section_unlock (crit);
+
+ if (err)
+ __hurd_fail (err);
+ return member;
+}
+
+weak_alias (__group_member, group_member)
diff --git a/libc/sysdeps/mach/hurd/i386/Makefile b/libc/sysdeps/mach/hurd/i386/Makefile
new file mode 100644
index 000000000..0eef17e8f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/Makefile
@@ -0,0 +1,4 @@
+ifeq ($(subdir),misc)
+sysdep_routines += ioperm
+sysdep_headers += sys/io.h
+endif
diff --git a/libc/sysdeps/mach/hurd/i386/Versions b/libc/sysdeps/mach/hurd/i386/Versions
new file mode 100644
index 000000000..67e6d9420
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/Versions
@@ -0,0 +1,10 @@
+libc {
+ GLIBC_2.0 {
+ # Exception handling support functions from libgcc
+ __register_frame; __register_frame_table; __deregister_frame;
+ __frame_state_for; __register_frame_info_table;
+ }
+ GLIBC_2.2.6 {
+ ioperm;
+ }
+}
diff --git a/libc/sysdeps/mach/hurd/i386/bits/sigcontext.h b/libc/sysdeps/mach/hurd/i386/bits/sigcontext.h
new file mode 100644
index 000000000..a78dd2f27
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/bits/sigcontext.h
@@ -0,0 +1,120 @@
+/* Machine-dependent signal context structure for GNU Hurd. i386 version.
+ Copyright (C) 1991, 1992, 1994, 1997, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
+# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
+#endif
+
+#ifndef sc_pc
+
+/* Signal handlers are actually called:
+ void handler (int sig, int code, struct sigcontext *scp); */
+
+#include <mach/machine/fp_reg.h>
+
+/* State of this thread when the signal was taken. */
+struct sigcontext
+ {
+ /* These first members are machine-independent. */
+
+ int sc_onstack; /* Nonzero if running on sigstack. */
+ __sigset_t sc_mask; /* Blocked signals to restore. */
+
+ /* MiG reply port this thread is using. */
+ unsigned int sc_reply_port;
+
+ /* Port this thread is doing an interruptible RPC on. */
+ unsigned int sc_intr_port;
+
+ /* Error code associated with this signal (interpreted as `error_t'). */
+ int sc_error;
+
+ /* All following members are machine-dependent. The rest of this
+ structure is written to be laid out identically to:
+ {
+ struct i386_thread_state basic;
+ struct i386_float_state fpu;
+ }
+ trampoline.c knows this, so it must be changed if this changes. */
+
+#define sc_i386_thread_state sc_gs /* Beginning of correspondence. */
+ /* Segment registers. */
+ int sc_gs;
+ int sc_fs;
+ int sc_es;
+ int sc_ds;
+
+ /* "General" registers. These members are in the order that the i386
+ `pusha' and `popa' instructions use (`popa' ignores %esp). */
+ int sc_edi;
+ int sc_esi;
+ int sc_ebp;
+ int sc_esp; /* Not used; sc_uesp is used instead. */
+ int sc_ebx;
+ int sc_edx;
+ int sc_ecx;
+ int sc_eax;
+
+ int sc_eip; /* Instruction pointer. */
+ int sc_cs; /* Code segment register. */
+
+ int sc_efl; /* Processor flags. */
+
+ int sc_uesp; /* This stack pointer is used. */
+ int sc_ss; /* Stack segment register. */
+
+ /* Following mimics struct i386_float_state. Structures and symbolic
+ values can be found in <mach/i386/fp_reg.h>. */
+#define sc_i386_float_state sc_fpkind
+ int sc_fpkind; /* FP_NO, FP_387, etc. */
+ int sc_fpused; /* If zero, ignore rest of float state. */
+ struct i386_fp_save sc_fpsave;
+ struct i386_fp_regs sc_fpregs;
+ int sc_fpexcsr; /* FPSR including exception bits. */
+ };
+
+/* Traditional BSD names for some members. */
+#define sc_sp sc_uesp /* Stack pointer. */
+#define sc_fp sc_ebp /* Frame pointer. */
+#define sc_pc sc_eip /* Process counter. */
+#define sc_ps sc_efl
+
+
+/* Codes for SIGFPE. */
+#define FPE_INTOVF_TRAP 0x1 /* integer overflow */
+#define FPE_INTDIV_FAULT 0x2 /* integer divide by zero */
+#define FPE_FLTOVF_FAULT 0x3 /* floating overflow */
+#define FPE_FLTDIV_FAULT 0x4 /* floating divide by zero */
+#define FPE_FLTUND_FAULT 0x5 /* floating underflow */
+#define FPE_SUBRNG_FAULT 0x7 /* BOUNDS instruction failed */
+#define FPE_FLTDNR_FAULT 0x8 /* denormalized operand */
+#define FPE_FLTINX_FAULT 0x9 /* floating loss of precision */
+#define FPE_EMERR_FAULT 0xa /* mysterious emulation error 33 */
+#define FPE_EMBND_FAULT 0xb /* emulation BOUNDS instruction failed */
+
+/* Codes for SIGILL. */
+#define ILL_INVOPR_FAULT 0x1 /* invalid operation */
+#define ILL_STACK_FAULT 0x2 /* fault on microkernel stack access */
+#define ILL_FPEOPR_FAULT 0x3 /* invalid floating operation */
+
+/* Codes for SIGTRAP. */
+#define DBG_SINGLE_TRAP 0x1 /* single step */
+#define DBG_BRKPNT_FAULT 0x2 /* breakpoint instruction */
+
+#endif /* sc_pc */
diff --git a/libc/sysdeps/mach/hurd/i386/dl-machine.h b/libc/sysdeps/mach/hurd/i386/dl-machine.h
new file mode 100644
index 000000000..40f2ff29d
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/dl-machine.h
@@ -0,0 +1,7 @@
+/* Dynamic linker magic for Hurd/i386.
+ This file just gets us a call to _dl_first_init inserted
+ into the asm in sysdeps/i386/dl-machine.h that contains
+ the initializer code. */
+
+#define RTLD_START_SPECIAL_INIT "call _dl_init_first@PLT; movl (%esp), %edx"
+#include_next "dl-machine.h"
diff --git a/libc/sysdeps/mach/hurd/i386/exc2signal.c b/libc/sysdeps/mach/hurd/i386/exc2signal.c
new file mode 100644
index 000000000..a6bf750d7
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/exc2signal.c
@@ -0,0 +1,166 @@
+/* Translate Mach exception codes into signal numbers. i386 version.
+ Copyright (C) 1991,1992,1994,1996,1997,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <mach/exception.h>
+
+/* Translate the Mach exception codes, as received in an `exception_raise' RPC,
+ into a signal number and signal subcode. */
+
+void
+_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
+{
+ detail->error = 0;
+
+ switch (detail->exc)
+ {
+ default:
+ *signo = SIGIOT;
+ detail->code = detail->exc;
+ break;
+
+ case EXC_BAD_ACCESS:
+ if (detail->exc_code == KERN_INVALID_ADDRESS
+ || detail->exc_code == KERN_PROTECTION_FAILURE
+ || detail->exc_code == KERN_WRITE_PROTECTION_FAILURE)
+ *signo = SIGSEGV;
+ else
+ *signo = SIGBUS;
+ detail->code = detail->exc_subcode;
+ detail->error = detail->exc_code;
+ break;
+
+ case EXC_BAD_INSTRUCTION:
+ *signo = SIGILL;
+ if (detail->exc_code == EXC_I386_INVOP)
+ detail->code = ILL_INVOPR_FAULT;
+ else if (detail->exc_code == EXC_I386_STKFLT)
+ detail->code = ILL_STACK_FAULT;
+ else
+ detail->code = 0;
+ break;
+
+ case EXC_ARITHMETIC:
+ switch (detail->exc_code)
+ {
+ case EXC_I386_DIV: /* integer divide by zero */
+ *signo = SIGFPE;
+ detail->code = FPE_INTDIV_FAULT;
+ break;
+
+ case EXC_I386_INTO: /* integer overflow */
+ *signo = SIGFPE;
+ detail->code = FPE_INTOVF_TRAP;
+ break;
+
+ /* These aren't anywhere documented or used in Mach 3.0. */
+ case EXC_I386_NOEXT:
+ case EXC_I386_EXTOVR:
+ default:
+ *signo = SIGFPE;
+ detail->code = 0;
+ break;
+
+ case EXC_I386_EXTERR:
+ /* Subcode is the fp_status word saved by the hardware.
+ Give an error code corresponding to the first bit set. */
+ if (detail->exc_subcode & FPS_IE)
+ {
+ *signo = SIGILL;
+ detail->code = ILL_FPEOPR_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_DE)
+ {
+ *signo = SIGFPE;
+ detail->code = FPE_FLTDNR_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_ZE)
+ {
+ *signo = SIGFPE;
+ detail->code = FPE_FLTDIV_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_OE)
+ {
+ *signo = SIGFPE;
+ detail->code = FPE_FLTOVF_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_UE)
+ {
+ *signo = SIGFPE;
+ detail->code = FPE_FLTUND_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_PE)
+ {
+ *signo = SIGFPE;
+ detail->code = FPE_FLTINX_FAULT;
+ }
+ else
+ {
+ *signo = SIGFPE;
+ detail->code = 0;
+ }
+ break;
+
+ /* These two can only be arithmetic exceptions if we
+ are in V86 mode, which sounds like emulation to me.
+ (See Mach 3.0 i386/trap.c.) */
+ case EXC_I386_EMERR:
+ *signo = SIGFPE;
+ detail->code = FPE_EMERR_FAULT;
+ break;
+ case EXC_I386_BOUND:
+ *signo = SIGFPE;
+ detail->code = FPE_EMBND_FAULT;
+ break;
+ }
+ break;
+
+ case EXC_EMULATION:
+ /* 3.0 doesn't give this one, why, I don't know. */
+ *signo = SIGEMT;
+ detail->code = 0;
+ break;
+
+ case EXC_SOFTWARE:
+ /* The only time we get this in Mach 3.0
+ is for an out of bounds trap. */
+ if (detail->exc_code == EXC_I386_BOUND)
+ {
+ *signo = SIGFPE;
+ detail->code = FPE_SUBRNG_FAULT;
+ }
+ else
+ {
+ *signo = SIGEMT;
+ detail->code = 0;
+ }
+ break;
+
+ case EXC_BREAKPOINT:
+ *signo = SIGTRAP;
+ if (detail->exc_code == EXC_I386_SGL)
+ detail->code = DBG_SINGLE_TRAP;
+ else if (detail->exc_code == EXC_I386_BPT)
+ detail->code = DBG_BRKPNT_FAULT;
+ else
+ detail->code = 0;
+ break;
+ }
+}
diff --git a/libc/sysdeps/mach/hurd/i386/init-first.c b/libc/sysdeps/mach/hurd/i386/init-first.c
new file mode 100644
index 000000000..f9a7a58de
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/init-first.c
@@ -0,0 +1,393 @@
+/* Initialization code run first thing by the ELF startup code. For i386/Hurd.
+ Copyright (C) 1995,96,97,98,99,2000,01,02,03,04,05
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <hurd.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sysdep.h>
+#include <set-hooks.h>
+#include "hurdstartup.h"
+#include "hurdmalloc.h" /* XXX */
+#include "../locale/localeinfo.h"
+
+#include <ldsodefs.h>
+#include <fpu_control.h>
+
+extern void __mach_init (void);
+extern void __init_misc (int, char **, char **);
+#ifdef USE_NONOPTION_FLAGS
+extern void __getopt_clean_environment (char **);
+#endif
+#ifndef SHARED
+extern void _dl_non_dynamic_init (void) internal_function;
+#endif
+extern void __libc_global_ctors (void);
+
+unsigned int __hurd_threadvar_max;
+unsigned long int __hurd_threadvar_stack_offset;
+unsigned long int __hurd_threadvar_stack_mask;
+
+#ifndef SHARED
+int __libc_enable_secure;
+#endif
+int __libc_multiple_libcs attribute_hidden = 1;
+
+extern int __libc_argc attribute_hidden;
+extern char **__libc_argv attribute_hidden;
+extern char **_dl_argv;
+
+extern void *(*_cthread_init_routine) (void) __attribute__ ((weak));
+void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__));
+
+/* Things that want to be run before _hurd_init or much anything else.
+ Importantly, these are called before anything tries to use malloc. */
+DEFINE_HOOK (_hurd_preinit_hook, (void));
+
+
+/* We call this once the Hurd magic is all set up and we are ready to be a
+ Posixoid program. This does the same things the generic version does. */
+static void
+posixland_init (int argc, char **argv, char **envp)
+{
+ __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up;
+
+ /* Make sure we don't initialize twice. */
+ if (!__libc_multiple_libcs)
+ {
+ /* Set the FPU control word to the proper default value. */
+ __setfpucw (__fpu_control);
+ }
+
+ /* Save the command-line arguments. */
+ __libc_argc = argc;
+ __libc_argv = argv;
+ __environ = envp;
+
+#ifndef SHARED
+ _dl_non_dynamic_init ();
+#endif
+ __init_misc (argc, argv, envp);
+
+#ifdef USE_NONOPTION_FLAGS
+ /* This is a hack to make the special getopt in GNU libc working. */
+ __getopt_clean_environment (envp);
+#endif
+
+#ifdef SHARED
+ __libc_global_ctors ();
+#endif
+}
+
+
+static void
+init1 (int argc, char *arg0, ...)
+{
+ char **argv = &arg0;
+ char **envp = &argv[argc + 1];
+ struct hurd_startup_data *d;
+#ifndef SHARED
+ extern ElfW(Phdr) *_dl_phdr;
+ extern size_t _dl_phnum;
+#endif
+
+ while (*envp)
+ ++envp;
+ d = (void *) ++envp;
+
+ /* If we are the bootstrap task started by the kernel,
+ then after the environment pointers there is no Hurd
+ data block; the argument strings start there. */
+ if ((void *) d == argv[0])
+ {
+#ifndef SHARED
+ /* We may need to see our own phdrs, e.g. for TLS setup.
+ Try the usual kludge to find the headers without help from
+ the exec server. */
+ extern const void _start;
+ const ElfW(Ehdr) *const ehdr = &_start;
+ _dl_phdr = (ElfW(Phdr) *) ((const void *) ehdr + ehdr->e_phoff);
+ _dl_phnum = ehdr->e_phnum;
+ assert (ehdr->e_phentsize == sizeof (ElfW(Phdr)));
+#endif
+ return;
+ }
+
+#ifndef SHARED
+ __libc_enable_secure = d->flags & EXEC_SECURE;
+
+ _dl_phdr = (ElfW(Phdr) *) d->phdr;
+ _dl_phnum = d->phdrsz / sizeof (ElfW(Phdr));
+ assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0);
+#endif
+
+ _hurd_init_dtable = d->dtable;
+ _hurd_init_dtablesize = d->dtablesize;
+
+ {
+ /* Check if the stack we are now on is different from
+ the one described by _hurd_stack_{base,size}. */
+
+ char dummy;
+ const vm_address_t newsp = (vm_address_t) &dummy;
+
+ if (d->stack_size != 0 && (newsp < d->stack_base ||
+ newsp - d->stack_base > d->stack_size))
+ /* The new stack pointer does not intersect with the
+ stack the exec server set up for us, so free that stack. */
+ __vm_deallocate (__mach_task_self (), d->stack_base, d->stack_size);
+ }
+
+ if (d->portarray || d->intarray)
+ /* Initialize library data structures, start signal processing, etc. */
+ _hurd_init (d->flags, argv,
+ d->portarray, d->portarraysize,
+ d->intarray, d->intarraysize);
+}
+
+
+static inline void
+init (int *data)
+{
+ int argc = *data;
+ char **argv = (void *) (data + 1);
+ char **envp = &argv[argc + 1];
+ struct hurd_startup_data *d;
+ unsigned long int threadvars[_HURD_THREADVAR_MAX];
+
+ /* Provide temporary storage for thread-specific variables on the
+ startup stack so the cthreads initialization code can use them
+ for malloc et al, or so we can use malloc below for the real
+ threadvars array. */
+ memset (threadvars, 0, sizeof threadvars);
+ threadvars[_HURD_THREADVAR_LOCALE] = (unsigned long int) &_nl_global_locale;
+ __hurd_threadvar_stack_offset = (unsigned long int) threadvars;
+
+ /* Since the cthreads initialization code uses malloc, and the
+ malloc initialization code needs to get at the environment, make
+ sure we can find it. We'll need to do this again later on since
+ switching stacks changes the location where the environment is
+ stored. */
+ __environ = envp;
+
+ while (*envp)
+ ++envp;
+ d = (void *) ++envp;
+
+ /* The user might have defined a value for this, to get more variables.
+ Otherwise it will be zero on startup. We must make sure it is set
+ properly before before cthreads initialization, so cthreads can know
+ how much space to leave for thread variables. */
+ if (__hurd_threadvar_max < _HURD_THREADVAR_MAX)
+ __hurd_threadvar_max = _HURD_THREADVAR_MAX;
+
+
+ /* After possibly switching stacks, call `init1' (above) with the user
+ code as the return address, and the argument data immediately above
+ that on the stack. */
+
+ if (&_cthread_init_routine && _cthread_init_routine)
+ {
+ /* Initialize cthreads, which will allocate us a new stack to run on. */
+ int *newsp = (*_cthread_init_routine) ();
+ struct hurd_startup_data *od;
+
+ void switch_stacks (void);
+
+ /* Copy per-thread variables from that temporary
+ area onto the new cthread stack. */
+ memcpy (__hurd_threadvar_location_from_sp (0, newsp),
+ threadvars, sizeof threadvars);
+
+ /* Copy the argdata from the old stack to the new one. */
+ newsp = memcpy (newsp - ((char *) &d[1] - (char *) data), data,
+ (char *) d - (char *) data);
+
+#ifdef SHARED
+ /* And readjust the dynamic linker's idea of where the argument
+ vector lives. */
+ assert (_dl_argv == argv);
+ _dl_argv = (void *) (newsp + 1);
+#endif
+
+ /* Set up the Hurd startup data block immediately following
+ the argument and environment pointers on the new stack. */
+ od = ((void *) newsp + ((char *) d - (char *) data));
+ if ((void *) argv[0] == d)
+ /* We were started up by the kernel with arguments on the stack.
+ There is no Hurd startup data, so zero the block. */
+ memset (od, 0, sizeof *od);
+ else
+ /* Copy the Hurd startup data block to the new stack. */
+ *od = *d;
+
+ /* Push the user code address on the top of the new stack. It will
+ be the return address for `init1'; we will jump there with NEWSP
+ as the stack pointer. */
+ *--newsp = data[-1];
+ ((void **) data)[-1] = switch_stacks;
+ /* Force NEWSP into %ecx and &init1 into %eax, which are not restored
+ by function return. */
+ asm volatile ("# a %0 c %1" : : "a" (newsp), "c" (&init1));
+ }
+ else
+ {
+ /* We are not using cthreads, so we will have just a single allocated
+ area for the per-thread variables of the main user thread. */
+ unsigned long int *array;
+ unsigned int i;
+ int usercode;
+
+ void call_init1 (void);
+
+ array = malloc (__hurd_threadvar_max * sizeof (unsigned long int));
+ if (array == NULL)
+ __libc_fatal ("Can't allocate single-threaded thread variables.");
+
+ /* Copy per-thread variables from the temporary array into the
+ newly malloc'd space. */
+ memcpy (array, threadvars, sizeof threadvars);
+ __hurd_threadvar_stack_offset = (unsigned long int) array;
+ for (i = _HURD_THREADVAR_MAX; i < __hurd_threadvar_max; ++i)
+ array[i] = 0;
+
+ /* The argument data is just above the stack frame we will unwind by
+ returning. Mutate our own return address to run the code below. */
+ usercode = data[-1];
+ data[-1] = (int) &call_init1;
+ /* Force USERCODE into %eax and &init1 into %ecx, which are not
+ restored by function return. */
+ asm volatile ("# a %0 c %1" : : "a" (usercode), "c" (&init1));
+ }
+}
+
+/* These bits of inline assembler used to be located inside `init'.
+ However they were optimized away by gcc 2.95. */
+
+/* The return address of `init' above, was redirected to here, so at
+ this point our stack is unwound and callers' registers restored.
+ Only %ecx and %eax are call-clobbered and thus still have the
+ values we set just above. Fetch from there the new stack pointer
+ we will run on, and jmp to the run-time address of `init1'; when it
+ returns, it will run the user code with the argument data at the
+ top of the stack. */
+asm ("switch_stacks:\n"
+ " movl %eax, %esp\n"
+ " jmp *%ecx");
+
+/* As in the stack-switching case, at this point our stack is unwound
+ and callers' registers restored, and only %ecx and %eax communicate
+ values from the lines above. In this case we have stashed in %eax
+ the user code return address. Push it on the top of the stack so
+ it acts as init1's return address, and then jump there. */
+asm ("call_init1:\n"
+ " push %eax\n"
+ " jmp *%ecx\n");
+
+
+/* Do the first essential initializations that must precede all else. */
+static inline void
+first_init (void)
+{
+ /* Initialize data structures so we can do RPCs. */
+ __mach_init ();
+
+ RUN_HOOK (_hurd_preinit_hook, ());
+}
+
+#ifdef SHARED
+/* This function is called specially by the dynamic linker to do early
+ initialization of the shared C library before normal initializers
+ expecting a Posixoid environment can run. It gets called with the
+ stack set up just as the user will see it, so it can switch stacks. */
+
+void
+_dl_init_first (void)
+{
+ first_init ();
+
+ init ((int *) __builtin_frame_address (0) + 2);
+}
+#endif
+
+
+#ifdef SHARED
+/* The regular posixland initialization is what goes into libc's
+ normal initializer. */
+/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
+ pointer in the dynamic section based solely on that. It is convention
+ for this function to be in the `.init' section, but the symbol name is
+ the only thing that really matters!! */
+strong_alias (posixland_init, _init);
+
+void
+__libc_init_first (int argc, char **argv, char **envp)
+{
+ /* Everything was done in the shared library initializer, _init. */
+}
+#else
+strong_alias (posixland_init, __libc_init_first);
+
+
+/* XXX This is all a crock and I am not happy with it.
+ This poorly-named function is called by static-start.S,
+ which should not exist at all. */
+void
+_hurd_stack_setup (void)
+{
+ intptr_t caller = (intptr_t) __builtin_return_address (0);
+
+ void doinit (intptr_t *data)
+ {
+ /* This function gets called with the argument data at TOS. */
+ void doinit1 (void)
+ {
+ init ((int *) __builtin_frame_address (0) + 2);
+ }
+
+ /* Push the user return address after the argument data, and then
+ jump to `doinit1' (above), so it is as if __libc_init_first's
+ caller had called `doinit1' with the argument data already on the
+ stack. */
+ *--data = caller;
+ asm volatile ("movl %0, %%esp\n" /* Switch to new outermost stack. */
+ "movl $0, %%ebp\n" /* Clear outermost frame pointer. */
+ "jmp *%1" : : "r" (data), "r" (&doinit1) : "sp");
+ /* NOTREACHED */
+ }
+
+ first_init ();
+
+ _hurd_startup ((void **) __builtin_frame_address (0) + 2, &doinit);
+}
+#endif
+
+
+/* This function is defined here so that if this file ever gets into
+ ld.so we will get a link error. Having this file silently included
+ in ld.so causes disaster, because the _init definition above will
+ cause ld.so to gain an init function, which is not a cool thing. */
+
+void
+_dl_start (void)
+{
+ abort ();
+}
diff --git a/libc/sysdeps/mach/hurd/i386/intr-msg.h b/libc/sysdeps/mach/hurd/i386/intr-msg.h
new file mode 100644
index 000000000..8b9b34b37
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/intr-msg.h
@@ -0,0 +1,113 @@
+/* Machine-dependent details of interruptible RPC messaging. i386 version.
+ Copyright (C) 1995,96,97,99,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* Note that we must mark OPTION and TIMEOUT as outputs of this operation,
+ to indicate that the signal thread might mutate them as part
+ of sending us to a signal handler. */
+#define INTR_MSG_TRAP(msg, option, send_size, rcv_size, rcv_name, timeout, notify) \
+({ \
+ error_t err; \
+ asm (".globl _hurd_intr_rpc_msg_do_trap\n" \
+ ".globl _hurd_intr_rpc_msg_in_trap\n" \
+ ".globl _hurd_intr_rpc_msg_cx_sp\n" \
+ ".globl _hurd_intr_rpc_msg_sp_restored\n" \
+ " movl %%esp, %%ecx\n" \
+ " leal %3, %%esp\n" \
+ "_hurd_intr_rpc_msg_cx_sp: movl $-25, %%eax\n" \
+ "_hurd_intr_rpc_msg_do_trap: lcall $7, $0 # status in %0\n" \
+ "_hurd_intr_rpc_msg_in_trap: movl %%ecx, %%esp\n" \
+ "_hurd_intr_rpc_msg_sp_restored:" \
+ : "=a" (err), "=m" (option), "=m" (timeout) \
+ : "m" ((&msg)[-1]), "1" (option), "2" (timeout) \
+ : "%ecx"); \
+ err; \
+})
+
+
+static void inline
+INTR_MSG_BACK_OUT (struct i386_thread_state *state)
+{
+ extern const void _hurd_intr_rpc_msg_cx_sp;
+ if (state->eip >= (natural_t) &_hurd_intr_rpc_msg_cx_sp)
+ state->uesp = state->ecx;
+ else
+ state->ecx = state->uesp;
+}
+
+#include "hurdfault.h"
+
+/* This cannot be an inline function because it calls setjmp. */
+#define SYSCALL_EXAMINE(state, callno) \
+({ \
+ struct { unsigned int c[2]; } *p = (void *) ((state)->eip - 7); \
+ int result; \
+ if (_hurdsig_catch_memory_fault (p)) \
+ return 0; \
+ if (result = p->c[0] == 0x0000009a && (p->c[1] & 0x00ffffff) == 0x00000700) \
+ /* The PC is just after an `lcall $7,$0' instruction. \
+ This is a system call in progress; %eax holds the call number. */ \
+ *(callno) = (state)->eax; \
+ _hurdsig_end_catch_fault (); \
+ result; \
+})
+
+
+struct mach_msg_trap_args
+ {
+ void *retaddr; /* Address mach_msg_trap will return to. */
+ /* This is the order of arguments to mach_msg_trap. */
+ mach_msg_header_t *msg;
+ mach_msg_option_t option;
+ mach_msg_size_t send_size;
+ mach_msg_size_t rcv_size;
+ mach_port_t rcv_name;
+ mach_msg_timeout_t timeout;
+ mach_port_t notify;
+ };
+
+
+/* This cannot be an inline function because it calls setjmp. */
+#define MSG_EXAMINE(state, msgid, rcvname, send_name, opt, tmout) \
+({ \
+ const struct mach_msg_trap_args *args = (const void *) (state)->uesp; \
+ mach_msg_header_t *msg; \
+ _hurdsig_catch_memory_fault (args) ? -1 : \
+ ({ \
+ msg = args->msg; \
+ *(opt) = args->option; \
+ *(tmout) = args->timeout; \
+ *(rcvname) = args->rcv_name; \
+ _hurdsig_end_catch_fault (); \
+ if (msg == 0) \
+ { \
+ *(send_name) = MACH_PORT_NULL; \
+ *(msgid) = 0; \
+ } \
+ else \
+ { \
+ if (_hurdsig_catch_memory_fault (msg)) \
+ return -1; \
+ *(send_name) = msg->msgh_remote_port; \
+ *(msgid) = msg->msgh_id; \
+ _hurdsig_end_catch_fault (); \
+ } \
+ 0; \
+ }); \
+})
diff --git a/libc/sysdeps/mach/hurd/i386/ioperm.c b/libc/sysdeps/mach/hurd/i386/ioperm.c
new file mode 100644
index 000000000..be243d1ac
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/ioperm.c
@@ -0,0 +1,54 @@
+/* Access to hardware i/o ports. Hurd/x86 version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/io.h>
+#include <hurd.h>
+#include <mach/i386/mach_i386.h>
+
+int
+ioperm (unsigned long int from, unsigned long int num, int turn_on)
+{
+#if ! HAVE_I386_IO_PERM_MODIFY
+ return __hurd_fail (ENOSYS);
+#else
+ error_t err;
+ device_t devmaster;
+
+ /* With the device master port we get a capability that represents
+ this range of io ports. */
+ err = __get_privileged_ports (NULL, &devmaster);
+ if (! err)
+ {
+ io_perm_t perm;
+ err = __i386_io_perm_create (devmaster, from, from + num - 1, &perm);
+ __mach_port_deallocate (__mach_task_self (), devmaster);
+ if (! err)
+ {
+ /* Now we add or remove that set from our task's bitmap. */
+ err = __i386_io_perm_modify (__mach_task_self (), perm, turn_on);
+ __mach_port_deallocate (__mach_task_self (), perm);
+ }
+
+ if (err == MIG_BAD_ID) /* Old kernels don't have these RPCs. */
+ err = ENOSYS;
+ }
+
+ return err ? __hurd_fail (err) : 0;
+#endif
+}
diff --git a/libc/sysdeps/mach/hurd/i386/longjmp-ts.c b/libc/sysdeps/mach/hurd/i386/longjmp-ts.c
new file mode 100644
index 000000000..c902002cb
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/longjmp-ts.c
@@ -0,0 +1,40 @@
+/* Perform a `longjmp' on a Mach thread_state. i386 version.
+ Copyright (C) 1991, 1994, 1995, 1997, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd/signal.h>
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <mach/thread_status.h>
+
+
+/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'. */
+
+void
+_hurd_longjmp_thread_state (void *state, jmp_buf env, int val)
+{
+ struct i386_thread_state *ts = state;
+
+ ts->ebx = env[0].__jmpbuf[JB_BX];
+ ts->esi = env[0].__jmpbuf[JB_SI];
+ ts->edi = env[0].__jmpbuf[JB_DI];
+ ts->ebp = env[0].__jmpbuf[JB_BP];
+ ts->uesp = env[0].__jmpbuf[JB_SP];
+ ts->eip = env[0].__jmpbuf[JB_PC];
+ ts->eax = val ?: 1;
+}
diff --git a/libc/sysdeps/mach/hurd/i386/sigcontextinfo.h b/libc/sysdeps/mach/hurd/i386/sigcontextinfo.h
new file mode 100644
index 000000000..a3bad2af8
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/sigcontextinfo.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define SIGCONTEXT struct sigcontext
+#define SIGCONTEXT_EXTRA_ARGS
+#define GET_PC(ctx) ((void *) (ctx).sc_eip)
+#define GET_FRAME(ctx) ((void *) (ctx).sc_ebp)
+#define GET_STACK(ctx) ((void *) (ctx).sc_uesp)
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/libc/sysdeps/mach/hurd/i386/sigreturn.c b/libc/sysdeps/mach/hurd/i386/sigreturn.c
new file mode 100644
index 000000000..60b0d006a
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/sigreturn.c
@@ -0,0 +1,140 @@
+/* Copyright (C) 1991,92,94,95,96,97,98,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+register int *sp asm ("%esp");
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/threadvar.h>
+#include <hurd/msg.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+__sigreturn (struct sigcontext *scp)
+{
+ struct hurd_sigstate *ss;
+ struct hurd_userlink *link = (void *) &scp[1];
+ mach_port_t *reply_port;
+
+ if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ ss = _hurd_self_sigstate ();
+ __spin_lock (&ss->lock);
+
+ /* Remove the link on the `active resources' chain added by
+ _hurd_setup_sighandler. Its purpose was to make sure
+ that we got called; now we have, it is done. */
+ _hurd_userlink_unlink (link);
+
+ /* Restore the set of blocked signals, and the intr_port slot. */
+ ss->blocked = scp->sc_mask;
+ ss->intr_port = scp->sc_intr_port;
+
+ /* Check for pending signals that were blocked by the old set. */
+ if (ss->pending & ~ss->blocked)
+ {
+ /* There are pending signals that just became unblocked. Wake up the
+ signal thread to deliver them. But first, squirrel away SCP where
+ the signal thread will notice it if it runs another handler, and
+ arrange to have us called over again in the new reality. */
+ ss->context = scp;
+ __spin_unlock (&ss->lock);
+ __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
+ /* If a pending signal was handled, sig_post never returned.
+ If it did return, the pending signal didn't run a handler;
+ proceed as usual. */
+ __spin_lock (&ss->lock);
+ ss->context = NULL;
+ }
+
+ if (scp->sc_onstack)
+ {
+ ss->sigaltstack.ss_flags &= ~SS_ONSTACK; /* XXX threadvars */
+ /* XXX cannot unlock until off sigstack */
+ abort ();
+ }
+ else
+ __spin_unlock (&ss->lock);
+
+ /* Destroy the MiG reply port used by the signal handler, and restore the
+ reply port in use by the thread when interrupted. */
+ reply_port =
+ (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY);
+ if (*reply_port)
+ {
+ mach_port_t port = *reply_port;
+
+ /* Assigning MACH_PORT_DEAD here tells libc's mig_get_reply_port not to
+ get another reply port, but avoids mig_dealloc_reply_port trying to
+ deallocate it after the receive fails (which it will, because the
+ reply port will be bogus, whether we do this or not). */
+ *reply_port = MACH_PORT_DEAD;
+
+ __mach_port_destroy (__mach_task_self (), port);
+ }
+ *reply_port = scp->sc_reply_port;
+
+ if (scp->sc_fpused)
+ /* Restore the FPU state. Mach conveniently stores the state
+ in the format the i387 `frstor' instruction uses to restore it. */
+ asm volatile ("frstor %0" : : "m" (scp->sc_fpsave));
+
+ {
+ /* There are convenient instructions to pop state off the stack, so we
+ copy the registers onto the user's stack, switch there, pop and
+ return. */
+
+ int *usp = (int *) scp->sc_uesp;
+
+ *--usp = scp->sc_eip;
+ *--usp = scp->sc_efl;
+ memcpy (usp -= 12, &scp->sc_i386_thread_state, 12 * sizeof (int));
+
+ sp = usp;
+
+#define A(line) asm volatile (#line)
+ /* The members in the sigcontext are arranged in this order
+ so we can pop them easily. */
+
+ /* Pop the segment registers (except %cs and %ss, done last). */
+ A (popl %gs);
+ A (popl %fs);
+ A (popl %es);
+ A (popl %ds);
+ /* Pop the general registers. */
+ A (popa);
+ /* Pop the processor flags. */
+ A (popf);
+ /* Return to the saved PC. */
+ A (ret);
+
+ /* Firewall. */
+ A (hlt);
+#undef A
+ }
+
+ /* NOTREACHED */
+ return -1;
+}
+
+weak_alias (__sigreturn, sigreturn)
diff --git a/libc/sysdeps/mach/hurd/i386/static-start.S b/libc/sysdeps/mach/hurd/i386/static-start.S
new file mode 100644
index 000000000..e80d5b755
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/static-start.S
@@ -0,0 +1,28 @@
+/* Startup code for statically linked Hurd/i386 binaries.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+ .text
+ .globl _start
+_start:
+ call _hurd_stack_setup
+ xorl %edx, %edx
+ jmp _start1
+
+#define _start _start1
+#include <sysdeps/i386/elf/start.S>
diff --git a/libc/sysdeps/mach/hurd/i386/sys/io.h b/libc/sysdeps/mach/hurd/i386/sys/io.h
new file mode 100644
index 000000000..49ac9985a
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/sys/io.h
@@ -0,0 +1,178 @@
+/* Access to hardware i/o ports. GNU/x86 version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IO_H
+#define _SYS_IO_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* If TURN_ON is TRUE, request for permission to do direct i/o on the
+ port numbers in the range [FROM,FROM+NUM-1]. Otherwise, turn I/O
+ permission off for that range. This call requires root privileges. */
+extern int ioperm (unsigned long int __from, unsigned long int __num,
+ int __turn_on) __THROW;
+
+/* Set the I/O privilege level to LEVEL. If LEVEL>3, permission to
+ access any I/O port is granted. This call requires root
+ privileges. */
+extern int iopl (int __level) __THROW;
+
+#if defined __GNUC__ && __GNUC__ >= 2
+
+static __inline unsigned char
+inb (unsigned short int port)
+{
+ unsigned char _v;
+
+ __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned char
+inb_p (unsigned short int port)
+{
+ unsigned char _v;
+
+ __asm__ __volatile__ ("inb %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned short int
+inw (unsigned short int port)
+{
+ unsigned short _v;
+
+ __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned short int
+inw_p (unsigned short int port)
+{
+ unsigned short int _v;
+
+ __asm__ __volatile__ ("inw %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned int
+inl (unsigned short int port)
+{
+ unsigned int _v;
+
+ __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned int
+inl_p (unsigned short int port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("inl %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline void
+outb (unsigned char value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port));
+}
+
+static __inline void
+outb_p (unsigned char value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outb %b0,%w1\noutb %%al,$0x80": :"a" (value),
+ "Nd" (port));
+}
+
+static __inline void
+outw (unsigned short int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port));
+
+}
+
+static __inline void
+outw_p (unsigned short int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outw %w0,%w1\noutb %%al,$0x80": :"a" (value),
+ "Nd" (port));
+}
+
+static __inline void
+outl (unsigned int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port));
+}
+
+static __inline void
+outl_p (unsigned int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outl %0,%w1\noutb %%al,$0x80": :"a" (value),
+ "Nd" (port));
+}
+
+static __inline void
+insb (unsigned short int port, void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; insb":"=D" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+insw (unsigned short int port, void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; insw":"=D" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+insl (unsigned short int port, void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; insl":"=D" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+outsb (unsigned short int port, const void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; outsb":"=S" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+outsw (unsigned short int port, const void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; outsw":"=S" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+outsl (unsigned short int port, const void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; outsl":"=S" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+#endif /* GNU C */
+
+__END_DECLS
+#endif /* _SYS_IO_H */
diff --git a/libc/sysdeps/mach/hurd/i386/tls.h b/libc/sysdeps/mach/hurd/i386/tls.h
new file mode 100644
index 000000000..223a47d2f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/tls.h
@@ -0,0 +1,174 @@
+/* Definitions for thread-local data handling. Hurd/i386 version.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _I386_TLS_H
+#define _I386_TLS_H
+
+#if defined HAVE_TLS_SUPPORT
+
+/* Some things really need not be machine-dependent. */
+# include <sysdeps/mach/hurd/tls.h>
+
+/* Indiciate that TLS support is available. */
+# define USE_TLS 1
+
+/* The TCB can have any size and the memory following the address the
+ thread pointer points to is unspecified. Allocate the TCB there. */
+# define TLS_TCB_AT_TP 1
+
+# ifndef ASSEMBLER
+
+/* Use i386-specific RPCs to arrange that %gs segment register prefix
+ addresses the TCB in each thread. */
+# include <mach/i386/mach_i386.h>
+
+# ifndef HAVE_I386_SET_GDT
+# define __i386_set_gdt(thr, sel, desc) ((void) (thr), (void) (sel), (void) (desc), MIG_BAD_ID)
+# endif
+
+# include <errno.h>
+# include <assert.h>
+
+#define HURD_TLS_DESC_DECL(desc, tcb) \
+ struct descriptor desc = \
+ { /* low word: */ \
+ 0xffff /* limit 0..15 */ \
+ | (((unsigned int) (tcb)) << 16) /* base 0..15 */ \
+ , /* high word: */ \
+ ((((unsigned int) (tcb)) >> 16) & 0xff) /* base 16..23 */ \
+ | ((0x12 | 0x60 | 0x80) << 8) /* access = ACC_DATA_W|ACC_PL_U|ACC_P */ \
+ | (0xf << 16) /* limit 16..19 */ \
+ | ((4 | 8) << 20) /* granularity = SZ_32|SZ_G */ \
+ | (((unsigned int) (tcb)) & 0xff000000) /* base 24..31 */ \
+ }
+
+
+static inline const char * __attribute__ ((unused))
+_hurd_tls_init (tcbhead_t *tcb, int secondcall)
+{
+ HURD_TLS_DESC_DECL (desc, tcb);
+
+ if (!secondcall)
+ {
+ /* This field is used by TLS accesses to get our "thread pointer"
+ from the TLS point of view. */
+ tcb->tcb = tcb;
+
+ /* Cache our thread port. */
+ tcb->self = __mach_thread_self ();
+
+ /* Get the first available selector. */
+ int sel = -1;
+ error_t err = __i386_set_gdt (tcb->self, &sel, desc);
+ if (err == MIG_BAD_ID)
+ {
+ /* Old kernel, use a per-thread LDT. */
+ sel = 0x27;
+ err = __i386_set_ldt (tcb->self, sel, &desc, 1);
+ assert_perror (err);
+ if (err)
+ return "i386_set_ldt failed";
+ }
+ else if (err)
+ {
+ assert_perror (err); /* Separate from above with different line #. */
+ return "i386_set_gdt failed";
+ }
+
+ /* Now install the new selector. */
+ asm volatile ("mov %w0, %%gs" :: "q" (sel));
+ }
+ else
+ {
+ /* Fetch the selector set by the first call. */
+ int sel;
+ asm ("mov %%gs, %w0" : "=q" (sel) : "0" (0));
+ if (__builtin_expect (sel, 0x50) & 4) /* LDT selector */
+ {
+ error_t err = __i386_set_ldt (tcb->self, sel, &desc, 1);
+ assert_perror (err);
+ if (err)
+ return "i386_set_ldt failed";
+ }
+ else
+ {
+ error_t err = __i386_set_gdt (tcb->self, &sel, desc);
+ assert_perror (err);
+ if (err)
+ return "i386_set_gdt failed";
+ }
+ }
+
+ return 0;
+}
+
+/* Code to initially initialize the thread pointer. This might need
+ special attention since 'errno' is not yet available and if the
+ operation can cause a failure 'errno' must not be touched. */
+# define TLS_INIT_TP(descr, secondcall) \
+ _hurd_tls_init ((tcbhead_t *) (descr), (secondcall))
+# define TLS_INIT_TP_EXPENSIVE 1
+
+/* Return the TCB address of the current thread. */
+# define THREAD_SELF \
+ ({ tcbhead_t *__tcb; \
+ __asm__ ("movl %%gs:%c1,%0" : "=r" (__tcb) \
+ : "i" (offsetof (tcbhead_t, tcb))); \
+ __tcb;})
+
+/* Install new dtv for current thread. */
+# define INSTALL_NEW_DTV(dtvp) \
+ ({ asm volatile ("movl %0,%%gs:%P1" \
+ : : "ir" (dtvp), "i" (offsetof (tcbhead_t, dtv))); })
+
+/* Return the address of the dtv for the current thread. */
+# define THREAD_DTV() \
+ ({ dtv_t *_dtv; \
+ asm ("movl %%gs:%P1,%0" : "=q" (_dtv) : "i" (offsetof (tcbhead_t, dtv)));\
+ _dtv; })
+
+#include <mach/machine/thread_status.h>
+
+/* Set up TLS in the new thread of a fork child, copying from our own. */
+static inline error_t __attribute__ ((unused))
+_hurd_tls_fork (thread_t child, struct i386_thread_state *state)
+{
+ /* Fetch the selector set by _hurd_tls_init. */
+ int sel;
+ asm ("mov %%gs, %w0" : "=q" (sel) : "0" (0));
+ if (sel == state->ds) /* _hurd_tls_init was never called. */
+ return 0;
+
+ tcbhead_t *const tcb = THREAD_SELF;
+ HURD_TLS_DESC_DECL (desc, tcb);
+ error_t err;
+
+ if (__builtin_expect (sel, 0x50) & 4) /* LDT selector */
+ err = __i386_set_ldt (child, sel, &desc, 1);
+ else
+ err = __i386_set_gdt (child, &sel, desc);
+
+ state->gs = sel;
+ return err;
+}
+
+# endif /* !ASSEMBLER */
+#endif /* HAVE_TLS_SUPPORT */
+
+#endif /* i386/tls.h */
diff --git a/libc/sysdeps/mach/hurd/i386/trampoline.c b/libc/sysdeps/mach/hurd/i386/trampoline.c
new file mode 100644
index 000000000..dddc6f3ef
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/i386/trampoline.c
@@ -0,0 +1,264 @@
+/* Set thread_state for sighandler, and sigcontext to recover. i386 version.
+ Copyright (C) 1994,1995,1996,1997,1998,1999,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd/signal.h>
+#include <hurd/userlink.h>
+#include <thread_state.h>
+#include <assert.h>
+#include <errno.h>
+#include "hurdfault.h"
+#include <intr-msg.h>
+
+
+struct sigcontext *
+_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+ int signo, struct hurd_signal_detail *detail,
+ volatile int rpc_wait,
+ struct machine_thread_all_state *state)
+{
+ void trampoline (void);
+ void rpc_wait_trampoline (void);
+ void firewall (void);
+ extern const void _hurd_intr_rpc_msg_in_trap;
+ extern const void _hurd_intr_rpc_msg_cx_sp;
+ extern const void _hurd_intr_rpc_msg_sp_restored;
+ void *volatile sigsp;
+ struct sigcontext *scp;
+ struct
+ {
+ int signo;
+ long int sigcode;
+ struct sigcontext *scp; /* Points to ctx, below. */
+ void *sigreturn_addr;
+ void *sigreturn_returns_here;
+ struct sigcontext *return_scp; /* Same; arg to sigreturn. */
+ struct sigcontext ctx;
+ struct hurd_userlink link;
+ } *stackframe;
+
+ if (ss->context)
+ {
+ /* We have a previous sigcontext that sigreturn was about
+ to restore when another signal arrived. We will just base
+ our setup on that. */
+ if (! _hurdsig_catch_memory_fault (ss->context))
+ {
+ memcpy (&state->basic, &ss->context->sc_i386_thread_state,
+ sizeof (state->basic));
+ memcpy (&state->fpu, &ss->context->sc_i386_float_state,
+ sizeof (state->fpu));
+ state->set |= (1 << i386_THREAD_STATE) | (1 << i386_FLOAT_STATE);
+ }
+ }
+
+ if (! machine_get_basic_state (ss->thread, state))
+ return NULL;
+
+ /* Save the original SP in the gratuitous `esp' slot.
+ We may need to reset the SP (the `uesp' slot) to avoid clobbering an
+ interrupted RPC frame. */
+ state->basic.esp = state->basic.uesp;
+
+ if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
+ !(ss->sigaltstack.ss_flags & (SS_DISABLE|SS_ONSTACK)))
+ {
+ sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
+ ss->sigaltstack.ss_flags |= SS_ONSTACK;
+ /* XXX need to set up base of new stack for
+ per-thread variables, cthreads. */
+ }
+ /* This code has intimate knowledge of the special mach_msg system call
+ done in intr-msg.c; that code does (see intr-msg.h):
+ movl %esp, %ecx
+ leal ARGS, %esp
+ _hurd_intr_rpc_msg_cx_sp: movl $-25, %eax
+ _hurd_intr_rpc_msg_do_trap: lcall $7, $0
+ _hurd_intr_rpc_msg_in_trap: movl %ecx, %esp
+ _hurd_intr_rpc_msg_sp_restored:
+ We must check for the window during which %esp points at the
+ mach_msg arguments. The space below until %ecx is used by
+ the _hurd_intr_rpc_mach_msg frame, and must not be clobbered. */
+ else if (state->basic.eip >= (int) &_hurd_intr_rpc_msg_cx_sp &&
+ state->basic.eip < (int) &_hurd_intr_rpc_msg_sp_restored)
+ /* The SP now points at the mach_msg args, but there is more stack
+ space used below it. The real SP is saved in %ecx; we must push the
+ new frame below there, and restore that value as the SP on
+ sigreturn. */
+ sigsp = (char *) (state->basic.uesp = state->basic.ecx);
+ else
+ sigsp = (char *) state->basic.uesp;
+
+ /* Push the arguments to call `trampoline' on the stack. */
+ sigsp -= sizeof (*stackframe);
+ stackframe = sigsp;
+
+ if (_hurdsig_catch_memory_fault (stackframe))
+ {
+ /* We got a fault trying to write the stack frame.
+ We cannot set up the signal handler.
+ Returning NULL tells our caller, who will nuke us with a SIGILL. */
+ return NULL;
+ }
+ else
+ {
+ int ok;
+
+ extern void _hurdsig_longjmp_from_handler (void *, jmp_buf, int);
+
+ /* Add a link to the thread's active-resources list. We mark this as
+ the only user of the "resource", so the cleanup function will be
+ called by any longjmp which is unwinding past the signal frame.
+ The cleanup function (in sigunwind.c) will make sure that all the
+ appropriate cleanups done by sigreturn are taken care of. */
+ stackframe->link.cleanup = &_hurdsig_longjmp_from_handler;
+ stackframe->link.cleanup_data = &stackframe->ctx;
+ stackframe->link.resource.next = NULL;
+ stackframe->link.resource.prevp = NULL;
+ stackframe->link.thread.next = ss->active_resources;
+ stackframe->link.thread.prevp = &ss->active_resources;
+ if (stackframe->link.thread.next)
+ stackframe->link.thread.next->thread.prevp
+ = &stackframe->link.thread.next;
+ ss->active_resources = &stackframe->link;
+
+ /* Set up the arguments for the signal handler. */
+ stackframe->signo = signo;
+ stackframe->sigcode = detail->code;
+ stackframe->scp = stackframe->return_scp = scp = &stackframe->ctx;
+ stackframe->sigreturn_addr = &__sigreturn;
+ stackframe->sigreturn_returns_here = firewall; /* Crash on return. */
+
+ /* Set up the sigcontext from the current state of the thread. */
+
+ scp->sc_onstack = ss->sigaltstack.ss_flags & SS_ONSTACK ? 1 : 0;
+
+ /* struct sigcontext is laid out so that starting at sc_gs mimics a
+ struct i386_thread_state. */
+ memcpy (&scp->sc_i386_thread_state,
+ &state->basic, sizeof (state->basic));
+
+ /* struct sigcontext is laid out so that starting at sc_fpkind mimics
+ a struct i386_float_state. */
+ ok = machine_get_state (ss->thread, state, i386_FLOAT_STATE,
+ &state->fpu, &scp->sc_i386_float_state,
+ sizeof (state->fpu));
+
+ _hurdsig_end_catch_fault ();
+
+ if (! ok)
+ return NULL;
+ }
+
+ /* Modify the thread state to call the trampoline code on the new stack. */
+ if (rpc_wait)
+ {
+ /* The signalee thread was blocked in a mach_msg_trap system call,
+ still waiting for a reply. We will have it run the special
+ trampoline code which retries the message receive before running
+ the signal handler.
+
+ To do this we change the OPTION argument on its stack to enable only
+ message reception, since the request message has already been
+ sent. */
+
+ struct mach_msg_trap_args *args = (void *) state->basic.esp;
+
+ if (_hurdsig_catch_memory_fault (args))
+ {
+ /* Faulted accessing ARGS. Bomb. */
+ return NULL;
+ }
+
+ assert (args->option & MACH_RCV_MSG);
+ /* Disable the message-send, since it has already completed. The
+ calls we retry need only wait to receive the reply message. */
+ args->option &= ~MACH_SEND_MSG;
+
+ /* Limit the time to receive the reply message, in case the server
+ claimed that `interrupt_operation' succeeded but in fact the RPC
+ is hung. */
+ args->option |= MACH_RCV_TIMEOUT;
+ args->timeout = _hurd_interrupted_rpc_timeout;
+
+ _hurdsig_end_catch_fault ();
+
+ state->basic.eip = (int) rpc_wait_trampoline;
+ /* The reply-receiving trampoline code runs initially on the original
+ user stack. We pass it the signal stack pointer in %ebx. */
+ state->basic.uesp = state->basic.esp; /* Restore mach_msg syscall SP. */
+ state->basic.ebx = (int) sigsp;
+ /* After doing the message receive, the trampoline code will need to
+ update the %eax value to be restored by sigreturn. To simplify
+ the assembly code, we pass the address of its slot in SCP to the
+ trampoline code in %ecx. */
+ state->basic.ecx = (int) &scp->sc_eax;
+ }
+ else
+ {
+ state->basic.eip = (int) trampoline;
+ state->basic.uesp = (int) sigsp;
+ }
+ /* We pass the handler function to the trampoline code in %edx. */
+ state->basic.edx = (int) handler;
+
+ return scp;
+}
+
+/* The trampoline code follows. This used to be located inside
+ _hurd_setup_sighandler, but was optimized away by gcc 2.95. */
+
+asm ("rpc_wait_trampoline:\n");
+ /* This is the entry point when we have an RPC reply message to receive
+ before running the handler. The MACH_MSG_SEND bit has already been
+ cleared in the OPTION argument on our stack. The interrupted user
+ stack pointer has not been changed, so the system call can find its
+ arguments; the signal stack pointer is in %ebx. For our convenience,
+ %ecx points to the sc_eax member of the sigcontext. */
+asm (/* Retry the interrupted mach_msg system call. */
+ "movl $-25, %eax\n" /* mach_msg_trap */
+ "lcall $7, $0\n"
+ /* When the sigcontext was saved, %eax was MACH_RCV_INTERRUPTED. But
+ now the message receive has completed and the original caller of
+ the RPC (i.e. the code running when the signal arrived) needs to
+ see the final return value of the message receive in %eax. So
+ store the new %eax value into the sc_eax member of the sigcontext
+ (whose address is in %ecx to make this code simpler). */
+ "movl %eax, (%ecx)\n"
+ /* Switch to the signal stack. */
+ "movl %ebx, %esp\n");
+
+ asm ("trampoline:\n");
+ /* Entry point for running the handler normally. The arguments to the
+ handler function are already on the top of the stack:
+
+ 0(%esp) SIGNO
+ 4(%esp) SIGCODE
+ 8(%esp) SCP
+ */
+asm ("call *%edx\n" /* Call the handler function. */
+ "addl $12, %esp\n" /* Pop its args. */
+ /* The word at the top of stack is &__sigreturn; following are a dummy
+ word to fill the slot for the address for __sigreturn to return to,
+ and a copy of SCP for __sigreturn's argument. "Return" to calling
+ __sigreturn (SCP); this call never returns. */
+ "ret");
+
+asm ("firewall:\n"
+ "hlt");
diff --git a/libc/sysdeps/mach/hurd/if_index.c b/libc/sysdeps/mach/hurd/if_index.c
new file mode 100644
index 000000000..664a3a1ef
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/if_index.c
@@ -0,0 +1,190 @@
+/* Find network interface names and index numbers. Hurd version.
+ Copyright (C) 2000,01,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <error.h>
+#include <net/if.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <hurd.h>
+#include <hurd/ioctl.h>
+#include <hurd/pfinet.h>
+
+/* Return the interface index corresponding to interface IFNAME.
+ On error, return 0. */
+unsigned int
+if_nametoindex (const char *ifname)
+{
+ struct ifreq ifr;
+ int fd = __opensock ();
+
+ if (fd < 0)
+ return 0;
+
+ strncpy (ifr.ifr_name, ifname, IFNAMSIZ);
+ if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
+ {
+ int saved_errno = errno;
+ __close (fd);
+ if (saved_errno == EINVAL || saved_errno == ENOTTY)
+ __set_errno (ENOSYS);
+ return 0;
+ }
+ __close (fd);
+ return ifr.ifr_ifindex;
+}
+libc_hidden_def (if_nametoindex)
+
+/* Free the structure IFN returned by if_nameindex. */
+void
+if_freenameindex (struct if_nameindex *ifn)
+{
+ struct if_nameindex *ptr = ifn;
+ while (ptr->if_name || ptr->if_index)
+ {
+ if (ptr->if_name)
+ free (ptr->if_name);
+ ++ptr;
+ }
+ free (ifn);
+}
+
+/* Return an array of if_nameindex structures, one for each network
+ interface present, plus one indicating the end of the array. On
+ error, return NULL. */
+struct if_nameindex *
+if_nameindex (void)
+{
+ error_t err = 0;
+ char data[2048];
+ file_t server;
+ int fd = __opensock ();
+ struct ifconf ifc;
+ unsigned int nifs, i;
+ struct if_nameindex *idx = NULL;
+
+ ifc.ifc_buf = data;
+
+ if (fd < 0)
+ return NULL;
+
+ server = _hurd_socket_server (PF_INET, 0);
+ if (server == MACH_PORT_NULL)
+ nifs = 0;
+ else
+ {
+ size_t len = sizeof data;
+ err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf, &len);
+ if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED)
+ {
+ /* On the first use of the socket server during the operation,
+ allow for the old server port dying. */
+ server = _hurd_socket_server (PF_INET, 1);
+ if (server == MACH_PORT_NULL)
+ goto out;
+ err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf, &len);
+ }
+ if (err)
+ goto out;
+
+ ifc.ifc_len = len;
+ nifs = len / sizeof (struct ifreq);
+ }
+
+ idx = malloc ((nifs + 1) * sizeof (struct if_nameindex));
+ if (idx == NULL)
+ {
+ err = ENOBUFS;
+ goto out;
+ }
+
+ for (i = 0; i < nifs; ++i)
+ {
+ struct ifreq *ifr = &ifc.ifc_req[i];
+ idx[i].if_name = __strdup (ifr->ifr_name);
+ if (idx[i].if_name == NULL
+ || __ioctl (fd, SIOCGIFINDEX, ifr) < 0)
+ {
+ unsigned int j;
+ err = errno;
+
+ for (j = 0; j < i; ++j)
+ free (idx[j].if_name);
+ free (idx);
+ idx = NULL;
+
+ if (err == EINVAL)
+ err = ENOSYS;
+ else if (err == ENOMEM)
+ err = ENOBUFS;
+ goto out;
+ }
+ idx[i].if_index = ifr->ifr_ifindex;
+ }
+
+ idx[i].if_index = 0;
+ idx[i].if_name = NULL;
+
+ out:
+ __close (fd);
+ if (data != ifc.ifc_buf)
+ __vm_deallocate (__mach_task_self (), (vm_address_t) ifc.ifc_buf,
+ ifc.ifc_len);
+ __set_errno (err);
+ return idx;
+}
+
+/* Store the name of the interface corresponding to index IFINDEX in
+ IFNAME (which has space for at least IFNAMSIZ characters). Return
+ IFNAME, or NULL on error. */
+char *
+if_indextoname (unsigned int ifindex, char *ifname)
+{
+ struct ifreq ifr;
+ int fd = __opensock ();
+
+ if (fd < 0)
+ return NULL;
+
+ ifr.ifr_ifindex = ifindex;
+ if (__ioctl (fd, SIOCGIFNAME, &ifr) < 0)
+ {
+ int saved_errno = errno;
+ __close (fd);
+ if (saved_errno == EINVAL || saved_errno == ENOTTY)
+ __set_errno (ENOSYS);
+ else if (saved_errno == ENODEV)
+ __set_errno (ENXIO);
+ return NULL;
+ }
+ __close (fd);
+ return strncpy (ifname, ifr.ifr_name, IFNAMSIZ);
+}
+libc_hidden_def (if_indextoname)
+
+#if 0
+void
+internal_function
+__protocol_available (int *have_inet, int *have_inet6)
+{
+ *have_inet = _hurd_socket_server (PF_INET, 0) != MACH_PORT_NULL;
+ *have_inet6 = _hurd_socket_server (PF_INET6, 0) != MACH_PORT_NULL;
+}
+#endif
diff --git a/libc/sysdeps/mach/hurd/ifreq.c b/libc/sysdeps/mach/hurd/ifreq.c
new file mode 100644
index 000000000..9da8a6803
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/ifreq.c
@@ -0,0 +1,65 @@
+/* Fetch the host's network interface list. Hurd version.
+ Copyright (C) 2002,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ifreq.h>
+#include <hurd.h>
+#include <hurd/pfinet.h>
+#include <sys/mman.h>
+
+
+void
+__ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd)
+{
+ file_t server;
+
+ server = _hurd_socket_server (PF_INET, 0);
+ if (server == MACH_PORT_NULL)
+ {
+ out:
+ *num_ifs = 0;
+ *ifreqs = NULL;
+ }
+ else
+ {
+ char *data = NULL;
+ size_t len = 0;
+ error_t err = __pfinet_siocgifconf (server, -1, &data, &len);
+ if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED)
+ {
+ /* On the first use of the socket server during the operation,
+ allow for the old server port dying. */
+ server = _hurd_socket_server (PF_INET, 1);
+ if (server == MACH_PORT_NULL)
+ goto out;
+ err = __pfinet_siocgifconf (server, -1, (data_t *) ifreqs, &len);
+ }
+ if (err)
+ goto out;
+
+ if (len % sizeof (struct ifreq) != 0)
+ {
+ munmap (data, len);
+ errno = EGRATUITOUS;
+ goto out;
+ }
+ *num_ifs = len / sizeof (struct ifreq);
+ *ifreqs = (struct ifreq *) data;
+ }
+
+}
diff --git a/libc/sysdeps/mach/hurd/init-posix.c b/libc/sysdeps/mach/hurd/init-posix.c
new file mode 100644
index 000000000..eaf6332fe
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/init-posix.c
@@ -0,0 +1,2 @@
+/* We don't need the unix/bsd version. */
+#include <posix/init-posix.c>
diff --git a/libc/sysdeps/mach/hurd/ioctl.c b/libc/sysdeps/mach/hurd/ioctl.c
new file mode 100644
index 000000000..bcc78bc84
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/ioctl.c
@@ -0,0 +1,324 @@
+/* Copyright (C) 1992,93,94,95,96,97,99,2000,2002,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/signal.h>
+#include <stdarg.h>
+#include <mach/notify.h>
+#include <assert.h>
+#include <string.h>
+#include <stdint.h>
+#include <hurd/ioctl.h>
+#include <mach/mig_support.h>
+
+#include <hurd/ioctls.defs>
+
+#define typesize(type) (1 << (type))
+
+
+/* Perform the I/O control operation specified by REQUEST on FD.
+ The actual type and use of ARG and the return value depend on REQUEST. */
+int
+__ioctl (int fd, unsigned long int request, ...)
+{
+#ifdef MACH_MSG_TYPE_CHAR
+ /* Map individual type fields to Mach IPC types. */
+ static const int mach_types[] =
+ { MACH_MSG_TYPE_CHAR, MACH_MSG_TYPE_INTEGER_16, MACH_MSG_TYPE_INTEGER_32,
+ MACH_MSG_TYPE_INTEGER_64 };
+#define io2mach_type(count, type) \
+ ((mach_msg_type_t) { mach_types[type], typesize (type) * 8, count, 1, 0, 0 })
+#endif
+
+ /* Extract the type information encoded in the request. */
+ unsigned int type = _IOC_TYPE (request);
+
+ /* Message buffer. */
+#define msg_align(x) \
+ (((x) + sizeof (mach_msg_type_t) - 1) & ~(sizeof (mach_msg_type_t) - 1))
+ struct
+ {
+#ifdef MACH_MSG_TYPE_BIT
+ union
+ {
+ mig_reply_header_t header;
+ struct
+ {
+ mach_msg_header_t Head;
+ int RetCodeType;
+ kern_return_t RetCode;
+ } header_typecheck;
+ };
+ char data[3 * sizeof (mach_msg_type_t) +
+ msg_align (_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type))) +
+ msg_align (_IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type))) +
+ _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
+#else /* Untyped Mach IPC format. */
+ mig_reply_error_t header;
+ char data[_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type)) +
+ _IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type)) +
+ _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
+ mach_msg_trailer_t trailer;
+#endif
+ } msg;
+ mach_msg_header_t *const m = &msg.header.Head;
+ mach_msg_id_t msgid;
+ unsigned int reply_size;
+#ifdef MACH_MSG_TYPE_BIT
+ mach_msg_type_t *t;
+#else
+ void *p;
+#endif
+
+ void *arg;
+
+ error_t err;
+
+ /* Send the RPC already packed up in MSG to IOPORT
+ and decode the return value. */
+ error_t send_rpc (io_t ioport)
+ {
+ error_t err;
+#ifdef MACH_MSG_TYPE_BIT
+ mach_msg_type_t *t = &msg.header.RetCodeType;
+#else
+ void *p = &msg.header.RetCode;
+#endif
+
+ /* Marshal the request arguments into the message buffer.
+ We must redo this work each time we retry the RPC after a SIGTTOU,
+ because the reply message containing the EBACKGROUND error code
+ clobbers the same message buffer also used for the request. */
+
+ if (_IOC_INOUT (request) & IOC_IN)
+ {
+ /* We don't want to advance ARG since it will be used to copy out
+ too if IOC_OUT is also set. */
+ void *argptr = arg;
+
+ /* Pack an argument into the message buffer. */
+ void in (unsigned int count, enum __ioctl_datum type)
+ {
+ if (count > 0)
+ {
+ const size_t len = count * typesize ((unsigned int) type);
+#ifdef MACH_MSG_TYPE_BIT
+ void *p = &t[1];
+ *t = io2mach_type (count, type);
+ p = __mempcpy (p, argptr, len);
+ p = (void *) (((uintptr_t) p + sizeof (*t) - 1)
+ & ~(sizeof (*t) - 1));
+ t = p;
+#else
+ p = __mempcpy (p, argptr, len);
+#endif
+ argptr += len;
+ }
+ }
+
+ /* Pack the argument data. */
+ in (_IOT_COUNT0 (type), _IOT_TYPE0 (type));
+ in (_IOT_COUNT1 (type), _IOT_TYPE1 (type));
+ in (_IOT_COUNT2 (type), _IOT_TYPE2 (type));
+ }
+ else if (_IOC_INOUT (request) == IOC_VOID)
+ {
+ /* The RPC takes a single integer_t argument.
+ Rather than pointing to the value, ARG is the value itself. */
+#ifdef MACH_MSG_TYPE_BIT
+ *t++ = io2mach_type (1, _IOTS (integer_t));
+ *(integer_t *) t = (integer_t) arg;
+ t = (void *) t + sizeof (integer_t);
+#else
+ *(integer_t *) p = (integer_t) arg;
+ p = (void *) p + sizeof (integer_t);
+#endif
+ }
+
+ memset (m, 0, sizeof *m); /* Clear unused fields. */
+ m->msgh_size = (
+#ifdef MACH_MSG_TYPE_BIT
+ (char *) t
+#else
+ (char *) p
+#endif
+ - (char *) &msg);
+ m->msgh_remote_port = ioport;
+ m->msgh_local_port = __mig_get_reply_port ();
+ m->msgh_id = msgid;
+ m->msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE);
+ err = _hurd_intr_rpc_mach_msg (m, MACH_SEND_MSG|MACH_RCV_MSG,
+ m->msgh_size, sizeof (msg),
+ m->msgh_local_port,
+ MACH_MSG_TIMEOUT_NONE,
+ MACH_PORT_NULL);
+ switch (err)
+ {
+ case MACH_MSG_SUCCESS:
+ break;
+ case MACH_SEND_INVALID_REPLY:
+ case MACH_RCV_INVALID_NAME:
+ __mig_dealloc_reply_port (m->msgh_local_port);
+ default:
+ return err;
+ }
+
+ if ((m->msgh_bits & MACH_MSGH_BITS_COMPLEX))
+ {
+ /* Allow no ports or VM. */
+ __mach_msg_destroy (m);
+ /* Want to return a different error below for a different msgid. */
+ if (m->msgh_id == msgid + 100)
+ return MIG_TYPE_ERROR;
+ }
+
+ if (m->msgh_id != msgid + 100)
+ return (m->msgh_id == MACH_NOTIFY_SEND_ONCE ?
+ MIG_SERVER_DIED : MIG_REPLY_MISMATCH);
+
+ if (m->msgh_size != reply_size &&
+ m->msgh_size != sizeof msg.header)
+ return MIG_TYPE_ERROR;
+
+#ifdef MACH_MSG_TYPE_BIT
+ if (msg.header_typecheck.RetCodeType !=
+ ((union { mach_msg_type_t t; int i; })
+ { t: io2mach_type (1, _IOTS (msg.header.RetCode)) }).i)
+ return MIG_TYPE_ERROR;
+#endif
+ return msg.header.RetCode;
+ }
+
+ va_list ap;
+
+ va_start (ap, request);
+ arg = va_arg (ap, void *);
+ va_end (ap);
+
+ {
+ /* Check for a registered handler for REQUEST. */
+ ioctl_handler_t handler = _hurd_lookup_ioctl_handler (request);
+ if (handler)
+ {
+ /* This handler groks REQUEST. Se lo puntamonos. */
+ int save = errno;
+ int result = (*handler) (fd, request, arg);
+ if (result != -1 || errno != ENOTTY)
+ return result;
+
+ /* The handler doesn't really grok this one.
+ Try the normal RPC translation. */
+ errno = save;
+ }
+ }
+
+ /* Compute the Mach message ID for the RPC from the group and command
+ parts of the ioctl request. */
+ msgid = IOC_MSGID (request);
+
+ /* Compute the expected size of the reply. There is a standard header
+ consisting of the message header and the reply code. Then, for out
+ and in/out ioctls, there come the data with their type headers. */
+ reply_size = sizeof msg.header;
+
+ if (_IOC_INOUT (request) & IOC_OUT)
+ {
+ inline void figure_reply (unsigned int count, enum __ioctl_datum type)
+ {
+ if (count > 0)
+ {
+#ifdef MACH_MSG_TYPE_BIT
+ /* Add the size of the type and data. */
+ reply_size += sizeof (mach_msg_type_t) + typesize (type) * count;
+ /* Align it to word size. */
+ reply_size += sizeof (mach_msg_type_t) - 1;
+ reply_size &= ~(sizeof (mach_msg_type_t) - 1);
+#else
+ reply_size += typesize (type) * count;
+#endif
+ }
+ }
+ figure_reply (_IOT_COUNT0 (type), _IOT_TYPE0 (type));
+ figure_reply (_IOT_COUNT1 (type), _IOT_TYPE1 (type));
+ figure_reply (_IOT_COUNT2 (type), _IOT_TYPE2 (type));
+ }
+
+ /* Marshal the arguments into the request message and make the RPC.
+ This wrapper function handles EBACKGROUND returns, turning them
+ into either SIGTTOU or EIO. */
+ err = HURD_DPORT_USE (fd, _hurd_ctty_output (port, ctty, send_rpc));
+
+#ifdef MACH_MSG_TYPE_BIT
+ t = (mach_msg_type_t *) msg.data;
+#else
+ p = (void *) msg.data;
+#endif
+ switch (err)
+ {
+ /* Unpack the message buffer into the argument location. */
+ int out (unsigned int count, unsigned int type,
+ void *store, void **update)
+ {
+ if (count > 0)
+ {
+ const size_t len = count * typesize (type);
+#ifdef MACH_MSG_TYPE_BIT
+ union { mach_msg_type_t t; int i; } ipctype;
+ ipctype.t = io2mach_type (count, type);
+ if (*(int *) t != ipctype.i)
+ return 1;
+ ++t;
+ memcpy (store, t, len);
+ if (update != NULL)
+ *update += len;
+ t = (void *) (((uintptr_t) t + len + sizeof (*t) - 1)
+ & ~(sizeof (*t) - 1));
+#else
+ memcpy (store, p, len);
+ p += len;
+ if (update != NULL)
+ *update += len;
+#endif
+ }
+ return 0;
+ }
+
+ case 0:
+ if (m->msgh_size != reply_size ||
+ ((_IOC_INOUT (request) & IOC_OUT) &&
+ (out (_IOT_COUNT0 (type), _IOT_TYPE0 (type), arg, &arg) ||
+ out (_IOT_COUNT1 (type), _IOT_TYPE1 (type), arg, &arg) ||
+ out (_IOT_COUNT2 (type), _IOT_TYPE2 (type), arg, &arg))))
+ return __hurd_fail (MIG_TYPE_ERROR);
+ return 0;
+
+ case MIG_BAD_ID:
+ case EOPNOTSUPP:
+ /* The server didn't understand the RPC. */
+ err = ENOTTY;
+ default:
+ return __hurd_fail (err);
+ }
+}
+
+weak_alias (__ioctl, ioctl)
diff --git a/libc/sysdeps/mach/hurd/isatty.c b/libc/sysdeps/mach/hurd/isatty.c
new file mode 100644
index 000000000..faf498038
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/isatty.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd/fd.h>
+#include <hurd/term.h>
+
+/* Return 1 if FD is a terminal, 0 if not. */
+int
+__isatty (fd)
+ int fd;
+{
+ error_t err;
+ mach_port_t id;
+
+ err = HURD_DPORT_USE (fd, __term_getctty (port, &id));
+ if (! err)
+ __mach_port_deallocate (__mach_task_self (), id);
+
+ return !err;
+}
+
+weak_alias (__isatty, isatty)
diff --git a/libc/sysdeps/mach/hurd/jmp-unwind.c b/libc/sysdeps/mach/hurd/jmp-unwind.c
new file mode 100644
index 000000000..e0e16e28b
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/jmp-unwind.c
@@ -0,0 +1,80 @@
+/* _longjmp_unwind -- Clean up stack frames unwound by longjmp. Hurd version.
+ Copyright (C) 1995,1996,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <jmpbuf-unwind.h>
+#include <hurd/userlink.h>
+#include <hurd/signal.h>
+#include <hurd/sigpreempt.h>
+#include <assert.h>
+#include <stdint.h>
+
+
+#ifndef _JMPBUF_UNWINDS
+#error "<jmpbuf-unwind.h> fails to define _JMPBUF_UNWINDS"
+#endif
+
+static inline uintptr_t
+demangle_ptr (uintptr_t x)
+{
+# ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (x);
+# endif
+ return x;
+}
+
+/* This function is called by `longjmp' (with its arguments) to restore
+ active resources to a sane state before the frames code using them are
+ jumped out of. */
+
+void
+_longjmp_unwind (jmp_buf env, int val)
+{
+ struct hurd_sigstate *ss = _hurd_self_sigstate ();
+ struct hurd_userlink *link;
+
+ /* All access to SS->active_resources must take place inside a critical
+ section where signal handlers cannot run. */
+ __spin_lock (&ss->lock);
+ assert (! __spin_lock_locked (&ss->critical_section_lock));
+ __spin_lock (&ss->critical_section_lock);
+
+ /* Remove local signal preemptors being unwound past. */
+ while (ss->preemptors &&
+ _JMPBUF_UNWINDS (env[0].__jmpbuf, ss->preemptors, demangle_ptr))
+ ss->preemptors = ss->preemptors->next;
+
+ __spin_unlock (&ss->lock);
+
+ /* Iterate over the current thread's list of active resources.
+ Process the head portion of the list whose links reside
+ in stack frames being unwound by this jump. */
+
+ for (link = ss->active_resources;
+ link && _JMPBUF_UNWINDS (env[0].__jmpbuf, link, demangle_ptr);
+ link = link->thread.next)
+ /* Remove this link from the resource's users list,
+ since the frame using the resource is being unwound.
+ This call returns nonzero if that was the last user. */
+ if (_hurd_userlink_unlink (link))
+ /* One of the frames being unwound by the longjmp was the last user
+ of its resource. Call the cleanup function to deallocate it. */
+ (*link->cleanup) (link->cleanup_data, env, val);
+
+ _hurd_critical_section_unlock (ss);
+}
diff --git a/libc/sysdeps/mach/hurd/kill.c b/libc/sysdeps/mach/hurd/kill.c
new file mode 100644
index 000000000..a9946e0af
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/kill.c
@@ -0,0 +1,150 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <hurd/signal.h>
+#include <hurd/msg.h>
+
+/* Send signal SIG to process number PID. If PID is zero,
+ send SIG to all processes in the current process's process group.
+ If PID is < -1, send SIG to all processes in process group - PID. */
+int
+__kill (pid_t pid, int sig)
+{
+ int delivered = 0; /* Set when we deliver any signal. */
+ error_t err;
+ mach_port_t proc;
+ struct hurd_userlink ulink;
+
+ void kill_pid (pid_t pid) /* Kill one PID. */
+ {
+ /* SIGKILL is not delivered as a normal signal.
+ Sending SIGKILL to a process means to terminate its task. */
+ if (sig == SIGKILL)
+ /* Fetch the process's task port and terminate the task. We
+ loop in case the process execs and changes its task port.
+ If the old task port dies after we fetch it but before we
+ send the RPC, we get MACH_SEND_INVALID_DEST; if it dies
+ after we send the RPC request but before it is serviced, we
+ get MIG_SERVER_DIED. */
+ do
+ {
+ task_t refport;
+ err = __proc_pid2task (proc, pid, &refport);
+ /* Ignore zombies. */
+ if (!err && refport != MACH_PORT_NULL)
+ {
+ err = __task_terminate (refport);
+ __mach_port_deallocate (__mach_task_self (), refport);
+ }
+ } while (err == MACH_SEND_INVALID_DEST ||
+ err == MIG_SERVER_DIED);
+ else
+ {
+ error_t taskerr;
+ error_t kill_port (mach_port_t msgport, mach_port_t refport)
+ {
+ if (msgport != MACH_PORT_NULL)
+ /* Send a signal message to his message port. */
+ return __msg_sig_post (msgport, sig, 0, refport);
+
+ /* The process has no message port. Perhaps try direct
+ frobnication of the task. */
+
+ if (taskerr)
+ /* If we could not get the task port, we can do nothing. */
+ return taskerr;
+
+ if (refport == MACH_PORT_NULL)
+ /* proc_pid2task returned success with a null task port.
+ That means the process is a zombie. Signals
+ to zombies should return success and do nothing. */
+ return 0;
+
+ /* For user convenience in the case of a task that has
+ not registered any message port with the proc server,
+ translate a few signals to direct task operations. */
+ switch (sig)
+ {
+ /* The only signals that really make sense for an
+ unregistered task are kill, suspend, and continue. */
+ case SIGSTOP:
+ case SIGTSTP:
+ return __task_suspend (refport);
+ case SIGCONT:
+ return __task_resume (refport);
+ case SIGTERM:
+ case SIGQUIT:
+ case SIGINT:
+ return __task_terminate (refport);
+ default:
+ /* We have full permission to send signals, but there is
+ no meaningful way to express this signal. */
+ return EPERM;
+ }
+ }
+ err = HURD_MSGPORT_RPC (__proc_getmsgport (proc, pid, &msgport),
+ (taskerr = __proc_pid2task (proc, pid,
+ &refport)) ?
+ __proc_getsidport (proc, &refport) : 0, 1,
+ kill_port (msgport, refport));
+ }
+ if (! err)
+ delivered = 1;
+ }
+
+ proc = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink);
+
+ if (pid <= 0)
+ {
+ /* Send SIG to each process in pgrp (- PID). */
+ pid_t pidbuf[10], *pids = pidbuf;
+ mach_msg_type_number_t i, npids = sizeof (pidbuf) / sizeof (pidbuf[0]);
+
+ err = __proc_getpgrppids (proc, - pid, &pids, &npids);
+ if (!err)
+ {
+ for (i = 0; i < npids; ++i)
+ {
+ kill_pid (pids[i]);
+ if (err == ESRCH)
+ /* The process died already. Ignore it. */
+ err = 0;
+ }
+ if (pids != pidbuf)
+ __vm_deallocate (__mach_task_self (),
+ (vm_address_t) pids, npids * sizeof (pids[0]));
+ }
+ }
+ else
+ kill_pid (pid);
+
+ _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, proc);
+
+ /* If we delivered no signals, but ERR is clear, this must mean that
+ every kill_pid call failed with ESRCH, meaning all the processes in
+ the pgrp died between proc_getpgrppids and kill_pid; in that case we
+ fail with ESRCH. */
+ return delivered ? 0 : __hurd_fail (err ?: ESRCH);
+}
+
+weak_alias (__kill, kill)
diff --git a/libc/sysdeps/mach/hurd/lchmod.c b/libc/sysdeps/mach/hurd/lchmod.c
new file mode 100644
index 000000000..284c2815c
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/lchmod.c
@@ -0,0 +1,39 @@
+/* lchmod -- Change the protections of a file or symbolic link. Hurd version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <hurd.h>
+
+/* Change the protections of FILE to MODE. */
+int
+lchmod (const char *file, mode_t mode)
+{
+ error_t err;
+ file_t port = __file_name_lookup (file, O_NOLINK, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_chmod (port, mode);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/lchown.c b/libc/sysdeps/mach/hurd/lchown.c
new file mode 100644
index 000000000..9795e4b8e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/lchown.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1991, 92, 94, 95, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <fcntl.h>
+
+/* Change the owner and group of FILE; if it's a link, do the link and
+ not the target. */
+int
+__lchown (file, owner, group)
+ const char *file;
+ uid_t owner;
+ gid_t group;
+{
+ error_t err;
+ file_t port = __file_name_lookup (file, O_NOLINK, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_chown (port, owner, group);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__lchown, lchown)
diff --git a/libc/sysdeps/mach/hurd/lgetxattr.c b/libc/sysdeps/mach/hurd/lgetxattr.c
new file mode 100644
index 000000000..5ab591575
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/lgetxattr.c
@@ -0,0 +1,36 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <fcntl.h>
+
+ssize_t
+lgetxattr (const char *path, const char *name, void *value, size_t size)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, O_NOLINK, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_get (port, name, value, &size);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return err ? __hurd_fail (err) : size;
+}
diff --git a/libc/sysdeps/mach/hurd/libc-ldscript b/libc/sysdeps/mach/hurd/libc-ldscript
new file mode 100644
index 000000000..499a2b2b9
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/libc-ldscript
@@ -0,0 +1,6 @@
+/* GNU ld script
+ This linker script is installed as /lib/libc.a.
+ It makes -lc become just like -( -lcrt -lmachuser -lhurduser -).
+ */
+
+GROUP ( libcrt.a libmachuser.a libhurduser.a )
diff --git a/libc/sysdeps/mach/hurd/libc_p-ldscript b/libc/sysdeps/mach/hurd/libc_p-ldscript
new file mode 100644
index 000000000..7dcd52eec
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/libc_p-ldscript
@@ -0,0 +1,6 @@
+/* GNU ld script
+ This linker script is installed as /lib/libc_p.a.
+ It makes -lc_p become just like -( -lcrt_p -lmachuser_p -lhurduser_p -).
+ */
+
+GROUP ( libcrt_p.a libmachuser_p.a libhurduser_p.a )
diff --git a/libc/sysdeps/mach/hurd/link.c b/libc/sysdeps/mach/hurd/link.c
new file mode 100644
index 000000000..f97d7bdfd
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/link.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Make a link to FROM called TO. */
+int
+__link (from, to)
+ const char *from;
+ const char *to;
+{
+ error_t err;
+ file_t oldfile, linknode, todir;
+ char *toname;
+
+ oldfile = __file_name_lookup (from, 0, 0);
+ if (oldfile == MACH_PORT_NULL)
+ return -1;
+
+ /* The file_getlinknode RPC returns the port that should be passed to
+ the receiving filesystem (the one containing TODIR) in dir_link. */
+
+ err = __file_getlinknode (oldfile, &linknode);
+ __mach_port_deallocate (__mach_task_self (), oldfile);
+ if (err)
+ return __hurd_fail (err);
+
+ todir = __file_name_split (to, &toname);
+ if (todir != MACH_PORT_NULL)
+ {
+ err = __dir_link (todir, linknode, toname, 1);
+ __mach_port_deallocate (__mach_task_self (), todir);
+ }
+ __mach_port_deallocate (__mach_task_self (), linknode);
+ if (todir == MACH_PORT_NULL)
+ return -1;
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__link, link)
diff --git a/libc/sysdeps/mach/hurd/linkat.c b/libc/sysdeps/mach/hurd/linkat.c
new file mode 100644
index 000000000..1942144e0
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/linkat.c
@@ -0,0 +1,66 @@
+/* Make a link between file names relative to open directories. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+
+/* Make a link to FROM relative to FROMFD called TO relative to TOFD. */
+int
+linkat (fromfd, from, tofd, to, flags)
+ int fromfd;
+ const char *from;
+ int tofd;
+ const char *to;
+ int flags;
+{
+ error_t err;
+ file_t oldfile, linknode, todir;
+ char *toname;
+
+ oldfile = __file_name_lookup_at (fromfd, flags, from, 0, 0);
+ if (oldfile == MACH_PORT_NULL)
+ return -1;
+
+ /* The file_getlinknode RPC returns the port that should be passed to
+ the receiving filesystem (the one containing TODIR) in dir_link. */
+
+ err = __file_getlinknode (oldfile, &linknode);
+ __mach_port_deallocate (__mach_task_self (), oldfile);
+ if (err)
+ return __hurd_fail (err);
+
+ todir = __file_name_split_at (tofd, to, &toname);
+ if (todir != MACH_PORT_NULL)
+ {
+ err = __dir_link (todir, linknode, toname, 1);
+ __mach_port_deallocate (__mach_task_self (), todir);
+ }
+ __mach_port_deallocate (__mach_task_self (), linknode);
+ if (todir == MACH_PORT_NULL)
+ return -1;
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/listen.c b/libc/sysdeps/mach/hurd/listen.c
new file mode 100644
index 000000000..8ee2650be
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/listen.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1992, 1994, 1997, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <sys/socket.h>
+#include <hurd/socket.h>
+
+/* Prepare to accept connections on socket FD.
+ N connection requests will be queued before further requests are refused.
+ Returns 0 on success, -1 for errors. */
+
+int
+__listen (fd, n)
+ int fd;
+ int n;
+{
+ error_t err = HURD_DPORT_USE (fd, __socket_listen (port, n));
+ if (err)
+ return __hurd_dfail (fd, err);
+ return 0;
+}
+
+weak_alias (__listen, listen)
diff --git a/libc/sysdeps/mach/hurd/listxattr.c b/libc/sysdeps/mach/hurd/listxattr.c
new file mode 100644
index 000000000..5f84e8831
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/listxattr.c
@@ -0,0 +1,35 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+
+ssize_t
+listxattr (const char *path, char *list, size_t size)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_list (port, list, &size);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return err ? __hurd_fail (err) : size;
+}
diff --git a/libc/sysdeps/mach/hurd/lseek.c b/libc/sysdeps/mach/hurd/lseek.c
new file mode 100644
index 000000000..e4b70b3fa
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/lseek.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991,92,93,94,95,97,2000,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <sys/types.h>
+
+/* Seek to OFFSET on FD, starting from WHENCE. */
+off_t
+__libc_lseek (int fd, off_t offset, int whence)
+{
+ return __libc_lseek64 (fd, (off64_t) offset, whence);
+}
+
+weak_alias (__libc_lseek, __lseek)
+libc_hidden_def (__lseek)
+weak_alias (__libc_lseek, lseek)
diff --git a/libc/sysdeps/mach/hurd/lseek64.c b/libc/sysdeps/mach/hurd/lseek64.c
new file mode 100644
index 000000000..0345d38f0
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/lseek64.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2000,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Seek to OFFSET on FD, starting from WHENCE. */
+off64_t
+__libc_lseek64 (int fd, off64_t offset, int whence)
+{
+ error_t err;
+ if (err = HURD_DPORT_USE (fd, __io_seek (port, offset, whence, &offset)))
+ return __hurd_dfail (fd, err);
+ return offset;
+}
+
+weak_alias (__libc_lseek64, __lseek64)
+weak_alias (__libc_lseek64, lseek64)
diff --git a/libc/sysdeps/mach/hurd/lsetxattr.c b/libc/sysdeps/mach/hurd/lsetxattr.c
new file mode 100644
index 000000000..c2eae40e3
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/lsetxattr.c
@@ -0,0 +1,37 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <fcntl.h>
+
+ssize_t
+lsetxattr (const char *path, const char *name, const void *value, size_t size,
+ int flags)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, O_NOLINK, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_set (port, name, value, size, flags);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return err ? __hurd_fail (err) : size;
+}
diff --git a/libc/sysdeps/mach/hurd/lutimes.c b/libc/sysdeps/mach/hurd/lutimes.c
new file mode 100644
index 000000000..cf89d8862
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/lutimes.c
@@ -0,0 +1,53 @@
+/* lutimes -- change access and modification times of a symlink. Hurd version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/time.h>
+#include <errno.h>
+#include <stddef.h>
+#include <hurd.h>
+#include <fcntl.h>
+
+/* Change the access time of FILE to TVP[0] and
+ the modification time of FILE to TVP[1]. */
+int
+__lutimes (const char *file, const struct timeval tvp[2])
+{
+ struct timeval timevals[2];
+ error_t err;
+ file_t port;
+
+ if (tvp == NULL)
+ {
+ /* Setting the number of microseconds to `-1' tells the
+ underlying filesystems to use the current time. */
+ timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1;
+ tvp = timevals;
+ }
+
+ port = __file_name_lookup (file, O_NOLINK, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_utimes (port,
+ *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+weak_alias (__lutimes, lutimes)
diff --git a/libc/sysdeps/mach/hurd/lxstat.c b/libc/sysdeps/mach/hurd/lxstat.c
new file mode 100644
index 000000000..d6d12798e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/lxstat.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1992,93,94,95,96,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <stddef.h>
+
+#include "xstatconv.c"
+
+int
+__lxstat (int vers, const char *file, struct stat *buf)
+{
+ struct stat64 buf64;
+ return __lxstat64 (vers, file, &buf64) ?: xstat64_conv (buf, &buf64);
+}
+hidden_def (__lxstat)
+weak_alias (__lxstat, _lxstat)
diff --git a/libc/sysdeps/mach/hurd/lxstat64.c b/libc/sysdeps/mach/hurd/lxstat64.c
new file mode 100644
index 000000000..a53f6921e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/lxstat64.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 2000,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <hurd.h>
+
+/* Get information about the file descriptor FD in BUF. */
+int
+__lxstat64 (int vers, const char *file, struct stat64 *buf)
+{
+ error_t err;
+ file_t port;
+
+ if (vers != _STAT_VER)
+ return __hurd_fail (EINVAL);
+
+ port = __file_name_lookup (file, O_NOLINK, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __io_stat (port, buf);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+hidden_def (__lxstat64)
diff --git a/libc/sysdeps/mach/hurd/malloc-machine.h b/libc/sysdeps/mach/hurd/malloc-machine.h
new file mode 100644
index 000000000..70aaf11b8
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/malloc-machine.h
@@ -0,0 +1,68 @@
+/* Basic platform-independent macro definitions for mutexes,
+ thread-specific data and parameters for malloc.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MALLOC_MACHINE_H
+#define _MALLOC_MACHINE_H
+
+#undef thread_atfork_static
+
+#include <atomic.h>
+#include <bits/libc-lock.h>
+
+/* Assume hurd, with cthreads */
+
+/* Cthreads `mutex_t' is a pointer to a mutex, and malloc wants just the
+ mutex itself. */
+#undef mutex_t
+#define mutex_t struct mutex
+
+#undef mutex_init
+#define mutex_init(m) (__mutex_init(m), 0)
+
+#undef mutex_lock
+#define mutex_lock(m) (__mutex_lock(m), 0)
+
+#undef mutex_unlock
+#define mutex_unlock(m) (__mutex_unlock(m), 0)
+
+#define mutex_trylock(m) (!__mutex_trylock(m))
+
+#define thread_atfork(prepare, parent, child) do {} while(0)
+#define thread_atfork_static(prepare, parent, child) \
+ text_set_element(_hurd_fork_prepare_hook, prepare); \
+ text_set_element(_hurd_fork_parent_hook, parent); \
+ text_set_element(_hurd_fork_child_hook, child);
+
+/* No we're *not* using pthreads. */
+#define __pthread_initialize ((void (*)(void))0)
+
+/* thread specific data for glibc */
+
+#include <bits/libc-tsd.h>
+
+typedef int tsd_key_t[1]; /* no key data structure, libc magic does it */
+__libc_tsd_define (static, MALLOC) /* declaration/common definition */
+#define tsd_key_create(key, destr) ((void) (key))
+#define tsd_setspecific(key, data) __libc_tsd_set (MALLOC, (data))
+#define tsd_getspecific(key, vptr) ((vptr) = __libc_tsd_get (MALLOC))
+
+#include <sysdeps/generic/malloc-machine.h>
+
+#endif /* !defined(_MALLOC_MACHINE_H) */
diff --git a/libc/sysdeps/mach/hurd/mig-reply.c b/libc/sysdeps/mach/hurd/mig-reply.c
new file mode 100644
index 000000000..5e40c147b
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/mig-reply.c
@@ -0,0 +1,88 @@
+/* Copyright (C) 1994,1995,1996,1997,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <mach.h>
+#include <hurd/threadvar.h>
+
+#define GETPORT \
+ mach_port_t *portloc = \
+ (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY)
+#define reply_port (*(use_threadvar ? portloc : &global_reply_port))
+
+static int use_threadvar;
+static mach_port_t global_reply_port;
+
+/* These functions are called by MiG-generated code. */
+
+/* Called by MiG to get a reply port. */
+mach_port_t
+__mig_get_reply_port (void)
+{
+ GETPORT;
+
+ if (reply_port == MACH_PORT_NULL)
+ reply_port = __mach_reply_port ();
+
+ return reply_port;
+}
+weak_alias (__mig_get_reply_port, mig_get_reply_port)
+
+/* Called by MiG to deallocate the reply port. */
+void
+__mig_dealloc_reply_port (mach_port_t arg)
+{
+ mach_port_t port;
+
+ GETPORT;
+
+ port = reply_port;
+ reply_port = MACH_PORT_NULL; /* So the mod_refs RPC won't use it. */
+
+ if (MACH_PORT_VALID (port))
+ __mach_port_mod_refs (__mach_task_self (), port,
+ MACH_PORT_RIGHT_RECEIVE, -1);
+}
+weak_alias (__mig_dealloc_reply_port, mig_dealloc_reply_port)
+
+/* Called by mig interfaces when done with a port. Used to provide the
+ same interface as needed when a custom allocator is used. */
+void
+__mig_put_reply_port(mach_port_t port)
+{
+ /* Do nothing. */
+}
+weak_alias (__mig_put_reply_port, mig_put_reply_port)
+
+/* Called at startup with STACK == NULL. When per-thread variables are set
+ up, this is called again with STACK set to the new stack being switched
+ to, where per-thread variables should be set up. */
+void
+__mig_init (void *stack)
+{
+ use_threadvar = stack != 0;
+
+ if (use_threadvar)
+ {
+ /* Recycle the reply port used before multithreading was enabled. */
+ mach_port_t *portloc = (mach_port_t *)
+ __hurd_threadvar_location_from_sp (_HURD_THREADVAR_MIG_REPLY, stack);
+ *portloc = global_reply_port;
+ global_reply_port = MACH_PORT_NULL;
+ }
+}
+weak_alias (__mig_init, mig_init)
diff --git a/libc/sysdeps/mach/hurd/mkdir.c b/libc/sysdeps/mach/hurd/mkdir.c
new file mode 100644
index 000000000..b7e80748f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/mkdir.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991,93,94,95,96,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Create a directory named FILE_NAME with protections MODE. */
+int
+__mkdir (file_name, mode)
+ const char *file_name;
+ mode_t mode;
+{
+ error_t err;
+ const char *name;
+ file_t parent = __directory_name_split (file_name, (char **) &name);
+ if (parent == MACH_PORT_NULL)
+ return -1;
+ err = __dir_mkdir (parent, name, mode & ~_hurd_umask);
+ __mach_port_deallocate (__mach_task_self (), parent);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__mkdir, mkdir)
diff --git a/libc/sysdeps/mach/hurd/mkdirat.c b/libc/sysdeps/mach/hurd/mkdirat.c
new file mode 100644
index 000000000..321d59f2f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/mkdirat.c
@@ -0,0 +1,42 @@
+/* Create a directory named relative to another open directory. Hurd version.
+ Copyright (C) 1991,1993,1994,1995,1996,1997,2002,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+int
+mkdirat (fd, path, mode)
+ int fd;
+ const char *path;
+ mode_t mode;
+{
+ error_t err;
+ const char *name;
+ file_t parent = __directory_name_split (path, (char **) &name);
+ if (parent == MACH_PORT_NULL)
+ return -1;
+ err = __dir_mkdir (parent, name, mode & ~_hurd_umask);
+ __mach_port_deallocate (__mach_task_self (), parent);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/mlock.c b/libc/sysdeps/mach/hurd/mlock.c
new file mode 100644
index 000000000..bb96c9c07
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/mlock.c
@@ -0,0 +1,47 @@
+/* mlock -- guarantee pages are resident in memory. Mach/Hurd version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <hurd.h>
+#include <mach/mach_host.h>
+
+/* Guarantee all whole pages mapped by the range [ADDR,ADDR+LEN) to
+ be memory resident. */
+
+int
+mlock (const void *addr, size_t len)
+{
+ mach_port_t hostpriv;
+ vm_address_t page;
+ error_t err;
+
+ err = __get_privileged_ports (&hostpriv, NULL);
+ if (err)
+ return __hurd_fail (EPERM);
+
+ page = trunc_page ((vm_address_t) addr);
+ len = round_page ((vm_address_t) addr + len) - page;
+ err = __vm_wire (hostpriv, __mach_task_self (), page, len,
+ VM_PROT_ALL); /* XXX ? */
+ __mach_port_deallocate (__mach_task_self (), hostpriv);
+
+ return err ? __hurd_fail (err) : 0;
+}
diff --git a/libc/sysdeps/mach/hurd/mmap.c b/libc/sysdeps/mach/hurd/mmap.c
new file mode 100644
index 000000000..1d1460cea
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/mmap.c
@@ -0,0 +1,168 @@
+/* Copyright (C) 1994,1995,1996,1997,1999,2002,2003,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Map addresses starting near ADDR and extending for LEN bytes. from
+ OFFSET into the file FD describes according to PROT and FLAGS. If ADDR
+ is nonzero, it is the desired mapping address. If the MAP_FIXED bit is
+ set in FLAGS, the mapping will be at ADDR exactly (which must be
+ page-aligned); otherwise the system chooses a convenient nearby address.
+ The return value is the actual mapping address chosen or (__ptr_t) -1
+ for errors (in which case `errno' is set). A successful `mmap' call
+ deallocates any previous mapping for the affected region. */
+
+__ptr_t
+__mmap (__ptr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
+{
+ error_t err;
+ vm_prot_t vmprot;
+ memory_object_t memobj;
+ vm_address_t mapaddr;
+
+ mapaddr = (vm_address_t) addr;
+
+ /* ADDR and OFFSET must be page-aligned. */
+ if ((mapaddr & (vm_page_size - 1)) || (offset & (vm_page_size - 1)))
+ return (__ptr_t) (long int) __hurd_fail (EINVAL);
+
+ if ((flags & (MAP_TYPE|MAP_INHERIT)) == MAP_ANON
+ && prot == (PROT_READ|PROT_WRITE)) /* cf VM_PROT_DEFAULT */
+ {
+ /* vm_allocate has (a little) less overhead in the kernel too. */
+ err = __vm_allocate (__mach_task_self (), &mapaddr, len,
+ !(flags & MAP_FIXED));
+
+ if (err == KERN_NO_SPACE && (flags & MAP_FIXED))
+ {
+ /* XXX this is not atomic as it is in unix! */
+ /* The region is already allocated; deallocate it first. */
+ err = __vm_deallocate (__mach_task_self (), mapaddr, len);
+ if (!err)
+ err = __vm_allocate (__mach_task_self (), &mapaddr, len, 0);
+ }
+
+ return err ? (__ptr_t) (long int) __hurd_fail (err) : (__ptr_t) mapaddr;
+ }
+
+ vmprot = VM_PROT_NONE;
+ if (prot & PROT_READ)
+ vmprot |= VM_PROT_READ;
+ if (prot & PROT_WRITE)
+ vmprot |= VM_PROT_WRITE;
+ if (prot & PROT_EXEC)
+ vmprot |= VM_PROT_EXECUTE;
+
+ switch (flags & MAP_TYPE)
+ {
+ default:
+ return (__ptr_t) (long int) __hurd_fail (EINVAL);
+
+ case MAP_ANON:
+ memobj = MACH_PORT_NULL;
+ break;
+
+ case MAP_FILE:
+ case 0: /* Allow, e.g., just MAP_SHARED. */
+ {
+ mach_port_t robj, wobj;
+ if (err = HURD_DPORT_USE (fd, __io_map (port, &robj, &wobj)))
+ {
+ if (err == MIG_BAD_ID || err == EOPNOTSUPP || err == ENOSYS)
+ err = ENODEV; /* File descriptor doesn't support mmap. */
+ return (__ptr_t) (long int) __hurd_dfail (fd, err);
+ }
+ switch (prot & (PROT_READ|PROT_WRITE))
+ {
+ case PROT_READ:
+ memobj = robj;
+ if (wobj != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), wobj);
+ break;
+ case PROT_WRITE:
+ memobj = wobj;
+ if (robj != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), robj);
+ break;
+ case PROT_READ|PROT_WRITE:
+ if (robj == wobj)
+ {
+ memobj = wobj;
+ /* Remove extra reference. */
+ __mach_port_deallocate (__mach_task_self (), memobj);
+ }
+ else if (wobj == MACH_PORT_NULL && /* Not writable by mapping. */
+ !(flags & MAP_SHARED))
+ /* The file can only be mapped for reading. Since we are
+ making a private mapping, we will never try to write the
+ object anyway, so we don't care. */
+ memobj = robj;
+ else
+ {
+ __mach_port_deallocate (__mach_task_self (), wobj);
+ return (__ptr_t) (long int) __hurd_fail (EACCES);
+ }
+ break;
+ default: /* impossible */
+ return 0;
+ }
+ break;
+ /* XXX handle MAP_NOEXTEND */
+ }
+ }
+
+ /* XXX handle MAP_INHERIT */
+
+ err = __vm_map (__mach_task_self (),
+ &mapaddr, (vm_size_t) len, (vm_address_t) 0,
+ ! (flags & MAP_FIXED),
+ memobj, (vm_offset_t) offset,
+ ! (flags & MAP_SHARED),
+ vmprot, VM_PROT_ALL,
+ (flags & MAP_SHARED) ? VM_INHERIT_SHARE : VM_INHERIT_COPY);
+
+ if (err == KERN_NO_SPACE && (flags & MAP_FIXED))
+ {
+ /* XXX this is not atomic as it is in unix! */
+ /* The region is already allocated; deallocate it first. */
+ err = __vm_deallocate (__mach_task_self (), mapaddr, len);
+ if (! err)
+ err = __vm_map (__mach_task_self (),
+ &mapaddr, (vm_size_t) len, (vm_address_t) 0,
+ 0, memobj, (vm_offset_t) offset,
+ ! (flags & MAP_SHARED),
+ vmprot, VM_PROT_ALL,
+ (flags & MAP_SHARED) ? VM_INHERIT_SHARE
+ : VM_INHERIT_COPY);
+ }
+
+ if (memobj != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), memobj);
+
+ if (err)
+ return (__ptr_t) (long int) __hurd_fail (err);
+
+ return (__ptr_t) mapaddr;
+}
+
+weak_alias (__mmap, mmap)
diff --git a/libc/sysdeps/mach/hurd/munlock.c b/libc/sysdeps/mach/hurd/munlock.c
new file mode 100644
index 000000000..8753006b6
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/munlock.c
@@ -0,0 +1,45 @@
+/* munlock -- undo the effects of prior mlock calls. Mach/Hurd version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <hurd.h>
+#include <mach/mach_host.h>
+
+/* Undo the effects on these whole pages of any prior mlock calls. */
+
+int
+munlock (const void *addr, size_t len)
+{
+ mach_port_t hostpriv;
+ vm_address_t page;
+ error_t err;
+
+ err = __get_privileged_ports (&hostpriv, NULL);
+ if (err)
+ return __hurd_fail (EPERM);
+
+ page = trunc_page ((vm_address_t) addr);
+ len = round_page ((vm_address_t) addr + len) - page;
+ err = __vm_wire (hostpriv, __mach_task_self (), page, len, VM_PROT_NONE);
+ __mach_port_deallocate (__mach_task_self (), hostpriv);
+
+ return err ? __hurd_fail (err) : 0;
+}
diff --git a/libc/sysdeps/mach/hurd/net/ethernet.h b/libc/sysdeps/mach/hurd/net/ethernet.h
new file mode 100644
index 000000000..2c524dc12
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/net/ethernet.h
@@ -0,0 +1,76 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Based on the FreeBSD version of this file. Curiously, that file
+ lacks a copyright in the header. */
+
+#ifndef __NET_ETHERNET_H
+#define __NET_ETHERNET_H 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <net/if_ether.h> /* IEEE 802.3 Ethernet constants */
+
+__BEGIN_DECLS
+
+/* This is a name for the 48 bit ethernet address available on many
+ systems. */
+struct ether_addr
+{
+ u_int8_t ether_addr_octet[ETH_ALEN];
+};
+
+/* 10Mb/s ethernet header */
+struct ether_header
+{
+ u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
+ u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */
+ u_int16_t ether_type; /* packet type ID field */
+};
+
+/* Ethernet protocol ID's */
+#define ETHERTYPE_PUP 0x0200 /* Xerox PUP */
+#define ETHERTYPE_IP 0x0800 /* IP */
+#define ETHERTYPE_ARP 0x0806 /* Address resolution */
+#define ETHERTYPE_REVARP 0x8035 /* Reverse ARP */
+
+#define ETHER_ADDR_LEN ETH_ALEN /* size of ethernet addr */
+#define ETHER_TYPE_LEN 2 /* bytes in type field */
+#define ETHER_CRC_LEN 4 /* bytes in CRC field */
+#define ETHER_HDR_LEN ETH_HLEN /* total octets in header */
+#define ETHER_MIN_LEN (ETH_ZLEN + ETH_CRC_LEN) /* min packet length */
+#define ETHER_MAX_LEN (ETH_FRAME_LEN + ETH_CRC_LEN) /* max packet length */
+
+/* make sure ethenet length is valid */
+#define ETHER_IS_VALID_LEN(foo) \
+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHERMTU ETH_DATA_LEN
+#define ETHERMIN (ETHER_MIN_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
+
+__END_DECLS
+
+#endif /* net/ethernet.h */
diff --git a/libc/sysdeps/mach/hurd/net/if_arp.h b/libc/sysdeps/mach/hurd/net/if_arp.h
new file mode 100644
index 000000000..c0153c93a
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/net/if_arp.h
@@ -0,0 +1,145 @@
+/* Definitions for Address Resolution Protocol.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Based on the 4.4BSD and Linux version of this file. */
+
+#ifndef _NET_IF_ARP_H
+
+#define _NET_IF_ARP_H 1
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+__BEGIN_DECLS
+
+/* Some internals from deep down in the kernel. */
+#define MAX_ADDR_LEN 7
+
+
+/* This structure defines an ethernet arp header. */
+
+/* ARP protocol opcodes. */
+#define ARPOP_REQUEST 1 /* ARP request. */
+#define ARPOP_REPLY 2 /* ARP reply. */
+#define ARPOP_RREQUEST 3 /* RARP request. */
+#define ARPOP_RREPLY 4 /* RARP reply. */
+
+/* See RFC 826 for protocol description. ARP packets are variable
+ in size; the arphdr structure defines the fixed-length portion.
+ Protocol type values are the same as those for 10 Mb/s Ethernet.
+ It is followed by the variable-sized fields ar_sha, arp_spa,
+ arp_tha and arp_tpa in that order, according to the lengths
+ specified. Field names used correspond to RFC 826. */
+
+struct arphdr
+ {
+ unsigned short int ar_hrd; /* Format of hardware address. */
+ unsigned short int ar_pro; /* Format of protocol address. */
+ unsigned char ar_hln; /* Length of hardware address. */
+ unsigned char ar_pln; /* Length of protocol address. */
+ unsigned short int ar_op; /* ARP opcode (command). */
+#if 0
+ /* Ethernet looks like this : This bit is variable sized
+ however... */
+ unsigned char __ar_sha[ETH_ALEN]; /* Sender hardware address. */
+ unsigned char __ar_sip[4]; /* Sender IP address. */
+ unsigned char __ar_tha[ETH_ALEN]; /* Target hardware address. */
+ unsigned char __ar_tip[4]; /* Target IP address. */
+#endif
+ };
+
+
+/* ARP protocol HARDWARE identifiers. */
+#define ARPHRD_NETROM 0 /* From KA9Q: NET/ROM pseudo. */
+#define ARPHRD_ETHER 1 /* Ethernet 10Mbps. */
+#define ARPHRD_EETHER 2 /* Experimental Ethernet. */
+#define ARPHRD_AX25 3 /* AX.25 Level 2. */
+#define ARPHRD_PRONET 4 /* PROnet token ring. */
+#define ARPHRD_CHAOS 5 /* Chaosnet. */
+#define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB. */
+#define ARPHRD_ARCNET 7 /* ARCnet. */
+#define ARPHRD_APPLETLK 8 /* APPLEtalk. */
+#define ARPHRD_DLCI 15 /* Frame Relay DLCI. */
+#define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id). */
+
+/* Dummy types for non ARP hardware */
+#define ARPHRD_SLIP 256
+#define ARPHRD_CSLIP 257
+#define ARPHRD_SLIP6 258
+#define ARPHRD_CSLIP6 259
+#define ARPHRD_RSRVD 260 /* Notional KISS type. */
+#define ARPHRD_ADAPT 264
+#define ARPHRD_ROSE 270
+#define ARPHRD_X25 271 /* CCITT X.25. */
+#define ARPHRD_PPP 512
+#define ARPHRD_HDLC 513 /* (Cisco) HDLC. */
+#define ARPHRD_LAPB 516 /* LAPB. */
+
+#define ARPHRD_TUNNEL 768 /* IPIP tunnel. */
+#define ARPHRD_TUNNEL6 769 /* IPIP6 tunnel. */
+#define ARPHRD_FRAD 770 /* Frame Relay Access Device. */
+#define ARPHRD_SKIP 771 /* SKIP vif. */
+#define ARPHRD_LOOPBACK 772 /* Loopback device. */
+#define ARPHRD_LOCALTLK 773 /* Localtalk device. */
+#define ARPHRD_FDDI 774 /* Fiber Distributed Data Interface. */
+#define ARPHRD_BIF 775 /* AP1000 BIF. */
+#define ARPHRD_SIT 776 /* sit0 device - IPv6-in-IPv4. */
+
+
+/* ARP ioctl request. */
+struct arpreq
+ {
+ struct sockaddr arp_pa; /* Protocol address. */
+ struct sockaddr arp_ha; /* Hardware address. */
+ int arp_flags; /* Flags. */
+ struct sockaddr arp_netmask; /* Netmask (only for proxy arps). */
+ char arp_dev[16];
+ };
+
+/* ARP Flag values. */
+#define ATF_COM 0x02 /* Completed entry (ha valid). */
+#define ATF_PERM 0x04 /* Permanent entry. */
+#define ATF_PUBL 0x08 /* Publish entry. */
+#define ATF_USETRAILERS 0x10 /* Has requested trailers. */
+#define ATF_NETMASK 0x20 /* Want to use a netmask (only
+ for proxy entries). */
+#define ATF_DONTPUB 0x40 /* Don't answer this addresses. */
+#define ATF_MAGIC 0x80 /* Automatically added entry. */
+
+
+/* Support for the user space arp daemon, arpd. */
+#define ARPD_UPDATE 0x01
+#define ARPD_LOOKUP 0x02
+#define ARPD_FLUSH 0x03
+
+struct arpd_request
+ {
+ unsigned short int req; /* Request type. */
+ u_int32_t ip; /* IP address of entry. */
+ unsigned long int dev; /* Device entry is tied to. */
+ unsigned long int stamp;
+ unsigned long int updated;
+ unsigned char ha[MAX_ADDR_LEN]; /* Hardware address. */
+ };
+
+__END_DECLS
+
+#endif /* net/if_arp.h */
diff --git a/libc/sysdeps/mach/hurd/net/if_ether.h b/libc/sysdeps/mach/hurd/net/if_ether.h
new file mode 100644
index 000000000..36300cb72
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/net/if_ether.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NET_IF_ETHER_H
+#define _NET_IF_ETHER_H 1
+
+/*
+ * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
+ * and FCS/CRC (frame check sequence).
+ */
+
+#define ETH_ALEN 6 /* Octets in one ethernet addr */
+#define ETH_HLEN 14 /* Total octets in header. */
+#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
+#define ETH_DATA_LEN 1500 /* Max. octets in payload */
+#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
+
+/*
+ * These are the defined Ethernet Protocol ID's.
+ */
+
+#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
+#define ETH_P_ECHO 0x0200 /* Ethernet Echo packet */
+#define ETH_P_PUP 0x0400 /* Xerox PUP packet */
+#define ETH_P_IP 0x0800 /* Internet Protocol packet */
+#define ETH_P_X25 0x0805 /* CCITT X.25 */
+#define ETH_P_ARP 0x0806 /* Address Resolution packet */
+#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
+#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
+#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
+#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
+#define ETH_P_LAT 0x6004 /* DEC LAT */
+#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
+#define ETH_P_CUST 0x6006 /* DEC Customer use */
+#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
+#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
+#define ETH_P_ATALK 0x809B /* Appletalk DDP */
+#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
+#define ETH_P_IPX 0x8137 /* IPX over DIX */
+#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
+
+/*
+ * Non DIX types. Won't clash for 1500 types.
+ */
+
+#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
+#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
+#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
+#define ETH_P_802_2 0x0004 /* 802.2 frames */
+#define ETH_P_SNAP 0x0005 /* Internal only */
+#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */
+#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
+#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
+#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */
+#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
+#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */
+
+/*
+ * This is an Ethernet frame header.
+ */
+
+struct ethhdr
+{
+ unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
+ unsigned char h_source[ETH_ALEN]; /* source ether addr */
+ unsigned short int h_proto; /* packet type ID field */
+};
+
+#endif /* net/if_ether.h */
diff --git a/libc/sysdeps/mach/hurd/net/if_ppp.h b/libc/sysdeps/mach/hurd/net/if_ppp.h
new file mode 100644
index 000000000..bf5ec8387
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/net/if_ppp.h
@@ -0,0 +1,169 @@
+/* From: if_ppp.h,v 1.3 1995/06/12 11:36:50 paulus Exp */
+
+/*
+ * if_ppp.h - Point-to-Point Protocol definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon University.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY 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 UNIVERSITY 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.
+ *
+ */
+
+/*
+ * ==FILEVERSION 960926==
+ *
+ * NOTE TO MAINTAINERS:
+ * If you modify this file at all, please set the above date.
+ * if_ppp.h is shipped with a PPP distribution as well as with the kernel;
+ * if everyone increases the FILEVERSION number above, then scripts
+ * can do the right thing when deciding whether to install a new if_ppp.h
+ * file. Don't change the format of that line otherwise, so the
+ * installation script can recognize it.
+ */
+
+
+#ifndef __NET_IF_PPP_H
+#define __NET_IF_PPP_H 1
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <net/ppp_defs.h>
+
+__BEGIN_DECLS
+
+/*
+ * Packet sizes
+ */
+
+#define PPP_MTU 1500 /* Default MTU (size of Info field) */
+#define PPP_MAXMRU 65000 /* Largest MRU we allow */
+#define PPP_VERSION "2.2.0"
+#define PPP_MAGIC 0x5002 /* Magic value for the ppp structure */
+#define PROTO_IPX 0x002b /* protocol numbers */
+#define PROTO_DNA_RT 0x0027 /* DNA Routing */
+
+
+/*
+ * Bit definitions for flags.
+ */
+
+#define SC_COMP_PROT 0x00000001 /* protocol compression (output) */
+#define SC_COMP_AC 0x00000002 /* header compression (output) */
+#define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */
+#define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */
+#define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */
+#define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */
+#define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */
+#define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */
+#define SC_ENABLE_IP 0x00000100 /* IP packets may be exchanged */
+#define SC_COMP_RUN 0x00001000 /* compressor has been inited */
+#define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */
+#define SC_DEBUG 0x00010000 /* enable debug messages */
+#define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */
+#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */
+#define SC_LOG_RAWIN 0x00080000 /* log all chars received */
+#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */
+#define SC_MASK 0x0fE0ffff /* bits that user can change */
+
+/* state bits */
+#define SC_ESCAPED 0x80000000 /* saw a PPP_ESCAPE */
+#define SC_FLUSH 0x40000000 /* flush input until next PPP_FLAG */
+#define SC_VJ_RESET 0x20000000 /* Need to reset the VJ decompressor */
+#define SC_XMIT_BUSY 0x10000000 /* ppp_write_wakeup is active */
+#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */
+#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */
+#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */
+#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */
+#define SC_DC_FERROR 0x00800000 /* fatal decomp error detected */
+#define SC_DC_ERROR 0x00400000 /* non-fatal decomp error detected */
+
+/*
+ * Ioctl definitions.
+ */
+
+struct npioctl {
+ int protocol; /* PPP protocol, e.g. PPP_IP */
+ enum NPmode mode;
+};
+
+/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */
+struct ppp_option_data {
+ u_int8_t *ptr;
+ u_int32_t length;
+ int transmit;
+};
+
+struct ifpppstatsreq {
+ struct ifreq b;
+ struct ppp_stats stats; /* statistic information */
+};
+
+struct ifpppcstatsreq {
+ struct ifreq b;
+ struct ppp_comp_stats stats;
+};
+
+#define ifr__name b.ifr_ifrn.ifrn_name
+#define stats_ptr b.ifr_ifru.ifru_data
+
+/*
+ * Ioctl definitions.
+ */
+
+#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */
+#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */
+#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */
+#define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */
+#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */
+#define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */
+#define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */
+#define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */
+#define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */
+#define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */
+#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */
+#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */
+#define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */
+#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data)
+#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */
+#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */
+#define PPPIOCGDEBUG _IOR('t', 65, int) /* Read debug level */
+#define PPPIOCSDEBUG _IOW('t', 64, int) /* Set debug level */
+#define PPPIOCGIDLE _IOR('t', 63, struct ppp_idle) /* get idle time */
+
+#define SIOCGPPPSTATS (SIOCDEVPRIVATE + 0)
+#define SIOCGPPPVER (SIOCDEVPRIVATE + 1) /* NEVER change this!! */
+#define SIOCGPPPCSTATS (SIOCDEVPRIVATE + 2)
+
+#if !defined(ifr_mtu)
+#define ifr_mtu ifr_ifru.ifru_metric
+#endif
+
+__END_DECLS
+
+#endif /* net/if_ppp.h */
diff --git a/libc/sysdeps/mach/hurd/net/route.h b/libc/sysdeps/mach/hurd/net/route.h
new file mode 100644
index 000000000..7b674611a
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/net/route.h
@@ -0,0 +1,141 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc..
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Based on the 4.4BSD and Linux version of this file. */
+
+#ifndef _NET_ROUTE_H
+
+#define _NET_ROUTE_H 1
+#include <features.h>
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+
+/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */
+struct rtentry
+ {
+ unsigned long int rt_pad1;
+ struct sockaddr rt_dst; /* Target address. */
+ struct sockaddr rt_gateway; /* Gateway addr (RTF_GATEWAY). */
+ struct sockaddr rt_genmask; /* Target network mask (IP). */
+ unsigned short int rt_flags;
+ short int rt_pad2;
+ unsigned long int rt_pad3;
+ unsigned char rt_tos;
+ unsigned char rt_class;
+ short int rt_pad4;
+ short int rt_metric; /* +1 for binary compatibility! */
+ char *rt_dev; /* Forcing the device at add. */
+ unsigned long int rt_mtu; /* Per route MTU/Window. */
+ unsigned long int rt_window; /* Window clamping. */
+ unsigned short int rt_irtt; /* Initial RTT. */
+ };
+/* Compatibility hack. */
+#define rt_mss rt_mtu
+
+
+struct in6_rtmsg
+ {
+ struct in6_addr rtmsg_dst;
+ struct in6_addr rtmsg_src;
+ struct in6_addr rtmsg_gateway;
+ u_int32_t rtmsg_type;
+ u_int16_t rtmsg_dst_len;
+ u_int16_t rtmsg_src_len;
+ u_int32_t rtmsg_metric;
+ unsigned long int rtmsg_info;
+ u_int32_t rtmsg_flags;
+ int rtmsg_ifindex;
+ };
+
+
+#define RTF_UP 0x0001 /* Route usable. */
+#define RTF_GATEWAY 0x0002 /* Destination is a gateway. */
+
+#define RTF_HOST 0x0004 /* Host entry (net otherwise). */
+#define RTF_REINSTATE 0x0008 /* Reinstate route after timeout. */
+#define RTF_DYNAMIC 0x0010 /* Created dyn. (by redirect). */
+#define RTF_MODIFIED 0x0020 /* Modified dyn. (by redirect). */
+#define RTF_MTU 0x0040 /* Specific MTU for this route. */
+#define RTF_MSS RTF_MTU /* Compatibility. */
+#define RTF_WINDOW 0x0080 /* Per route window clamping. */
+#define RTF_IRTT 0x0100 /* Initial round trip time. */
+#define RTF_REJECT 0x0200 /* Reject route. */
+#define RTF_STATIC 0x0400 /* Manually injected route. */
+#define RTF_XRESOLVE 0x0800 /* External resolver. */
+#define RTF_NOFORWARD 0x1000 /* Forwarding inhibited. */
+#define RTF_THROW 0x2000 /* Go to next class. */
+#define RTF_NOPMTUDISC 0x4000 /* Do not send packets with DF. */
+
+/* for IPv6 */
+#define RTF_DEFAULT 0x00010000 /* default - learned via ND */
+#define RTF_ALLONLINK 0x00020000 /* fallback, no routers on link */
+#define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */
+
+#define RTF_LINKRT 0x00100000 /* link specific - device match */
+#define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */
+
+#define RTF_CACHE 0x01000000 /* cache entry */
+#define RTF_FLOW 0x02000000 /* flow significant route */
+#define RTF_POLICY 0x04000000 /* policy route */
+
+#define RTCF_VALVE 0x00200000
+#define RTCF_MASQ 0x00400000
+#define RTCF_NAT 0x00800000
+#define RTCF_DOREDIRECT 0x01000000
+#define RTCF_LOG 0x02000000
+#define RTCF_DIRECTSRC 0x04000000
+
+#define RTF_LOCAL 0x80000000
+#define RTF_INTERFACE 0x40000000
+#define RTF_MULTICAST 0x20000000
+#define RTF_BROADCAST 0x10000000
+#define RTF_NAT 0x08000000
+
+#define RTF_ADDRCLASSMASK 0xF8000000
+#define RT_ADDRCLASS(flags) ((__u_int32_t) flags >> 23)
+
+#define RT_TOS(tos) ((tos) & IPTOS_TOS_MASK)
+
+#define RT_LOCALADDR(flags) ((flags & RTF_ADDRCLASSMASK) \
+ == (RTF_LOCAL|RTF_INTERFACE))
+
+#define RT_CLASS_UNSPEC 0
+#define RT_CLASS_DEFAULT 253
+
+#define RT_CLASS_MAIN 254
+#define RT_CLASS_LOCAL 255
+#define RT_CLASS_MAX 255
+
+
+#define RTMSG_ACK NLMSG_ACK
+#define RTMSG_OVERRUN NLMSG_OVERRUN
+
+#define RTMSG_NEWDEVICE 0x11
+#define RTMSG_DELDEVICE 0x12
+#define RTMSG_NEWROUTE 0x21
+#define RTMSG_DELROUTE 0x22
+#define RTMSG_NEWRULE 0x31
+#define RTMSG_DELRULE 0x32
+#define RTMSG_CONTROL 0x40
+
+#define RTMSG_AR_FAILED 0x51 /* Address Resolution failed. */
+
+#endif /* net/route.h */
diff --git a/libc/sysdeps/mach/hurd/open.c b/libc/sysdeps/mach/hurd/open.c
new file mode 100644
index 000000000..bdfed5e31
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/open.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1992,93,94,95,97,2000,2002,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
+ a third argument is the file protection. */
+int
+__libc_open (const char *file, int oflag, ...)
+{
+ mode_t mode;
+ io_t port;
+
+ if (oflag & O_CREAT)
+ {
+ va_list arg;
+ va_start (arg, oflag);
+ mode = va_arg (arg, mode_t);
+ va_end (arg);
+ }
+ else
+ mode = 0;
+
+ port = __file_name_lookup (file, oflag, mode);
+ if (port == MACH_PORT_NULL)
+ return -1;
+
+ return _hurd_intern_fd (port, oflag, 1);
+}
+
+libc_hidden_def (__libc_open)
+weak_alias (__libc_open, __open)
+libc_hidden_weak (__open)
+weak_alias (__libc_open, open)
+
+/* open64 is just the same as open for us. */
+weak_alias (__libc_open, __libc_open64)
+weak_alias (__libc_open, __open64)
+libc_hidden_weak (_open64)
+weak_alias (__libc_open, open64)
diff --git a/libc/sysdeps/mach/hurd/open64.c b/libc/sysdeps/mach/hurd/open64.c
new file mode 100644
index 000000000..018ac94f2
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/open64.c
@@ -0,0 +1 @@
+/* open64 is defined in open.c as an alias. */
diff --git a/libc/sysdeps/mach/hurd/openat.c b/libc/sysdeps/mach/hurd/openat.c
new file mode 100644
index 000000000..1faf857e1
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/openat.c
@@ -0,0 +1,62 @@
+/* openat -- Open a file named relative to an open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Open FILE with access OFLAG. Interpret relative paths relative to
+ the directory associated with FD. If OFLAG includes O_CREAT, a
+ third argument is the file protection. */
+int
+__openat (fd, file, oflag)
+ int fd;
+ const char *file;
+ int oflag;
+{
+ int mode;
+ io_t port;
+
+ if (oflag & O_CREAT)
+ {
+ va_list arg;
+ va_start (arg, oflag);
+ mode = va_arg (arg, int);
+ va_end (arg);
+ }
+ else
+ mode = 0;
+
+ port = __file_name_lookup_at (fd, 0, file, oflag, mode);
+ if (port == MACH_PORT_NULL)
+ return -1;
+
+ return _hurd_intern_fd (port, oflag, 1);
+}
+libc_hidden_def (__openat)
+weak_alias (__openat, openat)
+
+/* openat64 is just the same as openat for us. */
+weak_alias (__openat, __openat64)
+libc_hidden_weak (__openat64)
+weak_alias (__openat, openat64)
diff --git a/libc/sysdeps/mach/hurd/openat64.c b/libc/sysdeps/mach/hurd/openat64.c
new file mode 100644
index 000000000..15d9d6a18
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/openat64.c
@@ -0,0 +1 @@
+/* openat64 is defined in openat.c as an alias. */
diff --git a/libc/sysdeps/mach/hurd/opendir.c b/libc/sysdeps/mach/hurd/opendir.c
new file mode 100644
index 000000000..23e04ede0
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/opendir.c
@@ -0,0 +1,93 @@
+/* Copyright (C) 1993,1994,1995,1996,1997,1998,2001,2003,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include "dirstream.h"
+
+
+/* Open a directory stream on a file descriptor in Hurd internal form.
+ We do no checking here on the descriptor. */
+DIR *
+_hurd_fd_opendir (struct hurd_fd *d)
+{
+ DIR *dirp;
+
+ if (d == NULL)
+ {
+ errno = EBADF;
+ return NULL;
+ }
+
+ dirp = (DIR *) malloc (sizeof (DIR));
+ if (dirp == NULL)
+ return NULL;
+
+ /* Set the descriptor to close on exec. */
+ __spin_lock (&d->port.lock);
+ d->flags |= FD_CLOEXEC;
+ __spin_unlock (&d->port.lock);
+
+ dirp->__fd = d;
+ dirp->__data = dirp->__ptr = NULL;
+ dirp->__entry_data = dirp->__entry_ptr = 0;
+ dirp->__allocation = 0;
+ dirp->__size = 0;
+
+ __libc_lock_init (dirp->__lock);
+
+ return dirp;
+}
+
+
+/* Open a directory stream on NAME. */
+DIR *
+__opendir (const char *name)
+{
+ if (name[0] == '\0')
+ {
+ /* POSIX.1-1990 says an empty name gets ENOENT;
+ but `open' might like it fine. */
+ __set_errno (ENOENT);
+ return NULL;
+ }
+
+ int fd = __open (name, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
+ if (fd < 0)
+ return NULL;
+
+ /* Extract the pointer to the descriptor structure. */
+ DIR *dirp = _hurd_fd_opendir (_hurd_fd_get (fd));
+ if (dirp == NULL)
+ __close (fd);
+
+ return dirp;
+}
+weak_alias (__opendir, opendir)
diff --git a/libc/sysdeps/mach/hurd/pathconf.c b/libc/sysdeps/mach/hurd/pathconf.c
new file mode 100644
index 000000000..2f95e2be8
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/pathconf.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1991, 1992, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Get file-specific information about FILE. */
+long int
+__pathconf (const char *file, int name)
+{
+ error_t err;
+ int value; /* RPC returns an `int', not a `long int'. */
+ file_t port = __file_name_lookup (file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1L;
+ err = __io_pathconf (port, name, &value);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err), -1L;
+ return value;
+}
+
+weak_alias (__pathconf, pathconf)
diff --git a/libc/sysdeps/mach/hurd/pipe.c b/libc/sysdeps/mach/hurd/pipe.c
new file mode 100644
index 000000000..7a5d78c29
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/pipe.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1992,93,94,95,96,99,2000,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+/* Create a one-way communication channel (pipe).
+ Actually the channel is two-way on the Hurd.
+ If successful, two file descriptors are stored in FDS;
+ bytes written on FDS[1] can be read from FDS[0].
+ Returns 0 if successful, -1 if not. */
+int
+__pipe (int fds[2])
+{
+ int save_errno = errno;
+ int result;
+
+ /* The magic S_IFIFO protocol tells the pflocal server to create
+ sockets which report themselves as FIFOs, as POSIX requires for
+ pipes. */
+ result = __socketpair (PF_LOCAL, SOCK_STREAM, S_IFIFO, fds);
+ if (result == -1 && errno == EPROTONOSUPPORT)
+ {
+ /* We contacted an "old" pflocal server that doesn't support the
+ magic S_IFIFO protocol.
+ FIXME: Remove this junk somewhere in the future. */
+ __set_errno (save_errno);
+ return __socketpair (PF_LOCAL, SOCK_STREAM, 0, fds);
+ }
+
+ return result;
+}
+libc_hidden_def (__pipe)
+weak_alias (__pipe, pipe)
diff --git a/libc/sysdeps/mach/hurd/poll.c b/libc/sysdeps/mach/hurd/poll.c
new file mode 100644
index 000000000..f6f7127ef
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/poll.c
@@ -0,0 +1,51 @@
+/* poll file descriptors. Hurd version.
+ Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/poll.h>
+#include <sys/time.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Poll the file descriptors described by the NFDS structures starting at
+ FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for
+ an event to occur; if TIMEOUT is -1, block until an event occurs.
+ Returns the number of file descriptors with events, zero if timed out,
+ or -1 for errors. */
+
+int
+__poll (fds, nfds, timeout)
+ struct pollfd *fds;
+ nfds_t nfds;
+ int timeout;
+{
+ struct timespec ts, *to;
+
+ if (timeout < 0)
+ to = NULL;
+ else
+ {
+ ts.tv_sec = timeout / 1000;
+ ts.tv_nsec = (timeout % 1000) * 1000000;
+ to = &ts;
+ }
+
+ return _hurd_select (nfds, fds, NULL, NULL, NULL, to, NULL);
+}
+libc_hidden_def (__poll)
+weak_alias (__poll, poll)
diff --git a/libc/sysdeps/mach/hurd/powerpc/bits/sigcontext.h b/libc/sysdeps/mach/hurd/powerpc/bits/sigcontext.h
new file mode 100644
index 000000000..bbed8f9ff
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/powerpc/bits/sigcontext.h
@@ -0,0 +1,80 @@
+/* Machine-dependent signal context structure for GNU Hurd. PowerPC version.
+ Copyright (C) 2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
+# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
+#endif
+
+#ifndef sc_pc
+
+/* Signal handlers are actually called:
+ void handler (int sig, int code, struct sigcontext *scp); */
+
+/* State of this thread when the signal was taken. */
+struct sigcontext
+ {
+ /* These first members are machine-independent. */
+
+ int sc_onstack; /* Nonzero if running on sigstack. */
+ __sigset_t sc_mask; /* Blocked signals to restore. */
+
+ /* MiG reply port this thread is using. */
+ unsigned int sc_reply_port;
+
+ /* Port this thread is doing an interruptible RPC on. */
+ unsigned int sc_intr_port;
+
+ /* Error code associated with this signal (interpreted as `error_t'). */
+ int sc_error;
+
+ /* All following members are machine-dependent. The rest of this
+ structure is written to be laid out identically to:
+ {
+ struct ppc_thread_state basic;
+ struct ppc_exc_state exc;
+ struct ppc_float_state fpu;
+ }
+ trampoline.c knows this, so it must be changed if this changes. */
+
+#define sc_ppc_thread_state sc_srr0 /* Beginning of correspondence. */
+#define sc_pc sc_srr0 /* For sysdeps/generic/profil-counter.h. */
+ unsigned int sc_srr0;
+ unsigned int sc_srr1;
+ unsigned int sc_gprs[32];
+ unsigned int sc_cr;
+ unsigned int sc_xer;
+ unsigned int sc_lr;
+ unsigned int sc_ctr;
+ unsigned int sc_mq;
+ unsigned int sc_ts_pad;
+
+#define sc_ppc_exc_state sc_dar
+ unsigned int sc_dar;
+ unsigned int sc_dsisr;
+ unsigned int sc_exception;
+ unsigned int sc_es_pad0;
+ unsigned int sc_es_pad1[4];
+
+#define sc_ppc_float_state sc_fprs[0]
+ double sc_fprs[32];
+ unsigned int sc_fpscr_pad;
+ unsigned int sc_fpscr;
+ };
+
+#endif /* sc_pc */
diff --git a/libc/sysdeps/mach/hurd/powerpc/exc2signal.c b/libc/sysdeps/mach/hurd/powerpc/exc2signal.c
new file mode 100644
index 000000000..7cea85daa
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/powerpc/exc2signal.c
@@ -0,0 +1,74 @@
+/* Translate Mach exception codes into signal numbers. PowerPC version.
+ Copyright (C) 1991,92,94,96,97,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <mach/exception.h>
+
+/* Translate the Mach exception codes, as received in an `exception_raise' RPC,
+ into a signal number and signal subcode. */
+
+void
+_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
+{
+ detail->error = 0;
+
+ switch (detail->exc)
+ {
+ default:
+ *signo = SIGIOT;
+ detail->code = detail->exc;
+ break;
+
+ case EXC_BAD_ACCESS:
+ if (detail->exc_code == KERN_PROTECTION_FAILURE)
+ *signo = SIGSEGV;
+ else
+ *signo = SIGBUS;
+ detail->code = detail->exc_subcode;
+ detail->error = detail->exc_code;
+ break;
+
+ /* XXX there has got to be something more here */
+
+ case EXC_BAD_INSTRUCTION:
+ *signo = SIGILL;
+ detail->code = 0;
+ break;
+
+ case EXC_ARITHMETIC:
+ *signo = SIGFPE;
+ detail->code = 0;
+ break;
+
+ case EXC_EMULATION:
+ *signo = SIGEMT;
+ detail->code = 0;
+ break;
+
+ case EXC_SOFTWARE:
+ *signo = SIGEMT;
+ detail->code = 0;
+ break;
+
+ case EXC_BREAKPOINT:
+ *signo = SIGTRAP;
+ detail->code = 0;
+ }
+}
diff --git a/libc/sysdeps/mach/hurd/powerpc/init-first.c b/libc/sysdeps/mach/hurd/powerpc/init-first.c
new file mode 100644
index 000000000..20fa1d4f1
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/powerpc/init-first.c
@@ -0,0 +1,339 @@
+/* Initialization code run first thing by the ELF startup code. PowerPC/Hurd.
+ Copyright (C) 1995-2001, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <hurd.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sysdep.h>
+#include <set-hooks.h>
+#include "hurdstartup.h"
+#include "hurdmalloc.h" /* XXX */
+
+extern void __mach_init (void);
+extern void __init_misc (int, char **, char **);
+#ifdef USE_NONOPTION_FLAGS
+extern void __getopt_clean_environment (char **);
+#endif
+#ifndef SHARED
+extern void _dl_non_dynamic_init (void) internal_function;
+#endif
+extern void __libc_global_ctors (void);
+
+unsigned int __hurd_threadvar_max;
+unsigned long int __hurd_threadvar_stack_offset;
+unsigned long int __hurd_threadvar_stack_mask;
+
+#ifndef SHARED
+int __libc_enable_secure;
+#endif
+int __libc_multiple_libcs attribute_hidden = 1;
+
+extern int __libc_argc attribute_hidden;
+extern char **__libc_argv attribute_hidden;
+extern char **_dl_argv;
+
+void *(*_cthread_init_routine) (void); /* Returns new SP to use. */
+void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__));
+
+#ifndef SHARED
+static unsigned int return_address; /* Make init1 return to _start. */
+#endif
+
+/* Things that want to be run before _hurd_init or much anything else.
+ Importantly, these are called before anything tries to use malloc. */
+DEFINE_HOOK (_hurd_preinit_hook, (void));
+
+
+/* We call this once the Hurd magic is all set up and we are ready to be a
+ Posixoid program. This does the same things the generic version does. */
+static void internal_function
+posixland_init (int argc, char **argv, char **envp)
+{
+ asm ("li 3,0xbb; .long 0");
+ __libc_argc = argc;
+ __libc_argv = argv;
+ __environ = envp;
+
+#ifndef SHARED
+ _dl_non_dynamic_init ();
+#endif
+ __init_misc (argc, argv, envp);
+
+#ifdef USE_NONOPTION_FLAGS
+ /* This is a hack to make the special getopt in GNU libc working. */
+ __getopt_clean_environment (__environ);
+#endif
+
+#ifdef SHARED
+ __libc_global_ctors ();
+#endif
+}
+
+
+static void
+init1 (int *data)
+{
+ int argc = *data;
+ char **argv = (char **) &data[1];
+ char **envp = &argv[argc + 1];
+ struct hurd_startup_data *d;
+
+ while (*envp)
+ ++envp;
+ d = (void *) ++envp;
+
+ /* If we are the bootstrap task started by the kernel,
+ then after the environment pointers there is no Hurd
+ data block; the argument strings start there. */
+ /* OSF Mach starts the bootstrap task with argc == 0.
+ XXX This fails if a non-bootstrap task gets started
+ with argc == 0. */
+ if (argc && (void *) d != argv[0])
+ {
+ _hurd_init_dtable = d->dtable;
+ _hurd_init_dtablesize = d->dtablesize;
+
+#if 0 /* We can't free the old stack because it contains the argument strings. */
+ {
+ /* Check if the stack we are now on is different from
+ the one described by _hurd_stack_{base,size}. */
+
+ char dummy;
+ const vm_address_t newsp = (vm_address_t) &dummy;
+
+ if (d->stack_size != 0 && (newsp < d->stack_base ||
+ newsp - d->stack_base > d->stack_size))
+ /* The new stack pointer does not intersect with the
+ stack the exec server set up for us, so free that stack. */
+ __vm_deallocate (__mach_task_self (), d->stack_base, d->stack_size);
+ }
+#endif
+ }
+
+ if (argc && (void *) d != argv[0] && (d->portarray || d->intarray))
+ /* Initialize library data structures, start signal processing, etc. */
+ _hurd_init (d->flags, argv,
+ d->portarray, d->portarraysize,
+ d->intarray, d->intarraysize);
+
+#ifndef SHARED
+ __libc_enable_secure = d->flags & EXEC_SECURE;
+#endif
+}
+
+
+static inline void
+init (int *data)
+{
+ int argc = *data;
+ char **argv = (void *) (data + 1);
+ char **envp = &argv[argc + 1];
+ struct hurd_startup_data *d;
+ unsigned long int threadvars[_HURD_THREADVAR_MAX];
+
+ /* Provide temporary storage for thread-specific variables on the startup
+ stack so the cthreads initialization code can use them for malloc et al,
+ or so we can use malloc below for the real threadvars array. */
+ memset (threadvars, 0, sizeof threadvars);
+ __hurd_threadvar_stack_offset = (unsigned long int) threadvars;
+
+ while (*envp)
+ ++envp;
+ d = (void *) ++envp;
+
+ /* The user might have defined a value for this, to get more variables.
+ Otherwise it will be zero on startup. We must make sure it is set
+ properly before before cthreads initialization, so cthreads can know
+ how much space to leave for thread variables. */
+ if (__hurd_threadvar_max < _HURD_THREADVAR_MAX)
+ __hurd_threadvar_max = _HURD_THREADVAR_MAX;
+
+
+ /* After possibly switching stacks, call `init1' (above) with the user
+ code as the return address, and the argument data immediately above
+ that on the stack. */
+
+ if (_cthread_init_routine)
+ {
+ /* Initialize cthreads, which will allocate us a new stack to run on. */
+ void *newsp = (*_cthread_init_routine) ();
+ struct hurd_startup_data *od;
+#ifdef SHARED
+ void *oldsp;
+ unsigned int i, data_offset;
+#endif
+
+ /* Copy per-thread variables from that temporary
+ area onto the new cthread stack. */
+ memcpy (__hurd_threadvar_location_from_sp (0, newsp),
+ threadvars, sizeof threadvars);
+
+ /* Copy the argdata from the old stack to the new one. */
+ newsp = memcpy (newsp - ((char *) &d[1] - (char *) data), data,
+ (char *) d - (char *) data);
+
+#ifdef SHARED
+ /* And readjust the dynamic linker's idea of where the argument
+ vector lives. */
+ assert (_dl_argv == argv);
+ _dl_argv = (void *) ((int *) newsp + 1);
+#endif
+
+ /* Set up the Hurd startup data block immediately following
+ the argument and environment pointers on the new stack. */
+ od = (newsp + ((char *) d - (char *) data));
+ if (!argc || (void *) argv[0] == d)
+ /* We were started up by the kernel with arguments on the stack.
+ There is no Hurd startup data, so zero the block. */
+ memset (od, 0, sizeof *od);
+ else
+ /* Copy the Hurd startup data block to the new stack. */
+ *od = *d;
+
+#ifndef SHARED
+ asm ("mtlr %0; mr 1,%1; li 0,0; mr 3,%1; stwu 0,-16(1); b init1"
+ : : "r" (return_address), "r" (newsp));
+ (void) init1; /* To avoid `defined but not used' warning. */
+ /* NOTREACHED */
+#else
+ /* Copy the rest of the stack. Don't call a function to do that,
+ because that will alter the current stack. */
+ asm ("mr %0,1" : "=r" (oldsp));
+ data_offset = (unsigned int) data - (unsigned int) oldsp;
+ newsp -= data_offset;
+ for (i = 0; i < data_offset / 4; i++)
+ ((unsigned int *)newsp)[i] = ((unsigned int *)oldsp)[i];
+
+ /* Relocate stack frames. */
+ {
+ unsigned int *oldframe0 = (unsigned int *)oldsp;
+ unsigned int *oldframe1 = *(unsigned int **)oldframe0;
+ unsigned int *oldframe2 = *(unsigned int **)oldframe1;
+ unsigned int *newframe0 = (unsigned int *)newsp;
+ unsigned int *newframe1 = newframe0 + (unsigned int)(oldframe1 - oldframe0);
+ unsigned int *newframe2 = newframe1 + (unsigned int)(oldframe2 - oldframe1);
+ *(unsigned int **)newframe0 = newframe1;
+ *(unsigned int **)newframe1 = newframe2;
+ }
+
+ asm ("mr 1,%0; mr 31,%0" : : "r" (newsp)); /* XXX */
+ init1 (newsp + data_offset);
+#endif
+ }
+ else
+ {
+ /* We are not using cthreads, so we will have just a single allocated
+ area for the per-thread variables of the main user thread. */
+ unsigned long int *array;
+ unsigned int i;
+
+ array = malloc (__hurd_threadvar_max * sizeof (unsigned long int));
+ if (array == NULL)
+ __libc_fatal ("Can't allocate single-threaded thread variables.");
+
+ /* Copy per-thread variables from the temporary array into the
+ newly malloc'd space. */
+ memcpy (array, threadvars, sizeof threadvars);
+ __hurd_threadvar_stack_offset = (unsigned long int) array;
+ for (i = _HURD_THREADVAR_MAX; i < __hurd_threadvar_max; ++i)
+ array[i] = 0;
+
+#ifndef SHARED
+ asm ("mr 3,%0; mtlr %1; addi 1,3,-16; b init1"
+ : : "r" (data), "r" (return_address));
+ /* NOTREACHED */
+#else
+ init1 (data);
+#endif
+ }
+}
+
+
+/* Do the first essential initializations that must precede all else. */
+static inline void
+first_init (void)
+{
+ /* Initialize data structures so we can do RPCs. */
+ __mach_init ();
+
+ RUN_HOOK (_hurd_preinit_hook, ());
+}
+
+#ifdef SHARED
+/* This function is called specially by the dynamic linker to do early
+ initialization of the shared C library before normal initializers
+ expecting a Posixoid environment can run. It gets called with the
+ stack set up just as the user will see it, so it can switch stacks. */
+
+void
+_dl_init_first (int argc, ...)
+{
+ asm ("li 3,0xaa; .long 0");
+ first_init ();
+
+ init (&argc);
+}
+#endif
+
+
+#ifdef SHARED
+/* The regular posixland initialization is what goes into libc's
+ normal initializer. */
+/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
+ pointer in the dynamic section based solely on that. It is convention
+ for this function to be in the `.init' section, but the symbol name is
+ the only thing that really matters!! */
+strong_alias (posixland_init, _init);
+
+
+void
+__libc_init_first (int argc, char **argv, char **envp)
+{
+ /* Everything was done in the shared library initializer, _init. */
+}
+#else
+strong_alias (posixland_init, __libc_init_first);
+
+
+void
+_hurd_stack_setup (int *data)
+{
+ register unsigned int address;
+ asm ("mflr %0" : "=r" (address));
+ return_address = address;
+
+ first_init ();
+
+ _hurd_startup ((void **) data, &init);
+}
+#endif
+
+
+/* This function is defined here so that if this file ever gets into
+ ld.so we will get a link error. Having this file silently included
+ in ld.so causes disaster, because the _init definition above will
+ cause ld.so to gain an init function, which is not a cool thing. */
+
+void
+_dl_start (void)
+{
+ abort ();
+}
diff --git a/libc/sysdeps/mach/hurd/powerpc/intr-msg.h b/libc/sysdeps/mach/hurd/powerpc/intr-msg.h
new file mode 100644
index 000000000..a3cb6ef7e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/powerpc/intr-msg.h
@@ -0,0 +1,99 @@
+/* Machine-dependent details of interruptible RPC messaging. PowerPC version.
+ Copyright (C) 1995,96,97,99,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define INTR_MSG_TRAP(msg, option, send_size, rcv_size, rcv_name, timeout, notify) \
+({ \
+ error_t err; \
+ asm (".globl _hurd_intr_rpc_msg_do_trap\n" \
+ ".globl _hurd_intr_rpc_msg_in_trap\n" \
+ " mr 3, %1\n" \
+ " mr 4, %2\n" \
+ " mr 5, %3\n" \
+ " mr 6, %4\n" \
+ " mr 7, %5\n" \
+ " mr 8, %6\n" \
+ " mr 9, %7\n" \
+ " li 0, -25\n" \
+ "_hurd_intr_rpc_msg_do_trap: sc\n" \
+ "_hurd_intr_rpc_msg_in_trap: mr 3, %0\n" \
+ : "=r" (err) \
+ : "r" (msg), "r" (option), "r" (send_size), "r" (rcv_size), \
+ "r" (rcv_name), "r" (timeout), "r" (notify) \
+ : "0", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); \
+ err; \
+})
+
+static void inline
+INTR_MSG_BACK_OUT (struct ppc_thread_state *state)
+{
+ return;
+}
+
+#include "hurdfault.h"
+
+/* This cannot be an inline function because it calls setjmp. */
+#define SYSCALL_EXAMINE(state, callno) \
+({ \
+ u_int32_t *p = (void *) ((state)->srr0 - 4); \
+ int result; \
+ _hurdsig_catch_memory_fault (p) ? 0 : \
+ ({ \
+ if (result = (*p == 0x44000002)) \
+ /* The PC is just after an `sc' instruction. \
+ This is a system call in progress; %r0 holds the call number. */ \
+ *(callno) = (state)->r0; \
+ _hurdsig_end_catch_fault (); \
+ result; \
+ }); \
+})
+
+struct mach_msg_trap_args
+ {
+ /* This is the order of arguments to mach_msg_trap. */
+ mach_msg_header_t *msg;
+ mach_msg_option_t option;
+ mach_msg_size_t send_size;
+ mach_msg_size_t rcv_size;
+ mach_port_t rcv_name;
+ mach_msg_timeout_t timeout;
+ mach_port_t notify;
+ };
+
+/* This cannot be an inline function because it calls setjmp. */
+#define MSG_EXAMINE(state, msgid, rcv_name, send_name, option, timeout) \
+({ \
+ mach_msg_header_t *msg = (mach_msg_header_t *) (state)->r3; \
+ *(option) = (mach_msg_option_t) (state)->r4; \
+ *(rcv_name) = (mach_port_t) (state)->r7; \
+ *(timeout) = (mach_msg_timeout_t) (state)->r8; \
+ (msg == 0) ? \
+ ({ \
+ *(send_name) = MACH_PORT_NULL; \
+ *(msgid) = 0; \
+ 0; \
+ }) : \
+ (_hurdsig_catch_memory_fault (msg) ? -1 : \
+ ({ \
+ *(send_name) = msg->msgh_remote_port; \
+ *(msgid) = msg->msgh_id; \
+ _hurdsig_end_catch_fault (); \
+ 0; \
+ }) \
+ ); \
+})
diff --git a/libc/sysdeps/mach/hurd/powerpc/longjmp-ts.c b/libc/sysdeps/mach/hurd/powerpc/longjmp-ts.c
new file mode 100644
index 000000000..757366bc4
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/powerpc/longjmp-ts.c
@@ -0,0 +1,57 @@
+/* Perform a `longjmp' on a Mach thread_state. PowerPC version.
+ Copyright (C) 1991,94,95,97,2001, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd/signal.h>
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <mach/thread_status.h>
+
+
+/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'. */
+
+void
+_hurd_longjmp_thread_state (void *state, jmp_buf env, int val)
+{
+ struct ppc_thread_state *ts = state;
+
+ /* XXX should we set up the FPRs as well? And how? */
+ ts->r1 = env[0].__jmpbuf[JB_GPR1];
+ ts->r2 = env[0].__jmpbuf[JB_GPR2];
+ ts->r14 = env[0].__jmpbuf[JB_GPRS+0];
+ ts->r15 = env[0].__jmpbuf[JB_GPRS+1];
+ ts->r16 = env[0].__jmpbuf[JB_GPRS+2];
+ ts->r17 = env[0].__jmpbuf[JB_GPRS+3];
+ ts->r18 = env[0].__jmpbuf[JB_GPRS+4];
+ ts->r19 = env[0].__jmpbuf[JB_GPRS+5];
+ ts->r20 = env[0].__jmpbuf[JB_GPRS+6];
+ ts->r21 = env[0].__jmpbuf[JB_GPRS+7];
+ ts->r22 = env[0].__jmpbuf[JB_GPRS+8];
+ ts->r23 = env[0].__jmpbuf[JB_GPRS+9];
+ ts->r24 = env[0].__jmpbuf[JB_GPRS+10];
+ ts->r25 = env[0].__jmpbuf[JB_GPRS+11];
+ ts->r26 = env[0].__jmpbuf[JB_GPRS+12];
+ ts->r27 = env[0].__jmpbuf[JB_GPRS+13];
+ ts->r28 = env[0].__jmpbuf[JB_GPRS+14];
+ ts->r29 = env[0].__jmpbuf[JB_GPRS+15];
+ ts->r30 = env[0].__jmpbuf[JB_GPRS+16];
+ ts->r31 = env[0].__jmpbuf[JB_GPRS+17];
+ ts->cr = env[0].__jmpbuf[JB_CR];
+ ts->r3 = val ?: 1;
+ ts->srr0 = ts->lr = env[0].__jmpbuf[JB_LR];
+}
diff --git a/libc/sysdeps/mach/hurd/powerpc/register-dump.h b/libc/sysdeps/mach/hurd/powerpc/register-dump.h
new file mode 100644
index 000000000..037717522
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/powerpc/register-dump.h
@@ -0,0 +1,120 @@
+/* Dump registers. PowerPC/Hurd version.
+ Copyright (C) 1998, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/uio.h>
+#include <stdio-common/_itoa.h>
+
+/* This prints out the information in the following form: */
+static const char dumpform[] = "\
+Register dump:\n\
+fp0-3: 0000030%0000031% 0000032%0000033% 0000034%0000035% 0000036%0000037%\n\
+fp4-7: 0000038%0000039% 000003a%000003b% 000003c%000003d% 000003e%000003f%\n\
+fp8-11: 0000040%0000041% 0000042%0000043% 0000044%0000045% 0000046%0000047%\n\
+fp12-15: 0000048%0000049% 000004a%000004b% 000004c%000004d% 000004e%000004f%\n\
+fp16-19: 0000050%0000051% 0000052%0000053% 0000054%0000055% 0000056%0000057%\n\
+fp20-23: 0000058%0000059% 000005a%000005b% 000005c%000005d% 000005e%000005f%\n\
+fp24-27: 0000060%0000061% 0000062%0000063% 0000064%0000065% 0000066%0000067%\n\
+fp28-31: 0000068%0000069% 000006a%000006b% 000006c%000006d% 000006e%000006f%\n\
+r0 =0000002% sp =0000003% r2 =0000004% r3 =0000005%\n\
+r4 =0000006% r5 =0000007% r6 =0000008% r7 =0000009% sr0=0000000% sr1=0000001%\n\
+r8 =000000a% r9 =000000b% r10=000000c% r11=000000d% cr=0000022% xer=0000023%\n\
+r12=000000e% r13=000000f% r14=0000010% r15=0000011% lr=0000024% ctr=0000025%\n\
+r16=0000012% r17=0000013% r18=0000014% r19=0000015% mq=0000026% fcr=0000071%\n\
+r20=0000016% r21=0000017% r22=0000018% r23=0000019% dar=0000028% dsi=0000029%\n\
+r24=000001a% r25=000001b% r26=000001c% r27=000001d% exc=000002a%\n\
+r28=000001e% r29=000001f% r30=0000020% r31=0000021%\n\
+";
+
+/* Most of the fields are self-explanatory. 'sr0' is the next
+ instruction to execute, from SRR0, which may have some relationship
+ with the instruction that caused the exception. 'r3*' is the value
+ that will be returned in register 3 when the current system call
+ returns. 'sr1' is SRR1, bits 16-31 of which are copied from the MSR:
+
+ 16 - External interrupt enable
+ 17 - Privilege level (1=user, 0=supervisor)
+ 18 - FP available
+ 19 - Machine check enable (if clear, processor locks up on machine check)
+ 20 - FP exception mode bit 0 (FP exceptions recoverable)
+ 21 - Single-step trace enable
+ 22 - Branch trace enable
+ 23 - FP exception mode bit 1
+ 25 - exception prefix (if set, exceptions are taken from 0xFFFnnnnn,
+ otherwise from 0x000nnnnn).
+ 26 - Instruction address translation enabled.
+ 27 - Data address translation enabled.
+ 30 - Exception is recoverable (otherwise, don't try to return).
+ 31 - Little-endian mode enable.
+
+ 'Trap' is the address of the exception:
+
+ 00200 - Machine check exception (memory parity error, for instance)
+ 00300 - Data access exception (memory not mapped, see dsisr for why)
+ 00400 - Instruction access exception (memory not mapped)
+ 00500 - External interrupt
+ 00600 - Alignment exception (see dsisr for more information)
+ 00700 - Program exception (illegal/trap instruction, FP exception)
+ 00800 - FP unavailable (should not be seen by user code)
+ 00900 - Decrementer exception (for instance, SIGALRM)
+ 00A00 - I/O controller interface exception
+ 00C00 - System call exception (for instance, kill(3)).
+ 00E00 - FP assist exception (optional FP instructions, etc.)
+
+ 'dar' is the memory location, for traps 00300, 00400, 00600, 00A00.
+ 'dsisr' has the following bits under trap 00300:
+ 0 - direct-store error exception
+ 1 - no page table entry for page
+ 4 - memory access not permitted
+ 5 - trying to access I/O controller space or using lwarx/stwcx on
+ non-write-cached memory
+ 6 - access was store
+ 9 - data access breakpoint hit
+ 10 - segment table search failed to find translation (64-bit ppcs only)
+ 11 - I/O controller instruction not permitted
+ For trap 00400, the same bits are set in SRR1 instead.
+ For trap 00600, bits 12-31 of the DSISR set to allow emulation of
+ the instruction without actually having to read it from memory.
+*/
+
+#define xtoi(x) (x >= 'a' ? x + 10 - 'a' : x - '0')
+
+static void
+register_dump (int fd, struct sigcontext *ctx)
+{
+ char buffer[sizeof(dumpform)];
+ char *bufferpos;
+ unsigned regno;
+ unsigned *regs = (unsigned *)(&ctx->sc_srr0);
+
+ memcpy(buffer, dumpform, sizeof(dumpform));
+
+ /* Generate the output. */
+ while ((bufferpos = memchr (buffer, '%', sizeof(dumpform))))
+ {
+ regno = xtoi (bufferpos[-1]) | xtoi (bufferpos[-2]) << 4;
+ memset (bufferpos-2, '0', 3);
+ _itoa_word (regs[regno], bufferpos+1, 16, 0);
+ }
+
+ /* Write the output. */
+ write (fd, buffer, sizeof(buffer));
+}
+
+#define REGISTER_DUMP \
+ register_dump (fd, ctx)
diff --git a/libc/sysdeps/mach/hurd/powerpc/sigreturn.c b/libc/sysdeps/mach/hurd/powerpc/sigreturn.c
new file mode 100644
index 000000000..18e37a3d4
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/powerpc/sigreturn.c
@@ -0,0 +1,186 @@
+/* Return from signal handler for Hurd. PowerPC version.
+ Copyright (C) 1996,97,98,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/threadvar.h>
+#include <stdlib.h>
+
+int
+__sigreturn (struct sigcontext *scp)
+{
+ struct hurd_sigstate *ss;
+ mach_port_t *reply_port;
+
+ if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ ss = _hurd_self_sigstate ();
+ __spin_lock (&ss->lock);
+
+ /* Restore the set of blocked signals, and the intr_port slot. */
+ ss->blocked = scp->sc_mask;
+ ss->intr_port = scp->sc_intr_port;
+
+ /* Check for pending signals that were blocked by the old set. */
+ if (ss->pending & ~ss->blocked)
+ {
+ /* There are pending signals that just became unblocked. Wake up the
+ signal thread to deliver them. But first, squirrel away SCP where
+ the signal thread will notice it if it runs another handler, and
+ arrange to have us called over again in the new reality. */
+ ss->context = scp;
+ __spin_unlock (&ss->lock);
+ __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
+ /* If a pending signal was handled, sig_post never returned. */
+ __spin_lock (&ss->lock);
+ ss->context = NULL;
+ }
+
+ if (scp->sc_onstack)
+ {
+ ss->sigaltstack.ss_flags &= ~SS_ONSTACK; /* XXX threadvars */
+ /* XXX cannot unlock until off sigstack */
+ abort ();
+ }
+ else
+ __spin_unlock (&ss->lock);
+
+ /* Destroy the MiG reply port used by the signal handler, and restore the
+ reply port in use by the thread when interrupted. */
+ reply_port =
+ (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY);
+ if (*reply_port)
+ {
+ mach_port_t port = *reply_port;
+
+ /* Assigning MACH_PORT_DEAD here tells libc's mig_get_reply_port not to
+ get another reply port, but avoids mig_dealloc_reply_port trying to
+ deallocate it after the receive fails (which it will, because the
+ reply port will be bogus, whether we do this or not). */
+ *reply_port = MACH_PORT_DEAD;
+
+ __mach_port_destroy (__mach_task_self (), port);
+ }
+ *reply_port = scp->sc_reply_port;
+
+ /* Restore FPU state. */
+#define restore_fpr(n) \
+ asm volatile ("lfd " #n ",%0(31)" : : "i" (n * 4))
+
+ asm volatile ("mr 31,%0" : : "r" (scp->sc_fprs));
+
+ /* Restore the floating-point control/status register. */
+ asm volatile ("lfd 0,256(31)");
+ asm volatile ("mtfsf 0xff,0");
+
+ /* Restore floating-point registers. */
+ restore_fpr (0);
+ restore_fpr (1);
+ restore_fpr (2);
+ restore_fpr (3);
+ restore_fpr (4);
+ restore_fpr (5);
+ restore_fpr (6);
+ restore_fpr (7);
+ restore_fpr (8);
+ restore_fpr (9);
+ restore_fpr (10);
+ restore_fpr (11);
+ restore_fpr (12);
+ restore_fpr (13);
+ restore_fpr (14);
+ restore_fpr (15);
+ restore_fpr (16);
+ restore_fpr (17);
+ restore_fpr (18);
+ restore_fpr (19);
+ restore_fpr (20);
+ restore_fpr (21);
+ restore_fpr (22);
+ restore_fpr (23);
+ restore_fpr (24);
+ restore_fpr (25);
+ restore_fpr (26);
+ restore_fpr (27);
+ restore_fpr (28);
+ restore_fpr (29);
+ restore_fpr (30);
+ restore_fpr (31);
+
+ /* Load all the registers from the sigcontext. */
+#define restore_gpr(n) \
+ asm volatile ("lwz " #n ",%0(31)" : : "i" (n * 4))
+
+ asm volatile ("addi 31,31,-188"); /* r31 = scp->gprs */
+
+ /* Restore the special purpose registers. */
+ asm volatile ("lwz 0,128(31); mtcr 0");
+ asm volatile ("lwz 0,132(31); mtxer 0");
+ asm volatile ("lwz 0,136(31); mtlr 0");
+ asm volatile ("lwz 0,-8(31); mtctr 0"); /* XXX this is the PC */
+#if 0
+ asm volatile ("lwz 0,144(31); mtmq %0"); /* PPC601 only */
+#endif
+
+ /* Restore the normal registers. */
+ restore_gpr (0);
+ restore_gpr (1);
+ restore_gpr (2);
+ restore_gpr (3);
+ restore_gpr (4);
+ restore_gpr (5);
+ restore_gpr (6);
+ restore_gpr (7);
+ restore_gpr (8);
+ restore_gpr (9);
+ restore_gpr (10);
+ restore_gpr (11);
+ restore_gpr (12);
+ restore_gpr (13);
+ restore_gpr (14);
+ restore_gpr (15);
+ restore_gpr (16);
+ restore_gpr (17);
+ restore_gpr (18);
+ restore_gpr (19);
+ restore_gpr (20);
+ restore_gpr (21);
+ restore_gpr (22);
+ restore_gpr (23);
+ restore_gpr (24);
+ restore_gpr (25);
+ restore_gpr (26);
+ restore_gpr (27);
+ restore_gpr (28);
+ restore_gpr (29);
+ restore_gpr (30);
+ restore_gpr (31);
+
+ /* Return. */
+ asm volatile ("bctr"); /* XXX CTR is not restored! */
+
+ /* NOTREACHED */
+ return -1;
+}
+
+weak_alias (__sigreturn, sigreturn)
diff --git a/libc/sysdeps/mach/hurd/powerpc/static-start.S b/libc/sysdeps/mach/hurd/powerpc/static-start.S
new file mode 100644
index 000000000..3420fcd31
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/powerpc/static-start.S
@@ -0,0 +1,59 @@
+/* Startup code for statically linked Hurd/PowerPC binaries.
+ Copyright (C) 1998,2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ /* These are the various addresses we require. */
+ .section ".rodata"
+ .align 2
+ weak_extern(__libc_csu_init)
+ weak_extern(__libc_csu_fini)
+L(start_addresses):
+ .long _SDA_BASE_
+ .long JUMPTARGET(main)
+ .long JUMPTARGET(__libc_csu_init)
+ .long JUMPTARGET(__libc_csu_fini)
+ ASM_SIZE_DIRECTIVE(L(start_addresses))
+
+ .section ".text"
+ENTRY(_start)
+ /* Save the stack pointer to pass to _hurd_stack_setup. */
+ mr r3,r1
+ /* Set up an initial stack frame. */
+ li r0,0
+ stwu r0,-16(r1)
+ /* Call _hurd_stack_setup. */
+ bl JUMPTARGET(_hurd_stack_setup)
+ /* Pass the argument data to __libc_start_main. */
+ addi r9,r1,16
+ /* Clear the LR. */
+ li r0,0
+ mtlr r0
+ /* Set r13 to point at the 'small data area', and put the address of
+ start_addresses in r8... */
+ lis r8,L(start_addresses)@ha
+ lwzu r13,L(start_addresses)@l(r8)
+ /* and continue in libc-start, in glibc. */
+ b JUMPTARGET(__libc_start_main)
+END(_start)
+
+/* Define a symbol for the first piece of initialized data. */
+ .section ".data"
+__data_start:
+weak_alias (__data_start, data_start)
diff --git a/libc/sysdeps/mach/hurd/powerpc/trampoline.c b/libc/sysdeps/mach/hurd/powerpc/trampoline.c
new file mode 100644
index 000000000..4e1ea4b9d
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/powerpc/trampoline.c
@@ -0,0 +1,257 @@
+/* Set thread_state for sighandler, and sigcontext to recover. For PowerPC.
+ Copyright (C) 1994,1995,1996,1997,1998,1999,2001,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd/signal.h>
+#include <hurd/userlink.h>
+#include <thread_state.h>
+#include <assert.h>
+#include <errno.h>
+#include "hurdfault.h"
+#include <intr-msg.h>
+
+struct sigcontext *
+_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+ int signo, struct hurd_signal_detail *detail,
+ volatile int rpc_wait,
+ struct machine_thread_all_state *state)
+{
+ void trampoline (void);
+ void rpc_wait_trampoline (void);
+ void *volatile sigsp;
+ struct sigcontext *scp;
+
+ if (ss->context)
+ {
+ /* We have a previous sigcontext that sigreturn was about
+ to restore when another signal arrived. We will just base
+ our setup on that. */
+ if (! _hurdsig_catch_memory_fault (ss->context))
+ {
+ memcpy (&state->basic, &ss->context->sc_ppc_thread_state,
+ sizeof (state->basic));
+ memcpy (&state->exc, &ss->context->sc_ppc_exc_state,
+ sizeof (state->exc));
+ memcpy (&state->fpu, &ss->context->sc_ppc_float_state,
+ sizeof (state->fpu));
+ state->set = (1 << PPC_THREAD_STATE) | (1 << PPC_EXCEPTION_STATE)
+ | (1 << PPC_FLOAT_STATE);
+ }
+ }
+
+ if (! machine_get_basic_state (ss->thread, state))
+ return NULL;
+
+ if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
+ !(ss->sigaltstack.ss_flags & (SS_DISABLE|SS_ONSTACK)))
+ {
+ sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
+ ss->sigaltstack.ss_flags |= SS_ONSTACK;
+ /* XXX need to set up base of new stack for
+ per-thread variables, cthreads. */
+ }
+ else
+ sigsp = (char *) state->basic.SP;
+
+ /* Set up the sigcontext structure on the stack. This is all the stack
+ needs, since the args are passed in registers (below). */
+ sigsp -= sizeof (*scp);
+ scp = sigsp;
+ sigsp -= 16; /* Reserve some space for a stack frame. */
+
+ if (_hurdsig_catch_memory_fault (scp))
+ {
+ /* We got a fault trying to write the stack frame.
+ We cannot set up the signal handler.
+ Returning NULL tells our caller, who will nuke us with a SIGILL. */
+ return NULL;
+ }
+ else
+ {
+ int ok;
+
+ /* Set up the sigcontext from the current state of the thread. */
+
+ scp->sc_onstack = ss->sigaltstack.ss_flags & SS_ONSTACK ? 1 : 0;
+
+ /* struct sigcontext is laid out so that starting at sc_srr0
+ mimics a struct ppc_thread_state. */
+ memcpy (&scp->sc_ppc_thread_state,
+ &state->basic, sizeof (state->basic));
+
+ /* struct sigcontext is laid out so that starting at sc_dar
+ mimics a struct ppc_exc_state. */
+ ok = machine_get_state (ss->thread, state, PPC_EXCEPTION_STATE,
+ &state->exc, &scp->sc_ppc_exc_state,
+ sizeof (state->exc));
+
+ /* struct sigcontext is laid out so that starting at sc_fprs[0]
+ mimics a struct ppc_float_state. */
+ if (ok)
+ ok = machine_get_state (ss->thread, state, PPC_FLOAT_STATE,
+ &state->fpu, &scp->sc_ppc_float_state,
+ sizeof (state->fpu));
+
+ _hurdsig_end_catch_fault ();
+
+ if (!ok)
+ return NULL;
+ }
+
+ /* Modify the thread state to call the trampoline code on the new stack. */
+ if (rpc_wait)
+ {
+ /* The signalee thread was blocked in a mach_msg_trap system call,
+ still waiting for a reply. We will have it run the special
+ trampoline code which retries the message receive before running
+ the signal handler.
+
+ To do this we change the OPTION argument in its registers to
+ enable only message reception, since the request message has
+ already been sent. */
+
+ /* The system call arguments are stored in consecutive registers
+ starting with r3. */
+ struct mach_msg_trap_args *args = (void *) &state->basic.r3;
+
+ if (_hurdsig_catch_memory_fault (args))
+ {
+ /* Faulted accessing ARGS. Bomb. */
+ return NULL;
+ }
+
+ assert (args->option & MACH_RCV_MSG);
+ /* Disable the message-send, since it has already completed. The
+ calls we retry need only wait to receive the reply message. */
+ args->option &= ~MACH_SEND_MSG;
+
+ /* Limit the time to receive the reply message, in case the server
+ claimed that `interrupt_operation' succeeded but in fact the RPC
+ is hung. */
+ args->option |= MACH_RCV_TIMEOUT;
+ args->timeout = _hurd_interrupted_rpc_timeout;
+
+ _hurdsig_end_catch_fault ();
+
+ state->basic.PC = (int) rpc_wait_trampoline;
+ /* After doing the message receive, the trampoline code will need to
+ update the r3 value to be restored by sigreturn. To simplify
+ the assembly code, we pass the address of its slot in SCP to the
+ trampoline code in r10. */
+ state->basic.r10 = (long int) &scp->sc_gprs[3];
+ /* We must preserve the mach_msg_trap args in r3..r9.
+ Pass the handler args to the trampoline code in r11..r13. */
+ state->basic.r11 = signo;
+ state->basic.r12 = detail->code;
+ state->basic.r13 = (int) scp;
+ }
+ else
+ {
+ state->basic.PC = (int) trampoline;
+ state->basic.r3 = signo;
+ state->basic.r4 = detail->code;
+ state->basic.r5 = (int) scp;
+ }
+
+ state->basic.r1 = (int) sigsp; /* r1 is the stack pointer. */
+
+ /* We pass the handler function to the trampoline code in ctr. */
+ state->basic.ctr = (int) handler;
+ /* In r15, we store the address of __sigreturn itself,
+ for the trampoline code to use. */
+ state->basic.r15 = (int) &__sigreturn;
+ /* In r16, we save the SCP value to pass to __sigreturn
+ after the handler returns. */
+ state->basic.r16 = (int) scp;
+
+ /* In r3, we store a pointer to the registers in STATE so that the
+ trampoline code can load the registers from that. For some reason,
+ thread_set_state doesn't set all registers. */
+ state->basic.r17 = state->basic.r3; /* Store the real r3 in r17. */
+ state->basic.r3 = (int) &state->basic.r0;
+
+ return scp;
+}
+
+/* The trampoline code follows. This used to be located inside
+ _hurd_setup_sighandler, but was optimized away by gcc 2.95. */
+
+/* This function sets some registers which the trampoline code uses
+ and which are not automatically set by thread_set_state.
+ In r3 we have a pointer to the registers in STATE. */
+asm ("trampoline_load_registers:\n"
+ "lwz 17,68(3)\n" /* The real r3. */
+ "lwz 4,16(3)\n"
+ "lwz 5,20(3)\n"
+ "lwz 6,24(3)\n"
+ "lwz 7,28(3)\n"
+ "lwz 8,32(3)\n"
+ "lwz 9,36(3)\n"
+ "lwz 10,40(3)\n"
+ "lwz 11,44(3)\n"
+ "lwz 12,48(3)\n"
+ "lwz 13,52(3)\n"
+ "lwz 14,56(3)\n"
+ "lwz 15,60(3)\n"
+ "lwz 16,64(3)\n"
+ "mr 3,17\n"
+ "blr\n");
+
+asm ("rpc_wait_trampoline:\n");
+ /* This is the entry point when we have an RPC reply message to receive
+ before running the handler. The MACH_MSG_SEND bit has already been
+ cleared in the OPTION argument in our registers. For our convenience,
+ r10 points to the sc_regs[3] member of the sigcontext (saved r3). */
+
+asm (/* Retry the interrupted mach_msg system call. */
+ "bl trampoline_load_registers\n"
+ "li 0, -25\n" /* mach_msg_trap */
+ "sc\n"
+ /* When the sigcontext was saved, r3 was MACH_RCV_INTERRUPTED. But
+ now the message receive has completed and the original caller of
+ the RPC (i.e. the code running when the signal arrived) needs to
+ see the final return value of the message receive in r3. So
+ store the new r3 value into the sc_regs[3] member of the sigcontext
+ (whose address is in r10 to make this code simpler). */
+ "stw 3, 0(10)\n"
+ /* Since the argument registers needed to have the mach_msg_trap
+ arguments, we've stored the arguments to the handler function
+ in registers r11..r13 of the state structure. */
+ "mr 3,11\n"
+ "mr 4,12\n"
+ "mr 5,13\n");
+
+asm ("trampoline:\n");
+ /* Entry point for running the handler normally. The arguments to the
+ handler function are already in the standard registers:
+
+ r3 SIGNO
+ r4 SIGCODE
+ r5 SCP
+
+ r16 also contains SCP; this value is callee-saved (and so should not get
+ clobbered by running the handler). We use this saved value to pass to
+ __sigreturn, so the handler can clobber the argument registers if it
+ likes. */
+asm ("bl trampoline_load_registers\n"
+ "bctrl\n" /* Call the handler function. */
+ "mtctr 15\n" /* Copy &__sigreturn to CTR. */
+ "mr 3,16\n" /* Copy the saved SCP to r3. */
+ "bctr\n" /* Call __sigreturn (SCP). */
+ );
diff --git a/libc/sysdeps/mach/hurd/ppoll.c b/libc/sysdeps/mach/hurd/ppoll.c
new file mode 100644
index 000000000..693bc1383
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/ppoll.c
@@ -0,0 +1,30 @@
+/* poll file descriptors. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/poll.h>
+#include <sys/time.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+int
+ppoll (struct pollfd *fds, nfds_t nfds,
+ const struct timespec *timeout, const sigset_t *sigmask)
+{
+ return _hurd_select (nfds, fds, NULL, NULL, NULL, timeout, sigmask);
+}
diff --git a/libc/sysdeps/mach/hurd/pread.c b/libc/sysdeps/mach/hurd/pread.c
new file mode 100644
index 000000000..a14553be7
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/pread.c
@@ -0,0 +1,33 @@
+/* Read block from given position in file without changing file pointer.
+ Hurd version.
+ Copyright (C) 1999,2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+ssize_t
+__libc_pread (int fd, void *buf, size_t nbytes, off_t offset)
+{
+ return __libc_pread64 (fd, buf, nbytes, (off64_t) offset);
+}
+
+#ifndef __libc_pread
+strong_alias (__libc_pread, __pread)
+weak_alias (__libc_pread, pread)
+#endif
diff --git a/libc/sysdeps/mach/hurd/pread64.c b/libc/sysdeps/mach/hurd/pread64.c
new file mode 100644
index 000000000..fc69ae505
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/pread64.c
@@ -0,0 +1,39 @@
+/* Read block from given position in file without changing file pointer.
+ Hurd version.
+ Copyright (C) 2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd/fd.h>
+
+ssize_t
+__libc_pread64 (int fd, void *buf, size_t nbytes, off64_t offset)
+{
+ error_t err;
+ if (offset < 0)
+ err = EINVAL;
+ else
+ err = HURD_FD_USE (fd, _hurd_fd_read (descriptor, buf, &nbytes, offset));
+ return err ? __hurd_dfail (fd, err) : nbytes;
+}
+
+#ifndef __libc_pread64
+weak_alias (__libc_pread64, __pread64)
+weak_alias (__libc_pread64, pread64)
+#endif
diff --git a/libc/sysdeps/mach/hurd/prof-freq.c b/libc/sysdeps/mach/hurd/prof-freq.c
new file mode 100644
index 000000000..a3707033a
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/prof-freq.c
@@ -0,0 +1,2 @@
+/* __profile_frequency is in sysdeps/mach/hurd/profil.c. This file
+is here as a place-holder to prevent the use of sysdeps/generic/prof-freq.c. */
diff --git a/libc/sysdeps/mach/hurd/profil.c b/libc/sysdeps/mach/hurd/profil.c
new file mode 100644
index 000000000..0426f67b6
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/profil.c
@@ -0,0 +1,285 @@
+/* Low-level statistical profiling support function. Mach/Hurd version.
+ Copyright (C) 1995, 1996, 1997, 2000, 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <hurd.h>
+#include <mach/mach4.h>
+#include <mach/pc_sample.h>
+#include <cthreads.h>
+#include <assert.h>
+#include <libc-internal.h>
+
+
+#define MAX_PC_SAMPLES 512 /* XXX ought to be exported in kernel hdr */
+
+static thread_t profile_thread = MACH_PORT_NULL;
+static u_short *samples;
+static size_t maxsamples;
+static size_t pc_offset;
+static size_t sample_scale;
+static sampled_pc_seqno_t seqno;
+static spin_lock_t lock = SPIN_LOCK_INITIALIZER;
+static mach_msg_timeout_t collector_timeout; /* ms between collections. */
+static int profile_tick;
+
+/* Reply port used by profiler thread */
+static mach_port_t profil_reply_port;
+
+/* Forwards */
+static kern_return_t profil_task_get_sampled_pcs (mach_port_t,
+ sampled_pc_seqno_t *,
+ sampled_pc_array_t,
+ mach_msg_type_number_t *);
+static void fetch_samples (void);
+static void profile_waiter (void);
+
+/* Enable statistical profiling, writing samples of the PC into at most
+ SIZE bytes of SAMPLE_BUFFER; every processor clock tick while profiling
+ is enabled, the system examines the user PC and increments
+ SAMPLE_BUFFER[((PC - OFFSET) / 2) * SCALE / 65536]. If SCALE is zero,
+ disable profiling. Returns zero on success, -1 on error. */
+
+static error_t
+update_waiter (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+{
+ error_t err;
+
+ if (profile_thread == MACH_PORT_NULL)
+ {
+ /* Set up the profiling collector thread. */
+ err = __thread_create (__mach_task_self (), &profile_thread);
+ if (! err)
+ err = __mach_setup_thread (__mach_task_self (), profile_thread,
+ &profile_waiter, NULL, NULL);
+ }
+ else
+ err = 0;
+
+ if (! err)
+ {
+ err = __task_enable_pc_sampling (__mach_task_self (), &profile_tick,
+ SAMPLED_PC_PERIODIC);
+ if (!err && sample_scale == 0)
+ /* Profiling was not turned on, so the collector thread was
+ suspended. Resume it. */
+ err = __thread_resume (profile_thread);
+ if (! err)
+ {
+ samples = sample_buffer;
+ maxsamples = size / sizeof *sample_buffer;
+ pc_offset = offset;
+ sample_scale = scale;
+ /* Calculate a good period for the collector thread. From TICK
+ and the kernel buffer size we get the length of time it takes
+ to fill the buffer; translate that to milliseconds for
+ mach_msg, and chop it in half for general lag factor. */
+ collector_timeout = MAX_PC_SAMPLES * profile_tick / 1000 / 2;
+ }
+ }
+
+ return err;
+}
+
+int
+__profile_frequency (void)
+{
+ return profile_tick;
+}
+libc_hidden_def (__profile_frequency)
+
+int
+__profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+{
+ error_t err;
+
+ __spin_lock (&lock);
+
+ if (scale == 0)
+ {
+ /* Disable profiling. */
+ int count;
+
+ if (profile_thread != MACH_PORT_NULL)
+ __thread_suspend (profile_thread);
+
+ /* Fetch the last set of samples */
+ if (sample_scale)
+ fetch_samples ();
+
+ err = __task_disable_pc_sampling (__mach_task_self (), &count);
+ sample_scale = 0;
+ seqno = 0;
+ }
+ else
+ err = update_waiter (sample_buffer, size, offset, scale);
+
+ __spin_unlock (&lock);
+
+ return err ? __hurd_fail (err) : 0;
+}
+weak_alias (__profil, profil)
+
+/* Fetch PC samples. This function must be very careful not to depend
+ on Hurd threadvar variables. We arrange that by using a special
+ stub arranged for at the end of this file. */
+static void
+fetch_samples (void)
+{
+ sampled_pc_t pc_samples[MAX_PC_SAMPLES];
+ mach_msg_type_number_t nsamples, i;
+ error_t err;
+
+ nsamples = MAX_PC_SAMPLES;
+
+ err = profil_task_get_sampled_pcs (__mach_task_self (), &seqno,
+ pc_samples, &nsamples);
+ if (err)
+ {
+ static error_t special_profil_failure;
+ static volatile int a, b, c;
+
+ special_profil_failure = err;
+ a = 1;
+ b = 0;
+ while (1)
+ c = a / b;
+ }
+
+ for (i = 0; i < nsamples; ++i)
+ {
+ /* Do arithmetic in long long to avoid overflow problems. */
+ long long pc_difference = pc_samples[i].pc - pc_offset;
+ size_t idx = ((pc_difference / 2) * sample_scale) / 65536;
+ if (idx < maxsamples)
+ ++samples[idx];
+ }
+}
+
+
+/* This function must be very careful not to depend on Hurd threadvar
+ variables. We arrange that by using special stubs arranged for at the
+ end of this file. */
+static void
+profile_waiter (void)
+{
+ mach_msg_header_t msg;
+ mach_port_t timeout_reply_port;
+
+ profil_reply_port = __mach_reply_port ();
+ timeout_reply_port = __mach_reply_port ();
+
+ while (1)
+ {
+ __spin_lock (&lock);
+
+ fetch_samples ();
+
+ __spin_unlock (&lock);
+
+ __mach_msg (&msg, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, sizeof msg,
+ timeout_reply_port, collector_timeout, MACH_PORT_NULL);
+ }
+}
+
+/* Fork interaction */
+
+/* Before fork, lock the interlock so that we are in a clean state. */
+static void
+fork_profil_prepare (void)
+{
+ __spin_lock (&lock);
+}
+text_set_element (_hurd_fork_prepare_hook, fork_profil_prepare);
+
+/* In the parent, unlock the interlock once fork is complete. */
+static void
+fork_profil_parent (void)
+{
+ __spin_unlock (&lock);
+}
+text_set_element (_hurd_fork_parent_hook, fork_profil_parent);
+
+/* In the childs, unlock the interlock, and start a profiling thread up
+ if necessary. */
+static void
+fork_profil_child (void)
+{
+ u_short *sb;
+ size_t n, o, ss;
+ error_t err;
+
+ __spin_unlock (&lock);
+
+ if (profile_thread != MACH_PORT_NULL)
+ {
+ __mach_port_deallocate (__mach_task_self (), profile_thread);
+ profile_thread = MACH_PORT_NULL;
+ }
+
+ sb = samples;
+ samples = NULL;
+ n = maxsamples;
+ maxsamples = 0;
+ o = pc_offset;
+ pc_offset = 0;
+ ss = sample_scale;
+ sample_scale = 0;
+
+ if (ss != 0)
+ {
+ err = update_waiter (sb, n * sizeof *sb, o, ss);
+ assert_perror (err);
+ }
+}
+text_set_element (_hurd_fork_child_hook, fork_profil_child);
+
+
+
+
+/* Special RPC stubs for profile_waiter are made by including the normal
+ source code, with special CPP state to prevent it from doing the
+ usual thing. */
+
+/* Include these first; then our #define's will take full effect, not
+ being overridden. */
+#include <mach/mig_support.h>
+
+/* This need not do anything; it is always associated with errors, which
+ are fatal in profile_waiter anyhow. */
+#define __mig_put_reply_port(foo)
+
+/* Use our static variable instead of the usual threadvar mechanism for
+ this. */
+#define __mig_get_reply_port() profil_reply_port
+
+/* Make the functions show up as static */
+#define mig_external static
+
+/* Turn off the attempt to generate ld aliasing records. */
+#undef weak_alias
+#define weak_alias(a,b)
+
+/* And change their names to avoid confusing disasters. */
+#define __vm_deallocate_rpc profil_vm_deallocate
+#define __task_get_sampled_pcs profil_task_get_sampled_pcs
+
+/* And include the source code */
+#include <../mach/RPC_task_get_sampled_pcs.c>
diff --git a/libc/sysdeps/mach/hurd/pselect.c b/libc/sysdeps/mach/hurd/pselect.c
new file mode 100644
index 000000000..b67122919
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/pselect.c
@@ -0,0 +1,45 @@
+/* pselect for Hurd.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Check the first NFDS descriptors each in READFDS (if not NULL) for read
+ readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
+ (if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out
+ after waiting the interval specified therein. Additionally set the sigmask
+ SIGMASK for this call. Returns the number of ready descriptors, or -1 for
+ errors. */
+int
+__pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask)
+ int nfds;
+ fd_set *readfds;
+ fd_set *writefds;
+ fd_set *exceptfds;
+ const struct timespec *timeout;
+ const sigset_t *sigmask;
+{
+ return _hurd_select (nfds, NULL,
+ readfds, writefds, exceptfds, timeout, sigmask);
+}
+weak_alias (__pselect, pselect)
diff --git a/libc/sysdeps/mach/hurd/ptrace.c b/libc/sysdeps/mach/hurd/ptrace.c
new file mode 100644
index 000000000..8f04c130f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/ptrace.c
@@ -0,0 +1,386 @@
+/* Process tracing interface `ptrace' for GNU Hurd.
+ Copyright (C) 1991, 92, 93, 95, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/msg.h>
+#include <thread_state.h>
+
+/* Perform process tracing functions. REQUEST is one of the values
+ in <sys/ptrace.h>, and determines the action to be taken.
+ For all requests except PTRACE_TRACEME, PID specifies the process to be
+ traced.
+
+ PID and the other arguments described above for the various requests should
+ appear (those that are used for the particular request) as:
+ pid_t PID, void *ADDR, int DATA, void *ADDR2
+ after PID. */
+int
+ptrace (enum __ptrace_request request, ... )
+{
+ pid_t pid;
+ void *addr, *addr2;
+ natural_t data;
+ va_list ap;
+
+ /* Read data from PID's address space, from ADDR for DATA bytes. */
+ error_t read_data (task_t task, vm_address_t *ourpage, vm_size_t *size)
+ {
+ /* Read the pages containing the addressed range. */
+ error_t err;
+ *size = round_page (addr + data) - trunc_page (addr);
+ err = __vm_read (task, trunc_page (addr), *size, ourpage, size);
+ return err;
+ }
+
+ /* Fetch the thread port for PID's user thread. */
+ error_t fetch_user_thread (task_t task, thread_t *thread)
+ {
+ thread_t threadbuf[3], *threads = threadbuf;
+ mach_msg_type_number_t nthreads = 3, i;
+ error_t err = __task_threads (task, &threads, &nthreads);
+ if (err)
+ return err;
+ if (nthreads == 0)
+ return EINVAL;
+ *thread = threads[0]; /* Assume user thread is first. */
+ for (i = 1; i < nthreads; ++i)
+ __mach_port_deallocate (__mach_task_self (), threads[i]);
+ if (threads != threadbuf)
+ __vm_deallocate (__mach_task_self (),
+ (vm_address_t) threads, nthreads * sizeof threads[0]);
+ return 0;
+ }
+
+ /* Fetch a thread state structure from PID and store it at ADDR. */
+ int get_regs (int flavor, mach_msg_type_number_t count)
+ {
+ error_t err;
+ task_t task = __pid2task (pid);
+ thread_t thread;
+ if (task == MACH_PORT_NULL)
+ return -1;
+ err = fetch_user_thread (task, &thread);
+ __mach_port_deallocate (__mach_task_self (), task);
+ if (!err)
+ err = __thread_get_state (thread, flavor, addr, &count);
+ __mach_port_deallocate (__mach_task_self (), thread);
+ return err ? __hurd_fail (err) : 0;
+ }
+
+
+ switch (request)
+ {
+ case PTRACE_TRACEME:
+ /* Make this process be traced. */
+ __sigfillset (&_hurdsig_traced);
+ __USEPORT (PROC, __proc_mark_traced (port));
+ break;
+
+ case PTRACE_CONT:
+ va_start (ap, request);
+ pid = va_arg (ap, pid_t);
+ addr = va_arg (ap, void *);
+ data = va_arg (ap, int);
+ va_end (ap);
+ {
+ /* Send a DATA signal to PID, telling it to take the signal
+ normally even if it's traced. */
+ error_t err;
+ task_t task = __pid2task (pid);
+ if (task == MACH_PORT_NULL)
+ return -1;
+ if (data == SIGKILL)
+ err = __task_terminate (task);
+ else
+ {
+ if (addr != (void *) 1)
+ {
+ /* Move the user thread's PC to ADDR. */
+ thread_t thread;
+ err = fetch_user_thread (task, &thread);
+ if (!err)
+ {
+ struct machine_thread_state state;
+ mach_msg_type_number_t count = MACHINE_THREAD_STATE_COUNT;
+ err = __thread_get_state (thread,
+ MACHINE_THREAD_STATE_FLAVOR,
+ (natural_t *) &state, &count);
+ if (!err)
+ {
+ MACHINE_THREAD_STATE_SET_PC (&state, addr);
+ err = __thread_set_state (thread,
+ MACHINE_THREAD_STATE_FLAVOR,
+ (natural_t *) &state, count);
+ }
+
+ }
+ __mach_port_deallocate (__mach_task_self (), thread);
+ }
+ else
+ err = 0;
+
+ if (! err)
+ /* Tell the process to take the signal (or just resume if 0). */
+ err = HURD_MSGPORT_RPC
+ (__USEPORT (PROC, __proc_getmsgport (port, pid, &msgport)),
+ 0, 0, __msg_sig_post_untraced (msgport, data, 0, task));
+ }
+ __mach_port_deallocate (__mach_task_self (), task);
+ return err ? __hurd_fail (err) : 0;
+ }
+
+ case PTRACE_KILL:
+ va_start (ap, request);
+ pid = va_arg (ap, pid_t);
+ va_end (ap);
+ /* SIGKILL always just terminates the task,
+ so normal kill is just the same when traced. */
+ return kill (pid, SIGKILL);
+
+ case PTRACE_SINGLESTEP:
+ /* This is a machine-dependent kernel RPC on
+ machines that support it. Punt. */
+ return EOPNOTSUPP;
+
+ case PTRACE_ATTACH:
+ case PTRACE_DETACH:
+ va_start (ap, request);
+ pid = va_arg (ap, pid_t);
+ va_end (ap);
+ {
+ /* Tell PID to set or clear its trace bit. */
+ error_t err;
+ mach_port_t msgport;
+ task_t task = __pid2task (pid);
+ if (task == MACH_PORT_NULL)
+ return -1;
+ err = __USEPORT (PROC, __proc_getmsgport (port, pid, &msgport));
+ if (! err)
+ {
+ err = __msg_set_init_int (msgport, task, INIT_TRACEMASK,
+ request == PTRACE_DETACH ? 0 :
+ ~(sigset_t) 0);
+ if (! err)
+ {
+ if (request == PTRACE_ATTACH)
+ /* Now stop the process. */
+ err = __msg_sig_post (msgport, SIGSTOP, 0, task);
+ else
+ /* Resume the process from tracing stop. */
+ err = __msg_sig_post_untraced (msgport, 0, 0, task);
+ }
+ __mach_port_deallocate (__mach_task_self (), msgport);
+ }
+ __mach_port_deallocate (__mach_task_self (), task);
+ return err ? __hurd_fail (err) : 0;
+ }
+
+ case PTRACE_PEEKTEXT:
+ case PTRACE_PEEKDATA:
+ va_start (ap, request);
+ pid = va_arg (ap, pid_t);
+ addr = va_arg (ap, void *);
+ va_end (ap);
+ {
+ /* Read the page (or two pages, if the word lies on a boundary)
+ containing the addressed word. */
+ error_t err;
+ vm_address_t ourpage;
+ vm_size_t size;
+ natural_t word;
+ task_t task = __pid2task (pid);
+ if (task == MACH_PORT_NULL)
+ return -1;
+ data = sizeof word;
+ ourpage = 0;
+ size = 0;
+ err = read_data (task, &ourpage, &size);
+ __mach_port_deallocate (__mach_task_self (), task);
+ if (err)
+ return __hurd_fail (err);
+ word = *(natural_t *) ((vm_address_t) addr - trunc_page (addr)
+ + ourpage);
+ __vm_deallocate (__mach_task_self (), ourpage, size);
+ return word;
+ }
+
+ case PTRACE_PEEKUSER:
+ case PTRACE_POKEUSER:
+ /* U area, what's that? */
+ return EOPNOTSUPP;
+
+ case PTRACE_GETREGS:
+ case PTRACE_SETREGS:
+ va_start (ap, request);
+ pid = va_arg (ap, pid_t);
+ addr = va_arg (ap, void *);
+ va_end (ap);
+ return get_regs (MACHINE_THREAD_STATE_FLAVOR,
+ MACHINE_THREAD_STATE_COUNT);
+
+ case PTRACE_GETFPREGS:
+ case PTRACE_SETFPREGS:
+ va_start (ap, request);
+ pid = va_arg (ap, pid_t);
+ addr = va_arg (ap, void *);
+ va_end (ap);
+#ifdef MACHINE_THREAD_FLOAT_STATE_FLAVOR
+ return get_regs (MACHINE_THREAD_FLOAT_STATE_FLAVOR,
+ MACHINE_THREAD_FLOAT_STATE_COUNT);
+#else
+ return EOPNOTSUPP;
+#endif
+
+ case PTRACE_GETFPAREGS:
+ case PTRACE_SETFPAREGS:
+ va_start (ap, request);
+ pid = va_arg (ap, pid_t);
+ addr = va_arg (ap, void *);
+ va_end (ap);
+#ifdef MACHINE_THREAD_FPA_STATE_FLAVOR
+ return get_regs (MACHINE_THREAD_FPA_STATE_FLAVOR,
+ MACHINE_THREAD_FPA_STATE_COUNT);
+#else
+ return EOPNOTSUPP;
+#endif
+
+ case PTRACE_POKETEXT:
+ case PTRACE_POKEDATA:
+ va_start (ap, request);
+ pid = va_arg (ap, pid_t);
+ addr = va_arg (ap, void *);
+ data = va_arg (ap, int);
+ va_end (ap);
+ {
+ /* Read the page (or two pages, if the word lies on a boundary)
+ containing the addressed word. */
+ error_t err;
+ vm_address_t ourpage;
+ vm_size_t size;
+ task_t task = __pid2task (pid);
+ if (task == MACH_PORT_NULL)
+ return -1;
+ data = sizeof (natural_t);
+ ourpage = 0;
+ size = 0;
+ err = read_data (task, &ourpage, &size);
+
+ if (!err)
+ {
+ /* Now modify the specified word and write the page back. */
+ *(natural_t *) ((vm_address_t) addr - trunc_page (addr)
+ + ourpage) = data;
+ err = __vm_write (task, trunc_page (addr), ourpage, size);
+ __vm_deallocate (__mach_task_self (), ourpage, size);
+ }
+
+ __mach_port_deallocate (__mach_task_self (), task);
+ return err ? __hurd_fail (err) : 0;
+ }
+
+ case PTRACE_READDATA:
+ case PTRACE_READTEXT:
+ va_start (ap, request);
+ pid = va_arg (ap, pid_t);
+ addr = va_arg (ap, void *);
+ data = va_arg (ap, int);
+ addr2 = va_arg (ap, void *);
+ va_end (ap);
+ {
+ error_t err;
+ vm_address_t ourpage;
+ vm_size_t size;
+ task_t task = __pid2task (pid);
+ if (task == MACH_PORT_NULL)
+ return -1;
+ if (((vm_address_t) addr2 + data) % __vm_page_size == 0)
+ {
+ /* Perhaps we can write directly to the user's buffer. */
+ ourpage = (vm_address_t) addr2;
+ size = data;
+ }
+ else
+ {
+ ourpage = 0;
+ size = 0;
+ }
+ err = read_data (task, &ourpage, &size);
+ __mach_port_deallocate (__mach_task_self (), task);
+ if (!err && ourpage != (vm_address_t) addr2)
+ {
+ memcpy (addr2, (void *) ourpage, data);
+ __vm_deallocate (__mach_task_self (), ourpage, size);
+ }
+ return err ? __hurd_fail (err) : 0;
+ }
+
+ case PTRACE_WRITEDATA:
+ case PTRACE_WRITETEXT:
+ va_start (ap, request);
+ pid = va_arg (ap, pid_t);
+ addr = va_arg (ap, void *);
+ data = va_arg (ap, int);
+ addr2 = va_arg (ap, void *);
+ va_end (ap);
+ {
+ error_t err;
+ vm_address_t ourpage;
+ vm_size_t size;
+ task_t task = __pid2task (pid);
+ if (task == MACH_PORT_NULL)
+ return -1;
+ if ((vm_address_t) addr % __vm_page_size == 0 &&
+ (vm_address_t) data % __vm_page_size == 0)
+ {
+ /* Writing whole pages; can go directly from the user's buffer. */
+ ourpage = (vm_address_t) addr2;
+ size = data;
+ err = 0;
+ }
+ else
+ {
+ /* Read the task's pages and modify our own copy. */
+ ourpage = 0;
+ size = 0;
+ err = read_data (task, &ourpage, &size);
+ if (!err)
+ memcpy ((void *) ((vm_address_t) addr - trunc_page (addr)
+ + ourpage),
+ addr2,
+ data);
+ }
+ if (!err)
+ /* Write back the modified pages. */
+ err = __vm_write (task, trunc_page (addr), ourpage, size);
+ __mach_port_deallocate (__mach_task_self (), task);
+ return err ? __hurd_fail (err) : 0;
+ }
+
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/ptsname.c b/libc/sysdeps/mach/hurd/ptsname.c
new file mode 100644
index 000000000..b68cd9c2e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/ptsname.c
@@ -0,0 +1,65 @@
+/* ptsname -- return the name of a pty slave given an FD to the pty master
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/term.h>
+
+
+/* Return the pathname of the pseudo terminal slave associated with
+ the master FD is open on, or NULL on errors.
+ The returned storage is good until the next call to this function. */
+char *
+ptsname (int fd)
+{
+ static char peername[1024]; /* XXX */
+ error_t err;
+
+ err = __ptsname_r (fd, peername, sizeof (peername));
+ if (err)
+ __set_errno (err);
+
+ return err ? NULL : peername;
+}
+
+
+/* Store at most BUFLEN characters of the pathname of the slave pseudo
+ terminal associated with the master FD is open on in BUF.
+ Return 0 on success, otherwise an error number. */
+int
+__ptsname_r (int fd, char *buf, size_t buflen)
+{
+ char peername[1024]; /* XXX */
+ size_t len;
+ error_t err;
+
+ peername[0] = '\0';
+ if (err = HURD_DPORT_USE (fd, __term_get_peername (port, peername)))
+ return _hurd_fd_error (fd, err);
+
+ len = strlen (peername) + 1;
+ if (len > buflen)
+ return ERANGE;
+
+ memcpy (buf, peername, len);
+ return 0;
+}
+weak_alias (__ptsname_r, ptsname_r)
diff --git a/libc/sysdeps/mach/hurd/pwrite.c b/libc/sysdeps/mach/hurd/pwrite.c
new file mode 100644
index 000000000..42236e4c3
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/pwrite.c
@@ -0,0 +1,35 @@
+/* Write block at given position in file without changing file pointer.
+ Hurd version.
+ Copyright (C) 1999,2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+/* Write NBYTES of BUF to FD at given position OFFSET without changing
+ the file position. Return the number written, or -1. */
+ssize_t
+__libc_pwrite (int fd, const void *buf, size_t nbytes, off_t offset)
+{
+ return __libc_pwrite64 (fd, buf, nbytes, (off64_t) offset);
+}
+
+#ifndef __libc_pwrite
+strong_alias (__libc_pwrite, __pwrite)
+weak_alias (__libc_pwrite, pwrite)
+#endif
diff --git a/libc/sysdeps/mach/hurd/pwrite64.c b/libc/sysdeps/mach/hurd/pwrite64.c
new file mode 100644
index 000000000..2637003ca
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/pwrite64.c
@@ -0,0 +1,40 @@
+/* Write block to given position in file without changing file pointer.
+ Hurd version.
+ Copyright (C) 2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd/fd.h>
+
+ssize_t
+__libc_pwrite64 (int fd, const void *buf, size_t nbytes, off64_t offset)
+{
+ error_t err;
+ if (offset < 0)
+ err = EINVAL;
+ else
+ err = HURD_FD_USE (fd, _hurd_fd_write (descriptor, buf, &nbytes, offset));
+ return err ? __hurd_dfail (fd, err) : nbytes;
+}
+
+#ifndef __libc_pwrite64
+weak_alias (__libc_pwrite64, __pwrite64)
+libc_hidden_weak (__pwrite64)
+weak_alias (__libc_pwrite64, pwrite64)
+#endif
diff --git a/libc/sysdeps/mach/hurd/read.c b/libc/sysdeps/mach/hurd/read.c
new file mode 100644
index 000000000..d32cb85d7
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/read.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1993,94,95,97,98,99,2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd/fd.h>
+
+/* Read NBYTES into BUF from FD. Return the number read or -1. */
+ssize_t
+__libc_read (int fd, void *buf, size_t nbytes)
+{
+ error_t err = HURD_FD_USE (fd, _hurd_fd_read (descriptor, buf, &nbytes, -1));
+ return err ? __hurd_dfail (fd, err) : nbytes;
+}
+libc_hidden_def (__libc_read)
+weak_alias (__libc_read, __read)
+libc_hidden_weak (__read)
+weak_alias (__libc_read, read)
diff --git a/libc/sysdeps/mach/hurd/readdir.c b/libc/sysdeps/mach/hurd/readdir.c
new file mode 100644
index 000000000..4bf19564d
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/readdir.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 1993,94,95,96,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <endian.h>
+#include <assert.h>
+
+/* Read a directory entry from DIRP. */
+struct dirent *
+__readdir (DIR *dirp)
+{
+ struct dirent64 *entry64 = __readdir64 (dirp);
+
+ if (sizeof (struct dirent64) == sizeof (struct dirent))
+ /* We should in fact just be an alias to readdir64 on this machine. */
+ return (struct dirent *) entry64;
+
+ /* These are all compile-time constants. We know that d_ino is the first
+ member and that the layout of the following members matches exactly in
+ both structures. */
+ assert (offsetof (struct dirent, d_ino) == 0);
+ assert (offsetof (struct dirent64, d_ino) == 0);
+# define MATCH(memb) \
+ assert (offsetof (struct dirent64, memb) - sizeof (entry64->d_ino) \
+ == offsetof (struct dirent, memb) - sizeof (ino_t))
+ MATCH (d_reclen);
+ MATCH (d_type);
+ MATCH (d_namlen);
+# undef MATCH
+
+ if (entry64 == NULL)
+ return NULL;
+
+ struct dirent *const entry = ((void *) (&entry64->d_ino + 1)
+ - sizeof entry->d_ino);
+ const ino_t d_ino = entry64->d_ino;
+ if (d_ino != entry64->d_ino)
+ {
+ __set_errno (EOVERFLOW);
+ return NULL;
+ }
+# if BYTE_ORDER != BIG_ENDIAN /* We just skipped over the zero high word. */
+ entry->d_ino = d_ino; /* ... or the nonzero low word, swap it. */
+# endif
+ entry->d_reclen -= sizeof entry64->d_ino - sizeof entry->d_ino;
+ return entry;
+}
+
+weak_alias (__readdir, readdir)
diff --git a/libc/sysdeps/mach/hurd/readdir64.c b/libc/sysdeps/mach/hurd/readdir64.c
new file mode 100644
index 000000000..1953e81b3
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/readdir64.c
@@ -0,0 +1,102 @@
+/* Copyright (C) 2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dirent.h>
+#include <stddef.h>
+#include <hurd.h>
+#include <hurd/fs.h>
+#include <hurd/fd.h>
+#include "dirstream.h"
+
+/* Read a directory entry from DIRP. */
+struct dirent64 *
+__readdir64 (DIR *dirp)
+{
+ struct dirent64 *dp;
+
+ if (dirp == NULL)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ __libc_lock_lock (dirp->__lock);
+
+ do
+ {
+ if (dirp->__ptr - dirp->__data >= dirp->__size)
+ {
+ /* We've emptied out our buffer. Refill it. */
+
+ char *data = dirp->__data;
+ int nentries;
+ error_t err;
+
+ if (err = HURD_FD_PORT_USE (dirp->__fd,
+ __dir_readdir (port,
+ &data, &dirp->__size,
+ dirp->__entry_ptr,
+ -1, 0, &nentries)))
+ {
+ __hurd_fail (err);
+ dp = NULL;
+ break;
+ }
+
+ /* DATA now corresponds to entry index DIRP->__entry_ptr. */
+ dirp->__entry_data = dirp->__entry_ptr;
+
+ if (data != dirp->__data)
+ {
+ /* The data was passed out of line, so our old buffer is no
+ longer useful. Deallocate the old buffer and reset our
+ information for the new buffer. */
+ __vm_deallocate (__mach_task_self (),
+ (vm_address_t) dirp->__data,
+ dirp->__allocation);
+ dirp->__data = data;
+ dirp->__allocation = round_page (dirp->__size);
+ }
+
+ /* Reset the pointer into the buffer. */
+ dirp->__ptr = dirp->__data;
+
+ if (nentries == 0)
+ {
+ /* End of file. */
+ dp = NULL;
+ break;
+ }
+
+ /* We trust the filesystem to return correct data and so we
+ ignore NENTRIES. */
+ }
+
+ dp = (struct dirent64 *) dirp->__ptr;
+ dirp->__ptr += dp->d_reclen;
+ ++dirp->__entry_ptr;
+
+ /* Loop to ignore deleted files. */
+ } while (dp->d_fileno == 0);
+
+ __libc_lock_unlock (dirp->__lock);
+
+ return dp;
+}
+
+weak_alias (__readdir64, readdir64)
diff --git a/libc/sysdeps/mach/hurd/readdir64_r.c b/libc/sysdeps/mach/hurd/readdir64_r.c
new file mode 100644
index 000000000..5b5a7fe36
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/readdir64_r.c
@@ -0,0 +1,112 @@
+/* Copyright (C) 2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dirent.h>
+#include <stddef.h>
+#include <string.h>
+#include <hurd.h>
+#include <hurd/fs.h>
+#include <hurd/fd.h>
+#include "dirstream.h"
+
+/* Read a directory entry from DIRP. */
+int
+__readdir64_r (DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
+{
+ struct dirent64 *dp;
+ error_t err = 0;
+
+ if (dirp == NULL)
+ {
+ errno = EINVAL;
+ return errno;
+ }
+
+ __libc_lock_lock (dirp->__lock);
+
+ do
+ {
+ if (dirp->__ptr - dirp->__data >= dirp->__size)
+ {
+ /* We've emptied out our buffer. Refill it. */
+
+ char *data = dirp->__data;
+ int nentries;
+
+ if (err = HURD_FD_PORT_USE (dirp->__fd,
+ __dir_readdir (port,
+ &data, &dirp->__size,
+ dirp->__entry_ptr,
+ -1, 0, &nentries)))
+ {
+ __hurd_fail (err);
+ dp = NULL;
+ break;
+ }
+
+ /* DATA now corresponds to entry index DIRP->__entry_ptr. */
+ dirp->__entry_data = dirp->__entry_ptr;
+
+ if (data != dirp->__data)
+ {
+ /* The data was passed out of line, so our old buffer is no
+ longer useful. Deallocate the old buffer and reset our
+ information for the new buffer. */
+ __vm_deallocate (__mach_task_self (),
+ (vm_address_t) dirp->__data,
+ dirp->__allocation);
+ dirp->__data = data;
+ dirp->__allocation = round_page (dirp->__size);
+ }
+
+ /* Reset the pointer into the buffer. */
+ dirp->__ptr = dirp->__data;
+
+ if (nentries == 0)
+ {
+ /* End of file. */
+ dp = NULL;
+ break;
+ }
+
+ /* We trust the filesystem to return correct data and so we
+ ignore NENTRIES. */
+ }
+
+ dp = (struct dirent64 *) dirp->__ptr;
+ dirp->__ptr += dp->d_reclen;
+ ++dirp->__entry_ptr;
+
+ /* Loop to ignore deleted files. */
+ } while (dp->d_fileno == 0);
+
+ if (dp)
+ {
+ *entry = *dp;
+ memcpy (entry->d_name, dp->d_name, dp->d_namlen + 1);
+ *result = entry;
+ }
+ else
+ *result = NULL;
+
+ __libc_lock_unlock (dirp->__lock);
+
+ return dp ? 0 : err ? errno : 0;
+}
+
+weak_alias (__readdir64_r, readdir64_r)
diff --git a/libc/sysdeps/mach/hurd/readdir_r.c b/libc/sysdeps/mach/hurd/readdir_r.c
new file mode 100644
index 000000000..b740721db
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/readdir_r.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1993,94,95,96,97,2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <string.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include "dirstream.h"
+
+
+/* Read a directory entry from DIRP. */
+int
+__readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
+{
+ if (sizeof (struct dirent64) == sizeof (struct dirent))
+ /* We should in fact just be an alias to readdir64_r on this machine. */
+ return __readdir64_r (dirp,
+ (struct dirent64 *) entry,
+ (struct dirent64 **) result);
+
+ struct dirent64 *result64;
+ union
+ {
+ struct dirent64 d;
+ char b[offsetof (struct dirent64, d_name) + UCHAR_MAX + 1];
+ } u;
+ int err;
+
+ err = __readdir64_r (dirp, &u.d, &result64);
+ if (result64)
+ {
+ entry->d_fileno = result64->d_fileno;
+ entry->d_reclen = result64->d_reclen;
+ entry->d_type = result64->d_type;
+ entry->d_namlen = result64->d_namlen;
+ memcpy (entry->d_name, result64->d_name, result64->d_namlen + 1);
+ *result = entry;
+ }
+ else
+ *result = NULL;
+
+ return err;
+}
+
+weak_alias (__readdir_r, readdir_r)
diff --git a/libc/sysdeps/mach/hurd/readlink.c b/libc/sysdeps/mach/hurd/readlink.c
new file mode 100644
index 000000000..f95b6c0b8
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/readlink.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1991,92,93,94,95,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/paths.h>
+#include <fcntl.h>
+#include <string.h>
+
+/* Read the contents of the symbolic link FILE_NAME into no more than
+ LEN bytes of BUF. The contents are not null-terminated.
+ Returns the number of characters read, or -1 for errors. */
+ssize_t
+__readlink (file_name, buf, len)
+ const char *file_name;
+ char *buf;
+ size_t len;
+{
+ error_t err;
+ file_t file;
+ struct stat64 st;
+
+ file = __file_name_lookup (file_name, O_READ | O_NOLINK, 0);
+ if (file == MACH_PORT_NULL)
+ return -1;
+
+ err = __io_stat (file, &st);
+ if (! err)
+ if (S_ISLNK (st.st_mode))
+ {
+ char *rbuf = buf;
+
+ err = __io_read (file, &rbuf, &len, 0, len);
+ if (!err && rbuf != buf)
+ {
+ memcpy (buf, rbuf, len);
+ __vm_deallocate (__mach_task_self (), (vm_address_t)rbuf, len);
+ }
+ }
+ else
+ err = EINVAL;
+
+ __mach_port_deallocate (__mach_task_self (), file);
+
+ if (err)
+ return __hurd_fail (err);
+ else
+ return len;
+}
+weak_alias (__readlink, readlink)
diff --git a/libc/sysdeps/mach/hurd/reboot.c b/libc/sysdeps/mach/hurd/reboot.c
new file mode 100644
index 000000000..2e43e0d11
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/reboot.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 1992,93,94,97,98,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/startup.h>
+#include <sys/reboot.h>
+
+/* Reboot the system. */
+int
+reboot (int howto)
+{
+ error_t err;
+ startup_t init;
+ mach_port_t hostpriv;
+
+ err = __get_privileged_ports (&hostpriv, NULL);
+ if (err)
+ return __hurd_fail (EPERM);
+
+ err = __USEPORT (PROC, __proc_getmsgport (port, 1, &init));
+ if (!err)
+ {
+ err = __startup_reboot (init, hostpriv, howto);
+ __mach_port_deallocate (__mach_task_self (), init);
+ }
+
+ __mach_port_deallocate (__mach_task_self (), hostpriv);
+
+ if (err)
+ return __hurd_fail (err);
+
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/recv.c b/libc/sysdeps/mach/hurd/recv.c
new file mode 100644
index 000000000..b001729d1
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/recv.c
@@ -0,0 +1,64 @@
+/* Copyright (C) 1994,1997,2001,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+#include <string.h>
+
+/* Read N bytes into BUF from socket FD.
+ Returns the number read or -1 for errors. */
+
+ssize_t
+__recv (fd, buf, n, flags)
+ int fd;
+ void *buf;
+ size_t n;
+ int flags;
+{
+ error_t err;
+ mach_port_t addrport;
+ char *bufp = buf;
+ mach_msg_type_number_t nread = n;
+ mach_port_t *ports;
+ mach_msg_type_number_t nports;
+ char *cdata = NULL;
+ mach_msg_type_number_t clen = 0;
+
+ if (err = HURD_DPORT_USE (fd, __socket_recv (port, &addrport,
+ flags, &bufp, &nread,
+ &ports, &nports,
+ &cdata, &clen,
+ &flags,
+ n)))
+ return __hurd_dfail (fd, err);
+
+ __mach_port_deallocate (__mach_task_self (), addrport);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
+
+ if (bufp != buf)
+ {
+ memcpy (buf, bufp, nread);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) bufp, nread);
+ }
+
+ return nread;
+}
+weak_alias (__recv, recv)
diff --git a/libc/sysdeps/mach/hurd/recvfrom.c b/libc/sysdeps/mach/hurd/recvfrom.c
new file mode 100644
index 000000000..d5c73f444
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/recvfrom.c
@@ -0,0 +1,107 @@
+/* Copyright (C) 1994, 1997, 1999, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+
+/* Read N bytes into BUF through socket FD.
+ If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address of
+ the sender, and store the actual size of the address in *ADDR_LEN.
+ Returns the number of bytes read or -1 for errors. */
+ssize_t
+__recvfrom (fd, buf, n, flags, addrarg, addr_len)
+ int fd;
+ void *buf;
+ size_t n;
+ int flags;
+ __SOCKADDR_ARG addrarg;
+ socklen_t *addr_len;
+{
+ error_t err;
+ mach_port_t addrport;
+ char *bufp = buf;
+ mach_msg_type_number_t nread = n;
+ mach_port_t *ports;
+ mach_msg_type_number_t nports;
+ char *cdata = NULL;
+ mach_msg_type_number_t clen = 0;
+ struct sockaddr *addr = addrarg.__sockaddr__;
+
+ if (err = HURD_DPORT_USE (fd, __socket_recv (port, &addrport,
+ flags, &bufp, &nread,
+ &ports, &nports,
+ &cdata, &clen,
+ &flags,
+ n)))
+ return __hurd_dfail (fd, err);
+
+ /* Get address data for the returned address port if requested. */
+ if (addr != NULL)
+ {
+ char *buf = (char *) addr;
+ mach_msg_type_number_t buflen = *addr_len;
+ int type;
+
+ err = __socket_whatis_address (addrport, &type, &buf, &buflen);
+ if (err == EOPNOTSUPP)
+ /* If the protocol server can't tell us the address, just return a
+ zero-length one. */
+ {
+ buf = (char *)addr;
+ buflen = 0;
+ err = 0;
+ }
+
+ if (err)
+ {
+ __mach_port_deallocate (__mach_task_self (), addrport);
+ return __hurd_dfail (fd, err);
+ }
+
+ if (*addr_len > buflen)
+ *addr_len = buflen;
+
+ if (buf != (char *) addr)
+ {
+ memcpy (addr, buf, *addr_len);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+ }
+
+ if (buflen > 0)
+ addr->sa_family = type;
+ }
+
+ __mach_port_deallocate (__mach_task_self (), addrport);
+
+ /* Toss control data; we don't care. */
+ __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
+
+ if (bufp != buf)
+ {
+ memcpy (buf, bufp, nread);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) bufp, nread);
+ }
+
+ return nread;
+}
+
+weak_alias (__recvfrom, recvfrom)
diff --git a/libc/sysdeps/mach/hurd/recvmsg.c b/libc/sysdeps/mach/hurd/recvmsg.c
new file mode 100644
index 000000000..c6874e8bd
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/recvmsg.c
@@ -0,0 +1,145 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+
+/* Receive a message as described by MESSAGE from socket FD.
+ Returns the number of bytes read or -1 for errors. */
+ssize_t
+__libc_recvmsg (int fd, struct msghdr *message, int flags)
+{
+ error_t err;
+ addr_port_t aport;
+ char *data = NULL;
+ mach_msg_type_number_t len = 0;
+ mach_port_t *ports;
+ mach_msg_type_number_t nports;
+ char *cdata = NULL;
+ mach_msg_type_number_t clen = 0;
+ size_t amount;
+ char *buf;
+ int i;
+
+ /* Find the total number of bytes to be read. */
+ amount = 0;
+ for (i = 0; i < message->msg_iovlen; i++)
+ {
+ amount += message->msg_iov[i].iov_len;
+
+ /* As an optimization, we set the initial values of DATA and LEN
+ from the first non-empty iovec. This kicks-in in the case
+ where the whole packet fits into that iovec buffer. */
+ if (data == NULL && message->msg_iov[i].iov_len > 0)
+ {
+ data = message->msg_iov[i].iov_base;
+ len = message->msg_iov[i].iov_len;
+ }
+ }
+
+ buf = data;
+ if (err = HURD_DPORT_USE (fd, __socket_recv (port, &aport,
+ flags, &data, &len,
+ &ports, &nports,
+ &cdata, &clen,
+ &message->msg_flags, amount)))
+ return __hurd_dfail (fd, err);
+
+ if (message->msg_name != NULL)
+ {
+ char *buf = message->msg_name;
+ mach_msg_type_number_t buflen = message->msg_namelen;
+ int type;
+
+ err = __socket_whatis_address (aport, &type, &buf, &buflen);
+ if (err == EOPNOTSUPP)
+ /* If the protocol server can't tell us the address, just return a
+ zero-length one. */
+ {
+ buf = message->msg_name;
+ buflen = 0;
+ err = 0;
+ }
+
+ if (err)
+ {
+ __mach_port_deallocate (__mach_task_self (), aport);
+ return __hurd_dfail (fd, err);
+ }
+
+ if (message->msg_namelen > buflen)
+ message->msg_namelen = buflen;
+
+ if (buf != message->msg_name)
+ {
+ memcpy (message->msg_name, buf, message->msg_namelen);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+ }
+
+ if (buflen > 0)
+ ((struct sockaddr *) message->msg_name)->sa_family = type;
+ }
+
+ __mach_port_deallocate (__mach_task_self (), aport);
+
+ if (buf == data)
+ buf += len;
+ else
+ {
+ /* Copy the data into MSG. */
+ if (len > amount)
+ message->msg_flags |= MSG_TRUNC;
+ else
+ amount = len;
+
+ buf = data;
+ for (i = 0; i < message->msg_iovlen; i++)
+ {
+#define min(a, b) ((a) > (b) ? (b) : (a))
+ size_t copy = min (message->msg_iov[i].iov_len, amount);
+
+ memcpy (message->msg_iov[i].iov_base, buf, copy);
+
+ buf += copy;
+ amount -= copy;
+ if (len == 0)
+ break;
+ }
+
+ __vm_deallocate (__mach_task_self (), (vm_address_t) data, len);
+ }
+
+ /* Copy the control message into MSG. */
+ if (clen > message->msg_controllen)
+ message->msg_flags |= MSG_CTRUNC;
+ else
+ message->msg_controllen = clen;
+ memcpy (message->msg_control, cdata, message->msg_controllen);
+
+ __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
+
+ return (buf - data);
+}
+
+weak_alias (__libc_recvmsg, recvmsg)
+weak_alias (__libc_recvmsg, __recvmsg)
diff --git a/libc/sysdeps/mach/hurd/removexattr.c b/libc/sysdeps/mach/hurd/removexattr.c
new file mode 100644
index 000000000..bbfee3d30
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/removexattr.c
@@ -0,0 +1,35 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+
+ssize_t
+removexattr (const char *path, const char *name)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_remove (port, name);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return __hurd_fail (err);
+}
diff --git a/libc/sysdeps/mach/hurd/rename.c b/libc/sysdeps/mach/hurd/rename.c
new file mode 100644
index 000000000..181c58897
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/rename.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1991,92,93,94,96,97,99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <hurd.h>
+
+/* Rename the file OLD to NEW. */
+int
+rename (old, new)
+ const char *old;
+ const char *new;
+{
+ error_t err;
+ file_t olddir, newdir;
+ const char *oldname, *newname;
+
+ olddir = __directory_name_split (old, (char **) &oldname);
+ if (olddir == MACH_PORT_NULL)
+ return -1;
+ newdir = __directory_name_split (new, (char **) &newname);
+ if (newdir == MACH_PORT_NULL)
+ {
+ __mach_port_deallocate (__mach_task_self (), olddir);
+ return -1;
+ }
+
+ err = __dir_rename (olddir, oldname, newdir, newname, 0);
+ __mach_port_deallocate (__mach_task_self (), olddir);
+ __mach_port_deallocate (__mach_task_self (), newdir);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/revoke.c b/libc/sysdeps/mach/hurd/revoke.c
new file mode 100644
index 000000000..32b3574ee
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/revoke.c
@@ -0,0 +1,40 @@
+/* Revoke the access of all descriptors currently open on a file. Hurd version
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <errno.h>
+#include <hurd.h>
+
+int
+revoke (file_name)
+ const char *file_name;
+{
+ error_t err;
+ file_t file = __file_name_lookup (file_name, 0, 0);
+
+ if (file == MACH_PORT_NULL)
+ return -1;
+
+ err = __io_revoke (file);
+ __mach_port_deallocate (__mach_task_self (), file);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/rewinddir.c b/libc/sysdeps/mach/hurd/rewinddir.c
new file mode 100644
index 000000000..69564536c
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/rewinddir.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/* Rewind DIRP to the beginning of the directory. */
+/* XXX should be __rewinddir ? */
+void
+rewinddir (dirp)
+ DIR *dirp;
+{
+ seekdir (dirp, (off_t) 0L);
+}
diff --git a/libc/sysdeps/mach/hurd/rmdir.c b/libc/sysdeps/mach/hurd/rmdir.c
new file mode 100644
index 000000000..46bdf46ee
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/rmdir.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1991,92,93,94,95,97,99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Remove the directory FILE_NAME. */
+int
+__rmdir (file_name)
+ const char *file_name;
+{
+ error_t err;
+ const char *name;
+ file_t parent = __directory_name_split (file_name, (char **) &name);
+ if (parent == MACH_PORT_NULL)
+ return -1;
+ err = __dir_rmdir (parent, name);
+ __mach_port_deallocate (__mach_task_self (), parent);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__rmdir, rmdir)
diff --git a/libc/sysdeps/mach/hurd/sbrk.c b/libc/sysdeps/mach/hurd/sbrk.c
new file mode 100644
index 000000000..a5ca703a4
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sbrk.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991,94,95,97,98,2000,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <hurd.h>
+#include <unistd.h>
+
+/* Extend the process's data space by INCREMENT.
+ If INCREMENT is negative, shrink data space by - INCREMENT.
+ Return the address of the start of the new data space, or -1 for errors. */
+void *
+__sbrk (intptr_t increment)
+{
+ void *result;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_brk_lock);
+ result = (void *) _hurd_brk;
+ if (increment != 0 && _hurd_set_brk (_hurd_brk + increment) < 0)
+ result = (void *) -1;
+ __mutex_unlock (&_hurd_brk_lock);
+ HURD_CRITICAL_END;
+
+ return result;
+}
+libc_hidden_def (__sbrk)
+weak_alias (__sbrk, sbrk)
diff --git a/libc/sysdeps/mach/hurd/seekdir.c b/libc/sysdeps/mach/hurd/seekdir.c
new file mode 100644
index 000000000..741824a1d
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/seekdir.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1993, 94, 95, 96, 97, 99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <unistd.h>
+#include "dirstream.h"
+
+/* Seek to position POS in DIRP. */
+/* XXX should be __seekdir ? */
+void
+seekdir (dirp, pos)
+ DIR *dirp;
+ long int pos;
+{
+ __libc_lock_lock (dirp->__lock);
+ /* Change our entry index pointer to POS and discard any data already
+ read. The next `readdir' call will notice the empty block and read
+ anew from the location in DIRP->__entry_ptr and reset the other state
+ variables. */
+ dirp->__entry_ptr = pos;
+ dirp->__size = 0;
+ __libc_lock_unlock (dirp->__lock);
+}
diff --git a/libc/sysdeps/mach/hurd/select.c b/libc/sysdeps/mach/hurd/select.c
new file mode 100644
index 000000000..fb85d0cf8
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/select.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,98,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Check the first NFDS descriptors each in READFDS (if not NULL) for read
+ readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
+ (if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out
+ after waiting the interval specified therein. Returns the number of ready
+ descriptors, or -1 for errors. */
+int
+__select (nfds, readfds, writefds, exceptfds, timeout)
+ int nfds;
+ fd_set *readfds;
+ fd_set *writefds;
+ fd_set *exceptfds;
+ struct timeval *timeout;
+{
+ struct timespec ts, *to;
+
+ if (timeout)
+ {
+ to = &ts;
+ TIMEVAL_TO_TIMESPEC (timeout, to);
+ }
+ else
+ to = NULL;
+
+ return _hurd_select (nfds, NULL, readfds, writefds, exceptfds, to, NULL);
+}
+libc_hidden_def (__select)
+weak_alias (__select, select)
diff --git a/libc/sysdeps/mach/hurd/send.c b/libc/sysdeps/mach/hurd/send.c
new file mode 100644
index 000000000..4810cd68c
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/send.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1994,96,97,2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/socket.h>
+#include <hurd/fd.h>
+
+/* Send N bytes of BUF to socket FD. Returns the number sent or -1. */
+ssize_t
+__send (fd, buf, n, flags)
+ int fd;
+ const void *buf;
+ size_t n;
+ int flags;
+{
+ error_t err;
+ size_t wrote;
+
+ err = HURD_DPORT_USE (fd, __socket_send (port, MACH_PORT_NULL,
+ flags, buf, n,
+ NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ NULL, 0, &wrote));
+
+ return err ? __hurd_dfail (fd, err) : wrote;
+}
+libc_hidden_def (__send)
+weak_alias (__send, send)
diff --git a/libc/sysdeps/mach/hurd/sendfile.c b/libc/sysdeps/mach/hurd/sendfile.c
new file mode 100644
index 000000000..683365fc0
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sendfile.c
@@ -0,0 +1,37 @@
+/* sendfile -- copy data directly from one file descriptor to another
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/sendfile.h>
+#include <stddef.h>
+
+/* Send COUNT bytes from file associated with IN_FD starting at OFFSET to
+ descriptor OUT_FD. */
+ssize_t
+sendfile (int out_fd, int in_fd, off_t *offset, size_t count)
+{
+ if (offset == NULL || sizeof (off_t) == sizeof (off64_t))
+ return sendfile64 (out_fd, in_fd, (off64_t *) offset, count);
+ else
+ {
+ off64_t ofs = *offset;
+ ssize_t ret = sendfile64 (out_fd, in_fd, &ofs, count);
+ *offset = ofs;
+ return ret;
+ }
+}
diff --git a/libc/sysdeps/mach/hurd/sendfile64.c b/libc/sysdeps/mach/hurd/sendfile64.c
new file mode 100644
index 000000000..1f63d2a2f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sendfile64.c
@@ -0,0 +1,60 @@
+/* sendfile -- copy data directly from one file descriptor to another
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/sendfile.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <sys/mman.h>
+
+/* Send COUNT bytes from file associated with IN_FD starting at OFFSET to
+ descriptor OUT_FD. */
+ssize_t
+sendfile64 (int out_fd, int in_fd, off64_t *offset, size_t count)
+{
+ /* We just do a vanilla io_read followed by a vanilla io_write here.
+ In theory the IN_FD filesystem can return us out-of-line data that
+ we then send out-of-line to the OUT_FD filesystem and no copying
+ takes place until those pages need to be flushed or packaged by
+ that filesystem (e.g. packetized by a network socket). However,
+ we momentarily consume COUNT bytes of our local address space,
+ which might blow if it's huge or address space is real tight. */
+
+ char *data = 0;
+ size_t datalen = 0;
+ error_t err = HURD_DPORT_USE (in_fd,
+ __io_read (port, &data, &datalen,
+ offset ? *offset : (off_t) -1,
+ count));
+ if (err == 0)
+ {
+ size_t nwrote;
+ if (datalen == 0)
+ return 0;
+ err = HURD_DPORT_USE (out_fd, __io_write (port, data, datalen,
+ (off_t) -1, &nwrote));
+ munmap (data, datalen);
+ if (err == 0)
+ {
+ if (offset)
+ *offset += datalen;
+ return nwrote;
+ }
+ }
+ return __hurd_fail (err);
+}
diff --git a/libc/sysdeps/mach/hurd/sendmsg.c b/libc/sysdeps/mach/hurd/sendmsg.c
new file mode 100644
index 000000000..5fdfd734e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sendmsg.c
@@ -0,0 +1,156 @@
+/* Copyright (C) 2001,2002,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/ifsock.h>
+#include <hurd/socket.h>
+
+/* Send a message described MESSAGE on socket FD.
+ Returns the number of bytes sent, or -1 for errors. */
+ssize_t
+__libc_sendmsg (int fd, const struct msghdr *message, int flags)
+{
+ error_t err = 0;
+ struct sockaddr_un *addr = message->msg_name;
+ socklen_t addr_len = message->msg_namelen;
+ addr_port_t aport = MACH_PORT_NULL;
+ union
+ {
+ char *ptr;
+ vm_address_t addr;
+ } data = { .ptr = NULL };
+ char data_buf[2048];
+ mach_msg_type_number_t len;
+ mach_msg_type_number_t amount;
+ int dealloc = 0;
+ int i;
+
+ /* Find the total number of bytes to be written. */
+ len = 0;
+ for (i = 0; i < message->msg_iovlen; i++)
+ {
+ if (message->msg_iov[i].iov_len > 0)
+ {
+ /* As an optimization, if we only have a single non-empty
+ iovec, we set DATA and LEN from it. */
+ if (len == 0)
+ data.ptr = message->msg_iov[i].iov_base;
+ else
+ data.ptr = NULL;
+
+ len += message->msg_iov[i].iov_len;
+ }
+ }
+
+ if (data.ptr == NULL)
+ {
+ size_t to_copy;
+ char *buf;
+
+ /* Allocate a temporary buffer to hold the data. For small
+ amounts of data, we allocate a buffer on the stack. Larger
+ amounts of data are stored in a page-aligned buffer. The
+ limit of 2048 bytes is inspired by the MiG stubs. */
+ if (len > 2048)
+ {
+ err = __vm_allocate (__mach_task_self (), &data.addr, len, 1);
+ if (err)
+ {
+ __set_errno (err);
+ return -1;
+ }
+ dealloc = 1;
+ }
+ else
+ data.ptr = data_buf;
+
+ /* Copy the data into DATA. */
+ to_copy = len;
+ buf = data.ptr;
+ for (i = 0; i < len; i++)
+ {
+#define min(a, b) ((a) > (b) ? (b) : (a))
+ size_t copy = min (message->msg_iov[i].iov_len, to_copy);
+
+ buf = __mempcpy (buf, message->msg_iov[i].iov_base, copy);
+
+ to_copy -= copy;
+ if (to_copy == 0)
+ break;
+ }
+ }
+
+ if (addr)
+ {
+ if (addr->sun_family == AF_LOCAL)
+ {
+ /* For the local domain, we must look up the name as a file
+ and talk to it with the ifsock protocol. */
+ file_t file = __file_name_lookup (addr->sun_path, 0, 0);
+ if (file == MACH_PORT_NULL)
+ return -1;
+ err = __ifsock_getsockaddr (file, &aport);
+ __mach_port_deallocate (__mach_task_self (), file);
+ if (err == MIG_BAD_ID || err == EOPNOTSUPP)
+ /* The file did not grok the ifsock protocol. */
+ err = ENOTSOCK;
+ if (err)
+ return __hurd_fail (err);
+ }
+ else
+ err = EIEIO;
+ }
+
+ err = HURD_DPORT_USE (fd,
+ ({
+ if (err)
+ err = __socket_create_address (port,
+ addr->sun_family,
+ (char *) addr,
+ addr_len,
+ &aport);
+ if (! err)
+ {
+ /* Send the data. */
+ err = __socket_send (port, aport,
+ flags, data.ptr, len,
+ NULL,
+ MACH_MSG_TYPE_COPY_SEND, 0,
+ message->msg_control,
+ message->msg_controllen,
+ &amount);
+ __mach_port_deallocate (__mach_task_self (),
+ aport);
+ }
+ err;
+ }));
+
+ if (dealloc)
+ __vm_deallocate (__mach_task_self (), data.addr, len);
+
+ return err ? __hurd_dfail (fd, err) : amount;
+}
+
+weak_alias (__libc_sendmsg, sendmsg)
+weak_alias (__libc_sendmsg, __sendmsg)
diff --git a/libc/sysdeps/mach/hurd/sendto.c b/libc/sysdeps/mach/hurd/sendto.c
new file mode 100644
index 000000000..0a6912a3b
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sendto.c
@@ -0,0 +1,85 @@
+/* Copyright (C) 1994,95,96,97,99,2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/ifsock.h>
+#include <hurd/socket.h>
+
+/* Send N bytes of BUF on socket FD to peer at address ADDR (which is
+ ADDR_LEN bytes long). Returns the number sent, or -1 for errors. */
+ssize_t
+__sendto (int fd,
+ const void *buf,
+ size_t n,
+ int flags,
+ const struct sockaddr_un *addr,
+ socklen_t addr_len)
+{
+ addr_port_t aport;
+ error_t err;
+ size_t wrote;
+
+ if (addr->sun_family == AF_LOCAL)
+ {
+ /* For the local domain, we must look up the name as a file and talk
+ to it with the ifsock protocol. */
+ file_t file = __file_name_lookup (addr->sun_path, 0, 0);
+ if (file == MACH_PORT_NULL)
+ return -1;
+ err = __ifsock_getsockaddr (file, &aport);
+ __mach_port_deallocate (__mach_task_self (), file);
+ if (err == MIG_BAD_ID || err == EOPNOTSUPP)
+ /* The file did not grok the ifsock protocol. */
+ err = ENOTSOCK;
+ if (err)
+ return __hurd_fail (err);
+ }
+ else
+ err = EIEIO;
+
+ /* Get an address port for the desired destination address. */
+ err = HURD_DPORT_USE (fd,
+ ({
+ if (err)
+ err = __socket_create_address (port,
+ addr->sun_family,
+ (char *) addr,
+ addr_len,
+ &aport);
+ if (! err)
+ {
+ /* Send the data. */
+ err = __socket_send (port, aport,
+ flags, buf, n,
+ NULL,
+ MACH_MSG_TYPE_COPY_SEND, 0,
+ NULL, 0, &wrote);
+ __mach_port_deallocate (__mach_task_self (),
+ aport);
+ }
+ err;
+ }));
+
+ return err ? __hurd_dfail (fd, err) : wrote;
+}
+
+weak_alias (__sendto, sendto)
diff --git a/libc/sysdeps/mach/hurd/setdomain.c b/libc/sysdeps/mach/hurd/setdomain.c
new file mode 100644
index 000000000..5bff21d99
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setdomain.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include "hurdhost.h"
+
+/* Set the name of the current YP domain to NAME, which is LEN bytes long.
+ This call is restricted to the super-user. */
+int
+setdomainname (name, len)
+ const char *name;
+ size_t len;
+{
+ /* The NIS domain name is just the contents of the file /etc/nisdomain. */
+ ssize_t n = _hurd_set_host_config ("/etc/nisdomain", name, len);
+ return n < 0 ? -1 : 0;
+}
diff --git a/libc/sysdeps/mach/hurd/setegid.c b/libc/sysdeps/mach/hurd/setegid.c
new file mode 100644
index 000000000..c84b8e2e1
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setegid.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <sys/types.h>
+#include <hurd/id.h>
+#include <string.h>
+
+/* Set the effective user ID of the calling process to GID. */
+int
+setegid (gid)
+ gid_t gid;
+{
+ auth_t newauth;
+ error_t err;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+ err = _hurd_check_ids ();
+
+ if (!err)
+ {
+ /* Make a new auth handle which has EGID as the first element in the
+ list of effective gids. */
+
+ if (_hurd_id.gen.ngids > 0)
+ {
+ _hurd_id.gen.gids[0] = gid;
+ _hurd_id.valid = 0;
+ }
+
+ err = __USEPORT (AUTH, __auth_makeauth
+ (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ _hurd_id.gen.uids, _hurd_id.gen.nuids,
+ _hurd_id.aux.uids, _hurd_id.aux.nuids,
+ _hurd_id.gen.ngids ? _hurd_id.gen.gids : &gid,
+ _hurd_id.gen.ngids ?: 1,
+ _hurd_id.aux.gids, _hurd_id.aux.ngids,
+ &newauth));
+ }
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ /* Install the new handle and reauthenticate everything. */
+ err = __setauth (newauth);
+ __mach_port_deallocate (__mach_task_self (), newauth);
+ return err;
+}
+libc_hidden_def (setegid)
diff --git a/libc/sysdeps/mach/hurd/seteuid.c b/libc/sysdeps/mach/hurd/seteuid.c
new file mode 100644
index 000000000..8a6effef8
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/seteuid.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <sys/types.h>
+#include <hurd/id.h>
+#include <string.h>
+
+/* Set the effective user ID of the calling process to UID. */
+int
+seteuid (uid)
+ uid_t uid;
+{
+ auth_t newauth;
+ error_t err;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+ err = _hurd_check_ids ();
+
+ if (!err)
+ {
+ /* Make a new auth handle which has EUID as the first element in the
+ list of effective uids. */
+
+ if (_hurd_id.gen.nuids > 0)
+ {
+ _hurd_id.gen.uids[0] = uid;
+ _hurd_id.valid = 0;
+ }
+
+ err = __USEPORT (AUTH, __auth_makeauth
+ (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ _hurd_id.gen.nuids ? _hurd_id.gen.uids : &uid,
+ _hurd_id.gen.nuids ?: 1,
+ _hurd_id.aux.uids, _hurd_id.aux.nuids,
+ _hurd_id.gen.gids, _hurd_id.gen.ngids,
+ _hurd_id.aux.gids, _hurd_id.aux.ngids,
+ &newauth));
+ }
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ /* Install the new handle and reauthenticate everything. */
+ err = __setauth (newauth);
+ __mach_port_deallocate (__mach_task_self (), newauth);
+ return err;
+}
+libc_hidden_def (seteuid)
diff --git a/libc/sysdeps/mach/hurd/setgid.c b/libc/sysdeps/mach/hurd/setgid.c
new file mode 100644
index 000000000..a7f3dda7d
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setgid.c
@@ -0,0 +1,96 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/id.h>
+#include <string.h>
+
+/* Set the group ID of the calling process to UID.
+ If the calling process is the super-user, the real
+ and effective group IDs, and the saved set-group-ID to UID;
+ if not, the effective group ID is set to GID. */
+int
+__setgid (gid)
+ gid_t gid;
+{
+ auth_t newauth;
+ error_t err;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+ err = _hurd_check_ids ();
+
+ if (!err)
+ {
+ /* Make a new auth handle which has GID as the real gid,
+ and as the first element in the list of effective gids. */
+
+ gid_t *newgen, *newaux, auxbuf[2];
+ size_t ngen, naux;
+
+ if (_hurd_id.gen.ngids == 0)
+ {
+ /* No effective gids now. The new set will be just GID. */
+ newgen = &gid;
+ ngen = 1;
+ }
+ else
+ {
+ _hurd_id.gen.gids[0] = gid;
+ _hurd_id.valid = 0;
+ newgen = _hurd_id.gen.gids;
+ ngen = _hurd_id.gen.ngids;
+ }
+
+ newaux = _hurd_id.aux.gids;
+ naux = _hurd_id.aux.ngids;
+ if (_hurd_id.gen.nuids > 0 && _hurd_id.gen.uids[0] == 0)
+ {
+ /* We are root; set the real and saved IDs too. */
+ _hurd_id.valid = 0;
+ if (_hurd_id.aux.ngids < 2)
+ {
+ newaux = auxbuf;
+ naux = 2;
+ }
+ newaux[0] = newaux[1] = gid;
+ }
+
+ err = __USEPORT (AUTH, __auth_makeauth
+ (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ _hurd_id.gen.uids, _hurd_id.gen.nuids,
+ _hurd_id.aux.uids, _hurd_id.aux.nuids,
+ newgen, ngen, newaux, naux,
+ &newauth));
+ }
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ /* Install the new handle and reauthenticate everything. */
+ err = __setauth (newauth);
+ __mach_port_deallocate (__mach_task_self (), newauth);
+ return err;
+}
+
+weak_alias (__setgid, setgid)
diff --git a/libc/sysdeps/mach/hurd/setgroups.c b/libc/sysdeps/mach/hurd/setgroups.c
new file mode 100644
index 000000000..d0bd63442
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setgroups.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1993,94,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <grp.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Set the group set for the current user to GROUPS (N of them). */
+int
+setgroups (n, groups)
+ size_t n;
+ const gid_t *groups;
+{
+ error_t err;
+ auth_t newauth;
+ size_t i;
+ gid_t new[n];
+
+ /* Fault before taking locks. */
+ for (i = 0; i < n; ++i)
+ new[i] = groups[i];
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+ err = _hurd_check_ids ();
+ if (! err)
+ {
+ /* Get a new auth port using those IDs. */
+ err = __USEPORT (AUTH,
+ __auth_makeauth (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ _hurd_id.gen.uids, _hurd_id.gen.nuids,
+ _hurd_id.aux.uids, _hurd_id.aux.nuids,
+ new, n,
+ _hurd_id.aux.gids, _hurd_id.aux.ngids,
+ &newauth));
+ }
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ /* Install the new auth port and reauthenticate everything. */
+ err = __setauth (newauth);
+ __mach_port_deallocate (__mach_task_self (), newauth);
+ return err;
+}
+libc_hidden_def (setgroups)
diff --git a/libc/sysdeps/mach/hurd/sethostid.c b/libc/sysdeps/mach/hurd/sethostid.c
new file mode 100644
index 000000000..5d720ca55
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sethostid.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include "hurdhost.h"
+#include <stdio-common/_itoa.h>
+
+/* Set the current machine's Internet number to ID.
+ This call is restricted to the super-user. */
+/* XXX should be __sethostid?
+ isn't hostid supposed to be hardwired and unchangeable? */
+int
+sethostid (id)
+ long int id;
+{
+ char buf[8], *bp;
+ ssize_t n;
+
+ /* The hostid is kept in the file /etc/hostid,
+ eight characters of upper-case hexadecimal. */
+
+ bp = _itoa_word (id, &buf[sizeof buf], 16, 1);
+ while (bp > buf)
+ *--bp = '0';
+
+ n = _hurd_set_host_config ("/etc/hostid", buf, sizeof buf);
+ return n < 0 ? -1 : 0;
+}
diff --git a/libc/sysdeps/mach/hurd/sethostname.c b/libc/sysdeps/mach/hurd/sethostname.c
new file mode 100644
index 000000000..564d600ef
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sethostname.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991, 92, 93, 94, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include "hurdhost.h"
+
+/* Set the name of the current host to NAME, which is LEN bytes long.
+ This call is restricted to the super-user. */
+/* XXX should be __sethostname ? */
+int
+sethostname (name, len)
+ const char *name;
+ size_t len;
+{
+ /* The host name is just the contents of the file /etc/hostname. */
+ ssize_t n = _hurd_set_host_config ("/etc/hostname", name, len);
+ return n < 0 ? -1 : 0;
+}
diff --git a/libc/sysdeps/mach/hurd/setitimer.c b/libc/sysdeps/mach/hurd/setitimer.c
new file mode 100644
index 000000000..fec64a8cb
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setitimer.c
@@ -0,0 +1,374 @@
+/* Copyright (C) 1994,1995,1996,1997,2000,2001,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <time.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/sigpreempt.h>
+#include <hurd/msg_request.h>
+#include <mach/message.h>
+
+/* XXX Temporary cheezoid implementation of ITIMER_REAL/SIGALRM. */
+
+spin_lock_t _hurd_itimer_lock = SPIN_LOCK_INITIALIZER;
+struct itimerval _hurd_itimerval; /* Current state of the timer. */
+mach_port_t _hurd_itimer_port; /* Port the timer thread blocks on. */
+thread_t _hurd_itimer_thread; /* Thread waiting for timeout. */
+int _hurd_itimer_thread_suspended; /* Nonzero if that thread is suspended. */
+vm_address_t _hurd_itimer_thread_stack_base; /* Base of its stack. */
+vm_address_t _hurd_itimer_thread_stack_size; /* Size of its stack. */
+struct timeval _hurd_itimer_started; /* Time the thread started waiting. */
+
+static void
+quantize_timeval (struct timeval *tv)
+{
+ static time_t quantum = -1;
+
+ if (quantum == -1)
+ quantum = 1000000 / __getclktck ();
+
+ tv->tv_usec = ((tv->tv_usec + (quantum - 1)) / quantum) * quantum;
+ if (tv->tv_usec >= 1000000)
+ {
+ ++tv->tv_sec;
+ tv->tv_usec -= 1000000;
+ }
+}
+
+static inline void
+subtract_timeval (struct timeval *from, const struct timeval *subtract)
+{
+ from->tv_usec -= subtract->tv_usec;
+ from->tv_sec -= subtract->tv_sec;
+ while (from->tv_usec < 0)
+ {
+ --from->tv_sec;
+ from->tv_usec += 1000000;
+ }
+}
+
+/* Function run by the itimer thread.
+ This code must be very careful not ever to require a MiG reply port. */
+
+static void
+timer_thread (void)
+{
+ while (1)
+ {
+ error_t err;
+ /* The only message we ever expect to receive is the reply from the
+ signal thread to a sig_post call we did. We never examine the
+ contents. */
+ struct
+ {
+ mach_msg_header_t header;
+ error_t return_code;
+ } msg;
+
+ /* Wait for a message on a port that noone sends to. The purpose is
+ the receive timeout. Notice interrupts so that if we are
+ thread_abort'd, we will loop around and fetch new values from
+ _hurd_itimerval. */
+ err = __mach_msg (&msg.header,
+ MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
+ 0, 0, _hurd_itimer_port,
+ _hurd_itimerval.it_value.tv_sec * 1000 +
+ _hurd_itimerval.it_value.tv_usec / 1000,
+ MACH_PORT_NULL);
+ switch (err)
+ {
+ case MACH_RCV_TIMED_OUT:
+ /* We got the expected timeout. Send a message to the signal
+ thread to tell it to post a SIGALRM signal. We use
+ _hurd_itimer_port as the reply port just so we will block until
+ the signal thread has frobnicated things to reload the itimer or
+ has terminated this thread. */
+ __msg_sig_post_request (_hurd_msgport,
+ _hurd_itimer_port,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ SIGALRM, 0, __mach_task_self ());
+ break;
+
+ case MACH_RCV_INTERRUPTED:
+ /* We were thread_abort'd. This is to tell us that
+ _hurd_itimerval has changed and we need to reexamine it
+ and start waiting with the new timeout value. */
+ break;
+
+ case MACH_MSG_SUCCESS:
+ /* We got the reply message from the sig_post_request above.
+ Ignore it and reexamine the timer value. */
+ __mach_msg_destroy (&msg.header); /* Just in case. */
+ break;
+
+ default:
+ /* Unexpected lossage. Oh well, keep trying. */
+ break;
+ }
+ }
+}
+
+
+/* Forward declaration. */
+static int setitimer_locked (const struct itimerval *new,
+ struct itimerval *old, void *crit);
+
+static sighandler_t
+restart_itimer (struct hurd_signal_preemptor *preemptor,
+ struct hurd_sigstate *ss,
+ int *signo, struct hurd_signal_detail *detail)
+{
+ /* This function gets called in the signal thread
+ each time a SIGALRM is arriving (even if blocked). */
+ struct itimerval it;
+
+ /* Either reload or disable the itimer. */
+ __spin_lock (&_hurd_itimer_lock);
+ it.it_value = it.it_interval = _hurd_itimerval.it_interval;
+ setitimer_locked (&it, NULL, NULL);
+
+ /* Continue with normal delivery (or hold, etc.) of SIGALRM. */
+ return SIG_ERR;
+}
+
+
+/* Called before any normal SIGALRM signal is delivered.
+ Reload the itimer, or disable the itimer. */
+
+static int
+setitimer_locked (const struct itimerval *new, struct itimerval *old,
+ void *crit)
+{
+ struct itimerval newval;
+ struct timeval now, remaining, elapsed;
+ struct timeval old_interval;
+ error_t err;
+
+ inline void kill_itimer_thread (void)
+ {
+ __thread_terminate (_hurd_itimer_thread);
+ __vm_deallocate (__mach_task_self (),
+ _hurd_itimer_thread_stack_base,
+ _hurd_itimer_thread_stack_size);
+ _hurd_itimer_thread = MACH_PORT_NULL;
+ }
+
+ if (!new)
+ {
+ /* Just return the current value in OLD without changing anything.
+ This is what BSD does, even though it's not documented. */
+ if (old)
+ *old = _hurd_itimerval;
+ spin_unlock (&_hurd_itimer_lock);
+ _hurd_critical_section_unlock (crit);
+ return 0;
+ }
+
+ newval = *new;
+ quantize_timeval (&newval.it_interval);
+ quantize_timeval (&newval.it_value);
+ if ((newval.it_value.tv_sec | newval.it_value.tv_usec) != 0)
+ {
+ /* Make sure the itimer thread is set up. */
+
+ /* Set up a signal preemptor global for all threads to
+ run `restart_itimer' each time a SIGALRM would arrive. */
+ static struct hurd_signal_preemptor preemptor =
+ {
+ __sigmask (SIGALRM), 0, 0,
+ &restart_itimer,
+ };
+ __mutex_lock (&_hurd_siglock);
+ if (! preemptor.next && _hurdsig_preemptors != &preemptor)
+ {
+ preemptor.next = _hurdsig_preemptors;
+ _hurdsig_preemptors = &preemptor;
+ }
+ __mutex_unlock (&_hurd_siglock);
+
+ if (_hurd_itimer_port == MACH_PORT_NULL)
+ {
+ /* Allocate a receive right that the itimer thread will
+ block waiting for a message on. */
+ if (err = __mach_port_allocate (__mach_task_self (),
+ MACH_PORT_RIGHT_RECEIVE,
+ &_hurd_itimer_port))
+ goto out;
+ }
+
+ if (_hurd_itimer_thread == MACH_PORT_NULL)
+ {
+ /* Start up the itimer thread running `timer_thread' (below). */
+ if (err = __thread_create (__mach_task_self (),
+ &_hurd_itimer_thread))
+ return __hurd_fail (err);
+ _hurd_itimer_thread_stack_base = 0; /* Anywhere. */
+ _hurd_itimer_thread_stack_size = __vm_page_size; /* Small stack. */
+ if (err = __mach_setup_thread (__mach_task_self (),
+ _hurd_itimer_thread,
+ &timer_thread,
+ &_hurd_itimer_thread_stack_base,
+ &_hurd_itimer_thread_stack_size))
+ {
+ __thread_terminate (_hurd_itimer_thread);
+ _hurd_itimer_thread = MACH_PORT_NULL;
+ goto out;
+ }
+ _hurd_itimer_thread_suspended = 1;
+ }
+ }
+
+ if ((newval.it_value.tv_sec | newval.it_value.tv_usec) != 0 || old != NULL)
+ {
+ /* Calculate how much time is remaining for the pending alarm. */
+ if (__gettimeofday (&now, NULL) < 0)
+ {
+ __spin_unlock (&_hurd_itimer_lock);
+ _hurd_critical_section_unlock (crit);
+ return -1;
+ }
+ elapsed = now;
+ subtract_timeval (&elapsed, &_hurd_itimer_started);
+ remaining = _hurd_itimerval.it_value;
+ if (timercmp (&remaining, &elapsed, <))
+ {
+ /* Hmm. The timer should have just gone off, but has not been reset.
+ This is a possible timing glitch. The alarm will signal soon. */
+ /* XXX wrong */
+ remaining.tv_sec = 0;
+ remaining.tv_usec = 0;
+ }
+ else
+ subtract_timeval (&remaining, &elapsed);
+
+ /* Remember the old reload interval before changing it. */
+ old_interval = _hurd_itimerval.it_interval;
+
+ /* Record the starting time that the timer interval relates to. */
+ _hurd_itimer_started = now;
+ }
+
+ /* Load the new itimer value. */
+ _hurd_itimerval = newval;
+
+ if ((newval.it_value.tv_sec | newval.it_value.tv_usec) == 0)
+ {
+ /* Disable the itimer. */
+ if (_hurd_itimer_thread && !_hurd_itimer_thread_suspended)
+ {
+ /* Suspend the itimer thread so it does nothing. Then abort its
+ kernel context so that when the thread is resumed, mach_msg
+ will return to timer_thread (below) and it will fetch new
+ values from _hurd_itimerval. */
+ if ((err = __thread_suspend (_hurd_itimer_thread)) ||
+ (err = __thread_abort (_hurd_itimer_thread)))
+ /* If we can't save it for later, nuke it. */
+ kill_itimer_thread ();
+ else
+ _hurd_itimer_thread_suspended = 1;
+ }
+ }
+ /* See if the timeout changed. If so, we must alert the itimer thread. */
+ else if (remaining.tv_sec != newval.it_value.tv_sec ||
+ remaining.tv_usec != newval.it_value.tv_usec)
+ {
+ /* The timeout value is changing. Tell the itimer thread to
+ reexamine it and start counting down. If the itimer thread is
+ marked as suspended, either we just created it, or it was
+ suspended and thread_abort'd last time the itimer was disabled;
+ either way it will wake up and start waiting for the new timeout
+ value when we resume it. If it is not suspended, the itimer
+ thread is waiting to deliver a pending alarm that we will override
+ (since it would come later than the new alarm being set);
+ thread_abort will make mach_msg return MACH_RCV_INTERRUPTED, so it
+ will loop around and use the new timeout value. */
+ if (err = (_hurd_itimer_thread_suspended
+ ? __thread_resume : __thread_abort) (_hurd_itimer_thread))
+ {
+ kill_itimer_thread ();
+ goto out;
+ }
+ _hurd_itimer_thread_suspended = 0;
+ }
+
+ __spin_unlock (&_hurd_itimer_lock);
+ _hurd_critical_section_unlock (crit);
+
+ if (old != NULL)
+ {
+ old->it_value = remaining;
+ old->it_interval = old_interval;
+ }
+ return 0;
+
+ out:
+ __spin_unlock (&_hurd_itimer_lock);
+ _hurd_critical_section_unlock (crit);
+ return __hurd_fail (err);
+}
+
+/* Set the timer WHICH to *NEW. If OLD is not NULL,
+ set *OLD to the old value of timer WHICH.
+ Returns 0 on success, -1 on errors. */
+int
+__setitimer (enum __itimer_which which, const struct itimerval *new,
+ struct itimerval *old)
+{
+ void *crit;
+
+ switch (which)
+ {
+ default:
+ return __hurd_fail (EINVAL);
+
+ case ITIMER_VIRTUAL:
+ case ITIMER_PROF:
+ return __hurd_fail (ENOSYS);
+
+ case ITIMER_REAL:
+ break;
+ }
+
+ crit = _hurd_critical_section_lock ();
+ __spin_lock (&_hurd_itimer_lock);
+ return setitimer_locked (new, old, crit);
+}
+
+static void
+fork_itimer (void)
+{
+ /* We must restart the itimer in the child. */
+
+ struct itimerval it;
+
+ __spin_lock (&_hurd_itimer_lock);
+ _hurd_itimer_thread = MACH_PORT_NULL;
+ it = _hurd_itimerval;
+ it.it_value = it.it_interval;
+
+ setitimer_locked (&it, NULL, NULL);
+
+ (void) &fork_itimer; /* Avoid gcc optimizing out the function. */
+}
+text_set_element (_hurd_fork_child_hook, fork_itimer);
+
+weak_alias (__setitimer, setitimer)
diff --git a/libc/sysdeps/mach/hurd/setlogin.c b/libc/sysdeps/mach/hurd/setlogin.c
new file mode 100644
index 000000000..2cd438254
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setlogin.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Set the login name returned by `getlogin'. */
+int
+setlogin (name)
+ const char *name;
+{
+ error_t err;
+ if (err = __USEPORT (PROC, __proc_setlogin (port, name)))
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/setpgid.c b/libc/sysdeps/mach/hurd/setpgid.c
new file mode 100644
index 000000000..27b15b228
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setpgid.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1993,1994,1995,1996,1997,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+
+/* Set the process group ID of the process matching PID to PGID.
+ If PID is zero, the current process's process group ID is set.
+ If PGID is zero, the process ID of the process is used. */
+int
+__setpgid (pid, pgid)
+ pid_t pid;
+ pid_t pgid;
+{
+ error_t err;
+ unsigned int stamp;
+
+ stamp = _hurd_pids_changed_stamp; /* Atomic fetch. */
+
+ if (err = __USEPORT (PROC, __proc_setpgrp (port, pid, pgid)))
+ return __hurd_fail (err);
+
+ if (pid == 0 || pid == _hurd_pid)
+ /* Synchronize with the signal thread to make sure we have
+ received and processed proc_newids before returning to the user. */
+ while (_hurd_pids_changed_stamp == stamp)
+ {
+#ifdef noteven
+ /* XXX we have no need for a mutex, but cthreads demands one. */
+ __condition_wait (&_hurd_pids_changed_sync, NULL);
+#else
+ __swtch_pri(0);
+#endif
+ }
+
+ return 0;
+
+}
+libc_hidden_def (__setpgid)
+weak_alias (__setpgid, setpgid)
diff --git a/libc/sysdeps/mach/hurd/setpriority.c b/libc/sysdeps/mach/hurd/setpriority.c
new file mode 100644
index 000000000..bf739aa09
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setpriority.c
@@ -0,0 +1,98 @@
+/* Copyright (C) 1994,95,97,2000,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hurd.h>
+#include <hurd/resource.h>
+
+/* Set the priority of all processes specified by WHICH and WHO
+ to PRIO. Returns 0 on success, -1 on errors. */
+int
+setpriority (enum __priority_which which, id_t who, int prio)
+{
+ error_t err;
+ error_t pidloser, priloser;
+ unsigned int npids, ntasks, nwin, nperm, nacces;
+
+ error_t setonepriority (pid_t pid, struct procinfo *pi)
+ {
+ task_t task;
+ error_t piderr = __USEPORT (PROC, __proc_pid2task (port, pid, &task));
+ if (piderr == EPERM)
+ ++nperm;
+ if (piderr != ESRCH)
+ {
+ ++npids;
+ if (piderr && piderr != EPERM)
+ pidloser = piderr;
+ }
+ if (! piderr)
+ {
+ error_t prierr;
+ ++ntasks;
+#ifdef POLICY_TIMESHARE_BASE_COUNT
+ {
+ /* XXX This assumes timeshare policy. */
+ struct policy_timeshare_base base
+ = { NICE_TO_MACH_PRIORITY (prio) };
+ prierr = __task_policy (task, POLICY_TIMESHARE,
+ (policy_base_t) &base,
+ POLICY_TIMESHARE_BASE_COUNT,
+ 0, 1);
+ }
+#else
+ prierr = __task_priority (task, NICE_TO_MACH_PRIORITY (prio), 1);
+#endif
+ __mach_port_deallocate (__mach_task_self (), task);
+ switch (prierr)
+ {
+ case KERN_FAILURE:
+ ++nacces;
+ break;
+ case KERN_SUCCESS:
+ ++nwin;
+ break;
+ case KERN_INVALID_ARGUMENT: /* Task died. */
+ --npids;
+ --ntasks;
+ break;
+ default:
+ priloser = prierr;
+ }
+ }
+ return 0;
+ }
+
+ npids = ntasks = nwin = nperm = nacces = 0;
+ pidloser = priloser = 0;
+ err = _hurd_priority_which_map (which, who, setonepriority, 0);
+
+ if (!err && npids == 0)
+ /* No error, but no pids found. */
+ err = ESRCH;
+ else if (nperm == npids)
+ /* Got EPERM from proc_task2pid for every process. */
+ err = EPERM;
+ else if (nacces == ntasks)
+ /* Got KERN_FAILURE from task_priority for every task. */
+ err = EACCES;
+ else if (nwin == 0)
+ err = pidloser ?: priloser;
+
+ return err ? __hurd_fail (err) : 0;
+}
+libc_hidden_def (setpriority)
diff --git a/libc/sysdeps/mach/hurd/setregid.c b/libc/sysdeps/mach/hurd/setregid.c
new file mode 100644
index 000000000..84d09cc61
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setregid.c
@@ -0,0 +1,98 @@
+/* Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+#include <string.h>
+
+int
+__setregid (rgid, egid)
+ gid_t rgid;
+ gid_t egid;
+{
+ auth_t newauth;
+ error_t err;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+ err = _hurd_check_ids ();
+
+ if (!err)
+ {
+ /* Make a new auth handle which has RGID as the real gid,
+ and EGID as the first element in the list of effective gids. */
+
+ gid_t *newgen, *newaux;
+ size_t ngen, naux;
+
+ newgen = _hurd_id.gen.gids;
+ ngen = _hurd_id.gen.ngids;
+ if (egid != -1)
+ {
+ if (_hurd_id.gen.ngids == 0)
+ {
+ /* No effective gids now. The new set will be just GID. */
+ newgen = &egid;
+ ngen = 1;
+ }
+ else
+ {
+ _hurd_id.gen.gids[0] = egid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ newaux = _hurd_id.aux.gids;
+ naux = _hurd_id.aux.ngids;
+ if (rgid != -1)
+ {
+ if (_hurd_id.aux.ngids == 0)
+ {
+ newaux = &rgid;
+ naux = 1;
+ }
+ else
+ {
+ _hurd_id.aux.gids[0] = rgid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ err = __USEPORT (AUTH, __auth_makeauth
+ (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ _hurd_id.gen.uids, _hurd_id.gen.nuids,
+ _hurd_id.aux.uids, _hurd_id.aux.nuids,
+ newgen, ngen, newaux, naux,
+ &newauth));
+ }
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ /* Install the new handle and reauthenticate everything. */
+ err = __setauth (newauth);
+ __mach_port_deallocate (__mach_task_self (), newauth);
+ return err;
+}
+
+weak_alias (__setregid, setregid)
diff --git a/libc/sysdeps/mach/hurd/setresgid.c b/libc/sysdeps/mach/hurd/setresgid.c
new file mode 100644
index 000000000..8fcf26eaf
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setresgid.c
@@ -0,0 +1,78 @@
+/* setresgid -- set real group ID, effective group ID, and saved-set group ID
+ Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Set the real group ID, effective group ID, and saved-set group ID,
+ of the calling process to RGID, EGID, and SGID, respectively. */
+int
+__setresgid (gid_t rgid, gid_t egid, gid_t sgid)
+{
+ auth_t newauth;
+ error_t err;
+ gid_t agids[2] = { rgid, sgid };
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+ err = _hurd_check_ids ();
+
+ if (!err)
+ {
+ /* Make a new auth handle which has EGID as the first element in the
+ list of effective gids. */
+
+ if (_hurd_id.gen.ngids > 0)
+ {
+ _hurd_id.gen.gids[0] = egid;
+ _hurd_id.valid = 0;
+ }
+ if (_hurd_id.aux.ngids > 1)
+ {
+ _hurd_id.aux.gids[0] = rgid;
+ _hurd_id.aux.gids[1] = sgid;
+ _hurd_id.valid = 0;
+ }
+
+ err = __USEPORT (AUTH, __auth_makeauth
+ (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ _hurd_id.gen.uids, _hurd_id.gen.nuids,
+ _hurd_id.aux.uids, _hurd_id.aux.nuids,
+ _hurd_id.gen.ngids ? _hurd_id.gen.gids : &egid,
+ _hurd_id.gen.ngids ?: 1,
+ _hurd_id.aux.ngids > 1 ? _hurd_id.aux.gids : agids,
+ _hurd_id.aux.ngids > 1 ? _hurd_id.aux.ngids : 2,
+ &newauth));
+ }
+
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ /* Install the new handle and reauthenticate everything. */
+ err = __setauth (newauth);
+ __mach_port_deallocate (__mach_task_self (), newauth);
+ return err;
+}
+libc_hidden_def (__setresgid)
+weak_alias (__setresgid, setresgid)
diff --git a/libc/sysdeps/mach/hurd/setresuid.c b/libc/sysdeps/mach/hurd/setresuid.c
new file mode 100644
index 000000000..ccf8d08d4
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setresuid.c
@@ -0,0 +1,78 @@
+/* setresuid -- set real user ID, effective user ID, and saved-set user ID
+ Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Set the real user ID, effective user ID, and saved-set user ID,
+ of the calling process to RUID, EUID, and SUID, respectively. */
+int
+__setresuid (uid_t ruid, uid_t euid, uid_t suid)
+{
+ auth_t newauth;
+ error_t err;
+ uid_t auids[2] = { ruid, suid };
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+ err = _hurd_check_ids ();
+
+ if (!err)
+ {
+ /* Make a new auth handle which has EUID as the first element in the
+ list of effective uids. */
+
+ if (_hurd_id.gen.nuids > 0)
+ {
+ _hurd_id.gen.uids[0] = euid;
+ _hurd_id.valid = 0;
+ }
+ if (_hurd_id.aux.nuids > 1)
+ {
+ _hurd_id.aux.uids[0] = ruid;
+ _hurd_id.aux.uids[1] = suid;
+ _hurd_id.valid = 0;
+ }
+
+ err = __USEPORT (AUTH, __auth_makeauth
+ (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ _hurd_id.gen.nuids ? _hurd_id.gen.uids : &euid,
+ _hurd_id.gen.nuids ?: 1,
+ _hurd_id.aux.nuids > 1 ? _hurd_id.aux.uids : auids,
+ _hurd_id.aux.nuids > 1 ? _hurd_id.aux.nuids : 2,
+ _hurd_id.gen.gids, _hurd_id.gen.ngids,
+ _hurd_id.aux.gids, _hurd_id.aux.ngids,
+ &newauth));
+ }
+
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ /* Install the new handle and reauthenticate everything. */
+ err = __setauth (newauth);
+ __mach_port_deallocate (__mach_task_self (), newauth);
+ return err;
+}
+libc_hidden_def (__setresuid)
+weak_alias (__setresuid, setresuid)
diff --git a/libc/sysdeps/mach/hurd/setreuid.c b/libc/sysdeps/mach/hurd/setreuid.c
new file mode 100644
index 000000000..b88879f18
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setreuid.c
@@ -0,0 +1,98 @@
+/* Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+#include <string.h>
+
+int
+__setreuid (ruid, euid)
+ uid_t ruid;
+ uid_t euid;
+{
+ auth_t newauth;
+ error_t err;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+ err = _hurd_check_ids ();
+
+ if (!err)
+ {
+ /* Make a new auth handle which has RUID as the real uid,
+ and EUID as the first element in the list of effective uids. */
+
+ uid_t *newgen, *newaux;
+ size_t ngen, naux;
+
+ newgen = _hurd_id.gen.uids;
+ ngen = _hurd_id.gen.nuids;
+ if (euid != -1)
+ {
+ if (_hurd_id.gen.nuids == 0)
+ {
+ /* No effective uids now. The new set will be just UID. */
+ newgen = &euid;
+ ngen = 1;
+ }
+ else
+ {
+ _hurd_id.gen.uids[0] = euid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ newaux = _hurd_id.aux.uids;
+ naux = _hurd_id.aux.nuids;
+ if (ruid != -1)
+ {
+ if (_hurd_id.aux.nuids == 0)
+ {
+ newaux = &ruid;
+ naux = 1;
+ }
+ else
+ {
+ _hurd_id.aux.uids[0] = ruid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ err = __USEPORT (AUTH, __auth_makeauth
+ (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ newgen, ngen, newaux, naux,
+ _hurd_id.gen.gids, _hurd_id.gen.ngids,
+ _hurd_id.aux.gids, _hurd_id.aux.ngids,
+ &newauth));
+ }
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ /* Install the new handle and reauthenticate everything. */
+ err = __setauth (newauth);
+ __mach_port_deallocate (__mach_task_self (), newauth);
+ return err;
+}
+
+weak_alias (__setreuid, setreuid)
diff --git a/libc/sysdeps/mach/hurd/setrlimit.c b/libc/sysdeps/mach/hurd/setrlimit.c
new file mode 100644
index 000000000..29f91cf92
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setrlimit.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1991,92,93,94,97,98,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/resource.h>
+
+/* Set the soft and hard limits for RESOURCE to *RLIMITS.
+ Only the super-user can increase hard limits.
+ Return 0 if successful, -1 if not (and sets errno). */
+int
+__setrlimit (enum __rlimit_resource resource, const struct rlimit *rlimits)
+{
+ struct rlimit lim;
+
+ if (rlimits == NULL || (unsigned int) resource >= RLIMIT_NLIMITS)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ lim = *rlimits;
+
+ /* Even though most limits do nothing, there is no inheritance, and hard
+ limits are not really hard, we just let any old call succeed to make
+ life easier for programs that expect normal behavior. */
+
+ if (lim.rlim_cur > lim.rlim_max)
+ lim.rlim_cur = lim.rlim_max;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_rlimit_lock);
+ _hurd_rlimits[resource] = lim;
+ __mutex_unlock (&_hurd_rlimit_lock);
+ HURD_CRITICAL_END;
+
+ return 0;
+}
+
+weak_alias (__setrlimit, setrlimit)
diff --git a/libc/sysdeps/mach/hurd/setsid.c b/libc/sysdeps/mach/hurd/setsid.c
new file mode 100644
index 000000000..e4e3eb92a
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setsid.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 1993,94,95,97,99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <hurd/fd.h>
+
+/* Create a new session with the calling process as its leader.
+ The process group IDs of the session and the calling process
+ are set to the process ID of the calling process, which is returned. */
+pid_t
+__setsid (void)
+{
+ error_t err;
+ unsigned int stamp;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_dtable_lock);
+
+ stamp = _hurd_pids_changed_stamp; /* Atomic fetch. */
+
+ /* Tell the proc server we want to start a new session. */
+ err = __USEPORT (PROC, __proc_setsid (port));
+ if (err)
+ __mutex_unlock (&_hurd_dtable_lock);
+ else
+ {
+ /* Punt our current ctty, and update the dtable accordingly. We hold
+ the dtable lock from before the proc_setsid call through clearing
+ the cttyid port and processing the dtable, so that we can be sure
+ that it's all done by the time the signal thread processes the
+ pgrp change notification. */
+ _hurd_locked_install_cttyid (MACH_PORT_NULL);
+
+ /* Synchronize with the signal thread to make sure we have received
+ and processed proc_newids before returning to the user.
+ This is necessary to ensure that _hurd_pgrp (and thus the value
+ returned by `getpgrp ()' in other threads) has been updated before
+ we return. */
+ while (_hurd_pids_changed_stamp == stamp)
+ {
+#ifdef noteven
+ /* XXX we have no need for a mutex, but cthreads demands one. */
+ __condition_wait (&_hurd_pids_changed_sync, NULL);
+#else
+ __swtch_pri (0);
+#endif
+ }
+ }
+
+ HURD_CRITICAL_END;
+
+ return err ? __hurd_fail (err) : _hurd_pgrp;
+}
+
+weak_alias (__setsid, setsid)
diff --git a/libc/sysdeps/mach/hurd/setsockopt.c b/libc/sysdeps/mach/hurd/setsockopt.c
new file mode 100644
index 000000000..8ca7f0c72
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setsockopt.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1992,94,97,98,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/socket.h>
+#include <hurd/fd.h>
+
+/* Set socket FD's option OPTNAME at protocol level LEVEL
+ to *OPTVAL (which is OPTLEN bytes long).
+ Returns 0 on success, -1 for errors. */
+int
+__setsockopt (int fd,
+ int level,
+ int optname,
+ const void *optval,
+ socklen_t optlen)
+{
+ error_t err = HURD_DPORT_USE (fd, __socket_setopt (port,
+ level, optname,
+ optval, optlen));
+ if (err)
+ return __hurd_dfail (fd, err);
+ return 0;
+}
+
+weak_alias (__setsockopt, setsockopt)
diff --git a/libc/sysdeps/mach/hurd/settimeofday.c b/libc/sysdeps/mach/hurd/settimeofday.c
new file mode 100644
index 000000000..d76041a80
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/settimeofday.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1991,92,93,94,95,97,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/time.h>
+#include <hurd.h>
+#include <hurd/port.h>
+
+/* Set the current time of day and timezone information.
+ This call is restricted to the super-user. */
+int
+__settimeofday (tv, tz)
+ const struct timeval *tv;
+ const struct timezone *tz;
+{
+ error_t err;
+ mach_port_t hostpriv;
+
+ if (tz != NULL)
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ err = __get_privileged_ports (&hostpriv, NULL);
+ if (err)
+ return __hurd_fail (EPERM);
+
+ /* `time_value_t' and `struct timeval' are in fact identical with the
+ names changed. */
+ err = __host_set_time (hostpriv, *(time_value_t *) tv);
+ __mach_port_deallocate (__mach_task_self (), hostpriv);
+
+ if (err)
+ return __hurd_fail (err);
+
+ return 0;
+}
+
+weak_alias (__settimeofday, settimeofday)
diff --git a/libc/sysdeps/mach/hurd/setuid.c b/libc/sysdeps/mach/hurd/setuid.c
new file mode 100644
index 000000000..3679e8e0f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setuid.c
@@ -0,0 +1,101 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/id.h>
+#include <string.h>
+
+/* Set the user ID of the calling process to UID.
+ If the calling process is the super-user, the real
+ and effective user IDs, and the saved set-user-ID to UID;
+ if not, the effective user ID is set to UID. */
+int
+__setuid (uid)
+ uid_t uid;
+{
+ auth_t newauth;
+ error_t err;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+ err = _hurd_check_ids ();
+
+ if (!err)
+ {
+ /* Make a new auth handle which has UID as the real uid,
+ and as the first element in the list of effective uids. */
+
+ uid_t *newgen, *newaux, auxbuf[2];
+ size_t ngen, naux;
+
+ newaux = _hurd_id.aux.uids;
+ naux = _hurd_id.aux.nuids;
+ if (_hurd_id.gen.nuids == 0)
+ {
+ /* No effective uids now. The new set will be just UID. */
+ newgen = &uid;
+ ngen = 1;
+ }
+ else if (_hurd_id.gen.uids[0] == 0)
+ {
+ /* We are root; set the effective, real, and saved to UID. */
+ _hurd_id.gen.uids[0] = uid;
+ _hurd_id.valid = 0;
+ newgen = _hurd_id.gen.uids;
+ ngen = _hurd_id.gen.nuids;
+ if (_hurd_id.aux.nuids < 2)
+ {
+ newaux = auxbuf;
+ naux = 2;
+ }
+ newaux[0] = newaux[1] = uid;
+ }
+ else
+ {
+ /* We are not root; just change the effective UID. */
+ /* XXX that implies an unprivileged setuid(0) will give
+ the caller root, no questions asked! */
+ _hurd_id.gen.uids[0] = uid;
+ _hurd_id.valid = 0;
+ newgen = _hurd_id.gen.uids;
+ ngen = _hurd_id.gen.nuids;
+ }
+
+ err = __USEPORT (AUTH, __auth_makeauth
+ (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ newgen, ngen, newaux, naux,
+ _hurd_id.gen.gids, _hurd_id.gen.ngids,
+ _hurd_id.aux.gids, _hurd_id.aux.ngids,
+ &newauth));
+ }
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ /* Install the new handle and reauthenticate everything. */
+ err = __setauth (newauth);
+ __mach_port_deallocate (__mach_task_self (), newauth);
+ return err;
+}
+
+weak_alias (__setuid, setuid)
diff --git a/libc/sysdeps/mach/hurd/setxattr.c b/libc/sysdeps/mach/hurd/setxattr.c
new file mode 100644
index 000000000..afabc8ee0
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/setxattr.c
@@ -0,0 +1,36 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+
+ssize_t
+setxattr (const char *path, const char *name, const void *value, size_t size,
+ int flags)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_set (port, name, value, size, flags);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return __hurd_fail (err);
+}
diff --git a/libc/sysdeps/mach/hurd/shutdown.c b/libc/sysdeps/mach/hurd/shutdown.c
new file mode 100644
index 000000000..eb425f06e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/shutdown.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1992, 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/socket.h>
+#include <hurd/fd.h>
+
+/* Shut down all or part of the connection open on socket FD.
+ HOW determines what to shut down:
+ 0 = No more receptions;
+ 1 = No more transmissions;
+ 2 = No more receptions or transmissions.
+ Returns 0 on success, -1 for errors. */
+/* XXX should be __shutdown ? */
+int
+shutdown (fd, how)
+ int fd;
+ int how;
+{
+ error_t err = HURD_DPORT_USE (fd, __socket_shutdown (port, how));
+ if (err)
+ return __hurd_dfail (fd, err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/sigaction.c b/libc/sysdeps/mach/hurd/sigaction.c
new file mode 100644
index 000000000..3dc530955
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sigaction.c
@@ -0,0 +1,94 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+ If OACT is not NULL, put the old action for SIG in *OACT. */
+int
+__sigaction (sig, act, oact)
+ int sig;
+ const struct sigaction *act;
+ struct sigaction *oact;
+{
+ struct hurd_sigstate *ss;
+ struct sigaction a, old;
+ sigset_t pending;
+
+ if (sig <= 0 || sig >= NSIG ||
+ (act != NULL && act->sa_handler != SIG_DFL &&
+ ((__sigmask (sig) & _SIG_CANT_MASK) ||
+ act->sa_handler == SIG_ERR)))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Copy so we fault before taking locks. */
+ if (act != NULL)
+ a = *act;
+
+ ss = _hurd_self_sigstate ();
+
+ __spin_lock (&ss->critical_section_lock);
+ __spin_lock (&ss->lock);
+ old = ss->actions[sig];
+ if (act != NULL)
+ ss->actions[sig] = a;
+
+ if (act != NULL && sig == SIGCHLD &&
+ (a.sa_flags & SA_NOCLDSTOP) != (old.sa_flags & SA_NOCLDSTOP))
+ {
+ __spin_unlock (&ss->lock);
+
+ /* Inform the proc server whether or not it should send us SIGCHLD for
+ stopped children. We do this in a critical section so that no
+ SIGCHLD can arrive in the middle and be of indeterminate status. */
+ __USEPORT (PROC,
+ __proc_mod_stopchild (port, !(a.sa_flags & SA_NOCLDSTOP)));
+
+ __spin_lock (&ss->lock);
+ pending = ss->pending & ~ss->blocked;
+ }
+ else if (a.sa_handler == SIG_IGN || a.sa_handler == SIG_DFL)
+ /* We are changing to an action that might be to ignore SIG signals.
+ If SIG is blocked and pending and the new action is to ignore it, we
+ must remove it from the pending set now; if the action is changed
+ back and then SIG is unblocked, the signal pending now should not
+ arrive. So wake up the signal thread to check the new state and do
+ the right thing. */
+ pending = ss->pending & __sigmask (sig);
+ else
+ pending = 0;
+
+ __spin_unlock (&ss->lock);
+ __spin_unlock (&ss->critical_section_lock);
+
+ if (pending)
+ __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
+
+ if (oact != NULL)
+ *oact = old;
+
+ return 0;
+}
+libc_hidden_def (__sigaction)
+weak_alias (__sigaction, sigaction)
diff --git a/libc/sysdeps/mach/hurd/sigaltstack.c b/libc/sysdeps/mach/hurd/sigaltstack.c
new file mode 100644
index 000000000..5b2f06561
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sigaltstack.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1992, 93, 94, 95, 97, 98 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+
+/* Run signals handlers on the stack specified by SS (if not NULL).
+ If OSS is not NULL, it is filled in with the old signal stack status. */
+int
+__sigaltstack (argss, oss)
+ const struct sigaltstack *argss;
+ struct sigaltstack *oss;
+{
+ struct hurd_sigstate *s;
+ struct sigaltstack ss, old;
+
+ /* Fault before taking any locks. */
+ if (argss != NULL)
+ ss = *argss;
+ if (oss != NULL)
+ *(volatile struct sigaltstack *) oss = *oss;
+
+ s = _hurd_self_sigstate ();
+ __spin_lock (&s->lock);
+
+ if (argss != NULL &&
+ (ss.ss_flags & SS_DISABLE) && (s->sigaltstack.ss_flags & SS_ONSTACK))
+ {
+ /* Can't disable a stack that is in use. */
+ __spin_unlock (&s->lock);
+ errno = EINVAL;
+ return -1;
+ }
+
+ old = s->sigaltstack;
+
+ if (argss != NULL)
+ s->sigaltstack = ss;
+
+ __spin_unlock (&s->lock);
+
+ if (oss != NULL)
+ *oss = old;
+
+ return 0;
+}
+weak_alias (__sigaltstack, sigaltstack)
diff --git a/libc/sysdeps/mach/hurd/siglist.h b/libc/sysdeps/mach/hurd/siglist.h
new file mode 100644
index 000000000..75701c874
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/siglist.h
@@ -0,0 +1,23 @@
+/* Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file is included multiple times. */
+
+#include_next <siglist.h> /* Get the canonical list. */
+
+#define OLD_SIGLIST_SIZE 33 /* For GLIBC_2.0 binary compatibility. */
diff --git a/libc/sysdeps/mach/hurd/sigpending.c b/libc/sysdeps/mach/hurd/sigpending.c
new file mode 100644
index 000000000..84ac92714
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sigpending.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1991, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+
+
+/* Store in SET all signals that are blocked and pending. */
+/* XXX should be __sigpending ? */
+int
+sigpending (set)
+ sigset_t *set;
+{
+ struct hurd_sigstate *ss;
+ sigset_t pending;
+
+ if (set == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ ss = _hurd_self_sigstate ();
+ __spin_lock (&ss->lock);
+ pending = ss->pending;
+ __spin_unlock (&ss->lock);
+
+ *set = pending;
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/sigprocmask.c b/libc/sysdeps/mach/hurd/sigprocmask.c
new file mode 100644
index 000000000..cbb5ecce2
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sigprocmask.c
@@ -0,0 +1,87 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/msg.h>
+
+/* If SET is not NULL, modify the current set of blocked signals
+ according to HOW, which may be SIG_BLOCK, SIG_UNBLOCK or SIG_SETMASK.
+ If OSET is not NULL, store the old set of blocked signals in *OSET. */
+int
+__sigprocmask (how, set, oset)
+ int how;
+ const sigset_t *set;
+ sigset_t *oset;
+{
+ struct hurd_sigstate *ss;
+ sigset_t old, new;
+ sigset_t pending;
+
+ if (set != NULL)
+ new = *set;
+
+ ss = _hurd_self_sigstate ();
+
+ __spin_lock (&ss->lock);
+
+ old = ss->blocked;
+
+ if (set != NULL)
+ {
+ switch (how)
+ {
+ case SIG_BLOCK:
+ __sigorset (&ss->blocked, &ss->blocked, &new);
+ break;
+
+ case SIG_UNBLOCK:
+ ss->blocked &= ~new;
+ break;
+
+ case SIG_SETMASK:
+ ss->blocked = new;
+ break;
+
+ default:
+ __spin_unlock (&ss->lock);
+ errno = EINVAL;
+ return -1;
+ }
+
+ ss->blocked &= ~_SIG_CANT_MASK;
+ }
+
+ pending = ss->pending & ~ss->blocked;
+
+ __spin_unlock (&ss->lock);
+
+ if (oset != NULL)
+ *oset = old;
+
+ if (pending)
+ /* Send a message to the signal thread so it
+ will wake up and check for pending signals. */
+ __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
+
+ return 0;
+}
+
+weak_alias (__sigprocmask, sigprocmask)
diff --git a/libc/sysdeps/mach/hurd/sigstack.c b/libc/sysdeps/mach/hurd/sigstack.c
new file mode 100644
index 000000000..3282da3de
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sigstack.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1992,97,98,2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <hurd.h>
+
+/* Run signals handlers on the stack specified by SS (if not NULL).
+ If OSS is not NULL, it is filled in with the old signal stack status. */
+int
+sigstack (struct sigstack *ss, struct sigstack *oss)
+{
+ struct sigaltstack as, oas;
+
+ as.ss_sp = ss->ss_sp;
+ as.ss_size = 0;
+ as.ss_flags = 0;
+
+ if (__sigaltstack (&as, &oas) < 0)
+ return -1;
+
+ if (oss != NULL)
+ {
+ oss->ss_sp = oas.ss_sp;
+ oss->ss_onstack = oas.ss_flags & SS_ONSTACK;
+ }
+
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/sigsuspend.c b/libc/sysdeps/mach/hurd/sigsuspend.c
new file mode 100644
index 000000000..96b3857c7
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sigsuspend.c
@@ -0,0 +1,83 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,98,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/msg.h>
+
+/* Change the set of blocked signals to SET,
+ wait until a signal arrives, and restore the set of blocked signals. */
+int
+__sigsuspend (set)
+ const sigset_t *set;
+{
+ struct hurd_sigstate *ss;
+ sigset_t newmask, oldmask, pending;
+ mach_port_t wait;
+ mach_msg_header_t msg;
+
+ if (set != NULL)
+ /* Crash before locking. */
+ newmask = *set;
+
+ /* Get a fresh port we will wait on. */
+ wait = __mach_reply_port ();
+
+ ss = _hurd_self_sigstate ();
+
+ __spin_lock (&ss->lock);
+
+ oldmask = ss->blocked;
+ if (set != NULL)
+ /* Change to the new blocked signal mask. */
+ ss->blocked = newmask & ~_SIG_CANT_MASK;
+
+ /* Notice if any pending signals just became unblocked. */
+ pending = ss->pending & ~ss->blocked;
+
+ /* Tell the signal thread to message us when a signal arrives. */
+ ss->suspended = wait;
+ __spin_unlock (&ss->lock);
+
+ if (pending)
+ /* Tell the signal thread to check for pending signals. */
+ __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
+
+ /* Wait for the signal thread's message. */
+ __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait,
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ __mach_port_destroy (__mach_task_self (), wait);
+
+ __spin_lock (&ss->lock);
+ ss->blocked = oldmask; /* Restore the old mask. */
+ pending = ss->pending & ~ss->blocked; /* Again check for pending signals. */
+ __spin_unlock (&ss->lock);
+
+ if (pending)
+ /* Tell the signal thread to check for pending signals. */
+ __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
+
+ /* We've been interrupted! And a good thing, too.
+ Otherwise we'd never return.
+ That's right; this function always returns an error. */
+ errno = EINTR;
+ return -1;
+}
+libc_hidden_def (__sigsuspend)
+weak_alias (__sigsuspend, sigsuspend)
diff --git a/libc/sysdeps/mach/hurd/sigwait.c b/libc/sysdeps/mach/hurd/sigwait.c
new file mode 100644
index 000000000..9794076be
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sigwait.c
@@ -0,0 +1,133 @@
+/* Copyright (C) 1996,97,2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/msg.h>
+#include <hurd/sigpreempt.h>
+#include <assert.h>
+
+/* Select any of pending signals from SET or wait for any to arrive. */
+int
+__sigwait (const sigset_t *set, int *sig)
+{
+ struct hurd_sigstate *ss;
+ sigset_t mask, ready;
+ int signo = 0;
+ struct hurd_signal_preemptor preemptor;
+ jmp_buf buf;
+ mach_port_t wait;
+ mach_msg_header_t msg;
+
+ sighandler_t
+ preempt_fun (struct hurd_signal_preemptor *pe,
+ struct hurd_sigstate *ss,
+ int *sigp,
+ struct hurd_signal_detail *detail)
+ {
+ if (signo)
+ /* We've already been run; don't interfere. */
+ return SIG_ERR;
+
+ signo = *sigp;
+
+ /* Make sure this is all kosher */
+ assert (__sigismember (&mask, signo));
+
+ /* Make sure this signal is unblocked */
+ __sigdelset (&ss->blocked, signo);
+
+ return pe->handler;
+ }
+
+ void
+ handler (int sig)
+ {
+ assert (sig == signo);
+ longjmp (buf, 1);
+ }
+
+ wait = __mach_reply_port ();
+
+ if (set != NULL)
+ /* Crash before locking */
+ mask = *set;
+ else
+ __sigemptyset (&mask);
+
+ ss = _hurd_self_sigstate ();
+ __spin_lock (&ss->lock);
+
+ /* See if one of these signals is currently pending. */
+ __sigandset (&ready, &ss->pending, &mask);
+ if (! __sigisemptyset (&ready))
+ {
+ for (signo = 1; signo < NSIG; signo++)
+ if (__sigismember (&ready, signo))
+ {
+ __sigdelset (&ready, signo);
+ goto all_done;
+ }
+ /* Huh? Where'd it go? */
+ abort ();
+ }
+
+ /* Wait for one of them to show up. */
+
+ if (!setjmp (buf))
+ {
+ /* Make the preemptor */
+ preemptor.signals = mask;
+ preemptor.first = 0;
+ preemptor.last = -1;
+ preemptor.preemptor = preempt_fun;
+ preemptor.handler = handler;
+
+ /* Install this preemptor */
+ preemptor.next = ss->preemptors;
+ ss->preemptors = &preemptor;
+
+ __spin_unlock (&ss->lock);
+
+ /* Wait. */
+ __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait,
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ abort ();
+ }
+ else
+ {
+ assert (signo);
+
+ __spin_lock (&ss->lock);
+
+ /* Delete our preemptor. */
+ assert (ss->preemptors == &preemptor);
+ ss->preemptors = preemptor.next;
+ }
+
+
+all_done:
+ spin_unlock (&ss->lock);
+
+ __mach_port_destroy (__mach_task_self (), wait);
+ *sig = signo;
+ return 0;
+}
+
+weak_alias (__sigwait, sigwait)
diff --git a/libc/sysdeps/mach/hurd/socket.c b/libc/sysdeps/mach/hurd/socket.c
new file mode 100644
index 000000000..a707ed90e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/socket.c
@@ -0,0 +1,68 @@
+/* Copyright (C) 1992, 93, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/socket.h>
+#include <hurd/fd.h>
+#include <fcntl.h>
+
+/* Create a new socket of type TYPE in domain DOMAIN, using
+ protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically.
+ Returns a file descriptor for the new socket, or -1 for errors. */
+int
+__socket (domain, type, protocol)
+ int domain;
+ int type;
+ int protocol;
+{
+ error_t err;
+ socket_t sock, server;
+
+ /* Find the socket server for DOMAIN. */
+ server = _hurd_socket_server (domain, 0);
+ if (server == MACH_PORT_NULL)
+ return -1;
+
+ err = __socket_create (server, type, protocol, &sock);
+ if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED
+ || err == MIG_BAD_ID || err == EOPNOTSUPP)
+ {
+ /* On the first use of the socket server during the operation,
+ allow for the old server port dying. */
+ server = _hurd_socket_server (domain, 1);
+ if (server == MACH_PORT_NULL)
+ return -1;
+ err = __socket_create (server, type, protocol, &sock);
+ }
+
+ /* These errors all mean that the server node doesn't support the
+ socket.defs protocol, which we'll take to mean that the protocol
+ isn't supported. */
+ if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED
+ || err == MIG_BAD_ID || err == EOPNOTSUPP)
+ err = EPFNOSUPPORT;
+
+ if (err)
+ return __hurd_fail (err);
+
+ return _hurd_intern_fd (sock, O_IGNORE_CTTY, 1);
+}
+
+weak_alias (__socket, socket)
diff --git a/libc/sysdeps/mach/hurd/socketpair.c b/libc/sysdeps/mach/hurd/socketpair.c
new file mode 100644
index 000000000..b124d2017
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/socketpair.c
@@ -0,0 +1,95 @@
+/* Copyright (C) 1992, 94, 95, 96, 97, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+
+/* Create two new sockets, of type TYPE in domain DOMAIN and using
+ protocol PROTOCOL, which are connected to each other, and put file
+ descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
+ one will be chosen automatically. Returns 0 on success, -1 for errors. */
+int
+__socketpair (int domain, int type, int protocol, int fds[2])
+{
+ error_t err;
+ socket_t server, sock1, sock2;
+ int d1, d2;
+
+ if (fds == NULL)
+ return __hurd_fail (EINVAL);
+
+ /* Find the domain's socket server. */
+ server = _hurd_socket_server (domain, 0);
+ if (server == MACH_PORT_NULL)
+ return -1;
+
+ /* Create two sockets and connect them together. */
+
+ err = __socket_create (server, type, protocol, &sock1);
+ if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED
+ || err == MIG_BAD_ID || err == EOPNOTSUPP)
+ {
+ /* On the first use of the socket server during the operation,
+ allow for the old server port dying. */
+ server = _hurd_socket_server (domain, 1);
+ if (server == MACH_PORT_NULL)
+ return -1;
+ err = __socket_create (server, type, protocol, &sock1);
+ }
+ if (err)
+ return __hurd_fail (err);
+ if (err = __socket_create (server, type, protocol, &sock2))
+ {
+ __mach_port_deallocate (__mach_task_self (), sock1);
+ return __hurd_fail (err);
+ }
+ if (err = __socket_connect2 (sock1, sock2))
+ {
+ __mach_port_deallocate (__mach_task_self (), sock1);
+ __mach_port_deallocate (__mach_task_self (), sock2);
+ return __hurd_fail (err);
+ }
+
+ /* Put the sockets into file descriptors. */
+
+ d1 = _hurd_intern_fd (sock1, O_IGNORE_CTTY, 1);
+ if (d1 < 0)
+ {
+ __mach_port_deallocate (__mach_task_self (), sock2);
+ return -1;
+ }
+ d2 = _hurd_intern_fd (sock2, O_IGNORE_CTTY, 1);
+ if (d2 < 0)
+ {
+ err = errno;
+ (void) close (d1);
+ return __hurd_fail (err);
+ }
+
+ fds[0] = d1;
+ fds[1] = d2;
+ return 0;
+}
+
+weak_alias (__socketpair, socketpair)
diff --git a/libc/sysdeps/mach/hurd/spawni.c b/libc/sysdeps/mach/hurd/spawni.c
new file mode 100644
index 000000000..244ca2d6e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/spawni.c
@@ -0,0 +1,756 @@
+/* spawn a new process running an executable. Hurd version.
+ Copyright (C) 2001,02,04 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <spawn.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/fd.h>
+#include <hurd/id.h>
+#include <hurd/lookup.h>
+#include <hurd/resource.h>
+#include <assert.h>
+#include <argz.h>
+#include "spawn_int.h"
+
+/* Spawn a new process executing PATH with the attributes describes in *ATTRP.
+ Before running the process perform the actions described in FILE-ACTIONS. */
+int
+__spawni (pid_t *pid, const char *file,
+ const posix_spawn_file_actions_t *file_actions,
+ const posix_spawnattr_t *attrp,
+ char *const argv[], char *const envp[],
+ int use_path)
+{
+ pid_t new_pid;
+ char *path, *p, *name;
+ size_t len;
+ size_t pathlen;
+ short int flags;
+
+ /* The generic POSIX.1 implementation of posix_spawn uses fork and exec.
+ In traditional POSIX systems (Unix, Linux, etc), the only way to
+ create a new process is by fork, which also copies all the things from
+ the parent process that will be immediately wiped and replaced by the
+ exec.
+
+ This Hurd implementation works by doing an exec on a fresh task,
+ without ever doing all the work of fork. The only work done by fork
+ that remains visible after an exec is registration with the proc
+ server, and the inheritance of various values and ports. All those
+ inherited values and ports are what get collected up and passed in the
+ file_exec RPC by an exec call. So we do the proc server registration
+ here, following the model of fork (see fork.c). We then collect up
+ the inherited values and ports from this (parent) process following
+ the model of exec (see hurd/hurdexec.c), modify or replace each value
+ that fork would (plus the specific changes demanded by ATTRP and
+ FILE_ACTIONS), and make the file_exec RPC on the requested executable
+ file with the child process's task port rather than our own. This
+ should be indistinguishable from the fork + exec implementation,
+ except that all errors will be detected here (in the parent process)
+ and return proper errno codes rather than the child dying with 127.
+
+ XXX The one exception to this supposed indistinguishableness is that
+ when posix_spawn_file_actions_addopen has been used, the parent
+ process can do various filesystem RPCs on the child's behalf, rather
+ than the child process doing it. If these block due to a broken or
+ malicious filesystem server or just a blocked network fs or a serial
+ port waiting for carrier detect (!!), the parent's posix_spawn call
+ can block arbitrarily rather than just the child blocking. Possible
+ solutions include:
+ * punt to plain fork + exec implementation if addopen was used
+ ** easy to do
+ ** gives up all benefits of this implementation in that case
+ * if addopen was used, don't do any file actions at all here;
+ instead, exec an installed helper program e.g.:
+ /libexec/spawn-helper close 3 dup2 1 2 open 0 /file 0x123 0666 exec /bin/foo foo a1 a2
+ ** extra exec might be more or less overhead than fork
+ * could do some weird half-fork thing where the child would inherit
+ our vm and run some code here, but not do the full work of fork
+
+ XXX Actually, the parent opens the executable file on behalf of
+ the child, and that has all the same issues.
+
+ I am favoring the half-fork solution. That is, we do task_create with
+ vm inheritance, and we setjmp/longjmp the child like fork does. But
+ rather than all the fork hair, the parent just packs up init/dtable
+ ports and does a single IPC to a receive right inserted in the child. */
+
+ error_t err;
+ task_t task;
+ file_t execfile;
+ process_t proc;
+ auth_t auth;
+ int ints[INIT_INT_MAX];
+ file_t *dtable;
+ unsigned int dtablesize, orig_dtablesize, i;
+ struct hurd_port **dtable_cells;
+ char *dtable_cloexec;
+ struct hurd_userlink *ulink_dtable = NULL;
+ struct hurd_sigstate *ss;
+
+ /* For POSIX_SPAWN_RESETIDS, this reauthenticates our root/current
+ directory ports with the new AUTH port. */
+ file_t rcrdir = MACH_PORT_NULL, rcwdir = MACH_PORT_NULL;
+ error_t reauthenticate (int which, file_t *result)
+ {
+ error_t err;
+ mach_port_t ref;
+ if (*result != MACH_PORT_NULL)
+ return 0;
+ ref = __mach_reply_port ();
+ err = HURD_PORT_USE
+ (&_hurd_ports[which],
+ ({
+ err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
+ if (!err)
+ err = __auth_user_authenticate (auth,
+ ref, MACH_MSG_TYPE_MAKE_SEND,
+ result);
+ err;
+ }));
+ __mach_port_destroy (__mach_task_self (), ref);
+ return err;
+ }
+
+ /* Reauthenticate one of our file descriptors for the child. A null
+ element of DTABLE_CELLS indicates a descriptor that was already
+ reauthenticated, or was newly opened on behalf of the child. */
+ error_t reauthenticate_fd (int fd)
+ {
+ if (dtable_cells[fd] != NULL)
+ {
+ file_t newfile;
+ mach_port_t ref = __mach_reply_port ();
+ error_t err = __io_reauthenticate (dtable[fd],
+ ref, MACH_MSG_TYPE_MAKE_SEND);
+ if (!err)
+ err = __auth_user_authenticate (auth,
+ ref, MACH_MSG_TYPE_MAKE_SEND,
+ &newfile);
+ __mach_port_destroy (__mach_task_self (), ref);
+ if (err)
+ return err;
+ _hurd_port_free (dtable_cells[fd], &ulink_dtable[fd], dtable[fd]);
+ dtable_cells[fd] = NULL;
+ dtable[fd] = newfile;
+ }
+ return 0;
+ }
+
+ /* These callbacks are for looking up file names on behalf of the child. */
+ error_t child_init_port (int which, error_t (*operate) (mach_port_t))
+ {
+ if (flags & POSIX_SPAWN_RESETIDS)
+ switch (which)
+ {
+ case INIT_PORT_AUTH:
+ return (*operate) (auth);
+ case INIT_PORT_CRDIR:
+ return (reauthenticate (INIT_PORT_CRDIR, &rcrdir)
+ ?: (*operate) (rcrdir));
+ case INIT_PORT_CWDIR:
+ return (reauthenticate (INIT_PORT_CWDIR, &rcwdir)
+ ?: (*operate) (rcwdir));
+ }
+ assert (which != INIT_PORT_PROC);
+ return _hurd_ports_use (which, operate);
+ }
+ file_t child_fd (int fd)
+ {
+ if ((unsigned int) fd < dtablesize && dtable[fd] != MACH_PORT_NULL)
+ {
+ if (flags & POSIX_SPAWN_RESETIDS)
+ {
+ /* Reauthenticate this descriptor right now,
+ since it is going to be used on behalf of the child. */
+ errno = reauthenticate_fd (fd);
+ if (errno)
+ return MACH_PORT_NULL;
+ }
+ __mach_port_mod_refs (__mach_task_self (), dtable[fd],
+ MACH_PORT_RIGHT_SEND, +1);
+ return dtable[fd];
+ }
+ errno = EBADF;
+ return MACH_PORT_NULL;
+ }
+ inline error_t child_lookup (const char *file, int oflag, mode_t mode,
+ file_t *result)
+ {
+ return __hurd_file_name_lookup (&child_init_port, &child_fd, 0,
+ file, oflag, mode, result);
+ }
+
+
+ /* Do this once. */
+ flags = attrp == NULL ? 0 : attrp->__flags;
+
+ /* Generate the new process. We create a task that does not inherit our
+ memory, and then register it as our child like fork does. See fork.c
+ for comments about the sequencing of these proc operations. */
+
+ err = __task_create (__mach_task_self (),
+#ifdef KERN_INVALID_LEDGER
+ NULL, 0, /* OSF Mach */
+#endif
+ 0, &task);
+ if (err)
+ return __hurd_fail (err);
+ // From here down we must deallocate TASK and PROC before returning.
+ proc = MACH_PORT_NULL;
+ auth = MACH_PORT_NULL;
+ err = __USEPORT (PROC, __proc_task2pid (port, task, &new_pid));
+ if (!err)
+ err = __USEPORT (PROC, __proc_task2proc (port, task, &proc));
+ if (!err)
+ err = __USEPORT (PROC, __proc_child (port, task));
+ if (err)
+ goto out;
+
+ /* Load up the ints to give the new program. */
+ memset (ints, 0, sizeof ints);
+ ints[INIT_UMASK] = _hurd_umask;
+ ints[INIT_TRACEMASK] = _hurdsig_traced;
+
+ ss = _hurd_self_sigstate ();
+
+ assert (! __spin_lock_locked (&ss->critical_section_lock));
+ __spin_lock (&ss->critical_section_lock);
+
+ __spin_lock (&ss->lock);
+ ints[INIT_SIGMASK] = ss->blocked;
+ ints[INIT_SIGPENDING] = ss->pending;
+ ints[INIT_SIGIGN] = 0;
+ /* Unless we were asked to reset all handlers to SIG_DFL,
+ pass down the set of signals that were set to SIG_IGN. */
+ if ((flags & POSIX_SPAWN_SETSIGDEF) == 0)
+ for (i = 1; i < NSIG; ++i)
+ if (ss->actions[i].sa_handler == SIG_IGN)
+ ints[INIT_SIGIGN] |= __sigmask (i);
+
+ /* We hold the sigstate lock until the exec has failed so that no signal
+ can arrive between when we pack the blocked and ignored signals, and
+ when the exec actually happens. A signal handler could change what
+ signals are blocked and ignored. Either the change will be reflected
+ in the exec, or the signal will never be delivered. Setting the
+ critical section flag avoids anything we call trying to acquire the
+ sigstate lock. */
+
+ __spin_unlock (&ss->lock);
+
+ /* Set signal mask. */
+ if ((flags & POSIX_SPAWN_SETSIGMASK) != 0)
+ ints[INIT_SIGMASK] = attrp->__ss;
+
+#ifdef _POSIX_PRIORITY_SCHEDULING
+ /* Set the scheduling algorithm and parameters. */
+# error implement me
+ if ((flags & (POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER))
+ == POSIX_SPAWN_SETSCHEDPARAM)
+ {
+ if (__sched_setparam (0, &attrp->__sp) == -1)
+ _exit (SPAWN_ERROR);
+ }
+ else if ((flags & POSIX_SPAWN_SETSCHEDULER) != 0)
+ {
+ if (__sched_setscheduler (0, attrp->__policy,
+ (flags & POSIX_SPAWN_SETSCHEDPARAM) != 0
+ ? &attrp->__sp : NULL) == -1)
+ _exit (SPAWN_ERROR);
+ }
+#endif
+
+ /* Set the process group ID. */
+ if (!err && (flags & POSIX_SPAWN_SETPGROUP) != 0)
+ err = __proc_setpgrp (proc, new_pid, attrp->__pgrp);
+
+ /* Set the effective user and group IDs. */
+ if (!err && (flags & POSIX_SPAWN_RESETIDS) != 0)
+ {
+ /* We need a different auth port for the child. */
+
+ __mutex_lock (&_hurd_id.lock);
+ err = _hurd_check_ids (); /* Get _hurd_id up to date. */
+ if (!err && _hurd_id.rid_auth == MACH_PORT_NULL)
+ {
+ /* Set up _hurd_id.rid_auth. This is a special auth server port
+ which uses the real uid and gid (the first aux uid and gid) as
+ the only effective uid and gid. */
+
+ if (_hurd_id.aux.nuids < 1 || _hurd_id.aux.ngids < 1)
+ /* We do not have a real UID and GID. Lose, lose, lose! */
+ err = EGRATUITOUS;
+
+ /* Create a new auth port using our real UID and GID (the first
+ auxiliary UID and GID) as the only effective IDs. */
+ if (!err)
+ err = __USEPORT (AUTH,
+ __auth_makeauth (port,
+ NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ _hurd_id.aux.uids, 1,
+ _hurd_id.aux.uids,
+ _hurd_id.aux.nuids,
+ _hurd_id.aux.gids, 1,
+ _hurd_id.aux.gids,
+ _hurd_id.aux.ngids,
+ &_hurd_id.rid_auth));
+ }
+ if (!err)
+ {
+ /* Use the real-ID auth port in place of the normal one. */
+ assert (_hurd_id.rid_auth != MACH_PORT_NULL);
+ auth = _hurd_id.rid_auth;
+ __mach_port_mod_refs (__mach_task_self (), auth,
+ MACH_PORT_RIGHT_SEND, +1);
+ }
+ __mutex_unlock (&_hurd_id.lock);
+ }
+ else
+ /* Copy our existing auth port. */
+ err = __USEPORT (AUTH, __mach_port_mod_refs (__mach_task_self (),
+ (auth = port),
+ MACH_PORT_RIGHT_SEND, +1));
+
+ if (err)
+ goto out;
+
+ /* Pack up the descriptor table to give the new program.
+ These descriptors will need to be reauthenticated below
+ if POSIX_SPAWN_RESETIDS is set. */
+ __mutex_lock (&_hurd_dtable_lock);
+ dtablesize = _hurd_dtablesize;
+ orig_dtablesize = _hurd_dtablesize;
+ dtable = __alloca (dtablesize * sizeof (dtable[0]));
+ ulink_dtable = __alloca (dtablesize * sizeof (ulink_dtable[0]));
+ dtable_cells = __alloca (dtablesize * sizeof (dtable_cells[0]));
+ dtable_cloexec = __alloca (dtablesize);
+ for (i = 0; i < dtablesize; ++i)
+ {
+ struct hurd_fd *const d = _hurd_dtable[i];
+ if (d == NULL)
+ {
+ dtable[i] = MACH_PORT_NULL;
+ dtable_cells[i] = NULL;
+ continue;
+ }
+ /* Note that this might return MACH_PORT_NULL. */
+ dtable[i] = _hurd_port_get (&d->port, &ulink_dtable[i]);
+ dtable_cells[i] = &d->port;
+ dtable_cloexec[i] = (d->flags & FD_CLOEXEC) != 0;
+ }
+ __mutex_unlock (&_hurd_dtable_lock);
+
+ /* Safe to let signals happen now. */
+ _hurd_critical_section_unlock (ss);
+
+ /* Execute the file actions. */
+ if (file_actions != NULL)
+ for (i = 0; i < file_actions->__used; ++i)
+ {
+ /* Close a file descriptor in the child. */
+ error_t do_close (int fd)
+ {
+ if ((unsigned int)fd < dtablesize
+ && dtable[fd] != MACH_PORT_NULL)
+ {
+ if (dtable_cells[fd] == NULL)
+ __mach_port_deallocate (__mach_task_self (), dtable[fd]);
+ else
+ {
+ _hurd_port_free (dtable_cells[fd],
+ &ulink_dtable[fd], dtable[fd]);
+ }
+ dtable_cells[fd] = NULL;
+ dtable[fd] = MACH_PORT_NULL;
+ return 0;
+ }
+ return EBADF;
+ }
+
+ /* Make sure the dtable can hold NEWFD. */
+#define EXPAND_DTABLE(newfd) \
+ ({ \
+ if ((unsigned int)newfd >= dtablesize \
+ && newfd < _hurd_rlimits[RLIMIT_OFILE].rlim_cur) \
+ { \
+ /* We need to expand the dtable for the child. */ \
+ NEW_TABLE (dtable, newfd); \
+ NEW_TABLE (ulink_dtable, newfd); \
+ NEW_TABLE (dtable_cells, newfd); \
+ dtablesize = newfd + 1; \
+ } \
+ ((unsigned int)newfd < dtablesize ? 0 : EMFILE); \
+ })
+#define NEW_TABLE(x, newfd) \
+ do { __typeof (x) new_##x = __alloca ((newfd + 1) * sizeof (x[0])); \
+ memcpy (new_##x, x, dtablesize * sizeof (x[0])); \
+ memset (&new_##x[dtablesize], 0, (newfd + 1 - dtablesize) * sizeof (x[0])); \
+ x = new_##x; } while (0)
+
+ struct __spawn_action *action = &file_actions->__actions[i];
+
+ switch (action->tag)
+ {
+ case spawn_do_close:
+ err = do_close (action->action.close_action.fd);
+ break;
+
+ case spawn_do_dup2:
+ if ((unsigned int)action->action.dup2_action.fd < dtablesize
+ && dtable[action->action.dup2_action.fd] != MACH_PORT_NULL)
+ {
+ const int fd = action->action.dup2_action.fd;
+ const int newfd = action->action.dup2_action.newfd;
+ // dup2 always clears any old FD_CLOEXEC flag on the new fd.
+ if (newfd < orig_dtablesize)
+ dtable_cloexec[newfd] = 0;
+ if (fd == newfd)
+ // Same is same as same was.
+ break;
+ err = EXPAND_DTABLE (newfd);
+ if (!err)
+ {
+ /* Close the old NEWFD and replace it with FD's
+ contents, which can be either an original
+ descriptor (DTABLE_CELLS[FD] != 0) or a new
+ right that we acquired in this function. */
+ do_close (newfd);
+ dtable_cells[newfd] = dtable_cells[fd];
+ if (dtable_cells[newfd] != NULL)
+ dtable[newfd] = _hurd_port_get (dtable_cells[newfd],
+ &ulink_dtable[newfd]);
+ else
+ {
+ dtable[newfd] = dtable[fd];
+ err = __mach_port_mod_refs (__mach_task_self (),
+ dtable[fd],
+ MACH_PORT_RIGHT_SEND, +1);
+ }
+ }
+ }
+ else
+ // The old FD specified was bogus.
+ err = EBADF;
+ break;
+
+ case spawn_do_open:
+ /* Open a file on behalf of the child.
+
+ XXX note that this can subject the parent to arbitrary
+ delays waiting for the files to open. I don't know what the
+ spec says about this. If it's not permissible, then this
+ whole forkless implementation is probably untenable. */
+ {
+ const int fd = action->action.open_action.fd;
+
+ do_close (fd);
+ if (fd < orig_dtablesize)
+ dtable_cloexec[fd] = 0;
+ err = EXPAND_DTABLE (fd);
+ if (err)
+ break;
+
+ err = child_lookup (action->action.open_action.path,
+ action->action.open_action.oflag,
+ action->action.open_action.mode,
+ &dtable[fd]);
+ dtable_cells[fd] = NULL;
+ break;
+ }
+ }
+
+ if (err)
+ goto out;
+ }
+
+ /* Only now can we perform FD_CLOEXEC. We had to leave the descriptors
+ unmolested for the file actions to use. Note that the DTABLE_CLOEXEC
+ array is never expanded by file actions, so it might now have fewer
+ than DTABLESIZE elements. */
+ for (i = 0; i < orig_dtablesize; ++i)
+ if (dtable[i] != MACH_PORT_NULL && dtable_cloexec[i])
+ {
+ assert (dtable_cells[i] != NULL);
+ _hurd_port_free (dtable_cells[i], &ulink_dtable[i], dtable[i]);
+ dtable[i] = MACH_PORT_NULL;
+ }
+
+ /* Prune trailing null ports from the descriptor table. */
+ while (dtablesize > 0 && dtable[dtablesize - 1] == MACH_PORT_NULL)
+ --dtablesize;
+
+ if (flags & POSIX_SPAWN_RESETIDS)
+ {
+ /* Reauthenticate all the child's ports with its new auth handle. */
+
+ mach_port_t ref;
+ process_t newproc;
+
+ /* Reauthenticate with the proc server. */
+ ref = __mach_reply_port ();
+ err = __proc_reauthenticate (proc, ref, MACH_MSG_TYPE_MAKE_SEND);
+ if (!err)
+ err = __auth_user_authenticate (auth,
+ ref, MACH_MSG_TYPE_MAKE_SEND,
+ &newproc);
+ __mach_port_destroy (__mach_task_self (), ref);
+ if (!err)
+ {
+ __mach_port_deallocate (__mach_task_self (), proc);
+ proc = newproc;
+ }
+
+ if (!err)
+ err = reauthenticate (INIT_PORT_CRDIR, &rcrdir);
+ if (!err)
+ err = reauthenticate (INIT_PORT_CWDIR, &rcwdir);
+
+ /* We must reauthenticate all the fds except those that came from
+ `spawn_do_open' file actions, which were opened using the child's
+ auth port to begin with. */
+ for (i = 0; !err && i < dtablesize; ++i)
+ err = reauthenticate_fd (i);
+ }
+ if (err)
+ goto out;
+
+ /* Now we are ready to open the executable file using the child's ports.
+ We do this after performing all the file actions so the order of
+ events is the same as for a fork, exec sequence. This affects things
+ like the meaning of a /dev/fd file name, as well as which error
+ conditions are diagnosed first and what side effects (file creation,
+ etc) can be observed before what errors. */
+
+ if (! use_path || strchr (file, '/') != NULL)
+ /* The FILE parameter is actually a path. */
+ err = child_lookup (file, O_EXEC, 0, &execfile);
+ else
+ {
+ /* We have to search for FILE on the path. */
+ path = getenv ("PATH");
+ if (path == NULL)
+ {
+ /* There is no `PATH' in the environment.
+ The default search path is the current directory
+ followed by the path `confstr' returns for `_CS_PATH'. */
+ len = confstr (_CS_PATH, (char *) NULL, 0);
+ path = (char *) __alloca (1 + len);
+ path[0] = ':';
+ (void) confstr (_CS_PATH, path + 1, len);
+ }
+
+ len = strlen (file) + 1;
+ pathlen = strlen (path);
+ name = __alloca (pathlen + len + 1);
+ /* Copy the file name at the top. */
+ name = (char *) memcpy (name + pathlen + 1, file, len);
+ /* And add the slash. */
+ *--name = '/';
+
+ p = path;
+ do
+ {
+ char *startp;
+
+ path = p;
+ p = __strchrnul (path, ':');
+
+ if (p == path)
+ /* Two adjacent colons, or a colon at the beginning or the end
+ of `PATH' means to search the current directory. */
+ startp = name + 1;
+ else
+ startp = (char *) memcpy (name - (p - path), path, p - path);
+
+ /* Try to open this file name. */
+ err = child_lookup (startp, O_EXEC, 0, &execfile);
+ switch (err)
+ {
+ case EACCES:
+ case ENOENT:
+ case ESTALE:
+ case ENOTDIR:
+ /* Those errors indicate the file is missing or not executable
+ by us, in which case we want to just try the next path
+ directory. */
+ continue;
+
+ case 0: /* Success! */
+ default:
+ /* Some other error means we found an executable file, but
+ something went wrong executing it; return the error to our
+ caller. */
+ break;
+ }
+
+ // We only get here when we are done looking for the file.
+ break;
+ }
+ while (*p++ != '\0');
+ }
+ if (err)
+ goto out;
+
+ /* Almost there! */
+ {
+ mach_port_t ports[_hurd_nports];
+ struct hurd_userlink ulink_ports[_hurd_nports];
+ char *args = NULL, *env = NULL;
+ size_t argslen = 0, envlen = 0;
+
+ inline error_t exec (file_t file)
+ {
+ return __file_exec (file, task,
+ (__sigismember (&_hurdsig_traced, SIGKILL)
+ ? EXEC_SIGTRAP : 0),
+ args, argslen, env, envlen,
+ dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize,
+ ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports,
+ ints, INIT_INT_MAX,
+ NULL, 0, NULL, 0);
+ }
+
+ /* Now we are out of things that can fail before the file_exec RPC,
+ for which everything else must be prepared. The only thing left
+ to do is packing up the argument and environment strings,
+ and the array of init ports. */
+
+ if (argv != NULL)
+ err = __argz_create (argv, &args, &argslen);
+ if (!err && envp != NULL)
+ err = __argz_create (envp, &env, &envlen);
+
+ /* Load up the ports to give to the new program.
+ Note the loop/switch below must parallel exactly to release refs. */
+ for (i = 0; i < _hurd_nports; ++i)
+ {
+ switch (i)
+ {
+ case INIT_PORT_AUTH:
+ ports[i] = auth;
+ continue;
+ case INIT_PORT_PROC:
+ ports[i] = proc;
+ continue;
+ case INIT_PORT_CRDIR:
+ if (flags & POSIX_SPAWN_RESETIDS)
+ {
+ ports[i] = rcrdir;
+ continue;
+ }
+ break;
+ case INIT_PORT_CWDIR:
+ if (flags & POSIX_SPAWN_RESETIDS)
+ {
+ ports[i] = rcwdir;
+ continue;
+ }
+ break;
+ }
+ ports[i] = _hurd_port_get (&_hurd_ports[i], &ulink_ports[i]);
+ }
+
+ /* Finally, try executing the file we opened. */
+ if (!err)
+ err = exec (execfile);
+ __mach_port_deallocate (__mach_task_self (), execfile);
+
+ if (err == ENOEXEC)
+ {
+ /* The file is accessible but it is not an executable file.
+ Invoke the shell to interpret it as a script. */
+ err = __argz_insert (&args, &argslen, args, _PATH_BSHELL);
+ if (!err)
+ err = child_lookup (_PATH_BSHELL, O_EXEC, 0, &execfile);
+ if (!err)
+ {
+ err = exec (execfile);
+ __mach_port_deallocate (__mach_task_self (), execfile);
+ }
+ }
+
+ /* Release the references just packed up in PORTS.
+ This switch must always parallel the one above that fills PORTS. */
+ for (i = 0; i < _hurd_nports; ++i)
+ {
+ switch (i)
+ {
+ case INIT_PORT_AUTH:
+ case INIT_PORT_PROC:
+ continue;
+ case INIT_PORT_CRDIR:
+ if (flags & POSIX_SPAWN_RESETIDS)
+ continue;
+ break;
+ case INIT_PORT_CWDIR:
+ if (flags & POSIX_SPAWN_RESETIDS)
+ continue;
+ break;
+ }
+ _hurd_port_free (&_hurd_ports[i], &ulink_ports[i], ports[i]);
+ }
+
+ free (args);
+ free (env);
+ }
+
+ /* We did it! We have a child! */
+ if (pid != NULL)
+ *pid = new_pid;
+
+ out:
+ /* Clean up all the references we are now holding. */
+
+ if (task != MACH_PORT_NULL)
+ {
+ if (err)
+ /* We failed after creating the task, so kill it. */
+ __task_terminate (task);
+ __mach_port_deallocate (__mach_task_self (), task);
+ }
+ __mach_port_deallocate (__mach_task_self (), auth);
+ __mach_port_deallocate (__mach_task_self (), proc);
+ if (rcrdir != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), rcrdir);
+ if (rcwdir != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), rcwdir);
+
+ if (ulink_dtable)
+ /* Release references to the file descriptor ports. */
+ for (i = 0; i < dtablesize; ++i)
+ if (dtable[i] != MACH_PORT_NULL)
+ {
+ if (dtable_cells[i] == NULL)
+ __mach_port_deallocate (__mach_task_self (), dtable[i]);
+ else
+ _hurd_port_free (dtable_cells[i], &ulink_dtable[i], dtable[i]);
+ }
+
+ if (err)
+ /* This hack canonicalizes the error code that we return. */
+ err = (__hurd_fail (err), errno);
+
+ return err;
+}
diff --git a/libc/sysdeps/mach/hurd/statfs.c b/libc/sysdeps/mach/hurd/statfs.c
new file mode 100644
index 000000000..65956ae66
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/statfs.c
@@ -0,0 +1,32 @@
+/* statfs -- Return information about the filesystem on which FILE resides.
+ Copyright (C) 1996,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/statfs.h>
+
+#include "statfsconv.c"
+
+/* Return information about the filesystem on which FILE resides. */
+int
+__statfs (const char *file, struct statfs *buf)
+{
+ struct statfs64 buf64;
+ return __statfs64 (file, &buf64) ?: statfs64_conv (buf, &buf64);
+}
+libc_hidden_def (__statfs)
+weak_alias (__statfs, statfs)
diff --git a/libc/sysdeps/mach/hurd/statfs64.c b/libc/sysdeps/mach/hurd/statfs64.c
new file mode 100644
index 000000000..2d5b0363e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/statfs64.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/statfs.h>
+#include <hurd.h>
+
+/* Return information about the filesystem on which FILE resides. */
+int
+__statfs64 (const char *file, struct statfs64 *buf)
+{
+ error_t err;
+ file_t port;
+
+ port = __file_name_lookup (file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_statfs (port, buf);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+weak_alias (__statfs64, statfs64)
diff --git a/libc/sysdeps/mach/hurd/statfsconv.c b/libc/sysdeps/mach/hurd/statfsconv.c
new file mode 100644
index 000000000..57a06c450
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/statfsconv.c
@@ -0,0 +1,49 @@
+/* Convert between `struct statfs' format, and `struct statfs64' format.
+ Copyright (C) 2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/statfs.h>
+#include <errno.h>
+
+static inline int
+statfs64_conv (struct statfs *buf, const struct statfs64 *buf64)
+{
+# define DO(memb) \
+ buf->memb = buf64->memb; \
+ if (sizeof buf->memb != sizeof buf64->memb && buf->memb != buf64->memb) \
+ { \
+ __set_errno (EOVERFLOW); \
+ return -1; \
+ }
+
+ DO (f_type);
+ DO (f_bsize);
+ DO (f_blocks);
+ DO (f_bfree);
+ DO (f_bavail);
+ DO (f_files);
+ DO (f_fsid);
+ DO (f_namelen);
+ DO (f_favail);
+ DO (f_frsize);
+ DO (f_flag);
+
+# undef DO
+
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/statvfs.c b/libc/sysdeps/mach/hurd/statvfs.c
new file mode 100644
index 000000000..759a7cfe4
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/statvfs.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+int
+statvfs (const char *file, struct statvfs *buf)
+{
+ /* `struct statvfs' is in fact identical to `struct statfs' so we
+ can simply call statfs. */
+ return __statfs (file, (struct statfs *)buf);
+}
+libc_hidden_def (statvfs)
diff --git a/libc/sysdeps/mach/hurd/statvfs64.c b/libc/sysdeps/mach/hurd/statvfs64.c
new file mode 100644
index 000000000..6f1940772
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/statvfs64.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+int
+statvfs64 (const char *file, struct statvfs64 *buf)
+{
+ /* `struct statvfs64' is in fact identical to `struct statfs64' so
+ we can simply call statfs64. */
+ return __statfs64 (file, (struct statfs64 *)buf);
+}
diff --git a/libc/sysdeps/mach/hurd/symlink.c b/libc/sysdeps/mach/hurd/symlink.c
new file mode 100644
index 000000000..857e236b8
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/symlink.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/paths.h>
+#include <fcntl.h>
+
+/* Make a link to FROM called TO. */
+int
+__symlink (from, to)
+ const char *from;
+ const char *to;
+{
+ error_t err;
+ file_t dir, node;
+ char *name;
+ const size_t len = strlen (from) + 1;
+ char buf[sizeof (_HURD_SYMLINK) + len];
+
+ /* A symlink is a file whose translator is "/hurd/symlink\0target\0". */
+
+ memcpy (buf, _HURD_SYMLINK, sizeof (_HURD_SYMLINK));
+ memcpy (&buf[sizeof (_HURD_SYMLINK)], from, len);
+
+ dir = __file_name_split (to, &name);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ /* Create a new, unlinked node in the target directory. */
+ err = __dir_mkfile (dir, O_WRITE, 0777 & ~_hurd_umask, &node);
+
+ if (! err)
+ /* Set the node's translator to make it a symlink. */
+ err = __file_set_translator (node,
+ FS_TRANS_EXCL|FS_TRANS_SET,
+ FS_TRANS_EXCL|FS_TRANS_SET, 0,
+ buf, sizeof (_HURD_SYMLINK) + len,
+ MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
+
+ if (! err)
+ /* Link the node, now a valid symlink, into the target directory. */
+ err = __dir_link (dir, node, name, 1);
+
+ __mach_port_deallocate (__mach_task_self (), dir);
+ __mach_port_deallocate (__mach_task_self (), node);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__symlink, symlink)
diff --git a/libc/sysdeps/mach/hurd/symlinkat.c b/libc/sysdeps/mach/hurd/symlinkat.c
new file mode 100644
index 000000000..9a51c66d8
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/symlinkat.c
@@ -0,0 +1,74 @@
+/* Create a symbolic link named relative to an open directory. Hurd version.
+ Copyright (C) 1991,1992,1993,1994,1995,1996,1997,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/paths.h>
+#include <hurd/fd.h>
+#include <string.h>
+
+
+/* Make a link to FROM called TO relative to FD. */
+int
+symlinkat (from, fd, to)
+ const char *from;
+ int fd;
+ const char *to;
+{
+ error_t err;
+ file_t dir, node;
+ char *name;
+ const size_t len = strlen (from) + 1;
+ char buf[sizeof (_HURD_SYMLINK) + len];
+
+ /* A symlink is a file whose translator is "/hurd/symlink\0target\0". */
+
+ memcpy (buf, _HURD_SYMLINK, sizeof (_HURD_SYMLINK));
+ memcpy (&buf[sizeof (_HURD_SYMLINK)], from, len);
+
+ dir = __file_name_split_at (fd, to, &name);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ /* Create a new, unlinked node in the target directory. */
+ err = __dir_mkfile (dir, O_WRITE, 0777 & ~_hurd_umask, &node);
+
+ if (! err)
+ /* Set the node's translator to make it a symlink. */
+ err = __file_set_translator (node,
+ FS_TRANS_EXCL|FS_TRANS_SET,
+ FS_TRANS_EXCL|FS_TRANS_SET, 0,
+ buf, sizeof (_HURD_SYMLINK) + len,
+ MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
+
+ if (! err)
+ /* Link the node, now a valid symlink, into the target directory. */
+ err = __dir_link (dir, node, name, 1);
+
+ __mach_port_deallocate (__mach_task_self (), dir);
+ __mach_port_deallocate (__mach_task_self (), node);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/sync.c b/libc/sysdeps/mach/hurd/sync.c
new file mode 100644
index 000000000..4a97e48dd
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sync.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991,1992,1993,1994,1997,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Make all changes done to all files actually appear on disk. */
+void
+sync ()
+{
+ /* This is not actually synchronous; we don't wait. */
+ error_t err = __USEPORT (CRDIR, __file_syncfs (port, 0, 1));
+ if (err)
+ (void) __hurd_fail (err);
+}
diff --git a/libc/sysdeps/mach/hurd/sys/param.h b/libc/sysdeps/mach/hurd/sys/param.h
new file mode 100644
index 000000000..699ba3510
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/sys/param.h
@@ -0,0 +1,132 @@
+/* Copyright (C) 1993, 1994, 1995, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file is deprecated and is provided only for compatibility with
+ Unix systems. It is unwise to include this file on programs which
+ are intended only for GNU systems.
+
+ Parts from:
+
+ * Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)param.h 7.23 (Berkeley) 5/6/91
+ */
+
+
+#ifndef _SYS_PARAM_H
+
+#define _SYS_PARAM_H 1
+#include <features.h>
+
+#define __need_NULL
+#include <stddef.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <signal.h>
+#include <endian.h>
+#include <limits.h>
+#ifdef notyet
+# include <ufs/param.h>
+#endif
+
+
+/* What versions of BSD we are compatible with. */
+#define BSD 199306 /* System version (year & month). */
+#define BSD4_3 1
+#define BSD4_4 1
+
+#define GNU 1994100 /* GNU version (year, month, and release). */
+
+
+/* BSD names for some <limits.h> values. We do not define the BSD names
+ for the values which are not statically limited, such as NOFILE. */
+
+#define NBBY CHAR_BIT
+#define NGROUPS NGROUPS_MAX
+#define MAXSYMLINKS SYMLOOP_MAX
+#define CANBSIZ MAX_CANON /* XXX ? */
+
+/* ARG_MAX is unlimited, but we define NCARGS for BSD programs that want to
+ compare against some fixed limit. */
+#define NCARGS INT_MAX
+
+/* There is nothing quite equivalent in GNU to Unix "mounts", but there is
+ no limit on the number of simultaneously attached filesystems. */
+#define NMOUNT INT_MAX
+
+
+/* Magical constants. */
+#define NOGROUP 65535 /* Marker for empty group set member. */
+#define NODEV ((dev_t) -1) /* Non-existent device. */
+
+
+/* Bit map related macros. */
+#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
+#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
+#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+
+/* Macros for counting and rounding. */
+#ifndef howmany
+# define howmany(x, y) (((x)+((y)-1))/(y))
+#endif
+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
+#define powerof2(x) ((((x)-1)&(x))==0)
+
+/* Macros for min/max. */
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
+
+/* Scale factor for scaled integers used to count %cpu time and load avgs.
+
+ The number of CPU `tick's that map to a unique `%age' can be expressed
+ by the formula (1 / (2 ^ (FSHIFT - 11))). The maximum load average that
+ can be calculated (assuming 32 bits) can be closely approximated using
+ the formula (2 ^ (2 * (16 - FSHIFT))) for (FSHIFT < 15). */
+
+#define FSHIFT 11 /* Bits to right of fixed binary point. */
+#define FSCALE (1<<FSHIFT)
+
+#endif /* sys/param.h */
diff --git a/libc/sysdeps/mach/hurd/telldir.c b/libc/sysdeps/mach/hurd/telldir.c
new file mode 100644
index 000000000..8a889f4bf
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/telldir.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1993, 1994, 1995, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include "dirstream.h"
+
+/* Return the current position of DIRP. */
+/* XXX should be __telldir ? */
+long int
+telldir (dirp)
+ DIR *dirp;
+{
+ return dirp->__entry_ptr;
+}
diff --git a/libc/sysdeps/mach/hurd/times.c b/libc/sysdeps/mach/hurd/times.c
new file mode 100644
index 000000000..deab40e5e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/times.c
@@ -0,0 +1,75 @@
+/* Return CPU and real time used by process and its children. Hurd version.
+ Copyright (C) 2001,2002,2003,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/resource.h>
+#include <sys/times.h>
+#include <sys/time.h>
+#include <time.h>
+#include <mach.h>
+#include <mach/task_info.h>
+#include <hurd.h>
+
+static inline clock_t
+clock_from_time_value (const time_value_t *t)
+{
+ return t->seconds * 1000000 + t->microseconds;
+}
+
+/* Store the CPU time used by this process and all its
+ dead children (and their dead children) in BUFFER.
+ Return the elapsed real time, or (clock_t) -1 for errors.
+ All times are in CLK_TCKths of a second. */
+clock_t
+__times (struct tms *tms)
+{
+ struct task_basic_info bi;
+ struct task_thread_times_info tti;
+ mach_msg_type_number_t count;
+ union { time_value_t tvt; struct timeval tv; } now;
+ error_t err;
+
+ count = TASK_BASIC_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_BASIC_INFO,
+ (task_info_t) &bi, &count);
+ if (err)
+ return __hurd_fail (err);
+
+ count = TASK_THREAD_TIMES_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_THREAD_TIMES_INFO,
+ (task_info_t) &tti, &count);
+ if (err)
+ return __hurd_fail (err);
+
+ tms->tms_utime = (clock_from_time_value (&bi.user_time)
+ + clock_from_time_value (&tti.user_time));
+ tms->tms_stime = (clock_from_time_value (&bi.system_time)
+ + clock_from_time_value (&tti.system_time));
+
+ /* XXX This can't be implemented until getrusage(RUSAGE_CHILDREN) can be. */
+ tms->tms_cutime = tms->tms_cstime = 0;
+
+ if (__gettimeofday (&now.tv, NULL) < 0)
+ return -1;
+
+ return (clock_from_time_value (&now.tvt)
+ - clock_from_time_value (&bi.creation_time));
+}
+weak_alias (__times, times)
diff --git a/libc/sysdeps/mach/hurd/tls.h b/libc/sysdeps/mach/hurd/tls.h
new file mode 100644
index 000000000..cce42ef37
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/tls.h
@@ -0,0 +1,77 @@
+/* Definitions for thread-local data handling. Hurd version.
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _TLS_H
+#define _TLS_H
+
+#if defined HAVE_TLS_SUPPORT && !defined ASSEMBLER
+
+# include <stddef.h>
+# include <stdbool.h>
+# include <mach/mig_errors.h>
+# include <mach.h>
+
+
+/* Type for the dtv. */
+typedef union dtv
+{
+ size_t counter;
+ struct
+ {
+ void *val;
+ bool is_static;
+ } pointer;
+} dtv_t;
+
+
+/* Type of the TCB. */
+typedef struct
+{
+ void *tcb; /* Points to this structure. */
+ dtv_t *dtv; /* Vector of pointers to TLS data. */
+ thread_t self; /* This thread's control port. */
+} tcbhead_t;
+
+
+/* This is the size of the initial TCB. */
+# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB. */
+# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+
+/* This is the size of the TCB. */
+# define TLS_TCB_SIZE TLS_INIT_TCB_SIZE /* XXX */
+
+/* Alignment requirements for the TCB. */
+# define TLS_TCB_ALIGN TLS_INIT_TCB_ALIGN /* XXX */
+
+
+/* Install the dtv pointer. The pointer passed is to the element with
+ index -1 which contain the length. */
+# define INSTALL_DTV(descr, dtvp) \
+ ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
+
+/* Return dtv of given thread descriptor. */
+# define GET_DTV(descr) \
+ (((tcbhead_t *) (descr))->dtv)
+
+#endif /* HAVE_TLS_SUPPORT */
+
+
+#endif /* tls.h */
diff --git a/libc/sysdeps/mach/hurd/tmpfile.c b/libc/sysdeps/mach/hurd/tmpfile.c
new file mode 100644
index 000000000..ea32d4a99
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/tmpfile.c
@@ -0,0 +1,69 @@
+/* Open a stdio stream on an anonymous temporary file. Hurd version.
+ Copyright (C) 2001,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <hurd.h>
+#include <hurd/fs.h>
+#include <hurd/fd.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <iolibio.h>
+
+/* This returns a new stream opened on a temporary file (generated
+ by tmpnam). The file is opened with mode "w+b" (binary read/write).
+ If we couldn't generate a unique filename or the file couldn't
+ be opened, NULL is returned. */
+FILE *
+__tmpfile (void)
+{
+ error_t err;
+ file_t file;
+ int fd;
+ FILE *f;
+
+ /* Get a port to the directory that will contain the file. */
+ const char *dirname = __secure_getenv ("TMPDIR") ?: P_tmpdir;
+ file_t dir = __file_name_lookup (dirname, 0, 0);
+ if (dir == MACH_PORT_NULL)
+ return NULL;
+
+ /* Create an unnamed file in the temporary directory. */
+ err = __dir_mkfile (dir, O_RDWR, S_IRUSR | S_IWUSR, &file);
+ __mach_port_deallocate (__mach_task_self (), dir);
+ if (err)
+ return __hurd_fail (err), NULL;
+
+ /* Get a file descriptor for that port. POSIX.1 requires that streams
+ returned by tmpfile allocate file descriptors as fopen would. */
+ fd = _hurd_intern_fd (file, O_RDWR, 1); /* dealloc on error */
+ if (fd < 0)
+ return NULL;
+
+ /* Open a stream on the unnamed file.
+ It will cease to exist when this stream is closed. */
+ if ((f = INTUSE(_IO_fdopen) (fd, "w+b")) == NULL)
+ __close (fd);
+
+ return f;
+}
+
+#include <shlib-compat.h>
+versioned_symbol (libc, __tmpfile, tmpfile, GLIBC_2_1);
+
+weak_alias (__tmpfile, tmpfile64)
diff --git a/libc/sysdeps/mach/hurd/tmpfile64.c b/libc/sysdeps/mach/hurd/tmpfile64.c
new file mode 100644
index 000000000..094304a07
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/tmpfile64.c
@@ -0,0 +1 @@
+/* tmpfile64 is an alias for tmpfile, defined in tmpfile.c. */
diff --git a/libc/sysdeps/mach/hurd/truncate.c b/libc/sysdeps/mach/hurd/truncate.c
new file mode 100644
index 000000000..aaca1b2fc
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/truncate.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1991,92,93,94,95,97,98,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Truncate FILE_NAME to LENGTH bytes. */
+int
+__truncate (file_name, length)
+ const char *file_name;
+ off_t length;
+{
+ error_t err;
+ file_t file = __file_name_lookup (file_name, O_WRITE, 0);
+
+ if (file == MACH_PORT_NULL)
+ return -1;
+
+ err = __file_set_size (file, length);
+ __mach_port_deallocate (__mach_task_self (), file);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+weak_alias (__truncate, truncate)
diff --git a/libc/sysdeps/mach/hurd/ttyname.c b/libc/sysdeps/mach/hurd/ttyname.c
new file mode 100644
index 000000000..927851e2e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/ttyname.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/term.h>
+#include <hurd/fd.h>
+
+/* Return the pathname of the terminal FD is open on, or NULL on errors.
+ The returned storage is good only until the next call to this function. */
+char *
+ttyname (int fd)
+{
+ error_t err;
+ static char nodename[1024]; /* XXX */
+
+ nodename[0] = '\0';
+ if (err = HURD_DPORT_USE (fd, __term_get_nodename (port, nodename)))
+ return __hurd_dfail (fd, err), NULL;
+
+ return nodename;
+}
diff --git a/libc/sysdeps/mach/hurd/ttyname_r.c b/libc/sysdeps/mach/hurd/ttyname_r.c
new file mode 100644
index 000000000..7313b9afc
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/ttyname_r.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 1994, 95, 96, 98 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/term.h>
+#include <hurd/fd.h>
+
+/* Store at most BUFLEN characters of the pathname of the terminal FD is
+ open on in BUF. Return 0 on success, -1 otherwise. */
+int
+__ttyname_r (int fd, char *buf, size_t buflen)
+{
+ error_t err;
+ char nodename[1024]; /* XXX */
+ size_t len;
+
+ nodename[0] = '\0';
+ if (err = HURD_DPORT_USE (fd, __term_get_nodename (port, nodename)))
+ return __hurd_dfail (fd, err), -1;
+
+ len = strlen (nodename) + 1;
+ if (len > buflen)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ memcpy (buf, nodename, len);
+ return 0;
+}
+
+weak_alias (__ttyname_r, ttyname_r)
diff --git a/libc/sysdeps/mach/hurd/umask.c b/libc/sysdeps/mach/hurd/umask.c
new file mode 100644
index 000000000..1a6d3adca
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/umask.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991, 1992, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Set the file creation mask to MASK, returning the old mask. */
+mode_t
+__umask (mask)
+ mode_t mask;
+{
+ mode_t omask;
+ mask &= 0777;
+ omask = _hurd_umask;
+ _hurd_umask = mask;
+ return omask;
+}
+
+weak_alias (__umask, umask)
diff --git a/libc/sysdeps/mach/hurd/uname.c b/libc/sysdeps/mach/hurd/uname.c
new file mode 100644
index 000000000..8077e1497
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/uname.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1992,93,94,96,97,2000,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <sys/utsname.h>
+#include <hurd.h>
+#include <hurd/startup.h>
+
+int
+__uname (struct utsname *uname)
+{
+ error_t err;
+
+ if (err = __USEPORT (PROC, __proc_uname (port, uname)))
+ return __hurd_fail (err);
+
+ /* Fill in the hostname, which the proc server doesn't know. */
+ err = errno;
+ if (__gethostname (uname->nodename, sizeof uname->nodename) < 0)
+ {
+ if (errno == ENAMETOOLONG)
+ /* Ignore the error of the buffer being too small.
+ It is of fixed size, nothing to do about it. */
+ errno = err;
+ else
+ return -1;
+ }
+
+ return 0;
+}
+weak_alias (__uname, uname)
+libc_hidden_def (__uname)
+libc_hidden_def (uname)
diff --git a/libc/sysdeps/mach/hurd/unlink.c b/libc/sysdeps/mach/hurd/unlink.c
new file mode 100644
index 000000000..959c2f8d0
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/unlink.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1991,92,93,94,95,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+
+
+/* Remove the link named NAME. */
+int
+__unlink (name)
+ const char *name;
+{
+ error_t err;
+ file_t dir;
+ const char *file;
+
+ dir = __directory_name_split (name, (char **) &file);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ err = __dir_unlink (dir, file);
+ __mach_port_deallocate (__mach_task_self (), dir);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__unlink, unlink)
diff --git a/libc/sysdeps/mach/hurd/unlinkat.c b/libc/sysdeps/mach/hurd/unlinkat.c
new file mode 100644
index 000000000..7740c5a29
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/unlinkat.c
@@ -0,0 +1,55 @@
+/* unlinkat -- Remove a name relative to an open directory. Hurd version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+
+/* Remove the link named NAME. */
+int
+unlinkat (fd, name, flag)
+ int fd;
+ const char *name;
+ int flag;
+{
+ error_t err;
+ file_t dir;
+ const char *file;
+
+ if ((flag &~ AT_REMOVEDIR) != 0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ dir = __directory_name_split_at (fd, name, (char **) &file);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ err = ((flag & AT_REMOVEDIR) ? __dir_rmdir : __dir_unlink) (dir, file);
+ __mach_port_deallocate (__mach_task_self (), dir);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/utimes.c b/libc/sysdeps/mach/hurd/utimes.c
new file mode 100644
index 000000000..74f3a342f
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/utimes.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1991-1995, 97, 99, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/time.h>
+#include <errno.h>
+#include <stddef.h>
+#include <hurd.h>
+
+/* Change the access time of FILE to TVP[0] and
+ the modification time of FILE to TVP[1]. */
+int
+__utimes (file, tvp)
+ const char *file;
+ const struct timeval tvp[2];
+{
+ struct timeval timevals[2];
+ error_t err;
+ file_t port;
+
+ if (tvp == NULL)
+ {
+ /* Setting the number of microseconds to `-1' tells the
+ underlying filesystems to use the current time. */
+ timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1;
+ tvp = timevals;
+ }
+
+ port = __file_name_lookup (file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_utimes (port,
+ *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__utimes, utimes)
diff --git a/libc/sysdeps/mach/hurd/wait4.c b/libc/sysdeps/mach/hurd/wait4.c
new file mode 100644
index 000000000..d9e23412e
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/wait4.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1993,94,95,96,97,98,99,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/port.h>
+
+pid_t
+__wait4 (pid_t pid, __WAIT_STATUS_DEFN stat_loc, int options,
+ struct rusage *usage)
+{
+ pid_t dead;
+ error_t err;
+ struct rusage ignored;
+ int sigcode;
+ int dummy;
+
+ err = __USEPORT (PROC, __proc_wait (port, pid, options,
+ stat_loc ?: &dummy, &sigcode,
+ usage ?: &ignored, &dead));
+ switch (err)
+ {
+ case 0: /* Got a child. */
+ return dead;
+ case EAGAIN:
+ /* The RPC returns this error when the WNOHANG flag is set and no
+ selected children are dead (but some are living). In that
+ situation, our return value is zero. (The RPC can't return zero
+ for DEAD without also returning some garbage for the other out
+ parameters, so an error return is much more natural here. Hence
+ the difference between the RPC and the POSIX.1 interface. */
+ return (pid_t) 0;
+ default:
+ return (pid_t) __hurd_fail (err);
+ }
+}
+
+weak_alias (__wait4, wait4)
diff --git a/libc/sysdeps/mach/hurd/write.c b/libc/sysdeps/mach/hurd/write.c
new file mode 100644
index 000000000..514e46093
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/write.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991-1999,2001,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd/fd.h>
+
+ssize_t
+__libc_write (int fd, const void *buf, size_t nbytes)
+{
+ error_t err = HURD_FD_USE (fd, _hurd_fd_write (descriptor,
+ buf, &nbytes, -1));
+ return err ? __hurd_dfail (fd, err) : nbytes;
+}
+libc_hidden_def (__libc_write)
+weak_alias (__libc_write, __write)
+libc_hidden_weak (__write)
+weak_alias (__libc_write, write)
diff --git a/libc/sysdeps/mach/hurd/xmknod.c b/libc/sysdeps/mach/hurd/xmknod.c
new file mode 100644
index 000000000..5f40188fb
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/xmknod.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991,1992,1993,1994,1995,1996,1999,2002,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+/* Create a device file named FILE_NAME, with permission and special bits MODE
+ and device number DEV (which can be constructed from major and minor
+ device numbers with the `makedev' macro above). */
+int
+__xmknod (int vers, const char *file_name, mode_t mode, dev_t *dev)
+{
+ return __xmknodat (vers, AT_FDCWD, file_name, mode, dev);
+}
+libc_hidden_def (__xmknod)
diff --git a/libc/sysdeps/mach/hurd/xmknodat.c b/libc/sysdeps/mach/hurd/xmknodat.c
new file mode 100644
index 000000000..b2227593c
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/xmknodat.c
@@ -0,0 +1,118 @@
+/* Create a device file relative to an open directory. Hurd version.
+ Copyright (C) 1991,1992,1993,1994,1995,1996,1999,2002,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/paths.h>
+#include <fcntl.h>
+#include "stdio-common/_itoa.h"
+#include <string.h>
+#include <sys/types.h>
+
+/* Create a device file named PATH relative to FD, with permission and
+ special bits MODE and device number DEV (which can be constructed
+ from major and minor device numbers with the `makedev' macro
+ above). */
+int
+__xmknodat (int vers, int fd, const char *path, mode_t mode, dev_t *dev)
+{
+ error_t err;
+ file_t dir, node;
+ char *name;
+ char buf[100], *bp;
+ const char *translator;
+ size_t len;
+
+ if (vers != _MKNOD_VER)
+ return __hurd_fail (EINVAL);
+
+ if (S_ISCHR (mode))
+ {
+ translator = _HURD_CHRDEV;
+ len = sizeof (_HURD_CHRDEV);
+ }
+ else if (S_ISBLK (mode))
+ {
+ translator = _HURD_BLKDEV;
+ len = sizeof (_HURD_BLKDEV);
+ }
+ else if (S_ISFIFO (mode))
+ {
+ translator = _HURD_FIFO;
+ len = sizeof (_HURD_FIFO);
+ }
+ else if (S_ISREG (mode))
+ {
+ translator = NULL;
+ len = 0;
+ }
+ else
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (translator != NULL && ! S_ISFIFO (mode))
+ {
+ /* We set the translator to "ifmt\0major\0minor\0", where IFMT
+ depends on the S_IFMT bits of our MODE argument, and MAJOR and
+ MINOR are ASCII decimal (octal or hex would do as well)
+ representations of our arguments. Thus the convention is that
+ CHRDEV and BLKDEV translators are invoked with two non-switch
+ arguments, giving the major and minor device numbers in %i format. */
+
+ bp = buf + sizeof (buf);
+ *--bp = '\0';
+ bp = _itoa (minor (*dev), bp, 10, 0);
+ *--bp = '\0';
+ bp = _itoa (major (*dev), bp, 10, 0);
+ memcpy (bp - len, translator, len);
+ translator = bp - len;
+ len = buf + sizeof (buf) - translator;
+ }
+
+ dir = __file_name_split_at (fd, path, &name);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ /* Create a new, unlinked node in the target directory. */
+ err = __dir_mkfile (dir, O_WRITE, (mode & ~S_IFMT) & ~_hurd_umask, &node);
+
+ if (! err && translator != NULL)
+ /* Set the node's translator to make it a device. */
+ err = __file_set_translator (node,
+ FS_TRANS_EXCL | FS_TRANS_SET,
+ FS_TRANS_EXCL | FS_TRANS_SET, 0,
+ translator, len,
+ MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
+
+ if (! err)
+ /* Link the node, now a valid device, into the target directory. */
+ err = __dir_link (dir, node, name, 1);
+
+ __mach_port_deallocate (__mach_task_self (), dir);
+ __mach_port_deallocate (__mach_task_self (), node);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/libc/sysdeps/mach/hurd/xstat.c b/libc/sysdeps/mach/hurd/xstat.c
new file mode 100644
index 000000000..97719b082
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/xstat.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1992,93,94,95,96,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/stat.h>
+
+#include "xstatconv.c"
+
+/* Get file information about FILE in BUF. */
+int
+__xstat (int vers, const char *file, struct stat *buf)
+{
+ struct stat64 buf64;
+ return __xstat64 (vers, file, &buf64) ?: xstat64_conv (buf, &buf64);
+}
+hidden_def (__xstat)
+weak_alias (__xstat, _xstat)
diff --git a/libc/sysdeps/mach/hurd/xstat64.c b/libc/sysdeps/mach/hurd/xstat64.c
new file mode 100644
index 000000000..572ae4e59
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/xstat64.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 2000,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef RTLD_STAT64 /* dl-xstat64.c, but we don't want it. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Get information about the file descriptor FD in BUF. */
+int
+__xstat64 (int vers, const char *file, struct stat64 *buf)
+{
+ error_t err;
+ file_t port;
+
+ if (vers != _STAT_VER)
+ return __hurd_fail (EINVAL);
+
+ port = __file_name_lookup (file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __io_stat (port, buf);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+hidden_def (__xstat64)
+
+#endif
diff --git a/libc/sysdeps/mach/hurd/xstatconv.c b/libc/sysdeps/mach/hurd/xstatconv.c
new file mode 100644
index 000000000..e28643cd5
--- /dev/null
+++ b/libc/sysdeps/mach/hurd/xstatconv.c
@@ -0,0 +1,68 @@
+/* Convert between `struct stat' format, and `struct stat64' format.
+ Copyright (C) 2000,01,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/stat.h>
+
+static inline int
+xstat64_conv (struct stat *buf, const struct stat64 *buf64)
+{
+ if (sizeof *buf == sizeof *buf64
+ && sizeof buf->st_ino == sizeof buf64->st_ino
+ && sizeof buf->st_size == sizeof buf64->st_size
+ && sizeof buf->st_blocks == sizeof buf64->st_blocks)
+ {
+ *buf = *(struct stat *) buf64;
+ return 0;
+ }
+
+ buf->st_fstype = buf64->st_fstype;
+ buf->st_fsid = buf64->st_fsid;
+ buf->st_ino = buf64->st_ino;
+ buf->st_gen = buf64->st_gen;
+ buf->st_rdev = buf64->st_rdev;
+ buf->st_mode = buf64->st_mode;
+ buf->st_nlink = buf64->st_nlink;
+ buf->st_uid = buf64->st_uid;
+ buf->st_gid = buf64->st_gid;
+ buf->st_size = buf64->st_size;
+ buf->st_atime = buf64->st_atime;
+ buf->st_atime_usec = buf64->st_atime_usec;
+ buf->st_mtime = buf64->st_mtime;
+ buf->st_mtime_usec = buf64->st_mtime_usec;
+ buf->st_ctime = buf64->st_ctime;
+ buf->st_ctime_usec = buf64->st_ctime_usec;
+ buf->st_blksize = buf64->st_blksize;
+ buf->st_blocks = buf64->st_blocks;
+ buf->st_author = buf64->st_author;
+ buf->st_flags = buf64->st_flags;
+
+ if ((sizeof buf->st_ino != sizeof buf64->st_ino
+ && buf->st_ino != buf64->st_ino)
+ || (sizeof buf->st_size != sizeof buf64->st_size
+ && buf->st_size != buf64->st_size)
+ || (sizeof buf->st_blocks != sizeof buf64->st_blocks
+ && buf->st_blocks != buf64->st_blocks))
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/libc/sysdeps/mach/i386/machine-lock.h b/libc/sysdeps/mach/i386/machine-lock.h
new file mode 100644
index 000000000..7c23fba8c
--- /dev/null
+++ b/libc/sysdeps/mach/i386/machine-lock.h
@@ -0,0 +1,66 @@
+/* Machine-specific definition for spin locks. i386 version.
+ Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MACHINE_LOCK_H
+#define _MACHINE_LOCK_H
+
+/* The type of a spin lock variable. */
+
+typedef __volatile int __spin_lock_t;
+
+/* Value to initialize `__spin_lock_t' variables to. */
+
+#define __SPIN_LOCK_INITIALIZER 0
+
+
+#ifndef _EXTERN_INLINE
+#define _EXTERN_INLINE extern __inline
+#endif
+
+/* Unlock LOCK. */
+
+_EXTERN_INLINE void
+__spin_unlock (__spin_lock_t *__lock)
+{
+ register int __unlocked;
+ __asm__ __volatile ("xchgl %0, %1"
+ : "=&r" (__unlocked), "=m" (*__lock) : "0" (0));
+}
+
+/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */
+
+_EXTERN_INLINE int
+__spin_try_lock (__spin_lock_t *__lock)
+{
+ register int __locked;
+ __asm__ __volatile ("xchgl %0, %1"
+ : "=&r" (__locked), "=m" (*__lock) : "0" (1));
+ return !__locked;
+}
+
+/* Return nonzero if LOCK is locked. */
+
+_EXTERN_INLINE int
+__spin_lock_locked (__spin_lock_t *__lock)
+{
+ return *__lock != 0;
+}
+
+
+#endif /* machine-lock.h */
diff --git a/libc/sysdeps/mach/i386/machine-sp.h b/libc/sysdeps/mach/i386/machine-sp.h
new file mode 100644
index 000000000..536f69021
--- /dev/null
+++ b/libc/sysdeps/mach/i386/machine-sp.h
@@ -0,0 +1,31 @@
+/* Machine-specific function to return the stack pointer. i386 version.
+ Copyright (C) 1994,97,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MACHINE_SP_H
+#define _MACHINE_SP_H
+
+/* Return the current stack pointer. */
+
+#define __thread_stack_pointer() ({ \
+ void *__sp__; \
+ __asm__ ("movl %%esp, %0" : "=r" (__sp__)); \
+ __sp__; \
+})
+
+#endif /* machine-sp.h */
diff --git a/libc/sysdeps/mach/i386/syscall.S b/libc/sysdeps/mach/i386/syscall.S
new file mode 100644
index 000000000..ff50e971c
--- /dev/null
+++ b/libc/sysdeps/mach/i386/syscall.S
@@ -0,0 +1,27 @@
+/* Copyright (C) 1993, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY (syscall)
+ popl %ecx /* Pop return address into %ecx. */
+ popl %eax /* Pop syscall number into %eax. */
+ pushl %ecx /* Push back return address. */
+ .byte 0x9a, 0, 0, 0, 0, 7, 0 /* lcall $7, $0 -- gas bug */
+ ret
+END (syscall)
diff --git a/libc/sysdeps/mach/i386/sysdep.h b/libc/sysdeps/mach/i386/sysdep.h
new file mode 100644
index 000000000..1f138f475
--- /dev/null
+++ b/libc/sysdeps/mach/i386/sysdep.h
@@ -0,0 +1,60 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define LOSE asm volatile ("hlt")
+
+#define SNARF_ARGS(entry_sp, argc, argv, envp) \
+ do \
+ { \
+ register char **p; \
+ argc = (int) *entry_sp; \
+ argv = (char **) (entry_sp + 1); \
+ p = argv; \
+ while (*p++ != NULL) \
+ ; \
+ if (p >= (char **) argv[0]) \
+ --p; \
+ envp = p; \
+ } while (0)
+
+#define CALL_WITH_SP(fn, info, sp) \
+ do { \
+ void **ptr = (void **) sp; \
+ *--(__typeof (info) *) ptr = info; \
+ ptr[-1] = ptr; \
+ --ptr; \
+ asm volatile ("movl %0, %%esp; call %1" : : \
+ "g" (ptr), "m" (*(long int *) (fn)) : "%esp"); \
+ } while (0)
+
+#define RETURN_TO(sp, pc, retval) \
+ asm volatile ("movl %0, %%esp; jmp %*%1 # %2" \
+ : : "g" (sp), "r" (pc), "a" (retval))
+
+
+#define STACK_GROWTH_DOWN
+
+/* Get the machine-independent Mach definitions. */
+#include <sysdeps/mach/sysdep.h>
+
+
+/* This should be rearranged, but at the moment this file provides
+ the most useful definitions for assembler syntax details. */
+#undef ENTRY
+#undef ALIGN
+#include <sysdeps/unix/i386/sysdep.h>
diff --git a/libc/sysdeps/mach/i386/thread_state.h b/libc/sysdeps/mach/i386/thread_state.h
new file mode 100644
index 000000000..cefea2cfb
--- /dev/null
+++ b/libc/sysdeps/mach/i386/thread_state.h
@@ -0,0 +1,38 @@
+/* Mach thread state definitions for machine-independent code. i386 version.
+ Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <mach/machine/thread_status.h>
+
+#define MACHINE_THREAD_STATE_FLAVOR i386_THREAD_STATE
+#define MACHINE_THREAD_STATE_COUNT i386_THREAD_STATE_COUNT
+
+#define machine_thread_state i386_thread_state
+
+#define PC eip
+#define SP uesp
+#define SYSRETURN eax
+
+struct machine_thread_all_state
+ {
+ int set; /* Mask of bits (1 << FLAVOR). */
+ struct i386_thread_state basic;
+ struct i386_float_state fpu;
+ };
+
+#include <sysdeps/mach/thread_state.h>
diff --git a/libc/sysdeps/mach/mprotect.c b/libc/sysdeps/mach/mprotect.c
new file mode 100644
index 000000000..a003cd434
--- /dev/null
+++ b/libc/sysdeps/mach/mprotect.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <mach.h>
+
+/* Change the memory protection of the region starting at ADDR and
+ extending LEN bytes to PROT. Returns 0 if successful, -1 for errors
+ (and sets errno). */
+
+int
+__mprotect (__ptr_t addr, size_t len, int prot)
+{
+ kern_return_t err;
+ vm_prot_t vmprot;
+
+ vmprot = VM_PROT_NONE;
+ if (prot & PROT_READ)
+ vmprot |= VM_PROT_READ;
+ if (prot & PROT_WRITE)
+ vmprot |= VM_PROT_WRITE;
+ if (prot & PROT_EXEC)
+ vmprot |= VM_PROT_EXECUTE;
+
+ if (err = __vm_protect (__mach_task_self (),
+ (vm_address_t) addr, (vm_size_t) len,
+ 0, vmprot))
+ {
+ errno = err;
+ return -1;
+ }
+ return 0;
+}
+weak_alias (__mprotect, mprotect)
diff --git a/libc/sysdeps/mach/msync.c b/libc/sysdeps/mach/msync.c
new file mode 100644
index 000000000..567143f72
--- /dev/null
+++ b/libc/sysdeps/mach/msync.c
@@ -0,0 +1,57 @@
+/* msync -- Synchronize mapped memory to external storage. Mach version.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <mach.h>
+
+/* Some Mach variants have vm_msync and some don't. Those that have it
+ define the VM_SYNC_* bits when we include <mach/mach_types.h>. */
+
+#ifndef VM_SYNC_SYNCHRONOUS
+# include <misc/msync.c>
+#else
+
+/* Synchronize the region starting at ADDR and extending LEN bytes with the
+ file it maps. Filesystem operations on a file being mapped are
+ unpredictable before this is done. */
+
+int
+msync (__ptr_t addr, size_t len, int flags)
+{
+ vm_sync_t sync_flags = 0;
+ kern_return_t err;
+
+ if (flags & MS_SYNC)
+ sync_flags |= VM_SYNC_SYNCHRONOUS;
+ if (flags & MS_ASYNC)
+ sync_flags |= VM_SYNC_ASYNCHRONOUS;
+ if (flags & MS_INVALIDATE)
+ sync_flags |= VM_SYNC_INVALIDATE;
+
+ if (err = __vm_msync (__mach_task_self (),
+ (vm_address_t) addr, (vm_size_t) len, sync_flags))
+ {
+ errno = err;
+ return -1;
+ }
+ return 0;
+}
+#endif
diff --git a/libc/sysdeps/mach/munmap.c b/libc/sysdeps/mach/munmap.c
new file mode 100644
index 000000000..03a9c6070
--- /dev/null
+++ b/libc/sysdeps/mach/munmap.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <mach.h>
+
+/* Deallocate any mapping for the region starting at ADDR and extending LEN
+ bytes. Returns 0 if successful, -1 for errors (and sets errno). */
+
+int
+__munmap (__ptr_t addr, size_t len)
+{
+ kern_return_t err;
+ if (err = __vm_deallocate (__mach_task_self (),
+ (vm_address_t) addr, (vm_size_t) len))
+ {
+ errno = err;
+ return -1;
+ }
+ return 0;
+}
+
+weak_alias (__munmap, munmap)
diff --git a/libc/sysdeps/mach/nanosleep.c b/libc/sysdeps/mach/nanosleep.c
new file mode 100644
index 000000000..e433adb8b
--- /dev/null
+++ b/libc/sysdeps/mach/nanosleep.c
@@ -0,0 +1,54 @@
+/* nanosleep -- sleep for a period specified with a struct timespec
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <mach.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+int
+__nanosleep (const struct timespec *requested_time,
+ struct timespec *remaining)
+{
+ mach_port_t recv;
+ struct timeval before, after;
+ const mach_msg_timeout_t ms
+ = requested_time->tv_sec * 1000
+ + (requested_time->tv_nsec + 999999) / 1000000;
+
+ recv = __mach_reply_port ();
+
+ if (remaining && __gettimeofday (&before, NULL) < 0)
+ return -1;
+ (void) __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
+ 0, 0, recv, ms, MACH_PORT_NULL);
+ __mach_port_destroy (mach_task_self (), recv);
+ if (remaining && __gettimeofday (&after, NULL) < 0)
+ return -1;
+
+ if (remaining)
+ {
+ timersub (&after, &before, &after);
+ TIMEVAL_TO_TIMESPEC (&after, remaining);
+ }
+
+ return 0;
+}
+libc_hidden_def (__nanosleep)
+weak_alias (__nanosleep, nanosleep)
diff --git a/libc/sysdeps/mach/pagecopy.h b/libc/sysdeps/mach/pagecopy.h
new file mode 100644
index 000000000..1d0c9d135
--- /dev/null
+++ b/libc/sysdeps/mach/pagecopy.h
@@ -0,0 +1,36 @@
+/* Macros for copying by pages; used in memcpy, memmove. Mach version.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <mach.h>
+
+/* Threshold at which vm_copy is more efficient than well-optimized copying
+ by words. This parameter should be tuned as necessary. */
+#define PAGE_THRESHOLD (2 * PAGE_SIZE) /* XXX ? */
+
+#define PAGE_SIZE __vm_page_size
+#define PAGE_COPY_FWD(dstp, srcp, nbytes_left, nbytes) \
+ ((nbytes_left) = ((nbytes) - \
+ (__vm_copy (__mach_task_self (), \
+ (vm_address_t) srcp, trunc_page (nbytes), \
+ (vm_address_t) dstp) == KERN_SUCCESS \
+ ? trunc_page (nbytes) \
+ : 0)))
+
+/* Get the generic macro. */
+#include <sysdeps/generic/pagecopy.h>
diff --git a/libc/sysdeps/mach/powerpc/machine-lock.h b/libc/sysdeps/mach/powerpc/machine-lock.h
new file mode 100644
index 000000000..cba6b0a6e
--- /dev/null
+++ b/libc/sysdeps/mach/powerpc/machine-lock.h
@@ -0,0 +1,78 @@
+/* Machine-specific definition for spin locks. PowerPC version.
+ Copyright (C) 1994,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MACHINE_LOCK_H
+#define _MACHINE_LOCK_H
+
+/* The type of a spin lock variable. */
+
+typedef __volatile long int __spin_lock_t;
+
+/* Value to initialize `__spin_lock_t' variables to. */
+
+#define __SPIN_LOCK_INITIALIZER 0L
+
+
+#ifndef _EXTERN_INLINE
+#define _EXTERN_INLINE extern __inline
+#endif
+
+/* Unlock LOCK. */
+
+_EXTERN_INLINE void
+__spin_unlock (__spin_lock_t *__lock)
+{
+ long int __locked;
+ __asm__ __volatile__ ("\
+0: lwarx %0,0,%1\n\
+ stwcx. %2,0,%1\n\
+ bne- 0b\n\
+" : "=&r" (__locked) : "r" (__lock), "r" (0) : "cr0");
+}
+
+/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */
+
+_EXTERN_INLINE int
+__spin_try_lock (register __spin_lock_t *__lock)
+{
+ long int __rtn;
+ __asm__ __volatile__ ("\
+0: lwarx %0,0,%1\n\
+ stwcx. %2,0,%1\n\
+ bne- 0b\n\
+" : "=&r" (__rtn) : "r" (__lock), "r" (1) : "cr0");
+ return !__rtn;
+}
+
+/* Return nonzero if LOCK is locked. */
+
+_EXTERN_INLINE int
+__spin_lock_locked (__spin_lock_t *__lock)
+{
+ long int __rtn;
+ __asm__ __volatile__ ("\
+0: lwarx %0,0,%1\n\
+ stwcx. %0,0,%1\n\
+ bne- 0b\n\
+" : "=&r" (__rtn) : "r" (__lock) : "cr0");
+ return __rtn;
+}
+
+
+#endif /* machine-lock.h */
diff --git a/libc/sysdeps/mach/powerpc/machine-sp.h b/libc/sysdeps/mach/powerpc/machine-sp.h
new file mode 100644
index 000000000..cf5341cb9
--- /dev/null
+++ b/libc/sysdeps/mach/powerpc/machine-sp.h
@@ -0,0 +1,42 @@
+/* Machine-specific function to return the stack pointer. PowerPC version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _MACHINE_SP_H
+#define _MACHINE_SP_H
+
+/* Return the current stack pointer. */
+
+#ifndef _EXTERN_INLINE
+/* Make sure this function is included in hurd/threadvar-inlines.c. */
+# ifdef _HURD_THREADVAR_H_EXTERN_INLINE
+# define _EXTERN_INLINE _HURD_THREADVAR_H_EXTERN_INLINE
+# else
+# define _EXTERN_INLINE extern __inline
+# endif
+#endif
+
+_EXTERN_INLINE void *
+__thread_stack_pointer (void)
+{
+ register void *__sp__;
+ __asm__ ("mr %0, 1" : "=r" (__sp__));
+ return __sp__;
+}
+
+#endif /* machine-sp.h */
diff --git a/libc/sysdeps/mach/powerpc/syscall.S b/libc/sysdeps/mach/powerpc/syscall.S
new file mode 100644
index 000000000..6482f0d72
--- /dev/null
+++ b/libc/sysdeps/mach/powerpc/syscall.S
@@ -0,0 +1,30 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY (syscall)
+ mr r0,r3
+ mr r3,r4
+ mr r4,r5
+ mr r5,r6
+ mr r6,r7
+ mr r7,r8
+ sc
+ blr
+END (syscall)
diff --git a/libc/sysdeps/mach/powerpc/sysdep.h b/libc/sysdeps/mach/powerpc/sysdep.h
new file mode 100644
index 000000000..acfacc473
--- /dev/null
+++ b/libc/sysdeps/mach/powerpc/sysdep.h
@@ -0,0 +1,51 @@
+/* system call details for Mach on PowerPC
+ Copyright (C) 2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _MACH_POWERPC_SYSDEP_H
+#define _MACH_POWERPC_SYSDEP_H
+
+#define START_ARGS char **sparg
+#define SNARF_ARGS(argc, argv, envp) \
+ do { \
+ argv = &sparg[1]; \
+ argc = *(int *)sparg; \
+ envp = &argv[argc + 1]; \
+ } while (0)
+
+#define CALL_WITH_SP(fn, sp) \
+ do { \
+ register long __sp = (long) sp, __fn = (long) fn; \
+ asm volatile ("mr 1, %0; mtlr %1; blr" \
+ : : "r" (__sp), "r" (__fn)); \
+ } while (0)
+
+#define STACK_GROWTH_DOWN
+
+#define RETURN_TO(sp, pc, retval) \
+ asm volatile ("mr 1, %0; mtctr %1; mr 3, %2; bctr" \
+ : : "r" (sp), "r" (pc), "r" (retval))
+
+/* Get the machine-independent Mach definitions. */
+#define _MACH_MACHINE_ASM_H 1 /* Kludge to avoid bad Darwin header file. */
+#include <sysdeps/mach/sysdep.h>
+
+#undef ENTRY
+#include <sysdeps/unix/powerpc/sysdep.h>
+
+#endif /* _MACH_POWERPC_SYSDEP_H */
diff --git a/libc/sysdeps/mach/powerpc/thread_state.h b/libc/sysdeps/mach/powerpc/thread_state.h
new file mode 100644
index 000000000..e6ca1042f
--- /dev/null
+++ b/libc/sysdeps/mach/powerpc/thread_state.h
@@ -0,0 +1,39 @@
+/* Mach thread state definitions for machine-independent code. PowerPC version
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <mach/machine/thread_status.h>
+
+#define MACHINE_THREAD_STATE_FLAVOR PPC_THREAD_STATE
+#define MACHINE_THREAD_STATE_COUNT PPC_THREAD_STATE_COUNT
+
+#define machine_thread_state ppc_thread_state
+
+#define PC srr0
+#define SP r1
+#define SYSRETURN r3
+
+struct machine_thread_all_state
+ {
+ int set; /* Mask of bits (1 << FLAVOR). */
+ struct ppc_thread_state basic;
+ struct ppc_exception_state exc;
+ struct ppc_float_state fpu;
+ };
+
+#include <sysdeps/mach/thread_state.h>
diff --git a/libc/sysdeps/mach/readonly-area.c b/libc/sysdeps/mach/readonly-area.c
new file mode 100644
index 000000000..afee7a4bd
--- /dev/null
+++ b/libc/sysdeps/mach/readonly-area.c
@@ -0,0 +1,57 @@
+/* Test if a memory region is wholly unwritable. Mach version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <mach.h>
+
+/* Return 1 if the whole area PTR .. PTR+SIZE is not writable.
+ Return -1 if it is writable. */
+
+int
+__readonly_area (const char *ptr, size_t size)
+{
+ vm_address_t region_address = (uintptr_t) ptr;
+ vm_size_t region_length = size;
+ vm_prot_t protection;
+ vm_prot_t max_protection;
+ vm_inherit_t inheritance;
+ boolean_t is_shared;
+ mach_port_t object_name;
+ vm_offset_t offset;
+
+ while (__vm_region (__mach_task_self (),
+ &region_address, &region_length,
+ &protection, &max_protection, &inheritance, &is_shared,
+ &object_name, &offset) == KERN_SUCCESS
+ && region_address <= (uintptr_t) ptr)
+ {
+ region_address += region_length;
+ if (region_address < (uintptr_t) ptr)
+ continue;
+
+ if (protection & VM_PROT_WRITE)
+ return -1;
+
+ if (region_address - (uintptr_t) ptr >= size)
+ break;
+ }
+
+ return 1;
+}
diff --git a/libc/sysdeps/mach/sched_yield.c b/libc/sysdeps/mach/sched_yield.c
new file mode 100644
index 000000000..0c35ef098
--- /dev/null
+++ b/libc/sysdeps/mach/sched_yield.c
@@ -0,0 +1,32 @@
+/* sched_yield -- yield the processor. Mach version.
+ Copyright (C) 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sched.h>
+#include <mach.h>
+
+/* Yield the processor. */
+int
+__sched_yield (void)
+{
+ (void) __swtch ();
+ return 0;
+}
+libc_hidden_def (__sched_yield)
+weak_alias (__sched_yield, sched_yield)
diff --git a/libc/sysdeps/mach/sleep.c b/libc/sysdeps/mach/sleep.c
new file mode 100644
index 000000000..93e70f662
--- /dev/null
+++ b/libc/sysdeps/mach/sleep.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+#include <time.h>
+#include <unistd.h>
+#include <mach.h>
+
+/* Make the process sleep for SECONDS seconds, or until a signal arrives
+ and is not ignored. The function returns the number of seconds less
+ than SECONDS which it actually slept (zero if it slept the full time).
+ There is no return value to indicate error, but if `sleep' returns
+ SECONDS, it probably didn't work. */
+unsigned int
+__sleep (unsigned int seconds)
+{
+ time_t before, after;
+ mach_port_t recv;
+
+ recv = __mach_reply_port ();
+
+ before = time ((time_t *) NULL);
+ (void) __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
+ 0, 0, recv, seconds * 1000, MACH_PORT_NULL);
+ after = time ((time_t *) NULL);
+ __mach_port_destroy (__mach_task_self (), recv);
+
+ return seconds - (after - before);
+}
+weak_alias (__sleep, sleep)
diff --git a/libc/sysdeps/mach/start.c b/libc/sysdeps/mach/start.c
new file mode 100644
index 000000000..92d2a8273
--- /dev/null
+++ b/libc/sysdeps/mach/start.c
@@ -0,0 +1,104 @@
+/* Copyright (C) 1992, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sysdep.h>
+
+#ifndef __GNUC__
+ #error This file uses GNU C extensions; you must compile with GCC.
+#endif
+
+/* The first piece of initialized data. */
+int __data_start = 0;
+
+#ifndef _HURD_THREADVAR_H
+volatile int errno;
+#endif
+
+extern void __mach_init (void);
+extern void __libc_init (int argc, char **argv, char **envp);
+extern int main (int argc, char **argv, char **envp);
+
+/* These are uninitialized common definitions so they will be zero
+ by default. If the user links in C threads, that will provide initialized
+ definitions that override these. */
+void *(*_cthread_init_routine) (void); /* Returns new SP to use. */
+void (*_cthread_exit_routine) (int status);
+
+
+/* These are for communication from _start to start1,
+ where we cannot use the stack for anything. */
+static int start_argc;
+static char **start_argv;
+
+/* _start calls this on the new stack. */
+static volatile void
+start1 (void)
+{
+ __libc_init (start_argc, start_argv, __environ);
+
+ (_cthread_exit_routine != NULL ? *_cthread_exit_routine : exit)
+ (main (start_argc, start_argv, __environ));
+
+ /* Should never get here. */
+ LOSE;
+}
+
+#ifndef START_ARGS
+#define START_ARGS void
+#endif
+#ifdef START_MACHDEP
+START_MACHDEP
+#define _start _start0
+#endif
+
+void
+_start (START_ARGS)
+{
+ SNARF_ARGS (start_argc, start_argv, __environ);
+
+ __mach_init ();
+
+ if (_cthread_init_routine != NULL)
+ CALL_WITH_SP (start1, (*_cthread_init_routine) ());
+ else
+ start1 ();
+
+ /* Should never get here. */
+ LOSE;
+}
diff --git a/libc/sysdeps/mach/sys/reboot.h b/libc/sysdeps/mach/sys/reboot.h
new file mode 100644
index 000000000..fc7308929
--- /dev/null
+++ b/libc/sysdeps/mach/sys/reboot.h
@@ -0,0 +1,171 @@
+/*
+ * Mach Operating System
+ * Copyright (C) 1993,1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * (pre-GNU) HISTORY
+ *
+ * Revision 2.8 93/03/11 13:46:40 danner
+ * u_long -> u_int.
+ * [93/03/09 danner]
+ *
+ * Revision 2.7 92/05/21 17:25:11 jfriedl
+ * Appended 'U' to constants that would otherwise be signed.
+ * [92/05/16 jfriedl]
+ *
+ * Revision 2.6 91/06/19 11:59:44 rvb
+ * Second byte of boothowto is flags for "startup" program.
+ * [91/06/18 rvb]
+ * Add ifndef __ASSEMBLER__ so that vax_init.s can include it.
+ * [91/06/11 rvb]
+ *
+ * Revision 2.5 91/05/14 17:40:11 mrt
+ * Correcting copyright
+ *
+ * Revision 2.4 91/02/05 17:56:48 mrt
+ * Changed to new Mach copyright
+ * [91/02/01 17:49:12 mrt]
+ *
+ * Revision 2.3 90/08/27 22:12:56 dbg
+ * Added definitions used by Mach Kernel: RB_DEBUGGER, RB_UNIPROC,
+ * RB_NOBOOTRC, RB_ALTBOOT. Moved RB_KDB to 0x04 (Mach value).
+ * Removed RB_RDONLY, RB_DUMP, RB_NOSYNC.
+ * [90/08/14 dbg]
+ *
+ */
+
+/*
+ Copyright (C) 1982, 1986, 1988 Regents of the University of California.
+ 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.
+ 4. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.*/
+
+/*
+ * @(#)reboot.h 7.5 (Berkeley) 6/27/88
+ */
+
+#ifndef _SYS_REBOOT_H_
+#define _SYS_REBOOT_H_
+
+#include <features.h>
+
+/*
+ * Arguments to reboot system call.
+ * These are converted to switches, and passed to startup program,
+ * and on to init.
+ */
+#define RB_AUTOBOOT 0 /* flags for system auto-booting itself */
+
+#define RB_ASKNAME 0x01 /* -a: ask for file name to reboot from */
+#define RB_SINGLE 0x02 /* -s: reboot to single user only */
+#define RB_KDB 0x04 /* -d: kernel debugger symbols loaded */
+#define RB_HALT 0x08 /* -h: enter KDB at bootup */
+ /* for host_reboot(): don't reboot,
+ just halt */
+#define RB_INITNAME 0x10 /* -i: name given for /etc/init (unused) */
+#define RB_DFLTROOT 0x20 /* use compiled-in rootdev */
+#define RB_NOBOOTRC 0x20 /* -b: don't run /etc/rc.boot */
+#define RB_ALTBOOT 0x40 /* use /boot.old vs /boot */
+#define RB_UNIPROC 0x80 /* -u: start only one processor */
+
+#define RB_SHIFT 8 /* second byte is for ux */
+
+#define RB_DEBUGGER 0x1000 /* for host_reboot(): enter kernel
+ debugger from user level */
+
+/*
+ * Constants for converting boot-style device number to type,
+ * adaptor (uba, mba, etc), unit number and partition number.
+ * Type (== major device number) is in the low byte
+ * for backward compatibility. Except for that of the "magic
+ * number", each mask applies to the shifted value.
+ * Format:
+ * (4) (4) (4) (4) (8) (8)
+ * --------------------------------
+ * |MA | AD| CT| UN| PART | TYPE |
+ * --------------------------------
+ */
+#define B_ADAPTORSHIFT 24
+#define B_ADAPTORMASK 0x0f
+#define B_ADAPTOR(val) (((val) >> B_ADAPTORSHIFT) & B_ADAPTORMASK)
+#define B_CONTROLLERSHIFT 20
+#define B_CONTROLLERMASK 0xf
+#define B_CONTROLLER(val) (((val)>>B_CONTROLLERSHIFT) & B_CONTROLLERMASK)
+#define B_UNITSHIFT 16
+#define B_UNITMASK 0xf
+#define B_UNIT(val) (((val) >> B_UNITSHIFT) & B_UNITMASK)
+#define B_PARTITIONSHIFT 8
+#define B_PARTITIONMASK 0xff
+#define B_PARTITION(val) (((val) >> B_PARTITIONSHIFT) & B_PARTITIONMASK)
+#define B_TYPESHIFT 0
+#define B_TYPEMASK 0xff
+#define B_TYPE(val) (((val) >> B_TYPESHIFT) & B_TYPEMASK)
+
+#define B_MAGICMASK ((u_int)0xf0000000U)
+#define B_DEVMAGIC ((u_int)0xa0000000U)
+
+#define MAKEBOOTDEV(type, adaptor, controller, unit, partition) \
+ (((type) << B_TYPESHIFT) | ((adaptor) << B_ADAPTORSHIFT) | \
+ ((controller) << B_CONTROLLERSHIFT) | ((unit) << B_UNITSHIFT) | \
+ ((partition) << B_PARTITIONSHIFT) | B_DEVMAGIC)
+
+
+#ifdef KERNEL
+#ifndef __ASSEMBLER__
+extern int boothowto;
+#endif /* __ASSEMBLER__ */
+#endif
+
+__BEGIN_DECLS
+
+/* Reboot or halt the system. */
+extern int reboot (int __howto) __THROW;
+
+__END_DECLS
+
+
+#endif /* _SYS_REBOOT_H_ */
diff --git a/libc/sysdeps/mach/sys/syscall.h b/libc/sysdeps/mach/sys/syscall.h
new file mode 100644
index 000000000..6e4ed4d64
--- /dev/null
+++ b/libc/sysdeps/mach/sys/syscall.h
@@ -0,0 +1 @@
+/* The Mach syscalls are in <mach/syscall_sw.h>. */
diff --git a/libc/sysdeps/mach/sysdep.h b/libc/sysdeps/mach/sysdep.h
new file mode 100644
index 000000000..825198c79
--- /dev/null
+++ b/libc/sysdeps/mach/sysdep.h
@@ -0,0 +1,93 @@
+/* Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef __ASSEMBLER__
+
+/* Get the Mach definitions of ENTRY and kernel_trap. */
+#include <mach/machine/syscall_sw.h>
+
+/* The Mach definitions assume underscores should be prepended to
+ symbol names. Redefine them to do so only when appropriate. */
+#undef EXT
+#undef LEXT
+#define EXT(x) C_SYMBOL_NAME(x)
+#define LEXT(x) C_SYMBOL_NAME(x##:)
+
+#ifdef HAVE_ELF
+/* For ELF we need to add the `.type' directive to make shared libraries
+ work right. */
+#undef ENTRY
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE name; \
+ .align ALIGN; \
+ .type name,@function; \
+ name:
+#endif
+
+#endif
+
+/* This is invoked by things run when there is random lossage, before they
+ try to do anything else. Just to be safe, deallocate the reply port so
+ bogons arriving on it don't foul up future RPCs. */
+
+#ifndef __ASSEMBLER__
+#define FATAL_PREPARE_INCLUDE <mach/mig_support.h>
+#define FATAL_PREPARE __mig_dealloc_reply_port (MACH_PORT_NULL)
+#endif
+
+/* sysdeps/mach/MACHINE/sysdep.h should define the following macros. */
+
+/* Produce a text assembler label for the C global symbol NAME. */
+#ifndef ENTRY
+#define ENTRY(name) .error ENTRY not defined by sysdeps/mach/MACHINE/sysdep.h
+/* This is not used on all machines. */
+#endif
+
+/* Set variables ARGC, ARGV, and ENVP for the arguments
+ left on the stack by the microkernel. */
+#ifndef SNARF_ARGS
+#define SNARF_ARGS(argc, argv, envp)
+#error SNARF_ARGS not defined by sysdeps/mach/MACHINE/sysdep.h
+#endif
+
+/* Call the C function FN with no arguments,
+ on a stack starting at SP (as returned by *_cthread_init_routine).
+ You don't need to deal with FN returning; it shouldn't. */
+#ifndef CALL_WITH_SP
+#define CALL_WITH_SP(fn, sp)
+#error CALL_WITH_SP not defined by sysdeps/mach/MACHINE/sysdep.h
+#endif
+
+/* LOSE can be defined as the `halt' instruction or something
+ similar which will cause the process to die in a characteristic
+ way suggesting a bug. */
+#ifndef LOSE
+#define LOSE ({ volatile int zero = 0; zero / zero; })
+#endif
+
+/* One of these should be defined to specify the stack direction. */
+#if !defined (STACK_GROWTH_UP) && !defined (STACK_GROWTH_DOWN)
+#error stack direction unspecified
+#endif
+
+/* Used by some assembly code. */
+#ifdef NO_UNDERSCORES
+#define C_SYMBOL_NAME(name) name
+#else
+#define C_SYMBOL_NAME(name) _##name
+#endif
diff --git a/libc/sysdeps/mach/thread_state.h b/libc/sysdeps/mach/thread_state.h
new file mode 100644
index 000000000..38effdf5e
--- /dev/null
+++ b/libc/sysdeps/mach/thread_state.h
@@ -0,0 +1,87 @@
+/* Generic definitions for dealing with Mach thread states.
+ Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* Everything else is called `thread_state', but CMU's header file is
+ called `thread_status'. Oh boy. */
+#include <mach/thread_status.h>
+
+/* The machine-dependent thread_state.h file can either define these
+ macros, or just define PC and SP to the register names. */
+
+#ifndef MACHINE_THREAD_STATE_SET_PC
+#define MACHINE_THREAD_STATE_SET_PC(ts, pc) \
+ ((ts)->PC = (unsigned long int) (pc))
+#endif
+#ifndef MACHINE_THREAD_STATE_SET_SP
+#ifdef STACK_GROWTH_UP
+#define MACHINE_THREAD_STATE_SET_SP(ts, stack, size) \
+ ((ts)->SP = (unsigned long int) (stack))
+#else
+#define MACHINE_THREAD_STATE_SET_SP(ts, stack, size) \
+ ((ts)->SP = (unsigned long int) (stack) + (size))
+#endif
+#endif
+
+/* These functions are of use in machine-dependent signal trampoline
+ implementations. */
+
+#include <string.h> /* size_t, memcpy */
+#include <mach/mach_interface.h> /* __thread_get_state */
+
+static inline int
+machine_get_state (thread_t thread, struct machine_thread_all_state *state,
+ int flavor, void *stateptr, void *scpptr, size_t size)
+{
+ if (state->set & (1 << flavor))
+ {
+ /* Copy the saved state. */
+ memcpy (scpptr, stateptr, size);
+ return 1;
+ }
+ else
+ {
+ /* No one asked about this flavor of state before; fetch the state
+ directly from the kernel into the sigcontext. */
+ mach_msg_type_number_t got = (size / sizeof (int));
+ return (! __thread_get_state (thread, flavor, scpptr, &got)
+ && got == (size / sizeof (int)));
+ }
+}
+
+static inline int
+machine_get_basic_state (thread_t thread,
+ struct machine_thread_all_state *state)
+{
+ mach_msg_type_number_t count;
+
+ if (state->set & (1 << MACHINE_THREAD_STATE_FLAVOR))
+ return 1;
+
+ count = MACHINE_THREAD_STATE_COUNT;
+ if (__thread_get_state (thread, MACHINE_THREAD_STATE_FLAVOR,
+ (natural_t *) &state->basic,
+ &count) != KERN_SUCCESS ||
+ count != MACHINE_THREAD_STATE_COUNT)
+ /* What kind of thread?? */
+ return 0; /* XXX */
+
+ state->set |= 1 << MACHINE_THREAD_STATE_FLAVOR;
+ return 1;
+}
diff --git a/libc/sysdeps/mach/usleep.c b/libc/sysdeps/mach/usleep.c
new file mode 100644
index 000000000..ecbd2ed41
--- /dev/null
+++ b/libc/sysdeps/mach/usleep.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1992, 93, 94, 97, 98, 99, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <mach.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+/* Sleep USECONDS microseconds, or until a previously set timer goes off. */
+int
+usleep (useconds_t useconds)
+{
+ mach_port_t recv;
+ struct timeval before, after;
+
+ recv = __mach_reply_port ();
+
+ if (__gettimeofday (&before, NULL) < 0)
+ return -1;
+ (void) __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
+ 0, 0, recv, (useconds + 999) / 1000, MACH_PORT_NULL);
+ __mach_port_destroy (mach_task_self (), recv);
+ if (__gettimeofday (&after, NULL) < 0)
+ return -1;
+
+ return 0;
+}
diff --git a/libc/sysdeps/mach/xpg-strerror.c b/libc/sysdeps/mach/xpg-strerror.c
new file mode 100644
index 000000000..8d0b31e60
--- /dev/null
+++ b/libc/sysdeps/mach/xpg-strerror.c
@@ -0,0 +1,83 @@
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <libintl.h>
+#include <stdio.h>
+#include <string.h>
+#include <mach/error.h>
+#include <errorlib.h>
+#include <sys/param.h>
+#include <stdio-common/_itoa.h>
+
+/* It is critical here that we always use the `dcgettext' function for
+ the message translation. Since <libintl.h> only defines the macro
+ `dgettext' to use `dcgettext' for optimizing programs this is not
+ always guaranteed. */
+#ifndef dgettext
+# include <locale.h> /* We need LC_MESSAGES. */
+# define dgettext(domainname, msgid) dcgettext (domainname, msgid, LC_MESSAGES)
+#endif
+
+/* Fill buf with a string describing the errno code in ERRNUM. */
+int
+__xpg_strerror_r (int errnum, char *buf, size_t buflen)
+{
+ int system;
+ int sub;
+ int code;
+ const struct error_system *es;
+ extern void __mach_error_map_compat (int *);
+ const char *estr;
+
+ __mach_error_map_compat (&errnum);
+
+ system = err_get_system (errnum);
+ sub = err_get_sub (errnum);
+ code = err_get_code (errnum);
+
+ if (system > err_max_system || ! __mach_error_systems[system].bad_sub)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ es = &__mach_error_systems[system];
+
+ if (sub >= es->max_sub)
+ estr = (const char *) es->bad_sub;
+ else if (code >= es->subsystem[sub].max_code)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ else
+ estr = (const char *) _(es->subsystem[sub].codes[code]);
+
+ size_t estrlen = strlen (estr) + 1;
+
+ if (buflen < estrlen)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+
+ memcpy (buf, estr, estrlen);
+ return 0;
+}
diff --git a/libc/sysdeps/posix/Makefile b/libc/sysdeps/posix/Makefile
new file mode 100644
index 000000000..b58aa6aad
--- /dev/null
+++ b/libc/sysdeps/posix/Makefile
@@ -0,0 +1,5 @@
+# These affect the generated bits/stdio_lim.h file.
+L_tmpnam = 20
+TMP_MAX = 238328
+L_ctermid = 9
+L_cuserid = 9
diff --git a/libc/sysdeps/posix/clock.c b/libc/sysdeps/posix/clock.c
new file mode 100644
index 000000000..182a1b196
--- /dev/null
+++ b/libc/sysdeps/posix/clock.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/times.h>
+#include <time.h>
+
+/* Return the time used by the program so far (user time + system time). */
+clock_t
+clock ()
+{
+ struct tms buf;
+
+ if (__times (&buf) < 0)
+ return (clock_t) -1;
+
+ return buf.tms_utime + buf.tms_stime;
+}
diff --git a/libc/sysdeps/posix/clock_getres.c b/libc/sysdeps/posix/clock_getres.c
new file mode 100644
index 000000000..f4dc21f8a
--- /dev/null
+++ b/libc/sysdeps/posix/clock_getres.c
@@ -0,0 +1,118 @@
+/* clock_getres -- Get the resolution of a POSIX clockid_t.
+ Copyright (C) 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <libc-internal.h>
+
+
+#if HP_TIMING_AVAIL
+static long int nsec; /* Clock frequency of the processor. */
+
+static inline int
+hp_timing_getres (struct timespec *res)
+{
+ if (__builtin_expect (nsec == 0, 0))
+ {
+ hp_timing_t freq;
+
+ /* This can only happen if we haven't initialized the `nsec'
+ variable yet. Do this now. We don't have to protect this
+ code against multiple execution since all of them should
+ lead to the same result. */
+ freq = __get_clockfreq ();
+ if (__builtin_expect (freq == 0, 0))
+ /* Something went wrong. */
+ return -1;
+
+ nsec = MAX (UINT64_C (1000000000) / freq, 1);
+ }
+
+ /* Fill in the values.
+ The seconds are always zero (unless we have a 1Hz machine). */
+ res->tv_sec = 0;
+ res->tv_nsec = nsec;
+
+ return 0;
+}
+#endif
+
+static inline int
+realtime_getres (struct timespec *res)
+{
+ long int clk_tck = sysconf (_SC_CLK_TCK);
+
+ if (__builtin_expect (clk_tck != -1, 1))
+ {
+ /* This implementation assumes that the realtime clock has a
+ resolution higher than 1 second. This is the case for any
+ reasonable implementation. */
+ res->tv_sec = 0;
+ res->tv_nsec = 1000000000 / clk_tck;
+ return 0;
+ }
+
+ return -1;
+}
+
+
+/* Get resolution of clock. */
+int
+clock_getres (clockid_t clock_id, struct timespec *res)
+{
+ int retval = -1;
+
+ switch (clock_id)
+ {
+#ifdef SYSDEP_GETRES
+ SYSDEP_GETRES;
+#endif
+
+#ifndef HANDLED_REALTIME
+ case CLOCK_REALTIME:
+ retval = realtime_getres (res);
+ break;
+#endif /* handled REALTIME */
+
+ default:
+#ifdef SYSDEP_GETRES_CPU
+ SYSDEP_GETRES_CPU;
+#endif
+#if HP_TIMING_AVAIL
+ if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
+ == CLOCK_THREAD_CPUTIME_ID)
+ retval = hp_timing_getres (res);
+ else
+#endif
+ __set_errno (EINVAL);
+ break;
+
+#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
+ case CLOCK_PROCESS_CPUTIME_ID:
+ case CLOCK_THREAD_CPUTIME_ID:
+ retval = hp_timing_getres (res);
+ break;
+#endif
+ }
+
+ return retval;
+}
diff --git a/libc/sysdeps/posix/ctermid.c b/libc/sysdeps/posix/ctermid.c
new file mode 100644
index 000000000..004b8fecf
--- /dev/null
+++ b/libc/sysdeps/posix/ctermid.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <string.h>
+
+
+/* Return the name of the controlling terminal.
+ If S is not NULL, the name is copied into it (it should be at
+ least L_ctermid bytes long), otherwise a static buffer is used. */
+char *
+ctermid (s)
+ char *s;
+{
+ static char name[L_ctermid];
+
+ if (s == NULL)
+ s = name;
+
+ return strcpy (s, "/dev/tty");
+}
diff --git a/libc/sysdeps/posix/cuserid.c b/libc/sysdeps/posix/cuserid.c
new file mode 100644
index 000000000..11c827a68
--- /dev/null
+++ b/libc/sysdeps/posix/cuserid.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1991, 1996, 1998, 1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+/* Return the username of the caller.
+ If S is not NULL, it points to a buffer of at least L_cuserid bytes
+ into which the name is copied; otherwise, a static buffer is used. */
+char *
+cuserid (s)
+ char *s;
+{
+ static char name[L_cuserid];
+ char buf[NSS_BUFLEN_PASSWD];
+ struct passwd pwent;
+ struct passwd *pwptr;
+
+ if (__getpwuid_r (__geteuid (), &pwent, buf, sizeof (buf), &pwptr)
+ || pwptr == NULL)
+ {
+ if (s != NULL)
+ s[0] = '\0';
+ return s;
+ }
+
+ if (s == NULL)
+ s = name;
+ return strncpy (s, pwptr->pw_name, L_cuserid);
+}
diff --git a/libc/sysdeps/posix/dup.c b/libc/sysdeps/posix/dup.c
new file mode 100644
index 000000000..0bbc9dc3f
--- /dev/null
+++ b/libc/sysdeps/posix/dup.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+/* Duplicate FD, returning a new file descriptor open on the same file. */
+int
+__dup (fd)
+ int fd;
+{
+ return fcntl (fd, F_DUPFD, 0);
+}
+
+weak_alias (__dup, dup)
diff --git a/libc/sysdeps/posix/dup2.c b/libc/sysdeps/posix/dup2.c
new file mode 100644
index 000000000..46c679899
--- /dev/null
+++ b/libc/sysdeps/posix/dup2.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1991, 92, 93, 95, 96, 97, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+
+/* Duplicate FD to FD2, closing the old FD2 and making FD2 be
+ open the same file as FD is. Return FD2 or -1. */
+int
+__dup2 (fd, fd2)
+ int fd;
+ int fd2;
+{
+ int save;
+
+ if (fd2 < 0
+#ifdef OPEN_MAX
+ || fd2 >= OPEN_MAX
+#endif
+)
+ {
+ __set_errno (EBADF);
+ return -1;
+ }
+
+ /* Check if FD is kosher. */
+ if (fcntl (fd, F_GETFL) < 0)
+ return -1;
+
+ if (fd == fd2)
+ return fd2;
+
+ /* This is not atomic. */
+
+ save = errno;
+ (void) close (fd2);
+ __set_errno (save);
+
+ return fcntl (fd, F_DUPFD, fd2);
+}
+libc_hidden_def (__dup2)
+weak_alias (__dup2, dup2)
diff --git a/libc/sysdeps/posix/euidaccess.c b/libc/sysdeps/posix/euidaccess.c
new file mode 100644
index 000000000..76a09d455
--- /dev/null
+++ b/libc/sysdeps/posix/euidaccess.c
@@ -0,0 +1,220 @@
+/* Check if effective user id can access file
+ Copyright (C) 1990,1991,1995-2001,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Written by David MacKenzie and Torbjorn Granlund.
+ Adapted for GNU C library by Roland McGrath. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef S_IEXEC
+# ifndef S_IXUSR
+# define S_IXUSR S_IEXEC
+# endif
+# ifndef S_IXGRP
+# define S_IXGRP (S_IEXEC >> 3)
+# endif
+# ifndef S_IXOTH
+# define S_IXOTH (S_IEXEC >> 6)
+# endif
+#endif /* S_IEXEC */
+
+#if defined HAVE_UNISTD_H || defined _LIBC
+# include <unistd.h>
+#endif
+
+#ifndef _POSIX_VERSION
+uid_t getuid ();
+gid_t getgid ();
+uid_t geteuid ();
+gid_t getegid ();
+#endif /* not POSIX_VERSION */
+
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+#ifndef __set_errno
+# define __set_errno(val) errno = (val)
+#endif
+
+#if defined EACCES && !defined EACCESS
+# define EACCESS EACCES
+#endif
+
+#ifndef F_OK
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+#if !defined S_IROTH && defined R_OK
+# define S_IROTH R_OK
+#endif
+#if !defined S_IWOTH && defined W_OK
+# define S_IWOTH W_OK
+#endif
+#if !defined S_IXOTH && defined X_OK
+# define S_IXOTH X_OK
+#endif
+
+
+#ifdef _LIBC
+
+# define group_member __group_member
+# define euidaccess __euidaccess
+
+#else
+
+/* The user's real user id. */
+static uid_t uid;
+
+/* The user's real group id. */
+static gid_t gid;
+
+/* The user's effective user id. */
+static uid_t euid;
+
+/* The user's effective group id. */
+static gid_t egid;
+
+/* Nonzero if UID, GID, EUID, and EGID have valid values. */
+static int have_ids;
+
+# ifdef HAVE_GETGROUPS
+int group_member ();
+# else
+# define group_member(gid) 0
+# endif
+
+#endif
+
+
+/* Return 0 if the user has permission of type MODE on file PATH;
+ otherwise, return -1 and set `errno' to EACCESS.
+ Like access, except that it uses the effective user and group
+ id's instead of the real ones, and it does not check for read-only
+ filesystem, text busy, etc. */
+
+int
+euidaccess (path, mode)
+ const char *path;
+ int mode;
+{
+ struct stat64 stats;
+ int granted;
+
+#ifdef _LIBC
+ uid_t euid;
+ gid_t egid;
+
+ if (! __libc_enable_secure)
+ /* If we are not set-uid or set-gid, access does the same. */
+ return __access (path, mode);
+#else
+ if (have_ids == 0)
+ {
+ have_ids = 1;
+ uid = getuid ();
+ gid = getgid ();
+ euid = geteuid ();
+ egid = getegid ();
+ }
+
+ if (uid == euid && gid == egid)
+ /* If we are not set-uid or set-gid, access does the same. */
+ return access (path, mode);
+#endif
+
+ if (stat64 (path, &stats))
+ return -1;
+
+ mode &= (X_OK | W_OK | R_OK); /* Clear any bogus bits. */
+#if R_OK != S_IROTH || W_OK != S_IWOTH || X_OK != S_IXOTH
+ ?error Oops, portability assumptions incorrect.
+#endif
+
+ if (mode == F_OK)
+ return 0; /* The file exists. */
+
+#ifdef _LIBC
+ /* Now we need the IDs. */
+ euid = __geteuid ();
+ egid = __getegid ();
+#endif
+
+ /* The super-user can read and write any file, and execute any file
+ that anyone can execute. */
+ if (euid == 0 && ((mode & X_OK) == 0
+ || (stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
+ return 0;
+
+ if (euid == stats.st_uid)
+ granted = (unsigned int) (stats.st_mode & (mode << 6)) >> 6;
+ else if (egid == stats.st_gid || group_member (stats.st_gid))
+ granted = (unsigned int) (stats.st_mode & (mode << 3)) >> 3;
+ else
+ granted = (stats.st_mode & mode);
+ /* XXX Add support for ACLs. */
+ if (granted == mode)
+ return 0;
+ __set_errno (EACCESS);
+ return -1;
+}
+#undef euidaccess
+#undef eaccess
+#ifdef weak_alias
+weak_alias (__euidaccess, euidaccess)
+weak_alias (__euidaccess, eaccess)
+#endif
+
+#ifdef TEST
+# include <stdio.h>
+# include <errno.h>
+# include "error.h"
+
+char *program_name;
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *file;
+ int mode;
+ int err;
+
+ program_name = argv[0];
+ if (argc < 3)
+ abort ();
+ file = argv[1];
+ mode = atoi (argv[2]);
+
+ err = euidaccess (file, mode);
+ printf ("%d\n", err);
+ if (err != 0)
+ error (0, errno, "%s", file);
+ exit (0);
+}
+#endif
diff --git a/libc/sysdeps/posix/flock.c b/libc/sysdeps/posix/flock.c
new file mode 100644
index 000000000..ee8038bbb
--- /dev/null
+++ b/libc/sysdeps/posix/flock.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file implements the `flock' function in terms of the POSIX.1 `fcntl'
+ locking mechanism. In 4BSD, these are two incompatible locking mechanisms,
+ perhaps with different semantics? */
+
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/file.h>
+
+/* Apply or remove an advisory lock, according to OPERATION,
+ on the file FD refers to. */
+int
+__flock (fd, operation)
+ int fd;
+ int operation;
+{
+ struct flock lbuf;
+
+ switch (operation & ~LOCK_NB)
+ {
+ case LOCK_SH:
+ lbuf.l_type = F_RDLCK;
+ break;
+ case LOCK_EX:
+ lbuf.l_type = F_WRLCK;
+ break;
+ case LOCK_UN:
+ lbuf.l_type = F_UNLCK;
+ break;
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ lbuf.l_whence = SEEK_SET;
+ lbuf.l_start = lbuf.l_len = 0L; /* Lock the whole file. */
+
+ return __fcntl (fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &lbuf);
+}
+
+weak_alias (__flock, flock)
diff --git a/libc/sysdeps/posix/fpathconf.c b/libc/sysdeps/posix/fpathconf.c
new file mode 100644
index 000000000..605cd171d
--- /dev/null
+++ b/libc/sysdeps/posix/fpathconf.c
@@ -0,0 +1,241 @@
+/* Copyright (C) 1991,1995,1996,1998,2000,2001,2003
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+
+/* Get file-specific information about descriptor FD. */
+long int
+__fpathconf (fd, name)
+ int fd;
+ int name;
+{
+ if (fd < 0)
+ {
+ __set_errno (EBADF);
+ return -1;
+ }
+
+ switch (name)
+ {
+ default:
+ __set_errno (EINVAL);
+ return -1;
+
+ case _PC_LINK_MAX:
+#ifdef LINK_MAX
+ return LINK_MAX;
+#else
+ return -1;
+#endif
+
+ case _PC_MAX_CANON:
+#ifdef MAX_CANON
+ return MAX_CANON;
+#else
+ return -1;
+#endif
+
+ case _PC_MAX_INPUT:
+#ifdef MAX_INPUT
+ return MAX_INPUT;
+#else
+ return -1;
+#endif
+
+ case _PC_NAME_MAX:
+#ifdef NAME_MAX
+ {
+ struct statfs buf;
+ int save_errno = errno;
+
+ if (__fstatfs (fd, &buf) < 0)
+ {
+ if (errno == ENOSYS)
+ {
+ __set_errno (save_errno);
+ return NAME_MAX;
+ }
+ else if (errno == ENODEV)
+ __set_errno (EINVAL);
+
+ return -1;
+ }
+ else
+ {
+#ifdef _STATFS_F_NAMELEN
+ return buf.f_namelen;
+#else
+# ifdef _STATFS_F_NAME_MAX
+ return buf.f_name_max;
+# else
+ return NAME_MAX;
+# endif
+#endif
+ }
+ }
+#else
+ return -1;
+#endif
+
+ case _PC_PATH_MAX:
+#ifdef PATH_MAX
+ return PATH_MAX;
+#else
+ return -1;
+#endif
+
+ case _PC_PIPE_BUF:
+#ifdef PIPE_BUF
+ return PIPE_BUF;
+#else
+ return -1;
+#endif
+
+ case _PC_CHOWN_RESTRICTED:
+#ifdef _POSIX_CHOWN_RESTRICTED
+ return _POSIX_CHOWN_RESTRICTED;
+#else
+ return -1;
+#endif
+
+ case _PC_NO_TRUNC:
+#ifdef _POSIX_NO_TRUNC
+ return _POSIX_NO_TRUNC;
+#else
+ return -1;
+#endif
+
+ case _PC_VDISABLE:
+#ifdef _POSIX_VDISABLE
+ return _POSIX_VDISABLE;
+#else
+ return -1;
+#endif
+
+ case _PC_SYNC_IO:
+#ifdef _POSIX_SYNC_IO
+ return _POSIX_SYNC_IO;
+#else
+ return -1;
+#endif
+
+ case _PC_ASYNC_IO:
+#ifdef _POSIX_ASYNC_IO
+ {
+ /* AIO is only allowed on regular files and block devices. */
+ struct stat64 st;
+
+ if (__fxstat64 (_STAT_VER, fd, &st) < 0
+ || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode)))
+ return -1;
+ else
+ return 1;
+ }
+#else
+ return -1;
+#endif
+
+ case _PC_PRIO_IO:
+#ifdef _POSIX_PRIO_IO
+ return _POSIX_PRIO_IO;
+#else
+ return -1;
+#endif
+
+ case _PC_SOCK_MAXBUF:
+#ifdef SOCK_MAXBUF
+ return SOCK_MAXBUF;
+#else
+ return -1;
+#endif
+
+ case _PC_FILESIZEBITS:
+#ifdef FILESIZEBITS
+ return FILESIZEBITS;
+#else
+ /* We let platforms with larger file sizes overwrite this value. */
+ return 32;
+#endif
+
+ case _PC_REC_INCR_XFER_SIZE:
+ /* XXX It is not entirely clear what the limit is supposed to do.
+ What is incremented? */
+ return -1;
+
+ case _PC_REC_MAX_XFER_SIZE:
+ /* XXX It is not entirely clear what the limit is supposed to do.
+ In general there is no top limit of the number of bytes which
+ case be transported at once. */
+ return -1;
+
+ case _PC_REC_MIN_XFER_SIZE:
+ {
+ /* XXX It is not entirely clear what the limit is supposed to do.
+ I assume this is the block size of the filesystem. */
+ struct statvfs64 sv;
+
+ if (__fstatvfs64 (fd, &sv) < 0)
+ return -1;
+ return sv.f_bsize;
+ }
+
+ case _PC_REC_XFER_ALIGN:
+ {
+ /* XXX It is not entirely clear what the limit is supposed to do.
+ I assume that the number should reflect the minimal block
+ alignment. */
+ struct statvfs64 sv;
+
+ if (__fstatvfs64 (fd, &sv) < 0)
+ return -1;
+ return sv.f_frsize;
+ }
+
+ case _PC_ALLOC_SIZE_MIN:
+ {
+ /* XXX It is not entirely clear what the limit is supposed to do.
+ I assume that the number should reflect the minimal block
+ alignment. */
+ struct statvfs64 sv;
+
+ if (__fstatvfs64 (fd, &sv) < 0)
+ return -1;
+ return sv.f_frsize;
+ }
+
+ case _PC_SYMLINK_MAX:
+ /* In general there are no limits. If a system has one it should
+ overwrite this case. */
+ return -1;
+
+ case _PC_2_SYMLINKS:
+ /* Unix systems generally have symlinks. */
+ return 1;
+ }
+}
+
+#undef __fpathconf
+weak_alias (__fpathconf, fpathconf)
diff --git a/libc/sysdeps/posix/gai_strerror-strs.h b/libc/sysdeps/posix/gai_strerror-strs.h
new file mode 100644
index 000000000..19040a513
--- /dev/null
+++ b/libc/sysdeps/posix/gai_strerror-strs.h
@@ -0,0 +1,17 @@
+_S(EAI_ADDRFAMILY, N_("Address family for hostname not supported"))
+_S(EAI_AGAIN, N_("Temporary failure in name resolution"))
+_S(EAI_BADFLAGS, N_("Bad value for ai_flags"))
+_S(EAI_FAIL, N_("Non-recoverable failure in name resolution"))
+_S(EAI_FAMILY, N_("ai_family not supported"))
+_S(EAI_MEMORY, N_("Memory allocation failure"))
+_S(EAI_NODATA, N_("No address associated with hostname"))
+_S(EAI_NONAME, N_("Name or service not known"))
+_S(EAI_SERVICE, N_("Servname not supported for ai_socktype"))
+_S(EAI_SOCKTYPE, N_("ai_socktype not supported"))
+_S(EAI_SYSTEM, N_("System error"))
+_S(EAI_INPROGRESS, N_("Processing request in progress"))
+_S(EAI_CANCELED, N_("Request canceled"))
+_S(EAI_NOTCANCELED, N_("Request not canceled"))
+_S(EAI_ALLDONE, N_("All requests done"))
+_S(EAI_INTR, N_("Interrupted by a signal"))
+_S(EAI_IDN_ENCODE, N_("Parameter string not correctly encoded"))
diff --git a/libc/sysdeps/posix/gai_strerror.c b/libc/sysdeps/posix/gai_strerror.c
new file mode 100644
index 000000000..cc13dd4da
--- /dev/null
+++ b/libc/sysdeps/posix/gai_strerror.c
@@ -0,0 +1,70 @@
+/* Copyright (C) 1997, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Philip Blundell <pjb27@cam.ac.uk>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <libintl.h>
+#include <netdb.h>
+#include <stdint.h>
+#include <stdio.h>
+
+
+#define MSGSTRFIELD(line) MSGSTRFIELD1 (line)
+#define MSGSTRFIELD1(line) str##line
+static const union msgstr_t
+{
+ struct
+ {
+#define _S(n, s) char MSGSTRFIELD(__LINE__)[sizeof (s)];
+#include "gai_strerror-strs.h"
+#undef _S
+ };
+ char str[0];
+} msgstr =
+ {
+ {
+#define _S(n, s) s,
+#include "gai_strerror-strs.h"
+#undef _S
+ }
+ };
+static const struct
+{
+ int16_t code;
+ uint16_t idx;
+} msgidx[] =
+ {
+#define _S(n, s) { n, offsetof (union msgstr_t, MSGSTRFIELD (__LINE__)) },
+#include "gai_strerror-strs.h"
+#undef _S
+ };
+
+
+const char *
+gai_strerror (int code)
+{
+ const char *result = "Unknown error";
+ for (size_t i = 0; i < sizeof (msgidx) / sizeof (msgidx[0]); ++i)
+ if (msgidx[i].code == code)
+ {
+ result = msgstr.str + msgidx[i].idx;
+ break;
+ }
+
+ return _(result);
+}
+libc_hidden_def (gai_strerror)
diff --git a/libc/sysdeps/posix/getaddrinfo.c b/libc/sysdeps/posix/getaddrinfo.c
new file mode 100644
index 000000000..185957be6
--- /dev/null
+++ b/libc/sysdeps/posix/getaddrinfo.c
@@ -0,0 +1,2154 @@
+/* The Inner Net License, Version 2.00
+
+ The author(s) grant permission for redistribution and use in source and
+binary forms, with or without modification, of the software and documentation
+provided that the following conditions are met:
+
+0. If you receive a version of the software that is specifically labelled
+ as not being for redistribution (check the version message and/or README),
+ you are not permitted to redistribute that version of the software in any
+ way or form.
+1. All terms of the all other applicable copyrights and licenses must be
+ followed.
+2. Redistributions of source code must retain the authors' copyright
+ notice(s), this list of conditions, and the following disclaimer.
+3. Redistributions in binary form must reproduce the authors' copyright
+ notice(s), this list of conditions, and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+4. [The copyright holder has authorized the removal of this clause.]
+5. Neither the name(s) of the author(s) nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY ITS AUTHORS 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 AUTHORS 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.
+
+ If these license terms cause you a real problem, contact the author. */
+
+/* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <ifaddrs.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#include <nsswitch.h>
+#include <bits/libc-lock.h>
+#include <not-cancel.h>
+#include <nscd/nscd-client.h>
+#include <nscd/nscd_proto.h>
+
+#ifdef HAVE_LIBIDN
+extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
+extern int __idna_to_unicode_lzlz (const char *input, char **output,
+ int flags);
+# include <libidn/idna.h>
+#endif
+
+#define GAIH_OKIFUNSPEC 0x0100
+#define GAIH_EAI ~(GAIH_OKIFUNSPEC)
+
+#ifndef UNIX_PATH_MAX
+# define UNIX_PATH_MAX 108
+#endif
+
+struct gaih_service
+ {
+ const char *name;
+ int num;
+ };
+
+struct gaih_servtuple
+ {
+ struct gaih_servtuple *next;
+ int socktype;
+ int protocol;
+ int port;
+ };
+
+static const struct gaih_servtuple nullserv;
+
+struct gaih_addrtuple
+ {
+ struct gaih_addrtuple *next;
+ char *name;
+ int family;
+ uint32_t addr[4];
+ uint32_t scopeid;
+ };
+
+struct gaih_typeproto
+ {
+ int socktype;
+ int protocol;
+ char name[4];
+ int protoflag;
+ };
+
+/* Values for `protoflag'. */
+#define GAI_PROTO_NOSERVICE 1
+#define GAI_PROTO_PROTOANY 2
+
+static const struct gaih_typeproto gaih_inet_typeproto[] =
+{
+ { 0, 0, "", 0 },
+ { SOCK_STREAM, IPPROTO_TCP, "tcp", 0 },
+ { SOCK_DGRAM, IPPROTO_UDP, "udp", 0 },
+ { SOCK_RAW, 0, "raw", GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE },
+ { 0, 0, "", 0 }
+};
+
+struct gaih
+ {
+ int family;
+ int (*gaih)(const char *name, const struct gaih_service *service,
+ const struct addrinfo *req, struct addrinfo **pai,
+ unsigned int *naddrs);
+ };
+
+static const struct addrinfo default_hints =
+ {
+ .ai_flags = AI_DEFAULT,
+ .ai_family = PF_UNSPEC,
+ .ai_socktype = 0,
+ .ai_protocol = 0,
+ .ai_addrlen = 0,
+ .ai_addr = NULL,
+ .ai_canonname = NULL,
+ .ai_next = NULL
+ };
+
+
+#if 0
+/* Using Unix sockets this way is a security risk. */
+static int
+gaih_local (const char *name, const struct gaih_service *service,
+ const struct addrinfo *req, struct addrinfo **pai)
+{
+ struct utsname utsname;
+
+ if ((name != NULL) && (req->ai_flags & AI_NUMERICHOST))
+ return GAIH_OKIFUNSPEC | -EAI_NONAME;
+
+ if ((name != NULL) || (req->ai_flags & AI_CANONNAME))
+ if (uname (&utsname) < 0)
+ return -EAI_SYSTEM;
+
+ if (name != NULL)
+ {
+ if (strcmp(name, "localhost") &&
+ strcmp(name, "local") &&
+ strcmp(name, "unix") &&
+ strcmp(name, utsname.nodename))
+ return GAIH_OKIFUNSPEC | -EAI_NONAME;
+ }
+
+ if (req->ai_protocol || req->ai_socktype)
+ {
+ const struct gaih_typeproto *tp = gaih_inet_typeproto + 1;
+
+ while (tp->name[0]
+ && ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0
+ || (req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
+ || (req->ai_protocol != 0
+ && !(tp->protoflag & GAI_PROTO_PROTOANY)
+ && req->ai_protocol != tp->protocol)))
+ ++tp;
+
+ if (! tp->name[0])
+ {
+ if (req->ai_socktype)
+ return GAIH_OKIFUNSPEC | -EAI_SOCKTYPE;
+ else
+ return GAIH_OKIFUNSPEC | -EAI_SERVICE;
+ }
+ }
+
+ *pai = malloc (sizeof (struct addrinfo) + sizeof (struct sockaddr_un)
+ + ((req->ai_flags & AI_CANONNAME)
+ ? (strlen(utsname.nodename) + 1): 0));
+ if (*pai == NULL)
+ return -EAI_MEMORY;
+
+ (*pai)->ai_next = NULL;
+ (*pai)->ai_flags = req->ai_flags;
+ (*pai)->ai_family = AF_LOCAL;
+ (*pai)->ai_socktype = req->ai_socktype ? req->ai_socktype : SOCK_STREAM;
+ (*pai)->ai_protocol = req->ai_protocol;
+ (*pai)->ai_addrlen = sizeof (struct sockaddr_un);
+ (*pai)->ai_addr = (void *) (*pai) + sizeof (struct addrinfo);
+
+#ifdef _HAVE_SA_LEN
+ ((struct sockaddr_un *) (*pai)->ai_addr)->sun_len =
+ sizeof (struct sockaddr_un);
+#endif /* _HAVE_SA_LEN */
+
+ ((struct sockaddr_un *)(*pai)->ai_addr)->sun_family = AF_LOCAL;
+ memset(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, 0, UNIX_PATH_MAX);
+
+ if (service)
+ {
+ struct sockaddr_un *sunp = (struct sockaddr_un *) (*pai)->ai_addr;
+
+ if (strchr (service->name, '/') != NULL)
+ {
+ if (strlen (service->name) >= sizeof (sunp->sun_path))
+ return GAIH_OKIFUNSPEC | -EAI_SERVICE;
+
+ strcpy (sunp->sun_path, service->name);
+ }
+ else
+ {
+ if (strlen (P_tmpdir "/") + 1 + strlen (service->name) >=
+ sizeof (sunp->sun_path))
+ return GAIH_OKIFUNSPEC | -EAI_SERVICE;
+
+ __stpcpy (__stpcpy (sunp->sun_path, P_tmpdir "/"), service->name);
+ }
+ }
+ else
+ {
+ /* This is a dangerous use of the interface since there is a time
+ window between the test for the file and the actual creation
+ (done by the caller) in which a file with the same name could
+ be created. */
+ char *buf = ((struct sockaddr_un *) (*pai)->ai_addr)->sun_path;
+
+ if (__builtin_expect (__path_search (buf, L_tmpnam, NULL, NULL, 0),
+ 0) != 0
+ || __builtin_expect (__gen_tempname (buf, __GT_NOCREATE), 0) != 0)
+ return -EAI_SYSTEM;
+ }
+
+ if (req->ai_flags & AI_CANONNAME)
+ (*pai)->ai_canonname = strcpy ((char *) *pai + sizeof (struct addrinfo)
+ + sizeof (struct sockaddr_un),
+ utsname.nodename);
+ else
+ (*pai)->ai_canonname = NULL;
+ return 0;
+}
+#endif /* 0 */
+
+
+static int
+gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
+ const struct addrinfo *req, struct gaih_servtuple *st)
+{
+ struct servent *s;
+ size_t tmpbuflen = 1024;
+ struct servent ts;
+ char *tmpbuf;
+ int r;
+
+ do
+ {
+ tmpbuf = __alloca (tmpbuflen);
+
+ r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
+ &s);
+ if (r != 0 || s == NULL)
+ {
+ if (r == ERANGE)
+ tmpbuflen *= 2;
+ else
+ return GAIH_OKIFUNSPEC | -EAI_SERVICE;
+ }
+ }
+ while (r);
+
+ st->next = NULL;
+ st->socktype = tp->socktype;
+ st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
+ ? req->ai_protocol : tp->protocol);
+ st->port = s->s_port;
+
+ return 0;
+}
+
+#define gethosts(_family, _type) \
+ { \
+ int i; \
+ int herrno; \
+ struct hostent th; \
+ struct hostent *h; \
+ char *localcanon = NULL; \
+ no_data = 0; \
+ while (1) { \
+ rc = 0; \
+ status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \
+ &rc, &herrno, NULL, &localcanon)); \
+ if (rc != ERANGE || herrno != NETDB_INTERNAL) \
+ break; \
+ tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
+ } \
+ if (status == NSS_STATUS_SUCCESS && rc == 0) \
+ h = &th; \
+ else \
+ h = NULL; \
+ if (rc != 0) \
+ { \
+ if (herrno == NETDB_INTERNAL) \
+ { \
+ __set_h_errno (herrno); \
+ return -EAI_SYSTEM; \
+ } \
+ if (herrno == TRY_AGAIN) \
+ no_data = EAI_AGAIN; \
+ else \
+ no_data = herrno == NO_DATA; \
+ } \
+ else if (h != NULL) \
+ { \
+ for (i = 0; h->h_addr_list[i]; i++) \
+ { \
+ if (*pat == NULL) \
+ { \
+ *pat = __alloca (sizeof (struct gaih_addrtuple)); \
+ (*pat)->scopeid = 0; \
+ } \
+ uint32_t *addr = (*pat)->addr; \
+ (*pat)->next = NULL; \
+ (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
+ if (_family == AF_INET && req->ai_family == AF_INET6) \
+ { \
+ (*pat)->family = AF_INET6; \
+ addr[3] = *(uint32_t *) h->h_addr_list[i]; \
+ addr[2] = htonl (0xffff); \
+ addr[1] = 0; \
+ addr[0] = 0; \
+ } \
+ else \
+ { \
+ (*pat)->family = _family; \
+ memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
+ } \
+ pat = &((*pat)->next); \
+ } \
+ \
+ if (localcanon != NULL && canon == NULL) \
+ canon = strdupa (localcanon); \
+ \
+ if (_family == AF_INET6 && i > 0) \
+ got_ipv6 = true; \
+ } \
+ }
+
+
+typedef enum nss_status (*nss_gethostbyname3_r)
+ (const char *name, int af, struct hostent *host,
+ char *buffer, size_t buflen, int *errnop,
+ int *h_errnop, int32_t *ttlp, char **canonp);
+typedef enum nss_status (*nss_getcanonname_r)
+ (const char *name, char *buffer, size_t buflen, char **result,
+ int *errnop, int *h_errnop);
+extern service_user *__nss_hosts_database attribute_hidden;
+
+
+static int
+gaih_inet (const char *name, const struct gaih_service *service,
+ const struct addrinfo *req, struct addrinfo **pai,
+ unsigned int *naddrs)
+{
+ const struct gaih_typeproto *tp = gaih_inet_typeproto;
+ struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
+ struct gaih_addrtuple *at = NULL;
+ int rc;
+ bool got_ipv6 = false;
+ const char *canon = NULL;
+ const char *orig_name = name;
+
+ if (req->ai_protocol || req->ai_socktype)
+ {
+ ++tp;
+
+ while (tp->name[0]
+ && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
+ || (req->ai_protocol != 0
+ && !(tp->protoflag & GAI_PROTO_PROTOANY)
+ && req->ai_protocol != tp->protocol)))
+ ++tp;
+
+ if (! tp->name[0])
+ {
+ if (req->ai_socktype)
+ return GAIH_OKIFUNSPEC | -EAI_SOCKTYPE;
+ else
+ return GAIH_OKIFUNSPEC | -EAI_SERVICE;
+ }
+ }
+
+ int port = 0;
+ if (service != NULL)
+ {
+ if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
+ return GAIH_OKIFUNSPEC | -EAI_SERVICE;
+
+ if (service->num < 0)
+ {
+ if (tp->name[0])
+ {
+ st = (struct gaih_servtuple *)
+ __alloca (sizeof (struct gaih_servtuple));
+
+ if ((rc = gaih_inet_serv (service->name, tp, req, st)))
+ return rc;
+ }
+ else
+ {
+ struct gaih_servtuple **pst = &st;
+ for (tp++; tp->name[0]; tp++)
+ {
+ struct gaih_servtuple *newp;
+
+ if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
+ continue;
+
+ if (req->ai_socktype != 0
+ && req->ai_socktype != tp->socktype)
+ continue;
+ if (req->ai_protocol != 0
+ && !(tp->protoflag & GAI_PROTO_PROTOANY)
+ && req->ai_protocol != tp->protocol)
+ continue;
+
+ newp = (struct gaih_servtuple *)
+ __alloca (sizeof (struct gaih_servtuple));
+
+ if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
+ {
+ if (rc & GAIH_OKIFUNSPEC)
+ continue;
+ return rc;
+ }
+
+ *pst = newp;
+ pst = &(newp->next);
+ }
+ if (st == (struct gaih_servtuple *) &nullserv)
+ return GAIH_OKIFUNSPEC | -EAI_SERVICE;
+ }
+ }
+ else
+ {
+ port = htons (service->num);
+ goto got_port;
+ }
+ }
+ else
+ {
+ got_port:
+
+ if (req->ai_socktype || req->ai_protocol)
+ {
+ st = __alloca (sizeof (struct gaih_servtuple));
+ st->next = NULL;
+ st->socktype = tp->socktype;
+ st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
+ ? req->ai_protocol : tp->protocol);
+ st->port = port;
+ }
+ else
+ {
+ /* Neither socket type nor protocol is set. Return all socket types
+ we know about. */
+ struct gaih_servtuple **lastp = &st;
+ for (++tp; tp->name[0]; ++tp)
+ {
+ struct gaih_servtuple *newp;
+
+ newp = __alloca (sizeof (struct gaih_servtuple));
+ newp->next = NULL;
+ newp->socktype = tp->socktype;
+ newp->protocol = tp->protocol;
+ newp->port = port;
+
+ *lastp = newp;
+ lastp = &newp->next;
+ }
+ }
+ }
+
+ if (name != NULL)
+ {
+ at = __alloca (sizeof (struct gaih_addrtuple));
+
+ at->family = AF_UNSPEC;
+ at->scopeid = 0;
+ at->next = NULL;
+
+#ifdef HAVE_LIBIDN
+ if (req->ai_flags & AI_IDN)
+ {
+ int idn_flags = 0;
+ if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
+ idn_flags |= IDNA_ALLOW_UNASSIGNED;
+ if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
+ idn_flags |= IDNA_USE_STD3_ASCII_RULES;
+
+ char *p = NULL;
+ rc = __idna_to_ascii_lz (name, &p, idn_flags);
+ if (rc != IDNA_SUCCESS)
+ {
+ if (rc == IDNA_MALLOC_ERROR)
+ return -EAI_MEMORY;
+ if (rc == IDNA_DLOPEN_ERROR)
+ return -EAI_SYSTEM;
+ return -EAI_IDN_ENCODE;
+ }
+ /* In case the output string is the same as the input string
+ no new string has been allocated. */
+ if (p != name)
+ {
+ name = strdupa (p);
+ free (p);
+ }
+ }
+#endif
+
+ if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
+ {
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
+ at->family = AF_INET;
+ else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
+ {
+ at->addr[3] = at->addr[0];
+ at->addr[2] = htonl (0xffff);
+ at->addr[1] = 0;
+ at->addr[0] = 0;
+ at->family = AF_INET6;
+ }
+ else
+ return -EAI_ADDRFAMILY;
+
+ if (req->ai_flags & AI_CANONNAME)
+ canon = name;
+ }
+ else if (at->family == AF_UNSPEC)
+ {
+ char *namebuf = (char *) name;
+ char *scope_delim = strchr (name, SCOPE_DELIMITER);
+
+ if (__builtin_expect (scope_delim != NULL, 0))
+ {
+ namebuf = alloca (scope_delim - name + 1);
+ *((char *) __mempcpy (namebuf, name, scope_delim - name)) = '\0';
+ }
+
+ if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
+ {
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
+ at->family = AF_INET6;
+ else if (req->ai_family == AF_INET
+ && IN6_IS_ADDR_V4MAPPED (at->addr))
+ {
+ at->addr[0] = at->addr[3];
+ at->family = AF_INET;
+ }
+ else
+ return -EAI_ADDRFAMILY;
+
+ if (scope_delim != NULL)
+ {
+ int try_numericscope = 0;
+ if (IN6_IS_ADDR_LINKLOCAL (at->addr)
+ || IN6_IS_ADDR_MC_LINKLOCAL (at->addr))
+ {
+ at->scopeid = if_nametoindex (scope_delim + 1);
+ if (at->scopeid == 0)
+ try_numericscope = 1;
+ }
+ else
+ try_numericscope = 1;
+
+ if (try_numericscope != 0)
+ {
+ char *end;
+ assert (sizeof (uint32_t) <= sizeof (unsigned long));
+ at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
+ 10);
+ if (*end != '\0')
+ return GAIH_OKIFUNSPEC | -EAI_NONAME;
+ }
+ }
+
+ if (req->ai_flags & AI_CANONNAME)
+ canon = name;
+ }
+ }
+
+ if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
+ {
+ struct gaih_addrtuple **pat = &at;
+ int no_data = 0;
+ int no_inet6_data = 0;
+ service_user *nip = NULL;
+ enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
+ enum nss_status status = NSS_STATUS_UNAVAIL;
+ int no_more;
+ int old_res_options;
+
+ /* If we do not have to look for IPv4 and IPv6 together, use
+ the simple, old functions. */
+ if (req->ai_family == AF_INET
+ || (req->ai_family == AF_INET6
+ && ((req->ai_flags & AI_V4MAPPED) == 0
+ || (req->ai_flags & AI_ALL) == 0)))
+ {
+ int family = req->ai_family;
+ size_t tmpbuflen = 512;
+ char *tmpbuf = alloca (tmpbuflen);
+ int rc;
+ struct hostent th;
+ struct hostent *h;
+ int herrno;
+
+ simple_again:
+ while (1)
+ {
+ rc = __gethostbyname2_r (name, family, &th, tmpbuf,
+ tmpbuflen, &h, &herrno);
+ if (rc != ERANGE || herrno != NETDB_INTERNAL)
+ break;
+ tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
+ }
+
+ if (rc == 0)
+ {
+ if (h == NULL)
+ {
+ if (req->ai_family == AF_INET6
+ && (req->ai_flags & AI_V4MAPPED)
+ && family == AF_INET6)
+ {
+ /* Try again, this time looking for IPv4
+ addresses. */
+ family = AF_INET;
+ goto simple_again;
+ }
+ }
+ else
+ {
+ /* We found data, now convert it into the list. */
+ for (int i = 0; h->h_addr_list[i]; ++i)
+ {
+ if (*pat == NULL)
+ {
+ *pat = __alloca (sizeof (struct gaih_addrtuple));
+ (*pat)->scopeid = 0;
+ }
+ (*pat)->next = NULL;
+ (*pat)->family = req->ai_family;
+ if (family == req->ai_family)
+ memcpy ((*pat)->addr, h->h_addr_list[i],
+ h->h_length);
+ else
+ {
+ uint32_t *addr = (uint32_t *) (*pat)->addr;
+ addr[3] = *(uint32_t *) h->h_addr_list[i];
+ addr[2] = htonl (0xffff);
+ addr[1] = 0;
+ addr[0] = 0;
+ }
+ pat = &((*pat)->next);
+ }
+ }
+ }
+ else
+ {
+ if (herrno == NETDB_INTERNAL)
+ {
+ __set_h_errno (herrno);
+ return -EAI_SYSTEM;
+ }
+ if (herrno == TRY_AGAIN)
+ {
+ return -EAI_AGAIN;
+ }
+ /* We made requests but they turned out no data.
+ The name is known, though. */
+ return GAIH_OKIFUNSPEC | -EAI_NODATA;
+ }
+
+ goto process_list;
+ }
+
+#ifdef USE_NSCD
+ if (__nss_not_use_nscd_hosts > 0
+ && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
+ __nss_not_use_nscd_hosts = 0;
+
+ if (!__nss_not_use_nscd_hosts)
+ {
+ /* Try to use nscd. */
+ struct nscd_ai_result *air = NULL;
+ int herrno;
+ int err = __nscd_getai (name, &air, &herrno);
+ if (air != NULL)
+ {
+ /* Transform into gaih_addrtuple list. */
+ bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
+ char *addrs = air->addrs;
+
+ for (int i = 0; i < air->naddrs; ++i)
+ {
+ socklen_t size = (air->family[i] == AF_INET
+ ? INADDRSZ : IN6ADDRSZ);
+ if (*pat == NULL)
+ {
+ *pat = __alloca (sizeof (struct gaih_addrtuple));
+ (*pat)->scopeid = 0;
+ }
+ uint32_t *pataddr = (*pat)->addr;
+ (*pat)->next = NULL;
+ if (added_canon || air->canon == NULL)
+ (*pat)->name = NULL;
+ else
+ canon = (*pat)->name = strdupa (air->canon);
+
+ if (air->family[i] == AF_INET
+ && req->ai_family == AF_INET6
+ && (req->ai_flags & AI_V4MAPPED))
+ {
+ (*pat)->family = AF_INET6;
+ pataddr[3] = *(uint32_t *) addrs;
+ pataddr[2] = htonl (0xffff);
+ pataddr[1] = 0;
+ pataddr[0] = 0;
+ pat = &((*pat)->next);
+ added_canon = true;
+ }
+ else if (req->ai_family == AF_UNSPEC
+ || air->family[i] == req->ai_family)
+ {
+ (*pat)->family = air->family[i];
+ memcpy (pataddr, addrs, size);
+ pat = &((*pat)->next);
+ added_canon = true;
+ if (air->family[i] == AF_INET6)
+ got_ipv6 = true;
+ }
+ addrs += size;
+ }
+
+ free (air);
+
+ if (at->family == AF_UNSPEC)
+ return GAIH_OKIFUNSPEC | -EAI_NONAME;
+
+ goto process_list;
+ }
+ else if (err != 0 && __nss_not_use_nscd_hosts == 0)
+ {
+ if (herrno == NETDB_INTERNAL && errno == ENOMEM)
+ return -EAI_MEMORY;
+ if (herrno == TRY_AGAIN)
+ return -EAI_AGAIN;
+ return -EAI_SYSTEM;
+ }
+ }
+#endif
+
+ if (__nss_hosts_database != NULL)
+ {
+ no_more = 0;
+ nip = __nss_hosts_database;
+ }
+ else
+ no_more = __nss_database_lookup ("hosts", NULL,
+ "dns [!UNAVAIL=return] files",
+ &nip);
+
+ if (__res_maybe_init (&_res, 0) == -1)
+ no_more = 1;
+
+ /* If we are looking for both IPv4 and IPv6 address we don't
+ want the lookup functions to automatically promote IPv4
+ addresses to IPv6 addresses. Currently this is decided
+ by setting the RES_USE_INET6 bit in _res.options. */
+ old_res_options = _res.options;
+ _res.options &= ~RES_USE_INET6;
+
+ size_t tmpbuflen = 512;
+ char *tmpbuf = alloca (tmpbuflen);
+
+ while (!no_more)
+ {
+ nss_gethostbyname3_r fct = NULL;
+ if (req->ai_flags & AI_CANONNAME)
+ /* No need to use this function if we do not look for
+ the canonical name. The function does not exist in
+ all NSS modules and therefore the lookup would
+ often fail. */
+ fct = __nss_lookup_function (nip, "gethostbyname3_r");
+ if (fct == NULL)
+ /* We are cheating here. The gethostbyname2_r function does
+ not have the same interface as gethostbyname3_r but the
+ extra arguments the latter takes are added at the end.
+ So the gethostbyname2_r code will just ignore them. */
+ fct = __nss_lookup_function (nip, "gethostbyname2_r");
+
+ if (fct != NULL)
+ {
+ if (req->ai_family == AF_INET6
+ || req->ai_family == AF_UNSPEC)
+ {
+ gethosts (AF_INET6, struct in6_addr);
+ no_inet6_data = no_data;
+ inet6_status = status;
+ }
+ if (req->ai_family == AF_INET
+ || req->ai_family == AF_UNSPEC
+ || (req->ai_family == AF_INET6
+ && (req->ai_flags & AI_V4MAPPED)
+ /* Avoid generating the mapped addresses if we
+ know we are not going to need them. */
+ && ((req->ai_flags & AI_ALL) || !got_ipv6)))
+ {
+ gethosts (AF_INET, struct in_addr);
+
+ if (req->ai_family == AF_INET)
+ {
+ no_inet6_data = no_data;
+ inet6_status = status;
+ }
+ }
+
+ /* If we found one address for AF_INET or AF_INET6,
+ don't continue the search. */
+ if (inet6_status == NSS_STATUS_SUCCESS
+ || status == NSS_STATUS_SUCCESS)
+ {
+ if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
+ {
+ /* If we need the canonical name, get it
+ from the same service as the result. */
+ nss_getcanonname_r cfct;
+ int herrno;
+
+ cfct = __nss_lookup_function (nip, "getcanonname_r");
+ if (cfct != NULL)
+ {
+ const size_t max_fqdn_len = 256;
+ char *buf = alloca (max_fqdn_len);
+ char *s;
+
+ if (DL_CALL_FCT (cfct, (at->name ?: name, buf,
+ max_fqdn_len, &s, &rc,
+ &herrno))
+ == NSS_STATUS_SUCCESS)
+ canon = s;
+ else
+ /* Set to name now to avoid using
+ gethostbyaddr. */
+ canon = name;
+ }
+ }
+
+ break;
+ }
+
+ /* We can have different states for AF_INET and
+ AF_INET6. Try to find a useful one for both. */
+ if (inet6_status == NSS_STATUS_TRYAGAIN)
+ status = NSS_STATUS_TRYAGAIN;
+ else if (status == NSS_STATUS_UNAVAIL
+ && inet6_status != NSS_STATUS_UNAVAIL)
+ status = inet6_status;
+ }
+
+ if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
+ break;
+
+ if (nip->next == NULL)
+ no_more = -1;
+ else
+ nip = nip->next;
+ }
+
+ _res.options = old_res_options;
+
+ if (no_data != 0 && no_inet6_data != 0)
+ {
+ /* If both requests timed out report this. */
+ if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
+ return -EAI_AGAIN;
+
+ /* We made requests but they turned out no data. The name
+ is known, though. */
+ return GAIH_OKIFUNSPEC | -EAI_NODATA;
+ }
+ }
+
+ process_list:
+ if (at->family == AF_UNSPEC)
+ return GAIH_OKIFUNSPEC | -EAI_NONAME;
+ }
+ else
+ {
+ struct gaih_addrtuple *atr;
+ atr = at = __alloca (sizeof (struct gaih_addrtuple));
+ memset (at, '\0', sizeof (struct gaih_addrtuple));
+
+ if (req->ai_family == AF_UNSPEC)
+ {
+ at->next = __alloca (sizeof (struct gaih_addrtuple));
+ memset (at->next, '\0', sizeof (struct gaih_addrtuple));
+ }
+
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
+ {
+ at->family = AF_INET6;
+ if ((req->ai_flags & AI_PASSIVE) == 0)
+ memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
+ atr = at->next;
+ }
+
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
+ {
+ atr->family = AF_INET;
+ if ((req->ai_flags & AI_PASSIVE) == 0)
+ atr->addr[0] = htonl (INADDR_LOOPBACK);
+ }
+ }
+
+ if (pai == NULL)
+ return 0;
+
+ {
+ struct gaih_servtuple *st2;
+ struct gaih_addrtuple *at2 = at;
+ size_t socklen;
+ sa_family_t family;
+
+ /*
+ buffer is the size of an unformatted IPv6 address in printable format.
+ */
+ while (at2 != NULL)
+ {
+ /* Only the first entry gets the canonical name. */
+ if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
+ {
+ if (canon == NULL)
+ {
+ struct hostent *h = NULL;
+ int herrno;
+ struct hostent th;
+ size_t tmpbuflen = 512;
+ char *tmpbuf = NULL;
+
+ do
+ {
+ tmpbuf = extend_alloca (tmpbuf, tmpbuflen, tmpbuflen * 2);
+ rc = __gethostbyaddr_r (at2->addr,
+ ((at2->family == AF_INET6)
+ ? sizeof (struct in6_addr)
+ : sizeof (struct in_addr)),
+ at2->family, &th, tmpbuf,
+ tmpbuflen, &h, &herrno);
+ }
+ while (rc == ERANGE && herrno == NETDB_INTERNAL);
+
+ if (rc != 0 && herrno == NETDB_INTERNAL)
+ {
+ __set_h_errno (herrno);
+ return -EAI_SYSTEM;
+ }
+
+ if (h != NULL)
+ canon = h->h_name;
+ else
+ {
+ assert (orig_name != NULL);
+ /* If the canonical name cannot be determined, use
+ the passed in string. */
+ canon = orig_name;
+ }
+ }
+
+#ifdef HAVE_LIBIDN
+ if (req->ai_flags & AI_CANONIDN)
+ {
+ int idn_flags = 0;
+ if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
+ idn_flags |= IDNA_ALLOW_UNASSIGNED;
+ if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
+ idn_flags |= IDNA_USE_STD3_ASCII_RULES;
+
+ char *out;
+ int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
+ if (rc != IDNA_SUCCESS)
+ {
+ if (rc == IDNA_MALLOC_ERROR)
+ return -EAI_MEMORY;
+ if (rc == IDNA_DLOPEN_ERROR)
+ return -EAI_SYSTEM;
+ return -EAI_IDN_ENCODE;
+ }
+ /* In case the output string is the same as the input
+ string no new string has been allocated. Otherwise
+ make a copy. */
+ if (out == canon)
+ goto make_copy;
+ }
+ else
+#endif
+ {
+#ifdef HAVE_LIBIDN
+ make_copy:
+#endif
+ canon = strdup (canon);
+ if (canon == NULL)
+ return -EAI_MEMORY;
+ }
+ }
+
+ family = at2->family;
+ if (family == AF_INET6)
+ {
+ socklen = sizeof (struct sockaddr_in6);
+
+ /* If we looked up IPv4 mapped address discard them here if
+ the caller isn't interested in all address and we have
+ found at least one IPv6 address. */
+ if (got_ipv6
+ && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
+ && IN6_IS_ADDR_V4MAPPED (at2->addr))
+ goto ignore;
+ }
+ else
+ socklen = sizeof (struct sockaddr_in);
+
+ for (st2 = st; st2 != NULL; st2 = st2->next)
+ {
+ struct addrinfo *ai;
+ ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
+ if (ai == NULL)
+ {
+ free ((char *) canon);
+ return -EAI_MEMORY;
+ }
+
+ ai->ai_flags = req->ai_flags;
+ ai->ai_family = family;
+ ai->ai_socktype = st2->socktype;
+ ai->ai_protocol = st2->protocol;
+ ai->ai_addrlen = socklen;
+ ai->ai_addr = (void *) (ai + 1);
+
+ /* We only add the canonical name once. */
+ ai->ai_canonname = (char *) canon;
+ canon = NULL;
+
+#ifdef _HAVE_SA_LEN
+ ai->ai_addr->sa_len = socklen;
+#endif /* _HAVE_SA_LEN */
+ ai->ai_addr->sa_family = family;
+
+ /* In case of an allocation error the list must be NULL
+ terminated. */
+ ai->ai_next = NULL;
+
+ if (family == AF_INET6)
+ {
+ struct sockaddr_in6 *sin6p =
+ (struct sockaddr_in6 *) ai->ai_addr;
+
+ sin6p->sin6_port = st2->port;
+ sin6p->sin6_flowinfo = 0;
+ memcpy (&sin6p->sin6_addr,
+ at2->addr, sizeof (struct in6_addr));
+ sin6p->sin6_scope_id = at2->scopeid;
+ }
+ else
+ {
+ struct sockaddr_in *sinp =
+ (struct sockaddr_in *) ai->ai_addr;
+ sinp->sin_port = st2->port;
+ memcpy (&sinp->sin_addr,
+ at2->addr, sizeof (struct in_addr));
+ memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
+ }
+
+ pai = &(ai->ai_next);
+ }
+
+ ++*naddrs;
+
+ ignore:
+ at2 = at2->next;
+ }
+ }
+ return 0;
+}
+
+#if 0
+static const struct gaih gaih[] =
+ {
+ { PF_INET6, gaih_inet },
+ { PF_INET, gaih_inet },
+#if 0
+ { PF_LOCAL, gaih_local },
+#endif
+ { PF_UNSPEC, NULL }
+ };
+#endif
+
+struct sort_result
+{
+ struct addrinfo *dest_addr;
+ struct sockaddr_storage source_addr;
+ uint8_t source_addr_len;
+ bool got_source_addr;
+ uint8_t source_addr_flags;
+};
+
+
+static int
+get_scope (const struct sockaddr_storage *ss)
+{
+ int scope;
+ if (ss->ss_family == PF_INET6)
+ {
+ const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *) ss;
+
+ if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
+ {
+ if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr))
+ scope = 2;
+ else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
+ scope = 5;
+ else
+ /* XXX Is this the correct default behavior? */
+ scope = 14;
+ }
+ else
+ scope = in6->sin6_addr.s6_addr[1] & 0xf;
+ }
+ else if (ss->ss_family == PF_INET)
+ {
+ const struct sockaddr_in *in = (const struct sockaddr_in *) ss;
+ const uint8_t *addr = (const uint8_t *) &in->sin_addr;
+
+ /* RFC 3484 specifies how to map IPv6 addresses to scopes.
+ 169.254/16 and 127/8 are link-local. */
+ if ((addr[0] == 169 && addr[1] == 254) || addr[0] == 127)
+ scope = 2;
+ else if (addr[0] == 10 || (addr[0] == 172 && addr[1] == 16)
+ || (addr[0] == 192 && addr[1] == 168))
+ scope = 5;
+ else
+ scope = 14;
+ }
+ else
+ /* XXX What is a good default? */
+ scope = 15;
+
+ return scope;
+}
+
+
+struct prefixentry
+{
+ struct in6_addr prefix;
+ unsigned int bits;
+ int val;
+};
+
+
+/* The label table. */
+static const struct prefixentry *labels;
+
+/* Default labels. */
+static const struct prefixentry default_labels[] =
+ {
+ /* See RFC 3484 for the details. */
+ { { .in6_u
+ = { .u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } },
+ 128, 0 },
+ { { .in6_u
+ = { .u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ 16, 2 },
+ { { .in6_u
+ = { .u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ 96, 3 },
+ { { .in6_u
+ = { .u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } },
+ 96, 4 },
+ /* The next two entries differ from RFC 3484. We need to treat
+ IPv6 site-local addresses special because they are never NATed,
+ unlike site-locale IPv4 addresses. If this would not happen, on
+ machines which have only IPv4 and IPv6 site-local addresses, the
+ sorting would prefer the IPv6 site-local addresses, causing
+ unnecessary delays when trying to connect to a global IPv6 address
+ through a site-local IPv6 address. */
+ { { .in6_u
+ = { .u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ 10, 5 },
+ { { .in6_u
+ = { .u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ 7, 6 },
+ { { .in6_u
+ = { .u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ 0, 1 }
+ };
+
+
+/* The precedence table. */
+static const struct prefixentry *precedence;
+
+/* The default precedences. */
+static const struct prefixentry default_precedence[] =
+ {
+ /* See RFC 3484 for the details. */
+ { { .in6_u
+ = { .u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } },
+ 128, 50 },
+ { { .in6_u
+ = { .u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ 16, 30 },
+ { { .in6_u
+ = { .u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ 96, 20 },
+ { { .in6_u
+ = { .u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } },
+ 96, 10 },
+ { { .in6_u
+ = { .u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ 0, 40 }
+ };
+
+
+static int
+match_prefix (const struct sockaddr_storage *ss,
+ const struct prefixentry *list, int default_val)
+{
+ int idx;
+ struct sockaddr_in6 in6_mem;
+ const struct sockaddr_in6 *in6;
+
+ if (ss->ss_family == PF_INET6)
+ in6 = (const struct sockaddr_in6 *) ss;
+ else if (ss->ss_family == PF_INET)
+ {
+ const struct sockaddr_in *in = (const struct sockaddr_in *) ss;
+
+ /* Convert to IPv6 address. */
+ in6_mem.sin6_family = PF_INET6;
+ in6_mem.sin6_port = in->sin_port;
+ in6_mem.sin6_flowinfo = 0;
+ if (in->sin_addr.s_addr == htonl (0x7f000001))
+ in6_mem.sin6_addr = (struct in6_addr) IN6ADDR_LOOPBACK_INIT;
+ else
+ {
+ /* Construct a V4-to-6 mapped address. */
+ memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
+ in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
+ in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
+ in6_mem.sin6_scope_id = 0;
+ }
+
+ in6 = &in6_mem;
+ }
+ else
+ return default_val;
+
+ for (idx = 0; ; ++idx)
+ {
+ unsigned int bits = list[idx].bits;
+ uint8_t *mask = list[idx].prefix.s6_addr;
+ uint8_t *val = in6->sin6_addr.s6_addr;
+
+ while (bits >= 8)
+ {
+ if (*mask != *val)
+ break;
+
+ ++mask;
+ ++val;
+ bits -= 8;
+ }
+
+ if (bits < 8)
+ {
+ if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
+ /* Match! */
+ break;
+ }
+ }
+
+ return list[idx].val;
+}
+
+
+static int
+get_label (const struct sockaddr_storage *ss)
+{
+ /* XXX What is a good default value? */
+ return match_prefix (ss, labels, INT_MAX);
+}
+
+
+static int
+get_precedence (const struct sockaddr_storage *ss)
+{
+ /* XXX What is a good default value? */
+ return match_prefix (ss, precedence, 0);
+}
+
+
+/* Find last bit set in a word. */
+static int
+fls (uint32_t a)
+{
+ uint32_t mask;
+ int n = 0;
+ for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
+ if ((a & mask) != 0)
+ break;
+ return n;
+}
+
+
+static int
+rfc3484_sort (const void *p1, const void *p2)
+{
+ const struct sort_result *a1 = (const struct sort_result *) p1;
+ const struct sort_result *a2 = (const struct sort_result *) p2;
+
+ /* Rule 1: Avoid unusable destinations.
+ We have the got_source_addr flag set if the destination is reachable. */
+ if (a1->got_source_addr && ! a2->got_source_addr)
+ return -1;
+ if (! a1->got_source_addr && a2->got_source_addr)
+ return 1;
+
+
+ /* Rule 2: Prefer matching scope. Only interesting if both
+ destination addresses are IPv6. */
+ int a1_dst_scope
+ = get_scope ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
+
+ int a2_dst_scope
+ = get_scope ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
+
+ if (a1->got_source_addr)
+ {
+ int a1_src_scope = get_scope (&a1->source_addr);
+ int a2_src_scope = get_scope (&a2->source_addr);
+
+ if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
+ return -1;
+ if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
+ return 1;
+ }
+
+
+ /* Rule 3: Avoid deprecated addresses. */
+ if (a1->got_source_addr)
+ {
+ if (!(a1->source_addr_flags & in6ai_deprecated)
+ && (a2->source_addr_flags & in6ai_deprecated))
+ return -1;
+ if ((a1->source_addr_flags & in6ai_deprecated)
+ && !(a2->source_addr_flags & in6ai_deprecated))
+ return 1;
+ }
+
+ /* Rule 4: Prefer home addresses.
+ Another thing only the kernel can decide. */
+
+ /* Rule 5: Prefer matching label. */
+ if (a1->got_source_addr)
+ {
+ int a1_dst_label
+ = get_label ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
+ int a1_src_label = get_label (&a1->source_addr);
+
+ int a2_dst_label
+ = get_label ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
+ int a2_src_label = get_label (&a2->source_addr);
+
+ if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
+ return -1;
+ if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
+ return 1;
+ }
+
+
+ /* Rule 6: Prefer higher precedence. */
+ int a1_prec
+ = get_precedence ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
+ int a2_prec
+ = get_precedence ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
+
+ if (a1_prec > a2_prec)
+ return -1;
+ if (a1_prec < a2_prec)
+ return 1;
+
+
+ /* Rule 7: Prefer native transport. */
+ if (a1->got_source_addr)
+ {
+ if (!(a1->source_addr_flags & in6ai_temporary)
+ && (a1->source_addr_flags & in6ai_temporary))
+ return -1;
+ if ((a1->source_addr_flags & in6ai_temporary)
+ && !(a1->source_addr_flags & in6ai_temporary))
+ return -1;
+
+ /* XXX Do we need to check anything beside temporary addresses? */
+ }
+
+
+ /* Rule 8: Prefer smaller scope. */
+ if (a1_dst_scope < a2_dst_scope)
+ return -1;
+ if (a1_dst_scope > a2_dst_scope)
+ return 1;
+
+
+ /* Rule 9: Use longest matching prefix. */
+ if (a1->got_source_addr
+ && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
+ {
+ int bit1 = 0;
+ int bit2 = 0;
+
+ if (a1->dest_addr->ai_family == PF_INET)
+ {
+ assert (a1->source_addr.ss_family == PF_INET);
+ assert (a2->source_addr.ss_family == PF_INET);
+
+ struct sockaddr_in *in1_dst;
+ struct sockaddr_in *in1_src;
+ struct sockaddr_in *in2_dst;
+ struct sockaddr_in *in2_src;
+
+ in1_dst = (struct sockaddr_in *) a1->dest_addr->ai_addr;
+ in1_src = (struct sockaddr_in *) &a1->source_addr;
+ in2_dst = (struct sockaddr_in *) a2->dest_addr->ai_addr;
+ in2_src = (struct sockaddr_in *) &a2->source_addr;
+
+ bit1 = fls (ntohl (in1_dst->sin_addr.s_addr
+ ^ in1_src->sin_addr.s_addr));
+ bit2 = fls (ntohl (in2_dst->sin_addr.s_addr
+ ^ in2_src->sin_addr.s_addr));
+ }
+ else if (a1->dest_addr->ai_family == PF_INET6)
+ {
+ assert (a1->source_addr.ss_family == PF_INET6);
+ assert (a2->source_addr.ss_family == PF_INET6);
+
+ struct sockaddr_in6 *in1_dst;
+ struct sockaddr_in6 *in1_src;
+ struct sockaddr_in6 *in2_dst;
+ struct sockaddr_in6 *in2_src;
+
+ in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
+ in1_src = (struct sockaddr_in6 *) &a1->source_addr;
+ in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
+ in2_src = (struct sockaddr_in6 *) &a2->source_addr;
+
+ int i;
+ for (i = 0; i < 4; ++i)
+ if (in1_dst->sin6_addr.s6_addr32[i]
+ != in1_src->sin6_addr.s6_addr32[i]
+ || (in2_dst->sin6_addr.s6_addr32[i]
+ != in2_src->sin6_addr.s6_addr32[i]))
+ break;
+
+ if (i < 4)
+ {
+ bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
+ ^ in1_src->sin6_addr.s6_addr32[i]));
+ bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
+ ^ in2_src->sin6_addr.s6_addr32[i]));
+ }
+ }
+
+ if (bit1 > bit2)
+ return -1;
+ if (bit1 < bit2)
+ return 1;
+ }
+
+
+ /* Rule 10: Otherwise, leave the order unchanged. */
+ return 0;
+}
+
+
+static int
+in6aicmp (const void *p1, const void *p2)
+{
+ struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
+ struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
+
+ return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
+}
+
+
+/* Name of the config file for RFC 3484 sorting (for now). */
+#define GAICONF_FNAME "/etc/gai.conf"
+
+
+/* Nozero if we are supposed to reload the config file automatically
+ whenever it changed. */
+static int gaiconf_reload_flag;
+
+/* Last modification time. */
+static struct timespec gaiconf_mtime;
+
+
+libc_freeres_fn(fini)
+{
+ if (labels != default_labels)
+ {
+ const struct prefixentry *old = labels;
+ labels = default_labels;
+ free ((void *) old);
+ }
+
+ if (precedence != default_precedence)
+ {
+ const struct prefixentry *old = precedence;
+ precedence = default_precedence;
+ free ((void *) old);
+ }
+}
+
+
+struct prefixlist
+{
+ struct prefixentry entry;
+ struct prefixlist *next;
+};
+
+
+static void
+free_prefixlist (struct prefixlist *list)
+{
+ while (list != NULL)
+ {
+ struct prefixlist *oldp = list;
+ list = list->next;
+ free (oldp);
+ }
+}
+
+
+static int
+prefixcmp (const void *p1, const void *p2)
+{
+ const struct prefixentry *e1 = (const struct prefixentry *) p1;
+ const struct prefixentry *e2 = (const struct prefixentry *) p2;
+
+ if (e1->bits < e2->bits)
+ return 1;
+ if (e1->bits == e2->bits)
+ return 0;
+ return -1;
+}
+
+
+static void
+gaiconf_init (void)
+{
+ struct prefixlist *labellist = NULL;
+ size_t nlabellist = 0;
+ bool labellist_nullbits = false;
+ struct prefixlist *precedencelist = NULL;
+ size_t nprecedencelist = 0;
+ bool precedencelist_nullbits = false;
+
+ FILE *fp = fopen (GAICONF_FNAME, "rc");
+ if (fp != NULL)
+ {
+ struct stat64 st;
+ if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
+ {
+ fclose (fp);
+ goto no_file;
+ }
+
+ char *line = NULL;
+ size_t linelen = 0;
+
+ __fsetlocking (fp, FSETLOCKING_BYCALLER);
+
+ while (!feof_unlocked (fp))
+ {
+ ssize_t n = __getline (&line, &linelen, fp);
+ if (n <= 0)
+ break;
+
+ /* Handle comments. No escaping possible so this is easy. */
+ char *cp = strchr (line, '#');
+ if (cp != NULL)
+ *cp = '\0';
+
+ cp = line;
+ while (isspace (*cp))
+ ++cp;
+
+ char *cmd = cp;
+ while (*cp != '\0' && !isspace (*cp))
+ ++cp;
+ size_t cmdlen = cp - cmd;
+
+ if (*cp != '\0')
+ *cp++ = '\0';
+ while (isspace (*cp))
+ ++cp;
+
+ char *val1 = cp;
+ while (*cp != '\0' && !isspace (*cp))
+ ++cp;
+ size_t val1len = cp - cmd;
+
+ /* We always need at least two values. */
+ if (val1len == 0)
+ continue;
+
+ if (*cp != '\0')
+ *cp++ = '\0';
+ while (isspace (*cp))
+ ++cp;
+
+ char *val2 = cp;
+ while (*cp != '\0' && !isspace (*cp))
+ ++cp;
+
+ /* Ignore the rest of the line. */
+ *cp = '\0';
+
+ struct prefixlist **listp;
+ size_t *lenp;
+ bool *nullbitsp;
+ switch (cmdlen)
+ {
+ case 5:
+ if (strcmp (cmd, "label") == 0)
+ {
+ struct in6_addr prefix;
+ unsigned long int bits;
+ unsigned long int val;
+ char *endp;
+
+ listp = &labellist;
+ lenp = &nlabellist;
+ nullbitsp = &labellist_nullbits;
+
+ new_elem:
+ bits = 128;
+ __set_errno (0);
+ cp = strchr (val1, '/');
+ if (cp != NULL)
+ *cp++ = '\0';
+ if (inet_pton (AF_INET6, val1, &prefix)
+ && (cp == NULL
+ || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
+ || errno != ERANGE)
+ && *endp == '\0'
+ && bits <= INT_MAX
+ && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
+ || errno != ERANGE)
+ && *endp == '\0'
+ && val <= INT_MAX)
+ {
+ struct prefixlist *newp = malloc (sizeof (*newp));
+ if (newp == NULL)
+ {
+ free (line);
+ fclose (fp);
+ goto no_file;
+ }
+
+ memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
+ newp->entry.bits = bits;
+ newp->entry.val = val;
+ newp->next = *listp;
+ *listp = newp;
+ ++*lenp;
+ *nullbitsp |= bits == 0;
+ }
+ }
+ break;
+
+ case 6:
+ if (strcmp (cmd, "reload") == 0)
+ gaiconf_reload_flag = strcmp (val1, "yes") == 0;
+ break;
+
+ case 10:
+ if (strcmp (cmd, "precedence") == 0)
+ {
+ listp = &precedencelist;
+ lenp = &nprecedencelist;
+ nullbitsp = &precedencelist_nullbits;
+ goto new_elem;
+ }
+ break;
+ }
+ }
+
+ free (line);
+
+ fclose (fp);
+
+ /* Create the array for the labels. */
+ struct prefixentry *new_labels;
+ if (nlabellist > 0)
+ {
+ if (!labellist_nullbits)
+ ++nlabellist;
+ new_labels = malloc (nlabellist * sizeof (*new_labels));
+ if (new_labels == NULL)
+ goto no_file;
+
+ int i = nlabellist;
+ if (!labellist_nullbits)
+ {
+ --i;
+ memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
+ new_labels[i].bits = 0;
+ new_labels[i].val = 1;
+ }
+
+ struct prefixlist *l = labellist;
+ while (i-- > 0)
+ {
+ new_labels[i] = l->entry;
+ l = l->next;
+ }
+ free_prefixlist (labellist);
+
+ /* Sort the entries so that the most specific ones are at
+ the beginning. */
+ qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
+ }
+ else
+ new_labels = (struct prefixentry *) default_labels;
+
+ struct prefixentry *new_precedence;
+ if (nprecedencelist > 0)
+ {
+ if (!precedencelist_nullbits)
+ ++nprecedencelist;
+ new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
+ if (new_precedence == NULL)
+ {
+ if (new_labels != default_labels)
+ free (new_labels);
+ goto no_file;
+ }
+
+ int i = nprecedencelist;
+ if (!precedencelist_nullbits)
+ {
+ --i;
+ memset (&new_precedence[i].prefix, '\0',
+ sizeof (struct in6_addr));
+ new_precedence[i].bits = 0;
+ new_precedence[i].val = 40;
+ }
+
+ struct prefixlist *l = precedencelist;
+ while (i-- > 0)
+ {
+ new_precedence[i] = l->entry;
+ l = l->next;
+ }
+ free_prefixlist (precedencelist);
+
+ /* Sort the entries so that the most specific ones are at
+ the beginning. */
+ qsort (new_precedence, nprecedencelist, sizeof (*new_labels),
+ prefixcmp);
+ }
+ else
+ new_precedence = (struct prefixentry *) default_precedence;
+
+ /* Now we are ready to replace the values. */
+ const struct prefixentry *old = labels;
+ labels = new_labels;
+ if (old != default_labels)
+ free ((void *) old);
+
+ old = precedence;
+ precedence = new_precedence;
+ if (old != default_precedence)
+ free ((void *) old);
+
+ gaiconf_mtime = st.st_mtim;
+ }
+ else
+ {
+ no_file:
+ free_prefixlist (labellist);
+ free_prefixlist (precedencelist);
+
+ /* If we previously read the file but it is gone now, free the
+ old data and use the builtin one. Leave the reload flag
+ alone. */
+ fini ();
+ }
+}
+
+
+static void
+gaiconf_reload (void)
+{
+ struct stat64 st;
+ if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
+ || memcmp (&st.st_mtim, &gaiconf_mtime, sizeof (gaiconf_mtime)) != 0)
+ gaiconf_init ();
+}
+
+
+int
+getaddrinfo (const char *name, const char *service,
+ const struct addrinfo *hints, struct addrinfo **pai)
+{
+ int i = 0, last_i = 0;
+ int nresults = 0;
+ struct addrinfo *p = NULL;
+ struct gaih_service gaih_service, *pservice;
+ struct addrinfo local_hints;
+
+ if (name != NULL && name[0] == '*' && name[1] == 0)
+ name = NULL;
+
+ if (service != NULL && service[0] == '*' && service[1] == 0)
+ service = NULL;
+
+ if (name == NULL && service == NULL)
+ return EAI_NONAME;
+
+ if (hints == NULL)
+ hints = &default_hints;
+
+ if (hints->ai_flags
+ & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
+#ifdef HAVE_LIBIDN
+ |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
+ |AI_IDN_USE_STD3_ASCII_RULES
+#endif
+ |AI_NUMERICSERV|AI_ALL))
+ return EAI_BADFLAGS;
+
+ if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
+ return EAI_BADFLAGS;
+
+ struct in6addrinfo *in6ai = NULL;
+ size_t in6ailen;
+ bool seen_ipv4 = false;
+ bool seen_ipv6 = false;
+ /* We might need information about what kind of interfaces are available.
+ But even if AI_ADDRCONFIG is not used, if the user requested IPv6
+ addresses we have to know whether an address is deprecated or
+ temporary. */
+ if ((hints->ai_flags & AI_ADDRCONFIG) || hints->ai_family == PF_UNSPEC
+ || hints->ai_family == PF_INET6)
+ /* Determine whether we have IPv4 or IPv6 interfaces or both. We
+ cannot cache the results since new interfaces could be added at
+ any time. */
+ __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
+
+ if (hints->ai_flags & AI_ADDRCONFIG)
+ {
+ /* Now make a decision on what we return, if anything. */
+ if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
+ {
+ /* If we haven't seen both IPv4 and IPv6 interfaces we can
+ narrow down the search. */
+ if (! seen_ipv4 || ! seen_ipv6)
+ {
+ local_hints = *hints;
+ local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
+ hints = &local_hints;
+ }
+ }
+ else if ((hints->ai_family == PF_INET && ! seen_ipv4)
+ || (hints->ai_family == PF_INET6 && ! seen_ipv6))
+ {
+ /* We cannot possibly return a valid answer. */
+ free (in6ai);
+ return EAI_NONAME;
+ }
+ }
+
+ if (service && service[0])
+ {
+ char *c;
+ gaih_service.name = service;
+ gaih_service.num = strtoul (gaih_service.name, &c, 10);
+ if (*c != '\0')
+ {
+ if (hints->ai_flags & AI_NUMERICSERV)
+ {
+ free (in6ai);
+ return EAI_NONAME;
+ }
+
+ gaih_service.num = -1;
+ }
+
+ pservice = &gaih_service;
+ }
+ else
+ pservice = NULL;
+
+ struct addrinfo **end;
+ if (pai)
+ end = &p;
+ else
+ end = NULL;
+
+ unsigned int naddrs = 0;
+#if 0
+ /* If we would support more protocols than just IPv4 and IPv6 we
+ would iterate over a table with appropriate callback functions.
+ Since we currently only handle IPv4 and IPv6 this is not
+ necessary. */
+ const struct gaih *g = gaih;
+ const struct gaih *pg = NULL;
+ int j = 0;
+ while (g->gaih)
+ {
+ if (hints->ai_family == g->family || hints->ai_family == AF_UNSPEC)
+ {
+ j++;
+ if (pg == NULL || pg->gaih != g->gaih)
+ {
+ pg = g;
+ i = g->gaih (name, pservice, hints, end, &naddrs);
+ if (i != 0)
+ {
+ /* EAI_NODATA is a more specific result as it says that
+ we found a result but it is not usable. */
+ if (last_i != (GAIH_OKIFUNSPEC | -EAI_NODATA))
+ last_i = i;
+
+ if (hints->ai_family == AF_UNSPEC && (i & GAIH_OKIFUNSPEC))
+ {
+ ++g;
+ continue;
+ }
+
+ freeaddrinfo (p);
+ free (in6ai);
+
+ return -(i & GAIH_EAI);
+ }
+ if (end)
+ while (*end)
+ {
+ end = &((*end)->ai_next);
+ ++nresults;
+ }
+ }
+ }
+ ++g;
+ }
+
+ if (j == 0)
+ {
+ free (in6ai);
+ return EAI_FAMILY;
+ }
+#else
+ if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
+ || hints->ai_family == AF_INET6)
+ {
+ last_i = gaih_inet (name, pservice, hints, end, &naddrs);
+ if (last_i != 0)
+ {
+ freeaddrinfo (p);
+ free (in6ai);
+
+ return -(last_i & GAIH_EAI);
+ }
+ if (end)
+ while (*end)
+ {
+ end = &((*end)->ai_next);
+ ++nresults;
+ }
+ }
+ else
+ {
+ free (in6ai);
+ return EAI_FAMILY;
+ }
+#endif
+
+ if (naddrs > 1)
+ {
+ /* Read the config file. */
+ __libc_once_define (static, once);
+ __typeof (once) old_once = once;
+ __libc_once (once, gaiconf_init);
+ if (old_once && gaiconf_reload_flag)
+ gaiconf_reload ();
+
+ /* Sort results according to RFC 3484. */
+ struct sort_result results[nresults];
+ struct addrinfo *q;
+ struct addrinfo *last = NULL;
+ char *canonname = NULL;
+
+ /* If we have information about deprecated and temporary address
+ sort the array now. */
+ if (in6ai != NULL)
+ qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
+
+ for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
+ {
+ results[i].dest_addr = q;
+ results[i].got_source_addr = false;
+
+ /* If we just looked up the address for a different
+ protocol, reuse the result. */
+ if (last != NULL && last->ai_addrlen == q->ai_addrlen
+ && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
+ {
+ memcpy (&results[i].source_addr, &results[i - 1].source_addr,
+ results[i - 1].source_addr_len);
+ results[i].source_addr_len = results[i - 1].source_addr_len;
+ results[i].got_source_addr = results[i - 1].got_source_addr;
+ results[i].source_addr_flags = results[i - 1].source_addr_flags;
+ }
+ else
+ {
+ results[i].source_addr_flags = 0;
+
+ /* We overwrite the type with SOCK_DGRAM since we do not
+ want connect() to connect to the other side. If we
+ cannot determine the source address remember this
+ fact. */
+ int fd = __socket (q->ai_family, SOCK_DGRAM, IPPROTO_IP);
+ socklen_t sl = sizeof (results[i].source_addr);
+ if (fd != -1
+ && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
+ && __getsockname (fd,
+ (struct sockaddr *) &results[i].source_addr,
+ &sl) == 0)
+ {
+ results[i].source_addr_len = sl;
+ results[i].got_source_addr = true;
+
+ if (q->ai_family == PF_INET6 && in6ai != NULL)
+ {
+ /* See whether the address is the list of deprecated
+ or temporary addresses. */
+ struct in6addrinfo tmp;
+ memcpy (tmp.addr, q->ai_addr, IN6ADDRSZ);
+
+ struct in6addrinfo *found
+ = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
+ in6aicmp);
+ if (found != NULL)
+ results[i].source_addr_flags = found->flags;
+ }
+ }
+ else
+ /* Just make sure that if we have to process the same
+ address again we do not copy any memory. */
+ results[i].source_addr_len = 0;
+
+ if (fd != -1)
+ close_not_cancel_no_status (fd);
+ }
+
+ /* Remember the canonical name. */
+ if (q->ai_canonname != NULL)
+ {
+ assert (canonname == NULL);
+ canonname = q->ai_canonname;
+ q->ai_canonname = NULL;
+ }
+ }
+
+ /* We got all the source addresses we can get, now sort using
+ the information. */
+ qsort (results, nresults, sizeof (results[0]), rfc3484_sort);
+
+ /* Queue the results up as they come out of sorting. */
+ q = p = results[0].dest_addr;
+ for (i = 1; i < nresults; ++i)
+ q = q->ai_next = results[i].dest_addr;
+ q->ai_next = NULL;
+
+ /* Fill in the canonical name into the new first entry. */
+ p->ai_canonname = canonname;
+ }
+
+ free (in6ai);
+
+ if (p)
+ {
+ *pai = p;
+ return 0;
+ }
+
+ if (pai == NULL && last_i == 0)
+ return 0;
+
+ return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
+}
+libc_hidden_def (getaddrinfo)
+
+static_link_warning (getaddrinfo)
+
+void
+freeaddrinfo (struct addrinfo *ai)
+{
+ struct addrinfo *p;
+
+ while (ai != NULL)
+ {
+ p = ai;
+ ai = ai->ai_next;
+ free (p->ai_canonname);
+ free (p);
+ }
+}
+libc_hidden_def (freeaddrinfo)
diff --git a/libc/sysdeps/posix/getcwd.c b/libc/sysdeps/posix/getcwd.c
new file mode 100644
index 000000000..f79352134
--- /dev/null
+++ b/libc/sysdeps/posix/getcwd.c
@@ -0,0 +1,428 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Wants:
+ AC_STDC_HEADERS
+ AC_DIR_HEADER
+ AC_UNISTD_H
+ AC_MEMORY_H
+ AC_CONST
+ AC_ALLOCA
+ */
+
+/* AIX requires this to be the first thing in the file. */
+#if defined _AIX && !defined __GNUC__
+ #pragma alloca
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef STDC_HEADERS
+# include <stddef.h>
+#endif
+
+#if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS
+extern int errno;
+#endif
+#ifndef __set_errno
+# define __set_errno(val) errno = (val)
+#endif
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+#if defined USGr3 && !defined DIRENT
+# define DIRENT
+#endif /* USGr3 */
+#if defined Xenix && !defined SYSNDIR
+# define SYSNDIR
+#endif /* Xenix */
+
+#if defined POSIX || defined DIRENT || defined __GNU_LIBRARY__
+# include <dirent.h>
+# ifndef __GNU_LIBRARY__
+# define D_NAMLEN(d) strlen((d)->d_name)
+# else
+# define HAVE_D_NAMLEN
+# define D_NAMLEN(d) ((d)->d_namlen)
+# endif
+#else /* not POSIX or DIRENT */
+# define dirent direct
+# define D_NAMLEN(d) ((d)->d_namlen)
+# define HAVE_D_NAMLEN
+# if defined USG && !defined sgi
+# if defined SYSNDIR
+# include <sys/ndir.h>
+# else /* Not SYSNDIR */
+# include "ndir.h"
+# endif /* SYSNDIR */
+# else /* not USG */
+# include <sys/dir.h>
+# endif /* USG */
+#endif /* POSIX or DIRENT or __GNU_LIBRARY__ */
+
+#if defined HAVE_UNISTD_H || defined __GNU_LIBRARY__
+# include <unistd.h>
+#endif
+
+#if defined STDC_HEADERS || defined __GNU_LIBRARY__ || defined POSIX
+# include <stdlib.h>
+# include <string.h>
+# define ANSI_STRING
+#else /* No standard headers. */
+
+# ifdef USG
+
+# include <string.h>
+# ifdef NEED_MEMORY_H
+# include <memory.h>
+# endif
+# define ANSI_STRING
+
+# else /* Not USG. */
+
+# ifdef NeXT
+
+# include <string.h>
+
+# else /* Not NeXT. */
+
+# include <strings.h>
+
+# ifndef bcmp
+extern int bcmp ();
+# endif
+# ifndef bzero
+extern void bzero ();
+# endif
+# ifndef bcopy
+extern void bcopy ();
+# endif
+
+# endif /* NeXT. */
+
+# endif /* USG. */
+
+extern char *malloc (), *realloc ();
+extern void free ();
+
+#endif /* Standard headers. */
+
+#ifndef ANSI_STRING
+# define memcpy(d, s, n) bcopy((s), (d), (n))
+# define memmove memcpy
+#endif /* Not ANSI_STRING. */
+
+#ifndef MAX
+# define MAX(a, b) ((a) < (b) ? (b) : (a))
+#endif
+
+#ifdef _LIBC
+# ifndef mempcpy
+# define mempcpy __mempcpy
+# endif
+# define HAVE_MEMPCPY 1
+#endif
+
+#if !defined __alloca && !defined __GNU_LIBRARY__
+
+# ifdef __GNUC__
+# undef alloca
+# define alloca(n) __builtin_alloca (n)
+# else /* Not GCC. */
+# if defined sparc || defined HAVE_ALLOCA_H
+# include <alloca.h>
+# else /* Not sparc or HAVE_ALLOCA_H. */
+# ifndef _AIX
+extern char *alloca ();
+# endif /* Not _AIX. */
+# endif /* sparc or HAVE_ALLOCA_H. */
+# endif /* GCC. */
+
+# define __alloca alloca
+
+#endif
+
+#if defined HAVE_LIMITS_H || defined STDC_HEADERS || defined __GNU_LIBRARY__
+# include <limits.h>
+#else
+# include <sys/param.h>
+#endif
+
+#ifndef PATH_MAX
+# ifdef MAXPATHLEN
+# define PATH_MAX MAXPATHLEN
+# else
+# define PATH_MAX 1024
+# endif
+#endif
+
+#if !defined STDC_HEADERS && !defined __GNU_LIBRARY__
+# undef size_t
+# define size_t unsigned int
+#endif
+
+#if !__STDC__ && !defined const
+# define const
+#endif
+
+#ifndef __GNU_LIBRARY__
+# define __lstat stat
+#endif
+
+#ifndef _LIBC
+# define __getcwd getcwd
+#endif
+
+#ifndef GETCWD_RETURN_TYPE
+# define GETCWD_RETURN_TYPE char *
+#endif
+
+/* Get the pathname of the current working directory, and put it in SIZE
+ bytes of BUF. Returns NULL if the directory couldn't be determined or
+ SIZE was too small. If successful, returns BUF. In GNU, if BUF is
+ NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
+ unless SIZE == 0, in which case it is as big as necessary. */
+
+GETCWD_RETURN_TYPE
+__getcwd (buf, size)
+ char *buf;
+ size_t size;
+{
+ static const char dots[]
+ = "../../../../../../../../../../../../../../../../../../../../../../../\
+../../../../../../../../../../../../../../../../../../../../../../../../../../\
+../../../../../../../../../../../../../../../../../../../../../../../../../..";
+ const char *dotp = &dots[sizeof (dots)];
+ const char *dotlist = dots;
+ size_t dotsize = sizeof (dots) - 1;
+ dev_t rootdev, thisdev;
+ ino_t rootino, thisino;
+ char *path;
+ register char *pathp;
+ struct stat st;
+ int prev_errno = errno;
+ size_t allocated = size;
+
+ if (size == 0)
+ {
+ if (buf != NULL)
+ {
+ __set_errno (EINVAL);
+ return NULL;
+ }
+
+ allocated = PATH_MAX + 1;
+ }
+
+ if (buf != NULL)
+ path = buf;
+ else
+ {
+ path = malloc (allocated);
+ if (path == NULL)
+ return NULL;
+ }
+
+ pathp = path + allocated;
+ *--pathp = '\0';
+
+ if (__lstat (".", &st) < 0)
+ goto lose2;
+ thisdev = st.st_dev;
+ thisino = st.st_ino;
+
+ if (__lstat ("/", &st) < 0)
+ goto lose2;
+ rootdev = st.st_dev;
+ rootino = st.st_ino;
+
+ while (!(thisdev == rootdev && thisino == rootino))
+ {
+ register DIR *dirstream;
+ struct dirent *d;
+ dev_t dotdev;
+ ino_t dotino;
+ char mount_point;
+
+ /* Look at the parent directory. */
+ if (dotp == dotlist)
+ {
+ /* My, what a deep directory tree you have, Grandma. */
+ char *new;
+ if (dotlist == dots)
+ {
+ new = malloc (dotsize * 2 + 1);
+ if (new == NULL)
+ goto lose;
+#ifdef HAVE_MEMPCPY
+ dotp = mempcpy (new, dots, dotsize);
+#else
+ memcpy (new, dots, dotsize);
+ dotp = &new[dotsize];
+#endif
+ }
+ else
+ {
+ new = realloc ((__ptr_t) dotlist, dotsize * 2 + 1);
+ if (new == NULL)
+ goto lose;
+ dotp = &new[dotsize];
+ }
+#ifdef HAVE_MEMPCPY
+ *((char *) mempcpy ((char *) dotp, new, dotsize)) = '\0';
+ dotsize *= 2;
+#else
+ memcpy ((char *) dotp, new, dotsize);
+ dotsize *= 2;
+ new[dotsize] = '\0';
+#endif
+ dotlist = new;
+ }
+
+ dotp -= 3;
+
+ /* Figure out if this directory is a mount point. */
+ if (__lstat (dotp, &st) < 0)
+ goto lose;
+ dotdev = st.st_dev;
+ dotino = st.st_ino;
+ mount_point = dotdev != thisdev;
+
+ /* Search for the last directory. */
+ dirstream = __opendir (dotp);
+ if (dirstream == NULL)
+ goto lose;
+ /* Clear errno to distinguish EOF from error if readdir returns
+ NULL. */
+ __set_errno (0);
+ while ((d = __readdir (dirstream)) != NULL)
+ {
+ if (d->d_name[0] == '.' &&
+ (d->d_name[1] == '\0' ||
+ (d->d_name[1] == '.' && d->d_name[2] == '\0')))
+ continue;
+ if (mount_point || (ino_t) d->d_ino == thisino)
+ {
+ char name[dotlist + dotsize - dotp + 1 + _D_ALLOC_NAMLEN (d)];
+#ifdef HAVE_MEMPCPY
+ char *tmp = mempcpy (name, dotp, dotlist + dotsize - dotp);
+ *tmp++ = '/';
+ strcpy (tmp, d->d_name);
+#else
+ memcpy (name, dotp, dotlist + dotsize - dotp);
+ name[dotlist + dotsize - dotp] = '/';
+ strcpy (&name[dotlist + dotsize - dotp + 1], d->d_name);
+#endif
+ /* We don't fail here if we cannot stat() a directory entry.
+ This can happen when (network) filesystems fail. If this
+ entry is in fact the one we are looking for we will find
+ out soon as we reach the end of the directory without
+ having found anything. */
+ if (__lstat (name, &st) >= 0
+ && st.st_dev == thisdev && st.st_ino == thisino)
+ break;
+ }
+ }
+ if (d == NULL)
+ {
+ int save = errno;
+ (void) __closedir (dirstream);
+ if (save == 0)
+ /* EOF on dirstream, which means that the current directory
+ has been removed. */
+ save = ENOENT;
+ __set_errno (save);
+ goto lose;
+ }
+ else
+ {
+ size_t namlen = _D_EXACT_NAMLEN (d);
+
+ if ((size_t) (pathp - path) <= namlen)
+ {
+ if (size != 0)
+ {
+ (void) __closedir (dirstream);
+ __set_errno (ERANGE);
+ goto lose;
+ }
+ else
+ {
+ char *tmp;
+ size_t oldsize = allocated;
+
+ allocated = 2 * MAX (allocated, namlen);
+ tmp = realloc (path, allocated);
+ if (tmp == NULL)
+ {
+ (void) __closedir (dirstream);
+ __set_errno (ENOMEM);/* closedir might have changed it.*/
+ goto lose;
+ }
+
+ /* Move current contents up to the end of the buffer.
+ This is guaranteed to be non-overlapping. */
+ pathp = memcpy (tmp + allocated - (path + oldsize - pathp),
+ tmp + (pathp - path),
+ path + oldsize - pathp);
+ path = tmp;
+ }
+ }
+ pathp -= namlen;
+ (void) memcpy (pathp, d->d_name, namlen);
+ *--pathp = '/';
+ (void) __closedir (dirstream);
+ }
+
+ thisdev = dotdev;
+ thisino = dotino;
+ }
+
+ if (pathp == &path[allocated - 1])
+ *--pathp = '/';
+
+ if (dotlist != dots)
+ free ((__ptr_t) dotlist);
+
+ memmove (path, pathp, path + allocated - pathp);
+
+ /* Restore errno on successful return. */
+ __set_errno (prev_errno);
+
+ return path;
+
+ lose:
+ if (dotlist != dots)
+ free ((__ptr_t) dotlist);
+ lose2:
+ if (buf == NULL)
+ free (path);
+ return NULL;
+}
+
+#if defined _LIBC && !defined __getcwd
+weak_alias (__getcwd, getcwd)
+#endif
diff --git a/libc/sysdeps/posix/getdtsz.c b/libc/sysdeps/posix/getdtsz.c
new file mode 100644
index 000000000..77a5cdc31
--- /dev/null
+++ b/libc/sysdeps/posix/getdtsz.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991, 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <limits.h>
+#include <unistd.h>
+#include <sys/resource.h>
+
+/* Return the maximum number of file descriptors
+ the current process could possibly have. */
+int
+__getdtablesize (void)
+{
+ struct rlimit ru;
+
+ /* This should even work if `getrlimit' is not implemented. POSIX.1
+ does not define this function but we will generate a stub which
+ returns -1. */
+ return __getrlimit (RLIMIT_NOFILE, &ru) < 0 ? OPEN_MAX : ru.rlim_cur;
+}
+
+weak_alias (__getdtablesize, getdtablesize)
diff --git a/libc/sysdeps/posix/getpagesize.c b/libc/sysdeps/posix/getpagesize.c
new file mode 100644
index 000000000..5a5f04782
--- /dev/null
+++ b/libc/sysdeps/posix/getpagesize.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1993, 1995, 1996, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Brendan Kehoe (brendan@cygnus.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+
+/* Return the system page size. */
+int
+__getpagesize (void)
+{
+ return __sysconf (_SC_PAGESIZE);
+}
+libc_hidden_def (__getpagesize)
+weak_alias (__getpagesize, getpagesize)
diff --git a/libc/sysdeps/posix/gettimeofday.c b/libc/sysdeps/posix/gettimeofday.c
new file mode 100644
index 000000000..bda40f48e
--- /dev/null
+++ b/libc/sysdeps/posix/gettimeofday.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 1991,1992,1994-1997,2002,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+
+#undef __gettimeofday
+
+/* Get the current time of day and timezone information,
+ putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
+ Returns 0 on success, -1 on errors. */
+int
+__gettimeofday (tv, tz)
+ struct timeval *tv;
+ struct timezone *tz;
+{
+ if (tv == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ tv->tv_sec = (long int) time ((time_t *) NULL);
+ tv->tv_usec = 0L;
+
+ if (tz != NULL)
+ {
+ const time_t timer = tv->tv_sec;
+ struct tm tm;
+ const struct tm *tmp;
+
+ const long int save_timezone = __timezone;
+ const long int save_daylight = __daylight;
+ char *save_tzname[2];
+ save_tzname[0] = __tzname[0];
+ save_tzname[1] = __tzname[1];
+
+ tmp = localtime_r (&timer, &tm);
+
+ tz->tz_minuteswest = __timezone / 60;
+ tz->tz_dsttime = __daylight;
+
+ __timezone = save_timezone;
+ __daylight = save_daylight;
+ __tzname[0] = save_tzname[0];
+ __tzname[1] = save_tzname[1];
+
+ if (tmp == NULL)
+ return -1;
+ }
+
+ return 0;
+}
+
+INTDEF(__gettimeofday)
+weak_alias (__gettimeofday, gettimeofday)
diff --git a/libc/sysdeps/posix/isatty.c b/libc/sysdeps/posix/isatty.c
new file mode 100644
index 000000000..6e1e5016a
--- /dev/null
+++ b/libc/sysdeps/posix/isatty.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <termios.h>
+
+/* Return 1 if FD is a terminal, 0 if not. */
+int
+__isatty (fd)
+ int fd;
+{
+ struct termios term;
+
+ return __tcgetattr (fd, &term) == 0;
+}
+
+weak_alias (__isatty, isatty)
diff --git a/libc/sysdeps/posix/isfdtype.c b/libc/sysdeps/posix/isfdtype.c
new file mode 100644
index 000000000..7ed8ff685
--- /dev/null
+++ b/libc/sysdeps/posix/isfdtype.c
@@ -0,0 +1,38 @@
+/* Determine whether descriptor has given property.
+ Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+int
+isfdtype (int fildes, int fdtype)
+{
+ struct stat64 st;
+ int result;
+
+ {
+ int save_error = errno;
+ result = fstat64 (fildes, &st);
+ __set_errno (save_error);
+ }
+
+ return result ?: (st.st_mode & S_IFMT) == (mode_t) fdtype;
+}
diff --git a/libc/sysdeps/posix/killpg.c b/libc/sysdeps/posix/killpg.c
new file mode 100644
index 000000000..7a5b6fd3b
--- /dev/null
+++ b/libc/sysdeps/posix/killpg.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1991, 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+
+
+/* Send SIG to all processes in process group PGRP.
+ If PGRP is zero, send SIG to all processes in
+ the current process's process group. */
+int
+killpg (pgrp, sig)
+ __pid_t pgrp;
+ int sig;
+{
+ if (pgrp < 0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return __kill (- pgrp, sig);
+}
diff --git a/libc/sysdeps/posix/libc_fatal.c b/libc/sysdeps/posix/libc_fatal.c
new file mode 100644
index 000000000..c611b8436
--- /dev/null
+++ b/libc/sysdeps/posix/libc_fatal.c
@@ -0,0 +1,150 @@
+/* Copyright (C) 1993,1994,1995,1997,2000,2004,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysdep.h>
+#include <unistd.h>
+#include <sys/syslog.h>
+#include <sys/uio.h>
+#include <not-cancel.h>
+
+#ifdef FATAL_PREPARE_INCLUDE
+#include FATAL_PREPARE_INCLUDE
+#endif
+
+struct str_list
+{
+ const char *str;
+ size_t len;
+ struct str_list *next;
+};
+
+
+/* Abort with an error message. */
+void
+__libc_message (int do_abort, const char *fmt, ...)
+{
+ va_list ap;
+ va_list ap_copy;
+ int fd = -1;
+
+ va_start (ap, fmt);
+ va_copy (ap_copy, ap);
+
+#ifdef FATAL_PREPARE
+ FATAL_PREPARE;
+#endif
+
+ /* Open a descriptor for /dev/tty unless the user explicitly
+ requests errors on standard error. */
+ const char *on_2 = __secure_getenv ("LIBC_FATAL_STDERR_");
+ if (on_2 == NULL || *on_2 == '\0')
+ fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
+
+ if (fd == -1)
+ fd = STDERR_FILENO;
+
+ struct str_list *list = NULL;
+ int nlist = 0;
+
+ const char *cp = fmt;
+ while (*cp != '\0')
+ {
+ /* Find the next "%s" or the end of the string. */
+ const char *next = cp;
+ while (next[0] != '%' || next[1] != 's')
+ {
+ next = __strchrnul (next + 1, '%');
+
+ if (next[0] == '\0')
+ break;
+ }
+
+ /* Determine what to print. */
+ const char *str;
+ size_t len;
+ if (cp[0] == '%' && cp[1] == 's')
+ {
+ str = va_arg (ap, const char *);
+ len = strlen (str);
+ cp += 2;
+ }
+ else
+ {
+ str = cp;
+ len = next - cp;
+ cp = next;
+ }
+
+ struct str_list *newp = alloca (sizeof (struct str_list));
+ newp->str = str;
+ newp->len = len;
+ newp->next = list;
+ list = newp;
+ ++nlist;
+ }
+
+ bool written = false;
+ if (nlist > 0)
+ {
+ struct iovec *iov = alloca (nlist * sizeof (struct iovec));
+ ssize_t total = 0;
+
+ for (int cnt = nlist - 1; cnt >= 0; --cnt)
+ {
+ iov[cnt].iov_base = (char *) list->str;
+ iov[cnt].iov_len = list->len;
+ total += list->len;
+ list = list->next;
+ }
+
+ if (TEMP_FAILURE_RETRY (__writev (fd, iov, nlist)) == total)
+ written = true;
+ }
+
+ va_end (ap);
+
+ /* If we had no success writing the message, use syslog. */
+ if (! written)
+ vsyslog (LOG_ERR, fmt, ap_copy);
+
+ va_end (ap_copy);
+
+ if (do_abort)
+ /* Kill the application. */
+ abort ();
+}
+
+
+void
+__libc_fatal (message)
+ const char *message;
+{
+ /* The loop is added only to keep gcc happy. */
+ while (1)
+ __libc_message (1, "%s", message);
+}
+libc_hidden_def (__libc_fatal)
diff --git a/libc/sysdeps/posix/open64.c b/libc/sysdeps/posix/open64.c
new file mode 100644
index 000000000..8d8bdbac5
--- /dev/null
+++ b/libc/sysdeps/posix/open64.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 1991,1995-1997,1999,2000,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fcntl.h>
+#include <stdarg.h>
+#include <bp-sym.h>
+#include <sysdep-cancel.h>
+
+/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
+ a third argument is the file protection. */
+int
+__libc_open64 (const char *file, int oflag, ...)
+{
+ int mode = 0;
+
+ if (oflag & O_CREAT)
+ {
+ va_list arg;
+ va_start (arg, oflag);
+ mode = va_arg (arg, int);
+ va_end (arg);
+ }
+
+ if (SINGLE_THREAD_P)
+ return __libc_open (file, oflag | O_LARGEFILE, mode);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = __libc_open (file, oflag | O_LARGEFILE, mode);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+weak_alias (__libc_open64, BP_SYM (__open64))
+libc_hidden_weak (BP_SYM (__open64))
+weak_alias (__libc_open64, BP_SYM (open64))
diff --git a/libc/sysdeps/posix/pathconf.c b/libc/sysdeps/posix/pathconf.c
new file mode 100644
index 000000000..75c99ee5c
--- /dev/null
+++ b/libc/sysdeps/posix/pathconf.c
@@ -0,0 +1,237 @@
+/* Copyright (C) 1991,1995,1996,1998,2000,2001,2003
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+
+/* Get file-specific information about PATH. */
+long int
+__pathconf (const char *path, int name)
+{
+ if (path[0] == '\0')
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+
+ switch (name)
+ {
+ default:
+ __set_errno (EINVAL);
+ return -1;
+
+ case _PC_LINK_MAX:
+#ifdef LINK_MAX
+ return LINK_MAX;
+#else
+ return -1;
+#endif
+
+ case _PC_MAX_CANON:
+#ifdef MAX_CANON
+ return MAX_CANON;
+#else
+ return -1;
+#endif
+
+ case _PC_MAX_INPUT:
+#ifdef MAX_INPUT
+ return MAX_INPUT;
+#else
+ return -1;
+#endif
+
+ case _PC_NAME_MAX:
+#ifdef NAME_MAX
+ {
+ struct statfs buf;
+ int save_errno = errno;
+
+ if (__statfs (path, &buf) < 0)
+ {
+ if (errno == ENOSYS)
+ {
+ errno = save_errno;
+ return NAME_MAX;
+ }
+ return -1;
+ }
+ else
+ {
+#ifdef _STATFS_F_NAMELEN
+ return buf.f_namelen;
+#else
+# ifdef _STATFS_F_NAME_MAX
+ return buf.f_name_max;
+# else
+ return NAME_MAX;
+# endif
+#endif
+ }
+ }
+#else
+ return -1;
+#endif
+
+ case _PC_PATH_MAX:
+#ifdef PATH_MAX
+ return PATH_MAX;
+#else
+ return -1;
+#endif
+
+ case _PC_PIPE_BUF:
+#ifdef PIPE_BUF
+ return PIPE_BUF;
+#else
+ return -1;
+#endif
+
+ case _PC_CHOWN_RESTRICTED:
+#ifdef _POSIX_CHOWN_RESTRICTED
+ return _POSIX_CHOWN_RESTRICTED;
+#else
+ return -1;
+#endif
+
+ case _PC_NO_TRUNC:
+#ifdef _POSIX_NO_TRUNC
+ return _POSIX_NO_TRUNC;
+#else
+ return -1;
+#endif
+
+ case _PC_VDISABLE:
+#ifdef _POSIX_VDISABLE
+ return _POSIX_VDISABLE;
+#else
+ return -1;
+#endif
+
+ case _PC_SYNC_IO:
+#ifdef _POSIX_SYNC_IO
+ return _POSIX_SYNC_IO;
+#else
+ return -1;
+#endif
+
+ case _PC_ASYNC_IO:
+#ifdef _POSIX_ASYNC_IO
+ {
+ /* AIO is only allowed on regular files and block devices. */
+ struct stat64 st;
+
+ if (__xstat64 (_STAT_VER, path, &st) < 0
+ || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode)))
+ return -1;
+ else
+ return 1;
+ }
+#else
+ return -1;
+#endif
+
+ case _PC_PRIO_IO:
+#ifdef _POSIX_PRIO_IO
+ return _POSIX_PRIO_IO;
+#else
+ return -1;
+#endif
+
+ case _PC_SOCK_MAXBUF:
+#ifdef SOCK_MAXBUF
+ return SOCK_MAXBUF;
+#else
+ return -1;
+#endif
+
+ case _PC_FILESIZEBITS:
+#ifdef FILESIZEBITS
+ return FILESIZEBITS;
+#else
+ /* We let platforms with larger file sizes overwrite this value. */
+ return 32;
+#endif
+
+ case _PC_REC_INCR_XFER_SIZE:
+ /* XXX It is not entirely clear what the limit is supposed to do.
+ What is incremented? */
+ return -1;
+
+ case _PC_REC_MAX_XFER_SIZE:
+ /* XXX It is not entirely clear what the limit is supposed to do.
+ In general there is no top limit of the number of bytes which
+ case be transported at once. */
+ return -1;
+
+ case _PC_REC_MIN_XFER_SIZE:
+ {
+ /* XXX It is not entirely clear what the limit is supposed to do.
+ I assume this is the block size of the filesystem. */
+ struct statvfs64 sv;
+
+ if (__statvfs64 (path, &sv) < 0)
+ return -1;
+ return sv.f_bsize;
+ }
+
+ case _PC_REC_XFER_ALIGN:
+ {
+ /* XXX It is not entirely clear what the limit is supposed to do.
+ I assume that the number should reflect the minimal block
+ alignment. */
+ struct statvfs64 sv;
+
+ if (__statvfs64 (path, &sv) < 0)
+ return -1;
+ return sv.f_frsize;
+ }
+
+ case _PC_ALLOC_SIZE_MIN:
+ {
+ /* XXX It is not entirely clear what the limit is supposed to do.
+ I assume that the number should reflect the minimal block
+ alignment. */
+ struct statvfs64 sv;
+
+ if (__statvfs64 (path, &sv) < 0)
+ return -1;
+ return sv.f_frsize;
+ }
+
+ case _PC_SYMLINK_MAX:
+ /* In general there are no limits. If a system has one it should
+ overwrite this case. */
+ return -1;
+
+ case _PC_2_SYMLINKS:
+ /* Unix systems generally have symlinks. */
+ return 1;
+ }
+}
+
+#undef __pathconf
+weak_alias (__pathconf, pathconf)
diff --git a/libc/sysdeps/posix/pause.c b/libc/sysdeps/posix/pause.c
new file mode 100644
index 000000000..538c186ec
--- /dev/null
+++ b/libc/sysdeps/posix/pause.c
@@ -0,0 +1,57 @@
+/* pause -- suspend the process until a signal arrives. POSIX.1 version.
+ Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+#include <unistd.h>
+#include <sysdep-cancel.h>
+
+/* Suspend the process until a signal arrives.
+ This always returns -1 and sets errno to EINTR. */
+
+int
+__libc_pause (void)
+{
+ sigset_t set;
+
+ __sigemptyset (&set);
+ __sigprocmask (SIG_BLOCK, NULL, &set);
+
+ /* pause is a cancellation point, but so is sigsuspend.
+ So no need for anything special here. */
+
+ return __sigsuspend (&set);
+}
+weak_alias (__libc_pause, pause)
+
+LIBC_CANCEL_HANDLED (); /* sigsuspend handles our cancellation. */
+
+#ifndef NO_CANCELLATION
+# include <not-cancel.h>
+
+int
+__pause_nocancel (void)
+{
+ sigset_t set;
+
+ __sigemptyset (&set);
+ __sigprocmask (SIG_BLOCK, NULL, &set);
+
+ return sigsuspend_not_cancel (&set);
+}
+#endif
diff --git a/libc/sysdeps/posix/posix_fallocate.c b/libc/sysdeps/posix/posix_fallocate.c
new file mode 100644
index 000000000..cbaeb4948
--- /dev/null
+++ b/libc/sysdeps/posix/posix_fallocate.c
@@ -0,0 +1,94 @@
+/* Copyright (C) 2000, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+
+/* Reserve storage for the data of the file associated with FD. */
+
+int
+posix_fallocate (int fd, __off_t offset, __off_t len)
+{
+ struct stat64 st;
+ struct statfs f;
+
+ /* `off_t' is a signed type. Therefore we can determine whether
+ OFFSET + LEN is too large if it is a negative value. */
+ if (offset < 0 || len < 0)
+ return EINVAL;
+ if (offset + len < 0)
+ return EFBIG;
+
+ /* First thing we have to make sure is that this is really a regular
+ file. */
+ if (__fxstat64 (_STAT_VER, fd, &st) != 0)
+ return EBADF;
+ if (S_ISFIFO (st.st_mode))
+ return ESPIPE;
+ if (! S_ISREG (st.st_mode))
+ return ENODEV;
+
+ if (len == 0)
+ {
+ if (st.st_size < offset)
+ {
+ int ret = __ftruncate (fd, offset);
+
+ if (ret != 0)
+ ret = errno;
+ return ret;
+ }
+ return 0;
+ }
+
+ /* We have to know the block size of the filesystem to get at least some
+ sort of performance. */
+ if (__fstatfs (fd, &f) != 0)
+ return errno;
+
+ /* Try to play safe. */
+ if (f.f_bsize == 0)
+ f.f_bsize = 512;
+
+ /* Write something to every block. */
+ for (offset += (len - 1) % f.f_bsize; len > 0; offset += f.f_bsize)
+ {
+ len -= f.f_bsize;
+
+ if (offset < st.st_size)
+ {
+ unsigned char c;
+ ssize_t rsize = __pread (fd, &c, 1, offset);
+
+ if (rsize < 0)
+ return errno;
+ /* If there is a non-zero byte, the block must have been
+ allocated already. */
+ else if (rsize == 1 && c != 0)
+ continue;
+ }
+
+ if (__pwrite (fd, "", 1, offset) != 1)
+ return errno;
+ }
+
+ return 0;
+}
diff --git a/libc/sysdeps/posix/posix_fallocate64.c b/libc/sysdeps/posix/posix_fallocate64.c
new file mode 100644
index 000000000..64ca9ae83
--- /dev/null
+++ b/libc/sysdeps/posix/posix_fallocate64.c
@@ -0,0 +1,113 @@
+/* Copyright (C) 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+
+/* Reserve storage for the data of the file associated with FD. */
+
+int
+__posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len)
+{
+ struct stat64 st;
+ struct statfs64 f;
+
+ /* `off64_t' is a signed type. Therefore we can determine whether
+ OFFSET + LEN is too large if it is a negative value. */
+ if (offset < 0 || len < 0)
+ return EINVAL;
+ if (offset + len < 0)
+ return EFBIG;
+
+ /* First thing we have to make sure is that this is really a regular
+ file. */
+ if (__fxstat64 (_STAT_VER, fd, &st) != 0)
+ return EBADF;
+ if (S_ISFIFO (st.st_mode))
+ return ESPIPE;
+ if (! S_ISREG (st.st_mode))
+ return ENODEV;
+
+ if (len == 0)
+ {
+ if (st.st_size < offset)
+ {
+ int ret = __ftruncate64 (fd, offset);
+
+ if (ret != 0)
+ ret = errno;
+ return ret;
+ }
+ return 0;
+ }
+
+ /* We have to know the block size of the filesystem to get at least some
+ sort of performance. */
+ if (__fstatfs64 (fd, &f) != 0)
+ return errno;
+
+ /* Try to play safe. */
+ if (f.f_bsize == 0)
+ f.f_bsize = 512;
+
+ /* Write something to every block. */
+ for (offset += (len - 1) % f.f_bsize; len > 0; offset += f.f_bsize)
+ {
+ len -= f.f_bsize;
+
+ if (offset < st.st_size)
+ {
+ unsigned char c;
+ ssize_t rsize = __libc_pread64 (fd, &c, 1, offset);
+
+ if (rsize < 0)
+ return errno;
+ /* If there is a non-zero byte, the block must have been
+ allocated already. */
+ else if (rsize == 1 && c != 0)
+ continue;
+ }
+
+ if (__libc_pwrite64 (fd, "", 1, offset) != 1)
+ return errno;
+ }
+
+ return 0;
+}
+
+#include <shlib-compat.h>
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 32 && SHLIB_COMPAT(libc, GLIBC_2_2, GLIBC_2_3_3)
+
+int
+attribute_compat_text_section
+__posix_fallocate64_l32 (int fd, off64_t offset, size_t len)
+{
+ return __posix_fallocate64_l64 (fd, offset, len);
+}
+
+versioned_symbol (libc, __posix_fallocate64_l64, posix_fallocate64,
+ GLIBC_2_3_3);
+compat_symbol (libc, __posix_fallocate64_l32, posix_fallocate64, GLIBC_2_2);
+#else
+strong_alias (__posix_fallocate64_l64, posix_fallocate64);
+#endif
diff --git a/libc/sysdeps/posix/pread.c b/libc/sysdeps/posix/pread.c
new file mode 100644
index 000000000..3b226a0dc
--- /dev/null
+++ b/libc/sysdeps/posix/pread.c
@@ -0,0 +1,63 @@
+/* Read block from given position in file without changing file pointer.
+ POSIX version.
+ Copyright (C) 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+/* Note: This implementation of pread is not multithread-safe. */
+
+ssize_t
+__libc_pread (int fd, void *buf, size_t nbyte, off_t offset)
+{
+ /* Since we must not change the file pointer preserve the value so that
+ we can restore it later. */
+ int save_errno;
+ ssize_t result;
+ off_t old_offset = __libc_lseek (fd, 0, SEEK_CUR);
+ if (old_offset == (off_t) -1)
+ return -1;
+
+ /* Set to wanted position. */
+ if (__libc_lseek (fd, offset, SEEK_SET) == (off_t) -1)
+ return -1;
+
+ /* Write out the data. */
+ result = __libc_read (fd, buf, nbyte);
+
+ /* Now we have to restore the position. If this fails we have to
+ return this as an error. But if the writing also failed we
+ return this error. */
+ save_errno = errno;
+ if (__libc_lseek (fd, old_offset, SEEK_SET) == (off_t) -1)
+ {
+ if (result == -1)
+ __set_errno (save_errno);
+ return -1;
+ }
+ __set_errno (save_errno);
+
+ return result;
+}
+
+#ifndef __libc_pread
+strong_alias (__libc_pread, __pread)
+weak_alias (__libc_pread, pread)
+#endif
diff --git a/libc/sysdeps/posix/pread64.c b/libc/sysdeps/posix/pread64.c
new file mode 100644
index 000000000..b19eabe4a
--- /dev/null
+++ b/libc/sysdeps/posix/pread64.c
@@ -0,0 +1,63 @@
+/* Read block from given position in file without changing file pointer.
+ POSIX version.
+ Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+/* Note: This implementation of pread64 is not multithread-safe. */
+
+ssize_t
+__libc_pread64 (int fd, void *buf, size_t nbyte, off64_t offset)
+{
+ /* Since we must not change the file pointer preserve the value so that
+ we can restore it later. */
+ int save_errno;
+ ssize_t result;
+ off64_t old_offset = __libc_lseek64 (fd, 0, SEEK_CUR);
+ if (old_offset == (off64_t) -1)
+ return -1;
+
+ /* Set to wanted position. */
+ if (__libc_lseek64 (fd, offset, SEEK_SET) == (off64_t) -1)
+ return -1;
+
+ /* Write out the data. */
+ result = __libc_read (fd, buf, nbyte);
+
+ /* Now we have to restore the position. If this fails we have to
+ return this as an error. But if the writing also failed we
+ return this error. */
+ save_errno = errno;
+ if (__libc_lseek64 (fd, old_offset, SEEK_SET) == (off64_t) -1)
+ {
+ if (result == -1)
+ __set_errno (save_errno);
+ return -1;
+ }
+ __set_errno (save_errno);
+
+ return result;
+}
+
+#ifndef __libc_pread64
+weak_alias (__libc_pread64, __pread64)
+weak_alias (__libc_pread64, pread64)
+#endif
diff --git a/libc/sysdeps/posix/profil.c b/libc/sysdeps/posix/profil.c
new file mode 100644
index 000000000..281b53bf6
--- /dev/null
+++ b/libc/sysdeps/posix/profil.c
@@ -0,0 +1,121 @@
+/* Low-level statistical profiling support function. Mostly POSIX.1 version.
+ Copyright (C) 1996,1997,1998,2002,2004,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <libc-internal.h>
+
+#ifndef SIGPROF
+
+#include <gmon/profil.c>
+
+#else
+
+static u_short *samples;
+static size_t nsamples;
+static size_t pc_offset;
+static u_int pc_scale;
+
+static inline void
+profil_count (void *pc)
+{
+ size_t i = (pc - pc_offset - (void *) 0) / 2;
+
+ if (sizeof (unsigned long long int) > sizeof (size_t))
+ i = (unsigned long long int) i * pc_scale / 65536;
+ else
+ i = i / 65536 * pc_scale + i % 65536 * pc_scale / 65536;
+
+ if (i < nsamples)
+ ++samples[i];
+}
+
+/* Get the machine-dependent definition of `profil_counter', the signal
+ handler for SIGPROF. It calls `profil_count' (above) with the PC of the
+ interrupted code. */
+#include "profil-counter.h"
+
+/* Enable statistical profiling, writing samples of the PC into at most
+ SIZE bytes of SAMPLE_BUFFER; every processor clock tick while profiling
+ is enabled, the system examines the user PC and increments
+ SAMPLE_BUFFER[((PC - OFFSET) / 2) * SCALE / 65536]. If SCALE is zero,
+ disable profiling. Returns zero on success, -1 on error. */
+
+int
+__profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+{
+ struct sigaction act;
+ struct itimerval timer;
+#ifndef IS_IN_rtld
+ static struct sigaction oact;
+ static struct itimerval otimer;
+# define oact_ptr &oact
+# define otimer_ptr &otimer
+
+ if (sample_buffer == NULL)
+ {
+ /* Disable profiling. */
+ if (samples == NULL)
+ /* Wasn't turned on. */
+ return 0;
+
+ if (__setitimer (ITIMER_PROF, &otimer, NULL) < 0)
+ return -1;
+ samples = NULL;
+ return __sigaction (SIGPROF, &oact, NULL);
+ }
+
+ if (samples)
+ {
+ /* Was already turned on. Restore old timer and signal handler
+ first. */
+ if (__setitimer (ITIMER_PROF, &otimer, NULL) < 0
+ || __sigaction (SIGPROF, &oact, NULL) < 0)
+ return -1;
+ }
+#else
+ /* In ld.so profiling should never be disabled once it runs. */
+ //assert (sample_buffer != NULL);
+# define oact_ptr NULL
+# define otimer_ptr NULL
+#endif
+
+ samples = sample_buffer;
+ nsamples = size / sizeof *samples;
+ pc_offset = offset;
+ pc_scale = scale;
+
+ act.sa_handler = (sighandler_t) &profil_counter;
+ act.sa_flags = SA_RESTART;
+ __sigfillset (&act.sa_mask);
+ if (__sigaction (SIGPROF, &act, oact_ptr) < 0)
+ return -1;
+
+ timer.it_value.tv_sec = 0;
+ timer.it_value.tv_usec = 1000000 / __profile_frequency ();
+ timer.it_interval = timer.it_value;
+ return __setitimer (ITIMER_PROF, &timer, otimer_ptr);
+}
+weak_alias (__profil, profil)
+
+#endif
diff --git a/libc/sysdeps/posix/pwrite.c b/libc/sysdeps/posix/pwrite.c
new file mode 100644
index 000000000..51624e5a5
--- /dev/null
+++ b/libc/sysdeps/posix/pwrite.c
@@ -0,0 +1,63 @@
+/* Write block to given position in file without changing file pointer.
+ POSIX version.
+ Copyright (C) 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+/* Note: This implementation of pwrite is not multithread-safe. */
+
+ssize_t
+__libc_pwrite (int fd, const void *buf, size_t nbyte, off_t offset)
+{
+ /* Since we must not change the file pointer preserve the value so that
+ we can restore it later. */
+ int save_errno;
+ ssize_t result;
+ off_t old_offset = __libc_lseek (fd, 0, SEEK_CUR);
+ if (old_offset == (off_t) -1)
+ return -1;
+
+ /* Set to wanted position. */
+ if (__libc_lseek (fd, offset, SEEK_SET) == (off_t) -1)
+ return -1;
+
+ /* Write out the data. */
+ result = __libc_write (fd, buf, nbyte);
+
+ /* Now we have to restore the position. If this fails we have to
+ return this as an error. But if the writing also failed we
+ return this error. */
+ save_errno = errno;
+ if (__libc_lseek (fd, old_offset, SEEK_SET) == (off_t) -1)
+ {
+ if (result == -1)
+ __set_errno (save_errno);
+ return -1;
+ }
+ __set_errno (save_errno);
+
+ return result;
+}
+
+#ifndef __libc_pwrite
+strong_alias (__libc_pwrite, __pwrite)
+weak_alias (__libc_pwrite, pwrite)
+#endif
diff --git a/libc/sysdeps/posix/pwrite64.c b/libc/sysdeps/posix/pwrite64.c
new file mode 100644
index 000000000..33446c66b
--- /dev/null
+++ b/libc/sysdeps/posix/pwrite64.c
@@ -0,0 +1,64 @@
+/* Write block to given position in file without changing file pointer.
+ POSIX version.
+ Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+/* Note: This implementation of pwrite64 is not multithread-safe. */
+
+ssize_t
+__libc_pwrite64 (int fd, const void *buf, size_t nbyte, off64_t offset)
+{
+ /* Since we must not change the file pointer preserve the value so that
+ we can restore it later. */
+ int save_errno;
+ ssize_t result;
+ off64_t old_offset = __libc_lseek64 (fd, 0, SEEK_CUR);
+ if (old_offset == (off64_t) -1)
+ return -1;
+
+ /* Set to wanted position. */
+ if (__libc_lseek64 (fd, offset, SEEK_SET) == (off64_t) -1)
+ return -1;
+
+ /* Write out the data. */
+ result = __libc_write (fd, buf, nbyte);
+
+ /* Now we have to restore the position. If this fails we have to
+ return this as an error. But if the writing also failed we
+ return this error. */
+ save_errno = errno;
+ if (__libc_lseek64 (fd, old_offset, SEEK_SET) == (off64_t) -1)
+ {
+ if (result == -1)
+ __set_errno (save_errno);
+ return -1;
+ }
+ __set_errno (save_errno);
+
+ return result;
+}
+#ifndef __libc_pwrite64
+libc_hidden_def (__libc_pwrite64)
+weak_alias (__libc_pwrite64, __pwrite64)
+libc_hidden_weak (__pwrite64)
+weak_alias (__libc_pwrite64, pwrite64)
+#endif
diff --git a/libc/sysdeps/posix/raise.c b/libc/sysdeps/posix/raise.c
new file mode 100644
index 000000000..c2fe12fda
--- /dev/null
+++ b/libc/sysdeps/posix/raise.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991,96,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+#include <unistd.h>
+
+/* Raise the signal SIG. */
+int
+raise (sig)
+ int sig;
+{
+ return __kill (__getpid (), sig);
+}
+libc_hidden_def (raise)
+weak_alias (raise, gsignal)
diff --git a/libc/sysdeps/posix/readv.c b/libc/sysdeps/posix/readv.c
new file mode 100644
index 000000000..f0e78e666
--- /dev/null
+++ b/libc/sysdeps/posix/readv.c
@@ -0,0 +1,101 @@
+/* Copyright (C) 1991, 1992, 1996, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <sys/param.h>
+#include <sys/uio.h>
+#include <errno.h>
+
+/* Read data from file descriptor FD, and put the result in the
+ buffers described by VECTOR, which is a vector of COUNT `struct iovec's.
+ The buffers are filled in the order specified.
+ Operates just like `read' (see <unistd.h>) except that data are
+ put in VECTOR instead of a contiguous buffer. */
+ssize_t
+__libc_readv (int fd, const struct iovec *vector, int count)
+{
+ char *buffer;
+ char *buffer_start;
+ size_t bytes;
+ ssize_t bytes_read;
+ int i;
+ bool use_malloc = false;
+
+ /* Find the total number of bytes to be read. */
+ bytes = 0;
+ for (i = 0; i < count; ++i)
+ {
+ /* Check for ssize_t overflow. */
+ if (SSIZE_MAX - bytes < vector[i].iov_len)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ bytes += vector[i].iov_len;
+ }
+
+ /* Allocate a temporary buffer to hold the data. We should normally
+ use alloca since it's faster and does not require synchronization
+ with other threads. But we cannot if the amount of memory
+ required is too large. */
+ if (__libc_use_alloca (bytes))
+ buffer = (char *) __alloca (bytes);
+ else
+ {
+ buffer = (char *) malloc (bytes);
+ if (buffer == NULL)
+ /* XXX I don't know whether it is acceptable to try reading
+ the data in chunks. Probably not so we just fail here. */
+ return -1;
+
+ use_malloc = true;
+ }
+
+ /* Read the data. */
+ bytes_read = __read (fd, buffer, bytes);
+ if (bytes_read <= 0)
+ return -1;
+
+ /* Copy the data from BUFFER into the memory specified by VECTOR. */
+ bytes = bytes_read;
+ buffer_start = buffer;
+ for (i = 0; i < count; ++i)
+ {
+ size_t copy = MIN (vector[i].iov_len, bytes);
+
+ (void) memcpy ((void *) vector[i].iov_base, (void *) buffer, copy);
+
+ buffer += copy;
+ bytes -= copy;
+ if (bytes == 0)
+ break;
+ }
+
+ if (use_malloc)
+ free (buffer_start);
+
+ return bytes_read;
+}
+#ifndef __libc_readv
+strong_alias (__libc_readv, __readv)
+weak_alias (__libc_readv, readv)
+#endif
diff --git a/libc/sysdeps/posix/remove.c b/libc/sysdeps/posix/remove.c
new file mode 100644
index 000000000..c44af92d7
--- /dev/null
+++ b/libc/sysdeps/posix/remove.c
@@ -0,0 +1,39 @@
+/* ANSI C `remove' function to delete a file or directory. POSIX.1 version.
+ Copyright (C) 1995,96,97,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int
+remove (file)
+ const char *file;
+{
+ /* First try to unlink since this is more frequently the necessary action. */
+ if (__unlink (file) != 0
+ /* If it is indeed a directory... */
+ && (errno != EISDIR
+ /* ...try to remove it. */
+ || __rmdir (file) != 0))
+ /* Cannot remove the object for whatever reason. */
+ return -1;
+
+ return 0;
+}
+libc_hidden_def (remove)
diff --git a/libc/sysdeps/posix/rename.c b/libc/sysdeps/posix/rename.c
new file mode 100644
index 000000000..6d1283a4e
--- /dev/null
+++ b/libc/sysdeps/posix/rename.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1991, 1992, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+/* Rename the file OLD to NEW. */
+int
+rename (old, new)
+ const char *old;
+ const char *new;
+{
+ int save = errno;
+ if (__link (old, new) < 0)
+ {
+ if (errno == EEXIST)
+ {
+ __set_errno (save);
+ /* Race condition, required for 1003.1 conformance. */
+ if (__unlink (new) < 0 ||
+ __link (old, new) < 0)
+ return -1;
+ }
+ else
+ return -1;
+ }
+ if (__unlink (old) < 0)
+ {
+ save = errno;
+ if (__unlink (new) == 0)
+ __set_errno (save);
+ return -1;
+ }
+ return 0;
+}
diff --git a/libc/sysdeps/posix/shm_open.c b/libc/sysdeps/posix/shm_open.c
new file mode 100644
index 000000000..0a657fadf
--- /dev/null
+++ b/libc/sysdeps/posix/shm_open.c
@@ -0,0 +1,85 @@
+/* shm_open -- open a POSIX shared memory object. Generic POSIX file version.
+ Copyright (C) 2001,2002,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+
+#if ! _POSIX_MAPPED_FILES
+#include <rt/shm_open.c>
+
+#else
+
+#include <errno.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <paths.h>
+
+#define SHMDIR (_PATH_DEV "shm/")
+
+/* Open shared memory object. */
+int
+shm_open (const char *name, int oflag, mode_t mode)
+{
+ size_t namelen;
+ char *fname;
+ int fd;
+
+ /* Construct the filename. */
+ while (name[0] == '/')
+ ++name;
+
+ if (name[0] == '\0')
+ {
+ /* The name "/" is not supported. */
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ namelen = strlen (name);
+ fname = (char *) __alloca (sizeof SHMDIR - 1 + namelen + 1);
+ __mempcpy (__mempcpy (fname, SHMDIR, sizeof SHMDIR - 1),
+ name, namelen + 1);
+
+ fd = open (name, oflag, mode);
+ if (fd != -1)
+ {
+ /* We got a descriptor. Now set the FD_CLOEXEC bit. */
+ int flags = fcntl (fd, F_GETFD, 0);
+
+ if (__builtin_expect (flags, 0) != -1)
+ {
+ flags |= FD_CLOEXEC;
+ flags = fcntl (fd, F_SETFD, flags);
+ }
+
+ if (flags == -1)
+ {
+ /* Something went wrong. We cannot return the descriptor. */
+ int save_errno = errno;
+ close (fd);
+ fd = -1;
+ __set_errno (save_errno);
+ }
+ }
+
+ return fd;
+}
+
+#endif
diff --git a/libc/sysdeps/posix/shm_unlink.c b/libc/sysdeps/posix/shm_unlink.c
new file mode 100644
index 000000000..18ca416e1
--- /dev/null
+++ b/libc/sysdeps/posix/shm_unlink.c
@@ -0,0 +1,61 @@
+/* shm_unlink -- remove a POSIX shared memory object. Generic POSIX version.
+ Copyright (C) 2001,2002,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+
+#if ! _POSIX_MAPPED_FILES
+#include <rt/shm_unlink.c>
+
+#else
+
+#include <errno.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <stdlib.h>
+#include <paths.h>
+
+#define SHMDIR (_PATH_DEV "shm/")
+
+/* Remove shared memory object. */
+int
+shm_unlink (const char *name)
+{
+ size_t namelen;
+ char *fname;
+
+ /* Construct the filename. */
+ while (name[0] == '/')
+ ++name;
+
+ if (name[0] == '\0')
+ {
+ /* The name "/" is not supported. */
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ namelen = strlen (name);
+ fname = (char *) __alloca (sizeof SHMDIR - 1 + namelen + 1);
+ __mempcpy (__mempcpy (fname, SHMDIR, sizeof SHMDIR - 1),
+ name, namelen + 1);
+
+ return unlink (name);
+}
+
+#endif
diff --git a/libc/sysdeps/posix/sigblock.c b/libc/sysdeps/posix/sigblock.c
new file mode 100644
index 000000000..143b4c8d4
--- /dev/null
+++ b/libc/sysdeps/posix/sigblock.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1991, 1994-1998, 2001-2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+
+#include <sigset-cvt-mask.h>
+
+/* Block signals in MASK, returning the old mask. */
+int
+__sigblock (mask)
+ int mask;
+{
+ sigset_t set, oset;
+
+ if (sigset_set_old_mask (&set, mask) < 0)
+ return -1;
+
+ if (__sigprocmask (SIG_BLOCK, &set, &oset) < 0)
+ return -1;
+
+ return sigset_get_old_mask (&oset);
+}
+
+weak_alias (__sigblock, sigblock)
diff --git a/libc/sysdeps/posix/sigignore.c b/libc/sysdeps/posix/sigignore.c
new file mode 100644
index 000000000..9787e8d23
--- /dev/null
+++ b/libc/sysdeps/posix/sigignore.c
@@ -0,0 +1,40 @@
+/* Set the disposition of SIG to SIG_IGN.
+ Copyright (C) 1998, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#define __need_NULL
+#include <stddef.h>
+#include <signal.h>
+#include <string.h> /* For the real memset prototype. */
+
+
+int
+sigignore (sig)
+ int sig;
+{
+ struct sigaction act;
+
+ act.sa_handler = SIG_IGN;
+ if (__sigemptyset (&act.sa_mask) < 0)
+ return -1;
+ act.sa_flags = 0;
+
+ return __sigaction (sig, &act, NULL);
+}
diff --git a/libc/sysdeps/posix/sigintr.c b/libc/sysdeps/posix/sigintr.c
new file mode 100644
index 000000000..ceac262e5
--- /dev/null
+++ b/libc/sysdeps/posix/sigintr.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1992, 1994, 1996, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <signal.h>
+#include <errno.h>
+
+/* If INTERRUPT is nonzero, make signal SIG interrupt system calls
+ (causing them to fail with EINTR); if INTERRUPT is zero, make system
+ calls be restarted after signal SIG. */
+int
+siginterrupt (sig, interrupt)
+ int sig;
+ int interrupt;
+{
+#ifdef SA_RESTART
+ extern sigset_t _sigintr attribute_hidden; /* Defined in signal.c. */
+ struct sigaction action;
+
+ if (__sigaction (sig, (struct sigaction *) NULL, &action) < 0)
+ return -1;
+
+ if (interrupt)
+ {
+ __sigaddset (&_sigintr, sig);
+ action.sa_flags &= ~SA_RESTART;
+ }
+ else
+ {
+ __sigdelset (&_sigintr, sig);
+ action.sa_flags |= SA_RESTART;
+ }
+
+ if (__sigaction (sig, &action, (struct sigaction *) NULL) < 0)
+ return -1;
+
+ return 0;
+#else
+ __set_errno (ENOSYS);
+ return -1;
+#endif
+}
diff --git a/libc/sysdeps/posix/signal.c b/libc/sysdeps/posix/signal.c
new file mode 100644
index 000000000..9fc514c72
--- /dev/null
+++ b/libc/sysdeps/posix/signal.c
@@ -0,0 +1,56 @@
+/* BSD-like signal function.
+ Copyright (C) 1991,1992,1996,1997,2000,2002,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h> /* For the real memset prototype. */
+
+
+sigset_t _sigintr attribute_hidden; /* Set by siginterrupt. */
+
+/* Set the handler for the signal SIG to HANDLER,
+ returning the old handler, or SIG_ERR on error. */
+__sighandler_t
+__bsd_signal (sig, handler)
+ int sig;
+ __sighandler_t handler;
+{
+ struct sigaction act, oact;
+
+ /* Check signal extents to protect __sigismember. */
+ if (handler == SIG_ERR || sig < 1 || sig >= NSIG)
+ {
+ __set_errno (EINVAL);
+ return SIG_ERR;
+ }
+
+ act.sa_handler = handler;
+ if (__sigemptyset (&act.sa_mask) < 0
+ || __sigaddset (&act.sa_mask, sig) < 0)
+ return SIG_ERR;
+ act.sa_flags = __sigismember (&_sigintr, sig) ? 0 : SA_RESTART;
+ if (__sigaction (sig, &act, &oact) < 0)
+ return SIG_ERR;
+
+ return oact.sa_handler;
+}
+weak_alias (__bsd_signal, bsd_signal)
+weak_alias (__bsd_signal, signal)
+weak_alias (__bsd_signal, ssignal)
diff --git a/libc/sysdeps/posix/sigpause.c b/libc/sysdeps/posix/sigpause.c
new file mode 100644
index 000000000..5ea1b114d
--- /dev/null
+++ b/libc/sysdeps/posix/sigpause.c
@@ -0,0 +1,91 @@
+/* Copyright (C) 1991,92,94-98,2000,2002,2003,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define sigpause __rename_sigpause
+#include <errno.h>
+#include <signal.h>
+#include <stddef.h> /* For NULL. */
+#include <sysdep-cancel.h>
+#undef sigpause
+
+#include <sigset-cvt-mask.h>
+
+/* Set the mask of blocked signals to MASK,
+ wait for a signal to arrive, and then restore the mask. */
+static int
+do_sigpause (int sig_or_mask, int is_sig)
+{
+ sigset_t set;
+
+ if (is_sig != 0)
+ {
+ /* The modern X/Open implementation is requested. */
+ if (__sigprocmask (0, NULL, &set) < 0
+ || sigdelset (&set, sig_or_mask) < 0)
+ return -1;
+ }
+ else if (sigset_set_old_mask (&set, sig_or_mask) < 0)
+ return -1;
+
+ /* Note the sigpause() is a cancellation point. But since we call
+ sigsuspend() which itself is a cancellation point we do not have
+ to do anything here. */
+ return __sigsuspend (&set);
+}
+
+int
+__sigpause (int sig_or_mask, int is_sig)
+{
+ if (SINGLE_THREAD_P)
+ return do_sigpause (sig_or_mask, is_sig);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_sigpause (sig_or_mask, is_sig);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+libc_hidden_def (__sigpause)
+
+/* We have to provide a default version of this function since the
+ standards demand it. The version which is a bit more reasonable is
+ the BSD version. So make this the default. */
+int
+__attribute__ ((weak))
+__default_sigpause (int mask)
+{
+ return __sigpause (mask, 0);
+}
+#undef sigpause
+weak_alias (__default_sigpause, sigpause)
+strong_alias (__default_sigpause, __libc_sigpause)
+
+
+/* We have to provide a default version of this function since the
+ standards demand it. The version which is a bit more reasonable is
+ the BSD version. So make this the default. */
+int
+__attribute__ ((weak))
+__xpg_sigpause (int sig)
+{
+ return __sigpause (sig, 1);
+}
+strong_alias (__xpg_sigpause, __libc___xpg_sigpause)
diff --git a/libc/sysdeps/posix/sigset.c b/libc/sysdeps/posix/sigset.c
new file mode 100644
index 000000000..8f96e3d61
--- /dev/null
+++ b/libc/sysdeps/posix/sigset.c
@@ -0,0 +1,93 @@
+/* Copyright (C) 1998, 2000, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#define __need_NULL
+#include <stddef.h>
+#include <signal.h>
+#include <string.h> /* For the real memset prototype. */
+
+
+/* Set the disposition for SIG. */
+__sighandler_t
+sigset (sig, disp)
+ int sig;
+ __sighandler_t disp;
+{
+ struct sigaction act;
+ struct sigaction oact;
+ sigset_t set;
+ sigset_t oset;
+
+#ifdef SIG_HOLD
+ /* Handle SIG_HOLD first. */
+ if (disp == SIG_HOLD)
+ {
+ /* Create an empty signal set. */
+ if (__sigemptyset (&set) < 0)
+ return SIG_ERR;
+
+ /* Add the specified signal. */
+ if (__sigaddset (&set, sig) < 0)
+ return SIG_ERR;
+
+ /* Add the signal set to the current signal mask. */
+ if (__sigprocmask (SIG_BLOCK, &set, &oset) < 0)
+ return SIG_ERR;
+
+ /* If the signal was already blocked signal this to the caller. */
+ if (__sigismember (&oset, sig))
+ return SIG_HOLD;
+
+ /* We need to determine whether a specific handler is installed. */
+ if (__sigaction (sig, NULL, &oact) < 0)
+ return SIG_ERR;
+
+ return oact.sa_handler;
+ }
+#endif /* SIG_HOLD */
+
+ /* Check signal extents to protect __sigismember. */
+ if (disp == SIG_ERR || sig < 1 || sig >= NSIG)
+ {
+ __set_errno (EINVAL);
+ return SIG_ERR;
+ }
+
+ act.sa_handler = disp;
+ if (__sigemptyset (&act.sa_mask) < 0)
+ return SIG_ERR;
+ act.sa_flags = 0;
+ if (__sigaction (sig, &act, &oact) < 0)
+ return SIG_ERR;
+
+ /* Create an empty signal set. */
+ if (__sigemptyset (&set) < 0)
+ return SIG_ERR;
+
+ /* Add the specified signal. */
+ if (__sigaddset (&set, sig) < 0)
+ return SIG_ERR;
+
+ /* Remove the signal set from the current signal mask. */
+ if (__sigprocmask (SIG_UNBLOCK, &set, &oset) < 0)
+ return SIG_ERR;
+
+ /* If the signal was already blocked return SIG_HOLD. */
+ return __sigismember (&oset, sig) ? SIG_HOLD : oact.sa_handler;
+}
diff --git a/libc/sysdeps/posix/sigsetmask.c b/libc/sysdeps/posix/sigsetmask.c
new file mode 100644
index 000000000..bb50e4fc1
--- /dev/null
+++ b/libc/sysdeps/posix/sigsetmask.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1991,1994-1997,2001-2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+
+#include <sigset-cvt-mask.h>
+
+/* Set the mask of blocked signals to MASK, returning the old mask. */
+int
+__sigsetmask (int mask)
+{
+ sigset_t set, oset;
+
+ if (sigset_set_old_mask (&set, mask) < 0)
+ return -1;
+
+ if (__sigprocmask (SIG_SETMASK, &set, &oset) < 0)
+ return -1;
+
+ return sigset_get_old_mask (&oset);
+}
+
+weak_alias (__sigsetmask, sigsetmask)
diff --git a/libc/sysdeps/posix/sigsuspend.c b/libc/sysdeps/posix/sigsuspend.c
new file mode 100644
index 000000000..e85752a47
--- /dev/null
+++ b/libc/sysdeps/posix/sigsuspend.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1991, 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <stddef.h>
+#include <unistd.h>
+
+
+/* Change the set of blocked signals to SET,
+ wait until a signal arrives, and restore the set of blocked signals. */
+int
+__sigsuspend (set)
+ const sigset_t *set;
+{
+ sigset_t oset;
+ int save;
+
+ if (set == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (sigprocmask (SIG_SETMASK, set, &oset) < 0)
+ return -1;
+
+ (void) pause();
+ save = errno;
+
+ if (sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL) < 0)
+ return -1;
+
+ __set_errno (save);
+ return -1;
+}
+libc_hidden_def (__sigsuspend)
+weak_alias (__sigsuspend, sigsuspend)
diff --git a/libc/sysdeps/posix/sigvec.c b/libc/sysdeps/posix/sigvec.c
new file mode 100644
index 000000000..22a759332
--- /dev/null
+++ b/libc/sysdeps/posix/sigvec.c
@@ -0,0 +1,182 @@
+/* Copyright (C) 1991,92,1994-98,2002,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+#include <errno.h>
+#include <stddef.h>
+
+/* Include macros to convert between `sigset_t' and old-style mask. */
+#include <sigset-cvt-mask.h>
+
+#ifndef SA_RESETHAND
+/* When sigaction lacks the extension bit for it,
+ we use a wrapper handler to support SV_RESETHAND. */
+struct sigvec_wrapper_data
+{
+ __sighandler_t sw_handler;
+ unsigned int sw_mask;
+};
+
+static void sigvec_wrapper_handler (int sig) __THROW;
+
+static struct sigvec_wrapper_data sigvec_wrapper_data[NSIG];
+#endif
+
+
+/* If VEC is non-NULL, set the handler for SIG to the `sv_handler' member
+ of VEC. The signals in `sv_mask' will be blocked while the handler runs.
+ If the SV_RESETHAND bit is set in `sv_flags', the handler for SIG will be
+ reset to SIG_DFL before `sv_handler' is entered. If OVEC is non-NULL,
+ it is filled in with the old information for SIG. */
+int
+__sigvec (sig, vec, ovec)
+ int sig;
+ const struct sigvec *vec;
+ struct sigvec *ovec;
+{
+ struct sigaction old;
+
+#ifndef SA_RESETHAND
+ if (vec == NULL || !(vec->sv_flags & SV_RESETHAND))
+#endif
+ {
+ struct sigaction new, *n;
+
+ if (vec == NULL)
+ n = NULL;
+ else
+ {
+ __sighandler_t handler;
+ unsigned int mask;
+ unsigned int sv_flags;
+ unsigned int sa_flags;
+
+ handler = vec->sv_handler;
+ mask = vec->sv_mask;
+ sv_flags = vec->sv_flags;
+ sa_flags = 0;
+ if (sv_flags & SV_ONSTACK)
+ {
+#ifdef SA_ONSTACK
+ sa_flags |= SA_ONSTACK;
+#else
+ __set_errno (ENOSYS);
+ return -1;
+#endif
+ }
+#ifdef SA_RESTART
+ if (!(sv_flags & SV_INTERRUPT))
+ sa_flags |= SA_RESTART;
+#endif
+#ifdef SA_RESETHAND
+ if (sv_flags & SV_RESETHAND)
+ sa_flags |= SA_RESETHAND;
+#endif
+ n = &new;
+ new.sa_handler = handler;
+ if (sigset_set_old_mask (&new.sa_mask, mask) < 0)
+ return -1;
+ new.sa_flags = sa_flags;
+ }
+
+ if (__sigaction (sig, n, &old) < 0)
+ return -1;
+ }
+#ifndef SA_RESETHAND
+ else
+ {
+ __sighandler_t handler;
+ unsigned int mask;
+ struct sigvec_wrapper_data *data;
+ struct sigaction wrapper;
+
+ handler = vec->sv_handler;
+ mask = (unsigned int)vec->sv_mask;
+ data = &sigvec_wrapper_data[sig];
+ wrapper.sa_handler = sigvec_wrapper_handler;
+ /* FIXME: should we set wrapper.sa_mask, wrapper.sa_flags?? */
+ data->sw_handler = handler;
+ data->sw_mask = mask;
+
+ if (__sigaction (sig, &wrapper, &old) < 0)
+ return -1;
+ }
+#endif
+
+ if (ovec != NULL)
+ {
+ __sighandler_t handler;
+ unsigned int sv_flags;
+ unsigned int sa_flags;
+ unsigned int mask;
+
+ handler = old.sa_handler;
+ sv_flags = 0;
+ sa_flags = old.sa_flags;
+#ifndef SA_RESETHAND
+ if (handler == sigvec_wrapper_handler)
+ {
+ handler = sigvec_wrapper_data[sig].sw_handler;
+ /* should we use data->sw_mask?? */
+ sv_flags |= SV_RESETHAND;
+ }
+#else
+ if (sa_flags & SA_RESETHAND)
+ sv_flags |= SV_RESETHAND;
+#endif
+ mask = sigset_get_old_mask (&old.sa_mask);
+#ifdef SA_ONSTACK
+ if (sa_flags & SA_ONSTACK)
+ sv_flags |= SV_ONSTACK;
+#endif
+#ifdef SA_RESTART
+ if (!(sa_flags & SA_RESTART))
+#endif
+ sv_flags |= SV_INTERRUPT;
+ ovec->sv_handler = handler;
+ ovec->sv_mask = (int)mask;
+ ovec->sv_flags = (int)sv_flags;
+ }
+
+ return 0;
+}
+
+weak_alias (__sigvec, sigvec)
+
+#ifndef SA_RESETHAND
+static void
+sigvec_wrapper_handler (sig)
+ int sig;
+{
+ struct sigvec_wrapper_data *data;
+ struct sigaction act;
+ int save;
+ __sighandler_t handler;
+
+ data = &sigvec_wrapper_data[sig];
+ act.sa_handler = SIG_DFL;
+ act.sa_flags = 0;
+ sigset_set_old_mask (&act.sa_mask, data->sw_mask);
+ handler = data->sw_handler;
+ save = errno;
+ (void) __sigaction (sig, &act, (struct sigaction *) NULL);
+ __set_errno (save);
+
+ (*handler) (sig);
+}
+#endif
diff --git a/libc/sysdeps/posix/sigwait.c b/libc/sysdeps/posix/sigwait.c
new file mode 100644
index 000000000..8b422d2b9
--- /dev/null
+++ b/libc/sysdeps/posix/sigwait.c
@@ -0,0 +1,109 @@
+/* Implementation of sigwait function from POSIX.1c.
+ Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <stddef.h> /* For NULL. */
+#include <sysdep-cancel.h>
+
+/* This is our dummy signal handler we use here. */
+static void ignore_signal (int sig);
+
+/* Place where to remember which signal we got. Please note that this
+ implementation cannot be used for the threaded libc. The
+ libpthread must provide an own version. */
+static int was_sig;
+
+
+static int
+do_sigwait (const sigset_t *set, int *sig)
+{
+ sigset_t tmp_mask;
+ struct sigaction saved[NSIG];
+ struct sigaction action;
+ int save_errno;
+ int this;
+
+ /* Prepare set. */
+ __sigfillset (&tmp_mask);
+
+ /* Unblock all signals in the SET and register our nice handler. */
+ action.sa_handler = ignore_signal;
+ action.sa_flags = 0;
+ __sigfillset (&action.sa_mask); /* Block all signals for handler. */
+
+ /* Make sure we recognize error conditions by setting WAS_SIG to a
+ value which does not describe a legal signal number. */
+ was_sig = -1;
+
+ for (this = 1; this < NSIG; ++this)
+ if (__sigismember (set, this))
+ {
+ /* Unblock this signal. */
+ __sigdelset (&tmp_mask, this);
+
+ /* Register temporary action handler. */
+ if (__sigaction (this, &action, &saved[this]) != 0)
+ goto restore_handler;
+ }
+
+ /* Now we can wait for signals. */
+ __sigsuspend (&tmp_mask);
+
+ restore_handler:
+ save_errno = errno;
+
+ while (--this >= 1)
+ if (__sigismember (set, this))
+ /* We ignore errors here since we must restore all handlers. */
+ __sigaction (this, &saved[this], NULL);
+
+ __set_errno (save_errno);
+
+ /* Store the result and return. */
+ *sig = was_sig;
+ return was_sig == -1 ? -1 : 0;
+}
+
+
+int
+__sigwait (const sigset_t *set, int *sig)
+{
+ if (SINGLE_THREAD_P)
+ return do_sigwait (set, sig);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_sigwait (set, sig);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+libc_hidden_def (__sigwait)
+weak_alias (__sigwait, sigwait)
+
+
+static void
+ignore_signal (int sig)
+{
+ /* Remember the signal. */
+ was_sig = sig;
+}
diff --git a/libc/sysdeps/posix/sleep.c b/libc/sysdeps/posix/sleep.c
new file mode 100644
index 000000000..f961dcd2e
--- /dev/null
+++ b/libc/sysdeps/posix/sleep.c
@@ -0,0 +1,106 @@
+/* Copyright (C) 1991, 1992, 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+#include <time.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+/* SIGALRM signal handler for `sleep'. This does nothing but return,
+ but SIG_IGN isn't supposed to break `pause'. */
+static void
+sleep_handler (int sig)
+{
+ return;
+}
+
+/* Make the process sleep for SECONDS seconds, or until a signal arrives
+ and is not ignored. The function returns the number of seconds less
+ than SECONDS which it actually slept (zero if it slept the full time).
+ If a signal handler does a `longjmp' or modifies the handling of the
+ SIGALRM signal while inside `sleep' call, the handling of the SIGALRM
+ signal afterwards is undefined. There is no return value to indicate
+ error, but if `sleep' returns SECONDS, it probably didn't work. */
+unsigned int
+__sleep (unsigned int seconds)
+{
+ unsigned int remaining, slept;
+ time_t before, after;
+ sigset_t set, oset;
+ struct sigaction act, oact;
+ int save = errno;
+
+ if (seconds == 0)
+ return 0;
+
+ /* Block SIGALRM signals while frobbing the handler. */
+ if (sigemptyset (&set) < 0 ||
+ sigaddset (&set, SIGALRM) < 0 ||
+ sigprocmask (SIG_BLOCK, &set, &oset))
+ return seconds;
+
+ act.sa_handler = sleep_handler;
+ act.sa_flags = 0;
+ act.sa_mask = oset; /* execute handler with original mask */
+ if (sigaction (SIGALRM, &act, &oact) < 0)
+ return seconds;
+
+ before = time ((time_t *) NULL);
+ remaining = alarm (seconds);
+
+ if (remaining > 0 && remaining < seconds)
+ {
+ /* The user's alarm will expire before our own would.
+ Restore the user's signal action state and let his alarm happen. */
+ (void) sigaction (SIGALRM, &oact, (struct sigaction *) NULL);
+ alarm (remaining); /* Restore sooner alarm. */
+ sigsuspend (&oset); /* Wait for it to go off. */
+ after = time ((time_t *) NULL);
+ }
+ else
+ {
+ /* Atomically restore the old signal mask
+ (which had better not block SIGALRM),
+ and wait for a signal to arrive. */
+ sigsuspend (&oset);
+
+ after = time ((time_t *) NULL);
+
+ /* Restore the old signal action state. */
+ (void) sigaction (SIGALRM, &oact, (struct sigaction *) NULL);
+ }
+
+ /* Notice how long we actually slept. */
+ slept = after - before;
+
+ /* Restore the user's alarm if we have not already past it.
+ If we have, be sure to turn off the alarm in case a signal
+ other than SIGALRM was what woke us up. */
+ (void) alarm (remaining > slept ? remaining - slept : 0);
+
+ /* Restore the original signal mask. */
+ (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);
+
+ /* Restore the `errno' value we started with.
+ Some of the calls we made might have failed, but we didn't care. */
+ __set_errno (save);
+
+ return slept > seconds ? 0 : seconds - slept;
+}
+weak_alias (__sleep, sleep)
diff --git a/libc/sysdeps/posix/spawni.c b/libc/sysdeps/posix/spawni.c
new file mode 100644
index 000000000..29803a846
--- /dev/null
+++ b/libc/sysdeps/posix/spawni.c
@@ -0,0 +1,293 @@
+/* Guts of POSIX spawn interface. Generic POSIX.1 version.
+ Copyright (C) 2000-2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <spawn.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "spawn_int.h"
+#include <not-cancel.h>
+#include <local-setxid.h>
+
+
+/* The Unix standard contains a long explanation of the way to signal
+ an error after the fork() was successful. Since no new wait status
+ was wanted there is no way to signal an error using one of the
+ available methods. The committee chose to signal an error by a
+ normal program exit with the exit code 127. */
+#define SPAWN_ERROR 127
+
+
+/* The file is accessible but it is not an executable file. Invoke
+ the shell to interpret it as a script. */
+static void
+internal_function
+script_execute (const char *file, char *const argv[], char *const envp[])
+{
+ /* Count the arguments. */
+ int argc = 0;
+ while (argv[argc++])
+ ;
+
+ /* Construct an argument list for the shell. */
+ {
+ char *new_argv[argc + 1];
+ new_argv[0] = (char *) _PATH_BSHELL;
+ new_argv[1] = (char *) file;
+ while (argc > 1)
+ {
+ new_argv[argc] = argv[argc - 1];
+ --argc;
+ }
+
+ /* Execute the shell. */
+ __execve (new_argv[0], new_argv, envp);
+ }
+}
+
+
+/* Spawn a new process executing PATH with the attributes describes in *ATTRP.
+ Before running the process perform the actions described in FILE-ACTIONS. */
+int
+__spawni (pid_t *pid, const char *file,
+ const posix_spawn_file_actions_t *file_actions,
+ const posix_spawnattr_t *attrp, char *const argv[],
+ char *const envp[], int use_path)
+{
+ pid_t new_pid;
+ char *path, *p, *name;
+ size_t len;
+ size_t pathlen;
+
+ /* Do this once. */
+ short int flags = attrp == NULL ? 0 : attrp->__flags;
+
+ /* Generate the new process. */
+ if ((flags & POSIX_SPAWN_USEVFORK) != 0
+ /* If no major work is done, allow using vfork. Note that we
+ might perform the path searching. But this would be done by
+ a call to execvp(), too, and such a call must be OK according
+ to POSIX. */
+ || ((flags & (POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF
+ | POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER
+ | POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_RESETIDS)) == 0
+ && file_actions == NULL))
+ new_pid = __vfork ();
+ else
+ new_pid = __fork ();
+
+ if (new_pid != 0)
+ {
+ if (new_pid < 0)
+ return errno;
+
+ /* The call was successful. Store the PID if necessary. */
+ if (pid != NULL)
+ *pid = new_pid;
+
+ return 0;
+ }
+
+ /* Set signal mask. */
+ if ((flags & POSIX_SPAWN_SETSIGMASK) != 0
+ && __sigprocmask (SIG_SETMASK, &attrp->__ss, NULL) != 0)
+ _exit (SPAWN_ERROR);
+
+ /* Set signal default action. */
+ if ((flags & POSIX_SPAWN_SETSIGDEF) != 0)
+ {
+ /* We have to iterate over all signals. This could possibly be
+ done better but it requires system specific solutions since
+ the sigset_t data type can be very different on different
+ architectures. */
+ int sig;
+ struct sigaction sa;
+
+ memset (&sa, '\0', sizeof (sa));
+ sa.sa_handler = SIG_DFL;
+
+ for (sig = 1; sig <= _NSIG; ++sig)
+ if (__sigismember (&attrp->__sd, sig) != 0
+ && __sigaction (sig, &sa, NULL) != 0)
+ _exit (SPAWN_ERROR);
+
+ }
+
+#ifdef _POSIX_PRIORITY_SCHEDULING
+ /* Set the scheduling algorithm and parameters. */
+ if ((flags & (POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER))
+ == POSIX_SPAWN_SETSCHEDPARAM)
+ {
+ if (__sched_setparam (0, &attrp->__sp) == -1)
+ _exit (SPAWN_ERROR);
+ }
+ else if ((flags & POSIX_SPAWN_SETSCHEDULER) != 0)
+ {
+ if (__sched_setscheduler (0, attrp->__policy,
+ (flags & POSIX_SPAWN_SETSCHEDPARAM) != 0
+ ? &attrp->__sp : NULL) == -1)
+ _exit (SPAWN_ERROR);
+ }
+#endif
+
+ /* Set the process group ID. */
+ if ((flags & POSIX_SPAWN_SETPGROUP) != 0
+ && __setpgid (0, attrp->__pgrp) != 0)
+ _exit (SPAWN_ERROR);
+
+ /* Set the effective user and group IDs. */
+ if ((flags & POSIX_SPAWN_RESETIDS) != 0
+ && (local_seteuid (__getuid ()) != 0
+ || local_setegid (__getgid ()) != 0))
+ _exit (SPAWN_ERROR);
+
+ /* Execute the file actions. */
+ if (file_actions != NULL)
+ {
+ int cnt;
+
+ for (cnt = 0; cnt < file_actions->__used; ++cnt)
+ {
+ struct __spawn_action *action = &file_actions->__actions[cnt];
+
+ switch (action->tag)
+ {
+ case spawn_do_close:
+ if (close_not_cancel (action->action.close_action.fd) != 0)
+ /* Signal the error. */
+ _exit (SPAWN_ERROR);
+ break;
+
+ case spawn_do_open:
+ {
+ int new_fd = open_not_cancel (action->action.open_action.path,
+ action->action.open_action.oflag
+ | O_LARGEFILE,
+ action->action.open_action.mode);
+
+ if (new_fd == -1)
+ /* The `open' call failed. */
+ _exit (SPAWN_ERROR);
+
+ /* Make sure the desired file descriptor is used. */
+ if (new_fd != action->action.open_action.fd)
+ {
+ if (__dup2 (new_fd, action->action.open_action.fd)
+ != action->action.open_action.fd)
+ /* The `dup2' call failed. */
+ _exit (SPAWN_ERROR);
+
+ if (close_not_cancel (new_fd) != 0)
+ /* The `close' call failed. */
+ _exit (SPAWN_ERROR);
+ }
+ }
+ break;
+
+ case spawn_do_dup2:
+ if (__dup2 (action->action.dup2_action.fd,
+ action->action.dup2_action.newfd)
+ != action->action.dup2_action.newfd)
+ /* The `dup2' call failed. */
+ _exit (SPAWN_ERROR);
+ break;
+ }
+ }
+ }
+
+ if (! use_path || strchr (file, '/') != NULL)
+ {
+ /* The FILE parameter is actually a path. */
+ __execve (file, argv, envp);
+
+ if (errno == ENOEXEC)
+ script_execute (file, argv, envp);
+
+ /* Oh, oh. `execve' returns. This is bad. */
+ _exit (SPAWN_ERROR);
+ }
+
+ /* We have to search for FILE on the path. */
+ path = getenv ("PATH");
+ if (path == NULL)
+ {
+ /* There is no `PATH' in the environment.
+ The default search path is the current directory
+ followed by the path `confstr' returns for `_CS_PATH'. */
+ len = confstr (_CS_PATH, (char *) NULL, 0);
+ path = (char *) __alloca (1 + len);
+ path[0] = ':';
+ (void) confstr (_CS_PATH, path + 1, len);
+ }
+
+ len = strlen (file) + 1;
+ pathlen = strlen (path);
+ name = __alloca (pathlen + len + 1);
+ /* Copy the file name at the top. */
+ name = (char *) memcpy (name + pathlen + 1, file, len);
+ /* And add the slash. */
+ *--name = '/';
+
+ p = path;
+ do
+ {
+ char *startp;
+
+ path = p;
+ p = __strchrnul (path, ':');
+
+ if (p == path)
+ /* Two adjacent colons, or a colon at the beginning or the end
+ of `PATH' means to search the current directory. */
+ startp = name + 1;
+ else
+ startp = (char *) memcpy (name - (p - path), path, p - path);
+
+ /* Try to execute this name. If it works, execv will not return. */
+ __execve (startp, argv, envp);
+
+ if (errno == ENOEXEC)
+ script_execute (startp, argv, envp);
+
+ switch (errno)
+ {
+ case EACCES:
+ case ENOENT:
+ case ESTALE:
+ case ENOTDIR:
+ /* Those errors indicate the file is missing or not executable
+ by us, in which case we want to just try the next path
+ directory. */
+ break;
+
+ default:
+ /* Some other error means we found an executable file, but
+ something went wrong executing it; return the error to our
+ caller. */
+ _exit (SPAWN_ERROR);
+ }
+ }
+ while (*p++ != '\0');
+
+ /* Return with an error. */
+ _exit (SPAWN_ERROR);
+}
diff --git a/libc/sysdeps/posix/sprofil.c b/libc/sysdeps/posix/sprofil.c
new file mode 100644
index 000000000..853038d07
--- /dev/null
+++ b/libc/sysdeps/posix/sprofil.c
@@ -0,0 +1,356 @@
+/* Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/time.h>
+#include <sys/profil.h>
+
+#ifndef SIGPROF
+# include <gmon/sprofil.c>
+#else
+
+#include <libc-internal.h>
+
+struct region
+ {
+ size_t offset;
+ size_t nsamples;
+ unsigned int scale;
+ union
+ {
+ void *vp;
+ unsigned short *us;
+ unsigned int *ui;
+ }
+ sample;
+ size_t start;
+ size_t end;
+ };
+
+struct prof_info
+ {
+ unsigned int num_regions;
+ struct region *region;
+ struct region *last, *overflow;
+ struct itimerval saved_timer;
+ struct sigaction saved_action;
+ };
+
+static unsigned int overflow_counter;
+
+static struct region default_overflow_region =
+ {
+ .offset = 0,
+ .nsamples = 1,
+ .scale = 2,
+ .sample = { &overflow_counter },
+ .start = 0,
+ .end = ~(size_t) 0
+ };
+
+static struct prof_info prof_info;
+
+static unsigned long int
+pc_to_index (size_t pc, size_t offset, unsigned int scale, int prof_uint)
+{
+ size_t i = (pc - offset) / (prof_uint ? sizeof (int) : sizeof (short));
+
+ if (sizeof (unsigned long long int) > sizeof (size_t))
+ return (unsigned long long int) i * scale / 65536;
+ else
+ return i / 65536 * scale + i % 65536 * scale / 65536;
+}
+
+static inline size_t
+index_to_pc (unsigned long int n, size_t offset, unsigned int scale,
+ int prof_uint)
+{
+ size_t pc, bin_size = (prof_uint ? sizeof (int) : sizeof (short));
+
+ if (sizeof (unsigned long long int) > sizeof (size_t))
+ pc = offset + (unsigned long long int) n * bin_size * 65536ull / scale;
+ else
+ pc = (offset + n * bin_size / scale * 65536
+ + n * bin_size % scale * 65536 / scale);
+
+ if (pc_to_index (pc, offset, scale, prof_uint) < n)
+ /* Adjust for rounding error. */
+ ++pc;
+
+ assert (pc_to_index (pc - 1, offset, scale, prof_uint) < n
+ && pc_to_index (pc, offset, scale, prof_uint) >= n);
+
+ return pc;
+}
+
+static void
+profil_count (void *pcp, int prof_uint)
+{
+ struct region *region, *r = prof_info.last;
+ size_t lo, hi, mid, pc = (unsigned long int) pcp;
+ unsigned long int i;
+
+ /* Fast path: pc is in same region as before. */
+ if (pc >= r->start && pc < r->end)
+ region = r;
+ else
+ {
+ /* Slow path: do a binary search for the right region. */
+ lo = 0; hi = prof_info.num_regions - 1;
+ while (lo <= hi)
+ {
+ mid = (lo + hi) / 2;
+
+ r = prof_info.region + mid;
+ if (pc >= r->start && pc < r->end)
+ {
+ prof_info.last = r;
+ region = r;
+ break;
+ }
+
+ if (pc < r->start)
+ hi = mid - 1;
+ else
+ lo = mid + 1;
+ }
+
+ /* No matching region: increment overflow count. There is no point
+ in updating the cache here, as it won't hit anyhow. */
+ region = prof_info.overflow;
+ }
+
+ i = pc_to_index (pc, region->offset, region->scale, prof_uint);
+ if (i < r->nsamples)
+ {
+ if (prof_uint)
+ {
+ if (r->sample.ui[i] < (unsigned int) ~0)
+ ++r->sample.ui[i];
+ }
+ else
+ {
+ if (r->sample.us[i] < (unsigned short) ~0)
+ ++r->sample.us[i];
+ }
+ }
+ else
+ {
+ if (prof_uint)
+ ++prof_info.overflow->sample.ui[0];
+ else
+ ++prof_info.overflow->sample.us[0];
+ }
+}
+
+static inline void
+profil_count_ushort (void *pcp)
+{
+ profil_count (pcp, 0);
+}
+
+static inline void
+profil_count_uint (void *pcp)
+{
+ profil_count (pcp, 1);
+}
+
+/* Get the machine-dependent definition of `profil_counter', the signal
+ handler for SIGPROF. It calls `profil_count' (above) with the PC of the
+ interrupted code. */
+#define profil_counter profil_counter_ushort
+#define profil_count(pc) profil_count (pc, 0)
+#include <profil-counter.h>
+
+#undef profil_counter
+#undef profil_count
+
+#define profil_counter profil_counter_uint
+#define profil_count(pc) profil_count (pc, 1)
+#include <profil-counter.h>
+
+static int
+insert (int i, unsigned long int start, unsigned long int end, struct prof *p,
+ int prof_uint)
+{
+ struct region *r;
+ size_t to_copy;
+
+ if (start >= end)
+ return 0; /* don't bother with empty regions */
+
+ if (prof_info.num_regions == 0)
+ r = malloc (sizeof (*r));
+ else
+ r = realloc (prof_info.region, (prof_info.num_regions + 1) * sizeof (*r));
+ if (r == NULL)
+ return -1;
+
+ to_copy = prof_info.num_regions - i;
+ if (to_copy > 0)
+ memmove (r + i + 1, r + i, to_copy * sizeof (*r));
+
+ r[i].offset = p->pr_off;
+ r[i].nsamples = p->pr_size / (prof_uint ? sizeof (int) : sizeof (short));
+ r[i].scale = p->pr_scale;
+ r[i].sample.vp = p->pr_base;
+ r[i].start = start;
+ r[i].end = end;
+
+ prof_info.region = r;
+ ++prof_info.num_regions;
+
+ if (p->pr_off == 0 && p->pr_scale == 2)
+ prof_info.overflow = r;
+
+ return 0;
+}
+
+/* Add a new profiling region. If the new region overlaps with
+ existing ones, this may add multiple subregions so that the final
+ data structure is free of overlaps. The absence of overlaps makes
+ it possible to use a binary search in profil_count(). Note that
+ this function depends on new regions being presented in DECREASING
+ ORDER of starting address. */
+
+static int
+add_region (struct prof *p, int prof_uint)
+{
+ unsigned long int nsamples;
+ size_t start, end;
+ unsigned int i;
+
+ if (p->pr_scale < 2)
+ return 0;
+
+ nsamples = p->pr_size / (prof_uint ? sizeof (int) : sizeof (short));
+
+ start = p->pr_off;
+ end = index_to_pc (nsamples, p->pr_off, p->pr_scale, prof_uint);
+
+ /* Merge with existing regions. */
+ for (i = 0; i < prof_info.num_regions; ++i)
+ {
+ if (start < prof_info.region[i].start)
+ {
+ if (end < prof_info.region[i].start)
+ break;
+ else if (insert (i, start, prof_info.region[i].start, p, prof_uint)
+ < 0)
+ return -1;
+ }
+ start = prof_info.region[i].end;
+ }
+ return insert (i, start, end, p, prof_uint);
+}
+
+static int
+pcmp (const void *left, const void *right)
+{
+ struct prof *l = *(struct prof **) left;
+ struct prof *r = *(struct prof **) right;
+
+ if (l->pr_off < r->pr_off)
+ return 1;
+ else if (l->pr_off > r->pr_off)
+ return -1;
+ return 0;
+}
+
+int
+__sprofil (struct prof *profp, int profcnt, struct timeval *tvp,
+ unsigned int flags)
+{
+ struct prof *p[profcnt];
+ struct itimerval timer;
+ struct sigaction act;
+ int i;
+
+ if (tvp != NULL)
+ {
+ /* Return profiling period. */
+ unsigned long int t = 1000000 / __profile_frequency ();
+ tvp->tv_sec = t / 1000000;
+ tvp->tv_usec = t % 1000000;
+ }
+
+ if (prof_info.num_regions > 0)
+ {
+ /* Disable profiling. */
+ if (__setitimer (ITIMER_PROF, &prof_info.saved_timer, NULL) < 0)
+ return -1;
+
+ if (__sigaction (SIGPROF, &prof_info.saved_action, NULL) < 0)
+ return -1;
+
+ free (prof_info.region);
+ return 0;
+ }
+
+ prof_info.num_regions = 0;
+ prof_info.region = NULL;
+ prof_info.overflow = &default_overflow_region;
+
+ for (i = 0; i < profcnt; ++i)
+ p[i] = profp + i;
+
+ /* Sort in order of decreasing starting address: */
+ qsort (p, profcnt, sizeof (p[0]), pcmp);
+
+ /* Add regions in order of decreasing starting address: */
+ for (i = 0; i < profcnt; ++i)
+ if (add_region (p[i], (flags & PROF_UINT) != 0) < 0)
+ {
+ if (prof_info.region)
+ free (prof_info.region);
+ prof_info.num_regions = 0;
+ prof_info.region = NULL;
+ return -1;
+ }
+
+ if (prof_info.num_regions == 0)
+ return 0;
+
+ prof_info.last = prof_info.region;
+
+ /* Install SIGPROF handler. */
+ if (flags & PROF_UINT)
+ act.sa_handler = (sighandler_t) &profil_counter_uint;
+ else
+ act.sa_handler = (sighandler_t) &profil_counter_ushort;
+ act.sa_flags = SA_RESTART;
+ __sigfillset (&act.sa_mask);
+ if (__sigaction (SIGPROF, &act, &prof_info.saved_action) < 0)
+ return -1;
+
+ /* Setup profiling timer. */
+ timer.it_value.tv_sec = 0;
+ timer.it_value.tv_usec = 1;
+ timer.it_interval = timer.it_value;
+ return __setitimer (ITIMER_PROF, &timer, &prof_info.saved_timer);
+}
+
+weak_alias (__sprofil, sprofil)
+
+#endif /* SIGPROF */
diff --git a/libc/sysdeps/posix/sysconf.c b/libc/sysdeps/posix/sysconf.c
new file mode 100644
index 000000000..0c0d7d141
--- /dev/null
+++ b/libc/sysdeps/posix/sysconf.c
@@ -0,0 +1,1241 @@
+/* Copyright (C) 1991,1993,1995-1997,1999-2003,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <grp.h>
+#include <pwd.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/sysinfo.h>
+#include <sys/types.h>
+#include <regex.h>
+
+
+#define NEED_CHECK_SPEC \
+ (!defined _XBS5_ILP32_OFF32 || !defined _XBS5_ILP32_OFFBIG \
+ || !defined _XBS5_LP64_OFF64 || !defined _XBS5_LPBIG_OFFBIG \
+ || !defined _POSIX_V6_ILP32_OFF32 || !defined _POSIX_V6_ILP32_OFFBIG \
+ || !defined _POSIX_V6_LP64_OFF64 || !defined _POSIX_V6_LPBIG_OFFBIG)
+#if NEED_CHECK_SPEC
+static long int __sysconf_check_spec (const char *spec);
+#endif
+
+
+/* Get the value of the system variable NAME. */
+long int
+__sysconf (name)
+ int name;
+{
+ switch (name)
+ {
+ /* Also add obsolete or unnecessarily added constants here. */
+ case _SC_EQUIV_CLASS_MAX:
+ default:
+ __set_errno (EINVAL);
+ return -1;
+
+ case _SC_ARG_MAX:
+#ifdef ARG_MAX
+ return ARG_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_CHILD_MAX:
+#ifdef CHILD_MAX
+ return CHILD_MAX;
+#else
+ return __get_child_max ();
+#endif
+
+ case _SC_CLK_TCK:
+ return __getclktck ();
+
+ case _SC_NGROUPS_MAX:
+#ifdef NGROUPS_MAX
+ return NGROUPS_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_OPEN_MAX:
+ return __getdtablesize ();
+
+ case _SC_STREAM_MAX:
+#ifdef STREAM_MAX
+ return STREAM_MAX;
+#else
+ return FOPEN_MAX;
+#endif
+
+ case _SC_TZNAME_MAX:
+ return MAX (__tzname_max (), _POSIX_TZNAME_MAX);
+
+ case _SC_JOB_CONTROL:
+#if _POSIX_JOB_CONTROL > 0
+ return _POSIX_JOB_CONTROL;
+#else
+ return -1;
+#endif
+
+ case _SC_SAVED_IDS:
+#if _POSIX_SAVED_IDS > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ case _SC_REALTIME_SIGNALS:
+#if _POSIX_REALTIME_SIGNALS > 0
+ return _POSIX_REALTIME_SIGNALS;
+#else
+ return -1;
+#endif
+
+ case _SC_PRIORITY_SCHEDULING:
+#if _POSIX_PRIORITY_SCHEDULING > 0
+ return _POSIX_PRIORITY_SCHEDULING;
+#else
+ return -1;
+#endif
+
+ case _SC_TIMERS:
+#if _POSIX_TIMERS > 0
+ return _POSIX_TIMERS;
+#else
+ return -1;
+#endif
+
+ case _SC_ASYNCHRONOUS_IO:
+#if _POSIX_ASYNCHRONOUS_IO > 0
+ return _POSIX_ASYNCHRONOUS_IO;
+#else
+ return -1;
+#endif
+
+ case _SC_PRIORITIZED_IO:
+#if _POSIX_PRIORITIZED_IO > 0
+ return _POSIX_PRIORITIZED_IO;
+#else
+ return -1;
+#endif
+
+ case _SC_SYNCHRONIZED_IO:
+#if _POSIX_SYNCHRONIZED_IO > 0
+ return _POSIX_SYNCHRONIZED_IO;
+#else
+ return -1;
+#endif
+
+ case _SC_FSYNC:
+#if _POSIX_FSYNC > 0
+ return _POSIX_FSYNC;
+#else
+ return -1;
+#endif
+
+ case _SC_MAPPED_FILES:
+#if _POSIX_MAPPED_FILES > 0
+ return _POSIX_MAPPED_FILES;
+#else
+ return -1;
+#endif
+
+ case _SC_MEMLOCK:
+#if _POSIX_MEMLOCK > 0
+ return _POSIX_MEMLOCK;
+#else
+ return -1;
+#endif
+
+ case _SC_MEMLOCK_RANGE:
+#if _POSIX_MEMLOCK_RANGE > 0
+ return _POSIX_MEMLOCK_RANGE;
+#else
+ return -1;
+#endif
+
+ case _SC_MEMORY_PROTECTION:
+#if _POSIX_MEMORY_PROTECTION > 0
+ return _POSIX_MEMORY_PROTECTION;
+#else
+ return -1;
+#endif
+
+ case _SC_MESSAGE_PASSING:
+#if _POSIX_MESSAGE_PASSING > 0
+ return _POSIX_MESSAGE_PASSING;
+#else
+ return -1;
+#endif
+
+ case _SC_SEMAPHORES:
+#if _POSIX_SEMAPHORES > 0
+ return _POSIX_SEMAPHORES;
+#else
+ return -1;
+#endif
+
+ case _SC_SHARED_MEMORY_OBJECTS:
+#if _POSIX_SHARED_MEMORY_OBJECTS > 0
+ return _POSIX_SHARED_MEMORY_OBJECTS;
+#else
+ return -1;
+#endif
+
+ case _SC_VERSION:
+ return _POSIX_VERSION;
+
+ case _SC_PAGESIZE:
+ return __getpagesize ();
+
+ case _SC_AIO_LISTIO_MAX:
+#ifdef AIO_LISTIO_MAX
+ return AIO_LISTIO_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_AIO_MAX:
+#ifdef AIO_MAX
+ return AIO_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_AIO_PRIO_DELTA_MAX:
+#ifdef AIO_PRIO_DELTA_MAX
+ return AIO_PRIO_DELTA_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_DELAYTIMER_MAX:
+#ifdef DELAYTIMER_MAX
+ return DELAYTIMER_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_MQ_OPEN_MAX:
+#ifdef MQ_OPEN_MAX
+ return MQ_OPEN_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_MQ_PRIO_MAX:
+#ifdef MQ_PRIO_MAX
+ return MQ_PRIO_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_RTSIG_MAX:
+#ifdef RTSIG_MAX
+ return RTSIG_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_SEM_NSEMS_MAX:
+#ifdef SEM_NSEMS_MAX
+ return SEM_NSEMS_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_SEM_VALUE_MAX:
+#ifdef SEM_VALUE_MAX
+ return SEM_VALUE_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_SIGQUEUE_MAX:
+#ifdef SIGQUEUE_MAX
+ return SIGQUEUE_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_TIMER_MAX:
+#ifdef TIMER_MAX
+ return TIMER_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_BC_BASE_MAX:
+#ifdef BC_BASE_MAX
+ return BC_BASE_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_BC_DIM_MAX:
+#ifdef BC_DIM_MAX
+ return BC_DIM_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_BC_SCALE_MAX:
+#ifdef BC_SCALE_MAX
+ return BC_SCALE_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_BC_STRING_MAX:
+#ifdef BC_STRING_MAX
+ return BC_STRING_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_COLL_WEIGHTS_MAX:
+#ifdef COLL_WEIGHTS_MAX
+ return COLL_WEIGHTS_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_EXPR_NEST_MAX:
+#ifdef EXPR_NEST_MAX
+ return EXPR_NEST_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_LINE_MAX:
+#ifdef LINE_MAX
+ return LINE_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_RE_DUP_MAX:
+#ifdef RE_DUP_MAX
+ return RE_DUP_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_CHARCLASS_NAME_MAX:
+#ifdef CHARCLASS_NAME_MAX
+ return CHARCLASS_NAME_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_PII:
+#if _POSIX_PII > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ case _SC_PII_XTI:
+#if _POSIX_PII_XTI > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ case _SC_PII_SOCKET:
+#if _POSIX_PII_SOCKET > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ case _SC_PII_INTERNET:
+#if _POSIX_PII_INTERNET > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ case _SC_PII_OSI:
+#if _POSIX_PII_OSI > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ case _SC_POLL:
+#if _POSIX_POLL > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ case _SC_SELECT:
+#if _POSIX_SELECT > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ /* The same as _SC_IOV_MAX. */
+ case _SC_UIO_MAXIOV:
+#ifdef UIO_MAXIOV
+ return UIO_MAXIOV;
+#else
+ return -1;
+#endif
+
+ case _SC_PII_INTERNET_STREAM:
+#if _POSIX_PII_INTERNET_STREAM > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ case _SC_PII_INTERNET_DGRAM:
+#if _POSIX_PII_INTERNET_DGRAM > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ case _SC_PII_OSI_COTS:
+#if _POSIX_PII_OSI_COTS > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ case _SC_PII_OSI_CLTS:
+#if _POSIX_PII_OSI_CLTS > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ case _SC_PII_OSI_M:
+#if _POSIX_PII_OSI_M > 0
+ return 1;
+#else
+ return -1;
+#endif
+
+ case _SC_T_IOV_MAX:
+#ifdef _T_IOV_MAX
+ return _T_IOV_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_2_VERSION:
+ return _POSIX2_VERSION;
+
+ case _SC_2_C_BIND:
+#ifdef _POSIX2_C_BIND
+ return _POSIX2_C_BIND;
+#else
+ return -1;
+#endif
+
+ case _SC_2_C_DEV:
+#ifdef _POSIX2_C_DEV
+ return _POSIX2_C_DEV;
+#else
+ return -1;
+#endif
+
+ case _SC_2_C_VERSION:
+#ifdef _POSIX2_C_VERSION
+ return _POSIX2_C_VERSION;
+#else
+ return -1;
+#endif
+
+ case _SC_2_FORT_DEV:
+#ifdef _POSIX2_FORT_DEV
+ return _POSIX2_FORT_DEV;
+#else
+ return -1;
+#endif
+
+ case _SC_2_FORT_RUN:
+#ifdef _POSIX2_FORT_RUN
+ return _POSIX2_FORT_RUN;
+#else
+ return -1;
+#endif
+
+ case _SC_2_LOCALEDEF:
+#ifdef _POSIX2_LOCALEDEF
+ return _POSIX2_LOCALEDEF;
+#else
+ return -1;
+#endif
+
+ case _SC_2_SW_DEV:
+#ifdef _POSIX2_SW_DEV
+ return _POSIX2_SW_DEV;
+#else
+ return -1;
+#endif
+
+ case _SC_2_CHAR_TERM:
+#ifdef _POSIX2_CHAR_TERM
+ return _POSIX2_CHAR_TERM;
+#else
+ return -1;
+#endif
+
+ case _SC_2_UPE:
+#ifdef _POSIX2_UPE
+ return _POSIX2_UPE;
+#else
+ return -1;
+#endif
+
+ /* POSIX 1003.1c (POSIX Threads). */
+ case _SC_THREADS:
+#if _POSIX_THREADS > 0
+ return _POSIX_THREADS;
+#else
+ return -1;
+#endif
+
+ case _SC_THREAD_SAFE_FUNCTIONS:
+#if _POSIX_THREAD_SAFE_FUNCTIONS > 0
+ return _POSIX_THREAD_SAFE_FUNCTIONS;
+#else
+ return -1;
+#endif
+
+ case _SC_GETGR_R_SIZE_MAX:
+ return NSS_BUFLEN_GROUP;
+
+ case _SC_GETPW_R_SIZE_MAX:
+ return NSS_BUFLEN_PASSWD;
+
+ case _SC_LOGIN_NAME_MAX:
+#ifdef LOGIN_NAME_MAX
+ return LOGIN_NAME_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_TTY_NAME_MAX:
+#ifdef TTY_NAME_MAX
+ return TTY_NAME_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_THREAD_DESTRUCTOR_ITERATIONS:
+#if _POSIX_THREAD_DESTRUCTOR_ITERATIONS > 0
+ return _POSIX_THREAD_DESTRUCTOR_ITERATIONS;
+#else
+ return -1;
+#endif
+
+ case _SC_THREAD_KEYS_MAX:
+#ifdef PTHREAD_KEYS_MAX
+ return PTHREAD_KEYS_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_THREAD_STACK_MIN:
+#ifdef PTHREAD_STACK_MIN
+ return PTHREAD_STACK_MIN;
+#else
+ return -1;
+#endif
+
+ case _SC_THREAD_THREADS_MAX:
+#ifdef PTHREAD_THREADS_MAX
+ return PTHREAD_THREADS_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_THREAD_ATTR_STACKADDR:
+#if _POSIX_THREAD_ATTR_STACKADDR > 0
+ return _POSIX_THREAD_ATTR_STACKADDR;
+#else
+ return -1;
+#endif
+
+ case _SC_THREAD_ATTR_STACKSIZE:
+#if _POSIX_THREAD_ATTR_STACKSIZE > 0
+ return _POSIX_THREAD_ATTR_STACKSIZE;
+#else
+ return -1;
+#endif
+
+ case _SC_THREAD_PRIORITY_SCHEDULING:
+#if _POSIX_THREAD_PRIORITY_SCHEDULING > 0
+ return _POSIX_THREAD_PRIORITY_SCHEDULING;
+#else
+ return -1;
+#endif
+
+ case _SC_THREAD_PRIO_INHERIT:
+#if _POSIX_THREAD_PRIO_INHERIT > 0
+ return _POSIX_THREAD_PRIO_INHERIT;
+#else
+ return -1;
+#endif
+
+ case _SC_THREAD_PRIO_PROTECT:
+#if _POSIX_THREAD_PRIO_PROTECT > 0
+ return _POSIX_THREAD_PRIO_PROTECT;
+#else
+ return -1;
+#endif
+
+ case _SC_THREAD_PROCESS_SHARED:
+#if _POSIX_THREAD_PROCESS_SHARED > 0
+ return _POSIX_THREAD_PROCESS_SHARED;
+#else
+ return -1;
+#endif
+
+ case _SC_NPROCESSORS_CONF:
+ return __get_nprocs_conf ();
+
+ case _SC_NPROCESSORS_ONLN:
+ return __get_nprocs ();
+
+ case _SC_PHYS_PAGES:
+ return __get_phys_pages ();
+
+ case _SC_AVPHYS_PAGES:
+ return __get_avphys_pages ();
+
+ case _SC_ATEXIT_MAX:
+ /* We have no limit since we use lists. */
+ return INT_MAX;
+
+ case _SC_PASS_MAX:
+ /* We have no limit but since the return value might be used to
+ allocate a buffer we restrict the value. */
+ return BUFSIZ;
+
+ case _SC_XOPEN_VERSION:
+ return _XOPEN_VERSION;
+
+ case _SC_XOPEN_XCU_VERSION:
+ return _XOPEN_XCU_VERSION;
+
+ case _SC_XOPEN_UNIX:
+ return _XOPEN_UNIX;
+
+ case _SC_XOPEN_CRYPT:
+#ifdef _XOPEN_CRYPT
+ return _XOPEN_CRYPT;
+#else
+ return -1;
+#endif
+
+ case _SC_XOPEN_ENH_I18N:
+#ifdef _XOPEN_ENH_I18N
+ return _XOPEN_ENH_I18N;
+#else
+ return -1;
+#endif
+
+ case _SC_XOPEN_SHM:
+#ifdef _XOPEN_SHM
+ return _XOPEN_SHM;
+#else
+ return -1;
+#endif
+
+ case _SC_XOPEN_XPG2:
+#ifdef _XOPEN_XPG2
+ return _XOPEN_XPG2;
+#else
+ return -1;
+#endif
+
+ case _SC_XOPEN_XPG3:
+#ifdef _XOPEN_XPG3
+ return _XOPEN_XPG3;
+#else
+ return -1;
+#endif
+
+ case _SC_XOPEN_XPG4:
+#ifdef _XOPEN_XPG4
+ return _XOPEN_XPG4;
+#else
+ return -1;
+#endif
+
+ case _SC_CHAR_BIT:
+ return CHAR_BIT;
+
+ case _SC_CHAR_MAX:
+ return CHAR_MAX;
+
+ case _SC_CHAR_MIN:
+ return CHAR_MIN;
+
+ case _SC_INT_MAX:
+ return INT_MAX;
+
+ case _SC_INT_MIN:
+ return INT_MIN;
+
+ case _SC_LONG_BIT:
+ return sizeof (long int) * CHAR_BIT;
+
+ case _SC_WORD_BIT:
+ return sizeof (int) * CHAR_BIT;
+
+ case _SC_MB_LEN_MAX:
+ return MB_LEN_MAX;
+
+ case _SC_NZERO:
+ return NZERO;
+
+ case _SC_SSIZE_MAX:
+ return _POSIX_SSIZE_MAX;
+
+ case _SC_SCHAR_MAX:
+ return SCHAR_MAX;
+
+ case _SC_SCHAR_MIN:
+ return SCHAR_MIN;
+
+ case _SC_SHRT_MAX:
+ return SHRT_MAX;
+
+ case _SC_SHRT_MIN:
+ return SHRT_MIN;
+
+ case _SC_UCHAR_MAX:
+ return UCHAR_MAX;
+
+ case _SC_UINT_MAX:
+ return UINT_MAX;
+
+ case _SC_ULONG_MAX:
+ return ULONG_MAX;
+
+ case _SC_USHRT_MAX:
+ return USHRT_MAX;
+
+ case _SC_NL_ARGMAX:
+#ifdef NL_ARGMAX
+ return NL_ARGMAX;
+#else
+ return -1;
+#endif
+
+ case _SC_NL_LANGMAX:
+#ifdef NL_LANGMAX
+ return NL_LANGMAX;
+#else
+ return -1;
+#endif
+
+ case _SC_NL_MSGMAX:
+#ifdef NL_MSGMAX
+ return NL_MSGMAX;
+#else
+ return -1;
+#endif
+
+ case _SC_NL_NMAX:
+#ifdef NL_NMAX
+ return NL_NMAX;
+#else
+ return -1;
+#endif
+
+ case _SC_NL_SETMAX:
+#ifdef NL_SETMAX
+ return NL_SETMAX;
+#else
+ return -1;
+#endif
+
+ case _SC_NL_TEXTMAX:
+#ifdef NL_TEXTMAX
+ return NL_TEXTMAX;
+#else
+ return -1;
+#endif
+
+ case _SC_XBS5_ILP32_OFF32:
+#ifdef _XBS5_ILP32_OFF32
+ return _XBS5_ILP32_OFF32;
+#else
+ return __sysconf_check_spec ("ILP32_OFF32");
+#endif
+ case _SC_XBS5_ILP32_OFFBIG:
+#ifdef _XBS5_ILP32_OFFBIG
+ return _XBS5_ILP32_OFFBIG;
+#else
+ return __sysconf_check_spec ("ILP32_OFFBIG");
+#endif
+ case _SC_XBS5_LP64_OFF64:
+#ifdef _XBS5_LP64_OFF64
+ return _XBS5_LP64_OFF64;
+#else
+ return __sysconf_check_spec ("LP64_OFF64");
+#endif
+ case _SC_XBS5_LPBIG_OFFBIG:
+#ifdef _XBS5_LPBIG_OFFBIG
+ return _XBS5_LPBIG_OFFBIG;
+#else
+ return __sysconf_check_spec ("LPBIG_OFFBIG");
+#endif
+
+ case _SC_V6_ILP32_OFF32:
+#ifdef _POSIX_V6_ILP32_OFF32
+ return _POSIX_V6_ILP32_OFF32;
+#else
+ return __sysconf_check_spec ("ILP32_OFF32");
+#endif
+ case _SC_V6_ILP32_OFFBIG:
+#ifdef _POSIX_V6_ILP32_OFFBIG
+ return _POSIX_V6_ILP32_OFFBIG;
+#else
+ return __sysconf_check_spec ("ILP32_OFFBIG");
+#endif
+ case _SC_V6_LP64_OFF64:
+#ifdef _POSIX_V6_LP64_OFF64
+ return _POSIX_V6_LP64_OFF64;
+#else
+ return __sysconf_check_spec ("LP64_OFF64");
+#endif
+ case _SC_V6_LPBIG_OFFBIG:
+#ifdef _POSIX_V6_LPBIG_OFFBIG
+ return _POSIX_V6_LPBIG_OFFBIG;
+#else
+ return __sysconf_check_spec ("LPBIG_OFFBIG");
+#endif
+
+ case _SC_XOPEN_LEGACY:
+ return _XOPEN_LEGACY;
+
+ case _SC_XOPEN_REALTIME:
+#ifdef _XOPEN_REALTIME
+ return _XOPEN_REALTIME;
+#else
+ return -1;
+#endif
+ case _SC_XOPEN_REALTIME_THREADS:
+#ifdef _XOPEN_REALTIME_THREADS
+ return _XOPEN_REALTIME_THREADS;
+#else
+ return -1;
+#endif
+
+ case _SC_ADVISORY_INFO:
+#if _POSIX_ADVISORY_INFO > 0
+ return _POSIX_ADVISORY_INFO;
+#else
+ return -1;
+#endif
+
+ case _SC_BARRIERS:
+#if _POSIX_BARRIERS > 0
+ return _POSIX_BARRIERS;
+#else
+ return -1;
+#endif
+
+ case _SC_BASE:
+#if _POSIX_BASE > 0
+ return _POSIX_BASE;
+#else
+ return -1;
+#endif
+ case _SC_C_LANG_SUPPORT:
+#if _POSIX_C_LANG_SUPPORT > 0
+ return _POSIX_C_LANG_SUPPORT;
+#else
+ return -1;
+#endif
+ case _SC_C_LANG_SUPPORT_R:
+#if _POSIX_C_LANG_SUPPORT_R > 0
+ return _POSIX_C_LANG_SUPPORT_R;
+#else
+ return -1;
+#endif
+
+ case _SC_CLOCK_SELECTION:
+#if _POSIX_CLOCK_SELECTION > 0
+ return _POSIX_CLOCK_SELECTION;
+#else
+ return -1;
+#endif
+
+ case _SC_CPUTIME:
+#if _POSIX_CPUTIME > 0
+ return _POSIX_CPUTIME;
+#else
+ return -1;
+#endif
+
+ case _SC_DEVICE_IO:
+#if _POSIX_DEVICE_IO > 0
+ return _POSIX_DEVICE_IO;
+#else
+ return -1;
+#endif
+ case _SC_DEVICE_SPECIFIC:
+#if _POSIX_DEVICE_SPCIFIC > 0
+ return _POSIX_DEVICE_SPECIFIC;
+#else
+ return -1;
+#endif
+ case _SC_DEVICE_SPECIFIC_R:
+#if _POSIX_DEVICE_SPCIFIC_R > 0
+ return _POSIX_DEVICE_SPECIFIC_R;
+#else
+ return -1;
+#endif
+
+ case _SC_FD_MGMT:
+#if _POSIX_FD_MGMT > 0
+ return _POSIX_FD_MGMT;
+#else
+ return -1;
+#endif
+
+ case _SC_FIFO:
+#if _POSIX_FIFO > 0
+ return _POSIX_FIFO;
+#else
+ return -1;
+#endif
+ case _SC_PIPE:
+#if _POSIX_PIPE > 0
+ return _POSIX_PIPE;
+#else
+ return -1;
+#endif
+
+ case _SC_FILE_ATTRIBUTES:
+#if _POSIX_FILE_ATTRIBUTES > 0
+ return _POSIX_FILE_ATTRIBUTES;
+#else
+ return -1;
+#endif
+ case _SC_FILE_LOCKING:
+#if _POSIX_FILE_LOCKING > 0
+ return _POSIX_FILE_LOCKING;
+#else
+ return -1;
+#endif
+ case _SC_FILE_SYSTEM:
+#if _POSIX_FILE_SYSTEM > 0
+ return _POSIX_FILE_SYSTEM;
+#else
+ return -1;
+#endif
+
+ case _SC_MONOTONIC_CLOCK:
+#if _POSIX_MONOTONIC_CLOCK
+ return _POSIX_MONOTONIC_CLOCK;
+#else
+ return -1;
+#endif
+
+ case _SC_MULTI_PROCESS:
+#if _POSIX_MULTI_PROCESS > 0
+ return _POSIX_MULTI_PROCESS;
+#else
+ return -1;
+#endif
+ case _SC_SINGLE_PROCESS:
+#if _POSIX_SINGLE_PROCESS > 0
+ return _POSIX_SINGLE_PROCESS;
+#else
+ return -1;
+#endif
+
+ case _SC_NETWORKING:
+#if _POSIX_NETWORKING > 0
+ return _POSIX_NETWORKING;
+#else
+ return -1;
+#endif
+
+ case _SC_READER_WRITER_LOCKS:
+#if _POSIX_READER_WRITER_LOCKS > 0
+ return _POSIX_READER_WRITER_LOCKS;
+#else
+ return -1;
+#endif
+ case _SC_SPIN_LOCKS:
+#if _POSIX_SPIN_LOCKS > 0
+ return _POSIX_SPIN_LOCKS;
+#else
+ return -1;
+#endif
+
+ case _SC_REGEXP:
+#if _POSIX_REGEXP > 0
+ return _POSIX_REGEXP;
+#else
+ return -1;
+#endif
+ case _SC_REGEX_VERSION:
+#if _POSIX_REGEX_VERSION > 0
+ return _POSIX_REGEX_VERSION;
+#else
+ return -1;
+#endif
+
+ case _SC_SHELL:
+#if _POSIX_SHELL > 0
+ return _POSIX_SHELL;
+#else
+ return -1;
+#endif
+
+ case _SC_SIGNALS:
+#ifdef _POSUX_SIGNALS
+ return _POSIX_SIGNALS;
+#else
+ return -1;
+#endif
+
+ case _SC_SPAWN:
+#if _POSIX_SPAWN > 0
+ return _POSIX_SPAWN;
+#else
+ return -1;
+#endif
+
+ case _SC_SPORADIC_SERVER:
+#if _POSIX_SPORADIC_SERVER > 0
+ return _POSIX_SPORADIC_SERVER;
+#else
+ return -1;
+#endif
+ case _SC_THREAD_SPORADIC_SERVER:
+#if _POSIX_THREAD_SPORADIC_SERVER > 0
+ return _POSIX_THREAD_SPORADIC_SERVER;
+#else
+ return -1;
+#endif
+
+ case _SC_SYSTEM_DATABASE:
+#if _POSIX_SYSTEM_DATABASE > 0
+ return _POSIX_SYSTEM_DATABASE;
+#else
+ return -1;
+#endif
+ case _SC_SYSTEM_DATABASE_R:
+#if _POSIX_SYSTEM_DATABASE_R > 0
+ return _POSIX_SYSTEM_DATABASE_R;
+#else
+ return -1;
+#endif
+
+ case _SC_THREAD_CPUTIME:
+#if _POSIX_THREAD_CPUTIME > 0
+ return _POSIX_THREAD_CPUTIME;
+#else
+ return -1;
+#endif
+
+ case _SC_TIMEOUTS:
+#if _POSIX_TIMEOUTS > 0
+ return _POSIX_TIMEOUTS;
+#else
+ return -1;
+#endif
+
+ case _SC_TYPED_MEMORY_OBJECTS:
+#if _POSIX_TYPED_MEMORY_OBJECTS > 0
+ return _POSIX_TYPED_MEMORY_OBJECTS;
+#else
+ return -1;
+#endif
+
+ case _SC_USER_GROUPS:
+#if _POSIX_USER_GROUPS > 0
+ return _POSIX_USER_GROUPS;
+#else
+ return -1;
+#endif
+ case _SC_USER_GROUPS_R:
+#if _POSIX_USER_GROUPS_R > 0
+ return _POSIX_USER_GROUPS_R;
+#else
+ return -1;
+#endif
+
+ case _SC_2_PBS:
+#ifdef _POSIX2_PBS
+ return _POSIX2_PBS;
+#else
+ return -1;
+#endif
+ case _SC_2_PBS_ACCOUNTING:
+#ifdef _POSIX2_PBS_ACCOUNTING
+ return _POSIX2_PBS_ACCOUNTING;
+#else
+ return -1;
+#endif
+ case _SC_2_PBS_CHECKPOINT:
+#ifdef _POSIX2_PBS_CHECKPOINT
+ return _POSIX2_PBS_CHECKPOINT;
+#else
+ return -1;
+#endif
+ case _SC_2_PBS_LOCATE:
+#ifdef _POSIX2_PBS_LOCATE
+ return _POSIX2_PBS_LOCATE;
+#else
+ return -1;
+#endif
+ case _SC_2_PBS_MESSAGE:
+#ifdef _POSIX2_PBS_MESSAGE
+ return _POSIX2_PBS_MESSAGE;
+#else
+ return -1;
+#endif
+ case _SC_2_PBS_TRACK:
+#ifdef _POSIX2_PBS_TRACK
+ return _POSIX2_PBS_TRACK;
+#else
+ return -1;
+#endif
+
+ case _SC_SYMLOOP_MAX:
+#ifdef SYMLOOP_MAX
+ return SYMLOOP_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_STREAMS:
+#ifdef _XOPEN_STREAMS
+ return _XOPEN_STREAMS;
+#else
+ return -1;
+#endif
+
+ case _SC_HOST_NAME_MAX:
+#ifdef HOST_NAME_MAX
+ return HOST_NAME_MAX;
+#else
+ return -1;
+#endif
+
+ case _SC_TRACE:
+#if _POSIX_TRACE > 0
+ return _POSIX_TRACE;
+#else
+ return -1;
+#endif
+ case _SC_TRACE_EVENT_FILTER:
+#if _POSIX_TRACE_EVENT_FILTER > 0
+ return _POSIX_TRACE_EVENT_FILTER;
+#else
+ return -1;
+#endif
+ case _SC_TRACE_INHERIT:
+#if _POSIX_TRACE_INHERIT > 0
+ return _POSIX_TRACE_INHERIT;
+#else
+ return -1;
+#endif
+ case _SC_TRACE_LOG:
+#if _POSIX_TRACE_LOG > 0
+ return _POSIX_TRACE_LOG;
+#else
+ return -1;
+#endif
+
+ case _SC_LEVEL1_ICACHE_SIZE:
+ case _SC_LEVEL1_ICACHE_ASSOC:
+ case _SC_LEVEL1_ICACHE_LINESIZE:
+ case _SC_LEVEL1_DCACHE_SIZE:
+ case _SC_LEVEL1_DCACHE_ASSOC:
+ case _SC_LEVEL1_DCACHE_LINESIZE:
+ case _SC_LEVEL2_CACHE_SIZE:
+ case _SC_LEVEL2_CACHE_ASSOC:
+ case _SC_LEVEL2_CACHE_LINESIZE:
+ case _SC_LEVEL3_CACHE_SIZE:
+ case _SC_LEVEL3_CACHE_ASSOC:
+ case _SC_LEVEL3_CACHE_LINESIZE:
+ case _SC_LEVEL4_CACHE_SIZE:
+ case _SC_LEVEL4_CACHE_ASSOC:
+ /* In general we cannot determine these values. Therefore we
+ return zero which indicates that no information is
+ available. */
+ return 0;
+
+ case _SC_IPV6:
+#if _POSIX_IPV6 > 0
+ return _POSIX_IPV6;
+#else
+ return -1;
+#endif
+
+ case _SC_RAW_SOCKETS:
+#if _POSIX_RAW_SOCKETS > 0
+ return _POSIX_RAW_SOCKETS;
+#else
+ return -1;
+#endif
+ }
+}
+
+#undef __sysconf
+weak_alias (__sysconf, sysconf)
+libc_hidden_def (__sysconf)
+
+#if NEED_CHECK_SPEC
+static long int
+__sysconf_check_spec (const char *spec)
+{
+ int save_errno = errno;
+
+ const char *getconf_dir = __secure_getenv ("GETCONF_DIR") ?: GETCONF_DIR;
+ size_t getconf_dirlen = strlen (getconf_dir);
+ size_t speclen = strlen (spec);
+
+ char name[getconf_dirlen + sizeof ("/POSIX_V6_") + speclen];
+ memcpy (mempcpy (mempcpy (name, getconf_dir, getconf_dirlen),
+ "/POSIX_V6_", sizeof ("/POSIX_V6_") - 1),
+ spec, speclen + 1);
+
+ struct stat64 st;
+ long int ret = __xstat64 (_STAT_VER, name, &st) >= 0 ? 1 : -1;
+
+ __set_errno (save_errno);
+ return ret;
+}
+#endif
diff --git a/libc/sysdeps/posix/system.c b/libc/sysdeps/posix/system.c
new file mode 100644
index 000000000..f63dde4da
--- /dev/null
+++ b/libc/sysdeps/posix/system.c
@@ -0,0 +1,212 @@
+/* Copyright (C) 1991-2000, 2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <bits/libc-lock.h>
+#include <sysdep-cancel.h>
+
+
+#define SHELL_PATH "/bin/sh" /* Path of the shell. */
+#define SHELL_NAME "sh" /* Name to give it. */
+
+
+#ifdef _LIBC_REENTRANT
+static struct sigaction intr, quit;
+static int sa_refcntr;
+__libc_lock_define_initialized (static, lock);
+
+# define DO_LOCK() __libc_lock_lock (lock)
+# define DO_UNLOCK() __libc_lock_unlock (lock)
+# define INIT_LOCK() ({ __libc_lock_init (lock); sa_refcntr = 0; })
+# define ADD_REF() sa_refcntr++
+# define SUB_REF() --sa_refcntr
+#else
+# define DO_LOCK()
+# define DO_UNLOCK()
+# define INIT_LOCK()
+# define ADD_REF() 0
+# define SUB_REF() 0
+#endif
+
+
+/* Execute LINE as a shell command, returning its status. */
+static int
+do_system (const char *line)
+{
+ int status, save;
+ pid_t pid;
+ struct sigaction sa;
+#ifndef _LIBC_REENTRANT
+ struct sigaction intr, quit;
+#endif
+ sigset_t omask;
+
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = 0;
+ __sigemptyset (&sa.sa_mask);
+
+ DO_LOCK ();
+ if (ADD_REF () == 0)
+ {
+ if (__sigaction (SIGINT, &sa, &intr) < 0)
+ {
+ SUB_REF ();
+ goto out;
+ }
+ if (__sigaction (SIGQUIT, &sa, &quit) < 0)
+ {
+ save = errno;
+ SUB_REF ();
+ goto out_restore_sigint;
+ }
+ }
+ DO_UNLOCK ();
+
+ /* We reuse the bitmap in the 'sa' structure. */
+ __sigaddset (&sa.sa_mask, SIGCHLD);
+ save = errno;
+ if (__sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0)
+ {
+#ifndef _LIBC
+ if (errno == ENOSYS)
+ __set_errno (save);
+ else
+#endif
+ {
+ DO_LOCK ();
+ if (SUB_REF () == 0)
+ {
+ save = errno;
+ (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
+ out_restore_sigint:
+ (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
+ __set_errno (save);
+ }
+ out:
+ DO_UNLOCK ();
+ return -1;
+ }
+ }
+
+#ifdef CLEANUP_HANDLER
+ CLEANUP_HANDLER;
+#endif
+
+#ifdef FORK
+ pid = FORK ();
+#else
+ pid = __fork ();
+#endif
+ if (pid == (pid_t) 0)
+ {
+ /* Child side. */
+ const char *new_argv[4];
+ new_argv[0] = SHELL_NAME;
+ new_argv[1] = "-c";
+ new_argv[2] = line;
+ new_argv[3] = NULL;
+
+ /* Restore the signals. */
+ (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
+ (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
+ (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
+ INIT_LOCK ();
+
+ /* Exec the shell. */
+ (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ);
+ _exit (127);
+ }
+ else if (pid < (pid_t) 0)
+ /* The fork failed. */
+ status = -1;
+ else
+ /* Parent side. */
+ {
+#ifdef NO_WAITPID
+ pid_t child;
+ do
+ {
+ child = __wait (&status);
+ if (child <= -1 && errno != EINTR)
+ {
+ status = -1;
+ break;
+ }
+ /* Note that pid cannot be <= -1 and therefore the loop continues
+ when __wait returned with EINTR. */
+ }
+ while (child != pid);
+#else
+ /* Note the system() is a cancellation point. But since we call
+ waitpid() which itself is a cancellation point we do not
+ have to do anything here. */
+ if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) != pid)
+ status = -1;
+#endif
+ }
+
+#ifdef CLEANUP_HANDLER
+ CLEANUP_RESET;
+#endif
+
+ save = errno;
+ DO_LOCK ();
+ if ((SUB_REF () == 0
+ && (__sigaction (SIGINT, &intr, (struct sigaction *) NULL)
+ | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0)
+ || __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0)
+ {
+#ifndef _LIBC
+ /* glibc cannot be used on systems without waitpid. */
+ if (errno == ENOSYS)
+ __set_errno (save);
+ else
+#endif
+ status = -1;
+ }
+ DO_UNLOCK ();
+
+ return status;
+}
+
+int
+__libc_system (const char *line)
+{
+ if (line == NULL)
+ /* Check that we have a command processor available. It might
+ not be available after a chroot(), for example. */
+ return do_system ("exit 0") == 0;
+
+ if (SINGLE_THREAD_P)
+ return do_system (line);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_system (line);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+weak_alias (__libc_system, system)
diff --git a/libc/sysdeps/posix/sysv_signal.c b/libc/sysdeps/posix/sysv_signal.c
new file mode 100644
index 000000000..16fcd2c2a
--- /dev/null
+++ b/libc/sysdeps/posix/sysv_signal.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 1991, 1992, 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h> /* For the real memset prototype. */
+
+
+/* Tolerate non-threads versions of Posix */
+#ifndef SA_ONESHOT
+#define SA_ONESHOT 0
+#endif
+#ifndef SA_NOMASK
+#define SA_NOMASK 0
+#endif
+#ifndef SA_INTERRUPT
+#define SA_INTERRUPT 0
+#endif
+
+/* Set the handler for the signal SIG to HANDLER,
+ returning the old handler, or SIG_ERR on error. */
+__sighandler_t
+__sysv_signal (sig, handler)
+ int sig;
+ __sighandler_t handler;
+{
+ struct sigaction act, oact;
+
+ /* Check signal extents to protect __sigismember. */
+ if (handler == SIG_ERR || sig < 1 || sig >= NSIG)
+ {
+ __set_errno (EINVAL);
+ return SIG_ERR;
+ }
+
+ act.sa_handler = handler;
+ if (__sigemptyset (&act.sa_mask) < 0)
+ return SIG_ERR;
+ act.sa_flags = SA_ONESHOT | SA_NOMASK | SA_INTERRUPT;
+ act.sa_flags &= ~SA_RESTART;
+ if (__sigaction (sig, &act, &oact) < 0)
+ return SIG_ERR;
+
+ return oact.sa_handler;
+}
+
+weak_alias (__sysv_signal, sysv_signal)
diff --git a/libc/sysdeps/posix/tempname.c b/libc/sysdeps/posix/tempname.c
new file mode 100644
index 000000000..c8973a085
--- /dev/null
+++ b/libc/sysdeps/posix/tempname.c
@@ -0,0 +1,346 @@
+/* Copyright (C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <assert.h>
+
+#include <errno.h>
+#ifndef __set_errno
+# define __set_errno(Val) errno = (Val)
+#endif
+
+#include <stdio.h>
+#ifndef P_tmpdir
+# define P_tmpdir "/tmp"
+#endif
+#ifndef TMP_MAX
+# define TMP_MAX 238328
+#endif
+#ifndef __GT_FILE
+# define __GT_FILE 0
+# define __GT_BIGFILE 1
+# define __GT_DIR 2
+# define __GT_NOCREATE 3
+#endif
+
+#if STDC_HEADERS || _LIBC
+# include <stddef.h>
+# include <stdlib.h>
+# include <string.h>
+#endif
+
+#if HAVE_FCNTL_H || _LIBC
+# include <fcntl.h>
+#endif
+
+#if HAVE_SYS_TIME_H || _LIBC
+# include <sys/time.h>
+#endif
+
+#if HAVE_STDINT_H || _LIBC
+# include <stdint.h>
+#endif
+
+#if HAVE_UNISTD_H || _LIBC
+# include <unistd.h>
+#endif
+
+#include <sys/stat.h>
+#if STAT_MACROS_BROKEN
+# undef S_ISDIR
+#endif
+#if !defined S_ISDIR && defined S_IFDIR
+# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#endif
+#if !S_IRUSR && S_IREAD
+# define S_IRUSR S_IREAD
+#endif
+#if !S_IRUSR
+# define S_IRUSR 00400
+#endif
+#if !S_IWUSR && S_IWRITE
+# define S_IWUSR S_IWRITE
+#endif
+#if !S_IWUSR
+# define S_IWUSR 00200
+#endif
+#if !S_IXUSR && S_IEXEC
+# define S_IXUSR S_IEXEC
+#endif
+#if !S_IXUSR
+# define S_IXUSR 00100
+#endif
+
+#if _LIBC
+# define struct_stat64 struct stat64
+#else
+# define struct_stat64 struct stat
+# define __getpid getpid
+# define __gettimeofday gettimeofday
+# define __mkdir mkdir
+# define __open open
+# define __open64 open
+# define __lxstat64(version, path, buf) lstat (path, buf)
+# define __xstat64(version, path, buf) stat (path, buf)
+#endif
+
+#if ! (HAVE___SECURE_GETENV || _LIBC)
+# define __secure_getenv getenv
+#endif
+
+#ifdef _LIBC
+# include <hp-timing.h>
+# if HP_TIMING_AVAIL
+# define RANDOM_BITS(Var) \
+ if (__builtin_expect (value == UINT64_C (0), 0)) \
+ { \
+ /* If this is the first time this function is used initialize \
+ the variable we accumulate the value in to some somewhat \
+ random value. If we'd not do this programs at startup time \
+ might have a reduced set of possible names, at least on slow \
+ machines. */ \
+ struct timeval tv; \
+ __gettimeofday (&tv, NULL); \
+ value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \
+ } \
+ HP_TIMING_NOW (Var)
+# endif
+#endif
+
+/* Use the widest available unsigned type if uint64_t is not
+ available. The algorithm below extracts a number less than 62**6
+ (approximately 2**35.725) from uint64_t, so ancient hosts where
+ uintmax_t is only 32 bits lose about 3.725 bits of randomness,
+ which is better than not having mkstemp at all. */
+#if !defined UINT64_MAX && !defined uint64_t
+# define uint64_t uintmax_t
+#endif
+
+/* Return nonzero if DIR is an existent directory. */
+static int
+direxists (const char *dir)
+{
+ struct_stat64 buf;
+ return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode);
+}
+
+/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is
+ non-null and exists, uses it; otherwise uses the first of $TMPDIR,
+ P_tmpdir, /tmp that exists. Copies into TMPL a template suitable
+ for use with mk[s]temp. Will fail (-1) if DIR is non-null and
+ doesn't exist, none of the searched dirs exists, or there's not
+ enough space in TMPL. */
+int
+__path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
+ int try_tmpdir)
+{
+ const char *d;
+ size_t dlen, plen;
+
+ if (!pfx || !pfx[0])
+ {
+ pfx = "file";
+ plen = 4;
+ }
+ else
+ {
+ plen = strlen (pfx);
+ if (plen > 5)
+ plen = 5;
+ }
+
+ if (try_tmpdir)
+ {
+ d = __secure_getenv ("TMPDIR");
+ if (d != NULL && direxists (d))
+ dir = d;
+ else if (dir != NULL && direxists (dir))
+ /* nothing */ ;
+ else
+ dir = NULL;
+ }
+ if (dir == NULL)
+ {
+ if (direxists (P_tmpdir))
+ dir = P_tmpdir;
+ else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
+ dir = "/tmp";
+ else
+ {
+ __set_errno (ENOENT);
+ return -1;
+ }
+ }
+
+ dlen = strlen (dir);
+ while (dlen > 1 && dir[dlen - 1] == '/')
+ dlen--; /* remove trailing slashes */
+
+ /* check we have room for "${dir}/${pfx}XXXXXX\0" */
+ if (tmpl_len < dlen + 1 + plen + 6 + 1)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx);
+ return 0;
+}
+
+/* These are the characters used in temporary filenames. */
+static const char letters[] =
+"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+/* Generate a temporary file name based on TMPL. TMPL must match the
+ rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
+ does not exist at the time of the call to __gen_tempname. TMPL is
+ overwritten with the result.
+
+ KIND may be one of:
+ __GT_NOCREATE: simply verify that the name does not exist
+ at the time of the call.
+ __GT_FILE: create the file using open(O_CREAT|O_EXCL)
+ and return a read-write fd. The file is mode 0600.
+ __GT_BIGFILE: same as __GT_FILE but use open64().
+ __GT_DIR: create a directory, which will be mode 0700.
+
+ We use a clever algorithm to get hard-to-predict names. */
+int
+__gen_tempname (char *tmpl, int kind)
+{
+ int len;
+ char *XXXXXX;
+ static uint64_t value;
+ uint64_t random_time_bits;
+ unsigned int count;
+ int fd = -1;
+ int save_errno = errno;
+ struct_stat64 st;
+
+ /* A lower bound on the number of temporary files to attempt to
+ generate. The maximum total number of temporary file names that
+ can exist for a given template is 62**6. It should never be
+ necessary to try all these combinations. Instead if a reasonable
+ number of names is tried (we define reasonable as 62**3) fail to
+ give the system administrator the chance to remove the problems. */
+#define ATTEMPTS_MIN (62 * 62 * 62)
+
+ /* The number of times to attempt to generate a temporary file. To
+ conform to POSIX, this must be no smaller than TMP_MAX. */
+#if ATTEMPTS_MIN < TMP_MAX
+ unsigned int attempts = TMP_MAX;
+#else
+ unsigned int attempts = ATTEMPTS_MIN;
+#endif
+
+ len = strlen (tmpl);
+ if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* This is where the Xs start. */
+ XXXXXX = &tmpl[len - 6];
+
+ /* Get some more or less random data. */
+#ifdef RANDOM_BITS
+ RANDOM_BITS (random_time_bits);
+#else
+# if HAVE_GETTIMEOFDAY || _LIBC
+ {
+ struct timeval tv;
+ __gettimeofday (&tv, NULL);
+ random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
+ }
+# else
+ random_time_bits = time (NULL);
+# endif
+#endif
+ value += random_time_bits ^ __getpid ();
+
+ for (count = 0; count < attempts; value += 7777, ++count)
+ {
+ uint64_t v = value;
+
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+ switch (kind)
+ {
+ case __GT_FILE:
+ fd = __open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ break;
+
+ case __GT_BIGFILE:
+ fd = __open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ break;
+
+ case __GT_DIR:
+ fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
+ break;
+
+ case __GT_NOCREATE:
+ /* This case is backward from the other three. __gen_tempname
+ succeeds if __xstat fails because the name does not exist.
+ Note the continue to bypass the common logic at the bottom
+ of the loop. */
+ if (__lxstat64 (_STAT_VER, tmpl, &st) < 0)
+ {
+ if (errno == ENOENT)
+ {
+ __set_errno (save_errno);
+ return 0;
+ }
+ else
+ /* Give up now. */
+ return -1;
+ }
+ continue;
+
+ default:
+ assert (! "invalid KIND in __gen_tempname");
+ }
+
+ if (fd >= 0)
+ {
+ __set_errno (save_errno);
+ return fd;
+ }
+ else if (errno != EEXIST)
+ return -1;
+ }
+
+ /* We got out of the loop because we ran out of combinations to try. */
+ __set_errno (EEXIST);
+ return -1;
+}
diff --git a/libc/sysdeps/posix/truncate.c b/libc/sysdeps/posix/truncate.c
new file mode 100644
index 000000000..3fff487f2
--- /dev/null
+++ b/libc/sysdeps/posix/truncate.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/* Truncate PATH to LENGTH bytes. */
+int
+truncate (path, length)
+ const char *path;
+ off_t length;
+{
+ int fd, ret, save;
+
+ fd = open (path, O_WRONLY);
+ if (fd < 0)
+ return -1;
+
+ ret = ftruncate (fd, length);
+ save = errno;
+ (void) close (fd);
+ if (ret < 0)
+ __set_errno (save);
+ return ret;
+}
diff --git a/libc/sysdeps/posix/ttyname.c b/libc/sysdeps/posix/ttyname.c
new file mode 100644
index 000000000..b7a5d8566
--- /dev/null
+++ b/libc/sysdeps/posix/ttyname.c
@@ -0,0 +1,136 @@
+/* Copyright (C) 1991,92,93,96,97,98,2000,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+char *__ttyname;
+
+static char *getttyname (int fd, dev_t mydev, ino_t myino,
+ int save, int *dostat) internal_function;
+
+
+libc_freeres_ptr (static char *getttyname_name);
+
+static char *
+internal_function
+getttyname (fd, mydev, myino, save, dostat)
+ int fd;
+ dev_t mydev;
+ ino_t myino;
+ int save;
+ int *dostat;
+{
+ static const char dev[] = "/dev";
+ static size_t namelen;
+ struct stat st;
+ DIR *dirstream;
+ struct dirent *d;
+
+ dirstream = __opendir (dev);
+ if (dirstream == NULL)
+ {
+ *dostat = -1;
+ return NULL;
+ }
+
+ while ((d = __readdir (dirstream)) != NULL)
+ if (((ino_t) d->d_fileno == myino || *dostat)
+ && strcmp (d->d_name, "stdin")
+ && strcmp (d->d_name, "stdout")
+ && strcmp (d->d_name, "stderr"))
+ {
+ size_t dlen = _D_ALLOC_NAMLEN (d);
+ if (sizeof (dev) + dlen > namelen)
+ {
+ free (getttyname_name);
+ namelen = 2 * (sizeof (dev) + dlen); /* Big enough. */
+ getttyname_name = malloc (namelen);
+ if (! getttyname_name)
+ {
+ *dostat = -1;
+ /* Perhaps it helps to free the directory stream buffer. */
+ (void) __closedir (dirstream);
+ return NULL;
+ }
+ *((char *) __mempcpy (getttyname_name, dev, sizeof (dev) - 1))
+ = '/';
+ }
+ (void) __mempcpy (&getttyname_name[sizeof (dev)], d->d_name, dlen);
+ if (stat (getttyname_name, &st) == 0
+#ifdef _STATBUF_ST_RDEV
+ && S_ISCHR (st.st_mode) && st.st_rdev == mydev
+#else
+ && (ino_t) d->d_fileno == myino && st.st_dev == mydev
+#endif
+ )
+ {
+ (void) __closedir (dirstream);
+ __ttyname = getttyname_name;
+ __set_errno (save);
+ return getttyname_name;
+ }
+ }
+
+ (void) __closedir (dirstream);
+ __set_errno (save);
+ return NULL;
+}
+
+/* Return the pathname of the terminal FD is open on, or NULL on errors.
+ The returned storage is good only until the next call to this function. */
+char *
+ttyname (fd)
+ int fd;
+{
+ struct stat st;
+ int dostat = 0;
+ char *name;
+ int save = errno;
+
+ if (!__isatty (fd))
+ return NULL;
+
+ if (fstat (fd, &st) < 0)
+ return NULL;
+
+#ifdef _STATBUF_ST_RDEV
+ name = getttyname (fd, st.st_rdev, st.st_ino, save, &dostat);
+#else
+ name = getttyname (fd, st.st_dev, st.st_ino, save, &dostat);
+#endif
+
+ if (!name && dostat != -1)
+ {
+ dostat = 1;
+#ifdef _STATBUF_ST_RDEV
+ name = getttyname (fd, st.st_rdev, st.st_ino, save, &dostat);
+#else
+ name = getttyname (fd, st.st_dev, st.st_ino, save, &dostat);
+#endif
+ }
+
+ return name;
+}
diff --git a/libc/sysdeps/posix/ttyname_r.c b/libc/sysdeps/posix/ttyname_r.c
new file mode 100644
index 000000000..37916de26
--- /dev/null
+++ b/libc/sysdeps/posix/ttyname_r.c
@@ -0,0 +1,166 @@
+/* Copyright (C) 1991,92,93,95,96,97,98,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+static const char dev[] = "/dev";
+
+static int getttyname_r (int fd, char *buf, size_t buflen,
+ dev_t mydev, ino_t myino, int save,
+ int *dostat) __THROW internal_function;
+
+static int
+internal_function
+getttyname_r (fd, buf, buflen, mydev, myino, save, dostat)
+ int fd;
+ char *buf;
+ size_t buflen;
+ dev_t mydev;
+ ino_t myino;
+ int save;
+ int *dostat;
+{
+ struct stat st;
+ DIR *dirstream;
+ struct dirent *d;
+
+ dirstream = __opendir (dev);
+ if (dirstream == NULL)
+ {
+ *dostat = -1;
+ return errno;
+ }
+
+ while ((d = __readdir (dirstream)) != NULL)
+ if (((ino_t) d->d_fileno == myino || *dostat)
+ && strcmp (d->d_name, "stdin")
+ && strcmp (d->d_name, "stdout")
+ && strcmp (d->d_name, "stderr"))
+ {
+ char *cp;
+ size_t needed = _D_EXACT_NAMLEN (d) + 1;
+
+ if (needed > buflen)
+ {
+ *dostat = -1;
+ (void) __closedir (dirstream);
+ __set_errno (ERANGE);
+ return ERANGE;
+ }
+
+ cp = __stpncpy (&buf[sizeof (dev)], d->d_name, needed);
+ cp[0] = '\0';
+
+ if (stat (buf, &st) == 0
+#ifdef _STATBUF_ST_RDEV
+ && S_ISCHR (st.st_mode) && st.st_rdev == mydev
+#else
+ && (ino_t) d->d_fileno == myino && st.st_dev == mydev
+#endif
+ )
+ {
+ (void) __closedir (dirstream);
+ __set_errno (save);
+ return 0;
+ }
+ }
+
+ (void) __closedir (dirstream);
+ __set_errno (save);
+ /* It is not clear what to return in this case. `isatty' says FD
+ refers to a TTY but no entry in /dev has this inode. */
+ return ENOTTY;
+}
+
+/* Store at most BUFLEN character of the pathname of the terminal FD is
+ open on in BUF. Return 0 on success, otherwise an error number. */
+int
+__ttyname_r (fd, buf, buflen)
+ int fd;
+ char *buf;
+ size_t buflen;
+{
+ struct stat st;
+ int dostat = 0;
+ int save = errno;
+ int ret;
+
+ /* Test for the absolute minimal size. This makes life easier inside
+ the loop. */
+ if (!buf)
+ {
+ __set_errno (EINVAL);
+ return EINVAL;
+ }
+
+ if (buflen < (int) (sizeof (dev) + 1))
+ {
+ __set_errno (ERANGE);
+ return ERANGE;
+ }
+
+ if (!__isatty (fd))
+ {
+ __set_errno (ENOTTY);
+ return ENOTTY;
+ }
+
+ if (fstat (fd, &st) < 0)
+ return errno;
+
+ /* Prepare the result buffer. */
+ memcpy (buf, dev, sizeof (dev) - 1);
+ buf[sizeof (dev) - 1] = '/';
+ buflen -= sizeof (dev);
+
+#ifdef _STATBUF_ST_RDEV
+ ret = getttyname_r (fd, buf, buflen, st.st_rdev, st.st_ino, save,
+ &dostat);
+#else
+ ret = getttyname_r (fd, buf, buflen, st.st_dev, st.st_ino, save,
+ &dostat);
+#endif
+
+ if (ret && dostat != -1)
+ {
+ dostat = 1;
+#ifdef _STATBUF_ST_RDEV
+ ret = getttyname_r (fd, buf, buflen, st.st_rdev, st.st_ino,
+ save, &dostat);
+#else
+ ret = getttyname_r (fd, buf, buflen, st.st_dev, st.st_ino,
+ save, &dostat);
+#endif
+ }
+
+ return ret;
+}
+
+weak_alias (__ttyname_r, ttyname_r)
diff --git a/libc/sysdeps/posix/utimes.c b/libc/sysdeps/posix/utimes.c
new file mode 100644
index 000000000..d0381a5b6
--- /dev/null
+++ b/libc/sysdeps/posix/utimes.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1995, 1997, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <utime.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <stddef.h>
+
+/* Change the access time of FILE to TVP[0] and
+ the modification time of FILE to TVP[1]. */
+int
+__utimes (const char *file, const struct timeval tvp[2])
+{
+ struct utimbuf buf, *times;
+
+ if (tvp)
+ {
+ times = &buf;
+ buf.actime = tvp[0].tv_sec + tvp[0].tv_usec / 1000000;
+ buf.modtime = tvp[1].tv_sec + tvp[1].tv_usec / 1000000;
+ }
+ else
+ times = NULL;
+
+ return utime (file, times);
+}
+
+weak_alias (__utimes, utimes)
diff --git a/libc/sysdeps/posix/wait.c b/libc/sysdeps/posix/wait.c
new file mode 100644
index 000000000..225661a98
--- /dev/null
+++ b/libc/sysdeps/posix/wait.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/wait.h>
+
+
+/* Wait for a child to die. When one does, put its status in *STAT_LOC
+ and return its process ID. For errors, return (pid_t) -1. */
+__pid_t
+__libc_wait (__WAIT_STATUS_DEFN stat_loc)
+{
+ return __waitpid (WAIT_ANY, (int *) stat_loc, 0);
+}
+
+weak_alias (__libc_wait, __wait)
+weak_alias (__libc_wait, wait)
diff --git a/libc/sysdeps/posix/wait3.c b/libc/sysdeps/posix/wait3.c
new file mode 100644
index 000000000..64c00bb27
--- /dev/null
+++ b/libc/sysdeps/posix/wait3.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1992, 93, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <stddef.h>
+
+/* Wait for a child to exit. When one does, put its status in *STAT_LOC and
+ return its process ID. For errors return (pid_t) -1. If USAGE is not nil,
+ store information about the child's resource usage (as a `struct rusage')
+ there. If the WUNTRACED bit is set in OPTIONS, return status for stopped
+ children; otherwise don't. */
+pid_t
+__wait3 (__WAIT_STATUS stat_loc, int options, struct rusage *usage)
+{
+ if (usage != NULL)
+ {
+ __set_errno (ENOSYS);
+ return (pid_t) -1;
+ }
+ return __waitpid (WAIT_ANY, stat_loc.__iptr, options);
+}
+
+weak_alias (__wait3, wait3)
diff --git a/libc/sysdeps/posix/waitid.c b/libc/sysdeps/posix/waitid.c
new file mode 100644
index 000000000..7d65e42fd
--- /dev/null
+++ b/libc/sysdeps/posix/waitid.c
@@ -0,0 +1,171 @@
+/* Pseudo implementation of waitid.
+ Copyright (C) 1997, 1998, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#define __need_NULL
+#include <stddef.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sysdep-cancel.h>
+
+
+#ifdef DO_WAITID
+# define OUR_WAITID DO_WAITID
+#elif !defined NO_DO_WAITID
+# define OUR_WAITID do_waitid
+#endif
+
+#ifdef OUR_WAITID
+static int
+OUR_WAITID (idtype_t idtype, id_t id, siginfo_t *infop, int options)
+{
+ pid_t pid, child;
+ int status;
+
+ switch (idtype)
+ {
+ case P_PID:
+ if(id <= 0)
+ goto invalid;
+ pid = (pid_t) id;
+ break;
+ case P_PGID:
+ if (id < 0 || id == 1)
+ goto invalid;
+ pid = (pid_t) -id;
+ break;
+ case P_ALL:
+ pid = -1;
+ break;
+ default:
+ invalid:
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* Technically we're supposed to return EFAULT if infop is bogus,
+ but that would involve mucking with signals, which is
+ too much hassle. User will have to deal with SIGSEGV/SIGBUS.
+ We just check for a null pointer. */
+
+ if (infop == NULL)
+ {
+ __set_errno (EFAULT);
+ return -1;
+ }
+
+ /* This emulation using waitpid cannot support the waitid modes in which
+ we do not reap the child, or match only stopped and not dead children. */
+ if (0
+#ifdef WNOWAIT
+ || (options & WNOWAIT)
+#endif
+#ifdef WEXITED
+ || ((options & (WEXITED|WSTOPPED|WCONTINUED))
+ != (WEXITED | (options & WUNTRACED)))
+#endif
+ )
+ {
+ __set_errno (ENOTSUP);
+ return -1;
+ }
+
+ /* Note the waitid() is a cancellation point. But since we call
+ waitpid() which itself is a cancellation point we do not have
+ to do anything here. */
+ child = __waitpid (pid, &status,
+ options
+#ifdef WEXITED
+ &~ WEXITED
+#endif
+ );
+
+ if (child == -1)
+ /* `waitpid' set `errno' for us. */
+ return -1;
+
+ if (child == 0)
+ {
+ /* The WHOHANG bit in OPTIONS is set and there are children available
+ but none has a status for us. The XPG docs do not mention this
+ case so we clear the `siginfo_t' struct and return successfully. */
+ infop->si_signo = 0;
+ infop->si_code = 0;
+ return 0;
+ }
+
+ /* Decode the status field and set infop members... */
+ infop->si_signo = SIGCHLD;
+ infop->si_pid = child;
+ infop->si_errno = 0;
+
+ if (WIFEXITED (status))
+ {
+ infop->si_code = CLD_EXITED;
+ infop->si_status = WEXITSTATUS (status);
+ }
+ else if (WIFSIGNALED (status))
+ {
+ infop->si_code = WCOREDUMP (status) ? CLD_DUMPED : CLD_KILLED;
+ infop->si_status = WTERMSIG (status);
+ }
+ else if (WIFSTOPPED (status))
+ {
+ infop->si_code = CLD_STOPPED;
+ infop->si_status = WSTOPSIG (status);
+ }
+#ifdef WIFCONTINUED
+ else if (WIFCONTINUED (status))
+ {
+ infop->si_code = CLD_CONTINUED;
+ infop->si_status = SIGCONT;
+ }
+#endif
+ else
+ /* Can't happen. */
+ assert (! "What?");
+
+ return 0;
+}
+#endif
+
+
+int
+__waitid (idtype, id, infop, options)
+ idtype_t idtype;
+ id_t id;
+ siginfo_t *infop;
+ int options;
+{
+ if (SINGLE_THREAD_P)
+ return do_waitid (idtype, id, infop, options);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_waitid (idtype, id, infop, options);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+weak_alias (__waitid, waitid)
+strong_alias (__waitid, __libc_waitid)
diff --git a/libc/sysdeps/posix/writev.c b/libc/sysdeps/posix/writev.c
new file mode 100644
index 000000000..a347cc2ea
--- /dev/null
+++ b/libc/sysdeps/posix/writev.c
@@ -0,0 +1,97 @@
+/* Copyright (C) 1991, 1992, 1996, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <sys/param.h>
+#include <sys/uio.h>
+#include <errno.h>
+
+/* Write data pointed by the buffers described by VECTOR, which
+ is a vector of COUNT `struct iovec's, to file descriptor FD.
+ The data is written in the order specified.
+ Operates just like `write' (see <unistd.h>) except that the data
+ are taken from VECTOR instead of a contiguous buffer. */
+ssize_t
+__libc_writev (int fd, const struct iovec *vector, int count)
+{
+ char *buffer;
+ register char *bp;
+ size_t bytes, to_copy;
+ ssize_t bytes_written;
+ int i;
+ bool use_malloc = false;
+
+ /* Find the total number of bytes to be written. */
+ bytes = 0;
+ for (i = 0; i < count; ++i)
+ {
+ /* Check for ssize_t overflow. */
+ if (SSIZE_MAX - bytes < vector[i].iov_len)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ bytes += vector[i].iov_len;
+ }
+
+ /* Allocate a temporary buffer to hold the data. We should normally
+ use alloca since it's faster and does not require synchronization
+ with other threads. But we cannot if the amount of memory
+ required is too large. */
+ if (__libc_use_alloca (bytes))
+ buffer = (char *) __alloca (bytes);
+ else
+ {
+ buffer = (char *) malloc (bytes);
+ if (buffer == NULL)
+ /* XXX I don't know whether it is acceptable to try writing
+ the data in chunks. Probably not so we just fail here. */
+ return -1;
+
+ use_malloc = true;
+ }
+
+ /* Copy the data into BUFFER. */
+ to_copy = bytes;
+ bp = buffer;
+ for (i = 0; i < count; ++i)
+ {
+ size_t copy = MIN (vector[i].iov_len, to_copy);
+
+ bp = __mempcpy ((void *) bp, (void *) vector[i].iov_base, copy);
+
+ to_copy -= copy;
+ if (to_copy == 0)
+ break;
+ }
+
+ bytes_written = __write (fd, buffer, bytes);
+
+ if (use_malloc)
+ free (buffer);
+
+ return bytes_written;
+}
+#ifndef __libc_writev
+strong_alias (__libc_writev, __writev)
+weak_alias (__libc_writev, writev)
+#endif
diff --git a/libc/sysdeps/powerpc/Implies b/libc/sysdeps/powerpc/Implies
new file mode 100644
index 000000000..7ccf9a7c4
--- /dev/null
+++ b/libc/sysdeps/powerpc/Implies
@@ -0,0 +1,4 @@
+# On PowerPC we use the IBM extended long double format.
+ieee754/ldbl-128ibm
+ieee754/dbl-64
+ieee754/flt-32
diff --git a/libc/sysdeps/powerpc/Makefile b/libc/sysdeps/powerpc/Makefile
new file mode 100644
index 000000000..616458f13
--- /dev/null
+++ b/libc/sysdeps/powerpc/Makefile
@@ -0,0 +1,30 @@
+# We always want to use the new mnemonic syntax even if we are on a RS6000
+# machine.
++cflags += -mnew-mnemonics
+
+ifeq ($(subdir),gmon)
+sysdep_routines += ppc-mcount
+endif
+
+ifeq ($(subdir),string)
+CFLAGS-memcmp.c += -Wno-uninitialized
+endif
+
+ifeq ($(subdir),elf)
+# extra shared linker files to link into dl-allobjs.so and libc
+sysdep-dl-routines += dl-machine
+sysdep_routines += dl-machine
+# extra shared linker files to link only into dl-allobjs.so
+sysdep-rtld-routines += dl-machine
+endif
+
+ifeq ($(subdir),setjmp)
+ifeq (yes,$(build-shared))
+sysdep_routines += novmx-longjmp novmx-sigjmp
+endif
+endif
+
+ifeq ($(subdir),csu)
+# get offset to rtld_global._dl_hwcap
+gen-as-const-headers += rtld-global-offsets.sym
+endif
diff --git a/libc/sysdeps/powerpc/Versions b/libc/sysdeps/powerpc/Versions
new file mode 100644
index 000000000..47c2c3e6e
--- /dev/null
+++ b/libc/sysdeps/powerpc/Versions
@@ -0,0 +1,17 @@
+libm {
+ GLIBC_2.1 {
+ # symbols used in macros from sysdeps/powerpc/bits/fenv.h
+ __fe_dfl_env; __fe_enabled_env; __fe_nonieee_env; __fe_nomask_env;
+ }
+}
+
+libc {
+ GLIBC_2.3.4 {
+ _longjmp; __sigsetjmp; _setjmp;
+ longjmp; setjmp;
+ }
+ GLIBC_PRIVATE {
+ __novmx__libc_longjmp; __novmx__libc_siglongjmp;
+ __vmx__libc_longjmp; __vmx__libc_siglongjmp;
+ }
+}
diff --git a/libc/sysdeps/powerpc/abort-instr.h b/libc/sysdeps/powerpc/abort-instr.h
new file mode 100644
index 000000000..43746e65b
--- /dev/null
+++ b/libc/sysdeps/powerpc/abort-instr.h
@@ -0,0 +1,2 @@
+/* An op-code of 0 is guaranteed to be illegal. */
+#define ABORT_INSTRUCTION asm (".long 0")
diff --git a/libc/sysdeps/powerpc/bits/atomic.h b/libc/sysdeps/powerpc/bits/atomic.h
new file mode 100644
index 000000000..31f27e9e1
--- /dev/null
+++ b/libc/sysdeps/powerpc/bits/atomic.h
@@ -0,0 +1,290 @@
+/* Atomic operations. PowerPC Common version.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * Never include sysdeps/powerpc/bits/atomic.h directly.
+ * Alway use include/atomic.h which will include either
+ * sysdeps/powerpc/powerpc32/bits/atomic.h
+ * or
+ * sysdeps/powerpc/powerpc64/bits/atomic.h
+ * as appropriate and which in turn include this file.
+ */
+
+#include <stdint.h>
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+/*
+ * Powerpc does not have byte and halfword forms of load and reserve and
+ * store conditional. So for powerpc we stub out the 8- and 16-bit forms.
+ */
+#define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \
+ (abort (), 0)
+
+#define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval) \
+ (abort (), 0)
+
+#define __arch_compare_and_exchange_bool_8_rel(mem, newval, oldval) \
+ (abort (), 0)
+
+#define __arch_compare_and_exchange_bool_16_rel(mem, newval, oldval) \
+ (abort (), 0)
+
+#ifdef UP
+# define __ARCH_ACQ_INSTR ""
+# define __ARCH_REL_INSTR ""
+#else
+# define __ARCH_ACQ_INSTR "isync"
+# ifndef __ARCH_REL_INSTR
+# define __ARCH_REL_INSTR "sync"
+# endif
+#endif
+
+#define atomic_full_barrier() __asm ("sync" ::: "memory")
+#define atomic_write_barrier() __asm ("eieio" ::: "memory")
+
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ ({ \
+ __typeof (*(mem)) __tmp; \
+ __typeof (mem) __memp = (mem); \
+ __asm __volatile ( \
+ "1: lwarx %0,0,%1\n" \
+ " cmpw %0,%2\n" \
+ " bne 2f\n" \
+ " stwcx. %3,0,%1\n" \
+ " bne- 1b\n" \
+ "2: " __ARCH_ACQ_INSTR \
+ : "=&r" (__tmp) \
+ : "b" (__memp), "r" (oldval), "r" (newval) \
+ : "cr0", "memory"); \
+ __tmp; \
+ })
+
+#define __arch_compare_and_exchange_val_32_rel(mem, newval, oldval) \
+ ({ \
+ __typeof (*(mem)) __tmp; \
+ __typeof (mem) __memp = (mem); \
+ __asm __volatile (__ARCH_REL_INSTR "\n" \
+ "1: lwarx %0,0,%1\n" \
+ " cmpw %0,%2\n" \
+ " bne 2f\n" \
+ " stwcx. %3,0,%1\n" \
+ " bne- 1b\n" \
+ "2: " \
+ : "=&r" (__tmp) \
+ : "b" (__memp), "r" (oldval), "r" (newval) \
+ : "cr0", "memory"); \
+ __tmp; \
+ })
+
+#define __arch_atomic_exchange_32_acq(mem, value) \
+ ({ \
+ __typeof (*mem) __val; \
+ __asm __volatile ( \
+ "1: lwarx %0,0,%2\n" \
+ " stwcx. %3,0,%2\n" \
+ " bne- 1b\n" \
+ " " __ARCH_ACQ_INSTR \
+ : "=&r" (__val), "=m" (*mem) \
+ : "b" (mem), "r" (value), "m" (*mem) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+#define __arch_atomic_exchange_32_rel(mem, value) \
+ ({ \
+ __typeof (*mem) __val; \
+ __asm __volatile (__ARCH_REL_INSTR "\n" \
+ "1: lwarx %0,0,%2\n" \
+ " stwcx. %3,0,%2\n" \
+ " bne- 1b" \
+ : "=&r" (__val), "=m" (*mem) \
+ : "b" (mem), "r" (value), "m" (*mem) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+#define __arch_atomic_exchange_and_add_32(mem, value) \
+ ({ \
+ __typeof (*mem) __val, __tmp; \
+ __asm __volatile ("1: lwarx %0,0,%3\n" \
+ " add %1,%0,%4\n" \
+ " stwcx. %1,0,%3\n" \
+ " bne- 1b" \
+ : "=&b" (__val), "=&r" (__tmp), "=m" (*mem) \
+ : "b" (mem), "r" (value), "m" (*mem) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+#define __arch_atomic_increment_val_32(mem) \
+ ({ \
+ __typeof (*(mem)) __val; \
+ __asm __volatile ("1: lwarx %0,0,%2\n" \
+ " addi %0,%0,1\n" \
+ " stwcx. %0,0,%2\n" \
+ " bne- 1b" \
+ : "=&b" (__val), "=m" (*mem) \
+ : "b" (mem), "m" (*mem) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+#define __arch_atomic_decrement_val_32(mem) \
+ ({ \
+ __typeof (*(mem)) __val; \
+ __asm __volatile ("1: lwarx %0,0,%2\n" \
+ " subi %0,%0,1\n" \
+ " stwcx. %0,0,%2\n" \
+ " bne- 1b" \
+ : "=&b" (__val), "=m" (*mem) \
+ : "b" (mem), "m" (*mem) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+#define __arch_atomic_decrement_if_positive_32(mem) \
+ ({ int __val, __tmp; \
+ __asm __volatile ("1: lwarx %0,0,%3\n" \
+ " cmpwi 0,%0,0\n" \
+ " addi %1,%0,-1\n" \
+ " ble 2f\n" \
+ " stwcx. %1,0,%3\n" \
+ " bne- 1b\n" \
+ "2: " __ARCH_ACQ_INSTR \
+ : "=&b" (__val), "=&r" (__tmp), "=m" (*mem) \
+ : "b" (mem), "m" (*mem) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
+ ({ \
+ __typeof (*(mem)) __result; \
+ if (sizeof (*mem) == 4) \
+ __result = __arch_compare_and_exchange_val_32_acq(mem, newval, oldval); \
+ else if (sizeof (*mem) == 8) \
+ __result = __arch_compare_and_exchange_val_64_acq(mem, newval, oldval); \
+ else \
+ abort (); \
+ __result; \
+ })
+
+#define atomic_compare_and_exchange_val_rel(mem, newval, oldval) \
+ ({ \
+ __typeof (*(mem)) __result; \
+ if (sizeof (*mem) == 4) \
+ __result = __arch_compare_and_exchange_val_32_rel(mem, newval, oldval); \
+ else if (sizeof (*mem) == 8) \
+ __result = __arch_compare_and_exchange_val_64_rel(mem, newval, oldval); \
+ else \
+ abort (); \
+ __result; \
+ })
+
+#define atomic_exchange_acq(mem, value) \
+ ({ \
+ __typeof (*(mem)) __result; \
+ if (sizeof (*mem) == 4) \
+ __result = __arch_atomic_exchange_32_acq (mem, value); \
+ else if (sizeof (*mem) == 8) \
+ __result = __arch_atomic_exchange_64_acq (mem, value); \
+ else \
+ abort (); \
+ __result; \
+ })
+
+#define atomic_exchange_rel(mem, value) \
+ ({ \
+ __typeof (*(mem)) __result; \
+ if (sizeof (*mem) == 4) \
+ __result = __arch_atomic_exchange_32_rel (mem, value); \
+ else if (sizeof (*mem) == 8) \
+ __result = __arch_atomic_exchange_64_rel (mem, value); \
+ else \
+ abort (); \
+ __result; \
+ })
+
+#define atomic_exchange_and_add(mem, value) \
+ ({ \
+ __typeof (*(mem)) __result; \
+ if (sizeof (*mem) == 4) \
+ __result = __arch_atomic_exchange_and_add_32 (mem, value); \
+ else if (sizeof (*mem) == 8) \
+ __result = __arch_atomic_exchange_and_add_64 (mem, value); \
+ else \
+ abort (); \
+ __result; \
+ })
+
+#define atomic_increment_val(mem) \
+ ({ \
+ __typeof (*(mem)) __result; \
+ if (sizeof (*(mem)) == 4) \
+ __result = __arch_atomic_increment_val_32 (mem); \
+ else if (sizeof (*(mem)) == 8) \
+ __result = __arch_atomic_increment_val_64 (mem); \
+ else \
+ abort (); \
+ __result; \
+ })
+
+#define atomic_increment(mem) ({ atomic_increment_val (mem); (void) 0; })
+
+#define atomic_decrement_val(mem) \
+ ({ \
+ __typeof (*(mem)) __result; \
+ if (sizeof (*(mem)) == 4) \
+ __result = __arch_atomic_decrement_val_32 (mem); \
+ else if (sizeof (*(mem)) == 8) \
+ __result = __arch_atomic_decrement_val_64 (mem); \
+ else \
+ abort (); \
+ __result; \
+ })
+
+#define atomic_decrement(mem) ({ atomic_decrement_val (mem); (void) 0; })
+
+
+/* Decrement *MEM if it is > 0, and return the old value. */
+#define atomic_decrement_if_positive(mem) \
+ ({ __typeof (*(mem)) __result; \
+ if (sizeof (*mem) == 4) \
+ __result = __arch_atomic_decrement_if_positive_32 (mem); \
+ else if (sizeof (*mem) == 8) \
+ __result = __arch_atomic_decrement_if_positive_64 (mem); \
+ else \
+ abort (); \
+ __result; \
+ })
diff --git a/libc/sysdeps/powerpc/bits/endian.h b/libc/sysdeps/powerpc/bits/endian.h
new file mode 100644
index 000000000..2a079347d
--- /dev/null
+++ b/libc/sysdeps/powerpc/bits/endian.h
@@ -0,0 +1,37 @@
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* PowerPC can be little or big endian. Hopefully gcc will know... */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN
+# if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
+# error Both BIG_ENDIAN and LITTLE_ENDIAN defined!
+# endif
+# define __BYTE_ORDER __BIG_ENDIAN
+#else
+# if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
+# define __BYTE_ORDER __LITTLE_ENDIAN
+# else
+# warning Cannot determine current byte order, assuming big-endian.
+# define __BYTE_ORDER __BIG_ENDIAN
+# endif
+#endif
diff --git a/libc/sysdeps/powerpc/bits/fenv.h b/libc/sysdeps/powerpc/bits/fenv.h
new file mode 100644
index 000000000..8509b4b0c
--- /dev/null
+++ b/libc/sysdeps/powerpc/bits/fenv.h
@@ -0,0 +1,145 @@
+/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+
+/* Define bits representing the exception. We use the bit positions of
+ the appropriate bits in the FPSCR... */
+enum
+ {
+ FE_INEXACT = 1 << (31 - 6),
+#define FE_INEXACT FE_INEXACT
+ FE_DIVBYZERO = 1 << (31 - 5),
+#define FE_DIVBYZERO FE_DIVBYZERO
+ FE_UNDERFLOW = 1 << (31 - 4),
+#define FE_UNDERFLOW FE_UNDERFLOW
+ FE_OVERFLOW = 1 << (31 - 3),
+#define FE_OVERFLOW FE_OVERFLOW
+
+ /* ... except for FE_INVALID, for which we use bit 31. FE_INVALID
+ actually corresponds to bits 7 through 12 and 21 through 23
+ in the FPSCR, but we can't use that because the current draft
+ says that it must be a power of 2. Instead we use bit 2 which
+ is the summary bit for all the FE_INVALID exceptions, which
+ kind of makes sense. */
+ FE_INVALID = 1 << (31 - 2),
+#define FE_INVALID FE_INVALID
+
+#ifdef __USE_GNU
+ /* Breakdown of the FE_INVALID bits. Setting FE_INVALID on an
+ input to a routine is equivalent to setting all of these bits;
+ FE_INVALID will be set on output from a routine iff one of
+ these bits is set. Note, though, that you can't disable or
+ enable these exceptions individually. */
+
+ /* Operation with SNaN. */
+ FE_INVALID_SNAN = 1 << (31 - 7),
+# define FE_INVALID_SNAN FE_INVALID_SNAN
+
+ /* Inf - Inf */
+ FE_INVALID_ISI = 1 << (31 - 8),
+# define FE_INVALID_ISI FE_INVALID_ISI
+
+ /* Inf / Inf */
+ FE_INVALID_IDI = 1 << (31 - 9),
+# define FE_INVALID_IDI FE_INVALID_IDI
+
+ /* 0 / 0 */
+ FE_INVALID_ZDZ = 1 << (31 - 10),
+# define FE_INVALID_ZDZ FE_INVALID_ZDZ
+
+ /* Inf * 0 */
+ FE_INVALID_IMZ = 1 << (31 - 11),
+# define FE_INVALID_IMZ FE_INVALID_IMZ
+
+ /* Comparison with NaN or SNaN. */
+ FE_INVALID_COMPARE = 1 << (31 - 12),
+# define FE_INVALID_COMPARE FE_INVALID_COMPARE
+
+ /* Invalid operation flag for software (not set by hardware). */
+ /* Note that some chips don't have this implemented, presumably
+ because no-one expected anyone to write software for them %-). */
+ FE_INVALID_SOFTWARE = 1 << (31 - 21),
+# define FE_INVALID_SOFTWARE FE_INVALID_SOFTWARE
+
+ /* Square root of negative number (including -Inf). */
+ /* Note that some chips don't have this implemented. */
+ FE_INVALID_SQRT = 1 << (31 - 22),
+# define FE_INVALID_SQRT FE_INVALID_SQRT
+
+ /* Conversion-to-integer of a NaN or a number too large or too small. */
+ FE_INVALID_INTEGER_CONVERSION = 1 << (31 - 23)
+# define FE_INVALID_INTEGER_CONVERSION FE_INVALID_INTEGER_CONVERSION
+
+# define FE_ALL_INVALID \
+ (FE_INVALID_SNAN | FE_INVALID_ISI | FE_INVALID_IDI | FE_INVALID_ZDZ \
+ | FE_INVALID_IMZ | FE_INVALID_COMPARE | FE_INVALID_SOFTWARE \
+ | FE_INVALID_SQRT | FE_INVALID_INTEGER_CONVERSION)
+#endif
+ };
+
+#define FE_ALL_EXCEPT \
+ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+/* PowerPC chips support all of the four defined rounding modes. We
+ use the bit pattern in the FPSCR as the values for the
+ appropriate macros. */
+enum
+ {
+ FE_TONEAREST = 0,
+#define FE_TONEAREST FE_TONEAREST
+ FE_TOWARDZERO = 1,
+#define FE_TOWARDZERO FE_TOWARDZERO
+ FE_UPWARD = 2,
+#define FE_UPWARD FE_UPWARD
+ FE_DOWNWARD = 3
+#define FE_DOWNWARD FE_DOWNWARD
+ };
+
+/* Type representing exception flags. */
+typedef unsigned int fexcept_t;
+
+/* Type representing floating-point environment. We leave it as 'double'
+ for efficiency reasons (rather than writing it to a 32-bit integer). */
+typedef double fenv_t;
+
+/* If the default argument is used we use this value. */
+extern const fenv_t __fe_dfl_env;
+#define FE_DFL_ENV (&__fe_dfl_env)
+
+#ifdef __USE_GNU
+/* Floating-point environment where all exceptions are enabled. Note that
+ this is not sufficient to give you SIGFPE. */
+extern const fenv_t __fe_enabled_env;
+# define FE_ENABLED_ENV (&__fe_enabled_env)
+
+/* Floating-point environment with (processor-dependent) non-IEEE floating
+ point. */
+extern const fenv_t __fe_nonieee_env;
+# define FE_NONIEEE_ENV (&__fe_nonieee_env)
+
+/* Floating-point environment with all exceptions enabled. Note that
+ just evaluating this value will set the processor into 'FPU
+ exceptions imprecise recoverable' mode, which may cause a significant
+ performance penalty (but have no other visible effect). */
+extern const fenv_t *__fe_nomask_env (void);
+# define FE_NOMASK_ENV (__fe_nomask_env ())
+#endif
diff --git a/libc/sysdeps/powerpc/bits/link.h b/libc/sysdeps/powerpc/bits/link.h
new file mode 100644
index 000000000..6c6f6042a
--- /dev/null
+++ b/libc/sysdeps/powerpc/bits/link.h
@@ -0,0 +1,111 @@
+/* Machine-specific declarations for dynamic linker interface. PowerPC version
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+
+#if __ELF_NATIVE_CLASS == 32
+
+/* Registers for entry into PLT on PPC32. */
+typedef struct La_ppc32_regs
+{
+ uint32_t lr_reg[8];
+ double lr_fp[8];
+ uint32_t lr_vreg[12][4];
+ uint32_t lr_r1;
+ uint32_t lr_lr;
+} La_ppc32_regs;
+
+/* Return values for calls from PLT on PPC32. */
+typedef struct La_ppc32_retval
+{
+ uint32_t lrv_r3;
+ uint32_t lrv_r4;
+ double lrv_fp[8];
+ uint32_t lrv_v2[4];
+} La_ppc32_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf32_Addr la_ppc32_gnu_pltenter (Elf32_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_ppc32_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_ppc32_gnu_pltexit (Elf32_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_ppc32_regs *__inregs,
+ La_ppc32_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
+
+#else
+
+/* Registers for entry into PLT on PPC64. */
+typedef struct La_ppc64_regs
+{
+ uint64_t lr_reg[8];
+ double lr_fp[13];
+ uint32_t __padding;
+ uint32_t lr_vrsave;
+ uint32_t lr_vreg[12][4];
+ uint64_t lr_r1;
+ uint64_t lr_lr;
+} La_ppc64_regs;
+
+/* Return values for calls from PLT on PPC64. */
+typedef struct La_ppc64_retval
+{
+ uint64_t lrv_r3;
+ uint64_t lrv_r4;
+ double lrv_fp[4]; /* f1-f4, float - complex long double. */
+ uint32_t lrv_v2[4]; /* v2. */
+} La_ppc64_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf64_Addr la_ppc64_gnu_pltenter (Elf64_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_ppc64_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_ppc64_gnu_pltexit (Elf64_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_ppc64_regs *__inregs,
+ La_ppc64_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
+
+#endif
diff --git a/libc/sysdeps/powerpc/bits/mathdef.h b/libc/sysdeps/powerpc/bits/mathdef.h
new file mode 100644
index 000000000..b79cc6ff9
--- /dev/null
+++ b/libc/sysdeps/powerpc/bits/mathdef.h
@@ -0,0 +1,64 @@
+/* Copyright (C) 1997,1998,1999,2000,2003,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+
+/* FIXME! This file describes properties of the compiler, not the machine;
+ it should not be part of libc!
+
+ FIXME! This file does not deal with the -fshort-double option of
+ gcc! */
+
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
+# ifdef __GNUC__
+# if __STDC__ == 1
+
+/* In GNU or ANSI mode, gcc leaves `float' expressions as-is. */
+typedef float float_t; /* `float' expressions are evaluated as
+ `float'. */
+typedef double double_t; /* `double' expressions are evaluated as
+ `double'. */
+
+# else
+
+/* For `gcc -traditional', `float' expressions are evaluated as `double'. */
+typedef double float_t; /* `float' expressions are evaluated as
+ `double'. */
+typedef double double_t; /* `double' expressions are evaluated as
+ `double'. */
+
+# endif
+# else
+
+/* Wild guess at types for float_t and double_t. */
+typedef double float_t;
+typedef double double_t;
+
+# endif
+
+/* The values returned by `ilogb' for 0 and NaN respectively. */
+# define FP_ILOGB0 (-2147483647)
+# define FP_ILOGBNAN (2147483647)
+
+#endif /* ISO C99 */
diff --git a/libc/sysdeps/powerpc/bits/setjmp.h b/libc/sysdeps/powerpc/bits/setjmp.h
new file mode 100644
index 000000000..9c3e22aba
--- /dev/null
+++ b/libc/sysdeps/powerpc/bits/setjmp.h
@@ -0,0 +1,52 @@
+/* Copyright (C) 1997,1998,2000,2003,2004,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Define the machine-dependent type `jmp_buf'. PowerPC version. */
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H 1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+/* The previous bits/setjmp.h had __jmp_buf defined as a structure.
+ We use an array of 'long int' instead, to make writing the
+ assembler easier. Naturally, user code should not depend on
+ either representation. */
+
+#include <bits/wordsize.h>
+
+/* The current powerpc 32-bit Altivec ABI specifies for SVR4 ABI and EABI
+ the vrsave must be at byte 248 & v20 at byte 256. So we must pad this
+ correctly on 32 bit. It also insists that vecregs are only gauranteed
+ 4 byte alignment so we need to use vperm in the setjmp/longjmp routines.
+ We have to version the code because members like int __mask_was_saved
+ in the jmp_buf will move as jmp_buf is now larger than 248 bytes. We
+ cannot keep the altivec jmp_buf backward compatible with the jmp_buf. */
+#ifndef _ASM
+# if __WORDSIZE == 64
+typedef long int __jmp_buf[64] __attribute__ ((__aligned__ (16)));
+# else
+/* The alignment is not essential, i.e.the buffer can be copied to a 4 byte
+ aligned buffer as per the ABI it is just added for performance reasons. */
+typedef long int __jmp_buf[64 + (12 * 4)] __attribute__ ((__aligned__ (16)));
+# endif
+#endif
+
+#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/powerpc/configure b/libc/sysdeps/powerpc/configure
new file mode 100755
index 000000000..07e3d091b
--- /dev/null
+++ b/libc/sysdeps/powerpc/configure
@@ -0,0 +1,38 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/powerpc.
+
+# Accept binutils which knows about ".machine".
+echo "$as_me:$LINENO: checking for .machine support" >&5
+echo $ECHO_N "checking for .machine support... $ECHO_C" >&6
+if test "${libc_cv_ppc_machine+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<\EOF
+ .machine "altivec"
+ blr
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_ppc_machine=yes
+else
+ libc_cv_ppc_machine=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_ppc_machine" >&5
+echo "${ECHO_T}$libc_cv_ppc_machine" >&6
+if test $libc_cv_ppc_machine != yes; then
+ { { echo "$as_me:$LINENO: error:
+*** A binutils version which can handle
+*** .machine \"altivec\"
+*** is needed." >&5
+echo "$as_me: error:
+*** A binutils version which can handle
+*** .machine \"altivec\"
+*** is needed." >&2;}
+ { (exit 1); exit 1; }; }
+fi
diff --git a/libc/sysdeps/powerpc/configure.in b/libc/sysdeps/powerpc/configure.in
new file mode 100644
index 000000000..28cc85934
--- /dev/null
+++ b/libc/sysdeps/powerpc/configure.in
@@ -0,0 +1,21 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/powerpc.
+
+# Accept binutils which knows about ".machine".
+AC_CACHE_CHECK(for .machine support, libc_cv_ppc_machine, [dnl
+cat > conftest.s <<\EOF
+ .machine "altivec"
+ blr
+EOF
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_ppc_machine=yes
+else
+ libc_cv_ppc_machine=no
+fi
+rm -f conftest*])
+if test $libc_cv_ppc_machine != yes; then
+ AC_MSG_ERROR([
+*** A binutils version which can handle
+*** .machine "altivec"
+*** is needed.])
+fi
diff --git a/libc/sysdeps/powerpc/dl-procinfo.c b/libc/sysdeps/powerpc/dl-procinfo.c
new file mode 100644
index 000000000..7c1ab7bad
--- /dev/null
+++ b/libc/sysdeps/powerpc/dl-procinfo.c
@@ -0,0 +1,66 @@
+/* Data for processor capability information. PowerPC version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This information must be kept in sync with the _DL_HWCAP_COUNT and
+ _DL_PLATFORM_COUNT definitions in procinfo.h.
+
+ If anything should be added here check whether the size of each string
+ is still ok with the given array size.
+
+ All the #ifdefs in the definitions are quite irritating but
+ necessary if we want to avoid duplicating the information. There
+ are three different modes:
+
+ - PROCINFO_DECL is defined. This means we are only interested in
+ declarations.
+
+ - PROCINFO_DECL is not defined:
+
+ + if SHARED is defined the file is included in an array
+ initializer. The .element = { ... } syntax is needed.
+
+ + if SHARED is not defined a normal array initialization is
+ needed.
+ */
+
+#ifndef PROCINFO_CLASS
+# define PROCINFO_CLASS
+#endif
+
+#if !defined PROCINFO_DECL && defined SHARED
+ ._dl_powerpc_cap_flags
+#else
+PROCINFO_CLASS const char _dl_powerpc_cap_flags[16][10]
+#endif
+#ifndef PROCINFO_DECL
+= {
+ "cell", "power5+", "power5", "power4",
+ "notb", "efpdouble", "efpsingle", "spe",
+ "ucache", "4xxmac", "mmu", "fpu",
+ "altivec", "ppc601", "ppc64", "ppc32",
+ }
+#endif
+#if !defined SHARED || defined PROCINFO_DECL
+;
+#else
+,
+#endif
+
+#undef PROCINFO_DECL
+#undef PROCINFO_CLASS
diff --git a/libc/sysdeps/powerpc/dl-procinfo.h b/libc/sysdeps/powerpc/dl-procinfo.h
new file mode 100644
index 000000000..8edc5e539
--- /dev/null
+++ b/libc/sysdeps/powerpc/dl-procinfo.h
@@ -0,0 +1,75 @@
+/* Processor capability information handling macros. PowerPC version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DL_PROCINFO_H
+#define _DL_PROCINFO_H 1
+
+#include <ldsodefs.h>
+#include <sysdep.h> /* This defines the PPC_FEATURE_* macros. */
+
+/* There are 16 bits used, but they are bits 16..31. */
+#define _DL_HWCAP_FIRST 16
+#define _DL_HWCAP_COUNT 32
+
+/* These bits influence library search. */
+#define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \
+ | PPC_FEATURE_POWER4 \
+ | PPC_FEATURE_POWER5 \
+ | PPC_FEATURE_POWER5_PLUS \
+ | PPC_FEATURE_CELL)
+
+/* We don't use AT_PLATFORM. */
+#define _DL_HWCAP_PLATFORM 0
+#define _dl_string_platform(str) (-1)
+
+static inline const char *
+__attribute__ ((unused))
+_dl_hwcap_string (int idx)
+{
+ return GLRO(dl_powerpc_cap_flags)[idx - _DL_HWCAP_FIRST];
+};
+
+static inline int
+__attribute__ ((unused))
+_dl_string_hwcap (const char *str)
+{
+ for (int i = _DL_HWCAP_FIRST; i < _DL_HWCAP_COUNT; ++i)
+ if (strcmp (str, _dl_hwcap_string (i)) == 0)
+ return i;
+ return -1;
+};
+
+#ifdef IS_IN_rtld
+static inline int
+__attribute__ ((unused))
+_dl_procinfo (int word)
+{
+ _dl_printf ("AT_HWCAP: ");
+
+ for (int i = _DL_HWCAP_FIRST; i < _DL_HWCAP_COUNT; ++i)
+ if (word & (1 << i))
+ _dl_printf (" %s", _dl_hwcap_string (i));
+
+ _dl_printf ("\n");
+
+ return 0;
+}
+#endif
+
+#endif /* dl-procinfo.h */
diff --git a/libc/sysdeps/powerpc/dl-tls.h b/libc/sysdeps/powerpc/dl-tls.h
new file mode 100644
index 000000000..957d4b4b9
--- /dev/null
+++ b/libc/sysdeps/powerpc/dl-tls.h
@@ -0,0 +1,49 @@
+/* Thread-local storage handling in the ELF dynamic linker. PowerPC version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* Type used for the representation of TLS information in the TOC. */
+typedef struct
+{
+ unsigned long int ti_module;
+ unsigned long int ti_offset;
+} tls_index;
+
+/* The thread pointer points 0x7000 past the first static TLS block. */
+#define TLS_TP_OFFSET 0x7000
+
+/* Dynamic thread vector pointers point 0x8000 past the start of each
+ TLS block. */
+#define TLS_DTV_OFFSET 0x8000
+
+/* Compute the value for a @tprel reloc. */
+#define TLS_TPREL_VALUE(sym_map, sym, reloc) \
+ ((sym_map)->l_tls_offset + (sym)->st_value + (reloc)->r_addend \
+ - TLS_TP_OFFSET)
+
+/* Compute the value for a @dtprel reloc. */
+#define TLS_DTPREL_VALUE(sym, reloc) \
+ ((sym)->st_value + (reloc)->r_addend - TLS_DTV_OFFSET)
+
+#ifdef SHARED
+extern void *__tls_get_addr (tls_index *ti);
+
+# define GET_ADDR_OFFSET (ti->ti_offset + TLS_DTV_OFFSET)
+# define __TLS_GET_ADDR(__ti) (__tls_get_addr (__ti) - TLS_DTV_OFFSET)
+#endif
diff --git a/libc/sysdeps/powerpc/elf/rtld-global-offsets.sym b/libc/sysdeps/powerpc/elf/rtld-global-offsets.sym
new file mode 100644
index 000000000..830106ba2
--- /dev/null
+++ b/libc/sysdeps/powerpc/elf/rtld-global-offsets.sym
@@ -0,0 +1,7 @@
+#define SHARED 1
+
+#include <ldsodefs.h>
+
+#define rtdl_global_ro_offsetof(mem) offsetof (struct rtld_global_ro, mem)
+
+RTLD_GLOBAL_RO_DL_HWCAP_OFFSET rtdl_global_ro_offsetof (_dl_hwcap)
diff --git a/libc/sysdeps/powerpc/ffs.c b/libc/sysdeps/powerpc/ffs.c
new file mode 100644
index 000000000..61d79c4c2
--- /dev/null
+++ b/libc/sysdeps/powerpc/ffs.c
@@ -0,0 +1,47 @@
+/* Find first set bit in a word, counted from least significant end.
+ For PowerPC.
+ Copyright (C) 1991, 1992, 1997, 1998, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define ffsl __something_else
+#include <limits.h>
+#include <string.h>
+
+#undef ffs
+
+#ifdef __GNUC__
+
+int
+__ffs (int x)
+{
+ int cnt;
+
+ asm ("cntlzw %0,%1" : "=r" (cnt) : "r" (x & -x));
+ return 32 - cnt;
+}
+weak_alias (__ffs, ffs)
+libc_hidden_builtin_def (ffs)
+#if ULONG_MAX == UINT_MAX
+#undef ffsl
+weak_alias (__ffs, ffsl)
+#endif
+
+#else
+#include <string/ffs.c>
+#endif
diff --git a/libc/sysdeps/powerpc/fpu/Makefile b/libc/sysdeps/powerpc/fpu/Makefile
new file mode 100644
index 000000000..d0fe4a8ba
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/Makefile
@@ -0,0 +1,6 @@
+ifeq ($(subdir),math)
+libm-support += fenv_const fe_nomask t_sqrt
+
+# libm needs ld.so to access dl_hwcap
+$(objpfx)libm.so: $(elfobjdir)/ld.so
+endif
diff --git a/libc/sysdeps/powerpc/fpu/bits/fenvinline.h b/libc/sysdeps/powerpc/fpu/bits/fenvinline.h
new file mode 100644
index 000000000..f7700a49e
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/bits/fenvinline.h
@@ -0,0 +1,61 @@
+/* Inline floating-point environment handling functions for powerpc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if defined __GNUC__ && !defined _SOFT_FLOAT && !defined __NO_MATH_INLINES
+
+/* Inline definition for fegetround. */
+# define fegetround() \
+ (__extension__ ({ int __fegetround_result; \
+ __asm__ __volatile__ \
+ ("mcrfs 7,7 ; mfcr %0" \
+ : "=r"(__fegetround_result) : : "cr7"); \
+ __fegetround_result & 3; }))
+
+/* The weird 'i#*X' constraints on the following suppress a gcc
+ warning when __excepts is not a constant. Otherwise, they mean the
+ same as just plain 'i'. */
+
+/* Inline definition for feraiseexcept. */
+# define feraiseexcept(__excepts) \
+ ((__builtin_constant_p (__excepts) \
+ && ((__excepts) & ((__excepts)-1)) == 0 \
+ && (__excepts) != FE_INVALID) \
+ ? ((__excepts) != 0 \
+ ? (__extension__ ({ __asm__ __volatile__ \
+ ("mtfsb1 %s0" \
+ : : "i#*X"(__builtin_ffs (__excepts))); \
+ 0; })) \
+ : 0) \
+ : (feraiseexcept) (__excepts))
+
+/* Inline definition for feclearexcept. */
+# define feclearexcept(__excepts) \
+ ((__builtin_constant_p (__excepts) \
+ && ((__excepts) & ((__excepts)-1)) == 0 \
+ && (__excepts) != FE_INVALID) \
+ ? ((__excepts) != 0 \
+ ? (__extension__ ({ __asm__ __volatile__ \
+ ("mtfsb0 %s0" \
+ : : "i#*X"(__builtin_ffs (__excepts))); \
+ 0; })) \
+ : 0) \
+ : (feclearexcept) (__excepts))
+
+#endif /* __GNUC__ && !_SOFT_FLOAT */
diff --git a/libc/sysdeps/powerpc/fpu/bits/mathinline.h b/libc/sysdeps/powerpc/fpu/bits/mathinline.h
new file mode 100644
index 000000000..aed899e88
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/bits/mathinline.h
@@ -0,0 +1,182 @@
+/* Inline math functions for powerpc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
+#endif
+
+#ifdef __cplusplus
+# define __MATH_INLINE __inline
+#else
+# define __MATH_INLINE extern __inline
+#endif /* __cplusplus */
+
+#if defined __GNUC__ && !defined _SOFT_FLOAT
+
+#ifdef __USE_ISOC99
+# if !__GNUC_PREREQ (2,97)
+# define __unordered_cmp(x, y) \
+ (__extension__ \
+ ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
+ unsigned __r; \
+ __asm__("fcmpu 7,%1,%2 ; mfcr %0" : "=r" (__r) : "f" (__x), "f"(__y) \
+ : "cr7"); \
+ __r; }))
+
+# undef isgreater
+# undef isgreaterequal
+# undef isless
+# undef islessequal
+# undef islessgreater
+# undef isunordered
+
+# define isgreater(x, y) (__unordered_cmp (x, y) >> 2 & 1)
+# define isgreaterequal(x, y) ((__unordered_cmp (x, y) & 6) != 0)
+# define isless(x, y) (__unordered_cmp (x, y) >> 3 & 1)
+# define islessequal(x, y) ((__unordered_cmp (x, y) & 0xA) != 0)
+# define islessgreater(x, y) ((__unordered_cmp (x, y) & 0xC) != 0)
+# define isunordered(x, y) (__unordered_cmp (x, y) & 1)
+
+# endif /* __GNUC_PREREQ (2,97) */
+
+/* The gcc, version 2.7 or below, has problems with all this inlining
+ code. So disable it for this version of the compiler. */
+# if __GNUC_PREREQ (2, 8)
+/* Test for negative number. Used in the signbit() macro. */
+__MATH_INLINE int
+__NTH (__signbitf (float __x))
+{
+ __extension__ union { float __f; int __i; } __u = { __f: __x };
+ return __u.__i < 0;
+}
+__MATH_INLINE int
+__NTH (__signbit (double __x))
+{
+ __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
+ return __u.__i[0] < 0;
+}
+# endif
+#endif /* __USE_ISOC99 */
+
+#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
+
+#ifdef __USE_ISOC99
+
+# ifndef __powerpc64__
+__MATH_INLINE long int lrint (double __x) __THROW;
+__MATH_INLINE long int
+__NTH (lrint (double __x))
+{
+ union {
+ double __d;
+ int __ll[2];
+ } __u;
+ __asm__ ("fctiw %0,%1" : "=f"(__u.__d) : "f"(__x));
+ return __u.__ll[1];
+}
+
+__MATH_INLINE long int lrintf (float __x) __THROW;
+__MATH_INLINE long int
+__NTH (lrintf (float __x))
+{
+ union {
+ double __d;
+ int __ll[2];
+ } __u;
+ __asm__ ("fctiw %0,%1" : "=f"(__u.__d) : "f"(__x));
+ return __u.__ll[1];
+}
+# endif
+
+__MATH_INLINE double fdim (double __x, double __y) __THROW;
+__MATH_INLINE double
+__NTH (fdim (double __x, double __y))
+{
+ return __x <= __y ? 0 : __x - __y;
+}
+
+__MATH_INLINE float fdimf (float __x, float __y) __THROW;
+__MATH_INLINE float
+__NTH (fdimf (float __x, float __y))
+{
+ return __x <= __y ? 0 : __x - __y;
+}
+
+#endif /* __USE_ISOC99 */
+#endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
+
+/* This code is used internally in the GNU libc. */
+#ifdef __LIBC_INTERNAL_MATH_INLINES
+
+#include <sysdep.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+# if __WORDSIZE == 64 || defined _ARCH_PWR4
+# define __CPU_HAS_FSQRT 1
+# else
+# define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
+# endif
+
+extern double __slow_ieee754_sqrt (double);
+__MATH_INLINE double
+__NTH (__ieee754_sqrt (double __x))
+{
+ double __z;
+
+ /* If the CPU is 64-bit we can use the optional FP instructions. */
+ if (__CPU_HAS_FSQRT)
+ {
+ /* Volatile is required to prevent the compiler from moving the
+ fsqrt instruction above the branch. */
+ __asm __volatile (
+ " fsqrt %0,%1\n"
+ : "=f" (__z)
+ : "f" (__x));
+ }
+ else
+ __z = __slow_ieee754_sqrt(__x);
+
+ return __z;
+}
+
+extern float __slow_ieee754_sqrtf (float);
+__MATH_INLINE float
+__NTH (__ieee754_sqrtf (float __x))
+{
+ float __z;
+
+ /* If the CPU is 64-bit we can use the optional FP instructions. */
+ if (__CPU_HAS_FSQRT)
+ {
+ /* Volatile is required to prevent the compiler from moving the
+ fsqrts instruction above the branch. */
+ __asm __volatile (
+ " fsqrts %0,%1\n"
+ : "=f" (__z)
+ : "f" (__x));
+ }
+ else
+ __z = __slow_ieee754_sqrtf(__x);
+
+ return __z;
+}
+#endif /* __LIBC_INTERNAL_MATH_INLINES */
+#endif /* __GNUC__ && !_SOFT_FLOAT */
diff --git a/libc/sysdeps/powerpc/fpu/e_sqrt.c b/libc/sysdeps/powerpc/fpu/e_sqrt.c
new file mode 100644
index 000000000..540b92465
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/e_sqrt.c
@@ -0,0 +1,184 @@
+/* Double-precision floating point square root.
+ Copyright (C) 1997, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_private.h>
+#include <fenv_libc.h>
+#include <inttypes.h>
+
+#include <sysdep.h>
+#include <ldsodefs.h>
+
+static const double almost_half = 0.5000000000000001; /* 0.5 + 2^-53 */
+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
+static const float two108 = 3.245185536584267269e+32;
+static const float twom54 = 5.551115123125782702e-17;
+extern const float __t_sqrt[1024];
+
+/* The method is based on a description in
+ Computation of elementary functions on the IBM RISC System/6000 processor,
+ P. W. Markstein, IBM J. Res. Develop, 34(1) 1990.
+ Basically, it consists of two interleaved Newton-Rhapson approximations,
+ one to find the actual square root, and one to find its reciprocal
+ without the expense of a division operation. The tricky bit here
+ is the use of the POWER/PowerPC multiply-add operation to get the
+ required accuracy with high speed.
+
+ The argument reduction works by a combination of table lookup to
+ obtain the initial guesses, and some careful modification of the
+ generated guesses (which mostly runs on the integer unit, while the
+ Newton-Rhapson is running on the FPU). */
+
+#ifdef __STDC__
+double
+__slow_ieee754_sqrt (double x)
+#else
+double
+__slow_ieee754_sqrt (x)
+ double x;
+#endif
+{
+ const float inf = a_inf.value;
+
+ if (x > 0)
+ {
+ /* schedule the EXTRACT_WORDS to get separation between the store
+ and the load. */
+ ieee_double_shape_type ew_u;
+ ieee_double_shape_type iw_u;
+ ew_u.value = (x);
+ if (x != inf)
+ {
+ /* Variables named starting with 's' exist in the
+ argument-reduced space, so that 2 > sx >= 0.5,
+ 1.41... > sg >= 0.70.., 0.70.. >= sy > 0.35... .
+ Variables named ending with 'i' are integer versions of
+ floating-point values. */
+ double sx; /* The value of which we're trying to find the
+ square root. */
+ double sg, g; /* Guess of the square root of x. */
+ double sd, d; /* Difference between the square of the guess and x. */
+ double sy; /* Estimate of 1/2g (overestimated by 1ulp). */
+ double sy2; /* 2*sy */
+ double e; /* Difference between y*g and 1/2 (se = e * fsy). */
+ double shx; /* == sx * fsg */
+ double fsg; /* sg*fsg == g. */
+ fenv_t fe; /* Saved floating-point environment (stores rounding
+ mode and whether the inexact exception is
+ enabled). */
+ uint32_t xi0, xi1, sxi, fsgi;
+ const float *t_sqrt;
+
+ fe = fegetenv_register ();
+ /* complete the EXTRACT_WORDS (xi0,xi1,x) operation. */
+ xi0 = ew_u.parts.msw;
+ xi1 = ew_u.parts.lsw;
+ relax_fenv_state ();
+ sxi = (xi0 & 0x3fffffff) | 0x3fe00000;
+ /* schedule the INSERT_WORDS (sx, sxi, xi1) to get separation
+ between the store and the load. */
+ iw_u.parts.msw = sxi;
+ iw_u.parts.lsw = xi1;
+ t_sqrt = __t_sqrt + (xi0 >> (52 - 32 - 8 - 1) & 0x3fe);
+ sg = t_sqrt[0];
+ sy = t_sqrt[1];
+ /* complete the INSERT_WORDS (sx, sxi, xi1) operation. */
+ sx = iw_u.value;
+
+ /* Here we have three Newton-Rhapson iterations each of a
+ division and a square root and the remainder of the
+ argument reduction, all interleaved. */
+ sd = -(sg * sg - sx);
+ fsgi = (xi0 + 0x40000000) >> 1 & 0x7ff00000;
+ sy2 = sy + sy;
+ sg = sy * sd + sg; /* 16-bit approximation to sqrt(sx). */
+
+ /* schedule the INSERT_WORDS (fsg, fsgi, 0) to get separation
+ between the store and the load. */
+ INSERT_WORDS (fsg, fsgi, 0);
+ iw_u.parts.msw = fsgi;
+ iw_u.parts.lsw = (0);
+ e = -(sy * sg - almost_half);
+ sd = -(sg * sg - sx);
+ if ((xi0 & 0x7ff00000) == 0)
+ goto denorm;
+ sy = sy + e * sy2;
+ sg = sg + sy * sd; /* 32-bit approximation to sqrt(sx). */
+ sy2 = sy + sy;
+ /* complete the INSERT_WORDS (fsg, fsgi, 0) operation. */
+ fsg = iw_u.value;
+ e = -(sy * sg - almost_half);
+ sd = -(sg * sg - sx);
+ sy = sy + e * sy2;
+ shx = sx * fsg;
+ sg = sg + sy * sd; /* 64-bit approximation to sqrt(sx),
+ but perhaps rounded incorrectly. */
+ sy2 = sy + sy;
+ g = sg * fsg;
+ e = -(sy * sg - almost_half);
+ d = -(g * sg - shx);
+ sy = sy + e * sy2;
+ fesetenv_register (fe);
+ return g + sy * d;
+ denorm:
+ /* For denormalised numbers, we normalise, calculate the
+ square root, and return an adjusted result. */
+ fesetenv_register (fe);
+ return __slow_ieee754_sqrt (x * two108) * twom54;
+ }
+ }
+ else if (x < 0)
+ {
+ /* For some reason, some PowerPC32 processors don't implement
+ FE_INVALID_SQRT. */
+#ifdef FE_INVALID_SQRT
+ feraiseexcept (FE_INVALID_SQRT);
+ if (!fetestexcept (FE_INVALID))
+#endif
+ feraiseexcept (FE_INVALID);
+ x = a_nan.value;
+ }
+ return f_wash (x);
+}
+
+#ifdef __STDC__
+double
+__ieee754_sqrt (double x)
+#else
+double
+__ieee754_sqrt (x)
+ double x;
+#endif
+{
+ double z;
+
+ /* If the CPU is 64-bit we can use the optional FP instructions. */
+ if (__CPU_HAS_FSQRT)
+ {
+ /* Volatile is required to prevent the compiler from moving the
+ fsqrt instruction above the branch. */
+ __asm __volatile (" fsqrt %0,%1\n"
+ :"=f" (z):"f" (x));
+ }
+ else
+ z = __slow_ieee754_sqrt (x);
+
+ return z;
+}
diff --git a/libc/sysdeps/powerpc/fpu/e_sqrtf.c b/libc/sysdeps/powerpc/fpu/e_sqrtf.c
new file mode 100644
index 000000000..b63d31472
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/e_sqrtf.c
@@ -0,0 +1,161 @@
+/* Single-precision floating point square root.
+ Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_private.h>
+#include <fenv_libc.h>
+#include <inttypes.h>
+
+#include <sysdep.h>
+#include <ldsodefs.h>
+
+static const float almost_half = 0.50000006; /* 0.5 + 2^-24 */
+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
+static const float two48 = 281474976710656.0;
+static const float twom24 = 5.9604644775390625e-8;
+extern const float __t_sqrt[1024];
+
+/* The method is based on a description in
+ Computation of elementary functions on the IBM RISC System/6000 processor,
+ P. W. Markstein, IBM J. Res. Develop, 34(1) 1990.
+ Basically, it consists of two interleaved Newton-Rhapson approximations,
+ one to find the actual square root, and one to find its reciprocal
+ without the expense of a division operation. The tricky bit here
+ is the use of the POWER/PowerPC multiply-add operation to get the
+ required accuracy with high speed.
+
+ The argument reduction works by a combination of table lookup to
+ obtain the initial guesses, and some careful modification of the
+ generated guesses (which mostly runs on the integer unit, while the
+ Newton-Rhapson is running on the FPU). */
+
+#ifdef __STDC__
+float
+__slow_ieee754_sqrtf (float x)
+#else
+float
+__slow_ieee754_sqrtf (x)
+ float x;
+#endif
+{
+ const float inf = a_inf.value;
+
+ if (x > 0)
+ {
+ if (x != inf)
+ {
+ /* Variables named starting with 's' exist in the
+ argument-reduced space, so that 2 > sx >= 0.5,
+ 1.41... > sg >= 0.70.., 0.70.. >= sy > 0.35... .
+ Variables named ending with 'i' are integer versions of
+ floating-point values. */
+ float sx; /* The value of which we're trying to find the square
+ root. */
+ float sg, g; /* Guess of the square root of x. */
+ float sd, d; /* Difference between the square of the guess and x. */
+ float sy; /* Estimate of 1/2g (overestimated by 1ulp). */
+ float sy2; /* 2*sy */
+ float e; /* Difference between y*g and 1/2 (note that e==se). */
+ float shx; /* == sx * fsg */
+ float fsg; /* sg*fsg == g. */
+ fenv_t fe; /* Saved floating-point environment (stores rounding
+ mode and whether the inexact exception is
+ enabled). */
+ uint32_t xi, sxi, fsgi;
+ const float *t_sqrt;
+
+ GET_FLOAT_WORD (xi, x);
+ fe = fegetenv_register ();
+ relax_fenv_state ();
+ sxi = (xi & 0x3fffffff) | 0x3f000000;
+ SET_FLOAT_WORD (sx, sxi);
+ t_sqrt = __t_sqrt + (xi >> (23 - 8 - 1) & 0x3fe);
+ sg = t_sqrt[0];
+ sy = t_sqrt[1];
+
+ /* Here we have three Newton-Rhapson iterations each of a
+ division and a square root and the remainder of the
+ argument reduction, all interleaved. */
+ sd = -(sg * sg - sx);
+ fsgi = (xi + 0x40000000) >> 1 & 0x7f800000;
+ sy2 = sy + sy;
+ sg = sy * sd + sg; /* 16-bit approximation to sqrt(sx). */
+ e = -(sy * sg - almost_half);
+ SET_FLOAT_WORD (fsg, fsgi);
+ sd = -(sg * sg - sx);
+ sy = sy + e * sy2;
+ if ((xi & 0x7f800000) == 0)
+ goto denorm;
+ shx = sx * fsg;
+ sg = sg + sy * sd; /* 32-bit approximation to sqrt(sx),
+ but perhaps rounded incorrectly. */
+ sy2 = sy + sy;
+ g = sg * fsg;
+ e = -(sy * sg - almost_half);
+ d = -(g * sg - shx);
+ sy = sy + e * sy2;
+ fesetenv_register (fe);
+ return g + sy * d;
+ denorm:
+ /* For denormalised numbers, we normalise, calculate the
+ square root, and return an adjusted result. */
+ fesetenv_register (fe);
+ return __slow_ieee754_sqrtf (x * two48) * twom24;
+ }
+ }
+ else if (x < 0)
+ {
+ /* For some reason, some PowerPC32 processors don't implement
+ FE_INVALID_SQRT. */
+#ifdef FE_INVALID_SQRT
+ feraiseexcept (FE_INVALID_SQRT);
+ if (!fetestexcept (FE_INVALID))
+#endif
+ feraiseexcept (FE_INVALID);
+ x = a_nan.value;
+ }
+ return f_washf (x);
+}
+
+
+#ifdef __STDC__
+float
+__ieee754_sqrtf (float x)
+#else
+float
+__ieee754_sqrtf (x)
+ float x;
+#endif
+{
+ double z;
+
+ /* If the CPU is 64-bit we can use the optional FP instructions. */
+ if (__CPU_HAS_FSQRT)
+ {
+ /* Volatile is required to prevent the compiler from moving the
+ fsqrt instruction above the branch. */
+ __asm __volatile (" fsqrts %0,%1\n"
+ :"=f" (z):"f" (x));
+ }
+ else
+ z = __slow_ieee754_sqrtf (x);
+
+ return z;
+}
diff --git a/libc/sysdeps/powerpc/fpu/fclrexcpt.c b/libc/sysdeps/powerpc/fpu/fclrexcpt.c
new file mode 100644
index 000000000..d06e47143
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fclrexcpt.c
@@ -0,0 +1,48 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+#undef feclearexcept
+int
+__feclearexcept (int excepts)
+{
+ fenv_union_t u;
+
+ /* Get the current state. */
+ u.fenv = fegetenv_register ();
+
+ /* Clear the relevant bits. */
+ u.l[1] = u.l[1] & ~((-(excepts >> (31 - FPSCR_VX) & 1) & FE_ALL_INVALID)
+ | (excepts & FPSCR_STICKY_BITS));
+
+ /* Put the new state in effect. */
+ fesetenv_register (u.fenv);
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feclearexcept, __old_feclearexcept)
+compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
diff --git a/libc/sysdeps/powerpc/fpu/fe_nomask.c b/libc/sysdeps/powerpc/fpu/fe_nomask.c
new file mode 100644
index 000000000..ba45d8570
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fe_nomask.c
@@ -0,0 +1,32 @@
+/* Procedure definition for FE_NOMASK_ENV.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <errno.h>
+
+/* This is presently a stub, until it's decided how the kernels should
+ support this. */
+
+const fenv_t *
+__fe_nomask_env(void)
+{
+ __set_errno (ENOSYS);
+ return FE_ENABLED_ENV;
+}
+stub_warning (__fe_nomask_env)
diff --git a/libc/sysdeps/powerpc/fpu/fedisblxcpt.c b/libc/sysdeps/powerpc/fpu/fedisblxcpt.c
new file mode 100644
index 000000000..633a6e6e3
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fedisblxcpt.c
@@ -0,0 +1,50 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Geoffrey Keating <geoffk@geoffk.org>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+fedisableexcept (int excepts)
+{
+ fenv_union_t fe;
+ int result;
+
+ result = fegetexcept ();
+
+ if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID)
+ excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID;
+
+ fe.fenv = fegetenv_register ();
+ if (excepts & FE_INEXACT)
+ fe.l[1] &= ~(1 << (31 - FPSCR_XE));
+ if (excepts & FE_DIVBYZERO)
+ fe.l[1] &= ~(1 << (31 - FPSCR_ZE));
+ if (excepts & FE_UNDERFLOW)
+ fe.l[1] &= ~(1 << (31 - FPSCR_UE));
+ if (excepts & FE_OVERFLOW)
+ fe.l[1] &= ~(1 << (31 - FPSCR_OE));
+ if (excepts & FE_INVALID)
+ fe.l[1] &= ~(1 << (31 - FPSCR_VE));
+ fesetenv_register (fe.fenv);
+
+ if ((fegetexcept () & excepts) != 0)
+ result = -1;
+ return result;
+}
diff --git a/libc/sysdeps/powerpc/fpu/feenablxcpt.c b/libc/sysdeps/powerpc/fpu/feenablxcpt.c
new file mode 100644
index 000000000..7bff18b42
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/feenablxcpt.c
@@ -0,0 +1,55 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Geoffrey Keating <geoffk@geoffk.org>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+feenableexcept (int excepts)
+{
+ fenv_union_t fe;
+ int result, new;
+
+ result = fegetexcept ();
+
+ if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID)
+ excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID;
+
+ fe.fenv = fegetenv_register ();
+ if (excepts & FE_INEXACT)
+ fe.l[1] |= (1 << (31 - FPSCR_XE));
+ if (excepts & FE_DIVBYZERO)
+ fe.l[1] |= (1 << (31 - FPSCR_ZE));
+ if (excepts & FE_UNDERFLOW)
+ fe.l[1] |= (1 << (31 - FPSCR_UE));
+ if (excepts & FE_OVERFLOW)
+ fe.l[1] |= (1 << (31 - FPSCR_OE));
+ if (excepts & FE_INVALID)
+ fe.l[1] |= (1 << (31 - FPSCR_VE));
+ fesetenv_register (fe.fenv);
+
+ new = fegetexcept ();
+ if (new != 0 && result == 0)
+ (void)__fe_nomask_env ();
+
+ if ((new & excepts) != excepts)
+ result = -1;
+
+ return result;
+}
diff --git a/libc/sysdeps/powerpc/fpu/fegetenv.c b/libc/sysdeps/powerpc/fpu/fegetenv.c
new file mode 100644
index 000000000..53953454c
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fegetenv.c
@@ -0,0 +1,38 @@
+/* Store current floating-point environment.
+ Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <bp-sym.h>
+
+int
+__fegetenv (fenv_t *envp)
+{
+ *envp = fegetenv_register ();
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fegetenv, __old_fegetenv)
+compat_symbol (libm, BP_SYM (__old_fegetenv), BP_SYM (fegetenv), GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, BP_SYM (__fegetenv), BP_SYM (fegetenv), GLIBC_2_2);
diff --git a/libc/sysdeps/powerpc/fpu/fegetexcept.c b/libc/sysdeps/powerpc/fpu/fegetexcept.c
new file mode 100644
index 000000000..0b5cebb6d
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fegetexcept.c
@@ -0,0 +1,43 @@
+/* Get floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Geoffrey Keating <geoffk@geoffk.org>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+fegetexcept (void)
+{
+ fenv_union_t fe;
+ int result = 0;
+
+ fe.fenv = fegetenv_register ();
+
+ if (fe.l[1] & (1 << (31 - FPSCR_XE)))
+ result |= FE_INEXACT;
+ if (fe.l[1] & (1 << (31 - FPSCR_ZE)))
+ result |= FE_DIVBYZERO;
+ if (fe.l[1] & (1 << (31 - FPSCR_UE)))
+ result |= FE_UNDERFLOW;
+ if (fe.l[1] & (1 << (31 - FPSCR_OE)))
+ result |= FE_OVERFLOW;
+ if (fe.l[1] & (1 << (31 - FPSCR_VE)))
+ result |= FE_INVALID;
+
+ return result;
+}
diff --git a/libc/sysdeps/powerpc/fpu/fegetround.c b/libc/sysdeps/powerpc/fpu/fegetround.c
new file mode 100644
index 000000000..93663ad54
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fegetround.c
@@ -0,0 +1,27 @@
+/* Return current rounding direction.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+#undef fegetround
+int
+fegetround (void)
+{
+ return __fegetround();
+}
diff --git a/libc/sysdeps/powerpc/fpu/feholdexcpt.c b/libc/sysdeps/powerpc/fpu/feholdexcpt.c
new file mode 100644
index 000000000..150becd67
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/feholdexcpt.c
@@ -0,0 +1,39 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ fenv_union_t u;
+
+ /* Get the current state. */
+ u.fenv = *envp = fegetenv_register ();
+
+ /* Clear everything except for the rounding mode and non-IEEE arithmetic
+ flag. */
+ u.l[1] = u.l[1] & 7;
+
+ /* Put the new state in effect. */
+ fesetenv_register (u.fenv);
+
+ return 0;
+}
+libm_hidden_def (feholdexcept)
diff --git a/libc/sysdeps/powerpc/fpu/fenv_const.c b/libc/sysdeps/powerpc/fpu/fenv_const.c
new file mode 100644
index 000000000..7c348f021
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fenv_const.c
@@ -0,0 +1,33 @@
+/* Constants for fenv_bits.h.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* We want to specify the bit pattern of the __fe_*_env constants, so
+ pretend they're really `long long' instead of `double'. */
+
+/* If the default argument is used we use this value. */
+const unsigned long long __fe_dfl_env __attribute__ ((aligned (8))) =
+0xfff8000000000000ULL;
+
+/* Floating-point environment where none of the exceptions are masked. */
+const unsigned long long __fe_enabled_env __attribute__ ((aligned (8))) =
+0xfff80000000000f8ULL;
+
+/* Floating-point environment with the NI bit set. */
+const unsigned long long __fe_nonieee_env __attribute__ ((aligned (8))) =
+0xfff8000000000004ULL;
diff --git a/libc/sysdeps/powerpc/fpu/fenv_libc.h b/libc/sysdeps/powerpc/fpu/fenv_libc.h
new file mode 100644
index 000000000..fd5fc0c76
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fenv_libc.h
@@ -0,0 +1,141 @@
+/* Internal libc stuff for floating point environment routines.
+ Copyright (C) 1997, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FENV_LIBC_H
+#define _FENV_LIBC_H 1
+
+#include <fenv.h>
+
+/* The sticky bits in the FPSCR indicating exceptions have occurred. */
+#define FPSCR_STICKY_BITS ((FE_ALL_EXCEPT | FE_ALL_INVALID) & ~FE_INVALID)
+
+/* Equivalent to fegetenv, but returns a fenv_t instead of taking a
+ pointer. */
+#define fegetenv_register() \
+ ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; })
+
+/* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */
+#define fesetenv_register(env) \
+ ({ double d = (env); asm volatile ("mtfsf 0xff,%0" : : "f" (d)); })
+
+/* This very handy macro:
+ - Sets the rounding mode to 'round to nearest';
+ - Sets the processor into IEEE mode; and
+ - Prevents exceptions from being raised for inexact results.
+ These things happen to be exactly what you need for typical elementary
+ functions. */
+#define relax_fenv_state() asm ("mtfsfi 7,0")
+
+/* Set/clear a particular FPSCR bit (for instance,
+ reset_fpscr_bit(FPSCR_VE);
+ prevents INVALID exceptions from being raised). */
+#define set_fpscr_bit(x) asm volatile ("mtfsb1 %0" : : "i"(x))
+#define reset_fpscr_bit(x) asm volatile ("mtfsb0 %0" : : "i"(x))
+
+typedef union
+{
+ fenv_t fenv;
+ unsigned int l[2];
+} fenv_union_t;
+
+
+static inline int
+__fegetround (void)
+{
+ int result;
+ asm volatile ("mcrfs 7,7\n\t"
+ "mfcr %0" : "=r"(result) : : "cr7");
+ return result & 3;
+}
+#define fegetround() __fegetround()
+
+static inline int
+__fesetround (int round)
+{
+ if ((unsigned int) round < 2)
+ {
+ asm volatile ("mtfsb0 30");
+ if ((unsigned int) round == 0)
+ asm volatile ("mtfsb0 31");
+ else
+ asm volatile ("mtfsb1 31");
+ }
+ else
+ {
+ asm volatile ("mtfsb1 30");
+ if ((unsigned int) round == 2)
+ asm volatile ("mtfsb0 31");
+ else
+ asm volatile ("mtfsb1 31");
+ }
+
+ return 0;
+}
+#define fesetround(mode) __fesetround(mode)
+
+/* Definitions of all the FPSCR bit numbers */
+enum {
+ FPSCR_FX = 0, /* exception summary */
+ FPSCR_FEX, /* enabled exception summary */
+ FPSCR_VX, /* invalid operation summary */
+ FPSCR_OX, /* overflow */
+ FPSCR_UX, /* underflow */
+ FPSCR_ZX, /* zero divide */
+ FPSCR_XX, /* inexact */
+ FPSCR_VXSNAN, /* invalid operation for SNaN */
+ FPSCR_VXISI, /* invalid operation for Inf-Inf */
+ FPSCR_VXIDI, /* invalid operation for Inf/Inf */
+ FPSCR_VXZDZ, /* invalid operation for 0/0 */
+ FPSCR_VXIMZ, /* invalid operation for Inf*0 */
+ FPSCR_VXVC, /* invalid operation for invalid compare */
+ FPSCR_FR, /* fraction rounded [fraction was incremented by round] */
+ FPSCR_FI, /* fraction inexact */
+ FPSCR_FPRF_C, /* result class descriptor */
+ FPSCR_FPRF_FL, /* result less than (usually, less than 0) */
+ FPSCR_FPRF_FG, /* result greater than */
+ FPSCR_FPRF_FE, /* result equal to */
+ FPSCR_FPRF_FU, /* result unordered */
+ FPSCR_20, /* reserved */
+ FPSCR_VXSOFT, /* invalid operation set by software */
+ FPSCR_VXSQRT, /* invalid operation for square root */
+ FPSCR_VXCVI, /* invalid operation for invalid integer convert */
+ FPSCR_VE, /* invalid operation exception enable */
+ FPSCR_OE, /* overflow exception enable */
+ FPSCR_UE, /* underflow exception enable */
+ FPSCR_ZE, /* zero divide exception enable */
+ FPSCR_XE, /* inexact exception enable */
+ FPSCR_NI /* non-IEEE mode (typically, no denormalised numbers) */
+ /* the remaining two least-significant bits keep the rounding mode */
+};
+
+/* This operation (i) sets the appropriate FPSCR bits for its
+ parameter, (ii) converts SNaN to the corresponding NaN, and (iii)
+ otherwise passes its parameter through unchanged (in particular, -0
+ and +0 stay as they were). The `obvious' way to do this is optimised
+ out by gcc. */
+#define f_wash(x) \
+ ({ double d; asm volatile ("fmul %0,%1,%2" \
+ : "=f"(d) \
+ : "f" (x), "f"((float)1.0)); d; })
+#define f_washf(x) \
+ ({ float f; asm volatile ("fmuls %0,%1,%2" \
+ : "=f"(f) \
+ : "f" (x), "f"((float)1.0)); f; })
+
+#endif /* fenv_libc.h */
diff --git a/libc/sysdeps/powerpc/fpu/fesetenv.c b/libc/sysdeps/powerpc/fpu/fesetenv.c
new file mode 100644
index 000000000..ff82dfd17
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fesetenv.c
@@ -0,0 +1,39 @@
+/* Install given floating-point environment.
+ Copyright (C) 1997,99,2000,01,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <bp-sym.h>
+
+int
+__fesetenv (const fenv_t *envp)
+{
+ fesetenv_register (*envp);
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fesetenv, __old_fesetenv)
+compat_symbol (libm, BP_SYM (__old_fesetenv), BP_SYM (fesetenv), GLIBC_2_1);
+#endif
+
+libm_hidden_ver (__fesetenv, fesetenv)
+versioned_symbol (libm, BP_SYM (__fesetenv), BP_SYM (fesetenv), GLIBC_2_2);
diff --git a/libc/sysdeps/powerpc/fpu/fesetround.c b/libc/sysdeps/powerpc/fpu/fesetround.c
new file mode 100644
index 000000000..a7efa3bbb
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fesetround.c
@@ -0,0 +1,32 @@
+/* Set current rounding direction.
+ Copyright (C) 1997, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+#undef fesetround
+int
+fesetround (int round)
+{
+ if ((unsigned int) round > 3)
+ return 1;
+ else
+ return __fesetround(round);
+}
+libm_hidden_def (fesetround)
diff --git a/libc/sysdeps/powerpc/fpu/feupdateenv.c b/libc/sysdeps/powerpc/fpu/feupdateenv.c
new file mode 100644
index 000000000..3a60d0f33
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/feupdateenv.c
@@ -0,0 +1,49 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <bp-sym.h>
+
+int
+__feupdateenv (const fenv_t *envp)
+{
+ fenv_union_t old, new;
+
+ /* Save the currently set exceptions. */
+ new.fenv = *envp;
+ old.fenv = fegetenv_register ();
+
+ /* Copy the set exceptions from `old' to `new'. */
+ new.l[1] = (new.l[1] & 0xE00000FF) | (old.l[1] & 0x1FFFFF00);
+
+ /* Atomically enable and raise (if appropriate) exceptions set in `new'. */
+ fesetenv_register (new.fenv);
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feupdateenv, __old_feupdateenv)
+compat_symbol (libm, BP_SYM (__old_feupdateenv), BP_SYM (feupdateenv), GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, BP_SYM (__feupdateenv), BP_SYM (feupdateenv), GLIBC_2_2);
diff --git a/libc/sysdeps/powerpc/fpu/fgetexcptflg.c b/libc/sysdeps/powerpc/fpu/fgetexcptflg.c
new file mode 100644
index 000000000..a652eb8e5
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fgetexcptflg.c
@@ -0,0 +1,44 @@
+/* Store current representation for exceptions.
+ Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <bp-sym.h>
+
+int
+__fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ fenv_union_t u;
+
+ /* Get the current state. */
+ u.fenv = fegetenv_register ();
+
+ /* Return (all of) it. */
+ *flagp = u.l[1] & excepts & FE_ALL_EXCEPT;
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fegetexceptflag, __old_fegetexceptflag)
+compat_symbol (libm, BP_SYM (__old_fegetexceptflag), BP_SYM (fegetexceptflag), GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, BP_SYM (__fegetexceptflag), BP_SYM (fegetexceptflag), GLIBC_2_2);
diff --git a/libc/sysdeps/powerpc/fpu/fpu_control.h b/libc/sysdeps/powerpc/fpu/fpu_control.h
new file mode 100644
index 000000000..1b2ba87c9
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fpu_control.h
@@ -0,0 +1,69 @@
+/* FPU control word definitions. PowerPC version.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H
+
+/* rounding control */
+#define _FPU_RC_NEAREST 0x00 /* RECOMMENDED */
+#define _FPU_RC_DOWN 0x03
+#define _FPU_RC_UP 0x02
+#define _FPU_RC_ZERO 0x01
+
+#define _FPU_MASK_NI 0x04 /* non-ieee mode */
+
+/* masking of interrupts */
+#define _FPU_MASK_ZM 0x10 /* zero divide */
+#define _FPU_MASK_OM 0x40 /* overflow */
+#define _FPU_MASK_UM 0x20 /* underflow */
+#define _FPU_MASK_XM 0x08 /* inexact */
+#define _FPU_MASK_IM 0x80 /* invalid operation */
+
+#define _FPU_RESERVED 0xffffff00 /* These bits are reserved are not changed. */
+
+/* The fdlibm code requires no interrupts for exceptions. */
+#define _FPU_DEFAULT 0x00000000 /* Default value. */
+
+/* IEEE: same as above, but (some) exceptions;
+ we leave the 'inexact' exception off.
+ */
+#define _FPU_IEEE 0x000000f0
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
+
+/* Macros for accessing the hardware control word. */
+#define _FPU_GETCW(__cw) ( { \
+ union { double d; fpu_control_t cw[2]; } \
+ tmp __attribute__ ((__aligned__(8))); \
+ __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0"); \
+ (__cw)=tmp.cw[1]; \
+ tmp.cw[1]; } )
+#define _FPU_SETCW(__cw) { \
+ union { double d; fpu_control_t cw[2]; } \
+ tmp __attribute__ ((__aligned__(8))); \
+ tmp.cw[0] = 0xFFF80000; /* More-or-less arbitrary; this is a QNaN. */ \
+ tmp.cw[1] = __cw; \
+ __asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (tmp.d) : "fr0"); \
+}
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* _FPU_CONTROL_H */
diff --git a/libc/sysdeps/powerpc/fpu/fraiseexcpt.c b/libc/sysdeps/powerpc/fpu/fraiseexcpt.c
new file mode 100644
index 000000000..dbe36c3d5
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fraiseexcpt.c
@@ -0,0 +1,66 @@
+/* Raise given exceptions.
+ Copyright (C) 1997,99,2000,01,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <bp-sym.h>
+
+#undef feraiseexcept
+int
+__feraiseexcept (int excepts)
+{
+ fenv_union_t u;
+
+ /* Raise exceptions represented by EXCEPTS. It is the responsibility of
+ the OS to ensure that if multiple exceptions occur they are fed back
+ to this process in the proper way; this can happen in hardware,
+ anyway (in particular, inexact with overflow or underflow). */
+
+ /* Get the current state. */
+ u.fenv = fegetenv_register ();
+
+ /* Add the exceptions */
+ u.l[1] = (u.l[1]
+ | (excepts & FPSCR_STICKY_BITS)
+ /* Turn FE_INVALID into FE_INVALID_SOFTWARE. */
+ | (excepts >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT))
+ & FE_INVALID_SOFTWARE));
+
+ /* Store the new status word (along with the rest of the environment),
+ triggering any appropriate exceptions. */
+ fesetenv_register (u.fenv);
+
+ if ((excepts & FE_INVALID)
+ /* For some reason, some PowerPC chips (the 601, in particular)
+ don't have FE_INVALID_SOFTWARE implemented. Detect this
+ case and raise FE_INVALID_SNAN instead. */
+ && !fetestexcept (FE_INVALID))
+ set_fpscr_bit (FPSCR_VXSNAN);
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feraiseexcept, __old_feraiseexcept)
+compat_symbol (libm, BP_SYM (__old_feraiseexcept), BP_SYM (feraiseexcept), GLIBC_2_1);
+#endif
+
+libm_hidden_ver (__feraiseexcept, feraiseexcept)
+versioned_symbol (libm, BP_SYM (__feraiseexcept), BP_SYM (feraiseexcept), GLIBC_2_2);
diff --git a/libc/sysdeps/powerpc/fpu/fsetexcptflg.c b/libc/sysdeps/powerpc/fpu/fsetexcptflg.c
new file mode 100644
index 000000000..eddfd55c1
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/fsetexcptflg.c
@@ -0,0 +1,60 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <bp-sym.h>
+
+int
+__fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fenv_union_t u;
+ fexcept_t flag;
+
+ /* Get the current state. */
+ u.fenv = fegetenv_register ();
+
+ /* Ignore exceptions not listed in 'excepts'. */
+ flag = *flagp & excepts;
+
+ /* Replace the exception status */
+ u.l[1] = ((u.l[1] & ~(FPSCR_STICKY_BITS & excepts))
+ | (flag & FPSCR_STICKY_BITS)
+ | (flag >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT))
+ & FE_INVALID_SOFTWARE));
+
+ /* Store the new status word (along with the rest of the environment).
+ This may cause floating-point exceptions if the restored state
+ requests it. */
+ fesetenv_register (u.fenv);
+
+ /* Deal with FE_INVALID_SOFTWARE not being implemented on some chips. */
+ if (flag & FE_INVALID)
+ feraiseexcept(FE_INVALID);
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fesetexceptflag, __old_fesetexceptflag)
+compat_symbol (libm, BP_SYM (__old_fesetexceptflag), BP_SYM (fesetexceptflag), GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, BP_SYM (__fesetexceptflag), BP_SYM (fesetexceptflag), GLIBC_2_2);
diff --git a/libc/sysdeps/powerpc/fpu/ftestexcept.c b/libc/sysdeps/powerpc/fpu/ftestexcept.c
new file mode 100644
index 000000000..64406c41d
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/ftestexcept.c
@@ -0,0 +1,33 @@
+/* Test exception in current environment.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+
+int
+fetestexcept (int excepts)
+{
+ fenv_union_t u;
+
+ /* Get the current state. */
+ u.fenv = fegetenv_register ();
+
+ /* The FE_INVALID bit is dealt with correctly by the hardware, so we can
+ just: */
+ return u.l[1] & excepts;
+}
diff --git a/libc/sysdeps/powerpc/fpu/libm-test-ulps b/libc/sysdeps/powerpc/fpu/libm-test-ulps
new file mode 100644
index 000000000..37ebc93d9
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/libm-test-ulps
@@ -0,0 +1,1328 @@
+# Begin of automatic generation
+
+# acos
+Test "acos (2e-17) == 1.57079632679489659923132169163975144":
+ildouble: 1
+ldouble: 1
+
+# asin
+Test "asin (0.75) == 0.848062078981481008052944338998418080":
+ildouble: 2
+ldouble: 2
+
+# atan2
+Test "atan2 (-0.00756827042671106339, -.001792735857538728036) == -1.80338464113663849327153994379639112":
+ildouble: 1
+ldouble: 1
+Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025":
+float: 1
+ifloat: 1
+Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025":
+float: 1
+ifloat: 1
+Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# atanh
+Test "atanh (0.75) == 0.972955074527656652552676371721589865":
+float: 1
+ifloat: 1
+
+# cabs
+Test "cabs (0.75 + 1.25 i) == 1.45773797371132511771853821938639577":
+ildouble: 1
+ldouble: 1
+
+# cacosh
+Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+
+# casin
+Test "Real part of: casin (-2 - 3 i) == -0.57065278432109940071028387968566963 - 1.9833870299165354323470769028940395 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# casinh
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 4
+ldouble: 4
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 1
+ldouble: 1
+Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# catan
+Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+float: 3
+ifloat: 3
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+float: 4
+ifloat: 4
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 4
+idouble: 4
+Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+float: 4
+ifloat: 4
+Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+float: 6
+ifloat: 6
+
+# cbrt
+Test "cbrt (-27.0) == -3.0":
+double: 1
+idouble: 1
+Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217":
+double: 1
+idouble: 1
+
+# ccos
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+float: 1
+ifloat: 1
+
+# ccosh
+Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+# cexp
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+float: 1
+ifloat: 1
+Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+ildouble: 1
+ldouble: 1
+
+# clog
+Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+float: 3
+ifloat: 3
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+ildouble: 1
+ldouble: 1
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# cos
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "cos (pi/2) == 0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "cos (16.0) == -0.9576594803233846418996372326511034717803"
+ildouble: 2
+ldouble: 2
+
+# cpow
+Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i":
+ildouble: 2
+ldouble: 2
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+Test "Real part of: cpow (2 + 0 i, 10 + 0 i) == 1024.0 + 0.0 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+# csinh
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# csqrt
+Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+
+# ctan
+Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+double: 1
+idouble: 1
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+ifloat: 1
+Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# erf
+Test "erf (1.25) == 0.922900128256458230136523481197281140":
+double: 1
+idouble: 1
+
+# erfc
+Test "erfc (0.75) == 0.288844366346484868401062165408589223":
+float: 1
+ifloat: 1
+Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
+double: 1
+idouble: 1
+Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8":
+double: 1
+idouble: 1
+
+# exp
+Test "exp (0.75) == 2.11700001661267466854536981983709561":
+ildouble: 1
+ldouble: 1
+Test "exp (50.0) == 5184705528587072464087.45332293348538":
+ildouble: 1
+ldouble: 1
+
+# exp10
+Test "exp10 (-1) == 0.1":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "exp10 (3) == 1000":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 8
+ldouble: 8
+
+# exp2
+Test "exp2 (10) == 1024":
+ildouble: 2
+ldouble: 2
+
+# expm1
+Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+double: 1
+idouble: 1
+Test "expm1 (1) == M_El - 1.0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.75, 1.25) == 1.45773797371132511771853821938639577":
+ildouble: 1
+ldouble: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+
+# j0
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# j1
+Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# jn
+Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, -1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (10, 1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+float: 1
+ifloat: 1
+ildouble: 4
+ldouble: 4
+Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+float: 4
+ifloat: 4
+Test "jn (3, -1.0) == -0.0195633539826684059189053216217515083":
+ildouble: 1
+ldouble: 1
+Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+double: 1
+idouble: 1
+Test "jn (3, 1.0) == 0.0195633539826684059189053216217515083":
+ildouble: 1
+ldouble: 1
+Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+# lgamma
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+# log10
+Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "log10 (e) == log10(e)":
+float: 1
+ifloat: 1
+
+# log1p
+Test "log1p (-0.25) == -0.287682072451780927439219005993827432":
+float: 1
+ifloat: 1
+
+# log2
+Test "log2 (e) == M_LOG2El":
+ildouble: 1
+ldouble: 1
+
+# sin
+Test "sin (16.0) == -0.2879033166650652947844562482186175296207"
+ildouble: 2
+ldouble: 2
+
+# sincos
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
+float: 1
+ifloat: 1
+
+# sinh
+Test "sinh (0.75) == 0.822316731935829980703661634446913849":
+ildouble: 1
+ldouble: 1
+
+# tan
+Test "tan (pi/4) == 1":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# tanh
+Test "tanh (-0.75) == -0.635148952387287319214434357312496495":
+ildouble: 1
+ldouble: 1
+Test "tanh (0.75) == 0.635148952387287319214434357312496495":
+ildouble: 1
+ldouble: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+ifloat: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# y0
+Test "y0 (0.75) == -0.137172769385772397522814379396581855":
+ildouble: 1
+ldouble: 1
+Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y0 (2.0) == 0.510375672649745119596606592727157873":
+double: 1
+idouble: 1
+Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# y1
+Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "y1 (1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 2
+ifloat: 2
+Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+# yn
+Test "yn (0, 0.75) == -0.137172769385772397522814379396581855":
+ildouble: 1
+ldouble: 1
+Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (0, 2.0) == 0.510375672649745119596606592727157873":
+double: 1
+idouble: 1
+Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "yn (1, 1.5) == -0.412308626973911295952829820633445323":
+float: 2
+ifloat: 2
+Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (1, 2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+idouble: 1
+Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+double: 1
+idouble: 1
+Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+float: 2
+ifloat: 2
+Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+idouble: 1
+Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+float: 1
+ifloat: 1
+Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+double: 1
+idouble: 1
+
+# Maximal error of functions:
+Function: "acos":
+ildouble: 1
+ldouble: 1
+
+Function: "acosh":
+ildouble: 1
+ldouble: 1
+
+Function: "asin":
+ildouble: 2
+ldouble: 2
+
+Function: "asinh":
+ildouble: 1
+ldouble: 1
+
+Function: "atan2":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "atanh":
+float: 1
+ifloat: 1
+
+Function: "cabs":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cacos":
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "cacos":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cacosh":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "casin":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catan":
+float: 4
+ifloat: 4
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh":
+double: 4
+idouble: 4
+
+Function: Imaginary part of "catanh":
+float: 6
+ifloat: 6
+
+Function: "cbrt":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccos":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccosh":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cexp":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cexp":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "clog":
+float: 3
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog10":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cosh":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cpow":
+double: 2
+float: 5
+idouble: 2
+ifloat: 5
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cproj":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csin":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csinh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csqrt":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csqrt":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ctan":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ctan":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ctanh":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ctanh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "erf":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "erfc":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "exp":
+ildouble: 1
+ldouble: 1
+
+Function: "exp10":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 8
+ldouble: 8
+
+Function: "exp2":
+ildouble: 2
+ldouble: 2
+
+Function: "expm1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "gamma":
+ildouble: 1
+ldouble: 1
+
+Function: "hypot":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "j0":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "jn":
+double: 3
+float: 4
+idouble: 3
+ifloat: 4
+ildouble: 4
+ldouble: 4
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: "log":
+ildouble: 1
+ldouble: 1
+
+Function: "log10":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log1p":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log2":
+ildouble: 1
+ldouble: 1
+
+Function: "pow":
+ildouble: 1
+ldouble: 1
+
+Function: "sin":
+ildouble: 1
+ldouble: 1
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "sinh":
+ildouble: 1
+ldouble: 1
+
+Function: "tan":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "tanh":
+ildouble: 1
+ldouble: 1
+
+Function: "tgamma":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+# end of automatic generation
diff --git a/libc/sysdeps/powerpc/fpu/math_ldbl.h b/libc/sysdeps/powerpc/fpu/math_ldbl.h
new file mode 100644
index 000000000..6cd6d0bdf
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/math_ldbl.h
@@ -0,0 +1,189 @@
+#ifndef _MATH_PRIVATE_H_
+#error "Never use <math_ldbl.h> directly; include <math_private.h> instead."
+#endif
+
+#include <sysdeps/ieee754/ldbl-128/math_ldbl.h>
+#include <ieee754.h>
+
+static inline void
+ldbl_extract_mantissa (int64_t *hi64, u_int64_t *lo64, int *exp, long double x)
+{
+ /* We have 105 bits of mantissa plus one implicit digit. Since
+ 106 bits are representable we use the first implicit digit for
+ the number before the decimal point and the second implicit bit
+ as bit 53 of the mantissa. */
+ unsigned long long hi, lo;
+ int ediff;
+ union ibm_extended_long_double eldbl;
+ eldbl.d = x;
+ *exp = eldbl.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS;
+
+ lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3;
+ hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1;
+ /* If the lower double is not a denomal or zero then set the hidden
+ 53rd bit. */
+ if (eldbl.ieee.exponent2 > 0x001)
+ {
+ lo |= (1ULL << 52);
+ lo = lo << 7; /* pre-shift lo to match ieee854. */
+ /* The lower double is normalized separately from the upper. We
+ may need to adjust the lower manitissa to reflect this. */
+ ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2;
+ if (ediff > 53)
+ lo = lo >> (ediff-53);
+ }
+ hi |= (1ULL << 52);
+
+ if ((eldbl.ieee.negative != eldbl.ieee.negative2)
+ && ((eldbl.ieee.exponent2 != 0) && (lo != 0LL)))
+ {
+ hi--;
+ lo = (1ULL << 60) - lo;
+ if (hi < (1ULL << 52))
+ {
+ /* we have a borrow from the hidden bit, so shift left 1. */
+ hi = (hi << 1) | (lo >> 59);
+ lo = 0xfffffffffffffffLL & (lo << 1);
+ *exp = *exp - 1;
+ }
+ }
+ *lo64 = (hi << 60) | lo;
+ *hi64 = hi >> 4;
+}
+
+static inline long double
+ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64)
+{
+ union ibm_extended_long_double u;
+ unsigned long hidden2, lzcount;
+ unsigned long long hi, lo;
+
+ u.ieee.negative = sign;
+ u.ieee.negative2 = sign;
+ u.ieee.exponent = exp + IBM_EXTENDED_LONG_DOUBLE_BIAS;
+ u.ieee.exponent2 = exp-53 + IBM_EXTENDED_LONG_DOUBLE_BIAS;
+ /* Expect 113 bits (112 bits + hidden) right justified in two longs.
+ The low order 53 bits (52 + hidden) go into the lower double */
+ lo = (lo64 >> 7)& ((1ULL << 53) - 1);
+ hidden2 = (lo64 >> 59) & 1ULL;
+ /* The high order 53 bits (52 + hidden) go into the upper double */
+ hi = (lo64 >> 60) & ((1ULL << 11) - 1);
+ hi |= (hi64 << 4);
+
+ if (lo != 0LL)
+ {
+ /* hidden2 bit of low double controls rounding of the high double.
+ If hidden2 is '1' then round up hi and adjust lo (2nd mantissa)
+ plus change the sign of the low double to compensate. */
+ if (hidden2)
+ {
+ hi++;
+ u.ieee.negative2 = !sign;
+ lo = (1ULL << 53) - lo;
+ }
+ /* The hidden bit of the lo mantissa is zero so we need to
+ normalize the it for the low double. Shift it left until the
+ hidden bit is '1' then adjust the 2nd exponent accordingly. */
+
+ if (sizeof (lo) == sizeof (long))
+ lzcount = __builtin_clzl (lo);
+ else if ((lo >> 32) != 0)
+ lzcount = __builtin_clzl ((long) (lo >> 32));
+ else
+ lzcount = __builtin_clzl ((long) lo) + 32;
+ lzcount = lzcount - 11;
+ if (lzcount > 0)
+ {
+ int expnt2 = u.ieee.exponent2 - lzcount;
+ if (expnt2 >= 1)
+ {
+ /* Not denormal. Normalize and set low exponent. */
+ lo = lo << lzcount;
+ u.ieee.exponent2 = expnt2;
+ }
+ else
+ {
+ /* Is denormal. */
+ lo = lo << (lzcount + expnt2);
+ u.ieee.exponent2 = 0;
+ }
+ }
+ }
+ else
+ {
+ u.ieee.negative2 = 0;
+ u.ieee.exponent2 = 0;
+ }
+
+ u.ieee.mantissa3 = lo & ((1ULL << 32) - 1);
+ u.ieee.mantissa2 = (lo >> 32) & ((1ULL << 20) - 1);
+ u.ieee.mantissa1 = hi & ((1ULL << 32) - 1);
+ u.ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1);
+ return u.d;
+}
+
+/* gcc generates disgusting code to pack and unpack long doubles.
+ This tells gcc that pack/unpack is really a nop. We use fr1/fr2
+ because those are the regs used to pass/return a single
+ long double arg. */
+static inline long double
+ldbl_pack (double a, double aa)
+{
+ register long double x __asm__ ("fr1");
+ register double xh __asm__ ("fr1");
+ register double xl __asm__ ("fr2");
+ xh = a;
+ xl = aa;
+ __asm__ ("" : "=f" (x) : "f" (xh), "f" (xl));
+ return x;
+}
+
+static inline void
+ldbl_unpack (long double l, double *a, double *aa)
+{
+ register long double x __asm__ ("fr1");
+ register double xh __asm__ ("fr1");
+ register double xl __asm__ ("fr2");
+ x = l;
+ __asm__ ("" : "=f" (xh), "=f" (xl) : "f" (x));
+ *a = xh;
+ *aa = xl;
+}
+
+
+/* Convert a finite long double to canonical form.
+ Does not handle +/-Inf properly. */
+static inline void
+ldbl_canonicalize (double *a, double *aa)
+{
+ double xh, xl;
+
+ xh = *a + *aa;
+ xl = (*a - xh) + *aa;
+ *a = xh;
+ *aa = xl;
+}
+
+/* Simple inline nearbyint (double) function .
+ Only works in the default rounding mode
+ but is useful in long double rounding functions. */
+static inline double
+ldbl_nearbyint (double a)
+{
+ double two52 = 0x10000000000000LL;
+
+ if (__builtin_expect ((__builtin_fabs (a) < two52), 1))
+ {
+ if (__builtin_expect ((a > 0.0), 1))
+ {
+ a += two52;
+ a -= two52;
+ }
+ else if (__builtin_expect ((a < 0.0), 1))
+ {
+ a = two52 - a;
+ a = -(a - two52);
+ }
+ }
+ return a;
+}
diff --git a/libc/sysdeps/powerpc/fpu/s_fabs.S b/libc/sysdeps/powerpc/fpu/s_fabs.S
new file mode 100644
index 000000000..ab9a3a99b
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_fabs.S
@@ -0,0 +1,37 @@
+/* Floating-point absolute value. PowerPC version.
+ Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY(__fabs)
+/* double [f1] fabs (double [f1] x); */
+ fabs fp1,fp1
+ blr
+END(__fabs)
+
+weak_alias (__fabs,fabs)
+
+/* It turns out that it's safe to use this code even for single-precision. */
+strong_alias(__fabs,__fabsf)
+weak_alias (__fabs,fabsf)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__fabs,__fabsl)
+weak_alias (__fabs,fabsl)
+#endif
diff --git a/libc/sysdeps/powerpc/fpu/s_fabsf.S b/libc/sysdeps/powerpc/fpu/s_fabsf.S
new file mode 100644
index 000000000..877c710ce
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_fabsf.S
@@ -0,0 +1 @@
+/* __fabsf is in s_fabs.S */
diff --git a/libc/sysdeps/powerpc/fpu/s_fdim.c b/libc/sysdeps/powerpc/fpu/s_fdim.c
new file mode 100644
index 000000000..2b767adda
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_fdim.c
@@ -0,0 +1,31 @@
+/* Return positive difference between arguments.
+ Copyright (C) 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+double
+__fdim (double x, double y)
+{
+ return x <= y ? 0 : x - y;
+}
+weak_alias (__fdim, fdim)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__fdim, __fdiml)
+weak_alias (__fdim, fdiml)
+#endif
diff --git a/libc/sysdeps/powerpc/fpu/s_fdimf.c b/libc/sysdeps/powerpc/fpu/s_fdimf.c
new file mode 100644
index 000000000..a27c1e403
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_fdimf.c
@@ -0,0 +1,27 @@
+/* Return positive difference between arguments.
+ Copyright (C) 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+float
+__fdimf (float x, float y)
+{
+ return x <= y ? 0 : x - y;
+}
+weak_alias (__fdimf, fdimf)
diff --git a/libc/sysdeps/powerpc/fpu/s_fmax.S b/libc/sysdeps/powerpc/fpu/s_fmax.S
new file mode 100644
index 000000000..8502c863b
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_fmax.S
@@ -0,0 +1,43 @@
+/* Floating-point maximum. PowerPC version.
+ Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY(__fmax)
+/* double [f1] fmax (double [f1] x, double [f2] y); */
+ fcmpu cr0,fp1,fp2
+ blt cr0,0f /* if x < y, neither x nor y can be NaN... */
+ bnulr+ cr0
+/* x and y are unordered, so one of x or y must be a NaN... */
+ fcmpu cr1,fp2,fp2
+ bunlr cr1
+0: fmr fp1,fp2
+ blr
+END(__fmax)
+
+weak_alias (__fmax,fmax)
+
+/* It turns out that it's safe to use this code even for single-precision. */
+strong_alias(__fmax,__fmaxf)
+weak_alias (__fmax,fmaxf)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__fmax,__fmaxl)
+weak_alias (__fmax,fmaxl)
+#endif
diff --git a/libc/sysdeps/powerpc/fpu/s_fmaxf.S b/libc/sysdeps/powerpc/fpu/s_fmaxf.S
new file mode 100644
index 000000000..3c2d62bb8
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_fmaxf.S
@@ -0,0 +1 @@
+/* __fmaxf is in s_fmax.c */
diff --git a/libc/sysdeps/powerpc/fpu/s_fmin.S b/libc/sysdeps/powerpc/fpu/s_fmin.S
new file mode 100644
index 000000000..5f788d06f
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_fmin.S
@@ -0,0 +1,43 @@
+/* Floating-point minimum. PowerPC version.
+ Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY(__fmin)
+/* double [f1] fmin (double [f1] x, double [f2] y); */
+ fcmpu cr0,fp1,fp2
+ bgt cr0,0f /* if x > y, neither x nor y can be NaN... */
+ bnulr+ cr0
+/* x and y are unordered, so one of x or y must be a NaN... */
+ fcmpu cr1,fp2,fp2
+ bunlr cr1
+0: fmr fp1,fp2
+ blr
+END(__fmin)
+
+weak_alias (__fmin,fmin)
+
+/* It turns out that it's safe to use this code even for single-precision. */
+strong_alias(__fmin,__fminf)
+weak_alias (__fmin,fminf)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__fmin,__fminl)
+weak_alias (__fmin,fminl)
+#endif
diff --git a/libc/sysdeps/powerpc/fpu/s_fminf.S b/libc/sysdeps/powerpc/fpu/s_fminf.S
new file mode 100644
index 000000000..10ab7fe53
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_fminf.S
@@ -0,0 +1 @@
+/* __fminf is in s_fmin.c */
diff --git a/libc/sysdeps/powerpc/fpu/s_isnan.c b/libc/sysdeps/powerpc/fpu/s_isnan.c
new file mode 100644
index 000000000..f3313c7b0
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_isnan.c
@@ -0,0 +1,64 @@
+/* Return 1 if argument is a NaN, else 0.
+ Copyright (C) 1997, 2000, 2002, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ugly kludge to avoid declarations. */
+#define __isnanf __Xisnanf
+#define isnanf Xisnanf
+#define __GI___isnanf __GI___Xisnanf
+
+#include "math.h"
+#include <math_ldbl_opt.h>
+#include <fenv_libc.h>
+
+#undef __isnanf
+#undef isnanf
+#undef __GI___isnanf
+
+
+/* The hidden_proto in include/math.h was obscured by the macro hackery. */
+__typeof (__isnan) __isnanf;
+hidden_proto (__isnanf)
+
+
+int
+__isnan (x)
+ double x;
+{
+ fenv_t savedstate;
+ int result;
+ savedstate = fegetenv_register ();
+ reset_fpscr_bit (FPSCR_VE);
+ result = !(x == x);
+ fesetenv_register (savedstate);
+ return result;
+}
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
+
+
+/* It turns out that the 'double' version will also always work for
+ single-precision. */
+strong_alias (__isnan, __isnanf)
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__isnan, __isnanl)
+weak_alias (__isnan, isnanl)
+#endif
diff --git a/libc/sysdeps/powerpc/fpu/s_isnanf.S b/libc/sysdeps/powerpc/fpu/s_isnanf.S
new file mode 100644
index 000000000..fc22f678a
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_isnanf.S
@@ -0,0 +1 @@
+/* __isnanf is in s_isnan.c */
diff --git a/libc/sysdeps/powerpc/fpu/s_llround.c b/libc/sysdeps/powerpc/fpu/s_llround.c
new file mode 100644
index 000000000..90f0cfb18
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_llround.c
@@ -0,0 +1,50 @@
+/* Round double value to long long int.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+/* I think that what this routine is supposed to do is round a value
+ to the nearest integer, with values exactly on the boundary rounded
+ away from zero. */
+/* This routine relies on (long long)x, when x is out of range of a long long,
+ clipping to MAX_LLONG or MIN_LLONG. */
+
+long long int
+__llround (double x)
+{
+ double xrf;
+ long long int xr;
+ xr = (long long int) x;
+ xrf = (double) xr;
+ if (x >= 0.0)
+ if (x - xrf >= 0.5 && x - xrf < 1.0 && x+1 > 0)
+ return x+1;
+ else
+ return x;
+ else
+ if (xrf - x >= 0.5 && xrf - x < 1.0 && x-1 < 0)
+ return x-1;
+ else
+ return x;
+}
+weak_alias (__llround, llround)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__llround, __llroundl)
+weak_alias (__llround, llroundl)
+#endif
diff --git a/libc/sysdeps/powerpc/fpu/s_llroundf.c b/libc/sysdeps/powerpc/fpu/s_llroundf.c
new file mode 100644
index 000000000..dd5eed9bb
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_llroundf.c
@@ -0,0 +1,46 @@
+/* Round float value to long long int.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+/* I think that what this routine is supposed to do is round a value
+ to the nearest integer, with values exactly on the boundary rounded
+ away from zero. */
+/* This routine relies on (long long)x, when x is out of range of a long long,
+ clipping to MAX_LLONG or MIN_LLONG. */
+
+long long int
+__llroundf (float x)
+{
+ float xrf;
+ long long int xr;
+ xr = (long long int) x;
+ xrf = (float) xr;
+ if (x >= 0.0)
+ if (x - xrf >= 0.5 && x - xrf < 1.0 && x+1 > 0)
+ return x+1;
+ else
+ return x;
+ else
+ if (xrf - x >= 0.5 && xrf - x < 1.0 && x-1 < 0)
+ return x-1;
+ else
+ return x;
+}
+weak_alias (__llroundf, llroundf)
diff --git a/libc/sysdeps/powerpc/fpu/s_lrintf.S b/libc/sysdeps/powerpc/fpu/s_lrintf.S
new file mode 100644
index 000000000..e24766535
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_lrintf.S
@@ -0,0 +1 @@
+/* __lrintf is in s_lrint.c */
diff --git a/libc/sysdeps/powerpc/fpu/s_rint.c b/libc/sysdeps/powerpc/fpu/s_rint.c
new file mode 100644
index 000000000..8d867f4ac
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_rint.c
@@ -0,0 +1,47 @@
+/* Round a 64-bit floating point value to the nearest integer.
+ Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+
+double
+__rint (double x)
+{
+ static const float TWO52 = 4503599627370496.0;
+
+ if (fabs (x) < TWO52)
+ {
+ if (x > 0.0)
+ {
+ x += TWO52;
+ x -= TWO52;
+ }
+ else if (x < 0.0)
+ {
+ x = TWO52 - x;
+ x = -(x - TWO52);
+ }
+ }
+
+ return x;
+}
+weak_alias (__rint, rint)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__rint, __rintl)
+weak_alias (__rint, rintl)
+#endif
diff --git a/libc/sysdeps/powerpc/fpu/s_rintf.c b/libc/sysdeps/powerpc/fpu/s_rintf.c
new file mode 100644
index 000000000..e2788ce6a
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/s_rintf.c
@@ -0,0 +1,43 @@
+/* Round a 32-bit floating point value to the nearest integer.
+ Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+
+float
+__rintf (float x)
+{
+ static const float TWO23 = 8388608.0;
+
+ if (fabsf (x) < TWO23)
+ {
+ if (x > 0.0)
+ {
+ x += TWO23;
+ x -= TWO23;
+ }
+ else if (x < 0.0)
+ {
+ x = TWO23 - x;
+ x = -(x - TWO23);
+ }
+ }
+
+ return x;
+}
+weak_alias (__rintf, rintf)
diff --git a/libc/sysdeps/powerpc/fpu/t_sqrt.c b/libc/sysdeps/powerpc/fpu/t_sqrt.c
new file mode 100644
index 000000000..c49380c0f
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/t_sqrt.c
@@ -0,0 +1,144 @@
+const float __t_sqrt[1024] = {
+0.7078,0.7064, 0.7092,0.7050, 0.7106,0.7037, 0.7119,0.7023, 0.7133,0.7010,
+0.7147,0.6996, 0.7160,0.6983, 0.7174,0.6970, 0.7187,0.6957, 0.7201,0.6943,
+0.7215,0.6930, 0.7228,0.6917, 0.7242,0.6905, 0.7255,0.6892, 0.7269,0.6879,
+0.7282,0.6866, 0.7295,0.6854, 0.7309,0.6841, 0.7322,0.6829, 0.7335,0.6816,
+0.7349,0.6804, 0.7362,0.6792, 0.7375,0.6779, 0.7388,0.6767, 0.7402,0.6755,
+0.7415,0.6743, 0.7428,0.6731, 0.7441,0.6719, 0.7454,0.6708, 0.7467,0.6696,
+0.7480,0.6684, 0.7493,0.6672, 0.7507,0.6661, 0.7520,0.6649, 0.7532,0.6638,
+0.7545,0.6627, 0.7558,0.6615, 0.7571,0.6604, 0.7584,0.6593, 0.7597,0.6582,
+0.7610,0.6570, 0.7623,0.6559, 0.7635,0.6548, 0.7648,0.6537, 0.7661,0.6527,
+0.7674,0.6516, 0.7686,0.6505, 0.7699,0.6494, 0.7712,0.6484, 0.7725,0.6473,
+0.7737,0.6462, 0.7750,0.6452, 0.7762,0.6441, 0.7775,0.6431, 0.7787,0.6421,
+0.7800,0.6410, 0.7812,0.6400, 0.7825,0.6390, 0.7837,0.6380, 0.7850,0.6370,
+0.7862,0.6359, 0.7875,0.6349, 0.7887,0.6339, 0.7900,0.6330, 0.7912,0.6320,
+0.7924,0.6310, 0.7937,0.6300, 0.7949,0.6290, 0.7961,0.6281, 0.7973,0.6271,
+0.7986,0.6261, 0.7998,0.6252, 0.8010,0.6242, 0.8022,0.6233, 0.8034,0.6223,
+0.8046,0.6214, 0.8059,0.6205, 0.8071,0.6195, 0.8083,0.6186, 0.8095,0.6177,
+0.8107,0.6168, 0.8119,0.6158, 0.8131,0.6149, 0.8143,0.6140, 0.8155,0.6131,
+0.8167,0.6122, 0.8179,0.6113, 0.8191,0.6104, 0.8203,0.6096, 0.8215,0.6087,
+0.8227,0.6078, 0.8238,0.6069, 0.8250,0.6060, 0.8262,0.6052, 0.8274,0.6043,
+0.8286,0.6035, 0.8297,0.6026, 0.8309,0.6017, 0.8321,0.6009, 0.8333,0.6000,
+0.8344,0.5992, 0.8356,0.5984, 0.8368,0.5975, 0.8379,0.5967, 0.8391,0.5959,
+0.8403,0.5950, 0.8414,0.5942, 0.8426,0.5934, 0.8437,0.5926, 0.8449,0.5918,
+0.8461,0.5910, 0.8472,0.5902, 0.8484,0.5894, 0.8495,0.5886, 0.8507,0.5878,
+0.8518,0.5870, 0.8530,0.5862, 0.8541,0.5854, 0.8552,0.5846, 0.8564,0.5838,
+0.8575,0.5831, 0.8587,0.5823, 0.8598,0.5815, 0.8609,0.5808, 0.8621,0.5800,
+0.8632,0.5792, 0.8643,0.5785, 0.8655,0.5777, 0.8666,0.5770, 0.8677,0.5762,
+0.8688,0.5755, 0.8700,0.5747, 0.8711,0.5740, 0.8722,0.5733, 0.8733,0.5725,
+0.8744,0.5718, 0.8756,0.5711, 0.8767,0.5703, 0.8778,0.5696, 0.8789,0.5689,
+0.8800,0.5682, 0.8811,0.5675, 0.8822,0.5667, 0.8833,0.5660, 0.8844,0.5653,
+0.8855,0.5646, 0.8866,0.5639, 0.8877,0.5632, 0.8888,0.5625, 0.8899,0.5618,
+0.8910,0.5611, 0.8921,0.5605, 0.8932,0.5598, 0.8943,0.5591, 0.8954,0.5584,
+0.8965,0.5577, 0.8976,0.5570, 0.8987,0.5564, 0.8998,0.5557, 0.9008,0.5550,
+0.9019,0.5544, 0.9030,0.5537, 0.9041,0.5530, 0.9052,0.5524, 0.9062,0.5517,
+0.9073,0.5511, 0.9084,0.5504, 0.9095,0.5498, 0.9105,0.5491, 0.9116,0.5485,
+0.9127,0.5478, 0.9138,0.5472, 0.9148,0.5465, 0.9159,0.5459, 0.9170,0.5453,
+0.9180,0.5446, 0.9191,0.5440, 0.9202,0.5434, 0.9212,0.5428, 0.9223,0.5421,
+0.9233,0.5415, 0.9244,0.5409, 0.9254,0.5403, 0.9265,0.5397, 0.9276,0.5391,
+0.9286,0.5384, 0.9297,0.5378, 0.9307,0.5372, 0.9318,0.5366, 0.9328,0.5360,
+0.9338,0.5354, 0.9349,0.5348, 0.9359,0.5342, 0.9370,0.5336, 0.9380,0.5330,
+0.9391,0.5324, 0.9401,0.5319, 0.9411,0.5313, 0.9422,0.5307, 0.9432,0.5301,
+0.9442,0.5295, 0.9453,0.5289, 0.9463,0.5284, 0.9473,0.5278, 0.9484,0.5272,
+0.9494,0.5266, 0.9504,0.5261, 0.9515,0.5255, 0.9525,0.5249, 0.9535,0.5244,
+0.9545,0.5238, 0.9556,0.5233, 0.9566,0.5227, 0.9576,0.5221, 0.9586,0.5216,
+0.9596,0.5210, 0.9607,0.5205, 0.9617,0.5199, 0.9627,0.5194, 0.9637,0.5188,
+0.9647,0.5183, 0.9657,0.5177, 0.9667,0.5172, 0.9677,0.5167, 0.9687,0.5161,
+0.9698,0.5156, 0.9708,0.5151, 0.9718,0.5145, 0.9728,0.5140, 0.9738,0.5135,
+0.9748,0.5129, 0.9758,0.5124, 0.9768,0.5119, 0.9778,0.5114, 0.9788,0.5108,
+0.9798,0.5103, 0.9808,0.5098, 0.9818,0.5093, 0.9828,0.5088, 0.9838,0.5083,
+0.9847,0.5077, 0.9857,0.5072, 0.9867,0.5067, 0.9877,0.5062, 0.9887,0.5057,
+0.9897,0.5052, 0.9907,0.5047, 0.9917,0.5042, 0.9926,0.5037, 0.9936,0.5032,
+0.9946,0.5027, 0.9956,0.5022, 0.9966,0.5017, 0.9976,0.5012, 0.9985,0.5007,
+0.9995,0.5002,
+1.0010,0.4995, 1.0029,0.4985, 1.0049,0.4976, 1.0068,0.4966, 1.0088,0.4957,
+1.0107,0.4947, 1.0126,0.4938, 1.0145,0.4928, 1.0165,0.4919, 1.0184,0.4910,
+1.0203,0.4901, 1.0222,0.4891, 1.0241,0.4882, 1.0260,0.4873, 1.0279,0.4864,
+1.0298,0.4855, 1.0317,0.4846, 1.0336,0.4837, 1.0355,0.4829, 1.0374,0.4820,
+1.0393,0.4811, 1.0411,0.4802, 1.0430,0.4794, 1.0449,0.4785, 1.0468,0.4777,
+1.0486,0.4768, 1.0505,0.4760, 1.0523,0.4751, 1.0542,0.4743, 1.0560,0.4735,
+1.0579,0.4726, 1.0597,0.4718, 1.0616,0.4710, 1.0634,0.4702, 1.0653,0.4694,
+1.0671,0.4686, 1.0689,0.4678, 1.0707,0.4670, 1.0726,0.4662, 1.0744,0.4654,
+1.0762,0.4646, 1.0780,0.4638, 1.0798,0.4630, 1.0816,0.4623, 1.0834,0.4615,
+1.0852,0.4607, 1.0870,0.4600, 1.0888,0.4592, 1.0906,0.4585, 1.0924,0.4577,
+1.0942,0.4570, 1.0960,0.4562, 1.0978,0.4555, 1.0995,0.4547, 1.1013,0.4540,
+1.1031,0.4533, 1.1049,0.4525, 1.1066,0.4518, 1.1084,0.4511, 1.1101,0.4504,
+1.1119,0.4497, 1.1137,0.4490, 1.1154,0.4483, 1.1172,0.4476, 1.1189,0.4469,
+1.1207,0.4462, 1.1224,0.4455, 1.1241,0.4448, 1.1259,0.4441, 1.1276,0.4434,
+1.1293,0.4427, 1.1311,0.4421, 1.1328,0.4414, 1.1345,0.4407, 1.1362,0.4401,
+1.1379,0.4394, 1.1397,0.4387, 1.1414,0.4381, 1.1431,0.4374, 1.1448,0.4368,
+1.1465,0.4361, 1.1482,0.4355, 1.1499,0.4348, 1.1516,0.4342, 1.1533,0.4335,
+1.1550,0.4329, 1.1567,0.4323, 1.1584,0.4316, 1.1600,0.4310, 1.1617,0.4304,
+1.1634,0.4298, 1.1651,0.4292, 1.1668,0.4285, 1.1684,0.4279, 1.1701,0.4273,
+1.1718,0.4267, 1.1734,0.4261, 1.1751,0.4255, 1.1768,0.4249, 1.1784,0.4243,
+1.1801,0.4237, 1.1817,0.4231, 1.1834,0.4225, 1.1850,0.4219, 1.1867,0.4213,
+1.1883,0.4208, 1.1900,0.4202, 1.1916,0.4196, 1.1932,0.4190, 1.1949,0.4185,
+1.1965,0.4179, 1.1981,0.4173, 1.1998,0.4167, 1.2014,0.4162, 1.2030,0.4156,
+1.2046,0.4151, 1.2063,0.4145, 1.2079,0.4139, 1.2095,0.4134, 1.2111,0.4128,
+1.2127,0.4123, 1.2143,0.4117, 1.2159,0.4112, 1.2175,0.4107, 1.2192,0.4101,
+1.2208,0.4096, 1.2224,0.4090, 1.2239,0.4085, 1.2255,0.4080, 1.2271,0.4075,
+1.2287,0.4069, 1.2303,0.4064, 1.2319,0.4059, 1.2335,0.4054, 1.2351,0.4048,
+1.2366,0.4043, 1.2382,0.4038, 1.2398,0.4033, 1.2414,0.4028, 1.2429,0.4023,
+1.2445,0.4018, 1.2461,0.4013, 1.2477,0.4008, 1.2492,0.4003, 1.2508,0.3998,
+1.2523,0.3993, 1.2539,0.3988, 1.2555,0.3983, 1.2570,0.3978, 1.2586,0.3973,
+1.2601,0.3968, 1.2617,0.3963, 1.2632,0.3958, 1.2648,0.3953, 1.2663,0.3949,
+1.2678,0.3944, 1.2694,0.3939, 1.2709,0.3934, 1.2725,0.3929, 1.2740,0.3925,
+1.2755,0.3920, 1.2771,0.3915, 1.2786,0.3911, 1.2801,0.3906, 1.2816,0.3901,
+1.2832,0.3897, 1.2847,0.3892, 1.2862,0.3887, 1.2877,0.3883, 1.2892,0.3878,
+1.2907,0.3874, 1.2923,0.3869, 1.2938,0.3865, 1.2953,0.3860, 1.2968,0.3856,
+1.2983,0.3851, 1.2998,0.3847, 1.3013,0.3842, 1.3028,0.3838, 1.3043,0.3834,
+1.3058,0.3829, 1.3073,0.3825, 1.3088,0.3820, 1.3103,0.3816, 1.3118,0.3812,
+1.3132,0.3807, 1.3147,0.3803, 1.3162,0.3799, 1.3177,0.3794, 1.3192,0.3790,
+1.3207,0.3786, 1.3221,0.3782, 1.3236,0.3778, 1.3251,0.3773, 1.3266,0.3769,
+1.3280,0.3765, 1.3295,0.3761, 1.3310,0.3757, 1.3324,0.3753, 1.3339,0.3748,
+1.3354,0.3744, 1.3368,0.3740, 1.3383,0.3736, 1.3397,0.3732, 1.3412,0.3728,
+1.3427,0.3724, 1.3441,0.3720, 1.3456,0.3716, 1.3470,0.3712, 1.3485,0.3708,
+1.3499,0.3704, 1.3514,0.3700, 1.3528,0.3696, 1.3542,0.3692, 1.3557,0.3688,
+1.3571,0.3684, 1.3586,0.3680, 1.3600,0.3676, 1.3614,0.3673, 1.3629,0.3669,
+1.3643,0.3665, 1.3657,0.3661, 1.3672,0.3657, 1.3686,0.3653, 1.3700,0.3650,
+1.3714,0.3646, 1.3729,0.3642, 1.3743,0.3638, 1.3757,0.3634, 1.3771,0.3631,
+1.3785,0.3627, 1.3800,0.3623, 1.3814,0.3620, 1.3828,0.3616, 1.3842,0.3612,
+1.3856,0.3609, 1.3870,0.3605, 1.3884,0.3601, 1.3898,0.3598, 1.3912,0.3594,
+1.3926,0.3590, 1.3940,0.3587, 1.3954,0.3583, 1.3968,0.3580, 1.3982,0.3576,
+1.3996,0.3572, 1.4010,0.3569, 1.4024,0.3565, 1.4038,0.3562, 1.4052,0.3558,
+1.4066,0.3555, 1.4080,0.3551, 1.4094,0.3548, 1.4108,0.3544, 1.4121,0.3541,
+1.4135,0.3537
+};
+
+
+/* Generated by: */
+#if 0
+#include <math.h>
+#include <stdio.h>
+#include <assert.h>
+
+int
+main(int argc, char **argv)
+{
+ int i, j;
+
+ printf ("const float __t_sqrt[1024] = {");
+ for (i = 0; i < 2; i++)
+ {
+ putchar('\n');
+ for (j = 0; j < 256; j++)
+ {
+ double mval = j/512.0 + 0.5;
+ double eval = i==0 ? 1.0 : 2.0;
+ double ls = sqrt(mval*eval);
+ double hs = sqrt((mval+1/512.0)*eval);
+ double as = (ls+hs)*0.5;
+ double lx = 1/(2.0*ls);
+ double hx = 1/(2.0*hs);
+ double ax = (lx+hx)*0.5;
+
+ printf("%.4f,%.4f%s",as,ax,
+ i*j==255 ? "\n" : j % 5 == 4 ? ",\n" : ", ");
+ assert((hs-ls)/as < 1/256.0);
+ assert((hx-lx)/ax < 1/256.0);
+ }
+ }
+ printf ("};\n");
+ return 0;
+}
+#endif /* 0 */
diff --git a/libc/sysdeps/powerpc/fpu/w_sqrt.c b/libc/sysdeps/powerpc/fpu/w_sqrt.c
new file mode 100644
index 000000000..806d8e490
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/w_sqrt.c
@@ -0,0 +1,51 @@
+/* Double-precision floating point square root wrapper.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+#include <fenv_libc.h>
+
+#ifdef __STDC__
+double
+__sqrt (double x) /* wrapper sqrt */
+#else
+double
+__sqrt (x) /* wrapper sqrt */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_sqrt (x);
+#else
+ double z;
+ z = __ieee754_sqrt (x);
+ if (_LIB_VERSION == _IEEE_ || (x != x))
+ return z;
+
+ if (x < 0.0)
+ return __kernel_standard (x, x, 26); /* sqrt(negative) */
+ else
+ return z;
+#endif
+}
+
+weak_alias (__sqrt, sqrt)
+#ifdef NO_LONG_DOUBLE
+ strong_alias (__sqrt, __sqrtl) weak_alias (__sqrt, sqrtl)
+#endif
diff --git a/libc/sysdeps/powerpc/fpu/w_sqrtf.c b/libc/sysdeps/powerpc/fpu/w_sqrtf.c
new file mode 100644
index 000000000..54b4f3be7
--- /dev/null
+++ b/libc/sysdeps/powerpc/fpu/w_sqrtf.c
@@ -0,0 +1,53 @@
+/* Single-precision floating point square root wrapper.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+#include "math_private.h"
+#include <fenv_libc.h>
+
+#include <sysdep.h>
+#include <ldsodefs.h>
+
+#ifdef __STDC__
+float
+__sqrtf (float x) /* wrapper sqrtf */
+#else
+float
+__sqrtf (x) /* wrapper sqrtf */
+ float x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_sqrtf (x);
+#else
+ float z;
+ z = __ieee754_sqrtf (x);
+
+ if (_LIB_VERSION == _IEEE_ || (x != x))
+ return z;
+
+ if (x < (float) 0.0)
+ /* sqrtf(negative) */
+ return (float) __kernel_standard ((double) x, (double) x, 126);
+ else
+ return z;
+#endif
+}
+
+weak_alias (__sqrtf, sqrtf)
diff --git a/libc/sysdeps/powerpc/gccframe.h b/libc/sysdeps/powerpc/gccframe.h
new file mode 100644
index 000000000..d08e80f18
--- /dev/null
+++ b/libc/sysdeps/powerpc/gccframe.h
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. powerpc version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define DWARF_FRAME_REGISTERS 77
+
+#include <sysdeps/generic/gccframe.h>
diff --git a/libc/sysdeps/powerpc/jmpbuf-offsets.h b/libc/sysdeps/powerpc/jmpbuf-offsets.h
new file mode 100644
index 000000000..5f74a85af
--- /dev/null
+++ b/libc/sysdeps/powerpc/jmpbuf-offsets.h
@@ -0,0 +1,39 @@
+/* Private macros for accessing __jmp_buf contents. PowerPC version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define JB_GPR1 0 /* Also known as the stack pointer */
+#define JB_GPR2 1
+#define JB_LR 2 /* The address we will return to */
+#if __WORDSIZE == 64
+# define JB_GPRS 3 /* GPRs 14 through 31 are saved, 18*2 words total. */
+# define JB_CR 21 /* Condition code registers with the VRSAVE at */
+ /* offset 172 (low half of the double word. */
+# define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total. */
+# define JB_SIZE (64 * 8) /* As per PPC64-VMX ABI. */
+# define JB_VRSAVE 21 /* VRSAVE shares a double word with the CR at offset */
+ /* 168 (high half of the double word). */
+# define JB_VRS 40 /* VRs 20 through 31 are saved, 12*4 words total. */
+#else
+# define JB_GPRS 3 /* GPRs 14 through 31 are saved, 18 in total. */
+# define JB_CR 21 /* Condition code registers. */
+# define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total. */
+# define JB_SIZE ((64 + (12 * 4)) * 4)
+# define JB_VRSAVE 62
+# define JB_VRS 64
+#endif
diff --git a/libc/sysdeps/powerpc/jmpbuf-unwind.h b/libc/sysdeps/powerpc/jmpbuf-unwind.h
new file mode 100644
index 000000000..20bab7560
--- /dev/null
+++ b/libc/sysdeps/powerpc/jmpbuf-unwind.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <stdint.h>
+#include <unwind.h>
+#include <sysdep.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame
+ containing a local variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \
+ ((void *) (address) < (void *) demangle ((jmpbuf)[JB_GPR1]))
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+static inline uintptr_t __attribute__ ((unused))
+_jmpbuf_sp (__jmp_buf regs)
+{
+ uintptr_t sp = regs[JB_GPR1];
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (sp);
+#endif
+ return sp;
+}
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
+
+/* We use the normal longjmp for unwinding. */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libc/sysdeps/powerpc/longjmp.c b/libc/sysdeps/powerpc/longjmp.c
new file mode 100644
index 000000000..0345492c2
--- /dev/null
+++ b/libc/sysdeps/powerpc/longjmp.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 1991,92,94,95,97,98,2000,2002,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Versioned copy of sysdeps/generic/longjmp.c modified for AltiVec support. */
+
+#include <shlib-compat.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <signal.h>
+
+extern void __vmx__longjmp (__jmp_buf __env, int __val)
+ __attribute__ ((noreturn));
+extern void __vmx__libc_longjmp (sigjmp_buf env, int val)
+ __attribute__ ((noreturn));
+libc_hidden_proto (__vmx__libc_longjmp)
+
+/* Set the signal mask to the one specified in ENV, and jump
+ to the position specified in ENV, causing the setjmp
+ call there to return VAL, or 1 if VAL is 0. */
+void
+__vmx__libc_siglongjmp (sigjmp_buf env, int val)
+{
+ /* Perform any cleanups needed by the frames being unwound. */
+ _longjmp_unwind (env, val);
+
+ if (env[0].__mask_was_saved)
+ /* Restore the saved signal mask. */
+ (void) __sigprocmask (SIG_SETMASK, &env[0].__saved_mask,
+ (sigset_t *) NULL);
+
+ /* Call the machine-dependent function to restore machine state. */
+ __vmx__longjmp (env[0].__jmpbuf, val ?: 1);
+}
+
+strong_alias (__vmx__libc_siglongjmp, __vmx__libc_longjmp)
+libc_hidden_def (__vmx__libc_longjmp)
+weak_alias (__vmx__libc_siglongjmp, __vmx_longjmp)
+weak_alias (__vmx__libc_siglongjmp, __vmxlongjmp)
+weak_alias (__vmx__libc_siglongjmp, __vmxsiglongjmp)
+
+
+default_symbol_version (__vmx__libc_longjmp, __libc_longjmp, GLIBC_PRIVATE);
+default_symbol_version (__vmx__libc_siglongjmp, __libc_siglongjmp, GLIBC_PRIVATE);
+default_symbol_version (__vmx_longjmp, _longjmp, GLIBC_2.3.4);
+default_symbol_version (__vmxlongjmp, longjmp, GLIBC_2.3.4);
+default_symbol_version (__vmxsiglongjmp, siglongjmp, GLIBC_2.3.4);
diff --git a/libc/sysdeps/powerpc/machine-gmon.h b/libc/sysdeps/powerpc/machine-gmon.h
new file mode 100644
index 000000000..b0f3d8130
--- /dev/null
+++ b/libc/sysdeps/powerpc/machine-gmon.h
@@ -0,0 +1,31 @@
+/* PowerPC-specific implementation of profiling support.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* We need a special version of the `mcount' function because it has
+ to preserve more registers than your usual function. */
+
+void __mcount_internal (unsigned long frompc, unsigned long selfpc);
+
+#define _MCOUNT_DECL(frompc, selfpc) \
+void __mcount_internal (unsigned long frompc, unsigned long selfpc)
+
+
+/* Define MCOUNT as empty since we have the implementation in another
+ file. */
+#define MCOUNT
diff --git a/libc/sysdeps/powerpc/memusage.h b/libc/sysdeps/powerpc/memusage.h
new file mode 100644
index 000000000..715bf860c
--- /dev/null
+++ b/libc/sysdeps/powerpc/memusage.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("%r1"); stack_ptr; })
+
+#include <sysdeps/generic/memusage.h>
diff --git a/libc/sysdeps/powerpc/mp_clz_tab.c b/libc/sysdeps/powerpc/mp_clz_tab.c
new file mode 100644
index 000000000..4b5f29bfe
--- /dev/null
+++ b/libc/sysdeps/powerpc/mp_clz_tab.c
@@ -0,0 +1 @@
+/* __clz_tab not needed on powerpc. */
diff --git a/libc/sysdeps/powerpc/novmx-longjmp.c b/libc/sysdeps/powerpc/novmx-longjmp.c
new file mode 100644
index 000000000..b4a6b56aa
--- /dev/null
+++ b/libc/sysdeps/powerpc/novmx-longjmp.c
@@ -0,0 +1,64 @@
+/* Copyright (C) 1991,92,94,95,97,98,2000,2002,2003,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copy of sysdeps/generic/longjmp.c modified for backward compatibility
+ with old non AltiVec/VMX longjmp. */
+
+#include <bits/wordsize.h>
+#include <shlib-compat.h>
+#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+# include <stddef.h>
+# include <novmxsetjmp.h>
+# include <signal.h>
+
+
+/* Set the signal mask to the one specified in ENV, and jump
+ to the position specified in ENV, causing the setjmp
+ call there to return VAL, or 1 if VAL is 0. */
+void
+__novmx__libc_siglongjmp (__novmx__sigjmp_buf env, int val)
+{
+ /* Perform any cleanups needed by the frames being unwound. */
+ _longjmp_unwind (env, val);
+
+ if (env[0].__mask_was_saved)
+ /* Restore the saved signal mask. */
+ (void) __sigprocmask (SIG_SETMASK, &env[0].__saved_mask,
+ (sigset_t *) NULL);
+
+ /* Call the machine-dependent function to restore machine state. */
+ __novmx__longjmp (env[0].__jmpbuf, val ?: 1);
+}
+
+strong_alias (__novmx__libc_siglongjmp, __novmx__libc_longjmp)
+libc_hidden_def (__novmx__libc_longjmp)
+weak_alias (__novmx__libc_siglongjmp, __novmx_longjmp)
+weak_alias (__novmx__libc_siglongjmp, __novmxlongjmp)
+weak_alias (__novmx__libc_siglongjmp, __novmxsiglongjmp)
+
+# if __WORDSIZE == 64
+symbol_version (__novmx_longjmp,_longjmp,GLIBC_2.3);
+symbol_version (__novmxlongjmp,longjmp,GLIBC_2.3);
+symbol_version (__novmxsiglongjmp,siglongjmp,GLIBC_2.3);
+# else
+symbol_version (__novmx_longjmp,_longjmp,GLIBC_2.0);
+symbol_version (__novmxlongjmp,longjmp,GLIBC_2.0);
+symbol_version (__novmxsiglongjmp,siglongjmp,GLIBC_2.0);
+# endif
+#endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)) */
diff --git a/libc/sysdeps/powerpc/novmx-sigjmp.c b/libc/sysdeps/powerpc/novmx-sigjmp.c
new file mode 100644
index 000000000..f5d487f52
--- /dev/null
+++ b/libc/sysdeps/powerpc/novmx-sigjmp.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1992, 1994, 1997, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copy of sysdeps/generic/sigjmp.c modified for backward compatibility
+ with old non AltiVec/VMX setjmp. */
+
+#include <bits/wordsize.h>
+#include <shlib-compat.h>
+#if !defined NOT_IN_libc && defined SHARED
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+# include <stddef.h>
+# include <novmxsetjmp.h>
+# include <signal.h>
+
+/* This function is called by the `sigsetjmp' macro
+ before doing a `__setjmp' on ENV[0].__jmpbuf.
+ Always return zero. */
+
+int
+__novmx__sigjmp_save (__novmx__sigjmp_buf env, int savemask)
+{
+ env[0].__mask_was_saved = (savemask &&
+ __sigprocmask (SIG_BLOCK, (sigset_t *) NULL,
+ &env[0].__saved_mask) == 0);
+
+ return 0;
+}
+
+# endif /* SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) */
+#endif /* !NOT_IN_libc && SHARED */
diff --git a/libc/sysdeps/powerpc/novmxsetjmp.h b/libc/sysdeps/powerpc/novmxsetjmp.h
new file mode 100644
index 000000000..1c46a77db
--- /dev/null
+++ b/libc/sysdeps/powerpc/novmxsetjmp.h
@@ -0,0 +1,133 @@
+/* Copyright (C) 1991-1999, 2001, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copied from setjmp/setjmp.h, powerpc/bits/setjmp.h and modified
+ appropriately to keep backward compatible with setjmp without
+ AltiVec/VMX support.
+
+ This file is not exported and the interfaces are private to libc. */
+
+#ifndef __NOVMX_SETJMP_H
+#define __NOVMX_SETJMP_H 1
+
+#include <bits/wordsize.h>
+
+/* The following definitions are needed by ASM implementations of the old
+ (novmx) __longjmp/__setjmp functions. */
+
+# define JB_GPR1 0 /* Also known as the stack pointer */
+# define JB_GPR2 1
+# define JB_LR 2 /* The address we will return to */
+# if __WORDSIZE == 64
+# define JB_GPRS 3 /* GPRs 14 through 31 are saved, 18*2 words total. */
+# define JB_CR 21 /* Condition code registers. */
+# define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total. */
+# define JB_SIZE (40 * 8)
+# else
+# define JB_GPRS 3 /* GPRs 14 through 31 are saved, 18 in total. */
+# define JB_CR 21 /* Condition code registers. */
+# define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total. */
+# define JB_SIZE (58 * 4)
+# endif
+
+#ifndef _ASM
+/* The following definitions are needed by the novmx* implementations of
+ setjmp/longjmp/sigsetjmp/etc that wrapper __setjmp/__longjmp. */
+
+# if __WORDSIZE == 64
+typedef long int __jmp_buf[40];
+# else
+typedef long int __jmp_buf[58];
+# endif
+
+# include <bits/sigset.h> /* Get `__sigset_t'. */
+
+/* Calling environment, plus possibly a saved signal mask. */
+typedef struct __novmx__jmp_buf_tag
+ {
+ /* NOTE: The machine-dependent definitions of `__sigsetjmp'
+ assume that a `jmp_buf' begins with a `__jmp_buf' and that
+ `__mask_was_saved' follows it. Do not move these members
+ or add others before it. */
+ __jmp_buf __jmpbuf; /* Calling environment. */
+ int __mask_was_saved; /* Saved the signal mask? */
+ __sigset_t __saved_mask; /* Saved signal mask. */
+ } __novmx__jmp_buf[1];
+
+
+/* Store the calling environment in ENV, also saving the signal mask.
+ Return 0. */
+extern int __novmxsetjmp (__novmx__jmp_buf __env);
+
+/* Store the calling environment in ENV, also saving the
+ signal mask if SAVEMASK is nonzero. Return 0.
+ This is the internal name for `sigsetjmp'. */
+extern int __novmx__sigsetjmp (struct __novmx__jmp_buf_tag __env[1],
+ int __savemask);
+
+/* Store the calling environment in ENV, not saving the signal mask.
+ Return 0. */
+extern int __novmx_setjmp (struct __novmx__jmp_buf_tag __env[1]);
+
+/* Jump to the environment saved in ENV, making the
+ `setjmp' call there return VAL, or 1 if VAL is 0. */
+extern void __novmxlongjmp (struct __novmx__jmp_buf_tag __env[1], int __val)
+ __attribute__ ((__noreturn__));
+
+/* Same. Usually `_longjmp' is used with `_setjmp', which does not save
+ the signal mask. But it is how ENV was saved that determines whether
+ `longjmp' restores the mask; `_longjmp' is just an alias. */
+extern void __novmx_longjmp (struct __novmx__jmp_buf_tag __env[1], int __val)
+ __attribute__ ((__noreturn__));
+
+/* Use the same type for `jmp_buf' and `sigjmp_buf'.
+ The `__mask_was_saved' flag determines whether
+ or not `longjmp' will restore the signal mask. */
+typedef struct __novmx__jmp_buf_tag __novmx__sigjmp_buf[1];
+
+/* Jump to the environment saved in ENV, making the
+ sigsetjmp call there return VAL, or 1 if VAL is 0.
+ Restore the signal mask if that sigsetjmp call saved it.
+ This is just an alias `longjmp'. */
+extern void __novmxsiglongjmp (__novmx__sigjmp_buf __env, int __val)
+ __attribute__ ((__noreturn__));
+
+/* Internal machine-dependent function to restore context sans signal mask. */
+extern void __novmx__longjmp (__jmp_buf __env, int __val)
+ __attribute__ ((__noreturn__));
+
+/* Internal function to possibly save the current mask of blocked signals
+ in ENV, and always set the flag saying whether or not it was saved.
+ This is used by the machine-dependent definition of `__sigsetjmp'.
+ Always returns zero, for convenience. */
+extern int __novmx__sigjmp_save (__novmx__jmp_buf __env, int __savemask);
+
+extern void _longjmp_unwind (__novmx__jmp_buf env, int val);
+
+extern void __novmx__libc_siglongjmp (__novmx__sigjmp_buf env, int val)
+ __attribute__ ((noreturn));
+
+extern void __novmx__libc_longjmp (__novmx__sigjmp_buf env, int val)
+ __attribute__ ((noreturn));
+
+libc_hidden_proto (__novmx__libc_longjmp)
+libc_hidden_proto (__novmx_setjmp)
+libc_hidden_proto (__novmx__sigsetjmp)
+#endif /* !_ASM */
+
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/Implies b/libc/sysdeps/powerpc/powerpc32/Implies
new file mode 100644
index 000000000..39a34c5f5
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/Implies
@@ -0,0 +1 @@
+wordsize-32
diff --git a/libc/sysdeps/powerpc/powerpc32/Makefile b/libc/sysdeps/powerpc/powerpc32/Makefile
new file mode 100644
index 000000000..1d58a063d
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/Makefile
@@ -0,0 +1,44 @@
+# Powerpc32 specific build options.
+
+ifeq ($(with-fp),no)
++cflags += -msoft-float
+sysdep-LDFLAGS += -msoft-float
+endif
+
+ifeq ($(subdir),misc)
+sysdep_routines += gprsave0 gprrest0 gprsave1 gprrest1
+endif
+
+# On PPC, -fpic works until the GOT contains 32768 bytes, and possibly
+# more depending on how clever the linker is. Each GOT entry takes 4 bytes,
+# so that's at least 8192 entries. Since libc only uses about 2000 entries,
+# we want to use -fpic, because this generates fewer relocs.
+ifeq (yes,$(build-shared))
+pic-ccflag = -fpic
+endif
+
+ifeq ($(subdir),csu)
+ifneq ($(elf),no)
+# The initfini generation code doesn't work in the presence of -fPIC, so
+# we use -fpic instead which is much better.
+CFLAGS-initfini.s += -fpic -O1
+
+# There is no benefit to using sdata for these objects, and the user
+# of the library should be able to control what goes into sdata.
+CFLAGS-init.o = -G0
+CFLAGS-gmon-start.o = -G0
+endif
+ifeq (yes,$(build-shared))
+# Compatibility
+ifeq (yes,$(have-protected))
+CPPFLAGS-libgcc-compat.S = -DHAVE_DOT_HIDDEN
+endif
+sysdep_routines += libgcc-compat
+shared-only-routines += libgcc-compat
+endif
+endif
+
+ifeq ($(subdir),elf)
+# extra shared linker files to link only into dl-allobjs.so
+sysdep-rtld-routines += dl-start
+endif
diff --git a/libc/sysdeps/powerpc/powerpc32/Versions b/libc/sysdeps/powerpc/powerpc32/Versions
new file mode 100644
index 000000000..3635c4a4a
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/Versions
@@ -0,0 +1,34 @@
+libc {
+ GLIBC_2.0 {
+ # Functions from libgcc.
+ __divdi3; __moddi3; __udivdi3; __umoddi3;
+ __cmpdi2; __ucmpdi2;
+ __ashldi3; __ashrdi3; __lshrdi3;
+ __fixdfdi; __fixunsdfdi;
+ __fixsfdi; __fixunssfdi;
+ __floatdidf; __floatdisf;
+ }
+}
+
+libm {
+ GLIBC_2.2 {
+ # Special functions to save and restore registers used by the
+ # runtime libraries.
+ _restgpr0_13; _restgpr0_14; _restgpr0_15; _restgpr0_16; _restgpr0_17;
+ _restgpr0_18; _restgpr0_19; _restgpr0_20; _restgpr0_21; _restgpr0_22;
+ _restgpr0_22; _restgpr0_23; _restgpr0_24; _restgpr0_25; _restgpr0_26;
+ _restgpr0_27; _restgpr0_28; _restgpr0_29; _restgpr0_30; _restgpr0_31;
+ _savegpr0_13; _savegpr0_14; _savegpr0_15; _savegpr0_16; _savegpr0_17;
+ _savegpr0_18; _savegpr0_19; _savegpr0_20; _savegpr0_21; _savegpr0_22;
+ _savegpr0_22; _savegpr0_23; _savegpr0_24; _savegpr0_25; _savegpr0_26;
+ _savegpr0_27; _savegpr0_28; _savegpr0_29; _savegpr0_30; _savegpr0_31;
+ _restgpr1_13; _restgpr1_14; _restgpr1_15; _restgpr1_16; _restgpr1_17;
+ _restgpr1_18; _restgpr1_19; _restgpr1_20; _restgpr1_21; _restgpr1_22;
+ _restgpr1_22; _restgpr1_23; _restgpr1_24; _restgpr1_25; _restgpr1_26;
+ _restgpr1_27; _restgpr1_28; _restgpr1_29; _restgpr1_30; _restgpr1_31;
+ _savegpr1_13; _savegpr1_14; _savegpr1_15; _savegpr1_16; _savegpr1_17;
+ _savegpr1_18; _savegpr1_19; _savegpr1_20; _savegpr1_21; _savegpr1_22;
+ _savegpr1_22; _savegpr1_23; _savegpr1_24; _savegpr1_25; _savegpr1_26;
+ _savegpr1_27; _savegpr1_28; _savegpr1_29; _savegpr1_30; _savegpr1_31;
+ }
+}
diff --git a/libc/sysdeps/powerpc/powerpc32/__longjmp-common.S b/libc/sysdeps/powerpc/powerpc32/__longjmp-common.S
new file mode 100644
index 000000000..411b6a20c
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/__longjmp-common.S
@@ -0,0 +1,63 @@
+/* longjmp for PowerPC.
+ Copyright (C) 1995-1997, 1999-2001, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ASM
+#ifdef __NO_VMX__
+# include <novmxsetjmp.h>
+#else
+# include <jmpbuf-offsets.h>
+#endif
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+ENTRY (BP_SYM (__longjmp))
+ CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
+
+ lwz r1,(JB_GPR1*4)(r3)
+ lwz r0,(JB_LR*4)(r3)
+ lwz r14,((JB_GPRS+0)*4)(r3)
+ lwz r15,((JB_GPRS+1)*4)(r3)
+ lwz r16,((JB_GPRS+2)*4)(r3)
+ lwz r17,((JB_GPRS+3)*4)(r3)
+ lwz r18,((JB_GPRS+4)*4)(r3)
+ lwz r19,((JB_GPRS+5)*4)(r3)
+ lwz r20,((JB_GPRS+6)*4)(r3)
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (r0, r25)
+ PTR_DEMANGLE2 (r1, r25)
+#endif
+ mtlr r0
+ lwz r21,((JB_GPRS+7)*4)(r3)
+ lwz r22,((JB_GPRS+8)*4)(r3)
+ lwz r0,(JB_CR*4)(r3)
+ lwz r23,((JB_GPRS+9)*4)(r3)
+ lwz r24,((JB_GPRS+10)*4)(r3)
+ lwz r25,((JB_GPRS+11)*4)(r3)
+ mtcrf 0xFF,r0
+ lwz r26,((JB_GPRS+12)*4)(r3)
+ lwz r27,((JB_GPRS+13)*4)(r3)
+ lwz r28,((JB_GPRS+14)*4)(r3)
+ lwz r29,((JB_GPRS+15)*4)(r3)
+ lwz r30,((JB_GPRS+16)*4)(r3)
+ lwz r31,((JB_GPRS+17)*4)(r3)
+ mr r3,r4
+ blr
+END (BP_SYM (__longjmp))
diff --git a/libc/sysdeps/powerpc/powerpc32/__longjmp.S b/libc/sysdeps/powerpc/powerpc32/__longjmp.S
new file mode 100644
index 000000000..5a050f1e7
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/__longjmp.S
@@ -0,0 +1,39 @@
+/* AltiVec/VMX (new) version of __longjmp for PowerPC.
+ Copyright (C) 1995-1997,1999,2000,2003,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <libc-symbols.h>
+#include <shlib-compat.h>
+
+#if defined NOT_IN_libc
+/* Build a non-versioned object for rtld-*. */
+# include "__longjmp-common.S"
+
+#else /* !NOT_IN_libc */
+strong_alias (__vmx__longjmp, __longjmp);
+# define __longjmp __vmx__longjmp
+# include "__longjmp-common.S"
+
+# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+# define __NO_VMX__
+# undef JB_SIZE
+# undef __longjmp
+# define __longjmp __novmx__longjmp
+# include "__longjmp-common.S"
+# endif
+#endif /* !NOT_IN_libc */
diff --git a/libc/sysdeps/powerpc/powerpc32/add_n.S b/libc/sysdeps/powerpc/powerpc32/add_n.S
new file mode 100644
index 000000000..89e1a30c1
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/add_n.S
@@ -0,0 +1,77 @@
+/* Add two limb vectors of equal, non-zero length for PowerPC.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ mp_size_t size)
+ Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1. */
+
+/* Note on optimisation: This code is optimal for the 601. Almost every other
+ possible 2-unrolled inner loop will not be. Also, watch out for the
+ alignment... */
+
+EALIGN (BP_SYM (__mpn_add_n), 3, 0)
+
+#if __BOUNDED_POINTERS__
+ slwi r10,r6,2 /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
+ CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
+ CHECK_BOUNDS_BOTH_WIDE (r5, r8, r9, r10)
+#endif
+/* Set up for loop below. */
+ mtcrf 0x01,r6
+ srwi. r7,r6,1
+ li r10,0
+ mtctr r7
+ bt 31,L(2)
+
+/* Clear the carry. */
+ addic r0,r0,0
+/* Adjust pointers for loop. */
+ addi r3,r3,-4
+ addi r4,r4,-4
+ addi r5,r5,-4
+ b L(0)
+
+L(2): lwz r7,0(r5)
+ lwz r6,0(r4)
+ addc r6,r6,r7
+ stw r6,0(r3)
+ beq L(1)
+
+/* The loop. */
+
+/* Align start of loop to an odd word boundary to guarantee that the
+ last two words can be fetched in one access (for 601). */
+L(0): lwz r9,4(r4)
+ lwz r8,4(r5)
+ lwzu r6,8(r4)
+ lwzu r7,8(r5)
+ adde r8,r9,r8
+ stw r8,4(r3)
+ adde r6,r6,r7
+ stwu r6,8(r3)
+ bdnz L(0)
+/* Return the carry. */
+L(1): addze r3,r10
+ blr
+END (BP_SYM (__mpn_add_n))
diff --git a/libc/sysdeps/powerpc/powerpc32/addmul_1.S b/libc/sysdeps/powerpc/powerpc32/addmul_1.S
new file mode 100644
index 000000000..98fad2b8e
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/addmul_1.S
@@ -0,0 +1,56 @@
+/* Multiply a limb vector by a single limb, for PowerPC.
+ Copyright (C) 1993-1995, 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate res+s1*s2 and put result back in res; return carry. */
+ENTRY (BP_SYM (__mpn_addmul_1))
+#if __BOUNDED_POINTERS__
+ slwi r10,r5,2 /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
+ CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
+#endif
+ mtctr r5
+
+ lwz r0,0(r4)
+ mullw r7,r0,r6
+ mulhwu r10,r0,r6
+ lwz r9,0(r3)
+ addc r8,r7,r9
+ addi r3,r3,-4 /* adjust res_ptr */
+ bdz L(1)
+
+L(0): lwzu r0,4(r4)
+ stwu r8,4(r3)
+ mullw r8,r0,r6
+ adde r7,r8,r10
+ mulhwu r10,r0,r6
+ lwz r9,4(r3)
+ addze r10,r10
+ addc r8,r7,r9
+ bdnz L(0)
+
+L(1): stw r8,4(r3)
+ addze r3,r10
+ blr
+END (BP_SYM (__mpn_addmul_1))
diff --git a/libc/sysdeps/powerpc/powerpc32/backtrace.c b/libc/sysdeps/powerpc/powerpc32/backtrace.c
new file mode 100644
index 000000000..e7e12544c
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/backtrace.c
@@ -0,0 +1,67 @@
+/* Return backtrace of current program state.
+ Copyright (C) 1998, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <execinfo.h>
+#include <stddef.h>
+#include <bp-checks.h>
+
+/* This is the stack layout we see with every stack frame.
+ Note that every routine is required by the ABI to lay out the stack
+ like this.
+
+ +----------------+ +-----------------+
+ %r1 -> | %r1 last frame--------> | %r1 last frame--->... --> NULL
+ | | | |
+ | (unused) | | return address |
+ +----------------+ +-----------------+
+*/
+struct layout
+{
+ struct layout *__unbounded next;
+ void *__unbounded return_address;
+};
+
+int
+__backtrace (void **array, int size)
+{
+ struct layout *current;
+ int count;
+
+ /* Force gcc to spill LR. */
+ asm volatile ("" : "=l"(current));
+
+ /* Get the address on top-of-stack. */
+ asm volatile ("lwz %0,0(1)" : "=r"(current));
+ current = BOUNDED_1 (current);
+
+ for ( count = 0;
+ current != NULL && count < size;
+ current = BOUNDED_1 (current->next), count++)
+ array[count] = current->return_address;
+
+ /* It's possible the second-last stack frame can't return
+ (that is, it's __libc_start_main), in which case
+ the CRT startup code will have set its LR to 'NULL'. */
+ if (count > 0 && array[count-1] == NULL)
+ count--;
+
+ return count;
+}
+weak_alias (__backtrace, backtrace)
+libc_hidden_def (__backtrace)
diff --git a/libc/sysdeps/powerpc/powerpc32/bits/atomic.h b/libc/sysdeps/powerpc/powerpc32/bits/atomic.h
new file mode 100644
index 000000000..6fcc669fb
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/bits/atomic.h
@@ -0,0 +1,118 @@
+/* Atomic operations. PowerPC32 version.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * The 32-bit exchange_bool is different on powerpc64 because the subf
+ * does signed 64-bit arthmatic while the lwarx is 32-bit unsigned
+ * (a load word and zero (high 32) form). So powerpc64 has a slightly
+ * different version in sysdeps/powerpc/powerpc64/bits/atomic.h.
+ */
+# define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \
+({ \
+ unsigned int __tmp; \
+ __asm __volatile ( \
+ "1: lwarx %0,0,%1\n" \
+ " subf. %0,%2,%0\n" \
+ " bne 2f\n" \
+ " stwcx. %3,0,%1\n" \
+ " bne- 1b\n" \
+ "2: " __ARCH_ACQ_INSTR \
+ : "=&r" (__tmp) \
+ : "b" (mem), "r" (oldval), "r" (newval) \
+ : "cr0", "memory"); \
+ __tmp != 0; \
+})
+
+# define __arch_compare_and_exchange_bool_32_rel(mem, newval, oldval) \
+({ \
+ unsigned int __tmp; \
+ __asm __volatile (__ARCH_REL_INSTR "\n" \
+ "1: lwarx %0,0,%1\n" \
+ " subf. %0,%2,%0\n" \
+ " bne 2f\n" \
+ " stwcx. %3,0,%1\n" \
+ " bne- 1b\n" \
+ "2: " \
+ : "=&r" (__tmp) \
+ : "b" (mem), "r" (oldval), "r" (newval) \
+ : "cr0", "memory"); \
+ __tmp != 0; \
+})
+
+/* Powerpc32 processors don't implement the 64-bit (doubleword) forms of
+ load and reserve (ldarx) and store conditional (stdcx.) instructions.
+ So for powerpc32 we stub out the 64-bit forms. */
+# define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \
+ (abort (), 0)
+
+# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+
+# define __arch_compare_and_exchange_bool_64_rel(mem, newval, oldval) \
+ (abort (), 0)
+
+# define __arch_compare_and_exchange_val_64_rel(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+
+# define __arch_atomic_exchange_64_acq(mem, value) \
+ ({ abort (); (*mem) = (value); })
+
+# define __arch_atomic_exchange_64_rel(mem, value) \
+ ({ abort (); (*mem) = (value); })
+
+# define __arch_atomic_exchange_and_add_64(mem, value) \
+ ({ abort (); (*mem) = (value); })
+
+# define __arch_atomic_increment_val_64(mem) \
+ ({ abort (); (*mem)++; })
+
+# define __arch_atomic_decrement_val_64(mem) \
+ ({ abort (); (*mem)--; })
+
+# define __arch_atomic_decrement_if_positive_64(mem) \
+ ({ abort (); (*mem)--; })
+
+#ifdef _ARCH_PWR4
+/*
+ * Newer powerpc64 processors support the new "light weight" sync (lwsync)
+ * So if the build is using -mcpu=[power4,power5,power5+,970] we can
+ * safely use lwsync.
+ */
+# define atomic_read_barrier() __asm ("lwsync" ::: "memory")
+/*
+ * "light weight" sync can also be used for the release barrier.
+ */
+# ifndef UP
+# define __ARCH_REL_INSTR "lwsync"
+# endif
+#else
+/*
+ * Older powerpc32 processors don't support the new "light weight"
+ * sync (lwsync). So the only safe option is to use normal sync
+ * for all powerpc32 applications.
+ */
+# define atomic_read_barrier() __asm ("sync" ::: "memory")
+#endif
+
+/*
+ * Include the rest of the atomic ops macros which are common to both
+ * powerpc32 and powerpc64.
+ */
+#include_next <bits/atomic.h>
diff --git a/libc/sysdeps/powerpc/powerpc32/bits/wordsize.h b/libc/sysdeps/powerpc/powerpc32/bits/wordsize.h
new file mode 100644
index 000000000..1a79c8636
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/bits/wordsize.h
@@ -0,0 +1,8 @@
+/* Determine the wordsize from the preprocessor defines. */
+
+#if defined __powerpc64__
+# define __WORDSIZE 64
+# define __WORDSIZE_COMPAT32 1
+#else
+# define __WORDSIZE 32
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/bp-asm.h b/libc/sysdeps/powerpc/powerpc32/bp-asm.h
new file mode 100644
index 000000000..b3bbba757
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/bp-asm.h
@@ -0,0 +1,114 @@
+/* Bounded-pointer definitions for PowerPC assembler.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Greg McGary <greg@mcgary.org>
+ This file is part of the GNU C Library. Its master source is NOT part of
+ the C library, however. The master source lives in the GNU MP Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if __BOUNDED_POINTERS__
+
+/* Byte offsets of BP components. */
+# define oVALUE 0
+# define oLOW 4
+# define oHIGH 8
+
+/* Don't check bounds, just convert the BP register to its simple
+ pointer value. */
+
+# define DISCARD_BOUNDS(rBP) \
+ lwz rBP, oVALUE(rBP)
+
+/* Check low bound, with the side effect that the BP register is converted
+ its simple pointer value. Move the high bound into a register for
+ later use. */
+
+# define CHECK_BOUNDS_LOW(rBP, rLOW, rHIGH) \
+ lwz rHIGH, oHIGH(rBP); \
+ lwz rLOW, oLOW(rBP); \
+ lwz rBP, oVALUE(rBP); \
+ twllt rBP, rLOW
+
+/* Check the high bound, which is in a register, using the given
+ conditional trap instruction. */
+
+# define CHECK_BOUNDS_HIGH(rVALUE, rHIGH, TWLcc) \
+ TWLcc rVALUE, rHIGH
+
+/* Check the high bound, which is stored at the return-value's high
+ bound slot, using the given conditional trap instruction. */
+
+# define CHECK_BOUNDS_HIGH_RTN(rVALUE, rHIGH, TWLcc) \
+ lwz rHIGH, oHIGH(rRTN); \
+ TWLcc rVALUE, rHIGH
+
+/* Check both bounds, with the side effect that the BP register is
+ converted to its simple pointer value. */
+
+# define CHECK_BOUNDS_BOTH(rBP, rLOW, rHIGH) \
+ CHECK_BOUNDS_LOW(rBP, rLOW, rHIGH); \
+ twlge rBP, rHIGH
+
+/* Check bounds on a memory region of given length, with the side
+ effect that the BP register is converted to its simple pointer
+ value. */
+
+# define CHECK_BOUNDS_BOTH_WIDE(rBP, rLOW, rHIGH, rLENGTH) \
+ CHECK_BOUNDS_LOW (rBP, rLOW, rHIGH); \
+ sub rHIGH, rHIGH, rLENGTH; \
+ twlgt rBP, rHIGH
+
+# define CHECK_BOUNDS_BOTH_WIDE_LIT(rBP, rLOW, rHIGH, LENGTH) \
+ CHECK_BOUNDS_LOW (rBP, rLOW, rHIGH); \
+ subi rHIGH, rHIGH, LENGTH; \
+ twlgt rBP, rHIGH
+
+/* Store a pointer value register into the return-value's pointer
+ value slot. */
+
+# define STORE_RETURN_VALUE(rVALUE) \
+ stw rVALUE, oVALUE(rRTN)
+
+/* Store a low and high bounds into the return-value's pointer bounds
+ slots. */
+
+# define STORE_RETURN_BOUNDS(rLOW, rHIGH) \
+ stw rLOW, oLOW(rRTN); \
+ stw rHIGH, oHIGH(rRTN)
+
+/* Stuff zero value/low/high into the BP addressed by rRTN. */
+
+# define RETURN_NULL_BOUNDED_POINTER \
+ li r4, 0; \
+ STORE_RETURN_VALUE (r4); \
+ STORE_RETURN_BOUNDS (r4, r4)
+
+#else
+
+# define DISCARD_BOUNDS(rBP)
+# define CHECK_BOUNDS_LOW(rBP, rLOW, rHIGH)
+# define CHECK_BOUNDS_HIGH(rVALUE, rHIGH, TWLcc)
+# define CHECK_BOUNDS_HIGH_RTN(rVALUE, rHIGH, TWLcc)
+# define CHECK_BOUNDS_BOTH(rBP, rLOW, rHIGH)
+# define CHECK_BOUNDS_BOTH_WIDE(rBP, rLOW, rHIGH, rLENGTH)
+# define CHECK_BOUNDS_BOTH_WIDE_LIT(rBP, rLOW, rHIGH, LENGTH)
+# define STORE_RETURN_VALUE(rVALUE)
+# define STORE_RETURN_BOUNDS(rLOW, rHIGH)
+
+# define RETURN_NULL_BOUNDED_POINTER li rRTN, 0
+
+#endif
+
diff --git a/libc/sysdeps/powerpc/powerpc32/bsd-_setjmp.S b/libc/sysdeps/powerpc/powerpc32/bsd-_setjmp.S
new file mode 100644
index 000000000..4c28c2e54
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/bsd-_setjmp.S
@@ -0,0 +1,59 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. PowerPC32/64 version.
+ Copyright (C) 1994,1997,1999,2000,2002,2003,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+#include <shlib-compat.h>
+#include <libc-symbols.h>
+#include <sysdep.h>
+#include <bp-sym.h>
+
+#if defined NOT_IN_libc
+/* Build a non-versioned object for rtld-*. */
+ENTRY (BP_SYM (_setjmp))
+ li r4,0 /* Set second argument to 0. */
+ b BP_SYM (__sigsetjmp@local)
+END (BP_SYM (_setjmp))
+libc_hidden_def (_setjmp)
+#else
+/* Build a versioned object for libc. */
+
+# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+symbol_version (__novmx_setjmp,_setjmp,GLIBC_2.0);
+
+ENTRY (BP_SYM (__novmx_setjmp))
+ li r4,0 /* Set second argument to 0. */
+ b BP_SYM (__novmx__sigsetjmp@local)
+END (BP_SYM (__novmx_setjmp))
+libc_hidden_def (__novmx_setjmp)
+# endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) */
+
+default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4)
+/* __GI__setjmp prototype is needed for ntpl i.e. _setjmp is defined
+ as a libc_hidden_proto & is used in sysdeps/generic/libc-start.c
+ if HAVE_CLEANUP_JMP_BUF is defined */
+ENTRY (BP_SYM (__GI__setjmp))
+ li r4,0 /* Set second argument to 0. */
+ b BP_SYM (__vmx__sigsetjmp@local)
+END (BP_SYM (__GI__setjmp))
+
+ENTRY (BP_SYM (__vmx_setjmp))
+ li r4,0 /* Set second argument to 0. */
+ b BP_SYM (__vmx__sigsetjmp@local)
+END (BP_SYM (__vmx_setjmp))
+libc_hidden_def (__vmx_setjmp)
+#endif /* !NOT_IN_libc */
diff --git a/libc/sysdeps/powerpc/powerpc32/bsd-setjmp.S b/libc/sysdeps/powerpc/powerpc32/bsd-setjmp.S
new file mode 100644
index 000000000..01b195d83
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/bsd-setjmp.S
@@ -0,0 +1,41 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. PowerPC32/64 version.
+ Copyright (C) 1994,1997,1999,2000,2003,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+#include <shlib-compat.h>
+#include <libc-symbols.h>
+#include <sysdep.h>
+#include <bp-sym.h>
+
+#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+
+ENTRY (__novmxsetjmp)
+ li r4,1 /* Set second argument to 1. */
+ b __novmx__sigsetjmp@local
+END (__novmxsetjmp)
+strong_alias (__novmxsetjmp, __novmx__setjmp)
+symbol_version (__novmxsetjmp, setjmp, GLIBC_2.0)
+
+#endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) ) */
+
+ENTRY (__vmxsetjmp)
+ li r4,1 /* Set second argument to 1. */
+ b __vmx__sigsetjmp@local
+END (__vmxsetjmp)
+strong_alias (__vmxsetjmp, __vmx__setjmp)
+strong_alias (__vmx__setjmp, __setjmp)
+default_symbol_version (__vmxsetjmp,setjmp,GLIBC_2.3.4)
diff --git a/libc/sysdeps/powerpc/powerpc32/configure b/libc/sysdeps/powerpc/powerpc32/configure
new file mode 100644
index 000000000..0ff56c936
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/configure
@@ -0,0 +1,62 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/powerpc/powerpc32.
+
+# See whether gas has R_PPC_REL16 relocs.
+echo "$as_me:$LINENO: checking for R_PPC_REL16 gas support" >&5
+echo $ECHO_N "checking for R_PPC_REL16 gas support... $ECHO_C" >&6
+if test "${libc_cv_ppc_rel16+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<\EOF
+ .text
+ addis 11,30,_GLOBAL_OFFSET_TABLE_-.@ha
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_ppc_rel16=yes
+else
+ libc_cv_ppc_rel16=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_ppc_rel16" >&5
+echo "${ECHO_T}$libc_cv_ppc_rel16" >&6
+if test $libc_cv_ppc_rel16 = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_ASM_PPC_REL16 1
+_ACEOF
+
+fi
+
+# See whether GCC uses -msecure-plt.
+echo "$as_me:$LINENO: checking for -msecure-plt by default" >&5
+echo $ECHO_N "checking for -msecure-plt by default... $ECHO_C" >&6
+if test "${libc_cv_ppc_secure_plt+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ echo 'int foo (void) { extern int bar; return bar; }' > conftest.c
+libc_cv_ppc_secure_plt=no
+if { ac_try='${CC-cc} -S $CFLAGS conftest.c -fpic -o conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if grep '_GLOBAL_OFFSET_TABLE_-.*@ha' conftest.s > /dev/null 2>&1; then
+ libc_cv_ppc_secure_plt=yes
+ fi
+fi
+rm -rf conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_ppc_secure_plt" >&5
+echo "${ECHO_T}$libc_cv_ppc_secure_plt" >&6
+if test $libc_cv_ppc_secure_plt = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_PPC_SECURE_PLT 1
+_ACEOF
+
+fi
diff --git a/libc/sysdeps/powerpc/powerpc32/configure.in b/libc/sysdeps/powerpc/powerpc32/configure.in
new file mode 100644
index 000000000..7219ad993
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/configure.in
@@ -0,0 +1,32 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/powerpc/powerpc32.
+
+# See whether gas has R_PPC_REL16 relocs.
+AC_CACHE_CHECK(for R_PPC_REL16 gas support, libc_cv_ppc_rel16, [dnl
+cat > conftest.s <<\EOF
+ .text
+ addis 11,30,_GLOBAL_OFFSET_TABLE_-.@ha
+EOF
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_ppc_rel16=yes
+else
+ libc_cv_ppc_rel16=no
+fi
+rm -f conftest*])
+if test $libc_cv_ppc_rel16 = yes; then
+ AC_DEFINE(HAVE_ASM_PPC_REL16)
+fi
+
+# See whether GCC uses -msecure-plt.
+AC_CACHE_CHECK(for -msecure-plt by default, libc_cv_ppc_secure_plt, [dnl
+echo 'int foo (void) { extern int bar; return bar; }' > conftest.c
+libc_cv_ppc_secure_plt=no
+if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.c -fpic -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ if grep '_GLOBAL_OFFSET_TABLE_-.*@ha' conftest.s > /dev/null 2>&1; then
+ libc_cv_ppc_secure_plt=yes
+ fi
+fi
+rm -rf conftest*])
+if test $libc_cv_ppc_secure_plt = yes; then
+ AC_DEFINE(HAVE_PPC_SECURE_PLT)
+fi
diff --git a/libc/sysdeps/powerpc/powerpc32/dl-dtprocnum.h b/libc/sysdeps/powerpc/powerpc32/dl-dtprocnum.h
new file mode 100644
index 000000000..7fe2be793
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/dl-dtprocnum.h
@@ -0,0 +1,3 @@
+/* Number of extra dynamic section entries for this architecture. By
+ default there are none. */
+#define DT_THISPROCNUM DT_PPC_NUM
diff --git a/libc/sysdeps/powerpc/powerpc32/dl-machine.c b/libc/sysdeps/powerpc/powerpc32/dl-machine.c
new file mode 100644
index 000000000..4120a0238
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/dl-machine.c
@@ -0,0 +1,620 @@
+/* Machine-dependent ELF dynamic relocation functions. PowerPC version.
+ Copyright (C) 1995-2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <string.h>
+#include <sys/param.h>
+#include <link.h>
+#include <ldsodefs.h>
+#include <elf/dynamic-link.h>
+#include <dl-machine.h>
+#include <stdio-common/_itoa.h>
+
+/* The value __cache_line_size is defined in memset.S and is initialised
+ by _dl_sysdep_start via DL_PLATFORM_INIT. */
+extern int __cache_line_size;
+weak_extern (__cache_line_size)
+
+/* Because ld.so is now versioned, these functions can be in their own file;
+ no relocations need to be done to call them.
+ Of course, if ld.so is not versioned... */
+#if defined SHARED && !(DO_VERSIONING - 0)
+#error This will not work with versioning turned off, sorry.
+#endif
+
+
+/* Stuff for the PLT. */
+#define PLT_INITIAL_ENTRY_WORDS 18
+#define PLT_LONGBRANCH_ENTRY_WORDS 0
+#define PLT_TRAMPOLINE_ENTRY_WORDS 6
+#define PLT_DOUBLE_SIZE (1<<13)
+#define PLT_ENTRY_START_WORDS(entry_number) \
+ (PLT_INITIAL_ENTRY_WORDS + (entry_number)*2 \
+ + ((entry_number) > PLT_DOUBLE_SIZE \
+ ? ((entry_number) - PLT_DOUBLE_SIZE)*2 \
+ : 0))
+#define PLT_DATA_START_WORDS(num_entries) PLT_ENTRY_START_WORDS(num_entries)
+
+/* Macros to build PowerPC opcode words. */
+#define OPCODE_ADDI(rd,ra,simm) \
+ (0x38000000 | (rd) << 21 | (ra) << 16 | ((simm) & 0xffff))
+#define OPCODE_ADDIS(rd,ra,simm) \
+ (0x3c000000 | (rd) << 21 | (ra) << 16 | ((simm) & 0xffff))
+#define OPCODE_ADD(rd,ra,rb) \
+ (0x7c000214 | (rd) << 21 | (ra) << 16 | (rb) << 11)
+#define OPCODE_B(target) (0x48000000 | ((target) & 0x03fffffc))
+#define OPCODE_BA(target) (0x48000002 | ((target) & 0x03fffffc))
+#define OPCODE_BCTR() 0x4e800420
+#define OPCODE_LWZ(rd,d,ra) \
+ (0x80000000 | (rd) << 21 | (ra) << 16 | ((d) & 0xffff))
+#define OPCODE_LWZU(rd,d,ra) \
+ (0x84000000 | (rd) << 21 | (ra) << 16 | ((d) & 0xffff))
+#define OPCODE_MTCTR(rd) (0x7C0903A6 | (rd) << 21)
+#define OPCODE_RLWINM(ra,rs,sh,mb,me) \
+ (0x54000000 | (rs) << 21 | (ra) << 16 | (sh) << 11 | (mb) << 6 | (me) << 1)
+
+#define OPCODE_LI(rd,simm) OPCODE_ADDI(rd,0,simm)
+#define OPCODE_ADDIS_HI(rd,ra,value) \
+ OPCODE_ADDIS(rd,ra,((value) + 0x8000) >> 16)
+#define OPCODE_LIS_HI(rd,value) OPCODE_ADDIS_HI(rd,0,value)
+#define OPCODE_SLWI(ra,rs,sh) OPCODE_RLWINM(ra,rs,sh,0,31-sh)
+
+
+#define PPC_DCBST(where) asm volatile ("dcbst 0,%0" : : "r"(where) : "memory")
+#define PPC_SYNC asm volatile ("sync" : : : "memory")
+#define PPC_ISYNC asm volatile ("sync; isync" : : : "memory")
+#define PPC_ICBI(where) asm volatile ("icbi 0,%0" : : "r"(where) : "memory")
+#define PPC_DIE asm volatile ("tweq 0,0")
+
+/* Use this when you've modified some code, but it won't be in the
+ instruction fetch queue (or when it doesn't matter if it is). */
+#define MODIFIED_CODE_NOQUEUE(where) \
+ do { PPC_DCBST(where); PPC_SYNC; PPC_ICBI(where); } while (0)
+/* Use this when it might be in the instruction queue. */
+#define MODIFIED_CODE(where) \
+ do { PPC_DCBST(where); PPC_SYNC; PPC_ICBI(where); PPC_ISYNC; } while (0)
+
+
+/* The idea here is that to conform to the ABI, we are supposed to try
+ to load dynamic objects between 0x10000 (we actually use 0x40000 as
+ the lower bound, to increase the chance of a memory reference from
+ a null pointer giving a segfault) and the program's load address;
+ this may allow us to use a branch instruction in the PLT rather
+ than a computed jump. The address is only used as a preference for
+ mmap, so if we get it wrong the worst that happens is that it gets
+ mapped somewhere else. */
+
+ElfW(Addr)
+__elf_preferred_address (struct link_map *loader, size_t maplength,
+ ElfW(Addr) mapstartpref)
+{
+ ElfW(Addr) low, high;
+ struct link_map *l;
+ Lmid_t nsid;
+
+ /* If the object has a preference, load it there! */
+ if (mapstartpref != 0)
+ return mapstartpref;
+
+ /* Otherwise, quickly look for a suitable gap between 0x3FFFF and
+ 0x70000000. 0x3FFFF is so that references off NULL pointers will
+ cause a segfault, 0x70000000 is just paranoia (it should always
+ be superceded by the program's load address). */
+ low = 0x0003FFFF;
+ high = 0x70000000;
+ for (nsid = 0; nsid < DL_NNS; ++nsid)
+ for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
+ {
+ ElfW(Addr) mapstart, mapend;
+ mapstart = l->l_map_start & ~(GLRO(dl_pagesize) - 1);
+ mapend = l->l_map_end | (GLRO(dl_pagesize) - 1);
+ assert (mapend > mapstart);
+
+ /* Prefer gaps below the main executable, note that l ==
+ _dl_loaded does not work for static binaries loading
+ e.g. libnss_*.so. */
+ if ((mapend >= high || l->l_type == lt_executable)
+ && high >= mapstart)
+ high = mapstart;
+ else if (mapend >= low && low >= mapstart)
+ low = mapend;
+ else if (high >= mapend && mapstart >= low)
+ {
+ if (high - mapend >= mapstart - low)
+ low = mapend;
+ else
+ high = mapstart;
+ }
+ }
+
+ high -= 0x10000; /* Allow some room between objects. */
+ maplength = (maplength | (GLRO(dl_pagesize) - 1)) + 1;
+ if (high <= low || high - low < maplength )
+ return 0;
+ return high - maplength; /* Both high and maplength are page-aligned. */
+}
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c.
+ Also install a small trampoline to be used by entries that have
+ been relocated to an address too far away for a single branch. */
+
+/* There are many kinds of PLT entries:
+
+ (1) A direct jump to the actual routine, either a relative or
+ absolute branch. These are set up in __elf_machine_fixup_plt.
+
+ (2) Short lazy entries. These cover the first 8192 slots in
+ the PLT, and look like (where 'index' goes from 0 to 8191):
+
+ li %r11, index*4
+ b &plt[PLT_TRAMPOLINE_ENTRY_WORDS+1]
+
+ (3) Short indirect jumps. These replace (2) when a direct jump
+ wouldn't reach. They look the same except that the branch
+ is 'b &plt[PLT_LONGBRANCH_ENTRY_WORDS]'.
+
+ (4) Long lazy entries. These cover the slots when a short entry
+ won't fit ('index*4' overflows its field), and look like:
+
+ lis %r11, %hi(index*4 + &plt[PLT_DATA_START_WORDS])
+ lwzu %r12, %r11, %lo(index*4 + &plt[PLT_DATA_START_WORDS])
+ b &plt[PLT_TRAMPOLINE_ENTRY_WORDS]
+ bctr
+
+ (5) Long indirect jumps. These replace (4) when a direct jump
+ wouldn't reach. They look like:
+
+ lis %r11, %hi(index*4 + &plt[PLT_DATA_START_WORDS])
+ lwz %r12, %r11, %lo(index*4 + &plt[PLT_DATA_START_WORDS])
+ mtctr %r12
+ bctr
+
+ (6) Long direct jumps. These are used when thread-safety is not
+ required. They look like:
+
+ lis %r12, %hi(finaladdr)
+ addi %r12, %r12, %lo(finaladdr)
+ mtctr %r12
+ bctr
+
+
+ The lazy entries, (2) and (4), are set up here in
+ __elf_machine_runtime_setup. (1), (3), and (5) are set up in
+ __elf_machine_fixup_plt. (1), (3), and (6) can also be constructed
+ in __process_machine_rela.
+
+ The reason for the somewhat strange construction of the long
+ entries, (4) and (5), is that we need to ensure thread-safety. For
+ (1) and (3), this is obvious because only one instruction is
+ changed and the PPC architecture guarantees that aligned stores are
+ atomic. For (5), this is more tricky. When changing (4) to (5),
+ the `b' instruction is first changed to to `mtctr'; this is safe
+ and is why the `lwzu' instruction is not just a simple `addi'.
+ Once this is done, and is visible to all processors, the `lwzu' can
+ safely be changed to a `lwz'. */
+int
+__elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
+{
+ if (map->l_info[DT_JMPREL])
+ {
+ Elf32_Word i;
+ Elf32_Word *plt = (Elf32_Word *) D_PTR (map, l_info[DT_PLTGOT]);
+ Elf32_Word num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
+ / sizeof (Elf32_Rela));
+ Elf32_Word rel_offset_words = PLT_DATA_START_WORDS (num_plt_entries);
+ Elf32_Word data_words = (Elf32_Word) (plt + rel_offset_words);
+ Elf32_Word size_modified;
+
+ extern void _dl_runtime_resolve (void);
+ extern void _dl_prof_resolve (void);
+
+ /* Convert the index in r11 into an actual address, and get the
+ word at that address. */
+ plt[PLT_LONGBRANCH_ENTRY_WORDS] = OPCODE_ADDIS_HI (11, 11, data_words);
+ plt[PLT_LONGBRANCH_ENTRY_WORDS + 1] = OPCODE_LWZ (11, data_words, 11);
+
+ /* Call the procedure at that address. */
+ plt[PLT_LONGBRANCH_ENTRY_WORDS + 2] = OPCODE_MTCTR (11);
+ plt[PLT_LONGBRANCH_ENTRY_WORDS + 3] = OPCODE_BCTR ();
+
+ if (lazy)
+ {
+ Elf32_Word *tramp = plt + PLT_TRAMPOLINE_ENTRY_WORDS;
+ Elf32_Word dlrr = (Elf32_Word)(profile
+ ? _dl_prof_resolve
+ : _dl_runtime_resolve);
+ Elf32_Word offset;
+
+ if (profile && GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), map))
+ /* This is the object we are looking for. Say that we really
+ want profiling and the timers are started. */
+ GL(dl_profile_map) = map;
+
+ /* For the long entries, subtract off data_words. */
+ tramp[0] = OPCODE_ADDIS_HI (11, 11, -data_words);
+ tramp[1] = OPCODE_ADDI (11, 11, -data_words);
+
+ /* Multiply index of entry by 3 (in r11). */
+ tramp[2] = OPCODE_SLWI (12, 11, 1);
+ tramp[3] = OPCODE_ADD (11, 12, 11);
+ if (dlrr <= 0x01fffffc || dlrr >= 0xfe000000)
+ {
+ /* Load address of link map in r12. */
+ tramp[4] = OPCODE_LI (12, (Elf32_Word) map);
+ tramp[5] = OPCODE_ADDIS_HI (12, 12, (Elf32_Word) map);
+
+ /* Call _dl_runtime_resolve. */
+ tramp[6] = OPCODE_BA (dlrr);
+ }
+ else
+ {
+ /* Get address of _dl_runtime_resolve in CTR. */
+ tramp[4] = OPCODE_LI (12, dlrr);
+ tramp[5] = OPCODE_ADDIS_HI (12, 12, dlrr);
+ tramp[6] = OPCODE_MTCTR (12);
+
+ /* Load address of link map in r12. */
+ tramp[7] = OPCODE_LI (12, (Elf32_Word) map);
+ tramp[8] = OPCODE_ADDIS_HI (12, 12, (Elf32_Word) map);
+
+ /* Call _dl_runtime_resolve. */
+ tramp[9] = OPCODE_BCTR ();
+ }
+
+ /* Set up the lazy PLT entries. */
+ offset = PLT_INITIAL_ENTRY_WORDS;
+ i = 0;
+ while (i < num_plt_entries && i < PLT_DOUBLE_SIZE)
+ {
+ plt[offset ] = OPCODE_LI (11, i * 4);
+ plt[offset+1] = OPCODE_B ((PLT_TRAMPOLINE_ENTRY_WORDS + 2
+ - (offset+1))
+ * 4);
+ i++;
+ offset += 2;
+ }
+ while (i < num_plt_entries)
+ {
+ plt[offset ] = OPCODE_LIS_HI (11, i * 4 + data_words);
+ plt[offset+1] = OPCODE_LWZU (12, i * 4 + data_words, 11);
+ plt[offset+2] = OPCODE_B ((PLT_TRAMPOLINE_ENTRY_WORDS
+ - (offset+2))
+ * 4);
+ plt[offset+3] = OPCODE_BCTR ();
+ i++;
+ offset += 4;
+ }
+ }
+
+ /* Now, we've modified code. We need to write the changes from
+ the data cache to a second-level unified cache, then make
+ sure that stale data in the instruction cache is removed.
+ (In a multiprocessor system, the effect is more complex.)
+ Most of the PLT shouldn't be in the instruction cache, but
+ there may be a little overlap at the start and the end.
+
+ Assumes that dcbst and icbi apply to lines of 16 bytes or
+ more. Current known line sizes are 16, 32, and 128 bytes.
+ The following gets the __cache_line_size, when available. */
+
+ /* Default minimum 4 words per cache line. */
+ int line_size_words = 4;
+
+ /* Don't try this until ld.so has relocated itself! */
+ int *line_size_ptr = &__cache_line_size;
+ if (lazy && line_size_ptr != NULL)
+ {
+ /* Verify that __cache_line_size is defined and set. */
+ if (*line_size_ptr != 0)
+ /* Convert bytes to words. */
+ line_size_words = *line_size_ptr / 4;
+ }
+
+ size_modified = lazy ? rel_offset_words : 6;
+ for (i = 0; i < size_modified; i += line_size_words)
+ PPC_DCBST (plt + i);
+ PPC_DCBST (plt + size_modified - 1);
+ PPC_SYNC;
+
+ for (i = 0; i < size_modified; i += line_size_words)
+ PPC_ICBI (plt + i);
+ PPC_ICBI (plt + size_modified - 1);
+ PPC_ISYNC;
+ }
+
+ return lazy;
+}
+
+Elf32_Addr
+__elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr finaladdr)
+{
+ Elf32_Sword delta = finaladdr - (Elf32_Word) reloc_addr;
+ if (delta << 6 >> 6 == delta)
+ *reloc_addr = OPCODE_B (delta);
+ else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000)
+ *reloc_addr = OPCODE_BA (finaladdr);
+ else
+ {
+ Elf32_Word *plt, *data_words;
+ Elf32_Word index, offset, num_plt_entries;
+
+ num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
+ / sizeof(Elf32_Rela));
+ plt = (Elf32_Word *) D_PTR (map, l_info[DT_PLTGOT]);
+ offset = reloc_addr - plt;
+ index = (offset - PLT_INITIAL_ENTRY_WORDS)/2;
+ data_words = plt + PLT_DATA_START_WORDS (num_plt_entries);
+
+ reloc_addr += 1;
+
+ if (index < PLT_DOUBLE_SIZE)
+ {
+ data_words[index] = finaladdr;
+ PPC_SYNC;
+ *reloc_addr = OPCODE_B ((PLT_LONGBRANCH_ENTRY_WORDS - (offset+1))
+ * 4);
+ }
+ else
+ {
+ index -= (index - PLT_DOUBLE_SIZE)/2;
+
+ data_words[index] = finaladdr;
+ PPC_SYNC;
+
+ reloc_addr[1] = OPCODE_MTCTR (12);
+ MODIFIED_CODE_NOQUEUE (reloc_addr + 1);
+ PPC_SYNC;
+
+ reloc_addr[0] = OPCODE_LWZ (12,
+ (Elf32_Word) (data_words + index), 11);
+ }
+ }
+ MODIFIED_CODE (reloc_addr);
+ return finaladdr;
+}
+
+void
+_dl_reloc_overflow (struct link_map *map,
+ const char *name,
+ Elf32_Addr *const reloc_addr,
+ const Elf32_Sym *refsym)
+{
+ char buffer[128];
+ char *t;
+ t = stpcpy (buffer, name);
+ t = stpcpy (t, " relocation at 0x00000000");
+ _itoa_word ((unsigned) reloc_addr, t, 16, 0);
+ if (refsym)
+ {
+ const char *strtab;
+
+ strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+ t = stpcpy (t, " for symbol `");
+ t = stpcpy (t, strtab + refsym->st_name);
+ t = stpcpy (t, "'");
+ }
+ t = stpcpy (t, " out of range");
+ _dl_signal_error (0, map->l_name, NULL, buffer);
+}
+
+void
+__process_machine_rela (struct link_map *map,
+ const Elf32_Rela *reloc,
+ struct link_map *sym_map,
+ const Elf32_Sym *sym,
+ const Elf32_Sym *refsym,
+ Elf32_Addr *const reloc_addr,
+ Elf32_Addr const finaladdr,
+ int rinfo)
+{
+ switch (rinfo)
+ {
+ case R_PPC_NONE:
+ return;
+
+ case R_PPC_ADDR32:
+ case R_PPC_GLOB_DAT:
+ case R_PPC_RELATIVE:
+ *reloc_addr = finaladdr;
+ return;
+
+ case R_PPC_UADDR32:
+ ((char *) reloc_addr)[0] = finaladdr >> 24;
+ ((char *) reloc_addr)[1] = finaladdr >> 16;
+ ((char *) reloc_addr)[2] = finaladdr >> 8;
+ ((char *) reloc_addr)[3] = finaladdr;
+ break;
+
+ case R_PPC_ADDR24:
+ if (__builtin_expect (finaladdr > 0x01fffffc && finaladdr < 0xfe000000, 0))
+ _dl_reloc_overflow (map, "R_PPC_ADDR24", reloc_addr, refsym);
+ *reloc_addr = (*reloc_addr & 0xfc000003) | (finaladdr & 0x3fffffc);
+ break;
+
+ case R_PPC_ADDR16:
+ if (__builtin_expect (finaladdr > 0x7fff && finaladdr < 0xffff8000, 0))
+ _dl_reloc_overflow (map, "R_PPC_ADDR16", reloc_addr, refsym);
+ *(Elf32_Half*) reloc_addr = finaladdr;
+ break;
+
+ case R_PPC_UADDR16:
+ if (__builtin_expect (finaladdr > 0x7fff && finaladdr < 0xffff8000, 0))
+ _dl_reloc_overflow (map, "R_PPC_UADDR16", reloc_addr, refsym);
+ ((char *) reloc_addr)[0] = finaladdr >> 8;
+ ((char *) reloc_addr)[1] = finaladdr;
+ break;
+
+ case R_PPC_ADDR16_LO:
+ *(Elf32_Half*) reloc_addr = finaladdr;
+ break;
+
+ case R_PPC_ADDR16_HI:
+ *(Elf32_Half*) reloc_addr = finaladdr >> 16;
+ break;
+
+ case R_PPC_ADDR16_HA:
+ *(Elf32_Half*) reloc_addr = (finaladdr + 0x8000) >> 16;
+ break;
+
+ case R_PPC_ADDR14:
+ case R_PPC_ADDR14_BRTAKEN:
+ case R_PPC_ADDR14_BRNTAKEN:
+ if (__builtin_expect (finaladdr > 0x7fff && finaladdr < 0xffff8000, 0))
+ _dl_reloc_overflow (map, "R_PPC_ADDR14", reloc_addr, refsym);
+ *reloc_addr = (*reloc_addr & 0xffff0003) | (finaladdr & 0xfffc);
+ if (rinfo != R_PPC_ADDR14)
+ *reloc_addr = ((*reloc_addr & 0xffdfffff)
+ | ((rinfo == R_PPC_ADDR14_BRTAKEN)
+ ^ (finaladdr >> 31)) << 21);
+ break;
+
+ case R_PPC_REL24:
+ {
+ Elf32_Sword delta = finaladdr - (Elf32_Word) reloc_addr;
+ if (delta << 6 >> 6 != delta)
+ _dl_reloc_overflow (map, "R_PPC_REL24", reloc_addr, refsym);
+ *reloc_addr = (*reloc_addr & 0xfc000003) | (delta & 0x3fffffc);
+ }
+ break;
+
+ case R_PPC_COPY:
+ if (sym == NULL)
+ /* This can happen in trace mode when an object could not be
+ found. */
+ return;
+ if (sym->st_size > refsym->st_size
+ || (GLRO(dl_verbose) && sym->st_size < refsym->st_size))
+ {
+ const char *strtab;
+
+ strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+ _dl_error_printf ("\
+%s: Symbol `%s' has different size in shared object, onsider re-linking\n",
+ rtld_progname ?: "<program name unknown>",
+ strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr, (char *) finaladdr, MIN (sym->st_size,
+ refsym->st_size));
+ return;
+
+ case R_PPC_REL32:
+ *reloc_addr = finaladdr - (Elf32_Word) reloc_addr;
+ return;
+
+ case R_PPC_JMP_SLOT:
+ /* It used to be that elf_machine_fixup_plt was used here,
+ but that doesn't work when ld.so relocates itself
+ for the second time. On the bright side, there's
+ no need to worry about thread-safety here. */
+ {
+ Elf32_Sword delta = finaladdr - (Elf32_Word) reloc_addr;
+ if (delta << 6 >> 6 == delta)
+ *reloc_addr = OPCODE_B (delta);
+ else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000)
+ *reloc_addr = OPCODE_BA (finaladdr);
+ else
+ {
+ Elf32_Word *plt, *data_words;
+ Elf32_Word index, offset, num_plt_entries;
+
+ plt = (Elf32_Word *) D_PTR (map, l_info[DT_PLTGOT]);
+ offset = reloc_addr - plt;
+
+ if (offset < PLT_DOUBLE_SIZE*2 + PLT_INITIAL_ENTRY_WORDS)
+ {
+ index = (offset - PLT_INITIAL_ENTRY_WORDS)/2;
+ num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
+ / sizeof(Elf32_Rela));
+ data_words = plt + PLT_DATA_START_WORDS (num_plt_entries);
+ data_words[index] = finaladdr;
+ reloc_addr[0] = OPCODE_LI (11, index * 4);
+ reloc_addr[1] = OPCODE_B ((PLT_LONGBRANCH_ENTRY_WORDS
+ - (offset+1))
+ * 4);
+ MODIFIED_CODE_NOQUEUE (reloc_addr + 1);
+ }
+ else
+ {
+ reloc_addr[0] = OPCODE_LIS_HI (12, finaladdr);
+ reloc_addr[1] = OPCODE_ADDI (12, 12, finaladdr);
+ reloc_addr[2] = OPCODE_MTCTR (12);
+ reloc_addr[3] = OPCODE_BCTR ();
+ MODIFIED_CODE_NOQUEUE (reloc_addr + 3);
+ }
+ }
+ }
+ break;
+
+#ifdef USE_TLS
+#define CHECK_STATIC_TLS(map, sym_map) \
+ do { \
+ if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET, 0)) \
+ _dl_allocate_static_tls (sym_map); \
+ } while (0)
+# define DO_TLS_RELOC(suffix) \
+ case R_PPC_DTPREL##suffix: \
+ /* During relocation all TLS symbols are defined and used. \
+ Therefore the offset is already correct. */ \
+ if (sym_map != NULL) \
+ do_reloc##suffix ("R_PPC_DTPREL"#suffix, \
+ TLS_DTPREL_VALUE (sym, reloc)); \
+ break; \
+ case R_PPC_TPREL##suffix: \
+ if (sym_map != NULL) \
+ { \
+ CHECK_STATIC_TLS (map, sym_map); \
+ do_reloc##suffix ("R_PPC_TPREL"#suffix, \
+ TLS_TPREL_VALUE (sym_map, sym, reloc)); \
+ } \
+ break;
+
+ inline void do_reloc16 (const char *r_name, Elf32_Addr value)
+ {
+ if (__builtin_expect (value > 0x7fff && value < 0xffff8000, 0))
+ _dl_reloc_overflow (map, r_name, reloc_addr, refsym);
+ *(Elf32_Half *) reloc_addr = value;
+ }
+ inline void do_reloc16_LO (const char *r_name, Elf32_Addr value)
+ {
+ *(Elf32_Half *) reloc_addr = value;
+ }
+ inline void do_reloc16_HI (const char *r_name, Elf32_Addr value)
+ {
+ *(Elf32_Half *) reloc_addr = value >> 16;
+ }
+ inline void do_reloc16_HA (const char *r_name, Elf32_Addr value)
+ {
+ *(Elf32_Half *) reloc_addr = (value + 0x8000) >> 16;
+ }
+ DO_TLS_RELOC (16)
+ DO_TLS_RELOC (16_LO)
+ DO_TLS_RELOC (16_HI)
+ DO_TLS_RELOC (16_HA)
+#endif
+
+ default:
+ _dl_reloc_bad_type (map, rinfo, 0);
+ return;
+ }
+
+ MODIFIED_CODE_NOQUEUE (reloc_addr);
+}
diff --git a/libc/sysdeps/powerpc/powerpc32/dl-machine.h b/libc/sysdeps/powerpc/powerpc32/dl-machine.h
new file mode 100644
index 000000000..496fa71ec
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -0,0 +1,402 @@
+/* Machine-dependent ELF dynamic relocation inline functions. PowerPC version.
+ Copyright (C) 1995-2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "powerpc"
+
+#include <assert.h>
+#include <dl-tls.h>
+
+/* Translate a processor specific dynamic tag to the index
+ in l_info array. */
+#define DT_PPC(x) (DT_PPC_##x - DT_LOPROC + DT_NUM)
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int
+elf_machine_matches_host (const Elf32_Ehdr *ehdr)
+{
+ return ehdr->e_machine == EM_PPC;
+}
+
+/* Return the value of the GOT pointer. */
+static inline Elf32_Addr * __attribute__ ((const))
+ppc_got (void)
+{
+ Elf32_Addr *got;
+#ifdef HAVE_ASM_PPC_REL16
+ asm ("bcl 20,31,1f\n"
+ "1: mflr %0\n"
+ " addis %0,%0,_GLOBAL_OFFSET_TABLE_-1b@ha\n"
+ " addi %0,%0,_GLOBAL_OFFSET_TABLE_-1b@l\n"
+ : "=b" (got) : : "lr");
+#else
+ asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
+ : "=l" (got));
+#endif
+ return got;
+}
+
+/* Return the link-time address of _DYNAMIC, stored as
+ the first value in the GOT. */
+static inline Elf32_Addr __attribute__ ((const))
+elf_machine_dynamic (void)
+{
+ return *ppc_got ();
+}
+
+/* Return the run-time load address of the shared object. */
+static inline Elf32_Addr __attribute__ ((const))
+elf_machine_load_address (void)
+{
+ Elf32_Addr *branchaddr;
+ Elf32_Addr runtime_dynamic;
+
+ /* This is much harder than you'd expect. Possibly I'm missing something.
+ The 'obvious' way:
+
+ Apparently, "bcl 20,31,$+4" is what should be used to load LR
+ with the address of the next instruction.
+ I think this is so that machines that do bl/blr pairing don't
+ get confused.
+
+ asm ("bcl 20,31,0f ;"
+ "0: mflr 0 ;"
+ "lis %0,0b@ha;"
+ "addi %0,%0,0b@l;"
+ "subf %0,%0,0"
+ : "=b" (addr) : : "r0", "lr");
+
+ doesn't work, because the linker doesn't have to (and in fact doesn't)
+ update the @ha and @l references; the loader (which runs after this
+ code) will do that.
+
+ Instead, we use the following trick:
+
+ The linker puts the _link-time_ address of _DYNAMIC at the first
+ word in the GOT. We could branch to that address, if we wanted,
+ by using an @local reloc; the linker works this out, so it's safe
+ to use now. We can't, of course, actually branch there, because
+ we'd cause an illegal instruction exception; so we need to compute
+ the address ourselves. That gives us the following code: */
+
+ /* Get address of the 'b _DYNAMIC@local'... */
+ asm ("bcl 20,31,0f;"
+ "b _DYNAMIC@local;"
+ "0:"
+ : "=l" (branchaddr));
+
+ /* So now work out the difference between where the branch actually points,
+ and the offset of that location in memory from the start of the file. */
+ runtime_dynamic = ((Elf32_Addr) branchaddr
+ + ((Elf32_Sword) (*branchaddr << 6 & 0xffffff00) >> 6));
+
+ return runtime_dynamic - elf_machine_dynamic ();
+}
+
+#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */
+
+/* The PLT uses Elf32_Rela relocs. */
+#define elf_machine_relplt elf_machine_rela
+
+/* Mask identifying addresses reserved for the user program,
+ where the dynamic linker should not map anything. */
+#define ELF_MACHINE_USER_ADDRESS_MASK 0xf0000000UL
+
+/* The actual _start code is in dl-start.S. Use a really
+ ugly bit of assembler to let dl-start.o see _dl_start. */
+#define RTLD_START asm (".globl _dl_start");
+
+/* Decide where a relocatable object should be loaded. */
+extern ElfW(Addr)
+__elf_preferred_address(struct link_map *loader, size_t maplength,
+ ElfW(Addr) mapstartpref);
+#define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) \
+ __elf_preferred_address (loader, maplength, mapstartpref)
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
+ PLT entries should not be allowed to define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+/* We never want to use a PLT entry as the destination of a
+ reloc, when what is being relocated is a branch. This is
+ partly for efficiency, but mostly so we avoid loops. */
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#define elf_machine_type_class(type) \
+ ((((type) == R_PPC_JMP_SLOT \
+ || (type) == R_PPC_REL24 \
+ || ((type) >= R_PPC_DTPMOD32 /* contiguous TLS */ \
+ && (type) <= R_PPC_DTPREL32) \
+ || (type) == R_PPC_ADDR24) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_PPC_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+#define elf_machine_type_class(type) \
+ ((((type) == R_PPC_JMP_SLOT \
+ || (type) == R_PPC_REL24 \
+ || (type) == R_PPC_ADDR24) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_PPC_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_PPC_JMP_SLOT
+
+/* The PowerPC never uses REL relocations. */
+#define ELF_MACHINE_NO_REL 1
+
+/* Set up the loaded object described by MAP so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c.
+ Also install a small trampoline to be used by entries that have
+ been relocated to an address too far away for a single branch. */
+extern int __elf_machine_runtime_setup (struct link_map *map,
+ int lazy, int profile);
+
+static inline int
+elf_machine_runtime_setup (struct link_map *map,
+ int lazy, int profile)
+{
+ if (map->l_info[DT_JMPREL] == 0)
+ return lazy;
+
+ if (map->l_info[DT_PPC(GOT)] == 0)
+ /* Handle old style PLT. */
+ return __elf_machine_runtime_setup (map, lazy, profile);
+
+ /* New style non-exec PLT consisting of an array of addresses. */
+ map->l_info[DT_PPC(GOT)]->d_un.d_ptr += map->l_addr;
+ if (lazy)
+ {
+ Elf32_Addr *plt, *got, glink;
+ Elf32_Word num_plt_entries;
+ void (*dlrr) (void);
+ extern void _dl_runtime_resolve (void);
+ extern void _dl_prof_resolve (void);
+
+ if (__builtin_expect (!profile, 1))
+ dlrr = _dl_runtime_resolve;
+ else
+ {
+ if (GLRO(dl_profile) != NULL
+ &&_dl_name_match_p (GLRO(dl_profile), map))
+ GL(dl_profile_map) = map;
+ dlrr = _dl_prof_resolve;
+ }
+ got = (Elf32_Addr *) map->l_info[DT_PPC(GOT)]->d_un.d_ptr;
+ glink = got[1];
+ got[1] = (Elf32_Addr) dlrr;
+ got[2] = (Elf32_Addr) map;
+
+ /* Relocate everything in .plt by the load address offset. */
+ plt = (Elf32_Addr *) D_PTR (map, l_info[DT_PLTGOT]);
+ num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
+ / sizeof (Elf32_Rela));
+
+ /* If a library is prelinked but we have to relocate anyway,
+ we have to be able to undo the prelinking of .plt section.
+ The prelinker saved us at got[1] address of .glink
+ section's start. */
+ if (glink)
+ {
+ glink += map->l_addr;
+ while (num_plt_entries-- != 0)
+ *plt++ = glink, glink += 4;
+ }
+ else
+ while (num_plt_entries-- != 0)
+ *plt++ += map->l_addr;
+ }
+ return lazy;
+}
+
+/* Change the PLT entry whose reloc is 'reloc' to call the actual routine. */
+extern Elf32_Addr __elf_machine_fixup_plt (struct link_map *map,
+ const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr,
+ Elf32_Addr finaladdr);
+
+static inline Elf32_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr, Elf64_Addr finaladdr)
+{
+ if (map->l_info[DT_PPC(GOT)] == 0)
+ /* Handle old style PLT. */
+ return __elf_machine_fixup_plt (map, reloc, reloc_addr, finaladdr);
+
+ *reloc_addr = finaladdr;
+ return finaladdr;
+}
+
+/* Return the final value of a plt relocation. */
+static inline Elf32_Addr
+elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+ Elf32_Addr value)
+{
+ return value + reloc->r_addend;
+}
+
+
+/* Names of the architecture-specific auditing callback functions. */
+#define ARCH_LA_PLTENTER ppc32_gnu_pltenter
+#define ARCH_LA_PLTEXIT ppc32_gnu_pltexit
+
+#endif /* dl_machine_h */
+
+#ifdef RESOLVE_MAP
+
+/* Do the actual processing of a reloc, once its target address
+ has been determined. */
+extern void __process_machine_rela (struct link_map *map,
+ const Elf32_Rela *reloc,
+ struct link_map *sym_map,
+ const Elf32_Sym *sym,
+ const Elf32_Sym *refsym,
+ Elf32_Addr *const reloc_addr,
+ Elf32_Addr finaladdr,
+ int rinfo) attribute_hidden;
+
+/* Call _dl_signal_error when a resolved value overflows a relocated area. */
+extern void _dl_reloc_overflow (struct link_map *map,
+ const char *name,
+ Elf32_Addr *const reloc_addr,
+ const Elf32_Sym *refsym) attribute_hidden;
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ LOADADDR is the load address of the object; INFO is an array indexed
+ by DT_* of the .dynamic section info. */
+
+auto inline void __attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
+ const Elf32_Sym *sym, const struct r_found_version *version,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ const Elf32_Sym *const refsym = sym;
+ Elf32_Addr value;
+ const int r_type = ELF32_R_TYPE (reloc->r_info);
+ struct link_map *sym_map = NULL;
+
+#ifndef RESOLVE_CONFLICT_FIND_MAP
+ if (r_type == R_PPC_RELATIVE)
+ {
+ *reloc_addr = map->l_addr + reloc->r_addend;
+ return;
+ }
+
+ if (__builtin_expect (r_type == R_PPC_NONE, 0))
+ return;
+
+ /* binutils on ppc32 includes st_value in r_addend for relocations
+ against local symbols. */
+ if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0)
+ && sym->st_shndx != SHN_UNDEF)
+ value = map->l_addr;
+ else
+ {
+ sym_map = RESOLVE_MAP (&sym, version, r_type);
+ value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+ }
+ value += reloc->r_addend;
+#else
+ value = reloc->r_addend;
+#endif
+
+ /* A small amount of code is duplicated here for speed. In libc,
+ more than 90% of the relocs are R_PPC_RELATIVE; in the X11 shared
+ libraries, 60% are R_PPC_RELATIVE, 24% are R_PPC_GLOB_DAT or
+ R_PPC_ADDR32, and 16% are R_PPC_JMP_SLOT (which this routine
+ wouldn't usually handle). As an bonus, doing this here allows
+ the switch statement in __process_machine_rela to work. */
+ switch (r_type)
+ {
+ case R_PPC_GLOB_DAT:
+ case R_PPC_ADDR32:
+ *reloc_addr = value;
+ break;
+
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+ && !defined RESOLVE_CONFLICT_FIND_MAP
+# ifdef RTLD_BOOTSTRAP
+# define NOT_BOOTSTRAP 0
+# else
+# define NOT_BOOTSTRAP 1
+# endif
+
+ case R_PPC_DTPMOD32:
+ if (!NOT_BOOTSTRAP)
+ /* During startup the dynamic linker is always index 1. */
+ *reloc_addr = 1;
+ else if (sym_map != NULL)
+ /* Get the information from the link map returned by the
+ RESOLVE_MAP function. */
+ *reloc_addr = sym_map->l_tls_modid;
+ break;
+ case R_PPC_DTPREL32:
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ if (NOT_BOOTSTRAP && sym_map != NULL)
+ *reloc_addr = TLS_DTPREL_VALUE (sym, reloc);
+ break;
+ case R_PPC_TPREL32:
+ if (!NOT_BOOTSTRAP || sym_map != NULL)
+ {
+ if (NOT_BOOTSTRAP)
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
+ }
+ break;
+#endif /* USE_TLS etc. */
+
+ case R_PPC_JMP_SLOT:
+#ifdef RESOLVE_CONFLICT_FIND_MAP
+ RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr);
+#endif
+ if (map->l_info[DT_PPC(GOT)] != 0)
+ {
+ *reloc_addr = value;
+ break;
+ }
+ /* FALLTHROUGH */
+
+ default:
+ __process_machine_rela (map, reloc, sym_map, sym, refsym,
+ reloc_addr, value, r_type);
+ }
+}
+
+auto inline void __attribute__ ((always_inline))
+elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ *reloc_addr = l_addr + reloc->r_addend;
+}
+
+auto inline void __attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf32_Addr l_addr, const Elf32_Rela *reloc)
+{
+ /* elf_machine_runtime_setup handles this. */
+}
+
+/* The SVR4 ABI specifies that the JMPREL relocs must be inside the
+ DT_RELA table. */
+#define ELF_MACHINE_PLTREL_OVERLAP 1
+
+#endif /* RESOLVE_MAP */
diff --git a/libc/sysdeps/powerpc/powerpc32/dl-start.S b/libc/sysdeps/powerpc/powerpc32/dl-start.S
new file mode 100644
index 000000000..c77c4de19
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/dl-start.S
@@ -0,0 +1,110 @@
+/* Machine-dependent ELF startup code. PowerPC version.
+ Copyright (C) 1995-2000, 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+ENTRY(_start)
+/* We start with the following on the stack, from top:
+ argc (4 bytes);
+ arguments for program (terminated by NULL);
+ environment variables (terminated by NULL);
+ arguments for the program loader. */
+
+/* Call _dl_start with one parameter pointing at argc */
+ mr r3,r1
+/* (we have to frob the stack pointer a bit to allow room for
+ _dl_start to save the link register). */
+ li r4,0
+ addi r1,r1,-16
+ stw r4,0(r1)
+ bl _dl_start@local
+
+ /* FALLTHRU */
+_dl_start_user:
+/* Now, we do our main work of calling initialisation procedures.
+ The ELF ABI doesn't say anything about parameters for these,
+ so we just pass argc, argv, and the environment.
+ Changing these is strongly discouraged (not least because argc is
+ passed by value!). */
+
+/* Put our GOT pointer in r31, */
+#ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r31
+ addis r31,r31,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r31,r31,_GLOBAL_OFFSET_TABLE_-1b@l
+#else
+ bl _GLOBAL_OFFSET_TABLE_-4@local
+ mflr r31
+#endif
+/* the address of _start in r30, */
+ mr r30,r3
+/* &_dl_argc in 29, &_dl_argv in 27, and _dl_loaded in 28. */
+ lwz r28,_rtld_global@got(r31)
+ lwz r29,_dl_argc@got(r31)
+ lwz r27,_dl_argv@got(r31)
+
+/* Call _dl_init (_dl_loaded, _dl_argc, _dl_argv, _dl_argv+_dl_argc+1). */
+ lwz r3,0(r28)
+ lwz r4,0(r29)
+ lwz r5,0(r27)
+ slwi r6,r4,2
+ add r6,r5,r6
+ addi r6,r6,4
+ bl _dl_init_internal@local
+
+/* Now, to conform to the ELF ABI, we have to: */
+/* Pass argc (actually _dl_argc) in r3; */
+ lwz r3,0(r29)
+/* pass argv (actually _dl_argv) in r4; */
+ lwz r4,0(r27)
+/* pass envp (actually _dl_argv+_dl_argc+1) in r5; */
+ slwi r5,r3,2
+ add r6,r4,r5
+ addi r5,r6,4
+/* pass the auxilary vector in r6. This is passed to us just after _envp. */
+2: lwzu r0,4(r6)
+ cmpwi r0,0
+ bne 2b
+ addi r6,r6,4
+/* Pass a termination function pointer (in this case _dl_fini) in r7. */
+ lwz r7,_dl_fini@got(r31)
+/* Now, call the start function in r30... */
+ mtctr r30
+/* Pass the stack pointer in r1 (so far so good), pointing to a NULL value.
+ (This lets our startup code distinguish between a program linked statically,
+ which linux will call with argc on top of the stack which will hopefully
+ never be zero, and a dynamically linked program which will always have
+ a NULL on the top of the stack).
+ Take the opportunity to clear LR, so anyone who accidentally returns
+ from _start gets SEGV. Also clear the next few words of the stack. */
+
+_dl_main_dispatch:
+ li r31,0
+ stw r31,0(r1)
+ mtlr r31
+ stw r31,4(r1)
+ stw r31,8(r1)
+ stw r31,12(r1)
+/* Go do it! */
+ bctr
+END(_start)
diff --git a/libc/sysdeps/powerpc/powerpc32/dl-trampoline.S b/libc/sysdeps/powerpc/powerpc32/dl-trampoline.S
new file mode 100644
index 000000000..6a158c3ff
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/dl-trampoline.S
@@ -0,0 +1,186 @@
+/* PLT trampolines. PPC32 version.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+
+ .section ".text"
+ .align 2
+ .globl _dl_runtime_resolve
+ .type _dl_runtime_resolve,@function
+_dl_runtime_resolve:
+ cfi_startproc
+ # We need to save the registers used to pass parameters, and register 0,
+ # which is used by _mcount; the registers are saved in a stack frame.
+ stwu r1,-64(r1)
+ cfi_adjust_cfa_offset (64)
+ stw r0,12(r1)
+ stw r3,16(r1)
+ stw r4,20(r1)
+ # The code that calls this has put parameters for `fixup' in r12 and r11.
+ mr r3,r12
+ stw r5,24(r1)
+ mr r4,r11
+ stw r6,28(r1)
+ mflr r0
+ # We also need to save some of the condition register fields
+ stw r7,32(r1)
+ # Don't clobber the caller's LRSAVE, it is needed by _mcount.
+ stw r0,48(r1)
+ cfi_offset (lr, -16)
+ stw r8,36(r1)
+ mfcr r0
+ stw r9,40(r1)
+ stw r10,44(r1)
+ stw r0,8(r1)
+ bl _dl_fixup@local
+ # 'fixup' returns the address we want to branch to.
+ mtctr r3
+ # Put the registers back...
+ lwz r0,48(r1)
+ lwz r10,44(r1)
+ lwz r9,40(r1)
+ mtlr r0
+ lwz r8,36(r1)
+ lwz r0,8(r1)
+ lwz r7,32(r1)
+ lwz r6,28(r1)
+ mtcrf 0xFF,r0
+ lwz r5,24(r1)
+ lwz r4,20(r1)
+ lwz r3,16(r1)
+ lwz r0,12(r1)
+ # ...unwind the stack frame, and jump to the PLT entry we updated.
+ addi r1,r1,64
+ bctr
+ cfi_endproc
+ .size _dl_runtime_resolve,.-_dl_runtime_resolve
+
+#ifndef PROF
+ .align 2
+ .globl _dl_prof_resolve
+ .type _dl_prof_resolve,@function
+_dl_prof_resolve:
+ cfi_startproc
+ # We need to save the registers used to pass parameters, and register 0,
+ # which is used by _mcount; the registers are saved in a stack frame.
+ stwu r1,-320(r1)
+ cfi_adjust_cfa_offset (320)
+ /* Stack layout:
+
+ +312 stackframe
+ +308 lr
+ +304 r1
+ +288 v12
+ +272 v11
+ +256 v10
+ +240 v9
+ +224 v8
+ +208 v7
+ +192 v6
+ +176 v5
+ +160 v4
+ +144 v3
+ +128 v2
+ +112 v1
+ +104 fp8
+ +96 fp7
+ +88 fp6
+ +80 fp5
+ +72 fp4
+ +64 fp3
+ +56 fp2
+ +48 fp1
+ +44 r10
+ +40 r9
+ +36 r8
+ +32 r7
+ +28 r6
+ +24 r5
+ +20 r4
+ +16 r3
+ +12 r0
+ +8 cr
+ r1 link
+ */
+ stw r0,12(r1)
+ stw r3,16(r1)
+ stw r4,20(r1)
+ # The code that calls this has put parameters for `fixup' in r12 and r11.
+ mr r3,r12
+ stw r5,24(r1)
+ mr r4,r11
+ stw r6,28(r1)
+ mflr r5
+ # We also need to save some of the condition register fields.
+ stw r7,32(r1)
+ # Don't clobber the caller's LRSAVE, it is needed by _mcount.
+ stw r5,308(r1)
+ cfi_offset (lr, -12)
+ stw r8,36(r1)
+ mfcr r0
+ stw r9,40(r1)
+ stw r10,44(r1)
+ stw r0,8(r1)
+ # Save the floating point registers
+ stfd fp1,48(r1)
+ stfd fp2,56(r1)
+ stfd fp3,64(r1)
+ stfd fp4,72(r1)
+ stfd fp5,80(r1)
+ stfd fp6,88(r1)
+ stfd fp7,96(r1)
+ stfd fp8,104(r1)
+ # XXX TODO: store vmx registers
+ # Load the extra parameters.
+ addi r6,r1,16
+ addi r7,r1,312
+ li r0,-1
+ stw r0,0(r7)
+ bl _dl_profile_fixup@local
+ # 'fixup' returns the address we want to branch to.
+ mtctr r3
+ # Put the registers back...
+ lwz r0,308(r1)
+ lwz r10,44(r1)
+ lwz r9,40(r1)
+ mtlr r0
+ lwz r8,36(r1)
+ lwz r0,8(r1)
+ lwz r7,32(r1)
+ lwz r6,28(r1)
+ mtcrf 0xFF,r0
+ lwz r5,24(r1)
+ lwz r4,20(r1)
+ lwz r3,16(r1)
+ lwz r0,12(r1)
+ # Load the floating point registers.
+ lfd fp1,48(r1)
+ lfd fp2,56(r1)
+ lfd fp3,64(r1)
+ lfd fp4,72(r1)
+ lfd fp5,80(r1)
+ lfd fp6,88(r1)
+ lfd fp7,96(r1)
+ lfd fp8,104(r1)
+ # ...unwind the stack frame, and jump to the PLT entry we updated.
+ addi r1,r1,320
+ bctr
+ cfi_endproc
+ .size _dl_prof_resolve,.-_dl_prof_resolve
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/elf/bzero.S b/libc/sysdeps/powerpc/powerpc32/elf/bzero.S
new file mode 100644
index 000000000..17c6f5611
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/elf/bzero.S
@@ -0,0 +1,37 @@
+/* Optimized bzero `implementation' for PowerPC.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+
+ENTRY (BP_SYM (__bzero))
+
+#if __BOUNDED_POINTERS__
+ mr r6,r4
+ li r5,0
+ mr r4,r3
+ /* Tell memset that we don't want a return value. */
+ li r3,0
+#else
+ mr r5,r4
+ li r4,0
+#endif
+ b BP_SYM (memset)@local
+END (BP_SYM (__bzero))
+weak_alias (BP_SYM (__bzero), BP_SYM (bzero))
diff --git a/libc/sysdeps/powerpc/powerpc32/elf/configure b/libc/sysdeps/powerpc/powerpc32/elf/configure
new file mode 100755
index 000000000..536052e0e
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/elf/configure
@@ -0,0 +1,52 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/powerpc32/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+echo "$as_me:$LINENO: checking for powerpc32 TLS support" >&5
+echo $ECHO_N "checking for powerpc32 TLS support... $ECHO_C" >&6
+if test "${libc_cv_powerpc32_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<\EOF
+ .section ".tdata","awT",@progbits
+x: .long 1
+x1: .long 1
+x2: .long 1
+ .text
+ addi 3,31,x@got@tlsgd
+ addi 3,31,x1@got@tlsld
+ addi 9,3,x1@dtprel
+ addis 9,3,x2@dtprel@ha
+ addi 9,9,x2@dtprel@l
+ lwz 0,x1@dtprel(3)
+ addis 9,3,x2@dtprel@ha
+ lwz 0,x2@dtprel@l(9)
+ lwz 9,x3@got@tprel(31)
+ add 9,9,x@tls
+ addi 9,2,x1@tprel
+ addis 9,2,x2@tprel@ha
+ addi 9,9,x2@tprel@l
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_powerpc32_tls=yes
+else
+ libc_cv_powerpc32_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_powerpc32_tls" >&5
+echo "${ECHO_T}$libc_cv_powerpc32_tls" >&6
+if test $libc_cv_powerpc32_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
diff --git a/libc/sysdeps/powerpc/powerpc32/elf/configure.in b/libc/sysdeps/powerpc/powerpc32/elf/configure.in
new file mode 100644
index 000000000..fbf41a498
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/elf/configure.in
@@ -0,0 +1,38 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/powerpc32/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for powerpc32 TLS support, libc_cv_powerpc32_tls, [dnl
+cat > conftest.s <<\EOF
+ .section ".tdata","awT",@progbits
+x: .long 1
+x1: .long 1
+x2: .long 1
+ .text
+ addi 3,31,x@got@tlsgd
+ addi 3,31,x1@got@tlsld
+ addi 9,3,x1@dtprel
+ addis 9,3,x2@dtprel@ha
+ addi 9,9,x2@dtprel@l
+ lwz 0,x1@dtprel(3)
+ addis 9,3,x2@dtprel@ha
+ lwz 0,x2@dtprel@l(9)
+ lwz 9,x3@got@tprel(31)
+ add 9,9,x@tls
+ addi 9,2,x1@tprel
+ addis 9,2,x2@tprel@ha
+ addi 9,9,x2@tprel@l
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_powerpc32_tls=yes
+else
+ libc_cv_powerpc32_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_powerpc32_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
diff --git a/libc/sysdeps/powerpc/powerpc32/elf/start.S b/libc/sysdeps/powerpc/powerpc32/elf/start.S
new file mode 100644
index 000000000..bafd2ae00
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/elf/start.S
@@ -0,0 +1,101 @@
+/* Startup code for programs linked with GNU libc.
+ Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "bp-sym.h"
+
+ /* These are the various addresses we require. */
+#ifdef PIC
+ .section ".data"
+#else
+ .section ".rodata"
+#endif
+ .align 2
+L(start_addresses):
+ .long _SDA_BASE_
+ .long BP_SYM (main)
+ .long __libc_csu_init
+ .long __libc_csu_fini
+ ASM_SIZE_DIRECTIVE(L(start_addresses))
+
+ .section ".text"
+#if defined PIC && !defined HAVE_ASM_PPC_REL16
+L(start_addressesp):
+ .long L(start_addresses)-L(branch)
+#endif
+ENTRY(_start)
+ /* Save the stack pointer, in case we're statically linked under Linux. */
+ mr r9,r1
+ /* Set up an initial stack frame, and clear the LR. */
+ clrrwi r1,r1,4
+#ifdef PIC
+ bcl 20,31,L(branch)
+L(branch):
+ li r0,0
+ mflr r13
+#else
+ li r0,0
+#endif
+ stwu r1,-16(r1)
+ mtlr r0
+ stw r0,0(r1)
+ /* Set r13 to point at the 'small data area', and put the address of
+ start_addresses in r8. Also load the GOT pointer so that new PLT
+ calls work, like the one to __libc_start_main. */
+#ifdef PIC
+# ifdef HAVE_ASM_PPC_REL16
+ addis r30,r13,_GLOBAL_OFFSET_TABLE_-L(branch)@ha
+ addis r8,r13,L(start_addresses)-L(branch)@ha
+ addi r30,r30,_GLOBAL_OFFSET_TABLE_-L(branch)@l
+ lwzu r13,L(start_addresses)-L(branch)@l(r8)
+# else
+ lwz r8,L(start_addressesp)-L(branch)(r13)
+ add r8,r13,r8
+ lwz r13,0(r8)
+# endif
+#else
+ lis r8,L(start_addresses)@ha
+ lwzu r13,L(start_addresses)@l(r8)
+#endif
+ /* and continue in libc-start, in glibc. */
+ b JUMPTARGET(BP_SYM (__libc_start_main))
+END(_start)
+
+/* Define a symbol for the first piece of initialized data. */
+ .section ".data"
+ .globl __data_start
+__data_start:
+weak_alias (__data_start, data_start)
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/Makefile b/libc/sysdeps/powerpc/powerpc32/fpu/Makefile
new file mode 100644
index 000000000..e05073970
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),misc)
+sysdep_routines += fprsave fprrest
+endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S b/libc/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
new file mode 100644
index 000000000..aa24b059d
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
@@ -0,0 +1,164 @@
+/* longjmp for PowerPC.
+ Copyright (C) 1995-99, 2000, 2003-2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#define _ASM
+#ifdef __NO_VMX__
+# include <novmxsetjmp.h>
+#else
+# include <jmpbuf-offsets.h>
+#endif
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+ .machine "altivec"
+ENTRY (BP_SYM (__longjmp))
+ CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
+#ifndef __NO_VMX__
+# ifdef PIC
+ mflr r6
+ cfi_register (lr,r6)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r5
+ addis r5,r5,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r5,r5,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r5
+# endif
+# ifdef SHARED
+ lwz r5,_rtld_global_ro@got(r5)
+ mtlr r6
+ cfi_same_value (lr)
+ lwz r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
+# else
+ lwz r5,_dl_hwcap@got(r5)
+ mtlr r6
+ cfi_same_value (lr)
+ lwz r5,0(r5)
+# endif
+# else
+ lis r5,_dl_hwcap@ha
+ lwz r5,_dl_hwcap@l(r5)
+# endif
+ andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ beq L(no_vmx)
+ la r5,((JB_VRS)*4)(3)
+ andi. r6,r5,0xf
+ lwz r0,((JB_VRSAVE)*4)(3)
+ mtspr VRSAVE,r0
+ beq+ aligned_restore_vmx
+ addi r6,r5,16
+ lvsl v0,0,r5
+ lvx v1,0,r5
+ addi r5,r5,32
+ lvx v21,0,r6
+ vperm v20,v1,v21,v0
+# define load_misaligned_vmx_lo_loaded(loadvr,lovr,shiftvr,loadgpr,addgpr) \
+ addi addgpr,addgpr,32; \
+ lvx lovr,0,loadgpr; \
+ vperm loadvr,loadvr,lovr,shiftvr;
+ load_misaligned_vmx_lo_loaded(v21,v22,v0,r5,r6)
+ load_misaligned_vmx_lo_loaded(v22,v23,v0,r6,r5)
+ load_misaligned_vmx_lo_loaded(v23,v24,v0,r5,r6)
+ load_misaligned_vmx_lo_loaded(v24,v25,v0,r6,r5)
+ load_misaligned_vmx_lo_loaded(v25,v26,v0,r5,r6)
+ load_misaligned_vmx_lo_loaded(v26,v27,v0,r6,r5)
+ load_misaligned_vmx_lo_loaded(v27,v28,v0,r5,r6)
+ load_misaligned_vmx_lo_loaded(v28,v29,v0,r6,r5)
+ load_misaligned_vmx_lo_loaded(v29,v30,v0,r5,r6)
+ load_misaligned_vmx_lo_loaded(v30,v31,v0,r6,r5)
+ lvx v1,0,r5
+ vperm v31,v31,v1,v0
+ b L(no_vmx)
+aligned_restore_vmx:
+ addi r6,r5,16
+ lvx v20,0,r5
+ addi r5,r5,32
+ lvx v21,0,r6
+ addi r6,r6,32
+ lvx v22,0,r5
+ addi r5,r5,32
+ lvx v23,0,r6
+ addi r6,r6,32
+ lvx v24,0,r5
+ addi r5,r5,32
+ lvx v25,0,r6
+ addi r6,r6,32
+ lvx v26,0,r5
+ addi r5,r5,32
+ lvx v27,0,r6
+ addi r6,r6,32
+ lvx v28,0,r5
+ addi r5,r5,32
+ lvx v29,0,r6
+ addi r6,r6,32
+ lvx v30,0,r5
+ lvx v31,0,r6
+L(no_vmx):
+#endif
+ lwz r1,(JB_GPR1*4)(r3)
+ lwz r0,(JB_LR*4)(r3)
+ lwz r14,((JB_GPRS+0)*4)(r3)
+ lfd fp14,((JB_FPRS+0*2)*4)(r3)
+ lwz r15,((JB_GPRS+1)*4)(r3)
+ lfd fp15,((JB_FPRS+1*2)*4)(r3)
+ lwz r16,((JB_GPRS+2)*4)(r3)
+ lfd fp16,((JB_FPRS+2*2)*4)(r3)
+ lwz r17,((JB_GPRS+3)*4)(r3)
+ lfd fp17,((JB_FPRS+3*2)*4)(r3)
+ lwz r18,((JB_GPRS+4)*4)(r3)
+ lfd fp18,((JB_FPRS+4*2)*4)(r3)
+ lwz r19,((JB_GPRS+5)*4)(r3)
+ lfd fp19,((JB_FPRS+5*2)*4)(r3)
+ lwz r20,((JB_GPRS+6)*4)(r3)
+ lfd fp20,((JB_FPRS+6*2)*4)(r3)
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (r0, r25)
+ PTR_DEMANGLE2 (r1, r25)
+#endif
+ mtlr r0
+ lwz r21,((JB_GPRS+7)*4)(r3)
+ lfd fp21,((JB_FPRS+7*2)*4)(r3)
+ lwz r22,((JB_GPRS+8)*4)(r3)
+ lfd fp22,((JB_FPRS+8*2)*4)(r3)
+ lwz r0,(JB_CR*4)(r3)
+ lwz r23,((JB_GPRS+9)*4)(r3)
+ lfd fp23,((JB_FPRS+9*2)*4)(r3)
+ lwz r24,((JB_GPRS+10)*4)(r3)
+ lfd fp24,((JB_FPRS+10*2)*4)(r3)
+ lwz r25,((JB_GPRS+11)*4)(r3)
+ lfd fp25,((JB_FPRS+11*2)*4)(r3)
+ mtcrf 0xFF,r0
+ lwz r26,((JB_GPRS+12)*4)(r3)
+ lfd fp26,((JB_FPRS+12*2)*4)(r3)
+ lwz r27,((JB_GPRS+13)*4)(r3)
+ lfd fp27,((JB_FPRS+13*2)*4)(r3)
+ lwz r28,((JB_GPRS+14)*4)(r3)
+ lfd fp28,((JB_FPRS+14*2)*4)(r3)
+ lwz r29,((JB_GPRS+15)*4)(r3)
+ lfd fp29,((JB_FPRS+15*2)*4)(r3)
+ lwz r30,((JB_GPRS+16)*4)(r3)
+ lfd fp30,((JB_FPRS+16*2)*4)(r3)
+ lwz r31,((JB_GPRS+17)*4)(r3)
+ lfd fp31,((JB_FPRS+17*2)*4)(r3)
+ mr r3,r4
+ blr
+END (BP_SYM (__longjmp))
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/__longjmp.S b/libc/sysdeps/powerpc/powerpc32/fpu/__longjmp.S
new file mode 100644
index 000000000..161bf213c
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/__longjmp.S
@@ -0,0 +1,42 @@
+/* AltiVec/VMX (new) version of __longjmp for PowerPC.
+ Copyright (C) 1995,1996,1997,1999,2000,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <libc-symbols.h>
+#include <rtld-global-offsets.h>
+#include <shlib-compat.h>
+
+#if defined NOT_IN_libc
+/* Build a non-versioned object for rtld-*. */
+# include "__longjmp-common.S"
+
+#else /* !NOT_IN_libc */
+/* Build a versioned object for libc. */
+default_symbol_version (__vmx__longjmp,__longjmp,GLIBC_2.3.4);
+# define __longjmp __vmx__longjmp
+# include "__longjmp-common.S"
+
+# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+# define __NO_VMX__
+# undef JB_SIZE
+symbol_version (__novmx__longjmp,__longjmp,GLIBC_2.0);
+# undef __longjmp
+# define __longjmp __novmx__longjmp
+# include "__longjmp-common.S"
+# endif
+#endif /* !NOT_IN_libc */
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/fprrest.S b/libc/sysdeps/powerpc/powerpc32/fpu/fprrest.S
new file mode 100644
index 000000000..2f6c6deb2
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/fprrest.S
@@ -0,0 +1,95 @@
+/* Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/*
+ Floating Point Registers (FPRs) restore routine
+*/
+
+#include <sysdep.h>
+
+ENTRY(_restfpr_all)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf14)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_14)
+C_TEXT(_restf14):
+C_TEXT(_restfpr_14): lfd fp14,-144(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf15)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_15)
+C_TEXT(_restf15):
+C_TEXT(_restfpr_15): lfd fp15,-136(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf16)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_16)
+C_TEXT(_restf16):
+C_TEXT(_restfpr_16): lfd fp16,-128(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf17)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_17)
+C_TEXT(_restf17):
+C_TEXT(_restfpr_17): lfd fp17,-120(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf18)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_18)
+C_TEXT(_restf18):
+C_TEXT(_restfpr_18): lfd fp18,-112(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf19)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_19)
+C_TEXT(_restf19):
+C_TEXT(_restfpr_19): lfd fp19,-104(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf20)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_20)
+C_TEXT(_restf20):
+C_TEXT(_restfpr_20): lfd fp20,-96(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf21)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_21)
+C_TEXT(_restf21):
+C_TEXT(_restfpr_21): lfd fp21,-88(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf22)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_22)
+C_TEXT(_restf22):
+C_TEXT(_restfpr_22): lfd fp22,-80(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf23)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_23)
+C_TEXT(_restf23):
+C_TEXT(_restfpr_23): lfd fp23,-72(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf24)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_24)
+C_TEXT(_restf24):
+C_TEXT(_restfpr_24): lfd fp24,-64(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf25)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_25)
+C_TEXT(_restf25):
+C_TEXT(_restfpr_25): lfd fp25,-56(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf26)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_26)
+C_TEXT(_restf26):
+C_TEXT(_restfpr_26): lfd fp26,-48(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf27)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_27)
+C_TEXT(_restf27):
+C_TEXT(_restfpr_27): lfd fp27,-40(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf28)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_28)
+C_TEXT(_restf28):
+C_TEXT(_restfpr_28): lfd fp28,-32(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restf29)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restfpr_29)
+C_TEXT(_restf29):
+C_TEXT(_restfpr_29): lwz r0,8(r1) #get return address from frame
+ lfd fp29,-24(r1) #restore f29
+ mtlr r0 #move return address to LR
+ lfd fp30,-16(r1) #restore f30
+ lfd fp31,-8(r1) #restore f31
+ blr #return
+END (_restfpr_all)
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/fprsave.S b/libc/sysdeps/powerpc/powerpc32/fpu/fprsave.S
new file mode 100644
index 000000000..c05178775
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/fprsave.S
@@ -0,0 +1,112 @@
+/* Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/*
+ Floating Point Registers (FPRs) save routine
+*/
+
+#include <sysdep.h>
+
+ENTRY(_savefpr_all)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef14)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_14)
+C_TEXT(_savef14):
+C_TEXT(_savefpr_14): stfd fp14,-144(r1)
+ cfi_offset(fp14,-144)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef15)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_15)
+C_TEXT(_savef15):
+C_TEXT(_savefpr_15): stfd fp15,-136(r1)
+ cfi_offset(fp15,-136)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef16)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_16)
+C_TEXT(_savef16):
+C_TEXT(_savefpr_16): stfd fp16,-128(r1)
+ cfi_offset(fp16,-128)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef17)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_17)
+C_TEXT(_savef17):
+C_TEXT(_savefpr_17): stfd fp17,-120(r1)
+ cfi_offset(fp17,-120)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef18)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_18)
+C_TEXT(_savef18):
+C_TEXT(_savefpr_18): stfd fp18,-112(r1)
+ cfi_offset(fp18,-112)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef19)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_19)
+C_TEXT(_savef19):
+C_TEXT(_savefpr_19): stfd fp19,-104(r1)
+ cfi_offset(fp19,-104)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef20)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_20)
+C_TEXT(_savef20):
+C_TEXT(_savefpr_20): stfd fp20,-96(r1)
+ cfi_offset(fp20,-96)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef21)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_21)
+C_TEXT(_savef21):
+C_TEXT(_savefpr_21): stfd fp21,-88(r1)
+ cfi_offset(fp21,-88)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef22)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_22)
+C_TEXT(_savef22):
+C_TEXT(_savefpr_22): stfd fp22,-80(r1)
+ cfi_offset(fp22,-80)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef23)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_23)
+C_TEXT(_savef23):
+C_TEXT(_savefpr_23): stfd fp23,-72(r1)
+ cfi_offset(fp23,-72)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef24)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_24)
+C_TEXT(_savef24):
+C_TEXT(_savefpr_24): stfd fp24,-64(r1)
+ cfi_offset(fp24,-64)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef25)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_25)
+C_TEXT(_savef25):
+C_TEXT(_savefpr_25): stfd fp25,-56(r1)
+ cfi_offset(fp25,-56)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef26)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_26)
+C_TEXT(_savef26):
+C_TEXT(_savefpr_26): stfd fp26,-48(r1)
+ cfi_offset(fp26,-48)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef27)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_27)
+C_TEXT(_savef27):
+C_TEXT(_savefpr_27): stfd fp27,-40(r1)
+ cfi_offset(fp27,-40)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef28)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_28)
+C_TEXT(_savef28):
+C_TEXT(_savefpr_28): stfd fp28,-32(r1)
+ cfi_offset(fp28,-32)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savef29)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_29)
+C_TEXT(_savef29):
+C_TEXT(_savefpr_29): stfd fp29,-24(r1) #save f29
+ stfd fp30,-16(r1) #save f30
+ stfd fp31,-8(r1) #save f31
+ cfi_offset(fp29,-24)
+ cfi_offset(fp30,-16)
+ cfi_offset(fp31,-8)
+ stw r0,8(r1) #save LR in callers frame
+ blr #return
+END (_savefpr_all)
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_ceil.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_ceil.S
new file mode 100644
index 000000000..bc74d302f
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_ceil.S
@@ -0,0 +1,83 @@
+/* ceil function. PowerPC32 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section .rodata.cst4,"aM",@progbits,4
+ .align 2
+.LC0: /* 2**52 */
+ .long 0x59800000
+
+ .section ".text"
+ENTRY (__ceil)
+ mffs fp11 /* Save current FPU rounding mode. */
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC0-1b@ha
+ lfs fp13,.LC0-1b@l(r9)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC0@got(10)
+ lfs fp13,0(r9)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+#else
+ lis r9,.LC0@ha
+ lfs fp13,.LC0@l(r9)
+#endif
+ fabs fp0,fp1
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,2 /* Set rounding mode toward +inf. */
+ ble- cr6,.L4
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__ceil)
+
+weak_alias (__ceil, ceil)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__ceil, ceill)
+strong_alias (__ceil, __ceill)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __ceil, ceill, GLIBC_2_0)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S
new file mode 100644
index 000000000..47a75ec0c
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S
@@ -0,0 +1,75 @@
+/* float ceil function. PowerPC32 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+
+ .section .rodata.cst4,"aM",@progbits,4
+ .align 2
+.LC0: /* 2**23 */
+ .long 0x4b000000
+
+ .section ".text"
+ENTRY (__ceilf)
+ mffs fp11 /* Save current FPU rounding mode. */
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC0-1b@ha
+ lfs fp13,.LC0-1b@l(r9)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC0@got(10)
+ lfs fp13,0(r9)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+#else
+ lis r9,.LC0@ha
+ lfs fp13,.LC0@l(r9)
+#endif
+ fabs fp0,fp1
+ fsubs fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,2 /* Set rounding mode toward +inf. */
+ ble- cr6,.L4
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__ceilf)
+
+weak_alias (__ceilf, ceilf)
+
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_copysign.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_copysign.S
new file mode 100644
index 000000000..dd68b0869
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_copysign.S
@@ -0,0 +1,60 @@
+/* Copy a sign bit between floating-point values.
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/* This has been coded in assembler because GCC makes such a mess of it
+ when it's coded in C. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ENTRY(__copysign)
+/* double [f1] copysign (double [f1] x, double [f2] y);
+ copysign(x,y) returns a value with the magnitude of x and
+ with the sign bit of y. */
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ stfd fp2,8(r1)
+ lwz r3,8(r1)
+ cmpwi r3,0
+ addi r1,r1,16
+ cfi_adjust_cfa_offset (-16)
+ blt L(0)
+ fabs fp1,fp1
+ blr
+L(0): fnabs fp1,fp1
+ blr
+ END (__copysign)
+
+weak_alias (__copysign,copysign)
+
+/* It turns out that it's safe to use this code even for single-precision. */
+weak_alias (__copysign,copysignf)
+strong_alias(__copysign,__copysignf)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__copysign,copysignl)
+strong_alias(__copysign,__copysignl)
+#endif
+#ifdef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __copysign, copysignl, GLIBC_2_0)
+# endif
+#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __copysign, copysignl, GLIBC_2_0)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_copysignf.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_copysignf.S
new file mode 100644
index 000000000..e05438ae7
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_copysignf.S
@@ -0,0 +1 @@
+/* __copysignf is in s_copysign.S */
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S
new file mode 100644
index 000000000..64b6a4543
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S
@@ -0,0 +1,50 @@
+/* Copy a sign bit between floating-point values.
+ IBM extended format long double version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ENTRY(__copysignl)
+/* long double [f1,f2] copysign (long double [f1,f2] x, long double [f3,f4] y);
+ copysign(x,y) returns a value with the magnitude of x and
+ with the sign bit of y. */
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ stfd fp3,8(r1)
+ fmr fp0,fp1
+ fabs fp1,fp1
+ fcmpu cr7,fp0,fp1
+ lwz r3,8(r1)
+ cmpwi cr6,r3,0
+ addi r1,r1,16
+ cfi_adjust_cfa_offset (-16)
+ beq cr7,L(0)
+ fneg fp2,fp2
+L(0): bgelr cr6
+ fneg fp1,fp1
+ fneg fp2,fp2
+ blr
+END (__copysignl)
+
+#ifdef IS_IN_libm
+long_double_symbol (libm, __copysignl, copysignl)
+#else
+long_double_symbol (libc, __copysignl, copysignl)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_fabs.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_fabs.S
new file mode 100644
index 000000000..53d21301e
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_fabs.S
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/powerpc/fpu/s_fabs.S>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __fabs, fabsl, GLIBC_2_0)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S
new file mode 100644
index 000000000..3655e5b2f
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S
@@ -0,0 +1,36 @@
+/* Copy a sign bit between floating-point values.
+ IBM extended format long double version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ENTRY(__fabsl)
+/* long double [f1,f2] fabs (long double [f1,f2] x);
+ fabs(x,y) returns a value with the magnitude of x and
+ with the sign bit of y. */
+ fmr fp0,fp1
+ fabs fp1,fp1
+ fcmpu cr1,fp0,fp1
+ beqlr cr1
+ fneg fp2,fp2
+ blr
+END (__fabsl)
+
+long_double_symbol (libm, __fabsl, fabsl)
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_fdim.c b/libc/sysdeps/powerpc/powerpc32/fpu/s_fdim.c
new file mode 100644
index 000000000..e34b51ee5
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_fdim.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/powerpc/fpu/s_fdim.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fdim, fdiml, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_floor.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_floor.S
new file mode 100644
index 000000000..a29e4791e
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_floor.S
@@ -0,0 +1,83 @@
+/* Floor function. PowerPC32 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section .rodata.cst4,"aM",@progbits,4
+ .align 2
+.LC0: /* 2**52 */
+ .long 0x59800000
+
+ .section ".text"
+ENTRY (__floor)
+ mffs fp11 /* Save current FPU rounding mode. */
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC0-1b@ha
+ lfs fp13,.LC0-1b@l(r9)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC0@got(10)
+ lfs fp13,0(r9)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+#else
+ lis r9,.LC0@ha
+ lfs fp13,.LC0@l(r9)
+#endif
+ fabs fp0,fp1
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,3 /* Set rounding mode toward -inf. */
+ ble- cr6,.L4
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__floor)
+
+weak_alias (__floor, floor)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__floor, floorl)
+strong_alias (__floor, __floorl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __floor, floorl, GLIBC_2_0)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_floorf.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_floorf.S
new file mode 100644
index 000000000..99fbdc5f8
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_floorf.S
@@ -0,0 +1,75 @@
+/* float Floor function. PowerPC32 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+
+ .section .rodata.cst4,"aM",@progbits,4
+ .align 2
+.LC0: /* 2**23 */
+ .long 0x4b000000
+
+ .section ".text"
+ENTRY (__floorf)
+ mffs fp11 /* Save current FPU rounding mode. */
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC0-1b@ha
+ lfs fp13,.LC0-1b@l(r9)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC0@got(10)
+ lfs fp13,0(r9)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+#else
+ lis r9,.LC0@ha
+ lfs fp13,.LC0@l(r9)
+#endif
+ fabs fp0,fp1
+ fsubs fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,3 /* Set rounding mode toward -inf. */
+ ble- cr6,.L4
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__floorf)
+
+weak_alias (__floorf, floorf)
+
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_fmax.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_fmax.S
new file mode 100644
index 000000000..69735761a
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_fmax.S
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/powerpc/fpu/s_fmax.S>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fmax, fmaxl, GLIBC_2_1)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_fmin.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_fmin.S
new file mode 100644
index 000000000..6d4a0a946
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_fmin.S
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/powerpc/fpu/s_fmin.S>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fmin, fminl, GLIBC_2_1)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_isnan.c b/libc/sysdeps/powerpc/powerpc32/fpu/s_isnan.c
new file mode 100644
index 000000000..397717ba9
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_isnan.c
@@ -0,0 +1,7 @@
+#include <sysdeps/powerpc/fpu/s_isnan.c>
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
+compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
+# endif
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_llrint.c b/libc/sysdeps/powerpc/powerpc32/fpu/s_llrint.c
new file mode 100644
index 000000000..cb96be7c9
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_llrint.c
@@ -0,0 +1,35 @@
+/* Round a double value to a long long in the current rounding mode.
+ Copyright (C) 1997, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+long long int
+__llrint (double x)
+{
+ return (long long int) __rint (x);
+}
+weak_alias (__llrint, llrint)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__llrint, __llrintl)
+weak_alias (__llrint, llrintl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __llrint, llrintl, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_llrintf.c b/libc/sysdeps/powerpc/powerpc32/fpu/s_llrintf.c
new file mode 100644
index 000000000..0439e4558
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_llrintf.c
@@ -0,0 +1,27 @@
+/* Round a float value to a long long in the current rounding mode.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "math.h"
+
+long long int
+__llrintf (float x)
+{
+ return (long long int) __rintf (x);
+}
+weak_alias (__llrintf, llrintf)
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_lrint.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_lrint.S
new file mode 100644
index 000000000..55e9de7e2
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_lrint.S
@@ -0,0 +1,45 @@
+/* Round double to long int. PowerPC32 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* long int[r3] __lrint (double x[fp1]) */
+ENTRY (__lrint)
+ fctiw fp13,fp1
+ stfd fp13,-8(r1)
+ nop /* Insure the following load is in a different dispatch group */
+ nop /* to avoid pipe stall on POWER4&5. */
+ nop
+ lwz r3,-4(r1)
+ blr
+ END (__lrint)
+
+weak_alias (__lrint, lrint)
+
+strong_alias (__lrint, __lrintf)
+weak_alias (__lrint, lrintf)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__lrint, __lrintl)
+weak_alias (__lrint, lrintl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __lrint, lrintl, GLIBC_2_1)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_lround.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_lround.S
new file mode 100644
index 000000000..9c534ec2b
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_lround.S
@@ -0,0 +1,99 @@
+/* lround function. PowerPC32 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section .rodata.cst8,"aM",@progbits,8
+ .align 2
+.LC0: /* 0.0 */
+ .long 0x00000000
+.LC1: /* 0.5 */
+ .long 0x3f000000
+
+ .section ".text"
+
+/* long [r3] lround (float x [fp1])
+ IEEE 1003.1 lround function. IEEE specifies "round to the nearest
+ integer value, rounding halfway cases away from zero, regardless of
+ the current rounding mode." However PowerPC Architecture defines
+ "round to Nearest" as "Choose the best approximation. In case of a
+ tie, choose the one that is even (least significant bit o).".
+ So we can't use the PowerPC "round to Nearest" mode. Instead we set
+ "round toward Zero" mode and round by adding +-0.5 before rounding
+ to the integer value. */
+
+ENTRY (__lround)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC0-1b@ha
+ addi r9,r9,.LC0-1b@l
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC0@got(10)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+ lfs fp12,0(r9)
+#else
+ lis r9,.LC0@ha
+ lfs fp12,.LC0@l(r9)
+#endif
+#ifdef SHARED
+ lfs fp10,.LC1-.LC0(r9)
+#else
+ lis r9,.LC1@ha
+ lfs fp10,.LC1@l(r9)
+#endif
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ ble- cr6,.L4
+ fadd fp1,fp1,fp10 /* x+= 0.5; */
+.L9:
+ fctiwz fp2,fp1 /* Convert To Integer DW lround toward 0. */
+ stfd fp2,8(r1)
+ nop /* Ensure the following load is in a different dispatch */
+ nop /* group to avoid pipe stall on POWER4&5. */
+ nop
+ lwz r3,12(r1)
+ addi r1,r1,16
+ blr
+.L4:
+ fsub fp1,fp1,fp10 /* x-= 0.5; */
+ b .L9
+ END (__lround)
+
+weak_alias (__lround, lround)
+
+strong_alias (__lround, __lroundf)
+weak_alias (__lround, lroundf)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__lround, lroundl)
+strong_alias (__lround, __lroundl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __lround, lroundl, GLIBC_2_1)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_lroundf.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_lroundf.S
new file mode 100644
index 000000000..e3c992d77
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_lroundf.S
@@ -0,0 +1,2 @@
+/* __lroundf is in s_lround.S */
+/* __lroundf is in s_lround.S */
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_rint.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_rint.S
new file mode 100644
index 000000000..c8dca313a
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_rint.S
@@ -0,0 +1,79 @@
+/* Round to int floating-point values. PowerPC32 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/* This has been coded in assembler because GCC makes such a mess of it
+ when it's coded in C. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section .rodata.cst4,"aM",@progbits,4
+ .align 2
+.LC0: /* 2**52 */
+ .long 0x59800000
+
+ .section ".text"
+ENTRY (__rint)
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC0-1b@ha
+ lfs fp13,.LC0-1b@l(r9)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC0@got(10)
+ lfs fp13,0(r9)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+#else
+ lis r9,.LC0@ha
+ lfs fp13,.LC0@l(r9)
+#endif
+ fabs fp0,fp1
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ bng- cr6,.L4
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ blr /* x = 0.0; */
+.L4:
+ bnllr- cr6 /* if (x < 0.0) */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ blr /* x = -0.0; */
+ END (__rint)
+
+weak_alias (__rint, rint)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__rint, rintl)
+strong_alias (__rint, __rintl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __rint, rintl, GLIBC_2_0)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_rintf.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_rintf.S
new file mode 100644
index 000000000..7771cb2bc
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_rintf.S
@@ -0,0 +1,68 @@
+/* Round float to int floating-point values. PowerPC32 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+
+ .section .rodata.cst4,"aM",@progbits,4
+ .align 2
+.LC0: /* 2**23 */
+ .long 0x4b000000
+
+ .section ".text"
+ENTRY (__rintf)
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC0-1b@ha
+ lfs fp13,.LC0-1b@l(r9)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC0@got(10)
+ lfs fp13,0(r9)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+#else
+ lis r9,.LC0@ha
+ lfs fp13,.LC0@l(r9)
+#endif
+ fabs fp0,fp1
+ fsubs fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ bng- cr6,.L4
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ blr /* x = 0.0; */
+.L4:
+ bnllr- cr6 /* if (x < 0.0) */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ blr /* x = -0.0; */
+ END (__rintf)
+
+weak_alias (__rintf, rintf)
+
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_round.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_round.S
new file mode 100644
index 000000000..590c87ad8
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_round.S
@@ -0,0 +1,103 @@
+/* round function. PowerPC32 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section .rodata.cst8,"aM",@progbits,8
+ .align 2
+.LC0: /* 2**52 */
+ .long 0x59800000
+.LC1: /* 0.5 */
+ .long 0x3f000000
+
+/* double [fp1] round (double x [fp1])
+ IEEE 1003.1 round function. IEEE specifies "round to the nearest
+ integer value, rounding halfway cases away from zero, regardless of
+ the current rounding mode." However PowerPC Architecture defines
+ "Round to Nearest" as "Choose the best approximation. In case of a
+ tie, choose the one that is even (least significant bit o).".
+ So we can't use the PowerPC "Round to Nearest" mode. Instead we set
+ "Round toward Zero" mode and round by adding +-0.5 before rounding
+ to the integer value. */
+
+ .section ".text"
+ENTRY (__round)
+ mffs fp11 /* Save current FPU rounding mode. */
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC0-1b@ha
+ addi r9,r9,.LC0-1b@l
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC0@got(10)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+ lfs fp13,0(r9)
+#else
+ lis r9,.LC0@ha
+ lfs fp13,.LC0@l(r9)
+#endif
+ fabs fp0,fp1
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,1 /* Set rounding mode toward 0. */
+#ifdef SHARED
+ lfs fp10,.LC1-.LC0(r9)
+#else
+ lis r9,.LC1@ha
+ lfs fp10,.LC1@l(r9)
+#endif
+ ble- cr6,.L4
+ fadd fp1,fp1,fp10 /* x+= 0.5; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ fsub fp9,fp1,fp10 /* x+= 0.5; */
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsub fp1,fp9,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__round)
+
+weak_alias (__round, round)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__round, roundl)
+strong_alias (__round, __roundl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __round, roundl, GLIBC_2_1)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_roundf.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_roundf.S
new file mode 100644
index 000000000..7e99bca31
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_roundf.S
@@ -0,0 +1,95 @@
+/* roundf function. PowerPC32 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+
+ .section .rodata.cst8,"aM",@progbits,8
+ .align 2
+.LC0: /* 2**23 */
+ .long 0x4b000000
+.LC1: /* 0.5 */
+ .long 0x3f000000
+
+/* float [fp1] roundf (float x [fp1])
+ IEEE 1003.1 round function. IEEE specifies "round to the nearest
+ integer value, rounding halfway cases away from zero, regardless of
+ the current rounding mode." However PowerPC Architecture defines
+ "Round to Nearest" as "Choose the best approximation. In case of a
+ tie, choose the one that is even (least significant bit o).".
+ So we can't use the PowerPC "Round to Nearest" mode. Instead we set
+ "Round toward Zero" mode and round by adding +-0.5 before rounding
+ to the integer value. */
+
+ .section ".text"
+ENTRY (__roundf )
+ mffs fp11 /* Save current FPU rounding mode. */
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC0-1b@ha
+ addi r9,r9,.LC0-1b@l
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC0@got(10)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+ lfs fp13,0(r9)
+#else
+ lis r9,.LC0@ha
+ lfs fp13,.LC0@l(r9)
+#endif
+ fabs fp0,fp1
+ fsubs fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,1 /* Set rounding mode toward 0. */
+#ifdef SHARED
+ lfs fp10,.LC1-.LC0(r9)
+#else
+ lis r9,.LC1@ha
+ lfs fp10,.LC1@l(r9)
+#endif
+ ble- cr6,.L4
+ fadds fp1,fp1,fp10 /* x+= 0.5; */
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ fsubs fp9,fp1,fp10 /* x+= 0.5; */
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsubs fp1,fp9,fp13 /* x-= TWO23; */
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__roundf)
+
+weak_alias (__roundf, roundf)
+
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_trunc.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_trunc.S
new file mode 100644
index 000000000..5bc0856b9
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_trunc.S
@@ -0,0 +1,90 @@
+/* trunc function. PowerPC32 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section .rodata.cst4,"aM",@progbits,4
+ .align 2
+.LC0: /* 2**52 */
+ .long 0x59800000
+
+/* double [fp1] trunc (double x [fp1])
+ IEEE 1003.1 trunc function. IEEE specifies "trunc to the integer
+ value, in floating format, nearest to but no larger in magnitude
+ then the argument."
+ We set "round toward Zero" mode and trunc by adding +-2**52 then
+ subtracting +-2**52. */
+
+ .section ".text"
+ENTRY (__trunc)
+ mffs fp11 /* Save current FPU rounding mode. */
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC0-1b@ha
+ lfs fp13,.LC0-1b@l(r9)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC0@got(10)
+ lfs fp13,0(r9)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+#else
+ lis r9,.LC0@ha
+ lfs fp13,.LC0@l(r9)
+#endif
+ fabs fp0,fp1
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,1 /* Set rounding toward 0 mode. */
+ ble- cr6,.L4
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__trunc)
+
+weak_alias (__trunc, trunc)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__trunc, truncl)
+strong_alias (__trunc, __truncl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __trunc, truncl, GLIBC_2_1)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/s_truncf.S b/libc/sysdeps/powerpc/powerpc32/fpu/s_truncf.S
new file mode 100644
index 000000000..e2e3bd674
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/s_truncf.S
@@ -0,0 +1,82 @@
+/* truncf function. PowerPC32 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+
+ .section .rodata.cst4,"aM",@progbits,4
+ .align 2
+.LC0: /* 2**23 */
+ .long 0x4b000000
+
+/* float [fp1] truncf (float x [fp1])
+ IEEE 1003.1 trunc function. IEEE specifies "trunc to the integer
+ value, in floating format, nearest to but no larger in magnitude
+ then the argument."
+ We set "round toward Zero" mode and trunc by adding +-2**23 then
+ subtracting +-2**23. */
+
+ .section ".text"
+ENTRY (__truncf)
+ mffs fp11 /* Save current FPU rounding mode. */
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC0-1b@ha
+ lfs fp13,.LC0-1b@l(r9)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC0@got(10)
+ lfs fp13,0(r9)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+#else
+ lis r9,.LC0@ha
+ lfs fp13,.LC0@l(r9)
+#endif
+ fabs fp0,fp1
+ fsubs fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,1 /* Set rounding toward 0 mode. */
+ ble- cr6,.L4
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__truncf)
+
+weak_alias (__truncf, truncf)
+
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S b/libc/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S
new file mode 100644
index 000000000..851480d2e
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S
@@ -0,0 +1,184 @@
+/* setjmp for PowerPC.
+ Copyright (C) 1995-2000, 2003-2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#define _ASM
+#ifdef __NO_VMX__
+# include <novmxsetjmp.h>
+#else
+# include <jmpbuf-offsets.h>
+#endif
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+ .machine "altivec"
+ENTRY (BP_SYM (__sigsetjmp))
+ CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
+
+#ifdef PTR_MANGLE
+ mr r5,r1
+ PTR_MANGLE(r5, r6)
+ stw r5,(JB_GPR1*4)(3)
+#else
+ stw r1,(JB_GPR1*4)(3)
+#endif
+ mflr r0
+ stw r14,((JB_GPRS+0)*4)(3)
+ stfd fp14,((JB_FPRS+0*2)*4)(3)
+#ifdef PTR_MANGLE
+ PTR_MANGLE2 (r0, r6)
+#endif
+ stw r0,(JB_LR*4)(3)
+ stw r15,((JB_GPRS+1)*4)(3)
+ stfd fp15,((JB_FPRS+1*2)*4)(3)
+ mfcr r0
+ stw r16,((JB_GPRS+2)*4)(3)
+ stfd fp16,((JB_FPRS+2*2)*4)(3)
+ stw r0,(JB_CR*4)(3)
+ stw r17,((JB_GPRS+3)*4)(3)
+ stfd fp17,((JB_FPRS+3*2)*4)(3)
+ stw r18,((JB_GPRS+4)*4)(3)
+ stfd fp18,((JB_FPRS+4*2)*4)(3)
+ stw r19,((JB_GPRS+5)*4)(3)
+ stfd fp19,((JB_FPRS+5*2)*4)(3)
+ stw r20,((JB_GPRS+6)*4)(3)
+ stfd fp20,((JB_FPRS+6*2)*4)(3)
+ stw r21,((JB_GPRS+7)*4)(3)
+ stfd fp21,((JB_FPRS+7*2)*4)(3)
+ stw r22,((JB_GPRS+8)*4)(3)
+ stfd fp22,((JB_FPRS+8*2)*4)(3)
+ stw r23,((JB_GPRS+9)*4)(3)
+ stfd fp23,((JB_FPRS+9*2)*4)(3)
+ stw r24,((JB_GPRS+10)*4)(3)
+ stfd fp24,((JB_FPRS+10*2)*4)(3)
+ stw r25,((JB_GPRS+11)*4)(3)
+ stfd fp25,((JB_FPRS+11*2)*4)(3)
+ stw r26,((JB_GPRS+12)*4)(3)
+ stfd fp26,((JB_FPRS+12*2)*4)(3)
+ stw r27,((JB_GPRS+13)*4)(3)
+ stfd fp27,((JB_FPRS+13*2)*4)(3)
+ stw r28,((JB_GPRS+14)*4)(3)
+ stfd fp28,((JB_FPRS+14*2)*4)(3)
+ stw r29,((JB_GPRS+15)*4)(3)
+ stfd fp29,((JB_FPRS+15*2)*4)(3)
+ stw r30,((JB_GPRS+16)*4)(3)
+ stfd fp30,((JB_FPRS+16*2)*4)(3)
+ stw r31,((JB_GPRS+17)*4)(3)
+ stfd fp31,((JB_FPRS+17*2)*4)(3)
+#ifndef __NO_VMX__
+# ifdef PIC
+ mflr r6
+ cfi_register(lr,r6)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r5
+ addis r5,r5,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r5,r5,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r5
+# endif
+ mtlr r6
+ cfi_same_value (lr)
+# ifdef SHARED
+ lwz r5,_rtld_global_ro@got(r5)
+ lwz r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
+# else
+ lwz r5,_dl_hwcap@got(r5)
+ lwz r5,0(r5)
+# endif
+# else
+ lis r6,_dl_hwcap@ha
+ lwz r5,_dl_hwcap@l(r6)
+# endif
+ andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ beq L(no_vmx)
+ la r5,((JB_VRS)*4)(3)
+ andi. r6,r5,0xf
+ mfspr r0,VRSAVE
+ stw r0,((JB_VRSAVE)*4)(3)
+ addi r6,r5,16
+ beq+ L(aligned_save_vmx)
+ lvsr v0,0,r5
+ vspltisb v1,-1 /* set v1 to all 1's */
+ vspltisb v2,0 /* set v2 to all 0's */
+ vperm v3,v2,v1,v0 /* v3 contains shift mask with num all 1 bytes on left = misalignment */
+
+
+ /* Special case for v20 we need to preserve what is in save area below v20 before obliterating it */
+ lvx v5,0,r5
+ vperm v20,v20,v20,v0
+ vsel v5,v5,v20,v3
+ vsel v20,v20,v2,v3
+ stvx v5,0,r5
+
+#define save_2vmx_partial(savevr,prev_savevr,hivr,shiftvr,maskvr,savegpr,addgpr) \
+ addi addgpr,addgpr,32; \
+ vperm savevr,savevr,savevr,shiftvr; \
+ vsel hivr,prev_savevr,savevr,maskvr; \
+ stvx hivr,0,savegpr;
+
+ save_2vmx_partial(v21,v20,v5,v0,v3,r6,r5)
+ save_2vmx_partial(v22,v21,v5,v0,v3,r5,r6)
+ save_2vmx_partial(v23,v22,v5,v0,v3,r6,r5)
+ save_2vmx_partial(v24,v23,v5,v0,v3,r5,r6)
+ save_2vmx_partial(v25,v24,v5,v0,v3,r6,r5)
+ save_2vmx_partial(v26,v25,v5,v0,v3,r5,r6)
+ save_2vmx_partial(v27,v26,v5,v0,v3,r6,r5)
+ save_2vmx_partial(v28,v27,v5,v0,v3,r5,r6)
+ save_2vmx_partial(v29,v28,v5,v0,v3,r6,r5)
+ save_2vmx_partial(v30,v29,v5,v0,v3,r5,r6)
+
+ /* Special case for r31 we need to preserve what is in save area above v31 before obliterating it */
+ addi r5,r5,32
+ vperm v31,v31,v31,v0
+ lvx v4,0,r5
+ vsel v5,v30,v31,v3
+ stvx v5,0,r6
+ vsel v4,v31,v4,v3
+ stvx v4,0,r5
+ b L(no_vmx)
+
+L(aligned_save_vmx):
+ stvx 20,0,r5
+ addi r5,r5,32
+ stvx 21,0,r6
+ addi r6,r6,32
+ stvx 22,0,r5
+ addi r5,r5,32
+ stvx 23,0,r6
+ addi r6,r6,32
+ stvx 24,0,r5
+ addi r5,r5,32
+ stvx 25,0,r6
+ addi r6,r6,32
+ stvx 26,0,r5
+ addi r5,r5,32
+ stvx 27,0,r6
+ addi r6,r6,32
+ stvx 28,0,r5
+ addi r5,r5,32
+ stvx 29,0,r6
+ addi r6,r6,32
+ stvx 30,0,r5
+ stvx 31,0,r6
+L(no_vmx):
+#endif
+ b BP_SYM (__sigjmp_save@local)
+END (BP_SYM (__sigsetjmp))
diff --git a/libc/sysdeps/powerpc/powerpc32/fpu/setjmp.S b/libc/sysdeps/powerpc/powerpc32/fpu/setjmp.S
new file mode 100644
index 000000000..139611a9b
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/fpu/setjmp.S
@@ -0,0 +1,45 @@
+/* non alitivec (old) version of setjmp for PowerPC.
+ Copyright (C) 1995-1997,1999,2000,2003,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <libc-symbols.h>
+#include <rtld-global-offsets.h>
+#include <shlib-compat.h>
+
+#if defined NOT_IN_libc
+/* Build a non-versioned object for rtld-*. */
+# include "setjmp-common.S"
+
+#else /* !NOT_IN_libc */
+/* Build a versioned object for libc. */
+default_symbol_version (__vmx__sigsetjmp,__sigsetjmp,GLIBC_2.3.4)
+# define __sigsetjmp __vmx__sigsetjmp
+# define __sigjmp_save __vmx__sigjmp_save
+# include "setjmp-common.S"
+
+# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+# define __NO_VMX__
+# undef __sigsetjmp
+# undef __sigjmp_save
+# undef JB_SIZE
+symbol_version (__novmx__sigsetjmp,__sigsetjmp,GLIBC_2.0)
+# define __sigsetjmp __novmx__sigsetjmp
+# define __sigjmp_save __novmx__sigjmp_save
+# include "setjmp-common.S"
+# endif
+#endif /* !NOT_IN_libc */
diff --git a/libc/sysdeps/powerpc/powerpc32/gprrest0.S b/libc/sysdeps/powerpc/powerpc32/gprrest0.S
new file mode 100644
index 000000000..90eb4a0c4
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/gprrest0.S
@@ -0,0 +1,70 @@
+/* Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/*
+ General Purpose Register (GPR) restore routine
+ when Floating Point Registers (FPRs) are not saved
+
+ Note: This restore routine must not be called when GPR30 or
+ GPR31, or both, are the only registers beings saved. In these
+ cases, the saving and restoring must be done inline.
+*/
+
+#include <sysdep.h>
+
+ENTRY(_restgpr0_all)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_13)
+C_TEXT(_restgpr0_13): lwz r13,-76(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_14)
+C_TEXT(_restgpr0_14): lwz r14,-72(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_15)
+C_TEXT(_restgpr0_15): lwz r15,-68(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_16)
+C_TEXT(_restgpr0_16): lwz r16,-64(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_17)
+C_TEXT(_restgpr0_17): lwz r17,-60(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_18)
+C_TEXT(_restgpr0_18): lwz r18,-56(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_19)
+C_TEXT(_restgpr0_19): lwz r19,-52(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_20)
+C_TEXT(_restgpr0_20): lwz r20,-48(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_21)
+C_TEXT(_restgpr0_21): lwz r21,-44(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_22)
+C_TEXT(_restgpr0_22): lwz r22,-40(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_23)
+C_TEXT(_restgpr0_23): lwz r23,-36(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_24)
+C_TEXT(_restgpr0_24): lwz r24,-32(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_25)
+C_TEXT(_restgpr0_25): lwz r25,-28(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_26)
+C_TEXT(_restgpr0_26): lwz r26,-24(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_27)
+C_TEXT(_restgpr0_27): lwz r27,-20(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_28)
+C_TEXT(_restgpr0_28): lwz r28,-16(r1)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr0_29)
+C_TEXT(_restgpr0_29): lwz r0,8(r1) #get return address from frame
+ lwz r29,-12(r1) #restore r29
+ mtlr r0 #move return address to LR
+ lwz r30,-8(r1) #restore r30
+ lwz r31,-4(r1) #restore r31
+ blr #return
+END (_restgpr0_all)
diff --git a/libc/sysdeps/powerpc/powerpc32/gprrest1.S b/libc/sysdeps/powerpc/powerpc32/gprrest1.S
new file mode 100644
index 000000000..ca00b8f13
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/gprrest1.S
@@ -0,0 +1,64 @@
+/* Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/*
+ General Purpose Register (GPR) restore routine
+ when Floating Point Registers (FPRs) are saved
+*/
+
+#include <sysdep.h>
+
+ENTRY(_restgpr1_all)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_13)
+C_TEXT(_restgpr1_13): lwz r13,-76(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_14)
+C_TEXT(_restgpr1_14): lwz r14,-72(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_15)
+C_TEXT(_restgpr1_15): lwz r15,-68(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_16)
+C_TEXT(_restgpr1_16): lwz r16,-64(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_17)
+C_TEXT(_restgpr1_17): lwz r17,-60(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_18)
+C_TEXT(_restgpr1_18): lwz r18,-56(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_19)
+C_TEXT(_restgpr1_19): lwz r19,-52(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_20)
+C_TEXT(_restgpr1_20): lwz r20,-48(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_21)
+C_TEXT(_restgpr1_21): lwz r21,-44(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_22)
+C_TEXT(_restgpr1_22): lwz r22,-40(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_23)
+C_TEXT(_restgpr1_23): lwz r23,-36(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_24)
+C_TEXT(_restgpr1_24): lwz r24,-32(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_25)
+C_TEXT(_restgpr1_25): lwz r25,-28(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_26)
+C_TEXT(_restgpr1_26): lwz r26,-24(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_27)
+C_TEXT(_restgpr1_27): lwz r27,-20(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_28)
+C_TEXT(_restgpr1_28): lwz r28,-16(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_restgpr1_29)
+C_TEXT(_restgpr1_29): lwz r29,-12(r12) #restore r29
+ lwz r30,-8(r12) #restore r30
+ lwz r31,-4(r12) #restore r31
+ blr #return
+END (_restgpr1_all)
diff --git a/libc/sysdeps/powerpc/powerpc32/gprsave0.S b/libc/sysdeps/powerpc/powerpc32/gprsave0.S
new file mode 100644
index 000000000..c74272b56
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/gprsave0.S
@@ -0,0 +1,88 @@
+/* Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/*
+ General Purpose Register (GPR) save routine
+ when Floating Point Registers (FPRs) are not saved
+
+ Note: This save routine must not be called when GPR30 or
+ GPR31, or both, are the only registers beings saved. In these
+ cases, the saving and restoring must be done inline.
+*/
+
+#include <sysdep.h>
+
+ENTRY(_savegpr0_all)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_13)
+C_TEXT(_savegpr0_13): stw r13,-76(r1)
+ cfi_offset(r13,-76)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_14)
+C_TEXT(_savegpr0_14): stw r14,-72(r1)
+ cfi_offset(r14,-72)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_15)
+C_TEXT(_savegpr0_15): stw r15,-68(r1)
+ cfi_offset(r15,-68)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_16)
+C_TEXT(_savegpr0_16): stw r16,-64(r1)
+ cfi_offset(r16,-64)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_17)
+C_TEXT(_savegpr0_17): stw r17,-60(r1)
+ cfi_offset(r17,-60)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_18)
+C_TEXT(_savegpr0_18): stw r18,-56(r1)
+ cfi_offset(r18,-56)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_19)
+C_TEXT(_savegpr0_19): stw r19,-52(r1)
+ cfi_offset(r19,-52)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_20)
+C_TEXT(_savegpr0_20): stw r20,-48(r1)
+ cfi_offset(r20,-48)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_21)
+C_TEXT(_savegpr0_21): stw r21,-44(r1)
+ cfi_offset(r21,-44)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_22)
+C_TEXT(_savegpr0_22): stw r22,-40(r1)
+ cfi_offset(r22,-40)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_23)
+C_TEXT(_savegpr0_23): stw r23,-36(r1)
+ cfi_offset(r23,-36)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_24)
+C_TEXT(_savegpr0_24): stw r24,-32(r1)
+ cfi_offset(r24,-32)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_25)
+C_TEXT(_savegpr0_25): stw r25,-28(r1)
+ cfi_offset(r25,-28)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_26)
+C_TEXT(_savegpr0_26): stw r26,-24(r1)
+ cfi_offset(r26,-24)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_27)
+C_TEXT(_savegpr0_27): stw r27,-20(r1)
+ cfi_offset(r27,-20)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_28)
+C_TEXT(_savegpr0_28): stw r28,-16(r1)
+ cfi_offset(r28,-16)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_29)
+C_TEXT(_savegpr0_29): stw r29,-12(r1) #save r29
+ stw r30,-8(r1) #save r30
+ stw r31,-4(r1) #save r31
+ cfi_offset(r29,-12)
+ cfi_offset(r30,-8)
+ cfi_offset(r31,-4)
+ stw r0,8(r1) #save LR in callers frame
+ blr #return
+END (_savegpr0_all)
diff --git a/libc/sysdeps/powerpc/powerpc32/gprsave1.S b/libc/sysdeps/powerpc/powerpc32/gprsave1.S
new file mode 100644
index 000000000..6c1790129
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/gprsave1.S
@@ -0,0 +1,64 @@
+/* Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/*
+ General Purpose Register (GPR) save routine
+ when Floating Point Registers (FPRs) are saved
+*/
+
+#include <sysdep.h>
+
+ENTRY(_savegpr1_all)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_13)
+C_TEXT(_savegpr1_13): stw r13,-76(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_14)
+C_TEXT(_savegpr1_14): stw r14,-72(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_15)
+C_TEXT(_savegpr1_15): stw r15,-68(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_16)
+C_TEXT(_savegpr1_16): stw r16,-64(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_17)
+C_TEXT(_savegpr1_17): stw r17,-60(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_18)
+C_TEXT(_savegpr1_18): stw r18,-56(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_19)
+C_TEXT(_savegpr1_19): stw r19,-52(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_20)
+C_TEXT(_savegpr1_20): stw r20,-48(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_21)
+C_TEXT(_savegpr1_21): stw r21,-44(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_22)
+C_TEXT(_savegpr1_22): stw r22,-40(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_23)
+C_TEXT(_savegpr1_23): stw r23,-36(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_24)
+C_TEXT(_savegpr1_24): stw r24,-32(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_25)
+C_TEXT(_savegpr1_25): stw r25,-28(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_26)
+C_TEXT(_savegpr1_26): stw r26,-24(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_27)
+C_TEXT(_savegpr1_27): stw r27,-20(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_28)
+C_TEXT(_savegpr1_28): stw r28,-16(r12)
+ ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr1_29)
+C_TEXT(_savegpr1_29): stw r29,-12(r12) #save r29
+ stw r30,-8(r12) #save r30
+ stw r31,-4(r12) #save r31
+ blr #return
+END (_savegpr1_all)
diff --git a/libc/sysdeps/powerpc/powerpc32/hp-timing.h b/libc/sysdeps/powerpc/powerpc32/hp-timing.h
new file mode 100644
index 000000000..b62b0f213
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/hp-timing.h
@@ -0,0 +1,82 @@
+/* High precision, low overhead timing functions. Linux/PPC32 version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H 1
+
+
+/* There are no generic definitions for the times. We could write something
+ using the `gettimeofday' system call where available but the overhead of
+ the system call might be too high.
+
+ In case a platform supports timers in the hardware the following macros
+ and types must be defined:
+
+ - HP_TIMING_AVAIL: test for availability.
+
+ - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
+ implemented using function calls but instead uses some inlined code
+ which might simply consist of a few assembler instructions. We have to
+ know this since we might want to use the macros here in places where we
+ cannot make function calls.
+
+ - hp_timing_t: This is the type for variables used to store the time
+ values.
+
+ - HP_TIMING_ZERO: clear `hp_timing_t' object.
+
+ - HP_TIMING_NOW: place timestamp for current time in variable given as
+ parameter.
+
+ - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
+ HP_TIMING_DIFF macro.
+
+ - HP_TIMING_DIFF: compute difference between two times and store it
+ in a third. Source and destination might overlap.
+
+ - HP_TIMING_ACCUM: add time difference to another variable. This might
+ be a bit more complicated to implement for some platforms as the
+ operation should be thread-safe and 64bit arithmetic on 32bit platforms
+ is not.
+
+ - HP_TIMING_ACCUM_NT: this is the variant for situations where we know
+ there are no threads involved.
+
+ - HP_TIMING_PRINT: write decimal representation of the timing value into
+ the given string. This operation need not be inline even though
+ HP_TIMING_INLINE is specified.
+
+*/
+
+/* Provide dummy definitions. */
+#define HP_TIMING_AVAIL (0)
+#define HP_TIMING_INLINE (0)
+typedef unsigned long long int hp_timing_t;
+#define HP_TIMING_ZERO(Var)
+#define HP_TIMING_NOW(var)
+#define HP_TIMING_DIFF_INIT()
+#define HP_TIMING_DIFF(Diff, Start, End)
+#define HP_TIMING_ACCUM(Sum, Diff)
+#define HP_TIMING_ACCUM_NT(Sum, Diff)
+#define HP_TIMING_PRINT(Buf, Len, Val)
+
+/* Since this implementation is not available we tell the user about it. */
+#define HP_TIMING_NONAVAIL 1
+
+#endif /* hp-timing.h */
diff --git a/libc/sysdeps/powerpc/powerpc32/libgcc-compat.S b/libc/sysdeps/powerpc/powerpc32/libgcc-compat.S
new file mode 100644
index 000000000..196293fd9
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/libgcc-compat.S
@@ -0,0 +1,144 @@
+/* pre-.hidden libgcc compatibility
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+ .file "libgcc-compat.S"
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2_6)
+
+#define __ashldi3_v_glibc20 INTUSE (__ashldi3)
+#define __ashrdi3_v_glibc20 INTUSE (__ashrdi3)
+#define __lshrdi3_v_glibc20 INTUSE (__lshrdi3)
+#define __cmpdi2_v_glibc20 INTUSE (__cmpdi2)
+#define __ucmpdi2_v_glibc20 INTUSE (__ucmpdi2)
+#define __fixdfdi_v_glibc20 INTUSE (__fixdfdi)
+#define __fixsfdi_v_glibc20 INTUSE (__fixsfdi)
+#define __fixunsdfdi_v_glibc20 INTUSE (__fixunsdfdi)
+#define __fixunssfdi_v_glibc20 INTUSE (__fixunssfdi)
+#define __floatdidf_v_glibc20 INTUSE (__floatdidf)
+#define __floatdisf_v_glibc20 INTUSE (__floatdisf)
+
+ .symver __ashldi3_v_glibc20,__ashldi3@GLIBC_2.0
+ .symver __ashrdi3_v_glibc20,__ashrdi3@GLIBC_2.0
+ .symver __lshrdi3_v_glibc20,__lshrdi3@GLIBC_2.0
+ .symver __cmpdi2_v_glibc20,__cmpdi2@GLIBC_2.0
+ .symver __ucmpdi2_v_glibc20,__ucmpdi2@GLIBC_2.0
+ .symver __fixdfdi_v_glibc20,__fixdfdi@GLIBC_2.0
+ .symver __fixunsdfdi_v_glibc20,__fixunsdfdi@GLIBC_2.0
+ .symver __fixsfdi_v_glibc20,__fixsfdi@GLIBC_2.0
+ .symver __fixunssfdi_v_glibc20,__fixunssfdi@GLIBC_2.0
+ .symver __floatdidf_v_glibc20,__floatdidf@GLIBC_2.0
+ .symver __floatdisf_v_glibc20,__floatdisf@GLIBC_2.0
+
+#ifdef HAVE_DOT_HIDDEN
+ .hidden __ashldi3
+ .hidden __ashrdi3
+ .hidden __lshrdi3
+ .hidden __cmpdi2
+ .hidden __ucmpdi2
+ .hidden __fixdfdi
+ .hidden __fixsfdi
+ .hidden __fixunsdfdi
+ .hidden __fixunssfdi
+ .hidden __floatdidf
+ .hidden __floatdisf
+#endif
+
+ .section ".text"
+
+ .align 2
+ .globl __ashldi3_v_glibc20
+ .type __ashldi3_v_glibc20,@function
+__ashldi3_v_glibc20:
+ b __ashldi3@local
+.Lfe5:
+ .size __ashldi3_v_glibc20,.Lfe5-__ashldi3_v_glibc20
+ .align 2
+ .globl __ashrdi3_v_glibc20
+ .type __ashrdi3_v_glibc20,@function
+__ashrdi3_v_glibc20:
+ b __ashrdi3@local
+.Lfe6:
+ .size __ashrdi3_v_glibc20,.Lfe6-__ashrdi3_v_glibc20
+ .align 2
+ .globl __lshrdi3_v_glibc20
+ .type __lshrdi3_v_glibc20,@function
+__lshrdi3_v_glibc20:
+ b __lshrdi3@local
+.Lfe7:
+ .size __lshrdi3_v_glibc20,.Lfe7-__lshrdi3_v_glibc20
+ .align 2
+ .globl __cmpdi2_v_glibc20
+ .type __cmpdi2_v_glibc20,@function
+__cmpdi2_v_glibc20:
+ b __cmpdi2@local
+.Lfe8:
+ .size __cmpdi2_v_glibc20,.Lfe8-__cmpdi2_v_glibc20
+ .align 2
+ .globl __ucmpdi2_v_glibc20
+ .type __ucmpdi2_v_glibc20,@function
+__ucmpdi2_v_glibc20:
+ b __ucmpdi2@local
+.Lfe9:
+ .size __ucmpdi2_v_glibc20,.Lfe9-__ucmpdi2_v_glibc20
+ .align 2
+ .globl __fixdfdi_v_glibc20
+ .type __fixdfdi_v_glibc20,@function
+__fixdfdi_v_glibc20:
+ b __fixdfdi@local
+.Lfe10:
+ .size __fixdfdi_v_glibc20,.Lfe10-__fixdfdi_v_glibc20
+ .align 2
+ .globl __fixunsdfdi_v_glibc20
+ .type __fixunsdfdi_v_glibc20,@function
+__fixunsdfdi_v_glibc20:
+ b __fixunsdfdi@local
+.Lfe11:
+ .size __fixunsdfdi_v_glibc20,.Lfe11-__fixunsdfdi_v_glibc20
+ .align 2
+ .globl __fixsfdi_v_glibc20
+ .type __fixsfdi_v_glibc20,@function
+__fixsfdi_v_glibc20:
+ b __fixsfdi@local
+.Lfe12:
+ .size __fixsfdi_v_glibc20,.Lfe12-__fixsfdi_v_glibc20
+ .align 2
+ .globl __fixunssfdi_v_glibc20
+ .type __fixunssfdi_v_glibc20,@function
+__fixunssfdi_v_glibc20:
+ b __fixunssfdi@local
+.Lfe13:
+ .size __fixunssfdi_v_glibc20,.Lfe13-__fixunssfdi_v_glibc20
+ .align 2
+ .globl __floatdidf_v_glibc20
+ .type __floatdidf_v_glibc20,@function
+__floatdidf_v_glibc20:
+ b __floatdidf@local
+.Lfe14:
+ .size __floatdidf_v_glibc20,.Lfe14-__floatdidf_v_glibc20
+ .align 2
+ .globl __floatdisf_v_glibc20
+ .type __floatdisf_v_glibc20,@function
+__floatdisf_v_glibc20:
+ b __floatdisf@local
+.Lfe15:
+ .size __floatdisf_v_glibc20,.Lfe15-__floatdisf_v_glibc20
+
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc32/lshift.S b/libc/sysdeps/powerpc/powerpc32/lshift.S
new file mode 100644
index 000000000..65054f229
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/lshift.S
@@ -0,0 +1,133 @@
+/* Shift a limb left, low level routine.
+ Copyright (C) 1996, 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
+ unsigned int cnt) */
+
+EALIGN (BP_SYM (__mpn_lshift), 3, 0)
+
+#if __BOUNDED_POINTERS__
+ slwi r10,r5,2 /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
+ CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
+#endif
+ mtctr r5 # copy size into CTR
+ cmplwi cr0,r5,16 # is size < 16
+ slwi r0,r5,2
+ add r7,r3,r0 # make r7 point at end of res
+ add r4,r4,r0 # make r4 point at end of s1
+ lwzu r11,-4(r4) # load first s1 limb
+ subfic r8,r6,32
+ srw r3,r11,r8 # compute function return value
+ bge cr0,L(big) # branch if size >= 16
+
+ bdz L(end1)
+
+L(0): lwzu r10,-4(r4)
+ slw r9,r11,r6
+ srw r12,r10,r8
+ or r9,r9,r12
+ stwu r9,-4(r7)
+ bdz L(end2)
+ lwzu r11,-4(r4)
+ slw r9,r10,r6
+ srw r12,r11,r8
+ or r9,r9,r12
+ stwu r9,-4(r7)
+ bdnz L(0)
+
+L(end1):slw r0,r11,r6
+ stw r0,-4(r7)
+ blr
+
+
+/* Guaranteed not to succeed. */
+L(boom): tweq r0,r0
+
+/* We imitate a case statement, by using (yuk!) fixed-length code chunks,
+ of size 4*12 bytes. We have to do this (or something) to make this PIC. */
+L(big): mflr r9
+ cfi_register(lr,r9)
+ bltl- cr0,L(boom) # Never taken, only used to set LR.
+ slwi r10,r6,4
+ mflr r12
+ add r10,r12,r10
+ slwi r8,r6,5
+ add r10,r8,r10
+ mtctr r10
+ addi r5,r5,-1
+ mtlr r9
+ cfi_same_value (lr)
+ bctr
+
+L(end2):slw r0,r10,r6
+ stw r0,-4(r7)
+ blr
+
+#define DO_LSHIFT(n) \
+ mtctr r5; \
+L(n): lwzu r10,-4(r4); \
+ slwi r9,r11,n; \
+ inslwi r9,r10,n,32-n; \
+ stwu r9,-4(r7); \
+ bdz- L(end2); \
+ lwzu r11,-4(r4); \
+ slwi r9,r10,n; \
+ inslwi r9,r11,n,32-n; \
+ stwu r9,-4(r7); \
+ bdnz L(n); \
+ b L(end1)
+
+ DO_LSHIFT(1)
+ DO_LSHIFT(2)
+ DO_LSHIFT(3)
+ DO_LSHIFT(4)
+ DO_LSHIFT(5)
+ DO_LSHIFT(6)
+ DO_LSHIFT(7)
+ DO_LSHIFT(8)
+ DO_LSHIFT(9)
+ DO_LSHIFT(10)
+ DO_LSHIFT(11)
+ DO_LSHIFT(12)
+ DO_LSHIFT(13)
+ DO_LSHIFT(14)
+ DO_LSHIFT(15)
+ DO_LSHIFT(16)
+ DO_LSHIFT(17)
+ DO_LSHIFT(18)
+ DO_LSHIFT(19)
+ DO_LSHIFT(20)
+ DO_LSHIFT(21)
+ DO_LSHIFT(22)
+ DO_LSHIFT(23)
+ DO_LSHIFT(24)
+ DO_LSHIFT(25)
+ DO_LSHIFT(26)
+ DO_LSHIFT(27)
+ DO_LSHIFT(28)
+ DO_LSHIFT(29)
+ DO_LSHIFT(30)
+ DO_LSHIFT(31)
+
+END (BP_SYM (__mpn_lshift))
diff --git a/libc/sysdeps/powerpc/powerpc32/memset.S b/libc/sysdeps/powerpc/powerpc32/memset.S
new file mode 100644
index 000000000..f09c29467
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/memset.S
@@ -0,0 +1,342 @@
+/* Optimized memset implementation for PowerPC.
+ Copyright (C) 1997, 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* Define a global static that can hold the cache line size. The
+ assumption is that startup code will access the "aux vector" to
+ to obtain the value set by the kernel and store it into this
+ variable. */
+
+ .globl __cache_line_size
+ .lcomm __cache_line_size,4,4
+
+/* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
+ Returns 's'.
+
+ The memset is done in four sizes: byte (8 bits), word (32 bits),
+ 32-byte blocks (256 bits) and __cache_line_size (128, 256, 1024 bits).
+ There is a special case for setting whole cache lines to 0, which
+ takes advantage of the dcbz instruction. */
+
+ .section ".text"
+EALIGN (BP_SYM (memset), 5, 1)
+
+#define rTMP r0
+#define rRTN r3 /* initial value of 1st argument */
+#if __BOUNDED_POINTERS__
+# define rMEMP0 r4 /* original value of 1st arg */
+# define rCHR r5 /* char to set in each byte */
+# define rLEN r6 /* length of region to set */
+# define rMEMP r10 /* address at which we are storing */
+#else
+# define rMEMP0 r3 /* original value of 1st arg */
+# define rCHR r4 /* char to set in each byte */
+# define rLEN r5 /* length of region to set */
+# define rMEMP r6 /* address at which we are storing */
+#endif
+#define rALIGN r7 /* number of bytes we are setting now (when aligning) */
+#define rMEMP2 r8
+
+#define rPOS32 r7 /* constant +32 for clearing with dcbz */
+#define rNEG64 r8 /* constant -64 for clearing with dcbz */
+#define rNEG32 r9 /* constant -32 for clearing with dcbz */
+
+#define rGOT r9 /* Address of the Global Offset Table. */
+#define rCLS r8 /* Cache line size obtained from static. */
+#define rCLM r9 /* Cache line size mask to check for cache alignment. */
+
+#if __BOUNDED_POINTERS__
+ cmplwi cr1, rRTN, 0
+ CHECK_BOUNDS_BOTH_WIDE (rMEMP0, rTMP, rTMP2, rLEN)
+ beq cr1, L(b0)
+ STORE_RETURN_VALUE (rMEMP0)
+ STORE_RETURN_BOUNDS (rTMP, rTMP2)
+L(b0):
+#endif
+
+/* take care of case for size <= 4 */
+ cmplwi cr1, rLEN, 4
+ andi. rALIGN, rMEMP0, 3
+ mr rMEMP, rMEMP0
+ ble- cr1, L(small)
+/* align to word boundary */
+ cmplwi cr5, rLEN, 31
+ rlwimi rCHR, rCHR, 8, 16, 23
+ beq+ L(aligned) /* 8th instruction from .align */
+ mtcrf 0x01, rMEMP0
+ subfic rALIGN, rALIGN, 4
+ add rMEMP, rMEMP, rALIGN
+ sub rLEN, rLEN, rALIGN
+ bf+ 31, L(g0)
+ stb rCHR, 0(rMEMP0)
+ bt 30, L(aligned)
+L(g0): sth rCHR, -2(rMEMP) /* 16th instruction from .align */
+/* take care of case for size < 31 */
+L(aligned):
+ mtcrf 0x01, rLEN
+ rlwimi rCHR, rCHR, 16, 0, 15
+ ble cr5, L(medium)
+/* align to cache line boundary... */
+ andi. rALIGN, rMEMP, 0x1C
+ subfic rALIGN, rALIGN, 0x20
+ beq L(caligned)
+ mtcrf 0x01, rALIGN
+ add rMEMP, rMEMP, rALIGN
+ sub rLEN, rLEN, rALIGN
+ cmplwi cr1, rALIGN, 0x10
+ mr rMEMP2, rMEMP
+ bf 28, L(a1)
+ stw rCHR, -4(rMEMP2)
+ stwu rCHR, -8(rMEMP2)
+L(a1): blt cr1, L(a2)
+ stw rCHR, -4(rMEMP2) /* 32nd instruction from .align */
+ stw rCHR, -8(rMEMP2)
+ stw rCHR, -12(rMEMP2)
+ stwu rCHR, -16(rMEMP2)
+L(a2): bf 29, L(caligned)
+ stw rCHR, -4(rMEMP2)
+/* now aligned to a cache line. */
+L(caligned):
+ cmplwi cr1, rCHR, 0
+ clrrwi. rALIGN, rLEN, 5
+ mtcrf 0x01, rLEN /* 40th instruction from .align */
+
+/* Check if we can use the special case for clearing memory using dcbz.
+ This requires that we know the correct cache line size for this
+ processor. Getting the __cache_line_size may require establishing GOT
+ addressability, so branch out of line to set this up. */
+ beq cr1, L(checklinesize)
+
+/* Store blocks of 32-bytes (256-bits) starting on a 32-byte boundary.
+ Can't assume that rCHR is zero or that the cache line size is either
+ 32-bytes or even known. */
+L(nondcbz):
+ srwi rTMP, rALIGN, 5
+ mtctr rTMP
+ beq L(medium) /* we may not actually get to do a full line */
+ clrlwi. rLEN, rLEN, 27
+ add rMEMP, rMEMP, rALIGN
+ li rNEG64, -0x40
+ bdz L(cloopdone) /* 48th instruction from .align */
+
+/* We can't use dcbz here as we don't know the cache line size. We can
+ use "data cache block touch for store", which is safe. */
+L(c3): dcbtst rNEG64, rMEMP
+ stw rCHR, -4(rMEMP)
+ stw rCHR, -8(rMEMP)
+ stw rCHR, -12(rMEMP)
+ stw rCHR, -16(rMEMP)
+ nop /* let 601 fetch last 4 instructions of loop */
+ stw rCHR, -20(rMEMP)
+ stw rCHR, -24(rMEMP) /* 56th instruction from .align */
+ nop /* let 601 fetch first 8 instructions of loop */
+ stw rCHR, -28(rMEMP)
+ stwu rCHR, -32(rMEMP)
+ bdnz L(c3)
+L(cloopdone):
+ stw rCHR, -4(rMEMP)
+ stw rCHR, -8(rMEMP)
+ stw rCHR, -12(rMEMP)
+ stw rCHR, -16(rMEMP) /* 64th instruction from .align */
+ stw rCHR, -20(rMEMP)
+ cmplwi cr1, rLEN, 16
+ stw rCHR, -24(rMEMP)
+ stw rCHR, -28(rMEMP)
+ stwu rCHR, -32(rMEMP)
+ beqlr
+ add rMEMP, rMEMP, rALIGN
+ b L(medium_tail2) /* 72nd instruction from .align */
+
+ .align 5
+ nop
+/* Clear cache lines of memory in 128-byte chunks.
+ This code is optimized for processors with 32-byte cache lines.
+ It is further optimized for the 601 processor, which requires
+ some care in how the code is aligned in the i-cache. */
+L(zloopstart):
+ clrlwi rLEN, rLEN, 27
+ mtcrf 0x02, rALIGN
+ srwi. rTMP, rALIGN, 7
+ mtctr rTMP
+ li rPOS32, 0x20
+ li rNEG64, -0x40
+ cmplwi cr1, rLEN, 16 /* 8 */
+ bf 26, L(z0)
+ dcbz 0, rMEMP
+ addi rMEMP, rMEMP, 0x20
+L(z0): li rNEG32, -0x20
+ bf 25, L(z1)
+ dcbz 0, rMEMP
+ dcbz rPOS32, rMEMP
+ addi rMEMP, rMEMP, 0x40 /* 16 */
+L(z1): cmplwi cr5, rLEN, 0
+ beq L(medium)
+L(zloop):
+ dcbz 0, rMEMP
+ dcbz rPOS32, rMEMP
+ addi rMEMP, rMEMP, 0x80
+ dcbz rNEG64, rMEMP
+ dcbz rNEG32, rMEMP
+ bdnz L(zloop)
+ beqlr cr5
+ b L(medium_tail2)
+
+ .align 5
+L(small):
+/* Memset of 4 bytes or less. */
+ cmplwi cr5, rLEN, 1
+ cmplwi cr1, rLEN, 3
+ bltlr cr5
+ stb rCHR, 0(rMEMP)
+ beqlr cr5
+ nop
+ stb rCHR, 1(rMEMP)
+ bltlr cr1
+ stb rCHR, 2(rMEMP)
+ beqlr cr1
+ nop
+ stb rCHR, 3(rMEMP)
+ blr
+
+/* Memset of 0-31 bytes. */
+ .align 5
+L(medium):
+ cmplwi cr1, rLEN, 16
+L(medium_tail2):
+ add rMEMP, rMEMP, rLEN
+L(medium_tail):
+ bt- 31, L(medium_31t)
+ bt- 30, L(medium_30t)
+L(medium_30f):
+ bt- 29, L(medium_29t)
+L(medium_29f):
+ bge- cr1, L(medium_27t)
+ bflr- 28
+ stw rCHR, -4(rMEMP) /* 8th instruction from .align */
+ stw rCHR, -8(rMEMP)
+ blr
+
+L(medium_31t):
+ stbu rCHR, -1(rMEMP)
+ bf- 30, L(medium_30f)
+L(medium_30t):
+ sthu rCHR, -2(rMEMP)
+ bf- 29, L(medium_29f)
+L(medium_29t):
+ stwu rCHR, -4(rMEMP)
+ blt- cr1, L(medium_27f) /* 16th instruction from .align */
+L(medium_27t):
+ stw rCHR, -4(rMEMP)
+ stw rCHR, -8(rMEMP)
+ stw rCHR, -12(rMEMP)
+ stwu rCHR, -16(rMEMP)
+L(medium_27f):
+ bflr- 28
+L(medium_28t):
+ stw rCHR, -4(rMEMP)
+ stw rCHR, -8(rMEMP)
+ blr
+
+L(checklinesize):
+#ifdef SHARED
+ mflr rTMP
+/* If the remaining length is less the 32 bytes then don't bother getting
+ the cache line size. */
+ beq L(medium)
+/* Establishes GOT addressability so we can load __cache_line_size
+ from static. This value was set from the aux vector during startup. */
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr rGOT
+ addis rGOT,rGOT,__cache_line_size-1b@ha
+ lwz rCLS,__cache_line_size-1b@l(rGOT)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr rGOT
+ lwz rGOT,__cache_line_size@got(rGOT)
+ lwz rCLS,0(rGOT)
+# endif
+ mtlr rTMP
+#else
+/* Load __cache_line_size from static. This value was set from the
+ aux vector during startup. */
+ lis rCLS,__cache_line_size@ha
+/* If the remaining length is less the 32 bytes then don't bother getting
+ the cache line size. */
+ beq L(medium)
+ lwz rCLS,__cache_line_size@l(rCLS)
+#endif
+
+/* If the cache line size was not set then goto to L(nondcbz), which is
+ safe for any cache line size. */
+ cmplwi cr1,rCLS,0
+ beq cr1,L(nondcbz)
+
+/* If the cache line size is 32 bytes then goto to L(zloopstart),
+ which is coded specificly for 32-byte lines (and 601). */
+ cmplwi cr1,rCLS,32
+ beq cr1,L(zloopstart)
+
+/* Now we know the cache line size and it is not 32-bytes. However
+ we may not yet be aligned to the cache line and may have a partial
+ line to fill. Touch it 1st to fetch the cache line. */
+ dcbtst 0,rMEMP
+
+ addi rCLM,rCLS,-1
+L(getCacheAligned):
+ cmplwi cr1,rLEN,32
+ and. rTMP,rCLM,rMEMP
+ blt cr1,L(handletail32)
+ beq L(cacheAligned)
+/* We are not aligned to start of a cache line yet. Store 32-byte
+ of data and test again. */
+ addi rMEMP,rMEMP,32
+ addi rLEN,rLEN,-32
+ stw rCHR,-32(rMEMP)
+ stw rCHR,-28(rMEMP)
+ stw rCHR,-24(rMEMP)
+ stw rCHR,-20(rMEMP)
+ stw rCHR,-16(rMEMP)
+ stw rCHR,-12(rMEMP)
+ stw rCHR,-8(rMEMP)
+ stw rCHR,-4(rMEMP)
+ b L(getCacheAligned)
+
+/* Now we are aligned to the cache line and can use dcbz. */
+L(cacheAligned):
+ cmplw cr1,rLEN,rCLS
+ blt cr1,L(handletail32)
+ dcbz 0,rMEMP
+ subf rLEN,rCLS,rLEN
+ add rMEMP,rMEMP,rCLS
+ b L(cacheAligned)
+
+/* We are here because; the cache line size was set, it was not
+ 32-bytes, and the remainder (rLEN) is now less than the actual cache
+ line size. Set up the preconditions for L(nondcbz) and go there to
+ store the remaining bytes. */
+L(handletail32):
+ clrrwi. rALIGN, rLEN, 5
+ b L(nondcbz)
+
+END (BP_SYM (memset))
+libc_hidden_builtin_def (memset)
diff --git a/libc/sysdeps/powerpc/powerpc32/mul_1.S b/libc/sysdeps/powerpc/powerpc32/mul_1.S
new file mode 100644
index 000000000..f0e008633
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/mul_1.S
@@ -0,0 +1,53 @@
+/* Multiply a limb vector by a limb, for PowerPC.
+ Copyright (C) 1993-1995, 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate s1*s2 and put result in res_ptr; return carry. */
+
+ENTRY (BP_SYM (__mpn_mul_1))
+#if __BOUNDED_POINTERS__
+ slwi r10,r5,2 /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
+ CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
+#endif
+ mtctr r5
+
+ lwz r0,0(r4)
+ mullw r7,r0,r6
+ mulhwu r10,r0,r6
+ addi r3,r3,-4 # adjust res_ptr
+ addic r5,r5,0 # clear cy with dummy insn
+ bdz L(1)
+
+L(0): lwzu r0,4(r4)
+ stwu r7,4(r3)
+ mullw r8,r0,r6
+ adde r7,r8,r10
+ mulhwu r10,r0,r6
+ bdnz L(0)
+
+L(1): stw r7,4(r3)
+ addze r3,r10
+ blr
+END (BP_SYM (__mpn_mul_1))
diff --git a/libc/sysdeps/powerpc/powerpc32/ppc-mcount.S b/libc/sysdeps/powerpc/powerpc32/ppc-mcount.S
new file mode 100644
index 000000000..7e39acb55
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/ppc-mcount.S
@@ -0,0 +1,81 @@
+/* PowerPC-specific implementation of profiling support.
+ Copyright (C) 1997, 1999, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/* This would be bad. */
+#ifdef PROF
+#undef PROF
+#endif
+
+#include <sysdep.h>
+
+/* We do profiling as described in the SYSV ELF ABI, except that glibc
+ _mcount manages its own counters. The caller has put the address the
+ caller will return to in the usual place on the stack, 4(r1). _mcount
+ is responsible for ensuring that when it returns no argument-passing
+ registers are disturbed, and that the LR is set back to (what the
+ caller sees as) 4(r1).
+
+ This is intended so that the following code can be inserted at the
+ front of any routine without changing the routine:
+
+ .data
+ mflr r0
+ stw r0,4(r1)
+ bl _mcount
+*/
+
+ENTRY(_mcount)
+ stwu r1,-48(r1)
+ cfi_adjust_cfa_offset (48)
+/* We need to save the parameter-passing registers. */
+ stw r3, 12(r1)
+ stw r4, 16(r1)
+ stw r5, 20(r1)
+ stw r6, 24(r1)
+ mflr r4
+ lwz r3, 52(r1)
+ mfcr r5
+ stw r7, 28(r1)
+ stw r8, 32(r1)
+ stw r9, 36(r1)
+ stw r10,40(r1)
+ stw r4, 44(r1)
+ cfi_offset (lr, -4)
+ stw r5, 8(r1)
+ bl __mcount_internal@local
+ nop
+ /* Restore the registers... */
+ lwz r6, 8(r1)
+ lwz r0, 44(r1)
+ lwz r3, 12(r1)
+ mtctr r0
+ lwz r4, 16(r1)
+ mtcrf 0xff,r6
+ lwz r5, 20(r1)
+ lwz r6, 24(r1)
+ lwz r0, 52(r1)
+ lwz r7, 28(r1)
+ lwz r8, 32(r1)
+ mtlr r0
+ lwz r9, 36(r1)
+ lwz r10,40(r1)
+ /* ...unwind the stack frame, and return to your usual programming. */
+ addi r1,r1,48
+ bctr
+END(_mcount)
diff --git a/libc/sysdeps/powerpc/powerpc32/register-dump.h b/libc/sysdeps/powerpc/powerpc32/register-dump.h
new file mode 100644
index 000000000..d341eea8f
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/register-dump.h
@@ -0,0 +1,121 @@
+/* Dump registers.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/uio.h>
+#include <stdio-common/_itoa.h>
+
+/* This prints out the information in the following form: */
+static const char dumpform[] = "\
+Register dump:\n\
+fp0-3: 0000030%0000031% 0000032%0000033% 0000034%0000035% 0000036%0000037%\n\
+fp4-7: 0000038%0000039% 000003a%000003b% 000003c%000003d% 000003e%000003f%\n\
+fp8-11: 0000040%0000041% 0000042%0000043% 0000044%0000045% 0000046%0000047%\n\
+fp12-15: 0000048%0000049% 000004a%000004b% 000004c%000004d% 000004e%000004f%\n\
+fp16-19: 0000050%0000051% 0000052%0000053% 0000054%0000055% 0000056%0000057%\n\
+fp20-23: 0000058%0000059% 000005a%000005b% 000005c%000005d% 000005e%000005f%\n\
+fp24-27: 0000060%0000061% 0000062%0000063% 0000064%0000065% 0000066%0000067%\n\
+fp28-31: 0000068%0000069% 000006a%000006b% 000006c%000006d% 000006e%000006f%\n\
+r0 =0000000% sp =0000001% r2 =0000002% r3 =0000003% trap=0000028%\n\
+r4 =0000004% r5 =0000005% r6 =0000006% r7 =0000007% sr0=0000020% sr1=0000021%\n\
+r8 =0000008% r9 =0000009% r10=000000a% r11=000000b% dar=0000029% dsi=000002a%\n\
+r12=000000c% r13=000000d% r14=000000e% r15=000000f% r3*=0000022%\n\
+r16=0000010% r17=0000011% r18=0000012% r19=0000013%\n\
+r20=0000014% r21=0000015% r22=0000016% r23=0000017% lr=0000024% xer=0000025%\n\
+r24=0000018% r25=0000019% r26=000001a% r27=000001b% mq=0000027% ctr=0000023%\n\
+r28=000001c% r29=000001d% r30=000001e% r31=000001f% fscr=0000071% ccr=0000026%\n\
+";
+
+/* Most of the fields are self-explanatory. 'sr0' is the next
+ instruction to execute, from SRR0, which may have some relationship
+ with the instruction that caused the exception. 'r3*' is the value
+ that will be returned in register 3 when the current system call
+ returns. 'sr1' is SRR1, bits 16-31 of which are copied from the MSR:
+
+ 16 - External interrupt enable
+ 17 - Privilege level (1=user, 0=supervisor)
+ 18 - FP available
+ 19 - Machine check enable (if clear, processor locks up on machine check)
+ 20 - FP exception mode bit 0 (FP exceptions recoverable)
+ 21 - Single-step trace enable
+ 22 - Branch trace enable
+ 23 - FP exception mode bit 1
+ 25 - exception prefix (if set, exceptions are taken from 0xFFFnnnnn,
+ otherwise from 0x000nnnnn).
+ 26 - Instruction address translation enabled.
+ 27 - Data address translation enabled.
+ 30 - Exception is recoverable (otherwise, don't try to return).
+ 31 - Little-endian mode enable.
+
+ 'Trap' is the address of the exception:
+
+ 00200 - Machine check exception (memory parity error, for instance)
+ 00300 - Data access exception (memory not mapped, see dsisr for why)
+ 00400 - Instruction access exception (memory not mapped)
+ 00500 - External interrupt
+ 00600 - Alignment exception (see dsisr for more information)
+ 00700 - Program exception (illegal/trap instruction, FP exception)
+ 00800 - FP unavailable (should not be seen by user code)
+ 00900 - Decrementer exception (for instance, SIGALRM)
+ 00A00 - I/O controller interface exception
+ 00C00 - System call exception (for instance, kill(3)).
+ 00E00 - FP assist exception (optional FP instructions, etc.)
+
+ 'dar' is the memory location, for traps 00300, 00400, 00600, 00A00.
+ 'dsisr' has the following bits under trap 00300:
+ 0 - direct-store error exception
+ 1 - no page table entry for page
+ 4 - memory access not permitted
+ 5 - trying to access I/O controller space or using lwarx/stwcx on
+ non-write-cached memory
+ 6 - access was store
+ 9 - data access breakpoint hit
+ 10 - segment table search failed to find translation (64-bit ppcs only)
+ 11 - I/O controller instruction not permitted
+ For trap 00400, the same bits are set in SRR1 instead.
+ For trap 00600, bits 12-31 of the DSISR set to allow emulation of
+ the instruction without actually having to read it from memory.
+*/
+
+#define xtoi(x) (x >= 'a' ? x + 10 - 'a' : x - '0')
+
+static void
+register_dump (int fd, struct sigcontext *ctx)
+{
+ char buffer[sizeof(dumpform)];
+ char *bufferpos;
+ unsigned regno;
+ unsigned *regs = (unsigned *)(ctx->regs);
+
+ memcpy(buffer, dumpform, sizeof(dumpform));
+
+ /* Generate the output. */
+ while ((bufferpos = memchr (buffer, '%', sizeof(dumpform))))
+ {
+ regno = xtoi (bufferpos[-1]) | xtoi (bufferpos[-2]) << 4;
+ memset (bufferpos-2, '0', 3);
+ _itoa_word (regs[regno], bufferpos+1, 16, 0);
+ }
+
+ /* Write the output. */
+ write (fd, buffer, sizeof(buffer));
+}
+
+
+#define REGISTER_DUMP \
+ register_dump (fd, ctx)
diff --git a/libc/sysdeps/powerpc/powerpc32/rshift.S b/libc/sysdeps/powerpc/powerpc32/rshift.S
new file mode 100644
index 000000000..498b6c4a8
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/rshift.S
@@ -0,0 +1,63 @@
+/* Shift a limb right, low level routine.
+ Copyright (C) 1995, 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* INPUT PARAMETERS
+ res_ptr r3
+ s1_ptr r4
+ size r5
+ cnt r6 */
+
+ENTRY (BP_SYM (__mpn_rshift))
+#if __BOUNDED_POINTERS__
+ slwi r10,r5,2 /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
+ CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
+#endif
+ mtctr r5 # copy size into CTR
+ addi r7,r3,-4 # move adjusted res_ptr to free return reg
+ subfic r8,r6,32
+ lwz r11,0(r4) # load first s1 limb
+ slw r3,r11,r8 # compute function return value
+ bdz L(1)
+
+L(0): lwzu r10,4(r4)
+ srw r9,r11,r6
+ slw r12,r10,r8
+ or r9,r9,r12
+ stwu r9,4(r7)
+ bdz L(2)
+ lwzu r11,4(r4)
+ srw r9,r10,r6
+ slw r12,r11,r8
+ or r9,r9,r12
+ stwu r9,4(r7)
+ bdnz L(0)
+
+L(1): srw r0,r11,r6
+ stw r0,4(r7)
+ blr
+
+L(2): srw r0,r10,r6
+ stw r0,4(r7)
+ blr
+END (BP_SYM (__mpn_rshift))
diff --git a/libc/sysdeps/powerpc/powerpc32/setjmp-common.S b/libc/sysdeps/powerpc/powerpc32/setjmp-common.S
new file mode 100644
index 000000000..12ee14d78
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/setjmp-common.S
@@ -0,0 +1,74 @@
+/* setjmp for PowerPC.
+ Copyright (C) 1995-1997,1999-2001,2003,2004,2005, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ASM
+#ifdef __NO_VMX__
+# include <novmxsetjmp.h>
+#else
+# include <jmpbuf-offsets.h>
+#endif
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+
+ENTRY (BP_SYM (__sigsetjmp))
+ CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
+
+#ifdef PTR_MANGLE
+ mr r5,r1
+ PTR_MANGLE(r5, r10)
+ stw r5,(JB_GPR1*4)(3)
+#else
+ stw r1,(JB_GPR1*4)(3)
+#endif
+ mflr r0
+ stw r14,((JB_GPRS+0)*4)(3)
+#ifdef PTR_MANGLE
+ PTR_MANGLE2 (r0, r10)
+ li r10,0
+#endif
+ stw r0,(JB_LR*4)(3)
+ stw r15,((JB_GPRS+1)*4)(3)
+ mfcr r0
+ stw r16,((JB_GPRS+2)*4)(3)
+ stw r0,(JB_CR*4)(3)
+ stw r17,((JB_GPRS+3)*4)(3)
+ stw r18,((JB_GPRS+4)*4)(3)
+ stw r19,((JB_GPRS+5)*4)(3)
+ stw r20,((JB_GPRS+6)*4)(3)
+ stw r21,((JB_GPRS+7)*4)(3)
+ stw r22,((JB_GPRS+8)*4)(3)
+ stw r23,((JB_GPRS+9)*4)(3)
+ stw r24,((JB_GPRS+10)*4)(3)
+ stw r25,((JB_GPRS+11)*4)(3)
+ stw r26,((JB_GPRS+12)*4)(3)
+ stw r27,((JB_GPRS+13)*4)(3)
+ stw r28,((JB_GPRS+14)*4)(3)
+ stw r29,((JB_GPRS+15)*4)(3)
+ stw r30,((JB_GPRS+16)*4)(3)
+ stw r31,((JB_GPRS+17)*4)(3)
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ li r3,0
+ blr
+#else
+ b BP_SYM (__sigjmp_save@local)
+#endif
+END (BP_SYM (__sigsetjmp))
diff --git a/libc/sysdeps/powerpc/powerpc32/setjmp.S b/libc/sysdeps/powerpc/powerpc32/setjmp.S
new file mode 100644
index 000000000..ef3514a46
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/setjmp.S
@@ -0,0 +1,44 @@
+/* non alitivec (old) version of setjmp for PowerPC.
+ Copyright (C) 1995-1997,1999-2001,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <shlib-compat.h>
+#include <libc-symbols.h>
+
+#if defined NOT_IN_libc
+/* Build a non-versioned object for rtld-*. */
+# include "setjmp-common.S"
+
+#else /* !NOT_IN_libc */
+/* Build a versioned object for libc. */
+default_symbol_version (__vmx__sigsetjmp,__sigsetjmp,GLIBC_2.3.4)
+# define __sigsetjmp __vmx__sigsetjmp
+# define __sigjmp_save __vmx__sigjmp_save
+# include "setjmp-common.S"
+
+# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+# define __NO_VMX__
+# undef __sigsetjmp
+# undef __sigjmp_save
+# undef JB_SIZE
+symbol_version (__novmx__sigsetjmp,__sigsetjmp,GLIBC_2.0)
+# define __sigsetjmp __novmx__sigsetjmp
+# define __sigjmp_save __novmx__sigjmp_save
+# include "setjmp-common.S"
+# endif
+#endif /* !NOT_IN_libc */
diff --git a/libc/sysdeps/powerpc/powerpc32/stpcpy.S b/libc/sysdeps/powerpc/powerpc32/stpcpy.S
new file mode 100644
index 000000000..819fcdb7e
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/stpcpy.S
@@ -0,0 +1,122 @@
+/* Optimized stpcpy implementation for PowerPC.
+ Copyright (C) 1997, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* See strlen.s for comments on how the end-of-string testing works. */
+
+/* char * [r3] stpcpy (char *dest [r3], const char *src [r4]) */
+
+EALIGN (BP_SYM (__stpcpy), 4, 0)
+
+#define rTMP r0
+#define rRTN r3
+#if __BOUNDED_POINTERS__
+# define rDEST r4 /* pointer to previous word in dest */
+# define rSRC r5 /* pointer to previous word in src */
+# define rLOW r11
+# define rHIGH r12
+#else
+# define rDEST r3 /* pointer to previous word in dest */
+# define rSRC r4 /* pointer to previous word in src */
+#endif
+#define rWORD r6 /* current word from src */
+#define rFEFE r7 /* 0xfefefeff */
+#define r7F7F r8 /* 0x7f7f7f7f */
+#define rNEG r9 /* ~(word in src | 0x7f7f7f7f) */
+#define rALT r10 /* alternate word from src */
+
+ CHECK_BOUNDS_LOW (rSRC, rLOW, rHIGH)
+ CHECK_BOUNDS_LOW (rDEST, rLOW, rHIGH)
+ STORE_RETURN_BOUNDS (rLOW, rHIGH)
+
+ or rTMP, rSRC, rDEST
+ clrlwi. rTMP, rTMP, 30
+ addi rDEST, rDEST, -4
+ bne L(unaligned)
+
+ lis rFEFE, -0x101
+ lis r7F7F, 0x7f7f
+ lwz rWORD, 0(rSRC)
+ addi rFEFE, rFEFE, -0x101
+ addi r7F7F, r7F7F, 0x7f7f
+ b L(g2)
+
+L(g0): lwzu rALT, 4(rSRC)
+ stwu rWORD, 4(rDEST)
+ add rTMP, rFEFE, rALT
+ nor rNEG, r7F7F, rALT
+ and. rTMP, rTMP, rNEG
+ bne- L(g1)
+ lwzu rWORD, 4(rSRC)
+ stwu rALT, 4(rDEST)
+L(g2): add rTMP, rFEFE, rWORD
+ nor rNEG, r7F7F, rWORD
+ and. rTMP, rTMP, rNEG
+ beq+ L(g0)
+
+ mr rALT, rWORD
+/* We've hit the end of the string. Do the rest byte-by-byte. */
+L(g1): rlwinm. rTMP, rALT, 8, 24, 31
+ stbu rTMP, 4(rDEST)
+ beqlr-
+ rlwinm. rTMP, rALT, 16, 24, 31
+ stbu rTMP, 1(rDEST)
+ beqlr-
+ rlwinm. rTMP, rALT, 24, 24, 31
+ stbu rTMP, 1(rDEST)
+ beqlr-
+ stbu rALT, 1(rDEST)
+ CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt)
+ STORE_RETURN_VALUE (rDEST)
+ blr
+
+/* Oh well. In this case, we just do a byte-by-byte copy. */
+ .align 4
+ nop
+L(unaligned):
+ lbz rWORD, 0(rSRC)
+ addi rDEST, rDEST, 3
+ cmpwi rWORD, 0
+ beq- L(u2)
+
+L(u0): lbzu rALT, 1(rSRC)
+ stbu rWORD, 1(rDEST)
+ cmpwi rALT, 0
+ beq- L(u1)
+ nop /* Let 601 load start of loop. */
+ lbzu rWORD, 1(rSRC)
+ stbu rALT, 1(rDEST)
+ cmpwi rWORD, 0
+ bne+ L(u0)
+L(u2): stbu rWORD, 1(rDEST)
+ CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt)
+ STORE_RETURN_VALUE (rDEST)
+ blr
+L(u1): stbu rALT, 1(rDEST)
+ CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt)
+ STORE_RETURN_VALUE (rDEST)
+ blr
+END (BP_SYM (__stpcpy))
+
+weak_alias (BP_SYM (__stpcpy), BP_SYM (stpcpy))
+libc_hidden_def (__stpcpy)
+libc_hidden_builtin_def (stpcpy)
diff --git a/libc/sysdeps/powerpc/powerpc32/strchr.S b/libc/sysdeps/powerpc/powerpc32/strchr.S
new file mode 100644
index 000000000..0c6f4e9f5
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/strchr.S
@@ -0,0 +1,131 @@
+/* Optimized strchr implementation for PowerPC.
+ Copyright (C) 1997, 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* See strlen.s for comments on how this works. */
+
+/* char * [r3] strchr (const char *s [r3] , int c [r4] ) */
+
+ENTRY (BP_SYM (strchr))
+
+#define rTMP1 r0
+#define rRTN r3 /* outgoing result */
+#if __BOUNDED_POINTERS__
+# define rSTR r4
+# define rCHR r5 /* byte we're looking for, spread over the whole word */
+# define rWORD r8 /* the current word */
+#else
+# define rSTR r8 /* current word pointer */
+# define rCHR r4 /* byte we're looking for, spread over the whole word */
+# define rWORD r5 /* the current word */
+#endif
+#define rCLZB rCHR /* leading zero byte count */
+#define rFEFE r6 /* constant 0xfefefeff (-0x01010101) */
+#define r7F7F r7 /* constant 0x7f7f7f7f */
+#define rTMP2 r9
+#define rIGN r10 /* number of bits we should ignore in the first word */
+#define rMASK r11 /* mask with the bits to ignore set to 0 */
+#define rTMP3 r12
+
+ CHECK_BOUNDS_LOW (rSTR, rTMP1, rTMP2)
+ STORE_RETURN_BOUNDS (rTMP1, rTMP2)
+
+ rlwimi rCHR, rCHR, 8, 16, 23
+ li rMASK, -1
+ rlwimi rCHR, rCHR, 16, 0, 15
+ rlwinm rIGN, rRTN, 3, 27, 28
+ lis rFEFE, -0x101
+ lis r7F7F, 0x7f7f
+ clrrwi rSTR, rRTN, 2
+ addi rFEFE, rFEFE, -0x101
+ addi r7F7F, r7F7F, 0x7f7f
+/* Test the first (partial?) word. */
+ lwz rWORD, 0(rSTR)
+ srw rMASK, rMASK, rIGN
+ orc rWORD, rWORD, rMASK
+ add rTMP1, rFEFE, rWORD
+ nor rTMP2, r7F7F, rWORD
+ and. rTMP1, rTMP1, rTMP2
+ xor rTMP3, rCHR, rWORD
+ orc rTMP3, rTMP3, rMASK
+ b L(loopentry)
+
+/* The loop. */
+
+L(loop):lwzu rWORD, 4(rSTR)
+ and. rTMP1, rTMP1, rTMP2
+/* Test for 0. */
+ add rTMP1, rFEFE, rWORD
+ nor rTMP2, r7F7F, rWORD
+ bne L(foundit)
+ and. rTMP1, rTMP1, rTMP2
+/* Start test for the bytes we're looking for. */
+ xor rTMP3, rCHR, rWORD
+L(loopentry):
+ add rTMP1, rFEFE, rTMP3
+ nor rTMP2, r7F7F, rTMP3
+ beq L(loop)
+/* There is a zero byte in the word, but may also be a matching byte (either
+ before or after the zero byte). In fact, we may be looking for a
+ zero byte, in which case we return a match. We guess that this hasn't
+ happened, though. */
+L(missed):
+ and. rTMP1, rTMP1, rTMP2
+ li rRTN, 0
+ STORE_RETURN_VALUE (rSTR)
+ beqlr
+/* It did happen. Decide which one was first...
+ I'm not sure if this is actually faster than a sequence of
+ rotates, compares, and branches (we use it anyway because it's shorter). */
+ and rFEFE, r7F7F, rWORD
+ or rMASK, r7F7F, rWORD
+ and rTMP1, r7F7F, rTMP3
+ or rIGN, r7F7F, rTMP3
+ add rFEFE, rFEFE, r7F7F
+ add rTMP1, rTMP1, r7F7F
+ nor rWORD, rMASK, rFEFE
+ nor rTMP2, rIGN, rTMP1
+ cmplw rWORD, rTMP2
+ bgtlr
+ cntlzw rCLZB, rTMP2
+ srwi rCLZB, rCLZB, 3
+ add rRTN, rSTR, rCLZB
+ CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, twlge)
+ STORE_RETURN_VALUE (rSTR)
+ blr
+
+L(foundit):
+ and rTMP1, r7F7F, rTMP3
+ or rIGN, r7F7F, rTMP3
+ add rTMP1, rTMP1, r7F7F
+ nor rTMP2, rIGN, rTMP1
+ cntlzw rCLZB, rTMP2
+ subi rSTR, rSTR, 4
+ srwi rCLZB, rCLZB, 3
+ add rRTN, rSTR, rCLZB
+ CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, twlge)
+ STORE_RETURN_VALUE (rSTR)
+ blr
+END (BP_SYM (strchr))
+
+weak_alias (BP_SYM (strchr), BP_SYM (index))
+libc_hidden_builtin_def (strchr)
diff --git a/libc/sysdeps/powerpc/powerpc32/strcmp.S b/libc/sysdeps/powerpc/powerpc32/strcmp.S
new file mode 100644
index 000000000..fa75eca3a
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/strcmp.S
@@ -0,0 +1,127 @@
+/* Optimized strcmp implementation for PowerPC.
+ Copyright (C) 1997, 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* See strlen.s for comments on how the end-of-string testing works. */
+
+/* int [r3] strcmp (const char *s1 [r3], const char *s2 [r4]) */
+
+EALIGN (BP_SYM (strcmp), 4, 0)
+
+#define rTMP r0
+#define rRTN r3
+#define rSTR1 r3 /* first string arg */
+#define rSTR2 r4 /* second string arg */
+#if __BOUNDED_POINTERS__
+# define rHIGH1 r11
+# define rHIGH2 r12
+#endif
+#define rWORD1 r5 /* current word in s1 */
+#define rWORD2 r6 /* current word in s2 */
+#define rFEFE r7 /* constant 0xfefefeff (-0x01010101) */
+#define r7F7F r8 /* constant 0x7f7f7f7f */
+#define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f) */
+#define rBITDIF r10 /* bits that differ in s1 & s2 words */
+
+ CHECK_BOUNDS_LOW (rSTR1, rTMP, rHIGH1)
+ CHECK_BOUNDS_LOW (rSTR2, rTMP, rHIGH2)
+
+ or rTMP, rSTR2, rSTR1
+ clrlwi. rTMP, rTMP, 30
+ lis rFEFE, -0x101
+ bne L(unaligned)
+
+ lwz rWORD1, 0(rSTR1)
+ lwz rWORD2, 0(rSTR2)
+ lis r7F7F, 0x7f7f
+ addi rFEFE, rFEFE, -0x101
+ addi r7F7F, r7F7F, 0x7f7f
+ b L(g1)
+
+L(g0): lwzu rWORD1, 4(rSTR1)
+ bne cr1, L(different)
+ lwzu rWORD2, 4(rSTR2)
+L(g1): add rTMP, rFEFE, rWORD1
+ nor rNEG, r7F7F, rWORD1
+ and. rTMP, rTMP, rNEG
+ cmpw cr1, rWORD1, rWORD2
+ beq+ L(g0)
+L(endstring):
+/* OK. We've hit the end of the string. We need to be careful that
+ we don't compare two strings as different because of gunk beyond
+ the end of the strings... */
+ and rTMP, r7F7F, rWORD1
+ beq cr1, L(equal)
+ add rTMP, rTMP, r7F7F
+ xor. rBITDIF, rWORD1, rWORD2
+ andc rNEG, rNEG, rTMP
+ blt- L(highbit)
+ cntlzw rBITDIF, rBITDIF
+ cntlzw rNEG, rNEG
+ addi rNEG, rNEG, 7
+ cmpw cr1, rNEG, rBITDIF
+ sub rRTN, rWORD1, rWORD2
+ bgelr+ cr1
+L(equal):
+ li rRTN, 0
+ /* GKM FIXME: check high bounds. */
+ blr
+
+L(different):
+ lwz rWORD1, -4(rSTR1)
+ xor. rBITDIF, rWORD1, rWORD2
+ sub rRTN, rWORD1, rWORD2
+ bgelr+
+L(highbit):
+ ori rRTN, rWORD2, 1
+ /* GKM FIXME: check high bounds. */
+ blr
+
+
+/* Oh well. In this case, we just do a byte-by-byte comparison. */
+ .align 4
+L(unaligned):
+ lbz rWORD1, 0(rSTR1)
+ lbz rWORD2, 0(rSTR2)
+ b L(u1)
+
+L(u0): lbzu rWORD1, 1(rSTR1)
+ bne- L(u4)
+ lbzu rWORD2, 1(rSTR2)
+L(u1): cmpwi cr1, rWORD1, 0
+ beq- cr1, L(u3)
+ cmpw rWORD1, rWORD2
+ bne- L(u3)
+ lbzu rWORD1, 1(rSTR1)
+ lbzu rWORD2, 1(rSTR2)
+ cmpwi cr1, rWORD1, 0
+ cmpw rWORD1, rWORD2
+ bne+ cr1, L(u0)
+L(u3): sub rRTN, rWORD1, rWORD2
+ /* GKM FIXME: check high bounds. */
+ blr
+L(u4): lbz rWORD1, -1(rSTR1)
+ sub rRTN, rWORD1, rWORD2
+ /* GKM FIXME: check high bounds. */
+ blr
+END (BP_SYM (strcmp))
+libc_hidden_builtin_def (strcmp)
diff --git a/libc/sysdeps/powerpc/powerpc32/strcpy.S b/libc/sysdeps/powerpc/powerpc32/strcpy.S
new file mode 100644
index 000000000..7fd89d2e4
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/strcpy.S
@@ -0,0 +1,121 @@
+/* Optimized strcpy implementation for PowerPC.
+ Copyright (C) 1997, 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* See strlen.s for comments on how the end-of-string testing works. */
+
+/* char * [r3] strcpy (char *dest [r3], const char *src [r4]) */
+
+EALIGN (BP_SYM (strcpy), 4, 0)
+
+#define rTMP r0
+#define rRTN r3 /* incoming DEST arg preserved as result */
+#if __BOUNDED_POINTERS__
+# define rDEST r4 /* pointer to previous word in dest */
+# define rSRC r5 /* pointer to previous word in src */
+# define rLOW r11
+# define rHIGH r12
+#else
+# define rSRC r4 /* pointer to previous word in src */
+# define rDEST r5 /* pointer to previous word in dest */
+#endif
+#define rWORD r6 /* current word from src */
+#define rFEFE r7 /* constant 0xfefefeff (-0x01010101) */
+#define r7F7F r8 /* constant 0x7f7f7f7f */
+#define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f) */
+#define rALT r10 /* alternate word from src */
+
+ CHECK_BOUNDS_LOW (rSRC, rLOW, rHIGH)
+ CHECK_BOUNDS_LOW (rDEST, rLOW, rHIGH)
+ STORE_RETURN_BOUNDS (rLOW, rHIGH)
+
+ or rTMP, rSRC, rRTN
+ clrlwi. rTMP, rTMP, 30
+#if __BOUNDED_POINTERS__
+ addi rDEST, rDEST, -4
+#else
+ addi rDEST, rRTN, -4
+#endif
+ bne L(unaligned)
+
+ lis rFEFE, -0x101
+ lis r7F7F, 0x7f7f
+ lwz rWORD, 0(rSRC)
+ addi rFEFE, rFEFE, -0x101
+ addi r7F7F, r7F7F, 0x7f7f
+ b L(g2)
+
+L(g0): lwzu rALT, 4(rSRC)
+ stwu rWORD, 4(rDEST)
+ add rTMP, rFEFE, rALT
+ nor rNEG, r7F7F, rALT
+ and. rTMP, rTMP, rNEG
+ bne- L(g1)
+ lwzu rWORD, 4(rSRC)
+ stwu rALT, 4(rDEST)
+L(g2): add rTMP, rFEFE, rWORD
+ nor rNEG, r7F7F, rWORD
+ and. rTMP, rTMP, rNEG
+ beq+ L(g0)
+
+ mr rALT, rWORD
+/* We've hit the end of the string. Do the rest byte-by-byte. */
+L(g1): rlwinm. rTMP, rALT, 8, 24, 31
+ stb rTMP, 4(rDEST)
+ beqlr-
+ rlwinm. rTMP, rALT, 16, 24, 31
+ stb rTMP, 5(rDEST)
+ beqlr-
+ rlwinm. rTMP, rALT, 24, 24, 31
+ stb rTMP, 6(rDEST)
+ beqlr-
+ stb rALT, 7(rDEST)
+ /* GKM FIXME: check high bound. */
+ blr
+
+/* Oh well. In this case, we just do a byte-by-byte copy. */
+ .align 4
+ nop
+L(unaligned):
+ lbz rWORD, 0(rSRC)
+ addi rDEST, rRTN, -1
+ cmpwi rWORD, 0
+ beq- L(u2)
+
+L(u0): lbzu rALT, 1(rSRC)
+ stbu rWORD, 1(rDEST)
+ cmpwi rALT, 0
+ beq- L(u1)
+ nop /* Let 601 load start of loop. */
+ lbzu rWORD, 1(rSRC)
+ stbu rALT, 1(rDEST)
+ cmpwi rWORD, 0
+ bne+ L(u0)
+L(u2): stb rWORD, 1(rDEST)
+ /* GKM FIXME: check high bound. */
+ blr
+L(u1): stb rALT, 1(rDEST)
+ /* GKM FIXME: check high bound. */
+ blr
+
+END (BP_SYM (strcpy))
+libc_hidden_builtin_def (strcpy)
diff --git a/libc/sysdeps/powerpc/powerpc32/strlen.S b/libc/sysdeps/powerpc/powerpc32/strlen.S
new file mode 100644
index 000000000..ec35d2309
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/strlen.S
@@ -0,0 +1,160 @@
+/* Optimized strlen implementation for PowerPC.
+ Copyright (C) 1997, 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* The algorithm here uses the following techniques:
+
+ 1) Given a word 'x', we can test to see if it contains any 0 bytes
+ by subtracting 0x01010101, and seeing if any of the high bits of each
+ byte changed from 0 to 1. This works because the least significant
+ 0 byte must have had no incoming carry (otherwise it's not the least
+ significant), so it is 0x00 - 0x01 == 0xff. For all other
+ byte values, either they have the high bit set initially, or when
+ 1 is subtracted you get a value in the range 0x00-0x7f, none of which
+ have their high bit set. The expression here is
+ (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
+ there were no 0x00 bytes in the word.
+
+ 2) Given a word 'x', we can test to see _which_ byte was zero by
+ calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
+ This produces 0x80 in each byte that was zero, and 0x00 in all
+ the other bytes. The '| 0x7f7f7f7f' clears the low 7 bits in each
+ byte, and the '| x' part ensures that bytes with the high bit set
+ produce 0x00. The addition will carry into the high bit of each byte
+ iff that byte had one of its low 7 bits set. We can then just see
+ which was the most significant bit set and divide by 8 to find how
+ many to add to the index.
+ This is from the book 'The PowerPC Compiler Writer's Guide',
+ by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
+
+ We deal with strings not aligned to a word boundary by taking the
+ first word and ensuring that bytes not part of the string
+ are treated as nonzero. To allow for memory latency, we unroll the
+ loop a few times, being careful to ensure that we do not read ahead
+ across cache line boundaries.
+
+ Questions to answer:
+ 1) How long are strings passed to strlen? If they're often really long,
+ we should probably use cache management instructions and/or unroll the
+ loop more. If they're often quite short, it might be better to use
+ fact (2) in the inner loop than have to recalculate it.
+ 2) How popular are bytes with the high bit set? If they are very rare,
+ on some processors it might be useful to use the simpler expression
+ ~((x - 0x01010101) | 0x7f7f7f7f) (that is, on processors with only one
+ ALU), but this fails when any character has its high bit set. */
+
+/* Some notes on register usage: Under the SVR4 ABI, we can use registers
+ 0 and 3 through 12 (so long as we don't call any procedures) without
+ saving them. We can also use registers 14 through 31 if we save them.
+ We can't use r1 (it's the stack pointer), r2 nor r13 because the user
+ program may expect them to hold their usual value if we get sent
+ a signal. Integer parameters are passed in r3 through r10.
+ We can use condition registers cr0, cr1, cr5, cr6, and cr7 without saving
+ them, the others we must save. */
+
+/* int [r3] strlen (char *s [r3]) */
+
+ENTRY (BP_SYM (strlen))
+
+#define rTMP1 r0
+#define rRTN r3 /* incoming STR arg, outgoing result */
+#define rSTR r4 /* current string position */
+#define rPADN r5 /* number of padding bits we prepend to the
+ string to make it start at a word boundary */
+#define rFEFE r6 /* constant 0xfefefeff (-0x01010101) */
+#define r7F7F r7 /* constant 0x7f7f7f7f */
+#define rWORD1 r8 /* current string word */
+#define rWORD2 r9 /* next string word */
+#define rMASK r9 /* mask for first string word */
+#define rTMP2 r10
+#define rTMP3 r11
+#define rTMP4 r12
+
+ CHECK_BOUNDS_LOW (rRTN, rTMP1, rTMP2)
+
+ clrrwi rSTR, rRTN, 2
+ lis r7F7F, 0x7f7f
+ rlwinm rPADN, rRTN, 3, 27, 28
+ lwz rWORD1, 0(rSTR)
+ li rMASK, -1
+ addi r7F7F, r7F7F, 0x7f7f
+/* That's the setup done, now do the first pair of words.
+ We make an exception and use method (2) on the first two words, to reduce
+ overhead. */
+ srw rMASK, rMASK, rPADN
+ and rTMP1, r7F7F, rWORD1
+ or rTMP2, r7F7F, rWORD1
+ add rTMP1, rTMP1, r7F7F
+ nor rTMP1, rTMP2, rTMP1
+ and. rWORD1, rTMP1, rMASK
+ mtcrf 0x01, rRTN
+ bne L(done0)
+ lis rFEFE, -0x101
+ addi rFEFE, rFEFE, -0x101
+/* Are we now aligned to a doubleword boundary? */
+ bt 29, L(loop)
+
+/* Handle second word of pair. */
+ lwzu rWORD1, 4(rSTR)
+ and rTMP1, r7F7F, rWORD1
+ or rTMP2, r7F7F, rWORD1
+ add rTMP1, rTMP1, r7F7F
+ nor. rWORD1, rTMP2, rTMP1
+ bne L(done0)
+
+/* The loop. */
+
+L(loop):
+ lwz rWORD1, 4(rSTR)
+ lwzu rWORD2, 8(rSTR)
+ add rTMP1, rFEFE, rWORD1
+ nor rTMP2, r7F7F, rWORD1
+ and. rTMP1, rTMP1, rTMP2
+ add rTMP3, rFEFE, rWORD2
+ nor rTMP4, r7F7F, rWORD2
+ bne L(done1)
+ and. rTMP1, rTMP3, rTMP4
+ beq L(loop)
+
+ and rTMP1, r7F7F, rWORD2
+ add rTMP1, rTMP1, r7F7F
+ andc rWORD1, rTMP4, rTMP1
+ b L(done0)
+
+L(done1):
+ and rTMP1, r7F7F, rWORD1
+ subi rSTR, rSTR, 4
+ add rTMP1, rTMP1, r7F7F
+ andc rWORD1, rTMP2, rTMP1
+
+/* When we get to here, rSTR points to the first word in the string that
+ contains a zero byte, and the most significant set bit in rWORD1 is in that
+ byte. */
+L(done0):
+ cntlzw rTMP3, rWORD1
+ subf rTMP1, rRTN, rSTR
+ srwi rTMP3, rTMP3, 3
+ add rRTN, rTMP1, rTMP3
+ /* GKM FIXME: check high bound. */
+ blr
+END (BP_SYM (strlen))
+libc_hidden_builtin_def (strlen)
diff --git a/libc/sysdeps/powerpc/powerpc32/strncmp.S b/libc/sysdeps/powerpc/powerpc32/strncmp.S
new file mode 100644
index 000000000..3e0fff5ac
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/strncmp.S
@@ -0,0 +1,161 @@
+/* Optimized strcmp implementation for PowerPC32.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* See strlen.s for comments on how the end-of-string testing works. */
+
+/* int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5]) */
+
+EALIGN (BP_SYM(strncmp), 4, 0)
+
+#define rTMP r0
+#define rRTN r3
+#define rSTR1 r3 /* first string arg */
+#define rSTR2 r4 /* second string arg */
+#define rN r5 /* max string length */
+/* Note: The Bounded pointer support in this code is broken. This code
+ was inherited from PPC32 and and that support was never completed.
+ Current PPC gcc does not support -fbounds-check or -fbounded-pointers. */
+#define rWORD1 r6 /* current word in s1 */
+#define rWORD2 r7 /* current word in s2 */
+#define rFEFE r8 /* constant 0xfefefeff (-0x01010101) */
+#define r7F7F r9 /* constant 0x7f7f7f7f */
+#define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f) */
+#define rBITDIF r11 /* bits that differ in s1 & s2 words */
+
+ dcbt 0,rSTR1
+ or rTMP, rSTR2, rSTR1
+ lis r7F7F, 0x7f7f
+ dcbt 0,rSTR2
+ clrlwi. rTMP, rTMP, 30
+ cmplwi cr1, rN, 0
+ lis rFEFE, -0x101
+ bne L(unaligned)
+/* We are word alligned so set up for two loops. first a word
+ loop, then fall into the byte loop if any residual. */
+ srwi. rTMP, rN, 2
+ clrlwi rN, rN, 30
+ addi rFEFE, rFEFE, -0x101
+ addi r7F7F, r7F7F, 0x7f7f
+ cmplwi cr1, rN, 0
+ beq L(unaligned)
+
+ mtctr rTMP /* Power4 wants mtctr 1st in dispatch group. */
+ lwz rWORD1, 0(rSTR1)
+ lwz rWORD2, 0(rSTR2)
+ b L(g1)
+
+L(g0):
+ lwzu rWORD1, 4(rSTR1)
+ bne- cr1, L(different)
+ lwzu rWORD2, 4(rSTR2)
+L(g1): add rTMP, rFEFE, rWORD1
+ nor rNEG, r7F7F, rWORD1
+ bdz L(tail)
+ and. rTMP, rTMP, rNEG
+ cmpw cr1, rWORD1, rWORD2
+ beq+ L(g0)
+
+/* OK. We've hit the end of the string. We need to be careful that
+ we don't compare two strings as different because of gunk beyond
+ the end of the strings... */
+
+L(endstring):
+ and rTMP, r7F7F, rWORD1
+ beq cr1, L(equal)
+ add rTMP, rTMP, r7F7F
+ xor. rBITDIF, rWORD1, rWORD2
+
+ andc rNEG, rNEG, rTMP
+ blt- L(highbit)
+ cntlzw rBITDIF, rBITDIF
+ cntlzw rNEG, rNEG
+ addi rNEG, rNEG, 7
+ cmpw cr1, rNEG, rBITDIF
+ sub rRTN, rWORD1, rWORD2
+ blt- cr1, L(equal)
+ srawi rRTN, rRTN, 31
+ ori rRTN, rRTN, 1
+ blr
+L(equal):
+ li rRTN, 0
+ blr
+
+L(different):
+ lwzu rWORD1, -4(rSTR1)
+ xor. rBITDIF, rWORD1, rWORD2
+ sub rRTN, rWORD1, rWORD2
+ blt- L(highbit)
+ srawi rRTN, rRTN, 31
+ ori rRTN, rRTN, 1
+ blr
+L(highbit):
+ srwi rWORD2, rWORD2, 24
+ srwi rWORD1, rWORD1, 24
+ sub rRTN, rWORD1, rWORD2
+ blr
+
+
+/* Oh well. In this case, we just do a byte-by-byte comparison. */
+ .align 4
+L(tail):
+ and. rTMP, rTMP, rNEG
+ cmpw cr1, rWORD1, rWORD2
+ bne- L(endstring)
+ addi rSTR1, rSTR1, 4
+ bne- cr1, L(different)
+ addi rSTR2, rSTR2, 4
+ cmplwi cr1, rN, 0
+L(unaligned):
+ mtctr rN /* Power4 wants mtctr 1st in dispatch group */
+ bgt cr1, L(uz)
+L(ux):
+ li rRTN, 0
+ blr
+ .align 4
+L(uz):
+ lbz rWORD1, 0(rSTR1)
+ lbz rWORD2, 0(rSTR2)
+ nop
+ b L(u1)
+L(u0):
+ lbzu rWORD2, 1(rSTR2)
+L(u1):
+ bdz L(u3)
+ cmpwi cr1, rWORD1, 0
+ cmpw rWORD1, rWORD2
+ beq- cr1, L(u3)
+ lbzu rWORD1, 1(rSTR1)
+ bne- L(u2)
+ lbzu rWORD2, 1(rSTR2)
+ bdz L(u3)
+ cmpwi cr1, rWORD1, 0
+ cmpw rWORD1, rWORD2
+ bne- L(u3)
+ lbzu rWORD1, 1(rSTR1)
+ bne+ cr1, L(u0)
+
+L(u2): lbzu rWORD1, -1(rSTR1)
+L(u3): sub rRTN, rWORD1, rWORD2
+ blr
+END (BP_SYM (strncmp))
+libc_hidden_builtin_def (strncmp)
diff --git a/libc/sysdeps/powerpc/powerpc32/sub_n.S b/libc/sysdeps/powerpc/powerpc32/sub_n.S
new file mode 100644
index 000000000..3ebd22e30
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/sub_n.S
@@ -0,0 +1,78 @@
+/* Subtract two limb vectors of equal, non-zero length for PowerPC.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ mp_size_t size)
+ Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1. */
+
+/* Note on optimisation: This code is optimal for the 601. Almost every other
+ possible 2-unrolled inner loop will not be. Also, watch out for the
+ alignment... */
+
+EALIGN (BP_SYM (__mpn_sub_n), 3, 1)
+
+#if __BOUNDED_POINTERS__
+ slwi r10,r6,2 /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
+ CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
+ CHECK_BOUNDS_BOTH_WIDE (r5, r8, r9, r10)
+#endif
+
+/* Set up for loop below. */
+ mtcrf 0x01,r6
+ srwi. r7,r6,1
+ mtctr r7
+ bt 31,L(2)
+
+/* Set the carry (clear the borrow). */
+ subfc r0,r0,r0
+/* Adjust pointers for loop. */
+ addi r3,r3,-4
+ addi r4,r4,-4
+ addi r5,r5,-4
+ b L(0)
+
+L(2): lwz r7,0(r5)
+ lwz r6,0(r4)
+ subfc r6,r7,r6
+ stw r6,0(r3)
+ beq L(1)
+
+/* Align start of loop to an odd word boundary to guarantee that the
+ last two words can be fetched in one access (for 601). This turns
+ out to be important. */
+L(0):
+ lwz r9,4(r4)
+ lwz r8,4(r5)
+ lwzu r6,8(r4)
+ lwzu r7,8(r5)
+ subfe r8,r8,r9
+ stw r8,4(r3)
+ subfe r6,r7,r6
+ stwu r6,8(r3)
+ bdnz L(0)
+/* Return the borrow. */
+L(1): subfe r3,r3,r3
+ neg r3,r3
+ blr
+END (BP_SYM (__mpn_sub_n))
diff --git a/libc/sysdeps/powerpc/powerpc32/submul_1.S b/libc/sysdeps/powerpc/powerpc32/submul_1.S
new file mode 100644
index 000000000..6e45d1983
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/submul_1.S
@@ -0,0 +1,59 @@
+/* Multiply a limb vector by a single limb, for PowerPC.
+ Copyright (C) 1993-1995, 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate res-s1*s2 and put result back in res; return carry. */
+
+ENTRY (BP_SYM (__mpn_submul_1))
+#if __BOUNDED_POINTERS__
+ slwi r10,r5,2 /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (r3, r8, r9, r10)
+ CHECK_BOUNDS_BOTH_WIDE (r4, r8, r9, r10)
+#endif
+ mtctr r5
+
+ lwz r0,0(r4)
+ mullw r7,r0,r6
+ mulhwu r10,r0,r6
+ lwz r9,0(r3)
+ subf r8,r7,r9
+ addc r7,r7,r8 # invert cy (r7 is junk)
+ addi r3,r3,-4 # adjust res_ptr
+ bdz L(1)
+
+L(0): lwzu r0,4(r4)
+ stwu r8,4(r3)
+ mullw r8,r0,r6
+ adde r7,r8,r10
+ mulhwu r10,r0,r6
+ lwz r9,4(r3)
+ addze r10,r10
+ subf r8,r7,r9
+ addc r7,r7,r8 # invert cy (r7 is junk)
+ bdnz L(0)
+
+L(1): stw r8,4(r3)
+ addze r3,r10
+ blr
+END (BP_SYM (__mpn_submul_1))
diff --git a/libc/sysdeps/powerpc/powerpc32/sysdep.h b/libc/sysdeps/powerpc/powerpc32/sysdep.h
new file mode 100644
index 000000000..8fc624ebd
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc32/sysdep.h
@@ -0,0 +1,153 @@
+/* Assembly macros for 32-bit PowerPC.
+ Copyright (C) 1999, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdeps/powerpc/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+#ifdef __ELF__
+
+/* If compiled for profiling, call `_mcount' at the start of each
+ function. */
+#ifdef PROF
+/* The mcount code relies on a the return address being on the stack
+ to locate our caller and so it can restore it; so store one just
+ for its benefit. */
+# define CALL_MCOUNT \
+ mflr r0; \
+ stw r0,4(r1); \
+ cfi_offset (lr, 4); \
+ bl JUMPTARGET(_mcount);
+#else /* PROF */
+# define CALL_MCOUNT /* Do nothing. */
+#endif /* PROF */
+
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ cfi_startproc; \
+ CALL_MCOUNT
+
+#define EALIGN_W_0 /* No words to insert. */
+#define EALIGN_W_1 nop
+#define EALIGN_W_2 nop;nop
+#define EALIGN_W_3 nop;nop;nop
+#define EALIGN_W_4 EALIGN_W_3;nop
+#define EALIGN_W_5 EALIGN_W_4;nop
+#define EALIGN_W_6 EALIGN_W_5;nop
+#define EALIGN_W_7 EALIGN_W_6;nop
+
+/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+ past a 2^align boundary. */
+#ifdef PROF
+# define EALIGN(name, alignt, words) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ cfi_startproc; \
+ CALL_MCOUNT \
+ b 0f; \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+ 0:
+#else /* PROF */
+# define EALIGN(name, alignt, words) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+ C_LABEL(name) \
+ cfi_startproc;
+#endif
+
+#undef END
+#define END(name) \
+ cfi_endproc; \
+ ASM_SIZE_DIRECTIVE(name)
+
+#define DO_CALL(syscall) \
+ li 0,syscall; \
+ sc
+
+#undef JUMPTARGET
+#ifdef PIC
+# define JUMPTARGET(name) name##@plt
+#else
+# define JUMPTARGET(name) name
+#endif
+
+#if defined SHARED && defined DO_VERSIONING && defined PIC \
+ && !defined HAVE_BROKEN_ALIAS_ATTRIBUTE && !defined NO_HIDDEN
+# undef HIDDEN_JUMPTARGET
+# define HIDDEN_JUMPTARGET(name) __GI_##name##@local
+#endif
+
+#define PSEUDO(name, syscall_name, args) \
+ .section ".text"; \
+ ENTRY (name) \
+ DO_CALL (SYS_ify (syscall_name));
+
+#define PSEUDO_RET \
+ bnslr+; \
+ b __syscall_error@local
+#define ret PSEUDO_RET
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
+
+#define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .section ".text"; \
+ ENTRY (name) \
+ DO_CALL (SYS_ify (syscall_name));
+
+#define PSEUDO_RET_NOERRNO \
+ blr
+#define ret_NOERRNO PSEUDO_RET_NOERRNO
+
+#undef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(name) \
+ END (name)
+
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .section ".text"; \
+ ENTRY (name) \
+ DO_CALL (SYS_ify (syscall_name));
+
+#define PSEUDO_RET_ERRVAL \
+ blr
+#define ret_ERRVAL PSEUDO_RET_ERRVAL
+
+#undef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(name) \
+ END (name)
+
+/* Local labels stripped out by the linker. */
+#undef L
+#define L(x) .L##x
+
+/* Label in text section. */
+#define C_TEXT(name) name
+
+#endif /* __ELF__ */
+
+#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/powerpc/powerpc64/Implies b/libc/sysdeps/powerpc/powerpc64/Implies
new file mode 100644
index 000000000..a8cae95f9
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/Implies
@@ -0,0 +1 @@
+wordsize-64
diff --git a/libc/sysdeps/powerpc/powerpc64/Makefile b/libc/sysdeps/powerpc/powerpc64/Makefile
new file mode 100644
index 000000000..78d4f07e5
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/Makefile
@@ -0,0 +1,45 @@
+# Powerpc64 specific build options.
+# this is ./sysdeps/powerpc/powerpc64/Makefile
+
+# Each TOC entry takes 8 bytes and the TOC holds up to 2^16 bytes,
+# or 8192 entries.
+# If -fpic is not specified, the latest gcc-3.2.1 now generates
+# different code for call stubs (without the TOC reload).
+# Shared objects need the TOC reload so specify -fpic.
+ifeq (yes,$(build-shared))
+pic-ccflag = -fpic
+endif
+
+# These flags prevent FPU or Altivec registers from being used,
+# for code called in contexts that is not allowed to touch those registers.
+# Stupid GCC requires us to pass all these ridiculous switches.
+no-special-regs := $(sort $(foreach n,40 41 50 51 60 61 62 63 \
+ $(foreach m,2 3 4 5 6 7 8 9, \
+ 3$m 4$m 5$m),\
+ -ffixed-$n)) \
+ $(sort $(foreach n,$(foreach m,0 1 2 3 4 5 6 7 8 9,\
+ $m 1$m 2$m) 30 31,\
+ -ffixed-v$n)) \
+ -ffixed-vrsave -ffixed-vscr
+
+ifeq ($(subdir),csu)
+sysdep_routines += hp-timing
+elide-routines.os += hp-timing
+ifneq ($(elf),no)
+# The initfini generation code doesn't work in the presence of -fPIC, so
+# we use -fpic instead which is much better.
+CFLAGS-initfini.s += -fpic -O1
+endif
+endif
+
+ifeq ($(subdir),elf)
+# help gcc inline asm code from dl-machine.h
++cflags += -finline-limit=2000
+endif
+
+ifeq ($(subdir),gmon)
+# The assembly functions assume that fp arg regs are not trashed.
+# Compiling with -msoft-float ensures that fp regs are not used
+# for moving memory around.
+CFLAGS-mcount.c += $(no-special-regs)
+endif
diff --git a/libc/sysdeps/powerpc/powerpc64/__longjmp-common.S b/libc/sysdeps/powerpc/powerpc64/__longjmp-common.S
new file mode 100644
index 000000000..31b1af34f
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/__longjmp-common.S
@@ -0,0 +1,165 @@
+/* longjmp for PowerPC64.
+ Copyright (C) 1995, 1996,1997,1999,2000,2001,2002,2003,2004,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ASM
+#define _SETJMP_H
+#ifdef __NO_VMX__
+# include <novmxsetjmp.h>
+#else
+# include <jmpbuf-offsets.h>
+#endif
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+#ifndef __NO_VMX__
+ .section ".toc","aw"
+.LC__dl_hwcap:
+# ifdef SHARED
+ .tc _rtld_global_ro[TC],_rtld_global_ro
+# else
+ .tc _dl_hwcap[TC],_dl_hwcap
+# endif
+ .section ".text"
+#endif
+
+ .machine "altivec"
+ENTRY (BP_SYM (__longjmp))
+ CALL_MCOUNT 2
+ CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
+#ifndef __NO_VMX__
+ ld r5,.LC__dl_hwcap@toc(r2)
+# ifdef SHARED
+ /* Load _rtld-global._dl_hwcap. */
+ ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
+# else
+ ld r5,0(r5) /* Load extern _dl_hwcap. */
+# endif
+ andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ beq L(no_vmx)
+ la r5,((JB_VRS)*8)(3)
+ andi. r6,r5,0xf
+ lwz r0,((JB_VRSAVE)*8)(3)
+ mtspr VRSAVE,r0
+ beq+ aligned_restore_vmx
+ addi r6,r5,16
+ lvsl v0,0,r5
+ lvx v1,0,r5
+ addi r5,r5,32
+ lvx v21,0,r6
+ vperm v20,v1,v21,v0
+# define load_misaligned_vmx_lo_loaded(loadvr,lovr,shiftvr,loadgpr,addgpr) \
+ addi addgpr,addgpr,32; \
+ lvx lovr,0,loadgpr; \
+ vperm loadvr,loadvr,lovr,shiftvr;
+ load_misaligned_vmx_lo_loaded(v21,v22,v0,r5,r6)
+ load_misaligned_vmx_lo_loaded(v22,v23,v0,r6,r5)
+ load_misaligned_vmx_lo_loaded(v23,v24,v0,r5,r6)
+ load_misaligned_vmx_lo_loaded(v24,v25,v0,r6,r5)
+ load_misaligned_vmx_lo_loaded(v25,v26,v0,r5,r6)
+ load_misaligned_vmx_lo_loaded(v26,v27,v0,r6,r5)
+ load_misaligned_vmx_lo_loaded(v27,v28,v0,r5,r6)
+ load_misaligned_vmx_lo_loaded(v28,v29,v0,r6,r5)
+ load_misaligned_vmx_lo_loaded(v29,v30,v0,r5,r6)
+ load_misaligned_vmx_lo_loaded(v30,v31,v0,r6,r5)
+ lvx v1,0,r5
+ vperm v31,v31,v1,v0
+ b L(no_vmx)
+aligned_restore_vmx:
+ addi r6,r5,16
+ lvx v20,0,r5
+ addi r5,r5,32
+ lvx v21,0,r6
+ addi r6,r6,32
+ lvx v22,0,r5
+ addi r5,r5,32
+ lvx v23,0,r6
+ addi r6,r6,32
+ lvx v24,0,r5
+ addi r5,r5,32
+ lvx v25,0,r6
+ addi r6,r6,32
+ lvx v26,0,r5
+ addi r5,r5,32
+ lvx v27,0,r6
+ addi r6,r6,32
+ lvx v28,0,r5
+ addi r5,r5,32
+ lvx v29,0,r6
+ addi r6,r6,32
+ lvx v30,0,r5
+ lvx v31,0,r6
+L(no_vmx):
+#endif
+ ld r1,(JB_GPR1*8)(r3)
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (r1, r25)
+#endif
+ ld r2,(JB_GPR2*8)(r3)
+ ld r0,(JB_LR*8)(r3)
+ ld r14,((JB_GPRS+0)*8)(r3)
+ lfd fp14,((JB_FPRS+0)*8)(r3)
+#if defined SHARED && !defined IS_IN_rtld
+ std r2,40(r1) /* Restore the callers TOC save area. */
+#endif
+ ld r15,((JB_GPRS+1)*8)(r3)
+ lfd fp15,((JB_FPRS+1)*8)(r3)
+ ld r16,((JB_GPRS+2)*8)(r3)
+ lfd fp16,((JB_FPRS+2)*8)(r3)
+ ld r17,((JB_GPRS+3)*8)(r3)
+ lfd fp17,((JB_FPRS+3)*8)(r3)
+ ld r18,((JB_GPRS+4)*8)(r3)
+ lfd fp18,((JB_FPRS+4)*8)(r3)
+ ld r19,((JB_GPRS+5)*8)(r3)
+ lfd fp19,((JB_FPRS+5)*8)(r3)
+ ld r20,((JB_GPRS+6)*8)(r3)
+ lfd fp20,((JB_FPRS+6)*8)(r3)
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE2 (r0, r25)
+#endif
+ mtlr r0
+/* std r2,40(r1) Restore the TOC save area. */
+ ld r21,((JB_GPRS+7)*8)(r3)
+ lfd fp21,((JB_FPRS+7)*8)(r3)
+ ld r22,((JB_GPRS+8)*8)(r3)
+ lfd fp22,((JB_FPRS+8)*8)(r3)
+ ld r0,(JB_CR*8)(r3)
+ ld r23,((JB_GPRS+9)*8)(r3)
+ lfd fp23,((JB_FPRS+9)*8)(r3)
+ ld r24,((JB_GPRS+10)*8)(r3)
+ lfd fp24,((JB_FPRS+10)*8)(r3)
+ ld r25,((JB_GPRS+11)*8)(r3)
+ lfd fp25,((JB_FPRS+11)*8)(r3)
+ mtcrf 0xFF,r0
+ ld r26,((JB_GPRS+12)*8)(r3)
+ lfd fp26,((JB_FPRS+12)*8)(r3)
+ ld r27,((JB_GPRS+13)*8)(r3)
+ lfd fp27,((JB_FPRS+13)*8)(r3)
+ ld r28,((JB_GPRS+14)*8)(r3)
+ lfd fp28,((JB_FPRS+14)*8)(r3)
+ ld r29,((JB_GPRS+15)*8)(r3)
+ lfd fp29,((JB_FPRS+15)*8)(r3)
+ ld r30,((JB_GPRS+16)*8)(r3)
+ lfd fp30,((JB_FPRS+16)*8)(r3)
+ ld r31,((JB_GPRS+17)*8)(r3)
+ lfd fp31,((JB_FPRS+17)*8)(r3)
+ mr r3,r4
+ blr
+END (BP_SYM (__longjmp))
diff --git a/libc/sysdeps/powerpc/powerpc64/__longjmp.S b/libc/sysdeps/powerpc/powerpc64/__longjmp.S
new file mode 100644
index 000000000..968e9dce5
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/__longjmp.S
@@ -0,0 +1,40 @@
+/* AltiVec/VMX (new) version of __longjmp for PowerPC64.
+ Copyright (C) 1995-1997, 1999-2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <libc-symbols.h>
+#include <rtld-global-offsets.h>
+#include <shlib-compat.h>
+
+#if defined NOT_IN_libc
+/* Build a non-versioned object for rtld-*. */
+# include "__longjmp-common.S"
+
+#else /* !NOT_IN_libc */
+strong_alias (__vmx__longjmp, __longjmp)
+# define __longjmp __vmx__longjmp
+# include "__longjmp-common.S"
+
+# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
+# define __NO_VMX__
+# undef __longjmp
+# undef JB_SIZE
+# define __longjmp __novmx__longjmp
+# include "__longjmp-common.S"
+# endif
+#endif /* !NOT_IN_libc */
diff --git a/libc/sysdeps/powerpc/powerpc64/backtrace.c b/libc/sysdeps/powerpc/powerpc64/backtrace.c
new file mode 100644
index 000000000..9c8ebbb18
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/backtrace.c
@@ -0,0 +1,70 @@
+/* Return backtrace of current program state.
+ Copyright (C) 1998, 2000, 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <execinfo.h>
+#include <stddef.h>
+#include <bp-checks.h>
+
+/* This is the stack layout we see with every stack frame.
+ Note that every routine is required by the ABI to lay out the stack
+ like this.
+
+ +----------------+ +-----------------+
+ %r1 -> | %r1 last frame--------> | %r1 last frame--->... --> NULL
+ | | | |
+ | cr save | | cr save |
+ | | | |
+ | (unused) | | return address |
+ +----------------+ +-----------------+
+*/
+struct layout
+{
+ struct layout *__unbounded next;
+ long condition_register;
+ void *__unbounded return_address;
+};
+
+int
+__backtrace (void **array, int size)
+{
+ struct layout *current;
+ int count;
+
+ /* Force gcc to spill LR. */
+ asm volatile ("" : "=l"(current));
+
+ /* Get the address on top-of-stack. */
+ asm volatile ("ld %0,0(1)" : "=r"(current));
+ current = BOUNDED_1 (current);
+
+ for ( count = 0;
+ current != NULL && count < size;
+ current = BOUNDED_1 (current->next), count++)
+ array[count] = current->return_address;
+
+ /* It's possible the second-last stack frame can't return
+ (that is, it's __libc_start_main), in which case
+ the CRT startup code will have set its LR to 'NULL'. */
+ if (count > 0 && array[count-1] == NULL)
+ count--;
+
+ return count;
+}
+weak_alias (__backtrace, backtrace)
+libc_hidden_def (__backtrace)
diff --git a/libc/sysdeps/powerpc/powerpc64/bits/atomic.h b/libc/sysdeps/powerpc/powerpc64/bits/atomic.h
new file mode 100644
index 000000000..e46dc1e4d
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/bits/atomic.h
@@ -0,0 +1,227 @@
+/* Atomic operations. PowerPC64 version.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The 32-bit exchange_bool is different on powerpc64 because the subf
+ does signed 64-bit arthmatic while the lwarx is 32-bit unsigned
+ (a load word and zero (high 32) form) load.
+ In powerpc64 register values are 64-bit by default, including oldval.
+ The value in old val unknown sign extension, lwarx loads the 32-bit
+ value as unsigned. So we explicitly clear the high 32 bits in oldval. */
+# define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \
+({ \
+ unsigned int __tmp, __tmp2; \
+ __asm __volatile (" clrldi %1,%1,32\n" \
+ "1: lwarx %0,0,%2\n" \
+ " subf. %0,%1,%0\n" \
+ " bne 2f\n" \
+ " stwcx. %4,0,%2\n" \
+ " bne- 1b\n" \
+ "2: " __ARCH_ACQ_INSTR \
+ : "=&r" (__tmp), "=r" (__tmp2) \
+ : "b" (mem), "1" (oldval), "r" (newval) \
+ : "cr0", "memory"); \
+ __tmp != 0; \
+})
+
+# define __arch_compare_and_exchange_bool_32_rel(mem, newval, oldval) \
+({ \
+ unsigned int __tmp, __tmp2; \
+ __asm __volatile (__ARCH_REL_INSTR "\n" \
+ " clrldi %1,%1,32\n" \
+ "1: lwarx %0,0,%2\n" \
+ " subf. %0,%1,%0\n" \
+ " bne 2f\n" \
+ " stwcx. %4,0,%2\n" \
+ " bne- 1b\n" \
+ "2: " \
+ : "=&r" (__tmp), "=r" (__tmp2) \
+ : "b" (mem), "1" (oldval), "r" (newval) \
+ : "cr0", "memory"); \
+ __tmp != 0; \
+})
+
+/*
+ * Only powerpc64 processors support Load doubleword and reserve index (ldarx)
+ * and Store doubleword conditional indexed (stdcx) instructions. So here
+ * we define the 64-bit forms.
+ */
+# define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \
+({ \
+ unsigned long __tmp; \
+ __asm __volatile ( \
+ "1: ldarx %0,0,%1\n" \
+ " subf. %0,%2,%0\n" \
+ " bne 2f\n" \
+ " stdcx. %3,0,%1\n" \
+ " bne- 1b\n" \
+ "2: " __ARCH_ACQ_INSTR \
+ : "=&r" (__tmp) \
+ : "b" (mem), "r" (oldval), "r" (newval) \
+ : "cr0", "memory"); \
+ __tmp != 0; \
+})
+
+# define __arch_compare_and_exchange_bool_64_rel(mem, newval, oldval) \
+({ \
+ unsigned long __tmp; \
+ __asm __volatile (__ARCH_REL_INSTR "\n" \
+ "1: ldarx %0,0,%1\n" \
+ " subf. %0,%2,%0\n" \
+ " bne 2f\n" \
+ " stdcx. %3,0,%1\n" \
+ " bne- 1b\n" \
+ "2: " \
+ : "=&r" (__tmp) \
+ : "b" (mem), "r" (oldval), "r" (newval) \
+ : "cr0", "memory"); \
+ __tmp != 0; \
+})
+
+#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ \
+ __typeof (*(mem)) __tmp; \
+ __typeof (mem) __memp = (mem); \
+ __asm __volatile ( \
+ "1: ldarx %0,0,%1\n" \
+ " cmpd %0,%2\n" \
+ " bne 2f\n" \
+ " stdcx. %3,0,%1\n" \
+ " bne- 1b\n" \
+ "2: " __ARCH_ACQ_INSTR \
+ : "=&r" (__tmp) \
+ : "b" (__memp), "r" (oldval), "r" (newval) \
+ : "cr0", "memory"); \
+ __tmp; \
+ })
+
+#define __arch_compare_and_exchange_val_64_rel(mem, newval, oldval) \
+ ({ \
+ __typeof (*(mem)) __tmp; \
+ __typeof (mem) __memp = (mem); \
+ __asm __volatile (__ARCH_REL_INSTR "\n" \
+ "1: ldarx %0,0,%1\n" \
+ " cmpd %0,%2\n" \
+ " bne 2f\n" \
+ " stdcx. %3,0,%1\n" \
+ " bne- 1b\n" \
+ "2: " \
+ : "=&r" (__tmp) \
+ : "b" (__memp), "r" (oldval), "r" (newval) \
+ : "cr0", "memory"); \
+ __tmp; \
+ })
+
+# define __arch_atomic_exchange_64_acq(mem, value) \
+ ({ \
+ __typeof (*mem) __val; \
+ __asm __volatile (__ARCH_REL_INSTR "\n" \
+ "1: ldarx %0,0,%2\n" \
+ " stdcx. %3,0,%2\n" \
+ " bne- 1b\n" \
+ " " __ARCH_ACQ_INSTR \
+ : "=&r" (__val), "=m" (*mem) \
+ : "b" (mem), "r" (value), "m" (*mem) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+# define __arch_atomic_exchange_64_rel(mem, value) \
+ ({ \
+ __typeof (*mem) __val; \
+ __asm __volatile (__ARCH_REL_INSTR "\n" \
+ "1: ldarx %0,0,%2\n" \
+ " stdcx. %3,0,%2\n" \
+ " bne- 1b" \
+ : "=&r" (__val), "=m" (*mem) \
+ : "b" (mem), "r" (value), "m" (*mem) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+# define __arch_atomic_exchange_and_add_64(mem, value) \
+ ({ \
+ __typeof (*mem) __val, __tmp; \
+ __asm __volatile ("1: ldarx %0,0,%3\n" \
+ " add %1,%0,%4\n" \
+ " stdcx. %1,0,%3\n" \
+ " bne- 1b" \
+ : "=&b" (__val), "=&r" (__tmp), "=m" (*mem) \
+ : "b" (mem), "r" (value), "m" (*mem) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+# define __arch_atomic_increment_val_64(mem) \
+ ({ \
+ __typeof (*(mem)) __val; \
+ __asm __volatile ("1: ldarx %0,0,%2\n" \
+ " addi %0,%0,1\n" \
+ " stdcx. %0,0,%2\n" \
+ " bne- 1b" \
+ : "=&b" (__val), "=m" (*mem) \
+ : "b" (mem), "m" (*mem) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+# define __arch_atomic_decrement_val_64(mem) \
+ ({ \
+ __typeof (*(mem)) __val; \
+ __asm __volatile ("1: ldarx %0,0,%2\n" \
+ " subi %0,%0,1\n" \
+ " stdcx. %0,0,%2\n" \
+ " bne- 1b" \
+ : "=&b" (__val), "=m" (*mem) \
+ : "b" (mem), "m" (*mem) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+# define __arch_atomic_decrement_if_positive_64(mem) \
+ ({ int __val, __tmp; \
+ __asm __volatile ("1: ldarx %0,0,%3\n" \
+ " cmpdi 0,%0,0\n" \
+ " addi %1,%0,-1\n" \
+ " ble 2f\n" \
+ " stdcx. %1,0,%3\n" \
+ " bne- 1b\n" \
+ "2: " __ARCH_ACQ_INSTR \
+ : "=&b" (__val), "=&r" (__tmp), "=m" (*mem) \
+ : "b" (mem), "m" (*mem) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+/*
+ * All powerpc64 processors support the new "light weight" sync (lwsync).
+ */
+# define atomic_read_barrier() __asm ("lwsync" ::: "memory")
+/*
+ * "light weight" sync can also be used for the release barrier.
+ */
+# ifndef UP
+# define __ARCH_REL_INSTR "lwsync"
+# endif
+
+/*
+ * Include the rest of the atomic ops macros which are common to both
+ * powerpc32 and powerpc64.
+ */
+#include_next <bits/atomic.h>
diff --git a/libc/sysdeps/powerpc/powerpc64/bits/wordsize.h b/libc/sysdeps/powerpc/powerpc64/bits/wordsize.h
new file mode 100644
index 000000000..1a79c8636
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/bits/wordsize.h
@@ -0,0 +1,8 @@
+/* Determine the wordsize from the preprocessor defines. */
+
+#if defined __powerpc64__
+# define __WORDSIZE 64
+# define __WORDSIZE_COMPAT32 1
+#else
+# define __WORDSIZE 32
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/bp-asm.h b/libc/sysdeps/powerpc/powerpc64/bp-asm.h
new file mode 100644
index 000000000..ee99e3044
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/bp-asm.h
@@ -0,0 +1,115 @@
+/* Bounded-pointer definitions for PowerPC64 assembler.
+ Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ Contributed by Greg McGary <greg@mcgary.org>
+
+ This file is part of the GNU C Library. Its master source is NOT part of
+ the C library, however. The master source lives in the GNU MP Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#if __BOUNDED_POINTERS__
+
+/* Byte offsets of BP components. */
+# define oVALUE 0
+# define oLOW 4
+# define oHIGH 8
+
+/* Don't check bounds, just convert the BP register to its simple
+ pointer value. */
+
+# define DISCARD_BOUNDS(rBP) \
+ ld rBP, oVALUE(rBP)
+
+/* Check low bound, with the side effect that the BP register is converted
+ its simple pointer value. Move the high bound into a register for
+ later use. */
+
+# define CHECK_BOUNDS_LOW(rBP, rLOW, rHIGH) \
+ ld rHIGH, oHIGH(rBP); \
+ ld rLOW, oLOW(rBP); \
+ ld rBP, oVALUE(rBP); \
+ tdllt rBP, rLOW
+
+/* Check the high bound, which is in a register, using the given
+ conditional trap instruction. */
+
+# define CHECK_BOUNDS_HIGH(rVALUE, rHIGH, TWLcc) \
+ TWLcc rVALUE, rHIGH
+
+/* Check the high bound, which is stored at the return-value's high
+ bound slot, using the given conditional trap instruction. */
+
+# define CHECK_BOUNDS_HIGH_RTN(rVALUE, rHIGH, TWLcc) \
+ ld rHIGH, oHIGH(rRTN); \
+ TWLcc rVALUE, rHIGH
+
+/* Check both bounds, with the side effect that the BP register is
+ converted to its simple pointer value. */
+
+# define CHECK_BOUNDS_BOTH(rBP, rLOW, rHIGH) \
+ CHECK_BOUNDS_LOW(rBP, rLOW, rHIGH); \
+ tdlge rBP, rHIGH
+
+/* Check bounds on a memory region of given length, with the side
+ effect that the BP register is converted to its simple pointer
+ value. */
+
+# define CHECK_BOUNDS_BOTH_WIDE(rBP, rLOW, rHIGH, rLENGTH) \
+ CHECK_BOUNDS_LOW (rBP, rLOW, rHIGH); \
+ sub rHIGH, rHIGH, rLENGTH; \
+ tdlgt rBP, rHIGH
+
+# define CHECK_BOUNDS_BOTH_WIDE_LIT(rBP, rLOW, rHIGH, LENGTH) \
+ CHECK_BOUNDS_LOW (rBP, rLOW, rHIGH); \
+ subi rHIGH, rHIGH, LENGTH; \
+ tdlgt rBP, rHIGH
+
+/* Store a pointer value register into the return-value's pointer
+ value slot. */
+
+# define STORE_RETURN_VALUE(rVALUE) \
+ std rVALUE, oVALUE(rRTN)
+
+/* Store a low and high bounds into the return-value's pointer bounds
+ slots. */
+
+# define STORE_RETURN_BOUNDS(rLOW, rHIGH) \
+ std rLOW, oLOW(rRTN); \
+ std rHIGH, oHIGH(rRTN)
+
+/* Stuff zero value/low/high into the BP addressed by rRTN. */
+
+# define RETURN_NULL_BOUNDED_POINTER \
+ li r4, 0; \
+ STORE_RETURN_VALUE (r4); \
+ STORE_RETURN_BOUNDS (r4, r4)
+
+#else
+
+# define DISCARD_BOUNDS(rBP)
+# define CHECK_BOUNDS_LOW(rBP, rLOW, rHIGH)
+# define CHECK_BOUNDS_HIGH(rVALUE, rHIGH, TWLcc)
+# define CHECK_BOUNDS_HIGH_RTN(rVALUE, rHIGH, TWLcc)
+# define CHECK_BOUNDS_BOTH(rBP, rLOW, rHIGH)
+# define CHECK_BOUNDS_BOTH_WIDE(rBP, rLOW, rHIGH, rLENGTH)
+# define CHECK_BOUNDS_BOTH_WIDE_LIT(rBP, rLOW, rHIGH, LENGTH)
+# define STORE_RETURN_VALUE(rVALUE)
+# define STORE_RETURN_BOUNDS(rLOW, rHIGH)
+
+# define RETURN_NULL_BOUNDED_POINTER li rRTN, 0
+
+#endif
+
diff --git a/libc/sysdeps/powerpc/powerpc64/bsd-_setjmp.S b/libc/sysdeps/powerpc/powerpc64/bsd-_setjmp.S
new file mode 100644
index 000000000..82b79a809
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/bsd-_setjmp.S
@@ -0,0 +1,66 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. PowerPC32/64 version.
+ Copyright (C) 1994, 1997, 1999, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+#include <shlib-compat.h>
+#include <libc-symbols.h>
+#include <sysdep.h>
+#include <bp-sym.h>
+
+#if defined NOT_IN_libc
+/* Build a non-versioned object for rtld-*. */
+ENTRY (BP_SYM (_setjmp))
+ CALL_MCOUNT 1
+ li r4,0 /* Set second argument to 0. */
+ b JUMPTARGET (__sigsetjmp_ent)
+END (BP_SYM (_setjmp))
+libc_hidden_def (_setjmp)
+
+#else
+/* Build a versioned object for libc. */
+# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
+symbol_version (__novmx_setjmp,_setjmp,GLIBC_2.3);
+
+ENTRY (BP_SYM (__novmx_setjmp))
+ CALL_MCOUNT 1
+ li r4,0 /* Set second argument to 0. */
+ b JUMPTARGET (__novmx__sigsetjmp_ent)
+END (BP_SYM (__novmx_setjmp))
+libc_hidden_def (__novmx_setjmp)
+# endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4) */
+
+default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4)
+/* __GI__setjmp prototype is needed for ntpl i.e. _setjmp is defined
+ as a libc_hidden_proto & is used in sysdeps/generic/libc-start.c
+ if HAVE_CLEANUP_JMP_BUF is defined */
+ENTRY (BP_SYM (__GI__setjmp))
+#if defined SHARED && !defined IS_IN_rtld
+ std r2,40(r1) /* Save the callers TOC in the save area. */
+#endif
+ CALL_MCOUNT 1
+ li r4,0 /* Set second argument to 0. */
+ b JUMPTARGET (__vmx__sigsetjmp_ent)
+END (BP_SYM (__GI__setjmp))
+
+ENTRY (BP_SYM (__vmx_setjmp))
+ CALL_MCOUNT 1
+ li r4,0 /* Set second argument to 0. */
+ b JUMPTARGET (__vmx__sigsetjmp_ent)
+END (BP_SYM (__vmx_setjmp))
+libc_hidden_def (__vmx_setjmp)
+#endif /* !NOT_IN_libc */
diff --git a/libc/sysdeps/powerpc/powerpc64/bsd-setjmp.S b/libc/sysdeps/powerpc/powerpc64/bsd-setjmp.S
new file mode 100644
index 000000000..543e83faa
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/bsd-setjmp.S
@@ -0,0 +1,45 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. PowerPC32/64 version.
+ Copyright (C) 1994,1997,1999,2000,2003,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+#include <shlib-compat.h>
+#include <libc-symbols.h>
+#include <sysdep.h>
+#include <bp-sym.h>
+
+#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
+
+
+ENTRY (__novmxsetjmp)
+ CALL_MCOUNT 1
+ li r4,1 /* Set second argument to 1. */
+ b JUMPTARGET (__novmx__sigsetjmp_ent)
+END (__novmxsetjmp)
+strong_alias (__novmxsetjmp, __novmx__setjmp)
+symbol_version (__novmxsetjmp, setjmp, GLIBC_2.3)
+
+#endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4) */
+
+
+ENTRY (__vmxsetjmp)
+ CALL_MCOUNT 1
+ li r4,1 /* Set second argument to 1. */
+ b JUMPTARGET (__vmx__sigsetjmp_ent)
+END (__vmxsetjmp)
+strong_alias (__vmxsetjmp, __vmx__setjmp)
+strong_alias (__vmx__sigsetjmp, __setjmp)
+default_symbol_version (__vmxsetjmp, setjmp, GLIBC_2.3.4)
diff --git a/libc/sysdeps/powerpc/powerpc64/configure b/libc/sysdeps/powerpc/powerpc64/configure
new file mode 100644
index 000000000..9075a5c8c
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/configure
@@ -0,0 +1,68 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/powerpc/powerpc64.
+
+# The Aix ld uses global .symbol_names instead of symbol_names
+# and unfortunately early Linux PPC64 linkers use it as well.
+echo "$as_me:$LINENO: checking for support for omitting dot symbols" >&5
+echo $ECHO_N "checking for support for omitting dot symbols... $ECHO_C" >&6
+if test "${libc_cv_omit_dot_syms+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ libc_cv_omit_dot_syms=no
+echo 'void foo (void) {}' > conftest.c
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -S conftest.c -o conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if grep -w '\.foo' conftest.s > /dev/null; then
+ :
+ else
+ libc_cv_omit_dot_syms=yes
+ fi
+fi
+rm -f conftest.c conftest.s
+
+fi
+echo "$as_me:$LINENO: result: $libc_cv_omit_dot_syms" >&5
+echo "${ECHO_T}$libc_cv_omit_dot_syms" >&6
+if test x$libc_cv_omit_dot_syms != xyes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_ASM_GLOBAL_DOT_NAME 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for linker support for overlapping .opd entries" >&5
+echo $ECHO_N "checking for linker support for overlapping .opd entries... $ECHO_C" >&6
+if test "${libc_cv_overlapping_opd+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ libc_cv_overlapping_opd=no
+echo 'void foo (void) {}' > conftest.c
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -S conftest.c -o conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if grep '\.TOC\.@tocbase' conftest.s > /dev/null; then
+ if grep '\.TOC\.@tocbase[ ]*,[ ]*0' conftest.s > /dev/null; then
+ :
+ else
+ libc_cv_overlapping_opd=yes
+ fi
+ fi
+fi
+rm -f conftest.c conftest.s
+
+fi
+echo "$as_me:$LINENO: result: $libc_cv_overlapping_opd" >&5
+echo "${ECHO_T}$libc_cv_overlapping_opd" >&6
+if test x$libc_cv_overlapping_opd = xyes; then
+ cat >>confdefs.h <<\_ACEOF
+#define USE_PPC64_OVERLAPPING_OPD 1
+_ACEOF
+
+fi
diff --git a/libc/sysdeps/powerpc/powerpc64/configure.in b/libc/sysdeps/powerpc/powerpc64/configure.in
new file mode 100644
index 000000000..67aac663d
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/configure.in
@@ -0,0 +1,42 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/powerpc/powerpc64.
+
+# The Aix ld uses global .symbol_names instead of symbol_names
+# and unfortunately early Linux PPC64 linkers use it as well.
+AC_CACHE_CHECK(for support for omitting dot symbols,
+libc_cv_omit_dot_syms, [dnl
+libc_cv_omit_dot_syms=no
+echo 'void foo (void) {}' > conftest.c
+if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ if grep -w '\.foo' conftest.s > /dev/null; then
+ :
+ else
+ libc_cv_omit_dot_syms=yes
+ fi
+fi
+rm -f conftest.c conftest.s
+])
+if test x$libc_cv_omit_dot_syms != xyes; then
+ AC_DEFINE(HAVE_ASM_GLOBAL_DOT_NAME)
+fi
+
+AC_CACHE_CHECK(for linker support for overlapping .opd entries,
+libc_cv_overlapping_opd, [dnl
+libc_cv_overlapping_opd=no
+echo 'void foo (void) {}' > conftest.c
+if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+changequote(,)dnl
+ if grep '\.TOC\.@tocbase' conftest.s > /dev/null; then
+ if grep '\.TOC\.@tocbase[ ]*,[ ]*0' conftest.s > /dev/null; then
+ :
+ else
+ libc_cv_overlapping_opd=yes
+ fi
+ fi
+changequote([,])dnl
+fi
+rm -f conftest.c conftest.s
+])
+if test x$libc_cv_overlapping_opd = xyes; then
+ AC_DEFINE(USE_PPC64_OVERLAPPING_OPD)
+fi
diff --git a/libc/sysdeps/powerpc/powerpc64/dl-dtprocnum.h b/libc/sysdeps/powerpc/powerpc64/dl-dtprocnum.h
new file mode 100644
index 000000000..477cb4433
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/dl-dtprocnum.h
@@ -0,0 +1,22 @@
+/* Configuration of lookup functions. PowerPC64 version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Number of extra dynamic section entries for this architecture. By
+ default there are none. */
+#define DT_THISPROCNUM DT_PPC64_NUM
diff --git a/libc/sysdeps/powerpc/powerpc64/dl-machine.c b/libc/sysdeps/powerpc/powerpc64/dl-machine.c
new file mode 100644
index 000000000..6d9a585d2
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/dl-machine.c
@@ -0,0 +1,48 @@
+/* Machine-dependent ELF dynamic relocation functions. PowerPC64 version.
+ Copyright (C) 1995-2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <stdio-common/_itoa.h>
+#include <dl-machine.h>
+
+void
+_dl_reloc_overflow (struct link_map *map,
+ const char *name,
+ Elf64_Addr *const reloc_addr,
+ const Elf64_Sym *refsym)
+{
+ char buffer[128];
+ char *t;
+ t = stpcpy (buffer, name);
+ t = stpcpy (t, " reloc at 0x");
+ _itoa_word ((unsigned long) reloc_addr, t, 16, 0);
+ if (refsym)
+ {
+ const char *strtab;
+
+ strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+ t = stpcpy (t, " for symbol `");
+ t = stpcpy (t, strtab + refsym->st_name);
+ t = stpcpy (t, "'");
+ }
+ t = stpcpy (t, " out of range");
+ _dl_signal_error (0, map->l_name, NULL, buffer);
+}
diff --git a/libc/sysdeps/powerpc/powerpc64/dl-machine.h b/libc/sysdeps/powerpc/powerpc64/dl-machine.h
new file mode 100644
index 000000000..cec271bb3
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -0,0 +1,814 @@
+/* Machine-dependent ELF dynamic relocation inline functions.
+ PowerPC64 version.
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "powerpc64"
+
+#include <assert.h>
+#include <sys/param.h>
+#include <dl-tls.h>
+#include <sysdep.h>
+
+/* Translate a processor specific dynamic tag to the index
+ in l_info array. */
+#define DT_PPC64(x) (DT_PPC64_##x - DT_LOPROC + DT_NUM)
+
+/* A PowerPC64 function descriptor. The .plt (procedure linkage
+ table) and .opd (official procedure descriptor) sections are
+ arrays of these. */
+typedef struct
+{
+ Elf64_Addr fd_func;
+ Elf64_Addr fd_toc;
+ Elf64_Addr fd_aux;
+} Elf64_FuncDesc;
+
+#define ELF_MULT_MACHINES_SUPPORTED
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int
+elf_machine_matches_host (const Elf64_Ehdr *ehdr)
+{
+ return ehdr->e_machine == EM_PPC64;
+}
+
+/* Return nonzero iff ELF header is compatible with the running host,
+ but not this loader. */
+static inline int
+elf_host_tolerates_machine (const Elf64_Ehdr *ehdr)
+{
+ return ehdr->e_machine == EM_PPC;
+}
+
+/* Return nonzero iff ELF header is compatible with the running host,
+ but not this loader. */
+static inline int
+elf_host_tolerates_class (const Elf64_Ehdr *ehdr)
+{
+ return ehdr->e_ident[EI_CLASS] == ELFCLASS32;
+}
+
+
+/* Return the run-time load address of the shared object, assuming it
+ was originally linked at zero. */
+static inline Elf64_Addr
+elf_machine_load_address (void) __attribute__ ((const));
+
+static inline Elf64_Addr
+elf_machine_load_address (void)
+{
+ Elf64_Addr ret;
+
+ /* The first entry in .got (and thus the first entry in .toc) is the
+ link-time TOC_base, ie. r2. So the difference between that and
+ the current r2 set by the kernel is how far the shared lib has
+ moved. */
+ asm ( " ld %0,-32768(2)\n"
+ " subf %0,%0,2\n"
+ : "=r" (ret));
+ return ret;
+}
+
+/* Return the link-time address of _DYNAMIC. */
+static inline Elf64_Addr
+elf_machine_dynamic (void)
+{
+ Elf64_Addr runtime_dynamic;
+ /* It's easier to get the run-time address. */
+ asm ( " addis %0,2,_DYNAMIC@toc@ha\n"
+ " addi %0,%0,_DYNAMIC@toc@l\n"
+ : "=b" (runtime_dynamic));
+ /* Then subtract off the load address offset. */
+ return runtime_dynamic - elf_machine_load_address() ;
+}
+
+#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */
+
+/* The PLT uses Elf64_Rela relocs. */
+#define elf_machine_relplt elf_machine_rela
+
+
+#ifdef HAVE_INLINED_SYSCALLS
+/* We do not need _dl_starting_up. */
+# define DL_STARTING_UP_DEF
+#else
+# define DL_STARTING_UP_DEF \
+".LC__dl_starting_up:\n" \
+" .tc _dl_starting_up_internal[TC],_dl_starting_up_internal\n"
+#endif
+
+
+/* Initial entry point code for the dynamic linker. The C function
+ `_dl_start' is the real entry point; its return value is the user
+ program's entry point. */
+#define RTLD_START \
+ asm (".pushsection \".text\"\n" \
+" .align 2\n" \
+" .type " BODY_PREFIX "_start,@function\n" \
+" .pushsection \".opd\",\"aw\"\n" \
+" .align 3\n" \
+" .globl _start\n" \
+" " ENTRY_2(_start) "\n" \
+"_start:\n" \
+" " OPD_ENT(_start) "\n" \
+" .popsection\n" \
+BODY_PREFIX "_start:\n" \
+/* We start with the following on the stack, from top: \
+ argc (4 bytes); \
+ arguments for program (terminated by NULL); \
+ environment variables (terminated by NULL); \
+ arguments for the program loader. */ \
+" mr 3,1\n" \
+" li 4,0\n" \
+" stdu 4,-128(1)\n" \
+/* Call _dl_start with one parameter pointing at argc. */ \
+" bl " DOT_PREFIX "_dl_start\n" \
+" nop\n" \
+/* Transfer control to _dl_start_user! */ \
+" b " DOT_PREFIX "_dl_start_user\n" \
+".LT__start:\n" \
+" .long 0\n" \
+" .byte 0x00,0x0c,0x24,0x40,0x00,0x00,0x00,0x00\n" \
+" .long .LT__start-" BODY_PREFIX "_start\n" \
+" .short .LT__start_name_end-.LT__start_name_start\n" \
+".LT__start_name_start:\n" \
+" .ascii \"_start\"\n" \
+".LT__start_name_end:\n" \
+" .align 2\n" \
+" " END_2(_start) "\n" \
+" .globl _dl_start_user\n" \
+" .pushsection \".opd\",\"aw\"\n" \
+"_dl_start_user:\n" \
+" " OPD_ENT(_dl_start_user) "\n" \
+" .popsection\n" \
+" .pushsection \".toc\",\"aw\"\n" \
+DL_STARTING_UP_DEF \
+".LC__rtld_global:\n" \
+" .tc _rtld_global[TC],_rtld_global\n" \
+".LC__dl_argc:\n" \
+" .tc _dl_argc[TC],_dl_argc\n" \
+".LC__dl_argv:\n" \
+" .tc _dl_argv_internal[TC],_dl_argv_internal\n" \
+".LC__dl_fini:\n" \
+" .tc _dl_fini[TC],_dl_fini\n" \
+" .popsection\n" \
+" .type " BODY_PREFIX "_dl_start_user,@function\n" \
+" " ENTRY_2(_dl_start_user) "\n" \
+/* Now, we do our main work of calling initialisation procedures. \
+ The ELF ABI doesn't say anything about parameters for these, \
+ so we just pass argc, argv, and the environment. \
+ Changing these is strongly discouraged (not least because argc is \
+ passed by value!). */ \
+BODY_PREFIX "_dl_start_user:\n" \
+/* the address of _start in r30. */ \
+" mr 30,3\n" \
+/* &_dl_argc in 29, &_dl_argv in 27, and _dl_loaded in 28. */ \
+" ld 28,.LC__rtld_global@toc(2)\n" \
+" ld 29,.LC__dl_argc@toc(2)\n" \
+" ld 27,.LC__dl_argv@toc(2)\n" \
+/* _dl_init (_dl_loaded, _dl_argc, _dl_argv, _dl_argv+_dl_argc+1). */ \
+" ld 3,0(28)\n" \
+" lwa 4,0(29)\n" \
+" ld 5,0(27)\n" \
+" sldi 6,4,3\n" \
+" add 6,5,6\n" \
+" addi 6,6,8\n" \
+" bl " DOT_PREFIX "_dl_init\n" \
+" nop\n" \
+/* Now, to conform to the ELF ABI, we have to: \
+ Pass argc (actually _dl_argc) in r3; */ \
+" lwa 3,0(29)\n" \
+/* Pass argv (actually _dl_argv) in r4; */ \
+" ld 4,0(27)\n" \
+/* Pass argv+argc+1 in r5; */ \
+" sldi 5,3,3\n" \
+" add 6,4,5\n" \
+" addi 5,6,8\n" \
+/* Pass the auxilary vector in r6. This is passed to us just after \
+ _envp. */ \
+"2: ldu 0,8(6)\n" \
+" cmpdi 0,0\n" \
+" bne 2b\n" \
+" addi 6,6,8\n" \
+/* Pass a termination function pointer (in this case _dl_fini) in \
+ r7. */ \
+" ld 7,.LC__dl_fini@toc(2)\n" \
+/* Pass the stack pointer in r1 (so far so good), pointing to a NULL \
+ value. This lets our startup code distinguish between a program \
+ linked statically, which linux will call with argc on top of the \
+ stack which will hopefully never be zero, and a dynamically linked \
+ program which will always have a NULL on the top of the stack. \
+ Take the opportunity to clear LR, so anyone who accidentally \
+ returns from _start gets SEGV. Also clear the next few words of \
+ the stack. */ \
+" li 31,0\n" \
+" std 31,0(1)\n" \
+" mtlr 31\n" \
+" std 31,8(1)\n" \
+" std 31,16(1)\n" \
+" std 31,24(1)\n" \
+/* Now, call the start function descriptor at r30... */ \
+" .globl ._dl_main_dispatch\n" \
+"._dl_main_dispatch:\n" \
+" ld 0,0(30)\n" \
+" ld 2,8(30)\n" \
+" mtctr 0\n" \
+" ld 11,16(30)\n" \
+" bctr\n" \
+".LT__dl_start_user:\n" \
+" .long 0\n" \
+" .byte 0x00,0x0c,0x24,0x40,0x00,0x00,0x00,0x00\n" \
+" .long .LT__dl_start_user-" BODY_PREFIX "_dl_start_user\n" \
+" .short .LT__dl_start_user_name_end-.LT__dl_start_user_name_start\n" \
+".LT__dl_start_user_name_start:\n" \
+" .ascii \"_dl_start_user\"\n" \
+".LT__dl_start_user_name_end:\n" \
+" .align 2\n" \
+" " END_2(_dl_start_user) "\n" \
+" .popsection");
+
+/* Nonzero iff TYPE should not be allowed to resolve to one of
+ the main executable's symbols, as for a COPY reloc. */
+#define elf_machine_lookup_noexec_p(type) ((type) == R_PPC64_COPY)
+
+/* Nonzero iff TYPE describes relocation of a PLT entry, so
+ PLT entries should not be allowed to define the value. */
+#define elf_machine_lookup_noplt_p(type) ((type) == R_PPC64_JMP_SLOT)
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
+ PLT entries should not be allowed to define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#define elf_machine_type_class(type) \
+ /* This covers all the TLS relocs, though most won't appear. */ \
+ (((((type) >= R_PPC64_DTPMOD64 && (type) <= R_PPC64_TPREL16_HIGHESTA) \
+ || (type) == R_PPC64_ADDR24) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+#define elf_machine_type_class(type) \
+ ((((type) == R_PPC64_ADDR24) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_PPC64_JMP_SLOT
+
+/* The PowerPC never uses REL relocations. */
+#define ELF_MACHINE_NO_REL 1
+
+/* Stuff for the PLT. */
+#define PLT_INITIAL_ENTRY_WORDS 3
+#define GLINK_INITIAL_ENTRY_WORDS 8
+
+#define PPC_DCBST(where) asm volatile ("dcbst 0,%0" : : "r"(where) : "memory")
+#define PPC_SYNC asm volatile ("sync" : : : "memory")
+#define PPC_ISYNC asm volatile ("sync; isync" : : : "memory")
+#define PPC_ICBI(where) asm volatile ("icbi 0,%0" : : "r"(where) : "memory")
+#define PPC_DIE asm volatile ("tweq 0,0")
+/* Use this when you've modified some code, but it won't be in the
+ instruction fetch queue (or when it doesn't matter if it is). */
+#define MODIFIED_CODE_NOQUEUE(where) \
+ do { PPC_DCBST(where); PPC_SYNC; PPC_ICBI(where); } while (0)
+/* Use this when it might be in the instruction queue. */
+#define MODIFIED_CODE(where) \
+ do { PPC_DCBST(where); PPC_SYNC; PPC_ICBI(where); PPC_ISYNC; } while (0)
+
+/* Set up the loaded object described by MAP so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+static inline int __attribute__ ((always_inline))
+elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
+{
+ if (map->l_info[DT_JMPREL])
+ {
+ Elf64_Word i;
+ Elf64_Word *glink = NULL;
+ Elf64_Xword *plt = (Elf64_Xword *) D_PTR (map, l_info[DT_PLTGOT]);
+ Elf64_Word num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
+ / sizeof (Elf64_Rela));
+ Elf64_Addr l_addr = map->l_addr;
+ Elf64_Dyn **info = map->l_info;
+ char *p;
+
+ extern void _dl_runtime_resolve (void);
+ extern void _dl_profile_resolve (void);
+
+ /* Relocate the DT_PPC64_GLINK entry in the _DYNAMIC section.
+ elf_get_dynamic_info takes care of the standard entries but
+ doesn't know exactly what to do with processor specific
+ entires. */
+ if (info[DT_PPC64(GLINK)] != NULL)
+ info[DT_PPC64(GLINK)]->d_un.d_ptr += l_addr;
+
+ if (lazy)
+ {
+ /* The function descriptor of the appropriate trampline
+ routine is used to set the 1st and 2nd doubleword of the
+ plt_reserve. */
+ Elf64_FuncDesc *resolve_fd;
+ Elf64_Word glink_offset;
+ /* the plt_reserve area is the 1st 3 doublewords of the PLT */
+ Elf64_FuncDesc *plt_reserve = (Elf64_FuncDesc *) plt;
+ Elf64_Word offset;
+
+ resolve_fd = (Elf64_FuncDesc *) (profile ? _dl_profile_resolve
+ : _dl_runtime_resolve);
+ if (profile && GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), map))
+ /* This is the object we are looking for. Say that we really
+ want profiling and the timers are started. */
+ GL(dl_profile_map) = map;
+
+
+ /* We need to stuff the address/TOC of _dl_runtime_resolve
+ into doublewords 0 and 1 of plt_reserve. Then we need to
+ stuff the map address into doubleword 2 of plt_reserve.
+ This allows the GLINK0 code to transfer control to the
+ correct trampoline which will transfer control to fixup
+ in dl-machine.c. */
+ plt_reserve->fd_func = resolve_fd->fd_func;
+ plt_reserve->fd_toc = resolve_fd->fd_toc;
+ plt_reserve->fd_aux = (Elf64_Addr) map;
+#ifdef RTLD_BOOTSTRAP
+ /* When we're bootstrapping, the opd entry will not have
+ been relocated yet. */
+ plt_reserve->fd_func += l_addr;
+ plt_reserve->fd_toc += l_addr;
+#endif
+
+ /* Set up the lazy PLT entries. */
+ glink = (Elf64_Word *) D_PTR (map, l_info[DT_PPC64(GLINK)]);
+ offset = PLT_INITIAL_ENTRY_WORDS;
+ glink_offset = GLINK_INITIAL_ENTRY_WORDS;
+ for (i = 0; i < num_plt_entries; i++)
+ {
+
+ plt[offset] = (Elf64_Xword) &glink[glink_offset];
+ offset += 3;
+ /* The first 32k entries of glink can set an index and
+ branch using two instructions; Past that point,
+ glink uses three instructions. */
+ if (i < 0x8000)
+ glink_offset += 2;
+ else
+ glink_offset += 3;
+ }
+
+ /* Now, we've modified data. We need to write the changes from
+ the data cache to a second-level unified cache, then make
+ sure that stale data in the instruction cache is removed.
+ (In a multiprocessor system, the effect is more complex.)
+ Most of the PLT shouldn't be in the instruction cache, but
+ there may be a little overlap at the start and the end.
+
+ Assumes that dcbst and icbi apply to lines of 16 bytes or
+ more. Current known line sizes are 16, 32, and 128 bytes. */
+
+ for (p = (char *) plt; p < (char *) &plt[offset]; p += 16)
+ PPC_DCBST (p);
+ PPC_SYNC;
+ }
+ }
+ return lazy;
+}
+
+/* Change the PLT entry whose reloc is 'reloc' to call the actual
+ routine. */
+static inline Elf64_Addr __attribute__ ((always_inline))
+elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map,
+ const Elf64_Rela *reloc,
+ Elf64_Addr *reloc_addr, Elf64_Addr finaladdr)
+{
+ Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr;
+ Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr;
+ Elf64_Addr offset = 0;
+
+ /* If sym_map is NULL, it's a weak undefined sym; Leave the plt zero. */
+ if (sym_map == NULL)
+ return 0;
+
+ /* If the opd entry is not yet relocated (because it's from a shared
+ object that hasn't been processed yet), then manually reloc it. */
+ if (map != sym_map && !sym_map->l_relocated
+#if !defined RTLD_BOOTSTRAP && defined SHARED
+ /* Bootstrap map doesn't have l_relocated set for it. */
+ && sym_map != &GL(dl_rtld_map)
+#endif
+ )
+ offset = sym_map->l_addr;
+
+ /* For PPC64, fixup_plt copies the function descriptor from opd
+ over the corresponding PLT entry.
+ Initially, PLT Entry[i] is set up for lazy linking, or is zero.
+ For lazy linking, the fd_toc and fd_aux entries are irrelevant,
+ so for thread safety we write them before changing fd_func. */
+
+ plt->fd_aux = rel->fd_aux + offset;
+ plt->fd_toc = rel->fd_toc + offset;
+ PPC_DCBST (&plt->fd_aux);
+ PPC_DCBST (&plt->fd_toc);
+ PPC_SYNC;
+
+ plt->fd_func = rel->fd_func + offset;
+ PPC_DCBST (&plt->fd_func);
+ PPC_SYNC;
+
+ return finaladdr;
+}
+
+static inline void __attribute__ ((always_inline))
+elf_machine_plt_conflict (Elf64_Addr *reloc_addr, Elf64_Addr finaladdr)
+{
+ Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr;
+ Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr;
+
+ plt->fd_func = rel->fd_func;
+ plt->fd_aux = rel->fd_aux;
+ plt->fd_toc = rel->fd_toc;
+ PPC_DCBST (&plt->fd_func);
+ PPC_DCBST (&plt->fd_aux);
+ PPC_DCBST (&plt->fd_toc);
+ PPC_SYNC;
+}
+
+/* Return the final value of a plt relocation. */
+static inline Elf64_Addr
+elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
+ Elf64_Addr value)
+{
+ return value + reloc->r_addend;
+}
+
+
+/* Names of the architecture-specific auditing callback functions. */
+#define ARCH_LA_PLTENTER ppc64_gnu_pltenter
+#define ARCH_LA_PLTEXIT ppc64_gnu_pltexit
+
+#endif /* dl_machine_h */
+
+#ifdef RESOLVE_MAP
+
+#define PPC_LO(v) ((v) & 0xffff)
+#define PPC_HI(v) (((v) >> 16) & 0xffff)
+#define PPC_HA(v) PPC_HI ((v) + 0x8000)
+#define PPC_HIGHER(v) (((v) >> 32) & 0xffff)
+#define PPC_HIGHERA(v) PPC_HIGHER ((v) + 0x8000)
+#define PPC_HIGHEST(v) (((v) >> 48) & 0xffff)
+#define PPC_HIGHESTA(v) PPC_HIGHEST ((v) + 0x8000)
+#define BIT_INSERT(var, val, mask) \
+ ((var) = ((var) & ~(Elf64_Addr) (mask)) | ((val) & (mask)))
+
+#define dont_expect(X) __builtin_expect ((X), 0)
+
+extern void _dl_reloc_overflow (struct link_map *map,
+ const char *name,
+ Elf64_Addr *const reloc_addr,
+ const Elf64_Sym *refsym)
+ attribute_hidden;
+
+auto inline void __attribute__ ((always_inline))
+elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+ *reloc_addr = l_addr + reloc->r_addend;
+}
+
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+/* This computes the value used by TPREL* relocs. */
+auto inline Elf64_Addr __attribute__ ((always_inline, const))
+elf_machine_tprel (struct link_map *map,
+ struct link_map *sym_map,
+ const Elf64_Sym *sym,
+ const Elf64_Rela *reloc)
+{
+# ifndef RTLD_BOOTSTRAP
+ if (sym_map)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+# endif
+ return TLS_TPREL_VALUE (sym_map, sym, reloc);
+# ifndef RTLD_BOOTSTRAP
+ }
+# endif
+ return 0;
+}
+#endif
+
+/* Perform the relocation specified by RELOC and SYM (which is fully
+ resolved). MAP is the object containing the reloc. */
+auto inline void __attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map,
+ const Elf64_Rela *reloc,
+ const Elf64_Sym *sym,
+ const struct r_found_version *version,
+ void *const reloc_addr_arg)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+ const int r_type = ELF64_R_TYPE (reloc->r_info);
+#ifndef RTLD_BOOTSTRAP
+ const Elf64_Sym *const refsym = sym;
+#endif
+
+ if (r_type == R_PPC64_RELATIVE)
+ {
+ *reloc_addr = map->l_addr + reloc->r_addend;
+ return;
+ }
+
+ if (__builtin_expect (r_type == R_PPC64_NONE, 0))
+ return;
+
+ /* We need SYM_MAP even in the absence of TLS, for elf_machine_fixup_plt. */
+ struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+ Elf64_Addr value = ((sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value)
+ + reloc->r_addend);
+
+ /* For relocs that don't edit code, return.
+ For relocs that might edit instructions, break from the switch. */
+ switch (r_type)
+ {
+ case R_PPC64_ADDR64:
+ case R_PPC64_GLOB_DAT:
+ *reloc_addr = value;
+ return;
+
+ case R_PPC64_JMP_SLOT:
+#ifdef RESOLVE_CONFLICT_FIND_MAP
+ elf_machine_plt_conflict (reloc_addr, value);
+#else
+ elf_machine_fixup_plt (map, sym_map, reloc, reloc_addr, value);
+#endif
+ return;
+
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+ case R_PPC64_DTPMOD64:
+# ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always index 1. */
+ *reloc_addr = 1;
+# else
+ /* Get the information from the link map returned by the
+ resolve function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+# endif
+ return;
+
+ case R_PPC64_DTPREL64:
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+# ifndef RTLD_BOOTSTRAP
+ if (sym_map != NULL)
+ *reloc_addr = TLS_DTPREL_VALUE (sym, reloc);
+# endif
+ return;
+
+ case R_PPC64_TPREL64:
+ *reloc_addr = elf_machine_tprel (map, sym_map, sym, reloc);
+ return;
+
+ case R_PPC64_TPREL16_LO_DS:
+ value = elf_machine_tprel (map, sym_map, sym, reloc);
+ if (dont_expect ((value & 3) != 0))
+ _dl_reloc_overflow (map, "R_PPC64_TPREL16_LO_DS", reloc_addr, refsym);
+ *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr,
+ value, 0xfffc);
+ break;
+
+ case R_PPC64_TPREL16_DS:
+ value = elf_machine_tprel (map, sym_map, sym, reloc);
+ if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
+ _dl_reloc_overflow (map, "R_PPC64_TPREL16_DS", reloc_addr, refsym);
+ *(Elf64_Half *) reloc_addr = BIT_INSERT (*(Elf64_Half *) reloc_addr,
+ value, 0xfffc);
+ break;
+
+ case R_PPC64_TPREL16:
+ value = elf_machine_tprel (map, sym_map, sym, reloc);
+ if (dont_expect ((value + 0x8000) >= 0x10000))
+ _dl_reloc_overflow (map, "R_PPC64_TPREL16", reloc_addr, refsym);
+ *(Elf64_Half *) reloc_addr = PPC_LO (value);
+ break;
+
+ case R_PPC64_TPREL16_LO:
+ value = elf_machine_tprel (map, sym_map, sym, reloc);
+ *(Elf64_Half *) reloc_addr = PPC_LO (value);
+ break;
+
+ case R_PPC64_TPREL16_HI:
+ value = elf_machine_tprel (map, sym_map, sym, reloc);
+ *(Elf64_Half *) reloc_addr = PPC_HI (value);
+ break;
+
+ case R_PPC64_TPREL16_HA:
+ value = elf_machine_tprel (map, sym_map, sym, reloc);
+ *(Elf64_Half *) reloc_addr = PPC_HA (value);
+ break;
+
+ case R_PPC64_TPREL16_HIGHER:
+ value = elf_machine_tprel (map, sym_map, sym, reloc);
+ *(Elf64_Half *) reloc_addr = PPC_HIGHER (value);
+ break;
+
+ case R_PPC64_TPREL16_HIGHEST:
+ value = elf_machine_tprel (map, sym_map, sym, reloc);
+ *(Elf64_Half *) reloc_addr = PPC_HIGHEST (value);
+ break;
+
+ case R_PPC64_TPREL16_HIGHERA:
+ value = elf_machine_tprel (map, sym_map, sym, reloc);
+ *(Elf64_Half *) reloc_addr = PPC_HIGHERA (value);
+ break;
+
+ case R_PPC64_TPREL16_HIGHESTA:
+ value = elf_machine_tprel (map, sym_map, sym, reloc);
+ *(Elf64_Half *) reloc_addr = PPC_HIGHESTA (value);
+ break;
+#endif /* USE_TLS etc. */
+
+#ifndef RTLD_BOOTSTRAP /* None of the following appear in ld.so */
+ case R_PPC64_ADDR16_LO_DS:
+ if (dont_expect ((value & 3) != 0))
+ _dl_reloc_overflow (map, "R_PPC64_ADDR16_LO_DS", reloc_addr, refsym);
+ BIT_INSERT (*(Elf64_Half *) reloc_addr, value, 0xfffc);
+ break;
+
+ case R_PPC64_ADDR16_LO:
+ *(Elf64_Half *) reloc_addr = PPC_LO (value);
+ break;
+
+ case R_PPC64_ADDR16_HI:
+ *(Elf64_Half *) reloc_addr = PPC_HI (value);
+ break;
+
+ case R_PPC64_ADDR16_HA:
+ *(Elf64_Half *) reloc_addr = PPC_HA (value);
+ break;
+
+ case R_PPC64_ADDR30:
+ {
+ Elf64_Addr delta = value - (Elf64_Xword) reloc_addr;
+ if (dont_expect ((delta + 0x80000000) >= 0x10000000
+ || (delta & 3) != 0))
+ _dl_reloc_overflow (map, "R_PPC64_ADDR30", reloc_addr, refsym);
+ BIT_INSERT (*(Elf64_Word *) reloc_addr, delta, 0xfffffffc);
+ }
+ break;
+
+ case R_PPC64_COPY:
+ if (dont_expect (sym == NULL))
+ /* This can happen in trace mode when an object could not be found. */
+ return;
+ if (dont_expect (sym->st_size > refsym->st_size
+ || (GLRO(dl_verbose)
+ && sym->st_size < refsym->st_size)))
+ {
+ const char *strtab;
+
+ strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+ _dl_error_printf ("%s: Symbol `%s' has different size" \
+ " in shared object," \
+ " consider re-linking\n",
+ _dl_argv[0] ?: "<program name unknown>",
+ strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr_arg, (char *) value,
+ MIN (sym->st_size, refsym->st_size));
+ return;
+
+ case R_PPC64_UADDR64:
+ /* We are big-endian. */
+ ((char *) reloc_addr_arg)[0] = (value >> 56) & 0xff;
+ ((char *) reloc_addr_arg)[1] = (value >> 48) & 0xff;
+ ((char *) reloc_addr_arg)[2] = (value >> 40) & 0xff;
+ ((char *) reloc_addr_arg)[3] = (value >> 32) & 0xff;
+ ((char *) reloc_addr_arg)[4] = (value >> 24) & 0xff;
+ ((char *) reloc_addr_arg)[5] = (value >> 16) & 0xff;
+ ((char *) reloc_addr_arg)[6] = (value >> 8) & 0xff;
+ ((char *) reloc_addr_arg)[7] = (value >> 0) & 0xff;
+ return;
+
+ case R_PPC64_UADDR32:
+ /* We are big-endian. */
+ ((char *) reloc_addr_arg)[0] = (value >> 24) & 0xff;
+ ((char *) reloc_addr_arg)[1] = (value >> 16) & 0xff;
+ ((char *) reloc_addr_arg)[2] = (value >> 8) & 0xff;
+ ((char *) reloc_addr_arg)[3] = (value >> 0) & 0xff;
+ return;
+
+ case R_PPC64_ADDR32:
+ if (dont_expect ((value + 0x80000000) >= 0x10000000))
+ _dl_reloc_overflow (map, "R_PPC64_ADDR32", reloc_addr, refsym);
+ *(Elf64_Word *) reloc_addr = value;
+ return;
+
+ case R_PPC64_ADDR24:
+ if (dont_expect ((value + 0x2000000) >= 0x4000000 || (value & 3) != 0))
+ _dl_reloc_overflow (map, "R_PPC64_ADDR24", reloc_addr, refsym);
+ BIT_INSERT (*(Elf64_Word *) reloc_addr, value, 0x3fffffc);
+ break;
+
+ case R_PPC64_ADDR16:
+ if (dont_expect ((value + 0x8000) >= 0x10000))
+ _dl_reloc_overflow (map, "R_PPC64_ADDR16", reloc_addr, refsym);
+ *(Elf64_Half *) reloc_addr = value;
+ break;
+
+ case R_PPC64_UADDR16:
+ if (dont_expect ((value + 0x8000) >= 0x10000))
+ _dl_reloc_overflow (map, "R_PPC64_UADDR16", reloc_addr, refsym);
+ /* We are big-endian. */
+ ((char *) reloc_addr_arg)[0] = (value >> 8) & 0xff;
+ ((char *) reloc_addr_arg)[1] = (value >> 0) & 0xff;
+ break;
+
+ case R_PPC64_ADDR16_DS:
+ if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
+ _dl_reloc_overflow (map, "R_PPC64_ADDR16_DS", reloc_addr, refsym);
+ BIT_INSERT (*(Elf64_Half *) reloc_addr, value, 0xfffc);
+ break;
+
+ case R_PPC64_ADDR16_HIGHER:
+ *(Elf64_Half *) reloc_addr = PPC_HIGHER (value);
+ break;
+
+ case R_PPC64_ADDR16_HIGHEST:
+ *(Elf64_Half *) reloc_addr = PPC_HIGHEST (value);
+ break;
+
+ case R_PPC64_ADDR16_HIGHERA:
+ *(Elf64_Half *) reloc_addr = PPC_HIGHERA (value);
+ break;
+
+ case R_PPC64_ADDR16_HIGHESTA:
+ *(Elf64_Half *) reloc_addr = PPC_HIGHESTA (value);
+ break;
+
+ case R_PPC64_ADDR14:
+ case R_PPC64_ADDR14_BRTAKEN:
+ case R_PPC64_ADDR14_BRNTAKEN:
+ {
+ if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
+ _dl_reloc_overflow (map, "R_PPC64_ADDR14", reloc_addr, refsym);
+ Elf64_Word insn = *(Elf64_Word *) reloc_addr;
+ BIT_INSERT (insn, value, 0xfffc);
+ if (r_type != R_PPC64_ADDR14)
+ {
+ insn &= ~(1 << 21);
+ if (r_type == R_PPC64_ADDR14_BRTAKEN)
+ insn |= 1 << 21;
+ if ((insn & (0x14 << 21)) == (0x04 << 21))
+ insn |= 0x02 << 21;
+ else if ((insn & (0x14 << 21)) == (0x10 << 21))
+ insn |= 0x08 << 21;
+ }
+ *(Elf64_Word *) reloc_addr = insn;
+ }
+ break;
+
+ case R_PPC64_REL32:
+ *(Elf64_Word *) reloc_addr = value - (Elf64_Addr) reloc_addr;
+ return;
+
+ case R_PPC64_REL64:
+ *reloc_addr = value - (Elf64_Addr) reloc_addr;
+ return;
+#endif /* !RTLD_BOOTSTRAP */
+
+ default:
+ _dl_reloc_bad_type (map, r_type, 0);
+ return;
+ }
+ MODIFIED_CODE_NOQUEUE (reloc_addr);
+}
+
+auto inline void __attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf64_Addr l_addr, const Elf64_Rela *reloc)
+{
+ /* elf_machine_runtime_setup handles this. */
+}
+
+
+#endif /* RESOLVE */
diff --git a/libc/sysdeps/powerpc/powerpc64/dl-trampoline.S b/libc/sysdeps/powerpc/powerpc64/dl-trampoline.S
new file mode 100644
index 000000000..9ca394dda
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/dl-trampoline.S
@@ -0,0 +1,442 @@
+/* PLT trampolines. PPC64 version.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+
+
+ .section ".text"
+/* On entry r0 contains the index of the PLT entry we need to fixup
+ and r11 contains the link_map (from PLT0+16). The link_map becomes
+ parm1 (r3) and the index (r0) need to be converted to an offset
+ (index * 24) in parm2 (r4). */
+
+EALIGN(_dl_runtime_resolve, 4, 0)
+/* We need to save the registers used to pass parameters, ie. r3 thru
+ r10; the registers are saved in a stack frame. */
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ std r3,48(r1)
+ mr r3,r11
+ std r4,56(r1)
+ sldi r4,r0,1
+ std r5,64(r1)
+ add r4,r4,r0
+ std r6,72(r1)
+ sldi r4,r4,3
+ std r7,80(r1)
+ mflr r0
+ std r8,88(r1)
+/* Store the LR in the LR Save area of the previous frame. */
+ std r0,128+16(r1)
+ cfi_offset (lr, 16)
+ mfcr r0
+ std r9,96(r1)
+ std r10,104(r1)
+/* I'm almost certain we don't have to save cr... be safe. */
+ std r0,8(r1)
+ bl JUMPTARGET(_dl_fixup)
+/* Put the registers back. */
+ ld r0,128+16(r1)
+ ld r10,104(r1)
+ ld r9,96(r1)
+ ld r8,88(r1)
+ ld r7,80(r1)
+ mtlr r0
+ ld r0,8(r1)
+ ld r6,72(r1)
+ ld r5,64(r1)
+ ld r4,56(r1)
+ mtcrf 0xFF,r0
+/* Load the target address, toc and static chain reg from the function
+ descriptor returned by fixup. */
+ ld r0,0(r3)
+ ld r2,8(r3)
+ mtctr r0
+ ld r11,16(r3)
+ ld r3,48(r1)
+/* Unwind the stack frame, and jump. */
+ addi r1,r1,128
+ bctr
+END(_dl_runtime_resolve)
+
+ /* Stack layout:
+ +592 previous backchain
+ +584 spill_r31
+ +576 spill_r30
+ +560 v1
+ +552 fp4
+ +544 fp3
+ +536 fp2
+ +528 fp1
+ +520 r4
+ +512 r3
+ return values
+ +504 free
+ +496 stackframe
+ +488 lr
+ +480 r1
+ +464 v13
+ +448 v12
+ +432 v11
+ +416 v10
+ +400 v9
+ +384 v8
+ +368 v7
+ +352 v6
+ +336 v5
+ +320 v4
+ +304 v3
+ +288 v2
+ * VMX Parms in V2-V13, V0-V1 are scratch
+ +284 vrsave
+ +280 free
+ +272 fp13
+ +264 fp12
+ +256 fp11
+ +248 fp10
+ +240 fp9
+ +232 fp8
+ +224 fp7
+ +216 fp6
+ +208 fp5
+ +200 fp4
+ +192 fp3
+ +184 fp2
+ +176 fp1
+ * FP Parms in FP1-FP13, FP0 is a scratch register
+ +168 r10
+ +160 r9
+ +152 r8
+ +144 r7
+ +136 r6
+ +128 r5
+ +120 r4
+ +112 r3
+ * Integer parms in R3-R10, R0 is scratch, R1 SP, R2 is TOC
+ +104 parm8
+ +96 parm7
+ +88 parm6
+ +80 parm5
+ +72 parm4
+ +64 parm3
+ +56 parm2
+ +48 parm1
+ * Parameter save area, Allocated by the call, at least 8 double words
+ +40 TOC save area
+ +32 Reserved for linker
+ +24 Reserved for compiler
+ +16 LR save area
+ +8 CR save area
+ r1+0 stack back chain
+ */
+#define FRAME_SIZE 592
+#define INT_RTN 512
+#define FPR_RTN 528
+#define VR_RTN 560
+#define STACK_FRAME 496
+#define CALLING_LR 488
+#define CALLING_SP 480
+#define INT_PARMS 112
+#define FPR_PARMS 176
+#define VR_PARMS 288
+#define VR_VRSAVE 284
+ .section ".toc","aw"
+.LC__dl_hwcap:
+# ifdef SHARED
+ .tc _rtld_global_ro[TC],_rtld_global_ro
+# else
+ .tc _dl_hwcap[TC],_dl_hwcap
+# endif
+ .section ".text"
+
+ .machine "altivec"
+/* On entry r0 contains the index of the PLT entry we need to fixup
+ and r11 contains the link_map (from PLT0+16). The link_map becomes
+ parm1 (r3) and the index (r0) needs to be converted to an offset
+ (index * 24) in parm2 (r4). */
+#ifndef PROF
+EALIGN(_dl_profile_resolve, 4, 0)
+/* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
+ need to call _dl_call_pltexit. */
+ std r31,-8(r1)
+ cfi_offset(r31,-8)
+ std r30,-16(r1)
+ cfi_offset(r30,-16)
+/* We need to save the registers used to pass parameters, ie. r3 thru
+ r10; the registers are saved in a stack frame. */
+ stdu r1,-FRAME_SIZE(r1)
+ cfi_adjust_cfa_offset (FRAME_SIZE)
+ std r3,INT_PARMS+0(r1)
+ mr r3,r11
+ std r4,INT_PARMS+8(r1)
+ sldi r4,r0,1 /* index * 2 */
+ std r5,INT_PARMS+16(r1)
+ add r4,r4,r0 /* index * 3 */
+ std r6,INT_PARMS+24(r1)
+ sldi r4,r4,3 /* index * 24 == PLT offset */
+ mflr r5
+ std r7,INT_PARMS+32(r1)
+ std r8,INT_PARMS+40(r1)
+/* Store the LR in the LR Save area of the previous frame. */
+/* XXX Do we have to do this? */
+ la r8,FRAME_SIZE(r1)
+ std r5,FRAME_SIZE+16(r1)
+ cfi_offset (lr, 16)
+ std r5,CALLING_LR(r1)
+ mfcr r0
+ std r9,INT_PARMS+48(r1)
+ std r10,INT_PARMS+56(r1)
+ std r8,CALLING_SP(r1)
+/* I'm almost certain we don't have to save cr... be safe. */
+ std r0,8(r1)
+ ld r12,.LC__dl_hwcap@toc(r2)
+#ifdef SHARED
+ /* Load _rtld-global._dl_hwcap. */
+ ld r12,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r12)
+#else
+ ld r12,0(r12) /* Load extern _dl_hwcap. */
+#endif
+ andis. r0,r12,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ beq L(saveFP)
+ la r10,(VR_PARMS+0)(r1)
+ la r9,(VR_PARMS+16)(r1)
+ li r11,32
+ li r12,64
+ stvx v2,0,r10
+ stvx v3,0,r9
+
+ stvx v4,r11,r10
+ stvx v5,r11,r9
+ addi r11,r11,64
+
+ stvx v6,r12,r10
+ stvx v7,r12,r9
+ addi r12,r12,64
+
+ stvx v8,r11,r10
+ stvx v9,r11,r9
+ addi r11,r11,64
+
+ stvx v10,r12,r10
+ stvx v11,r12,r9
+ mfspr r0,VRSAVE
+
+ stvx v12,r11,r10
+ stvx v13,r11,r9
+L(saveFP):
+ stw r0,VR_VRSAVE(r1)
+/* Save floating registers. */
+ stfd fp1,FPR_PARMS+0(r1)
+ stfd fp2,FPR_PARMS+8(r1)
+ stfd fp3,FPR_PARMS+16(r1)
+ stfd fp4,FPR_PARMS+24(r1)
+ stfd fp5,FPR_PARMS+32(r1)
+ stfd fp6,FPR_PARMS+40(r1)
+ stfd fp7,FPR_PARMS+48(r1)
+ stfd fp8,FPR_PARMS+56(r1)
+ stfd fp9,FPR_PARMS+64(r1)
+ stfd fp10,FPR_PARMS+72(r1)
+ stfd fp11,FPR_PARMS+80(r1)
+ li r0,-1
+ stfd fp12,FPR_PARMS+88(r1)
+ stfd fp13,FPR_PARMS+96(r1)
+/* Load the extra parameters. */
+ addi r6,r1,INT_PARMS
+ addi r7,r1,STACK_FRAME
+/* Save link_map* and reloc_addr parms for later. */
+ mr r31,r3
+ mr r30,r4
+ std r0,0(r7)
+ bl JUMPTARGET(_dl_profile_fixup)
+ nop
+/* Test *framesizep > 0 to see if need to do pltexit processing. */
+ ld r0,STACK_FRAME(r1)
+/* Put the registers back. */
+ lwz r12,VR_VRSAVE(r1)
+ cmpdi cr1,r0,0
+ cmpdi cr0,r12,0
+ bgt cr1,L(do_pltexit)
+ la r10,(VR_PARMS+0)(r1)
+ la r9,(VR_PARMS+16)(r1)
+/* VRSAVE must be non-zero if VMX is present and VRs are in use. */
+ beq L(restoreFXR)
+ li r11,32
+ li r12,64
+ lvx v2,0,r10
+ lvx v3,0,r9
+
+ lvx v4,r11,r10
+ lvx v5,r11,r9
+ addi r11,r11,64
+
+ lvx v6,r12,r10
+ lvx v7,r12,r9
+ addi r12,r12,64
+
+ lvx v8,r11,r10
+ lvx v9,r11,r9
+ addi r11,r11,64
+
+ lvx v10,r12,r10
+ lvx v11,r12,r9
+
+ lvx v12,r11,r10
+ lvx v13,r11,r9
+L(restoreFXR):
+ ld r0,FRAME_SIZE+16(r1)
+ ld r10,INT_PARMS+56(r1)
+ ld r9,INT_PARMS+48(r1)
+ ld r8,INT_PARMS+40(r1)
+ ld r7,INT_PARMS+32(r1)
+ mtlr r0
+ ld r0,8(r1)
+ ld r6,INT_PARMS+24(r1)
+ ld r5,INT_PARMS+16(r1)
+ ld r4,INT_PARMS+8(r1)
+ mtcrf 0xFF,r0
+/* Load the target address, toc and static chain reg from the function
+ descriptor returned by fixup. */
+ ld r0,0(r3)
+ ld r2,8(r3)
+ ld r11,16(r3)
+ ld r3,INT_PARMS+0(r1)
+ mtctr r0
+/* Load the floating point registers. */
+ lfd fp1,FPR_PARMS+0(r1)
+ lfd fp2,FPR_PARMS+8(r1)
+ lfd fp3,FPR_PARMS+16(r1)
+ lfd fp4,FPR_PARMS+24(r1)
+ lfd fp5,FPR_PARMS+32(r1)
+ lfd fp6,FPR_PARMS+40(r1)
+ lfd fp7,FPR_PARMS+48(r1)
+ lfd fp8,FPR_PARMS+56(r1)
+ lfd fp9,FPR_PARMS+64(r1)
+ lfd fp10,FPR_PARMS+72(r1)
+ lfd fp11,FPR_PARMS+80(r1)
+ lfd fp12,FPR_PARMS+88(r1)
+ lfd fp13,FPR_PARMS+96(r1)
+/* Unwind the stack frame, and jump. */
+ ld r31,584(r1)
+ ld r30,576(r1)
+ addi r1,r1,FRAME_SIZE
+ bctr
+L(do_pltexit):
+ la r10,(VR_PARMS+0)(r1)
+ la r9,(VR_PARMS+16)(r1)
+ beq L(restoreFXR2)
+ li r11,32
+ li r12,64
+ lvx v2,0,r10
+ lvx v3,0,r9
+
+ lvx v4,r11,r10
+ lvx v5,r11,r9
+ addi r11,r11,64
+
+ lvx v6,r12,r10
+ lvx v7,r12,r9
+ addi r12,r12,64
+
+ lvx v8,r11,r10
+ lvx v9,r11,r9
+ addi r11,r11,64
+
+ lvx v10,r12,r10
+ lvx v11,r12,r9
+
+ lvx v12,r11,r10
+ lvx v13,r11,r9
+L(restoreFXR2):
+ ld r0,FRAME_SIZE+16(r1)
+ ld r10,INT_PARMS+56(r1)
+ ld r9,INT_PARMS+48(r1)
+ ld r8,INT_PARMS+40(r1)
+ ld r7,INT_PARMS+32(r1)
+ mtlr r0
+ ld r0,8(r1)
+ ld r6,INT_PARMS+24(r1)
+ ld r5,INT_PARMS+16(r1)
+ ld r4,INT_PARMS+8(r1)
+ mtcrf 0xFF,r0
+/* Load the target address, toc and static chain reg from the function
+ descriptor returned by fixup. */
+ ld r0,0(r3)
+ std r2,40(r1)
+ ld r2,8(r3)
+ ld r11,16(r3)
+ ld r3,INT_PARMS+0(r1)
+ mtctr r0
+/* Load the floating point registers. */
+ lfd fp1,FPR_PARMS+0(r1)
+ lfd fp2,FPR_PARMS+8(r1)
+ lfd fp3,FPR_PARMS+16(r1)
+ lfd fp4,FPR_PARMS+24(r1)
+ lfd fp5,FPR_PARMS+32(r1)
+ lfd fp6,FPR_PARMS+40(r1)
+ lfd fp7,FPR_PARMS+48(r1)
+ lfd fp8,FPR_PARMS+56(r1)
+ lfd fp9,FPR_PARMS+64(r1)
+ lfd fp10,FPR_PARMS+72(r1)
+ lfd fp11,FPR_PARMS+80(r1)
+ lfd fp12,FPR_PARMS+88(r1)
+ lfd fp13,FPR_PARMS+96(r1)
+/* Call the target function. */
+ bctrl
+ ld r2,40(r1)
+ lwz r12,VR_VRSAVE(r1)
+/* But return here and store the return values. */
+ std r3,INT_RTN(r1)
+ std r4,INT_RTN+8(r1)
+ stfd fp1,FPR_PARMS+0(r1)
+ stfd fp2,FPR_PARMS+8(r1)
+ cmpdi cr0,r12,0
+ la r10,VR_RTN(r1)
+ stfd fp3,FPR_PARMS+16(r1)
+ stfd fp4,FPR_PARMS+24(r1)
+ mr r3,r31
+ mr r4,r30
+ beq L(callpltexit)
+ stvx v2,0,r10
+L(callpltexit):
+ addi r5,r1,INT_PARMS
+ addi r6,r1,INT_RTN
+ bl JUMPTARGET(_dl_call_pltexit)
+ nop
+/* Restore the return values from target function. */
+ lwz r12,VR_VRSAVE(r1)
+ ld r3,INT_RTN(r1)
+ ld r4,INT_RTN+8(r1)
+ lfd fp1,FPR_PARMS+0(r1)
+ lfd fp2,FPR_PARMS+8(r1)
+ cmpdi cr0,r12,0
+ la r10,VR_RTN(r1)
+ lfd fp3,FPR_PARMS+16(r1)
+ lfd fp4,FPR_PARMS+24(r1)
+ beq L(pltexitreturn)
+ lvx v2,0,r10
+L(pltexitreturn):
+ ld r0,FRAME_SIZE+16(r1)
+ ld r31,584(r1)
+ ld r30,576(r1)
+ mtlr r0
+ ld r1,0(r1)
+ blr
+END(_dl_profile_resolve)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/elf/Makefile b/libc/sysdeps/powerpc/powerpc64/elf/Makefile
new file mode 100644
index 000000000..6a77e116b
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/elf/Makefile
@@ -0,0 +1,11 @@
+# powerpc64/ELF specific definitions.
+
+# Need to prevent gcc from using fprs in code used during dynamic linking.
+
+CFLAGS-dl-runtime.os = $(no-special-regs)
+CFLAGS-dl-lookup.os = $(no-special-regs)
+CFLAGS-dl-misc.os = $(no-special-regs)
+CFLAGS-rtld-mempcpy.os = $(no-special-regs)
+CFLAGS-rtld-memmove.os = $(no-special-regs)
+CFLAGS-rtld-memchr.os = $(no-special-regs)
+CFLAGS-rtld-strnlen.os = $(no-special-regs)
diff --git a/libc/sysdeps/powerpc/powerpc64/elf/bzero.S b/libc/sysdeps/powerpc/powerpc64/elf/bzero.S
new file mode 100644
index 000000000..f899bd234
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/elf/bzero.S
@@ -0,0 +1,21 @@
+/* Optimized bzero `implementation' for PowerPC64.
+ Copyright (C) 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This code was moved into memset.S to solve a double stub call problem.
+ @local would have worked but it is not supported in PowerPC64 asm. */
diff --git a/libc/sysdeps/powerpc/powerpc64/elf/configure b/libc/sysdeps/powerpc/powerpc64/elf/configure
new file mode 100644
index 000000000..ab79a5ab4
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/elf/configure
@@ -0,0 +1,72 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/powerpc64/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+echo "$as_me:$LINENO: checking for powerpc64 TLS support" >&5
+echo $ECHO_N "checking for powerpc64 TLS support... $ECHO_C" >&6
+if test "${libc_cv_powerpc64_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<\EOF
+ .section ".tdata","awT",@progbits
+x: .quad 1
+x1: .quad 1
+x2: .quad 1
+x3: .quad 1
+x4: .long 1
+ .section ".toc","aw"
+.LC0:
+ .quad x@dtpmod
+ .quad x@dtprel
+.LC1:
+ .quad x1@dtpmod
+ .quad 0
+.LC2:
+ .quad x@tprel
+ .text
+ addi 3,2,x@got@tlsgd
+ addi 3,2,.LC0@toc
+ addi 3,2,x1@got@tlsld
+ addi 9,3,x1@dtprel
+ addis 9,3,x2@dtprel@ha
+ addi 9,9,x2@dtprel@l
+ ld 9,x3@got@dtprel(2)
+ addi 3,2,.LC0@toc
+ lwz 0,x1@dtprel(3)
+ ld 0,x1@dtprel(3)
+ addis 9,3,x2@dtprel@ha
+ lwz 0,x2@dtprel@l(9)
+ ld 0,x2@dtprel@l(9)
+ ld 9,x3@got@dtprel(2)
+ ld 9,x@got@tprel(2)
+ add 9,9,x@tls
+ ld 9,.LC2@toc(2)
+ add 9,9,.LC2@tls
+ addi 9,13,x1@tprel
+ addis 9,13,x2@tprel@ha
+ addi 9,9,x2@tprel@l
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_powerpc64_tls=yes
+else
+ libc_cv_powerpc64_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_powerpc64_tls" >&5
+echo "${ECHO_T}$libc_cv_powerpc64_tls" >&6
+if test $libc_cv_powerpc64_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
diff --git a/libc/sysdeps/powerpc/powerpc64/elf/configure.in b/libc/sysdeps/powerpc/powerpc64/elf/configure.in
new file mode 100644
index 000000000..5466367cf
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/elf/configure.in
@@ -0,0 +1,58 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/powerpc64/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for powerpc64 TLS support, libc_cv_powerpc64_tls, [dnl
+cat > conftest.s <<\EOF
+ .section ".tdata","awT",@progbits
+x: .quad 1
+x1: .quad 1
+x2: .quad 1
+x3: .quad 1
+x4: .long 1
+ .section ".toc","aw"
+.LC0:
+ .quad x@dtpmod
+ .quad x@dtprel
+.LC1:
+ .quad x1@dtpmod
+ .quad 0
+.LC2:
+ .quad x@tprel
+ .text
+ addi 3,2,x@got@tlsgd
+ addi 3,2,.LC0@toc
+ addi 3,2,x1@got@tlsld
+ addi 9,3,x1@dtprel
+ addis 9,3,x2@dtprel@ha
+ addi 9,9,x2@dtprel@l
+ ld 9,x3@got@dtprel(2)
+ addi 3,2,.LC0@toc
+ lwz 0,x1@dtprel(3)
+ ld 0,x1@dtprel(3)
+ addis 9,3,x2@dtprel@ha
+ lwz 0,x2@dtprel@l(9)
+ ld 0,x2@dtprel@l(9)
+ ld 9,x3@got@dtprel(2)
+ ld 9,x@got@tprel(2)
+ add 9,9,x@tls
+ ld 9,.LC2@toc(2)
+ add 9,9,.LC2@tls
+ addi 9,13,x1@tprel
+ addis 9,13,x2@tprel@ha
+ addi 9,9,x2@tprel@l
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_powerpc64_tls=yes
+else
+ libc_cv_powerpc64_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_powerpc64_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
diff --git a/libc/sysdeps/powerpc/powerpc64/elf/entry.h b/libc/sysdeps/powerpc/powerpc64/elf/entry.h
new file mode 100644
index 000000000..f9a7669fc
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/elf/entry.h
@@ -0,0 +1,34 @@
+/* Finding the entry point and start of text. PowerPC64 version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#ifndef __ASSEMBLY__
+extern void _start (void);
+#endif
+
+#define ENTRY_POINT _start
+
+/* We have to provide a special declaration. */
+#define ENTRY_POINT_DECL(class) class void _start (void);
+
+/* Use the address of ._start as the lowest address for which we need
+ to keep profiling records. We can't copy the ia64 scheme as our
+ entry poiny address is really the address of the function
+ descriptor, not the actual function entry. */
+#define TEXT_START (((long int *) ENTRY_POINT)[0])
diff --git a/libc/sysdeps/powerpc/powerpc64/elf/start.S b/libc/sysdeps/powerpc/powerpc64/elf/start.S
new file mode 100644
index 000000000..c9119a262
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/elf/start.S
@@ -0,0 +1,86 @@
+/* Startup code for programs linked with GNU libc. PowerPC64 version.
+ Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "bp-sym.h"
+
+ /* These are the various addresses we require. */
+#ifdef PIC
+ .section ".data.rel.ro.local","aw"
+#else
+ .section ".rodata"
+#endif
+ .align 3
+L(start_addresses):
+ .quad 0 /* was _SDA_BASE_ but not in 64-bit ABI*/
+/* function descriptors so don't need JUMPTARGET */
+ .quad BP_SYM(main)
+ .quad __libc_csu_init
+ .quad __libc_csu_fini
+
+ ASM_SIZE_DIRECTIVE(L(start_addresses))
+
+ .section ".toc","aw"
+.L01:
+ .tc L(start_addresses)[TC],L(start_addresses)
+ .section ".text"
+ENTRY(_start)
+ /* Save the stack pointer, in case we're statically linked under Linux. */
+ mr r9,r1
+ /* Set up an initial stack frame, and clear the LR. */
+ clrrdi r1,r1,4
+ li r0,0
+ stdu r1,-128(r1)
+ mtlr r0
+ std r0,0(r1)
+
+ /* put the address of start_addresses in r8... **
+** PPC64 ABI uses R13 for thread local, so we leave it alone */
+ ld r8,.L01(r2)
+
+ /* and continue in libc-start, in glibc. */
+ b JUMPTARGET(BP_SYM(__libc_start_main))
+/* The linker needs this nop to recognize that it's OK to call via a
+ TOC adjusting stub. */
+ nop
+
+END(_start)
+
+/* Define a symbol for the first piece of initialized data. */
+ .section ".data"
+ .globl __data_start
+__data_start:
+weak_alias (__data_start, data_start)
diff --git a/libc/sysdeps/powerpc/powerpc64/ffsll.c b/libc/sysdeps/powerpc/powerpc64/ffsll.c
new file mode 100644
index 000000000..3a0018955
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/ffsll.c
@@ -0,0 +1,38 @@
+/* Find first set bit in a word, counted from least significant end.
+ For PowerPC.
+ Copyright (C) 1991, 1992, 1997, 1998, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define ffsl __something_else
+#include <limits.h>
+#include <string.h>
+
+#undef ffs
+
+int
+__ffsll (long long int x)
+{
+ int cnt;
+
+ asm ("cntlzd %0,%1" : "=r" (cnt) : "r" (x & -x));
+ return 64 - cnt;
+}
+weak_alias (__ffsll, ffsll)
+#undef ffsl
+weak_alias (__ffsll, ffsl)
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c b/libc/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c
new file mode 100644
index 000000000..0a229cbe2
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c
@@ -0,0 +1,29 @@
+/* Double-precision floating point square root.
+ Copyright (C) 1997, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_private.h>
+
+double
+__ieee754_sqrt (double x)
+{
+ double z;
+ __asm __volatile ("fsqrt %0,%1" : "=f" (z) : "f" (x));
+ return z;
+}
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c b/libc/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c
new file mode 100644
index 000000000..0f17a64a8
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c
@@ -0,0 +1,29 @@
+/* Single-precision floating point square root.
+ Copyright (C) 1997, 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+#include <math_private.h>
+
+float
+__ieee754_sqrtf (float x)
+{
+ double z;
+ __asm ("fsqrts %0,%1" : "=f" (z) : "f" (x));
+ return z;
+}
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_ceil.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_ceil.S
new file mode 100644
index 000000000..02b70940e
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_ceil.S
@@ -0,0 +1,64 @@
+/* ceil function. PowerPC64 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**52 */
+ .tc FD_43300000_0[TC],0x4330000000000000
+ .section ".text"
+
+EALIGN (__ceil, 4, 0)
+ CALL_MCOUNT 0
+ mffs fp11 /* Save current FPU rounding mode. */
+ lfd fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,2 /* Set rounding mode toward +inf. */
+ ble- cr6,.L4
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__ceil)
+
+weak_alias (__ceil, ceil)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__ceil, ceill)
+strong_alias (__ceil, __ceill)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __ceil, ceill, GLIBC_2_0)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S
new file mode 100644
index 000000000..1ccd133b6
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S
@@ -0,0 +1,56 @@
+/* float ceil function. PowerPC64 version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**23 */
+ .tc FD_4b000000_0[TC],0x4b00000000000000
+ .section ".text"
+
+EALIGN (__ceilf, 4, 0)
+ CALL_MCOUNT 0
+ mffs fp11 /* Save current FPU rounding mode. */
+ lfs fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fsubs fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,2 /* Set rounding mode toward +inf. */
+ ble- cr6,.L4
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__ceilf)
+
+weak_alias (__ceilf, ceilf)
+
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_ceill.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_ceill.S
new file mode 100644
index 000000000..a8f8a0afc
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_ceill.S
@@ -0,0 +1,133 @@
+/* s_ceill.S IBM extended format long double version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**52 */
+ .tc FD_43300000_0[TC],0x4330000000000000
+
+ .section ".text"
+
+/* long double [fp1,fp2] ceill (long double x [fp1,fp2])
+ IEEE 1003.1 ceil function.
+
+ PowerPC64 long double uses the IBM extended format which is
+ represented two 64-floating point double values. The values are
+ non-overlapping giving an effective precision of 106 bits. The first
+ double contains the high order bits of mantisa and is always ceiled
+ to represent a normal ceiling of long double to double. Since the
+ long double value is sum of the high and low values, the low double
+ normally has the opposite sign to compensate for the this ceiling.
+
+ For long double there are two cases:
+ 1) |x| < 2**52, all the integer bits are in the high double.
+ ceil the high double and set the low double to -0.0.
+ 2) |x| >= 2**52, ceiling involves both doubles.
+ See the comment before lable .L2 for details.
+ */
+
+ENTRY (__ceill)
+ mffs fp11 /* Save current FPU rounding mode. */
+ lfd fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fabs fp9,fp2
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnl- cr7,.L2
+ mtfsfi 7,2 /* Set rounding mode toward +inf. */
+ fneg fp2,fp12
+ ble- cr6,.L1
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+.L0:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr /* x = 0.0; */
+.L1:
+ bge- cr6,.L0 /* if (x < 0.0) */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fcmpu cr5,fp1,fp12 /* if (x > 0.0) */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ blr /* x = -0.0; */
+
+/* The high double is > TWO52 so we need to round the low double and
+ perhaps the high double. In this case we have to round the low
+ double and handle any adjustment to the high double that may be
+ caused by rounding (up). This is complicated by the fact that the
+ high double may already be rounded and the low double may have the
+ opposite sign to compensate.This gets a bit tricky so we use the
+ following algorithm:
+
+ tau = floor(x_high/TWO52);
+ x0 = x_high - tau;
+ x1 = x_low + tau;
+ r1 = rint(x1);
+ y_high = x0 + r1;
+ y_low = x0 - y_high + r1;
+ return y; */
+.L2:
+ fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */
+ fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */
+ fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */
+ bgelr- cr7 /* return x; */
+ beqlr- cr0
+ mtfsfi 7,2 /* Set rounding mode toward +inf. */
+ fdiv fp8,fp1,fp13 /* x_high/TWO52 */
+
+ bng- cr6,.L6 /* if (x > 0.0) */
+ fctidz fp0,fp8
+ fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
+ bng cr5,.L4 /* if (x_low > 0.0) */
+ fmr fp3,fp1
+ fmr fp4,fp2
+ b .L5
+.L4: /* if (x_low < 0.0) */
+ fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
+ fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
+.L5:
+ fadd fp5,fp4,fp13 /* r1 = r1 + TWO52; */
+ fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */
+ b .L9
+.L6: /* if (x < 0.0) */
+ fctidz fp0,fp8
+ fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
+ bnl cr5,.L7 /* if (x_low < 0.0) */
+ fmr fp3,fp1
+ fmr fp4,fp2
+ b .L8
+.L7: /* if (x_low > 0.0) */
+ fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
+ fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
+.L8:
+ fsub fp5,fp4,fp13 /* r1-= TWO52; */
+ fadd fp5,fp5,fp13 /* r1+= TWO52; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ fadd fp1,fp3,fp5 /* y_high = x0 + r1; */
+ fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */
+ fadd fp2,fp2,fp5
+ blr
+END (__ceill)
+
+long_double_symbol (libm, __ceill, ceill)
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_copysign.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
new file mode 100644
index 000000000..38171e31d
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
@@ -0,0 +1,63 @@
+/* Copy a sign bit between floating-point values. PowerPC64 version.
+ Copyright (C) 1997, 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This has been coded in assembler because GCC makes such a mess of it
+ when it's coded in C. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ENTRY(__copysign)
+ CALL_MCOUNT 0
+/* double [f1] copysign (double [f1] x, double [f2] y);
+ copysign(x,y) returns a value with the magnitude of x and
+ with the sign bit of y. */
+ stdu r1,-48(r1)
+ cfi_adjust_cfa_offset (48)
+ stfd fp2,24(r1)
+ nop
+ nop
+ nop
+ ld r3,24(r1)
+ cmpdi r3,0
+ addi r1,r1,48
+ blt L(0)
+ fabs fp1,fp1
+ blr
+L(0): fnabs fp1,fp1
+ blr
+ END (__copysign)
+
+weak_alias (__copysign,copysign)
+
+/* It turns out that it's safe to use this code even for single-precision. */
+weak_alias (__copysign,copysignf)
+strong_alias(__copysign,__copysignf)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__copysign,copysignl)
+strong_alias(__copysign,__copysignl)
+#endif
+#ifdef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __copysign, copysignl, GLIBC_2_0)
+# endif
+#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __copysign, copysignl, GLIBC_2_0)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_copysignf.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_copysignf.S
new file mode 100644
index 000000000..e05438ae7
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_copysignf.S
@@ -0,0 +1 @@
+/* __copysignf is in s_copysign.S */
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_copysignl.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_copysignl.S
new file mode 100644
index 000000000..b2c62eacb
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_copysignl.S
@@ -0,0 +1,51 @@
+/* Copy a sign bit between floating-point values.
+ IBM extended format long double version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ENTRY(__copysignl)
+/* long double [f1,f2] copysign (long double [f1,f2] x, long double [f3,f4] y);
+ copysign(x,y) returns a value with the magnitude of x and
+ with the sign bit of y. */
+ stfd fp3,-16(r1)
+ ld r3,-16(r1)
+ cmpdi r3,0
+ blt L(0)
+ fmr fp0,fp1
+ fabs fp1,fp1
+ fcmpu cr1,fp0,fp1
+ beqlr cr1
+ fneg fp2,fp2
+ blr
+L(0):
+ fmr fp0,fp1
+ fnabs fp1,fp1
+ fcmpu cr1,fp0,fp1
+ beqlr cr1
+ fneg fp2,fp2
+ blr
+END (__copysignl)
+
+#ifdef IS_IN_libm
+long_double_symbol (libm, __copysignl, copysignl)
+#else
+long_double_symbol (libc, __copysignl, copysignl)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_fabs.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_fabs.S
new file mode 100644
index 000000000..53d21301e
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_fabs.S
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/powerpc/fpu/s_fabs.S>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __fabs, fabsl, GLIBC_2_0)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_fabsl.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_fabsl.S
new file mode 100644
index 000000000..3655e5b2f
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_fabsl.S
@@ -0,0 +1,36 @@
+/* Copy a sign bit between floating-point values.
+ IBM extended format long double version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ENTRY(__fabsl)
+/* long double [f1,f2] fabs (long double [f1,f2] x);
+ fabs(x,y) returns a value with the magnitude of x and
+ with the sign bit of y. */
+ fmr fp0,fp1
+ fabs fp1,fp1
+ fcmpu cr1,fp0,fp1
+ beqlr cr1
+ fneg fp2,fp2
+ blr
+END (__fabsl)
+
+long_double_symbol (libm, __fabsl, fabsl)
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_fdim.c b/libc/sysdeps/powerpc/powerpc64/fpu/s_fdim.c
new file mode 100644
index 000000000..e34b51ee5
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_fdim.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/powerpc/fpu/s_fdim.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fdim, fdiml, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_floor.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_floor.S
new file mode 100644
index 000000000..65a2848b6
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_floor.S
@@ -0,0 +1,64 @@
+/* Floor function. PowerPC64 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**52 */
+ .tc FD_43300000_0[TC],0x4330000000000000
+ .section ".text"
+
+EALIGN (__floor, 4, 0)
+ CALL_MCOUNT 0
+ mffs fp11 /* Save current FPU rounding mode. */
+ lfd fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,3 /* Set rounding mode toward -inf. */
+ ble- cr6,.L4
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__floor)
+
+weak_alias (__floor, floor)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__floor, floorl)
+strong_alias (__floor, __floorl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __floor, floorl, GLIBC_2_0)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_floorf.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_floorf.S
new file mode 100644
index 000000000..bcdbf7823
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_floorf.S
@@ -0,0 +1,56 @@
+/* float Floor function. PowerPC64 version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**23 */
+ .tc FD_4b000000_0[TC],0x4b00000000000000
+ .section ".text"
+
+EALIGN (__floorf, 4, 0)
+ CALL_MCOUNT 0
+ mffs fp11 /* Save current FPU rounding mode. */
+ lfs fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fsubs fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,3 /* Set rounding mode toward -inf. */
+ ble- cr6,.L4
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__floorf)
+
+weak_alias (__floorf, floorf)
+
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_floorl.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_floorl.S
new file mode 100644
index 000000000..01b3c2101
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_floorl.S
@@ -0,0 +1,134 @@
+/* long double floor function.
+ IBM extended format long double version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**52 */
+ .tc FD_43300000_0[TC],0x4330000000000000
+
+ .section ".text"
+/* long double [fp1,fp2] floorl (long double x [fp1,fp2])
+ IEEE 1003.1 floor function.
+
+ PowerPC64 long double uses the IBM extended format which is
+ represented two 64-floating point double values. The values are
+ non-overlapping giving an effective precision of 106 bits. The first
+ double contains the high order bits of mantisa and is always rounded
+ to represent a normal rounding of long double to double. Since the
+ long double value is sum of the high and low values, the low double
+ normally has the opposite sign to compensate for the this rounding.
+
+ For long double there are two cases:
+ 1) |x| < 2**52, all the integer bits are in the high double.
+ floor the high double and set the low double to -0.0.
+ 2) |x| >= 2**52, Rounding involves both doubles.
+ See the comment before lable .L2 for details.
+ */
+
+ENTRY (__floorl)
+ mffs fp11 /* Save current FPU rounding mode. */
+ lfd fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fabs fp9,fp2
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnl- cr7,.L2
+ mtfsfi 7,3 /* Set rounding mode toward -inf. */
+ fneg fp2,fp12 /* set low double to -0.0. */
+ ble- cr6,.L0
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fcmpu cr5,fp1,fp12 /* if (x > 0.0) */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ bnelr+ cr5
+ fmr fp1,fp12 /* x must be +0.0 for the 0.0 case. */
+ blr
+.L0:
+ bge- cr6,.L1 /* if (x < 0.0) */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+.L1:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+
+
+/* The high double is > TWO52 so we need to round the low double and
+ perhaps the high double. In this case we have to round the low
+ double and handle any adjustment to the high double that may be
+ caused by rounding (up). This is complicated by the fact that the
+ high double may already be rounded and the low double may have the
+ opposite sign to compensate.This gets a bit tricky so we use the
+ following algorithm:
+
+ tau = floor(x_high/TWO52);
+ x0 = x_high - tau;
+ x1 = x_low + tau;
+ r1 = rint(x1);
+ y_high = x0 + r1;
+ y_low = x0 - y_high + r1;
+ return y; */
+.L2:
+ fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */
+ fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */
+ fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */
+ bgelr- cr7 /* return x; */
+ beqlr- cr0
+ mtfsfi 7,3 /* Set rounding mode toward -inf. */
+ fdiv fp8,fp1,fp13 /* x_high/TWO52 */
+
+ bng- cr6,.L6 /* if (x > 0.0) */
+ fctidz fp0,fp8
+ fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
+ bng cr5,.L4 /* if (x_low > 0.0) */
+ fmr fp3,fp1
+ fmr fp4,fp2
+ b .L5
+.L4: /* if (x_low < 0.0) */
+ fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
+ fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
+.L5:
+ fadd fp5,fp4,fp13 /* r1 = r1 + TWO52; */
+ fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */
+ b .L9
+.L6: /* if (x < 0.0) */
+ fctidz fp0,fp8
+ fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
+ bnl cr5,.L7 /* if (x_low < 0.0) */
+ fmr fp3,fp1
+ fmr fp4,fp2
+ b .L8
+.L7: /* if (x_low > 0.0) */
+ fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
+ fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
+.L8:
+ fsub fp5,fp4,fp13 /* r1-= TWO52; */
+ fadd fp5,fp5,fp13 /* r1+= TWO52; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ fadd fp1,fp3,fp5 /* y_high = x0 + r1; */
+ fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */
+ fadd fp2,fp2,fp5
+ blr
+END (__floorl)
+
+long_double_symbol (libm, __floorl, floorl)
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_fmax.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_fmax.S
new file mode 100644
index 000000000..69735761a
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_fmax.S
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/powerpc/fpu/s_fmax.S>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fmax, fmaxl, GLIBC_2_1)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_fmin.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_fmin.S
new file mode 100644
index 000000000..6d4a0a946
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_fmin.S
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/powerpc/fpu/s_fmin.S>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fmin, fminl, GLIBC_2_1)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_isnan.c b/libc/sysdeps/powerpc/powerpc64/fpu/s_isnan.c
new file mode 100644
index 000000000..397717ba9
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_isnan.c
@@ -0,0 +1,7 @@
+#include <sysdeps/powerpc/fpu/s_isnan.c>
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
+compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
+# endif
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_llrint.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_llrint.S
new file mode 100644
index 000000000..ff0ba948a
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_llrint.S
@@ -0,0 +1,48 @@
+/* Round double to long int. PowerPC64 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* long long int[r3] __llrint (double x[fp1]) */
+ENTRY (__llrint)
+ CALL_MCOUNT 0
+ fctid fp13,fp1
+ stfd fp13,-16(r1)
+ nop /* Insure the following load is in a different dispatch group */
+ nop /* to avoid pipe stall on POWER4&5. */
+ nop
+ ld r3,-16(r1)
+ blr
+ END (__llrint)
+
+strong_alias (__llrint, __lrint)
+weak_alias (__llrint, llrint)
+weak_alias (__lrint, lrint)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__llrint, __llrintl)
+weak_alias (__llrint, llrintl)
+strong_alias (__lrint, __lrintl)
+weak_alias (__lrint, lrintl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __llrint, llrintl, GLIBC_2_1)
+compat_symbol (libm, __lrint, lrintl, GLIBC_2_1)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_llrintf.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_llrintf.S
new file mode 100644
index 000000000..b7b2a8fc6
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_llrintf.S
@@ -0,0 +1,37 @@
+/* Round double to long int. PowerPC64 version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* long long int[r3] __llrintf (float x[fp1]) */
+ENTRY (__llrintf)
+ CALL_MCOUNT 0
+ fctid fp13,fp1
+ stfd fp13,-16(r1)
+ nop /* Insure the following load is in a different dispatch group */
+ nop /* to avoid pipe stall on POWER4&5. */
+ nop
+ ld r3,-16(r1)
+ blr
+ END (__llrintf)
+
+strong_alias (__llrintf, __lrintf)
+weak_alias (__llrintf, llrintf)
+weak_alias (__lrintf, lrintf)
+
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_llround.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_llround.S
new file mode 100644
index 000000000..d023b8f2c
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_llround.S
@@ -0,0 +1,73 @@
+/* llround function. PowerPC64 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC0: /* -0.0 */
+ .tc FD_00000000_0[TC],0x0000000000000000
+.LC1: /* 0.5 */
+ .tc FD_3fe00000_0[TC],0x3fe0000000000000
+ .section ".text"
+
+/* long long [r3] llround (float x [fp1])
+ IEEE 1003.1 llround function. IEEE specifies "round to the nearest
+ integer value, rounding halfway cases away from zero, regardless of
+ the current rounding mode." However PowerPC Architecture defines
+ "round to Nearest" as "Choose the best approximation. In case of a
+ tie, choose the one that is even (least significant bit o).".
+ So we can't use the PowerPC "round to Nearest" mode. Instead we set
+ "round toward Zero" mode and round by adding +-0.5 before rounding
+ to the integer value. */
+
+ENTRY (__llround)
+ CALL_MCOUNT 0
+ lfd fp12,.LC0@toc(2)
+ lfd fp10,.LC1@toc(2)
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ ble- cr6,.L4
+ fadd fp1,fp1,fp10 /* x+= 0.5; */
+.L9:
+ fctidz fp2,fp1 /* Convert To Integer DW llround toward 0. */
+ stfd fp2,-16(r1)
+ nop /* Insure the following load is in a different dispatch group */
+ nop /* to avoid pipe stall on POWER4&5. */
+ nop
+ ld r3,-16(r1)
+ blr
+.L4:
+ fsub fp1,fp1,fp10 /* x-= 0.5; */
+ b .L9
+ END (__llround)
+
+strong_alias (__llround, __lround)
+weak_alias (__llround, llround)
+weak_alias (__lround, lround)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__llround, llroundl)
+strong_alias (__llround, __llroundl)
+weak_alias (__lround, lroundl)
+strong_alias (__lround, __lroundl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __llround, llroundl, GLIBC_2_1)
+compat_symbol (libm, __lround, lroundl, GLIBC_2_1)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S
new file mode 100644
index 000000000..bbbd05492
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S
@@ -0,0 +1,60 @@
+/* llroundf function. PowerPC64 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .section ".toc","aw"
+.LC0: /* -0.0 */
+ .tc FD_00000000_0[TC],0x0000000000000000
+.LC1: /* 0.5 */
+ .tc FD_3fe00000_0[TC],0x3fe0000000000000
+ .section ".text"
+
+/* long long [r3] llroundf (float x [fp1])
+ IEEE 1003.1 llroundf function. IEEE specifies "roundf to the nearest
+ integer value, rounding halfway cases away from zero, regardless of
+ the current rounding mode." However PowerPC Architecture defines
+ "roundf to Nearest" as "Choose the best approximation. In case of a
+ tie, choose the one that is even (least significant bit o).".
+ So we can't use the PowerPC "round to Nearest" mode. Instead we set
+ "round toward Zero" mode and round by adding +-0.5 before rounding
+ to the integer value. */
+
+ENTRY (__llroundf)
+ CALL_MCOUNT 0
+ lfd fp12,.LC0@toc(2)
+ lfd fp10,.LC1@toc(2)
+ fcmpu cr6,fp1,fp12 /* if (x < 0.0) */
+ fsubs fp3,fp1,fp10 /* x-= 0.5; */
+ ble- cr6,.L9
+ fadds fp3,fp1,fp10 /* x+= 0.5; */
+.L9:
+ fctidz fp2,fp3 /* Convert To Integer DW round toward 0. */
+ stfd fp2,-16(r1)
+ nop /* Insure the following load is in a different dispatch group */
+ nop /* to avoid pipe stall on POWER4&5. */
+ nop
+ ld r3,-16(r1)
+ blr
+ END (__llroundf)
+
+strong_alias (__llroundf, __lroundf)
+weak_alias (__llroundf, llroundf)
+weak_alias (__lroundf, lroundf)
+
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_lrint.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_lrint.S
new file mode 100644
index 000000000..fe774693b
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_lrint.S
@@ -0,0 +1,2 @@
+/* __lrint is in s_llrint.c */
+/* __lrint is in s_llrint.c */
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_lround.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_lround.S
new file mode 100644
index 000000000..883bba1c5
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_lround.S
@@ -0,0 +1,2 @@
+/* __lround is in s_llround.S */
+/* __lround is in s_llround.S */
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_lroundf.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_lroundf.S
new file mode 100644
index 000000000..15506f680
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_lroundf.S
@@ -0,0 +1,2 @@
+/* __lroundf is in s_llroundf.S */
+/* __lroundf is in s_llroundf.S */
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S
new file mode 100644
index 000000000..0d0eb36f9
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S
@@ -0,0 +1,114 @@
+/* nearbyint long double.
+ IBM extended format long double version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**52 */
+ .tc FD_43300000_0[TC],0x4330000000000000
+ .section ".text"
+
+/* long double [fp1,fp2] nearbyintl (long double x [fp1,fp2])
+ IEEE 1003.1 nearbyintl function. nearbyintl is simular to the rintl
+ but does raise the "inexact" exception. This implementation is
+ based on rintl but explicitly maskes the inexact exception on entry
+ and clears any pending inexact before restoring the exception mask
+ on exit.
+
+ PowerPC64 long double uses the IBM extended format which is
+ represented two 64-floating point double values. The values are
+ non-overlapping giving an effective precision of 106 bits. The first
+ double contains the high order bits of mantisa and is always rounded
+ to represent a normal rounding of long double to double. Since the
+ long double value is sum of the high and low values, the low double
+ normally has the opposite sign to compensate for the this rounding.
+
+ For long double there are two cases:
+ 1) |x| < 2**52, all the integer bits are in the high double.
+ floor the high double and set the low double to -0.0.
+ 2) |x| >= 2**52, Rounding involves both doubles.
+ See the comment before lable .L2 for details.
+ */
+ENTRY (__nearbyintl)
+ mffs fp11 /* Save current FPSCR. */
+ lfd fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ mtfsb0 28 /* Disable "inexact" exceptions. */
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fabs fp9,fp2
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnl- cr7,.L2
+ fmr fp2,fp12
+ bng- cr6,.L4
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ b .L9
+.L4:
+ bnl- cr6,.L9 /* if (x < 0.0) */
+ fsub fp1,fp13,fp1 /* x = TWO52 - x; */
+ fsub fp0,fp1,fp13 /* x = - (x - TWO52); */
+ fneg fp1,fp0
+.L9:
+ mtfsb0 6 /* Clear any pending "inexact" exceptions. */
+ mtfsf 0x01,fp11 /* restore exception mask. */
+ blr
+
+/* The high double is > TWO52 so we need to round the low double and
+ perhaps the high double. This gets a bit tricky so we use the
+ following algorithm:
+
+ tau = floor(x_high/TWO52);
+ x0 = x_high - tau;
+ x1 = x_low + tau;
+ r1 = nearbyint(x1);
+ y_high = x0 + r1;
+ y_low = r1 - tau;
+ return y; */
+.L2:
+ fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */
+ fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */
+ bge- cr7,.L9 /* return x; */
+ beq- cr0,.L9
+ fdiv fp8,fp1,fp13 /* x_high/TWO52 */
+ fctidz fp0,fp8
+ fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
+ fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
+ fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
+
+ fcmpu cr6,fp4,fp12 /* if (x1 > 0.0) */
+ bng- cr6,.L8
+ fadd fp5,fp4,fp13 /* r1 = x1 + TWO52; */
+ fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */
+ b .L6
+.L8:
+ fmr fp5,fp4
+ bge- cr6,.L6 /* if (x1 < 0.0) */
+ fsub fp5,fp13,fp4 /* r1 = TWO52 - x1; */
+ fsub fp0,fp5,fp13 /* r1 = - (r1 - TWO52); */
+ fneg fp5,fp0
+.L6:
+ fadd fp1,fp3,fp5 /* y_high = x0 + r1; */
+ fsub fp2,fp5,fp8 /* y_low = r1 - tau; */
+ b .L9
+END (__nearbyintl)
+
+long_double_symbol (libm, __nearbyintl, nearbyintl)
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_rint.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_rint.S
new file mode 100644
index 000000000..b4fbc0b51
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_rint.S
@@ -0,0 +1,60 @@
+/* Round to int floating-point values. PowerPC64 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This has been coded in assembler because GCC makes such a mess of it
+ when it's coded in C. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**52 */
+ .tc FD_43300000_0[TC],0x4330000000000000
+ .section ".text"
+
+EALIGN (__rint, 4, 0)
+ CALL_MCOUNT 0
+ lfd fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ bng- cr6,.L4
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ blr /* x = 0.0; */
+.L4:
+ bnllr- cr6 /* if (x < 0.0) */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ blr /* x = -0.0; */
+ END (__rint)
+
+weak_alias (__rint, rint)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__rint, rintl)
+strong_alias (__rint, __rintl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __rint, rintl, GLIBC_2_0)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_rintf.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_rintf.S
new file mode 100644
index 000000000..e4fa9ba2e
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_rintf.S
@@ -0,0 +1,49 @@
+/* Round float to int floating-point values. PowerPC64 version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**23 */
+ .tc FD_4b000000_0[TC],0x4b00000000000000
+ .section ".text"
+
+EALIGN (__rintf, 4, 0)
+ CALL_MCOUNT 0
+ lfs fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fsubs fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ bng- cr6,.L4
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ blr /* x = 0.0; */
+.L4:
+ bnllr- cr6 /* if (x < 0.0) */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ blr /* x = -0.0; */
+ END (__rintf)
+
+weak_alias (__rintf, rintf)
+
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_round.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_round.S
new file mode 100644
index 000000000..15afca154
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_round.S
@@ -0,0 +1,79 @@
+/* round function. PowerPC64 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**52 */
+ .tc FD_43300000_0[TC],0x4330000000000000
+.LC1: /* 0.5 */
+ .tc FD_3fe00000_0[TC],0x3fe0000000000000
+ .section ".text"
+
+/* double [fp1] round (double x [fp1])
+ IEEE 1003.1 round function. IEEE specifies "round to the nearest
+ integer value, rounding halfway cases away from zero, regardless of
+ the current rounding mode." However PowerPC Architecture defines
+ "Round to Nearest" as "Choose the best approximation. In case of a
+ tie, choose the one that is even (least significant bit o).".
+ So we can't use the PowerPC "Round to Nearest" mode. Instead we set
+ "Round toward Zero" mode and round by adding +-0.5 before rounding
+ to the integer value. */
+
+EALIGN (__round, 4, 0)
+ CALL_MCOUNT 0
+ mffs fp11 /* Save current FPU rounding mode. */
+ lfd fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,1 /* Set rounding mode toward 0. */
+ lfd fp10,.LC1@toc(2)
+ ble- cr6,.L4
+ fadd fp1,fp1,fp10 /* x+= 0.5; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ fsub fp9,fp1,fp10 /* x+= 0.5; */
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsub fp1,fp9,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__round)
+
+weak_alias (__round, round)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__round, roundl)
+strong_alias (__round, __roundl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __round, roundl, GLIBC_2_1)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_roundf.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_roundf.S
new file mode 100644
index 000000000..d2e29fdb8
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_roundf.S
@@ -0,0 +1,71 @@
+/* roundf function. PowerPC64 version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**23 */
+ .tc FD_4b000000_0[TC],0x4b00000000000000
+.LC1: /* 0.5 */
+ .tc FD_3f000000_0[TC],0x3f00000000000000
+ .section ".text"
+
+/* float [fp1] roundf (float x [fp1])
+ IEEE 1003.1 round function. IEEE specifies "round to the nearest
+ integer value, rounding halfway cases away from zero, regardless of
+ the current rounding mode." However PowerPC Architecture defines
+ "Round to Nearest" as "Choose the best approximation. In case of a
+ tie, choose the one that is even (least significant bit o).".
+ So we can't use the PowerPC "Round to Nearest" mode. Instead we set
+ "Round toward Zero" mode and round by adding +-0.5 before rounding
+ to the integer value. */
+
+EALIGN (__roundf, 4, 0)
+ CALL_MCOUNT 0
+ mffs fp11 /* Save current FPU rounding mode. */
+ lfs fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fsubs fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,1 /* Set rounding mode toward 0. */
+ lfs fp10,.LC1@toc(2)
+ ble- cr6,.L4
+ fadds fp1,fp1,fp10 /* x+= 0.5; */
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ fsubs fp9,fp1,fp10 /* x+= 0.5; */
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsubs fp1,fp9,fp13 /* x-= TWO23; */
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__roundf)
+
+weak_alias (__roundf, roundf)
+
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_roundl.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_roundl.S
new file mode 100644
index 000000000..20da828a8
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_roundl.S
@@ -0,0 +1,133 @@
+/* long double round function.
+ IBM extended format long double version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**52 */
+ .tc FD_43300000_0[TC],0x4330000000000000
+.LC1: /* 0.5 */
+ .tc FD_3fe00000_0[TC],0x3fe0000000000000
+ .section ".text"
+
+/* long double [fp1,fp2] roundl (long double x [fp1,fp2])
+ IEEE 1003.1 round function. IEEE specifies "round to the nearest
+ integer value, rounding halfway cases away from zero, regardless of
+ the current rounding mode." However PowerPC Architecture defines
+ "Round to Nearest" as "Choose the best approximation. In case of a
+ tie, choose the one that is even (least significant bit o).".
+ So we can't use the PowerPC "Round to Nearest" mode. Instead we set
+ "Round toward Zero" mode and round by adding +-0.5 before rounding
+ to the integer value. */
+
+ENTRY (__roundl)
+ mffs fp11 /* Save current FPU rounding mode. */
+ lfd fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fabs fp9,fp2
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnl- cr7,.L2
+ mtfsfi 7,1 /* Set rounding mode toward 0. */
+ lfd fp10,.LC1@toc(2)
+ ble- cr6,.L1
+ fneg fp2,fp12
+ fadd fp1,fp1,fp10 /* x+= 0.5; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) x = 0.0; */
+.L0:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L1:
+ fsub fp9,fp1,fp10 /* x-= 0.5; */
+ fneg fp2,fp12
+ bge- cr6,.L0 /* if (x < 0.0) */
+ fsub fp1,fp9,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fnabs fp1,fp1 /* if (x == 0.0) x = -0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+
+/* The high double is > TWO52 so we need to round the low double and
+ perhaps the high double. In this case we have to round the low
+ double and handle any adjustment to the high double that may be
+ caused by rounding (up). This is complicated by the fact that the
+ high double may already be rounded and the low double may have the
+ opposite sign to compensate.This gets a bit tricky so we use the
+ following algorithm:
+
+ tau = floor(x_high/TWO52);
+ x0 = x_high - tau;
+ x1 = x_low + tau;
+ r1 = rint(x1);
+ y_high = x0 + r1;
+ y_low = x0 - y_high + r1;
+ return y; */
+.L2:
+ fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */
+ fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */
+ fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */
+ lfd fp10,.LC1@toc(2)
+ bgelr- cr7 /* return x; */
+ beqlr- cr0
+ mtfsfi 7,1 /* Set rounding mode toward 0. */
+ fdiv fp8,fp1,fp13 /* x_high/TWO52 */
+
+ bng- cr6,.L6 /* if (x > 0.0) */
+ fctidz fp0,fp8
+ fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
+ bng cr5,.L4 /* if (x_low > 0.0) */
+ fmr fp3,fp1
+ fmr fp4,fp2
+ b .L5
+.L4: /* if (x_low < 0.0) */
+ fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
+ fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
+.L5:
+ fadd fp5,fp4,fp10 /* r1 = x1 + 0.5; */
+ fadd fp5,fp5,fp13 /* r1 = r1 + TWO52; */
+ fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */
+ b .L9
+.L6: /* if (x < 0.0) */
+ fctidz fp0,fp8
+ fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
+ bnl cr5,.L7 /* if (x_low < 0.0) */
+ fmr fp3,fp1
+ fmr fp4,fp2
+ b .L8
+.L7: /* if (x_low > 0.0) */
+ fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
+ fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
+.L8:
+ fsub fp5,fp4,fp10 /* r1 = x1 - 0.5; */
+ fsub fp5,fp5,fp13 /* r1-= TWO52; */
+ fadd fp5,fp5,fp13 /* r1+= TWO52; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ fadd fp1,fp3,fp5 /* y_high = x0 + r1; */
+ fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */
+ fadd fp2,fp2,fp5
+ blr
+END (__roundl)
+
+long_double_symbol (libm, __roundl, roundl)
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_trunc.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_trunc.S
new file mode 100644
index 000000000..086ed0025
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_trunc.S
@@ -0,0 +1,71 @@
+/* trunc function. PowerPC64 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**52 */
+ .tc FD_43300000_0[TC],0x4330000000000000
+ .section ".text"
+
+/* double [fp1] trunc (double x [fp1])
+ IEEE 1003.1 trunc function. IEEE specifies "trunc to the integer
+ value, in floating format, nearest to but no larger in magnitude
+ then the argument."
+ We set "round toward Zero" mode and trunc by adding +-2**52 then
+ subtracting +-2**52. */
+
+EALIGN (__trunc, 4, 0)
+ CALL_MCOUNT 0
+ mffs fp11 /* Save current FPU rounding mode. */
+ lfd fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,1 /* Set rounding toward 0 mode. */
+ ble- cr6,.L4
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__trunc)
+
+weak_alias (__trunc, trunc)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__trunc, truncl)
+strong_alias (__trunc, __truncl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __trunc, truncl, GLIBC_2_1)
+#endif
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_truncf.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_truncf.S
new file mode 100644
index 000000000..1456e7f43
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_truncf.S
@@ -0,0 +1,63 @@
+/* truncf function. PowerPC64 version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**23 */
+ .tc FD_4b000000_0[TC],0x4b00000000000000
+ .section ".text"
+
+/* float [fp1] truncf (float x [fp1])
+ IEEE 1003.1 trunc function. IEEE specifies "trunc to the integer
+ value, in floating format, nearest to but no larger in magnitude
+ then the argument."
+ We set "round toward Zero" mode and trunc by adding +-2**23 then
+ subtracting +-2**23. */
+
+EALIGN (__truncf, 4, 0)
+ CALL_MCOUNT 0
+ mffs fp11 /* Save current FPU rounding mode. */
+ lfs fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fsubs fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnllr- cr7
+ mtfsfi 7,1 /* Set rounding toward 0 mode. */
+ ble- cr6,.L4
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fabs fp1,fp1 /* if (x == 0.0) */
+ /* x = 0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L4:
+ bge- cr6,.L9 /* if (x < 0.0) */
+ fsubs fp1,fp1,fp13 /* x-= TWO23; */
+ fadds fp1,fp1,fp13 /* x+= TWO23; */
+ fnabs fp1,fp1 /* if (x == 0.0) */
+ /* x = -0.0; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+ END (__truncf)
+
+weak_alias (__truncf, truncf)
+
diff --git a/libc/sysdeps/powerpc/powerpc64/fpu/s_truncl.S b/libc/sysdeps/powerpc/powerpc64/fpu/s_truncl.S
new file mode 100644
index 000000000..1864fc14b
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/fpu/s_truncl.S
@@ -0,0 +1,121 @@
+/* long double trunc function.
+ IBM extended format long double version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC0: /* 2**52 */
+ .tc FD_43300000_0[TC],0x4330000000000000
+.LC1: /* 0.5 */
+ .tc FD_3fe00000_0[TC],0x3fe0000000000000
+ .section ".text"
+
+/* long double [fp1,fp2] truncl (long double x [fp1,fp2]) */
+
+ENTRY (__truncl)
+ mffs fp11 /* Save current FPU rounding mode. */
+ lfd fp13,.LC0@toc(2)
+ fabs fp0,fp1
+ fabs fp9,fp2
+ fsub fp12,fp13,fp13 /* generate 0.0 */
+ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
+ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
+ bnl- cr7,.L2
+ mtfsfi 7,1 /* Set rounding mode toward 0. */
+ ble- cr6,.L1
+ fneg fp2,fp12
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fabs fp1,fp1 /* if (x == 0.0) x = 0.0; */
+.L0:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+.L1:
+ fneg fp2,fp12
+ bge- cr6,.L0 /* if (x < 0.0) */
+ fsub fp1,fp1,fp13 /* x-= TWO52; */
+ fadd fp1,fp1,fp13 /* x+= TWO52; */
+ fnabs fp1,fp1 /* if (x == 0.0) x = -0.0; */
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ blr
+
+/* The high double is > TWO52 so we need to round the low double and
+ perhaps the high double. In this case we have to round the low
+ double and handle any adjustment to the high double that may be
+ caused by rounding (up). This is complicated by the fact that the
+ high double may already be rounded and the low double may have the
+ opposite sign to compensate.This gets a bit tricky so we use the
+ following algorithm:
+
+ tau = floor(x_high/TWO52);
+ x0 = x_high - tau;
+ x1 = x_low + tau;
+ r1 = rint(x1);
+ y_high = x0 + r1;
+ y_low = x0 - y_high + r1;
+ return y; */
+.L2:
+ fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */
+ fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */
+ fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */
+ bgelr- cr7 /* return x; */
+ beqlr- cr0
+ mtfsfi 7,1 /* Set rounding mode toward 0. */
+ fdiv fp8,fp1,fp13 /* x_high/TWO52 */
+
+ bng- cr6,.L6 /* if (x > 0.0) */
+ fctidz fp0,fp8
+ fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
+ fadd fp8,fp8,fp8 /* tau++; Make tau even */
+ bng cr5,.L4 /* if (x_low > 0.0) */
+ fmr fp3,fp1
+ fmr fp4,fp2
+ b .L5
+.L4: /* if (x_low < 0.0) */
+ fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
+ fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
+.L5:
+ fadd fp5,fp4,fp13 /* r1 = r1 + TWO52; */
+ fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */
+ b .L9
+.L6: /* if (x < 0.0) */
+ fctidz fp0,fp8
+ fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
+ fadd fp8,fp8,fp8 /* tau++; Make tau even */
+ bnl cr5,.L7 /* if (x_low < 0.0) */
+ fmr fp3,fp1
+ fmr fp4,fp2
+ b .L8
+.L7: /* if (x_low > 0.0) */
+ fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
+ fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
+.L8:
+ fsub fp5,fp4,fp13 /* r1-= TWO52; */
+ fadd fp5,fp5,fp13 /* r1+= TWO52; */
+.L9:
+ mtfsf 0x01,fp11 /* restore previous rounding mode. */
+ fadd fp1,fp3,fp5 /* y_high = x0 + r1; */
+ fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */
+ fadd fp2,fp2,fp5
+ blr
+END (__truncl)
+
+long_double_symbol (libm, __truncl, truncl)
diff --git a/libc/sysdeps/powerpc/powerpc64/hp-timing.c b/libc/sysdeps/powerpc/powerpc64/hp-timing.c
new file mode 100644
index 000000000..4e54e66e5
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/hp-timing.c
@@ -0,0 +1,25 @@
+/* Support for high precision, low overhead timing functions.
+ powerpc64 version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hp-timing.h>
+
+/* We have to define the variable for the overhead. */
+hp_timing_t _dl_hp_timing_overhead;
diff --git a/libc/sysdeps/powerpc/powerpc64/hp-timing.h b/libc/sysdeps/powerpc/powerpc64/hp-timing.h
new file mode 100644
index 000000000..b58cca900
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/hp-timing.h
@@ -0,0 +1,136 @@
+/* High precision, low overhead timing functions. powerpc64 version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H 1
+
+#include <string.h>
+#include <sys/param.h>
+#include <stdio-common/_itoa.h>
+#include <atomic.h>
+
+/* The macros defined here use the powerpc 64-bit time base register.
+ The time base is nominally clocked at 1/8th the CPU clock, but this
+ can vary.
+
+ The list of macros we need includes the following:
+
+ - HP_TIMING_AVAIL: test for availability.
+
+ - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
+ implemented using function calls but instead uses some inlined code
+ which might simply consist of a few assembler instructions. We have to
+ know this since we might want to use the macros here in places where we
+ cannot make function calls.
+
+ - hp_timing_t: This is the type for variables used to store the time
+ values.
+
+ - HP_TIMING_ZERO: clear `hp_timing_t' object.
+
+ - HP_TIMING_NOW: place timestamp for current time in variable given as
+ parameter.
+
+ - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
+ HP_TIMING_DIFF macro.
+
+ - HP_TIMING_DIFF: compute difference between two times and store it
+ in a third. Source and destination might overlap.
+
+ - HP_TIMING_ACCUM: add time difference to another variable. This might
+ be a bit more complicated to implement for some platforms as the
+ operation should be thread-safe and 64bit arithmetic on 32bit platforms
+ is not.
+
+ - HP_TIMING_ACCUM_NT: this is the variant for situations where we know
+ there are no threads involved.
+
+ - HP_TIMING_PRINT: write decimal representation of the timing value into
+ the given string. This operation need not be inline even though
+ HP_TIMING_INLINE is specified.
+
+*/
+
+/* We always assume having the timestamp register. */
+#define HP_TIMING_AVAIL (1)
+
+/* We indeed have inlined functions. */
+#define HP_TIMING_INLINE (1)
+
+/* We use 64bit values for the times. */
+typedef unsigned long long int hp_timing_t;
+
+/* Set timestamp value to zero. */
+#define HP_TIMING_ZERO(Var) (Var) = (0)
+
+/* That's quite simple. Use the `mftb' instruction. Note that the value
+ might not be 100% accurate since there might be some more instructions
+ running in this moment. This could be changed by using a barrier like
+ 'lwsync' right before the `mftb' instruciton. But we are not interested
+ in accurate clock cycles here so we don't do this. */
+#define HP_TIMING_NOW(Var) __asm__ __volatile__ ("mftb %0" : "=r" (Var))
+
+/* Use two 'mftb' instructions in a row to find out how long it takes.
+ On current POWER4, POWER5, and 970 processors mftb take ~10 cycles. */
+#define HP_TIMING_DIFF_INIT() \
+ do { \
+ if (GLRO(dl_hp_timing_overhead) == 0) \
+ { \
+ int __cnt = 5; \
+ GLRO(dl_hp_timing_overhead) = ~0ull; \
+ do \
+ { \
+ hp_timing_t __t1, __t2; \
+ HP_TIMING_NOW (__t1); \
+ HP_TIMING_NOW (__t2); \
+ if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \
+ GLRO(dl_hp_timing_overhead) = __t2 - __t1; \
+ } \
+ while (--__cnt > 0); \
+ } \
+ } while (0)
+
+/* It's simple arithmetic in 64-bit. */
+#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start))
+
+/* We need to insure that this add is atomic in threaded environments. We use
+ __arch_atomic_exchange_and_add_64 from atomic.h to get thread safety. */
+#define HP_TIMING_ACCUM(Sum, Diff) \
+ do { \
+ hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \
+ __arch_atomic_exchange_and_add_64 (&(Sum), __diff); \
+ } while (0)
+
+/* No threads, no extra work. */
+#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff)
+
+/* Print the time value. */
+#define HP_TIMING_PRINT(Buf, Len, Val) \
+ do { \
+ char __buf[20]; \
+ char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \
+ size_t __len = (Len); \
+ char *__dest = (Buf); \
+ while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \
+ *__dest++ = *__cp++; \
+ memcpy (__dest, " ticks", MIN (__len, sizeof (" ticks"))); \
+ } while (0)
+
+#endif /* hp-timing.h */
diff --git a/libc/sysdeps/powerpc/powerpc64/memcpy.S b/libc/sysdeps/powerpc/powerpc64/memcpy.S
new file mode 100644
index 000000000..f395de906
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/memcpy.S
@@ -0,0 +1,369 @@
+/* Optimized memcpy implementation for PowerPC64.
+ Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
+ Returns 'dst'.
+
+ Memcpy handles short copies (< 32-bytes) using a binary move blocks
+ (no loops) of lwz/stw. The tail (remaining 1-3) bytes is handled
+ with the appropriate combination of byte and halfword load/stores.
+ There is minimal effort to optimize the alignment of short moves.
+ The 64-bit implementations of POWER3 and POWER4 do a reasonable job
+ of handling unligned load/stores that do not cross 32-byte boundries.
+
+ Longer moves (>= 32-bytes) justify the effort to get at least the
+ destination doubleword (8-byte) aligned. Further optimization is
+ posible when both source and destination are doubleword aligned.
+ Each case has a optimized unrolled loop. */
+
+EALIGN (BP_SYM (memcpy), 5, 0)
+ CALL_MCOUNT 3
+
+ cmpldi cr1,5,31
+ neg 0,3
+ std 3,-16(1)
+ std 31,-8(1)
+ cfi_offset(31,-8)
+ andi. 11,3,7 /* check alignement of dst. */
+ clrldi 0,0,61 /* Number of bytes until the 1st doubleword of dst. */
+ clrldi 10,4,61 /* check alignement of src. */
+ cmpldi cr6,5,8
+ ble- cr1,.L2 /* If move < 32 bytes use short move code. */
+ cmpld cr6,10,11
+ mr 12,4
+ srdi 9,5,3 /* Number of full double words remaining. */
+ mtcrf 0x01,0
+ mr 31,5
+ beq .L0
+
+ subf 31,0,5
+ /* Move 0-7 bytes as needed to get the destination doubleword alligned. */
+1: bf 31,2f
+ lbz 6,0(12)
+ addi 12,12,1
+ stb 6,0(3)
+ addi 3,3,1
+2: bf 30,4f
+ lhz 6,0(12)
+ addi 12,12,2
+ sth 6,0(3)
+ addi 3,3,2
+4: bf 29,0f
+ lwz 6,0(12)
+ addi 12,12,4
+ stw 6,0(3)
+ addi 3,3,4
+0:
+ clrldi 10,12,61 /* check alignement of src again. */
+ srdi 9,31,3 /* Number of full double words remaining. */
+
+ /* Copy doublewords from source to destination, assumpting the
+ destination is aligned on a doubleword boundary.
+
+ At this point we know there are at least 25 bytes left (32-7) to copy.
+ The next step is to determine if the source is also doubleword aligned.
+ If not branch to the unaligned move code at .L6. which uses
+ a load, shift, store strategy.
+
+ Otherwise source and destination are doubleword aligned, and we can
+ the optimized doubleword copy loop. */
+.L0:
+ clrldi 11,31,61
+ mtcrf 0x01,9
+ bne- cr6,.L6 /* If source is not DW aligned. */
+
+ /* Move doublewords where destination and source are DW aligned.
+ Use a unrolled loop to copy 4 doubleword (32-bytes) per iteration.
+ If the the copy is not an exact multiple of 32 bytes, 1-3
+ doublewords are copied as needed to set up the main loop. After
+ the main loop exits there may be a tail of 1-7 bytes. These byte are
+ copied a word/halfword/byte at a time as needed to preserve alignment. */
+
+ srdi 8,31,5
+ cmpldi cr1,9,4
+ cmpldi cr6,11,0
+ mr 11,12
+
+ bf 30,1f
+ ld 6,0(12)
+ ld 7,8(12)
+ addi 11,12,16
+ mtctr 8
+ std 6,0(3)
+ std 7,8(3)
+ addi 10,3,16
+ bf 31,4f
+ ld 0,16(12)
+ std 0,16(3)
+ blt cr1,3f
+ addi 11,12,24
+ addi 10,3,24
+ b 4f
+ .align 4
+1:
+ mr 10,3
+ mtctr 8
+ bf 31,4f
+ ld 6,0(12)
+ addi 11,12,8
+ std 6,0(3)
+ addi 10,3,8
+
+ .align 4
+4:
+ ld 6,0(11)
+ ld 7,8(11)
+ ld 8,16(11)
+ ld 0,24(11)
+ addi 11,11,32
+2:
+ std 6,0(10)
+ std 7,8(10)
+ std 8,16(10)
+ std 0,24(10)
+ addi 10,10,32
+ bdnz 4b
+3:
+
+ rldicr 0,31,0,60
+ mtcrf 0x01,31
+ beq cr6,0f
+.L9:
+ add 3,3,0
+ add 12,12,0
+
+/* At this point we have a tail of 0-7 bytes and we know that the
+ destiniation is double word aligned. */
+4: bf 29,2f
+ lwz 6,0(12)
+ addi 12,12,4
+ stw 6,0(3)
+ addi 3,3,4
+2: bf 30,1f
+ lhz 6,0(12)
+ addi 12,12,2
+ sth 6,0(3)
+ addi 3,3,2
+1: bf 31,0f
+ lbz 6,0(12)
+ stb 6,0(3)
+0:
+ /* Return original dst pointer. */
+ ld 31,-8(1)
+ ld 3,-16(1)
+ blr
+
+/* Copy up to 31 bytes. This divided into two cases 0-8 bytes and 9-31
+ bytes. Each case is handled without loops, using binary (1,2,4,8)
+ tests.
+
+ In the short (0-8 byte) case no attempt is made to force alignment
+ of either source or destination. The hardware will handle the
+ unaligned load/stores with small delays for crossing 32- 64-byte, and
+ 4096-byte boundaries. Since these short moves are unlikely to be
+ unaligned or cross these boundaries, the overhead to force
+ alignment is not justified.
+
+ The longer (9-31 byte) move is more likely to cross 32- or 64-byte
+ boundaries. Since only loads are sensitive to the 32-/64-byte
+ boundaries it is more important to align the source then the
+ destination. If the source is not already word aligned, we first
+ move 1-3 bytes as needed. Since we are only word aligned we don't
+ use double word load/stores to insure that all loads are aligned.
+ While the destination and stores may still be unaligned, this
+ is only an issue for page (4096 byte boundary) crossing, which
+ should be rare for these short moves. The hardware handles this
+ case automatically with a small delay. */
+
+ .align 4
+.L2:
+ mtcrf 0x01,5
+ neg 8,4
+ clrrdi 11,4,2
+ andi. 0,8,3
+ ble cr6,.LE8 /* Handle moves of 0-8 bytes. */
+/* At least 9 bytes left. Get the source word aligned. */
+ cmpldi cr1,5,16
+ mr 10,5
+ mr 12,4
+ cmpldi cr6,0,2
+ beq .L3 /* If the source is already word aligned skip this. */
+/* Copy 1-3 bytes to get source address word aligned. */
+ lwz 6,0(11)
+ subf 10,0,5
+ add 12,4,0
+ blt cr6,5f
+ srdi 7,6,16
+ bgt cr6,3f
+ sth 6,0(3)
+ b 7f
+ .align 4
+3:
+ stb 7,0(3)
+ sth 6,1(3)
+ b 7f
+ .align 4
+5:
+ stb 6,0(3)
+7:
+ cmpldi cr1,10,16
+ add 3,3,0
+ mtcrf 0x01,10
+ .align 4
+.L3:
+/* At least 6 bytes left and the source is word aligned. */
+ blt cr1,8f
+16: /* Move 16 bytes. */
+ lwz 6,0(12)
+ lwz 7,4(12)
+ stw 6,0(3)
+ lwz 6,8(12)
+ stw 7,4(3)
+ lwz 7,12(12)
+ addi 12,12,16
+ stw 6,8(3)
+ stw 7,12(3)
+ addi 3,3,16
+8: /* Move 8 bytes. */
+ bf 28,4f
+ lwz 6,0(12)
+ lwz 7,4(12)
+ addi 12,12,8
+ stw 6,0(3)
+ stw 7,4(3)
+ addi 3,3,8
+4: /* Move 4 bytes. */
+ bf 29,2f
+ lwz 6,0(12)
+ addi 12,12,4
+ stw 6,0(3)
+ addi 3,3,4
+2: /* Move 2-3 bytes. */
+ bf 30,1f
+ lhz 6,0(12)
+ sth 6,0(3)
+ bf 31,0f
+ lbz 7,2(12)
+ stb 7,2(3)
+ ld 3,-16(1)
+ blr
+1: /* Move 1 byte. */
+ bf 31,0f
+ lbz 6,0(12)
+ stb 6,0(3)
+0:
+ /* Return original dst pointer. */
+ ld 3,-16(1)
+ blr
+
+/* Special case to copy 0-8 bytes. */
+ .align 4
+.LE8:
+ mr 12,4
+ bne cr6,4f
+/* Would have liked to use use ld/std here but the 630 processors are
+ slow for load/store doubles that are not at least word aligned.
+ Unaligned Load/Store word execute with only a 1 cycle penaltity. */
+ lwz 6,0(4)
+ lwz 7,4(4)
+ stw 6,0(3)
+ stw 7,4(3)
+ /* Return original dst pointer. */
+ ld 3,-16(1)
+ blr
+ .align 4
+4: bf 29,2b
+ lwz 6,0(4)
+ stw 6,0(3)
+6:
+ bf 30,5f
+ lhz 7,4(4)
+ sth 7,4(3)
+ bf 31,0f
+ lbz 8,6(4)
+ stb 8,6(3)
+ ld 3,-16(1)
+ blr
+ .align 4
+5:
+ bf 31,0f
+ lbz 6,4(4)
+ stb 6,4(3)
+ .align 4
+0:
+ /* Return original dst pointer. */
+ ld 3,-16(1)
+ blr
+
+ .align 4
+.L6:
+
+ /* Copy doublewords where the destination is aligned but the source is
+ not. Use aligned doubleword loads from the source, shifted to realign
+ the data, to allow aligned destination stores. */
+ subf 5,10,12
+ andi. 0,9,1
+ cmpldi cr6,11,0
+ sldi 10,10,3
+ mr 11,9
+ mr 4,3
+ ld 6,0(5)
+ ld 7,8(5)
+ subfic 9,10,64
+ beq 2f
+ sld 0,6,10
+ cmpldi 11,1
+ mr 6,7
+ addi 4,4,-8
+ addi 11,11,-1
+ b 1f
+2: addi 5,5,8
+ .align 4
+0: sld 0,6,10
+ srd 8,7,9
+ cmpldi 11,2
+ ld 6,8(5)
+ or 0,0,8
+ addi 11,11,-2
+ std 0,0(4)
+ sld 0,7,10
+1: srd 8,6,9
+ or 0,0,8
+ beq 8f
+ ld 7,16(5)
+ std 0,8(4)
+ addi 5,5,16
+ addi 4,4,16
+ b 0b
+ .align 4
+8:
+ std 0,8(4)
+ rldicr 0,31,0,60
+ mtcrf 0x01,31
+ bne cr6,.L9 /* If the tail is 0 bytes we are done! */
+ /* Return original dst pointer. */
+ ld 31,-8(1)
+ ld 3,-16(1)
+ blr
+END_GEN_TB (BP_SYM (memcpy),TB_TOCLESS)
+libc_hidden_builtin_def (memcpy)
diff --git a/libc/sysdeps/powerpc/powerpc64/memset.S b/libc/sysdeps/powerpc/powerpc64/memset.S
new file mode 100644
index 000000000..09c79fccd
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/memset.S
@@ -0,0 +1,292 @@
+/* Optimized memset implementation for PowerPC64.
+ Copyright (C) 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* Define a global static that can hold the cache line size. The
+ assumption is that startup code will access the "aux vector" to
+ to obtain the value set by the kernel and store it into this
+ variable. */
+ .globl __cache_line_size
+ .lcomm __cache_line_size,4,4
+ .section ".toc","aw"
+.LC0:
+ .tc __cache_line_size[TC],__cache_line_size
+ .section ".text"
+ .align 2
+
+/* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
+ Returns 's'.
+
+ The memset is done in three sizes: byte (8 bits), word (32 bits),
+ cache line (256 bits). There is a special case for setting cache lines
+ to 0, to take advantage of the dcbz instruction. */
+
+EALIGN (BP_SYM (memset), 5, 0)
+ CALL_MCOUNT 3
+
+#define rTMP r0
+#define rRTN r3 /* Initial value of 1st argument. */
+#if __BOUNDED_POINTERS__
+# define rMEMP0 r4 /* Original value of 1st arg. */
+# define rCHR r5 /* Char to set in each byte. */
+# define rLEN r6 /* Length of region to set. */
+# define rMEMP r10 /* Address at which we are storing. */
+#else
+# define rMEMP0 r3 /* Original value of 1st arg. */
+# define rCHR r4 /* Char to set in each byte. */
+# define rLEN r5 /* Length of region to set. */
+# define rMEMP r6 /* Address at which we are storing. */
+#endif
+#define rALIGN r7 /* Number of bytes we are setting now (when aligning). */
+#define rMEMP2 r8
+
+#define rNEG64 r8 /* Constant -64 for clearing with dcbz. */
+#define rCLS r8 /* Cache line size obtained from static. */
+#define rCLM r9 /* Cache line size mask to check for cache alignment. */
+L(_memset):
+#if __BOUNDED_POINTERS__
+ cmpldi cr1, rRTN, 0
+ CHECK_BOUNDS_BOTH_WIDE (rMEMP0, rTMP, rTMP2, rLEN)
+ beq cr1, L(b0)
+ STORE_RETURN_VALUE (rMEMP0)
+ STORE_RETURN_BOUNDS (rTMP, rTMP2)
+L(b0):
+#endif
+/* Take care of case for size <= 4. */
+ cmpldi cr1, rLEN, 8
+ andi. rALIGN, rMEMP0, 7
+ mr rMEMP, rMEMP0
+ ble- cr1, L(small)
+
+/* Align to doubleword boundary. */
+ cmpldi cr5, rLEN, 31
+ rlwimi rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword. */
+ beq+ L(aligned2)
+ mtcrf 0x01, rMEMP0
+ subfic rALIGN, rALIGN, 8
+ cror 28,30,31 /* Detect odd word aligned. */
+ add rMEMP, rMEMP, rALIGN
+ sub rLEN, rLEN, rALIGN
+ rlwimi rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word. */
+ bt 29, L(g4)
+/* Process the even word of doubleword. */
+ bf+ 31, L(g2)
+ stb rCHR, 0(rMEMP0)
+ bt 30, L(g4x)
+L(g2):
+ sth rCHR, -6(rMEMP)
+L(g4x):
+ stw rCHR, -4(rMEMP)
+ b L(aligned)
+/* Process the odd word of doubleword. */
+L(g4):
+ bf 28, L(g4x) /* If false, word aligned on odd word. */
+ bf+ 31, L(g0)
+ stb rCHR, 0(rMEMP0)
+ bt 30, L(aligned)
+L(g0):
+ sth rCHR, -2(rMEMP)
+
+/* Handle the case of size < 31. */
+L(aligned2):
+ rlwimi rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word. */
+L(aligned):
+ mtcrf 0x01, rLEN
+ ble cr5, L(medium)
+/* Align to 32-byte boundary. */
+ andi. rALIGN, rMEMP, 0x18
+ subfic rALIGN, rALIGN, 0x20
+ insrdi rCHR,rCHR,32,0 /* Replicate word to double word. */
+ beq L(caligned)
+ mtcrf 0x01, rALIGN
+ add rMEMP, rMEMP, rALIGN
+ sub rLEN, rLEN, rALIGN
+ cmplwi cr1, rALIGN, 0x10
+ mr rMEMP2, rMEMP
+ bf 28, L(a1)
+ stdu rCHR, -8(rMEMP2)
+L(a1): blt cr1, L(a2)
+ std rCHR, -8(rMEMP2)
+ stdu rCHR, -16(rMEMP2)
+L(a2):
+
+/* Now aligned to a 32 byte boundary. */
+L(caligned):
+ cmpldi cr1, rCHR, 0
+ clrrdi. rALIGN, rLEN, 5
+ mtcrf 0x01, rLEN
+ beq cr1, L(zloopstart) /* Special case for clearing memory using dcbz. */
+L(nondcbz):
+ srdi rTMP, rALIGN, 5
+ mtctr rTMP
+ beq L(medium) /* We may not actually get to do a full line. */
+ clrldi. rLEN, rLEN, 59
+ add rMEMP, rMEMP, rALIGN
+ li rNEG64, -0x40
+ bdz L(cloopdone)
+
+L(c3): dcbtst rNEG64, rMEMP
+ std rCHR, -8(rMEMP)
+ std rCHR, -16(rMEMP)
+ std rCHR, -24(rMEMP)
+ stdu rCHR, -32(rMEMP)
+ bdnz L(c3)
+L(cloopdone):
+ std rCHR, -8(rMEMP)
+ std rCHR, -16(rMEMP)
+ cmpldi cr1, rLEN, 16
+ std rCHR, -24(rMEMP)
+ stdu rCHR, -32(rMEMP)
+ beqlr
+ add rMEMP, rMEMP, rALIGN
+ b L(medium_tail2)
+
+ .align 5
+/* Clear lines of memory in 128-byte chunks. */
+L(zloopstart):
+/* If the remaining length is less the 32 bytes, don't bother getting
+ the cache line size. */
+ beq L(medium)
+ ld rCLS,.LC0@toc(r2)
+ lwz rCLS,0(rCLS)
+/* If the cache line size was not set just goto to L(nondcbz) which is
+ safe for any cache line size. */
+ cmpldi cr1,rCLS,0
+ beq cr1,L(nondcbz)
+
+
+/* Now we know the cache line size, and it is not 32-bytes, but
+ we may not yet be aligned to the cache line. May have a partial
+ line to fill, so touch it 1st. */
+ dcbt 0,rMEMP
+ addi rCLM,rCLS,-1
+L(getCacheAligned):
+ cmpldi cr1,rLEN,32
+ and. rTMP,rCLM,rMEMP
+ blt cr1,L(handletail32)
+ beq L(cacheAligned)
+ addi rMEMP,rMEMP,32
+ addi rLEN,rLEN,-32
+ std rCHR,-32(rMEMP)
+ std rCHR,-24(rMEMP)
+ std rCHR,-16(rMEMP)
+ std rCHR,-8(rMEMP)
+ b L(getCacheAligned)
+
+/* Now we are aligned to the cache line and can use dcbz. */
+L(cacheAligned):
+ cmpld cr1,rLEN,rCLS
+ blt cr1,L(handletail32)
+ dcbz 0,rMEMP
+ subf rLEN,rCLS,rLEN
+ add rMEMP,rMEMP,rCLS
+ b L(cacheAligned)
+
+/* We are here because the cache line size was set and was not 32-bytes
+ and the remainder (rLEN) is less than the actual cache line size.
+ So set up the preconditions for L(nondcbz) and go there. */
+L(handletail32):
+ clrrwi. rALIGN, rLEN, 5
+ b L(nondcbz)
+
+ .align 5
+L(small):
+/* Memset of 8 bytes or less. */
+ cmpldi cr6, rLEN, 4
+ cmpldi cr5, rLEN, 1
+ ble cr6,L(le4)
+ subi rLEN, rLEN, 4
+ stb rCHR,0(rMEMP)
+ stb rCHR,1(rMEMP)
+ stb rCHR,2(rMEMP)
+ stb rCHR,3(rMEMP)
+ addi rMEMP,rMEMP, 4
+ cmpldi cr5, rLEN, 1
+L(le4):
+ cmpldi cr1, rLEN, 3
+ bltlr cr5
+ stb rCHR, 0(rMEMP)
+ beqlr cr5
+ stb rCHR, 1(rMEMP)
+ bltlr cr1
+ stb rCHR, 2(rMEMP)
+ beqlr cr1
+ stb rCHR, 3(rMEMP)
+ blr
+
+/* Memset of 0-31 bytes. */
+ .align 5
+L(medium):
+ insrdi rCHR,rCHR,32,0 /* Replicate word to double word. */
+ cmpldi cr1, rLEN, 16
+L(medium_tail2):
+ add rMEMP, rMEMP, rLEN
+L(medium_tail):
+ bt- 31, L(medium_31t)
+ bt- 30, L(medium_30t)
+L(medium_30f):
+ bt- 29, L(medium_29t)
+L(medium_29f):
+ bge- cr1, L(medium_27t)
+ bflr- 28
+ std rCHR, -8(rMEMP)
+ blr
+
+L(medium_31t):
+ stbu rCHR, -1(rMEMP)
+ bf- 30, L(medium_30f)
+L(medium_30t):
+ sthu rCHR, -2(rMEMP)
+ bf- 29, L(medium_29f)
+L(medium_29t):
+ stwu rCHR, -4(rMEMP)
+ blt- cr1, L(medium_27f)
+L(medium_27t):
+ std rCHR, -8(rMEMP)
+ stdu rCHR, -16(rMEMP)
+L(medium_27f):
+ bflr- 28
+L(medium_28t):
+ std rCHR, -8(rMEMP)
+ blr
+END_GEN_TB (BP_SYM (memset),TB_TOCLESS)
+libc_hidden_builtin_def (memset)
+
+/* Copied from bzero.S to prevent the linker from inserting a stub
+ between bzero and memset. */
+ENTRY (BP_SYM (__bzero))
+ CALL_MCOUNT 3
+#if __BOUNDED_POINTERS__
+ mr r6,r4
+ li r5,0
+ mr r4,r3
+ /* Tell memset that we don't want a return value. */
+ li r3,0
+ b L(_memset)
+#else
+ mr r5,r4
+ li r4,0
+ b L(_memset)
+#endif
+END_GEN_TB (BP_SYM (__bzero),TB_TOCLESS)
+
+weak_alias (BP_SYM (__bzero), BP_SYM (bzero))
diff --git a/libc/sysdeps/powerpc/powerpc64/ppc-mcount.S b/libc/sysdeps/powerpc/powerpc64/ppc-mcount.S
new file mode 100644
index 000000000..5df965057
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/ppc-mcount.S
@@ -0,0 +1,40 @@
+/* PowerPC64-specific implementation of profiling support.
+ Copyright (C) 1997, 1999, 2002, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+/* We don't need to save the parameter-passing registers as gcc takes
+ care of that for us. Thus this function looks fairly normal.
+ In fact, the generic code would work for us. */
+
+ENTRY(_mcount)
+ mflr r4
+ ld r11, 0(r1)
+ stdu r1,-112(r1)
+ cfi_adjust_cfa_offset (112)
+ std r4, 128(r1)
+ cfi_offset (lr, 16)
+ ld r3, 16(r11)
+ bl JUMPTARGET(__mcount_internal)
+ nop
+ ld r0, 128(r1)
+ mtlr r0
+ addi r1,r1,112
+ blr
+END(_mcount)
+
diff --git a/libc/sysdeps/powerpc/powerpc64/register-dump.h b/libc/sysdeps/powerpc/powerpc64/register-dump.h
new file mode 100644
index 000000000..dd69af3fa
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/register-dump.h
@@ -0,0 +1,125 @@
+/* Dump registers.
+ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/uio.h>
+#include <stdio-common/_itoa.h>
+
+/* This prints out the information in the following form: */
+static const char dumpform[] = "\
+Register dump:\n\
+sr0=000000000000020% sr1=000000000000021% dar=000000000000029% dsi=000002a%\n\
+lr=000000000000024% ctr=000000000000023% gr3*=000000000000022% trap=0000028%\n\
+ccr=0000026% xer=0000025%\n\
+gr0-3: 000000000000000% 000000000000001% 000000000000002% 000000000000003%\n\
+gr4-7: 000000000000004% 000000000000005% 000000000000006% 000000000000007%\n\
+gr8-11: 000000000000008% 000000000000009% 00000000000000a% 00000000000000b%\n\
+gr12-15: 00000000000000c% 00000000000000d% 00000000000000e% 00000000000000f%\n\
+gr16-19: 000000000000010% 000000000000011% 000000000000012% 000000000000013%\n\
+gr20-23: 000000000000014% 000000000000015% 000000000000016% 000000000000017%\n\
+gr24-27: 000000000000018% 000000000000019% 00000000000001a% 00000000000001b%\n\
+gr28-31: 00000000000001c% 00000000000001d% 00000000000001e% 00000000000001f%\n\
+fscr=0000071%\n\
+fp0-3: 000000000000030% 000000000000031% 000000000000032% 000000000000033%\n\
+fp4-7: 000000000000034% 000000000000035% 000000000000036% 000000000000037%\n\
+fp8-11: 000000000000038% 000000000000038% 00000000000003a% 00000000000003b%\n\
+fp12-15: 00000000000003c% 00000000000003d% 00000000000003e% 00000000000003f%\n\
+fp16-19: 000000000000040% 000000000000041% 000000000000042% 000000000000043%\n\
+fp20-23: 000000000000044% 000000000000045% 000000000000046% 000000000000047%\n\
+fp24-27: 000000000000048% 000000000000049% 00000000000004a% 00000000000004b%\n\
+fp28-31: 00000000000004c% 00000000000004d% 00000000000004e% 00000000000004f%\n\
+";
+
+/* Most of the fields are self-explanatory. 'sr0' is the next
+ instruction to execute, from SRR0, which may have some relationship
+ with the instruction that caused the exception. 'r3*' is the value
+ that will be returned in register 3 when the current system call
+ returns. 'sr1' is SRR1, bits 16-31 of which are copied from the MSR:
+
+ 16 - External interrupt enable
+ 17 - Privilege level (1=user, 0=supervisor)
+ 18 - FP available
+ 19 - Machine check enable (if clear, processor locks up on machine check)
+ 20 - FP exception mode bit 0 (FP exceptions recoverable)
+ 21 - Single-step trace enable
+ 22 - Branch trace enable
+ 23 - FP exception mode bit 1
+ 25 - exception prefix (if set, exceptions are taken from 0xFFFnnnnn,
+ otherwise from 0x000nnnnn).
+ 26 - Instruction address translation enabled.
+ 27 - Data address translation enabled.
+ 30 - Exception is recoverable (otherwise, don't try to return).
+ 31 - Little-endian mode enable.
+
+ 'Trap' is the address of the exception:
+
+ 00200 - Machine check exception (memory parity error, for instance)
+ 00300 - Data access exception (memory not mapped, see dsisr for why)
+ 00400 - Instruction access exception (memory not mapped)
+ 00500 - External interrupt
+ 00600 - Alignment exception (see dsisr for more information)
+ 00700 - Program exception (illegal/trap instruction, FP exception)
+ 00800 - FP unavailable (should not be seen by user code)
+ 00900 - Decrementer exception (for instance, SIGALRM)
+ 00A00 - I/O controller interface exception
+ 00C00 - System call exception (for instance, kill(3)).
+ 00E00 - FP assist exception (optional FP instructions, etc.)
+
+ 'dar' is the memory location, for traps 00300, 00400, 00600, 00A00.
+ 'dsisr' has the following bits under trap 00300:
+ 0 - direct-store error exception
+ 1 - no page table entry for page
+ 4 - memory access not permitted
+ 5 - trying to access I/O controller space or using lwarx/stwcx on
+ non-write-cached memory
+ 6 - access was store
+ 9 - data access breakpoint hit
+ 10 - segment table search failed to find translation (64-bit ppcs only)
+ 11 - I/O controller instruction not permitted
+ For trap 00400, the same bits are set in SRR1 instead.
+ For trap 00600, bits 12-31 of the DSISR set to allow emulation of
+ the instruction without actually having to read it from memory.
+*/
+
+#define xtoi(x) (x >= 'a' ? x + 10 - 'a' : x - '0')
+
+static void
+register_dump (int fd, struct sigcontext *ctx)
+{
+ char buffer[sizeof(dumpform)];
+ char *bufferpos;
+ unsigned regno;
+ unsigned *regs = (unsigned *)(ctx->regs);
+
+ memcpy(buffer, dumpform, sizeof(dumpform));
+
+ /* Generate the output. */
+ while ((bufferpos = memchr (buffer, '%', sizeof(dumpform))))
+ {
+ regno = xtoi (bufferpos[-1]) | xtoi (bufferpos[-2]) << 4;
+ memset (bufferpos-2, '0', 3);
+ _itoa_word (regs[regno], bufferpos+1, 16, 0);
+ }
+
+ /* Write the output. */
+ write (fd, buffer, sizeof(buffer));
+}
+
+
+#define REGISTER_DUMP \
+ register_dump (fd, ctx)
diff --git a/libc/sysdeps/powerpc/powerpc64/setjmp-common.S b/libc/sysdeps/powerpc/powerpc64/setjmp-common.S
new file mode 100644
index 000000000..606eef593
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/setjmp-common.S
@@ -0,0 +1,196 @@
+/* setjmp for PowerPC64.
+ Copyright (C) 1995-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ASM
+#ifdef __NO_VMX__
+#include <novmxsetjmp.h>
+#else
+#include <jmpbuf-offsets.h>
+#endif
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+#ifndef __NO_VMX__
+ .section ".toc","aw"
+.LC__dl_hwcap:
+# ifdef SHARED
+ .tc _rtld_global_ro[TC],_rtld_global_ro
+# else
+ .tc _dl_hwcap[TC],_dl_hwcap
+# endif
+ .section ".text"
+#endif
+
+ .machine "altivec"
+ENTRY (BP_SYM (__sigsetjmp))
+ CALL_MCOUNT 2
+ .globl JUMPTARGET(GLUE(__sigsetjmp,_ent))
+ .hidden JUMPTARGET(GLUE(__sigsetjmp,_ent))
+JUMPTARGET(GLUE(__sigsetjmp,_ent)):
+ CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
+#ifdef PTR_MANGLE
+ mr r5, r1
+ PTR_MANGLE (r5, r6)
+ std r5,(JB_GPR1*8)(3)
+#else
+ std r1,(JB_GPR1*8)(3)
+#endif
+ mflr r0
+#if defined SHARED && !defined IS_IN_rtld
+ ld r5,40(r1) /* Retrieve the callers TOC. */
+ std r5,(JB_GPR2*8)(3)
+#else
+ std r2,(JB_GPR2*8)(3)
+#endif
+ std r14,((JB_GPRS+0)*8)(3)
+ stfd fp14,((JB_FPRS+0)*8)(3)
+#ifdef PTR_MANGLE
+ PTR_MANGLE2 (r0, r6)
+#endif
+ std r0,(JB_LR*8)(3)
+ std r15,((JB_GPRS+1)*8)(3)
+ stfd fp15,((JB_FPRS+1)*8)(3)
+ mfcr r0
+ std r16,((JB_GPRS+2)*8)(3)
+ stfd fp16,((JB_FPRS+2)*8)(3)
+ std r0,(JB_CR*8)(3)
+ std r17,((JB_GPRS+3)*8)(3)
+ stfd fp17,((JB_FPRS+3)*8)(3)
+ std r18,((JB_GPRS+4)*8)(3)
+ stfd fp18,((JB_FPRS+4)*8)(3)
+ std r19,((JB_GPRS+5)*8)(3)
+ stfd fp19,((JB_FPRS+5)*8)(3)
+ std r20,((JB_GPRS+6)*8)(3)
+ stfd fp20,((JB_FPRS+6)*8)(3)
+ std r21,((JB_GPRS+7)*8)(3)
+ stfd fp21,((JB_FPRS+7)*8)(3)
+ std r22,((JB_GPRS+8)*8)(3)
+ stfd fp22,((JB_FPRS+8)*8)(3)
+ std r23,((JB_GPRS+9)*8)(3)
+ stfd fp23,((JB_FPRS+9)*8)(3)
+ std r24,((JB_GPRS+10)*8)(3)
+ stfd fp24,((JB_FPRS+10)*8)(3)
+ std r25,((JB_GPRS+11)*8)(3)
+ stfd fp25,((JB_FPRS+11)*8)(3)
+ std r26,((JB_GPRS+12)*8)(3)
+ stfd fp26,((JB_FPRS+12)*8)(3)
+ std r27,((JB_GPRS+13)*8)(3)
+ stfd fp27,((JB_FPRS+13)*8)(3)
+ std r28,((JB_GPRS+14)*8)(3)
+ stfd fp28,((JB_FPRS+14)*8)(3)
+ std r29,((JB_GPRS+15)*8)(3)
+ stfd fp29,((JB_FPRS+15)*8)(3)
+ std r30,((JB_GPRS+16)*8)(3)
+ stfd fp30,((JB_FPRS+16)*8)(3)
+ std r31,((JB_GPRS+17)*8)(3)
+ stfd fp31,((JB_FPRS+17)*8)(3)
+#ifndef __NO_VMX__
+ ld r6,.LC__dl_hwcap@toc(r2)
+# ifdef SHARED
+ /* Load _rtld-global._dl_hwcap. */
+ ld r6,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r6)
+# else
+ ld r6,0(r6) /* Load extern _dl_hwcap. */
+# endif
+ andis. r6,r6,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ beq L(no_vmx)
+ la r5,((JB_VRS)*8)(3)
+ andi. r6,r5,0xf
+ mfspr r0,VRSAVE
+ stw r0,((JB_VRSAVE)*8)(3)
+ addi r6,r5,16
+ beq+ L(aligned_save_vmx)
+ lvsr v0,0,r5
+ vspltisb v1,-1 /* set v1 to all 1's */
+ vspltisb v2,0 /* set v2 to all 0's */
+ vperm v3,v2,v1,v0 /* v3 contains shift mask with num all 1 bytes
+ on left = misalignment */
+
+
+ /* Special case for v20 we need to preserve what is in save area
+ below v20 before obliterating it */
+ lvx v5,0,r5
+ vperm v20,v20,v20,v0
+ vsel v5,v5,v20,v3
+ vsel v20,v20,v2,v3
+ stvx v5,0,r5
+
+# define save_2vmx_partial(savevr,prev_savevr,hivr,shiftvr,maskvr,savegpr,addgpr) \
+ addi addgpr,addgpr,32; \
+ vperm savevr,savevr,savevr,shiftvr; \
+ vsel hivr,prev_savevr,savevr,maskvr; \
+ stvx hivr,0,savegpr;
+
+ save_2vmx_partial(v21,v20,v5,v0,v3,r6,r5)
+ save_2vmx_partial(v22,v21,v5,v0,v3,r5,r6)
+ save_2vmx_partial(v23,v22,v5,v0,v3,r6,r5)
+ save_2vmx_partial(v24,v23,v5,v0,v3,r5,r6)
+ save_2vmx_partial(v25,v24,v5,v0,v3,r6,r5)
+ save_2vmx_partial(v26,v25,v5,v0,v3,r5,r6)
+ save_2vmx_partial(v27,v26,v5,v0,v3,r6,r5)
+ save_2vmx_partial(v28,v27,v5,v0,v3,r5,r6)
+ save_2vmx_partial(v29,v28,v5,v0,v3,r6,r5)
+ save_2vmx_partial(v30,v29,v5,v0,v3,r5,r6)
+
+ /* Special case for r31 we need to preserve what is in save area
+ above v31 before obliterating it */
+ addi r5,r5,32
+ vperm v31,v31,v31,v0
+ lvx v4,0,r5
+ vsel v5,v30,v31,v3
+ stvx v5,0,r6
+ vsel v4,v31,v4,v3
+ stvx v4,0,r5
+ b L(no_vmx)
+
+L(aligned_save_vmx):
+ stvx 20,0,r5
+ addi r5,r5,32
+ stvx 21,0,r6
+ addi r6,r6,32
+ stvx 22,0,r5
+ addi r5,r5,32
+ stvx 23,0,r6
+ addi r6,r6,32
+ stvx 24,0,r5
+ addi r5,r5,32
+ stvx 25,0,r6
+ addi r6,r6,32
+ stvx 26,0,r5
+ addi r5,r5,32
+ stvx 27,0,r6
+ addi r6,r6,32
+ stvx 28,0,r5
+ addi r5,r5,32
+ stvx 29,0,r6
+ addi r6,r6,32
+ stvx 30,0,r5
+ stvx 31,0,r6
+L(no_vmx):
+#else
+ li r6,0
+#endif
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ li r3,0
+ blr
+#else
+ b JUMPTARGET (BP_SYM (__sigjmp_save))
+#endif
+END (BP_SYM (__sigsetjmp))
diff --git a/libc/sysdeps/powerpc/powerpc64/setjmp.S b/libc/sysdeps/powerpc/powerpc64/setjmp.S
new file mode 100644
index 000000000..acbf3728e
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/setjmp.S
@@ -0,0 +1,45 @@
+/* AltiVec (new) version of setjmp for PowerPC.
+ Copyright (C) 1995-97, 1999-2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <libc-symbols.h>
+#include <rtld-global-offsets.h>
+#include <shlib-compat.h>
+
+#if defined NOT_IN_libc
+/* Build a non-versioned object for rtld-*. */
+# include "setjmp-common.S"
+
+#else /* !NOT_IN_libc */
+/* Build a versioned object for libc. */
+default_symbol_version (__vmx__sigsetjmp,__sigsetjmp,GLIBC_2.3.4)
+# define __sigsetjmp __vmx__sigsetjmp
+# define __sigjmp_save __vmx__sigjmp_save
+# include "setjmp-common.S"
+
+# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
+# undef __sigsetjmp
+# undef __sigjmp_save
+# undef JB_SIZE
+# define __NO_VMX__
+symbol_version (__novmx__sigsetjmp,__sigsetjmp,GLIBC_2.3)
+# define __sigsetjmp __novmx__sigsetjmp
+# define __sigjmp_save __novmx__sigjmp_save
+# include "setjmp-common.S"
+# endif
+#endif /* !NOT_IN_libc */
diff --git a/libc/sysdeps/powerpc/powerpc64/stpcpy.S b/libc/sysdeps/powerpc/powerpc64/stpcpy.S
new file mode 100644
index 000000000..cc7a6ab66
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/stpcpy.S
@@ -0,0 +1,123 @@
+/* Optimized stpcpy implementation for PowerPC64.
+ Copyright (C) 1997, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* See strlen.s for comments on how the end-of-string testing works. */
+
+/* char * [r3] stpcpy (char *dest [r3], const char *src [r4]) */
+
+EALIGN (BP_SYM (__stpcpy), 4, 0)
+ CALL_MCOUNT 2
+
+#define rTMP r0
+#define rRTN r3
+#if __BOUNDED_POINTERS__
+# define rDEST r4 /* pointer to previous word in dest */
+# define rSRC r5 /* pointer to previous word in src */
+# define rLOW r11
+# define rHIGH r12
+#else
+# define rDEST r3 /* pointer to previous word in dest */
+# define rSRC r4 /* pointer to previous word in src */
+#endif
+#define rWORD r6 /* current word from src */
+#define rFEFE r7 /* 0xfefefeff */
+#define r7F7F r8 /* 0x7f7f7f7f */
+#define rNEG r9 /* ~(word in src | 0x7f7f7f7f) */
+#define rALT r10 /* alternate word from src */
+
+ CHECK_BOUNDS_LOW (rSRC, rLOW, rHIGH)
+ CHECK_BOUNDS_LOW (rDEST, rLOW, rHIGH)
+ STORE_RETURN_BOUNDS (rLOW, rHIGH)
+
+ or rTMP, rSRC, rDEST
+ clrldi. rTMP, rTMP, 62
+ addi rDEST, rDEST, -4
+ bne L(unaligned)
+
+ lis rFEFE, -0x101
+ lis r7F7F, 0x7f7f
+ lwz rWORD, 0(rSRC)
+ addi rFEFE, rFEFE, -0x101
+ addi r7F7F, r7F7F, 0x7f7f
+ b L(g2)
+
+L(g0): lwzu rALT, 4(rSRC)
+ stwu rWORD, 4(rDEST)
+ add rTMP, rFEFE, rALT
+ nor rNEG, r7F7F, rALT
+ and. rTMP, rTMP, rNEG
+ bne- L(g1)
+ lwzu rWORD, 4(rSRC)
+ stwu rALT, 4(rDEST)
+L(g2): add rTMP, rFEFE, rWORD
+ nor rNEG, r7F7F, rWORD
+ and. rTMP, rTMP, rNEG
+ beq+ L(g0)
+
+ mr rALT, rWORD
+/* We've hit the end of the string. Do the rest byte-by-byte. */
+L(g1): rlwinm. rTMP, rALT, 8, 24, 31
+ stbu rTMP, 4(rDEST)
+ beqlr-
+ rlwinm. rTMP, rALT, 16, 24, 31
+ stbu rTMP, 1(rDEST)
+ beqlr-
+ rlwinm. rTMP, rALT, 24, 24, 31
+ stbu rTMP, 1(rDEST)
+ beqlr-
+ stbu rALT, 1(rDEST)
+ CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt)
+ STORE_RETURN_VALUE (rDEST)
+ blr
+
+/* Oh well. In this case, we just do a byte-by-byte copy. */
+ .align 4
+ nop
+L(unaligned):
+ lbz rWORD, 0(rSRC)
+ addi rDEST, rDEST, 3
+ cmpwi rWORD, 0
+ beq- L(u2)
+
+L(u0): lbzu rALT, 1(rSRC)
+ stbu rWORD, 1(rDEST)
+ cmpwi rALT, 0
+ beq- L(u1)
+ nop /* Let 601 load start of loop. */
+ lbzu rWORD, 1(rSRC)
+ stbu rALT, 1(rDEST)
+ cmpwi rWORD, 0
+ bne+ L(u0)
+L(u2): stbu rWORD, 1(rDEST)
+ CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt)
+ STORE_RETURN_VALUE (rDEST)
+ blr
+L(u1): stbu rALT, 1(rDEST)
+ CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt)
+ STORE_RETURN_VALUE (rDEST)
+ blr
+END (BP_SYM (__stpcpy))
+
+weak_alias (BP_SYM (__stpcpy), BP_SYM (stpcpy))
+libc_hidden_def (__stpcpy)
+libc_hidden_builtin_def (stpcpy)
diff --git a/libc/sysdeps/powerpc/powerpc64/strchr.S b/libc/sysdeps/powerpc/powerpc64/strchr.S
new file mode 100644
index 000000000..93ea61e49
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/strchr.S
@@ -0,0 +1,142 @@
+/* Optimized strchr implementation for PowerPC64.
+ Copyright (C) 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* See strlen.s for comments on how this works. */
+
+/* char * [r3] strchr (const char *s [r3] , int c [r4] ) */
+
+ENTRY (BP_SYM (strchr))
+ CALL_MCOUNT 2
+
+#define rTMP1 r0
+#define rRTN r3 /* outgoing result */
+/* Note: The Bounded pointer support in this code is broken. This code
+ was inherited from PPC32 and and that support was never completed.
+ Currently PPC gcc does not support -fbounds-check or -fbounded-pointers.
+ These artifacts are left in the code as a reminder in case we need
+ bounded pointer support in the future. */
+#if __BOUNDED_POINTERS__
+# define rSTR r4
+# define rCHR r5 /* byte we're looking for, spread over the whole word */
+# define rWORD r8 /* the current word */
+#else
+# define rSTR r8 /* current word pointer */
+# define rCHR r4 /* byte we're looking for, spread over the whole word */
+# define rWORD r5 /* the current word */
+#endif
+#define rCLZB rCHR /* leading zero byte count */
+#define rFEFE r6 /* constant 0xfefefefefefefeff (-0x0101010101010101) */
+#define r7F7F r7 /* constant 0x7f7f7f7f7f7f7f7f */
+#define rTMP2 r9
+#define rIGN r10 /* number of bits we should ignore in the first word */
+#define rMASK r11 /* mask with the bits to ignore set to 0 */
+#define rTMP3 r12
+
+ CHECK_BOUNDS_LOW (rSTR, rTMP1, rTMP2)
+ STORE_RETURN_BOUNDS (rTMP1, rTMP2)
+
+ dcbt 0,rRTN
+ rlwimi rCHR, rCHR, 8, 16, 23
+ li rMASK, -1
+ rlwimi rCHR, rCHR, 16, 0, 15
+ rlwinm rIGN, rRTN, 3, 26, 28
+ insrdi rCHR, rCHR, 32, 0
+ lis rFEFE, -0x101
+ lis r7F7F, 0x7f7f
+ clrrdi rSTR, rRTN, 3
+ addi rFEFE, rFEFE, -0x101
+ addi r7F7F, r7F7F, 0x7f7f
+ sldi rTMP1, rFEFE, 32
+ insrdi r7F7F, r7F7F, 32, 0
+ add rFEFE, rFEFE, rTMP1
+/* Test the first (partial?) word. */
+ ld rWORD, 0(rSTR)
+ srd rMASK, rMASK, rIGN
+ orc rWORD, rWORD, rMASK
+ add rTMP1, rFEFE, rWORD
+ nor rTMP2, r7F7F, rWORD
+ and. rTMP1, rTMP1, rTMP2
+ xor rTMP3, rCHR, rWORD
+ orc rTMP3, rTMP3, rMASK
+ b L(loopentry)
+
+/* The loop. */
+
+L(loop):ldu rWORD, 8(rSTR)
+ and. rTMP1, rTMP1, rTMP2
+/* Test for 0. */
+ add rTMP1, rFEFE, rWORD
+ nor rTMP2, r7F7F, rWORD
+ bne L(foundit)
+ and. rTMP1, rTMP1, rTMP2
+/* Start test for the bytes we're looking for. */
+ xor rTMP3, rCHR, rWORD
+L(loopentry):
+ add rTMP1, rFEFE, rTMP3
+ nor rTMP2, r7F7F, rTMP3
+ beq L(loop)
+/* There is a zero byte in the word, but may also be a matching byte (either
+ before or after the zero byte). In fact, we may be looking for a
+ zero byte, in which case we return a match. We guess that this hasn't
+ happened, though. */
+L(missed):
+ and. rTMP1, rTMP1, rTMP2
+ li rRTN, 0
+ STORE_RETURN_VALUE (rSTR)
+ beqlr
+/* It did happen. Decide which one was first...
+ I'm not sure if this is actually faster than a sequence of
+ rotates, compares, and branches (we use it anyway because it's shorter). */
+ and rFEFE, r7F7F, rWORD
+ or rMASK, r7F7F, rWORD
+ and rTMP1, r7F7F, rTMP3
+ or rIGN, r7F7F, rTMP3
+ add rFEFE, rFEFE, r7F7F
+ add rTMP1, rTMP1, r7F7F
+ nor rWORD, rMASK, rFEFE
+ nor rTMP2, rIGN, rTMP1
+ cmpld rWORD, rTMP2
+ bgtlr
+ cntlzd rCLZB, rTMP2
+ srdi rCLZB, rCLZB, 3
+ add rRTN, rSTR, rCLZB
+ CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, tdlge)
+ STORE_RETURN_VALUE (rSTR)
+ blr
+
+L(foundit):
+ and rTMP1, r7F7F, rTMP3
+ or rIGN, r7F7F, rTMP3
+ add rTMP1, rTMP1, r7F7F
+ nor rTMP2, rIGN, rTMP1
+ cntlzd rCLZB, rTMP2
+ subi rSTR, rSTR, 8
+ srdi rCLZB, rCLZB, 3
+ add rRTN, rSTR, rCLZB
+ CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, tdlge)
+ STORE_RETURN_VALUE (rSTR)
+ blr
+END (BP_SYM (strchr))
+
+weak_alias (BP_SYM (strchr), BP_SYM (index))
+libc_hidden_builtin_def (strchr)
diff --git a/libc/sysdeps/powerpc/powerpc64/strcmp.S b/libc/sysdeps/powerpc/powerpc64/strcmp.S
new file mode 100644
index 000000000..4d7eb21bf
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/strcmp.S
@@ -0,0 +1,148 @@
+/* Optimized strcmp implementation for PowerPC64.
+ Copyright (C) 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* See strlen.s for comments on how the end-of-string testing works. */
+
+/* int [r3] strcmp (const char *s1 [r3], const char *s2 [r4]) */
+
+EALIGN (BP_SYM(strcmp), 4, 0)
+ CALL_MCOUNT 2
+
+#define rTMP r0
+#define rRTN r3
+#define rSTR1 r3 /* first string arg */
+#define rSTR2 r4 /* second string arg */
+/* Note: The Bounded pointer support in this code is broken. This code
+ was inherited from PPC32 and and that support was never completed.
+ Current PPC gcc does not support -fbounds-check or -fbounded-pointers.
+ These artifacts are left in the code as a reminder in case we need
+ bounded pointer support in the future. */
+#if __BOUNDED_POINTERS__
+# define rHIGH1 r11
+# define rHIGH2 r12
+#endif
+#define rWORD1 r5 /* current word in s1 */
+#define rWORD2 r6 /* current word in s2 */
+#define rFEFE r7 /* constant 0xfefefefefefefeff (-0x0101010101010101) */
+#define r7F7F r8 /* constant 0x7f7f7f7f7f7f7f7f */
+#define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
+#define rBITDIF r10 /* bits that differ in s1 & s2 words */
+
+ CHECK_BOUNDS_LOW (rSTR1, rTMP, rHIGH1)
+ CHECK_BOUNDS_LOW (rSTR2, rTMP, rHIGH2)
+
+ dcbt 0,rSTR1
+ or rTMP, rSTR2, rSTR1
+ dcbt 0,rSTR2
+ clrldi. rTMP, rTMP, 61
+ lis rFEFE, -0x101
+ bne L(unaligned)
+
+ ld rWORD1, 0(rSTR1)
+ ld rWORD2, 0(rSTR2)
+ lis r7F7F, 0x7f7f
+ addi rFEFE, rFEFE, -0x101
+ addi r7F7F, r7F7F, 0x7f7f
+ sldi rTMP, rFEFE, 32
+ insrdi r7F7F, r7F7F, 32, 0
+ add rFEFE, rFEFE, rTMP
+ b L(g1)
+
+L(g0): ldu rWORD1, 8(rSTR1)
+ bne cr1, L(different)
+ ldu rWORD2, 8(rSTR2)
+L(g1): add rTMP, rFEFE, rWORD1
+ nor rNEG, r7F7F, rWORD1
+
+ and. rTMP, rTMP, rNEG
+ cmpd cr1, rWORD1, rWORD2
+ beq+ L(g0)
+L(endstring):
+/* OK. We've hit the end of the string. We need to be careful that
+ we don't compare two strings as different because of gunk beyond
+ the end of the strings... */
+ and rTMP, r7F7F, rWORD1
+ beq cr1, L(equal)
+ add rTMP, rTMP, r7F7F
+ xor. rBITDIF, rWORD1, rWORD2
+
+ andc rNEG, rNEG, rTMP
+ blt- L(highbit)
+ cntlzd rBITDIF, rBITDIF
+ cntlzd rNEG, rNEG
+ addi rNEG, rNEG, 7
+ cmpd cr1, rNEG, rBITDIF
+ sub rRTN, rWORD1, rWORD2
+ blt- cr1, L(equal)
+ sradi rRTN, rRTN, 63
+ ori rRTN, rRTN, 1
+ blr
+L(equal):
+ li rRTN, 0
+ /* GKM FIXME: check high bounds. */
+ blr
+
+L(different):
+ ld rWORD1, -8(rSTR1)
+ xor. rBITDIF, rWORD1, rWORD2
+ sub rRTN, rWORD1, rWORD2
+ blt- L(highbit)
+ sradi rRTN, rRTN, 63
+ ori rRTN, rRTN, 1
+ blr
+L(highbit):
+ srdi rWORD2, rWORD2, 56
+ srdi rWORD1, rWORD1, 56
+ sub rRTN, rWORD1, rWORD2
+ /* GKM FIXME: check high bounds. */
+ blr
+
+
+/* Oh well. In this case, we just do a byte-by-byte comparison. */
+ .align 4
+L(unaligned):
+ lbz rWORD1, 0(rSTR1)
+ lbz rWORD2, 0(rSTR2)
+ b L(u1)
+
+L(u0): lbzu rWORD1, 1(rSTR1)
+ bne- L(u4)
+ lbzu rWORD2, 1(rSTR2)
+L(u1): cmpwi cr1, rWORD1, 0
+ beq- cr1, L(u3)
+ cmpd rWORD1, rWORD2
+ bne- L(u3)
+ lbzu rWORD1, 1(rSTR1)
+ lbzu rWORD2, 1(rSTR2)
+ cmpdi cr1, rWORD1, 0
+ cmpd rWORD1, rWORD2
+ bne+ cr1, L(u0)
+L(u3): sub rRTN, rWORD1, rWORD2
+ /* GKM FIXME: check high bounds. */
+ blr
+L(u4): lbz rWORD1, -1(rSTR1)
+ sub rRTN, rWORD1, rWORD2
+ /* GKM FIXME: check high bounds. */
+ blr
+END (BP_SYM (strcmp))
+libc_hidden_builtin_def (strcmp)
diff --git a/libc/sysdeps/powerpc/powerpc64/strcpy.S b/libc/sysdeps/powerpc/powerpc64/strcpy.S
new file mode 100644
index 000000000..e9e9fc78c
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/strcpy.S
@@ -0,0 +1,145 @@
+/* Optimized strcpy implementation for PowerPC64.
+ Copyright (C) 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* See strlen.s for comments on how the end-of-string testing works. */
+
+/* char * [r3] strcpy (char *dest [r3], const char *src [r4]) */
+
+EALIGN (BP_SYM (strcpy), 4, 0)
+ CALL_MCOUNT 2
+
+#define rTMP r0
+#define rRTN r3 /* incoming DEST arg preserved as result */
+/* Note. The Bounded pointer support in this code is broken. This code
+ was inherited from PPC32 and and that support was never completed.
+ Current PPC gcc does not support -fbounds-check or -fbounded-pointers.
+ These artifacts are left in the code as a reminder in case we need
+ bounded pointer support in the future. */
+#if __BOUNDED_POINTERS__
+# define rDEST r4 /* pointer to previous word in dest */
+# define rSRC r5 /* pointer to previous word in src */
+# define rLOW r11
+# define rHIGH r12
+#else
+# define rSRC r4 /* pointer to previous word in src */
+# define rDEST r5 /* pointer to previous word in dest */
+#endif
+#define rWORD r6 /* current word from src */
+#define rFEFE r7 /* constant 0xfefefefefefefeff (-0x0101010101010101) */
+#define r7F7F r8 /* constant 0x7f7f7f7f7f7f7f7f */
+#define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
+#define rALT r10 /* alternate word from src */
+
+ CHECK_BOUNDS_LOW (rSRC, rLOW, rHIGH)
+ CHECK_BOUNDS_LOW (rDEST, rLOW, rHIGH)
+ STORE_RETURN_BOUNDS (rLOW, rHIGH)
+
+ dcbt 0,rSRC
+ or rTMP, rSRC, rRTN
+ clrldi. rTMP, rTMP, 61
+#if __BOUNDED_POINTERS__
+ addi rDEST, rDEST, -8
+#else
+ addi rDEST, rRTN, -8
+#endif
+ dcbtst 0,rRTN
+ bne L(unaligned)
+
+ lis rFEFE, -0x101
+ lis r7F7F, 0x7f7f
+ ld rWORD, 0(rSRC)
+ addi rFEFE, rFEFE, -0x101
+ addi r7F7F, r7F7F, 0x7f7f
+ sldi rTMP, rFEFE, 32
+ insrdi r7F7F, r7F7F, 32, 0
+ add rFEFE, rFEFE, rTMP
+ b L(g2)
+
+L(g0): ldu rALT, 8(rSRC)
+ stdu rWORD, 8(rDEST)
+ add rTMP, rFEFE, rALT
+ nor rNEG, r7F7F, rALT
+ and. rTMP, rTMP, rNEG
+ bne- L(g1)
+ ldu rWORD, 8(rSRC)
+ stdu rALT, 8(rDEST)
+L(g2): add rTMP, rFEFE, rWORD
+ nor rNEG, r7F7F, rWORD
+ and. rTMP, rTMP, rNEG
+ beq+ L(g0)
+
+ mr rALT, rWORD
+/* We've hit the end of the string. Do the rest byte-by-byte. */
+L(g1):
+ extrdi. rTMP, rALT, 8, 0
+ stb rTMP, 8(rDEST)
+ beqlr-
+ extrdi. rTMP, rALT, 8, 8
+ stb rTMP, 9(rDEST)
+ beqlr-
+ extrdi. rTMP, rALT, 8, 16
+ stb rTMP, 10(rDEST)
+ beqlr-
+ extrdi. rTMP, rALT, 8, 24
+ stb rTMP, 11(rDEST)
+ beqlr-
+ extrdi. rTMP, rALT, 8, 32
+ stb rTMP, 12(rDEST)
+ beqlr-
+ extrdi. rTMP, rALT, 8, 40
+ stb rTMP, 13(rDEST)
+ beqlr-
+ extrdi. rTMP, rALT, 8, 48
+ stb rTMP, 14(rDEST)
+ beqlr-
+ stb rALT, 15(rDEST)
+ /* GKM FIXME: check high bound. */
+ blr
+
+/* Oh well. In this case, we just do a byte-by-byte copy. */
+ .align 4
+ nop
+L(unaligned):
+ lbz rWORD, 0(rSRC)
+ addi rDEST, rRTN, -1
+ cmpwi rWORD, 0
+ beq- L(u2)
+
+L(u0): lbzu rALT, 1(rSRC)
+ stbu rWORD, 1(rDEST)
+ cmpwi rALT, 0
+ beq- L(u1)
+ nop /* Let 601 load start of loop. */
+ lbzu rWORD, 1(rSRC)
+ stbu rALT, 1(rDEST)
+ cmpwi rWORD, 0
+ bne+ L(u0)
+L(u2): stb rWORD, 1(rDEST)
+ /* GKM FIXME: check high bound. */
+ blr
+L(u1): stb rALT, 1(rDEST)
+ /* GKM FIXME: check high bound. */
+ blr
+
+END (BP_SYM (strcpy))
+libc_hidden_builtin_def (strcpy)
diff --git a/libc/sysdeps/powerpc/powerpc64/strlen.S b/libc/sysdeps/powerpc/powerpc64/strlen.S
new file mode 100644
index 000000000..4c1385aea
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/strlen.S
@@ -0,0 +1,175 @@
+/* Optimized strlen implementation for PowerPC64.
+ Copyright (C) 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* The algorithm here uses the following techniques:
+
+ 1) Given a word 'x', we can test to see if it contains any 0 bytes
+ by subtracting 0x01010101, and seeing if any of the high bits of each
+ byte changed from 0 to 1. This works because the least significant
+ 0 byte must have had no incoming carry (otherwise it's not the least
+ significant), so it is 0x00 - 0x01 == 0xff. For all other
+ byte values, either they have the high bit set initially, or when
+ 1 is subtracted you get a value in the range 0x00-0x7f, none of which
+ have their high bit set. The expression here is
+ (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
+ there were no 0x00 bytes in the word.
+
+ 2) Given a word 'x', we can test to see _which_ byte was zero by
+ calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
+ This produces 0x80 in each byte that was zero, and 0x00 in all
+ the other bytes. The '| 0x7f7f7f7f' clears the low 7 bits in each
+ byte, and the '| x' part ensures that bytes with the high bit set
+ produce 0x00. The addition will carry into the high bit of each byte
+ iff that byte had one of its low 7 bits set. We can then just see
+ which was the most significant bit set and divide by 8 to find how
+ many to add to the index.
+ This is from the book 'The PowerPC Compiler Writer's Guide',
+ by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
+
+ We deal with strings not aligned to a word boundary by taking the
+ first word and ensuring that bytes not part of the string
+ are treated as nonzero. To allow for memory latency, we unroll the
+ loop a few times, being careful to ensure that we do not read ahead
+ across cache line boundaries.
+
+ Questions to answer:
+ 1) How long are strings passed to strlen? If they're often really long,
+ we should probably use cache management instructions and/or unroll the
+ loop more. If they're often quite short, it might be better to use
+ fact (2) in the inner loop than have to recalculate it.
+ 2) How popular are bytes with the high bit set? If they are very rare,
+ on some processors it might be useful to use the simpler expression
+ ~((x - 0x01010101) | 0x7f7f7f7f) (that is, on processors with only one
+ ALU), but this fails when any character has its high bit set.
+
+ Answer:
+ 1) Added a Data Cache Block Touch early to prefetch the first 128
+ byte cache line. Adding dcbt instructions to the loop would not be
+ effective since most strings will be shorter than the cache line.*/
+
+/* Some notes on register usage: Under the SVR4 ABI, we can use registers
+ 0 and 3 through 12 (so long as we don't call any procedures) without
+ saving them. We can also use registers 14 through 31 if we save them.
+ We can't use r1 (it's the stack pointer), r2 nor r13 because the user
+ program may expect them to hold their usual value if we get sent
+ a signal. Integer parameters are passed in r3 through r10.
+ We can use condition registers cr0, cr1, cr5, cr6, and cr7 without saving
+ them, the others we must save. */
+
+/* int [r3] strlen (char *s [r3]) */
+
+ENTRY (BP_SYM (strlen))
+ CALL_MCOUNT 1
+
+#define rTMP1 r0
+#define rRTN r3 /* incoming STR arg, outgoing result */
+#define rSTR r4 /* current string position */
+#define rPADN r5 /* number of padding bits we prepend to the
+ string to make it start at a word boundary */
+#define rFEFE r6 /* constant 0xfefefefefefefeff (-0x0101010101010101) */
+#define r7F7F r7 /* constant 0x7f7f7f7f7f7f7f7f */
+#define rWORD1 r8 /* current string doubleword */
+#define rWORD2 r9 /* next string doubleword */
+#define rMASK r9 /* mask for first string doubleword */
+#define rTMP2 r10
+#define rTMP3 r11
+#define rTMP4 r12
+
+/* Note: The Bounded pointer support in this code is broken. This code
+ was inherited from PPC32 and and that support was never completed.
+ Current PPC gcc does not support -fbounds-check or -fbounded-pointers.
+ These artifacts are left in the code as a reminder in case we need
+ bounded pointer support in the future. */
+ CHECK_BOUNDS_LOW (rRTN, rTMP1, rTMP2)
+
+ dcbt 0,rRTN
+ clrrdi rSTR, rRTN, 3
+ lis r7F7F, 0x7f7f
+ rlwinm rPADN, rRTN, 3, 26, 28
+ ld rWORD1, 0(rSTR)
+ addi r7F7F, r7F7F, 0x7f7f
+ li rMASK, -1
+ insrdi r7F7F, r7F7F, 32, 0
+/* That's the setup done, now do the first pair of doublewords.
+ We make an exception and use method (2) on the first two doublewords,
+ to reduce overhead. */
+ srd rMASK, rMASK, rPADN
+ and rTMP1, r7F7F, rWORD1
+ or rTMP2, r7F7F, rWORD1
+ lis rFEFE, -0x101
+ add rTMP1, rTMP1, r7F7F
+ addi rFEFE, rFEFE, -0x101
+ nor rTMP1, rTMP2, rTMP1
+ and. rWORD1, rTMP1, rMASK
+ mtcrf 0x01, rRTN
+ bne L(done0)
+ sldi rTMP1, rFEFE, 32
+ add rFEFE, rFEFE, rTMP1
+/* Are we now aligned to a doubleword boundary? */
+ bt 28, L(loop)
+
+/* Handle second doubleword of pair. */
+ ldu rWORD1, 8(rSTR)
+ and rTMP1, r7F7F, rWORD1
+ or rTMP2, r7F7F, rWORD1
+ add rTMP1, rTMP1, r7F7F
+ nor. rWORD1, rTMP2, rTMP1
+ bne L(done0)
+
+/* The loop. */
+
+L(loop):
+ ld rWORD1, 8(rSTR)
+ ldu rWORD2, 16(rSTR)
+ add rTMP1, rFEFE, rWORD1
+ nor rTMP2, r7F7F, rWORD1
+ and. rTMP1, rTMP1, rTMP2
+ add rTMP3, rFEFE, rWORD2
+ nor rTMP4, r7F7F, rWORD2
+ bne L(done1)
+ and. rTMP1, rTMP3, rTMP4
+ beq L(loop)
+
+ and rTMP1, r7F7F, rWORD2
+ add rTMP1, rTMP1, r7F7F
+ andc rWORD1, rTMP4, rTMP1
+ b L(done0)
+
+L(done1):
+ and rTMP1, r7F7F, rWORD1
+ subi rSTR, rSTR, 8
+ add rTMP1, rTMP1, r7F7F
+ andc rWORD1, rTMP2, rTMP1
+
+/* When we get to here, rSTR points to the first doubleword in the string that
+ contains a zero byte, and the most significant set bit in rWORD1 is in that
+ byte. */
+L(done0):
+ cntlzd rTMP3, rWORD1
+ subf rTMP1, rRTN, rSTR
+ srdi rTMP3, rTMP3, 3
+ add rRTN, rTMP1, rTMP3
+ /* GKM FIXME: check high bound. */
+ blr
+END (BP_SYM (strlen))
+libc_hidden_builtin_def (strlen)
diff --git a/libc/sysdeps/powerpc/powerpc64/strncmp.S b/libc/sysdeps/powerpc/powerpc64/strncmp.S
new file mode 100644
index 000000000..34479e2e9
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/strncmp.S
@@ -0,0 +1,165 @@
+/* Optimized strcmp implementation for PowerPC64.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* See strlen.s for comments on how the end-of-string testing works. */
+
+/* int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5]) */
+
+EALIGN (BP_SYM(strncmp), 4, 0)
+ CALL_MCOUNT 3
+
+#define rTMP r0
+#define rRTN r3
+#define rSTR1 r3 /* first string arg */
+#define rSTR2 r4 /* second string arg */
+#define rN r5 /* max string length */
+/* Note: The Bounded pointer support in this code is broken. This code
+ was inherited from PPC32 and and that support was never completed.
+ Current PPC gcc does not support -fbounds-check or -fbounded-pointers. */
+#define rWORD1 r6 /* current word in s1 */
+#define rWORD2 r7 /* current word in s2 */
+#define rFEFE r8 /* constant 0xfefefefefefefeff (-0x0101010101010101) */
+#define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */
+#define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
+#define rBITDIF r11 /* bits that differ in s1 & s2 words */
+
+ dcbt 0,rSTR1
+ or rTMP, rSTR2, rSTR1
+ lis r7F7F, 0x7f7f
+ dcbt 0,rSTR2
+ clrldi. rTMP, rTMP, 61
+ cmpldi cr1, rN, 0
+ lis rFEFE, -0x101
+ bne L(unaligned)
+/* We are doubleword alligned so set up for two loops. first a double word
+ loop, then fall into the byte loop if any residual. */
+ srdi. rTMP, rN, 3
+ clrldi rN, rN, 61
+ addi rFEFE, rFEFE, -0x101
+ addi r7F7F, r7F7F, 0x7f7f
+ cmpldi cr1, rN, 0
+ beq L(unaligned)
+
+ mtctr rTMP /* Power4 wants mtctr 1st in dispatch group. */
+ ld rWORD1, 0(rSTR1)
+ ld rWORD2, 0(rSTR2)
+ sldi rTMP, rFEFE, 32
+ insrdi r7F7F, r7F7F, 32, 0
+ add rFEFE, rFEFE, rTMP
+ b L(g1)
+
+L(g0):
+ ldu rWORD1, 8(rSTR1)
+ bne- cr1, L(different)
+ ldu rWORD2, 8(rSTR2)
+L(g1): add rTMP, rFEFE, rWORD1
+ nor rNEG, r7F7F, rWORD1
+ bdz L(tail)
+ and. rTMP, rTMP, rNEG
+ cmpd cr1, rWORD1, rWORD2
+ beq+ L(g0)
+
+/* OK. We've hit the end of the string. We need to be careful that
+ we don't compare two strings as different because of gunk beyond
+ the end of the strings... */
+
+L(endstring):
+ and rTMP, r7F7F, rWORD1
+ beq cr1, L(equal)
+ add rTMP, rTMP, r7F7F
+ xor. rBITDIF, rWORD1, rWORD2
+
+ andc rNEG, rNEG, rTMP
+ blt- L(highbit)
+ cntlzd rBITDIF, rBITDIF
+ cntlzd rNEG, rNEG
+ addi rNEG, rNEG, 7
+ cmpd cr1, rNEG, rBITDIF
+ sub rRTN, rWORD1, rWORD2
+ blt- cr1, L(equal)
+ sradi rRTN, rRTN, 63
+ ori rRTN, rRTN, 1
+ blr
+L(equal):
+ li rRTN, 0
+ blr
+
+L(different):
+ ldu rWORD1, -8(rSTR1)
+ xor. rBITDIF, rWORD1, rWORD2
+ sub rRTN, rWORD1, rWORD2
+ blt- L(highbit)
+ sradi rRTN, rRTN, 63
+ ori rRTN, rRTN, 1
+ blr
+L(highbit):
+ srdi rWORD2, rWORD2, 56
+ srdi rWORD1, rWORD1, 56
+ sub rRTN, rWORD1, rWORD2
+ blr
+
+
+/* Oh well. In this case, we just do a byte-by-byte comparison. */
+ .align 4
+L(tail):
+ and. rTMP, rTMP, rNEG
+ cmpd cr1, rWORD1, rWORD2
+ bne- L(endstring)
+ addi rSTR1, rSTR1, 8
+ bne- cr1, L(different)
+ addi rSTR2, rSTR2, 8
+ cmpldi cr1, rN, 0
+L(unaligned):
+ mtctr rN /* Power4 wants mtctr 1st in dispatch group */
+ bgt cr1, L(uz)
+L(ux):
+ li rRTN, 0
+ blr
+ .align 4
+L(uz):
+ lbz rWORD1, 0(rSTR1)
+ lbz rWORD2, 0(rSTR2)
+ nop
+ b L(u1)
+L(u0):
+ lbzu rWORD2, 1(rSTR2)
+L(u1):
+ bdz L(u3)
+ cmpdi cr1, rWORD1, 0
+ cmpd rWORD1, rWORD2
+ beq- cr1, L(u3)
+ lbzu rWORD1, 1(rSTR1)
+ bne- L(u2)
+ lbzu rWORD2, 1(rSTR2)
+ bdz L(u3)
+ cmpdi cr1, rWORD1, 0
+ cmpd rWORD1, rWORD2
+ bne- L(u3)
+ lbzu rWORD1, 1(rSTR1)
+ bne+ cr1, L(u0)
+
+L(u2): lbzu rWORD1, -1(rSTR1)
+L(u3): sub rRTN, rWORD1, rWORD2
+ blr
+END (BP_SYM (strncmp))
+libc_hidden_builtin_def (strncmp)
diff --git a/libc/sysdeps/powerpc/powerpc64/sysdep.h b/libc/sysdeps/powerpc/powerpc64/sysdep.h
new file mode 100644
index 000000000..2745d7eb7
--- /dev/null
+++ b/libc/sysdeps/powerpc/powerpc64/sysdep.h
@@ -0,0 +1,266 @@
+/* Assembly macros for 64-bit PowerPC.
+ Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdeps/powerpc/sysdep.h>
+
+#ifdef __ELF__
+
+#ifdef __ASSEMBLER__
+
+/* Support macros for CALL_MCOUNT. */
+ .macro SAVE_ARG NARG
+ .if \NARG
+ SAVE_ARG \NARG-1
+ std 2+\NARG,-72+8*(\NARG)(1)
+ .endif
+ .endm
+
+ .macro REST_ARG NARG
+ .if \NARG
+ REST_ARG \NARG-1
+ ld 2+\NARG,40+8*(\NARG)(1)
+ .endif
+ .endm
+
+/* If compiled for profiling, call `_mcount' at the start of each function.
+ see ppc-mcount.S for more details. */
+ .macro CALL_MCOUNT NARG
+#ifdef PROF
+ mflr r0
+ SAVE_ARG \NARG
+ std r0,16(r1)
+ stdu r1,-112(r1)
+ bl JUMPTARGET (_mcount)
+ ld r0,128(r1)
+ REST_ARG \NARG
+ addi r1,r1,112
+ mtlr r0
+#endif
+ .endm
+
+#ifdef USE_PPC64_OVERLAPPING_OPD
+# define OPD_ENT(name) .quad BODY_LABEL (name), .TOC.@tocbase
+#else
+# define OPD_ENT(name) .quad BODY_LABEL (name), .TOC.@tocbase, 0
+#endif
+
+#define ENTRY_1(name) \
+ .section ".text"; \
+ .type BODY_LABEL(name),@function; \
+ .globl name; \
+ .section ".opd","aw"; \
+ .align 3; \
+name##: OPD_ENT (name); \
+ .previous;
+
+#ifdef HAVE_ASM_GLOBAL_DOT_NAME
+# define DOT_LABEL(X) .##X
+# define BODY_LABEL(X) .##X
+# define ENTRY_2(name) \
+ .globl BODY_LABEL(name); \
+ ENTRY_1(name) \
+ .size name, 24;
+# define END_2(name) \
+ .size BODY_LABEL(name),.-BODY_LABEL(name);
+#else
+# define DOT_LABEL(X) X
+# define BODY_LABEL(X) .LY##X
+# define ENTRY_2(name) \
+ .type name,@function; \
+ ENTRY_1(name)
+# define END_2(name) \
+ .size name,.-BODY_LABEL(name); \
+ .size BODY_LABEL(name),.-BODY_LABEL(name);
+#endif
+
+#define ENTRY(name) \
+ ENTRY_2(name) \
+ .align ALIGNARG(2); \
+BODY_LABEL(name): \
+ cfi_startproc;
+
+#define EALIGN_W_0 /* No words to insert. */
+#define EALIGN_W_1 nop
+#define EALIGN_W_2 nop;nop
+#define EALIGN_W_3 nop;nop;nop
+#define EALIGN_W_4 EALIGN_W_3;nop
+#define EALIGN_W_5 EALIGN_W_4;nop
+#define EALIGN_W_6 EALIGN_W_5;nop
+#define EALIGN_W_7 EALIGN_W_6;nop
+
+/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+ past a 2^alignt boundary. */
+#define EALIGN(name, alignt, words) \
+ ENTRY_2(name) \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+BODY_LABEL(name): \
+ cfi_startproc;
+
+/* Local labels stripped out by the linker. */
+#undef L
+#define L(x) .L##x
+
+#define tostring(s) #s
+#define stringify(s) tostring(s)
+#define XGLUE(a,b) a##b
+#define GLUE(a,b) XGLUE(a,b)
+#define LT_LABEL(name) GLUE(.LT,name)
+#define LT_LABELSUFFIX(name,suffix) GLUE(GLUE(.LT,name),suffix)
+
+/* Support Traceback tables */
+#define TB_ASM 0x000c000000000000
+#define TB_GLOBALLINK 0x0000800000000000
+#define TB_IS_EPROL 0x0000400000000000
+#define TB_HAS_TBOFF 0x0000200000000000
+#define TB_INT_PROC 0x0000100000000000
+#define TB_HAS_CTL 0x0000080000000000
+#define TB_TOCLESS 0x0000040000000000
+#define TB_FP_PRESENT 0x0000020000000000
+#define TB_LOG_ABORT 0x0000010000000000
+#define TB_INT_HANDL 0x0000008000000000
+#define TB_NAME_PRESENT 0x0000004000000000
+#define TB_USES_ALLOCA 0x0000002000000000
+#define TB_SAVES_CR 0x0000000200000000
+#define TB_SAVES_LR 0x0000000100000000
+#define TB_STORES_BC 0x0000000080000000
+#define TB_FIXUP 0x0000000040000000
+#define TB_FP_SAVED(fprs) (((fprs) & 0x3f) << 24)
+#define TB_GPR_SAVED(gprs) (((fprs) & 0x3f) << 16)
+#define TB_FIXEDPARMS(parms) (((parms) & 0xff) << 8)
+#define TB_FLOATPARMS(parms) (((parms) & 0x7f) << 1)
+#define TB_PARMSONSTK 0x0000000000000001
+
+#define PPC_HIGHER(v) (((v) >> 32) & 0xffff)
+#define TB_DEFAULT TB_ASM | TB_HAS_TBOFF | TB_NAME_PRESENT
+
+#define TRACEBACK(name) \
+LT_LABEL(name): ; \
+ .long 0 ; \
+ .quad TB_DEFAULT ; \
+ .long LT_LABEL(name)-BODY_LABEL(name) ; \
+ .short LT_LABELSUFFIX(name,_name_end)-LT_LABELSUFFIX(name,_name_start) ; \
+LT_LABELSUFFIX(name,_name_start): ;\
+ .ascii stringify(name) ; \
+LT_LABELSUFFIX(name,_name_end): ; \
+ .align 2 ;
+
+#define TRACEBACK_MASK(name,mask) \
+LT_LABEL(name): ; \
+ .long 0 ; \
+ .quad TB_DEFAULT | mask ; \
+ .long LT_LABEL(name)-BODY_LABEL(name) ; \
+ .short LT_LABELSUFFIX(name,_name_end)-LT_LABELSUFFIX(name,_name_start) ; \
+LT_LABELSUFFIX(name,_name_start): ;\
+ .ascii stringify(name) ; \
+LT_LABELSUFFIX(name,_name_end): ; \
+ .align 2 ;
+
+/* END generates Traceback tables */
+#undef END
+#define END(name) \
+ cfi_endproc; \
+ TRACEBACK(name) \
+ END_2(name)
+
+/* This form supports more informative traceback tables */
+#define END_GEN_TB(name,mask) \
+ cfi_endproc; \
+ TRACEBACK_MASK(name,mask) \
+ END_2(name)
+
+#define DO_CALL(syscall) \
+ li 0,syscall; \
+ sc
+
+/* ppc64 is always PIC */
+#undef JUMPTARGET
+#define JUMPTARGET(name) DOT_LABEL(name)
+
+#define PSEUDO(name, syscall_name, args) \
+ .section ".text"; \
+ ENTRY (name) \
+ DO_CALL (SYS_ify (syscall_name));
+
+#define PSEUDO_RET \
+ bnslr+; \
+ b JUMPTARGET(__syscall_error)
+
+#define ret PSEUDO_RET
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
+
+#define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .section ".text"; \
+ ENTRY (name) \
+ DO_CALL (SYS_ify (syscall_name));
+
+#define PSEUDO_RET_NOERRNO \
+ blr
+
+#define ret_NOERRNO PSEUDO_RET_NOERRNO
+
+#undef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(name) \
+ END (name)
+
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .section ".text"; \
+ ENTRY (name) \
+ DO_CALL (SYS_ify (syscall_name));
+
+#define PSEUDO_RET_ERRVAL \
+ blr
+
+#define ret_ERRVAL PSEUDO_RET_ERRVAL
+
+#undef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(name) \
+ END (name)
+
+#else /* !__ASSEMBLER__ */
+
+#ifdef USE_PPC64_OVERLAPPING_OPD
+# define OPD_ENT(name) ".quad " BODY_PREFIX #name ", .TOC.@tocbase;"
+#else
+# define OPD_ENT(name) ".quad " BODY_PREFIX #name ", .TOC.@tocbase, 0;"
+#endif
+
+#ifdef HAVE_ASM_GLOBAL_DOT_NAME
+# define DOT_PREFIX "."
+# define BODY_PREFIX "."
+# define ENTRY_2(name) \
+ ".globl " BODY_PREFIX #name ";\n" \
+ ".size " #name ", 24;"
+# define END_2(name) \
+ ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
+#else
+# define DOT_PREFIX ""
+# define BODY_PREFIX ".LY"
+# define ENTRY_2(name) ".type " #name ",@function;"
+# define END_2(name) \
+ ".size " #name ",.-" BODY_PREFIX #name ";\n" \
+ ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
+#endif
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __ELF__ */
diff --git a/libc/sysdeps/powerpc/sigjmp.c b/libc/sysdeps/powerpc/sigjmp.c
new file mode 100644
index 000000000..5c8fd9eb7
--- /dev/null
+++ b/libc/sysdeps/powerpc/sigjmp.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1992, 1994, 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Versioned copy of sysdeps/generic/sigjmp.c modified for AltiVec support. */
+
+#include <shlib-compat.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <signal.h>
+
+/* This function is called by the `sigsetjmp' macro
+ before doing a `__setjmp' on ENV[0].__jmpbuf.
+ Always return zero. */
+
+int
+__vmx__sigjmp_save (sigjmp_buf env, int savemask)
+{
+ env[0].__mask_was_saved = (savemask &&
+ __sigprocmask (SIG_BLOCK, (sigset_t *) NULL,
+ &env[0].__saved_mask) == 0);
+
+ return 0;
+}
+
+strong_alias (__vmx__sigjmp_save,__sigjmp_save)
diff --git a/libc/sysdeps/powerpc/soft-fp/Makefile b/libc/sysdeps/powerpc/soft-fp/Makefile
new file mode 100644
index 000000000..ff0a19119
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/Makefile
@@ -0,0 +1,36 @@
+# Software floating-point emulation.
+# Makefile for PowerPC SVR4 ABI mandated long double utility
+# functions (_q_*).
+# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+#
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifeq ($(subdir),soft-fp)
+ifeq ($(sizeof-long-double),16)
+powerpc-quad-routines := q_add q_cmp q_cmpe q_div q_dtoq q_feq q_fge \
+ q_fgt q_fle q_flt q_fne q_itoq q_mul q_neg q_qtod q_qtoi \
+ q_qtos q_qtou q_qtoull q_qtoll q_sqrt q_stoq q_sub q_utoq \
+ q_ulltoq q_lltoq q_util
+sysdep_routines += $(powerpc-quad-routines)
+endif
+endif
+
+ifeq ($(subdir),math)
+CPPFLAGS += -I../soft-fp/
+endif
diff --git a/libc/sysdeps/powerpc/soft-fp/Subdirs b/libc/sysdeps/powerpc/soft-fp/Subdirs
new file mode 100644
index 000000000..87eadf302
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/Subdirs
@@ -0,0 +1 @@
+soft-fp
diff --git a/libc/sysdeps/powerpc/soft-fp/Versions b/libc/sysdeps/powerpc/soft-fp/Versions
new file mode 100644
index 000000000..935c9c8ef
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/Versions
@@ -0,0 +1,9 @@
+libc {
+ GLIBC_2.2 {
+ _q_add; _q_cmp; _q_cmpe; _q_div; _q_dtoq; _q_feq; _q_fge; _q_fgt;
+ _q_fle; _q_flt; _q_fne; _q_itoq; _q_mul; _q_neg; _q_qtod; _q_qtoi;
+ _q_qtos; _q_qtou; _q_sqrt; _q_stoq; _q_sub;
+ _q_utoq;
+ _q_lltoq; _q_qtoll; _q_qtoull; _q_ulltoq;
+ }
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_add.c b/libc/sysdeps/powerpc/soft-fp/q_add.c
new file mode 100644
index 000000000..80a0b3f6d
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_add.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+ Return a + b
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _q_add(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ long double c;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+ FP_UNPACK_SEMIRAW_Q(B, b);
+ FP_ADD_Q(C, A, B);
+ FP_PACK_SEMIRAW_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_cmp.c b/libc/sysdeps/powerpc/soft-fp/q_cmp.c
new file mode 100644
index 000000000..e6120ac2e
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_cmp.c
@@ -0,0 +1,41 @@
+/* Software floating-point emulation.
+ Compare a and b, return float condition code.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _q_cmp(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == -1) r = 2;
+ if (r == 3 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_cmpe.c b/libc/sysdeps/powerpc/soft-fp/q_cmpe.c
new file mode 100644
index 000000000..89499d77e
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_cmpe.c
@@ -0,0 +1,42 @@
+/* Software floating-point emulation.
+ Compare a and b, return float condition code.
+ Signal exception (unless masked) if unordered.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _q_cmpe(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == -1) r = 2;
+ if (r == 3)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_div.c b/libc/sysdeps/powerpc/soft-fp/q_div.c
new file mode 100644
index 000000000..b5299eb13
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_div.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+ Return a / b
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _q_div(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ long double c;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_Q(A, a);
+ FP_UNPACK_Q(B, b);
+ FP_DIV_Q(C, A, B);
+ FP_PACK_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_dtoq.c b/libc/sysdeps/powerpc/soft-fp/q_dtoq.c
new file mode 100644
index 000000000..baebea546
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_dtoq.c
@@ -0,0 +1,44 @@
+/* Software floating-point emulation.
+ Return (long double)(a)
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+long double _q_dtoq(const double a)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ FP_DECL_Q(C);
+ long double c;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_D(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_EXTEND(Q,D,4,2,C,A);
+#else
+ FP_EXTEND(Q,D,2,1,C,A);
+#endif
+ FP_PACK_RAW_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_feq.c b/libc/sysdeps/powerpc/soft-fp/q_feq.c
new file mode 100644
index 000000000..5e0e8196e
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_feq.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+ Return 1 if a == b
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _q_feq(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_EQ_Q(r, A, B);
+ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return !r;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_fge.c b/libc/sysdeps/powerpc/soft-fp/q_fge.c
new file mode 100644
index 000000000..c33c5c3c1
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_fge.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+ Return 1 if a >= b
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _q_fge(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == 3)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return (r <= 0);
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_fgt.c b/libc/sysdeps/powerpc/soft-fp/q_fgt.c
new file mode 100644
index 000000000..60dfed18d
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_fgt.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+ Return 1 if a > b
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _q_fgt(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == 3)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return (r == -1);
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_fle.c b/libc/sysdeps/powerpc/soft-fp/q_fle.c
new file mode 100644
index 000000000..8512431fe
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_fle.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+ Return 1 if a <= b
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _q_fle(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, B, A, -2);
+ if (r == -2)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return (r >= 0);
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_flt.c b/libc/sysdeps/powerpc/soft-fp/q_flt.c
new file mode 100644
index 000000000..eb2325678
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_flt.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+ Return 1 if a < b
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _q_flt(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == 3)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return (r == 1);
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_fne.c b/libc/sysdeps/powerpc/soft-fp/q_fne.c
new file mode 100644
index 000000000..d72061060
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_fne.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+ Return 1 if a != b
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _q_fne(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_EQ_Q(r, A, B);
+ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_itoq.c b/libc/sysdeps/powerpc/soft-fp/q_itoq.c
new file mode 100644
index 000000000..e2884005a
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_itoq.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (long double)(a)
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _q_itoq(const int a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ int b = a;
+ long double c;
+
+ FP_FROM_INT_Q(C, b, 32, unsigned int);
+ FP_PACK_RAW_Q(c, C);
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_lltoq.c b/libc/sysdeps/powerpc/soft-fp/q_lltoq.c
new file mode 100644
index 000000000..22d2e55fa
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_lltoq.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (long double)a
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _q_lltoq(const long long a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ long double c;
+ long long b = a;
+
+ FP_FROM_INT_Q(C, b, 64, unsigned long long);
+ FP_PACK_RAW_Q(c, C);
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_mul.c b/libc/sysdeps/powerpc/soft-fp/q_mul.c
new file mode 100644
index 000000000..d296caa96
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_mul.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+ Return a * b
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _q_mul(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ long double c;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_Q(A, a);
+ FP_UNPACK_Q(B, b);
+ FP_MUL_Q(C, A, B);
+ FP_PACK_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_neg.c b/libc/sysdeps/powerpc/soft-fp/q_neg.c
new file mode 100644
index 000000000..7466b5105
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_neg.c
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+ Return !a
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _q_neg(const long double a)
+{
+ FP_DECL_EX;
+ long double c = a;
+
+#if (__BYTE_ORDER == __BIG_ENDIAN)
+ ((UWtype *)&c)[0] ^= (((UWtype)1) << (W_TYPE_SIZE - 1));
+#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 64)
+ ((UWtype *)&c)[1] ^= (((UWtype)1) << (W_TYPE_SIZE - 1));
+#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 32)
+ ((UWtype *)&c)[3] ^= (((UWtype)1) << (W_TYPE_SIZE - 1));
+#else
+ FP_DECL_Q(A); FP_DECL_Q(C);
+
+ FP_UNPACK_Q(A, a);
+ FP_NEG_Q(C, A);
+ FP_PACK_Q(c, C);
+#endif
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_qtod.c b/libc/sysdeps/powerpc/soft-fp/q_qtod.c
new file mode 100644
index 000000000..685aa68e6
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_qtod.c
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+ Return (double)a
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+double _q_qtod(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ FP_DECL_D(R);
+ double r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_TRUNC(D,Q,2,4,R,A);
+#else
+ FP_TRUNC(D,Q,1,2,R,A);
+#endif
+ FP_PACK_SEMIRAW_D(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_qtoi.c b/libc/sysdeps/powerpc/soft-fp/q_qtoi.c
new file mode 100644
index 000000000..89410d125
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_qtoi.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (int)a
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+int _q_qtoi(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, 32, 1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_qtoll.c b/libc/sysdeps/powerpc/soft-fp/q_qtoll.c
new file mode 100644
index 000000000..3b0251f1b
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_qtoll.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (long)a
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+long long _q_qtoll(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned long long r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, 64, 1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_qtos.c b/libc/sysdeps/powerpc/soft-fp/q_qtos.c
new file mode 100644
index 000000000..0d71271d0
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_qtos.c
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+ Return (float)a
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+float _q_qtos(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ FP_DECL_S(R);
+ float r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_TRUNC(S,Q,1,4,R,A);
+#else
+ FP_TRUNC(S,Q,1,2,R,A);
+#endif
+ FP_PACK_SEMIRAW_S(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_qtou.c b/libc/sysdeps/powerpc/soft-fp/q_qtou.c
new file mode 100644
index 000000000..e5d21f1f4
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_qtou.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (unsigned int)a
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+unsigned int _q_qtou(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, 32, -1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_qtoull.c b/libc/sysdeps/powerpc/soft-fp/q_qtoull.c
new file mode 100644
index 000000000..a01100c79
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_qtoull.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (long)a
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+unsigned long long _q_qtoull(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned long long r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, 64, -1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_sqrt.c b/libc/sysdeps/powerpc/soft-fp/q_sqrt.c
new file mode 100644
index 000000000..e5320f88c
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_sqrt.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return sqrtl(a)
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _q_sqrt(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(C);
+ long double c;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_Q(A, a);
+ FP_SQRT_Q(C, A);
+ FP_PACK_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_stoq.c b/libc/sysdeps/powerpc/soft-fp/q_stoq.c
new file mode 100644
index 000000000..f43a93cea
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_stoq.c
@@ -0,0 +1,43 @@
+/* Software floating-point emulation.
+ c = (long double)(a)
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+long double _q_stoq(const float a)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ FP_DECL_Q(C);
+ long double c;
+
+ FP_UNPACK_RAW_S(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_EXTEND(Q,S,4,1,C,A);
+#else
+ FP_EXTEND(Q,S,2,1,C,A);
+#endif
+ FP_PACK_RAW_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_sub.c b/libc/sysdeps/powerpc/soft-fp/q_sub.c
new file mode 100644
index 000000000..399be021d
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_sub.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+ c = a - b
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _q_sub(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ long double c;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+ FP_UNPACK_SEMIRAW_Q(B, b);
+ FP_SUB_Q(C, A, B);
+ FP_PACK_SEMIRAW_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_ulltoq.c b/libc/sysdeps/powerpc/soft-fp/q_ulltoq.c
new file mode 100644
index 000000000..30f5fc9bf
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_ulltoq.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (long double)a
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _q_ulltoq(const unsigned long long a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ long double c;
+ unsigned long long b = a;
+
+ FP_FROM_INT_Q(C, b, 64, unsigned long long);
+ FP_PACK_RAW_Q(c, C);
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_util.c b/libc/sysdeps/powerpc/soft-fp/q_util.c
new file mode 100644
index 000000000..353f70a95
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_util.c
@@ -0,0 +1,57 @@
+/* Software floating-point emulation.
+ Helper routine for _q_* routines.
+ Simulate exceptions using double arithmetics.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+
+unsigned long long ___q_numbers [] = {
+0x0000000000000000ULL, /* Zero */
+0x0010100000000000ULL, /* Very tiny number */
+0x0010000000000000ULL, /* Minimum normalized number */
+0x7fef000000000000ULL, /* A huge double number */
+};
+
+double ___q_simulate_exceptions(int exceptions)
+{
+ double d, *p = (double *)___q_numbers;
+ if (exceptions & FP_EX_INVALID)
+ d = p[0]/p[0];
+ if (exceptions & FP_EX_OVERFLOW)
+ {
+ d = p[3] + p[3];
+ exceptions &= ~FP_EX_INEXACT;
+ }
+ if (exceptions & FP_EX_UNDERFLOW)
+ {
+ if (exceptions & FP_EX_INEXACT)
+ {
+ d = p[2] * p[2];
+ exceptions &= ~FP_EX_INEXACT;
+ }
+ else
+ d = p[1] - p[2];
+ }
+ if (exceptions & FP_EX_DIVZERO)
+ d = 1.0/p[0];
+ if (exceptions & FP_EX_INEXACT)
+ d = p[3] - p[2];
+ return d;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/q_utoq.c b/libc/sysdeps/powerpc/soft-fp/q_utoq.c
new file mode 100644
index 000000000..232bcfe3e
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/q_utoq.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ c = (long double)(a)
+ Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _q_uitoq(const unsigned int a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ long double c;
+ unsigned int b = a;
+
+ FP_FROM_INT_Q(C, b, 32, unsigned int);
+ FP_PACK_RAW_Q(c, C);
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/powerpc/soft-fp/sfp-machine.h b/libc/sysdeps/powerpc/soft-fp/sfp-machine.h
new file mode 100644
index 000000000..44a9184f2
--- /dev/null
+++ b/libc/sysdeps/powerpc/soft-fp/sfp-machine.h
@@ -0,0 +1,62 @@
+#define _FP_W_TYPE_SIZE 32
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+#define _FP_MUL_MEAT_S(R,X,Y) \
+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y) \
+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y) \
+ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S 0
+#define _FP_NANSIGN_D 0
+#define _FP_NANSIGN_Q 0
+
+#define _FP_KEEPNANFRACP 1
+
+/* Someone please check this. */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
+ && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,Y); \
+ } \
+ else \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ } \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+/* Exception flags. We use the bit positions of the appropriate bits
+ in the FPSCR, which also correspond to the FE_* bits. This makes
+ everything easier ;-). */
+#define FP_EX_INVALID (1 << (31 - 2))
+#define FP_EX_OVERFLOW (1 << (31 - 3))
+#define FP_EX_UNDERFLOW (1 << (31 - 4))
+#define FP_EX_DIVZERO (1 << (31 - 5))
+#define FP_EX_INEXACT (1 << (31 - 6))
+
+#define FP_HANDLE_EXCEPTIONS __simulate_exceptions (_fex)
+#define FP_ROUNDMODE __sim_round_mode
+
+extern int __sim_exceptions;
+libc_hidden_proto (__sim_exceptions);
+extern int __sim_disabled_exceptions;
+libc_hidden_proto (__sim_disabled_exceptions);
+extern int __sim_round_mode;
+libc_hidden_proto (__sim_round_mode);
+
+extern void __simulate_exceptions (int x) attribute_hidden;
diff --git a/libc/sysdeps/powerpc/stackinfo.h b/libc/sysdeps/powerpc/stackinfo.h
new file mode 100644
index 000000000..839758a4e
--- /dev/null
+++ b/libc/sysdeps/powerpc/stackinfo.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file contains a bit of information about the stack allocation
+ of the processor. */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H 1
+
+/* On PPC the stack grows down. */
+#define _STACK_GROWS_DOWN 1
+
+#endif /* stackinfo.h */
diff --git a/libc/sysdeps/powerpc/strcat.c b/libc/sysdeps/powerpc/strcat.c
new file mode 100644
index 000000000..dac2326cb
--- /dev/null
+++ b/libc/sysdeps/powerpc/strcat.c
@@ -0,0 +1,31 @@
+/* strcat version that uses fast strcpy/strlen.
+ Copyright (C) 1997, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+
+#undef strcat
+
+/* Append SRC on the end of DEST. */
+char *
+strcat (char *dest, const char *src)
+{
+ strcpy (dest + strlen (dest), src);
+ return dest;
+}
+libc_hidden_builtin_def (strcat)
diff --git a/libc/sysdeps/powerpc/sysdep.h b/libc/sysdeps/powerpc/sysdep.h
new file mode 100644
index 000000000..296231f65
--- /dev/null
+++ b/libc/sysdeps/powerpc/sysdep.h
@@ -0,0 +1,173 @@
+/* Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * Powerpc Feature masks for the Aux Vector Hardware Capabilities (AT_HWCAP).
+ * This entry is copied to _dl_hwcap or rtld_global._dl_hwcap during startup.
+ * The following must match the kernels linux/asm/cputable.h.
+ */
+#define PPC_FEATURE_32 0x80000000 /* 32-bit mode. */
+#define PPC_FEATURE_64 0x40000000 /* 64-bit mode. */
+#define PPC_FEATURE_601_INSTR 0x20000000 /* 601 chip, Old POWER ISA. */
+#define PPC_FEATURE_HAS_ALTIVEC 0x10000000 /* SIMD/Vector Unit. */
+#define PPC_FEATURE_HAS_FPU 0x08000000 /* Floating Point Unit. */
+#define PPC_FEATURE_HAS_MMU 0x04000000 /* Memory Management Unit. */
+#define PPC_FEATURE_HAS_4xxMAC 0x02000000 /* 4xx Multiply Accumulator. */
+#define PPC_FEATURE_UNIFIED_CACHE 0x01000000 /* Unified I/D cache. */
+#define PPC_FEATURE_HAS_SPE 0x00800000
+#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
+#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
+#define PPC_FEATURE_NO_TB 0x00100000 /* 601/403gx have no timebase */
+#define PPC_FEATURE_POWER4 0x00080000 /* POWER4 microarch level */
+#define PPC_FEATURE_POWER5 0x00040000 /* POWER5 microarch level */
+#define PPC_FEATURE_POWER5_PLUS 0x00020000 /* POWER5+ microarch level */
+#define PPC_FEATURE_CELL 0x00010000 /* CELL PU microarch level */
+#define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC)
+
+#ifdef __ASSEMBLER__
+
+/* Symbolic names for the registers. The only portable way to write asm
+ code is to use number but this produces really unreadable code.
+ Therefore these symbolic names. */
+
+/* Integer registers. */
+#define r0 0
+#define r1 1
+#define r2 2
+#define r3 3
+#define r4 4
+#define r5 5
+#define r6 6
+#define r7 7
+#define r8 8
+#define r9 9
+#define r10 10
+#define r11 11
+#define r12 12
+#define r13 13
+#define r14 14
+#define r15 15
+#define r16 16
+#define r17 17
+#define r18 18
+#define r19 19
+#define r20 20
+#define r21 21
+#define r22 22
+#define r23 23
+#define r24 24
+#define r25 25
+#define r26 26
+#define r27 27
+#define r28 28
+#define r29 29
+#define r30 30
+#define r31 31
+
+/* Floating-point registers. */
+#define fp0 0
+#define fp1 1
+#define fp2 2
+#define fp3 3
+#define fp4 4
+#define fp5 5
+#define fp6 6
+#define fp7 7
+#define fp8 8
+#define fp9 9
+#define fp10 10
+#define fp11 11
+#define fp12 12
+#define fp13 13
+#define fp14 14
+#define fp15 15
+#define fp16 16
+#define fp17 17
+#define fp18 18
+#define fp19 19
+#define fp20 20
+#define fp21 21
+#define fp22 22
+#define fp23 23
+#define fp24 24
+#define fp25 25
+#define fp26 26
+#define fp27 27
+#define fp28 28
+#define fp29 29
+#define fp30 30
+#define fp31 31
+
+/* Condition code registers. */
+#define cr0 0
+#define cr1 1
+#define cr2 2
+#define cr3 3
+#define cr4 4
+#define cr5 5
+#define cr6 6
+#define cr7 7
+
+/* Vector registers. */
+#define v0 0
+#define v1 1
+#define v2 2
+#define v3 3
+#define v4 4
+#define v5 5
+#define v6 6
+#define v7 7
+#define v8 8
+#define v9 9
+#define v10 10
+#define v11 11
+#define v12 12
+#define v13 13
+#define v14 14
+#define v15 15
+#define v16 16
+#define v17 17
+#define v18 18
+#define v19 19
+#define v20 20
+#define v21 21
+#define v22 22
+#define v23 23
+#define v24 24
+#define v25 25
+#define v26 26
+#define v27 27
+#define v28 28
+#define v29 29
+#define v30 30
+#define v31 31
+
+#define VRSAVE 256
+
+
+#ifdef __ELF__
+
+/* This seems to always be the case on PPC. */
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+#endif /* __ELF__ */
+#endif /* __ASSEMBLER__ */
+
diff --git a/libc/sysdeps/powerpc/test-arith.c b/libc/sysdeps/powerpc/test-arith.c
new file mode 100644
index 000000000..484265bf7
--- /dev/null
+++ b/libc/sysdeps/powerpc/test-arith.c
@@ -0,0 +1,605 @@
+/* Test floating-point arithmetic operations.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fenv.h>
+#include <assert.h>
+
+#ifndef ESIZE
+typedef double tocheck_t;
+#define ESIZE 11
+#define MSIZE 52
+#define FUNC(x) x
+#endif
+
+#define R_NEAREST 1
+#define R_ZERO 2
+#define R_UP 4
+#define R_DOWN 8
+#define R_ALL (R_NEAREST|R_ZERO|R_UP|R_DOWN)
+static fenv_t rmodes[4];
+static const char * const rmnames[4] =
+{ "nearest","zero","+Inf","-Inf" };
+
+typedef union {
+ tocheck_t tc;
+ unsigned char c[sizeof(tocheck_t)];
+} union_t;
+
+/* Don't try reading these in a font that doesn't distinguish
+ O and zero. */
+typedef enum {
+ P_Z = 0x0, /* 00000...0 */
+ P_000O = 0x1, /* 00011...1 */
+ P_001Z = 0x2, /* 00100...0 */
+ P_00O = 0x3, /* 00111...1 */
+ P_01Z = 0x4, /* 01000...0 */
+ P_010O = 0x5, /* 01011...1 */
+ P_011Z = 0x6, /* 01100...0 */
+ P_0O = 0x7, /* 01111...1 */
+ P_1Z = 0x8, /* 10000...0 */
+ P_100O = 0x9, /* 10011...1 */
+ P_101Z = 0xa, /* 10100...0 */
+ P_10O = 0xb, /* 10111...1 */
+ P_11Z = 0xc, /* 11000...0 */
+ P_110O = 0xd, /* 11011...1 */
+ P_111Z = 0xe, /* 11100...0 */
+ P_O = 0xf, /* 11111...1 */
+ P_Z1 = 0x11, /* 000...001 */
+ P_Z10 = 0x12, /* 000...010 */
+ P_Z11 = 0x13, /* 000...011 */
+ P_0O00 = 0x14, /* 011...100 */
+ P_0O01 = 0x15, /* 011...101 */
+ P_0O0 = 0x16, /* 011...110 */
+ P_1Z1 = 0x19, /* 100...001 */
+ P_1Z10 = 0x1a, /* 100...010 */
+ P_1Z11 = 0x1b, /* 100...011 */
+ P_O00 = 0x1c, /* 111...100 */
+ P_O01 = 0x1d, /* 111...101 */
+ P_O0 = 0x1e, /* 111...110 */
+ P_R = 0x20, /* rrr...rrr */ /* ('r' means random. ) */
+ P_Ro = 0x21, /* rrr...rrr, with odd parity. */
+ P_0R = 0x22, /* 0rr...rrr */
+ P_1R = 0x23, /* 1rr...rrr */
+ P_Rno = 0x24, /* rrr...rrr, but not all ones. */
+} pattern_t;
+
+static void
+pattern_fill(pattern_t ptn, unsigned char *start, int bitoffset, int count)
+{
+#define bitset(count, value) \
+ start[(count)/8] = (start[(count)/8] & ~(1 << 7-(count)%8) \
+ | (value) << 7-(count)%8)
+ int i;
+
+ if (ptn >= 0 && ptn <= 0xf)
+ {
+ /* Patterns between 0 and 0xF have the following format:
+ The LSBit is used to fill the last n-3 bits of the pattern;
+ The next 3 bits are the first 3 bits of the pattern. */
+ for (i = 0; i < count; i++)
+ if (i < 3)
+ bitset((bitoffset+i), ptn >> (3-i) & 1);
+ else
+ bitset((bitoffset+i), ptn >> 0 & 1);
+ }
+ else if (ptn <= 0x1f)
+ {
+ /* Patterns between 0x10 and 0x1F have the following format:
+ The two LSBits are the last two bits of the pattern;
+ The 0x8 bit is the first bit of the pattern;
+ The 0x4 bit is used to fill the remainder. */
+ for (i = 0; i < count; i++)
+ if (i == 0)
+ bitset((bitoffset+i), ptn >> 3 & 1);
+ else if (i >= count-2)
+ bitset((bitoffset+i), ptn >> (count-1-i) & 1);
+ else
+ bitset((bitoffset+i), ptn >> 2 & 1);
+ }
+ else switch (ptn)
+ {
+ case P_0R: case P_1R:
+ assert(count > 0);
+ bitset(bitoffset, ptn & 1);
+ count--;
+ bitoffset++;
+ case P_R:
+ for (; count > 0; count--, bitoffset++)
+ bitset(bitoffset, rand() & 1);
+ break;
+ case P_Ro:
+ {
+ int op = 1;
+ assert(count > 0);
+ for (; count > 1; count--, bitoffset++)
+ bitset(bitoffset, op ^= (rand() & 1));
+ bitset(bitoffset, op);
+ break;
+ }
+ case P_Rno:
+ {
+ int op = 1;
+ assert(count > 0);
+ for (; count > 1; count--, bitoffset++)
+ {
+ int r = rand() & 1;
+ op &= r;
+ bitset(bitoffset, r);
+ }
+ bitset(bitoffset, rand() & (op ^ 1));
+ break;
+ }
+
+ default:
+ assert(0);
+ }
+#undef bitset
+}
+
+static tocheck_t
+pattern(int negative, pattern_t exp, pattern_t mant)
+{
+ union_t result;
+#if 0
+ int i;
+#endif
+
+ pattern_fill(negative ? P_O : P_Z, result.c, 0, 1);
+ pattern_fill(exp, result.c, 1, ESIZE);
+ pattern_fill(mant, result.c, ESIZE+1, MSIZE);
+#if 0
+ printf("neg=%d exp=%02x mant=%02x: ", negative, exp, mant);
+ for (i = 0; i < sizeof(tocheck_t); i++)
+ printf("%02x", result.c[i]);
+ printf("\n");
+#endif
+ return result.tc;
+}
+
+/* Return the closest different tocheck_t to 'x' in the direction of
+ 'direction', or 'x' if there is no such value. Assumes 'x' is not
+ a NaN. */
+static tocheck_t
+delta(tocheck_t x, int direction)
+{
+ union_t xx;
+ int i;
+
+ xx.tc = x;
+ if (xx.c[0] & 0x80)
+ direction = -direction;
+ if (direction == +1)
+ {
+ union_t tx;
+ tx.tc = pattern(xx.c[0] >> 7, P_O, P_Z);
+ if (memcmp(tx.c, xx.c, sizeof(tocheck_t)) == 0)
+ return x;
+ }
+ for (i = sizeof(tocheck_t)-1; i > 0; i--)
+ {
+ xx.c[i] += direction;
+ if (xx.c[i] != (direction > 0 ? 0 : 0xff))
+ return xx.tc;
+ }
+ if (direction < 0 && (xx.c[0] & 0x7f) == 0)
+ return pattern(~(xx.c[0] >> 7) & 1, P_Z, P_Z1);
+ else
+ {
+ xx.c[0] += direction;
+ return xx.tc;
+ }
+}
+
+static int nerrors = 0;
+
+#ifdef FE_ALL_INVALID
+static const int all_exceptions = FE_ALL_INVALID | FE_ALL_EXCEPT;
+#else
+static const int all_exceptions = FE_ALL_EXCEPT;
+#endif
+
+static void
+check_result(int line, const char *rm, tocheck_t expected, tocheck_t actual)
+{
+ if (memcmp(&expected, &actual, sizeof(tocheck_t)) != 0)
+ {
+ unsigned char *ex, *ac;
+ size_t i;
+
+ printf("%s:%d:round %s:result failed\n"
+ " expected result 0x", __FILE__, line, rm);
+ ex = (unsigned char *)&expected;
+ ac = (unsigned char *)&actual;
+ for (i = 0; i < sizeof(tocheck_t); i++)
+ printf("%02x", ex[i]);
+ printf(" got 0x");
+ for (i = 0; i < sizeof(tocheck_t); i++)
+ printf("%02x", ac[i]);
+ printf("\n");
+ nerrors++;
+ }
+}
+
+static const struct {
+ int except;
+ const char *name;
+} excepts[] = {
+#define except_entry(ex) { ex, #ex } ,
+#ifdef FE_INEXACT
+ except_entry(FE_INEXACT)
+#else
+# define FE_INEXACT 0
+#endif
+#ifdef FE_DIVBYZERO
+ except_entry(FE_DIVBYZERO)
+#else
+# define FE_DIVBYZERO 0
+#endif
+#ifdef FE_UNDERFLOW
+ except_entry(FE_UNDERFLOW)
+#else
+# define FE_UNDERFLOW 0
+#endif
+#ifdef FE_OVERFLOW
+ except_entry(FE_OVERFLOW)
+#else
+# define FE_OVERFLOW 0
+#endif
+#ifdef FE_INVALID
+ except_entry(FE_INVALID)
+#else
+# define FE_INVALID 0
+#endif
+#ifdef FE_INVALID_SNAN
+ except_entry(FE_INVALID_SNAN)
+#else
+# define FE_INVALID_SNAN FE_INVALID
+#endif
+#ifdef FE_INVALID_ISI
+ except_entry(FE_INVALID_ISI)
+#else
+# define FE_INVALID_ISI FE_INVALID
+#endif
+#ifdef FE_INVALID_IDI
+ except_entry(FE_INVALID_IDI)
+#else
+# define FE_INVALID_IDI FE_INVALID
+#endif
+#ifdef FE_INVALID_ZDZ
+ except_entry(FE_INVALID_ZDZ)
+#else
+# define FE_INVALID_ZDZ FE_INVALID
+#endif
+#ifdef FE_INVALID_COMPARE
+ except_entry(FE_INVALID_COMPARE)
+#else
+# define FE_INVALID_COMPARE FE_INVALID
+#endif
+#ifdef FE_INVALID_SOFTWARE
+ except_entry(FE_INVALID_SOFTWARE)
+#else
+# define FE_INVALID_SOFTWARE FE_INVALID
+#endif
+#ifdef FE_INVALID_SQRT
+ except_entry(FE_INVALID_SQRT)
+#else
+# define FE_INVALID_SQRT FE_INVALID
+#endif
+#ifdef FE_INVALID_INTEGER_CONVERSION
+ except_entry(FE_INVALID_INTEGER_CONVERSION)
+#else
+# define FE_INVALID_INTEGER_CONVERSION FE_INVALID
+#endif
+};
+
+static int excepts_missing = 0;
+
+static void
+check_excepts(int line, const char *rm, int expected, int actual)
+{
+ if (expected & excepts_missing)
+ expected = expected & ~excepts_missing | FE_INVALID_SNAN;
+ if ((expected & all_exceptions) != actual)
+ {
+ size_t i;
+ printf("%s:%d:round %s:exceptions failed\n"
+ " expected exceptions ", __FILE__, line,rm);
+ for (i = 0; i < sizeof(excepts)/sizeof(excepts[0]); i++)
+ if (expected & excepts[i].except)
+ printf("%s ",excepts[i].name);
+ if ((expected & all_exceptions) == 0)
+ printf("- ");
+ printf("got");
+ for (i = 0; i < sizeof(excepts)/sizeof(excepts[0]); i++)
+ if (actual & excepts[i].except)
+ printf(" %s",excepts[i].name);
+ if ((actual & all_exceptions) == 0)
+ printf("- ");
+ printf(".\n");
+ nerrors++;
+ }
+}
+
+typedef enum {
+ B_ADD, B_SUB, B_MUL, B_DIV, B_NEG, B_ABS, B_SQRT
+} op_t;
+typedef struct {
+ int line;
+ op_t op;
+ int a_sgn;
+ pattern_t a_exp, a_mant;
+ int b_sgn;
+ pattern_t b_exp, b_mant;
+ int rmode;
+ int excepts;
+ int x_sgn;
+ pattern_t x_exp, x_mant;
+} optest_t;
+static const optest_t optests[] = {
+ /* Additions of zero. */
+ {__LINE__,B_ADD, 0,P_Z,P_Z, 0,P_Z,P_Z, R_ALL,0, 0,P_Z,P_Z },
+ {__LINE__,B_ADD, 1,P_Z,P_Z, 0,P_Z,P_Z, R_ALL & ~R_DOWN,0, 0,P_Z,P_Z },
+ {__LINE__,B_ADD, 1,P_Z,P_Z, 0,P_Z,P_Z, R_DOWN,0, 1,P_Z,P_Z },
+ {__LINE__,B_ADD, 1,P_Z,P_Z, 1,P_Z,P_Z, R_ALL,0, 1,P_Z,P_Z },
+
+ /* Additions with NaN. */
+ {__LINE__,B_ADD, 0,P_O,P_101Z, 0,P_Z,P_Z, R_ALL,0, 0,P_O,P_101Z },
+ {__LINE__,B_ADD, 0,P_O,P_01Z, 0,P_Z,P_Z, R_ALL,
+ FE_INVALID | FE_INVALID_SNAN, 0,P_O,P_11Z },
+ {__LINE__,B_ADD, 0,P_O,P_Z, 0,P_O,P_0O, R_ALL,
+ FE_INVALID | FE_INVALID_SNAN, 0,P_O,P_O },
+ {__LINE__,B_ADD, 0,P_Z,P_Z, 0,P_O,P_11Z, R_ALL,0, 0,P_O,P_11Z },
+ {__LINE__,B_ADD, 0,P_O,P_001Z, 0,P_O,P_001Z, R_ALL,
+ FE_INVALID | FE_INVALID_SNAN, 0,P_O,P_101Z },
+ {__LINE__,B_ADD, 0,P_O,P_1Z, 0,P_Z,P_Z, R_ALL,0, 0,P_O,P_1Z },
+ {__LINE__,B_ADD, 0,P_0O,P_Z, 0,P_O,P_10O, R_ALL,0, 0,P_O,P_10O },
+
+ /* Additions with infinity. */
+ {__LINE__,B_ADD, 0,P_O,P_Z, 0,P_Z,P_Z, R_ALL,0, 0,P_O,P_Z },
+ {__LINE__,B_ADD, 0,P_O,P_Z, 1,P_Z,P_Z, R_ALL,0, 0,P_O,P_Z },
+ {__LINE__,B_ADD, 1,P_O,P_Z, 0,P_Z,P_Z, R_ALL,0, 1,P_O,P_Z },
+ {__LINE__,B_ADD, 1,P_O,P_Z, 1,P_Z,P_Z, R_ALL,0, 1,P_O,P_Z },
+ {__LINE__,B_ADD, 0,P_O,P_Z, 0,P_O,P_Z, R_ALL,0, 0,P_O,P_Z },
+ {__LINE__,B_ADD, 1,P_O,P_Z, 1,P_O,P_Z, R_ALL,0, 1,P_O,P_Z },
+ {__LINE__,B_ADD, 0,P_O,P_Z, 1,P_O,P_Z, R_ALL,
+ FE_INVALID | FE_INVALID_ISI, 0,P_O,P_1Z },
+ {__LINE__,B_ADD, 1,P_O,P_Z, 0,P_O,P_Z, R_ALL,
+ FE_INVALID | FE_INVALID_ISI, 0,P_O,P_1Z },
+ {__LINE__,B_ADD, 0,P_O,P_Z, 0,P_0O,P_Z, R_ALL,0, 0,P_O,P_Z },
+ {__LINE__,B_ADD, 1,P_O,P_Z, 0,P_0O,P_Z, R_ALL,0, 1,P_O,P_Z },
+ {__LINE__,B_ADD, 0,P_O,P_Z, 1,P_0O,P_Z, R_ALL,0, 0,P_O,P_Z },
+ {__LINE__,B_ADD, 1,P_O,P_Z, 1,P_0O,P_Z, R_ALL,0, 1,P_O,P_Z },
+
+ /* Overflow (and zero). */
+ {__LINE__,B_ADD, 0,P_O0,P_Z, 0,P_O0,P_Z, R_NEAREST | R_UP,
+ FE_INEXACT | FE_OVERFLOW, 0,P_O,P_Z },
+ {__LINE__,B_ADD, 0,P_O0,P_Z, 0,P_O0,P_Z, R_ZERO | R_DOWN,
+ FE_INEXACT | FE_OVERFLOW, 0,P_O0,P_O },
+ {__LINE__,B_ADD, 1,P_O0,P_Z, 1,P_O0,P_Z, R_NEAREST | R_DOWN,
+ FE_INEXACT | FE_OVERFLOW, 1,P_O,P_Z },
+ {__LINE__,B_ADD, 1,P_O0,P_Z, 1,P_O0,P_Z, R_ZERO | R_UP,
+ FE_INEXACT | FE_OVERFLOW, 1,P_O0,P_O },
+ {__LINE__,B_ADD, 0,P_O0,P_Z, 1,P_O0,P_Z, R_ALL & ~R_DOWN,
+ 0, 0,P_Z,P_Z },
+ {__LINE__,B_ADD, 0,P_O0,P_Z, 1,P_O0,P_Z, R_DOWN,
+ 0, 1,P_Z,P_Z },
+
+ /* Negation. */
+ {__LINE__,B_NEG, 0,P_Z,P_Z, 0,0,0, R_ALL, 0, 1,P_Z,P_Z },
+ {__LINE__,B_NEG, 1,P_Z,P_Z, 0,0,0, R_ALL, 0, 0,P_Z,P_Z },
+ {__LINE__,B_NEG, 0,P_O,P_Z, 0,0,0, R_ALL, 0, 1,P_O,P_Z },
+ {__LINE__,B_NEG, 1,P_O,P_Z, 0,0,0, R_ALL, 0, 0,P_O,P_Z },
+ {__LINE__,B_NEG, 0,P_O,P_1Z, 0,0,0, R_ALL, 0, 1,P_O,P_1Z },
+ {__LINE__,B_NEG, 1,P_O,P_1Z, 0,0,0, R_ALL, 0, 0,P_O,P_1Z },
+ {__LINE__,B_NEG, 0,P_O,P_01Z, 0,0,0, R_ALL, 0, 1,P_O,P_01Z },
+ {__LINE__,B_NEG, 1,P_O,P_01Z, 0,0,0, R_ALL, 0, 0,P_O,P_01Z },
+ {__LINE__,B_NEG, 0,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 1,P_1Z,P_1Z1 },
+ {__LINE__,B_NEG, 1,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 0,P_1Z,P_1Z1 },
+ {__LINE__,B_NEG, 0,P_Z,P_Z1, 0,0,0, R_ALL, 0, 1,P_Z,P_Z1 },
+ {__LINE__,B_NEG, 1,P_Z,P_Z1, 0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
+
+ /* Absolute value. */
+ {__LINE__,B_ABS, 0,P_Z,P_Z, 0,0,0, R_ALL, 0, 0,P_Z,P_Z },
+ {__LINE__,B_ABS, 1,P_Z,P_Z, 0,0,0, R_ALL, 0, 0,P_Z,P_Z },
+ {__LINE__,B_ABS, 0,P_O,P_Z, 0,0,0, R_ALL, 0, 0,P_O,P_Z },
+ {__LINE__,B_ABS, 1,P_O,P_Z, 0,0,0, R_ALL, 0, 0,P_O,P_Z },
+ {__LINE__,B_ABS, 0,P_O,P_1Z, 0,0,0, R_ALL, 0, 0,P_O,P_1Z },
+ {__LINE__,B_ABS, 1,P_O,P_1Z, 0,0,0, R_ALL, 0, 0,P_O,P_1Z },
+ {__LINE__,B_ABS, 0,P_O,P_01Z, 0,0,0, R_ALL, 0, 0,P_O,P_01Z },
+ {__LINE__,B_ABS, 1,P_O,P_01Z, 0,0,0, R_ALL, 0, 0,P_O,P_01Z },
+ {__LINE__,B_ABS, 0,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 0,P_1Z,P_1Z1 },
+ {__LINE__,B_ABS, 1,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 0,P_1Z,P_1Z1 },
+ {__LINE__,B_ABS, 0,P_Z,P_Z1, 0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
+ {__LINE__,B_ABS, 1,P_Z,P_Z1, 0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
+
+ /* Square root. */
+ {__LINE__,B_SQRT, 0,P_Z,P_Z, 0,0,0, R_ALL, 0, 0,P_Z,P_Z },
+ {__LINE__,B_SQRT, 1,P_Z,P_Z, 0,0,0, R_ALL, 0, 1,P_Z,P_Z },
+ {__LINE__,B_SQRT, 0,P_O,P_1Z, 0,0,0, R_ALL, 0, 0,P_O,P_1Z },
+ {__LINE__,B_SQRT, 1,P_O,P_1Z, 0,0,0, R_ALL, 0, 1,P_O,P_1Z },
+ {__LINE__,B_SQRT, 0,P_O,P_01Z, 0,0,0, R_ALL,
+ FE_INVALID | FE_INVALID_SNAN, 0,P_O,P_11Z },
+ {__LINE__,B_SQRT, 1,P_O,P_01Z, 0,0,0, R_ALL,
+ FE_INVALID | FE_INVALID_SNAN, 1,P_O,P_11Z },
+
+ {__LINE__,B_SQRT, 0,P_O,P_Z, 0,0,0, R_ALL, 0, 0,P_O,P_Z },
+ {__LINE__,B_SQRT, 0,P_0O,P_Z, 0,0,0, R_ALL, 0, 0,P_0O,P_Z },
+
+ {__LINE__,B_SQRT, 1,P_O,P_Z, 0,0,0, R_ALL,
+ FE_INVALID | FE_INVALID_SQRT, 0,P_O,P_1Z },
+ {__LINE__,B_SQRT, 1,P_1Z,P_1Z1, 0,0,0, R_ALL,
+ FE_INVALID | FE_INVALID_SQRT, 0,P_O,P_1Z },
+ {__LINE__,B_SQRT, 1,P_Z,P_Z1, 0,0,0, R_ALL,
+ FE_INVALID | FE_INVALID_SQRT, 0,P_O,P_1Z },
+
+};
+
+static void
+check_op(void)
+{
+ size_t i;
+ int j;
+ tocheck_t r, a, b, x;
+ int raised;
+
+ for (i = 0; i < sizeof(optests)/sizeof(optests[0]); i++)
+ {
+ a = pattern(optests[i].a_sgn, optests[i].a_exp,
+ optests[i].a_mant);
+ b = pattern(optests[i].b_sgn, optests[i].b_exp,
+ optests[i].b_mant);
+ x = pattern(optests[i].x_sgn, optests[i].x_exp,
+ optests[i].x_mant);
+ for (j = 0; j < 4; j++)
+ if (optests[i].rmode & 1<<j)
+ {
+ fesetenv(rmodes+j);
+ switch (optests[i].op)
+ {
+ case B_ADD: r = a + b; break;
+ case B_SUB: r = a - b; break;
+ case B_MUL: r = a * b; break;
+ case B_DIV: r = a / b; break;
+ case B_NEG: r = -a; break;
+ case B_ABS: r = FUNC(fabs)(a); break;
+ case B_SQRT: r = FUNC(sqrt)(a); break;
+ }
+ raised = fetestexcept(all_exceptions);
+ check_result(optests[i].line,rmnames[j],x,r);
+ check_excepts(optests[i].line,rmnames[j],
+ optests[i].excepts,raised);
+ }
+ }
+}
+
+static void
+fail_xr(int line, const char *rm, tocheck_t x, tocheck_t r, tocheck_t xx,
+ int xflag)
+{
+ size_t i;
+ unsigned char *cx, *cr, *cxx;
+
+ printf("%s:%d:round %s:fail\n with x=0x", __FILE__, line,rm);
+ cx = (unsigned char *)&x;
+ cr = (unsigned char *)&r;
+ cxx = (unsigned char *)&xx;
+ for (i = 0; i < sizeof(tocheck_t); i++)
+ printf("%02x", cx[i]);
+ printf(" r=0x");
+ for (i = 0; i < sizeof(tocheck_t); i++)
+ printf("%02x", cr[i]);
+ printf(" xx=0x");
+ for (i = 0; i < sizeof(tocheck_t); i++)
+ printf("%02x", cxx[i]);
+ printf(" inexact=%d\n", xflag != 0);
+ nerrors++;
+}
+
+static void
+check_sqrt(tocheck_t a)
+{
+ int j;
+ tocheck_t r0, r1, r2, x0, x1, x2;
+ int raised = 0;
+ int ok;
+
+ for (j = 0; j < 4; j++)
+ {
+ int excepts;
+
+ fesetenv(rmodes+j);
+ r1 = FUNC(sqrt)(a);
+ excepts = fetestexcept(all_exceptions);
+ fesetenv(FE_DFL_ENV);
+ raised |= excepts & ~FE_INEXACT;
+ x1 = r1 * r1 - a;
+ if (excepts & FE_INEXACT)
+ {
+ r0 = delta(r1,-1); r2 = delta(r1,1);
+ switch (1 << j)
+ {
+ case R_NEAREST:
+ x0 = r0 * r0 - a; x2 = r2 * r2 - a;
+ ok = fabs(x0) >= fabs(x1) && fabs(x1) <= fabs(x2);
+ break;
+ case R_ZERO: case R_DOWN:
+ x2 = r2 * r2 - a;
+ ok = x1 <= 0 && x2 >= 0;
+ break;
+ case R_UP:
+ x0 = r0 * r0 - a;
+ ok = x1 >= 0 && x0 <= 0;
+ break;
+ default:
+ assert(0);
+ }
+ }
+ else
+ ok = x1 == 0;
+ if (!ok)
+ fail_xr(__LINE__,rmnames[j],a,r1,x1,excepts&FE_INEXACT);
+ }
+ check_excepts(__LINE__,"all",0,raised);
+}
+
+int main(int argc, char **argv)
+{
+ int i;
+
+ _LIB_VERSION = _IEEE_;
+
+ /* Set up environments for rounding modes. */
+ fesetenv(FE_DFL_ENV);
+ fesetround(FE_TONEAREST);
+ fegetenv(rmodes+0);
+ fesetround(FE_TOWARDZERO);
+ fegetenv(rmodes+1);
+ fesetround(FE_UPWARD);
+ fegetenv(rmodes+2);
+ fesetround(FE_DOWNWARD);
+ fegetenv(rmodes+3);
+
+#if defined(FE_INVALID_SOFTWARE) || defined(FE_INVALID_SQRT)
+ /* There's this really stupid feature of the 601... */
+ fesetenv(FE_DFL_ENV);
+ feraiseexcept(FE_INVALID_SOFTWARE);
+ if (!fetestexcept(FE_INVALID_SOFTWARE))
+ excepts_missing |= FE_INVALID_SOFTWARE;
+ fesetenv(FE_DFL_ENV);
+ feraiseexcept(FE_INVALID_SQRT);
+ if (!fetestexcept(FE_INVALID_SQRT))
+ excepts_missing |= FE_INVALID_SQRT;
+#endif
+
+ check_op();
+ for (i = 0; i < 100000; i++)
+ check_sqrt(pattern(0, P_Rno, P_R));
+ for (i = 0; i < 100; i++)
+ check_sqrt(pattern(0, P_Z, P_R));
+ check_sqrt(pattern(0,P_Z,P_Z1));
+
+ printf("%d errors.\n", nerrors);
+ return nerrors == 0 ? 0 : 1;
+}
diff --git a/libc/sysdeps/powerpc/test-arithf.c b/libc/sysdeps/powerpc/test-arithf.c
new file mode 100644
index 000000000..d78ec4900
--- /dev/null
+++ b/libc/sysdeps/powerpc/test-arithf.c
@@ -0,0 +1,6 @@
+typedef float tocheck_t;
+#define ESIZE 8
+#define MSIZE 23
+#define FUNC(x) x##f
+
+#include "test-arith.c"
diff --git a/libc/sysdeps/powerpc/tst-stack-align.h b/libc/sysdeps/powerpc/tst-stack-align.h
new file mode 100644
index 000000000..99a0ffcef
--- /dev/null
+++ b/libc/sysdeps/powerpc/tst-stack-align.h
@@ -0,0 +1,47 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#define TEST_STACK_ALIGN() \
+ ({ \
+ /* Altivec __vector int etc. needs 16byte aligned stack. \
+ Instead of using altivec.h here, use aligned attribute instead. */ \
+ struct _S \
+ { \
+ int _i __attribute__((aligned (16))); \
+ int _j[3]; \
+ } _s = { ._i = 18, ._j[0] = 19, ._j[1] = 20, ._j[2] = 21 }; \
+ double _d = 12.0; \
+ long double _ld = 15.0; \
+ int _ret = 0; \
+ printf ("__vector int: { %d, %d, %d, %d } %p %zu\n", _s._i, _s._j[0], \
+ _s._j[1], _s._j[2], &_s, __alignof (_s)); \
+ if ((((uintptr_t) &_s) & (__alignof (_s) - 1)) != 0) \
+ _ret = 1; \
+ \
+ printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
+ if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
+ _ret = 1; \
+ \
+ printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
+ if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
+ _ret = 1; \
+ _ret; \
+ })
diff --git a/libc/sysdeps/pthread/Versions b/libc/sysdeps/pthread/Versions
new file mode 100644
index 000000000..a71cffbed
--- /dev/null
+++ b/libc/sysdeps/pthread/Versions
@@ -0,0 +1,5 @@
+librt {
+ GLIBC_2.4 {
+ lio_listio; lio_listio64;
+ }
+}
diff --git a/libc/sysdeps/pthread/aio_cancel.c b/libc/sysdeps/pthread/aio_cancel.c
new file mode 100644
index 000000000..aa1ee443a
--- /dev/null
+++ b/libc/sysdeps/pthread/aio_cancel.c
@@ -0,0 +1,159 @@
+/* Cancel requests associated with given file descriptor.
+ Copyright (C) 1997, 1998, 2000, 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* We use an UGLY hack to prevent gcc from finding us cheating. The
+ implementation of aio_cancel and aio_cancel64 are identical and so
+ we want to avoid code duplication by using aliases. But gcc sees
+ the different parameter lists and prints a warning. We define here
+ a function so that aio_cancel64 has no prototype. */
+#ifndef aio_cancel
+#define aio_cancel64 XXX
+#include <aio.h>
+/* And undo the hack. */
+#undef aio_cancel64
+#endif
+
+#include <assert.h>
+#include <errno.h>
+
+#include <aio_misc.h>
+
+
+int
+aio_cancel (fildes, aiocbp)
+ int fildes;
+ struct aiocb *aiocbp;
+{
+ struct requestlist *req = NULL;
+ int result = AIO_ALLDONE;
+
+ /* If fildes is invalid, error. */
+ if (fcntl (fildes, F_GETFL) < 0)
+ {
+ __set_errno (EBADF);
+ return -1;
+ }
+
+ /* Request the mutex. */
+ pthread_mutex_lock (&__aio_requests_mutex);
+
+ /* We are asked to cancel a specific AIO request. */
+ if (aiocbp != NULL)
+ {
+ /* If the AIO request is not for this descriptor it has no value
+ to look for the request block. */
+ if (aiocbp->aio_fildes != fildes)
+ {
+ pthread_mutex_unlock (&__aio_requests_mutex);
+ __set_errno (EINVAL);
+ return -1;
+ }
+ else if (aiocbp->__error_code == EINPROGRESS)
+ {
+ struct requestlist *last = NULL;
+
+ req = __aio_find_req_fd (fildes);
+
+ if (req == NULL)
+ {
+ not_found:
+ pthread_mutex_unlock (&__aio_requests_mutex);
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ while (req->aiocbp != (aiocb_union *) aiocbp)
+ {
+ last = req;
+ req = req->next_prio;
+ if (req == NULL)
+ goto not_found;
+ }
+
+ /* Don't remove the entry if a thread is already working on it. */
+ if (req->running == allocated)
+ {
+ result = AIO_NOTCANCELED;
+ req = NULL;
+ }
+ else
+ {
+ /* We can remove the entry. */
+ __aio_remove_request (last, req, 0);
+
+ result = AIO_CANCELED;
+
+ req->next_prio = NULL;
+ }
+ }
+ }
+ else
+ {
+ /* Find the beginning of the list of all requests for this
+ desriptor. */
+ req = __aio_find_req_fd (fildes);
+
+ /* If any request is worked on by a thread it must be the first.
+ So either we can delete all requests or all but the first. */
+ if (req != NULL)
+ {
+ if (req->running == allocated)
+ {
+ struct requestlist *old = req;
+ req = req->next_prio;
+ old->next_prio = NULL;
+
+ result = AIO_NOTCANCELED;
+
+ if (req != NULL)
+ __aio_remove_request (old, req, 1);
+ }
+ else
+ {
+ result = AIO_CANCELED;
+
+ /* We can remove the entry. */
+ __aio_remove_request (NULL, req, 1);
+ }
+ }
+ }
+
+ /* Mark requests as canceled and send signal. */
+ while (req != NULL)
+ {
+ struct requestlist *old = req;
+ assert (req->running == yes || req->running == queued);
+ req->aiocbp->aiocb.__error_code = ECANCELED;
+ req->aiocbp->aiocb.__return_value = -1;
+ __aio_notify (req);
+ req = req->next_prio;
+ __aio_free_request (old);
+ }
+
+ /* Release the mutex. */
+ pthread_mutex_unlock (&__aio_requests_mutex);
+
+ return result;
+}
+
+#ifndef aio_cancel
+weak_alias (aio_cancel, aio_cancel64)
+#endif
diff --git a/libc/sysdeps/pthread/aio_fsync.c b/libc/sysdeps/pthread/aio_fsync.c
new file mode 100644
index 000000000..47cc29991
--- /dev/null
+++ b/libc/sysdeps/pthread/aio_fsync.c
@@ -0,0 +1,60 @@
+/* Synchronize I/O in given file descriptor.
+ Copyright (C) 1997, 1999, 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* We use an UGLY hack to prevent gcc from finding us cheating. The
+ implementation of aio_fsync and aio_fsync64 are identical and so
+ we want to avoid code duplication by using aliases. But gcc sees
+ the different parameter lists and prints a warning. We define here
+ a function so that aio_fsync64 has no prototype. */
+#define aio_fsync64 XXX
+#include <aio.h>
+/* And undo the hack. */
+#undef aio_fsync64
+#include <errno.h>
+
+#include <aio_misc.h>
+
+
+int
+aio_fsync (int op, struct aiocb *aiocbp)
+{
+ int flags;
+
+ if (op != O_DSYNC && __builtin_expect (op != O_SYNC, 0))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ flags = fcntl (aiocbp->aio_fildes, F_GETFL);
+ if (__builtin_expect (flags == -1, 0)
+ || __builtin_expect ((flags & (O_RDWR | O_WRONLY)) == 0, 0))
+ {
+ __set_errno (EBADF);
+ return -1;
+ }
+
+ return (__aio_enqueue_request ((aiocb_union *) aiocbp,
+ op == O_SYNC ? LIO_SYNC : LIO_DSYNC) == NULL
+ ? -1 : 0);
+}
+
+weak_alias (aio_fsync, aio_fsync64)
diff --git a/libc/sysdeps/pthread/aio_misc.c b/libc/sysdeps/pthread/aio_misc.c
new file mode 100644
index 000000000..3e1dbe9c6
--- /dev/null
+++ b/libc/sysdeps/pthread/aio_misc.c
@@ -0,0 +1,720 @@
+/* Handle general operations.
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <aio.h>
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <aio_misc.h>
+
+#ifndef aio_create_helper_thread
+# define aio_create_helper_thread __aio_create_helper_thread
+
+extern inline int
+__aio_create_helper_thread (pthread_t *threadp, void *(*tf) (void *), void *arg)
+{
+ pthread_attr_t attr;
+
+ /* Make sure the thread is created detached. */
+ pthread_attr_init (&attr);
+ pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+
+ int ret = pthread_create (threadp, &attr, tf, arg);
+
+ (void) pthread_attr_destroy (&attr);
+ return ret;
+}
+#endif
+
+static void add_request_to_runlist (struct requestlist *newrequest);
+
+/* Pool of request list entries. */
+static struct requestlist **pool;
+
+/* Number of total and allocated pool entries. */
+static size_t pool_max_size;
+static size_t pool_size;
+
+/* We implement a two dimensional array but allocate each row separately.
+ The macro below determines how many entries should be used per row.
+ It should better be a power of two. */
+#define ENTRIES_PER_ROW 32
+
+/* How many rows we allocate at once. */
+#define ROWS_STEP 8
+
+/* List of available entries. */
+static struct requestlist *freelist;
+
+/* List of request waiting to be processed. */
+static struct requestlist *runlist;
+
+/* Structure list of all currently processed requests. */
+static struct requestlist *requests;
+
+/* Number of threads currently running. */
+static int nthreads;
+
+/* Number of threads waiting for work to arrive. */
+static int idle_thread_count;
+
+
+/* These are the values used to optimize the use of AIO. The user can
+ overwrite them by using the `aio_init' function. */
+static struct aioinit optim =
+{
+ 20, /* int aio_threads; Maximal number of threads. */
+ 64, /* int aio_num; Number of expected simultanious requests. */
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0
+};
+
+
+/* Since the list is global we need a mutex protecting it. */
+pthread_mutex_t __aio_requests_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+
+/* When you add a request to the list and there are idle threads present,
+ you signal this condition variable. When a thread finishes work, it waits
+ on this condition variable for a time before it actually exits. */
+pthread_cond_t __aio_new_request_notification = PTHREAD_COND_INITIALIZER;
+
+
+/* Functions to handle request list pool. */
+static struct requestlist *
+get_elem (void)
+{
+ struct requestlist *result;
+
+ if (freelist == NULL)
+ {
+ struct requestlist *new_row;
+ int cnt;
+
+ assert (sizeof (struct aiocb) == sizeof (struct aiocb64));
+
+ if (pool_size + 1 >= pool_max_size)
+ {
+ size_t new_max_size = pool_max_size + ROWS_STEP;
+ struct requestlist **new_tab;
+
+ new_tab = (struct requestlist **)
+ realloc (pool, new_max_size * sizeof (struct requestlist *));
+
+ if (new_tab == NULL)
+ return NULL;
+
+ pool_max_size = new_max_size;
+ pool = new_tab;
+ }
+
+ /* Allocate the new row. */
+ cnt = pool_size == 0 ? optim.aio_num : ENTRIES_PER_ROW;
+ new_row = (struct requestlist *) calloc (cnt,
+ sizeof (struct requestlist));
+ if (new_row == NULL)
+ return NULL;
+
+ pool[pool_size++] = new_row;
+
+ /* Put all the new entries in the freelist. */
+ do
+ {
+ new_row->next_prio = freelist;
+ freelist = new_row++;
+ }
+ while (--cnt > 0);
+ }
+
+ result = freelist;
+ freelist = freelist->next_prio;
+
+ return result;
+}
+
+
+void
+internal_function
+__aio_free_request (struct requestlist *elem)
+{
+ elem->running = no;
+ elem->next_prio = freelist;
+ freelist = elem;
+}
+
+
+struct requestlist *
+internal_function
+__aio_find_req (aiocb_union *elem)
+{
+ struct requestlist *runp = requests;
+ int fildes = elem->aiocb.aio_fildes;
+
+ while (runp != NULL && runp->aiocbp->aiocb.aio_fildes < fildes)
+ runp = runp->next_fd;
+
+ if (runp != NULL)
+ {
+ if (runp->aiocbp->aiocb.aio_fildes != fildes)
+ runp = NULL;
+ else
+ while (runp != NULL && runp->aiocbp != elem)
+ runp = runp->next_prio;
+ }
+
+ return runp;
+}
+
+
+struct requestlist *
+internal_function
+__aio_find_req_fd (int fildes)
+{
+ struct requestlist *runp = requests;
+
+ while (runp != NULL && runp->aiocbp->aiocb.aio_fildes < fildes)
+ runp = runp->next_fd;
+
+ return (runp != NULL && runp->aiocbp->aiocb.aio_fildes == fildes
+ ? runp : NULL);
+}
+
+
+void
+internal_function
+__aio_remove_request (struct requestlist *last, struct requestlist *req,
+ int all)
+{
+ assert (req->running == yes || req->running == queued
+ || req->running == done);
+
+ if (last != NULL)
+ last->next_prio = all ? NULL : req->next_prio;
+ else
+ {
+ if (all || req->next_prio == NULL)
+ {
+ if (req->last_fd != NULL)
+ req->last_fd->next_fd = req->next_fd;
+ else
+ requests = req->next_fd;
+ if (req->next_fd != NULL)
+ req->next_fd->last_fd = req->last_fd;
+ }
+ else
+ {
+ if (req->last_fd != NULL)
+ req->last_fd->next_fd = req->next_prio;
+ else
+ requests = req->next_prio;
+
+ if (req->next_fd != NULL)
+ req->next_fd->last_fd = req->next_prio;
+
+ req->next_prio->last_fd = req->last_fd;
+ req->next_prio->next_fd = req->next_fd;
+
+ /* Mark this entry as runnable. */
+ req->next_prio->running = yes;
+ }
+
+ if (req->running == yes)
+ {
+ struct requestlist *runp = runlist;
+
+ last = NULL;
+ while (runp != NULL)
+ {
+ if (runp == req)
+ {
+ if (last == NULL)
+ runlist = runp->next_run;
+ else
+ last->next_run = runp->next_run;
+ break;
+ }
+ last = runp;
+ runp = runp->next_run;
+ }
+ }
+ }
+}
+
+
+/* The thread handler. */
+static void *handle_fildes_io (void *arg);
+
+
+/* User optimization. */
+void
+__aio_init (const struct aioinit *init)
+{
+ /* Get the mutex. */
+ pthread_mutex_lock (&__aio_requests_mutex);
+
+ /* Only allow writing new values if the table is not yet allocated. */
+ if (pool == NULL)
+ {
+ optim.aio_threads = init->aio_threads < 1 ? 1 : init->aio_threads;
+ optim.aio_num = (init->aio_num < ENTRIES_PER_ROW
+ ? ENTRIES_PER_ROW
+ : init->aio_num & ~ENTRIES_PER_ROW);
+ }
+
+ if (init->aio_idle_time != 0)
+ optim.aio_idle_time = init->aio_idle_time;
+
+ /* Release the mutex. */
+ pthread_mutex_unlock (&__aio_requests_mutex);
+}
+weak_alias (__aio_init, aio_init)
+
+
+/* The main function of the async I/O handling. It enqueues requests
+ and if necessary starts and handles threads. */
+struct requestlist *
+internal_function
+__aio_enqueue_request (aiocb_union *aiocbp, int operation)
+{
+ int result = 0;
+ int policy, prio;
+ struct sched_param param;
+ struct requestlist *last, *runp, *newp;
+ int running = no;
+
+ if (operation == LIO_SYNC || operation == LIO_DSYNC)
+ aiocbp->aiocb.aio_reqprio = 0;
+ else if (aiocbp->aiocb.aio_reqprio < 0
+ || aiocbp->aiocb.aio_reqprio > AIO_PRIO_DELTA_MAX)
+ {
+ /* Invalid priority value. */
+ __set_errno (EINVAL);
+ aiocbp->aiocb.__error_code = EINVAL;
+ aiocbp->aiocb.__return_value = -1;
+ return NULL;
+ }
+
+ /* Compute priority for this request. */
+ pthread_getschedparam (pthread_self (), &policy, &param);
+ prio = param.sched_priority - aiocbp->aiocb.aio_reqprio;
+
+ /* Get the mutex. */
+ pthread_mutex_lock (&__aio_requests_mutex);
+
+ last = NULL;
+ runp = requests;
+ /* First look whether the current file descriptor is currently
+ worked with. */
+ while (runp != NULL
+ && runp->aiocbp->aiocb.aio_fildes < aiocbp->aiocb.aio_fildes)
+ {
+ last = runp;
+ runp = runp->next_fd;
+ }
+
+ /* Get a new element for the waiting list. */
+ newp = get_elem ();
+ if (newp == NULL)
+ {
+ pthread_mutex_unlock (&__aio_requests_mutex);
+ __set_errno (EAGAIN);
+ return NULL;
+ }
+ newp->aiocbp = aiocbp;
+#ifdef BROKEN_THREAD_SIGNALS
+ newp->caller_pid = (aiocbp->aiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL
+ ? getpid () : 0);
+#endif
+ newp->waiting = NULL;
+
+ aiocbp->aiocb.__abs_prio = prio;
+ aiocbp->aiocb.__policy = policy;
+ aiocbp->aiocb.aio_lio_opcode = operation;
+ aiocbp->aiocb.__error_code = EINPROGRESS;
+ aiocbp->aiocb.__return_value = 0;
+
+ if (runp != NULL
+ && runp->aiocbp->aiocb.aio_fildes == aiocbp->aiocb.aio_fildes)
+ {
+ /* The current file descriptor is worked on. It makes no sense
+ to start another thread since this new thread would fight
+ with the running thread for the resources. But we also cannot
+ say that the thread processing this desriptor shall immediately
+ after finishing the current job process this request if there
+ are other threads in the running queue which have a higher
+ priority. */
+
+ /* Simply enqueue it after the running one according to the
+ priority. */
+ while (runp->next_prio != NULL
+ && runp->next_prio->aiocbp->aiocb.__abs_prio >= prio)
+ runp = runp->next_prio;
+
+ newp->next_prio = runp->next_prio;
+ runp->next_prio = newp;
+
+ running = queued;
+ }
+ else
+ {
+ running = yes;
+ /* Enqueue this request for a new descriptor. */
+ if (last == NULL)
+ {
+ newp->last_fd = NULL;
+ newp->next_fd = requests;
+ if (requests != NULL)
+ requests->last_fd = newp;
+ requests = newp;
+ }
+ else
+ {
+ newp->next_fd = last->next_fd;
+ newp->last_fd = last;
+ last->next_fd = newp;
+ if (newp->next_fd != NULL)
+ newp->next_fd->last_fd = newp;
+ }
+
+ newp->next_prio = NULL;
+ }
+
+ if (running == yes)
+ {
+ /* We try to create a new thread for this file descriptor. The
+ function which gets called will handle all available requests
+ for this descriptor and when all are processed it will
+ terminate.
+
+ If no new thread can be created or if the specified limit of
+ threads for AIO is reached we queue the request. */
+
+ /* See if we need to and are able to create a thread. */
+ if (nthreads < optim.aio_threads && idle_thread_count == 0)
+ {
+ pthread_t thid;
+
+ running = newp->running = allocated;
+
+ /* Now try to start a thread. */
+ if (aio_create_helper_thread (&thid, handle_fildes_io, newp) == 0)
+ /* We managed to enqueue the request. All errors which can
+ happen now can be recognized by calls to `aio_return' and
+ `aio_error'. */
+ ++nthreads;
+ else
+ {
+ /* Reset the running flag. The new request is not running. */
+ running = newp->running = yes;
+
+ if (nthreads == 0)
+ /* We cannot create a thread in the moment and there is
+ also no thread running. This is a problem. `errno' is
+ set to EAGAIN if this is only a temporary problem. */
+ result = -1;
+ }
+ }
+ }
+
+ /* Enqueue the request in the run queue if it is not yet running. */
+ if (running == yes && result == 0)
+ {
+ add_request_to_runlist (newp);
+
+ /* If there is a thread waiting for work, then let it know that we
+ have just given it something to do. */
+ if (idle_thread_count > 0)
+ pthread_cond_signal (&__aio_new_request_notification);
+ }
+
+ if (result == 0)
+ newp->running = running;
+ else
+ {
+ /* Something went wrong. */
+ __aio_free_request (newp);
+ newp = NULL;
+ }
+
+ /* Release the mutex. */
+ pthread_mutex_unlock (&__aio_requests_mutex);
+
+ return newp;
+}
+
+
+static void *
+handle_fildes_io (void *arg)
+{
+ pthread_t self = pthread_self ();
+ struct sched_param param;
+ struct requestlist *runp = (struct requestlist *) arg;
+ aiocb_union *aiocbp;
+ int policy;
+ int fildes;
+
+ pthread_getschedparam (self, &policy, &param);
+
+ do
+ {
+ /* If runp is NULL, then we were created to service the work queue
+ in general, not to handle any particular request. In that case we
+ skip the "do work" stuff on the first pass, and go directly to the
+ "get work off the work queue" part of this loop, which is near the
+ end. */
+ if (runp == NULL)
+ pthread_mutex_lock (&__aio_requests_mutex);
+ else
+ {
+ /* Hopefully this request is marked as running. */
+ assert (runp->running == allocated);
+
+ /* Update our variables. */
+ aiocbp = runp->aiocbp;
+ fildes = aiocbp->aiocb.aio_fildes;
+
+ /* Change the priority to the requested value (if necessary). */
+ if (aiocbp->aiocb.__abs_prio != param.sched_priority
+ || aiocbp->aiocb.__policy != policy)
+ {
+ param.sched_priority = aiocbp->aiocb.__abs_prio;
+ policy = aiocbp->aiocb.__policy;
+ pthread_setschedparam (self, policy, &param);
+ }
+
+ /* Process request pointed to by RUNP. We must not be disturbed
+ by signals. */
+ if ((aiocbp->aiocb.aio_lio_opcode & 127) == LIO_READ)
+ {
+ if (aiocbp->aiocb.aio_lio_opcode & 128)
+ aiocbp->aiocb.__return_value =
+ TEMP_FAILURE_RETRY (__pread64 (fildes, (void *)
+ aiocbp->aiocb64.aio_buf,
+ aiocbp->aiocb64.aio_nbytes,
+ aiocbp->aiocb64.aio_offset));
+ else
+ aiocbp->aiocb.__return_value =
+ TEMP_FAILURE_RETRY (pread (fildes,
+ (void *) aiocbp->aiocb.aio_buf,
+ aiocbp->aiocb.aio_nbytes,
+ aiocbp->aiocb.aio_offset));
+
+ if (aiocbp->aiocb.__return_value == -1 && errno == ESPIPE)
+ /* The Linux kernel is different from others. It returns
+ ESPIPE if using pread on a socket. Other platforms
+ simply ignore the offset parameter and behave like
+ read. */
+ aiocbp->aiocb.__return_value =
+ TEMP_FAILURE_RETRY (read (fildes,
+ (void *) aiocbp->aiocb64.aio_buf,
+ aiocbp->aiocb64.aio_nbytes));
+ }
+ else if ((aiocbp->aiocb.aio_lio_opcode & 127) == LIO_WRITE)
+ {
+ if (aiocbp->aiocb.aio_lio_opcode & 128)
+ aiocbp->aiocb.__return_value =
+ TEMP_FAILURE_RETRY (__pwrite64 (fildes, (const void *)
+ aiocbp->aiocb64.aio_buf,
+ aiocbp->aiocb64.aio_nbytes,
+ aiocbp->aiocb64.aio_offset));
+ else
+ aiocbp->aiocb.__return_value =
+ TEMP_FAILURE_RETRY (__libc_pwrite (fildes, (const void *)
+ aiocbp->aiocb.aio_buf,
+ aiocbp->aiocb.aio_nbytes,
+ aiocbp->aiocb.aio_offset));
+
+ if (aiocbp->aiocb.__return_value == -1 && errno == ESPIPE)
+ /* The Linux kernel is different from others. It returns
+ ESPIPE if using pwrite on a socket. Other platforms
+ simply ignore the offset parameter and behave like
+ write. */
+ aiocbp->aiocb.__return_value =
+ TEMP_FAILURE_RETRY (write (fildes,
+ (void *) aiocbp->aiocb64.aio_buf,
+ aiocbp->aiocb64.aio_nbytes));
+ }
+ else if (aiocbp->aiocb.aio_lio_opcode == LIO_DSYNC)
+ aiocbp->aiocb.__return_value =
+ TEMP_FAILURE_RETRY (fdatasync (fildes));
+ else if (aiocbp->aiocb.aio_lio_opcode == LIO_SYNC)
+ aiocbp->aiocb.__return_value =
+ TEMP_FAILURE_RETRY (fsync (fildes));
+ else
+ {
+ /* This is an invalid opcode. */
+ aiocbp->aiocb.__return_value = -1;
+ __set_errno (EINVAL);
+ }
+
+ /* Get the mutex. */
+ pthread_mutex_lock (&__aio_requests_mutex);
+
+ /* In theory we would need here a write memory barrier since the
+ callers test using aio_error() whether the request finished
+ and once this value != EINPROGRESS the field __return_value
+ must be committed to memory.
+
+ But since the pthread_mutex_lock call involves write memory
+ barriers as well it is not necessary. */
+
+ if (aiocbp->aiocb.__return_value == -1)
+ aiocbp->aiocb.__error_code = errno;
+ else
+ aiocbp->aiocb.__error_code = 0;
+
+ /* Send the signal to notify about finished processing of the
+ request. */
+ __aio_notify (runp);
+
+ /* For debugging purposes we reset the running flag of the
+ finished request. */
+ assert (runp->running == allocated);
+ runp->running = done;
+
+ /* Now dequeue the current request. */
+ __aio_remove_request (NULL, runp, 0);
+ if (runp->next_prio != NULL)
+ add_request_to_runlist (runp->next_prio);
+
+ /* Free the old element. */
+ __aio_free_request (runp);
+ }
+
+ runp = runlist;
+
+ /* If the runlist is empty, then we sleep for a while, waiting for
+ something to arrive in it. */
+ if (runp == NULL && optim.aio_idle_time >= 0)
+ {
+ struct timeval now;
+ struct timespec wakeup_time;
+
+ ++idle_thread_count;
+ gettimeofday (&now, NULL);
+ wakeup_time.tv_sec = now.tv_sec + optim.aio_idle_time;
+ wakeup_time.tv_nsec = now.tv_usec * 1000;
+ if (wakeup_time.tv_nsec > 1000000000)
+ {
+ wakeup_time.tv_nsec -= 1000000000;
+ ++wakeup_time.tv_sec;
+ }
+ pthread_cond_timedwait (&__aio_new_request_notification,
+ &__aio_requests_mutex,
+ &wakeup_time);
+ --idle_thread_count;
+ runp = runlist;
+ }
+
+ if (runp == NULL)
+ --nthreads;
+ else
+ {
+ assert (runp->running == yes);
+ runp->running = allocated;
+ runlist = runp->next_run;
+
+ /* If we have a request to process, and there's still another in
+ the run list, then we need to either wake up or create a new
+ thread to service the request that is still in the run list. */
+ if (runlist != NULL)
+ {
+ /* There are at least two items in the work queue to work on.
+ If there are other idle threads, then we should wake them
+ up for these other work elements; otherwise, we should try
+ to create a new thread. */
+ if (idle_thread_count > 0)
+ pthread_cond_signal (&__aio_new_request_notification);
+ else if (nthreads < optim.aio_threads)
+ {
+ pthread_t thid;
+ pthread_attr_t attr;
+
+ /* Make sure the thread is created detached. */
+ pthread_attr_init (&attr);
+ pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+
+ /* Now try to start a thread. If we fail, no big deal,
+ because we know that there is at least one thread (us)
+ that is working on AIO operations. */
+ if (pthread_create (&thid, &attr, handle_fildes_io, NULL)
+ == 0)
+ ++nthreads;
+ }
+ }
+ }
+
+ /* Release the mutex. */
+ pthread_mutex_unlock (&__aio_requests_mutex);
+ }
+ while (runp != NULL);
+
+ return NULL;
+}
+
+
+/* Free allocated resources. */
+libc_freeres_fn (free_res)
+{
+ size_t row;
+
+ for (row = 0; row < pool_max_size; ++row)
+ free (pool[row]);
+
+ free (pool);
+}
+
+
+/* Add newrequest to the runlist. The __abs_prio flag of newrequest must
+ be correctly set to do this. Also, you had better set newrequest's
+ "running" flag to "yes" before you release your lock or you'll throw an
+ assertion. */
+static void
+add_request_to_runlist (struct requestlist *newrequest)
+{
+ int prio = newrequest->aiocbp->aiocb.__abs_prio;
+ struct requestlist *runp;
+
+ if (runlist == NULL || runlist->aiocbp->aiocb.__abs_prio < prio)
+ {
+ newrequest->next_run = runlist;
+ runlist = newrequest;
+ }
+ else
+ {
+ runp = runlist;
+
+ while (runp->next_run != NULL
+ && runp->next_run->aiocbp->aiocb.__abs_prio >= prio)
+ runp = runp->next_run;
+
+ newrequest->next_run = runp->next_run;
+ runp->next_run = newrequest;
+ }
+}
diff --git a/libc/sysdeps/pthread/aio_misc.h b/libc/sysdeps/pthread/aio_misc.h
new file mode 100644
index 000000000..50962c751
--- /dev/null
+++ b/libc/sysdeps/pthread/aio_misc.h
@@ -0,0 +1,144 @@
+/* Copyright (C) 1997,1999,2000,2001,2003,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _AIO_MISC_H
+#define _AIO_MISC_H 1
+
+#include <aio.h>
+#include <pthread.h>
+
+
+/* Extend the operation enum. */
+enum
+{
+ LIO_DSYNC = LIO_NOP + 1,
+ LIO_SYNC,
+ LIO_READ64 = LIO_READ | 128,
+ LIO_WRITE64 = LIO_WRITE | 128
+};
+
+
+/* Union of the two request types. */
+typedef union
+ {
+ struct aiocb aiocb;
+ struct aiocb64 aiocb64;
+ } aiocb_union;
+
+
+/* Used to synchronize. */
+struct waitlist
+ {
+ struct waitlist *next;
+
+ /* The next two fields is used in synchronous `lio_listio' operations. */
+#ifndef DONT_NEED_AIO_MISC_COND
+ pthread_cond_t *cond;
+#endif
+ int *result;
+
+ volatile int *counterp;
+ /* The next field is used in asynchronous `lio_listio' operations. */
+ struct sigevent *sigevp;
+#ifdef BROKEN_THREAD_SIGNALS
+ /* XXX See requestlist, it's used to work around the broken signal
+ handling in Linux. */
+ pid_t caller_pid;
+#endif
+ };
+
+
+/* Status of a request. */
+enum
+{
+ no,
+ queued,
+ yes,
+ allocated,
+ done
+};
+
+
+/* Used to queue requests.. */
+struct requestlist
+ {
+ int running;
+
+ struct requestlist *last_fd;
+ struct requestlist *next_fd;
+ struct requestlist *next_prio;
+ struct requestlist *next_run;
+
+ /* Pointer to the actual data. */
+ aiocb_union *aiocbp;
+
+#ifdef BROKEN_THREAD_SIGNALS
+ /* PID of the initiator thread.
+ XXX This is only necessary for the broken signal handling on Linux. */
+ pid_t caller_pid;
+#endif
+
+ /* List of waiting processes. */
+ struct waitlist *waiting;
+ };
+
+
+/* Lock for global I/O list of requests. */
+extern pthread_mutex_t __aio_requests_mutex attribute_hidden;
+
+
+/* Enqueue request. */
+extern struct requestlist *__aio_enqueue_request (aiocb_union *aiocbp,
+ int operation)
+ attribute_hidden internal_function;
+
+/* Find request entry for given AIO control block. */
+extern struct requestlist *__aio_find_req (aiocb_union *elem)
+ attribute_hidden internal_function;
+
+/* Find request entry for given file descriptor. */
+extern struct requestlist *__aio_find_req_fd (int fildes)
+ attribute_hidden internal_function;
+
+/* Remove request from the list. */
+extern void __aio_remove_request (struct requestlist *last,
+ struct requestlist *req, int all)
+ attribute_hidden internal_function;
+
+/* Release the entry for the request. */
+extern void __aio_free_request (struct requestlist *req)
+ attribute_hidden internal_function;
+
+/* Notify initiator of request and tell this everybody listening. */
+extern void __aio_notify (struct requestlist *req)
+ attribute_hidden internal_function;
+
+/* Notify initiator of request. */
+#ifdef BROKEN_THREAD_SIGNALS
+extern int __aio_notify_only (struct sigevent *sigev, pid_t caller_pid)
+ attribute_hidden internal_function;
+#else
+extern int __aio_notify_only (struct sigevent *sigev)
+ attribute_hidden internal_function;
+#endif
+
+/* Send the signal. */
+extern int __aio_sigqueue (int sig, const union sigval val, pid_t caller_pid)
+ attribute_hidden internal_function;
+
+#endif /* aio_misc.h */
diff --git a/libc/sysdeps/pthread/aio_notify.c b/libc/sysdeps/pthread/aio_notify.c
new file mode 100644
index 000000000..3f7f70ef7
--- /dev/null
+++ b/libc/sysdeps/pthread/aio_notify.c
@@ -0,0 +1,177 @@
+/* Notify initiator of AIO request.
+ Copyright (C) 1997-2001, 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <aio_misc.h>
+
+#ifndef aio_start_notify_thread
+# define aio_start_notify_thread() do { } while (0)
+#endif
+
+struct notify_func
+ {
+ void (*func) (sigval_t);
+ sigval_t value;
+ };
+
+static void *
+notify_func_wrapper (void *arg)
+{
+ aio_start_notify_thread ();
+ struct notify_func *const n = arg;
+ void (*func) (sigval_t) = n->func;
+ sigval_t value = n->value;
+ free (n);
+ (*func) (value);
+ return NULL;
+}
+
+
+int
+internal_function
+#ifdef BROKEN_THREAD_SIGNALS
+__aio_notify_only (struct sigevent *sigev, pid_t caller_pid)
+#else
+__aio_notify_only (struct sigevent *sigev)
+#endif
+{
+ int result = 0;
+
+ /* Send the signal to notify about finished processing of the request. */
+ if (__builtin_expect (sigev->sigev_notify == SIGEV_THREAD, 0))
+ {
+ /* We have to start a thread. */
+ pthread_t tid;
+ pthread_attr_t attr, *pattr;
+
+ pattr = (pthread_attr_t *) sigev->sigev_notify_attributes;
+ if (pattr == NULL)
+ {
+ pthread_attr_init (&attr);
+ pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+ pattr = &attr;
+ }
+
+ /* SIGEV may be freed as soon as we return, so we cannot let the
+ notification thread use that pointer. Even though a sigval_t is
+ only one word and the same size as a void *, we cannot just pass
+ the value through pthread_create as the argument and have the new
+ thread run the user's function directly, because on some machines
+ the calling convention for a union like sigval_t is different from
+ that for a pointer type like void *. */
+ struct notify_func *nf = malloc (sizeof *nf);
+ if (nf == NULL)
+ result = -1;
+ else
+ {
+ nf->func = sigev->sigev_notify_function;
+ nf->value = sigev->sigev_value;
+ if (pthread_create (&tid, pattr, notify_func_wrapper, nf) < 0)
+ {
+ free (nf);
+ result = -1;
+ }
+ }
+ }
+ else if (sigev->sigev_notify == SIGEV_SIGNAL)
+ {
+ /* We have to send a signal. */
+#if _POSIX_REALTIME_SIGNALS
+ /* Note that the standard gives us the option of using a plain
+ non-queuing signal here when SA_SIGINFO is not set for the signal. */
+# ifdef BROKEN_THREAD_SIGNALS
+ if (__aio_sigqueue (sigev->sigev_signo, sigev->sigev_value, caller_pid)
+ < 0)
+ result = -1;
+# else
+ if (__aio_sigqueue (sigev->sigev_signo, sigev->sigev_value, getpid ())
+ < 0)
+ result = -1;
+# endif
+#else
+ /* There are no queued signals on this system at all. */
+ result = raise (sigev->sigev_signo);
+#endif
+ }
+
+ return result;
+}
+
+
+void
+internal_function
+__aio_notify (struct requestlist *req)
+{
+ struct waitlist *waitlist;
+ struct aiocb *aiocbp = &req->aiocbp->aiocb;
+
+#ifdef BROKEN_THREAD_SIGNALS
+ if (__aio_notify_only (&aiocbp->aio_sigevent, req->caller_pid) != 0)
+#else
+ if (__aio_notify_only (&aiocbp->aio_sigevent) != 0)
+#endif
+ {
+ /* XXX What shall we do if already an error is set by
+ read/write/fsync? */
+ aiocbp->__error_code = errno;
+ aiocbp->__return_value = -1;
+ }
+
+ /* Now also notify possibly waiting threads. */
+ waitlist = req->waiting;
+ while (waitlist != NULL)
+ {
+ struct waitlist *next = waitlist->next;
+
+ if (waitlist->sigevp == NULL)
+ {
+ if (waitlist->result != NULL && aiocbp->__return_value == -1)
+ *waitlist->result = -1;
+
+#ifdef DONT_NEED_AIO_MISC_COND
+ AIO_MISC_NOTIFY (waitlist);
+#else
+ /* Decrement the counter. */
+ --*waitlist->counterp;
+
+ pthread_cond_signal (waitlist->cond);
+#endif
+ }
+ else
+ /* This is part of a asynchronous `lio_listio' operation. If
+ this request is the last one, send the signal. */
+ if (--*waitlist->counterp == 0)
+ {
+#ifdef BROKEN_THREAD_SIGNALS
+ __aio_notify_only (waitlist->sigevp, waitlist->caller_pid);
+#else
+ __aio_notify_only (waitlist->sigevp);
+#endif
+ /* This is tricky. See lio_listio.c for the reason why
+ this works. */
+ free ((void *) waitlist->counterp);
+ }
+
+ waitlist = next;
+ }
+}
diff --git a/libc/sysdeps/pthread/aio_read.c b/libc/sysdeps/pthread/aio_read.c
new file mode 100644
index 000000000..973c6cdd4
--- /dev/null
+++ b/libc/sysdeps/pthread/aio_read.c
@@ -0,0 +1,32 @@
+/* Asynchronous read.
+ Copyright (C) 1997, 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <aio.h>
+
+#include <aio_misc.h>
+
+
+int
+aio_read (aiocbp)
+ struct aiocb *aiocbp;
+{
+ return (__aio_enqueue_request ((aiocb_union *) aiocbp, LIO_READ) == NULL
+ ? -1 : 0);
+}
diff --git a/libc/sysdeps/pthread/aio_read64.c b/libc/sysdeps/pthread/aio_read64.c
new file mode 100644
index 000000000..a3a427d80
--- /dev/null
+++ b/libc/sysdeps/pthread/aio_read64.c
@@ -0,0 +1,32 @@
+/* Asynchronous read, 64bit offset version.
+ Copyright (C) 1997, 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <aio.h>
+
+#include <aio_misc.h>
+
+
+int
+aio_read64 (aiocbp)
+ struct aiocb64 *aiocbp;
+{
+ return (__aio_enqueue_request ((aiocb_union *) aiocbp, LIO_READ64) == NULL
+ ? -1 : 0);
+}
diff --git a/libc/sysdeps/pthread/aio_suspend.c b/libc/sysdeps/pthread/aio_suspend.c
new file mode 100644
index 000000000..b85b16d10
--- /dev/null
+++ b/libc/sysdeps/pthread/aio_suspend.c
@@ -0,0 +1,247 @@
+/* Suspend until termination of a requests.
+ Copyright (C) 1997-2000,2002,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* We use an UGLY hack to prevent gcc from finding us cheating. The
+ implementations of aio_suspend and aio_suspend64 are identical and so
+ we want to avoid code duplication by using aliases. But gcc sees
+ the different parameter lists and prints a warning. We define here
+ a function so that aio_suspend64 has no prototype. */
+#define aio_suspend64 XXX
+#include <aio.h>
+/* And undo the hack. */
+#undef aio_suspend64
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include <bits/libc-lock.h>
+#include <aio_misc.h>
+
+
+struct clparam
+{
+ const struct aiocb *const *list;
+ struct waitlist *waitlist;
+ struct requestlist **requestlist;
+#ifndef DONT_NEED_AIO_MISC_COND
+ pthread_cond_t *cond;
+#endif
+ int nent;
+};
+
+
+static void
+cleanup (void *arg)
+{
+#ifdef DONT_NEED_AIO_MISC_COND
+ /* Acquire the mutex. If pthread_cond_*wait is used this would
+ happen implicitly. */
+ pthread_mutex_lock (&__aio_requests_mutex);
+#endif
+
+ const struct clparam *param = (const struct clparam *) arg;
+
+ /* Now remove the entry in the waiting list for all requests
+ which didn't terminate. */
+ int cnt = param->nent;
+ while (cnt-- > 0)
+ if (param->list[cnt] != NULL
+ && param->list[cnt]->__error_code == EINPROGRESS)
+ {
+ struct waitlist **listp;
+
+ assert (param->requestlist[cnt] != NULL);
+
+ /* There is the chance that we cannot find our entry anymore. This
+ could happen if the request terminated and restarted again. */
+ listp = &param->requestlist[cnt]->waiting;
+ while (*listp != NULL && *listp != &param->waitlist[cnt])
+ listp = &(*listp)->next;
+
+ if (*listp != NULL)
+ *listp = (*listp)->next;
+ }
+
+#ifndef DONT_NEED_AIO_MISC_COND
+ /* Release the conditional variable. */
+ (void) pthread_cond_destroy (param->cond);
+#endif
+
+ /* Release the mutex. */
+ pthread_mutex_unlock (&__aio_requests_mutex);
+}
+
+
+int
+aio_suspend (list, nent, timeout)
+ const struct aiocb *const list[];
+ int nent;
+ const struct timespec *timeout;
+{
+ if (__builtin_expect (nent < 0, 0))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ struct waitlist waitlist[nent];
+ struct requestlist *requestlist[nent];
+#ifndef DONT_NEED_AIO_MISC_COND
+ pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+#endif
+ int cnt;
+ bool any = false;
+ int result = 0;
+ int cntr = 1;
+
+ /* Request the mutex. */
+ pthread_mutex_lock (&__aio_requests_mutex);
+
+ /* There is not yet a finished request. Signal the request that
+ we are working for it. */
+ for (cnt = 0; cnt < nent; ++cnt)
+ if (list[cnt] != NULL)
+ {
+ if (list[cnt]->__error_code == EINPROGRESS)
+ {
+ requestlist[cnt] = __aio_find_req ((aiocb_union *) list[cnt]);
+
+ if (requestlist[cnt] != NULL)
+ {
+#ifndef DONT_NEED_AIO_MISC_COND
+ waitlist[cnt].cond = &cond;
+#endif
+ waitlist[cnt].result = NULL;
+ waitlist[cnt].next = requestlist[cnt]->waiting;
+ waitlist[cnt].counterp = &cntr;
+ waitlist[cnt].sigevp = NULL;
+#ifdef BROKEN_THREAD_SIGNALS
+ waitlist[cnt].caller_pid = 0; /* Not needed. */
+#endif
+ requestlist[cnt]->waiting = &waitlist[cnt];
+ any = true;
+ }
+ else
+ /* We will never suspend. */
+ break;
+ }
+ else
+ /* We will never suspend. */
+ break;
+ }
+
+
+ /* Only if none of the entries is NULL or finished to be wait. */
+ if (cnt == nent && any)
+ {
+ struct clparam clparam =
+ {
+ .list = list,
+ .waitlist = waitlist,
+ .requestlist = requestlist,
+#ifndef DONT_NEED_AIO_MISC_COND
+ .cond = &cond,
+#endif
+ .nent = nent
+ };
+
+ pthread_cleanup_push (cleanup, &clparam);
+
+#ifdef DONT_NEED_AIO_MISC_COND
+ AIO_MISC_WAIT (result, cntr, timeout, 1);
+#else
+ if (timeout == NULL)
+ result = pthread_cond_wait (&cond, &__aio_requests_mutex);
+ else
+ {
+ /* We have to convert the relative timeout value into an
+ absolute time value with pthread_cond_timedwait expects. */
+ struct timeval now;
+ struct timespec abstime;
+
+ __gettimeofday (&now, NULL);
+ abstime.tv_nsec = timeout->tv_nsec + now.tv_usec * 1000;
+ abstime.tv_sec = timeout->tv_sec + now.tv_sec;
+ if (abstime.tv_nsec >= 1000000000)
+ {
+ abstime.tv_nsec -= 1000000000;
+ abstime.tv_sec += 1;
+ }
+
+ result = pthread_cond_timedwait (&cond, &__aio_requests_mutex,
+ &abstime);
+ }
+#endif
+
+ pthread_cleanup_pop (0);
+ }
+
+ /* Now remove the entry in the waiting list for all requests
+ which didn't terminate. */
+ while (cnt-- > 0)
+ if (list[cnt] != NULL && list[cnt]->__error_code == EINPROGRESS)
+ {
+ struct waitlist **listp;
+
+ assert (requestlist[cnt] != NULL);
+
+ /* There is the chance that we cannot find our entry anymore. This
+ could happen if the request terminated and restarted again. */
+ listp = &requestlist[cnt]->waiting;
+ while (*listp != NULL && *listp != &waitlist[cnt])
+ listp = &(*listp)->next;
+
+ if (*listp != NULL)
+ *listp = (*listp)->next;
+ }
+
+#ifndef DONT_NEED_AIO_MISC_COND
+ /* Release the conditional variable. */
+ if (__builtin_expect (pthread_cond_destroy (&cond) != 0, 0))
+ /* This must never happen. */
+ abort ();
+#endif
+
+ if (result != 0)
+ {
+#ifndef DONT_NEED_AIO_MISC_COND
+ /* An error occurred. Possibly it's ETIMEDOUT. We have to translate
+ the timeout error report of `pthread_cond_timedwait' to the
+ form expected from `aio_suspend'. */
+ if (result == ETIMEDOUT)
+ __set_errno (EAGAIN);
+ else
+#endif
+ __set_errno (result);
+
+ result = -1;
+ }
+
+ /* Release the mutex. */
+ pthread_mutex_unlock (&__aio_requests_mutex);
+
+ return result;
+}
+
+weak_alias (aio_suspend, aio_suspend64)
diff --git a/libc/sysdeps/pthread/aio_write.c b/libc/sysdeps/pthread/aio_write.c
new file mode 100644
index 000000000..d61c5fbf9
--- /dev/null
+++ b/libc/sysdeps/pthread/aio_write.c
@@ -0,0 +1,32 @@
+/* Asynchronous write.
+ Copyright (C) 1997, 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <aio.h>
+
+#include <aio_misc.h>
+
+
+int
+aio_write (aiocbp)
+ struct aiocb *aiocbp;
+{
+ return (__aio_enqueue_request ((aiocb_union *) aiocbp, LIO_WRITE) == NULL
+ ? -1 : 0);
+}
diff --git a/libc/sysdeps/pthread/aio_write64.c b/libc/sysdeps/pthread/aio_write64.c
new file mode 100644
index 000000000..4e23a3af9
--- /dev/null
+++ b/libc/sysdeps/pthread/aio_write64.c
@@ -0,0 +1,32 @@
+/* Asynchronous write, 64bit offset version.
+ Copyright (C) 1997, 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <aio.h>
+
+#include <aio_misc.h>
+
+
+int
+aio_write64 (aiocbp)
+ struct aiocb64 *aiocbp;
+{
+ return (__aio_enqueue_request ((aiocb_union *) aiocbp, LIO_WRITE64) == NULL
+ ? -1 : 0);
+}
diff --git a/libc/sysdeps/pthread/configure b/libc/sysdeps/pthread/configure
new file mode 100644
index 000000000..e39d31138
--- /dev/null
+++ b/libc/sysdeps/pthread/configure
@@ -0,0 +1,3 @@
+# Local configure fragment for sysdeps/pthread.
+
+DEFINES="$DEFINES -D_LIBC_REENTRANT"
diff --git a/libc/sysdeps/pthread/lio_listio.c b/libc/sysdeps/pthread/lio_listio.c
new file mode 100644
index 000000000..c652404ae
--- /dev/null
+++ b/libc/sysdeps/pthread/lio_listio.c
@@ -0,0 +1,266 @@
+/* Enqueue and list of read or write requests.
+ Copyright (C) 1997,1998,1999,2000,2001,2003,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef lio_listio
+#include <aio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <aio_misc.h>
+
+#define LIO_OPCODE_BASE 0
+#endif
+
+#include <shlib-compat.h>
+
+
+/* We need this special structure to handle asynchronous I/O. */
+struct async_waitlist
+ {
+ int counter;
+ struct sigevent sigev;
+ struct waitlist list[0];
+ };
+
+
+/* The code in glibc 2.1 to glibc 2.4 issued only one event when all
+ requests submitted with lio_listio finished. The existing practice
+ is to issue events for the individual requests as well. This is
+ what the new code does. */
+#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_4)
+# define LIO_MODE(mode) ((mode) & 127)
+# define NO_INDIVIDUAL_EVENT_P(mode) ((mode) & 128)
+#else
+# define LIO_MODE(mode) mode
+# define NO_INDIVIDUAL_EVENT_P(mode) 0
+#endif
+
+
+static int
+lio_listio_internal (int mode, struct aiocb *const list[], int nent,
+ struct sigevent *sig)
+{
+ struct sigevent defsigev;
+ struct requestlist *requests[nent];
+ int cnt;
+ volatile int total = 0;
+ int result = 0;
+
+ if (sig == NULL)
+ {
+ defsigev.sigev_notify = SIGEV_NONE;
+ sig = &defsigev;
+ }
+
+ /* Request the mutex. */
+ pthread_mutex_lock (&__aio_requests_mutex);
+
+ /* Now we can enqueue all requests. Since we already acquired the
+ mutex the enqueue function need not do this. */
+ for (cnt = 0; cnt < nent; ++cnt)
+ if (list[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP)
+ {
+ if (NO_INDIVIDUAL_EVENT_P (mode))
+ list[cnt]->aio_sigevent.sigev_notify = SIGEV_NONE;
+
+ requests[cnt] = __aio_enqueue_request ((aiocb_union *) list[cnt],
+ (list[cnt]->aio_lio_opcode
+ | LIO_OPCODE_BASE));
+
+ if (requests[cnt] != NULL)
+ /* Successfully enqueued. */
+ ++total;
+ else
+ /* Signal that we've seen an error. `errno' and the error code
+ of the aiocb will tell more. */
+ result = -1;
+ }
+ else
+ requests[cnt] = NULL;
+
+ if (total == 0)
+ {
+ /* We don't have anything to do except signalling if we work
+ asynchronously. */
+
+ /* Release the mutex. We do this before raising a signal since the
+ signal handler might do a `siglongjmp' and then the mutex is
+ locked forever. */
+ pthread_mutex_unlock (&__aio_requests_mutex);
+
+ if (LIO_MODE (mode) == LIO_NOWAIT)
+ {
+#ifdef BROKEN_THREAD_SIGNALS
+ __aio_notify_only (sig,
+ sig->sigev_notify == SIGEV_SIGNAL ? getpid () : 0);
+#else
+ __aio_notify_only (sig);
+#endif
+ }
+
+ return result;
+ }
+ else if (LIO_MODE (mode) == LIO_WAIT)
+ {
+#ifndef DONT_NEED_AIO_MISC_COND
+ pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+ int oldstate;
+#endif
+ struct waitlist waitlist[nent];
+
+ total = 0;
+ for (cnt = 0; cnt < nent; ++cnt)
+ {
+ assert (requests[cnt] == NULL || list[cnt] != NULL);
+
+ if (requests[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP)
+ {
+#ifndef DONT_NEED_AIO_MISC_COND
+ waitlist[cnt].cond = &cond;
+#endif
+ waitlist[cnt].result = &result;
+ waitlist[cnt].next = requests[cnt]->waiting;
+ waitlist[cnt].counterp = &total;
+ waitlist[cnt].sigevp = NULL;
+#ifdef BROKEN_THREAD_SIGNALS
+ waitlist[cnt].caller_pid = 0; /* Not needed. */
+#endif
+ requests[cnt]->waiting = &waitlist[cnt];
+ ++total;
+ }
+ }
+
+#ifdef DONT_NEED_AIO_MISC_COND
+ AIO_MISC_WAIT (result, total, NULL, 0);
+#else
+ /* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancellation
+ points we must be careful. We added entries to the waiting lists
+ which we must remove. So defer cancellation for now. */
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);
+
+ while (total > 0)
+ pthread_cond_wait (&cond, &__aio_requests_mutex);
+
+ /* Now it's time to restore the cancellation state. */
+ pthread_setcancelstate (oldstate, NULL);
+
+ /* Release the conditional variable. */
+ if (pthread_cond_destroy (&cond) != 0)
+ /* This must never happen. */
+ abort ();
+#endif
+
+ /* If any of the I/O requests failed, return -1 and set errno. */
+ if (result != 0)
+ {
+ __set_errno (result == EINTR ? EINTR : EIO);
+ result = -1;
+ }
+ }
+ else
+ {
+ struct async_waitlist *waitlist;
+
+ waitlist = (struct async_waitlist *)
+ malloc (sizeof (struct async_waitlist)
+ + (nent * sizeof (struct waitlist)));
+
+ if (waitlist == NULL)
+ {
+ __set_errno (EAGAIN);
+ result = -1;
+ }
+ else
+ {
+#ifdef BROKEN_THREAD_SIGNALS
+ pid_t caller_pid = sig->sigev_notify == SIGEV_SIGNAL ? getpid () : 0;
+#endif
+ total = 0;
+
+ for (cnt = 0; cnt < nent; ++cnt)
+ {
+ assert (requests[cnt] == NULL || list[cnt] != NULL);
+
+ if (requests[cnt] != NULL
+ && list[cnt]->aio_lio_opcode != LIO_NOP)
+ {
+#ifndef DONT_NEED_AIO_MISC_COND
+ waitlist->list[cnt].cond = NULL;
+#endif
+ waitlist->list[cnt].result = NULL;
+ waitlist->list[cnt].next = requests[cnt]->waiting;
+ waitlist->list[cnt].counterp = &waitlist->counter;
+ waitlist->list[cnt].sigevp = &waitlist->sigev;
+#ifdef BROKEN_THREAD_SIGNALS
+ waitlist->list[cnt].caller_pid = caller_pid;
+#endif
+ requests[cnt]->waiting = &waitlist->list[cnt];
+ ++total;
+ }
+ }
+
+ waitlist->counter = total;
+ waitlist->sigev = *sig;
+ }
+ }
+
+ /* Release the mutex. */
+ pthread_mutex_unlock (&__aio_requests_mutex);
+
+ return result;
+}
+
+
+#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_4)
+int
+attribute_compat_text_section
+__lio_listio_21 (int mode, struct aiocb *const list[], int nent,
+ struct sigevent *sig)
+{
+ /* Check arguments. */
+ if (mode != LIO_WAIT && mode != LIO_NOWAIT)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return lio_listio_internal (mode | LIO_NO_INDIVIDUAL_EVENT, list, nent, sig);
+}
+compat_symbol (librt, __lio_listio_21, lio_listio, GLIBC_2_1);
+#endif
+
+
+int
+__lio_listio_item_notify (int mode, struct aiocb *const list[], int nent,
+ struct sigevent *sig)
+{
+ /* Check arguments. */
+ if (mode != LIO_WAIT && mode != LIO_NOWAIT)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return lio_listio_internal (mode, list, nent, sig);
+}
+versioned_symbol (librt, __lio_listio_item_notify, lio_listio, GLIBC_2_4);
diff --git a/libc/sysdeps/pthread/lio_listio64.c b/libc/sysdeps/pthread/lio_listio64.c
new file mode 100644
index 000000000..c6b7cf7bd
--- /dev/null
+++ b/libc/sysdeps/pthread/lio_listio64.c
@@ -0,0 +1,34 @@
+/* Enqueue and list of read or write requests, 64bit offset version.
+ Copyright (C) 1997,1998,1999,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <aio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <aio_misc.h>
+
+#define lio_listio lio_listio64
+#define __lio_listio_21 __lio_listio64_21
+#define __lio_listio_item_notify __lio_listio64_item_notify
+#define aiocb aiocb64
+#define LIO_OPCODE_BASE 128
+#include <lio_listio.c>
diff --git a/libc/sysdeps/s390/Implies b/libc/sysdeps/s390/Implies
new file mode 100644
index 000000000..1945b1f4b
--- /dev/null
+++ b/libc/sysdeps/s390/Implies
@@ -0,0 +1,3 @@
+ieee754/ldbl-128
+ieee754/dbl-64
+ieee754/flt-32
diff --git a/libc/sysdeps/s390/Versions b/libc/sysdeps/s390/Versions
new file mode 100644
index 000000000..e18617c39
--- /dev/null
+++ b/libc/sysdeps/s390/Versions
@@ -0,0 +1,6 @@
+ld {
+ GLIBC_2.3 {
+ # runtime interface to TLS
+ __tls_get_offset;
+ }
+}
diff --git a/libc/sysdeps/s390/abort-instr.h b/libc/sysdeps/s390/abort-instr.h
new file mode 100644
index 000000000..6544b2d61
--- /dev/null
+++ b/libc/sysdeps/s390/abort-instr.h
@@ -0,0 +1,2 @@
+/* An op-code of 0 should crash any program. */
+#define ABORT_INSTRUCTION asm (".word 0")
diff --git a/libc/sysdeps/s390/asm-syntax.h b/libc/sysdeps/s390/asm-syntax.h
new file mode 100644
index 000000000..d1cd80f10
--- /dev/null
+++ b/libc/sysdeps/s390/asm-syntax.h
@@ -0,0 +1,41 @@
+/* Definitions for S/390 syntax variations.
+ Copyright (C) 1992, 1994, 1995, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library. Its master source is NOT part of
+ the C library, however. The master source lives in the GNU MP Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#undef ALIGN
+#if defined NOLOG_ALIGN || defined HAVE_ELF
+# define ALIGN(log) .align 1<<log
+#else
+# define ALIGN(log) .align log
+#endif
+
+#undef L
+#ifdef __ELF__
+# ifdef __STDC__
+# define L(body) .L##body
+# else
+# define L(body) .L/**/body
+# endif
+#else
+# ifdef __STDC__
+# define L(body) L##body
+# else
+# define L(body) L/**/body
+# endif
+#endif
diff --git a/libc/sysdeps/s390/bits/atomic.h b/libc/sysdeps/s390/bits/atomic.h
new file mode 100644
index 000000000..aa0047341
--- /dev/null
+++ b/libc/sysdeps/s390/bits/atomic.h
@@ -0,0 +1,76 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+
+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+
+#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ ({ __typeof (mem) __archmem = (mem); \
+ __typeof (*mem) __archold = (oldval); \
+ __asm __volatile ("cs %0,%2,%1" \
+ : "+d" (__archold), "=Q" (*__archmem) \
+ : "d" (newval), "m" (*__archmem) : "cc" ); \
+ __archold; })
+
+#ifdef __s390x__
+# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ __typeof (mem) __archmem = (mem); \
+ __typeof (*mem) __archold = (oldval); \
+ __asm __volatile ("csg %0,%2,%1" \
+ : "+d" (__archold), "=Q" (*__archmem) \
+ : "d" ((long) (newval)), "m" (*__archmem) : "cc" ); \
+ __archold; })
+#else
+/* For 31 bit we do not really need 64-bit compare-and-exchange. We can
+ implement them by use of the csd instruction. The straightforward
+ implementation causes warnings so we skip the definition for now. */
+# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+#endif
diff --git a/libc/sysdeps/s390/bits/byteswap.h b/libc/sysdeps/s390/bits/byteswap.h
new file mode 100644
index 000000000..d0e31b836
--- /dev/null
+++ b/libc/sysdeps/s390/bits/byteswap.h
@@ -0,0 +1,158 @@
+/* Macros to swap the order of bytes in integer values. s390 version.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
+# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H 1
+
+#define __bswap_constant_16(x) \
+ ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+
+/* Swap bytes in 16 bit value. */
+#if defined __GNUC__ && __GNUC__ >= 2
+# if __WORDSIZE == 64
+# define __bswap_16(x) \
+ (__extension__ \
+ ({ unsigned short int __v, __x = (x); \
+ if (__builtin_constant_p (x)) \
+ __v = __bswap_constant_16 (__x); \
+ else { \
+ unsigned short int __tmp = (unsigned short int) (__x); \
+ __asm__ __volatile__ ( \
+ "lrvh %0,%1" \
+ : "=&d" (__v) : "m" (__tmp) ); \
+ } \
+ __v; }))
+# else
+# define __bswap_16(x) \
+ (__extension__ \
+ ({ unsigned short int __v, __x = (x); \
+ if (__builtin_constant_p (x)) \
+ __v = __bswap_constant_16 (__x); \
+ else { \
+ unsigned short int __tmp = (unsigned short int) (__x); \
+ __asm__ __volatile__ ( \
+ "sr %0,%0\n" \
+ "la 1,%1\n" \
+ "icm %0,2,1(1)\n" \
+ "ic %0,0(1)" \
+ : "=&d" (__v) : "m" (__tmp) : "1"); \
+ } \
+ __v; }))
+# endif
+#else
+/* This is better than nothing. */
+static __inline unsigned short int
+__bswap_16 (unsigned short int __bsx)
+{
+ return __bswap_constant_16 (__bsx);
+}
+#endif
+
+/* Swap bytes in 32 bit value. */
+#define __bswap_constant_32(x) \
+ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
+ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+# if __WORDSIZE == 64
+# define __bswap_32(x) \
+ (__extension__ \
+ ({ unsigned int __v, __x = (x); \
+ if (__builtin_constant_p (x)) \
+ __v = __bswap_constant_32 (__x); \
+ else { \
+ unsigned int __tmp = (unsigned int) (__x); \
+ __asm__ __volatile__ ( \
+ "lrv %0,%1" \
+ : "=&d" (__v) : "m" (__tmp)); \
+ } \
+ __v; }))
+# else
+# define __bswap_32(x) \
+ (__extension__ \
+ ({ unsigned int __v, __x = (x); \
+ if (__builtin_constant_p (x)) \
+ __v = __bswap_constant_32 (__x); \
+ else { \
+ unsigned int __tmp = (unsigned int) (__x); \
+ __asm__ __volatile__ ( \
+ "la 1,%1\n" \
+ "icm %0,8,3(1)\n" \
+ "icm %0,4,2(1)\n" \
+ "icm %0,2,1(1)\n" \
+ "ic %0,0(1)" \
+ : "=&d" (__v) : "m" (__tmp) : "1"); \
+ } \
+ __v; }))
+# endif
+#else
+static __inline unsigned int
+__bswap_32 (unsigned int __bsx)
+{
+ return __bswap_constant_32 (__bsx);
+}
+#endif
+
+/* Swap bytes in 64 bit value. */
+#define __bswap_constant_64(x) \
+ ((((x)&0xff00000000000000) >> 56) | (((x)&0x00ff000000000000) >> 40) | \
+ (((x)&0x0000ff0000000000) >> 24) | (((x)&0x000000ff00000000) >> 8) | \
+ (((x)&0x00000000ff000000) << 8) | (((x)&0x0000000000ff0000) << 24) | \
+ (((x)&0x000000000000ff00) << 40) | (((x)&0x00000000000000ff) << 56))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+# if __WORDSIZE == 64
+# define __bswap_64(x) \
+ (__extension__ \
+ ({ unsigned long __w, __x = (x); \
+ if (__builtin_constant_p (x)) \
+ __w = __bswap_constant_64 (__x); \
+ else { \
+ unsigned long __tmp = (unsigned long) (__x); \
+ __asm__ __volatile__ ( \
+ "lrvg %0,%1" \
+ : "=&d" (__w) : "m" (__tmp)); \
+ } \
+ __w; }))
+# else
+# define __bswap_64(x) \
+ __extension__ \
+ ({ union { unsigned long long int __ll; \
+ unsigned long int __l[2]; } __w, __r; \
+ __w.__ll = (x); \
+ __r.__l[0] = __bswap_32 (__w.__l[1]); \
+ __r.__l[1] = __bswap_32 (__w.__l[0]); \
+ __r.__ll; })
+# endif
+#else
+static __inline unsigned long long int
+__bswap_64 (unsigned long long int __bsx)
+{
+ return __bswap_constant_64 (__bsx);
+}
+#endif
+
+#endif /* _BITS_BYTESWAP_H */
diff --git a/libc/sysdeps/s390/bits/endian.h b/libc/sysdeps/s390/bits/endian.h
new file mode 100644
index 000000000..ac27f0119
--- /dev/null
+++ b/libc/sysdeps/s390/bits/endian.h
@@ -0,0 +1,7 @@
+/* s390 is big-endian */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#define __BYTE_ORDER __BIG_ENDIAN
diff --git a/libc/sysdeps/s390/bits/link.h b/libc/sysdeps/s390/bits/link.h
new file mode 100644
index 000000000..70f004382
--- /dev/null
+++ b/libc/sysdeps/s390/bits/link.h
@@ -0,0 +1,111 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+
+#if __ELF_NATIVE_CLASS == 32
+
+/* Registers for entry into PLT on s390-32. */
+typedef struct La_s390_32_regs
+{
+ uint32_t lr_r2;
+ uint32_t lr_r3;
+ uint32_t lr_r4;
+ uint32_t lr_r5;
+ uint32_t lr_r6;
+ double lr_fp0;
+ double lr_fp2;
+} La_s390_32_regs;
+
+/* Return values for calls from PLT on s390-32. */
+typedef struct La_s390_32_retval
+{
+ uint32_t lrv_r2;
+ uint32_t lrv_r3;
+ double lrv_fp0;
+} La_s390_32_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf32_Addr la_s390_32_gnu_pltenter (Elf32_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_s390_32_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_s390_32_gnu_pltexit (Elf32_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_s390_32_regs *__inregs,
+ La_s390_32_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
+
+#else
+
+/* Registers for entry into PLT on s390-64. */
+typedef struct La_s390_64_regs
+{
+ uint64_t lr_r2;
+ uint64_t lr_r3;
+ uint64_t lr_r4;
+ uint64_t lr_r5;
+ uint64_t lr_r6;
+ double lr_fp0;
+ double lr_fp2;
+ double lr_fp4;
+ double lr_fp6;
+} La_s390_64_regs;
+
+/* Return values for calls from PLT on s390-64. */
+typedef struct La_s390_64_retval
+{
+ uint64_t lrv_r2;
+ double lrv_fp0;
+} La_s390_64_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf64_Addr la_s390_64_gnu_pltenter (Elf64_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_s390_64_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_s390_64_gnu_pltexit (Elf64_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_s390_64_regs *__inregs,
+ La_s390_64_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
+
+#endif
diff --git a/libc/sysdeps/s390/bits/linkmap.h b/libc/sysdeps/s390/bits/linkmap.h
new file mode 100644
index 000000000..fc1fba363
--- /dev/null
+++ b/libc/sysdeps/s390/bits/linkmap.h
@@ -0,0 +1,13 @@
+#if __WORDSIZE == 64
+struct link_map_machine
+ {
+ Elf64_Addr plt; /* Address of .plt + 0x2e */
+ Elf64_Addr gotplt; /* Address of .got + 0x18 */
+ };
+#else
+struct link_map_machine
+ {
+ Elf32_Addr plt; /* Address of .plt + 0x2c */
+ Elf32_Addr gotplt; /* Address of .got + 0x0c */
+ };
+#endif
diff --git a/libc/sysdeps/s390/bits/mathdef.h b/libc/sysdeps/s390/bits/mathdef.h
new file mode 100644
index 000000000..4dcb612c3
--- /dev/null
+++ b/libc/sysdeps/s390/bits/mathdef.h
@@ -0,0 +1,38 @@
+/* Copyright (C) 1997, 1998, 1999, 2000, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
+/* Normally, there is no long double type and the `float' and `double'
+ expressions are evaluated as `double'. */
+typedef double float_t; /* `float' expressions are evaluated as
+ `double'. */
+typedef double double_t; /* `double' expressions are evaluated as
+ `double'. */
+
+/* The values returned by `ilogb' for 0 and NaN respectively. */
+# define FP_ILOGB0 (-2147483647)
+# define FP_ILOGBNAN 2147483647
+
+#endif /* ISO C99 */
diff --git a/libc/sysdeps/s390/bits/setjmp.h b/libc/sysdeps/s390/bits/setjmp.h
new file mode 100644
index 000000000..5588c0330
--- /dev/null
+++ b/libc/sysdeps/s390/bits/setjmp.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 2000,2001,2002,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Define the machine-dependent type `jmp_buf'. IBM s390 version. */
+
+#ifndef __S390_SETJMP_H__
+#define __S390_SETJMP_H__
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#ifndef _ASM
+
+typedef struct __s390_jmp_buf
+{
+ /* We save registers 6-15. */
+ long int __gregs[10];
+
+# if __WORDSIZE == 64
+ /* We save fpu registers 1, 3, 5 and 7. */
+ long __fpregs[8];
+# else
+ /* We save fpu registers 4 and 6. */
+ long __fpregs[4];
+# endif
+} __jmp_buf[1];
+
+#endif
+
+#endif /* __S390_SETJMP_H__ */
diff --git a/libc/sysdeps/s390/bits/string.h b/libc/sysdeps/s390/bits/string.h
new file mode 100644
index 000000000..d83df39bb
--- /dev/null
+++ b/libc/sysdeps/s390/bits/string.h
@@ -0,0 +1,231 @@
+/* Optimized, inlined string functions. S/390 version.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _STRING_H
+# error "Never use <bits/string.h> directly; include <string.h> instead."
+#endif
+
+/* The s390 processors can access unaligned multi-byte variables. */
+#define _STRING_ARCH_unaligned 1
+
+/* We only provide optimizations if the user selects them and if
+ GNU CC is used. */
+#if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
+ && defined __GNUC__ && __GNUC__ >= 2
+
+#ifndef __STRING_INLINE
+# ifdef __cplusplus
+# define __STRING_INLINE inline
+# else
+# define __STRING_INLINE extern __inline
+# endif
+#endif
+
+#define _HAVE_STRING_ARCH_strlen 1
+#ifndef _FORCE_INLINES
+__STRING_INLINE size_t
+strlen (__const char *__str)
+{
+ char *__ptr, *__tmp;
+
+ __ptr = (char *) 0;
+ __tmp = (char *) __str;
+ __asm__ __volatile__ (" la 0,0\n"
+ "0: srst %0,%1\n"
+ " jo 0b\n"
+ : "+&a" (__ptr), "+&a" (__tmp) :
+ : "cc", "memory", "0" );
+ return (size_t) (__ptr - __str);
+}
+#endif
+
+/* Copy SRC to DEST. */
+#define _HAVE_STRING_ARCH_strcpy 1
+#ifndef _FORCE_INLINES
+__STRING_INLINE char *
+strcpy (char *__dest, __const char *__src)
+{
+ char *tmp = __dest;
+
+ __asm__ __volatile__ (" la 0,0\n"
+ "0: mvst %0,%1\n"
+ " jo 0b"
+ : "+&a" (__dest), "+&a" (__src) :
+ : "cc", "memory", "0" );
+ return tmp;
+}
+#endif
+
+#define _HAVE_STRING_ARCH_strncpy 1
+#ifndef _FORCE_INLINES
+__STRING_INLINE char *
+strncpy (char *__dest, __const char *__src, size_t __n)
+{
+ char *__ret = __dest;
+ char *__ptr;
+ size_t __diff;
+
+ if (__n > 0) {
+ __diff = (size_t) (__dest - __src);
+ __ptr = (char *) __src;
+ __asm__ __volatile__ (" j 1f\n"
+ "0: la %0,1(%0)\n"
+ "1: icm 0,1,0(%0)\n"
+ " stc 0,0(%2,%0)\n"
+ " jz 3f\n"
+#if defined(__s390x__)
+ " brctg %1,0b\n"
+#else
+ " brct %1,0b\n"
+#endif
+ " j 4f\n"
+ "2: la %0,1(%0)\n"
+ " stc 0,0(%2,%0)\n"
+#if defined(__s390x__)
+ "3: brctg %1,2b\n"
+#else
+ "3: brct %1,2b\n"
+#endif
+ "4:"
+ : "+&a" (__ptr), "+&a" (__n) : "a" (__diff)
+ : "cc", "memory", "0" );
+ }
+ return __ret;
+}
+#endif
+
+/* Append SRC onto DEST. */
+#define _HAVE_STRING_ARCH_strcat 1
+#ifndef _FORCE_INLINES
+__STRING_INLINE char *
+strcat(char *__dest, const char *__src)
+{
+ char *__ret = __dest;
+ char *__ptr, *__tmp;
+
+ /* Move __ptr to the end of __dest. */
+ __ptr = (char *) 0;
+ __tmp = __dest;
+ __asm__ __volatile__ (" la 0,0\n"
+ "0: srst %0,%1\n"
+ " jo 0b\n"
+ : "+&a" (__ptr), "+&a" (__tmp) :
+ : "cc", "0" );
+
+ /* Now do the copy. */
+ __asm__ __volatile__ (" la 0,0\n"
+ "0: mvst %0,%1\n"
+ " jo 0b"
+ : "+&a" (__ptr), "+&a" (__src) :
+ : "cc", "memory", "0" );
+ return __ret;
+}
+#endif
+
+/* Append no more than N characters from SRC onto DEST. */
+#define _HAVE_STRING_ARCH_strncat 1
+#ifndef _FORCE_INLINES
+__STRING_INLINE char *
+strncat (char *__dest, __const char *__src, size_t __n)
+{
+ char *__ret = __dest;
+ char *__ptr, *__tmp;
+ size_t __diff;
+
+ if (__n > 0) {
+ /* Move __ptr to the end of __dest. */
+ __ptr = (char *) 0;
+ __tmp = __dest;
+ __asm__ __volatile__ (" la 0,0\n"
+ "0: srst %0,%1\n"
+ " jo 0b\n"
+ : "+&a" (__ptr), "+&a" (__tmp) :
+ : "cc", "memory", "0" );
+
+ __diff = (size_t) (__ptr - __src);
+ __tmp = (char *) __src;
+ __asm__ __volatile__ (" j 1f\n"
+ "0: la %0,1(%0)\n"
+ "1: icm 0,1,0(%0)\n"
+ " stc 0,0(%2,%0)\n"
+ " jz 2f\n"
+#if defined(__s390x__)
+ " brctg %1,0b\n"
+#else
+ " brct %1,0b\n"
+#endif
+ " slr 0,0\n"
+ " stc 0,1(%2,%0)\n"
+ "2:"
+ : "+&a" (__tmp), "+&a" (__n) : "a" (__diff)
+ : "cc", "memory", "0" );
+
+ }
+ return __ret;
+}
+#endif
+
+/* Search N bytes of S for C. */
+#define _HAVE_STRING_ARCH_memchr 1
+#ifndef _FORCE_INLINES
+__STRING_INLINE void *
+memchr (__const void *__str, int __c, size_t __n)
+{
+ char *__ptr, *__tmp;
+
+ __tmp = (char *) __str;
+ __ptr = (char *) __tmp + __n;
+ __asm__ __volatile__ (" lhi 0,0xff\n"
+ " nr 0,%2\n"
+ "0: srst %0,%1\n"
+ " jo 0b\n"
+ " brc 13,1f\n"
+ " la %0,0\n"
+ "1:"
+ : "+&a" (__ptr), "+&a" (__tmp) : "d" (__c)
+ : "cc", "memory", "0" );
+ return __ptr;
+}
+#endif
+
+/* Search N bytes of S for C. */
+#define _HAVE_STRING_ARCH_memchr 1
+#ifndef _FORCE_INLINES
+__STRING_INLINE int
+strcmp (__const char *__s1, __const char *__s2)
+{
+ char *__p1, *__p2;
+ int __ret;
+
+ __p1 = (char *) __s1;
+ __p2 = (char *) __s2;
+ __asm__ __volatile__ (" slr 0,0\n"
+ "0: clst %1,%2\n"
+ " jo 0b\n"
+ " ipm %0\n"
+ " srl %0,28"
+ : "=d" (__ret), "+&a" (__p1), "+&a" (__p2) :
+ : "cc", "memory", "0" );
+ __ret = (__ret == 0) ? 0 : (__ret == 1) ? -1 : 1;
+ return __ret;
+}
+#endif
+
+#endif /* Use string inlines && GNU CC. */
diff --git a/libc/sysdeps/s390/bits/xtitypes.h b/libc/sysdeps/s390/bits/xtitypes.h
new file mode 100644
index 000000000..9ea14a13d
--- /dev/null
+++ b/libc/sysdeps/s390/bits/xtitypes.h
@@ -0,0 +1,34 @@
+/* bits/xtitypes.h -- Define some types used by <bits/stropts.h>. S390/S390x
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _STROPTS_H
+# error "Never include <bits/xtitypes.h> directly; use <stropts.h> instead."
+#endif
+
+#ifndef _BITS_XTITYPES_H
+#define _BITS_XTITYPES_H 1
+
+#include <bits/types.h>
+
+/* This type is used by some structs in <bits/stropts.h>. */
+typedef __S32_TYPE __t_scalar_t;
+typedef __U32_TYPE __t_uscalar_t;
+
+
+#endif /* bits/xtitypes.h */
diff --git a/libc/sysdeps/s390/dl-tls.h b/libc/sysdeps/s390/dl-tls.h
new file mode 100644
index 000000000..056046285
--- /dev/null
+++ b/libc/sysdeps/s390/dl-tls.h
@@ -0,0 +1,77 @@
+/* Thread-local storage handling in the ELF dynamic linker. s390 version.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* Type used for the representation of TLS information in the GOT. */
+typedef struct
+{
+ unsigned long int ti_module;
+ unsigned long int ti_offset;
+} tls_index;
+
+
+#ifdef SHARED
+/* This is the prototype for the GNU version. */
+extern void *__tls_get_addr (tls_index *ti) attribute_hidden;
+extern unsigned long __tls_get_offset (unsigned long got_offset);
+
+# ifdef IS_IN_rtld
+/* The special thing about the s390 TLS ABI is that we do not have the
+ standard __tls_get_addr function but the __tls_get_offset function
+ which differs in two important aspects:
+ 1) __tls_get_offset gets a got offset instead of a pointer to the
+ tls_index structure
+ 2) __tls_get_offset returns the offset of the requested variable to
+ the thread descriptor instead of a pointer to the variable.
+ */
+# ifdef __s390x__
+asm("\n\
+ .text\n\
+ .globl __tls_get_offset\n\
+ .type __tls_get_offset, @function\n\
+ .align 4\n\
+__tls_get_offset:\n\
+ la %r2,0(%r2,%r12)\n\
+ jg __tls_get_addr\n\
+");
+# elif defined __s390__
+asm("\n\
+ .text\n\
+ .globl __tls_get_offset\n\
+ .type __tls_get_offset, @function\n\
+ .align 4\n\
+__tls_get_offset:\n\
+ basr %r3,0\n\
+0: la %r2,0(%r2,%r12)\n\
+ l %r4,1f-0b(%r3)\n\
+ b 0(%r4,%r3)\n\
+1: .long __tls_get_addr - 0b\n\
+");
+# endif
+# endif
+
+# define GET_ADDR_OFFSET \
+ (ti->ti_offset - (unsigned long) __builtin_thread_pointer ())
+
+# define __TLS_GET_ADDR(__ti) \
+ ({ extern char _GLOBAL_OFFSET_TABLE_[] attribute_hidden; \
+ (void *) __tls_get_offset ((char *) (__ti) - _GLOBAL_OFFSET_TABLE_) \
+ + (unsigned long) __builtin_thread_pointer (); })
+
+#endif
diff --git a/libc/sysdeps/s390/ffs.c b/libc/sysdeps/s390/ffs.c
new file mode 100644
index 000000000..aa17233db
--- /dev/null
+++ b/libc/sysdeps/s390/ffs.c
@@ -0,0 +1,71 @@
+/* ffs -- find first set bit in a word, counted from least significant end.
+ S/390 version.
+ Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <limits.h>
+#define ffsl __something_else
+#include <string.h>
+
+#undef ffs
+
+/* ffs: find first bit set. This is defined the same way as
+ the libc and compiler builtin ffs routines, therefore
+ differs in spirit from the above ffz (man ffs). */
+
+int
+__ffs (x)
+ int x;
+{
+ int r;
+
+ if (x == 0)
+ return 0;
+ __asm__(" lr %%r1,%1\n"
+ " sr %0,%0\n"
+ " tml %%r1,0xFFFF\n"
+ " jnz 0f\n"
+ " ahi %0,16\n"
+ " srl %%r1,16\n"
+ "0: tml %%r1,0x00FF\n"
+ " jnz 1f\n"
+ " ahi %0,8\n"
+ " srl %%r1,8\n"
+ "1: tml %%r1,0x000F\n"
+ " jnz 2f\n"
+ " ahi %0,4\n"
+ " srl %%r1,4\n"
+ "2: tml %%r1,0x0003\n"
+ " jnz 3f\n"
+ " ahi %0,2\n"
+ " srl %%r1,2\n"
+ "3: tml %%r1,0x0001\n"
+ " jnz 4f\n"
+ " ahi %0,1\n"
+ "4:"
+ : "=&d" (r) : "d" (x) : "cc", "1" );
+ return r+1;
+}
+
+weak_alias (__ffs, ffs)
+libc_hidden_builtin_def (ffs)
+#if ULONG_MAX == UINT_MAX
+#undef ffsl
+weak_alias (__ffs, ffsl)
+#endif
diff --git a/libc/sysdeps/s390/fpu/bits/fenv.h b/libc/sysdeps/s390/fpu/bits/fenv.h
new file mode 100644
index 000000000..df1ee6e64
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/bits/fenv.h
@@ -0,0 +1,82 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+/* Define bits representing the exception. We use the bit positions
+ of the appropriate bits in the FPU control word. */
+enum
+ {
+ FE_INVALID = 0x80,
+#define FE_INVALID FE_INVALID
+ FE_DIVBYZERO = 0x40,
+#define FE_DIVBYZERO FE_DIVBYZERO
+ FE_OVERFLOW = 0x20,
+#define FE_OVERFLOW FE_OVERFLOW
+ FE_UNDERFLOW = 0x10,
+#define FE_UNDERFLOW FE_UNDERFLOW
+ FE_INEXACT = 0x08
+#define FE_INEXACT FE_INEXACT
+ };
+/* We dont use the y bit of the DXC in the floating point control register
+ as glibc has no FE encoding for fe inexact incremented
+ or fe inexact truncated.
+ We currently use the flag bits in the fpc
+ as these are sticky for feholdenv & feupdatenv as it is defined
+ in the HP Manpages. */
+
+
+#define FE_ALL_EXCEPT \
+ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+enum
+ {
+ FE_TONEAREST = 0,
+#define FE_TONEAREST FE_TONEAREST
+ FE_DOWNWARD = 0x3,
+#define FE_DOWNWARD FE_DOWNWARD
+ FE_UPWARD = 0x2,
+#define FE_UPWARD FE_UPWARD
+ FE_TOWARDZERO = 0x1
+#define FE_TOWARDZERO FE_TOWARDZERO
+ };
+
+
+/* Type representing exception flags. */
+typedef unsigned int fexcept_t; /* size of fpc */
+
+
+/* Type representing floating-point environment. This function corresponds
+ to the layout of the block written by the `fstenv'. */
+typedef struct
+{
+ fexcept_t fpc;
+ void *ieee_instruction_pointer;
+ /* failing instruction for ieee exceptions */
+} fenv_t;
+
+/* If the default argument is used we use this value. */
+#define FE_DFL_ENV ((__const fenv_t *) -1)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exceptions are masked. */
+# define FE_NOMASK_ENV ((__const fenv_t *) -2)
+#endif
diff --git a/libc/sysdeps/s390/fpu/bits/mathinline.h b/libc/sysdeps/s390/fpu/bits/mathinline.h
new file mode 100644
index 000000000..5c6b83ad0
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/bits/mathinline.h
@@ -0,0 +1,101 @@
+/* Inline math functions for s390.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
+#endif
+
+#ifdef __cplusplus
+# define __MATH_INLINE __inline
+#else
+# define __MATH_INLINE extern __inline
+#endif
+
+#if (!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \
+ && defined __OPTIMIZE__
+
+#ifdef __USE_ISOC99
+
+/* Test for negative number. Used in the signbit() macro. */
+__MATH_INLINE int
+__NTH (__signbitf (float __x))
+{
+ __extension__ union { float __f; int __i; } __u = { __f: __x };
+ return __u.__i < 0;
+}
+
+__MATH_INLINE int
+__NTH (__signbit (double __x))
+{
+ __extension__ union { double __d; long __i; } __u = { __d: __x };
+ return __u.__i < 0;
+}
+
+# ifndef __NO_LONG_DOUBLE_MATH
+__MATH_INLINE int
+__NTH (__signbitl (long double __x))
+{
+ __extension__ union { long double __l; int __i[4]; } __u = { __l: __x };
+ return __u.__i[0] < 0;
+}
+# else
+__MATH_INLINE int
+__NTH (__signbitl (long double __x))
+{
+ return __signbit ((double) __x);
+}
+# endif
+
+#endif /* C99 */
+
+/* This code is used internally in the GNU libc. */
+#ifdef __LIBC_INTERNAL_MATH_INLINES
+
+__MATH_INLINE double
+__NTH (__ieee754_sqrt (double x))
+{
+ double res;
+
+ asm ( "sqdbr %0,%1" : "=f" (res) : "f" (x) );
+ return res;
+}
+
+__MATH_INLINE float
+__NTH (__ieee754_sqrtf (float x))
+{
+ float res;
+
+ asm ( "sqebr %0,%1" : "=f" (res) : "f" (x) );
+ return res;
+}
+
+# if !defined __NO_LONG_DOUBLE_MATH
+__MATH_INLINE long double
+__NTH (sqrtl (long double __x))
+{
+ long double res;
+
+ asm ( "sqxbr %0,%1" : "=f" (res) : "f" (__x) );
+ return res;
+}
+# endif /* !__NO_LONG_DOUBLE_MATH */
+
+#endif /* __LIBC_INTERNAL_MATH_INLINES */
+
+#endif /* __NO_MATH_INLINES */
diff --git a/libc/sysdeps/s390/fpu/e_sqrt.c b/libc/sysdeps/s390/fpu/e_sqrt.c
new file mode 100644
index 000000000..e4b183e4c
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/e_sqrt.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math_private.h>
+
+double
+__ieee754_sqrt (double x)
+{
+ double res;
+
+ asm ( "sqdbr %0,%1" : "=f" (res) : "f" (x) );
+ return res;
+}
diff --git a/libc/sysdeps/s390/fpu/e_sqrtf.c b/libc/sysdeps/s390/fpu/e_sqrtf.c
new file mode 100644
index 000000000..5b5e06e8a
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/e_sqrtf.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math_private.h>
+
+float
+__ieee754_sqrtf (float x)
+{
+ float res;
+
+ asm ( "sqebr %0,%1" : "=f" (res) : "f" (x) );
+ return res;
+}
diff --git a/libc/sysdeps/s390/fpu/e_sqrtl.c b/libc/sysdeps/s390/fpu/e_sqrtl.c
new file mode 100644
index 000000000..e1daac197
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/e_sqrtl.c
@@ -0,0 +1,30 @@
+/* Square root. S/390 FPU version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math_private.h>
+
+long double
+__ieee754_sqrtl (long double x)
+{
+ long double res;
+
+ asm ( "sqxbr %0,%1" : "=f" (res) : "f" (x) );
+ return res;
+}
diff --git a/libc/sysdeps/s390/fpu/fclrexcpt.c b/libc/sysdeps/s390/fpu/fclrexcpt.c
new file mode 100644
index 000000000..358f36bd8
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/fclrexcpt.c
@@ -0,0 +1,40 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+feclearexcept (int excepts)
+{
+ fexcept_t temp;
+
+ /* Mask out unsupported bits/exceptions. */
+ excepts &= FE_ALL_EXCEPT;
+
+ _FPU_GETCW (temp);
+ /* Clear the relevant bits. */
+ temp &= ~((excepts << FPC_DXC_SHIFT)|(excepts << FPC_FLAGS_SHIFT));
+
+ /* Put the new data in effect. */
+ _FPU_SETCW (temp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libc/sysdeps/s390/fpu/fedisblxcpt.c b/libc/sysdeps/s390/fpu/fedisblxcpt.c
new file mode 100644
index 000000000..eb9749918
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/fedisblxcpt.c
@@ -0,0 +1,35 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+fedisableexcept (int excepts)
+{
+ fexcept_t temp, old_exc, new_flags;
+
+ _FPU_GETCW (temp);
+ old_exc = (temp & FPC_EXCEPTION_MASK) >> FPC_EXCEPTION_MASK_SHIFT;
+ new_flags = (temp & (~((excepts & FE_ALL_EXCEPT) << FPC_EXCEPTION_MASK_SHIFT)));
+ _FPU_SETCW (new_flags);
+
+ return old_exc;
+}
diff --git a/libc/sysdeps/s390/fpu/feenablxcpt.c b/libc/sysdeps/s390/fpu/feenablxcpt.c
new file mode 100644
index 000000000..d7a0abef0
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/feenablxcpt.c
@@ -0,0 +1,35 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+feenableexcept (int excepts)
+{
+ fexcept_t temp, old_exc, new_flags;
+
+ _FPU_GETCW (temp);
+ old_exc = (temp & FPC_EXCEPTION_MASK) >> FPC_EXCEPTION_MASK_SHIFT;
+ new_flags = (temp | ((excepts & FE_ALL_EXCEPT) << FPC_EXCEPTION_MASK_SHIFT));
+ _FPU_SETCW (new_flags);
+
+ return old_exc;
+}
diff --git a/libc/sysdeps/s390/fpu/fegetenv.c b/libc/sysdeps/s390/fpu/fegetenv.c
new file mode 100644
index 000000000..b35a76a4e
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/fegetenv.c
@@ -0,0 +1,43 @@
+/* Store current floating-point environment.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <fpu_control.h>
+#include <stddef.h>
+#include <asm/ptrace.h>
+#include <sys/ptrace.h>
+#include <unistd.h>
+
+int
+fegetenv (fenv_t *envp)
+{
+ /* The S/390 IEEE fpu doesn't keep track of the ieee instruction pointer.
+ To get around that the kernel will store the address of the last
+ fpu fault to the process structure. This ptrace call reads this value
+ from the kernel space. That means the ieee_instruction_pointer is
+ only correct after a fpu fault. That's the best we can do, there is
+ no way to find out the ieee instruction pointer if there was no fault. */
+ _FPU_GETCW (envp->fpc);
+ envp->ieee_instruction_pointer =
+ (void *) ptrace (PTRACE_PEEKUSER, getpid (), PT_IEEE_IP);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libc/sysdeps/s390/fpu/fegetexcept.c b/libc/sysdeps/s390/fpu/fegetexcept.c
new file mode 100644
index 000000000..207700639
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/fegetexcept.c
@@ -0,0 +1,31 @@
+/* Get enabled floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+fegetexcept (void)
+{
+ fexcept_t exc;
+
+ _FPU_GETCW (exc);
+ return ((exc & FPC_EXCEPTION_MASK) >> FPC_EXCEPTION_MASK_SHIFT);
+}
diff --git a/libc/sysdeps/s390/fpu/fegetround.c b/libc/sysdeps/s390/fpu/fegetround.c
new file mode 100644
index 000000000..77db27a1b
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/fegetround.c
@@ -0,0 +1,32 @@
+/* Return current rounding direction.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+fegetround (void)
+{
+ fexcept_t cw;
+
+ _FPU_GETCW (cw);
+
+ return cw & FPC_RM_MASK;
+}
diff --git a/libc/sysdeps/s390/fpu/feholdexcpt.c b/libc/sysdeps/s390/fpu/feholdexcpt.c
new file mode 100644
index 000000000..dee44dcee
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/feholdexcpt.c
@@ -0,0 +1,35 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int feholdexcept (fenv_t *envp)
+{
+ /* Store the environment. */
+ fegetenv (envp);
+ /* Clear the current sticky bits as more than one exception
+ may be generated. */
+ envp->fpc &= ~(FPC_FLAGS_MASK | FPC_DXC_MASK);
+ /* Hold from generating fpu exceptions temporarily. */
+ _FPU_SETCW ((envp->fpc & ~(FE_ALL_EXCEPT << FPC_EXCEPTION_MASK_SHIFT)));
+ return 0;
+}
+libm_hidden_def (feholdexcept)
diff --git a/libc/sysdeps/s390/fpu/fenv_libc.h b/libc/sysdeps/s390/fpu/fenv_libc.h
new file mode 100644
index 000000000..c0acff70e
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/fenv_libc.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FENV_LIBC_H
+#define _FENV_LIBC_H 1
+
+#include <fenv.h>
+
+/* Definitions from asm/s390-regs-common.h that are needed in glibc. */
+
+
+#define FPC_EXCEPTION_MASK 0xF8000000
+#define FPC_FLAGS_MASK 0x00F80000
+#define FPC_DXC_MASK 0x0000FF00
+#define FPC_RM_MASK 0x00000003
+#define FPC_VALID_MASK ((FPC_EXCEPTION_MASK|FPC_FLAGS_MASK| \
+ FPC_DXC_MASK|FPC_RM_MASK))
+
+#define FPC_EXCEPTION_MASK_SHIFT 24
+#define FPC_FLAGS_SHIFT 16
+#define FPC_DXC_SHIFT 8
+#define FPC_NOT_FPU_EXCEPTION 0x300
+
+#endif /* _FENV_LIBC_H */
diff --git a/libc/sysdeps/s390/fpu/fesetenv.c b/libc/sysdeps/s390/fpu/fesetenv.c
new file mode 100644
index 000000000..bb71c95a1
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/fesetenv.c
@@ -0,0 +1,57 @@
+/* Install given floating-point environment.
+ Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <fpu_control.h>
+#include <stddef.h>
+#include <asm/ptrace.h>
+#include <sys/ptrace.h>
+#include <unistd.h>
+
+int
+fesetenv (const fenv_t *envp)
+{
+ fenv_t env;
+
+ if (envp == FE_DFL_ENV)
+ {
+ env.fpc = _FPU_DEFAULT;
+ env.ieee_instruction_pointer = 0;
+ }
+ else if (envp == FE_NOMASK_ENV)
+ {
+ env.fpc = FPC_EXCEPTION_MASK;
+ env.ieee_instruction_pointer = 0;
+ }
+ else
+ env = (*envp);
+
+ /* The S/390 IEEE fpu doesn't have a register for the ieee
+ instruction pointer. The operating system is required to keep an
+ instruction pointer on a per process base. We read and write this
+ value with the ptrace interface. */
+ _FPU_SETCW (env.fpc);
+ ptrace (PTRACE_POKEUSER, getpid (), PT_IEEE_IP,
+ env.ieee_instruction_pointer);
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (fesetenv)
diff --git a/libc/sysdeps/s390/fpu/fesetround.c b/libc/sysdeps/s390/fpu/fesetround.c
new file mode 100644
index 000000000..d99f1db18
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/fesetround.c
@@ -0,0 +1,38 @@
+/* Set current rounding direction.
+ Copyright (C) 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+fesetround (int round)
+{
+ if ((round|FPC_RM_MASK) != FPC_RM_MASK)
+ {
+ /* ROUND is not a valid rounding mode. */
+ return 1;
+ }
+ __asm__ volatile ("srnm 0(%0)"
+ :
+ : "a" (round));
+
+ return 0;
+}
+libm_hidden_def (fesetround)
diff --git a/libc/sysdeps/s390/fpu/feupdateenv.c b/libc/sysdeps/s390/fpu/feupdateenv.c
new file mode 100644
index 000000000..64411e880
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/feupdateenv.c
@@ -0,0 +1,40 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+feupdateenv (const fenv_t *envp)
+{
+ fexcept_t temp;
+
+ _FPU_GETCW (temp);
+ temp = (temp & FPC_FLAGS_MASK) >> FPC_FLAGS_SHIFT;
+
+ /* Raise the exceptions since the last call to feholdenv */
+ /* re install saved environment. */
+ fesetenv (envp);
+ feraiseexcept ((int) temp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libc/sysdeps/s390/fpu/fgetexcptflg.c b/libc/sysdeps/s390/fpu/fgetexcptflg.c
new file mode 100644
index 000000000..b074ac302
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/fgetexcptflg.c
@@ -0,0 +1,36 @@
+/* Store current representation for exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ fexcept_t temp, newexcepts;
+
+ /* Get the current exceptions. */
+ _FPU_GETCW (temp);
+ newexcepts = (excepts << FPC_DXC_SHIFT) | (excepts << FPC_FLAGS_SHIFT);
+ *flagp = temp & newexcepts;
+
+ /* Success. */
+ return 0;
+}
diff --git a/libc/sysdeps/s390/fpu/fpu_control.h b/libc/sysdeps/s390/fpu/fpu_control.h
new file mode 100644
index 000000000..137a4d5d4
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/fpu_control.h
@@ -0,0 +1,44 @@
+/* FPU control word definitions. Stub version.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com) and
+ Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FPU_CONTROL_H
+# define _FPU_CONTROL_H
+
+# include <features.h>
+
+/* These bits are reserved are not changed. */
+# define _FPU_RESERVED 0x070700FC
+
+/* The fdlibm code requires no interrupts for exceptions. Don't
+ change the rounding mode, it would break long double I/O! */
+#define _FPU_DEFAULT 0x00000000 /* Default value. */
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t;
+
+/* Macros for accessing the hardware control word. */
+#define _FPU_GETCW(cw) __asm__ volatile ("efpc %0,0" : "=d" (cw))
+#define _FPU_SETCW(cw) __asm__ volatile ("sfpc %0,0" : : "d" (cw))
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* _FPU_CONTROL_H */
diff --git a/libc/sysdeps/s390/fpu/fraiseexcpt.c b/libc/sysdeps/s390/fpu/fraiseexcpt.c
new file mode 100644
index 000000000..4ceb5ce7b
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/fraiseexcpt.c
@@ -0,0 +1,73 @@
+/* Raise given exceptions.
+ Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com) and
+ Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <float.h>
+#include <math.h>
+
+
+static __inline__ void
+fexceptdiv (float d, float e)
+{
+ __asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) );
+}
+
+static __inline__ void
+fexceptadd (float d, float e)
+{
+ __asm__ __volatile__ ("aebr %0,%1" : : "f" (d), "f" (e) );
+}
+
+
+int
+feraiseexcept (int excepts)
+{
+ /* Raise exceptions represented by EXPECTS. But we must raise only
+ one signal at a time. It is important that if the overflow/underflow
+ exception and the inexact exception are given at the same time,
+ the overflow/underflow exception follows the inexact exception. */
+
+ /* First: invalid exception. */
+ if (FE_INVALID & excepts)
+ fexceptdiv (0.0, 0.0);
+
+ /* Next: division by zero. */
+ if (FE_DIVBYZERO & excepts)
+ fexceptdiv (1.0, 0.0);
+
+ /* Next: overflow. */
+ if (FE_OVERFLOW & excepts)
+ /* I don't think we can do the same trick as intel so we will have
+ to live with inexact coming also. */
+ fexceptadd (FLT_MAX, 1.0e32);
+
+ /* Next: underflow. */
+ if (FE_UNDERFLOW & excepts)
+ fexceptdiv (FLT_MIN, 3.0);
+
+ /* Last: inexact. */
+ if (FE_INEXACT & excepts)
+ fexceptdiv (2.0, 3.0);
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (feraiseexcept)
diff --git a/libc/sysdeps/s390/fpu/fsetexcptflg.c b/libc/sysdeps/s390/fpu/fsetexcptflg.c
new file mode 100644
index 000000000..12e3409d1
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/fsetexcptflg.c
@@ -0,0 +1,46 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <math.h>
+#include <fpu_control.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fexcept_t temp,newexcepts;
+
+ /* Get the current environment. We have to do this since we cannot
+ separately set the status word. */
+ _FPU_GETCW (temp);
+ /* Install the new exception bits in the Accrued Exception Byte. */
+ excepts = excepts & FE_ALL_EXCEPT;
+ newexcepts = (excepts << FPC_DXC_SHIFT) | (excepts << FPC_FLAGS_SHIFT);
+ temp &= ~newexcepts;
+ temp |= *flagp & newexcepts;
+
+ /* Store the new status word (along with the rest of the environment.
+ Possibly new exceptions are set but they won't get executed unless
+ the next floating-point instruction. */
+ _FPU_SETCW (temp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libc/sysdeps/s390/fpu/ftestexcept.c b/libc/sysdeps/s390/fpu/ftestexcept.c
new file mode 100644
index 000000000..51af57e90
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/ftestexcept.c
@@ -0,0 +1,33 @@
+/* Test exception in current environment.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+int
+fetestexcept (int excepts)
+{
+ fexcept_t temp;
+
+ /* Get current exceptions. */
+ _FPU_GETCW (temp);
+ temp = (temp >> FPC_DXC_SHIFT) | (temp >> FPC_FLAGS_SHIFT);
+ return temp & excepts & FE_ALL_EXCEPT;
+}
diff --git a/libc/sysdeps/s390/fpu/libm-test-ulps b/libc/sysdeps/s390/fpu/libm-test-ulps
new file mode 100644
index 000000000..989722e65
--- /dev/null
+++ b/libc/sysdeps/s390/fpu/libm-test-ulps
@@ -0,0 +1,1332 @@
+# Begin of automatic generation
+
+# atan2
+Test "atan2 (-0.00756827042671106339, -.001792735857538728036) == -1.80338464113663849327153994379639112":
+ildouble: 1
+ldouble: 1
+Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# atanh
+Test "atanh (0.75) == 0.972955074527656652552676371721589865":
+float: 1
+ifloat: 1
+
+# cacos
+Test "Imaginary part of: cacos (0.75 + 1.25 i) == 1.11752014915610270578240049553777969 - 1.13239363160530819522266333696834467 i":
+ildouble: 1
+ldouble: 1
+
+# cacosh
+Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+# casin
+Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+ildouble: 1
+ldouble: 1
+
+# casinh
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 4
+ldouble: 4
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 2
+ldouble: 2
+Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# catan
+Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+float: 3
+ifloat: 3
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+float: 4
+ifloat: 4
+Test "Imaginary part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+ildouble: 1
+ldouble: 1
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 4
+idouble: 4
+Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+float: 4
+ifloat: 4
+Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+float: 6
+ifloat: 6
+ildouble: 1
+ldouble: 1
+
+# cbrt
+Test "cbrt (-0.001) == -0.1":
+ildouble: 1
+ldouble: 1
+Test "cbrt (-27.0) == -3.0":
+double: 1
+idouble: 1
+Test "cbrt (0.75) == 0.908560296416069829445605878163630251":
+double: 1
+idouble: 1
+Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217":
+double: 1
+idouble: 1
+
+# ccos
+Test "Real part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+float: 1
+ifloat: 1
+
+# ccosh
+Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+float: 1
+ifloat: 1
+
+# cexp
+Test "Real part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+ildouble: 1
+ldouble: 1
+
+# clog
+Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+float: 3
+ifloat: 3
+Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# cos
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "cos (pi/2) == 0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# cpow
+Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+ildouble: 4
+ldouble: 4
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i":
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 10
+ldouble: 10
+Test "Real part of: cpow (2 + 0 i, 10 + 0 i) == 1024.0 + 0.0 i":
+ildouble: 2
+ldouble: 2
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+ildouble: 3
+ldouble: 3
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 2
+ifloat: 2
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# csin
+Test "Imaginary part of: csin (-2 - 3 i) == -9.15449914691142957346729954460983256 + 4.16890695996656435075481305885375484 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
+ildouble: 1
+ldouble: 1
+
+# csinh
+Test "Real part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+
+# csqrt
+Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csqrt (0.75 + 1.25 i) == 1.05065169626078392338656675760808326 + 0.594868882070379067881984030639932657 i":
+ildouble: 1
+ldouble: 1
+
+# ctan
+Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+ifloat: 1
+Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+idouble: 1
+
+# erf
+Test "erf (1.25) == 0.922900128256458230136523481197281140":
+double: 1
+idouble: 1
+
+# erfc
+Test "erfc (0.75) == 0.288844366346484868401062165408589223":
+float: 1
+ifloat: 1
+Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
+double: 1
+idouble: 1
+Test "erfc (27.0) == 0.523704892378925568501606768284954709e-318":
+ildouble: 1
+ldouble: 1
+Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8":
+double: 1
+idouble: 1
+
+# exp10
+Test "exp10 (-1) == 0.1":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "exp10 (3) == 1000":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# exp2
+Test "exp2 (10) == 1024":
+ildouble: 2
+ldouble: 2
+
+# expm1
+Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+double: 1
+idouble: 1
+Test "expm1 (1) == M_El - 1.0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# gamma
+Test "gamma (-0.5) == log(2*sqrt(pi))":
+ildouble: 1
+ldouble: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+
+# j0
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "j0 (0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# j1
+Test "j1 (-1.0) == -0.440050585744933515959682203718914913":
+ildouble: 1
+ldouble: 1
+Test "j1 (0.75) == 0.349243602174862192523281016426251335":
+ildouble: 1
+ldouble: 1
+Test "j1 (1.0) == 0.440050585744933515959682203718914913":
+ildouble: 1
+ldouble: 1
+Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+ildouble: 4
+ldouble: 4
+
+# jn
+Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "jn (0, 0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (1, -1.0) == -0.440050585744933515959682203718914913":
+ildouble: 1
+ldouble: 1
+Test "jn (1, 0.75) == 0.349243602174862192523281016426251335":
+ildouble: 1
+ldouble: 1
+Test "jn (1, 1.0) == 0.440050585744933515959682203718914913":
+ildouble: 1
+ldouble: 1
+Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+ildouble: 4
+ldouble: 4
+Test "jn (10, -1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, 1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 2
+ldouble: 2
+Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+float: 4
+ifloat: 4
+Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# lgamma
+Test "lgamma (-0.5) == log(2*sqrt(pi))":
+ildouble: 1
+ldouble: 1
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# log10
+Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "log10 (e) == log10(e)":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# log1p
+Test "log1p (-0.25) == -0.287682072451780927439219005993827432":
+float: 1
+ifloat: 1
+
+# log2
+Test "log2 (0.75) == -.415037499278843818546261056052183492":
+ildouble: 1
+ldouble: 1
+
+# sincos
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
+float: 1
+ifloat: 1
+
+# sqrt
+Test "sqrt (2) == M_SQRT2l":
+ildouble: 1
+ldouble: 1
+
+# tan
+Test "tan (pi/4) == 1":
+double: 1
+idouble: 1
+
+# tanh
+Test "tanh (-0.75) == -0.635148952387287319214434357312496495":
+ildouble: 1
+ldouble: 1
+Test "tanh (-1.0) == -0.7615941559557648881194582826047935904":
+ildouble: 1
+ldouble: 1
+Test "tanh (0.75) == 0.635148952387287319214434357312496495":
+ildouble: 1
+ldouble: 1
+Test "tanh (1.0) == 0.7615941559557648881194582826047935904":
+ildouble: 1
+ldouble: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+ifloat: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "tgamma (4) == 6":
+ildouble: 1
+ldouble: 1
+
+# y0
+Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+Test "y0 (2.0) == 0.510375672649745119596606592727157873":
+double: 1
+idouble: 1
+Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+# y1
+Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "y1 (0.75) == -1.03759455076928541973767132140642198":
+ildouble: 1
+ldouble: 1
+Test "y1 (1.5) == -0.412308626973911295952829820633445323":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# yn
+Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+Test "yn (0, 2.0) == 0.510375672649745119596606592727157873":
+double: 1
+idouble: 1
+Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "yn (1, 0.75) == -1.03759455076928541973767132140642198":
+ildouble: 1
+ldouble: 1
+Test "yn (1, 1.5) == -0.412308626973911295952829820633445323":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "yn (1, 2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 5
+ldouble: 5
+Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+idouble: 1
+Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+double: 1
+idouble: 1
+
+# Maximal error of functions:
+Function: "atan2":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "atanh":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "cacos":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cacosh":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "casin":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "catan":
+float: 4
+ifloat: 4
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh":
+double: 4
+idouble: 4
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catanh":
+float: 6
+ifloat: 6
+ildouble: 1
+ldouble: 1
+
+Function: "cbrt":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccos":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccosh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cexp":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "cexp":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "clog":
+float: 3
+ifloat: 3
+
+Function: Real part of "clog10":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cpow":
+double: 2
+float: 4
+idouble: 2
+ifloat: 4
+ildouble: 10
+ldouble: 10
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csin":
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csin":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csinh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "csqrt":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csqrt":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ctan":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ctan":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "ctanh":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ctanh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "erf":
+double: 1
+idouble: 1
+
+Function: "erfc":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "exp10":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "exp2":
+ildouble: 2
+ldouble: 2
+
+Function: "expm1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "gamma":
+ildouble: 1
+ldouble: 1
+
+Function: "hypot":
+float: 1
+ifloat: 1
+
+Function: "j0":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: "jn":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 4
+ldouble: 4
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log10":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log1p":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log2":
+ildouble: 1
+ldouble: 1
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "sqrt":
+ildouble: 1
+ldouble: 1
+
+Function: "tan":
+double: 1
+idouble: 1
+
+Function: "tanh":
+ildouble: 1
+ldouble: 1
+
+Function: "tgamma":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+# end of automatic generation
diff --git a/libc/sysdeps/s390/gccframe.h b/libc/sysdeps/s390/gccframe.h
new file mode 100644
index 000000000..2f624b8f5
--- /dev/null
+++ b/libc/sysdeps/s390/gccframe.h
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. s390 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FIRST_PSEUDO_REGISTER 34
+
+#include <sysdeps/generic/gccframe.h>
diff --git a/libc/sysdeps/s390/gmp-mparam.h b/libc/sysdeps/s390/gmp-mparam.h
new file mode 100644
index 000000000..32a2e6996
--- /dev/null
+++ b/libc/sysdeps/s390/gmp-mparam.h
@@ -0,0 +1,31 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <bits/wordsize.h>
+
+#define BITS_PER_MP_LIMB __WORDSIZE
+#define BYTES_PER_MP_LIMB (__WORDSIZE / 8)
+#define BITS_PER_LONGINT __WORDSIZE
+#define BITS_PER_INT 32
+#define BITS_PER_SHORTINT 16
+#define BITS_PER_CHAR 8
+
+#define IEEE_DOUBLE_BIG_ENDIAN 0
diff --git a/libc/sysdeps/s390/jmpbuf-offsets.h b/libc/sysdeps/s390/jmpbuf-offsets.h
new file mode 100644
index 000000000..d99fc92a2
--- /dev/null
+++ b/libc/sysdeps/s390/jmpbuf-offsets.h
@@ -0,0 +1,29 @@
+/* Private macros for accessing __jmp_buf contents. S/390 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __JB_GPR6 0
+#define __JB_GPR7 1
+#define __JB_GPR8 2
+#define __JB_GPR9 3
+#define __JB_GPR10 4
+#define __JB_GPR11 5
+#define __JB_GPR12 6
+#define __JB_GPR13 7
+#define __JB_GPR14 8
+#define __JB_GPR15 9
diff --git a/libc/sysdeps/s390/jmpbuf-unwind.h b/libc/sysdeps/s390/jmpbuf-unwind.h
new file mode 100644
index 000000000..c1a670fc7
--- /dev/null
+++ b/libc/sysdeps/s390/jmpbuf-unwind.h
@@ -0,0 +1,55 @@
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <stdint.h>
+#include <unwind.h>
+#include <bits/wordsize.h>
+#include <sysdep.h>
+
+
+/* Test if longjmp to JMPBUF would unwind the frame
+ containing a local variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \
+ ((void *) (address) < (void *) demangle ((jmpbuf)->__gregs[__JB_GPR15]))
+
+
+/* On s390{,x}, CFA is always 96 (resp. 160) bytes above actual
+ %r15. */
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, \
+ (void *) (_Unwind_GetCFA (_context) \
+ - 32 - 2 * __WORDSIZE), _adj)
+
+static inline uintptr_t __attribute__ ((unused))
+_jmpbuf_sp (__jmp_buf regs)
+{
+ uintptr_t sp = regs[0].__gregs[__JB_GPR15];
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (sp);
+#endif
+ return sp;
+}
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
+
+/* We use the normal longjmp for unwinding. */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libc/sysdeps/s390/libc-tls.c b/libc/sysdeps/s390/libc-tls.c
new file mode 100644
index 000000000..f177f436e
--- /dev/null
+++ b/libc/sysdeps/s390/libc-tls.c
@@ -0,0 +1,37 @@
+/* Thread-local storage handling in the ELF dynamic linker. S390 version.
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+#include <csu/libc-tls.c>
+
+#if USE_TLS
+
+/* On s390, the literal pool entry that refers to __tls_get_offset
+ is not removed, even if all branches that use the literal pool
+ entry gets removed by TLS optimizations. To get binaries
+ statically linked __tls_get_offset is defined here but
+ aborts if it is used. */
+
+void *
+__tls_get_offset (size_t m, size_t offset)
+{
+ abort ();
+}
+
+#endif
diff --git a/libc/sysdeps/s390/machine-gmon.h b/libc/sysdeps/s390/machine-gmon.h
new file mode 100644
index 000000000..7ca020691
--- /dev/null
+++ b/libc/sysdeps/s390/machine-gmon.h
@@ -0,0 +1,36 @@
+/* s390-specific implementation of profiling support.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* We need a special version of the `mcount' function since for S/390 it
+ must not clobber any register. */
+
+/* We must not pollute the global namespace. */
+#define mcount_internal __mcount_internal
+
+void mcount_internal (u_long frompc, u_long selfpc);
+
+#define _MCOUNT_DECL(frompc, selfpc) \
+void mcount_internal (u_long frompc, u_long selfpc)
+
+
+/* Define MCOUNT as empty since we have the implementation in another
+ file. */
+#define MCOUNT
diff --git a/libc/sysdeps/s390/memusage.h b/libc/sysdeps/s390/memusage.h
new file mode 100644
index 000000000..b74175392
--- /dev/null
+++ b/libc/sysdeps/s390/memusage.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("15"); stack_ptr; })
+
+#include <sysdeps/generic/memusage.h>
diff --git a/libc/sysdeps/s390/s390-32/Implies b/libc/sysdeps/s390/s390-32/Implies
new file mode 100644
index 000000000..39a34c5f5
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/Implies
@@ -0,0 +1 @@
+wordsize-32
diff --git a/libc/sysdeps/s390/s390-32/Makefile b/libc/sysdeps/s390/s390-32/Makefile
new file mode 100644
index 000000000..057862d91
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/Makefile
@@ -0,0 +1,11 @@
+pic-ccflag = -fpic
+
+ifeq ($(subdir),gmon)
+sysdep_routines += s390-mcount
+endif
+
+ifeq ($(subdir),elf)
+CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused
+CFLAGS-dl-load.c += -Wno-unused
+CFLAGS-dl-reloc.c += -Wno-unused
+endif
diff --git a/libc/sysdeps/s390/s390-32/Versions b/libc/sysdeps/s390/s390-32/Versions
new file mode 100644
index 000000000..2b020f8f5
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/Versions
@@ -0,0 +1,6 @@
+libc {
+ GLIBC_2.0 {
+ # Functions from libgcc.
+ __divdi3; __moddi3; __udivdi3; __umoddi3;
+ }
+}
diff --git a/libc/sysdeps/s390/s390-32/__longjmp.c b/libc/sysdeps/s390/s390-32/__longjmp.c
new file mode 100644
index 000000000..c47ebbc52
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/__longjmp.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 2000, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <setjmp.h>
+#include <bits/setjmp.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Jump to the position specified by ENV, causing the
+ setjmp call there to return VAL, or 1 if VAL is 0. */
+void
+__longjmp (__jmp_buf env, int val)
+{
+ register int r2 __asm ("%r2") = val == 0 ? 1 : val;
+#ifdef PTR_DEMANGLE
+ register uintptr_t r3 __asm ("%r3") = THREAD_GET_POINTER_GUARD ();
+ register void *r1 __asm ("%r1") = (void *) env;
+#endif
+ /* Restore registers and jump back. */
+ asm volatile ("ld %%f6,48(%1)\n\t"
+ "ld %%f4,40(%1)\n\t"
+#ifdef PTR_DEMANGLE
+ "lm %%r6,%%r13,0(%1)\n\t"
+ "lm %%r4,%%r5,32(%1)\n\t"
+ "xr %%r4,%2\n\t"
+ "xr %%r5,%2\n\t"
+ "lr %%r15,%%r5\n\t"
+ "br %%r4"
+#else
+ "lm %%r6,%%r15,0(%1)\n\t"
+ "br %%r14"
+#endif
+ : : "r" (r2),
+#ifdef PTR_DEMANGLE
+ "r" (r1), "r" (r3)
+#else
+ "a" (env)
+#endif
+ );
+
+ /* Avoid `volatile function does return' warnings. */
+ for (;;);
+}
diff --git a/libc/sysdeps/s390/s390-32/add_n.S b/libc/sysdeps/s390/s390-32/add_n.S
new file mode 100644
index 000000000..b7e6682dd
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/add_n.S
@@ -0,0 +1,64 @@
+/* Add two limb vectors of the same length > 0 and store sum in a third
+ limb vector.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr %r2
+ s1_ptr %r3
+ s2_ptr %r4
+ size %r5
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__mpn_add_n)
+ st %r6,24(%r15) # save register 6
+ cfi_offset (%r6, -72)
+ sr %r1,%r1
+ lhi %r0,1 # cannot use ahi to add carry, use alr
+.L0: l %r6,0(%r1,%r3) # .L0 -> no carry from last add
+ al %r6,0(%r1,%r4)
+ st %r6,0(%r1,%r2)
+ la %r1,4(0,%r1)
+ brc 3,.L3
+.L1: brct %r5,.L0
+ slr %r2,%r2 # no last carry to return
+ j .Lexit
+.L2: l %r6,0(%r1,%r3) # .L2 -> carry from last add
+ al %r6,0(%r1,%r4)
+ brc 3,.L4
+ alr %r6,%r0 # no carry yet, add carry from last add
+ st %r6,0(%r1,%r2)
+ la %r1,4(0,%r1)
+ brc 12,.L1 # new carry ?
+.L3: brct %r5,.L2
+ lr %r2,%r0 # return last carry
+ j .Lexit
+.L4: alr %r6,%r0 # already a carry, add carry from last add
+ st %r6,0(%r1,%r2)
+ la %r1,4(0,%r1)
+ brct %r5,.L2
+ lr %r2,%r0 # return last carry
+.Lexit: l %r6,24(%r15) # restore register 6
+ br %r14
+END(__mpn_add_n)
diff --git a/libc/sysdeps/s390/s390-32/addmul_1.S b/libc/sysdeps/s390/s390-32/addmul_1.S
new file mode 100644
index 000000000..40ba87162
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/addmul_1.S
@@ -0,0 +1,59 @@
+/* S390 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ the result to a second limb vector.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr %r2
+ s1_ptr %r3
+ sizeP %r4
+ s2_limb %r5
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__mpn_addmul_1)
+ st %r6,24(%r15)
+ cfi_offset (%r6, -72)
+ slr %r6,%r6 # cy_limb = 0
+.L0: icm %r1,15,0(%r3) # get s1_ptr[i]
+ mr %r0,%r5 # umul_ppmm(prod_high,prod_low,s1_ptr[j],s2_limb)
+ jnm .L1
+ alr %r0,%r5
+.L1: ltr %r5,%r5
+ jnm .L2
+ al %r0,0(%r3)
+.L2: alr %r1,%r6 # prod_low += cy_limb
+ lr %r6,%r0 # cy_limb = prod_high
+ brc 12,.L3
+ ahi %r6,1 # + (prod_low < cy_limb)
+.L3: al %r1,0(%r2) # prod_low += res_ptr[i]
+ brc 12,.L4
+ ahi %r6,1 # cy_limb++
+.L4: st %r1,0(%r2)
+ la %r2,4(0,%r2)
+ la %r3,4(0,%r3)
+ brct %r4,.L0
+ lr %r2,%r6 # return cy_limb
+ l %r6,24(%r15)
+.Lexit: br %r14
+END(__mpn_addmul_1)
diff --git a/libc/sysdeps/s390/s390-32/backtrace.c b/libc/sysdeps/s390/s390-32/backtrace.c
new file mode 100644
index 000000000..6adc3bc3d
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/backtrace.c
@@ -0,0 +1,145 @@
+/* Return backtrace of current program state.
+ Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <bits/libc-lock.h>
+#include <dlfcn.h>
+#include <execinfo.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unwind.h>
+
+/* This is a global variable set at program start time. It marks the
+ highest used stack address. */
+extern void *__libc_stack_end;
+
+
+/* This is the stack layout we see for every non-leaf function.
+ size offset
+ %r15 -> +------------------+
+ 4 | back chain | 0
+ 4 | end of stack | 4
+ 8 | glue | 8
+ 8 | scratch | 16
+ 40 | save area r6-r15 | 24
+ 16 | save area f4,f6 | 64
+ 16 | empty | 80
+ +------------------+
+ r14 in the save area holds the return address.
+*/
+
+struct layout
+{
+ int back_chain;
+ int end_of_stack;
+ int glue[2];
+ int scratch[2];
+ int save_grps[10];
+ int save_fp[4];
+ int empty[2];
+};
+
+struct trace_arg
+{
+ void **array;
+ int cnt, size;
+};
+
+#ifdef SHARED
+static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
+static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *);
+
+static void
+init (void)
+{
+ void *handle = __libc_dlopen ("libgcc_s.so.1");
+
+ if (handle == NULL)
+ return;
+
+ unwind_backtrace = __libc_dlsym (handle, "_Unwind_Backtrace");
+ unwind_getip = __libc_dlsym (handle, "_Unwind_GetIP");
+ if (unwind_getip == NULL)
+ unwind_backtrace = NULL;
+}
+#else
+# define unwind_backtrace _Unwind_Backtrace
+# define unwind_getip _Unwind_GetIP
+#endif
+
+static int
+__backchain_backtrace (void **array, int size)
+{
+ /* We assume that all the code is generated with frame pointers set. */
+ struct layout *stack;
+ int cnt = 0;
+
+ asm ("LR %0,%%r15" : "=d" (stack) );
+ /* We skip the call to this function, it makes no sense to record it. */
+ stack = (struct layout *) stack->back_chain;
+ while (cnt < size)
+ {
+ if (stack == NULL || (void *) stack > __libc_stack_end)
+ /* This means the address is out of range. Note that for the
+ toplevel we see a frame pointer with value NULL which clearly is
+ out of range. */
+ break;
+
+ array[cnt++] = (void *) (stack->save_grps[8] & 0x7fffffff);
+
+ stack = (struct layout *) stack->back_chain;
+ }
+
+ return cnt;
+}
+
+static _Unwind_Reason_Code
+backtrace_helper (struct _Unwind_Context *ctx, void *a)
+{
+ struct trace_arg *arg = a;
+
+ /* We are first called with address in the __backtrace function.
+ Skip it. */
+ if (arg->cnt != -1)
+ arg->array[arg->cnt] = (void *) unwind_getip (ctx);
+ if (++arg->cnt == arg->size)
+ return _URC_END_OF_STACK;
+ return _URC_NO_REASON;
+}
+
+int
+__backtrace (void **array, int size)
+{
+ struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
+#ifdef SHARED
+ __libc_once_define (static, once);
+
+ __libc_once (once, init);
+#endif
+ if (unwind_backtrace == NULL)
+ return __backchain_backtrace (array, size);
+
+ if (size >= 1)
+ unwind_backtrace (backtrace_helper, &arg);
+
+ return arg.cnt != -1 ? arg.cnt : 0;
+}
+
+weak_alias (__backtrace, backtrace)
+libc_hidden_def (__backtrace)
diff --git a/libc/sysdeps/s390/s390-32/bcopy.S b/libc/sysdeps/s390/s390-32/bcopy.S
new file mode 100644
index 000000000..ae90dc158
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/bcopy.S
@@ -0,0 +1,86 @@
+/* bcopy -- copy a block from source to destination. S/390 version.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* INPUT PARAMETERS
+ %r2 = address of source
+ %r3 = address of destination
+ %r4 = number of bytes to copy. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__bcopy)
+ ltr %r1,%r4 # zero bcopy ?
+ jz .L4
+ clr %r2,%r3 # check against destructive overlap
+ jnl .L0
+ alr %r1,%r2
+ clr %r1,%r3
+ jh .L7
+.L0: ahi %r4,-1 # length - 1
+ lr %r1,%r4
+ srl %r1,8
+ ltr %r1,%r1 # < 256 bytes to move ?
+ jz .L2
+ chi %r1,255 # > 1MB to move ?
+ jh .L5
+.L1: mvc 0(256,%r3),0(%r2) # move in 256 byte chunks
+ la %r2,256(%r2)
+ la %r3,256(%r3)
+ brct %r1,.L1
+.L2: bras %r1,.L3 # setup base pointer for execute
+ mvc 0(1,%r3),0(%r2) # instruction for execute
+.L3: ex %r4,0(%r1) # execute mvc with length ((%r4)&255)+1
+.L4: br %r14
+
+ # data copies > 1MB are faster with mvcle.
+.L5: ahi %r4,1 # length + 1
+ lr %r5,%r4 # source length
+ lr %r4,%r2 # source address
+ lr %r2,%r3 # set destination
+ lr %r3,%r5 # destination length = source length
+.L6: mvcle %r2,%r4,0 # thats it, MVCLE is your friend
+ jo .L6
+ br %r14
+.L7: # destructive overlay, can not use mvcle
+ lr %r1,%r2 # bcopy is called with source,dest
+ lr %r2,%r3 # memmove with dest,source! Oh, well...
+ lr %r3,%r1
+ basr %r1,0
+.L8:
+#ifdef PIC
+ al %r1,.L9-.L8(%r1) # get address of global offset table
+ # load address of memmove
+ l %r1,memmove@GOT12(%r1)
+ br %r1
+.L9: .long _GLOBAL_OFFSET_TABLE_-.L8
+#else
+ al %r1,.L9-.L8(%r1) # load address of memmove
+ br %r1 # jump to memmove
+.L9: .long memmove-.L8
+#endif
+
+END(__bcopy)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__bcopy, bcopy)
+#endif
+
diff --git a/libc/sysdeps/s390/s390-32/bits/wordsize.h b/libc/sysdeps/s390/s390-32/bits/wordsize.h
new file mode 100644
index 000000000..b41661217
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/bits/wordsize.h
@@ -0,0 +1,18 @@
+/* Determine the wordsize from the preprocessor defines. */
+
+#if defined __s390x__
+# define __WORDSIZE 64
+#else
+# define __WORDSIZE 32
+#endif
+
+#if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL
+
+/* Signal that we didn't used to have a `long double'. The changes all
+ the `long double' function variants to be redirects to the double
+ functions. */
+# define __LONG_DOUBLE_MATH_OPTIONAL 1
+# ifndef __LONG_DOUBLE_128__
+# define __NO_LONG_DOUBLE_MATH 1
+# endif
+#endif
diff --git a/libc/sysdeps/s390/s390-32/bsd-_setjmp.S b/libc/sysdeps/s390/s390-32/bsd-_setjmp.S
new file mode 100644
index 000000000..01c349d18
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/bsd-_setjmp.S
@@ -0,0 +1,47 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. s390 version.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#include <sysdep.h>
+
+ENTRY(_setjmp)
+#ifdef PIC
+ /* We cannot use the PLT, because it requires that %r12 be set, but
+ we can't save and restore our caller's value. Instead, we do an
+ indirect jump through the GOT. */
+ basr %r1,0
+.L0: al %r1,.L1 - .L0(0,%r1) /* get address of global offset table */
+ /* get address of __sigjmp_save from got */
+ l %r1,__sigjmp_save@GOT12(0,%r1)
+ lhi %r3,0 /* second argument of one */
+ br %r1
+.L1: .long _GLOBAL_OFFSET_TABLE_ - .L0
+#else
+ basr %r1,0
+.L0: l %r1,.L1 - .L0(0,%r1) /* load address of __sigsetjmp */
+ lhi %r3,0 /* second argument of zero */
+ br %r1 /* branch to __sigsetjmp */
+.L1: .long __sigsetjmp
+#endif
+END (_setjmp)
+libc_hidden_def (_setjmp)
diff --git a/libc/sysdeps/s390/s390-32/bsd-setjmp.S b/libc/sysdeps/s390/s390-32/bsd-setjmp.S
new file mode 100644
index 000000000..1f4ab87ef
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/bsd-setjmp.S
@@ -0,0 +1,46 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. s390 version.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#include <sysdep.h>
+
+ENTRY(setjmp)
+#ifdef PIC
+ /* We cannot use the PLT, because it requires that %r12 be set, but
+ we can't save and restore our caller's value. Instead, we do an
+ indirect jump through the GOT. */
+ basr %r1,0
+.L0: al %r1,.L1 - .L0(0,%r1) /* get address of global offset table */
+ /* get address of __sigjmp_save from got */
+ l %r1,__sigjmp_save@GOT12(0,%r1)
+ lhi %r3,1 /* second argument of one */
+ br %r1
+.L1: .long _GLOBAL_OFFSET_TABLE_ - .L0
+#else
+ basr %r1,0
+.L0: l %r1,.L1 - .L0(0,%r1) /* load address of __sigsetjmp */
+ lhi %r3,1 /* second argument of zero */
+ br %r1 /* branch to __sigsetjmp */
+.L1: .long __sigsetjmp
+#endif
+END (setjmp)
diff --git a/libc/sysdeps/s390/s390-32/bzero.S b/libc/sysdeps/s390/s390-32/bzero.S
new file mode 100644
index 000000000..c45ce5514
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/bzero.S
@@ -0,0 +1,43 @@
+/* bzero -- set a block of memory to zero. IBM S390 version
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * R2 = address to memory area
+ * R3 = number of bytes to fill
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__bzero)
+ ltr %r3,%r3
+ jz .L1
+ sr %r1,%r1 # set pad byte to zero
+ sr %r4,%r4 # no source for MVCLE, only a pad byte
+ sr %r5,%r5
+.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend
+ jo .L0
+.L1: br %r14
+END(__bzero)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__bzero, bzero)
+#endif
diff --git a/libc/sysdeps/s390/s390-32/dl-machine.h b/libc/sysdeps/s390/s390-32/dl-machine.h
new file mode 100644
index 000000000..8bbf858fb
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/dl-machine.h
@@ -0,0 +1,451 @@
+/* Machine-dependent ELF dynamic relocation inline functions. S390 Version.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+ Contributed by Carl Pederson & Martin Schwidefsky.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "s390"
+
+#include <sys/param.h>
+#include <string.h>
+#include <link.h>
+
+/* This is an older, now obsolete value. */
+#define EM_S390_OLD 0xA390
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int
+elf_machine_matches_host (const Elf32_Ehdr *ehdr)
+{
+ return (ehdr->e_machine == EM_S390 || ehdr->e_machine == EM_S390_OLD)
+ && ehdr->e_ident[EI_CLASS] == ELFCLASS32;
+}
+
+
+/* Return the link-time address of _DYNAMIC. Conveniently, this is the
+ first element of the GOT. This must be inlined in a function which
+ uses global data. */
+
+static inline Elf32_Addr
+elf_machine_dynamic (void)
+{
+ register Elf32_Addr *got;
+
+ asm( " bras %0,2f\n"
+ "1: .long _GLOBAL_OFFSET_TABLE_-1b\n"
+ "2: al %0,0(%0)"
+ : "=&a" (got) : : "0" );
+
+ return *got;
+}
+
+
+/* Return the run-time load address of the shared object. */
+static inline Elf32_Addr
+elf_machine_load_address (void)
+{
+ Elf32_Addr addr;
+
+ asm( " bras 1,2f\n"
+ "1: .long _GLOBAL_OFFSET_TABLE_ - 1b\n"
+ " .long _dl_start - 1b - 0x80000000\n"
+ "2: l %0,4(1)\n"
+ " ar %0,1\n"
+ " al 1,0(1)\n"
+ " sl %0,_dl_start@GOT12(1)"
+ : "=&d" (addr) : : "1" );
+ return addr;
+}
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int __attribute__ ((unused))
+elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+{
+ extern void _dl_runtime_resolve (Elf32_Word);
+ extern void _dl_runtime_profile (Elf32_Word);
+
+ if (l->l_info[DT_JMPREL] && lazy)
+ {
+ /* The GOT entries for functions in the PLT have not yet been filled
+ in. Their initial contents will arrange when called to push an
+ offset into the .rel.plt section, push _GLOBAL_OFFSET_TABLE_[1],
+ and then jump to _GLOBAL_OFFSET_TABLE[2]. */
+ Elf32_Addr *got;
+ got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
+ /* If a library is prelinked but we have to relocate anyway,
+ we have to be able to undo the prelinking of .got.plt.
+ The prelinker saved us here address of .plt + 0x2c. */
+ if (got[1])
+ {
+ l->l_mach.plt = got[1] + l->l_addr;
+ l->l_mach.gotplt = (Elf32_Addr) &got[3];
+ }
+ got[1] = (Elf32_Addr) l; /* Identify this shared object. */
+
+ /* The got[2] entry contains the address of a function which gets
+ called to get the address of a so far unresolved function and
+ jump to it. The profiling extension of the dynamic linker allows
+ to intercept the calls to collect information. In this case we
+ don't store the address in the GOT so that all future calls also
+ end in this function. */
+ if (__builtin_expect (profile, 0))
+ {
+ got[2] = (Elf32_Addr) &_dl_runtime_profile;
+
+ if (GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), l))
+ /* This is the object we are looking for. Say that we really
+ want profiling and the timers are started. */
+ GL(dl_profile_map) = l;
+ }
+ else
+ /* This function will get called to fix up the GOT entry indicated by
+ the offset on the stack, and then jump to the resolved address. */
+ got[2] = (Elf32_Addr) &_dl_runtime_resolve;
+ }
+
+ return lazy;
+}
+
+/* Mask identifying addresses reserved for the user program,
+ where the dynamic linker should not map anything. */
+#define ELF_MACHINE_USER_ADDRESS_MASK 0xf8000000UL
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+
+#define RTLD_START asm ("\n\
+.text\n\
+.align 4\n\
+.globl _start\n\
+.globl _dl_start_user\n\
+_start:\n\
+ basr %r13,0\n\
+.L0: ahi %r13,.Llit-.L0\n\
+ lr %r2,%r15\n\
+ # Alloc stack frame\n\
+ ahi %r15,-96\n\
+ # Set the back chain to zero\n\
+ xc 0(4,%r15),0(%r15)\n\
+ # Call _dl_start with %r2 pointing to arg on stack\n\
+ l %r14,.Ladr1-.Llit(%r13)\n\
+ bas %r14,0(%r14,%r13) # call _dl_start\n\
+_dl_start_user:\n\
+ # Save the user entry point address in %r8.\n\
+ lr %r8,%r2\n\
+ # Point %r12 at the GOT.\n\
+ l %r12,.Ladr0-.Llit(%r13)\n\
+ ar %r12,%r13\n\
+ # See if we were run as a command with the executable file\n\
+ # name as an extra leading argument.\n\
+ l %r1,_dl_skip_args@GOT12(0,%r12)\n\
+ l %r1,0(%r1) # load _dl_skip_args\n\
+ # Get the original argument count.\n\
+ l %r0,96(%r15)\n\
+ # Subtract _dl_skip_args from it.\n\
+ sr %r0,%r1\n\
+ # Adjust the stack pointer to skip _dl_skip_args words.\n\
+ sll %r1,2\n\
+ ar %r15,%r1\n\
+ # Set the back chain to zero again\n\
+ xc 0(4,%r15),0(%r15)\n\
+ # Store back the modified argument count.\n\
+ st %r0,96(%r15)\n\
+ # The special initializer gets called with the stack just\n\
+ # as the application's entry point will see it; it can\n\
+ # switch stacks if it moves these contents over.\n\
+" RTLD_START_SPECIAL_INIT "\n\
+ # Call the function to run the initializers.\n\
+ # Load the parameters:\n\
+ # (%r2, %r3, %r4, %r5) = (_dl_loaded, argc, argv, envp)\n\
+ l %r2,_rtld_local@GOT(%r12)\n\
+ l %r2,0(%r2)\n\
+ l %r3,96(%r15)\n\
+ la %r4,100(%r15)\n\
+ lr %r5,%r3\n\
+ sll %r5,2\n\
+ la %r5,104(%r5,%r15)\n\
+ l %r1,.Ladr4-.Llit(%r13)\n\
+ bas %r14,0(%r1,%r13)\n\
+ # Pass our finalizer function to the user in %r14, as per ELF ABI.\n\
+ l %r14,_dl_fini@GOT(%r12)\n\
+ # Free stack frame\n\
+ ahi %r15,96\n\
+ # Jump to the user's entry point (saved in %r8).\n\
+ br %r8\n\
+.Llit:\n\
+.Ladr0: .long _GLOBAL_OFFSET_TABLE_-.Llit\n\
+.Ladr1: .long _dl_start-.Llit\n\
+.Ladr4: .long _dl_init_internal@PLT-.Llit\n\
+");
+
+#ifndef RTLD_START_SPECIAL_INIT
+#define RTLD_START_SPECIAL_INIT /* nothing */
+#endif
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#ifdef USE_TLS
+# define elf_machine_type_class(type) \
+ ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD \
+ || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+# define elf_machine_type_class(type) \
+ ((((type) == R_390_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT
+
+/* The S390 never uses Elf32_Rel relocations. */
+#define ELF_MACHINE_NO_REL 1
+
+/* The S390 overlaps DT_RELA and DT_PLTREL. */
+#define ELF_MACHINE_PLTREL_OVERLAP 1
+
+/* We define an initialization functions. This is called very early in
+ _dl_sysdep_start. */
+#define DL_PLATFORM_INIT dl_platform_init ()
+
+static inline void __attribute__ ((unused))
+dl_platform_init (void)
+{
+ if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
+ /* Avoid an empty string which would disturb us. */
+ GLRO(dl_platform) = NULL;
+}
+
+static inline Elf32_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+ return *reloc_addr = value;
+}
+
+/* Return the final value of a plt relocation. */
+static inline Elf32_Addr
+elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+ Elf32_Addr value)
+{
+ return value;
+}
+
+/* Names of the architecture-specific auditing callback functions. */
+#define ARCH_LA_PLTENTER s390_32_gnu_pltenter
+#define ARCH_LA_PLTEXIT s390_32_gnu_pltexit
+
+#endif /* !dl_machine_h */
+
+
+#ifdef RESOLVE_MAP
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ MAP is the object containing the reloc. */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
+ const Elf32_Sym *sym, const struct r_found_version *version,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+ if (__builtin_expect (r_type == R_390_RELATIVE, 0))
+ {
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ /* This is defined in rtld.c, but nowhere in the static libc.a;
+ make the reference weak so static programs can still link.
+ This declaration cannot be done when compiling rtld.c
+ (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the
+ common defn for _dl_rtld_map, which is incompatible with a
+ weak decl in the same file. */
+# ifndef SHARED
+ weak_extern (GL(dl_rtld_map));
+# endif
+ if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
+# endif
+ *reloc_addr = map->l_addr + reloc->r_addend;
+ }
+ else
+#endif
+ if (__builtin_expect (r_type == R_390_NONE, 0))
+ return;
+ else
+ {
+#ifndef RESOLVE_CONFLICT_FIND_MAP
+ const Elf32_Sym *const refsym = sym;
+#endif
+ struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+ Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+
+ switch (r_type)
+ {
+ case R_390_GLOB_DAT:
+ case R_390_JMP_SLOT:
+ *reloc_addr = value + reloc->r_addend;
+ break;
+
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+ && !defined RESOLVE_CONFLICT_FIND_MAP
+ case R_390_TLS_DTPMOD:
+# ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always the module
+ with index 1.
+ XXX If this relocation is necessary move before RESOLVE
+ call. */
+ *reloc_addr = 1;
+# else
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+# endif
+ break;
+ case R_390_TLS_DTPOFF:
+# ifndef RTLD_BOOTSTRAP
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ if (sym != NULL)
+ *reloc_addr = sym->st_value + reloc->r_addend;
+# endif
+ break;
+ case R_390_TLS_TPOFF:
+ /* The offset is negative, forward from the thread pointer. */
+# ifdef RTLD_BOOTSTRAP
+ *reloc_addr = sym->st_value + reloc->r_addend - map->l_tls_offset;
+# else
+ /* We know the offset of the object the symbol is contained in.
+ It is a negative value which will be added to the
+ thread pointer. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = (sym->st_value + reloc->r_addend
+ - sym_map->l_tls_offset);
+ }
+#endif
+ break;
+#endif /* use TLS */
+
+#ifndef RTLD_BOOTSTRAP
+# ifndef RESOLVE_CONFLICT_FIND_MAP
+ /* Not needed in dl-conflict.c. */
+ case R_390_COPY:
+ if (sym == NULL)
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
+ if (__builtin_expect (sym->st_size > refsym->st_size, 0)
+ || (__builtin_expect (sym->st_size < refsym->st_size, 0)
+ && __builtin_expect (GLRO(dl_verbose), 0)))
+ {
+ const char *strtab;
+
+ strtab = (const char *) D_PTR(map,l_info[DT_STRTAB]);
+ _dl_error_printf ("\
+%s: Symbol `%s' has different size in shared object, consider re-linking\n",
+ rtld_progname ?: "<program name unknown>",
+ strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr_arg, (void *) value,
+ MIN (sym->st_size, refsym->st_size));
+ break;
+# endif
+ case R_390_32:
+ *reloc_addr = value + reloc->r_addend;
+ break;
+ case R_390_16:
+ *(unsigned short *) reloc_addr = value + reloc->r_addend;
+ break;
+ case R_390_8:
+ *(char *) reloc_addr = value + reloc->r_addend;
+ break;
+# ifndef RESOLVE_CONFLICT_FIND_MAP
+ case R_390_PC32:
+ *reloc_addr = value + reloc->r_addend - (Elf32_Addr) reloc_addr;
+ break;
+ case R_390_PC16DBL:
+ case R_390_PLT16DBL:
+ *(unsigned short *) reloc_addr = (unsigned short)
+ ((short) (value + reloc->r_addend - (Elf32_Addr) reloc_addr) >> 1);
+ break;
+ case R_390_PC16:
+ *(unsigned short *) reloc_addr =
+ value + reloc->r_addend - (Elf32_Addr) reloc_addr;
+ break;
+ case R_390_NONE:
+ break;
+# endif
+#endif
+#if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG)
+ default:
+ /* We add these checks in the version to relocate ld.so only
+ if we are still debugging. */
+ _dl_reloc_bad_type (map, r_type, 0);
+ break;
+#endif
+ }
+ }
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ *reloc_addr = l_addr + reloc->r_addend;
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf32_Addr l_addr, const Elf32_Rela *reloc)
+{
+ Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
+ const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+ /* Check for unexpected PLT reloc type. */
+ if (__builtin_expect (r_type == R_390_JMP_SLOT, 1))
+ {
+ if (__builtin_expect (map->l_mach.plt, 0) == 0)
+ *reloc_addr += l_addr;
+ else
+ *reloc_addr =
+ map->l_mach.plt
+ + (((Elf32_Addr) reloc_addr) - map->l_mach.gotplt) * 8;
+ }
+ else
+ _dl_reloc_bad_type (map, r_type, 1);
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/libc/sysdeps/s390/s390-32/dl-trampoline.S b/libc/sysdeps/s390/s390-32/dl-trampoline.S
new file mode 100644
index 000000000..fbbbc189d
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/dl-trampoline.S
@@ -0,0 +1,134 @@
+/* PLT trampolines. s390 version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This code is used in dl-runtime.c to call the `fixup' function
+ and then redirect to the address it returns. */
+
+/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile
+ * with the following linkage:
+ * r2 - r6 : parameter registers
+ * f0, f2 : floating point parameter registers
+ * 24(r15), 28(r15) : PLT arguments PLT1, PLT2
+ * 96(r15) : additional stack parameters
+ * The normal clobber rules for function calls apply:
+ * r0 - r5 : call clobbered
+ * r6 - r13 : call saved
+ * r14 : return address (call clobbered)
+ * r15 : stack pointer (call saved)
+ * f4, f6 : call saved
+ * f0 - f3, f5, f7 - f15 : call clobbered
+ */
+
+#include <sysdep.h>
+
+ .text
+ .globl _dl_runtime_resolve
+ .type _dl_runtime_resolve, @function
+ cfi_startproc
+ .align 16
+_dl_runtime_resolve:
+ stm %r2,%r5,32(%r15) # save registers
+ st %r14,8(%r15)
+ lr %r0,%r15 # create stack frame
+ ahi %r15,-96
+ cfi_adjust_cfa_offset (96)
+ st 0,0(%r15)
+ lm %r2,%r3,120(%r15) # load args saved by PLT
+ basr %r1,0
+0: l %r14,1f-0b(%r1)
+ bas %r14,0(%r14,%r1) # call resolver
+ lr %r1,%r2 # function addr returned in r2
+ ahi %r15,96 # remove stack frame
+ cfi_adjust_cfa_offset (-96)
+ l %r14,8(15) # restore registers
+ lm %r2,%r5,32(%r15)
+ br %r1
+1: .long _dl_fixup - 0b
+ cfi_endproc
+ .size _dl_runtime_resolve, .-_dl_runtime_resolve
+
+
+#ifndef PROF
+ .globl _dl_runtime_profile
+ .type _dl_runtime_profile, @function
+ cfi_startproc
+ .align 16
+_dl_runtime_profile:
+ stm %r2,%r6,32(%r15) # save registers
+ std %f0,56(%r15)
+ std %f2,64(%r15)
+ st %r6,8(%r15)
+ st %r12,12(%r15)
+ st %r14,16(%r15)
+ lr %r12,%r15 # create stack frame
+ cfi_def_cfa_register (12)
+ ahi %r15,-96
+ st %r12,0(%r15)
+ lm %r2,%r3,24(%r12) # load arguments saved by PLT
+ lr %r4,%r14 # return address as third parameter
+ basr %r1,0
+0: l %r14,6f-0b(%r1)
+ la %r5,32(%r12) # pointer to struct La_s390_32_regs
+ la %r6,20(%r12) # long int * framesize
+ bas %r14,0(%r14,%r1) # call resolver
+ lr %r1,%r2 # function addr returned in r2
+ icm %r0,15,20(%r12) # load & test framesize
+ jnm 2f
+ lm %r2,%r6,32(%r12)
+ ld %f0,56(%r12)
+ ld %f2,64(%r12)
+ basr %r14,%r1 # call resolved function
+1: lr %r15,%r12 # remove stack frame
+ cfi_def_cfa_register (15)
+ l %r14,16(%r15) # restore registers
+ l %r12,12(%r15)
+ l %r6,8(%r15)
+ br %r14
+ cfi_def_cfa_register (12)
+2: jz 4f # framesize == 0 ?
+ ahi %r0,7 # align framesize to 8
+ lhi %r2,-8
+ nr %r0,%r2
+ slr %r15,%r0 # make room for framesize bytes
+ st %r12,0(%r15)
+ la %r2,96(%r15)
+ la %r3,96(%r12)
+ srl %r0,3
+3: mvc 0(8,%r2),0(%r3) # copy additional parameters
+ la %r2,8(%r2)
+ la %r3,8(%r3)
+ brct %r0,3b
+4: lm %r2,%r6,32(%r12) # load register parameters
+ ld %f0,56(%r12)
+ ld %f2,64(%r12)
+ basr %r14,%r1 # call resolved function
+ stm %r2,%r3,72(%r12)
+ std %f0,80(%r12)
+ lm %r2,%r3,24(%r12) # load arguments saved by PLT
+ basr %r1,0
+5: l %r14,7f-5b(%r1)
+ la %r4,32(%r12) # pointer to struct La_s390_32_regs
+ la %r5,72(%r12) # pointer to struct La_s390_32_retval
+ basr %r14,%r1 # call _dl_call_pltexit
+ j 1b
+6: .long _dl_profile_fixup - 0b
+7: .long _dl_call_pltexit - 5b
+ cfi_endproc
+ .size _dl_runtime_profile, .-_dl_runtime_profile
+#endif
diff --git a/libc/sysdeps/s390/s390-32/elf/bsd-_setjmp.S b/libc/sysdeps/s390/s390-32/elf/bsd-_setjmp.S
new file mode 100644
index 000000000..141727020
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/elf/bsd-_setjmp.S
@@ -0,0 +1 @@
+/* We don't need any code here since the setjmp.S file contains it. */
diff --git a/libc/sysdeps/s390/s390-32/elf/bsd-setjmp.S b/libc/sysdeps/s390/s390-32/elf/bsd-setjmp.S
new file mode 100644
index 000000000..141727020
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/elf/bsd-setjmp.S
@@ -0,0 +1 @@
+/* We don't need any code here since the setjmp.S file contains it. */
diff --git a/libc/sysdeps/s390/s390-32/elf/configure b/libc/sysdeps/s390/s390-32/elf/configure
new file mode 100644
index 000000000..684573049
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/elf/configure
@@ -0,0 +1,52 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/s390/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+echo "$as_me:$LINENO: checking for s390 TLS support" >&5
+echo $ECHO_N "checking for s390 TLS support... $ECHO_C" >&6
+if test "${libc_cv_390_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.S <<\EOF
+ .section ".tdata", "awT", @progbits
+foo: .long 25
+ .text
+ .long foo@TLSGD
+ .long foo@TLSLDM
+ .long foo@DTPOFF
+ .long foo@NTPOFF
+ .long foo@GOTNTPOFF
+ .long foo@INDNTPOFF
+ l %r1,foo@GOTNTPOFF(%r12)
+ l %r1,0(%r1):tls_load:foo
+ bas %r14,0(%r1,%r13):tls_gdcall:foo
+ bas %r14,0(%r1,%r13):tls_ldcall:foo
+EOF
+if { ac_try='${CC-cc} -S $CFLAGS conftest.S 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_390_tls=yes
+else
+ libc_cv_390_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_390_tls" >&5
+echo "${ECHO_T}$libc_cv_390_tls" >&6
+if test $libc_cv_390_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+cat >>confdefs.h <<\_ACEOF
+#define PI_STATIC_AND_HIDDEN 1
+_ACEOF
+
diff --git a/libc/sysdeps/s390/s390-32/elf/configure.in b/libc/sysdeps/s390/s390-32/elf/configure.in
new file mode 100644
index 000000000..fcf932999
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/elf/configure.in
@@ -0,0 +1,37 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/s390/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for s390 TLS support, libc_cv_390_tls, [dnl
+cat > conftest.S <<\EOF
+ .section ".tdata", "awT", @progbits
+foo: .long 25
+ .text
+ .long foo@TLSGD
+ .long foo@TLSLDM
+ .long foo@DTPOFF
+ .long foo@NTPOFF
+ .long foo@GOTNTPOFF
+ .long foo@INDNTPOFF
+ l %r1,foo@GOTNTPOFF(%r12)
+ l %r1,0(%r1):tls_load:foo
+ bas %r14,0(%r1,%r13):tls_gdcall:foo
+ bas %r14,0(%r1,%r13):tls_ldcall:foo
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.S 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_390_tls=yes
+else
+ libc_cv_390_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_390_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
+dnl It is always possible to access static and hidden symbols in an
+dnl position independent way.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
diff --git a/libc/sysdeps/s390/s390-32/elf/setjmp.S b/libc/sysdeps/s390/s390-32/elf/setjmp.S
new file mode 100644
index 000000000..ed28008a5
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/elf/setjmp.S
@@ -0,0 +1,81 @@
+/* setjmp for s390, ELF version.
+ Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ASM
+#define _SETJMP_H
+#include <bits/setjmp.h>
+
+ /* We include the BSD entry points here as well but we make
+ them weak. */
+ENTRY (setjmp)
+ .weak C_SYMBOL_NAME (setjmp)
+ lhi %r3,1 /* second argument of one */
+ j .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */
+END (setjmp)
+
+ /* Binary compatibility entry point. */
+ENTRY(_setjmp)
+ .weak C_SYMBOL_NAME (_setjmp)
+ lhi %r3,0 /* second argument of zero */
+ j .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */
+END (_setjmp)
+libc_hidden_def (_setjmp)
+
+ENTRY(__setjmp)
+ lhi %r3,0 /* second argument of zero */
+ j .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */
+END (__setjmp)
+
+ENTRY(__sigsetjmp)
+.Linternal_sigsetjmp:
+#ifdef PTR_MANGLE
+ stm %r6,%r13,0(%r2) /* store registers in jmp_buf */
+ lr %r4,%r14
+ lr %r5,%r15
+ PTR_MANGLE (%r4, %r1)
+ PTR_MANGLE2 (%r5, %r1)
+ stm %r4,%r5,32(%r2)
+#else
+ stm %r6,%r15,0(%r2) /* store registers in jmp_buf */
+#endif
+ std %f4,40(%r2)
+ std %f6,48(%r2)
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ /* In ld.so we never save the signal mask. */
+ lhi %r2,0
+ br %r14
+#elif defined PIC
+ /* We cannot use the PLT, because it requires that %r12 be set, but
+ we can't save and restore our caller's value. Instead, we do an
+ indirect jump through the GOT. */
+ basr %r1,0
+.L0: al %r1,.L1 - .L0(0,%r1) /* get address of global offset table */
+ /* get address of __sigjmp_save from got */
+ l %r1,__sigjmp_save@GOT12(0,%r1)
+ br %r1
+.L1: .long _GLOBAL_OFFSET_TABLE_ - .L0
+#else
+ basr %r1,0
+.L0: l %r1,.L1-.L0(0,%r1) /* load address of __sigjmp_save */
+ br %r1 /* tail-call __sigjmp_save */
+.L1: .long __sigjmp_save
+#endif
+END (__sigsetjmp)
diff --git a/libc/sysdeps/s390/s390-32/elf/start.S b/libc/sysdeps/s390/s390-32/elf/start.S
new file mode 100644
index 000000000..f7290106c
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/elf/start.S
@@ -0,0 +1,123 @@
+/* Startup code compliant to the ELF s390 ABI.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006
+ Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ This is the canonical entry point, usually the first thing in the text
+ segment. Most registers' values are unspecified, except for:
+
+ %r14 Contains a function pointer to be registered with `atexit'.
+ This is how the dynamic linker arranges to have DT_FINI
+ functions called for shared libraries that have been loaded
+ before this code runs.
+
+ %r15 The stack contains the arguments and environment:
+ 0(%r15) argc
+ 4(%r15) argv[0]
+ ...
+ (4*argc)(%r15) NULL
+ (4*(argc+1))(%r15) envp[0]
+ ...
+ NULL
+*/
+
+ .text
+ .globl _start
+ .type _start,@function
+_start:
+ /* Setup pointer to literal pool of _start */
+ basr %r13,0
+.L0: ahi %r13,.Llit-.L0
+
+ /* load argc and argv from stack */
+ la %r4,4(%r15) # get argv
+ l %r3,0(%r15) # get argc
+
+ /* align the stack to a double word boundary */
+ lhi %r0,-8
+ nr %r15,%r0
+
+ /* Setup a stack frame and a parameter area */
+ ahi %r15,-104 # make room on stack
+ xc 0(4,%r15),0(%r15) # clear back-chain
+
+ /* set up arguments for __libc_start_main:
+ main, argc, argv, envp, _init, _fini, rtld_fini, stack_end
+ Note that envp will be determined later in __libc_start_main
+ */
+ stm %r14,%r15,96(%r15) # store rtld_fini/stack_end to parameter area
+ la %r7,96(%r15)
+ l %r6,.L2-.Llit(%r13) # load pointer to __libc_csu_fini
+ l %r5,.L1-.Llit(%r13) # load pointer to __libc_csu_init
+ l %r2,.L3-.Llit(%r13) # load pointer to main
+ l %r1,.L4-.Llit(%r13) # load pointer to __libc_start_main
+#ifdef PIC
+ l %r12,.L5-.Llit(%r13) # load .got pointer
+ la %r6,0(%r13,%r6)
+ la %r5,0(%r13,%r5)
+ la %r12,0(%r13,%r12)
+ l %r2,0(%r12,%r2)
+ la %r1,0(%r13,%r1)
+#endif
+
+ /* ok, now branch to the libc main routine */
+ basr %r14,%r1
+
+ /* crash if __libc_start_main returns */
+ .word 0
+
+.Llit:
+#ifndef PIC
+.L1: .long __libc_csu_init
+.L2: .long __libc_csu_fini
+.L3: .long main
+.L4: .long __libc_start_main
+#else
+.L1: .long __libc_csu_init-.Llit
+.L2: .long __libc_csu_fini-.Llit
+.L3: .long main@GOT
+.L4: .long __libc_start_main@plt-.Llit
+.L5: .long _GLOBAL_OFFSET_TABLE_-.Llit
+#endif
+
+/* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+ .long 0
+ .weak data_start
+ data_start = __data_start
diff --git a/libc/sysdeps/s390/s390-32/initfini.c b/libc/sysdeps/s390/s390-32/initfini.c
new file mode 100644
index 000000000..4ec0e9b1d
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/initfini.c
@@ -0,0 +1,157 @@
+/* Special .init and .fini section support for S/390.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file is compiled into assembly code which is then munged by a sed
+ script into two files: crti.s and crtn.s.
+
+ * crti.s puts a function prologue at the beginning of the
+ .init and .fini sections and defines global symbols for
+ those addresses, so they can be called as functions.
+
+ * crtn.s puts the corresponding function epilogues
+ in the .init and .fini sections. */
+
+__asm__ ("\
+\n\
+#include \"defs.h\"\n\
+\n\
+/*@HEADER_ENDS*/\n\
+\n\
+/*@TESTS_BEGIN*/\n\
+\n\
+/*@TESTS_END*/\n\
+\n\
+/*@_init_PROLOG_BEGINS*/\n\
+\n\
+ .section .init\n\
+#NO_APP\n\
+ .align 4\n\
+.globl _init\n\
+ .type _init,@function\n\
+_init:\n\
+# leaf function 0\n\
+# automatics 0\n\
+# outgoing args 0\n\
+# need frame pointer 0\n\
+# call alloca 0\n\
+# has varargs 0\n\
+# incoming args (stack) 0\n\
+# function length 36\n\
+ STM 6,15,24(15)\n\
+ BRAS 13,.LTN1_0\n\
+.LT1_0:\n\
+.LC14:\n\
+ .long __gmon_start__@GOT\n\
+.LC15:\n\
+ .long _GLOBAL_OFFSET_TABLE_-.LT1_0\n\
+.LTN1_0:\n\
+ LR 1,15\n\
+ AHI 15,-96\n\
+ ST 1,0(15)\n\
+ L 12,.LC15-.LT1_0(13)\n\
+ AR 12,13\n\
+ L 1,.LC14-.LT1_0(13)\n\
+ L 1,0(1,12)\n\
+ LTR 1,1\n\
+ JE .L22\n\
+ BASR 14,1\n\
+.L22:\n\
+#APP\n\
+ .align 4,0x07\n\
+ END_INIT\n\
+\n\
+/*@_init_PROLOG_ENDS*/\n\
+\n\
+/*@_init_EPILOG_BEGINS*/\n\
+ .align 4\n\
+ .section .init\n\
+#NO_APP\n\
+ .align 4\n\
+ L 4,152(15)\n\
+ LM 6,15,120(15)\n\
+ BR 4\n\
+#APP\n\
+ END_INIT\n\
+\n\
+/*@_init_EPILOG_ENDS*/\n\
+\n\
+/*@_fini_PROLOG_BEGINS*/\n\
+ .section .fini\n\
+#NO_APP\n\
+ .align 4\n\
+.globl _fini\n\
+ .type _fini,@function\n\
+_fini:\n\
+# leaf function 0\n\
+# automatics 0\n\
+# outgoing args 0\n\
+# need frame pointer 0\n\
+# call alloca 0\n\
+# has varargs 0\n\
+# incoming args (stack) 0\n\
+# function length 30\n\
+ STM 6,15,24(15)\n\
+ BRAS 13,.LTN2_0\n\
+.LT2_0:\n\
+.LC17:\n\
+ .long _GLOBAL_OFFSET_TABLE_-.LT2_0\n\
+.LTN2_0:\n\
+ LR 1,15\n\
+ AHI 15,-96\n\
+ ST 1,0(15)\n\
+ L 12,.LC17-.LT2_0(13)\n\
+ AR 12,13\n\
+#APP\n\
+ .align 4,0x07\n\
+ END_FINI\n\
+\n\
+/*@_fini_PROLOG_ENDS*/\n\
+\n\
+/*@_fini_EPILOG_BEGINS*/\n\
+ .align 4\n\
+ .section .fini\n\
+#NO_APP\n\
+ .align 4\n\
+ L 4,152(15)\n\
+ LM 6,15,120(15)\n\
+ BR 4\n\
+#APP\n\
+ END_FINI\n\
+\n\
+/*@_fini_EPILOG_ENDS*/\n\
+\n\
+/*@TRAILER_BEGINS*/\
+");
diff --git a/libc/sysdeps/s390/s390-32/memchr.S b/libc/sysdeps/s390/s390-32/memchr.S
new file mode 100644
index 000000000..1ce186850
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/memchr.S
@@ -0,0 +1,42 @@
+/* Search a character in a block of memory. For IBM S390
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * R2 = address to memory area
+ * R3 = character to find
+ * R4 = number of bytes to search
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(memchr)
+ lhi %r0,0xff
+ nr %r0,%r3
+ lr %r1,%r2
+ la %r2,0(%r4,%r1)
+0: srst %r2,%r1
+ jo 0b
+ brc 13,1f
+ slr %r2,%r2
+1: br %r14
+END(memchr)
+libc_hidden_builtin_def (memchr)
diff --git a/libc/sysdeps/s390/s390-32/memcpy.S b/libc/sysdeps/s390/s390-32/memcpy.S
new file mode 100644
index 000000000..201c86467
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/memcpy.S
@@ -0,0 +1,59 @@
+/* memcpy - copy a block from source to destination. S/390 version.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* INPUT PARAMETERS
+ %r2 = address of destination memory area
+ %r3 = address of source memory area
+ %r4 = number of bytes to copy. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(memcpy)
+ ltr %r4,%r4
+ jz .L3
+ ahi %r4,-1 # length - 1
+ lr %r1,%r2 # copy destination address
+ lr %r5,%r4
+ srl %r5,8
+ ltr %r5,%r5 # < 256 bytes to move ?
+ jz .L1
+ chi %r5,255 # > 1MB to move ?
+ jh .L4
+.L0: mvc 0(256,%r1),0(%r3) # move in 256 byte chunks
+ la %r1,256(%r1)
+ la %r3,256(%r3)
+ brct %r5,.L0
+.L1: bras %r5,.L2 # setup base pointer for execute
+ mvc 0(1,%r1),0(%r3) # instruction for execute
+.L2: ex %r4,0(%r5) # execute mvc with length ((%r4)&255)+1
+.L3: br %r14
+ # data copies > 1MB are faster with mvcle.
+.L4: ahi %r4,1 # length + 1
+ lr %r5,%r4 # source length
+ lr %r4,%r3 # source address
+ lr %r3,%r5 # destination length = source length
+.L5: mvcle %r2,%r4,0 # thats it, MVCLE is your friend
+ jo .L5
+ lr %r2,%r1 # return destination address
+ br %r14
+END(memcpy)
+libc_hidden_builtin_def (memcpy)
diff --git a/libc/sysdeps/s390/s390-32/memset.S b/libc/sysdeps/s390/s390-32/memset.S
new file mode 100644
index 000000000..bb9c45965
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/memset.S
@@ -0,0 +1,45 @@
+/* Set a block of memory to some byte value. For IBM S390
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * R2 = address to memory area
+ * R3 = byte to fill memory with
+ * R4 = number of bytes to fill
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(memset)
+ ltr %r4,%r4
+ jz .L1
+ lr %r0,%r2 # save source address
+ lr %r1,%r3 # move pad byte to R1
+ lr %r3,%r4
+ sr %r4,%r4 # no source for MVCLE, only a pad byte
+ sr %r5,%r5
+.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend
+ jo .L0
+ lr %r2,%r0 # return value is source address
+.L1:
+ br %r14
+END(memset)
+libc_hidden_builtin_def (memset)
diff --git a/libc/sysdeps/s390/s390-32/mul_1.S b/libc/sysdeps/s390/s390-32/mul_1.S
new file mode 100644
index 000000000..019447618
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/mul_1.S
@@ -0,0 +1,56 @@
+/* __mpn_mul_1 -- Multiply a limb vector with a limb and store
+ the result in a second limb vector.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr %r2
+ s1_ptr %r3
+ size %r4
+ s2_limb %r5
+*/
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__mpn_mul_1)
+ st %r6,24(%r15)
+ cfi_offset (%r6, -72)
+ slr %r6,%r6 # cy_limb = 0
+.L0: icm %r1,15,0(%r3) # get s1_ptr[i]
+ mr %r0,%r5 # umul_ppmm(prod_high,prod_low,s1_ptr[j],s2_limb)
+ jnm .L1
+ alr %r0,%r5
+.L1: ltr %r5,%r5
+ jnm .L2
+ al %r0,0(%r3)
+.L2: alr %r1,%r6 # prod_low += cy_limb
+ lr %r6,%r0 # cy_limb = prod_high
+ brc 12,.L3
+ ahi %r6,1 # + (prod_low < cy_limb)
+.L3: st %r1,0(%r2)
+ la %r2,4(0,%r2)
+ la %r3,4(0,%r3)
+ brct %r4,.L0
+ lr %r2,%r6 # return cy_limb
+ l %r6,24(%r15)
+.Lexit: br %r14
+END(__mpn_mul_1)
diff --git a/libc/sysdeps/s390/s390-32/s390-mcount.S b/libc/sysdeps/s390/s390-32/s390-mcount.S
new file mode 100644
index 000000000..6d11f9bbd
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/s390-mcount.S
@@ -0,0 +1,84 @@
+/* S/390-specific implemetation of profiling support.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com)
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/*
+ * How profiling works on S/390:
+ * On the start of each function _mcount is called with the address of a
+ * data word in %r1 (initialized to 0, used for counting). The compiler
+ * with the option -p generates code of the form:
+ *
+ * STM 6,15,24(15)
+ * BRAS 13,.LTN0_0
+ * .LT0_0:
+ * .LC12: .long _mcount
+ * .LC13: .long .LP0
+ * .data
+ * .align 4
+ * .LP0: .long 0
+ * .text
+ * # function profiler
+ * st 14,4(15)
+ * l 14,.LC12-.LT0_0(13)
+ * l 1,.LC13-.LT0_0(13)
+ * basr 14,14
+ * l 14,4(15)
+ *
+ * The _mcount implementation now has to call __mcount_internal with the
+ * address of .LP0 as first parameter and the return address as second
+ * parameter. &.LP0 was loaded to %r1 and the return address is in %r14.
+ * _mcount may not modify any register.
+ */
+
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(_mcount)
+ ASM_TYPE_DIRECTIVE(C_SYMBOL_NAME(_mcount), @function)
+ .align ALIGNARG(4)
+C_LABEL(_mcount)
+ /* Save the caller-clobbered registers. */
+ ahi %r15,-128
+ stm %r14,%r5,96(%r15)
+ l %r2,132(%r15) # callers address = first parameter
+ la %r2,0(%r2) # clear bit 0
+ la %r3,0(%r14) # callees address = second parameter
+
+#ifdef PIC
+ bras %r14,0f
+ .long _GLOBAL_OFFSET_TABLE_-.
+0: al %r14,0(%r14)
+ l %r14,__mcount_internal@GOT(%r14)
+#else
+ bras %r14,0f
+ .long __mcount_internal
+0: l %r14,0(%r14)
+#endif
+ basr %r14,%r14
+
+ /*
+ * Pop the saved registers. Please note that `mcount' has no
+ * return value.
+ */
+ lm %r14,%r5,96(%r15)
+ ahi %r15,128
+ br %r14
+ ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(_mcount))
+
+#undef mcount
+weak_alias (_mcount, mcount)
diff --git a/libc/sysdeps/s390/s390-32/setjmp.S b/libc/sysdeps/s390/s390-32/setjmp.S
new file mode 100644
index 000000000..b943085e9
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/setjmp.S
@@ -0,0 +1,64 @@
+/*
+ Copyright (C) 2000, 2001, 2005 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _ASM
+#define _ASM
+#endif
+
+#include <sysdep.h>
+#include <bits/setjmp.h>
+
+/* Save the current program position in ENV and return 0. */
+/* R2 = pointer to jmp_buf, R3 = savemask */
+
+ENTRY(__sigsetjmp)
+#ifdef PTR_MANGLE
+ stm %r6,%r13,0(%r2) /* store registers in jmp_buf */
+ lr %r4,%r14
+ lr %r5,%r15
+ PTR_MANGLE (%r4, %r1)
+ PTR_MANGLE2 (%r5, %r1)
+ stm %r4,%r5,32(%r2)
+#else
+ stm %r6,%r15,0(%r2) /* store registers in jmp_buf */
+#endif
+ std %f4,40(%r2)
+ std %f6,48(%r2)
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ /* In ld.so we never save the signal mask. */
+ lhi %r2,0
+ br %r14
+#elif defined PIC
+ /* We cannot use the PLT, because it requires that %r12 be set, but
+ we can't save and restore our caller's value. Instead, we do an
+ indirect jump through the GOT. */
+ basr %r1,0
+.L0: al %r1,.L1 - .L0(0,%r1) /* get address of global offset table */
+ /* get address of __sigjmp_save from got */
+ l %r1,__sigjmp_save@GOT12(0,%r1)
+ br %r1
+.L1: .long _GLOBAL_OFFSET_TABLE_ - .L0
+#else
+ basr %r1,0
+.L0: l %r1,.L1-.L0(0,%r1) /* load address of __sigjmp_save */
+ br %r1 /* tail-call __sigjmp_save */
+.L1: .long __sigjmp_save
+#endif
+END (__sigsetjmp)
diff --git a/libc/sysdeps/s390/s390-32/strcmp.S b/libc/sysdeps/s390/s390-32/strcmp.S
new file mode 100644
index 000000000..fa077b6ff
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/strcmp.S
@@ -0,0 +1,42 @@
+/* strcmp - compare two string. S/390 version.
+ This file is part of the GNU C Library.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* INPUT PARAMETERS
+ %r2 = address of string 1
+ %r3 = address of string 2. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(strcmp)
+ slr %r0,%r0
+0: clst %r2,%r3
+ jo 0b
+ jp 1f
+ jm 2f
+ slr %r2,%r2
+ br %r14
+1: lhi %r2,1
+ br %r14
+2: lhi %r2,-1
+ br %r14
+END(strcmp)
+libc_hidden_builtin_def (strcmp)
diff --git a/libc/sysdeps/s390/s390-32/strcpy.S b/libc/sysdeps/s390/s390-32/strcpy.S
new file mode 100644
index 000000000..319ddfaec
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/strcpy.S
@@ -0,0 +1,37 @@
+/* strcpy - copy a string from source to destination. For IBM S390
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * R2 = address of destination
+ * R3 = address of source
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(strcpy)
+ slr %r0,%r0
+ lr %r1,%r2
+0: mvst %r1,%r3
+ jo 0b
+ br %r14
+END(strcpy)
+libc_hidden_builtin_def (strcpy)
diff --git a/libc/sysdeps/s390/s390-32/strncpy.S b/libc/sysdeps/s390/s390-32/strncpy.S
new file mode 100644
index 000000000..fdd81348b
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/strncpy.S
@@ -0,0 +1,80 @@
+/* strncpy - copy at most n characters from a string from source to
+ destination. For IBM S390
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * R2 = address of destination (dst)
+ * R3 = address of source (src)
+ * R4 = max of bytes to copy
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ENTRY(strncpy)
+ .text
+ st %r2,24(%r15) # save dst pointer
+ slr %r2,%r3 # %r3 points to src, %r2+%r3 to dst
+ lhi %r1,3
+ nr %r1,%r4 # last 2 bits of # bytes
+ srl %r4,2
+ ltr %r4,%r4 # less than 4 bytes to copy ?
+ jz .L1
+ bras %r5,.L0 # enter loop & load address of a 0
+ .long 0
+.L0: icm %r0,8,0(%r3) # first byte
+ jz .L3
+ icm %r0,4,1(%r3) # second byte
+ jz .L4
+ icm %r0,2,2(%r3) # third byte
+ jz .L5
+ icm %r0,1,3(%r3) # fourth byte
+ jz .L6
+ st %r0,0(%r2,%r3) # store all four to dest.
+ la %r3,4(%r3)
+ brct %r4,.L0
+.L1: ltr %r1,%r1
+ jz .Lexit
+.L2: icm %r0,1,0(%r3)
+ stc %r0,0(%r2,%r3)
+ la %r3,1(%r3)
+ jz .L7
+ brct %r1,.L2
+ j .Lexit
+.L3: icm %r0,4,0(%r5)
+.L4: icm %r0,2,0(%r5)
+.L5: icm %r0,1,0(%r5)
+.L6: st %r0,0(%r2,%r3)
+ la %r3,4(%r3)
+ ahi %r4,-1
+ j .L8
+.L7: ahi %r1,-1
+.L8: sll %r4,2
+ alr %r4,%r1
+ alr %r2,%r3 # start of dst area to be zeroed
+ lr %r3,%r4
+ slr %r4,%r4
+ slr %r5,%r5
+.L9: mvcle %r2,%r4,0 # pad dst with zeroes
+ jo .L9
+.Lexit: l %r2,24(%r15) # return dst pointer
+ br %r14
+END(strncpy)
+libc_hidden_builtin_def (strncpy)
diff --git a/libc/sysdeps/s390/s390-32/sub_n.S b/libc/sysdeps/s390/s390-32/sub_n.S
new file mode 100644
index 000000000..058183bc8
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/sub_n.S
@@ -0,0 +1,63 @@
+/* __mpn_sub_n -- Add two limb vectors of the same length > 0 and store
+ sum in a third limb vector.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr %r2
+ s1_ptr %r3
+ s2_ptr %r4
+ size %r5
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ENTRY(__mpn_sub_n)
+ st %r6,24(%r15) # save register 6
+ cfi_offset (%r6, -72)
+ sr %r1,%r1
+ lhi %r0,1 # cannot use ahi to add carry, use slr
+.L0: l %r6,0(%r1,%r3) # .L0 -> no carry from last sub
+ sl %r6,0(%r1,%r4)
+ st %r6,0(%r1,%r2)
+ la %r1,4(0,%r1)
+ brc 4,.L3
+.L1: brct %r5,.L0
+ slr %r2,%r2 # no last carry to return
+ j .Lexit
+.L2: l %r6,0(%r1,%r3) # .L2 -> carry from last sub
+ sl %r6,0(%r1,%r4)
+ brc 4,.L4
+ slr %r6,%r0 # no carry yet, add carry from last sub
+ st %r6,0(%r1,%r2)
+ la %r1,4(0,%r1)
+ brc 11,.L1 # new carry ?
+.L3: brct %r5,.L2
+ lr %r2,%r0 # return last carry
+ j .Lexit
+.L4: slr %r6,%r0 # already a carry, add carry from last sub
+ st %r6,0(%r1,%r2)
+ la %r1,4(0,%r1)
+ brct %r5,.L2
+ lr %r2,%r0 # return last carry
+.Lexit: l %r6,24(%r15) # restore register 6
+ br %r14
+END(__mpn_sub_n)
diff --git a/libc/sysdeps/s390/s390-32/sysdep.h b/libc/sysdeps/s390/s390-32/sysdep.h
new file mode 100644
index 000000000..f2d5bada8
--- /dev/null
+++ b/libc/sysdeps/s390/s390-32/sysdep.h
@@ -0,0 +1,119 @@
+/* Assembler macros for s390.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+/* Syntactic details of assembler. */
+
+#ifdef HAVE_ELF
+
+/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */
+#define ALIGNARG(log2) 1<<log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
+
+/* In ELF C symbols are asm symbols. */
+#undef NO_UNDERSCORES
+#define NO_UNDERSCORES
+
+#else
+
+#define ALIGNARG(log2) log2
+#define ASM_TYPE_DIRECTIVE(name,type) /* Nothing is specified. */
+#define ASM_SIZE_DIRECTIVE(name) /* Nothing is specified. */
+
+#endif
+
+
+/* Define an entry point visible from C. */
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ cfi_startproc; \
+ CALL_MCOUNT
+
+#undef END
+#define END(name) \
+ cfi_endproc; \
+ ASM_SIZE_DIRECTIVE(name) \
+
+/* If compiled for profiling, call `mcount' at the start of each function. */
+#ifdef PROF
+#ifdef PIC
+#define CALL_MCOUNT \
+ lr 0,14 ; bras 14,.+12 ; .long _GLOBAL_OFFSET_TABLE_ - . ; .long 0f-. ; \
+ lr 1,14 ; al 1,4(14) ; al 14,0(14) ; l 14,_mcount@GOT(14) ; \
+ basr 14,14 ; lr 14,0 ; .data ; .align 4 ; 0: .long 0 ; .text ;
+#else
+#define CALL_MCOUNT \
+ lr 0,14 ; bras 14,.+12 ; .long _mcount ; .long 0f ; \
+ l 1,4(14) ; l 14,0(14) ; basr 14,14 ; lr 14,0 ; \
+ .data ; .align 4 ; 0: .long 0 ; .text ;
+#endif
+#else
+#define CALL_MCOUNT /* Do nothing. */
+#endif
+
+#ifdef NO_UNDERSCORES
+/* Since C identifiers are not normally prefixed with an underscore
+ on this system, the asm identifier `syscall_error' intrudes on the
+ C name space. Make sure we use an innocuous name. */
+#define syscall_error __syscall_error
+#define mcount _mcount
+#endif
+
+#define PSEUDO(name, syscall_name, args) \
+lose: SYSCALL_PIC_SETUP \
+ basr %r1,0; \
+0: al %r1,1f-0b(%r1); \
+ br %r1; \
+1: .long JUMPTARGET(syscall_error) - 0b; \
+ .globl syscall_error; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ jm lose
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
+
+#undef JUMPTARGET
+#ifdef PIC
+#define JUMPTARGET(name) name##@PLT
+#define SYSCALL_PIC_SETUP \
+ bras %r12,1f \
+0: .long _GLOBAL_OFFSET_TABLE_-0b \
+1: al %r12,0(%r12)
+#else
+#define JUMPTARGET(name) name
+#define SYSCALL_PIC_SETUP /* Nothing. */
+#endif
+
+/* Local label name for asm code. */
+#ifndef L
+#define L(name) .L##name
+#endif
+
+#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/s390/s390-64/Implies b/libc/sysdeps/s390/s390-64/Implies
new file mode 100644
index 000000000..a8cae95f9
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/Implies
@@ -0,0 +1 @@
+wordsize-64
diff --git a/libc/sysdeps/s390/s390-64/Makefile b/libc/sysdeps/s390/s390-64/Makefile
new file mode 100644
index 000000000..0a5051449
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/Makefile
@@ -0,0 +1,11 @@
+pic-ccflag = -fpic
+
+ifeq ($(subdir),gmon)
+sysdep_routines += s390x-mcount
+endif
+
+ifeq ($(subdir),elf)
+CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused
+CFLAGS-dl-load.c += -Wno-unused
+CFLAGS-dl-reloc.c += -Wno-unused
+endif
diff --git a/libc/sysdeps/s390/s390-64/__longjmp.c b/libc/sysdeps/s390/s390-64/__longjmp.c
new file mode 100644
index 000000000..030fb5b51
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/__longjmp.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <setjmp.h>
+#include <bits/setjmp.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Jump to the position specified by ENV, causing the
+ setjmp call there to return VAL, or 1 if VAL is 0. */
+void
+__longjmp (__jmp_buf env, int val)
+{
+ register long int r2 __asm ("%r2") = val == 0 ? 1 : val;
+#ifdef PTR_DEMANGLE
+ register uintptr_t r3 __asm ("%r3") = THREAD_GET_POINTER_GUARD ();
+ register void *r1 __asm ("%r1") = (void *) env;
+#endif
+ /* Restore registers and jump back. */
+ asm volatile ("ld %%f7,104(%1)\n\t"
+ "ld %%f5,96(%1)\n\t"
+ "ld %%f3,88(%1)\n\t"
+ "ld %%f1,80(%1)\n\t"
+#ifdef PTR_DEMANGLE
+ "lmg %%r6,%%r13,0(%1)\n\t"
+ "lmg %%r4,%%r5,64(%1)\n\t"
+ "xgr %%r4,%2\n\t"
+ "xgr %%r5,%2\n\t"
+ "lgr %%r15,%%r5\n\t"
+ "br %%r4"
+#else
+ "lmg %%r6,%%r15,0(%1)\n\t"
+ "br %%r14"
+#endif
+ : : "r" (r2),
+#ifdef PTR_DEMANGLE
+ "r" (r1), "r" (r3)
+#else
+ "a" (env)
+#endif
+ );
+
+ /* Avoid `volatile function does return' warnings. */
+ for (;;);
+}
diff --git a/libc/sysdeps/s390/s390-64/add_n.S b/libc/sysdeps/s390/s390-64/add_n.S
new file mode 100644
index 000000000..51bf73f6f
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/add_n.S
@@ -0,0 +1,64 @@
+/* Add two limb vectors of the same length > 0 and store sum in a third
+ limb vector.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr %r2
+ s1_ptr %r3
+ s2_ptr %r4
+ size %r5
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__mpn_add_n)
+ stg %r6,48(%r15) # save register 6
+ cfi_offset (%r6,-112)
+ slgr %r1,%r1
+ lghi %r0,1 # cannot use ahi to add carry, use alr
+.L0: lg %r6,0(%r1,%r3) # .L0 -> no carry from last add
+ alg %r6,0(%r1,%r4)
+ stg %r6,0(%r1,%r2)
+ la %r1,8(%r1)
+ brc 3,.L3
+.L1: brct %r5,.L0
+ slgr %r2,%r2 # no last carry to return
+ j .Lexit
+.L2: lg %r6,0(%r1,%r3) # .L2 -> carry from last add
+ alg %r6,0(%r1,%r4)
+ brc 3,.L4
+ algr %r6,%r0 # no carry yet, add carry from last add
+ stg %r6,0(%r1,%r2)
+ la %r1,8(%r1)
+ brc 12,.L1 # new carry ?
+.L3: brct %r5,.L2
+ lgr %r2,%r0 # return last carry
+ j .Lexit
+.L4: algr %r6,%r0 # already a carry, add carry from last add
+ stg %r6,0(%r1,%r2)
+ la %r1,8(%r1)
+ brct %r5,.L2
+ lgr %r2,%r0 # return last carry
+.Lexit: lg %r6,48(%r15) # restore register 6
+ br %r14
+END(__mpn_add_n)
diff --git a/libc/sysdeps/s390/s390-64/backtrace.c b/libc/sysdeps/s390/s390-64/backtrace.c
new file mode 100644
index 000000000..7ba195cb7
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/backtrace.c
@@ -0,0 +1,144 @@
+/* Return backtrace of current program state. 64 bit S/390 version.
+ Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <bits/libc-lock.h>
+#include <dlfcn.h>
+#include <execinfo.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unwind.h>
+
+
+/* This is a global variable set at program start time. It marks the
+ highest used stack address. */
+extern void *__libc_stack_end;
+
+
+/* This is the stack layout we see for every non-leaf function.
+ size offset
+ %r15 -> +------------------+
+ 8 | back chain | 0
+ 8 | end of stack | 8
+ 32 | scratch | 16
+ 80 | save area r6-r15 | 48
+ 16 | save area f4,f6 | 128
+ 16 | empty | 144
+ +------------------+
+ r14 in the save area holds the return address.
+*/
+
+struct layout
+{
+ long back_chain;
+ long end_of_stack;
+ long scratch[4];
+ long save_grps[10];
+ long save_fp[2];
+ long empty[2];
+};
+
+struct trace_arg
+{
+ void **array;
+ int cnt, size;
+};
+
+#ifdef SHARED
+static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
+static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *);
+
+static void
+init (void)
+{
+ void *handle = __libc_dlopen ("libgcc_s.so.1");
+
+ if (handle == NULL)
+ return;
+
+ unwind_backtrace = __libc_dlsym (handle, "_Unwind_Backtrace");
+ unwind_getip = __libc_dlsym (handle, "_Unwind_GetIP");
+ if (unwind_getip == NULL)
+ unwind_backtrace = NULL;
+}
+#else
+# define unwind_backtrace _Unwind_Backtrace
+# define unwind_getip _Unwind_GetIP
+#endif
+
+int
+__backchain_backtrace (void **array, int size)
+{
+ /* We assume that all the code is generated with frame pointers set. */
+ struct layout *stack;
+ int cnt = 0;
+
+ asm ("LGR %0,%%r15" : "=d" (stack) );
+ /* We skip the call to this function, it makes no sense to record it. */
+ stack = (struct layout *) stack->back_chain;
+ while (cnt < size)
+ {
+ if (stack == NULL || (void *) stack > __libc_stack_end)
+ /* This means the address is out of range. Note that for the
+ toplevel we see a frame pointer with value NULL which clearly is
+ out of range. */
+ break;
+
+ array[cnt++] = (void *) stack->save_grps[8];
+
+ stack = (struct layout *) stack->back_chain;
+ }
+
+ return cnt;
+}
+
+static _Unwind_Reason_Code
+backtrace_helper (struct _Unwind_Context *ctx, void *a)
+{
+ struct trace_arg *arg = a;
+
+ /* We are first called with address in the __backtrace function.
+ Skip it. */
+ if (arg->cnt != -1)
+ arg->array[arg->cnt] = (void *) unwind_getip (ctx);
+ if (++arg->cnt == arg->size)
+ return _URC_END_OF_STACK;
+ return _URC_NO_REASON;
+}
+
+int
+__backtrace (void **array, int size)
+{
+ struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
+#ifdef SHARED
+ __libc_once_define (static, once);
+
+ __libc_once (once, init);
+#endif
+ if (unwind_backtrace == NULL)
+ return __backchain_backtrace (array, size);
+
+ if (size >= 1)
+ unwind_backtrace (backtrace_helper, &arg);
+
+ return arg.cnt != -1 ? arg.cnt : 0;
+}
+
+weak_alias (__backtrace, backtrace)
+libc_hidden_def (__backtrace)
diff --git a/libc/sysdeps/s390/s390-64/bcopy.S b/libc/sysdeps/s390/s390-64/bcopy.S
new file mode 100644
index 000000000..abcb1fb1b
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/bcopy.S
@@ -0,0 +1,72 @@
+/* bcopy -- copy a block from source to destination. 64 bit S/390 version.
+ This file is part of the GNU C Library.
+ Copyright (C) 2000, 2001, 2005 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* INPUT PARAMETERS
+ %r2 = address of source
+ %r3 = address of destination
+ %r4 = number of bytes to copy. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__bcopy)
+ ltgr %r1,%r4 # zero bcopy ?
+ jz .L4
+ clgr %r2,%r3 # check against destructive overlap
+ jnl .L0
+ algr %r1,%r2
+ clgr %r1,%r3
+ jh .L7
+.L0: aghi %r4,-1 # length - 1
+ srlg %r1,%r4,8
+ ltgr %r1,%r1 # < 256 bytes to move ?
+ jz .L2
+ cghi %r1,255 # > 1MB to move ?
+ jh .L5
+.L1: mvc 0(256,%r3),0(%r2) # move in 256 byte chunks
+ la %r2,256(%r2)
+ la %r3,256(%r3)
+ brctg %r1,.L1
+.L2: bras %r1,.L3 # setup base pointer for execute
+ mvc 0(1,%r3),0(%r2) # instruction for execute
+.L3: ex %r4,0(%r1) # execute mvc with length ((%r4)&255)+1
+.L4: br %r14
+ # data copies > 1MB are faster with mvcle.
+.L5: aghi %r4,1 # length + 1
+ lgr %r5,%r4 # source length
+ lgr %r4,%r2 # source address
+ lgr %r2,%r3 # set destination
+ lgr %r3,%r5 # destination length = source length
+.L6: mvcle %r2,%r4,0 # thats it, MVCLE is your friend
+ jo .L6
+ br %r14
+.L7: # destructive overlay, can not use mvcle
+ lgr %r1,%r2 # bcopy is called with source,dest
+ lgr %r2,%r3 # memmove with dest,source! Oh, well...
+ lgr %r3,%r1
+ jg HIDDEN_BUILTIN_JUMPTARGET(memmove)
+
+END(__bcopy)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__bcopy, bcopy)
+#endif
+
diff --git a/libc/sysdeps/s390/s390-64/bits/wordsize.h b/libc/sysdeps/s390/s390-64/bits/wordsize.h
new file mode 100644
index 000000000..b41661217
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/bits/wordsize.h
@@ -0,0 +1,18 @@
+/* Determine the wordsize from the preprocessor defines. */
+
+#if defined __s390x__
+# define __WORDSIZE 64
+#else
+# define __WORDSIZE 32
+#endif
+
+#if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL
+
+/* Signal that we didn't used to have a `long double'. The changes all
+ the `long double' function variants to be redirects to the double
+ functions. */
+# define __LONG_DOUBLE_MATH_OPTIONAL 1
+# ifndef __LONG_DOUBLE_128__
+# define __NO_LONG_DOUBLE_MATH 1
+# endif
+#endif
diff --git a/libc/sysdeps/s390/s390-64/bsd-_setjmp.S b/libc/sysdeps/s390/s390-64/bsd-_setjmp.S
new file mode 100644
index 000000000..78c6563b6
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/bsd-_setjmp.S
@@ -0,0 +1,35 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. 64 bit S/390 version.
+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#include <sysdep.h>
+
+ENTRY(_setjmp)
+ slgr %r3,%r3 /* Second argument of zero. */
+#ifdef PIC
+ jg __sigsetjmp@PLT /* Branch to PLT of __sigsetjmp. */
+#else
+ jg __sigsetjmp /* Branch to __sigsetjmp. */
+#endif
+END (_setjmp)
+libc_hidden_def (_setjmp)
diff --git a/libc/sysdeps/s390/s390-64/bsd-setjmp.S b/libc/sysdeps/s390/s390-64/bsd-setjmp.S
new file mode 100644
index 000000000..828a4e72b
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/bsd-setjmp.S
@@ -0,0 +1,34 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. 64 bit S/390 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#include <sysdep.h>
+
+ENTRY(setjmp)
+ lghi %r1,1 /* Second argument of one. */
+#ifdef PIC
+ jg __sigsetjmp@PLT /* Branch to PLT of __sigsetjmp. */
+#else
+ jg __sigsetjmp /* Branch to __sigsetjmp. */
+#endif
+END (setjmp)
diff --git a/libc/sysdeps/s390/s390-64/bzero.S b/libc/sysdeps/s390/s390-64/bzero.S
new file mode 100644
index 000000000..6c319e112
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/bzero.S
@@ -0,0 +1,42 @@
+/* bzero -- set a block of memory to zero. 64 bit S/390 version.
+ This file is part of the GNU C Library.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* INPUT PARAMETERS
+ %r2 = address of memory area
+ %r3 = number of bytes to fill. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(__bzero)
+ ltgr %r3,%r3
+ jz .L1
+ sgr %r1,%r1 # set pad byte to zero
+ sgr %r4,%r4 # no source for MVCLE, only a pad byte
+ sgr %r5,%r5
+.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend
+ jo .L0
+.L1: br %r14
+END(__bzero)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__bzero, bzero)
+#endif
diff --git a/libc/sysdeps/s390/s390-64/dl-machine.h b/libc/sysdeps/s390/s390-64/dl-machine.h
new file mode 100644
index 000000000..5026a2eda
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/dl-machine.h
@@ -0,0 +1,442 @@
+/* Machine-dependent ELF dynamic relocation inline functions.
+ 64 bit S/390 Version.
+ Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "s390x"
+
+#include <sys/param.h>
+#include <string.h>
+#include <link.h>
+
+/* This is an older, now obsolete value. */
+#define EM_S390_OLD 0xA390
+
+/* Return nonzero iff E_MACHINE is compatible with the running host. */
+static inline int
+elf_machine_matches_host (const Elf64_Ehdr *ehdr)
+{
+ return (ehdr->e_machine == EM_S390 || ehdr->e_machine == EM_S390_OLD)
+ && ehdr->e_ident[EI_CLASS] == ELFCLASS64;
+}
+
+/* Return the link-time address of _DYNAMIC. Conveniently, this is the
+ first element of the GOT. This must be inlined in a function which
+ uses global data. */
+
+static inline Elf64_Addr
+elf_machine_dynamic (void)
+{
+ register Elf64_Addr *got;
+
+ asm( " larl %0,_GLOBAL_OFFSET_TABLE_\n"
+ : "=&a" (got) : : "0" );
+
+ return *got;
+}
+
+/* Return the run-time load address of the shared object. */
+static inline Elf64_Addr
+elf_machine_load_address (void)
+{
+ Elf64_Addr addr;
+
+ asm( " larl %0,_dl_start\n"
+ " larl 1,_GLOBAL_OFFSET_TABLE_\n"
+ " lghi 2,_dl_start@GOT\n"
+ " slg %0,0(2,1)"
+ : "=&d" (addr) : : "1", "2" );
+ return addr;
+}
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int __attribute__ ((unused))
+elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+{
+ extern void _dl_runtime_resolve (Elf64_Word);
+ extern void _dl_runtime_profile (Elf64_Word);
+
+ if (l->l_info[DT_JMPREL] && lazy)
+ {
+ /* The GOT entries for functions in the PLT have not yet been filled
+ in. Their initial contents will arrange when called to push an
+ offset into the .rela.plt section, push _GLOBAL_OFFSET_TABLE_[1],
+ and then jump to _GLOBAL_OFFSET_TABLE[2]. */
+ Elf64_Addr *got;
+ got = (Elf64_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
+ /* If a library is prelinked but we have to relocate anyway,
+ we have to be able to undo the prelinking of .got.plt.
+ The prelinker saved us here address of .plt + 0x2e. */
+ if (got[1])
+ {
+ l->l_mach.plt = got[1] + l->l_addr;
+ l->l_mach.gotplt = (Elf64_Addr) &got[3];
+ }
+ got[1] = (Elf64_Addr) l; /* Identify this shared object. */
+
+ /* The got[2] entry contains the address of a function which gets
+ called to get the address of a so far unresolved function and
+ jump to it. The profiling extension of the dynamic linker allows
+ to intercept the calls to collect information. In this case we
+ don't store the address in the GOT so that all future calls also
+ end in this function. */
+ if (__builtin_expect (profile, 0))
+ {
+ got[2] = (Elf64_Addr) &_dl_runtime_profile;
+
+ if (GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), l))
+ /* This is the object we are looking for. Say that we really
+ want profiling and the timers are started. */
+ GL(dl_profile_map) = l;
+ }
+ else
+ /* This function will get called to fix up the GOT entry indicated by
+ the offset on the stack, and then jump to the resolved address. */
+ got[2] = (Elf64_Addr) &_dl_runtime_resolve;
+ }
+
+ return lazy;
+}
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+
+#define RTLD_START asm ("\n\
+.text\n\
+.align 4\n\
+.globl _start\n\
+.globl _dl_start_user\n\
+_start:\n\
+ lgr %r2,%r15\n\
+ # Alloc stack frame\n\
+ aghi %r15,-160\n\
+ # Set the back chain to zero\n\
+ xc 0(8,%r15),0(%r15)\n\
+ # Call _dl_start with %r2 pointing to arg on stack\n\
+ brasl %r14,_dl_start # call _dl_start\n\
+_dl_start_user:\n\
+ # Save the user entry point address in %r8.\n\
+ lgr %r8,%r2\n\
+ # Point %r12 at the GOT.\n\
+ larl %r12,_GLOBAL_OFFSET_TABLE_\n\
+ # See if we were run as a command with the executable file\n\
+ # name as an extra leading argument.\n\
+ lghi %r1,_dl_skip_args@GOT\n\
+ lg %r1,0(%r1,%r12)\n\
+ lgf %r1,0(%r1) # load _dl_skip_args\n\
+ # Get the original argument count.\n\
+ lg %r0,160(%r15)\n\
+ # Subtract _dl_skip_args from it.\n\
+ sgr %r0,%r1\n\
+ # Adjust the stack pointer to skip _dl_skip_args words.\n\
+ sllg %r1,%r1,3\n\
+ agr %r15,%r1\n\
+ # Set the back chain to zero again\n\
+ xc 0(8,%r15),0(%r15)\n\
+ # Store back the modified argument count.\n\
+ stg %r0,160(%r15)\n\
+ # The special initializer gets called with the stack just\n\
+ # as the application's entry point will see it; it can\n\
+ # switch stacks if it moves these contents over.\n\
+" RTLD_START_SPECIAL_INIT "\n\
+ # Call the function to run the initializers.\n\
+ # Load the parameters:\n\
+ # (%r2, %r3, %r4, %r5) = (_dl_loaded, argc, argv, envp)\n\
+ lghi %r2,_rtld_local@GOT\n\
+ lg %r2,0(%r2,%r12)\n\
+ lg %r2,0(%r2)\n\
+ lg %r3,160(%r15)\n\
+ la %r4,168(%r15)\n\
+ lgr %r5,%r3\n\
+ sllg %r5,%r5,3\n\
+ la %r5,176(%r5,%r15)\n\
+ brasl %r14,_dl_init_internal@PLT\n\
+ # Pass our finalizer function to the user in %r14, as per ELF ABI.\n\
+ lghi %r14,_dl_fini@GOT\n\
+ lg %r14,0(%r14,%r12)\n\
+ # Free stack frame\n\
+ aghi %r15,160\n\
+ # Jump to the user's entry point (saved in %r8).\n\
+ br %r8\n\
+");
+
+#ifndef RTLD_START_SPECIAL_INIT
+#define RTLD_START_SPECIAL_INIT /* nothing */
+#endif
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#ifdef USE_TLS
+# define elf_machine_type_class(type) \
+ ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD \
+ || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+# define elf_machine_type_class(type) \
+ ((((type) == R_390_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT
+
+/* The 64 bit S/390 never uses Elf64_Rel relocations. */
+#define ELF_MACHINE_NO_REL 1
+
+/* We define an initialization functions. This is called very early in
+ _dl_sysdep_start. */
+#define DL_PLATFORM_INIT dl_platform_init ()
+
+static inline void __attribute__ ((unused))
+dl_platform_init (void)
+{
+ if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
+ /* Avoid an empty string which would disturb us. */
+ GLRO(dl_platform) = NULL;
+}
+
+static inline Elf64_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf64_Rela *reloc,
+ Elf64_Addr *reloc_addr, Elf64_Addr value)
+{
+ return *reloc_addr = value;
+}
+
+/* Return the final value of a plt relocation. */
+static inline Elf64_Addr
+elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
+ Elf64_Addr value)
+{
+ return value;
+}
+
+/* Names of the architecture-specific auditing callback functions. */
+#define ARCH_LA_PLTENTER s390_64_gnu_pltenter
+#define ARCH_LA_PLTEXIT s390_64_gnu_pltexit
+
+#endif /* !dl_machine_h */
+
+#ifdef RESOLVE_MAP
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ MAP is the object containing the reloc. */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
+ const Elf64_Sym *sym, const struct r_found_version *version,
+ void *const reloc_addr_arg)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+ const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
+
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+ if (__builtin_expect (r_type == R_390_RELATIVE, 0))
+ {
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ /* This is defined in rtld.c, but nowhere in the static libc.a;
+ make the reference weak so static programs can still link.
+ This declaration cannot be done when compiling rtld.c
+ (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the
+ common defn for _dl_rtld_map, which is incompatible with a
+ weak decl in the same file. */
+# ifndef SHARED
+ weak_extern (GL(dl_rtld_map));
+# endif
+ if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
+# endif
+ *reloc_addr = map->l_addr + reloc->r_addend;
+ }
+ else
+#endif
+ if (__builtin_expect (r_type == R_390_NONE, 0))
+ return;
+ else
+ {
+#ifndef RESOLVE_CONFLICT_FIND_MAP
+ const Elf64_Sym *const refsym = sym;
+#endif
+ struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+ Elf64_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+
+ switch (r_type)
+ {
+ case R_390_GLOB_DAT:
+ case R_390_JMP_SLOT:
+ *reloc_addr = value + reloc->r_addend;
+ break;
+
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+ && !defined RESOLVE_CONFLICT_FIND_MAP
+ case R_390_TLS_DTPMOD:
+# ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always the module
+ with index 1.
+ XXX If this relocation is necessary move before RESOLVE
+ call. */
+ *reloc_addr = 1;
+# else
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+# endif
+ break;
+ case R_390_TLS_DTPOFF:
+# ifndef RTLD_BOOTSTRAP
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ if (sym != NULL)
+ *reloc_addr = sym->st_value + reloc->r_addend;
+# endif
+ break;
+ case R_390_TLS_TPOFF:
+ /* The offset is negative, forward from the thread pointer. */
+# ifdef RTLD_BOOTSTRAP
+ *reloc_addr = sym->st_value + reloc->r_addend - map->l_tls_offset;
+# else
+ /* We know the offset of the object the symbol is contained in.
+ It is a negative value which will be added to the
+ thread pointer. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = (sym->st_value + reloc->r_addend
+ - sym_map->l_tls_offset);
+ }
+#endif
+ break;
+#endif /* use TLS */
+
+#ifndef RTLD_BOOTSTRAP
+# ifndef RESOLVE_CONFLICT_FIND_MAP
+ /* Not needed for dl-conflict.c. */
+ case R_390_COPY:
+ if (sym == NULL)
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
+ if (__builtin_expect (sym->st_size > refsym->st_size, 0)
+ || (__builtin_expect (sym->st_size < refsym->st_size, 0)
+ && __builtin_expect (GLRO(dl_verbose), 0)))
+ {
+ const char *strtab;
+
+ strtab = (const char *) D_PTR (map,l_info[DT_STRTAB]);
+ _dl_error_printf ("\
+%s: Symbol `%s' has different size in shared object, consider re-linking\n",
+ rtld_progname ?: "<program name unknown>",
+ strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr_arg, (void *) value,
+ MIN (sym->st_size, refsym->st_size));
+ break;
+# endif
+ case R_390_64:
+ *reloc_addr = value + reloc->r_addend;
+ break;
+ case R_390_32:
+ *(unsigned int *) reloc_addr = value + reloc->r_addend;
+ break;
+ case R_390_16:
+ *(unsigned short *) reloc_addr = value + reloc->r_addend;
+ break;
+ case R_390_8:
+ *(char *) reloc_addr = value + reloc->r_addend;
+ break;
+# ifndef RESOLVE_CONFLICT_FIND_MAP
+ case R_390_PC64:
+ *reloc_addr = value +reloc->r_addend - (Elf64_Addr) reloc_addr;
+ break;
+ case R_390_PC32DBL:
+ case R_390_PLT32DBL:
+ *(unsigned int *) reloc_addr = (unsigned int)
+ ((int) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1);
+ break;
+ case R_390_PC32:
+ *(unsigned int *) reloc_addr =
+ value + reloc->r_addend - (Elf64_Addr) reloc_addr;
+ break;
+ case R_390_PC16DBL:
+ case R_390_PLT16DBL:
+ *(unsigned short *) reloc_addr = (unsigned short)
+ ((short) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1);
+ break;
+ case R_390_PC16:
+ *(unsigned short *) reloc_addr =
+ value + reloc->r_addend - (Elf64_Addr) reloc_addr;
+ break;
+ case R_390_NONE:
+ break;
+# endif
+#endif
+#if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG)
+ default:
+ /* We add these checks in the version to relocate ld.so only
+ if we are still debugging. */
+ _dl_reloc_bad_type (map, r_type, 0);
+ break;
+#endif
+ }
+ }
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+ *reloc_addr = l_addr + reloc->r_addend;
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf64_Addr l_addr, const Elf64_Rela *reloc)
+{
+ Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
+ const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
+ /* Check for unexpected PLT reloc type. */
+ if (__builtin_expect (r_type == R_390_JMP_SLOT, 1))
+ {
+ if (__builtin_expect (map->l_mach.plt, 0) == 0)
+ *reloc_addr += l_addr;
+ else
+ *reloc_addr =
+ map->l_mach.plt
+ + (((Elf64_Addr) reloc_addr) - map->l_mach.gotplt) * 4;
+ }
+ else
+ _dl_reloc_bad_type (map, r_type, 1);
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/libc/sysdeps/s390/s390-64/dl-trampoline.S b/libc/sysdeps/s390/s390-64/dl-trampoline.S
new file mode 100644
index 000000000..809358216
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/dl-trampoline.S
@@ -0,0 +1,128 @@
+/* PLT trampolines. s390 version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile
+ * with the following linkage:
+ * r2 - r6 : parameter registers
+ * f0, f2, f4, f6 : floating point parameter registers
+ * 24(r15), 28(r15) : PLT arguments PLT1, PLT2
+ * 96(r15) : additional stack parameters
+ * The normal clobber rules for function calls apply:
+ * r0 - r5 : call clobbered
+ * r6 - r13 : call saved
+ * r14 : return address (call clobbered)
+ * r15 : stack pointer (call saved)
+ * f1, f3, f5, f7 : call saved
+ * f0 - f3, f5, f7 - f15 : call clobbered
+ */
+
+#include <sysdep.h>
+
+ .text
+ .globl _dl_runtime_resolve
+ .type _dl_runtime_resolve, @function
+ cfi_startproc
+ .align 16
+_dl_runtime_resolve:
+ stmg 2,5,64(15) # save registers
+ stg 14,96(15)
+ lgr 0,15 # create stack frame
+ aghi 15,-160
+ cfi_adjust_cfa_offset (160)
+ stg 0,0(15)
+ lmg 2,3,208(15) # load args saved by PLT
+ brasl 14,_dl_fixup # call fixup
+ lgr 1,2 # function addr returned in r2
+ aghi 15,160 # remove stack frame
+ cfi_adjust_cfa_offset (-160)
+ lg 14,96(15) # restore registers
+ lmg 2,5,64(15)
+ br 1
+ cfi_endproc
+ .size _dl_runtime_resolve, .-_dl_runtime_resolve
+
+
+#ifndef PROF
+ .globl _dl_runtime_profile
+ .type _dl_runtime_profile, @function
+ cfi_startproc
+ .align 16
+_dl_runtime_profile:
+ stmg %r2,%r6,64(%r15) # save registers
+ std %f0,104(%r15)
+ std %f2,112(%r15)
+ std %f4,120(%r15)
+ std %f6,128(%r15)
+ stg %r6,16(%r15)
+ stg %r12,24(%r15)
+ stg %r14,32(%r15)
+ lgr %r12,%r15 # create stack frame
+ cfi_def_cfa_register (12)
+ aghi %r15,-160
+ stg %r12,0(%r15)
+ lmg %r2,%r3,48(%r12) # load arguments saved by PLT
+ lgr %r4,%r14 # return address as third parameter
+ la %r5,64(%r12) # pointer to struct La_s390_32_regs
+ la %r6,40(%r12) # long int * framesize
+ brasl %r14,_dl_profile_fixup # call resolver
+ lgr %r1,%r2 # function addr returned in r2
+ lg %r0,40(%r12) # load framesize
+ ltgr %r0,%r0
+ jnm 1f
+ lmg %r2,%r6,64(%r12)
+ ld %f0,104(%r12)
+ ld %f2,112(%r12)
+ ld %f4,120(%r12)
+ ld %f6,128(%r12)
+ basr %r14,%r1 # call resolved function
+0: lr %r15,%r12 # remove stack frame
+ cfi_def_cfa_register (15)
+ lg %r14,32(%r15) # restore registers
+ lg %r12,24(%r15)
+ lg %r6,16(%r15)
+ br %r14
+ cfi_def_cfa_register (12)
+1: jz 4f # framesize == 0 ?
+ aghi %r0,7 # align framesize to 8
+ nill %r0,0xfff8
+ slgr %r15,%r0 # make room for framesize bytes
+ stg %r12,0(%r15)
+ la %r2,160(%r15)
+ la %r3,160(%r12)
+ srlg %r0,%r0,3
+3: mvc 0(8,%r2),0(%r3) # copy additional parameters
+ la %r2,8(%r2)
+ la %r3,8(%r3)
+ brctg %r0,3b
+4: lmg %r2,%r6,64(%r12) # load register parameters
+ ld %f0,104(%r12)
+ ld %f2,112(%r12)
+ ld %f4,120(%r12)
+ ld %f6,128(%r12)
+ basr %r14,%r1 # call resolved function
+ stg %r2,136(%r12)
+ std %f0,144(%r12)
+ lmg %r2,%r3,48(%r12) # load arguments saved by PLT
+ la %r4,32(%r12) # pointer to struct La_s390_32_regs
+ la %r5,72(%r12) # pointer to struct La_s390_32_retval
+ brasl %r14,_dl_call_pltexit
+ j 0b
+ cfi_endproc
+ .size _dl_runtime_profile, .-_dl_runtime_profile
+#endif
diff --git a/libc/sysdeps/s390/s390-64/elf/bsd-_setjmp.S b/libc/sysdeps/s390/s390-64/elf/bsd-_setjmp.S
new file mode 100644
index 000000000..141727020
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/elf/bsd-_setjmp.S
@@ -0,0 +1 @@
+/* We don't need any code here since the setjmp.S file contains it. */
diff --git a/libc/sysdeps/s390/s390-64/elf/bsd-setjmp.S b/libc/sysdeps/s390/s390-64/elf/bsd-setjmp.S
new file mode 100644
index 000000000..141727020
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/elf/bsd-setjmp.S
@@ -0,0 +1 @@
+/* We don't need any code here since the setjmp.S file contains it. */
diff --git a/libc/sysdeps/s390/s390-64/elf/configure b/libc/sysdeps/s390/s390-64/elf/configure
new file mode 100644
index 000000000..adf5174ab
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/elf/configure
@@ -0,0 +1,52 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/s390/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+echo "$as_me:$LINENO: checking for s390 TLS support" >&5
+echo $ECHO_N "checking for s390 TLS support... $ECHO_C" >&6
+if test "${libc_cv_390_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.S <<\EOF
+ .section ".tdata", "awT", @progbits
+foo: .long 25
+ .text
+ .quad foo@TLSGD
+ .quad foo@TLSLDM
+ .quad foo@DTPOFF
+ .quad foo@NTPOFF
+ .quad foo@GOTNTPOFF
+ .quad foo@INDNTPOFF
+ lg %r1,foo@GOTNTPOFF(%r12)
+ lg %r1,0(%r1):tls_load:foo
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:foo
+ brasl %r14,__tls_get_offset@plt:tls_ldcall:foo
+EOF
+if { ac_try='${CC-cc} -S $CFLAGS conftest.S 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_390_tls=yes
+else
+ libc_cv_390_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_390_tls" >&5
+echo "${ECHO_T}$libc_cv_390_tls" >&6
+if test $libc_cv_390_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+cat >>confdefs.h <<\_ACEOF
+#define PI_STATIC_AND_HIDDEN 1
+_ACEOF
+
diff --git a/libc/sysdeps/s390/s390-64/elf/configure.in b/libc/sysdeps/s390/s390-64/elf/configure.in
new file mode 100644
index 000000000..ac953fcff
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/elf/configure.in
@@ -0,0 +1,37 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/s390/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for s390 TLS support, libc_cv_390_tls, [dnl
+cat > conftest.S <<\EOF
+ .section ".tdata", "awT", @progbits
+foo: .long 25
+ .text
+ .quad foo@TLSGD
+ .quad foo@TLSLDM
+ .quad foo@DTPOFF
+ .quad foo@NTPOFF
+ .quad foo@GOTNTPOFF
+ .quad foo@INDNTPOFF
+ lg %r1,foo@GOTNTPOFF(%r12)
+ lg %r1,0(%r1):tls_load:foo
+ brasl %r14,__tls_get_offset@plt:tls_gdcall:foo
+ brasl %r14,__tls_get_offset@plt:tls_ldcall:foo
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.S 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_390_tls=yes
+else
+ libc_cv_390_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_390_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
+dnl It is always possible to access static and hidden symbols in an
+dnl position independent way.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
diff --git a/libc/sysdeps/s390/s390-64/elf/setjmp.S b/libc/sysdeps/s390/s390-64/elf/setjmp.S
new file mode 100644
index 000000000..28b6a5a35
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/elf/setjmp.S
@@ -0,0 +1,72 @@
+/* setjmp for 64 bit S/390, ELF version.
+ Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ASM
+#define _SETJMP_H
+#include <bits/setjmp.h>
+
+ /* We include the BSD entry points here as well but we make
+ them weak. */
+ENTRY (setjmp)
+ .weak C_SYMBOL_NAME (setjmp)
+ lghi %r3,1 /* Second argument of one. */
+ j .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp. */
+END (setjmp)
+
+ /* Binary compatibility entry point. */
+ENTRY(_setjmp)
+ .weak C_SYMBOL_NAME (_setjmp)
+ slgr %r3,%r3 /* Second argument of zero. */
+ j .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp. */
+END (setjmp)
+libc_hidden_def (_setjmp)
+
+ENTRY(__setjmp)
+ slgr %r3,%r3 /* Second argument of zero. */
+ j .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp. */
+END (setjmp)
+
+ENTRY(__sigsetjmp)
+.Linternal_sigsetjmp:
+#ifdef PTR_MANGLE
+ stmg %r6,%r13,0(%r2) /* Store registers in jmp_buf. */
+ lgr %r4,%r14
+ lgr %r5,%r15
+ PTR_MANGLE (%r4, %r1)
+ PTR_MANGLE2 (%r5, %r1)
+ stmg %r4,%r5,64(%r2)
+#else
+ stmg %r6,%r15,0(%r2) /* Store registers in jmp_buf. */
+#endif
+ std %f1,80(%r2)
+ std %f3,88(%r2)
+ std %f5,96(%r2)
+ std %f7,104(%r2)
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ /* In ld.so we never save the signal mask. */
+ lghi %r2,0
+ br %r14
+#elif defined PIC
+ jg __sigjmp_save@PLT /* Branch to PLT of __sigsetjmp. */
+#else
+ jg __sigjmp_save
+#endif
+END (__sigsetjmp)
diff --git a/libc/sysdeps/s390/s390-64/elf/start.S b/libc/sysdeps/s390/s390-64/elf/start.S
new file mode 100644
index 000000000..c4cb34d02
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/elf/start.S
@@ -0,0 +1,101 @@
+/* Startup code compliant to the 64 bit S/390 ELF ABI.
+ Copyright (C) 2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ This is the canonical entry point, usually the first thing in the text
+ segment. Most registers' values are unspecified, except for:
+
+ %r14 Contains a function pointer to be registered with `atexit'.
+ This is how the dynamic linker arranges to have DT_FINI
+ functions called for shared libraries that have been loaded
+ before this code runs.
+
+ %r15 The stack contains the arguments and environment:
+ 0(%r15) argc
+ 8(%r15) argv[0]
+ ...
+ (8*argc)(%r15) NULL
+ (8*(argc+1))(%r15) envp[0]
+ ...
+ NULL
+*/
+
+ .text
+ .globl _start
+ .type _start,@function
+_start:
+ /* Load argc and argv from stack. */
+ la %r4,8(%r15) # get argv
+ lg %r3,0(%r15) # get argc
+
+ /* Align the stack to a double word boundary. */
+ lghi %r0,-16
+ ngr %r15,%r0
+
+ /* Setup a stack frame and a parameter area. */
+ aghi %r15,-176 # make room on stack
+ xc 0(8,%r15),0(%r15) # clear back-chain
+
+ /* Set up arguments for __libc_start_main:
+ main, argc, argv, envp, _init, _fini, rtld_fini, stack_end
+ Note that envp will be determined later in __libc_start_main.
+ */
+ stmg %r14,%r15,160(%r15) # store rtld_fini/stack_end to parameter area
+ la %r7,160(%r15)
+ larl %r6,__libc_csu_fini # load pointer to __libc_csu_fini
+ larl %r5,__libc_csu_init # load pointer to __libc_csu_init
+
+ /* Ok, now branch to the libc main routine. */
+#ifdef PIC
+ larl %r2,main@GOTENT # load pointer to main
+ lg %r2,0(%r2)
+ brasl %r14,__libc_start_main@plt
+#else
+ larl %r2,main # load pointer to main
+ brasl %r14,__libc_start_main
+#endif
+
+ /* Crash if __libc_start_main returns. */
+ .word 0
+
+ /* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+ .long 0
+ .weak data_start
+ data_start = __data_start
diff --git a/libc/sysdeps/s390/s390-64/initfini.c b/libc/sysdeps/s390/s390-64/initfini.c
new file mode 100644
index 000000000..083a16044
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/initfini.c
@@ -0,0 +1,144 @@
+/* Special .init and .fini section support for 64 bit S/390.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file is compiled into assembly code which is then munged by a sed
+ script into two files: crti.s and crtn.s.
+
+ * crti.s puts a function prologue at the beginning of the
+ .init and .fini sections and defines global symbols for
+ those addresses, so they can be called as functions.
+
+ * crtn.s puts the corresponding function epilogues
+ in the .init and .fini sections. */
+
+__asm__ ("\
+\n\
+#include \"defs.h\"\n\
+\n\
+/*@HEADER_ENDS*/\n\
+\n\
+/*@TESTS_BEGIN*/\n\
+\n\
+/*@TESTS_END*/\n\
+\n\
+/*@_init_PROLOG_BEGINS*/\n\
+\n\
+ .section .init\n\
+#NO_APP\n\
+ .align 4\n\
+.globl _init\n\
+ .type _init,@function\n\
+_init:\n\
+# leaf function 0\n\
+# automatics 0\n\
+# outgoing args 0\n\
+# need frame pointer 0\n\
+# call alloca 0\n\
+# has varargs 0\n\
+# incoming args (stack) 0\n\
+# function length 36\n\
+ STMG 6,15,48(15)\n\
+ LGR 1,15\n\
+ AGHI 15,-160\n\
+ STG 1,0(15)\n\
+ LARL 12,_GLOBAL_OFFSET_TABLE_\n\
+ LARL 1,__gmon_start__@GOTENT\n\
+ LG 1,0(1)\n\
+ LTGR 1,1\n\
+ JE .L22\n\
+ BASR 14,1\n\
+.L22:\n\
+#APP\n\
+ .align 4,0x07\n\
+ END_INIT\n\
+\n\
+/*@_init_PROLOG_ENDS*/\n\
+\n\
+/*@_init_EPILOG_BEGINS*/\n\
+ .align 4\n\
+ .section .init\n\
+#NO_APP\n\
+ .align 4\n\
+ LG 4,272(15)\n\
+ LMG 6,15,208(15)\n\
+ BR 4\n\
+#APP\n\
+ END_INIT\n\
+\n\
+/*@_init_EPILOG_ENDS*/\n\
+\n\
+/*@_fini_PROLOG_BEGINS*/\n\
+ .section .fini\n\
+#NO_APP\n\
+ .align 4\n\
+.globl _fini\n\
+ .type _fini,@function\n\
+_fini:\n\
+# leaf function 0\n\
+# automatics 0\n\
+# outgoing args 0\n\
+# need frame pointer 0\n\
+# call alloca 0\n\
+# has varargs 0\n\
+# incoming args (stack) 0\n\
+# function length 30\n\
+ STMG 6,15,48(15)\n\
+ LGR 1,15\n\
+ AGHI 15,-160\n\
+ STG 1,0(15)\n\
+ LARL 12,_GLOBAL_OFFSET_TABLE_\n\
+#APP\n\
+ .align 4,0x07\n\
+ END_FINI\n\
+\n\
+/*@_fini_PROLOG_ENDS*/\n\
+\n\
+/*@_fini_EPILOG_BEGINS*/\n\
+ .align 4\n\
+ .section .fini\n\
+#NO_APP\n\
+ .align 4\n\
+ LG 4,272(15)\n\
+ LMG 6,15,208(15)\n\
+ BR 4\n\
+#APP\n\
+ END_FINI\n\
+\n\
+/*@_fini_EPILOG_ENDS*/\n\
+\n\
+ /*@TRAILER_BEGINS*/\
+");
diff --git a/libc/sysdeps/s390/s390-64/memchr.S b/libc/sysdeps/s390/s390-64/memchr.S
new file mode 100644
index 000000000..e06bfb111
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/memchr.S
@@ -0,0 +1,41 @@
+/* Search a character in a block of memory. 64 bit S/390 version.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* INPUT PARAMETERS
+ %r2 = address to memory area
+ %r3 = character to find
+ %r4 = number of bytes to search. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(memchr)
+ lghi %r0,0xff
+ ngr %r0,%r3
+ lgr %r1,%r2
+ la %r2,0(%r4,%r1)
+0: srst %r2,%r1
+ jo 0b
+ brc 13,1f
+ slgr %r2,%r2
+1: br %r14
+END(memchr)
+libc_hidden_builtin_def (memchr)
diff --git a/libc/sysdeps/s390/s390-64/memcpy.S b/libc/sysdeps/s390/s390-64/memcpy.S
new file mode 100644
index 000000000..c62ba8890
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/memcpy.S
@@ -0,0 +1,58 @@
+/* memcpy - copy a block from source to destination. 64 bit S/390 version.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* INPUT PARAMETERS
+ %r2 = address of destination memory area
+ %r3 = address of source memory area
+ %r4 = number of bytes to copy. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(memcpy)
+ ltgr %r4,%r4
+ jz .L3
+ aghi %r4,-1 # length - 1
+ lgr %r1,%r2 # copy destination address
+ srlg %r5,%r4,8
+ ltgr %r5,%r5 # < 256 bytes to mvoe ?
+ jz .L1
+ chi %r5,255 # > 1 MB to move ?
+ jh .L4
+.L0: mvc 0(256,%r1),0(%r3) # move in 256 byte chunks
+ la %r1,256(%r1)
+ la %r3,256(%r3)
+ brctg %r5,.L0
+.L1: bras %r5,.L2 # setup base pointer for execute
+ mvc 0(1,%r1),0(%r3) # instruction for execute
+.L2: ex %r4,0(%r5) # execute mvc with length ((%r4)&255)+1
+.L3: br %r14
+ # data copies > 1MB are faster with mvcle.
+.L4: aghi %r4,1 # length + 1
+ lgr %r5,%r4 # source length
+ lgr %r4,%r3 # source address
+ lgr %r3,%r5 # destination length = source length
+.L5: mvcle %r2,%r4,0 # thats it, MVCLE is your friend
+ jo .L5
+ lgr %r2,%r1 # return destination address
+ br %r14
+END(memcpy)
+libc_hidden_builtin_def (memcpy)
diff --git a/libc/sysdeps/s390/s390-64/memset.S b/libc/sysdeps/s390/s390-64/memset.S
new file mode 100644
index 000000000..cfbab643b
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/memset.S
@@ -0,0 +1,44 @@
+/* Set a block of memory to some byte value. 64 bit S/390 version.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* INPUT PARAMETERS
+ %r2 = address of memory area
+ %r3 = byte to fill memory with
+ %r4 = number of bytes to fill. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(memset)
+ ltgr %r4,%r4
+ jz .L1
+ lgr %r0,%r2 # save source address
+ lgr %r1,%r3 # move pad byte to R1
+ lgr %r3,%r4
+ sgr %r4,%r4 # no source for MVCLE, only a pad byte
+ sgr %r5,%r5
+.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend
+ jo .L0
+ lgr %r2,%r0 # return value is source address
+.L1:
+ br %r14
+END(memset)
+libc_hidden_builtin_def (memset)
diff --git a/libc/sysdeps/s390/s390-64/s390x-mcount.S b/libc/sysdeps/s390/s390-64/s390x-mcount.S
new file mode 100644
index 000000000..0fa614cbf
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/s390x-mcount.S
@@ -0,0 +1,72 @@
+/* 64 bit S/390-specific implemetation of profiling support.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com)
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* How profiling works on 64 bit S/390:
+ On the start of each function _mcount is called with the address of a
+ data word in %r1 (initialized to 0, used for counting). The compiler
+ with the option -p generates code of the form:
+
+ STM 6,15,24(15)
+ BRAS 13,.LTN0_0
+ .LT0_0:
+ .LC13: .long .LP0
+ .data
+ .align 4
+ .LP0: .long 0
+ .text
+ # function profiler
+ stg 14,4(15)
+ lg 1,.LC13-.LT0_0(13)
+ brasl 14,_mcount
+ lg 14,4(15)
+
+ The _mcount implementation now has to call __mcount_internal with the
+ address of .LP0 as first parameter and the return address as second
+ parameter. &.LP0 was loaded to %r1 and the return address is in %r14.
+ _mcount may not modify any register. */
+
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(_mcount)
+ ASM_TYPE_DIRECTIVE(C_SYMBOL_NAME(_mcount), @function)
+ .align ALIGNARG(4)
+C_LABEL(_mcount)
+ /* Save the caller-clobbered registers. */
+ aghi %r15,-224
+ stmg %r14,%r5,160(%r15)
+ lg %r2,232(%r15) # callers address = first parameter
+ la %r2,0(%r2) # clear bit 0
+ la %r3,0(%r14) # callees address = second parameter
+
+#ifdef PIC
+ brasl %r14,__mcount_internal@PLT
+#else
+ brasl %r14,__mcount_internal
+#endif
+
+ /* Pop the saved registers. Please note that `mcount' has no
+ return value. */
+ lmg %r14,%r5,160(%r15)
+ ahi %r15,224
+ br %r14
+ ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(_mcount))
+
+#undef mcount
+weak_alias (_mcount, mcount)
diff --git a/libc/sysdeps/s390/s390-64/setjmp.S b/libc/sysdeps/s390/s390-64/setjmp.S
new file mode 100644
index 000000000..a962db46c
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/setjmp.S
@@ -0,0 +1,54 @@
+/* Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _ASM
+#define _ASM
+#endif
+
+#include <sysdep.h>
+#include <bits/setjmp.h>
+
+/* Save the current program position in ENV and return 0. */
+/* R2 = pointer to jmp_buf, R3 = savemask. */
+
+ENTRY(__sigsetjmp)
+#ifdef PTR_MANGLE
+ stmg %r6,%r13,0(%r2) /* Store registers in jmp_buf. */
+ lgr %r4,%r14
+ lgr %r5,%r15
+ PTR_MANGLE (%r4, %r1)
+ PTR_MANGLE2 (%r5, %r1)
+ stmg %r4,%r5,64(%r2)
+#else
+ stmg %r6,%r15,0(%r2) /* Store registers in jmp_buf. */
+#endif
+ std %f1,80(%r2)
+ std %f3,88(%r2)
+ std %f5,96(%r2)
+ std %f7,104(%r2)
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ /* In ld.so we never save the signal mask. */
+ lghi %r2,0
+ br %r14
+#elif defined PIC
+ jg __sigjmp_save@PLT /* Tail-call __sigjmp_save. */
+#else
+ jg __sigjmp_save /* Tail-call __sigjmp_save. */
+#endif
+END (__sigsetjmp)
diff --git a/libc/sysdeps/s390/s390-64/strcmp.S b/libc/sysdeps/s390/s390-64/strcmp.S
new file mode 100644
index 000000000..6cd8baa2f
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/strcmp.S
@@ -0,0 +1,42 @@
+/* strcmp - compare two string. 64 bit S/390 version.
+ This file is part of the GNU C Library.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* INPUT PARAMETERS
+ %r2 = address of string 1
+ %r3 = address of string 2. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(strcmp)
+ slr %r0,%r0
+0: clst %r2,%r3
+ jo 0b
+ jp 1f
+ jm 2f
+ slgr %r2,%r2
+ br %r14
+1: lghi %r2,1
+ br %r14
+2: lghi %r2,-1
+ br %r14
+END(strcmp)
+libc_hidden_builtin_def (strcmp)
diff --git a/libc/sysdeps/s390/s390-64/strcpy.S b/libc/sysdeps/s390/s390-64/strcpy.S
new file mode 100644
index 000000000..15785dcc0
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/strcpy.S
@@ -0,0 +1,36 @@
+/* strcpy - copy a string from source to destination. 64 bit S/390 version.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* INPUT PARAMETERS
+ %r2 = address of destination
+ %r3 = address of source. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ .text
+ENTRY(strcpy)
+ slgr %r0,%r0
+ lgr %r1,%r2
+0: mvst %r1,%r3
+ jo 0b
+ br %r14
+END(strcpy)
+libc_hidden_builtin_def (strcpy)
diff --git a/libc/sysdeps/s390/s390-64/strncpy.S b/libc/sysdeps/s390/s390-64/strncpy.S
new file mode 100644
index 000000000..cc6986fb4
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/strncpy.S
@@ -0,0 +1,91 @@
+/* strncpy - copy at most n characters from a string from source to
+ destination. 64 bit S/390 version
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* INPUT PARAMETERS
+ %r2 = address of destination (dst)
+ %r3 = address of source (src)
+ %r4 = max of bytes to copy. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ENTRY(strncpy)
+ .text
+ stg %r2,48(%r15) # save dst pointer
+ slgr %r2,%r3 # %r3 points to src, %r2+%r3 to dst
+ lghi %r1,7
+ ngr %r1,%r4 # last 3 bits of # bytes
+ srlg %r4,%r4,3
+ ltgr %r4,%r4 # less than 8 bytes to copy ?
+ jz .L1
+ bras %r5,.L0 # enter loop & load address of a 0
+ .long 0
+.L0: icmh %r0,8,0(%r3) # first byte
+ jz .L3
+ icmh %r0,4,1(%r3) # second byte
+ jz .L4
+ icmh %r0,2,2(%r3) # third byte
+ jz .L5
+ icmh %r0,1,3(%r3) # fourth byte
+ jz .L6
+ icm %r0,8,4(%r3) # fifth byte
+ jz .L7
+ icm %r0,4,5(%r3) # sixth byte
+ jz .L8
+ icm %r0,2,6(%r3) # seventh byte
+ jz .L9
+ icm %r0,1,7(%r3) # eigth byte
+ jz .L10
+ stg %r0,0(%r2,%r3) # store all eight to dest.
+ la %r3,8(%r3)
+ brct %r4,.L0
+.L1: ltgr %r1,%r1
+ jz .Lexit
+.L2: icm %r0,1,0(%r3)
+ stc %r0,0(%r2,%r3)
+ la %r3,1(%r3)
+ jz .L11
+ brct %r1,.L2
+ j .Lexit
+.L3: icmh %r0,4,0(%r5)
+.L4: icmh %r0,2,0(%r5)
+.L5: icmh %r0,1,0(%r5)
+.L6: icm %r0,8,0(%r5)
+.L7: icm %r0,4,0(%r5)
+.L8: icm %r0,2,0(%r5)
+.L9: icm %r0,1,0(%r5)
+.L10: stg %r0,0(%r2,%r3)
+ la %r3,8(%r3)
+ aghi %r4,-1
+ j .L12
+.L11: aghi %r1,-1
+.L12: sllg %r4,%r4,3
+ algr %r4,%r1
+ algr %r2,%r3 # start of dst area to be zeroed
+ lgr %r3,%r4
+ slgr %r4,%r4
+ slgr %r5,%r5
+.L13: mvcle %r2,%r4,0 # pad dst with zeroes
+ jo .L13
+.Lexit: lg %r2,48(%r15) # return dst pointer
+ br %r14
+END(strncpy)
+libc_hidden_builtin_def (strncpy)
diff --git a/libc/sysdeps/s390/s390-64/sub_n.S b/libc/sysdeps/s390/s390-64/sub_n.S
new file mode 100644
index 000000000..65d1c9f79
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/sub_n.S
@@ -0,0 +1,61 @@
+/* __mpn_sub_n -- Add two limb vectors of the same length > 0 and store
+ sum in a third limb vector. 64 bit S/390 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU MP Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* INPUT PARAMETERS
+ %r2 = res_ptr
+ %r3 = s1_ptr
+ %r4 = s2_ptr
+ %r5 = size. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+ENTRY(__mpn_sub_n)
+ stg %r6,48(%r15) # save register 6
+ cfi_offset (%r6,-112)
+ sgr %r1,%r1
+ lghi %r0,1 # cannot use ahi to add carry, use slr
+.L0: lg %r6,0(%r1,%r3) # .L0 -> no carry from last sub
+ slg %r6,0(%r1,%r4)
+ stg %r6,0(%r1,%r2)
+ la %r1,8(%r1)
+ brc 4,.L3
+.L1: brct %r5,.L0
+ slgr %r2,%r2 # no last carry to return
+ j .Lexit
+.L2: lg %r6,0(%r1,%r3) # .L2 -> carry from last sub
+ slg %r6,0(%r1,%r4)
+ brc 4,.L4
+ slgr %r6,%r0 # no carry yet, add carry from last sub
+ stg %r6,0(%r1,%r2)
+ la %r1,8(%r1)
+ brc 11,.L1 # new carry ?
+.L3: brct %r5,.L2
+ lgr %r2,%r0 # return last carry
+ j .Lexit
+.L4: slgr %r6,%r0 # already a carry, add carry from last sub
+ stg %r6,0(%r1,%r2)
+ la %r1,8(%r1)
+ brct %r5,.L2
+ lgr %r2,%r0 # return last carry
+.Lexit: lg %r6,48(%r15) # restore register 6
+ br %r14
+END(__mpn_sub_n)
diff --git a/libc/sysdeps/s390/s390-64/sysdep.h b/libc/sysdeps/s390/s390-64/sysdep.h
new file mode 100644
index 000000000..75fee7380
--- /dev/null
+++ b/libc/sysdeps/s390/s390-64/sysdep.h
@@ -0,0 +1,112 @@
+/* Assembler macros for 64 bit S/390.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+/* Syntactic details of assembler. */
+
+#ifdef HAVE_ELF
+
+/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */
+#define ALIGNARG(log2) 1<<log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
+
+/* In ELF C symbols are asm symbols. */
+#undef NO_UNDERSCORES
+#define NO_UNDERSCORES
+
+#else
+
+#define ALIGNARG(log2) log2
+#define ASM_TYPE_DIRECTIVE(name,type) /* Nothing is specified. */
+#define ASM_SIZE_DIRECTIVE(name) /* Nothing is specified. */
+
+#endif
+
+
+/* Define an entry point visible from C. */
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ cfi_startproc; \
+ CALL_MCOUNT
+
+#undef END
+#define END(name) \
+ cfi_endproc; \
+ ASM_SIZE_DIRECTIVE(name) \
+
+/* If compiled for profiling, call `mcount' at the start of each function. */
+#ifdef PROF
+#ifdef PIC
+#define CALL_MCOUNT \
+ lgr 0,14 ; larl 1,0f ; brasl 14,_mcount@PLT ; lgr 14,0 ; \
+ .data ; .align 4 ; 0: .long 0 ; .text ;
+#else
+#define CALL_MCOUNT \
+ lgr 0,14 ; larl 1,0f ; brasl 14,_mcount ; lgr 14,0 ; \
+ .data ; .align 4 ; 0: .long 0 ; .text ;
+#endif
+#else
+#define CALL_MCOUNT /* Do nothing. */
+#endif
+
+#ifdef NO_UNDERSCORES
+/* Since C identifiers are not normally prefixed with an underscore
+ on this system, the asm identifier `syscall_error' intrudes on the
+ C name space. Make sure we use an innocuous name. */
+#define syscall_error __syscall_error
+#define mcount _mcount
+#endif
+
+#define PSEUDO(name, syscall_name, args) \
+lose: SYSCALL_PIC_SETUP \
+ jg JUMPTARGET(syscall_error); \
+ .globl syscall_error; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ jm lose
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
+
+#undef JUMPTARGET
+#ifdef PIC
+#define JUMPTARGET(name) name##@PLT
+#define SYSCALL_PIC_SETUP \
+ larl %r12,_GLOBAL_OFFSET_TABLE_
+#else
+#define JUMPTARGET(name) name
+#define SYSCALL_PIC_SETUP /* Nothing. */
+#endif
+
+/* Local label name for asm code. */
+#ifndef L
+#define L(name) .L##name
+#endif
+
+#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/s390/stackinfo.h b/libc/sysdeps/s390/stackinfo.h
new file mode 100644
index 000000000..7e09c85b9
--- /dev/null
+++ b/libc/sysdeps/s390/stackinfo.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file contains a bit of information about the stack allocation
+ of the processor. */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H 1
+
+/* On s390 the stack grows down. */
+#define _STACK_GROWS_DOWN 1
+
+#endif /* stackinfo.h */
diff --git a/libc/sysdeps/sh/Implies b/libc/sysdeps/sh/Implies
new file mode 100644
index 000000000..780c4e246
--- /dev/null
+++ b/libc/sysdeps/sh/Implies
@@ -0,0 +1,3 @@
+wordsize-32
+ieee754/flt-32
+ieee754/dbl-64
diff --git a/libc/sysdeps/sh/Makefile b/libc/sysdeps/sh/Makefile
new file mode 100644
index 000000000..cf18dedc4
--- /dev/null
+++ b/libc/sysdeps/sh/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),gmon)
+sysdep_routines += _mcount
+endif
diff --git a/libc/sysdeps/sh/_mcount.S b/libc/sysdeps/sh/_mcount.S
new file mode 100644
index 000000000..069da13e9
--- /dev/null
+++ b/libc/sysdeps/sh/_mcount.S
@@ -0,0 +1,79 @@
+/* Machine-specific calling sequence for `mcount' profiling function. SuperH
+ Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+ Contributed by NIIBE Yutaka <gniibe@m17n.org>
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(_mcount)
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(_mcount),function)
+ cfi_startproc
+ .align 5
+C_LABEL(_mcount)
+ /* Save registers. */
+ mov.l r4,@-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (r4, 0)
+ mov.l r5,@-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (r5, 0)
+ mov.l r6,@-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (r6, 0)
+ mov.l r7,@-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (r7, 0)
+ sts.l pr,@-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (pr, 0)
+
+ mov.l @(20,r15),r4
+ sts pr,r5
+
+#ifdef SHARED
+ mov.l 0f,r1
+ mova 0f,r0
+ add r1,r0
+ mov.l 1f,r1
+ mov.l @(r0,r1),r1
+#else
+ mov.l 1f,r1
+#endif
+ jsr @r1
+ nop
+
+ /* Pop the saved registers. */
+ lds.l @r15+,pr
+ mov.l @r15+,r7
+ mov.l @r15+,r6
+ mov.l @r15+,r5
+ rts
+ mov.l @r15+,r4
+
+ .align 2
+#ifdef SHARED
+0: .long _GLOBAL_OFFSET_TABLE_
+1: .long C_SYMBOL_NAME(__mcount_internal)@GOT
+#else
+1: .long C_SYMBOL_NAME(__mcount_internal)
+#endif
+ cfi_endproc
+ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(_mcount))
+
+#undef mcount
+weak_alias (_mcount, mcount)
diff --git a/libc/sysdeps/sh/bits/endian.h b/libc/sysdeps/sh/bits/endian.h
new file mode 100644
index 000000000..1fef1ff93
--- /dev/null
+++ b/libc/sysdeps/sh/bits/endian.h
@@ -0,0 +1,13 @@
+/* SH is bi-endian but with a big-endian FPU. */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#define __FLOAT_WORD_ORDER __LITTLE_ENDIAN
+#else
+#define __BYTE_ORDER __BIG_ENDIAN
+#define __FLOAT_WORD_ORDER __BIG_ENDIAN
+#endif
diff --git a/libc/sysdeps/sh/bits/huge_val.h b/libc/sysdeps/sh/bits/huge_val.h
new file mode 100644
index 000000000..732b06503
--- /dev/null
+++ b/libc/sysdeps/sh/bits/huge_val.h
@@ -0,0 +1,56 @@
+/* `HUGE_VAL' constants for IEEE 754 machines (where it is infinity).
+ Used by <stdlib.h> and <math.h> functions for overflow.
+ SH version.
+ Copyright (C) 1992, 95, 96, 97, 98, 99, 2000, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/huge_val.h> directly; include <math.h> instead."
+#endif
+
+/* IEEE positive infinity (-HUGE_VAL is negative infinity). */
+
+#if __GNUC_PREREQ(3,3)
+# define HUGE_VAL (__builtin_huge_val())
+#elif __GNUC_PREREQ(2,96)
+# define HUGE_VAL (__extension__ 0x1.0p2047)
+#elif defined __GNUC__
+
+# define HUGE_VAL \
+ (__extension__ \
+ ((union { unsigned __l __attribute__((__mode__(__DI__))); double __d; }) \
+ { __l: 0x000000007ff00000ULL }).__d)
+
+#else /* not GCC */
+
+# include <endian.h>
+
+typedef union { unsigned char __c[8]; double __d; } __huge_val_t;
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define __HUGE_VAL_bytes { 0, 0, 0, 0, 0x7f, 0xf0, 0, 0 }
+# endif
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define __HUGE_VAL_bytes { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 }
+# endif
+
+static __huge_val_t __huge_val = { __HUGE_VAL_bytes };
+# define HUGE_VAL (__huge_val.__d)
+
+#endif /* GCC. */
diff --git a/libc/sysdeps/sh/bits/link.h b/libc/sysdeps/sh/bits/link.h
new file mode 100644
index 000000000..282667733
--- /dev/null
+++ b/libc/sysdeps/sh/bits/link.h
@@ -0,0 +1,70 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+
+/* Registers for entry into PLT on SH. */
+typedef struct La_sh_regs
+{
+ uint32_t lr_r2;
+ uint32_t lr_r3;
+ uint32_t lr_r4;
+ uint32_t lr_r5;
+ uint32_t lr_r6;
+ uint32_t lr_r7;
+ uint32_t lr_fpscr;
+ float lr_fr4;
+ float lr_fr5;
+ float lr_fr6;
+ float lr_fr7;
+ float lr_fr8;
+ float lr_fr9;
+ float lr_fr10;
+ float lr_fr11;
+} La_sh_regs;
+
+/* Return values for calls from PLT on SH. */
+typedef struct La_sh_retval
+{
+ uint32_t lrv_r0;
+ uint32_t lrv_r1;
+ float lrv_fr0;
+ float lrv_fr1;
+} La_sh_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf32_Addr la_sh_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_sh_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_sh_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_sh_regs *__inregs,
+ La_sh_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
diff --git a/libc/sysdeps/sh/bits/linkmap.h b/libc/sysdeps/sh/bits/linkmap.h
new file mode 100644
index 000000000..bb2fbb5f1
--- /dev/null
+++ b/libc/sysdeps/sh/bits/linkmap.h
@@ -0,0 +1,5 @@
+struct link_map_machine
+ {
+ Elf32_Addr plt; /* Address of .plt + 36 */
+ Elf32_Addr gotplt; /* Address of .got + 0x0c */
+ };
diff --git a/libc/sysdeps/sh/bits/setjmp.h b/libc/sysdeps/sh/bits/setjmp.h
new file mode 100644
index 000000000..7e3fbd339
--- /dev/null
+++ b/libc/sysdeps/sh/bits/setjmp.h
@@ -0,0 +1,47 @@
+/* Copyright (C) 1999,2000,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Define the machine-dependent type `jmp_buf'. SH version. */
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H 1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#ifndef _ASM
+typedef struct
+ {
+ /* Callee-saved registers r8 through r15. */
+ int __regs[8];
+
+ /* Program counter. */
+ void * __pc;
+
+ /* The global pointer. */
+ void * __gbr;
+
+ /* Floating point status register. */
+ int __fpscr;
+
+ /* Callee-saved floating point registers fr12 through fr15. */
+ int __fpregs[4];
+ } __jmp_buf[1];
+#endif
+
+#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/sh/bsd-_setjmp.S b/libc/sysdeps/sh/bsd-_setjmp.S
new file mode 100644
index 000000000..2811fcfd1
--- /dev/null
+++ b/libc/sysdeps/sh/bsd-_setjmp.S
@@ -0,0 +1,52 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. SH version.
+ Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#include <sysdep.h>
+
+ENTRY (_setjmp)
+#ifdef SHARED
+ mova 1f, r0
+ mov.l 1f, r1
+ bra 2f
+ add r1, r0
+ .align 2
+1:
+ .long _GLOBAL_OFFSET_TABLE_
+2:
+ mov.l 3f, r1
+ mov.l @(r0,r1), r1
+ jmp @r1
+ mov #0, r0
+ .align 2
+3:
+ .long C_SYMBOL_NAME(__sigsetjmp@GOT)
+#else
+ mov.l 1f, r1
+ jmp @r1
+ mov #0, r0
+ .align 2
+1:
+ .long C_SYMBOL_NAME(__sigsetjmp)
+#endif
+END (_setjmp)
+libc_hidden_def (_setjmp)
diff --git a/libc/sysdeps/sh/bsd-setjmp.S b/libc/sysdeps/sh/bsd-setjmp.S
new file mode 100644
index 000000000..e07628442
--- /dev/null
+++ b/libc/sysdeps/sh/bsd-setjmp.S
@@ -0,0 +1,51 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. SH version.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#include <sysdep.h>
+
+ENTRY (setjmp)
+#ifdef SHARED
+ mova 1f, r0
+ mov.l 1f, r1
+ bra 2f
+ add r1, r0
+ .align 2
+1:
+ .long _GLOBAL_OFFSET_TABLE_
+2:
+ mov.l 3f, r1
+ mov.l @(r0,r1), r1
+ jmp @r1
+ mov #1, r0
+ .align 2
+3:
+ .long C_SYMBOL_NAME(__sigsetjmp@GOT)
+#else
+ mov.l 1f, r1
+ jmp @r1
+ mov #1, r0
+ .align 2
+1:
+ .long C_SYMBOL_NAME(__sigsetjmp)
+#endif
+END (setjmp)
diff --git a/libc/sysdeps/sh/dl-machine.h b/libc/sysdeps/sh/dl-machine.h
new file mode 100644
index 000000000..e73c6d79c
--- /dev/null
+++ b/libc/sysdeps/sh/dl-machine.h
@@ -0,0 +1,474 @@
+/* Machine-dependent ELF dynamic relocation inline functions. SH version.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "SH"
+
+#include <sys/param.h>
+#include <sysdep.h>
+#include <assert.h>
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int __attribute__ ((unused))
+elf_machine_matches_host (const Elf32_Ehdr *ehdr)
+{
+ return ehdr->e_machine == EM_SH;
+}
+
+
+/* Return the link-time address of _DYNAMIC. Conveniently, this is the
+ first element of the GOT. This must be inlined in a function which
+ uses global data. */
+static inline Elf32_Addr __attribute__ ((unused))
+elf_machine_dynamic (void)
+{
+ register Elf32_Addr *got;
+ asm ("mov r12,%0" :"=r" (got));
+ return *got;
+}
+
+
+/* Return the run-time load address of the shared object. */
+static inline Elf32_Addr __attribute__ ((unused))
+elf_machine_load_address (void)
+{
+ Elf32_Addr addr;
+ asm ("mov.l 1f,r0\n\
+ mov.l 3f,r2\n\
+ add r12,r2\n\
+ mov.l @(r0,r12),r0\n\
+ bra 2f\n\
+ sub r0,r2\n\
+ .align 2\n\
+ 1: .long _dl_start@GOT\n\
+ 3: .long _dl_start@GOTOFF\n\
+ 2: mov r2,%0"
+ : "=r" (addr) : : "r0", "r1", "r2");
+ return addr;
+}
+
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int __attribute__ ((unused, always_inline))
+elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+{
+ Elf32_Addr *got;
+ extern void _dl_runtime_resolve (Elf32_Word);
+ extern void _dl_runtime_profile (Elf32_Word);
+
+ if (l->l_info[DT_JMPREL] && lazy)
+ {
+ /* The GOT entries for functions in the PLT have not yet been filled
+ in. Their initial contents will arrange when called to load an
+ offset into the .rela.plt section and _GLOBAL_OFFSET_TABLE_[1],
+ and then jump to _GLOBAL_OFFSET_TABLE[2]. */
+ got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
+ /* If a library is prelinked but we have to relocate anyway,
+ we have to be able to undo the prelinking of .got.plt.
+ The prelinker saved us here address of .plt + 36. */
+ if (got[1])
+ {
+ l->l_mach.plt = got[1] + l->l_addr;
+ l->l_mach.gotplt = (Elf32_Addr) &got[3];
+ }
+ got[1] = (Elf32_Addr) l; /* Identify this shared object. */
+
+ /* The got[2] entry contains the address of a function which gets
+ called to get the address of a so far unresolved function and
+ jump to it. The profiling extension of the dynamic linker allows
+ to intercept the calls to collect information. In this case we
+ don't store the address in the GOT so that all future calls also
+ end in this function. */
+ if (profile)
+ {
+ got[2] = (Elf32_Addr) &_dl_runtime_profile;
+ /* Say that we really want profiling and the timers are started. */
+ if (GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), l))
+ GL(dl_profile_map) = l;
+ }
+ else
+ /* This function will get called to fix up the GOT entry indicated by
+ the offset on the stack, and then jump to the resolved address. */
+ got[2] = (Elf32_Addr) &_dl_runtime_resolve;
+ }
+ return lazy;
+}
+
+#define ELF_MACHINE_RUNTIME_FIXUP_ARGS int plt_type
+
+/* Mask identifying addresses reserved for the user program,
+ where the dynamic linker should not map anything. */
+#define ELF_MACHINE_USER_ADDRESS_MASK 0x80000000UL
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+
+#define RTLD_START asm ("\
+.text\n\
+.globl _start\n\
+.globl _dl_start_user\n\
+_start:\n\
+ mov r15,r4\n\
+ mov.l .L_dl_start,r1\n\
+ mova .L_dl_start,r0\n\
+ add r1,r0\n\
+ jsr @r0\n\
+ nop\n\
+_dl_start_user:\n\
+ ! Save the user entry point address in r8.\n\
+ mov r0,r8\n\
+ ! Point r12 at the GOT.\n\
+ mov.l 1f,r12\n\
+ mova 1f,r0\n\
+ bra 2f\n\
+ add r0,r12\n\
+ .align 2\n\
+1: .long _GLOBAL_OFFSET_TABLE_\n\
+2: ! See if we were run as a command with the executable file\n\
+ ! name as an extra leading argument.\n\
+ mov.l .L_dl_skip_args,r0\n\
+ mov.l @(r0,r12),r0\n\
+ mov.l @r0,r0\n\
+ ! Get the original argument count.\n\
+ mov.l @r15,r5\n\
+ ! Subtract _dl_skip_args from it.\n\
+ sub r0,r5\n\
+ ! Adjust the stack pointer to skip _dl_skip_args words.\n\
+ shll2 r0\n\
+ add r0,r15\n\
+ ! Store back the modified argument count.\n\
+ mov.l r5,@r15\n\
+ ! Compute argv address and envp.\n\
+ mov r15,r6\n\
+ add #4,r6\n\
+ mov r5,r7\n\
+ shll2 r7\n\
+ add r15,r7\n\
+ add #8,r7\n\
+ mov.l .L_dl_loaded,r0\n\
+ mov.l @(r0,r12),r0\n\
+ mov.l @r0,r4\n\
+ ! Call _dl_init.\n\
+ mov.l .L_dl_init,r1\n\
+ mova .L_dl_init,r0\n\
+ add r1,r0\n\
+ jsr @r0\n\
+ nop\n\
+1: ! Pass our finalizer function to the user in r4, as per ELF ABI.\n\
+ mov.l .L_dl_fini,r0\n\
+ mov.l @(r0,r12),r4\n\
+ ! Jump to the user's entry point.\n\
+ jmp @r8\n\
+ nop\n\
+ .align 2\n\
+.L_dl_start:\n\
+ .long _dl_start@PLT\n\
+.L_dl_skip_args:\n\
+ .long _dl_skip_args@GOT\n\
+.L_dl_init:\n\
+ .long _dl_init_internal@PLT\n\
+.L_dl_loaded:\n\
+ .long _rtld_local@GOT\n\
+.L_dl_fini:\n\
+ .long _dl_fini@GOT\n\
+ .type __fpscr_values,@object\n\
+ .global __fpscr_values\n\
+__fpscr_values:\n\
+ .long 0\n\
+ .long 0x80000\n\
+ .weak __fpscr_values\n\
+.previous\n\
+");
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+# define elf_machine_type_class(type) \
+ ((((type) == R_SH_JMP_SLOT || (type) == R_SH_TLS_DTPMOD32 \
+ || (type) == R_SH_TLS_DTPOFF32 || (type) == R_SH_TLS_TPOFF32) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_SH_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+#define elf_machine_type_class(type) \
+ ((((type) == R_SH_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_SH_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_SH_JMP_SLOT
+
+/* We define an initialization functions. This is called very early in
+ _dl_sysdep_start. */
+#define DL_PLATFORM_INIT dl_platform_init ()
+
+static inline void __attribute__ ((unused))
+dl_platform_init (void)
+{
+ if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
+ /* Avoid an empty string which would disturb us. */
+ GLRO(dl_platform) = NULL;
+}
+
+static inline Elf32_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+ return *reloc_addr = value;
+}
+
+/* Return the final value of a plt relocation. */
+static inline Elf32_Addr
+elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+ Elf32_Addr value)
+{
+ return value + reloc->r_addend;
+}
+
+#define ARCH_LA_PLTENTER sh_gnu_pltenter
+#define ARCH_LA_PLTEXIT sh_gnu_pltexit
+
+#endif /* !dl_machine_h */
+
+/* SH never uses Elf32_Rel relocations. */
+#define ELF_MACHINE_NO_REL 1
+
+#ifdef RESOLVE_MAP
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ MAP is the object containing the reloc. */
+
+auto inline void
+__attribute ((always_inline))
+elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
+ const Elf32_Sym *sym, const struct r_found_version *version,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+ Elf32_Addr value;
+
+#define COPY_UNALIGNED_WORD(swp, twp, align) \
+ { \
+ void *__s = (swp), *__t = (twp); \
+ unsigned char *__s1 = __s, *__t1 = __t; \
+ unsigned short *__s2 = __s, *__t2 = __t; \
+ unsigned long *__s4 = __s, *__t4 = __t; \
+ switch ((align)) \
+ { \
+ case 0: \
+ *__t4 = *__s4; \
+ break; \
+ case 2: \
+ *__t2++ = *__s2++; \
+ *__t2 = *__s2; \
+ break; \
+ default: \
+ *__t1++ = *__s1++; \
+ *__t1++ = *__s1++; \
+ *__t1++ = *__s1++; \
+ *__t1 = *__s1; \
+ break; \
+ } \
+ }
+
+ if (__builtin_expect (r_type == R_SH_RELATIVE, 0))
+ {
+#ifndef RTLD_BOOTSTRAP
+ if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
+#endif
+ {
+ if (reloc->r_addend)
+ value = map->l_addr + reloc->r_addend;
+ else
+ {
+ COPY_UNALIGNED_WORD (reloc_addr_arg, &value,
+ (int) reloc_addr_arg & 3);
+ value += map->l_addr;
+ }
+ COPY_UNALIGNED_WORD (&value, reloc_addr_arg,
+ (int) reloc_addr_arg & 3);
+ }
+ }
+#ifndef RTLD_BOOTSTRAP
+ else if (__builtin_expect (r_type == R_SH_NONE, 0))
+ return;
+#endif
+ else
+ {
+ const Elf32_Sym *const refsym = sym;
+ struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+
+ value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+ value += reloc->r_addend;
+
+ switch (r_type)
+ {
+ case R_SH_COPY:
+ if (sym == NULL)
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
+ if (sym->st_size > refsym->st_size
+ || (sym->st_size < refsym->st_size && GLRO(dl_verbose)))
+ {
+ const char *strtab;
+
+ strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
+ _dl_error_printf ("\
+%s: Symbol `%s' has different size in shared object, consider re-linking\n",
+ rtld_progname ?: "<program name unknown>",
+ strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr_arg, (void *) value,
+ MIN (sym->st_size, refsym->st_size));
+ break;
+ case R_SH_GLOB_DAT:
+ case R_SH_JMP_SLOT:
+ /* These addresses are always aligned. */
+ *reloc_addr = value;
+ break;
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+ /* XXX Remove TLS relocations which are not needed. */
+ case R_SH_TLS_DTPMOD32:
+# ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always the module
+ with index 1.
+ XXX If this relocation is necessary move before RESOLVE
+ call. */
+ *reloc_addr = 1;
+# else
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+# endif
+ break;
+ case R_SH_TLS_DTPOFF32:
+# ifndef RTLD_BOOTSTRAP
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ if (sym != NULL)
+ *reloc_addr = sym->st_value;
+# endif
+ break;
+ case R_SH_TLS_TPOFF32:
+ /* The offset is positive, afterward from the thread pointer. */
+# ifdef RTLD_BOOTSTRAP
+ *reloc_addr = map->l_tls_offset + sym->st_value + reloc->r_addend;
+# else
+ /* We know the offset of object the symbol is contained in.
+ It is a positive value which will be added to the thread
+ pointer. To get the variable position in the TLS block
+ we add the offset from that of the TLS block. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = sym_map->l_tls_offset + sym->st_value
+ + reloc->r_addend;
+ }
+# endif
+ break;
+#endif /* use TLS */
+ case R_SH_DIR32:
+ {
+#ifndef RTLD_BOOTSTRAP
+ /* This is defined in rtld.c, but nowhere in the static
+ libc.a; make the reference weak so static programs can
+ still link. This declaration cannot be done when
+ compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP) because
+ rtld.c contains the common defn for _dl_rtld_map, which
+ is incompatible with a weak decl in the same file. */
+# ifndef SHARED
+ weak_extern (_dl_rtld_map);
+# endif
+ if (map == &GL(dl_rtld_map))
+ /* Undo the relocation done here during bootstrapping.
+ Now we will relocate it anew, possibly using a
+ binding found in the user program or a loaded library
+ rather than the dynamic linker's built-in definitions
+ used while loading those libraries. */
+ value -= map->l_addr + refsym->st_value + reloc->r_addend;
+#endif
+ COPY_UNALIGNED_WORD (&value, reloc_addr_arg,
+ (int) reloc_addr_arg & 3);
+ break;
+ }
+ case R_SH_REL32:
+ value = (value - (Elf32_Addr) reloc_addr);
+ COPY_UNALIGNED_WORD (&value, reloc_addr_arg,
+ (int) reloc_addr_arg & 3);
+ break;
+ default:
+ _dl_reloc_bad_type (map, r_type, 0);
+ break;
+ }
+ }
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr value;
+
+ if (reloc->r_addend)
+ value = l_addr + reloc->r_addend;
+ else
+ {
+ COPY_UNALIGNED_WORD (reloc_addr_arg, &value, (int) reloc_addr_arg & 3);
+ value += l_addr;
+ }
+ COPY_UNALIGNED_WORD (&value, reloc_addr_arg, (int) reloc_addr_arg & 3);
+
+#undef COPY_UNALIGNED_WORD
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf32_Addr l_addr, const Elf32_Rela *reloc)
+{
+ Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
+ /* Check for unexpected PLT reloc type. */
+ if (ELF32_R_TYPE (reloc->r_info) == R_SH_JMP_SLOT)
+ {
+ if (__builtin_expect (map->l_mach.plt, 0) == 0)
+ *reloc_addr += l_addr;
+ else
+ *reloc_addr =
+ map->l_mach.plt
+ + (((Elf32_Addr) reloc_addr) - map->l_mach.gotplt) * 7;
+ }
+ else
+ _dl_reloc_bad_type (map, ELF32_R_TYPE (reloc->r_info), 1);
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/libc/sysdeps/sh/dl-tls.h b/libc/sysdeps/sh/dl-tls.h
new file mode 100644
index 000000000..98e2f1904
--- /dev/null
+++ b/libc/sysdeps/sh/dl-tls.h
@@ -0,0 +1,29 @@
+/* Thread-local storage handling in the ELF dynamic linker. SH version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* Type used for the representation of TLS information in the GOT. */
+typedef struct
+{
+ unsigned long int ti_module;
+ unsigned long int ti_offset;
+} tls_index;
+
+
+extern void *__tls_get_addr (tls_index *ti);
diff --git a/libc/sysdeps/sh/dl-trampoline.S b/libc/sysdeps/sh/dl-trampoline.S
new file mode 100644
index 000000000..79493d50b
--- /dev/null
+++ b/libc/sysdeps/sh/dl-trampoline.S
@@ -0,0 +1,431 @@
+/* PLT trampolines. SH version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ .globl _dl_runtime_resolve
+ .type _dl_runtime_resolve, @function
+ cfi_startproc
+ .align 5
+_dl_runtime_resolve:
+ mov.l r2,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov.l r3,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov.l r4,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov.l r5,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov.l r6,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov.l r7,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov.l r12,@-r15
+ cfi_adjust_cfa_offset (4)
+ sts.l macl,@-r15
+ cfi_adjust_cfa_offset (4)
+ sts.l mach,@-r15
+ cfi_adjust_cfa_offset (4)
+ movt r3 ! Save T flag.
+ mov.l r3,@-r15
+ cfi_adjust_cfa_offset (4)
+#ifdef HAVE_FPU
+ sts.l fpscr,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov #8,r3
+ swap.w r3,r3
+ lds r3,fpscr
+ fmov.s fr11,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr10,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr9,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr8,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr7,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr6,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr5,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr4,@-r15
+ cfi_adjust_cfa_offset (4)
+#endif
+ sts.l pr,@-r15
+ cfi_adjust_cfa_offset (4)
+ tst r0,r0
+ bt 1f
+ mov r0,r2
+1:
+ mov r0,r4 ! PLT type
+ mov r2,r5 ! link map address
+#ifdef SHARED
+ mov.l 2f,r2
+ mova 2f,r0
+ add r0,r2 ! Get GOT address in r2
+ mov.l 3f,r0
+ add r2,r0
+#else
+ mov.l 3f,r0
+#endif
+ jsr @r0 ! Call resolver.
+ mov r1,r6 ! reloc offset
+ lds.l @r15+,pr ! Get register content back.
+ cfi_adjust_cfa_offset (-4)
+#ifdef HAVE_FPU
+ fmov.s @r15+,fr4
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr5
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr6
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr7
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr8
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr9
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr10
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr11
+ cfi_adjust_cfa_offset (-4)
+ lds.l @r15+,fpscr
+ cfi_adjust_cfa_offset (-4)
+#endif
+ mov.l @r15+,r3
+ cfi_adjust_cfa_offset (-4)
+ shal r3 ! Lode T flag.
+ lds.l @r15+,mach
+ cfi_adjust_cfa_offset (-4)
+ lds.l @r15+,macl
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r12
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r7
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r6
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r5
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r4
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r3
+ cfi_adjust_cfa_offset (-4)
+ jmp @r0 ! Jump to function address.
+ mov.l @r15+,r2
+ cfi_adjust_cfa_offset (-4)
+ .align 2
+#ifdef SHARED
+2: .long _GLOBAL_OFFSET_TABLE_
+3: .long _dl_fixup@GOTOFF
+#else
+3: .long _dl_fixup
+#endif
+ cfi_endproc
+ .size _dl_runtime_resolve, .-_dl_runtime_resolve
+
+
+ .globl _dl_runtime_profile
+ .type _dl_runtime_profile,@function
+ cfi_startproc
+ .align 5
+_dl_runtime_profile:
+ mov.l r12,@-r15
+ cfi_adjust_cfa_offset (4)
+#ifdef HAVE_FPU
+ sts.l fpscr,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov #8,r12
+ swap.w r12,r12
+ lds r12,fpscr
+ fmov.s fr11,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr10,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr9,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr8,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr7,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr6,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr5,@-r15
+ cfi_adjust_cfa_offset (4)
+ fmov.s fr4,@-r15
+ cfi_adjust_cfa_offset (4)
+#else
+ add #-36,r15
+ cfi_adjust_cfa_offset (36)
+#endif
+ mov.l r7,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov.l r6,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov.l r5,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov.l r4,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov.l r3,@-r15
+ cfi_adjust_cfa_offset (4)
+ mov.l r2,@-r15
+ cfi_adjust_cfa_offset (4)
+ sts.l macl,@-r15
+ cfi_adjust_cfa_offset (4)
+ sts.l mach,@-r15
+ cfi_adjust_cfa_offset (4)
+ movt r3 ! Save T flag.
+ mov.l r3,@-r15
+ cfi_adjust_cfa_offset (4)
+ sts.l pr,@-r15
+ cfi_adjust_cfa_offset (4)
+ tst r0,r0
+ bt 1f
+ mov r0,r2
+1:
+ mov r0,r4 ! PLT type
+ mov r2,r5 ! link map address
+ sts pr,r7 ! return address
+ add #-24,r15
+ cfi_adjust_cfa_offset (24)
+ mov #40,r0
+ add r15,r0
+ mov.l r0,@r15 ! Address of the register structure
+ mov #-1,r0
+ mov.l r0,@(8,r15)
+ mov #8,r0
+ add r15,r0
+ mov.l r0,@(4,r15)
+ mov.l r5,@(12,r15)
+ mov.l r1,@(16,r15)
+#ifdef SHARED
+ mov.l 2f,r12
+ mova 2f,r0
+ add r0,r12 ! Get GOT address in r12
+ mov.l 3f,r0
+ add r12,r0
+#else
+ mov.l 3f,r0
+#endif
+ jsr @r0 ! Call resolver.
+ mov r1,r6 ! reloc offset
+ mov.l @(8,r15),r1
+ cmp/pz r1
+ bt 4f
+ add #24,r15
+ cfi_adjust_cfa_offset (-24)
+ lds.l @r15+,pr ! Get register content back.
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r3
+ cfi_adjust_cfa_offset (-4)
+ shal r3 ! Lode T flag.
+ lds.l @r15+,mach
+ cfi_adjust_cfa_offset (-4)
+ lds.l @r15+,macl
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r2
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r3
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r4
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r5
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r6
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r7
+ cfi_adjust_cfa_offset (-4)
+#ifdef HAVE_FPU
+ fmov.s @r15+,fr4
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr5
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr6
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr7
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr8
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr9
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr10
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr11
+ cfi_adjust_cfa_offset (-4)
+ lds.l @r15+,fpscr
+ cfi_adjust_cfa_offset (-4)
+#else
+ add #36,r15
+ cfi_adjust_cfa_offset (-36)
+#endif
+ jmp @r0 ! Jump to function address.
+ mov.l @r15+,r12
+ cfi_adjust_cfa_offset (-4)
+ .align 2
+#ifdef SHARED
+2: .long _GLOBAL_OFFSET_TABLE_
+3: .long _dl_profile_fixup@GOTOFF
+#else
+3: .long _dl_profile_fixup
+#endif
+
+ cfi_adjust_cfa_offset (104)
+4:
+ mov #104,r3
+ add r15,r3 ! Original stack
+ mov.l r8,@(20,r15)
+ cfi_rel_offset (r8, 20)
+ mov r15,r8
+ sub r1,r15
+ shlr2 r15
+ shll2 r15
+ mov r15,r4
+ shlr2 r1
+ tst r1,r1
+5:
+ bt/s 6f
+ dt r1
+ mov.l @r3+,r2
+ mov.l r2,@r4
+ bra 5b
+ add #4,r4
+6:
+ mov.l @r8,r12
+ mov.l @r12+,r2
+ mov.l @r12+,r3
+ mov.l @r12+,r4
+ mov.l @r12+,r5
+ mov.l @r12+,r6
+ mov.l @r12+,r7
+#ifdef HAVE_FPU
+ fmov.s @r12+,fr4
+ fmov.s @r12+,fr5
+ fmov.s @r12+,fr6
+ fmov.s @r12+,fr7
+ fmov.s @r12+,fr8
+ fmov.s @r12+,fr9
+ fmov.s @r12+,fr10
+ fmov.s @r12+,fr11
+ lds.l @r12+,fpscr
+#else
+ add #36,r2
+#endif
+ jsr @r0 ! Call function.
+ nop
+ mov r8,r15
+ mov.l @(12,r15),r4 ! link map address
+ mov.l @(16,r15),r5 ! reloc offset
+ mov.l @r15,r6 ! input registers
+#ifdef HAVE_FPU
+ mov #16,r8
+ add r15,r8
+ fmov.s fr1,@-r8
+ fmov.s fr0,@-r8
+#else
+ mov #8,r8
+ add r15,r8
+#endif
+ mov.l r1,@-r8
+ mov.l r0,@-r8
+ mov.l @(20,r15),r8
+ cfi_restore (r8)
+#ifdef SHARED
+ mov.l 7f,r12
+ mova 7f,r0
+ add r0,r12 ! Get GOT address in r12
+ mov.l 8f,r0
+ add r12,r0
+#else
+ mov.l 8f,r0
+#endif
+ jsr @r0
+ mov r15,r7 ! output registers
+ mov.l @r15+,r0
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r1
+ cfi_adjust_cfa_offset (-4)
+#ifdef HAVE_FPU
+ fmov.s @r15+,fr0
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr1
+ cfi_adjust_cfa_offset (-4)
+ add #8,r15
+ cfi_adjust_cfa_offset (-8)
+#else
+ add #16,r15
+ cfi_adjust_cfa_offset (-16)
+#endif
+ lds.l @r15+,pr ! Get register content back.
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r3
+ cfi_adjust_cfa_offset (-4)
+ shal r3 ! Lode T flag.
+ lds.l @r15+,mach
+ cfi_adjust_cfa_offset (-4)
+ lds.l @r15+,macl
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r2
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r3
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r4
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r5
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r6
+ cfi_adjust_cfa_offset (-4)
+ mov.l @r15+,r7
+ cfi_adjust_cfa_offset (-4)
+#ifdef HAVE_FPU
+ fmov.s @r15+,fr4
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr5
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr6
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr7
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr8
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr9
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr10
+ cfi_adjust_cfa_offset (-4)
+ fmov.s @r15+,fr11
+ cfi_adjust_cfa_offset (-4)
+ lds.l @r15+,fpscr
+ cfi_adjust_cfa_offset (-4)
+#else
+ add #36,r15
+ cfi_adjust_cfa_offset (-36)
+#endif
+ rts ! Jump to function address.
+ mov.l @r15+,r12
+ cfi_adjust_cfa_offset (-4)
+ cfi_endproc
+ .align 2
+#ifdef SHARED
+7: .long _GLOBAL_OFFSET_TABLE_
+8: .long _dl_call_pltexit@GOTOFF
+#else
+8: .long _dl_call_pltexit
+#endif
+ .size _dl_runtime_profile, .-_dl_runtime_profile
diff --git a/libc/sysdeps/sh/elf/configure b/libc/sysdeps/sh/elf/configure
new file mode 100644
index 000000000..d38b0ece5
--- /dev/null
+++ b/libc/sysdeps/sh/elf/configure
@@ -0,0 +1,47 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/sh/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+echo "$as_me:$LINENO: checking for SH TLS support" >&5
+echo $ECHO_N "checking for SH TLS support... $ECHO_C" >&6
+if test "${libc_cv_sh_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.S <<\EOF
+ .section ".tdata", "awT", @progbits
+foo: .long 25
+ .text
+ .long foo@TLSGD
+ .long foo@TLSLDM
+ .long foo@DTPOFF
+ .long foo@GOTTPOFF
+ .long foo@TPOFF
+EOF
+if { ac_try='${CC-cc} -S $CFLAGS conftest.S 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_sh_tls=yes
+else
+ libc_cv_sh_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_sh_tls" >&5
+echo "${ECHO_T}$libc_cv_sh_tls" >&6
+if test $libc_cv_sh_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+cat >>confdefs.h <<\_ACEOF
+#define PI_STATIC_AND_HIDDEN 1
+_ACEOF
+
diff --git a/libc/sysdeps/sh/elf/configure.in b/libc/sysdeps/sh/elf/configure.in
new file mode 100644
index 000000000..42aca3f8e
--- /dev/null
+++ b/libc/sysdeps/sh/elf/configure.in
@@ -0,0 +1,32 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/sh/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for SH TLS support, libc_cv_sh_tls, [dnl
+cat > conftest.S <<\EOF
+ .section ".tdata", "awT", @progbits
+foo: .long 25
+ .text
+ .long foo@TLSGD
+ .long foo@TLSLDM
+ .long foo@DTPOFF
+ .long foo@GOTTPOFF
+ .long foo@TPOFF
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.S 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_sh_tls=yes
+else
+ libc_cv_sh_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_sh_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
+dnl It is always possible to access static and hidden symbols in an
+dnl position independent way.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
diff --git a/libc/sysdeps/sh/elf/initfini.c b/libc/sysdeps/sh/elf/initfini.c
new file mode 100644
index 000000000..6c8ed8529
--- /dev/null
+++ b/libc/sysdeps/sh/elf/initfini.c
@@ -0,0 +1,159 @@
+/* Special .init and .fini section support for SH.
+ Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file is compiled into assembly code which is then munged by a sed
+ script into two files: crti.s and crtn.s.
+
+ * crti.s puts a function prologue at the beginning of the
+ .init and .fini sections and defines global symbols for
+ those addresses, so they can be called as functions.
+
+ * crtn.s puts the corresponding function epilogues
+ in the .init and .fini sections. */
+
+__asm__ ("\
+\n\
+#include \"defs.h\"\n\
+#define SHARED\n\
+\n\
+/*@HEADER_ENDS*/\n\
+\n\
+/*@TESTS_BEGIN*/\n\
+\n\
+/*@TESTS_END*/\n\
+\n\
+/*@_init_PROLOG_BEGINS*/\n\
+ .section .init\n\
+ .align 5\n\
+ .global _init\n\
+ .type _init,@function\n\
+_init:\n\
+ mov.l r12,@-r15\n\
+ mov.l r14,@-r15\n\
+ sts.l pr,@-r15\n\
+#ifdef SHARED\n\
+ mova .L22,r0\n\
+ mov.l .L22,r12\n\
+ add r0,r12\n\
+ mova .L23,r0\n\
+ mov.l .L23,r1\n\
+ add r0,r1\n\
+#else\n\
+ mov.l .L23,r1\n\
+#endif\n\
+ jsr @r1\n\
+ mov r15,r14\n\
+ bra 1f\n\
+ nop\n\
+ .align 2\n\
+#ifdef SHARED\n\
+.L22:\n\
+ .long _GLOBAL_OFFSET_TABLE_\n\
+.L23:\n\
+ .long __gmon_start__@PLT\n\
+#else\n\
+.L23:\n\
+ .long __gmon_start__\n\
+#endif\n\
+1:\n\
+ ALIGN\n\
+ END_INIT\n\
+\n\
+ \n\
+/*@_init_PROLOG_ENDS*/\n\
+\n\
+/*@_init_EPILOG_BEGINS*/\n\
+ .section .init\n\
+ mov r14,r15\n\
+ lds.l @r15+,pr\n\
+ mov.l @r15+,r14\n\
+ rts \n\
+ mov.l @r15+,r12\n\
+ END_INIT\n\
+ .section .text\n\
+ .align 5\n\
+ .weak __gmon_start__\n\
+ .type __gmon_start__,@function\n\
+__gmon_start__:\n\
+ mov.l r14,@-r15\n\
+ mov r15,r14\n\
+ mov r14,r15\n\
+ rts \n\
+ mov.l @r15+,r14\n\
+ \n\
+/*@_init_EPILOG_ENDS*/\n\
+\n\
+/*@_fini_PROLOG_BEGINS*/\n\
+ .section .fini\n\
+ .align 5\n\
+ .global _fini\n\
+ .type _fini,@function\n\
+_fini:\n\
+ mov.l r12,@-r15\n\
+ mov.l r14,@-r15\n\
+ sts.l pr,@-r15\n\
+#ifdef SHARED\n\
+ mova .L27,r0\n\
+ mov.l .L27,r12\n\
+ add r0,r12\n\
+#endif\n\
+ mov r15,r14\n\
+ ALIGN\n\
+ END_FINI\n\
+#ifdef SHARED\n\
+ bra 1f\n\
+ nop\n\
+ .align 2\n\
+.L27:\n\
+ .long _GLOBAL_OFFSET_TABLE_\n\
+#endif\n\
+1:\n\
+/*@_fini_PROLOG_ENDS*/\n\
+\n\
+/*@_fini_EPILOG_BEGINS*/\n\
+ .section .fini\n\
+ mov r14,r15\n\
+ lds.l @r15+,pr\n\
+ mov.l @r15+,r14\n\
+ rts \n\
+ mov.l @r15+,r12\n\
+\n\
+ END_FINI\n\
+ \n\
+/*@_fini_EPILOG_ENDS*/\n\
+\n\
+/*@TRAILER_BEGINS*/\
+");
diff --git a/libc/sysdeps/sh/elf/start.S b/libc/sysdeps/sh/elf/start.S
new file mode 100644
index 000000000..0da0861f6
--- /dev/null
+++ b/libc/sysdeps/sh/elf/start.S
@@ -0,0 +1,112 @@
+/* Startup code for SH & ELF.
+ Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This is the canonical entry point, usually the first thing in the text
+ segment.
+
+ Note that the code in the .init section has already been run.
+ This includes _init and _libc_init
+
+
+ At this entry point, most registers' values are unspecified, except:
+
+ r4 Contains a function pointer to be registered with `atexit'.
+ This is how the dynamic linker arranges to have DT_FINI
+ functions called for shared libraries that have been loaded
+ before this code runs.
+
+ sp The stack contains the arguments and environment:
+ 0(sp) argc
+ 4(sp) argv[0]
+ ...
+ (4*argc)(sp) NULL
+ (4*(argc+1))(sp) envp[0]
+ ...
+ NULL
+*/
+
+ .text
+ .globl _start
+ .type _start,@function
+_start:
+ /* Clear the frame pointer since this is the outermost frame. */
+ mov #0, r14
+
+ /* Pop argc off the stack and save a pointer to argv */
+ mov.l @r15+,r5
+ mov r15, r6
+
+ /* Push the last arguments to main() onto the stack */
+ mov.l r4,@-r15
+ mov.l L_fini,r0
+ mov.l r0,@-r15
+
+ /* Set up the other arguments for main() that go in registers */
+ mov.l L_main,r4
+ mov.l L_init,r7
+
+ /* __libc_start_main (main, argc, argv, init, fini, rtld_fini) */
+
+ /* Let the libc call main and exit with its return code. */
+ mov.l L_libc_start_main,r1
+ jsr @r1
+ nop
+ /* should never get here....*/
+ mov.l L_abort,r1
+ jsr @r1
+ nop
+ .align 2
+L_main:
+ .long main
+L_init:
+ .long __libc_csu_init
+L_fini:
+ .long __libc_csu_fini
+L_libc_start_main:
+ .long __libc_start_main
+L_abort:
+ .long abort
+/* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+ .long 0
+ .weak data_start
+ data_start = __data_start
+ .global __fpscr_values
+__fpscr_values:
+ .long 0
+ .long 0x80000
diff --git a/libc/sysdeps/sh/gccframe.h b/libc/sysdeps/sh/gccframe.h
new file mode 100644
index 000000000..ad392741c
--- /dev/null
+++ b/libc/sysdeps/sh/gccframe.h
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. sh version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define DWARF_FRAME_REGISTERS 49
+
+#include <sysdeps/generic/gccframe.h>
diff --git a/libc/sysdeps/sh/gmp-mparam.h b/libc/sysdeps/sh/gmp-mparam.h
new file mode 100644
index 000000000..edd7e3dbf
--- /dev/null
+++ b/libc/sysdeps/sh/gmp-mparam.h
@@ -0,0 +1,30 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright (C) 1991, 1993, 1994, 1995, 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at your
+option) any later version.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#define BITS_PER_MP_LIMB 32
+#define BYTES_PER_MP_LIMB 4
+#define BITS_PER_LONGINT 32
+#define BITS_PER_INT 32
+#define BITS_PER_SHORTINT 16
+#define BITS_PER_CHAR 8
+
+#define IEEE_DOUBLE_BIG_ENDIAN 0
+#define IEEE_DOUBLE_MIXED_ENDIAN 1
diff --git a/libc/sysdeps/sh/init-first.c b/libc/sysdeps/sh/init-first.c
new file mode 100644
index 000000000..d816625ef
--- /dev/null
+++ b/libc/sysdeps/sh/init-first.c
@@ -0,0 +1,73 @@
+/* Initialization code run first thing by the ELF startup code. For SH.
+ Copyright (C) 1995-1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+
+extern void __libc_init (int, char **, char **);
+#ifdef USE_NONOPTION_FLAGS
+extern void __getopt_clean_environment (char **);
+#endif
+extern void __libc_global_ctors (void);
+
+int __libc_multiple_libcs attribute_hidden = 1;
+
+static void
+init (int *data)
+{
+ int argc = *data;
+ char **argv = (void *) (data + 1);
+ char **envp = &argv[argc + 1];
+
+ __environ = envp;
+ __libc_init (argc, argv, envp);
+
+#ifdef USE_NONOPTION_FLAGS
+ /* This is a hack to make the special getopt in GNU libc working. */
+ __getopt_clean_environment (envp);
+#endif
+}
+
+#ifdef SHARED
+/* This function is called to initialize the shared C library.
+ It is called just before the user _start code from sh/sh[34]/elf/start.S,
+ with the stack set up as that code gets it. */
+
+/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
+ pointer in the dynamic section based solely on that. It is convention
+ for this function to be in the `.init' section, but the symbol name is
+ the only thing that really matters!! */
+/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/
+
+void
+_init (int argc, ...)
+{
+ init (&argc);
+
+ __libc_global_ctors ();
+}
+#endif
+
+
+void
+__libc_init_first (int argc __attribute__ ((unused)), ...)
+{
+#ifndef SHARED
+ init (&argc);
+#endif
+}
diff --git a/libc/sysdeps/sh/jmpbuf-offsets.h b/libc/sysdeps/sh/jmpbuf-offsets.h
new file mode 100644
index 000000000..312051e7e
--- /dev/null
+++ b/libc/sysdeps/sh/jmpbuf-offsets.h
@@ -0,0 +1,20 @@
+/* Private macros for accessing __jmp_buf contents. SH version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define JB_SIZE (4 * 15)
diff --git a/libc/sysdeps/sh/jmpbuf-unwind.h b/libc/sysdeps/sh/jmpbuf-unwind.h
new file mode 100644
index 000000000..a69a465ef
--- /dev/null
+++ b/libc/sysdeps/sh/jmpbuf-unwind.h
@@ -0,0 +1,47 @@
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+#include <sysdep.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame
+ containing a local variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \
+ ((void *) (address) < (void *) demangle ((jmpbuf)[0].__regs[7]))
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+static inline uintptr_t __attribute__ ((unused))
+_jmpbuf_sp (__jmp_buf regs)
+{
+ uintptr_t sp = regs[0].__regs[7];
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (sp);
+#endif
+ return sp;
+}
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
+
+/* We use the normal longjmp for unwinding. */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libc/sysdeps/sh/machine-gmon.h b/libc/sysdeps/sh/machine-gmon.h
new file mode 100644
index 000000000..46c7b191a
--- /dev/null
+++ b/libc/sysdeps/sh/machine-gmon.h
@@ -0,0 +1,32 @@
+/* Machine-dependent definitions for profiling support. SH version.
+ Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* We must not pollute the global namespace. */
+#define mcount_internal __mcount_internal
+
+void mcount_internal (u_long frompc, u_long selfpc);
+
+#define _MCOUNT_DECL(frompc, selfpc) \
+void mcount_internal (u_long frompc, u_long selfpc)
+
+
+/* Define MCOUNT as empty since we have the implementation in another
+ file. */
+#define MCOUNT
+
diff --git a/libc/sysdeps/sh/memcpy.S b/libc/sysdeps/sh/memcpy.S
new file mode 100644
index 000000000..b084cc93c
--- /dev/null
+++ b/libc/sysdeps/sh/memcpy.S
@@ -0,0 +1,200 @@
+/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
+ Optimized by Toshiyasu Morita <toshiyasu.morita@hsa.hitachi.com>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <endian.h>
+
+/* void *memcpy(void *dst, const void *src, size_t n);
+ No overlap between the memory of DST and of SRC are assumed. */
+
+ENTRY(memcpy)
+ mov r4,r3 /* Save destination. */
+
+ /* If less than 11 bytes, just do a byte copy. */
+ mov #11,r0
+ cmp/gt r6,r0
+ bt L_byteloop_init
+
+ /* Check if we need to word-align source. */
+ mov r5,r0
+ tst #1,r0
+ bt L_wordalign
+
+ mov.b @r0+,r1 /* Copy one byte. */
+ add #-1,r6
+ mov.b r1,@r4
+ add #1,r4
+
+ .balignw 4,0x0009
+L_wordalign:
+ /* Check if we need to longword-align source. */
+ tst #2,r0
+ bt L_copy
+
+ mov.w @r0+,r1 /* Copy one word. */
+ add #-2,r6
+#if __BYTE_ORDER == __BIG_ENDIAN
+ add #1,r4
+ mov.b r1,@r4
+ shlr8 r1
+ mov.b r1,@-r4
+ add #2,r4
+#else
+ mov.b r1,@r4
+ add #1,r4
+ shlr8 r1
+ mov.b r1,@r4
+ add #1,r4
+#endif
+L_copy:
+ mov r0,r5
+
+ /* Calculate the correct routine to handle the destination
+ alignment and simultaneously calculate the loop counts for
+ both the 2 word copy loop and byte copy loop. */
+ mova L_jumptable,r0
+ mov r0,r1
+ mov r4,r0
+ mov r6,r7
+ and #3,r0
+ shlr2 r7
+ shll r0
+ shlr r7
+ mov.w @(r0,r1),r2
+ mov #7,r0
+ braf r2
+ and r0,r6
+L_base:
+
+ .balign 4
+L_jumptable:
+ .word L_copydest0 - L_base
+ .word L_copydest1_or_3 - L_base
+ .word L_copydest2 - L_base
+ .word L_copydest1_or_3 - L_base
+
+ .balign 4
+ /* Copy routine for (dest mod 4) == 1 or == 3. */
+L_copydest1_or_3:
+ add #-1,r4
+ .balignw 4,0x0009
+L_copydest1_or_3_loop:
+ mov.l @r5+,r0 /* Read first longword. */
+ dt r7
+ mov.l @r5+,r1 /* Read second longword. */
+#if __BYTE_ORDER == __BIG_ENDIAN
+ /* Write first longword as byte, word, byte. */
+ mov.b r0,@(4,r4)
+ shlr8 r0
+ mov.w r0,@(2,r4)
+ shlr16 r0
+ mov.b r0,@(1,r4)
+ mov r1,r0
+ /* Write second longword as byte, word, byte. */
+ mov.b r0,@(8,r4)
+ shlr8 r0
+ mov.w r0,@(6,r4)
+ shlr16 r0
+ mov.b r0,@(5,r4)
+#else
+ /* Write first longword as byte, word, byte. */
+ mov.b r0,@(1,r4)
+ shlr8 r0
+ mov.w r0,@(2,r4)
+ shlr16 r0
+ mov.b r0,@(4,r4)
+ mov r1,r0
+ /* Write second longword as byte, word, byte. */
+ mov.b r0,@(5,r4)
+ shlr8 r0
+ mov.w r0,@(6,r4)
+ shlr16 r0
+ mov.b r0,@(8,r4)
+#endif
+ bf/s L_copydest1_or_3_loop
+ add #8,r4
+
+ bra L_byteloop_init
+ add #1,r4
+
+ .balign 4
+ /* Copy routine for (dest mod 4) == 2. */
+L_copydest2:
+L_copydest2_loop:
+ mov.l @r5+,r0
+ dt r7
+ mov.l @r5+,r1
+#if __BYTE_ORDER == __BIG_ENDIAN
+ mov.w r0,@(2,r4)
+ shlr16 r0
+ mov.w r0,@r4
+ mov r1,r0
+ mov.w r0,@(6,r4)
+ shlr16 r0
+ mov.w r0,@(4,r4)
+#else
+ mov.w r0,@r4
+ shlr16 r0
+ mov.w r0,@(2,r4)
+ mov r1,r0
+ mov.w r0,@(4,r4)
+ shlr16 r0
+ mov.w r0,@(6,r4)
+#endif
+ bf/s L_copydest2_loop
+ add #8,r4
+
+ bra L_byteloop_init
+ nop
+
+ .balign 4
+ /* Copy routine for (dest mod 4) == 0. */
+L_copydest0:
+ add #-8,r4
+ .balignw 4,0x0009
+L_copydest0_loop:
+ mov.l @r5+,r0
+ dt r7
+ mov.l @r5+,r1
+ add #8,r4
+ mov.l r0,@r4
+ bf/s L_copydest0_loop
+ mov.l r1,@(4,r4)
+
+ add #8,r4 /* Fall through. */
+
+L_byteloop_init:
+ tst r6,r6
+ bt L_exit
+
+ .balignw 4,0x0009
+ /* Copy remaining bytes. */
+L_byteloop:
+ mov.b @r5+,r0
+ dt r6
+ mov.b r0,@r4
+ bf/s L_byteloop
+ add #1,r4
+
+L_exit:
+ rts
+ mov r3,r0 /* Return destination. */
+END(memcpy)
+libc_hidden_builtin_def (memcpy)
diff --git a/libc/sysdeps/sh/memset.S b/libc/sysdeps/sh/memset.S
new file mode 100644
index 000000000..9a8e2efd9
--- /dev/null
+++ b/libc/sysdeps/sh/memset.S
@@ -0,0 +1,89 @@
+/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
+ Optimized by Toshiyasu Morita <toshiyasu.morita@hsa.hitachi.com>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* void *memset (t, c, len); */
+
+ENTRY(memset)
+ mov #12,r0
+ cmp/gt r6,r0
+ bt.s L_byte_loop_init
+ mov r4,r7
+
+ extu.b r5,r5
+ swap.b r5,r1
+ or r1,r5
+ swap.w r5,r1
+ or r1,r5
+
+ mov r4,r0
+ tst #1,r0
+ bt L_wordalign
+
+ mov.b r5,@r4
+ add #-1,r6
+ add #1,r4
+ mov r4,r0
+
+ .balignw 4,0x0009
+L_wordalign:
+ tst #2,r0
+ bt L_word_loop_init
+
+ mov.w r5,@r4
+ add #-2,r6
+ add #2,r4
+ mov r4,r0
+
+ .balignw 4,0x0009
+L_word_loop_init:
+ mov r6,r3
+ shlr2 r3
+ mov #7,r0
+ shlr r3
+ and r0,r6
+
+ .balignw 4,0x0009
+L_2word_loop:
+ mov.l r5,@r4
+ dt r3
+ mov.l r5,@(4,r4)
+ bf.s L_2word_loop
+ add #8,r4
+
+ .balignw 4,0x0009
+L_byte_loop_init:
+ tst r6,r6
+ bt L_byte_exit
+
+ .balignw 4,0x0009
+L_byte_loop:
+ mov.b r5,@r4
+ dt r6
+ bf.s L_byte_loop
+ add #1,r4
+
+ .balignw 4,0x0009
+L_byte_exit:
+ rts
+ mov r7,r0
+END(memset)
+libc_hidden_builtin_def (memset)
diff --git a/libc/sysdeps/sh/memusage.h b/libc/sysdeps/sh/memusage.h
new file mode 100644
index 000000000..8a0ce4a18
--- /dev/null
+++ b/libc/sysdeps/sh/memusage.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("r15"); stack_ptr; })
+
+#include <sysdeps/generic/memusage.h>
diff --git a/libc/sysdeps/sh/sh3/__longjmp.S b/libc/sysdeps/sh/sh3/__longjmp.S
new file mode 100644
index 000000000..c6d8a3214
--- /dev/null
+++ b/libc/sysdeps/sh/sh3/__longjmp.S
@@ -0,0 +1,57 @@
+/* longjmp for SH.
+ Copyright (C) 1999, 2000, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _SETJMP_H
+#define _ASM
+#include <bits/setjmp.h>
+
+/* __longjmp(jmpbuf, val) */
+
+ENTRY (__longjmp)
+ mov.l @r4+, r8
+ mov.l @r4+, r9
+ mov.l @r4+, r10
+ mov.l @r4+, r11
+ mov.l @r4+, r12
+ mov r5, r0 /* get the return value in place */
+ tst r0, r0
+ bf.s 1f
+ mov.l @r4+, r13
+ mov #1,r0 /* can't let setjmp() return zero! */
+1:
+#ifdef PTR_DEMANGLE
+ mov.l @r4+, r2
+ PTR_DEMANGLE (r2, r1)
+ mov r2, r14
+ mov.l @r4+, r2
+ PTR_DEMANGLE2 (r2, r1)
+ mov r2, r15
+ mov.l @r4+, r2
+ PTR_DEMANGLE2 (r2, r1)
+ lds r2, pr
+ mov #0, r1
+#else
+ mov.l @r4+, r14
+ mov.l @r4+, r15
+ lds.l @r4+, pr
+#endif
+ rts
+ ldc.l @r4+, gbr
+END (__longjmp)
diff --git a/libc/sysdeps/sh/sh3/setjmp.S b/libc/sysdeps/sh/sh3/setjmp.S
new file mode 100644
index 000000000..d04e4b851
--- /dev/null
+++ b/libc/sysdeps/sh/sh3/setjmp.S
@@ -0,0 +1,81 @@
+/* setjmp for SH3.
+ Copyright (C) 1999, 2000, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+
+ENTRY (__sigsetjmp)
+ /* Save registers */
+ add #(JB_SIZE - 4 * 5), r4
+ stc.l gbr, @-r4
+#ifdef PTR_MANGLE
+ sts pr, r2
+ PTR_MANGLE (r2, r1)
+ mov.l r2, @-r4
+ mov r15, r2
+ PTR_MANGLE2 (r2, r1)
+ mov.l r2, @-r4
+ mov r14, r2
+ PTR_MANGLE2 (r2, r1)
+ mov.l r2, @-r4
+ mov #0, r1
+#else
+ sts.l pr, @-r4
+ mov.l r15, @-r4
+ mov.l r14, @-r4
+#endif
+ mov.l r13, @-r4
+ mov.l r12, @-r4
+ mov.l r11, @-r4
+ mov.l r10, @-r4
+ mov.l r9, @-r4
+ mov.l r8, @-r4
+
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ /* In ld.so we never save the signal mask. */
+ rts
+ mov #0, r0
+#else
+ /* Make a tail call to __sigjmp_save; it takes the same args. */
+# ifdef SHARED
+ mov.l 1f, r1
+ mova 1f, r0
+ bra 2f
+ add r1, r0
+ .align 2
+1:
+ .long _GLOBAL_OFFSET_TABLE_
+2:
+ mov.l .L1, r1
+ mov.l @(r0,r1), r1
+ jmp @r1
+ nop
+ .align 2
+.L1:
+ .long C_SYMBOL_NAME(__sigjmp_save@GOT)
+# else
+ mov.l .L1, r1
+ jmp @r1
+ nop
+ .align 2
+.L1:
+ .long C_SYMBOL_NAME(__sigjmp_save)
+# endif
+#endif
+END (__sigsetjmp)
diff --git a/libc/sysdeps/sh/sh4/Versions b/libc/sysdeps/sh/sh4/Versions
new file mode 100644
index 000000000..8cc1c7b7d
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/Versions
@@ -0,0 +1,5 @@
+ld {
+ GLIBC_PRIVATE {
+ __fpscr_values;
+ }
+}
diff --git a/libc/sysdeps/sh/sh4/__longjmp.S b/libc/sysdeps/sh/sh4/__longjmp.S
new file mode 100644
index 000000000..320a7d11f
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/__longjmp.S
@@ -0,0 +1,62 @@
+/* longjmp for SH.
+ Copyright (C) 1999, 2000, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _SETJMP_H
+#define _ASM
+#include <bits/setjmp.h>
+
+/* __longjmp(jmpbuf, val) */
+
+ENTRY (__longjmp)
+ mov.l @r4+, r8
+ mov.l @r4+, r9
+ mov.l @r4+, r10
+ mov.l @r4+, r11
+ mov.l @r4+, r12
+ mov r5, r0 /* get the return value in place */
+ tst r0, r0
+ bf.s 1f
+ mov.l @r4+, r13
+ mov #1,r0 /* can't let setjmp() return zero! */
+1:
+#ifdef PTR_DEMANGLE
+ mov.l @r4+, r2
+ PTR_DEMANGLE (r2, r1)
+ mov r2, r14
+ mov.l @r4+, r2
+ PTR_DEMANGLE2 (r2, r1)
+ mov r2, r15
+ mov.l @r4+, r2
+ PTR_DEMANGLE2 (r2, r1)
+ lds r2, pr
+ mov #0, r1
+#else
+ mov.l @r4+, r14
+ mov.l @r4+, r15
+ lds.l @r4+, pr
+#endif
+ ldc.l @r4+, gbr
+ lds.l @r4+, fpscr
+ fmov.s @r4+, fr12
+ fmov.s @r4+, fr13
+ fmov.s @r4+, fr14
+ rts
+ fmov.s @r4+, fr15
+END (__longjmp)
diff --git a/libc/sysdeps/sh/sh4/bits/mathdef.h b/libc/sysdeps/sh/sh4/bits/mathdef.h
new file mode 100644
index 000000000..2b8caf194
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/bits/mathdef.h
@@ -0,0 +1,69 @@
+/* Copyright (C) 1997, 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+
+/* FIXME! This file describes properties of the compiler, not the machine;
+ it should not be part of libc!
+
+ FIXME! This file does not deal with the -fshort-double option of
+ gcc! */
+
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
+# ifdef __GNUC__
+# if __STDC__ == 1
+
+/* In GNU or ANSI mode, gcc leaves `float' expressions as-is. */
+typedef float float_t; /* `float' expressions are evaluated as
+ `float'. */
+typedef double double_t; /* `double' expressions are evaluated as
+ `double'. */
+
+# else
+
+/* For `gcc -traditional', `float' expressions are evaluated as `double'. */
+typedef double float_t; /* `float' expressions are evaluated as
+ `double'. */
+typedef double double_t; /* `double' expressions are evaluated as
+ `double'. */
+
+# endif
+# else
+
+/* Wild guess at types for float_t and double_t. */
+typedef double float_t;
+typedef double double_t;
+
+# endif
+
+/* The values returned by `ilogb' for 0 and NaN respectively. */
+# define FP_ILOGB0 0x80000001
+# define FP_ILOGBNAN 0x7fffffff
+
+#endif /* ISO C99 */
+
+#ifndef __NO_LONG_DOUBLE_MATH
+/* Signal that we do not really have a `long double'. The disables the
+ declaration of all the `long double' function variants. */
+# define __NO_LONG_DOUBLE_MATH 1
+#endif
diff --git a/libc/sysdeps/sh/sh4/dl-trampoline.S b/libc/sysdeps/sh/sh4/dl-trampoline.S
new file mode 100644
index 000000000..f9529851a
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/dl-trampoline.S
@@ -0,0 +1,2 @@
+#define HAVE_FPU
+#include <sysdeps/sh/dl-trampoline.S>
diff --git a/libc/sysdeps/sh/sh4/fpu/bits/fenv.h b/libc/sysdeps/sh/sh4/fpu/bits/fenv.h
new file mode 100644
index 000000000..cbbad92e1
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/fpu/bits/fenv.h
@@ -0,0 +1,72 @@
+/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+
+/* Define bits representing the exception. We use the bit positions
+ of the appropriate bits in the FPU control word. */
+enum
+ {
+ FE_INEXACT = 0x04,
+#define FE_INEXACT FE_INEXACT
+ FE_UNDERFLOW = 0x08,
+#define FE_UNDERFLOW FE_UNDERFLOW
+ FE_OVERFLOW = 0x10,
+#define FE_OVERFLOW FE_OVERFLOW
+ FE_DIVBYZERO = 0x20,
+#define FE_DIVBYZERO FE_DIVBYZERO
+ FE_INVALID = 0x40,
+#define FE_INVALID FE_INVALID
+ };
+
+#define FE_ALL_EXCEPT \
+ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+/* The SH FPU supports all of the four defined rounding modes. We
+ use again the bit positions in the FPU control word as the values
+ for the appropriate macros. */
+enum
+ {
+ FE_TONEAREST = 0x0,
+#define FE_TONEAREST FE_TONEAREST
+ FE_TOWARDZERO = 0x1,
+#define FE_TOWARDZERO FE_TOWARDZERO
+ FE_UPWARD = 0x2,
+#define FE_UPWARD FE_UPWARD
+ FE_DOWNWARD = 0x3
+#define FE_DOWNWARD FE_DOWNWARD
+ };
+
+
+/* Type representing exception flags. */
+typedef unsigned short int fexcept_t;
+
+
+/* Type representing floating-point environment. This function corresponds
+ to the layout of the block written by the `fstenv'. */
+typedef struct
+ {
+ unsigned int __fpscr;
+ }
+fenv_t;
+
+/* If the default argument is used we use this value. */
+#define FE_DFL_ENV ((fenv_t *) -1)
diff --git a/libc/sysdeps/sh/sh4/fpu/fclrexcpt.c b/libc/sysdeps/sh/sh4/fpu/fclrexcpt.c
new file mode 100644
index 000000000..e10042ff3
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/fpu/fclrexcpt.c
@@ -0,0 +1,42 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+feclearexcept (int excepts)
+{
+ int cw;
+
+ /* Mask out unsupported bits/exceptions. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Read the complete control word. */
+ _FPU_GETCW (cw);
+
+ /* Clear exception bits. */
+ cw &= ~excepts;
+
+ /* Put the new data in effect. */
+ _FPU_SETCW (cw);
+
+ return 0;
+}
diff --git a/libc/sysdeps/sh/sh4/fpu/fegetenv.c b/libc/sysdeps/sh/sh4/fpu/fegetenv.c
new file mode 100644
index 000000000..c07b32af3
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/fpu/fegetenv.c
@@ -0,0 +1,31 @@
+/* Store current floating-point environment.
+ Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fegetenv (fenv_t *envp)
+{
+ unsigned long int temp;
+ _FPU_GETCW (temp);
+ envp->__fpscr = temp;
+
+ return 0;
+}
diff --git a/libc/sysdeps/sh/sh4/fpu/fegetround.c b/libc/sysdeps/sh/sh4/fpu/fegetround.c
new file mode 100644
index 000000000..4aca3e5ef
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/fpu/fegetround.c
@@ -0,0 +1,33 @@
+/* Return current rounding direction.
+ Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fegetround (void)
+{
+ int cw;
+
+ /* Get control word. */
+ _FPU_GETCW (cw);
+
+ return cw & 0x3;
+}
diff --git a/libc/sysdeps/sh/sh4/fpu/feholdexcpt.c b/libc/sysdeps/sh/sh4/fpu/feholdexcpt.c
new file mode 100644
index 000000000..7aac5a0d3
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/fpu/feholdexcpt.c
@@ -0,0 +1,38 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 1997, 1998, 1999, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ unsigned long int temp;
+
+ /* Store the environment. */
+ _FPU_GETCW (temp);
+ envp->__fpscr = temp;
+
+ /* Now set all exceptions to non-stop. */
+ temp &= ~FE_ALL_EXCEPT;
+ _FPU_SETCW (temp);
+
+ return 1;
+}
+libm_hidden_def (feholdexcept)
diff --git a/libc/sysdeps/sh/sh4/fpu/fesetenv.c b/libc/sysdeps/sh/sh4/fpu/fesetenv.c
new file mode 100644
index 000000000..b66ed7f5e
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/fpu/fesetenv.c
@@ -0,0 +1,35 @@
+/* Install given floating-point environment.
+ Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fesetenv (const fenv_t *envp)
+{
+ if (envp == FE_DFL_ENV)
+ _FPU_SETCW (_FPU_DEFAULT);
+ else
+ {
+ unsigned long int temp = envp->__fpscr;
+ _FPU_SETCW (temp);
+ }
+ return 0;
+}
+libm_hidden_def (fesetenv)
diff --git a/libc/sysdeps/sh/sh4/fpu/fesetround.c b/libc/sysdeps/sh/sh4/fpu/fesetround.c
new file mode 100644
index 000000000..cf4349004
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/fpu/fesetround.c
@@ -0,0 +1,44 @@
+/* Set current rounding direction.
+ Copyright (C) 1998, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fesetround (int round)
+{
+ unsigned int cw;
+
+ if ((round & ~0x3) != 0)
+ /* ROUND is no valid rounding mode. */
+ return 0;
+
+ /* Get current state. */
+ _FPU_GETCW (cw);
+
+ /* Set rounding bits. */
+ cw &= ~0x3;
+ cw |= round;
+ /* Set new state. */
+ _FPU_SETCW (cw);
+
+ return 1;
+}
+libm_hidden_def (fesetround)
diff --git a/libc/sysdeps/sh/sh4/fpu/fpu_control.h b/libc/sysdeps/sh/sh4/fpu/fpu_control.h
new file mode 100644
index 000000000..43eb9e549
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/fpu/fpu_control.h
@@ -0,0 +1,56 @@
+/* FPU control word definitions. SH version.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H
+
+/* masking of interrupts */
+#define _FPU_MASK_VM 0x0800 /* Invalid operation */
+#define _FPU_MASK_ZM 0x0400 /* Division by zero */
+#define _FPU_MASK_OM 0x0200 /* Overflow */
+#define _FPU_MASK_UM 0x0100 /* Underflow */
+#define _FPU_MASK_IM 0x0080 /* Inexact operation */
+
+/* rounding control */
+#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
+#define _FPU_RC_ZERO 0x1
+
+#define _FPU_RESERVED 0xffc00000 /* These bits are reserved. */
+
+/* The fdlibm code requires strict IEEE double precision arithmetic,
+ and no interrupts for exceptions, rounding to nearest. */
+#define _FPU_DEFAULT 0x00080000 /* Default value. */
+#define _FPU_IEEE 0x00080f80 /* Default + exceptions enabled. */
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t;
+
+/* Macros for accessing the hardware control word. */
+#define _FPU_GETCW(cw) __asm__ ("sts fpscr,%0" : "=r" (cw))
+
+#if defined __GNUC__
+#define _FPU_SETCW(cw) __set_fpscr ((cw))
+#else
+#define _FPU_SETCW(cw) __asm__ ("lds %0,fpscr" : : "r" (cw))
+#endif
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* _FPU_CONTROL_H */
diff --git a/libc/sysdeps/sh/sh4/fpu/fraiseexcpt.c b/libc/sysdeps/sh/sh4/fpu/fraiseexcpt.c
new file mode 100644
index 000000000..f67ec1520
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/fpu/fraiseexcpt.c
@@ -0,0 +1,36 @@
+/* Raise given exceptions.
+ Copyright (C) 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+#include <math.h>
+
+int
+feraiseexcept (int excepts)
+{
+ /* Raise exceptions represented by EXPECTS. */
+ fexcept_t temp;
+ _FPU_GETCW (temp);
+ temp |= (excepts & FE_ALL_EXCEPT);
+ temp |= (excepts & FE_ALL_EXCEPT) << 5;
+ _FPU_SETCW (temp);
+
+ return 0;
+}
+libm_hidden_def (feraiseexcept)
diff --git a/libc/sysdeps/sh/sh4/fpu/fsetexcptflg.c b/libc/sysdeps/sh/sh4/fpu/fsetexcptflg.c
new file mode 100644
index 000000000..f83a4e5a1
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/fpu/fsetexcptflg.c
@@ -0,0 +1,40 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <math.h>
+#include <fpu_control.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fexcept_t temp;
+
+ /* Get the current environment. */
+ _FPU_GETCW (temp);
+
+ /* Set the desired exception mask. */
+ temp &= ~(excepts & FE_ALL_EXCEPT);
+ temp |= (*flagp & excepts & FE_ALL_EXCEPT);
+
+ /* Save state back to the FPU. */
+ _FPU_SETCW (temp);
+
+ return 0;
+}
diff --git a/libc/sysdeps/sh/sh4/fpu/ftestexcept.c b/libc/sysdeps/sh/sh4/fpu/ftestexcept.c
new file mode 100644
index 000000000..17a2ccfc8
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/fpu/ftestexcept.c
@@ -0,0 +1,32 @@
+/* Test exception in current environment.
+ Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fetestexcept (int excepts)
+{
+ fexcept_t temp;
+
+ /* Get current exceptions. */
+ _FPU_GETCW (temp);
+
+ return temp & excepts & FE_ALL_EXCEPT;
+}
diff --git a/libc/sysdeps/sh/sh4/fpu/libm-test-ulps b/libc/sysdeps/sh/sh4/fpu/libm-test-ulps
new file mode 100644
index 000000000..4831f4849
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/fpu/libm-test-ulps
@@ -0,0 +1,1094 @@
+# Begin of automatic generation
+
+# asin
+Test "asin (-0.5) == -pi/6":
+float: 2
+ifloat: 2
+Test "asin (0.5) == pi/6":
+float: 2
+ifloat: 2
+Test "asin (0.7) == 0.7753974966107530637":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# atan2
+Test "atan2 (0.7, -1.0) == 2.530866689200584621918884506789267":
+float: 3
+ifloat: 3
+Test "atan2 (-0.7, -1.0) == -2.530866689200584621918884506789267":
+float: 3
+ifloat: 3
+Test "atan2 (1.4, -0.93) == 2.1571487668237843754887415992772736":
+float: 4
+ifloat: 4
+
+# atanh
+Test "atanh (0.7) == 0.8673005276940531944":
+double: 1
+idouble: 1
+
+# cabs
+Test "cabs (-0.7 + 12.4 i) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "cabs (-0.7 - 12.4 i) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "cabs (-12.4 + 0.7 i) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "cabs (-12.4 - 0.7 i) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "cabs (0.7 + 1.2 i) == 1.3892443989449804508432547041028554":
+double: 1
+idouble: 1
+Test "cabs (0.7 + 12.4 i) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+
+# cacos
+Test "Real part of: cacos (0.7 + 1.2 i) == 1.1351827477151551088992008271819053 - 1.0927647857577371459105272080819308 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: cacos (0.7 + 1.2 i) == 1.1351827477151551088992008271819053 - 1.0927647857577371459105272080819308 i":
+float: 1
+ifloat: 1
+
+# cacosh
+Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+Test "Real part of: cacosh (0.7 + 1.2 i) == 1.0927647857577371459105272080819308 + 1.1351827477151551088992008271819053 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# casin
+Test "Real part of: casin (0.7 + 1.2 i) == 0.4356135790797415103321208644578462 + 1.0927647857577371459105272080819308 i":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+Test "Imaginary part of: casin (0.7 + 1.2 i) == 0.4356135790797415103321208644578462 + 1.0927647857577371459105272080819308 i":
+float: 1
+ifloat: 1
+
+# casinh
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+Test "Real part of: casinh (0.7 + 1.2 i) == 0.97865459559367387689317593222160964 + 0.91135418953156011567903546856170941 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: casinh (0.7 + 1.2 i) == 0.97865459559367387689317593222160964 + 0.91135418953156011567903546856170941 i":
+float: 1
+ifloat: 1
+
+# catan
+Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+float: 3
+ifloat: 3
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: catan (0.7 + 1.2 i) == 1.0785743834118921877443707996386368 + 0.57705737765343067644394541889341712 i":
+float: 4
+ifloat: 4
+Test "Imaginary part of: catan (0.7 + 1.2 i) == 1.0785743834118921877443707996386368 + 0.57705737765343067644394541889341712 i":
+double: 1
+idouble: 1
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 4
+idouble: 4
+Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+float: 4
+ifloat: 4
+Test "Real part of: catanh (0.7 + 1.2 i) == 0.2600749516525135959200648705635915 + 0.97024030779509898497385130162655963 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: catanh (0.7 + 1.2 i) == 0.2600749516525135959200648705635915 + 0.97024030779509898497385130162655963 i":
+double: 1
+float: 6
+idouble: 1
+ifloat: 6
+
+# cbrt
+Test "cbrt (-27.0) == -3.0":
+double: 1
+idouble: 1
+Test "cbrt (0.970299) == 0.99":
+double: 1
+idouble: 1
+
+# ccos
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccos (0.7 + 1.2 i) == 1.3848657645312111080 - 0.97242170335830028619 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (0.7 + 1.2 i) == 1.3848657645312111080 - 0.97242170335830028619 i":
+double: 1
+idouble: 1
+
+# ccosh
+Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccosh (0.7 + 1.2 i) == 0.4548202223691477654 + 0.7070296600921537682 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (0.7 + 1.2 i) == 0.4548202223691477654 + 0.7070296600921537682 i":
+double: 1
+idouble: 1
+
+# cexp
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+float: 1
+ifloat: 1
+Test "Real part of: cexp (0.7 + 1.2 i) == 0.7296989091503236012 + 1.8768962328348102821 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: cexp (0.7 + 1.2 i) == 0.7296989091503236012 + 1.8768962328348102821 i":
+float: 1
+ifloat: 1
+
+# clog
+Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Real part of: clog10 (0.7 + 1.2 i) == 0.1427786545038868803 + 0.4528483579352493248 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0.7 + 1.2 i) == 0.1427786545038868803 + 0.4528483579352493248 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+float: 1
+ifloat: 1
+
+# cos
+Test "cos (0.7) == 0.7648421872844884262":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+float: 0.5
+idouble: 1
+ifloat: 0.5
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "cos (pi/2) == 0":
+double: 0.2758
+float: 0.3667
+idouble: 0.2758
+ifloat: 0.3667
+
+# cpow
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 2
+ifloat: 2
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 1.1031
+float: 1.5
+idouble: 1.1031
+ifloat: 1.5
+
+# csin
+Test "Imaginary part of: csin (0.7 + 1.2 i) == 1.1664563419657581376 + 1.1544997246948547371 i":
+float: 1
+ifloat: 1
+
+# csinh
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+Test "Real part of: csinh (0.7 + 1.2 i) == 0.27487868678117583582 + 1.1698665727426565139 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (0.7 + 1.2 i) == 0.27487868678117583582 + 1.1698665727426565139 i":
+float: 1
+ifloat: 1
+
+# csqrt
+Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+Test "Real part of: csqrt (0.7 + 1.2 i) == 1.022067610030026450706487883081139 + 0.58704531296356521154977678719838035 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: csqrt (0.7 + 1.2 i) == 1.022067610030026450706487883081139 + 0.58704531296356521154977678719838035 i":
+float: 1
+ifloat: 1
+
+# ctan
+Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+double: 1
+idouble: 1
+Test "Real part of: ctan (0.7 + 1.2 i) == 0.1720734197630349001 + 0.9544807059989405538 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ctan (0.7 + 1.2 i) == 0.1720734197630349001 + 0.9544807059989405538 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+ifloat: 1
+Test "Real part of: ctanh (0.7 + 1.2 i) == 1.3472197399061191630 + 0.4778641038326365540 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: ctanh (0.7 + 1.2 i) == 1.3472197399061191630 + 0.4778641038326365540 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+# erfc
+Test "erfc (0.7) == 0.32219880616258152702":
+double: 1
+idouble: 1
+Test "erfc (1.2) == 0.089686021770364619762":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+Test "erfc (2.0) == 0.0046777349810472658379":
+double: 1
+idouble: 1
+Test "erfc (4.1) == 0.67000276540848983727e-8":
+double: 24
+float: 12
+idouble: 24
+ifloat: 12
+
+# exp10
+Test "exp10 (-1) == 0.1":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "exp10 (0.7) == 5.0118723362727228500":
+float: 1
+ifloat: 1
+Test "exp10 (3) == 1000":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+
+# expm1
+Test "expm1 (1) == M_El - 1.0":
+float: 1
+ifloat: 1
+
+# fmod
+Test "fmod (-6.5, -2.3) == -1.9":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "fmod (-6.5, 2.3) == -1.9":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "fmod (6.5, -2.3) == 1.9":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "fmod (6.5, 2.3) == 1.9":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, 1.2) == 1.3892443989449804508432547041028554":
+double: 1
+idouble: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+
+# j0
+Test "j0 (10.0) == -0.24593576445134833520":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "j0 (2.0) == 0.22389077914123566805":
+float: 2
+ifloat: 2
+Test "j0 (8.0) == 0.17165080713755390609":
+float: 1
+ifloat: 1
+
+# j1
+Test "j1 (10.0) == 0.043472746168861436670":
+float: 2
+ifloat: 2
+Test "j1 (2.0) == 0.57672480775687338720":
+double: 1
+idouble: 1
+Test "j1 (8.0) == 0.23463634685391462438":
+double: 1
+idouble: 1
+
+# jn
+Test "jn (0, 10.0) == -0.24593576445134833520":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "jn (0, 2.0) == 0.22389077914123566805":
+float: 2
+ifloat: 2
+Test "jn (0, 8.0) == 0.17165080713755390609":
+float: 1
+ifloat: 1
+Test "jn (1, 10.0) == 0.043472746168861436670":
+float: 2
+ifloat: 2
+Test "jn (1, 2.0) == 0.57672480775687338720":
+double: 1
+idouble: 1
+Test "jn (1, 8.0) == 0.23463634685391462438":
+double: 1
+idouble: 1
+Test "jn (10, 0.1) == 0.26905328954342155795e-19":
+double: 6
+float: 4
+idouble: 6
+ifloat: 4
+Test "jn (10, 0.7) == 0.75175911502153953928e-11":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "jn (10, 10.0) == 0.20748610663335885770":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+Test "jn (10, 2.0) == 0.25153862827167367096e-6":
+float: 4
+ifloat: 4
+Test "jn (3, 0.1) == 0.000020820315754756261429":
+double: 1
+idouble: 1
+Test "jn (3, 0.7) == 0.0069296548267508408077":
+float: 1
+ifloat: 1
+Test "jn (3, 10.0) == 0.058379379305186812343":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "jn (3, 2.0) == 0.12894324947440205110":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# lgamma
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# log
+Test "log (0.7) == -0.35667494393873237891263871124118447":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# log10
+Test "log10 (0.7) == -0.15490195998574316929":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "log10 (e) == log10(e)":
+float: 1
+ifloat: 1
+
+# log1p
+Test "log1p (-0.3) == -0.35667494393873237891263871124118447":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# log2
+Test "log2 (0.7) == -0.51457317282975824043":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# sincos
+Test "sincos (0.7, &sin_res, &cos_res) puts 0.76484218728448842626 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+float: 0.5
+idouble: 1
+ifloat: 0.5
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.866025403784438646764 in sin_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+double: 0.2758
+float: 0.3667
+idouble: 0.2758
+ifloat: 0.3667
+Test "sincos (pi/6, &sin_res, &cos_res) puts 0.866025403784438646764 in cos_res":
+float: 1
+ifloat: 1
+
+# sinh
+Test "sinh (0.7) == 0.75858370183953350346":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# tan
+Test "tan (pi/4) == 1":
+double: 0.5
+idouble: 0.5
+
+# tanh
+Test "tanh (0.7) == 0.60436777711716349631":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+ifloat: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# y0
+Test "y0 (0.7) == -0.19066492933739506743":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (1.0) == 0.088256964215676957983":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (1.5) == 0.38244892379775884396":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (10.0) == 0.055671167283599391424":
+float: 1
+ifloat: 1
+Test "y0 (8.0) == 0.22352148938756622053":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# y1
+Test "y1 (0.1) == -6.4589510947020269877":
+double: 1
+idouble: 1
+Test "y1 (0.7) == -1.1032498719076333697":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "y1 (1.5) == -0.41230862697391129595":
+float: 1
+ifloat: 1
+Test "y1 (10.0) == 0.24901542420695388392":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "y1 (2.0) == -0.10703243154093754689":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "y1 (8.0) == -0.15806046173124749426":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# yn
+Test "yn (0, 0.7) == -0.19066492933739506743":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 1.0) == 0.088256964215676957983":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 1.5) == 0.38244892379775884396":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 10.0) == 0.055671167283599391424":
+float: 1
+ifloat: 1
+Test "yn (0, 8.0) == 0.22352148938756622053":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (1, 0.1) == -6.4589510947020269877":
+double: 1
+idouble: 1
+Test "yn (1, 0.7) == -1.1032498719076333697":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (1, 1.5) == -0.41230862697391129595":
+float: 1
+ifloat: 1
+Test "yn (1, 10.0) == 0.24901542420695388392":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "yn (1, 2.0) == -0.10703243154093754689":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (1, 8.0) == -0.15806046173124749426":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "yn (10, 0.1) == -0.11831335132045197885e19":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+Test "yn (10, 0.7) == -0.42447194260703866924e10":
+double: 3
+idouble: 3
+Test "yn (10, 1.0) == -0.12161801427868918929e9":
+double: 1
+idouble: 1
+Test "yn (10, 10.0) == -0.35981415218340272205":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (10, 2.0) == -129184.54220803928264":
+double: 2
+idouble: 2
+Test "yn (3, 0.1) == -5099.3323786129048894":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (3, 0.7) == -15.819479052819633505":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "yn (3, 10.0) == -0.25136265718383732978":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (3, 2.0) == -1.1277837768404277861":
+double: 1
+idouble: 1
+
+# Maximal error of functions:
+Function: "asin":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "atan2":
+float: 4
+ifloat: 4
+
+Function: "atanh":
+double: 1
+idouble: 1
+
+Function: "cabs":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "cacos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "cacos":
+float: 1
+ifloat: 1
+
+Function: Real part of "cacosh":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+
+Function: Real part of "casin":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+
+Function: Imaginary part of "casin":
+float: 1
+ifloat: 1
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+
+Function: Real part of "catan":
+float: 4
+ifloat: 4
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "catanh":
+double: 4
+float: 1
+idouble: 4
+ifloat: 1
+
+Function: Imaginary part of "catanh":
+double: 1
+float: 6
+idouble: 1
+ifloat: 6
+
+Function: "cbrt":
+double: 1
+idouble: 1
+
+Function: Real part of "ccos":
+double: 1
+idouble: 1
+
+Function: Imaginary part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "cexp":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "cexp":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "clog":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+
+Function: Real part of "clog10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: Real part of "cpow":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+
+Function: Imaginary part of "cpow":
+double: 1.1031
+float: 2
+idouble: 1.1031
+ifloat: 2
+
+Function: Imaginary part of "csin":
+float: 1
+ifloat: 1
+
+Function: Real part of "csinh":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "csqrt":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "csqrt":
+float: 1
+ifloat: 1
+
+Function: Real part of "ctan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ctan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "ctanh":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: Imaginary part of "ctanh":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: "erfc":
+double: 24
+float: 12
+idouble: 24
+ifloat: 12
+
+Function: "exp10":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+
+Function: "expm1":
+float: 1
+ifloat: 1
+
+Function: "fmod":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: "hypot":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "j0":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "jn":
+double: 6
+float: 4
+idouble: 6
+ifloat: 4
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "log":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "log10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "log1p":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "log2":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "sinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "tan":
+double: 0.5
+idouble: 0.5
+
+Function: "tanh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "tgamma":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+
+# end of automatic generation
diff --git a/libc/sysdeps/sh/sh4/setjmp.S b/libc/sysdeps/sh/sh4/setjmp.S
new file mode 100644
index 000000000..f9a4f0a8c
--- /dev/null
+++ b/libc/sysdeps/sh/sh4/setjmp.S
@@ -0,0 +1,86 @@
+/* setjmp for SH4.
+ Copyright (C) 1999, 2000, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+
+ENTRY (__sigsetjmp)
+ /* Save registers */
+ add #JB_SIZE, r4
+ fmov.s fr15, @-r4
+ fmov.s fr14, @-r4
+ fmov.s fr13, @-r4
+ fmov.s fr12, @-r4
+ sts.l fpscr, @-r4
+ stc.l gbr, @-r4
+#ifdef PTR_MANGLE
+ sts pr, r2
+ PTR_MANGLE (r2, r1)
+ mov.l r2, @-r4
+ mov r15, r2
+ PTR_MANGLE2 (r2, r1)
+ mov.l r2, @-r4
+ mov r14, r2
+ PTR_MANGLE2 (r2, r1)
+ mov.l r2, @-r4
+ mov #0, r1
+#else
+ sts.l pr, @-r4
+ mov.l r15, @-r4
+ mov.l r14, @-r4
+#endif
+ mov.l r13, @-r4
+ mov.l r12, @-r4
+ mov.l r11, @-r4
+ mov.l r10, @-r4
+ mov.l r9, @-r4
+ mov.l r8, @-r4
+
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ /* In ld.so we never save the signal mask. */
+ rts
+ mov #0, r0
+#else
+ /* Make a tail call to __sigjmp_save; it takes the same args. */
+# ifdef SHARED
+ mov.l 1f, r1
+ mova 1f, r0
+ bra 2f
+ add r1, r0
+ .align 2
+1:
+ .long _GLOBAL_OFFSET_TABLE_
+2:
+ mov.l .L1, r1
+ mov.l @(r0,r1), r1
+ jmp @r1
+ nop
+ .align 2
+.L1:
+ .long C_SYMBOL_NAME(__sigjmp_save@GOT)
+# else
+ mov.l .L1, r1
+ jmp @r1
+ nop
+ .align 2
+.L1:
+ .long C_SYMBOL_NAME(__sigjmp_save)
+# endif
+#endif
+END (__sigsetjmp)
diff --git a/libc/sysdeps/sh/stackinfo.h b/libc/sysdeps/sh/stackinfo.h
new file mode 100644
index 000000000..e65338f25
--- /dev/null
+++ b/libc/sysdeps/sh/stackinfo.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file contains a bit of information about the stack allocation
+ of the processor. */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H 1
+
+/* On SH the stack grows down. */
+#define _STACK_GROWS_DOWN 1
+
+#endif /* stackinfo.h */
diff --git a/libc/sysdeps/sh/strlen.S b/libc/sysdeps/sh/strlen.S
new file mode 100644
index 000000000..e25d7ef5e
--- /dev/null
+++ b/libc/sysdeps/sh/strlen.S
@@ -0,0 +1,85 @@
+/* Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <endian.h>
+
+/* size_t strlen (const char *s) */
+
+ENTRY(strlen)
+ mov r4, r0
+ and #3, r0
+ tst r0, r0
+ bt/s 1f
+ mov #0, r2
+
+ add #-1, r0
+ shll2 r0
+ shll r0
+ braf r0
+ nop
+
+ mov.b @r4+, r1
+ tst r1, r1
+ bt 8f
+ add #1, r2
+
+ mov.b @r4+, r1
+ tst r1, r1
+ bt 8f
+ add #1, r2
+
+ mov.b @r4+, r1
+ tst r1, r1
+ bt 8f
+ add #1, r2
+
+1:
+ mov #0, r3
+2:
+ mov.l @r4+, r1
+ cmp/str r3, r1
+ bf/s 2b
+ add #4, r2
+
+ add #-4, r2
+#if __BYTE_ORDER == __BIG_ENDIAN
+ swap.b r1, r1
+ swap.w r1, r1
+ swap.b r1, r1
+#endif
+ extu.b r1, r0
+ tst r0, r0
+ bt/s 8f
+ shlr8 r1
+ add #1, r2
+ extu.b r1, r0
+ tst r0, r0
+ bt/s 8f
+ shlr8 r1
+ add #1, r2
+ extu.b r1, r0
+ tst r0, r0
+ bt 8f
+ add #1, r2
+8:
+ rts
+ mov r2, r0
+END(strlen)
+libc_hidden_builtin_def (strlen)
diff --git a/libc/sysdeps/sh/sys/ucontext.h b/libc/sysdeps/sh/sys/ucontext.h
new file mode 100644
index 000000000..961905db1
--- /dev/null
+++ b/libc/sysdeps/sh/sys/ucontext.h
@@ -0,0 +1,99 @@
+/* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Where is System V/SH ABI? */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+
+typedef int greg_t;
+
+/* Number of general registers. */
+#define NFPREG 16
+
+/* Container for all general registers. */
+typedef greg_t gregset_t[NFPREG];
+
+/* Number of each register is the `gregset_t' array. */
+enum
+{
+ R0 = 0,
+#define R0 R0
+ R1 = 1,
+#define R1 R1
+ R2 = 2,
+#define R2 R2
+ R3 = 3,
+#define R3 R3
+ R4 = 4,
+#define R4 R4
+ R5 = 5,
+#define R5 R5
+ R6 = 6,
+#define R6 R6
+ R7 = 7,
+#define R7 R7
+ R8 = 8,
+#define R8 R8
+ R9 = 9,
+#define R9 R9
+ R10 = 10,
+#define R10 R10
+ R11 = 11,
+#define R11 R11
+ R12 = 12,
+#define R12 R12
+ R13 = 13,
+#define R13 R13
+ R14 = 14,
+#define R14 R14
+ R15 = 15,
+#define R15 R15
+};
+
+typedef int freg_t;
+
+/* Number of FPU registers. */
+#define NFREG 16
+
+/* Structure to describe FPU registers. */
+typedef freg_t fpregset_t[NFREG];
+
+/* Context to describe whole processor state. */
+typedef struct
+ {
+ gregset_t gregs;
+ fpregset_t fpregs;
+ fpregset_t xfpregs;
+ } mcontext_t;
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ __sigset_t uc_sigmask;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ long int uc_filler[5];
+ } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/sh/sysdep.h b/libc/sysdeps/sh/sysdep.h
new file mode 100644
index 000000000..743631ad7
--- /dev/null
+++ b/libc/sysdeps/sh/sysdep.h
@@ -0,0 +1,91 @@
+/* Assembler macros for SH.
+ Copyright (C) 1999, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+/* Syntactic details of assembler. */
+
+#ifdef HAVE_ELF
+
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,@##typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+#ifdef SHARED
+#define PLTJMP(_x) _x##@PLT
+#else
+#define PLTJMP(_x) _x
+#endif
+
+#else
+
+#define ALIGNARG(log2) log2
+#define ASM_TYPE_DIRECTIVE(name,type) /* Nothing is specified. */
+#define ASM_SIZE_DIRECTIVE(name) /* Nothing is specified. */
+
+#define PLTJMP(_x) _x
+
+#endif
+
+/* Define an entry point visible from C. */
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),function) \
+ .align ALIGNARG(5); \
+ C_LABEL(name) \
+ cfi_startproc; \
+ CALL_MCOUNT
+
+#undef END
+#define END(name) \
+ cfi_endproc; \
+ ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(name))
+
+/* If compiled for profiling, call `mcount' at the start of each function. */
+#ifdef PROF
+#define CALL_MCOUNT \
+ mov.l 1f,r1; \
+ sts.l pr,@-r15; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (pr, 0); \
+ mova 2f,r0; \
+ jmp @r1; \
+ lds r0,pr; \
+ .align 2; \
+1: .long mcount; \
+2: lds.l @r15+,pr; \
+ cfi_adjust_cfa_offset (-4); \
+ cfi_restore (pr)
+
+#else
+#define CALL_MCOUNT /* Do nothing. */
+#endif
+
+#ifdef NO_UNDERSCORES
+/* Since C identifiers are not normally prefixed with an underscore
+ on this system, the asm identifier `syscall_error' intrudes on the
+ C name space. Make sure we use an innocuous name. */
+#define syscall_error __syscall_error
+#define mcount _mcount
+#endif
+
+#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/sparc/Makefile b/libc/sysdeps/sparc/Makefile
new file mode 100644
index 000000000..40323a064
--- /dev/null
+++ b/libc/sysdeps/sparc/Makefile
@@ -0,0 +1,6 @@
+# The Sparc `long double' is a distinct type we support.
+long-double-fcts = yes
+
+ifeq ($(subdir),db2)
+CPPFLAGS += -DHAVE_SPINLOCKS=1 -DHAVE_ASSEM_SPARC_GCC=1
+endif
diff --git a/libc/sysdeps/sparc/Subdirs b/libc/sysdeps/sparc/Subdirs
new file mode 100644
index 000000000..87eadf302
--- /dev/null
+++ b/libc/sysdeps/sparc/Subdirs
@@ -0,0 +1 @@
+soft-fp
diff --git a/libc/sysdeps/sparc/abort-instr.h b/libc/sysdeps/sparc/abort-instr.h
new file mode 100644
index 000000000..ea92dfe86
--- /dev/null
+++ b/libc/sysdeps/sparc/abort-instr.h
@@ -0,0 +1,2 @@
+/* An instruction which should crash any program is an unimp. */
+#define ABORT_INSTRUCTION asm ("unimp 0xf00")
diff --git a/libc/sysdeps/sparc/bits/endian.h b/libc/sysdeps/sparc/bits/endian.h
new file mode 100644
index 000000000..8acfdf5df
--- /dev/null
+++ b/libc/sysdeps/sparc/bits/endian.h
@@ -0,0 +1,12 @@
+/* Sparc is big-endian, but v9 supports endian conversion on loads/stores
+ and GCC supports such a mode. Be prepared. */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+# define __BYTE_ORDER __LITTLE_ENDIAN
+#else
+# define __BYTE_ORDER __BIG_ENDIAN
+#endif
diff --git a/libc/sysdeps/sparc/bits/huge_vall.h b/libc/sysdeps/sparc/bits/huge_vall.h
new file mode 100644
index 000000000..e4e2749a1
--- /dev/null
+++ b/libc/sysdeps/sparc/bits/huge_vall.h
@@ -0,0 +1,49 @@
+/* `HUGE_VALL' constant for IEEE 754 machines (where it is infinity).
+ Used by <stdlib.h> and <math.h> functions for overflow.
+ Copyright (C) 1992, 1995, 1996, 1997, 1999, 2000, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/huge_vall.h> directly; include <math.h> instead."
+#endif
+
+#if __GNUC_PREREQ(3,3)
+# define HUGE_VALL (__builtin_huge_vall())
+#else
+# include <bits/wordsize.h>
+# if __WORDSIZE == 32
+# define HUGE_VALL ((long double) HUGE_VAL)
+# elif __GNUC_PREREQ(2,96)
+# define HUGE_VALL (__extension__ 0x1.0p32767L)
+# elif defined __GNUC__
+
+# define HUGE_VALL \
+ (__extension__ \
+ ((union { struct { unsigned long __h, __l; } __i; long double __d; }) \
+ { __i: { __h: 0x7fff000000000000UL, __l: 0 } }).__d)
+
+# else /* not GCC */
+
+typedef union { unsigned char __c[16]; long double __d; } __huge_vall_t;
+# define __HUGE_VALL_bytes { 0x7f, 0xff, 0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+static __huge_vall_t __huge_vall = { __HUGE_VALL_bytes };
+# define HUGE_VALL (__huge_vall.__d)
+
+# endif /* GCC. */
+#endif /* GCC 3.3. */
diff --git a/libc/sysdeps/sparc/bits/link.h b/libc/sysdeps/sparc/bits/link.h
new file mode 100644
index 000000000..9b8434f56
--- /dev/null
+++ b/libc/sysdeps/sparc/bits/link.h
@@ -0,0 +1,100 @@
+/* Machine-specific audit interfaces for dynamic linker. SPARC version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+#if __WORDSIZE == 32
+
+typedef struct La_sparc32_regs
+{
+ uint32_t lr_lreg[8]; /* %l0 through %l7 */
+ uint32_t lr_reg[6]; /* %o0 through %o5 */
+ uint32_t lr_sp; /* %o6 */
+ uint32_t lr_ra; /* %o7 */
+ uint32_t lr_struct; /* Pass-by-reference struct pointer */
+} La_sparc32_regs;
+
+typedef struct La_sparc32_retval
+{
+ uint32_t lrv_reg[2]; /* %o0 and %o1 */
+ double lrv_fpreg[2]; /* %f0 and %f2 */
+} La_sparc32_retval;
+
+#else
+
+typedef struct La_sparc64_regs
+{
+ uint64_t lr_lreg[8]; /* %l0 through %l7 */
+ uint64_t lr_reg[6]; /* %o0 through %o5 */
+ uint64_t lr_sp; /* %o6 */
+ uint64_t lr_ra; /* %o7 */
+ double lr_fpreg[16]; /* %f0 through %f30 */
+} La_sparc64_regs;
+
+typedef struct La_sparc64_retval
+{
+ uint64_t lrv_reg[4]; /* %o0 through %o3 */
+ double lrv_fprev[4]; /* %f0 through %f8 */
+} La_sparc64_retval;
+
+#endif
+
+__BEGIN_DECLS
+
+#if __WORDSIZE == 32
+
+extern Elf32_Addr la_sparc32_gnu_pltenter (Elf32_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_sparc32_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_sparc32_gnu_pltexit (Elf32_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_sparc32_regs *__inregs,
+ La_sparc32_retval *__outregs,
+ const char *symname);
+
+#else
+
+extern Elf64_Addr la_sparc64_gnu_pltenter (Elf64_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_sparc64_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_sparc64_gnu_pltexit (Elf64_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_sparc64_regs *__inregs,
+ La_sparc64_retval *__outregs,
+ const char *symname);
+
+#endif
+
+__END_DECLS
diff --git a/libc/sysdeps/sparc/bits/mathdef.h b/libc/sysdeps/sparc/bits/mathdef.h
new file mode 100644
index 000000000..c8dcc9c93
--- /dev/null
+++ b/libc/sysdeps/sparc/bits/mathdef.h
@@ -0,0 +1,58 @@
+/* Copyright (C) 1997, 1998, 1999, 2000, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+#include <bits/wordsize.h>
+
+/* FIXME! This file describes properties of the compiler, not the machine;
+ it should not be part of libc! */
+
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
+# ifdef __GNUC__
+# if __STDC__ == 1
+
+/* In GNU or ANSI mode, gcc leaves `float' expressions as-is. */
+typedef float float_t;
+typedef double double_t;
+
+# else
+
+/* For `gcc -traditional', `float' expressions are evaluated as `double'. */
+typedef double float_t;
+typedef double double_t;
+
+# endif
+# else
+
+/* Wild guess at types for float_t and double_t. */
+typedef double float_t;
+typedef double double_t;
+
+# endif
+
+/* The values returned by `ilogb' for 0 and NaN respectively. */
+# define FP_ILOGB0 (-2147483647)
+# define FP_ILOGBNAN (2147483647)
+
+#endif /* ISO C99 */
diff --git a/libc/sysdeps/sparc/bits/string.h b/libc/sysdeps/sparc/bits/string.h
new file mode 100644
index 000000000..03f717676
--- /dev/null
+++ b/libc/sysdeps/sparc/bits/string.h
@@ -0,0 +1,26 @@
+/* Optimized, inlined string functions. SPARC version.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _STRING_H
+# error "Never use <bits/string.h> directly; include <string.h> instead."
+#endif
+
+/* sparc32 and sparc64 strchr(x, '\0') perform better than
+ __rawmemchr(x, '\0'). */
+#define _HAVE_STRING_ARCH_strchr 1
diff --git a/libc/sysdeps/sparc/dl-dtprocnum.h b/libc/sysdeps/sparc/dl-dtprocnum.h
new file mode 100644
index 000000000..55b7fd7a5
--- /dev/null
+++ b/libc/sysdeps/sparc/dl-dtprocnum.h
@@ -0,0 +1,22 @@
+/* Configuration of lookup functions. SPARC version.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Number of extra dynamic section entries for this architecture. By
+ default there are none. */
+#define DT_THISPROCNUM DT_SPARC_NUM
diff --git a/libc/sysdeps/sparc/dl-procinfo.c b/libc/sysdeps/sparc/dl-procinfo.c
new file mode 100644
index 000000000..875820fab
--- /dev/null
+++ b/libc/sysdeps/sparc/dl-procinfo.c
@@ -0,0 +1,62 @@
+/* Data for Linux/sparc version of processor capability information.
+ Copyright (C) 2002,2003,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This information must be kept in sync with the _DL_HWCAP_COUNT
+ definition in procinfo.h.
+
+ If anything should be added here check whether the size of each string
+ is still ok with the given array size.
+
+ All the #ifdefs in the definitions ar equite irritating but
+ necessary if we want to avoid duplicating the information. There
+ are three different modes:
+
+ - PROCINFO_DECL is defined. This means we are only interested in
+ declarations.
+
+ - PROCINFO_DECL is not defined:
+
+ + if SHARED is defined the file is included in an array
+ initializer. The .element = { ... } syntax is needed.
+
+ + if SHARED is not defined a normal array initialization is
+ needed.
+ */
+
+#ifndef PROCINFO_CLASS
+#define PROCINFO_CLASS
+#endif
+
+#if !defined PROCINFO_DECL && defined SHARED
+ ._dl_sparc_cap_flags
+#else
+PROCINFO_CLASS const char _dl_sparc_cap_flags[7][7]
+#endif
+#ifndef PROCINFO_DECL
+ = { "flush", "stbar", "swap", "muldiv", "v9", "ultra3", "v9v" }
+#endif
+#if !defined SHARED || defined PROCINFO_DECL
+;
+#else
+,
+#endif
+
+#undef PROCINFO_DECL
+#undef PROCINFO_CLASS
diff --git a/libc/sysdeps/sparc/dl-procinfo.h b/libc/sysdeps/sparc/dl-procinfo.h
new file mode 100644
index 000000000..dde02b556
--- /dev/null
+++ b/libc/sysdeps/sparc/dl-procinfo.h
@@ -0,0 +1,79 @@
+/* Linux/sparc version of processor capability information handling macros.
+ Copyright (C) 1999,2000,2001,2002,2003,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DL_PROCINFO_H
+#define _DL_PROCINFO_H 1
+
+#include <ldsodefs.h>
+
+#define _DL_HWCAP_COUNT 7
+
+static inline int
+__attribute__ ((unused))
+_dl_procinfo (int word)
+{
+ int i;
+
+ _dl_printf ("AT_HWCAP: ");
+
+ for (i = 0; i < _DL_HWCAP_COUNT; ++i)
+ if (word & (1 << i))
+ _dl_printf (" %s", GLRO(dl_sparc_cap_flags)[i]);
+
+ _dl_printf ("\n");
+
+ return 0;
+}
+
+static inline const char *
+__attribute__ ((unused))
+_dl_hwcap_string (int idx)
+{
+ return GLRO(dl_sparc_cap_flags)[idx];
+};
+
+static inline int
+__attribute__ ((unused, always_inline))
+_dl_string_hwcap (const char *str)
+{
+ int i;
+ for (i = 0; i < _DL_HWCAP_COUNT; i++)
+ {
+ if (strcmp (str, GLRO(dl_sparc_cap_flags) [i]) == 0)
+ return i;
+ }
+ return -1;
+};
+
+#include <bits/wordsize.h>
+#define HWCAP_IMPORTANT_V9 (__WORDSIZE == 64 ? 0 : HWCAP_SPARC_V9)
+#define HWCAP_IMPORTANT (HWCAP_IMPORTANT_V9 | HWCAP_SPARC_ULTRA3 \
+ | HWCAP_SPARC_BLKINIT)
+
+/* There are no different platforms defined. */
+#define _dl_platform_string(idx) ""
+
+/* There're no platforms to filter out. */
+#define _DL_HWCAP_PLATFORM 0
+
+#define _dl_string_platform(str) (-1)
+
+#endif /* dl-procinfo.h */
diff --git a/libc/sysdeps/sparc/dl-sysdep.h b/libc/sysdeps/sparc/dl-sysdep.h
new file mode 100644
index 000000000..2dee6b1f5
--- /dev/null
+++ b/libc/sysdeps/sparc/dl-sysdep.h
@@ -0,0 +1,24 @@
+/* System-specific settings for dynamic linker code. SPARC version.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include_next <dl-sysdep.h>
+
+/* _dl_argv cannot be attribute_relro, because _dl_start_user
+ might write into it after _dl_start returns. */
+#define DL_ARGV_NOT_RELRO 1
diff --git a/libc/sysdeps/sparc/dl-tls.h b/libc/sysdeps/sparc/dl-tls.h
new file mode 100644
index 000000000..6edf8d525
--- /dev/null
+++ b/libc/sysdeps/sparc/dl-tls.h
@@ -0,0 +1,29 @@
+/* Thread-local storage handling in the ELF dynamic linker. SPARC version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* Type used for the representation of TLS information in the GOT. */
+typedef struct
+{
+ unsigned long int ti_module;
+ unsigned long int ti_offset;
+} tls_index;
+
+
+extern void *__tls_get_addr (tls_index *ti);
diff --git a/libc/sysdeps/sparc/fpu/bits/fenv.h b/libc/sysdeps/sparc/fpu/bits/fenv.h
new file mode 100644
index 000000000..d2ef97e0e
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/bits/fenv.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+
+/* Define bits representing the exception. We use the bit positions
+ of the appropriate accrued exception bits from the FSR. */
+enum
+ {
+ FE_INVALID = (1 << 9),
+#define FE_INVALID FE_INVALID
+ FE_OVERFLOW = (1 << 8),
+#define FE_OVERFLOW FE_OVERFLOW
+ FE_UNDERFLOW = (1 << 7),
+#define FE_UNDERFLOW FE_UNDERFLOW
+ FE_DIVBYZERO = (1 << 6),
+#define FE_DIVBYZERO FE_DIVBYZERO
+ FE_INEXACT = (1 << 5)
+#define FE_INEXACT FE_INEXACT
+ };
+
+#define FE_ALL_EXCEPT \
+ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+/* The Sparc FPU supports all of the four defined rounding modes. We
+ use again the bit positions in the FPU control word as the values
+ for the appropriate macros. */
+enum
+ {
+ FE_TONEAREST = (0U << 30),
+#define FE_TONEAREST FE_TONEAREST
+ FE_TOWARDZERO = (1U << 30),
+#define FE_TOWARDZERO FE_TOWARDZERO
+ FE_UPWARD = (2U << 30),
+#define FE_UPWARD FE_UPWARD
+ FE_DOWNWARD = (3U << 30)
+#define FE_DOWNWARD FE_DOWNWARD
+ };
+
+#define __FE_ROUND_MASK (3U << 30)
+
+
+/* Type representing exception flags. */
+typedef unsigned long int fexcept_t;
+
+
+/* Type representing floating-point environment. */
+typedef unsigned long int fenv_t;
+
+/* If the default argument is used we use this value. */
+#define FE_DFL_ENV ((__const fenv_t *) -1)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exception is masked. */
+# define FE_NOMASK_ENV ((__const fenv_t *) -2)
+#endif
+
+/* For internal use only: access the fp state register. */
+#if __WORDSIZE == 64
+# define __fenv_stfsr(X) __asm__ ("stx %%fsr,%0" : "=m" (X))
+# define __fenv_ldfsr(X) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (X))
+#else
+# define __fenv_stfsr(X) __asm__ ("st %%fsr,%0" : "=m" (X))
+# define __fenv_ldfsr(X) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (X))
+#endif
diff --git a/libc/sysdeps/sparc/fpu/bits/mathinline.h b/libc/sysdeps/sparc/fpu/bits/mathinline.h
new file mode 100644
index 000000000..9dd784d12
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/bits/mathinline.h
@@ -0,0 +1,292 @@
+/* Inline math functions for SPARC.
+ Copyright (C) 1999, 2000, 2001, 2002, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#ifdef __GNUC__
+
+#if defined __USE_ISOC99 && !__GNUC_PREREQ (3, 0)
+# undef isgreater
+# undef isgreaterequal
+# undef isless
+# undef islessequal
+# undef islessgreater
+# undef isunordered
+
+# if __WORDSIZE == 32
+
+# ifndef __NO_LONG_DOUBLE_MATH
+
+# define __unordered_cmp(x, y) \
+ (__extension__ \
+ ({ unsigned __r; \
+ if (sizeof (x) == 4 && sizeof (y) == 4) \
+ { \
+ float __x = (x); float __y = (y); \
+ __asm__ ("fcmps %1,%2; st %%fsr, %0" : "=m" (__r) : "f" (__x), \
+ "f" (__y) : "cc"); \
+ } \
+ else if (sizeof (x) <= 8 && sizeof (y) <= 8) \
+ { \
+ double __x = (x); double __y = (y); \
+ __asm__ ("fcmpd\t%1,%2\n\tst\t%%fsr,%0" : "=m" (__r) : "f" (__x), \
+ "f" (__y) : "cc"); \
+ } \
+ else \
+ { \
+ long double __x = (x); long double __y = (y); \
+ extern int _Q_cmp (const long double a, const long double b); \
+ __r = _Q_cmp (__x, __y) << 10; \
+ } \
+ __r; }))
+
+# else
+
+# define __unordered_cmp(x, y) \
+ (__extension__ \
+ ({ unsigned __r; \
+ if (sizeof (x) == 4 && sizeof (y) == 4) \
+ { \
+ float __x = (x); float __y = (y); \
+ __asm__ ("fcmps %1,%2; st %%fsr, %0" : "=m" (__r) : "f" (__x), \
+ "f" (__y) : "cc"); \
+ } \
+ else \
+ { \
+ double __x = (x); double __y = (y); \
+ __asm__ ("fcmpd\t%1,%2\n\tst\t%%fsr,%0" : "=m" (__r) : "f" (__x), \
+ "f" (__y) : "cc"); \
+ } \
+ __r; }))
+
+# endif
+
+# define isgreater(x, y) ((__unordered_cmp (x, y) & (3 << 10)) == (2 << 10))
+# define isgreaterequal(x, y) ((__unordered_cmp (x, y) & (1 << 10)) == 0)
+# define isless(x, y) ((__unordered_cmp (x, y) & (3 << 10)) == (1 << 10))
+# define islessequal(x, y) ((__unordered_cmp (x, y) & (2 << 10)) == 0)
+# define islessgreater(x, y) (((__unordered_cmp (x, y) + (1 << 10)) & (2 << 10)) != 0)
+# define isunordered(x, y) ((__unordered_cmp (x, y) & (3 << 10)) == (3 << 10))
+
+# else /* sparc64 */
+
+# define __unordered_v9cmp(x, y, op, qop) \
+ (__extension__ \
+ ({ unsigned __r; \
+ if (sizeof (x) == 4 && sizeof (y) == 4) \
+ { \
+ float __x = (x); float __y = (y); \
+ __asm__ ("fcmps\t%%fcc3,%1,%2\n\tmov" op "\t%%fcc3,1,%0" \
+ : "=r" (__r) : "f" (__x), "f" (__y), "0" (0) : "cc"); \
+ } \
+ else if (sizeof (x) <= 8 && sizeof (y) <= 8) \
+ { \
+ double __x = (x); double __y = (y); \
+ __asm__ ("fcmpd\t%%fcc3,%1,%2\n\tmov" op "\t%%fcc3,1,%0" \
+ : "=r" (__r) : "f" (__x), "f" (__y), "0" (0) : "cc"); \
+ } \
+ else \
+ { \
+ long double __x = (x); long double __y = (y); \
+ extern int _Qp_cmp (const long double *a, const long double *b); \
+ __r = qop; \
+ } \
+ __r; }))
+
+# define isgreater(x, y) __unordered_v9cmp(x, y, "g", _Qp_cmp (&__x, &__y) == 2)
+# define isgreaterequal(x, y) __unordered_v9cmp(x, y, "ge", (_Qp_cmp (&__x, &__y) & 1) == 0)
+# define isless(x, y) __unordered_v9cmp(x, y, "l", _Qp_cmp (&__x, &__y) == 1)
+# define islessequal(x, y) __unordered_v9cmp(x, y, "le", (_Qp_cmp (&__x, &__y) & 2) == 0)
+# define islessgreater(x, y) __unordered_v9cmp(x, y, "lg", ((_Qp_cmp (&__x, &__y) + 1) & 2) != 0)
+# define isunordered(x, y) __unordered_v9cmp(x, y, "u", _Qp_cmp (&__x, &__y) == 3)
+
+# endif /* sparc64 */
+
+#endif /* __USE_ISOC99 */
+
+#if (!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) && defined __OPTIMIZE__
+
+# ifdef __cplusplus
+# define __MATH_INLINE __inline
+# else
+# define __MATH_INLINE extern __inline
+# endif /* __cplusplus */
+
+/* The gcc, version 2.7 or below, has problems with all this inlining
+ code. So disable it for this version of the compiler. */
+# if __GNUC_PREREQ (2, 8)
+
+# ifdef __USE_ISOC99
+
+/* Test for negative number. Used in the signbit() macro. */
+__MATH_INLINE int
+__NTH (__signbitf (float __x))
+{
+ __extension__ union { float __f; int __i; } __u = { __f: __x };
+ return __u.__i < 0;
+}
+
+# if __WORDSIZE == 32
+
+__MATH_INLINE int
+__NTH (__signbit (double __x))
+{
+ __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
+ return __u.__i[0] < 0;
+}
+
+# ifndef __NO_LONG_DOUBLE_MATH
+__MATH_INLINE int
+__NTH (__signbitl (long double __x))
+{
+ __extension__ union { long double __l; int __i[4]; } __u = { __l: __x };
+ return __u.__i[0] < 0;
+}
+# else
+__MATH_INLINE int
+__NTH (__signbitl (long double __x))
+{
+ return __signbit ((double)__x);
+}
+# endif
+
+# else /* sparc64 */
+
+__MATH_INLINE int
+__NTH (__signbit (double __x))
+{
+ __extension__ union { double __d; long int __i; } __u = { __d: __x };
+ return __u.__i < 0;
+}
+
+__MATH_INLINE int
+__NTH (__signbitl (long double __x))
+{
+ __extension__ union { long double __l; long int __i[2]; } __u = { __l: __x };
+ return __u.__i[0] < 0;
+}
+
+# endif /* sparc64 */
+
+# endif /* __USE_ISOC99 */
+
+# if !defined __NO_MATH_INLINES && !__GNUC_PREREQ (3, 2)
+
+__MATH_INLINE double
+__NTH (sqrt (double __x))
+{
+ register double __r;
+ __asm ("fsqrtd %1,%0" : "=f" (__r) : "f" (__x));
+ return __r;
+}
+
+__MATH_INLINE float
+__NTH (sqrtf (float __x))
+{
+ register float __r;
+ __asm ("fsqrts %1,%0" : "=f" (__r) : "f" (__x));
+ return __r;
+}
+
+# if __WORDSIZE == 64
+__MATH_INLINE long double
+__NTH (sqrtl (long double __x))
+{
+ long double __r;
+ extern void _Qp_sqrt (long double *, __const__ long double *);
+ _Qp_sqrt (&__r, &__x);
+ return __r;
+}
+# elif !defined __NO_LONG_DOUBLE_MATH
+__MATH_INLINE long double
+sqrtl (long double __x) __THROW
+{
+ extern long double _Q_sqrt (__const__ long double);
+ return _Q_sqrt (__x);
+}
+# endif /* sparc64 */
+
+# endif /* !__NO_MATH_INLINES && !GCC 3.2+ */
+
+/* This code is used internally in the GNU libc. */
+# ifdef __LIBC_INTERNAL_MATH_INLINES
+__MATH_INLINE double
+__ieee754_sqrt (double __x)
+{
+ register double __r;
+ __asm ("fsqrtd %1,%0" : "=f" (__r) : "f" (__x));
+ return __r;
+}
+
+__MATH_INLINE float
+__ieee754_sqrtf (float __x)
+{
+ register float __r;
+ __asm ("fsqrts %1,%0" : "=f" (__r) : "f" (__x));
+ return __r;
+}
+
+# if __WORDSIZE == 64
+__MATH_INLINE long double
+__ieee754_sqrtl (long double __x)
+{
+ long double __r;
+ extern void _Qp_sqrt (long double *, __const__ long double *);
+ _Qp_sqrt(&__r, &__x);
+ return __r;
+}
+# elif !defined __NO_LONG_DOUBLE_MATH
+__MATH_INLINE long double
+__ieee754_sqrtl (long double __x)
+{
+ extern long double _Q_sqrt (__const__ long double);
+ return _Q_sqrt (__x);
+}
+# endif /* sparc64 */
+# endif /* __LIBC_INTERNAL_MATH_INLINES */
+# endif /* gcc 2.8+ */
+
+# ifdef __USE_ISOC99
+
+# ifndef __NO_MATH_INLINES
+
+__MATH_INLINE double __NTH (fdim (double __x, double __y));
+__MATH_INLINE double
+__NTH (fdim (double __x, double __y))
+{
+ return __x <= __y ? 0 : __x - __y;
+}
+
+__MATH_INLINE float __NTH (fdimf (float __x, float __y));
+__MATH_INLINE float
+__NTH (fdimf (float __x, float __y))
+{
+ return __x <= __y ? 0 : __x - __y;
+}
+
+# endif /* !__NO_MATH_INLINES */
+# endif /* __USE_ISOC99 */
+#endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
+#endif /* __GNUC__ */
diff --git a/libc/sysdeps/sparc/fpu/fclrexcpt.c b/libc/sysdeps/sparc/fpu/fclrexcpt.c
new file mode 100644
index 000000000..7e860812a
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/fclrexcpt.c
@@ -0,0 +1,43 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <shlib-compat.h>
+
+int
+__feclearexcept (int excepts)
+{
+ fenv_t tmp;
+
+ __fenv_stfsr (tmp);
+
+ tmp &= ~(excepts & FE_ALL_EXCEPT);
+
+ __fenv_ldfsr (tmp);
+
+ /* Success. */
+ return 0;
+}
+
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feclearexcept, __old_feclearexcept)
+compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
diff --git a/libc/sysdeps/sparc/fpu/fedisblxcpt.c b/libc/sysdeps/sparc/fpu/fedisblxcpt.c
new file mode 100644
index 000000000..7f28551a7
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/fedisblxcpt.c
@@ -0,0 +1,36 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fedisableexcept (int excepts)
+{
+ fenv_t new_exc, old_exc;
+
+ __fenv_stfsr (new_exc);
+
+ old_exc = (new_exc >> 18) & FE_ALL_EXCEPT;
+ new_exc &= ~(((fenv_t)excepts & FE_ALL_EXCEPT) << 18);
+
+ __fenv_ldfsr (new_exc);
+
+ return old_exc;
+}
diff --git a/libc/sysdeps/sparc/fpu/feenablxcpt.c b/libc/sysdeps/sparc/fpu/feenablxcpt.c
new file mode 100644
index 000000000..82f285749
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/feenablxcpt.c
@@ -0,0 +1,36 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+feenableexcept (int excepts)
+{
+ fenv_t new_exc, old_exc;
+
+ __fenv_stfsr (new_exc);
+
+ old_exc = (new_exc >> 18) & FE_ALL_EXCEPT;
+ new_exc |= (((fenv_t)excepts & FE_ALL_EXCEPT) << 18);
+
+ __fenv_ldfsr (new_exc);
+
+ return old_exc;
+}
diff --git a/libc/sysdeps/sparc/fpu/fegetenv.c b/libc/sysdeps/sparc/fpu/fegetenv.c
new file mode 100644
index 000000000..36486f597
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/fegetenv.c
@@ -0,0 +1,37 @@
+/* Store current floating-point environment.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <shlib-compat.h>
+
+int
+__fegetenv (fenv_t *envp)
+{
+ __fenv_stfsr (*envp);
+
+ /* Success. */
+ return 0;
+}
+
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fegetenv, __old_fegetenv)
+compat_symbol (libm, __old_fegetenv, fegetenv, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __fegetenv, fegetenv, GLIBC_2_2);
diff --git a/libc/sysdeps/sparc/fpu/fegetexcept.c b/libc/sysdeps/sparc/fpu/fegetexcept.c
new file mode 100644
index 000000000..5b136b301
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/fegetexcept.c
@@ -0,0 +1,30 @@
+/* Get enabled floating-point exceptions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetexcept (void)
+{
+ fenv_t exc;
+ __fenv_stfsr (exc);
+
+ return (exc >> 18) & FE_ALL_EXCEPT;
+}
diff --git a/libc/sysdeps/sparc/fpu/fegetround.c b/libc/sysdeps/sparc/fpu/fegetround.c
new file mode 100644
index 000000000..ffe1d3549
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/fegetround.c
@@ -0,0 +1,30 @@
+/* Return current rounding direction.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetround (void)
+{
+ fenv_t tmp;
+
+ __fenv_stfsr (tmp);
+
+ return tmp & __FE_ROUND_MASK;
+}
diff --git a/libc/sysdeps/sparc/fpu/feholdexcpt.c b/libc/sysdeps/sparc/fpu/feholdexcpt.c
new file mode 100644
index 000000000..729637ad1
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/feholdexcpt.c
@@ -0,0 +1,36 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 1997, 1998, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ fenv_t tmp;
+
+ __fenv_stfsr (*envp);
+
+ /* Set all exceptions to non-stop. */
+ tmp = *envp & ~(0x1f << 23);
+
+ __fenv_ldfsr (tmp);
+
+ return 0;
+}
+libm_hidden_def (feholdexcept)
diff --git a/libc/sysdeps/sparc/fpu/fesetenv.c b/libc/sysdeps/sparc/fpu/fesetenv.c
new file mode 100644
index 000000000..89e97a7d5
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/fesetenv.c
@@ -0,0 +1,55 @@
+/* Install given floating-point environment.
+ Copyright (C) 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <shlib-compat.h>
+
+int
+__fesetenv (const fenv_t *envp)
+{
+ fenv_t dummy;
+
+ /* Put these constants in memory explicitly, so as to cope with a
+ -fPIC bug as of gcc 970624. Making them automatic is quicker
+ than loading up the pic register in this instance. */
+
+ if (envp == FE_DFL_ENV)
+ {
+ dummy = 0;
+ envp = &dummy;
+ }
+ else if (envp == FE_NOMASK_ENV)
+ {
+ dummy = 0x1f << 23;
+ envp = &dummy;
+ }
+
+ __fenv_ldfsr (*envp);
+
+ /* Success. */
+ return 0;
+}
+
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fesetenv, __old_fesetenv)
+compat_symbol (libm, __old_fesetenv, fesetenv, GLIBC_2_1);
+#endif
+
+libm_hidden_ver (__fesetenv, fesetenv)
+versioned_symbol (libm, __fesetenv, fesetenv, GLIBC_2_2);
diff --git a/libc/sysdeps/sparc/fpu/fesetround.c b/libc/sysdeps/sparc/fpu/fesetround.c
new file mode 100644
index 000000000..e3b441cd5
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/fesetround.c
@@ -0,0 +1,38 @@
+/* Set current rounding direction.
+ Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fesetround (int round)
+{
+ fenv_t tmp;
+
+ if ((round & ~__FE_ROUND_MASK) != 0)
+ /* ROUND is no valid rounding mode. */
+ return 1;
+
+ __fenv_stfsr (tmp);
+ tmp &= ~__FE_ROUND_MASK;
+ tmp |= round;
+ __fenv_ldfsr (tmp);
+
+ return 0;
+}
+libm_hidden_def (fesetround)
diff --git a/libc/sysdeps/sparc/fpu/feupdateenv.c b/libc/sysdeps/sparc/fpu/feupdateenv.c
new file mode 100644
index 000000000..b2615379b
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/feupdateenv.c
@@ -0,0 +1,49 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <shlib-compat.h>
+
+int
+__feupdateenv (const fenv_t *envp)
+{
+ fexcept_t tmp;
+
+ /* Save current exceptions. */
+ __fenv_stfsr (tmp);
+ tmp &= FE_ALL_EXCEPT;
+
+ /* Install new environment. */
+ fesetenv (envp);
+
+ /* Raise the safed exception. Incidently for us the implementation
+ defined format of the values in objects of type fexcept_t is the
+ same as the ones specified using the FE_* constants. */
+ feraiseexcept ((int) tmp);
+
+ /* Success. */
+ return 0;
+}
+
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feupdateenv, __old_feupdateenv)
+compat_symbol (libm, __old_feupdateenv, feupdateenv, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __feupdateenv, feupdateenv, GLIBC_2_2);
diff --git a/libc/sysdeps/sparc/fpu/fgetexcptflg.c b/libc/sysdeps/sparc/fpu/fgetexcptflg.c
new file mode 100644
index 000000000..4fdbd3c59
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/fgetexcptflg.c
@@ -0,0 +1,42 @@
+/* Store current representation for exceptions.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <shlib-compat.h>
+
+int
+__fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ fexcept_t tmp;
+
+ /* Get the current exceptions. */
+ __fenv_stfsr (tmp);
+
+ *flagp = tmp & excepts & FE_ALL_EXCEPT;
+
+ /* Success. */
+ return 0;
+}
+
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fegetexceptflag, __old_fegetexceptflag)
+compat_symbol (libm, __old_fegetexceptflag, fegetexceptflag, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __fegetexceptflag, fegetexceptflag, GLIBC_2_2);
diff --git a/libc/sysdeps/sparc/fpu/fpu_control.h b/libc/sysdeps/sparc/fpu/fpu_control.h
new file mode 100644
index 000000000..b29734ce2
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/fpu_control.h
@@ -0,0 +1,73 @@
+/* FPU control word bits. SPARC version.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H 1
+
+
+#include <features.h>
+#include <bits/wordsize.h>
+
+/* masking of interrupts */
+#define _FPU_MASK_IM 0x08000000
+#define _FPU_MASK_OM 0x04000000
+#define _FPU_MASK_UM 0x02000000
+#define _FPU_MASK_ZM 0x01000000
+#define _FPU_MASK_PM 0x00800000
+
+/* precision control */
+#define _FPU_EXTENDED 0x00000000 /* RECOMMENDED */
+#define _FPU_DOUBLE 0x20000000
+#define _FPU_80BIT 0x30000000
+#define _FPU_SINGLE 0x10000000 /* DO NOT USE */
+
+/* rounding control / Sparc */
+#define _FPU_RC_DOWN 0xc0000000
+#define _FPU_RC_UP 0x80000000
+#define _FPU_RC_ZERO 0x40000000
+#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
+
+#define _FPU_RESERVED 0x30300000 /* Reserved bits in cw */
+
+
+/* Now two recommended cw */
+
+/* Linux and IEEE default:
+ - extended precision
+ - rounding to nearest
+ - no exceptions */
+#define _FPU_DEFAULT 0x0
+#define _FPU_IEEE 0x0
+
+/* Type of the control word. */
+typedef unsigned long int fpu_control_t;
+
+#if __WORDSIZE == 64
+# define _FPU_GETCW(cw) __asm__ ("stx %%fsr,%0" : "=m" (*&cw))
+# define _FPU_SETCW(cw) __asm__ ("ldx %0,%%fsr" : : "m" (*&cw))
+#else
+# define _FPU_GETCW(cw) __asm__ ("st %%fsr,%0" : "=m" (*&cw))
+# define _FPU_SETCW(cw) __asm__ ("ld %0,%%fsr" : : "m" (*&cw))
+#endif
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* fpu_control.h */
diff --git a/libc/sysdeps/sparc/fpu/fraiseexcpt.c b/libc/sysdeps/sparc/fpu/fraiseexcpt.c
new file mode 100644
index 000000000..cbb8be80e
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/fraiseexcpt.c
@@ -0,0 +1,91 @@
+/* Raise given exceptions.
+ Copyright (C) 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <float.h>
+#include <math.h>
+#include <shlib-compat.h>
+
+int
+__feraiseexcept (int excepts)
+{
+ static const struct {
+ double zero, one, max, min, sixteen, pi;
+ } c = {
+ 0.0, 1.0, DBL_MAX, DBL_MIN, 16.0, M_PI
+ };
+ double d;
+
+ /* Raise exceptions represented by EXPECTS. But we must raise only
+ one signal at a time. It is important the if the overflow/underflow
+ exception and the inexact exception are given at the same time,
+ the overflow/underflow exception follows the inexact exception. */
+
+ /* First: invalid exception. */
+ if ((FE_INVALID & excepts) != 0)
+ {
+ /* One example of a invalid operation is 0/0. */
+ __asm ("" : "=e" (d) : "0" (c.zero));
+ d /= c.zero;
+ __asm __volatile ("" : : "e" (d));
+ }
+
+ /* Next: division by zero. */
+ if ((FE_DIVBYZERO & excepts) != 0)
+ {
+ __asm ("" : "=e" (d) : "0" (c.one));
+ d /= c.zero;
+ __asm __volatile ("" : : "e" (d));
+ }
+
+ /* Next: overflow. */
+ if ((FE_OVERFLOW & excepts) != 0)
+ {
+ __asm ("" : "=e" (d) : "0" (c.max));
+ d *= d;
+ __asm __volatile ("" : : "e" (d));
+ }
+
+ /* Next: underflow. */
+ if ((FE_UNDERFLOW & excepts) != 0)
+ {
+ __asm ("" : "=e" (d) : "0" (c.min));
+ d /= c.sixteen;
+ __asm __volatile ("" : : "e" (d));
+ }
+
+ /* Last: inexact. */
+ if ((FE_INEXACT & excepts) != 0)
+ {
+ __asm ("" : "=e" (d) : "0" (c.one));
+ d /= c.pi;
+ __asm __volatile ("" : : "e" (d));
+ }
+
+ /* Success. */
+ return 0;
+}
+
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feraiseexcept, __old_feraiseexcept)
+compat_symbol (libm, __old_feraiseexcept, feraiseexcept, GLIBC_2_1);
+#endif
+
+libm_hidden_ver (__feraiseexcept, feraiseexcept)
+versioned_symbol (libm, __feraiseexcept, feraiseexcept, GLIBC_2_2);
diff --git a/libc/sysdeps/sparc/fpu/fsetexcptflg.c b/libc/sysdeps/sparc/fpu/fsetexcptflg.c
new file mode 100644
index 000000000..3e1761dbd
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/fsetexcptflg.c
@@ -0,0 +1,45 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <math.h>
+#include <shlib-compat.h>
+
+int
+__fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fenv_t tmp;
+
+ __fenv_stfsr (tmp);
+
+ tmp &= ~(excepts & FE_ALL_EXCEPT);
+ tmp |= *flagp & excepts & FE_ALL_EXCEPT;
+
+ __fenv_ldfsr (tmp);
+
+ /* Success. */
+ return 0;
+}
+
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fesetexceptflag, __old_fesetexceptflag)
+compat_symbol (libm, __old_fesetexceptflag, fesetexceptflag, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __fesetexceptflag, fesetexceptflag, GLIBC_2_2);
diff --git a/libc/sysdeps/sparc/fpu/ftestexcept.c b/libc/sysdeps/sparc/fpu/ftestexcept.c
new file mode 100644
index 000000000..abfaa3299
--- /dev/null
+++ b/libc/sysdeps/sparc/fpu/ftestexcept.c
@@ -0,0 +1,30 @@
+/* Test exception in current environment.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fetestexcept (int excepts)
+{
+ fenv_t tmp;
+
+ __fenv_stfsr (tmp);
+
+ return tmp & excepts & FE_ALL_EXCEPT;
+}
diff --git a/libc/sysdeps/sparc/gccframe.h b/libc/sysdeps/sparc/gccframe.h
new file mode 100644
index 000000000..236baab14
--- /dev/null
+++ b/libc/sysdeps/sparc/gccframe.h
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. sparc version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FIRST_PSEUDO_REGISTER 101
+
+#include <sysdeps/generic/gccframe.h>
diff --git a/libc/sysdeps/sparc/memusage.h b/libc/sysdeps/sparc/memusage.h
new file mode 100644
index 000000000..35a5d7342
--- /dev/null
+++ b/libc/sysdeps/sparc/memusage.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("%sp"); stack_ptr; })
+
+#include <sysdeps/generic/memusage.h>
diff --git a/libc/sysdeps/sparc/sparc32/Implies b/libc/sysdeps/sparc/sparc32/Implies
new file mode 100644
index 000000000..436436a65
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/Implies
@@ -0,0 +1,6 @@
+wordsize-32
+# SPARC uses IEEE 754 floating point.
+ieee754/ldbl-128
+ieee754/dbl-64
+ieee754/flt-32
+sparc/sparc32/soft-fp
diff --git a/libc/sysdeps/sparc/sparc32/Makefile b/libc/sysdeps/sparc/sparc32/Makefile
new file mode 100644
index 000000000..ed4fba741
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/Makefile
@@ -0,0 +1,53 @@
+# Copyright (C) 1991,92,93,94,95,96,97,98,2000 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifeq ($(subdir),gnulib)
+sysdep_routines = dotmul umul $(divrem) alloca
+endif # gnulib
+
+# We distribute these files, even though they are generated,
+# so as to avoid the need for a functioning m4 to build the library.
+divrem := sdiv udiv rem urem
+
++divrem-NAME-sdiv := div
++divrem-NAME-udiv := udiv
++divrem-NAME-rem := rem
++divrem-NAME-urem := urem
++divrem-NAME = $(+divrem-NAME-$(basename $(notdir $@)))
++divrem-OP-div := div
++divrem-OP-udiv := div
++divrem-OP-rem := rem
++divrem-OP-urem := rem
++divrem-S-div := true
++divrem-S-rem := true
++divrem-S-udiv := false
++divrem-S-urem := false
+$(divrem:%=$(sysdep_dir)/sparc/sparc32/%.S): $(sysdep_dir)/sparc/sparc32/divrem.m4
+ (echo "define(NAME,\`.$(+divrem-NAME)')\
+ define(OP,\`$(+divrem-OP-$(+divrem-NAME))')\
+ define(S,\`$(+divrem-S-$(+divrem-NAME))')\
+ /* This file is generated from divrem.m4; DO NOT EDIT! */"; \
+ cat $<) | $(M4) > $@-tmp
+# Make it unwritable so noone will edit it by mistake.
+ -chmod a-w $@-tmp
+ mv -f $@-tmp $@
+ifeq ($(with-cvs),yes)
+ test ! -d CVS || cvs commit -m'Regenerated from $<' $@
+endif
+
+sysdep-realclean := $(sysdep-realclean) $(divrem:%=sysdeps/sparc/sparc32/%.S)
diff --git a/libc/sysdeps/sparc/sparc32/Versions b/libc/sysdeps/sparc/sparc32/Versions
new file mode 100644
index 000000000..aa36082e9
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/Versions
@@ -0,0 +1,5 @@
+libc {
+ GLIBC_2.0 {
+ .div; .mul; .rem; .udiv; .umul; .urem;
+ }
+}
diff --git a/libc/sysdeps/sparc/sparc32/__longjmp.S b/libc/sysdeps/sparc/sparc32/__longjmp.S
new file mode 100644
index 000000000..a5453b429
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/__longjmp.S
@@ -0,0 +1,97 @@
+/* Copyright (C) 1991, 1993, 1996, 1997, 1998, 1999, 2000, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include <jmpbuf-offsets.h>
+#define ENV(base,reg) [%base + (reg * 4)]
+#define ST_FLUSH_WINDOWS 3
+#define RW_FP [%fp + 0x48]
+
+ENTRY(__longjmp)
+ /* Store our arguments in global registers so we can still
+ use them while unwinding frames and their register windows. */
+
+ ld ENV(o0,JB_FP), %g3 /* Cache target FP in register %g3. */
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (%g3, %g3, %g4)
+#endif
+ mov %o0, %g1 /* ENV in %g1 */
+ orcc %o1, %g0, %g2 /* VAL in %g2 */
+ be,a 0f /* Branch if zero; else skip delay slot. */
+ mov 1, %g2 /* Delay slot only hit if zero: VAL = 1. */
+0:
+ xor %fp, %g3, %o0
+ add %fp, 512, %o1
+ andncc %o0, 4095, %o0
+ bne LOC(thread)
+ cmp %o1, %g3
+ bl LOC(thread)
+
+ /* Now we will loop, unwinding the register windows up the stack
+ until the restored %fp value matches the target value in %g3. */
+
+LOC(loop):
+ cmp %fp, %g3 /* Have we reached the target frame? */
+ bl,a LOC(loop) /* Loop while current fp is below target. */
+ restore /* Unwind register window in delay slot. */
+ be,a LOC(found) /* Better have hit it exactly. */
+ ld ENV(g1,JB_SP), %o0 /* Delay slot: extract target SP. */
+
+LOC(thread):
+ /*
+ * Do a "flush register windows trap". The trap handler in the
+ * kernel writes all the register windows to their stack slots, and
+ * marks them all as invalid (needing to be sucked up from the
+ * stack when used). This ensures that all information needed to
+ * unwind to these callers is in memory, not in the register
+ * windows.
+ */
+ ta ST_FLUSH_WINDOWS
+#ifdef PTR_DEMANGLE
+ ld ENV(g1,JB_PC), %g5 /* Set return PC. */
+ ld ENV(g1,JB_SP), %g1 /* Set saved SP on restore below. */
+ PTR_DEMANGLE2 (%o7, %g5, %g4)
+ PTR_DEMANGLE2 (%fp, %g1, %g4)
+#else
+ ld ENV(g1,JB_PC), %o7 /* Set return PC. */
+ ld ENV(g1,JB_SP), %fp /* Set saved SP on restore below. */
+#endif
+ sub %fp, 64, %sp /* Allocate a register frame. */
+ st %g3, RW_FP /* Set saved FP on restore below. */
+ retl
+ restore %g2, 0, %o0 /* Restore values from above register frame. */
+
+LOC(found):
+ /* We have unwound register windows so %fp matches the target. */
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE2 (%sp, %o0, %g4)
+#else
+ mov %o0, %sp /* OK, install new SP. */
+#endif
+
+LOC(sp_ok):
+ ld ENV(g1,JB_PC), %o0 /* Extract target return PC. */
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE2 (%o0, %o0, %g4)
+#endif
+ jmp %o0 + 8 /* Return there. */
+ mov %g2, %o0 /* Delay slot: set return value. */
+
+END(__longjmp)
diff --git a/libc/sysdeps/sparc/sparc32/add_n.S b/libc/sysdeps/sparc/sparc32/add_n.S
new file mode 100644
index 000000000..0db7c650b
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/add_n.S
@@ -0,0 +1,238 @@
+! SPARC __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+! sum in a third limb vector.
+!
+! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+!
+! This file is part of the GNU MP Library.
+!
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at your
+! option) any later version.
+!
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+! License for more details.
+!
+! You should have received a copy of the GNU Lesser General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+#define RES_PTR %o0
+#define S1_PTR %o1
+#define S2_PTR %o2
+#define SIZE %o3
+
+#include <sysdep.h>
+
+ENTRY(__mpn_add_n)
+ xor S2_PTR,RES_PTR,%g1
+ andcc %g1,4,%g0
+ bne LOC(1) ! branch if alignment differs
+ nop
+! ** V1a **
+LOC(0): andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
+ be LOC(v1) ! if no, branch
+ nop
+/* Add least significant limb separately to align RES_PTR and S2_PTR */
+ ld [S1_PTR],%g4
+ add S1_PTR,4,S1_PTR
+ ld [S2_PTR],%g2
+ add S2_PTR,4,S2_PTR
+ add SIZE,-1,SIZE
+ addcc %g4,%g2,%o4
+ st %o4,[RES_PTR]
+ add RES_PTR,4,RES_PTR
+LOC(v1):
+ addx %g0,%g0,%o4 ! save cy in register
+ cmp SIZE,2 ! if SIZE < 2 ...
+ bl LOC(end2) ! ... branch to tail code
+ subcc %g0,%o4,%g0 ! restore cy
+
+ ld [S1_PTR+0],%g4
+ addcc SIZE,-10,SIZE
+ ld [S1_PTR+4],%g1
+ ldd [S2_PTR+0],%g2
+ blt LOC(fin1)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+LOC(loop1):
+ addxcc %g4,%g2,%o4
+ ld [S1_PTR+8],%g4
+ addxcc %g1,%g3,%o5
+ ld [S1_PTR+12],%g1
+ ldd [S2_PTR+8],%g2
+ std %o4,[RES_PTR+0]
+ addxcc %g4,%g2,%o4
+ ld [S1_PTR+16],%g4
+ addxcc %g1,%g3,%o5
+ ld [S1_PTR+20],%g1
+ ldd [S2_PTR+16],%g2
+ std %o4,[RES_PTR+8]
+ addxcc %g4,%g2,%o4
+ ld [S1_PTR+24],%g4
+ addxcc %g1,%g3,%o5
+ ld [S1_PTR+28],%g1
+ ldd [S2_PTR+24],%g2
+ std %o4,[RES_PTR+16]
+ addxcc %g4,%g2,%o4
+ ld [S1_PTR+32],%g4
+ addxcc %g1,%g3,%o5
+ ld [S1_PTR+36],%g1
+ ldd [S2_PTR+32],%g2
+ std %o4,[RES_PTR+24]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ add S1_PTR,32,S1_PTR
+ add S2_PTR,32,S2_PTR
+ add RES_PTR,32,RES_PTR
+ bge LOC(loop1)
+ subcc %g0,%o4,%g0 ! restore cy
+
+LOC(fin1):
+ addcc SIZE,8-2,SIZE
+ blt LOC(end1)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+LOC(loope1):
+ addxcc %g4,%g2,%o4
+ ld [S1_PTR+8],%g4
+ addxcc %g1,%g3,%o5
+ ld [S1_PTR+12],%g1
+ ldd [S2_PTR+8],%g2
+ std %o4,[RES_PTR+0]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-2,SIZE
+ add S1_PTR,8,S1_PTR
+ add S2_PTR,8,S2_PTR
+ add RES_PTR,8,RES_PTR
+ bge LOC(loope1)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(end1):
+ addxcc %g4,%g2,%o4
+ addxcc %g1,%g3,%o5
+ std %o4,[RES_PTR+0]
+ addx %g0,%g0,%o4 ! save cy in register
+
+ andcc SIZE,1,%g0
+ be LOC(ret1)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+ ld [S1_PTR+8],%g4
+ ld [S2_PTR+8],%g2
+ addxcc %g4,%g2,%o4
+ st %o4,[RES_PTR+8]
+
+LOC(ret1):
+ retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+LOC(1): xor S1_PTR,RES_PTR,%g1
+ andcc %g1,4,%g0
+ bne LOC(2)
+ nop
+! ** V1b **
+ mov S2_PTR,%g1
+ mov S1_PTR,S2_PTR
+ b LOC(0)
+ mov %g1,S1_PTR
+
+! ** V2 **
+/* If we come here, the alignment of S1_PTR and RES_PTR as well as the
+ alignment of S2_PTR and RES_PTR differ. Since there are only two ways
+ things can be aligned (that we care about) we now know that the alignment
+ of S1_PTR and S2_PTR are the same. */
+
+LOC(2): cmp SIZE,1
+ be LOC(jone)
+ nop
+ andcc S1_PTR,4,%g0 ! S1_PTR unaligned? Side effect: cy=0
+ be LOC(v2) ! if no, branch
+ nop
+/* Add least significant limb separately to align S1_PTR and S2_PTR */
+ ld [S1_PTR],%g4
+ add S1_PTR,4,S1_PTR
+ ld [S2_PTR],%g2
+ add S2_PTR,4,S2_PTR
+ add SIZE,-1,SIZE
+ addcc %g4,%g2,%o4
+ st %o4,[RES_PTR]
+ add RES_PTR,4,RES_PTR
+
+LOC(v2):
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ blt LOC(fin2)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+LOC(loop2):
+ ldd [S1_PTR+0],%g2
+ ldd [S2_PTR+0],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+0]
+ addxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+4]
+ ldd [S1_PTR+8],%g2
+ ldd [S2_PTR+8],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+8]
+ addxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+12]
+ ldd [S1_PTR+16],%g2
+ ldd [S2_PTR+16],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+16]
+ addxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+20]
+ ldd [S1_PTR+24],%g2
+ ldd [S2_PTR+24],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+24]
+ addxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+28]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ add S1_PTR,32,S1_PTR
+ add S2_PTR,32,S2_PTR
+ add RES_PTR,32,RES_PTR
+ bge LOC(loop2)
+ subcc %g0,%o4,%g0 ! restore cy
+
+LOC(fin2):
+ addcc SIZE,8-2,SIZE
+ blt LOC(end2)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(loope2):
+ ldd [S1_PTR+0],%g2
+ ldd [S2_PTR+0],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+0]
+ addxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+4]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-2,SIZE
+ add S1_PTR,8,S1_PTR
+ add S2_PTR,8,S2_PTR
+ add RES_PTR,8,RES_PTR
+ bge LOC(loope2)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(end2):
+ andcc SIZE,1,%g0
+ be LOC(ret2)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+LOC(jone):
+ ld [S1_PTR],%g4
+ ld [S2_PTR],%g2
+ addxcc %g4,%g2,%o4
+ st %o4,[RES_PTR]
+
+LOC(ret2):
+ retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+END(__mpn_add_n)
diff --git a/libc/sysdeps/sparc/sparc32/addmul_1.S b/libc/sysdeps/sparc/sparc32/addmul_1.S
new file mode 100644
index 000000000..3eab4e68e
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/addmul_1.S
@@ -0,0 +1,147 @@
+! SPARC __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+! the result to a second limb vector.
+!
+! Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+!
+! This file is part of the GNU MP Library.
+!
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at your
+! option) any later version.
+!
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+! License for more details.
+!
+! You should have received a copy of the GNU Lesser General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! RES_PTR o0
+! S1_PTR o1
+! SIZE o2
+! S2_LIMB o3
+
+#include <sysdep.h>
+
+ENTRY(__mpn_addmul_1)
+ ! Make S1_PTR and RES_PTR point at the end of their blocks
+ ! and put (- 4 x SIZE) in index/loop counter.
+ sll %o2,2,%o2
+ add %o0,%o2,%o4 ! RES_PTR in o4 since o0 is retval
+ add %o1,%o2,%o1
+ sub %g0,%o2,%o2
+
+ cmp %o3,0xfff
+ bgu LOC(large)
+ nop
+
+ ld [%o1+%o2],%o5
+ mov 0,%o0
+ b LOC(0)
+ add %o4,-4,%o4
+LOC(loop0):
+ addcc %o5,%g1,%g1
+ ld [%o1+%o2],%o5
+ addx %o0,%g0,%o0
+ st %g1,[%o4+%o2]
+LOC(0): wr %g0,%o3,%y
+ sra %o5,31,%g2
+ and %o3,%g2,%g2
+ andcc %g1,0,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,0,%g1
+ sra %g1,20,%g4
+ sll %g1,12,%g1
+ rd %y,%g3
+ srl %g3,20,%g3
+ or %g1,%g3,%g1
+
+ addcc %g1,%o0,%g1
+ addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
+ addcc %o2,4,%o2 ! loop counter
+ bne LOC(loop0)
+ ld [%o4+%o2],%o5
+
+ addcc %o5,%g1,%g1
+ addx %o0,%g0,%o0
+ retl
+ st %g1,[%o4+%o2]
+
+
+LOC(large):
+ ld [%o1+%o2],%o5
+ mov 0,%o0
+ sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
+ b LOC(1)
+ add %o4,-4,%o4
+LOC(loop):
+ addcc %o5,%g3,%g3
+ ld [%o1+%o2],%o5
+ addx %o0,%g0,%o0
+ st %g3,[%o4+%o2]
+LOC(1): wr %g0,%o5,%y
+ and %o5,%g4,%g2
+ andcc %g0,%g0,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%g0,%g1
+ rd %y,%g3
+ addcc %g3,%o0,%g3
+ addx %g2,%g1,%o0
+ addcc %o2,4,%o2
+ bne LOC(loop)
+ ld [%o4+%o2],%o5
+
+ addcc %o5,%g3,%g3
+ addx %o0,%g0,%o0
+ retl
+ st %g3,[%o4+%o2]
+
+END(__mpn_addmul_1)
diff --git a/libc/sysdeps/sparc/sparc32/alloca.S b/libc/sysdeps/sparc/sparc32/alloca.S
new file mode 100644
index 000000000..42a2c61b4
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/alloca.S
@@ -0,0 +1,33 @@
+/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* Code produced by Sun's C compiler calls this function with two extra
+ arguments which it makes relocatable symbols but seem always to be
+ the constant 96; I have no idea what they are for. */
+
+#ifndef NO_UNDERSCORES
+#define __builtin_alloca ___builtin_alloca
+#endif
+
+ENTRY (__builtin_alloca)
+ sub %sp, %o0, %sp /* Push some stack space. */
+ retl /* Return; the returned buffer leaves 96 */
+ add %sp, 96, %o0 /* bytes of register save area at the top. */
+END (__builtin_alloca)
diff --git a/libc/sysdeps/sparc/sparc32/bcopy.c b/libc/sysdeps/sparc/sparc32/bcopy.c
new file mode 100644
index 000000000..9a455f33c
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/bcopy.c
@@ -0,0 +1 @@
+/* bcopy is in memcpy.S */
diff --git a/libc/sysdeps/sparc/sparc32/bits/atomic.h b/libc/sysdeps/sparc/sparc32/bits/atomic.h
new file mode 100644
index 000000000..ef553f727
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/bits/atomic.h
@@ -0,0 +1,327 @@
+/* Atomic operations. sparc32 version.
+ Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_ATOMIC_H
+#define _BITS_ATOMIC_H 1
+
+#include <stdint.h>
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+
+/* We have no compare and swap, just test and set.
+ The following implementation contends on 64 global locks
+ per library and assumes no variable will be accessed using atomic.h
+ macros from two different libraries. */
+
+__make_section_unallocated
+ (".gnu.linkonce.b.__sparc32_atomic_locks, \"aw\", %nobits");
+
+volatile unsigned char __sparc32_atomic_locks[64]
+ __attribute__ ((nocommon, section (".gnu.linkonce.b.__sparc32_atomic_locks"
+ __sec_comment),
+ visibility ("hidden")));
+
+#define __sparc32_atomic_do_lock(addr) \
+ do \
+ { \
+ unsigned int __old_lock; \
+ unsigned int __idx = (((long) addr >> 2) ^ ((long) addr >> 12)) \
+ & 63; \
+ do \
+ __asm __volatile ("ldstub %1, %0" \
+ : "=r" (__old_lock), \
+ "=m" (__sparc32_atomic_locks[__idx]) \
+ : "m" (__sparc32_atomic_locks[__idx]) \
+ : "memory"); \
+ while (__old_lock); \
+ } \
+ while (0)
+
+#define __sparc32_atomic_do_unlock(addr) \
+ do \
+ { \
+ __sparc32_atomic_locks[(((long) addr >> 2) \
+ ^ ((long) addr >> 12)) & 63] = 0; \
+ __asm __volatile ("" ::: "memory"); \
+ } \
+ while (0)
+
+#define __sparc32_atomic_do_lock24(addr) \
+ do \
+ { \
+ unsigned int __old_lock; \
+ do \
+ __asm __volatile ("ldstub %1, %0" \
+ : "=r" (__old_lock), "=m" (*(addr)) \
+ : "m" (*(addr)) \
+ : "memory"); \
+ while (__old_lock); \
+ } \
+ while (0)
+
+#define __sparc32_atomic_do_unlock24(addr) \
+ do \
+ { \
+ *(char *) (addr) = 0; \
+ __asm __volatile ("" ::: "memory"); \
+ } \
+ while (0)
+
+
+#ifndef SHARED
+# define __v9_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+({ \
+ register __typeof (*(mem)) __acev_tmp __asm ("%g6"); \
+ register __typeof (mem) __acev_mem __asm ("%g1") = (mem); \
+ register __typeof (*(mem)) __acev_oldval __asm ("%g5"); \
+ __acev_tmp = (newval); \
+ __acev_oldval = (oldval); \
+ /* .word 0xcde05005 is cas [%g1], %g5, %g6. Can't use cas here though, \
+ because as will then mark the object file as V8+ arch. */ \
+ __asm __volatile (".word 0xcde05005" \
+ : "+r" (__acev_tmp), "=m" (*__acev_mem) \
+ : "r" (__acev_oldval), "m" (*__acev_mem), \
+ "r" (__acev_mem) : "memory"); \
+ __acev_tmp; })
+#endif
+
+/* The only basic operation needed is compare and exchange. */
+#define __v7_compare_and_exchange_val_acq(mem, newval, oldval) \
+ ({ __typeof (mem) __acev_memp = (mem); \
+ __typeof (*mem) __acev_ret; \
+ __typeof (*mem) __acev_newval = (newval); \
+ \
+ __sparc32_atomic_do_lock (__acev_memp); \
+ __acev_ret = *__acev_memp; \
+ if (__acev_ret == (oldval)) \
+ *__acev_memp = __acev_newval; \
+ __sparc32_atomic_do_unlock (__acev_memp); \
+ __acev_ret; })
+
+#define __v7_compare_and_exchange_bool_acq(mem, newval, oldval) \
+ ({ __typeof (mem) __aceb_memp = (mem); \
+ int __aceb_ret; \
+ __typeof (*mem) __aceb_newval = (newval); \
+ \
+ __sparc32_atomic_do_lock (__aceb_memp); \
+ __aceb_ret = 0; \
+ if (*__aceb_memp == (oldval)) \
+ *__aceb_memp = __aceb_newval; \
+ else \
+ __aceb_ret = 1; \
+ __sparc32_atomic_do_unlock (__aceb_memp); \
+ __aceb_ret; })
+
+#define __v7_exchange_acq(mem, newval) \
+ ({ __typeof (mem) __acev_memp = (mem); \
+ __typeof (*mem) __acev_ret; \
+ __typeof (*mem) __acev_newval = (newval); \
+ \
+ __sparc32_atomic_do_lock (__acev_memp); \
+ __acev_ret = *__acev_memp; \
+ *__acev_memp = __acev_newval; \
+ __sparc32_atomic_do_unlock (__acev_memp); \
+ __acev_ret; })
+
+#define __v7_exchange_and_add(mem, value) \
+ ({ __typeof (mem) __acev_memp = (mem); \
+ __typeof (*mem) __acev_ret; \
+ \
+ __sparc32_atomic_do_lock (__acev_memp); \
+ __acev_ret = *__acev_memp; \
+ *__acev_memp = __acev_ret + (value); \
+ __sparc32_atomic_do_unlock (__acev_memp); \
+ __acev_ret; })
+
+/* Special versions, which guarantee that top 8 bits of all values
+ are cleared and use those bits as the ldstub lock. */
+#define __v7_compare_and_exchange_val_24_acq(mem, newval, oldval) \
+ ({ __typeof (mem) __acev_memp = (mem); \
+ __typeof (*mem) __acev_ret; \
+ __typeof (*mem) __acev_newval = (newval); \
+ \
+ __sparc32_atomic_do_lock24 (__acev_memp); \
+ __acev_ret = *__acev_memp & 0xffffff; \
+ if (__acev_ret == (oldval)) \
+ *__acev_memp = __acev_newval; \
+ else \
+ __sparc32_atomic_do_unlock24 (__acev_memp); \
+ __asm __volatile ("" ::: "memory"); \
+ __acev_ret; })
+
+#define __v7_exchange_24_rel(mem, newval) \
+ ({ __typeof (mem) __acev_memp = (mem); \
+ __typeof (*mem) __acev_ret; \
+ __typeof (*mem) __acev_newval = (newval); \
+ \
+ __sparc32_atomic_do_lock24 (__acev_memp); \
+ __acev_ret = *__acev_memp & 0xffffff; \
+ *__acev_memp = __acev_newval; \
+ __asm __volatile ("" ::: "memory"); \
+ __acev_ret; })
+
+#ifdef SHARED
+
+/* When dynamically linked, we assume pre-v9 libraries are only ever
+ used on pre-v9 CPU. */
+# define __atomic_is_v9 0
+
+# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
+ __v7_compare_and_exchange_val_acq (mem, newval, oldval)
+
+# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
+ __v7_compare_and_exchange_bool_acq (mem, newval, oldval)
+
+# define atomic_exchange_acq(mem, newval) \
+ __v7_exchange_acq (mem, newval)
+
+# define atomic_exchange_and_add(mem, value) \
+ __v7_exchange_and_add (mem, value)
+
+# define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \
+ ({ \
+ if (sizeof (*mem) != 4) \
+ abort (); \
+ __v7_compare_and_exchange_val_24_acq (mem, newval, oldval); })
+
+# define atomic_exchange_24_rel(mem, newval) \
+ ({ \
+ if (sizeof (*mem) != 4) \
+ abort (); \
+ __v7_exchange_24_rel (mem, newval); })
+
+#else
+
+/* In libc.a/libpthread.a etc. we don't know if we'll be run on
+ pre-v9 or v9 CPU. To be interoperable with dynamically linked
+ apps on v9 CPUs e.g. with process shared primitives, use cas insn
+ on v9 CPUs and ldstub on pre-v9. */
+
+/* Avoid <ldsodefs.h> include here. */
+extern uint64_t _dl_hwcap __attribute__((weak));
+# define __ATOMIC_HWCAP_SPARC_V9 16
+# define __atomic_is_v9 \
+ (__builtin_expect (&_dl_hwcap != 0, 1) \
+ && __builtin_expect (_dl_hwcap & __ATOMIC_HWCAP_SPARC_V9, \
+ __ATOMIC_HWCAP_SPARC_V9))
+
+# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
+ ({ \
+ __typeof (*mem) __acev_wret; \
+ if (sizeof (*mem) != 4) \
+ abort (); \
+ if (__atomic_is_v9) \
+ __acev_wret \
+ = __v9_compare_and_exchange_val_32_acq (mem, newval, oldval);\
+ else \
+ __acev_wret \
+ = __v7_compare_and_exchange_val_acq (mem, newval, oldval); \
+ __acev_wret; })
+
+# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
+ ({ \
+ int __acev_wret; \
+ if (sizeof (*mem) != 4) \
+ abort (); \
+ if (__atomic_is_v9) \
+ { \
+ __typeof (oldval) __acev_woldval = (oldval); \
+ __acev_wret \
+ = __v9_compare_and_exchange_val_32_acq (mem, newval, \
+ __acev_woldval) \
+ != __acev_woldval; \
+ } \
+ else \
+ __acev_wret \
+ = __v7_compare_and_exchange_bool_acq (mem, newval, oldval); \
+ __acev_wret; })
+
+# define atomic_exchange_rel(mem, newval) \
+ ({ \
+ __typeof (*mem) __acev_wret; \
+ if (sizeof (*mem) != 4) \
+ abort (); \
+ if (__atomic_is_v9) \
+ { \
+ __typeof (mem) __acev_wmemp = (mem); \
+ __typeof (*(mem)) __acev_wval = (newval); \
+ do \
+ __acev_wret = *__acev_wmemp; \
+ while (__builtin_expect \
+ (__v9_compare_and_exchange_val_32_acq (__acev_wmemp,\
+ __acev_wval, \
+ __acev_wret) \
+ != __acev_wret, 0)); \
+ } \
+ else \
+ __acev_wret = __v7_exchange_acq (mem, newval); \
+ __acev_wret; })
+
+# define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \
+ ({ \
+ __typeof (*mem) __acev_wret; \
+ if (sizeof (*mem) != 4) \
+ abort (); \
+ if (__atomic_is_v9) \
+ __acev_wret \
+ = __v9_compare_and_exchange_val_32_acq (mem, newval, oldval);\
+ else \
+ __acev_wret \
+ = __v7_compare_and_exchange_val_24_acq (mem, newval, oldval);\
+ __acev_wret; })
+
+# define atomic_exchange_24_rel(mem, newval) \
+ ({ \
+ __typeof (*mem) __acev_w24ret; \
+ if (sizeof (*mem) != 4) \
+ abort (); \
+ if (__atomic_is_v9) \
+ __acev_w24ret = atomic_exchange_rel (mem, newval); \
+ else \
+ __acev_w24ret = __v7_exchange_24_rel (mem, newval); \
+ __acev_w24ret; })
+
+#endif
+
+#endif /* bits/atomic.h */
diff --git a/libc/sysdeps/sparc/sparc32/bits/setjmp.h b/libc/sysdeps/sparc/sparc32/bits/setjmp.h
new file mode 100644
index 000000000..86ccc20d2
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/bits/setjmp.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 1997, 1998, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Define the machine-dependent type `jmp_buf'. SPARC version. */
+
+#ifndef _SETJMP_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#ifndef _ASM
+typedef int __jmp_buf[3];
+#endif
diff --git a/libc/sysdeps/sparc/sparc32/bits/wordsize.h b/libc/sysdeps/sparc/sparc32/bits/wordsize.h
new file mode 100644
index 000000000..0dee88b28
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/bits/wordsize.h
@@ -0,0 +1,8 @@
+/* Determine the wordsize from the preprocessor defines. */
+
+#if defined __arch64__ || defined __sparcv9
+# define __WORDSIZE 64
+# define __WORDSIZE_COMPAT32 1
+#else
+# define __WORDSIZE 32
+#endif
diff --git a/libc/sysdeps/sparc/sparc32/bsd-_setjmp.S b/libc/sysdeps/sparc/sparc32/bsd-_setjmp.S
new file mode 100644
index 000000000..4e6a2da56
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/bsd-_setjmp.S
@@ -0,0 +1 @@
+/* _setjmp is in setjmp.S */
diff --git a/libc/sysdeps/sparc/sparc32/bsd-setjmp.S b/libc/sysdeps/sparc/sparc32/bsd-setjmp.S
new file mode 100644
index 000000000..1da848d2f
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/bsd-setjmp.S
@@ -0,0 +1 @@
+/* setjmp is in setjmp.S */
diff --git a/libc/sysdeps/sparc/sparc32/bzero.c b/libc/sysdeps/sparc/sparc32/bzero.c
new file mode 100644
index 000000000..37f0f6f99
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/bzero.c
@@ -0,0 +1 @@
+/* bzero is in memset.S */
diff --git a/libc/sysdeps/sparc/sparc32/divrem.m4 b/libc/sysdeps/sparc/sparc32/divrem.m4
new file mode 100644
index 000000000..30d532ad7
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/divrem.m4
@@ -0,0 +1,232 @@
+/*
+ * Division and remainder, from Appendix E of the Sparc Version 8
+ * Architecture Manual, with fixes from Gordon Irlam.
+ */
+
+/*
+ * Input: dividend and divisor in %o0 and %o1 respectively.
+ *
+ * m4 parameters:
+ * NAME name of function to generate
+ * OP OP=div => %o0 / %o1; OP=rem => %o0 % %o1
+ * S S=true => signed; S=false => unsigned
+ *
+ * Algorithm parameters:
+ * N how many bits per iteration we try to get (4)
+ * WORDSIZE total number of bits (32)
+ *
+ * Derived constants:
+ * TOPBITS number of bits in the top `decade' of a number
+ *
+ * Important variables:
+ * Q the partial quotient under development (initially 0)
+ * R the remainder so far, initially the dividend
+ * ITER number of main division loop iterations required;
+ * equal to ceil(log2(quotient) / N). Note that this
+ * is the log base (2^N) of the quotient.
+ * V the current comparand, initially divisor*2^(ITER*N-1)
+ *
+ * Cost:
+ * Current estimate for non-large dividend is
+ * ceil(log2(quotient) / N) * (10 + 7N/2) + C
+ * A large dividend is one greater than 2^(31-TOPBITS) and takes a
+ * different path, as the upper bits of the quotient must be developed
+ * one bit at a time.
+ */
+
+define(N, `4')dnl
+define(WORDSIZE, `32')dnl
+define(TOPBITS, eval(WORDSIZE - N*((WORDSIZE-1)/N)))dnl
+dnl
+define(dividend, `%o0')dnl
+define(divisor, `%o1')dnl
+define(Q, `%o2')dnl
+define(R, `%o3')dnl
+define(ITER, `%o4')dnl
+define(V, `%o5')dnl
+dnl
+dnl m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d
+define(T, `%g1')dnl
+define(SC, `%g2')dnl
+ifelse(S, `true', `define(SIGN, `%g3')')dnl
+
+dnl
+dnl This is the recursive definition for developing quotient digits.
+dnl
+dnl Parameters:
+dnl $1 the current depth, 1 <= $1 <= N
+dnl $2 the current accumulation of quotient bits
+dnl N max depth
+dnl
+dnl We add a new bit to $2 and either recurse or insert the bits in
+dnl the quotient. R, Q, and V are inputs and outputs as defined above;
+dnl the condition codes are expected to reflect the input R, and are
+dnl modified to reflect the output R.
+dnl
+define(DEVELOP_QUOTIENT_BITS,
+` ! depth $1, accumulated bits $2
+ bl LOC($1.eval(2**N+$2))
+ srl V,1,V
+ ! remainder is positive
+ subcc R,V,R
+ ifelse($1, N,
+ ` b 9f
+ add Q, ($2*2+1), Q
+ ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')')
+LOC($1.eval(2**N+$2)):
+ ! remainder is negative
+ addcc R,V,R
+ ifelse($1, N,
+ ` b 9f
+ add Q, ($2*2-1), Q
+ ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')')
+ ifelse($1, 1, `9:')')dnl
+
+#include <sysdep.h>
+#include <sys/trap.h>
+
+ENTRY(NAME)
+ifelse(S, `true',
+` ! compute sign of result; if neither is negative, no problem
+ orcc divisor, dividend, %g0 ! either negative?
+ bge 2f ! no, go do the divide
+ifelse(OP, `div',
+` xor divisor, dividend, SIGN ! compute sign in any case',
+` mov dividend, SIGN ! sign of remainder matches dividend')
+ tst divisor
+ bge 1f
+ tst dividend
+ ! divisor is definitely negative; dividend might also be negative
+ bge 2f ! if dividend not negative...
+ sub %g0, divisor, divisor ! in any case, make divisor nonneg
+1: ! dividend is negative, divisor is nonnegative
+ sub %g0, dividend, dividend ! make dividend nonnegative
+2:
+')
+ ! Ready to divide. Compute size of quotient; scale comparand.
+ orcc divisor, %g0, V
+ bne 1f
+ mov dividend, R
+
+ ! Divide by zero trap. If it returns, return 0 (about as
+ ! wrong as possible, but that is what SunOS does...).
+ ta ST_DIV0
+ retl
+ clr %o0
+
+1:
+ cmp R, V ! if divisor exceeds dividend, done
+ blu LOC(got_result) ! (and algorithm fails otherwise)
+ clr Q
+ sethi %hi(1 << (WORDSIZE - TOPBITS - 1)), T
+ cmp R, T
+ blu LOC(not_really_big)
+ clr ITER
+
+ ! `Here the dividend is >= 2**(31-N) or so. We must be careful here,
+ ! as our usual N-at-a-shot divide step will cause overflow and havoc.
+ ! The number of bits in the result here is N*ITER+SC, where SC <= N.
+ ! Compute ITER in an unorthodox manner: know we need to shift V into
+ ! the top decade: so do not even bother to compare to R.'
+ 1:
+ cmp V, T
+ bgeu 3f
+ mov 1, SC
+ sll V, N, V
+ b 1b
+ add ITER, 1, ITER
+
+ ! Now compute SC.
+ 2: addcc V, V, V
+ bcc LOC(not_too_big)
+ add SC, 1, SC
+
+ ! We get here if the divisor overflowed while shifting.
+ ! This means that R has the high-order bit set.
+ ! Restore V and subtract from R.
+ sll T, TOPBITS, T ! high order bit
+ srl V, 1, V ! rest of V
+ add V, T, V
+ b LOC(do_single_div)
+ sub SC, 1, SC
+
+ LOC(not_too_big):
+ 3: cmp V, R
+ blu 2b
+ nop
+ be LOC(do_single_div)
+ nop
+ /* NB: these are commented out in the V8-Sparc manual as well */
+ /* (I do not understand this) */
+ ! V > R: went too far: back up 1 step
+ ! srl V, 1, V
+ ! dec SC
+ ! do single-bit divide steps
+ !
+ ! We have to be careful here. We know that R >= V, so we can do the
+ ! first divide step without thinking. BUT, the others are conditional,
+ ! and are only done if R >= 0. Because both R and V may have the high-
+ ! order bit set in the first step, just falling into the regular
+ ! division loop will mess up the first time around.
+ ! So we unroll slightly...
+ LOC(do_single_div):
+ subcc SC, 1, SC
+ bl LOC(end_regular_divide)
+ nop
+ sub R, V, R
+ mov 1, Q
+ b LOC(end_single_divloop)
+ nop
+ LOC(single_divloop):
+ sll Q, 1, Q
+ bl 1f
+ srl V, 1, V
+ ! R >= 0
+ sub R, V, R
+ b 2f
+ add Q, 1, Q
+ 1: ! R < 0
+ add R, V, R
+ sub Q, 1, Q
+ 2:
+ LOC(end_single_divloop):
+ subcc SC, 1, SC
+ bge LOC(single_divloop)
+ tst R
+ b,a LOC(end_regular_divide)
+
+LOC(not_really_big):
+1:
+ sll V, N, V
+ cmp V, R
+ bleu 1b
+ addcc ITER, 1, ITER
+ be LOC(got_result)
+ sub ITER, 1, ITER
+
+ tst R ! set up for initial iteration
+LOC(divloop):
+ sll Q, N, Q
+ DEVELOP_QUOTIENT_BITS(1, 0)
+LOC(end_regular_divide):
+ subcc ITER, 1, ITER
+ bge LOC(divloop)
+ tst R
+ bl,a LOC(got_result)
+ ! non-restoring fixup here (one instruction only!)
+ifelse(OP, `div',
+` sub Q, 1, Q
+', ` add R, divisor, R
+')
+
+LOC(got_result):
+ifelse(S, `true',
+` ! check to see if answer should be < 0
+ tst SIGN
+ bl,a 1f
+ ifelse(OP, `div', `sub %g0, Q, Q', `sub %g0, R, R')
+1:')
+ retl
+ ifelse(OP, `div', `mov Q, %o0', `mov R, %o0')
+
+END(NAME)
diff --git a/libc/sysdeps/sparc/sparc32/dl-machine.h b/libc/sysdeps/sparc/sparc32/dl-machine.h
new file mode 100644
index 000000000..02dabaabb
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/dl-machine.h
@@ -0,0 +1,575 @@
+/* Machine-dependent ELF dynamic relocation inline functions. SPARC version.
+ Copyright (C) 1996-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "sparc"
+
+#include <string.h>
+#include <sys/param.h>
+#include <ldsodefs.h>
+#include <tls.h>
+
+#ifndef VALIDX
+# define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
+ + DT_EXTRANUM + DT_VALTAGIDX (tag))
+#endif
+
+/* Some SPARC opcodes we need to use for self-modifying code. */
+#define OPCODE_NOP 0x01000000 /* nop */
+#define OPCODE_CALL 0x40000000 /* call ?; add PC-rel word address */
+#define OPCODE_SETHI_G1 0x03000000 /* sethi ?, %g1; add value>>10 */
+#define OPCODE_JMP_G1 0x81c06000 /* jmp %g1+?; add lo 10 bits of value */
+#define OPCODE_SAVE_SP 0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */
+#define OPCODE_BA 0x30800000 /* b,a ?; add PC-rel word address */
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int
+elf_machine_matches_host (const Elf32_Ehdr *ehdr)
+{
+ if (ehdr->e_machine == EM_SPARC)
+ return 1;
+ else if (ehdr->e_machine == EM_SPARC32PLUS)
+ {
+ /* XXX The following is wrong! Dave Miller rejected to implement it
+ correctly. If this causes problems shoot *him*! */
+#ifdef SHARED
+ return GLRO(dl_hwcap) & GLRO(dl_hwcap_mask) & HWCAP_SPARC_V9;
+#else
+ return GLRO(dl_hwcap) & HWCAP_SPARC_V9;
+#endif
+ }
+ else
+ return 0;
+}
+
+/* We have to do this because elf_machine_{dynamic,load_address} can be
+ invoked from functions that have no GOT references, and thus the compiler
+ has no obligation to load the PIC register. */
+#define LOAD_PIC_REG(PIC_REG) \
+do { register Elf32_Addr pc __asm("o7"); \
+ __asm("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \
+ "call 1f\n\t" \
+ "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n" \
+ "1:\tadd %1, %0, %1" \
+ : "=r" (pc), "=r" (PIC_REG)); \
+} while (0)
+
+/* Return the link-time address of _DYNAMIC. Conveniently, this is the
+ first element of the GOT. This must be inlined in a function which
+ uses global data. */
+static inline Elf32_Addr
+elf_machine_dynamic (void)
+{
+ register Elf32_Addr *got asm ("%l7");
+
+ LOAD_PIC_REG (got);
+
+ return *got;
+}
+
+/* Return the run-time load address of the shared object. */
+static inline Elf32_Addr
+elf_machine_load_address (void)
+{
+ register Elf32_Addr *pc __asm ("%o7"), *got __asm ("%l7");
+
+ __asm ("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t"
+ "call 1f\n\t"
+ " add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t"
+ "call _DYNAMIC\n\t"
+ "call _GLOBAL_OFFSET_TABLE_\n"
+ "1:\tadd %1, %0, %1\n\t" : "=r" (pc), "=r" (got));
+
+ /* got is now l_addr + _GLOBAL_OFFSET_TABLE_
+ *got is _DYNAMIC
+ pc[2]*4 is l_addr + _DYNAMIC - (long)pc - 8
+ pc[3]*4 is l_addr + _GLOBAL_OFFSET_TABLE_ - (long)pc - 12 */
+ return (Elf32_Addr) got - *got + (pc[2] - pc[3]) * 4 - 4;
+}
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int
+elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+{
+ Elf32_Addr *plt;
+ extern void _dl_runtime_resolve (Elf32_Word);
+ extern void _dl_runtime_profile (Elf32_Word);
+
+ if (l->l_info[DT_JMPREL] && lazy)
+ {
+ Elf32_Addr rfunc;
+
+ /* The entries for functions in the PLT have not yet been filled in.
+ Their initial contents will arrange when called to set the high 22
+ bits of %g1 with an offset into the .rela.plt section and jump to
+ the beginning of the PLT. */
+ plt = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
+ if (__builtin_expect(profile, 0))
+ {
+ rfunc = (Elf32_Addr) &_dl_runtime_profile;
+
+ if (GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), l))
+ GL(dl_profile_map) = l;
+ }
+ else
+ {
+ rfunc = (Elf32_Addr) &_dl_runtime_resolve;
+ }
+
+ /* The beginning of the PLT does:
+
+ sethi %hi(_dl_runtime_{resolve,profile}), %g2
+ pltpc: jmpl %g2 + %lo(_dl_runtime_{resolve,profile}), %g2
+ nop
+ .word MAP
+
+ The PC value (pltpc) saved in %g2 by the jmpl points near the
+ location where we store the link_map pointer for this object. */
+
+ plt[0] = 0x05000000 | ((rfunc >> 10) & 0x003fffff);
+ plt[1] = 0x85c0a000 | (rfunc & 0x3ff);
+ plt[2] = OPCODE_NOP; /* Fill call delay slot. */
+ plt[3] = (Elf32_Addr) l;
+ if (__builtin_expect (l->l_info[VALIDX(DT_GNU_PRELINKED)] != NULL, 0)
+ || __builtin_expect (l->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL, 0))
+ {
+ /* Need to reinitialize .plt to undo prelinking. */
+ int do_flush;
+ Elf32_Rela *rela = (Elf32_Rela *) D_PTR (l, l_info[DT_JMPREL]);
+ Elf32_Rela *relaend
+ = (Elf32_Rela *) ((char *) rela
+ + l->l_info[DT_PLTRELSZ]->d_un.d_val);
+ do_flush = GLRO(dl_hwcap) & HWCAP_SPARC_FLUSH;
+
+ /* prelink must ensure there are no R_SPARC_NONE relocs left
+ in .rela.plt. */
+ while (rela < relaend)
+ {
+ *(unsigned int *) rela->r_offset
+ = OPCODE_SETHI_G1 | (rela->r_offset - (Elf32_Addr) plt);
+ *(unsigned int *) (rela->r_offset + 4)
+ = OPCODE_BA | ((((Elf32_Addr) plt
+ - rela->r_offset - 4) >> 2) & 0x3fffff);
+ if (do_flush)
+ {
+ __asm __volatile ("flush %0" : : "r"(rela->r_offset));
+ __asm __volatile ("flush %0+4" : : "r"(rela->r_offset));
+ }
+ ++rela;
+ }
+ }
+ }
+
+ return lazy;
+}
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
+ PLT entries should not be allowed to define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+# define elf_machine_type_class(type) \
+ ((((type) == R_SPARC_JMP_SLOT \
+ || ((type) >= R_SPARC_TLS_GD_HI22 && (type) <= R_SPARC_TLS_TPOFF64)) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+# define elf_machine_type_class(type) \
+ ((((type) == R_SPARC_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_SPARC_JMP_SLOT
+
+/* The SPARC never uses Elf32_Rel relocations. */
+#define ELF_MACHINE_NO_REL 1
+
+/* The SPARC overlaps DT_RELA and DT_PLTREL. */
+#define ELF_MACHINE_PLTREL_OVERLAP 1
+
+/* Undo the sub %sp, 6*4, %sp; add %sp, 22*4, %o0 below to get at the
+ value we want in __libc_stack_end. */
+#define DL_STACK_END(cookie) \
+ ((void *) (((long) (cookie)) - (22 - 6) * 4))
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+
+#define RTLD_START __asm__ ("\
+ .text\n\
+ .globl _start\n\
+ .type _start, @function\n\
+ .align 32\n\
+_start:\n\
+ /* Allocate space for functions to drop their arguments. */\n\
+ sub %sp, 6*4, %sp\n\
+ /* Pass pointer to argument block to _dl_start. */\n\
+ call _dl_start\n\
+ add %sp, 22*4, %o0\n\
+ /* FALTHRU */\n\
+ .globl _dl_start_user\n\
+ .type _dl_start_user, @function\n\
+_dl_start_user:\n\
+ /* Load the PIC register. */\n\
+1: call 2f\n\
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\
+2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\
+ add %l7, %o7, %l7\n\
+ /* Save the user entry point address in %l0 */\n\
+ mov %o0, %l0\n\
+ /* See if we were run as a command with the executable file name as an\n\
+ extra leading argument. If so, adjust the contents of the stack. */\n\
+ sethi %hi(_dl_skip_args), %g2\n\
+ or %g2, %lo(_dl_skip_args), %g2\n\
+ ld [%l7+%g2], %i0\n\
+ ld [%i0], %i0\n\
+ tst %i0\n\
+ beq 3f\n\
+ ld [%sp+22*4], %i5 /* load argc */\n\
+ /* Find out how far to shift. */\n\
+ sethi %hi(_dl_argv), %l3\n\
+ or %l3, %lo(_dl_argv), %l3\n\
+ ld [%l7+%l3], %l3\n\
+ sub %i5, %i0, %i5\n\
+ ld [%l3], %l4\n\
+ sll %i0, 2, %i2\n\
+ st %i5, [%sp+22*4]\n\
+ sub %l4, %i2, %l4\n\
+ add %sp, 23*4, %i1\n\
+ add %i1, %i2, %i2\n\
+ st %l4, [%l3]\n\
+ /* Copy down argv */\n\
+21: ld [%i2], %i3\n\
+ add %i2, 4, %i2\n\
+ tst %i3\n\
+ st %i3, [%i1]\n\
+ bne 21b\n\
+ add %i1, 4, %i1\n\
+ /* Copy down env */\n\
+22: ld [%i2], %i3\n\
+ add %i2, 4, %i2\n\
+ tst %i3\n\
+ st %i3, [%i1]\n\
+ bne 22b\n\
+ add %i1, 4, %i1\n\
+ /* Copy down auxiliary table. */\n\
+23: ld [%i2], %i3\n\
+ ld [%i2+4], %i4\n\
+ add %i2, 8, %i2\n\
+ tst %i3\n\
+ st %i3, [%i1]\n\
+ st %i4, [%i1+4]\n\
+ bne 23b\n\
+ add %i1, 8, %i1\n\
+ /* %o0 = _dl_loaded, %o1 = argc, %o2 = argv, %o3 = envp. */\n\
+3: sethi %hi(_rtld_local), %o0\n\
+ add %sp, 23*4, %o2\n\
+ orcc %o0, %lo(_rtld_local), %o0\n\
+ sll %i5, 2, %o3\n\
+ ld [%l7+%o0], %o0\n\
+ add %o3, 4, %o3\n\
+ mov %i5, %o1\n\
+ add %o2, %o3, %o3\n\
+ call _dl_init_internal\n\
+ ld [%o0], %o0\n\
+ /* Pass our finalizer function to the user in %g1. */\n\
+ sethi %hi(_dl_fini), %g1\n\
+ or %g1, %lo(_dl_fini), %g1\n\
+ ld [%l7+%g1], %g1\n\
+ /* Jump to the user's entry point and deallocate the extra stack we got. */\n\
+ jmp %l0\n\
+ add %sp, 6*4, %sp\n\
+ .size _dl_start_user, . - _dl_start_user\n\
+ .previous");
+
+static inline Elf32_Addr
+sparc_fixup_plt (const Elf32_Rela *reloc, Elf32_Addr *reloc_addr,
+ Elf32_Addr value, int t)
+{
+ Elf32_Sword disp = value - (Elf32_Addr) reloc_addr;
+#ifndef RTLD_BOOTSTRAP
+ /* Note that we don't mask the hwcap here, as the flush is essential to
+ functionality on those cpu's that implement it. */
+ int do_flush = GLRO(dl_hwcap) & HWCAP_SPARC_FLUSH;
+#else
+ /* Unfortunately, this is necessary, so that we can ensure
+ ld.so will not execute corrupt PLT entry instructions. */
+ const int do_flush = 1;
+#endif
+
+ if (0 && disp >= -0x800000 && disp < 0x800000)
+ {
+ /* Don't need to worry about thread safety. We're writing just one
+ instruction. */
+
+ reloc_addr[0] = OPCODE_BA | ((disp >> 2) & 0x3fffff);
+ if (do_flush)
+ __asm __volatile ("flush %0" : : "r"(reloc_addr));
+ }
+ else
+ {
+ /* For thread safety, write the instructions from the bottom and
+ flush before we overwrite the critical "b,a". This of course
+ need not be done during bootstrapping, since there are no threads.
+ But we also can't tell if we _can_ use flush, so don't. */
+
+ reloc_addr += t;
+ reloc_addr[1] = OPCODE_JMP_G1 | (value & 0x3ff);
+ if (do_flush)
+ __asm __volatile ("flush %0+4" : : "r"(reloc_addr));
+
+ reloc_addr[0] = OPCODE_SETHI_G1 | (value >> 10);
+ if (do_flush)
+ __asm __volatile ("flush %0" : : "r"(reloc_addr));
+ }
+
+ return value;
+}
+
+static inline Elf32_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+ return sparc_fixup_plt (reloc, reloc_addr, value, 1);
+}
+
+/* Return the final value of a plt relocation. */
+static inline Elf32_Addr
+elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+ Elf32_Addr value)
+{
+ return value + reloc->r_addend;
+}
+
+#endif /* dl_machine_h */
+
+#define ARCH_LA_PLTENTER sparc32_gnu_pltenter
+#define ARCH_LA_PLTEXIT sparc32_gnu_pltexit
+
+#ifdef RESOLVE_MAP
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ MAP is the object containing the reloc. */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
+ const Elf32_Sym *sym, const struct r_found_version *version,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ const Elf32_Sym *const refsym = sym;
+ Elf32_Addr value;
+ const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+ struct link_map *sym_map = NULL;
+
+#if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ /* This is defined in rtld.c, but nowhere in the static libc.a; make the
+ reference weak so static programs can still link. This declaration
+ cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
+ because rtld.c contains the common defn for _dl_rtld_map, which is
+ incompatible with a weak decl in the same file. */
+ weak_extern (_dl_rtld_map);
+#endif
+
+ if (__builtin_expect (r_type == R_SPARC_NONE, 0))
+ return;
+
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+ if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0))
+ {
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ if (map != &_dl_rtld_map) /* Already done in rtld itself. */
+# endif
+ *reloc_addr += map->l_addr + reloc->r_addend;
+ return;
+ }
+#endif
+
+#ifndef RESOLVE_CONFLICT_FIND_MAP
+ if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0)
+ && sym->st_shndx != SHN_UNDEF)
+ {
+ value = map->l_addr;
+ }
+ else
+ {
+ sym_map = RESOLVE_MAP (&sym, version, r_type);
+ value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+ }
+#else
+ value = 0;
+#endif
+
+ value += reloc->r_addend; /* Assume copy relocs have zero addend. */
+
+ switch (r_type)
+ {
+#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
+ case R_SPARC_COPY:
+ if (sym == NULL)
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
+ if (sym->st_size > refsym->st_size
+ || (GLRO(dl_verbose) && sym->st_size < refsym->st_size))
+ {
+ const char *strtab;
+
+ strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+ _dl_error_printf ("\
+%s: Symbol `%s' has different size in shared object, consider re-linking\n",
+ rtld_progname ?: "<program name unknown>",
+ strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr_arg, (void *) value,
+ MIN (sym->st_size, refsym->st_size));
+ break;
+#endif
+ case R_SPARC_GLOB_DAT:
+ case R_SPARC_32:
+ *reloc_addr = value;
+ break;
+ case R_SPARC_JMP_SLOT:
+ /* At this point we don't need to bother with thread safety,
+ so we can optimize the first instruction of .plt out. */
+ sparc_fixup_plt (reloc, reloc_addr, value, 0);
+ break;
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+ && !defined RESOLVE_CONFLICT_FIND_MAP
+ case R_SPARC_TLS_DTPMOD32:
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+ break;
+ case R_SPARC_TLS_DTPOFF32:
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
+ break;
+ case R_SPARC_TLS_TPOFF32:
+ /* The offset is negative, forward from the thread pointer. */
+ /* We know the offset of object the symbol is contained in.
+ It is a negative value which will be added to the
+ thread pointer. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = sym->st_value - sym_map->l_tls_offset
+ + reloc->r_addend;
+ }
+ break;
+# ifndef RTLD_BOOTSTRAP
+ case R_SPARC_TLS_LE_HIX22:
+ case R_SPARC_TLS_LE_LOX10:
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ value = sym->st_value - sym_map->l_tls_offset
+ + reloc->r_addend;
+ if (r_type == R_SPARC_TLS_LE_HIX22)
+ *reloc_addr = (*reloc_addr & 0xffc00000) | ((~value) >> 10);
+ else
+ *reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff)
+ | 0x1c00;
+ }
+ break;
+# endif
+#endif
+#ifndef RTLD_BOOTSTRAP
+ case R_SPARC_8:
+ *(char *) reloc_addr = value;
+ break;
+ case R_SPARC_16:
+ *(short *) reloc_addr = value;
+ break;
+ case R_SPARC_DISP8:
+ *(char *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
+ break;
+ case R_SPARC_DISP16:
+ *(short *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
+ break;
+ case R_SPARC_DISP32:
+ *reloc_addr = (value - (Elf32_Addr) reloc_addr);
+ break;
+ case R_SPARC_LO10:
+ *reloc_addr = (*reloc_addr & ~0x3ff) | (value & 0x3ff);
+ break;
+ case R_SPARC_WDISP30:
+ *reloc_addr = ((*reloc_addr & 0xc0000000)
+ | ((value - (unsigned int) reloc_addr) >> 2));
+ break;
+ case R_SPARC_HI22:
+ *reloc_addr = (*reloc_addr & 0xffc00000) | (value >> 10);
+ break;
+ case R_SPARC_UA16:
+ ((unsigned char *) reloc_addr_arg) [0] = value >> 8;
+ ((unsigned char *) reloc_addr_arg) [1] = value;
+ break;
+ case R_SPARC_UA32:
+ ((unsigned char *) reloc_addr_arg) [0] = value >> 24;
+ ((unsigned char *) reloc_addr_arg) [1] = value >> 16;
+ ((unsigned char *) reloc_addr_arg) [2] = value >> 8;
+ ((unsigned char *) reloc_addr_arg) [3] = value;
+ break;
+#endif
+#if !defined RTLD_BOOTSTRAP || defined _NDEBUG
+ default:
+ _dl_reloc_bad_type (map, r_type, 0);
+ break;
+#endif
+ }
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ *reloc_addr += l_addr + reloc->r_addend;
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf32_Addr l_addr, const Elf32_Rela *reloc)
+{
+ switch (ELF32_R_TYPE (reloc->r_info))
+ {
+ case R_SPARC_NONE:
+ break;
+ case R_SPARC_JMP_SLOT:
+ break;
+ default:
+ _dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 1);
+ break;
+ }
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/libc/sysdeps/sparc/sparc32/dl-trampoline.S b/libc/sysdeps/sparc/sparc32/dl-trampoline.S
new file mode 100644
index 000000000..b0f86dda4
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/dl-trampoline.S
@@ -0,0 +1,184 @@
+/* PLT trampolines. Sparc 32-bit version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ .align 32
+
+ /* %g1: PLT offset loaded by PLT entry
+ * %g2: callers PC, which is PLT0 + 4, and we store the
+ * link map at PLT0 + 12, therefore we add 8 to get
+ * the address of the link map
+ */
+ .globl _dl_runtime_resolve
+ .type _dl_runtime_resolve, @function
+_dl_runtime_resolve:
+ cfi_startproc
+
+ save %sp, -104, %sp
+ cfi_def_cfa_register(%fp)
+ cfi_window_save
+ cfi_register (%o7, %i7)
+
+ ld [%g2 + 8], %o0
+ srl %g1, 10, %o1
+ call _dl_fixup
+ sub %o1, 4*12, %o1
+ jmp %o0
+ restore
+
+ cfi_endproc
+
+ .size _dl_runtime_resolve, .-_dl_runtime_resolve
+
+ /* For the profiling cases we pass in our stack frame
+ * as the base of the La_sparc64_regs, so it looks
+ * like:
+ * %l0 %sp
+ * ...
+ * %l7 %sp + (7 * 8)
+ * %i0 %sp + (8 * 8)
+ * ...
+ * %i7 %sp + (15 * 8)
+ * %f0 %sp + (16 * 8)
+ * %f16 %sp + (31 * 8)
+ * framesize %sp + (32 * 8)
+ */
+
+ .globl _dl_profile_save_regs
+ .type _dl_profile_save_regs, @function
+_dl_profile_save_regs:
+ cfi_startproc
+
+ std %l0, [%sp + ( 0 * 8)]
+ std %l2, [%sp + ( 1 * 8)]
+ std %l4, [%sp + ( 2 * 8)]
+ std %l6, [%sp + ( 3 * 8)]
+ std %i0, [%sp + ( 4 * 8)]
+ std %i2, [%sp + ( 5 * 8)]
+ std %i4, [%sp + ( 6 * 8)]
+ std %i6, [%sp + ( 7 * 8)]
+ ld [%sp + (8 * 8)], %l4
+ retl
+ st %l4, [%sp + (8 * 8)]
+
+ cfi_endproc
+
+ .size _dl_profile_save_regs, .-_dl_profile_save_regs
+
+ /* If we are going to call pltexit, then we must replicate
+ * the caller's stack frame.
+ * %o0: PLT resolved function address
+ */
+ .globl _dl_profile_invoke
+ .type _dl_profile_invoke, @function
+_dl_profile_invoke:
+ cfi_startproc
+
+ sub %sp, %l0, %sp
+1:
+ srl %l0, 3, %l7
+ mov %o0, %l1
+ mov %i0, %o0
+ mov %i1, %o1
+ mov %i2, %o2
+ mov %i3, %o3
+ mov %i4, %o4
+ mov %i5, %o5
+ mov %fp, %l2
+ mov %sp, %l3
+1: ldd [%l2], %g2
+ add %l2, 0x8, %l2
+ subcc %l7, 1, %l7
+ std %g2, [%l3]
+ bne 1b
+ add %l3, 0x8, %l3
+
+ jmpl %l1, %o7
+ nop
+
+ std %o0, [%sp + ( 9 * 8)]
+ std %f0, [%sp + (10 * 8)]
+
+ mov %l5, %o0
+ mov %l6, %o1
+ add %sp, %l0, %o2
+ call _dl_call_pltexit
+ add %sp, (16 * 8), %o3
+
+ ldd [%sp + (9 * 8)], %i0
+
+ jmpl %i7 + 8, %g0
+ restore
+
+ cfi_endproc
+
+ .size _dl_profile_invoke, .-_dl_profile_invoke
+
+ /* %g1: PLT offset loaded by PLT entry
+ * %g2: callers PC, which is PLT0 + 4, and we store the
+ * link map at PLT0 + 12, therefore we add 8 to get
+ * the address of the link map
+ */
+ .align 32
+ .globl _dl_runtime_profile
+ .type _dl_runtime_profile, @function
+_dl_runtime_profile:
+ cfi_startproc
+
+ cmp %fp, 0
+ be,a 1f
+ mov 104, %g3
+ sub %fp, %sp, %g3
+1: save %sp, -104, %sp
+ cfi_def_cfa_register(%fp)
+ cfi_window_save
+ cfi_register(%o7, %i7)
+
+ ld [%g2 + 8], %o0
+ srl %g1, 10, %o1
+ mov %i7, %o2
+ sub %o1, 4*12, %o1
+
+ mov %g3, %l0
+ mov %o0, %l5
+ mov %o1, %l6
+
+ call _dl_profile_save_regs
+ nop
+
+ mov %sp, %o3
+ call _dl_profile_fixup
+ add %sp, (9 * 8), %o4
+
+ ld [%sp + (9 * 8)], %o1
+ cmp %o1, 0
+ bgeu 1f
+ nop
+
+ call _dl_profile_invoke
+ nop
+
+1: jmp %o0
+ restore
+
+ cfi_endproc
+
+ .size _dl_runtime_profile, .-_dl_runtime_profile
diff --git a/libc/sysdeps/sparc/sparc32/dotmul.S b/libc/sysdeps/sparc/sparc32/dotmul.S
new file mode 100644
index 000000000..821aa8bdb
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/dotmul.S
@@ -0,0 +1,127 @@
+/*
+ * Signed multiply, from Appendix E of the Sparc Version 8
+ * Architecture Manual.
+ */
+
+/*
+ * Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the upper 32 bits of
+ * the 64-bit product).
+ *
+ * This code optimizes short (less than 13-bit) multiplies.
+ */
+
+#include <sysdep.h>
+
+
+ENTRY(.mul)
+ mov %o0, %y ! multiplier -> Y
+ andncc %o0, 0xfff, %g0 ! test bits 12..31
+ be LOC(mul_shortway) ! if zero, can do it the short way
+ andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
+
+ /*
+ * Long multiply. 32 steps, followed by a final shift step.
+ */
+ mulscc %o4, %o1, %o4 ! 1
+ mulscc %o4, %o1, %o4 ! 2
+ mulscc %o4, %o1, %o4 ! 3
+ mulscc %o4, %o1, %o4 ! 4
+ mulscc %o4, %o1, %o4 ! 5
+ mulscc %o4, %o1, %o4 ! 6
+ mulscc %o4, %o1, %o4 ! 7
+ mulscc %o4, %o1, %o4 ! 8
+ mulscc %o4, %o1, %o4 ! 9
+ mulscc %o4, %o1, %o4 ! 10
+ mulscc %o4, %o1, %o4 ! 11
+ mulscc %o4, %o1, %o4 ! 12
+ mulscc %o4, %o1, %o4 ! 13
+ mulscc %o4, %o1, %o4 ! 14
+ mulscc %o4, %o1, %o4 ! 15
+ mulscc %o4, %o1, %o4 ! 16
+ mulscc %o4, %o1, %o4 ! 17
+ mulscc %o4, %o1, %o4 ! 18
+ mulscc %o4, %o1, %o4 ! 19
+ mulscc %o4, %o1, %o4 ! 20
+ mulscc %o4, %o1, %o4 ! 21
+ mulscc %o4, %o1, %o4 ! 22
+ mulscc %o4, %o1, %o4 ! 23
+ mulscc %o4, %o1, %o4 ! 24
+ mulscc %o4, %o1, %o4 ! 25
+ mulscc %o4, %o1, %o4 ! 26
+ mulscc %o4, %o1, %o4 ! 27
+ mulscc %o4, %o1, %o4 ! 28
+ mulscc %o4, %o1, %o4 ! 29
+ mulscc %o4, %o1, %o4 ! 30
+ mulscc %o4, %o1, %o4 ! 31
+ mulscc %o4, %o1, %o4 ! 32
+ mulscc %o4, %g0, %o4 ! final shift
+
+ ! If %o0 was negative, the result is
+ ! (%o0 * %o1) + (%o1 << 32))
+ ! We fix that here.
+
+#if 0
+ tst %o0
+ bge 1f
+ rd %y, %o0
+
+ ! %o0 was indeed negative; fix upper 32 bits of result by subtracting
+ ! %o1 (i.e., return %o4 - %o1 in %o1).
+ retl
+ sub %o4, %o1, %o1
+
+1:
+ retl
+ mov %o4, %o1
+#else
+ /* Faster code adapted from tege@sics.se's code for umul.S. */
+ sra %o0, 31, %o2 ! make mask from sign bit
+ and %o1, %o2, %o2 ! %o2 = 0 or %o1, depending on sign of %o0
+ rd %y, %o0 ! get lower half of product
+ retl
+ sub %o4, %o2, %o1 ! subtract compensation
+ ! and put upper half in place
+#endif
+
+LOC(mul_shortway):
+ /*
+ * Short multiply. 12 steps, followed by a final shift step.
+ * The resulting bits are off by 12 and (32-12) = 20 bit positions,
+ * but there is no problem with %o0 being negative (unlike above).
+ */
+ mulscc %o4, %o1, %o4 ! 1
+ mulscc %o4, %o1, %o4 ! 2
+ mulscc %o4, %o1, %o4 ! 3
+ mulscc %o4, %o1, %o4 ! 4
+ mulscc %o4, %o1, %o4 ! 5
+ mulscc %o4, %o1, %o4 ! 6
+ mulscc %o4, %o1, %o4 ! 7
+ mulscc %o4, %o1, %o4 ! 8
+ mulscc %o4, %o1, %o4 ! 9
+ mulscc %o4, %o1, %o4 ! 10
+ mulscc %o4, %o1, %o4 ! 11
+ mulscc %o4, %o1, %o4 ! 12
+ mulscc %o4, %g0, %o4 ! final shift
+
+ /*
+ * %o4 has 20 of the bits that should be in the low part of the
+ * result; %y has the bottom 12 (as %y's top 12). That is:
+ *
+ * %o4 %y
+ * +----------------+----------------+
+ * | -12- | -20- | -12- | -20- |
+ * +------(---------+------)---------+
+ * --hi-- ----low-part----
+ *
+ * The upper 12 bits of %o4 should be sign-extended to form the
+ * high part of the product (i.e., highpart = %o4 >> 20).
+ */
+
+ rd %y, %o5
+ sll %o4, 12, %o0 ! shift middle bits left 12
+ srl %o5, 20, %o5 ! shift low bits right 20, zero fill at left
+ or %o5, %o0, %o0 ! construct low part of result
+ retl
+ sra %o4, 20, %o1 ! ... and extract high part of result
+
+END(.mul)
diff --git a/libc/sysdeps/sparc/sparc32/e_sqrt.c b/libc/sysdeps/sparc/sparc32/e_sqrt.c
new file mode 100644
index 000000000..0be4b6c0c
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/e_sqrt.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <math.h>
+
+#ifndef __GNUC__
+ #error This file uses GNU C extensions; you must compile with GCC.
+#endif
+
+/* Return the square root of X. */
+double
+__ieee754_sqrt (x)
+ double x;
+{
+ register double result;
+ asm ("fsqrtd %1, %0" : "=f" (result) : "f" (x));
+ return result;
+}
diff --git a/libc/sysdeps/sparc/sparc32/elf/Makefile b/libc/sysdeps/sparc/sparc32/elf/Makefile
new file mode 100644
index 000000000..a995e6cdf
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/elf/Makefile
@@ -0,0 +1,4 @@
+# Sparc/ELF specific definitions.
+
+# The assembler on SPARC needs the -fPIC flag even when it's assembler code.
+ASFLAGS-.os = -fPIC
diff --git a/libc/sysdeps/sparc/sparc32/elf/configure b/libc/sysdeps/sparc/sparc32/elf/configure
new file mode 100644
index 000000000..d4f951795
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/elf/configure
@@ -0,0 +1,89 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/sparc/sparc32/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and linker.
+echo "$as_me:$LINENO: checking for sparc32 TLS support" >&5
+echo $ECHO_N "checking for sparc32 TLS support... $ECHO_C" >&6
+if test "${libc_cv_sparc32_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<\EOF
+ .section ".tdata", "awT", @progbits
+ .globl foo
+foo: .word 1
+ .section ".tbss", "awT", @nobits
+ .globl bar
+bar: .skip 4
+ .text
+baz: sethi %tgd_hi22(foo), %l1
+ add %l1, %tgd_lo10(foo), %l1
+ add %l7, %l1, %o0, %tgd_add(foo)
+ call __tls_get_addr, %tgd_call(foo)
+ sethi %tldm_hi22(bar), %l1
+ add %l1, %tldm_lo10(bar), %l1
+ add %l7, %l1, %o0, %tldm_add(bar)
+ call __tls_get_addr, %tldm_call(bar)
+ sethi %tldo_hix22(bar), %l1
+ xor %l1, %tldo_lox10(bar), %l1
+ add %o0, %l1, %l1, %tldo_add(bar)
+ sethi %tie_hi22(foo), %l1
+ add %l1, %tie_lo10(foo), %l1
+ ld [%l7 + %l1], %l1, %tie_ld(foo)
+ add %g7, %l1, %l1, %tie_add(foo)
+ sethi %tle_hix22(foo), %l1
+ xor %l1, %tle_lox10(foo), %l1
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_sparc32_tls=yes
+else
+ libc_cv_sparc32_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_sparc32_tls" >&5
+echo "${ECHO_T}$libc_cv_sparc32_tls" >&6
+if test $libc_cv_sparc32_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+# Check for broken WDISP22 in the linker.
+echo "$as_me:$LINENO: checking for sparc32 ld WDISP22 handling" >&5
+echo $ECHO_N "checking for sparc32 ld WDISP22 handling... $ECHO_C" >&6
+if test "${libc_cv_sparc32_wdisp22+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ echo 'bne foo; nop' > conftest1.s
+echo '.globl foo; .hidden foo; foo: nop' > conftest2.s
+libc_cv_sparc32_wdisp22=unknown
+if { ac_try='${CC-cc} -nostdlib -shared $CFLAGS conftest1.s conftest2.s -o conftest.so 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if readelf -r conftest.so | grep -q R_SPARC_WDISP22; then
+ libc_cv_sparc32_wdisp22=broken
+ else
+ libc_cv_sparc32_wdisp22=ok
+ fi
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_sparc32_wdisp22" >&5
+echo "${ECHO_T}$libc_cv_sparc32_wdisp22" >&6
+if test $libc_cv_sparc32_wdisp22 != ok; then
+ cat >>confdefs.h <<\_ACEOF
+#define BROKEN_SPARC_WDISP22 1
+_ACEOF
+
+fi
diff --git a/libc/sysdeps/sparc/sparc32/elf/configure.in b/libc/sysdeps/sparc/sparc32/elf/configure.in
new file mode 100644
index 000000000..aa75e0bfa
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/elf/configure.in
@@ -0,0 +1,62 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/sparc/sparc32/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and linker.
+AC_CACHE_CHECK(for sparc32 TLS support, libc_cv_sparc32_tls, [dnl
+changequote(,)dnl
+cat > conftest.s <<\EOF
+ .section ".tdata", "awT", @progbits
+ .globl foo
+foo: .word 1
+ .section ".tbss", "awT", @nobits
+ .globl bar
+bar: .skip 4
+ .text
+baz: sethi %tgd_hi22(foo), %l1
+ add %l1, %tgd_lo10(foo), %l1
+ add %l7, %l1, %o0, %tgd_add(foo)
+ call __tls_get_addr, %tgd_call(foo)
+ sethi %tldm_hi22(bar), %l1
+ add %l1, %tldm_lo10(bar), %l1
+ add %l7, %l1, %o0, %tldm_add(bar)
+ call __tls_get_addr, %tldm_call(bar)
+ sethi %tldo_hix22(bar), %l1
+ xor %l1, %tldo_lox10(bar), %l1
+ add %o0, %l1, %l1, %tldo_add(bar)
+ sethi %tie_hi22(foo), %l1
+ add %l1, %tie_lo10(foo), %l1
+ ld [%l7 + %l1], %l1, %tie_ld(foo)
+ add %g7, %l1, %l1, %tie_add(foo)
+ sethi %tle_hix22(foo), %l1
+ xor %l1, %tle_lox10(foo), %l1
+EOF
+changequote([,])dnl
+dnl
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_sparc32_tls=yes
+else
+ libc_cv_sparc32_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_sparc32_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
+# Check for broken WDISP22 in the linker.
+AC_CACHE_CHECK(for sparc32 ld WDISP22 handling, libc_cv_sparc32_wdisp22, [dnl
+echo 'bne foo; nop' > conftest1.s
+echo '.globl foo; .hidden foo; foo: nop' > conftest2.s
+libc_cv_sparc32_wdisp22=unknown
+if AC_TRY_COMMAND(${CC-cc} -nostdlib -shared $CFLAGS conftest1.s conftest2.s -o conftest.so 1>&AS_MESSAGE_LOG_FD); then
+ if readelf -r conftest.so | grep -q R_SPARC_WDISP22; then
+ libc_cv_sparc32_wdisp22=broken
+ else
+ libc_cv_sparc32_wdisp22=ok
+ fi
+fi
+rm -f conftest*])
+if test $libc_cv_sparc32_wdisp22 != ok; then
+ AC_DEFINE(BROKEN_SPARC_WDISP22)
+fi
diff --git a/libc/sysdeps/sparc/sparc32/elf/start.S b/libc/sysdeps/sparc/sparc32/elf/start.S
new file mode 100644
index 000000000..702dd755e
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/elf/start.S
@@ -0,0 +1,104 @@
+/* Startup code for elf32-sparc
+ Copyright (C) 1997, 1998, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+
+ .section ".text"
+ .align 4
+#ifdef SHARED
+.LLGETPC0:
+ retl
+ add %o7, %l7, %l7
+#endif
+ .global _start
+ .type _start,#function
+_start:
+ cfi_startproc
+
+#ifdef SHARED
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7
+ call .LLGETPC0
+ add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7
+#endif
+
+ /* Terminate the stack frame, and reserve space for functions to
+ drop their arguments. */
+ mov %g0, %fp
+ sub %sp, 6*4, %sp
+ cfi_adjust_cfa_offset(6*4)
+
+ /* Extract the arguments and environment as encoded on the stack. The
+ argument info starts after one register window (16 words) past the SP. */
+ ld [%sp+22*4], %o1
+ add %sp, 23*4, %o2
+
+ /* Load the addresses of the user entry points. */
+ sethi %hi(main), %o0
+ sethi %hi(__libc_csu_init), %o3
+ sethi %hi(__libc_csu_fini), %o4
+ or %o0, %lo(main), %o0
+ or %o3, %lo(__libc_csu_init), %o3
+ or %o4, %lo(__libc_csu_fini), %o4
+#ifdef SHARED
+ ld [%l7 + %o0], %o0
+ ld [%l7 + %o3], %o3
+ ld [%l7 + %o4], %o4
+#endif
+
+ /* When starting a binary via the dynamic linker, %g1 contains the
+ address of the shared library termination function, which will be
+ registered with atexit(). If we are statically linked, this will
+ be NULL. */
+ mov %g1, %o5
+
+ /* Let libc do the rest of the initialization, and call main. */
+ call __libc_start_main
+ nop
+
+ /* Die very horribly if exit returns. */
+ unimp
+
+ cfi_endproc
+
+ .size _start, .-_start
+
+/* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+weak_alias (__data_start, data_start)
diff --git a/libc/sysdeps/sparc/sparc32/fpu/e_sqrtl.c b/libc/sysdeps/sparc/sparc32/fpu/e_sqrtl.c
new file mode 100644
index 000000000..3c3acfee0
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/fpu/e_sqrtl.c
@@ -0,0 +1 @@
+/* __ieee754_sqrtl is defined in q_sqrt.c. */
diff --git a/libc/sysdeps/sparc/sparc32/fpu/libm-test-ulps b/libc/sysdeps/sparc/sparc32/fpu/libm-test-ulps
new file mode 100644
index 000000000..ccf53788a
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/fpu/libm-test-ulps
@@ -0,0 +1,1322 @@
+# Begin of automatic generation
+
+# atan2
+Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025":
+float: 3
+ifloat: 3
+ildouble: 1
+ldouble: 1
+Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025":
+float: 3
+ifloat: 3
+ildouble: 1
+ldouble: 1
+Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "atan2 (-0.00756827042671106339, -.001792735857538728036) == -1.80338464113663849327153994379639112":
+float: 6
+ifloat: 6
+ildouble: 1
+ldouble: 1
+
+# atanh
+Test "atanh (0.75) == 0.972955074527656652552676371721589865":
+float: 1
+ifloat: 1
+
+# cacos
+Test "Imaginary part of: cacos (0.75 + 1.25 i) == 1.11752014915610270578240049553777969 - 1.13239363160530819522266333696834467 i":
+ildouble: 1
+ldouble: 1
+
+# cacosh
+Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+ildouble: 5
+ldouble: 5
+Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+# casin
+Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+ildouble: 1
+ldouble: 1
+
+# casinh
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 4
+ldouble: 4
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 2
+ldouble: 2
+Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# catan
+Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+float: 3
+ifloat: 3
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+float: 4
+ifloat: 4
+Test "Imaginary part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+ildouble: 1
+ldouble: 1
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 4
+idouble: 4
+Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+float: 4
+ifloat: 4
+Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+float: 6
+ifloat: 6
+ildouble: 1
+ldouble: 1
+
+# cbrt
+Test "cbrt (-0.001) == -0.1":
+ildouble: 1
+ldouble: 1
+Test "cbrt (-27.0) == -3.0":
+double: 1
+idouble: 1
+Test "cbrt (0.75) == 0.908560296416069829445605878163630251":
+double: 1
+idouble: 1
+Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217":
+double: 1
+idouble: 1
+
+# ccos
+Test "Real part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+float: 1
+ifloat: 1
+
+# ccosh
+Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+float: 1
+ifloat: 1
+
+# cexp
+Test "Real part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+ildouble: 1
+ldouble: 1
+
+# clog
+Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+float: 3
+ifloat: 3
+Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# cos
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "cos (pi/2) == 0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# cpow
+Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+ildouble: 4
+ldouble: 4
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i":
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 10
+ldouble: 10
+Test "Real part of: cpow (2 + 0 i, 10 + 0 i) == 1024.0 + 0.0 i":
+ildouble: 2
+ldouble: 2
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+ildouble: 3
+ldouble: 3
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 2
+ifloat: 2
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# csin
+Test "Imaginary part of: csin (-2 - 3 i) == -9.15449914691142957346729954460983256 + 4.16890695996656435075481305885375484 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
+ildouble: 1
+ldouble: 1
+
+# csinh
+Test "Real part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+
+# csqrt
+Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csqrt (0.75 + 1.25 i) == 1.05065169626078392338656675760808326 + 0.594868882070379067881984030639932657 i":
+ildouble: 1
+ldouble: 1
+
+# ctan
+Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+ifloat: 1
+Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+idouble: 1
+
+# erf
+Test "erf (1.25) == 0.922900128256458230136523481197281140":
+double: 1
+idouble: 1
+
+# erfc
+Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
+double: 1
+idouble: 1
+Test "erfc (27.0) == 0.523704892378925568501606768284954709e-318":
+ildouble: 1
+ldouble: 1
+Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8":
+double: 1
+idouble: 1
+
+# exp10
+Test "exp10 (-1) == 0.1":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "exp10 (3) == 1000":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# exp2
+Test "exp2 (10) == 1024":
+ildouble: 2
+ldouble: 2
+
+# expm1
+Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+double: 1
+idouble: 1
+Test "expm1 (1) == M_El - 1.0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# gamma
+Test "gamma (-0.5) == log(2*sqrt(pi))":
+ildouble: 1
+ldouble: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+
+# j0
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "j0 (0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# j1
+Test "j1 (-1.0) == -0.440050585744933515959682203718914913":
+ildouble: 1
+ldouble: 1
+Test "j1 (0.75) == 0.349243602174862192523281016426251335":
+ildouble: 1
+ldouble: 1
+Test "j1 (1.0) == 0.440050585744933515959682203718914913":
+ildouble: 1
+ldouble: 1
+Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+ildouble: 4
+ldouble: 4
+
+# jn
+Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (0, 0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (1, -1.0) == -0.440050585744933515959682203718914913":
+ildouble: 1
+ldouble: 1
+Test "jn (1, 0.75) == 0.349243602174862192523281016426251335":
+ildouble: 1
+ldouble: 1
+Test "jn (1, 1.0) == 0.440050585744933515959682203718914913":
+ildouble: 1
+ldouble: 1
+Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+ildouble: 4
+ldouble: 4
+Test "jn (10, -1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, 1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 2
+ldouble: 2
+Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+float: 4
+ifloat: 4
+Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# lgamma
+Test "lgamma (-0.5) == log(2*sqrt(pi))":
+ildouble: 1
+ldouble: 1
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# log10
+Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "log10 (e) == log10(e)":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# log1p
+Test "log1p (-0.25) == -0.287682072451780927439219005993827432":
+float: 1
+ifloat: 1
+Test "log1p (M_El - 1.0) == 1":
+ildouble: 1
+ldouble: 1
+
+# log2
+Test "log2 (0.75) == -.415037499278843818546261056052183492":
+ildouble: 1
+ldouble: 1
+
+# sincos
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
+float: 1
+ifloat: 1
+
+# sqrt
+Test "sqrt (2) == M_SQRT2l":
+ildouble: 1
+ldouble: 1
+
+# tan
+Test "tan (pi/4) == 1":
+double: 1
+idouble: 1
+
+# tanh
+Test "tanh (-0.75) == -0.635148952387287319214434357312496495":
+ildouble: 1
+ldouble: 1
+Test "tanh (-1.0) == -0.7615941559557648881194582826047935904":
+ildouble: 1
+ldouble: 1
+Test "tanh (0.75) == 0.635148952387287319214434357312496495":
+ildouble: 1
+ldouble: 1
+Test "tanh (1.0) == 0.7615941559557648881194582826047935904":
+ildouble: 1
+ldouble: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+ifloat: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "tgamma (4) == 6":
+ildouble: 1
+ldouble: 1
+
+# y0
+Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+# y1
+Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "y1 (0.75) == -1.03759455076928541973767132140642198":
+ildouble: 1
+ldouble: 1
+Test "y1 (1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# yn
+Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "yn (1, 0.75) == -1.03759455076928541973767132140642198":
+ildouble: 1
+ldouble: 1
+Test "yn (1, 1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "yn (1, 2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 5
+ldouble: 5
+Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+double: 2
+idouble: 2
+ildouble: 2
+ldouble: 2
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+idouble: 1
+Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+double: 1
+idouble: 1
+
+# Maximal error of functions:
+Function: "atan2":
+float: 6
+ifloat: 6
+ildouble: 1
+ldouble: 1
+
+Function: "atanh":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "cacos":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cacosh":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "casin":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "catan":
+float: 4
+ifloat: 4
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh":
+double: 4
+idouble: 4
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catanh":
+float: 6
+ifloat: 6
+ildouble: 1
+ldouble: 1
+
+Function: "cbrt":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccos":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccosh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cexp":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "cexp":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "clog":
+float: 3
+ifloat: 3
+
+Function: Real part of "clog10":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cpow":
+double: 2
+float: 4
+idouble: 2
+ifloat: 4
+ildouble: 10
+ldouble: 10
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csin":
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csin":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csinh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "csqrt":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csqrt":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ctan":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ctan":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "ctanh":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ctanh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "erf":
+double: 1
+idouble: 1
+
+Function: "erfc":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "exp10":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "exp2":
+ildouble: 2
+ldouble: 2
+
+Function: "expm1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "gamma":
+ildouble: 1
+ldouble: 1
+
+Function: "hypot":
+float: 1
+ifloat: 1
+
+Function: "j0":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: "jn":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 4
+ldouble: 4
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log10":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log1p":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log2":
+ildouble: 1
+ldouble: 1
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "sqrt":
+ildouble: 1
+ldouble: 1
+
+Function: "tan":
+double: 1
+idouble: 1
+
+Function: "tanh":
+ildouble: 1
+ldouble: 1
+
+Function: "tgamma":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+# end of automatic generation
diff --git a/libc/sysdeps/sparc/sparc32/fpu/s_fabs.c b/libc/sysdeps/sparc/sparc32/fpu/s_fabs.c
new file mode 100644
index 000000000..b883e6e86
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/fpu/s_fabs.c
@@ -0,0 +1,11 @@
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+double __fabs (double x)
+{
+ return __builtin_fabs (x);
+}
+weak_alias (__fabs, fabs)
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __fabs, fabsl, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/sparc/sparc32/fpu/s_fabsf.S b/libc/sysdeps/sparc/sparc32/fpu/s_fabsf.S
new file mode 100644
index 000000000..e1487247d
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/fpu/s_fabsf.S
@@ -0,0 +1,29 @@
+/* Float absolute value, sparc32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2006.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY (__fabsf)
+ st %o0, [%sp+64]
+ ld [%sp+64], %f0
+ retl
+ fabss %f0, %f0
+END (__fabsf)
+weak_alias (__fabsf, fabsf)
diff --git a/libc/sysdeps/sparc/sparc32/fpu/s_fabsl.c b/libc/sysdeps/sparc/sparc32/fpu/s_fabsl.c
new file mode 100644
index 000000000..3c03b9282
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/fpu/s_fabsl.c
@@ -0,0 +1,8 @@
+#include <math.h>
+#include <math_ldbl_opt.h>
+
+long double __fabsl (long double x)
+{
+ return __builtin_fabsl (x);
+}
+long_double_symbol (libm, __fabsl, fabsl);
diff --git a/libc/sysdeps/sparc/sparc32/ieee754.h b/libc/sysdeps/sparc/sparc32/ieee754.h
new file mode 100644
index 000000000..126025e7a
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/ieee754.h
@@ -0,0 +1,171 @@
+/* Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _IEEE754_H
+
+#define _IEEE754_H 1
+#include <features.h>
+
+#include <endian.h>
+
+__BEGIN_DECLS
+
+union ieee754_float
+ {
+ float f;
+
+ /* This is the IEEE 754 single-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int mantissa:23;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int mantissa:23;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int quiet_nan:1;
+ unsigned int mantissa:22;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int mantissa:22;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee_nan;
+ };
+
+#define IEEE754_FLOAT_BIAS 0x7f /* Added to exponent. */
+
+
+union ieee754_double
+ {
+ double d;
+
+ /* This is the IEEE 754 double-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:20;
+ unsigned int mantissa1:32;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:20;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ unsigned int quiet_nan:1;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:19;
+ unsigned int mantissa1:32;
+#else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:19;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+#endif
+ } ieee_nan;
+ };
+
+#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */
+
+
+union ieee854_long_double
+ {
+ long double d;
+
+ /* This is the IEEE 854 quad-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:15;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:16;
+ unsigned int mantissa1:32;
+ unsigned int mantissa2:32;
+ unsigned int mantissa3:32;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa3:32;
+ unsigned int mantissa2:32;
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:16;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:15;
+ unsigned int quiet_nan:1;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:15;
+ unsigned int mantissa1:32;
+ unsigned int mantissa2:32;
+ unsigned int mantissa3:32;
+#else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa3:32;
+ unsigned int mantissa2:32;
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:15;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+#endif
+ } ieee_nan;
+ };
+
+#define IEEE854_LONG_DOUBLE_BIAS 0x3fff /* Added to exponent. */
+
+__END_DECLS
+
+#endif /* ieee754.h */
diff --git a/libc/sysdeps/sparc/sparc32/jmpbuf-offsets.h b/libc/sysdeps/sparc/sparc32/jmpbuf-offsets.h
new file mode 100644
index 000000000..1c6f7a9d1
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/jmpbuf-offsets.h
@@ -0,0 +1,22 @@
+/* Private macros for accessing __jmp_buf contents. SPARC version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define JB_SP 0
+#define JB_FP 1
+#define JB_PC 2
diff --git a/libc/sysdeps/sparc/sparc32/jmpbuf-unwind.h b/libc/sysdeps/sparc/sparc32/jmpbuf-unwind.h
new file mode 100644
index 000000000..0f317b99d
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/jmpbuf-unwind.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <stdint.h>
+#include <unwind.h>
+#include <sysdep.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame
+ containing a local variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \
+ ((int) (address) < demangle ((jmpbuf)[JB_SP]))
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+static inline uintptr_t __attribute__ ((unused))
+_jmpbuf_sp (__jmp_buf regs)
+{
+ uintptr_t sp = regs[JB_SP];
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (sp);
+#endif
+ return sp;
+}
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
+
+/* We use the normal lobngjmp for unwinding. */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libc/sysdeps/sparc/sparc32/lshift.S b/libc/sysdeps/sparc/sparc32/lshift.S
new file mode 100644
index 000000000..bbe43618c
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/lshift.S
@@ -0,0 +1,97 @@
+! Sparc __mpn_lshift --
+!
+! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+!
+! This file is part of the GNU MP Library.
+!
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at your
+! option) any later version.
+!
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+! License for more details.
+!
+! You should have received a copy of the GNU Lesser General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! RES_PTR %o0
+! SRC_PTR %o1
+! SIZE %o2
+! CNT %o3
+
+#include <sysdep.h>
+
+ENTRY(__mpn_lshift)
+ sll %o2,2,%g1
+ add %o1,%g1,%o1 ! make %o1 point at end of src
+ ld [%o1-4],%g2 ! load first limb
+ sub %g0,%o3,%o5 ! negate shift count
+ add %o0,%g1,%o0 ! make %o0 point at end of res
+ add %o2,-1,%o2
+ andcc %o2,4-1,%g4 ! number of limbs in first loop
+ srl %g2,%o5,%g1 ! compute function result
+ be LOC(0) ! if multiple of 4 limbs, skip first loop
+ st %g1,[%sp+80]
+
+ sub %o2,%g4,%o2 ! adjust count for main loop
+
+LOC(loop0):
+ ld [%o1-8],%g3
+ add %o0,-4,%o0
+ add %o1,-4,%o1
+ addcc %g4,-1,%g4
+ sll %g2,%o3,%o4
+ srl %g3,%o5,%g1
+ mov %g3,%g2
+ or %o4,%g1,%o4
+ bne LOC(loop0)
+ st %o4,[%o0+0]
+
+LOC(0): tst %o2
+ be LOC(end)
+ nop
+
+LOC(loop):
+ ld [%o1-8],%g3
+ add %o0,-16,%o0
+ addcc %o2,-4,%o2
+ sll %g2,%o3,%o4
+ srl %g3,%o5,%g1
+
+ ld [%o1-12],%g2
+ sll %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0+12]
+ srl %g2,%o5,%g1
+
+ ld [%o1-16],%g3
+ sll %g2,%o3,%o4
+ or %g4,%g1,%g4
+ st %g4,[%o0+8]
+ srl %g3,%o5,%g1
+
+ ld [%o1-20],%g2
+ sll %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0+4]
+ srl %g2,%o5,%g1
+
+ add %o1,-16,%o1
+ or %g4,%g1,%g4
+ bne LOC(loop)
+ st %g4,[%o0+0]
+
+LOC(end):
+ sll %g2,%o3,%g2
+ st %g2,[%o0-4]
+ retl
+ ld [%sp+80],%o0
+
+END(__mpn_lshift)
diff --git a/libc/sysdeps/sparc/sparc32/memchr.S b/libc/sysdeps/sparc/sparc32/memchr.S
new file mode 100644
index 000000000..fcd98315d
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/memchr.S
@@ -0,0 +1,146 @@
+/* memchr (str, ch, n) -- Return pointer to first occurrence of CH in STR less
+ than N.
+ For SPARC v7.
+ Copyright (C) 1996, 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz> and
+ David S. Miller <davem@caip.rutgers.edu>.
+ This version is developed using the same algorithm as the fast C
+ version which carries the following introduction:
+ Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+ with help from Dan Sahlin (dan@sics.se) and
+ commentary by Jim Blandy (jimb@ai.mit.edu);
+ adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+ and implemented by Roland McGrath (roland@ai.mit.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ .align 4
+ENTRY(__memchr)
+ andcc %o1, 0xff, %o1
+ sll %o1, 8, %g6
+ andcc %o0, 3, %g0
+ or %o1, %g6, %g6
+ sll %g6, 16, %o3
+ be 10f
+ or %o3, %g6, %g2
+ cmp %o2, 0
+ be 9f
+ sethi %hi(0x80808080), %o4
+ ldub [%o0], %g4
+ cmp %g4, %o1
+ be 1f
+ add %o0, 1, %o0
+ subcc %o2, 1, %o2
+ be 9f
+ andcc %o0, 3, %g0
+ be 4f
+ or %o4, %lo(0x80808080), %o3
+ ldub [%o0], %g4
+ cmp %g4, %o1
+ be 1f
+ add %o0, 1, %o0
+ subcc %o2, 1, %o2
+ be 9f
+ andcc %o0, 3, %g0
+ be 5f
+ sethi %hi(0x01010101), %o5
+ ldub [%o0], %g4
+ cmp %g4, %o1
+ be 1f
+ add %o0, 1, %o0
+ subcc %o2, 1, %o2
+ bne,a 7f
+ and %o2, 3, %g1
+ retl
+ clr %o0
+1: retl
+ sub %o0, 1, %o0
+10: sethi %hi(0x80808080), %o4
+ or %o4, %lo(0x80808080), %o3
+4: sethi %hi(0x01010101), %o5
+5: and %o2, 3, %g1
+7: andcc %o2, 0xfffffffc, %o2
+ be 0f
+ or %o5, %lo(0x01010101), %g6
+ ld [%o0], %g4
+6: xor %g4, %g2, %g5
+ add %o0, 4, %o0
+ sub %g5, %g6, %g5
+ andcc %g5, %o3, %g0
+ bne 8f
+ subcc %o2, 4, %o2
+ bne,a 6b
+ ld [%o0], %g4
+0: cmp %g1, 0
+1: be 9f
+ add %o0, 4, %o0
+ ldub [%o0 - 4], %g4
+ cmp %g4, %o1
+ be 4f
+ cmp %g1, 1
+ be 9f
+ ldub [%o0 - 3], %g4
+ cmp %g4, %o1
+ be 3f
+ cmp %g1, 2
+ be 9f
+ ldub [%o0 - 2], %g4
+ cmp %g4, %o1
+ be 2f
+ nop
+9: retl
+ clr %o0
+
+ /* Check every byte. */
+8: srl %g4, 24, %g5
+ and %g5, 0xff, %g5
+ cmp %g5, %o1
+ be 4f
+ srl %g4, 16, %g5
+ and %g5, 0xff, %g5
+ cmp %g5, %o1
+ be 3f
+ srl %g4, 8, %g5
+ and %g5, 0xff, %g5
+ cmp %g5, %o1
+ be 2f
+ and %g4, 0xff, %g5
+ cmp %g5, %o1
+ be 1f
+ cmp %o2, 0
+ bne,a 6b
+ ld [%o0], %g4
+ b 1b
+ cmp %g1, 0
+1: retl
+ sub %o0, 1, %o0
+2: retl
+ sub %o0, 2, %o0
+3: retl
+ sub %o0, 3, %o0
+4: retl
+ sub %o0, 4, %o0
+END(__memchr)
+
+weak_alias (__memchr, memchr)
+#if !__BOUNDED_POINTERS__
+weak_alias (__memchr, __ubp_memchr)
+#endif
+libc_hidden_builtin_def (memchr)
diff --git a/libc/sysdeps/sparc/sparc32/memcopy.h b/libc/sysdeps/sparc/sparc32/memcopy.h
new file mode 100644
index 000000000..284759f08
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/memcopy.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/memcopy.h>
+#undef reg_char
+#define reg_char int
diff --git a/libc/sysdeps/sparc/sparc32/memcpy.S b/libc/sysdeps/sparc/sparc32/memcpy.S
new file mode 100644
index 000000000..6bd55c06a
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/memcpy.S
@@ -0,0 +1,972 @@
+/* Copy SIZE bytes from SRC to DEST.
+ For SPARC v7.
+ Copyright (C) 1996, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller <davem@caip.rutgers.edu>,
+ Eddie C. Dost <ecd@skynet.be> and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* Both these macros have to start with exactly the same insn */
+#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
+ ldd [%src + offset + 0x00], %t0; \
+ ldd [%src + offset + 0x08], %t2; \
+ ldd [%src + offset + 0x10], %t4; \
+ ldd [%src + offset + 0x18], %t6; \
+ st %t0, [%dst + offset + 0x00]; \
+ st %t1, [%dst + offset + 0x04]; \
+ st %t2, [%dst + offset + 0x08]; \
+ st %t3, [%dst + offset + 0x0c]; \
+ st %t4, [%dst + offset + 0x10]; \
+ st %t5, [%dst + offset + 0x14]; \
+ st %t6, [%dst + offset + 0x18]; \
+ st %t7, [%dst + offset + 0x1c];
+
+#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
+ ldd [%src + offset + 0x00], %t0; \
+ ldd [%src + offset + 0x08], %t2; \
+ ldd [%src + offset + 0x10], %t4; \
+ ldd [%src + offset + 0x18], %t6; \
+ std %t0, [%dst + offset + 0x00]; \
+ std %t2, [%dst + offset + 0x08]; \
+ std %t4, [%dst + offset + 0x10]; \
+ std %t6, [%dst + offset + 0x18];
+
+#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldd [%src - offset - 0x10], %t0; \
+ ldd [%src - offset - 0x08], %t2; \
+ st %t0, [%dst - offset - 0x10]; \
+ st %t1, [%dst - offset - 0x0c]; \
+ st %t2, [%dst - offset - 0x08]; \
+ st %t3, [%dst - offset - 0x04];
+
+#define MOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldd [%src - offset - 0x10], %t0; \
+ ldd [%src - offset - 0x08], %t2; \
+ std %t0, [%dst - offset - 0x10]; \
+ std %t2, [%dst - offset - 0x08];
+
+#define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
+ ldub [%src - offset - 0x02], %t0; \
+ ldub [%src - offset - 0x01], %t1; \
+ stb %t0, [%dst - offset - 0x02]; \
+ stb %t1, [%dst - offset - 0x01];
+
+/* Both these macros have to start with exactly the same insn */
+#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
+ ldd [%src - offset - 0x20], %t0; \
+ ldd [%src - offset - 0x18], %t2; \
+ ldd [%src - offset - 0x10], %t4; \
+ ldd [%src - offset - 0x08], %t6; \
+ st %t0, [%dst - offset - 0x20]; \
+ st %t1, [%dst - offset - 0x1c]; \
+ st %t2, [%dst - offset - 0x18]; \
+ st %t3, [%dst - offset - 0x14]; \
+ st %t4, [%dst - offset - 0x10]; \
+ st %t5, [%dst - offset - 0x0c]; \
+ st %t6, [%dst - offset - 0x08]; \
+ st %t7, [%dst - offset - 0x04];
+
+#define RMOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
+ ldd [%src - offset - 0x20], %t0; \
+ ldd [%src - offset - 0x18], %t2; \
+ ldd [%src - offset - 0x10], %t4; \
+ ldd [%src - offset - 0x08], %t6; \
+ std %t0, [%dst - offset - 0x20]; \
+ std %t2, [%dst - offset - 0x18]; \
+ std %t4, [%dst - offset - 0x10]; \
+ std %t6, [%dst - offset - 0x08];
+
+#define RMOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldd [%src + offset + 0x00], %t0; \
+ ldd [%src + offset + 0x08], %t2; \
+ st %t0, [%dst + offset + 0x00]; \
+ st %t1, [%dst + offset + 0x04]; \
+ st %t2, [%dst + offset + 0x08]; \
+ st %t3, [%dst + offset + 0x0c];
+
+#define RMOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
+ ldub [%src + offset + 0x00], %t0; \
+ ldub [%src + offset + 0x01], %t1; \
+ stb %t0, [%dst + offset + 0x00]; \
+ stb %t1, [%dst + offset + 0x01];
+
+#define SMOVE_CHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \
+ ldd [%src + offset + 0x00], %t0; \
+ ldd [%src + offset + 0x08], %t2; \
+ srl %t0, shir, %t5; \
+ srl %t1, shir, %t6; \
+ sll %t0, shil, %t0; \
+ or %t5, %prev, %t5; \
+ sll %t1, shil, %prev; \
+ or %t6, %t0, %t0; \
+ srl %t2, shir, %t1; \
+ srl %t3, shir, %t6; \
+ sll %t2, shil, %t2; \
+ or %t1, %prev, %t1; \
+ std %t4, [%dst + offset + offset2 - 0x04]; \
+ std %t0, [%dst + offset + offset2 + 0x04]; \
+ sll %t3, shil, %prev; \
+ or %t6, %t2, %t4;
+
+#define SMOVE_ALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \
+ ldd [%src + offset + 0x00], %t0; \
+ ldd [%src + offset + 0x08], %t2; \
+ srl %t0, shir, %t4; \
+ srl %t1, shir, %t5; \
+ sll %t0, shil, %t6; \
+ or %t4, %prev, %t0; \
+ sll %t1, shil, %prev; \
+ or %t5, %t6, %t1; \
+ srl %t2, shir, %t4; \
+ srl %t3, shir, %t5; \
+ sll %t2, shil, %t6; \
+ or %t4, %prev, %t2; \
+ sll %t3, shil, %prev; \
+ or %t5, %t6, %t3; \
+ std %t0, [%dst + offset + offset2 + 0x00]; \
+ std %t2, [%dst + offset + offset2 + 0x08];
+
+ .text
+ .align 4
+
+ENTRY(bcopy)
+ mov %o0, %o3
+ mov %o1, %o0
+ mov %o3, %o1
+END(bcopy)
+
+ENTRY(memmove)
+ cmp %o0, %o1
+ st %o0, [%sp + 64]
+ bleu 9f
+ sub %o0, %o1, %o4
+
+ add %o1, %o2, %o3
+ cmp %o3, %o0
+ bleu 0f
+ andcc %o4, 3, %o5
+
+ add %o1, %o2, %o1
+ add %o0, %o2, %o0
+ bne 77f
+ cmp %o2, 15
+ bleu 91f
+ andcc %o1, 3, %g0
+ be 3f
+ nop
+
+ andcc %o1, 1, %g0
+ be 4f
+ andcc %o1, 2, %g0
+
+ ldub [%o1 - 1], %g2
+ sub %o1, 1, %o1
+ stb %g2, [%o0 - 1]
+ sub %o2, 1, %o2
+ be 3f
+ sub %o0, 1, %o0
+4: lduh [%o1 - 2], %g2
+ sub %o1, 2, %o1
+ sth %g2, [%o0 - 2]
+ sub %o2, 2, %o2
+ sub %o0, 2, %o0
+
+3: andcc %o1, 4, %g0
+
+ be 2f
+ mov %o2, %g1
+
+ ld [%o1 - 4], %o4
+ sub %g1, 4, %g1
+ st %o4, [%o0 - 4]
+ sub %o1, 4, %o1
+ sub %o0, 4, %o0
+2: andcc %g1, 0xffffff80, %g6
+ be 3f
+ andcc %o0, 4, %g0
+
+ be 74f + 4
+5: RMOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
+ RMOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
+ RMOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
+ RMOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
+ subcc %g6, 128, %g6
+ sub %o1, 128, %o1
+ bne 5b
+ sub %o0, 128, %o0
+
+3: andcc %g1, 0x70, %g6
+ be 72f
+ andcc %g1, 8, %g0
+
+ srl %g6, 1, %o4
+ mov %o7, %g2
+ add %g6, %o4, %o4
+101: call 100f
+ sub %o1, %g6, %o1
+ mov %g2, %o7
+ jmpl %o5 + (72f - 101b), %g0
+ sub %o0, %g6, %o0
+
+71: RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
+ RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
+ RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
+ RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
+ RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
+ RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
+ RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
+72: be 73f
+ andcc %g1, 4, %g0
+
+ ldd [%o1 - 0x08], %g2
+ sub %o0, 8, %o0
+ sub %o1, 8, %o1
+ st %g2, [%o0]
+ st %g3, [%o0 + 0x04]
+73: be 1f
+ andcc %g1, 2, %g0
+
+ ld [%o1 - 4], %g2
+ sub %o1, 4, %o1
+ st %g2, [%o0 - 4]
+ sub %o0, 4, %o0
+1: be 1f
+ andcc %g1, 1, %g0
+
+ lduh [%o1 - 2], %g2
+ sub %o1, 2, %o1
+ sth %g2, [%o0 - 2]
+ sub %o0, 2, %o0
+1: be 1f
+ nop
+
+ ldub [%o1 - 1], %g2
+ stb %g2, [%o0 - 1]
+1: retl
+ ld [%sp + 64], %o0
+
+74: RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
+ RMOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
+ RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
+ RMOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
+ subcc %g6, 128, %g6
+ sub %o1, 128, %o1
+ bne 74b
+ sub %o0, 128, %o0
+
+ andcc %g1, 0x70, %g6
+ be 72b
+ andcc %g1, 8, %g0
+
+ srl %g6, 1, %o4
+ mov %o7, %g2
+ add %g6, %o4, %o4
+102: call 100f
+ sub %o1, %g6, %o1
+ mov %g2, %o7
+ jmpl %o5 + (72b - 102b), %g0
+ sub %o0, %g6, %o0
+
+75: and %o2, 0xe, %o3
+ mov %o7, %g2
+ sll %o3, 3, %o4
+ sub %o0, %o3, %o0
+103: call 100f
+ sub %o1, %o3, %o1
+ mov %g2, %o7
+ jmpl %o5 + (76f - 103b), %g0
+ andcc %o2, 1, %g0
+
+ RMOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
+ RMOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
+ RMOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
+ RMOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
+ RMOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
+ RMOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
+ RMOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
+
+76: be 1f
+ nop
+ ldub [%o1 - 1], %g2
+ stb %g2, [%o0 - 1]
+1: retl
+ ld [%sp + 64], %o0
+
+91: bne 75b
+ andcc %o2, 8, %g0
+
+ be 1f
+ andcc %o2, 4, %g0
+
+ ld [%o1 - 0x08], %g2
+ ld [%o1 - 0x04], %g3
+ sub %o1, 8, %o1
+ st %g2, [%o0 - 0x08]
+ st %g3, [%o0 - 0x04]
+ sub %o0, 8, %o0
+1: b 73b
+ mov %o2, %g1
+
+77: cmp %o2, 15
+ bleu 75b
+ andcc %o0, 3, %g0
+ be 64f
+ andcc %o0, 1, %g0
+ be 63f
+ andcc %o0, 2, %g0
+ ldub [%o1 - 1], %g5
+ sub %o1, 1, %o1
+ stb %g5, [%o0 - 1]
+ sub %o0, 1, %o0
+ be 64f
+ sub %o2, 1, %o2
+
+63: ldub [%o1 - 1], %g5
+ sub %o1, 2, %o1
+ stb %g5, [%o0 - 1]
+ sub %o0, 2, %o0
+ ldub [%o1], %g5
+ sub %o2, 2, %o2
+ stb %g5, [%o0]
+64: and %o1, 3, %g2
+ and %o1, -4, %o1
+ and %o2, 0xc, %g3
+ add %o1, 4, %o1
+ cmp %g3, 4
+ sll %g2, 3, %g4
+ mov 32, %g2
+ be 4f
+ sub %g2, %g4, %g6
+
+ blu 3f
+ cmp %g3, 8
+
+ be 2f
+ srl %o2, 2, %g3
+
+ ld [%o1 - 4], %o3
+ add %o0, -8, %o0
+ ld [%o1 - 8], %o4
+ add %o1, -16, %o1
+ b 7f
+ add %g3, 1, %g3
+2: ld [%o1 - 4], %o4
+ add %o0, -4, %o0
+ ld [%o1 - 8], %g1
+ add %o1, -12, %o1
+ b 8f
+ add %g3, 2, %g3
+3: ld [%o1 - 4], %o5
+ add %o0, -12, %o0
+ ld [%o1 - 8], %o3
+ add %o1, -20, %o1
+ b 6f
+ srl %o2, 2, %g3
+4: ld [%o1 - 4], %g1
+ srl %o2, 2, %g3
+ ld [%o1 - 8], %o5
+ add %o1, -24, %o1
+ add %o0, -16, %o0
+ add %g3, -1, %g3
+
+ ld [%o1 + 12], %o3
+5: sll %o5, %g4, %g2
+ srl %g1, %g6, %g5
+ or %g2, %g5, %g2
+ st %g2, [%o0 + 12]
+6: ld [%o1 + 8], %o4
+ sll %o3, %g4, %g2
+ srl %o5, %g6, %g5
+ or %g2, %g5, %g2
+ st %g2, [%o0 + 8]
+7: ld [%o1 + 4], %g1
+ sll %o4, %g4, %g2
+ srl %o3, %g6, %g5
+ or %g2, %g5, %g2
+ st %g2, [%o0 + 4]
+8: ld [%o1], %o5
+ sll %g1, %g4, %g2
+ srl %o4, %g6, %g5
+ addcc %g3, -4, %g3
+ or %g2, %g5, %g2
+ add %o1, -16, %o1
+ st %g2, [%o0]
+ add %o0, -16, %o0
+ bne,a 5b
+ ld [%o1 + 12], %o3
+ sll %o5, %g4, %g2
+ srl %g1, %g6, %g5
+ srl %g4, 3, %g3
+ or %g2, %g5, %g2
+ add %o1, %g3, %o1
+ andcc %o2, 2, %g0
+ st %g2, [%o0 + 12]
+ be 1f
+ andcc %o2, 1, %g0
+
+ ldub [%o1 + 15], %g5
+ add %o1, -2, %o1
+ stb %g5, [%o0 + 11]
+ add %o0, -2, %o0
+ ldub [%o1 + 16], %g5
+ stb %g5, [%o0 + 12]
+1: be 1f
+ nop
+ ldub [%o1 + 15], %g5
+ stb %g5, [%o0 + 11]
+1: retl
+ ld [%sp + 64], %o0
+
+78: andcc %o1, 1, %g0
+ be 4f
+ andcc %o1, 2, %g0
+
+ ldub [%o1], %g2
+ add %o1, 1, %o1
+ stb %g2, [%o0]
+ sub %o2, 1, %o2
+ bne 3f
+ add %o0, 1, %o0
+4: lduh [%o1], %g2
+ add %o1, 2, %o1
+ sth %g2, [%o0]
+ sub %o2, 2, %o2
+ b 3f
+ add %o0, 2, %o0
+END(memmove)
+
+ENTRY(memcpy) /* %o0=dst %o1=src %o2=len */
+ sub %o0, %o1, %o4
+ st %o0, [%sp + 64]
+9: andcc %o4, 3, %o5
+0: bne 86f
+ cmp %o2, 15
+
+ bleu 90f
+ andcc %o1, 3, %g0
+
+ bne 78b
+3: andcc %o1, 4, %g0
+
+ be 2f
+ mov %o2, %g1
+
+ ld [%o1], %o4
+ sub %g1, 4, %g1
+ st %o4, [%o0]
+ add %o1, 4, %o1
+ add %o0, 4, %o0
+2: andcc %g1, 0xffffff80, %g6
+ be 3f
+ andcc %o0, 4, %g0
+
+ be 82f + 4
+5: MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
+ MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
+ MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
+ MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
+ subcc %g6, 128, %g6
+ add %o1, 128, %o1
+ bne 5b
+ add %o0, 128, %o0
+3: andcc %g1, 0x70, %g6
+ be 80f
+ andcc %g1, 8, %g0
+
+ srl %g6, 1, %o4
+ mov %o7, %g2
+ add %g6, %o4, %o4
+ add %o1, %g6, %o1
+104: call 100f
+ add %o0, %g6, %o0
+ jmpl %o5 + (80f - 104b), %g0
+ mov %g2, %o7
+
+79: MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
+ MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
+ MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
+ MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
+ MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
+ MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
+ MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
+
+80: be 81f
+ andcc %g1, 4, %g0
+
+ ldd [%o1], %g2
+ add %o0, 8, %o0
+ st %g2, [%o0 - 0x08]
+ add %o1, 8, %o1
+ st %g3, [%o0 - 0x04]
+
+81: be 1f
+ andcc %g1, 2, %g0
+
+ ld [%o1], %g2
+ add %o1, 4, %o1
+ st %g2, [%o0]
+ add %o0, 4, %o0
+1: be 1f
+ andcc %g1, 1, %g0
+
+ lduh [%o1], %g2
+ add %o1, 2, %o1
+ sth %g2, [%o0]
+ add %o0, 2, %o0
+1: be 1f
+ nop
+
+ ldub [%o1], %g2
+ stb %g2, [%o0]
+1: retl
+ ld [%sp + 64], %o0
+
+82: /* ldd_std */
+ MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
+ MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
+ MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
+ MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
+ subcc %g6, 128, %g6
+ add %o1, 128, %o1
+ bne 82b
+ add %o0, 128, %o0
+
+ andcc %g1, 0x70, %g6
+ be 84f
+ andcc %g1, 8, %g0
+
+ mov %o7, %g2
+111: call 110f
+ add %o1, %g6, %o1
+ mov %g2, %o7
+ jmpl %o5 + (84f - 111b), %g0
+ add %o0, %g6, %o0
+
+83: MOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
+
+84: be 85f
+ andcc %g1, 4, %g0
+
+ ldd [%o1], %g2
+ add %o0, 8, %o0
+ std %g2, [%o0 - 0x08]
+ add %o1, 8, %o1
+85: be 1f
+ andcc %g1, 2, %g0
+
+ ld [%o1], %g2
+ add %o1, 4, %o1
+ st %g2, [%o0]
+ add %o0, 4, %o0
+1: be 1f
+ andcc %g1, 1, %g0
+
+ lduh [%o1], %g2
+ add %o1, 2, %o1
+ sth %g2, [%o0]
+ add %o0, 2, %o0
+1: be 1f
+ nop
+
+ ldub [%o1], %g2
+ stb %g2, [%o0]
+1: retl
+ ld [%sp + 64], %o0
+
+86: cmp %o2, 6
+ bleu 88f
+
+ cmp %o2, 256
+ bcc 87f
+
+ andcc %o0, 3, %g0
+ be 61f
+ andcc %o0, 1, %g0
+ be 60f
+ andcc %o0, 2, %g0
+
+ ldub [%o1], %g5
+ add %o1, 1, %o1
+ stb %g5, [%o0]
+ sub %o2, 1, %o2
+ bne 61f
+ add %o0, 1, %o0
+60: ldub [%o1], %g3
+ add %o1, 2, %o1
+ stb %g3, [%o0]
+ sub %o2, 2, %o2
+ ldub [%o1 - 1], %g3
+ add %o0, 2, %o0
+ stb %g3, [%o0 - 1]
+61: and %o1, 3, %g2
+ and %o2, 0xc, %g3
+ and %o1, -4, %o1
+ cmp %g3, 4
+ sll %g2, 3, %g4
+ mov 32, %g2
+ be 4f
+ sub %g2, %g4, %g6
+
+ blu 3f
+ cmp %g3, 0x8
+
+ be 2f
+ srl %o2, 2, %g3
+
+ ld [%o1], %o3
+ add %o0, -8, %o0
+ ld [%o1 + 4], %o4
+ b 8f
+ add %g3, 1, %g3
+2: ld [%o1], %o4
+ add %o0, -12, %o0
+ ld [%o1 + 4], %o5
+ add %g3, 2, %g3
+ b 9f
+ add %o1, -4, %o1
+3: ld [%o1], %g1
+ add %o0, -4, %o0
+ ld [%o1 + 4], %o3
+ srl %o2, 2, %g3
+ b 7f
+ add %o1, 4, %o1
+4: ld [%o1], %o5
+ cmp %o2, 7
+ ld [%o1 + 4], %g1
+ srl %o2, 2, %g3
+ bleu 10f
+ add %o1, 8, %o1
+
+ ld [%o1], %o3
+ add %g3, -1, %g3
+5: sll %o5, %g4, %g2
+ srl %g1, %g6, %g5
+ or %g2, %g5, %g2
+ st %g2, [%o0]
+7: ld [%o1 + 4], %o4
+ sll %g1, %g4, %g2
+ srl %o3, %g6, %g5
+ or %g2, %g5, %g2
+ st %g2, [%o0 + 4]
+8: ld [%o1 + 8], %o5
+ sll %o3, %g4, %g2
+ srl %o4, %g6, %g5
+ or %g2, %g5, %g2
+ st %g2, [%o0 + 8]
+9: ld [%o1 + 12], %g1
+ sll %o4, %g4, %g2
+ srl %o5, %g6, %g5
+ addcc %g3, -4, %g3
+ or %g2, %g5, %g2
+ add %o1, 16, %o1
+ st %g2, [%o0 + 12]
+ add %o0, 16, %o0
+ bne,a 5b
+ ld [%o1], %o3
+10: sll %o5, %g4, %g2
+ srl %g1, %g6, %g5
+ srl %g6, 3, %g3
+ or %g2, %g5, %g2
+ sub %o1, %g3, %o1
+ andcc %o2, 2, %g0
+ st %g2, [%o0]
+ be 1f
+ andcc %o2, 1, %g0
+
+ ldub [%o1], %g2
+ add %o1, 2, %o1
+ stb %g2, [%o0 + 4]
+ add %o0, 2, %o0
+ ldub [%o1 - 1], %g2
+ stb %g2, [%o0 + 3]
+1: be 1f
+ nop
+ ldub [%o1], %g2
+ stb %g2, [%o0 + 4]
+1: retl
+ ld [%sp + 64], %o0
+
+87: andcc %o1, 3, %g0
+ be 3f
+ andcc %o1, 1, %g0
+
+ be 4f
+ andcc %o1, 2, %g0
+
+ ldub [%o1], %g2
+ add %o1, 1, %o1
+ stb %g2, [%o0]
+ sub %o2, 1, %o2
+ bne 3f
+ add %o0, 1, %o0
+4: lduh [%o1], %g2
+ add %o1, 2, %o1
+ srl %g2, 8, %g3
+ sub %o2, 2, %o2
+ stb %g3, [%o0]
+ add %o0, 2, %o0
+ stb %g2, [%o0 - 1]
+3: andcc %o1, 4, %g0
+
+ bne 2f
+ cmp %o5, 1
+
+ ld [%o1], %o4
+ srl %o4, 24, %g2
+ stb %g2, [%o0]
+ srl %o4, 16, %g3
+ stb %g3, [%o0 + 1]
+ srl %o4, 8, %g2
+ stb %g2, [%o0 + 2]
+ sub %o2, 4, %o2
+ stb %o4, [%o0 + 3]
+ add %o1, 4, %o1
+ add %o0, 4, %o0
+2: be 33f
+ cmp %o5, 2
+ be 32f
+ sub %o2, 4, %o2
+31: ld [%o1], %g2
+ add %o1, 4, %o1
+ srl %g2, 24, %g3
+ and %o0, 7, %g5
+ stb %g3, [%o0]
+ cmp %g5, 7
+ sll %g2, 8, %g1
+ add %o0, 4, %o0
+ be 41f
+ and %o2, 0xffffffc0, %o3
+ ld [%o0 - 7], %o4
+4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
+ SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
+ SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
+ SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
+ subcc %o3, 64, %o3
+ add %o1, 64, %o1
+ bne 4b
+ add %o0, 64, %o0
+
+ andcc %o2, 0x30, %o3
+ be,a 1f
+ srl %g1, 16, %g2
+4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
+ subcc %o3, 16, %o3
+ add %o1, 16, %o1
+ bne 4b
+ add %o0, 16, %o0
+
+ srl %g1, 16, %g2
+1: st %o4, [%o0 - 7]
+ sth %g2, [%o0 - 3]
+ srl %g1, 8, %g4
+ b 88f
+ stb %g4, [%o0 - 1]
+32: ld [%o1], %g2
+ add %o1, 4, %o1
+ srl %g2, 16, %g3
+ and %o0, 7, %g5
+ sth %g3, [%o0]
+ cmp %g5, 6
+ sll %g2, 16, %g1
+ add %o0, 4, %o0
+ be 42f
+ and %o2, 0xffffffc0, %o3
+ ld [%o0 - 6], %o4
+4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
+ SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
+ SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
+ SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
+ subcc %o3, 64, %o3
+ add %o1, 64, %o1
+ bne 4b
+ add %o0, 64, %o0
+
+ andcc %o2, 0x30, %o3
+ be,a 1f
+ srl %g1, 16, %g2
+4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
+ subcc %o3, 16, %o3
+ add %o1, 16, %o1
+ bne 4b
+ add %o0, 16, %o0
+
+ srl %g1, 16, %g2
+1: st %o4, [%o0 - 6]
+ b 88f
+ sth %g2, [%o0 - 2]
+33: ld [%o1], %g2
+ sub %o2, 4, %o2
+ srl %g2, 24, %g3
+ and %o0, 7, %g5
+ stb %g3, [%o0]
+ cmp %g5, 5
+ srl %g2, 8, %g4
+ sll %g2, 24, %g1
+ sth %g4, [%o0 + 1]
+ add %o1, 4, %o1
+ be 43f
+ and %o2, 0xffffffc0, %o3
+
+ ld [%o0 - 1], %o4
+ add %o0, 4, %o0
+4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
+ SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
+ SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
+ SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
+ subcc %o3, 64, %o3
+ add %o1, 64, %o1
+ bne 4b
+ add %o0, 64, %o0
+
+ andcc %o2, 0x30, %o3
+ be,a 1f
+ srl %g1, 24, %g2
+4: SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, -1)
+ subcc %o3, 16, %o3
+ add %o1, 16, %o1
+ bne 4b
+ add %o0, 16, %o0
+
+ srl %g1, 24, %g2
+1: st %o4, [%o0 - 5]
+ b 88f
+ stb %g2, [%o0 - 1]
+41: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
+ subcc %o3, 64, %o3
+ add %o1, 64, %o1
+ bne 41b
+ add %o0, 64, %o0
+
+ andcc %o2, 0x30, %o3
+ be,a 1f
+ srl %g1, 16, %g2
+4: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 8, 24, -3)
+ subcc %o3, 16, %o3
+ add %o1, 16, %o1
+ bne 4b
+ add %o0, 16, %o0
+
+ srl %g1, 16, %g2
+1: sth %g2, [%o0 - 3]
+ srl %g1, 8, %g4
+ b 88f
+ stb %g4, [%o0 - 1]
+43: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
+ subcc %o3, 64, %o3
+ add %o1, 64, %o1
+ bne 43b
+ add %o0, 64, %o0
+
+ andcc %o2, 0x30, %o3
+ be,a 1f
+ srl %g1, 24, %g2
+4: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 24, 8, 3)
+ subcc %o3, 16, %o3
+ add %o1, 16, %o1
+ bne 4b
+ add %o0, 16, %o0
+
+ srl %g1, 24, %g2
+1: stb %g2, [%o0 + 3]
+ b 88f
+ add %o0, 4, %o0
+42: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
+ subcc %o3, 64, %o3
+ add %o1, 64, %o1
+ bne 42b
+ add %o0, 64, %o0
+
+ andcc %o2, 0x30, %o3
+ be,a 1f
+ srl %g1, 16, %g2
+4: SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g6, g1, 16, 16, -2)
+ subcc %o3, 16, %o3
+ add %o1, 16, %o1
+ bne 4b
+ add %o0, 16, %o0
+
+ srl %g1, 16, %g2
+1: sth %g2, [%o0 - 2]
+
+ /* Fall through */
+
+88: and %o2, 0xe, %o3
+ mov %o7, %g2
+ sll %o3, 3, %o4
+ add %o0, %o3, %o0
+106: call 100f
+ add %o1, %o3, %o1
+ mov %g2, %o7
+ jmpl %o5 + (89f - 106b), %g0
+ andcc %o2, 1, %g0
+
+ MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
+ MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
+ MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
+ MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
+ MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
+ MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
+ MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
+
+89: be 1f
+ nop
+
+ ldub [%o1], %g2
+ stb %g2, [%o0]
+1: retl
+ ld [%sp + 64], %o0
+
+90: bne 88b
+ andcc %o2, 8, %g0
+
+ be 1f
+ andcc %o2, 4, %g0
+
+ ld [%o1 + 0x00], %g2
+ ld [%o1 + 0x04], %g3
+ add %o1, 8, %o1
+ st %g2, [%o0 + 0x00]
+ st %g3, [%o0 + 0x04]
+ add %o0, 8, %o0
+1: b 81b
+ mov %o2, %g1
+
+100: retl
+ sub %o7, %o4, %o5
+110: retl
+ sub %o7, %g6, %o5
+END(memcpy)
+libc_hidden_builtin_def (memcpy)
+libc_hidden_builtin_def (memmove)
diff --git a/libc/sysdeps/sparc/sparc32/memmove.c b/libc/sysdeps/sparc/sparc32/memmove.c
new file mode 100644
index 000000000..a8d2d4994
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/memmove.c
@@ -0,0 +1 @@
+/* memmove is in memcpy.S */
diff --git a/libc/sysdeps/sparc/sparc32/memset.S b/libc/sysdeps/sparc/sparc32/memset.S
new file mode 100644
index 000000000..e6204e8ac
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/memset.S
@@ -0,0 +1,155 @@
+/* Set a block of memory to some byte value.
+ For SPARC v7.
+ Copyright (C) 1996, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller <davem@caip.rutgers.edu> and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ /* Store 64 bytes at (BASE + OFFSET) using value SOURCE. */
+#define ZERO_BIG_BLOCK(base, offset, source) \
+ std source, [base + offset + 0x00]; \
+ std source, [base + offset + 0x08]; \
+ std source, [base + offset + 0x10]; \
+ std source, [base + offset + 0x18]; \
+ std source, [base + offset + 0x20]; \
+ std source, [base + offset + 0x28]; \
+ std source, [base + offset + 0x30]; \
+ std source, [base + offset + 0x38];
+
+#define ZERO_LAST_BLOCKS(base, offset, source) \
+ std source, [base - offset - 0x38]; \
+ std source, [base - offset - 0x30]; \
+ std source, [base - offset - 0x28]; \
+ std source, [base - offset - 0x20]; \
+ std source, [base - offset - 0x18]; \
+ std source, [base - offset - 0x10]; \
+ std source, [base - offset - 0x08]; \
+ std source, [base - offset - 0x00];
+
+ .text
+ .align 4
+ENTRY(__bzero)
+ b 1f
+ mov %g0, %g3
+
+3: cmp %o2, 3
+ be 2f
+ stb %g3, [%o0]
+
+ cmp %o2, 2
+ be 2f
+ stb %g3, [%o0 + 0x01]
+
+ stb %g3, [%o0 + 0x02]
+2: sub %o2, 4, %o2
+ add %o1, %o2, %o1
+ b 4f
+ sub %o0, %o2, %o0
+END(__bzero)
+
+ENTRY(memset)
+ and %o1, 0xff, %g3
+ sll %g3, 8, %g2
+ or %g3, %g2, %g3
+ sll %g3, 16, %g2
+ or %g3, %g2, %g3
+ orcc %o2, %g0, %o1
+1: cmp %o1, 7
+ bleu 7f
+ mov %o0, %g1
+
+ andcc %o0, 3, %o2
+ bne 3b
+4: andcc %o0, 4, %g0
+
+ be 2f
+ mov %g3, %g2
+
+ st %g3, [%o0]
+ sub %o1, 4, %o1
+ add %o0, 4, %o0
+2: andcc %o1, 0xffffff80, %o3
+ be 9f
+ andcc %o1, 0x78, %o2
+4: ZERO_BIG_BLOCK (%o0, 0x00, %g2)
+ subcc %o3, 128, %o3
+ ZERO_BIG_BLOCK (%o0, 0x40, %g2)
+ bne 4b
+ add %o0, 128, %o0
+
+ orcc %o2, %g0, %g0
+9: be 6f
+ andcc %o1, 7, %o1
+
+ mov %o7, %g4
+101: call 100f
+ srl %o2, 1, %o3
+ mov %g4, %o7
+ jmpl %o4 + (20f + 64 - 101b), %g0
+ add %o0, %o2, %o0
+
+100: retl
+ sub %o7, %o3, %o4
+
+20: ZERO_LAST_BLOCKS(%o0, 0x48, %g2)
+ ZERO_LAST_BLOCKS(%o0, 0x08, %g2)
+
+6: be 8f
+ andcc %o1, 4, %g0
+ be 1f
+ andcc %o1, 2, %g0
+ st %g3, [%o0]
+ add %o0, 4, %o0
+1: be 1f
+ andcc %o1, 1, %g0
+ sth %g3, [%o0]
+ add %o0, 2, %o0
+1: bne,a 8f
+ stb %g3, [%o0]
+8: retl
+ mov %g1, %o0
+7: orcc %o1, 0, %g0
+ be 0f
+ subcc %o1, 1, %o1
+ stb %g3, [%o0]
+ be 0f
+ subcc %o1, 1, %o1
+ stb %g3, [%o0 + 1]
+ be 0f
+ subcc %o1, 1, %o1
+ stb %g3, [%o0 + 2]
+ be 0f
+ subcc %o1, 1, %o1
+ stb %g3, [%o0 + 3]
+ be 0f
+ subcc %o1, 1, %o1
+ stb %g3, [%o0 + 4]
+ be 0f
+ subcc %o1, 1, %o1
+ stb %g3, [%o0 + 5]
+ be 0f
+ subcc %o1, 1, %o1
+ stb %g3, [%o0 + 6]
+0: retl
+ nop
+END(memset)
+libc_hidden_builtin_def (memset)
+
+weak_alias (__bzero, bzero)
diff --git a/libc/sysdeps/sparc/sparc32/mul_1.S b/libc/sysdeps/sparc/sparc32/mul_1.S
new file mode 100644
index 000000000..868ca2614
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/mul_1.S
@@ -0,0 +1,199 @@
+! SPARC __mpn_mul_1 -- Multiply a limb vector with a limb and store
+! the result in a second limb vector.
+!
+! Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+!
+! This file is part of the GNU MP Library.
+!
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at your
+! option) any later version.
+!
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+! License for more details.
+!
+! You should have received a copy of the GNU Lesser General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! RES_PTR o0
+! S1_PTR o1
+! SIZE o2
+! S2_LIMB o3
+
+! ADD CODE FOR SMALL MULTIPLIERS!
+!1: ld
+! st
+!
+!2: ld ,a
+! addxcc a,a,x
+! st x,
+!
+!3_unrolled:
+! ld ,a
+! addxcc a,a,x1 ! 2a + cy
+! addx %g0,%g0,x2
+! addcc a,x1,x ! 3a + c
+! st x,
+!
+! ld ,a
+! addxcc a,a,y1
+! addx %g0,%g0,y2
+! addcc a,y1,x
+! st x,
+!
+!4_unrolled:
+! ld ,a
+! srl a,2,x1 ! 4a
+! addxcc y2,x1,x
+! sll a,30,x2
+! st x,
+!
+! ld ,a
+! srl a,2,y1
+! addxcc x2,y1,y
+! sll a,30,y2
+! st x,
+!
+!5_unrolled:
+! ld ,a
+! srl a,2,x1 ! 4a
+! addxcc a,x1,x ! 5a + c
+! sll a,30,x2
+! addx %g0,x2,x2
+! st x,
+!
+! ld ,a
+! srl a,2,y1
+! addxcc a,y1,x
+! sll a,30,y2
+! addx %g0,y2,y2
+! st x,
+!
+!8_unrolled:
+! ld ,a
+! srl a,3,x1 ! 8a
+! addxcc y2,x1,x
+! sll a,29,x2
+! st x,
+!
+! ld ,a
+! srl a,3,y1
+! addxcc x2,y1,y
+! sll a,29,y2
+! st x,
+
+#include <sysdep.h>
+
+ENTRY(__mpn_mul_1)
+ ! Make S1_PTR and RES_PTR point at the end of their blocks
+ ! and put (- 4 x SIZE) in index/loop counter.
+ sll %o2,2,%o2
+ add %o0,%o2,%o4 ! RES_PTR in o4 since o0 is retval
+ add %o1,%o2,%o1
+ sub %g0,%o2,%o2
+
+ cmp %o3,0xfff
+ bgu LOC(large)
+ nop
+
+ ld [%o1+%o2],%o5
+ mov 0,%o0
+ b LOC(0)
+ add %o4,-4,%o4
+LOC(loop0):
+ st %g1,[%o4+%o2]
+LOC(0): wr %g0,%o3,%y
+ sra %o5,31,%g2
+ and %o3,%g2,%g2
+ andcc %g1,0,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,0,%g1
+ sra %g1,20,%g4
+ sll %g1,12,%g1
+ rd %y,%g3
+ srl %g3,20,%g3
+ or %g1,%g3,%g1
+
+ addcc %g1,%o0,%g1
+ addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
+ addcc %o2,4,%o2 ! loop counter
+ bne,a LOC(loop0)
+ ld [%o1+%o2],%o5
+
+ retl
+ st %g1,[%o4+%o2]
+
+
+LOC(large):
+ ld [%o1+%o2],%o5
+ mov 0,%o0
+ sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
+ b LOC(1)
+ add %o4,-4,%o4
+LOC(loop):
+ st %g3,[%o4+%o2]
+LOC(1): wr %g0,%o5,%y
+ and %o5,%g4,%g2 ! g2 = S1_LIMB iff S2_LIMB < 0, else 0
+ andcc %g0,%g0,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%g0,%g1
+ rd %y,%g3
+ addcc %g3,%o0,%g3
+ addx %g2,%g1,%o0 ! add sign-compensation and cy to hi limb
+ addcc %o2,4,%o2 ! loop counter
+ bne,a LOC(loop)
+ ld [%o1+%o2],%o5
+
+ retl
+ st %g3,[%o4+%o2]
+
+END(__mpn_mul_1)
diff --git a/libc/sysdeps/sparc/sparc32/rem.S b/libc/sysdeps/sparc/sparc32/rem.S
new file mode 100644
index 000000000..effacee0d
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/rem.S
@@ -0,0 +1,363 @@
+ /* This file is generated from divrem.m4; DO NOT EDIT! */
+/*
+ * Division and remainder, from Appendix E of the Sparc Version 8
+ * Architecture Manual, with fixes from Gordon Irlam.
+ */
+
+/*
+ * Input: dividend and divisor in %o0 and %o1 respectively.
+ *
+ * m4 parameters:
+ * .rem name of function to generate
+ * rem rem=div => %o0 / %o1; rem=rem => %o0 % %o1
+ * true true=true => signed; true=false => unsigned
+ *
+ * Algorithm parameters:
+ * N how many bits per iteration we try to get (4)
+ * WORDSIZE total number of bits (32)
+ *
+ * Derived constants:
+ * TOPBITS number of bits in the top decade of a number
+ *
+ * Important variables:
+ * Q the partial quotient under development (initially 0)
+ * R the remainder so far, initially the dividend
+ * ITER number of main division loop iterations required;
+ * equal to ceil(log2(quotient) / N). Note that this
+ * is the log base (2^N) of the quotient.
+ * V the current comparand, initially divisor*2^(ITER*N-1)
+ *
+ * Cost:
+ * Current estimate for non-large dividend is
+ * ceil(log2(quotient) / N) * (10 + 7N/2) + C
+ * A large dividend is one greater than 2^(31-TOPBITS) and takes a
+ * different path, as the upper bits of the quotient must be developed
+ * one bit at a time.
+ */
+
+
+
+#include <sysdep.h>
+#include <sys/trap.h>
+
+ENTRY(.rem)
+ ! compute sign of result; if neither is negative, no problem
+ orcc %o1, %o0, %g0 ! either negative?
+ bge 2f ! no, go do the divide
+ mov %o0, %g3 ! sign of remainder matches %o0
+ tst %o1
+ bge 1f
+ tst %o0
+ ! %o1 is definitely negative; %o0 might also be negative
+ bge 2f ! if %o0 not negative...
+ sub %g0, %o1, %o1 ! in any case, make %o1 nonneg
+1: ! %o0 is negative, %o1 is nonnegative
+ sub %g0, %o0, %o0 ! make %o0 nonnegative
+2:
+
+ ! Ready to divide. Compute size of quotient; scale comparand.
+ orcc %o1, %g0, %o5
+ bne 1f
+ mov %o0, %o3
+
+ ! Divide by zero trap. If it returns, return 0 (about as
+ ! wrong as possible, but that is what SunOS does...).
+ ta ST_DIV0
+ retl
+ clr %o0
+
+1:
+ cmp %o3, %o5 ! if %o1 exceeds %o0, done
+ blu LOC(got_result) ! (and algorithm fails otherwise)
+ clr %o2
+ sethi %hi(1 << (32 - 4 - 1)), %g1
+ cmp %o3, %g1
+ blu LOC(not_really_big)
+ clr %o4
+
+ ! Here the dividend is >= 2**(31-N) or so. We must be careful here,
+ ! as our usual N-at-a-shot divide step will cause overflow and havoc.
+ ! The number of bits in the result here is N*ITER+SC, where SC <= N.
+ ! Compute ITER in an unorthodox manner: know we need to shift V into
+ ! the top decade: so do not even bother to compare to R.
+ 1:
+ cmp %o5, %g1
+ bgeu 3f
+ mov 1, %g2
+ sll %o5, 4, %o5
+ b 1b
+ add %o4, 1, %o4
+
+ ! Now compute %g2.
+ 2: addcc %o5, %o5, %o5
+ bcc LOC(not_too_big)
+ add %g2, 1, %g2
+
+ ! We get here if the %o1 overflowed while shifting.
+ ! This means that %o3 has the high-order bit set.
+ ! Restore %o5 and subtract from %o3.
+ sll %g1, 4, %g1 ! high order bit
+ srl %o5, 1, %o5 ! rest of %o5
+ add %o5, %g1, %o5
+ b LOC(do_single_div)
+ sub %g2, 1, %g2
+
+ LOC(not_too_big):
+ 3: cmp %o5, %o3
+ blu 2b
+ nop
+ be LOC(do_single_div)
+ nop
+ /* NB: these are commented out in the V8-Sparc manual as well */
+ /* (I do not understand this) */
+ ! %o5 > %o3: went too far: back up 1 step
+ ! srl %o5, 1, %o5
+ ! dec %g2
+ ! do single-bit divide steps
+ !
+ ! We have to be careful here. We know that %o3 >= %o5, so we can do the
+ ! first divide step without thinking. BUT, the others are conditional,
+ ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high-
+ ! order bit set in the first step, just falling into the regular
+ ! division loop will mess up the first time around.
+ ! So we unroll slightly...
+ LOC(do_single_div):
+ subcc %g2, 1, %g2
+ bl LOC(end_regular_divide)
+ nop
+ sub %o3, %o5, %o3
+ mov 1, %o2
+ b LOC(end_single_divloop)
+ nop
+ LOC(single_divloop):
+ sll %o2, 1, %o2
+ bl 1f
+ srl %o5, 1, %o5
+ ! %o3 >= 0
+ sub %o3, %o5, %o3
+ b 2f
+ add %o2, 1, %o2
+ 1: ! %o3 < 0
+ add %o3, %o5, %o3
+ sub %o2, 1, %o2
+ 2:
+ LOC(end_single_divloop):
+ subcc %g2, 1, %g2
+ bge LOC(single_divloop)
+ tst %o3
+ b,a LOC(end_regular_divide)
+
+LOC(not_really_big):
+1:
+ sll %o5, 4, %o5
+ cmp %o5, %o3
+ bleu 1b
+ addcc %o4, 1, %o4
+ be LOC(got_result)
+ sub %o4, 1, %o4
+
+ tst %o3 ! set up for initial iteration
+LOC(divloop):
+ sll %o2, 4, %o2
+ ! depth 1, accumulated bits 0
+ bl LOC(1.16)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 2, accumulated bits 1
+ bl LOC(2.17)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 3, accumulated bits 3
+ bl LOC(3.19)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 7
+ bl LOC(4.23)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (7*2+1), %o2
+
+LOC(4.23):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (7*2-1), %o2
+
+
+LOC(3.19):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 5
+ bl LOC(4.21)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (5*2+1), %o2
+
+LOC(4.21):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (5*2-1), %o2
+
+
+
+LOC(2.17):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 3, accumulated bits 1
+ bl LOC(3.17)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 3
+ bl LOC(4.19)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (3*2+1), %o2
+
+LOC(4.19):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (3*2-1), %o2
+
+
+LOC(3.17):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 1
+ bl LOC(4.17)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (1*2+1), %o2
+
+LOC(4.17):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (1*2-1), %o2
+
+
+
+
+LOC(1.16):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 2, accumulated bits -1
+ bl LOC(2.15)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 3, accumulated bits -1
+ bl LOC(3.15)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -1
+ bl LOC(4.15)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-1*2+1), %o2
+
+LOC(4.15):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-1*2-1), %o2
+
+
+LOC(3.15):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -3
+ bl LOC(4.13)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-3*2+1), %o2
+
+LOC(4.13):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-3*2-1), %o2
+
+
+
+LOC(2.15):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 3, accumulated bits -3
+ bl LOC(3.13)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -5
+ bl LOC(4.11)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-5*2+1), %o2
+
+LOC(4.11):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-5*2-1), %o2
+
+
+LOC(3.13):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -7
+ bl LOC(4.9)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-7*2+1), %o2
+
+LOC(4.9):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-7*2-1), %o2
+
+
+
+
+ 9:
+LOC(end_regular_divide):
+ subcc %o4, 1, %o4
+ bge LOC(divloop)
+ tst %o3
+ bl,a LOC(got_result)
+ ! non-restoring fixup here (one instruction only!)
+ add %o3, %o1, %o3
+
+
+LOC(got_result):
+ ! check to see if answer should be < 0
+ tst %g3
+ bl,a 1f
+ sub %g0, %o3, %o3
+1:
+ retl
+ mov %o3, %o0
+
+END(.rem)
diff --git a/libc/sysdeps/sparc/sparc32/rshift.S b/libc/sysdeps/sparc/sparc32/rshift.S
new file mode 100644
index 000000000..f2c1d47db
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/rshift.S
@@ -0,0 +1,94 @@
+! sparc __mpn_rshift --
+!
+! Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+!
+! This file is part of the GNU MP Library.
+!
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at your
+! option) any later version.
+!
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+! License for more details.
+!
+! You should have received a copy of the GNU Lesser General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! RES_PTR %o0
+! SRC_PTR %o1
+! SIZE %o2
+! CNT %o3
+
+#include <sysdep.h>
+
+ENTRY(__mpn_rshift)
+ ld [%o1],%g2 ! load first limb
+ sub %g0,%o3,%o5 ! negate shift count
+ add %o2,-1,%o2
+ andcc %o2,4-1,%g4 ! number of limbs in first loop
+ sll %g2,%o5,%g1 ! compute function result
+ be LOC(0) ! if multiple of 4 limbs, skip first loop
+ st %g1,[%sp+80]
+
+ sub %o2,%g4,%o2 ! adjust count for main loop
+
+LOC(loop0):
+ ld [%o1+4],%g3
+ add %o0,4,%o0
+ add %o1,4,%o1
+ addcc %g4,-1,%g4
+ srl %g2,%o3,%o4
+ sll %g3,%o5,%g1
+ mov %g3,%g2
+ or %o4,%g1,%o4
+ bne LOC(loop0)
+ st %o4,[%o0-4]
+
+LOC(0): tst %o2
+ be LOC(end)
+ nop
+
+LOC(loop):
+ ld [%o1+4],%g3
+ add %o0,16,%o0
+ addcc %o2,-4,%o2
+ srl %g2,%o3,%o4
+ sll %g3,%o5,%g1
+
+ ld [%o1+8],%g2
+ srl %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0-16]
+ sll %g2,%o5,%g1
+
+ ld [%o1+12],%g3
+ srl %g2,%o3,%o4
+ or %g4,%g1,%g4
+ st %g4,[%o0-12]
+ sll %g3,%o5,%g1
+
+ ld [%o1+16],%g2
+ srl %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0-8]
+ sll %g2,%o5,%g1
+
+ add %o1,16,%o1
+ or %g4,%g1,%g4
+ bne LOC(loop)
+ st %g4,[%o0-4]
+
+LOC(end):
+ srl %g2,%o3,%g2
+ st %g2,[%o0-0]
+ retl
+ ld [%sp+80],%o0
+
+END(__mpn_rshift)
diff --git a/libc/sysdeps/sparc/sparc32/sdiv.S b/libc/sysdeps/sparc/sparc32/sdiv.S
new file mode 100644
index 000000000..4b325476d
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sdiv.S
@@ -0,0 +1,363 @@
+ /* This file is generated from divrem.m4; DO NOT EDIT! */
+/*
+ * Division and remainder, from Appendix E of the Sparc Version 8
+ * Architecture Manual, with fixes from Gordon Irlam.
+ */
+
+/*
+ * Input: dividend and divisor in %o0 and %o1 respectively.
+ *
+ * m4 parameters:
+ * .div name of function to generate
+ * div div=div => %o0 / %o1; div=rem => %o0 % %o1
+ * true true=true => signed; true=false => unsigned
+ *
+ * Algorithm parameters:
+ * N how many bits per iteration we try to get (4)
+ * WORDSIZE total number of bits (32)
+ *
+ * Derived constants:
+ * TOPBITS number of bits in the top decade of a number
+ *
+ * Important variables:
+ * Q the partial quotient under development (initially 0)
+ * R the remainder so far, initially the dividend
+ * ITER number of main division loop iterations required;
+ * equal to ceil(log2(quotient) / N). Note that this
+ * is the log base (2^N) of the quotient.
+ * V the current comparand, initially divisor*2^(ITER*N-1)
+ *
+ * Cost:
+ * Current estimate for non-large dividend is
+ * ceil(log2(quotient) / N) * (10 + 7N/2) + C
+ * A large dividend is one greater than 2^(31-TOPBITS) and takes a
+ * different path, as the upper bits of the quotient must be developed
+ * one bit at a time.
+ */
+
+
+
+#include <sysdep.h>
+#include <sys/trap.h>
+
+ENTRY(.div)
+ ! compute sign of result; if neither is negative, no problem
+ orcc %o1, %o0, %g0 ! either negative?
+ bge 2f ! no, go do the divide
+ xor %o1, %o0, %g3 ! compute sign in any case
+ tst %o1
+ bge 1f
+ tst %o0
+ ! %o1 is definitely negative; %o0 might also be negative
+ bge 2f ! if %o0 not negative...
+ sub %g0, %o1, %o1 ! in any case, make %o1 nonneg
+1: ! %o0 is negative, %o1 is nonnegative
+ sub %g0, %o0, %o0 ! make %o0 nonnegative
+2:
+
+ ! Ready to divide. Compute size of quotient; scale comparand.
+ orcc %o1, %g0, %o5
+ bne 1f
+ mov %o0, %o3
+
+ ! Divide by zero trap. If it returns, return 0 (about as
+ ! wrong as possible, but that is what SunOS does...).
+ ta ST_DIV0
+ retl
+ clr %o0
+
+1:
+ cmp %o3, %o5 ! if %o1 exceeds %o0, done
+ blu LOC(got_result) ! (and algorithm fails otherwise)
+ clr %o2
+ sethi %hi(1 << (32 - 4 - 1)), %g1
+ cmp %o3, %g1
+ blu LOC(not_really_big)
+ clr %o4
+
+ ! Here the dividend is >= 2**(31-N) or so. We must be careful here,
+ ! as our usual N-at-a-shot divide step will cause overflow and havoc.
+ ! The number of bits in the result here is N*ITER+SC, where SC <= N.
+ ! Compute ITER in an unorthodox manner: know we need to shift V into
+ ! the top decade: so do not even bother to compare to R.
+ 1:
+ cmp %o5, %g1
+ bgeu 3f
+ mov 1, %g2
+ sll %o5, 4, %o5
+ b 1b
+ add %o4, 1, %o4
+
+ ! Now compute %g2.
+ 2: addcc %o5, %o5, %o5
+ bcc LOC(not_too_big)
+ add %g2, 1, %g2
+
+ ! We get here if the %o1 overflowed while shifting.
+ ! This means that %o3 has the high-order bit set.
+ ! Restore %o5 and subtract from %o3.
+ sll %g1, 4, %g1 ! high order bit
+ srl %o5, 1, %o5 ! rest of %o5
+ add %o5, %g1, %o5
+ b LOC(do_single_div)
+ sub %g2, 1, %g2
+
+ LOC(not_too_big):
+ 3: cmp %o5, %o3
+ blu 2b
+ nop
+ be LOC(do_single_div)
+ nop
+ /* NB: these are commented out in the V8-Sparc manual as well */
+ /* (I do not understand this) */
+ ! %o5 > %o3: went too far: back up 1 step
+ ! srl %o5, 1, %o5
+ ! dec %g2
+ ! do single-bit divide steps
+ !
+ ! We have to be careful here. We know that %o3 >= %o5, so we can do the
+ ! first divide step without thinking. BUT, the others are conditional,
+ ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high-
+ ! order bit set in the first step, just falling into the regular
+ ! division loop will mess up the first time around.
+ ! So we unroll slightly...
+ LOC(do_single_div):
+ subcc %g2, 1, %g2
+ bl LOC(end_regular_divide)
+ nop
+ sub %o3, %o5, %o3
+ mov 1, %o2
+ b LOC(end_single_divloop)
+ nop
+ LOC(single_divloop):
+ sll %o2, 1, %o2
+ bl 1f
+ srl %o5, 1, %o5
+ ! %o3 >= 0
+ sub %o3, %o5, %o3
+ b 2f
+ add %o2, 1, %o2
+ 1: ! %o3 < 0
+ add %o3, %o5, %o3
+ sub %o2, 1, %o2
+ 2:
+ LOC(end_single_divloop):
+ subcc %g2, 1, %g2
+ bge LOC(single_divloop)
+ tst %o3
+ b,a LOC(end_regular_divide)
+
+LOC(not_really_big):
+1:
+ sll %o5, 4, %o5
+ cmp %o5, %o3
+ bleu 1b
+ addcc %o4, 1, %o4
+ be LOC(got_result)
+ sub %o4, 1, %o4
+
+ tst %o3 ! set up for initial iteration
+LOC(divloop):
+ sll %o2, 4, %o2
+ ! depth 1, accumulated bits 0
+ bl LOC(1.16)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 2, accumulated bits 1
+ bl LOC(2.17)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 3, accumulated bits 3
+ bl LOC(3.19)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 7
+ bl LOC(4.23)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (7*2+1), %o2
+
+LOC(4.23):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (7*2-1), %o2
+
+
+LOC(3.19):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 5
+ bl LOC(4.21)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (5*2+1), %o2
+
+LOC(4.21):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (5*2-1), %o2
+
+
+
+LOC(2.17):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 3, accumulated bits 1
+ bl LOC(3.17)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 3
+ bl LOC(4.19)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (3*2+1), %o2
+
+LOC(4.19):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (3*2-1), %o2
+
+
+LOC(3.17):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 1
+ bl LOC(4.17)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (1*2+1), %o2
+
+LOC(4.17):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (1*2-1), %o2
+
+
+
+
+LOC(1.16):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 2, accumulated bits -1
+ bl LOC(2.15)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 3, accumulated bits -1
+ bl LOC(3.15)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -1
+ bl LOC(4.15)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-1*2+1), %o2
+
+LOC(4.15):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-1*2-1), %o2
+
+
+LOC(3.15):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -3
+ bl LOC(4.13)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-3*2+1), %o2
+
+LOC(4.13):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-3*2-1), %o2
+
+
+
+LOC(2.15):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 3, accumulated bits -3
+ bl LOC(3.13)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -5
+ bl LOC(4.11)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-5*2+1), %o2
+
+LOC(4.11):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-5*2-1), %o2
+
+
+LOC(3.13):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -7
+ bl LOC(4.9)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-7*2+1), %o2
+
+LOC(4.9):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-7*2-1), %o2
+
+
+
+
+ 9:
+LOC(end_regular_divide):
+ subcc %o4, 1, %o4
+ bge LOC(divloop)
+ tst %o3
+ bl,a LOC(got_result)
+ ! non-restoring fixup here (one instruction only!)
+ sub %o2, 1, %o2
+
+
+LOC(got_result):
+ ! check to see if answer should be < 0
+ tst %g3
+ bl,a 1f
+ sub %g0, %o2, %o2
+1:
+ retl
+ mov %o2, %o0
+
+END(.div)
diff --git a/libc/sysdeps/sparc/sparc32/setjmp.S b/libc/sysdeps/sparc/sparc32/setjmp.S
new file mode 100644
index 000000000..0a5d3cece
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/setjmp.S
@@ -0,0 +1,60 @@
+/* Copyright (C) 1991, 1993, 1994, 1996, 1997, 1998, 2002, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <sys/trap.h>
+
+#include <jmpbuf-offsets.h>
+
+ENTRY(_setjmp)
+ b 1f
+ set 0, %o1
+END(_setjmp)
+libc_hidden_def (_setjmp)
+
+ENTRY(setjmp)
+ set 1, %o1
+END(setjmp)
+
+ENTRY (__sigsetjmp)
+1:
+ /* Save our PC, SP and FP. Save the signal mask if requested with
+ a tail-call for simplicity; it always returns zero. */
+ ta ST_FLUSH_WINDOWS
+
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%g1, %o7, %g4)
+ PTR_MANGLE2 (%g2, %sp, %g4)
+ PTR_MANGLE2 (%g3, %fp, %g4)
+ st %g1, [%o0 + (JB_PC * 4)]
+ st %g2, [%o0 + (JB_SP * 4)]
+ st %g3, [%o0 + (JB_FP * 4)]
+#else
+ st %o7, [%o0 + (JB_PC * 4)]
+ st %sp, [%o0 + (JB_SP * 4)]
+ st %fp, [%o0 + (JB_FP * 4)]
+#endif
+
+ mov %o7, %g1
+ call __sigjmp_save
+ mov %g1, %o7
+END(__sigsetjmp)
+
+weak_extern(_setjmp)
+weak_extern(setjmp)
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/Makefile b/libc/sysdeps/sparc/sparc32/soft-fp/Makefile
new file mode 100644
index 000000000..d447b4828
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/Makefile
@@ -0,0 +1,30 @@
+# Software floating-point emulation.
+# Makefile for SPARC v8 long double utility functions (_Q_*).
+# Copyright (C) 1999, 2000, 2006 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+#
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifeq ($(subdir),soft-fp)
+sparc32-quad-routines := q_add q_cmp q_cmpe q_div q_dtoq q_feq q_fge \
+ q_fgt q_fle q_flt q_fne q_itoq q_mul q_neg q_qtod q_qtoi \
+ q_qtos q_qtou q_qtoull q_qtoll q_sqrt q_stoq q_sub q_utoq \
+ q_ulltoq q_lltoq q_util
+sysdep_routines += $(sparc32-quad-routines)
+
+endif
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/Versions b/libc/sysdeps/sparc/sparc32/soft-fp/Versions
new file mode 100644
index 000000000..6a09249c4
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/Versions
@@ -0,0 +1,8 @@
+libc {
+ GLIBC_2.4 {
+ _Q_add; _Q_cmp; _Q_cmpe; _Q_div; _Q_dtoq; _Q_feq; _Q_fge; _Q_fgt;
+ _Q_fle; _Q_flt; _Q_fne; _Q_itoq; _Q_mul; _Q_neg; _Q_qtod; _Q_qtoi;
+ _Q_qtos; _Q_qtou; _Q_qtoull; _Q_qtoll; _Q_sqrt; _Q_stoq; _Q_sub;
+ _Q_utoq; _Q_ulltoq; _Q_lltoq;
+ }
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_add.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_add.c
new file mode 100644
index 000000000..987c72558
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_add.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+ Return a + b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_add(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ long double c;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+ FP_UNPACK_SEMIRAW_Q(B, b);
+ FP_ADD_Q(C, A, B);
+ FP_PACK_SEMIRAW_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_cmp.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_cmp.c
new file mode 100644
index 000000000..a93792ba6
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_cmp.c
@@ -0,0 +1,41 @@
+/* Software floating-point emulation.
+ Compare a and b, return float condition code.
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_cmp(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == -1) r = 2;
+ if (r == 3 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_cmpe.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_cmpe.c
new file mode 100644
index 000000000..135d63cc6
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_cmpe.c
@@ -0,0 +1,42 @@
+/* Software floating-point emulation.
+ Compare a and b, return float condition code.
+ Signal exception (unless masked) if unordered.
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_cmpe(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == -1) r = 2;
+ if (r == 3)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_div.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_div.c
new file mode 100644
index 000000000..86db5ed9e
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_div.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+ Return a / b
+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_div(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ long double c;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_Q(A, a);
+ FP_UNPACK_Q(B, b);
+ FP_DIV_Q(C, A, B);
+ FP_PACK_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_dtoq.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_dtoq.c
new file mode 100644
index 000000000..6b119f450
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_dtoq.c
@@ -0,0 +1,44 @@
+/* Software floating-point emulation.
+ Return (long double)(a)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+long double _Q_dtoq(const double a)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ FP_DECL_Q(C);
+ long double c;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_D(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_EXTEND(Q,D,4,2,C,A);
+#else
+ FP_EXTEND(Q,D,2,1,C,A);
+#endif
+ FP_PACK_RAW_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_feq.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_feq.c
new file mode 100644
index 000000000..12cd7972d
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_feq.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+ Return 1 if a == b
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_feq(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_EQ_Q(r, A, B);
+ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return !r;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_fge.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_fge.c
new file mode 100644
index 000000000..db1fdbe82
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_fge.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+ Return 1 if a >= b
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_fge(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == 3)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return (r <= 0);
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_fgt.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_fgt.c
new file mode 100644
index 000000000..a9f8cd0bb
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_fgt.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+ Return 1 if a > b
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_fgt(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == 3)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return (r == -1);
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_fle.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_fle.c
new file mode 100644
index 000000000..a4b97e6c6
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_fle.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+ Return 1 if a <= b
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_fle(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, B, A, -2);
+ if (r == -2)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return (r >= 0);
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_flt.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_flt.c
new file mode 100644
index 000000000..3979d6576
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_flt.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+ Return 1 if a < b
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_flt(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == 3)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return (r == 1);
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_fne.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_fne.c
new file mode 100644
index 000000000..a38059bca
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_fne.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+ Return 1 if a != b
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_fne(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_UNPACK_RAW_Q(B, b);
+ FP_CMP_EQ_Q(r, A, B);
+ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_itoq.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_itoq.c
new file mode 100644
index 000000000..b50942f75
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_itoq.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (long double)(a)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_itoq(const int a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ int b = a;
+ long double c;
+
+ FP_FROM_INT_Q(C, b, 32, unsigned int);
+ FP_PACK_RAW_Q(c, C);
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_lltoq.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_lltoq.c
new file mode 100644
index 000000000..f977585e4
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_lltoq.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (long double)a
+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_lltoq(const long long a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ long double c;
+ long long b = a;
+
+ FP_FROM_INT_Q(C, b, 64, unsigned long long);
+ FP_PACK_RAW_Q(c, C);
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_mul.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_mul.c
new file mode 100644
index 000000000..61c3a8fac
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_mul.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+ Return a * b
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_mul(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ long double c;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_Q(A, a);
+ FP_UNPACK_Q(B, b);
+ FP_MUL_Q(C, A, B);
+ FP_PACK_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_neg.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_neg.c
new file mode 100644
index 000000000..14f39e820
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_neg.c
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+ Return !a
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_neg(const long double a)
+{
+ FP_DECL_EX;
+ long double c = a;
+
+#if (__BYTE_ORDER == __BIG_ENDIAN)
+ ((UWtype *)&c)[0] ^= (((UWtype)1) << (W_TYPE_SIZE - 1));
+#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 64)
+ ((UWtype *)&c)[1] ^= (((UWtype)1) << (W_TYPE_SIZE - 1));
+#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 32)
+ ((UWtype *)&c)[3] ^= (((UWtype)1) << (W_TYPE_SIZE - 1));
+#else
+ FP_DECL_Q(A); FP_DECL_Q(C);
+
+ FP_UNPACK_Q(A, a);
+ FP_NEG_Q(C, A);
+ FP_PACK_Q(c, C);
+#endif
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_qtod.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_qtod.c
new file mode 100644
index 000000000..82b01ec8a
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_qtod.c
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+ Return (double)a
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+double _Q_qtod(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ FP_DECL_D(R);
+ double r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_TRUNC(D,Q,2,4,R,A);
+#else
+ FP_TRUNC(D,Q,1,2,R,A);
+#endif
+ FP_PACK_SEMIRAW_D(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_qtoi.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_qtoi.c
new file mode 100644
index 000000000..270ba9f67
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_qtoi.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (int)a
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_qtoi(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, 32, 1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_qtoll.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_qtoll.c
new file mode 100644
index 000000000..e0d29019b
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_qtoll.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (long long)a
+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+long long _Q_qtoll(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned long long r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, 64, 1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_qtos.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_qtos.c
new file mode 100644
index 000000000..93daa23ca
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_qtos.c
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+ Return (float)a
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+float _Q_qtos(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ FP_DECL_S(R);
+ float r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_TRUNC(S,Q,1,4,R,A);
+#else
+ FP_TRUNC(S,Q,1,2,R,A);
+#endif
+ FP_PACK_SEMIRAW_S(r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_qtou.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_qtou.c
new file mode 100644
index 000000000..812b4e06e
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_qtou.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (unsigned int)a
+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+unsigned int _Q_qtou(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned int r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, 32, -1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_qtoull.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_qtoull.c
new file mode 100644
index 000000000..7a88c9f38
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_qtoull.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (unsigned long long)a
+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+unsigned long long _Q_qtoull(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned long long r;
+
+ FP_UNPACK_RAW_Q(A, a);
+ FP_TO_INT_Q(r, A, 64, -1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_sqrt.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_sqrt.c
new file mode 100644
index 000000000..373d02a63
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_sqrt.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+ Return sqrtl(a)
+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_sqrt(const long double a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(C);
+ long double c;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_Q(A, a);
+ FP_SQRT_Q(C, A);
+ FP_PACK_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
+strong_alias (_Q_sqrt, __ieee754_sqrtl);
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_stoq.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_stoq.c
new file mode 100644
index 000000000..714d880dd
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_stoq.c
@@ -0,0 +1,43 @@
+/* Software floating-point emulation.
+ c = (long double)(a)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+long double _Q_stoq(const float a)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ FP_DECL_Q(C);
+ long double c;
+
+ FP_UNPACK_RAW_S(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_EXTEND(Q,S,4,1,C,A);
+#else
+ FP_EXTEND(Q,S,2,1,C,A);
+#endif
+ FP_PACK_RAW_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_sub.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_sub.c
new file mode 100644
index 000000000..8616727bb
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_sub.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+ c = a - b
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_sub(const long double a, const long double b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+ long double c;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_Q(A, a);
+ FP_UNPACK_SEMIRAW_Q(B, b);
+ FP_SUB_Q(C, A, B);
+ FP_PACK_SEMIRAW_Q(c, C);
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_ulltoq.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_ulltoq.c
new file mode 100644
index 000000000..53c0add2d
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_ulltoq.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ Return (long double)(a)
+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_ulltoq(const unsigned long long a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ long double c;
+ unsigned long long b = a;
+
+ FP_FROM_INT_Q(C, b, 64, unsigned long long);
+ FP_PACK_RAW_Q(c, C);
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_util.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_util.c
new file mode 100644
index 000000000..41ecd685d
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_util.c
@@ -0,0 +1,57 @@
+/* Software floating-point emulation.
+ Helper routine for _Q_* routines.
+ Simulate exceptions using double arithmetics.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+
+unsigned long long ___Q_numbers [] = {
+0x0000000000000000ULL, /* Zero */
+0x0010100000000000ULL, /* Very tiny number */
+0x0010000000000000ULL, /* Minimum normalized number */
+0x7fef000000000000ULL, /* A huge double number */
+};
+
+double ___Q_simulate_exceptions(int exceptions)
+{
+ double d, *p = (double *)___Q_numbers;
+ if (exceptions & FP_EX_INVALID)
+ d = p[0]/p[0];
+ if (exceptions & FP_EX_OVERFLOW)
+ {
+ d = p[3] + p[3];
+ exceptions &= ~FP_EX_INEXACT;
+ }
+ if (exceptions & FP_EX_UNDERFLOW)
+ {
+ if (exceptions & FP_EX_INEXACT)
+ {
+ d = p[2] * p[2];
+ exceptions &= ~FP_EX_INEXACT;
+ }
+ else
+ d = p[1] - p[2];
+ }
+ if (exceptions & FP_EX_DIVZERO)
+ d = 1.0/p[0];
+ if (exceptions & FP_EX_INEXACT)
+ d = p[3] - p[2];
+ return d;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/q_utoq.c b/libc/sysdeps/sparc/sparc32/soft-fp/q_utoq.c
new file mode 100644
index 000000000..f902bf839
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/q_utoq.c
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+ c = (long double)(a)
+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_utoq(const unsigned int a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ long double c;
+ unsigned int b = a;
+
+ FP_FROM_INT_Q(C, b, 32, unsigned int);
+ FP_PACK_RAW_Q(c, C);
+ FP_CLEAR_EXCEPTIONS;
+ FP_HANDLE_EXCEPTIONS;
+ return c;
+}
diff --git a/libc/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h b/libc/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h
new file mode 100644
index 000000000..f1211705e
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h
@@ -0,0 +1,213 @@
+/* Machine-dependent software floating-point definitions.
+ Sparc userland (_Q_*) version.
+ Copyright (C) 1997,1998,1999, 2002, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz) and
+ David S. Miller (davem@redhat.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fpu_control.h>
+#include <stdlib.h>
+
+#define _FP_W_TYPE_SIZE 32
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+#define _FP_MUL_MEAT_S(R,X,Y) \
+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y) \
+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y) \
+ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S 0
+#define _FP_NANSIGN_D 0
+#define _FP_NANSIGN_Q 0
+
+#define _FP_KEEPNANFRACP 1
+
+/* If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose X.
+ */
+/* For _Qp_* and _Q_*, this should prefer X, for
+ * CPU instruction emulation this should prefer Y.
+ * (see SPAMv9 B.2.2 section).
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
+ && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,Y); \
+ } \
+ else \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ } \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+/* Some assembly to speed things up. */
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
+ __asm__ ("addcc %r7,%8,%2\n\
+ addxcc %r5,%6,%1\n\
+ addx %r3,%4,%0" \
+ : "=r" ((USItype)(r2)), \
+ "=&r" ((USItype)(r1)), \
+ "=&r" ((USItype)(r0)) \
+ : "%rJ" ((USItype)(x2)), \
+ "rI" ((USItype)(y2)), \
+ "%rJ" ((USItype)(x1)), \
+ "rI" ((USItype)(y1)), \
+ "%rJ" ((USItype)(x0)), \
+ "rI" ((USItype)(y0)) \
+ : "cc")
+
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
+ __asm__ ("subcc %r7,%8,%2\n\
+ subxcc %r5,%6,%1\n\
+ subx %r3,%4,%0" \
+ : "=r" ((USItype)(r2)), \
+ "=&r" ((USItype)(r1)), \
+ "=&r" ((USItype)(r0)) \
+ : "%rJ" ((USItype)(x2)), \
+ "rI" ((USItype)(y2)), \
+ "%rJ" ((USItype)(x1)), \
+ "rI" ((USItype)(y1)), \
+ "%rJ" ((USItype)(x0)), \
+ "rI" ((USItype)(y0)) \
+ : "cc")
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
+ do { \
+ /* We need to fool gcc, as we need to pass more than 10 \
+ input/outputs. */ \
+ register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \
+ __asm__ __volatile__ ("\
+ addcc %r8,%9,%1\n\
+ addxcc %r6,%7,%0\n\
+ addxcc %r4,%5,%%g2\n\
+ addx %r2,%3,%%g1" \
+ : "=&r" ((USItype)(r1)), \
+ "=&r" ((USItype)(r0)) \
+ : "%rJ" ((USItype)(x3)), \
+ "rI" ((USItype)(y3)), \
+ "%rJ" ((USItype)(x2)), \
+ "rI" ((USItype)(y2)), \
+ "%rJ" ((USItype)(x1)), \
+ "rI" ((USItype)(y1)), \
+ "%rJ" ((USItype)(x0)), \
+ "rI" ((USItype)(y0)) \
+ : "cc", "g1", "g2"); \
+ __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2)); \
+ r3 = _t1; r2 = _t2; \
+ } while (0)
+
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
+ do { \
+ /* We need to fool gcc, as we need to pass more than 10 \
+ input/outputs. */ \
+ register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \
+ __asm__ __volatile__ ("\
+ subcc %r8,%9,%1\n\
+ subxcc %r6,%7,%0\n\
+ subxcc %r4,%5,%%g2\n\
+ subx %r2,%3,%%g1" \
+ : "=&r" ((USItype)(r1)), \
+ "=&r" ((USItype)(r0)) \
+ : "%rJ" ((USItype)(x3)), \
+ "rI" ((USItype)(y3)), \
+ "%rJ" ((USItype)(x2)), \
+ "rI" ((USItype)(y2)), \
+ "%rJ" ((USItype)(x1)), \
+ "rI" ((USItype)(y1)), \
+ "%rJ" ((USItype)(x0)), \
+ "rI" ((USItype)(y0)) \
+ : "cc", "g1", "g2"); \
+ __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2)); \
+ r3 = _t1; r2 = _t2; \
+ } while (0)
+
+#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0)
+
+#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0)
+
+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \
+ __asm__ ("addcc %3,%4,%3\n\
+ addxcc %2,%%g0,%2\n\
+ addxcc %1,%%g0,%1\n\
+ addx %0,%%g0,%0" \
+ : "=&r" ((USItype)(x3)), \
+ "=&r" ((USItype)(x2)), \
+ "=&r" ((USItype)(x1)), \
+ "=&r" ((USItype)(x0)) \
+ : "rI" ((USItype)(i)), \
+ "0" ((USItype)(x3)), \
+ "1" ((USItype)(x2)), \
+ "2" ((USItype)(x1)), \
+ "3" ((USItype)(x0)) \
+ : "cc")
+
+/* Obtain the current rounding mode. */
+#ifndef FP_ROUNDMODE
+#define FP_ROUNDMODE ((_fcw >> 30) & 0x3)
+#endif
+
+/* Exception flags. */
+#define FP_EX_INVALID (1 << 4)
+#define FP_EX_OVERFLOW (1 << 3)
+#define FP_EX_UNDERFLOW (1 << 2)
+#define FP_EX_DIVZERO (1 << 1)
+#define FP_EX_INEXACT (1 << 0)
+
+#define _FP_DECL_EX fpu_control_t _fcw
+
+#define FP_INIT_ROUNDMODE \
+do { \
+ _FPU_GETCW(_fcw); \
+} while (0)
+
+/* Simulate exceptions using double arithmetics. */
+extern double ___Q_simulate_exceptions(int exc);
+
+#define FP_HANDLE_EXCEPTIONS \
+do { \
+ if (!_fex) \
+ { \
+ /* This is the common case, so we do it inline. \
+ * We need to clear cexc bits if any. \
+ */ \
+ extern unsigned long long ___Q_numbers[]; \
+ __asm__ __volatile__("\
+ ldd [%0], %%f30\n\
+ faddd %%f30, %%f30, %%f30\
+ " : : "r" (___Q_numbers) : "f30"); \
+ } \
+ else \
+ ___Q_simulate_exceptions (_fex); \
+} while (0)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv8/Makefile b/libc/sysdeps/sparc/sparc32/sparcv8/Makefile
new file mode 100644
index 000000000..2ff985345
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv8/Makefile
@@ -0,0 +1 @@
+sysdep-CFLAGS += -mcpu=v8
diff --git a/libc/sysdeps/sparc/sparc32/sparcv8/addmul_1.S b/libc/sysdeps/sparc/sparc32/sparcv8/addmul_1.S
new file mode 100644
index 000000000..1cc8fd9c9
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv8/addmul_1.S
@@ -0,0 +1,119 @@
+! SPARC v8 __mpn_addmul_1 -- Multiply a limb vector with a limb and
+! add the result to a second limb vector.
+
+! Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+! License for more details.
+
+! You should have received a copy of the GNU Lesser General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr o0
+! s1_ptr o1
+! size o2
+! s2_limb o3
+
+#include <sysdep.h>
+
+ENTRY(__mpn_addmul_1)
+ ld [%o1+0],%o4 ! 1
+ sll %o2,4,%g1
+ orcc %g0,%g0,%g2
+ mov %o7,%g4 ! Save return address register
+ and %g1,(4-1)<<4,%g1
+1: call 2f
+ add %o7,3f-1b,%g3
+2: jmp %g3+%g1
+ mov %g4,%o7 ! Restore return address register
+
+ .align 4
+3:
+LOC(00):
+ add %o0,-4,%o0
+ b LOC(loop00) /* 4, 8, 12, ... */
+ add %o1,-4,%o1
+ nop
+LOC(01):
+ b LOC(loop01) /* 1, 5, 9, ... */
+ nop
+ nop
+ nop
+LOC(10):
+ add %o0,-12,%o0 /* 2, 6, 10, ... */
+ b LOC(loop10)
+ add %o1,4,%o1
+ nop
+LOC(11):
+ add %o0,-8,%o0 /* 3, 7, 11, ... */
+ b LOC(loop11)
+ add %o1,-8,%o1
+ nop
+
+LOC(loop):
+ addcc %g3,%g2,%g3 ! 1
+ ld [%o1+4],%o4 ! 2
+ rd %y,%g2 ! 1
+ addx %g0,%g2,%g2
+ ld [%o0+0],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+0] ! 1
+LOC(loop00):
+ umul %o4,%o3,%g3 ! 2
+ ld [%o0+4],%g1 ! 2
+ addxcc %g3,%g2,%g3 ! 2
+ ld [%o1+8],%o4 ! 3
+ rd %y,%g2 ! 2
+ addx %g0,%g2,%g2
+ nop
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+4] ! 2
+LOC(loop11):
+ umul %o4,%o3,%g3 ! 3
+ addxcc %g3,%g2,%g3 ! 3
+ ld [%o1+12],%o4 ! 4
+ rd %y,%g2 ! 3
+ add %o1,16,%o1
+ addx %g0,%g2,%g2
+ ld [%o0+8],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+8] ! 3
+LOC(loop10):
+ umul %o4,%o3,%g3 ! 4
+ addxcc %g3,%g2,%g3 ! 4
+ ld [%o1+0],%o4 ! 1
+ rd %y,%g2 ! 4
+ addx %g0,%g2,%g2
+ ld [%o0+12],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+12] ! 4
+ add %o0,16,%o0
+ addx %g0,%g2,%g2
+LOC(loop01):
+ addcc %o2,-4,%o2
+ bg LOC(loop)
+ umul %o4,%o3,%g3 ! 1
+
+ addcc %g3,%g2,%g3 ! 4
+ rd %y,%g2 ! 4
+ addx %g0,%g2,%g2
+ ld [%o0+0],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+0] ! 4
+ retl
+ addx %g0,%g2,%o0
+
+END(__mpn_addmul_1)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv8/dotmul.S b/libc/sysdeps/sparc/sparc32/sparcv8/dotmul.S
new file mode 100644
index 000000000..9b20cc368
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv8/dotmul.S
@@ -0,0 +1,13 @@
+/*
+ * Sparc v8 has multiply.
+ */
+
+#include <sysdep.h>
+
+ENTRY(.mul)
+
+ smul %o0, %o1, %o0
+ retl
+ rd %y, %o1
+
+END(.mul)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv8/mul_1.S b/libc/sysdeps/sparc/sparc32/sparcv8/mul_1.S
new file mode 100644
index 000000000..b3c9f2b45
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv8/mul_1.S
@@ -0,0 +1,103 @@
+! SPARC v8 __mpn_mul_1 -- Multiply a limb vector with a single limb and
+! store the product in a second limb vector.
+
+! Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+! License for more details.
+
+! You should have received a copy of the GNU Lesser General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr o0
+! s1_ptr o1
+! size o2
+! s2_limb o3
+
+#include <sysdep.h>
+
+ENTRY(__mpn_mul_1)
+ sll %o2,4,%g1
+ mov %o7,%g4 ! Save return address register
+ and %g1,(4-1)<<4,%g1
+1: call 2f
+ add %o7,3f-1b,%g3
+2: mov %g4,%o7 ! Restore return address register
+ jmp %g3+%g1
+ ld [%o1+0],%o4 ! 1
+
+ .align 4
+3:
+LOC(00):
+ add %o0,-4,%o0
+ add %o1,-4,%o1
+ b LOC(loop00) /* 4, 8, 12, ... */
+ orcc %g0,%g0,%g2
+LOC(01):
+ b LOC(loop01) /* 1, 5, 9, ... */
+ orcc %g0,%g0,%g2
+ nop
+ nop
+LOC(10):
+ add %o0,-12,%o0 /* 2, 6, 10, ... */
+ add %o1,4,%o1
+ b LOC(loop10)
+ orcc %g0,%g0,%g2
+ nop
+LOC(11):
+ add %o0,-8,%o0 /* 3, 7, 11, ... */
+ add %o1,-8,%o1
+ b LOC(loop11)
+ orcc %g0,%g0,%g2
+
+LOC(loop):
+ addcc %g3,%g2,%g3 ! 1
+ ld [%o1+4],%o4 ! 2
+ st %g3,[%o0+0] ! 1
+ rd %y,%g2 ! 1
+LOC(loop00):
+ umul %o4,%o3,%g3 ! 2
+ addxcc %g3,%g2,%g3 ! 2
+ ld [%o1+8],%o4 ! 3
+ st %g3,[%o0+4] ! 2
+ rd %y,%g2 ! 2
+LOC(loop11):
+ umul %o4,%o3,%g3 ! 3
+ addxcc %g3,%g2,%g3 ! 3
+ ld [%o1+12],%o4 ! 4
+ add %o1,16,%o1
+ st %g3,[%o0+8] ! 3
+ rd %y,%g2 ! 3
+LOC(loop10):
+ umul %o4,%o3,%g3 ! 4
+ addxcc %g3,%g2,%g3 ! 4
+ ld [%o1+0],%o4 ! 1
+ st %g3,[%o0+12] ! 4
+ add %o0,16,%o0
+ rd %y,%g2 ! 4
+ addx %g0,%g2,%g2
+LOC(loop01):
+ addcc %o2,-4,%o2
+ bg LOC(loop)
+ umul %o4,%o3,%g3 ! 1
+
+ addcc %g3,%g2,%g3 ! 4
+ st %g3,[%o0+0] ! 4
+ rd %y,%g2 ! 4
+ retl
+ addx %g0,%g2,%o0
+
+END(__mpn_mul_1)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv8/rem.S b/libc/sysdeps/sparc/sparc32/sparcv8/rem.S
new file mode 100644
index 000000000..a2694e699
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv8/rem.S
@@ -0,0 +1,21 @@
+/*
+ * Sparc v8 has divide.
+ */
+
+#include <sysdep.h>
+
+ENTRY(.rem)
+
+ sra %o0, 31, %o2
+ wr %o2, 0, %y
+ nop
+ nop
+ nop
+ sdivcc %o0, %o1, %o2
+ bvs,a 1f
+ xnor %o2, %g0, %o2
+1: smul %o2, %o1, %o2
+ retl
+ sub %o0, %o2, %o0
+
+END(.rem)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv8/sdiv.S b/libc/sysdeps/sparc/sparc32/sparcv8/sdiv.S
new file mode 100644
index 000000000..bfc4acf2f
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv8/sdiv.S
@@ -0,0 +1,20 @@
+/*
+ * Sparc v8 has divide.
+ */
+
+#include <sysdep.h>
+
+ENTRY(.div)
+
+ sra %o0, 31, %o2
+ wr %o2, 0, %y
+ nop
+ nop
+ nop
+ sdivcc %o0, %o1, %o0
+ bvs,a 1f
+ xnor %o0, %g0, %o0
+1: retl
+ nop
+
+END(.div)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv8/submul_1.S b/libc/sysdeps/sparc/sparc32/sparcv8/submul_1.S
new file mode 100644
index 000000000..f99f1288e
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv8/submul_1.S
@@ -0,0 +1,58 @@
+! SPARC v8 __mpn_submul_1 -- Multiply a limb vector with a limb and
+! subtract the result from a second limb vector.
+
+! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+! License for more details.
+
+! You should have received a copy of the GNU Lesser General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr o0
+! s1_ptr o1
+! size o2
+! s2_limb o3
+
+#include <sysdep.h>
+
+ENTRY(__mpn_submul_1)
+ sub %g0,%o2,%o2 ! negate ...
+ sll %o2,2,%o2 ! ... and scale size
+ sub %o1,%o2,%o1 ! o1 is offset s1_ptr
+ sub %o0,%o2,%g1 ! g1 is offset res_ptr
+
+ mov 0,%o0 ! clear cy_limb
+
+LOC(loop):
+ ld [%o1+%o2],%o4
+ ld [%g1+%o2],%g2
+ umul %o4,%o3,%o5
+ rd %y,%g3
+ addcc %o5,%o0,%o5
+ addx %g3,0,%o0
+ subcc %g2,%o5,%g2
+ addx %o0,0,%o0
+ st %g2,[%g1+%o2]
+
+ addcc %o2,4,%o2
+ bne LOC(loop)
+ nop
+
+ retl
+ nop
+
+END(__mpn_submul_1)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv8/udiv.S b/libc/sysdeps/sparc/sparc32/sparcv8/udiv.S
new file mode 100644
index 000000000..d71954351
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv8/udiv.S
@@ -0,0 +1,15 @@
+/*
+ * Sparc v8 has divide.
+ */
+
+#include <sysdep.h>
+
+ENTRY(.udiv)
+
+ wr %g0, 0, %y
+ nop
+ nop
+ retl
+ udiv %o0, %o1, %o0
+
+END(.udiv)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv8/udiv_qrnnd.S b/libc/sysdeps/sparc/sparc32/sparcv8/udiv_qrnnd.S
new file mode 100644
index 000000000..c3f097118
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv8/udiv_qrnnd.S
@@ -0,0 +1,215 @@
+! SPARC __udiv_qrnnd division support, used from longlong.h.
+
+! Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+! License for more details.
+
+! You should have received a copy of the GNU Lesser General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+! INPUT PARAMETERS
+! rem_ptr o0
+! n1 o1
+! n0 o2
+! d o3
+
+#include "sysdep.h"
+
+ENTRY(__udiv_qrnnd)
+ tst %o3
+ bneg LOC(largedivisor)
+ mov 8,%g1
+
+ b LOC(p1)
+ addxcc %o2,%o2,%o2
+
+LOC(plop):
+ bcc LOC(n1)
+ addxcc %o2,%o2,%o2
+LOC(p1):
+ addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc LOC(n2)
+ addxcc %o2,%o2,%o2
+LOC(p2):
+ addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc LOC(n3)
+ addxcc %o2,%o2,%o2
+LOC(p3):
+ addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc LOC(n4)
+ addxcc %o2,%o2,%o2
+LOC(p4):
+ addx %o1,%o1,%o1
+ addcc %g1,-1,%g1
+ bne LOC(plop)
+ subcc %o1,%o3,%o4
+ bcc LOC(n5)
+ addxcc %o2,%o2,%o2
+LOC(p5):
+ st %o1,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+LOC(nlop):
+ bcc LOC(p1)
+ addxcc %o2,%o2,%o2
+LOC(n1):
+ addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc LOC(p2)
+ addxcc %o2,%o2,%o2
+LOC(n2):
+ addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc LOC(p3)
+ addxcc %o2,%o2,%o2
+LOC(n3):
+ addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc LOC(p4)
+ addxcc %o2,%o2,%o2
+LOC(n4):
+ addx %o4,%o4,%o4
+ addcc %g1,-1,%g1
+ bne LOC(nlop)
+ subcc %o4,%o3,%o1
+ bcc LOC(p5)
+ addxcc %o2,%o2,%o2
+LOC(n5):
+ st %o4,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+LOC(largedivisor):
+ and %o2,1,%o5 ! %o5 = n0 & 1
+
+ srl %o2,1,%o2
+ sll %o1,31,%g2
+ or %g2,%o2,%o2 ! %o2 = lo(n1n0 >> 1)
+ srl %o1,1,%o1 ! %o1 = hi(n1n0 >> 1)
+
+ and %o3,1,%g2
+ srl %o3,1,%g3 ! %g3 = floor(d / 2)
+ add %g3,%g2,%g3 ! %g3 = ceil(d / 2)
+
+ b LOC(Lp1)
+ addxcc %o2,%o2,%o2
+
+LOC(Lplop):
+ bcc LOC(Ln1)
+ addxcc %o2,%o2,%o2
+LOC(Lp1):
+ addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc LOC(Ln2)
+ addxcc %o2,%o2,%o2
+LOC(Lp2):
+ addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc LOC(Ln3)
+ addxcc %o2,%o2,%o2
+LOC(Lp3):
+ addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc LOC(Ln4)
+ addxcc %o2,%o2,%o2
+LOC(Lp4):
+ addx %o1,%o1,%o1
+ addcc %g1,-1,%g1
+ bne LOC(Lplop)
+ subcc %o1,%g3,%o4
+ bcc LOC(Ln5)
+ addxcc %o2,%o2,%o2
+LOC(Lp5):
+ add %o1,%o1,%o1 ! << 1
+ tst %g2
+ bne LOC(Oddp)
+ add %o5,%o1,%o1
+ st %o1,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+LOC(Lnlop):
+ bcc LOC(Lp1)
+ addxcc %o2,%o2,%o2
+LOC(Ln1):
+ addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc LOC(Lp2)
+ addxcc %o2,%o2,%o2
+LOC(Ln2):
+ addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc LOC(Lp3)
+ addxcc %o2,%o2,%o2
+LOC(Ln3):
+ addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc LOC(Lp4)
+ addxcc %o2,%o2,%o2
+LOC(Ln4):
+ addx %o4,%o4,%o4
+ addcc %g1,-1,%g1
+ bne LOC(Lnlop)
+ subcc %o4,%g3,%o1
+ bcc LOC(Lp5)
+ addxcc %o2,%o2,%o2
+LOC(Ln5):
+ add %o4,%o4,%o4 ! << 1
+ tst %g2
+ bne LOC(Oddn)
+ add %o5,%o4,%o4
+ st %o4,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+LOC(Oddp):
+ xnor %g0,%o2,%o2
+ ! q' in %o2. r' in %o1
+ addcc %o1,%o2,%o1
+ bcc LOC(Lp6)
+ addx %o2,0,%o2
+ sub %o1,%o3,%o1
+LOC(Lp6):
+ subcc %o1,%o3,%g0
+ bcs LOC(Lp7)
+ subx %o2,-1,%o2
+ sub %o1,%o3,%o1
+LOC(Lp7):
+ st %o1,[%o0]
+ retl
+ mov %o2,%o0
+
+LOC(Oddn):
+ xnor %g0,%o2,%o2
+ ! q' in %o2. r' in %o4
+ addcc %o4,%o2,%o4
+ bcc LOC(Ln6)
+ addx %o2,0,%o2
+ sub %o4,%o3,%o4
+LOC(Ln6):
+ subcc %o4,%o3,%g0
+ bcs LOC(Ln7)
+ subx %o2,-1,%o2
+ sub %o4,%o3,%o4
+LOC(Ln7):
+ st %o4,[%o0]
+ retl
+ mov %o2,%o0
+
+END(__udiv_qrnnd)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv8/umul.S b/libc/sysdeps/sparc/sparc32/sparcv8/umul.S
new file mode 100644
index 000000000..cec454a7d
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv8/umul.S
@@ -0,0 +1,13 @@
+/*
+ * Sparc v8 has multiply.
+ */
+
+#include <sysdep.h>
+
+ENTRY(.umul)
+
+ umul %o0, %o1, %o0
+ retl
+ rd %y, %o1
+
+END(.umul)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv8/urem.S b/libc/sysdeps/sparc/sparc32/sparcv8/urem.S
new file mode 100644
index 000000000..cc2689d51
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv8/urem.S
@@ -0,0 +1,18 @@
+/*
+ * Sparc v8 has divide.
+ */
+
+#include <sysdep.h>
+
+ENTRY(.urem)
+
+ wr %g0, 0, %y
+ nop
+ nop
+ nop
+ udiv %o0, %o1, %o2
+ umul %o2, %o1, %o2
+ retl
+ sub %o0, %o2, %o0
+
+END(.urem)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/Makefile b/libc/sysdeps/sparc/sparc32/sparcv9/Makefile
new file mode 100644
index 000000000..58f5759b3
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/Makefile
@@ -0,0 +1,13 @@
+sysdep-CFLAGS += -mcpu=ultrasparc -Wa,-Av9a
+
+ifeq ($(subdir),csu)
+sysdep_routines += hp-timing
+elide-routines.os += hp-timing
+endif
+
+ASFLAGS-.o += -Wa,-Av9a
+ASFLAGS-.os += -Wa,-Av9a
+ASFLAGS-.op += -Wa,-Av9a
+ASFLAGS-.og += -Wa,-Av9a
+ASFLAGS-.ob += -Wa,-Av9a
+ASFLAGS-.oS += -Wa,-Av9a
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/bcopy.c b/libc/sysdeps/sparc/sparc32/sparcv9/bcopy.c
new file mode 100644
index 000000000..9a455f33c
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/bcopy.c
@@ -0,0 +1 @@
+/* bcopy is in memcpy.S */
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h b/libc/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
new file mode 100644
index 000000000..7b9d61d46
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
@@ -0,0 +1,94 @@
+/* Atomic operations. sparcv9 version.
+ Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+
+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+
+#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+({ \
+ __typeof (*(mem)) __acev_tmp; \
+ __typeof (mem) __acev_mem = (mem); \
+ __asm __volatile ("cas [%4], %2, %0" \
+ : "=r" (__acev_tmp), "=m" (*__acev_mem) \
+ : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \
+ "0" (newval) : "memory"); \
+ __acev_tmp; })
+
+/* This can be implemented if needed. */
+#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+
+#define atomic_exchange_acq(mem, newvalue) \
+ ({ __typeof (*(mem)) __oldval; \
+ __typeof (mem) __memp = (mem); \
+ __typeof (*(mem)) __value = (newvalue); \
+ \
+ if (sizeof (*(mem)) == 4) \
+ __asm ("swap %0, %1" \
+ : "=m" (*__memp), "=r" (__oldval) \
+ : "m" (*__memp), "1" (__value) : "memory"); \
+ else \
+ abort (); \
+ __oldval; })
+
+#define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \
+ atomic_compare_and_exchange_val_acq (mem, newval, oldval)
+
+#define atomic_exchange_24_rel(mem, newval) \
+ atomic_exchange_rel (mem, newval)
+
+#define atomic_full_barrier() \
+ __asm __volatile ("membar #LoadLoad | #LoadStore" \
+ " | #StoreLoad | #StoreStore" : : : "memory")
+#define atomic_read_barrier() \
+ __asm __volatile ("membar #LoadLoad | #LoadStore" : : : "memory")
+#define atomic_write_barrier() \
+ __asm __volatile ("membar #StoreLoad | #StoreStore" : : : "memory")
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/bzero.c b/libc/sysdeps/sparc/sparc32/sparcv9/bzero.c
new file mode 100644
index 000000000..37f0f6f99
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/bzero.c
@@ -0,0 +1 @@
+/* bzero is in memset.S */
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/dotmul.S b/libc/sysdeps/sparc/sparc32/sparcv9/dotmul.S
new file mode 100644
index 000000000..811cf1e89
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/dotmul.S
@@ -0,0 +1,17 @@
+/*
+ * Sparc v9 has multiply.
+ */
+
+#include <sysdep.h>
+
+ .text
+ .align 32
+ENTRY(.mul)
+
+ sra %o0, 0, %o0
+ sra %o1, 0, %o1
+ mulx %o0, %o1, %o0
+ retl
+ srax %o0, 32, %o1
+
+END(.mul)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/hp-timing.c b/libc/sysdeps/sparc/sparc32/sparcv9/hp-timing.c
new file mode 100644
index 000000000..49fb94d7a
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/hp-timing.c
@@ -0,0 +1,24 @@
+/* Support for high precision, low overhead timing functions. sparcv9 version.
+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller <davem@redhat.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hp-timing.h>
+
+/* We have to define the variable for the overhead. */
+hp_timing_t _dl_hp_timing_overhead;
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/hp-timing.h b/libc/sysdeps/sparc/sparc32/sparcv9/hp-timing.h
new file mode 100644
index 000000000..2c88a72f2
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/hp-timing.h
@@ -0,0 +1,87 @@
+/* High precision, low overhead timing functions. sparcv9 version.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller <davem@redhat.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H 1
+
+#include <string.h>
+#include <sys/param.h>
+#include <stdio-common/_itoa.h>
+
+#define HP_TIMING_AVAIL (1)
+#define HP_TIMING_INLINE (1)
+
+typedef unsigned long long int hp_timing_t;
+
+#define HP_TIMING_ZERO(Var) (Var) = (0)
+
+#define HP_TIMING_NOW(Var) \
+ __asm__ __volatile__ ("rd %%tick, %L0\n\t" \
+ "srlx %L0, 32, %H0" \
+ : "=r" (Var))
+
+#define HP_TIMING_DIFF_INIT() \
+ do { \
+ int __cnt = 5; \
+ GLRO(dl_hp_timing_overhead) = ~0ull; \
+ do \
+ { \
+ hp_timing_t __t1, __t2; \
+ HP_TIMING_NOW (__t1); \
+ HP_TIMING_NOW (__t2); \
+ if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \
+ GLRO(dl_hp_timing_overhead) = __t2 - __t1; \
+ } \
+ while (--__cnt > 0); \
+ } while (0)
+
+#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start))
+
+#define HP_TIMING_ACCUM(Sum, Diff) \
+do { \
+ hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \
+ __asm__ __volatile__("srl %L0, 0, %%g1\n\t" \
+ "sllx %H0, 32, %%g6\n\t" \
+ "or %%g1, %%g6, %%g1\n\t" \
+ "1: ldx [%1], %%g5\n\t" \
+ "add %%g5, %%g1, %%g6\n\t" \
+ "casx [%1], %%g5, %%g6\n\t" \
+ "cmp %%g5, %%g6\n\t" \
+ "bne,pn %%xcc, 1b\n\t" \
+ " nop" \
+ : /* no outputs */ \
+ : "r" (__diff), "r" (&(Sum)) \
+ : "memory", "g1", "g5", "g6"); \
+} while(0)
+
+#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff)
+
+#define HP_TIMING_PRINT(Buf, Len, Val) \
+ do { \
+ char __buf[20]; \
+ char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \
+ int __len = (Len); \
+ char *__dest = (Buf); \
+ while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \
+ *__dest++ = *__cp++; \
+ memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles"))); \
+ } while (0)
+
+#endif /* hp-timing.h */
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/memchr.S b/libc/sysdeps/sparc/sparc32/sparcv9/memchr.S
new file mode 100644
index 000000000..c5dfbef18
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/memchr.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/memchr.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/memcmp.S b/libc/sysdeps/sparc/sparc32/sparcv9/memcmp.S
new file mode 100644
index 000000000..44878f448
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/memcmp.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/memcmp.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/memcpy.S b/libc/sysdeps/sparc/sparc32/sparcv9/memcpy.S
new file mode 100644
index 000000000..675ec496b
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/memcpy.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/memcpy.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/memmove.c b/libc/sysdeps/sparc/sparc32/sparcv9/memmove.c
new file mode 100644
index 000000000..a8d2d4994
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/memmove.c
@@ -0,0 +1 @@
+/* memmove is in memcpy.S */
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/memset.S b/libc/sysdeps/sparc/sparc32/sparcv9/memset.S
new file mode 100644
index 000000000..ac67b7ab7
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/memset.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/memset.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/rawmemchr.S b/libc/sysdeps/sparc/sparc32/sparcv9/rawmemchr.S
new file mode 100644
index 000000000..05c269ecc
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/rawmemchr.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/rawmemchr.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/rem.S b/libc/sysdeps/sparc/sparc32/sparcv9/rem.S
new file mode 100644
index 000000000..5385bd830
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/rem.S
@@ -0,0 +1,22 @@
+/*
+ * Sparc v9 has divide.
+ * As divx takes 68 cycles and sdivcc only 36,
+ * we use sdivcc eventhough it is deprecated.
+ */
+
+#include <sysdep.h>
+
+ .text
+ .align 32
+ENTRY(.rem)
+
+ sra %o0, 31, %o2
+ wr %o2, 0, %y
+ sdivcc %o0, %o1, %o2
+ xnor %o2, %g0, %o3
+ movvs %icc, %o3, %o2
+ smul %o2, %o1, %o2
+ retl
+ sub %o0, %o2, %o0
+
+END(.rem)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/sdiv.S b/libc/sysdeps/sparc/sparc32/sparcv9/sdiv.S
new file mode 100644
index 000000000..d765514ce
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/sdiv.S
@@ -0,0 +1,20 @@
+/*
+ * Sparc v9 has divide.
+ * As divx takes 68 cycles and sdivcc only 36,
+ * we use sdivcc eventhough it is deprecated.
+ */
+
+#include <sysdep.h>
+
+ .text
+ .align 32
+ENTRY(.div)
+
+ sra %o0, 31, %o2
+ wr %o2, 0, %y
+ sdivcc %o0, %o1, %o0
+ xnor %o0, %g0, %o2
+ retl
+ movvs %icc, %o2, %o0
+
+END(.div)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/stpcpy.S b/libc/sysdeps/sparc/sparc32/sparcv9/stpcpy.S
new file mode 100644
index 000000000..440ad7e21
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/stpcpy.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/stpcpy.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/stpncpy.S b/libc/sysdeps/sparc/sparc32/sparcv9/stpncpy.S
new file mode 100644
index 000000000..124136a0b
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/stpncpy.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/stpncpy.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/strcat.S b/libc/sysdeps/sparc/sparc32/sparcv9/strcat.S
new file mode 100644
index 000000000..7a2223570
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/strcat.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/strcat.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/strchr.S b/libc/sysdeps/sparc/sparc32/sparcv9/strchr.S
new file mode 100644
index 000000000..ddd32120d
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/strchr.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/strchr.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/strcmp.S b/libc/sysdeps/sparc/sparc32/sparcv9/strcmp.S
new file mode 100644
index 000000000..5330f4359
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/strcmp.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/strcmp.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/strcpy.S b/libc/sysdeps/sparc/sparc32/sparcv9/strcpy.S
new file mode 100644
index 000000000..0b35c9be0
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/strcpy.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/strcpy.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/strcspn.S b/libc/sysdeps/sparc/sparc32/sparcv9/strcspn.S
new file mode 100644
index 000000000..f9d6beabe
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/strcspn.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/strcspn.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/strlen.S b/libc/sysdeps/sparc/sparc32/sparcv9/strlen.S
new file mode 100644
index 000000000..b8f4dba4f
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/strlen.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/strlen.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/strncmp.S b/libc/sysdeps/sparc/sparc32/sparcv9/strncmp.S
new file mode 100644
index 000000000..addd89e05
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/strncmp.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/strncmp.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/strncpy.S b/libc/sysdeps/sparc/sparc32/sparcv9/strncpy.S
new file mode 100644
index 000000000..688f9dfd6
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/strncpy.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/strncpy.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/strpbrk.S b/libc/sysdeps/sparc/sparc32/sparcv9/strpbrk.S
new file mode 100644
index 000000000..62294c0af
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/strpbrk.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/strpbrk.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/strrchr.c b/libc/sysdeps/sparc/sparc32/sparcv9/strrchr.c
new file mode 100644
index 000000000..ec608d6ab
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/strrchr.c
@@ -0,0 +1 @@
+/* strrchr is in strchr.S */
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/strspn.S b/libc/sysdeps/sparc/sparc32/sparcv9/strspn.S
new file mode 100644
index 000000000..291e79808
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/strspn.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/strspn.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/udiv.S b/libc/sysdeps/sparc/sparc32/sparcv9/udiv.S
new file mode 100644
index 000000000..de7989975
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/udiv.S
@@ -0,0 +1,17 @@
+/*
+ * Sparc v9 has divide.
+ * As divx takes 68 cycles and udiv only 37,
+ * we use udiv eventhough it is deprecated.
+ */
+
+#include <sysdep.h>
+
+ .text
+ .align 32
+ENTRY(.udiv)
+
+ wr %g0, 0, %y
+ retl
+ udiv %o0, %o1, %o0
+
+END(.udiv)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/umul.S b/libc/sysdeps/sparc/sparc32/sparcv9/umul.S
new file mode 100644
index 000000000..608b72aca
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/umul.S
@@ -0,0 +1,17 @@
+/*
+ * Sparc v9 has multiply.
+ */
+
+#include <sysdep.h>
+
+ .text
+ .align 32
+ENTRY(.umul)
+
+ srl %o0, 0, %o0
+ srl %o1, 0, %o1
+ mulx %o0, %o1, %o0
+ retl
+ srlx %o0, 32, %o1
+
+END(.umul)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9/urem.S b/libc/sysdeps/sparc/sparc32/sparcv9/urem.S
new file mode 100644
index 000000000..cab16c919
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9/urem.S
@@ -0,0 +1,19 @@
+/*
+ * Sparc v9 has divide.
+ * As divx takes 68 cycles and udiv only 37,
+ * we use udiv eventhough it is deprecated.
+ */
+
+#include <sysdep.h>
+
+ .text
+ .align 32
+ENTRY(.urem)
+
+ wr %g0, 0, %y
+ udiv %o0, %o1, %o2
+ umul %o2, %o1, %o2
+ retl
+ sub %o0, %o2, %o0
+
+END(.urem)
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9b/memcpy.S b/libc/sysdeps/sparc/sparc32/sparcv9b/memcpy.S
new file mode 100644
index 000000000..1404dead7
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9b/memcpy.S
@@ -0,0 +1,4 @@
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define XCC icc
+#include <sparc64/sparcv9b/memcpy.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9v/memcpy.S b/libc/sysdeps/sparc/sparc32/sparcv9v/memcpy.S
new file mode 100644
index 000000000..4c05f57bc
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9v/memcpy.S
@@ -0,0 +1,2 @@
+#define XCC icc
+#include <sparc64/sparcv9v/memcpy.S>
diff --git a/libc/sysdeps/sparc/sparc32/sparcv9v/memset.S b/libc/sysdeps/sparc/sparc32/sparcv9v/memset.S
new file mode 100644
index 000000000..5e46c7489
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sparcv9v/memset.S
@@ -0,0 +1,2 @@
+#define XCC icc
+#include <sparc64/sparcv9v/memset.S>
diff --git a/libc/sysdeps/sparc/sparc32/stpcpy.S b/libc/sysdeps/sparc/sparc32/stpcpy.S
new file mode 100644
index 000000000..222bc2a44
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/stpcpy.S
@@ -0,0 +1,167 @@
+/* Copy SRC to DEST returning the address of the terminating '\0' in DEST.
+ For SPARC v7.
+ Copyright (C) 1996, 1999, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ /* Normally, this uses ((xword - 0x01010101) & 0x80808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x01010101) & (~xword) & 0x80808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 4
+
+ENTRY(__stpcpy)
+ andcc %o1, 3, %g0
+ be 20f
+ sethi %hi(0x80808080), %o4
+
+ ldub [%o1], %o5
+ stb %o5, [%o0]
+ cmp %o5, 0
+ add %o0, 1, %o0
+ be 1f
+ add %o1, 1, %o1
+ andcc %o1, 3, %g0
+ be 4f
+ or %o4, %lo(0x80808080), %o3
+ ldub [%o1], %o5
+ stb %o5, [%o0]
+ cmp %o5, 0
+ add %o0, 1, %o0
+ be 1f
+ add %o1, 1, %o1
+ andcc %o1, 3, %g0
+ be 5f
+ sethi %hi(0x01010101), %o4
+ ldub [%o1], %o5
+ stb %o5, [%o0]
+ cmp %o5, 0
+ add %o0, 1, %o0
+ be 1f
+ add %o1, 1, %o1
+ b 6f
+ or %o4, %lo(0x01010101), %o2
+1: retl
+ add %o0, -1, %o0
+
+20: or %o4, %lo(0x80808080), %o3
+4: sethi %hi(0x01010101), %o4
+5: or %o4, %lo(0x01010101), %o2
+6: andcc %o0, 3, %g0
+ bne 16f
+ sub %g0, 4, %g1
+
+11: add %g1, 4, %g1
+ ld [%o1 + %g1], %o5
+ sub %o5, %o2, %o4
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o5, %o4
+#endif
+ andcc %o4, %o3, %g0
+ be,a 11b
+ st %o5, [%o0 + %g1]
+
+ /* Check every byte. */
+ srl %o5, 24, %g5
+ andcc %g5, 0xff, %g0
+ be 14f
+ srl %o5, 16, %g5
+ andcc %g5, 0xff, %g0
+ be 13f
+ srl %o5, 8, %g5
+ andcc %g5, 0xff, %g0
+ be 12f
+ andcc %o5, 0xff, %g0
+ bne 11b
+ st %o5, [%o0 + %g1]
+ add %o0, %g1, %o0
+ retl
+ add %o0, 3, %o0
+12: srl %o5, 16, %o5
+ sth %o5, [%o0 + %g1]
+ add %g1, 2, %g1
+ stb %g0, [%o0 + %g1]
+ retl
+ add %o0, %g1, %o0
+13: srl %o5, 16, %o5
+ sth %o5, [%o0 + %g1]
+ add %g1, 1, %g1
+ retl
+ add %o0, %g1, %o0
+14: stb %g0, [%o0 + %g1]
+ retl
+ add %o0, %g1, %o0
+
+15: srl %o5, 24, %o4
+ srl %o5, 16, %g1
+ stb %o4, [%o0]
+ srl %o5, 8, %g4
+ stb %g1, [%o0 + 1]
+ stb %g4, [%o0 + 2]
+ stb %o5, [%o0 + 3]
+ add %o0, 4, %o0
+16: ld [%o1], %o5
+ sub %o5, %o2, %o4
+ andcc %o4, %o3, %g0
+ be 15b
+ add %o1, 4, %o1
+
+ /* Check every byte. */
+ srl %o5, 24, %g5
+ andcc %g5, 0xff, %g4
+ be 19f
+ stb %g4, [%o0]
+ srl %o5, 16, %g5
+ andcc %g5, 0xff, %g4
+ be 18f
+ stb %g4, [%o0 + 1]
+ srl %o5, 8, %g5
+ andcc %g5, 0xff, %g4
+ be 17f
+ stb %g4, [%o0 + 2]
+ andcc %o5, 0xff, %g4
+ stb %g4, [%o0 + 3]
+ bne 16b
+ add %o0, 4, %o0
+ retl
+ sub %o0, 1, %o0
+17: retl
+ add %o0, 2, %o0
+18: retl
+ add %o0, 1, %o0
+19: retl
+ nop
+END(__stpcpy)
+
+weak_alias (__stpcpy, stpcpy)
+libc_hidden_def (__stpcpy)
+libc_hidden_builtin_def (stpcpy)
diff --git a/libc/sysdeps/sparc/sparc32/strcat.S b/libc/sysdeps/sparc/sparc32/strcat.S
new file mode 100644
index 000000000..4ce077190
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/strcat.S
@@ -0,0 +1,353 @@
+/* strcat (dest, src) -- Append SRC on the end of DEST.
+ For SPARC v7.
+ Copyright (C) 1996, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ /* Normally, this uses ((xword - 0x01010101) & 0x80808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x01010101) & (~xword) & 0x80808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 4
+
+ENTRY(strcat)
+ mov %o0, %g2
+ andcc %o0, 3, %g0
+ be 30f
+ sethi %hi(0x80808080), %o4
+
+ ldub [%o0], %o5
+ cmp %o5, 0
+ be 1f
+ add %o0, 1, %o0
+ andcc %o0, 3, %g0
+ be 7f
+ or %o4, %lo(0x80808080), %o3
+ ldub [%o0], %o5
+ cmp %o5, 0
+ be 2f
+ add %o0, 1, %o0
+ andcc %o0, 3, %g0
+ be 8f
+ sethi %hi(0x01010101), %o4
+ ldub [%o0], %o5
+ cmp %o5, 0
+ be 3f
+ add %o0, 1, %o0
+ b 9f
+ or %o4, %lo(0x01010101), %o2
+1: or %o4, %lo(0x80808080), %o3
+2: sethi %hi(0x01010101), %o4
+3: or %o4, %lo(0x01010101), %o2
+ b 3f
+ sub %o0, 1, %o0
+
+30: or %o4, %lo(0x80808080), %o3
+7: sethi %hi(0x01010101), %o4
+8: or %o4, %lo(0x01010101), %o2
+9: ld [%o0], %o5
+7: sub %o5, %o2, %o4
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o5, %o4
+#endif
+ andcc %o4, %o3, %g0
+ be 9b
+ add %o0, 4, %o0
+
+ srl %o5, 24, %g5
+ andcc %g5, 0xff, %g0
+ be 3f
+ add %o0, -4, %o0
+ srl %o5, 16, %g5
+ andcc %g5, 0xff, %g0
+ be 3f
+ add %o0, 1, %o0
+ srl %o5, 8, %g5
+ andcc %g5, 0xff, %g0
+ be 3f
+ add %o0, 1, %o0
+ andcc %o5, 0xff, %g0
+ add %o0, 2, %o0
+ bne,a 7b
+ ld [%o0], %o5
+ sub %o0, 1, %o0
+3: andcc %o1, 3, %o4
+ be 4f
+ nop
+
+ cmp %o4, 2
+ be 11f
+ cmp %o4, 3
+ ldub [%o1], %o5
+ add %o1, 1, %o1
+ stb %o5, [%o0]
+ be 13f
+ cmp %o5, 0
+ be 0f
+ add %o0, 1, %o0
+11: lduh [%o1], %o5
+ add %o1, 2, %o1
+ srl %o5, 8, %o4
+ cmp %o4, 0
+ stb %o4, [%o0]
+ bne,a 12f
+ stb %o5, [%o0 + 1]
+ retl
+ mov %g2, %o0
+12: andcc %o5, 0xff, %o5
+ bne 4f
+ add %o0, 2, %o0
+ retl
+ mov %g2, %o0
+13: bne 4f
+ add %o0, 1, %o0
+ retl
+ mov %g2, %o0
+
+4: andcc %o0, 3, %g3
+ bne 12f
+1: ld [%o1], %o5
+ add %o1, 4, %o1
+ sub %o5, %o2, %o4
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o5, %o4
+#endif
+ add %o0, 4, %o0
+ andcc %o4, %o3, %g0
+ be,a 1b
+ st %o5, [%o0 - 4]
+
+ srl %o5, 24, %g5
+ andcc %g5, 0xff, %g0
+ be 1f
+ srl %o5, 16, %g5
+ andcc %g5, 0xff, %g0
+ be 2f
+ srl %o5, 8, %g5
+ andcc %g5, 0xff, %g0
+ be 3f
+ andcc %o5, 0xff, %g0
+ bne 1b
+ st %o5, [%o0 - 4]
+ retl
+ mov %g2, %o0
+3: srl %o5, 16, %o5
+ sth %o5, [%o0 - 4]
+ stb %g0, [%o0 - 2]
+ retl
+ mov %g2, %o0
+2: srl %o5, 16, %o5
+ sth %o5, [%o0 - 4]
+ retl
+ mov %g2, %o0
+1: stb %g0, [%o0 - 4]
+ retl
+ mov %g2, %o0
+
+12: add %o1, 4, %o1
+ sub %o5, %o2, %o4
+ cmp %g3, 2
+ be 2f
+ cmp %g3, 3
+ be 3f
+ andcc %o4, %o3, %g0
+ bne 5f
+ srl %o5, 24, %g5
+ stb %g5, [%o0]
+ sub %o0, 1, %o0
+ srl %o5, 8, %g5
+ sth %g5, [%o0 + 2]
+1: add %o0, 4, %o0
+4: sll %o5, 24, %g6
+ ld [%o1], %o5
+ add %o1, 4, %o1
+ srl %o5, 8, %g5
+ sub %o5, %o2, %o4
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o5, %o4
+#endif
+ or %g5, %g6, %g5
+ andcc %o4, %o3, %g0
+ be,a 1b
+ st %g5, [%o0]
+ srl %o5, 24, %o4
+ andcc %o4, 0xff, %g0
+ be 6f
+ srl %o5, 16, %o4
+ andcc %o4, 0xff, %g0
+ be 7f
+ srl %o5, 8, %o4
+ st %g5, [%o0]
+ andcc %o4, 0xff, %g0
+ be 0f
+ andcc %o5, 0xff, %g0
+1: bne 4b
+ add %o0, 4, %o0
+9: stb %g0, [%o0]
+0: retl
+ mov %g2, %o0
+
+6: srl %g5, 16, %g5
+ sth %g5, [%o0]
+ retl
+ mov %g2, %o0
+
+7: srl %g5, 16, %g5
+ sth %g5, [%o0]
+ stb %g0, [%o0 + 2]
+ retl
+ mov %g2, %o0
+
+5: andcc %g5, 0xff, %g4
+ be 9b
+ srl %o5, 16, %g5
+ andcc %g5, 0xff, %g0
+ be 7f
+ srl %o5, 8, %g5
+ andcc %g5, 0xff, %g0
+ stb %g4, [%o0]
+ sth %g5, [%o0 + 1]
+ sub %o0, 1, %o0
+ bne 1b
+ andcc %o5, 0xff, %g0
+ retl
+ mov %g2, %o0
+
+7: stb %g4, [%o0]
+ stb %g0, [%o0 + 1]
+ retl
+ mov %g2, %o0
+
+2: andcc %o4, %o3, %g0
+ bne 5f
+ srl %o5, 16, %g5
+ sth %g5, [%o0]
+ sub %o0, 2, %o0
+1: add %o0, 4, %o0
+4: sll %o5, 16, %g6
+ ld [%o1], %o5
+ add %o1, 4, %o1
+ srl %o5, 16, %g5
+ sub %o5, %o2, %o4
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o5, %o4
+#endif
+ or %g5, %g6, %g5
+ andcc %o4, %o3, %g0
+ be,a 1b
+ st %g5, [%o0]
+ srl %o5, 24, %o4
+ andcc %o4, 0xff, %g0
+ be 7f
+ srl %o5, 16, %o4
+ st %g5, [%o0]
+ andcc %o4, 0xff, %g0
+ be 0b
+ srl %o5, 8, %o4
+1: andcc %o4, 0xff, %g0
+ be 8f
+ andcc %o5, 0xff, %g0
+ bne 4b
+ add %o0, 4, %o0
+ sth %o5, [%o0]
+ retl
+ mov %g2, %o0
+
+7: srl %g5, 16, %g5
+ sth %g5, [%o0]
+ stb %g0, [%o0 + 2]
+ retl
+ mov %g2, %o0
+
+8: stb %g0, [%o0 + 4]
+ retl
+ mov %g2, %o0
+
+5: srl %o5, 24, %g5
+ andcc %g5, 0xff, %g0
+ be 9b
+ srl %o5, 16, %g5
+ andcc %g5, 0xff, %g0
+ sth %g5, [%o0]
+ sub %o0, 2, %o0
+ bne 1b
+ srl %o5, 8, %o4
+ retl
+ mov %g2, %o0
+
+3: bne 5f
+ srl %o5, 24, %g5
+ stb %g5, [%o0]
+ sub %o0, 3, %o0
+1: add %o0, 4, %o0
+4: sll %o5, 8, %g6
+ ld [%o1], %o5
+ add %o1, 4, %o1
+ srl %o5, 24, %g5
+ sub %o5, %o2, %o4
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o5, %o4
+#endif
+ or %g5, %g6, %g5
+ andcc %o4, %o3, %g0
+ be 1b
+ st %g5, [%o0]
+ srl %o5, 24, %o4
+ andcc %o4, 0xff, %g0
+ be 0b
+ srl %o5, 16, %o4
+1: andcc %o4, 0xff, %g0
+ be 8b
+ srl %o5, 8, %o4
+ andcc %o4, 0xff, %g0
+ be 9f
+ andcc %o5, 0xff, %g0
+ bne 4b
+ add %o0, 4, %o0
+ srl %o5, 8, %o5
+ sth %o5, [%o0]
+ stb %g0, [%o0 + 2]
+ retl
+ mov %g2, %o0
+9: srl %o5, 8, %o5
+ sth %o5, [%o0 + 4]
+ retl
+ mov %g2, %o0
+5: andcc %g5, 0xff, %g0
+ stb %g5, [%o0]
+ sub %o0, 3, %o0
+ bne 1b
+ srl %o5, 16, %o4
+ retl
+ mov %g2, %o0
+END(strcat)
+libc_hidden_builtin_def (strcat)
diff --git a/libc/sysdeps/sparc/sparc32/strchr.S b/libc/sysdeps/sparc/sparc32/strchr.S
new file mode 100644
index 000000000..7c397171f
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/strchr.S
@@ -0,0 +1,285 @@
+/* strchr (str, ch) -- Return pointer to first occurrence of CH in STR.
+ For SPARC v7.
+ Copyright (C) 1996, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz> and
+ David S. Miller <davem@caip.rutgers.edu>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ /* Normally, this uses ((xword - 0x01010101) & 0x80808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x01010101) & (~xword) & 0x80808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 4
+ENTRY(strchr)
+ andcc %o1, 0xff, %o1
+ be 12f
+ sll %o1, 8, %o2
+ andcc %o0, 3, %g0
+ or %o1, %o2, %o2
+ sethi %hi(0x80808080), %o4
+ sll %o2, 16, %o3
+ be 13f
+ or %o3, %o2, %g2
+
+ ldub [%o0], %g4
+ cmp %g4, %o1
+ be 11f
+ add %o0, 1, %o0
+ cmp %g4, 0
+ be 9f
+ andcc %o0, 3, %g0
+ be 4f
+ or %o4, %lo(0x80808080), %o3
+ ldub [%o0], %g4
+ cmp %g4, %o1
+ be 11f
+ add %o0, 1, %o0
+ cmp %g4, 0
+ be 9f
+ andcc %o0, 3, %g0
+ be 5f
+ sethi %hi(0x01010101), %o5
+ ldub [%o0], %g4
+ cmp %g4, %o1
+ be 11f
+ add %o0, 1, %o0
+ cmp %g4, 0
+ be 9f
+ or %o5, %lo(0x01010101), %o2
+ b 6f
+ ld [%o0], %g4
+11: retl
+ sub %o0, 1, %o0
+
+13: or %o4, %lo(0x80808080), %o3
+4: sethi %hi(0x01010101), %o5
+5: or %o5, %lo(0x01010101), %o2
+7: ld [%o0], %g4
+6: xor %g4, %g2, %g5
+ sub %g4, %o2, %o4
+#ifdef EIGHTBIT_NOT_RARE
+ sub %g5, %o2, %g6
+ andn %o4, %g4, %o4
+ andn %g6, %g5, %g5
+#else
+ sub %g5, %o2, %g5
+#endif
+ or %g5, %o4, %o4
+ andcc %o4, %o3, %g0
+ be 7b
+ add %o0, 4, %o0
+
+ /* Check every byte. */
+8: srl %g4, 24, %g5
+7: andcc %g5, 0xff, %g5
+ be 9f
+ cmp %g5, %o1
+ be 4f
+ srl %g4, 16, %g5
+ andcc %g5, 0xff, %g5
+ be 9f
+ cmp %g5, %o1
+ be 3f
+ srl %g4, 8, %g5
+ andcc %g5, 0xff, %g5
+ be 9f
+ cmp %g5, %o1
+ be 2f
+ andcc %g4, 0xff, %g5
+ be 9f
+ cmp %g5, %o1
+ bne,a 6b
+ ld [%o0], %g4
+ retl
+ sub %o0, 1, %o0
+2: retl
+ sub %o0, 2, %o0
+3: retl
+ sub %o0, 3, %o0
+4: retl
+ sub %o0, 4, %o0
+9: retl
+ clr %o0
+
+11: ldub [%o0], %o5
+ cmp %o5, 0
+ be 1f
+ add %o0, 1, %o0
+ andcc %o0, 3, %g0
+ be 4f
+ or %o4, %lo(0x80808080), %o3
+ ldub [%o0], %o5
+ cmp %o5, 0
+ be 1f
+ add %o0, 1, %o0
+ andcc %o0, 3, %g0
+ be 5f
+ sethi %hi(0x01010101), %o4
+ ldub [%o0], %o5
+ cmp %o5, 0
+ be 1f
+ add %o0, 1, %o0
+ b 6f
+ or %o4, %lo(0x01010101), %o2
+1: retl
+ sub %o0, 1, %o0
+
+12: andcc %o0, 3, %g0
+ bne 11b
+ sethi %hi(0x80808080), %o4
+ or %o4, %lo(0x80808080), %o3
+4: sethi %hi(0x01010101), %o4
+5: or %o4, %lo(0x01010101), %o2
+6: ld [%o0], %o5
+7: sub %o5, %o2, %o4
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o5, %o4
+#endif
+ andcc %o4, %o3, %g0
+ be 6b
+ add %o0, 4, %o0
+
+ /* Check every byte. */
+ srl %o5, 24, %g5
+ andcc %g5, 0xff, %g0
+ be 8f
+ add %o0, -4, %o4
+ srl %o5, 16, %g5
+ andcc %g5, 0xff, %g0
+ be 8f
+ add %o4, 1, %o4
+ srl %o5, 8, %g5
+ andcc %g5, 0xff, %g0
+ be 8f
+ add %o4, 1, %o4
+ andcc %o5, 0xff, %g0
+ bne,a 7b
+ ld [%o0], %o5
+ add %o4, 1, %o4
+8: retl
+ mov %o4, %o0
+
+13: ldub [%o0], %g4
+ cmp %g4, %o1
+ add %o0, 1, %o0
+ be,a 1f
+ sub %o0, 1, %o5
+ cmp %g4, 0
+ be 9f
+1: andcc %o0, 3, %g0
+ be 4f
+ or %o4, %lo(0x80808080), %o3
+ ldub [%o0], %g4
+ cmp %g4, %o1
+ add %o0, 1, %o0
+ be,a 1f
+ sub %o0, 1, %o5
+ cmp %g4, 0
+ be 9f
+1: andcc %o0, 3, %g0
+ be 5f
+ sethi %hi(0x01010101), %o4
+ ldub [%o0], %g4
+ cmp %g4, %o1
+ add %o0, 1, %o0
+ be,a 1f
+ sub %o0, 1, %o5
+ cmp %g4, 0
+ be 9f
+1: or %o4, %lo(0x01010101), %o2
+ b 7f
+ ld [%o0], %g4
+END(strchr)
+
+ENTRY(strrchr)
+ andcc %o1, 0xff, %o1
+ clr %o5
+ be 12b
+ sll %o1, 8, %o2
+ andcc %o0, 3, %g0
+ or %o1, %o2, %o2
+ sethi %hi(0x80808080), %o4
+ sll %o2, 16, %o3
+ bne 13b
+ or %o3, %o2, %g2
+ or %o4, %lo(0x80808080), %o3
+4: sethi %hi(0x01010101), %o4
+5: or %o4, %lo(0x01010101), %o2
+6: ld [%o0], %g4
+7: xor %g4, %g2, %g5
+ sub %g4, %o2, %o4
+#ifdef EIGHTBIT_NOT_RARE
+ sub %g5, %o2, %g6
+ andn %o4, %g4, %o4
+ andn %g6, %g5, %g5
+#else
+ sub %g5, %o2, %g5
+#endif
+ or %g5, %o4, %o4
+ andcc %o4, %o3, %g0
+ be 6b
+ add %o0, 4, %o0
+
+ /* Check every byte. */
+3: srl %g4, 24, %g5
+8: andcc %g5, 0xff, %g5
+ be 9f
+ cmp %g5, %o1
+ be,a 1f
+ sub %o0, 4, %o5
+1: srl %g4, 16, %g5
+ andcc %g5, 0xff, %g5
+ be 9f
+ cmp %g5, %o1
+ be,a 1f
+ sub %o0, 3, %o5
+1: srl %g4, 8, %g5
+ andcc %g5, 0xff, %g5
+ be 9f
+ cmp %g5, %o1
+ be,a 1f
+ sub %o0, 2, %o5
+1: andcc %g4, 0xff, %g5
+ be 9f
+ cmp %g5, %o1
+ be,a 1f
+ sub %o0, 1, %o5
+1: b 7b
+ ld [%o0], %g4
+9: retl
+ mov %o5, %o0
+END(strrchr)
+
+weak_alias (strchr, index)
+weak_alias (strrchr, rindex)
+libc_hidden_builtin_def (strchr)
+libc_hidden_builtin_def (strrchr)
diff --git a/libc/sysdeps/sparc/sparc32/strcmp.S b/libc/sysdeps/sparc/sparc32/strcmp.S
new file mode 100644
index 000000000..cf369dd83
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/strcmp.S
@@ -0,0 +1,260 @@
+/* Compare two strings for differences.
+ For SPARC v7.
+ Copyright (C) 1996, 97, 99, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ /* Normally, this uses ((xword - 0x01010101) & 0x80808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x01010101) & (~xword) & 0x80808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 4
+
+ENTRY(strcmp)
+ andcc %o0, 3, %g0
+ be 13f
+ sethi %hi(0x80808080), %g1
+
+ ldub [%o0], %o4
+ add %o0, 1, %o0
+ ldub [%o1], %o5
+ cmp %o4, 0
+ add %o1, 1, %o1
+ be 2f
+ subcc %o4, %o5, %o4
+ bne 2f
+ andcc %o0, 3, %g0
+ be 4f
+ or %g1, %lo(0x80808080), %o3
+ ldub [%o0], %o4
+ add %o0, 1, %o0
+ ldub [%o1], %o5
+ cmp %o4, 0
+ add %o1, 1, %o1
+ be 2f
+ subcc %o4, %o5, %o4
+ bne 2f
+ andcc %o0, 3, %g0
+ be 5f
+ sethi %hi(0x01010101), %g1
+ ldub [%o0], %o4
+ add %o0, 1, %o0
+ ldub [%o1], %o5
+ cmp %o4, 0
+ add %o1, 1, %o1
+ be 2f
+ subcc %o4, %o5, %o4
+ bne 2f
+ andcc %o1, 3, %g2
+ bne 12f
+ or %g1, %lo(0x01010101), %o2
+ b 1f
+ ld [%o0], %o4
+2: retl
+ mov %o4, %o0
+
+13: or %g1, %lo(0x80808080), %o3
+4: sethi %hi(0x01010101), %g1
+5: andcc %o1, 3, %g2
+ bne 12f
+ or %g1, %lo(0x01010101), %o2
+
+0: ld [%o0], %o4
+1: ld [%o1], %o5
+ sub %o4, %o2, %g1
+ add %o0, 4, %o0
+ cmp %o4, %o5
+#ifdef EIGHTBIT_NOT_RARE
+ andn %g1, %o4, %g1
+#endif
+ bne 11f
+ andcc %g1, %o3, %g0
+ be 0b
+ add %o1, 4, %o1
+
+ srl %o4, 24, %g4
+ andcc %g4, 0xff, %g0
+ be 2f
+ srl %o4, 16, %g4
+ andcc %g4, 0xff, %g0
+ be 2f
+ srl %o4, 8, %g4
+ andcc %g4, 0xff, %g0
+ be 2f
+ andcc %o4, 0xff, %g0
+ bne,a 1b
+ ld [%o0], %o4
+2: retl
+ clr %o0
+
+11: srl %o4, 24, %g4
+ srl %o5, 24, %g5
+ andcc %g4, 0xff, %g0
+ be 3f
+ subcc %g4, %g5, %g4
+ bne 3f
+ srl %o5, 16, %g5
+ srl %o4, 16, %g4
+ andcc %g4, 0xff, %g0
+ be 3f
+ subcc %g4, %g5, %g4
+ bne 3f
+ srl %o5, 8, %g5
+ srl %o4, 8, %g4
+ andcc %g4, 0xff, %g0
+ be 3f
+ subcc %g4, %g5, %g4
+ bne 3f
+ subcc %o4, %o5, %o4
+ retl
+ mov %o4, %o0
+3: retl
+ mov %g4, %o0
+
+12: save %sp, -64, %sp
+ ld [%i0], %i4
+ sll %g2, 3, %g3
+ andn %i1, 3, %i1
+ mov 32, %l1
+ ld [%i1], %l2
+ mov -1, %g6
+ add %i1, 4, %i1
+ sub %l1, %g3, %l1
+ sll %g6, %g3, %g6
+
+1: sll %l2, %g3, %g5
+ and %i4, %g6, %l3
+ sub %i4, %i2, %g1
+#ifdef EIGHTBIT_NOT_RARE
+ andn %g1, %i4, %g1
+#endif
+ andcc %g1, %i3, %g1
+ bne 3f
+ cmp %g5, %l3
+ bne 2f
+ add %i0, 4, %i0
+ ld [%i1], %l2
+ add %i1, 4, %i1
+ srl %l2, %l1, %l4
+ or %l4, %g5, %l4
+ cmp %l4, %i4
+ be,a 1b
+ ld [%i0], %i4
+ restore %l4, %g0, %o3
+ retl
+ sub %o4, %o3, %o0
+
+2: sll %l2, %g3, %i2
+ srl %i4, %g3, %i3
+ srl %i2, %g3, %i2
+ restore
+ retl
+ sub %o3, %o2, %o0
+
+3: srl %i4, 24, %g4
+ srl %g5, 24, %l6
+ andcc %g4, 0xff, %g0
+ be 4f
+ subcc %g4, %l6, %g4
+ bne 4f
+ cmp %g2, 3
+ be 6f
+ srl %i4, 16, %g4
+ srl %g5, 16, %l6
+ andcc %g4, 0xff, %g0
+ be 4f
+ subcc %g4, %l6, %g4
+ bne 4f
+ cmp %g2, 2
+ be 5f
+ srl %i4, 8, %g4
+ srl %g5, 8, %l6
+ andcc %g4, 0xff, %g0
+ be 4f
+ subcc %g4, %l6, %g4
+ bne 4f
+ add %i0, 4, %i0
+ ld [%i1], %l2
+ add %i1, 4, %i1
+ srl %l2, 24, %g5
+ andcc %i4, 0xff, %g4
+ be 4f
+ subcc %g4, %g5, %g4
+ be,a 1b
+ ld [%i0], %i4
+4: jmpl %i7 + 8, %g0
+ restore %g4, %g0, %o0
+
+5: ld [%i1], %l2
+ add %i1, 4, %i1
+ add %i0, 4, %i0
+ srl %l2, 24, %l6
+ andcc %g4, 0xff, %g4
+ be 4b
+ subcc %g4, %l6, %g4
+ bne 4b
+ srl %l2, 16, %l6
+ andcc %i4, 0xff, %g4
+ and %l6, 0xff, %l6
+ be 4b
+ subcc %g4, %l6, %g4
+ be,a 1b
+ ld [%i0], %i4
+ jmpl %i7 + 8, %g0
+ restore %g4, %g0, %o0
+
+6: ld [%i1], %l2
+ add %i1, 4, %i1
+ add %i0, 4, %i0
+ srl %l2, 24, %l6
+ andcc %g4, 0xff, %g4
+ be 4b
+ subcc %g4, %l6, %g4
+ bne 4b
+ srl %l2, 16, %l6
+ srl %i4, 8, %g4
+ and %l6, 0xff, %l6
+ andcc %g4, 0xff, %g4
+ be 4b
+ subcc %g4, %l6, %g4
+ bne 4b
+ srl %l2, 8, %l6
+ andcc %i4, 0xff, %g4
+ and %l6, 0xff, %l6
+ be 4b
+ subcc %g4, %l6, %g4
+ be,a 1b
+ ld [%i0], %i4
+ jmpl %i7 + 8, %g0
+ restore %g4, %g0, %o0
+END(strcmp)
+libc_hidden_builtin_def (strcmp)
diff --git a/libc/sysdeps/sparc/sparc32/strcpy.S b/libc/sysdeps/sparc/sparc32/strcpy.S
new file mode 100644
index 000000000..f3f337e3f
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/strcpy.S
@@ -0,0 +1,277 @@
+/* Copy SRC to DEST returning DEST.
+ For SPARC v7.
+ Copyright (C) 1996, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ /* Normally, this uses ((xword - 0x01010101) & 0x80808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x01010101) & (~xword) & 0x80808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 4
+
+ENTRY(strcpy)
+ mov %o0, %g2
+ andcc %o1, 3, %g0
+ be 10f
+ sethi %hi(0x80808080), %o4
+
+ ldub [%o1], %o5
+ stb %o5, [%o0]
+ cmp %o5, 0
+ add %o0, 1, %o0
+ be 0f
+ add %o1, 1, %o1
+ andcc %o1, 3, %g0
+ be 4f
+ or %o4, %lo(0x80808080), %o3
+ ldub [%o1], %o5
+ stb %o5, [%o0]
+ cmp %o5, 0
+ add %o0, 1, %o0
+ be 0f
+ add %o1, 1, %o1
+ andcc %o1, 3, %g0
+ be 5f
+ sethi %hi(0x01010101), %o4
+ ldub [%o1], %o5
+ stb %o5, [%o0]
+ cmp %o5, 0
+ add %o0, 1, %o0
+ be 0f
+ add %o1, 1, %o1
+ b 6f
+ andcc %o0, 3, %g3
+
+10: or %o4, %lo(0x80808080), %o3
+4: sethi %hi(0x01010101), %o4
+5: andcc %o0, 3, %g3
+6: bne 10f
+ or %o4, %lo(0x01010101), %o2
+1: ld [%o1], %o5
+ add %o1, 4, %o1
+ sub %o5, %o2, %o4
+ add %o0, 4, %o0
+ andcc %o4, %o3, %g0
+ be,a 1b
+ st %o5, [%o0 - 4]
+
+ srl %o5, 24, %g5
+ andcc %g5, 0xff, %g0
+ be 1f
+ srl %o5, 16, %g5
+ andcc %g5, 0xff, %g0
+ be 2f
+ srl %o5, 8, %g5
+ andcc %g5, 0xff, %g0
+ be 3f
+ andcc %o5, 0xff, %g0
+ bne 1b
+ st %o5, [%o0 - 4]
+ retl
+ mov %g2, %o0
+3: srl %o5, 16, %o5
+ sth %o5, [%o0 - 4]
+ stb %g0, [%o0 - 2]
+ retl
+ mov %g2, %o0
+2: srl %o5, 16, %o5
+ sth %o5, [%o0 - 4]
+ retl
+ mov %g2, %o0
+1: stb %g0, [%o0 - 4]
+ retl
+ mov %g2, %o0
+
+10: ld [%o1], %o5
+ add %o1, 4, %o1
+ sub %o5, %o2, %o4
+ cmp %g3, 2
+ be 2f
+ cmp %g3, 3
+ be 3f
+ andcc %o4, %o3, %g0
+ bne 5f
+ srl %o5, 24, %g5
+ stb %g5, [%o0]
+ sub %o0, 1, %o0
+ srl %o5, 8, %g5
+ sth %g5, [%o0 + 2]
+1: add %o0, 4, %o0
+4: sll %o5, 24, %g6
+ ld [%o1], %o5
+ add %o1, 4, %o1
+ srl %o5, 8, %g5
+ sub %o5, %o2, %o4
+ or %g5, %g6, %g5
+ andcc %o4, %o3, %g0
+ be,a 1b
+ st %g5, [%o0]
+ srl %o5, 24, %o4
+ andcc %o4, 0xff, %g0
+ be 6f
+ srl %o5, 16, %o4
+ andcc %o4, 0xff, %g0
+ be 7f
+ srl %o5, 8, %o4
+ st %g5, [%o0]
+ andcc %o4, 0xff, %g0
+ be 0f
+ andcc %o5, 0xff, %g0
+1: bne 4b
+ add %o0, 4, %o0
+9: stb %g0, [%o0]
+0: retl
+ mov %g2, %o0
+6: srl %g5, 16, %g5
+ sth %g5, [%o0]
+ retl
+ mov %g2, %o0
+7: srl %g5, 16, %g5
+ sth %g5, [%o0]
+ stb %g0, [%o0 + 2]
+ retl
+ mov %g2, %o0
+5: andcc %g5, 0xff, %g4
+ be 9b
+ srl %o5, 16, %g5
+ andcc %g5, 0xff, %g0
+ be 7f
+ srl %o5, 8, %g5
+ andcc %g5, 0xff, %g0
+ stb %g4, [%o0]
+ sth %g5, [%o0 + 1]
+ sub %o0, 1, %o0
+ bne 1b
+ andcc %o5, 0xff, %g0
+ retl
+ mov %g2, %o0
+7: stb %g4, [%o0]
+ stb %g0, [%o0 + 1]
+ retl
+ mov %g2, %o0
+
+2: andcc %o4, %o3, %g0
+ bne 5f
+ srl %o5, 16, %g5
+ sth %g5, [%o0]
+ sub %o0, 2, %o0
+1: add %o0, 4, %o0
+4: sll %o5, 16, %g6
+ ld [%o1], %o5
+ add %o1, 4, %o1
+ srl %o5, 16, %g5
+ sub %o5, %o2, %o4
+ or %g5, %g6, %g5
+ andcc %o4, %o3, %g0
+ be,a 1b
+ st %g5, [%o0]
+ srl %o5, 24, %o4
+ andcc %o4, 0xff, %g0
+ be 7f
+ srl %o5, 16, %o4
+ st %g5, [%o0]
+ andcc %o4, 0xff, %g0
+ be 0b
+ srl %o5, 8, %o4
+1: andcc %o4, 0xff, %g0
+ be 8f
+ andcc %o5, 0xff, %g0
+ bne 4b
+ add %o0, 4, %o0
+ sth %o5, [%o0]
+ retl
+ mov %g2, %o0
+7: srl %g5, 16, %g5
+ sth %g5, [%o0]
+ stb %g0, [%o0 + 2]
+ retl
+ mov %g2, %o0
+8: stb %g0, [%o0 + 4]
+ retl
+ mov %g2, %o0
+5: srl %o5, 24, %g5
+ andcc %g5, 0xff, %g0
+ be 9b
+ srl %o5, 16, %g5
+ andcc %g5, 0xff, %g0
+ sth %g5, [%o0]
+ sub %o0, 2, %o0
+ bne 1b
+ srl %o5, 8, %o4
+ retl
+ mov %g2, %o0
+
+3: bne 5f
+ srl %o5, 24, %g5
+ stb %g5, [%o0]
+ sub %o0, 3, %o0
+1: add %o0, 4, %o0
+4: sll %o5, 8, %g6
+ ld [%o1], %o5
+ add %o1, 4, %o1
+ srl %o5, 24, %g5
+ sub %o5, %o2, %o4
+ or %g5, %g6, %g5
+ andcc %o4, %o3, %g0
+ be 1b
+ st %g5, [%o0]
+ srl %o5, 24, %o4
+ andcc %o4, 0xff, %g0
+ be 0b
+ srl %o5, 16, %o4
+1: andcc %o4, 0xff, %g0
+ be 8b
+ srl %o5, 8, %o4
+ andcc %o4, 0xff, %g0
+ be 9f
+ andcc %o5, 0xff, %g0
+ bne 4b
+ add %o0, 4, %o0
+ srl %o5, 8, %o5
+ sth %o5, [%o0]
+ stb %g0, [%o0 + 2]
+ retl
+ mov %g2, %o0
+9: srl %o5, 8, %o5
+ sth %o5, [%o0 + 4]
+ retl
+ mov %g2, %o0
+5: andcc %g5, 0xff, %g0
+ stb %g5, [%o0]
+ sub %o0, 3, %o0
+ bne 1b
+ srl %o5, 16, %o4
+ retl
+ mov %g2, %o0
+END(strcpy)
+libc_hidden_builtin_def (strcpy)
diff --git a/libc/sysdeps/sparc/sparc32/strlen.S b/libc/sysdeps/sparc/sparc32/strlen.S
new file mode 100644
index 000000000..ed92f20e2
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/strlen.S
@@ -0,0 +1,106 @@
+/* Determine the length of a string.
+ For SPARC v7.
+ Copyright (C) 1996, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ /* Normally, this uses ((xword - 0x01010101) & 0x80808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x01010101) & (~xword) & 0x80808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 4
+
+ENTRY(strlen)
+ mov %o0, %o1
+ andcc %o0, 3, %g0
+ be 20f
+ sethi %hi(0x80808080), %o4
+
+ ldub [%o0], %o5
+ cmp %o5, 0
+ be 21f
+ add %o0, 1, %o0
+ andcc %o0, 3, %g0
+ be 4f
+ or %o4, %lo(0x80808080), %o3
+ ldub [%o0], %o5
+ cmp %o5, 0
+ be 22f
+ add %o0, 1, %o0
+ andcc %o0, 3, %g0
+ be 5f
+ sethi %hi(0x01010101), %o4
+ ldub [%o0], %o5
+ cmp %o5, 0
+ be 23f
+ add %o0, 1, %o0
+ b 11f
+ or %o4, %lo(0x01010101), %o2
+21: retl
+ mov 0, %o0
+22: retl
+ mov 1, %o0
+23: retl
+ mov 2, %o0
+
+20: or %o4, %lo(0x80808080), %o3
+4: sethi %hi(0x01010101), %o4
+5: or %o4, %lo(0x01010101), %o2
+11: ld [%o0], %o5
+12: sub %o5, %o2, %o4
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o5, %o4
+#endif
+ andcc %o4, %o3, %g0
+ be 11b
+ add %o0, 4, %o0
+
+ srl %o5, 24, %g5
+ andcc %g5, 0xff, %g0
+ be 13f
+ add %o0, -4, %o4
+ srl %o5, 16, %g5
+ andcc %g5, 0xff, %g0
+ be 13f
+ add %o4, 1, %o4
+ srl %o5, 8, %g5
+ andcc %g5, 0xff, %g0
+ be 13f
+ add %o4, 1, %o4
+ andcc %o5, 0xff, %g0
+ bne,a 12b
+ ld [%o0], %o5
+ add %o4, 1, %o4
+13: retl
+ sub %o4, %o1, %o0
+END(strlen)
+libc_hidden_builtin_def (strlen)
diff --git a/libc/sysdeps/sparc/sparc32/strrchr.c b/libc/sysdeps/sparc/sparc32/strrchr.c
new file mode 100644
index 000000000..ec608d6ab
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/strrchr.c
@@ -0,0 +1 @@
+/* strrchr is in strchr.S */
diff --git a/libc/sysdeps/sparc/sparc32/sub_n.S b/libc/sysdeps/sparc/sparc32/sub_n.S
new file mode 100644
index 000000000..941efe1a2
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/sub_n.S
@@ -0,0 +1,329 @@
+! SPARC __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+! store difference in a third limb vector.
+!
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+!
+! This file is part of the GNU MP Library.
+!
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at your
+! option) any later version.
+!
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+! License for more details.
+!
+! You should have received a copy of the GNU Lesser General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+#define RES_PTR %o0
+#define S1_PTR %o1
+#define S2_PTR %o2
+#define SIZE %o3
+
+#include <sysdep.h>
+
+ENTRY(__mpn_sub_n)
+ xor S2_PTR,RES_PTR,%g1
+ andcc %g1,4,%g0
+ bne LOC(1) ! branch if alignment differs
+ nop
+! ** V1a **
+ andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
+ be LOC(v1) ! if no, branch
+ nop
+/* Add least significant limb separately to align RES_PTR and S2_PTR */
+ ld [S1_PTR],%g4
+ add S1_PTR,4,S1_PTR
+ ld [S2_PTR],%g2
+ add S2_PTR,4,S2_PTR
+ add SIZE,-1,SIZE
+ subcc %g4,%g2,%o4
+ st %o4,[RES_PTR]
+ add RES_PTR,4,RES_PTR
+LOC(v1):
+ addx %g0,%g0,%o4 ! save cy in register
+ cmp SIZE,2 ! if SIZE < 2 ...
+ bl LOC(end2) ! ... branch to tail code
+ subcc %g0,%o4,%g0 ! restore cy
+
+ ld [S1_PTR+0],%g4
+ addcc SIZE,-10,SIZE
+ ld [S1_PTR+4],%g1
+ ldd [S2_PTR+0],%g2
+ blt LOC(fin1)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+LOC(loop1):
+ subxcc %g4,%g2,%o4
+ ld [S1_PTR+8],%g4
+ subxcc %g1,%g3,%o5
+ ld [S1_PTR+12],%g1
+ ldd [S2_PTR+8],%g2
+ std %o4,[RES_PTR+0]
+ subxcc %g4,%g2,%o4
+ ld [S1_PTR+16],%g4
+ subxcc %g1,%g3,%o5
+ ld [S1_PTR+20],%g1
+ ldd [S2_PTR+16],%g2
+ std %o4,[RES_PTR+8]
+ subxcc %g4,%g2,%o4
+ ld [S1_PTR+24],%g4
+ subxcc %g1,%g3,%o5
+ ld [S1_PTR+28],%g1
+ ldd [S2_PTR+24],%g2
+ std %o4,[RES_PTR+16]
+ subxcc %g4,%g2,%o4
+ ld [S1_PTR+32],%g4
+ subxcc %g1,%g3,%o5
+ ld [S1_PTR+36],%g1
+ ldd [S2_PTR+32],%g2
+ std %o4,[RES_PTR+24]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ add S1_PTR,32,S1_PTR
+ add S2_PTR,32,S2_PTR
+ add RES_PTR,32,RES_PTR
+ bge LOC(loop1)
+ subcc %g0,%o4,%g0 ! restore cy
+
+LOC(fin1):
+ addcc SIZE,8-2,SIZE
+ blt LOC(end1)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+LOC(loope1):
+ subxcc %g4,%g2,%o4
+ ld [S1_PTR+8],%g4
+ subxcc %g1,%g3,%o5
+ ld [S1_PTR+12],%g1
+ ldd [S2_PTR+8],%g2
+ std %o4,[RES_PTR+0]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-2,SIZE
+ add S1_PTR,8,S1_PTR
+ add S2_PTR,8,S2_PTR
+ add RES_PTR,8,RES_PTR
+ bge LOC(loope1)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(end1):
+ subxcc %g4,%g2,%o4
+ subxcc %g1,%g3,%o5
+ std %o4,[RES_PTR+0]
+ addx %g0,%g0,%o4 ! save cy in register
+
+ andcc SIZE,1,%g0
+ be LOC(ret1)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+ ld [S1_PTR+8],%g4
+ ld [S2_PTR+8],%g2
+ subxcc %g4,%g2,%o4
+ st %o4,[RES_PTR+8]
+
+LOC(ret1):
+ retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+LOC(1): xor S1_PTR,RES_PTR,%g1
+ andcc %g1,4,%g0
+ bne LOC(2)
+ nop
+! ** V1b **
+ andcc RES_PTR,4,%g0 ! RES_PTR unaligned? Side effect: cy=0
+ be LOC(v1b) ! if no, branch
+ nop
+/* Add least significant limb separately to align RES_PTR and S1_PTR */
+ ld [S2_PTR],%g4
+ add S2_PTR,4,S2_PTR
+ ld [S1_PTR],%g2
+ add S1_PTR,4,S1_PTR
+ add SIZE,-1,SIZE
+ subcc %g2,%g4,%o4
+ st %o4,[RES_PTR]
+ add RES_PTR,4,RES_PTR
+LOC(v1b):
+ addx %g0,%g0,%o4 ! save cy in register
+ cmp SIZE,2 ! if SIZE < 2 ...
+ bl LOC(end2) ! ... branch to tail code
+ subcc %g0,%o4,%g0 ! restore cy
+
+ ld [S2_PTR+0],%g4
+ addcc SIZE,-10,SIZE
+ ld [S2_PTR+4],%g1
+ ldd [S1_PTR+0],%g2
+ blt LOC(fin1b)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+LOC(loop1b):
+ subxcc %g2,%g4,%o4
+ ld [S2_PTR+8],%g4
+ subxcc %g3,%g1,%o5
+ ld [S2_PTR+12],%g1
+ ldd [S1_PTR+8],%g2
+ std %o4,[RES_PTR+0]
+ subxcc %g2,%g4,%o4
+ ld [S2_PTR+16],%g4
+ subxcc %g3,%g1,%o5
+ ld [S2_PTR+20],%g1
+ ldd [S1_PTR+16],%g2
+ std %o4,[RES_PTR+8]
+ subxcc %g2,%g4,%o4
+ ld [S2_PTR+24],%g4
+ subxcc %g3,%g1,%o5
+ ld [S2_PTR+28],%g1
+ ldd [S1_PTR+24],%g2
+ std %o4,[RES_PTR+16]
+ subxcc %g2,%g4,%o4
+ ld [S2_PTR+32],%g4
+ subxcc %g3,%g1,%o5
+ ld [S2_PTR+36],%g1
+ ldd [S1_PTR+32],%g2
+ std %o4,[RES_PTR+24]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ add S1_PTR,32,S1_PTR
+ add S2_PTR,32,S2_PTR
+ add RES_PTR,32,RES_PTR
+ bge LOC(loop1b)
+ subcc %g0,%o4,%g0 ! restore cy
+
+LOC(fin1b):
+ addcc SIZE,8-2,SIZE
+ blt LOC(end1b)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+LOC(loope1b):
+ subxcc %g2,%g4,%o4
+ ld [S2_PTR+8],%g4
+ subxcc %g3,%g1,%o5
+ ld [S2_PTR+12],%g1
+ ldd [S1_PTR+8],%g2
+ std %o4,[RES_PTR+0]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-2,SIZE
+ add S1_PTR,8,S1_PTR
+ add S2_PTR,8,S2_PTR
+ add RES_PTR,8,RES_PTR
+ bge LOC(loope1b)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(end1b):
+ subxcc %g2,%g4,%o4
+ subxcc %g3,%g1,%o5
+ std %o4,[RES_PTR+0]
+ addx %g0,%g0,%o4 ! save cy in register
+
+ andcc SIZE,1,%g0
+ be LOC(ret1b)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+ ld [S2_PTR+8],%g4
+ ld [S1_PTR+8],%g2
+ subxcc %g2,%g4,%o4
+ st %o4,[RES_PTR+8]
+
+LOC(ret1b):
+ retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+! ** V2 **
+/* If we come here, the alignment of S1_PTR and RES_PTR as well as the
+ alignment of S2_PTR and RES_PTR differ. Since there are only two ways
+ things can be aligned (that we care about) we now know that the alignment
+ of S1_PTR and S2_PTR are the same. */
+
+LOC(2): cmp SIZE,1
+ be LOC(jone)
+ nop
+ andcc S1_PTR,4,%g0 ! S1_PTR unaligned? Side effect: cy=0
+ be LOC(v2) ! if no, branch
+ nop
+/* Add least significant limb separately to align S1_PTR and S2_PTR */
+ ld [S1_PTR],%g4
+ add S1_PTR,4,S1_PTR
+ ld [S2_PTR],%g2
+ add S2_PTR,4,S2_PTR
+ add SIZE,-1,SIZE
+ subcc %g4,%g2,%o4
+ st %o4,[RES_PTR]
+ add RES_PTR,4,RES_PTR
+
+LOC(v2):
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ blt LOC(fin2)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+LOC(loop2):
+ ldd [S1_PTR+0],%g2
+ ldd [S2_PTR+0],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+0]
+ subxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+4]
+ ldd [S1_PTR+8],%g2
+ ldd [S2_PTR+8],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+8]
+ subxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+12]
+ ldd [S1_PTR+16],%g2
+ ldd [S2_PTR+16],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+16]
+ subxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+20]
+ ldd [S1_PTR+24],%g2
+ ldd [S2_PTR+24],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+24]
+ subxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+28]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-8,SIZE
+ add S1_PTR,32,S1_PTR
+ add S2_PTR,32,S2_PTR
+ add RES_PTR,32,RES_PTR
+ bge LOC(loop2)
+ subcc %g0,%o4,%g0 ! restore cy
+
+LOC(fin2):
+ addcc SIZE,8-2,SIZE
+ blt LOC(end2)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(loope2):
+ ldd [S1_PTR+0],%g2
+ ldd [S2_PTR+0],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[RES_PTR+0]
+ subxcc %g3,%o5,%g3
+ st %g3,[RES_PTR+4]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc SIZE,-2,SIZE
+ add S1_PTR,8,S1_PTR
+ add S2_PTR,8,S2_PTR
+ add RES_PTR,8,RES_PTR
+ bge LOC(loope2)
+ subcc %g0,%o4,%g0 ! restore cy
+LOC(end2):
+ andcc SIZE,1,%g0
+ be LOC(ret2)
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+LOC(jone):
+ ld [S1_PTR],%g4
+ ld [S2_PTR],%g2
+ subxcc %g4,%g2,%o4
+ st %o4,[RES_PTR]
+
+LOC(ret2):
+ retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+END(__mpn_sub_n)
diff --git a/libc/sysdeps/sparc/sparc32/submul_1.S b/libc/sysdeps/sparc/sparc32/submul_1.S
new file mode 100644
index 000000000..8468377e9
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/submul_1.S
@@ -0,0 +1,147 @@
+! SPARC __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+! the result from a second limb vector.
+!
+! Copyright (C) 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
+!
+! This file is part of the GNU MP Library.
+!
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at your
+! option) any later version.
+!
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+! License for more details.
+!
+! You should have received a copy of the GNU Lesser General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! RES_PTR o0
+! S1_PTR o1
+! SIZE o2
+! S2_LIMB o3
+
+#include <sysdep.h>
+
+ENTRY(__mpn_submul_1)
+ ! Make S1_PTR and RES_PTR point at the end of their blocks
+ ! and put (- 4 x SIZE) in index/loop counter.
+ sll %o2,2,%o2
+ add %o0,%o2,%o4 ! RES_PTR in o4 since o0 is retval
+ add %o1,%o2,%o1
+ sub %g0,%o2,%o2
+
+ cmp %o3,0xfff
+ bgu LOC(large)
+ nop
+
+ ld [%o1+%o2],%o5
+ mov 0,%o0
+ b LOC(0)
+ add %o4,-4,%o4
+LOC(loop0):
+ subcc %o5,%g1,%g1
+ ld [%o1+%o2],%o5
+ addx %o0,%g0,%o0
+ st %g1,[%o4+%o2]
+LOC(0): wr %g0,%o3,%y
+ sra %o5,31,%g2
+ and %o3,%g2,%g2
+ andcc %g1,0,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,0,%g1
+ sra %g1,20,%g4
+ sll %g1,12,%g1
+ rd %y,%g3
+ srl %g3,20,%g3
+ or %g1,%g3,%g1
+
+ addcc %g1,%o0,%g1
+ addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb
+ addcc %o2,4,%o2 ! loop counter
+ bne LOC(loop0)
+ ld [%o4+%o2],%o5
+
+ subcc %o5,%g1,%g1
+ addx %o0,%g0,%o0
+ retl
+ st %g1,[%o4+%o2]
+
+
+LOC(large):
+ ld [%o1+%o2],%o5
+ mov 0,%o0
+ sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0
+ b LOC(1)
+ add %o4,-4,%o4
+LOC(loop):
+ subcc %o5,%g3,%g3
+ ld [%o1+%o2],%o5
+ addx %o0,%g0,%o0
+ st %g3,[%o4+%o2]
+LOC(1): wr %g0,%o5,%y
+ and %o5,%g4,%g2
+ andcc %g0,%g0,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%g0,%g1
+ rd %y,%g3
+ addcc %g3,%o0,%g3
+ addx %g2,%g1,%o0
+ addcc %o2,4,%o2
+ bne LOC(loop)
+ ld [%o4+%o2],%o5
+
+ subcc %o5,%g3,%g3
+ addx %o0,%g0,%o0
+ retl
+ st %g3,[%o4+%o2]
+
+END(__mpn_submul_1)
diff --git a/libc/sysdeps/sparc/sparc32/udiv.S b/libc/sysdeps/sparc/sparc32/udiv.S
new file mode 100644
index 000000000..0dd48f32b
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/udiv.S
@@ -0,0 +1,346 @@
+ /* This file is generated from divrem.m4; DO NOT EDIT! */
+/*
+ * Division and remainder, from Appendix E of the Sparc Version 8
+ * Architecture Manual, with fixes from Gordon Irlam.
+ */
+
+/*
+ * Input: dividend and divisor in %o0 and %o1 respectively.
+ *
+ * m4 parameters:
+ * .udiv name of function to generate
+ * div div=div => %o0 / %o1; div=rem => %o0 % %o1
+ * false false=true => signed; false=false => unsigned
+ *
+ * Algorithm parameters:
+ * N how many bits per iteration we try to get (4)
+ * WORDSIZE total number of bits (32)
+ *
+ * Derived constants:
+ * TOPBITS number of bits in the top decade of a number
+ *
+ * Important variables:
+ * Q the partial quotient under development (initially 0)
+ * R the remainder so far, initially the dividend
+ * ITER number of main division loop iterations required;
+ * equal to ceil(log2(quotient) / N). Note that this
+ * is the log base (2^N) of the quotient.
+ * V the current comparand, initially divisor*2^(ITER*N-1)
+ *
+ * Cost:
+ * Current estimate for non-large dividend is
+ * ceil(log2(quotient) / N) * (10 + 7N/2) + C
+ * A large dividend is one greater than 2^(31-TOPBITS) and takes a
+ * different path, as the upper bits of the quotient must be developed
+ * one bit at a time.
+ */
+
+
+
+#include <sysdep.h>
+#include <sys/trap.h>
+
+ENTRY(.udiv)
+
+ ! Ready to divide. Compute size of quotient; scale comparand.
+ orcc %o1, %g0, %o5
+ bne 1f
+ mov %o0, %o3
+
+ ! Divide by zero trap. If it returns, return 0 (about as
+ ! wrong as possible, but that is what SunOS does...).
+ ta ST_DIV0
+ retl
+ clr %o0
+
+1:
+ cmp %o3, %o5 ! if %o1 exceeds %o0, done
+ blu LOC(got_result) ! (and algorithm fails otherwise)
+ clr %o2
+ sethi %hi(1 << (32 - 4 - 1)), %g1
+ cmp %o3, %g1
+ blu LOC(not_really_big)
+ clr %o4
+
+ ! Here the dividend is >= 2**(31-N) or so. We must be careful here,
+ ! as our usual N-at-a-shot divide step will cause overflow and havoc.
+ ! The number of bits in the result here is N*ITER+SC, where SC <= N.
+ ! Compute ITER in an unorthodox manner: know we need to shift V into
+ ! the top decade: so do not even bother to compare to R.
+ 1:
+ cmp %o5, %g1
+ bgeu 3f
+ mov 1, %g2
+ sll %o5, 4, %o5
+ b 1b
+ add %o4, 1, %o4
+
+ ! Now compute %g2.
+ 2: addcc %o5, %o5, %o5
+ bcc LOC(not_too_big)
+ add %g2, 1, %g2
+
+ ! We get here if the %o1 overflowed while shifting.
+ ! This means that %o3 has the high-order bit set.
+ ! Restore %o5 and subtract from %o3.
+ sll %g1, 4, %g1 ! high order bit
+ srl %o5, 1, %o5 ! rest of %o5
+ add %o5, %g1, %o5
+ b LOC(do_single_div)
+ sub %g2, 1, %g2
+
+ LOC(not_too_big):
+ 3: cmp %o5, %o3
+ blu 2b
+ nop
+ be LOC(do_single_div)
+ nop
+ /* NB: these are commented out in the V8-Sparc manual as well */
+ /* (I do not understand this) */
+ ! %o5 > %o3: went too far: back up 1 step
+ ! srl %o5, 1, %o5
+ ! dec %g2
+ ! do single-bit divide steps
+ !
+ ! We have to be careful here. We know that %o3 >= %o5, so we can do the
+ ! first divide step without thinking. BUT, the others are conditional,
+ ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high-
+ ! order bit set in the first step, just falling into the regular
+ ! division loop will mess up the first time around.
+ ! So we unroll slightly...
+ LOC(do_single_div):
+ subcc %g2, 1, %g2
+ bl LOC(end_regular_divide)
+ nop
+ sub %o3, %o5, %o3
+ mov 1, %o2
+ b LOC(end_single_divloop)
+ nop
+ LOC(single_divloop):
+ sll %o2, 1, %o2
+ bl 1f
+ srl %o5, 1, %o5
+ ! %o3 >= 0
+ sub %o3, %o5, %o3
+ b 2f
+ add %o2, 1, %o2
+ 1: ! %o3 < 0
+ add %o3, %o5, %o3
+ sub %o2, 1, %o2
+ 2:
+ LOC(end_single_divloop):
+ subcc %g2, 1, %g2
+ bge LOC(single_divloop)
+ tst %o3
+ b,a LOC(end_regular_divide)
+
+LOC(not_really_big):
+1:
+ sll %o5, 4, %o5
+ cmp %o5, %o3
+ bleu 1b
+ addcc %o4, 1, %o4
+ be LOC(got_result)
+ sub %o4, 1, %o4
+
+ tst %o3 ! set up for initial iteration
+LOC(divloop):
+ sll %o2, 4, %o2
+ ! depth 1, accumulated bits 0
+ bl LOC(1.16)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 2, accumulated bits 1
+ bl LOC(2.17)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 3, accumulated bits 3
+ bl LOC(3.19)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 7
+ bl LOC(4.23)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (7*2+1), %o2
+
+LOC(4.23):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (7*2-1), %o2
+
+
+LOC(3.19):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 5
+ bl LOC(4.21)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (5*2+1), %o2
+
+LOC(4.21):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (5*2-1), %o2
+
+
+
+LOC(2.17):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 3, accumulated bits 1
+ bl LOC(3.17)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 3
+ bl LOC(4.19)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (3*2+1), %o2
+
+LOC(4.19):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (3*2-1), %o2
+
+
+LOC(3.17):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 1
+ bl LOC(4.17)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (1*2+1), %o2
+
+LOC(4.17):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (1*2-1), %o2
+
+
+
+
+LOC(1.16):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 2, accumulated bits -1
+ bl LOC(2.15)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 3, accumulated bits -1
+ bl LOC(3.15)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -1
+ bl LOC(4.15)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-1*2+1), %o2
+
+LOC(4.15):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-1*2-1), %o2
+
+
+LOC(3.15):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -3
+ bl LOC(4.13)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-3*2+1), %o2
+
+LOC(4.13):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-3*2-1), %o2
+
+
+
+LOC(2.15):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 3, accumulated bits -3
+ bl LOC(3.13)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -5
+ bl LOC(4.11)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-5*2+1), %o2
+
+LOC(4.11):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-5*2-1), %o2
+
+
+LOC(3.13):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -7
+ bl LOC(4.9)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-7*2+1), %o2
+
+LOC(4.9):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-7*2-1), %o2
+
+
+
+
+ 9:
+LOC(end_regular_divide):
+ subcc %o4, 1, %o4
+ bge LOC(divloop)
+ tst %o3
+ bl,a LOC(got_result)
+ ! non-restoring fixup here (one instruction only!)
+ sub %o2, 1, %o2
+
+
+LOC(got_result):
+
+ retl
+ mov %o2, %o0
+
+END(.udiv)
diff --git a/libc/sysdeps/sparc/sparc32/udiv_qrnnd.S b/libc/sysdeps/sparc/sparc32/udiv_qrnnd.S
new file mode 100644
index 000000000..4955318a6
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/udiv_qrnnd.S
@@ -0,0 +1,168 @@
+! SPARC __udiv_qrnnd division support, used from longlong.h.
+!
+! Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
+!
+! This file is part of the GNU MP Library.
+!
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at your
+! option) any later version.
+!
+! The GNU MP Library is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+! License for more details.
+!
+! You should have received a copy of the GNU Lesser General Public License
+! along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+!
+! Added PIC support - May/96, Miguel de Icaza
+!
+! INPUT PARAMETERS
+! rem_ptr i0
+! n1 i1
+! n0 i2
+! d i3
+
+#include <sysdep.h>
+#undef ret /* Kludge for glibc */
+
+#ifdef PIC
+ .text
+#else
+ .section .rodata,#alloc
+#endif
+ .align 8
+
+ .type two_to_32,@object
+ .size two_to_32,8
+two_to_32:
+ .double 0r4294967296
+
+ .type two_to_31,@object
+ .size two_to_31,8
+two_to_31:
+ .double 0r2147483648
+
+ .text
+ENTRY(__udiv_qrnnd)
+ !#PROLOGUE# 0
+ save %sp,-104,%sp
+ !#PROLOGUE# 1
+ st %i1,[%fp-8]
+ ld [%fp-8],%f10
+#ifdef PIC
+LOC(base):
+ call 1f
+ fitod %f10,%f4
+1: ldd [%o7-(LOC(base)-two_to_32)],%f8
+#else
+ sethi %hi(two_to_32),%o7
+ fitod %f10,%f4
+ ldd [%o7+%lo(two_to_32)],%f8
+#endif
+ cmp %i1,0
+ bge LOC(248)
+ mov %i0,%i5
+ faddd %f4,%f8,%f4
+LOC(248):
+ st %i2,[%fp-8]
+ ld [%fp-8],%f10
+ fmuld %f4,%f8,%f6
+ cmp %i2,0
+ bge LOC(249)
+ fitod %f10,%f2
+ faddd %f2,%f8,%f2
+LOC(249):
+ st %i3,[%fp-8]
+ faddd %f6,%f2,%f2
+ ld [%fp-8],%f10
+ cmp %i3,0
+ bge LOC(250)
+ fitod %f10,%f4
+ faddd %f4,%f8,%f4
+LOC(250):
+ fdivd %f2,%f4,%f2
+#ifdef PIC
+ ldd [%o7-(LOC(base)-two_to_31)],%f4
+#else
+ sethi %hi(two_to_31),%o7
+ ldd [%o7+%lo(two_to_31)],%f4
+#endif
+ fcmped %f2,%f4
+ nop
+ fbge,a LOC(251)
+ fsubd %f2,%f4,%f2
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ b LOC(252)
+ ld [%fp-8],%i4
+LOC(251):
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ ld [%fp-8],%i4
+ sethi %hi(-2147483648),%g2
+ xor %i4,%g2,%i4
+LOC(252):
+ wr %g0,%i4,%y
+ sra %i3,31,%g2
+ and %i4,%g2,%g2
+ andcc %g0,0,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,0,%g1
+ add %g1,%g2,%i0
+ rd %y,%g3
+ subcc %i2,%g3,%o7
+ subxcc %i1,%i0,%g0
+ be LOC(253)
+ cmp %o7,%i3
+
+ add %i4,-1,%i0
+ add %o7,%i3,%o7
+ st %o7,[%i5]
+ ret
+ restore
+LOC(253):
+ blu LOC(246)
+ mov %i4,%i0
+ add %i4,1,%i0
+ sub %o7,%i3,%o7
+LOC(246):
+ st %o7,[%i5]
+ ret
+ restore
+
+END(__udiv_qrnnd)
diff --git a/libc/sysdeps/sparc/sparc32/umul.S b/libc/sysdeps/sparc/sparc32/umul.S
new file mode 100644
index 000000000..096554a2b
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/umul.S
@@ -0,0 +1,155 @@
+/*
+ * Unsigned multiply. Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the
+ * upper 32 bits of the 64-bit product).
+ *
+ * This code optimizes short (less than 13-bit) multiplies. Short
+ * multiplies require 25 instruction cycles, and long ones require
+ * 45 instruction cycles.
+ *
+ * On return, overflow has occurred (%o1 is not zero) if and only if
+ * the Z condition code is clear, allowing, e.g., the following:
+ *
+ * call .umul
+ * nop
+ * bnz overflow (or tnz)
+ */
+
+#include <sysdep.h>
+
+ENTRY(.umul)
+ or %o0, %o1, %o4
+ mov %o0, %y ! multiplier -> Y
+ andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args
+ be LOC(mul_shortway) ! if zero, can do it the short way
+ andcc %g0, %g0, %o4 ! zero the partial product; clear N & V
+
+ /*
+ * Long multiply. 32 steps, followed by a final shift step.
+ */
+ mulscc %o4, %o1, %o4 ! 1
+ mulscc %o4, %o1, %o4 ! 2
+ mulscc %o4, %o1, %o4 ! 3
+ mulscc %o4, %o1, %o4 ! 4
+ mulscc %o4, %o1, %o4 ! 5
+ mulscc %o4, %o1, %o4 ! 6
+ mulscc %o4, %o1, %o4 ! 7
+ mulscc %o4, %o1, %o4 ! 8
+ mulscc %o4, %o1, %o4 ! 9
+ mulscc %o4, %o1, %o4 ! 10
+ mulscc %o4, %o1, %o4 ! 11
+ mulscc %o4, %o1, %o4 ! 12
+ mulscc %o4, %o1, %o4 ! 13
+ mulscc %o4, %o1, %o4 ! 14
+ mulscc %o4, %o1, %o4 ! 15
+ mulscc %o4, %o1, %o4 ! 16
+ mulscc %o4, %o1, %o4 ! 17
+ mulscc %o4, %o1, %o4 ! 18
+ mulscc %o4, %o1, %o4 ! 19
+ mulscc %o4, %o1, %o4 ! 20
+ mulscc %o4, %o1, %o4 ! 21
+ mulscc %o4, %o1, %o4 ! 22
+ mulscc %o4, %o1, %o4 ! 23
+ mulscc %o4, %o1, %o4 ! 24
+ mulscc %o4, %o1, %o4 ! 25
+ mulscc %o4, %o1, %o4 ! 26
+ mulscc %o4, %o1, %o4 ! 27
+ mulscc %o4, %o1, %o4 ! 28
+ mulscc %o4, %o1, %o4 ! 29
+ mulscc %o4, %o1, %o4 ! 30
+ mulscc %o4, %o1, %o4 ! 31
+ mulscc %o4, %o1, %o4 ! 32
+ mulscc %o4, %g0, %o4 ! final shift
+
+ /*
+ * Normally, with the shift-and-add approach, if both numbers are
+ * positive you get the correct result. With 32-bit two's-complement
+ * numbers, -x is represented as
+ *
+ * x 32
+ * ( 2 - ------ ) mod 2 * 2
+ * 32
+ * 2
+ *
+ * (the `mod 2' subtracts 1 from 1.bbbb). To avoid lots of 2^32s,
+ * we can treat this as if the radix point were just to the left
+ * of the sign bit (multiply by 2^32), and get
+ *
+ * -x = (2 - x) mod 2
+ *
+ * Then, ignoring the `mod 2's for convenience:
+ *
+ * x * y = xy
+ * -x * y = 2y - xy
+ * x * -y = 2x - xy
+ * -x * -y = 4 - 2x - 2y + xy
+ *
+ * For signed multiplies, we subtract (x << 32) from the partial
+ * product to fix this problem for negative multipliers (see mul.s).
+ * Because of the way the shift into the partial product is calculated
+ * (N xor V), this term is automatically removed for the multiplicand,
+ * so we don't have to adjust.
+ *
+ * But for unsigned multiplies, the high order bit wasn't a sign bit,
+ * and the correction is wrong. So for unsigned multiplies where the
+ * high order bit is one, we end up with xy - (y << 32). To fix it
+ * we add y << 32.
+ */
+#if 0
+ tst %o1
+ bl,a 1f ! if %o1 < 0 (high order bit = 1),
+ add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half)
+1: rd %y, %o0 ! get lower half of product
+ retl
+ addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0
+#else
+ /* Faster code from tege@sics.se. */
+ sra %o1, 31, %o2 ! make mask from sign bit
+ and %o0, %o2, %o2 ! %o2 = 0 or %o0, depending on sign of %o1
+ rd %y, %o0 ! get lower half of product
+ retl
+ addcc %o4, %o2, %o1 ! add compensation and put upper half in place
+#endif
+
+LOC(mul_shortway):
+ /*
+ * Short multiply. 12 steps, followed by a final shift step.
+ * The resulting bits are off by 12 and (32-12) = 20 bit positions,
+ * but there is no problem with %o0 being negative (unlike above),
+ * and overflow is impossible (the answer is at most 24 bits long).
+ */
+ mulscc %o4, %o1, %o4 ! 1
+ mulscc %o4, %o1, %o4 ! 2
+ mulscc %o4, %o1, %o4 ! 3
+ mulscc %o4, %o1, %o4 ! 4
+ mulscc %o4, %o1, %o4 ! 5
+ mulscc %o4, %o1, %o4 ! 6
+ mulscc %o4, %o1, %o4 ! 7
+ mulscc %o4, %o1, %o4 ! 8
+ mulscc %o4, %o1, %o4 ! 9
+ mulscc %o4, %o1, %o4 ! 10
+ mulscc %o4, %o1, %o4 ! 11
+ mulscc %o4, %o1, %o4 ! 12
+ mulscc %o4, %g0, %o4 ! final shift
+
+ /*
+ * %o4 has 20 of the bits that should be in the result; %y has
+ * the bottom 12 (as %y's top 12). That is:
+ *
+ * %o4 %y
+ * +----------------+----------------+
+ * | -12- | -20- | -12- | -20- |
+ * +------(---------+------)---------+
+ * -----result-----
+ *
+ * The 12 bits of %o4 left of the `result' area are all zero;
+ * in fact, all top 20 bits of %o4 are zero.
+ */
+
+ rd %y, %o5
+ sll %o4, 12, %o0 ! shift middle bits left 12
+ srl %o5, 20, %o5 ! shift low bits right 20
+ or %o5, %o0, %o0
+ retl
+ addcc %g0, %g0, %o1 ! %o1 = zero, and set Z
+
+END(.umul)
diff --git a/libc/sysdeps/sparc/sparc32/urem.S b/libc/sysdeps/sparc/sparc32/urem.S
new file mode 100644
index 000000000..5644e7a89
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc32/urem.S
@@ -0,0 +1,346 @@
+ /* This file is generated from divrem.m4; DO NOT EDIT! */
+/*
+ * Division and remainder, from Appendix E of the Sparc Version 8
+ * Architecture Manual, with fixes from Gordon Irlam.
+ */
+
+/*
+ * Input: dividend and divisor in %o0 and %o1 respectively.
+ *
+ * m4 parameters:
+ * .urem name of function to generate
+ * rem rem=div => %o0 / %o1; rem=rem => %o0 % %o1
+ * false false=true => signed; false=false => unsigned
+ *
+ * Algorithm parameters:
+ * N how many bits per iteration we try to get (4)
+ * WORDSIZE total number of bits (32)
+ *
+ * Derived constants:
+ * TOPBITS number of bits in the top decade of a number
+ *
+ * Important variables:
+ * Q the partial quotient under development (initially 0)
+ * R the remainder so far, initially the dividend
+ * ITER number of main division loop iterations required;
+ * equal to ceil(log2(quotient) / N). Note that this
+ * is the log base (2^N) of the quotient.
+ * V the current comparand, initially divisor*2^(ITER*N-1)
+ *
+ * Cost:
+ * Current estimate for non-large dividend is
+ * ceil(log2(quotient) / N) * (10 + 7N/2) + C
+ * A large dividend is one greater than 2^(31-TOPBITS) and takes a
+ * different path, as the upper bits of the quotient must be developed
+ * one bit at a time.
+ */
+
+
+
+#include <sysdep.h>
+#include <sys/trap.h>
+
+ENTRY(.urem)
+
+ ! Ready to divide. Compute size of quotient; scale comparand.
+ orcc %o1, %g0, %o5
+ bne 1f
+ mov %o0, %o3
+
+ ! Divide by zero trap. If it returns, return 0 (about as
+ ! wrong as possible, but that is what SunOS does...).
+ ta ST_DIV0
+ retl
+ clr %o0
+
+1:
+ cmp %o3, %o5 ! if %o1 exceeds %o0, done
+ blu LOC(got_result) ! (and algorithm fails otherwise)
+ clr %o2
+ sethi %hi(1 << (32 - 4 - 1)), %g1
+ cmp %o3, %g1
+ blu LOC(not_really_big)
+ clr %o4
+
+ ! Here the dividend is >= 2**(31-N) or so. We must be careful here,
+ ! as our usual N-at-a-shot divide step will cause overflow and havoc.
+ ! The number of bits in the result here is N*ITER+SC, where SC <= N.
+ ! Compute ITER in an unorthodox manner: know we need to shift V into
+ ! the top decade: so do not even bother to compare to R.
+ 1:
+ cmp %o5, %g1
+ bgeu 3f
+ mov 1, %g2
+ sll %o5, 4, %o5
+ b 1b
+ add %o4, 1, %o4
+
+ ! Now compute %g2.
+ 2: addcc %o5, %o5, %o5
+ bcc LOC(not_too_big)
+ add %g2, 1, %g2
+
+ ! We get here if the %o1 overflowed while shifting.
+ ! This means that %o3 has the high-order bit set.
+ ! Restore %o5 and subtract from %o3.
+ sll %g1, 4, %g1 ! high order bit
+ srl %o5, 1, %o5 ! rest of %o5
+ add %o5, %g1, %o5
+ b LOC(do_single_div)
+ sub %g2, 1, %g2
+
+ LOC(not_too_big):
+ 3: cmp %o5, %o3
+ blu 2b
+ nop
+ be LOC(do_single_div)
+ nop
+ /* NB: these are commented out in the V8-Sparc manual as well */
+ /* (I do not understand this) */
+ ! %o5 > %o3: went too far: back up 1 step
+ ! srl %o5, 1, %o5
+ ! dec %g2
+ ! do single-bit divide steps
+ !
+ ! We have to be careful here. We know that %o3 >= %o5, so we can do the
+ ! first divide step without thinking. BUT, the others are conditional,
+ ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high-
+ ! order bit set in the first step, just falling into the regular
+ ! division loop will mess up the first time around.
+ ! So we unroll slightly...
+ LOC(do_single_div):
+ subcc %g2, 1, %g2
+ bl LOC(end_regular_divide)
+ nop
+ sub %o3, %o5, %o3
+ mov 1, %o2
+ b LOC(end_single_divloop)
+ nop
+ LOC(single_divloop):
+ sll %o2, 1, %o2
+ bl 1f
+ srl %o5, 1, %o5
+ ! %o3 >= 0
+ sub %o3, %o5, %o3
+ b 2f
+ add %o2, 1, %o2
+ 1: ! %o3 < 0
+ add %o3, %o5, %o3
+ sub %o2, 1, %o2
+ 2:
+ LOC(end_single_divloop):
+ subcc %g2, 1, %g2
+ bge LOC(single_divloop)
+ tst %o3
+ b,a LOC(end_regular_divide)
+
+LOC(not_really_big):
+1:
+ sll %o5, 4, %o5
+ cmp %o5, %o3
+ bleu 1b
+ addcc %o4, 1, %o4
+ be LOC(got_result)
+ sub %o4, 1, %o4
+
+ tst %o3 ! set up for initial iteration
+LOC(divloop):
+ sll %o2, 4, %o2
+ ! depth 1, accumulated bits 0
+ bl LOC(1.16)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 2, accumulated bits 1
+ bl LOC(2.17)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 3, accumulated bits 3
+ bl LOC(3.19)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 7
+ bl LOC(4.23)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (7*2+1), %o2
+
+LOC(4.23):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (7*2-1), %o2
+
+
+LOC(3.19):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 5
+ bl LOC(4.21)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (5*2+1), %o2
+
+LOC(4.21):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (5*2-1), %o2
+
+
+
+LOC(2.17):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 3, accumulated bits 1
+ bl LOC(3.17)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 3
+ bl LOC(4.19)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (3*2+1), %o2
+
+LOC(4.19):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (3*2-1), %o2
+
+
+LOC(3.17):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits 1
+ bl LOC(4.17)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (1*2+1), %o2
+
+LOC(4.17):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (1*2-1), %o2
+
+
+
+
+LOC(1.16):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 2, accumulated bits -1
+ bl LOC(2.15)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 3, accumulated bits -1
+ bl LOC(3.15)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -1
+ bl LOC(4.15)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-1*2+1), %o2
+
+LOC(4.15):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-1*2-1), %o2
+
+
+LOC(3.15):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -3
+ bl LOC(4.13)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-3*2+1), %o2
+
+LOC(4.13):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-3*2-1), %o2
+
+
+
+LOC(2.15):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 3, accumulated bits -3
+ bl LOC(3.13)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -5
+ bl LOC(4.11)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-5*2+1), %o2
+
+LOC(4.11):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-5*2-1), %o2
+
+
+LOC(3.13):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ ! depth 4, accumulated bits -7
+ bl LOC(4.9)
+ srl %o5,1,%o5
+ ! remainder is positive
+ subcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-7*2+1), %o2
+
+LOC(4.9):
+ ! remainder is negative
+ addcc %o3,%o5,%o3
+ b 9f
+ add %o2, (-7*2-1), %o2
+
+
+
+
+ 9:
+LOC(end_regular_divide):
+ subcc %o4, 1, %o4
+ bge LOC(divloop)
+ tst %o3
+ bl,a LOC(got_result)
+ ! non-restoring fixup here (one instruction only!)
+ add %o3, %o1, %o3
+
+
+LOC(got_result):
+
+ retl
+ mov %o3, %o0
+
+END(.urem)
diff --git a/libc/sysdeps/sparc/sparc64/Implies b/libc/sysdeps/sparc/sparc64/Implies
new file mode 100644
index 000000000..01bf14e73
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/Implies
@@ -0,0 +1,6 @@
+wordsize-64
+# SPARC uses IEEE 754 floating point.
+ieee754/ldbl-128
+ieee754/dbl-64
+ieee754/flt-32
+sparc/sparc64/soft-fp
diff --git a/libc/sysdeps/sparc/sparc64/Makefile b/libc/sysdeps/sparc/sparc64/Makefile
new file mode 100644
index 000000000..c1df31727
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/Makefile
@@ -0,0 +1,4 @@
+ifeq ($(subdir),csu)
+sysdep_routines += hp-timing
+elide-routines.os += hp-timing
+endif
diff --git a/libc/sysdeps/sparc/sparc64/Versions b/libc/sysdeps/sparc/sparc64/Versions
new file mode 100644
index 000000000..4cef7bcc7
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/Versions
@@ -0,0 +1,14 @@
+libc {
+ GLIBC_2.1.1 {
+ # SPARC v9 SYSV ABI helper functions
+ __align_cpy_1; __align_cpy_2; __align_cpy_4;
+ __align_cpy_8; __align_cpy_16;
+ }
+}
+libm {
+ GLIBC_2.1 {
+ # A generic bug got this omitted from other configurations' version
+ # sets, but we always had it.
+ exp2l;
+ }
+}
diff --git a/libc/sysdeps/sparc/sparc64/add_n.S b/libc/sysdeps/sparc/sparc64/add_n.S
new file mode 100644
index 000000000..d1996a0b1
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/add_n.S
@@ -0,0 +1,58 @@
+/* SPARC v9 __mpn_add_n -- Add two limb vectors of the same length > 0 and
+ store sum in a third limb vector.
+
+ Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+
+#include <sysdep.h>
+
+
+/* INPUT PARAMETERS
+ res_ptr %o0
+ s1_ptr %o1
+ s2_ptr %o2
+ size %o3 */
+
+
+ENTRY(__mpn_add_n)
+
+ sub %g0,%o3,%g5
+ sllx %o3,3,%g1
+ add %o1,%g1,%o1 ! make s1_ptr point at end
+ add %o2,%g1,%o2 ! make s2_ptr point at end
+ add %o0,%g1,%o0 ! make res_ptr point at end
+ mov 0,%o4 ! clear carry variable
+ sllx %g5,3,%o5 ! compute initial address index
+
+1: ldx [%o2+%o5],%g1 ! load s2 limb
+ add %g5,1,%g5 ! increment loop count
+ ldx [%o1+%o5],%o3 ! load s1 limb
+ addcc %g1,%o4,%g1 ! add s2 limb and carry variable
+ movcc %xcc,0,%o4 ! if carry-out, o4 was 1; clear it
+ addcc %g1,%o3,%g1 ! add s1 limb to sum
+ stx %g1,[%o0+%o5] ! store result
+ add %o5,8,%o5 ! increment address index
+ brnz,pt %g5,1b
+ movcs %xcc,1,%o4 ! if s1 add gave carry, record it
+
+ retl
+ mov %o4,%o0
+
+END(__mpn_add_n)
diff --git a/libc/sysdeps/sparc/sparc64/addmul_1.S b/libc/sysdeps/sparc/sparc64/addmul_1.S
new file mode 100644
index 000000000..2add679f9
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/addmul_1.S
@@ -0,0 +1,84 @@
+/* SPARC v9 __mpn_addmul_1 -- Multiply a limb vector with a single limb and
+ add the product to a second limb vector.
+
+ Copyright (C) 1996, 1999 Free Software Foundation, Inc.
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include <sysdep.h>
+
+
+/* INPUT PARAMETERS
+ res_ptr o0
+ s1_ptr o1
+ size o2
+ s2_limb o3 */
+
+
+ENTRY(__mpn_addmul_1)
+ save %sp,-192,%sp
+
+ sub %g0,%i2,%o7
+ mov 0,%o0 ! zero cy_limb
+ sllx %o7,3,%o7
+ sethi %hi(0x80000000),%o2
+ srl %i3,0,%o1 ! extract low 32 bits of s2_limb
+ sub %i1,%o7,%o3
+ srlx %i3,32,%i3 ! extract high 32 bits of s2_limb
+ sub %i0,%o7,%o4
+ add %o2,%o2,%o2 ! o2 = 0x100000000
+
+ ! hi !
+ ! mid-1 !
+ ! mid-2 !
+ ! lo !
+1:
+ ldx [%o3+%o7],%g5
+ srl %g5,0,%i0 ! zero hi bits
+ ldx [%o4+%o7],%l1
+ srlx %g5,32,%g5
+ mulx %o1,%i0,%i4 ! lo product
+ mulx %i3,%i0,%i1 ! mid-1 product
+ mulx %o1,%g5,%l2 ! mid-2 product
+ mulx %i3,%g5,%i5 ! hi product
+ srlx %i4,32,%i0 ! extract high 32 bits of lo product...
+ add %i1,%i0,%i1 ! ...and add it to the mid-1 product
+ addcc %i1,%l2,%i1 ! add mid products
+ mov 0,%l0 ! we need the carry from that add...
+ movcs %xcc,%o2,%l0 ! ...compute it and...
+ sllx %i1,32,%i0 ! align low bits of mid product
+ add %i5,%l0,%i5 ! ...add to bit 32 of the hi product
+ srl %i4,0,%g5 ! zero high 32 bits of lo product
+ add %i0,%g5,%i0 ! combine into low 64 bits of result
+ srlx %i1,32,%i1 ! extract high bits of mid product...
+ addcc %i0,%o0,%i0 ! add cy_limb to low 64 bits of result
+ add %i5,%i1,%i1 ! ...and add them to the high result
+ mov 0,%g5
+ movcs %xcc,1,%g5
+ addcc %l1,%i0,%i0
+ stx %i0,[%o4+%o7]
+ add %g5,1,%l1
+ movcs %xcc,%l1,%g5
+ addcc %o7,8,%o7
+ bne,pt %xcc,1b
+ add %i1,%g5,%o0 ! compute new cy_limb
+
+ jmpl %i7+8, %g0
+ restore %o0,%g0,%o0
+
+END(__mpn_addmul_1)
diff --git a/libc/sysdeps/sparc/sparc64/bcopy.c b/libc/sysdeps/sparc/sparc64/bcopy.c
new file mode 100644
index 000000000..9a455f33c
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/bcopy.c
@@ -0,0 +1 @@
+/* bcopy is in memcpy.S */
diff --git a/libc/sysdeps/sparc/sparc64/bits/atomic.h b/libc/sysdeps/sparc/sparc64/bits/atomic.h
new file mode 100644
index 000000000..d0a64afce
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/bits/atomic.h
@@ -0,0 +1,109 @@
+/* Atomic operations. sparc64 version.
+ Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+
+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+
+#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+({ \
+ __typeof (*(mem)) __acev_tmp; \
+ __typeof (mem) __acev_mem = (mem); \
+ __asm __volatile ("cas [%4], %2, %0" \
+ : "=r" (__acev_tmp), "=m" (*__acev_mem) \
+ : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \
+ "0" (newval) : "memory"); \
+ __acev_tmp; })
+
+#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+({ \
+ __typeof (*(mem)) __acev_tmp; \
+ __typeof (mem) __acev_mem = (mem); \
+ __asm __volatile ("casx [%4], %2, %0" \
+ : "=r" (__acev_tmp), "=m" (*__acev_mem) \
+ : "r" ((long) (oldval)), "m" (*__acev_mem), \
+ "r" (__acev_mem), "0" ((long) (newval)) : "memory"); \
+ __acev_tmp; })
+
+#define atomic_exchange_acq(mem, newvalue) \
+ ({ __typeof (*(mem)) __oldval, __val; \
+ __typeof (mem) __memp = (mem); \
+ __typeof (*(mem)) __value = (newvalue); \
+ \
+ if (sizeof (*(mem)) == 4) \
+ __asm ("swap %0, %1" \
+ : "=m" (*__memp), "=r" (__oldval) \
+ : "m" (*__memp), "1" (__value) : "memory"); \
+ else \
+ { \
+ __val = *__memp; \
+ do \
+ { \
+ __oldval = __val; \
+ __val = atomic_compare_and_exchange_val_acq (__memp, __value, \
+ __oldval); \
+ } \
+ while (__builtin_expect (__val != __oldval, 0)); \
+ } \
+ __oldval; })
+
+#define atomic_compare_and_exchange_val_24_acq(mem, newval, oldval) \
+ atomic_compare_and_exchange_val_acq (mem, newval, oldval)
+
+#define atomic_exchange_24_rel(mem, newval) \
+ atomic_exchange_rel (mem, newval)
+
+#define atomic_full_barrier() \
+ __asm __volatile ("membar #LoadLoad | #LoadStore" \
+ " | #StoreLoad | #StoreStore" : : : "memory")
+#define atomic_read_barrier() \
+ __asm __volatile ("membar #LoadLoad | #LoadStore" : : : "memory")
+#define atomic_write_barrier() \
+ __asm __volatile ("membar #StoreLoad | #StoreStore" : : : "memory")
diff --git a/libc/sysdeps/sparc/sparc64/bits/wordsize.h b/libc/sysdeps/sparc/sparc64/bits/wordsize.h
new file mode 100644
index 000000000..0dee88b28
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/bits/wordsize.h
@@ -0,0 +1,8 @@
+/* Determine the wordsize from the preprocessor defines. */
+
+#if defined __arch64__ || defined __sparcv9
+# define __WORDSIZE 64
+# define __WORDSIZE_COMPAT32 1
+#else
+# define __WORDSIZE 32
+#endif
diff --git a/libc/sysdeps/sparc/sparc64/bzero.c b/libc/sysdeps/sparc/sparc64/bzero.c
new file mode 100644
index 000000000..37f0f6f99
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/bzero.c
@@ -0,0 +1 @@
+/* bzero is in memset.S */
diff --git a/libc/sysdeps/sparc/sparc64/dl-machine.h b/libc/sysdeps/sparc/sparc64/dl-machine.h
new file mode 100644
index 000000000..ce9b8c9dd
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/dl-machine.h
@@ -0,0 +1,771 @@
+/* Machine-dependent ELF dynamic relocation inline functions. Sparc64 version.
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "sparc64"
+
+#include <string.h>
+#include <sys/param.h>
+#include <ldsodefs.h>
+#include <sysdep.h>
+
+#ifndef VALIDX
+# define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
+ + DT_EXTRANUM + DT_VALTAGIDX (tag))
+#endif
+
+#define ELF64_R_TYPE_ID(info) ((info) & 0xff)
+#define ELF64_R_TYPE_DATA(info) ((info) >> 8)
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int
+elf_machine_matches_host (const Elf64_Ehdr *ehdr)
+{
+ return ehdr->e_machine == EM_SPARCV9;
+}
+
+/* We have to do this because elf_machine_{dynamic,load_address} can be
+ invoked from functions that have no GOT references, and thus the compiler
+ has no obligation to load the PIC register. */
+#define LOAD_PIC_REG(PIC_REG) \
+do { Elf64_Addr tmp; \
+ __asm("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \
+ "rd %%pc, %0\n\t" \
+ "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t" \
+ "add %0, %1, %0" \
+ : "=r" (PIC_REG), "=r" (tmp)); \
+} while (0)
+
+/* Return the link-time address of _DYNAMIC. Conveniently, this is the
+ first element of the GOT. This must be inlined in a function which
+ uses global data. */
+static inline Elf64_Addr
+elf_machine_dynamic (void)
+{
+ register Elf64_Addr *elf_pic_register __asm__("%l7");
+
+ LOAD_PIC_REG (elf_pic_register);
+
+ return *elf_pic_register;
+}
+
+/* Return the run-time load address of the shared object. */
+static inline Elf64_Addr
+elf_machine_load_address (void)
+{
+ register Elf32_Addr *pc __asm ("%o7");
+ register Elf64_Addr *got __asm ("%l7");
+
+ __asm ("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t"
+ "call 1f\n\t"
+ " add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t"
+ "call _DYNAMIC\n\t"
+ "call _GLOBAL_OFFSET_TABLE_\n"
+ "1:\tadd %1, %0, %1\n\t" : "=r" (pc), "=r" (got));
+
+ /* got is now l_addr + _GLOBAL_OFFSET_TABLE_
+ *got is _DYNAMIC
+ pc[2]*4 is l_addr + _DYNAMIC - (long)pc - 8
+ pc[3]*4 is l_addr + _GLOBAL_OFFSET_TABLE_ - (long)pc - 12 */
+ return (Elf64_Addr) got - *got + (Elf32_Sword) ((pc[2] - pc[3]) * 4) - 4;
+}
+
+/* We have 4 cases to handle. And we code different code sequences
+ for each one. I love V9 code models... */
+static inline void __attribute__ ((always_inline))
+sparc64_fixup_plt (struct link_map *map, const Elf64_Rela *reloc,
+ Elf64_Addr *reloc_addr, Elf64_Addr value,
+ Elf64_Addr high, int t)
+{
+ unsigned int *insns = (unsigned int *) reloc_addr;
+ Elf64_Addr plt_vaddr = (Elf64_Addr) reloc_addr;
+ Elf64_Sxword disp = value - plt_vaddr;
+
+ /* Now move plt_vaddr up to the call instruction. */
+ plt_vaddr += ((t + 1) * 4);
+
+ /* PLT entries .PLT32768 and above look always the same. */
+ if (__builtin_expect (high, 0) != 0)
+ {
+ *reloc_addr = value - map->l_addr;
+ }
+ /* Near destination. */
+ else if (disp >= -0x800000 && disp < 0x800000)
+ {
+ /* As this is just one instruction, it is thread safe and so
+ we can avoid the unnecessary sethi FOO, %g1.
+ b,a target */
+ insns[0] = 0x30800000 | ((disp >> 2) & 0x3fffff);
+ __asm __volatile ("flush %0" : : "r" (insns));
+ }
+ /* 32-bit Sparc style, the target is in the lower 32-bits of
+ address space. */
+ else if (insns += t, (value >> 32) == 0)
+ {
+ /* sethi %hi(target), %g1
+ jmpl %g1 + %lo(target), %g0 */
+
+ insns[1] = 0x81c06000 | (value & 0x3ff);
+ __asm __volatile ("flush %0 + 4" : : "r" (insns));
+
+ insns[0] = 0x03000000 | ((unsigned int)(value >> 10));
+ __asm __volatile ("flush %0" : : "r" (insns));
+ }
+ /* We can also get somewhat simple sequences if the distance between
+ the target and the PLT entry is within +/- 2GB. */
+ else if ((plt_vaddr > value
+ && ((plt_vaddr - value) >> 31) == 0)
+ || (value > plt_vaddr
+ && ((value - plt_vaddr) >> 31) == 0))
+ {
+ unsigned int displacement;
+
+ if (plt_vaddr > value)
+ displacement = (0 - (plt_vaddr - value));
+ else
+ displacement = value - plt_vaddr;
+
+ /* mov %o7, %g1
+ call displacement
+ mov %g1, %o7 */
+
+ insns[2] = 0x9e100001;
+ __asm __volatile ("flush %0 + 8" : : "r" (insns));
+
+ insns[1] = 0x40000000 | (displacement >> 2);
+ __asm __volatile ("flush %0 + 4" : : "r" (insns));
+
+ insns[0] = 0x8210000f;
+ __asm __volatile ("flush %0" : : "r" (insns));
+ }
+ /* Worst case, ho hum... */
+ else
+ {
+ unsigned int high32 = (value >> 32);
+ unsigned int low32 = (unsigned int) value;
+
+ /* ??? Some tricks can be stolen from the sparc64 egcs backend
+ constant formation code I wrote. -DaveM */
+
+ if (__builtin_expect (high32 & 0x3ff, 0))
+ {
+ /* sethi %hh(value), %g1
+ sethi %lm(value), %g5
+ or %g1, %hm(value), %g1
+ or %g5, %lo(value), %g5
+ sllx %g1, 32, %g1
+ jmpl %g1 + %g5, %g0
+ nop */
+
+ insns[5] = 0x81c04005;
+ __asm __volatile ("flush %0 + 20" : : "r" (insns));
+
+ insns[4] = 0x83287020;
+ __asm __volatile ("flush %0 + 16" : : "r" (insns));
+
+ insns[3] = 0x8a116000 | (low32 & 0x3ff);
+ __asm __volatile ("flush %0 + 12" : : "r" (insns));
+
+ insns[2] = 0x82106000 | (high32 & 0x3ff);
+ }
+ else
+ {
+ /* sethi %hh(value), %g1
+ sethi %lm(value), %g5
+ sllx %g1, 32, %g1
+ or %g5, %lo(value), %g5
+ jmpl %g1 + %g5, %g0
+ nop */
+
+ insns[4] = 0x81c04005;
+ __asm __volatile ("flush %0 + 16" : : "r" (insns));
+
+ insns[3] = 0x8a116000 | (low32 & 0x3ff);
+ __asm __volatile ("flush %0 + 12" : : "r" (insns));
+
+ insns[2] = 0x83287020;
+ }
+
+ __asm __volatile ("flush %0 + 8" : : "r" (insns));
+
+ insns[1] = 0x0b000000 | (low32 >> 10);
+ __asm __volatile ("flush %0 + 4" : : "r" (insns));
+
+ insns[0] = 0x03000000 | (high32 >> 10);
+ __asm __volatile ("flush %0" : : "r" (insns));
+ }
+}
+
+static inline Elf64_Addr __attribute__ ((always_inline))
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf64_Rela *reloc,
+ Elf64_Addr *reloc_addr, Elf64_Addr value)
+{
+ sparc64_fixup_plt (map, reloc, reloc_addr, value + reloc->r_addend,
+ reloc->r_addend, 1);
+ return value;
+}
+
+/* Return the final value of a plt relocation. */
+static inline Elf64_Addr
+elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
+ Elf64_Addr value)
+{
+ /* Don't add addend here, but in elf_machine_fixup_plt instead.
+ value + reloc->r_addend is the value which should actually be
+ stored into .plt data slot. */
+ return value;
+}
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
+ PLT entries should not be allowed to define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+# define elf_machine_type_class(type) \
+ ((((type) == R_SPARC_JMP_SLOT \
+ || ((type) >= R_SPARC_TLS_GD_HI22 && (type) <= R_SPARC_TLS_TPOFF64)) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+# define elf_machine_type_class(type) \
+ ((((type) == R_SPARC_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_SPARC_JMP_SLOT
+
+/* The SPARC never uses Elf64_Rel relocations. */
+#define ELF_MACHINE_NO_REL 1
+
+/* The SPARC overlaps DT_RELA and DT_PLTREL. */
+#define ELF_MACHINE_PLTREL_OVERLAP 1
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int
+elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+{
+ if (l->l_info[DT_JMPREL] && lazy)
+ {
+ extern void _dl_runtime_resolve_0 (void);
+ extern void _dl_runtime_resolve_1 (void);
+ extern void _dl_runtime_profile_0 (void);
+ extern void _dl_runtime_profile_1 (void);
+ Elf64_Addr res0_addr, res1_addr;
+ unsigned int *plt = (void *) D_PTR (l, l_info[DT_PLTGOT]);
+
+ if (__builtin_expect(profile, 0))
+ {
+ res0_addr = (Elf64_Addr) &_dl_runtime_profile_0;
+ res1_addr = (Elf64_Addr) &_dl_runtime_profile_1;
+
+ if (GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), l))
+ GL(dl_profile_map) = l;
+ }
+ else
+ {
+ res0_addr = (Elf64_Addr) &_dl_runtime_resolve_0;
+ res1_addr = (Elf64_Addr) &_dl_runtime_resolve_1;
+ }
+
+ /* PLT0 looks like:
+
+ sethi %uhi(_dl_runtime_{resolve,profile}_0), %g4
+ sethi %hi(_dl_runtime_{resolve,profile}_0), %g5
+ or %g4, %ulo(_dl_runtime_{resolve,profile}_0), %g4
+ or %g5, %lo(_dl_runtime_{resolve,profile}_0), %g5
+ sllx %g4, 32, %g4
+ add %g4, %g5, %g5
+ jmpl %g5, %g4
+ nop
+ */
+
+ plt[0] = 0x09000000 | (res0_addr >> (64 - 22));
+ plt[1] = 0x0b000000 | ((res0_addr >> 10) & 0x003fffff);
+ plt[2] = 0x88112000 | ((res0_addr >> 32) & 0x3ff);
+ plt[3] = 0x8a116000 | (res0_addr & 0x3ff);
+ plt[4] = 0x89293020;
+ plt[5] = 0x8a010005;
+ plt[6] = 0x89c14000;
+ plt[7] = 0x01000000;
+
+ /* PLT1 looks like:
+
+ sethi %uhi(_dl_runtime_{resolve,profile}_1), %g4
+ sethi %hi(_dl_runtime_{resolve,profile}_1), %g5
+ or %g4, %ulo(_dl_runtime_{resolve,profile}_1), %g4
+ or %g5, %lo(_dl_runtime_{resolve,profile}_1), %g5
+ sllx %g4, 32, %g4
+ add %g4, %g5, %g5
+ jmpl %g5, %g4
+ nop
+ */
+
+ plt[8] = 0x09000000 | (res1_addr >> (64 - 22));
+ plt[9] = 0x0b000000 | ((res1_addr >> 10) & 0x003fffff);
+ plt[10] = 0x88112000 | ((res1_addr >> 32) & 0x3ff);
+ plt[11] = 0x8a116000 | (res1_addr & 0x3ff);
+ plt[12] = 0x89293020;
+ plt[13] = 0x8a010005;
+ plt[14] = 0x89c14000;
+ plt[15] = 0x01000000;
+
+ /* Now put the magic cookie at the beginning of .PLT2
+ Entry .PLT3 is unused by this implementation. */
+ *((struct link_map **)(&plt[16])) = l;
+
+ if (__builtin_expect (l->l_info[VALIDX(DT_GNU_PRELINKED)] != NULL, 0)
+ || __builtin_expect (l->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL, 0))
+ {
+ /* Need to reinitialize .plt to undo prelinking. */
+ Elf64_Rela *rela = (Elf64_Rela *) D_PTR (l, l_info[DT_JMPREL]);
+ Elf64_Rela *relaend
+ = (Elf64_Rela *) ((char *) rela
+ + l->l_info[DT_PLTRELSZ]->d_un.d_val);
+
+ /* prelink must ensure there are no R_SPARC_NONE relocs left
+ in .rela.plt. */
+ while (rela < relaend)
+ {
+ if (__builtin_expect (rela->r_addend, 0) != 0)
+ {
+ Elf64_Addr slot = ((rela->r_offset + 0x400
+ - (Elf64_Addr) plt)
+ / 0x1400) * 0x1400
+ + (Elf64_Addr) plt - 0x400;
+ /* ldx [%o7 + X], %g1 */
+ unsigned int first_ldx = *(unsigned int *)(slot + 12);
+ Elf64_Addr ptr = slot + (first_ldx & 0xfff) + 4;
+
+ *(Elf64_Addr *) rela->r_offset
+ = (Elf64_Addr) plt
+ - (slot + ((rela->r_offset - ptr) / 8) * 24 + 4);
+ ++rela;
+ continue;
+ }
+
+ *(unsigned int *) rela->r_offset
+ = 0x03000000 | (rela->r_offset - (Elf64_Addr) plt);
+ *(unsigned int *) (rela->r_offset + 4)
+ = 0x30680000 | ((((Elf64_Addr) plt + 32
+ - rela->r_offset - 4) >> 2) & 0x7ffff);
+ __asm __volatile ("flush %0" : : "r" (rela->r_offset));
+ __asm __volatile ("flush %0+4" : : "r" (rela->r_offset));
+ ++rela;
+ }
+ }
+ }
+
+ return lazy;
+}
+
+/* The PLT uses Elf64_Rela relocs. */
+#define elf_machine_relplt elf_machine_rela
+
+/* Undo the sub %sp, 6*8, %sp; add %sp, STACK_BIAS + 22*8, %o0 below
+ to get at the value we want in __libc_stack_end. */
+#define DL_STACK_END(cookie) \
+ ((void *) (((long) (cookie)) - (22 - 6) * 8 - STACK_BIAS))
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+
+#define __S1(x) #x
+#define __S(x) __S1(x)
+
+#define RTLD_START __asm__ ( "\n" \
+" .text\n" \
+" .global _start\n" \
+" .type _start, @function\n" \
+" .align 32\n" \
+"_start:\n" \
+" /* Make room for functions to drop their arguments on the stack. */\n" \
+" sub %sp, 6*8, %sp\n" \
+" /* Pass pointer to argument block to _dl_start. */\n" \
+" call _dl_start\n" \
+" add %sp," __S(STACK_BIAS) "+22*8,%o0\n" \
+" /* FALLTHRU */\n" \
+" .size _start, .-_start\n" \
+"\n" \
+" .global _dl_start_user\n" \
+" .type _dl_start_user, @function\n" \
+"_dl_start_user:\n" \
+" /* Load the GOT register. */\n" \
+"1: call 11f\n" \
+" sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n" \
+"11: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n" \
+" sethi %hi(_dl_skip_args), %g5\n" \
+" add %l7, %o7, %l7\n" \
+" or %g5, %lo(_dl_skip_args), %g5\n" \
+" /* Save the user entry point address in %l0. */\n" \
+" mov %o0, %l0\n" \
+" /* See if we were run as a command with the executable file name as an\n" \
+" extra leading argument. If so, we must shift things around since we\n" \
+" must keep the stack doubleword aligned. */\n" \
+" ldx [%l7 + %g5], %i0\n" \
+" ld [%i0], %i0\n" \
+" brz,pt %i0, 2f\n" \
+" ldx [%sp + " __S(STACK_BIAS) " + 22*8], %i5\n" \
+" /* Find out how far to shift. */\n" \
+" sethi %hi(_dl_argv), %l4\n" \
+" sub %i5, %i0, %i5\n" \
+" or %l4, %lo(_dl_argv), %l4\n" \
+" sllx %i0, 3, %l6\n" \
+" ldx [%l7 + %l4], %l4\n" \
+" stx %i5, [%sp + " __S(STACK_BIAS) " + 22*8]\n" \
+" add %sp, " __S(STACK_BIAS) " + 23*8, %i1\n" \
+" add %i1, %l6, %i2\n" \
+" ldx [%l4], %l5\n" \
+" /* Copy down argv. */\n" \
+"12: ldx [%i2], %i3\n" \
+" add %i2, 8, %i2\n" \
+" stx %i3, [%i1]\n" \
+" brnz,pt %i3, 12b\n" \
+" add %i1, 8, %i1\n" \
+" sub %l5, %l6, %l5\n" \
+" /* Copy down envp. */\n" \
+"13: ldx [%i2], %i3\n" \
+" add %i2, 8, %i2\n" \
+" stx %i3, [%i1]\n" \
+" brnz,pt %i3, 13b\n" \
+" add %i1, 8, %i1\n" \
+" /* Copy down auxiliary table. */\n" \
+"14: ldx [%i2], %i3\n" \
+" ldx [%i2 + 8], %i4\n" \
+" add %i2, 16, %i2\n" \
+" stx %i3, [%i1]\n" \
+" stx %i4, [%i1 + 8]\n" \
+" brnz,pt %i3, 14b\n" \
+" add %i1, 16, %i1\n" \
+" stx %l5, [%l4]\n" \
+" /* %o0 = _dl_loaded, %o1 = argc, %o2 = argv, %o3 = envp. */\n" \
+"2: sethi %hi(_rtld_local), %o0\n" \
+" add %sp, " __S(STACK_BIAS) " + 23*8, %o2\n" \
+" orcc %o0, %lo(_rtld_local), %o0\n" \
+" sllx %i5, 3, %o3\n" \
+" ldx [%l7 + %o0], %o0\n" \
+" add %o3, 8, %o3\n" \
+" mov %i5, %o1\n" \
+" add %o2, %o3, %o3\n" \
+" call _dl_init_internal\n" \
+" ldx [%o0], %o0\n" \
+" /* Pass our finalizer function to the user in %g1. */\n" \
+" sethi %hi(_dl_fini), %g1\n" \
+" or %g1, %lo(_dl_fini), %g1\n" \
+" ldx [%l7 + %g1], %g1\n" \
+" /* Jump to the user's entry point and deallocate the extra stack we got. */\n" \
+" jmp %l0\n" \
+" add %sp, 6*8, %sp\n" \
+" .size _dl_start_user, . - _dl_start_user\n" \
+" .previous\n");
+
+#endif /* dl_machine_h */
+
+#define ARCH_LA_PLTENTER sparc64_gnu_pltenter
+#define ARCH_LA_PLTEXIT sparc64_gnu_pltexit
+
+#ifdef RESOLVE_MAP
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ MAP is the object containing the reloc. */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
+ const Elf64_Sym *sym, const struct r_found_version *version,
+ void *const reloc_addr_arg)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
+ const Elf64_Sym *const refsym = sym;
+#endif
+ Elf64_Addr value;
+ const unsigned long int r_type = ELF64_R_TYPE_ID (reloc->r_info);
+#if !defined RESOLVE_CONFLICT_FIND_MAP
+ struct link_map *sym_map = NULL;
+#endif
+
+#if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ /* This is defined in rtld.c, but nowhere in the static libc.a; make the
+ reference weak so static programs can still link. This declaration
+ cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
+ because rtld.c contains the common defn for _dl_rtld_map, which is
+ incompatible with a weak decl in the same file. */
+ weak_extern (_dl_rtld_map);
+#endif
+
+ if (__builtin_expect (r_type == R_SPARC_NONE, 0))
+ return;
+
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+ if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0))
+ {
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ if (map != &_dl_rtld_map) /* Already done in rtld itself. */
+# endif
+ *reloc_addr += map->l_addr + reloc->r_addend;
+ return;
+ }
+#endif
+
+#ifndef RESOLVE_CONFLICT_FIND_MAP
+ if (__builtin_expect (ELF64_ST_BIND (sym->st_info) == STB_LOCAL, 0)
+ && sym->st_shndx != SHN_UNDEF)
+ {
+ value = map->l_addr;
+ }
+ else
+ {
+ sym_map = RESOLVE_MAP (&sym, version, r_type);
+ value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+ }
+#else
+ value = 0;
+#endif
+
+ value += reloc->r_addend; /* Assume copy relocs have zero addend. */
+
+ switch (r_type)
+ {
+#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
+ case R_SPARC_COPY:
+ if (sym == NULL)
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
+ if (sym->st_size > refsym->st_size
+ || (GLRO(dl_verbose) && sym->st_size < refsym->st_size))
+ {
+ const char *strtab;
+
+ strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+ _dl_error_printf ("\
+%s: Symbol `%s' has different size in shared object, consider re-linking\n",
+ rtld_progname ?: "<program name unknown>",
+ strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr_arg, (void *) value,
+ MIN (sym->st_size, refsym->st_size));
+ break;
+#endif
+ case R_SPARC_64:
+ case R_SPARC_GLOB_DAT:
+ *reloc_addr = value;
+ break;
+ case R_SPARC_JMP_SLOT:
+#ifdef RESOLVE_CONFLICT_FIND_MAP
+ /* R_SPARC_JMP_SLOT conflicts against .plt[32768+]
+ relocs should be turned into R_SPARC_64 relocs
+ in .gnu.conflict section.
+ r_addend non-zero does not mean it is a .plt[32768+]
+ reloc, instead it is the actual address of the function
+ to call. */
+ sparc64_fixup_plt (NULL, reloc, reloc_addr, value, 0, 0);
+#else
+ sparc64_fixup_plt (map, reloc, reloc_addr, value, reloc->r_addend, 0);
+#endif
+ break;
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+ && !defined RESOLVE_CONFLICT_FIND_MAP
+ case R_SPARC_TLS_DTPMOD64:
+ /* Get the information from the link map returned by the
+ resolv function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+ break;
+ case R_SPARC_TLS_DTPOFF64:
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
+ break;
+ case R_SPARC_TLS_TPOFF64:
+ /* The offset is negative, forward from the thread pointer. */
+ /* We know the offset of object the symbol is contained in.
+ It is a negative value which will be added to the
+ thread pointer. */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = sym->st_value - sym_map->l_tls_offset
+ + reloc->r_addend;
+ }
+ break;
+# ifndef RTLD_BOOTSTRAP
+ case R_SPARC_TLS_LE_HIX22:
+ case R_SPARC_TLS_LE_LOX10:
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ value = sym->st_value - sym_map->l_tls_offset
+ + reloc->r_addend;
+ if (r_type == R_SPARC_TLS_LE_HIX22)
+ *reloc_addr = (*reloc_addr & 0xffc00000) | ((~value) >> 10);
+ else
+ *reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff)
+ | 0x1c00;
+ }
+ break;
+# endif
+#endif
+#ifndef RTLD_BOOTSTRAP
+ case R_SPARC_8:
+ *(char *) reloc_addr = value;
+ break;
+ case R_SPARC_16:
+ *(short *) reloc_addr = value;
+ break;
+ case R_SPARC_32:
+ *(unsigned int *) reloc_addr = value;
+ break;
+ case R_SPARC_DISP8:
+ *(char *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
+ break;
+ case R_SPARC_DISP16:
+ *(short *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
+ break;
+ case R_SPARC_DISP32:
+ *(unsigned int *) reloc_addr = (value - (Elf64_Addr) reloc_addr);
+ break;
+ case R_SPARC_WDISP30:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & 0xc0000000) |
+ ((value - (Elf64_Addr) reloc_addr) >> 2));
+ break;
+
+ /* MEDLOW code model relocs */
+ case R_SPARC_LO10:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & ~0x3ff) |
+ (value & 0x3ff));
+ break;
+ case R_SPARC_HI22:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & 0xffc00000) |
+ (value >> 10));
+ break;
+ case R_SPARC_OLO10:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & ~0x1fff) |
+ (((value & 0x3ff) + ELF64_R_TYPE_DATA (reloc->r_info)) & 0x1fff));
+ break;
+
+ /* MEDMID code model relocs */
+ case R_SPARC_H44:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & 0xffc00000) |
+ (value >> 22));
+ break;
+ case R_SPARC_M44:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & ~0x3ff) |
+ ((value >> 12) & 0x3ff));
+ break;
+ case R_SPARC_L44:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & ~0xfff) |
+ (value & 0xfff));
+ break;
+
+ /* MEDANY code model relocs */
+ case R_SPARC_HH22:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & 0xffc00000) |
+ (value >> 42));
+ break;
+ case R_SPARC_HM10:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & ~0x3ff) |
+ ((value >> 32) & 0x3ff));
+ break;
+ case R_SPARC_LM22:
+ *(unsigned int *) reloc_addr =
+ ((*(unsigned int *)reloc_addr & 0xffc00000) |
+ ((value >> 10) & 0x003fffff));
+ break;
+ case R_SPARC_UA16:
+ ((unsigned char *) reloc_addr_arg) [0] = value >> 8;
+ ((unsigned char *) reloc_addr_arg) [1] = value;
+ break;
+ case R_SPARC_UA32:
+ ((unsigned char *) reloc_addr_arg) [0] = value >> 24;
+ ((unsigned char *) reloc_addr_arg) [1] = value >> 16;
+ ((unsigned char *) reloc_addr_arg) [2] = value >> 8;
+ ((unsigned char *) reloc_addr_arg) [3] = value;
+ break;
+ case R_SPARC_UA64:
+ if (! ((long) reloc_addr_arg & 3))
+ {
+ /* Common in .eh_frame */
+ ((unsigned int *) reloc_addr_arg) [0] = value >> 32;
+ ((unsigned int *) reloc_addr_arg) [1] = value;
+ break;
+ }
+ ((unsigned char *) reloc_addr_arg) [0] = value >> 56;
+ ((unsigned char *) reloc_addr_arg) [1] = value >> 48;
+ ((unsigned char *) reloc_addr_arg) [2] = value >> 40;
+ ((unsigned char *) reloc_addr_arg) [3] = value >> 32;
+ ((unsigned char *) reloc_addr_arg) [4] = value >> 24;
+ ((unsigned char *) reloc_addr_arg) [5] = value >> 16;
+ ((unsigned char *) reloc_addr_arg) [6] = value >> 8;
+ ((unsigned char *) reloc_addr_arg) [7] = value;
+ break;
+#endif
+#if !defined RTLD_BOOTSTRAP || defined _NDEBUG
+ default:
+ _dl_reloc_bad_type (map, r_type, 0);
+ break;
+#endif
+ }
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+ *reloc_addr = l_addr + reloc->r_addend;
+}
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf64_Addr l_addr, const Elf64_Rela *reloc)
+{
+ switch (ELF64_R_TYPE (reloc->r_info))
+ {
+ case R_SPARC_NONE:
+ break;
+ case R_SPARC_JMP_SLOT:
+ break;
+ default:
+ _dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 1);
+ break;
+ }
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/libc/sysdeps/sparc/sparc64/dl-trampoline.S b/libc/sysdeps/sparc/sparc64/dl-trampoline.S
new file mode 100644
index 000000000..81e5c556c
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/dl-trampoline.S
@@ -0,0 +1,327 @@
+/* PLT trampolines. Sparc 64-bit version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ .align 32
+
+ /* %g1: PLT offset loaded by PLT entry
+ * %g4: callers PC, which is PLT0 + 24, therefore we
+ * add (32 + 8) to get the address of PLT2 which
+ * is where the magic cookie is stored
+ */
+ .globl _dl_runtime_resolve_0
+ .type _dl_runtime_resolve_0, @function
+_dl_runtime_resolve_0:
+ cfi_startproc
+
+ save %sp, -192, %sp
+ cfi_def_cfa_register(%fp)
+ cfi_window_save
+ cfi_register(%o7, %i7)
+
+ sethi %hi(1047552), %l2
+ ldx [%g4 + 32 + 8], %o0
+ sub %g1, %g4, %l0
+ xor %l2, -1016, %l2
+ sethi %hi(5120), %l3 /* 160 * 32 */
+ add %l0, %l2, %l0
+ sethi %hi(32768), %l4
+ udivx %l0, %l3, %l3
+ sllx %l3, 2, %l1
+ add %l1, %l3, %l1
+ sllx %l1, 10, %l2
+ sub %l4, 4, %l4
+ sllx %l1, 5, %l1
+ sub %l0, %l2, %l0
+ udivx %l0, 24, %l0
+ add %l0, %l4, %l0
+ add %l1, %l0, %l1
+ add %l1, %l1, %l0
+ add %l0, %l1, %l0
+ call _dl_fixup
+ sllx %l0, 3, %o1
+ jmp %o0
+ restore
+
+ cfi_endproc
+
+ .size _dl_runtime_resolve_0, .-_dl_runtime_resolve_0
+
+ /* %g1: PLT offset loaded by PLT entry
+ * %g4: callers PC, which is PLT1 + 24, therefore we
+ * add 8 to get the address of PLT2 which
+ * is where the magic cookie is stored
+ */
+ .globl _dl_runtime_resolve_1
+ .type _dl_runtime_resolve_1, @function
+_dl_runtime_resolve_1:
+ cfi_startproc
+
+ save %sp, -192, %sp
+ cfi_def_cfa_register(%fp)
+ cfi_window_save
+ cfi_register(%o7, %i7)
+
+ srlx %g1, 12, %o1
+ ldx [%g4 + 8], %o0
+ add %o1, %o1, %o3
+ sub %o1, 96, %o1
+ call _dl_fixup
+ add %o1, %o3, %o1
+ jmp %o0
+ restore
+
+ cfi_endproc
+
+ .size _dl_runtime_resolve_1, .-_dl_runtime_resolve_1
+
+ /* For the profiling cases we pass in our stack frame
+ * as the base of the La_sparc64_regs, so it looks
+ * like:
+ * %l0 %sp
+ * ...
+ * %l7 %sp + (7 * 8)
+ * %i0 %sp + (8 * 8)
+ * ...
+ * %i7 %sp + (15 * 8)
+ * %f0 %sp + (16 * 8)
+ * %f16 %sp + (31 * 8)
+ * framesize %sp + (32 * 8)
+ */
+
+ .globl _dl_profile_save_regs
+ .type _dl_profile_save_regs, @function
+_dl_profile_save_regs:
+ cfi_startproc
+
+ stx %l0, [%sp + STACK_BIAS + ( 0 * 8)]
+ stx %l1, [%sp + STACK_BIAS + ( 1 * 8)]
+ stx %l2, [%sp + STACK_BIAS + ( 2 * 8)]
+ stx %l3, [%sp + STACK_BIAS + ( 3 * 8)]
+ stx %l4, [%sp + STACK_BIAS + ( 4 * 8)]
+ stx %l5, [%sp + STACK_BIAS + ( 5 * 8)]
+ stx %l6, [%sp + STACK_BIAS + ( 6 * 8)]
+ stx %l7, [%sp + STACK_BIAS + ( 7 * 8)]
+ stx %i0, [%sp + STACK_BIAS + ( 8 * 8)]
+ stx %i1, [%sp + STACK_BIAS + ( 9 * 8)]
+ stx %i2, [%sp + STACK_BIAS + (10 * 8)]
+ stx %i3, [%sp + STACK_BIAS + (11 * 8)]
+ stx %i4, [%sp + STACK_BIAS + (12 * 8)]
+ stx %i5, [%sp + STACK_BIAS + (13 * 8)]
+ stx %i6, [%sp + STACK_BIAS + (14 * 8)]
+ stx %i7, [%sp + STACK_BIAS + (15 * 8)]
+ std %f0, [%sp + STACK_BIAS + (16 * 8)]
+ std %f2, [%sp + STACK_BIAS + (17 * 8)]
+ std %f4, [%sp + STACK_BIAS + (18 * 8)]
+ std %f6, [%sp + STACK_BIAS + (19 * 8)]
+ std %f8, [%sp + STACK_BIAS + (20 * 8)]
+ std %f10, [%sp + STACK_BIAS + (21 * 8)]
+ std %f12, [%sp + STACK_BIAS + (22 * 8)]
+ std %f14, [%sp + STACK_BIAS + (23 * 8)]
+ std %f16, [%sp + STACK_BIAS + (24 * 8)]
+ std %f18, [%sp + STACK_BIAS + (25 * 8)]
+ std %f20, [%sp + STACK_BIAS + (26 * 8)]
+ std %f22, [%sp + STACK_BIAS + (27 * 8)]
+ std %f24, [%sp + STACK_BIAS + (28 * 8)]
+ std %f26, [%sp + STACK_BIAS + (29 * 8)]
+ std %f28, [%sp + STACK_BIAS + (30 * 8)]
+ retl
+ std %f30, [%sp + STACK_BIAS + (31 * 8)]
+
+ cfi_endproc
+
+ .size _dl_profile_save_regs, .-_dl_profile_save_regs
+
+ /* If we are going to call pltexit, then we must replicate
+ * the caller's stack frame.
+ * %o0: PLT resolved function address
+ */
+ .globl _dl_profile_invoke
+ .type _dl_profile_invoke, @function
+_dl_profile_invoke:
+ cfi_startproc
+
+ sub %sp, %l0, %sp
+1:
+ srlx %l0, 3, %l7
+ mov %o0, %l1
+ mov %i0, %o0
+ mov %i1, %o1
+ mov %i2, %o2
+ mov %i3, %o3
+ mov %i4, %o4
+ mov %i5, %o5
+ add %fp, STACK_BIAS, %l2
+ add %sp, STACK_BIAS, %l3
+1: ldx [%l2], %l4
+ add %l2, 0x8, %l2
+ subcc %l7, 1, %l7
+ stx %l4, [%l3]
+ bne,pt %xcc, 1b
+ add %l3, 0x8, %l3
+
+ jmpl %l1, %o7
+ nop
+
+ stx %o0, [%sp + STACK_BIAS + (16 * 8)]
+ stx %o1, [%sp + STACK_BIAS + (17 * 8)]
+ stx %o2, [%sp + STACK_BIAS + (18 * 8)]
+ stx %o3, [%sp + STACK_BIAS + (19 * 8)]
+ std %f0, [%sp + STACK_BIAS + (20 * 8)]
+ std %f2, [%sp + STACK_BIAS + (21 * 8)]
+ std %f4, [%sp + STACK_BIAS + (22 * 8)]
+ std %f8, [%sp + STACK_BIAS + (23 * 8)]
+
+ mov %l5, %o0
+ mov %l6, %o1
+ add %sp, %l0, %o2
+ add %sp, STACK_BIAS + (16 * 8), %o3
+ call _dl_call_pltexit
+ add %o2, STACK_BIAS, %o2
+
+ ldx [%sp + STACK_BIAS + (16 * 8)], %i0
+ ldx [%sp + STACK_BIAS + (17 * 8)], %i1
+ ldx [%sp + STACK_BIAS + (18 * 8)], %i2
+ ldx [%sp + STACK_BIAS + (19 * 8)], %i3
+
+ jmpl %i7 + 8, %g0
+ restore
+
+ cfi_endproc
+
+ .size _dl_profile_invoke, .-_dl_profile_invoke
+
+ /* %g1: PLT offset loaded by PLT entry
+ * %g4: callers PC, which is PLT0 + 24, therefore we
+ * add (32 + 8) to get the address of PLT2 which
+ * is where the magic cookie is stored
+ */
+ .align 32
+ .globl _dl_runtime_profile_0
+ .type _dl_runtime_profile_0, @function
+_dl_runtime_profile_0:
+ cfi_startproc
+
+ brz,a,pn %fp, 1f
+ mov 192, %g5
+ sub %fp, %sp, %g5
+1: save %sp, -336, %sp
+ cfi_def_cfa_register(%fp)
+ cfi_window_save
+ cfi_register(%o7, %i7)
+
+ sethi %hi(1047552), %l2
+ ldx [%g4 + 32 + 8], %o0
+ sub %g1, %g4, %l0
+ xor %l2, -1016, %l2
+ sethi %hi(5120), %l3 /* 160 * 32 */
+ add %l0, %l2, %l0
+ sethi %hi(32768), %l4
+ udivx %l0, %l3, %l3
+ sllx %l3, 2, %l1
+ add %l1, %l3, %l1
+ sllx %l1, 10, %l2
+ sub %l4, 4, %l4
+ sllx %l1, 5, %l1
+ sub %l0, %l2, %l0
+ udivx %l0, 24, %l0
+ add %l0, %l4, %l0
+ add %l1, %l0, %l1
+ add %l1, %l1, %l0
+ add %l0, %l1, %l0
+
+ mov %i7, %o2
+ sllx %l0, 3, %o1
+
+ mov %g5, %l0
+ mov %o0, %l5
+ mov %o1, %l6
+
+ call _dl_profile_save_regs
+ nop
+
+ add %sp, STACK_BIAS, %o3
+ call _dl_profile_fixup
+ add %sp, (STACK_BIAS + (32 * 8)), %o4
+
+ ldx [%sp + STACK_BIAS + (32 * 8)], %o1
+ brgez,pt %o1, 1f
+ nop
+
+ call _dl_profile_invoke
+ nop
+
+1: jmp %o0
+ restore
+
+ cfi_endproc
+
+ .size _dl_runtime_profile_0, .-_dl_runtime_profile_0
+
+ /* %g1: PLT offset loaded by PLT entry
+ * %g4: callers PC, which is PLT1 + 24, therefore we
+ * add 8 to get the address of PLT2 which
+ * is where the magic cookie is stored
+ */
+ .globl _dl_runtime_profile_1
+ .type _dl_runtime_profile_1, @function
+_dl_runtime_profile_1:
+ cfi_startproc
+
+ brz,a,pn %fp, 1f
+ mov 192, %g5
+ sub %fp, %sp, %g5
+1: save %sp, -336, %sp
+ cfi_def_cfa_register(%fp)
+ cfi_window_save
+ cfi_register(%o7, %i7)
+
+ srlx %g1, 12, %o1
+ ldx [%g4 + 8], %o0
+ add %o1, %o1, %o3
+ sub %o1, 96, %o1
+ mov %i7, %o2
+ add %o1, %o3, %o1
+
+ mov %g5, %l0
+ mov %o0, %l5
+ mov %o1, %l6
+
+ call _dl_profile_save_regs
+ nop
+
+ add %sp, STACK_BIAS, %o3
+ call _dl_profile_fixup
+ add %sp, (STACK_BIAS + (32 * 8)), %o4
+
+ ldx [%sp + STACK_BIAS + (32 * 8)], %o1
+ brgez,pt %o1, 1f
+ nop
+
+ call _dl_profile_invoke
+ nop
+
+1: jmp %o0
+ restore
+
+ cfi_endproc
+
+ .size _dl_runtime_resolve_1, .-_dl_runtime_resolve_1
diff --git a/libc/sysdeps/sparc/sparc64/elf/Makefile b/libc/sysdeps/sparc/sparc64/elf/Makefile
new file mode 100644
index 000000000..a995e6cdf
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/elf/Makefile
@@ -0,0 +1,4 @@
+# Sparc/ELF specific definitions.
+
+# The assembler on SPARC needs the -fPIC flag even when it's assembler code.
+ASFLAGS-.os = -fPIC
diff --git a/libc/sysdeps/sparc/sparc64/elf/configure b/libc/sysdeps/sparc/sparc64/elf/configure
new file mode 100644
index 000000000..46181524c
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/elf/configure
@@ -0,0 +1,90 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/sparc/sparc64/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and linker.
+echo "$as_me:$LINENO: checking for sparc64 TLS support" >&5
+echo $ECHO_N "checking for sparc64 TLS support... $ECHO_C" >&6
+if test "${libc_cv_sparc64_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<\EOF
+ .section ".tdata", "awT", @progbits
+ .globl foo
+foo: .word 1
+ .section ".tbss", "awT", @nobits
+ .globl bar
+bar: .skip 4
+ .text
+ .globl main
+main: sethi %tgd_hi22(foo), %l1
+ add %l1, %tgd_lo10(foo), %l1
+ add %l7, %l1, %o0, %tgd_add(foo)
+ call __tls_get_addr, %tgd_call(foo)
+ sethi %tldm_hi22(bar), %l1
+ add %l1, %tldm_lo10(bar), %l1
+ add %l7, %l1, %o0, %tldm_add(bar)
+ call __tls_get_addr, %tldm_call(bar)
+ sethi %tldo_hix22(bar), %l1
+ xor %l1, %tldo_lox10(bar), %l1
+ add %o0, %l1, %l1, %tldo_add(bar)
+ sethi %tie_hi22(foo), %l1
+ add %l1, %tie_lo10(foo), %l1
+ ldx [%l7 + %l1], %l1, %tie_ldx(foo)
+ add %g7, %l1, %l1, %tie_add(foo)
+ sethi %tle_hix22(foo), %l1
+ xor %l1, %tle_lox10(foo), %l1
+EOF
+if { ac_try='${CC-cc} -o conftest.bin $CFLAGS conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_sparc64_tls=yes
+else
+ libc_cv_sparc64_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_sparc64_tls" >&5
+echo "${ECHO_T}$libc_cv_sparc64_tls" >&6
+if test $libc_cv_sparc64_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+# Check for broken WDISP22 in the linker.
+echo "$as_me:$LINENO: checking for sparc64 ld WDISP22 handling" >&5
+echo $ECHO_N "checking for sparc64 ld WDISP22 handling... $ECHO_C" >&6
+if test "${libc_cv_sparc64_wdisp22+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ echo 'bne foo; nop' > conftest1.s
+echo '.globl foo; .hidden foo; foo: nop' > conftest2.s
+libc_cv_sparc64_wdisp22=unknown
+if { ac_try='${CC-cc} -nostdlib -shared $CFLAGS conftest1.s conftest2.s -o conftest.so 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if readelf -r conftest.so | grep -q R_SPARC_WDISP22; then
+ libc_cv_sparc64_wdisp22=broken
+ else
+ libc_cv_sparc64_wdisp22=ok
+ fi
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_sparc64_wdisp22" >&5
+echo "${ECHO_T}$libc_cv_sparc64_wdisp22" >&6
+if test $libc_cv_sparc64_wdisp22 != ok; then
+ cat >>confdefs.h <<\_ACEOF
+#define BROKEN_SPARC_WDISP22 1
+_ACEOF
+
+fi
diff --git a/libc/sysdeps/sparc/sparc64/elf/configure.in b/libc/sysdeps/sparc/sparc64/elf/configure.in
new file mode 100644
index 000000000..fd7e34e90
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/elf/configure.in
@@ -0,0 +1,63 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/sparc/sparc64/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and linker.
+AC_CACHE_CHECK(for sparc64 TLS support, libc_cv_sparc64_tls, [dnl
+changequote(,)dnl
+cat > conftest.s <<\EOF
+ .section ".tdata", "awT", @progbits
+ .globl foo
+foo: .word 1
+ .section ".tbss", "awT", @nobits
+ .globl bar
+bar: .skip 4
+ .text
+ .globl main
+main: sethi %tgd_hi22(foo), %l1
+ add %l1, %tgd_lo10(foo), %l1
+ add %l7, %l1, %o0, %tgd_add(foo)
+ call __tls_get_addr, %tgd_call(foo)
+ sethi %tldm_hi22(bar), %l1
+ add %l1, %tldm_lo10(bar), %l1
+ add %l7, %l1, %o0, %tldm_add(bar)
+ call __tls_get_addr, %tldm_call(bar)
+ sethi %tldo_hix22(bar), %l1
+ xor %l1, %tldo_lox10(bar), %l1
+ add %o0, %l1, %l1, %tldo_add(bar)
+ sethi %tie_hi22(foo), %l1
+ add %l1, %tie_lo10(foo), %l1
+ ldx [%l7 + %l1], %l1, %tie_ldx(foo)
+ add %g7, %l1, %l1, %tie_add(foo)
+ sethi %tle_hix22(foo), %l1
+ xor %l1, %tle_lox10(foo), %l1
+EOF
+changequote([,])dnl
+dnl
+if AC_TRY_COMMAND(${CC-cc} -o conftest.bin $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_sparc64_tls=yes
+else
+ libc_cv_sparc64_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_sparc64_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
+# Check for broken WDISP22 in the linker.
+AC_CACHE_CHECK(for sparc64 ld WDISP22 handling, libc_cv_sparc64_wdisp22, [dnl
+echo 'bne foo; nop' > conftest1.s
+echo '.globl foo; .hidden foo; foo: nop' > conftest2.s
+libc_cv_sparc64_wdisp22=unknown
+if AC_TRY_COMMAND(${CC-cc} -nostdlib -shared $CFLAGS conftest1.s conftest2.s -o conftest.so 1>&AS_MESSAGE_LOG_FD); then
+ if readelf -r conftest.so | grep -q R_SPARC_WDISP22; then
+ libc_cv_sparc64_wdisp22=broken
+ else
+ libc_cv_sparc64_wdisp22=ok
+ fi
+fi
+rm -f conftest*])
+if test $libc_cv_sparc64_wdisp22 != ok; then
+ AC_DEFINE(BROKEN_SPARC_WDISP22)
+fi
diff --git a/libc/sysdeps/sparc/sparc64/elf/start.S b/libc/sysdeps/sparc/sparc64/elf/start.S
new file mode 100644
index 000000000..df44cae06
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/elf/start.S
@@ -0,0 +1,105 @@
+/* Startup code for elf64-sparc
+ Copyright (C) 1997, 1998, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+
+ .section ".text"
+ .align 4
+#ifdef SHARED
+.LLGETPC0:
+ retl
+ add %o7, %l7, %l7
+#endif
+ .global _start
+ .type _start,#function
+_start:
+ cfi_startproc
+
+#ifdef SHARED
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7
+ call .LLGETPC0
+ add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7
+#endif
+
+ /* Terminate the stack frame, and reserve space for functions to
+ drop their arguments. */
+ mov %g0, %fp
+ sub %sp, 6*8, %sp
+ cfi_adjust_cfa_offset(6*8)
+
+ /* Extract the arguments and environment as encoded on the stack. The
+ argument info starts after one register window (16 words) past the SP,
+ plus the bias we added, plus the magic v9 STACK_BIAS. */
+ ldx [%sp+STACK_BIAS+22*8], %o1
+ add %sp, STACK_BIAS+23*8, %o2
+
+ /* Load the addresses of the user entry points. */
+ sethi %hi(main), %o0
+ sethi %hi(__libc_csu_init), %o3
+ sethi %hi(__libc_csu_fini), %o4
+ or %o0, %lo(main), %o0
+ or %o3, %lo(__libc_csu_init), %o3
+ or %o4, %lo(__libc_csu_fini), %o4
+#ifdef SHARED
+ ldx [%l7 + %o0], %o0
+ ldx [%l7 + %o3], %o3
+ ldx [%l7 + %o4], %o4
+#endif
+
+ /* When starting a binary via the dynamic linker, %g1 contains the
+ address of the shared library termination function, which will be
+ registered with atexit(). If we are statically linked, this will
+ be NULL. */
+ mov %g1, %o5
+
+ /* Let libc do the rest of the initialization, and call main. */
+ call __libc_start_main
+ nop
+
+ /* Die very horribly if exit returns. */
+ illtrap 0
+
+ cfi_endproc
+
+ .size _start, .-_start
+
+/* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+weak_alias (__data_start, data_start)
diff --git a/libc/sysdeps/sparc/sparc64/fpu/e_sqrtl.c b/libc/sysdeps/sparc/sparc64/fpu/e_sqrtl.c
new file mode 100644
index 000000000..4c3d19a50
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/fpu/e_sqrtl.c
@@ -0,0 +1,31 @@
+/* Long double square root, sparc64 version.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+extern void _Qp_sqrt(long double *, const long double *);
+
+long double
+__ieee754_sqrtl (long double x)
+{
+ long double ret;
+ _Qp_sqrt (&ret, &x);
+ return ret;
+}
diff --git a/libc/sysdeps/sparc/sparc64/fpu/libm-test-ulps b/libc/sysdeps/sparc/sparc64/fpu/libm-test-ulps
new file mode 100644
index 000000000..db5543e9e
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/fpu/libm-test-ulps
@@ -0,0 +1,1322 @@
+# Begin of automatic generation
+
+# atan2
+Test "atan2 (-0.00756827042671106339, -.001792735857538728036) == -1.80338464113663849327153994379639112":
+float: 6
+ifloat: 6
+ildouble: 1
+ldouble: 1
+Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025":
+float: 3
+ifloat: 3
+ildouble: 1
+ldouble: 1
+Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025":
+float: 3
+ifloat: 3
+ildouble: 1
+ldouble: 1
+Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# atanh
+Test "atanh (0.75) == 0.972955074527656652552676371721589865":
+float: 1
+ifloat: 1
+
+# cacos
+Test "Imaginary part of: cacos (0.75 + 1.25 i) == 1.11752014915610270578240049553777969 - 1.13239363160530819522266333696834467 i":
+ildouble: 1
+ldouble: 1
+
+# cacosh
+Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+ildouble: 5
+ldouble: 5
+Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+# casin
+Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+ildouble: 1
+ldouble: 1
+
+# casinh
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 4
+ldouble: 4
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 2
+ldouble: 2
+Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# catan
+Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+float: 3
+ifloat: 3
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+float: 4
+ifloat: 4
+Test "Imaginary part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+ildouble: 1
+ldouble: 1
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 4
+idouble: 4
+Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+float: 4
+ifloat: 4
+Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+float: 6
+ifloat: 6
+ildouble: 1
+ldouble: 1
+
+# cbrt
+Test "cbrt (-0.001) == -0.1":
+ildouble: 1
+ldouble: 1
+Test "cbrt (-27.0) == -3.0":
+double: 1
+idouble: 1
+Test "cbrt (0.75) == 0.908560296416069829445605878163630251":
+double: 1
+idouble: 1
+Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217":
+double: 1
+idouble: 1
+
+# ccos
+Test "Real part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+float: 1
+ifloat: 1
+
+# ccosh
+Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+float: 1
+ifloat: 1
+
+# cexp
+Test "Real part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+ildouble: 1
+ldouble: 1
+
+# clog
+Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+float: 3
+ifloat: 3
+Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# cos
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "cos (pi/2) == 0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# cpow
+Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+ildouble: 4
+ldouble: 4
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i":
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 10
+ldouble: 10
+Test "Real part of: cpow (2 + 0 i, 10 + 0 i) == 1024.0 + 0.0 i":
+ildouble: 2
+ldouble: 2
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+ildouble: 3
+ldouble: 3
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 2
+ifloat: 2
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# csin
+Test "Imaginary part of: csin (-2 - 3 i) == -9.15449914691142957346729954460983256 + 4.16890695996656435075481305885375484 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
+ildouble: 1
+ldouble: 1
+
+# csinh
+Test "Real part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+
+# csqrt
+Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csqrt (0.75 + 1.25 i) == 1.05065169626078392338656675760808326 + 0.594868882070379067881984030639932657 i":
+ildouble: 1
+ldouble: 1
+
+# ctan
+Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+ifloat: 1
+Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+idouble: 1
+
+# erf
+Test "erf (1.25) == 0.922900128256458230136523481197281140":
+double: 1
+idouble: 1
+
+# erfc
+Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
+double: 1
+idouble: 1
+Test "erfc (27.0) == 0.523704892378925568501606768284954709e-318":
+ildouble: 1
+ldouble: 1
+Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8":
+double: 1
+idouble: 1
+
+# exp10
+Test "exp10 (-1) == 0.1":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "exp10 (3) == 1000":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# exp2
+Test "exp2 (10) == 1024":
+ildouble: 2
+ldouble: 2
+
+# expm1
+Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+double: 1
+idouble: 1
+Test "expm1 (1) == M_El - 1.0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# gamma
+Test "gamma (-0.5) == log(2*sqrt(pi))":
+ildouble: 1
+ldouble: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+
+# j0
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "j0 (0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# j1
+Test "j1 (-1.0) == -0.440050585744933515959682203718914913":
+ildouble: 1
+ldouble: 1
+Test "j1 (0.75) == 0.349243602174862192523281016426251335":
+ildouble: 1
+ldouble: 1
+Test "j1 (1.0) == 0.440050585744933515959682203718914913":
+ildouble: 1
+ldouble: 1
+Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+ildouble: 4
+ldouble: 4
+
+# jn
+Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (0, 0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (1, -1.0) == -0.440050585744933515959682203718914913":
+ildouble: 1
+ldouble: 1
+Test "jn (1, 0.75) == 0.349243602174862192523281016426251335":
+ildouble: 1
+ldouble: 1
+Test "jn (1, 1.0) == 0.440050585744933515959682203718914913":
+ildouble: 1
+ldouble: 1
+Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+ildouble: 4
+ldouble: 4
+Test "jn (10, -1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, 1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 2
+ldouble: 2
+Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+float: 4
+ifloat: 4
+Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# lgamma
+Test "lgamma (-0.5) == log(2*sqrt(pi))":
+ildouble: 1
+ldouble: 1
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# log10
+Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "log10 (e) == log10(e)":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# log1p
+Test "log1p (-0.25) == -0.287682072451780927439219005993827432":
+float: 1
+ifloat: 1
+Test "log1p (M_El - 1.0) == 1":
+ildouble: 1
+ldouble: 1
+
+# log2
+Test "log2 (0.75) == -.415037499278843818546261056052183492":
+ildouble: 1
+ldouble: 1
+
+# sincos
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
+float: 1
+ifloat: 1
+
+# sqrt
+Test "sqrt (2) == M_SQRT2l":
+ildouble: 1
+ldouble: 1
+
+# tan
+Test "tan (pi/4) == 1":
+double: 1
+idouble: 1
+
+# tanh
+Test "tanh (-0.75) == -0.635148952387287319214434357312496495":
+ildouble: 1
+ldouble: 1
+Test "tanh (-1.0) == -0.7615941559557648881194582826047935904":
+ildouble: 1
+ldouble: 1
+Test "tanh (0.75) == 0.635148952387287319214434357312496495":
+ildouble: 1
+ldouble: 1
+Test "tanh (1.0) == 0.7615941559557648881194582826047935904":
+ildouble: 1
+ldouble: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+ifloat: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "tgamma (4) == 6":
+ildouble: 1
+ldouble: 1
+
+# y0
+Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+# y1
+Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "y1 (0.75) == -1.03759455076928541973767132140642198":
+ildouble: 1
+ldouble: 1
+Test "y1 (1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# yn
+Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "yn (1, 0.75) == -1.03759455076928541973767132140642198":
+ildouble: 1
+ldouble: 1
+Test "yn (1, 1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "yn (1, 2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 5
+ldouble: 5
+Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+double: 2
+idouble: 2
+ildouble: 2
+ldouble: 2
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+idouble: 1
+Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+double: 1
+idouble: 1
+
+# Maximal error of functions:
+Function: "atan2":
+float: 6
+ifloat: 6
+ildouble: 1
+ldouble: 1
+
+Function: "atanh":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "cacos":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cacosh":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "casin":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "catan":
+float: 4
+ifloat: 4
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh":
+double: 4
+idouble: 4
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catanh":
+float: 6
+ifloat: 6
+ildouble: 1
+ldouble: 1
+
+Function: "cbrt":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccos":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccosh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cexp":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "cexp":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "clog":
+float: 3
+ifloat: 3
+
+Function: Real part of "clog10":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cpow":
+double: 2
+float: 4
+idouble: 2
+ifloat: 4
+ildouble: 10
+ldouble: 10
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csin":
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csin":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csinh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "csqrt":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csqrt":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ctan":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ctan":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "ctanh":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ctanh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "erf":
+double: 1
+idouble: 1
+
+Function: "erfc":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "exp10":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "exp2":
+ildouble: 2
+ldouble: 2
+
+Function: "expm1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "gamma":
+ildouble: 1
+ldouble: 1
+
+Function: "hypot":
+float: 1
+ifloat: 1
+
+Function: "j0":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: "jn":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 4
+ldouble: 4
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log10":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log1p":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log2":
+ildouble: 1
+ldouble: 1
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "sqrt":
+ildouble: 1
+ldouble: 1
+
+Function: "tan":
+double: 1
+idouble: 1
+
+Function: "tanh":
+ildouble: 1
+ldouble: 1
+
+Function: "tgamma":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+# end of automatic generation
diff --git a/libc/sysdeps/sparc/sparc64/fpu/s_fabs.c b/libc/sysdeps/sparc/sparc64/fpu/s_fabs.c
new file mode 100644
index 000000000..db5ecf216
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/fpu/s_fabs.c
@@ -0,0 +1,5 @@
+double __fabs (double x)
+{
+ return __builtin_fabs (x);
+}
+weak_alias (__fabs, fabs)
diff --git a/libc/sysdeps/sparc/sparc64/fpu/s_fabsf.c b/libc/sysdeps/sparc/sparc64/fpu/s_fabsf.c
new file mode 100644
index 000000000..8a218e494
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/fpu/s_fabsf.c
@@ -0,0 +1,5 @@
+float __fabsf (float x)
+{
+ return __builtin_fabsf (x);
+}
+weak_alias (__fabsf, fabsf)
diff --git a/libc/sysdeps/sparc/sparc64/fpu/s_fabsl.c b/libc/sysdeps/sparc/sparc64/fpu/s_fabsl.c
new file mode 100644
index 000000000..67e9f4707
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/fpu/s_fabsl.c
@@ -0,0 +1,5 @@
+long double __fabsl (long double x)
+{
+ return __builtin_fabsl (x);
+}
+weak_alias (__fabsl, fabsl)
diff --git a/libc/sysdeps/sparc/sparc64/hp-timing.c b/libc/sysdeps/sparc/sparc64/hp-timing.c
new file mode 100644
index 000000000..8f9f86b89
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/hp-timing.c
@@ -0,0 +1,24 @@
+/* Support for high precision, low overhead timing functions. sparc64 version.
+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller <davem@redhat.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hp-timing.h>
+
+/* We have to define the variable for the overhead. */
+hp_timing_t _dl_hp_timing_overhead;
diff --git a/libc/sysdeps/sparc/sparc64/hp-timing.h b/libc/sysdeps/sparc/sparc64/hp-timing.h
new file mode 100644
index 000000000..e45c6a88f
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/hp-timing.h
@@ -0,0 +1,82 @@
+/* High precision, low overhead timing functions. sparc64 version.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller <davem@redhat.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H 1
+
+#include <string.h>
+#include <sys/param.h>
+#include <stdio-common/_itoa.h>
+
+#define HP_TIMING_AVAIL (1)
+#define HP_TIMING_INLINE (1)
+
+typedef unsigned long int hp_timing_t;
+
+#define HP_TIMING_ZERO(Var) (Var) = (0)
+
+#define HP_TIMING_NOW(Var) __asm__ __volatile__ ("rd %%tick, %0" : "=r" (Var))
+
+#define HP_TIMING_DIFF_INIT() \
+ do { \
+ int __cnt = 5; \
+ GLRO(dl_hp_timing_overhead) = ~0ull; \
+ do \
+ { \
+ hp_timing_t __t1, __t2; \
+ HP_TIMING_NOW (__t1); \
+ HP_TIMING_NOW (__t2); \
+ if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \
+ GLRO(dl_hp_timing_overhead) = __t2 - __t1; \
+ } \
+ while (--__cnt > 0); \
+ } while (0)
+
+#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start))
+
+#define HP_TIMING_ACCUM(Sum, Diff) \
+do { \
+ hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \
+ hp_timing_t tmp1, tmp2; \
+ __asm__ __volatile__("1: ldx [%3], %0\n\t" \
+ "add %0, %2, %1\n\t" \
+ "casx [%3], %0, %1\n\t" \
+ "cmp %0, %1\n\t" \
+ "bne,pn %%xcc, 1b\n\t" \
+ " nop" \
+ : "=&r" (tmp1), "=&r" (tmp2) \
+ : "r" (__diff), "r" (&(Sum)) \
+ : "memory", "g1", "g5", "g6"); \
+} while(0)
+
+#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff)
+
+#define HP_TIMING_PRINT(Buf, Len, Val) \
+ do { \
+ char __buf[20]; \
+ char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \
+ int __len = (Len); \
+ char *__dest = (Buf); \
+ while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \
+ *__dest++ = *__cp++; \
+ memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles"))); \
+ } while (0)
+
+#endif /* hp-timing.h */
diff --git a/libc/sysdeps/sparc/sparc64/jmpbuf-unwind.h b/libc/sysdeps/sparc/sparc64/jmpbuf-unwind.h
new file mode 100644
index 000000000..f7eed15ea
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/jmpbuf-unwind.h
@@ -0,0 +1,37 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller <davem@davemloft.net>, 2005.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame
+ containing a local variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \
+ ((unsigned long int) (address) < (jmpbuf)->uc_mcontext.mc_fp + 2047)
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t) (_address) - (_adj) \
+ < (uintptr_t) (_jmpbuf)[0].uc_mcontext.mc_fp + 2047 - (_adj))
+
+/* We use the normal lobngjmp for unwinding. */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libc/sysdeps/sparc/sparc64/lshift.S b/libc/sysdeps/sparc/sparc64/lshift.S
new file mode 100644
index 000000000..b7ced72f0
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/lshift.S
@@ -0,0 +1,96 @@
+/* SPARC v9 __mpn_lshift --
+
+ Copyright (C) 1996, 1999 Free Software Foundation, Inc.
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include <sysdep.h>
+
+/* INPUT PARAMETERS
+ res_ptr %o0
+ src_ptr %o1
+ size %o2
+ cnt %o3 */
+
+ .register %g2, #scratch
+ .register %g3, #scratch
+
+ENTRY(__mpn_lshift)
+ sllx %o2,3,%g1
+ add %o1,%g1,%o1 ! make %o1 point at end of src
+ ldx [%o1-8],%g2 ! load first limb
+ sub %g0,%o3,%o5 ! negate shift count
+ add %o0,%g1,%o0 ! make %o0 point at end of res
+ add %o2,-1,%o2
+ andcc %o2,4-1,%g4 ! number of limbs in first loop
+ srlx %g2,%o5,%g1 ! compute function result
+ be,pn %xcc,.L0 ! if multiple of 4 limbs, skip first loop
+ mov %g1,%g5
+
+ sub %o2,%g4,%o2 ! adjust count for main loop
+
+.Loop0: ldx [%o1-16],%g3
+ add %o0,-8,%o0
+ add %o1,-8,%o1
+ sllx %g2,%o3,%o4
+ addcc %g4,-1,%g4
+ srlx %g3,%o5,%g1
+ mov %g3,%g2
+ or %o4,%g1,%o4
+ bne,pt %xcc,.Loop0
+ stx %o4,[%o0+0]
+
+.L0: brz,pn %o2,.Lend
+ nop
+
+.Loop: ldx [%o1-16],%g3
+ add %o0,-32,%o0
+ sllx %g2,%o3,%o4
+ addcc %o2,-4,%o2
+ srlx %g3,%o5,%g1
+
+ ldx [%o1-24],%g2
+ sllx %g3,%o3,%g4
+ or %o4,%g1,%o4
+ stx %o4,[%o0+24]
+ srlx %g2,%o5,%g1
+
+ ldx [%o1-32],%g3
+ sllx %g2,%o3,%o4
+ or %g4,%g1,%g4
+ stx %g4,[%o0+16]
+ srlx %g3,%o5,%g1
+
+ ldx [%o1-40],%g2
+ sllx %g3,%o3,%g4
+ or %o4,%g1,%o4
+ stx %o4,[%o0+8]
+ srlx %g2,%o5,%g1
+
+ add %o1,-32,%o1
+ or %g4,%g1,%g4
+ bne,pt %xcc,.Loop
+ stx %g4,[%o0+0]
+
+.Lend: sllx %g2,%o3,%g2
+ stx %g2,[%o0-8]
+
+ jmpl %o7+8, %g0
+ mov %g5,%o0
+
+END(__mpn_lshift)
diff --git a/libc/sysdeps/sparc/sparc64/memchr.S b/libc/sysdeps/sparc/sparc64/memchr.S
new file mode 100644
index 000000000..4f13cb570
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/memchr.S
@@ -0,0 +1,263 @@
+/* memchr (str, ch, n) -- Return pointer to first occurrence of CH in STR less
+ than N.
+ For SPARC v9.
+ Copyright (C) 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz> and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+ This version is developed using the same algorithm as the fast C
+ version which carries the following introduction:
+ Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+ with help from Dan Sahlin (dan@sics.se) and
+ commentary by Jim Blandy (jimb@ai.mit.edu);
+ adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+ and implemented by Roland McGrath (roland@ai.mit.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define XCC xcc
+#define USE_BPR
+ .register %g2, #scratch
+ .register %g3, #scratch
+#endif
+
+ /* Normally, this uses
+ ((xword - 0x0101010101010101) & 0x8080808080808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 32
+ENTRY(__memchr)
+ and %o1, 0xff, %o1 /* IEU0 Group */
+#ifdef USE_BPR
+ brz,pn %o2, 12f /* CTI+IEU1 */
+#else
+ tst %o2 /* IEU1 */
+ be,pn %XCC, 12f /* CTI */
+#endif
+ sll %o1, 8, %g3 /* IEU0 Group */
+ add %o0, %o2, %o2 /* IEU1 */
+
+ sethi %hi(0x01010101), %g1 /* IEU0 Group */
+ or %g3, %o1, %g3 /* IEU1 */
+ ldub [%o0], %o3 /* Load */
+ sllx %g3, 16, %g5 /* IEU0 Group */
+
+ or %g1, %lo(0x01010101), %g1 /* IEU1 */
+ sllx %g1, 32, %g2 /* IEU0 Group */
+ or %g3, %g5, %g3 /* IEU1 */
+ sllx %g3, 32, %g5 /* IEU0 Group */
+
+ cmp %o3, %o1 /* IEU1 */
+ be,pn %xcc, 13f /* CTI */
+ or %g1, %g2, %g1 /* IEU0 Group */
+ andcc %o0, 7, %g0 /* IEU1 */
+
+ bne,a,pn %icc, 21f /* CTI */
+ add %o0, 1, %o0 /* IEU0 Group */
+ ldx [%o0], %o3 /* Load Group */
+ sllx %g1, 7, %g2 /* IEU0 */
+
+ or %g3, %g5, %g3 /* IEU1 */
+1: add %o0, 8, %o0 /* IEU0 Group */
+ xor %o3, %g3, %o4 /* IEU1 */
+ /* %g1 = 0101010101010101 *
+ * %g2 = 8080088080808080 *
+ * %g3 = c c c c c c c c *
+ * %o3 = value *
+ * %o4 = value XOR c */
+2: cmp %o0, %o2 /* IEU1 Group */
+
+ bg,pn %XCC, 11f /* CTI */
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ sub %o4, %g1, %o5 /* IEU0 Group */
+ add %o0, 8, %o0 /* IEU1 */
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o5, %o4, %o5 /* IEU0 Group */
+#endif
+
+ andcc %o5, %g2, %g0 /* IEU1 Group */
+ be,a,pt %xcc, 2b /* CTI */
+ xor %o3, %g3, %o4 /* IEU0 */
+ srlx %o4, 56, %g5 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 3f /* CTI */
+ srlx %o4, 48, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 4f /* CTI */
+ srlx %o4, 40, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 5f /* CTI */
+
+ srlx %o4, 32, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 6f /* CTI */
+ srlx %o4, 24, %g5 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 7f /* CTI */
+ srlx %o4, 16, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 8f /* CTI */
+ srlx %o4, 8, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 9f /* CTI */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ bne,pt %icc, 2b /* CTI */
+ xor %o3, %g3, %o4 /* IEU0 */
+ retl /* CTI+IEU1 Group */
+
+ add %o0, -9, %o0 /* IEU0 */
+
+ .align 16
+3: retl /* CTI+IEU1 Group */
+ add %o0, -16, %o0 /* IEU0 */
+4: retl /* CTI+IEU1 Group */
+ add %o0, -15, %o0 /* IEU0 */
+
+5: retl /* CTI+IEU1 Group */
+ add %o0, -14, %o0 /* IEU0 */
+6: retl /* CTI+IEU1 Group */
+ add %o0, -13, %o0 /* IEU0 */
+
+7: retl /* CTI+IEU1 Group */
+ add %o0, -12, %o0 /* IEU0 */
+8: retl /* CTI+IEU1 Group */
+ add %o0, -11, %o0 /* IEU0 */
+
+9: retl /* CTI+IEU1 Group */
+ add %o0, -10, %o0 /* IEU0 */
+11: sub %o4, %g1, %o5 /* IEU0 Group */
+ sub %o0, 8, %o0 /* IEU1 */
+
+ andcc %o5, %g2, %g0 /* IEU1 Group */
+ be,pt %xcc, 12f /* CTI */
+ sub %o2, %o0, %o2 /* IEU0 */
+ tst %o2 /* IEU1 Group */
+
+ be,pn %XCC, 12f /* CTI */
+ srlx %o4, 56, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 13f /* CTI */
+
+ cmp %o2, 1 /* IEU0 */
+ be,pn %XCC, 12f /* CTI Group */
+ srlx %o4, 48, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 14f /* CTI */
+ cmp %o2, 2 /* IEU1 Group */
+ be,pn %XCC, 12f /* CTI */
+ srlx %o4, 40, %g5 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 15f /* CTI */
+ cmp %o2, 3 /* IEU1 Group */
+ be,pn %XCC, 12f /* CTI */
+
+ srlx %o4, 32, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 16f /* CTI */
+ cmp %o2, 4 /* IEU1 Group */
+
+ be,pn %XCC, 12f /* CTI */
+ srlx %o4, 24, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 17f /* CTI */
+
+ cmp %o2, 5 /* IEU1 Group */
+ be,pn %XCC, 12f /* CTI */
+ srlx %o4, 16, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 18f /* CTI */
+ cmp %o2, 6 /* IEU1 Group */
+ be,pn %XCC, 12f /* CTI */
+ srlx %o4, 8, %g5 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 19f /* CTI */
+ nop /* IEU0 */
+12: retl /* CTI+IEU1 Group */
+
+ clr %o0 /* IEU0 */
+ nop /* Stub */
+13: retl /* CTI+IEU1 Group */
+ nop /* IEU0 */
+
+14: retl /* CTI+IEU1 Group */
+ add %o0, 1, %o0 /* IEU0 */
+15: retl /* CTI+IEU1 Group */
+ add %o0, 2, %o0 /* IEU0 */
+
+16: retl /* CTI+IEU1 Group */
+ add %o0, 3, %o0 /* IEU0 */
+17: retl /* CTI+IEU1 Group */
+ add %o0, 4, %o0 /* IEU0 */
+
+18: retl /* CTI+IEU1 Group */
+ add %o0, 5, %o0 /* IEU0 */
+19: retl /* CTI+IEU1 Group */
+ add %o0, 6, %o0 /* IEU0 */
+
+21: cmp %o0, %o2 /* IEU1 */
+ be,pn %XCC, 12b /* CTI */
+ sllx %g1, 7, %g2 /* IEU0 Group */
+ ldub [%o0], %o3 /* Load */
+
+ or %g3, %g5, %g3 /* IEU1 */
+22: andcc %o0, 7, %g0 /* IEU1 Group */
+ be,a,pn %icc, 1b /* CTI */
+ ldx [%o0], %o3 /* Load */
+
+ cmp %o3, %o1 /* IEU1 Group */
+ be,pn %xcc, 23f /* CTI */
+ add %o0, 1, %o0 /* IEU0 */
+ cmp %o0, %o2 /* IEU1 Group */
+
+ bne,a,pt %XCC, 22b /* CTI */
+ ldub [%o0], %o3 /* Load */
+ retl /* CTI+IEU1 Group */
+ clr %o0 /* IEU0 */
+
+23: retl /* CTI+IEU1 Group */
+ add %o0, -1, %o0 /* IEU0 */
+END(__memchr)
+
+weak_alias (__memchr, memchr)
+#if !__BOUNDED_POINTERS__
+weak_alias (__memchr, __ubp_memchr)
+#endif
+libc_hidden_builtin_def (memchr)
diff --git a/libc/sysdeps/sparc/sparc64/memcmp.S b/libc/sysdeps/sparc/sparc64/memcmp.S
new file mode 100644
index 000000000..f9502d63f
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/memcmp.S
@@ -0,0 +1,143 @@
+/* Compare two memory blocks for differences in the first COUNT bytes.
+ For SPARC v9.
+ Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz> and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define XCC xcc
+#define USE_BPR
+ .register %g2, #scratch
+ .register %g3, #scratch
+#endif
+
+ .text
+ .align 32
+ENTRY(memcmp)
+#ifdef USE_BPR
+ brz,pn %o2, 3f /* CTI+IEU1 Group */
+#else
+ tst %o2 /* IEU1 Group */
+ be,pn %XCC, 3f /* CTI */
+#endif
+ andcc %o0, 7, %g0 /* IEU1 Group */
+ bne,pn %icc, 8f /* CTI */
+1: andcc %o1, 7, %g1 /* IEU1 Group */
+
+ bne,pn %icc, 10f /* CTI */
+ mov 64, %g3 /* IEU0 */
+ ldx [%o0], %g1 /* Load Group */
+ sub %o1, %o0, %o1 /* IEU0 */
+
+ ldx [%o0 + %o1], %g2 /* Load Group */
+ add %o0, 8, %o0 /* IEU0 */
+2: mov %g1, %o3 /* IEU0 Group */
+ subcc %o2, 8, %o2 /* IEU1 */
+
+ bl,pn %XCC, 5f /* CTI */
+ ldxa [%o0] ASI_PNF, %g1 /* Load Group */
+ mov %g2, %o4 /* IEU0 */
+ ldxa [%o0 + %o1] ASI_PNF, %g2 /* Load Group */
+
+ cmp %o3, %o4 /* IEU1 */
+ be,pt %xcc, 2b /* CTI */
+ add %o0, 8, %o0 /* IEU0 */
+7: mov -1, %o0 /* IEU1 */
+
+ retl /* CTI+IEU1 Group */
+ movgu %xcc, 1, %o0 /* Single Group */
+3: retl /* CTI+IEU1 Group */
+ clr %o0 /* IEU0 */
+
+ .align 16
+5: mov %g2, %o4 /* IEU0 */
+6: cmp %o2, -8 /* IEU1 */
+ be,pn %XCC, 3b /* CTI */
+ sub %g0, %o2, %o2 /* IEU0 Group */
+
+ sllx %o2, 3, %o2 /* IEU0 Group */
+ srlx %o3, %o2, %o3 /* IEU0 Group */
+ srlx %o4, %o2, %o4 /* IEU0 Group */
+ clr %o0 /* IEU1 */
+
+ cmp %o3, %o4 /* IEU1 Group */
+ movgu %xcc, 1, %o0 /* Single Group */
+ retl /* CTI+IEU1 Group */
+ movlu %xcc, -1, %o0 /* Single Group */
+
+8: ldub [%o0], %o3 /* Load */
+ add %o0, 1, %o0 /* IEU0 */
+ ldub [%o1], %o4 /* Load Group */
+ add %o1, 1, %o1 /* IEU0 */
+
+9: cmp %o3, %o4 /* IEU1 Group */
+ bne,pn %xcc, 12f /* CTI */
+ subcc %o2, 1, %o2 /* IEU1 Group */
+ be,pn %XCC, 3b /* CTI */
+
+ lduba [%o0] ASI_PNF, %o3 /* Load */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+ be,pn %icc, 1b /* CTI */
+ lduba [%o1] ASI_PNF, %o4 /* Load */
+
+ add %o0, 1, %o0 /* IEU0 Group */
+ ba,pt %xcc, 9b /* CTI */
+ add %o1, 1, %o1 /* IEU1 */
+
+ .align 16
+12: mov -1, %o0 /* IEU0 Group */
+ cmp %o3, %o4 /* IEU1 */
+ retl /* CTI+IEU1 Group */
+ movgu %xcc, 1, %o0 /* Single Group */
+
+ .align 16
+ nop /* Stub */
+10: sllx %g1, 3, %g2 /* IEU0 Group */
+ sub %o1, %g1, %o1 /* IEU1 */
+ sub %g3, %g2, %g3 /* IEU0 Group */
+
+ ldxa [%o0] ASI_PNF, %g5 /* Load */
+ sub %o1, %o0, %o1 /* IEU1 */
+ ldxa [%o0 + %o1] ASI_PNF, %g4 /* Load Group */
+ add %o0, 8, %o0 /* IEU0 */
+
+11: sllx %g4, %g2, %o4 /* IEU0 Group */
+ ldxa [%o0 + %o1] ASI_PNF, %g4 /* Load */
+ srlx %g4, %g3, %o5 /* IEU0 Group */
+ mov %g5, %o3 /* IEU1 */
+
+ ldxa [%o0] ASI_PNF, %g5 /* Load */
+ subcc %o2, 8, %o2 /* IEU1 Group */
+ bl,pn %XCC, 6b /* CTI */
+ or %o4, %o5, %o4 /* IEU0 */
+
+ cmp %o3, %o4 /* IEU1 Group */
+ be,pt %xcc, 11b /* CTI */
+ add %o0, 8, %o0 /* IEU0 */
+ mov -1, %o0 /* IEU0 */
+
+ retl /* CTI+IEU1 Group */
+ movgu %xcc, 1, %o0 /* Single Group */
+END(memcmp)
+
+#undef bcmp
+weak_alias (memcmp, bcmp)
+libc_hidden_builtin_def (memcmp)
diff --git a/libc/sysdeps/sparc/sparc64/memcpy.S b/libc/sysdeps/sparc/sparc64/memcpy.S
new file mode 100644
index 000000000..599335801
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/memcpy.S
@@ -0,0 +1,925 @@
+/* Copy SIZE bytes from SRC to DEST.
+ For UltraSPARC.
+ Copyright (C) 1996, 97, 98, 99, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller (davem@caip.rutgers.edu) and
+ Jakub Jelinek (jakub@redhat.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define USE_BPR
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .register %g6, #scratch
+#define XCC xcc
+#endif
+#define FPRS_FEF 4
+
+#define FREG_FROB(f1, f2, f3, f4, f5, f6, f7, f8, f9) \
+ faligndata %f1, %f2, %f48; \
+ faligndata %f2, %f3, %f50; \
+ faligndata %f3, %f4, %f52; \
+ faligndata %f4, %f5, %f54; \
+ faligndata %f5, %f6, %f56; \
+ faligndata %f6, %f7, %f58; \
+ faligndata %f7, %f8, %f60; \
+ faligndata %f8, %f9, %f62;
+
+#define MAIN_LOOP_CHUNK(src, dest, fdest, fsrc, len, jmptgt) \
+ ldda [%src] %asi, %fdest; \
+ add %src, 0x40, %src; \
+ add %dest, 0x40, %dest; \
+ subcc %len, 0x40, %len; \
+ be,pn %xcc, jmptgt; \
+ stda %fsrc, [%dest - 0x40] %asi;
+
+#define LOOP_CHUNK1(src, dest, len, branch_dest) \
+ MAIN_LOOP_CHUNK(src, dest, f0, f48, len, branch_dest)
+#define LOOP_CHUNK2(src, dest, len, branch_dest) \
+ MAIN_LOOP_CHUNK(src, dest, f16, f48, len, branch_dest)
+#define LOOP_CHUNK3(src, dest, len, branch_dest) \
+ MAIN_LOOP_CHUNK(src, dest, f32, f48, len, branch_dest)
+
+#define STORE_SYNC(dest, fsrc) \
+ stda %fsrc, [%dest] %asi; \
+ add %dest, 0x40, %dest;
+
+#define STORE_JUMP(dest, fsrc, target) \
+ stda %fsrc, [%dest] %asi; \
+ add %dest, 0x40, %dest; \
+ ba,pt %xcc, target;
+
+#define VISLOOP_PAD nop; nop; nop; nop; \
+ nop; nop; nop; nop; \
+ nop; nop; nop; nop; \
+ nop; nop; nop;
+
+#define FINISH_VISCHUNK(dest, f0, f1, left) \
+ subcc %left, 8, %left; \
+ bl,pn %xcc, 205f; \
+ faligndata %f0, %f1, %f48; \
+ std %f48, [%dest]; \
+ add %dest, 8, %dest;
+
+#define UNEVEN_VISCHUNK(dest, f0, f1, left) \
+ subcc %left, 8, %left; \
+ bl,pn %xcc, 205f; \
+ fsrc1 %f0, %f1; \
+ ba,a,pt %xcc, 204f;
+
+ /* Macros for non-VIS memcpy code. */
+#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldx [%src + offset + 0x00], %t0; \
+ ldx [%src + offset + 0x08], %t1; \
+ ldx [%src + offset + 0x10], %t2; \
+ ldx [%src + offset + 0x18], %t3; \
+ stw %t0, [%dst + offset + 0x04]; \
+ srlx %t0, 32, %t0; \
+ stw %t0, [%dst + offset + 0x00]; \
+ stw %t1, [%dst + offset + 0x0c]; \
+ srlx %t1, 32, %t1; \
+ stw %t1, [%dst + offset + 0x08]; \
+ stw %t2, [%dst + offset + 0x14]; \
+ srlx %t2, 32, %t2; \
+ stw %t2, [%dst + offset + 0x10]; \
+ stw %t3, [%dst + offset + 0x1c]; \
+ srlx %t3, 32, %t3; \
+ stw %t3, [%dst + offset + 0x18];
+
+#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldx [%src + offset + 0x00], %t0; \
+ ldx [%src + offset + 0x08], %t1; \
+ ldx [%src + offset + 0x10], %t2; \
+ ldx [%src + offset + 0x18], %t3; \
+ stx %t0, [%dst + offset + 0x00]; \
+ stx %t1, [%dst + offset + 0x08]; \
+ stx %t2, [%dst + offset + 0x10]; \
+ stx %t3, [%dst + offset + 0x18]; \
+ ldx [%src + offset + 0x20], %t0; \
+ ldx [%src + offset + 0x28], %t1; \
+ ldx [%src + offset + 0x30], %t2; \
+ ldx [%src + offset + 0x38], %t3; \
+ stx %t0, [%dst + offset + 0x20]; \
+ stx %t1, [%dst + offset + 0x28]; \
+ stx %t2, [%dst + offset + 0x30]; \
+ stx %t3, [%dst + offset + 0x38];
+
+#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldx [%src - offset - 0x10], %t0; \
+ ldx [%src - offset - 0x08], %t1; \
+ stw %t0, [%dst - offset - 0x0c]; \
+ srlx %t0, 32, %t2; \
+ stw %t2, [%dst - offset - 0x10]; \
+ stw %t1, [%dst - offset - 0x04]; \
+ srlx %t1, 32, %t3; \
+ stw %t3, [%dst - offset - 0x08];
+
+#define MOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1) \
+ ldx [%src - offset - 0x10], %t0; \
+ ldx [%src - offset - 0x08], %t1; \
+ stx %t0, [%dst - offset - 0x10]; \
+ stx %t1, [%dst - offset - 0x08];
+
+ /* Macros for non-VIS memmove code. */
+#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldx [%src - offset - 0x20], %t0; \
+ ldx [%src - offset - 0x18], %t1; \
+ ldx [%src - offset - 0x10], %t2; \
+ ldx [%src - offset - 0x08], %t3; \
+ stw %t0, [%dst - offset - 0x1c]; \
+ srlx %t0, 32, %t0; \
+ stw %t0, [%dst - offset - 0x20]; \
+ stw %t1, [%dst - offset - 0x14]; \
+ srlx %t1, 32, %t1; \
+ stw %t1, [%dst - offset - 0x18]; \
+ stw %t2, [%dst - offset - 0x0c]; \
+ srlx %t2, 32, %t2; \
+ stw %t2, [%dst - offset - 0x10]; \
+ stw %t3, [%dst - offset - 0x04]; \
+ srlx %t3, 32, %t3; \
+ stw %t3, [%dst - offset - 0x08];
+
+#define RMOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldx [%src - offset - 0x20], %t0; \
+ ldx [%src - offset - 0x18], %t1; \
+ ldx [%src - offset - 0x10], %t2; \
+ ldx [%src - offset - 0x08], %t3; \
+ stx %t0, [%dst - offset - 0x20]; \
+ stx %t1, [%dst - offset - 0x18]; \
+ stx %t2, [%dst - offset - 0x10]; \
+ stx %t3, [%dst - offset - 0x08]; \
+ ldx [%src - offset - 0x40], %t0; \
+ ldx [%src - offset - 0x38], %t1; \
+ ldx [%src - offset - 0x30], %t2; \
+ ldx [%src - offset - 0x28], %t3; \
+ stx %t0, [%dst - offset - 0x40]; \
+ stx %t1, [%dst - offset - 0x38]; \
+ stx %t2, [%dst - offset - 0x30]; \
+ stx %t3, [%dst - offset - 0x28];
+
+#define RMOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldx [%src + offset + 0x00], %t0; \
+ ldx [%src + offset + 0x08], %t1; \
+ stw %t0, [%dst + offset + 0x04]; \
+ srlx %t0, 32, %t2; \
+ stw %t2, [%dst + offset + 0x00]; \
+ stw %t1, [%dst + offset + 0x0c]; \
+ srlx %t1, 32, %t3; \
+ stw %t3, [%dst + offset + 0x08];
+
+#define RMOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1) \
+ ldx [%src + offset + 0x00], %t0; \
+ ldx [%src + offset + 0x08], %t1; \
+ stx %t0, [%dst + offset + 0x00]; \
+ stx %t1, [%dst + offset + 0x08];
+
+ .text
+ .align 32
+
+ENTRY(bcopy)
+ sub %o1, %o0, %o4 /* IEU0 Group */
+ mov %o0, %g3 /* IEU1 */
+ cmp %o4, %o2 /* IEU1 Group */
+ mov %o1, %o0 /* IEU0 */
+ bgeu,pt %XCC, 210f /* CTI */
+ mov %g3, %o1 /* IEU0 Group */
+#ifndef USE_BPR
+ srl %o2, 0, %o2 /* IEU1 */
+#endif
+ brnz,pn %o2, 220f /* CTI Group */
+ add %o0, %o2, %o0 /* IEU0 */
+ retl
+ nop
+END(bcopy)
+
+ .align 32
+ENTRY(__memcpy_large)
+200: be,pt %xcc, 201f /* CTI */
+ andcc %o0, 0x38, %g5 /* IEU1 Group */
+ mov 8, %g1 /* IEU0 */
+ sub %g1, %g2, %g2 /* IEU0 Group */
+ andcc %o0, 1, %g0 /* IEU1 */
+ be,pt %icc, 2f /* CTI */
+ sub %o2, %g2, %o2 /* IEU0 Group */
+1: ldub [%o1], %o5 /* Load Group */
+ add %o1, 1, %o1 /* IEU0 */
+ add %o0, 1, %o0 /* IEU1 */
+ subcc %g2, 1, %g2 /* IEU1 Group */
+ be,pn %xcc, 3f /* CTI */
+ stb %o5, [%o0 - 1] /* Store */
+2: ldub [%o1], %o5 /* Load Group */
+ add %o0, 2, %o0 /* IEU0 */
+ ldub [%o1 + 1], %g3 /* Load Group */
+ subcc %g2, 2, %g2 /* IEU1 Group */
+ stb %o5, [%o0 - 2] /* Store */
+ add %o1, 2, %o1 /* IEU0 */
+ bne,pt %xcc, 2b /* CTI Group */
+ stb %g3, [%o0 - 1] /* Store */
+3: andcc %o0, 0x38, %g5 /* IEU1 Group */
+201: be,pt %icc, 202f /* CTI */
+ mov 64, %g1 /* IEU0 */
+ fmovd %f0, %f2 /* FPU */
+ sub %g1, %g5, %g5 /* IEU0 Group */
+ alignaddr %o1, %g0, %g1 /* GRU Group */
+ ldd [%g1], %f4 /* Load Group */
+ sub %o2, %g5, %o2 /* IEU0 */
+1: ldd [%g1 + 0x8], %f6 /* Load Group */
+ add %g1, 0x8, %g1 /* IEU0 Group */
+ subcc %g5, 8, %g5 /* IEU1 */
+ faligndata %f4, %f6, %f0 /* GRU Group */
+ std %f0, [%o0] /* Store */
+ add %o1, 8, %o1 /* IEU0 Group */
+ be,pn %xcc, 202f /* CTI */
+ add %o0, 8, %o0 /* IEU1 */
+ ldd [%g1 + 0x8], %f4 /* Load Group */
+ add %g1, 8, %g1 /* IEU0 */
+ subcc %g5, 8, %g5 /* IEU1 */
+ faligndata %f6, %f4, %f0 /* GRU Group */
+ std %f0, [%o0] /* Store */
+ add %o1, 8, %o1 /* IEU0 */
+ bne,pt %xcc, 1b /* CTI Group */
+ add %o0, 8, %o0 /* IEU0 */
+202: membar #LoadStore | #StoreStore | #StoreLoad /* LSU Group */
+ wr %g0, ASI_BLK_P, %asi /* LSU Group */
+ subcc %o2, 0x40, %g6 /* IEU1 Group */
+ mov %o1, %g1 /* IEU0 */
+ andncc %g6, (0x40 - 1), %g6 /* IEU1 Group */
+ srl %g1, 3, %g2 /* IEU0 */
+ sub %o2, %g6, %g3 /* IEU0 Group */
+ andn %o1, (0x40 - 1), %o1 /* IEU1 */
+ and %g2, 7, %g2 /* IEU0 Group */
+ andncc %g3, 0x7, %g3 /* IEU1 */
+ fmovd %f0, %f2 /* FPU */
+ sub %g3, 0x10, %g3 /* IEU0 Group */
+ sub %o2, %g6, %o2 /* IEU1 */
+ alignaddr %g1, %g0, %g0 /* GRU Group */
+ add %g1, %g6, %g1 /* IEU0 Group */
+ subcc %o2, %g3, %o2 /* IEU1 */
+ ldda [%o1 + 0x00] %asi, %f0 /* LSU Group */
+ add %g1, %g3, %g1 /* IEU0 */
+ ldda [%o1 + 0x40] %asi, %f16 /* LSU Group */
+ sub %g6, 0x80, %g6 /* IEU0 */
+ ldda [%o1 + 0x80] %asi, %f32 /* LSU Group */
+ /* Clk1 Group 8-( */
+ /* Clk2 Group 8-( */
+ /* Clk3 Group 8-( */
+ /* Clk4 Group 8-( */
+203: rd %pc, %g5 /* PDU Group 8-( */
+ addcc %g5, %lo(300f - 203b), %g5 /* IEU1 Group */
+ sll %g2, 9, %g2 /* IEU0 */
+ jmpl %g5 + %g2, %g0 /* CTI Group brk forced*/
+ addcc %o1, 0xc0, %o1 /* IEU1 Group */
+
+ .align 512 /* OK, here comes the fun part... */
+300: FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) LOOP_CHUNK1(o1, o0, g6, 301f)
+ FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) LOOP_CHUNK2(o1, o0, g6, 302f)
+ FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) LOOP_CHUNK3(o1, o0, g6, 303f)
+ b,pt %xcc, 300b+4; faligndata %f0, %f2, %f48
+301: FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) STORE_JUMP(o0, f48, 400f) membar #Sync
+302: FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) STORE_JUMP(o0, f48, 416f) membar #Sync
+303: FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) STORE_JUMP(o0, f48, 432f) membar #Sync
+ VISLOOP_PAD
+310: FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) LOOP_CHUNK1(o1, o0, g6, 311f)
+ FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) LOOP_CHUNK2(o1, o0, g6, 312f)
+ FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) LOOP_CHUNK3(o1, o0, g6, 313f)
+ b,pt %xcc, 310b+4; faligndata %f2, %f4, %f48
+311: FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) STORE_JUMP(o0, f48, 402f) membar #Sync
+312: FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) STORE_JUMP(o0, f48, 418f) membar #Sync
+313: FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) STORE_JUMP(o0, f48, 434f) membar #Sync
+ VISLOOP_PAD
+320: FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) LOOP_CHUNK1(o1, o0, g6, 321f)
+ FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) LOOP_CHUNK2(o1, o0, g6, 322f)
+ FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) LOOP_CHUNK3(o1, o0, g6, 323f)
+ b,pt %xcc, 320b+4; faligndata %f4, %f6, %f48
+321: FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) STORE_JUMP(o0, f48, 404f) membar #Sync
+322: FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) STORE_JUMP(o0, f48, 420f) membar #Sync
+323: FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) STORE_JUMP(o0, f48, 436f) membar #Sync
+ VISLOOP_PAD
+330: FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) LOOP_CHUNK1(o1, o0, g6, 331f)
+ FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) LOOP_CHUNK2(o1, o0, g6, 332f)
+ FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) LOOP_CHUNK3(o1, o0, g6, 333f)
+ b,pt %xcc, 330b+4; faligndata %f6, %f8, %f48
+331: FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) STORE_JUMP(o0, f48, 406f) membar #Sync
+332: FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) STORE_JUMP(o0, f48, 422f) membar #Sync
+333: FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) STORE_JUMP(o0, f48, 438f) membar #Sync
+ VISLOOP_PAD
+340: FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) LOOP_CHUNK1(o1, o0, g6, 341f)
+ FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) LOOP_CHUNK2(o1, o0, g6, 342f)
+ FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) LOOP_CHUNK3(o1, o0, g6, 343f)
+ b,pt %xcc, 340b+4; faligndata %f8, %f10, %f48
+341: FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) STORE_JUMP(o0, f48, 408f) membar #Sync
+342: FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) STORE_JUMP(o0, f48, 424f) membar #Sync
+343: FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) STORE_JUMP(o0, f48, 440f) membar #Sync
+ VISLOOP_PAD
+350: FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) LOOP_CHUNK1(o1, o0, g6, 351f)
+ FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) LOOP_CHUNK2(o1, o0, g6, 352f)
+ FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) LOOP_CHUNK3(o1, o0, g6, 353f)
+ b,pt %xcc, 350b+4; faligndata %f10, %f12, %f48
+351: FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) STORE_JUMP(o0, f48, 410f) membar #Sync
+352: FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) STORE_JUMP(o0, f48, 426f) membar #Sync
+353: FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) STORE_JUMP(o0, f48, 442f) membar #Sync
+ VISLOOP_PAD
+360: FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) LOOP_CHUNK1(o1, o0, g6, 361f)
+ FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) LOOP_CHUNK2(o1, o0, g6, 362f)
+ FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) LOOP_CHUNK3(o1, o0, g6, 363f)
+ b,pt %xcc, 360b+4; faligndata %f12, %f14, %f48
+361: FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) STORE_JUMP(o0, f48, 412f) membar #Sync
+362: FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) STORE_JUMP(o0, f48, 428f) membar #Sync
+363: FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) STORE_JUMP(o0, f48, 444f) membar #Sync
+ VISLOOP_PAD
+370: FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) LOOP_CHUNK1(o1, o0, g6, 371f)
+ FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) LOOP_CHUNK2(o1, o0, g6, 372f)
+ FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) LOOP_CHUNK3(o1, o0, g6, 373f)
+ b,pt %xcc, 370b+4; faligndata %f14, %f16, %f48
+371: FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) STORE_JUMP(o0, f48, 414f) membar #Sync
+372: FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) STORE_JUMP(o0, f48, 430f) membar #Sync
+373: FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) STORE_JUMP(o0, f48, 446f) membar #Sync
+ VISLOOP_PAD
+400: FINISH_VISCHUNK(o0, f0, f2, g3)
+402: FINISH_VISCHUNK(o0, f2, f4, g3)
+404: FINISH_VISCHUNK(o0, f4, f6, g3)
+406: FINISH_VISCHUNK(o0, f6, f8, g3)
+408: FINISH_VISCHUNK(o0, f8, f10, g3)
+410: FINISH_VISCHUNK(o0, f10, f12, g3)
+412: FINISH_VISCHUNK(o0, f12, f14, g3)
+414: UNEVEN_VISCHUNK(o0, f14, f0, g3)
+416: FINISH_VISCHUNK(o0, f16, f18, g3)
+418: FINISH_VISCHUNK(o0, f18, f20, g3)
+420: FINISH_VISCHUNK(o0, f20, f22, g3)
+422: FINISH_VISCHUNK(o0, f22, f24, g3)
+424: FINISH_VISCHUNK(o0, f24, f26, g3)
+426: FINISH_VISCHUNK(o0, f26, f28, g3)
+428: FINISH_VISCHUNK(o0, f28, f30, g3)
+430: UNEVEN_VISCHUNK(o0, f30, f0, g3)
+432: FINISH_VISCHUNK(o0, f32, f34, g3)
+434: FINISH_VISCHUNK(o0, f34, f36, g3)
+436: FINISH_VISCHUNK(o0, f36, f38, g3)
+438: FINISH_VISCHUNK(o0, f38, f40, g3)
+440: FINISH_VISCHUNK(o0, f40, f42, g3)
+442: FINISH_VISCHUNK(o0, f42, f44, g3)
+444: FINISH_VISCHUNK(o0, f44, f46, g3)
+446: UNEVEN_VISCHUNK(o0, f46, f0, g3)
+204: ldd [%o1], %f2 /* Load Group */
+ add %o1, 8, %o1 /* IEU0 */
+ subcc %g3, 8, %g3 /* IEU1 */
+ faligndata %f0, %f2, %f8 /* GRU Group */
+ std %f8, [%o0] /* Store */
+ bl,pn %xcc, 205f /* CTI */
+ add %o0, 8, %o0 /* IEU0 Group */
+ ldd [%o1], %f0 /* Load Group */
+ add %o1, 8, %o1 /* IEU0 */
+ subcc %g3, 8, %g3 /* IEU1 */
+ faligndata %f2, %f0, %f8 /* GRU Group */
+ std %f8, [%o0] /* Store */
+ bge,pt %xcc, 204b /* CTI */
+ add %o0, 8, %o0 /* IEU0 Group */
+205: brz,pt %o2, 207f /* CTI Group */
+ mov %g1, %o1 /* IEU0 */
+206: ldub [%o1], %g5 /* LOAD */
+ add %o1, 1, %o1 /* IEU0 */
+ add %o0, 1, %o0 /* IEU1 */
+ subcc %o2, 1, %o2 /* IEU1 */
+ bne,pt %xcc, 206b /* CTI */
+ stb %g5, [%o0 - 1] /* Store Group */
+207: membar #StoreLoad | #StoreStore /* LSU Group */
+ wr %g0, FPRS_FEF, %fprs
+ retl
+ mov %g4, %o0
+
+208: andcc %o2, 1, %g0 /* IEU1 Group */
+ be,pt %icc, 2f+4 /* CTI */
+1: ldub [%o1], %g5 /* LOAD Group */
+ add %o1, 1, %o1 /* IEU0 */
+ add %o0, 1, %o0 /* IEU1 */
+ subcc %o2, 1, %o2 /* IEU1 Group */
+ be,pn %xcc, 209f /* CTI */
+ stb %g5, [%o0 - 1] /* Store */
+2: ldub [%o1], %g5 /* LOAD Group */
+ add %o0, 2, %o0 /* IEU0 */
+ ldub [%o1 + 1], %o5 /* LOAD Group */
+ add %o1, 2, %o1 /* IEU0 */
+ subcc %o2, 2, %o2 /* IEU1 Group */
+ stb %g5, [%o0 - 2] /* Store */
+ bne,pt %xcc, 2b /* CTI */
+ stb %o5, [%o0 - 1] /* Store */
+209: retl
+ mov %g4, %o0
+END(__memcpy_large)
+
+#ifdef USE_BPR
+
+ /* void *__align_cpy_4(void *dest, void *src, size_t n)
+ * SPARC v9 SYSV ABI
+ * Like memcpy, but results are undefined if (!n || ((dest | src | n) & 3))
+ */
+
+ .align 32
+ENTRY(__align_cpy_4)
+ mov %o0, %g4 /* IEU0 Group */
+ cmp %o2, 15 /* IEU1 */
+ bleu,pn %xcc, 208b /* CTI */
+ cmp %o2, (64 * 6) /* IEU1 Group */
+ bgeu,pn %xcc, 200b /* CTI */
+ andcc %o0, 7, %g2 /* IEU1 Group */
+ ba,pt %xcc, 216f /* CTI */
+ andcc %o1, 4, %g0 /* IEU1 Group */
+END(__align_cpy_4)
+
+ /* void *__align_cpy_8(void *dest, void *src, size_t n)
+ * SPARC v9 SYSV ABI
+ * Like memcpy, but results are undefined if (!n || ((dest | src | n) & 7))
+ */
+
+ .align 32
+ENTRY(__align_cpy_8)
+ mov %o0, %g4 /* IEU0 Group */
+ cmp %o2, 15 /* IEU1 */
+ bleu,pn %xcc, 208b /* CTI */
+ cmp %o2, (64 * 6) /* IEU1 Group */
+ bgeu,pn %xcc, 201b /* CTI */
+ andcc %o0, 0x38, %g5 /* IEU1 Group */
+ andcc %o2, -128, %g6 /* IEU1 Group */
+ bne,a,pt %xcc, 82f + 4 /* CTI */
+ ldx [%o1], %g1 /* Load */
+ ba,pt %xcc, 41f /* CTI Group */
+ andcc %o2, 0x70, %g6 /* IEU1 */
+END(__align_cpy_8)
+
+ /* void *__align_cpy_16(void *dest, void *src, size_t n)
+ * SPARC v9 SYSV ABI
+ * Like memcpy, but results are undefined if (!n || ((dest | src | n) & 15))
+ */
+
+ .align 32
+ENTRY(__align_cpy_16)
+ mov %o0, %g4 /* IEU0 Group */
+ cmp %o2, (64 * 6) /* IEU1 */
+ bgeu,pn %xcc, 201b /* CTI */
+ andcc %o0, 0x38, %g5 /* IEU1 Group */
+ andcc %o2, -128, %g6 /* IEU1 Group */
+ bne,a,pt %xcc, 82f + 4 /* CTI */
+ ldx [%o1], %g1 /* Load */
+ ba,pt %xcc, 41f /* CTI Group */
+ andcc %o2, 0x70, %g6 /* IEU1 */
+END(__align_cpy_16)
+
+#endif
+
+ .align 32
+ENTRY(memcpy)
+210:
+#ifndef USE_BPR
+ srl %o2, 0, %o2 /* IEU1 Group */
+#endif
+ brz,pn %o2, 209b /* CTI Group */
+ mov %o0, %g4 /* IEU0 */
+218: cmp %o2, 15 /* IEU1 Group */
+ bleu,pn %xcc, 208b /* CTI */
+ cmp %o2, (64 * 6) /* IEU1 Group */
+ bgeu,pn %xcc, 200b /* CTI */
+ andcc %o0, 7, %g2 /* IEU1 Group */
+ sub %o0, %o1, %g5 /* IEU0 */
+ andcc %g5, 3, %o5 /* IEU1 Group */
+ bne,pn %xcc, 212f /* CTI */
+ andcc %o1, 3, %g0 /* IEU1 Group */
+ be,a,pt %xcc, 216f /* CTI */
+ andcc %o1, 4, %g0 /* IEU1 Group */
+ andcc %o1, 1, %g0 /* IEU1 Group */
+ be,pn %xcc, 4f /* CTI */
+ andcc %o1, 2, %g0 /* IEU1 Group */
+ ldub [%o1], %g2 /* Load Group */
+ add %o1, 1, %o1 /* IEU0 */
+ add %o0, 1, %o0 /* IEU1 */
+ sub %o2, 1, %o2 /* IEU0 Group */
+ bne,pn %xcc, 5f /* CTI Group */
+ stb %g2, [%o0 - 1] /* Store */
+4: lduh [%o1], %g2 /* Load Group */
+ add %o1, 2, %o1 /* IEU0 */
+ add %o0, 2, %o0 /* IEU1 */
+ sub %o2, 2, %o2 /* IEU0 */
+ sth %g2, [%o0 - 2] /* Store Group + bubble */
+5: andcc %o1, 4, %g0 /* IEU1 */
+216: be,a,pn %xcc, 2f /* CTI */
+ andcc %o2, -128, %g6 /* IEU1 Group */
+ lduw [%o1], %g5 /* Load Group */
+ add %o1, 4, %o1 /* IEU0 */
+ add %o0, 4, %o0 /* IEU1 */
+ sub %o2, 4, %o2 /* IEU0 Group */
+ stw %g5, [%o0 - 4] /* Store */
+ andcc %o2, -128, %g6 /* IEU1 Group */
+2: be,pn %xcc, 215f /* CTI */
+ andcc %o0, 4, %g0 /* IEU1 Group */
+ be,pn %xcc, 82f + 4 /* CTI Group */
+5: MOVE_BIGCHUNK(o1, o0, 0x00, g1, g3, g5, o5)
+ MOVE_BIGCHUNK(o1, o0, 0x20, g1, g3, g5, o5)
+ MOVE_BIGCHUNK(o1, o0, 0x40, g1, g3, g5, o5)
+ MOVE_BIGCHUNK(o1, o0, 0x60, g1, g3, g5, o5)
+35: subcc %g6, 128, %g6 /* IEU1 Group */
+ add %o1, 128, %o1 /* IEU0 */
+ bne,pt %xcc, 5b /* CTI */
+ add %o0, 128, %o0 /* IEU0 Group */
+215: andcc %o2, 0x70, %g6 /* IEU1 Group */
+41: be,pn %xcc, 80f /* CTI */
+ andcc %o2, 8, %g0 /* IEU1 Group */
+ /* Clk1 8-( */
+ /* Clk2 8-( */
+ /* Clk3 8-( */
+ /* Clk4 8-( */
+79: rd %pc, %o5 /* PDU Group */
+ sll %g6, 1, %g5 /* IEU0 Group */
+ add %o1, %g6, %o1 /* IEU1 */
+ sub %o5, %g5, %o5 /* IEU0 Group */
+ jmpl %o5 + %lo(80f - 79b), %g0 /* CTI Group brk forced*/
+ add %o0, %g6, %o0 /* IEU0 Group */
+36: MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g5, o5)
+ MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g5, o5)
+ MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g5, o5)
+ MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g5, o5)
+ MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g5, o5)
+ MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g5, o5)
+ MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g5, o5)
+80: be,pt %xcc, 81f /* CTI */
+ andcc %o2, 4, %g0 /* IEU1 */
+ ldx [%o1], %g2 /* Load Group */
+ add %o0, 8, %o0 /* IEU0 */
+ stw %g2, [%o0 - 0x4] /* Store Group */
+ add %o1, 8, %o1 /* IEU1 */
+ srlx %g2, 32, %g2 /* IEU0 Group */
+ stw %g2, [%o0 - 0x8] /* Store */
+81: be,pt %xcc, 1f /* CTI */
+ andcc %o2, 2, %g0 /* IEU1 Group */
+ lduw [%o1], %g2 /* Load Group */
+ add %o1, 4, %o1 /* IEU0 */
+ stw %g2, [%o0] /* Store Group */
+ add %o0, 4, %o0 /* IEU0 */
+1: be,pt %xcc, 1f /* CTI */
+ andcc %o2, 1, %g0 /* IEU1 Group */
+ lduh [%o1], %g2 /* Load Group */
+ add %o1, 2, %o1 /* IEU0 */
+ sth %g2, [%o0] /* Store Group */
+ add %o0, 2, %o0 /* IEU0 */
+1: be,pt %xcc, 211f /* CTI */
+ nop /* IEU1 */
+ ldub [%o1], %g2 /* Load Group */
+ stb %g2, [%o0] /* Store Group + bubble */
+211: retl
+ mov %g4, %o0
+
+82: MOVE_BIGALIGNCHUNK(o1, o0, 0x00, g1, g3, g5, o5)
+ MOVE_BIGALIGNCHUNK(o1, o0, 0x40, g1, g3, g5, o5)
+37: subcc %g6, 128, %g6 /* IEU1 Group */
+ add %o1, 128, %o1 /* IEU0 */
+ bne,pt %xcc, 82b /* CTI */
+ add %o0, 128, %o0 /* IEU0 Group */
+ andcc %o2, 0x70, %g6 /* IEU1 */
+ be,pn %xcc, 84f /* CTI */
+ andcc %o2, 8, %g0 /* IEU1 Group */
+ /* Clk1 8-( */
+ /* Clk2 8-( */
+ /* Clk3 8-( */
+ /* Clk4 8-( */
+83: rd %pc, %o5 /* PDU Group */
+ add %o1, %g6, %o1 /* IEU0 Group */
+ sub %o5, %g6, %o5 /* IEU1 */
+ jmpl %o5 + %lo(84f - 83b), %g0 /* CTI Group brk forced*/
+ add %o0, %g6, %o0 /* IEU0 Group */
+38: MOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3)
+84: be,pt %xcc, 85f /* CTI Group */
+ andcc %o2, 4, %g0 /* IEU1 */
+ ldx [%o1], %g2 /* Load Group */
+ add %o0, 8, %o0 /* IEU0 */
+ add %o1, 8, %o1 /* IEU0 Group */
+ stx %g2, [%o0 - 0x8] /* Store */
+85: be,pt %xcc, 1f /* CTI */
+ andcc %o2, 2, %g0 /* IEU1 Group */
+ lduw [%o1], %g2 /* Load Group */
+ add %o0, 4, %o0 /* IEU0 */
+ add %o1, 4, %o1 /* IEU0 Group */
+ stw %g2, [%o0 - 0x4] /* Store */
+1: be,pt %xcc, 1f /* CTI */
+ andcc %o2, 1, %g0 /* IEU1 Group */
+ lduh [%o1], %g2 /* Load Group */
+ add %o0, 2, %o0 /* IEU0 */
+ add %o1, 2, %o1 /* IEU0 Group */
+ sth %g2, [%o0 - 0x2] /* Store */
+1: be,pt %xcc, 1f /* CTI */
+ nop /* IEU0 Group */
+ ldub [%o1], %g2 /* Load Group */
+ stb %g2, [%o0] /* Store Group + bubble */
+1: retl
+ mov %g4, %o0
+
+212: brz,pt %g2, 2f /* CTI Group */
+ mov 8, %g1 /* IEU0 */
+ sub %g1, %g2, %g2 /* IEU0 Group */
+ sub %o2, %g2, %o2 /* IEU0 Group */
+1: ldub [%o1], %g5 /* Load Group */
+ add %o1, 1, %o1 /* IEU0 */
+ add %o0, 1, %o0 /* IEU1 */
+ subcc %g2, 1, %g2 /* IEU1 Group */
+ bne,pt %xcc, 1b /* CTI */
+ stb %g5, [%o0 - 1] /* Store */
+2: andn %o2, 7, %g5 /* IEU0 Group */
+ and %o2, 7, %o2 /* IEU1 */
+ fmovd %f0, %f2 /* FPU */
+ alignaddr %o1, %g0, %g1 /* GRU Group */
+ ldd [%g1], %f4 /* Load Group */
+1: ldd [%g1 + 0x8], %f6 /* Load Group */
+ add %g1, 0x8, %g1 /* IEU0 Group */
+ subcc %g5, 8, %g5 /* IEU1 */
+ faligndata %f4, %f6, %f0 /* GRU Group */
+ std %f0, [%o0] /* Store */
+ add %o1, 8, %o1 /* IEU0 Group */
+ be,pn %xcc, 213f /* CTI */
+ add %o0, 8, %o0 /* IEU1 */
+ ldd [%g1 + 0x8], %f4 /* Load Group */
+ add %g1, 8, %g1 /* IEU0 */
+ subcc %g5, 8, %g5 /* IEU1 */
+ faligndata %f6, %f4, %f0 /* GRU Group */
+ std %f0, [%o0] /* Store */
+ add %o1, 8, %o1 /* IEU0 */
+ bne,pn %xcc, 1b /* CTI Group */
+ add %o0, 8, %o0 /* IEU0 */
+213: brz,pn %o2, 214f /* CTI Group */
+ nop /* IEU0 */
+ ldub [%o1], %g5 /* LOAD */
+ add %o1, 1, %o1 /* IEU0 */
+ add %o0, 1, %o0 /* IEU1 */
+ subcc %o2, 1, %o2 /* IEU1 */
+ bne,pt %xcc, 206b /* CTI */
+ stb %g5, [%o0 - 1] /* Store Group */
+214: wr %g0, FPRS_FEF, %fprs
+ retl
+ mov %g4, %o0
+END(memcpy)
+
+ .align 32
+ENTRY(__memmove_slowpath)
+228: andcc %o2, 1, %g0 /* IEU1 Group */
+ be,pt %icc, 2f+4 /* CTI */
+1: ldub [%o1 - 1], %o5 /* LOAD Group */
+ sub %o1, 1, %o1 /* IEU0 */
+ sub %o0, 1, %o0 /* IEU1 */
+ subcc %o2, 1, %o2 /* IEU1 Group */
+ be,pn %xcc, 229f /* CTI */
+ stb %o5, [%o0] /* Store */
+2: ldub [%o1 - 1], %o5 /* LOAD Group */
+ sub %o0, 2, %o0 /* IEU0 */
+ ldub [%o1 - 2], %g5 /* LOAD Group */
+ sub %o1, 2, %o1 /* IEU0 */
+ subcc %o2, 2, %o2 /* IEU1 Group */
+ stb %o5, [%o0 + 1] /* Store */
+ bne,pt %xcc, 2b /* CTI */
+ stb %g5, [%o0] /* Store */
+229: retl
+ mov %g4, %o0
+219: retl
+ nop
+END(__memmove_slowpath)
+
+ .align 32
+ENTRY(memmove)
+#ifndef USE_BPR
+ srl %o2, 0, %o2 /* IEU1 Group */
+#endif
+ brz,pn %o2, 219b /* CTI Group */
+ sub %o0, %o1, %o4 /* IEU0 */
+ cmp %o4, %o2 /* IEU1 Group */
+ bgeu,pt %XCC, 218b /* CTI */
+ mov %o0, %g4 /* IEU0 */
+ add %o0, %o2, %o0 /* IEU0 Group */
+220: add %o1, %o2, %o1 /* IEU1 */
+ cmp %o2, 15 /* IEU1 Group */
+ bleu,pn %xcc, 228b /* CTI */
+ andcc %o0, 7, %g2 /* IEU1 Group */
+ sub %o0, %o1, %g5 /* IEU0 */
+ andcc %g5, 3, %o5 /* IEU1 Group */
+ bne,pn %xcc, 232f /* CTI */
+ andcc %o1, 3, %g0 /* IEU1 Group */
+ be,a,pt %xcc, 236f /* CTI */
+ andcc %o1, 4, %g0 /* IEU1 Group */
+ andcc %o1, 1, %g0 /* IEU1 Group */
+ be,pn %xcc, 4f /* CTI */
+ andcc %o1, 2, %g0 /* IEU1 Group */
+ ldub [%o1 - 1], %g2 /* Load Group */
+ sub %o1, 1, %o1 /* IEU0 */
+ sub %o0, 1, %o0 /* IEU1 */
+ sub %o2, 1, %o2 /* IEU0 Group */
+ be,pn %xcc, 5f /* CTI Group */
+ stb %g2, [%o0] /* Store */
+4: lduh [%o1 - 2], %g2 /* Load Group */
+ sub %o1, 2, %o1 /* IEU0 */
+ sub %o0, 2, %o0 /* IEU1 */
+ sub %o2, 2, %o2 /* IEU0 */
+ sth %g2, [%o0] /* Store Group + bubble */
+5: andcc %o1, 4, %g0 /* IEU1 */
+236: be,a,pn %xcc, 2f /* CTI */
+ andcc %o2, -128, %g6 /* IEU1 Group */
+ lduw [%o1 - 4], %g5 /* Load Group */
+ sub %o1, 4, %o1 /* IEU0 */
+ sub %o0, 4, %o0 /* IEU1 */
+ sub %o2, 4, %o2 /* IEU0 Group */
+ stw %g5, [%o0] /* Store */
+ andcc %o2, -128, %g6 /* IEU1 Group */
+2: be,pn %xcc, 235f /* CTI */
+ andcc %o0, 4, %g0 /* IEU1 Group */
+ be,pn %xcc, 282f + 4 /* CTI Group */
+5: RMOVE_BIGCHUNK(o1, o0, 0x00, g1, g3, g5, o5)
+ RMOVE_BIGCHUNK(o1, o0, 0x20, g1, g3, g5, o5)
+ RMOVE_BIGCHUNK(o1, o0, 0x40, g1, g3, g5, o5)
+ RMOVE_BIGCHUNK(o1, o0, 0x60, g1, g3, g5, o5)
+ subcc %g6, 128, %g6 /* IEU1 Group */
+ sub %o1, 128, %o1 /* IEU0 */
+ bne,pt %xcc, 5b /* CTI */
+ sub %o0, 128, %o0 /* IEU0 Group */
+235: andcc %o2, 0x70, %g6 /* IEU1 Group */
+41: be,pn %xcc, 280f /* CTI */
+ andcc %o2, 8, %g0 /* IEU1 Group */
+ /* Clk1 8-( */
+ /* Clk2 8-( */
+ /* Clk3 8-( */
+ /* Clk4 8-( */
+279: rd %pc, %o5 /* PDU Group */
+ sll %g6, 1, %g5 /* IEU0 Group */
+ sub %o1, %g6, %o1 /* IEU1 */
+ sub %o5, %g5, %o5 /* IEU0 Group */
+ jmpl %o5 + %lo(280f - 279b), %g0 /* CTI Group brk forced*/
+ sub %o0, %g6, %o0 /* IEU0 Group */
+ RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g5, o5)
+280: be,pt %xcc, 281f /* CTI */
+ andcc %o2, 4, %g0 /* IEU1 */
+ ldx [%o1 - 8], %g2 /* Load Group */
+ sub %o0, 8, %o0 /* IEU0 */
+ stw %g2, [%o0 + 4] /* Store Group */
+ sub %o1, 8, %o1 /* IEU1 */
+ srlx %g2, 32, %g2 /* IEU0 Group */
+ stw %g2, [%o0] /* Store */
+281: be,pt %xcc, 1f /* CTI */
+ andcc %o2, 2, %g0 /* IEU1 Group */
+ lduw [%o1 - 4], %g2 /* Load Group */
+ sub %o1, 4, %o1 /* IEU0 */
+ stw %g2, [%o0 - 4] /* Store Group */
+ sub %o0, 4, %o0 /* IEU0 */
+1: be,pt %xcc, 1f /* CTI */
+ andcc %o2, 1, %g0 /* IEU1 Group */
+ lduh [%o1 - 2], %g2 /* Load Group */
+ sub %o1, 2, %o1 /* IEU0 */
+ sth %g2, [%o0 - 2] /* Store Group */
+ sub %o0, 2, %o0 /* IEU0 */
+1: be,pt %xcc, 211f /* CTI */
+ nop /* IEU1 */
+ ldub [%o1 - 1], %g2 /* Load Group */
+ stb %g2, [%o0 - 1] /* Store Group + bubble */
+211: retl
+ mov %g4, %o0
+
+282: RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, g1, g3, g5, o5)
+ RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, g1, g3, g5, o5)
+ subcc %g6, 128, %g6 /* IEU1 Group */
+ sub %o1, 128, %o1 /* IEU0 */
+ bne,pt %xcc, 282b /* CTI */
+ sub %o0, 128, %o0 /* IEU0 Group */
+ andcc %o2, 0x70, %g6 /* IEU1 */
+ be,pn %xcc, 284f /* CTI */
+ andcc %o2, 8, %g0 /* IEU1 Group */
+ /* Clk1 8-( */
+ /* Clk2 8-( */
+ /* Clk3 8-( */
+ /* Clk4 8-( */
+283: rd %pc, %o5 /* PDU Group */
+ sub %o1, %g6, %o1 /* IEU0 Group */
+ sub %o5, %g6, %o5 /* IEU1 */
+ jmpl %o5 + %lo(284f - 283b), %g0 /* CTI Group brk forced*/
+ sub %o0, %g6, %o0 /* IEU0 Group */
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3)
+284: be,pt %xcc, 285f /* CTI Group */
+ andcc %o2, 4, %g0 /* IEU1 */
+ ldx [%o1 - 8], %g2 /* Load Group */
+ sub %o0, 8, %o0 /* IEU0 */
+ sub %o1, 8, %o1 /* IEU0 Group */
+ stx %g2, [%o0] /* Store */
+285: be,pt %xcc, 1f /* CTI */
+ andcc %o2, 2, %g0 /* IEU1 Group */
+ lduw [%o1 - 4], %g2 /* Load Group */
+ sub %o0, 4, %o0 /* IEU0 */
+ sub %o1, 4, %o1 /* IEU0 Group */
+ stw %g2, [%o0] /* Store */
+1: be,pt %xcc, 1f /* CTI */
+ andcc %o2, 1, %g0 /* IEU1 Group */
+ lduh [%o1 - 2], %g2 /* Load Group */
+ sub %o0, 2, %o0 /* IEU0 */
+ sub %o1, 2, %o1 /* IEU0 Group */
+ sth %g2, [%o0] /* Store */
+1: be,pt %xcc, 1f /* CTI */
+ nop /* IEU0 Group */
+ ldub [%o1 - 1], %g2 /* Load Group */
+ stb %g2, [%o0 - 1] /* Store Group + bubble */
+1: retl
+ mov %g4, %o0
+
+232: brz,pt %g2, 2f /* CTI Group */
+ sub %o2, %g2, %o2 /* IEU0 Group */
+1: ldub [%o1 - 1], %g5 /* Load Group */
+ sub %o1, 1, %o1 /* IEU0 */
+ sub %o0, 1, %o0 /* IEU1 */
+ subcc %g2, 1, %g2 /* IEU1 Group */
+ bne,pt %xcc, 1b /* CTI */
+ stb %g5, [%o0] /* Store */
+2: andn %o2, 7, %g5 /* IEU0 Group */
+ and %o2, 7, %o2 /* IEU1 */
+ fmovd %f0, %f2 /* FPU */
+ alignaddr %o1, %g0, %g1 /* GRU Group */
+ ldd [%g1], %f4 /* Load Group */
+1: ldd [%g1 - 8], %f6 /* Load Group */
+ sub %g1, 8, %g1 /* IEU0 Group */
+ subcc %g5, 8, %g5 /* IEU1 */
+ faligndata %f6, %f4, %f0 /* GRU Group */
+ std %f0, [%o0 - 8] /* Store */
+ sub %o1, 8, %o1 /* IEU0 Group */
+ be,pn %xcc, 233f /* CTI */
+ sub %o0, 8, %o0 /* IEU1 */
+ ldd [%g1 - 8], %f4 /* Load Group */
+ sub %g1, 8, %g1 /* IEU0 */
+ subcc %g5, 8, %g5 /* IEU1 */
+ faligndata %f4, %f6, %f0 /* GRU Group */
+ std %f0, [%o0 - 8] /* Store */
+ sub %o1, 8, %o1 /* IEU0 */
+ bne,pn %xcc, 1b /* CTI Group */
+ sub %o0, 8, %o0 /* IEU0 */
+233: brz,pn %o2, 234f /* CTI Group */
+ nop /* IEU0 */
+237: ldub [%o1 - 1], %g5 /* LOAD */
+ sub %o1, 1, %o1 /* IEU0 */
+ sub %o0, 1, %o0 /* IEU1 */
+ subcc %o2, 1, %o2 /* IEU1 */
+ bne,pt %xcc, 237b /* CTI */
+ stb %g5, [%o0] /* Store Group */
+234: wr %g0, FPRS_FEF, %fprs
+ retl
+ mov %g4, %o0
+END(memmove)
+
+#ifdef USE_BPR
+weak_alias (memcpy, __align_cpy_1)
+weak_alias (memcpy, __align_cpy_2)
+#endif
+libc_hidden_builtin_def (memcpy)
+libc_hidden_builtin_def (memmove)
diff --git a/libc/sysdeps/sparc/sparc64/memmove.c b/libc/sysdeps/sparc/sparc64/memmove.c
new file mode 100644
index 000000000..a8d2d4994
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/memmove.c
@@ -0,0 +1 @@
+/* memmove is in memcpy.S */
diff --git a/libc/sysdeps/sparc/sparc64/memset.S b/libc/sysdeps/sparc/sparc64/memset.S
new file mode 100644
index 000000000..99624ba9d
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/memset.S
@@ -0,0 +1,315 @@
+/* Set a block of memory to some byte value.
+ For UltraSPARC.
+ Copyright (C) 1996, 97, 98, 99, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller (davem@caip.rutgers.edu) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define XCC xcc
+#define USE_BPR
+#endif
+#define FPRS_FEF 4
+
+#define SET_BLOCKS(base, offset, source) \
+ stx source, [base - offset - 0x18]; \
+ stx source, [base - offset - 0x10]; \
+ stx source, [base - offset - 0x08]; \
+ stx source, [base - offset - 0x00];
+
+ /* Well, memset is a lot easier to get right than bcopy... */
+ .text
+ .align 32
+ENTRY(memset)
+ andcc %o1, 0xff, %o1
+ mov %o0, %o5
+ be,a,pt %icc, 50f
+#ifndef USE_BPR
+ srl %o2, 0, %o1
+#else
+ mov %o2, %o1
+#endif
+ cmp %o2, 7
+#ifndef USE_BPR
+ srl %o2, 0, %o2
+#endif
+ bleu,pn %XCC, 17f
+ andcc %o0, 3, %g5
+ be,pt %xcc, 4f
+ and %o1, 0xff, %o1
+ cmp %g5, 3
+ be,pn %xcc, 2f
+ stb %o1, [%o0 + 0x00]
+ cmp %g5, 2
+ be,pt %xcc, 2f
+ stb %o1, [%o0 + 0x01]
+ stb %o1, [%o0 + 0x02]
+2: sub %g5, 4, %g5
+ sub %o0, %g5, %o0
+ add %o2, %g5, %o2
+4: sllx %o1, 8, %g1
+ andcc %o0, 4, %g0
+ or %o1, %g1, %o1
+ sllx %o1, 16, %g1
+ or %o1, %g1, %o1
+ be,pt %xcc, 2f
+ sllx %o1, 32, %g1
+ stw %o1, [%o0]
+ sub %o2, 4, %o2
+ add %o0, 4, %o0
+2: cmp %o2, 128
+ or %o1, %g1, %o1
+ blu,pn %xcc, 9f
+ andcc %o0, 0x38, %g5
+ be,pn %icc, 6f
+ mov 64, %o4
+ andcc %o0, 8, %g0
+ be,pn %icc, 1f
+ sub %o4, %g5, %o4
+ stx %o1, [%o0]
+ add %o0, 8, %o0
+1: andcc %o4, 16, %g0
+ be,pn %icc, 1f
+ sub %o2, %o4, %o2
+ stx %o1, [%o0]
+ stx %o1, [%o0 + 8]
+ add %o0, 16, %o0
+1: andcc %o4, 32, %g0
+ be,pn %icc, 7f
+ andncc %o2, 0x3f, %o3
+ stw %o1, [%o0]
+ stw %o1, [%o0 + 4]
+ stw %o1, [%o0 + 8]
+ stw %o1, [%o0 + 12]
+ stw %o1, [%o0 + 16]
+ stw %o1, [%o0 + 20]
+ stw %o1, [%o0 + 24]
+ stw %o1, [%o0 + 28]
+ add %o0, 32, %o0
+7: be,pn %xcc, 9f
+ nop
+ ldd [%o0 - 8], %f0
+18: wr %g0, ASI_BLK_P, %asi
+ membar #StoreStore | #LoadStore
+ andcc %o3, 0xc0, %g5
+ and %o2, 0x3f, %o2
+ fmovd %f0, %f2
+ fmovd %f0, %f4
+ andn %o3, 0xff, %o3
+ fmovd %f0, %f6
+ cmp %g5, 64
+ fmovd %f0, %f8
+ fmovd %f0, %f10
+ fmovd %f0, %f12
+ brz,pn %g5, 10f
+ fmovd %f0, %f14
+ be,pn %icc, 2f
+ stda %f0, [%o0 + 0x00] %asi
+ cmp %g5, 128
+ be,pn %icc, 2f
+ stda %f0, [%o0 + 0x40] %asi
+ stda %f0, [%o0 + 0x80] %asi
+2: brz,pn %o3, 12f
+ add %o0, %g5, %o0
+10: stda %f0, [%o0 + 0x00] %asi
+ stda %f0, [%o0 + 0x40] %asi
+ stda %f0, [%o0 + 0x80] %asi
+ stda %f0, [%o0 + 0xc0] %asi
+11: subcc %o3, 256, %o3
+ bne,pt %xcc, 10b
+ add %o0, 256, %o0
+12: wr %g0, FPRS_FEF, %fprs
+ membar #StoreLoad | #StoreStore
+9: andcc %o2, 0x78, %g5
+ be,pn %xcc, 13f
+ andcc %o2, 7, %o2
+14: rd %pc, %o4
+ srl %g5, 1, %o3
+ sub %o4, %o3, %o4
+ jmpl %o4 + (13f - 14b), %g0
+ add %o0, %g5, %o0
+12: SET_BLOCKS (%o0, 0x68, %o1)
+ SET_BLOCKS (%o0, 0x48, %o1)
+ SET_BLOCKS (%o0, 0x28, %o1)
+ SET_BLOCKS (%o0, 0x08, %o1)
+13: be,pn %xcc, 8f
+ andcc %o2, 4, %g0
+ be,pn %xcc, 1f
+ andcc %o2, 2, %g0
+ stw %o1, [%o0]
+ add %o0, 4, %o0
+1: be,pn %xcc, 1f
+ andcc %o2, 1, %g0
+ sth %o1, [%o0]
+ add %o0, 2, %o0
+1: bne,a,pn %xcc, 8f
+ stb %o1, [%o0]
+8: retl
+ mov %o5, %o0
+17: brz,pn %o2, 0f
+8: add %o0, 1, %o0
+ subcc %o2, 1, %o2
+ bne,pt %xcc, 8b
+ stb %o1, [%o0 - 1]
+0: retl
+ mov %o5, %o0
+
+6: stx %o1, [%o0]
+ andncc %o2, 0x3f, %o3
+ be,pn %xcc, 9b
+ nop
+ ba,pt %xcc, 18b
+ ldd [%o0], %f0
+END(memset)
+libc_hidden_builtin_def (memset)
+
+#define ZERO_BLOCKS(base, offset, source) \
+ stx source, [base - offset - 0x38]; \
+ stx source, [base - offset - 0x30]; \
+ stx source, [base - offset - 0x28]; \
+ stx source, [base - offset - 0x20]; \
+ stx source, [base - offset - 0x18]; \
+ stx source, [base - offset - 0x10]; \
+ stx source, [base - offset - 0x08]; \
+ stx source, [base - offset - 0x00];
+
+ .text
+ .align 32
+ENTRY(__bzero)
+#ifndef USE_BPR
+ srl %o1, 0, %o1
+#endif
+ mov %o0, %o5
+50: cmp %o1, 7
+ bleu,pn %xcc, 17f
+ andcc %o0, 3, %o2
+ be,a,pt %xcc, 4f
+ andcc %o0, 4, %g0
+ cmp %o2, 3
+ be,pn %xcc, 2f
+ stb %g0, [%o0 + 0x00]
+ cmp %o2, 2
+ be,pt %xcc, 2f
+ stb %g0, [%o0 + 0x01]
+ stb %g0, [%o0 + 0x02]
+2: sub %o2, 4, %o2
+ sub %o0, %o2, %o0
+ add %o1, %o2, %o1
+ andcc %o0, 4, %g0
+4: be,pt %xcc, 2f
+ cmp %o1, 128
+ stw %g0, [%o0]
+ sub %o1, 4, %o1
+ add %o0, 4, %o0
+2: blu,pn %xcc, 9f
+ andcc %o0, 0x38, %o2
+ be,pn %icc, 6f
+ mov 64, %o4
+ andcc %o0, 8, %g0
+ be,pn %icc, 1f
+ sub %o4, %o2, %o4
+ stx %g0, [%o0]
+ add %o0, 8, %o0
+1: andcc %o4, 16, %g0
+ be,pn %icc, 1f
+ sub %o1, %o4, %o1
+ stx %g0, [%o0]
+ stx %g0, [%o0 + 8]
+ add %o0, 16, %o0
+1: andcc %o4, 32, %g0
+ be,pn %icc, 7f
+ andncc %o1, 0x3f, %o3
+ stx %g0, [%o0]
+ stx %g0, [%o0 + 8]
+ stx %g0, [%o0 + 16]
+ stx %g0, [%o0 + 24]
+ add %o0, 32, %o0
+6: andncc %o1, 0x3f, %o3
+7: be,pn %xcc, 9f
+ wr %g0, ASI_BLK_P, %asi
+ membar #StoreLoad | #StoreStore | #LoadStore
+ fzero %f0
+ andcc %o3, 0xc0, %o2
+ and %o1, 0x3f, %o1
+ fzero %f2
+ andn %o3, 0xff, %o3
+ faddd %f0, %f2, %f4
+ fmuld %f0, %f2, %f6
+ cmp %o2, 64
+ faddd %f0, %f2, %f8
+ fmuld %f0, %f2, %f10
+ faddd %f0, %f2, %f12
+ brz,pn %o2, 10f
+ fmuld %f0, %f2, %f14
+ be,pn %icc, 2f
+ stda %f0, [%o0 + 0x00] %asi
+ cmp %o2, 128
+ be,pn %icc, 2f
+ stda %f0, [%o0 + 0x40] %asi
+ stda %f0, [%o0 + 0x80] %asi
+2: brz,pn %o3, 12f
+ add %o0, %o2, %o0
+10: stda %f0, [%o0 + 0x00] %asi
+ stda %f0, [%o0 + 0x40] %asi
+ stda %f0, [%o0 + 0x80] %asi
+ stda %f0, [%o0 + 0xc0] %asi
+11: subcc %o3, 256, %o3
+ bne,pt %xcc, 10b
+ add %o0, 256, %o0
+12: wr %g0, FPRS_FEF, %fprs
+ membar #StoreLoad | #StoreStore
+9: andcc %o1, 0xf8, %o2
+ be,pn %xcc, 13f
+ andcc %o1, 7, %o1
+14: rd %pc, %o4
+ srl %o2, 1, %o3
+ sub %o4, %o3, %o4
+ jmpl %o4 + (13f - 14b), %g0
+ add %o0, %o2, %o0
+12: ZERO_BLOCKS (%o0, 0xc8, %g0)
+ ZERO_BLOCKS (%o0, 0x88, %g0)
+ ZERO_BLOCKS (%o0, 0x48, %g0)
+ ZERO_BLOCKS (%o0, 0x08, %g0)
+13: be,pn %xcc, 8f
+ andcc %o1, 4, %g0
+ be,pn %xcc, 1f
+ andcc %o1, 2, %g0
+ stw %g0, [%o0]
+ add %o0, 4, %o0
+1: be,pn %xcc, 1f
+ andcc %o1, 1, %g0
+ sth %g0, [%o0]
+ add %o0, 2, %o0
+1: bne,a,pn %xcc, 8f
+ stb %g0, [%o0]
+8: retl
+ mov %o5, %o0
+17: be,pn %xcc, 13b
+ orcc %o1, 0, %g0
+ be,pn %xcc, 0f
+8: add %o0, 1, %o0
+ subcc %o1, 1, %o1
+ bne,pt %xcc, 8b
+ stb %g0, [%o0 - 1]
+0: retl
+ mov %o5, %o0
+END(__bzero)
+
+weak_alias (__bzero, bzero)
diff --git a/libc/sysdeps/sparc/sparc64/mul_1.S b/libc/sysdeps/sparc/sparc64/mul_1.S
new file mode 100644
index 000000000..49f83464c
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/mul_1.S
@@ -0,0 +1,83 @@
+/* SPARC v9 __mpn_mul_1 -- Multiply a limb vector with a single limb and
+ store the product in a second limb vector.
+
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include <sysdep.h>
+
+
+/* INPUT PARAMETERS
+ res_ptr o0
+ s1_ptr o1
+ size o2
+ s2_limb o3 */
+
+ENTRY(__mpn_mul_1)
+ !#PROLOGUE# 0
+ save %sp,-192,%sp
+ !#PROLOGUE# 1
+
+ sub %g0,%i2,%o7
+ sllx %o7,3,%g5
+ sub %i1,%g5,%o3
+ sub %i0,%g5,%o4
+ mov 0,%o0 ! zero cy_limb
+
+ srl %i3,0,%o1 ! extract low 32 bits of s2_limb
+ srlx %i3,32,%i3 ! extract high 32 bits of s2_limb
+ mov 1,%o2
+ sllx %o2,32,%o2 ! o2 = 0x100000000
+
+ ! hi !
+ ! mid-1 !
+ ! mid-2 !
+ ! lo !
+.Loop:
+ sllx %o7,3,%g1
+ ldx [%o3+%g1],%g5
+ srl %g5,0,%i0 ! zero hi bits
+ srlx %g5,32,%g5
+ mulx %o1,%i0,%i4 ! lo product
+ mulx %i3,%i0,%i1 ! mid-1 product
+ mulx %o1,%g5,%l2 ! mid-2 product
+ mulx %i3,%g5,%i5 ! hi product
+ srlx %i4,32,%i0 ! extract high 32 bits of lo product...
+ add %i1,%i0,%i1 ! ...and add it to the mid-1 product
+ addcc %i1,%l2,%i1 ! add mid products
+ mov 0,%l0 ! we need the carry from that add...
+ movcs %xcc,%o2,%l0 ! ...compute it and...
+ add %i5,%l0,%i5 ! ...add to bit 32 of the hi product
+ sllx %i1,32,%i0 ! align low bits of mid product
+ srl %i4,0,%g5 ! zero high 32 bits of lo product
+ add %i0,%g5,%i0 ! combine into low 64 bits of result
+ srlx %i1,32,%i1 ! extract high bits of mid product...
+ add %i5,%i1,%i1 ! ...and add them to the high result
+ addcc %i0,%o0,%i0 ! add cy_limb to low 64 bits of result
+ mov 0,%g5
+ movcs %xcc,1,%g5
+ addcc %o7,1,%o7
+ stx %i0,[%o4+%g1]
+ bne,pt %xcc,.Loop
+ add %i1,%g5,%o0 ! compute new cy_limb
+
+ jmpl %i7+8,%g0
+ restore %o0,%g0,%o0
+
+END(__mpn_mul_1)
diff --git a/libc/sysdeps/sparc/sparc64/rawmemchr.S b/libc/sysdeps/sparc/sparc64/rawmemchr.S
new file mode 100644
index 000000000..de2e780c9
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/rawmemchr.S
@@ -0,0 +1,179 @@
+/* rawmemchr (str, ch) -- Return pointer to first occurrence of CH in STR.
+ For SPARC v9.
+ Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>.
+ This version is developed using the same algorithm as the fast C
+ version which carries the following introduction:
+ Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+ with help from Dan Sahlin (dan@sics.se) and
+ commentary by Jim Blandy (jimb@ai.mit.edu);
+ adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+ and implemented by Roland McGrath (roland@ai.mit.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define XCC xcc
+#define USE_BPR
+ .register %g2, #scratch
+ .register %g3, #scratch
+#endif
+
+ /* Normally, this uses
+ ((xword - 0x0101010101010101) & 0x8080808080808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 32
+ENTRY(__rawmemchr)
+ and %o1, 0xff, %o1 /* IEU0 Group */
+ sethi %hi(0x01010101), %g1 /* IEU1 */
+ ldub [%o0], %o3 /* Load */
+ sll %o1, 8, %o4 /* IEU0 Group */
+
+ or %g1, %lo(0x01010101), %g1 /* IEU1 */
+ sllx %g1, 32, %g2 /* IEU0 Group */
+ or %o4, %o1, %o4 /* IEU1 */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+
+ sll %o4, 16, %g5 /* IEU0 */
+ or %o4, %g5, %o4 /* IEU0 Group */
+ or %g1, %g2, %g1 /* IEU1 */
+ bne,pn %icc, 32f /* CTI */
+
+ sllx %o4, 32, %g5 /* IEU0 Group */
+ cmp %o3, %o1 /* IEU1 */
+ be,pn %icc, 30f /* CTI */
+ sllx %g1, 7, %g2 /* IEU0 Group */
+
+18: ldx [%o0], %o3 /* Load */
+ or %o4, %g5, %o4 /* IEU1 */
+ add %o0, 8, %o0 /* IEU0 Group */
+19: xor %o3, %o4, %o3 /* IEU0 Group */
+
+ sub %o3, %g1, %o2 /* IEU0 Group */
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o2, %o3, %o5 /* IEU0 Group */
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ andcc %o5, %g2, %g0 /* IEU1 Group */
+#else
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ andcc %o2, %g2, %g0 /* IEU1 Group */
+#endif
+ be,pt %xcc, 19b /* CTI */
+
+ add %o0, 8, %o0 /* IEU0 */
+ addcc %o2, %g1, %g3 /* IEU1 Group */
+ srlx %o2, 32, %o2 /* IEU0 */
+20: andcc %o2, %g2, %g0 /* IEU1 Group */
+
+ be,pn %xcc, 21f /* CTI */
+ srlx %g3, 56, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 29f /* CTI */
+
+ srlx %g3, 48, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 28f /* CTI */
+ srlx %g3, 40, %o2 /* IEU0 */
+
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 27f /* CTI */
+ srlx %g3, 32, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 26f /* CTI */
+21: srlx %g3, 24, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 25f /* CTI */
+
+ srlx %g3, 16, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 24f /* CTI */
+ srlx %g3, 8, %o2 /* IEU0 */
+
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 23f /* CTI */
+ xor %o3, %o4, %o3 /* IEU0 */
+ andcc %g3, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 22f /* CTI */
+ sub %o3, %g1, %o2 /* IEU0 */
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ andcc %o2, %g2, %g0 /* IEU1 Group */
+
+ be,pt %xcc, 19b /* CTI */
+ add %o0, 8, %o0 /* IEU0 */
+ addcc %o2, %g1, %g3 /* IEU1 Group */
+ ba,pt %xcc, 20b /* CTI */
+
+ srlx %o2, 32, %o2 /* IEU0 */
+
+ .align 16
+22: retl /* CTI+IEU1 Group */
+ add %o0, -9, %o0 /* IEU0 */
+23: retl /* CTI+IEU1 Group */
+ add %o0, -10, %o0 /* IEU0 */
+
+24: retl /* CTI+IEU1 Group */
+ add %o0, -11, %o0 /* IEU0 */
+25: retl /* CTI+IEU1 Group */
+ add %o0, -12, %o0 /* IEU0 */
+
+26: retl /* CTI+IEU1 Group */
+ add %o0, -13, %o0 /* IEU0 */
+27: retl /* CTI+IEU1 Group */
+ add %o0, -14, %o0 /* IEU0 */
+
+28: retl /* CTI+IEU1 Group */
+ add %o0, -15, %o0 /* IEU0 */
+29: retl /* CTI+IEU1 Group */
+ add %o0, -16, %o0 /* IEU0 */
+
+30: retl /* CTI+IEU1 Group */
+ nop /* IEU0 */
+
+ .align 16
+32: andcc %o0, 7, %g0 /* IEU1 Group */
+ be,a,pn %icc, 18b /* CTI */
+ sllx %g1, 7, %g2 /* IEU0 */
+ add %o0, 1, %o0 /* IEU0 Group */
+
+ cmp %o3, %o1 /* IEU1 */
+ bne,a,pt %icc, 32b /* CTI */
+ lduba [%o0] ASI_PNF, %o3 /* Load */
+ retl /* CTI+IEU1 Group */
+
+ add %o0, -1, %o0 /* IEU0 */
+END(__rawmemchr)
+
+libc_hidden_def (__rawmemchr)
+weak_alias (__rawmemchr, rawmemchr)
diff --git a/libc/sysdeps/sparc/sparc64/rshift.S b/libc/sysdeps/sparc/sparc64/rshift.S
new file mode 100644
index 000000000..cadd890b8
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/rshift.S
@@ -0,0 +1,93 @@
+/* SPARC v9 __mpn_rshift --
+
+ Copyright (C) 1996, 1999 Free Software Foundation, Inc.
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include <sysdep.h>
+
+/* INPUT PARAMETERS
+ res_ptr %o0
+ src_ptr %o1
+ size %o2
+ cnt %o3 */
+
+ .register %g2, #scratch
+ .register %g3, #scratch
+
+ENTRY(__mpn_rshift)
+ ldx [%o1],%g2 ! load first limb
+ sub %g0,%o3,%o5 ! negate shift count
+ add %o2,-1,%o2
+ andcc %o2,4-1,%g4 ! number of limbs in first loop
+ sllx %g2,%o5,%g1 ! compute function result
+ be,pn %xcc,.L0 ! if multiple of 4 limbs, skip first loop
+ mov %g1,%g5
+
+ sub %o2,%g4,%o2 ! adjust count for main loop
+
+.Loop0: ldx [%o1+8],%g3
+ add %o0,8,%o0
+ add %o1,8,%o1
+ srlx %g2,%o3,%o4
+ addcc %g4,-1,%g4
+ sllx %g3,%o5,%g1
+ mov %g3,%g2
+ or %o4,%g1,%o4
+ bne,pt %xcc,.Loop0
+ stx %o4,[%o0-8]
+
+.L0: brz,pn %o2,.Lend
+ nop
+
+.Loop: ldx [%o1+8],%g3
+ add %o0,32,%o0
+ srlx %g2,%o3,%o4
+ addcc %o2,-4,%o2
+ sllx %g3,%o5,%g1
+
+ ldx [%o1+16],%g2
+ srlx %g3,%o3,%g4
+ or %o4,%g1,%o4
+ stx %o4,[%o0-32]
+ sllx %g2,%o5,%g1
+
+ ldx [%o1+24],%g3
+ srlx %g2,%o3,%o4
+ or %g4,%g1,%g4
+ stx %g4,[%o0-24]
+ sllx %g3,%o5,%g1
+
+ ldx [%o1+32],%g2
+ srlx %g3,%o3,%g4
+ or %o4,%g1,%o4
+ stx %o4,[%o0-16]
+ sllx %g2,%o5,%g1
+
+ add %o1,32,%o1
+ or %g4,%g1,%g4
+ bne,pt %xcc,.Loop
+ stx %g4,[%o0-8]
+
+.Lend: srlx %g2,%o3,%g2
+ stx %g2,[%o0-0]
+
+ jmpl %o7+8,%g0
+ mov %g5,%o0
+
+END(__mpn_rshift)
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/Makefile b/libc/sysdeps/sparc/sparc64/soft-fp/Makefile
new file mode 100644
index 000000000..efc53b3c0
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/Makefile
@@ -0,0 +1,34 @@
+# Software floating-point emulation.
+# Makefile for SPARC v9 ABI mandated long double utility
+# functions (_Qp_*).
+# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+#
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifeq ($(subdir),soft-fp)
+sparc64-quad-routines := qp_add qp_cmp qp_cmpe qp_div qp_dtoq qp_feq qp_fge \
+ qp_fgt qp_fle qp_flt qp_fne qp_itoq qp_mul qp_neg qp_qtod qp_qtoi \
+ qp_qtos qp_qtoui qp_qtoux qp_qtox qp_sqrt qp_stoq qp_sub qp_uitoq \
+ qp_uxtoq qp_xtoq qp_util
+sysdep_routines += $(sparc64-quad-routines)
+endif
+
+ifeq ($(subdir),math)
+CPPFLAGS += -I../soft-fp/
+endif
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/Versions b/libc/sysdeps/sparc/sparc64/soft-fp/Versions
new file mode 100644
index 000000000..440482752
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/Versions
@@ -0,0 +1,8 @@
+libc {
+ GLIBC_2.2 {
+ _Qp_add; _Qp_cmp; _Qp_cmpe; _Qp_div; _Qp_dtoq; _Qp_feq; _Qp_fge; _Qp_fgt;
+ _Qp_fle; _Qp_flt; _Qp_fne; _Qp_itoq; _Qp_mul; _Qp_neg; _Qp_qtod; _Qp_qtoi;
+ _Qp_qtos; _Qp_qtoui; _Qp_qtoux; _Qp_qtox; _Qp_sqrt; _Qp_stoq; _Qp_sub;
+ _Qp_uitoq; _Qp_uxtoq; _Qp_xtoq; __Qp_handle_exceptions;
+ }
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_add.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_add.c
new file mode 100644
index 000000000..eced23fad
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_add.c
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+ (*c) = (*a) + (*b)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_add(long double *c, const long double *a, const long double *b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_QP(A, a);
+ FP_UNPACK_SEMIRAW_QP(B, b);
+ FP_ADD_Q(C, A, B);
+ FP_PACK_SEMIRAW_QP(c, C);
+ QP_HANDLE_EXCEPTIONS(__asm (
+" ldd [%1], %%f52\n"
+" ldd [%1+8], %%f54\n"
+" ldd [%2], %%f56\n"
+" ldd [%2+8], %%f58\n"
+" faddq %%f52, %%f56, %%f60\n"
+" std %%f60, [%0]\n"
+" std %%f62, [%0+8]\n"
+" " : : "r" (c), "r" (a), "r" (b) : QP_CLOBBER));
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_cmp.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_cmp.c
new file mode 100644
index 000000000..06adc0fe2
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_cmp.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Compare (*a) and (*b), return float condition code.
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_cmp(const long double *a, const long double *b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_QP(A, a);
+ FP_UNPACK_RAW_QP(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == -1) r = 2;
+ if (r == 3 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ QP_HANDLE_EXCEPTIONS(
+ __asm (
+" ldd [%0], %%f52\n"
+" ldd [%0+8], %%f54\n"
+" ldd [%1], %%f56\n"
+" ldd [%1+8], %%f58\n"
+" fcmpq %%fcc3, %%f52, %%f56\n"
+" " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+ _FPU_GETCW(_fcw);
+ r = ((_fcw >> 36) & 3));
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_cmpe.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_cmpe.c
new file mode 100644
index 000000000..5bfde4db9
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_cmpe.c
@@ -0,0 +1,52 @@
+/* Software floating-point emulation.
+ Compare (*a) and (*b), return float condition code.
+ Signal exception (unless masked) if unordered.
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_cmpe(const long double *a, const long double *b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_QP(A, a);
+ FP_UNPACK_RAW_QP(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == -1) r = 2;
+ if (r == 3)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ QP_HANDLE_EXCEPTIONS(
+ __asm (
+" ldd [%0], %%f52\n"
+" ldd [%0+8], %%f54\n"
+" ldd [%1], %%f56\n"
+" ldd [%1+8], %%f58\n"
+" fcmpeq %%fcc3, %%f52, %%f56\n"
+" " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+ _FPU_GETCW(_fcw);
+ r = ((_fcw >> 36) & 3));
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_div.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_div.c
new file mode 100644
index 000000000..029cade98
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_div.c
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+ (*c) = (*a) / (*b)
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_div(long double *c, const long double *a, const long double *b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_QP(A, a);
+ FP_UNPACK_QP(B, b);
+ FP_DIV_Q(C, A, B);
+ FP_PACK_QP(c, C);
+ QP_HANDLE_EXCEPTIONS(__asm (
+" ldd [%1], %%f52\n"
+" ldd [%1+8], %%f54\n"
+" ldd [%2], %%f56\n"
+" ldd [%2+8], %%f58\n"
+" fdivq %%f52, %%f56, %%f60\n"
+" std %%f60, [%0]\n"
+" std %%f62, [%0+8]\n"
+" " : : "r" (c), "r" (a), "r" (b) : QP_CLOBBER));
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_dtoq.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_dtoq.c
new file mode 100644
index 000000000..63f3d742a
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_dtoq.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ (*c) = (long double)(a)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+void _Qp_dtoq(long double *c, const double a)
+{
+ FP_DECL_EX;
+ FP_DECL_D(A);
+ FP_DECL_Q(C);
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_D(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_EXTEND(Q,D,4,2,C,A);
+#else
+ FP_EXTEND(Q,D,2,1,C,A);
+#endif
+ FP_PACK_RAW_QP(c, C);
+ QP_HANDLE_EXCEPTIONS(__asm (
+" fdtoq %1, %%f60\n"
+" std %%f60, [%0]\n"
+" std %%f62, [%0+8]\n"
+" " : : "r" (c), "e" (a) : QP_CLOBBER));
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_feq.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_feq.c
new file mode 100644
index 000000000..809b0cb3d
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_feq.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 1 if (*a) == (*b)
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_feq(const long double *a, const long double *b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_QP(A, a);
+ FP_UNPACK_RAW_QP(B, b);
+ FP_CMP_EQ_Q(r, A, B);
+ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+
+ QP_HANDLE_EXCEPTIONS(
+ __asm (
+" ldd [%0], %%f52\n"
+" ldd [%0+8], %%f54\n"
+" ldd [%1], %%f56\n"
+" ldd [%1+8], %%f58\n"
+" fcmpq %%fcc3, %%f52, %%f56\n"
+" " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+ _FPU_GETCW(_fcw);
+ r = ((_fcw >> 36) & 3));
+
+ return !r;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_fge.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_fge.c
new file mode 100644
index 000000000..9d73aaeb5
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_fge.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 1 if (*a) >= (*b)
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_fge(const long double *a, const long double *b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_QP(A, a);
+ FP_UNPACK_RAW_QP(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == 3)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+
+ QP_HANDLE_EXCEPTIONS(
+ __asm (
+" ldd [%0], %%f52\n"
+" ldd [%0+8], %%f54\n"
+" ldd [%1], %%f56\n"
+" ldd [%1+8], %%f58\n"
+" fcmpeq %%fcc3, %%f52, %%f56\n"
+" " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+ _FPU_GETCW(_fcw);
+ r = ((_fcw >> 36) & 1));
+
+ return (r <= 0);
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_fgt.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_fgt.c
new file mode 100644
index 000000000..f9a219f57
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_fgt.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 1 if (*a) > (*b)
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_fgt(const long double *a, const long double *b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_QP(A, a);
+ FP_UNPACK_RAW_QP(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == 3)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+
+ QP_HANDLE_EXCEPTIONS(
+ __asm (
+" ldd [%0], %%f52\n"
+" ldd [%0+8], %%f54\n"
+" ldd [%1], %%f56\n"
+" ldd [%1+8], %%f58\n"
+" fcmpeq %%fcc3, %%f52, %%f56\n"
+" " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+ _FPU_GETCW(_fcw);
+ r = ((_fcw >> 36) & 3) - 3);
+
+ return (r == -1);
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_fle.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_fle.c
new file mode 100644
index 000000000..bdc651945
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_fle.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 1 if (*a) <= (*b)
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_fle(const long double *a, const long double *b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_QP(A, a);
+ FP_UNPACK_RAW_QP(B, b);
+ FP_CMP_Q(r, B, A, -2);
+ if (r == -2)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+
+ QP_HANDLE_EXCEPTIONS(
+ __asm (
+" ldd [%0], %%f52\n"
+" ldd [%0+8], %%f54\n"
+" ldd [%1], %%f56\n"
+" ldd [%1+8], %%f58\n"
+" fcmpeq %%fcc3, %%f52, %%f56\n"
+" " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+ _FPU_GETCW(_fcw);
+ r = ((_fcw >> 36) & 2) ? -1 : 0);
+
+ return (r >= 0);
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_flt.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_flt.c
new file mode 100644
index 000000000..cdf611d07
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_flt.c
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+ Return 1 if (*a) < (*b)
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_flt(const long double *a, const long double *b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_QP(A, a);
+ FP_UNPACK_RAW_QP(B, b);
+ FP_CMP_Q(r, B, A, 3);
+ if (r == 3)
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+
+ QP_HANDLE_EXCEPTIONS(
+ __asm (
+" ldd [%0], %%f52\n"
+" ldd [%0+8], %%f54\n"
+" ldd [%1], %%f56\n"
+" ldd [%1+8], %%f58\n"
+" fcmpeq %%fcc3, %%f52, %%f56\n"
+" " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+ _FPU_GETCW(_fcw);
+ r = ((_fcw >> 36) & 3));
+
+ return (r == 1);
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_fne.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_fne.c
new file mode 100644
index 000000000..c21de533b
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_fne.c
@@ -0,0 +1,52 @@
+/* Software floating-point emulation.
+ Return 1 if (*a) != (*b)
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_fne(const long double *a, const long double *b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B);
+ int r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_QP(A, a);
+ FP_UNPACK_RAW_QP(B, b);
+ FP_CMP_EQ_Q(r, A, B);
+ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+
+ QP_HANDLE_EXCEPTIONS(
+ __asm (
+" ldd [%0], %%f52\n"
+" ldd [%0+8], %%f54\n"
+" ldd [%1], %%f56\n"
+" ldd [%1+8], %%f58\n"
+" fcmpq %%fcc3, %%f52, %%f56\n"
+" " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+ _FPU_GETCW(_fcw);
+ r = ((_fcw >> 36) & 3) != 0);
+
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_itoq.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_itoq.c
new file mode 100644
index 000000000..310d70c77
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_itoq.c
@@ -0,0 +1,35 @@
+/* Software floating-point emulation.
+ (*c) = (long double)(a)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_itoq(long double *c, const int a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ int b = a;
+
+ FP_FROM_INT_Q(C, b, 32, unsigned int);
+ FP_PACK_RAW_QP(c, C);
+ QP_NO_EXCEPTIONS;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_mul.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_mul.c
new file mode 100644
index 000000000..d36680444
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_mul.c
@@ -0,0 +1,50 @@
+/* Software floating-point emulation.
+ (*c) = (*a) * (*b)
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* As QP_HANDLE_EXCEPTIONS reloads FPU control word anyway,
+ avoid doing it twice. */
+#define _FP_MUL_MEAT_RESET_FE do {} while (0)
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_mul(long double *c, const long double *a, const long double *b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_QP(A, a);
+ FP_UNPACK_QP(B, b);
+ FP_MUL_Q(C, A, B);
+ FP_PACK_QP(c, C);
+ QP_HANDLE_EXCEPTIONS(
+ _FPU_SETCW(_fcw);
+ __asm (
+" ldd [%1], %%f52\n"
+" ldd [%1+8], %%f54\n"
+" ldd [%2], %%f56\n"
+" ldd [%2+8], %%f58\n"
+" fmulq %%f52, %%f56, %%f60\n"
+" std %%f60, [%0]\n"
+" std %%f62, [%0+8]\n"
+" " : : "r" (c), "r" (a), "r" (b) : QP_CLOBBER));
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_neg.S b/libc/sysdeps/sparc/sparc64/soft-fp/qp_neg.S
new file mode 100644
index 000000000..5d4bd917f
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_neg.S
@@ -0,0 +1,31 @@
+/* Quad floating-point emulation.
+ (*c) = !(*a)
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY(_Qp_neg)
+ ldd [%o1], %f60
+ ldd [%o1 + 8], %f62
+ fnegd %f60, %f60
+ std %f60, [%o0]
+ jmpl %o7 + 8, %g0
+ std %f62, [%o0 + 8]
+END(_Qp_neg)
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtod.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtod.c
new file mode 100644
index 000000000..2e5edadcb
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtod.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return (double)(*a)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+double _Qp_qtod(const long double *a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ FP_DECL_D(R);
+ double r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_QP(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_TRUNC(D,Q,2,4,R,A);
+#else
+ FP_TRUNC(D,Q,1,2,R,A);
+#endif
+ FP_PACK_SEMIRAW_D(r, R);
+ QP_HANDLE_EXCEPTIONS(__asm (
+" ldd [%1], %%f52\n"
+" ldd [%1+8], %%f54\n"
+" fqtod %%f52, %0\n"
+" " : "=&e" (r) : "r" (a) : QP_CLOBBER));
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtoi.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtoi.c
new file mode 100644
index 000000000..a40253654
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtoi.c
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+ Return (int)(*a)
+ Copyright (C) 1997, 1999, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_qtoi(const long double *a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned int r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_QP(A, a);
+ FP_TO_INT_Q(r, A, 32, 1);
+ QP_HANDLE_EXCEPTIONS(
+ int rx;
+ __asm (
+" ldd [%1], %%f52\n"
+" ldd [%1+8], %%f54\n"
+" fqtoi %%f52, %%f31\n"
+" st %%f31, [%0]\n"
+" " : : "r" (&rx), "r" (a) : QP_CLOBBER, "f31");
+ r = rx);
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtos.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtos.c
new file mode 100644
index 000000000..f5f9cdb19
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtos.c
@@ -0,0 +1,50 @@
+/* Software floating-point emulation.
+ Return (float)(*a)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+float _Qp_qtos(const long double *a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ FP_DECL_S(R);
+ float r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_QP(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_TRUNC(S,Q,1,4,R,A);
+#else
+ FP_TRUNC(S,Q,1,2,R,A);
+#endif
+ FP_PACK_SEMIRAW_S(r, R);
+
+ QP_HANDLE_EXCEPTIONS(__asm (
+" ldd [%1], %%f52\n"
+" ldd [%1+8], %%f54\n"
+" fqtos %%f52, %0\n"
+" " : "=&f" (r) : "r" (a) : QP_CLOBBER));
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtoui.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtoui.c
new file mode 100644
index 000000000..884d23e52
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtoui.c
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+ Return (unsigned int)(*a)
+ Copyright (C) 1997, 1999, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+unsigned int _Qp_qtoui(const long double *a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned int r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_QP(A, a);
+ FP_TO_INT_Q(r, A, 32, -1);
+ QP_HANDLE_EXCEPTIONS(
+ int rx;
+ __asm (
+" ldd [%1], %%f52\n"
+" ldd [%1+8], %%f54\n"
+" fqtoi %%f52, %%f31\n"
+" st %%f31, [%0]\n"
+" " : : "r" (&rx), "r" (a) : QP_CLOBBER, "f31");
+ r = rx);
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtoux.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtoux.c
new file mode 100644
index 000000000..4b6f265a4
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtoux.c
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+ Return (unsigned long)(*a)
+ Copyright (C) 1997, 1999, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+unsigned long _Qp_qtoux(const long double *a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned long r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_QP(A, a);
+ FP_TO_INT_Q(r, A, 64, -1);
+ QP_HANDLE_EXCEPTIONS(
+ unsigned long rx;
+ __asm (
+" ldd [%1], %%f52\n"
+" ldd [%1+8], %%f54\n"
+" fqtox %%f52, %%f60\n"
+" std %%f60, [%0]\n"
+" " : : "r" (&rx), "r" (a) : QP_CLOBBER);
+ r = rx);
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtox.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtox.c
new file mode 100644
index 000000000..fac6166c2
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_qtox.c
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+ Return (long)(*a)
+ Copyright (C) 1997, 1999, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+long _Qp_qtox(const long double *a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ unsigned long r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_QP(A, a);
+ FP_TO_INT_Q(r, A, 64, 1);
+ QP_HANDLE_EXCEPTIONS(
+ long rx;
+ __asm (
+" ldd [%1], %%f52\n"
+" ldd [%1+8], %%f54\n"
+" fqtox %%f52, %%f60\n"
+" std %%f60, [%0]\n"
+" " : : "r" (&rx), "r" (a) : QP_CLOBBER);
+ r = rx);
+
+ return r;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_sqrt.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_sqrt.c
new file mode 100644
index 000000000..d75b78b18
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_sqrt.c
@@ -0,0 +1,42 @@
+/* Software floating-point emulation.
+ (*c) = sqrtl(*a)
+ Copyright (C) 1997,1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_sqrt(long double *c, const long double *a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(C);
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_QP(A, a);
+ FP_SQRT_Q(C, A);
+ FP_PACK_QP(c, C);
+ QP_HANDLE_EXCEPTIONS(__asm (
+" ldd [%1], %%f52\n"
+" ldd [%1+8], %%f54\n"
+" fsqrtq %%f52, %%f60\n"
+" std %%f60, [%0]\n"
+" std %%f62, [%0+8]\n"
+" " : : "r" (c), "r" (a) : QP_CLOBBER));
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_stoq.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_stoq.c
new file mode 100644
index 000000000..1a4a03df8
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_stoq.c
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+ (*c) = (long double)(a)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+void _Qp_stoq(long double *c, const float a)
+{
+ FP_DECL_EX;
+ FP_DECL_S(A);
+ FP_DECL_Q(C);
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_RAW_S(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ FP_EXTEND(Q,S,4,1,C,A);
+#else
+ FP_EXTEND(Q,S,2,1,C,A);
+#endif
+ FP_PACK_RAW_QP(c, C);
+ QP_HANDLE_EXCEPTIONS(__asm (
+" fstoq %1, %%f60\n"
+" std %%f60, [%0]\n"
+" std %%f62, [%0+8]\n"
+" " : : "r" (c), "f" (a) : QP_CLOBBER));
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_sub.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_sub.c
new file mode 100644
index 000000000..056224fb4
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_sub.c
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+ (*c) = (*a) - (*b)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_sub(long double *c, const long double *a, const long double *b)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_QP(A, a);
+ FP_UNPACK_SEMIRAW_QP(B, b);
+ FP_SUB_Q(C, A, B);
+ FP_PACK_SEMIRAW_QP(c, C);
+ QP_HANDLE_EXCEPTIONS(__asm (
+" ldd [%1], %%f52\n"
+" ldd [%1+8], %%f54\n"
+" ldd [%2], %%f56\n"
+" ldd [%2+8], %%f58\n"
+" fsubq %%f52, %%f56, %%f60\n"
+" std %%f60, [%0]\n"
+" std %%f62, [%0+8]\n"
+" " : : "r" (c), "r" (a), "r" (b) : QP_CLOBBER));
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_uitoq.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_uitoq.c
new file mode 100644
index 000000000..a3bfaedfc
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_uitoq.c
@@ -0,0 +1,35 @@
+/* Software floating-point emulation.
+ (*c) = (long double)(a)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_uitoq(long double *c, const unsigned int a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ unsigned int b = a;
+
+ FP_FROM_INT_Q(C, b, 32, unsigned int);
+ FP_PACK_RAW_QP(c, C);
+ QP_NO_EXCEPTIONS;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_util.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_util.c
new file mode 100644
index 000000000..794d359a7
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_util.c
@@ -0,0 +1,57 @@
+/* Software floating-point emulation.
+ Helper routine for _Qp_* routines.
+ Simulate exceptions using double arithmetics.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+
+static unsigned long numbers [] = {
+0x7fef000000000000UL, /* A huge double number */
+0x0010100000000000UL, /* Very tiny number */
+0x0010000000000000UL, /* Minimum normalized number */
+0x0000000000000000UL, /* Zero */
+};
+
+double __Qp_handle_exceptions(int exceptions)
+{
+ double d, *p = (double *)numbers;
+ if (exceptions & FP_EX_INVALID)
+ d = p[3]/p[3];
+ if (exceptions & FP_EX_OVERFLOW)
+ {
+ d = p[0] + p[0];
+ exceptions &= ~FP_EX_INEXACT;
+ }
+ if (exceptions & FP_EX_UNDERFLOW)
+ {
+ if (exceptions & FP_EX_INEXACT)
+ {
+ d = p[2] * p[2];
+ exceptions &= ~FP_EX_INEXACT;
+ }
+ else
+ d = p[1] - p[2];
+ }
+ if (exceptions & FP_EX_DIVZERO)
+ d = 1.0/p[3];
+ if (exceptions & FP_EX_INEXACT)
+ d = p[0] - p[2];
+ return d;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_uxtoq.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_uxtoq.c
new file mode 100644
index 000000000..f691e4d36
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_uxtoq.c
@@ -0,0 +1,35 @@
+/* Software floating-point emulation.
+ (*c) = (long double)(a)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_uxtoq(long double *c, const unsigned long a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ unsigned long b = a;
+
+ FP_FROM_INT_Q(C, b, 64, unsigned long);
+ FP_PACK_RAW_QP(c, C);
+ QP_NO_EXCEPTIONS;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/qp_xtoq.c b/libc/sysdeps/sparc/sparc64/soft-fp/qp_xtoq.c
new file mode 100644
index 000000000..b7a610269
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/qp_xtoq.c
@@ -0,0 +1,35 @@
+/* Software floating-point emulation.
+ (*c) = (long double)(*a)
+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_xtoq(long double *c, const long a)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(C);
+ long b = a;
+
+ FP_FROM_INT_Q(C, b, 64, unsigned long);
+ FP_PACK_RAW_QP(c, C);
+ QP_NO_EXCEPTIONS;
+}
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/s_frexpl.c b/libc/sysdeps/sparc/sparc64/soft-fp/s_frexpl.c
new file mode 100644
index 000000000..6cfe24149
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/s_frexpl.c
@@ -0,0 +1,52 @@
+/* Software floating-point emulation.
+ frexpl(x, exp)
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * for non-zero x
+ * x = frexpl(arg,&exp);
+ * return a long double fp quantity x such that 0.5 <= |x| <1.0
+ * and the corresponding binary exponent "exp". That is
+ * arg = x*2^exp.
+ * If arg is inf, 0.0, or NaN, then frexpl(arg,&exp) returns arg
+ * with *exp=0.
+ */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __frexpl(long double arg, int *exp)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ long double r;
+
+ *exp = 0;
+ FP_UNPACK_Q(A, arg);
+ if (A_c != FP_CLS_NORMAL)
+ return arg;
+ *exp = A_e + 1;
+ A_e = -1;
+ FP_PACK_Q(r, A);
+
+ return r;
+}
+
+weak_alias (__frexpl, frexpl)
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/s_ilogbl.c b/libc/sysdeps/sparc/sparc64/soft-fp/s_ilogbl.c
new file mode 100644
index 000000000..f58190dca
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/s_ilogbl.c
@@ -0,0 +1,82 @@
+/* Software floating-point emulation.
+ ilogbl(x, exp)
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* ilogbl(long double x)
+ * return the binary exponent of non-zero x
+ * ilogbl(0) = 0x80000001
+ * ilogbl(inf/NaN) = 0x7fffffff (no signal is raised)
+ */
+
+#include "soft-fp.h"
+#include "quad.h"
+#include <math.h>
+
+int __ilogbl(long double x)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(X);
+
+/*
+ FP_UNPACK_Q(X, x);
+ switch (X_c)
+ {
+ case FP_CLS_ZERO:
+ return FP_ILOGB0;
+ case FP_CLS_NAN:
+ case FP_CLS_INF:
+ return FP_ILOGBNAN;
+ default:
+ return X_e;
+ }
+ */
+ FP_UNPACK_RAW_Q(X, x);
+ switch (X_e)
+ {
+ default:
+ return X_e - _FP_EXPBIAS_Q;
+ case 0:
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+ if (_FP_FRAC_ZEROP_4(X))
+ return FP_ILOGB0;
+ else
+ {
+ _FP_I_TYPE shift;
+ _FP_FRAC_CLZ_4(shift, X);
+ shift -= _FP_FRACXBITS_Q;
+ return X_e - _FP_EXPBIAS_Q - 1 + shift;
+ }
+#else
+ if (_FP_FRAC_ZEROP_2(X))
+ return FP_ILOGB0;
+ else
+ {
+ _FP_I_TYPE shift;
+ _FP_FRAC_CLZ_2(shift, X);
+ shift -= _FP_FRACXBITS_Q;
+ return X_e - _FP_EXPBIAS_Q - 1 + shift;
+ }
+#endif
+ case _FP_EXPBIAS_Q:
+ return FP_ILOGBNAN;
+ }
+}
+
+weak_alias (__ilogbl, ilogbl)
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/s_scalblnl.c b/libc/sysdeps/sparc/sparc64/soft-fp/s_scalblnl.c
new file mode 100644
index 000000000..31eed0462
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/s_scalblnl.c
@@ -0,0 +1,55 @@
+/* Software floating-point emulation.
+ scalblnl(x, exp)
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * scalblnl (long double x, long int n)
+ * scalblnl(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __scalblnl(long double arg, int exp)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ long double r;
+
+ FP_UNPACK_Q(A, arg);
+ switch (A_c)
+ {
+ case FP_CLS_ZERO:
+ return arg;
+ case FP_CLS_NAN:
+ case FP_CLS_INF:
+ FP_HANDLE_EXCEPTIONS;
+ return arg;
+ }
+ A_e += exp;
+ FP_PACK_Q(r, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
+weak_alias (__scalblnl, scalblnl)
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/s_scalbnl.c b/libc/sysdeps/sparc/sparc64/soft-fp/s_scalbnl.c
new file mode 100644
index 000000000..abd38719a
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/s_scalbnl.c
@@ -0,0 +1,55 @@
+/* Software floating-point emulation.
+ scalbnl(x, exp)
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * scalbnl (long double x, int n)
+ * scalbnl(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __scalbnl(long double arg, int exp)
+{
+ FP_DECL_EX;
+ FP_DECL_Q(A);
+ long double r;
+
+ FP_UNPACK_Q(A, arg);
+ switch (A_c)
+ {
+ case FP_CLS_ZERO:
+ return arg;
+ case FP_CLS_NAN:
+ case FP_CLS_INF:
+ FP_HANDLE_EXCEPTIONS;
+ return arg;
+ }
+ A_e += exp;
+ FP_PACK_Q(r, A);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
+weak_alias (__scalbnl, scalbnl)
diff --git a/libc/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h b/libc/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h
new file mode 100644
index 000000000..449e955c1
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h
@@ -0,0 +1,144 @@
+/* Machine-dependent software floating-point definitions.
+ Sparc64 userland (_Q_* and _Qp_*) version.
+ Copyright (C) 1997, 1998, 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@cygnus.com),
+ Jakub Jelinek (jj@ultra.linux.cz) and
+ David S. Miller (davem@redhat.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fpu_control.h>
+#include <fenv.h>
+#include <stdlib.h>
+
+#define _FP_W_TYPE_SIZE 64
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+/* Helper macros for _FP_MUL_MEAT_2_120_240_double. */
+#define _FP_MUL_MEAT_SET_FE_TZ \
+do { \
+ static fpu_control_t _fetz = _FPU_RC_DOWN; \
+ _FPU_SETCW(_fetz); \
+} while (0)
+#ifndef _FP_MUL_MEAT_RESET_FE
+#define _FP_MUL_MEAT_RESET_FE _FPU_SETCW(_fcw)
+#endif
+
+#define _FP_MUL_MEAT_S(R,X,Y) \
+ _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y) \
+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y) \
+ _FP_MUL_MEAT_2_120_240_double(_FP_WFRACBITS_Q,R,X,Y, \
+ _FP_MUL_MEAT_SET_FE_TZ, \
+ _FP_MUL_MEAT_RESET_FE)
+
+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1)
+#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1
+#define _FP_NANSIGN_S 0
+#define _FP_NANSIGN_D 0
+#define _FP_NANSIGN_Q 0
+
+#define _FP_KEEPNANFRACP 1
+
+/* If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose Y.
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs) \
+ && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ } \
+ else \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,Y); \
+ } \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+/* Obtain the current rounding mode. */
+#ifndef FP_ROUNDMODE
+#define FP_ROUNDMODE ((_fcw >> 30) & 0x3)
+#endif
+
+/* Exception flags. */
+#define FP_EX_INVALID (1 << 4)
+#define FP_EX_OVERFLOW (1 << 3)
+#define FP_EX_UNDERFLOW (1 << 2)
+#define FP_EX_DIVZERO (1 << 1)
+#define FP_EX_INEXACT (1 << 0)
+
+#define _FP_DECL_EX fpu_control_t _fcw
+
+#define FP_INIT_ROUNDMODE \
+do { \
+ _FPU_GETCW(_fcw); \
+} while (0)
+
+#define FP_INHIBIT_RESULTS ((_fcw >> 23) & _fex)
+
+/* Simulate exceptions using double arithmetics. */
+extern double __Qp_handle_exceptions(int exc);
+
+#define FP_HANDLE_EXCEPTIONS \
+do { \
+ if (!_fex) \
+ { \
+ /* This is the common case, so we do it inline. \
+ * We need to clear cexc bits if any. \
+ */ \
+ __asm__ __volatile__("\n" \
+" fzero %%f62\n" \
+" faddd %%f62, %%f62, %%f62\n" \
+" " : : : "f62"); \
+ } \
+ else \
+ { \
+ __Qp_handle_exceptions (_fex); \
+ } \
+} while (0)
+
+#define QP_HANDLE_EXCEPTIONS(_a) \
+do { \
+ if ((_fcw >> 23) & _fex) \
+ { \
+ _a; \
+ } \
+ else \
+ { \
+ _fcw = (_fcw & ~0x1fL) | (_fex << 5) | _fex; \
+ _FPU_SETCW(_fcw); \
+ } \
+} while (0)
+
+#define QP_NO_EXCEPTIONS \
+ __asm ("fzero %%f62\n" \
+" faddd %%f62, %%f62, %%f62" : : : "f62")
+
+#define QP_CLOBBER "memory", "f52", "f54", "f56", "f58", "f60", "f62"
+#define QP_CLOBBER_CC QP_CLOBBER , "cc"
diff --git a/libc/sysdeps/sparc/sparc64/sparcv9b/memcpy.S b/libc/sysdeps/sparc/sparc64/sparcv9b/memcpy.S
new file mode 100644
index 000000000..760d52663
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/sparcv9b/memcpy.S
@@ -0,0 +1,610 @@
+/* Copy SIZE bytes from SRC to DEST.
+ For UltraSPARC-III.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller (davem@redhat.com)
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#define ASI_BLK_P 0xf0
+#define FPRS_FEF 0x04
+#define VISEntryHalf rd %fprs, %o5; wr %g0, FPRS_FEF, %fprs
+#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs
+
+#ifndef XCC
+#define USE_BPR
+#define XCC xcc
+#endif
+
+ .register %g2,#scratch
+ .register %g3,#scratch
+ .register %g6,#scratch
+
+ .text
+ .align 32
+
+ENTRY(bcopy)
+ sub %o1, %o0, %o4
+ mov %o0, %g4
+ cmp %o4, %o2
+ mov %o1, %o0
+ bgeu,pt %XCC, 100f
+ mov %g4, %o1
+#ifndef USE_BPR
+ srl %o2, 0, %o2
+#endif
+ brnz,pn %o2, 220f
+ add %o0, %o2, %o0
+ retl
+ nop
+END(bcopy)
+
+ /* Special/non-trivial issues of this code:
+ *
+ * 1) %o5 is preserved from VISEntryHalf to VISExitHalf
+ * 2) Only low 32 FPU registers are used so that only the
+ * lower half of the FPU register set is dirtied by this
+ * code. This is especially important in the kernel.
+ * 3) This code never prefetches cachelines past the end
+ * of the source buffer.
+ *
+ * The cheetah's flexible spine, oversized liver, enlarged heart,
+ * slender muscular body, and claws make it the swiftest hunter
+ * in Africa and the fastest animal on land. Can reach speeds
+ * of up to 2.4GB per second.
+ */
+ .align 32
+ENTRY(memcpy)
+
+100: /* %o0=dst, %o1=src, %o2=len */
+ mov %o0, %g5
+ cmp %o2, 0
+ be,pn %XCC, out
+218: or %o0, %o1, %o3
+ cmp %o2, 16
+ bleu,a,pn %XCC, small_copy
+ or %o3, %o2, %o3
+
+ cmp %o2, 256
+ blu,pt %XCC, medium_copy
+ andcc %o3, 0x7, %g0
+
+ ba,pt %xcc, enter
+ andcc %o0, 0x3f, %g2
+
+ /* Here len >= 256 and condition codes reflect execution
+ * of "andcc %o0, 0x7, %g2", done by caller.
+ */
+ .align 64
+enter:
+ /* Is 'dst' already aligned on an 64-byte boundary? */
+ be,pt %XCC, 2f
+
+ /* Compute abs((dst & 0x3f) - 0x40) into %g2. This is the number
+ * of bytes to copy to make 'dst' 64-byte aligned. We pre-
+ * subtract this from 'len'.
+ */
+ sub %g2, 0x40, %g2
+ sub %g0, %g2, %g2
+ sub %o2, %g2, %o2
+
+ /* Copy %g2 bytes from src to dst, one byte at a time. */
+1: ldub [%o1 + 0x00], %o3
+ add %o1, 0x1, %o1
+ add %o0, 0x1, %o0
+ subcc %g2, 0x1, %g2
+
+ bg,pt %XCC, 1b
+ stb %o3, [%o0 + -1]
+
+2: VISEntryHalf
+ and %o1, 0x7, %g1
+ ba,pt %xcc, begin
+ alignaddr %o1, %g0, %o1
+
+ .align 64
+begin:
+ prefetch [%o1 + 0x000], #one_read
+ prefetch [%o1 + 0x040], #one_read
+ andn %o2, (0x40 - 1), %o4
+ prefetch [%o1 + 0x080], #one_read
+ prefetch [%o1 + 0x0c0], #one_read
+ ldd [%o1 + 0x000], %f0
+ prefetch [%o1 + 0x100], #one_read
+ ldd [%o1 + 0x008], %f2
+ prefetch [%o1 + 0x140], #one_read
+ ldd [%o1 + 0x010], %f4
+ prefetch [%o1 + 0x180], #one_read
+ faligndata %f0, %f2, %f16
+ ldd [%o1 + 0x018], %f6
+ faligndata %f2, %f4, %f18
+ ldd [%o1 + 0x020], %f8
+ faligndata %f4, %f6, %f20
+ ldd [%o1 + 0x028], %f10
+ faligndata %f6, %f8, %f22
+
+ ldd [%o1 + 0x030], %f12
+ faligndata %f8, %f10, %f24
+ ldd [%o1 + 0x038], %f14
+ faligndata %f10, %f12, %f26
+ ldd [%o1 + 0x040], %f0
+
+ sub %o4, 0x80, %o4
+ add %o1, 0x40, %o1
+ ba,pt %xcc, loop
+ srl %o4, 6, %o3
+
+ .align 64
+loop:
+ ldd [%o1 + 0x008], %f2
+ faligndata %f12, %f14, %f28
+ ldd [%o1 + 0x010], %f4
+ faligndata %f14, %f0, %f30
+ stda %f16, [%o0] ASI_BLK_P
+ ldd [%o1 + 0x018], %f6
+ faligndata %f0, %f2, %f16
+
+ ldd [%o1 + 0x020], %f8
+ faligndata %f2, %f4, %f18
+ ldd [%o1 + 0x028], %f10
+ faligndata %f4, %f6, %f20
+ ldd [%o1 + 0x030], %f12
+ faligndata %f6, %f8, %f22
+ ldd [%o1 + 0x038], %f14
+ faligndata %f8, %f10, %f24
+
+ ldd [%o1 + 0x040], %f0
+ prefetch [%o1 + 0x180], #one_read
+ faligndata %f10, %f12, %f26
+ subcc %o3, 0x01, %o3
+ add %o1, 0x40, %o1
+ bg,pt %XCC, loop
+ add %o0, 0x40, %o0
+
+ /* Finally we copy the last full 64-byte block. */
+loopfini:
+ ldd [%o1 + 0x008], %f2
+ faligndata %f12, %f14, %f28
+ ldd [%o1 + 0x010], %f4
+ faligndata %f14, %f0, %f30
+ stda %f16, [%o0] ASI_BLK_P
+ ldd [%o1 + 0x018], %f6
+ faligndata %f0, %f2, %f16
+ ldd [%o1 + 0x020], %f8
+ faligndata %f2, %f4, %f18
+ ldd [%o1 + 0x028], %f10
+ faligndata %f4, %f6, %f20
+ ldd [%o1 + 0x030], %f12
+ faligndata %f6, %f8, %f22
+ ldd [%o1 + 0x038], %f14
+ faligndata %f8, %f10, %f24
+ cmp %g1, 0
+ be,pt %XCC, 1f
+ add %o0, 0x40, %o0
+ ldd [%o1 + 0x040], %f0
+1: faligndata %f10, %f12, %f26
+ faligndata %f12, %f14, %f28
+ faligndata %f14, %f0, %f30
+ stda %f16, [%o0] ASI_BLK_P
+ add %o0, 0x40, %o0
+ add %o1, 0x40, %o1
+ membar #Sync
+
+ /* Now we copy the (len modulo 64) bytes at the end.
+ * Note how we borrow the %f0 loaded above.
+ *
+ * Also notice how this code is careful not to perform a
+ * load past the end of the src buffer.
+ */
+loopend:
+ and %o2, 0x3f, %o2
+ andcc %o2, 0x38, %g2
+ be,pn %XCC, endcruft
+ subcc %g2, 0x8, %g2
+ be,pn %XCC, endcruft
+ cmp %g1, 0
+
+ be,a,pt %XCC, 1f
+ ldd [%o1 + 0x00], %f0
+
+1: ldd [%o1 + 0x08], %f2
+ add %o1, 0x8, %o1
+ sub %o2, 0x8, %o2
+ subcc %g2, 0x8, %g2
+ faligndata %f0, %f2, %f8
+ std %f8, [%o0 + 0x00]
+ be,pn %XCC, endcruft
+ add %o0, 0x8, %o0
+ ldd [%o1 + 0x08], %f0
+ add %o1, 0x8, %o1
+ sub %o2, 0x8, %o2
+ subcc %g2, 0x8, %g2
+ faligndata %f2, %f0, %f8
+ std %f8, [%o0 + 0x00]
+ bne,pn %XCC, 1b
+ add %o0, 0x8, %o0
+
+ /* If anything is left, we copy it one byte at a time.
+ * Note that %g1 is (src & 0x3) saved above before the
+ * alignaddr was performed.
+ */
+endcruft:
+ cmp %o2, 0
+ add %o1, %g1, %o1
+ VISExitHalf
+ be,pn %XCC, out
+ sub %o0, %o1, %o3
+
+ andcc %g1, 0x7, %g0
+ bne,pn %icc, small_copy_unaligned
+ andcc %o2, 0x8, %g0
+ be,pt %icc, 1f
+ nop
+ ldx [%o1], %o5
+ stx %o5, [%o1 + %o3]
+ add %o1, 0x8, %o1
+
+1: andcc %o2, 0x4, %g0
+ be,pt %icc, 1f
+ nop
+ lduw [%o1], %o5
+ stw %o5, [%o1 + %o3]
+ add %o1, 0x4, %o1
+
+1: andcc %o2, 0x2, %g0
+ be,pt %icc, 1f
+ nop
+ lduh [%o1], %o5
+ sth %o5, [%o1 + %o3]
+ add %o1, 0x2, %o1
+
+1: andcc %o2, 0x1, %g0
+ be,pt %icc, out
+ nop
+ ldub [%o1], %o5
+ ba,pt %xcc, out
+ stb %o5, [%o1 + %o3]
+
+medium_copy: /* 16 < len <= 64 */
+ bne,pn %XCC, small_copy_unaligned
+ sub %o0, %o1, %o3
+
+medium_copy_aligned:
+ andn %o2, 0x7, %o4
+ and %o2, 0x7, %o2
+1: subcc %o4, 0x8, %o4
+ ldx [%o1], %o5
+ stx %o5, [%o1 + %o3]
+ bgu,pt %XCC, 1b
+ add %o1, 0x8, %o1
+ andcc %o2, 0x4, %g0
+ be,pt %XCC, 1f
+ nop
+ sub %o2, 0x4, %o2
+ lduw [%o1], %o5
+ stw %o5, [%o1 + %o3]
+ add %o1, 0x4, %o1
+1: cmp %o2, 0
+ be,pt %XCC, out
+ nop
+ ba,pt %xcc, small_copy_unaligned
+ nop
+
+small_copy: /* 0 < len <= 16 */
+ andcc %o3, 0x3, %g0
+ bne,pn %XCC, small_copy_unaligned
+ sub %o0, %o1, %o3
+
+small_copy_aligned:
+ subcc %o2, 4, %o2
+ lduw [%o1], %g1
+ stw %g1, [%o1 + %o3]
+ bgu,pt %XCC, small_copy_aligned
+ add %o1, 4, %o1
+
+out: retl
+ mov %g5, %o0
+
+ .align 32
+small_copy_unaligned:
+ subcc %o2, 1, %o2
+ ldub [%o1], %g1
+ stb %g1, [%o1 + %o3]
+ bgu,pt %XCC, small_copy_unaligned
+ add %o1, 1, %o1
+ retl
+ mov %g5, %o0
+
+END(memcpy)
+
+#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldx [%src - offset - 0x20], %t0; \
+ ldx [%src - offset - 0x18], %t1; \
+ ldx [%src - offset - 0x10], %t2; \
+ ldx [%src - offset - 0x08], %t3; \
+ stw %t0, [%dst - offset - 0x1c]; \
+ srlx %t0, 32, %t0; \
+ stw %t0, [%dst - offset - 0x20]; \
+ stw %t1, [%dst - offset - 0x14]; \
+ srlx %t1, 32, %t1; \
+ stw %t1, [%dst - offset - 0x18]; \
+ stw %t2, [%dst - offset - 0x0c]; \
+ srlx %t2, 32, %t2; \
+ stw %t2, [%dst - offset - 0x10]; \
+ stw %t3, [%dst - offset - 0x04]; \
+ srlx %t3, 32, %t3; \
+ stw %t3, [%dst - offset - 0x08];
+
+#define RMOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldx [%src - offset - 0x20], %t0; \
+ ldx [%src - offset - 0x18], %t1; \
+ ldx [%src - offset - 0x10], %t2; \
+ ldx [%src - offset - 0x08], %t3; \
+ stx %t0, [%dst - offset - 0x20]; \
+ stx %t1, [%dst - offset - 0x18]; \
+ stx %t2, [%dst - offset - 0x10]; \
+ stx %t3, [%dst - offset - 0x08]; \
+ ldx [%src - offset - 0x40], %t0; \
+ ldx [%src - offset - 0x38], %t1; \
+ ldx [%src - offset - 0x30], %t2; \
+ ldx [%src - offset - 0x28], %t3; \
+ stx %t0, [%dst - offset - 0x40]; \
+ stx %t1, [%dst - offset - 0x38]; \
+ stx %t2, [%dst - offset - 0x30]; \
+ stx %t3, [%dst - offset - 0x28];
+
+#define RMOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldx [%src + offset + 0x00], %t0; \
+ ldx [%src + offset + 0x08], %t1; \
+ stw %t0, [%dst + offset + 0x04]; \
+ srlx %t0, 32, %t2; \
+ stw %t2, [%dst + offset + 0x00]; \
+ stw %t1, [%dst + offset + 0x0c]; \
+ srlx %t1, 32, %t3; \
+ stw %t3, [%dst + offset + 0x08];
+
+#define RMOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1) \
+ ldx [%src + offset + 0x00], %t0; \
+ ldx [%src + offset + 0x08], %t1; \
+ stx %t0, [%dst + offset + 0x00]; \
+ stx %t1, [%dst + offset + 0x08];
+
+ .align 32
+228: andcc %o2, 1, %g0 /* IEU1 Group */
+ be,pt %icc, 2f+4 /* CTI */
+1: ldub [%o1 - 1], %o5 /* LOAD Group */
+ sub %o1, 1, %o1 /* IEU0 */
+ sub %o0, 1, %o0 /* IEU1 */
+ subcc %o2, 1, %o2 /* IEU1 Group */
+ be,pn %xcc, 229f /* CTI */
+ stb %o5, [%o0] /* Store */
+2: ldub [%o1 - 1], %o5 /* LOAD Group */
+ sub %o0, 2, %o0 /* IEU0 */
+ ldub [%o1 - 2], %g5 /* LOAD Group */
+ sub %o1, 2, %o1 /* IEU0 */
+ subcc %o2, 2, %o2 /* IEU1 Group */
+ stb %o5, [%o0 + 1] /* Store */
+ bne,pt %xcc, 2b /* CTI */
+ stb %g5, [%o0] /* Store */
+229: retl
+ mov %g4, %o0
+
+ .align 32
+ENTRY(memmove)
+ mov %o0, %g5
+#ifndef USE_BPR
+ srl %o2, 0, %o2 /* IEU1 Group */
+#endif
+ brz,pn %o2, out /* CTI Group */
+ sub %o0, %o1, %o4 /* IEU0 */
+ cmp %o4, %o2 /* IEU1 Group */
+ bgeu,pt %XCC, 218b /* CTI */
+ mov %o0, %g4 /* IEU0 */
+ add %o0, %o2, %o0 /* IEU0 Group */
+220: add %o1, %o2, %o1 /* IEU1 */
+ cmp %o2, 15 /* IEU1 Group */
+ bleu,pn %xcc, 228b /* CTI */
+ andcc %o0, 7, %g2 /* IEU1 Group */
+ sub %o0, %o1, %g5 /* IEU0 */
+ andcc %g5, 3, %o5 /* IEU1 Group */
+ bne,pn %xcc, 232f /* CTI */
+ andcc %o1, 3, %g0 /* IEU1 Group */
+ be,a,pt %xcc, 236f /* CTI */
+ andcc %o1, 4, %g0 /* IEU1 Group */
+ andcc %o1, 1, %g0 /* IEU1 Group */
+ be,pn %xcc, 4f /* CTI */
+ andcc %o1, 2, %g0 /* IEU1 Group */
+ ldub [%o1 - 1], %g2 /* Load Group */
+ sub %o1, 1, %o1 /* IEU0 */
+ sub %o0, 1, %o0 /* IEU1 */
+ sub %o2, 1, %o2 /* IEU0 Group */
+ be,pn %xcc, 5f /* CTI Group */
+ stb %g2, [%o0] /* Store */
+4: lduh [%o1 - 2], %g2 /* Load Group */
+ sub %o1, 2, %o1 /* IEU0 */
+ sub %o0, 2, %o0 /* IEU1 */
+ sub %o2, 2, %o2 /* IEU0 */
+ sth %g2, [%o0] /* Store Group + bubble */
+5: andcc %o1, 4, %g0 /* IEU1 */
+236: be,a,pn %xcc, 2f /* CTI */
+ andcc %o2, -128, %g6 /* IEU1 Group */
+ lduw [%o1 - 4], %g5 /* Load Group */
+ sub %o1, 4, %o1 /* IEU0 */
+ sub %o0, 4, %o0 /* IEU1 */
+ sub %o2, 4, %o2 /* IEU0 Group */
+ stw %g5, [%o0] /* Store */
+ andcc %o2, -128, %g6 /* IEU1 Group */
+2: be,pn %xcc, 235f /* CTI */
+ andcc %o0, 4, %g0 /* IEU1 Group */
+ be,pn %xcc, 282f + 4 /* CTI Group */
+5: RMOVE_BIGCHUNK(o1, o0, 0x00, g1, g3, g5, o5)
+ RMOVE_BIGCHUNK(o1, o0, 0x20, g1, g3, g5, o5)
+ RMOVE_BIGCHUNK(o1, o0, 0x40, g1, g3, g5, o5)
+ RMOVE_BIGCHUNK(o1, o0, 0x60, g1, g3, g5, o5)
+ subcc %g6, 128, %g6 /* IEU1 Group */
+ sub %o1, 128, %o1 /* IEU0 */
+ bne,pt %xcc, 5b /* CTI */
+ sub %o0, 128, %o0 /* IEU0 Group */
+235: andcc %o2, 0x70, %g6 /* IEU1 Group */
+41: be,pn %xcc, 280f /* CTI */
+ andcc %o2, 8, %g0 /* IEU1 Group */
+ /* Clk1 8-( */
+ /* Clk2 8-( */
+ /* Clk3 8-( */
+ /* Clk4 8-( */
+279: rd %pc, %o5 /* PDU Group */
+ sll %g6, 1, %g5 /* IEU0 Group */
+ sub %o1, %g6, %o1 /* IEU1 */
+ sub %o5, %g5, %o5 /* IEU0 Group */
+ jmpl %o5 + %lo(280f - 279b), %g0 /* CTI Group brk forced*/
+ sub %o0, %g6, %o0 /* IEU0 Group */
+ RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g5, o5)
+280: be,pt %xcc, 281f /* CTI */
+ andcc %o2, 4, %g0 /* IEU1 */
+ ldx [%o1 - 8], %g2 /* Load Group */
+ sub %o0, 8, %o0 /* IEU0 */
+ stw %g2, [%o0 + 4] /* Store Group */
+ sub %o1, 8, %o1 /* IEU1 */
+ srlx %g2, 32, %g2 /* IEU0 Group */
+ stw %g2, [%o0] /* Store */
+281: be,pt %xcc, 1f /* CTI */
+ andcc %o2, 2, %g0 /* IEU1 Group */
+ lduw [%o1 - 4], %g2 /* Load Group */
+ sub %o1, 4, %o1 /* IEU0 */
+ stw %g2, [%o0 - 4] /* Store Group */
+ sub %o0, 4, %o0 /* IEU0 */
+1: be,pt %xcc, 1f /* CTI */
+ andcc %o2, 1, %g0 /* IEU1 Group */
+ lduh [%o1 - 2], %g2 /* Load Group */
+ sub %o1, 2, %o1 /* IEU0 */
+ sth %g2, [%o0 - 2] /* Store Group */
+ sub %o0, 2, %o0 /* IEU0 */
+1: be,pt %xcc, 211f /* CTI */
+ nop /* IEU1 */
+ ldub [%o1 - 1], %g2 /* Load Group */
+ stb %g2, [%o0 - 1] /* Store Group + bubble */
+211: retl
+ mov %g4, %o0
+
+282: RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, g1, g3, g5, o5)
+ RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, g1, g3, g5, o5)
+ subcc %g6, 128, %g6 /* IEU1 Group */
+ sub %o1, 128, %o1 /* IEU0 */
+ bne,pt %xcc, 282b /* CTI */
+ sub %o0, 128, %o0 /* IEU0 Group */
+ andcc %o2, 0x70, %g6 /* IEU1 */
+ be,pn %xcc, 284f /* CTI */
+ andcc %o2, 8, %g0 /* IEU1 Group */
+ /* Clk1 8-( */
+ /* Clk2 8-( */
+ /* Clk3 8-( */
+ /* Clk4 8-( */
+283: rd %pc, %o5 /* PDU Group */
+ sub %o1, %g6, %o1 /* IEU0 Group */
+ sub %o5, %g6, %o5 /* IEU1 */
+ jmpl %o5 + %lo(284f - 283b), %g0 /* CTI Group brk forced*/
+ sub %o0, %g6, %o0 /* IEU0 Group */
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3)
+284: be,pt %xcc, 285f /* CTI Group */
+ andcc %o2, 4, %g0 /* IEU1 */
+ ldx [%o1 - 8], %g2 /* Load Group */
+ sub %o0, 8, %o0 /* IEU0 */
+ sub %o1, 8, %o1 /* IEU0 Group */
+ stx %g2, [%o0] /* Store */
+285: be,pt %xcc, 1f /* CTI */
+ andcc %o2, 2, %g0 /* IEU1 Group */
+ lduw [%o1 - 4], %g2 /* Load Group */
+ sub %o0, 4, %o0 /* IEU0 */
+ sub %o1, 4, %o1 /* IEU0 Group */
+ stw %g2, [%o0] /* Store */
+1: be,pt %xcc, 1f /* CTI */
+ andcc %o2, 1, %g0 /* IEU1 Group */
+ lduh [%o1 - 2], %g2 /* Load Group */
+ sub %o0, 2, %o0 /* IEU0 */
+ sub %o1, 2, %o1 /* IEU0 Group */
+ sth %g2, [%o0] /* Store */
+1: be,pt %xcc, 1f /* CTI */
+ nop /* IEU0 Group */
+ ldub [%o1 - 1], %g2 /* Load Group */
+ stb %g2, [%o0 - 1] /* Store Group + bubble */
+1: retl
+ mov %g4, %o0
+
+232: brz,pt %g2, 2f /* CTI Group */
+ sub %o2, %g2, %o2 /* IEU0 Group */
+1: ldub [%o1 - 1], %g5 /* Load Group */
+ sub %o1, 1, %o1 /* IEU0 */
+ sub %o0, 1, %o0 /* IEU1 */
+ subcc %g2, 1, %g2 /* IEU1 Group */
+ bne,pt %xcc, 1b /* CTI */
+ stb %g5, [%o0] /* Store */
+2: andn %o2, 7, %g5 /* IEU0 Group */
+ and %o2, 7, %o2 /* IEU1 */
+ fmovd %f0, %f2 /* FPU */
+ alignaddr %o1, %g0, %g1 /* GRU Group */
+ ldd [%g1], %f4 /* Load Group */
+1: ldd [%g1 - 8], %f6 /* Load Group */
+ sub %g1, 8, %g1 /* IEU0 Group */
+ subcc %g5, 8, %g5 /* IEU1 */
+ faligndata %f6, %f4, %f0 /* GRU Group */
+ std %f0, [%o0 - 8] /* Store */
+ sub %o1, 8, %o1 /* IEU0 Group */
+ be,pn %xcc, 233f /* CTI */
+ sub %o0, 8, %o0 /* IEU1 */
+ ldd [%g1 - 8], %f4 /* Load Group */
+ sub %g1, 8, %g1 /* IEU0 */
+ subcc %g5, 8, %g5 /* IEU1 */
+ faligndata %f4, %f6, %f0 /* GRU Group */
+ std %f0, [%o0 - 8] /* Store */
+ sub %o1, 8, %o1 /* IEU0 */
+ bne,pn %xcc, 1b /* CTI Group */
+ sub %o0, 8, %o0 /* IEU0 */
+233: brz,pn %o2, 234f /* CTI Group */
+ nop /* IEU0 */
+237: ldub [%o1 - 1], %g5 /* LOAD */
+ sub %o1, 1, %o1 /* IEU0 */
+ sub %o0, 1, %o0 /* IEU1 */
+ subcc %o2, 1, %o2 /* IEU1 */
+ bne,pt %xcc, 237b /* CTI */
+ stb %g5, [%o0] /* Store Group */
+234: wr %g0, FPRS_FEF, %fprs
+ retl
+ mov %g4, %o0
+END(memmove)
+
+#ifdef USE_BPR
+weak_alias (memcpy, __align_cpy_1)
+weak_alias (memcpy, __align_cpy_2)
+weak_alias (memcpy, __align_cpy_4)
+weak_alias (memcpy, __align_cpy_8)
+weak_alias (memcpy, __align_cpy_16)
+#endif
+libc_hidden_builtin_def (memcpy)
+libc_hidden_builtin_def (memmove)
diff --git a/libc/sysdeps/sparc/sparc64/sparcv9v/memcpy.S b/libc/sysdeps/sparc/sparc64/sparcv9v/memcpy.S
new file mode 100644
index 000000000..05c837fa2
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/sparcv9v/memcpy.S
@@ -0,0 +1,593 @@
+/* Copy SIZE bytes from SRC to DEST. For SUN4V Niagara.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller (davem@davemloft.net)
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#define ASI_BLK_INIT_QUAD_LDD_P 0xe2
+#define ASI_P 0x80
+#define ASI_PNF 0x82
+
+#define LOAD(type,addr,dest) type##a [addr] ASI_P, dest
+#define LOAD_TWIN(addr_reg,dest0,dest1) \
+ ldda [addr_reg] ASI_BLK_INIT_QUAD_LDD_P, dest0
+
+#define STORE(type,src,addr) type src, [addr]
+#define STORE_INIT(src,addr) stxa src, [addr] %asi
+
+#ifndef XCC
+#define USE_BPR
+#define XCC xcc
+#endif
+
+ .register %g2,#scratch
+ .register %g3,#scratch
+ .register %g6,#scratch
+
+ .text
+ .align 32
+
+ENTRY(bcopy)
+ sub %o1, %o0, %o4
+ mov %o0, %g4
+ cmp %o4, %o2
+ mov %o1, %o0
+ bgeu,pt %XCC, 100f
+ mov %g4, %o1
+#ifndef USE_BPR
+ srl %o2, 0, %o2
+#endif
+ brnz,pn %o2, 220f
+ add %o0, %o2, %o0
+ retl
+ nop
+END(bcopy)
+
+ .align 32
+ENTRY(memcpy)
+100: /* %o0=dst, %o1=src, %o2=len */
+ mov %o0, %g5
+ cmp %o2, 0
+ be,pn %XCC, 85f
+218: or %o0, %o1, %o3
+ cmp %o2, 16
+ blu,a,pn %XCC, 80f
+ or %o3, %o2, %o3
+
+ /* 2 blocks (128 bytes) is the minimum we can do the block
+ * copy with. We need to ensure that we'll iterate at least
+ * once in the block copy loop. At worst we'll need to align
+ * the destination to a 64-byte boundary which can chew up
+ * to (64 - 1) bytes from the length before we perform the
+ * block copy loop.
+ */
+ cmp %o2, (2 * 64)
+ blu,pt %XCC, 70f
+ andcc %o3, 0x7, %g0
+
+ /* %o0: dst
+ * %o1: src
+ * %o2: len (known to be >= 128)
+ *
+ * The block copy loops will use %o4/%o5,%g2/%g3 as
+ * temporaries while copying the data.
+ */
+
+ LOAD(prefetch, %o1, #one_read)
+ wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
+
+ /* Align destination on 64-byte boundary. */
+ andcc %o0, (64 - 1), %o4
+ be,pt %XCC, 2f
+ sub %o4, 64, %o4
+ sub %g0, %o4, %o4 ! bytes to align dst
+ sub %o2, %o4, %o2
+1: subcc %o4, 1, %o4
+ LOAD(ldub, %o1, %g1)
+ STORE(stb, %g1, %o0)
+ add %o1, 1, %o1
+ bne,pt %XCC, 1b
+ add %o0, 1, %o0
+
+ /* If the source is on a 16-byte boundary we can do
+ * the direct block copy loop. If it is 8-byte aligned
+ * we can do the 16-byte loads offset by -8 bytes and the
+ * init stores offset by one register.
+ *
+ * If the source is not even 8-byte aligned, we need to do
+ * shifting and masking (basically integer faligndata).
+ *
+ * The careful bit with init stores is that if we store
+ * to any part of the cache line we have to store the whole
+ * cacheline else we can end up with corrupt L2 cache line
+ * contents. Since the loop works on 64-bytes of 64-byte
+ * aligned store data at a time, this is easy to ensure.
+ */
+2:
+ andcc %o1, (16 - 1), %o4
+ andn %o2, (64 - 1), %g1 ! block copy loop iterator
+ sub %o2, %g1, %o2 ! final sub-block copy bytes
+ be,pt %XCC, 50f
+ cmp %o4, 8
+ be,a,pt %XCC, 10f
+ sub %o1, 0x8, %o1
+
+ /* Neither 8-byte nor 16-byte aligned, shift and mask. */
+ mov %g1, %o4
+ and %o1, 0x7, %g1
+ sll %g1, 3, %g1
+ mov 64, %o3
+ andn %o1, 0x7, %o1
+ LOAD(ldx, %o1, %g2)
+ sub %o3, %g1, %o3
+ sllx %g2, %g1, %g2
+
+#define SWIVEL_ONE_DWORD(SRC, TMP1, TMP2, PRE_VAL, PRE_SHIFT, POST_SHIFT, DST)\
+ LOAD(ldx, SRC, TMP1); \
+ srlx TMP1, PRE_SHIFT, TMP2; \
+ or TMP2, PRE_VAL, TMP2; \
+ STORE_INIT(TMP2, DST); \
+ sllx TMP1, POST_SHIFT, PRE_VAL;
+
+1: add %o1, 0x8, %o1
+ SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x00)
+ add %o1, 0x8, %o1
+ SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x08)
+ add %o1, 0x8, %o1
+ SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x10)
+ add %o1, 0x8, %o1
+ SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x18)
+ add %o1, 32, %o1
+ LOAD(prefetch, %o1, #one_read)
+ sub %o1, 32 - 8, %o1
+ SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x20)
+ add %o1, 8, %o1
+ SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x28)
+ add %o1, 8, %o1
+ SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x30)
+ add %o1, 8, %o1
+ SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x38)
+ subcc %o4, 64, %o4
+ bne,pt %XCC, 1b
+ add %o0, 64, %o0
+
+#undef SWIVEL_ONE_DWORD
+
+ srl %g1, 3, %g1
+ ba,pt %XCC, 60f
+ add %o1, %g1, %o1
+
+10: /* Destination is 64-byte aligned, source was only 8-byte
+ * aligned but it has been subtracted by 8 and we perform
+ * one twin load ahead, then add 8 back into source when
+ * we finish the loop.
+ */
+ LOAD_TWIN(%o1, %o4, %o5)
+1: add %o1, 16, %o1
+ LOAD_TWIN(%o1, %g2, %g3)
+ add %o1, 16 + 32, %o1
+ LOAD(prefetch, %o1, #one_read)
+ sub %o1, 32, %o1
+ STORE_INIT(%o5, %o0 + 0x00) ! initializes cache line
+ STORE_INIT(%g2, %o0 + 0x08)
+ LOAD_TWIN(%o1, %o4, %o5)
+ add %o1, 16, %o1
+ STORE_INIT(%g3, %o0 + 0x10)
+ STORE_INIT(%o4, %o0 + 0x18)
+ LOAD_TWIN(%o1, %g2, %g3)
+ add %o1, 16, %o1
+ STORE_INIT(%o5, %o0 + 0x20)
+ STORE_INIT(%g2, %o0 + 0x28)
+ LOAD_TWIN(%o1, %o4, %o5)
+ STORE_INIT(%g3, %o0 + 0x30)
+ STORE_INIT(%o4, %o0 + 0x38)
+ subcc %g1, 64, %g1
+ bne,pt %XCC, 1b
+ add %o0, 64, %o0
+
+ ba,pt %XCC, 60f
+ add %o1, 0x8, %o1
+
+50: /* Destination is 64-byte aligned, and source is 16-byte
+ * aligned.
+ */
+1: LOAD_TWIN(%o1, %o4, %o5)
+ add %o1, 16, %o1
+ LOAD_TWIN(%o1, %g2, %g3)
+ add %o1, 16 + 32, %o1
+ LOAD(prefetch, %o1, #one_read)
+ sub %o1, 32, %o1
+ STORE_INIT(%o4, %o0 + 0x00) ! initializes cache line
+ STORE_INIT(%o5, %o0 + 0x08)
+ LOAD_TWIN(%o1, %o4, %o5)
+ add %o1, 16, %o1
+ STORE_INIT(%g2, %o0 + 0x10)
+ STORE_INIT(%g3, %o0 + 0x18)
+ LOAD_TWIN(%o1, %g2, %g3)
+ add %o1, 16, %o1
+ STORE_INIT(%o4, %o0 + 0x20)
+ STORE_INIT(%o5, %o0 + 0x28)
+ STORE_INIT(%g2, %o0 + 0x30)
+ STORE_INIT(%g3, %o0 + 0x38)
+ subcc %g1, 64, %g1
+ bne,pt %XCC, 1b
+ add %o0, 64, %o0
+ /* fall through */
+
+60:
+ /* %o2 contains any final bytes still needed to be copied
+ * over. If anything is left, we copy it one byte at a time.
+ */
+ wr %g0, ASI_PNF, %asi
+ brz,pt %o2, 85f
+ sub %o0, %o1, %o3
+ ba,a,pt %XCC, 90f
+
+ .align 64
+70: /* 16 < len <= 64 */
+ bne,pn %XCC, 75f
+ sub %o0, %o1, %o3
+
+72:
+ andn %o2, 0xf, %o4
+ and %o2, 0xf, %o2
+1: subcc %o4, 0x10, %o4
+ LOAD(ldx, %o1, %o5)
+ add %o1, 0x08, %o1
+ LOAD(ldx, %o1, %g1)
+ sub %o1, 0x08, %o1
+ STORE(stx, %o5, %o1 + %o3)
+ add %o1, 0x8, %o1
+ STORE(stx, %g1, %o1 + %o3)
+ bgu,pt %XCC, 1b
+ add %o1, 0x8, %o1
+73: andcc %o2, 0x8, %g0
+ be,pt %XCC, 1f
+ nop
+ sub %o2, 0x8, %o2
+ LOAD(ldx, %o1, %o5)
+ STORE(stx, %o5, %o1 + %o3)
+ add %o1, 0x8, %o1
+1: andcc %o2, 0x4, %g0
+ be,pt %XCC, 1f
+ nop
+ sub %o2, 0x4, %o2
+ LOAD(lduw, %o1, %o5)
+ STORE(stw, %o5, %o1 + %o3)
+ add %o1, 0x4, %o1
+1: cmp %o2, 0
+ be,pt %XCC, 85f
+ nop
+ ba,pt %XCC, 90f
+ nop
+
+75:
+ andcc %o0, 0x7, %g1
+ sub %g1, 0x8, %g1
+ be,pn %icc, 2f
+ sub %g0, %g1, %g1
+ sub %o2, %g1, %o2
+
+1: subcc %g1, 1, %g1
+ LOAD(ldub, %o1, %o5)
+ STORE(stb, %o5, %o1 + %o3)
+ bgu,pt %icc, 1b
+ add %o1, 1, %o1
+
+2: add %o1, %o3, %o0
+ andcc %o1, 0x7, %g1
+ bne,pt %icc, 8f
+ sll %g1, 3, %g1
+
+ cmp %o2, 16
+ bgeu,pt %icc, 72b
+ nop
+ ba,a,pt %XCC, 73b
+
+8: mov 64, %o3
+ andn %o1, 0x7, %o1
+ LOAD(ldx, %o1, %g2)
+ sub %o3, %g1, %o3
+ andn %o2, 0x7, %o4
+ sllx %g2, %g1, %g2
+1: add %o1, 0x8, %o1
+ LOAD(ldx, %o1, %g3)
+ subcc %o4, 0x8, %o4
+ srlx %g3, %o3, %o5
+ or %o5, %g2, %o5
+ STORE(stx, %o5, %o0)
+ add %o0, 0x8, %o0
+ bgu,pt %icc, 1b
+ sllx %g3, %g1, %g2
+
+ srl %g1, 3, %g1
+ andcc %o2, 0x7, %o2
+ be,pn %icc, 85f
+ add %o1, %g1, %o1
+ ba,pt %XCC, 90f
+ sub %o0, %o1, %o3
+
+ .align 64
+80: /* 0 < len <= 16 */
+ andcc %o3, 0x3, %g0
+ bne,pn %XCC, 90f
+ sub %o0, %o1, %o3
+
+1:
+ subcc %o2, 4, %o2
+ LOAD(lduw, %o1, %g1)
+ STORE(stw, %g1, %o1 + %o3)
+ bgu,pt %XCC, 1b
+ add %o1, 4, %o1
+
+85: retl
+ mov %g5, %o0
+
+ .align 32
+90:
+ subcc %o2, 1, %o2
+ LOAD(ldub, %o1, %g1)
+ STORE(stb, %g1, %o1 + %o3)
+ bgu,pt %XCC, 90b
+ add %o1, 1, %o1
+ retl
+ mov %g5, %o0
+
+END(memcpy)
+
+#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldx [%src - offset - 0x20], %t0; \
+ ldx [%src - offset - 0x18], %t1; \
+ ldx [%src - offset - 0x10], %t2; \
+ ldx [%src - offset - 0x08], %t3; \
+ stw %t0, [%dst - offset - 0x1c]; \
+ srlx %t0, 32, %t0; \
+ stw %t0, [%dst - offset - 0x20]; \
+ stw %t1, [%dst - offset - 0x14]; \
+ srlx %t1, 32, %t1; \
+ stw %t1, [%dst - offset - 0x18]; \
+ stw %t2, [%dst - offset - 0x0c]; \
+ srlx %t2, 32, %t2; \
+ stw %t2, [%dst - offset - 0x10]; \
+ stw %t3, [%dst - offset - 0x04]; \
+ srlx %t3, 32, %t3; \
+ stw %t3, [%dst - offset - 0x08];
+
+#define RMOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldx [%src - offset - 0x20], %t0; \
+ ldx [%src - offset - 0x18], %t1; \
+ ldx [%src - offset - 0x10], %t2; \
+ ldx [%src - offset - 0x08], %t3; \
+ stx %t0, [%dst - offset - 0x20]; \
+ stx %t1, [%dst - offset - 0x18]; \
+ stx %t2, [%dst - offset - 0x10]; \
+ stx %t3, [%dst - offset - 0x08]; \
+ ldx [%src - offset - 0x40], %t0; \
+ ldx [%src - offset - 0x38], %t1; \
+ ldx [%src - offset - 0x30], %t2; \
+ ldx [%src - offset - 0x28], %t3; \
+ stx %t0, [%dst - offset - 0x40]; \
+ stx %t1, [%dst - offset - 0x38]; \
+ stx %t2, [%dst - offset - 0x30]; \
+ stx %t3, [%dst - offset - 0x28];
+
+#define RMOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldx [%src + offset + 0x00], %t0; \
+ ldx [%src + offset + 0x08], %t1; \
+ stw %t0, [%dst + offset + 0x04]; \
+ srlx %t0, 32, %t2; \
+ stw %t2, [%dst + offset + 0x00]; \
+ stw %t1, [%dst + offset + 0x0c]; \
+ srlx %t1, 32, %t3; \
+ stw %t3, [%dst + offset + 0x08];
+
+#define RMOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1) \
+ ldx [%src + offset + 0x00], %t0; \
+ ldx [%src + offset + 0x08], %t1; \
+ stx %t0, [%dst + offset + 0x00]; \
+ stx %t1, [%dst + offset + 0x08];
+
+ .align 32
+228: andcc %o2, 1, %g0
+ be,pt %icc, 2f+4
+1: ldub [%o1 - 1], %o5
+ sub %o1, 1, %o1
+ sub %o0, 1, %o0
+ subcc %o2, 1, %o2
+ be,pn %xcc, 229f
+ stb %o5, [%o0]
+2: ldub [%o1 - 1], %o5
+ sub %o0, 2, %o0
+ ldub [%o1 - 2], %g5
+ sub %o1, 2, %o1
+ subcc %o2, 2, %o2
+ stb %o5, [%o0 + 1]
+ bne,pt %xcc, 2b
+ stb %g5, [%o0]
+229: retl
+ mov %g4, %o0
+out: retl
+ mov %g5, %o0
+
+ .align 32
+ENTRY(memmove)
+ mov %o0, %g5
+#ifndef USE_BPR
+ srl %o2, 0, %o2
+#endif
+ brz,pn %o2, out
+ sub %o0, %o1, %o4
+ cmp %o4, %o2
+ bgeu,pt %XCC, 218b
+ mov %o0, %g4
+ add %o0, %o2, %o0
+220: add %o1, %o2, %o1
+ cmp %o2, 15
+ bleu,pn %xcc, 228b
+ andcc %o0, 7, %g2
+ sub %o0, %o1, %g5
+ andcc %g5, 3, %o5
+ bne,pn %xcc, 232f
+ andcc %o1, 3, %g0
+ be,a,pt %xcc, 236f
+ andcc %o1, 4, %g0
+ andcc %o1, 1, %g0
+ be,pn %xcc, 4f
+ andcc %o1, 2, %g0
+ ldub [%o1 - 1], %g2
+ sub %o1, 1, %o1
+ sub %o0, 1, %o0
+ sub %o2, 1, %o2
+ be,pn %xcc, 5f
+ stb %g2, [%o0]
+4: lduh [%o1 - 2], %g2
+ sub %o1, 2, %o1
+ sub %o0, 2, %o0
+ sub %o2, 2, %o2
+ sth %g2, [%o0]
+5: andcc %o1, 4, %g0
+236: be,a,pn %xcc, 2f
+ andcc %o2, -128, %g6
+ lduw [%o1 - 4], %g5
+ sub %o1, 4, %o1
+ sub %o0, 4, %o0
+ sub %o2, 4, %o2
+ stw %g5, [%o0]
+ andcc %o2, -128, %g6
+2: be,pn %xcc, 235f
+ andcc %o0, 4, %g0
+ be,pn %xcc, 282f + 4
+5: RMOVE_BIGCHUNK(o1, o0, 0x00, g1, g3, g5, o5)
+ RMOVE_BIGCHUNK(o1, o0, 0x20, g1, g3, g5, o5)
+ RMOVE_BIGCHUNK(o1, o0, 0x40, g1, g3, g5, o5)
+ RMOVE_BIGCHUNK(o1, o0, 0x60, g1, g3, g5, o5)
+ subcc %g6, 128, %g6
+ sub %o1, 128, %o1
+ bne,pt %xcc, 5b
+ sub %o0, 128, %o0
+235: andcc %o2, 0x70, %g6
+41: be,pn %xcc, 280f
+ andcc %o2, 8, %g0
+
+279: rd %pc, %o5
+ sll %g6, 1, %g5
+ sub %o1, %g6, %o1
+ sub %o5, %g5, %o5
+ jmpl %o5 + %lo(280f - 279b), %g0
+ sub %o0, %g6, %o0
+ RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g5, o5)
+ RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g5, o5)
+280: be,pt %xcc, 281f
+ andcc %o2, 4, %g0
+ ldx [%o1 - 8], %g2
+ sub %o0, 8, %o0
+ stw %g2, [%o0 + 4]
+ sub %o1, 8, %o1
+ srlx %g2, 32, %g2
+ stw %g2, [%o0]
+281: be,pt %xcc, 1f
+ andcc %o2, 2, %g0
+ lduw [%o1 - 4], %g2
+ sub %o1, 4, %o1
+ stw %g2, [%o0 - 4]
+ sub %o0, 4, %o0
+1: be,pt %xcc, 1f
+ andcc %o2, 1, %g0
+ lduh [%o1 - 2], %g2
+ sub %o1, 2, %o1
+ sth %g2, [%o0 - 2]
+ sub %o0, 2, %o0
+1: be,pt %xcc, 211f
+ nop
+ ldub [%o1 - 1], %g2
+ stb %g2, [%o0 - 1]
+211: retl
+ mov %g4, %o0
+
+282: RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, g1, g3, g5, o5)
+ RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, g1, g3, g5, o5)
+ subcc %g6, 128, %g6
+ sub %o1, 128, %o1
+ bne,pt %xcc, 282b
+ sub %o0, 128, %o0
+ andcc %o2, 0x70, %g6
+ be,pn %xcc, 284f
+ andcc %o2, 8, %g0
+
+283: rd %pc, %o5
+ sub %o1, %g6, %o1
+ sub %o5, %g6, %o5
+ jmpl %o5 + %lo(284f - 283b), %g0
+ sub %o0, %g6, %o0
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3)
+ RMOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3)
+284: be,pt %xcc, 285f
+ andcc %o2, 4, %g0
+ ldx [%o1 - 8], %g2
+ sub %o0, 8, %o0
+ sub %o1, 8, %o1
+ stx %g2, [%o0]
+285: be,pt %xcc, 1f
+ andcc %o2, 2, %g0
+ lduw [%o1 - 4], %g2
+ sub %o0, 4, %o0
+ sub %o1, 4, %o1
+ stw %g2, [%o0]
+1: be,pt %xcc, 1f
+ andcc %o2, 1, %g0
+ lduh [%o1 - 2], %g2
+ sub %o0, 2, %o0
+ sub %o1, 2, %o1
+ sth %g2, [%o0]
+1: be,pt %xcc, 1f
+ nop
+ ldub [%o1 - 1], %g2
+ stb %g2, [%o0 - 1]
+1: retl
+ mov %g4, %o0
+
+232: ldub [%o1 - 1], %g5
+ sub %o1, 1, %o1
+ sub %o0, 1, %o0
+ subcc %o2, 1, %o2
+ bne,pt %xcc, 232b
+ stb %g5, [%o0]
+234: retl
+ mov %g4, %o0
+END(memmove)
+
+#ifdef USE_BPR
+weak_alias (memcpy, __align_cpy_1)
+weak_alias (memcpy, __align_cpy_2)
+weak_alias (memcpy, __align_cpy_4)
+weak_alias (memcpy, __align_cpy_8)
+weak_alias (memcpy, __align_cpy_16)
+#endif
+libc_hidden_builtin_def (memcpy)
+libc_hidden_builtin_def (memmove)
diff --git a/libc/sysdeps/sparc/sparc64/sparcv9v/memset.S b/libc/sysdeps/sparc/sparc64/sparcv9v/memset.S
new file mode 100644
index 000000000..ac0a50cf8
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/sparcv9v/memset.S
@@ -0,0 +1,127 @@
+/* Set a block of memory to some byte value. For SUN4V Niagara.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David S. Miller (davem@davemloft.net)
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#define ASI_BLK_INIT_QUAD_LDD_P 0xe2
+#define ASI_P 0x80
+#define ASI_PNF 0x82
+
+#ifndef XCC
+#define USE_BPR
+#define XCC xcc
+#endif
+
+ .register %g2,#scratch
+
+ .text
+ .align 32
+
+ENTRY(memset)
+ /* %o0=buf, %o1=pat, %o2=len */
+ and %o1, 0xff, %o3
+ mov %o2, %o1
+ sllx %o3, 8, %g1
+ or %g1, %o3, %o2
+ sllx %o2, 16, %g1
+ or %g1, %o2, %o2
+ sllx %o2, 32, %g1
+ ba,pt %XCC, 1f
+ or %g1, %o2, %o2
+END(memset)
+
+ENTRY(__bzero)
+ clr %o2
+1: brz,pn %o1, 90f
+ mov %o0, %o3
+
+ wr %g0, ASI_P, %asi
+
+ cmp %o1, 15
+ bl,pn %icc, 70f
+ andcc %o0, 0x7, %g1
+ be,pt %XCC, 2f
+ mov 8, %g2
+ sub %g2, %g1, %g1
+ sub %o1, %g1, %o1
+1: stba %o2, [%o0 + 0x00] %asi
+ subcc %g1, 1, %g1
+ bne,pt %XCC, 1b
+ add %o0, 1, %o0
+2: cmp %o1, 128
+ bl,pn %icc, 60f
+ andcc %o0, (64 - 1), %g1
+ be,pt %XCC, 40f
+ mov 64, %g2
+ sub %g2, %g1, %g1
+ sub %o1, %g1, %o1
+1: stxa %o2, [%o0 + 0x00] %asi
+ subcc %g1, 8, %g1
+ bne,pt %XCC, 1b
+ add %o0, 8, %o0
+
+40:
+ wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
+ andn %o1, (64 - 1), %g1
+ sub %o1, %g1, %o1
+50:
+ stxa %o2, [%o0 + 0x00] %asi
+ stxa %o2, [%o0 + 0x08] %asi
+ stxa %o2, [%o0 + 0x10] %asi
+ stxa %o2, [%o0 + 0x18] %asi
+ stxa %o2, [%o0 + 0x20] %asi
+ stxa %o2, [%o0 + 0x28] %asi
+ stxa %o2, [%o0 + 0x30] %asi
+ stxa %o2, [%o0 + 0x38] %asi
+ subcc %g1, 64, %g1
+ bne,pt %XCC, 50b
+ add %o0, 64, %o0
+
+ wr %g0, ASI_P, %asi
+ brz,pn %o1, 80f
+60:
+ andncc %o1, 0x7, %g1
+ be,pn %XCC, 2f
+ sub %o1, %g1, %o1
+1: stxa %o2, [%o0 + 0x00] %asi
+ subcc %g1, 8, %g1
+ bne,pt %XCC, 1b
+ add %o0, 8, %o0
+2: brz,pt %o1, 80f
+ nop
+
+70:
+1: stba %o2, [%o0 + 0x00] %asi
+ subcc %o1, 1, %o1
+ bne,pt %icc, 1b
+ add %o0, 1, %o0
+
+ /* fallthrough */
+
+80:
+ wr %g0, ASI_PNF, %asi
+
+90:
+ retl
+ mov %o3, %o0
+END(__bzero)
+
+libc_hidden_builtin_def (memset)
+weak_alias (__bzero, bzero)
diff --git a/libc/sysdeps/sparc/sparc64/stpcpy.S b/libc/sysdeps/sparc/sparc64/stpcpy.S
new file mode 100644
index 000000000..f4366e9fc
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/stpcpy.S
@@ -0,0 +1,275 @@
+/* Copy SRC to DEST returning the address of the terminating '\0' in DEST.
+ For SPARC v9.
+ Copyright (C) 1998, 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz> and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .register %g6, #scratch
+#endif
+
+ /* Normally, this uses
+ ((xword - 0x0101010101010101) & 0x8080808080808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 32
+ENTRY(__stpcpy)
+ sethi %hi(0x01010101), %g1 /* IEU0 Group */
+ or %g1, %lo(0x01010101), %g1 /* IEU0 Group */
+ andcc %o0, 7, %g0 /* IEU1 */
+ sllx %g1, 32, %g2 /* IEU0 Group */
+
+ bne,pn %icc, 12f /* CTI */
+ andcc %o1, 7, %g3 /* IEU1 */
+ or %g1, %g2, %g1 /* IEU0 Group */
+ bne,pn %icc, 14f /* CTI */
+
+ sllx %g1, 7, %g2 /* IEU0 Group */
+1: ldx [%o1], %o3 /* Load */
+ add %o1, 8, %o1 /* IEU1 */
+2: mov %o3, %g3 /* IEU0 Group */
+
+ sub %o3, %g1, %o2 /* IEU1 */
+3: ldxa [%o1] ASI_PNF, %o3 /* Load */
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o2, %g3, %o2 /* IEU0 Group */
+#endif
+ add %o0, 8, %o0 /* IEU0 Group */
+ andcc %o2, %g2, %g0 /* IEU1 */
+
+ add %o1, 8, %o1 /* IEU0 Group */
+ be,a,pt %xcc, 2b /* CTI */
+ stx %g3, [%o0 - 8] /* Store */
+ srlx %g3, 56, %g5 /* IEU0 Group */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 11f /* CTI */
+ srlx %g3, 48, %g4 /* IEU0 */
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 10f /* CTI */
+ srlx %g3, 40, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 9f /* CTI */
+
+ srlx %g3, 32, %g4 /* IEU0 */
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 8f /* CTI */
+ srlx %g3, 24, %g5 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 7f /* CTI */
+ srlx %g3, 16, %g4 /* IEU0 */
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 6f /* CTI */
+ srlx %g3, 8, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 5f /* CTI */
+
+ sub %o3, %g1, %o2 /* IEU0 */
+ stx %g3, [%o0 - 8] /* Store Group */
+ andcc %g3, 0xff, %g0 /* IEU1 */
+ bne,pt %icc, 3b /* CTI */
+
+ mov %o3, %g3 /* IEU0 Group */
+4: retl /* CTI+IEU1 Group */
+ sub %o0, 1, %o0 /* IEU0 */
+
+ .align 16
+6: ba,pt %xcc, 23f /* CTI Group */
+ sub %o0, 3, %g6 /* IEU0 */
+5: sub %o0, 2, %g6 /* IEU0 Group */
+ stb %g5, [%o0 - 2] /* Store */
+
+ srlx %g3, 16, %g4 /* IEU0 Group */
+23: sth %g4, [%o0 - 4] /* Store */
+ srlx %g3, 32, %g4 /* IEU0 Group */
+ stw %g4, [%o0 - 8] /* Store */
+
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+8: ba,pt %xcc, 24f /* CTI Group */
+ sub %o0, 5, %g6 /* IEU0 */
+
+7: sub %o0, 4, %g6 /* IEU0 Group */
+ stb %g5, [%o0 - 4] /* Store */
+ srlx %g3, 32, %g4 /* IEU0 Group */
+24: stw %g4, [%o0 - 8] /* Store */
+
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+10: ba,pt %xcc, 25f /* CTI Group */
+ sub %o0, 7, %g6 /* IEU0 */
+
+9: sub %o0, 6, %g6 /* IEU0 Group */
+ stb %g5, [%o0 - 6] /* Store */
+ srlx %g3, 48, %g4 /* IEU0 */
+25: sth %g4, [%o0 - 8] /* Store Group */
+
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+11: stb %g5, [%o0 - 8] /* Store Group */
+ retl /* CTI+IEU1 Group */
+
+ sub %o0, 8, %o0 /* IEU0 */
+
+ .align 16
+12: or %g1, %g2, %g1 /* IEU0 Group */
+ ldub [%o1], %o3 /* Load */
+ sllx %g1, 7, %g2 /* IEU0 Group */
+ stb %o3, [%o0] /* Store Group */
+
+13: add %o0, 1, %o0 /* IEU0 */
+ add %o1, 1, %o1 /* IEU1 */
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+
+ lduba [%o1] ASI_PNF, %o3 /* Load */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+ bne,a,pt %icc, 13b /* CTI */
+ stb %o3, [%o0] /* Store */
+
+ andcc %o1, 7, %g3 /* IEU1 Group */
+ be,a,pt %icc, 1b /* CTI */
+ ldx [%o1], %o3 /* Load */
+14: orcc %g0, 64, %g4 /* IEU1 Group */
+
+ sllx %g3, 3, %g5 /* IEU0 */
+ sub %o1, %g3, %o1 /* IEU0 Group */
+ sub %g4, %g5, %g4 /* IEU1 */
+ /* %g1 = 0101010101010101 *
+ * %g2 = 8080808080808080 *
+ * %g3 = source alignment *
+ * %g5 = number of bits to shift left *
+ * %g4 = number of bits to shift right */
+ ldxa [%o1] ASI_PNF, %o5 /* Load Group */
+
+ addcc %o1, 8, %o1 /* IEU1 */
+15: sllx %o5, %g5, %o3 /* IEU0 Group */
+ ldxa [%o1] ASI_PNF, %o5 /* Load */
+ srlx %o5, %g4, %o4 /* IEU0 Group */
+
+ add %o0, 8, %o0 /* IEU1 */
+ or %o3, %o4, %o3 /* IEU0 Group */
+ add %o1, 8, %o1 /* IEU1 */
+ sub %o3, %g1, %o4 /* IEU0 Group */
+
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o3, %o4 /* IEU0 Group */
+#endif
+ andcc %o4, %g2, %g0 /* IEU1 Group */
+ be,a,pt %xcc, 15b /* CTI */
+ stx %o3, [%o0 - 8] /* Store */
+ srlx %o3, 56, %o4 /* IEU0 Group */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 22f /* CTI */
+ srlx %o3, 48, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 21f /* CTI */
+ srlx %o3, 40, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 20f /* CTI */
+
+ srlx %o3, 32, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 19f /* CTI */
+ srlx %o3, 24, %o4 /* IEU0 */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 18f /* CTI */
+ srlx %o3, 16, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 17f /* CTI */
+ srlx %o3, 8, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 16f /* CTI */
+
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+ bne,pn %icc, 15b /* CTI */
+ stx %o3, [%o0 - 8] /* Store */
+ retl /* CTI+IEU1 Group */
+
+ sub %o0, 1, %o0 /* IEU0 */
+
+ .align 16
+17: ba,pt %xcc, 26f /* CTI Group */
+ subcc %o0, 3, %g6 /* IEU1 */
+18: ba,pt %xcc, 27f /* CTI Group */
+ subcc %o0, 4, %g6 /* IEU1 */
+
+19: ba,pt %xcc, 28f /* CTI Group */
+ subcc %o0, 5, %g6 /* IEU1 */
+16: subcc %o0, 2, %g6 /* IEU1 Group */
+ srlx %o3, 8, %o4 /* IEU0 */
+
+ stb %o4, [%o0 - 2] /* Store */
+26: srlx %o3, 16, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 3] /* Store */
+27: srlx %o3, 24, %o4 /* IEU0 Group */
+
+ stb %o4, [%o0 - 4] /* Store */
+28: srlx %o3, 32, %o4 /* IEU0 Group */
+ stw %o4, [%o0 - 8] /* Store */
+ retl /* CTI+IEU1 Group */
+
+ mov %g6, %o0 /* IEU0 */
+
+ .align 16
+21: ba,pt %xcc, 29f /* CTI Group */
+ subcc %o0, 7, %g6 /* IEU1 */
+22: ba,pt %xcc, 30f /* CTI Group */
+ subcc %o0, 8, %g6 /* IEU1 */
+
+20: subcc %o0, 6, %g6 /* IEU1 Group */
+ srlx %o3, 40, %o4 /* IEU0 */
+ stb %o4, [%o0 - 6] /* Store */
+29: srlx %o3, 48, %o4 /* IEU0 Group */
+
+ stb %o4, [%o0 - 7] /* Store */
+30: srlx %o3, 56, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 8] /* Store */
+ retl /* CTI+IEU1 Group */
+
+ mov %g6, %o0 /* IEU0 */
+END(__stpcpy)
+
+weak_alias (__stpcpy, stpcpy)
+libc_hidden_def (__stpcpy)
+libc_hidden_builtin_def (stpcpy)
diff --git a/libc/sysdeps/sparc/sparc64/stpncpy.S b/libc/sysdeps/sparc/sparc64/stpncpy.S
new file mode 100644
index 000000000..c1ea820a9
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/stpncpy.S
@@ -0,0 +1,425 @@
+/* stpncpy(DST, SRC, COUNT) - Copy no more than N characters of
+ SRC to DEST, returning the address of the terminating '\0' in
+ DEST, if any, or else DEST + N.
+ For SPARC v9.
+ Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz> and
+ Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define XCC xcc
+#define USE_BPR
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .register %g6, #scratch
+#endif
+
+ /* Normally, this uses
+ ((xword - 0x0101010101010101) & 0x8080808080808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 32
+ENTRY(__stpncpy)
+ sethi %hi(0x01010101), %g1 /* IEU0 Group */
+#ifdef USE_BPR
+ brz,pn %o2, 19f /* CTI+IEU1 */
+#else
+ tst %o2 /* IEU1 */
+ be,pn %XCC, 19f /* CTI */
+#endif
+ or %g1, %lo(0x01010101), %g1 /* IEU1 */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+
+ sllx %g1, 32, %g2 /* IEU0 */
+ bne,pn %icc, 26f /* CTI */
+ or %g1, %g2, %g1 /* IEU0 Group */
+ andcc %o1, 7, %g3 /* IEU1 */
+
+ bne,pn %icc, 28f /* CTI */
+ sllx %g1, 7, %g2 /* IEU0 Group */
+ ldx [%o1], %o3 /* Load */
+1: add %o1, 8, %o1 /* IEU1 */
+
+2: subcc %o2, 8, %o2 /* IEU1 Group */
+ bl,pn %XCC, 18f /* CTI */
+ sub %o3, %g1, %o4 /* IEU0 */
+ add %o0, 8, %o0 /* IEU0 Group */
+
+#ifdef EIGHTBIT_NOT_MORE
+ andn %o4, %o3, %o4 /* IEU1 */
+#endif
+ mov %o3, %g3 /* IEU1 */
+ ldxa [%o1] ASI_PNF, %o3 /* Load */
+ add %o1, 8, %o1 /* IEU0 Group */
+ andcc %o4, %g2, %g0 /* IEU1 */
+
+ be,a,pt %xcc, 2b /* CTI */
+ stx %g3, [%o0-8] /* Store Group */
+ srlx %g3, 56, %g5 /* IEU0 Group */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 16f /* CTI */
+ srlx %g3, 48, %g4 /* IEU0 */
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 15f /* CTI */
+
+ srlx %g3, 40, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 14f /* CTI */
+ srlx %g3, 32, %g4 /* IEU0 */
+
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 13f /* CTI */
+ srlx %g3, 24, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 12f /* CTI */
+ srlx %g3, 16, %g4 /* IEU0 */
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 11f /* CTI */
+
+ srlx %g3, 8, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 10f /* CTI */
+ sub %o0, 1, %g6 /* IEU0 */
+
+ andcc %g3, 0xff, %g0 /* IEU1 Group */
+ bne,pt %icc, 2b /* CTI */
+3: stx %g3, [%o0-8] /* Store */
+ andncc %o2, 31, %g3 /* IEU1 Group */
+
+4: be,pn %XCC, 41f /* CTI */
+ and %o2, 31, %o2 /* IEU1 Group */
+40: stx %g0, [%o0] /* Store */
+ stx %g0, [%o0 + 8] /* Store Group */
+
+ subcc %g3, 32, %g3 /* IEU1 */
+ stx %g0, [%o0 + 16] /* Store Group */
+ stx %g0, [%o0 + 24] /* Store Group */
+ bne,pt %XCC, 40b /* CTI */
+
+ add %o0, 32, %o0 /* IEU0 */
+41: subcc %o2, 8, %o2 /* IEU1 Group */
+ bl,a,pn %XCC, 6f /* CTI */
+ andcc %o2, 4, %g0 /* IEU1 Group */
+
+5: stx %g0, [%o0] /* Store */
+ subcc %o2, 8, %o2 /* IEU1 Group */
+ bge,pt %XCC, 5b /* CTI */
+ add %o0, 8, %o0 /* IEU0 */
+
+ andcc %o2, 4, %g0 /* IEU1 Group */
+6: be,a,pn %icc, 7f /* CTI */
+ andcc %o2, 2, %g0 /* IEU1 Group */
+ stw %g0, [%o0] /* Store */
+
+ add %o0, 4, %o0 /* IEU0 */
+ andcc %o2, 2, %g0 /* IEU1 Group */
+7: be,a,pn %icc, 8f /* CTI */
+ andcc %o2, 1, %g0 /* IEU1 Group */
+
+ sth %g0, [%o0] /* Store */
+ add %o0, 2, %o0 /* IEU0 */
+ andcc %o2, 1, %g0 /* IEU1 Group */
+8: bne,a,pn %icc, 9f /* CTI */
+
+ stb %g0, [%o0] /* Store */
+9: retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+10: subcc %o0, 2, %g6 /* IEU1 Group */
+
+ ba,pt %xcc, 3b /* CTI */
+ sllx %g5, 8, %g3 /* IEU0 */
+11: subcc %o0, 3, %g6 /* IEU1 Group */
+ ba,pt %xcc, 3b /* CTI */
+
+ sllx %g4, 16, %g3 /* IEU0 */
+12: subcc %o0, 4, %g6 /* IEU1 Group */
+ ba,pt %xcc, 3b /* CTI */
+ sllx %g5, 24, %g3 /* IEU0 */
+
+13: subcc %o0, 5, %g6 /* IEU1 Group */
+ ba,pt %xcc, 3b /* CTI */
+ sllx %g4, 32, %g3 /* IEU0 */
+14: subcc %o0, 6, %g6 /* IEU1 Group */
+
+ ba,pt %xcc, 3b /* CTI */
+ sllx %g5, 40, %g3 /* IEU0 */
+15: subcc %o0, 7, %g6 /* IEU1 Group */
+ ba,pt %xcc, 3b /* CTI */
+
+ sllx %g4, 48, %g3 /* IEU0 */
+16: subcc %o0, 8, %g6 /* IEU1 Group */
+ ba,pt %xcc, 3b /* CTI */
+ clr %g3 /* IEU0 */
+
+ .align 16
+17: or %o3, %o4, %o3 /* IEU0 Group */
+ sub %o3, %g1, %o4 /* IEU1 */
+18: addcc %o2, 8, %o2 /* IEU1 Group */
+ be,pn %XCC, 19f /* CTI */
+
+ andcc %o4, %g2, %g0 /* IEU1 Group */
+ be,pt %xcc, 21f /* CTI */
+ srlx %o3, 56, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 20f /* CTI */
+ stb %g5, [%o0] /* Store */
+ add %o0, 1, %o0 /* IEU0 Group */
+ subcc %o2, 1, %o2 /* IEU1 */
+
+ be,pn %XCC, 19f /* CTI */
+ srlx %o3, 48, %g5 /* IEU0 Group */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 20f /* CTI */
+
+ stb %g5, [%o0] /* Store */
+ add %o0, 1, %o0 /* IEU0 Group */
+ subcc %o2, 1, %o2 /* IEU1 */
+ be,pn %XCC, 19f /* CTI */
+
+ srlx %o3, 40, %g5 /* IEU0 Group */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 20f /* CTI */
+ stb %g5, [%o0] /* Store */
+
+ add %o0, 1, %o0 /* IEU0 Group */
+ subcc %o2, 1, %o2 /* IEU1 */
+ be,pn %XCC, 19f /* CTI */
+ srlx %o3, 32, %g5 /* IEU0 Group */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 20f /* CTI */
+ stb %g5, [%o0] /* Store */
+ add %o0, 1, %o0 /* IEU0 Group */
+
+ subcc %o2, 1, %o2 /* IEU1 */
+ be,pn %XCC, 19f /* CTI */
+ srlx %o3, 24, %g5 /* IEU0 Group */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 20f /* CTI */
+ stb %g5, [%o0] /* Store */
+ add %o0, 1, %o0 /* IEU0 Group */
+ subcc %o2, 1, %o2 /* IEU1 */
+
+ be,pn %XCC, 19f /* CTI */
+ srlx %o3, 16, %g5 /* IEU0 Group */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 20f /* CTI */
+
+ stb %g5, [%o0] /* Store */
+ add %o0, 1, %o0 /* IEU0 Group */
+ subcc %o2, 1, %o2 /* IEU1 */
+ be,pn %XCC, 19f /* CTI */
+
+ srlx %o3, 8, %o3 /* IEU0 Group */
+ stb %o3, [%o0] /* Store */
+59: add %o0, 1, %o2 /* IEU1 */
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+
+ retl /* CTI+IEU1 Group */
+ movne %icc, %o2, %o0 /* Single Group */
+19: retl /* CTI+IEU1 Group */
+ nop /* IEU0 */
+
+20: mov %o0, %g6 /* IEU0 Group */
+ subcc %o2, 1, %o2 /* IEU1 */
+ be,pn %XCC, 51f /* CTI */
+ add %o0, 1, %o0 /* IEU0 Group */
+
+50: stb %g0, [%o0] /* Store Group */
+ subcc %o2, 1, %o2 /* IEU1 Group */
+ bne,pt %XCC, 50b /* CTI */
+ add %o0, 1, %o0 /* IEU0 */
+
+51: retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+
+ .align 16
+21: andcc %o2, 4, %g0 /* IEU1 Group */
+ be,pn %icc, 22f /* CTI */
+ srlx %o3, 32, %g5 /* IEU0 */
+ stw %g5, [%o0] /* Store Group */
+
+ add %o0, 4, %o0 /* IEU0 */
+ mov %o3, %g5 /* IEU1 */
+22: andcc %o2, 2, %g0 /* IEU1 Group */
+ be,pn %icc, 23f /* CTI */
+
+ srlx %g5, 16, %g4 /* IEU0 */
+ sth %g4, [%o0] /* Store Group */
+ add %o0, 2, %o0 /* IEU0 */
+ mov %g5, %g4 /* IEU1 */
+
+23: srlx %g4, 8, %g4 /* IEU0 Group */
+ andcc %o2, 1, %g0 /* IEU1 */
+ bne,a,pn %icc, 24f /* CTI */
+ stb %g4, [%o0] /* Store Group */
+
+ retl /* CTI+IEU1 Group */
+ nop /* IEU0 */
+24: retl /* CTI+IEU1 Group */
+ add %o0, 1, %o0 /* IEU0 */
+
+ .align 16
+55: sub %o0, 1, %g6 /* IEU0 Group */
+25: andcc %o0, 7, %g0 /* IEU1 */
+ be,a,pn %icc, 4b /* CTI */
+ andncc %o2, 31, %g3 /* IEU1 Group */
+
+ stb %g0, [%o0] /* Store Group */
+ subcc %o2, 1, %o2 /* IEU1 */
+ bne,pt %XCC, 25b /* CTI */
+ add %o0, 1, %o0 /* IEU0 Group */
+
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+
+ .align 16
+26: ldub [%o1], %o3 /* Load */
+ sllx %g1, 7, %g2 /* IEU0 Group */
+ stb %o3, [%o0] /* Store */
+27: subcc %o2, 1, %o2 /* IEU1 */
+
+ be,pn %XCC, 59b /* CTI */
+ add %o1, 1, %o1 /* IEU0 Group */
+ add %o0, 1, %o0 /* IEU1 */
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 55b /* CTI */
+ lduba [%o1] ASI_PNF, %o3 /* Load */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+ bne,a,pt %icc, 27b /* CTI */
+
+ stb %o3, [%o0] /* Store */
+ andcc %o1, 7, %g3 /* IEU1 Group */
+ be,a,pt %icc, 1b /* CTI */
+ ldx [%o1], %o3 /* Load */
+
+28: orcc %g0, 64, %g4 /* IEU1 Group */
+ sllx %g3, 3, %g5 /* IEU0 */
+ sub %g4, %g5, %g4 /* IEU0 Group */
+ sub %o1, %g3, %o1 /* IEU1 */
+ /* %g1 = 0101010101010101
+ %g2 = 8080808080808080
+ %g3 = source alignment
+ %g5 = number of bits to shift left
+ %g4 = number of bits to shift right */
+
+ ldxa [%o1] ASI_PNF, %o5 /* Load Group */
+ addcc %o1, 8, %o1 /* IEU1 */
+29: sllx %o5, %g5, %o3 /* IEU0 Group */
+ ldxa [%o1] ASI_PNF, %o5 /* Load */
+
+ subcc %o2, 8, %o2 /* IEU1 */
+ bl,pn %XCC, 17b /* CTI */
+ srlx %o5, %g4, %o4 /* IEU0 Group */
+ add %o1, 8, %o1 /* IEU1 */
+
+ or %o3, %o4, %o3 /* IEU0 Group */
+ add %o0, 8, %o0 /* IEU1 */
+ sub %o3, %g1, %o4 /* IEU0 Group */
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o3, %o4 /* IEU0 Group */
+#endif
+ andcc %o4, %g2, %g0 /* IEU1 Group */
+
+ be,a,pt %xcc, 29b /* CTI */
+ stx %o3, [%o0-8] /* Store */
+ srlx %o3, 56, %o4 /* IEU0 Group */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 36f /* CTI */
+ srlx %o3, 48, %g6 /* IEU0 */
+ andcc %g6, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 35f /* CTI */
+
+ srlx %o3, 40, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 34f /* CTI */
+ srlx %o3, 32, %g6 /* IEU0 */
+
+ andcc %g6, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 33f /* CTI */
+ srlx %o3, 24, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 32f /* CTI */
+ srlx %o3, 16, %g6 /* IEU0 */
+ andcc %g6, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 31f /* CTI */
+
+ srlx %o3, 8, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 30f /* CTI */
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+
+ bne,pn %icc, 29b /* CTI */
+ stx %o3, [%o0-8] /* Store */
+ sub %o0, 1, %g6 /* IEU0 Group */
+ ba,pt %xcc, 4b /* CTI */
+
+ andncc %o2, 31, %g3 /* IEU1 */
+30: subcc %o0, 2, %g6 /* IEU0 */
+ ba,pt %xcc, 3b /* CTI */
+ sllx %o4, 8, %g3 /* IEU0 Group */
+
+31: sllx %g6, 16, %g3 /* IEU0 Group */
+ ba,pt %xcc, 3b /* CTI */
+ sub %o0, 3, %g6 /* IEU1 */
+32: subcc %o0, 4, %g6 /* IEU1 Group */
+
+ ba,pt %xcc, 3b /* CTI */
+ sllx %o4, 24, %g3 /* IEU0 */
+33: sllx %g6, 32, %g3 /* IEU0 Group */
+ ba,pt %xcc, 3b /* CTI */
+
+ sub %o0, 5, %g6 /* IEU1 */
+34: subcc %o0, 6, %g6 /* IEU1 Group */
+ ba,pt %xcc, 3b /* CTI */
+ sllx %o4, 40, %g3 /* IEU0 */
+
+35: sllx %g6, 48, %g3 /* IEU0 Group */
+ ba,pt %xcc, 3b /* CTI */
+ sub %o0, 7, %g6 /* IEU1 */
+36: subcc %o0, 8, %g6 /* IEU1 Group */
+
+ ba,pt %xcc, 3b /* CTI */
+ sllx %o4, 56, %g3 /* IEU0 */
+END(__stpncpy)
+
+libc_hidden_def (__stpncpy)
+weak_alias (__stpncpy, stpncpy)
diff --git a/libc/sysdeps/sparc/sparc64/strcat.S b/libc/sysdeps/sparc/sparc64/strcat.S
new file mode 100644
index 000000000..43b3d6c17
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/strcat.S
@@ -0,0 +1,340 @@
+/* strcat (dest, src) -- Append SRC on the end of DEST.
+ For SPARC v9.
+ Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz> and
+ Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define XCC xcc
+#define USE_BPR
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .register %g6, #scratch
+#endif
+
+ /* Normally, this uses
+ ((xword - 0x0101010101010101) & 0x8080808080808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 32
+ENTRY(strcat)
+ sethi %hi(0x01010101), %g1 /* IEU0 Group */
+ ldub [%o0], %o3 /* Load */
+ or %g1, %lo(0x01010101), %g1 /* IEU0 Group */
+ mov %o0, %g6 /* IEU1 */
+
+ sllx %g1, 32, %g2 /* IEU0 Group */
+ andcc %o0, 7, %g0 /* IEU1 */
+ or %g1, %g2, %g1 /* IEU0 Group */
+ bne,pn %icc, 32f /* CTI */
+
+ sllx %g1, 7, %g2 /* IEU0 Group */
+ brz,pn %o3, 30f /* CTI+IEU1 */
+ ldx [%o0], %o3 /* Load */
+48: add %o0, 8, %o0 /* IEU0 Group */
+
+49: sub %o3, %g1, %o2 /* IEU0 Group */
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o2, %o3, %g5 /* IEU0 Group */
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ andcc %g5, %g2, %g0 /* IEU1 Group */
+#else
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ andcc %o2, %g2, %g0 /* IEU1 Group */
+#endif
+ be,pt %xcc, 49b /* CTI */
+
+ add %o0, 8, %o0 /* IEU0 */
+ addcc %o2, %g1, %g3 /* IEU1 Group */
+ srlx %o2, 32, %o2 /* IEU0 */
+50: andcc %o2, %g2, %g0 /* IEU1 Group */
+
+ be,pn %xcc, 51f /* CTI */
+ srlx %g3, 56, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 29f /* CTI */
+
+ srlx %g3, 48, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 28f /* CTI */
+ srlx %g3, 40, %o2 /* IEU0 */
+
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 27f /* CTI */
+ srlx %g3, 32, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 26f /* CTI */
+51: srlx %g3, 24, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 25f /* CTI */
+
+ srlx %g3, 16, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 24f /* CTI */
+ srlx %g3, 8, %o2 /* IEU0 */
+
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 23f /* CTI */
+ sub %o3, %g1, %o2 /* IEU0 */
+ andcc %g3, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 52f /* CTI */
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ andcc %o2, %g2, %g0 /* IEU1 Group */
+ be,pt %xcc, 49b /* CTI */
+
+ add %o0, 8, %o0 /* IEU0 */
+ addcc %o2, %g1, %g3 /* IEU1 Group */
+ ba,pt %xcc, 50b /* CTI */
+ srlx %o2, 32, %o2 /* IEU0 */
+
+ .align 16
+52: ba,pt %xcc, 12f /* CTI Group */
+ add %o0, -9, %o0 /* IEU0 */
+23: ba,pt %xcc, 12f /* CTI Group */
+ add %o0, -10, %o0 /* IEU0 */
+
+24: ba,pt %xcc, 12f /* CTI Group */
+ add %o0, -11, %o0 /* IEU0 */
+25: ba,pt %xcc, 12f /* CTI Group */
+ add %o0, -12, %o0 /* IEU0 */
+
+26: ba,pt %xcc, 12f /* CTI Group */
+ add %o0, -13, %o0 /* IEU0 */
+27: ba,pt %xcc, 12f /* CTI Group */
+ add %o0, -14, %o0 /* IEU0 */
+
+28: ba,pt %xcc, 12f /* CTI Group */
+ add %o0, -15, %o0 /* IEU0 */
+29: add %o0, -16, %o0 /* IEU0 Group */
+30: andcc %o1, 7, %g3 /* IEU1 */
+
+31: bne,pn %icc, 14f /* CTI */
+ orcc %g0, 64, %g4 /* IEU1 Group */
+1: ldx [%o1], %o3 /* Load */
+ add %o1, 8, %o1 /* IEU1 */
+
+2: mov %o3, %g3 /* IEU0 Group */
+3: sub %o3, %g1, %o2 /* IEU1 */
+ ldxa [%o1] ASI_PNF, %o3 /* Load */
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o2, %g3, %o2 /* IEU0 Group */
+#endif
+ add %o0, 8, %o0 /* IEU0 Group */
+
+ andcc %o2, %g2, %g0 /* IEU1 */
+ add %o1, 8, %o1 /* IEU0 Group */
+ be,a,pt %xcc, 2b /* CTI */
+ stx %g3, [%o0 - 8] /* Store */
+
+ srlx %g3, 56, %g5 /* IEU0 Group */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 11f /* CTI */
+ srlx %g3, 48, %g4 /* IEU0 */
+
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 10f /* CTI */
+ srlx %g3, 40, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 9f /* CTI */
+ srlx %g3, 32, %g4 /* IEU0 */
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 8f /* CTI */
+
+ srlx %g3, 24, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 7f /* CTI */
+ srlx %g3, 16, %g4 /* IEU0 */
+
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 6f /* CTI */
+ srlx %g3, 8, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 5f /* CTI */
+ sub %o3, %g1, %o2 /* IEU0 */
+ stx %g3, [%o0 - 8] /* Store Group */
+ andcc %g3, 0xff, %g0 /* IEU1 */
+
+ bne,pt %icc, 3b /* CTI */
+ mov %o3, %g3 /* IEU0 Group */
+4: retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+
+ .align 16
+5: stb %g5, [%o0 - 2] /* Store Group */
+ srlx %g3, 16, %g4 /* IEU0 */
+6: sth %g4, [%o0 - 4] /* Store Group */
+ srlx %g3, 32, %g4 /* IEU0 */
+
+ stw %g4, [%o0 - 8] /* Store Group */
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+7: stb %g5, [%o0 - 4] /* Store Group */
+
+ srlx %g3, 32, %g4 /* IEU0 */
+8: stw %g4, [%o0 - 8] /* Store Group */
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+
+9: stb %g5, [%o0 - 6] /* Store Group */
+ srlx %g3, 48, %g4 /* IEU0 */
+10: sth %g4, [%o0 - 8] /* Store Group */
+ retl /* CTI+IEU1 Group */
+
+ mov %g6, %o0 /* IEU0 */
+11: stb %g5, [%o0 - 8] /* Store Group */
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+
+ .align 16
+32: andcc %o0, 7, %g0 /* IEU1 Group */
+ be,a,pn %icc, 48b /* CTI */
+ ldx [%o0], %o3 /* Load */
+ add %o0, 1, %o0 /* IEU0 Group */
+
+ brnz,a,pt %o3, 32b /* CTI+IEU1 */
+ lduba [%o0] ASI_PNF, %o3 /* Load */
+ add %o0, -1, %o0 /* IEU0 Group */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+
+ be,a,pn %icc, 31b /* CTI */
+ andcc %o1, 7, %g3 /* IEU1 Group */
+12: ldub [%o1], %o3 /* Load */
+ stb %o3, [%o0] /* Store Group */
+
+13: add %o0, 1, %o0 /* IEU0 */
+ add %o1, 1, %o1 /* IEU1 */
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+
+ lduba [%o1] ASI_PNF, %o3 /* Load */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+ bne,a,pt %icc, 13b /* CTI */
+ stb %o3, [%o0] /* Store */
+
+ andcc %o1, 7, %g3 /* IEU1 Group */
+ be,a,pt %icc, 1b /* CTI */
+ ldx [%o1], %o3 /* Load */
+ orcc %g0, 64, %g4 /* IEU1 Group */
+
+14: sllx %g3, 3, %g5 /* IEU0 */
+ sub %o1, %g3, %o1 /* IEU0 Group */
+ sub %g4, %g5, %g4 /* IEU1 */
+ /* %g1 = 0101010101010101 *
+ * %g2 = 8080808080808080 *
+ * %g3 = source alignment *
+ * %g5 = number of bits to shift left *
+ * %g4 = number of bits to shift right */
+ ldxa [%o1] ASI_PNF, %o5 /* Load Group */
+
+ addcc %o1, 8, %o1 /* IEU1 */
+15: sllx %o5, %g5, %o3 /* IEU0 Group */
+ ldxa [%o1] ASI_PNF, %o5 /* Load */
+ srlx %o5, %g4, %o4 /* IEU0 Group */
+
+ add %o0, 8, %o0 /* IEU1 */
+ or %o3, %o4, %o3 /* IEU0 Group */
+ add %o1, 8, %o1 /* IEU1 */
+ sub %o3, %g1, %o4 /* IEU0 Group */
+
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o3, %o4 /* IEU0 Group */
+#endif
+ andcc %o4, %g2, %g0 /* IEU1 Group */
+ be,a,pt %xcc, 15b /* CTI */
+ stx %o3, [%o0 - 8] /* Store */
+ srlx %o3, 56, %o4 /* IEU0 Group */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 22f /* CTI */
+ srlx %o3, 48, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 21f /* CTI */
+ srlx %o3, 40, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 20f /* CTI */
+
+ srlx %o3, 32, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 19f /* CTI */
+ srlx %o3, 24, %o4 /* IEU0 */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 18f /* CTI */
+ srlx %o3, 16, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 17f /* CTI */
+ srlx %o3, 8, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 16f /* CTI */
+
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+ bne,pn %icc, 15b /* CTI */
+ stx %o3, [%o0 - 8] /* Store */
+ retl /* CTI+IEU1 Group */
+
+ mov %g6, %o0 /* IEU0 */
+
+ .align 16
+16: srlx %o3, 8, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 2] /* Store */
+17: srlx %o3, 16, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 3] /* Store */
+
+18: srlx %o3, 24, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 4] /* Store */
+19: srlx %o3, 32, %o4 /* IEU0 Group */
+ stw %o4, [%o0 - 8] /* Store */
+
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+ nop
+ nop
+
+20: srlx %o3, 40, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 6] /* Store */
+21: srlx %o3, 48, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 7] /* Store */
+
+22: srlx %o3, 56, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 8] /* Store */
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+END(strcat)
+libc_hidden_builtin_def (strcat)
diff --git a/libc/sysdeps/sparc/sparc64/strchr.S b/libc/sysdeps/sparc/sparc64/strchr.S
new file mode 100644
index 000000000..d19c2dddb
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/strchr.S
@@ -0,0 +1,483 @@
+/* strchr (str, ch) -- Return pointer to first occurrence of CH in STR.
+ For SPARC v9.
+ Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz> and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define XCC xcc
+#define USE_BPR
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .register %g6, #scratch
+#endif
+
+ /* Normally, this uses
+ ((xword - 0x0101010101010101) & 0x8080808080808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 32
+ENTRY(strchr)
+ andcc %o1, 0xff, %o1 /* IEU1 Group */
+ be,pn %icc, 17f /* CTI */
+ sllx %o1, 8, %g3 /* IEU0 Group */
+ sethi %hi(0x01010101), %g1 /* IEU1 */
+
+ or %g3, %o1, %g3 /* IEU0 Group */
+ ldub [%o0], %o3 /* Load */
+ sllx %g3, 16, %g5 /* IEU0 Group */
+ or %g1, %lo(0x01010101), %g1 /* IEU1 */
+
+ sllx %g1, 32, %g2 /* IEU0 Group */
+ brz,pn %o3, 5f /* CTI+IEU1 */
+ orcc %g3, %g5, %g3 /* IEU1 Group */
+ sllx %g3, 32, %g5 /* IEU0 */
+
+ cmp %o3, %o1 /* IEU1 Group */
+ be,pn %xcc, 14f /* CTI */
+ or %g1, %g2, %g1 /* IEU0 */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+
+ bne,a,pn %icc, 15f /* CTI */
+ add %o0, 1, %o0 /* IEU0 */
+ ldx [%o0], %o3 /* Load Group */
+1: sllx %g1, 7, %g2 /* IEU0 */
+
+ or %g3, %g5, %g3 /* IEU1 */
+ add %o0, 8, %o0 /* IEU0 Group */
+ xor %o3, %g3, %o4 /* IEU1 */
+ /* %g1 = 0101010101010101 *
+ * %g2 = 8080088080808080 *
+ * %g3 = c c c c c c c c *
+ * %o3 = value *
+ * %o4 = value XOR c */
+2: sub %o3, %g1, %o2 /* IEU0 Group */
+
+ sub %o4, %g1, %o5 /* IEU1 */
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o2, %o3, %g6 /* IEU0 Group */
+ andn %o5, %o4, %o5 /* IEU1 */
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ or %o5, %g6, %o5 /* IEU0 Group */
+#else
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ or %o5, %o2, %o5 /* IEU0 Group */
+#endif
+ add %o0, 8, %o0 /* IEU1 */
+
+ andcc %o5, %g2, %g0 /* IEU1 Group */
+ be,a,pt %xcc, 2b /* CTI */
+ xor %o3, %g3, %o4 /* IEU0 */
+ srlx %o5, 32, %g5 /* IEU0 Group */
+
+ add %o2, %g1, %o2 /* IEU1 */
+3: andcc %g5, %g2, %g0 /* IEU1 Group */
+ be,pn %xcc, 4f /* CTI */
+ srlx %o2, 56, %g5 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 5f /* CTI */
+ srlx %o4, 56, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 6f /* CTI */
+ srlx %o2, 48, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 5f /* CTI */
+
+ srlx %o4, 48, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 7f /* CTI */
+ srlx %o2, 40, %g5 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 5f /* CTI */
+ srlx %o4, 40, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 8f /* CTI */
+ srlx %o2, 32, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 5f /* CTI */
+
+ srlx %o4, 32, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 9f /* CTI */
+4: srlx %o2, 24, %g5 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 5f /* CTI */
+ srlx %o4, 24, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 10f /* CTI */
+ srlx %o2, 16, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 5f /* CTI */
+
+ srlx %o4, 16, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 11f /* CTI */
+ srlx %o2, 8, %g5 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 5f /* CTI */
+ srlx %o4, 8, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 12f /* CTI */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 5f /* CTI */
+ sub %o3, %g1, %o2 /* IEU0 */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 13f /* CTI */
+ xor %o3, %g3, %o4 /* IEU0 */
+ ldxa [%o0] ASI_PNF, %o3 /* Load Group */
+
+ sub %o4, %g1, %o5 /* IEU0 */
+ or %o5, %o2, %o5 /* IEU1 */
+ add %o0, 8, %o0 /* IEU0 Group */
+ andcc %o5, %g2, %g0 /* IEU1 */
+
+ be,a,pt %xcc, 2b /* CTI */
+ xor %o3, %g3, %o4 /* IEU0 Group */
+ srlx %o5, 32, %g5 /* IEU0 Group */
+ ba,pt %xcc, 3b /* CTI */
+
+ add %o2, %g1, %o2 /* IEU1 */
+
+ .align 16
+5: retl /* CTI+IEU1 Group */
+ clr %o0 /* IEU0 */
+6: retl /* CTI+IEU1 Group */
+ add %o0, -16, %o0 /* IEU0 */
+
+7: retl /* CTI+IEU1 Group */
+ add %o0, -15, %o0 /* IEU0 */
+8: retl /* CTI+IEU1 Group */
+ add %o0, -14, %o0 /* IEU0 */
+
+9: retl /* CTI+IEU1 Group */
+ add %o0, -13, %o0 /* IEU0 */
+10: retl /* CTI+IEU1 Group */
+ add %o0, -12, %o0 /* IEU0 */
+
+11: retl /* CTI+IEU1 Group */
+ add %o0, -11, %o0 /* IEU0 */
+12: retl /* CTI+IEU1 Group */
+ add %o0, -10, %o0 /* IEU0 */
+
+13: retl /* CTI+IEU1 Group */
+ add %o0, -9, %o0 /* IEU0 */
+14: retl /* CTI+IEU1 Group */
+ nop /* IEU0 */
+
+ .align 16
+15: ldub [%o0], %o3 /* Load Group */
+16: andcc %o0, 7, %g0 /* IEU1 */
+ be,a,pn %icc, 1b /* CTI */
+ ldx [%o0], %o3 /* Load Group */
+
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 5b /* CTI */
+ add %o0, 1, %o0 /* IEU0 */
+ cmp %o3, %o1 /* IEU1 Group */
+
+ bne,a,pn %icc, 16b /* CTI */
+ ldub [%o0], %o3 /* Load */
+ retl /* CTI+IEU1 Group */
+ add %o0, -1, %o0 /* IEU0 */
+
+ /* strchr (str, 0) */
+ .align 32
+ nop
+ .align 16
+17: sethi %hi(0x01010101), %g1 /* IEU0 Group */
+ ldub [%o0], %o3 /* Load */
+ or %g1, %lo(0x01010101), %g1 /* IEU0 Group */
+ sllx %g1, 32, %g2 /* IEU0 Group */
+
+ andcc %o0, 7, %g0 /* IEU1 */
+ or %g1, %g2, %g1 /* IEU0 Group */
+ bne,pn %icc, 32f /* CTI */
+ sllx %g1, 7, %g2 /* IEU0 Group */
+
+ brz,pn %o3, 30f /* CTI+IEU1 */
+ ldx [%o0], %o3 /* Load */
+18: add %o0, 8, %o0 /* IEU0 Group */
+19: sub %o3, %g1, %o2 /* IEU0 Group */
+
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o2, %o3, %g6 /* IEU0 Group */
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ andcc %g6, %g2, %g0 /* IEU1 Group */
+#else
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ andcc %o2, %g2, %g0 /* IEU1 Group */
+#endif
+ be,pt %xcc, 19b /* CTI */
+ add %o0, 8, %o0 /* IEU0 */
+
+ addcc %o2, %g1, %g3 /* IEU1 Group */
+ srlx %o2, 32, %o2 /* IEU0 */
+20: andcc %o2, %g2, %g0 /* IEU1 Group */
+ be,pn %xcc, 21f /* CTI */
+
+ srlx %g3, 56, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 29f /* CTI */
+ srlx %g3, 48, %o2 /* IEU0 */
+
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 28f /* CTI */
+ srlx %g3, 40, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 27f /* CTI */
+ srlx %g3, 32, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 26f /* CTI */
+
+21: srlx %g3, 24, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 25f /* CTI */
+ srlx %g3, 16, %o2 /* IEU0 */
+
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 24f /* CTI */
+ srlx %g3, 8, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 23f /* CTI */
+ sub %o3, %g1, %o2 /* IEU0 */
+ andcc %g3, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 22f /* CTI */
+
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ andcc %o2, %g2, %g0 /* IEU1 Group */
+ be,pt %xcc, 19b /* CTI */
+ add %o0, 8, %o0 /* IEU0 */
+
+ addcc %o2, %g1, %g3 /* IEU1 Group */
+ ba,pt %xcc, 20b /* CTI */
+ srlx %o2, 32, %o2 /* IEU0 */
+
+ .align 16
+22: retl /* CTI+IEU1 Group */
+ add %o0, -9, %o0 /* IEU0 */
+23: retl /* CTI+IEU1 Group */
+ add %o0, -10, %o0 /* IEU0 */
+
+24: retl /* CTI+IEU1 Group */
+ add %o0, -11, %o0 /* IEU0 */
+25: retl /* CTI+IEU1 Group */
+ add %o0, -12, %o0 /* IEU0 */
+
+26: retl /* CTI+IEU1 Group */
+ add %o0, -13, %o0 /* IEU0 */
+27: retl /* CTI+IEU1 Group */
+ add %o0, -14, %o0 /* IEU0 */
+
+28: retl /* CTI+IEU1 Group */
+ add %o0, -15, %o0 /* IEU0 */
+29: retl /* CTI+IEU1 Group */
+ add %o0, -16, %o0 /* IEU0 */
+
+30: retl /* CTI+IEU1 Group */
+ nop /* IEU0 */
+
+ .align 16
+32: andcc %o0, 7, %g0 /* IEU1 Group */
+ be,a,pn %icc, 18b /* CTI */
+ ldx [%o0], %o3 /* Load */
+ add %o0, 1, %o0 /* IEU0 Group */
+
+ brnz,a,pt %o3, 32b /* CTI+IEU1 */
+ lduba [%o0] ASI_PNF, %o3 /* Load */
+ retl /* CTI+IEU1 Group */
+ add %o0, -1, %o0 /* IEU0 */
+END(strchr)
+
+ .align 32
+ENTRY(strrchr)
+ andcc %o1, 0xff, %o1 /* IEU1 Group */
+ be,pn %icc, 17b /* CTI */
+ clr %g4 /* IEU0 */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+
+ bne,pn %icc, 13f /* CTI */
+ sllx %o1, 8, %g3 /* IEU0 */
+ ldx [%o0], %o3 /* Load Group */
+1: sethi %hi(0x01010101), %g1 /* IEU0 */
+
+ or %g3, %o1, %g3 /* IEU1 */
+ sllx %g3, 16, %g5 /* IEU0 Group */
+ or %g1, %lo(0x01010101), %g1 /* IEU1 */
+ sllx %g1, 32, %g2 /* IEU0 Group */
+
+ or %g3, %g5, %g3 /* IEU1 */
+ sllx %g3, 32, %g5 /* IEU0 Group */
+ or %g1, %g2, %g1 /* IEU1 */
+ sllx %g1, 7, %g2 /* IEU0 Group */
+
+ or %g3, %g5, %g3 /* IEU1 */
+ add %o0, 8, %o0 /* IEU0 Group */
+ xor %o3, %g3, %o4 /* IEU1 */
+ /* %g1 = 0101010101010101 *
+ * %g2 = 8080088080808080 *
+ * %g3 = c c c c c c c c *
+ * %o3 = value *
+ * %o4 = value XOR c */
+2: sub %o3, %g1, %o2 /* IEU0 Group */
+
+3: sub %o4, %g1, %o5 /* IEU1 */
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o2, %o3, %g6 /* IEU0 Group */
+ andn %o5, %o4, %o5 /* IEU1 */
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+
+ or %o5, %g6, %o5 /* IEU0 Group */
+#else
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+
+ or %o5, %o2, %o5 /* IEU0 Group */
+#endif
+ add %o0, 8, %o0 /* IEU1 */
+ andcc %o5, %g2, %g0 /* IEU1 Group */
+ be,a,pt %xcc, 2b /* CTI */
+
+ xor %o3, %g3, %o4 /* IEU0 */
+ srlx %o5, 32, %g5 /* IEU0 Group */
+ add %o2, %g1, %o2 /* IEU1 */
+ andcc %g5, %g2, %g0 /* IEU1 Group */
+
+ be,pn %xcc, 7f /* CTI */
+ srlx %o2, 56, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 12f /* CTI */
+
+ srlx %o4, 56, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ srlx %o2, 48, %g5 /* IEU0 */
+ be,a,pn %icc, 4f /* CTI */
+
+ add %o0, -16, %g4 /* IEU0 Group */
+4: andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 12f /* CTI */
+ srlx %o4, 48, %g5 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ srlx %o2, 40, %g5 /* IEU0 */
+ be,a,pn %icc, 5f /* CTI */
+ add %o0, -15, %g4 /* IEU0 Group */
+
+5: andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 12f /* CTI */
+ srlx %o4, 40, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ srlx %o2, 32, %g5 /* IEU0 */
+ be,a,pn %icc, 6f /* CTI */
+ add %o0, -14, %g4 /* IEU0 Group */
+6: andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 12f /* CTI */
+ srlx %o4, 32, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,a,pn %icc, 7f /* CTI */
+
+ add %o0, -13, %g4 /* IEU0 */
+7: srlx %o2, 24, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 12f /* CTI */
+
+ srlx %o4, 24, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ srlx %o2, 16, %g5 /* IEU0 */
+ be,a,pn %icc, 8f /* CTI */
+
+ add %o0, -12, %g4 /* IEU0 Group */
+8: andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 12f /* CTI */
+ srlx %o4, 16, %g5 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ srlx %o2, 8, %g5 /* IEU0 */
+ be,a,pn %icc, 9f /* CTI */
+ add %o0, -11, %g4 /* IEU0 Group */
+
+9: andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 12f /* CTI */
+ srlx %o4, 8, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,a,pn %icc, 10f /* CTI */
+ add %o0, -10, %g4 /* IEU0 */
+10: andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 12f /* CTI */
+
+ sub %o3, %g1, %o2 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,a,pn %icc, 11f /* CTI */
+ add %o0, -9, %g4 /* IEU0 */
+
+11: ba,pt %xcc, 3b /* CTI Group */
+ xor %o3, %g3, %o4 /* IEU0 Group */
+12: retl /* CTI+IEU1 Group */
+ mov %g4, %o0 /* IEU0 */
+
+ .align 16
+13: ldub [%o0], %o3 /* Load Group */
+ add %o0, 1, %o0 /* IEU0 */
+14: andcc %o3, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 12b /* CTI */
+
+ cmp %o3, %o1 /* IEU1 Group */
+ ldub [%o0], %o3 /* Load */
+ be,a,pn %icc, 15f /* CTI */
+ add %o0, -1, %g4 /* IEU0 Group */
+
+15: andcc %o0, 7, %g0 /* IEU1 Group */
+ bne,a,pt %icc, 14b /* CTI */
+ add %o0, 1, %o0 /* IEU0 */
+ ba,pt %xcc, 1b /* CTI Group */
+
+ ldx [%o0], %o3 /* Load */
+END(strrchr)
+
+weak_alias (strchr, index)
+weak_alias (strrchr, rindex)
+libc_hidden_builtin_def (strchr)
+libc_hidden_builtin_def (strrchr)
diff --git a/libc/sysdeps/sparc/sparc64/strcmp.S b/libc/sysdeps/sparc/sparc64/strcmp.S
new file mode 100644
index 000000000..fade4c4cb
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/strcmp.S
@@ -0,0 +1,280 @@
+/* Compare two strings for differences.
+ For SPARC v9.
+ Copyright (C) 1997, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz> and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .register %g6, #scratch
+#endif
+
+ /* Normally, this uses
+ ((xword - 0x0101010101010101) & 0x8080808080808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 32
+ENTRY(strcmp)
+ sethi %hi(0x01010101), %g1 /* IEU0 Group */
+ andcc %o0, 7, %g0 /* IEU1 */
+ bne,pn %icc, 7f /* CTI */
+ or %g1, %lo(0x01010101), %g1 /* IEU0 Group */
+
+ andcc %o1, 7, %g3 /* IEU1 */
+ bne,pn %icc, 9f /* CTI */
+ sllx %g1, 32, %g2 /* IEU0 Group */
+ ldx [%o0], %o2 /* Load */
+
+ or %g1, %g2, %g1 /* IEU0 Group */
+1: ldx [%o1], %o3 /* Load */
+ sub %o1, %o0, %o1 /* IEU1 */
+ sllx %g1, 7, %g2 /* IEU0 Group */
+
+2: add %o0, 8, %o0 /* IEU1 */
+ sub %o2, %g1, %g3 /* IEU0 Group */
+ subcc %o2, %o3, %g0 /* IEU1 */
+ bne,pn %xcc, 13f /* CTI */
+
+#ifdef EIGHTBIT_NOT_RARE
+ andn %g3, %o2, %g4 /* IEU0 Group */
+ ldxa [%o0] ASI_PNF, %o2 /* Load */
+ andcc %g4, %g2, %g0 /* IEU1 Group */
+#else
+ ldxa [%o0] ASI_PNF, %o2 /* Load Group */
+ andcc %g3, %g2, %g0 /* IEU1 */
+#endif
+ be,a,pt %xcc, 2b /* CTI */
+ ldxa [%o1 + %o0] ASI_PNF, %o3 /* Load Group */
+
+ addcc %g3, %g1, %o4 /* IEU1 */
+ srlx %g3, 32, %g3 /* IEU0 */
+ andcc %g3, %g2, %g0 /* IEU1 Group */
+ be,pt %xcc, 3f /* CTI */
+
+ srlx %o4, 56, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4f /* CTI */
+ srlx %o4, 48, %o5 /* IEU0 */
+
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4f /* CTI */
+ srlx %o4, 40, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 4f /* CTI */
+ srlx %o4, 32, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4f /* CTI */
+
+3: srlx %o4, 24, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4f /* CTI */
+ srlx %o4, 16, %o5 /* IEU0 */
+
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4f /* CTI */
+ srlx %o4, 8, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 4f /* CTI */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ bne,a,pn %icc, 2b /* CTI */
+ ldxa [%o1 + %o0] ASI_PNF, %o3 /* Load */
+
+4: retl /* CTI+IEU1 Group */
+ clr %o0 /* IEU0 */
+
+ .align 32
+13: mov 0xff, %g6 /* IEU0 Group */
+#ifdef EIGHTBIT_NOT_RARE
+ andcc %g4, %g2, %g0 /* IEU1 */
+#else
+ andcc %g3, %g2, %g0 /* IEU1 */
+#endif
+ be,pt %xcc, 25f /* CTI */
+ addcc %g3, %g1, %o4 /* IEU1 Group */
+
+ srlx %g3, 32, %g3 /* IEU0 */
+ andcc %g3, %g2, %g0 /* IEU1 Group */
+ be,pt %xcc, 23f /* CTI */
+ sllx %g6, 56, %o5 /* IEU0 */
+
+ andcc %o4, %o5, %g0 /* IEU1 Group */
+ be,pn %xcc, 24f /* CTI */
+ sllx %g6, 48, %o5 /* IEU0 */
+ andcc %o4, %o5, %g0 /* IEU1 Group */
+
+ be,pn %xcc, 24f /* CTI */
+ sllx %g6, 40, %o5 /* IEU0 */
+ andcc %o4, %o5, %g0 /* IEU1 Group */
+ be,pn %xcc, 24f /* CTI */
+
+ sllx %g6, 32, %o5 /* IEU0 */
+ andcc %o4, %o5, %g0 /* IEU1 Group */
+ be,pn %xcc, 24f /* CTI */
+23: sllx %g6, 24, %o5 /* IEU0 */
+
+ andcc %o4, %o5, %g0 /* IEU1 Group */
+ be,pn %icc, 24f /* CTI */
+ sllx %g6, 16, %o5 /* IEU0 */
+ andcc %o4, %o5, %g0 /* IEU1 Group */
+
+ be,pn %icc, 24f /* CTI */
+ sllx %g6, 8, %o5 /* IEU0 */
+ andcc %o4, %o5, %g0 /* IEU1 Group */
+ be,pn %icc, 24f /* CTI */
+
+ mov %g6, %o5 /* IEU0 */
+25: cmp %o4, %o3 /* IEU1 Group */
+5: mov -1, %o0 /* IEU0 */
+ retl /* CTI+IEU1 Group */
+
+ movgu %xcc, 1, %o0 /* Single Group */
+
+ .align 16
+24: sub %o5, 1, %g6 /* IEU0 Group */
+ clr %o0 /* IEU1 */
+ or %o5, %g6, %o5 /* IEU0 Group */
+ andn %o4, %o5, %o4 /* IEU0 Group */
+
+ andn %o3, %o5, %o3 /* IEU1 */
+ cmp %o4, %o3 /* IEU1 Group */
+ movgu %xcc, 1, %o0 /* Single Group */
+ retl /* CTI+IEU1 Group */
+
+ movlu %xcc, -1, %o0 /* Single Group */
+6: retl /* CTI+IEU1 Group */
+ mov %o4, %o0 /* IEU0 */
+
+ .align 16
+7: ldub [%o0], %o2 /* Load */
+ add %o0, 1, %o0 /* IEU1 */
+ ldub [%o1], %o3 /* Load Group */
+ sllx %g1, 32, %g2 /* IEU0 */
+
+8: add %o1, 1, %o1 /* IEU1 */
+ subcc %o2, %o3, %o4 /* IEU1 Group */
+ bne,pn %xcc, 6b /* CTI */
+ lduba [%o0] ASI_PNF, %o2 /* Load */
+
+ brz,pn %o3, 4b /* CTI+IEU1 Group */
+ lduba [%o1] ASI_PNF, %o3 /* Load */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+ bne,a,pn %icc, 8b /* CTI */
+
+ add %o0, 1, %o0 /* IEU0 */
+ or %g1, %g2, %g1 /* IEU0 Group */
+ andcc %o1, 7, %g3 /* IEU1 */
+ be,a,pn %icc, 1b /* CTI */
+
+ ldxa [%o0] ASI_PNF, %o2 /* Load Group */
+9: sllx %g3, 3, %g5 /* IEU0 */
+ mov 64, %o5 /* IEU1 */
+ sub %o1, %g3, %o1 /* IEU0 Group */
+
+ sub %o5, %g5, %o5 /* IEU1 */
+ ldxa [%o1] ASI_PNF, %g6 /* Load Group */
+ or %g1, %g2, %g1 /* IEU0 */
+ sub %o1, %o0, %o1 /* IEU1 */
+
+ sllx %g1, 7, %g2 /* IEU0 Group */
+ add %o1, 8, %o1 /* IEU1 */
+ /* %g1 = 0101010101010101
+ * %g2 = 8080808080800880
+ * %g5 = number of bits to shift left
+ * %o5 = number of bits to shift right */
+10: sllx %g6, %g5, %o3 /* IEU0 Group */
+ ldxa [%o1 + %o0] ASI_PNF, %g6 /* Load */
+
+11: srlx %g6, %o5, %o4 /* IEU0 Group */
+ ldxa [%o0] ASI_PNF, %o2 /* Load */
+ or %o3, %o4, %o3 /* IEU1 */
+ add %o0, 8, %o0 /* IEU0 Group */
+
+ subcc %o2, %o3, %g0 /* IEU1 */
+#ifdef EIGHTBIT_NOT_RARE
+ sub %o2, %g1, %g3 /* IEU0 Group */
+ bne,pn %xcc, 13b /* CTI */
+ andn %g3, %o2, %g4 /* IEU0 Group */
+
+ andcc %g4, %g2, %g0 /* IEU1 Group */
+ be,pt %xcc, 10b /* CTI */
+ srlx %g4, 32, %g4 /* IEU0 */
+ andcc %g4, %g2, %g0 /* IEU1 Group */
+#else
+ bne,pn %xcc, 13b /* CTI */
+ sub %o2, %g1, %g3 /* IEU0 Group */
+ andcc %g3, %g2, %g0 /* IEU1 Group */
+
+ be,pt %xcc, 10b /* CTI */
+ srlx %g3, 32, %g3 /* IEU0 */
+ andcc %g3, %g2, %g0 /* IEU1 Group */
+#endif
+ be,pt %xcc, 12f /* CTI */
+
+ srlx %o2, 56, %g3 /* IEU0 */
+ andcc %g3, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+ srlx %o2, 48, %g3 /* IEU0 */
+
+ andcc %g3, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+ srlx %o2, 40, %g3 /* IEU0 */
+ andcc %g3, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 4b /* CTI */
+ srlx %o2, 32, %g3 /* IEU0 */
+ andcc %g3, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+
+12: srlx %o2, 24, %g3 /* IEU0 */
+ andcc %g3, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+ srlx %o2, 16, %g3 /* IEU0 */
+
+ andcc %g3, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+ srlx %o2, 8, %g3 /* IEU0 */
+ andcc %g3, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 4b /* CTI */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+ sllx %g6, %g5, %o3 /* IEU0 */
+
+ ba,pt %xcc, 11b /* CTI Group */
+ ldxa [%o1 + %o0] ASI_PNF, %g6 /* Load */
+END(strcmp)
+libc_hidden_builtin_def (strcmp)
diff --git a/libc/sysdeps/sparc/sparc64/strcpy.S b/libc/sysdeps/sparc/sparc64/strcpy.S
new file mode 100644
index 000000000..59fa6d903
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/strcpy.S
@@ -0,0 +1,245 @@
+/* Copy SRC to DEST returning DEST.
+ For SPARC v9.
+ Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz> and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .register %g6, #scratch
+#endif
+
+ /* Normally, this uses
+ ((xword - 0x0101010101010101) & 0x8080808080808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 32
+ENTRY(strcpy)
+ sethi %hi(0x01010101), %g1 /* IEU0 Group */
+ mov %o0, %g6 /* IEU1 */
+ or %g1, %lo(0x01010101), %g1 /* IEU0 Group */
+ andcc %o0, 7, %g0 /* IEU1 */
+
+ sllx %g1, 32, %g2 /* IEU0 Group */
+ bne,pn %icc, 12f /* CTI */
+ andcc %o1, 7, %g3 /* IEU1 */
+ or %g1, %g2, %g1 /* IEU0 Group */
+
+ bne,pn %icc, 14f /* CTI */
+ sllx %g1, 7, %g2 /* IEU0 Group */
+1: ldx [%o1], %o3 /* Load */
+ add %o1, 8, %o1 /* IEU1 */
+
+2: mov %o3, %g3 /* IEU0 Group */
+3: sub %o3, %g1, %o2 /* IEU1 */
+ ldxa [%o1] ASI_PNF, %o3 /* Load */
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o2, %g3, %o2 /* IEU0 Group */
+#endif
+ add %o0, 8, %o0 /* IEU0 Group */
+
+ andcc %o2, %g2, %g0 /* IEU1 */
+ add %o1, 8, %o1 /* IEU0 Group */
+ be,a,pt %xcc, 2b /* CTI */
+ stx %g3, [%o0 - 8] /* Store */
+
+ srlx %g3, 56, %g5 /* IEU0 Group */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 11f /* CTI */
+ srlx %g3, 48, %g4 /* IEU0 */
+
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 10f /* CTI */
+ srlx %g3, 40, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 9f /* CTI */
+ srlx %g3, 32, %g4 /* IEU0 */
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 8f /* CTI */
+
+ srlx %g3, 24, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 7f /* CTI */
+ srlx %g3, 16, %g4 /* IEU0 */
+
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 6f /* CTI */
+ srlx %g3, 8, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 5f /* CTI */
+ sub %o3, %g1, %o2 /* IEU0 */
+ stx %g3, [%o0 - 8] /* Store Group */
+ andcc %g3, 0xff, %g0 /* IEU1 */
+
+ bne,pt %icc, 3b /* CTI */
+ mov %o3, %g3 /* IEU0 Group */
+4: retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+
+ .align 16
+5: stb %g5, [%o0 - 2] /* Store Group */
+ srlx %g3, 16, %g4 /* IEU0 */
+6: sth %g4, [%o0 - 4] /* Store Group */
+ srlx %g3, 32, %g4 /* IEU0 */
+
+ stw %g4, [%o0 - 8] /* Store Group */
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+7: stb %g5, [%o0 - 4] /* Store Group */
+
+ srlx %g3, 32, %g4 /* IEU0 */
+8: stw %g4, [%o0 - 8] /* Store Group */
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+
+9: stb %g5, [%o0 - 6] /* Store Group */
+ srlx %g3, 48, %g4 /* IEU0 */
+10: sth %g4, [%o0 - 8] /* Store Group */
+ retl /* CTI+IEU1 Group */
+
+ mov %g6, %o0 /* IEU0 */
+11: stb %g5, [%o0 - 8] /* Store Group */
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+
+12: or %g1, %g2, %g1 /* IEU0 Group */
+ ldub [%o1], %o3 /* Load */
+ sllx %g1, 7, %g2 /* IEU0 Group */
+ stb %o3, [%o0] /* Store Group */
+
+13: add %o0, 1, %o0 /* IEU0 */
+ add %o1, 1, %o1 /* IEU1 */
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+
+ lduba [%o1] ASI_PNF, %o3 /* Load */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+ bne,a,pt %icc, 13b /* CTI */
+ stb %o3, [%o0] /* Store */
+
+ andcc %o1, 7, %g3 /* IEU1 Group */
+ be,a,pt %icc, 1b /* CTI */
+ ldx [%o1], %o3 /* Load */
+14: orcc %g0, 64, %g4 /* IEU1 Group */
+
+ sllx %g3, 3, %g5 /* IEU0 */
+ sub %o1, %g3, %o1 /* IEU0 Group */
+ sub %g4, %g5, %g4 /* IEU1 */
+ /* %g1 = 0101010101010101 *
+ * %g2 = 8080808080808080 *
+ * %g3 = source alignment *
+ * %g5 = number of bits to shift left *
+ * %g4 = number of bits to shift right */
+ ldxa [%o1] ASI_PNF, %o5 /* Load Group */
+
+ addcc %o1, 8, %o1 /* IEU1 */
+15: sllx %o5, %g5, %o3 /* IEU0 Group */
+ ldxa [%o1] ASI_PNF, %o5 /* Load */
+ srlx %o5, %g4, %o4 /* IEU0 Group */
+
+ add %o0, 8, %o0 /* IEU1 */
+ or %o3, %o4, %o3 /* IEU0 Group */
+ add %o1, 8, %o1 /* IEU1 */
+ sub %o3, %g1, %o4 /* IEU0 Group */
+
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o3, %o4 /* IEU0 Group */
+#endif
+ andcc %o4, %g2, %g0 /* IEU1 Group */
+ be,a,pt %xcc, 15b /* CTI */
+ stx %o3, [%o0 - 8] /* Store */
+ srlx %o3, 56, %o4 /* IEU0 Group */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 22f /* CTI */
+ srlx %o3, 48, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 21f /* CTI */
+ srlx %o3, 40, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 20f /* CTI */
+
+ srlx %o3, 32, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 19f /* CTI */
+ srlx %o3, 24, %o4 /* IEU0 */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 18f /* CTI */
+ srlx %o3, 16, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 17f /* CTI */
+ srlx %o3, 8, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 16f /* CTI */
+
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+ bne,pn %icc, 15b /* CTI */
+ stx %o3, [%o0 - 8] /* Store */
+ retl /* CTI+IEU1 Group */
+
+ mov %g6, %o0 /* IEU0 */
+
+ .align 16
+16: srlx %o3, 8, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 2] /* Store */
+17: srlx %o3, 16, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 3] /* Store */
+
+18: srlx %o3, 24, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 4] /* Store */
+19: srlx %o3, 32, %o4 /* IEU0 Group */
+ stw %o4, [%o0 - 8] /* Store */
+
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+ nop
+ nop
+
+20: srlx %o3, 40, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 6] /* Store */
+21: srlx %o3, 48, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 7] /* Store */
+
+22: srlx %o3, 56, %o4 /* IEU0 Group */
+ stb %o4, [%o0 - 8] /* Store */
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+END(strcpy)
+libc_hidden_builtin_def (strcpy)
diff --git a/libc/sysdeps/sparc/sparc64/strcspn.S b/libc/sysdeps/sparc/sparc64/strcspn.S
new file mode 100644
index 000000000..a0f0ae1a4
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/strcspn.S
@@ -0,0 +1,213 @@
+/* strcspn (str, ss) -- Return the length of the initial segment of STR
+ which contains no characters from SS.
+ For SPARC v9.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define XCC xcc
+#define STACK_SIZE 128
+#define STACK_OFFSET 128+0x7ff
+ .register %g2, #scratch
+#else
+#define STACK_SIZE 64
+#define STACK_OFFSET 64
+#endif
+
+ .text
+ .align 32
+ENTRY(strcspn)
+ sub %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ mov 1, %o4 /* IEU1 */
+ stx %o4, [%sp + STACK_OFFSET] /* Store Group */
+ mov %o0, %g4 /* IEU0 */
+
+ stx %g0, [%sp + STACK_OFFSET + 8] /* Store Group */
+ add %sp, STACK_OFFSET, %o5 /* IEU0 */
+ stx %g0, [%sp + STACK_OFFSET + 16] /* Store Group */
+ stx %g0, [%sp + STACK_OFFSET + 24] /* Store Group */
+
+1: ldub [%o1], %o2 /* Load Group */
+ brz,pn %o2, 2f /* CTI+IEU1 Group */
+ srl %o2, 3, %o3 /* IEU0 */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+
+ and %o2, 0x3f, %o2 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ sllx %o4, %o2, %g1 /* IEU0 */
+ add %o1, 1, %o1 /* IEU1 */
+
+ or %g2, %g1, %g2 /* IEU0 Group */
+ ba,pt %xcc, 1b /* CTI */
+ stx %g2, [%o5 + %o3] /* Store */
+2: andcc %o0, 7, %g0 /* IEU1 Group */
+
+ be,a,pt %xcc, 4f /* CTI */
+ ldx [%o0], %o2 /* Load */
+ ldub [%o0], %o2 /* Load Group */
+3: srl %o2, 3, %o3 /* IEU0 Group */
+
+ and %o2, 0x3f, %o2 /* IEU1 */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ sllx %o4, %o2, %g1 /* IEU0 */
+
+ add %o0, 1, %o0 /* IEU1 */
+ andcc %g2, %g1, %g0 /* IEU1 Group */
+ bne,pn %xcc, 12f /* CTI */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+
+ bne,a,pt %icc, 3b /* CTI */
+ ldub [%o0], %o2 /* Load */
+ ldx [%o0], %o2 /* Load Group */
+4: srlx %o2, 59, %o3 /* IEU0 Group */
+
+ srlx %o2, 56, %g5 /* IEU0 Group */
+5: and %o3, 0x18, %o3 /* IEU1 */
+ andcc %g5, 0x3f, %g5 /* IEU1 Group */
+ ldx [%o5 + %o3], %g2 /* Load */
+
+ srlx %o2, 51, %o3 /* IEU0 */
+ sllx %o4, %g5, %g1 /* IEU0 Group */
+ srlx %o2, 48, %g5 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+
+ bne,pn %xcc, 13f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g5 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+
+ srlx %o2, 43, %o3 /* IEU0 */
+ sllx %o4, %g5, %g1 /* IEU0 Group */
+ srlx %o2, 40, %g5 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+
+ bne,pn %xcc, 14f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g5 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+
+ srlx %o2, 35, %o3 /* IEU0 */
+ sllx %o4, %g5, %g1 /* IEU0 Group */
+ srlx %o2, 32, %g5 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+
+ bne,pn %xcc, 15f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g5 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+
+ srlx %o2, 27, %o3 /* IEU0 */
+ sllx %o4, %g5, %g1 /* IEU0 Group */
+ srlx %o2, 24, %g5 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+
+ bne,pn %xcc, 16f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g5 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+
+ srlx %o2, 19, %o3 /* IEU0 */
+ sllx %o4, %g5, %g1 /* IEU0 Group */
+ srlx %o2, 16, %g5 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+
+ bne,pn %xcc, 17f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g5 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+
+ srlx %o2, 11, %o3 /* IEU0 */
+ sllx %o4, %g5, %g1 /* IEU0 Group */
+ add %o0, 8, %o0 /* IEU1 */
+ srlx %o2, 8, %g5 /* IEU0 Group */
+
+ andcc %g2, %g1, %g2 /* IEU1 */
+ bne,pn %xcc, 18f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g5 /* IEU1 */
+
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ sllx %o4, %g5, %g1 /* IEU0 */
+ mov %o2, %g5 /* IEU1 */
+ srlx %o2, 3, %o3 /* IEU0 Group */
+
+ ldxa [%o0] ASI_PNF, %o2 /* Load */
+ andcc %g2, %g1, %g2 /* IEU1 Group */
+ bne,pn %xcc, 19f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+
+ and %g5, 0x3f, %g5 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ sllx %o4, %g5, %g1 /* IEU0 */
+ srlx %o2, 59, %o3 /* IEU0 Group */
+
+ andcc %g2, %g1, %g2 /* IEU1 Group */
+ be,pt %xcc, 5b /* CTI */
+ srlx %o2, 56, %g5 /* IEU0 Group */
+ sub %o0, 1, %o0 /* IEU1 */
+
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+ .align 16
+19: sub %o0, 2, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+18: sub %o0, 3, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+17: add %o0, 4, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+16: add %o0, 3, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+15: add %o0, 2, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+14: add %o0, 1, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+13: add %sp, STACK_SIZE+32, %sp /* IEU1 */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+ .align 16
+12: sub %o0, 1, %o0 /* IEU0 Group */
+ add %sp, STACK_SIZE+32, %sp /* IEU1 */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+END(strcspn)
+libc_hidden_builtin_def (strcspn)
diff --git a/libc/sysdeps/sparc/sparc64/strlen.S b/libc/sysdeps/sparc/sparc64/strlen.S
new file mode 100644
index 000000000..cc15e4e3f
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/strlen.S
@@ -0,0 +1,174 @@
+/* Determine the length of a string. For SPARC v9.
+ Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz> and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+
+ /* Normally, this uses
+ ((xword - 0x0101010101010101) & 0x8080808080808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 32
+ENTRY(strlen)
+ sethi %hi(0x01010101), %g1 /* IEU0 Group */
+ ldub [%o0], %o3 /* Load */
+ or %g1, %lo(0x01010101), %g1 /* IEU0 Group */
+ mov %o0, %o1 /* IEU1 */
+
+ sllx %g1, 32, %g4 /* IEU0 Group */
+ andcc %o0, 7, %g0 /* IEU1 */
+ or %g1, %g4, %g1 /* IEU0 Group */
+ brz,pn %o3, 13f /* CTI+IEU1 */
+
+ sllx %g1, 7, %g4 /* IEU0 Group */
+ bne,a,pn %icc, 15f /* CTI */
+ add %o0, 1, %o0 /* IEU1 */
+ /* %g1 = 0x0101010101010101 *
+ * %g4 = 0x8080808080808080 *
+ * %o0 = string pointer *
+ * %o1 = start of string */
+1: ldx [%o0], %o3 /* Load Group */
+
+ add %o0, 8, %o0 /* IEU1 */
+2: sub %o3, %g1, %o2 /* IEU0 Group */
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o2, %o3, %o5 /* IEU0 Group */
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ andcc %o5, %g4, %g0 /* IEU1 Group */
+#else
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ andcc %o2, %g4, %g0 /* IEU1 Group */
+#endif
+
+ be,pt %xcc, 2b /* CTI */
+ add %o0, 8, %o0 /* IEU0 */
+ addcc %o2, %g1, %g5 /* IEU1 Group */
+#ifdef EIGHTBIT_NOT_RARE
+ srlx %o5, 32, %o5 /* IEU0 */
+
+3: andcc %o5, %g4, %g0 /* IEU1 Group */
+#else
+ srlx %o2, 32, %o2 /* IEU0 */
+
+3: andcc %o2, %g4, %g0 /* IEU1 Group */
+#endif
+ be,pn %xcc, 4f /* CTI */
+ srlx %g5, 56, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 12f /* CTI */
+ srlx %g5, 48, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 11f /* CTI */
+
+ srlx %g5, 40, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 10f /* CTI */
+ srlx %g5, 32, %o2 /* IEU0 */
+
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 9f /* CTI */
+4: srlx %g5, 24, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 8f /* CTI */
+ srlx %g5, 16, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 7f /* CTI */
+
+ srlx %g5, 8, %o2 /* IEU0 */
+ andcc %o2, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 6f /* CTI */
+ sub %o3, %g1, %o2 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 5f /* CTI */
+ ldxa [%o0] ASI_PNF, %o3 /* Load */
+ andcc %o2, %g4, %g0 /* IEU1 Group */
+
+ be,pt %xcc, 2b /* CTI */
+ add %o0, 8, %o0 /* IEU0 */
+ addcc %o2, %g1, %g5 /* IEU1 Group */
+ ba,pt %xcc, 3b /* CTI */
+
+ srlx %o2, 32, %o2 /* IEU0 */
+5: add %o0, -9, %o0 /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %o1, %o0 /* IEU0 */
+
+6: add %o0, -10, %o0 /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %o1, %o0 /* IEU0 */
+7: add %o0, -11, %o0 /* IEU0 Group */
+
+ retl /* CTI+IEU1 Group */
+ sub %o0, %o1, %o0 /* IEU0 */
+8: add %o0, -12, %o0 /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+
+ sub %o0, %o1, %o0 /* IEU0 */
+9: add %o0, -13, %o0 /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %o1, %o0 /* IEU0 */
+
+10: add %o0, -14, %o0 /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %o1, %o0 /* IEU0 */
+11: add %o0, -15, %o0 /* IEU0 Group */
+
+ retl /* CTI+IEU1 Group */
+ sub %o0, %o1, %o0 /* IEU0 */
+12: add %o0, -16, %o0 /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+
+ sub %o0, %o1, %o0 /* IEU0 */
+13: retl /* CTI+IEU1 Group */
+ mov 0, %o0 /* IEU0 */
+ nop
+
+15: ldub [%o0], %o3 /* Load Group */
+16: andcc %o0, 7, %g0 /* IEU1 */
+ be,pn %icc, 1b /* CTI */
+ nop /* IEU0 Group */
+
+ add %o0, 1, %o0 /* IEU1 */
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+ bne,a,pt %icc, 16b /* CTI */
+ lduba [%o0] ASI_PNF, %o3 /* Load */
+
+ add %o0, -1, %o0 /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %o1, %o0 /* IEU0 */
+END(strlen)
+libc_hidden_builtin_def (strlen)
diff --git a/libc/sysdeps/sparc/sparc64/strncmp.S b/libc/sysdeps/sparc/sparc64/strncmp.S
new file mode 100644
index 000000000..d10435146
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/strncmp.S
@@ -0,0 +1,364 @@
+/* Compare no more than N characters of S1 and S2, returning less than,
+ equal to or greater than zero if S1 is lexicographically less than,
+ equal to or greater than S2.
+ For SPARC v9.
+ Copyright (C) 1997, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz> and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define XCC xcc
+#define USE_BPR
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .register %g6, #scratch
+#endif
+
+ /* Normally, this uses
+ ((xword - 0x0101010101010101) & 0x8080808080808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 32
+ENTRY(strncmp)
+#ifdef USE_BPR
+ brz,pn %o2, 4f /* CTI+IEU1 Group */
+#else
+ tst %o2 /* IEU1 Group */
+ be,pn %XCC, 4f /* CTI */
+#endif
+ sethi %hi(0x1010101), %g1 /* IEU0 */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+ bne,pn %icc, 9f /* CTI */
+
+ or %g1, %lo(0x1010101), %g1 /* IEU0 */
+ andcc %o1, 7, %g3 /* IEU1 Group */
+ bne,pn %icc, 11f /* CTI */
+ sllx %g1, 32, %g2 /* IEU0 */
+
+ ldx [%o0], %g4 /* Load Group */
+ or %g1, %g2, %g1 /* IEU0 */
+1: ldx [%o1], %o3 /* Load Group */
+ sllx %g1, 7, %g2 /* IEU0 */
+
+ add %o0, 8, %o0 /* IEU1 */
+2: subcc %o2, 8, %o2 /* IEU1 Group */
+ bl,pn %XCC, 5f /* CTI */
+ add %o1, 8, %o1 /* IEU0 */
+
+ sub %g4, %g1, %g3 /* IEU0 Group */
+ subcc %g4, %o3, %o4 /* IEU1 */
+#ifdef EIGHTBIT_NOT_RARE
+ andn %g3, %g4, %g6 /* IEU0 Group */
+#endif
+ bne,pn %xcc, 6f /* CTI */
+ ldxa [%o0] ASI_PNF, %g4 /* Load Group */
+
+ add %o0, 8, %o0 /* IEU0 */
+#ifdef EIGHTBIT_NOT_RARE
+ andcc %g6, %g2, %g0 /* IEU1 */
+#else
+ andcc %g3, %g2, %g0 /* IEU1 */
+#endif
+ be,a,pt %xcc, 2b /* CTI */
+ ldxa [%o1] ASI_PNF, %o3 /* Load Group */
+
+ addcc %g3, %g1, %o4 /* IEU1 */
+#ifdef EIGHTBIT_NOT_RARE
+ srlx %g6, 32, %g6 /* IEU0 */
+ andcc %g6, %g2, %g0 /* IEU1 Group */
+#else
+ srlx %g3, 32, %g3 /* IEU0 */
+ andcc %g3, %g2, %g0 /* IEU1 Group */
+#endif
+ be,pt %xcc, 3f /* CTI */
+
+ srlx %o4, 56, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4f /* CTI */
+ srlx %o4, 48, %o5 /* IEU0 */
+
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4f /* CTI */
+ srlx %o4, 40, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 4f /* CTI */
+ srlx %o4, 32, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4f /* CTI */
+
+3: srlx %o4, 24, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4f /* CTI */
+ srlx %o4, 16, %o5 /* IEU0 */
+
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4f /* CTI */
+ srlx %o4, 8, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 4f /* CTI */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ bne,a,pn %icc, 2b /* CTI */
+ ldxa [%o1] ASI_PNF, %o3 /* Load */
+
+4: retl /* CTI+IEU1 Group */
+ clr %o0 /* IEU0 */
+
+ .align 16
+5: srlx %g4, 56, %o4 /* IEU0 Group */
+ cmp %o2, -8 /* IEU1 */
+ be,pn %XCC, 4b /* CTI */
+ srlx %o3, 56, %o5 /* IEU0 Group */
+
+ andcc %o4, 0xff, %g0 /* IEU1 */
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+ bne,pn %xcc, 8f /* CTI */
+
+ srlx %o3, 48, %o5 /* IEU0 */
+ cmp %o2, -7 /* IEU1 Group */
+ be,pn %XCC, 4b /* CTI */
+ srlx %g4, 48, %o4 /* IEU0 */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+ bne,pn %xcc, 8f /* CTI */
+
+ srlx %o3, 40, %o5 /* IEU0 */
+ cmp %o2, -6 /* IEU1 Group */
+ be,pn %XCC, 4b /* CTI */
+ srlx %g4, 40, %o4 /* IEU0 */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+ bne,pn %xcc, 8f /* CTI */
+
+ srlx %o3, 32, %o5 /* IEU0 */
+ cmp %o2, -5 /* IEU1 Group */
+ be,pn %XCC, 4b /* CTI */
+ srlx %g4, 32, %o4 /* IEU0 */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+ bne,pn %xcc, 8f /* CTI */
+
+ srlx %o3, 24, %o5 /* IEU0 */
+ cmp %o2, -4 /* IEU1 Group */
+ be,pn %XCC, 4b /* CTI */
+ srlx %g4, 24, %o4 /* IEU0 */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+ bne,pn %xcc, 8f /* CTI */
+
+ srlx %o3, 16, %o5 /* IEU0 */
+ cmp %o2, -3 /* IEU1 Group */
+ be,pn %XCC, 4b /* CTI */
+ srlx %g4, 16, %o4 /* IEU0 */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+ bne,pn %xcc, 8f /* CTI */
+
+ srlx %o3, 8, %o5 /* IEU0 */
+ cmp %o2, -2 /* IEU1 Group */
+ be,pn %XCC, 4b /* CTI */
+ srlx %g4, 8, %o4 /* IEU0 */
+
+ retl /* CTI+IEU1 Group */
+ sub %o4, %o5, %o0 /* IEU0 */
+6: addcc %o3, %o4, %g4 /* IEU1 */
+7: srlx %o3, 56, %o5 /* IEU0 */
+
+ srlx %g4, 56, %o4 /* IEU0 Group */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+
+ bne,pn %xcc, 8f /* CTI */
+ srlx %o3, 48, %o5 /* IEU0 */
+ srlx %g4, 48, %o4 /* IEU0 Group */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+ bne,pn %xcc, 8f /* CTI */
+ srlx %o3, 40, %o5 /* IEU0 */
+
+ srlx %g4, 40, %o4 /* IEU0 Group */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+
+ bne,pn %xcc, 8f /* CTI */
+ srlx %o3, 32, %o5 /* IEU0 */
+ srlx %g4, 32, %o4 /* IEU0 Group */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+ bne,pn %xcc, 8f /* CTI */
+ srlx %o3, 24, %o5 /* IEU0 */
+
+ srlx %g4, 24, %o4 /* IEU0 Group */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+
+ bne,pn %xcc, 8f /* CTI */
+ srlx %o3, 16, %o5 /* IEU0 */
+ srlx %g4, 16, %o4 /* IEU0 Group */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+ bne,pn %xcc, 8f /* CTI */
+ srlx %o3, 8, %o5 /* IEU0 */
+
+ srlx %g4, 8, %o4 /* IEU0 Group */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %xcc, 8f /* CTI */
+ subcc %o4, %o5, %o4 /* IEU1 Group */
+
+ retl /* CTI+IEU1 Group */
+ sub %g4, %o3, %o0 /* IEU0 */
+8: retl /* CTI+IEU1 Group */
+ mov %o4, %o0 /* IEU0 */
+
+9: ldub [%o0], %g4 /* Load Group */
+ add %o0, 1, %o0 /* IEU0 */
+ ldub [%o1], %o3 /* Load Group */
+ sllx %g1, 32, %g2 /* IEU0 */
+
+10: subcc %o2, 1, %o2 /* IEU1 Group */
+ be,pn %XCC, 8b /* CTI */
+ sub %g4, %o3, %o4 /* IEU0 */
+ add %o1, 1, %o1 /* IEU0 Group */
+
+ cmp %g4, %o3 /* IEU1 */
+ bne,pn %xcc, 8b /* CTI */
+ lduba [%o0] ASI_PNF, %g4 /* Load Group */
+ andcc %o3, 0xff, %g0 /* IEU1 */
+
+ be,pn %icc, 4b /* CTI */
+ lduba [%o1] ASI_PNF, %o3 /* Load Group */
+ andcc %o0, 7, %g0 /* IEU1 */
+ bne,a,pn %icc, 10b /* CTI */
+
+ add %o0, 1, %o0 /* IEU0 Group */
+ or %g1, %g2, %g1 /* IEU1 */
+ andcc %o1, 7, %g3 /* IEU1 Group */
+ be,pn %icc, 1b /* CTI */
+
+ ldxa [%o0] ASI_PNF, %g4 /* Load */
+11: sllx %g3, 3, %g5 /* IEU0 Group */
+ mov 64, %g6 /* IEU1 */
+ or %g1, %g2, %g1 /* IEU0 Group */
+ sub %o1, %g3, %o1 /* IEU1 */
+
+ sub %g6, %g5, %g6 /* IEU0 Group */
+ ldxa [%o1] ASI_PNF, %o4 /* Load */
+ sllx %g1, 7, %g2 /* IEU1 */
+ add %o1, 8, %o1 /* IEU0 Group */
+ /* %g1 = 0101010101010101
+ %g2 = 8080808080808080
+ %g3 = %o1 alignment
+ %g5 = number of bits to shift left
+ %g6 = number of bits to shift right */
+
+12: sllx %o4, %g5, %o3 /* IEU0 Group */
+ ldxa [%o1] ASI_PNF, %o4 /* Load */
+ add %o1, 8, %o1 /* IEU1 */
+13: ldxa [%o0] ASI_PNF, %g4 /* Load Group */
+
+ addcc %o0, 8, %o0 /* IEU1 */
+ srlx %o4, %g6, %o5 /* IEU0 */
+ subcc %o2, 8, %o2 /* IEU1 Group */
+ bl,pn %XCC, 5b /* CTI */
+
+ or %o3, %o5, %o3 /* IEU0 */
+ cmp %g4, %o3 /* IEU1 Group */
+ bne,pn %xcc, 7b /* CTI */
+ sub %g4, %g1, %o5 /* IEU0 */
+
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o5, %g4, %o5 /* IEU0 Group */
+#endif
+ andcc %o5, %g2, %g0 /* IEU1 Group */
+ be,pt %xcc, 12b /* CTI */
+ srlx %o5, 32, %o5 /* IEU0 */
+ andcc %o5, %g2, %g0 /* IEU1 Group */
+
+ be,pt %xcc, 14f /* CTI */
+ srlx %g4, 56, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+
+ srlx %g4, 48, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+ srlx %g4, 40, %o5 /* IEU0 */
+
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+ srlx %g4, 32, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 4b /* CTI */
+14: srlx %g4, 24, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+
+ srlx %g4, 16, %o5 /* IEU0 */
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+ srlx %g4, 8, %o5 /* IEU0 */
+
+ andcc %o5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 4b /* CTI */
+
+ sllx %o4, %g5, %o3 /* IEU0 */
+ ldxa [%o1] ASI_PNF, %o4 /* Load Group */
+ ba,pt %xcc, 13b /* CTI */
+ add %o1, 8, %o1 /* IEU0 */
+END(strncmp)
+libc_hidden_builtin_def (strncmp)
diff --git a/libc/sysdeps/sparc/sparc64/strncpy.S b/libc/sysdeps/sparc/sparc64/strncpy.S
new file mode 100644
index 000000000..23f8f4fa7
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/strncpy.S
@@ -0,0 +1,397 @@
+/* strncpy(DST, SRC, COUNT) - Copy no more than COUNT bytes of the
+ null-terminated string from SRC to DST. If SRC does not cover all of
+ COUNT, the balance is zeroed.
+ For SPARC v9.
+ Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz> and
+ Jakub Jelinek <jj@ultra.linux.cz>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define XCC xcc
+#define USE_BPR
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .register %g6, #scratch
+#endif
+
+ /* Normally, this uses
+ ((xword - 0x0101010101010101) & 0x8080808080808080) test
+ to find out if any byte in xword could be zero. This is fast, but
+ also gives false alarm for any byte in range 0x81-0xff. It does
+ not matter for correctness, as if this test tells us there could
+ be some zero byte, we check it byte by byte, but if bytes with
+ high bits set are common in the strings, then this will give poor
+ performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
+ will use one tick slower, but more precise test
+ ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
+ which does not give any false alarms (but if some bits are set,
+ one cannot assume from it which bytes are zero and which are not).
+ It is yet to be measured, what is the correct default for glibc
+ in these days for an average user.
+ */
+
+ .text
+ .align 32
+ENTRY(strncpy)
+ sethi %hi(0x01010101), %g1 /* IEU0 Group */
+#ifdef USE_BPR
+ brz,pn %o2, 19f /* CTI+IEU1 */
+#else
+ tst %o2 /* IEU1 */
+ be,pn %XCC, 19f /* CTI */
+#endif
+ mov %o0, %g6 /* IEU0 Group */
+ or %g1, %lo(0x01010101), %g1 /* IEU1 */
+
+ andcc %o0, 7, %g0 /* IEU1 Group */
+ sllx %g1, 32, %g2 /* IEU0 */
+ bne,pn %icc, 26f /* CTI */
+ or %g1, %g2, %g1 /* IEU0 Group */
+
+ andcc %o1, 7, %g3 /* IEU1 */
+ bne,pn %icc, 28f /* CTI */
+ sllx %g1, 7, %g2 /* IEU0 Group */
+ ldx [%o1], %o3 /* Load */
+
+1: add %o1, 8, %o1 /* IEU1 */
+2: subcc %o2, 8, %o2 /* IEU1 Group */
+ bl,pn %XCC, 18f /* CTI */
+ sub %o3, %g1, %o4 /* IEU0 */
+
+ add %o0, 8, %o0 /* IEU0 Group */
+#ifdef EIGHTBIT_NOT_MORE
+ andn %o4, %o3, %o4 /* IEU1 */
+#endif
+ mov %o3, %g3 /* IEU1 */
+ ldxa [%o1] ASI_PNF, %o3 /* Load */
+ add %o1, 8, %o1 /* IEU0 Group */
+
+ andcc %o4, %g2, %g0 /* IEU1 */
+ be,a,pt %xcc, 2b /* CTI */
+ stx %g3, [%o0-8] /* Store Group */
+ srlx %g3, 56, %g5 /* IEU0 Group */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 16f /* CTI */
+ srlx %g3, 48, %g4 /* IEU0 */
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 15f /* CTI */
+ srlx %g3, 40, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 14f /* CTI */
+
+ srlx %g3, 32, %g4 /* IEU0 */
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 13f /* CTI */
+ srlx %g3, 24, %g5 /* IEU0 */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 12f /* CTI */
+ srlx %g3, 16, %g4 /* IEU0 */
+ andcc %g4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 11f /* CTI */
+ srlx %g3, 8, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 10f /* CTI */
+
+ andcc %g3, 0xff, %g0 /* IEU1 Group */
+ bne,pt %icc, 2b /* CTI */
+3: stx %g3, [%o0-8] /* Store */
+ andncc %o2, 31, %g3 /* IEU1 Group */
+
+4: be,pn %XCC, 41f /* CTI */
+ and %o2, 31, %o2 /* IEU1 Group */
+40: stx %g0, [%o0] /* Store */
+ stx %g0, [%o0 + 8] /* Store Group */
+
+ subcc %g3, 32, %g3 /* IEU1 */
+ stx %g0, [%o0 + 16] /* Store Group */
+ stx %g0, [%o0 + 24] /* Store Group */
+ bne,pt %XCC, 40b /* CTI */
+
+ add %o0, 32, %o0 /* IEU0 */
+41: subcc %o2, 8, %o2 /* IEU1 Group */
+ bl,a,pn %XCC, 6f /* CTI */
+ andcc %o2, 4, %g0 /* IEU1 Group */
+
+5: stx %g0, [%o0] /* Store */
+ subcc %o2, 8, %o2 /* IEU1 Group */
+ bge,pt %XCC, 5b /* CTI */
+ add %o0, 8, %o0 /* IEU0 */
+
+ andcc %o2, 4, %g0 /* IEU1 Group */
+6: be,a,pn %icc, 7f /* CTI */
+ andcc %o2, 2, %g0 /* IEU1 Group */
+ stw %g0, [%o0] /* Store */
+
+ add %o0, 4, %o0 /* IEU0 */
+ andcc %o2, 2, %g0 /* IEU1 Group */
+7: be,a,pn %icc, 8f /* CTI */
+ andcc %o2, 1, %g0 /* IEU1 Group */
+
+ sth %g0, [%o0] /* Store */
+ add %o0, 2, %o0 /* IEU0 */
+ andcc %o2, 1, %g0 /* IEU1 Group */
+8: bne,a,pn %icc, 9f /* CTI */
+
+ stb %g0, [%o0] /* Store */
+9: retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+
+ .align 16
+10: ba,pt %xcc, 3b /* CTI */
+ sllx %g5, 8, %g3 /* IEU0 */
+11: ba,pt %xcc, 3b /* CTI Group */
+ sllx %g4, 16, %g3 /* IEU0 */
+
+12: ba,pt %xcc, 3b /* CTI Group */
+ sllx %g5, 24, %g3 /* IEU0 */
+13: ba,pt %xcc, 3b /* CTI Group */
+ sllx %g4, 32, %g3 /* IEU0 */
+
+14: ba,pt %xcc, 3b /* CTI Group */
+ sllx %g5, 40, %g3 /* IEU0 */
+15: ba,pt %xcc, 3b /* CTI Group */
+ sllx %g4, 48, %g3 /* IEU0 */
+
+16: ba,pt %xcc, 3b /* CTI */
+ sllx %g5, 56, %g3 /* IEU0 */
+17: or %o3, %o4, %o3 /* IEU0 Group */
+ sub %o3, %g1, %o4 /* IEU1 */
+
+18: addcc %o2, 8, %o2 /* IEU1 Group */
+ be,pn %XCC, 19f /* CTI */
+ andcc %o4, %g2, %g0 /* IEU1 Group */
+ be,pt %xcc, 21f /* CTI */
+
+ srlx %o3, 56, %g5 /* IEU0 */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 20f /* CTI */
+ stb %g5, [%o0] /* Store */
+
+ add %o0, 1, %o0 /* IEU0 Group */
+ subcc %o2, 1, %o2 /* IEU1 */
+ be,pn %XCC, 19f /* CTI */
+ srlx %o3, 48, %g5 /* IEU0 Group */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 20f /* CTI */
+ stb %g5, [%o0] /* Store */
+ add %o0, 1, %o0 /* IEU0 Group */
+
+ subcc %o2, 1, %o2 /* IEU1 */
+ be,pn %XCC, 19f /* CTI */
+ srlx %o3, 40, %g5 /* IEU0 Group */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 20f /* CTI */
+ stb %g5, [%o0] /* Store */
+ add %o0, 1, %o0 /* IEU0 Group */
+ subcc %o2, 1, %o2 /* IEU1 */
+
+ be,pn %XCC, 19f /* CTI */
+ srlx %o3, 32, %g5 /* IEU0 Group */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 20f /* CTI */
+
+ stb %g5, [%o0] /* Store */
+ add %o0, 1, %o0 /* IEU0 Group */
+ subcc %o2, 1, %o2 /* IEU1 */
+ be,pn %XCC, 19f /* CTI */
+
+ srlx %o3, 24, %g5 /* IEU0 Group */
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 20f /* CTI */
+ stb %g5, [%o0] /* Store */
+
+ add %o0, 1, %o0 /* IEU0 Group */
+ subcc %o2, 1, %o2 /* IEU1 */
+ be,pn %XCC, 19f /* CTI */
+ srlx %o3, 16, %g5 /* IEU0 Group */
+
+ andcc %g5, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 20f /* CTI */
+ stb %g5, [%o0] /* Store */
+ add %o0, 1, %o0 /* IEU0 Group */
+
+ subcc %o2, 1, %o2 /* IEU1 */
+ be,pn %XCC, 19f /* CTI */
+ srlx %o3, 8, %g5 /* IEU0 Group */
+ stb %g5, [%o0] /* Store */
+
+19: retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+50: stb %g0, [%o0] /* Store Group */
+20: subcc %o2, 1, %o2 /* IEU1 Group */
+
+ bne,pt %XCC, 50b /* CTI */
+ add %o0, 1, %o0 /* IEU0 */
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+
+21: andcc %o2, 4, %g0 /* IEU1 Group */
+ be,pn %icc, 22f /* CTI */
+ srlx %o3, 32, %g5 /* IEU0 */
+ stw %g5, [%o0] /* Store Group */
+
+ add %o0, 4, %o0 /* IEU0 */
+ mov %o3, %g5 /* IEU1 */
+22: andcc %o2, 2, %g0 /* IEU1 Group */
+ be,pn %icc, 23f /* CTI */
+
+ srlx %g5, 16, %g4 /* IEU0 */
+ sth %g4, [%o0] /* Store Group */
+ add %o0, 2, %o0 /* IEU0 */
+ mov %g5, %g4 /* IEU1 */
+
+23: srlx %g4, 8, %g4 /* IEU0 Group */
+ andcc %o2, 1, %g0 /* IEU1 */
+ bne,a,pn %icc, 24f /* CTI */
+ stb %g4, [%o0] /* Store Group */
+
+24: retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+25: andcc %o0, 7, %g0 /* IEU1 Group */
+ be,a,pn %icc, 4b /* CTI */
+
+ andncc %o2, 31, %g3 /* IEU1 Group */
+ stb %g0, [%o0] /* Store Group */
+ subcc %o2, 1, %o2 /* IEU1 */
+ bne,pt %XCC, 25b /* CTI */
+
+ add %o0, 1, %o0 /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ mov %g6, %o0 /* IEU0 */
+
+ .align 16
+26: ldub [%o1], %o3 /* Load */
+ sllx %g1, 7, %g2 /* IEU0 Group */
+ stb %o3, [%o0] /* Store */
+27: subcc %o2, 1, %o2 /* IEU1 */
+
+ be,pn %XCC, 9b /* CTI */
+ add %o1, 1, %o1 /* IEU0 Group */
+ add %o0, 1, %o0 /* IEU1 */
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 25b /* CTI */
+ lduba [%o1] ASI_PNF, %o3 /* Load */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+ bne,a,pt %icc, 27b /* CTI */
+
+ stb %o3, [%o0] /* Store */
+ andcc %o1, 7, %g3 /* IEU1 Group */
+ be,a,pt %icc, 1b /* CTI */
+ ldx [%o1], %o3 /* Load */
+
+28: orcc %g0, 64, %g4 /* IEU1 Group */
+ sllx %g3, 3, %g5 /* IEU0 */
+ sub %g4, %g5, %g4 /* IEU0 Group */
+ sub %o1, %g3, %o1 /* IEU1 */
+ /* %g1 = 0101010101010101
+ %g2 = 8080808080808080
+ %g3 = source alignment
+ %g5 = number of bits to shift left
+ %g4 = number of bits to shift right */
+
+ ldxa [%o1] ASI_PNF, %o5 /* Load Group */
+ addcc %o1, 8, %o1 /* IEU1 */
+
+29: sllx %o5, %g5, %o3 /* IEU0 Group */
+ ldxa [%o1] ASI_PNF, %o5 /* Load */
+ subcc %o2, 8, %o2 /* IEU1 */
+ bl,pn %XCC, 17b /* CTI */
+
+ srlx %o5, %g4, %o4 /* IEU0 Group */
+ add %o1, 8, %o1 /* IEU1 */
+ or %o3, %o4, %o3 /* IEU0 Group */
+ add %o0, 8, %o0 /* IEU1 */
+
+ sub %o3, %g1, %o4 /* IEU0 Group */
+#ifdef EIGHTBIT_NOT_RARE
+ andn %o4, %o3, %o4 /* IEU0 Group */
+#endif
+ andcc %o4, %g2, %g0 /* IEU1 Group */
+ be,a,pt %xcc, 29b /* CTI */
+ stx %o3, [%o0-8] /* Store */
+
+ srlx %o3, 56, %o4 /* IEU0 Group */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 36f /* CTI */
+ srlx %o3, 48, %o4 /* IEU0 */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 35f /* CTI */
+ srlx %o3, 40, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 34f /* CTI */
+ srlx %o3, 32, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 33f /* CTI */
+
+ srlx %o3, 24, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 32f /* CTI */
+ srlx %o3, 16, %o4 /* IEU0 */
+
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+ be,pn %icc, 31f /* CTI */
+ srlx %o3, 8, %o4 /* IEU0 */
+ andcc %o4, 0xff, %g0 /* IEU1 Group */
+
+ be,pn %icc, 30f /* CTI */
+ andcc %o3, 0xff, %g0 /* IEU1 Group */
+ bne,pn %icc, 29b /* CTI */
+ stx %o3, [%o0-8] /* Store */
+
+ ba,pt %xcc, 4b /* CTI Group */
+ andncc %o2, 31, %g3 /* IEU1 */
+30: srlx %o3, 8, %o4 /* IEU0 */
+ ba,pt %xcc, 3b /* CTI */
+
+ sllx %o4, 8, %g3 /* IEU0 Group */
+31: srlx %o3, 16, %o4 /* IEU0 Group */
+ ba,pt %xcc, 3b /* CTI */
+ sllx %o4, 16, %g3 /* IEU0 Group */
+
+32: srlx %o3, 24, %o4 /* IEU0 Group */
+ ba,pt %xcc, 3b /* CTI */
+ sllx %o4, 24, %g3 /* IEU0 Group */
+33: srlx %o3, 32, %o4 /* IEU0 Group */
+
+ ba,pt %xcc, 3b /* CTI */
+ sllx %o4, 32, %g3 /* IEU0 Group */
+34: srlx %o3, 40, %o4 /* IEU0 Group */
+ ba,pt %xcc, 3b /* CTI */
+
+ sllx %o4, 40, %g3 /* IEU0 Group */
+35: srlx %o3, 48, %o4 /* IEU0 Group */
+ ba,pt %xcc, 3b /* CTI */
+ sllx %o4, 48, %g3 /* IEU0 Group */
+
+36: srlx %o3, 56, %o4 /* IEU0 Group */
+ ba,pt %xcc, 3b /* CTI */
+ sllx %o4, 56, %g3 /* IEU0 Group */
+END(strncpy)
+libc_hidden_builtin_def (strncpy)
diff --git a/libc/sysdeps/sparc/sparc64/strpbrk.S b/libc/sysdeps/sparc/sparc64/strpbrk.S
new file mode 100644
index 000000000..36b0bbc8e
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/strpbrk.S
@@ -0,0 +1,231 @@
+/* strpbrk (s, accept) -- Find the first occurrence in S of any character in
+ ACCEPT.
+ For SPARC v9.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define XCC xcc
+#define STACK_SIZE 128
+#define STACK_OFFSET 128+0x7ff
+ .register %g2, #scratch
+#else
+#define STACK_SIZE 64
+#define STACK_OFFSET 64
+#endif
+
+ .text
+ .align 32
+ENTRY(strpbrk)
+ sub %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ mov 1, %o4 /* IEU1 */
+ stx %o4, [%sp + STACK_OFFSET] /* Store Group */
+ stx %g0, [%sp + STACK_OFFSET + 8] /* Store Group */
+
+ add %sp, STACK_OFFSET, %o5 /* IEU0 */
+ stx %g0, [%sp + STACK_OFFSET + 16] /* Store Group */
+ stx %g0, [%sp + STACK_OFFSET + 24] /* Store Group */
+1: ldub [%o1], %o2 /* Load Group */
+
+ brz,pn %o2, 2f /* CTI+IEU1 Group */
+ srl %o2, 3, %o3 /* IEU0 */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %o2, 0x3f, %o2 /* IEU1 */
+
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ sllx %o4, %o2, %g1 /* IEU0 */
+ add %o1, 1, %o1 /* IEU1 */
+ or %g2, %g1, %g2 /* IEU0 Group */
+
+ ba,pt %xcc, 1b /* CTI */
+ stx %g2, [%o5 + %o3] /* Store */
+2: andcc %o0, 7, %g0 /* IEU1 Group */
+ be,a,pt %xcc, 4f /* CTI */
+
+ ldx [%o0], %o2 /* Load */
+ ldub [%o0], %o2 /* Load Group */
+3: srl %o2, 3, %o3 /* IEU0 Group */
+ and %o2, 0x3f, %o2 /* IEU1 */
+
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ sllx %o4, %o2, %g1 /* IEU0 */
+ add %o0, 1, %o0 /* IEU1 */
+
+ andcc %g2, %g1, %g0 /* IEU1 Group */
+ bne,pn %xcc, 12f /* CTI */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+ bne,a,pt %icc, 3b /* CTI */
+
+ ldub [%o0], %o2 /* Load */
+ ldx [%o0], %o2 /* Load Group */
+4: srlx %o2, 59, %o3 /* IEU0 Group */
+ srlx %o2, 56, %g4 /* IEU0 Group */
+
+5: and %o3, 0x18, %o3 /* IEU1 */
+ andcc %g4, 0x3f, %g4 /* IEU1 Group */
+ ldx [%o5 + %o3], %g2 /* Load */
+ srlx %o2, 51, %o3 /* IEU0 */
+
+ sllx %o4, %g4, %g1 /* IEU0 Group */
+ srlx %o2, 48, %g4 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+ bne,pn %xcc, 13f /* CTI */
+
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g4, 0x3f, %g4 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ srlx %o2, 43, %o3 /* IEU0 */
+
+ sllx %o4, %g4, %g1 /* IEU0 Group */
+ srlx %o2, 40, %g4 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+ bne,pn %xcc, 14f /* CTI */
+
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g4, 0x3f, %g4 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ srlx %o2, 35, %o3 /* IEU0 */
+
+ sllx %o4, %g4, %g1 /* IEU0 Group */
+ srlx %o2, 32, %g4 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+ bne,pn %xcc, 15f /* CTI */
+
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g4, 0x3f, %g4 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ srlx %o2, 27, %o3 /* IEU0 */
+
+ sllx %o4, %g4, %g1 /* IEU0 Group */
+ srlx %o2, 24, %g4 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+ bne,pn %xcc, 16f /* CTI */
+
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g4, 0x3f, %g4 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ srlx %o2, 19, %o3 /* IEU0 */
+
+ sllx %o4, %g4, %g1 /* IEU0 Group */
+ srlx %o2, 16, %g4 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+ bne,pn %xcc, 17f /* CTI */
+
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g4, 0x3f, %g4 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ srlx %o2, 11, %o3 /* IEU0 */
+
+ sllx %o4, %g4, %g1 /* IEU0 Group */
+ add %o0, 8, %o0 /* IEU1 */
+ srlx %o2, 8, %g4 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+
+ bne,pn %xcc, 18f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g4, 0x3f, %g4 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+
+ sllx %o4, %g4, %g1 /* IEU0 */
+ mov %o2, %g5 /* IEU1 */
+ srlx %o2, 3, %o3 /* IEU0 Group */
+ ldxa [%o0] ASI_PNF, %o2 /* Load */
+
+ andcc %g2, %g1, %g2 /* IEU1 Group */
+ bne,pn %xcc, 19f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g4 /* IEU1 */
+
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ sllx %o4, %g4, %g1 /* IEU0 */
+ srlx %o2, 59, %o3 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 Group */
+
+ be,pt %xcc, 5b /* CTI */
+ srlx %o2, 56, %g4 /* IEU0 Group */
+ sub %o0, 1, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+
+ andcc %g5, 0xff, %g0 /* IEU1 */
+ retl /* CTI+IEU1 Group */
+ move %icc, 0, %o0 /* Single Group */
+
+ .align 16
+19: sub %o0, 2, %o0 /* IEU1 */
+ srl %g5, 8, %g1 /* IEU0 Group */
+ add %sp, STACK_SIZE+32, %sp /* IEU1 */
+ andcc %g1, 0xff, %g0 /* IEU1 Group */
+
+ retl /* CTI+IEU1 Group */
+ move %icc, 0, %o0 /* Single Group */
+18: sub %o0, 3, %o0 /* IEU1 */
+ srl %o2, 16, %g1 /* IEU0 Group */
+
+ add %sp, STACK_SIZE+32, %sp /* IEU1 */
+ andcc %g1, 0xff, %g0 /* IEU1 Group */
+ retl /* CTI+IEU1 Group */
+ move %icc, 0, %o0 /* Single Group */
+
+17: add %o0, 4, %o0 /* IEU1 */
+ srl %o2, 24, %g1 /* IEU0 Group */
+ add %sp, STACK_SIZE+32, %sp /* IEU1 */
+ retl /* CTI+IEU1 Group */
+
+ movrz %g1, 0, %o0 /* Single Group */
+16: add %o0, 3, %o0 /* IEU1 */
+ srlx %o2, 32, %g1 /* IEU0 Group */
+ add %sp, STACK_SIZE+32, %sp /* IEU1 */
+
+ andcc %g1, 0xff, %g0 /* IEU1 Group */
+ retl /* CTI+IEU1 Group */
+ move %icc, 0, %o0 /* Single Group */
+
+ .align 16
+15: add %o0, 2, %o0 /* IEU1 */
+ srlx %o2, 40, %g1 /* IEU0 Group */
+ add %sp, STACK_SIZE+32, %sp /* IEU1 */
+ andcc %g1, 0xff, %g0 /* IEU1 Group */
+
+ retl /* CTI+IEU1 Group */
+ move %icc, 0, %o0 /* Single Group */
+14: add %o0, 1, %o0 /* IEU1 */
+ srlx %o2, 48, %g1 /* IEU0 Group */
+
+ add %sp, STACK_SIZE+32, %sp /* IEU1 */
+ andcc %g1, 0xff, %g0 /* IEU1 Group */
+ retl /* CTI+IEU1 Group */
+ move %icc, 0, %o0 /* Single Group */
+
+13: add %sp, STACK_SIZE+32, %sp /* IEU1 */
+ srlx %o2, 56, %g1 /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ movrz %g1, 0, %o0 /* Single Group */
+
+ .align 16
+12: sub %o0, 1, %o0 /* IEU0 Group */
+ or %o3, %o2, %g1 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+
+ movrz %g1, 0, %o0 /* Single Group */
+END(strpbrk)
+libc_hidden_builtin_def (strpbrk)
diff --git a/libc/sysdeps/sparc/sparc64/strrchr.c b/libc/sysdeps/sparc/sparc64/strrchr.c
new file mode 100644
index 000000000..ec608d6ab
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/strrchr.c
@@ -0,0 +1 @@
+/* strrchr is in strchr.S */
diff --git a/libc/sysdeps/sparc/sparc64/strspn.S b/libc/sysdeps/sparc/sparc64/strspn.S
new file mode 100644
index 000000000..1af24854e
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/strspn.S
@@ -0,0 +1,213 @@
+/* strspn (str, ss) -- Return the length of the maximum initial segment
+ of S which contains only characters in ACCEPT.
+ For SPARC v9.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm/asi.h>
+#ifndef XCC
+#define XCC xcc
+#define STACK_SIZE 128
+#define STACK_OFFSET 128+0x7ff
+ .register %g2, #scratch
+#else
+#define STACK_SIZE 64
+#define STACK_OFFSET 64
+#endif
+
+ .text
+ .align 32
+ENTRY(strspn)
+ sub %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ mov 1, %o4 /* IEU1 */
+ stx %g0, [%sp + STACK_OFFSET] /* Store Group */
+ mov %o0, %g4 /* IEU0 */
+
+ stx %g0, [%sp + STACK_OFFSET + 8] /* Store Group */
+ add %sp, STACK_OFFSET, %o5 /* IEU0 */
+ stx %g0, [%sp + STACK_OFFSET + 16] /* Store Group */
+ stx %g0, [%sp + STACK_OFFSET + 24] /* Store Group */
+
+1: ldub [%o1], %o2 /* Load Group */
+ brz,pn %o2, 2f /* CTI+IEU1 Group */
+ srl %o2, 3, %o3 /* IEU0 */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+
+ and %o2, 0x3f, %o2 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ sllx %o4, %o2, %g1 /* IEU0 */
+ add %o1, 1, %o1 /* IEU1 */
+
+ or %g2, %g1, %g2 /* IEU0 Group */
+ ba,pt %xcc, 1b /* CTI */
+ stx %g2, [%o5 + %o3] /* Store */
+2: andcc %o0, 7, %g0 /* IEU1 Group */
+
+ be,a,pt %xcc, 4f /* CTI */
+ ldx [%o0], %o2 /* Load */
+ ldub [%o0], %o2 /* Load Group */
+3: srl %o2, 3, %o3 /* IEU0 Group */
+
+ and %o2, 0x3f, %o2 /* IEU1 */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ sllx %o4, %o2, %g1 /* IEU0 */
+
+ add %o0, 1, %o0 /* IEU1 */
+ andcc %g2, %g1, %g0 /* IEU1 Group */
+ be,pn %xcc, 12f /* CTI */
+ andcc %o0, 7, %g0 /* IEU1 Group */
+
+ bne,a,pt %icc, 3b /* CTI */
+ ldub [%o0], %o2 /* Load */
+ ldx [%o0], %o2 /* Load Group */
+4: srlx %o2, 59, %o3 /* IEU0 Group */
+
+ srlx %o2, 56, %g5 /* IEU0 Group */
+5: and %o3, 0x18, %o3 /* IEU1 */
+ andcc %g5, 0x3f, %g5 /* IEU1 Group */
+ ldx [%o5 + %o3], %g2 /* Load */
+
+ srlx %o2, 51, %o3 /* IEU0 */
+ sllx %o4, %g5, %g1 /* IEU0 Group */
+ srlx %o2, 48, %g5 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+
+ be,pn %xcc, 13f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g5 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+
+ srlx %o2, 43, %o3 /* IEU0 */
+ sllx %o4, %g5, %g1 /* IEU0 Group */
+ srlx %o2, 40, %g5 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+
+ be,pn %xcc, 14f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g5 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+
+ srlx %o2, 35, %o3 /* IEU0 */
+ sllx %o4, %g5, %g1 /* IEU0 Group */
+ srlx %o2, 32, %g5 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+
+ be,pn %xcc, 15f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g5 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+
+ srlx %o2, 27, %o3 /* IEU0 */
+ sllx %o4, %g5, %g1 /* IEU0 Group */
+ srlx %o2, 24, %g5 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+
+ be,pn %xcc, 16f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g5 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+
+ srlx %o2, 19, %o3 /* IEU0 */
+ sllx %o4, %g5, %g1 /* IEU0 Group */
+ srlx %o2, 16, %g5 /* IEU0 Group */
+ andcc %g2, %g1, %g2 /* IEU1 */
+
+ be,pn %xcc, 17f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g5 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+
+ srlx %o2, 11, %o3 /* IEU0 */
+ sllx %o4, %g5, %g1 /* IEU0 Group */
+ add %o0, 8, %o0 /* IEU1 */
+ srlx %o2, 8, %g5 /* IEU0 Group */
+
+ andcc %g2, %g1, %g2 /* IEU1 */
+ be,pn %xcc, 18f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+ and %g5, 0x3f, %g5 /* IEU1 */
+
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ sllx %o4, %g5, %g1 /* IEU0 */
+ mov %o2, %g5 /* IEU1 */
+ srlx %o2, 3, %o3 /* IEU0 Group */
+
+ ldxa [%o0] ASI_PNF, %o2 /* Load */
+ andcc %g2, %g1, %g2 /* IEU1 Group */
+ be,pn %xcc, 19f /* CTI */
+ and %o3, 0x18, %o3 /* IEU0 Group */
+
+ and %g5, 0x3f, %g5 /* IEU1 */
+ ldx [%o5 + %o3], %g2 /* Load Group */
+ sllx %o4, %g5, %g1 /* IEU0 */
+ srlx %o2, 59, %o3 /* IEU0 Group */
+
+ andcc %g2, %g1, %g2 /* IEU1 Group */
+ bne,pt %xcc, 5b /* CTI */
+ srlx %o2, 56, %g5 /* IEU0 Group */
+ sub %o0, 1, %o0 /* IEU1 */
+
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+ .align 16
+19: sub %o0, 2, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+18: sub %o0, 3, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+17: add %o0, 4, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+16: add %o0, 3, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+15: add %o0, 2, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+14: add %o0, 1, %o0 /* IEU1 */
+ add %sp, STACK_SIZE+32, %sp /* IEU0 Group */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+13: add %sp, STACK_SIZE+32, %sp /* IEU1 */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+
+ .align 16
+12: sub %o0, 1, %o0 /* IEU0 Group */
+ add %sp, STACK_SIZE+32, %sp /* IEU1 */
+ retl /* CTI+IEU1 Group */
+ sub %o0, %g4, %o0 /* IEU0 */
+END(strspn)
+libc_hidden_builtin_def (strspn)
diff --git a/libc/sysdeps/sparc/sparc64/sub_n.S b/libc/sysdeps/sparc/sparc64/sub_n.S
new file mode 100644
index 000000000..db1138b78
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/sub_n.S
@@ -0,0 +1,55 @@
+/* SPARC v9 __mpn_sub_n -- Subtract two limb vectors of the same length > 0
+ and store difference in a third limb vector.
+
+ Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include <sysdep.h>
+
+/* INPUT PARAMETERS
+ res_ptr %o0
+ s1_ptr %o1
+ s2_ptr %o2
+ size %o3 */
+
+ENTRY(__mpn_sub_n)
+
+ sub %g0,%o3,%g5
+ sllx %o3,3,%g1
+ add %o1,%g1,%o1 ! make s1_ptr point at end
+ add %o2,%g1,%o2 ! make s2_ptr point at end
+ add %o0,%g1,%o0 ! make res_ptr point at end
+ mov 0,%o4 ! clear carry variable
+ sllx %g5,3,%o5 ! compute initial address index
+
+1: ldx [%o2+%o5],%g1 ! load s2 limb
+ add %g5,1,%g5 ! increment loop count
+ ldx [%o1+%o5],%o3 ! load s1 limb
+ addcc %g1,%o4,%g1 ! add s2 limb and carry variable
+ movcc %xcc,0,%o4 ! if carry-out, o4 was 1; clear it
+ subcc %o3,%g1,%g1 ! subtract s1 limb from sum
+ stx %g1,[%o0+%o5] ! store result
+ add %o5,8,%o5 ! increment address index
+ brnz,pt %g5,1b
+ movcs %xcc,1,%o4 ! if s1 subtract gave carry, record it
+
+ retl
+ mov %o4,%o0
+
+END(__mpn_sub_n)
diff --git a/libc/sysdeps/sparc/sparc64/submul_1.S b/libc/sysdeps/sparc/sparc64/submul_1.S
new file mode 100644
index 000000000..bc42ff74b
--- /dev/null
+++ b/libc/sysdeps/sparc/sparc64/submul_1.S
@@ -0,0 +1,83 @@
+/* SPARC v9 __mpn_submul_1 -- Multiply a limb vector with a single limb and
+ subtract the product from a second limb vector.
+
+ Copyright (C) 1996 Free Software Foundation, Inc.
+
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include <sysdep.h>
+
+
+/* INPUT PARAMETERS
+ res_ptr o0
+ s1_ptr o1
+ size o2
+ s2_limb o3 */
+
+ENTRY(__mpn_submul_1)
+ save %sp,-192,%sp
+
+ sub %g0,%i2,%o7
+ mov 0,%o0 ! zero cy_limb
+ sllx %o7,3,%o7
+ sethi %hi(0x80000000),%o2
+ srl %i3,0,%o1 ! extract low 32 bits of s2_limb
+ sub %i1,%o7,%o3
+ srlx %i3,32,%i3 ! extract high 32 bits of s2_limb
+ sub %i0,%o7,%o4
+ add %o2,%o2,%o2 ! o2 = 0x100000000
+
+ ! hi !
+ ! mid-1 !
+ ! mid-2 !
+ ! lo !
+1:
+ ldx [%o3+%o7],%g5
+ srl %g5,0,%i0 ! zero hi bits
+ ldx [%o4+%o7],%l1
+ srlx %g5,32,%g5
+ mulx %o1,%i0,%i4 ! lo product
+ mulx %i3,%i0,%i1 ! mid-1 product
+ mulx %o1,%g5,%l2 ! mid-2 product
+ mulx %i3,%g5,%i5 ! hi product
+ srlx %i4,32,%i0 ! extract high 32 bits of lo product...
+ add %i1,%i0,%i1 ! ...and add it to the mid-1 product
+ addcc %i1,%l2,%i1 ! add mid products
+ mov 0,%l0 ! we need the carry from that add...
+ movcs %xcc,%o2,%l0 ! ...compute it and...
+ sllx %i1,32,%i0 ! align low bits of mid product
+ add %i5,%l0,%i5 ! ...add to bit 32 of the hi product
+ srl %i4,0,%g5 ! zero high 32 bits of lo product
+ add %i0,%g5,%i0 ! combine into low 64 bits of result
+ srlx %i1,32,%i1 ! extract high bits of mid product...
+ addcc %i0,%o0,%i0 ! add cy_limb to low 64 bits of result
+ add %i5,%i1,%i1 ! ...and add them to the high result
+ mov 0,%g5
+ movcs %xcc,1,%g5
+ subcc %l1,%i0,%i0
+ stx %i0,[%o4+%o7]
+ add %g5,1,%l1
+ movcs %xcc,%l1,%g5
+ addcc %o7,8,%o7
+ bne,pt %xcc,1b
+ add %i1,%g5,%o0 ! compute new cy_limb
+
+ jmpl %i7+8, %g0
+ restore %o0,%g0,%o0
+
+END(__mpn_submul_1)
diff --git a/libc/sysdeps/sparc/stackinfo.h b/libc/sysdeps/sparc/stackinfo.h
new file mode 100644
index 000000000..fd34e2deb
--- /dev/null
+++ b/libc/sysdeps/sparc/stackinfo.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file contains a bit of information about the stack allocation
+ of the processor. */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H 1
+
+/* On sparc the stack grows down. */
+#define _STACK_GROWS_DOWN 1
+
+#endif /* stackinfo.h */
diff --git a/libc/sysdeps/sparc/sys/trap.h b/libc/sysdeps/sparc/sys/trap.h
new file mode 100644
index 000000000..50be40668
--- /dev/null
+++ b/libc/sysdeps/sparc/sys/trap.h
@@ -0,0 +1,7 @@
+/* Include trap definitions. */
+#ifndef _SYS_TRAP_H
+#define _SYS_TRAP_H 1
+
+#include <machine/trap.h>
+
+#endif /* sys/trap.h */
diff --git a/libc/sysdeps/unix/Implies b/libc/sysdeps/unix/Implies
new file mode 100644
index 000000000..b3188f742
--- /dev/null
+++ b/libc/sysdeps/unix/Implies
@@ -0,0 +1 @@
+posix
diff --git a/libc/sysdeps/unix/Makefile b/libc/sysdeps/unix/Makefile
new file mode 100644
index 000000000..4ab06ba33
--- /dev/null
+++ b/libc/sysdeps/unix/Makefile
@@ -0,0 +1,346 @@
+# Copyright (C) 1991,1992,1993,1994,1995,1996,1997,1998,1999,2003, 2006
+# Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+# The unix-specific configure fragment writes `unix-generated' in config.make.
+config-generated := $(config-generated) $(unix-generated)
+
+ifeq (,$(filter-out $(sysdep_dir)/generic/ $(common-objpfx),\
+ $(dir $(firstword $(wildcard $(+sysdep_dirs:%=%/bits/local_lim.h))))))
+
+ifneq (,$(wildcard $(sysincludedir)/sys/param.h))
+mk-local_lim-CFLAGS += -DHAVE_SYS_PARAM_H
+endif
+ifneq (,$(wildcard $(sysincludedir)/sys/limits.h))
+mk-local_lim-CFLAGS += -DHAVE_SYS_LIMITS_H
+endif
+ifneq (,$(wildcard $(sysincludedir)/limits.h))
+mk-local_lim-CFLAGS += -DHAVE_LIMITS_H
+endif
+
+$(common-objpfx)bits/local_lim.h: $(common-objpfx)mk-local_lim
+ $(dir $<)$(notdir $<) > $@-t
+ mv -f $@-t $@
+$(common-objpfx)mk-local_lim: $(sysdep_dir)/unix/mk-local_lim.c
+ $(common-objdir-compile)
+
+before-compile += $(common-objpfx)bits/local_lim.h
+common-generated += bits/local_lim.h mk-local_lim
+
+endif
+
+ifeq (,$(filter-out $(sysdep_dir)/generic/ $(common-objpfx),\
+ $(patsubst %/sys/param.h,%/,\
+ $(firstword $(wildcard $(+sysdep_dirs:%=%/sys/param.h))))))
+
+before-compile := $(before-compile) $(common-objpfx)sys/param.h
+
+$(common-objpfx)sys/param.h: $(sysincludedir)/sys/param.h
+ $(make-target-directory)
+ (echo '#ifndef _SYS_PARAM_H'; \
+ echo '#define _SYS_PARAM_H 1'; \
+ echo '#include <endian.h>'; \
+ $(AWK) < $< \
+ '/^#define[ ]*NULL/ { print "#ifndef NULL"; \
+ print $$0; \
+ print "#endif"; \
+ was_null = 1 } \
+ { if (!was_null) print $$0; \
+ was_null = 0 }'; \
+ echo '#ifndef MAXHOSTNAMELEN'; \
+ echo '#define MAXHOSTNAMELEN 64 /* XXX */'; \
+ echo '#endif /* No MAXHOSTNAMELEN. */'; \
+ echo '#endif /* sys/param.h */') > $@-tmp
+ mv $@-tmp $@
+
+$(common-objpfx)param.h.c: $(sysincludedir)/sys/param.h
+ rm -f $@
+ cp $< $@
+$(common-objpfx)param.h.dep: $(common-objpfx)param.h.c \
+ $(sysdep_dir)/unix/Makefile
+ $(+mkdep) -I$(sysincludedir) $< \
+ | sed > $@-t \
+ -e 's@$(sysincludedir)/sys/param.h@@' \
+ -e 's@^.*:@@' \
+ -e 's@$<@@g' \
+ -e 's@$(sysincludedir)/*@@g' \
+ -e 's@\\$$@@' \
+ -e 's@^@sys/param.h-includes := $$(sys/param.h-includes) @'
+ mv $@-t $@
+
+# Get the generated definition of sys/param.h-includes.
+ifndef no_deps
+-include $(common-objpfx)param.h.dep
+endif
+
+# Don't preempt our own headers.
+sys/param.h-includes := \
+ $(filter-out $(patsubst $(..)%,%,\
+ $(wildcard $(addprefix $(..),\
+ $(sys/param.h-includes)))),\
+ $(sys/param.h-includes))
+
+
+.PHONY: sys/param.h-includes
+sys/param.h-includes: $(addprefix $(common-objpfx),$(sys/param.h-includes))
+
+ifdef sys/param.h-includes
+# Copy the system files to $(common-objdir).
+$(addprefix $(common-objpfx),$(sys/param.h-includes)): $(common-objpfx)%: \
+ $(sysincludedir)/%
+ $(make-target-directory)
+# Some of these files sometimes contain conflicting declarations for htons,
+# ntohs, etc. They also often contain definitions of *_ENDIAN and
+# BYTE_ORDER, which we define ourselves in <endian.h>.
+ sed -e '/[ ]*[hn]to[nh][sl][ (]*/d' \
+ -e '/^#define[ ]*[A-Z]*_ENDIAN/d' \
+ -e '/^#define[ ]*BYTE_ORDER/d' \
+ $< > $@-t
+ mv $@-t $@
+endif
+
+common-generated := $(common-generated) \
+ sys/param.h $(sys/param.h-includes) param.h.c param.h.dep
+
+
+ifeq ($(subdir),misc)
+
+# Install system headers the system sys/param.h uses.
+
+sysdep_headers := $(sysdep_headers) $(sys/param.h-includes)
+
+endif # misc
+
+endif # No sysdep sys/param.h.
+
+ifeq (,$(filter-out $(sysdep_dir)/generic/ $(common-objpfx),\
+ $(dir $(firstword $(wildcard $(+sysdep_dirs:%=%/bits/errno.h))))))
+
+# These need to exist before any compiling is done,
+# so cpp doesn't instead find the generic versions.
+before-compile := $(before-compile) $(common-objpfx)bits/errno.h
+
+$(common-objpfx)bits/errno.h: $(common-objpfx)make-errnos
+ $(dir $<)$(notdir $<) > $@-tmp
+ mv $@-tmp $@
+
+$(common-objpfx)make-errnos: $(common-objpfx)make-errnos.c
+ $(common-objdir-compile)
+
+$(common-objpfx)make-errnos.c: $(sysdep_dir)/unix/errnos-tmpl.c \
+ $(sysdep_dir)/unix/errnos.awk $(common-objpfx)errnos
+ $(AWK) -f $(word 2,$^) errnos="`tr '\012' ' ' < $(word 3,$^)`" $< > $@T
+ mv $@T $@
+
+$(common-objpfx)errnos: $(wildcard $(sysincludedir)/errno.h \
+ $(sysincludedir)/sys/errno.h)
+ sed -n 's/^#define[ ]*\(E[A-Z0-9][A-Z0-9]*\)[ ].*$$/\1/p' \
+ $^ > $@-tmp
+ mv $@-tmp $@
+
+common-generated := $(common-generated) \
+ errnos.h errnos make-errnos make-errnos.c
+endif
+
+ifeq (,$(filter-out $(sysdep_dir)/generic/ $(common-objpfx),\
+ $(dir $(firstword $(wildcard $(+sysdep_dirs:%=%/bits/ioctls.h))))))
+
+before-compile := $(before-compile) $(common-objpfx)bits/ioctls.h
+
+$(common-objpfx)bits/ioctls.h: $(common-objpfx)make-ioctls
+ $(dir $<)$(notdir $<) > $@-tmp
+ mv $@-tmp $@
+
+ioctl-includes := sys/termios.h net/nit.h
+ioctl-includes := $(wildcard $(addprefix $(sysincludedir)/,$(ioctl-includes)))
+make-ioctls-CFLAGS := $(subst /,_,$(subst .,_,\
+ $(patsubst $(sysincludedir)/%,-DHAVE_%,\
+ $(ioctl-includes))))
+
+$(common-objpfx)make-ioctls: $(common-objpfx)make-ioctls.c
+ $(common-objdir-compile)
+
+$(common-objpfx)make-ioctls.c: $(sysdep_dir)/unix/ioctls-tmpl.c \
+ $(sysdep_dir)/unix/ioctls.awk \
+ $(common-objpfx)ioctls
+ $(AWK) -f $(word 2,$^) requests="`cat $(word 3,$^)`" $< > $@T
+ mv $@T $@
+
+
+bits_termios.h := $(firstword $(wildcard $(+sysdep_dirs:%=%/bits/termios.h)))
+ifeq ($(bits_termios.h),$(sysdep_dir)/generic/bits/termios.h)
+bits_termios.h := # Ignore the generic version.
+endif
+
+# If there is a system-specific <bits/termios.h> file, we want to omit
+# all the symbols it defines from ioctls. Otherwise, both
+# <bits/ioctls.h> and <bits/termios.h> would define them. The
+# system-specific <bits/termios.h> file presumably defines them with
+# the same values as we find from the system's headers. We also want
+# to omit from ioctls the symbols defined in our own
+# <sys/ttydefaults.h>, to avoid multiple definition conflicts. We use
+# snarf-ioctls on these files to find what symbols we want to omit.
+# fgrep -xv gives all lines which do not match in their entirety;
+# without -x, CSTOP's presence elided TIOCSTOP.
+
+$(common-objpfx)ioctls: $(sysdep_dir)/unix/snarf-ioctls \
+ $(sysincludedir)/sys/ioctl.h $(ioctl-includes)
+ $(dir $<)$(notdir $<) $(filter-out $<,$^) \
+ | fgrep -xv "`($(dir $<)$(notdir $<) $(bits_termios.h) \
+ $(..)sysdeps/generic/sys/ttydefaults.h; \
+ echo NULL) \
+ | sort | uniq`" \
+ | sort | uniq | tr '\012' ' ' > $@-tmp
+ mv $@-tmp $@
+
+common-generated := $(common-generated) \
+ bits/ioctls.h ioctls make-ioctls make-ioctls.c
+endif
+
+ifeq (,$(filter-out $(sysdep_dir)/generic/ $(common-objpfx),\
+ $(dir $(firstword $(wildcard $(+sysdep_dirs:%=%/sys/syscall.h))))))
+
+# The syscall code assumes a file <sys/syscall.h> that defines macros
+# `SYS_call' for syscall `call'. Variations on this I have seen include:
+# it's in <sys/syscall.h>;
+# it's in <sys.s>;
+# it defines `CALL' instead of `SYS_call'.
+# Irix has a <syscall.h> which is not what we want, so check for <sys.s> first.
+
+# Find a file that might have these. NOTE: This list of possibilities is
+# repeated in sysdeps/unix/configure and the two should be kept in sync.
+syscall.h := $(firstword $(wildcard $(addprefix $(sysincludedir)/, \
+ sys.s sys/sys.s \
+ sys.S sys/sys.S \
+ syscall.h sys/syscall.h \
+ )))
+ifdef syscall.h
+
+# Transmogrify any of several formats of the file into the one we want.
+$(common-objpfx)sys/syscall.h: $(syscall.h)
+ $(make-target-directory)
+ tr '[A-Z]' '[a-z]' < $< | \
+ sed -e 's/[ ]sys_/ /' \
+ -e 's/^#define[ ]*\([a-z0-9_]*\)[ ]*/#define SYS_\1 /' \
+ -e 's/[ ]sys_/ SYS_/' \
+ -e 's/SYS_syscall_basenum/syscall_basenum/g' \
+ -e 's/SYS_kerncall_basenum/kerncall_basenum/g' \
+ -e 's/SYS_sysvoffset/sysvoffset/g' \
+ -e '/^#/!d' \
+ -e '/^#ident/d' \
+ -e 's-\(/\*[^*]*\)$$-\1\*/-' \
+ > $@-tmp
+ mv $@-tmp $@
+
+before-compile += $(common-objpfx)sys/syscall.h
+common-generated += sys/syscall.h
+
+endif
+
+endif
+
+ifndef inhibit-unix-syscalls
+
+# Sysdep dirs unix/... can contain a file syscalls.list,
+# which specifies objects to be compiled as simple Unix system calls.
+
+-include $(common-objpfx)sysd-syscalls
+omit-deps += $(unix-syscalls)
+
+ifeq (misc,$(subdir))
+sysdep_routines += $(unix-extra-syscalls)
+
+ifdef unix-stub-syscalls
+# The system call entry points in this list are supposed to be additional
+# functions not overriding any other sysdeps/.../call.c implementation, but
+# their system call numbers are unavailable in the kernel headers we're
+# using. Instead of a system call stub, these get a function that fails
+# with ENOSYS. We just generate a single module defining one function and
+# making all these entry point names aliases for it.
+sysdep_routines += stub-syscalls
+$(objpfx)stub-syscalls.c: $(common-objpfx)sysd-syscalls \
+ $(..)sysdeps/unix/Makefile
+ $(make-target-directory)
+ (for call in $(unix-stub-syscalls); do \
+ echo "#define $$call RENAMED_$$call"; \
+ done; \
+ echo '#include <errno.h>'; \
+ for call in $(unix-stub-syscalls); do \
+ echo "#undef $$call"; \
+ done; \
+ echo 'long int _no_syscall (void)'; \
+ echo '{ __set_errno (ENOSYS); return -1L; }'; \
+ for call in $(unix-stub-syscalls); do \
+ case $$call in \
+ *@@*) ver=$${call##*@}; call=$${call%%*@}; \
+ echo "strong_alias (_no_syscall, $${call}_$${ver})"; \
+ echo "default_symbol_version \
+ ($${call}_$${ver}, $$call, $$ver);" ;; \
+ *@@*) ver=$${call##*@}; call=$${call%%*@}; \
+ echo "strong_alias (_no_syscall, $${call}_$${ver})"; \
+ echo "symbol_version ($${call}_$${ver}, $$call, $$ver);" ;; \
+ *) echo "weak_alias (_no_syscall, $$call)"; \
+ echo "stub_warning ($$call)"; \
+ echo "weak_alias (_no_syscall, __GI_$$call)" ;; \
+ esac; \
+ echo '#include <stub-tag.h>'; \
+ done) > $@T
+ mv -f $@T $@
+generated += stub-syscalls.c
+endif
+endif
+
+# This is the end of the pipeline for compiling the syscall stubs.
+# The stdin in assembler with cpp using sysdep.h macros.
+# Be sure to disable debugging info since it would all just say "<stdin>".
+compile-syscall = $(filter-out -g%,$(COMPILE.S)) -x assembler-with-cpp -o $@ -
+
+ifndef avoid-generated
+$(common-objpfx)sysd-syscalls: $(..)sysdeps/unix/make-syscalls.sh \
+ $(wildcard $(+sysdep_dirs:%=%/syscalls.list))
+ for dir in $(+sysdep_dirs); do \
+ test -f $$dir/syscalls.list && \
+ { sysdirs='$(sysdirs)' \
+ asm_CPP='$(COMPILE.S) -E -x assembler-with-cpp' \
+ $(SHELL) $(dir $<)$(notdir $<) $$dir || exit 1; }; \
+ test $$dir = $(..)sysdeps/unix && break; \
+ done > $@T
+ mv -f $@T $@
+endif
+
+# The syscall objects depend on s-proto.d or s-proto-cancel.d, which
+# are generated to specify dependencies generated syscalls have on
+# headers.
+# These deps use file names relative to a subdir, so don't
+# include them in the parent directory.
+ifneq (,$(filter $(unix-syscalls),$(routines) $(sysdep_routines) $(aux)))
+ifndef no_deps
+-include $(common-objpfx)s-proto.d
+-include $(common-objpfx)s-proto-bp.d
+-include $(common-objpfx)s-proto-cancel.d
+endif
+endif
+
+$(common-objpfx)s-%.d: $(..)sysdeps/unix/s-%.S \
+ $(wildcard $(+sysdep_dirs:%=%/syscalls.list))
+ $(+make-deps)
+
+common-generated += s-proto.d s-proto-bp.d s-proto-cancel.d
+postclean-generated += sysd-syscalls
+
+endif
diff --git a/libc/sysdeps/unix/Subdirs b/libc/sysdeps/unix/Subdirs
new file mode 100644
index 000000000..a46884d4f
--- /dev/null
+++ b/libc/sysdeps/unix/Subdirs
@@ -0,0 +1 @@
+login
diff --git a/libc/sysdeps/unix/_exit.S b/libc/sysdeps/unix/_exit.S
new file mode 100644
index 000000000..115527efa
--- /dev/null
+++ b/libc/sysdeps/unix/_exit.S
@@ -0,0 +1,25 @@
+/* Copyright (C) 1991,92,97,99,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+PSEUDO (_exit, exit, 1)
+ /* Shouldn't get here. */
+PSEUDO_END(_exit)
+libc_hidden_def (_exit)
+weak_alias (_exit, _Exit)
diff --git a/libc/sysdeps/unix/alarm.c b/libc/sysdeps/unix/alarm.c
new file mode 100644
index 000000000..84ab5a52f
--- /dev/null
+++ b/libc/sysdeps/unix/alarm.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1991,1992,1994,1997,2002,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <sys/time.h>
+
+/* Schedule an alarm. In SECONDS seconds, the process will get a SIGALRM.
+ If SECONDS is zero, any currently scheduled alarm will be cancelled.
+ The function returns the number of seconds remaining until the last
+ alarm scheduled would have signaled, or zero if there wasn't one.
+ There is no return value to indicate an error, but you can set `errno'
+ to 0 and check its value after calling `alarm', and this might tell you.
+ The signal may come late due to processor scheduling. */
+unsigned int
+alarm (seconds)
+ unsigned int seconds;
+{
+ struct itimerval old, new;
+ unsigned int retval;
+
+ new.it_interval.tv_usec = 0;
+ new.it_interval.tv_sec = 0;
+ new.it_value.tv_usec = 0;
+ new.it_value.tv_sec = (long int) seconds;
+ if (__setitimer (ITIMER_REAL, &new, &old) < 0)
+ return 0;
+
+ retval = old.it_value.tv_sec;
+ /* Round to the nearest second, but never report zero seconds when
+ the alarm is still set. */
+ if (old.it_value.tv_usec >= 500000
+ || (retval == 0 && old.it_value.tv_usec > 0))
+ ++retval;
+ return retval;
+}
+libc_hidden_def (alarm)
diff --git a/libc/sysdeps/unix/alpha/Makefile b/libc/sysdeps/unix/alpha/Makefile
new file mode 100644
index 000000000..441aa02a8
--- /dev/null
+++ b/libc/sysdeps/unix/alpha/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),rt)
+librt-sysdep_routines += rt-sysdep
+endif
diff --git a/libc/sysdeps/unix/alpha/pipe.S b/libc/sysdeps/unix/alpha/pipe.S
new file mode 100644
index 000000000..2da4d78ab
--- /dev/null
+++ b/libc/sysdeps/unix/alpha/pipe.S
@@ -0,0 +1,32 @@
+/* Copyright (C) 1993, 1995, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger (davidm@cs.arizona.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* __pipe is a special syscall since it returns two values. */
+
+#include <sysdep.h>
+
+PSEUDO (__pipe, pipe, 0)
+ stl r0, 0(a0)
+ stl r1, 4(a0)
+ mov zero, v0
+ ret
+PSEUDO_END(__pipe)
+
+libc_hidden_def (__pipe)
+weak_alias (__pipe, pipe)
diff --git a/libc/sysdeps/unix/alpha/rt-sysdep.S b/libc/sysdeps/unix/alpha/rt-sysdep.S
new file mode 100644
index 000000000..f966bf1e5
--- /dev/null
+++ b/libc/sysdeps/unix/alpha/rt-sysdep.S
@@ -0,0 +1 @@
+#include <sysdep.S>
diff --git a/libc/sysdeps/unix/alpha/sysdep.S b/libc/sysdeps/unix/alpha/sysdep.S
new file mode 100644
index 000000000..c67a6542f
--- /dev/null
+++ b/libc/sysdeps/unix/alpha/sysdep.S
@@ -0,0 +1,135 @@
+/* Copyright (C) 1993, 1996, 1998, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Brendan Kehoe (brendan@zen.org).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <features.h>
+
+#if defined(__ELF__) && defined(PIC)
+ /* Put this at the end of libc's text segment so that all of
+ the direct branches from the syscalls are forward, and
+ thus predicted not taken. */
+ .section .text.last, "ax", @progbits
+#else
+ .text
+#endif
+
+#ifdef PIC
+ /* When building a shared library, we branch here without
+ having loaded the GP. Nor, since it was a direct branch,
+ have we loaded PV with our address. Do both. */
+# define LOADGP br pv, 1f; 1: ldgp gp, 0(pv)
+# define PROLOGUE .prologue 0
+# define EPILOGUE
+#else
+ /* When building the static library, we tail call here from
+ elsewhere, which might use a different GP. The entertaining
+ part is that we have to return with the GP of our caller
+ in place, so that linker relaxation works properly. */
+ /* ??? This is so ugly. Consider always putting the errno
+ setting code with the syscall in the static case. */
+# define GPSAVEREG t10
+# define LOADGP ldah t11, 0(pv) !gpdisp!1; \
+ br 1f; \
+ .subsection 2; \
+ 1: mov gp, GPSAVEREG; \
+ lda gp, 0(t11) !gpdisp!1; \
+ br 2f; \
+ .previous; \
+ mov gp, GPSAVEREG; \
+ 2:
+# define PROLOGUE .prologue 1
+# define EPILOGUE mov GPSAVEREG, gp
+#endif
+
+ .align 4
+ .globl __syscall_error
+ .ent __syscall_error
+__syscall_error:
+
+#if defined(_LIBC_REENTRANT) && USE___THREAD
+
+#ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+#else
+# define SYSCALL_ERROR_ERRNO errno
+#endif
+
+ LOADGP
+ PROLOGUE
+ mov v0, t0
+ call_pal PAL_rduniq
+ ldq t1, SYSCALL_ERROR_ERRNO(gp) !gottprel
+ addq v0, t1, v0
+ stl t0, 0(v0)
+ lda v0, -1
+ EPILOGUE
+ ret
+
+#elif defined(_LIBC_REENTRANT)
+
+ LOADGP
+ lda sp, -32(sp)
+ .frame sp, 32, ra, 0
+ stq ra, 0(sp)
+ stq v0, 8(sp)
+#ifdef GPSAVEREG
+ stq GPSAVEREG, 16(sp)
+#endif
+ .mask 0x4000001, -32
+ PROLOGUE
+
+ /* Find our per-thread errno address */
+#if defined PIC && !defined IS_IN_librt
+ bsr ra, __errno_location !samegp
+#else
+ jsr ra, __errno_location
+#ifndef GPSAVEREG
+ ldgp gp, 0(ra)
+#endif
+#endif
+
+ /* Store the error value. */
+ ldq t0, 8(sp)
+ stl t0, 0(v0)
+
+ /* And kick back a -1. */
+ ldi v0, -1
+
+#ifdef GPSAVEREG
+ ldq GPSAVEREG, 16(sp)
+#endif
+ ldq ra, 0(sp)
+ lda sp, 32(sp)
+ EPILOGUE
+ ret
+
+#else
+
+ LOADGP
+ PROLOGUE
+ stl v0, errno
+ lda v0, -1
+ EPILOGUE
+ ret
+
+#endif
+
+ .subsection 3
+ .end __syscall_error
diff --git a/libc/sysdeps/unix/alpha/sysdep.h b/libc/sysdeps/unix/alpha/sysdep.h
new file mode 100644
index 000000000..2e5bc798e
--- /dev/null
+++ b/libc/sysdeps/unix/alpha/sysdep.h
@@ -0,0 +1,438 @@
+/* Copyright (C) 1992, 1995, 1996, 2000, 2003, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Brendan Kehoe (brendan@zen.org).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/unix/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+#ifdef __linux__
+# include <alpha/regdef.h>
+#else
+# include <regdef.h>
+#endif
+
+#include <tls.h> /* Defines USE___THREAD. */
+
+#ifdef IS_IN_rtld
+# include <dl-sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */
+#endif
+
+
+#ifdef __STDC__
+#define __LABEL(x) x##:
+#else
+#define __LABEL(x) x/**/:
+#endif
+
+#define LEAF(name, framesize) \
+ .globl name; \
+ .align 4; \
+ .ent name, 0; \
+ __LABEL(name) \
+ .frame sp, framesize, ra
+
+#define ENTRY(name) \
+ .globl name; \
+ .align 4; \
+ .ent name, 0; \
+ __LABEL(name) \
+ .frame sp, 0, ra
+
+/* Mark the end of function SYM. */
+#undef END
+#define END(sym) .end sym
+
+#ifdef PROF
+# define PSEUDO_PROLOGUE \
+ .frame sp, 0, ra; \
+ ldgp gp,0(pv); \
+ .set noat; \
+ lda AT,_mcount; \
+ jsr AT,(AT),_mcount; \
+ .set at; \
+ .prologue 1
+#elif defined PIC
+# define PSEUDO_PROLOGUE \
+ .frame sp, 0, ra; \
+ .prologue 0
+#else
+# define PSEUDO_PROLOGUE \
+ .frame sp, 0, ra; \
+ ldgp gp,0(pv); \
+ .prologue 1
+#endif /* PROF */
+
+#if RTLD_PRIVATE_ERRNO
+# define SYSCALL_ERROR_LABEL $syscall_error
+# define SYSCALL_ERROR_HANDLER \
+ stl v0, rtld_errno(gp) !gprel; \
+ lda v0, -1; \
+ ret
+#elif defined(PIC)
+# define SYSCALL_ERROR_LABEL __syscall_error
+# define SYSCALL_ERROR_HANDLER \
+ br $31, __syscall_error !samegp
+#else
+# define SYSCALL_ERROR_LABEL $syscall_error
+# define SYSCALL_ERROR_HANDLER \
+ jmp $31, __syscall_error
+#endif /* RTLD_PRIVATE_ERRNO */
+
+/* Overridden by specific syscalls. */
+#undef PSEUDO_PREPARE_ARGS
+#define PSEUDO_PREPARE_ARGS /* Nothing. */
+
+#define PSEUDO(name, syscall_name, args) \
+ .globl name; \
+ .align 4; \
+ .ent name,0; \
+__LABEL(name) \
+ PSEUDO_PROLOGUE; \
+ PSEUDO_PREPARE_ARGS \
+ lda v0, SYS_ify(syscall_name); \
+ call_pal PAL_callsys; \
+ bne a3, SYSCALL_ERROR_LABEL
+
+#undef PSEUDO_END
+#if defined(PIC) && !RTLD_PRIVATE_ERRNO
+# define PSEUDO_END(sym) END(sym)
+#else
+# define PSEUDO_END(sym) \
+$syscall_error: \
+ SYSCALL_ERROR_HANDLER; \
+ END(sym)
+#endif
+
+#define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .globl name; \
+ .align 4; \
+ .ent name,0; \
+__LABEL(name) \
+ PSEUDO_PROLOGUE; \
+ PSEUDO_PREPARE_ARGS \
+ lda v0, SYS_ify(syscall_name); \
+ call_pal PAL_callsys;
+
+#undef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(sym) END(sym)
+
+#define ret_NOERRNO ret
+
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .globl name; \
+ .align 4; \
+ .ent name,0; \
+__LABEL(name) \
+ PSEUDO_PROLOGUE; \
+ PSEUDO_PREPARE_ARGS \
+ lda v0, SYS_ify(syscall_name); \
+ call_pal PAL_callsys;
+
+#undef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(sym) END(sym)
+
+#define ret_ERRVAL ret
+
+#define r0 v0
+#define r1 a4
+
+#define MOVE(x,y) mov x,y
+
+#else /* !ASSEMBLER */
+
+/* ??? Linux needs to be able to override INLINE_SYSCALL for one
+ particular special case. Make this easy. */
+
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+ INLINE_SYSCALL1(name, nr, args)
+
+#define INLINE_SYSCALL1(name, nr, args...) \
+({ \
+ long _sc_ret, _sc_err; \
+ inline_syscall##nr(__NR_##name, args); \
+ if (__builtin_expect (_sc_err, 0)) \
+ { \
+ __set_errno (_sc_ret); \
+ _sc_ret = -1L; \
+ } \
+ _sc_ret; \
+})
+
+#define INTERNAL_SYSCALL(name, err_out, nr, args...) \
+ INTERNAL_SYSCALL1(name, err_out, nr, args)
+
+#define INTERNAL_SYSCALL1(name, err_out, nr, args...) \
+ INTERNAL_SYSCALL_NCS(__NR_##name, err_out, nr, args)
+
+#define INTERNAL_SYSCALL_NCS(name, err_out, nr, args...) \
+({ \
+ long _sc_ret, _sc_err; \
+ inline_syscall##nr(name, args); \
+ err_out = _sc_err; \
+ _sc_ret; \
+})
+
+#define INTERNAL_SYSCALL_DECL(err) long int err
+#define INTERNAL_SYSCALL_ERROR_P(val, err) err
+#define INTERNAL_SYSCALL_ERRNO(val, err) val
+
+#define inline_syscall_clobbers \
+ "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", \
+ "$22", "$23", "$24", "$25", "$27", "$28", "memory"
+
+/* If TLS is in use, we have a conflict between the PAL_rduniq primitive,
+ as modeled within GCC, and explicit use of the R0 register. If we use
+ the register via the asm, the scheduler may place the PAL_rduniq insn
+ before we've copied the data from R0 into _sc_ret. If this happens
+ we'll get a reload abort, since R0 is live at the same time it is
+ needed for the PAL_rduniq.
+
+ Solve this by using the "v" constraint instead of an asm for the syscall
+ output. We don't do this unconditionally to allow compilation with
+ older compilers. */
+
+#ifdef HAVE___THREAD
+#define inline_syscall_r0_asm
+#define inline_syscall_r0_out_constraint "=v"
+#else
+#define inline_syscall_r0_asm __asm__("$0")
+#define inline_syscall_r0_out_constraint "=r"
+#endif
+
+/* It is moderately important optimization-wise to limit the lifetime
+ of the hard-register variables as much as possible. Thus we copy
+ in/out as close to the asm as possible. */
+
+#define inline_syscall0(name, args...) \
+{ \
+ register long _sc_0 inline_syscall_r0_asm; \
+ register long _sc_19 __asm__("$19"); \
+ \
+ _sc_0 = name; \
+ __asm__ __volatile__ \
+ ("callsys # %0 %1 <= %2" \
+ : inline_syscall_r0_out_constraint (_sc_0), \
+ "=r"(_sc_19) \
+ : "0"(_sc_0) \
+ : inline_syscall_clobbers, \
+ "$16", "$17", "$18", "$20", "$21"); \
+ _sc_ret = _sc_0, _sc_err = _sc_19; \
+}
+
+#define inline_syscall1(name,arg1) \
+{ \
+ register long _sc_0 inline_syscall_r0_asm; \
+ register long _sc_16 __asm__("$16"); \
+ register long _sc_19 __asm__("$19"); \
+ register long _tmp_16 = (long) (arg1); \
+ \
+ _sc_0 = name; \
+ _sc_16 = _tmp_16; \
+ __asm__ __volatile__ \
+ ("callsys # %0 %1 <= %2 %3" \
+ : inline_syscall_r0_out_constraint (_sc_0), \
+ "=r"(_sc_19), "=r"(_sc_16) \
+ : "0"(_sc_0), "2"(_sc_16) \
+ : inline_syscall_clobbers, \
+ "$17", "$18", "$20", "$21"); \
+ _sc_ret = _sc_0, _sc_err = _sc_19; \
+}
+
+#define inline_syscall2(name,arg1,arg2) \
+{ \
+ register long _sc_0 inline_syscall_r0_asm; \
+ register long _sc_16 __asm__("$16"); \
+ register long _sc_17 __asm__("$17"); \
+ register long _sc_19 __asm__("$19"); \
+ register long _tmp_16 = (long) (arg1); \
+ register long _tmp_17 = (long) (arg2); \
+ \
+ _sc_0 = name; \
+ _sc_16 = _tmp_16; \
+ _sc_17 = _tmp_17; \
+ __asm__ __volatile__ \
+ ("callsys # %0 %1 <= %2 %3 %4" \
+ : inline_syscall_r0_out_constraint (_sc_0), \
+ "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17) \
+ : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17) \
+ : inline_syscall_clobbers, \
+ "$18", "$20", "$21"); \
+ _sc_ret = _sc_0, _sc_err = _sc_19; \
+}
+
+#define inline_syscall3(name,arg1,arg2,arg3) \
+{ \
+ register long _sc_0 inline_syscall_r0_asm; \
+ register long _sc_16 __asm__("$16"); \
+ register long _sc_17 __asm__("$17"); \
+ register long _sc_18 __asm__("$18"); \
+ register long _sc_19 __asm__("$19"); \
+ register long _tmp_16 = (long) (arg1); \
+ register long _tmp_17 = (long) (arg2); \
+ register long _tmp_18 = (long) (arg3); \
+ \
+ _sc_0 = name; \
+ _sc_16 = _tmp_16; \
+ _sc_17 = _tmp_17; \
+ _sc_18 = _tmp_18; \
+ __asm__ __volatile__ \
+ ("callsys # %0 %1 <= %2 %3 %4 %5" \
+ : inline_syscall_r0_out_constraint (_sc_0), \
+ "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17), \
+ "=r"(_sc_18) \
+ : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), \
+ "4"(_sc_18) \
+ : inline_syscall_clobbers, "$20", "$21"); \
+ _sc_ret = _sc_0, _sc_err = _sc_19; \
+}
+
+#define inline_syscall4(name,arg1,arg2,arg3,arg4) \
+{ \
+ register long _sc_0 inline_syscall_r0_asm; \
+ register long _sc_16 __asm__("$16"); \
+ register long _sc_17 __asm__("$17"); \
+ register long _sc_18 __asm__("$18"); \
+ register long _sc_19 __asm__("$19"); \
+ register long _tmp_16 = (long) (arg1); \
+ register long _tmp_17 = (long) (arg2); \
+ register long _tmp_18 = (long) (arg3); \
+ register long _tmp_19 = (long) (arg4); \
+ \
+ _sc_0 = name; \
+ _sc_16 = _tmp_16; \
+ _sc_17 = _tmp_17; \
+ _sc_18 = _tmp_18; \
+ _sc_19 = _tmp_19; \
+ __asm__ __volatile__ \
+ ("callsys # %0 %1 <= %2 %3 %4 %5 %6" \
+ : inline_syscall_r0_out_constraint (_sc_0), \
+ "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17), \
+ "=r"(_sc_18) \
+ : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), \
+ "4"(_sc_18), "1"(_sc_19) \
+ : inline_syscall_clobbers, "$20", "$21"); \
+ _sc_ret = _sc_0, _sc_err = _sc_19; \
+}
+
+#define inline_syscall5(name,arg1,arg2,arg3,arg4,arg5) \
+{ \
+ register long _sc_0 inline_syscall_r0_asm; \
+ register long _sc_16 __asm__("$16"); \
+ register long _sc_17 __asm__("$17"); \
+ register long _sc_18 __asm__("$18"); \
+ register long _sc_19 __asm__("$19"); \
+ register long _sc_20 __asm__("$20"); \
+ register long _tmp_16 = (long) (arg1); \
+ register long _tmp_17 = (long) (arg2); \
+ register long _tmp_18 = (long) (arg3); \
+ register long _tmp_19 = (long) (arg4); \
+ register long _tmp_20 = (long) (arg5); \
+ \
+ _sc_0 = name; \
+ _sc_16 = _tmp_16; \
+ _sc_17 = _tmp_17; \
+ _sc_18 = _tmp_18; \
+ _sc_19 = _tmp_19; \
+ _sc_20 = _tmp_20; \
+ __asm__ __volatile__ \
+ ("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7" \
+ : inline_syscall_r0_out_constraint (_sc_0), \
+ "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17), \
+ "=r"(_sc_18), "=r"(_sc_20) \
+ : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), \
+ "4"(_sc_18), "1"(_sc_19), "5"(_sc_20) \
+ : inline_syscall_clobbers, "$21"); \
+ _sc_ret = _sc_0, _sc_err = _sc_19; \
+}
+
+#define inline_syscall6(name,arg1,arg2,arg3,arg4,arg5,arg6) \
+{ \
+ register long _sc_0 inline_syscall_r0_asm; \
+ register long _sc_16 __asm__("$16"); \
+ register long _sc_17 __asm__("$17"); \
+ register long _sc_18 __asm__("$18"); \
+ register long _sc_19 __asm__("$19"); \
+ register long _sc_20 __asm__("$20"); \
+ register long _sc_21 __asm__("$21"); \
+ register long _tmp_16 = (long) (arg1); \
+ register long _tmp_17 = (long) (arg2); \
+ register long _tmp_18 = (long) (arg3); \
+ register long _tmp_19 = (long) (arg4); \
+ register long _tmp_20 = (long) (arg5); \
+ register long _tmp_21 = (long) (arg6); \
+ \
+ _sc_0 = name; \
+ _sc_16 = _tmp_16; \
+ _sc_17 = _tmp_17; \
+ _sc_18 = _tmp_18; \
+ _sc_19 = _tmp_19; \
+ _sc_20 = _tmp_20; \
+ _sc_21 = _tmp_21; \
+ __asm__ __volatile__ \
+ ("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7 %8" \
+ : inline_syscall_r0_out_constraint (_sc_0), \
+ "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17), \
+ "=r"(_sc_18), "=r"(_sc_20), "=r"(_sc_21) \
+ : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), "4"(_sc_18), \
+ "1"(_sc_19), "5"(_sc_20), "6"(_sc_21) \
+ : inline_syscall_clobbers); \
+ _sc_ret = _sc_0, _sc_err = _sc_19; \
+}
+
+/* Pointer mangling support. Note that tls access is slow enough that
+ we don't deoptimize things by placing the pointer check value there. */
+
+#include <stdint.h>
+
+#if defined NOT_IN_libc && defined IS_IN_rtld
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(dst, src, tmp) \
+ ldah tmp, __pointer_chk_guard_local($29) !gprelhigh; \
+ ldq tmp, __pointer_chk_guard_local(tmp) !gprellow; \
+ xor src, tmp, dst
+# define PTR_MANGLE2(dst, src, tmp) \
+ xor src, tmp, dst
+# define PTR_DEMANGLE(dst, tmp) PTR_MANGLE(dst, dst, tmp)
+# define PTR_DEMANGLE2(dst, tmp) PTR_MANGLE2(dst, dst, tmp)
+# else
+extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
+# define PTR_MANGLE(var) \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
+# define PTR_DEMANGLE(var) PTR_MANGLE(var)
+# endif
+#elif defined PIC
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(dst, src, tmp) \
+ ldq tmp, __pointer_chk_guard; \
+ xor src, tmp, dst
+# define PTR_MANGLE2(dst, src, tmp) \
+ xor src, tmp, dst
+# define PTR_DEMANGLE(dst, tmp) PTR_MANGLE(dst, dst, tmp)
+# define PTR_DEMANGLE2(dst, tmp) PTR_MANGLE2(dst, dst, tmp)
+# else
+extern uintptr_t __pointer_chk_guard attribute_relro;
+# define PTR_MANGLE(var) \
+ (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard)
+# define PTR_DEMANGLE(var) PTR_MANGLE(var)
+# endif
+#endif
+
+#endif /* ASSEMBLER */
diff --git a/libc/sysdeps/unix/bsd/Implies b/libc/sysdeps/unix/bsd/Implies
new file mode 100644
index 000000000..cfc44915d
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/Implies
@@ -0,0 +1,5 @@
+# The directory unix/common contains things which are common to both BSD
+# and SVR4.
+unix/common
+# The directory unix/inet implements sockets and networking in the usual way.
+unix/inet
diff --git a/libc/sysdeps/unix/bsd/bits/dirent.h b/libc/sysdeps/unix/bsd/bits/dirent.h
new file mode 100644
index 000000000..e84719712
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bits/dirent.h
@@ -0,0 +1,33 @@
+/* Directory entry structure `struct dirent'. 4.2BSD version.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DIRENT_H
+# error "Never use <bits/dirent.h> directly; include <dirent.h> instead."
+#endif
+
+struct dirent
+ {
+ unsigned int d_fileno; /* 32 bits. */
+ unsigned short int d_reclen; /* 16 bits. */
+ unsigned short int d_namlen; /* 16 bits. */
+ char d_name[1]; /* Variable length. */
+ };
+
+#define _DIRENT_HAVE_D_RECLEN 1
+#define _DIRENT_HAVE_D_NAMLEN 1
diff --git a/libc/sysdeps/unix/bsd/bits/fcntl.h b/libc/sysdeps/unix/bsd/bits/fcntl.h
new file mode 100644
index 000000000..c992f93ef
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bits/fcntl.h
@@ -0,0 +1,139 @@
+/* O_*, F_*, FD_* bit values for 4.3 BSD.
+ Copyright (C) 1991, 1992, 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+
+/* File access modes for `open' and `fcntl'. */
+#define O_RDONLY 0 /* Open read-only. */
+#define O_WRONLY 1 /* Open write-only. */
+#define O_RDWR 2 /* Open read/write. */
+
+
+/* Bits OR'd into the second argument to open. */
+#define O_CREAT 0x0200 /* Create file if it doesn't exist. */
+#define O_EXCL 0x0800 /* Fail if file already exists. */
+#define O_TRUNC 0x0400 /* Truncate file to zero length. */
+/* Apparently not assigning a controlling terminal is the default
+ behavior in BSD, so no bit is required to request that behavior. */
+#define O_NOCTTY 0 /* Don't assign a controlling terminal. */
+#if defined __USE_BSD || defined __USE_SVID
+# define O_ASYNC 0x0040 /* Send SIGIO to owner when data is ready. */
+# define O_FSYNC 0x2000 /* Synchronous writes. */
+# define O_SYNC O_FSYNC
+#endif
+
+/* File status flags for `open' and `fcntl'. */
+#define O_APPEND 0x0008 /* Writes append to the file. */
+#define O_NONBLOCK 0x0004 /* Non-blocking I/O. */
+
+#ifdef __USE_BSD
+/* BSD before 4.4 doesn't support POSIX.1 O_NONBLOCK,
+ but O_NDELAY is close. */
+# define O_NDELAY O_NONBLOCK
+#endif
+
+#ifdef __USE_BSD
+/* Bits in the file status flags returned by F_GETFL.
+ These are all the O_* flags, plus FREAD and FWRITE, which are
+ independent bits set by which of O_RDONLY, O_WRONLY, and O_RDWR, was
+ given to `open'. */
+# define FREAD 1
+# define FWRITE 2
+
+/* Traditional BSD names the O_* bits. */
+# define FASYNC O_ASYNC
+# define FCREAT O_CREAT
+# define FEXCL O_EXCL
+# define FTRUNC O_TRUNC
+# define FNOCTTY O_NOCTTY
+# define FFSYNC O_FSYNC
+# define FSYNC O_SYNC
+# define FAPPEND O_APPEND
+# define FNONBLOCK O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif
+
+/* Mask for file access modes. This is system-dependent in case
+ some system ever wants to define some other flavor of access. */
+#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+
+/* XXX missing */
+#define O_LARGEFILE 0
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#if defined __USE_BSD || defined __USE_UNIX98
+# define F_GETOWN 5 /* Get owner (receiver of SIGIO). */
+# define F_SETOWN 6 /* Set owner (receiver of SIGIO). */
+#endif
+#define F_GETLK 7 /* Get record locking info. */
+#define F_SETLK 8 /* Set record locking info (non-blocking). */
+#define F_SETLKW 9 /* Set record locking info (blocking). */
+
+/* XXX missing */
+#define F_GETLK64 7 /* Get record locking info. */
+#define F_SETLK64 8 /* Set record locking info (non-blocking). */
+#define F_SETLKW64 9 /* Set record locking info (blocking). */
+
+/* File descriptor flags used with F_GETFD and F_SETFD. */
+#define FD_CLOEXEC 1 /* Close on exec. */
+
+
+#include <bits/types.h>
+
+/* The structure describing an advisory lock. This is the type of the third
+ argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+#ifndef __USE_FILE_OFFSET64
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+#else
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+#endif
+ short int l_pid; /* Process holding the lock. */
+ short int l_xxx; /* Reserved for future use. */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ short int l_pid; /* Process holding the lock. */
+ short int l_xxx; /* Reserved for future use. */
+ };
+#endif
+
+/* Values for the `l_type' field of a `struct flock'. */
+#define F_RDLCK 1 /* Read lock. */
+#define F_WRLCK 2 /* Write lock. */
+#define F_UNLCK 3 /* Remove lock. */
diff --git a/libc/sysdeps/unix/bsd/bits/posix_opt.h b/libc/sysdeps/unix/bsd/bits/posix_opt.h
new file mode 100644
index 000000000..7d5e5782e
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bits/posix_opt.h
@@ -0,0 +1,5 @@
+#define _POSIX_JOB_CONTROL 1
+#undef _POSIX_SAVED_IDS
+#define _POSIX_CHOWN_RESTRICTED 1
+#define _POSIX_NO_TRUNC -1
+#define _POSIX_VDISABLE ((unsigned char) -1)
diff --git a/libc/sysdeps/unix/bsd/bits/signum.h b/libc/sysdeps/unix/bsd/bits/signum.h
new file mode 100644
index 000000000..ce7d4682d
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bits/signum.h
@@ -0,0 +1,74 @@
+/* Signal number definitions. BSD version.
+ Copyright (C) 1991, 1992, 1993, 1996, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef _SIGNAL_H
+
+/* This file defines the fake signal functions and signal
+ number constants for 4.2 or 4.3 BSD-derived Unix system. */
+
+/* Fake signal functions. */
+#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
+#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
+#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
+
+#ifdef __USE_UNIX98
+# define SIG_HOLD ((__sighandler_t) 2) /* Add signal to hold mask. */
+#endif
+
+
+/* Signals. */
+#define SIGHUP 1 /* Hangup (POSIX). */
+#define SIGINT 2 /* Interrupt (ANSI). */
+#define SIGQUIT 3 /* Quit (POSIX). */
+#define SIGILL 4 /* Illegal instruction (ANSI). */
+#define SIGABRT SIGIOT /* Abort (ANSI). */
+#define SIGTRAP 5 /* Trace trap (POSIX). */
+#define SIGIOT 6 /* IOT trap (4.2 BSD). */
+#define SIGEMT 7 /* EMT trap (4.2 BSD). */
+#define SIGFPE 8 /* Floating-point exception (ANSI). */
+#define SIGKILL 9 /* Kill, unblockable (POSIX). */
+#define SIGBUS 10 /* Bus error (4.2 BSD). */
+#define SIGSEGV 11 /* Segmentation violation (ANSI). */
+#define SIGSYS 12 /* Bad argument to system call (4.2 BSD). */
+#define SIGPIPE 13 /* Broken pipe (POSIX). */
+#define SIGALRM 14 /* Alarm clock (POSIX). */
+#define SIGTERM 15 /* Termination (ANSI). */
+#define SIGURG 16 /* Urgent condition on socket (4.2 BSD). */
+#define SIGSTOP 17 /* Stop, unblockable (POSIX). */
+#define SIGTSTP 18 /* Keyboard stop (POSIX). */
+#define SIGCONT 19 /* Continue (POSIX). */
+#define SIGCHLD 20 /* Child status has changed (POSIX). */
+#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
+#define SIGTTIN 21 /* Background read from tty (POSIX). */
+#define SIGTTOU 22 /* Background write to tty (POSIX). */
+#define SIGIO 23 /* I/O now possible (4.2 BSD). */
+#define SIGPOLL SIGIO /* Same as SIGIO? (SVID). */
+#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */
+#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */
+#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */
+#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */
+#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */
+#define SIGINFO 29 /* Information request (4.4 BSD). */
+#define SIGUSR1 30 /* User-defined signal 1 (POSIX). */
+#define SIGUSR2 31 /* User-defined signal 2 (POSIX). */
+#define SIGLOST 32 /* Resource lost (Sun); server died (GNU). */
+
+#endif /* <signal.h> included. */
+
+#define _NSIG 33 /* Biggest signal number + 1. */
diff --git a/libc/sysdeps/unix/bsd/bits/stat.h b/libc/sysdeps/unix/bsd/bits/stat.h
new file mode 100644
index 000000000..84a58ffbc
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bits/stat.h
@@ -0,0 +1,86 @@
+/* Copyright (C) 1991, 92, 96, 97, 99, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Structure describing file characteristics. */
+struct stat
+ {
+ /* This is a short instead of dev_t for compatibility with 4.3. */
+ short int st_dev; /* Device containing the file. */
+ __ino_t st_ino; /* File serial number. */
+
+ /* This is a short instead of mode_t for compatibility with 4.3. */
+ unsigned short int st_mode; /* File mode. */
+
+ __nlink_t st_nlink; /* Link count. */
+
+ /* These are shorts instead of uid_t/gid_t for compatibility with 4.3. */
+ unsigned short int st_uid; /* User ID of the file's owner. */
+ unsigned short int st_gid; /* Group ID of the file's group.*/
+
+ /* This is a short instead of dev_t for compatibility with 4.3. */
+ short int st_rdev; /* Device number, if device. */
+
+ __off_t st_size; /* Size of file, in bytes. */
+
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atime_usec;
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtime_usec;
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctime_usec;
+
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+#define _STATBUF_ST_BLKSIZE /* Tell code we have this member. */
+
+ __blkcnt_t st_blocks; /* Number of 512-byte blocks allocated. */
+
+ long int st_spare[2];
+ };
+
+/* Encoding of the file mode. */
+
+#define __S_IFMT 0170000 /* These bits determine file type. */
+
+/* File types. */
+#define __S_IFDIR 0040000 /* Directory. */
+#define __S_IFCHR 0020000 /* Character device. */
+#define __S_IFBLK 0060000 /* Block device. */
+#define __S_IFREG 0100000 /* Regular file. */
+#define __S_IFLNK 0120000 /* Symbolic link. */
+#define __S_IFSOCK 0140000 /* Socket. */
+#define __S_IFIFO 0010000 /* FIFO. */
+
+/* POSIX.1b objects. */
+#define __S_TYPEISMQ(buf) (0)
+#define __S_TYPEISSEM(buf) (0)
+#define __S_TYPEISSHM(buf) (0)
+
+/* Protection bits. */
+
+#define __S_ISUID 04000 /* Set user ID on execution. */
+#define __S_ISGID 02000 /* Set group ID on execution. */
+#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
+#define __S_IREAD 0400 /* Read by owner. */
+#define __S_IWRITE 0200 /* Write by owner. */
+#define __S_IEXEC 0100 /* Execute by owner. */
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/Implies b/libc/sysdeps/unix/bsd/bsd4.4/Implies
new file mode 100644
index 000000000..3bdab5444
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/Implies
@@ -0,0 +1,2 @@
+# 4.4 BSD has the canonical set of <sys/mman.h> system calls.
+unix/mman
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/Makefile b/libc/sysdeps/unix/bsd/bsd4.4/Makefile
new file mode 100644
index 000000000..208fd2448
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),socket)
+sysdep_routines += cmsg_nxthdr
+endif
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/Versions b/libc/sysdeps/unix/bsd/bsd4.4/Versions
new file mode 100644
index 000000000..99b386b67
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/Versions
@@ -0,0 +1,6 @@
+libc {
+ GLIBC_2.2.5 {
+ # functions used in inline functions or macros
+ __cmsg_nxthdr;
+ }
+}
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/bits/dirent.h b/libc/sysdeps/unix/bsd/bsd4.4/bits/dirent.h
new file mode 100644
index 000000000..3f8990cb5
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/bits/dirent.h
@@ -0,0 +1,55 @@
+/* Directory entry structure `struct dirent'. 4.4BSD version.
+ Copyright (C) 1996,97,98,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DIRENT_H
+# error "Never use <bits/dirent.h> directly; include <dirent.h> instead."
+#endif
+
+struct dirent
+ {
+#ifndef __USE_FILE_OFFSET64
+ __ino_t d_ino; /* File serial number. */
+#else
+ __ino64_t d_ino;
+#endif
+ unsigned short int d_reclen; /* Length of the whole `struct dirent'. */
+ unsigned char d_type; /* File type, possibly unknown. */
+ unsigned char d_namlen; /* Length of the file name. */
+
+ /* Only this member is in the POSIX standard. */
+ char d_name[1]; /* File name (actually longer). */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct dirent64
+ {
+ __ino64_t d_ino;
+ unsigned short int d_reclen;
+ unsigned char d_type;
+ unsigned char d_namlen;
+
+ char d_name[1];
+ };
+#endif
+
+#define d_fileno d_ino /* Backwards compatibility. */
+
+#define _DIRENT_HAVE_D_RECLEN 1
+#define _DIRENT_HAVE_D_NAMLEN 1
+#define _DIRENT_HAVE_D_TYPE 1
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/bits/errno.h b/libc/sysdeps/unix/bsd/bsd4.4/bits/errno.h
new file mode 100644
index 000000000..48b1c8b6e
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/bits/errno.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)errno.h 8.5 (Berkeley) 1/21/94
+ */
+
+#ifdef _ERRNO_H
+
+#define EPERM 1 /* Operation not permitted */
+#define ENOENT 2 /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* Input/output error */
+#define ENXIO 6 /* Device not configured */
+#define E2BIG 7 /* Argument list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file descriptor */
+#define ECHILD 10 /* No child processes */
+#define EDEADLK 11 /* Resource deadlock avoided */
+ /* 11 was EAGAIN */
+#define ENOMEM 12 /* Cannot allocate memory */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+#ifdef __USE_BSD
+#define ENOTBLK 15 /* Block device required */
+#endif
+#define EBUSY 16 /* Device busy */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* Operation not supported by device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* Too many open files in system */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Inappropriate ioctl for device */
+#ifdef __USE_BSD
+#define ETXTBSY 26 /* Text file busy */
+#endif
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+
+#endif /* <errno.h> included. */
+
+/* math software */
+
+#if !defined(__Emath_defined) && (defined(_ERRNO_H) || defined(__need_Emath))
+#define EDOM 33 /* Numerical argument out of domain */
+#endif /* Emath not defined and <errno.h> included or need Emath. */
+#if !defined(__Emath_defined) && (defined(_ERRNO_H) || defined(__need_Emath))
+#define ERANGE 34 /* Result too large */
+#endif /* Emath not defined and <errno.h> included or need Emath. */
+
+#ifdef _ERRNO_H
+
+/* non-blocking and interrupt i/o */
+#define EAGAIN 35 /* Resource temporarily unavailable */
+#ifdef __USE_BSD
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#define EINPROGRESS 36 /* Operation now in progress */
+#define EALREADY 37 /* Operation already in progress */
+
+/* ipc/network software -- argument errors */
+#define ENOTSOCK 38 /* Socket operation on non-socket */
+#define EDESTADDRREQ 39 /* Destination address required */
+#define EMSGSIZE 40 /* Message too long */
+#define EPROTOTYPE 41 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 42 /* Protocol not available */
+#define EPROTONOSUPPORT 43 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
+#define EOPNOTSUPP 45 /* Operation not supported */
+#define EPFNOSUPPORT 46 /* Protocol family not supported */
+#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
+#define EADDRINUSE 48 /* Address already in use */
+#define EADDRNOTAVAIL 49 /* Can't assign requested address */
+
+/* ipc/network software -- operational errors */
+#define ENETDOWN 50 /* Network is down */
+#define ENETUNREACH 51 /* Network is unreachable */
+#define ENETRESET 52 /* Network dropped connection on reset */
+#define ECONNABORTED 53 /* Software caused connection abort */
+#define ECONNRESET 54 /* Connection reset by peer */
+#define ENOBUFS 55 /* No buffer space available */
+#define EISCONN 56 /* Socket is already connected */
+#define ENOTCONN 57 /* Socket is not connected */
+#define ESHUTDOWN 58 /* Can't send after socket shutdown */
+#define ETOOMANYREFS 59 /* Too many references: can't splice */
+#define ETIMEDOUT 60 /* Operation timed out */
+#define ECONNREFUSED 61 /* Connection refused */
+
+#define ELOOP 62 /* Too many levels of symbolic links */
+#endif /* __USE_BSD */
+#define ENAMETOOLONG 63 /* File name too long */
+
+/* should be rearranged */
+#ifdef __USE_BSD
+#define EHOSTDOWN 64 /* Host is down */
+#define EHOSTUNREACH 65 /* No route to host */
+#endif /* __USE_BSD */
+#define ENOTEMPTY 66 /* Directory not empty */
+
+/* quotas & mush */
+#ifdef __USE_BSD
+#define EPROCLIM 67 /* Too many processes */
+#define EUSERS 68 /* Too many users */
+#define EDQUOT 69 /* Disc quota exceeded */
+
+/* Network File System */
+#define ESTALE 70 /* Stale NFS file handle */
+#define EREMOTE 71 /* Too many levels of remote in path */
+#define EBADRPC 72 /* RPC struct is bad */
+#define ERPCMISMATCH 73 /* RPC version wrong */
+#define EPROGUNAVAIL 74 /* RPC prog. not avail */
+#define EPROGMISMATCH 75 /* Program version wrong */
+#define EPROCUNAVAIL 76 /* Bad procedure for program */
+#endif /* __USE_BSD */
+
+#define ENOLCK 77 /* No locks available */
+#define ENOSYS 78 /* Function not implemented */
+
+#define EFTYPE 79 /* Inappropriate file type or format */
+
+#ifdef __USE_BSD
+#define EAUTH 80 /* Authentication error */
+#define ENEEDAUTH 81 /* Need authenticator */
+#define ELAST 81 /* Must be equal largest errno */
+#endif /* __USE_BSD */
+
+
+#endif /* <errno.h> included. */
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/bits/fcntl.h b/libc/sysdeps/unix/bsd/bsd4.4/bits/fcntl.h
new file mode 100644
index 000000000..47a67e38e
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/bits/fcntl.h
@@ -0,0 +1,113 @@
+/* O_*, F_*, FD_* bit values for 4.4 BSD.
+ Copyright (C) 1991, 1992, 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+#error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+
+/* File access modes for `open' and `fcntl'. */
+#define O_RDONLY 0 /* Open read-only. */
+#define O_WRONLY 1 /* Open write-only. */
+#define O_RDWR 2 /* Open read/write. */
+
+
+/* Bits OR'd into the second argument to open. */
+#define O_CREAT 0x0200 /* Create file if it doesn't exist. */
+#define O_EXCL 0x0800 /* Fail if file already exists. */
+#define O_TRUNC 0x0400 /* Truncate file to zero length. */
+/* Apparently not assigning a controlling terminal is the default
+ behavior in BSD, so no bit is required to request that behavior. */
+#define O_NOCTTY 0 /* Don't assign a controlling terminal. */
+#ifdef __USE_MISC
+#define O_ASYNC 0x0040 /* Send SIGIO to owner when data is ready. */
+#define O_FSYNC 0x0080 /* Synchronous writes. */
+#define O_SYNC O_FSYNC
+#define O_SHLOCK 0x0010 /* Open with shared file lock. */
+#define O_EXLOCK 0x0020 /* Open with shared exclusive lock. */
+#endif
+
+/* File status flags for `open' and `fcntl'. */
+#define O_APPEND 0x0008 /* Writes append to the file. */
+#define O_NONBLOCK 0x0004 /* Non-blocking I/O. */
+
+#ifdef __USE_BSD
+#define O_NDELAY O_NONBLOCK
+#endif
+
+#ifdef __USE_BSD
+/* Bits in the file status flags returned by F_GETFL.
+ These are all the O_* flags, plus FREAD and FWRITE, which are
+ independent bits set by which of O_RDONLY, O_WRONLY, and O_RDWR, was
+ given to `open'. */
+#define FREAD 1
+#define FWRITE 2
+
+/* Traditional BSD names the O_* bits. */
+#define FASYNC O_ASYNC
+#define FCREAT O_CREAT
+#define FEXCL O_EXCL
+#define FTRUNC O_TRUNC
+#define FNOCTTY O_NOCTTY
+#define FFSYNC O_FSYNC
+#define FSYNC O_SYNC
+#define FAPPEND O_APPEND
+#define FNONBLOCK O_NONBLOCK
+#define FNDELAY O_NDELAY
+#endif
+
+/* Mask for file access modes. This is system-dependent in case
+ some system ever wants to define some other flavor of access. */
+#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#if defined __USE_BSD || defined __USE_UNIX98
+#define F_GETOWN 5 /* Get owner (receiver of SIGIO). */
+#define F_SETOWN 6 /* Set owner (receiver of SIGIO). */
+#endif
+#define F_GETLK 7 /* Get record locking info. */
+#define F_SETLK 8 /* Set record locking info (non-blocking). */
+#define F_SETLKW 9 /* Set record locking info (blocking). */
+
+/* File descriptor flags used with F_GETFD and F_SETFD. */
+#define FD_CLOEXEC 1 /* Close on exec. */
+
+
+#include <bits/types.h>
+
+/* The structure describing an advisory lock. This is the type of the third
+ argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+ short int l_pid; /* Process holding the lock. */
+ };
+
+/* Values for the `l_type' field of a `struct flock'. */
+#define F_RDLCK 1 /* Read lock. */
+#define F_WRLCK 2 /* Write lock. */
+#define F_UNLCK 3 /* Remove lock. */
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/bits/ioctls.h b/libc/sysdeps/unix/bsd/bsd4.4/bits/ioctls.h
new file mode 100644
index 000000000..526bfd090
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/bits/ioctls.h
@@ -0,0 +1,288 @@
+/*-
+ * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)ioctl.h 7.19 (Berkeley) 6/26/91
+ */
+
+#ifndef _IOCTLS_H_
+#define _IOCTLS_H_
+
+#define TIOCGSIZE TIOCGWINSZ
+#define TIOCSSIZE TIOCSWINSZ
+
+/*
+ * Ioctl's have the command encoded in the lower word, and the size of
+ * any in or out parameters in the upper word. The high 3 bits of the
+ * upper word are used to encode the in/out status of the parameter.
+ */
+#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */
+#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
+#define IOCBASECMD(x) ((x) & ~IOCPARM_MASK)
+#define IOCGROUP(x) (((x) >> 8) & 0xff)
+
+#define IOCPARM_MAX NBPG /* max size of ioctl, mult. of NBPG */
+#define IOC_VOID 0x20000000 /* no parameters */
+#define IOC_OUT 0x40000000 /* copy out parameters */
+#define IOC_IN 0x80000000 /* copy in parameters */
+#define IOC_INOUT (IOC_IN|IOC_OUT)
+#define IOC_DIRMASK 0xe0000000 /* mask for IN/OUT/VOID */
+
+#define _IOC(inout,group,num,len) \
+ (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num))
+#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0)
+#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t))
+#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t))
+/* this should be _IORW, but stdio got there first */
+#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t))
+
+#define TIOCMODG _IOR('t', 3, int) /* get modem control state */
+#define TIOCMODS _IOW('t', 4, int) /* set modem control state */
+#define TIOCM_LE 0001 /* line enable */
+#define TIOCM_DTR 0002 /* data terminal ready */
+#define TIOCM_RTS 0004 /* request to send */
+#define TIOCM_ST 0010 /* secondary transmit */
+#define TIOCM_SR 0020 /* secondary receive */
+#define TIOCM_CTS 0040 /* clear to send */
+#define TIOCM_CAR 0100 /* carrier detect */
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RNG 0200 /* ring */
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_DSR 0400 /* data set ready */
+ /* 8-10 compat */
+#define TIOCEXCL _IO('t', 13) /* set exclusive use of tty */
+#define TIOCNXCL _IO('t', 14) /* reset exclusive use of tty */
+ /* 15 unused */
+#define TIOCFLUSH _IOW('t', 16, int) /* flush buffers */
+ /* 17-18 compat */
+#define TIOCGETA _IOR('t', 19, struct termios) /* get termios struct */
+#define TIOCSETA _IOW('t', 20, struct termios) /* set termios struct */
+#define TIOCSETAW _IOW('t', 21, struct termios) /* drain output, set */
+#define TIOCSETAF _IOW('t', 22, struct termios) /* drn out, fls in, set */
+#define TIOCGETD _IOR('t', 26, int) /* get line discipline */
+#define TIOCSETD _IOW('t', 27, int) /* set line discipline */
+ /* 127-124 compat */
+#define TIOCSBRK _IO('t', 123) /* set break bit */
+#define TIOCCBRK _IO('t', 122) /* clear break bit */
+#define TIOCSDTR _IO('t', 121) /* set data terminal ready */
+#define TIOCCDTR _IO('t', 120) /* clear data terminal ready */
+#define TIOCGPGRP _IOR('t', 119, int) /* get pgrp of tty */
+#define TIOCSPGRP _IOW('t', 118, int) /* set pgrp of tty */
+ /* 117-116 compat */
+#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
+#define TIOCSTI _IOW('t', 114, char) /* simulate terminal input */
+#define TIOCNOTTY _IO('t', 113) /* void tty association */
+#define TIOCPKT _IOW('t', 112, int) /* pty: set/clear packet mode */
+#define TIOCPKT_DATA 0x00 /* data packet */
+#define TIOCPKT_FLUSHREAD 0x01 /* flush packet */
+#define TIOCPKT_FLUSHWRITE 0x02 /* flush packet */
+#define TIOCPKT_STOP 0x04 /* stop output */
+#define TIOCPKT_START 0x08 /* start output */
+#define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */
+#define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */
+#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */
+#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
+#define TIOCSTART _IO('t', 110) /* start output, like ^Q */
+#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */
+#define TIOCMBIS _IOW('t', 108, int) /* bis modem bits */
+#define TIOCMBIC _IOW('t', 107, int) /* bic modem bits */
+#define TIOCMGET _IOR('t', 106, int) /* get all modem bits */
+#define TIOCREMOTE _IOW('t', 105, int) /* remote input editing */
+#define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */
+#define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */
+#define TIOCUCNTL _IOW('t', 102, int) /* pty: set/clr usr cntl mode */
+#define UIOCCMD(n) _IO('u', n) /* usr cntl op "n" */
+#define TIOCCONS _IOW('t', 98, int) /* become virtual console */
+#define TIOCSCTTY _IO('t', 97) /* become controlling tty */
+#define TIOCEXT _IOW('t', 96, int) /* pty: external processing */
+#define TIOCSIG _IO('t', 95) /* pty: generate signal */
+#define TIOCDRAIN _IO('t', 94) /* wait till output drained */
+
+#define TTYDISC 0 /* termios tty line discipline */
+#define TABLDISC 3 /* tablet discipline */
+#define SLIPDISC 4 /* serial IP discipline */
+
+
+#define FIOCLEX _IO('f', 1) /* set close on exec on fd */
+#define FIONCLEX _IO('f', 2) /* remove close on exec */
+#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */
+#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */
+#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */
+#define FIOSETOWN _IOW('f', 124, int) /* set owner */
+#define FIOGETOWN _IOR('f', 123, int) /* get owner */
+
+/* socket i/o controls */
+#define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */
+#define SIOCGHIWAT _IOR('s', 1, int) /* get high watermark */
+#define SIOCSLOWAT _IOW('s', 2, int) /* set low watermark */
+#define SIOCGLOWAT _IOR('s', 3, int) /* get low watermark */
+#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */
+#define SIOCSPGRP _IOW('s', 8, int) /* set process group */
+#define SIOCGPGRP _IOR('s', 9, int) /* get process group */
+
+#define SIOCADDRT _IOW('r', 10, struct ortentry) /* add route */
+#define SIOCDELRT _IOW('r', 11, struct ortentry) /* delete route */
+
+#define SIOCSIFADDR _IOW('i', 12, struct ifreq) /* set ifnet address */
+#define OSIOCGIFADDR _IOWR('i',13, struct ifreq) /* get ifnet address */
+#define SIOCGIFADDR _IOWR('i',33, struct ifreq) /* get ifnet address */
+#define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) /* set p-p address */
+#define OSIOCGIFDSTADDR _IOWR('i',15, struct ifreq) /* get p-p address */
+#define SIOCGIFDSTADDR _IOWR('i',34, struct ifreq) /* get p-p address */
+#define SIOCSIFFLAGS _IOW('i', 16, struct ifreq) /* set ifnet flags */
+#define SIOCGIFFLAGS _IOWR('i',17, struct ifreq) /* get ifnet flags */
+#define OSIOCGIFBRDADDR _IOWR('i',18, struct ifreq) /* get broadcast addr */
+#define SIOCGIFBRDADDR _IOWR('i',35, struct ifreq) /* get broadcast addr */
+#define SIOCSIFBRDADDR _IOW('i',19, struct ifreq) /* set broadcast addr */
+#define OSIOCGIFCONF _IOWR('i',20, struct ifconf) /* get ifnet list */
+#define SIOCGIFCONF _IOWR('i',36, struct ifconf) /* get ifnet list */
+#define OSIOCGIFNETMASK _IOWR('i',21, struct ifreq) /* get net addr mask */
+#define SIOCGIFNETMASK _IOWR('i',37, struct ifreq) /* get net addr mask */
+#define SIOCSIFNETMASK _IOW('i',22, struct ifreq) /* set net addr mask */
+#define SIOCGIFMETRIC _IOWR('i',23, struct ifreq) /* get IF metric */
+#define SIOCSIFMETRIC _IOW('i',24, struct ifreq) /* set IF metric */
+#define SIOCDIFADDR _IOW('i',25, struct ifreq) /* delete IF addr */
+#define SIOCAIFADDR _IOW('i',26, struct ifaliasreq) /* add/chg IF alias */
+
+#define SIOCSARP _IOW('i', 30, struct arpreq) /* set arp entry */
+#define OSIOCGARP _IOWR('i',31, struct arpreq) /* get arp entry */
+#define SIOCGARP _IOWR('i',38, struct arpreq) /* get arp entry */
+#define SIOCDARP _IOW('i', 32, struct arpreq) /* delete arp entry */
+
+
+/* Compatibility with 4.3 BSD terminal driver.
+ From 4.4 <sys/ioctl_compat.h>. */
+
+#ifdef USE_OLD_TTY
+# undef TIOCGETD
+# define TIOCGETD _IOR('t', 0, int) /* get line discipline */
+# undef TIOCSETD
+# define TIOCSETD _IOW('t', 1, int) /* set line discipline */
+#else
+# define OTIOCGETD _IOR('t', 0, int) /* get line discipline */
+# define OTIOCSETD _IOW('t', 1, int) /* set line discipline */
+#endif
+#define TIOCHPCL _IO('t', 2) /* hang up on last close */
+#define TIOCGETP _IOR('t', 8,struct sgttyb)/* get parameters -- gtty */
+#define TIOCSETP _IOW('t', 9,struct sgttyb)/* set parameters -- stty */
+#define TIOCSETN _IOW('t',10,struct sgttyb)/* as above, but no flushtty*/
+#define TIOCSETC _IOW('t',17,struct tchars)/* set special characters */
+#define TIOCGETC _IOR('t',18,struct tchars)/* get special characters */
+#define TANDEM 0x00000001 /* send stopc on out q full */
+#define CBREAK 0x00000002 /* half-cooked mode */
+#define LCASE 0x00000004 /* simulate lower case */
+#define ECHO 0x00000008 /* echo input */
+#define CRMOD 0x00000010 /* map \r to \r\n on output */
+#define RAW 0x00000020 /* no i/o processing */
+#define ODDP 0x00000040 /* get/send odd parity */
+#define EVENP 0x00000080 /* get/send even parity */
+#define ANYP 0x000000c0 /* get any parity/send none */
+#define NLDELAY 0x00000300 /* \n delay */
+#define NL0 0x00000000
+#define NL1 0x00000100 /* tty 37 */
+#define NL2 0x00000200 /* vt05 */
+#define NL3 0x00000300
+#define TBDELAY 0x00000c00 /* horizontal tab delay */
+#define TAB0 0x00000000
+#define TAB1 0x00000400 /* tty 37 */
+#define TAB2 0x00000800
+#define XTABS 0x00000c00 /* expand tabs on output */
+#define CRDELAY 0x00003000 /* \r delay */
+#define CR0 0x00000000
+#define CR1 0x00001000 /* tn 300 */
+#define CR2 0x00002000 /* tty 37 */
+#define CR3 0x00003000 /* concept 100 */
+#define VTDELAY 0x00004000 /* vertical tab delay */
+#define FF0 0x00000000
+#define FF1 0x00004000 /* tty 37 */
+#define BSDELAY 0x00008000 /* \b delay */
+#define BS0 0x00000000
+#define BS1 0x00008000
+#define ALLDELAY (NLDELAY|TBDELAY|CRDELAY|VTDELAY|BSDELAY)
+#define CRTBS 0x00010000 /* do backspacing for crt */
+#define PRTERA 0x00020000 /* \ ... / erase */
+#define CRTERA 0x00040000 /* " \b " to wipe out char */
+#define TILDE 0x00080000 /* hazeltine tilde kludge */
+#define MDMBUF 0x00100000 /*start/stop output on carrier*/
+#define LITOUT 0x00200000 /* literal output */
+#define TOSTOP 0x00400000 /*SIGSTOP on background output*/
+#define FLUSHO 0x00800000 /* flush output to terminal */
+#define NOHANG 0x01000000 /* (no-op) was no SIGHUP on carrier drop */
+#define L001000 0x02000000
+#define CRTKIL 0x04000000 /* kill line with " \b " */
+#define PASS8 0x08000000
+#define CTLECH 0x10000000 /* echo control chars as ^X */
+#define PENDIN 0x20000000 /* tp->t_rawq needs reread */
+#define DECCTQ 0x40000000 /* only ^Q starts after ^S */
+#define NOFLSH 0x80000000 /* no output flush on signal */
+#define TIOCLBIS _IOW('t', 127, int) /* bis local mode bits */
+#define TIOCLBIC _IOW('t', 126, int) /* bic local mode bits */
+#define TIOCLSET _IOW('t', 125, int) /* set entire local mode word */
+#define TIOCLGET _IOR('t', 124, int) /* get local modes */
+#define LCRTBS (CRTBS>>16)
+#define LPRTERA (PRTERA>>16)
+#define LCRTERA (CRTERA>>16)
+#define LTILDE (TILDE>>16)
+#define LMDMBUF (MDMBUF>>16)
+#define LLITOUT (LITOUT>>16)
+#define LTOSTOP (TOSTOP>>16)
+#define LFLUSHO (FLUSHO>>16)
+#define LNOHANG (NOHANG>>16)
+#define LCRTKIL (CRTKIL>>16)
+#define LPASS8 (PASS8>>16)
+#define LCTLECH (CTLECH>>16)
+#define LPENDIN (PENDIN>>16)
+#define LDECCTQ (DECCTQ>>16)
+#define LNOFLSH (NOFLSH>>16)
+#define TIOCSLTC _IOW('t',117,struct ltchars)/* set local special chars*/
+#define TIOCGLTC _IOR('t',116,struct ltchars)/* get local special chars*/
+#define OTIOCCONS _IO('t', 98) /* for hp300 -- sans int arg */
+#define OTTYDISC 0
+#define NETLDISC 1
+#define NTTYDISC 2
+
+/* From 4.4 <sys/ttydev.h>. */
+#ifdef USE_OLD_TTY
+#define B0 0
+#define B50 1
+#define B75 2
+#define B110 3
+#define B134 4
+#define B150 5
+#define B200 6
+#define B300 7
+#define B600 8
+#define B1200 9
+#define B1800 10
+#define B2400 11
+#define B4800 12
+#define B9600 13
+#define EXTA 14
+#define EXTB 15
+#endif /* USE_OLD_TTY */
+
+#endif /* !_IOCTLS_H_ */
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/bits/sockaddr.h b/libc/sysdeps/unix/bsd/bsd4.4/bits/sockaddr.h
new file mode 100644
index 000000000..934548875
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/bits/sockaddr.h
@@ -0,0 +1,43 @@
+/* Definition of `struct sockaddr_*' common members. 4.4 BSD version.
+ Copyright (C) 1995, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * Never include this file directly; use <sys/socket.h> instead.
+ */
+
+#ifndef _BITS_SOCKADDR_H
+#define _BITS_SOCKADDR_H 1
+
+
+/* POSIX.1g specifies this type name for the `sa_family' member. */
+typedef unsigned char sa_family_t;
+
+/* This macro is used to declare the initial common members
+ of the data types used for socket addresses, `struct sockaddr',
+ `struct sockaddr_in', `struct sockaddr_un', etc. */
+
+#define __SOCKADDR_COMMON(sa_prefix) \
+ unsigned char sa_prefix##len; \
+ sa_family_t sa_prefix##family
+
+#define __SOCKADDR_COMMON_SIZE (2 * sizeof (unsigned char))
+
+#define _HAVE_SA_LEN 1 /* We have the sa_len field. */
+
+#endif /* bits/sockaddr.h */
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/bits/socket.h b/libc/sysdeps/unix/bsd/bsd4.4/bits/socket.h
new file mode 100644
index 000000000..b2227f10d
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/bits/socket.h
@@ -0,0 +1,341 @@
+/* System-specific socket constants and types. 4.4 BSD version.
+ Copyright (C) 1991,92,1994-2002,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef __BITS_SOCKET_H
+#define __BITS_SOCKET_H 1
+
+#if !defined _SYS_SOCKET_H && !defined _NETINET_IN_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+#define __need_size_t
+#define __need_NULL
+#include <stddef.h>
+
+#include <limits.h> /* XXX Is this allowed? */
+#include <bits/types.h>
+
+/* Type for length arguments in socket calls. */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+
+/* Types of sockets. */
+enum __socket_type
+{
+ SOCK_STREAM = 1, /* Sequenced, reliable, connection-based
+ byte streams. */
+#define SOCK_STREAM SOCK_STREAM
+ SOCK_DGRAM = 2, /* Connectionless, unreliable datagrams
+ of fixed maximum length. */
+#define SOCK_DGRAM SOCK_DGRAM
+ SOCK_RAW = 3, /* Raw protocol interface. */
+#define SOCK_RAW SOCK_RAW
+ SOCK_RDM = 4, /* Reliably-delivered messages. */
+#define SOCK_RDM SOCK_RDM
+ SOCK_SEQPACKET = 5 /* Sequenced, reliable, connection-based,
+ datagrams of fixed maximum length. */
+#define SOCK_SEQPACKET SOCK_SEQPACKET
+};
+
+/* Protocol families. */
+#define PF_UNSPEC 0 /* Unspecified. */
+#define PF_LOCAL 1 /* Local to host (pipes and file-domain). */
+#define PF_UNIX PF_LOCAL /* Old BSD name for PF_LOCAL. */
+#define PF_FILE PF_LOCAL /* POSIX name for PF_LOCAL. */
+#define PF_INET 2 /* IP protocol family. */
+#define PF_IMPLINK 3 /* ARPAnet IMP protocol. */
+#define PF_PUP 4 /* PUP protocols. */
+#define PF_CHAOS 5 /* MIT Chaos protocols. */
+#define PF_NS 6 /* Xerox NS protocols. */
+#define PF_ISO 7 /* ISO protocols. */
+#define PF_OSI PF_ISO
+#define PF_ECMA 8 /* ECMA protocols. */
+#define PF_DATAKIT 9 /* AT&T Datakit protocols. */
+#define PF_CCITT 10 /* CCITT protocols (X.25 et al). */
+#define PF_SNA 11 /* IBM SNA protocol. */
+#define PF_DECnet 12 /* DECnet protocols. */
+#define PF_DLI 13 /* Direct data link interface. */
+#define PF_LAT 14 /* DEC Local Area Transport protocol. */
+#define PF_HYLINK 15 /* NSC Hyperchannel protocol. */
+#define PF_APPLETALK 16 /* Don't use this. */
+#define PF_ROUTE 17 /* Internal Routing Protocol. */
+#define PF_LINK 18 /* Link layer interface. */
+#define PF_XTP 19 /* eXpress Transfer Protocol (no AF). */
+#define PF_COIP 20 /* Connection-oriented IP, aka ST II. */
+#define PF_CNT 21 /* Computer Network Technology. */
+#define PF_RTIP 22 /* Help Identify RTIP packets. **/
+#define PF_IPX 23 /* Novell Internet Protocol. */
+#define PF_SIP 24 /* Simple Internet Protocol. */
+#define PF_PIP 25 /* Help Identify PIP packets. */
+#define PF_INET6 26 /* IP version 6. */
+#define PF_MAX 27
+
+/* Address families. */
+#define AF_UNSPEC PF_UNSPEC
+#define AF_LOCAL PF_LOCAL
+#define AF_UNIX PF_UNIX
+#define AF_FILE PF_FILE
+#define AF_INET PF_INET
+#define AF_IMPLINK PF_IMPLINK
+#define AF_PUP PF_PUP
+#define AF_CHAOS PF_CHAOS
+#define AF_NS PF_NS
+#define AF_ISO PF_ISO
+#define AF_OSI PF_OSI
+#define AF_ECMA PF_ECMA
+#define AF_DATAKIT PF_DATAKIT
+#define AF_CCITT PF_CCITT
+#define AF_SNA PF_SNA
+#define AF_DECnet PF_DECnet
+#define AF_DLI PF_DLI
+#define AF_LAT PF_LAT
+#define AF_HYLINK PF_HYLINK
+#define AF_APPLETALK PF_APPLETALK
+#define AF_ROUTE PF_ROUTE
+#define AF_LINK PF_LINK
+#define pseudo_AF_XTP PF_XTP
+#define AF_COIP PF_COIP
+#define AF_CNT PF_CNT
+#define pseudo_AF_RTIP PF_RTIP
+#define AF_IPX PF_IPX
+#define AF_SIP PF_SIP
+#define pseudo_AF_PIP PF_PIP
+#define AF_INET6 PF_INET6
+#define AF_MAX PF_MAX
+
+/* Maximum queue length specifiable by listen. */
+#define SOMAXCONN 128 /* 5 on the origional 4.4 BSD. */
+
+/* Get the definition of the macro to define the common sockaddr members. */
+#include <bits/sockaddr.h>
+
+/* Structure describing a generic socket address. */
+struct sockaddr
+ {
+ __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
+ char sa_data[14]; /* Address data. */
+ };
+
+
+/* Structure large enough to hold any socket address (with the historical
+ exception of AF_UNIX). We reserve 128 bytes. */
+#if ULONG_MAX > 0xffffffff
+# define __ss_aligntype __uint64_t
+#else
+# define __ss_aligntype __uint32_t
+#endif
+#define _SS_SIZE 128
+#define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype)))
+
+struct sockaddr_storage
+ {
+ __SOCKADDR_COMMON (ss_); /* Address family, etc. */
+ __ss_aligntype __ss_align; /* Force desired alignment. */
+ char __ss_padding[_SS_PADSIZE];
+ };
+
+
+/* Bits in the FLAGS argument to `send', `recv', et al. */
+enum
+ {
+ MSG_OOB = 0x01, /* Process out-of-band data. */
+#define MSG_OOB MSG_OOB
+ MSG_PEEK = 0x02, /* Peek at incoming messages. */
+#define MSG_PEEK MSG_PEEK
+ MSG_DONTROUTE = 0x04, /* Don't use local routing. */
+#define MSG_DONTROUTE MSG_DONTROUTE
+ MSG_EOR = 0x08, /* Data completes record. */
+#define MSG_EOR MSG_EOR
+ MSG_TRUNC = 0x10, /* Data discarded before delivery. */
+#define MSG_TRUNC MSG_TRUNC
+ MSG_CTRUNC = 0x20, /* Control data lost before delivery. */
+#define MSG_CTRUNC MSG_CTRUNC
+ MSG_WAITALL = 0x40, /* Wait for full request or error. */
+#define MSG_WAITALL MSG_WAITALL
+ MSG_DONTWAIT = 0x80 /* This message should be nonblocking. */
+#define MSG_DONTWAIT MSG_DONTWAIT
+ };
+
+
+/* Structure describing messages sent by
+ `sendmsg' and received by `recvmsg'. */
+struct msghdr
+ {
+ void *msg_name; /* Address to send to/receive from. */
+ socklen_t msg_namelen; /* Length of address data. */
+
+ struct iovec *msg_iov; /* Vector of data to send/receive into. */
+ int msg_iovlen; /* Number of elements in the vector. */
+
+ void *msg_control; /* Ancillary data (eg BSD filedesc passing). */
+ socklen_t msg_controllen; /* Ancillary data buffer length. */
+
+ int msg_flags; /* Flags in received message. */
+ };
+
+/* Structure used for storage of ancillary data object information. */
+struct cmsghdr
+ {
+ socklen_t cmsg_len; /* Length of data in cmsg_data plus length
+ of cmsghdr structure. */
+ int cmsg_level; /* Originating protocol. */
+ int cmsg_type; /* Protocol specific type. */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+ __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data. */
+#endif
+ };
+
+/* Ancillary data object manipulation macros. */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+# define CMSG_DATA(cmsg) ((cmsg)->__cmsg_data)
+#else
+# define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1))
+#endif
+
+#define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr (mhdr, cmsg)
+
+#define CMSG_FIRSTHDR(mhdr) \
+ ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) \
+ ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) NULL)
+
+#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \
+ & (size_t) ~(sizeof (size_t) - 1))
+#define CMSG_SPACE(len) (CMSG_ALIGN (len) \
+ + CMSG_ALIGN (sizeof (struct cmsghdr)))
+#define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+
+extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
+ struct cmsghdr *__cmsg) __THROW;
+#ifdef __USE_EXTERN_INLINES
+# ifndef _EXTERN_INLINE
+# define _EXTERN_INLINE extern __inline
+# endif
+_EXTERN_INLINE struct cmsghdr *
+__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
+{
+ if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
+ /* The kernel header does this so there may be a reason. */
+ return 0;
+
+ __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ + CMSG_ALIGN (__cmsg->cmsg_len));
+ if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
+ + __mhdr->msg_controllen)
+ || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
+ > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
+ /* No more entries. */
+ return 0;
+ return __cmsg;
+}
+#endif /* Use `extern inline'. */
+
+/* Socket level message types. */
+enum
+ {
+ SCM_RIGHTS = 0x01, /* Access rights (array of int). */
+#define SCM_RIGHTS SCM_RIGHTS
+ SCM_TIMESTAMP = 0x02, /* Timestamp (struct timeval). */
+#define SCM_TIMESTAMP SCM_TIMESTAMP
+ SCM_CREDS = 0x03 /* Process creds (struct cmsgcred). */
+#define SCM_CREDS SCM_CREDS
+ };
+
+/* Unfortunately, BSD practice dictates this structure be of fixed size.
+ If there are more than CMGROUP_MAX groups, the list is truncated.
+ (On GNU systems, the `cmcred_euid' field is just the first in the
+ list of effective UIDs.) */
+#define CMGROUP_MAX 16
+
+/* Structure delivered by SCM_CREDS. This describes the identity of the
+ sender of the data simultaneously received on the socket. By BSD
+ convention, this is included only when a sender on a AF_LOCAL socket
+ sends cmsg data of this type and size; the sender's structure is
+ ignored, and the system fills in the various IDs of the sender process. */
+struct cmsgcred
+ {
+ __pid_t cmcred_pid;
+ __uid_t cmcred_uid;
+ __uid_t cmcred_euid;
+ __gid_t cmcred_gid;
+ int cmcred_ngroups;
+ __gid_t cmcred_groups[CMGROUP_MAX];
+ };
+
+/* Protocol number used to manipulate socket-level options
+ with `getsockopt' and `setsockopt'. */
+#define SOL_SOCKET 0xffff
+
+/* Socket-level options for `getsockopt' and `setsockopt'. */
+enum
+ {
+ SO_DEBUG = 0x0001, /* Record debugging information. */
+#define SO_DEBUG SO_DEBUG
+ SO_ACCEPTCONN = 0x0002, /* Accept connections on socket. */
+#define SO_ACCEPTCONN SO_ACCEPTCONN
+ SO_REUSEADDR = 0x0004, /* Allow reuse of local addresses. */
+#define SO_REUSEADDR SO_REUSEADDR
+ SO_KEEPALIVE = 0x0008, /* Keep connections alive and send
+ SIGPIPE when they die. */
+#define SO_KEEPALIVE SO_KEEPALIVE
+ SO_DONTROUTE = 0x0010, /* Don't do local routing. */
+#define SO_DONTROUTE SO_DONTROUTE
+ SO_BROADCAST = 0x0020, /* Allow transmission of
+ broadcast messages. */
+#define SO_BROADCAST SO_BROADCAST
+ SO_USELOOPBACK = 0x0040, /* Use the software loopback to avoid
+ hardware use when possible. */
+#define SO_USELOOPBACK SO_USELOOPBACK
+ SO_LINGER = 0x0080, /* Block on close of a reliable
+ socket to transmit pending data. */
+#define SO_LINGER SO_LINGER
+ SO_OOBINLINE = 0x0100, /* Receive out-of-band data in-band. */
+#define SO_OOBINLINE SO_OOBINLINE
+ SO_REUSEPORT = 0x0200, /* Allow local address and port reuse. */
+#define SO_REUSEPORT SO_REUSEPORT
+ SO_SNDBUF = 0x1001, /* Send buffer size. */
+#define SO_SNDBUF SO_SNDBUF
+ SO_RCVBUF = 0x1002, /* Receive buffer. */
+#define SO_RCVBUF SO_RCVBUF
+ SO_SNDLOWAT = 0x1003, /* Send low-water mark. */
+#define SO_SNDLOWAT SO_SNDLOWAT
+ SO_RCVLOWAT = 0x1004, /* Receive low-water mark. */
+#define SO_RCVLOWAT SO_RCVLOWAT
+ SO_SNDTIMEO = 0x1005, /* Send timeout. */
+#define SO_SNDTIMEO SO_SNDTIMEO
+ SO_RCVTIMEO = 0x1006, /* Receive timeout. */
+#define SO_RCVTIMEO SO_RCVTIMEO
+ SO_ERROR = 0x1007, /* Get and clear error status. */
+#define SO_ERROR SO_ERROR
+ SO_STYLE = 0x1008, /* Get socket connection style. */
+#define SO_STYLE SO_STYLE
+ SO_TYPE = SO_STYLE /* Compatible name for SO_STYLE. */
+#define SO_TYPE SO_TYPE
+ };
+
+/* Structure used to manipulate the SO_LINGER option. */
+struct linger
+ {
+ int l_onoff; /* Nonzero to linger on close. */
+ int l_linger; /* Time to linger. */
+ };
+
+#endif /* bits/socket.h */
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/cmsg_nxthdr.c b/libc/sysdeps/unix/bsd/bsd4.4/cmsg_nxthdr.c
new file mode 100644
index 000000000..1a542fa01
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/cmsg_nxthdr.c
@@ -0,0 +1,2 @@
+/* The Linux version is perfectly usable on 4.4 BSD. */
+#include <sysdeps/unix/sysv/linux/cmsg_nxthdr.c>
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/environments.h b/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/environments.h
new file mode 100644
index 000000000..92112b554
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/environments.h
@@ -0,0 +1,72 @@
+/* Copyright (C) 1999, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _UNISTD_H
+# error "Never include this file directly. Use <unistd.h> instead"
+#endif
+
+#include <bits/wordsize.h>
+
+/* This header should define the following symbols under the described
+ situations. A value `1' means that the model is always supported,
+ `-1' means it is never supported. Undefined means it cannot be
+ statically decided.
+
+ _POSIX_V6_ILP32_OFF32 32bit int, long, pointers, and off_t type
+ _POSIX_V6_ILP32_OFFBIG 32bit int, long, and pointers and larger off_t type
+
+ _POSIX_V6_LP64_OFF32 64bit long and pointers and 32bit off_t type
+ _POSIX_V6_LPBIG_OFFBIG 64bit long and pointers and large off_t type
+
+ The macros _XBS5_ILP32_OFF32, _XBS5_ILP32_OFFBIG, _XBS5_LP64_OFF32, and
+ _XBS5_LPBIG_OFFBIG were used in previous versions of the Unix standard
+ and are available only for compatibility.
+*/
+
+#if __WORDSIZE == 64
+
+/* We can never provide environments with 32-bit wide pointers. */
+# define _POSIX_V6_ILP32_OFF32 -1
+# define _POSIX_V6_ILP32_OFFBIG -1
+# define _XBS5_ILP32_OFF32 -1
+# define _XBS5_ILP32_OFFBIG -1
+/* We also have no use (for now) for an environment with bigger pointers
+ and offsets. */
+# define _POSIX_V6_LPBIG_OFFBIG -1
+# define _XBS5_LPBIG_OFFBIG -1
+
+/* By default we have 64-bit wide `long int', pointers and `off_t'. */
+# define _POSIX_V6_LP64_OFF64 1
+# define _XBS5_LP64_OFF64 1
+
+#else /* __WORDSIZE == 32 */
+
+/* By default we have 32-bit wide `int', `long int', pointers
+ and 64-bit `off_t'. */
+# define _POSIX_V6_ILP32_OFF32 -1
+# define _POSIX_V6_ILP32_OFFBIG 1
+# define _XBS5_ILP32_OFF32 -1
+# define _XBS5_ILP32_OFFBIG 1
+
+/* We can never provide environments with 64-bit wide pointers. */
+# define _POSIX_V6_LP64_OFF64 -1
+# define _POSIX_V6_LPBIG_OFFBIG -1
+# define _XBS5_LP64_OFF64 -1
+# define _XBS5_LPBIG_OFFBIG -1
+
+#endif /* __WORDSIZE == 32 */
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h b/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h
new file mode 100644
index 000000000..c0e267ff6
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/freebsd/bits/typesizes.h
@@ -0,0 +1,66 @@
+/* bits/typesizes.h -- underlying types for *_t. FreeBSD version.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_TYPES_H
+# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef _BITS_TYPESIZES_H
+#define _BITS_TYPESIZES_H 1
+
+/* See <bits/types.h> for the meaning of these macros. This file exists so
+ that <bits/types.h> need not vary across different GNU platforms. */
+
+#define __DEV_T_TYPE __U32_TYPE
+#define __UID_T_TYPE __U32_TYPE
+#define __GID_T_TYPE __U32_TYPE
+#define __INO_T_TYPE __U32_TYPE
+#define __INO64_T_TYPE __UQUAD_TYPE
+#define __MODE_T_TYPE __U16_TYPE
+#define __NLINK_T_TYPE __U16_TYPE
+#define __OFF_T_TYPE __SQUAD_TYPE
+#define __OFF64_T_TYPE __SQUAD_TYPE
+#define __PID_T_TYPE __S32_TYPE
+#define __RLIM_T_TYPE __SQUAD_TYPE
+#define __RLIM64_T_TYPE __SQUAD_TYPE
+#define __BLKCNT_T_TYPE __SLONGWORD_TYPE
+#define __BLKCNT64_T_TYPE __SQUAD_TYPE
+#define __FSBLKCNT_T_TYPE __ULONGWORD_TYPE
+#define __FSBLKCNT64_T_TYPE __UQUAD_TYPE
+#define __FSFILCNT_T_TYPE __ULONGWORD_TYPE
+#define __FSFILCNT64_T_TYPE __UQUAD_TYPE
+#define __ID_T_TYPE __U32_TYPE
+#define __CLOCK_T_TYPE __S32_TYPE
+#define __TIME_T_TYPE __SLONGWORD_TYPE
+#define __USECONDS_T_TYPE __U32_TYPE
+#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
+#define __DADDR_T_TYPE __S32_TYPE
+#define __SWBLK_T_TYPE __S32_TYPE
+#define __KEY_T_TYPE __S32_TYPE
+#define __CLOCKID_T_TYPE __S32_TYPE
+#define __TIMER_T_TYPE __S32_TYPE
+#define __BLKSIZE_T_TYPE __U32_TYPE
+#define __FSID_T_TYPE struct { int __val[2]; }
+#define __SSIZE_T_TYPE __SWORD_TYPE
+
+/* Number of descriptors that can fit in an `fd_set'. */
+#define __FD_SETSIZE 1024
+
+
+#endif /* bits/typesizes.h */
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/freebsd/sys/sysmacros.h b/libc/sysdeps/unix/bsd/bsd4.4/freebsd/sys/sysmacros.h
new file mode 100644
index 000000000..6b5e07e08
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/freebsd/sys/sysmacros.h
@@ -0,0 +1,28 @@
+/* Definitions of macros to access `dev_t' values. FreeBSD version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SYSMACROS_H
+#define _SYS_SYSMACROS_H 1
+
+/* For compatibility we provide alternative names. */
+#define major(dev) ((int)(((unsigned int) (dev) >> 8) & 0xff))
+#define minor(dev) ((int)((dev) & 0xffff00ff))
+#define makedev(major, minor) (((major) << 8) | (minor))
+
+#endif /* sys/sysmacros.h */
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/isatty.c b/libc/sysdeps/unix/bsd/bsd4.4/isatty.c
new file mode 100644
index 000000000..473368c93
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/isatty.c
@@ -0,0 +1,3 @@
+/* In a 4.4-derived world, tcgetattr is just one ioctl. */
+
+#include <sysdeps/posix/isatty.c>
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/sigblock.c b/libc/sysdeps/unix/bsd/bsd4.4/sigblock.c
new file mode 100644
index 000000000..2647327db
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/sigblock.c
@@ -0,0 +1 @@
+#include <sysdeps/posix/sigblock.c>
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/sigsetmask.c b/libc/sysdeps/unix/bsd/bsd4.4/sigsetmask.c
new file mode 100644
index 000000000..47f1e36a7
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/sigsetmask.c
@@ -0,0 +1 @@
+#include <sysdeps/posix/sigsetmask.c>
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/sigvec.c b/libc/sysdeps/unix/bsd/bsd4.4/sigvec.c
new file mode 100644
index 000000000..d03d9bb3d
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/sigvec.c
@@ -0,0 +1 @@
+#include <sysdeps/posix/sigvec.c>
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/syscalls.list b/libc/sysdeps/unix/bsd/bsd4.4/syscalls.list
new file mode 100644
index 000000000..a4d354685
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/syscalls.list
@@ -0,0 +1,8 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+chflags - chflags 2 chflags
+fchflags - fchflags 2 fchflags
+revoke - revoke 1 revoke
+setlogin - setlogin 2 setlogin
+sigaltstack - sigaltstack 2 __sigaltstack sigaltstack
+wait4 - wait4 4 __wait4 wait4
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/system.c b/libc/sysdeps/unix/bsd/bsd4.4/system.c
new file mode 100644
index 000000000..9283f7455
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/system.c
@@ -0,0 +1,2 @@
+/* BSD 4.4 does have `waitpid'. Avoid unix/system.c, which says we don't. */
+#include <sysdeps/posix/system.c>
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/tcdrain.c b/libc/sysdeps/unix/bsd/bsd4.4/tcdrain.c
new file mode 100644
index 000000000..4eb5612f7
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/tcdrain.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1992, 1994, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <sys/ioctl.h>
+
+/* Wait for pending output to be written on FD. */
+int
+__libc_tcdrain (int fd)
+{
+ return __ioctl (fd, TIOCDRAIN);
+}
+weak_alias (__libc_tcdrain, tcdrain)
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/tcgetattr.c b/libc/sysdeps/unix/bsd/bsd4.4/tcgetattr.c
new file mode 100644
index 000000000..ac60752f1
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/tcgetattr.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1991, 1992, 1994, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <termios.h>
+
+/* These are defined both in <bits/termios.h> and in <bits/ioctls.h>.
+ They should have the same values, but perhaps not written the same way. */
+#undef ECHO
+#undef MDMBUF
+#undef TOSTOP
+#undef FLUSHO
+#undef PENDIN
+#undef NOFLSH
+#include <sys/ioctl.h>
+
+/* Put the state of FD into *TERMIOS_P. */
+int
+__tcgetattr (fd, termios_p)
+ int fd;
+ struct termios *termios_p;
+{
+ return __ioctl (fd, TIOCGETA, termios_p);
+}
+
+weak_alias (__tcgetattr, tcgetattr)
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/tcsetattr.c b/libc/sysdeps/unix/bsd/bsd4.4/tcsetattr.c
new file mode 100644
index 000000000..b3142f6a2
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/tcsetattr.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1992, 1994, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <termios.h>
+
+/* These are defined both in <bits/termios.h> and in <bits/ioctls.h>.
+ They should have the same values, but perhaps not written the same way. */
+#undef ECHO
+#undef MDMBUF
+#undef TOSTOP
+#undef FLUSHO
+#undef PENDIN
+#undef NOFLSH
+#include <sys/ioctl.h>
+
+
+/* Set the state of FD to *TERMIOS_P. */
+int
+tcsetattr (fd, optional_actions, termios_p)
+ int fd;
+ int optional_actions;
+ const struct termios *termios_p;
+{
+ struct termios myt;
+
+ if (optional_actions & TCSASOFT)
+ {
+ myt = *termios_p;
+ myt.c_cflag |= CIGNORE;
+ termios_p = &myt;
+ optional_actions &= ~TCSASOFT;
+ }
+
+ switch (optional_actions)
+ {
+ case TCSANOW:
+ return __ioctl (fd, TIOCSETA, termios_p);
+
+ case TCSADRAIN:
+ return __ioctl (fd, TIOCSETAW, termios_p);
+
+ default:
+ return __ioctl (fd, TIOCSETAF, termios_p);
+ }
+}
+libc_hidden_def (tcsetattr)
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/wait.c b/libc/sysdeps/unix/bsd/bsd4.4/wait.c
new file mode 100644
index 000000000..643dd7a39
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/wait.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/wait.h>
+#include <errno.h>
+#include <sys/resource.h>
+#include <stddef.h>
+
+/* Wait for a child to die. When one does, put its status in *STAT_LOC
+ and return its process ID. For errors, return (pid_t) -1. */
+__pid_t
+__libc_wait (__WAIT_STATUS_DEFN stat_loc)
+{
+ return __wait4 (WAIT_ANY, stat_loc, 0, (struct rusage *) NULL);
+}
+
+weak_alias (__libc_wait, __wait)
+weak_alias (__libc_wait, wait)
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/wait3.c b/libc/sysdeps/unix/bsd/bsd4.4/wait3.c
new file mode 100644
index 000000000..540dad6fb
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/wait3.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991, 1992, 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+
+/* Wait for a child to exit. When one does, put its status in *STAT_LOC and
+ return its process ID. For errors return (pid_t) -1. If USAGE is not nil,
+ store information about the child's resource usage (as a `struct rusage')
+ there. If the WUNTRACED bit is set in OPTIONS, return status for stopped
+ children; otherwise don't. */
+pid_t
+__wait3 (stat_loc, options, usage)
+ __WAIT_STATUS stat_loc;
+ int options;
+ struct rusage *usage;
+{
+ return __wait4 (WAIT_ANY, stat_loc, options, usage);
+}
+
+weak_alias (__wait3, wait3)
diff --git a/libc/sysdeps/unix/bsd/bsd4.4/waitpid.c b/libc/sysdeps/unix/bsd/bsd4.4/waitpid.c
new file mode 100644
index 000000000..33b29d2c3
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsd4.4/waitpid.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1991,95,96,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <stddef.h>
+
+/* Wait for a child matching PID to die.
+ If PID is greater than 0, match any process whose process ID is PID.
+ If PID is (pid_t) -1, match any process.
+ If PID is (pid_t) 0, match any process with the
+ same process group as the current process.
+ If PID is less than -1, match any process whose
+ process group is the absolute value of PID.
+ If the WNOHANG bit is set in OPTIONS, and that child
+ is not already dead, return (pid_t) 0. If successful,
+ return PID and store the dead child's status in STAT_LOC.
+ Return (pid_t) -1 for errors. If the WUNTRACED bit is set in OPTIONS,
+ return status for stopped children; otherwise don't. */
+pid_t
+__libc_waitpid (pid_t pid, int *stat_loc, int options)
+{
+ return __wait4 (pid, (union wait *) stat_loc, options, NULL);
+}
+
+weak_alias (__libc_waitpid, __waitpid)
+libc_hidden_weak (__waitpid)
+weak_alias (__libc_waitpid, waitpid)
diff --git a/libc/sysdeps/unix/bsd/bsdstat.h b/libc/sysdeps/unix/bsd/bsdstat.h
new file mode 100644
index 000000000..f1e38c015
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsdstat.h
@@ -0,0 +1,112 @@
+/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+/* This will make it not define major, minor, makedev, and S_IF*. */
+#undef __USE_BSD
+#undef __USE_MISC
+#include <sys/stat.h>
+
+#undef stat
+#undef fstat
+
+#undef S_IRWXU
+#undef S_IRUSR
+#undef S_IWUSR
+#undef S_IXUSR
+#undef S_IRWXG
+#undef S_IRGRP
+#undef S_IWGRP
+#undef S_IXGRP
+#undef S_IRWXO
+#undef S_IROTH
+#undef S_IWOTH
+#undef S_IXOTH
+#undef S_ISBLK
+#undef S_ISCHR
+#undef S_ISDIR
+#undef S_ISFIFO
+#undef S_ISREG
+#undef S_ISUID
+#undef S_ISGID
+#define stat system_stat
+#define fstat system_fstat
+#define KERNEL /* Try to avoid misc decls. */
+#include "/usr/include/sys/stat.h"
+#undef KERNEL
+#undef stat
+#undef fstat
+
+#define member_same(statbufp, sysbufp, member) \
+ (offsetof(struct __stat, member) == offsetof(struct system_stat, member) && \
+ sizeof((statbufp)->member) == sizeof((sysbufp)->member))
+#define need_stat_mapping(statbufp, sysbufp) \
+ (!(member_same(statbufp, sysbufp, st_dev) && \
+ member_same(statbufp, sysbufp, st_ino) && \
+ member_same(statbufp, sysbufp, st_mode) && \
+ member_same(statbufp, sysbufp, st_nlink) && \
+ member_same(statbufp, sysbufp, st_uid) && \
+ member_same(statbufp, sysbufp, st_gid) && \
+ member_same(statbufp, sysbufp, st_rdev) && \
+ member_same(statbufp, sysbufp, st_size) && \
+ member_same(statbufp, sysbufp, st_atime) && \
+ member_same(statbufp, sysbufp, st_mtime) && \
+ member_same(statbufp, sysbufp, st_ctime) && \
+ member_same(statbufp, sysbufp, st_blksize) && \
+ member_same(statbufp, sysbufp, st_blocks)))
+
+/* Map a system `struct stat' to our `struct stat'. */
+#ifdef __GNUC__
+inline
+#endif
+static int
+mapstat (sysbuf, statbuf)
+ const struct system_stat *sysbuf;
+ struct __stat *buf;
+{
+ if (buf == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (!need_stat_mapping(buf, sysbuf))
+ /* Hopefully this will be optimized out. */
+ *buf = *(struct __stat *) sysbuf;
+ else
+ {
+ buf->st_dev = (dev_t) sysbuf->st_dev;
+ buf->st_ino = (ino_t) sysbuf->st_ino;
+ buf->st_mode = (mode_t) sysbuf->st_mode;
+ buf->st_nlink = (nlink_t) sysbuf->st_nlink;
+ buf->st_uid = (uid_t) sysbuf->st_uid;
+ buf->st_gid = (gid_t) sysbuf->st_gid;
+ buf->st_rdev = (dev_t) sysbuf->st_rdev;
+ buf->st_size = (size_t) sysbuf->st_size;
+ buf->st_atime = (time_t) sysbuf->st_atime;
+ buf->st_mtime = (time_t) sysbuf->st_mtime;
+ buf->st_ctime = (time_t) sysbuf->st_ctime;
+ buf->st_blksize = (size_t) sysbuf->st_blksize;
+ buf->st_blocks = (size_t) sysbuf->st_blocks;
+ }
+
+ return 0;
+}
diff --git a/libc/sysdeps/unix/bsd/bsdtty.h b/libc/sysdeps/unix/bsd/bsdtty.h
new file mode 100644
index 000000000..a1da8d5cc
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/bsdtty.h
@@ -0,0 +1,218 @@
+#undef B0
+#undef B50
+#undef B75
+#undef B110
+#undef B134
+#undef B150
+#undef B200
+#undef B300
+#undef B600
+#undef B1200
+#undef B1800
+#undef B2400
+#undef B4800
+#undef B9600
+#undef B19200
+#undef B38400
+#undef EXTA
+#undef EXTB
+#undef ECHO
+#undef TOSTOP
+#undef NOFLSH
+#undef MDMBUF
+#undef FLUSHO
+#undef PENDIN
+#undef CERASE
+#undef CKILL
+#undef CINTR
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CEOF
+#undef CEOT
+#undef CBRK
+#undef CSUSP
+#undef CDSUSP
+#undef CRPRNT
+#undef CFLUSH
+#undef CWERASE
+#undef CLNEXT
+#undef CSTATUS
+#undef CERASE
+#undef CKILL
+#undef CINTR
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CEOF
+#undef CEOT
+#undef CBRK
+#undef CSUSP
+#undef CDSUSP
+#undef CRPRNT
+#undef CFLUSH
+#undef CWERASE
+#undef CLNEXT
+#undef CSTATUS
+#undef CERASE
+#undef CKILL
+#undef CINTR
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CEOF
+#undef CEOT
+#undef CBRK
+#undef CSUSP
+#undef CDSUSP
+#undef CRPRNT
+#undef CFLUSH
+#undef CWERASE
+#undef CLNEXT
+#undef CSTATUS
+#undef CERASE
+#undef CKILL
+#undef CINTR
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CEOF
+#undef CEOT
+#undef CBRK
+#undef CSUSP
+#undef CDSUSP
+#undef CRPRNT
+#undef CFLUSH
+#undef CWERASE
+#undef CLNEXT
+#undef CSTATUS
+#undef CERASE
+#undef CKILL
+#undef CINTR
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CEOF
+#undef CEOT
+#undef CBRK
+#undef CSUSP
+#undef CDSUSP
+#undef CRPRNT
+#undef CFLUSH
+#undef CWERASE
+#undef CLNEXT
+#undef CSTATUS
+#undef CERASE
+#undef CKILL
+#undef CINTR
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CEOF
+#undef CEOT
+#undef CBRK
+#undef CSUSP
+#undef CDSUSP
+#undef CRPRNT
+#undef CFLUSH
+#undef CWERASE
+#undef CLNEXT
+#undef CSTATUS
+#undef CERASE
+#undef CKILL
+#undef CINTR
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CEOF
+#undef CEOT
+#undef CBRK
+#undef CSUSP
+#undef CDSUSP
+#undef CRPRNT
+#undef CFLUSH
+#undef CWERASE
+#undef CLNEXT
+#undef CSTATUS
+#undef CERASE
+#undef CKILL
+#undef CINTR
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CEOF
+#undef CEOT
+#undef CBRK
+#undef CSUSP
+#undef CDSUSP
+#undef CRPRNT
+#undef CFLUSH
+#undef CWERASE
+#undef CLNEXT
+#undef CSTATUS
+#undef CERASE
+#undef CKILL
+#undef CINTR
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CEOF
+#undef CEOT
+#undef CBRK
+#undef CSUSP
+#undef CDSUSP
+#undef CRPRNT
+#undef CFLUSH
+#undef CWERASE
+#undef CLNEXT
+#undef CSTATUS
+#undef CERASE
+#undef CKILL
+#undef CINTR
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CEOF
+#undef CEOT
+#undef CBRK
+#undef CSUSP
+#undef CDSUSP
+#undef CRPRNT
+#undef CFLUSH
+#undef CWERASE
+#undef CLNEXT
+#undef CSTATUS
+#undef CERASE
+#undef CKILL
+#undef CINTR
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CEOF
+#undef CEOT
+#undef CBRK
+#undef CSUSP
+#undef CDSUSP
+#undef CRPRNT
+#undef CFLUSH
+#undef CWERASE
+#undef CLNEXT
+#undef CSTATUS
+#undef CERASE
+#undef CKILL
+#undef CINTR
+#undef CQUIT
+#undef CSTART
+#undef CSTOP
+#undef CEOF
+#undef CEOT
+#undef CBRK
+#undef CSUSP
+#undef CDSUSP
+#undef CRPRNT
+#undef CFLUSH
+#undef CWERASE
+#undef CLNEXT
+#undef CSTATUS
+
+#include <sys/ioctl.h>
diff --git a/libc/sysdeps/unix/bsd/clock.c b/libc/sysdeps/unix/bsd/clock.c
new file mode 100644
index 000000000..4faae57dc
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/clock.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1991, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <time.h>
+
+#ifdef __GNUC__
+__inline
+#endif
+static clock_t
+timeval_to_clock_t (const struct timeval *tv)
+{
+ return (clock_t) ((tv->tv_sec * CLOCKS_PER_SEC) +
+ (tv->tv_usec * CLOCKS_PER_SEC / 1000000));
+}
+
+/* Return the time used by the program so far (user time + system time). */
+clock_t
+clock (void)
+{
+ struct rusage usage;
+
+ if (__getrusage (RUSAGE_SELF, &usage) < 0)
+ return (clock_t) -1;
+
+ return (timeval_to_clock_t (&usage.ru_stime) +
+ timeval_to_clock_t (&usage.ru_utime));
+}
diff --git a/libc/sysdeps/unix/bsd/confstr.h b/libc/sysdeps/unix/bsd/confstr.h
new file mode 100644
index 000000000..befefb652
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/confstr.h
@@ -0,0 +1 @@
+#define CS_PATH "/usr/ucb:/bin:/usr/bin"
diff --git a/libc/sysdeps/unix/bsd/ftime.c b/libc/sysdeps/unix/bsd/ftime.c
new file mode 100644
index 000000000..187c24c1d
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/ftime.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/timeb.h>
+#include <sys/time.h>
+
+int
+ftime (timebuf)
+ struct timeb *timebuf;
+{
+ struct timeval tv;
+ struct timezone tz;
+
+ if (__gettimeofday (&tv, &tz) < 0)
+ return -1;
+
+ timebuf->time = tv.tv_sec;
+ timebuf->millitm = (tv.tv_usec + 500) / 1000;
+ if (timebuf->millitm == 1000)
+ {
+ ++timebuf->time;
+ timebuf->millitm = 0;
+ }
+ timebuf->timezone = tz.tz_minuteswest;
+ timebuf->dstflag = tz.tz_dsttime;
+ return 0;
+}
diff --git a/libc/sysdeps/unix/bsd/getpt.c b/libc/sysdeps/unix/bsd/getpt.c
new file mode 100644
index 000000000..f4a6b17f0
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/getpt.c
@@ -0,0 +1,93 @@
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+
+/* Prefix for master pseudo terminal nodes. */
+#define _PATH_PTY "/dev/pty"
+
+
+/* Letters indicating a series of pseudo terminals. */
+#ifndef PTYNAME1
+#define PTYNAME1 "pqrsPQRS"
+#endif
+const char __libc_ptyname1[] attribute_hidden = PTYNAME1;
+
+/* Letters indicating the position within a series. */
+#ifndef PTYNAME2
+#define PTYNAME2 "0123456789abcdefghijklmnopqrstuv";
+#endif
+const char __libc_ptyname2[] attribute_hidden = PTYNAME2;
+
+
+/* Open a master pseudo terminal and return its file descriptor. */
+int
+__getpt (void)
+{
+ char buf[sizeof (_PATH_PTY) + 2];
+ const char *p, *q;
+ char *s;
+
+ s = __mempcpy (buf, _PATH_PTY, sizeof (_PATH_PTY) - 1);
+ /* s[0] and s[1] will be filled in the loop. */
+ s[2] = '\0';
+
+ for (p = __libc_ptyname1; *p != '\0'; ++p)
+ {
+ s[0] = *p;
+
+ for (q = __libc_ptyname2; *q != '\0'; ++q)
+ {
+ int fd;
+
+ s[1] = *q;
+
+ fd = __open (buf, O_RDWR);
+ if (fd != -1)
+ return fd;
+
+ if (errno == ENOENT)
+ return -1;
+ }
+ }
+
+ __set_errno (ENOENT);
+ return -1;
+}
+
+#undef __getpt
+weak_alias (__getpt, getpt)
+
+#ifndef HAVE_POSIX_OPENPT
+/* We cannot define posix_openpt in general for BSD systems. */
+int
+__posix_openpt (int oflag)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+weak_alias (__posix_openpt, posix_openpt)
+
+stub_warning (posix_openpt)
+# include <stub-tag.h>
+#endif
diff --git a/libc/sysdeps/unix/bsd/gtty.c b/libc/sysdeps/unix/bsd/gtty.c
new file mode 100644
index 000000000..081ce25ae
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/gtty.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sgtty.h>
+
+/* Fill in *PARAMS with terminal parameters associated with FD. */
+int
+gtty (fd, params)
+ int fd;
+ struct sgttyb *params;
+{
+ return ioctl (fd, TIOCGETP, (void *) params);
+}
diff --git a/libc/sysdeps/unix/bsd/i386/vfork.S b/libc/sysdeps/unix/bsd/i386/vfork.S
new file mode 100644
index 000000000..a245f3e14
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/i386/vfork.S
@@ -0,0 +1,40 @@
+/* Copyright (C) 1993, 1994, 1995, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* Since vfork shares the address space between the parent and child,
+ we must take care to avoid the child unwinding the stack frame and
+ clobbering it for the parent. */
+
+.text
+ENTRY (__vfork)
+ popl scratch /* Save the return PC in a register. */
+ DO_CALL (vfork, 0) /* Do the system call. */
+ pushl scratch /* Put the return PC back on the stack. */
+ jb syscall_error /* Branch if error. */
+ /* R1 is now 0 for the parent and 1 for the child. Decrement it to
+ make it -1 (all bits set) for the parent, and 0 (no bits set)
+ for the child. Then AND it with R0, so the parent gets
+ R0&-1==R0, and the child gets R0&0==0. */
+ decl r1
+ andl r1, r0
+ ret
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libc/sysdeps/unix/bsd/i386/wait3.S b/libc/sysdeps/unix/bsd/i386/wait3.S
new file mode 100644
index 000000000..5988340cc
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/i386/wait3.S
@@ -0,0 +1,44 @@
+/* Copyright (C) 1991, 1992, 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* <sysdeps/unix/bsd/sequent/i386/sysdep.h> defines this to put the first
+ two arguments into registers. Since the arguments to wait3 are
+ transferred magically through the same registers, we want to disable this.
+ This allows us to avoid rewriting this file for that system. */
+
+#undef ARGS_2
+#define ARGS_2 /* Special-case no-op. */
+
+.text
+.globl syscall_error
+.align 4
+ENTRY (__wait3)
+ mov 8(%esp), %ecx /* Flags. */
+ mov 12(%esp), %edx /* rusage pointer. */
+ pushl $0xdf; popf /* Set all the condition codes. */
+ DO_CALL (wait, 2) /* Do the system call. */
+ je syscall_error /* Check for error. */
+ mov 4(%esp), scratch /* Status pointer. */
+ orl scratch, scratch /* Is it nil? */
+ je done /* Yup; return. */
+ mov r1, 0(scratch) /* Non-nil; store the status in it. */
+done: ret
+
+weak_alias (__wait3, wait3)
diff --git a/libc/sysdeps/unix/bsd/init-posix.c b/libc/sysdeps/unix/bsd/init-posix.c
new file mode 100644
index 000000000..b5ea8846f
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/init-posix.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991, 94, 95, 97, 98, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <time.h>
+
+/* This must be initialized data or its presence will not be sufficient to
+ merit linkage of this file, which is necessary for the real
+ initialization function below to be called. */
+time_t _posix_start_time = -1;
+
+void
+__init_posix (void)
+{
+ _posix_start_time = time ((time_t *) NULL);
+}
+
+text_set_element(__libc_subinit, __init_posix);
diff --git a/libc/sysdeps/unix/bsd/isatty.c b/libc/sysdeps/unix/bsd/isatty.c
new file mode 100644
index 000000000..996c4ed41
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/isatty.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991,95,96,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+/* Return 1 if FD is a terminal, 0 if not. */
+int
+__isatty (fd)
+ int fd;
+{
+ struct sgttyb term;
+
+ return __ioctl (fd, TIOCGETP, &term) == 0;
+}
+weak_alias (__isatty, isatty)
diff --git a/libc/sysdeps/unix/bsd/poll.c b/libc/sysdeps/unix/bsd/poll.c
new file mode 100644
index 000000000..0bddf0b27
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/poll.c
@@ -0,0 +1,199 @@
+/* Copyright (C) 1994,1996,1997,1998,1999,2001,2002
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <alloca.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <unistd.h>
+
+/* Poll the file descriptors described by the NFDS structures starting at
+ FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for
+ an event to occur; if TIMEOUT is -1, block until an event occurs.
+ Returns the number of file descriptors with events, zero if timed out,
+ or -1 for errors. */
+
+int
+__poll (fds, nfds, timeout)
+ struct pollfd *fds;
+ nfds_t nfds;
+ int timeout;
+{
+ static int max_fd_size;
+ struct timeval tv;
+ fd_set *rset, *wset, *xset;
+ struct pollfd *f;
+ int ready;
+ int maxfd = 0;
+ int bytes;
+
+ if (!max_fd_size)
+ max_fd_size = __getdtablesize ();
+
+ bytes = howmany (max_fd_size, __NFDBITS);
+ rset = alloca (bytes);
+ wset = alloca (bytes);
+ xset = alloca (bytes);
+
+ /* We can't call FD_ZERO, since FD_ZERO only works with sets
+ of exactly __FD_SETSIZE size. */
+ __bzero (rset, bytes);
+ __bzero (wset, bytes);
+ __bzero (xset, bytes);
+
+ for (f = fds; f < &fds[nfds]; ++f)
+ {
+ f->revents = 0;
+ if (f->fd >= 0)
+ {
+ if (f->fd >= max_fd_size)
+ {
+ /* The user provides a file descriptor number which is higher
+ than the maximum we got from the `getdtablesize' call.
+ Maybe this is ok so enlarge the arrays. */
+ fd_set *nrset, *nwset, *nxset;
+ int nbytes;
+
+ max_fd_size = roundup (f->fd, __NFDBITS);
+ nbytes = howmany (max_fd_size, __NFDBITS);
+
+ nrset = alloca (nbytes);
+ nwset = alloca (nbytes);
+ nxset = alloca (nbytes);
+
+ __bzero ((char *) nrset + bytes, nbytes - bytes);
+ __bzero ((char *) nwset + bytes, nbytes - bytes);
+ __bzero ((char *) nxset + bytes, nbytes - bytes);
+
+ rset = memcpy (nrset, rset, bytes);
+ wset = memcpy (nwset, wset, bytes);
+ xset = memcpy (nxset, xset, bytes);
+
+ bytes = nbytes;
+ }
+
+ if (f->events & POLLIN)
+ FD_SET (f->fd, rset);
+ if (f->events & POLLOUT)
+ FD_SET (f->fd, wset);
+ if (f->events & POLLPRI)
+ FD_SET (f->fd, xset);
+ if (f->fd > maxfd && (f->events & (POLLIN|POLLOUT|POLLPRI)))
+ maxfd = f->fd;
+ }
+ }
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+
+ while (1)
+ {
+ ready = __select (maxfd + 1, rset, wset, xset,
+ timeout == -1 ? NULL : &tv);
+
+ /* It might be that one or more of the file descriptors is invalid.
+ We now try to find and mark them and then try again. */
+ if (ready == -1 && errno == EBADF)
+ {
+ fd_set *sngl_rset = alloca (bytes);
+ fd_set *sngl_wset = alloca (bytes);
+ fd_set *sngl_xset = alloca (bytes);
+ struct timeval sngl_tv;
+
+ /* Clear the original set. */
+ __bzero (rset, bytes);
+ __bzero (wset, bytes);
+ __bzero (xset, bytes);
+
+ /* This means we don't wait for input. */
+ sngl_tv.tv_sec = 0;
+ sngl_tv.tv_usec = 0;
+
+ maxfd = -1;
+
+ /* Reset the return value. */
+ ready = 0;
+
+ for (f = fds; f < &fds[nfds]; ++f)
+ if (f->fd != -1 && (f->events & (POLLIN|POLLOUT|POLLPRI))
+ && (f->revents & POLLNVAL) == 0)
+ {
+ int n;
+
+ __bzero (sngl_rset, bytes);
+ __bzero (sngl_wset, bytes);
+ __bzero (sngl_xset, bytes);
+
+ if (f->events & POLLIN)
+ FD_SET (f->fd, sngl_rset);
+ if (f->events & POLLOUT)
+ FD_SET (f->fd, sngl_wset);
+ if (f->events & POLLPRI)
+ FD_SET (f->fd, sngl_xset);
+
+ n = __select (f->fd + 1, sngl_rset, sngl_wset, sngl_xset,
+ &sngl_tv);
+ if (n != -1)
+ {
+ /* This descriptor is ok. */
+ if (f->events & POLLIN)
+ FD_SET (f->fd, rset);
+ if (f->events & POLLOUT)
+ FD_SET (f->fd, wset);
+ if (f->events & POLLPRI)
+ FD_SET (f->fd, xset);
+ if (f->fd > maxfd)
+ maxfd = f->fd;
+ if (n > 0)
+ /* Count it as being available. */
+ ++ready;
+ }
+ else if (errno == EBADF)
+ f->revents |= POLLNVAL;
+ }
+ /* Try again. */
+ continue;
+ }
+
+ break;
+ }
+
+ if (ready > 0)
+ for (f = fds; f < &fds[nfds]; ++f)
+ {
+ if (f->fd >= 0)
+ {
+ if (FD_ISSET (f->fd, rset))
+ f->revents |= POLLIN;
+ if (FD_ISSET (f->fd, wset))
+ f->revents |= POLLOUT;
+ if (FD_ISSET (f->fd, xset))
+ f->revents |= POLLPRI;
+ }
+ }
+
+ return ready;
+}
+#ifndef __poll
+libc_hidden_def (__poll)
+weak_alias (__poll, poll)
+#endif
diff --git a/libc/sysdeps/unix/bsd/ptsname.c b/libc/sysdeps/unix/bsd/ptsname.c
new file mode 100644
index 000000000..fd446a4b6
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/ptsname.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 1998,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <paths.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+/* Static buffer for `ptsname'. */
+static char buffer[sizeof (_PATH_TTY) + 2];
+
+
+/* Return the pathname of the pseudo terminal slave assoicated with
+ the master FD is open on, or NULL on errors.
+ The returned storage is good until the next call to this function. */
+char *
+ptsname (int fd)
+{
+ return __ptsname_r (fd, buffer, sizeof (buffer)) != 0 ? NULL : buffer;
+}
+
+
+/* Store at most BUFLEN characters of the pathname of the slave pseudo
+ terminal associated with the master FD is open on in BUF.
+ Return 0 on success, otherwise an error number. */
+int
+__ptsname_r (int fd, char *buf, size_t buflen)
+{
+ int save_errno = errno;
+ struct stat st;
+
+ if (buf == NULL)
+ {
+ __set_errno (EINVAL);
+ return EINVAL;
+ }
+
+ if (!__isatty (fd))
+ /* We rely on isatty to set errno properly (i.e. EBADF or ENOTTY). */
+ return errno;
+
+ if (buflen < strlen (_PATH_TTY) + 3)
+ {
+ __set_errno (ERANGE);
+ return ERANGE;
+ }
+
+ if (__ttyname_r (fd, buf, buflen) != 0)
+ return errno;
+
+ buf[sizeof (_PATH_DEV) - 1] = 't';
+
+ if (__stat (buf, &st) < 0)
+ return errno;
+
+ __set_errno (save_errno);
+ return 0;
+}
+weak_alias (__ptsname_r, ptsname_r)
diff --git a/libc/sysdeps/unix/bsd/seekdir.c b/libc/sysdeps/unix/bsd/seekdir.c
new file mode 100644
index 000000000..4d244f53b
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/seekdir.c
@@ -0,0 +1 @@
+/* Because they share a private data structure, seekdir is in telldir.c. */
diff --git a/libc/sysdeps/unix/bsd/setegid.c b/libc/sysdeps/unix/bsd/setegid.c
new file mode 100644
index 000000000..cc9f939ba
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/setegid.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+int
+setegid (gid)
+ gid_t gid;
+{
+ if (gid == (gid_t) ~0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return __setregid (-1, gid);
+}
+libc_hidden_def (setegid)
diff --git a/libc/sysdeps/unix/bsd/seteuid.c b/libc/sysdeps/unix/bsd/seteuid.c
new file mode 100644
index 000000000..056b6583c
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/seteuid.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+int
+seteuid (uid)
+ uid_t uid;
+{
+ if (uid == (uid_t) ~0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return __setreuid (-1, uid);
+}
+libc_hidden_def (seteuid)
diff --git a/libc/sysdeps/unix/bsd/setgid.c b/libc/sysdeps/unix/bsd/setgid.c
new file mode 100644
index 000000000..3d1fd3196
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/setgid.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+/* Set the group ID of the calling process to GID.
+ If the calling process is the super-user, the real
+ and effective group IDs, and the saved set-group-ID to GID;
+ if not, the effective group ID is set to GID. */
+int
+__setgid (gid)
+ gid_t gid;
+{
+ return __setregid (gid, gid);
+}
+
+weak_alias (__setgid, setgid)
diff --git a/libc/sysdeps/unix/bsd/setrgid.c b/libc/sysdeps/unix/bsd/setrgid.c
new file mode 100644
index 000000000..9083afd13
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/setrgid.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <sys/types.h>
+
+int
+setrgid (gid)
+ gid_t gid;
+{
+ return __setregid (gid, -1);
+}
diff --git a/libc/sysdeps/unix/bsd/setruid.c b/libc/sysdeps/unix/bsd/setruid.c
new file mode 100644
index 000000000..adaff4e48
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/setruid.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <sys/types.h>
+
+int
+setruid (uid)
+ uid_t uid;
+{
+ return __setreuid (uid, -1);
+}
diff --git a/libc/sysdeps/unix/bsd/setsid.c b/libc/sysdeps/unix/bsd/setsid.c
new file mode 100644
index 000000000..b09ad3c5b
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/setsid.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+/* Create a new session with the calling process as its leader.
+ The process group IDs of the session and the calling process
+ are set to the process ID of the calling process, which is returned. */
+int
+__setsid ()
+{
+ pid_t pid = getpid ();
+ int tty;
+ int save = errno;
+
+ if (__getpgid (pid) == pid)
+ {
+ /* Already the leader. */
+ __set_errno (EPERM);
+ return -1;
+ }
+
+ if (setpgid (pid, pid) < 0)
+ return -1;
+
+ tty = open ("/dev/tty", 0);
+ if (tty < 0)
+ {
+ __set_errno (save);
+ return 0;
+ }
+ (void) __ioctl (tty, TIOCNOTTY, 0);
+ (void) __close (tty);
+
+ __set_errno (save);
+ return 0;
+}
+
+weak_alias (__setsid, setsid)
diff --git a/libc/sysdeps/unix/bsd/setuid.c b/libc/sysdeps/unix/bsd/setuid.c
new file mode 100644
index 000000000..5a37f5c85
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/setuid.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+/* Set the user ID of the calling process to UID.
+ If the calling process is the super-user, the real
+ and effective user IDs, and the saved set-user-ID to UID;
+ if not, the effective user ID is set to UID. */
+int
+__setuid (uid)
+ uid_t uid;
+{
+ return __setreuid (uid, uid);
+}
+
+weak_alias (__setuid, setuid)
diff --git a/libc/sysdeps/unix/bsd/sigaction.c b/libc/sysdeps/unix/bsd/sigaction.c
new file mode 100644
index 000000000..ba73400af
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/sigaction.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1991,1995,1996,1997,2002,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <errno.h>
+#include <stddef.h>
+#include <signal.h>
+
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+ If OACT is not NULL, put the old action for SIG in *OACT. */
+int
+__sigaction (sig, act, oact)
+ int sig;
+ const struct sigaction *act;
+ struct sigaction *oact;
+{
+ struct sigvec vec, ovec;
+
+ if (sig <= 0 || sig >= NSIG)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (act != NULL)
+ {
+ vec.sv_mask = act->sa_mask;
+ vec.sv_handler = act->sa_handler;
+ vec.sv_flags = (((act->sa_flags & SA_ONSTACK) ? SV_ONSTACK : 0) |
+ (!(act->sa_flags & SA_RESTART) ? SV_INTERRUPT : 0));
+ }
+
+ if (__sigvec(sig, act != NULL ? &vec : (struct sigvec *) NULL, &ovec) < 0)
+ return -1;
+
+ if (oact != NULL)
+ {
+ oact->sa_handler = (void (*) (int)) ovec.sv_handler;
+ oact->sa_mask = ovec.sv_mask;
+ oact->sa_flags = (((ovec.sv_flags & SV_ONSTACK) ? SA_ONSTACK : 0) |
+ (!(ovec.sv_flags & SV_INTERRUPT) ? SA_RESTART : 0));
+ }
+
+ return 0;
+}
+libc_hidden_def (__sigaction)
+weak_alias (__sigaction, sigaction)
diff --git a/libc/sysdeps/unix/bsd/sigprocmask.c b/libc/sysdeps/unix/bsd/sigprocmask.c
new file mode 100644
index 000000000..5ad137e02
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/sigprocmask.c
@@ -0,0 +1,66 @@
+/* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <signal.h>
+
+
+/* If SET is not NULL, modify the current set of blocked signals
+ according to HOW, which may be SIG_BLOCK, SIG_UNBLOCK or SIG_SETMASK.
+ If OSET is not NULL, store the old set of blocked signals in *OSET. */
+int
+__sigprocmask (how, set, oset)
+ int how;
+ const sigset_t *set;
+ sigset_t *oset;
+{
+ int mask;
+
+ if (set != NULL)
+ {
+ mask = *set;
+ switch (how)
+ {
+ case SIG_BLOCK:
+ mask = __sigblock (mask);
+ break;
+
+ case SIG_UNBLOCK:
+ mask = __sigblock (0) & ~mask;
+ /* Fall through. */
+
+ case SIG_SETMASK:
+ mask = __sigsetmask (mask);
+ break;
+
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+ }
+ else
+ mask = __sigblock (0);
+
+ if (oset != NULL)
+ *oset = mask;
+
+ return 0;
+}
+
+weak_alias (__sigprocmask, sigprocmask)
diff --git a/libc/sysdeps/unix/bsd/sigsuspend.c b/libc/sysdeps/unix/bsd/sigsuspend.c
new file mode 100644
index 000000000..0d62ce218
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/sigsuspend.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1991, 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <stddef.h>
+#include <unistd.h>
+
+
+/* Change the set of blocked signals to SET,
+ wait until a signal arrives, and restore the set of blocked signals. */
+int
+__sigsuspend (set)
+ const sigset_t *set;
+{
+ int mask;
+ int sig;
+
+ if (set == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ mask = 0;
+ for (sig = 1; sig <= NSIG; ++sig)
+ if (__sigismember (set, sig))
+ mask |= sigmask (sig);
+
+ return __sigpause (mask, 0);
+}
+libc_hidden_def (__sigsuspend)
+weak_alias (__sigsuspend, sigsuspend)
diff --git a/libc/sysdeps/unix/bsd/stty.c b/libc/sysdeps/unix/bsd/stty.c
new file mode 100644
index 000000000..a995cd0db
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/stty.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sgtty.h>
+
+/* Set the terminal parameters associated with FD to *PARAMS. */
+int
+stty (fd, params)
+ int fd;
+ const struct sgttyb *params;
+{
+ return ioctl (fd, TIOCSETP, (void *) params);
+}
diff --git a/libc/sysdeps/unix/bsd/sys/reboot.h b/libc/sysdeps/unix/bsd/sys/reboot.h
new file mode 100644
index 000000000..76c2380b2
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/sys/reboot.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ * The Regents of the University of California. 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)reboot.h 8.1 (Berkeley) 6/2/93
+ */
+
+/*
+ * Arguments to reboot system call.
+ * These are passed to boot program in r11,
+ * and on to init.
+ */
+#define RB_AUTOBOOT 0 /* flags for system auto-booting itself */
+
+#define RB_ASKNAME 0x01 /* ask for file name to reboot from */
+#define RB_SINGLE 0x02 /* reboot to single user only */
+#define RB_NOSYNC 0x04 /* don't sync before reboot */
+#define RB_HALT 0x08 /* don't reboot, just halt */
+#define RB_INITNAME 0x10 /* name given for /etc/init (unused) */
+#define RB_DFLTROOT 0x20 /* use compiled-in rootdev */
+#define RB_KDB 0x40 /* give control to kernel debugger */
+#define RB_RDONLY 0x80 /* mount root fs read-only */
+#define RB_DUMP 0x100 /* dump kernel memory before reboot */
+#define RB_MINIROOT 0x200 /* mini-root present in memory at boot time */
+
+/*
+ * Constants for converting boot-style device number to type,
+ * adaptor (uba, mba, etc), unit number and partition number.
+ * Type (== major device number) is in the low byte
+ * for backward compatibility. Except for that of the "magic
+ * number", each mask applies to the shifted value.
+ * Format:
+ * (4) (4) (4) (4) (8) (8)
+ * --------------------------------
+ * |MA | AD| CT| UN| PART | TYPE |
+ * --------------------------------
+ */
+#define B_ADAPTORSHIFT 24
+#define B_ADAPTORMASK 0x0f
+#define B_ADAPTOR(val) (((val) >> B_ADAPTORSHIFT) & B_ADAPTORMASK)
+#define B_CONTROLLERSHIFT 20
+#define B_CONTROLLERMASK 0xf
+#define B_CONTROLLER(val) (((val)>>B_CONTROLLERSHIFT) & B_CONTROLLERMASK)
+#define B_UNITSHIFT 16
+#define B_UNITMASK 0xf
+#define B_UNIT(val) (((val) >> B_UNITSHIFT) & B_UNITMASK)
+#define B_PARTITIONSHIFT 8
+#define B_PARTITIONMASK 0xff
+#define B_PARTITION(val) (((val) >> B_PARTITIONSHIFT) & B_PARTITIONMASK)
+#define B_TYPESHIFT 0
+#define B_TYPEMASK 0xff
+#define B_TYPE(val) (((val) >> B_TYPESHIFT) & B_TYPEMASK)
+
+#define B_MAGICMASK ((u_long)0xf0000000)
+#define B_DEVMAGIC ((u_long)0xa0000000)
+
+#define MAKEBOOTDEV(type, adaptor, controller, unit, partition) \
+ (((type) << B_TYPESHIFT) | ((adaptor) << B_ADAPTORSHIFT) | \
+ ((controller) << B_CONTROLLERSHIFT) | ((unit) << B_UNITSHIFT) | \
+ ((partition) << B_PARTITIONSHIFT) | B_DEVMAGIC)
diff --git a/libc/sysdeps/unix/bsd/syscalls.list b/libc/sysdeps/unix/bsd/syscalls.list
new file mode 100644
index 000000000..e84819dc1
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/syscalls.list
@@ -0,0 +1,14 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+flock - flock 2 __flock flock
+getdents - getdirentries 4 __getdirentries getdirentries
+getdtsz - getdtablesize 0 __getdtablesize getdtablesize
+getpagesize - getpagesize 0 __getpagesize getpagesize
+killpg - killpg 2 killpg
+sigblock - sigblock 1 __sigblock sigblock
+sigpause - sigpause 1 __sigpause sigpause
+sigsetmask - sigsetmask 1 __sigsetmask sigsetmask
+sigstack - sigstack 2 sigstack
+sigvec - sigvec 3 __sigvec sigvec
+wait3 - wait3 3 __wait3 wait3
+waitpid - waitpid 3 __waitpid waitpid
diff --git a/libc/sysdeps/unix/bsd/tcdrain.c b/libc/sysdeps/unix/bsd/tcdrain.c
new file mode 100644
index 000000000..7dd60759e
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/tcdrain.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1991, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "bsdtty.h"
+
+/* Wait for pending output to be written on FD. */
+int
+__libc_tcdrain (int fd)
+{
+ /* The TIOCSETP control waits for pending output to be written before
+ affecting its changes, so we use that without changing anything. */
+ struct sgttyb b;
+ if (__ioctl (fd, TIOCGETP, (void *) &b) < 0 ||
+ __ioctl (fd, TIOCSETP, (void *) &b) < 0)
+ return -1;
+ return 0;
+}
+weak_alias (__libc_tcdrain, tcdrain)
diff --git a/libc/sysdeps/unix/bsd/tcflow.c b/libc/sysdeps/unix/bsd/tcflow.c
new file mode 100644
index 000000000..b3b6f8e11
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/tcflow.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1991, 1992, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "bsdtty.h"
+
+/* Suspend or restart transmission on FD. */
+int
+tcflow (fd, action)
+ int fd;
+ int action;
+{
+ switch (action)
+ {
+ case TCOOFF:
+ return __ioctl (fd, TIOCSTOP, (void *) NULL);
+ case TCOON:
+ return __ioctl (fd, TIOCSTART, (void *) NULL);
+
+ case TCIOFF:
+ case TCION:
+ {
+ /* This just writes the START or STOP character with
+ `write'. Is there another way to do this? */
+ struct termios attr;
+ unsigned char c;
+ if (tcgetattr (fd, &attr) < 0)
+ return -1;
+ c = attr.c_cc[action == TCIOFF ? VSTOP : VSTART];
+ if (c != _POSIX_VDISABLE && write (fd, &c, 1) < 1)
+ return -1;
+ return 0;
+ }
+
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+}
diff --git a/libc/sysdeps/unix/bsd/tcflush.c b/libc/sysdeps/unix/bsd/tcflush.c
new file mode 100644
index 000000000..9b5d3445c
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/tcflush.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1991, 1992, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <termios.h>
+#include <unistd.h>
+#include "bsdtty.h"
+#include <sys/file.h>
+
+/* Flush pending data on FD. */
+int
+tcflush (fd, queue_selector)
+ int fd;
+ int queue_selector;
+{
+ int arg;
+
+ switch (queue_selector)
+ {
+ case TCIFLUSH:
+ arg = FREAD;
+ break;
+ case TCOFLUSH:
+ arg = FWRITE;
+ break;
+ case TCIOFLUSH:
+ arg = FREAD | FWRITE;
+ break;
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return __ioctl (fd, TIOCFLUSH, (void *) &arg);
+}
diff --git a/libc/sysdeps/unix/bsd/tcgetattr.c b/libc/sysdeps/unix/bsd/tcgetattr.c
new file mode 100644
index 000000000..5743ffa4b
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/tcgetattr.c
@@ -0,0 +1,130 @@
+/* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <termios.h>
+
+#include "bsdtty.h"
+
+extern const speed_t __bsd_speeds[]; /* Defined in tcsetattr.c. */
+
+/* Put the state of FD into *TERMIOS_P. */
+int
+__tcgetattr (fd, termios_p)
+ int fd;
+ struct termios *termios_p;
+{
+ struct sgttyb buf;
+ struct tchars tchars;
+ struct ltchars ltchars;
+ int local;
+#ifdef TIOCGETX
+ int extra;
+#endif
+
+ if (termios_p == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (__ioctl(fd, TIOCGETP, &buf) < 0 ||
+ __ioctl(fd, TIOCGETC, &tchars) < 0 ||
+ __ioctl(fd, TIOCGLTC, &ltchars) < 0 ||
+#ifdef TIOCGETX
+ __ioctl(fd, TIOCGETX, &extra) < 0 ||
+#endif
+ __ioctl(fd, TIOCLGET, &local) < 0)
+ return -1;
+
+ termios_p->__ispeed = __bsd_speeds[(unsigned char) buf.sg_ispeed];
+ termios_p->__ospeed = __bsd_speeds[(unsigned char) buf.sg_ospeed];
+
+ termios_p->c_iflag = 0;
+ termios_p->c_oflag = 0;
+ termios_p->c_cflag = 0;
+ termios_p->c_lflag = 0;
+ termios_p->c_oflag |= CREAD | HUPCL;
+#ifdef LPASS8
+ if (local & LPASS8)
+ termios_p->c_oflag |= CS8;
+ else
+#endif
+ termios_p->c_oflag |= CS7;
+ if (!(buf.sg_flags & RAW))
+ {
+ termios_p->c_iflag |= IXON;
+ termios_p->c_cflag |= OPOST;
+#ifndef NOISIG
+ termios_p->c_lflag |= ISIG;
+#endif
+ }
+ if ((buf.sg_flags & (CBREAK|RAW)) == 0)
+ termios_p->c_lflag |= ICANON;
+ if (!(buf.sg_flags & RAW) && !(local & LLITOUT))
+ termios_p->c_oflag |= OPOST;
+ if (buf.sg_flags & CRMOD)
+ termios_p->c_iflag |= ICRNL;
+ if (buf.sg_flags & TANDEM)
+ termios_p->c_iflag |= IXOFF;
+#ifdef TIOCGETX
+ if (!(extra & NOISIG))
+ termios_p->c_lflag |= ISIG;
+ if (extra & STOPB)
+ termios_p->c_cflag |= CSTOPB;
+#endif
+
+ switch (buf.sg_flags & (EVENP|ODDP))
+ {
+ case EVENP|ODDP:
+ break;
+ case ODDP:
+ termios_p->c_cflag |= PARODD;
+ default:
+ termios_p->c_cflag |= PARENB;
+ termios_p->c_iflag |= IGNPAR | INPCK;
+ break;
+ }
+ if (buf.sg_flags & ECHO)
+ termios_p->c_lflag |= _ECHO;
+ if (local & LCRTERA)
+ termios_p->c_lflag |= ECHOE;
+ if (local & LCRTKIL)
+ termios_p->c_lflag |= ECHOK;
+ if (local & LTOSTOP)
+ termios_p->c_lflag |= _TOSTOP;
+ if (local & LNOFLSH)
+ termios_p->c_lflag |= _NOFLSH;
+
+ termios_p->c_cc[VEOF] = tchars.t_eofc;
+ termios_p->c_cc[VEOL] = '\n';
+ termios_p->c_cc[VERASE] = buf.sg_erase;
+ termios_p->c_cc[VKILL] = buf.sg_kill;
+ termios_p->c_cc[VINTR] = tchars.t_intrc;
+ termios_p->c_cc[VQUIT] = tchars.t_quitc;
+ termios_p->c_cc[VSTART] = tchars.t_startc;
+ termios_p->c_cc[VSTOP] = tchars.t_stopc;
+ termios_p->c_cc[VSUSP] = ltchars.t_suspc;
+ termios_p->c_cc[VMIN] = -1;
+ termios_p->c_cc[VTIME] = -1;
+
+ return 0;
+}
+
+weak_alias (__tcgetattr, tcgetattr)
diff --git a/libc/sysdeps/unix/bsd/tcgetpgrp.c b/libc/sysdeps/unix/bsd/tcgetpgrp.c
new file mode 100644
index 000000000..0ccadef87
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/tcgetpgrp.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+/* Return the foreground process group ID of FD. */
+pid_t
+tcgetpgrp (fd)
+ int fd;
+{
+ int pgrp;
+
+ if (__ioctl (fd, TIOCGPGRP, &pgrp) < 0)
+ return (pid_t) -1;
+ return (pid_t) pgrp;
+}
+libc_hidden_def (tcgetpgrp)
diff --git a/libc/sysdeps/unix/bsd/tcsendbrk.c b/libc/sysdeps/unix/bsd/tcsendbrk.c
new file mode 100644
index 000000000..e8583be53
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/tcsendbrk.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <signal.h>
+#include <termios.h>
+#include <unistd.h>
+#include "bsdtty.h"
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+/* Send zero bits on FD. */
+int
+tcsendbreak (fd, duration)
+ int fd;
+ int duration;
+{
+ struct timeval delay;
+
+ /* The break lasts 0.25 to 0.5 seconds if DURATION is zero,
+ and an implementation-defined period if DURATION is nonzero.
+ We define a positive DURATION to be number of microseconds to break. */
+ if (duration <= 0)
+ duration = 400000;
+
+ delay.tv_sec = 0;
+ delay.tv_usec = duration;
+
+ /* Starting sending break. */
+ if (__ioctl (fd, TIOCSBRK, (void *) NULL) < 0)
+ return -1;
+
+ /* Wait DURATION microseconds. */
+ (void) __select (0, (fd_set *) NULL, (fd_set *) NULL, (fd_set *) NULL,
+ &delay);
+
+ /* Turn off the break. */
+ return __ioctl (fd, TIOCCBRK, (void *) NULL);
+}
diff --git a/libc/sysdeps/unix/bsd/tcsetattr.c b/libc/sysdeps/unix/bsd/tcsetattr.c
new file mode 100644
index 000000000..fd390cd88
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/tcsetattr.c
@@ -0,0 +1,188 @@
+/* Copyright (C) 1991, 1993, 1996, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <termios.h>
+
+#include "bsdtty.h"
+
+
+const speed_t __bsd_speeds[] =
+ {
+ 0,
+ 50,
+ 75,
+ 110,
+ 134,
+ 150,
+ 200,
+ 300,
+ 600,
+ 1200,
+ 1800,
+ 2400,
+ 4800,
+ 9600,
+ 19200,
+ 38400,
+ };
+
+
+/* Set the state of FD to *TERMIOS_P. */
+int
+tcsetattr (fd, optional_actions, termios_p)
+ int fd;
+ int optional_actions;
+ const struct termios *termios_p;
+{
+ struct sgttyb buf;
+ struct tchars tchars;
+ struct ltchars ltchars;
+ int local;
+#ifdef TIOCGETX
+ int extra;
+#endif
+ size_t i;
+
+ if (__ioctl (fd, TIOCGETP, &buf) < 0 ||
+ __ioctl (fd, TIOCGETC, &tchars) < 0 ||
+ __ioctl (fd, TIOCGLTC, &ltchars) < 0 ||
+#ifdef TIOCGETX
+ __ioctl (fd, TIOCGETX, &extra) < 0 ||
+#endif
+ __ioctl (fd, TIOCLGET, &local) < 0)
+ return -1;
+
+ if (termios_p == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ switch (optional_actions)
+ {
+ case TCSANOW:
+ break;
+ case TCSADRAIN:
+ if (tcdrain (fd) < 0)
+ return -1;
+ break;
+ case TCSAFLUSH:
+ if (tcflush (fd, TCIFLUSH) < 0)
+ return -1;
+ break;
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ buf.sg_ispeed = buf.sg_ospeed = -1;
+ for (i = 0; i <= sizeof (__bsd_speeds) / sizeof (__bsd_speeds[0]); ++i)
+ {
+ if (__bsd_speeds[i] == termios_p->__ispeed)
+ buf.sg_ispeed = i;
+ if (__bsd_speeds[i] == termios_p->__ospeed)
+ buf.sg_ospeed = i;
+ }
+ if (buf.sg_ispeed == -1 || buf.sg_ospeed == -1)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ buf.sg_flags &= ~(CBREAK|RAW);
+ if (!(termios_p->c_lflag & ICANON))
+ buf.sg_flags |= (termios_p->c_cflag & ISIG) ? CBREAK : RAW;
+#ifdef LPASS8
+ if (termios_p->c_oflag & CS8)
+ local |= LPASS8;
+ else
+ local &= ~LPASS8;
+#endif
+ if (termios_p->c_lflag & _NOFLSH)
+ local |= LNOFLSH;
+ else
+ local &= ~LNOFLSH;
+ if (termios_p->c_oflag & OPOST)
+ local &= ~LLITOUT;
+ else
+ local |= LLITOUT;
+#ifdef TIOCGETX
+ if (termios_p->c_lflag & ISIG)
+ extra &= ~NOISIG;
+ else
+ extra |= NOISIG;
+ if (termios_p->c_cflag & CSTOPB)
+ extra |= STOPB;
+ else
+ extra &= ~STOPB;
+#endif
+ if (termios_p->c_iflag & ICRNL)
+ buf.sg_flags |= CRMOD;
+ else
+ buf.sg_flags &= ~CRMOD;
+ if (termios_p->c_iflag & IXOFF)
+ buf.sg_flags |= TANDEM;
+ else
+ buf.sg_flags &= ~TANDEM;
+
+ buf.sg_flags &= ~(ODDP|EVENP);
+ if (!(termios_p->c_cflag & PARENB))
+ buf.sg_flags |= ODDP | EVENP;
+ else if (termios_p->c_cflag & PARODD)
+ buf.sg_flags |= ODDP;
+ else
+ buf.sg_flags |= EVENP;
+
+ if (termios_p->c_lflag & _ECHO)
+ buf.sg_flags |= ECHO;
+ else
+ buf.sg_flags &= ~ECHO;
+ if (termios_p->c_lflag & ECHOE)
+ local |= LCRTERA;
+ else
+ local &= ~LCRTERA;
+ if (termios_p->c_lflag & ECHOK)
+ local |= LCRTKIL;
+ else
+ local &= ~LCRTKIL;
+ if (termios_p->c_lflag & _TOSTOP)
+ local |= LTOSTOP;
+ else
+ local &= ~LTOSTOP;
+
+ buf.sg_erase = termios_p->c_cc[VERASE];
+ buf.sg_kill = termios_p->c_cc[VKILL];
+ tchars.t_eofc = termios_p->c_cc[VEOF];
+ tchars.t_intrc = termios_p->c_cc[VINTR];
+ tchars.t_quitc = termios_p->c_cc[VQUIT];
+ ltchars.t_suspc = termios_p->c_cc[VSUSP];
+ tchars.t_startc = termios_p->c_cc[VSTART];
+ tchars.t_stopc = termios_p->c_cc[VSTOP];
+
+ if (__ioctl (fd, TIOCSETP, &buf) < 0 ||
+ __ioctl (fd, TIOCSETC, &tchars) < 0 ||
+ __ioctl (fd, TIOCSLTC, &ltchars) < 0 ||
+#ifdef TIOCGETX
+ __ioctl (fd, TIOCSETX, &extra) < 0 ||
+#endif
+ __ioctl (fd, TIOCLSET, &local) < 0)
+ return -1;
+ return 0;
+}
+libc_hidden_def (tcsetattr)
diff --git a/libc/sysdeps/unix/bsd/tcsetpgrp.c b/libc/sysdeps/unix/bsd/tcsetpgrp.c
new file mode 100644
index 000000000..ea7e4cc72
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/tcsetpgrp.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <unistd.h>
+
+/* Set the foreground process group ID of FD set PGRP_ID. */
+int
+tcsetpgrp (fd, pgrp_id)
+ int fd;
+ pid_t pgrp_id;
+{
+ return __ioctl (fd, TIOCSPGRP, &pgrp_id);
+}
diff --git a/libc/sysdeps/unix/bsd/telldir.c b/libc/sysdeps/unix/bsd/telldir.c
new file mode 100644
index 000000000..3d625c65d
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/telldir.c
@@ -0,0 +1,116 @@
+/* Copyright (C) 1994, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include "dirstream.h"
+
+/* Internal data structure for telldir and seekdir. */
+struct record
+ {
+ struct record *next; /* Link in chain. */
+ off_t cookie; /* Value returned by `telldir'. */
+ off_t pos;
+ size_t offset;
+ };
+#define NBUCKETS 32
+static struct record *records[32];
+static off_t lastpos;
+__libc_lock_define_initialized(static, lock) /* Locks above data. */
+
+
+/* Return the current position of DIRP. */
+long int
+telldir (dirp)
+ DIR *dirp;
+{
+ struct record *new;
+ long int pos;
+
+ new = malloc (sizeof *new);
+ if (new == NULL)
+ return -1l;
+
+ __libc_lock_lock (lock);
+
+ new->pos = dirp->filepos;
+ new->offset = dirp->offset;
+ new->cookie = ++lastpos;
+ new->next = records[new->cookie % NBUCKETS];
+ records[new->cookie % NBUCKETS] = new;
+
+ pos = new->cookie;
+
+ __libc_lock_unlock (lock);
+
+ return pos;
+}
+
+
+
+/* Seek to position POS in DIRP. */
+void
+seekdir (dirp, pos)
+ DIR *dirp;
+ long int pos;
+{
+ struct record *r, **prevr;
+
+ __libc_lock_lock (lock);
+
+ for (prevr = &records[pos % NBUCKETS], r = *prevr;
+ r != NULL;
+ prevr = &r->next, r = r->next)
+ if (r->cookie == pos)
+ {
+ __libc_lock_lock (dirp->__lock);
+ if (dirp->filepos != r->pos || dirp->offset != r->offset)
+ {
+ dirp->size = 0; /* Must read a fresh buffer. */
+ /* Move to the saved position. */
+ __lseek (dirp->fd, r->pos, SEEK_SET);
+ dirp->filepos = r->pos;
+ dirp->offset = 0;
+ /* Read entries until we reach the saved offset. */
+ while (dirp->offset < r->offset)
+ {
+ struct dirent *scan;
+ __libc_lock_unlock (dirp->__lock);
+ scan = readdir (dirp);
+ __libc_lock_lock (dirp->__lock);
+ if (! scan)
+ break;
+ }
+ }
+ __libc_lock_unlock (dirp->__lock);
+
+ /* To prevent leaking memory, cookies returned from telldir
+ can only be used once. So free this one's record now. */
+ *prevr = r->next;
+ free (r);
+ break;
+ }
+
+ __libc_lock_unlock (lock);
+
+ /* If we lost there is no way to indicate it. Oh well. */
+}
diff --git a/libc/sysdeps/unix/bsd/times.c b/libc/sysdeps/unix/bsd/times.c
new file mode 100644
index 000000000..d77438703
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/times.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 1991,92,93,95,96,97,1998,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/resource.h>
+#include <sys/times.h>
+#include <sys/time.h>
+#include <time.h>
+
+
+/* Time the program started. */
+extern time_t _posix_start_time;
+
+#ifdef __GNUC__
+__inline
+#endif
+static clock_t
+timeval_to_clock_t (const struct timeval *tv, clock_t clk_tck)
+{
+ return (clock_t) ((tv->tv_sec * clk_tck) +
+ (tv->tv_usec * clk_tck / 1000000L));
+}
+
+/* Store the CPU time used by this process and all its
+ dead children (and their dead children) in BUFFER.
+ Return the elapsed real time, or (clock_t) -1 for errors.
+ All times are in CLK_TCKths of a second. */
+clock_t
+__times (buffer)
+ struct tms *buffer;
+{
+ struct rusage usage;
+ clock_t clk_tck;
+
+ if (buffer == NULL)
+ {
+ __set_errno (EINVAL);
+ return (clock_t) -1;
+ }
+
+ clk_tck = __getclktck ();
+
+ if (__getrusage (RUSAGE_SELF, &usage) < 0)
+ return (clock_t) -1;
+ buffer->tms_utime = (clock_t) timeval_to_clock_t (&usage.ru_utime, clk_tck);
+ buffer->tms_stime = (clock_t) timeval_to_clock_t (&usage.ru_stime, clk_tck);
+
+ if (__getrusage (RUSAGE_CHILDREN, &usage) < 0)
+ return (clock_t) -1;
+ buffer->tms_cutime = (clock_t) timeval_to_clock_t (&usage.ru_utime, clk_tck);
+ buffer->tms_cstime = (clock_t) timeval_to_clock_t (&usage.ru_stime, clk_tck);
+
+ return (time ((time_t *) NULL) - _posix_start_time) * clk_tck;
+}
+
+weak_alias (__times, times)
diff --git a/libc/sysdeps/unix/bsd/ualarm.c b/libc/sysdeps/unix/bsd/ualarm.c
new file mode 100644
index 000000000..939ca6be2
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/ualarm.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1991, 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/time.h>
+#include <unistd.h>
+
+/* Set an alarm to go off (generating a SIGALRM signal) in VALUE microseconds.
+ If INTERVAL is nonzero, when the alarm goes off, the timer is reset to go
+ off every INTERVAL microseconds thereafter.
+
+ Returns the number of microseconds remaining before the alarm. */
+useconds_t
+ualarm (value, interval)
+ useconds_t value;
+ useconds_t interval;
+{
+ struct itimerval timer, otimer;
+
+ timer.it_value.tv_sec = 0;
+ timer.it_value.tv_usec = value;
+ timer.it_interval.tv_sec = 0;
+ timer.it_interval.tv_usec = interval;
+
+ if (__setitimer (ITIMER_REAL, &timer, &otimer) < 0)
+ return -1;
+
+ return (otimer.it_value.tv_sec * 1000000) + otimer.it_value.tv_usec;
+}
diff --git a/libc/sysdeps/unix/bsd/ulimit.c b/libc/sysdeps/unix/bsd/ulimit.c
new file mode 100644
index 000000000..963d156e2
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/ulimit.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 1991,1992,1994-1998,2001,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <sysdep.h>
+#include <ulimit.h>
+#include <unistd.h>
+#include <sys/resource.h>
+
+
+extern int _etext;
+
+/* Function depends on CMD:
+ 1 = Return the limit on the size of a file, in units of 512 bytes.
+ 2 = Set the limit on the size of a file to NEWLIMIT. Only the
+ super-user can increase the limit.
+ 3 = Return the maximum possible address of the data segment.
+ 4 = Return the maximum number of files that the calling process
+ can open.
+ Returns -1 on errors. */
+long int
+ulimit (int cmd, ...)
+{
+ struct rlimit limit;
+ va_list va;
+ long int result = -1;
+
+ va_start (va, cmd);
+
+ switch (cmd)
+ {
+ case UL_GETFSIZE:
+ /* Get limit on file size. */
+ if (getrlimit (RLIMIT_FSIZE, &limit) == 0)
+ /* Convert from bytes to 512 byte units. */
+ result = limit.rlim_cur / 512;
+ break;
+
+ case UL_SETFSIZE:
+ /* Set limit on file size. */
+ {
+ long int newlimit = va_arg (va, long int);
+
+ if ((rlim_t) newlimit > RLIM_INFINITY / 512)
+ {
+ limit.rlim_cur = RLIM_INFINITY;
+ limit.rlim_max = RLIM_INFINITY;
+ }
+ else
+ {
+ limit.rlim_cur = newlimit * 512;
+ limit.rlim_max = newlimit * 512;
+ }
+
+ result = setrlimit (RLIMIT_FSIZE, &limit);
+ }
+ break;
+
+ case __UL_GETMAXBRK:
+ /* Get maximum address for `brk'. */
+ if (getrlimit (RLIMIT_DATA, &limit) == 0)
+ result = ((long int) &_etext) + limit.rlim_cur;
+ break;
+
+ case __UL_GETOPENMAX:
+ result = sysconf (_SC_OPEN_MAX);
+ break;
+
+ default:
+ __set_errno (EINVAL);
+ }
+
+ va_end (va);
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/bsd/unlockpt.c b/libc/sysdeps/unix/bsd/unlockpt.c
new file mode 100644
index 000000000..59fc7392e
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/unlockpt.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <paths.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+/* Unlock the slave pseudo terminal associated with the master pseudo
+ terminal specified by FD. */
+int
+unlockpt (int fd)
+{
+ char buf[sizeof (_PATH_TTY) + 2];
+
+ /* BSD doesn't have a lock, but it does have `revoke'. */
+ if (__ptsname_r (fd, buf, sizeof (buf)))
+ return -1;
+ return revoke (buf);
+}
diff --git a/libc/sysdeps/unix/bsd/usleep.c b/libc/sysdeps/unix/bsd/usleep.c
new file mode 100644
index 000000000..9c1049c10
--- /dev/null
+++ b/libc/sysdeps/unix/bsd/usleep.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1992, 1996, 1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+/* Sleep USECONDS microseconds, or until a previously set timer goes off. */
+int
+usleep (useconds)
+ useconds_t useconds;
+{
+ struct timeval delay;
+
+ delay.tv_sec = 0;
+ delay.tv_usec = useconds;
+
+ return __select (0, (fd_set *) NULL, (fd_set *) NULL, (fd_set *) NULL,
+ &delay);
+}
diff --git a/libc/sysdeps/unix/clock_gettime.c b/libc/sysdeps/unix/clock_gettime.c
new file mode 100644
index 000000000..f698f0151
--- /dev/null
+++ b/libc/sysdeps/unix/clock_gettime.c
@@ -0,0 +1,134 @@
+/* clock_gettime -- Get the current time from a POSIX clockid_t. Unix version.
+ Copyright (C) 1999-2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdint.h>
+#include <time.h>
+#include <sys/time.h>
+#include <libc-internal.h>
+#include <ldsodefs.h>
+
+
+#if HP_TIMING_AVAIL
+/* Clock frequency of the processor. We make it a 64-bit variable
+ because some jokers are already playing with processors with more
+ than 4GHz. */
+static hp_timing_t freq;
+
+
+/* This function is defined in the thread library. */
+extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
+ struct timespec *tp)
+ __attribute__ ((__weak__));
+
+static int
+hp_timing_gettime (clockid_t clock_id, struct timespec *tp)
+{
+ hp_timing_t tsc;
+
+ if (__builtin_expect (freq == 0, 0))
+ {
+ /* This can only happen if we haven't initialized the `freq'
+ variable yet. Do this now. We don't have to protect this
+ code against multiple execution since all of them should
+ lead to the same result. */
+ freq = __get_clockfreq ();
+ if (__builtin_expect (freq == 0, 0))
+ /* Something went wrong. */
+ return -1;
+ }
+
+ if (clock_id != CLOCK_PROCESS_CPUTIME_ID
+ && __pthread_clock_gettime != NULL)
+ return __pthread_clock_gettime (clock_id, freq, tp);
+
+ /* Get the current counter. */
+ HP_TIMING_NOW (tsc);
+
+ /* Compute the offset since the start time of the process. */
+ tsc -= GL(dl_cpuclock_offset);
+
+ /* Compute the seconds. */
+ tp->tv_sec = tsc / freq;
+
+ /* And the nanoseconds. This computation should be stable until
+ we get machines with about 16GHz frequency. */
+ tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq;
+
+ return 0;
+}
+#endif
+
+
+static inline int
+realtime_gettime (struct timespec *tp)
+{
+ struct timeval tv;
+ int retval = gettimeofday (&tv, NULL);
+ if (retval == 0)
+ /* Convert into `timespec'. */
+ TIMEVAL_TO_TIMESPEC (&tv, tp);
+ return retval;
+}
+
+
+/* Get current value of CLOCK and store it in TP. */
+int
+clock_gettime (clockid_t clock_id, struct timespec *tp)
+{
+ int retval = -1;
+ struct timeval tv;
+
+ switch (clock_id)
+ {
+#ifdef SYSDEP_GETTIME
+ SYSDEP_GETTIME;
+#endif
+
+#ifndef HANDLED_REALTIME
+ case CLOCK_REALTIME:
+ retval = gettimeofday (&tv, NULL);
+ if (retval == 0)
+ TIMEVAL_TO_TIMESPEC (&tv, tp);
+ break;
+#endif
+
+ default:
+#ifdef SYSDEP_GETTIME_CPU
+ SYSDEP_GETTIME_CPU;
+#endif
+#if HP_TIMING_AVAIL
+ if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
+ == CLOCK_THREAD_CPUTIME_ID)
+ retval = hp_timing_gettime (clock_id, tp);
+ else
+#endif
+ __set_errno (EINVAL);
+ break;
+
+#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
+ case CLOCK_PROCESS_CPUTIME_ID:
+ retval = hp_timing_gettime (clock_id, tp);
+ break;
+#endif
+ }
+
+ return retval;
+}
+librt_hidden_def (clock_gettime)
diff --git a/libc/sysdeps/unix/clock_nanosleep.c b/libc/sysdeps/unix/clock_nanosleep.c
new file mode 100644
index 000000000..248bfe1c9
--- /dev/null
+++ b/libc/sysdeps/unix/clock_nanosleep.c
@@ -0,0 +1,101 @@
+/* High-resolution sleep with the specified clock.
+ Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <time.h>
+#include <hp-timing.h>
+#include <sysdep-cancel.h>
+
+#if HP_TIMING_AVAIL
+# define CPUCLOCK_P(clock) \
+ ((clock) == CLOCK_PROCESS_CPUTIME_ID \
+ || ((clock) & ((1 << CLOCK_IDFIELD_SIZE) - 1)) == CLOCK_THREAD_CPUTIME_ID)
+#else
+# define CPUCLOCK_P(clock) 0
+#endif
+
+#ifndef INVALID_CLOCK_P
+# define INVALID_CLOCK_P(cl) \
+ ((cl) < CLOCK_REALTIME || (cl) > CLOCK_THREAD_CPUTIME_ID)
+#endif
+
+
+/* This implementation assumes that these is only a `nanosleep' system
+ call. So we have to remap all other activities. */
+int
+clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
+ struct timespec *rem)
+{
+ struct timespec now;
+
+ if (__builtin_expect (req->tv_nsec, 0) < 0
+ || __builtin_expect (req->tv_nsec, 0) >= 1000000000)
+ return EINVAL;
+
+ if (clock_id == CLOCK_THREAD_CPUTIME_ID)
+ return EINVAL; /* POSIX specifies EINVAL for this case. */
+
+#ifdef SYSDEP_NANOSLEEP
+ SYSDEP_NANOSLEEP;
+#endif
+
+ if (CPUCLOCK_P (clock_id))
+ return ENOTSUP;
+
+ if (INVALID_CLOCK_P (clock_id))
+ return EINVAL;
+
+ /* If we got an absolute time, remap it. */
+ if (flags == TIMER_ABSTIME)
+ {
+ long int nsec;
+ long int sec;
+
+ /* Make sure we use safe data types. */
+ assert (sizeof (sec) >= sizeof (now.tv_sec));
+
+ /* Get the current time for this clock. */
+ if (__builtin_expect (clock_gettime (clock_id, &now), 0) != 0)
+ return errno;
+
+ /* Compute the difference. */
+ nsec = req->tv_nsec - now.tv_nsec;
+ sec = req->tv_sec - now.tv_sec - (nsec < 0);
+ if (sec < 0)
+ /* The time has already elapsed. */
+ return 0;
+
+ now.tv_sec = sec;
+ now.tv_nsec = nsec + (nsec < 0 ? 1000000000 : 0);
+
+ /* From now on this is our time. */
+ req = &now;
+
+ /* Make sure we are not modifying the struct pointed to by REM. */
+ rem = NULL;
+ }
+ else if (__builtin_expect (flags, 0) != 0)
+ return EINVAL;
+ else if (clock_id != CLOCK_REALTIME)
+ /* Not supported. */
+ return ENOTSUP;
+
+ return __builtin_expect (nanosleep (req, rem), 0) ? errno : 0;
+}
diff --git a/libc/sysdeps/unix/clock_settime.c b/libc/sysdeps/unix/clock_settime.c
new file mode 100644
index 000000000..a93be6349
--- /dev/null
+++ b/libc/sysdeps/unix/clock_settime.c
@@ -0,0 +1,129 @@
+/* Copyright (C) 1999-2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+#include <libc-internal.h>
+#include <ldsodefs.h>
+
+
+#if HP_TIMING_AVAIL
+/* Clock frequency of the processor. We make it a 64-bit variable
+ because some jokers are already playing with processors with more
+ than 4GHz. */
+static hp_timing_t freq;
+
+
+/* This function is defined in the thread library. */
+extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
+ __attribute__ ((__weak__));
+#endif
+
+
+#if HP_TIMING_AVAIL
+static int
+hp_timing_settime (clockid_t clock_id, const struct timespec *tp)
+{
+ hp_timing_t tsc;
+ hp_timing_t usertime;
+
+ /* First thing is to get the current time. */
+ HP_TIMING_NOW (tsc);
+
+ if (__builtin_expect (freq == 0, 0))
+ {
+ /* This can only happen if we haven't initialized the `freq'
+ variable yet. Do this now. We don't have to protect this
+ code against multiple execution since all of them should lead
+ to the same result. */
+ freq = __get_clockfreq ();
+ if (__builtin_expect (freq == 0, 0))
+ /* Something went wrong. */
+ return -1;
+ }
+
+ /* Convert the user-provided time into CPU ticks. */
+ usertime = tp->tv_sec * freq + (tp->tv_nsec * freq) / 1000000000ull;
+
+ /* Determine the offset and use it as the new base value. */
+ if (clock_id == CLOCK_PROCESS_CPUTIME_ID
+ || __pthread_clock_settime == NULL)
+ GL(dl_cpuclock_offset) = tsc - usertime;
+ else
+ __pthread_clock_settime (clock_id, tsc - usertime);
+
+ return 0;
+}
+#endif
+
+
+/* Set CLOCK to value TP. */
+int
+clock_settime (clockid_t clock_id, const struct timespec *tp)
+{
+ int retval;
+
+ /* Make sure the time cvalue is OK. */
+ if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ switch (clock_id)
+ {
+#define HANDLE_REALTIME \
+ do { \
+ struct timeval tv; \
+ TIMESPEC_TO_TIMEVAL (&tv, tp); \
+ \
+ retval = settimeofday (&tv, NULL); \
+ } while (0)
+
+#ifdef SYSDEP_SETTIME
+ SYSDEP_SETTIME;
+#endif
+
+#ifndef HANDLED_REALTIME
+ case CLOCK_REALTIME:
+ HANDLE_REALTIME;
+ break;
+#endif
+
+ default:
+#ifdef SYSDEP_SETTIME_CPU
+ SYSDEP_SETTIME_CPU;
+#endif
+#ifndef HANDLED_CPUTIME
+# if HP_TIMING_AVAIL
+ if (CPUCLOCK_WHICH (clock_id) == CLOCK_PROCESS_CPUTIME_ID
+ || CPUCLOCK_WHICH (clock_id) == CLOCK_THREAD_CPUTIME_ID)
+ retval = hp_timing_settime (clock_id, tp);
+ else
+# endif
+ {
+ __set_errno (EINVAL);
+ retval = -1;
+ }
+#endif
+ break;
+ }
+
+ return retval;
+}
diff --git a/libc/sysdeps/unix/closedir.c b/libc/sysdeps/unix/closedir.c
new file mode 100644
index 000000000..09deee7e8
--- /dev/null
+++ b/libc/sysdeps/unix/closedir.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1991,1993,1995,1996,1998,2002,2003
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <dirstream.h>
+#include <not-cancel.h>
+
+
+/* Close the directory stream DIRP.
+ Return 0 if successful, -1 if not. */
+int
+__closedir (DIR *dirp)
+{
+ int fd;
+
+ if (dirp == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* We do not try to synchronize access here. If some other thread
+ still uses this handle it is a big mistake and that thread
+ deserves all the bad data it gets. */
+
+ fd = dirp->fd;
+
+ __libc_lock_fini (dirp->lock);
+
+ free ((void *) dirp);
+
+ return close_not_cancel (fd);
+}
+weak_alias (__closedir, closedir)
diff --git a/libc/sysdeps/unix/common/.cvsignore b/libc/sysdeps/unix/common/.cvsignore
new file mode 100644
index 000000000..1f69fd919
--- /dev/null
+++ b/libc/sysdeps/unix/common/.cvsignore
@@ -0,0 +1,4 @@
+*.gz *.Z *.tar *.tgz
+=*
+TODO COPYING* AUTHORS copyr-* copying.*
+glibc-*
diff --git a/libc/sysdeps/unix/common/bits/dirent.h b/libc/sysdeps/unix/common/bits/dirent.h
new file mode 100644
index 000000000..666a89fe1
--- /dev/null
+++ b/libc/sysdeps/unix/common/bits/dirent.h
@@ -0,0 +1,33 @@
+/* Directory entry structure `struct dirent'. SVR4 version.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DIRENT_H
+# error "Never use <bits/dirent.h> directly; include <dirent.h> instead."
+#endif
+
+struct dirent
+ {
+ unsigned int d_fileno;
+ int d_off; /* Position in directory of following entry. */
+ unsigned short int d_reclen;
+ char d_name[1]; /* Variable length. */
+ };
+
+#define _DIRENT_HAVE_D_RECLEN 1
+#define _DIRENT_HAVE_D_OFF 1
diff --git a/libc/sysdeps/unix/common/bits/fcntl.h b/libc/sysdeps/unix/common/bits/fcntl.h
new file mode 100644
index 000000000..5bf6791b5
--- /dev/null
+++ b/libc/sysdeps/unix/common/bits/fcntl.h
@@ -0,0 +1,120 @@
+/* O_*, F_*, FD_* bit values for general Unix system.
+ Copyright (C) 1991, 1992, 1995, 1997, 2000, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+
+/* File access modes for `open' and `fcntl'. */
+#define O_RDONLY 0 /* Open read-only. */
+#define O_WRONLY 1 /* Open write-only. */
+#define O_RDWR 2 /* Open read/write. */
+
+
+/* Bits OR'd into the second argument to open. */
+#define O_CREAT 0x0100 /* Create file if it doesn't exist. */
+#define O_EXCL 0x0400 /* Fail if file already exists. */
+#define O_TRUNC 0x0200 /* Truncate file to zero length. */
+#define O_NOCTTY 0x0800 /* Don't assign a controlling terminal. */
+#ifdef __USE_MISC
+# define O_ASYNC 0x0040 /* Send SIGIO to owner when data is ready. */
+# define O_FSYNC 0x0010 /* Synchronous writes. */
+# define O_SYNC O_FSYNC
+#endif
+
+/* File status flags for `open' and `fcntl'. */
+#define O_APPEND 0x0008 /* Writes append to the file. */
+#define O_NONBLOCK 0x0080 /* Non-blocking I/O. */
+
+#ifdef __USE_MISC
+# define O_NDELAY 0x0004
+#endif
+
+#ifdef __USE_MISC
+/* Bits in the file status flags returned by F_GETFL.
+ These are all the O_* flags, plus FREAD and FWRITE, which are
+ independent bits set by which of O_RDONLY, O_WRONLY, and O_RDWR, was
+ given to `open'. */
+# define FREAD 1
+# define FWRITE 2
+
+/* Traditional Unix names the O_* bits. */
+# define FASYNC O_ASYNC
+# define FCREAT O_CREAT
+# define FEXCL O_EXCL
+# define FTRUNC O_TRUNC
+# define FNOCTTY O_NOCTTY
+# define FFSYNC O_FSYNC
+# define FSYNC O_SYNC
+# define FAPPEND O_APPEND
+# define FNONBLOCK O_NONBLOCK
+# define FNONBIO O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif
+
+/* Mask for file access modes. This is system-dependent in case
+ some system ever wants to define some other flavor of access. */
+#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#if defined __USE_BSD || defined __USE_UNIX98
+# define F_GETOWN 23 /* Get owner (receiver of SIGIO). */
+# define F_SETOWN 24 /* Set owner (receiver of SIGIO). */
+#endif
+#define F_GETLK 14 /* Get record locking info. */
+#define F_SETLK 6 /* Set record locking info (non-blocking). */
+#define F_SETLKW 7 /* Set record locking info (blocking). */
+#ifdef __USE_SVID
+# define F_ALLOCSP 10 /* Allocate space in the file. */
+# define F_FREESP 11 /* Free space in the file. */
+# define F_RGETLK 20 /* Get remote record locking info. */
+# define F_RSETLK 21 /* Set remote locking info (non-blocking). */
+# define F_RSETLKW 22 /* Set remote locking info (blocking). */
+#endif
+
+/* File descriptor flags used with F_GETFD and F_SETFD. */
+#define FD_CLOEXEC 1 /* Close on exec. */
+
+
+#include <bits/types.h>
+
+/* The structure describing an advisory lock. This is the type of the third
+ argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+ long int l_sysid; /* System ID where locking process resides. */
+ __pid_t l_pid; /* Process holding the lock. */
+ long int pad[4]; /* Reserved for future use. */
+ };
+
+/* Values for the `l_type' field of a `struct flock'. */
+#define F_RDLCK 1 /* Read lock. */
+#define F_WRLCK 2 /* Write lock. */
+#define F_UNLCK 3 /* Remove lock. */
diff --git a/libc/sysdeps/unix/common/lxstat.c b/libc/sysdeps/unix/common/lxstat.c
new file mode 100644
index 000000000..88cc87120
--- /dev/null
+++ b/libc/sysdeps/unix/common/lxstat.c
@@ -0,0 +1,39 @@
+/* lxstat using old-style Unix lstat system call.
+ Copyright (C) 1991,1995,1996,1997,2000,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <bp-checks.h>
+
+extern int __syscall_lstat (const char *__unbounded, struct stat *__unbounded);
+
+int
+__lxstat (int vers, const char *file, struct stat *buf)
+{
+ if (vers != _STAT_VER)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return __syscall_lstat (CHECK_STRING (file), CHECK_1 (buf));
+}
+hidden_def (__lxstat)
+weak_alias (__lxstat, _lxstat)
diff --git a/libc/sysdeps/unix/common/syscalls.list b/libc/sysdeps/unix/common/syscalls.list
new file mode 100644
index 000000000..baec92f78
--- /dev/null
+++ b/libc/sysdeps/unix/common/syscalls.list
@@ -0,0 +1,16 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+adjtime - adjtime i:pp __adjtime adjtime
+fchmod - fchmod i:ii __fchmod fchmod
+fchown - fchown i:iii __fchown fchown
+ftruncate - ftruncate i:ii __ftruncate ftruncate
+getrusage - getrusage i:ip __getrusage getrusage
+gettimeofday - gettimeofday i:PP __gettimeofday gettimeofday __gettimeofday_internal
+settimeofday - settimeofday i:PP __settimeofday settimeofday
+setpgid - setpgrp i:ii __setpgid setpgid
+setregid - setregid i:ii __setregid setregid
+setreuid - setreuid i:ii __setreuid setreuid
+sigaction - sigaction i:ipp __sigaction sigaction
+sys_lstat lxstat lstat i:sp __syscall_lstat
+truncate - truncate i:si __truncate truncate
+vhangup - vhangup i:i vhangup
diff --git a/libc/sysdeps/unix/common/tcsendbrk.c b/libc/sysdeps/unix/common/tcsendbrk.c
new file mode 100644
index 000000000..16736e925
--- /dev/null
+++ b/libc/sysdeps/unix/common/tcsendbrk.c
@@ -0,0 +1,46 @@
+/* Send break to terminal.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+/* Send zero bits on FD. */
+int
+tcsendbreak (int fd, int duration)
+{
+ /* The break lasts 0.25 to 0.5 seconds if DURATION is zero,
+ and an implementation-defined period if DURATION is nonzero.
+ We define a positive DURATION to be number of milliseconds to break. */
+ if (duration <= 0)
+ return __ioctl (fd, TCSBRK, 0);
+
+#ifdef TCSBRKP
+ /* Probably Linux-specific: a positive third TCSBRKP ioctl argument is
+ defined to be the number of 100ms units to break. */
+ return __ioctl (fd, TCSBRKP, (duration + 99) / 100);
+#else
+ /* ioctl can't send a break of any other duration for us.
+ This could be changed to use trickery (e.g. lower speed and
+ send a '\0') to send the break, but for now just return an error. */
+ __set_errno (EINVAL);
+ return -1;
+#endif
+}
diff --git a/libc/sysdeps/unix/confstr.h b/libc/sysdeps/unix/confstr.h
new file mode 100644
index 000000000..15859c3b2
--- /dev/null
+++ b/libc/sysdeps/unix/confstr.h
@@ -0,0 +1 @@
+#define CS_PATH "/bin:/usr/bin"
diff --git a/libc/sysdeps/unix/dirfd.c b/libc/sysdeps/unix/dirfd.c
new file mode 100644
index 000000000..9a43246fe
--- /dev/null
+++ b/libc/sysdeps/unix/dirfd.c
@@ -0,0 +1,30 @@
+/* Return the file descriptor used by a DIR stream. Unix version.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dirent.h>
+#include <dirstream.h>
+
+#undef dirfd
+
+int
+dirfd (dirp)
+ DIR *dirp;
+{
+ return dirp->fd;
+}
diff --git a/libc/sysdeps/unix/dirstream.h b/libc/sysdeps/unix/dirstream.h
new file mode 100644
index 000000000..a1f74473c
--- /dev/null
+++ b/libc/sysdeps/unix/dirstream.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DIRSTREAM_H
+
+#define _DIRSTREAM_H 1
+
+#include <sys/types.h>
+
+#include <bits/libc-lock.h>
+
+/* Directory stream type.
+
+ The miscellaneous Unix `readdir' implementations read directory data
+ into a buffer and return `struct dirent *' pointers into it. */
+
+struct __dirstream
+ {
+ int fd; /* File descriptor. */
+
+ char *data; /* Directory block. */
+ size_t allocation; /* Space allocated for the block. */
+ size_t size; /* Total valid data in the block. */
+ size_t offset; /* Current offset into the block. */
+
+ off_t filepos; /* Position of next entry to read. */
+
+ __libc_lock_define (, lock) /* Mutex lock for this structure. */
+ };
+
+#define _DIR_dirfd(dirp) ((dirp)->fd)
+
+#endif /* dirstream.h */
diff --git a/libc/sysdeps/unix/errnos-tmpl.c b/libc/sysdeps/unix/errnos-tmpl.c
new file mode 100644
index 000000000..25d7ec5db
--- /dev/null
+++ b/libc/sysdeps/unix/errnos-tmpl.c
@@ -0,0 +1,99 @@
+/* Copyright (C) 1991, 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+
+static char iferrno[] = "#ifdef _ERRNO_H";
+static char endiferrno[] = "#endif /* <errno.h> included. */";
+static char ifEmath[] = "#if !defined(__Emath_defined) && \
+ (defined(_ERRNO_H) || defined(__need_Emath))";
+static char endifEmath[] = "#endif /* Emath not defined and <errno.h> \
+included or need Emath. */";
+
+static int biggest_value = 0;
+static int done_ENOSYS = 0;
+static int done_ERANGE = 0, done_EDOM = 0;
+
+static void
+DO(name, value)
+ char *name;
+ int value;
+{
+ int is_ERANGE = !done_ERANGE && !strcmp(name, "ERANGE");
+ int is_EDOM = !done_EDOM && !strcmp(name, "EDOM");
+ int is_Emath = is_ERANGE || is_EDOM;
+
+ if (is_Emath)
+ {
+ puts(endiferrno);
+ puts(ifEmath);
+ }
+
+ if (!strcmp (name, "EWOULDBLOCK"))
+ {
+ puts ("#define EWOULDBLOCK EAGAIN /* Translated in glibc. */");
+ name = "EWOULDBLOCK_sys /* Value actually returned by kernel. */";
+ }
+
+ printf ("#define %s %d\n", name, value);
+
+ if (is_Emath)
+ {
+ puts(endifEmath);
+ puts(iferrno);
+ }
+
+ if (value > biggest_value)
+ biggest_value = value;
+
+ if (is_ERANGE)
+ done_ERANGE = 1;
+ else if (is_EDOM)
+ done_EDOM = 1;
+ else if (!done_ENOSYS && !strcmp(name, "ENOSYS"))
+ done_ENOSYS = 1;
+}
+
+int
+main()
+{
+ puts(iferrno);
+
+ ERRNOS;
+
+ if (!done_EDOM || !done_ERANGE)
+ {
+ puts(endiferrno);
+ puts(ifEmath);
+ if (!done_EDOM)
+ printf("#define EDOM %d\n", ++biggest_value);
+ if (!done_ERANGE)
+ printf("#define ERANGE %d\n", ++biggest_value);
+ puts(endifEmath);
+ }
+
+ if (!done_ENOSYS)
+ printf("#define ENOSYS %d\n", ++biggest_value);
+
+ puts(endiferrno);
+
+ puts("#undef __need_Emath");
+ puts("#ifndef __Emath_defined\n#define __Emath_defined 1\n#endif");
+
+ exit(0);
+}
diff --git a/libc/sysdeps/unix/errnos.awk b/libc/sysdeps/unix/errnos.awk
new file mode 100644
index 000000000..8648f41fb
--- /dev/null
+++ b/libc/sysdeps/unix/errnos.awk
@@ -0,0 +1,12 @@
+BEGIN { special = 0 }
+
+/ERRNOS/ { nerrnos = split(errnos, errs)
+ for (i = 1; i <= nerrnos; ++i)
+ # Some systems define errno codes inside undefined #ifdefs,
+ # and then never actually use them.
+ printf "#ifdef %s\n DO(\"%s\", %s);\n#endif\n", \
+ errs[i], errs[i], errs[i]
+ special = 1 }
+
+
+{ if (special == 0) print $0; special = 0 }
diff --git a/libc/sysdeps/unix/execve.S b/libc/sysdeps/unix/execve.S
new file mode 100644
index 000000000..de125d3f9
--- /dev/null
+++ b/libc/sysdeps/unix/execve.S
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991, 92, 93, 95, 96 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* Some systems misname the system call number macro for this. */
+#if !defined (SYS_execve) && defined (SYS_exece)
+#define SYS_execve SYS_exece
+#endif
+#if !defined (SYS_execve) && defined (SYS_exec)
+#define SYS_execve SYS_exec
+#endif
+
+SYSCALL__ (execve, 3)
+ ret
+PSEUDO_END(__execve)
+
+weak_alias (__execve, execve)
diff --git a/libc/sysdeps/unix/fdopendir.c b/libc/sysdeps/unix/fdopendir.c
new file mode 100644
index 000000000..565ce1ed7
--- /dev/null
+++ b/libc/sysdeps/unix/fdopendir.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <not-cancel.h>
+
+
+DIR *
+__fdopendir (int fd)
+{
+ struct stat64 statbuf;
+
+ if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &statbuf), 0) < 0)
+ return NULL;
+ if (__builtin_expect (! S_ISDIR (statbuf.st_mode), 0))
+ {
+ __set_errno (ENOTDIR);
+ return NULL;
+ }
+
+ /* Make sure the descriptor allows for reading. */
+ int flags = __fcntl (fd, F_GETFL);
+ if (__builtin_expect (flags == -1, 0))
+ return NULL;
+ if (__builtin_expect ((flags & O_ACCMODE) == O_WRONLY, 0))
+ {
+ __set_errno (EINVAL);
+ return NULL;
+ }
+
+ return __alloc_dir (fd, false, &statbuf);
+}
+weak_alias (__fdopendir, fdopendir)
diff --git a/libc/sysdeps/unix/fork.S b/libc/sysdeps/unix/fork.S
new file mode 100644
index 000000000..8717d513b
--- /dev/null
+++ b/libc/sysdeps/unix/fork.S
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991,92,94,95,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* This code works for at least m68k. */
+
+SYSCALL__ (fork, 0)
+ /* R1 is now 0 for the parent and 1 for the child. Decrement it to
+ make it -1 (all bits set) for the parent, and 0 (no bits set)
+ for the child. Then AND it with R0, so the parent gets
+ R0&-1==R0, and the child gets R0&0==0. */
+ subl #1, r1
+ andl r1, r0
+ ret
+PSEUDO_END (__fork)
+libc_hidden_def (__fork)
+
+weak_alias (__fork, fork)
diff --git a/libc/sysdeps/unix/fxstat.c b/libc/sysdeps/unix/fxstat.c
new file mode 100644
index 000000000..687ce9aba
--- /dev/null
+++ b/libc/sysdeps/unix/fxstat.c
@@ -0,0 +1,40 @@
+/* fxstat using old-style Unix fstat system call.
+ Copyright (C) 1991,1995,1996,1997,2000,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <bp-checks.h>
+
+extern int __syscall_fstat (int, struct stat *__unbounded);
+
+/* Get information about the file descriptor FD in BUF. */
+int
+__fxstat (int vers, int fd, struct stat *buf)
+{
+ if (vers != _STAT_VER)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return __syscall_fstat (fd, CHECK_1 (buf));
+}
+hidden_def (__fxstat)
+weak_alias (__fxstat, _fxstat)
diff --git a/libc/sysdeps/unix/get_child_max.c b/libc/sysdeps/unix/get_child_max.c
new file mode 100644
index 000000000..c59e4d895
--- /dev/null
+++ b/libc/sysdeps/unix/get_child_max.c
@@ -0,0 +1,37 @@
+/* Get POSIX {CHILD_MAX} run-time limit value. Unix version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <limits.h>
+#include <sys/sysinfo.h>
+#include <sys/resource.h>
+
+#ifndef CHILD_MAX
+long int
+__get_child_max (void)
+{
+# ifdef RLIMIT_NPROC
+ struct rlimit limit;
+ if (__getrlimit (RLIMIT_NPROC, &limit) == 0
+ && limit.rlim_cur != RLIM_INFINITY)
+ return limit.rlim_cur;
+# endif
+
+ return -1;
+}
+#endif
diff --git a/libc/sysdeps/unix/getdents.c b/libc/sysdeps/unix/getdents.c
new file mode 100644
index 000000000..54a76d9d8
--- /dev/null
+++ b/libc/sysdeps/unix/getdents.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+ssize_t
+__getdirentries (fd, buf, nbytes, basep)
+ int fd;
+ char *buf;
+ size_t nbytes;
+ off_t *basep;
+{
+ if (basep)
+ *basep = __lseek (fd, (off_t) 0, SEEK_CUR);
+
+ return (ssize_t) __read (fd, buf, nbytes);
+}
+
+weak_alias (__getdirentries, getdirentries)
diff --git a/libc/sysdeps/unix/getegid.S b/libc/sysdeps/unix/getegid.S
new file mode 100644
index 000000000..95ebd9262
--- /dev/null
+++ b/libc/sysdeps/unix/getegid.S
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991, 1992, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#ifdef SYS_getegid
+SYSCALL__ (getegid, 0)
+#else
+PSEUDO (__getegid, getgid, 0)
+ MOVE(r1, r0)
+#endif
+ ret
+PSEUDO_END(__getegid)
+
+weak_alias (__getegid, getegid)
diff --git a/libc/sysdeps/unix/geteuid.S b/libc/sysdeps/unix/geteuid.S
new file mode 100644
index 000000000..2a8910529
--- /dev/null
+++ b/libc/sysdeps/unix/geteuid.S
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991, 1992, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#ifdef SYS_geteuid
+SYSCALL__ (geteuid, 0)
+#else
+PSEUDO (__geteuid, getuid, 0)
+ MOVE(r1, r0)
+#endif
+ ret
+PSEUDO_END(__geteuid)
+
+weak_alias (__geteuid, geteuid)
diff --git a/libc/sysdeps/unix/getlogin.c b/libc/sysdeps/unix/getlogin.c
new file mode 100644
index 000000000..4752685f8
--- /dev/null
+++ b/libc/sysdeps/unix/getlogin.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 1991, 1992, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <limits.h>
+#include <fcntl.h>
+
+#include <utmp.h>
+
+/* Return the login name of the user, or NULL if it can't be determined.
+ The returned pointer, if not NULL, is good only until the next call. */
+
+char *
+getlogin (void)
+{
+ char tty_pathname[2 + 2 * NAME_MAX];
+ char *real_tty_path = tty_pathname;
+ char *result = NULL;
+ static char name[UT_NAMESIZE + 1];
+ struct utmp *ut, line, buffer;
+
+ /* Get name of tty connected to fd 0. Return NULL if not a tty or
+ if fd 0 isn't open. Note that a lot of documentation says that
+ getlogin() is based on the controlling terminal---what they
+ really mean is "the terminal connected to standard input". The
+ getlogin() implementation of DEC Unix, SunOS, Solaris, HP-UX all
+ return NULL if fd 0 has been closed, so this is the compatible
+ thing to do. Note that ttyname(open("/dev/tty")) on those
+ systems returns /dev/tty, so that is not a possible solution for
+ getlogin(). */
+ if (__ttyname_r (0, real_tty_path, sizeof (tty_pathname)) != 0)
+ return NULL;
+
+ real_tty_path += 5; /* Remove "/dev/". */
+
+ __setutent ();
+ strncpy (line.ut_line, real_tty_path, sizeof line.ut_line);
+ if (__getutline_r (&line, &buffer, &ut) < 0)
+ {
+ if (errno == ESRCH)
+ /* The caller expects ENOENT if nothing is found. */
+ __set_errno (ENOENT);
+ result = NULL;
+ }
+ else
+ {
+ strncpy (name, ut->ut_user, UT_NAMESIZE);
+ name[UT_NAMESIZE] = '\0';
+ result = name;
+ }
+
+ __endutent ();
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/getlogin_r.c b/libc/sysdeps/unix/getlogin_r.c
new file mode 100644
index 000000000..ba7badd05
--- /dev/null
+++ b/libc/sysdeps/unix/getlogin_r.c
@@ -0,0 +1,99 @@
+/* Reentrant function to return the current login name. Unix version.
+ Copyright (C) 1991,92,96,97,98,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <limits.h>
+#include <fcntl.h>
+
+#include <utmp.h>
+#include "../login/utmp-private.h"
+
+/* Return at most NAME_LEN characters of the login name of the user in NAME.
+ If it cannot be determined or some other error occurred, return the error
+ code. Otherwise return 0. */
+
+int
+getlogin_r (name, name_len)
+ char *name;
+ size_t name_len;
+{
+ char tty_pathname[2 + 2 * NAME_MAX];
+ char *real_tty_path = tty_pathname;
+ int result;
+ struct utmp *ut, line, buffer;
+
+ /* Get name of tty connected to fd 0. Return if not a tty or
+ if fd 0 isn't open. Note that a lot of documentation says that
+ getlogin() is based on the controlling terminal---what they
+ really mean is "the terminal connected to standard input". The
+ getlogin() implementation of DEC Unix, SunOS, Solaris, HP-UX all
+ return NULL if fd 0 has been closed, so this is the compatible
+ thing to do. Note that ttyname(open("/dev/tty")) on those
+ systems returns /dev/tty, so that is not a possible solution for
+ getlogin(). */
+
+ result = __ttyname_r (0, real_tty_path, sizeof (tty_pathname));
+
+ if (result != 0)
+ return result;
+
+ real_tty_path += 5; /* Remove "/dev/". */
+ strncpy (line.ut_line, real_tty_path, sizeof line.ut_line);
+
+ /* We don't use the normal entry points __setutent et al, because we
+ want setutent + getutline_r + endutent all to happen with the lock
+ held so that our search is thread-safe. */
+
+ __libc_lock_lock (__libc_utmp_lock);
+ (*__libc_utmp_jump_table->setutent) ();
+ result = (*__libc_utmp_jump_table->getutline_r) (&line, &buffer, &ut);
+ if (result < 0)
+ {
+ if (errno == ESRCH)
+ /* The caller expects ENOENT if nothing is found. */
+ result = ENOENT;
+ else
+ result = errno;
+ }
+ (*__libc_utmp_jump_table->endutent) ();
+ __libc_utmp_jump_table = &__libc_utmp_unknown_functions;
+ __libc_lock_unlock (__libc_utmp_lock);
+
+ if (result == 0)
+ {
+ size_t needed = strlen (ut->ut_user) + 1;
+
+ if (needed > name_len)
+ {
+ __set_errno (ERANGE);
+ result = ERANGE;
+ }
+ else
+ {
+ memcpy (name, ut->ut_user, needed);
+ result = 0;
+ }
+ }
+
+ return result;
+}
+libc_hidden_def (getlogin_r)
diff --git a/libc/sysdeps/unix/getpagesize.c b/libc/sysdeps/unix/getpagesize.c
new file mode 100644
index 000000000..6e62101ab
--- /dev/null
+++ b/libc/sysdeps/unix/getpagesize.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1991,1992,1995,1996,1997,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <sys/param.h>
+
+/* Return the system page size. */
+int
+__getpagesize ()
+{
+#ifdef EXEC_PAGESIZE
+ return EXEC_PAGESIZE;
+#else /* No EXEC_PAGESIZE. */
+#ifdef NBPG
+#ifndef CLSIZE
+#define CLSIZE 1
+#endif /* No CLSIZE. */
+ return NBPG * CLSIZE;
+#else /* No NBPG. */
+ return NBPC;
+#endif /* NBPG. */
+#endif /* EXEC_PAGESIZE. */
+}
+libc_hidden_def (__getpagesize)
+weak_alias (__getpagesize, getpagesize)
diff --git a/libc/sysdeps/unix/getppid.S b/libc/sysdeps/unix/getppid.S
new file mode 100644
index 000000000..a1821686a
--- /dev/null
+++ b/libc/sysdeps/unix/getppid.S
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991, 1992, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#ifdef SYS_getppid
+SYSCALL__ (getppid, 0)
+#else
+PSEUDO (__getppid, getpid, 0)
+ MOVE(r1, r0)
+#endif
+ ret
+PSEUDO_END(__getppid)
+
+weak_alias (__getppid, getppid)
diff --git a/libc/sysdeps/unix/grantpt.c b/libc/sysdeps/unix/grantpt.c
new file mode 100644
index 000000000..bdedbacec
--- /dev/null
+++ b/libc/sysdeps/unix/grantpt.c
@@ -0,0 +1,216 @@
+/* Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <grp.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "pty-private.h"
+
+
+/* Return the result of ptsname_r in the buffer pointed to by PTS,
+ which should be of length BUF_LEN. If it is too long to fit in
+ this buffer, a sufficiently long buffer is allocated using malloc,
+ and returned in PTS. 0 is returned upon success, -1 otherwise. */
+static int
+pts_name (int fd, char **pts, size_t buf_len)
+{
+ int rv;
+ char *buf = *pts;
+
+ for (;;)
+ {
+ char *new_buf;
+
+ if (buf_len)
+ {
+ rv = __ptsname_r (fd, buf, buf_len);
+ if (rv != 0)
+ {
+ if (rv == ENOTTY)
+ /* ptsname_r returns with ENOTTY to indicate
+ a descriptor not referring to a pty master.
+ For this condition, grantpt must return EINVAL. */
+ rv = EINVAL;
+ errno = rv; /* Not necessarily set by __ptsname_r. */
+ break;
+ }
+
+ if (memchr (buf, '\0', buf_len))
+ /* We succeeded and the returned name fit in the buffer. */
+ break;
+
+ /* Try again with a longer buffer. */
+ buf_len += buf_len; /* Double it */
+ }
+ else
+ /* No initial buffer; start out by mallocing one. */
+ buf_len = 128; /* First time guess. */
+
+ if (buf != *pts)
+ /* We've already malloced another buffer at least once. */
+ new_buf = (char *) realloc (buf, buf_len);
+ else
+ new_buf = (char *) malloc (buf_len);
+ if (! new_buf)
+ {
+ rv = -1;
+ __set_errno (ENOMEM);
+ break;
+ }
+ buf = new_buf;
+ }
+
+ if (rv == 0)
+ *pts = buf; /* Return buffer to the user. */
+ else if (buf != *pts)
+ free (buf); /* Free what we malloced when returning an error. */
+
+ return rv;
+}
+
+/* Change the ownership and access permission of the slave pseudo
+ terminal associated with the master pseudo terminal specified
+ by FD. */
+int
+grantpt (int fd)
+{
+ int retval = -1;
+#ifdef PATH_MAX
+ char _buf[PATH_MAX];
+#else
+ char _buf[512];
+#endif
+ char *buf = _buf;
+ struct stat64 st;
+ char *grtmpbuf;
+ struct group grbuf;
+ size_t grbuflen = __sysconf (_SC_GETGR_R_SIZE_MAX);
+ struct group *p;
+ uid_t uid;
+ gid_t gid;
+ pid_t pid;
+
+ if (pts_name (fd, &buf, sizeof (_buf)))
+ return -1;
+
+ if (__xstat64 (_STAT_VER, buf, &st) < 0)
+ goto cleanup;
+
+ /* Make sure that we own the device. */
+ uid = __getuid ();
+ if (st.st_uid != uid)
+ {
+ if (__chown (buf, uid, st.st_gid) < 0)
+ goto helper;
+ }
+
+ /* Get the group ID of the special `tty' group. */
+ if (grbuflen == (size_t) -1L)
+ /* `sysconf' does not support _SC_GETGR_R_SIZE_MAX.
+ Try a moderate value. */
+ grbuflen = 1024;
+ grtmpbuf = (char *) __alloca (grbuflen);
+ __getgrnam_r (TTY_GROUP, &grbuf, grtmpbuf, grbuflen, &p);
+ gid = p ? p->gr_gid : __getgid ();
+
+ /* Make sure the group of the device is that special group. */
+ if (st.st_gid != gid)
+ {
+ if (__chown (buf, uid, gid) < 0)
+ goto helper;
+ }
+
+ /* Make sure the permission mode is set to readable and writable by
+ the owner, and writable by the group. */
+ if ((st.st_mode & ACCESSPERMS) != (S_IRUSR|S_IWUSR|S_IWGRP))
+ {
+ if (__chmod (buf, S_IRUSR|S_IWUSR|S_IWGRP) < 0)
+ goto helper;
+ }
+
+ retval = 0;
+ goto cleanup;
+
+ /* We have to use the helper program. */
+ helper:
+
+ pid = __fork ();
+ if (pid == -1)
+ goto cleanup;
+ else if (pid == 0)
+ {
+ /* Disable core dumps. */
+ struct rlimit rl = { 0, 0 };
+ __setrlimit (RLIMIT_CORE, &rl);
+
+ /* We pass the master pseudo terminal as file descriptor PTY_FILENO. */
+ if (fd != PTY_FILENO)
+ if (__dup2 (fd, PTY_FILENO) < 0)
+ _exit (FAIL_EBADF);
+
+ execle (_PATH_PT_CHOWN, basename (_PATH_PT_CHOWN), NULL, NULL);
+ _exit (FAIL_EXEC);
+ }
+ else
+ {
+ int w;
+
+ if (__waitpid (pid, &w, 0) == -1)
+ goto cleanup;
+ if (!WIFEXITED (w))
+ __set_errno (ENOEXEC);
+ else
+ switch (WEXITSTATUS(w))
+ {
+ case 0:
+ retval = 0;
+ break;
+ case FAIL_EBADF:
+ __set_errno (EBADF);
+ break;
+ case FAIL_EINVAL:
+ __set_errno (EINVAL);
+ break;
+ case FAIL_EACCES:
+ __set_errno (EACCES);
+ break;
+ case FAIL_EXEC:
+ __set_errno (ENOEXEC);
+ break;
+
+ default:
+ assert(! "getpt: internal error: invalid exit code from pt_chown");
+ }
+ }
+
+ cleanup:
+ if (buf != _buf)
+ free (buf);
+
+ return retval;
+}
diff --git a/libc/sysdeps/unix/i386/brk.S b/libc/sysdeps/unix/i386/brk.S
new file mode 100644
index 000000000..d8dd96b4c
--- /dev/null
+++ b/libc/sysdeps/unix/i386/brk.S
@@ -0,0 +1,47 @@
+/* Copyright (C) 1991,92,93,95,97,2002,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#ifndef SYS_brk
+#define SYS_brk 17
+#endif
+
+.data
+.globl C_SYMBOL_NAME(__curbrk)
+C_LABEL(__curbrk)
+ .long C_SYMBOL_NAME(_end)
+
+.text
+SYSCALL__ (brk, 1)
+ movl 4(%esp), %eax
+#ifdef PIC
+ /* Standard PIC nonsense to store into `__curbrk' through the GOT. */
+ call L(here)
+L(here): popl %ecx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ecx
+ movl C_SYMBOL_NAME(__curbrk@GOT)(%ecx), %ecx
+ movl %eax, (%ecx)
+#else
+ movl %eax, C_SYMBOL_NAME(__curbrk)
+#endif
+ xorl %eax, %eax
+ ret
+PSEUDO_END (__brk)
+
+weak_alias (__brk, brk)
diff --git a/libc/sysdeps/unix/i386/dl-brk.S b/libc/sysdeps/unix/i386/dl-brk.S
new file mode 100644
index 000000000..eeb96544e
--- /dev/null
+++ b/libc/sysdeps/unix/i386/dl-brk.S
@@ -0,0 +1 @@
+#include <brk.S>
diff --git a/libc/sysdeps/unix/i386/fork.S b/libc/sysdeps/unix/i386/fork.S
new file mode 100644
index 000000000..b729d47f7
--- /dev/null
+++ b/libc/sysdeps/unix/i386/fork.S
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991,92,94,95,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+SYSCALL__ (fork, 0)
+ /* R1 is now 0 for the parent and 1 for the child. Decrement it to
+ make it -1 (all bits set) for the parent, and 0 (no bits set)
+ for the child. Then AND it with R0, so the parent gets
+ R0&-1==R0, and the child gets R0&0==0. */
+ decl r1
+ andl r1, r0
+ ret
+PSEUDO_END (__fork)
+libc_hidden_def (__fork)
+
+weak_alias (__fork, fork)
diff --git a/libc/sysdeps/unix/i386/pipe.S b/libc/sysdeps/unix/i386/pipe.S
new file mode 100644
index 000000000..1bdadc649
--- /dev/null
+++ b/libc/sysdeps/unix/i386/pipe.S
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991,92,93,95,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+SYSCALL__ (pipe, 1)
+ movl 4(%esp), scratch
+ movl %eax, (scratch)
+ movl r1, 4(scratch)
+ xorl %eax, %eax
+ ret
+PSEUDO_END (__pipe)
+
+libc_hidden_def (__pipe)
+weak_alias (__pipe, pipe)
diff --git a/libc/sysdeps/unix/i386/sigreturn.S b/libc/sysdeps/unix/i386/sigreturn.S
new file mode 100644
index 000000000..cf6f89e01
--- /dev/null
+++ b/libc/sysdeps/unix/i386/sigreturn.S
@@ -0,0 +1,27 @@
+/* Copyright (C) 1992, 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+.text
+ENTRY (__sigreturn)
+ addl $4, %esp /* Pop the return PC. */
+ DO_CALL (sigreturn, 0) /* Do the system call; it never returns. */
+ /* NOTREACHED */
+
+weak_alias (__sigreturn, sigreturn)
diff --git a/libc/sysdeps/unix/i386/start.c b/libc/sysdeps/unix/i386/start.c
new file mode 100644
index 000000000..e6c89ee3f
--- /dev/null
+++ b/libc/sysdeps/unix/i386/start.c
@@ -0,0 +1,2 @@
+#define DUMMIES dummy0
+#include <sysdeps/unix/start.c>
diff --git a/libc/sysdeps/unix/i386/syscall.S b/libc/sysdeps/unix/i386/syscall.S
new file mode 100644
index 000000000..b333c617c
--- /dev/null
+++ b/libc/sysdeps/unix/i386/syscall.S
@@ -0,0 +1,28 @@
+/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+.globl syscall_error
+ENTRY (syscall)
+ popl %ecx /* Pop return address into %ecx. */
+ popl %eax /* Pop syscall number into %eax. */
+ pushl %ecx /* Push back return address. */
+ .byte 0x9a, 0, 0, 0, 0, 7, 0 /* lcall $7, $0 -- gas bug */
+ jb JUMPTARGET(syscall_error)
+ ret
diff --git a/libc/sysdeps/unix/i386/sysdep.S b/libc/sysdeps/unix/i386/sysdep.S
new file mode 100644
index 000000000..3bc872add
--- /dev/null
+++ b/libc/sysdeps/unix/i386/sysdep.S
@@ -0,0 +1,106 @@
+/* Copyright (C) 1991,1992,1993,1994,1995,1996,1997,2000,2002,2004,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H
+#include <bits/errno.h>
+#include <bp-asm.h>
+#include <bp-sym.h>
+
+#ifdef IS_IN_rtld
+# include <dl-sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */
+#endif
+
+.globl C_SYMBOL_NAME(errno)
+.globl syscall_error
+
+#undef syscall_error
+#ifdef NO_UNDERSCORES
+__syscall_error:
+#else
+syscall_error:
+#endif
+#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN
+ /* We translate the system's EWOULDBLOCK error into EAGAIN.
+ The GNU C library always defines EWOULDBLOCK==EAGAIN.
+ EWOULDBLOCK_sys is the original number. */
+ cmpl $EWOULDBLOCK_sys, %eax /* Is it the old EWOULDBLOCK? */
+ jne notb /* Branch if not. */
+ movl $EAGAIN, %eax /* Yes; translate it to EAGAIN. */
+notb:
+#endif
+#ifndef PIC
+# if USE___THREAD
+# ifndef NO_TLS_DIRECT_SEG_REFS
+ movl %eax, %gs:C_SYMBOL_NAME(errno@NTPOFF)
+# else
+ movl %gs:0, %ecx
+ movl %eax, C_SYMBOL_NAME(errno@NTPOFF)(%ecx)
+# endif
+# elif !defined _LIBC_REENTRANT
+ movl %eax, C_SYMBOL_NAME(errno)
+# else
+ pushl %eax
+ PUSH_ERRNO_LOCATION_RETURN
+ call BP_SYM (__errno_location)
+ POP_ERRNO_LOCATION_RETURN
+ popl %ecx
+ movl %ecx, (%eax)
+# endif
+#else
+ /* The caller has pushed %ebx and then set it up to
+ point to the GOT before calling us through the PLT. */
+# if USE___THREAD
+ movl C_SYMBOL_NAME(errno@GOTNTPOFF)(%ebx), %ecx
+
+ /* Pop %ebx value saved before jumping here. */
+ popl %ebx
+# ifndef NO_TLS_DIRECT_SEG_REFS
+ addl %gs:0, %ecx
+ movl %eax, (%ecx)
+# else
+ movl %eax, %gs:0(%ecx)
+# endif
+# elif RTLD_PRIVATE_ERRNO
+ movl %eax, C_SYMBOL_NAME(rtld_errno@GOTOFF)(%ebx)
+
+ /* Pop %ebx value saved before jumping here. */
+ popl %ebx
+# elif !defined _LIBC_REENTRANT
+ movl C_SYMBOL_NAME(errno@GOT)(%ebx), %ecx
+
+ /* Pop %ebx value saved before jumping here. */
+ popl %ebx
+ movl %eax, (%ecx)
+# else
+ pushl %eax
+ PUSH_ERRNO_LOCATION_RETURN
+ call C_SYMBOL_NAME (BP_SYM (__errno_location)@PLT)
+ POP_ERRNO_LOCATION_RETURN
+ popl %ecx
+ /* Pop %ebx value saved before jumping here. */
+ popl %ebx
+ movl %ecx, (%eax)
+# endif
+#endif
+ movl $-1, %eax
+ ret
+
+#undef __syscall_error
+END (__syscall_error)
diff --git a/libc/sysdeps/unix/i386/sysdep.h b/libc/sysdeps/unix/i386/sysdep.h
new file mode 100644
index 000000000..d6b496223
--- /dev/null
+++ b/libc/sysdeps/unix/i386/sysdep.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991, 92, 93, 95, 96, 97 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/unix/sysdep.h>
+#include <sysdeps/i386/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+/* This is defined as a separate macro so that other sysdep.h files
+ can include this one and then redefine DO_CALL. */
+
+#define DO_CALL(syscall_name, args) \
+ lea SYS_ify (syscall_name), %eax; \
+ lcall $7, $0
+
+#define r0 %eax /* Normal return-value register. */
+#define r1 %edx /* Secondary return-value register. */
+#define scratch %ecx /* Call-clobbered register for random use. */
+#define MOVE(x,y) movl x, y
+
+#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/unix/i386/vfork.S b/libc/sysdeps/unix/i386/vfork.S
new file mode 100644
index 000000000..81d714878
--- /dev/null
+++ b/libc/sysdeps/unix/i386/vfork.S
@@ -0,0 +1,24 @@
+/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* Go directly into __vfork, don't do anything with the stack ptr. */
+
+ENTRY(vfork)
+ jmp __vfork
diff --git a/libc/sysdeps/unix/i386/wait.S b/libc/sysdeps/unix/i386/wait.S
new file mode 100644
index 000000000..49195a229
--- /dev/null
+++ b/libc/sysdeps/unix/i386/wait.S
@@ -0,0 +1,29 @@
+/* Copyright (C) 1991,92,93,95,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+SYSCALL__ (wait, 1)
+ movl 4(%esp), scratch /* Put status pointer in scratch register. */
+ testl scratch, scratch /* Is it non-nil? */
+ je null
+ movl r1, (scratch) /* Yes; store the status there. */
+null: ret
+PSEUDO_END (__wait)
+
+weak_alias (__wait, wait)
diff --git a/libc/sysdeps/unix/inet/Subdirs b/libc/sysdeps/unix/inet/Subdirs
new file mode 100644
index 000000000..4a191e299
--- /dev/null
+++ b/libc/sysdeps/unix/inet/Subdirs
@@ -0,0 +1,7 @@
+inet
+resolv
+hesiod
+sunrpc
+nis
+nscd
+streams
diff --git a/libc/sysdeps/unix/inet/syscalls.list b/libc/sysdeps/unix/inet/syscalls.list
new file mode 100644
index 000000000..df2f34eea
--- /dev/null
+++ b/libc/sysdeps/unix/inet/syscalls.list
@@ -0,0 +1,23 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+accept - accept Ci:iBN __libc_accept accept
+bind - bind i:ipi __bind bind
+connect - connect Ci:ipi __libc_connect __connect __connect_internal connect
+gethostid - gethostid i: gethostid
+gethostname - gethostname i:bn __gethostname gethostname
+getpeername - getpeername i:ibN __getpeername getpeername
+getsockname - getsockname i:ibN __getsockname getsockname
+getsockopt - getsockopt i:iiiBN getsockopt
+listen - listen i:ii __listen listen
+recv - recv Ci:ibni __libc_recv recv
+recvfrom - recvfrom Ci:ibniBN __libc_recvfrom __recvfrom recvfrom
+recvmsg - recvmsg Ci:ipi __libc_recvmsg __recvmsg recvmsg
+send - send Ci:ibni __libc_send __send send
+sendmsg - sendmsg Ci:ipi __libc_sendmsg __sendmsg sendmsg
+sendto - sendto Ci:ibnibn __libc_sendto __sendto sendto
+sethostid - sethostid i:i sethostid
+sethostname - sethostname i:pi sethostname
+setsockopt - setsockopt i:iiibn setsockopt __setsockopt
+shutdown - shutdown i:ii shutdown
+socket - socket i:iii __socket socket
+socketpair - socketpair i:iiif socketpair
diff --git a/libc/sysdeps/unix/ioctls-tmpl.c b/libc/sysdeps/unix/ioctls-tmpl.c
new file mode 100644
index 000000000..1c973c945
--- /dev/null
+++ b/libc/sysdeps/unix/ioctls-tmpl.c
@@ -0,0 +1,134 @@
+/* On SVR4, this #define is necessary to make <sys/ioctl.h> define
+ many of the ioctls. */
+#define BSD_COMP
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+/* On SunOS 4.1, <sys/ioctl.h> and <sys/termios.h> define some symbols
+ with different values, but <sys/termios.h> defines some ioctl symbols
+ not in <sys/ioctl.h>, so we need it. Our <sys/ioctl.h> should define
+ them with the values from Sun's <sys/ioctl.h>, not <sys/termios.h>.
+ So we include <sys/termios.h> and let <sys/ioctl.h> redefine things.
+ This produces some spurious warnings. */
+
+#ifdef HAVE_sys_termios_h
+#include <sys/termios.h>
+#endif
+
+/* This causes <sys/ioctl.h> to define some necessary data structure. */
+#ifdef sony_news
+#define KANJI
+#endif
+
+#include <sys/ioctl.h>
+
+#ifdef SIOCGIFCONF
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <net/if.h>
+#include <net/route.h>
+#if defined(SIOCGARP) && !defined(ARPOP_REQUEST)
+#include <net/if_arp.h>
+#endif
+#ifdef SIOCGNIT
+#ifdef HAVE_net_nit_h
+#include <net/nit.h>
+#else /* No net/nit.h. */
+#undef SIOCGNIT
+#undef SIOCSNIT
+#endif /* net/nit.h. */
+#endif /* SIOCGNIT. */
+#endif /* SIOCGIFCONF. */
+
+/* These exist on Sequents. */
+#ifdef SMIOSTATS
+#include <sec/sec.h>
+#include <sec/sm.h>
+#endif
+#ifdef SMIOGETREBOOT0
+#include <i386/cfg.h>
+#endif
+#ifdef ZIOCBCMD
+#include <zdc/zdc.h>
+#endif
+
+/* These exist under Ultrix, but I figured there may be others. */
+#ifdef DIOCGETPT
+#include <ufs/fs.h> /* for DIOC* */
+#endif
+#ifdef DEVGETGEOM
+#include <sys/devio.h>
+#endif
+
+#ifdef ultrix
+/* Ultrix has a conditional include that brings these in; we have to force
+ their inclusion when we actually compile them. */
+#undef TCGETA
+#undef TCSETA
+#undef TCSETAW
+#undef TCSETAF
+#undef TCGETP
+#undef TCSANOW
+#undef TCSADRAIN
+#undef TCSAFLUSH
+#ifdef ELSETPID
+#include <sys/un.h> /* get sockaddr_un for elcsd.h */
+#include <elcsd.h>
+#endif
+#ifdef DKIOCDOP
+#include <sys/dkio.h>
+#endif
+/* Couldn't find the header where the structures used by these are
+ defined; it looks like an unbundled LAT package or something. */
+#undef LIOCSOL
+#undef LIOCRES
+#undef LIOCCMD
+#undef LIOCINI
+#undef LIOCTTYI
+#undef LIOCCONN
+/* struct mtop hasn't been in sys/mtio.h since 4.1 */
+#undef MTIOCTOP
+#undef MTIOCGET
+#endif
+
+#if defined(__osf__) && defined(__alpha__)
+#include <sys/ioctl_compat.h> /* To get TIOCGETP, etc. */
+#include <alpha/pt.h> /* for DIOC* */
+#include <sys/mtio.h> /* for MTIOC* */
+/* The binlog_getstatus structure doesn't seem to be defined. */
+#undef BINLOG_GETSTATUS
+/* Can't find `struct ifdata' anywhere. */
+#undef SIOCMANREQ
+#undef SIOCGETEVENTS
+/* OSF/1 smells an awful lot like Ultrix. */
+#undef TCGETA
+#undef TCSETA
+#undef TCSETAF
+#undef TCSETAW
+/* This macro looks screwed in sys/devio.h. */
+#undef DEV_DISKPART
+/* This is in sys/dkio.h, but we don't need it. */
+#undef DKIOCACC
+#undef DKIOCDOP
+#undef DKIOCEXCL
+#undef DKIOCGET
+#undef DKIOCHDR
+/* Introduced by OSF/1 2.0. */
+#undef FIOPIPESTAT
+#undef SIOCSRREQR
+#undef SIOCSRREQW
+#undef SRVC_REQUEST
+#endif
+
+#define DEFINE(name, value) \
+ printf("#define %s 0x%.8x\n", (name), (value))
+
+int
+main()
+{
+ REQUESTS
+
+ exit(0);
+ return 0;
+}
diff --git a/libc/sysdeps/unix/ioctls.awk b/libc/sysdeps/unix/ioctls.awk
new file mode 100644
index 000000000..b05140af7
--- /dev/null
+++ b/libc/sysdeps/unix/ioctls.awk
@@ -0,0 +1,10 @@
+BEGIN { special = 0 }
+
+/REQUESTS/ { nreqs = split(requests, reqs)
+ for (i = 1; i <= nreqs; ++i)
+ printf "#ifdef\t%s\n DEFINE(\"%s\", %s);\n#endif\n", \
+ reqs[i], reqs[i], reqs[i]
+ special = 1 }
+
+
+{ if (special == 0) print $0; special = 0 }
diff --git a/libc/sysdeps/unix/make-syscalls.sh b/libc/sysdeps/unix/make-syscalls.sh
new file mode 100644
index 000000000..0ec8b28fd
--- /dev/null
+++ b/libc/sysdeps/unix/make-syscalls.sh
@@ -0,0 +1,342 @@
+#! /bin/sh
+
+# Usage: make-syscalls.sh ../sysdeps/unix/common
+# Expects $sysdirs in environment.
+
+##############################################################################
+
+# Syscall Signature Key Letters for BP Thunks:
+#
+# a: unchecked address (e.g., 1st arg to mmap)
+# b: non-NULL buffer (e.g., 2nd arg to read; return value from mmap)
+# B: optionally-NULL buffer (e.g., 4th arg to getsockopt)
+# f: buffer of 2 ints (e.g., 4th arg to socketpair)
+# F: 3rd arg to fcntl
+# i: scalar (any signedness & size: int, long, long long, enum, whatever)
+# I: 3rd arg to ioctl
+# n: scalar buffer length (e.g., 3rd arg to read)
+# N: pointer to value/return scalar buffer length (e.g., 6th arg to recvfrom)
+# p: non-NULL pointer to typed object (e.g., any non-void* arg)
+# P: optionally-NULL pointer to typed object (e.g., 2nd argument to gettimeofday)
+# s: non-NULL string (e.g., 1st arg to open)
+# S: optionally-NULL string (e.g., 1st arg to acct)
+# v: vararg scalar (e.g., optional 3rd arg to open)
+# V: byte-per-page vector (3rd arg to mincore)
+# W: wait status, optionally-NULL pointer to int (e.g., 2nd arg of wait4)
+
+ptr='[abBfFINpPsSWV]' # all pointer keyletters
+int='[inv]' # all scalar keyletters
+typ='[ifnNpP]' # typed-arg keyletters: we capture type for use in thunk
+
+##############################################################################
+
+thisdir=$1; shift
+
+echo ''
+echo \#### DIRECTORY = $thisdir
+# Check each sysdep dir with higher priority than this one,
+# and remove from $calls all the functions found in other dirs.
+# Punt when we reach the directory defining these syscalls.
+sysdirs=`for dir in $sysdirs; do
+ test $dir = $thisdir && break; echo $dir; done`
+echo \#### SYSDIRS = $sysdirs
+
+# Get the list of system calls for this directory.
+calls=`sed 's/#.*$//
+/^[ ]*$/d' $thisdir/syscalls.list`
+
+calls=`echo "$calls" |
+while read file caller rest; do
+ # Remove each syscall that is implemented by a file in $dir.
+ # If a syscall specified a "caller", then only compile that syscall
+ # if the caller function is also implemented in this directory.
+ srcfile=-;
+ for dir in $sysdirs; do
+ { test -f $dir/$file.c && srcfile=$dir/$file.c; } ||
+ { test -f $dir/$file.S && srcfile=$dir/$file.S; } ||
+ { test -f $dir/$file.s && srcfile=$dir/$file.s; } ||
+ { test x$caller != x- &&
+ { { test -f $dir/$caller.c && srcfile=$dir/$caller.c; } ||
+ { test -f $dir/$caller.S && srcfile=$dir/$caller.S; } ||
+ { test -f $dir/$caller.s && srcfile=$dir/$caller.s; }; }; } && break;
+ done;
+ echo $file $srcfile $caller $rest;
+done`
+
+# Any calls left?
+test -n "$calls" || exit 0
+
+# Emit rules to compile the syscalls remaining in $calls.
+echo "$calls" |
+while read file srcfile caller syscall args strong weak; do
+
+ case x"$syscall" in
+ x-) callnum=_ ;;
+ *)
+ # Figure out if $syscall is defined with a number in syscall.h.
+ callnum=-
+ eval `{ echo "#include <sysdep.h>";
+ echo "callnum=SYS_ify ($syscall)"; } |
+ $asm_CPP -D__OPTIMIZE__ - |
+ sed -n -e "/^callnum=.*$syscall/d" \
+ -e "/^\(callnum=\)[ ]*\(.*\)/s//\1'\2'/p"`
+ ;;
+ esac
+
+ cancellable=
+ noerrno=
+ case $args in
+ C*) cancellable=-cancel; args=`echo $args | sed 's/C:\?//'`;;
+ E*) noerrno=_NOERRNO; args=`echo $args | sed 's/E:\?//'`;;
+ V*) noerrno=_ERRVAL; args=`echo $args | sed 's/V:\?//'`;;
+ esac
+
+ # Derive the number of arguments from the argument signature
+ case $args in
+ [0-9]) nargs=$args;;
+ ?:) nargs=0;;
+ ?:?) nargs=1;;
+ ?:??) nargs=2;;
+ ?:???) nargs=3;;
+ ?:????) nargs=4;;
+ ?:?????) nargs=5;;
+ ?:??????) nargs=6;;
+ ?:???????) nargs=7;;
+ ?:????????) nargs=8;;
+ ?:?????????) nargs=9;;
+ esac
+
+ # Make sure only the first syscall rule is used, if multiple dirs
+ # define the same syscall.
+ echo ''
+ echo "#### CALL=$file NUMBER=$callnum ARGS=$args SOURCE=$srcfile"
+
+ case x$srcfile"$callnum" in
+ x--)
+ # Undefined callnum for an extra syscall.
+ if [ x$caller != x- ]; then
+ if [ x$noerrno != x ]; then
+ echo >&2 "$0: no number for $fileno, no-error syscall ($strong $weak)"
+ exit 2
+ fi
+ echo "unix-stub-syscalls += $strong $weak"
+ fi
+ ;;
+ x*-) ;; ### Do nothing for undefined callnum
+ x-*)
+ echo "ifeq (,\$(filter $file,\$(unix-syscalls)))"
+
+ case $weak in
+ *@*)
+ # The versioned symbols are only in the shared library.
+ echo "ifneq (,\$(filter .os,\$(object-suffixes)))"
+ ;;
+ esac
+ # Accumulate the list of syscall files for this directory.
+ echo "unix-syscalls += $file"
+ test x$caller = x- || echo "unix-extra-syscalls += $file"
+
+ # Emit a compilation rule for this syscall.
+ case $weak in
+ *@*)
+ # The versioned symbols are only in the shared library.
+ echo "\
+shared-only-routines += $file
+\$(objpfx)${file}.os: \\"
+ ;;
+ *)
+ echo "\
+\$(foreach o,\$(object-suffixes),\$(objpfx)$file\$o) \
+\$(foreach o,\$(object-suffixes),\$(objpfx)ptw-$file\$o) \
+\$(objpfx)rtld-$file.os: \\"
+ ;;
+ esac
+
+ echo " \$(common-objpfx)s-proto$cancellable.d"
+ case x"$callnum" in
+ x_)
+ echo "\
+ (echo '/* Dummy module requested by syscalls.list */'; \\"
+ ;;
+ x*)
+ echo "\
+ \$(make-target-directory)
+ (echo '#include <sysdep$cancellable.h>'; \\
+ echo 'PSEUDO$noerrno ($strong, $syscall, $nargs)'; \\
+ echo ' ret$noerrno'; \\
+ echo 'PSEUDO_END$noerrno($strong)'; \\
+ echo 'libc_hidden_def ($strong)'; \\"
+ ;;
+ esac
+
+ # Append any weak aliases or versions defined for this syscall function.
+
+ # A shortcoming in the current gas is that it will only allow one
+ # version-alias per symbol. So we create new strong aliases as needed.
+ vcount=""
+
+ for name in $weak; do
+ case $name in
+ *@@*)
+ base=`echo $name | sed 's/@@.*//'`
+ ver=`echo $name | sed 's/.*@@//'`
+ if test -z "$vcount" ; then
+ source=$strong
+ vcount=1
+ else
+ source="${strong}_${vcount}"
+ vcount=`expr $vcount + 1`
+ echo " echo 'strong_alias ($strong, $source)'; \\"
+ fi
+ echo " echo 'default_symbol_version($source, $base, $ver)'; \\"
+ ;;
+ *@*)
+ base=`echo $name | sed 's/@.*//'`
+ ver=`echo $name | sed 's/.*@//'`
+ if test -z "$vcount" ; then
+ source=$strong
+ vcount=1
+ else
+ source="${strong}_${vcount}"
+ vcount=`expr $vcount + 1`
+ echo " echo 'strong_alias ($strong, $source)'; \\"
+ fi
+ echo " echo 'symbol_version($source, $base, $ver)'; \\"
+ ;;
+ !*)
+ name=`echo $name | sed 's/.//'`
+ echo " echo 'strong_alias ($strong, $name)'; \\"
+ echo " echo 'libc_hidden_def ($name)'; \\"
+ ;;
+ *)
+ echo " echo 'weak_alias ($strong, $name)'; \\"
+ echo " echo 'libc_hidden_weak ($name)'; \\"
+ ;;
+ esac
+ done
+
+ # And finally, pipe this all into the compiler.
+ echo ' ) | $(compile-syscall)'
+
+ case $weak in
+ *@*)
+ # The versioned symbols are only in the shared library.
+ echo endif
+ ;;
+ esac
+
+ echo endif
+ ;;
+ esac
+
+ case x"$callnum",$srcfile,$args in
+ x[_-],-,* | x*,*.[sS],*V*) ;;
+ x*,-,*$ptr* | x*,*.[sS],*$ptr*)
+
+ nv_weak=`for name in $weak; do
+ case $name in
+ *@*) ;;
+ *) echo $name;;
+ esac; done`
+
+ # choose the name with the fewest leading underscores, preferably none
+ set `echo $strong $nv_weak |tr '@ \t' ' \n\n' |sort -r`
+ callname=$1
+
+ # convert signature string to individual numbered arg names
+ # e.g., i:ipbN -> i0 i1 p2 b3 N4
+ set `echo $args |
+ sed -e 's/^\(.\):\(.*\)/\2 <\10>/' \
+ -e 's/^\([^ ]\)\(.*\)/\2 <\11>/' \
+ -e 's/^\([^ ]\)\(.*\)/\2 <\12>/' \
+ -e 's/^\([^ ]\)\(.*\)/\2 <\13>/' \
+ -e 's/^\([^ ]\)\(.*\)/\2 <\14>/' \
+ -e 's/^\([^ ]\)\(.*\)/\2 <\15>/' \
+ -e 's/^\([^ ]\)\(.*\)/\2 <\16>/' \
+ -e 's/^\([^ ]\)\(.*\)/\2 <\17>/' \
+ -e 's/^\([^ ]\)\(.*\)/\2 <\18>/' \
+ -e 's/^\([^ ]\)\(.*\)/\2 <\19>/'`
+ rtn=$1; shift
+ args=$*
+ arglist=`echo $* |sed 's/ /, /g'`
+
+ # The best way to understand what's going on here is to examine
+ # the output in BUILDDIR/sysd-syscalls.
+
+ # generate makefile envelope & rule head
+ echo "ifeq (,\$(filter $file,\$(bp-thunks)))"
+ echo "bp-thunks += $file"
+ echo "\$(objpfx)\$(bppfx)$file.ob: \$(common-objpfx)s-proto-bp.d"
+
+ # generate macro head
+ echo " (echo '#define $callname(`echo $arglist | \
+ sed -e 's/[<>]//g'`) `echo $rtn | \
+ sed -e 's/<\('$typ'0\)>/\1v;/g' \
+ -e 's/<\(b0\)>/x0; extern char \1v;/g'` \\'; \\"
+
+ # generate extern decls of dummy variables for each arg
+ echo " echo '`echo $args | \
+ sed -e 's/<\('$typ'[1-9]\)>/extern \1, \1v;/g' \
+ -e 's/<\([abBFIsSV][1-9]\)>/extern char \1v;/g' \
+ -e 's/<\([Wv][1-9]\)>/extern int \1v;/g'` \\'; \\"
+
+ # generate bounded-pointer thunk declarator
+ echo " echo '`echo $rtn | \
+ sed -e 's/<\('$ptr'0\)>/__typeof (\1v) *__bounded/g' \
+ -e 's/<\('$int'0\)>/__typeof (\1v)/g'` BP_SYM ($strong) (`echo $arglist | \
+ sed -e 's/<\('$ptr'[1-9]\)>/__typeof (\1v) *__bounded \1a/g' \
+ -e 's/<\('$int'[1-9]\)>/__typeof (\1v) \1a/g'`) { \\'; \\"
+
+ # generate extern primitive syscall declaration
+ echo " echo ' extern `echo $rtn | \
+ sed -e 's/<\('$ptr'0\)>/__typeof (\1v) *__unbounded/g' \
+ -e 's/<\('$int'0\)>/__typeof (\1v)/g'` ($callname) (`echo $arglist | \
+ sed -e 's/<\('$ptr'[1-9]\)>/__typeof (\1v) *__unbounded/g' \
+ -e 's/<\('$int'[1-9]\)>/__typeof (\1v)/g'`); \\'; \\"
+
+ # generate call the primtive system call, optionally wrapping bounds
+ # around the result if the signature's return keyletter is `b'.
+ echo " echo ' return `echo $rtn |
+ sed -e 's/<b0>/BOUNDED_N (/' \
+ -e 's/<.0>//'`($callname) (`echo $arglist | \
+ sed -e 's/<\(a[1-9]\)>/__ptrvalue (\1a)/g' \
+ -e 's/<\(n[1-9]\)>, <\(V[1-9]\)>/\1a, CHECK_N_PAGES (\2a, \1a)/g' \
+ -e 's/<\(b[1-9]\)>, <\(n[1-9]\)>/CHECK_N (\1a, \2a), \2a/g' \
+ -e 's/<\(b[1-9]\)>, <\(N[1-9]\)>/CHECK_N (\1a, *CHECK_1 (\2a)), __ptrvalue (\2a)/g' \
+ -e 's/<\(B[1-9]\)>, <\(n[1-9]\)>/CHECK_N_NULL_OK (\1a, \2a), \2a/g' \
+ -e 's/<\(B[1-9]\)>, <\(N[1-9]\)>/CHECK_N_NULL_OK (\1a, *CHECK_1 (\2a)), __ptrvalue (\2a)/g' \
+ -e 's/<\(f[1-9]\)>/CHECK_N (\1a, 2)/g' \
+ -e 's/<\(i[1-9]\)>, <\(F[1-9]\)>/\1a, CHECK_FCNTL (\2a, \1a)/g' \
+ -e 's/<\(i[1-9]\)>, <\(I[1-9]\)>/\1a, CHECK_IOCTL (\2a, \1a)/g' \
+ -e 's/<\(p[1-9]\)>/CHECK_1 (\1a)/g' \
+ -e 's/<\([PW][1-9]\)>/CHECK_1_NULL_OK (\1a)/g' \
+ -e 's/<\(s[1-9]\)>/CHECK_STRING (\1a)/g' \
+ -e 's/<\(S[1-9]\)>/CHECK_STRING_NULL_OK (\1a)/g' \
+ -e 's/<\([ivn][1-9]\)>/\1a/g'`)`echo $rtn $args |
+ sed -e 's/<b0>.*<\(n[1-9]\)>.*/, \1a)/' \
+ -e 's/<.0>.*//'`; \\'; \\"
+
+ echo " echo '} \\'; \\"
+
+ echo " echo 'libc_hidden_def (BP_SYM ($strong)) \\'; \\"
+
+ # generate thunk aliases
+ for name in $nv_weak; do
+ echo " echo 'weak_alias (BP_SYM ($strong), BP_SYM ($name)) \\'; \\"
+ echo " echo 'libc_hidden_weak (BP_SYM ($name)) \\'; \\"
+ done
+
+ # wrap up
+ echo "\
+ echo ''; \\
+ echo '#include <bp-thunks.h>'; \\
+ ) | \$(COMPILE.c) -x c -o \$@ -"
+### Use this for debugging intermediate output:
+### ) >\$(@:.ob=.c)
+### \$(subst -c,-E,\$(COMPILE.c)) -o \$(@:.ob=.ib) \$(@:.ob=.c)
+### \$(COMPILE.c) -x cpp-output -o \$@ \$(@:.ob=.ib)"
+ echo endif
+ ;;
+ esac
+
+done
diff --git a/libc/sysdeps/unix/mk-local_lim.c b/libc/sysdeps/unix/mk-local_lim.c
new file mode 100644
index 000000000..5db0214cc
--- /dev/null
+++ b/libc/sysdeps/unix/mk-local_lim.c
@@ -0,0 +1,126 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifdef HAVE_SYS_LIMITS_H
+#include <sys/limits.h>
+#endif
+
+/* Generate bits/local_lim.h from the values defined in the system's
+ headers. */
+
+struct param
+ {
+ char *name;
+ int value;
+ };
+
+static struct param params[] =
+ {
+
+#if !defined (ARG_MAX) && defined (NCARGS)
+#define ARG_MAX NCARGS
+#endif
+#ifdef ARG_MAX
+ { "ARG_MAX", ARG_MAX },
+#endif
+
+#if !defined (CHILD_MAX) && defined (MAXUPRC)
+#define CHILD_MAX MAXUPRC
+#endif
+#ifdef CHILD_MAX
+ { "CHILD_MAX", CHILD_MAX },
+#endif
+
+#if !defined (LINK_MAX) && defined (MAXLINK)
+#define LINK_MAX MAXLINK
+#endif
+#ifdef LINK_MAX
+ { "LINK_MAX", LINK_MAX },
+#endif
+
+#if !defined (OPEN_MAX) && defined (NOFILE)
+#define OPEN_MAX NOFILE
+#endif
+#ifdef OPEN_MAX
+ { "OPEN_MAX", OPEN_MAX },
+#endif
+
+#if !defined (MAX_CANON) && defined (CANBSIZ)
+#define MAX_CANON CANBSIZ
+#endif
+#ifdef MAX_CANON
+ { "MAX_CANON", MAX_CANON },
+#endif
+
+#if !defined (NAME_MAX) && defined (MAXNAMLEN)
+#define NAME_MAX MAXNAMLEN
+#endif
+#ifndef NAME_MAX
+#define NAME_MAX 255 /* XXX ? */
+#endif
+ { "NAME_MAX", NAME_MAX },
+
+#if !defined (PATH_MAX) && defined (MAXPATHLEN)
+#define PATH_MAX MAXPATHLEN
+#endif
+#ifdef PATH_MAX
+ { "PATH_MAX", PATH_MAX },
+#endif
+
+#if !defined (SYMLOOP_MAX) && defined (MAXSYMLINKS)
+#define SYMLOOP_MAX MAXSYMLINKS
+#endif
+#ifdef SYMLOOP_MAX
+ { "SYMLOOP_MAX", SYMLOOP_MAX },
+#endif
+
+ { NULL, 0 }
+ };
+
+int
+main()
+{
+ extern char *ctime ();
+ extern time_t time ();
+ time_t now = time ((time_t *) NULL);
+ register struct param *p;
+
+ if (! params[0].name)
+ /* We have no information to give, so let the caller know. */
+ exit (1);
+
+ printf ("\
+/* Implementation-specific limits.\n\
+ Generated at %.24s. */\n\n", ctime (&now));
+
+ for (p = params; p->name != NULL; ++p)
+ printf ("#define %s %d\n", p->name, p->value);
+
+ exit (0);
+}
diff --git a/libc/sysdeps/unix/mkdir.c b/libc/sysdeps/unix/mkdir.c
new file mode 100644
index 000000000..dac88acb1
--- /dev/null
+++ b/libc/sysdeps/unix/mkdir.c
@@ -0,0 +1,98 @@
+/* Copyright (C) 1992, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <string.h>
+
+/* Create a directory named PATH with protections MODE. */
+int
+__mkdir (path, mode)
+ const char *path;
+ mode_t mode;
+{
+ char *cmd = __alloca (80 + strlen (path));
+ char *p;
+ int status;
+ mode_t mask;
+ int save;
+ struct stat statbuf;
+
+ if (path == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* Check for some errors. */
+ if (__stat (path, &statbuf) < 0)
+ {
+ if (errno != ENOENT)
+ return -1;
+ /* There is no file by that name. Good. */
+ }
+ else
+ {
+ __set_errno (EEXIST);
+ return -1;
+ }
+
+ /* Race condition, but how else to do it? */
+ mask = __umask (0777);
+ (void) __umask (mask);
+
+ p = cmd;
+ *p++ = 'm';
+ *p++ = 'k';
+ *p++ = 'd';
+ *p++ = 'i';
+ *p++ = 'r';
+ *p++ = ' ';
+
+ mode &= ~mask;
+ *p++ = '-';
+ *p++ = 'm';
+ *p++ = ' ';
+ *p++ = ((mode & 07000) >> 9) + '0';
+ *p++ = ((mode & 0700) >> 6) + '0';
+ *p++ = ((mode & 070) >> 3) + '0';
+ *p++ = ((mode & 07)) + '0';
+ *p++ = ' ';
+
+ strcpy (p, path);
+
+ save = errno;
+ /* If system doesn't set errno, but the mkdir fails, we really
+ have no idea what went wrong. EIO is the vaguest error I
+ can think of, so I'll use that. */
+ __set_errno (EIO);
+ status = system (cmd);
+ if (WIFEXITED (status) && WEXITSTATUS (status) == 0)
+ {
+ __set_errno (save);
+ return 0;
+ }
+ else
+ return -1;
+}
+
+weak_alias (__mkdir, mkdir)
diff --git a/libc/sysdeps/unix/mkfifo.c b/libc/sysdeps/unix/mkfifo.c
new file mode 100644
index 000000000..40676897e
--- /dev/null
+++ b/libc/sysdeps/unix/mkfifo.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+/* Create a named pipe (FIFO) named PATH with protections MODE. */
+int
+mkfifo (const char *path, mode_t mode)
+{
+ dev_t dev = 0;
+ return __xmknod (_MKNOD_VER, path, mode | S_IFIFO, &dev);
+}
diff --git a/libc/sysdeps/unix/mkfifoat.c b/libc/sysdeps/unix/mkfifoat.c
new file mode 100644
index 000000000..5c4da2a98
--- /dev/null
+++ b/libc/sysdeps/unix/mkfifoat.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/stat.h>
+
+
+/* Create a new FIFO with permission bits MODE. But interpret
+ relative PATH names relative to the directory associated with FD. */
+int
+mkfifoat (fd, file, mode)
+ int fd;
+ const char *file;
+ mode_t mode;
+{
+ dev_t dev = 0;
+ return __xmknodat (_MKNOD_VER, fd, file, mode | S_IFIFO, &dev);
+}
diff --git a/libc/sysdeps/unix/mman/syscalls.list b/libc/sysdeps/unix/mman/syscalls.list
new file mode 100644
index 000000000..7db8eb772
--- /dev/null
+++ b/libc/sysdeps/unix/mman/syscalls.list
@@ -0,0 +1,11 @@
+# This interface desciption corresponds to the POSIX.1 description. The
+# 4.4BSD interface is slightly different since the `msync' function takes
+# only 2 arguments.
+
+# File name Caller Syscall name # args Strong name Weak names
+
+madvise - madvise i:pii madvise
+mmap - mmap b:aniiii __mmap mmap
+mprotect - mprotect i:aii __mprotect mprotect
+msync - msync Ci:aii __libc_msync msync
+munmap - munmap i:ai __munmap munmap
diff --git a/libc/sysdeps/unix/nice.c b/libc/sysdeps/unix/nice.c
new file mode 100644
index 000000000..eb26c43a6
--- /dev/null
+++ b/libc/sysdeps/unix/nice.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1992, 1996, 1997, 2001, 2002, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/resource.h>
+
+/* Increment the scheduling priority of the calling process by INCR.
+ The superuser may use a negative INCR to decrement the priority. */
+int
+nice (int incr)
+{
+ int save;
+ int prio;
+ int result;
+
+ /* -1 is a valid priority, so we use errno to check for an error. */
+ save = errno;
+ __set_errno (0);
+ prio = getpriority (PRIO_PROCESS, 0);
+ if (prio == -1)
+ {
+ if (errno != 0)
+ return -1;
+ else
+ __set_errno (save);
+ }
+
+ result = setpriority (PRIO_PROCESS, 0, prio + incr);
+ if (result == -1)
+ {
+ if (errno == EACCES)
+ errno = EPERM;
+ return -1;
+ }
+ return getpriority (PRIO_PROCESS, 0);
+}
diff --git a/libc/sysdeps/unix/opendir.c b/libc/sysdeps/unix/opendir.c
new file mode 100644
index 000000000..6aa738fb6
--- /dev/null
+++ b/libc/sysdeps/unix/opendir.c
@@ -0,0 +1,179 @@
+/* Copyright (C) 1991-1996,98,2000-2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <dirstream.h>
+#include <not-cancel.h>
+
+
+/* opendir() must not accidentally open something other than a directory.
+ Some OS's have kernel support for that, some don't. In the worst
+ case we have to stat() before the open() AND fstat() after.
+
+ We have to test at runtime for kernel support since libc may have
+ been compiled with different headers to the kernel it's running on.
+ This test can't be done reliably in the general case. We'll use
+ /dev/null, which if it's not a device lots of stuff will break, as
+ a guinea pig. It may be missing in chroot environments, so we
+ make sure to fail safe. */
+#ifdef O_DIRECTORY
+# ifdef O_DIRECTORY_WORKS
+# define o_directory_works 1
+# define tryopen_o_directory() while (1) /* This must not be called. */
+# else
+static int o_directory_works;
+
+static void
+tryopen_o_directory (void)
+{
+ int serrno = errno;
+ int x = open_not_cancel_2 ("/dev/null", O_RDONLY|O_NDELAY|O_DIRECTORY);
+
+ if (x >= 0)
+ {
+ close_not_cancel_no_status (x);
+ o_directory_works = -1;
+ }
+ else if (errno != ENOTDIR)
+ o_directory_works = -1;
+ else
+ o_directory_works = 1;
+
+ __set_errno (serrno);
+}
+# endif
+# define EXTRA_FLAGS O_DIRECTORY
+#else
+# define EXTRA_FLAGS 0
+#endif
+
+
+/* Open a directory stream on NAME. */
+DIR *
+__opendir (const char *name)
+{
+ struct stat64 statbuf;
+
+ if (__builtin_expect (name[0], '\1') == '\0')
+ {
+ /* POSIX.1-1990 says an empty name gets ENOENT;
+ but `open' might like it fine. */
+ __set_errno (ENOENT);
+ return NULL;
+ }
+
+#ifdef O_DIRECTORY
+ /* Test whether O_DIRECTORY works. */
+ if (o_directory_works == 0)
+ tryopen_o_directory ();
+
+ /* We can skip the expensive `stat' call if O_DIRECTORY works. */
+ if (o_directory_works < 0)
+#endif
+ {
+ /* We first have to check whether the name is for a directory. We
+ cannot do this after the open() call since the open/close operation
+ performed on, say, a tape device might have undesirable effects. */
+ if (__builtin_expect (__xstat64 (_STAT_VER, name, &statbuf), 0) < 0)
+ return NULL;
+ if (__builtin_expect (! S_ISDIR (statbuf.st_mode), 0))
+ {
+ __set_errno (ENOTDIR);
+ return NULL;
+ }
+ }
+
+ int fd = open_not_cancel_2 (name, O_RDONLY|O_NDELAY|EXTRA_FLAGS|O_LARGEFILE);
+ if (__builtin_expect (fd, 0) < 0)
+ return NULL;
+
+ /* Now make sure this really is a directory and nothing changed since
+ the `stat' call. We do not have to perform the test for the
+ descriptor being associated with a directory if we know the
+ O_DIRECTORY flag is honored by the kernel. */
+ if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &statbuf), 0) < 0)
+ goto lose;
+#ifdef O_DIRECTORY
+ if (o_directory_works <= 0)
+#endif
+ {
+ if (__builtin_expect (! S_ISDIR (statbuf.st_mode), 0))
+ {
+ __set_errno (ENOTDIR);
+ lose:
+ close_not_cancel_no_status (fd);
+ return NULL;
+ }
+ }
+
+ return __alloc_dir (fd, true, &statbuf);
+}
+weak_alias (__opendir, opendir)
+
+
+DIR *
+internal_function
+__alloc_dir (int fd, bool close_fd, const struct stat64 *statp)
+{
+ if (__builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0)
+ goto lose;
+
+ size_t allocation;
+#ifdef _STATBUF_ST_BLKSIZE
+ if (__builtin_expect ((size_t) statp->st_blksize >= sizeof (struct dirent64),
+ 1))
+ allocation = statp->st_blksize;
+ else
+#endif
+ allocation = (BUFSIZ < sizeof (struct dirent64)
+ ? sizeof (struct dirent64) : BUFSIZ);
+
+ const int pad = -sizeof (DIR) % __alignof__ (struct dirent64);
+
+ DIR *dirp = (DIR *) malloc (sizeof (DIR) + allocation + pad);
+ if (dirp == NULL)
+ lose:
+ {
+ if (close_fd)
+ {
+ int save_errno = errno;
+ close_not_cancel_no_status (fd);
+ __set_errno (save_errno);
+ }
+ return NULL;
+ }
+ memset (dirp, '\0', sizeof (DIR));
+ dirp->data = (char *) (dirp + 1) + pad;
+ dirp->allocation = allocation;
+ dirp->fd = fd;
+
+ __libc_lock_init (dirp->lock);
+
+ return dirp;
+}
diff --git a/libc/sysdeps/unix/powerpc/sysdep.h b/libc/sysdeps/unix/powerpc/sysdep.h
new file mode 100644
index 000000000..90c1e49e8
--- /dev/null
+++ b/libc/sysdeps/unix/powerpc/sysdep.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 1991, 92, 93, 95, 96, 97, 1999, 2002
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/unix/sysdep.h>
+#include <bits/wordsize.h>
+#if __WORDSIZE == 64
+#include <sysdeps/powerpc/powerpc64/sysdep.h>
+#else
+#include <sysdeps/powerpc/powerpc32/sysdep.h>
+#endif
diff --git a/libc/sysdeps/unix/readdir.c b/libc/sysdeps/unix/readdir.c
new file mode 100644
index 000000000..4a0f0890e
--- /dev/null
+++ b/libc/sysdeps/unix/readdir.c
@@ -0,0 +1,120 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,99,2000,02
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <string.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <assert.h>
+
+#include <dirstream.h>
+
+#ifndef __READDIR
+# define __READDIR __readdir
+# define __GETDENTS __getdents
+# define DIRENT_TYPE struct dirent
+# define __READDIR_ALIAS
+#endif
+
+/* Read a directory entry from DIRP. */
+DIRENT_TYPE *
+__READDIR (DIR *dirp)
+{
+ DIRENT_TYPE *dp;
+ int saved_errno = errno;
+
+ __libc_lock_lock (dirp->lock);
+
+ do
+ {
+ size_t reclen;
+
+ if (dirp->offset >= dirp->size)
+ {
+ /* We've emptied out our buffer. Refill it. */
+
+ size_t maxread;
+ ssize_t bytes;
+
+#ifndef _DIRENT_HAVE_D_RECLEN
+ /* Fixed-size struct; must read one at a time (see below). */
+ maxread = sizeof *dp;
+#else
+ maxread = dirp->allocation;
+#endif
+
+ bytes = __GETDENTS (dirp->fd, dirp->data, maxread);
+ if (bytes <= 0)
+ {
+ /* On some systems getdents fails with ENOENT when the
+ open directory has been rmdir'd already. POSIX.1
+ requires that we treat this condition like normal EOF. */
+ if (bytes < 0 && errno == ENOENT)
+ bytes = 0;
+
+ /* Don't modifiy errno when reaching EOF. */
+ if (bytes == 0)
+ __set_errno (saved_errno);
+ dp = NULL;
+ break;
+ }
+ dirp->size = (size_t) bytes;
+
+ /* Reset the offset into the buffer. */
+ dirp->offset = 0;
+ }
+
+ dp = (DIRENT_TYPE *) &dirp->data[dirp->offset];
+
+#ifdef _DIRENT_HAVE_D_RECLEN
+ reclen = dp->d_reclen;
+#else
+ /* The only version of `struct dirent*' that lacks `d_reclen'
+ is fixed-size. */
+ assert (sizeof dp->d_name > 1);
+ reclen = sizeof *dp;
+ /* The name is not terminated if it is the largest possible size.
+ Clobber the following byte to ensure proper null termination. We
+ read jst one entry at a time above so we know that byte will not
+ be used later. */
+ dp->d_name[sizeof dp->d_name] = '\0';
+#endif
+
+ dirp->offset += reclen;
+
+#ifdef _DIRENT_HAVE_D_OFF
+ dirp->filepos = dp->d_off;
+#else
+ dirp->filepos += reclen;
+#endif
+
+ /* Skip deleted files. */
+ } while (dp->d_ino == 0);
+
+ __libc_lock_unlock (dirp->lock);
+
+ return dp;
+}
+
+#ifdef __READDIR_ALIAS
+weak_alias (__readdir, readdir)
+#endif
diff --git a/libc/sysdeps/unix/readdir_r.c b/libc/sysdeps/unix/readdir_r.c
new file mode 100644
index 000000000..f84709e73
--- /dev/null
+++ b/libc/sysdeps/unix/readdir_r.c
@@ -0,0 +1,127 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,02
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <string.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <assert.h>
+
+#include <dirstream.h>
+
+#ifndef __READDIR_R
+# define __READDIR_R __readdir_r
+# define __GETDENTS __getdents
+# define DIRENT_TYPE struct dirent
+# define __READDIR_R_ALIAS
+#endif
+
+/* Read a directory entry from DIRP. */
+int
+__READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result)
+{
+ DIRENT_TYPE *dp;
+ size_t reclen;
+ const int saved_errno = errno;
+
+ __libc_lock_lock (dirp->lock);
+
+ do
+ {
+ if (dirp->offset >= dirp->size)
+ {
+ /* We've emptied out our buffer. Refill it. */
+
+ size_t maxread;
+ ssize_t bytes;
+
+#ifndef _DIRENT_HAVE_D_RECLEN
+ /* Fixed-size struct; must read one at a time (see below). */
+ maxread = sizeof *dp;
+#else
+ maxread = dirp->allocation;
+#endif
+
+ bytes = __GETDENTS (dirp->fd, dirp->data, maxread);
+ if (bytes <= 0)
+ {
+ /* On some systems getdents fails with ENOENT when the
+ open directory has been rmdir'd already. POSIX.1
+ requires that we treat this condition like normal EOF. */
+ if (bytes < 0 && errno == ENOENT)
+ {
+ bytes = 0;
+ __set_errno (saved_errno);
+ }
+
+ dp = NULL;
+ /* Reclen != 0 signals that an error occurred. */
+ reclen = bytes != 0;
+ break;
+ }
+ dirp->size = (size_t) bytes;
+
+ /* Reset the offset into the buffer. */
+ dirp->offset = 0;
+ }
+
+ dp = (DIRENT_TYPE *) &dirp->data[dirp->offset];
+
+#ifdef _DIRENT_HAVE_D_RECLEN
+ reclen = dp->d_reclen;
+#else
+ /* The only version of `struct dirent*' that lacks `d_reclen'
+ is fixed-size. */
+ assert (sizeof dp->d_name > 1);
+ reclen = sizeof *dp;
+ /* The name is not terminated if it is the largest possible size.
+ Clobber the following byte to ensure proper null termination. We
+ read just one entry at a time above so we know that byte will not
+ be used later. */
+ dp->d_name[sizeof dp->d_name] = '\0';
+#endif
+
+ dirp->offset += reclen;
+
+#ifdef _DIRENT_HAVE_D_OFF
+ dirp->filepos = dp->d_off;
+#else
+ dirp->filepos += reclen;
+#endif
+
+ /* Skip deleted files. */
+ }
+ while (dp->d_ino == 0);
+
+ if (dp != NULL)
+ *result = memcpy (entry, dp, reclen);
+ else
+ *result = NULL;
+
+ __libc_lock_unlock (dirp->lock);
+
+ return dp != NULL ? 0 : reclen ? errno : 0;
+}
+
+#ifdef __READDIR_R_ALIAS
+weak_alias (__readdir_r, readdir_r)
+#endif
diff --git a/libc/sysdeps/unix/rewinddir.c b/libc/sysdeps/unix/rewinddir.c
new file mode 100644
index 000000000..051e93595
--- /dev/null
+++ b/libc/sysdeps/unix/rewinddir.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991, 1995-1998, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <dirstream.h>
+
+/* Rewind DIRP to the beginning of the directory. */
+/* XXX should be __rewinddir ? */
+void
+rewinddir (dirp)
+ DIR *dirp;
+{
+ __libc_lock_lock (dirp->lock);
+ (void) __lseek (dirp->fd, (off_t) 0, SEEK_SET);
+ dirp->filepos = 0;
+ dirp->offset = 0;
+ dirp->size = 0;
+ __libc_lock_unlock (dirp->lock);
+}
diff --git a/libc/sysdeps/unix/rmdir.c b/libc/sysdeps/unix/rmdir.c
new file mode 100644
index 000000000..ac68d280c
--- /dev/null
+++ b/libc/sysdeps/unix/rmdir.c
@@ -0,0 +1,78 @@
+/* Copyright (C) 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <string.h>
+
+/* Create a directory named PATH with protections MODE. */
+int
+__rmdir (path)
+ const char *path;
+{
+ char *cmd = __alloca (80 + strlen (path));
+ char *p;
+ int status;
+ int save;
+ struct stat statbuf;
+
+ if (path == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* Check for some errors. */
+ if (__stat (path, &statbuf) < 0)
+ return -1;
+ if (!S_ISDIR (statbuf.st_mode))
+ {
+ __set_errno (ENOTDIR);
+ return -1;
+ }
+
+ p = cmd;
+ *p++ = 'r';
+ *p++ = 'm';
+ *p++ = 'd';
+ *p++ = 'i';
+ *p++ = 'r';
+ *p++ = ' ';
+
+ strcpy (p, path);
+
+ save = errno;
+ /* If system doesn't set errno, but the rmdir fails, we really
+ have no idea what went wrong. EIO is the vaguest error I
+ can think of, so I'll use that. */
+ __set_errno (EIO);
+ status = system (cmd);
+ if (WIFEXITED (status) && WEXITSTATUS (status) == 0)
+ {
+ return 0;
+ __set_errno (save);
+ }
+ else
+ return -1;
+}
+
+weak_alias (__rmdir, rmdir)
diff --git a/libc/sysdeps/unix/s-proto-bp.S b/libc/sysdeps/unix/s-proto-bp.S
new file mode 100644
index 000000000..ba0363e16
--- /dev/null
+++ b/libc/sysdeps/unix/s-proto-bp.S
@@ -0,0 +1,4 @@
+/* This file exists just to have its dependencies determined.
+ Those dependencies are then used for the bp thunk objects. */
+
+#include <bp-thunks.h>
diff --git a/libc/sysdeps/unix/s-proto-cancel.S b/libc/sysdeps/unix/s-proto-cancel.S
new file mode 100644
index 000000000..042be3c8d
--- /dev/null
+++ b/libc/sysdeps/unix/s-proto-cancel.S
@@ -0,0 +1,5 @@
+/* This file exists just to have its dependencies determined.
+ Those dependencies are then used for the objects of the cancellable
+ system calls. */
+
+#include <sysdep-cancel.h>
diff --git a/libc/sysdeps/unix/s-proto.S b/libc/sysdeps/unix/s-proto.S
new file mode 100644
index 000000000..52a197036
--- /dev/null
+++ b/libc/sysdeps/unix/s-proto.S
@@ -0,0 +1,4 @@
+/* This file exists just to have its dependencies determined.
+ Those dependencies are then used for the simple system call objects. */
+
+#include <sysdep.h>
diff --git a/libc/sysdeps/unix/seekdir.c b/libc/sysdeps/unix/seekdir.c
new file mode 100644
index 000000000..1790e6237
--- /dev/null
+++ b/libc/sysdeps/unix/seekdir.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1991,1995,1996,1997,1999,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <dirstream.h>
+
+/* Seek to position POS in DIRP. */
+/* XXX should be __seekdir ? */
+void
+seekdir (dirp, pos)
+ DIR *dirp;
+ long int pos;
+{
+ __libc_lock_lock (dirp->lock);
+ (void) __lseek (dirp->fd, pos, SEEK_SET);
+ dirp->size = 0;
+ dirp->offset = 0;
+ dirp->filepos = pos;
+ __libc_lock_unlock (dirp->lock);
+}
diff --git a/libc/sysdeps/unix/setxid.h b/libc/sysdeps/unix/setxid.h
new file mode 100644
index 000000000..c18e2d4a6
--- /dev/null
+++ b/libc/sysdeps/unix/setxid.h
@@ -0,0 +1,4 @@
+#include <sysdep.h>
+
+#define INLINE_SETXID_SYSCALL(name, nr, args...) \
+ INLINE_SYSCALL (name, nr, args)
diff --git a/libc/sysdeps/unix/sh/sysdep.S b/libc/sysdeps/unix/sh/sysdep.S
new file mode 100644
index 000000000..802d51f3b
--- /dev/null
+++ b/libc/sysdeps/unix/sh/sysdep.S
@@ -0,0 +1,110 @@
+/* Copyright (C) 1999, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H
+#include <bits/errno.h>
+
+ENTRY(__syscall_error)
+#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN
+ /* We translate the system's EWOULDBLOCK error into EAGAIN.
+ The GNU C library always defines EWOULDBLOCK==EAGAIN.
+ EWOULDBLOCK_sys is the original number. */
+ mov.l .L1, r1
+ cmp/eq r1, r0
+ bf skip
+ nop
+ mov.l .L2, r0
+skip:
+#endif
+ /* Store it in errno... */
+#ifndef SHARED
+#ifndef _LIBC_REENTRANT
+ mov.l .L3, r1
+ mov.l r0, @r1
+#else
+ mov.l .L3, r1
+ sts.l pr, @-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (pr, 0)
+ jsr @r1
+ mov.l r0, @-r15
+ cfi_adjust_cfa_offset (4)
+ mov.l @r15+, r1
+ cfi_adjust_cfa_offset (-4)
+ lds.l @r15+, pr
+ cfi_adjust_cfa_offset (-4)
+ mov.l r1, @r0
+#endif
+#else
+ mov.l r12, @-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (r12, 0)
+#ifndef _LIBC_REENTRANT
+ mov r0, r2
+ mov.l 0f, r12
+ mova 0f, r0
+ add r0, r12
+ mov.l .L3, r0
+ mov.l @(r0,r12), r1
+ mov.l r2, @r1
+#else
+ mov.l r0, @-r15
+ cfi_adjust_cfa_offset (4)
+ sts.l pr, @-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (pr, 0)
+ mov.l 0f, r12
+ mova 0f, r0
+ add r0, r12
+ mov.l .L3, r1
+ mova .L3, r0
+ add r0, r1
+ jsr @r1
+ nop
+ lds.l @r15+, pr
+ mov.l @r15+, r1
+ mov.l r1, @r0
+#endif
+ mov.l @r15+, r12
+#endif
+ /* And just kick back a -1. */
+ rts
+ mov #-1, r0
+
+ .align 2
+#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN
+.L1: .long EWOULDBLOCK_sys
+.L2: .long EAGAIN
+#endif
+#ifndef SHARED
+#ifndef _LIBC_REENTRANT
+.L3: .long C_SYMBOL_NAME(errno)
+#else
+.L3: .long C_SYMBOL_NAME(__errno_location)
+#endif
+#else
+0:
+ .long _GLOBAL_OFFSET_TABLE_
+#ifndef _LIBC_REENTRANT
+.L3: .long C_SYMBOL_NAME(errno@GOT)
+#else
+.L3: .long C_SYMBOL_NAME(__errno_location@PLT)
+#endif
+#endif
+END(__syscall_error)
diff --git a/libc/sysdeps/unix/sh/sysdep.h b/libc/sysdeps/unix/sh/sysdep.h
new file mode 100644
index 000000000..bf1ac0fd4
--- /dev/null
+++ b/libc/sysdeps/unix/sh/sysdep.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/unix/sysdep.h>
+#include <sysdeps/sh/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+#define ret rts ; nop
+
+/* The sh move insn is s, d. */
+#define MOVE(x,y) mov x , y
+
+#endif
diff --git a/libc/sysdeps/unix/siglist.c b/libc/sysdeps/unix/siglist.c
new file mode 100644
index 000000000..821a2b048
--- /dev/null
+++ b/libc/sysdeps/unix/siglist.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <libintl.h>
+
+/* This is a list of all known signal numbers. */
+
+const char *const _sys_siglist[] =
+ {
+ N_("Signal 0"),
+ N_("Hangup"),
+ N_("Interrupt"),
+ N_("Quit"),
+ N_("Illegal instruction"),
+ N_("Trace/breakpoint trap"),
+ N_("IOT trap"),
+ N_("EMT trap"),
+ N_("Floating point exception"),
+ N_("Killed"),
+ N_("Bus error"),
+ N_("Segmentation fault"),
+ N_("Bad system call"),
+ N_("Broken pipe"),
+ N_("Alarm clock"),
+ N_("Terminated"),
+ N_("Urgent I/O condition"),
+ N_("Stopped (signal)"),
+ N_("Stopped"),
+ N_("Continued"),
+ N_("Child exited"),
+ N_("Stopped (tty input)"),
+ N_("Stopped (tty output)"),
+ N_("I/O possible"),
+ N_("CPU time limit exceeded"),
+ N_("File size limit exceeded"),
+ N_("Virtual timer expired"),
+ N_("Profiling timer expired"),
+ N_("Window changed"),
+ N_("Resource lost"),
+ N_("User defined signal 1"),
+ N_("User defined signal 2"),
+ NULL
+ };
+strong_alias (_sys_siglist, _sys_siglist_internal)
+
+weak_alias (_sys_siglist, sys_siglist)
diff --git a/libc/sysdeps/unix/snarf-ioctls b/libc/sysdeps/unix/snarf-ioctls
new file mode 100755
index 000000000..e6352bea7
--- /dev/null
+++ b/libc/sysdeps/unix/snarf-ioctls
@@ -0,0 +1,49 @@
+#!/bin/sh
+# Copyright (C) 1991, 1992, 1995, 1997 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+sysincludedir=${sysincludedir-/usr/include}
+
+if [ ! "$snarfexclude" ]; then
+ # Filter out some headers which cause trouble.
+ # Reportedly a bug in sunos4.1.2's sed makes this lose if
+ # the two cmds are in a single sed invocation.
+ snarfexclude="`echo !${sysincludedir}/sys/param.h! \
+ !${sysincludedir}/sys/time.h! \
+ !${sysincludedir}/sys/types.h! \
+ | sed 's,/,\\\\/,g' \
+ | sed 's,!\\([^!]*\\)!,-e /\\1/d,g'`"
+fi
+
+for file in $*; do
+ sed -n 's/^#define[ ]*\([A-Z][A-Z0-9_]*\)[ ][ ]*[^ ].*$/\1/p' \
+ < $file
+
+ snarfexclude="$snarfexclude \
+ `echo $file | sed -e 's,/,\\\\/,g' -e 's,^.*$,-e /&/d,'`"
+ export snarfexclude
+
+ included="`sed -n < $file \
+ -e 's,^#include[ ]*<\(.*\)>.*$,'${sysincludedir}'/\1,p'\
+ | sed $snarfexclude`"
+ if [ "$included" ]; then
+ $0 $included
+ fi
+done
+
+exit 0
diff --git a/libc/sysdeps/unix/sockatmark.c b/libc/sysdeps/unix/sockatmark.c
new file mode 100644
index 000000000..a2476415a
--- /dev/null
+++ b/libc/sysdeps/unix/sockatmark.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+/* Determine wheter socket is at a out-of-band mark. */
+int
+sockatmark (fd)
+ int fd;
+{
+ int answ;
+
+ return __ioctl (fd, SIOCATMARK, &answ) == -1 ? -1 : answ;
+}
diff --git a/libc/sysdeps/unix/sparc/brk.S b/libc/sysdeps/unix/sparc/brk.S
new file mode 100644
index 000000000..29255fc68
--- /dev/null
+++ b/libc/sysdeps/unix/sparc/brk.S
@@ -0,0 +1,51 @@
+/* Copyright (C) 1993, 1995, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#ifndef SYS_brk
+#define SYS_brk 17
+#endif
+
+#ifndef C_SYMBOL_NAME
+#define C_SYMBOL_NAME(name) _##name
+#endif
+
+.data
+.global C_SYMBOL_NAME(__curbrk)
+C_LABEL(__curbrk)
+ .long C_SYMBOL_NAME(_end)
+
+.text
+ENTRY (__brk)
+ add %o0, 7, %o0
+ andn %o0, 7, %o0
+ mov SYS_brk, %g1
+ mov %o0, %o1 /* Save rounded value. */
+ ta %g0
+ bcs error
+ sethi %hi(C_SYMBOL_NAME(__curbrk)), %g1
+ st %o1, [%g1 + %lo(C_SYMBOL_NAME(__curbrk))]
+ ret
+error: sethi %hi(C_SYMBOL_NAME(errno)), %g1
+ st %o0, [%g1 + %lo(C_SYMBOL_NAME(errno))]
+ sub %g0, 1, %o0
+ retl
+ nop /* Fill the delay slot. */
+
+weak_alias (__brk, brk)
diff --git a/libc/sysdeps/unix/sparc/dl-brk.S b/libc/sysdeps/unix/sparc/dl-brk.S
new file mode 100644
index 000000000..eeb96544e
--- /dev/null
+++ b/libc/sysdeps/unix/sparc/dl-brk.S
@@ -0,0 +1 @@
+#include <brk.S>
diff --git a/libc/sysdeps/unix/sparc/fork.S b/libc/sysdeps/unix/sparc/fork.S
new file mode 100644
index 000000000..ae594ec8e
--- /dev/null
+++ b/libc/sysdeps/unix/sparc/fork.S
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991, 92, 94, 95, 97, 99, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+SYSCALL__ (fork, 0)
+ /* %o1 is now 0 for the parent and 1 for the child. Decrement it to
+ make it -1 (all bits set) for the parent, and 0 (no bits set)
+ for the child. Then AND it with %o0, so the parent gets
+ %o0&-1==pid, and the child gets %o0&0==0. */
+ sub %o1, 1, %o1
+ retl
+ and %o0, %o1, %o0
+libc_hidden_def (__fork)
+
+weak_alias (__fork, fork)
diff --git a/libc/sysdeps/unix/sparc/pipe.S b/libc/sysdeps/unix/sparc/pipe.S
new file mode 100644
index 000000000..43981c895
--- /dev/null
+++ b/libc/sysdeps/unix/sparc/pipe.S
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991, 1992, 1995, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY (__pipe)
+ mov %o0, %o2 /* Save PIPEDES. */
+PSEUDO (__Spipe, pipe, 1)
+ st %o0, [%o2] /* PIPEDES[0] = %o0; */
+ st %o1, [%o2 + 4] /* PIPEDES[1] = %o1; */
+ retl /* return 0; */
+ clr %o0
+
+libc_hidden_def (__pipe)
+weak_alias (__pipe, pipe)
diff --git a/libc/sysdeps/unix/sparc/start.c b/libc/sysdeps/unix/sparc/start.c
new file mode 100644
index 000000000..a664189bb
--- /dev/null
+++ b/libc/sysdeps/unix/sparc/start.c
@@ -0,0 +1,189 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifndef NO_SHLIB
+#include <sys/exec.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <link.h>
+#include <syscall.h>
+#endif
+
+#if !defined (__GNUC__) || __GNUC__ < 2
+ #error This file uses GNU C extensions; you must compile with GCC version 2.
+#endif
+
+/* The first piece of initialized data. */
+int __data_start = 0;
+#ifdef HAVE_WEAK_SYMBOLS
+weak_alias (__data_start, data_start)
+#endif
+
+extern void __libc_init (int argc, char **argv, char **envp) __THROW;
+extern int main (int argc, char **argv, char **envp) __THROW;
+
+register long int sp asm("%sp"), fp asm("%fp");
+
+#ifndef NO_SHLIB
+static void init_shlib (void) __THROW;
+#endif
+
+#ifndef NO_EXPLICIT_START
+/* Declare _start with an explicit assembly symbol name of `start'
+ (note no leading underscore). This is the name Sun's crt0.o uses,
+ and programs are often linked with `ld -e start'. */
+void _start (void) asm ("start");
+#endif
+
+void
+_start (void)
+{
+ /* It is important that these be declared `register'.
+ Otherwise, when compiled without optimization, they are put on the
+ stack, which loses completely after we zero the FP. */
+ register int argc;
+ register char **argv, **envp;
+
+ /* Unwind the frame built when we entered the function. */
+ asm("restore");
+
+ /* And clear the frame pointer. */
+ fp = 0;
+
+ /* The argument info starts after one register
+ window (64 bytes) past the SP. */
+ argc = ((int *) sp)[16];
+ argv = (char **) &((int *) sp)[17];
+ envp = &argv[argc + 1];
+ __environ = envp;
+
+#ifndef NO_SHLIB
+ init_shlib ();
+#endif
+
+ /* Allocate 24 bytes of stack space for the register save area. */
+ sp -= 24;
+ __libc_init (argc, argv, envp);
+
+ exit (main (argc, argv, envp));
+}
+
+#ifndef NO_SHLIB
+
+/* System calls for use by the bootstrap routine.
+ These are defined here since the usual calls may be dynamically linked. */
+
+int syscall (int sysno, ...) asm ("init_syscall");
+asm ("init_syscall:\n"
+ " clr %g1\n"
+ " ta 0\n"
+ " bcc 1f\n"
+ " sethi %hi(_errno), %g1\n"
+ " st %o0, [%g1 + %lo(_errno)]\n"
+ " sub %g0, 1, %o0\n"
+ "1:retl\n"
+ " nop");
+
+static void
+init_shlib ()
+{
+ extern struct link_dynamic _DYNAMIC;
+ int so, zf;
+ caddr_t somap;
+ caddr_t sodmap;
+ caddr_t sobssmap;
+ void (*ldstart) (int, int);
+ struct exec soexec;
+ struct
+ {
+ caddr_t crt_ba;
+ int crt_dzfd;
+ int crt_ldfd;
+ struct link_dynamic *crt_dp;
+ char **crt_ep;
+ caddr_t crt_bp;
+ } soarg;
+
+ /* If not dynamically linked, do nothing. */
+ if (&_DYNAMIC == 0)
+ return;
+
+ /* Map in the dynamic linker. */
+ so = syscall (SYS_open, "/usr/lib/ld.so", O_RDONLY);
+ if (syscall (SYS_read, so, &soexec, sizeof (soexec)) != sizeof (soexec)
+ || soexec.a_magic != ZMAGIC)
+ {
+ static const char emsg[] = "crt0: no /usr/lib/ld.so\n";
+
+ syscall (SYS_write, 2, emsg, sizeof (emsg) - 1);
+ syscall (SYS_exit, 127);
+ }
+ somap = (caddr_t) syscall (SYS_mmap, 0,
+ soexec.a_text + soexec.a_data + soexec.a_bss,
+ PROT_READ | PROT_EXEC, _MAP_NEW | MAP_PRIVATE,
+ so, 0);
+ sodmap = (caddr_t) syscall (SYS_mmap, somap + soexec.a_text, soexec.a_data,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ _MAP_NEW | MAP_FIXED | MAP_PRIVATE,
+ so, soexec.a_text);
+ zf = syscall (SYS_open, "/dev/zero", O_RDONLY);
+ if (soexec.a_bss != 0)
+ sobssmap = (caddr_t) syscall (SYS_mmap,
+ somap + soexec.a_text + soexec.a_data,
+ soexec.a_bss,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ _MAP_NEW | MAP_FIXED | MAP_PRIVATE,
+ zf, 0);
+
+ /* Call the entry point of the dynamic linker. */
+ soarg.crt_ba = somap;
+ soarg.crt_dzfd = zf;
+ soarg.crt_ldfd = so;
+ soarg.crt_dp = &_DYNAMIC;
+ soarg.crt_ep = __environ;
+ soarg.crt_bp = (caddr_t) &&retaddr;
+
+ ldstart = (__typeof (ldstart)) (somap + soexec.a_entry);
+ (*ldstart) (1, (char *) &soarg - (char *) sp);
+
+ retaddr:
+}
+
+#endif
diff --git a/libc/sysdeps/unix/sparc/sysdep.S b/libc/sysdeps/unix/sparc/sysdep.S
new file mode 100644
index 000000000..7e2e4d4e8
--- /dev/null
+++ b/libc/sysdeps/unix/sparc/sysdep.S
@@ -0,0 +1,47 @@
+/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H
+#include <bits/errno.h>
+
+.global C_SYMBOL_NAME(errno)
+.global syscall_error
+
+.text
+.align 2
+#undef syscall_error
+#ifdef NO_UNDERSCORES
+__syscall_error:
+#else
+syscall_error:
+#endif
+#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN
+ /* We translate the system's EWOULDBLOCK error into EAGAIN.
+ The GNU C library always defines EWOULDBLOCK==EAGAIN.
+ EWOULDBLOCK_sys is the original number. */
+ cmp %o0, EWOULDBLOCK_sys
+ be,a notblock
+ mov EAGAIN, %o0
+#endif
+notblock: /* Store the error code in `errno'. */
+ sethi %hi(C_SYMBOL_NAME(errno)), %g1
+ st %o0, [%g1 + %lo(C_SYMBOL_NAME(errno))]
+ /* And return -1. */
+ retl
+ mov -1, %o0
diff --git a/libc/sysdeps/unix/sparc/sysdep.h b/libc/sysdeps/unix/sparc/sysdep.h
new file mode 100644
index 000000000..24225d962
--- /dev/null
+++ b/libc/sysdeps/unix/sparc/sysdep.h
@@ -0,0 +1,74 @@
+/* Copyright (C) 1993, 1994, 1995, 1997, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/unix/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+#ifdef NO_UNDERSCORES
+/* Since C identifiers are not normally prefixed with an underscore
+ on this system, the asm identifier `syscall_error' intrudes on the
+ C name space. Make sure we use an innocuous name. */
+#define syscall_error C_SYMBOL_NAME(__syscall_error)
+#endif
+
+#ifdef HAVE_ELF
+#define ENTRY(name) \
+ .global C_SYMBOL_NAME(name); \
+ .type name,@function; \
+ .align 4; \
+ C_LABEL(name)
+
+#else
+#define ENTRY(name) \
+ .global C_SYMBOL_NAME(name); \
+ .align 4; \
+ C_LABEL(name)
+
+#endif /* HAVE_ELF */
+
+#define PSEUDO(name, syscall_name, args) \
+ .global syscall_error; \
+ ENTRY (name) \
+ mov SYS_ify(syscall_name), %g1; \
+ ta 0; \
+ bcc 1f; \
+ sethi %hi(syscall_error), %g1; \
+ jmp %g1 + %lo(syscall_error); nop; \
+1:
+
+#define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .global syscall_error; \
+ ENTRY (name) \
+ mov SYS_ify(syscall_name), %g1; \
+ ta 0
+
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .global syscall_error; \
+ ENTRY (name) \
+ mov SYS_ify(syscall_name), %g1; \
+ ta 0
+
+#define ret retl; nop
+#define ret_NOERRNO retl; nop
+#define ret_ERRVAL retl; nop
+#define r0 %o0
+#define r1 %o1
+#define MOVE(x,y) mov x, y
+
+#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/unix/sparc/vfork.S b/libc/sysdeps/unix/sparc/vfork.S
new file mode 100644
index 000000000..5d48b090d
--- /dev/null
+++ b/libc/sysdeps/unix/sparc/vfork.S
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 92, 94, 95, 97, 99, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#ifndef SYS_vfork
+#define SYS_vfork 66
+#endif
+
+SYSCALL__ (vfork, 0)
+ /* %o1 is now 0 for the parent and 1 for the child. Decrement it to
+ make it -1 (all bits set) for the parent, and 0 (no bits set)
+ for the child. Then AND it with %o0, so the parent gets
+ %o0&-1==pid, and the child gets %o0&0==0. */
+ sub %o1, 1, %o1
+ retl
+ and %o0, %o1, %o0
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libc/sysdeps/unix/start.c b/libc/sysdeps/unix/start.c
new file mode 100644
index 000000000..2474fc2e7
--- /dev/null
+++ b/libc/sysdeps/unix/start.c
@@ -0,0 +1,105 @@
+/* Copyright (C) 1991, 93, 1995-1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sysdep.h> /* In case it wants to define anything. */
+
+/* The first piece of initialized data. */
+int __data_start = 0;
+#ifdef HAVE_WEAK_SYMBOLS
+weak_alias (__data_start, data_start)
+#endif
+
+#ifdef DUMMIES
+#define ARG_DUMMIES DUMMIES,
+#define DECL_DUMMIES int DUMMIES;
+#else
+#define ARG_DUMMIES
+#define DECL_DUMMIES
+#endif
+
+extern void __libc_init (int argc, char **argv, char **envp);
+extern int main (int argc, char **argv, char **envp);
+
+
+/* Not a prototype because it gets called strangely. */
+static void start1();
+
+#ifndef HAVE__start
+
+/* N.B.: It is important that this be the first function.
+ This file is the first thing in the text section. */
+void
+_start ()
+{
+ start1 ();
+}
+
+#ifndef NO_UNDERSCORES
+/* Make an alias called `start' (no leading underscore, so it can't
+ conflict with C symbols) for `_start'. This is the name vendor crt0.o's
+ tend to use, and thus the name most linkers expect. */
+asm (".set start, __start");
+#endif
+
+#endif
+
+/* ARGSUSED */
+static void
+start1 (ARG_DUMMIES argc, argp)
+ DECL_DUMMIES
+ int argc;
+ char *argp;
+{
+ char **argv = &argp;
+
+ /* The environment starts just after ARGV. */
+ __environ = &argv[argc + 1];
+
+ /* If the first thing after ARGV is the arguments
+ themselves, there is no environment. */
+ if ((char *) __environ == *argv)
+ /* The environment is empty. Make __environ
+ point at ARGV[ARGC], which is NULL. */
+ --__environ;
+
+ /* Do C library initializations. */
+ __libc_init (argc, argv, __environ);
+
+ /* Call the user program. */
+ exit (main (argc, argv, __environ));
+}
diff --git a/libc/sysdeps/unix/stime.c b/libc/sysdeps/unix/stime.c
new file mode 100644
index 000000000..c4dfdcf93
--- /dev/null
+++ b/libc/sysdeps/unix/stime.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1992, 1996, 1997, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h> /* For NULL. */
+#include <sys/time.h>
+#include <time.h>
+
+/* Set the system clock to *WHEN. */
+
+int
+stime (when)
+ const time_t *when;
+{
+ struct timeval tv;
+
+ if (when == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ tv.tv_sec = *when;
+ tv.tv_usec = 0;
+ return __settimeofday (&tv, (struct timezone *) 0);
+}
diff --git a/libc/sysdeps/unix/syscall.S b/libc/sysdeps/unix/syscall.S
new file mode 100644
index 000000000..8b685cf30
--- /dev/null
+++ b/libc/sysdeps/unix/syscall.S
@@ -0,0 +1,30 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#ifndef SYS_syscall
+#define SYS_syscall 0
+#endif
+
+/* This works if the kernel does an "indirect system call" for system call 0,
+ taking the first argument word off the stack as the system call number. */
+
+SYSCALL (syscall, 1)
+ ret
+PSEUDO_END(syscall)
diff --git a/libc/sysdeps/unix/syscalls.list b/libc/sysdeps/unix/syscalls.list
new file mode 100644
index 000000000..4c963abe5
--- /dev/null
+++ b/libc/sysdeps/unix/syscalls.list
@@ -0,0 +1,65 @@
+# File name Caller Syscall name Args Strong name Weak names
+
+access - access i:si __access access
+acct - acct i:S acct
+chdir - chdir i:s __chdir chdir
+chmod - chmod i:si __chmod chmod
+chown - chown i:sii __chown __chown_internal chown
+chroot - chroot i:s chroot
+close - close Ci:i __libc_close __close close
+dup - dup i:i __dup dup
+dup2 - dup2 i:ii __dup2 dup2
+fchdir - fchdir i:i __fchdir fchdir
+fcntl - fcntl Ci:iiF __libc_fcntl __fcntl __fcntl_internal fcntl
+fstatfs - fstatfs i:ip __fstatfs fstatfs
+fsync - fsync Ci:i __libc_fsync fsync
+getdomain - getdomainname i:si getdomainname
+getgid - getgid Ei: __getgid getgid
+getgroups - getgroups i:ip __getgroups getgroups
+getitimer - getitimer i:ip __getitimer getitimer
+getpid - getpid Ei: __getpid getpid
+getpriority - getpriority i:ii getpriority
+getrlimit - getrlimit i:ip __getrlimit getrlimit
+getuid - getuid Ei: __getuid getuid
+ioctl - ioctl i:iiI __ioctl ioctl
+kill - kill i:ii __kill kill
+link - link i:ss __link link
+lseek - lseek i:iii __libc_lseek __lseek lseek
+mkdir - mkdir i:si __mkdir mkdir
+open - open Ci:siv __libc_open __open open
+profil - profil i:piii __profil profil
+ptrace - ptrace i:iiii ptrace
+read - read Ci:ibn __libc_read __read read
+readlink - readlink i:spi __readlink readlink
+readv - readv Ci:ipi __readv readv
+reboot - reboot i:i reboot
+rename - rename i:ss rename
+rmdir - rmdir i:s __rmdir rmdir
+select - select Ci:iPPPP __select __libc_select select
+setdomain - setdomainname i:si setdomainname
+setegid - setegid i:i __setegid setegid
+seteuid - seteuid i:i __seteuid seteuid
+setgid - setgid i:i __setgid setgid
+setgroups - setgroups i:ip setgroups
+setitimer - setitimer i:ipp __setitimer setitimer
+setpriority - setpriority i:iii setpriority
+setrlimit - setrlimit i:ip __setrlimit setrlimit
+setsid - setsid i: __setsid setsid
+settimeofday - settimeofday i:PP __settimeofday settimeofday
+setuid - setuid i:i __setuid setuid
+sigsuspend - sigsuspend Ci:p sigsuspend
+sstk - sstk b:i sstk
+statfs - statfs i:sp __statfs statfs
+swapoff - swapoff i:s swapoff
+swapon - swapon i:s swapon
+symlink - symlink i:ss __symlink symlink
+sync - sync i: sync
+sys_fstat fxstat fstat i:ip __syscall_fstat
+sys_mknod xmknod mknod i:sii __syscall_mknod
+sys_stat xstat stat i:sp __syscall_stat
+umask - umask Ei:i __umask umask
+uname - uname i:p __uname uname
+unlink - unlink i:s __unlink unlink
+utimes - utimes i:sp __utimes utimes
+write - write Ci:ibn __libc_write __write write
+writev - writev Ci:ipi __writev writev
diff --git a/libc/sysdeps/unix/sysdep.h b/libc/sysdeps/unix/sysdep.h
new file mode 100644
index 000000000..11e5317df
--- /dev/null
+++ b/libc/sysdeps/unix/sysdep.h
@@ -0,0 +1,59 @@
+/* Copyright (C) 1991, 92, 93, 96, 98, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/sysdep.h>
+
+#include <sys/syscall.h>
+#define HAVE_SYSCALLS
+
+/* Note that using a `PASTE' macro loses. */
+#ifdef __STDC__
+#define SYSCALL__(name, args) PSEUDO (__##name, name, args)
+#else
+#define SYSCALL__(name, args) PSEUDO (__/**/name, name, args)
+#endif
+#define SYSCALL(name, args) PSEUDO (name, name, args)
+
+/* Machine-dependent sysdep.h files are expected to define the macro
+ PSEUDO (function_name, syscall_name) to emit assembly code to define the
+ C-callable function FUNCTION_NAME to do system call SYSCALL_NAME.
+ r0 and r1 are the system call outputs. MOVE(x, y) should be defined as
+ an instruction such that "MOVE(r1, r0)" works. ret should be defined
+ as the return instruction. */
+
+#ifdef __STDC__
+#define SYS_ify(syscall_name) SYS_##syscall_name
+#else
+#define SYS_ify(syscall_name) SYS_/**/syscall_name
+#endif
+
+/* Terminate a system call named SYM. This is used on some platforms
+ to generate correct debugging information. */
+#ifndef PSEUDO_END
+#define PSEUDO_END(sym)
+#endif
+#ifndef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(sym) PSEUDO_END(sym)
+#endif
+#ifndef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(sym) PSEUDO_END(sym)
+#endif
+
+/* Wrappers around system calls should normally inline the system call code.
+ But sometimes it is not possible or implemented and we use this code. */
+#define INLINE_SYSCALL(name, nr, args...) __syscall_##name (args)
diff --git a/libc/sysdeps/unix/system.c b/libc/sysdeps/unix/system.c
new file mode 100644
index 000000000..2c52ec81d
--- /dev/null
+++ b/libc/sysdeps/unix/system.c
@@ -0,0 +1,2 @@
+#define NO_WAITPID
+#include <sysdeps/posix/system.c>
diff --git a/libc/sysdeps/unix/sysv/Makefile b/libc/sysdeps/unix/sysv/Makefile
new file mode 100644
index 000000000..10f3e792f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/Makefile
@@ -0,0 +1,42 @@
+# Copyright (C) 1992, 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifeq ($(subdir),termios)
+
+ifeq (,$(filter termio.h,$(sysdep_headers)))
+
+sysdep_headers := $(sysdep_headers) termio.h
+generated := $(generated) termio.h
+
+# termio.h is just like sysv_termio.h except it uses the same names for
+# everything that System V termio does. sysv_termio.h is necessary to
+# include in __tcgetatr.c et al, because some of the names in termio.h
+# conflict with termios.h. The C library doesn't actually use termio.h,
+# but we generate it for those application programs which use it.
+$(objpfx)termio.h: $(..)sysdeps/unix/sysv/sysv_termio.h
+ sed < $< > $@-tmp \
+ -e 's/_SYSV_//' \
+ -e 's/^#define[ ]*_T/#define T/'\
+ -e 's/__sysv_termio/termio/'
+ mv $@-tmp $@
+
+endif
+endif
+
+# In SYSV style archives the symbol table member has an empty name.
+ar-symtab-name =
diff --git a/libc/sysdeps/unix/sysv/Versions b/libc/sysdeps/unix/sysv/Versions
new file mode 100644
index 000000000..bdb8ba836
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/Versions
@@ -0,0 +1,5 @@
+libc {
+ GLIBC_2.0 {
+ sysinfo;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/bits/dirent.h b/libc/sysdeps/unix/sysv/bits/dirent.h
new file mode 100644
index 000000000..3a5246a78
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/bits/dirent.h
@@ -0,0 +1,28 @@
+/* Directory entry structure `struct dirent'. Old System V version.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DIRENT_H
+# error "Never use <bits/dirent.h> directly; include <dirent.h> instead."
+#endif
+
+struct dirent
+ {
+ unsigned short int d_fileno;
+ char d_name[14];
+ };
diff --git a/libc/sysdeps/unix/sysv/bits/fcntl.h b/libc/sysdeps/unix/sysv/bits/fcntl.h
new file mode 100644
index 000000000..0eb81aa6e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/bits/fcntl.h
@@ -0,0 +1,94 @@
+/* O_*, F_*, FD_* bit values for System V.
+ Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+#error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+
+/* File access modes for `open' and `fcntl'. */
+#define O_RDONLY 0 /* Open read-only. */
+#define O_WRONLY 1 /* Open write-only. */
+#define O_RDWR 2 /* Open read/write. */
+
+
+/* Bits OR'd into the second argument to open. */
+#define O_CREAT 00400 /* Create file if it doesn't exist. */
+#define O_EXCL 02000 /* Fail if file already exists. */
+#define O_TRUNC 01000 /* Truncate file to zero length. */
+#if defined __USE_BSD || defined __USE_SVID
+#define O_SYNC 00020 /* Synchronous writes. */
+#define O_FSYNC O_SYNC
+#endif
+
+/* File status flags for `open' and `fcntl'. */
+#define O_APPEND 000010 /* Writes append to the file. */
+#define O_NONBLOCK 000004 /* Non-blocking I/O. */
+
+#ifdef __USE_BSD
+/* System V doesn't support POSIX.1 O_NONBLOCK, but O_NDELAY is close. */
+#define O_NDELAY O_NONBLOCK
+#endif
+
+/* Mask for file access modes. This is system-dependent in case
+ some system ever wants to define some other flavor of access. */
+#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#define F_GETLK 5 /* Get record locking info. */
+#define F_SETLK 6 /* Set record locking info. */
+#define F_SETLKW 7 /* Set record locking info, wait. */
+
+/* File descriptor flags used with F_GETFD and F_SETFD. */
+#define FD_CLOEXEC 1 /* Close on exec. */
+
+
+#include <bits/types.h>
+
+/* The structure describing an advisory lock. This is the type of the third
+ argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+ short int l_sysid; /* System ID where locking process resides. */
+ short int l_pid; /* Process holding the lock. */
+ };
+
+/* Values for the `l_type' field of a `struct flock'. */
+#define F_RDLCK 1 /* Read lock. */
+#define F_WRLCK 2 /* Write lock. */
+#define F_UNLCK 3 /* Remove lock. */
+
+
+/* Define some more compatibility macros to be backward compatible with
+ BSD systems which did not managed to hide these kernel macros. */
+#ifdef __USE_BSD
+#define FAPPEND O_APPEND
+#define FFSYNC O_FSYNC
+#define FNONBLOCK O_NONBLOCK
+#define FNDELAY O_NDELAY
+#endif /* Use BSD. */
diff --git a/libc/sysdeps/unix/sysv/bits/local_lim.h b/libc/sysdeps/unix/sysv/bits/local_lim.h
new file mode 100644
index 000000000..d9fa98809
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/bits/local_lim.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 1992, 1996 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define NGROUPS_MAX 0 /* No supplementary groups. */
+#define ARG_MAX 5120
+#define CHILD_MAX 25
+#define OPEN_MAX 60
+#define LINK_MAX 1000
+#define MAX_CANON 256
+
+/* For SVR3, this is 14. For SVR4, it is 255, at least on ufs
+ file systems, even though the System V limits.h incorrectly
+ defines it as 14. Giving it a value which is too large
+ is harmless (it is a maximum). */
+#define NAME_MAX 255
+
+#define PATH_MAX 1024
diff --git a/libc/sysdeps/unix/sysv/bits/signum.h b/libc/sysdeps/unix/sysv/bits/signum.h
new file mode 100644
index 000000000..d0fc7f469
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/bits/signum.h
@@ -0,0 +1,56 @@
+/* Signal number definitions. System V version.
+ Copyright (C) 1991, 1992, 1993, 1996 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef _SIGNAL_H
+
+/* This file defines the fake signal functions and signal
+ number constants for System V release 3. */
+
+/* Fake signal functions. */
+#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
+#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
+#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
+
+
+/* Signals. */
+#define SIGHUP 1 /* Hangup (POSIX). */
+#define SIGINT 2 /* Interrupt (ANSI). */
+#define SIGQUIT 3 /* Quit (POSIX). */
+#define SIGILL 4 /* Illegal instruction (ANSI). */
+#define SIGABRT SIGIOT /* Abort (ANSI). */
+#define SIGTRAP 5 /* Trace trap (POSIX). */
+#define SIGIOT 6 /* IOT trap (4.2 BSD). */
+#define SIGEMT 7 /* EMT trap (4.2 BSD). */
+#define SIGFPE 8 /* Floating-point exception (ANSI). */
+#define SIGKILL 9 /* Kill, unblockable (POSIX). */
+#define SIGBUS 10 /* Bus error (4.2 BSD). */
+#define SIGSEGV 11 /* Segmentation violation (ANSI). */
+#define SIGSYS 12 /* Bad argument to system call (4.2 BSD)*/
+#define SIGPIPE 13 /* Broken pipe (POSIX). */
+#define SIGALRM 14 /* Alarm clock (POSIX). */
+#define SIGTERM 15 /* Termination (ANSI). */
+#define SIGUSR1 16 /* User-defined signal 1 (POSIX). */
+#define SIGUSR2 17 /* User-defined signal 2 (POSIX). */
+#define SIGCHLD 18 /* Child status has changed (POSIX). */
+#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
+#define SIGPWR 19 /* Power failure restart (System V). */
+
+#endif /* <signal.h> included. */
+
+#define _NSIG 20 /* Biggest signal number + 1. */
diff --git a/libc/sysdeps/unix/sysv/bits/stat.h b/libc/sysdeps/unix/sysv/bits/stat.h
new file mode 100644
index 000000000..f9a9e614d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/bits/stat.h
@@ -0,0 +1,65 @@
+/* Copyright (C) 1992, 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+struct stat
+ {
+ short int st_dev;
+ unsigned short int st_ino;
+ unsigned short int st_mode;
+ short int st_nlink;
+ unsigned short int st_uid;
+ unsigned short int st_gid;
+ short int st_rdev;
+ long int st_size;
+ long int st_atime;
+ long int st_mtime;
+ long int st_ctime;
+ };
+
+/* Encoding of the file mode. */
+
+#define __S_IFMT 0170000 /* These bits determine file type. */
+
+/* File types. */
+#define __S_IFDIR 0040000 /* Directory. */
+#define __S_IFCHR 0020000 /* Character device. */
+#define __S_IFBLK 0060000 /* Block device. */
+#define __S_IFREG 0100000 /* Regular file. */
+#define __S_IFIFO 0010000 /* FIFO. */
+
+/* These don't actually exist on System V, but having them doesn't hurt. */
+#define __S_IFLNK 0120000 /* Symbolic link. */
+#define __S_IFSOCK 0140000 /* Socket. */
+
+/* POSIX.1b objects. */
+#define __S_TYPEISMQ(buf) (0)
+#define __S_TYPEISSEM(buf) (0)
+#define __S_TYPEISSHM(buf) (0)
+
+/* Protection bits. */
+
+#define __S_ISUID 04000 /* Set user ID on execution. */
+#define __S_ISGID 02000 /* Set group ID on execution. */
+#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
+#define __S_IREAD 0400 /* Read by owner. */
+#define __S_IWRITE 0200 /* Write by owner. */
+#define __S_IEXEC 0100 /* Execute by owner. */
diff --git a/libc/sysdeps/unix/sysv/bits/utmp.h b/libc/sysdeps/unix/sysv/bits/utmp.h
new file mode 100644
index 000000000..b5353b662
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/bits/utmp.h
@@ -0,0 +1,54 @@
+/* The `struct utmp' type, describing entries in the utmp file. System V.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _UTMP_H
+# error "Never include <bits/utmp.h> directly; use <utmp.h> instead."
+#endif
+
+
+#include <time.h>
+
+#define _PATH_UTMP "/var/adm/utmp"
+#define _PATH_WTMP "/var/adm/wtmp"
+#define _PATH_LASTLOG "/var/adm/lastlog"
+
+
+struct utmp
+ {
+#define ut_name ut_user
+ char ut_user[8];
+ char ut_id[4];
+ char ut_line[12];
+ short int ut_pid;
+ short int ut_type;
+ struct exit_status
+ {
+ short int e_termination;
+ short int e_exit;
+ } ut_exit;
+ __time_t ut_time;
+ };
+
+
+/* Tell the user that we have a modern system with UT_HOST, UT_TYPE, UT_ID
+ and UT_TV fields. */
+#define _HAVE_UT_TYPE 1
+#define _HAVE_UT_ID 1
+#define _HAVE_UT_TV 1
+#define _HAVE_UT_HOST 1
diff --git a/libc/sysdeps/unix/sysv/bits/utsname.h b/libc/sysdeps/unix/sysv/bits/utsname.h
new file mode 100644
index 000000000..0b2949b17
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/bits/utsname.h
@@ -0,0 +1,23 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_UTSNAME_H
+# error "Never include <bits/utsname.h> directly; use <sys/utsname.h> instead."
+#endif
+
+#define _UTSNAME_LENGTH 9
diff --git a/libc/sysdeps/unix/sysv/direct.h b/libc/sysdeps/unix/sysv/direct.h
new file mode 100644
index 000000000..dc1d77bee
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/direct.h
@@ -0,0 +1,10 @@
+struct direct
+ {
+ unsigned short int d_fileno;
+ char d_name[14];
+ };
+
+#define D_NAMLEN(d) \
+ ((d)->d_name[13] == '\0' ? strlen ((d)->d_name) : 14)
+
+#define D_RECLEN(d) (sizeof (*(d)))
diff --git a/libc/sysdeps/unix/sysv/getdents.c b/libc/sysdeps/unix/sysv/getdents.c
new file mode 100644
index 000000000..5f8fd8f6b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/getdents.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1993, 1995, 1997, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+extern ssize_t __getdents (int fd, char *buf, size_t nbytes);
+
+ssize_t
+__getdirentries (fd, buf, nbytes, basep)
+ int fd;
+ char *buf;
+ size_t nbytes;
+ off_t *basep;
+{
+ if (basep)
+ *basep = __lseek (fd, (off_t) 0, SEEK_CUR);
+
+ return __getdents (fd, buf, nbytes);
+}
+
+weak_alias (__getdirentries, getdirentries)
diff --git a/libc/sysdeps/unix/sysv/gethostname.c b/libc/sysdeps/unix/sysv/gethostname.c
new file mode 100644
index 000000000..330770c8b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/gethostname.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1992, 1995, 1997, 2000, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+
+/* Put the name of the current host in no more than LEN bytes of NAME.
+ The result is null-terminated if LEN is large enough for the full
+ name and the terminator. */
+int
+__gethostname (name, len)
+ char *name;
+ size_t len;
+{
+ struct utsname buf;
+ size_t node_len;
+
+ if (uname (&buf))
+ return -1;
+
+ node_len = strlen (buf.nodename) + 1;
+ memcpy (name, buf.nodename, len < node_len ? len : node_len);
+
+ if (node_len > len)
+ {
+ __set_errno (ENAMETOOLONG);
+ return -1;
+ }
+ return 0;
+}
+
+weak_alias (__gethostname, gethostname)
diff --git a/libc/sysdeps/unix/sysv/i386/sysdep.h b/libc/sysdeps/unix/sysv/i386/sysdep.h
new file mode 100644
index 000000000..fedd5ea82
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/i386/sysdep.h
@@ -0,0 +1,4 @@
+/* System V does not precede the asm names of C symbols with a `_'. */
+#define NO_UNDERSCORES
+
+#include <sysdeps/unix/i386/sysdep.h>
diff --git a/libc/sysdeps/unix/sysv/i386/time.S b/libc/sysdeps/unix/sysv/i386/time.S
new file mode 100644
index 000000000..83b8d1fd6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/i386/time.S
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991,92,96,97,2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <asm-syntax.h>
+
+PSEUDO_NOERRNO (time, time, 1)
+ movl 4(%esp), %edx /* Put passed pointer in %edx. */
+ testl %edx, %edx /* Is it non-nil? */
+ je L(null)
+ movl %eax, (%edx) /* Yes; store the time there. */
+L(null):
+ ret
+PSEUDO_END_NOERRNO (time)
+libc_hidden_def (time)
diff --git a/libc/sysdeps/unix/sysv/linux/Implies b/libc/sysdeps/unix/sysv/linux/Implies
new file mode 100644
index 000000000..4deb1c624
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/Implies
@@ -0,0 +1,14 @@
+# The gnu subdirectory exists for things common to both Linux-based and
+# Hurd-based GNU systems.
+gnu
+
+# Linux shares most of the syscalls which are also common to BSD and SVR4.
+unix/common
+
+# Linux as of version 1.3.29 has all functions of the mmap family
+# which are described in POSIX.4. Missing is only madvise() so
+# we define a stub here.
+unix/mman
+
+# Linux has network support in the kernel.
+unix/inet
diff --git a/libc/sysdeps/unix/sysv/linux/Makefile b/libc/sysdeps/unix/sysv/linux/Makefile
new file mode 100644
index 000000000..8bec6cdb8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/Makefile
@@ -0,0 +1,159 @@
+ifeq ($(subdir),csu)
+sysdep_routines += errno-loc
+endif
+
+ifeq ($(subdir),assert)
+CFLAGS-assert.c += -DFATAL_PREPARE_INCLUDE='<fatal-prepare.h>'
+CFLAGS-assert-perr.c += -DFATAL_PREPARE_INCLUDE='<fatal-prepare.h>'
+endif
+
+ifeq ($(subdir),malloc)
+CFLAGS-malloc.c += -DMORECORE_CLEARS=2
+endif
+
+ifeq ($(subdir),misc)
+sysdep_routines += sysctl clone llseek umount umount2 readahead \
+ setfsuid setfsgid makedev
+
+CFLAGS-gethostid.c = -fexceptions
+
+sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
+ sys/klog.h sys/kdaemon.h \
+ sys/user.h sys/procfs.h sys/prctl.h \
+ sys/kd.h sys/soundcard.h sys/vt.h \
+ sys/quota.h sys/fsuid.h \
+ scsi/sg.h scsi/scsi.h scsi/scsi_ioctl.h sys/pci.h \
+ sys/ultrasound.h sys/raw.h sys/personality.h sys/epoll.h \
+ bits/a.out.h sys/inotify.h
+
+install-others += $(inst_includedir)/bits/syscall.h
+
+tests += tst-clone
+
+# Generate the list of SYS_* macros for the system calls (__NR_* macros).
+# For bi-arch platforms, the CPU/Makefile defines {32,64}bit-predefine and
+# we generate a file that uses <bits/wordsize.h>.
+$(objpfx)syscall-%.h $(objpfx)syscall-%.d: ../sysdeps/unix/sysv/linux/sys/syscall.h
+ $(make-target-directory)
+ { \
+ echo '/* Generated at libc build time from kernel syscall list. */';\
+ echo ''; \
+ echo '#ifndef _SYSCALL_H'; \
+ echo '# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."'; \
+ echo '#endif'; \
+ echo ''; \
+ $(CC) -E -MD -MP -MF $(@:.h=.d)-t1 -MT '$(@:.d=.h) $(@:.h=.d)' \
+ -x c $(sysincludes) $< $(addprefix -U,$(64bit-predefine)) \
+ $(addprefix -D,$(32bit-predefine)) -D_LIBC -dM | \
+ sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \
+ LC_ALL=C sort > $(@:.d=.h).new32; \
+ $(CC) -E -MD -MP -MF $(@:.h=.d)-t2 -MT '$(@:.d=.h) $(@:.h=.d)' \
+ -x c $(sysincludes) $< $(addprefix -U,$(32bit-predefine)) \
+ $(addprefix -D,$(64bit-predefine)) -D_LIBC -dM | \
+ sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \
+ LC_ALL=C sort > $(@:.d=.h).new64; \
+ if cmp -s $(@:.d=.h).new32 $(@:.d=.h).new64; then \
+ cat $(@:.d=.h).new32; \
+ else \
+ echo '#include <bits/wordsize.h>'; \
+ echo ''; \
+ LC_ALL=C comm -12 $(@:.d=.h).new32 $(@:.d=.h).new64; \
+ echo '#if __WORDSIZE == 64'; \
+ LC_ALL=C comm -13 $(@:.d=.h).new32 $(@:.d=.h).new64; \
+ echo '#else'; \
+ LC_ALL=C comm -23 $(@:.d=.h).new32 $(@:.d=.h).new64; \
+ echo '#endif'; \
+ fi; \
+ rm -f $(@:.d=.h).new32 $(@:.d=.h).new64; \
+ } > $(@:.d=.h).new
+ mv -f $(@:.d=.h).new $(@:.d=.h)
+ifneq (,$(objpfx))
+ sed $(sed-remove-objpfx) $(@:.h=.d)-t1 $(@:.h=.d)-t2 > $(@:.h=.d)-t3
+else
+ cat $(@:.h=.d)-t1 $(@:.h=.d)-t2 > $(@:.h=.d)-t3
+endif
+ rm -f $(@:.h=.d)-t1 $(@:.h=.d)-t2
+ mv -f $(@:.h=.d)-t3 $(@:.h=.d)
+
+$(inst_includedir)/bits/syscall.h: $(objpfx)syscall-list.h $(+force)
+ $(make-target-directory)
+ if test -r $@ && cmp -s $< $@; \
+ then echo 'bits/syscall.h unchanged'; \
+ else $(INSTALL_DATA) $< $@; fi
+
+ifndef no_deps
+# Get the generated list of dependencies (probably /usr/include/asm/unistd.h).
+-include $(objpfx)syscall-list.d
+endif
+generated += syscall-list.h syscall-list.d
+endif
+
+ifeq ($(subdir),time)
+sysdep_headers += sys/timex.h
+
+sysdep_routines += ntp_gettime
+endif
+
+ifeq ($(subdir),socket)
+sysdep_headers += net/if_ppp.h net/ppp-comp.h \
+ net/ppp_defs.h net/if_arp.h net/route.h net/ethernet.h \
+ net/if_slip.h net/if_packet.h net/if_shaper.h
+sysdep_routines += cmsg_nxthdr sa_len
+endif
+
+ifeq ($(subdir),sunrpc)
+sysdep_headers += nfs/nfs.h
+endif
+
+ifeq ($(subdir),termios)
+sysdep_headers += termio.h
+endif
+
+ifeq ($(subdir),posix)
+sysdep_headers += bits/initspin.h
+
+sysdep_routines += exit-thread
+endif
+
+ifeq ($(subdir),inet)
+sysdep_headers += netinet/if_fddi.h netinet/if_tr.h \
+ netipx/ipx.h netash/ash.h netax25/ax25.h netatalk/at.h \
+ netrom/netrom.h netpacket/packet.h netrose/rose.h \
+ neteconet/ec.h
+endif
+
+# Don't compile the ctype glue code, since there is no old non-GNU C library.
+inhibit-glue = yes
+
+ifeq ($(subdir),dirent)
+sysdep_routines += getdirentries getdirentries64
+endif
+
+ifeq ($(subdir),nis)
+CFLAGS-ypclnt.c = -DUSE_BINDINGDIR=1
+endif
+
+ifeq ($(subdir),io)
+sysdep_routines += xstatconv internal_statvfs internal_statvfs64
+endif
+
+ifeq ($(subdir),elf)
+sysdep-rtld-routines += dl-brk dl-sbrk
+
+CPPFLAGS-lddlibc4 += -DNOT_IN_libc
+endif
+
+ifeq ($(subdir),rt)
+CFLAGS-mq_send.c += -fexceptions
+CFLAGS-mq_receive.c += -fexceptions
+endif
+
+ifeq ($(subdir),nscd)
+CFLAGS-connections.c += -DHAVE_EPOLL -DHAVE_SENDFILE
+CFLAGS-pwdcache.c += -DHAVE_SENDFILE
+CFLAGS-grpcache.c += -DHAVE_SENDFILE
+CFLAGS-hstcache.c += -DHAVE_SENDFILE
+CFLAGS-aicache.c += -DHAVE_SENDFILE
+CFLAGS-initgrcache.c += -DHAVE_SENDFILE
+CFLAGS-gai.c += -DNEED_NETLINK
+endif
diff --git a/libc/sysdeps/unix/sysv/linux/Versions b/libc/sysdeps/unix/sysv/linux/Versions
new file mode 100644
index 000000000..7c015b1d6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/Versions
@@ -0,0 +1,133 @@
+libc {
+ # The comment lines with "#errlist-compat" are magic; see errlist-compat.awk.
+ # When you get an error from errlist-compat.awk, you need to add a new
+ # version here. Don't do this blindly, since this means changing the ABI
+ # for all GNU/Linux configurations.
+
+ GLIBC_2.0 {
+ # functions used in inline functions or macros
+ __cmsg_nxthdr;
+
+ # functions used in other libraries
+ __clone;
+
+ # helper functions
+ __errno_location;
+
+ # b*
+ bdflush;
+
+ # c*
+ clone; create_module;
+
+ # d*
+ delete_module;
+
+ # g*
+ get_kernel_syms; getresgid; getresuid;
+
+ # i*
+ init_module;
+
+ # k*
+ klogctl;
+
+ # l*
+ llseek;
+
+ # m*
+ mremap;
+
+ # n*
+ nfsservctl;
+
+ # p*
+ personality; prctl;
+
+ # q*
+ query_module; quotactl;
+
+ # s*
+ setfsgid; setfsuid;
+
+ # s*
+ setresgid; setresuid; swapoff; swapon; sysctl;
+
+ # u*
+ umount; uselib;
+
+ #errlist-compat 123
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_2.1 {
+ # functions used in inline functions or macros
+ __libc_sa_len;
+
+ # Since we have new signals this structure changed.
+ _sys_siglist; sys_siglist; sys_sigabbrev;
+
+ # New errlist.
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+
+ # chown interface change.
+ chown;
+
+ # Change in pthread_attr_t.
+ pthread_attr_init;
+
+ # c*
+ capget; capset;
+
+ # n*
+ ntp_adjtime; ntp_gettime;
+
+ # u*
+ umount2;
+
+ #errlist-compat 125
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_2.2 {
+ # needed in other libraries.
+ __endmntent; __getmntent_r; __setmntent; __statfs; __sysctl;
+
+ # ipc ctl interface change.
+ semctl; shmctl; msgctl;
+ }
+ GLIBC_2.2.1 {
+ # p*
+ pivot_root;
+ }
+ GLIBC_2.3 {
+ # r*
+ readahead;
+
+ #errlist-compat 126
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_2.3.2 {
+ # New kernel interfaces.
+ epoll_create; epoll_ctl; epoll_wait;
+ }
+ GLIBC_2.3.3 {
+ gnu_dev_major; gnu_dev_minor; gnu_dev_makedev;
+ }
+ GLIBC_2.3.4 {
+ sched_getaffinity; sched_setaffinity;
+ }
+ GLIBC_2.4 {
+ inotify_init; inotify_add_watch; inotify_rm_watch;
+
+ unshare;
+
+ #errlist-compat 132
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_2.5 {
+ splice; sync_file_range; tee; vmsplice;
+ }
+ GLIBC_PRIVATE {
+ # functions used in other libraries
+ __syscall_rt_sigqueueinfo;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/_exit.c b/libc/sysdeps/unix/sysv/linux/_exit.c
new file mode 100644
index 000000000..1477bd80f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/_exit.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sysdep.h>
+#include <abort-instr.h>
+
+
+void
+_exit (status)
+ int status;
+{
+ while (1)
+ {
+#ifdef __NR_exit_group
+ INLINE_SYSCALL (exit_group, 1, status);
+#endif
+ INLINE_SYSCALL (exit, 1, status);
+
+#ifdef ABORT_INSTRUCTION
+ ABORT_INSTRUCTION;
+#endif
+ }
+}
+libc_hidden_def (_exit)
+weak_alias (_exit, _Exit)
diff --git a/libc/sysdeps/unix/sysv/linux/a.out.h b/libc/sysdeps/unix/sysv/linux/a.out.h
new file mode 100644
index 000000000..f0514c93a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/a.out.h
@@ -0,0 +1,138 @@
+#ifndef __A_OUT_GNU_H__
+#define __A_OUT_GNU_H__
+
+#include <bits/a.out.h>
+
+#define __GNU_EXEC_MACROS__
+
+struct exec
+{
+ unsigned long a_info; /* Use macros N_MAGIC, etc for access. */
+ unsigned int a_text; /* Length of text, in bytes. */
+ unsigned int a_data; /* Length of data, in bytes. */
+ unsigned int a_bss; /* Length of uninitialized data area for file, in bytes. */
+ unsigned int a_syms; /* Length of symbol table data in file, in bytes. */
+ unsigned int a_entry; /* Start address. */
+ unsigned int a_trsize;/* Length of relocation info for text, in bytes. */
+ unsigned int a_drsize;/* Length of relocation info for data, in bytes. */
+};
+
+enum machine_type
+{
+ M_OLDSUN2 = 0,
+ M_68010 = 1,
+ M_68020 = 2,
+ M_SPARC = 3,
+ M_386 = 100,
+ M_MIPS1 = 151,
+ M_MIPS2 = 152
+};
+
+#define N_MAGIC(exec) ((exec).a_info & 0xffff)
+#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
+#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
+#define N_SET_INFO(exec, magic, type, flags) \
+ ((exec).a_info = ((magic) & 0xffff) \
+ | (((int)(type) & 0xff) << 16) \
+ | (((flags) & 0xff) << 24))
+#define N_SET_MAGIC(exec, magic) \
+ ((exec).a_info = ((exec).a_info & 0xffff0000) | ((magic) & 0xffff))
+#define N_SET_MACHTYPE(exec, machtype) \
+ ((exec).a_info = \
+ ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
+#define N_SET_FLAGS(exec, flags) \
+ ((exec).a_info = \
+ ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
+
+/* Code indicating object file or impure executable. */
+#define OMAGIC 0407
+/* Code indicating pure executable. */
+#define NMAGIC 0410
+/* Code indicating demand-paged executable. */
+#define ZMAGIC 0413
+/* This indicates a demand-paged executable with the header in the text.
+ The first page is unmapped to help trap NULL pointer references. */
+#define QMAGIC 0314
+/* Code indicating core file. */
+#define CMAGIC 0421
+
+#define N_TRSIZE(a) ((a).a_trsize)
+#define N_DRSIZE(a) ((a).a_drsize)
+#define N_SYMSIZE(a) ((a).a_syms)
+#define N_BADMAG(x) \
+ (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC && N_MAGIC(x) != QMAGIC)
+#define _N_HDROFF(x) (1024 - sizeof (struct exec))
+#define N_TXTOFF(x) \
+ (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
+ (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
+#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
+#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
+#define N_DRELOFF(x) (N_TRELOFF(x) + N_TRSIZE(x))
+#define N_SYMOFF(x) (N_DRELOFF(x) + N_DRSIZE(x))
+#define N_STROFF(x) (N_SYMOFF(x) + N_SYMSIZE(x))
+
+/* Address of text segment in memory after it is loaded. */
+#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? 4096 : 0)
+
+/* Address of data segment in memory after it is loaded. */
+#define SEGMENT_SIZE 1024
+
+#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1))
+#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
+
+#define N_DATADDR(x) \
+ (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
+ : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
+#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
+
+#if !defined (N_NLIST_DECLARED)
+struct nlist
+{
+ union
+ {
+ char *n_name;
+ struct nlist *n_next;
+ long n_strx;
+ } n_un;
+ unsigned char n_type;
+ char n_other;
+ short n_desc;
+ unsigned long n_value;
+};
+#endif /* no N_NLIST_DECLARED. */
+
+#define N_UNDF 0
+#define N_ABS 2
+#define N_TEXT 4
+#define N_DATA 6
+#define N_BSS 8
+#define N_FN 15
+#define N_EXT 1
+#define N_TYPE 036
+#define N_STAB 0340
+#define N_INDR 0xa
+#define N_SETA 0x14 /* Absolute set element symbol. */
+#define N_SETT 0x16 /* Text set element symbol. */
+#define N_SETD 0x18 /* Data set element symbol. */
+#define N_SETB 0x1A /* Bss set element symbol. */
+#define N_SETV 0x1C /* Pointer to set vector in data area. */
+
+#if !defined (N_RELOCATION_INFO_DECLARED)
+/* This structure describes a single relocation to be performed.
+ The text-relocation section of the file is a vector of these structures,
+ all of which apply to the text section.
+ Likewise, the data-relocation section applies to the data section. */
+
+struct relocation_info
+{
+ int r_address;
+ unsigned int r_symbolnum:24;
+ unsigned int r_pcrel:1;
+ unsigned int r_length:2;
+ unsigned int r_extern:1;
+ unsigned int r_pad:4;
+};
+#endif /* no N_RELOCATION_INFO_DECLARED. */
+
+#endif /* __A_OUT_GNU_H__ */
diff --git a/libc/sysdeps/unix/sysv/linux/accept.S b/libc/sysdeps/unix/sysv/linux/accept.S
new file mode 100644
index 000000000..491ebe2ab
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/accept.S
@@ -0,0 +1,6 @@
+#define socket accept
+#define __socket __libc_accept
+#define NARGS 3
+#define NEED_CANCELLATION
+#include <socket.S>
+libc_hidden_def (accept)
diff --git a/libc/sysdeps/unix/sysv/linux/adjtime.c b/libc/sysdeps/unix/sysv/linux/adjtime.c
new file mode 100644
index 000000000..38ef805cd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/adjtime.c
@@ -0,0 +1,98 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 2002, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <sys/time.h>
+#include <sys/timex.h>
+
+#define MAX_SEC (INT_MAX / 1000000L - 2)
+#define MIN_SEC (INT_MIN / 1000000L + 2)
+
+#ifndef MOD_OFFSET
+#define modes mode
+#endif
+
+#ifndef TIMEVAL
+#define TIMEVAL timeval
+#endif
+
+#ifndef TIMEX
+#define TIMEX timex
+#endif
+
+#ifndef ADJTIME
+#define ADJTIME __adjtime
+#endif
+
+#ifndef ADJTIMEX
+#define NO_LOCAL_ADJTIME
+#define ADJTIMEX(x) INTUSE(__adjtimex) (x)
+extern int INTUSE(__adjtimex) (struct timex *__ntx);
+#endif
+
+#ifndef LINKAGE
+#define LINKAGE
+#endif
+
+LINKAGE int
+ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv)
+{
+ struct TIMEX tntx;
+
+ if (itv)
+ {
+ struct TIMEVAL tmp;
+
+ /* We will do some check here. */
+ tmp.tv_sec = itv->tv_sec + itv->tv_usec / 1000000L;
+ tmp.tv_usec = itv->tv_usec % 1000000L;
+ if (tmp.tv_sec > MAX_SEC || tmp.tv_sec < MIN_SEC)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ tntx.offset = tmp.tv_usec + tmp.tv_sec * 1000000L;
+ tntx.modes = ADJ_OFFSET_SINGLESHOT;
+ }
+ else
+ tntx.modes = 0;
+
+ if (ADJTIMEX (&tntx) < 0)
+ return -1;
+
+ if (otv)
+ {
+ if (tntx.offset < 0)
+ {
+ otv->tv_usec = -(-tntx.offset % 1000000);
+ otv->tv_sec = -(-tntx.offset / 1000000);
+ }
+ else
+ {
+ otv->tv_usec = tntx.offset % 1000000;
+ otv->tv_sec = tntx.offset / 1000000;
+ }
+ }
+ return 0;
+}
+
+#ifdef NO_LOCAL_ADJTIME
+weak_alias (__adjtime, adjtime)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/aio_sigqueue.c b/libc/sysdeps/unix/sysv/linux/aio_sigqueue.c
new file mode 100644
index 000000000..30e9fbf7e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/aio_sigqueue.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1997,1998,1999,2000,2003,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <aio.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <aio_misc.h>
+
+#ifdef __NR_rt_sigqueueinfo
+
+/* Return any pending signal or wait for one for the given time. */
+int
+__aio_sigqueue (sig, val, caller_pid)
+ int sig;
+ const union sigval val;
+ pid_t caller_pid;
+{
+ siginfo_t info;
+
+ /* First, clear the siginfo_t structure, so that we don't pass our
+ stack content to other tasks. */
+ memset (&info, 0, sizeof (siginfo_t));
+ /* We must pass the information about the data in a siginfo_t value. */
+ info.si_signo = sig;
+ info.si_code = SI_ASYNCIO;
+ info.si_pid = caller_pid;
+ info.si_uid = getuid ();
+ info.si_value = val;
+
+ return INLINE_SYSCALL (rt_sigqueueinfo, 3, info.si_pid,
+ sig, __ptrvalue (&info));
+}
+#else
+# include <rt/aio_sigqueue.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/Implies b/libc/sysdeps/unix/sysv/linux/alpha/Implies
new file mode 100644
index 000000000..1616efecb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/Implies
@@ -0,0 +1,4 @@
+unix/sysv/linux/wordsize-64
+# These supply the ABI compatibility for when long double was double.
+ieee754/ldbl-64-128
+ieee754/ldbl-opt
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/Makefile b/libc/sysdeps/unix/sysv/linux/alpha/Makefile
new file mode 100644
index 000000000..f64f23fd7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/Makefile
@@ -0,0 +1,38 @@
+ifeq ($(subdir),posix)
+sysdep_routines += oldglob
+endif
+
+ifeq ($(subdir),stdlib)
+gen-as-const-headers += ucontext-offsets.sym
+endif
+
+ifeq ($(subdir),misc)
+sysdep_headers += alpha/ptrace.h alpha/regdef.h sys/io.h
+
+sysdep_routines += ieee_get_fp_control ieee_set_fp_control \
+ ioperm llseek
+
+# Support old timeval32 entry points
+sysdep_routines += osf_select osf_gettimeofday osf_settimeofday \
+ osf_getitimer osf_setitimer osf_utimes \
+ osf_getrusage osf_wait4
+
+# Support old ipc control
+sysdep_routines += oldmsgctl oldsemctl oldshmctl
+
+CFLAGS-ioperm.c = -Wa,-mev6
+endif
+
+ifeq ($(subdir),signal)
+sysdep_routines += rt_sigaction
+endif
+
+ifeq ($(subdir),math)
+# These 2 routines are normally in libgcc{.a,_s.so.1}.
+# However, alpha -mlong-double-128 libgcc relies on
+# glibc providing _Ots* routines and without these files
+# glibc relies on __multc3/__divtc3 only provided
+# by libgcc if configured with -mlong-double-128.
+# Provide these routines here as well.
+libm-routines += multc3 divtc3
+endif # math
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/Versions b/libc/sysdeps/unix/sysv/linux/alpha/Versions
new file mode 100644
index 000000000..8709dd2a3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/Versions
@@ -0,0 +1,94 @@
+libc {
+ # The comment lines with "#errlist-compat" are magic; see
+ # sysdeps/gnu/errlist-compat.awk.
+ # When you get an error from errlist-compat.awk, you need to add a new
+ # version here. Don't do this blindly, since this means changing the ABI
+ # for all GNU/Linux configurations.
+
+ GLIBC_2.0 {
+ #errlist-compat 131
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+
+ # Unfortunately in wider use.
+ _inb; _inw; _inl; _outb; _outw; _outl; _bus_base; _bus_base_sparse;
+ _hae_shift;
+
+ # Exception handling support functions from libgcc
+ __register_frame; __register_frame_table; __deregister_frame;
+ __frame_state_for; __register_frame_info_table;
+
+ # b*
+ bus_base; bus_base_sparse;
+
+ # h*
+ hae_shift;
+
+ # i*
+ inb; inl; inw; ioperm; iopl;
+
+ # o*
+ outb; outl; outw;
+
+ # p*
+ pciconfig_read; pciconfig_write; sethae;
+ }
+ GLIBC_2.1 {
+ #errlist-compat 131
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+
+ # Linux/Alpha 64-bit timeval functions.
+ __select; select;
+ adjtime; adjtimex; __adjtimex;
+ __gettimeofday;
+
+ # glob interface change
+ glob; globfree;
+
+ # limit type change
+ getrusage;
+
+ # time type change
+ gettimeofday; getitimer;
+
+ # i*
+ ieee_get_fp_control; ieee_set_fp_control;
+
+ # s*
+ setitimer; settimeofday;
+
+ # u*
+ utimes;
+
+ # w*
+ wait4;
+ }
+ GLIBC_2.1.4 {
+ pciconfig_iobase;
+ }
+ GLIBC_2.2.2 {
+ # w*
+ wordexp;
+ }
+ GLIBC_2.3 {
+ #errlist-compat 132
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_2.4 {
+ #errlist-compat 138
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_PRIVATE {
+ __libc_alpha_cache_shape;
+ }
+}
+ld {
+ GLIBC_PRIVATE {
+ __libc_alpha_cache_shape;
+ }
+}
+librt {
+ GLIBC_2.3 {
+ # AIO functions.
+ aio_cancel; aio_cancel64;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/a.out.h b/libc/sysdeps/unix/sysv/linux/alpha/a.out.h
new file mode 100644
index 000000000..a7699f0fe
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/a.out.h
@@ -0,0 +1,197 @@
+#ifndef __A_OUT_GNU_H__
+#define __A_OUT_GNU_H__
+
+#include <bits/a.out.h>
+
+#define __GNU_EXEC_MACROS__
+
+/*
+ * OSF/1 ECOFF header structs. ECOFF files consist of:
+ * - a file header (struct filehdr),
+ * - an a.out header (struct aouthdr),
+ * - one or more section headers (struct scnhdr).
+ * The filhdr's "f_nscns" field contains the
+ * number of section headers.
+ */
+
+struct filehdr
+{
+ /* OSF/1 "file" header */
+ unsigned short f_magic, f_nscns;
+ unsigned int f_timdat;
+ unsigned long f_symptr;
+ unsigned int f_nsyms;
+ unsigned short f_opthdr, f_flags;
+};
+
+struct aouthdr
+{
+ unsigned long info; /* After that it looks quite normal.. */
+ unsigned long tsize;
+ unsigned long dsize;
+ unsigned long bsize;
+ unsigned long entry;
+ unsigned long text_start; /* With a few additions that actually make sense. */
+ unsigned long data_start;
+ unsigned long bss_start;
+ unsigned int gprmask, fprmask; /* Bitmask of general & floating point regs used in binary. */
+ unsigned long gpvalue;
+};
+
+struct scnhdr
+{
+ char s_name[8];
+ unsigned long s_paddr;
+ unsigned long s_vaddr;
+ unsigned long s_size;
+ unsigned long s_scnptr;
+ unsigned long s_relptr;
+ unsigned long s_lnnoptr;
+ unsigned short s_nreloc;
+ unsigned short s_nlnno;
+ unsigned int s_flags;
+};
+
+struct exec
+{
+ /* OSF/1 "file" header */
+ struct filehdr fh;
+ struct aouthdr ah;
+};
+
+#define a_info ah.info
+#define a_text ah.tsize
+#define a_data ah.dsize
+#define a_bss ah.bsize
+#define a_entry ah.entry
+#define a_textstart ah.text_start
+#define a_datastart ah.data_start
+#define a_bssstart ah.bss_start
+#define a_gprmask ah.gprmask
+#define a_fprmask ah.fprmask
+#define a_gpvalue ah.gpvalue
+
+
+#define AOUTHSZ sizeof(struct aouthdr)
+#define SCNHSZ sizeof(struct scnhdr)
+#define SCNROUND 16
+
+enum machine_type
+{
+ M_OLDSUN2 = 0,
+ M_68010 = 1,
+ M_68020 = 2,
+ M_SPARC = 3,
+ M_386 = 100,
+ M_MIPS1 = 151,
+ M_MIPS2 = 152
+};
+
+#define N_MAGIC(exec) ((exec).a_info & 0xffff)
+#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
+#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
+#define N_SET_INFO(exec, magic, type, flags) \
+ ((exec).a_info = ((magic) & 0xffff) \
+ | (((int)(type) & 0xff) << 16) \
+ | (((flags) & 0xff) << 24))
+#define N_SET_MAGIC(exec, magic) \
+ ((exec).a_info = ((exec).a_info & 0xffff0000) | ((magic) & 0xffff))
+#define N_SET_MACHTYPE(exec, machtype) \
+ ((exec).a_info = \
+ ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
+#define N_SET_FLAGS(exec, flags) \
+ ((exec).a_info = \
+ ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
+
+/* Code indicating object file or impure executable. */
+#define OMAGIC 0407
+/* Code indicating pure executable. */
+#define NMAGIC 0410
+/* Code indicating demand-paged executable. */
+#define ZMAGIC 0413
+/* This indicates a demand-paged executable with the header in the text.
+ The first page is unmapped to help trap NULL pointer references. */
+#define QMAGIC 0314
+/* Code indicating core file. */
+#define CMAGIC 0421
+
+#define N_TRSIZE(x) 0
+#define N_DRSIZE(x) 0
+#define N_SYMSIZE(x) 0
+#define N_BADMAG(x) \
+ (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC && N_MAGIC(x) != QMAGIC)
+#define _N_HDROFF(x) (1024 - sizeof (struct exec))
+#define N_TXTOFF(x) \
+ ((long) N_MAGIC(x) == ZMAGIC ? 0 : \
+ (sizeof (struct exec) + (x).fh.f_nscns * SCNHSZ + SCNROUND - 1) \
+ & ~(SCNROUND - 1))
+
+#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
+#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
+#define N_DRELOFF(x) (N_TRELOFF(x) + N_TRSIZE(x))
+#define N_SYMOFF(x) (N_DRELOFF(x) + N_DRSIZE(x))
+#define N_STROFF(x) (N_SYMOFF(x) + N_SYMSIZE(x))
+
+/* Address of text segment in memory after it is loaded. */
+#define N_TXTADDR(x) ((x).a_textstart)
+
+/* Address of data segment in memory after it is loaded. */
+#define SEGMENT_SIZE 1024
+
+#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1))
+#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
+
+#define N_DATADDR(x) ((x).a_datastart)
+#define N_BSSADDR(x) ((x).a_bssstart)
+
+#if !defined (N_NLIST_DECLARED)
+struct nlist
+{
+ union
+ {
+ char *n_name;
+ struct nlist *n_next;
+ long n_strx;
+ } n_un;
+ unsigned char n_type;
+ char n_other;
+ short n_desc;
+ unsigned long n_value;
+};
+#endif /* no N_NLIST_DECLARED. */
+
+#define N_UNDF 0
+#define N_ABS 2
+#define N_TEXT 4
+#define N_DATA 6
+#define N_BSS 8
+#define N_FN 15
+#define N_EXT 1
+#define N_TYPE 036
+#define N_STAB 0340
+#define N_INDR 0xa
+#define N_SETA 0x14 /* Absolute set element symbol. */
+#define N_SETT 0x16 /* Text set element symbol. */
+#define N_SETD 0x18 /* Data set element symbol. */
+#define N_SETB 0x1A /* Bss set element symbol. */
+#define N_SETV 0x1C /* Pointer to set vector in data area. */
+
+#if !defined (N_RELOCATION_INFO_DECLARED)
+/* This structure describes a single relocation to be performed.
+ The text-relocation section of the file is a vector of these structures,
+ all of which apply to the text section.
+ Likewise, the data-relocation section applies to the data section. */
+
+struct relocation_info
+{
+ int r_address;
+ unsigned int r_symbolnum:24;
+ unsigned int r_pcrel:1;
+ unsigned int r_length:2;
+ unsigned int r_extern:1;
+ unsigned int r_pad:4;
+};
+#endif /* no N_RELOCATION_INFO_DECLARED. */
+
+#endif /* __A_OUT_GNU_H__ */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/adjtime.c b/libc/sysdeps/unix/sysv/linux/alpha/adjtime.c
new file mode 100644
index 000000000..1700524d3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/adjtime.c
@@ -0,0 +1,220 @@
+/* Copyright (C) 1998,2000,2002,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <shlib-compat.h>
+#include <sysdep.h>
+#include <sys/time.h>
+#include <kernel-features.h>
+
+#if !defined __ASSUME_TIMEVAL64 || SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+struct timeval32
+{
+ int tv_sec, tv_usec;
+};
+
+struct timex32 {
+ unsigned int modes; /* mode selector */
+ long offset; /* time offset (usec) */
+ long freq; /* frequency offset (scaled ppm) */
+ long maxerror; /* maximum error (usec) */
+ long esterror; /* estimated error (usec) */
+ int status; /* clock command/status */
+ long constant; /* pll time constant */
+ long precision; /* clock precision (usec) (read only) */
+ long tolerance; /* clock frequency tolerance (ppm)
+ * (read only)
+ */
+ struct timeval32 time; /* (read only) */
+ long tick; /* (modified) usecs between clock ticks */
+
+ long ppsfreq; /* pps frequency (scaled ppm) (ro) */
+ long jitter; /* pps jitter (us) (ro) */
+ int shift; /* interval duration (s) (shift) (ro) */
+ long stabil; /* pps stability (scaled ppm) (ro) */
+ long jitcnt; /* jitter limit exceeded (ro) */
+ long calcnt; /* calibration intervals (ro) */
+ long errcnt; /* calibration errors (ro) */
+ long stbcnt; /* stability limit exceeded (ro) */
+
+ int :32; int :32; int :32; int :32;
+ int :32; int :32; int :32; int :32;
+ int :32; int :32; int :32; int :32;
+};
+
+#define TIMEVAL timeval32
+#define TIMEX timex32
+#define ADJTIME attribute_compat_text_section __adjtime_tv32
+#define ADJTIMEX(x) INLINE_SYSCALL (old_adjtimex, 1, x)
+#define ADJTIMEX32(x) INLINE_SYSCALL (old_adjtimex, 1, x)
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+#define LINKAGE
+#else
+#define LINKAGE static
+#endif
+
+LINKAGE int ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv);
+
+#include <sysdeps/unix/sysv/linux/adjtime.c>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+int
+attribute_compat_text_section
+__adjtimex_tv32 (struct timex32 *tx) { return ADJTIMEX (tx); }
+strong_alias (__adjtimex_tv32, __adjtimex_tv32_1);
+strong_alias (__adjtimex_tv32, __adjtimex_tv32_2);
+compat_symbol (libc, __adjtimex_tv32_1, __adjtimex, GLIBC_2_0);
+compat_symbol (libc, __adjtimex_tv32_2, adjtimex, GLIBC_2_0);
+compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0);
+#endif
+#endif /* !__ASSUME_TIMEVAL64 || SHLIB_COMPAT */
+
+#undef TIMEVAL
+#define TIMEVAL timeval
+#undef TIMEX
+#define TIMEX timex
+#undef ADJTIMEX
+#define ADJTIMEX(x) INLINE_SYSCALL (adjtimex, 1, x)
+
+#undef LINKAGE
+#undef ADJTIME
+#if !defined __ASSUME_TIMEVAL64
+#define LINKAGE static
+#define ADJTIME __adjtime_tv64
+#endif
+
+#include <sysdeps/unix/sysv/linux/adjtime.c>
+#include <stdbool.h>
+
+#if !defined __ASSUME_TIMEVAL64
+static bool missing_adjtimex;
+
+int
+__adjtime (itv, otv)
+ const struct timeval *itv;
+ struct timeval *otv;
+{
+ struct timeval32 itv32, otv32;
+ int ret;
+
+ switch (missing_adjtimex)
+ {
+ case false:
+ ret = __adjtime_tv64 (itv, otv);
+ if (ret && errno == ENOSYS)
+ missing_adjtimex = 1;
+ else
+ break;
+
+ /* FALLTHRU */
+
+ default:
+ itv32.tv_sec = itv->tv_sec;
+ itv32.tv_usec = itv->tv_usec;
+ ret = __adjtime_tv32 (&itv32, &otv32);
+ if (ret == 0)
+ {
+ otv->tv_sec = otv32.tv_sec;
+ otv->tv_usec = otv32.tv_usec;
+ }
+ break;
+ }
+
+ return ret;
+}
+#endif
+
+versioned_symbol (libc, __adjtime, adjtime, GLIBC_2_1);
+
+int
+__adjtimex_tv64 (struct timex *tx)
+{
+#if defined __ASSUME_TIMEVAL64
+ return ADJTIMEX (tx);
+#else
+ struct timex32 tx32;
+ int ret;
+
+ switch (missing_adjtimex)
+ {
+ case false:
+ ret = ADJTIMEX (tx);
+ if (ret && errno == ENOSYS)
+ missing_adjtimex = 1;
+ else
+ break;
+
+ /* FALLTHRU */
+
+ default:
+ tx32.modes = tx->modes;
+ tx32.offset = tx->offset;
+ tx32.freq = tx->freq;
+ tx32.maxerror = tx->maxerror;
+ tx32.esterror = tx->esterror;
+ tx32.status = tx->status;
+ tx32.constant = tx->constant;
+ tx32.precision = tx->precision;
+ tx32.tolerance = tx->tolerance;
+ tx32.time.tv_sec = tx->time.tv_sec;
+ tx32.time.tv_sec = tx->time.tv_usec;
+ tx32.tick = tx->tick;
+ tx32.ppsfreq = tx->ppsfreq;
+ tx32.jitter = tx->jitter;
+ tx32.shift = tx->shift;
+ tx32.stabil = tx->stabil;
+ tx32.jitcnt = tx->jitcnt;
+ tx32.calcnt = tx->calcnt;
+ tx32.errcnt = tx->errcnt;
+ tx32.stbcnt = tx->stbcnt;
+
+ ret = ADJTIMEX32 (&tx32);
+ if (ret == 0)
+ {
+ tx->modes = tx32.modes;
+ tx->offset = tx32.offset;
+ tx->freq = tx32.freq;
+ tx->maxerror = tx32.maxerror;
+ tx->esterror = tx32.esterror;
+ tx->status = tx32.status;
+ tx->constant = tx32.constant;
+ tx->precision = tx32.precision;
+ tx->tolerance = tx32.tolerance;
+ tx->time.tv_sec = tx32.time.tv_sec;
+ tx->time.tv_usec = tx32.time.tv_sec;
+ tx->tick = tx32.tick;
+ tx->ppsfreq = tx32.ppsfreq;
+ tx->jitter = tx32.jitter;
+ tx->shift = tx32.shift;
+ tx->stabil = tx32.stabil;
+ tx->jitcnt = tx32.jitcnt;
+ tx->calcnt = tx32.calcnt;
+ tx->errcnt = tx32.errcnt;
+ tx->stbcnt = tx32.stbcnt;
+ }
+ break;
+ }
+
+ return ret;
+#endif
+}
+
+strong_alias (__adjtimex_tv64, __adjtimex_internal);
+strong_alias (__adjtimex_tv64, __adjtimex_tv64p);
+weak_alias (__adjtimex_tv64, ntp_adjtime);
+versioned_symbol (libc, __adjtimex_tv64, __adjtimex, GLIBC_2_1);
+versioned_symbol (libc, __adjtimex_tv64p, adjtimex, GLIBC_2_1);
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/alpha/ptrace.h b/libc/sysdeps/unix/sysv/linux/alpha/alpha/ptrace.h
new file mode 100644
index 000000000..57b96d64d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/alpha/ptrace.h
@@ -0,0 +1,18 @@
+#ifndef __alpha_ptrace_h__
+#define __alpha_ptrace_h__
+
+/*
+ * Mostly for OSF/1 compatibility.
+ */
+
+#define REG_BASE 0
+#define NGP_REGS 32
+#define NFP_REGS 32
+
+#define GPR_BASE REG_BASE
+#define FPR_BASE (GPR_BASE+NGP_REGS)
+#define PC (FPR_BASE+NFP_REGS)
+#define SPR_PS (PC+1)
+#define NPTRC_REGS (SPR_PS+1)
+
+#endif /* __alpha_ptrace_h__ */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/alpha/regdef.h b/libc/sysdeps/unix/sysv/linux/alpha/alpha/regdef.h
new file mode 100644
index 000000000..142df9c4f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/alpha/regdef.h
@@ -0,0 +1,44 @@
+#ifndef __alpha_regdef_h__
+#define __alpha_regdef_h__
+
+#define v0 $0 /* function return value */
+
+#define t0 $1 /* temporary registers (caller-saved) */
+#define t1 $2
+#define t2 $3
+#define t3 $4
+#define t4 $5
+#define t5 $6
+#define t6 $7
+#define t7 $8
+
+#define s0 $9 /* saved-registers (callee-saved registers) */
+#define s1 $10
+#define s2 $11
+#define s3 $12
+#define s4 $13
+#define s5 $14
+#define s6 $15
+#define fp s6 /* frame-pointer (s6 in frame-less procedures) */
+
+#define a0 $16 /* argument registers (caller-saved) */
+#define a1 $17
+#define a2 $18
+#define a3 $19
+#define a4 $20
+#define a5 $21
+
+#define t8 $22 /* more temps (caller-saved) */
+#define t9 $23
+#define t10 $24
+#define t11 $25
+#define ra $26 /* return address register */
+#define t12 $27
+
+#define pv t12 /* procedure-variable register */
+#define AT $at /* assembler temporary */
+#define gp $29 /* global pointer */
+#define sp $30 /* stack pointer */
+#define zero $31 /* reads as zero, writes are noops */
+
+#endif /* __alpha_regdef_h__ */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/a.out.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/a.out.h
new file mode 100644
index 000000000..82a3dd4c0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/a.out.h
@@ -0,0 +1,9 @@
+#ifndef __A_OUT_GNU_H__
+# error "Never use <bits/a.out.h> directly; include <a.out.h> instead."
+#endif
+#ifndef __A_OUT_GNU_H__
+# error "Never use <bits/a.out.h> directly; include <a.out.h> instead."
+#endif
+#ifndef __A_OUT_GNU_H__
+# error "Never use <bits/a.out.h> directly; include <a.out.h> instead."
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/dirent.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
new file mode 100644
index 000000000..6ed74783a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/dirent.h
@@ -0,0 +1,55 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_DIRENT_H
+#define _BITS_DIRENT_H 1
+
+struct dirent
+ {
+#ifdef __USE_FILE_OFFSET64
+ __ino64_t d_ino;
+#else
+ __ino_t d_ino;
+ int __pad;
+#endif
+ __off_t d_off;
+ unsigned short int d_reclen;
+ unsigned char d_type;
+ char d_name[256]; /* We must not include limits.h! */
+ };
+
+#ifdef __USE_LARGEFILE64
+/* Note dirent64 is the same as dirent. */
+struct dirent64
+ {
+ __ino64_t d_ino;
+ __off64_t d_off;
+ unsigned short int d_reclen;
+ unsigned char d_type;
+ char d_name[256]; /* We must not include limits.h! */
+ };
+#endif
+
+#define d_fileno d_ino /* Backwards compatibility. */
+
+#undef _DIRENT_HAVE_D_NAMLEN
+#define _DIRENT_HAVE_D_RECLEN
+#define _DIRENT_HAVE_D_OFF
+#define _DIRENT_HAVE_D_TYPE
+
+#endif /* bits/dirent.h */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/elfclass.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/elfclass.h
new file mode 100644
index 000000000..e5aa4a0fb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/elfclass.h
@@ -0,0 +1,14 @@
+/* This file specifies the native word size of the machine, which indicates
+ the ELF file class used for executables and shared objects on this
+ machine. */
+
+#ifndef _LINK_H
+# error "Never use <bits/elfclass.h> directly; include <link.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#define __ELF_NATIVE_CLASS __WORDSIZE
+
+/* Linux/Alpha is exceptional as it has .hash section with 64 bit entries. */
+typedef uint64_t Elf_Symndx;
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/errno.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/errno.h
new file mode 100644
index 000000000..8b2f152a1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/errno.h
@@ -0,0 +1,58 @@
+/* Error constants. Linux/Alpha specific version.
+ Copyright (C) 1996,1997,1998,1999,2002,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef _ERRNO_H
+
+# undef EDOM
+# undef EILSEQ
+# undef ERANGE
+# include <linux/errno.h>
+
+/* Linux has no ENOTSUP error code. */
+# define ENOTSUP EOPNOTSUPP
+
+# ifndef ECANCELED
+# define ECANCELED 131
+# endif
+
+/* Support for error codes to support robust mutexes was added later, too. */
+# ifndef EOWNERDEAD
+# define EOWNERDEAD 136
+# define ENOTRECOVERABLE 137
+# endif
+
+# ifndef __ASSEMBLER__
+/* Function to get address of global `errno' variable. */
+extern int *__errno_location (void) __THROW __attribute__ ((__const__));
+
+# if !defined _LIBC || defined _LIBC_REENTRANT
+/* When using threads, errno is a per-thread value. */
+# define errno (*__errno_location ())
+# endif
+# endif /* !__ASSEMBLER__ */
+#endif /* _ERRNO_H */
+
+#if !defined _ERRNO_H && defined __need_Emath
+/* This is ugly but the kernel header is not clean enough. We must
+ define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
+ defined. */
+# define EDOM 33 /* Math argument out of domain of function. */
+# define EILSEQ 116 /* Illegal byte sequence. */
+# define ERANGE 34 /* Math result not representable. */
+#endif /* !_ERRNO_H && __need_Emath */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h
new file mode 100644
index 000000000..6084c38c9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h
@@ -0,0 +1,228 @@
+/* O_*, F_*, FD_* bit values for Linux.
+ Copyright (C) 1995-2000, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#include <sys/types.h>
+#ifdef __USE_GNU
+# include <bits/uio.h>
+#endif
+
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_ACCMODE 0003
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+#define O_CREAT 01000 /* not fcntl */
+#define O_TRUNC 02000 /* not fcntl */
+#define O_EXCL 04000 /* not fcntl */
+#define O_NOCTTY 010000 /* not fcntl */
+
+#define O_NONBLOCK 00004
+#define O_APPEND 00010
+#define O_NDELAY O_NONBLOCK
+#define O_SYNC 040000
+#define O_FSYNC O_SYNC
+#define O_ASYNC 020000 /* fcntl, for BSD compatibility */
+
+#ifdef __USE_GNU
+# define O_DIRECTORY 0100000 /* Must be a directory. */
+# define O_NOFOLLOW 0200000 /* Do not follow links. */
+# define O_DIRECT 02000000 /* Direct disk access. */
+# define O_NOATIME 04000000 /* Do not set atime. */
+#endif
+
+#ifdef __USE_LARGEFILE64
+/* Not necessary, files are always with 64bit off_t. */
+# define O_LARGEFILE 0
+#endif
+
+/* For now Linux has synchronisity options for data and read operations.
+ We define the symbols here but let them do the same as O_SYNC since
+ this is a superset. */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC O_SYNC /* Synchronize data. */
+# define O_RSYNC O_SYNC /* Synchronize read operations. */
+#endif
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#define F_GETLK 7 /* Get record locking info. */
+#define F_SETLK 8 /* Set record locking info (non-blocking). */
+#define F_SETLKW 9 /* Set record locking info (blocking). */
+#define F_GETLK64 F_GETLK /* Get record locking info. */
+#define F_SETLK64 F_SETLK /* Set record locking info (non-blocking). */
+#define F_SETLKW64 F_SETLKW /* Set record locking info (blocking). */
+
+#if defined __USE_BSD || defined __USE_UNIX98
+# define F_SETOWN 5 /* Get owner of socket (receiver of SIGIO). */
+# define F_GETOWN 6 /* Set owner of socket (receiver of SIGIO). */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETSIG 10 /* Set number of signal to be sent. */
+# define F_GETSIG 11 /* Get number of signal to be sent. */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETLEASE 1024 /* Set a lease. */
+# define F_GETLEASE 1025 /* Enquire what lease is active. */
+# define F_NOTIFY 1026 /* Request notfications on a directory. */
+#endif
+
+/* for F_[GET|SET]FD */
+#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf() */
+#define F_RDLCK 1 /* Read lock. */
+#define F_WRLCK 2 /* Write lock. */
+#define F_UNLCK 8 /* Remove lock. */
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK 16 /* or 3 */
+#define F_SHLCK 32 /* or 4 */
+
+/* Operations for bsd flock(), also used by the kernel implementation */
+#ifdef __USE_BSD
+# define LOCK_SH 1 /* shared lock */
+# define LOCK_EX 2 /* exclusive lock */
+# define LOCK_NB 4 /* or'd with one of the above to prevent
+ blocking */
+# define LOCK_UN 8 /* remove lock */
+#endif
+
+#ifdef __USE_GNU
+# define LOCK_MAND 32 /* This is a mandatory flock: */
+# define LOCK_READ 64 /* ... which allows concurrent read operations. */
+# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */
+# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */
+#endif
+
+#ifdef __USE_GNU
+/* Types of directory notifications that may be requested with F_NOTIFY. */
+# define DN_ACCESS 0x00000001 /* File accessed. */
+# define DN_MODIFY 0x00000002 /* File modified. */
+# define DN_CREATE 0x00000004 /* File created. */
+# define DN_DELETE 0x00000008 /* File removed. */
+# define DN_RENAME 0x00000010 /* File renamed. */
+# define DN_ATTRIB 0x00000020 /* File changed attibutes. */
+# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */
+#endif
+
+/* We don't need to support __USE_FILE_OFFSET64. */
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+#endif
+
+
+/* Define some more compatibility macros to be backward compatible with
+ BSD systems which did not managed to hide these kernel macros. */
+#ifdef __USE_BSD
+# define FAPPEND O_APPEND
+# define FFSYNC O_FSYNC
+# define FASYNC O_ASYNC
+# define FNONBLOCK O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif /* Use BSD. */
+
+/* Advise to `posix_fadvise'. */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
+# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
+#endif
+
+
+#ifdef __USE_GNU
+/* Flags for SYNC_FILE_RANGE. */
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+
+/* Flags for SPLICE and VMSPLICE. */
+# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */
+# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing
+ (but we may still block on the fd
+ we splice from/to). */
+# define SPLICE_F_MORE 4 /* Expect more data. */
+# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
+#endif
+
+__BEGIN_DECLS
+
+#ifdef __USE_GNU
+
+/* Provide kernel hint to read ahead. */
+extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
+ __THROW;
+
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice address range into a pipe. */
+extern int vmsplice (int __fdout, const struct iovec *__iov, size_t __count,
+ unsigned int __flags);
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/ioctls.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/ioctls.h
new file mode 100644
index 000000000..c525046e5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/ioctls.h
@@ -0,0 +1,37 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IOCTL_H
+# error "Never use <bits/ioctls.h> directly; include <sys/ioctl.h> instead."
+#endif
+
+/* Use the definitions from the kernel header files. */
+#include <asm/ioctls.h>
+
+/* Oh well, this is necessary since the kernel data structure is
+ different from the user-level version. */
+#undef TCGETS
+#undef TCSETS
+#undef TCSETSW
+#undef TCSETSF
+#define TCGETS _IOR ('t', 19, char[44])
+#define TCSETS _IOW ('t', 20, char[44])
+#define TCSETSW _IOW ('t', 21, char[44])
+#define TCSETSF _IOW ('t', 22, char[44])
+
+#include <linux/sockios.h>
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/ipc.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/ipc.h
new file mode 100644
index 000000000..77f3c938d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/ipc.h
@@ -0,0 +1,55 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IPC_H
+# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Mode bits for `msgget', `semget', and `shmget'. */
+#define IPC_CREAT 01000 /* Create key if key does not exist. */
+#define IPC_EXCL 02000 /* Fail if key exists. */
+#define IPC_NOWAIT 04000 /* Return error on wait. */
+
+/* Control commands for `msgctl', `semctl', and `shmctl'. */
+#define IPC_RMID 0 /* Remove identifier. */
+#define IPC_SET 1 /* Set `ipc_perm' options. */
+#define IPC_STAT 2 /* Get `ipc_perm' options. */
+#ifdef __USE_GNU
+# define IPC_INFO 3 /* See ipcs. */
+#endif
+
+/* Special key values. */
+#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
+
+
+/* Data structure used to pass permission information to IPC operations. */
+struct ipc_perm
+ {
+ __key_t __key; /* Key. */
+ unsigned int uid; /* Owner's user ID. */
+ unsigned int gid; /* Owner's group ID. */
+ unsigned int cuid; /* Creator's user ID. */
+ unsigned int cgid; /* Creator's group ID. */
+ unsigned int mode; /* Read/write permission. */
+ unsigned short int __seq; /* Sequence number. */
+ unsigned short int __pad1;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ };
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/mman.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/mman.h
new file mode 100644
index 000000000..2f0e56491
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/mman.h
@@ -0,0 +1,118 @@
+/* Definitions for POSIX memory map interface. Linux/Alpha version.
+ Copyright (C) 1997, 1998, 2000, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MMAN_H
+# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
+#endif
+
+/* The following definitions basically come from the kernel headers.
+ But the kernel header is not namespace clean. */
+
+
+/* Protections are chosen from these bits, OR'd together. The
+ implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ without PROT_READ. The only guarantees are that no writing will be
+ allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
+
+#define PROT_READ 0x1 /* Page can be read. */
+#define PROT_WRITE 0x2 /* Page can be written. */
+#define PROT_EXEC 0x4 /* Page can be executed. */
+#define PROT_NONE 0x0 /* Page can not be accessed. */
+#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
+ growsdown vma (mprotect only). */
+#define PROT_GROWSUP 0x02000000 /* Extend change to start of
+ growsup vma (mprotect only). */
+
+/* Sharing types (must choose one and only one of these). */
+#define MAP_SHARED 0x01 /* Share changes. */
+#define MAP_PRIVATE 0x02 /* Changes are private. */
+#ifdef __USE_MISC
+# define MAP_TYPE 0x0f /* Mask for type of mapping. */
+#endif
+
+/* Other flags. */
+#define MAP_FIXED 0x100 /* Interpret addr exactly. */
+#ifdef __USE_MISC
+# define MAP_FILE 0
+# define MAP_ANONYMOUS 0x10 /* Don't use a file. */
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+
+/* Not used by Linux, but here to make sure we don't clash with
+ OSF/1 defines. */
+#if 0 && defined __USE_BSD
+# define MAP_HASSEMAPHORE 0x0200
+# define MAP_INHERIT 0x0400
+# define MAP_UNALIGNED 0x0800
+#endif
+
+/* These are Linux-specific. */
+#ifdef __USE_MISC
+# define MAP_GROWSDOWN 0x01000 /* Stack-like segment. */
+# define MAP_DENYWRITE 0x02000 /* ETXTBSY */
+# define MAP_EXECUTABLE 0x04000 /* Mark it as an executable. */
+# define MAP_LOCKED 0x08000 /* Lock the mapping. */
+# define MAP_NORESERVE 0x10000 /* Don't check for reservations. */
+# define MAP_POPULATE 0x20000 /* Populate (prefault) pagetables. */
+# define MAP_NONBLOCK 0x40000 /* Do not block on IO. */
+#endif
+
+/* Flags to `msync'. */
+#define MS_ASYNC 1 /* Sync memory asynchronously. */
+#define MS_SYNC 2 /* Synchronous memory sync. */
+#define MS_INVALIDATE 4 /* Invalidate the caches. */
+
+/* Flags for `mlockall'. */
+#define MCL_CURRENT 8192 /* Lock all currently mapped pages. */
+#define MCL_FUTURE 16384 /* Lock all additions to address
+ space. */
+
+/* Flags for `mremap'. */
+#ifdef __USE_GNU
+# define MREMAP_MAYMOVE 1
+# define MREMAP_FIXED 2
+#endif
+
+/* Advice to `madvise'. */
+#ifdef __USE_BSD
+# define MADV_NORMAL 0 /* No further special treatment. */
+# define MADV_RANDOM 1 /* Expect random page references. */
+# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define MADV_WILLNEED 3 /* Will need these pages. */
+# define MADV_DONTNEED 6 /* Don't need these pages. */
+# define MADV_REMOVE 9 /* Remove these pages and resources. */
+# define MADV_DONTFORK 10 /* Do not inherit across fork. */
+# define MADV_DOFORK 11 /* Do inherit across fork. */
+#endif
+
+/* The POSIX people had to invent similar names for the same things. */
+#ifdef __USE_XOPEN2K
+# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_MADV_DONTNEED 6 /* Don't need these pages. */
+#endif
+
+/* Not used by Linux, but here to make sure we don't clash with
+ OSF/1 defines. */
+#if 0 && defined __USE_BSD
+# define MADV_DONTNEED_COMPAT 4 /* Old version? */
+# define MADV_SPACEAVAIL 5 /* Ensure resources are available. */
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/msq.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/msq.h
new file mode 100644
index 000000000..ab251eaf7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/msq.h
@@ -0,0 +1,74 @@
+/* Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Define options for message queue functions. */
+#define MSG_NOERROR 010000 /* no error if message is too big */
+#ifdef __USE_GNU
+# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+#endif
+
+/* Types used in the structure definition. */
+typedef unsigned long int msgqnum_t;
+typedef unsigned long int msglen_t;
+
+
+/* Structure of record for one message inside the kernel.
+ The type `struct msg' is opaque. */
+struct msqid_ds
+{
+ struct ipc_perm msg_perm; /* structure describing operation permission */
+ __time_t msg_stime; /* time of last msgsnd command */
+ __time_t msg_rtime; /* time of last msgrcv command */
+ __time_t msg_ctime; /* time of last change */
+ unsigned long int __msg_cbytes; /* current number of bytes on queue */
+ msgqnum_t msg_qnum; /* number of messages currently on queue */
+ msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+ __pid_t msg_lspid; /* pid of last msgsnd() */
+ __pid_t msg_lrpid; /* pid of last msgrcv() */
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+};
+
+#ifdef __USE_MISC
+
+# define msg_cbytes __msg_cbytes
+
+/* ipcs ctl commands */
+# define MSG_STAT 11
+# define MSG_INFO 12
+
+/* buffer for msgctl calls IPC_INFO, MSG_INFO */
+struct msginfo
+ {
+ int msgpool;
+ int msgmap;
+ int msgmax;
+ int msgmnb;
+ int msgmni;
+ int msgssz;
+ int msgtql;
+ unsigned short int msgseg;
+ };
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/netdb.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/netdb.h
new file mode 100644
index 000000000..e3664fd29
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/netdb.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NETDB_H
+# error "Never include <bits/netdb.h> directly; use <netdb.h> instead."
+#endif
+
+
+/* Description of data base entry for a single network. NOTE: here a
+ poor assumption is made. The network number is expected to fit
+ into an unsigned long int variable. */
+struct netent
+{
+ char *n_name; /* Official name of network. */
+ char **n_aliases; /* Alias list. */
+ int n_addrtype; /* Net address type. */
+ /* XXX We should probably use uint32_t for the field and ensure
+ compatiblity by adding appropriate padding. */
+ unsigned long int n_net; /* Network number. */
+};
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/resource.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/resource.h
new file mode 100644
index 000000000..216374584
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/resource.h
@@ -0,0 +1,225 @@
+/* Bit values & structures for resource limits. Alpha/Linux version.
+ Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2004, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_RESOURCE_H
+# error "Never use <bits/resource.h> directly; include <sys/resource.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Transmute defines to enumerations. The macro re-definitions are
+ necessary because some programs want to test for operating system
+ features with #ifdef RUSAGE_SELF. In ISO C the reflexive
+ definition is a no-op. */
+
+/* Kinds of resource limit. */
+enum __rlimit_resource
+{
+ /* Per-process CPU limit, in seconds. */
+ RLIMIT_CPU = 0,
+#define RLIMIT_CPU RLIMIT_CPU
+
+ /* Largest file that can be created, in bytes. */
+ RLIMIT_FSIZE = 1,
+#define RLIMIT_FSIZE RLIMIT_FSIZE
+
+ /* Maximum size of data segment, in bytes. */
+ RLIMIT_DATA = 2,
+#define RLIMIT_DATA RLIMIT_DATA
+
+ /* Maximum size of stack segment, in bytes. */
+ RLIMIT_STACK = 3,
+#define RLIMIT_STACK RLIMIT_STACK
+
+ /* Largest core file that can be created, in bytes. */
+ RLIMIT_CORE = 4,
+#define RLIMIT_CORE RLIMIT_CORE
+
+ /* Largest resident set size, in bytes.
+ This affects swapping; processes that are exceeding their
+ resident set size will be more likely to have physical memory
+ taken from them. */
+ __RLIMIT_RSS = 5,
+#define RLIMIT_RSS __RLIMIT_RSS
+
+ /* Number of open files. */
+ RLIMIT_NOFILE = 6,
+ __RLIMIT_OFILE = RLIMIT_NOFILE, /* BSD name for same. */
+#define RLIMIT_NOFILE RLIMIT_NOFILE
+#define RLIMIT_OFILE __RLIMIT_OFILE
+
+ /* Address space limit (?) */
+ RLIMIT_AS = 7,
+#define RLIMIT_AS RLIMIT_AS
+
+ /* Number of processes. */
+ __RLIMIT_NPROC = 8,
+#define RLIMIT_NPROC __RLIMIT_NPROC
+
+ /* Locked-in-memory address space. */
+ __RLIMIT_MEMLOCK = 9,
+#define RLIMIT_MEMLOCK __RLIMIT_MEMLOCK
+
+ /* Maximum number of file locks. */
+ __RLIMIT_LOCKS = 10,
+#define RLIMIT_LOCKS __RLIMIT_LOCKS
+
+ /* Maximum number of pending signals. */
+ __RLIMIT_SIGPENDING = 11,
+#define RLIMIT_SIGPENDING __RLIMIT_SIGPENDING
+
+ /* Maximum bytes in POSIX message queues. */
+ __RLIMIT_MSGQUEUE = 12,
+#define RLIMIT_MSGQUEUE __RLIMIT_MSGQUEUE
+
+ /* Maximum nice priority allowed to raise to.
+ Nice levels 19 .. -20 correspond to 0 .. 39
+ values of this resource limit. */
+ __RLIMIT_NICE = 13,
+#define RLIMIT_NICE __RLIMIT_NICE
+
+ /* Maximum realtime priority allowed for non-priviledged
+ processes. */
+ __RLIMIT_RTPRIO = 14,
+#define RLIMIT_RTPRIO __RLIMIT_RTPRIO
+
+ __RLIMIT_NLIMITS = 15,
+ __RLIM_NLIMITS = __RLIMIT_NLIMITS
+#define RLIMIT_NLIMITS __RLIMIT_NLIMITS
+#define RLIM_NLIMITS __RLIM_NLIMITS
+};
+
+/* Value to indicate that there is no limit. */
+#ifndef __USE_FILE_OFFSET64
+# define RLIM_INFINITY ((long int)(~0UL >> 1))
+#else
+# define RLIM_INFINITY 0x7fffffffffffffffLL
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define RLIM64_INFINITY 0x7fffffffffffffffLL
+#endif
+
+/* We can represent all limits. */
+#define RLIM_SAVED_MAX RLIM_INFINITY
+#define RLIM_SAVED_CUR RLIM_INFINITY
+
+
+/* Type for resource quantity measurement. */
+#ifndef __USE_FILE_OFFSET64
+typedef __rlim_t rlim_t;
+#else
+typedef __rlim64_t rlim_t;
+#endif
+#ifdef __USE_LARGEFILE64
+typedef __rlim64_t rlim64_t;
+#endif
+
+struct rlimit
+ {
+ /* The current (soft) limit. */
+ rlim_t rlim_cur;
+ /* The hard limit. */
+ rlim_t rlim_max;
+ };
+
+#ifdef __USE_LARGEFILE64
+struct rlimit64
+ {
+ /* The current (soft) limit. */
+ rlim64_t rlim_cur;
+ /* The hard limit. */
+ rlim64_t rlim_max;
+ };
+#endif
+
+/* Whose usage statistics do you want? */
+enum __rusage_who
+{
+ /* The calling process. */
+ RUSAGE_SELF = 0,
+#define RUSAGE_SELF RUSAGE_SELF
+
+ /* All of its terminated child processes. */
+ RUSAGE_CHILDREN = -1
+#define RUSAGE_CHILDREN RUSAGE_CHILDREN
+};
+
+#define __need_timeval
+#include <bits/time.h> /* For `struct timeval'. */
+
+/* Structure which says how much of each resource has been used. */
+struct rusage
+ {
+ /* Total amount of user time used. */
+ struct timeval ru_utime;
+ /* Total amount of system time used. */
+ struct timeval ru_stime;
+ /* Maximum resident set size (in kilobytes). */
+ long int ru_maxrss;
+ /* Amount of sharing of text segment memory
+ with other processes (kilobyte-seconds). */
+ long int ru_ixrss;
+ /* Amount of data segment memory used (kilobyte-seconds). */
+ long int ru_idrss;
+ /* Amount of stack memory used (kilobyte-seconds). */
+ long int ru_isrss;
+ /* Number of soft page faults (i.e. those serviced by reclaiming
+ a page from the list of pages awaiting reallocation. */
+ long int ru_minflt;
+ /* Number of hard page faults (i.e. those that required I/O). */
+ long int ru_majflt;
+ /* Number of times a process was swapped out of physical memory. */
+ long int ru_nswap;
+ /* Number of input operations via the file system. Note: This
+ and `ru_oublock' do not include operations with the cache. */
+ long int ru_inblock;
+ /* Number of output operations via the file system. */
+ long int ru_oublock;
+ /* Number of IPC messages sent. */
+ long int ru_msgsnd;
+ /* Number of IPC messages received. */
+ long int ru_msgrcv;
+ /* Number of signals delivered. */
+ long int ru_nsignals;
+ /* Number of voluntary context switches, i.e. because the process
+ gave up the process before it had to (usually to wait for some
+ resource to be available). */
+ long int ru_nvcsw;
+ /* Number of involuntary context switches, i.e. a higher priority process
+ became runnable or the current process used up its time slice. */
+ long int ru_nivcsw;
+ };
+
+/* Priority limits. */
+#define PRIO_MIN -20 /* Minimum priority a process can have. */
+#define PRIO_MAX 20 /* Maximum priority a process can have. */
+
+/* The type of the WHICH argument to `getpriority' and `setpriority',
+ indicating what flavor of entity the WHO argument specifies. */
+enum __priority_which
+{
+ PRIO_PROCESS = 0, /* WHO is a process ID. */
+#define PRIO_PROCESS PRIO_PROCESS
+ PRIO_PGRP = 1, /* WHO is a process group ID. */
+#define PRIO_PGRP PRIO_PGRP
+ PRIO_USER = 2 /* WHO is a user ID. */
+#define PRIO_USER PRIO_USER
+};
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/sem.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/sem.h
new file mode 100644
index 000000000..f63360b2b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/sem.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SEM_H
+# error "Never include <bits/sem.h> directly; use <sys/sem.h> instead."
+#endif
+
+#include <sys/types.h>
+
+/* Flags for `semop'. */
+#define SEM_UNDO 0x1000 /* undo the operation on exit */
+
+/* Commands for `semctl'. */
+#define GETPID 11 /* get sempid */
+#define GETVAL 12 /* get semval */
+#define GETALL 13 /* get all semval's */
+#define GETNCNT 14 /* get semncnt */
+#define GETZCNT 15 /* get semzcnt */
+#define SETVAL 16 /* set semval */
+#define SETALL 17 /* set all semval's */
+
+
+/* Data structure describing a set of semaphores. */
+struct semid_ds
+{
+ struct ipc_perm sem_perm; /* operation permission struct */
+ __time_t sem_otime; /* last semop() time */
+ __time_t sem_ctime; /* last time changed by semctl() */
+ unsigned long int sem_nsems; /* number of semaphores in set */
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+};
+
+/* The user should define a union like the following to use it for arguments
+ for `semctl'.
+
+ union semun
+ {
+ int val; <= value for SETVAL
+ struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET
+ unsigned short int *array; <= array for GETALL & SETALL
+ struct seminfo *__buf; <= buffer for IPC_INFO
+ };
+
+ Previous versions of this file used to define this union but this is
+ incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether
+ one must define the union or not. */
+#define _SEM_SEMUN_UNDEFINED 1
+
+#ifdef __USE_MISC
+
+/* ipcs ctl cmds */
+# define SEM_STAT 18
+# define SEM_INFO 19
+
+struct seminfo
+{
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvmx;
+ int semaem;
+};
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/shm.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/shm.h
new file mode 100644
index 000000000..35226c16c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/shm.h
@@ -0,0 +1,101 @@
+/* Copyright (C) 1995, 1996, 1997, 2000, 2002, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple. */
+#define SHMLBA (__getpagesize ())
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a set of semaphores. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+ size_t shm_segsz; /* size of segment in bytes */
+ __time_t shm_atime; /* time of last shmat() */
+ __time_t shm_dtime; /* time of last shmdt() */
+ __time_t shm_ctime; /* time of last change by shmctl() */
+ __pid_t shm_cpid; /* pid of creator */
+ __pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */
+# define SHM_NORESERVE 010000 /* don't check for reservations */
+
+struct shminfo
+ {
+ unsigned long int shmmax;
+ unsigned long int shmmin;
+ unsigned long int shmmni;
+ unsigned long int shmseg;
+ unsigned long int shmall;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ unsigned long int __unused3;
+ unsigned long int __unused4;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/sigaction.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/sigaction.h
new file mode 100644
index 000000000..80feb2fa2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/sigaction.h
@@ -0,0 +1,74 @@
+/* The proper definitions for Linux/Alpha sigaction.
+ Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIGNAL_H
+# error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
+#endif
+
+/* Structure describing the action to be taken when a signal arrives. */
+struct sigaction
+ {
+ /* Signal handler. */
+#ifdef __USE_POSIX199309
+ union
+ {
+ /* Used if SA_SIGINFO is not set. */
+ __sighandler_t sa_handler;
+ /* Used if SA_SIGINFO is set. */
+ void (*sa_sigaction) (int, siginfo_t *, void *);
+ }
+ __sigaction_handler;
+# define sa_handler __sigaction_handler.sa_handler
+# define sa_sigaction __sigaction_handler.sa_sigaction
+#else
+ __sighandler_t sa_handler;
+#endif
+
+ /* Additional set of signals to be blocked. */
+ __sigset_t sa_mask;
+
+ /* Special flags. */
+ unsigned int sa_flags;
+ };
+
+/* Bits in `sa_flags'. */
+#define SA_NOCLDSTOP 0x00000004 /* Don't send SIGCHLD when children stop. */
+#define SA_NOCLDWAIT 0x00000020 /* Don't create zombie on child death. */
+#define SA_SIGINFO 0x00000040 /* Invoke signal-catching function with
+ three arguments instead of one. */
+#if defined __USE_UNIX98 || defined __USE_MISC
+# define SA_ONSTACK 0x00000001 /* Use signal stack by using `sa_restorer'. */
+# define SA_RESTART 0x00000002 /* Restart syscall on signal return. */
+# define SA_NODEFER 0x00000008 /* Don't automatically block the signal
+ when its handler is being executed. */
+# define SA_RESETHAND 0x00000010 /* Reset to SIG_DFL on entry to handler. */
+#endif
+#ifdef __USE_MISC
+# define SA_INTERRUPT 0x20000000 /* Historical no-op. */
+
+/* Some aliases for the SA_ constants. */
+# define SA_NOMASK SA_NODEFER
+# define SA_ONESHOT SA_RESETHAND
+# define SA_STACK SA_ONSTACK
+#endif
+
+/* Values for the HOW argument to `sigprocmask'. */
+#define SIG_BLOCK 1 /* Block signals. */
+#define SIG_UNBLOCK 2 /* Unblock signals. */
+#define SIG_SETMASK 3 /* Set the set of blocked signals. */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/siginfo.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/siginfo.h
new file mode 100644
index 000000000..a2aacc04b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/siginfo.h
@@ -0,0 +1,303 @@
+/* siginfo_t, sigevent and constants. Linux/Alpha version.
+ Copyright (C) 1997-2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _SIGNAL_H && !defined __need_siginfo_t \
+ && !defined __need_sigevent_t
+# error "Never include this file directly. Use <signal.h> instead"
+#endif
+
+#if (!defined __have_sigval_t \
+ && (defined _SIGNAL_H || defined __need_siginfo_t \
+ || defined __need_sigevent_t))
+# define __have_sigval_t 1
+
+/* Type for data associated with a signal. */
+typedef union sigval
+ {
+ int sival_int;
+ void *sival_ptr;
+ } sigval_t;
+#endif
+
+#if (!defined __have_siginfo_t \
+ && (defined _SIGNAL_H || defined __need_siginfo_t))
+# define __have_siginfo_t 1
+
+# define __SI_MAX_SIZE 128
+# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
+
+typedef struct siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_errno; /* If non-zero, an errno value associated with
+ this signal, as defined in <errno.h>. */
+ int si_code; /* Signal code. */
+
+ union
+ {
+ int _pad[__SI_PAD_SIZE];
+
+ /* kill(). */
+ struct
+ {
+ __pid_t si_pid; /* Sending process ID. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ } _kill;
+
+ /* POSIX.1b timers. */
+ struct
+ {
+ int si_tid; /* Timer ID. */
+ int si_overrun; /* Overrun count. */
+ sigval_t si_sigval; /* Signal value. */
+ } _timer;
+
+ /* POSIX.1b signals. */
+ struct
+ {
+ __pid_t si_pid; /* Sending process ID. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ sigval_t si_sigval; /* Signal value. */
+ } _rt;
+
+ /* SIGCHLD. */
+ struct
+ {
+ __pid_t si_pid; /* Which child. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ int si_status; /* Exit value or signal. */
+ __clock_t si_utime;
+ __clock_t si_stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
+ struct
+ {
+ void *si_addr; /* Faulting insn/memory ref. */
+ } _sigfault;
+
+ /* SIGPOLL. */
+ struct
+ {
+ int si_band; /* Band event for SIGPOLL. */
+ int si_fd;
+ } _sigpoll;
+ } _sifields;
+ } siginfo_t;
+
+
+/* X/Open requires some more fields with fixed names. */
+# define si_pid _sifields._kill.si_pid
+# define si_uid _sifields._kill.si_uid
+# define si_timerid _sifields._timer.si_tid
+# define si_overrun _sifields._timer.si_overrun
+# define si_status _sifields._sigchld.si_status
+# define si_utime _sifields._sigchld.si_utime
+# define si_stime _sifields._sigchld.si_stime
+# define si_value _sifields._rt.si_sigval
+# define si_int _sifields._rt.si_sigval.sival_int
+# define si_ptr _sifields._rt.si_sigval.sival_ptr
+# define si_addr _sifields._sigfault.si_addr
+# define si_band _sifields._sigpoll.si_band
+# define si_fd _sifields._sigpoll.si_fd
+
+
+/* Values for `si_code'. Positive values are reserved for kernel-generated
+ signals. */
+enum
+{
+ SI_ASYNCNL = -60, /* Sent by asynch name lookup completion. */
+# define SI_ASYNCNL SI_ASYNCNL
+ SI_TKILL = -6, /* Sent by tkill. */
+# define SI_TKILL SI_TKILL
+ SI_SIGIO, /* Sent by queued SIGIO. */
+# define SI_SIGIO SI_SIGIO
+ SI_ASYNCIO, /* Sent by AIO completion. */
+# define SI_ASYNCIO SI_ASYNCIO
+ SI_MESGQ, /* Sent by real time mesq state change. */
+# define SI_MESGQ SI_MESGQ
+ SI_TIMER, /* Sent by timer expiration. */
+# define SI_TIMER SI_TIMER
+ SI_QUEUE, /* Sent by sigqueue. */
+# define SI_QUEUE SI_QUEUE
+ SI_USER, /* Sent by kill, sigsend, raise. */
+# define SI_USER SI_USER
+ SI_KERNEL = 0x80 /* Send by kernel. */
+#define SI_KERNEL SI_KERNEL
+};
+
+
+/* `si_code' values for SIGILL signal. */
+enum
+{
+ ILL_ILLOPC = 1, /* Illegal opcode. */
+# define ILL_ILLOPC ILL_ILLOPC
+ ILL_ILLOPN, /* Illegal operand. */
+# define ILL_ILLOPN ILL_ILLOPN
+ ILL_ILLADR, /* Illegal addressing mode. */
+# define ILL_ILLADR ILL_ILLADR
+ ILL_ILLTRP, /* Illegal trap. */
+# define ILL_ILLTRP ILL_ILLTRP
+ ILL_PRVOPC, /* Privileged opcode. */
+# define ILL_PRVOPC ILL_PRVOPC
+ ILL_PRVREG, /* Privileged register. */
+# define ILL_PRVREG ILL_PRVREG
+ ILL_COPROC, /* Coprocessor error. */
+# define ILL_COPROC ILL_COPROC
+ ILL_BADSTK /* Internal stack error. */
+# define ILL_BADSTK ILL_BADSTK
+};
+
+/* `si_code' values for SIGFPE signal. */
+enum
+{
+ FPE_INTDIV = 1, /* Integer divide by zero. */
+# define FPE_INTDIV FPE_INTDIV
+ FPE_INTOVF, /* Integer overflow. */
+# define FPE_INTOVF FPE_INTOVF
+ FPE_FLTDIV, /* Floating point divide by zero. */
+# define FPE_FLTDIV FPE_FLTDIV
+ FPE_FLTOVF, /* Floating point overflow. */
+# define FPE_FLTOVF FPE_FLTOVF
+ FPE_FLTUND, /* Floating point underflow. */
+# define FPE_FLTUND FPE_FLTUND
+ FPE_FLTRES, /* Floating point inexact result. */
+# define FPE_FLTRES FPE_FLTRES
+ FPE_FLTINV, /* Floating point invalid operation. */
+# define FPE_FLTINV FPE_FLTINV
+ FPE_FLTSUB /* Subscript out of range. */
+# define FPE_FLTSUB FPE_FLTSUB
+};
+
+/* `si_code' values for SIGSEGV signal. */
+enum
+{
+ SEGV_MAPERR = 1, /* Address not mapped to object. */
+# define SEGV_MAPERR SEGV_MAPERR
+ SEGV_ACCERR /* Invalid permissions for mapped object. */
+# define SEGV_ACCERR SEGV_ACCERR
+};
+
+/* `si_code' values for SIGBUS signal. */
+enum
+{
+ BUS_ADRALN = 1, /* Invalid address alignment. */
+# define BUS_ADRALN BUS_ADRALN
+ BUS_ADRERR, /* Non-existant physical address. */
+# define BUS_ADRERR BUS_ADRERR
+ BUS_OBJERR /* Object specific hardware error. */
+# define BUS_OBJERR BUS_OBJERR
+};
+
+/* `si_code' values for SIGTRAP signal. */
+enum
+{
+ TRAP_BRKPT = 1, /* Process breakpoint. */
+# define TRAP_BRKPT TRAP_BRKPT
+ TRAP_TRACE /* Process trace trap. */
+# define TRAP_TRACE TRAP_TRACE
+};
+
+/* `si_code' values for SIGCHLD signal. */
+enum
+{
+ CLD_EXITED = 1, /* Child has exited. */
+# define CLD_EXITED CLD_EXITED
+ CLD_KILLED, /* Child was killed. */
+# define CLD_KILLED CLD_KILLED
+ CLD_DUMPED, /* Child terminated abnormally. */
+# define CLD_DUMPED CLD_DUMPED
+ CLD_TRAPPED, /* Traced child has trapped. */
+# define CLD_TRAPPED CLD_TRAPPED
+ CLD_STOPPED, /* Child has stopped. */
+# define CLD_STOPPED CLD_STOPPED
+ CLD_CONTINUED /* Stopped child has continued. */
+# define CLD_CONTINUED CLD_CONTINUED
+};
+
+/* `si_code' values for SIGPOLL signal. */
+enum
+{
+ POLL_IN = 1, /* Data input available. */
+# define POLL_IN POLL_IN
+ POLL_OUT, /* Output buffers available. */
+# define POLL_OUT POLL_OUT
+ POLL_MSG, /* Input message available. */
+# define POLL_MSG POLL_MSG
+ POLL_ERR, /* I/O error. */
+# define POLL_ERR POLL_ERR
+ POLL_PRI, /* High priority input available. */
+# define POLL_PRI POLL_PRI
+ POLL_HUP /* Device disconnected. */
+# define POLL_HUP POLL_HUP
+};
+
+# undef __need_siginfo_t
+#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
+
+
+#if (defined _SIGNAL_H || defined __need_sigevent_t) \
+ && !defined __have_sigevent_t
+# define __have_sigevent_t 1
+
+/* Structure to transport application-defined values with signals. */
+# define __SIGEV_MAX_SIZE 64
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4)
+
+typedef struct sigevent
+ {
+ sigval_t sigev_value;
+ int sigev_signo;
+ int sigev_notify;
+
+ union
+ {
+ int _pad[__SIGEV_PAD_SIZE];
+
+ /* When SIGEV_SIGNAL and SIGEV_THREAD_ID set, LWP ID of the
+ thread to receive the signal. */
+ __pid_t _tid;
+
+ struct
+ {
+ void (*_function) (sigval_t); /* Function to start. */
+ void *_attribute; /* Really pthread_attr_t. */
+ } _sigev_thread;
+ } _sigev_un;
+ } sigevent_t;
+
+/* POSIX names to access some of the members. */
+# define sigev_notify_function _sigev_un._sigev_thread._function
+# define sigev_notify_attributes _sigev_un._sigev_thread._attribute
+
+/* `sigev_notify' values. */
+enum
+{
+ SIGEV_SIGNAL = 0, /* Notify via signal. */
+# define SIGEV_SIGNAL SIGEV_SIGNAL
+ SIGEV_NONE, /* Other notification: meaningless. */
+# define SIGEV_NONE SIGEV_NONE
+ SIGEV_THREAD, /* Deliver via thread creation. */
+# define SIGEV_THREAD SIGEV_THREAD
+
+ SIGEV_THREAD_ID = 4 /* Send signal to specific thread. */
+#define SIGEV_THREAD_ID SIGEV_THREAD_ID
+};
+
+#endif /* have _SIGNAL_H. */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/signum.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/signum.h
new file mode 100644
index 000000000..477c13175
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/signum.h
@@ -0,0 +1,82 @@
+/* Signal number definitions. Linux/Alpha version.
+ Copyright (C) 1996, 1997, 1998, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef _SIGNAL_H
+
+/* Fake signal functions. */
+#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
+#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
+#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
+
+#ifdef __USE_UNIX98
+# define SIG_HOLD ((__sighandler_t) 2) /* Add signal to hold mask. */
+#endif
+
+/*
+ * Linux/AXP has different signal numbers that Linux/i386: I'm trying
+ * to make it OSF/1 binary compatible, at least for normal binaries.
+ */
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGEMT 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGBUS 10
+#define SIGSEGV 11
+#define SIGSYS 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGURG 16
+#define SIGSTOP 17
+#define SIGTSTP 18
+#define SIGCONT 19
+#define SIGCHLD 20
+#define SIGCLD SIGCHLD
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGIO 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGINFO 29
+#define SIGUSR1 30
+#define SIGUSR2 31
+
+#define SIGPOLL SIGIO
+#define SIGPWR SIGINFO
+#define SIGIOT SIGABRT
+
+#define _NSIG 65 /* Biggest signal number + 1. */
+
+#define SIGRTMIN (__libc_current_sigrtmin ())
+#define SIGRTMAX (__libc_current_sigrtmax ())
+
+/* These are the hard limits of the kernel. These values should not be
+ used directly at user level. */
+#define __SIGRTMIN 32
+#define __SIGRTMAX (_NSIG - 1)
+
+#endif /* <signal.h> included. */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/sigstack.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/sigstack.h
new file mode 100644
index 000000000..7faaf98d5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/sigstack.h
@@ -0,0 +1,55 @@
+/* sigstack, sigaltstack definitions.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIGNAL_H
+# error "Never include this file directly. Use <signal.h> instead"
+#endif
+
+
+/* Structure describing a signal stack (obsolete). */
+struct sigstack
+ {
+ __ptr_t ss_sp; /* Signal stack pointer. */
+ int ss_onstack; /* Nonzero if executing on this stack. */
+ };
+
+
+/* Possible values for `ss_flags.'. */
+enum
+{
+ SS_ONSTACK = 1,
+#define SS_ONSTACK SS_ONSTACK
+ SS_DISABLE
+#define SS_DISABLE SS_DISABLE
+};
+
+/* Minimum stack size for a signal handler. */
+#define MINSIGSTKSZ 4096
+
+/* System default stack size. */
+#define SIGSTKSZ 16384
+
+
+/* Alternate, preferred interface. */
+typedef struct sigaltstack
+ {
+ __ptr_t ss_sp;
+ int ss_flags;
+ size_t ss_size;
+ } stack_t;
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/stat.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/stat.h
new file mode 100644
index 000000000..40b685343
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/stat.h
@@ -0,0 +1,151 @@
+/* Copyright (C) 1996,1997,1998,1999,2000,2001,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+/* Versions of the `struct stat' data structure. */
+#define _STAT_VER_KERNEL 0
+#define _STAT_VER_GLIBC2 1
+#define _STAT_VER_GLIBC2_1 2
+#define _STAT_VER_KERNEL64 3
+#define _STAT_VER_GLIBC2_3_4 3
+#define _STAT_VER _STAT_VER_GLIBC2_3_4
+
+/* Versions of the `xmknod' interface. */
+#define _MKNOD_VER_LINUX 0
+
+
+/* Nanosecond resolution timestamps are stored in a format equivalent to
+ 'struct timespec'. This is the type used whenever possible but the
+ Unix namespace rules do not allow the identifier 'timespec' to appear
+ in the <sys/stat.h> header. Therefore we have to handle the use of
+ this header in strictly standard-compliant sources special.
+
+ Use neat tidy anonymous unions and structures when possible. */
+
+#ifdef __USE_MISC
+# if __GNUC_PREREQ(3,3)
+# define __ST_TIME(X) \
+ __extension__ union { \
+ struct timespec st_##X##tim; \
+ struct { \
+ __time_t st_##X##time; \
+ unsigned long st_##X##timensec; \
+ }; \
+ }
+# else
+# define __ST_TIME(X) struct timespec st_##X##tim
+# define st_atime st_atim.tv_sec
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+# endif
+#else
+# define __ST_TIME(X) \
+ __time_t st_##X##time; \
+ unsigned long st_##X##timensec
+#endif
+
+
+struct stat
+ {
+ __dev_t st_dev; /* Device. */
+#ifdef __USE_FILE_OFFSET64
+ __ino64_t st_ino; /* File serial number. */
+#else
+ __ino_t st_ino; /* File serial number. */
+ int __pad0; /* 64-bit st_ino. */
+#endif
+ __dev_t st_rdev; /* Device number, if device. */
+ __off_t st_size; /* Size of file, in bytes. */
+#ifdef __USE_FILE_OFFSET64
+ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */
+#else
+ __blkcnt_t st_blocks; /* Nr. 512-byte blocks allocated. */
+ int __pad1; /* 64-bit st_blocks. */
+#endif
+ __mode_t st_mode; /* File mode. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ __nlink_t st_nlink; /* Link count. */
+ int __pad2; /* Real padding. */
+ __ST_TIME(a); /* Time of last access. */
+ __ST_TIME(m); /* Time of last modification. */
+ __ST_TIME(c); /* Time of last status change. */
+ long __unused[3];
+ };
+
+#ifdef __USE_LARGEFILE64
+/* Note stat64 is the same shape as stat. */
+struct stat64
+ {
+ __dev_t st_dev; /* Device. */
+ __ino64_t st_ino; /* File serial number. */
+ __dev_t st_rdev; /* Device number, if device. */
+ __off_t st_size; /* Size of file, in bytes. */
+ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */
+ __mode_t st_mode; /* File mode. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ __nlink_t st_nlink; /* Link count. */
+ int __pad0; /* Real padding. */
+ __ST_TIME(a); /* Time of last access. */
+ __ST_TIME(m); /* Time of last modification. */
+ __ST_TIME(c); /* Time of last status change. */
+ long __unused[3];
+ };
+#endif
+
+#undef __ST_TIME
+
+/* Tell code we have these members. */
+#define _STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+#define _STATBUF_ST_NSEC
+
+/* Encoding of the file mode. */
+
+#define __S_IFMT 0170000 /* These bits determine file type. */
+
+/* File types. */
+#define __S_IFDIR 0040000 /* Directory. */
+#define __S_IFCHR 0020000 /* Character device. */
+#define __S_IFBLK 0060000 /* Block device. */
+#define __S_IFREG 0100000 /* Regular file. */
+#define __S_IFIFO 0010000 /* FIFO. */
+#define __S_IFLNK 0120000 /* Symbolic link. */
+#define __S_IFSOCK 0140000 /* Socket. */
+
+/* POSIX.1b objects. Note that these macros always evaluate to zero. But
+ they do it by enforcing the correct use of the macros. */
+#define __S_TYPEISMQ(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
+
+/* Protection bits. */
+
+#define __S_ISUID 04000 /* Set user ID on execution. */
+#define __S_ISGID 02000 /* Set group ID on execution. */
+#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
+#define __S_IREAD 0400 /* Read by owner. */
+#define __S_IWRITE 0200 /* Write by owner. */
+#define __S_IEXEC 0100 /* Execute by owner. */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/statfs.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/statfs.h
new file mode 100644
index 000000000..d838e6bf4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/statfs.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 1997, 1998, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STATFS_H
+# error "Never include <bits/statfs.h> directly; use <sys/statfs.h> instead."
+#endif
+
+#include <bits/types.h> /* for __fsid_t and __fsblkcnt_t. */
+
+struct statfs
+ {
+ int f_type;
+ int f_bsize;
+#ifndef __USE_FILE_OFFSET64
+ __fsblkcnt_t f_blocks;
+ __fsblkcnt_t f_bfree;
+ __fsblkcnt_t f_bavail;
+ __fsfilcnt_t f_files;
+ __fsfilcnt_t f_ffree;
+#else
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsfilcnt64_t f_files;
+ __fsfilcnt64_t f_ffree;
+#endif
+ __fsid_t f_fsid;
+ int f_namelen;
+ int f_frsize;
+ int f_spare[5];
+ };
+
+#ifdef __USE_LARGEFILE64
+struct statfs64
+ {
+ int f_type;
+ int f_bsize;
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsfilcnt64_t f_files;
+ __fsfilcnt64_t f_ffree;
+ __fsid_t f_fsid;
+ int f_namelen;
+ int f_frsize;
+ int f_spare[5];
+ };
+#endif
+
+/* Tell code we have this member. */
+#define _STATFS_F_NAMELEN
+#define _STATFS_F_FRSIZE
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/termios.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/termios.h
new file mode 100644
index 000000000..966ccf94d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/termios.h
@@ -0,0 +1,226 @@
+/* termios type and macro definitions. Linux version.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2003, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _TERMIOS_H
+# error "Never include <bits/termios.h> directly; use <termios.h> instead."
+#endif
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 32
+struct termios
+ {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_cc[NCCS]; /* control characters */
+ cc_t c_line; /* line discipline (== c_cc[33]) */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
+#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
+ };
+
+/* c_cc characters */
+#define VEOF 0
+#define VEOL 1
+#define VEOL2 2
+#define VERASE 3
+#define VWERASE 4
+#define VKILL 5
+#define VREPRINT 6
+#define VSWTC 7
+#define VINTR 8
+#define VQUIT 9
+#define VSUSP 10
+#define VSTART 12
+#define VSTOP 13
+#define VLNEXT 14
+#define VDISCARD 15
+#define VMIN 16
+#define VTIME 17
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IXON 0001000
+#define IXOFF 0002000
+#ifdef __USE_BSD
+ /* POSIX.1 doesn't want these... */
+# define IXANY 0004000
+# define IUCLC 0010000
+# define IMAXBEL 0020000
+# define IUTF8 0040000
+#endif
+
+/* c_oflag bits */
+#define OPOST 0000001
+#define ONLCR 0000002
+#define OLCUC 0000004
+
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+
+#define OFILL 00000100
+#define OFDEL 00000200
+#if defined __USE_MISC || defined __USE_XOPEN
+# define NLDLY 00001400
+# define NL0 00000000
+# define NL1 00000400
+# define NL2 00001000
+# define NL3 00001400
+# define TABDLY 00006000
+# define TAB0 00000000
+# define TAB1 00002000
+# define TAB2 00004000
+# define TAB3 00006000
+# define CRDLY 00030000
+# define CR0 00000000
+# define CR1 00010000
+# define CR2 00020000
+# define CR3 00030000
+# define FFDLY 00040000
+# define FF0 00000000
+# define FF1 00040000
+# define BSDLY 00100000
+# define BS0 00000000
+# define BS1 00100000
+#endif
+
+#define VTDLY 00200000
+#define VT0 00000000
+#define VT1 00200000
+
+#ifdef __USE_MISC
+# define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
+#endif
+
+/* c_cflag bit meaning */
+#ifdef __USE_MISC
+# define CBAUD 0000037
+#endif
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#ifdef __USE_MISC
+# define EXTA B19200
+# define EXTB B38400
+# define CBAUDEX 0000000
+#endif
+#define B57600 00020
+#define B115200 00021
+#define B230400 00022
+#define B460800 00023
+#define B500000 00024
+#define B576000 00025
+#define B921600 00026
+#define B1000000 00027
+#define B1152000 00030
+#define B1500000 00031
+#define B2000000 00032
+#define B2500000 00033
+#define B3000000 00034
+#define B3500000 00035
+#define B4000000 00036
+
+#define __MAX_BAUD B4000000
+
+#define CSIZE 00001400
+#define CS5 00000000
+#define CS6 00000400
+#define CS7 00001000
+#define CS8 00001400
+
+#define CSTOPB 00002000
+#define CREAD 00004000
+#define PARENB 00010000
+#define PARODD 00020000
+#define HUPCL 00040000
+
+#define CLOCAL 00100000
+#ifdef __USE_MISC
+# define CMSPAR 010000000000 /* mark or space (stick) parity */
+# define CRTSCTS 020000000000 /* flow control */
+#endif
+
+/* c_lflag bits */
+#define ISIG 0x00000080
+#define ICANON 0x00000100
+#if defined __USE_MISC || defined __USE_XOPEN
+# define XCASE 0x00004000
+#endif
+#define ECHO 0x00000008
+#define ECHOE 0x00000002
+#define ECHOK 0x00000004
+#define ECHONL 0x00000010
+#define NOFLSH 0x80000000
+#define TOSTOP 0x00400000
+#ifdef __USE_MISC
+# define ECHOCTL 0x00000040
+# define ECHOPRT 0x00000020
+# define ECHOKE 0x00000001
+# define FLUSHO 0x00800000
+# define PENDIN 0x20000000
+#endif
+#define IEXTEN 0x00000400
+
+/* Values for the ACTION argument to `tcflow'. */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* Values for the QUEUE_SELECTOR argument to `tcflush'. */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+
+#define _IOT_termios /* Hurd ioctl type field. */ \
+ _IOT (_IOTS (cflag_t), 4, _IOTS (cc_t), NCCS, _IOTS (speed_t), 2)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h
new file mode 100644
index 000000000..201585af1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h
@@ -0,0 +1,66 @@
+/* bits/typesizes.h -- underlying types for *_t. Linux/Alpha version.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_TYPES_H
+# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef _BITS_TYPESIZES_H
+#define _BITS_TYPESIZES_H 1
+
+/* See <bits/types.h> for the meaning of these macros. This file exists so
+ that <bits/types.h> need not vary across different GNU platforms. */
+
+#define __DEV_T_TYPE __U64_TYPE
+#define __UID_T_TYPE __U32_TYPE
+#define __GID_T_TYPE __U32_TYPE
+#define __INO_T_TYPE __U32_TYPE
+#define __INO64_T_TYPE __U64_TYPE
+#define __MODE_T_TYPE __U32_TYPE
+#define __NLINK_T_TYPE __U32_TYPE
+#define __OFF_T_TYPE __SLONGWORD_TYPE
+#define __OFF64_T_TYPE __S64_TYPE
+#define __PID_T_TYPE __S32_TYPE
+#define __RLIM_T_TYPE __ULONGWORD_TYPE
+#define __RLIM64_T_TYPE __U64_TYPE
+#define __BLKCNT_T_TYPE __U32_TYPE
+#define __BLKCNT64_T_TYPE __U64_TYPE
+#define __FSBLKCNT_T_TYPE __S32_TYPE
+#define __FSBLKCNT64_T_TYPE __S64_TYPE
+#define __FSFILCNT_T_TYPE __U32_TYPE
+#define __FSFILCNT64_T_TYPE __U64_TYPE
+#define __ID_T_TYPE __U32_TYPE
+#define __CLOCK_T_TYPE __SLONGWORD_TYPE
+#define __TIME_T_TYPE __SLONGWORD_TYPE
+#define __USECONDS_T_TYPE __U32_TYPE
+#define __SUSECONDS_T_TYPE __S64_TYPE
+#define __DADDR_T_TYPE __S32_TYPE
+#define __SWBLK_T_TYPE __SLONGWORD_TYPE
+#define __KEY_T_TYPE __S32_TYPE
+#define __CLOCKID_T_TYPE __S32_TYPE
+#define __TIMER_T_TYPE void *
+#define __BLKSIZE_T_TYPE __U32_TYPE
+#define __FSID_T_TYPE struct { int __val[2]; }
+#define __SSIZE_T_TYPE __SWORD_TYPE
+
+/* Number of descriptors that can fit in an `fd_set'. */
+#define __FD_SETSIZE 1024
+
+
+#endif /* bits/typesizes.h */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/bits/wordsize.h b/libc/sysdeps/unix/sysv/linux/alpha/bits/wordsize.h
new file mode 100644
index 000000000..22fc64109
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/bits/wordsize.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __WORDSIZE 64
+
+#if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL
+
+/* Signal that we didn't used to have a `long double'. The changes all
+ the `long double' function variants to be redirects to the double
+ functions. */
+# define __LONG_DOUBLE_MATH_OPTIONAL 1
+# ifndef __LONG_DOUBLE_128__
+# define __NO_LONG_DOUBLE_MATH 1
+# endif
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/brk.S b/libc/sysdeps/unix/sysv/linux/alpha/brk.S
new file mode 100644
index 000000000..e01abebe0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/brk.S
@@ -0,0 +1,81 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Brendan Kehoe <brendan@zen.org>, 1993.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* __brk is a special syscall under Linux since it never returns an
+ error. Instead, the error condition is indicated by returning the old
+ break value (instead of the new, requested one). */
+
+#include <sysdep.h>
+#define _ERRNO_H
+#include <bits/errno.h>
+
+#ifdef PIC
+.section .bss
+ .align 3
+ .globl __curbrk
+__curbrk: .skip 8
+ .type __curbrk,@object
+ .size __curbrk,8
+#else
+.comm __curbrk, 8
+#endif
+
+ .text
+LEAF(__brk, 8)
+ ldgp gp, 0(t12)
+ subq sp, 8, sp
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ /* Save the requested brk across the system call. */
+ stq a0, 0(sp)
+
+ ldiq v0, __NR_brk
+ call_pal PAL_callsys
+
+ ldq a0, 0(sp)
+
+ /* Be prepared for an OSF-style brk. */
+ bne a3, $err1
+ beq v0, $ok
+
+ /* Correctly handle the brk(0) query case. */
+ cmoveq a0, v0, a0
+ xor a0, v0, t0
+ bne t0, $err0
+
+ /* Update __curbrk and return cleanly. */
+ mov zero, v0
+$ok: stq a0, __curbrk
+ addq sp, 8, sp
+ ret
+
+ /* What a horrible way to die. */
+$err0: ldi v0, ENOMEM
+$err1: addq sp, 8, sp
+ SYSCALL_ERROR_HANDLER
+
+ END(__brk)
+
+weak_alias (__brk, brk)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/clone.S b/libc/sysdeps/unix/sysv/linux/alpha/clone.S
new file mode 100644
index 000000000..5e0b21ea1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/clone.S
@@ -0,0 +1,149 @@
+/* Copyright (C) 1996, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@tamu.edu>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* clone() is even more special than fork() as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+#define CLONE_VM 0x00000100
+#define CLONE_THREAD 0x00010000
+
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags,
+ void *arg, pid_t *ptid, void *tls, pid_t *ctid);
+
+ Note that everything past ARG is technically optional, based
+ on FLAGS, and that CTID is arg 7, and thus is on the stack.
+ However, since a load from top-of-stack better be legal always,
+ we don't bother checking FLAGS. */
+
+ .text
+ENTRY(__clone)
+#ifdef PROF
+ ldgp gp,0(pv)
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ /* Sanity check arguments. */
+ ldiq v0,EINVAL
+ beq a0,$error /* no NULL function pointers */
+ beq a1,$error /* no NULL stack pointers */
+
+ /* Save the fn ptr and arg on the new stack. */
+ subq a1,32,a1
+ stq a0,0(a1)
+ stq a3,8(a1)
+#ifdef RESET_PID
+ stq a2,16(a1)
+#endif
+
+ /* The syscall is of the form clone(flags, usp, ptid, ctid, tls).
+ Shift the flags, ptid, ctid, tls arguments into place; the
+ child_stack argument is already correct. */
+ mov a2,a0
+ mov a4,a2
+ ldq a3,0(sp)
+ mov a5,a4
+
+ /* Do the system call. */
+ ldiq v0,__NR_clone
+ call_pal PAL_callsys
+
+ bne a3,$error
+ beq v0,thread_start
+
+ /* Successful return from the parent. */
+ ret
+
+ /* Something bad happened -- no child created. */
+$error:
+#ifndef PROF
+ br gp,1f
+1: ldgp gp,0(gp)
+#endif
+ SYSCALL_ERROR_HANDLER
+
+ END(__clone)
+
+/* Load up the arguments to the function. Put this block of code in
+ its own function so that we can terminate the stack trace with our
+ debug info. */
+
+ .ent thread_start
+thread_start:
+ .frame fp,0,fp,0
+ mov 0, fp
+ .prologue 0
+
+#ifdef RESET_PID
+ /* Check and see if we need to reset the PID. */
+ ldq t0,16(sp)
+ lda t1,CLONE_THREAD
+ and t0,t1,t2
+ beq t2,2f
+1:
+#endif
+
+ /* Load up the arguments. */
+ ldq pv,0(sp)
+ ldq a0,8(sp)
+ addq sp,32,sp
+
+ /* Call the user's function. */
+ jsr ra,(pv)
+ ldgp gp,0(ra)
+
+ /* Call _exit rather than doing it inline for breakpoint purposes. */
+ mov v0,a0
+#ifdef PIC
+ bsr ra, HIDDEN_JUMPTARGET(_exit) !samegp
+#else
+ jsr ra, HIDDEN_JUMPTARGET(_exit)
+#endif
+
+ /* Die horribly. */
+ halt
+
+#ifdef RESET_PID
+2:
+ rduniq
+ lda t1, CLONE_VM
+ mov v0, s0
+ lda v0, -1
+ and t0, t1, t2
+ bne t2, 3f
+ lda v0, __NR_getxpid
+ callsys
+3:
+ stl v0, PID_OFFSET(s0)
+ stl v0, TID_OFFSET(s0)
+ br 1b
+#endif
+
+ .end thread_start
+
+weak_alias (__clone, clone)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/dl-brk.S b/libc/sysdeps/unix/sysv/linux/alpha/dl-brk.S
new file mode 100644
index 000000000..eeb96544e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/dl-brk.S
@@ -0,0 +1 @@
+#include <brk.S>
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/dl-sysdep.c b/libc/sysdeps/unix/sysv/linux/alpha/dl-sysdep.c
new file mode 100644
index 000000000..d95e46f6f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/dl-sysdep.c
@@ -0,0 +1,59 @@
+/* Operating system support for run-time dynamic linker. Linux/Alpha version.
+ Copyright (C) 1997, 1998, 2001, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <config.h>
+#include <kernel-features.h>
+#include <ldsodefs.h>
+
+extern long __libc_alpha_cache_shape[4];
+weak_extern (__libc_alpha_cache_shape);
+
+
+/* Scan the Aux Vector for the cache shape entries. */
+#define DL_PLATFORM_AUXV \
+ case AT_L1I_CACHESHAPE: \
+ { \
+ long *cls = __libc_alpha_cache_shape; \
+ if (cls != NULL) \
+ cls[0] = av->a_un.a_val; \
+ break; \
+ } \
+ case AT_L1D_CACHESHAPE: \
+ { \
+ long *cls = __libc_alpha_cache_shape; \
+ if (cls != NULL) \
+ cls[1] = av->a_un.a_val; \
+ break; \
+ } \
+ case AT_L2_CACHESHAPE: \
+ { \
+ long *cls = __libc_alpha_cache_shape; \
+ if (cls != NULL) \
+ cls[2] = av->a_un.a_val; \
+ break; \
+ } \
+ case AT_L3_CACHESHAPE: \
+ { \
+ long *cls = __libc_alpha_cache_shape; \
+ if (cls != NULL) \
+ cls[3] = av->a_un.a_val; \
+ break; \
+ }
+
+#include <sysdeps/unix/sysv/linux/dl-sysdep.c>
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/fraiseexcpt.c b/libc/sysdeps/unix/sysv/linux/alpha/fraiseexcpt.c
new file mode 100644
index 000000000..5e63be5cc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/fraiseexcpt.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv_libc.h>
+#include <sysdep.h>
+#include <float.h>
+#include <kernel-features.h>
+#include "kernel_sysinfo.h"
+
+
+int
+__feraiseexcept (int excepts)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ unsigned long t = excepts;
+ long r;
+
+ r = INTERNAL_SYSCALL (osf_setsysinfo, err, 2, SSI_IEEE_RAISE_EXCEPTION, &t);
+
+#ifndef __ASSUME_IEEE_RAISE_EXCEPTION
+ if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+ return 0;
+
+ double d;
+
+ /* If we got an error from SSI_IEEE_RAISE_EXCEPTION, assume it means that
+ the system call isn't actually implemented. Do the best we can. */
+
+ /* Invalid implemented with 0 / 0 -> NaN. */
+ if (excepts & FE_INVALID)
+ __asm__ __volatile__ ("divs/su $f31,$f31,%0; trapb" : "=f"(d) : );
+
+ /* Division By Zero implemented with 1 / 0 -> NaN. */
+ if (excepts & FE_DIVBYZERO)
+ __asm__ __volatile__ ("divs/su %1,$f31,%0; trapb" : "=&f"(d) : "f"(1.0f));
+
+ /* Overflow and underflow cannot be had all by themselves. We can
+ generate them with arithmetic, but we always get INEXACT raised
+ at the same time. Prepare to undo. */
+ if ((excepts & (FE_OVERFLOW | FE_UNDERFLOW)) && !(excepts & FE_INEXACT))
+ INTERNAL_SYSCALL (osf_getsysinfo, err, 2, GSI_IEEE_FP_CONTROL, &t);
+
+ /* Overflow implemented with FLT_MAX + FLT_MAX -> Inf. */
+ if (excepts & FE_OVERFLOW)
+ __asm__ __volatile__ ("adds/sui %1,%1,%0; trapb"
+ : "=&f"(d) : "f"(FLT_MAX));
+
+ /* Underflow implemented with FLT_MIN * FLT_MIN -> 0. */
+ if (excepts & FE_UNDERFLOW)
+ __asm__ __volatile__ ("muls/sui %1,%1,%0; trapb"
+ : "=&f"(d) : "f"(FLT_MIN));
+
+ /* Inexact implemented with (long)0.5 -> 0. */
+ if ((excepts & (FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)) == FE_INEXACT)
+ __asm__ __volatile__ ("cvttq/svi %1,%0; trapb" : "=&f"(d) : "f"(0.5f));
+
+ /* If we raised inexact when not asked, and inexact was not previously
+ raised, then clear that exception. */
+ if ((excepts & (FE_OVERFLOW | FE_UNDERFLOW))
+ && !((excepts | t) & FE_INEXACT))
+ {
+ t |= excepts & SWCR_STATUS_MASK;
+ INTERNAL_SYSCALL (osf_setsysinfo, err, 2, SSI_IEEE_FP_CONTROL, &t);
+ }
+#endif /* !__ASSUME_IEEE_RAISE_EXCEPTION */
+
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feraiseexcept, __old_feraiseexcept)
+compat_symbol (libm, __old_feraiseexcept, feraiseexcept, GLIBC_2_1);
+#endif
+
+libm_hidden_ver (__feraiseexcept, feraiseexcept)
+versioned_symbol (libm, __feraiseexcept, feraiseexcept, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/fxstat.c b/libc/sysdeps/unix/sysv/linux/alpha/fxstat.c
new file mode 100644
index 000000000..40e08fd86
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/fxstat.c
@@ -0,0 +1,64 @@
+/* fxstat using old-style Unix stat system call.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __fxstat64 __fxstat64_disable
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <xstatconv.h>
+
+#undef __fxstat64
+
+
+/* Get information about the file NAME in BUF. */
+int
+__fxstat (int vers, int fd, struct stat *buf)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ int result, errno_out;
+ struct kernel_stat kbuf;
+
+ if (vers == _STAT_VER_KERNEL64 && !__libc_missing_axp_stat64)
+ {
+ result = INTERNAL_SYSCALL (fstat64, err, 2, fd, buf);
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return result;
+ errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
+ if (errno_out != ENOSYS)
+ goto fail;
+ __libc_missing_axp_stat64 = 1;
+ }
+
+ result = INTERNAL_SYSCALL (fstat, err, 2, fd, &kbuf);
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return __xstat_conv (vers, &kbuf, buf);
+ errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
+
+ fail:
+ __set_errno (errno_out);
+ return -1;
+}
+hidden_def (__fxstat)
+weak_alias (__fxstat, _fxstat);
+strong_alias (__fxstat, __fxstat64);
+hidden_ver (__fxstat, __fxstat64)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/fxstatat.c b/libc/sysdeps/unix/sysv/linux/alpha/fxstatat.c
new file mode 100644
index 000000000..497694619
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/fxstatat.c
@@ -0,0 +1,99 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __fxstatat64 __fxstatat64_disable
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <xstatconv.h>
+
+#undef __fxstatat64
+
+
+/* Get information about the file NAME in BUF. */
+int
+__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
+{
+ if (flag & ~AT_SYMLINK_NOFOLLOW)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+ int result, errno_out;
+ struct kernel_stat kst;
+
+ if (vers == _STAT_VER_KERNEL64 && !__libc_missing_axp_stat64)
+ {
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lstat64, err, 2, file, st);
+ else
+ result = INTERNAL_SYSCALL (stat64, err, 2, file, st);
+
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return result;
+ errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
+ if (errno_out != ENOSYS)
+ goto fail;
+ __libc_missing_axp_stat64 = 1;
+ }
+
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lstat, err, 2, file, &kst);
+ else
+ result = INTERNAL_SYSCALL (stat, err, 2, file, &kst);
+
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return __xstat_conv (vers, &kst, st);
+ errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
+
+ fail:
+ __atfct_seterrno (errno_out, fd, buf);
+
+ return -1;
+}
+libc_hidden_def (__fxstatat)
+strong_alias (__fxstatat, __fxstatat64);
+libc_hidden_ver(__fxstatat, __fxstatat64);
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/getclktck.c b/libc/sysdeps/unix/sysv/linux/alpha/getclktck.c
new file mode 100644
index 000000000..6636bbe68
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/getclktck.c
@@ -0,0 +1,2 @@
+#define SYSTEM_CLK_TCK 1024
+#include <sysdeps/unix/sysv/linux/getclktck.c>
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/getcontext.S b/libc/sysdeps/unix/sysv/linux/alpha/getcontext.S
new file mode 100644
index 000000000..f010f337e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/getcontext.S
@@ -0,0 +1,188 @@
+/* Save current context.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <ucontext-offsets.h>
+
+/* ??? Should be a better place for this that's asm friendly. */
+#define SIG_BLOCK 1
+
+
+ENTRY (__getcontext)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ bsr $0, __getcontext_x
+ mov $31, $0
+ ret
+
+END(__getcontext)
+weak_alias (__getcontext, getcontext)
+
+
+/* An internal routine used by getcontext and setcontext.
+ The incomming return address register is $0. */
+
+ .align 4
+ .globl __getcontext_x
+ .hidden __getcontext_x
+ .usepv __getcontext_x, no
+
+ cfi_startproc
+ cfi_return_column (64)
+__getcontext_x:
+ cfi_register (64, 0)
+
+ .set noat
+
+ /* Return value of getcontext. $0 is the only register
+ whose value is not preserved. */
+ stq $31, UC_SIGCTX+SC_REGS($16)
+
+ /* Store all registers into the context. */
+ stq $1, UC_SIGCTX+SC_REGS+1*8($16)
+ stq $2, UC_SIGCTX+SC_REGS+2*8($16)
+ stq $3, UC_SIGCTX+SC_REGS+3*8($16)
+ stq $4, UC_SIGCTX+SC_REGS+4*8($16)
+ stq $5, UC_SIGCTX+SC_REGS+5*8($16)
+ stq $6, UC_SIGCTX+SC_REGS+6*8($16)
+ stq $7, UC_SIGCTX+SC_REGS+7*8($16)
+ stq $8, UC_SIGCTX+SC_REGS+8*8($16)
+ stq $9, UC_SIGCTX+SC_REGS+9*8($16)
+ stq $10, UC_SIGCTX+SC_REGS+10*8($16)
+ stq $11, UC_SIGCTX+SC_REGS+11*8($16)
+ stq $12, UC_SIGCTX+SC_REGS+12*8($16)
+ stq $13, UC_SIGCTX+SC_REGS+13*8($16)
+ stq $14, UC_SIGCTX+SC_REGS+14*8($16)
+ stq $15, UC_SIGCTX+SC_REGS+15*8($16)
+ stq $16, UC_SIGCTX+SC_REGS+16*8($16)
+ stq $17, UC_SIGCTX+SC_REGS+17*8($16)
+ stq $18, UC_SIGCTX+SC_REGS+18*8($16)
+ stq $19, UC_SIGCTX+SC_REGS+19*8($16)
+ stq $20, UC_SIGCTX+SC_REGS+20*8($16)
+ stq $21, UC_SIGCTX+SC_REGS+21*8($16)
+ stq $22, UC_SIGCTX+SC_REGS+22*8($16)
+ stq $23, UC_SIGCTX+SC_REGS+23*8($16)
+ stq $24, UC_SIGCTX+SC_REGS+24*8($16)
+ stq $25, UC_SIGCTX+SC_REGS+25*8($16)
+ stq $26, UC_SIGCTX+SC_REGS+26*8($16)
+ stq $27, UC_SIGCTX+SC_REGS+27*8($16)
+ stq $28, UC_SIGCTX+SC_REGS+28*8($16)
+ stq $29, UC_SIGCTX+SC_REGS+29*8($16)
+ stq $30, UC_SIGCTX+SC_REGS+30*8($16)
+ stq $31, UC_SIGCTX+SC_REGS+31*8($16)
+
+ stt $f0, UC_SIGCTX+SC_FPREGS+0*8($16)
+ stt $f1, UC_SIGCTX+SC_FPREGS+1*8($16)
+ stt $f2, UC_SIGCTX+SC_FPREGS+2*8($16)
+ stt $f3, UC_SIGCTX+SC_FPREGS+3*8($16)
+ stt $f4, UC_SIGCTX+SC_FPREGS+4*8($16)
+ stt $f5, UC_SIGCTX+SC_FPREGS+5*8($16)
+ stt $f6, UC_SIGCTX+SC_FPREGS+6*8($16)
+ stt $f7, UC_SIGCTX+SC_FPREGS+7*8($16)
+ stt $f8, UC_SIGCTX+SC_FPREGS+8*8($16)
+ stt $f9, UC_SIGCTX+SC_FPREGS+9*8($16)
+ stt $f10, UC_SIGCTX+SC_FPREGS+10*8($16)
+ stt $f11, UC_SIGCTX+SC_FPREGS+11*8($16)
+ stt $f12, UC_SIGCTX+SC_FPREGS+12*8($16)
+ stt $f13, UC_SIGCTX+SC_FPREGS+13*8($16)
+ stt $f14, UC_SIGCTX+SC_FPREGS+14*8($16)
+ stt $f15, UC_SIGCTX+SC_FPREGS+15*8($16)
+ stt $f16, UC_SIGCTX+SC_FPREGS+16*8($16)
+ stt $f17, UC_SIGCTX+SC_FPREGS+17*8($16)
+ stt $f18, UC_SIGCTX+SC_FPREGS+18*8($16)
+ stt $f19, UC_SIGCTX+SC_FPREGS+19*8($16)
+ stt $f20, UC_SIGCTX+SC_FPREGS+20*8($16)
+ stt $f21, UC_SIGCTX+SC_FPREGS+21*8($16)
+ stt $f22, UC_SIGCTX+SC_FPREGS+22*8($16)
+ stt $f23, UC_SIGCTX+SC_FPREGS+23*8($16)
+ stt $f24, UC_SIGCTX+SC_FPREGS+24*8($16)
+ stt $f25, UC_SIGCTX+SC_FPREGS+25*8($16)
+ stt $f26, UC_SIGCTX+SC_FPREGS+26*8($16)
+ stt $f27, UC_SIGCTX+SC_FPREGS+27*8($16)
+ stt $f28, UC_SIGCTX+SC_FPREGS+28*8($16)
+ stt $f29, UC_SIGCTX+SC_FPREGS+29*8($16)
+ stt $f30, UC_SIGCTX+SC_FPREGS+30*8($16)
+ stt $f31, UC_SIGCTX+SC_FPREGS+31*8($16)
+
+ mf_fpcr $f0
+ lda $1, 8
+ stt $f0, UC_SIGCTX+SC_FPCR($16)
+
+ /* The return address of getcontext is the restart pc. */
+ stq $26, UC_SIGCTX+SC_PC($16)
+
+ /* Userlevel always has a processor status word of 8. */
+ stq $1, UC_SIGCTX+SC_PS($16)
+
+ /* Save registers around the syscall. We preserve $17
+ for the benefit of swapcontext. */
+ subq $30, 4*8, $30
+ cfi_adjust_cfa_offset(4*8)
+ stq $0, 0($30)
+ cfi_rel_offset(64, 0)
+ stq $16, 8($30)
+ stq $17, 16($30)
+
+ /* Save the current signal mask. Whee, there are three
+ copies of this in the alpha ucontext_t. */
+ lda $16, SIG_BLOCK
+ lda $17, 0
+ lda $0, __NR_osf_sigprocmask
+ callsys
+
+ ldq $16, 8($30)
+ ldq $17, 16($30)
+
+ stq $0, UC_OSF_SIGMASK($16)
+ stq $0, UC_SIGCTX+SC_MASK($16)
+ stq $0, UC_SIGMASK($16)
+ stq $31, UC_SIGMASK + 1*8($16)
+ stq $31, UC_SIGMASK + 2*8($16)
+ stq $31, UC_SIGMASK + 3*8($16)
+ stq $31, UC_SIGMASK + 4*8($16)
+ stq $31, UC_SIGMASK + 5*8($16)
+ stq $31, UC_SIGMASK + 6*8($16)
+ stq $31, UC_SIGMASK + 7*8($16)
+ stq $31, UC_SIGMASK + 8*8($16)
+ stq $31, UC_SIGMASK + 9*8($16)
+ stq $31, UC_SIGMASK +10*8($16)
+ stq $31, UC_SIGMASK +11*8($16)
+ stq $31, UC_SIGMASK +12*8($16)
+ stq $31, UC_SIGMASK +13*8($16)
+ stq $31, UC_SIGMASK +14*8($16)
+ stq $31, UC_SIGMASK +15*8($16)
+
+ ldq $0, 0($30)
+ addq $30, 4*8, $30
+ cfi_register (64, 0)
+ cfi_adjust_cfa_offset(-4*8)
+ ret $31, ($0), 1
+
+ cfi_endproc
+ .size __getcontext_x, .-__getcontext_x
+ .type __getcontext_x, @function
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/getdents.c b/libc/sysdeps/unix/sysv/linux/alpha/getdents.c
new file mode 100644
index 000000000..dfecfef92
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/getdents.c
@@ -0,0 +1,3 @@
+#define DIRENT_SET_DP_INO(dp, value) \
+ do { (dp)->d_ino = (value); (dp)->__pad = 0; } while (0)
+#include <sysdeps/unix/sysv/linux/getdents.c>
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/getdents64.c b/libc/sysdeps/unix/sysv/linux/alpha/getdents64.c
new file mode 100644
index 000000000..e53570c03
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/getdents64.c
@@ -0,0 +1 @@
+#include "../getdents64.c"
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/gethostname.c b/libc/sysdeps/unix/sysv/linux/alpha/gethostname.c
new file mode 100644
index 000000000..4e15ee43e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/gethostname.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+int
+__gethostname (char *name, size_t len)
+{
+ int result;
+
+ result = INLINE_SYSCALL (gethostname, 2, CHECK_N (name, len), len);
+
+ if (result == 0
+ /* See whether the string is terminated. If not we will return
+ an error. */
+ && memchr (name, '\0', len) == NULL)
+ {
+ __set_errno (EOVERFLOW);
+ result = -1;
+ }
+
+ return result;
+}
+
+weak_alias (__gethostname, gethostname)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/getitimer.S b/libc/sysdeps/unix/sysv/linux/alpha/getitimer.S
new file mode 100644
index 000000000..6644a5c36
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/getitimer.S
@@ -0,0 +1,113 @@
+/* Copyright (C) 1998, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+.text
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+#define GETITIMER __getitimer_tv64
+#else
+#define GETITIMER getitimer
+#endif
+
+#if defined __ASSUME_TIMEVAL64
+PSEUDO(GETITIMER, getitimer, 2)
+ ret
+PSEUDO_END(GETITIMER)
+#else
+/* The problem here is that initially we made struct timeval compatible with
+ OSF/1, using int32. But we defined time_t with uint64, and later found
+ that POSIX requires tv_sec to be time_t.
+
+ So now we have to do compatibility stuff. */
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. */
+.comm __libc_missing_axp_tv64, 4
+
+LEAF(GETITIMER, 16)
+ ldgp gp, 0(pv)
+ subq sp, 16, sp
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ ldl t0, __libc_missing_axp_tv64
+
+ /* Save arguments in case we do need to fall back. */
+ stq a0, 0(sp)
+ stq a1, 8(sp)
+
+ bne t0, $do32
+
+ ldi v0, SYS_ify(getitimer)
+ callsys
+ bne a3, $err64
+
+ /* Everything ok. */
+ addq sp, 16, sp
+ ret
+
+ /* If we didn't get ENOSYS, it is a real error. */
+ .align 3
+$err64: cmpeq v0, ENOSYS, t0
+ beq t0, $error
+ stl t0, __libc_missing_axp_tv64
+
+ /* Recover the saved arguments. */
+ ldq a1, 8(sp)
+ ldq a0, 0(sp)
+
+ .align 3
+$do32: ldi v0, SYS_ify(osf_getitimer)
+ callsys
+ bne a3, $error
+
+ /* Copy back to proper format. */
+ ldq a1, 8(sp)
+ ldl t0, 0(a1)
+ ldl t1, 4(a1)
+ ldl t2, 8(a1)
+ ldl t3, 12(a1)
+ stq t0, 0(a1)
+ stq t1, 8(a1)
+ stq t2, 16(a1)
+ stq t3, 24(a1)
+
+ addq sp, 16, sp
+ ret
+
+ .align 3
+$error:
+ addq sp, 16, sp
+ SYSCALL_ERROR_HANDLER
+
+END(GETITIMER)
+#endif /* __ASSUME_TIMEVAL64 */
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+default_symbol_version (__getitimer_tv64, getitimer, GLIBC_2.1)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/getrusage.S b/libc/sysdeps/unix/sysv/linux/alpha/getrusage.S
new file mode 100644
index 000000000..0bca4b5f2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/getrusage.S
@@ -0,0 +1,149 @@
+/* Copyright (C) 1998, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+.text
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+#define GETRUSAGE __getrusage_tv64
+#else
+#define GETRUSAGE __getrusage
+#endif
+
+#if defined __ASSUME_TIMEVAL64
+PSEUDO(GETRUSAGE, getrusage, 2)
+ ret
+PSEUDO_END(GETRUSAGE)
+#else
+/* The problem here is that initially we made struct timeval compatible with
+ OSF/1, using int32. But we defined time_t with uint64, and later found
+ that POSIX requires tv_sec to be time_t.
+
+ So now we have to do compatibility stuff. */
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. */
+.comm __libc_missing_axp_tv64, 4
+
+LEAF(GETRUSAGE, 16)
+ ldgp gp, 0(pv)
+ subq sp, 16, sp
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ ldl t0, __libc_missing_axp_tv64
+
+ /* Save arguments in case we do need to fall back. */
+ stq a0, 0(sp)
+ stq a1, 8(sp)
+
+ bne t0, $do32
+
+ ldi v0, SYS_ify(getrusage)
+ callsys
+ bne a3, $err64
+
+ /* Everything ok. */
+ addq sp, 16, sp
+ ret
+
+ /* If we didn't get ENOSYS, it is a real error. */
+ .align 3
+$err64: cmpeq v0, ENOSYS, t0
+ beq t0, $error
+ stl t0, __libc_missing_axp_tv64
+
+ /* Recover the saved arguments. */
+ ldq a1, 8(sp)
+ ldq a0, 0(sp)
+
+ .align 3
+$do32: ldi v0, SYS_ify(osf_getrusage)
+ callsys
+ bne a3, $error
+
+ /* Copy back to proper format. */
+ ldq a1, 8(sp)
+ ldl t0, 0(a1) # ru_utime.tv_sec
+ ldl t1, 4(a1) # ru_utime.tv_usec
+ ldl t2, 8(a1) # ru_stime.tv_sec
+ ldl t3, 12(a1) # ru_stime.tv_usec
+ ldt $f15, 16(a1) # ru_maxrss
+ ldt $f16, 24(a1) # ru_ixrss
+ ldt $f17, 32(a1) # ru_idrss
+ ldt $f18, 40(a1) # ru_isrss
+ ldt $f19, 48(a1) # ru_minflt
+ ldt $f20, 56(a1) # ru_majflt
+ ldt $f21, 64(a1) # ru_nswap
+ ldt $f22, 72(a1) # ru_inblock
+ ldt $f23, 80(a1) # ru_oublock
+ ldt $f24, 88(a1) # ru_msgsend
+ ldt $f25, 96(a1) # ru_msgrcv
+ ldt $f26, 104(a1) # ru_nsignals
+ ldt $f27, 112(a1) # ru_nvcsw
+ .set noat
+ ldt $f28, 120(a1) # ru_nivcsw
+ .set at
+ stq t0, 0(a1)
+ stq t1, 8(a1)
+ stq t2, 16(a1)
+ stq t3, 24(a1)
+ stt $f15, 32(a1)
+ stt $f16, 40(a1)
+ stt $f17, 48(a1)
+ stt $f18, 56(a1)
+ stt $f19, 64(a1)
+ stt $f20, 72(a1)
+ stt $f21, 80(a1)
+ stt $f22, 88(a1)
+ stt $f23, 96(a1)
+ stt $f24, 104(a1)
+ stt $f25, 112(a1)
+ stt $f26, 120(a1)
+ stt $f27, 128(a1)
+ .set noat
+ stt $f28, 136(a1)
+ .set at
+
+ addq sp, 16, sp
+ ret
+
+ .align 3
+$error:
+ addq sp, 16, sp
+ SYSCALL_ERROR_HANDLER
+
+END(GETRUSAGE)
+#endif /* __ASSUME_TIMEVAL64 */
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+strong_alias(__getrusage_tv64, ____getrusage_tv64)
+default_symbol_version (____getrusage_tv64, __getrusage, GLIBC_2.1)
+default_symbol_version (__getrusage_tv64, getrusage, GLIBC_2.1)
+#else
+weak_alias (__getrusage, getrusage)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/getsysstats.c b/libc/sysdeps/unix/sysv/linux/alpha/getsysstats.c
new file mode 100644
index 000000000..0e49a8452
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/getsysstats.c
@@ -0,0 +1,57 @@
+/* Determine various system internal values, Linux/Alpha version.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Schwab <schwab@suse.de>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* We need to define a special parser for /proc/cpuinfo. */
+#define GET_NPROCS_PARSER(FP, BUFFER, RESULT) \
+ do \
+ { \
+ /* Find the line that contains the information about the number of \
+ active cpus. We don't have to fear extremely long lines since \
+ the kernel will not generate them. 8192 bytes are really enough. \
+ If there is no "CPUs ..." line then we are on a UP system. */ \
+ (RESULT) = 1; \
+ while (fgets_unlocked (BUFFER, sizeof (BUFFER), FP) != NULL) \
+ if ((sscanf (BUFFER, "cpus active : %d", &(RESULT)) == 1) \
+ || (sscanf (BUFFER, "CPUs probed %*d active %d", \
+ &(RESULT)) == 1)) \
+ break; \
+ } \
+ while (0)
+
+
+/* On the Alpha we can distinguish between the number of configured and
+ active cpus. */
+#define GET_NPROCS_CONF_PARSER(FP, BUFFER, RESULT) \
+ do \
+ { \
+ /* Find the line that contains the information about the number of \
+ probed cpus. We don't have to fear extremely long lines since \
+ the kernel will not generate them. 8192 bytes are really enough. \
+ If there is no "CPUs ..." line then we are on a UP system. */ \
+ (RESULT) = 1; \
+ while (fgets_unlocked ((BUFFER), sizeof (BUFFER), (FP)) != NULL) \
+ if ((sscanf (buffer, "cpus detected : %d", &(RESULT)) == 1) \
+ || (sscanf (buffer, "CPUs probed %d", &(RESULT)) == 1)) \
+ break; \
+ } \
+ while (0)
+
+#include <sysdeps/unix/sysv/linux/getsysstats.c>
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/gettimeofday.S b/libc/sysdeps/unix/sysv/linux/alpha/gettimeofday.S
new file mode 100644
index 000000000..7c9183a4f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/gettimeofday.S
@@ -0,0 +1,120 @@
+/* Copyright (C) 1998, 2002, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+.text
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+#define GETTIMEOFDAY __gettimeofday_tv64
+#else
+#define GETTIMEOFDAY __gettimeofday
+#endif
+
+#if defined __ASSUME_TIMEVAL64
+PSEUDO(GETTIMEOFDAY, gettimeofday, 2)
+ ret
+PSEUDO_END(GETTIMEOFDAY)
+#else
+
+/* The problem here is that initially we made struct timeval compatible with
+ OSF/1, using int32. But we defined time_t with uint64, and later found
+ that POSIX requires tv_sec to be time_t.
+
+ So now we have to do compatibility stuff. */
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. */
+.comm __libc_missing_axp_tv64, 4
+
+LEAF(GETTIMEOFDAY, 16)
+ ldgp gp, 0(pv)
+ subq sp, 16, sp
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ ldl t0, __libc_missing_axp_tv64
+
+ /* Save arguments in case we do need to fall back. */
+ stq a0, 0(sp)
+ stq a1, 8(sp)
+
+ bne t0, $do32
+
+ ldi v0, SYS_ify(gettimeofday)
+ callsys
+ bne a3, $err64
+
+ /* Everything ok. */
+ addq sp, 16, sp
+ ret
+
+ /* If we didn't get ENOSYS, it is a real error. */
+ .align 3
+$err64: cmpeq v0, ENOSYS, t0
+ beq t0, $error
+ stl t0, __libc_missing_axp_tv64
+
+ /* Recover the saved arguments. */
+ ldq a1, 8(sp)
+ ldq a0, 0(sp)
+
+ .align 3
+$do32: ldi v0, SYS_ify(osf_gettimeofday)
+ callsys
+ bne a3, $error
+
+ /* Copy back to proper format. */
+ ldq a0, 0(sp)
+ beq a0, 2f
+ ldl t0, 0(a0)
+ ldl t1, 4(a0)
+ stq t0, 0(a0)
+ stq t1, 8(a0)
+
+2: addq sp, 16, sp
+ ret
+
+ .align 3
+$error:
+ addq sp, 16, sp
+ SYSCALL_ERROR_HANDLER
+
+END(GETTIMEOFDAY)
+#endif /* __ASSUME_TIMEVAL64 */
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+default_symbol_version (__gettimeofday_tv64, __gettimeofday, GLIBC_2.1)
+
+/* It seems to me to be a misfeature of the assembler that we can only
+ have one version-alias per symbol. So create an alias ourselves.
+ The 'p' is for 'public'. *Shrug* */
+strong_alias (__gettimeofday_tv64, __gettimeofday_tv64p)
+default_symbol_version (__gettimeofday_tv64p, gettimeofday, GLIBC_2.1)
+#else
+weak_alias (__gettimeofday, gettimeofday)
+#endif
+strong_alias(GETTIMEOFDAY, __gettimeofday_internal)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/glob.c b/libc/sysdeps/unix/sysv/linux/alpha/glob.c
new file mode 100644
index 000000000..84573899d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/glob.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 1998, 2000, 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define glob64 __no_glob64_decl
+#define globfree64 __no_globfree64_decl
+
+#include <sys/types.h>
+#include <glob.h>
+#include <shlib-compat.h>
+
+/* For Linux/Alpha we have to make the glob symbols versioned. */
+#define glob(pattern, flags, errfunc, pglob) \
+ __new_glob (pattern, flags, errfunc, pglob)
+#define globfree(pglob) \
+ __new_globfree (pglob)
+
+/* We need prototypes for these new names. */
+extern int __new_glob (const char *__pattern, int __flags,
+ int (*__errfunc) (const char *, int),
+ glob_t *__pglob);
+extern void __new_globfree (glob_t *__pglob);
+
+#include <posix/glob.c>
+
+#undef glob
+#undef globfree
+#undef glob64
+#undef globfree64
+
+versioned_symbol (libc, __new_glob, glob, GLIBC_2_1);
+versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1);
+libc_hidden_ver (__new_glob, glob)
+libc_hidden_ver (__new_globfree, globfree)
+
+weak_alias (__new_glob, glob64)
+weak_alias (__new_globfree, globfree64)
+libc_hidden_ver (__new_globfree, globfree64)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S b/libc/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S
new file mode 100644
index 000000000..4779f175e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S
@@ -0,0 +1,61 @@
+/* Copyright (C) 1993, 1995, 1996, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger <davidm@azstarnet.com>, 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "kernel_sysinfo.h"
+
+
+ .text
+
+LEAF(__ieee_get_fp_control, 16)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda sp, -16(sp)
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+ .prologue 1
+#elif defined PIC
+ lda sp, -16(sp)
+ .prologue 0
+#else
+ ldgp gp, 0(pv)
+ lda sp, -16(sp)
+ .prologue 1
+#endif
+
+ mov sp, a1
+ ldi a0, GSI_IEEE_FP_CONTROL
+ ldi v0, __NR_osf_getsysinfo
+ call_pal PAL_callsys
+ bne a3, $error
+
+ ldq v0, 0(sp)
+ lda sp, 16(sp)
+ ret
+
+$error:
+ lda sp, 16(sp)
+ SYSCALL_ERROR_HANDLER
+
+ END(__ieee_get_fp_control)
+
+libc_hidden_def(__ieee_get_fp_control)
+weak_alias (__ieee_get_fp_control, ieee_get_fp_control)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S b/libc/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S
new file mode 100644
index 000000000..a9c0891aa
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S
@@ -0,0 +1,61 @@
+/* Copyright (C) 1993, 1995, 1996, 1997, 2003, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger <davidm@azstarnet.com>, 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "kernel_sysinfo.h"
+
+
+LEAF(__ieee_set_fp_control, 16)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ lda sp, -16(sp)
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+ .prologue 1
+#elif defined PIC
+ lda sp, -16(sp)
+ .prologue 0
+#else
+ ldgp gp, 0(pv)
+ lda sp, -16(sp)
+ .prologue 1
+#endif
+
+ stq a0, 0(sp)
+ mov sp, a1
+ ldi a0, SSI_IEEE_FP_CONTROL
+ ldi v0, __NR_osf_setsysinfo
+ call_pal PAL_callsys
+
+ bne a3, $error
+
+ lda sp, 16(sp)
+ ret
+
+$error:
+ lda sp, 16(sp)
+ SYSCALL_ERROR_HANDLER
+
+ END(__ieee_set_fp_control)
+
+libc_hidden_def(__ieee_set_fp_control)
+weak_alias (__ieee_set_fp_control, ieee_set_fp_control)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/ioperm.c b/libc/sysdeps/unix/sysv/linux/alpha/ioperm.c
new file mode 100644
index 000000000..6c4115d1c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/ioperm.c
@@ -0,0 +1,878 @@
+/* Copyright (C) 1992, 1996-1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* I/O access is restricted to ISA port space (ports 0..65535).
+ Modern devices hopefully are sane enough not to put any performance
+ critical registers in i/o space.
+
+ On the first call to ioperm, the entire (E)ISA port space is mapped
+ into the virtual address space at address io.base. mprotect calls
+ are then used to enable/disable access to ports. Per page, there
+ are PAGE_SIZE>>IO_SHIFT I/O ports (e.g., 256 ports on a Low Cost Alpha
+ based system using 8KB pages).
+
+ Keep in mind that this code should be able to run in a 32bit address
+ space. It is therefore unreasonable to expect mmap'ing the entire
+ sparse address space would work (e.g., the Low Cost Alpha chip has an
+ I/O address space that's 512MB large!). */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/io.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#define PATH_ALPHA_SYSTYPE "/etc/alpha_systype"
+#define PATH_CPUINFO "/proc/cpuinfo"
+
+#define MAX_PORT 0x10000
+#define vip volatile int *
+#define vuip volatile unsigned int *
+#define vusp volatile unsigned short *
+#define vucp volatile unsigned char *
+
+#define JENSEN_IO_BASE (0x300000000UL)
+#define JENSEN_SPARSE_MEM (0x200000000UL)
+
+/* With respect to the I/O architecture, APECS and LCA are identical,
+ so the following defines apply to LCA as well. */
+#define APECS_IO_BASE (0x1c0000000UL)
+#define APECS_SPARSE_MEM (0x200000000UL)
+#define APECS_DENSE_MEM (0x300000000UL)
+
+/* The same holds for CIA and PYXIS, except for PYXIS we prefer BWX. */
+#define CIA_IO_BASE (0x8580000000UL)
+#define CIA_SPARSE_MEM (0x8000000000UL)
+#define CIA_DENSE_MEM (0x8600000000UL)
+
+#define PYXIS_IO_BASE (0x8900000000UL)
+#define PYXIS_DENSE_MEM (0x8800000000UL)
+
+/* SABLE is EV4, GAMMA is EV5 */
+#define T2_IO_BASE (0x3a0000000UL)
+#define T2_SPARSE_MEM (0x200000000UL)
+#define T2_DENSE_MEM (0x3c0000000UL)
+
+#define GAMMA_IO_BASE (0x83a0000000UL)
+#define GAMMA_SPARSE_MEM (0x8200000000UL)
+#define GAMMA_DENSE_MEM (0x83c0000000UL)
+
+/* NOTE: these are hardwired to PCI bus 0 addresses!!! */
+#define MCPCIA_IO_BASE (0xf980000000UL)
+#define MCPCIA_SPARSE_MEM (0xf800000000UL)
+#define MCPCIA_DENSE_MEM (0xf900000000UL)
+
+/* Tsunami and Irongate use the same offsets, at least for hose 0. */
+#define TSUNAMI_IO_BASE (0x801fc000000UL)
+#define TSUNAMI_DENSE_MEM (0x80000000000UL)
+
+/* Polaris has SPARSE space, but we prefer to use only DENSE
+ because of some idiosyncracies in actually using SPARSE. */
+#define POLARIS_IO_BASE (0xf9fc000000UL)
+#define POLARIS_DENSE_MEM (0xf900000000UL)
+
+typedef enum {
+ IOSYS_UNKNOWN, IOSYS_JENSEN, IOSYS_APECS, IOSYS_CIA, IOSYS_PYXIS, IOSYS_T2,
+ IOSYS_TSUNAMI, IOSYS_MCPCIA, IOSYS_GAMMA, IOSYS_POLARIS,
+ IOSYS_CPUDEP, IOSYS_PCIDEP
+} iosys_t;
+
+typedef enum {
+ IOSWIZZLE_JENSEN, IOSWIZZLE_SPARSE, IOSWIZZLE_DENSE
+} ioswizzle_t;
+
+static struct io_system {
+ unsigned long int bus_memory_base;
+ unsigned long int sparse_bus_mem_base;
+ unsigned long int bus_io_base;
+} io_system[] = { /* NOTE! must match iosys_t enumeration */
+/* UNKNOWN */ {0, 0, 0},
+/* JENSEN */ {0, JENSEN_SPARSE_MEM, JENSEN_IO_BASE},
+/* APECS */ {APECS_DENSE_MEM, APECS_SPARSE_MEM, APECS_IO_BASE},
+/* CIA */ {CIA_DENSE_MEM, CIA_SPARSE_MEM, CIA_IO_BASE},
+/* PYXIS */ {PYXIS_DENSE_MEM, 0, PYXIS_IO_BASE},
+/* T2 */ {T2_DENSE_MEM, T2_SPARSE_MEM, T2_IO_BASE},
+/* TSUNAMI */ {TSUNAMI_DENSE_MEM, 0, TSUNAMI_IO_BASE},
+/* MCPCIA */ {MCPCIA_DENSE_MEM, MCPCIA_SPARSE_MEM, MCPCIA_IO_BASE},
+/* GAMMA */ {GAMMA_DENSE_MEM, GAMMA_SPARSE_MEM, GAMMA_IO_BASE},
+/* POLARIS */ {POLARIS_DENSE_MEM, 0, POLARIS_IO_BASE},
+/* CPUDEP */ {0, 0, 0}, /* for platforms dependent on CPU type */
+/* PCIDEP */ {0, 0, 0}, /* for platforms dependent on core logic */
+};
+
+static struct platform {
+ const char *name;
+ iosys_t io_sys;
+} platform[] = {
+ {"Alcor", IOSYS_CIA},
+ {"Avanti", IOSYS_APECS},
+ {"Cabriolet", IOSYS_APECS},
+ {"EB164", IOSYS_PCIDEP},
+ {"EB64+", IOSYS_APECS},
+ {"EB66", IOSYS_APECS},
+ {"EB66P", IOSYS_APECS},
+ {"Jensen", IOSYS_JENSEN},
+ {"Miata", IOSYS_PYXIS},
+ {"Mikasa", IOSYS_CPUDEP},
+ {"Nautilus", IOSYS_TSUNAMI},
+ {"Noname", IOSYS_APECS},
+ {"Noritake", IOSYS_CPUDEP},
+ {"Rawhide", IOSYS_MCPCIA},
+ {"Ruffian", IOSYS_PYXIS},
+ {"Sable", IOSYS_CPUDEP},
+ {"Takara", IOSYS_CIA},
+ {"Tsunami", IOSYS_TSUNAMI},
+ {"XL", IOSYS_APECS},
+};
+
+struct ioswtch {
+ void (*sethae)(unsigned long int addr);
+ void (*outb)(unsigned char b, unsigned long int port);
+ void (*outw)(unsigned short b, unsigned long int port);
+ void (*outl)(unsigned int b, unsigned long int port);
+ unsigned int (*inb)(unsigned long int port);
+ unsigned int (*inw)(unsigned long int port);
+ unsigned int (*inl)(unsigned long int port);
+};
+
+static struct {
+ unsigned long int hae_cache;
+ unsigned long int base;
+ struct ioswtch * swp;
+ unsigned long int bus_memory_base;
+ unsigned long int sparse_bus_memory_base;
+ unsigned long int io_base;
+ ioswizzle_t swiz;
+} io;
+
+static inline void
+stb_mb(unsigned char val, unsigned long addr)
+{
+ __asm__("stb %1,%0; mb" : "=m"(*(vucp)addr) : "r"(val));
+}
+
+static inline void
+stw_mb(unsigned short val, unsigned long addr)
+{
+ __asm__("stw %1,%0; mb" : "=m"(*(vusp)addr) : "r"(val));
+}
+
+static inline void
+stl_mb(unsigned int val, unsigned long addr)
+{
+ __asm__("stl %1,%0; mb" : "=m"(*(vip)addr) : "r"(val));
+}
+
+/* No need to examine error -- sethae never fails. */
+static inline void
+__sethae(unsigned long value)
+{
+ register unsigned long r16 __asm__("$16") = value;
+ register unsigned long r0 __asm__("$0") = __NR_sethae;
+ __asm__ __volatile__ ("callsys"
+ : "=r"(r0)
+ : "0"(r0), "r" (r16)
+ : inline_syscall_clobbers, "$19");
+}
+
+extern long __pciconfig_iobase(enum __pciconfig_iobase_which __which,
+ unsigned long int __bus,
+ unsigned long int __dfn);
+
+static inline unsigned long int
+port_to_cpu_addr (unsigned long int port, ioswizzle_t ioswiz, int size)
+{
+ if (ioswiz == IOSWIZZLE_SPARSE)
+ return io.base + (port << 5) + ((size - 1) << 3);
+ else if (ioswiz == IOSWIZZLE_DENSE)
+ return port + io.base;
+ else
+ return io.base + (port << 7) + ((size - 1) << 5);
+}
+
+static inline void
+inline_sethae (unsigned long int addr, ioswizzle_t ioswiz)
+{
+ if (ioswiz == IOSWIZZLE_SPARSE)
+ {
+ unsigned long int msb;
+
+ /* no need to set hae if msb is 0: */
+ msb = addr & 0xf8000000;
+ if (msb && msb != io.hae_cache)
+ {
+ io.hae_cache = msb;
+ __sethae (msb);
+ }
+ }
+ else if (ioswiz == IOSWIZZLE_JENSEN)
+ {
+ /* HAE on the Jensen is bits 31:25 shifted right. */
+ addr >>= 25;
+ if (addr != io.hae_cache)
+ {
+ io.hae_cache = addr;
+ __sethae (addr);
+ }
+ }
+}
+
+static inline void
+inline_outb (unsigned char b, unsigned long int port, ioswizzle_t ioswiz)
+{
+ unsigned int w;
+ unsigned long int addr = port_to_cpu_addr (port, ioswiz, 1);
+
+ asm ("insbl %2,%1,%0" : "=r" (w) : "ri" (port & 0x3), "r" (b));
+ stl_mb(w, addr);
+}
+
+
+static inline void
+inline_outw (unsigned short int b, unsigned long int port, ioswizzle_t ioswiz)
+{
+ unsigned long w;
+ unsigned long int addr = port_to_cpu_addr (port, ioswiz, 2);
+
+ asm ("inswl %2,%1,%0" : "=r" (w) : "ri" (port & 0x3), "r" (b));
+ stl_mb(w, addr);
+}
+
+
+static inline void
+inline_outl (unsigned int b, unsigned long int port, ioswizzle_t ioswiz)
+{
+ unsigned long int addr = port_to_cpu_addr (port, ioswiz, 4);
+
+ stl_mb(b, addr);
+}
+
+
+static inline unsigned int
+inline_inb (unsigned long int port, ioswizzle_t ioswiz)
+{
+ unsigned long int addr = port_to_cpu_addr (port, ioswiz, 1);
+ int result;
+
+ result = *(vip) addr;
+ result >>= (port & 3) * 8;
+ return 0xffUL & result;
+}
+
+
+static inline unsigned int
+inline_inw (unsigned long int port, ioswizzle_t ioswiz)
+{
+ unsigned long int addr = port_to_cpu_addr (port, ioswiz, 2);
+ int result;
+
+ result = *(vip) addr;
+ result >>= (port & 3) * 8;
+ return 0xffffUL & result;
+}
+
+
+static inline unsigned int
+inline_inl (unsigned long int port, ioswizzle_t ioswiz)
+{
+ unsigned long int addr = port_to_cpu_addr (port, ioswiz, 4);
+
+ return *(vuip) addr;
+}
+
+/*
+ * Now define the inline functions for CPUs supporting byte/word insns,
+ * and whose core logic supports I/O space accesses utilizing them.
+ *
+ * These routines could be used by MIATA, for example, because it has
+ * and EV56 plus PYXIS, but it currently uses SPARSE anyway. This is
+ * also true of RX164 which used POLARIS, but we will choose to use
+ * these routines in that case instead of SPARSE.
+ *
+ * These routines are necessary for TSUNAMI/TYPHOON based platforms,
+ * which will have (at least) EV6.
+ */
+
+static inline unsigned long int
+dense_port_to_cpu_addr (unsigned long int port)
+{
+ return port + io.base;
+}
+
+static inline void
+inline_bwx_outb (unsigned char b, unsigned long int port)
+{
+ unsigned long int addr = dense_port_to_cpu_addr (port);
+ stb_mb (b, addr);
+}
+
+static inline void
+inline_bwx_outw (unsigned short int b, unsigned long int port)
+{
+ unsigned long int addr = dense_port_to_cpu_addr (port);
+ stw_mb (b, addr);
+}
+
+static inline void
+inline_bwx_outl (unsigned int b, unsigned long int port)
+{
+ unsigned long int addr = dense_port_to_cpu_addr (port);
+ stl_mb (b, addr);
+}
+
+static inline unsigned int
+inline_bwx_inb (unsigned long int port)
+{
+ unsigned long int addr = dense_port_to_cpu_addr (port);
+ unsigned char r;
+
+ __asm__ ("ldbu %0,%1" : "=r"(r) : "m"(*(vucp)addr));
+ return r;
+}
+
+static inline unsigned int
+inline_bwx_inw (unsigned long int port)
+{
+ unsigned long int addr = dense_port_to_cpu_addr (port);
+ unsigned short r;
+
+ __asm__ ("ldwu %0,%1" : "=r"(r) : "m"(*(vusp)addr));
+ return r;
+}
+
+static inline unsigned int
+inline_bwx_inl (unsigned long int port)
+{
+ unsigned long int addr = dense_port_to_cpu_addr (port);
+
+ return *(vuip) addr;
+}
+
+/* macros to define routines with appropriate names and functions */
+
+/* these do either SPARSE or JENSEN swizzle */
+
+#define DCL_SETHAE(name, ioswiz) \
+static void \
+name##_sethae (unsigned long int addr) \
+{ \
+ inline_sethae (addr, IOSWIZZLE_##ioswiz); \
+}
+
+#define DCL_OUT(name, func, type, ioswiz) \
+static void \
+name##_##func (unsigned type b, unsigned long int addr) \
+{ \
+ inline_##func (b, addr, IOSWIZZLE_##ioswiz); \
+}
+
+#define DCL_IN(name, func, ioswiz) \
+static unsigned int \
+name##_##func (unsigned long int addr) \
+{ \
+ return inline_##func (addr, IOSWIZZLE_##ioswiz); \
+}
+
+/* these do DENSE, so no swizzle is needed */
+
+#define DCL_OUT_BWX(name, func, type) \
+static void \
+name##_##func (unsigned type b, unsigned long int addr) \
+{ \
+ inline_bwx_##func (b, addr); \
+}
+
+#define DCL_IN_BWX(name, func) \
+static unsigned int \
+name##_##func (unsigned long int addr) \
+{ \
+ return inline_bwx_##func (addr); \
+}
+
+/* now declare/define the necessary routines */
+
+DCL_SETHAE(jensen, JENSEN)
+DCL_OUT(jensen, outb, char, JENSEN)
+DCL_OUT(jensen, outw, short int, JENSEN)
+DCL_OUT(jensen, outl, int, JENSEN)
+DCL_IN(jensen, inb, JENSEN)
+DCL_IN(jensen, inw, JENSEN)
+DCL_IN(jensen, inl, JENSEN)
+
+DCL_SETHAE(sparse, SPARSE)
+DCL_OUT(sparse, outb, char, SPARSE)
+DCL_OUT(sparse, outw, short int, SPARSE)
+DCL_OUT(sparse, outl, int, SPARSE)
+DCL_IN(sparse, inb, SPARSE)
+DCL_IN(sparse, inw, SPARSE)
+DCL_IN(sparse, inl, SPARSE)
+
+DCL_SETHAE(dense, DENSE)
+DCL_OUT_BWX(dense, outb, char)
+DCL_OUT_BWX(dense, outw, short int)
+DCL_OUT_BWX(dense, outl, int)
+DCL_IN_BWX(dense, inb)
+DCL_IN_BWX(dense, inw)
+DCL_IN_BWX(dense, inl)
+
+/* define the "swizzle" switch */
+static struct ioswtch ioswtch[] = {
+ {
+ jensen_sethae,
+ jensen_outb, jensen_outw, jensen_outl,
+ jensen_inb, jensen_inw, jensen_inl
+ },
+ {
+ sparse_sethae,
+ sparse_outb, sparse_outw, sparse_outl,
+ sparse_inb, sparse_inw, sparse_inl
+ },
+ {
+ dense_sethae,
+ dense_outb, dense_outw, dense_outl,
+ dense_inb, dense_inw, dense_inl
+ }
+};
+
+#undef DEBUG_IOPERM
+
+/* Routine to process the /proc/cpuinfo information into the fields
+ that are required for correctly determining the platform parameters. */
+
+struct cpuinfo_data
+{
+ char systype[256]; /* system type field */
+ char sysvari[256]; /* system variation field */
+ char cpumodel[256]; /* cpu model field */
+};
+
+static inline int
+process_cpuinfo(struct cpuinfo_data *data)
+{
+ int got_type, got_vari, got_model;
+ char dummy[256];
+ FILE * fp;
+ int n;
+
+ data->systype[0] = 0;
+ data->sysvari[0] = 0;
+ data->cpumodel[0] = 0;
+
+ /* If there's an /etc/alpha_systype link, we're intending to override
+ whatever's in /proc/cpuinfo. */
+ n = __readlink (PATH_ALPHA_SYSTYPE, data->systype, 256 - 1);
+ if (n > 0)
+ {
+ data->systype[n] = '\0';
+ return 1;
+ }
+
+ fp = fopen (PATH_CPUINFO, "r");
+ if (!fp)
+ return 0;
+
+ got_type = got_vari = got_model = 0;
+
+ while (1)
+ {
+ if (fgets (dummy, 256, fp) == NULL)
+ break;
+ if (!got_type &&
+ sscanf (dummy, "system type : %256[^\n]\n", data->systype) == 1)
+ got_type = 1;
+ if (!got_vari &&
+ sscanf (dummy, "system variation : %256[^\n]\n", data->sysvari) == 1)
+ got_vari = 1;
+ if (!got_model &&
+ sscanf (dummy, "cpu model : %256[^\n]\n", data->cpumodel) == 1)
+ got_model = 1;
+ }
+
+ fclose (fp);
+
+#ifdef DEBUG_IOPERM
+ fprintf(stderr, "system type: `%s'\n", data->systype);
+ fprintf(stderr, "system vari: `%s'\n", data->sysvari);
+ fprintf(stderr, "cpu model: `%s'\n", data->cpumodel);
+#endif
+
+ return got_type + got_vari + got_model;
+}
+
+
+/*
+ * Initialize I/O system.
+ */
+static int
+init_iosys (void)
+{
+ long addr;
+ int i, olderrno = errno;
+ struct cpuinfo_data data;
+
+ /* First try the pciconfig_iobase syscall added to 2.2.15 and 2.3.99. */
+
+#ifdef __NR_pciconfig_iobase
+ addr = __pciconfig_iobase (IOBASE_DENSE_MEM, 0, 0);
+ if (addr != -1)
+ {
+ ioswizzle_t io_swiz;
+
+ if (addr == 0)
+ {
+ /* Only Jensen doesn't have dense mem space. */
+ io.sparse_bus_memory_base
+ = io_system[IOSYS_JENSEN].sparse_bus_mem_base;
+ io.io_base = io_system[IOSYS_JENSEN].bus_io_base;
+ io_swiz = IOSWIZZLE_JENSEN;
+ }
+ else
+ {
+ io.bus_memory_base = addr;
+
+ addr = __pciconfig_iobase (IOBASE_DENSE_IO, 0, 0);
+ if (addr != 0)
+ {
+ /* The X server uses _bus_base_sparse == 0 to know that
+ BWX access are supported to dense mem space. This is
+ true of every system that supports dense io space, so
+ never fill in io.sparse_bus_memory_base in this case. */
+ io_swiz = IOSWIZZLE_DENSE;
+ io.io_base = addr;
+ }
+ else
+ {
+ io.sparse_bus_memory_base
+ = __pciconfig_iobase (IOBASE_SPARSE_MEM, 0, 0);
+ io.io_base = __pciconfig_iobase (IOBASE_SPARSE_IO, 0, 0);
+ io_swiz = IOSWIZZLE_SPARSE;
+ }
+ }
+
+ io.swiz = io_swiz;
+ io.swp = &ioswtch[io_swiz];
+
+ return 0;
+ }
+#endif
+
+ /* Second, collect the contents of /etc/alpha_systype or /proc/cpuinfo. */
+
+ if (process_cpuinfo(&data) == 0)
+ {
+ /* This can happen if the format of /proc/cpuinfo changes. */
+ fprintf (stderr,
+ "ioperm.init_iosys: Unable to determine system type.\n"
+ "\t(May need " PATH_ALPHA_SYSTYPE " symlink?)\n");
+ __set_errno (ENODEV);
+ return -1;
+ }
+
+ /* Translate systype name into i/o system. */
+ for (i = 0; i < sizeof (platform) / sizeof (platform[0]); ++i)
+ {
+ if (strcmp (platform[i].name, data.systype) == 0)
+ {
+ iosys_t io_sys = platform[i].io_sys;
+
+ /* Some platforms can have either EV4 or EV5 CPUs. */
+ if (io_sys == IOSYS_CPUDEP)
+ {
+ /* SABLE or MIKASA or NORITAKE so far. */
+ if (strcmp (platform[i].name, "Sable") == 0)
+ {
+ if (strncmp (data.cpumodel, "EV4", 3) == 0)
+ io_sys = IOSYS_T2;
+ else if (strncmp (data.cpumodel, "EV5", 3) == 0)
+ io_sys = IOSYS_GAMMA;
+ }
+ else
+ {
+ /* This covers MIKASA/NORITAKE. */
+ if (strncmp (data.cpumodel, "EV4", 3) == 0)
+ io_sys = IOSYS_APECS;
+ else if (strncmp (data.cpumodel, "EV5", 3) == 0)
+ io_sys = IOSYS_CIA;
+ }
+ if (io_sys == IOSYS_CPUDEP)
+ {
+ /* This can happen if the format of /proc/cpuinfo changes.*/
+ fprintf (stderr, "ioperm.init_iosys: Unable to determine"
+ " CPU model.\n");
+ __set_errno (ENODEV);
+ return -1;
+ }
+ }
+ /* Some platforms can have different core logic chipsets */
+ if (io_sys == IOSYS_PCIDEP)
+ {
+ /* EB164 so far */
+ if (strcmp (data.systype, "EB164") == 0)
+ {
+ if (strncmp (data.sysvari, "RX164", 5) == 0)
+ io_sys = IOSYS_POLARIS;
+ else if (strncmp (data.sysvari, "LX164", 5) == 0
+ || strncmp (data.sysvari, "SX164", 5) == 0)
+ io_sys = IOSYS_PYXIS;
+ else
+ io_sys = IOSYS_CIA;
+ }
+ if (io_sys == IOSYS_PCIDEP)
+ {
+ /* This can happen if the format of /proc/cpuinfo changes.*/
+ fprintf (stderr, "ioperm.init_iosys: Unable to determine"
+ " core logic chipset.\n");
+ __set_errno (ENODEV);
+ return -1;
+ }
+ }
+ io.bus_memory_base = io_system[io_sys].bus_memory_base;
+ io.sparse_bus_memory_base = io_system[io_sys].sparse_bus_mem_base;
+ io.io_base = io_system[io_sys].bus_io_base;
+
+ if (io_sys == IOSYS_JENSEN)
+ io.swiz = IOSWIZZLE_JENSEN;
+ else if (io_sys == IOSYS_TSUNAMI
+ || io_sys == IOSYS_POLARIS
+ || io_sys == IOSYS_PYXIS)
+ io.swiz = IOSWIZZLE_DENSE;
+ else
+ io.swiz = IOSWIZZLE_SPARSE;
+ io.swp = &ioswtch[io.swiz];
+
+ __set_errno (olderrno);
+ return 0;
+ }
+ }
+
+ __set_errno (ENODEV);
+ fprintf(stderr, "ioperm.init_iosys: Platform not recognized.\n"
+ "\t(May need " PATH_ALPHA_SYSTYPE " symlink?)\n");
+ return -1;
+}
+
+
+int
+_ioperm (unsigned long int from, unsigned long int num, int turn_on)
+{
+ unsigned long int addr, len, pagesize = __getpagesize();
+ int prot;
+
+ if (!io.swp && init_iosys() < 0)
+ {
+#ifdef DEBUG_IOPERM
+ fprintf(stderr, "ioperm: init_iosys() failed (%m)\n");
+#endif
+ return -1;
+ }
+
+ /* This test isn't as silly as it may look like; consider overflows! */
+ if (from >= MAX_PORT || from + num > MAX_PORT)
+ {
+ __set_errno (EINVAL);
+#ifdef DEBUG_IOPERM
+ fprintf(stderr, "ioperm: from/num out of range\n");
+#endif
+ return -1;
+ }
+
+#ifdef DEBUG_IOPERM
+ fprintf(stderr, "ioperm: turn_on %d io.base %ld\n", turn_on, io.base);
+#endif
+
+ if (turn_on)
+ {
+ if (!io.base)
+ {
+ int fd;
+
+ io.hae_cache = 0;
+ if (io.swiz != IOSWIZZLE_DENSE)
+ {
+ /* Synchronize with hw. */
+ __sethae (0);
+ }
+
+ fd = __open ("/dev/mem", O_RDWR);
+ if (fd < 0)
+ {
+#ifdef DEBUG_IOPERM
+ fprintf(stderr, "ioperm: /dev/mem open failed (%m)\n");
+#endif
+ return -1;
+ }
+
+ addr = port_to_cpu_addr (0, io.swiz, 1);
+ len = port_to_cpu_addr (MAX_PORT, io.swiz, 1) - addr;
+ io.base =
+ (unsigned long int) __mmap (0, len, PROT_NONE, MAP_SHARED,
+ fd, io.io_base);
+ __close (fd);
+#ifdef DEBUG_IOPERM
+ fprintf(stderr, "ioperm: mmap of len 0x%lx returned 0x%lx\n",
+ len, io.base);
+#endif
+ if ((long) io.base == -1)
+ return -1;
+ }
+ prot = PROT_READ | PROT_WRITE;
+ }
+ else
+ {
+ if (!io.base)
+ return 0; /* never was turned on... */
+
+ /* turnoff access to relevant pages: */
+ prot = PROT_NONE;
+ }
+ addr = port_to_cpu_addr (from, io.swiz, 1);
+ addr &= ~(pagesize - 1);
+ len = port_to_cpu_addr (from + num, io.swiz, 1) - addr;
+ return __mprotect ((void *) addr, len, prot);
+}
+
+
+int
+_iopl (int level)
+{
+ switch (level)
+ {
+ case 0:
+ return 0;
+
+ case 1: case 2: case 3:
+ return _ioperm (0, MAX_PORT, 1);
+
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+}
+
+
+void
+_sethae (unsigned long int addr)
+{
+ if (!io.swp && init_iosys () < 0)
+ return;
+
+ io.swp->sethae (addr);
+}
+
+
+void
+_outb (unsigned char b, unsigned long int port)
+{
+ if (port >= MAX_PORT)
+ return;
+
+ io.swp->outb (b, port);
+}
+
+
+void
+_outw (unsigned short b, unsigned long int port)
+{
+ if (port >= MAX_PORT)
+ return;
+
+ io.swp->outw (b, port);
+}
+
+
+void
+_outl (unsigned int b, unsigned long int port)
+{
+ if (port >= MAX_PORT)
+ return;
+
+ io.swp->outl (b, port);
+}
+
+
+unsigned int
+_inb (unsigned long int port)
+{
+ return io.swp->inb (port);
+}
+
+
+unsigned int
+_inw (unsigned long int port)
+{
+ return io.swp->inw (port);
+}
+
+
+unsigned int
+_inl (unsigned long int port)
+{
+ return io.swp->inl (port);
+}
+
+
+unsigned long int
+_bus_base(void)
+{
+ if (!io.swp && init_iosys () < 0)
+ return -1;
+ return io.bus_memory_base;
+}
+
+unsigned long int
+_bus_base_sparse(void)
+{
+ if (!io.swp && init_iosys () < 0)
+ return -1;
+ return io.sparse_bus_memory_base;
+}
+
+int
+_hae_shift(void)
+{
+ if (!io.swp && init_iosys () < 0)
+ return -1;
+ if (io.swiz == IOSWIZZLE_JENSEN)
+ return 7;
+ if (io.swiz == IOSWIZZLE_SPARSE)
+ return 5;
+ return 0;
+}
+
+weak_alias (_sethae, sethae);
+weak_alias (_ioperm, ioperm);
+weak_alias (_iopl, iopl);
+weak_alias (_inb, inb);
+weak_alias (_inw, inw);
+weak_alias (_inl, inl);
+weak_alias (_outb, outb);
+weak_alias (_outw, outw);
+weak_alias (_outl, outl);
+weak_alias (_bus_base, bus_base);
+weak_alias (_bus_base_sparse, bus_base_sparse);
+weak_alias (_hae_shift, hae_shift);
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/ipc_priv.h b/libc/sysdeps/unix/sysv/linux/alpha/ipc_priv.h
new file mode 100644
index 000000000..0328dc08e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/ipc_priv.h
@@ -0,0 +1,47 @@
+/* Copyright (C) 1995-1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/ipc.h>
+
+#define __IPC_64 0x100
+
+struct __old_ipc_perm
+{
+ __key_t __key; /* Key. */
+ unsigned int uid; /* Owner's user ID. */
+ unsigned int gid; /* Owner's group ID. */
+ unsigned int cuid; /* Creator's user ID. */
+ unsigned int cgid; /* Creator's group ID. */
+ unsigned int mode; /* Read/write permission. */
+ unsigned short int __seq; /* Sequence number. */
+};
+
+
+/* The codes for the functions to use the ipc syscall multiplexer. */
+#define IPCOP_semop 1
+#define IPCOP_semget 2
+#define IPCOP_semctl 3
+#define IPCOP_semtimedop 4
+#define IPCOP_msgsnd 11
+#define IPCOP_msgrcv 12
+#define IPCOP_msgget 13
+#define IPCOP_msgctl 14
+#define IPCOP_shmat 21
+#define IPCOP_shmdt 22
+#define IPCOP_shmget 23
+#define IPCOP_shmctl 24
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h b/libc/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h
new file mode 100644
index 000000000..4c35d969c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h
@@ -0,0 +1,15 @@
+/* This is the sigaction struction from the Linux 2.1.20 kernel. */
+
+struct old_kernel_sigaction {
+ __sighandler_t k_sa_handler;
+ unsigned long sa_mask;
+ unsigned int sa_flags;
+};
+
+/* This is the sigaction structure from the Linux 2.1.68 kernel. */
+
+struct kernel_sigaction {
+ __sighandler_t k_sa_handler;
+ unsigned int sa_flags;
+ sigset_t sa_mask;
+};
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/kernel_stat.h b/libc/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
new file mode 100644
index 000000000..a1d012ab0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
@@ -0,0 +1,88 @@
+/* Definition of `struct stat' used in the kernel. */
+struct kernel_stat
+ {
+ unsigned int st_dev;
+ unsigned int st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+ unsigned int st_uid;
+ unsigned int st_gid;
+ unsigned int st_rdev;
+ long int st_size;
+ unsigned long int st_atime;
+ unsigned long int st_mtime;
+ unsigned long int st_ctime;
+ unsigned int st_blksize;
+ int st_blocks;
+ unsigned int st_flags;
+ unsigned int st_gen;
+ };
+
+/* Definition of `struct stat64' used in the kernel. */
+struct kernel_stat64
+ {
+ unsigned long st_dev;
+ unsigned long st_ino;
+ unsigned long st_rdev;
+ long st_size;
+ unsigned long st_blocks;
+
+ unsigned int st_mode;
+ unsigned int st_uid;
+ unsigned int st_gid;
+ unsigned int st_blksize;
+ unsigned int st_nlink;
+ unsigned int __pad0;
+
+ unsigned long st_atime;
+ unsigned long st_atimensec;
+ unsigned long st_mtime;
+ unsigned long st_mtimensec;
+ unsigned long st_ctime;
+ unsigned long st_ctimensec;
+ long __unused[3];
+ };
+
+/* Definition of `struct stat' used by glibc 2.0. */
+struct glibc2_stat
+ {
+ __dev_t st_dev;
+ __ino_t st_ino;
+ __mode_t st_mode;
+ __nlink_t st_nlink;
+ __uid_t st_uid;
+ __gid_t st_gid;
+ __dev_t st_rdev;
+ __off_t st_size;
+ __time_t st_atime;
+ __time_t st_mtime;
+ __time_t st_ctime;
+ unsigned int st_blksize;
+ int st_blocks;
+ unsigned int st_flags;
+ unsigned int st_gen;
+ };
+
+/* Definition of `struct stat' used by glibc 2.1. */
+struct glibc21_stat
+ {
+ __dev_t st_dev;
+ __ino64_t st_ino;
+ __mode_t st_mode;
+ __nlink_t st_nlink;
+ __uid_t st_uid;
+ __gid_t st_gid;
+ __dev_t st_rdev;
+ __off_t st_size;
+ __time_t st_atime;
+ __time_t st_mtime;
+ __time_t st_ctime;
+ __blkcnt64_t st_blocks;
+ __blksize_t st_blksize;
+ unsigned int st_flags;
+ unsigned int st_gen;
+ int __pad3;
+ long __unused[4];
+ };
+
+#define XSTAT_IS_XSTAT64 1
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/kernel_sysinfo.h b/libc/sysdeps/unix/sysv/linux/alpha/kernel_sysinfo.h
new file mode 100644
index 000000000..a3edec226
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/kernel_sysinfo.h
@@ -0,0 +1,6 @@
+/* A copy of the couple of bits we need from <asm/sysinfo.h>. */
+
+#define GSI_IEEE_FP_CONTROL 45
+
+#define SSI_IEEE_FP_CONTROL 14
+#define SSI_IEEE_RAISE_EXCEPTION 1001
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/kernel_termios.h b/libc/sysdeps/unix/sysv/linux/alpha/kernel_termios.h
new file mode 100644
index 000000000..c38f1fac1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/kernel_termios.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _KERNEL_TERMIOS_H
+#define _KERNEL_TERMIOS_H 1
+
+/* The following corresponds to the values from the Linux 2.1.20 kernel. */
+
+/* We need the definition of tcflag_t, cc_t, and speed_t. */
+#include <termios.h>
+
+#define __KERNEL_NCCS 19
+
+struct __kernel_termios
+ {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_cc[__KERNEL_NCCS]; /* control characters */
+ cc_t c_line; /* line discipline */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+ };
+
+#define _HAVE_C_ISPEED 1
+#define _HAVE_C_OSPEED 1
+
+#endif /* kernel_termios.h */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/lxstat.c b/libc/sysdeps/unix/sysv/linux/alpha/lxstat.c
new file mode 100644
index 000000000..38fac2e2b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/lxstat.c
@@ -0,0 +1,64 @@
+/* lxstat using old-style Unix stat system call.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __lxstat64 __lxstat64_disable
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <xstatconv.h>
+
+#undef __lxstat64
+
+
+/* Get information about the file NAME in BUF. */
+int
+__lxstat (int vers, const char *name, struct stat *buf)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ int result, errno_out;
+ struct kernel_stat kbuf;
+
+ if (vers == _STAT_VER_KERNEL64 && !__libc_missing_axp_stat64)
+ {
+ result = INTERNAL_SYSCALL (lstat64, err, 2, name, buf);
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return result;
+ errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
+ if (errno_out != ENOSYS)
+ goto fail;
+ __libc_missing_axp_stat64 = 1;
+ }
+
+ result = INTERNAL_SYSCALL (lstat, err, 2, name, &kbuf);
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return __xstat_conv (vers, &kbuf, buf);
+ errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
+
+ fail:
+ __set_errno (errno_out);
+ return -1;
+}
+hidden_def (__lxstat)
+weak_alias (__lxstat, _lxstat);
+strong_alias (__lxstat, __lxstat64);
+hidden_ver (__lxstat, __lxstat64)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/makecontext.S b/libc/sysdeps/unix/sysv/linux/alpha/makecontext.S
new file mode 100644
index 000000000..223117e26
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/makecontext.S
@@ -0,0 +1,164 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <ucontext-offsets.h>
+
+
+ENTRY(__makecontext)
+ ldgp $29, 0($27)
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ /* Compute top of stack, including arguments. */
+ ldq $1, UC_STACK+SS_SP($16)
+ ldq $2, UC_STACK+SS_SIZE($16)
+ addq $1, $2, $8
+ subq $18, 6, $1
+ cmovlt $1, 0, $1
+ s8addq $1, 0, $2
+ subq $8, $2, $8
+
+ /* Copy all parameters. Switch statement header here. */
+ ldah $3, $jumptable($29) !gprelhigh
+ cmple $18, 6, $1
+ mov $18, $2
+ cmoveq $1, 7, $2
+ s4addq $2, $3, $3
+ ldl $4, $jumptable($3) !gprellow
+ addq $4, $29, $4
+ jmp $31, ($4), $args1
+
+ .section .rodata
+ .align 2
+$jumptable:
+ .gprel32 $args0
+ .gprel32 $args1
+ .gprel32 $args2
+ .gprel32 $args3
+ .gprel32 $args4
+ .gprel32 $args5
+ .gprel32 $args6
+ .gprel32 $argsN
+ .text
+
+ /* Here we process arguments 7 through N. This is a straight
+ stack-to-stack copy. */
+ .align 4
+$argsN:
+ subq $18, 6, $1
+ lda $2, 0($8)
+ lda $3, 3*8($30)
+ .align 4
+1:
+ ldq $0, 0($3)
+ subq $1, 1, $1
+ lda $3, 8($3)
+ stq $0, 0($2)
+ lda $2, 8($2)
+ bne $1, 1b
+
+ /* Here we process arguments 6 through 0. This involves
+ copying into the register save areas of the ucontext. */
+ .align 4
+$args6:
+ ldq $0, 2*8($30)
+ stq $0, UC_SIGCTX+SC_REGS+21*8($16)
+ unop
+ stq $0, UC_SIGCTX+SC_FPREGS+21*8($16)
+$args5:
+ ldq $0, 1*8($30)
+ stq $0, UC_SIGCTX+SC_REGS+20*8($16)
+ unop
+ stq $0, UC_SIGCTX+SC_FPREGS+20*8($16)
+$args4:
+ ldq $0, 0*8($30)
+ stq $0, UC_SIGCTX+SC_REGS+19*8($16)
+ unop
+ stq $0, UC_SIGCTX+SC_FPREGS+19*8($16)
+$args3:
+ unop
+ stq $21, UC_SIGCTX+SC_REGS+18*8($16)
+ unop
+ stt $f21, UC_SIGCTX+SC_FPREGS+18*8($16)
+$args2:
+ unop
+ stq $20, UC_SIGCTX+SC_REGS+17*8($16)
+ unop
+ stt $f20, UC_SIGCTX+SC_FPREGS+17*8($16)
+$args1:
+ unop
+ stq $19, UC_SIGCTX+SC_REGS+16*8($16)
+ unop
+ stt $f19, UC_SIGCTX+SC_FPREGS+16*8($16)
+$args0:
+
+ /* Set up the registers ready to invoke __startcontext.
+ We seed $27 with the target function address, and $9
+ with the link from ucp. */
+ ldah $0, __startcontext($29) !gprelhigh
+ ldq $1, UC_LINK($16)
+ lda $0, __startcontext($0) !gprellow
+ stq $17, UC_SIGCTX+SC_REGS+27*8($16)
+ stq $8, UC_SIGCTX+SC_REGS+30*8($16)
+ stq $0, UC_SIGCTX+SC_PC($16)
+ stq $1, UC_SIGCTX+SC_REGS+9*8($16)
+
+ /* No return value from makecontext. */
+ ret
+
+END(__makecontext)
+weak_alias (__makecontext, makecontext)
+
+/* This function is where a new makecontext "thread" begins life.
+ We have already set up $27 for calling the target function, and
+ we've set $9 to the UC_LINK of the parent context.
+
+ If the function returns, we either jump to the linked context
+ (if non-null) or exit. */
+
+ .align 4
+ .ent __startcontext
+__startcontext:
+ .frame $31, 0, $31, 0
+ .prologue 0
+
+ jsr $26, ($27), 0
+ ldgp $29, 0($26)
+ mov $9, $16
+ beq $9, 1f
+
+#ifdef PIC
+ bsr $26, __setcontext !samegp
+1: mov $31, $16
+ bsr $26, HIDDEN_JUMPTARGET(exit) !samegp
+#else
+ jsr $26, __setcontext
+ ldgp $29, 0($26)
+1: mov $31, $16
+ jsr $26, HIDDEN_JUMPTARGET(exit)
+#endif
+
+ halt
+
+ .end __startcontext
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/msgctl.c b/libc/sysdeps/unix/sysv/linux/alpha/msgctl.c
new file mode 100644
index 000000000..a59911fe4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/msgctl.c
@@ -0,0 +1,121 @@
+/* Copyright (C) 1995,1997,1998,2000,2003,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/msg.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+struct __old_msqid_ds
+{
+ struct __old_ipc_perm msg_perm; /* structure describing operation permission */
+ struct msg *__unbounded __msg_first; /* pointer to first message on queue */
+ struct msg *__unbounded __msg_last; /* pointer to last message on queue */
+ __time_t msg_stime; /* time of last msgsnd command */
+ __time_t msg_rtime; /* time of last msgrcv command */
+ __time_t msg_ctime; /* time of last change */
+ struct wait_queue *__unbounded __wwait; /* ??? */
+ struct wait_queue *__unbounded __rwait; /* ??? */
+ unsigned short int __msg_cbytes; /* current number of bytes on queue */
+ unsigned short int msg_qnum; /* number of messages currently on queue */
+ unsigned short int msg_qbytes; /* max number of bytes allowed on queue */
+ __ipc_pid_t msg_lspid; /* pid of last msgsnd() */
+ __ipc_pid_t msg_lrpid; /* pid of last msgrcv() */
+};
+
+/* Allows to control internal state and destruction of message queue
+ objects. */
+int __new_msgctl (int, int, struct msqid_ds *);
+
+int
+__new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
+{
+ /* This is a misnomer -- Alpha had 32-bit uids at the beginning
+ of time. However, msg_qnum and msg_qbytes changed size at
+ the same time the size of uid changed elsewhere. */
+#if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (msgctl, 3, msqid, cmd | __IPC_64, CHECK_1 (buf));
+#else
+ switch (cmd) {
+ case MSG_STAT:
+ case IPC_STAT:
+ case IPC_SET:
+ break;
+ default:
+ return INLINE_SYSCALL (msgctl, 3, msqid, cmd, CHECK_1 (buf));
+ }
+
+ {
+ int save_errno = errno, result;
+ struct __old_msqid_ds old;
+
+ /* Unfortunately there is no way how to find out for sure whether
+ we should use old or new msgctl. */
+ result = INLINE_SYSCALL (msgctl, 3, msqid, cmd | __IPC_64, CHECK_1 (buf));
+ if (result != -1 || errno != EINVAL)
+ return result;
+
+ __set_errno(save_errno);
+ if (cmd == IPC_SET)
+ {
+ old.msg_perm.uid = buf->msg_perm.uid;
+ old.msg_perm.gid = buf->msg_perm.gid;
+ old.msg_perm.mode = buf->msg_perm.mode;
+ old.msg_qbytes = buf->msg_qbytes;
+ if (old.msg_perm.uid != buf->msg_perm.uid ||
+ old.msg_perm.gid != buf->msg_perm.gid ||
+ old.msg_qbytes != buf->msg_qbytes)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ }
+ result = INLINE_SYSCALL (msgctl, 3, msqid, cmd, __ptrvalue (&old));
+ if (result != -1 && cmd != IPC_SET)
+ {
+ memset(buf, 0, sizeof(*buf));
+ buf->msg_perm.__key = old.msg_perm.__key;
+ buf->msg_perm.uid = old.msg_perm.uid;
+ buf->msg_perm.gid = old.msg_perm.gid;
+ buf->msg_perm.cuid = old.msg_perm.cuid;
+ buf->msg_perm.cgid = old.msg_perm.cgid;
+ buf->msg_perm.mode = old.msg_perm.mode;
+ buf->msg_perm.__seq = old.msg_perm.__seq;
+ buf->msg_stime = old.msg_stime;
+ buf->msg_rtime = old.msg_rtime;
+ buf->msg_ctime = old.msg_ctime;
+ buf->__msg_cbytes = old.__msg_cbytes;
+ buf->msg_qnum = old.msg_qnum;
+ buf->msg_qbytes = old.msg_qbytes;
+ buf->msg_lspid = old.msg_lspid;
+ buf->msg_lrpid = old.msg_lrpid;
+ }
+ return result;
+ }
+#endif
+}
+
+#include <shlib-compat.h>
+versioned_symbol (libc, __new_msgctl, msgctl, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/nldbl-abi.h b/libc/sysdeps/unix/sysv/linux/alpha/nldbl-abi.h
new file mode 100644
index 000000000..bd985cc59
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/nldbl-abi.h
@@ -0,0 +1,8 @@
+/* ABI version for long double switch.
+ This is used by the Versions and math_ldbl_opt.h files in
+ sysdeps/ieee754/ldbl-opt/. It gives the ABI version where
+ long double == double was replaced with proper long double
+ for libm *l functions and libc functions using long double. */
+
+#define NLDBL_VERSION GLIBC_2.4
+#define LONG_DOUBLE_COMPAT_VERSION GLIBC_2_4
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/oldglob.c b/libc/sysdeps/unix/sysv/linux/alpha/oldglob.c
new file mode 100644
index 000000000..6d9b79f2c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/oldglob.c
@@ -0,0 +1,100 @@
+/* Copyright (C) 1998, 2000, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file contains only wrappers around the real glob functions. It
+ became necessary since the glob_t structure changed. */
+#include <sys/types.h>
+#include <glob.h>
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+/* This is the old structure. The difference is that the gl_pathc and
+ gl_offs elements have type `int'. */
+typedef struct
+ {
+ int gl_pathc; /* Count of paths matched by the pattern. */
+ char **gl_pathv; /* List of matched pathnames. */
+ int gl_offs; /* Slots to reserve in `gl_pathv'. */
+ int gl_flags; /* Set to FLAGS, maybe | GLOB_MAGCHAR. */
+
+ /* If the GLOB_ALTDIRFUNC flag is set, the following functions
+ are used instead of the normal file access functions. */
+ void (*gl_closedir) (void *);
+ struct dirent *(*gl_readdir) (void *);
+ __ptr_t (*gl_opendir) (__const char *);
+ int (*gl_lstat) (__const char *, struct stat *);
+ int (*gl_stat) (__const char *, struct stat *);
+ } old_glob_t;
+
+
+int
+attribute_compat_text_section
+__old_glob (const char *pattern, int flags,
+ int (*errfunc) (const char *, int),
+ old_glob_t *pglob)
+{
+ glob_t correct;
+ int result;
+
+ /* Construct an object of correct type. */
+ correct.gl_pathc = pglob->gl_pathc;
+ correct.gl_pathv = pglob->gl_pathv;
+ correct.gl_offs = pglob->gl_offs;
+ correct.gl_flags = pglob->gl_flags;
+ correct.gl_closedir = pglob->gl_closedir;
+ correct.gl_readdir = pglob->gl_readdir;
+ correct.gl_opendir = pglob->gl_opendir;
+ correct.gl_lstat = pglob->gl_lstat;
+ correct.gl_stat = pglob->gl_stat;
+
+ result = glob (pattern, flags, errfunc, &correct);
+
+ /* And convert it back. */
+ pglob->gl_pathc = correct.gl_pathc;
+ pglob->gl_pathv = correct.gl_pathv;
+ pglob->gl_offs = correct.gl_offs;
+ pglob->gl_flags = correct.gl_flags;
+ pglob->gl_closedir = correct.gl_closedir;
+ pglob->gl_readdir = correct.gl_readdir;
+ pglob->gl_opendir = correct.gl_opendir;
+ pglob->gl_lstat = correct.gl_lstat;
+ pglob->gl_stat = correct.gl_stat;
+
+ return result;
+}
+compat_symbol (libc, __old_glob, glob, GLIBC_2_0);
+
+
+/* Free storage allocated in PGLOB by a previous `glob' call. */
+void
+attribute_compat_text_section
+__old_globfree (old_glob_t *pglob)
+{
+ glob_t correct;
+
+ /* We only need these two symbols. */
+ correct.gl_pathc = pglob->gl_pathc;
+ correct.gl_pathv = pglob->gl_pathv;
+ correct.gl_offs = pglob->gl_offs;
+
+ globfree (&correct);
+}
+compat_symbol (libc, __old_globfree, globfree, GLIBC_2_0);
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/pipe.S b/libc/sysdeps/unix/sysv/linux/alpha/pipe.S
new file mode 100644
index 000000000..1e7ec1c19
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/pipe.S
@@ -0,0 +1 @@
+#include <sysdeps/unix/alpha/pipe.S>
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/register-dump.h b/libc/sysdeps/unix/sysv/linux/alpha/register-dump.h
new file mode 100644
index 000000000..77f962952
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/register-dump.h
@@ -0,0 +1,157 @@
+/* Dump registers.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <string.h>
+
+/* We will print the register dump in this format:
+
+ V0: XXXXXXXXXXXXXXXX T0: XXXXXXXXXXXXXXXX T1: XXXXXXXXXXXXXXXX
+ T2: XXXXXXXXXXXXXXXX T3: XXXXXXXXXXXXXXXX T4: XXXXXXXXXXXXXXXX
+ T5: XXXXXXXXXXXXXXXX T6: XXXXXXXXXXXXXXXX T7: XXXXXXXXXXXXXXXX
+ S0: XXXXXXXXXXXXXXXX S1: XXXXXXXXXXXXXXXX S2: XXXXXXXXXXXXXXXX
+ S3: XXXXXXXXXXXXXXXX S4: XXXXXXXXXXXXXXXX S5: XXXXXXXXXXXXXXXX
+ S6: XXXXXXXXXXXXXXXX A0: XXXXXXXXXXXXXXXX A1: XXXXXXXXXXXXXXXX
+ A2: XXXXXXXXXXXXXXXX A3: XXXXXXXXXXXXXXXX A4: XXXXXXXXXXXXXXXX
+ A5: XXXXXXXXXXXXXXXX T8: XXXXXXXXXXXXXXXX T9: XXXXXXXXXXXXXXXX
+ T10: XXXXXXXXXXXXXXXX T11: XXXXXXXXXXXXXXXX RA: XXXXXXXXXXXXXXXX
+ T12: XXXXXXXXXXXXXXXX AT: XXXXXXXXXXXXXXXX GP: XXXXXXXXXXXXXXXX
+ SP: XXXXXXXXXXXXXXXX PC: XXXXXXXXXXXXXXXX
+
+ FP0: XXXXXXXXXXXXXXXX FP1: XXXXXXXXXXXXXXXX FP2: XXXXXXXXXXXXXXXX
+ FP3: XXXXXXXXXXXXXXXX FP4: XXXXXXXXXXXXXXXX FP5: XXXXXXXXXXXXXXXX
+ FP6: XXXXXXXXXXXXXXXX FP7: XXXXXXXXXXXXXXXX FP8: XXXXXXXXXXXXXXXX
+ FP9: XXXXXXXXXXXXXXXX FP10: XXXXXXXXXXXXXXXX FP11: XXXXXXXXXXXXXXXX
+ FP12: XXXXXXXXXXXXXXXX FP13: XXXXXXXXXXXXXXXX FP14: XXXXXXXXXXXXXXXX
+ FP15: XXXXXXXXXXXXXXXX FP16: XXXXXXXXXXXXXXXX FP17: XXXXXXXXXXXXXXXX
+ FP18: XXXXXXXXXXXXXXXX FP19: XXXXXXXXXXXXXXXX FP20: XXXXXXXXXXXXXXXX
+ FP21: XXXXXXXXXXXXXXXX FP22: XXXXXXXXXXXXXXXX FP23: XXXXXXXXXXXXXXXX
+ FP24: XXXXXXXXXXXXXXXX FP25: XXXXXXXXXXXXXXXX FP26: XXXXXXXXXXXXXXXX
+ FP27: XXXXXXXXXXXXXXXX FP28: XXXXXXXXXXXXXXXX FP29: XXXXXXXXXXXXXXXX
+ FP30: XXXXXXXXXXXXXXXX FPCR: XXXXXXXXXXXXXXXX
+
+ TA0: XXXXXXXXXXXXXXXX TA1: XXXXXXXXXXXXXXXX TA2: XXXXXXXXXXXXXXXX
+*/
+
+#define NREGS (32+32+3)
+
+static const char __attribute__((aligned(8))) regnames[NREGS][8] =
+{
+ " V0: ", " T0: ", " T1: ",
+ " T2: ", " T3: ", " T4: ",
+ " T5: ", " T6: ", " T7: ",
+ " S0: ", " S1: ", " S2: ",
+ " S3: ", " S4: ", " S5: ",
+ " S6: ", " A0: ", " A1: ",
+ " A2: ", " A3: ", " A4: ",
+ " A5: ", " T8: ", " T9: ",
+ " T10: ", " T11: ", " RA: ",
+ " T12: ", " AT: ", " GP: ",
+ " SP: ", " PC: ",
+
+ " FP0: ", " FP1: ", " FP2: ",
+ " FP3: ", " FP4: ", " FP5: ",
+ " FP6: ", " FP7: ", " FP8: ",
+ " FP9: ", " FP10: ", " FP11: ",
+ " FP12: ", " FP13: ", " FP14: ",
+ " FP15: ", " FP16: ", " FP17: ",
+ " FP18: ", " FP19: ", " FP20: ",
+ " FP21: ", " FP22: ", " FP23: ",
+ " FP24: ", " FP25: ", " FP26: ",
+ " FP27: ", " FP28: ", " FP29: ",
+ " FP30: ", " FPCR: ",
+
+ " TA0: ", " TA1: ", " TA2: "
+};
+
+#define O(FIELD, LF) offsetof(struct sigcontext, FIELD) + LF
+
+static const int offsets[NREGS] =
+{
+ O(sc_regs[0], 0), O(sc_regs[1], 0), O(sc_regs[2], 1),
+ O(sc_regs[3], 0), O(sc_regs[4], 0), O(sc_regs[5], 1),
+ O(sc_regs[6], 0), O(sc_regs[7], 0), O(sc_regs[8], 1),
+ O(sc_regs[9], 0), O(sc_regs[10], 0), O(sc_regs[11], 1),
+ O(sc_regs[12], 0), O(sc_regs[13], 0), O(sc_regs[14], 1),
+ O(sc_regs[15], 0), O(sc_regs[16], 0), O(sc_regs[17], 1),
+ O(sc_regs[18], 0), O(sc_regs[19], 0), O(sc_regs[20], 1),
+ O(sc_regs[21], 0), O(sc_regs[22], 0), O(sc_regs[23], 1),
+ O(sc_regs[24], 0), O(sc_regs[25], 0), O(sc_regs[26], 1),
+ O(sc_regs[27], 0), O(sc_regs[28], 0), O(sc_regs[29], 1),
+ O(sc_regs[30], 0), O(sc_pc, 2),
+
+ O(sc_fpregs[0], 0), O(sc_fpregs[1], 0), O(sc_fpregs[2], 1),
+ O(sc_fpregs[3], 0), O(sc_fpregs[4], 0), O(sc_fpregs[5], 1),
+ O(sc_fpregs[6], 0), O(sc_fpregs[7], 0), O(sc_fpregs[8], 1),
+ O(sc_fpregs[9], 0), O(sc_fpregs[10], 0), O(sc_fpregs[11], 1),
+ O(sc_fpregs[12], 0), O(sc_fpregs[13], 0), O(sc_fpregs[14], 1),
+ O(sc_fpregs[15], 0), O(sc_fpregs[16], 0), O(sc_fpregs[17], 1),
+ O(sc_fpregs[18], 0), O(sc_fpregs[19], 0), O(sc_fpregs[20], 1),
+ O(sc_fpregs[21], 0), O(sc_fpregs[22], 0), O(sc_fpregs[23], 1),
+ O(sc_fpregs[24], 0), O(sc_fpregs[25], 0), O(sc_fpregs[26], 1),
+ O(sc_fpregs[27], 0), O(sc_fpregs[28], 0), O(sc_fpregs[29], 1),
+ O(sc_fpregs[30], 0), O(sc_fpcr, 2),
+
+ O(sc_traparg_a0, 0), O(sc_traparg_a1, 0), O(sc_traparg_a2, 1)
+};
+
+#undef O
+
+static void
+register_dump (int fd, struct sigcontext *ctx)
+{
+ char buf[NREGS*(8+16) + 25 + 80];
+ char *p = buf;
+ size_t i;
+
+ p = stpcpy (p, "Register dump:\n\n");
+
+ for (i = 0; i < NREGS; ++i)
+ {
+ int this_offset, this_lf;
+ unsigned long val;
+ signed long j;
+
+ this_offset = offsets[i];
+ this_lf = this_offset & 7;
+
+ val = *(unsigned long *)(((size_t)ctx + this_offset) & -8);
+
+ memcpy (p, regnames[i], 8);
+ p += 8;
+
+ for (j = 60; j >= 0; j -= 4)
+ {
+ unsigned long x = (val >> j) & 15;
+ x += x < 10 ? '0' : 'a' - 10;
+ *p++ = x;
+ }
+
+ if (this_lf > 0)
+ {
+ if (this_lf > 1)
+ *p++ = '\n';
+ *p++ = '\n';
+ }
+ }
+
+ write (fd, buf, p - buf);
+}
+
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S b/libc/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S
new file mode 100644
index 000000000..e27949fef
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S
@@ -0,0 +1,120 @@
+/* Copyright (C) 1998, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <rth@cygnus.com>, 1998
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* On Alpha we desparately want to avoid having to issue an imb. Ordinarily
+ the kernel would have to issue one after setting up the signal return
+ stack, but the Linux rt_sigaction syscall is prepared to accept a pointer
+ to the sigreturn syscall, instead of inlining it on the stack.
+
+ This just about halves signal delivery time. */
+
+ .text
+
+ENTRY(__syscall_rt_sigaction)
+ .frame sp,0,ra,0
+ ldgp gp,0(pv)
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ beq a1, 0f
+ ldl t0, 8(a1) # sa_flags
+
+ /* The unwinder will subtract one from the return address when
+ attempting to find the call instruction that led us here.
+ Since we didn't get here via a normal call, if we do nothing
+ we would pick up the wrong symbol and the wrong FDE. Account
+ for this by adding a nop to the start of the function and
+ then skipping it here by adding 4. */
+ ldah a4, __syscall_sigreturn+4(gp) !gprelhigh
+ ldah t1, __syscall_rt_sigreturn+4(gp) !gprelhigh
+ lda a4, __syscall_sigreturn+4(a4) !gprellow
+ lda t1, __syscall_rt_sigreturn+4(t1) !gprellow
+ and t0, 0x40, t0 # SA_SIGINFO
+ cmovne t0, t1, a4
+
+0: ldi v0, __NR_rt_sigaction
+ callsys
+ bne a3, SYSCALL_ERROR_LABEL
+ ret
+
+PSEUDO_END(__syscall_rt_sigaction)
+
+/* To enable unwinding through the signal frame without special hackery
+ elsewhere, describe the entire struct sigcontext with unwind info.
+
+ In order to minimize the size of the encoding, we set the CFA to the
+ end of the sigcontext, which makes all of the registers have small
+ negative offsets from that. */
+
+ .macro SIGCONTEXT_REGS_I base, from=0
+ cfi_offset (\from, \base + (4 + \from) * 8)
+ .if 30-\from
+ SIGCONTEXT_REGS_I \base, "(\from+1)"
+ .endif
+ .endm
+
+ .macro SIGCONTEXT_REGS_F base, from=32
+ cfi_offset (\from, \base + (4 + 1 + \from) * 8)
+ .if 62-\from
+ SIGCONTEXT_REGS_F \base, "(\from+1)"
+ .endif
+ .endm
+
+ .macro SIGCONTEXT_REGS base
+ SIGCONTEXT_REGS_I \base
+ SIGCONTEXT_REGS_F \base
+ cfi_offset (63, \base + (4 + 32 + 1 + 32) * 8)
+ cfi_offset (64, \base + 2 * 8)
+ .endm
+
+ .align 4
+ nop
+ nop
+ nop
+
+ cfi_startproc
+ cfi_return_column (64)
+ SIGCONTEXT_REGS -648
+
+ cfi_def_cfa_offset (648)
+__syscall_sigreturn:
+ nop
+ mov sp, a0
+ ldi v0, __NR_sigreturn
+ callsys
+ .size __syscall_sigreturn, .-__syscall_sigreturn
+ .type __syscall_sigreturn, @function
+
+ cfi_def_cfa_offset (176 + 648)
+__syscall_rt_sigreturn:
+ nop
+ mov sp,a0
+ ldi v0,__NR_rt_sigreturn
+ callsys
+ .size __syscall_rt_sigreturn, .-__syscall_rt_sigreturn
+ .type __syscall_rt_sigreturn, @function
+
+ cfi_endproc
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/select.S b/libc/sysdeps/unix/sysv/linux/alpha/select.S
new file mode 100644
index 000000000..35a81e949
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/select.S
@@ -0,0 +1,241 @@
+/* Copyright (C) 1998,2002,2003,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep-cancel.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+.text
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+#define SELECT __select_tv64
+#else
+#define SELECT __select
+#endif
+
+#if defined __ASSUME_TIMEVAL64
+PSEUDO(SELECT, select, 5)
+ ret
+PSEUDO_END(SELECT)
+#else
+/* The problem here is that initially we made struct timeval compatible with
+ OSF/1, using int32. But we defined time_t with uint64, and later found
+ that POSIX requires tv_sec to be time_t.
+
+ So now we have to do compatibility stuff. */
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. */
+.comm __libc_missing_axp_tv64, 4
+
+LEAF(SELECT, 64)
+ ldgp gp, 0(pv)
+ subq sp, 64, sp
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ stq ra, 40(sp)
+ .mask 0x4000000, 40-64
+ .prologue 1
+
+#ifdef CENABLE
+ SINGLE_THREAD_P (t1)
+#else
+ ldl t0, __libc_missing_axp_tv64
+#endif
+
+ /* Save timeout early, since we'll need to recover this after
+ the system call. */
+ stq a4, 48(sp)
+
+#ifdef CENABLE
+ bne t1, $do_cancel
+#endif
+
+ bne t0, $do32
+
+ /* Save arguments in case we do need to fall back. */
+ stq a0, 8(sp)
+ stq a1, 16(sp)
+ stq a2, 24(sp)
+ stq a3, 32(sp)
+
+ ldi v0, SYS_ify(select)
+ callsys
+ bne a3, $err64
+
+ /* Everything ok. */
+ addq sp, 64, sp
+ ret
+
+ /* If we didn't get ENOSYS, it is a real error. */
+ .align 3
+$err64: cmpeq v0, ENOSYS, t0
+ beq t0, $error
+ stl t0, __libc_missing_axp_tv64
+
+ /* Recover the saved arguments. */
+ ldq a4, 48(sp)
+ ldq a3, 32(sp)
+ ldq a2, 24(sp)
+ ldq a1, 16(sp)
+ ldq a0, 8(sp)
+
+ .align 3
+$do32:
+ /* If the timeout argument is present bounce to the smaller fmt. */
+ beq a4, 1f
+ ldq t0, 0(a4)
+ ldq t1, 8(a4)
+ stl t0, 0(sp)
+ stl t1, 4(sp)
+ mov sp, a4
+
+1: ldi v0, SYS_ify(osf_select)
+ callsys
+ bne a3, $error
+
+ /* ... and bounce the remaining timeout back. */
+ ldq a4, 48(sp)
+ beq a4, 2f
+ ldl t0, 0(sp)
+ ldl t1, 4(sp)
+ stq t0, 0(a4)
+ stq t1, 8(a4)
+
+2: addq sp, 64, sp
+ ret
+
+#ifdef CENABLE
+ .align 3
+$do_cancel:
+ /* Save arguments. */
+ stq a0, 8(sp)
+ stq a1, 16(sp)
+ stq a2, 24(sp)
+ stq a3, 32(sp)
+
+ CENABLE
+ mov v0, ra
+
+ ldl t0, __libc_missing_axp_tv64
+ bne t0, $do_cancel32
+
+ /* Recover the saved arguments. */
+ ldq a4, 48(sp)
+ ldq a3, 32(sp)
+ ldq a2, 24(sp)
+ ldq a1, 16(sp)
+ ldq a0, 8(sp)
+
+ ldi v0, SYS_ify(select)
+ callsys
+
+ mov ra, a0
+ bne a3, $cancel_err64
+
+ stq v0, 8(sp)
+ CDISABLE
+ ldq v0, 8(sp)
+ ldq ra, 40(sp)
+
+ /* Everything ok. */
+ addq sp, 64, sp
+ ret
+
+ /* If we didn't get ENOSYS, it is a real error. */
+ .align 3
+$cancel_err64:
+ cmpeq v0, ENOSYS, t0
+ beq t0, $cancel_error
+ stl t0, __libc_missing_axp_tv64
+
+ /* Recover the saved arguments. */
+ .align 3
+$do_cancel32:
+ ldq a4, 48(sp)
+ ldq a3, 32(sp)
+ ldq a2, 24(sp)
+ ldq a1, 16(sp)
+ ldq a0, 8(sp)
+
+ /* If the timeout argument is present bounce to the smaller fmt. */
+ beq a4, 1f
+ ldq t0, 0(a4)
+ ldq t1, 8(a4)
+ stl t0, 0(sp)
+ stl t1, 4(sp)
+ mov sp, a4
+
+1: ldi v0, SYS_ify(osf_select)
+ callsys
+
+ mov ra, a0
+ bne a3, $cancel_error
+
+ /* ... and bounce the remaining timeout back. */
+ ldq a4, 48(sp)
+ beq a4, 2f
+ ldl t0, 0(sp)
+ ldl t1, 4(sp)
+ stq t0, 0(a4)
+ stq t1, 8(a4)
+
+2: stq v0, 8(sp)
+ CDISABLE
+ ldq v0, 8(sp)
+ ldq ra, 40(sp)
+
+ addq sp, 64, sp
+ ret
+
+ .align 3
+$cancel_error:
+ stq v0, 8(sp)
+ CDISABLE
+ ldq v0, 8(sp)
+ ldq ra, 40(sp)
+#endif
+
+ .align 3
+$error:
+ addq sp, 64, sp
+ SYSCALL_ERROR_HANDLER
+
+END(SELECT)
+#endif /* __ASSUME_TIMEVAL64 */
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+default_symbol_version (__select_tv64, __select, GLIBC_2.1)
+
+/* It seems to me to be a misfeature of the assembler that we can only
+ have one version-alias per symbol. So create an alias ourselves.
+ The 'p' is for 'public'. *Shrug* */
+strong_alias (__select_tv64, __select_tv64p)
+default_symbol_version (__select_tv64p, select, GLIBC_2.1)
+libc_hidden_ver (__select_tv64, __select)
+strong_alias (__select_tv64, __libc_select)
+#else
+strong_alias (__select, __libc_select)
+weak_alias (__select, select)
+libc_hidden_def (__select)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/semctl.c b/libc/sysdeps/unix/sysv/linux/alpha/semctl.c
new file mode 100644
index 000000000..9957f983b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/semctl.c
@@ -0,0 +1,136 @@
+/* Copyright (C) 1995,1997,1998,2000,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/sem.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+struct __old_semid_ds
+{
+ struct __old_ipc_perm sem_perm; /* operation permission struct */
+ __time_t sem_otime; /* last semop() time */
+ __time_t sem_ctime; /* last time changed by semctl() */
+ struct sem *__sembase; /* ptr to first semaphore in array */
+ struct sem_queue *__sem_pending; /* pending operations */
+ struct sem_queue *__sem_pending_last; /* last pending operation */
+ struct sem_undo *__undo; /* ondo requests on this array */
+ unsigned short int sem_nsems; /* number of semaphores in set */
+};
+
+/* Define a `union semun' suitable for Linux here. */
+union semun
+{
+ int val; /* value for SETVAL */
+ struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
+ unsigned short int *array; /* array for GETALL & SETALL */
+ struct seminfo *__buf; /* buffer for IPC_INFO */
+};
+
+#include <bp-checks.h>
+#include <bp-semctl.h> /* definition of CHECK_SEMCTL needs union semum */
+
+/* Return identifier for array of NSEMS semaphores associated with
+ KEY. */
+int __new_semctl (int semid, int semnum, int cmd, ...);
+
+int
+__new_semctl (int semid, int semnum, int cmd, ...)
+{
+ union semun arg;
+ va_list ap;
+
+ va_start (ap, cmd);
+
+ /* Get the argument. */
+ arg = va_arg (ap, union semun);
+
+ va_end (ap);
+
+#if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (semctl, 4, semid, semnum, cmd | __IPC_64,
+ CHECK_SEMCTL (&arg, semid, cmd | __IPC_64)->array);
+#else
+ switch (cmd) {
+ case SEM_STAT:
+ case IPC_STAT:
+ case IPC_SET:
+ break;
+ default:
+ return INLINE_SYSCALL (semctl, 4, semid, semnum, cmd,
+ CHECK_SEMCTL (&arg, semid, cmd)->array);
+ }
+
+ {
+ int save_errno = errno, result;
+ struct __old_semid_ds old;
+ struct semid_ds *buf;
+
+ /* Unfortunately there is no way how to find out for sure whether
+ we should use old or new semctl. */
+ result = INLINE_SYSCALL (semctl, 4, semid, semnum, cmd | __IPC_64,
+ CHECK_SEMCTL (&arg, semid, cmd | __IPC_64)->array);
+ if (result != -1 || errno != EINVAL)
+ return result;
+
+ __set_errno(save_errno);
+ buf = arg.buf;
+ arg.buf = (void *)&old;
+ if (cmd == IPC_SET)
+ {
+ old.sem_perm.uid = buf->sem_perm.uid;
+ old.sem_perm.gid = buf->sem_perm.gid;
+ old.sem_perm.mode = buf->sem_perm.mode;
+ if (old.sem_perm.uid != buf->sem_perm.uid ||
+ old.sem_perm.gid != buf->sem_perm.gid)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ }
+ result = INLINE_SYSCALL (semctl, 4, semid, semnum, cmd,
+ CHECK_SEMCTL (&arg, semid, cmd)->array);
+ if (result != -1 && cmd != IPC_SET)
+ {
+ memset(buf, 0, sizeof(*buf));
+ buf->sem_perm.__key = old.sem_perm.__key;
+ buf->sem_perm.uid = old.sem_perm.uid;
+ buf->sem_perm.gid = old.sem_perm.gid;
+ buf->sem_perm.cuid = old.sem_perm.cuid;
+ buf->sem_perm.cgid = old.sem_perm.cgid;
+ buf->sem_perm.mode = old.sem_perm.mode;
+ buf->sem_perm.__seq = old.sem_perm.__seq;
+ buf->sem_otime = old.sem_otime;
+ buf->sem_ctime = old.sem_ctime;
+ buf->sem_nsems = old.sem_nsems;
+ }
+ return result;
+ }
+#endif
+}
+
+#include <shlib-compat.h>
+versioned_symbol (libc, __new_semctl, semctl, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/setcontext.S b/libc/sysdeps/unix/sysv/linux/alpha/setcontext.S
new file mode 100644
index 000000000..27abfd0c1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/setcontext.S
@@ -0,0 +1,35 @@
+/* Install given context.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <ucontext-offsets.h>
+
+
+/* In case the user fiddled it, copy the "official" signal mask
+ from the ucontext_t into the sigcontext structure. */
+#undef PSEUDO_PREPARE_ARGS
+#define PSEUDO_PREPARE_ARGS \
+ ldq $0, UC_SIGMASK($16); \
+ stq $0, UC_SIGCTX+SC_MASK($16); \
+ lda $16, UC_SIGCTX($16);
+
+PSEUDO(__setcontext, sigreturn, 1)
+ ret
+PSEUDO_END(__setcontext)
+weak_alias (__setcontext, setcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/setfpucw.c b/libc/sysdeps/unix/sysv/linux/alpha/setfpucw.c
new file mode 100644
index 000000000..a7e3a5581
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/setfpucw.c
@@ -0,0 +1,80 @@
+/* Set FP exception mask and rounding mode.
+ Copyright (C) 1996, 1997, 1998, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fpu_control.h>
+#include <asm/fpu.h>
+
+extern void __ieee_set_fp_control (unsigned long);
+libc_hidden_proto(__ieee_set_fp_control)
+
+extern unsigned long __ieee_get_fp_control (void);
+libc_hidden_proto(__ieee_get_fp_control)
+
+static inline unsigned long
+rdfpcr (void)
+{
+ unsigned long fpcr;
+ asm ("excb; mf_fpcr %0" : "=f"(fpcr));
+ return fpcr;
+}
+
+
+static inline void
+wrfpcr (unsigned long fpcr)
+{
+ asm volatile ("mt_fpcr %0; excb" : : "f"(fpcr));
+}
+
+
+void
+__setfpucw (fpu_control_t fpu_control)
+{
+ unsigned long fpcr = 0, fpcw = 0;
+
+ if (!fpu_control)
+ fpu_control = _FPU_DEFAULT;
+
+ /* first, set dynamic rounding mode: */
+
+ fpcr = rdfpcr();
+ fpcr &= ~FPCR_DYN_MASK;
+ switch (fpu_control & 0xc00)
+ {
+ case _FPU_RC_NEAREST: fpcr |= FPCR_DYN_NORMAL; break;
+ case _FPU_RC_DOWN: fpcr |= FPCR_DYN_MINUS; break;
+ case _FPU_RC_UP: fpcr |= FPCR_DYN_PLUS; break;
+ case _FPU_RC_ZERO: fpcr |= FPCR_DYN_CHOPPED; break;
+ }
+ wrfpcr(fpcr);
+
+ /* now tell kernel about traps that we like to hear about: */
+
+ fpcw = __ieee_get_fp_control();
+ fpcw &= ~IEEE_TRAP_ENABLE_MASK;
+
+ if (!(fpu_control & _FPU_MASK_IM)) fpcw |= IEEE_TRAP_ENABLE_INV;
+ if (!(fpu_control & _FPU_MASK_DM)) fpcw |= IEEE_TRAP_ENABLE_UNF;
+ if (!(fpu_control & _FPU_MASK_ZM)) fpcw |= IEEE_TRAP_ENABLE_DZE;
+ if (!(fpu_control & _FPU_MASK_OM)) fpcw |= IEEE_TRAP_ENABLE_OVF;
+ if (!(fpu_control & _FPU_MASK_PM)) fpcw |= IEEE_TRAP_ENABLE_INE;
+
+ __fpu_control = fpu_control; /* update global copy */
+
+ __ieee_set_fp_control(fpcw);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/setitimer.S b/libc/sysdeps/unix/sysv/linux/alpha/setitimer.S
new file mode 100644
index 000000000..59caeac68
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/setitimer.S
@@ -0,0 +1,137 @@
+/* Copyright (C) 1998, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+.text
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+#define SETITIMER __setitimer_tv64
+#else
+#define SETITIMER __setitimer
+#endif
+
+#if defined __ASSUME_TIMEVAL64
+PSEUDO(SETITIMER, setitimer, 3)
+ ret
+PSEUDO_END(SETITIMER)
+#else
+/* The problem here is that initially we made struct timeval compatible with
+ OSF/1, using int32. But we defined time_t with uint64, and later found
+ that POSIX requires tv_sec to be time_t.
+
+ So now we have to do compatibility stuff. */
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. */
+.comm __libc_missing_axp_tv64, 4
+
+LEAF(SETITIMER, 48)
+ ldgp gp, 0(pv)
+ subq sp, 48, sp
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ ldl t0, __libc_missing_axp_tv64
+
+ /* Save arguments in case we do need to fall back. */
+ stq a0, 0(sp)
+ stq a1, 8(sp)
+ stq a2, 16(sp)
+
+ bne t0, $do32
+
+ ldi v0, SYS_ify(setitimer)
+ callsys
+ bne a3, $err64
+
+ /* Everything ok. */
+ addq sp, 48, sp
+ ret
+
+ /* If we didn't get ENOSYS, it is a real error. */
+ .align 3
+$err64: cmpeq v0, ENOSYS, t0
+ beq t0, $error
+ stl t0, __libc_missing_axp_tv64
+
+ /* Recover the saved arguments. */
+ ldq a2, 16(sp)
+ ldq a1, 8(sp)
+ ldq a0, 0(sp)
+
+ .align 3
+$do32:
+ /* Conditionally bounce new value down. */
+ beq a1, 1f
+ ldq t0, 0(a1)
+ ldq t1, 8(a1)
+ ldq t2, 16(a1)
+ ldq t3, 24(a1)
+ stl t0, 32(sp)
+ stl t1, 36(sp)
+ stl t2, 40(sp)
+ stl t3, 44(sp)
+ addq sp, 32, a1
+
+1: ldi v0, SYS_ify(osf_setitimer)
+ callsys
+ bne a3, $error
+
+ /* Conditionaly bounce old value up. */
+ ldq a2, 16(sp)
+ bne a2, 2f
+ ldl t0, 0(a2)
+ ldl t1, 4(a2)
+ ldl t2, 8(a2)
+ ldl t3, 12(a2)
+ stq t0, 0(a2)
+ stq t1, 8(a2)
+ stq t2, 48(a2)
+ stq t3, 24(a2)
+
+2: addq sp, 48, sp
+ ret
+
+ .align 3
+$error:
+ addq sp, 48, sp
+ SYSCALL_ERROR_HANDLER
+
+END(SETITIMER)
+#endif /* __ASSUME_TIMEVAL64 */
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+default_symbol_version (__setitimer_tv64, __setitimer, GLIBC_2.1)
+
+/* It seems to me to be a misfeature of the assembler that we can only
+ have one version-alias per symbol. So create an alias ourselves.
+ The 'p' is for 'public'. *Shrug* */
+strong_alias (__setitimer_tv64, __setitimer_tv64p)
+default_symbol_version (__setitimer_tv64p, setitimer, GLIBC_2.1)
+#else
+weak_alias (__setitimer, setitimer)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/setregid.c b/libc/sysdeps/unix/sysv/linux/alpha/setregid.c
new file mode 100644
index 000000000..0973fe4ac
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/setregid.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+
+
+int
+__setregid (gid_t rgid, gid_t egid)
+{
+ return INLINE_SETXID_SYSCALL (setregid, 2, (int) rgid, (int) egid);
+}
+#ifndef __setregid
+weak_alias (__setregid, setregid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/setresgid.c b/libc/sysdeps/unix/sysv/linux/alpha/setresgid.c
new file mode 100644
index 000000000..50e29e3c7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/setresgid.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+
+
+int
+__setresgid (gid_t rgid, gid_t egid, gid_t sgid)
+{
+ return INLINE_SETXID_SYSCALL (setresgid, 3, (int) rgid,
+ (int) egid, (int) sgid);
+}
+libc_hidden_def (__setresgid)
+#ifndef __setresgid
+weak_alias (__setresgid, setresgid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/setresuid.c b/libc/sysdeps/unix/sysv/linux/alpha/setresuid.c
new file mode 100644
index 000000000..e76413bf6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/setresuid.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+
+
+int
+__setresuid (uid_t ruid, uid_t euid, uid_t suid)
+{
+ return INLINE_SETXID_SYSCALL (setresuid, 3, (int) ruid,
+ (int) euid, (int) suid);
+}
+libc_hidden_def (__setresuid)
+#ifndef __setresuid
+weak_alias (__setresuid, setresuid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/setreuid.c b/libc/sysdeps/unix/sysv/linux/alpha/setreuid.c
new file mode 100644
index 000000000..a23a34792
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/setreuid.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+
+
+int
+__setreuid (uid_t ruid, uid_t euid)
+{
+ return INLINE_SETXID_SYSCALL (setreuid, 2, (int) ruid, (int) euid);
+}
+#ifndef __setreuid
+weak_alias (__setreuid, setreuid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/settimeofday.S b/libc/sysdeps/unix/sysv/linux/alpha/settimeofday.S
new file mode 100644
index 000000000..e39eadc20
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/settimeofday.S
@@ -0,0 +1,118 @@
+/* Copyright (C) 1998, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+.text
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+#define SETTIMEOFDAY __settimeofday_tv64
+#else
+#define SETTIMEOFDAY __settimeofday
+#endif
+
+#if defined __ASSUME_TIMEVAL64
+PSEUDO(SETTIMEOFDAY, settimeofday, 2)
+ ret
+PSEUDO_END(SETTIMEOFDAY)
+#else
+/* The problem here is that initially we made struct timeval compatible with
+ OSF/1, using int32. But we defined time_t with uint64, and later found
+ that POSIX requires tv_sec to be time_t.
+
+ So now we have to do compatibility stuff. */
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. */
+.comm __libc_missing_axp_tv64, 4
+
+LEAF(SETTIMEOFDAY, 16)
+ ldgp gp, 0(pv)
+ subq sp, 16, sp
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ ldl t0, __libc_missing_axp_tv64
+ bne t0, $do32
+
+ /* Save arguments in case we do need to fall back. */
+ stq a0, 0(sp)
+ stq a1, 8(sp)
+
+ ldi v0, SYS_ify(settimeofday)
+ callsys
+ bne a3, $err64
+
+ /* Everything ok. */
+ addq sp, 16, sp
+ ret
+
+ /* If we didn't get ENOSYS, it is a real error. */
+ .align 3
+$err64: cmpeq v0, ENOSYS, t0
+ beq t0, $error
+ stl t0, __libc_missing_axp_tv64
+
+ /* Recover the saved arguments. */
+ ldq a1, 8(sp)
+ ldq a0, 0(sp)
+
+ .align 3
+$do32:
+ /* Conditionally bounce the timeval down. */
+ beq a0, 1f
+ ldq t0, 0(a0)
+ ldq t1, 8(a0)
+ stl t0, 0(sp)
+ stl t1, 4(sp)
+ mov sp, a0
+
+1: ldi v0, SYS_ify(osf_settimeofday)
+ callsys
+ bne a3, $error
+
+ addq sp, 16, sp
+ ret
+
+ .align 3
+$error:
+ addq sp, 16, sp
+ SYSCALL_ERROR_HANDLER
+
+END(SETTIMEOFDAY)
+#endif /* __ASSUME_TIMEVAL64 */
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+default_symbol_version (__settimeofday_tv64, __settimeofday, GLIBC_2.1)
+
+/* It seems to me to be a misfeature of the assembler that we can only
+ have one version-alias per symbol. So create an alias ourselves.
+ The 'p' is for 'public'. *Shrug* */
+strong_alias (__settimeofday_tv64, __settimeofday_tv64p)
+default_symbol_version (__settimeofday_tv64p, settimeofday, GLIBC_2.1)
+#else
+weak_alias (__settimeofday, settimeofday)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/shmctl.c b/libc/sysdeps/unix/sysv/linux/alpha/shmctl.c
new file mode 100644
index 000000000..e63211fa0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/shmctl.c
@@ -0,0 +1,135 @@
+/* Copyright (C) 1995,1997,1998,2000,2003,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/shm.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <bits/wordsize.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+struct __old_shmid_ds
+{
+ struct __old_ipc_perm shm_perm; /* operation permission struct */
+ int shm_segsz; /* size of segment in bytes */
+ __time_t shm_atime; /* time of last shmat() */
+ __time_t shm_dtime; /* time of last shmdt() */
+ __time_t shm_ctime; /* time of last change by shmctl() */
+ __ipc_pid_t shm_cpid; /* pid of creator */
+ __ipc_pid_t shm_lpid; /* pid of last shmop */
+ unsigned short int shm_nattch; /* number of current attaches */
+ unsigned short int __shm_npages; /* size of segment (pages) */
+ unsigned long int *__unbounded __shm_pages; /* array of ptrs to frames -> SHMMAX */
+ struct vm_area_struct *__unbounded __attaches; /* descriptors for attaches */
+};
+
+struct __old_shminfo
+{
+ int shmmax;
+ int shmmin;
+ int shmmni;
+ int shmseg;
+ int shmall;
+};
+
+/* Provide operations to control over shared memory segments. */
+int __new_shmctl (int, int, struct shmid_ds *);
+
+int
+__new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
+{
+#if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (shmctl, 3, shmid, cmd | __IPC_64, CHECK_1 (buf));
+#else
+ switch (cmd) {
+ case SHM_STAT:
+ case IPC_STAT:
+ case IPC_SET:
+ case IPC_INFO:
+ break;
+ default:
+ return INLINE_SYSCALL (shmctl, 3, shmid, cmd, CHECK_1 (buf));
+ }
+
+ {
+ int save_errno = errno, result;
+ struct __old_shmid_ds old;
+
+ /* Unfortunately there is no way how to find out for sure whether
+ we should use old or new shmctl. */
+ result = INLINE_SYSCALL (shmctl, 3, shmid, cmd | __IPC_64, CHECK_1 (buf));
+ if (result != -1 || errno != EINVAL)
+ return result;
+
+ __set_errno(save_errno);
+ if (cmd == IPC_SET)
+ {
+ old.shm_perm.uid = buf->shm_perm.uid;
+ old.shm_perm.gid = buf->shm_perm.gid;
+ old.shm_perm.mode = buf->shm_perm.mode;
+ if (old.shm_perm.uid != buf->shm_perm.uid ||
+ old.shm_perm.gid != buf->shm_perm.gid)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ }
+ result = INLINE_SYSCALL (shmctl, 3, shmid, cmd, __ptrvalue (&old));
+ if (result != -1 && (cmd == SHM_STAT || cmd == IPC_STAT))
+ {
+ memset(buf, 0, sizeof(*buf));
+ buf->shm_perm.__key = old.shm_perm.__key;
+ buf->shm_perm.uid = old.shm_perm.uid;
+ buf->shm_perm.gid = old.shm_perm.gid;
+ buf->shm_perm.cuid = old.shm_perm.cuid;
+ buf->shm_perm.cgid = old.shm_perm.cgid;
+ buf->shm_perm.mode = old.shm_perm.mode;
+ buf->shm_perm.__seq = old.shm_perm.__seq;
+ buf->shm_atime = old.shm_atime;
+ buf->shm_dtime = old.shm_dtime;
+ buf->shm_ctime = old.shm_ctime;
+ buf->shm_segsz = old.shm_segsz;
+ buf->shm_nattch = old.shm_nattch;
+ buf->shm_cpid = old.shm_cpid;
+ buf->shm_lpid = old.shm_lpid;
+ }
+ else if (result != -1 && cmd == IPC_INFO)
+ {
+ struct __old_shminfo *oldi = (void *)&old;
+ struct shminfo *i = (struct shminfo *)buf;
+
+ memset(i, 0, sizeof(*i));
+ i->shmmax = oldi->shmmax;
+ i->shmmin = oldi->shmmin;
+ i->shmmni = oldi->shmmni;
+ i->shmseg = oldi->shmseg;
+ i->shmall = oldi->shmall;
+ }
+ return result;
+ }
+#endif
+}
+
+#include <shlib-compat.h>
+versioned_symbol (libc, __new_shmctl, shmctl, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/sigaction.c b/libc/sysdeps/unix/sysv/linux/alpha/sigaction.c
new file mode 100644
index 000000000..26b081d9a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/sigaction.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <sys/cdefs.h>
+#include <stddef.h>
+
+/*
+ * In order to get the hidden arguments for rt_sigaction set up
+ * properly, we need to call the assembly version. Detect this in the
+ * INLINE_SYSCALL macro, and fail to expand inline in that case.
+ */
+
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+ (__NR_##name == __NR_rt_sigaction \
+ ? __syscall_rt_sigaction(args) \
+ : INLINE_SYSCALL1(name, nr, args))
+
+struct kernel_sigaction;
+extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *__unbounded,
+ struct kernel_sigaction *__unbounded, size_t);
+
+#include <sysdeps/unix/sysv/linux/sigaction.c>
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h b/libc/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
new file mode 100644
index 000000000..16c5dcbc5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 1999, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define SIGCONTEXT int _code, struct sigcontext *
+#define SIGCONTEXT_EXTRA_ARGS _code,
+#define GET_PC(ctx) ((void *) (ctx)->sc_pc)
+#define GET_FRAME(ctx) ((void *) (ctx)->sc_regs[15])
+#define GET_STACK(ctx) ((void *) (ctx)->sc_regs[30])
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/sigprocmask.c b/libc/sysdeps/unix/sysv/linux/alpha/sigprocmask.c
new file mode 100644
index 000000000..1916111a2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/sigprocmask.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1993, 1995, 1997, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger (davidm@azstarnet.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <signal.h>
+
+/* When there is kernel support for more than 64 signals, we'll have to
+ switch to a new system call convention here. */
+
+int
+__sigprocmask (int how, const sigset_t *set, sigset_t *oset)
+{
+ unsigned long int setval;
+ long result;
+
+ if (set)
+ setval = set->__val[0];
+ else
+ {
+ setval = 0;
+ how = SIG_BLOCK; /* ensure blocked mask doesn't get changed */
+ }
+
+ result = INLINE_SYSCALL (osf_sigprocmask, 2, how, setval);
+ if (result == -1)
+ /* If there are ever more than 63 signals, we need to recode this
+ in assembler since we wouldn't be able to distinguish a mask of
+ all 1s from -1, but for now, we're doing just fine... */
+ return result;
+
+ if (oset)
+ {
+ oset->__val[0] = result;
+ result = _SIGSET_NWORDS;
+ while (--result > 0)
+ oset->__val[result] = 0;
+ }
+ return 0;
+}
+
+weak_alias (__sigprocmask, sigprocmask);
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/sigsuspend.S b/libc/sysdeps/unix/sysv/linux/alpha/sigsuspend.S
new file mode 100644
index 000000000..48c3f271c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/sigsuspend.S
@@ -0,0 +1,33 @@
+/* Copyright (C) 1993,1995,1996,1997,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger <davidm@cs.arizona.edu>, 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* sigsuspend is a special syscall since it needs to dereference the
+ sigset. This will have to change when we have more than 64 signals. */
+
+#include <sysdep-cancel.h>
+
+#undef PSEUDO_PREPARE_ARGS
+#define PSEUDO_PREPARE_ARGS ldq a0, 0(a0);
+
+PSEUDO(__sigsuspend, sigsuspend, 1)
+ ret
+PSEUDO_END(__sigsuspend)
+libc_hidden_def (__sigsuspend)
+weak_alias (__sigsuspend, sigsuspend)
+strong_alias (__sigsuspend, __libc_sigsuspend)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/sizes.h b/libc/sysdeps/unix/sysv/linux/alpha/sizes.h
new file mode 100644
index 000000000..0c7f4d5d2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/sizes.h
@@ -0,0 +1,24 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIZES_H
+#define _SIZES_H 1
+
+#define PTR_SIZE_STR "8"
+
+#endif /* sizes.h */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/swapcontext.S b/libc/sysdeps/unix/sysv/linux/alpha/swapcontext.S
new file mode 100644
index 000000000..1221f67f7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/swapcontext.S
@@ -0,0 +1,51 @@
+/* Save current context and install the given one.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <ucontext-offsets.h>
+
+ENTRY(__swapcontext)
+
+#ifdef PROF
+ ldgp $29, 0($27)
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+ .prologue 1
+#elif defined PIC
+ .prologue 0
+#else
+ ldgp $29, 0($27)
+ .prologue 1
+#endif
+
+#ifdef PIC
+ unop
+ bsr $0, __getcontext_x !samegp
+ mov $17, $16
+ br $31, __setcontext !samegp
+#else
+ jsr $0, __getcontext_x
+ mov $17, $16
+ jmp $31, __setcontext
+#endif
+
+END(__swapcontext)
+weak_alias (__swapcontext, swapcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/sys/acct.h b/libc/sysdeps/unix/sysv/linux/alpha/sys/acct.h
new file mode 100644
index 000000000..1e00006ef
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/sys/acct.h
@@ -0,0 +1,66 @@
+/* Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_ACCT_H
+
+#define _SYS_ACCT_H 1
+#include <features.h>
+
+#define __need_time_t
+#include <time.h>
+
+
+__BEGIN_DECLS
+
+#define ACCT_COMM 16
+
+struct acct
+ {
+ char ac_comm[ACCT_COMM]; /* Accounting command name. */
+ time_t ac_utime; /* Accounting user time. */
+ time_t ac_stime; /* Accounting system time. */
+ time_t ac_etime; /* Accounting elapsed time. */
+ time_t ac_btime; /* Beginning time. */
+ unsigned int ac_uid; /* Accounting user ID. */
+ unsigned int ac_gid; /* Accounting group ID. */
+ unsigned int ac_tty; /* Controlling tty. */
+ /* Please note that the value of the `ac_tty' field, a device number,
+ is encoded differently in the kernel and for the libc dev_t type. */
+ char ac_flag; /* Accounting flag. */
+ long int ac_minflt; /* Accounting minor pagefaults. */
+ long int ac_majflt; /* Accounting major pagefaults. */
+ long int ac_exitcode; /* Accounting process exitcode. */
+ };
+
+enum
+ {
+ AFORK = 0001, /* Has executed fork, but no exec. */
+ ASU = 0002, /* Used super-user privileges. */
+ ACORE = 0004, /* Dumped core. */
+ AXSIG = 0010 /* Killed by a signal. */
+ };
+
+#define AHZ 100
+
+
+/* Switch process accounting on and off. */
+extern int acct (__const char *__filename) __THROW;
+
+__END_DECLS
+
+#endif /* sys/acct.h */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/sys/io.h b/libc/sysdeps/unix/sysv/linux/alpha/sys/io.h
new file mode 100644
index 000000000..4334c6392
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/sys/io.h
@@ -0,0 +1,95 @@
+/* Copyright (C) 1996, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IO_H
+
+#define _SYS_IO_H 1
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* If TURN_ON is TRUE, request for permission to do direct i/o on the
+ port numbers in the range [FROM,FROM+NUM-1]. Otherwise, turn I/O
+ permission off for that range. This call requires root privileges.
+
+ Portability note: not all Linux platforms support this call. Most
+ platforms based on the PC I/O architecture probably will, however.
+ E.g., Linux/Alpha for Alpha PCs supports this. */
+extern int ioperm (unsigned long int __from, unsigned long int __num,
+ int __turn_on) __THROW;
+
+/* Set the I/O privilege level to LEVEL. If LEVEL>3, permission to
+ access any I/O port is granted. This call requires root
+ privileges. */
+extern int iopl (int __level) __THROW;
+
+/* Return the physical address of the DENSE I/O memory or NULL if none
+ is available (e.g. on a jensen). */
+extern unsigned long int _bus_base (void) __THROW __attribute__ ((const));
+extern unsigned long int bus_base (void) __THROW __attribute__ ((const));
+
+/* Return the physical address of the SPARSE I/O memory. */
+extern unsigned long _bus_base_sparse (void) __THROW __attribute__ ((const));
+extern unsigned long bus_base_sparse (void) __THROW __attribute__ ((const));
+
+/* Return the HAE shift used by the SPARSE I/O memory. */
+extern int _hae_shift (void) __THROW __attribute__ ((const));
+extern int hae_shift (void) __THROW __attribute__ ((const));
+
+/* Previous three are deprecated in favour of the following, which
+ knows about multiple PCI "hoses". Provide the PCI bus and dfn
+ numbers just as to pciconfig_read/write. */
+
+enum __pciconfig_iobase_which
+{
+ IOBASE_HOSE = 0, /* Return hose index. */
+ IOBASE_SPARSE_MEM = 1, /* Return physical memory addresses. */
+ IOBASE_DENSE_MEM = 2,
+ IOBASE_SPARSE_IO = 3,
+ IOBASE_DENSE_IO = 4
+};
+
+extern long pciconfig_iobase(enum __pciconfig_iobase_which __which,
+ unsigned long int __bus,
+ unsigned long int __dfn)
+ __THROW __attribute__ ((const));
+
+/* Access PCI space protected from machine checks. */
+extern int pciconfig_read (unsigned long int __bus,
+ unsigned long int __dfn,
+ unsigned long int __off,
+ unsigned long int __len,
+ unsigned char *__buf) __THROW;
+
+extern int pciconfig_write (unsigned long int __bus,
+ unsigned long int __dfn,
+ unsigned long int __off,
+ unsigned long int __len,
+ unsigned char *__buf) __THROW;
+
+/* Userspace declarations. */
+extern unsigned int inb (unsigned long __port) __THROW;
+extern unsigned int inw (unsigned long __port) __THROW;
+extern unsigned int inl (unsigned long __port) __THROW;
+extern void outb (unsigned char __b, unsigned long __port) __THROW;
+extern void outw (unsigned short __w, unsigned long __port) __THROW;
+extern void outl (unsigned int __l, unsigned long __port) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_IO_H */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/sys/procfs.h b/libc/sysdeps/unix/sysv/linux/alpha/sys/procfs.h
new file mode 100644
index 000000000..bee51f94e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/sys/procfs.h
@@ -0,0 +1,115 @@
+/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H 1
+
+/* This is somehow modelled after the file of the same name on SysVr4
+ systems. It provides a definition of the core file format for ELF
+ used on Linux. */
+
+#include <features.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ucontext.h>
+#include <sys/user.h>
+#include <asm/elf.h>
+
+__BEGIN_DECLS
+
+struct elf_siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_code; /* Extra code. */
+ int si_errno; /* Errno. */
+ };
+
+/* Definitions to generate Intel SVR4-like core files. These mostly
+ have the same names as the SVR4 types with "elf_" tacked on the
+ front to prevent clashes with linux definitions, and the typedef
+ forms have been avoided. This is mostly like the SVR4 structure,
+ but more Linuxy, with things that Linux does not support and which
+ gdb doesn't really use excluded. Fields present but not used are
+ marked with "XXX". */
+struct elf_prstatus
+ {
+#if 0
+ long int pr_flags; /* XXX Process flags. */
+ short int pr_why; /* XXX Reason for process halt. */
+ short int pr_what; /* XXX More detailed reason. */
+#endif
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned long int pr_sigpend; /* Set of pending signals. */
+ unsigned long int pr_sighold; /* Set of held signals. */
+#if 0
+ struct sigaltstack pr_altstack; /* Alternate stack info. */
+ struct sigaction pr_action; /* Signal action for current sig. */
+#endif
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct timeval pr_utime; /* User time. */
+ struct timeval pr_stime; /* System time. */
+ struct timeval pr_cutime; /* Cumulative user time. */
+ struct timeval pr_cstime; /* Cumulative system time. */
+#if 0
+ long int pr_instr; /* Current instruction. */
+#endif
+ elf_gregset_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+#define ELF_PRARGSZ (80) /* Number of chars for args */
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long int pr_flag; /* Flags. */
+ unsigned int pr_uid;
+ unsigned int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+/* Addresses. */
+typedef void *psaddr_t;
+
+/* Register sets. Linux has different names. */
+typedef gregset_t prgregset_t;
+typedef fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+ therefore habe only ine PID type. */
+typedef __pid_t lwpid_t;
+
+
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif /* sys/procfs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/sys/ucontext.h b/libc/sysdeps/unix/sysv/linux/alpha/sys/ucontext.h
new file mode 100644
index 000000000..438293c62
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/sys/ucontext.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+
+#include <bits/sigcontext.h>
+
+
+/* Type for general register. */
+typedef long int greg_t;
+
+/* Number of general registers. */
+#define NGREG 33
+
+/* Container for all general registers. */
+typedef greg_t gregset_t[NGREG];
+
+/* Type for floating-point register. */
+typedef long int fpreg_t;
+
+/* Number of general registers. */
+#define NFPREG 32
+
+/* Container for all general registers. */
+typedef fpreg_t fpregset_t[NFPREG];
+
+
+/* A machine context is exactly a sigcontext. */
+typedef struct sigcontext mcontext_t;
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ unsigned long __uc_osf_sigmask;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ __sigset_t uc_sigmask;
+ } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/sys/user.h b/libc/sysdeps/unix/sysv/linux/alpha/sys/user.h
new file mode 100644
index 000000000..4cd29d2ff
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/sys/user.h
@@ -0,0 +1,50 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H 1
+
+/* The whole purpose of this file is for gdb/strace and gdb/strace
+ only. Don't read too much into it. Don't use it for anything other
+ than gdb/strace unless you know what you are doing. */
+
+#include <asm/page.h>
+#include <asm/reg.h>
+
+struct user
+{
+ unsigned long int regs[EF_SIZE / 8 + 32]; /* integer and fp regs */
+ size_t u_tsize; /* text size (pages) */
+ size_t u_dsize; /* data size (pages) */
+ size_t u_ssize; /* stack size (pages) */
+ unsigned long int start_code; /* text starting address */
+ unsigned long int start_data; /* data starting address */
+ unsigned long int start_stack; /* stack starting address */
+ long int signal; /* signal causing core dump */
+ struct regs *u_ar0; /* help gdb find registers */
+ unsigned long int magic; /* identifies a core file */
+ char u_comm[32]; /* user command name */
+};
+
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_DATA_START_ADDR (u.start_data)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif /* sys/user.h */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/syscall.S b/libc/sysdeps/unix/sysv/linux/alpha/syscall.S
new file mode 100644
index 000000000..0c4081363
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/syscall.S
@@ -0,0 +1,77 @@
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger <davidm@azstarnet.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/*
+ * This is for COMPATIBILITY with Linux/x86 only. Linux/Alpha system
+ * calls return an error indication in a3. This allows arbitrary 64bit
+ * values to be returned in v0 (because negative values are not
+ * mistaken as error numbers). However, C allows only one value to
+ * be returned, so the interface below folds the error indication passed in
+ * a3 back into v0: it sets v0 to -errno if an error occurs. Thus,
+ * no negative 64bit numbers can be returned. To avoid this problem,
+ * use assembly stubs wherever possible/convenient.
+ *
+ * Usage:
+ *
+ * long syscall(syscall_number, arg1, arg2, arg3, arg4, arg5)
+ *
+ * syscall_number = the index of the system call we're invoking
+ * arg1-arg5 = up to 5 integer arguments to the system call
+ *
+ * We need to do some arg shifting: the kernel expects the
+ * syscall number in v0 and the first five args in a0-a4.
+ *
+ */
+
+
+LEAF(__syscall, 0)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ mov a0, v0 /* Syscall number -> v0 */
+ mov a1, a0 /* arg1-arg5 -> a0-a4 */
+ mov a2, a1
+ mov a3, a2
+ mov a4, a3
+ mov a5, a4
+
+ call_pal PAL_callsys /* Invoke system call */
+ bne a3, $error
+ ret
+
+$error:
+#ifndef PROF
+ br gp, 2f
+2: ldgp gp, 0(gp)
+#endif
+ SYSCALL_ERROR_HANDLER
+
+END(__syscall)
+
+weak_alias (__syscall, syscall)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/syscalls.list b/libc/sysdeps/unix/sysv/linux/alpha/syscalls.list
new file mode 100644
index 000000000..7b3f23356
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/syscalls.list
@@ -0,0 +1,57 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+oldmsgctl EXTRA msgctl i:iip __old_msgctl msgctl@GLIBC_2.0
+msgget - msgget i:ii __msgget msgget
+msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
+msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
+shmat - osf_shmat i:ipi __shmat shmat
+oldshmctl EXTRA shmctl i:iip __old_shmctl shmctl@GLIBC_2.0
+shmdt - shmdt i:s __shmdt shmdt
+shmget - shmget i:iii __shmget shmget
+semop - semop i:ipi __semop semop
+semtimedop - semtimedop i:ipip semtimedop
+semget - semget i:iii __semget semget
+oldsemctl EXTRA semctl i:iiii __old_semctl semctl@GLIBC_2.0
+
+sigstack - sigstack 2 sigstack
+vfork - vfork 0 __vfork vfork
+
+getpriority - getpriority i:ii __getpriority getpriority
+open - open Ci:siv __libc_open __open open !__libc_open64 __open64 open64
+open64 open -
+
+# proper socket implementations:
+accept - accept Ci:iBN __libc_accept __accept accept
+bind - bind i:ipi __bind bind
+connect - connect Ci:ipi __libc_connect __connect_internal __connect connect
+getpeername - getpeername i:ipp __getpeername getpeername
+getsockname - getsockname i:ipp __getsockname getsockname
+getsockopt - getsockopt i:iiiBN __getsockopt getsockopt
+listen - listen i:ii __listen listen
+recv - recv Ci:ibni __libc_recv __recv recv
+recvfrom - recvfrom Ci:ibniBN __libc_recvfrom __recvfrom recvfrom
+recvmsg - recvmsg Ci:ipi __libc_recvmsg __recvmsg recvmsg
+send - send Ci:ibni __libc_send __send send
+sendmsg - sendmsg Ci:ipi __libc_sendmsg __sendmsg sendmsg
+sendto - sendto Ci:ibnibn __libc_sendto __sendto sendto
+setsockopt - setsockopt i:iiibn __setsockopt setsockopt
+shutdown - shutdown i:ii __shutdown shutdown
+socket - socket i:iii __socket socket
+socketpair - socketpair i:iiif __socketpair socketpair
+
+ptrace - ptrace 4 __ptrace ptrace
+
+# access pci space protected from machine checks:
+pciconfig_read EXTRA pciconfig_read 5 pciconfig_read
+pciconfig_write EXTRA pciconfig_write 5 pciconfig_write
+pciconfig_iobase EXTRA pciconfig_iobase 3 __pciconfig_iobase pciconfig_iobase
+
+# support old timeval32 entry points
+osf_select - osf_select C:5 __select_tv32 __select@GLIBC_2.0 select@GLIBC_2.0
+osf_gettimeofday - osf_gettimeofday 2 __gettimeofday_tv32 __gettimeofday@GLIBC_2.0 gettimeofday@GLIBC_2.0
+osf_settimeofday - osf_settimeofday 2 __settimeofday_tv32 settimeofday@GLIBC_2.0
+osf_getitimer - osf_getitimer 2 __getitimer_tv32 getitimer@GLIBC_2.0
+osf_setitimer - osf_setitimer 3 __setitimer_tv32 setitimer@GLIBC_2.0
+osf_utimes - osf_utimes 2 __utimes_tv32 utimes@GLIBC_2.0
+osf_getrusage - osf_getrusage 2 __getrusage_tv32 getrusage@GLIBC_2.0
+osf_wait4 - osf_wait4 2 __wait4_tv32 wait4@GLIBC_2.0
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/sysconf.c b/libc/sysdeps/unix/sysv/linux/alpha/sysconf.c
new file mode 100644
index 000000000..2bbaf1f36
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/sysconf.c
@@ -0,0 +1,152 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+static long int linux_sysconf (int name);
+
+#define CSHAPE(totalsize, linesize, assoc) \
+ ((totalsize & ~0xff) | (linesize << 4) | assoc)
+
+long __libc_alpha_cache_shape[4] = { -2, -2, -2, -2 };
+
+static inline unsigned long
+implver (void)
+{
+ unsigned long i;
+#if __GNUC_PREREQ(3,3)
+ i = __builtin_alpha_implver ();
+#else
+ asm ("implver %0" : "=r" (i));
+#endif
+ return i;
+}
+
+static inline unsigned long
+amask (unsigned long x)
+{
+ unsigned long r;
+#if __GNUC_PREREQ(3,3)
+ r = __builtin_alpha_amask (x);
+#else
+ asm ("amask %1,%0" : "=r"(r) : "Ir"(x));
+#endif
+ return r;
+}
+
+/* Get the value of the system variable NAME. */
+long int
+__sysconf (int name)
+{
+ long shape, index;
+
+ /* We only handle the cache information here (for now). */
+ if (name < _SC_LEVEL1_ICACHE_SIZE || name > _SC_LEVEL4_CACHE_LINESIZE)
+ return linux_sysconf (name);
+
+ /* No Alpha has L4 caches. */
+ if (name >= _SC_LEVEL4_CACHE_SIZE)
+ return -1;
+
+ index = (name - _SC_LEVEL1_ICACHE_SIZE) / 3;
+ shape = __libc_alpha_cache_shape[index];
+ if (shape == -2)
+ {
+ long shape_l1i, shape_l1d, shape_l2, shape_l3 = -1;
+
+ /* ??? In the cases below for which we do not know L1 cache sizes,
+ we could do timings to measure sizes. But for the Bcache, it's
+ generally big enough that (without additional help) TLB effects
+ get in the way. We'd either need to be able to allocate large
+ pages or have the kernel do the timings from KSEG. Fortunately,
+ kernels beginning with 2.6.5 will pass us this info in auxvec. */
+
+ switch (implver())
+ {
+ case 0: /* EV4 */
+ /* EV4/LCA45 had 8k L1 caches; EV45 had 16k L1 caches. */
+ /* EV4/EV45 had 128k to 16M 32-byte direct Bcache. LCA45
+ had 64k to 8M 8-byte direct Bcache. Can't tell. */
+ shape_l1i = shape_l1d = shape_l2 = CSHAPE (0, 5, 1);
+ break;
+
+ case 1: /* EV5 */
+ if (amask (1 << 8))
+ {
+ /* MAX insns not present; either EV5 or EV56. */
+ shape_l1i = shape_l1d = CSHAPE(8*1024, 5, 1);
+ /* ??? L2 and L3 *can* be configured as 32-byte line. */
+ shape_l2 = CSHAPE (96*1024, 6, 3);
+ /* EV5/EV56 has 1M to 16M Bcache. */
+ shape_l3 = CSHAPE (0, 6, 1);
+ }
+ else
+ {
+ /* MAX insns present; either PCA56 or PCA57. */
+ /* PCA56 had 16k 64-byte cache; PCA57 had 32k Icache. */
+ /* PCA56 had 8k 64-byte cache; PCA57 had 16k Dcache. */
+ /* PCA5[67] had 512k to 4M Bcache. */
+ shape_l1i = shape_l1d = shape_l2 = CSHAPE (0, 6, 1);
+ }
+ break;
+
+ case 2: /* EV6 */
+ shape_l1i = shape_l1d = CSHAPE(64*1024, 6, 2);
+ /* EV6/EV67/EV68* had 1M to 16M Bcache. */
+ shape_l2 = CSHAPE (0, 6, 1);
+ break;
+
+ case 3: /* EV7 */
+ shape_l1i = shape_l1d = CSHAPE(64*1024, 6, 2);
+ shape_l2 = CSHAPE(7*1024*1024/4, 6, 7);
+ break;
+
+ default:
+ shape_l1i = shape_l1d = shape_l2 = 0;
+ break;
+ }
+
+ __libc_alpha_cache_shape[0] = shape_l1i;
+ __libc_alpha_cache_shape[1] = shape_l1d;
+ __libc_alpha_cache_shape[2] = shape_l2;
+ __libc_alpha_cache_shape[3] = shape_l3;
+ shape = __libc_alpha_cache_shape[index];
+ }
+
+ if (shape <= 0)
+ return shape;
+
+ switch (name % 3)
+ {
+ case 0: /* total size */
+ return shape & -0x100;
+ case 1: /* associativity */
+ return shape & 0xf;
+ default: /* line size */
+ return 1L << ((shape >> 4) & 0xf);
+ }
+}
+
+/* Now the generic Linux version. */
+#undef __sysconf
+#define __sysconf static linux_sysconf
+#include "../sysconf.c"
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/sysdep.h b/libc/sysdeps/unix/sysv/linux/alpha/sysdep.h
new file mode 100644
index 000000000..a22da71d6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/sysdep.h
@@ -0,0 +1,99 @@
+/* Copyright (C) 1992, 1993, 1995, 1996, 1997, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINUX_ALPHA_SYSDEP_H
+#define _LINUX_ALPHA_SYSDEP_H 1
+
+#ifdef __ASSEMBLER__
+#include <asm/pal.h>
+#include <alpha/regdef.h>
+#endif
+
+/* There is some commonality. */
+#include <sysdeps/unix/alpha/sysdep.h>
+
+/* For Linux we can use the system call table in the header file
+ /usr/include/asm/unistd.h
+ of the kernel. But these symbols do not follow the SYS_* syntax
+ so we have to redefine the `SYS_ify' macro here. */
+#undef SYS_ify
+#ifdef __STDC__
+# define SYS_ify(syscall_name) __NR_##syscall_name
+#else
+# define SYS_ify(syscall_name) __NR_/**/syscall_name
+#endif
+
+/* Define some aliases to make automatic syscall generation work
+ properly. The SYS_* variants are for the benefit of the files in
+ sysdeps/unix. */
+#define __NR_getpid __NR_getxpid
+#define __NR_getuid __NR_getxuid
+#define __NR_getgid __NR_getxgid
+#define SYS_getpid __NR_getxpid
+#define SYS_getuid __NR_getxuid
+#define SYS_getgid __NR_getxgid
+
+/*
+ * Some syscalls no Linux program should know about:
+ */
+#define __NR_osf_sigprocmask 48
+#define __NR_osf_shmat 209
+#define __NR_osf_getsysinfo 256
+#define __NR_osf_setsysinfo 257
+
+/* Help old kernel headers where particular syscalls are not available. */
+#ifndef __NR_semtimedop
+# define __NR_semtimedop 423
+#endif
+
+/* This is a kludge to make syscalls.list find these under the names
+ pread and pwrite, since some kernel headers define those names
+ and some define the *64 names for the same system calls. */
+#if !defined __NR_pread && defined __NR_pread64
+# define __NR_pread __NR_pread64
+#endif
+#if !defined __NR_pwrite && defined __NR_pwrite64
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+/*
+ * In order to get the hidden arguments for rt_sigaction set up
+ * properly, we need to call the assembly version. This shouldn't
+ * happen except for inside sigaction.c, where we handle this
+ * specially. Catch other uses and error.
+ */
+
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+({ \
+ extern char ChEcK[__NR_##name == __NR_rt_sigaction ? -1 : 1] \
+ __attribute__((unused)); \
+ INLINE_SYSCALL1(name, nr, args); \
+})
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err_out, nr, args...) \
+({ \
+ extern char ChEcK[__NR_##name == __NR_rt_sigaction ? -1 : 1] \
+ __attribute__((unused)); \
+ INTERNAL_SYSCALL1(name, err_out, nr, args); \
+})
+
+#endif /* _LINUX_ALPHA_SYSDEP_H */
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/ucontext-offsets.sym b/libc/sysdeps/unix/sysv/linux/alpha/ucontext-offsets.sym
new file mode 100644
index 000000000..f95ff7563
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/ucontext-offsets.sym
@@ -0,0 +1,18 @@
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+--
+UC_LINK offsetof (ucontext_t, uc_link)
+UC_OSF_SIGMASK offsetof (ucontext_t, __uc_osf_sigmask)
+UC_STACK offsetof (ucontext_t, uc_stack)
+UC_SIGCTX offsetof (ucontext_t, uc_mcontext)
+UC_SIGMASK offsetof (ucontext_t, uc_sigmask)
+SC_REGS offsetof (struct sigcontext, sc_regs)
+SC_FPREGS offsetof (struct sigcontext, sc_fpregs)
+SC_PC offsetof (struct sigcontext, sc_pc)
+SC_PS offsetof (struct sigcontext, sc_ps)
+SC_FPCRS offsetof (struct sigcontext, sc_fpcr)
+SC_MASK offsetof (struct sigcontext, sc_mask)
+SC_FPCR offsetof (struct sigcontext, sc_fpcr)
+SS_SP offsetof (stack_t, ss_sp)
+SS_SIZE offsetof (stack_t, ss_size)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/utimes.S b/libc/sysdeps/unix/sysv/linux/alpha/utimes.S
new file mode 100644
index 000000000..0dd0a9372
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/utimes.S
@@ -0,0 +1,123 @@
+/* Copyright (C) 1998, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+.text
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+#define UTIMES __utimes_tv64
+#else
+#define UTIMES __utimes
+#endif
+
+#if defined __ASSUME_TIMEVAL64
+PSEUDO(UTIMES, utimes, 2)
+ ret
+PSEUDO_END(UTIMES)
+#else
+/* The problem here is that initially we made struct timeval compatible with
+ OSF/1, using int32. But we defined time_t with uint64, and later found
+ that POSIX requires tv_sec to be time_t.
+
+ So now we have to do compatibility stuff. */
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. */
+.comm __libc_missing_axp_tv64, 4
+
+LEAF(UTIMES, 16)
+ ldgp gp, 0(pv)
+ subq sp, 16, sp
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ ldl t0, __libc_missing_axp_tv64
+
+ /* Save arguments in case we do need to fall back. */
+ stq a0, 0(sp)
+ stq a1, 8(sp)
+
+ bne t0, $do32
+
+ ldi v0, SYS_ify(utimes)
+ callsys
+ bne a3, $err64
+
+ /* Everything ok. */
+ addq sp, 16, sp
+ ret
+
+ /* If we didn't get ENOSYS, it is a real error. */
+ .align 3
+$err64: cmpeq v0, ENOSYS, t0
+ beq t0, $error
+ stl t0, __libc_missing_axp_tv64
+
+ /* Recover the saved arguments. */
+ ldq a1, 8(sp)
+ ldq a0, 0(sp)
+
+ .align 3
+$do32:
+ /* Conditionally bounce values down. */
+ beq a1, 1f
+ ldq t0, 0(a1)
+ ldq t1, 8(a1)
+ ldq t2, 16(a1)
+ ldq t3, 24(a1)
+ stl t0, 0(sp)
+ stl t1, 4(sp)
+ stl t2, 8(sp)
+ stl t3, 12(sp)
+ mov sp, a1
+
+1: ldi v0, SYS_ify(osf_utimes)
+ callsys
+ bne a3, $error
+
+ addq sp, 16, sp
+ ret
+
+ .align 3
+$error:
+ addq sp, 16, sp
+ SYSCALL_ERROR_HANDLER
+
+END(UTIMES)
+#endif /* __ASSUME_TIMEVAL64 */
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+default_symbol_version (__utimes_tv64, __utimes, GLIBC_2.1)
+
+/* It seems to me to be a misfeature of the assembler that we can only
+ have one version-alias per symbol. So create an alias ourselves.
+ The 'p' is for 'public'. *Shrug* */
+strong_alias (__utimes_tv64, __utimes_tv64p)
+default_symbol_version (__utimes_tv64p, utimes, GLIBC_2.1)
+#else
+weak_alias (__utimes, utimes)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/wait4.S b/libc/sysdeps/unix/sysv/linux/alpha/wait4.S
new file mode 100644
index 000000000..634993deb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/wait4.S
@@ -0,0 +1,156 @@
+/* Copyright (C) 1998, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+.text
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+#define WAIT4 __wait4_tv64
+#else
+#define WAIT4 __wait4
+#endif
+
+#if defined __ASSUME_TIMEVAL64
+PSEUDO(WAIT4, wait4, 4)
+ ret
+PSEUDO_END(WAIT4)
+#else
+/* The problem here is that initially we made struct timeval compatible with
+ OSF/1, using int32. But we defined time_t with uint64, and later found
+ that POSIX requires tv_sec to be time_t.
+
+ So now we have to do compatibility stuff. */
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. */
+.comm __libc_missing_axp_tv64, 4
+
+LEAF(WAIT4, 32)
+ ldgp gp, 0(pv)
+ subq sp, 32, sp
+#ifdef PROF
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+#endif
+ .prologue 1
+
+ ldl t0, __libc_missing_axp_tv64
+
+ /* Save arguments in case we do need to fall back. */
+ stq a0, 0(sp)
+ stq a1, 8(sp)
+ stq a2, 16(sp)
+ stq a3, 24(sp)
+
+ bne t0, $do32
+
+ ldi v0, SYS_ify(wait4)
+ callsys
+ bne a3, $err64
+
+ /* Everything ok. */
+ addq sp, 32, sp
+ ret
+
+ /* If we didn't get ENOSYS, it is a real error. */
+ .align 3
+$err64: cmpeq v0, ENOSYS, t0
+ beq t0, $error
+ stl t0, __libc_missing_axp_tv64
+
+ /* Recover the saved arguments. */
+ ldq a3, 24(sp)
+ ldq a2, 16(sp)
+ ldq a1, 8(sp)
+ ldq a0, 0(sp)
+
+ .align 3
+$do32: ldi v0, SYS_ify(osf_wait4)
+ callsys
+ bne a3, $error
+
+ /* Copy back to proper format. */
+ ldq a3, 24(sp)
+ beq a3, 2f
+ ldl t0, 0(a3) # ru_utime.tv_sec
+ ldl t1, 4(a3) # ru_utime.tv_usec
+ ldl t2, 8(a3) # ru_stime.tv_sec
+ ldl t3, 12(a3) # ru_stime.tv_usec
+ ldt $f15, 16(a3) # ru_maxrss
+ ldt $f16, 24(a3) # ru_ixrss
+ ldt $f17, 32(a3) # ru_idrss
+ ldt $f18, 40(a3) # ru_isrss
+ ldt $f19, 48(a3) # ru_minflt
+ ldt $f20, 56(a3) # ru_majflt
+ ldt $f21, 64(a3) # ru_nswap
+ ldt $f22, 72(a3) # ru_inblock
+ ldt $f23, 80(a3) # ru_oublock
+ ldt $f24, 88(a3) # ru_msgsend
+ ldt $f25, 96(a3) # ru_msgrcv
+ ldt $f26, 104(a3) # ru_nsignals
+ ldt $f27, 112(a3) # ru_nvcsw
+ .set noat
+ ldt $f28, 120(a3) # ru_nivcsw
+ stq t0, 0(a3)
+ stq t1, 8(a3)
+ stq t2, 16(a3)
+ stq t3, 24(a3)
+ stt $f15, 32(a3)
+ stt $f16, 40(a3)
+ stt $f17, 48(a3)
+ stt $f18, 56(a3)
+ stt $f19, 64(a3)
+ stt $f20, 72(a3)
+ stt $f21, 80(a3)
+ stt $f22, 88(a3)
+ stt $f23, 96(a3)
+ stt $f24, 104(a3)
+ stt $f25, 112(a3)
+ stt $f26, 120(a3)
+ stt $f27, 128(a3)
+ stt $f28, 136(a3)
+ .set at
+
+2: addq sp, 32, sp
+ ret
+
+ .align 3
+$error:
+ addq sp, 32, sp
+ SYSCALL_ERROR_HANDLER
+
+END(WAIT4)
+#endif /* __ASSUME_TIMEVAL64 */
+
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+default_symbol_version (__wait4_tv64, __wait4, GLIBC_2.1)
+
+/* It seems to me to be a misfeature of the assembler that we can only
+ have one version-alias per symbol. So create an alias ourselves.
+ The 'p' is for 'public'. *Shrug* */
+strong_alias (__wait4_tv64, __wait4_tv64p)
+default_symbol_version (__wait4_tv64p, wait4, GLIBC_2.1)
+#else
+weak_alias (__wait4, wait4)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/wordexp.c b/libc/sysdeps/unix/sysv/linux/alpha/wordexp.c
new file mode 100644
index 000000000..c2972e40c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/wordexp.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <shlib-compat.h>
+
+/* For Linux/Alpha we have to make the wordexp symbols versioned. */
+#define wordexp(words, pwordexp, flags) \
+ __new_wordexp (words, pwordexp, flags)
+
+#include <posix/wordexp.c>
+
+versioned_symbol (libc, __new_wordexp, wordexp, GLIBC_2_2_2);
+
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2_2)
+/* The old, incorrect wordexp_t definition. */
+typedef struct
+ {
+ int we_wordc; /* Count of words matched. */
+ char **we_wordv; /* List of expanded words. */
+ int we_offs; /* Slots to reserve in `we_wordv'. */
+ } old_wordexp_t;
+
+
+int
+attribute_compat_text_section
+__old_wordexp (const char *words, old_wordexp_t *pwordexp, int flags)
+{
+ wordexp_t we;
+ int result;
+
+ we.we_wordc = pwordexp->we_wordc;
+ we.we_wordv = pwordexp->we_wordv;
+ we.we_offs = pwordexp->we_offs;
+
+ result = __new_wordexp (words, &we, flags);
+
+ pwordexp->we_wordc = we.we_wordc;
+ pwordexp->we_wordv = we.we_wordv;
+ pwordexp->we_offs = we.we_offs;
+
+ return result;
+}
+compat_symbol (libc, __old_wordexp, wordexp, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/xstat.c b/libc/sysdeps/unix/sysv/linux/alpha/xstat.c
new file mode 100644
index 000000000..b7488e425
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/xstat.c
@@ -0,0 +1,64 @@
+/* xstat using old-style Unix stat system call.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __xstat64 __xstat64_disable
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <xstatconv.h>
+
+#undef __xstat64
+
+
+/* Get information about the file NAME in BUF. */
+int
+__xstat (int vers, const char *name, struct stat *buf)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ int result, errno_out;
+ struct kernel_stat kbuf;
+
+ if (vers == _STAT_VER_KERNEL64 && !__libc_missing_axp_stat64)
+ {
+ result = INTERNAL_SYSCALL (stat64, err, 2, name, buf);
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return result;
+ errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
+ if (errno_out != ENOSYS)
+ goto fail;
+ __libc_missing_axp_stat64 = 1;
+ }
+
+ result = INTERNAL_SYSCALL (stat, err, 2, name, &kbuf);
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return __xstat_conv (vers, &kbuf, buf);
+ errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
+
+ fail:
+ __set_errno (errno_out);
+ return -1;
+}
+hidden_def (__xstat)
+weak_alias (__xstat, _xstat);
+strong_alias (__xstat, __xstat64);
+hidden_ver (__xstat, __xstat64)
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/xstatconv.c b/libc/sysdeps/unix/sysv/linux/alpha/xstatconv.c
new file mode 100644
index 000000000..a193b62ad
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/xstatconv.c
@@ -0,0 +1,123 @@
+/* Convert between the kernel's `struct stat' format, and libc's.
+ Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+#include <xstatconv.h>
+
+
+int __libc_missing_axp_stat64;
+
+int
+__xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
+{
+ switch (vers)
+ {
+ case _STAT_VER_KERNEL:
+ *(struct kernel_stat *) ubuf = *kbuf;
+ break;
+
+ case _STAT_VER_GLIBC2:
+ {
+ struct glibc2_stat *buf = ubuf;
+
+ buf->st_dev = kbuf->st_dev;
+ buf->st_ino = kbuf->st_ino;
+ buf->st_mode = kbuf->st_mode;
+ buf->st_nlink = kbuf->st_nlink;
+ buf->st_uid = kbuf->st_uid;
+ buf->st_gid = kbuf->st_gid;
+ buf->st_rdev = kbuf->st_rdev;
+ buf->st_size = kbuf->st_size;
+ buf->st_atime = kbuf->st_atime;
+ buf->st_mtime = kbuf->st_mtime;
+ buf->st_ctime = kbuf->st_ctime;
+ buf->st_blksize = kbuf->st_blksize;
+ buf->st_blocks = kbuf->st_blocks;
+ buf->st_flags = kbuf->st_flags;
+ buf->st_gen = kbuf->st_gen;
+ }
+ break;
+
+ case _STAT_VER_GLIBC2_1:
+ {
+ struct glibc21_stat *buf = ubuf;
+
+ buf->st_dev = kbuf->st_dev;
+ buf->st_ino = kbuf->st_ino;
+ buf->st_mode = kbuf->st_mode;
+ buf->st_nlink = kbuf->st_nlink;
+ buf->st_uid = kbuf->st_uid;
+ buf->st_gid = kbuf->st_gid;
+ buf->st_rdev = kbuf->st_rdev;
+ buf->st_size = kbuf->st_size;
+ buf->st_atime = kbuf->st_atime;
+ buf->st_mtime = kbuf->st_mtime;
+ buf->st_ctime = kbuf->st_ctime;
+ buf->st_blocks = kbuf->st_blocks;
+ buf->st_blksize = kbuf->st_blksize;
+ buf->st_flags = kbuf->st_flags;
+ buf->st_gen = kbuf->st_gen;
+ buf->__pad3 = 0;
+ buf->__unused[0] = 0;
+ buf->__unused[1] = 0;
+ buf->__unused[2] = 0;
+ buf->__unused[3] = 0;
+ }
+ break;
+
+ case _STAT_VER_GLIBC2_3_4:
+ {
+ struct stat64 *buf = ubuf;
+
+ buf->st_dev = kbuf->st_dev;
+ buf->st_ino = kbuf->st_ino;
+ buf->st_rdev = kbuf->st_rdev;
+ buf->st_size = kbuf->st_size;
+ buf->st_blocks = kbuf->st_blocks;
+
+ buf->st_mode = kbuf->st_mode;
+ buf->st_uid = kbuf->st_uid;
+ buf->st_gid = kbuf->st_gid;
+ buf->st_blksize = kbuf->st_blksize;
+ buf->st_nlink = kbuf->st_nlink;
+ buf->__pad0 = 0;
+
+ buf->st_atime = kbuf->st_atime;
+ buf->st_atimensec = 0;
+ buf->st_mtime = kbuf->st_mtime;
+ buf->st_mtimensec = 0;
+ buf->st_ctime = kbuf->st_ctime;
+ buf->st_ctimensec = 0;
+
+ buf->__unused[0] = 0;
+ buf->__unused[1] = 0;
+ buf->__unused[2] = 0;
+ }
+ break;
+
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/alpha/xstatconv.h b/libc/sysdeps/unix/sysv/linux/alpha/xstatconv.h
new file mode 100644
index 000000000..094d11e5c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/alpha/xstatconv.h
@@ -0,0 +1,24 @@
+/* Convert between the kernel's `struct stat' format, and libc's.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <kernel-features.h>
+
+extern int __libc_missing_axp_stat64 attribute_hidden;
+extern int __xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
+ attribute_hidden;
diff --git a/libc/sysdeps/unix/sysv/linux/bind.S b/libc/sysdeps/unix/sysv/linux/bind.S
new file mode 100644
index 000000000..7719ad0be
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bind.S
@@ -0,0 +1,5 @@
+#define socket bind
+#define NARGS 3
+#define NO_WEAK_ALIAS 1
+#include <socket.S>
+weak_alias (bind, __bind)
diff --git a/libc/sysdeps/unix/sysv/linux/bits/a.out.h b/libc/sysdeps/unix/sysv/linux/bits/a.out.h
new file mode 100644
index 000000000..0e7fb030f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/a.out.h
@@ -0,0 +1,7 @@
+#ifndef __A_OUT_GNU_H__
+# error "Never use <bits/a.out.h> directly; include <a.out.h> instead."
+#endif
+
+/* Signal to users of this header that this architecture really doesn't
+ support a.out binary format. */
+#define __NO_A_OUT_SUPPORT 1
diff --git a/libc/sysdeps/unix/sysv/linux/bits/dirent.h b/libc/sysdeps/unix/sysv/linux/bits/dirent.h
new file mode 100644
index 000000000..76794b08d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/dirent.h
@@ -0,0 +1,53 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DIRENT_H
+# error "Never use <bits/dirent.h> directly; include <dirent.h> instead."
+#endif
+
+struct dirent
+ {
+#ifndef __USE_FILE_OFFSET64
+ __ino_t d_ino;
+ __off_t d_off;
+#else
+ __ino64_t d_ino;
+ __off64_t d_off;
+#endif
+ unsigned short int d_reclen;
+ unsigned char d_type;
+ char d_name[256]; /* We must not include limits.h! */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct dirent64
+ {
+ __ino64_t d_ino;
+ __off64_t d_off;
+ unsigned short int d_reclen;
+ unsigned char d_type;
+ char d_name[256]; /* We must not include limits.h! */
+ };
+#endif
+
+#define d_fileno d_ino /* Backwards compatibility. */
+
+#undef _DIRENT_HAVE_D_NAMLEN
+#define _DIRENT_HAVE_D_RECLEN
+#define _DIRENT_HAVE_D_OFF
+#define _DIRENT_HAVE_D_TYPE
diff --git a/libc/sysdeps/unix/sysv/linux/bits/errno.h b/libc/sysdeps/unix/sysv/linux/bits/errno.h
new file mode 100644
index 000000000..4de8cbba5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/errno.h
@@ -0,0 +1,59 @@
+/* Error constants. Linux specific version.
+ Copyright (C) 1996, 1997, 1998, 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef _ERRNO_H
+
+# undef EDOM
+# undef EILSEQ
+# undef ERANGE
+# include <linux/errno.h>
+
+/* Linux has no ENOTSUP error code. */
+# define ENOTSUP EOPNOTSUPP
+
+/* Older Linux versions also had no ECANCELED error code. */
+# ifndef ECANCELED
+# define ECANCELED 125
+# endif
+
+/* Support for error codes to support robust mutexes was added later, too. */
+# ifndef EOWNERDEAD
+# define EOWNERDEAD 130
+# define ENOTRECOVERABLE 131
+# endif
+
+# ifndef __ASSEMBLER__
+/* Function to get address of global `errno' variable. */
+extern int *__errno_location (void) __THROW __attribute__ ((__const__));
+
+# if !defined _LIBC || defined _LIBC_REENTRANT
+/* When using threads, errno is a per-thread value. */
+# define errno (*__errno_location ())
+# endif
+# endif /* !__ASSEMBLER__ */
+#endif /* _ERRNO_H */
+
+#if !defined _ERRNO_H && defined __need_Emath
+/* This is ugly but the kernel header is not clean enough. We must
+ define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
+ defined. */
+# define EDOM 33 /* Math argument out of domain of function. */
+# define EILSEQ 84 /* Illegal byte sequence. */
+# define ERANGE 34 /* Math result not representable. */
+#endif /* !_ERRNO_H && __need_Emath */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/fcntl.h b/libc/sysdeps/unix/sysv/linux/bits/fcntl.h
new file mode 100644
index 000000000..be40350e8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/fcntl.h
@@ -0,0 +1,3 @@
+/* bits/fcntl.h is architecture specific. */
+#error "This file must be supplied by every Linux architecture."
+
diff --git a/libc/sysdeps/unix/sysv/linux/bits/in.h b/libc/sysdeps/unix/sysv/linux/bits/in.h
new file mode 100644
index 000000000..6880a2e63
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/in.h
@@ -0,0 +1,170 @@
+/* Copyright (C) 1991-1999, 2000, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Linux version. */
+
+#ifndef _NETINET_IN_H
+# error "Never use <bits/in.h> directly; include <netinet/in.h> instead."
+#endif
+
+/* Options for use with `getsockopt' and `setsockopt' at the IP level.
+ The first word in the comment at the right is the data type used;
+ "bool" means a boolean value stored in an `int'. */
+#define IP_OPTIONS 4 /* ip_opts; IP per-packet options. */
+#define IP_HDRINCL 3 /* int; Header is included with data. */
+#define IP_TOS 1 /* int; IP type of service and precedence. */
+#define IP_TTL 2 /* int; IP time to live. */
+#define IP_RECVOPTS 6 /* bool; Receive all IP options w/datagram. */
+/* For BSD compatibility. */
+#define IP_RECVRETOPTS IP_RETOPTS /* bool; Receive IP options for response. */
+#define IP_RETOPTS 7 /* ip_opts; Set/get IP per-packet options. */
+#define IP_MULTICAST_IF 32 /* in_addr; set/get IP multicast i/f */
+#define IP_MULTICAST_TTL 33 /* u_char; set/get IP multicast ttl */
+#define IP_MULTICAST_LOOP 34 /* i_char; set/get IP multicast loopback */
+#define IP_ADD_MEMBERSHIP 35 /* ip_mreq; add an IP group membership */
+#define IP_DROP_MEMBERSHIP 36 /* ip_mreq; drop an IP group membership */
+#define IP_UNBLOCK_SOURCE 37 /* ip_mreq_source: unblock data from source */
+#define IP_BLOCK_SOURCE 38 /* ip_mreq_source: block data from source */
+#define IP_ADD_SOURCE_MEMBERSHIP 39 /* ip_mreq_source: join source group */
+#define IP_DROP_SOURCE_MEMBERSHIP 40 /* ip_mreq_source: leave source group */
+#define IP_MSFILTER 41
+#define MCAST_JOIN_GROUP 42 /* group_req: join any-source group */
+#define MCAST_BLOCK_SOURCE 43 /* group_source_req: block from given group */
+#define MCAST_UNBLOCK_SOURCE 44 /* group_source_req: unblock from given group*/
+#define MCAST_LEAVE_GROUP 45 /* group_req: leave any-source group */
+#define MCAST_JOIN_SOURCE_GROUP 46 /* group_source_req: join source-spec gr */
+#define MCAST_LEAVE_SOURCE_GROUP 47 /* group_source_req: leave source-spec gr*/
+#define MCAST_MSFILTER 48
+
+#define MCAST_EXCLUDE 0
+#define MCAST_INCLUDE 1
+
+#define IP_ROUTER_ALERT 5 /* bool */
+#define IP_PKTINFO 8 /* bool */
+#define IP_PKTOPTIONS 9
+#define IP_PMTUDISC 10 /* obsolete name? */
+#define IP_MTU_DISCOVER 10 /* int; see below */
+#define IP_RECVERR 11 /* bool */
+#define IP_RECVTTL 12 /* bool */
+#define IP_RECVTOS 13 /* bool */
+
+
+/* IP_MTU_DISCOVER arguments. */
+#define IP_PMTUDISC_DONT 0 /* Never send DF frames. */
+#define IP_PMTUDISC_WANT 1 /* Use per route hints. */
+#define IP_PMTUDISC_DO 2 /* Always DF. */
+
+/* To select the IP level. */
+#define SOL_IP 0
+
+#define IP_DEFAULT_MULTICAST_TTL 1
+#define IP_DEFAULT_MULTICAST_LOOP 1
+#define IP_MAX_MEMBERSHIPS 20
+
+/* Structure used to describe IP options for IP_OPTIONS and IP_RETOPTS.
+ The `ip_dst' field is used for the first-hop gateway when using a
+ source route (this gets put into the header proper). */
+struct ip_opts
+ {
+ struct in_addr ip_dst; /* First hop; zero without source route. */
+ char ip_opts[40]; /* Actually variable in size. */
+ };
+
+/* Like `struct ip_mreq' but including interface specification by index. */
+struct ip_mreqn
+ {
+ struct in_addr imr_multiaddr; /* IP multicast address of group */
+ struct in_addr imr_address; /* local IP address of interface */
+ int imr_ifindex; /* Interface index */
+ };
+
+/* Structure used for IP_PKTINFO. */
+struct in_pktinfo
+ {
+ int ipi_ifindex; /* Interface index */
+ struct in_addr ipi_spec_dst; /* Routing destination address */
+ struct in_addr ipi_addr; /* Header destination address */
+ };
+
+/* Options for use with `getsockopt' and `setsockopt' at the IPv6 level.
+ The first word in the comment at the right is the data type used;
+ "bool" means a boolean value stored in an `int'. */
+#define IPV6_ADDRFORM 1
+#define IPV6_2292PKTINFO 2
+#define IPV6_2292HOPOPTS 3
+#define IPV6_2292DSTOPTS 4
+#define IPV6_2292RTHDR 5
+#define IPV6_2292PKTOPTIONS 6
+#define IPV6_CHECKSUM 7
+#define IPV6_2292HOPLIMIT 8
+
+#define SCM_SRCRT IPV6_RXSRCRT
+
+#define IPV6_NEXTHOP 9
+#define IPV6_AUTHHDR 10
+#define IPV6_UNICAST_HOPS 16
+#define IPV6_MULTICAST_IF 17
+#define IPV6_MULTICAST_HOPS 18
+#define IPV6_MULTICAST_LOOP 19
+#define IPV6_JOIN_GROUP 20
+#define IPV6_LEAVE_GROUP 21
+#define IPV6_ROUTER_ALERT 22
+#define IPV6_MTU_DISCOVER 23
+#define IPV6_MTU 24
+#define IPV6_RECVERR 25
+#define IPV6_V6ONLY 26
+#define IPV6_JOIN_ANYCAST 27
+#define IPV6_LEAVE_ANYCAST 28
+#define IPV6_IPSEC_POLICY 34
+#define IPV6_XFRM_POLICY 35
+
+#define IPV6_RECVPKTINFO 49
+#define IPV6_PKTINFO 50
+#define IPV6_RECVHOPLIMIT 51
+#define IPV6_HOPLIMIT 52
+#define IPV6_RECVHOPOPTS 53
+#define IPV6_HOPOPTS 54
+#define IPV6_RTHDRDSTOPTS 55
+#define IPV6_RECVRTHDR 56
+#define IPV6_RTHDR 57
+#define IPV6_RECVDSTOPTS 58
+#define IPV6_DSTOPTS 59
+
+#define IPV6_RECVTCLASS 66
+#define IPV6_TCLASS 67
+
+/* Obsolete synonyms for the above. */
+#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
+#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
+#define IPV6_RXHOPOPTS IPV6_HOPOPTS
+#define IPV6_RXDSTOPTS IPV6_DSTOPTS
+
+/* IPV6_MTU_DISCOVER values. */
+#define IPV6_PMTUDISC_DONT 0 /* Never send DF frames. */
+#define IPV6_PMTUDISC_WANT 1 /* Use per route hints. */
+#define IPV6_PMTUDISC_DO 2 /* Always DF. */
+
+/* Socket level values for IPv6. */
+#define SOL_IPV6 41
+#define SOL_ICMPV6 58
+
+/* Routing header options for IPv6. */
+#define IPV6_RTHDR_LOOSE 0 /* Hop doesn't need to be neighbour. */
+#define IPV6_RTHDR_STRICT 1 /* Hop must be a neighbour. */
+
+#define IPV6_RTHDR_TYPE_0 0 /* IPv6 Routing header type 0. */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/initspin.h b/libc/sysdeps/unix/sysv/linux/bits/initspin.h
new file mode 100644
index 000000000..936f17849
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/initspin.h
@@ -0,0 +1 @@
+/* No thread support. */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/ioctl-types.h b/libc/sysdeps/unix/sysv/linux/bits/ioctl-types.h
new file mode 100644
index 000000000..e856a04b4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/ioctl-types.h
@@ -0,0 +1,78 @@
+/* Structure types for pre-termios terminal ioctls. Linux version.
+ Copyright (C) 1996, 1997, 1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IOCTL_H
+# error "Never use <bits/ioctl-types.h> directly; include <sys/ioctl.h> instead."
+#endif
+
+/* Get definition of constants for use with `ioctl'. */
+#include <asm/ioctls.h>
+
+
+struct winsize
+ {
+ unsigned short int ws_row;
+ unsigned short int ws_col;
+ unsigned short int ws_xpixel;
+ unsigned short int ws_ypixel;
+ };
+
+#define NCC 8
+struct termio
+ {
+ unsigned short int c_iflag; /* input mode flags */
+ unsigned short int c_oflag; /* output mode flags */
+ unsigned short int c_cflag; /* control mode flags */
+ unsigned short int c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6 /* X.25 async */
+#define N_6PACK 7
+#define N_MASC 8 /* Mobitex module */
+#define N_R3964 9 /* Simatic R3964 module */
+#define N_PROFIBUS_FDL 10 /* Profibus */
+#define N_IRDA 11 /* Linux IR */
+#define N_SMSBLOCK 12 /* SMS block mode */
+#define N_HDLC 13 /* synchronous HDLC */
+#define N_SYNC_PPP 14 /* synchronous PPP */
+#define N_HCI 15 /* Bluetooth HCI UART */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/ioctls.h b/libc/sysdeps/unix/sysv/linux/bits/ioctls.h
new file mode 100644
index 000000000..11bb4c485
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/ioctls.h
@@ -0,0 +1,109 @@
+/* Copyright (C) 1996, 1997, 1998, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IOCTL_H
+# error "Never use <bits/ioctls.h> directly; include <sys/ioctl.h> instead."
+#endif
+
+/* Use the definitions from the kernel header files. */
+#include <asm/ioctls.h>
+
+/* Routing table calls. */
+#define SIOCADDRT 0x890B /* add routing table entry */
+#define SIOCDELRT 0x890C /* delete routing table entry */
+#define SIOCRTMSG 0x890D /* call to routing system */
+
+/* Socket configuration controls. */
+#define SIOCGIFNAME 0x8910 /* get iface name */
+#define SIOCSIFLINK 0x8911 /* set iface channel */
+#define SIOCGIFCONF 0x8912 /* get iface list */
+#define SIOCGIFFLAGS 0x8913 /* get flags */
+#define SIOCSIFFLAGS 0x8914 /* set flags */
+#define SIOCGIFADDR 0x8915 /* get PA address */
+#define SIOCSIFADDR 0x8916 /* set PA address */
+#define SIOCGIFDSTADDR 0x8917 /* get remote PA address */
+#define SIOCSIFDSTADDR 0x8918 /* set remote PA address */
+#define SIOCGIFBRDADDR 0x8919 /* get broadcast PA address */
+#define SIOCSIFBRDADDR 0x891a /* set broadcast PA address */
+#define SIOCGIFNETMASK 0x891b /* get network PA mask */
+#define SIOCSIFNETMASK 0x891c /* set network PA mask */
+#define SIOCGIFMETRIC 0x891d /* get metric */
+#define SIOCSIFMETRIC 0x891e /* set metric */
+#define SIOCGIFMEM 0x891f /* get memory address (BSD) */
+#define SIOCSIFMEM 0x8920 /* set memory address (BSD) */
+#define SIOCGIFMTU 0x8921 /* get MTU size */
+#define SIOCSIFMTU 0x8922 /* set MTU size */
+#define SIOCSIFNAME 0x8923 /* set interface name */
+#define SIOCSIFHWADDR 0x8924 /* set hardware address */
+#define SIOCGIFENCAP 0x8925 /* get/set encapsulations */
+#define SIOCSIFENCAP 0x8926
+#define SIOCGIFHWADDR 0x8927 /* Get hardware address */
+#define SIOCGIFSLAVE 0x8929 /* Driver slaving support */
+#define SIOCSIFSLAVE 0x8930
+#define SIOCADDMULTI 0x8931 /* Multicast address lists */
+#define SIOCDELMULTI 0x8932
+#define SIOCGIFINDEX 0x8933 /* name -> if_index mapping */
+#define SIOGIFINDEX SIOCGIFINDEX /* misprint compatibility :-) */
+#define SIOCSIFPFLAGS 0x8934 /* set/get extended flags set */
+#define SIOCGIFPFLAGS 0x8935
+#define SIOCDIFADDR 0x8936 /* delete PA address */
+#define SIOCSIFHWBROADCAST 0x8937 /* set hardware broadcast addr */
+#define SIOCGIFCOUNT 0x8938 /* get number of devices */
+
+#define SIOCGIFBR 0x8940 /* Bridging support */
+#define SIOCSIFBR 0x8941 /* Set bridging options */
+
+#define SIOCGIFTXQLEN 0x8942 /* Get the tx queue length */
+#define SIOCSIFTXQLEN 0x8943 /* Set the tx queue length */
+
+
+/* ARP cache control calls. */
+ /* 0x8950 - 0x8952 * obsolete calls, don't re-use */
+#define SIOCDARP 0x8953 /* delete ARP table entry */
+#define SIOCGARP 0x8954 /* get ARP table entry */
+#define SIOCSARP 0x8955 /* set ARP table entry */
+
+/* RARP cache control calls. */
+#define SIOCDRARP 0x8960 /* delete RARP table entry */
+#define SIOCGRARP 0x8961 /* get RARP table entry */
+#define SIOCSRARP 0x8962 /* set RARP table entry */
+
+/* Driver configuration calls */
+
+#define SIOCGIFMAP 0x8970 /* Get device parameters */
+#define SIOCSIFMAP 0x8971 /* Set device parameters */
+
+/* DLCI configuration calls */
+
+#define SIOCADDDLCI 0x8980 /* Create new DLCI device */
+#define SIOCDELDLCI 0x8981 /* Delete DLCI device */
+
+/* Device private ioctl calls. */
+
+/* These 16 ioctls are available to devices via the do_ioctl() device
+ vector. Each device should include this file and redefine these
+ names as their own. Because these are device dependent it is a good
+ idea _NOT_ to issue them to random objects and hope. */
+
+#define SIOCDEVPRIVATE 0x89F0 /* to 89FF */
+
+/*
+ * These 16 ioctl calls are protocol private
+ */
+
+#define SIOCPROTOPRIVATE 0x89E0 /* to 89EF */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/ipc.h b/libc/sysdeps/unix/sysv/linux/bits/ipc.h
new file mode 100644
index 000000000..f1a043fe5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/ipc.h
@@ -0,0 +1,56 @@
+/* Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IPC_H
+# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Mode bits for `msgget', `semget', and `shmget'. */
+#define IPC_CREAT 01000 /* Create key if key does not exist. */
+#define IPC_EXCL 02000 /* Fail if key exists. */
+#define IPC_NOWAIT 04000 /* Return error on wait. */
+
+/* Control commands for `msgctl', `semctl', and `shmctl'. */
+#define IPC_RMID 0 /* Remove identifier. */
+#define IPC_SET 1 /* Set `ipc_perm' options. */
+#define IPC_STAT 2 /* Get `ipc_perm' options. */
+#ifdef __USE_GNU
+# define IPC_INFO 3 /* See ipcs. */
+#endif
+
+/* Special key values. */
+#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
+
+
+/* Data structure used to pass permission information to IPC operations. */
+struct ipc_perm
+ {
+ __key_t __key; /* Key. */
+ __uid_t uid; /* Owner's user ID. */
+ __gid_t gid; /* Owner's group ID. */
+ __uid_t cuid; /* Creator's user ID. */
+ __gid_t cgid; /* Creator's group ID. */
+ unsigned short int mode; /* Read/write permission. */
+ unsigned short int __pad1;
+ unsigned short int __seq; /* Sequence number. */
+ unsigned short int __pad2;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ };
diff --git a/libc/sysdeps/unix/sysv/linux/bits/local_lim.h b/libc/sysdeps/unix/sysv/linux/bits/local_lim.h
new file mode 100644
index 000000000..54a51ee76
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/local_lim.h
@@ -0,0 +1,68 @@
+/* Minimum guaranteed maximum values for system limits. Linux version.
+ Copyright (C) 1993-1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The kernel header pollutes the namespace with the NR_OPEN symbol
+ and defines LINK_MAX although filesystems have different maxima. A
+ similar thing is true for OPEN_MAX: the limit can be changed at
+ runtime and therefore the macro must not be defined. Remove this
+ after including the header if necessary. */
+#ifndef NR_OPEN
+# define __undef_NR_OPEN
+#endif
+#ifndef LINK_MAX
+# define __undef_LINK_MAX
+#endif
+#ifndef OPEN_MAX
+# define __undef_OPEN_MAX
+#endif
+
+/* The kernel sources contain a file with all the needed information. */
+#include <linux/limits.h>
+
+/* Have to remove NR_OPEN? */
+#ifdef __undef_NR_OPEN
+# undef NR_OPEN
+# undef __undef_NR_OPEN
+#endif
+/* Have to remove LINK_MAX? */
+#ifdef __undef_LINK_MAX
+# undef LINK_MAX
+# undef __undef_LINK_MAX
+#endif
+/* Have to remove OPEN_MAX? */
+#ifdef __undef_OPEN_MAX
+# undef OPEN_MAX
+# undef __undef_OPEN_MAX
+#endif
+
+/* Maximum amount by which a process can descrease its asynchronous I/O
+ priority level. */
+#define AIO_PRIO_DELTA_MAX 20
+
+/* Maximum tty name length. */
+#define TTY_NAME_MAX 32
+
+/* Maximum login name length. This is arbitrary. */
+#define LOGIN_NAME_MAX 256
+
+/* Maximum host name length. */
+#define HOST_NAME_MAX 64
+
+/* Maximum message queue priority level. */
+#define MQ_PRIO_MAX 32768
diff --git a/libc/sysdeps/unix/sysv/linux/bits/mqueue.h b/libc/sysdeps/unix/sysv/linux/bits/mqueue.h
new file mode 100644
index 000000000..df528f876
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/mqueue.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MQUEUE_H
+# error "Never use <bits/mqueue.h> directly; include <mqueue.h> instead."
+#endif
+
+typedef int mqd_t;
+
+struct mq_attr
+{
+ long int mq_flags; /* Message queue flags. */
+ long int mq_maxmsg; /* Maximum number of messages. */
+ long int mq_msgsize; /* Maximum message size. */
+ long int mq_curmsgs; /* Number of messages currently queued. */
+ long int __pad[4];
+};
diff --git a/libc/sysdeps/unix/sysv/linux/bits/msq.h b/libc/sysdeps/unix/sysv/linux/bits/msq.h
new file mode 100644
index 000000000..32a49b592
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/msq.h
@@ -0,0 +1,77 @@
+/* Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Define options for message queue functions. */
+#define MSG_NOERROR 010000 /* no error if message is too big */
+#ifdef __USE_GNU
+# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+#endif
+
+/* Types used in the structure definition. */
+typedef unsigned long int msgqnum_t;
+typedef unsigned long int msglen_t;
+
+
+/* Structure of record for one message inside the kernel.
+ The type `struct msg' is opaque. */
+struct msqid_ds
+{
+ struct ipc_perm msg_perm; /* structure describing operation permission */
+ __time_t msg_stime; /* time of last msgsnd command */
+ unsigned long int __unused1;
+ __time_t msg_rtime; /* time of last msgrcv command */
+ unsigned long int __unused2;
+ __time_t msg_ctime; /* time of last change */
+ unsigned long int __unused3;
+ unsigned long int __msg_cbytes; /* current number of bytes on queue */
+ msgqnum_t msg_qnum; /* number of messages currently on queue */
+ msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+ __pid_t msg_lspid; /* pid of last msgsnd() */
+ __pid_t msg_lrpid; /* pid of last msgrcv() */
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+};
+
+#ifdef __USE_MISC
+
+# define msg_cbytes __msg_cbytes
+
+/* ipcs ctl commands */
+# define MSG_STAT 11
+# define MSG_INFO 12
+
+/* buffer for msgctl calls IPC_INFO, MSG_INFO */
+struct msginfo
+ {
+ int msgpool;
+ int msgmap;
+ int msgmax;
+ int msgmnb;
+ int msgmni;
+ int msgssz;
+ int msgtql;
+ unsigned short int msgseg;
+ };
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/poll.h b/libc/sysdeps/unix/sysv/linux/bits/poll.h
new file mode 100644
index 000000000..d7996b46c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/poll.h
@@ -0,0 +1,50 @@
+/* Copyright (C) 1997, 2001, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_POLL_H
+# error "Never use <bits/poll.h> directly; include <sys/poll.h> instead."
+#endif
+
+/* Event types that can be polled for. These bits may be set in `events'
+ to indicate the interesting event types; they will appear in `revents'
+ to indicate the status of the file descriptor. */
+#define POLLIN 0x001 /* There is data to read. */
+#define POLLPRI 0x002 /* There is urgent data to read. */
+#define POLLOUT 0x004 /* Writing now will not block. */
+
+#ifdef __USE_XOPEN
+/* These values are defined in XPG4.2. */
+# define POLLRDNORM 0x040 /* Normal data may be read. */
+# define POLLRDBAND 0x080 /* Priority data may be read. */
+# define POLLWRNORM 0x100 /* Writing now will not block. */
+# define POLLWRBAND 0x200 /* Priority data may be written. */
+#endif
+
+#ifdef __USE_GNU
+/* These are extensions for Linux. */
+# define POLLMSG 0x400
+# define POLLREMOVE 0x1000
+# define POLLRDHUP 0x2000
+#endif
+
+/* Event types always implicitly polled for. These bits need not be set in
+ `events', but they will appear in `revents' to indicate the status of
+ the file descriptor. */
+#define POLLERR 0x008 /* Error condition. */
+#define POLLHUP 0x010 /* Hung up. */
+#define POLLNVAL 0x020 /* Invalid polling request. */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/posix_opt.h b/libc/sysdeps/unix/sysv/linux/bits/posix_opt.h
new file mode 100644
index 000000000..1a96db298
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/posix_opt.h
@@ -0,0 +1,96 @@
+/* Define POSIX options for Linux.
+ Copyright (C) 1996,1997,1999,2000,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * Never include this file directly; use <unistd.h> instead.
+ */
+
+#ifndef _BITS_POSIX_OPT_H
+#define _BITS_POSIX_OPT_H 1
+
+/* Job control is supported. */
+#define _POSIX_JOB_CONTROL 1
+
+/* Processes have a saved set-user-ID and a saved set-group-ID. */
+#define _POSIX_SAVED_IDS 1
+
+/* Priority scheduling is supported. */
+#define _POSIX_PRIORITY_SCHEDULING 200112L
+
+/* Synchronizing file data is supported. */
+#define _POSIX_SYNCHRONIZED_IO 200112L
+
+/* The fsync function is present. */
+#define _POSIX_FSYNC 200112L
+
+/* Mapping of files to memory is supported. */
+#define _POSIX_MAPPED_FILES 200112L
+
+/* Locking of all memory is supported. */
+#define _POSIX_MEMLOCK 200112L
+
+/* Locking of ranges of memory is supported. */
+#define _POSIX_MEMLOCK_RANGE 200112L
+
+/* Setting of memory protections is supported. */
+#define _POSIX_MEMORY_PROTECTION 200112L
+
+/* Only root can change owner of file. */
+#define _POSIX_CHOWN_RESTRICTED 1
+
+/* `c_cc' member of 'struct termios' structure can be disabled by
+ using the value _POSIX_VDISABLE. */
+#define _POSIX_VDISABLE '\0'
+
+/* Filenames are not silently truncated. */
+#define _POSIX_NO_TRUNC 1
+
+/* X/Open realtime support is available. */
+#define _XOPEN_REALTIME 1
+
+/* XPG4.2 shared memory is supported. */
+#define _XOPEN_SHM 1
+
+/* Real-time signals are supported. */
+#define _POSIX_REALTIME_SIGNALS 200112L
+
+/* The LFS interface is available, except for the asynchronous I/O. */
+#define _LFS_LARGEFILE 1
+#define _LFS64_LARGEFILE 1
+#define _LFS64_STDIO 1
+
+/* POSIX timers are available. */
+#define _POSIX_TIMERS 200112L
+
+/* POSIX shared memory objects are implemented. */
+#define _POSIX_SHARED_MEMORY_OBJECTS 200112L
+
+/* GNU libc provides regular expression handling. */
+#define _POSIX_REGEXP 1
+
+/* We have a POSIX shell. */
+#define _POSIX_SHELL 1
+
+/* The `spawn' function family is supported. */
+#define _POSIX_SPAWN 200112L
+
+/* The monotonic clock might be available. */
+#define _POSIX_MONOTONIC_CLOCK 0
+
+#endif /* bits/posix_opt.h */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/resource.h b/libc/sysdeps/unix/sysv/linux/bits/resource.h
new file mode 100644
index 000000000..526cdaf53
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/resource.h
@@ -0,0 +1,225 @@
+/* Bit values & structures for resource limits. Linux version.
+ Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2004, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_RESOURCE_H
+# error "Never use <bits/resource.h> directly; include <sys/resource.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Transmute defines to enumerations. The macro re-definitions are
+ necessary because some programs want to test for operating system
+ features with #ifdef RUSAGE_SELF. In ISO C the reflexive
+ definition is a no-op. */
+
+/* Kinds of resource limit. */
+enum __rlimit_resource
+{
+ /* Per-process CPU limit, in seconds. */
+ RLIMIT_CPU = 0,
+#define RLIMIT_CPU RLIMIT_CPU
+
+ /* Largest file that can be created, in bytes. */
+ RLIMIT_FSIZE = 1,
+#define RLIMIT_FSIZE RLIMIT_FSIZE
+
+ /* Maximum size of data segment, in bytes. */
+ RLIMIT_DATA = 2,
+#define RLIMIT_DATA RLIMIT_DATA
+
+ /* Maximum size of stack segment, in bytes. */
+ RLIMIT_STACK = 3,
+#define RLIMIT_STACK RLIMIT_STACK
+
+ /* Largest core file that can be created, in bytes. */
+ RLIMIT_CORE = 4,
+#define RLIMIT_CORE RLIMIT_CORE
+
+ /* Largest resident set size, in bytes.
+ This affects swapping; processes that are exceeding their
+ resident set size will be more likely to have physical memory
+ taken from them. */
+ __RLIMIT_RSS = 5,
+#define RLIMIT_RSS __RLIMIT_RSS
+
+ /* Number of open files. */
+ RLIMIT_NOFILE = 7,
+ __RLIMIT_OFILE = RLIMIT_NOFILE, /* BSD name for same. */
+#define RLIMIT_NOFILE RLIMIT_NOFILE
+#define RLIMIT_OFILE __RLIMIT_OFILE
+
+ /* Address space limit. */
+ RLIMIT_AS = 9,
+#define RLIMIT_AS RLIMIT_AS
+
+ /* Number of processes. */
+ __RLIMIT_NPROC = 6,
+#define RLIMIT_NPROC __RLIMIT_NPROC
+
+ /* Locked-in-memory address space. */
+ __RLIMIT_MEMLOCK = 8,
+#define RLIMIT_MEMLOCK __RLIMIT_MEMLOCK
+
+ /* Maximum number of file locks. */
+ __RLIMIT_LOCKS = 10,
+#define RLIMIT_LOCKS __RLIMIT_LOCKS
+
+ /* Maximum number of pending signals. */
+ __RLIMIT_SIGPENDING = 11,
+#define RLIMIT_SIGPENDING __RLIMIT_SIGPENDING
+
+ /* Maximum bytes in POSIX message queues. */
+ __RLIMIT_MSGQUEUE = 12,
+#define RLIMIT_MSGQUEUE __RLIMIT_MSGQUEUE
+
+ /* Maximum nice priority allowed to raise to.
+ Nice levels 19 .. -20 correspond to 0 .. 39
+ values of this resource limit. */
+ __RLIMIT_NICE = 13,
+#define RLIMIT_NICE __RLIMIT_NICE
+
+ /* Maximum realtime priority allowed for non-priviledged
+ processes. */
+ __RLIMIT_RTPRIO = 14,
+#define RLIMIT_RTPRIO __RLIMIT_RTPRIO
+
+ __RLIMIT_NLIMITS = 15,
+ __RLIM_NLIMITS = __RLIMIT_NLIMITS
+#define RLIMIT_NLIMITS __RLIMIT_NLIMITS
+#define RLIM_NLIMITS __RLIM_NLIMITS
+};
+
+/* Value to indicate that there is no limit. */
+#ifndef __USE_FILE_OFFSET64
+# define RLIM_INFINITY ((unsigned long int)(~0UL))
+#else
+# define RLIM_INFINITY 0xffffffffffffffffuLL
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define RLIM64_INFINITY 0xffffffffffffffffuLL
+#endif
+
+/* We can represent all limits. */
+#define RLIM_SAVED_MAX RLIM_INFINITY
+#define RLIM_SAVED_CUR RLIM_INFINITY
+
+
+/* Type for resource quantity measurement. */
+#ifndef __USE_FILE_OFFSET64
+typedef __rlim_t rlim_t;
+#else
+typedef __rlim64_t rlim_t;
+#endif
+#ifdef __USE_LARGEFILE64
+typedef __rlim64_t rlim64_t;
+#endif
+
+struct rlimit
+ {
+ /* The current (soft) limit. */
+ rlim_t rlim_cur;
+ /* The hard limit. */
+ rlim_t rlim_max;
+ };
+
+#ifdef __USE_LARGEFILE64
+struct rlimit64
+ {
+ /* The current (soft) limit. */
+ rlim64_t rlim_cur;
+ /* The hard limit. */
+ rlim64_t rlim_max;
+ };
+#endif
+
+/* Whose usage statistics do you want? */
+enum __rusage_who
+{
+ /* The calling process. */
+ RUSAGE_SELF = 0,
+#define RUSAGE_SELF RUSAGE_SELF
+
+ /* All of its terminated child processes. */
+ RUSAGE_CHILDREN = -1
+#define RUSAGE_CHILDREN RUSAGE_CHILDREN
+};
+
+#define __need_timeval
+#include <bits/time.h> /* For `struct timeval'. */
+
+/* Structure which says how much of each resource has been used. */
+struct rusage
+ {
+ /* Total amount of user time used. */
+ struct timeval ru_utime;
+ /* Total amount of system time used. */
+ struct timeval ru_stime;
+ /* Maximum resident set size (in kilobytes). */
+ long int ru_maxrss;
+ /* Amount of sharing of text segment memory
+ with other processes (kilobyte-seconds). */
+ long int ru_ixrss;
+ /* Amount of data segment memory used (kilobyte-seconds). */
+ long int ru_idrss;
+ /* Amount of stack memory used (kilobyte-seconds). */
+ long int ru_isrss;
+ /* Number of soft page faults (i.e. those serviced by reclaiming
+ a page from the list of pages awaiting reallocation. */
+ long int ru_minflt;
+ /* Number of hard page faults (i.e. those that required I/O). */
+ long int ru_majflt;
+ /* Number of times a process was swapped out of physical memory. */
+ long int ru_nswap;
+ /* Number of input operations via the file system. Note: This
+ and `ru_oublock' do not include operations with the cache. */
+ long int ru_inblock;
+ /* Number of output operations via the file system. */
+ long int ru_oublock;
+ /* Number of IPC messages sent. */
+ long int ru_msgsnd;
+ /* Number of IPC messages received. */
+ long int ru_msgrcv;
+ /* Number of signals delivered. */
+ long int ru_nsignals;
+ /* Number of voluntary context switches, i.e. because the process
+ gave up the process before it had to (usually to wait for some
+ resource to be available). */
+ long int ru_nvcsw;
+ /* Number of involuntary context switches, i.e. a higher priority process
+ became runnable or the current process used up its time slice. */
+ long int ru_nivcsw;
+ };
+
+/* Priority limits. */
+#define PRIO_MIN -20 /* Minimum priority a process can have. */
+#define PRIO_MAX 20 /* Maximum priority a process can have. */
+
+/* The type of the WHICH argument to `getpriority' and `setpriority',
+ indicating what flavor of entity the WHO argument specifies. */
+enum __priority_which
+{
+ PRIO_PROCESS = 0, /* WHO is a process ID. */
+#define PRIO_PROCESS PRIO_PROCESS
+ PRIO_PGRP = 1, /* WHO is a process group ID. */
+#define PRIO_PGRP PRIO_PGRP
+ PRIO_USER = 2 /* WHO is a user ID. */
+#define PRIO_USER PRIO_USER
+};
diff --git a/libc/sysdeps/unix/sysv/linux/bits/sched.h b/libc/sysdeps/unix/sysv/linux/bits/sched.h
new file mode 100644
index 000000000..4a95a263f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/sched.h
@@ -0,0 +1,130 @@
+/* Definitions of constants and data structure for POSIX 1003.1b-1993
+ scheduling interface.
+ Copyright (C) 1996-1999,2001-2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __need_schedparam
+
+#ifndef _SCHED_H
+# error "Never include <bits/sched.h> directly; use <sched.h> instead."
+#endif
+
+
+/* Scheduling algorithms. */
+#define SCHED_OTHER 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#ifdef __USE_GNU
+# define SCHED_BATCH 3
+#endif
+
+#ifdef __USE_MISC
+/* Cloning flags. */
+# define CSIGNAL 0x000000ff /* Signal mask to be sent at exit. */
+# define CLONE_VM 0x00000100 /* Set if VM shared between processes. */
+# define CLONE_FS 0x00000200 /* Set if fs info shared between processes. */
+# define CLONE_FILES 0x00000400 /* Set if open files shared between processes. */
+# define CLONE_SIGHAND 0x00000800 /* Set if signal handlers shared. */
+# define CLONE_PTRACE 0x00002000 /* Set if tracing continues on the child. */
+# define CLONE_VFORK 0x00004000 /* Set if the parent wants the child to
+ wake it up on mm_release. */
+# define CLONE_PARENT 0x00008000 /* Set if we want to have the same
+ parent as the cloner. */
+# define CLONE_THREAD 0x00010000 /* Set to add to same thread group. */
+# define CLONE_NEWNS 0x00020000 /* Set to create new namespace. */
+# define CLONE_SYSVSEM 0x00040000 /* Set to shared SVID SEM_UNDO semantics. */
+# define CLONE_SETTLS 0x00080000 /* Set TLS info. */
+# define CLONE_PARENT_SETTID 0x00100000 /* Store TID in userlevel buffer
+ before MM copy. */
+# define CLONE_CHILD_CLEARTID 0x00200000 /* Register exit futex and memory
+ location to clear. */
+# define CLONE_DETACHED 0x00400000 /* Create clone detached. */
+# define CLONE_UNTRACED 0x00800000 /* Set if the tracing process can't
+ force CLONE_PTRACE on this clone. */
+# define CLONE_CHILD_SETTID 0x01000000 /* Store TID in userlevel buffer in
+ the child. */
+# define CLONE_STOPPED 0x02000000 /* Start in stopped state. */
+#endif
+
+/* The official definition. */
+struct sched_param
+ {
+ int __sched_priority;
+ };
+
+__BEGIN_DECLS
+
+#ifdef __USE_MISC
+/* Clone current process. */
+extern int clone (int (*__fn) (void *__arg), void *__child_stack,
+ int __flags, void *__arg, ...) __THROW;
+
+/* Unshare the specified resources. */
+extern int unshare (int __flags) __THROW;
+#endif
+
+__END_DECLS
+
+#endif /* need schedparam */
+
+#if !defined __defined_schedparam \
+ && (defined __need_schedparam || defined _SCHED_H)
+# define __defined_schedparam 1
+/* Data structure to describe a process' schedulability. */
+struct __sched_param
+ {
+ int __sched_priority;
+ };
+# undef __need_schedparam
+#endif
+
+
+#if defined _SCHED_H && !defined __cpu_set_t_defined
+# define __cpu_set_t_defined
+/* Size definition for CPU sets. */
+# define __CPU_SETSIZE 1024
+# define __NCPUBITS (8 * sizeof (__cpu_mask))
+
+/* Type for array elements in 'cpu_set'. */
+typedef unsigned long int __cpu_mask;
+
+/* Basic access functions. */
+# define __CPUELT(cpu) ((cpu) / __NCPUBITS)
+# define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS))
+
+/* Data structure to describe CPU mask. */
+typedef struct
+{
+ __cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];
+} cpu_set_t;
+
+/* Access functions for CPU masks. */
+# define __CPU_ZERO(cpusetp) \
+ do { \
+ unsigned int __i; \
+ cpu_set_t *__arr = (cpusetp); \
+ for (__i = 0; __i < sizeof (cpu_set_t) / sizeof (__cpu_mask); ++__i) \
+ __arr->__bits[__i] = 0; \
+ } while (0)
+# define __CPU_SET(cpu, cpusetp) \
+ ((cpusetp)->__bits[__CPUELT (cpu)] |= __CPUMASK (cpu))
+# define __CPU_CLR(cpu, cpusetp) \
+ ((cpusetp)->__bits[__CPUELT (cpu)] &= ~__CPUMASK (cpu))
+# define __CPU_ISSET(cpu, cpusetp) \
+ (((cpusetp)->__bits[__CPUELT (cpu)] & __CPUMASK (cpu)) != 0)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/bits/sem.h b/libc/sysdeps/unix/sysv/linux/bits/sem.h
new file mode 100644
index 000000000..6193501e2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/sem.h
@@ -0,0 +1,87 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SEM_H
+# error "Never include <bits/sem.h> directly; use <sys/sem.h> instead."
+#endif
+
+#include <sys/types.h>
+
+/* Flags for `semop'. */
+#define SEM_UNDO 0x1000 /* undo the operation on exit */
+
+/* Commands for `semctl'. */
+#define GETPID 11 /* get sempid */
+#define GETVAL 12 /* get semval */
+#define GETALL 13 /* get all semval's */
+#define GETNCNT 14 /* get semncnt */
+#define GETZCNT 15 /* get semzcnt */
+#define SETVAL 16 /* set semval */
+#define SETALL 17 /* set all semval's */
+
+
+/* Data structure describing a set of semaphores. */
+struct semid_ds
+{
+ struct ipc_perm sem_perm; /* operation permission struct */
+ __time_t sem_otime; /* last semop() time */
+ unsigned long int __unused1;
+ __time_t sem_ctime; /* last time changed by semctl() */
+ unsigned long int __unused2;
+ unsigned long int sem_nsems; /* number of semaphores in set */
+ unsigned long int __unused3;
+ unsigned long int __unused4;
+};
+
+/* The user should define a union like the following to use it for arguments
+ for `semctl'.
+
+ union semun
+ {
+ int val; <= value for SETVAL
+ struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET
+ unsigned short int *array; <= array for GETALL & SETALL
+ struct seminfo *__buf; <= buffer for IPC_INFO
+ };
+
+ Previous versions of this file used to define this union but this is
+ incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether
+ one must define the union or not. */
+#define _SEM_SEMUN_UNDEFINED 1
+
+#ifdef __USE_MISC
+
+/* ipcs ctl cmds */
+# define SEM_STAT 18
+# define SEM_INFO 19
+
+struct seminfo
+{
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvmx;
+ int semaem;
+};
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/shm.h b/libc/sysdeps/unix/sysv/linux/bits/shm.h
new file mode 100644
index 000000000..318d601ae
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/shm.h
@@ -0,0 +1,103 @@
+/* Copyright (C) 1995,1996,1997,2000,2002,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple. */
+#define SHMLBA (__getpagesize ())
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a set of semaphores. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+ size_t shm_segsz; /* size of segment in bytes */
+ __time_t shm_atime; /* time of last shmat() */
+ unsigned long int __unused1;
+ __time_t shm_dtime; /* time of last shmdt() */
+ unsigned long int __unused2;
+ __time_t shm_ctime; /* time of last change by shmctl() */
+ unsigned long int __unused3;
+ __pid_t shm_cpid; /* pid of creator */
+ __pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */
+# define SHM_NORESERVE 010000 /* don't check for reservations */
+
+struct shminfo
+ {
+ unsigned long int shmmax;
+ unsigned long int shmmin;
+ unsigned long int shmmni;
+ unsigned long int shmseg;
+ unsigned long int shmall;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ unsigned long int __unused3;
+ unsigned long int __unused4;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/bits/sigaction.h b/libc/sysdeps/unix/sysv/linux/bits/sigaction.h
new file mode 100644
index 000000000..48cc5312f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/sigaction.h
@@ -0,0 +1,77 @@
+/* The proper definitions for Linux's sigaction.
+ Copyright (C) 1993-1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIGNAL_H
+# error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
+#endif
+
+/* Structure describing the action to be taken when a signal arrives. */
+struct sigaction
+ {
+ /* Signal handler. */
+#ifdef __USE_POSIX199309
+ union
+ {
+ /* Used if SA_SIGINFO is not set. */
+ __sighandler_t sa_handler;
+ /* Used if SA_SIGINFO is set. */
+ void (*sa_sigaction) (int, siginfo_t *, void *);
+ }
+ __sigaction_handler;
+# define sa_handler __sigaction_handler.sa_handler
+# define sa_sigaction __sigaction_handler.sa_sigaction
+#else
+ __sighandler_t sa_handler;
+#endif
+
+ /* Additional set of signals to be blocked. */
+ __sigset_t sa_mask;
+
+ /* Special flags. */
+ int sa_flags;
+
+ /* Restore handler. */
+ void (*sa_restorer) (void);
+ };
+
+/* Bits in `sa_flags'. */
+#define SA_NOCLDSTOP 1 /* Don't send SIGCHLD when children stop. */
+#define SA_NOCLDWAIT 2 /* Don't create zombie on child death. */
+#define SA_SIGINFO 4 /* Invoke signal-catching function with
+ three arguments instead of one. */
+#if defined __USE_UNIX98 || defined __USE_MISC
+# define SA_ONSTACK 0x08000000 /* Use signal stack by using `sa_restorer'. */
+# define SA_RESTART 0x10000000 /* Restart syscall on signal return. */
+# define SA_NODEFER 0x40000000 /* Don't automatically block the signal when
+ its handler is being executed. */
+# define SA_RESETHAND 0x80000000 /* Reset to SIG_DFL on entry to handler. */
+#endif
+#ifdef __USE_MISC
+# define SA_INTERRUPT 0x20000000 /* Historical no-op. */
+
+/* Some aliases for the SA_ constants. */
+# define SA_NOMASK SA_NODEFER
+# define SA_ONESHOT SA_RESETHAND
+# define SA_STACK SA_ONSTACK
+#endif
+
+/* Values for the HOW argument to `sigprocmask'. */
+#define SIG_BLOCK 0 /* Block signals. */
+#define SIG_UNBLOCK 1 /* Unblock signals. */
+#define SIG_SETMASK 2 /* Set the set of blocked signals. */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/sigcontext.h b/libc/sysdeps/unix/sysv/linux/bits/sigcontext.h
new file mode 100644
index 000000000..67dcf9498
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/sigcontext.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
+# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
+#endif
+
+#ifndef sigcontext_struct
+/* Kernel headers before 2.1.1 define a struct sigcontext_struct, but
+ we need sigcontext. */
+# define sigcontext_struct sigcontext
+
+# include <asm/sigcontext.h>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/bits/siginfo.h b/libc/sysdeps/unix/sysv/linux/bits/siginfo.h
new file mode 100644
index 000000000..4ce319dc9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/siginfo.h
@@ -0,0 +1,313 @@
+/* siginfo_t, sigevent and constants. Linux version.
+ Copyright (C) 1997-2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _SIGNAL_H && !defined __need_siginfo_t \
+ && !defined __need_sigevent_t
+# error "Never include this file directly. Use <signal.h> instead"
+#endif
+
+#include <bits/wordsize.h>
+
+#if (!defined __have_sigval_t \
+ && (defined _SIGNAL_H || defined __need_siginfo_t \
+ || defined __need_sigevent_t))
+# define __have_sigval_t 1
+
+/* Type for data associated with a signal. */
+typedef union sigval
+ {
+ int sival_int;
+ void *sival_ptr;
+ } sigval_t;
+#endif
+
+#if (!defined __have_siginfo_t \
+ && (defined _SIGNAL_H || defined __need_siginfo_t))
+# define __have_siginfo_t 1
+
+# define __SI_MAX_SIZE 128
+# if __WORDSIZE == 64
+# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
+# else
+# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
+# endif
+
+typedef struct siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_errno; /* If non-zero, an errno value associated with
+ this signal, as defined in <errno.h>. */
+ int si_code; /* Signal code. */
+
+ union
+ {
+ int _pad[__SI_PAD_SIZE];
+
+ /* kill(). */
+ struct
+ {
+ __pid_t si_pid; /* Sending process ID. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ } _kill;
+
+ /* POSIX.1b timers. */
+ struct
+ {
+ int si_tid; /* Timer ID. */
+ int si_overrun; /* Overrun count. */
+ sigval_t si_sigval; /* Signal value. */
+ } _timer;
+
+ /* POSIX.1b signals. */
+ struct
+ {
+ __pid_t si_pid; /* Sending process ID. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ sigval_t si_sigval; /* Signal value. */
+ } _rt;
+
+ /* SIGCHLD. */
+ struct
+ {
+ __pid_t si_pid; /* Which child. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ int si_status; /* Exit value or signal. */
+ __clock_t si_utime;
+ __clock_t si_stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
+ struct
+ {
+ void *si_addr; /* Faulting insn/memory ref. */
+ } _sigfault;
+
+ /* SIGPOLL. */
+ struct
+ {
+ long int si_band; /* Band event for SIGPOLL. */
+ int si_fd;
+ } _sigpoll;
+ } _sifields;
+ } siginfo_t;
+
+
+/* X/Open requires some more fields with fixed names. */
+# define si_pid _sifields._kill.si_pid
+# define si_uid _sifields._kill.si_uid
+# define si_timerid _sifields._timer.si_tid
+# define si_overrun _sifields._timer.si_overrun
+# define si_status _sifields._sigchld.si_status
+# define si_utime _sifields._sigchld.si_utime
+# define si_stime _sifields._sigchld.si_stime
+# define si_value _sifields._rt.si_sigval
+# define si_int _sifields._rt.si_sigval.sival_int
+# define si_ptr _sifields._rt.si_sigval.sival_ptr
+# define si_addr _sifields._sigfault.si_addr
+# define si_band _sifields._sigpoll.si_band
+# define si_fd _sifields._sigpoll.si_fd
+
+
+/* Values for `si_code'. Positive values are reserved for kernel-generated
+ signals. */
+enum
+{
+ SI_ASYNCNL = -60, /* Sent by asynch name lookup completion. */
+# define SI_ASYNCNL SI_ASYNCNL
+ SI_TKILL = -6, /* Sent by tkill. */
+# define SI_TKILL SI_TKILL
+ SI_SIGIO, /* Sent by queued SIGIO. */
+# define SI_SIGIO SI_SIGIO
+ SI_ASYNCIO, /* Sent by AIO completion. */
+# define SI_ASYNCIO SI_ASYNCIO
+ SI_MESGQ, /* Sent by real time mesq state change. */
+# define SI_MESGQ SI_MESGQ
+ SI_TIMER, /* Sent by timer expiration. */
+# define SI_TIMER SI_TIMER
+ SI_QUEUE, /* Sent by sigqueue. */
+# define SI_QUEUE SI_QUEUE
+ SI_USER, /* Sent by kill, sigsend, raise. */
+# define SI_USER SI_USER
+ SI_KERNEL = 0x80 /* Send by kernel. */
+#define SI_KERNEL SI_KERNEL
+};
+
+
+/* `si_code' values for SIGILL signal. */
+enum
+{
+ ILL_ILLOPC = 1, /* Illegal opcode. */
+# define ILL_ILLOPC ILL_ILLOPC
+ ILL_ILLOPN, /* Illegal operand. */
+# define ILL_ILLOPN ILL_ILLOPN
+ ILL_ILLADR, /* Illegal addressing mode. */
+# define ILL_ILLADR ILL_ILLADR
+ ILL_ILLTRP, /* Illegal trap. */
+# define ILL_ILLTRP ILL_ILLTRP
+ ILL_PRVOPC, /* Privileged opcode. */
+# define ILL_PRVOPC ILL_PRVOPC
+ ILL_PRVREG, /* Privileged register. */
+# define ILL_PRVREG ILL_PRVREG
+ ILL_COPROC, /* Coprocessor error. */
+# define ILL_COPROC ILL_COPROC
+ ILL_BADSTK /* Internal stack error. */
+# define ILL_BADSTK ILL_BADSTK
+};
+
+/* `si_code' values for SIGFPE signal. */
+enum
+{
+ FPE_INTDIV = 1, /* Integer divide by zero. */
+# define FPE_INTDIV FPE_INTDIV
+ FPE_INTOVF, /* Integer overflow. */
+# define FPE_INTOVF FPE_INTOVF
+ FPE_FLTDIV, /* Floating point divide by zero. */
+# define FPE_FLTDIV FPE_FLTDIV
+ FPE_FLTOVF, /* Floating point overflow. */
+# define FPE_FLTOVF FPE_FLTOVF
+ FPE_FLTUND, /* Floating point underflow. */
+# define FPE_FLTUND FPE_FLTUND
+ FPE_FLTRES, /* Floating point inexact result. */
+# define FPE_FLTRES FPE_FLTRES
+ FPE_FLTINV, /* Floating point invalid operation. */
+# define FPE_FLTINV FPE_FLTINV
+ FPE_FLTSUB /* Subscript out of range. */
+# define FPE_FLTSUB FPE_FLTSUB
+};
+
+/* `si_code' values for SIGSEGV signal. */
+enum
+{
+ SEGV_MAPERR = 1, /* Address not mapped to object. */
+# define SEGV_MAPERR SEGV_MAPERR
+ SEGV_ACCERR /* Invalid permissions for mapped object. */
+# define SEGV_ACCERR SEGV_ACCERR
+};
+
+/* `si_code' values for SIGBUS signal. */
+enum
+{
+ BUS_ADRALN = 1, /* Invalid address alignment. */
+# define BUS_ADRALN BUS_ADRALN
+ BUS_ADRERR, /* Non-existant physical address. */
+# define BUS_ADRERR BUS_ADRERR
+ BUS_OBJERR /* Object specific hardware error. */
+# define BUS_OBJERR BUS_OBJERR
+};
+
+/* `si_code' values for SIGTRAP signal. */
+enum
+{
+ TRAP_BRKPT = 1, /* Process breakpoint. */
+# define TRAP_BRKPT TRAP_BRKPT
+ TRAP_TRACE /* Process trace trap. */
+# define TRAP_TRACE TRAP_TRACE
+};
+
+/* `si_code' values for SIGCHLD signal. */
+enum
+{
+ CLD_EXITED = 1, /* Child has exited. */
+# define CLD_EXITED CLD_EXITED
+ CLD_KILLED, /* Child was killed. */
+# define CLD_KILLED CLD_KILLED
+ CLD_DUMPED, /* Child terminated abnormally. */
+# define CLD_DUMPED CLD_DUMPED
+ CLD_TRAPPED, /* Traced child has trapped. */
+# define CLD_TRAPPED CLD_TRAPPED
+ CLD_STOPPED, /* Child has stopped. */
+# define CLD_STOPPED CLD_STOPPED
+ CLD_CONTINUED /* Stopped child has continued. */
+# define CLD_CONTINUED CLD_CONTINUED
+};
+
+/* `si_code' values for SIGPOLL signal. */
+enum
+{
+ POLL_IN = 1, /* Data input available. */
+# define POLL_IN POLL_IN
+ POLL_OUT, /* Output buffers available. */
+# define POLL_OUT POLL_OUT
+ POLL_MSG, /* Input message available. */
+# define POLL_MSG POLL_MSG
+ POLL_ERR, /* I/O error. */
+# define POLL_ERR POLL_ERR
+ POLL_PRI, /* High priority input available. */
+# define POLL_PRI POLL_PRI
+ POLL_HUP /* Device disconnected. */
+# define POLL_HUP POLL_HUP
+};
+
+# undef __need_siginfo_t
+#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
+
+
+#if (defined _SIGNAL_H || defined __need_sigevent_t) \
+ && !defined __have_sigevent_t
+# define __have_sigevent_t 1
+
+/* Structure to transport application-defined values with signals. */
+# define __SIGEV_MAX_SIZE 64
+# if __WORDSIZE == 64
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4)
+# else
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 3)
+# endif
+
+typedef struct sigevent
+ {
+ sigval_t sigev_value;
+ int sigev_signo;
+ int sigev_notify;
+
+ union
+ {
+ int _pad[__SIGEV_PAD_SIZE];
+
+ /* When SIGEV_SIGNAL and SIGEV_THREAD_ID set, LWP ID of the
+ thread to receive the signal. */
+ __pid_t _tid;
+
+ struct
+ {
+ void (*_function) (sigval_t); /* Function to start. */
+ void *_attribute; /* Really pthread_attr_t. */
+ } _sigev_thread;
+ } _sigev_un;
+ } sigevent_t;
+
+/* POSIX names to access some of the members. */
+# define sigev_notify_function _sigev_un._sigev_thread._function
+# define sigev_notify_attributes _sigev_un._sigev_thread._attribute
+
+/* `sigev_notify' values. */
+enum
+{
+ SIGEV_SIGNAL = 0, /* Notify via signal. */
+# define SIGEV_SIGNAL SIGEV_SIGNAL
+ SIGEV_NONE, /* Other notification: meaningless. */
+# define SIGEV_NONE SIGEV_NONE
+ SIGEV_THREAD, /* Deliver via thread creation. */
+# define SIGEV_THREAD SIGEV_THREAD
+
+ SIGEV_THREAD_ID = 4 /* Send signal to specific thread. */
+#define SIGEV_THREAD_ID SIGEV_THREAD_ID
+};
+
+#endif /* have _SIGNAL_H. */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/signum.h b/libc/sysdeps/unix/sysv/linux/bits/signum.h
new file mode 100644
index 000000000..a18ac113a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/signum.h
@@ -0,0 +1,80 @@
+/* Signal number definitions. Linux version.
+ Copyright (C) 1995,1996,1997,1998,1999,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef _SIGNAL_H
+
+/* Fake signal functions. */
+#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
+#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
+#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
+
+#ifdef __USE_UNIX98
+# define SIG_HOLD ((__sighandler_t) 2) /* Add signal to hold mask. */
+#endif
+
+
+/* Signals. */
+#define SIGHUP 1 /* Hangup (POSIX). */
+#define SIGINT 2 /* Interrupt (ANSI). */
+#define SIGQUIT 3 /* Quit (POSIX). */
+#define SIGILL 4 /* Illegal instruction (ANSI). */
+#define SIGTRAP 5 /* Trace trap (POSIX). */
+#define SIGABRT 6 /* Abort (ANSI). */
+#define SIGIOT 6 /* IOT trap (4.2 BSD). */
+#define SIGBUS 7 /* BUS error (4.2 BSD). */
+#define SIGFPE 8 /* Floating-point exception (ANSI). */
+#define SIGKILL 9 /* Kill, unblockable (POSIX). */
+#define SIGUSR1 10 /* User-defined signal 1 (POSIX). */
+#define SIGSEGV 11 /* Segmentation violation (ANSI). */
+#define SIGUSR2 12 /* User-defined signal 2 (POSIX). */
+#define SIGPIPE 13 /* Broken pipe (POSIX). */
+#define SIGALRM 14 /* Alarm clock (POSIX). */
+#define SIGTERM 15 /* Termination (ANSI). */
+#define SIGSTKFLT 16 /* Stack fault. */
+#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
+#define SIGCHLD 17 /* Child status has changed (POSIX). */
+#define SIGCONT 18 /* Continue (POSIX). */
+#define SIGSTOP 19 /* Stop, unblockable (POSIX). */
+#define SIGTSTP 20 /* Keyboard stop (POSIX). */
+#define SIGTTIN 21 /* Background read from tty (POSIX). */
+#define SIGTTOU 22 /* Background write to tty (POSIX). */
+#define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */
+#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */
+#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */
+#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */
+#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */
+#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */
+#define SIGPOLL SIGIO /* Pollable event occurred (System V). */
+#define SIGIO 29 /* I/O now possible (4.2 BSD). */
+#define SIGPWR 30 /* Power failure restart (System V). */
+#define SIGSYS 31 /* Bad system call. */
+#define SIGUNUSED 31
+
+#define _NSIG 65 /* Biggest signal number + 1
+ (including real-time signals). */
+
+#define SIGRTMIN (__libc_current_sigrtmin ())
+#define SIGRTMAX (__libc_current_sigrtmax ())
+
+/* These are the hard limits of the kernel. These values should not be
+ used directly at user level. */
+#define __SIGRTMIN 32
+#define __SIGRTMAX (_NSIG - 1)
+
+#endif /* <signal.h> included. */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/sigset.h b/libc/sysdeps/unix/sysv/linux/bits/sigset.h
new file mode 100644
index 000000000..7ccadda45
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/sigset.h
@@ -0,0 +1,125 @@
+/* __sig_atomic_t, __sigset_t, and related definitions. Linux version.
+ Copyright (C) 1991, 1992, 1994, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIGSET_H_types
+# define _SIGSET_H_types 1
+
+typedef int __sig_atomic_t;
+
+/* A `sigset_t' has a bit for each signal. */
+
+# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))
+typedef struct
+ {
+ unsigned long int __val[_SIGSET_NWORDS];
+ } __sigset_t;
+
+#endif
+
+
+/* We only want to define these functions if <signal.h> was actually
+ included; otherwise we were included just to define the types. Since we
+ are namespace-clean, it wouldn't hurt to define extra macros. But
+ trouble can be caused by functions being defined (e.g., any global
+ register vars declared later will cause compilation errors). */
+
+#if !defined _SIGSET_H_fns && defined _SIGNAL_H
+# define _SIGSET_H_fns 1
+
+# ifndef _EXTERN_INLINE
+# define _EXTERN_INLINE extern __inline
+# endif
+
+/* Return a mask that includes the bit for SIG only. */
+# define __sigmask(sig) \
+ (((unsigned long int) 1) << (((sig) - 1) % (8 * sizeof (unsigned long int))))
+
+/* Return the word index for SIG. */
+# define __sigword(sig) (((sig) - 1) / (8 * sizeof (unsigned long int)))
+
+# if defined __GNUC__ && __GNUC__ >= 2
+# define __sigemptyset(set) \
+ (__extension__ ({ int __cnt = _SIGSET_NWORDS; \
+ sigset_t *__set = (set); \
+ while (--__cnt >= 0) __set->__val[__cnt] = 0; \
+ 0; }))
+# define __sigfillset(set) \
+ (__extension__ ({ int __cnt = _SIGSET_NWORDS; \
+ sigset_t *__set = (set); \
+ while (--__cnt >= 0) __set->__val[__cnt] = ~0UL; \
+ 0; }))
+
+# ifdef __USE_GNU
+/* The POSIX does not specify for handling the whole signal set in one
+ command. This is often wanted and so we define three more functions
+ here. */
+# define __sigisemptyset(set) \
+ (__extension__ ({ int __cnt = _SIGSET_NWORDS; \
+ const sigset_t *__set = (set); \
+ int __ret = __set->__val[--__cnt]; \
+ while (!__ret && --__cnt >= 0) \
+ __ret = __set->__val[__cnt]; \
+ __ret == 0; }))
+# define __sigandset(dest, left, right) \
+ (__extension__ ({ int __cnt = _SIGSET_NWORDS; \
+ sigset_t *__dest = (dest); \
+ const sigset_t *__left = (left); \
+ const sigset_t *__right = (right); \
+ while (--__cnt >= 0) \
+ __dest->__val[__cnt] = (__left->__val[__cnt] \
+ & __right->__val[__cnt]); \
+ 0; }))
+# define __sigorset(dest, left, right) \
+ (__extension__ ({ int __cnt = _SIGSET_NWORDS; \
+ sigset_t *__dest = (dest); \
+ const sigset_t *__left = (left); \
+ const sigset_t *__right = (right); \
+ while (--__cnt >= 0) \
+ __dest->__val[__cnt] = (__left->__val[__cnt] \
+ | __right->__val[__cnt]); \
+ 0; }))
+# endif
+# endif
+
+/* These functions needn't check for a bogus signal number -- error
+ checking is done in the non __ versions. */
+
+extern int __sigismember (__const __sigset_t *, int);
+extern int __sigaddset (__sigset_t *, int);
+extern int __sigdelset (__sigset_t *, int);
+
+# ifdef __USE_EXTERN_INLINES
+# define __SIGSETFN(NAME, BODY, CONST) \
+ _EXTERN_INLINE int \
+ NAME (CONST __sigset_t *__set, int __sig) \
+ { \
+ unsigned long int __mask = __sigmask (__sig); \
+ unsigned long int __word = __sigword (__sig); \
+ return BODY; \
+ }
+
+__SIGSETFN (__sigismember, (__set->__val[__word] & __mask) ? 1 : 0, __const)
+__SIGSETFN (__sigaddset, ((__set->__val[__word] |= __mask), 0), )
+__SIGSETFN (__sigdelset, ((__set->__val[__word] &= ~__mask), 0), )
+
+# undef __SIGSETFN
+# endif
+
+
+#endif /* ! _SIGSET_H_fns. */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/sigstack.h b/libc/sysdeps/unix/sysv/linux/bits/sigstack.h
new file mode 100644
index 000000000..7f260367b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/sigstack.h
@@ -0,0 +1,55 @@
+/* sigstack, sigaltstack definitions.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIGNAL_H
+# error "Never include this file directly. Use <signal.h> instead"
+#endif
+
+
+/* Structure describing a signal stack (obsolete). */
+struct sigstack
+ {
+ void *ss_sp; /* Signal stack pointer. */
+ int ss_onstack; /* Nonzero if executing on this stack. */
+ };
+
+
+/* Possible values for `ss_flags.'. */
+enum
+{
+ SS_ONSTACK = 1,
+#define SS_ONSTACK SS_ONSTACK
+ SS_DISABLE
+#define SS_DISABLE SS_DISABLE
+};
+
+/* Minimum stack size for a signal handler. */
+#define MINSIGSTKSZ 2048
+
+/* System default stack size. */
+#define SIGSTKSZ 8192
+
+
+/* Alternate, preferred interface. */
+typedef struct sigaltstack
+ {
+ void *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+ } stack_t;
diff --git a/libc/sysdeps/unix/sysv/linux/bits/socket.h b/libc/sysdeps/unix/sysv/linux/bits/socket.h
new file mode 100644
index 000000000..356a2ece7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/socket.h
@@ -0,0 +1,320 @@
+/* System-specific socket constants and types. Linux version.
+ Copyright (C) 1991,1992,1994-2001,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __BITS_SOCKET_H
+#define __BITS_SOCKET_H
+
+#if !defined _SYS_SOCKET_H && !defined _NETINET_IN_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+#define __need_size_t
+#define __need_NULL
+#include <stddef.h>
+
+#include <limits.h>
+#include <sys/types.h>
+
+/* Type for length arguments in socket calls. */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+/* Types of sockets. */
+enum __socket_type
+{
+ SOCK_STREAM = 1, /* Sequenced, reliable, connection-based
+ byte streams. */
+#define SOCK_STREAM SOCK_STREAM
+ SOCK_DGRAM = 2, /* Connectionless, unreliable datagrams
+ of fixed maximum length. */
+#define SOCK_DGRAM SOCK_DGRAM
+ SOCK_RAW = 3, /* Raw protocol interface. */
+#define SOCK_RAW SOCK_RAW
+ SOCK_RDM = 4, /* Reliably-delivered messages. */
+#define SOCK_RDM SOCK_RDM
+ SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based,
+ datagrams of fixed maximum length. */
+#define SOCK_SEQPACKET SOCK_SEQPACKET
+ SOCK_PACKET = 10 /* Linux specific way of getting packets
+ at the dev level. For writing rarp and
+ other similar things on the user level. */
+#define SOCK_PACKET SOCK_PACKET
+};
+
+/* Protocol families. */
+#define PF_UNSPEC 0 /* Unspecified. */
+#define PF_LOCAL 1 /* Local to host (pipes and file-domain). */
+#define PF_UNIX PF_LOCAL /* Old BSD name for PF_LOCAL. */
+#define PF_FILE PF_LOCAL /* Another non-standard name for PF_LOCAL. */
+#define PF_INET 2 /* IP protocol family. */
+#define PF_AX25 3 /* Amateur Radio AX.25. */
+#define PF_IPX 4 /* Novell Internet Protocol. */
+#define PF_APPLETALK 5 /* Appletalk DDP. */
+#define PF_NETROM 6 /* Amateur radio NetROM. */
+#define PF_BRIDGE 7 /* Multiprotocol bridge. */
+#define PF_ATMPVC 8 /* ATM PVCs. */
+#define PF_X25 9 /* Reserved for X.25 project. */
+#define PF_INET6 10 /* IP version 6. */
+#define PF_ROSE 11 /* Amateur Radio X.25 PLP. */
+#define PF_DECnet 12 /* Reserved for DECnet project. */
+#define PF_NETBEUI 13 /* Reserved for 802.2LLC project. */
+#define PF_SECURITY 14 /* Security callback pseudo AF. */
+#define PF_KEY 15 /* PF_KEY key management API. */
+#define PF_NETLINK 16
+#define PF_ROUTE PF_NETLINK /* Alias to emulate 4.4BSD. */
+#define PF_PACKET 17 /* Packet family. */
+#define PF_ASH 18 /* Ash. */
+#define PF_ECONET 19 /* Acorn Econet. */
+#define PF_ATMSVC 20 /* ATM SVCs. */
+#define PF_SNA 22 /* Linux SNA Project */
+#define PF_IRDA 23 /* IRDA sockets. */
+#define PF_PPPOX 24 /* PPPoX sockets. */
+#define PF_WANPIPE 25 /* Wanpipe API sockets. */
+#define PF_BLUETOOTH 31 /* Bluetooth sockets. */
+#define PF_MAX 32 /* For now.. */
+
+/* Address families. */
+#define AF_UNSPEC PF_UNSPEC
+#define AF_LOCAL PF_LOCAL
+#define AF_UNIX PF_UNIX
+#define AF_FILE PF_FILE
+#define AF_INET PF_INET
+#define AF_AX25 PF_AX25
+#define AF_IPX PF_IPX
+#define AF_APPLETALK PF_APPLETALK
+#define AF_NETROM PF_NETROM
+#define AF_BRIDGE PF_BRIDGE
+#define AF_ATMPVC PF_ATMPVC
+#define AF_X25 PF_X25
+#define AF_INET6 PF_INET6
+#define AF_ROSE PF_ROSE
+#define AF_DECnet PF_DECnet
+#define AF_NETBEUI PF_NETBEUI
+#define AF_SECURITY PF_SECURITY
+#define AF_KEY PF_KEY
+#define AF_NETLINK PF_NETLINK
+#define AF_ROUTE PF_ROUTE
+#define AF_PACKET PF_PACKET
+#define AF_ASH PF_ASH
+#define AF_ECONET PF_ECONET
+#define AF_ATMSVC PF_ATMSVC
+#define AF_SNA PF_SNA
+#define AF_IRDA PF_IRDA
+#define AF_PPPOX PF_PPPOX
+#define AF_WANPIPE PF_WANPIPE
+#define AF_BLUETOOTH PF_BLUETOOTH
+#define AF_MAX PF_MAX
+
+/* Socket level values. Others are defined in the appropriate headers.
+
+ XXX These definitions also should go into the appropriate headers as
+ far as they are available. */
+#define SOL_RAW 255
+#define SOL_DECNET 261
+#define SOL_X25 262
+#define SOL_PACKET 263
+#define SOL_ATM 264 /* ATM layer (cell level). */
+#define SOL_AAL 265 /* ATM Adaption Layer (packet level). */
+#define SOL_IRDA 266
+
+/* Maximum queue length specifiable by listen. */
+#define SOMAXCONN 128
+
+/* Get the definition of the macro to define the common sockaddr members. */
+#include <bits/sockaddr.h>
+
+/* Structure describing a generic socket address. */
+struct sockaddr
+ {
+ __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
+ char sa_data[14]; /* Address data. */
+ };
+
+
+/* Structure large enough to hold any socket address (with the historical
+ exception of AF_UNIX). We reserve 128 bytes. */
+#if ULONG_MAX > 0xffffffff
+# define __ss_aligntype __uint64_t
+#else
+# define __ss_aligntype __uint32_t
+#endif
+#define _SS_SIZE 128
+#define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype)))
+
+struct sockaddr_storage
+ {
+ __SOCKADDR_COMMON (ss_); /* Address family, etc. */
+ __ss_aligntype __ss_align; /* Force desired alignment. */
+ char __ss_padding[_SS_PADSIZE];
+ };
+
+
+/* Bits in the FLAGS argument to `send', `recv', et al. */
+enum
+ {
+ MSG_OOB = 0x01, /* Process out-of-band data. */
+#define MSG_OOB MSG_OOB
+ MSG_PEEK = 0x02, /* Peek at incoming messages. */
+#define MSG_PEEK MSG_PEEK
+ MSG_DONTROUTE = 0x04, /* Don't use local routing. */
+#define MSG_DONTROUTE MSG_DONTROUTE
+#ifdef __USE_GNU
+ /* DECnet uses a different name. */
+ MSG_TRYHARD = MSG_DONTROUTE,
+# define MSG_TRYHARD MSG_DONTROUTE
+#endif
+ MSG_CTRUNC = 0x08, /* Control data lost before delivery. */
+#define MSG_CTRUNC MSG_CTRUNC
+ MSG_PROXY = 0x10, /* Supply or ask second address. */
+#define MSG_PROXY MSG_PROXY
+ MSG_TRUNC = 0x20,
+#define MSG_TRUNC MSG_TRUNC
+ MSG_DONTWAIT = 0x40, /* Nonblocking IO. */
+#define MSG_DONTWAIT MSG_DONTWAIT
+ MSG_EOR = 0x80, /* End of record. */
+#define MSG_EOR MSG_EOR
+ MSG_WAITALL = 0x100, /* Wait for a full request. */
+#define MSG_WAITALL MSG_WAITALL
+ MSG_FIN = 0x200,
+#define MSG_FIN MSG_FIN
+ MSG_SYN = 0x400,
+#define MSG_SYN MSG_SYN
+ MSG_CONFIRM = 0x800, /* Confirm path validity. */
+#define MSG_CONFIRM MSG_CONFIRM
+ MSG_RST = 0x1000,
+#define MSG_RST MSG_RST
+ MSG_ERRQUEUE = 0x2000, /* Fetch message from error queue. */
+#define MSG_ERRQUEUE MSG_ERRQUEUE
+ MSG_NOSIGNAL = 0x4000, /* Do not generate SIGPIPE. */
+#define MSG_NOSIGNAL MSG_NOSIGNAL
+ MSG_MORE = 0x8000 /* Sender will send more. */
+#define MSG_MORE MSG_MORE
+ };
+
+
+/* Structure describing messages sent by
+ `sendmsg' and received by `recvmsg'. */
+struct msghdr
+ {
+ void *msg_name; /* Address to send to/receive from. */
+ socklen_t msg_namelen; /* Length of address data. */
+
+ struct iovec *msg_iov; /* Vector of data to send/receive into. */
+ size_t msg_iovlen; /* Number of elements in the vector. */
+
+ void *msg_control; /* Ancillary data (eg BSD filedesc passing). */
+ size_t msg_controllen; /* Ancillary data buffer length.
+ !! The type should be socklen_t but the
+ definition of the kernel is incompatible
+ with this. */
+
+ int msg_flags; /* Flags on received message. */
+ };
+
+/* Structure used for storage of ancillary data object information. */
+struct cmsghdr
+ {
+ size_t cmsg_len; /* Length of data in cmsg_data plus length
+ of cmsghdr structure.
+ !! The type should be socklen_t but the
+ definition of the kernel is incompatible
+ with this. */
+ int cmsg_level; /* Originating protocol. */
+ int cmsg_type; /* Protocol specific type. */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+ __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data. */
+#endif
+ };
+
+/* Ancillary data object manipulation macros. */
+#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
+# define CMSG_DATA(cmsg) ((cmsg)->__cmsg_data)
+#else
+# define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1))
+#endif
+#define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr (mhdr, cmsg)
+#define CMSG_FIRSTHDR(mhdr) \
+ ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) \
+ ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) NULL)
+#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \
+ & (size_t) ~(sizeof (size_t) - 1))
+#define CMSG_SPACE(len) (CMSG_ALIGN (len) \
+ + CMSG_ALIGN (sizeof (struct cmsghdr)))
+#define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+
+extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
+ struct cmsghdr *__cmsg) __THROW;
+#ifdef __USE_EXTERN_INLINES
+# ifndef _EXTERN_INLINE
+# define _EXTERN_INLINE extern __inline
+# endif
+_EXTERN_INLINE struct cmsghdr *
+__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
+{
+ if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
+ /* The kernel header does this so there may be a reason. */
+ return 0;
+
+ __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ + CMSG_ALIGN (__cmsg->cmsg_len));
+ if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
+ + __mhdr->msg_controllen)
+ || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
+ > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
+ /* No more entries. */
+ return 0;
+ return __cmsg;
+}
+#endif /* Use `extern inline'. */
+
+/* Socket level message types. This must match the definitions in
+ <linux/socket.h>. */
+enum
+ {
+ SCM_RIGHTS = 0x01 /* Transfer file descriptors. */
+#define SCM_RIGHTS SCM_RIGHTS
+#ifdef __USE_BSD
+ , SCM_CREDENTIALS = 0x02 /* Credentials passing. */
+# define SCM_CREDENTIALS SCM_CREDENTIALS
+#endif
+ };
+
+/* User visible structure for SCM_CREDENTIALS message */
+
+struct ucred
+{
+ pid_t pid; /* PID of sending process. */
+ uid_t uid; /* UID of sending process. */
+ gid_t gid; /* GID of sending process. */
+};
+
+/* Get socket manipulation related informations from kernel headers. */
+#include <asm/socket.h>
+
+
+/* Structure used to manipulate the SO_LINGER option. */
+struct linger
+ {
+ int l_onoff; /* Nonzero to linger on close. */
+ int l_linger; /* Time to linger. */
+ };
+
+#endif /* bits/socket.h */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/stat.h b/libc/sysdeps/unix/sysv/linux/bits/stat.h
new file mode 100644
index 000000000..e08899c9a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/stat.h
@@ -0,0 +1,163 @@
+/* Copyright (C) 1992, 1995-2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+/* Versions of the `struct stat' data structure. */
+#define _STAT_VER_LINUX_OLD 1
+#define _STAT_VER_KERNEL 1
+#define _STAT_VER_SVR4 2
+#define _STAT_VER_LINUX 3
+#define _STAT_VER _STAT_VER_LINUX /* The one defined below. */
+
+/* Versions of the `xmknod' interface. */
+#define _MKNOD_VER_LINUX 1
+#define _MKNOD_VER_SVR4 2
+#define _MKNOD_VER _MKNOD_VER_LINUX /* The bits defined below. */
+
+
+struct stat
+ {
+ __dev_t st_dev; /* Device. */
+ unsigned short int __pad1;
+#ifndef __USE_FILE_OFFSET64
+ __ino_t st_ino; /* File serial number. */
+#else
+ __ino_t __st_ino; /* 32bit file serial number. */
+#endif
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned short int __pad2;
+#ifndef __USE_FILE_OFFSET64
+ __off_t st_size; /* Size of file, in bytes. */
+#else
+ __off64_t st_size; /* Size of file, in bytes. */
+#endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+#ifndef __USE_FILE_OFFSET64
+ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
+#else
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+#endif
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+#ifndef __USE_FILE_OFFSET64
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+#else
+ __ino64_t st_ino; /* File serial number. */
+#endif
+ };
+
+#ifdef __USE_LARGEFILE64
+struct stat64
+ {
+ __dev_t st_dev; /* Device. */
+ unsigned int __pad1;
+
+ __ino_t __st_ino; /* 32bit file serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned int __pad2;
+ __off64_t st_size; /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+ __ino64_t st_ino; /* File serial number. */
+ };
+#endif
+
+/* Tell code we have these members. */
+#define _STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+/* Nanosecond resolution time values are supported. */
+#define _STATBUF_ST_NSEC
+
+/* Encoding of the file mode. */
+
+#define __S_IFMT 0170000 /* These bits determine file type. */
+
+/* File types. */
+#define __S_IFDIR 0040000 /* Directory. */
+#define __S_IFCHR 0020000 /* Character device. */
+#define __S_IFBLK 0060000 /* Block device. */
+#define __S_IFREG 0100000 /* Regular file. */
+#define __S_IFIFO 0010000 /* FIFO. */
+#define __S_IFLNK 0120000 /* Symbolic link. */
+#define __S_IFSOCK 0140000 /* Socket. */
+
+/* POSIX.1b objects. Note that these macros always evaluate to zero. But
+ they do it by enforcing the correct use of the macros. */
+#define __S_TYPEISMQ(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
+
+/* Protection bits. */
+
+#define __S_ISUID 04000 /* Set user ID on execution. */
+#define __S_ISGID 02000 /* Set group ID on execution. */
+#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
+#define __S_IREAD 0400 /* Read by owner. */
+#define __S_IWRITE 0200 /* Write by owner. */
+#define __S_IEXEC 0100 /* Execute by owner. */
diff --git a/libc/sysdeps/unix/sysv/linux/bits/statfs.h b/libc/sysdeps/unix/sysv/linux/bits/statfs.h
new file mode 100644
index 000000000..0e27865e8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/statfs.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STATFS_H
+# error "Never include <bits/statfs.h> directly; use <sys/statfs.h> instead."
+#endif
+
+#include <bits/types.h>
+
+struct statfs
+ {
+ __SWORD_TYPE f_type;
+ __SWORD_TYPE f_bsize;
+#ifndef __USE_FILE_OFFSET64
+ __fsblkcnt_t f_blocks;
+ __fsblkcnt_t f_bfree;
+ __fsblkcnt_t f_bavail;
+ __fsfilcnt_t f_files;
+ __fsfilcnt_t f_ffree;
+#else
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsfilcnt64_t f_files;
+ __fsfilcnt64_t f_ffree;
+#endif
+ __fsid_t f_fsid;
+ __SWORD_TYPE f_namelen;
+ __SWORD_TYPE f_frsize;
+ __SWORD_TYPE f_spare[5];
+ };
+
+#ifdef __USE_LARGEFILE64
+struct statfs64
+ {
+ __SWORD_TYPE f_type;
+ __SWORD_TYPE f_bsize;
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsfilcnt64_t f_files;
+ __fsfilcnt64_t f_ffree;
+ __fsid_t f_fsid;
+ __SWORD_TYPE f_namelen;
+ __SWORD_TYPE f_frsize;
+ __SWORD_TYPE f_spare[5];
+ };
+#endif
+
+/* Tell code we have these members. */
+#define _STATFS_F_NAMELEN
+#define _STATFS_F_FRSIZE
diff --git a/libc/sysdeps/unix/sysv/linux/bits/statvfs.h b/libc/sysdeps/unix/sysv/linux/bits/statvfs.h
new file mode 100644
index 000000000..cca0871ac
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/statvfs.h
@@ -0,0 +1,107 @@
+/* Copyright (C) 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STATVFS_H
+# error "Never include <bits/statvfs.h> directly; use <sys/statvfs.h> instead."
+#endif
+
+#include <bits/types.h> /* For __fsblkcnt_t and __fsfilcnt_t. */
+
+#if __WORDSIZE == 32
+#define _STATVFSBUF_F_UNUSED
+#endif
+
+struct statvfs
+ {
+ unsigned long int f_bsize;
+ unsigned long int f_frsize;
+#ifndef __USE_FILE_OFFSET64
+ __fsblkcnt_t f_blocks;
+ __fsblkcnt_t f_bfree;
+ __fsblkcnt_t f_bavail;
+ __fsfilcnt_t f_files;
+ __fsfilcnt_t f_ffree;
+ __fsfilcnt_t f_favail;
+#else
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsfilcnt64_t f_files;
+ __fsfilcnt64_t f_ffree;
+ __fsfilcnt64_t f_favail;
+#endif
+ unsigned long int f_fsid;
+#ifdef _STATVFSBUF_F_UNUSED
+ int __f_unused;
+#endif
+ unsigned long int f_flag;
+ unsigned long int f_namemax;
+ int __f_spare[6];
+ };
+
+#ifdef __USE_LARGEFILE64
+struct statvfs64
+ {
+ unsigned long int f_bsize;
+ unsigned long int f_frsize;
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsfilcnt64_t f_files;
+ __fsfilcnt64_t f_ffree;
+ __fsfilcnt64_t f_favail;
+ unsigned long int f_fsid;
+#ifdef _STATVFSBUF_F_UNUSED
+ int __f_unused;
+#endif
+ unsigned long int f_flag;
+ unsigned long int f_namemax;
+ int __f_spare[6];
+ };
+#endif
+
+/* Definitions for the flag in `f_flag'. These definitions should be
+ kept in sync with the definitions in <sys/mount.h>. */
+enum
+{
+ ST_RDONLY = 1, /* Mount read-only. */
+#define ST_RDONLY ST_RDONLY
+ ST_NOSUID = 2 /* Ignore suid and sgid bits. */
+#define ST_NOSUID ST_NOSUID
+#ifdef __USE_GNU
+ ,
+ ST_NODEV = 4, /* Disallow access to device special files. */
+# define ST_NODEV ST_NODEV
+ ST_NOEXEC = 8, /* Disallow program execution. */
+# define ST_NOEXEC ST_NOEXEC
+ ST_SYNCHRONOUS = 16, /* Writes are synced at once. */
+# define ST_SYNCHRONOUS ST_SYNCHRONOUS
+ ST_MANDLOCK = 64, /* Allow mandatory locks on an FS. */
+# define ST_MANDLOCK ST_MANDLOCK
+ ST_WRITE = 128, /* Write on file/directory/symlink. */
+# define ST_WRITE ST_WRITE
+ ST_APPEND = 256, /* Append-only file. */
+# define ST_APPEND ST_APPEND
+ ST_IMMUTABLE = 512, /* Immutable file. */
+# define ST_IMMUTABLE ST_IMMUTABLE
+ ST_NOATIME = 1024, /* Do not update access times. */
+# define ST_NOATIME ST_NOATIME
+ ST_NODIRATIME = 2048 /* Do not update directory access times. */
+# define ST_NODIRATIME ST_NODIRATIME
+#endif /* Use GNU. */
+};
diff --git a/libc/sysdeps/unix/sysv/linux/bits/sys_errlist.h b/libc/sysdeps/unix/sysv/linux/bits/sys_errlist.h
new file mode 100644
index 000000000..ee556e8ec
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/sys_errlist.h
@@ -0,0 +1,33 @@
+/* Declare sys_errlist and sys_nerr, or don't. Compatibility (do) version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _STDIO_H
+# error "Never include <bits/sys_errlist.h> directly; use <stdio.h> instead."
+#endif
+
+/* sys_errlist and sys_nerr are deprecated. Use strerror instead. */
+
+#ifdef __USE_BSD
+extern int sys_nerr;
+extern __const char *__const sys_errlist[];
+#endif
+#ifdef __USE_GNU
+extern int _sys_nerr;
+extern __const char *__const _sys_errlist[];
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/bits/termios.h b/libc/sysdeps/unix/sysv/linux/bits/termios.h
new file mode 100644
index 000000000..c71e4ad1f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/termios.h
@@ -0,0 +1,218 @@
+/* termios type and macro definitions. Linux version.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2003, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _TERMIOS_H
+# error "Never include <bits/termios.h> directly; use <termios.h> instead."
+#endif
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 32
+struct termios
+ {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
+#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
+ };
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+#define IUTF8 0040000
+
+/* c_oflag bits */
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#if defined __USE_MISC || defined __USE_XOPEN
+# define NLDLY 0000400
+# define NL0 0000000
+# define NL1 0000400
+# define CRDLY 0003000
+# define CR0 0000000
+# define CR1 0001000
+# define CR2 0002000
+# define CR3 0003000
+# define TABDLY 0014000
+# define TAB0 0000000
+# define TAB1 0004000
+# define TAB2 0010000
+# define TAB3 0014000
+# define BSDLY 0020000
+# define BS0 0000000
+# define BS1 0020000
+# define FFDLY 0100000
+# define FF0 0000000
+# define FF1 0100000
+#endif
+
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+
+#ifdef __USE_MISC
+# define XTABS 0014000
+#endif
+
+/* c_cflag bit meaning */
+#ifdef __USE_MISC
+# define CBAUD 0010017
+#endif
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#ifdef __USE_MISC
+# define EXTA B19200
+# define EXTB B38400
+#endif
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+#ifdef __USE_MISC
+# define CBAUDEX 0010000
+#endif
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define B500000 0010005
+#define B576000 0010006
+#define B921600 0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+#define __MAX_BAUD B4000000
+#ifdef __USE_MISC
+# define CIBAUD 002003600000 /* input baud rate (not used) */
+# define CMSPAR 010000000000 /* mark or space (stick) parity */
+# define CRTSCTS 020000000000 /* flow control */
+#endif
+
+/* c_lflag bits */
+#define ISIG 0000001
+#define ICANON 0000002
+#if defined __USE_MISC || defined __USE_XOPEN
+# define XCASE 0000004
+#endif
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#ifdef __USE_MISC
+# define ECHOCTL 0001000
+# define ECHOPRT 0002000
+# define ECHOKE 0004000
+# define FLUSHO 0010000
+# define PENDIN 0040000
+#endif
+#define IEXTEN 0100000
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+
+#define _IOT_termios /* Hurd ioctl type field. */ \
+ _IOT (_IOTS (cflag_t), 4, _IOTS (cc_t), NCCS, _IOTS (speed_t), 2)
diff --git a/libc/sysdeps/unix/sysv/linux/bits/uio.h b/libc/sysdeps/unix/sysv/linux/bits/uio.h
new file mode 100644
index 000000000..6a283ed77
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/uio.h
@@ -0,0 +1,50 @@
+/* Copyright (C) 1996, 1997, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _SYS_UIO_H && !defined _FCNTL_H
+# error "Never include <bits/uio.h> directly; use <sys/uio.h> instead."
+#endif
+
+#ifndef _BITS_UIO_H
+#define _BITS_UIO_H 1
+
+#include <sys/types.h>
+
+
+/* We should normally use the Linux kernel header file to define this
+ type and macros but this calls for trouble because of the header
+ includes other kernel headers. */
+
+/* Size of object which can be written atomically.
+
+ This macro has different values in different kernel versions. The
+ latest versions of the kernel use 1024 and this is good choice. Since
+ the C library implementation of readv/writev is able to emulate the
+ functionality even if the currently running kernel does not support
+ this large value the readv/writev call will not fail because of this. */
+#define UIO_MAXIOV 1024
+
+
+/* Structure for scatter/gather I/O. */
+struct iovec
+ {
+ void *iov_base; /* Pointer to data. */
+ size_t iov_len; /* Length of data. */
+ };
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/bits/utsname.h b/libc/sysdeps/unix/sysv/linux/bits/utsname.h
new file mode 100644
index 000000000..35e71e3ba
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/utsname.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_UTSNAME_H
+# error "Never include <bits/utsname.h> directly; use <sys/utsname.h> instead."
+#endif
+
+/* Length of the entries in `struct utsname' is 65. */
+#define _UTSNAME_LENGTH 65
+
+/* Linux provides as additional information in the `struct utsname'
+ the name of the current domain. Define _UTSNAME_DOMAIN_LENGTH
+ to a value != 0 to activate this entry. */
+#define _UTSNAME_DOMAIN_LENGTH _UTSNAME_LENGTH
diff --git a/libc/sysdeps/unix/sysv/linux/bits/waitflags.h b/libc/sysdeps/unix/sysv/linux/bits/waitflags.h
new file mode 100644
index 000000000..464cedb1f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/bits/waitflags.h
@@ -0,0 +1,38 @@
+/* Definitions of flag bits for `waitpid' et al.
+ Copyright (C) 1992,1996,1997,2000,2004,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _SYS_WAIT_H && !defined _STDLIB_H
+# error "Never include <bits/waitflags.h> directly; use <sys/wait.h> instead."
+#endif
+
+
+/* Bits in the third argument to `waitpid'. */
+#define WNOHANG 1 /* Don't block waiting. */
+#define WUNTRACED 2 /* Report status of stopped children. */
+
+/* Bits in the fourth argument to `waitid'. */
+#define WSTOPPED 2 /* Report stopped child (same as WUNTRACED). */
+#define WEXITED 4 /* Report dead child. */
+#define WCONTINUED 8 /* Report continued child. */
+#define WNOWAIT 0x01000000 /* Don't reap, just poll status. */
+
+#define __WNOTHREAD 0x20000000 /* Don't wait on children of other threads
+ in this group */
+#define __WALL 0x40000000 /* Wait for any child. */
+#define __WCLONE 0x80000000 /* Wait for cloned process. */
diff --git a/libc/sysdeps/unix/sysv/linux/check_pf.c b/libc/sysdeps/unix/sysv/linux/check_pf.c
new file mode 100644
index 000000000..7fbb7543d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/check_pf.c
@@ -0,0 +1,268 @@
+/* Determine protocol families for which interfaces exist. Linux version.
+ Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <ifaddrs.h>
+#include <netdb.h>
+#include <stddef.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+#include <asm/types.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <not-cancel.h>
+#include <kernel-features.h>
+
+
+#ifndef IFA_F_TEMPORARY
+# define IFA_F_TEMPORARY IFA_F_SECONDARY
+#endif
+
+
+static int
+make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
+ struct in6addrinfo **in6ai, size_t *in6ailen)
+{
+ struct req
+ {
+ struct nlmsghdr nlh;
+ struct rtgenmsg g;
+ /* struct rtgenmsg consists of a single byte. This means there
+ are three bytes of padding included in the REQ definition.
+ We make them explicit here. */
+ char pad[3];
+ } req;
+ struct sockaddr_nl nladdr;
+
+ req.nlh.nlmsg_len = sizeof (req);
+ req.nlh.nlmsg_type = RTM_GETADDR;
+ req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
+ req.nlh.nlmsg_pid = 0;
+ req.nlh.nlmsg_seq = time (NULL);
+ req.g.rtgen_family = AF_UNSPEC;
+
+ assert (sizeof (req) - offsetof (struct req, pad) == 3);
+ memset (req.pad, '\0', sizeof (req.pad));
+
+ memset (&nladdr, '\0', sizeof (nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0,
+ (struct sockaddr *) &nladdr,
+ sizeof (nladdr))) < 0)
+ return -1;
+
+ *seen_ipv4 = false;
+ *seen_ipv6 = false;
+
+ bool done = false;
+ char buf[4096];
+ struct iovec iov = { buf, sizeof (buf) };
+ struct in6ailist
+ {
+ struct in6addrinfo info;
+ struct in6ailist *next;
+ } *in6ailist = NULL;
+ size_t in6ailistlen = 0;
+
+ do
+ {
+ struct msghdr msg =
+ {
+ (void *) &nladdr, sizeof (nladdr),
+ &iov, 1,
+ NULL, 0,
+ 0
+ };
+
+ ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
+ if (read_len < 0)
+ return -1;
+
+ if (msg.msg_flags & MSG_TRUNC)
+ return -1;
+
+ struct nlmsghdr *nlmh;
+ for (nlmh = (struct nlmsghdr *) buf;
+ NLMSG_OK (nlmh, (size_t) read_len);
+ nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, read_len))
+ {
+ if (nladdr.nl_pid != 0 || (pid_t) nlmh->nlmsg_pid != pid
+ || nlmh->nlmsg_seq != req.nlh.nlmsg_seq)
+ continue;
+
+ if (nlmh->nlmsg_type == RTM_NEWADDR)
+ {
+ struct ifaddrmsg *ifam = (struct ifaddrmsg *) NLMSG_DATA (nlmh);
+
+ switch (ifam->ifa_family)
+ {
+ case AF_INET:
+ *seen_ipv4 = true;
+ break;
+ case AF_INET6:
+ *seen_ipv6 = true;
+
+ if (ifam->ifa_flags & (IFA_F_DEPRECATED | IFA_F_TEMPORARY))
+ {
+ struct rtattr *rta = IFA_RTA (ifam);
+ size_t len = (nlmh->nlmsg_len
+ - NLMSG_LENGTH (sizeof (*ifam)));
+ void *local = NULL;
+ void *address = NULL;
+ while (RTA_OK (rta, len))
+ {
+ switch (rta->rta_type)
+ {
+ case IFA_LOCAL:
+ local = RTA_DATA (rta);
+ break;
+
+ case IFA_ADDRESS:
+ address = RTA_DATA (rta);
+ break;
+ }
+
+ rta = RTA_NEXT (rta, len);
+ }
+
+ struct in6ailist *newp = alloca (sizeof (*newp));
+ newp->info.flags = (((ifam->ifa_flags & IFA_F_DEPRECATED)
+ ? in6ai_deprecated : 0)
+ | ((ifam->ifa_flags
+ & IFA_F_TEMPORARY)
+ ? in6ai_temporary : 0));
+ memcpy (newp->info.addr, address ?: local,
+ sizeof (newp->info.addr));
+ newp->next = in6ailist;
+ in6ailist = newp;
+ ++in6ailistlen;
+ }
+ break;
+ default:
+ /* Ignore. */
+ break;
+ }
+ }
+ else if (nlmh->nlmsg_type == NLMSG_DONE)
+ /* We found the end, leave the loop. */
+ done = true;
+ }
+ }
+ while (! done);
+
+ close_not_cancel_no_status (fd);
+
+ if (in6ailist != NULL)
+ {
+ *in6ai = malloc (in6ailistlen * sizeof (**in6ai));
+ if (*in6ai == NULL)
+ return -1;
+
+ *in6ailen = in6ailistlen;
+
+ do
+ {
+ (*in6ai)[--in6ailistlen] = in6ailist->info;
+ in6ailist = in6ailist->next;
+ }
+ while (in6ailist != NULL);
+ }
+
+ return 0;
+}
+
+
+/* We don't know if we have NETLINK support compiled in in our
+ Kernel. */
+#if __ASSUME_NETLINK_SUPPORT == 0
+/* Define in ifaddrs.h. */
+extern int __no_netlink_support attribute_hidden;
+#else
+# define __no_netlink_support 0
+#endif
+
+
+void
+attribute_hidden
+__check_pf (bool *seen_ipv4, bool *seen_ipv6,
+ struct in6addrinfo **in6ai, size_t *in6ailen)
+{
+ *in6ai = NULL;
+ *in6ailen = 0;
+
+ if (! __no_netlink_support)
+ {
+ int fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+
+ struct sockaddr_nl nladdr;
+ memset (&nladdr, '\0', sizeof (nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ socklen_t addr_len = sizeof (nladdr);
+
+ if (fd >= 0
+ && __bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) == 0
+ && __getsockname (fd, (struct sockaddr *) &nladdr, &addr_len) == 0
+ && make_request (fd, nladdr.nl_pid, seen_ipv4, seen_ipv6,
+ in6ai, in6ailen) == 0)
+ /* It worked. */
+ return;
+
+ if (fd >= 0)
+ __close (fd);
+
+#if __ASSUME_NETLINK_SUPPORT == 0
+ /* Remember that there is no netlink support. */
+ __no_netlink_support = 1;
+#else
+ /* We cannot determine what interfaces are available. Be
+ pessimistic. */
+ *seen_ipv4 = true;
+ *seen_ipv6 = true;
+#endif
+ }
+
+#if __ASSUME_NETLINK_SUPPORT == 0
+ /* No netlink. Get the interface list via getifaddrs. */
+ struct ifaddrs *ifa = NULL;
+ if (getifaddrs (&ifa) != 0)
+ {
+ /* We cannot determine what interfaces are available. Be
+ pessimistic. */
+ *seen_ipv4 = true;
+ *seen_ipv6 = true;
+ return;
+ }
+
+ struct ifaddrs *runp;
+ for (runp = ifa; runp != NULL; runp = runp->ifa_next)
+ if (runp->ifa_addr->sa_family == PF_INET)
+ *seen_ipv4 = true;
+ else if (runp->ifa_addr->sa_family == PF_INET6)
+ *seen_ipv6 = true;
+
+ (void) freeifaddrs (ifa);
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/clock.c b/libc/sysdeps/unix/sysv/linux/clock.c
new file mode 100644
index 000000000..e9d408d91
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/clock.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991, 1992, 1996, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/times.h>
+#include <time.h>
+#include <unistd.h>
+
+/* Return the time used by the program so far (user time + system time). */
+clock_t
+clock (void)
+{
+ struct tms buf;
+ long clk_tck = __sysconf (_SC_CLK_TCK);
+
+ /* We don't check for errors here. The only error the kernel
+ returns is EFAULT if the value cannot be written to the struct we
+ pass a pointer to. Otherwise the kernel returns an `unsigned
+ long' value which is the number of jiffies since system start.
+ But this number can be negative (when read as `long') when the
+ system is up for some time. Ignoring errors should therefore
+ have no negative impacts but solve the problem. */
+ __times (&buf);
+
+ return
+ (clk_tck <= CLOCKS_PER_SEC)
+ ? ((unsigned long) buf.tms_utime + buf.tms_stime) * (CLOCKS_PER_SEC
+ / clk_tck)
+ : ((unsigned long) buf.tms_utime + buf.tms_stime) / (clk_tck
+ / CLOCKS_PER_SEC);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/clock_getcpuclockid.c b/libc/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
new file mode 100644
index 000000000..04bf49e45
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
@@ -0,0 +1,103 @@
+/* clock_getcpuclockid -- Get a clockid_t for process CPU time. Linux version.
+ Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+#include <kernel-features.h>
+#include "kernel-posix-cpu-timers.h"
+
+#ifndef HAS_CPUCLOCK
+# define HAS_CPUCLOCK 1
+#endif
+
+int
+clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
+{
+#ifdef __NR_clock_getres
+ /* The clockid_t value is a simple computation from the PID.
+ But we do a clock_getres call to validate it. */
+
+ const clockid_t pidclock = MAKE_PROCESS_CPUCLOCK (pid, CPUCLOCK_SCHED);
+
+# if !(__ASSUME_POSIX_CPU_TIMERS > 0)
+ extern int __libc_missing_posix_cpu_timers attribute_hidden;
+# if !(__ASSUME_POSIX_TIMERS > 0)
+ extern int __libc_missing_posix_timers attribute_hidden;
+ if (__libc_missing_posix_timers && !__libc_missing_posix_cpu_timers)
+ __libc_missing_posix_cpu_timers = 1;
+# endif
+ if (!__libc_missing_posix_cpu_timers)
+# endif
+ {
+ INTERNAL_SYSCALL_DECL (err);
+ int r = INTERNAL_SYSCALL (clock_getres, err, 2, pidclock, NULL);
+ if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+ {
+ *clock_id = pidclock;
+ return 0;
+ }
+
+# if !(__ASSUME_POSIX_TIMERS > 0)
+ if (INTERNAL_SYSCALL_ERRNO (r, err) == ENOSYS)
+ {
+ /* The kernel doesn't support these calls at all. */
+ __libc_missing_posix_timers = 1;
+ __libc_missing_posix_cpu_timers = 1;
+ }
+ else
+# endif
+ if (INTERNAL_SYSCALL_ERRNO (r, err) == EINVAL)
+ {
+# if !(__ASSUME_POSIX_CPU_TIMERS > 0)
+ if (pidclock == MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED)
+ || INTERNAL_SYSCALL_ERROR_P (INTERNAL_SYSCALL
+ (clock_getres, err, 2,
+ MAKE_PROCESS_CPUCLOCK
+ (0, CPUCLOCK_SCHED), NULL),
+ err))
+ /* The kernel doesn't support these clocks at all. */
+ __libc_missing_posix_cpu_timers = 1;
+ else
+# endif
+ /* The clock_getres system call checked the PID for us. */
+ return ESRCH;
+ }
+ else
+ return INTERNAL_SYSCALL_ERRNO (r, err);
+ }
+#endif
+
+ /* We don't allow any process ID but our own. */
+ if (pid != 0 && pid != getpid ())
+ return EPERM;
+
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+ if (HAS_CPUCLOCK)
+ {
+ /* Store the number. */
+ *clock_id = CLOCK_PROCESS_CPUTIME_ID;
+
+ return 0;
+ }
+#endif
+
+ /* We don't have a timer for that. */
+ return ENOENT;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/clock_getres.c b/libc/sysdeps/unix/sysv/linux/clock_getres.c
new file mode 100644
index 000000000..813d3ebbf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/clock_getres.c
@@ -0,0 +1,193 @@
+/* clock_getres -- Get the resolution of a POSIX clockid_t. Linux version.
+ Copyright (C) 2003,2004,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <errno.h>
+#include <time.h>
+#include "kernel-posix-cpu-timers.h"
+#include <kernel-features.h>
+
+#ifndef HAVE_CLOCK_GETRES_VSYSCALL
+# undef INTERNAL_VSYSCALL
+# define INTERNAL_VSYSCALL INTERNAL_SYSCALL
+# undef INLINE_VSYSCALL
+# define INLINE_VSYSCALL INLINE_SYSCALL
+#else
+# include <bits/libc-vdso.h>
+#endif
+
+#define SYSCALL_GETRES \
+ retval = INLINE_VSYSCALL (clock_getres, 2, clock_id, res); \
+ break
+
+#ifdef __ASSUME_POSIX_TIMERS
+
+/* This means the REALTIME and MONOTONIC clock are definitely
+ supported in the kernel. */
+# define SYSDEP_GETRES \
+ SYSDEP_GETRES_CPUTIME \
+ case CLOCK_REALTIME: \
+ case CLOCK_MONOTONIC: \
+ SYSCALL_GETRES
+
+# define __libc_missing_posix_timers 0
+#elif defined __NR_clock_getres
+/* Is the syscall known to exist? */
+extern int __libc_missing_posix_timers attribute_hidden;
+
+static inline int
+maybe_syscall_getres (clockid_t clock_id, struct timespec *res)
+{
+ int e = EINVAL;
+
+ if (!__libc_missing_posix_timers)
+ {
+ INTERNAL_SYSCALL_DECL (err);
+ int r = INTERNAL_VSYSCALL (clock_getres, err, 2, clock_id, res);
+ if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+ return 0;
+
+ e = INTERNAL_SYSCALL_ERRNO (r, err);
+ if (e == ENOSYS)
+ {
+ __libc_missing_posix_timers = 1;
+ e = EINVAL;
+ }
+ }
+
+ return e;
+}
+
+/* The REALTIME and MONOTONIC clock might be available. Try the
+ syscall first. */
+# define SYSDEP_GETRES \
+ SYSDEP_GETRES_CPUTIME \
+ case CLOCK_REALTIME: \
+ case CLOCK_MONOTONIC: \
+ retval = maybe_syscall_getres (clock_id, res); \
+ if (retval == 0) \
+ break; \
+ /* Fallback code. */ \
+ if (retval == EINVAL && clock_id == CLOCK_REALTIME) \
+ retval = realtime_getres (res); \
+ else \
+ { \
+ __set_errno (retval); \
+ retval = -1; \
+ } \
+ break;
+#endif
+
+#ifdef __NR_clock_getres
+/* We handled the REALTIME clock here. */
+# define HANDLED_REALTIME 1
+# define HANDLED_CPUTIME 1
+
+# if __ASSUME_POSIX_CPU_TIMERS > 0
+
+# define SYSDEP_GETRES_CPU SYSCALL_GETRES
+# define SYSDEP_GETRES_CPUTIME /* Default catches them too. */
+
+# else
+
+extern int __libc_missing_posix_cpu_timers attribute_hidden;
+
+static int
+maybe_syscall_getres_cpu (clockid_t clock_id, struct timespec *res)
+{
+ int e = EINVAL;
+
+ if (!__libc_missing_posix_cpu_timers)
+ {
+ INTERNAL_SYSCALL_DECL (err);
+ int r = INTERNAL_VSYSCALL (clock_getres, err, 2, clock_id, res);
+ if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+ return 0;
+
+ e = INTERNAL_SYSCALL_ERRNO (r, err);
+# ifndef __ASSUME_POSIX_TIMERS
+ if (e == ENOSYS)
+ {
+ __libc_missing_posix_timers = 1;
+ __libc_missing_posix_cpu_timers = 1;
+ e = EINVAL;
+ }
+ else
+# endif
+ {
+ if (e == EINVAL)
+ {
+ /* Check whether the kernel supports CPU clocks at all.
+ If not, record it for the future. */
+ r = INTERNAL_VSYSCALL (clock_getres, err, 2,
+ MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED),
+ NULL);
+ if (INTERNAL_SYSCALL_ERROR_P (r, err))
+ __libc_missing_posix_cpu_timers = 1;
+ }
+ }
+ }
+
+ return e;
+}
+
+# define SYSDEP_GETRES_CPU \
+ retval = maybe_syscall_getres_cpu (clock_id, res); \
+ if (retval == 0) \
+ break; \
+ if (retval != EINVAL || !__libc_missing_posix_cpu_timers) \
+ { \
+ __set_errno (retval); \
+ retval = -1; \
+ break; \
+ } \
+ retval = -1 /* Otherwise continue on to the HP_TIMING version. */;
+
+static inline int
+maybe_syscall_getres_cputime (clockid_t clock_id, struct timespec *res)
+{
+ return maybe_syscall_getres_cpu
+ (clock_id == CLOCK_THREAD_CPUTIME_ID
+ ? MAKE_THREAD_CPUCLOCK (0, CPUCLOCK_SCHED)
+ : MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED),
+ res);
+}
+
+# define SYSDEP_GETRES_CPUTIME \
+ case CLOCK_PROCESS_CPUTIME_ID: \
+ case CLOCK_THREAD_CPUTIME_ID: \
+ retval = maybe_syscall_getres_cputime (clock_id, res); \
+ if (retval == 0) \
+ break; \
+ if (retval != EINVAL || !__libc_missing_posix_cpu_timers) \
+ { \
+ __set_errno (retval); \
+ retval = -1; \
+ break; \
+ } \
+ retval = hp_timing_getres (res); \
+ break;
+# if !HP_TIMING_AVAIL
+# define hp_timing_getres(res) (__set_errno (EINVAL), -1)
+# endif
+
+# endif
+#endif
+
+#include <sysdeps/posix/clock_getres.c>
diff --git a/libc/sysdeps/unix/sysv/linux/clock_gettime.c b/libc/sysdeps/unix/sysv/linux/clock_gettime.c
new file mode 100644
index 000000000..5afe20feb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/clock_gettime.c
@@ -0,0 +1,193 @@
+/* clock_gettime -- Get current time from a POSIX clockid_t. Linux version.
+ Copyright (C) 2003,2004,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <errno.h>
+#include <time.h>
+#include "kernel-posix-cpu-timers.h"
+#include <kernel-features.h>
+
+#ifndef HAVE_CLOCK_GETTIME_VSYSCALL
+# undef INTERNAL_VSYSCALL
+# define INTERNAL_VSYSCALL INTERNAL_SYSCALL
+# undef INLINE_VSYSCALL
+# define INLINE_VSYSCALL INLINE_SYSCALL
+#else
+# include <bits/libc-vdso.h>
+#endif
+
+#define SYSCALL_GETTIME \
+ retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \
+ break
+
+#ifdef __ASSUME_POSIX_TIMERS
+
+/* This means the REALTIME and MONOTONIC clock are definitely
+ supported in the kernel. */
+# define SYSDEP_GETTIME \
+ SYSDEP_GETTIME_CPUTIME \
+ case CLOCK_REALTIME: \
+ case CLOCK_MONOTONIC: \
+ SYSCALL_GETTIME
+
+# define __libc_missing_posix_timers 0
+#elif defined __NR_clock_gettime
+/* Is the syscall known to exist? */
+int __libc_missing_posix_timers attribute_hidden;
+
+static inline int
+maybe_syscall_gettime (clockid_t clock_id, struct timespec *tp)
+{
+ int e = EINVAL;
+
+ if (!__libc_missing_posix_timers)
+ {
+ INTERNAL_SYSCALL_DECL (err);
+ int r = INTERNAL_VSYSCALL (clock_gettime, err, 2, clock_id, tp);
+ if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+ return 0;
+
+ e = INTERNAL_SYSCALL_ERRNO (r, err);
+ if (e == ENOSYS)
+ {
+ __libc_missing_posix_timers = 1;
+ e = EINVAL;
+ }
+ }
+
+ return e;
+}
+
+/* The REALTIME and MONOTONIC clock might be available. Try the
+ syscall first. */
+# define SYSDEP_GETTIME \
+ SYSDEP_GETTIME_CPUTIME \
+ case CLOCK_REALTIME: \
+ case CLOCK_MONOTONIC: \
+ retval = maybe_syscall_gettime (clock_id, tp); \
+ if (retval == 0) \
+ break; \
+ /* Fallback code. */ \
+ if (retval == EINVAL && clock_id == CLOCK_REALTIME) \
+ retval = realtime_gettime (tp); \
+ else \
+ { \
+ __set_errno (retval); \
+ retval = -1; \
+ } \
+ break;
+#endif
+
+#ifdef __NR_clock_gettime
+/* We handled the REALTIME clock here. */
+# define HANDLED_REALTIME 1
+# define HANDLED_CPUTIME 1
+
+# if __ASSUME_POSIX_CPU_TIMERS > 0
+
+# define SYSDEP_GETTIME_CPU SYSCALL_GETTIME
+# define SYSDEP_GETTIME_CPUTIME /* Default catches them too. */
+
+# else
+
+int __libc_missing_posix_cpu_timers attribute_hidden;
+
+static int
+maybe_syscall_gettime_cpu (clockid_t clock_id, struct timespec *tp)
+{
+ int e = EINVAL;
+
+ if (!__libc_missing_posix_cpu_timers)
+ {
+ INTERNAL_SYSCALL_DECL (err);
+ int r = INTERNAL_VSYSCALL (clock_gettime, err, 2, clock_id, tp);
+ if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+ return 0;
+
+ e = INTERNAL_SYSCALL_ERRNO (r, err);
+# ifndef __ASSUME_POSIX_TIMERS
+ if (e == ENOSYS)
+ {
+ __libc_missing_posix_timers = 1;
+ __libc_missing_posix_cpu_timers = 1;
+ e = EINVAL;
+ }
+ else
+# endif
+ {
+ if (e == EINVAL)
+ {
+ /* Check whether the kernel supports CPU clocks at all.
+ If not, record it for the future. */
+ r = INTERNAL_VSYSCALL (clock_getres, err, 2,
+ MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED),
+ NULL);
+ if (INTERNAL_SYSCALL_ERROR_P (r, err))
+ __libc_missing_posix_cpu_timers = 1;
+ }
+ }
+ }
+
+ return e;
+}
+
+# define SYSDEP_GETTIME_CPU \
+ retval = maybe_syscall_gettime_cpu (clock_id, tp); \
+ if (retval == 0) \
+ break; \
+ if (retval != EINVAL || !__libc_missing_posix_cpu_timers) \
+ { \
+ __set_errno (retval); \
+ retval = -1; \
+ break; \
+ } \
+ retval = -1 /* Otherwise continue on to the HP_TIMING version. */;
+
+static inline int
+maybe_syscall_gettime_cputime (clockid_t clock_id, struct timespec *tp)
+{
+ return maybe_syscall_gettime_cpu
+ (clock_id == CLOCK_THREAD_CPUTIME_ID
+ ? MAKE_THREAD_CPUCLOCK (0, CPUCLOCK_SCHED)
+ : MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED),
+ tp);
+}
+
+# define SYSDEP_GETTIME_CPUTIME \
+ case CLOCK_PROCESS_CPUTIME_ID: \
+ case CLOCK_THREAD_CPUTIME_ID: \
+ retval = maybe_syscall_gettime_cputime (clock_id, tp); \
+ if (retval == 0) \
+ break; \
+ if (retval != EINVAL || !__libc_missing_posix_cpu_timers) \
+ { \
+ __set_errno (retval); \
+ retval = -1; \
+ break; \
+ } \
+ retval = hp_timing_gettime (clock_id, tp); \
+ break;
+# if !HP_TIMING_AVAIL
+# define hp_timing_gettime(clock_id, tp) (__set_errno (EINVAL), -1)
+# endif
+
+# endif
+#endif
+
+#include <sysdeps/unix/clock_gettime.c>
diff --git a/libc/sysdeps/unix/sysv/linux/clock_nanosleep.c b/libc/sysdeps/unix/sysv/linux/clock_nanosleep.c
new file mode 100644
index 000000000..7645262ce
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/clock_nanosleep.c
@@ -0,0 +1,96 @@
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <time.h>
+#include <errno.h>
+
+#include <sysdep-cancel.h>
+#include <kernel-features.h>
+#include "kernel-posix-cpu-timers.h"
+
+
+#ifdef __ASSUME_POSIX_TIMERS
+/* We can simply use the syscall. The CPU clocks are not supported
+ with this function. */
+int
+clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
+ struct timespec *rem)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ int r;
+
+ if (clock_id == CLOCK_THREAD_CPUTIME_ID)
+ return EINVAL;
+ if (clock_id == CLOCK_PROCESS_CPUTIME_ID)
+ clock_id = MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED);
+
+ if (SINGLE_THREAD_P)
+ r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem);
+ else
+ {
+ int oldstate = LIBC_CANCEL_ASYNC ();
+
+ r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req,
+ rem);
+
+ LIBC_CANCEL_RESET (oldstate);
+ }
+
+ return (INTERNAL_SYSCALL_ERROR_P (r, err)
+ ? INTERNAL_SYSCALL_ERRNO (r, err) : 0);
+}
+
+#else
+# ifdef __NR_clock_nanosleep
+/* Is the syscall known to exist? */
+extern int __libc_missing_posix_timers attribute_hidden;
+
+/* The REALTIME and MONOTONIC clock might be available. Try the
+ syscall first. */
+# define SYSDEP_NANOSLEEP \
+ if (!__libc_missing_posix_timers) \
+ { \
+ clockid_t syscall_clockid; \
+ INTERNAL_SYSCALL_DECL (err); \
+ \
+ if (clock_id == CLOCK_THREAD_CPUTIME_ID) \
+ return EINVAL; \
+ if (clock_id == CLOCK_PROCESS_CPUTIME_ID) \
+ syscall_clockid = MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED); \
+ else \
+ syscall_clockid = clock_id; \
+ \
+ int oldstate = LIBC_CANCEL_ASYNC (); \
+ \
+ int r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, \
+ syscall_clockid, flags, req, rem); \
+ \
+ LIBC_CANCEL_RESET (oldstate); \
+ \
+ if (!INTERNAL_SYSCALL_ERROR_P (r, err)) \
+ return 0; \
+ \
+ if (INTERNAL_SYSCALL_ERRNO (r, err) != ENOSYS) \
+ return INTERNAL_SYSCALL_ERRNO (r, err); \
+ \
+ __libc_missing_posix_timers = 1; \
+ }
+# endif
+
+# include <sysdeps/unix/clock_nanosleep.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/clock_settime.c b/libc/sysdeps/unix/sysv/linux/clock_settime.c
new file mode 100644
index 000000000..217ae3f29
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/clock_settime.c
@@ -0,0 +1,149 @@
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+
+#include "kernel-posix-cpu-timers.h"
+#include <kernel-features.h>
+
+#ifndef HAVE_CLOCK_GETRES_VSYSCALL
+# undef INTERNAL_VSYSCALL
+# define INTERNAL_VSYSCALL INTERNAL_SYSCALL
+# undef INLINE_VSYSCALL
+# define INLINE_VSYSCALL INLINE_SYSCALL
+#else
+# include <bits/libc-vdso.h>
+#endif
+
+#if __ASSUME_POSIX_CPU_TIMERS <= 0 && defined __NR_clock_settime
+extern int __libc_missing_posix_timers attribute_hidden;
+extern int __libc_missing_posix_cpu_timers attribute_hidden;
+
+static int
+maybe_syscall_settime_cpu (clockid_t clock_id, const struct timespec *tp)
+{
+ int e = EINVAL;
+
+ if (!__libc_missing_posix_cpu_timers)
+ {
+ INTERNAL_SYSCALL_DECL (err);
+ int r = INTERNAL_SYSCALL (clock_settime, err, 2, clock_id, tp);
+ if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+ return 0;
+
+ e = INTERNAL_SYSCALL_ERRNO (r, err);
+# ifndef __ASSUME_POSIX_TIMERS
+ if (e == ENOSYS)
+ {
+ __libc_missing_posix_timers = 1;
+ __libc_missing_posix_cpu_timers = 1;
+ e = EINVAL;
+ }
+ else
+# endif
+ {
+ if (e == EINVAL)
+ {
+ /* Check whether the kernel supports CPU clocks at all.
+ If not, record it for the future. */
+ r = INTERNAL_VSYSCALL (clock_getres, err, 2,
+ MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED),
+ NULL);
+ if (INTERNAL_SYSCALL_ERROR_P (r, err))
+ __libc_missing_posix_cpu_timers = 1;
+ }
+ }
+ }
+
+ return e;
+}
+#endif
+
+
+#ifdef __ASSUME_POSIX_TIMERS
+/* This means the REALTIME clock is definitely supported in the
+ kernel. */
+# define SYSDEP_SETTIME \
+ case CLOCK_REALTIME: \
+ retval = INLINE_SYSCALL (clock_settime, 2, clock_id, tp); \
+ break
+#elif defined __NR_clock_settime
+/* Is the syscall known to exist? */
+extern int __libc_missing_posix_timers attribute_hidden;
+
+/* The REALTIME clock might be available. Try the syscall first. */
+# define SYSDEP_SETTIME \
+ case CLOCK_REALTIME: \
+ { \
+ int e = EINVAL; \
+ \
+ if (!__libc_missing_posix_timers) \
+ { \
+ INTERNAL_SYSCALL_DECL (err); \
+ int r = INTERNAL_SYSCALL (clock_settime, err, 2, clock_id, tp); \
+ if (!INTERNAL_SYSCALL_ERROR_P (r, err)) \
+ { \
+ retval = 0; \
+ break; \
+ } \
+ \
+ e = INTERNAL_SYSCALL_ERRNO (r, err); \
+ if (e == ENOSYS) \
+ { \
+ __libc_missing_posix_timers = 1; \
+ e = EINVAL; \
+ } \
+ } \
+ \
+ /* Fallback code. */ \
+ if (e == EINVAL && clock_id == CLOCK_REALTIME) \
+ HANDLE_REALTIME; \
+ else \
+ { \
+ __set_errno (e); \
+ retval = -1; \
+ } \
+ } \
+ break
+#endif
+
+#ifdef __NR_clock_settime
+/* We handled the REALTIME clock here. */
+# define HANDLED_REALTIME 1
+#endif
+
+#if __ASSUME_POSIX_CPU_TIMERS > 0
+# define HANDLED_CPUTIME 1
+# define SYSDEP_SETTIME_CPU \
+ retval = INLINE_SYSCALL (clock_settime, 2, clock_id, tp)
+#elif defined __NR_clock_settime
+# define SYSDEP_SETTIME_CPU \
+ retval = maybe_syscall_settime_cpu (clock_id, tp); \
+ if (retval == 0) \
+ break; \
+ if (retval != EINVAL || !__libc_missing_posix_cpu_timers) \
+ { \
+ __set_errno (retval); \
+ retval = -1; \
+ break; \
+ } \
+ do { } while (0)
+#endif
+
+#include <sysdeps/unix/clock_settime.c>
diff --git a/libc/sysdeps/unix/sysv/linux/cmsg_nxthdr.c b/libc/sysdeps/unix/sysv/linux/cmsg_nxthdr.c
new file mode 100644
index 000000000..b7de285e3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/cmsg_nxthdr.c
@@ -0,0 +1,39 @@
+/* Return point to next ancillary data entry in message header.
+ Copyright (C) 1997, 1998, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/socket.h>
+
+
+struct cmsghdr *
+__cmsg_nxthdr (struct msghdr *mhdr, struct cmsghdr *cmsg)
+{
+ if ((size_t) cmsg->cmsg_len < sizeof (struct cmsghdr))
+ /* The kernel header does this so there may be a reason. */
+ return NULL;
+
+ cmsg = (struct cmsghdr *) ((unsigned char *) cmsg
+ + CMSG_ALIGN (cmsg->cmsg_len));
+ if ((unsigned char *) (cmsg + 1) > ((unsigned char *) mhdr->msg_control
+ + mhdr->msg_controllen)
+ || ((unsigned char *) cmsg + CMSG_ALIGN (cmsg->cmsg_len)
+ > ((unsigned char *) mhdr->msg_control + mhdr->msg_controllen)))
+ /* No more entries. */
+ return NULL;
+ return cmsg;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/configure b/libc/sysdeps/unix/sysv/linux/configure
new file mode 100644
index 000000000..a8a9cc470
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/configure
@@ -0,0 +1,367 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/unix/sysv/linux.
+
+# The Linux kernel headers can be found in
+# /lib/modules/$(uname -r)/build/include
+# Check whether this directory is available.
+if test -z "$sysheaders" &&
+ test "x$cross_compiling" = xno &&
+ test -d /lib/modules/`uname -r`/build/include; then
+ sysheaders="/lib/modules/`uname -r`/build/include"
+ ccheaders=`$CC -print-file-name=include`
+ SYSINCLUDES="-I $sysheaders"
+fi
+
+# Don't bother trying to generate any glue code to be compatible with the
+# existing system library, because we are the only system library.
+inhibit_glue=yes
+
+if test -n "$sysheaders"; then
+ OLD_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $SYSINCLUDES"
+fi
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking installed Linux kernel header files" >&5
+echo $ECHO_N "checking installed Linux kernel header files... $ECHO_C" >&6
+if test "${libc_cv_linux2010+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <linux/version.h>
+#if !defined LINUX_VERSION_CODE || LINUX_VERSION_CODE < (2 *65536+ 0 *256+ 10) /* 2.0.10 */
+eat flaming death
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "eat flaming death" >/dev/null 2>&1; then
+ libc_cv_linux2010='TOO OLD!'
+else
+ libc_cv_linux2010='2.0.10 or later'
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $libc_cv_linux2010" >&5
+echo "${ECHO_T}$libc_cv_linux2010" >&6
+if test "$libc_cv_linux2010" != '2.0.10 or later'; then
+ { { echo "$as_me:$LINENO: error: GNU libc requires kernel header files from
+Linux 2.0.10 or later to be installed before configuring.
+The kernel header files are found usually in /usr/include/asm and
+/usr/include/linux; make sure these directories use files from
+Linux 2.0.10 or later. This check uses <linux/version.h>, so
+make sure that file was built correctly when installing the kernel header
+files. To use kernel headers not from /usr/include/linux, use the
+configure option --with-headers." >&5
+echo "$as_me: error: GNU libc requires kernel header files from
+Linux 2.0.10 or later to be installed before configuring.
+The kernel header files are found usually in /usr/include/asm and
+/usr/include/linux; make sure these directories use files from
+Linux 2.0.10 or later. This check uses <linux/version.h>, so
+make sure that file was built correctly when installing the kernel header
+files. To use kernel headers not from /usr/include/linux, use the
+configure option --with-headers." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# If the user gave a minimal version number test whether the available
+# kernel headers are young enough. Additionally we have minimal
+# kernel versions for some architectures. If a previous configure fragment
+# set arch_minimum_kernel already, let that override our defaults here.
+# Note that we presume such a fragment has set libc_cv_gcc_unwind_find_fde
+# if appropriate too.
+test -n "$arch_minimum_kernel" ||
+case "$machine" in
+ alpha*)
+ arch_minimum_kernel=2.1.100
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ arm*)
+ arch_minimum_kernel=2.0.10
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ i386*)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.0.10
+ ;;
+ ia64*)
+ arch_minimum_kernel=2.4.0
+ ;;
+ hppa*)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.4.19
+ ;;
+ m68k*)
+ arch_minimum_kernel=2.0.10
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ powerpc/powerpc32)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.0.10
+ ;;
+ powerpc/powerpc64)
+ arch_minimum_kernel=2.4.19
+ ;;
+ s390/s390-32)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.2.10
+ ;;
+ s390/s390-64)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.4.0
+ ;;
+ sh*)
+ arch_minimum_kernel=2.3.99
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ sparc/sparc64*)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.4.21
+ ;;
+ sparc*)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.0.10
+ ;;
+ x86_64*)
+ arch_minimum_kernel=2.4.0
+ ;;
+ *)
+ arch_minimum_kernel=2.0.10
+ ;;
+esac
+if test -n "$minimum_kernel"; then
+
+ user_version=$((`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \* 65536 + \2 \* 256 + \3/'`))
+ arch_version=$((`echo "$arch_minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \* 65536 + \2 \* 256 + \3/'`))
+
+ if test $user_version -lt $arch_version; then
+ { echo "$as_me:$LINENO: WARNING: minimum kernel version reset to $arch_minimum_kernel" >&5
+echo "$as_me: WARNING: minimum kernel version reset to $arch_minimum_kernel" >&2;}
+ minimum_kernel=$arch_minimum_kernel
+ fi
+else
+ if test $arch_minimum_kernel != '2.0.10'; then
+ minimum_kernel=$arch_minimum_kernel
+ fi
+fi
+
+if test -n "$minimum_kernel"; then
+ echo "$as_me:$LINENO: checking for kernel header at least $minimum_kernel" >&5
+echo $ECHO_N "checking for kernel header at least $minimum_kernel... $ECHO_C" >&6
+ decnum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/(\1 * 65536 + \2 * 256 + \3)/'`;
+ abinum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1,\2,\3/'`;
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < $decnum
+eat flaming death
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "eat flaming death" >/dev/null 2>&1; then
+ libc_minimum_kernel='too old!'
+else
+ libc_minimum_kernel=ok
+fi
+rm -f conftest*
+
+ echo "$as_me:$LINENO: result: $libc_minimum_kernel" >&5
+echo "${ECHO_T}$libc_minimum_kernel" >&6
+ if test "$libc_minimum_kernel" = ok; then
+ cat >>confdefs.h <<_ACEOF
+#define __LINUX_KERNEL_VERSION $decnum
+_ACEOF
+
+ cat >>confdefs.h <<_ACEOF
+#define __ABI_TAG_VERSION $abinum
+_ACEOF
+
+ else
+ { { echo "$as_me:$LINENO: error: *** The available kernel headers are older than the requested
+*** compatible kernel version" >&5
+echo "$as_me: error: *** The available kernel headers are older than the requested
+*** compatible kernel version" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+
+# The result of the above test for the use of the FDE code is invalid if
+# the user overrides the decision about the minimum ABI.
+if test "$oldest_abi" != default && test "2.2.4" \< "$oldest_abi"; then
+ libc_cv_gcc_unwind_find_fde=no
+fi
+
+if test -n "$sysheaders"; then
+ CPPFLAGS=$OLD_CPPFLAGS
+fi
+# The Linux filesystem standard prescribes where to place "essential"
+# files. I.e., when the installation prefix is "/usr" we have to place
+# shared library objects and the configuration files on the root partition
+# in /lib and /etc.
+case "$prefix" in
+/usr | /usr/)
+ # 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib.
+ # Allow earlier configure scripts to handle libc_cv_slibdir, libdir,
+ # and libc_cv_localedir.
+ test -n "$libc_cv_slibdir" || \
+ case $machine in
+ sparc/sparc64 | x86_64 | powerpc/powerpc64 | s390/s390-64)
+ libc_cv_slibdir="/lib64"
+ if test "$libdir" = '${exec_prefix}/lib'; then
+ libdir='${exec_prefix}/lib64';
+ # Locale data can be shared between 32bit and 64bit libraries
+ libc_cv_localedir='${exec_prefix}/lib/locale'
+ fi
+ ;;
+ *)
+ libc_cv_slibdir="/lib"
+ ;;
+ esac
+ # Allow the user to override the path with --sysconfdir
+ if test $sysconfdir = '${prefix}/etc'; then
+ libc_cv_sysconfdir=/etc
+ else
+ libc_cv_sysconfdir=$sysconfdir
+ fi
+ libc_cv_rootsbindir="/sbin"
+ ;;
+esac
+
+# Under Linux the NPTL add-on should be available.
+case $add_ons in
+ # It is available. Good.
+ *nptl*)
+ nptl_missing=
+ ;;
+ *)
+ nptl_missing=yes
+ ;;
+esac
+
+if test "$nptl_missing"; then
+ if test $enable_sanity = yes; then
+ echo "\
+*** On GNU/Linux systems it is normal to compile GNU libc with the
+*** \`nptl' add-on. Without that, the library will be
+*** incompatible with normal GNU/Linux systems.
+*** If you really mean to not use this add-on, run configure again
+*** using the extra parameter \`--disable-sanity-checks'."
+ exit 1
+ else
+ echo "\
+*** WARNING: Are you sure you do not want to use the \`nptl'
+*** add-on?"
+ fi
+fi
+
+if test "$prefix" = "/usr/local" -o "$prefix" = "/usr/local/" -o "$prefix" = "NONE"; then
+ if test $enable_sanity = yes; then
+ echo "\
+*** On GNU/Linux systems the GNU C Library should not be installed into
+*** /usr/local since this might make your system totally unusable.
+*** We strongly advise to use a different prefix. For details read the FAQ.
+*** If you really mean to do this, run configure again using the extra
+*** parameter \`--disable-sanity-checks'."
+ exit 1
+ else
+ echo "\
+*** WARNING: Do you really want to install the GNU C Library into /usr/local?
+*** This might make your system totally unusable, for details read the FAQ."
+ fi
+fi
+
+
+# One Linux we use ldconfig.
+use_ldconfig=yes
+
+# We need some extensions to the `ldd' script.
+
+case "$machine" in
+ i[3456]86* | m68*)
+ ldd_rewrite_script=../sysdeps/unix/sysv/linux/ldd-rewrite.sed
+ ;;
+ ia64*)
+ ldd_rewrite_script=../sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed
+ ;;
+ s390*)
+ ldd_rewrite_script=../sysdeps/unix/sysv/linux/s390/ldd-rewrite.sed
+ ;;
+ sparc*)
+ ldd_rewrite_script=../sysdeps/unix/sysv/linux/sparc/ldd-rewrite.sed
+ ;;
+ x86_64*)
+ ldd_rewrite_script=../sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed
+ ;;
+ powerpc*)
+ ldd_rewrite_script=../sysdeps/unix/sysv/linux/powerpc/ldd-rewrite.sed
+ ;;
+ *)
+ ;;
+esac
+
+
+if test $host = $build; then
+ # If $prefix/include/{net,scsi} are symlinks, make install will
+ # clobber what they're linked to (probably a kernel tree).
+ # test -L ought to work on all Linux boxes.
+ if test "x$prefix" != xNONE; then
+ ac_prefix=$prefix
+ else
+ ac_prefix=$ac_default_prefix
+ fi
+ echo "$as_me:$LINENO: checking for symlinks in ${ac_prefix}/include" >&5
+echo $ECHO_N "checking for symlinks in ${ac_prefix}/include... $ECHO_C" >&6
+ ac_message=
+ if test -L ${ac_prefix}/include/net; then
+ ac_message="$ac_message
+ ${ac_prefix}/include/net is a symlink"
+ fi
+ if test -L ${ac_prefix}/include/scsi; then
+ ac_message="$ac_message
+ ${ac_prefix}/include/scsi is a symlink"
+ fi
+ if test -n "$ac_message"; then
+ { { echo "$as_me:$LINENO: error: $ac_message
+\`make install' will destroy the target of the link(s).
+Delete the links and re-run configure, or better still, move the entire
+${ac_prefix}/include directory out of the way." >&5
+echo "$as_me: error: $ac_message
+\`make install' will destroy the target of the link(s).
+Delete the links and re-run configure, or better still, move the entire
+${ac_prefix}/include directory out of the way." >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ fi
+fi
+
+# We have inlined syscalls.
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_INLINED_SYSCALLS 1
+_ACEOF
+
diff --git a/libc/sysdeps/unix/sysv/linux/configure.in b/libc/sysdeps/unix/sysv/linux/configure.in
new file mode 100644
index 000000000..43681f325
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/configure.in
@@ -0,0 +1,292 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/unix/sysv/linux.
+
+# The Linux kernel headers can be found in
+# /lib/modules/$(uname -r)/build/include
+# Check whether this directory is available.
+if test -z "$sysheaders" &&
+ test "x$cross_compiling" = xno &&
+ test -d /lib/modules/`uname -r`/build/include; then
+ sysheaders="/lib/modules/`uname -r`/build/include"
+ ccheaders=`$CC -print-file-name=include`
+ dnl We don't have to use -nostdinc. We just want one more directory
+ dnl to be used.
+ SYSINCLUDES="-I $sysheaders"
+fi
+
+# Don't bother trying to generate any glue code to be compatible with the
+# existing system library, because we are the only system library.
+inhibit_glue=yes
+
+define([LIBC_LINUX_VERSION],[2.0.10])dnl
+if test -n "$sysheaders"; then
+ OLD_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $SYSINCLUDES"
+fi
+define([libc_cv_linuxVER], [libc_cv_linux]patsubst(LIBC_LINUX_VERSION,[\.]))dnl
+AC_CACHE_CHECK(installed Linux kernel header files, libc_cv_linuxVER, [dnl
+AC_EGREP_CPP([eat flaming death], [#include <linux/version.h>
+#if !defined LINUX_VERSION_CODE || LINUX_VERSION_CODE < ]dnl
+patsubst(LIBC_LINUX_VERSION,[^\([^.]*\)\.\([^.]*\)\.\([^.]*\)$],dnl
+[ (\1 *65536+ \2 *256+ \3) /* \1.\2.\3 */])[
+eat flaming death
+#endif],
+ libc_cv_linuxVER='TOO OLD!',
+ libc_cv_linuxVER='LIBC_LINUX_VERSION or later')])
+if test "$libc_cv_linuxVER" != 'LIBC_LINUX_VERSION or later'; then
+ AC_MSG_ERROR([GNU libc requires kernel header files from
+Linux LIBC_LINUX_VERSION or later to be installed before configuring.
+The kernel header files are found usually in /usr/include/asm and
+/usr/include/linux; make sure these directories use files from
+Linux LIBC_LINUX_VERSION or later. This check uses <linux/version.h>, so
+make sure that file was built correctly when installing the kernel header
+files. To use kernel headers not from /usr/include/linux, use the
+configure option --with-headers.])
+fi
+
+# If the user gave a minimal version number test whether the available
+# kernel headers are young enough. Additionally we have minimal
+# kernel versions for some architectures. If a previous configure fragment
+# set arch_minimum_kernel already, let that override our defaults here.
+# Note that we presume such a fragment has set libc_cv_gcc_unwind_find_fde
+# if appropriate too.
+test -n "$arch_minimum_kernel" ||
+case "$machine" in
+ alpha*)
+ arch_minimum_kernel=2.1.100
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ arm*)
+ arch_minimum_kernel=2.0.10
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ i386*)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.0.10
+ ;;
+ ia64*)
+ arch_minimum_kernel=2.4.0
+ ;;
+ hppa*)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.4.19
+ ;;
+ m68k*)
+ arch_minimum_kernel=2.0.10
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ powerpc/powerpc32)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.0.10
+ ;;
+ powerpc/powerpc64)
+ arch_minimum_kernel=2.4.19
+ ;;
+ s390/s390-32)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.2.10
+ ;;
+ s390/s390-64)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.4.0
+ ;;
+ sh*)
+ arch_minimum_kernel=2.3.99
+ libc_cv_gcc_unwind_find_fde=yes
+ ;;
+ sparc/sparc64*)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.4.21
+ ;;
+ sparc*)
+ libc_cv_gcc_unwind_find_fde=yes
+ arch_minimum_kernel=2.0.10
+ ;;
+ x86_64*)
+ arch_minimum_kernel=2.4.0
+ ;;
+ *)
+ arch_minimum_kernel=2.0.10
+ ;;
+esac
+if test -n "$minimum_kernel"; then
+ changequote(,)
+ user_version=$((`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \* 65536 + \2 \* 256 + \3/'`))
+ arch_version=$((`echo "$arch_minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \* 65536 + \2 \* 256 + \3/'`))
+ changequote([,])
+ if test $user_version -lt $arch_version; then
+ AC_MSG_WARN([minimum kernel version reset to $arch_minimum_kernel])
+ minimum_kernel=$arch_minimum_kernel
+ fi
+else
+ if test $arch_minimum_kernel != '2.0.10'; then
+ minimum_kernel=$arch_minimum_kernel
+ fi
+fi
+
+if test -n "$minimum_kernel"; then
+ AC_MSG_CHECKING(for kernel header at least $minimum_kernel)
+changequote(,)dnl
+ decnum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/(\1 * 65536 + \2 * 256 + \3)/'`;
+ abinum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1,\2,\3/'`;
+changequote([,])dnl
+ AC_EGREP_CPP([eat flaming death], [#include <linux/version.h>
+#if LINUX_VERSION_CODE < $decnum
+eat flaming death
+#endif], libc_minimum_kernel='too old!', libc_minimum_kernel=ok)
+ AC_MSG_RESULT($libc_minimum_kernel)
+ if test "$libc_minimum_kernel" = ok; then
+ AC_DEFINE_UNQUOTED(__LINUX_KERNEL_VERSION, $decnum)
+ AC_DEFINE_UNQUOTED(__ABI_TAG_VERSION, $abinum)
+ else
+ AC_MSG_ERROR([*** The available kernel headers are older than the requested
+*** compatible kernel version])
+ fi
+fi
+
+# The result of the above test for the use of the FDE code is invalid if
+# the user overrides the decision about the minimum ABI.
+if test "$oldest_abi" != default && test "2.2.4" \< "$oldest_abi"; then
+ libc_cv_gcc_unwind_find_fde=no
+fi
+
+if test -n "$sysheaders"; then
+ CPPFLAGS=$OLD_CPPFLAGS
+fi
+# The Linux filesystem standard prescribes where to place "essential"
+# files. I.e., when the installation prefix is "/usr" we have to place
+# shared library objects and the configuration files on the root partition
+# in /lib and /etc.
+case "$prefix" in
+/usr | /usr/)
+ # 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib.
+ # Allow earlier configure scripts to handle libc_cv_slibdir, libdir,
+ # and libc_cv_localedir.
+ test -n "$libc_cv_slibdir" || \
+ case $machine in
+ sparc/sparc64 | x86_64 | powerpc/powerpc64 | s390/s390-64)
+ libc_cv_slibdir="/lib64"
+ if test "$libdir" = '${exec_prefix}/lib'; then
+ libdir='${exec_prefix}/lib64';
+ # Locale data can be shared between 32bit and 64bit libraries
+ libc_cv_localedir='${exec_prefix}/lib/locale'
+ fi
+ ;;
+ *)
+ libc_cv_slibdir="/lib"
+ ;;
+ esac
+ # Allow the user to override the path with --sysconfdir
+ if test $sysconfdir = '${prefix}/etc'; then
+ libc_cv_sysconfdir=/etc
+ else
+ libc_cv_sysconfdir=$sysconfdir
+ fi
+ libc_cv_rootsbindir="/sbin"
+ ;;
+esac
+
+# Under Linux the NPTL add-on should be available.
+case $add_ons in
+ # It is available. Good.
+ *nptl*)
+ nptl_missing=
+ ;;
+ *)
+ nptl_missing=yes
+ ;;
+esac
+
+if test "$nptl_missing"; then
+ if test $enable_sanity = yes; then
+ echo "\
+*** On GNU/Linux systems it is normal to compile GNU libc with the
+*** \`nptl' add-on. Without that, the library will be
+*** incompatible with normal GNU/Linux systems.
+*** If you really mean to not use this add-on, run configure again
+*** using the extra parameter \`--disable-sanity-checks'."
+ exit 1
+ else
+ echo "\
+*** WARNING: Are you sure you do not want to use the \`nptl'
+*** add-on?"
+ fi
+fi
+
+if test "$prefix" = "/usr/local" -o "$prefix" = "/usr/local/" -o "$prefix" = "NONE"; then
+ if test $enable_sanity = yes; then
+ echo "\
+*** On GNU/Linux systems the GNU C Library should not be installed into
+*** /usr/local since this might make your system totally unusable.
+*** We strongly advise to use a different prefix. For details read the FAQ.
+*** If you really mean to do this, run configure again using the extra
+*** parameter \`--disable-sanity-checks'."
+ exit 1
+ else
+ echo "\
+*** WARNING: Do you really want to install the GNU C Library into /usr/local?
+*** This might make your system totally unusable, for details read the FAQ."
+ fi
+fi
+
+
+# One Linux we use ldconfig.
+use_ldconfig=yes
+
+# We need some extensions to the `ldd' script.
+changequote(,)
+case "$machine" in
+ i[3456]86* | m68*)
+ ldd_rewrite_script=../sysdeps/unix/sysv/linux/ldd-rewrite.sed
+ ;;
+ ia64*)
+ ldd_rewrite_script=../sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed
+ ;;
+ s390*)
+ ldd_rewrite_script=../sysdeps/unix/sysv/linux/s390/ldd-rewrite.sed
+ ;;
+ sparc*)
+ ldd_rewrite_script=../sysdeps/unix/sysv/linux/sparc/ldd-rewrite.sed
+ ;;
+ x86_64*)
+ ldd_rewrite_script=../sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed
+ ;;
+ powerpc*)
+ ldd_rewrite_script=../sysdeps/unix/sysv/linux/powerpc/ldd-rewrite.sed
+ ;;
+ *)
+ ;;
+esac
+changequote([,])
+
+if test $host = $build; then
+ # If $prefix/include/{net,scsi} are symlinks, make install will
+ # clobber what they're linked to (probably a kernel tree).
+ # test -L ought to work on all Linux boxes.
+ if test "x$prefix" != xNONE; then
+ ac_prefix=$prefix
+ else
+ ac_prefix=$ac_default_prefix
+ fi
+ AC_MSG_CHECKING([for symlinks in ${ac_prefix}/include])
+ ac_message=
+ if test -L ${ac_prefix}/include/net; then
+ ac_message="$ac_message
+ ${ac_prefix}/include/net is a symlink"
+ fi
+ if test -L ${ac_prefix}/include/scsi; then
+ ac_message="$ac_message
+ ${ac_prefix}/include/scsi is a symlink"
+ fi
+ if test -n "$ac_message"; then
+ AC_MSG_ERROR([$ac_message
+\`make install' will destroy the target of the link(s).
+Delete the links and re-run configure, or better still, move the entire
+${ac_prefix}/include directory out of the way.])
+ else
+ AC_MSG_RESULT(ok)
+ fi
+fi
+
+# We have inlined syscalls.
+AC_DEFINE(HAVE_INLINED_SYSCALLS)
diff --git a/libc/sysdeps/unix/sysv/linux/connect.S b/libc/sysdeps/unix/sysv/linux/connect.S
new file mode 100644
index 000000000..7d1fa12b3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/connect.S
@@ -0,0 +1,7 @@
+#define socket connect
+#define __socket __libc_connect
+#define NARGS 3
+#define NEED_CANCELLATION
+#include <socket.S>
+strong_alias (__libc_connect, __connect_internal)
+weak_alias (__libc_connect, __connect)
diff --git a/libc/sysdeps/unix/sysv/linux/device-nrs.h b/libc/sysdeps/unix/sysv/linux/device-nrs.h
new file mode 100644
index 000000000..b30c1dbed
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/device-nrs.h
@@ -0,0 +1,46 @@
+/* Device numbers of devices used in the implementation. Linux version.
+ Copyright (C) 2000, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DEVICE_NRS_H
+#define _DEVICE_NRS_H 1
+
+#include <sys/sysmacros.h>
+
+/* /dev/null is (1,3). */
+#define DEV_NULL_MAJOR 1
+#define DEV_NULL_MINOR 3
+
+/* /dev/full is (1,7). */
+#define DEV_FULL_MAJOR 1
+#define DEV_FULL_MINOR 7
+
+/* Pseudo tty slaves. For Linux we use the Unix98 ttys. We could
+ also include the old BSD-style tty buts they should not be used and
+ the extra test would only slow down correctly set up systems. If a
+ system still uses those device the slower tests performed (using
+ isatty) will catch it. */
+#define DEV_TTY_LOW_MAJOR 136
+#define DEV_TTY_HIGH_MAJOR 143
+
+/* Test whether given device is a tty. */
+#define DEV_TTY_P(statp) \
+ ({ int __dev_major = major ((statp)->st_rdev); \
+ __dev_major >= DEV_TTY_LOW_MAJOR && __dev_major <= DEV_TTY_HIGH_MAJOR; })
+
+#endif /* device-nrs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/dl-brk.c b/libc/sysdeps/unix/sysv/linux/dl-brk.c
new file mode 100644
index 000000000..c37cdfec3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/dl-brk.c
@@ -0,0 +1,5 @@
+/* We can use the normal code but we also know the __curbrk is not exported
+ from ld.so. */
+extern void *__curbrk attribute_hidden;
+
+#include <brk.c>
diff --git a/libc/sysdeps/unix/sysv/linux/dl-execstack.c b/libc/sysdeps/unix/sysv/linux/dl-execstack.c
new file mode 100644
index 000000000..fcac5ae24
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/dl-execstack.c
@@ -0,0 +1,154 @@
+/* Stack executability handling for GNU dynamic linker. Linux version.
+ Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ldsodefs.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <libintl.h>
+#include <stdbool.h>
+#include <stackinfo.h>
+#include <caller.h>
+#include <sysdep.h>
+
+#include <kernel-features.h>
+
+
+extern int __stack_prot attribute_relro attribute_hidden;
+
+
+int
+internal_function
+_dl_make_stack_executable (void **stack_endp)
+{
+ /* This gives us the highest/lowest page that needs to be changed. */
+ uintptr_t page = ((uintptr_t) *stack_endp
+ & -(intptr_t) GLRO(dl_pagesize));
+ int result = 0;
+
+ /* Challenge the caller. */
+ if (__builtin_expect (__check_caller (RETURN_ADDRESS (0),
+ allow_ldso|allow_libpthread) != 0, 0)
+ || __builtin_expect (*stack_endp != __libc_stack_end, 0))
+ return EPERM;
+
+ /* Newer Linux kernels support a flag to make our job easy. */
+#if defined PROT_GROWSDOWN || defined PROT_GROWSUP
+# if __ASSUME_PROT_GROWSUPDOWN == 0
+ static bool no_growsupdown;
+ if (! no_growsupdown)
+# endif
+ {
+ if (__builtin_expect (__mprotect ((void *) page, GLRO(dl_pagesize),
+ __stack_prot) == 0, 1))
+ goto return_success;
+# if __ASSUME_PROT_GROWSUPDOWN == 0
+ if (errno == EINVAL)
+ no_growsupdown = true;
+ else
+# endif
+ {
+ result = errno;
+ goto out;
+ }
+ }
+#endif
+
+ /* There is always a hole in the address space below the bottom of the
+ stack. So when we make an mprotect call that starts below the bottom
+ of the stack, it will include the hole and fail with ENOMEM.
+
+ We start with a random guess at how deep the stack might have gotten
+ so as to have extended the GROWSDOWN mapping to lower pages. */
+
+#if __ASSUME_PROT_GROWSUPDOWN == 0
+ size_t size = GLRO(dl_pagesize) * 8;
+
+# if _STACK_GROWS_DOWN
+ page = page + GLRO(dl_pagesize) - size;
+ while (1)
+ {
+ if (__mprotect ((void *) page, size,
+ __stack_prot & ~PROT_GROWSDOWN) == 0)
+ /* We got this chunk changed; loop to do another chunk below. */
+ page -= size;
+ else
+ {
+ if (errno != ENOMEM) /* Unexpected failure mode. */
+ {
+ result = errno;
+ goto out;
+ }
+
+ if (size == GLRO(dl_pagesize))
+ /* We just tried to mprotect the top hole page and failed.
+ We are done. */
+ break;
+
+ /* Our mprotect call failed because it started below the lowest
+ stack page. Try again on just the top half of that region. */
+ size /= 2;
+ page += size;
+ }
+ }
+
+# elif _STACK_GROWS_UP
+ while (1)
+ {
+ if (__mprotect ((void *) page, size, __stack_prot & ~PROT_GROWSUP) == 0)
+ /* We got this chunk changed; loop to do another chunk below. */
+ page += size;
+ else
+ {
+ if (errno != ENOMEM) /* Unexpected failure mode. */
+ {
+ result = errno;
+ goto out;
+ }
+
+ if (size == GLRO(dl_pagesize))
+ /* We just tried to mprotect the lowest hole page and failed.
+ We are done. */
+ break;
+
+ /* Our mprotect call failed because it extended past the highest
+ stack page. Try again on just the bottom half of that region. */
+ size /= 2;
+ }
+ }
+
+# else
+# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
+# endif
+#endif
+
+ return_success:
+ /* Clear the address. */
+ *stack_endp = NULL;
+
+ /* Remember that we changed the permission. */
+ GL(dl_stack_flags) |= PF_X;
+
+ out:
+#ifdef check_consistency
+ check_consistency ();
+#endif
+
+ return result;
+}
+rtld_hidden_def (_dl_make_stack_executable)
diff --git a/libc/sysdeps/unix/sysv/linux/dl-librecon.h b/libc/sysdeps/unix/sysv/linux/dl-librecon.h
new file mode 100644
index 000000000..db46b98fb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/dl-librecon.h
@@ -0,0 +1,61 @@
+/* Optional code to distinguish library flavours.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DL_LIBRECON_H
+#define _DL_LIBRECON_H 1
+
+static inline void __attribute__ ((unused, always_inline))
+_dl_osversion_init (char *assume_kernel)
+{
+ unsigned long int i, j, osversion = 0;
+ char *p = assume_kernel, *q;
+
+ for (i = 0; i < 3; i++, p = q + 1)
+ {
+ j = __strtoul_internal (p, &q, 0, 0);
+ if (j >= 255 || p == q || (i < 2 && *q && *q != '.'))
+ {
+ osversion = 0;
+ break;
+ }
+ osversion |= j << (16 - 8 * i);
+ if (!*q)
+ break;
+ }
+ if (osversion)
+ GLRO(dl_osversion) = osversion;
+}
+
+/* Recognizing extra environment variables. */
+#define EXTRA_LD_ENVVARS_13 \
+ if (memcmp (envline, "ASSUME_KERNEL", 13) == 0) \
+ { \
+ _dl_osversion_init (&envline[14]); \
+ break; \
+ }
+
+#define DL_OSVERSION_INIT \
+ do { \
+ char *assume_kernel = getenv ("LD_ASSUME_KERNEL"); \
+ if (assume_kernel) \
+ _dl_osversion_init (assume_kernel); \
+ } while (0)
+
+#endif /* dl-librecon.h */
diff --git a/libc/sysdeps/unix/sysv/linux/dl-origin.c b/libc/sysdeps/unix/sysv/linux/dl-origin.c
new file mode 100644
index 000000000..a7fa53ea1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/dl-origin.c
@@ -0,0 +1,81 @@
+/* Find path of executable.
+ Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <ldsodefs.h>
+#include <sysdep.h>
+
+#include <dl-dst.h>
+
+/* On Linux >= 2.1 systems which have the dcache implementation we can get
+ the path of the application from the /proc/self/exe symlink. Try this
+ first and fall back on the generic method if necessary. */
+
+const char *
+_dl_get_origin (void)
+{
+ char linkval[PATH_MAX];
+ char *result;
+ int len;
+ INTERNAL_SYSCALL_DECL (err);
+
+ len = INTERNAL_SYSCALL (readlink, err, 3, "/proc/self/exe", linkval,
+ sizeof (linkval));
+ if (! INTERNAL_SYSCALL_ERROR_P (len, err) && len > 0 && linkval[0] != '[')
+ {
+ /* We can use this value. */
+ assert (linkval[0] == '/');
+ while (len > 1 && linkval[len - 1] != '/')
+ --len;
+ result = (char *) malloc (len + 1);
+ if (result == NULL)
+ result = (char *) -1;
+ else if (len == 1)
+ memcpy (result, "/", 2);
+ else
+ *((char *) __mempcpy (result, linkval, len - 1)) = '\0';
+ }
+ else
+ {
+ result = (char *) -1;
+ /* We use the environment variable LD_ORIGIN_PATH. If it is set make
+ a copy and strip out trailing slashes. */
+ if (GLRO(dl_origin_path) != NULL)
+ {
+ size_t len = strlen (GLRO(dl_origin_path));
+ result = (char *) malloc (len + 1);
+ if (result == NULL)
+ result = (char *) -1;
+ else
+ {
+ char *cp = __mempcpy (result, GLRO(dl_origin_path), len);
+ while (cp > result + 1 && cp[-1] == '/')
+ --cp;
+ *cp = '\0';
+ }
+ }
+ }
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/dl-osinfo.h b/libc/sysdeps/unix/sysv/linux/dl-osinfo.h
new file mode 100644
index 000000000..0738501a5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/dl-osinfo.h
@@ -0,0 +1,180 @@
+/* Operating system specific code for generic dynamic loader functions. Linux.
+ Copyright (C) 2000,2001,2002,2004,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <fcntl.h>
+#include <sys/utsname.h>
+#include <kernel-features.h>
+#include <dl-sysdep.h>
+#include <stdint.h>
+
+#ifndef MIN
+# define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+
+#ifdef SHARED
+/* This is the function used in the dynamic linker to print the fatal error
+ message. */
+static inline void
+__attribute__ ((__noreturn__))
+dl_fatal (const char *str)
+{
+ _dl_dprintf (2, str);
+ _exit (1);
+}
+#endif
+
+static inline int __attribute__ ((always_inline))
+_dl_discover_osversion (void)
+{
+#if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED
+ if (GLRO(dl_sysinfo_map) != NULL)
+ {
+ /* If the kernel-supplied DSO contains a note indicating the kernel's
+ version, we don't need to call uname or parse any strings. */
+
+ static const struct
+ {
+ ElfW(Word) vendorlen;
+ ElfW(Word) datalen;
+ ElfW(Word) type;
+ char vendor[8];
+ } expected_note = { sizeof "Linux", sizeof (ElfW(Word)), 0, "Linux" };
+ const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr;
+ const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum;
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdr[i].p_type == PT_NOTE)
+ {
+ const ElfW(Addr) start = (phdr[i].p_vaddr
+ + GLRO(dl_sysinfo_map)->l_addr);
+ const struct
+ {
+ ElfW(Word) vendorlen;
+ ElfW(Word) datalen;
+ ElfW(Word) type;
+ } *note = (const void *) start;
+ while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz)
+ {
+ if (!memcmp (note, &expected_note, sizeof expected_note))
+ return *(const ElfW(Word) *) ((const void *) note
+ + sizeof expected_note);
+#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
+ note = ((const void *) (note + 1)
+ + ROUND (note->vendorlen) + ROUND (note->datalen));
+ }
+ }
+ }
+#endif
+
+ char bufmem[64];
+ char *buf = bufmem;
+ unsigned int version;
+ int parts;
+ char *cp;
+ struct utsname uts;
+
+ /* Try the uname system call. */
+ if (__uname (&uts))
+ {
+ /* This was not successful. Now try reading the /proc filesystem. */
+ int fd = __open ("/proc/sys/kernel/osrelease", O_RDONLY);
+ if (fd < 0)
+ return -1;
+ ssize_t reslen = __read (fd, bufmem, sizeof (bufmem));
+ __close (fd);
+ if (reslen <= 0)
+ /* This also didn't work. We give up since we cannot
+ make sure the library can actually work. */
+ return -1;
+ buf[MIN (reslen, (ssize_t) sizeof (bufmem) - 1)] = '\0';
+ }
+ else
+ buf = uts.release;
+
+ /* Now convert it into a number. The string consists of at most
+ three parts. */
+ version = 0;
+ parts = 0;
+ cp = buf;
+ while ((*cp >= '0') && (*cp <= '9'))
+ {
+ unsigned int here = *cp++ - '0';
+
+ while ((*cp >= '0') && (*cp <= '9'))
+ {
+ here *= 10;
+ here += *cp++ - '0';
+ }
+
+ ++parts;
+ version <<= 8;
+ version |= here;
+
+ if (*cp++ != '.')
+ /* Another part following? */
+ break;
+ }
+
+ if (parts < 3)
+ version <<= 8 * (3 - parts);
+
+ return version;
+}
+
+#define DL_SYSDEP_OSCHECK(FATAL) \
+ do { \
+ /* Test whether the kernel is new enough. This test is only performed \
+ if the library is not compiled to run on all kernels. */ \
+ \
+ int version = _dl_discover_osversion (); \
+ if (__builtin_expect (version >= 0, 1)) \
+ { \
+ if (__builtin_expect (GLRO(dl_osversion) == 0, 1) \
+ || GLRO(dl_osversion) > version) \
+ GLRO(dl_osversion) = version; \
+ \
+ /* Now we can test with the required version. */ \
+ if (__LINUX_KERNEL_VERSION > 0 && version < __LINUX_KERNEL_VERSION) \
+ /* Not sufficent. */ \
+ FATAL ("FATAL: kernel too old\n"); \
+ } \
+ else if (__LINUX_KERNEL_VERSION > 0) \
+ FATAL ("FATAL: cannot determine kernel version\n"); \
+ } while (0)
+
+static inline uintptr_t __attribute__ ((always_inline))
+_dl_setup_stack_chk_guard (void)
+{
+ uintptr_t ret;
+#ifdef ENABLE_STACKGUARD_RANDOMIZE
+ int fd = __open ("/dev/urandom", O_RDONLY);
+ if (fd >= 0)
+ {
+ ssize_t reslen = __read (fd, &ret, sizeof (ret));
+ __close (fd);
+ if (reslen == (ssize_t) sizeof (ret))
+ return ret;
+ }
+#endif
+ ret = 0;
+ unsigned char *p = (unsigned char *) &ret;
+ p[sizeof (ret) - 1] = 255;
+ p[sizeof (ret) - 2] = '\n';
+ return ret;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/dl-sbrk.c b/libc/sysdeps/unix/sysv/linux/dl-sbrk.c
new file mode 100644
index 000000000..1ce5cb188
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/dl-sbrk.c
@@ -0,0 +1,5 @@
+/* We can use the normal code but we also know the __curbrk is not exported
+ from ld.so. */
+extern void *__curbrk attribute_hidden;
+
+#include <misc/sbrk.c>
diff --git a/libc/sysdeps/unix/sysv/linux/dl-sysdep.c b/libc/sysdeps/unix/sysv/linux/dl-sysdep.c
new file mode 100644
index 000000000..42aec77e8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/dl-sysdep.c
@@ -0,0 +1,56 @@
+/* Dynamic linker system dependencies for Linux.
+ Copyright (C) 1995,1997,2001,2004,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Linux needs some special initialization, but otherwise uses
+ the generic dynamic linker system interface code. */
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <kernel-features.h>
+
+#define DL_SYSDEP_INIT frob_brk ()
+
+static inline void
+frob_brk (void)
+{
+ __brk (0); /* Initialize the break. */
+
+#if ! __ASSUME_BRK_PAGE_ROUNDED
+ /* If the dynamic linker was executed as a program, then the break may
+ start immediately after our data segment. However, dl-minimal.c has
+ already stolen the remainder of the page for internal allocations.
+ If we don't adjust the break location recorded by the kernel, the
+ normal program startup will inquire, find the value at our &_end,
+ and start allocating its own data there, clobbering dynamic linker
+ data structures allocated there during startup.
+
+ Later Linux kernels have changed this behavior so that the initial
+ break value is rounded up to the page boundary before we start. */
+
+ extern void *__curbrk attribute_hidden;
+ extern void _end attribute_hidden;
+ void *const endpage = (void *) 0 + (((__curbrk - (void *) 0)
+ + GLRO(dl_pagesize) - 1)
+ & -GLRO(dl_pagesize));
+ if (__builtin_expect (__curbrk >= &_end && __curbrk < endpage, 0))
+ __brk (endpage);
+#endif
+}
+
+#include <elf/dl-sysdep.c>
diff --git a/libc/sysdeps/unix/sysv/linux/dl-sysdep.h b/libc/sysdeps/unix/sysv/linux/dl-sysdep.h
new file mode 100644
index 000000000..becfc8df3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/dl-sysdep.h
@@ -0,0 +1,27 @@
+/* System-specific settings for dynamic linker code. Linux version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include_next <dl-sysdep.h>
+
+/* On many architectures the kernel provides a virtual DSO and gives
+ AT_SYSINFO_EHDR to point us to it. As this is introduced for new
+ machines, we should look at it for unwind information even if
+ we aren't making direct use of it. So enable this across the board. */
+
+#define NEED_DL_SYSINFO_DSO 1
diff --git a/libc/sysdeps/unix/sysv/linux/errqueue.h b/libc/sysdeps/unix/sysv/linux/errqueue.h
new file mode 100644
index 000000000..9ed6dc62b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/errqueue.h
@@ -0,0 +1,46 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Linux version. */
+
+#ifndef _BITS_ERRQUEUE_H
+#define _BITS_ERRQUEUE_H 1
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+struct sock_extended_err
+ {
+ u_int32_t ee_errno;
+ u_int8_t ee_origin;
+ u_int8_t ee_type;
+ u_int8_t ee_code;
+ u_int8_t ee_pad;
+ u_int32_t ee_info;
+ u_int32_t ee_data;
+ };
+
+#define SO_EE_ORIGIN_NONE 0
+#define SO_EE_ORIGIN_LOCAL 1
+#define SO_EE_ORIGIN_ICMP 2
+#define SO_EE_ORIGIN_ICMP6 3
+
+#define SO_EE_OFFENDER(see) \
+ ((struct sockaddr *)(((struct sock_extended_err)(see))+1))
+
+#endif /* bits/errqueue.h */
diff --git a/libc/sysdeps/unix/sysv/linux/execve.c b/libc/sysdeps/unix/sysv/linux/execve.c
new file mode 100644
index 000000000..41dc0e75b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/execve.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <alloca.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+int
+__execve (file, argv, envp)
+ const char *file;
+ char *const argv[];
+ char *const envp[];
+{
+#if __BOUNDED_POINTERS__
+ {
+ char *const *v;
+ int i;
+ char *__unbounded *__unbounded ubp_argv;
+ char *__unbounded *__unbounded ubp_envp;
+ char *__unbounded *__unbounded ubp_v;
+
+ for (v = argv; *v; v++)
+ ;
+ i = v - argv + 1;
+ ubp_argv = (char *__unbounded *__unbounded) alloca (sizeof (*ubp_argv) * i);
+ for (v = argv, ubp_v = ubp_argv; --i; v++, ubp_v++)
+ *ubp_v = CHECK_STRING (*v);
+ *ubp_v = 0;
+
+ for (v = envp; *v; v++)
+ ;
+ i = v - envp + 1;
+ ubp_envp = (char *__unbounded *__unbounded) alloca (sizeof (*ubp_envp) * i);
+ for (v = envp, ubp_v = ubp_envp; --i; v++, ubp_v++)
+ *ubp_v = CHECK_STRING (*v);
+ *ubp_v = 0;
+
+ return INLINE_SYSCALL (execve, 3, CHECK_STRING (file), ubp_argv, ubp_envp);
+ }
+#else
+ return INLINE_SYSCALL (execve, 3, file, argv, envp);
+#endif
+}
+weak_alias (__execve, execve)
diff --git a/libc/sysdeps/unix/sysv/linux/exit-thread.S b/libc/sysdeps/unix/sysv/linux/exit-thread.S
new file mode 100644
index 000000000..bb996fecf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/exit-thread.S
@@ -0,0 +1,23 @@
+/* Copyright (C) 1991,92,97,99,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+PSEUDO (__exit_thread, exit, 1)
+ /* Shouldn't get here. */
+PSEUDO_END(__exit_thread)
diff --git a/libc/sysdeps/unix/sysv/linux/faccessat.c b/libc/sysdeps/unix/sysv/linux/faccessat.c
new file mode 100644
index 000000000..10b903d07
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/faccessat.c
@@ -0,0 +1,143 @@
+/* Test for access to file, relative to open directory. Linux version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <alloca.h>
+#include <kernel-features.h>
+#include <sysdep.h>
+
+
+int
+faccessat (fd, file, mode, flag)
+ int fd;
+ const char *file;
+ int mode;
+ int flag;
+{
+ if (flag & ~(AT_SYMLINK_NOFOLLOW | AT_EACCESS))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+#ifdef __NR_faccessat
+ if ((flag == 0 || ((flag & ~AT_EACCESS) == 0 && ! __libc_enable_secure))
+# ifndef __ASSUME_ATFCTS
+ && __have_atfcts >= 0
+# endif
+ )
+ {
+ int result = INLINE_SYSCALL (faccessat, 3, fd, file, mode);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ if ((!(flag & AT_EACCESS) || ! __libc_enable_secure)
+# ifndef __NR_laccess /* Linux so far has no laccess syscall. */
+ && !(flag & AT_SYMLINK_NOFOLLOW)
+# endif
+ )
+ {
+ /* If we are not set-uid or set-gid, access does the same. */
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ int result;
+ INTERNAL_SYSCALL_DECL (err);
+
+# ifdef __NR_laccess
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (laccess, err, 2, file, mode);
+ else
+# endif
+ result = INTERNAL_SYSCALL (access, err, 2, file, mode);
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ {
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
+ result = -1;
+ }
+
+ return result;
+ }
+#endif
+
+ struct stat64 stats;
+ if (fstatat64 (fd, file, &stats, flag & AT_SYMLINK_NOFOLLOW))
+ return -1;
+
+ mode &= (X_OK | W_OK | R_OK); /* Clear any bogus bits. */
+#if R_OK != S_IROTH || W_OK != S_IWOTH || X_OK != S_IXOTH
+# error Oops, portability assumptions incorrect.
+#endif
+
+ if (mode == F_OK)
+ return 0; /* The file exists. */
+
+ uid_t uid = (flag & AT_EACCESS) ? __geteuid () : __getuid ();
+
+ /* The super-user can read and write any file, and execute any file
+ that anyone can execute. */
+ if (uid == 0 && ((mode & X_OK) == 0
+ || (stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
+ return 0;
+
+ int granted = (uid == stats.st_uid
+ ? (unsigned int) (stats.st_mode & (mode << 6)) >> 6
+ : (stats.st_gid == ((flag & AT_EACCESS)
+ ? __getegid () : __getgid ())
+ || __group_member (stats.st_gid))
+ ? (unsigned int) (stats.st_mode & (mode << 3)) >> 3
+ : (stats.st_mode & mode));
+
+ if (granted == mode)
+ return 0;
+
+ __set_errno (EACCES);
+ return -1;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/fatal-prepare.h b/libc/sysdeps/unix/sysv/linux/fatal-prepare.h
new file mode 100644
index 000000000..d48ae625e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fatal-prepare.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <pthread.h>
+
+/* We have to completely disable cancellation. assert() must not be a
+ cancellation point but the implementation uses write() etc. */
+#ifdef SHARED
+# include <pthread-functions.h>
+# define FATAL_PREPARE \
+ { \
+ int (*fp) (int, int *); \
+ fp = __libc_pthread_functions.ptr_pthread_setcancelstate; \
+ if (fp != NULL) \
+ fp (PTHREAD_CANCEL_DISABLE, NULL); \
+ }
+#else
+# pragma weak pthread_setcancelstate
+# define FATAL_PREPARE \
+ { \
+ if (pthread_setcancelstate != NULL) \
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); \
+ }
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/fchmodat.c b/libc/sysdeps/unix/sysv/linux/fchmodat.c
new file mode 100644
index 000000000..8b420153f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fchmodat.c
@@ -0,0 +1,106 @@
+/* Change the protections of file relative to open directory. Linux version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <alloca.h>
+#include <kernel-features.h>
+#include <sysdep.h>
+
+int
+fchmodat (fd, file, mode, flag)
+ int fd;
+ const char *file;
+ mode_t mode;
+ int flag;
+{
+ if (flag & ~AT_SYMLINK_NOFOLLOW)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+#ifndef __NR_lchmod /* Linux so far has no lchmod syscall. */
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ {
+ __set_errno (ENOTSUP);
+ return -1;
+ }
+#endif
+
+ int result;
+
+#ifdef __NR_fchmodat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INLINE_SYSCALL (fchmodat, 3, fd, file, mode);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+# ifdef __NR_lchmod
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lchmod, err, 2, file, mode);
+ else
+# endif
+ result = INTERNAL_SYSCALL (chmod, err, 2, file, mode);
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ {
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
+ result = -1;
+ }
+
+ return result;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/fchownat.c b/libc/sysdeps/unix/sysv/linux/fchownat.c
new file mode 100644
index 000000000..0f731775b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fchownat.c
@@ -0,0 +1,99 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <alloca.h>
+#include <sysdep.h>
+#include <kernel-features.h>
+
+
+/* Change the owner and group of FILE. */
+int
+fchownat (fd, file, owner, group, flag)
+ int fd;
+ const char *file;
+ uid_t owner;
+ gid_t group;
+ int flag;
+{
+ int result;
+
+#ifdef __NR_fchownat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INLINE_SYSCALL (fchownat, 5, fd, file, owner, group, flag);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ if (flag & ~AT_SYMLINK_NOFOLLOW)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lchown, err, 3, file, owner, group);
+ else
+ result = INTERNAL_SYSCALL (chown, err, 3, file, owner, group);
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ {
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
+ result = -1;
+ }
+
+ return result;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/fcntl.c b/libc/sysdeps/unix/sysv/linux/fcntl.c
new file mode 100644
index 000000000..1f5aca14a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fcntl.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <sysdep-cancel.h> /* Must come before <fcntl.h>. */
+#include <fcntl.h>
+#include <stdarg.h>
+
+#include <sys/syscall.h>
+
+
+#ifndef NO_CANCELLATION
+int
+__fcntl_nocancel (int fd, int cmd, ...)
+{
+ va_list ap;
+ void *arg;
+
+ va_start (ap, cmd);
+ arg = va_arg (ap, void *);
+ va_end (ap);
+
+ return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+}
+#endif
+
+
+int
+__libc_fcntl (int fd, int cmd, ...)
+{
+ va_list ap;
+ void *arg;
+
+ va_start (ap, cmd);
+ arg = va_arg (ap, void *);
+ va_end (ap);
+
+ if (SINGLE_THREAD_P || cmd != F_SETLKW)
+ return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+libc_hidden_def (__libc_fcntl)
+
+weak_alias (__libc_fcntl, __fcntl)
+libc_hidden_weak (__fcntl)
+weak_alias (__libc_fcntl, fcntl)
diff --git a/libc/sysdeps/unix/sysv/linux/fd_to_filename.h b/libc/sysdeps/unix/sysv/linux/fd_to_filename.h
new file mode 100644
index 000000000..dc1bdcc92
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fd_to_filename.h
@@ -0,0 +1,46 @@
+/* Query filename corresponding to an open FD. Linux version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <stdio-common/_itoa.h>
+
+static inline const char *
+fd_to_filename (int fd)
+{
+ char *ret = malloc (30);
+
+ if (ret != NULL)
+ {
+ struct stat64 st;
+
+ *_fitoa_word (fd, __stpcpy (ret, "/proc/self/fd/"), 10, 0) = '\0';
+
+ /* We must make sure the file exists. */
+ if (__lxstat64 (_STAT_VER, ret, &st) < 0)
+ {
+ /* /proc is not mounted or something else happened. Don't
+ return the file name. */
+ free (ret);
+ ret = NULL;
+ }
+ }
+ return ret;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/fexecve.c b/libc/sysdeps/unix/sysv/linux/fexecve.c
new file mode 100644
index 000000000..50d2d779b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fexecve.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1994, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+/* Execute the file FD refers to, overlaying the running program image.
+ ARGV and ENVP are passed to the new program, as for `execve'. */
+int
+fexecve (fd, argv, envp)
+ int fd;
+ char *const argv[];
+ char *const envp[];
+{
+ if (fd < 0 || argv == NULL || envp == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* We use the /proc filesystem to get the information. If it is not
+ mounted we fail. */
+ char buf[sizeof "/proc/self/fd/" + sizeof (int) * 3];
+ __snprintf (buf, sizeof (buf), "/proc/self/fd/%d", fd);
+
+ /* We do not need the return value. */
+ __execve (buf, argv, envp);
+
+ int save = errno;
+
+ /* We come here only if the 'execve' call fails. Determine whether
+ /proc is mounted. If not we return ENOSYS. */
+ struct stat st;
+ if (stat ("/proc/self/fd", &st) != 0 && errno == ENOENT)
+ save = ENOSYS;
+
+ __set_errno (save);
+
+ return -1;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/fpathconf.c b/libc/sysdeps/unix/sysv/linux/fpathconf.c
new file mode 100644
index 000000000..c1cdb1b89
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fpathconf.c
@@ -0,0 +1,51 @@
+/* Get file-specific information about descriptor FD. Linux version.
+ Copyright (C) 1991,1995,1996,1998-2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "pathconf.h"
+
+static long int posix_fpathconf (int fd, int name);
+
+/* Define this first, so it can be inlined. */
+#define __fpathconf static posix_fpathconf
+#include <sysdeps/posix/fpathconf.c>
+
+
+/* Get file-specific information about descriptor FD. */
+long int
+__fpathconf (fd, name)
+ int fd;
+ int name;
+{
+ struct statfs fsbuf;
+
+ switch (name)
+ {
+ case _PC_LINK_MAX:
+ return __statfs_link_max (__fstatfs (fd, &fsbuf), &fsbuf);
+
+ case _PC_FILESIZEBITS:
+ return __statfs_filesize_max (__fstatfs (fd, &fsbuf), &fsbuf);
+
+ case _PC_2_SYMLINKS:
+ return __statfs_symlinks (__fstatfs (fd, &fsbuf), &fsbuf);
+
+ default:
+ return posix_fpathconf (fd, name);
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/fstatfs64.c b/libc/sysdeps/unix/sysv/linux/fstatfs64.c
new file mode 100644
index 000000000..48afd1f4d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fstatfs64.c
@@ -0,0 +1,72 @@
+/* Return information about the filesystem on which FD resides.
+ Copyright (C) 1996,1997,1998,1999,2000,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/statfs.h>
+#include <stddef.h>
+#include <sysdep.h>
+
+/* Defined in statfs64.c. */
+extern int __no_statfs64 attribute_hidden;
+
+/* Return information about the filesystem on which FD resides. */
+int
+__fstatfs64 (int fd, struct statfs64 *buf)
+{
+#ifdef __NR_fstatfs64
+# if __ASSUME_STATFS64 == 0
+ if (! __no_statfs64)
+# endif
+ {
+ int result = INLINE_SYSCALL (fstatfs64, 3, fd, sizeof (*buf), buf);
+
+# if __ASSUME_STATFS64 == 0
+ if (result == 0 || errno != ENOSYS)
+# endif
+ return result;
+
+# if __ASSUME_STATFS64 == 0
+ __no_statfs64 = 1;
+# endif
+ }
+#endif
+
+#if __ASSUME_STATFS64 == 0
+ struct statfs buf32;
+
+ if (__fstatfs (fd, &buf32) < 0)
+ return -1;
+
+ buf->f_type = buf32.f_type;
+ buf->f_bsize = buf32.f_bsize;
+ buf->f_blocks = buf32.f_blocks;
+ buf->f_bfree = buf32.f_bfree;
+ buf->f_bavail = buf32.f_bavail;
+ buf->f_files = buf32.f_files;
+ buf->f_ffree = buf32.f_ffree;
+ buf->f_fsid = buf32.f_fsid;
+ buf->f_namelen = buf32.f_namelen;
+ buf->f_frsize = buf32.f_frsize;
+ memcpy (buf->f_spare, buf32.f_spare, sizeof (buf32.f_spare));
+
+ return 0;
+#endif
+}
+weak_alias (__fstatfs64, fstatfs64)
diff --git a/libc/sysdeps/unix/sysv/linux/fstatvfs.c b/libc/sysdeps/unix/sysv/linux/fstatvfs.c
new file mode 100644
index 000000000..0dd56c104
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fstatvfs.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+extern void __internal_statvfs (const char *name, struct statvfs *buf,
+ struct statfs *fsbuf, struct stat64 *st);
+
+
+int
+fstatvfs (int fd, struct statvfs *buf)
+{
+ struct statfs fsbuf;
+ struct stat64 st;
+
+ /* Get as much information as possible from the system. */
+ if (__fstatfs (fd, &fsbuf) < 0)
+ return -1;
+
+ /* Convert the result. */
+ __internal_statvfs (NULL, buf, &fsbuf, fstat64 (fd, &st) == -1 ? NULL : &st);
+
+ /* We signal success if the statfs call succeeded. */
+ return 0;
+}
+libc_hidden_def (fstatvfs)
diff --git a/libc/sysdeps/unix/sysv/linux/fstatvfs64.c b/libc/sysdeps/unix/sysv/linux/fstatvfs64.c
new file mode 100644
index 000000000..24c0a8fed
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fstatvfs64.c
@@ -0,0 +1,74 @@
+/* Return information about the filesystem on which FD resides.
+ Copyright (C) 1996,1997,1998,2000,2001,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+#include <kernel-features.h>
+
+
+extern void __internal_statvfs64 (const char *name, struct statvfs64 *buf,
+ struct statfs64 *fsbuf, struct stat64 *st);
+
+
+/* Return information about the filesystem on which FD resides. */
+int
+__fstatvfs64 (int fd, struct statvfs64 *buf)
+{
+ struct statfs64 fsbuf;
+ int res = __fstatfs64 (fd, &fsbuf);
+
+#ifndef __ASSUME_STATFS64
+ if (res < 0 && errno == ENOSYS)
+ {
+ struct statvfs buf32;
+
+ res = fstatvfs (fd, &buf32);
+ if (res == 0)
+ {
+ buf->f_bsize = buf32.f_bsize;
+ buf->f_frsize = buf32.f_frsize;
+ buf->f_blocks = buf32.f_blocks;
+ buf->f_bfree = buf32.f_bfree;
+ buf->f_bavail = buf32.f_bavail;
+ buf->f_files = buf32.f_files;
+ buf->f_ffree = buf32.f_ffree;
+ buf->f_favail = buf32.f_favail;
+ buf->f_fsid = buf32.f_fsid;
+ buf->f_flag = buf32.f_flag;
+ buf->f_namemax = buf32.f_namemax;
+ memcpy (buf->__f_spare, buf32.__f_spare, sizeof (buf32.__f_spare));
+ }
+ }
+#endif
+
+ if (res == 0)
+ {
+ /* Convert the result. */
+ struct stat64 st;
+ __internal_statvfs64 (NULL, buf, &fsbuf,
+ fstat64 (fd, &st) == -1 ? NULL : &st);
+ }
+
+ return res;
+}
+weak_alias (__fstatvfs64, fstatvfs64)
diff --git a/libc/sysdeps/unix/sysv/linux/ftime.c b/libc/sysdeps/unix/sysv/linux/ftime.c
new file mode 100644
index 000000000..5a5949f60
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ftime.c
@@ -0,0 +1,3 @@
+/* Linux defines the ftime system call but doesn't actually implement
+ it. Use the BSD implementation. */
+#include <sysdeps/unix/bsd/ftime.c>
diff --git a/libc/sysdeps/unix/sysv/linux/ftruncate64.c b/libc/sysdeps/unix/sysv/linux/ftruncate64.c
new file mode 100644
index 000000000..60e7ae0ac
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ftruncate64.c
@@ -0,0 +1,77 @@
+/* Copyright (C) 1997,1998,1999,2000,2001,2003,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <endian.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_ftruncate64
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+/* The variable is shared between all wrappers around *truncate64 calls. */
+extern int __have_no_truncate64;
+#endif
+
+
+/* Truncate the file FD refers to to LENGTH bytes. */
+int
+__ftruncate64 (int fd, off64_t length)
+{
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ if (! __have_no_truncate64)
+#endif
+ {
+ unsigned int low = length & 0xffffffff;
+ unsigned int high = length >> 32;
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ int saved_errno = errno;
+#endif
+ int result = INLINE_SYSCALL (ftruncate64, 3, fd,
+ __LONG_LONG_PAIR (high, low));
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ if (result != -1 || errno != ENOSYS)
+#endif
+ return result;
+
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ __set_errno (saved_errno);
+ __have_no_truncate64 = 1;
+#endif
+ }
+
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ if ((off_t) length != length)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ return __ftruncate (fd, (off_t) length);
+#endif
+}
+weak_alias (__ftruncate64, ftruncate64)
+
+#else
+/* Use the generic implementation. */
+# include <misc/ftruncate64.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/futimes.c b/libc/sysdeps/unix/sysv/linux/futimes.c
new file mode 100644
index 000000000..b307c3ff6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/futimes.c
@@ -0,0 +1,101 @@
+/* futimes -- change access and modification times of open file. Linux version.
+ Copyright (C) 2002,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <string.h>
+#include <utime.h>
+#include <sys/time.h>
+#include <stdio-common/_itoa.h>
+#include <fcntl.h>
+
+#include <kernel-features.h>
+
+/* Change the access time of FILE to TVP[0] and
+ the modification time of FILE to TVP[1], but do not follow symlinks.
+
+ The Linux kernel has no futimes() syscall so we use the /proc
+ filesystem. */
+int
+__futimes (int fd, const struct timeval tvp[2])
+{
+ static const char selffd[] = "/proc/self/fd/";
+ char fname[sizeof (selffd) + 3 * sizeof (int)];
+ fname[sizeof (fname) - 1] = '\0';
+ char *cp = _itoa_word ((unsigned int) fd, fname + sizeof (fname) - 1, 10, 0);
+ cp = memcpy (cp - sizeof (selffd) + 1, selffd, sizeof (selffd) - 1);
+
+ int result;
+#ifdef __NR_utimes
+ result = INLINE_SYSCALL (utimes, 2, cp, tvp);
+# ifndef __ASSUME_UTIMES
+ if (result == -1 && errno == ENOSYS)
+# endif
+#endif
+ {
+ /* The utimes() syscall does not exist or is not available in the
+ used kernel. Use utime(). For this we have to convert to the
+ data format utime() expects. */
+#ifndef __ASSUME_UTIMES
+ struct utimbuf buf;
+ struct utimbuf *times;
+
+ if (tvp != NULL)
+ {
+ times = &buf;
+ buf.actime = tvp[0].tv_sec + (tvp[0].tv_usec + 500000) / 1000000;
+ buf.modtime = tvp[1].tv_sec + (tvp[1].tv_usec + 500000) / 1000000;
+ }
+ else
+ times = NULL;
+
+ result = INLINE_SYSCALL (utime, 2, cp, times);
+#endif
+ }
+
+ if (result == -1)
+ /* Check for errors that result from failing to find /proc.
+ This means we can't do futimes at all, so return ENOSYS
+ rather than some confusing error. */
+ switch (errno)
+ {
+ case EACCES:
+ if (tvp == NULL) /* Could be a path problem or a file problem. */
+ break;
+ /*FALLTHROUGH*/
+ case ELOOP:
+ case ENAMETOOLONG:
+ case ENOTDIR:
+ __set_errno (ENOSYS);
+ break;
+
+ case ENOENT:
+ /* Validate the file descriptor by letting fcntl set errno to
+ EBADF if it's bogus. Otherwise it's a /proc issue. */
+#if !defined __NR_fcntl && defined __NR_fcntl64
+# define __NR_fcntl __NR_fcntl64
+#endif
+ if (INLINE_SYSCALL (fcntl, 3, fd, F_GETFD, 0) != -1)
+ __set_errno (ENOSYS);
+ break;
+ }
+
+ return result;
+}
+weak_alias (__futimes, futimes)
diff --git a/libc/sysdeps/unix/sysv/linux/futimesat.c b/libc/sysdeps/unix/sysv/linux/futimesat.c
new file mode 100644
index 000000000..7c96b7804
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/futimesat.c
@@ -0,0 +1,134 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <utime.h>
+#include <sys/time.h>
+#include <sysdep.h>
+#include <kernel-features.h>
+
+
+/* Change the access time of FILE relative to FD to TVP[0] and
+ the modification time of FILE to TVP[1]. */
+int
+futimesat (fd, file, tvp)
+ int fd;
+ const char *file;
+ const struct timeval tvp[2];
+{
+ int result;
+
+#ifdef __NR_futimesat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ if (file == NULL)
+ return __futimes (fd, tvp);
+
+ result = INLINE_SYSCALL (futimesat, 3, fd, file, tvp);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ char *buf = NULL;
+
+ if (file == NULL)
+ {
+ static const char procfd[] = "/proc/self/fd/%d";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd);
+ file = buf;
+ }
+ else if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+# ifdef __NR_utimes
+ result = INTERNAL_SYSCALL (utimes, err, 2, file, tvp);
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return result;
+
+# ifndef __ASSUME_UTIMES
+ if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ goto fail;
+# endif
+# endif
+
+ /* The utimes() syscall does not exist or is not available in the
+ used kernel. Use utime(). For this we have to convert to the
+ data format utime() expects. */
+# ifndef __ASSUME_UTIMES
+ struct utimbuf tmp;
+ struct utimbuf *times;
+
+ if (tvp != NULL)
+ {
+ times = &tmp;
+ tmp.actime = tvp[0].tv_sec + tvp[0].tv_usec / 1000000;
+ tmp.modtime = tvp[1].tv_sec + tvp[1].tv_usec / 1000000;
+ }
+ else
+ times = NULL;
+
+ result = INTERNAL_SYSCALL (utime, err, 2, file, times);
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return result;
+
+ fail:
+# endif
+
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
+
+ return -1;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/fxstat.c b/libc/sysdeps/unix/sysv/linux/fxstat.c
new file mode 100644
index 000000000..47c98158b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fxstat.c
@@ -0,0 +1,64 @@
+/* fxstat using old-style Unix fstat system call.
+ Copyright (C) 1991,1995-1998,2000,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ho hum, if xstat == xstat64 we must get rid of the prototype or gcc
+ will complain since they don't strictly match. */
+#define __fxstat64 __fxstat64_disable
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <xstatconv.h>
+
+/* Get information about the file FD in BUF. */
+int
+__fxstat (int vers, int fd, struct stat *buf)
+{
+ if (vers == _STAT_VER_KERNEL)
+ return INLINE_SYSCALL (fstat, 2, fd, CHECK_1 ((struct kernel_stat *) buf));
+
+#ifdef STAT_IS_KERNEL_STAT
+ errno = EINVAL;
+ return -1;
+#else
+ struct kernel_stat kbuf;
+ int result;
+
+ result = INLINE_SYSCALL (fstat, 2, fd, __ptrvalue (&kbuf));
+ if (result == 0)
+ result = __xstat_conv (vers, &kbuf, buf);
+
+ return result;
+#endif
+}
+
+hidden_def (__fxstat)
+weak_alias (__fxstat, _fxstat);
+#ifdef XSTAT_IS_XSTAT64
+#undef __fxstat64
+strong_alias (__fxstat, __fxstat64);
+hidden_ver (__fxstat, __fxstat64)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/fxstat64.c b/libc/sysdeps/unix/sysv/linux/fxstat64.c
new file mode 100644
index 000000000..6bc560152
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fxstat64.c
@@ -0,0 +1,94 @@
+/* fxstat64 using old-style Unix fstat system call.
+ Copyright (C) 1997-2002, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if __ASSUME_STAT64_SYSCALL == 0
+# include <xstatconv.h>
+#endif
+
+#ifdef __NR_fstat64
+# if __ASSUME_STAT64_SYSCALL == 0
+/* The variable is shared between all wrappers around *stat64 calls. */
+extern int __have_no_stat64;
+# endif
+#endif
+
+/* Get information about the file FD in BUF. */
+
+int
+___fxstat64 (int vers, int fd, struct stat64 *buf)
+{
+ int result;
+#if __ASSUME_STAT64_SYSCALL > 0
+ result = INLINE_SYSCALL (fstat64, 2, fd, CHECK_1 (buf));
+# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+ if (__builtin_expect (!result, 1) && buf->__st_ino != (__ino_t) buf->st_ino)
+ buf->st_ino = buf->__st_ino;
+# endif
+ return result;
+#else
+ struct kernel_stat kbuf;
+# if defined __NR_fstat64
+ if (! __have_no_stat64)
+ {
+ int saved_errno = errno;
+ result = INLINE_SYSCALL (fstat64, 2, fd, CHECK_1 (buf));
+
+ if (result != -1 || errno != ENOSYS)
+ {
+# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+ if (!result && buf->__st_ino != (__ino_t)buf->st_ino)
+ buf->st_ino = buf->__st_ino;
+# endif
+ return result;
+ }
+
+ __set_errno (saved_errno);
+ __have_no_stat64 = 1;
+ }
+# endif
+ result = INLINE_SYSCALL (fstat, 2, fd, __ptrvalue (&kbuf));
+ if (result == 0)
+ result = __xstat64_conv (vers, &kbuf, buf);
+
+ return result;
+#endif
+}
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+versioned_symbol (libc, ___fxstat64, __fxstat64, GLIBC_2_2);
+strong_alias (___fxstat64, __old__fxstat64)
+compat_symbol (libc, __old__fxstat64, __fxstat64, GLIBC_2_1);
+hidden_ver (___fxstat64, __fxstat64)
+#else
+strong_alias (___fxstat64, __fxstat64)
+hidden_def (__fxstat64)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/fxstatat.c b/libc/sysdeps/unix/sysv/linux/fxstatat.c
new file mode 100644
index 000000000..c1c416abd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fxstatat.c
@@ -0,0 +1,141 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ho hum, if fxstatat == fxstatat64 we must get rid of the prototype or gcc
+ will complain since they don't strictly match. */
+#define __fxstatat64 __fxstatat64_disable
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <xstatconv.h>
+
+/* Get information about the file NAME in BUF. */
+int
+__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
+{
+ int result;
+ INTERNAL_SYSCALL_DECL (err);
+#ifdef STAT_IS_KERNEL_STAT
+# define kst (*st)
+#else
+ struct kernel_stat kst;
+#endif
+
+#ifdef __NR_newfstatat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INTERNAL_SYSCALL (newfstatat, err, 4, fd, file, &kst, flag);
+# ifndef __ASSUME_ATFCTS
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
+ && INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ {
+#ifdef STAT_IS_KERNEL_STAT
+ return 0;
+#else
+ return __xstat_conv (vers, &kst, st);
+#endif
+ }
+ else
+ {
+ __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
+ return -1;
+ }
+ }
+#endif
+
+ if (flag & ~AT_SYMLINK_NOFOLLOW)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ if (vers == _STAT_VER_KERNEL)
+ {
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
+ CHECK_1 ((struct kernel_stat *) st));
+ else
+ result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
+ CHECK_1 ((struct kernel_stat *) st));
+
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return result;
+ }
+#ifdef STAT_IS_KERNEL_STAT
+ else
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+#else
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
+ __ptrvalue (&kst));
+ else
+ result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
+ __ptrvalue (&kst));
+
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return __xstat_conv (vers, &kst, st);
+#endif
+
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
+
+ return -1;
+}
+libc_hidden_def (__fxstatat)
+#ifdef XSTAT_IS_XSTAT64
+# undef __fxstatat64
+strong_alias (__fxstatat, __fxstatat64);
+libc_hidden_def (__fxstatat64)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/fxstatat64.c b/libc/sysdeps/unix/sysv/linux/fxstatat64.c
new file mode 100644
index 000000000..cb932b8e5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/fxstatat64.c
@@ -0,0 +1,167 @@
+/* Copyright (C) 2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if __ASSUME_STAT64_SYSCALL == 0
+# include <xstatconv.h>
+#endif
+
+#ifdef __NR_stat64
+# if __ASSUME_STAT64_SYSCALL == 0
+/* The variable is shared between all wrappers around *stat64 calls.
+ This is the definition. */
+extern int __have_no_stat64;
+# endif
+#endif
+
+/* Get information about the file NAME in BUF. */
+
+int
+__fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
+{
+ if (__builtin_expect (vers != _STAT_VER_LINUX, 0))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ int result;
+ INTERNAL_SYSCALL_DECL (err);
+
+#ifdef __NR_fstatat64
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, st, flag);
+# ifndef __ASSUME_ATFCTS
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
+ && INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return 0;
+ else
+ {
+ __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
+ return -1;
+ }
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ if (flag & ~AT_SYMLINK_NOFOLLOW)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+# if __ASSUME_STAT64_SYSCALL > 0
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
+ CHECK_1 (st));
+ else
+ result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
+ CHECK_1 (st));
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ {
+# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+ if (st->__st_ino != (__ino_t) st->st_ino)
+ st->st_ino = st->__st_ino;
+# endif
+ return result;
+ }
+# else
+ struct kernel_stat kst;
+# ifdef __NR_stat64
+ if (! __have_no_stat64)
+ {
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
+ CHECK_1 (st));
+ else
+ result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
+ CHECK_1 (st));
+
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ {
+# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+ if (st->__st_ino != (__ino_t) st->st_ino)
+ st->st_ino = st->__st_ino;
+# endif
+ return result;
+ }
+ if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ goto fail;
+
+ __have_no_stat64 = 1;
+ }
+# endif
+
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
+ __ptrvalue (&kst));
+ else
+ result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
+ __ptrvalue (&kst));
+
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return __xstat64_conv (vers, &kst, st);
+
+ fail:
+# endif
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
+
+ return -1;
+#endif
+}
+libc_hidden_def (__fxstatat64)
diff --git a/libc/sysdeps/unix/sysv/linux/gai_sigqueue.c b/libc/sysdeps/unix/sysv/linux/gai_sigqueue.c
new file mode 100644
index 000000000..0c6654a38
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/gai_sigqueue.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <netdb.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include "gai_misc.h"
+
+#ifdef __NR_rt_sigqueueinfo
+
+/* Return any pending signal or wait for one for the given time. */
+int
+__gai_sigqueue (sig, val, caller_pid)
+ int sig;
+ const union sigval val;
+ pid_t caller_pid;
+{
+ siginfo_t info;
+
+ /* First, clear the siginfo_t structure, so that we don't pass our
+ stack content to other tasks. */
+ memset (&info, 0, sizeof (siginfo_t));
+ /* We must pass the information about the data in a siginfo_t value. */
+ info.si_signo = sig;
+ info.si_code = SI_ASYNCNL;
+ info.si_pid = caller_pid;
+ info.si_uid = __getuid ();
+ info.si_value = val;
+
+ return INLINE_SYSCALL (rt_sigqueueinfo, 3, info.si_pid,
+ sig, __ptrvalue (&info));
+}
+#else
+# include <resolv/gai_sigqueue.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/getclktck.c b/libc/sysdeps/unix/sysv/linux/getclktck.c
new file mode 100644
index 000000000..f9fece32f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getclktck.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <time.h>
+
+#include <ldsodefs.h>
+
+#ifndef SYSTEM_CLK_TCK
+# define SYSTEM_CLK_TCK 100
+#endif
+
+/* Return frequency of times(). */
+int
+__getclktck ()
+{
+ return GLRO(dl_clktck) ?: SYSTEM_CLK_TCK;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/getcwd.c b/libc/sysdeps/unix/sysv/linux/getcwd.c
new file mode 100644
index 000000000..911d85f43
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getcwd.c
@@ -0,0 +1,222 @@
+/* Determine current working directory. Linux version.
+ Copyright (C) 1997,1998,1999,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+
+/* If we compile the file for use in ld.so we don't need the feature
+ that getcwd() allocates the buffers itself. */
+#ifdef IS_IN_rtld
+# define NO_ALLOCATION 1
+#endif
+
+
+#if __ASSUME_GETCWD_SYSCALL > 0
+/* Kernel 2.1.92 introduced a third way to get the current working
+ directory: a syscall. We've got to be careful that even when
+ compiling under 2.1.92+ the libc still runs under older kernels. */
+# define no_syscall_getcwd 0
+# define have_new_dcache 1
+/* This is a trick since we don't define generic_getcwd. */
+# define generic_getcwd getcwd
+#else
+/* The "proc" filesystem provides an easy method to retrieve the value.
+ For each process, the corresponding directory contains a symbolic link
+ named `cwd'. Reading the content of this link immediate gives us the
+ information. But we have to take care for systems which do not have
+ the proc filesystem mounted. Use the POSIX implementation in this case. */
+static char *generic_getcwd (char *buf, size_t size) internal_function;
+
+# if __NR_getcwd
+/* Kernel 2.1.92 introduced a third way to get the current working
+ directory: a syscall. We've got to be careful that even when
+ compiling under 2.1.92+ the libc still runs under older kernels. */
+static int no_syscall_getcwd;
+static int have_new_dcache;
+# else
+# define no_syscall_getcwd 1
+static int have_new_dcache = 1;
+# endif
+#endif
+
+char *
+__getcwd (char *buf, size_t size)
+{
+ char *path;
+ int n;
+ char *result;
+
+ if (no_syscall_getcwd && !have_new_dcache)
+ return generic_getcwd (buf, size);
+
+#ifndef NO_ALLOCATION
+ size_t alloc_size = size;
+ if (size == 0)
+ {
+ if (buf != NULL)
+ {
+ __set_errno (EINVAL);
+ return NULL;
+ }
+
+ alloc_size = MAX (PATH_MAX, __getpagesize ());
+ }
+
+ if (buf == NULL)
+ {
+ path = malloc (alloc_size);
+ if (path == NULL)
+ return NULL;
+ }
+ else
+#else
+# define alloc_size size
+#endif
+ path = buf;
+
+#if defined __NR_getcwd || __LINUX_GETCWD_SYSCALL > 0
+ if (!no_syscall_getcwd)
+ {
+ int retval;
+
+ retval = INLINE_SYSCALL (getcwd, 2, CHECK_STRING (path), alloc_size);
+ if (retval >= 0)
+ {
+# ifndef NO_ALLOCATION
+ if (buf == NULL && size == 0)
+ /* Ensure that the buffer is only as large as necessary. */
+ buf = realloc (path, (size_t) retval);
+
+ if (buf == NULL)
+ /* Either buf was NULL all along, or `realloc' failed but
+ we still have the original string. */
+ buf = path;
+# endif
+
+ return buf;
+ }
+
+# if __ASSUME_GETCWD_SYSCALL
+ /* It should never happen that the `getcwd' syscall failed because
+ the buffer is too small if we allocated the buffer ourselves
+ large enough. */
+ assert (errno != ERANGE || buf != NULL || size != 0);
+
+# ifndef NO_ALLOCATION
+ if (buf == NULL)
+ free (path);
+# endif
+
+ return NULL;
+# else
+ if (errno == ENOSYS)
+ {
+ no_syscall_getcwd = 1;
+ have_new_dcache = 1; /* Now we will try the /proc method. */
+ }
+ else if (errno != ERANGE || buf != NULL)
+ {
+# ifndef NO_ALLOCATION
+ if (buf == NULL)
+ free (path);
+# endif
+ return NULL;
+ }
+# endif
+ }
+#endif
+
+ n = __readlink ("/proc/self/cwd", path, alloc_size - 1);
+ if (n != -1)
+ {
+ if (path[0] == '/')
+ {
+ if ((size_t) n >= alloc_size - 1)
+ {
+#ifndef NO_ALLOCATION
+ if (buf == NULL)
+ free (path);
+#endif
+ return NULL;
+ }
+
+ path[n] = '\0';
+#ifndef NO_ALLOCATION
+ if (buf == NULL && size == 0)
+ /* Ensure that the buffer is only as large as necessary. */
+ buf = realloc (path, (size_t) n + 1);
+ if (buf == NULL)
+ /* Either buf was NULL all along, or `realloc' failed but
+ we still have the original string. */
+ buf = path;
+#endif
+
+ return buf;
+ }
+#ifndef have_new_dcache
+ else
+ have_new_dcache = 0;
+#endif
+ }
+
+#if __ASSUME_GETCWD_SYSCALL == 0
+ /* Set to have_new_dcache only if error indicates that proc doesn't
+ exist. */
+ if (errno != EACCES && errno != ENAMETOOLONG)
+ have_new_dcache = 0;
+#endif
+
+#ifndef NO_ALLOCATION
+ /* Don't put restrictions on the length of the path unless the user does. */
+ if (size == 0)
+ {
+ free (path);
+ path = NULL;
+ }
+#endif
+
+ result = generic_getcwd (path, size);
+
+#ifndef NO_ALLOCATION
+ if (result == NULL && buf == NULL && size != 0)
+ free (path);
+#endif
+
+ return result;
+}
+weak_alias (__getcwd, getcwd)
+
+#if __ASSUME_GETCWD_SYSCALL == 0
+/* Get the code for the generic version. */
+# define GETCWD_RETURN_TYPE static char * internal_function
+# define __getcwd generic_getcwd
+# include <sysdeps/posix/getcwd.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/getdents.c b/libc/sysdeps/unix/sysv/linux/getdents.c
new file mode 100644
index 000000000..836cbf392
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getdents.c
@@ -0,0 +1,299 @@
+/* Copyright (C) 1993, 1995-2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <alloca.h>
+#include <assert.h>
+#include <errno.h>
+#include <dirent.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <linux/posix_types.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_getdents64
+# ifndef __ASSUME_GETDENTS64_SYSCALL
+# ifndef __GETDENTS
+/* The variable is shared between all *getdents* calls. */
+int __have_no_getdents64 attribute_hidden;
+# else
+extern int __have_no_getdents64 attribute_hidden;
+# endif
+# define have_no_getdents64_defined 1
+# endif
+#endif
+#ifndef have_no_getdents64_defined
+# define __have_no_getdents64 0
+#endif
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+/* For Linux we need a special version of this file since the
+ definition of `struct dirent' is not the same for the kernel and
+ the libc. There is one additional field which might be introduced
+ in the kernel structure in the future.
+
+ Here is the kernel definition of `struct dirent' as of 2.1.20: */
+
+struct kernel_dirent
+ {
+ long int d_ino;
+ __kernel_off_t d_off;
+ unsigned short int d_reclen;
+ char d_name[256];
+ };
+
+struct kernel_dirent64
+ {
+ uint64_t d_ino;
+ int64_t d_off;
+ unsigned short int d_reclen;
+ unsigned char d_type;
+ char d_name[256];
+ };
+
+#ifndef __GETDENTS
+# define __GETDENTS __getdents
+#endif
+#ifndef DIRENT_TYPE
+# define DIRENT_TYPE struct dirent
+#endif
+#ifndef DIRENT_SET_DP_INO
+# define DIRENT_SET_DP_INO(dp, value) (dp)->d_ino = (value)
+#endif
+
+/* The problem here is that we cannot simply read the next NBYTES
+ bytes. We need to take the additional field into account. We use
+ some heuristic. Assuming the directory contains names with 14
+ characters on average we can compute an estimated number of entries
+ which fit in the buffer. Taking this number allows us to specify a
+ reasonable number of bytes to read. If we should be wrong, we can
+ reset the file descriptor. In practice the kernel is limiting the
+ amount of data returned much more then the reduced buffer size. */
+ssize_t
+internal_function
+__GETDENTS (int fd, char *buf, size_t nbytes)
+{
+ ssize_t retval;
+
+#ifdef __ASSUME_GETDENTS32_D_TYPE
+ if (sizeof (DIRENT_TYPE) == sizeof (struct dirent))
+ {
+ retval = INLINE_SYSCALL (getdents, 3, fd, CHECK_N(buf, nbytes), nbytes);
+
+ /* The kernel added the d_type value after the name. Change
+ this now. */
+ if (retval != -1)
+ {
+ union
+ {
+ struct kernel_dirent k;
+ struct dirent u;
+ } *kbuf = (void *) buf;
+
+ while ((char *) kbuf < buf + retval)
+ {
+ char d_type = *((char *) kbuf + kbuf->k.d_reclen - 1);
+ memmove (kbuf->u.d_name, kbuf->k.d_name,
+ strlen (kbuf->k.d_name) + 1);
+ kbuf->u.d_type = d_type;
+
+ kbuf = (void *) ((char *) kbuf + kbuf->k.d_reclen);
+ }
+ }
+
+ return retval;
+ }
+#endif
+
+ off64_t last_offset = -1;
+
+#ifdef __NR_getdents64
+ if (!__have_no_getdents64)
+ {
+# ifndef __ASSUME_GETDENTS64_SYSCALL
+ int saved_errno = errno;
+# endif
+ union
+ {
+ struct kernel_dirent64 k;
+ DIRENT_TYPE u;
+ char b[1];
+ } *kbuf = (void *) buf, *outp, *inp;
+ size_t kbytes = nbytes;
+ if (offsetof (DIRENT_TYPE, d_name)
+ < offsetof (struct kernel_dirent64, d_name)
+ && nbytes <= sizeof (DIRENT_TYPE))
+ {
+ kbytes = nbytes + offsetof (struct kernel_dirent64, d_name)
+ - offsetof (DIRENT_TYPE, d_name);
+ kbuf = __alloca(kbytes);
+ }
+ retval = INLINE_SYSCALL (getdents64, 3, fd, CHECK_N(kbuf, kbytes),
+ kbytes);
+# ifndef __ASSUME_GETDENTS64_SYSCALL
+ if (retval != -1 || (errno != EINVAL && errno != ENOSYS))
+# endif
+ {
+ const size_t size_diff = (offsetof (struct kernel_dirent64, d_name)
+ - offsetof (DIRENT_TYPE, d_name));
+
+ /* Return the error if encountered. */
+ if (retval == -1)
+ return -1;
+
+ /* If the structure returned by the kernel is identical to what we
+ need, don't do any conversions. */
+ if (offsetof (DIRENT_TYPE, d_name)
+ == offsetof (struct kernel_dirent64, d_name)
+ && sizeof (outp->u.d_ino) == sizeof (inp->k.d_ino)
+ && sizeof (outp->u.d_off) == sizeof (inp->k.d_off))
+ return retval;
+
+ /* These two pointers might alias the same memory buffer.
+ Standard C requires that we always use the same type for them,
+ so we must use the union type. */
+ inp = kbuf;
+ outp = (void *) buf;
+
+ while (&inp->b < &kbuf->b + retval)
+ {
+ const size_t alignment = __alignof__ (DIRENT_TYPE);
+ /* Since inp->k.d_reclen is already aligned for the kernel
+ structure this may compute a value that is bigger
+ than necessary. */
+ size_t old_reclen = inp->k.d_reclen;
+ size_t new_reclen = ((old_reclen - size_diff + alignment - 1)
+ & ~(alignment - 1));
+
+ /* Copy the data out of the old structure into temporary space.
+ Then copy the name, which may overlap if BUF == KBUF. */
+ const uint64_t d_ino = inp->k.d_ino;
+ const int64_t d_off = inp->k.d_off;
+ const uint8_t d_type = inp->k.d_type;
+
+ memmove (outp->u.d_name, inp->k.d_name,
+ old_reclen - offsetof (struct kernel_dirent64, d_name));
+
+ /* Now we have copied the data from INP and access only OUTP. */
+
+ DIRENT_SET_DP_INO (&outp->u, d_ino);
+ outp->u.d_off = d_off;
+ if ((sizeof (outp->u.d_ino) != sizeof (inp->k.d_ino)
+ && outp->u.d_ino != d_ino)
+ || (sizeof (outp->u.d_off) != sizeof (inp->k.d_off)
+ && outp->u.d_off != d_off))
+ {
+ /* Overflow. If there was at least one entry
+ before this one, return them without error,
+ otherwise signal overflow. */
+ if (last_offset != -1)
+ {
+ __lseek64 (fd, last_offset, SEEK_SET);
+ return outp->b - buf;
+ }
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+
+ last_offset = d_off;
+ outp->u.d_reclen = new_reclen;
+ outp->u.d_type = d_type;
+
+ inp = (void *) inp + old_reclen;
+ outp = (void *) outp + new_reclen;
+ }
+
+ return outp->b - buf;
+ }
+
+# ifndef __ASSUME_GETDENTS64_SYSCALL
+ __set_errno (saved_errno);
+ __have_no_getdents64 = 1;
+# endif
+ }
+#endif
+ {
+ size_t red_nbytes;
+ struct kernel_dirent *skdp, *kdp;
+ const size_t size_diff = (offsetof (DIRENT_TYPE, d_name)
+ - offsetof (struct kernel_dirent, d_name));
+
+ red_nbytes = MIN (nbytes
+ - ((nbytes / (offsetof (DIRENT_TYPE, d_name) + 14))
+ * size_diff),
+ nbytes - size_diff);
+
+ skdp = kdp = __alloca (red_nbytes);
+
+ retval = INLINE_SYSCALL (getdents, 3, fd,
+ CHECK_N ((char *) kdp, red_nbytes), red_nbytes);
+
+ if (retval == -1)
+ return -1;
+
+ DIRENT_TYPE *dp = (DIRENT_TYPE *) buf;
+ while ((char *) kdp < (char *) skdp + retval)
+ {
+ const size_t alignment = __alignof__ (DIRENT_TYPE);
+ /* Since kdp->d_reclen is already aligned for the kernel structure
+ this may compute a value that is bigger than necessary. */
+ size_t new_reclen = ((kdp->d_reclen + size_diff + alignment - 1)
+ & ~(alignment - 1));
+ if ((char *) dp + new_reclen > buf + nbytes)
+ {
+ /* Our heuristic failed. We read too many entries. Reset
+ the stream. */
+ assert (last_offset != -1);
+ __lseek64 (fd, last_offset, SEEK_SET);
+
+ if ((char *) dp == buf)
+ {
+ /* The buffer the user passed in is too small to hold even
+ one entry. */
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ break;
+ }
+
+ last_offset = kdp->d_off;
+ DIRENT_SET_DP_INO(dp, kdp->d_ino);
+ dp->d_off = kdp->d_off;
+ dp->d_reclen = new_reclen;
+ dp->d_type = DT_UNKNOWN;
+ memcpy (dp->d_name, kdp->d_name,
+ kdp->d_reclen - offsetof (struct kernel_dirent, d_name));
+
+ dp = (DIRENT_TYPE *) ((char *) dp + new_reclen);
+ kdp = (struct kernel_dirent *) (((char *) kdp) + kdp->d_reclen);
+ }
+
+ return (char *) dp - buf;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/getdents64.c b/libc/sysdeps/unix/sysv/linux/getdents64.c
new file mode 100644
index 000000000..805917e27
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getdents64.c
@@ -0,0 +1,3 @@
+#define __GETDENTS __getdents64
+#define DIRENT_TYPE struct dirent64
+#include <sysdeps/unix/sysv/linux/getdents.c>
diff --git a/libc/sysdeps/unix/sysv/linux/getdirentries.c b/libc/sysdeps/unix/sysv/linux/getdirentries.c
new file mode 100644
index 000000000..73dabdb19
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getdirentries.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dirent.h>
+#include <unistd.h>
+
+#ifndef GETDIRENTRIES
+# define GETDIRENTRIES getdirentries
+# define __GETDENTS __getdents
+#else
+# define off_t off64_t
+# define __lseek __lseek64
+#endif
+
+ssize_t
+GETDIRENTRIES (int fd, char *buf, size_t nbytes, off_t *basep)
+{
+ off_t base = __lseek (fd, (off_t) 0, SEEK_CUR);
+ ssize_t result;
+
+ result = __GETDENTS (fd, buf, nbytes);
+
+ if (result != -1)
+ *basep = base;
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/getdirentries64.c b/libc/sysdeps/unix/sysv/linux/getdirentries64.c
new file mode 100644
index 000000000..e486a36a1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getdirentries64.c
@@ -0,0 +1,3 @@
+#define GETDIRENTRIES getdirentries64
+#define __GETDENTS __getdents64
+#include "getdirentries.c"
diff --git a/libc/sysdeps/unix/sysv/linux/getdtsz.c b/libc/sysdeps/unix/sysv/linux/getdtsz.c
new file mode 100644
index 000000000..1dcfa6dde
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getdtsz.c
@@ -0,0 +1,22 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This comes from the Linux kernel header. */
+#define OPEN_MAX 256
+
+#include <sysdeps/posix/getdtsz.c>
diff --git a/libc/sysdeps/unix/sysv/linux/gethostid.c b/libc/sysdeps/unix/sysv/linux/gethostid.c
new file mode 100644
index 000000000..de98fb3d7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/gethostid.c
@@ -0,0 +1,121 @@
+/* Copyright (C) 1995,1996,1998-2001,2003,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <alloca.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <not-cancel.h>
+
+#define HOSTIDFILE "/etc/hostid"
+
+#ifdef SET_PROCEDURE
+int
+sethostid (id)
+ long int id;
+{
+ int fd;
+ ssize_t written;
+ int32_t id32 = id;
+
+ /* Test for appropriate rights to set host ID. */
+ if (__libc_enable_secure)
+ {
+ __set_errno (EPERM);
+ return -1;
+ }
+
+ /* Make sure the ID is not too large. Needed for bi-arch support. */
+ if (id32 != id)
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+
+ /* Open file for writing. Everybody is allowed to read this file. */
+ fd = open_not_cancel (HOSTIDFILE, O_CREAT|O_WRONLY|O_TRUNC, 0644);
+ if (fd < 0)
+ return -1;
+
+ written = write_not_cancel (fd, &id32, sizeof (id32));
+
+ close_not_cancel_no_status (fd);
+
+ return written != sizeof (id32) ? -1 : 0;
+}
+
+#else
+# include <string.h>
+# include <sys/param.h>
+# include <resolv/netdb.h>
+# include <netinet/in.h>
+
+long int
+gethostid ()
+{
+ char hostname[MAXHOSTNAMELEN + 1];
+ size_t buflen;
+ char *buffer;
+ struct hostent hostbuf, *hp;
+ int32_t id;
+ struct in_addr in;
+ int herr;
+ int fd;
+
+ /* First try to get the ID from a former invocation of sethostid. */
+ fd = open_not_cancel (HOSTIDFILE, O_RDONLY|O_LARGEFILE, 0);
+ if (fd >= 0)
+ {
+ ssize_t n = read_not_cancel (fd, &id, sizeof (id));
+
+ close_not_cancel_no_status (fd);
+
+ if (n == sizeof (id))
+ return id;
+ }
+
+ /* Getting from the file was not successful. An intelligent guess for
+ a unique number of a host is its IP address. Return this. */
+ if (__gethostname (hostname, MAXHOSTNAMELEN) < 0 || hostname[0] == '\0')
+ /* This also fails. Return and arbitrary value. */
+ return 0;
+
+ buflen = 1024;
+ buffer = __alloca (buflen);
+
+ /* To get the IP address we need to know the host name. */
+ while (__gethostbyname_r (hostname, &hostbuf, buffer, buflen, &hp, &herr)
+ != 0
+ || hp == NULL)
+ if (herr != NETDB_INTERNAL || errno != ERANGE)
+ return 0;
+ else
+ /* Enlarge buffer. */
+ buffer = extend_alloca (buffer, buflen, 2 * buflen);
+
+ in.s_addr = 0;
+ memcpy (&in, hp->h_addr,
+ (int) sizeof (in) < hp->h_length ? (int) sizeof (in) : hp->h_length);
+
+ /* For the return value to be not exactly the IP address we do some
+ bit fiddling. */
+ return (int32_t) (in.s_addr << 16 | in.s_addr >> 16);
+}
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/getipv4sourcefilter.c b/libc/sysdeps/unix/sysv/linux/getipv4sourcefilter.c
new file mode 100644
index 000000000..1a4e16cdb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getipv4sourcefilter.c
@@ -0,0 +1,73 @@
+/* Get IPv4 source filter. Linux version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <alloca.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+
+int
+getipv4sourcefilter (int s, struct in_addr interface, struct in_addr group,
+ uint32_t *fmode, uint32_t *numsrc, struct in_addr *slist)
+{
+ /* We have to create an struct ip_msfilter object which we can pass
+ to the kernel. */
+ socklen_t needed = IP_MSFILTER_SIZE (*numsrc);
+ int use_alloca = __libc_use_alloca (needed);
+
+ struct ip_msfilter *imsf;
+ if (use_alloca)
+ imsf = (struct ip_msfilter *) alloca (needed);
+ else
+ {
+ imsf = (struct ip_msfilter *) malloc (needed);
+ if (imsf == NULL)
+ return -1;
+ }
+
+ imsf->imsf_multiaddr = group;
+ imsf->imsf_interface = interface;
+ imsf->imsf_numsrc = *numsrc;
+
+ int result = __getsockopt (s, SOL_IP, IP_MSFILTER, imsf, &needed);
+
+ /* If successful, copy the results to the places the caller wants
+ them in. */
+ if (result == 0)
+ {
+ *fmode = imsf->imsf_fmode;
+ memcpy (slist, imsf->imsf_slist,
+ MIN (*numsrc, imsf->imsf_numsrc) * sizeof (struct in_addr));
+ *numsrc = imsf->imsf_numsrc;
+ }
+
+ if (! use_alloca)
+ {
+ int save_errno = errno;
+ free (imsf);
+ __set_errno (save_errno);
+ }
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/getloadavg.c b/libc/sysdeps/unix/sysv/linux/getloadavg.c
new file mode 100644
index 000000000..81a1c0dd5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getloadavg.c
@@ -0,0 +1,69 @@
+/* Get system load averages. Linux (/proc/loadavg) version.
+ Copyright (C) 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <not-cancel.h>
+
+/* Put the 1 minute, 5 minute and 15 minute load averages
+ into the first NELEM elements of LOADAVG.
+ Return the number written (never more than 3, but may be less than NELEM),
+ or -1 if an error occurred. */
+
+int
+getloadavg (double loadavg[], int nelem)
+{
+ int fd;
+
+ fd = open_not_cancel_2 ("/proc/loadavg", O_RDONLY);
+ if (fd < 0)
+ return -1;
+ else
+ {
+ char buf[65], *p;
+ ssize_t nread;
+ int i;
+
+ nread = read_not_cancel (fd, buf, sizeof buf - 1);
+ close_not_cancel_no_status (fd);
+ if (nread <= 0)
+ return -1;
+ buf[nread - 1] = '\0';
+
+ if (nelem > 3)
+ nelem = 3;
+ p = buf;
+ for (i = 0; i < nelem; ++i)
+ {
+ char *endp;
+ loadavg[i] = __strtod_l (p, &endp, _nl_C_locobj_ptr);
+ if (endp == p)
+ /* This should not happen. The format of /proc/loadavg
+ must have changed. Don't return with what we have,
+ signal an error. */
+ return -1;
+ p = endp;
+ }
+
+ return i;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/getpagesize.c b/libc/sysdeps/unix/sysv/linux/getpagesize.c
new file mode 100644
index 000000000..6d03b3bbf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getpagesize.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1991,1992,1995-1997,2000,2002,2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <sys/param.h>
+
+#include <ldsodefs.h>
+
+/* Return the system page size. */
+int
+__getpagesize ()
+{
+ if (GLRO(dl_pagesize) != 0)
+ return GLRO(dl_pagesize);
+
+#ifdef EXEC_PAGESIZE
+ return EXEC_PAGESIZE;
+#else /* No EXEC_PAGESIZE. */
+#ifdef NBPG
+#ifndef CLSIZE
+#define CLSIZE 1
+#endif /* No CLSIZE. */
+ return NBPG * CLSIZE;
+#else /* No NBPG. */
+ return NBPC;
+#endif /* NBPG. */
+#endif /* EXEC_PAGESIZE. */
+}
+libc_hidden_def (__getpagesize)
+weak_alias (__getpagesize, getpagesize)
diff --git a/libc/sysdeps/unix/sysv/linux/getpeername.S b/libc/sysdeps/unix/sysv/linux/getpeername.S
new file mode 100644
index 000000000..a6d8e86d4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getpeername.S
@@ -0,0 +1,3 @@
+#define socket getpeername
+#define NARGS 3
+#include <socket.S>
diff --git a/libc/sysdeps/unix/sysv/linux/getpriority.c b/libc/sysdeps/unix/sysv/linux/getpriority.c
new file mode 100644
index 000000000..23da8495f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getpriority.c
@@ -0,0 +1,45 @@
+/* getpriority for Linux.
+ Copyright (C) 1996,98,2000,02,03 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/resource.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* The return value of getpriority syscall is biased by this value
+ to avoid returning negative values. */
+#define PZERO 20
+
+/* Return the highest priority of any process specified by WHICH and WHO
+ (see above); if WHO is zero, the current process, process group, or user
+ (as specified by WHO) is used. A lower priority number means higher
+ priority. Priorities range from PRIO_MIN to PRIO_MAX. */
+
+int
+getpriority (enum __priority_which which, id_t who)
+{
+ int res;
+
+ res = INLINE_SYSCALL (getpriority, 2, (int) which, who);
+ if (res >= 0)
+ res = PZERO - res;
+ return res;
+}
+libc_hidden_def (getpriority)
diff --git a/libc/sysdeps/unix/sysv/linux/getpt.c b/libc/sysdeps/unix/sysv/linux/getpt.c
new file mode 100644
index 000000000..bb1ea4764
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getpt.c
@@ -0,0 +1,100 @@
+/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <paths.h>
+#include <sys/statfs.h>
+
+#include "linux_fsinfo.h"
+
+/* Path to the master pseudo terminal cloning device. */
+#define _PATH_DEVPTMX _PATH_DEV "ptmx"
+/* Directory containing the UNIX98 pseudo terminals. */
+#define _PATH_DEVPTS _PATH_DEV "pts"
+
+/* Prototype for function that opens BSD-style master pseudo-terminals. */
+int __bsd_getpt (void);
+
+/* Open a master pseudo terminal and return its file descriptor. */
+int
+__posix_openpt (oflag)
+ int oflag;
+{
+ static int have_no_dev_ptmx;
+ int fd;
+
+ if (!have_no_dev_ptmx)
+ {
+ fd = __open (_PATH_DEVPTMX, oflag);
+ if (fd != -1)
+ {
+ struct statfs fsbuf;
+ static int devpts_mounted;
+
+ /* Check that the /dev/pts filesystem is mounted
+ or if /dev is a devfs filesystem (this implies /dev/pts). */
+ if (devpts_mounted
+ || (__statfs (_PATH_DEVPTS, &fsbuf) == 0
+ && fsbuf.f_type == DEVPTS_SUPER_MAGIC)
+ || (__statfs (_PATH_DEV, &fsbuf) == 0
+ && fsbuf.f_type == DEVFS_SUPER_MAGIC))
+ {
+ /* Everything is ok. */
+ devpts_mounted = 1;
+ return fd;
+ }
+
+ /* If /dev/pts is not mounted then the UNIX98 pseudo terminals
+ are not usable. */
+ __close (fd);
+ have_no_dev_ptmx = 1;
+ }
+ else
+ {
+ if (errno == ENOENT || errno == ENODEV)
+ have_no_dev_ptmx = 1;
+ else
+ return -1;
+ }
+ }
+
+ return -1;
+}
+weak_alias (__posix_openpt, posix_openpt)
+
+
+int
+__getpt (void)
+{
+ int fd = __posix_openpt (O_RDWR);
+ if (fd == -1)
+ fd = __bsd_getpt ();
+ return fd;
+}
+
+
+#define PTYNAME1 "pqrstuvwxyzabcde";
+#define PTYNAME2 "0123456789abcdef";
+
+#define __getpt __bsd_getpt
+#define HAVE_POSIX_OPENPT
+#include <sysdeps/unix/bsd/getpt.c>
diff --git a/libc/sysdeps/unix/sysv/linux/getsockname.S b/libc/sysdeps/unix/sysv/linux/getsockname.S
new file mode 100644
index 000000000..9ea371ff6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getsockname.S
@@ -0,0 +1,5 @@
+#define socket getsockname
+#define NARGS 3
+#define NO_WEAK_ALIAS 1
+#include <socket.S>
+weak_alias (getsockname, __getsockname)
diff --git a/libc/sysdeps/unix/sysv/linux/getsockopt.S b/libc/sysdeps/unix/sysv/linux/getsockopt.S
new file mode 100644
index 000000000..6f982082a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getsockopt.S
@@ -0,0 +1,3 @@
+#define socket getsockopt
+#define NARGS 5
+#include <socket.S>
diff --git a/libc/sysdeps/unix/sysv/linux/getsourcefilter.c b/libc/sysdeps/unix/sysv/linux/getsourcefilter.c
new file mode 100644
index 000000000..a6f89a3cc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getsourcefilter.c
@@ -0,0 +1,146 @@
+/* Get source filter. Linux version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <alloca.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netatalk/at.h>
+#include <netax25/ax25.h>
+#include <netinet/in.h>
+#include <netipx/ipx.h>
+#include <netpacket/packet.h>
+#include <netrose/rose.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+
+static const struct
+{
+ int sol;
+ int af;
+ socklen_t size;
+} sol_map[] =
+ {
+ /* Sort the array according to importance of the protocols. Add
+ more protocols when they become available. */
+ { SOL_IP, AF_INET, sizeof (struct sockaddr_in) },
+ { SOL_IPV6, AF_INET6, sizeof (struct sockaddr_in6) },
+ { SOL_AX25, AF_AX25, sizeof (struct sockaddr_ax25) },
+ { SOL_IPX, AF_IPX, sizeof (struct sockaddr_ipx) },
+ { SOL_ATALK, AF_APPLETALK, sizeof (struct sockaddr_at) },
+ { SOL_ROSE, AF_ROSE, sizeof (struct sockaddr_rose) },
+ { SOL_PACKET, AF_PACKET, sizeof (struct sockaddr_ll) }
+ };
+#define NSOL_MAP (sizeof (sol_map) / sizeof (sol_map[0]))
+
+
+/* Try to determine the socket level value. Ideally both side and
+ family are set. But sometimes only the size is correct and the
+ family value might be bogus. Loop over the array entries and look
+ for a perfect match or the first match based on size. */
+int
+__get_sol (int af, socklen_t len)
+{
+ int first_size_sol = -1;
+
+ for (size_t cnt = 0; cnt < NSOL_MAP; ++cnt)
+ {
+ /* Just a test so that we make sure the special value used to
+ signal the "we have so far no socket level value" is OK. */
+ assert (sol_map[cnt].sol != -1);
+
+ if (len == sol_map[cnt].size)
+ {
+ /* The size matches, which is a requirement. If the family
+ matches, too, we have a winner. Otherwise we remember the
+ socket level value for this protocol if it is the first
+ match. */
+ if (af == sol_map[cnt].af)
+ /* Bingo! */
+ return sol_map[cnt].sol;
+
+ if (first_size_sol == -1)
+ first_size_sol = sol_map[cnt].sol;
+ }
+ }
+
+ return first_size_sol;
+}
+
+
+int
+getsourcefilter (int s, uint32_t interface, const struct sockaddr *group,
+ socklen_t grouplen, uint32_t *fmode, uint32_t *numsrc,
+ struct sockaddr_storage *slist)
+{
+ /* We have to create an struct ip_msfilter object which we can pass
+ to the kernel. */
+ socklen_t needed = GROUP_FILTER_SIZE (*numsrc);
+ int use_alloca = __libc_use_alloca (needed);
+
+ struct group_filter *gf;
+ if (use_alloca)
+ gf = (struct group_filter *) alloca (needed);
+ else
+ {
+ gf = (struct group_filter *) malloc (needed);
+ if (gf == NULL)
+ return -1;
+ }
+
+ gf->gf_interface = interface;
+ memcpy (&gf->gf_group, group, grouplen);
+ gf->gf_numsrc = *numsrc;
+
+ /* We need to provide the appropriate socket level value. */
+ int result;
+ int sol = __get_sol (group->sa_family, grouplen);
+ if (sol == -1)
+ {
+ __set_errno (EINVAL);
+ result = -1;
+ }
+ else
+ {
+ result = __getsockopt (s, sol, MCAST_MSFILTER, gf, &needed);
+
+ /* If successful, copy the results to the places the caller wants
+ them in. */
+ if (result == 0)
+ {
+ *fmode = gf->gf_fmode;
+ memcpy (slist, gf->gf_slist,
+ MIN (*numsrc, gf->gf_numsrc)
+ * sizeof (struct sockaddr_storage));
+ *numsrc = gf->gf_numsrc;
+ }
+ }
+
+ if (! use_alloca)
+ {
+ int save_errno = errno;
+ free (gf);
+ __set_errno (save_errno);
+ }
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/getsysstats.c b/libc/sysdeps/unix/sysv/linux/getsysstats.c
new file mode 100644
index 000000000..d655ba3b2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/getsysstats.c
@@ -0,0 +1,214 @@
+/* Determine various system internal values, Linux version.
+ Copyright (C) 1996-2001, 2002, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <alloca.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <mntent.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/sysinfo.h>
+
+#include <atomic.h>
+
+
+/* How we can determine the number of available processors depends on
+ the configuration. There is currently (as of version 2.0.21) no
+ system call to determine the number. It is planned for the 2.1.x
+ series to add this, though.
+
+ One possibility to implement it for systems using Linux 2.0 is to
+ examine the pseudo file /proc/cpuinfo. Here we have one entry for
+ each processor.
+
+ But not all systems have support for the /proc filesystem. If it
+ is not available we simply return 1 since there is no way. */
+
+/* Other architectures use different formats for /proc/cpuinfo. This
+ provides a hook for alternative parsers. */
+#ifndef GET_NPROCS_PARSER
+# define GET_NPROCS_PARSER(FP, BUFFER, RESULT) \
+ do \
+ { \
+ (RESULT) = 0; \
+ /* Read all lines and count the lines starting with the string \
+ "processor". We don't have to fear extremely long lines since \
+ the kernel will not generate them. 8192 bytes are really \
+ enough. */ \
+ while (fgets_unlocked (BUFFER, sizeof (BUFFER), FP) != NULL) \
+ if (strncmp (BUFFER, "processor", 9) == 0) \
+ ++(RESULT); \
+ } \
+ while (0)
+#endif
+
+int
+__get_nprocs ()
+{
+ char buffer[8192];
+ int result = 1;
+
+ /* XXX Here will come a test for the new system call. */
+
+ /* The /proc/stat format is more uniform, use it by default. */
+ FILE *fp = fopen ("/proc/stat", "rc");
+ if (fp != NULL)
+ {
+ /* No threads use this stream. */
+ __fsetlocking (fp, FSETLOCKING_BYCALLER);
+
+ result = 0;
+ while (fgets_unlocked (buffer, sizeof (buffer), fp) != NULL)
+ if (strncmp (buffer, "cpu", 3) == 0 && isdigit (buffer[3]))
+ ++result;
+
+ fclose (fp);
+ }
+ else
+ {
+ fp = fopen ("/proc/cpuinfo", "rc");
+ if (fp != NULL)
+ {
+ /* No threads use this stream. */
+ __fsetlocking (fp, FSETLOCKING_BYCALLER);
+ GET_NPROCS_PARSER (fp, buffer, result);
+ fclose (fp);
+ }
+ }
+
+ return result;
+}
+weak_alias (__get_nprocs, get_nprocs)
+
+
+#ifdef GET_NPROCS_CONF_PARSER
+/* On some architectures it is possible to distinguish between configured
+ and active cpus. */
+int
+__get_nprocs_conf ()
+{
+ char buffer[8192];
+ int result = 1;
+
+ /* XXX Here will come a test for the new system call. */
+
+ /* If we haven't found an appropriate entry return 1. */
+ FILE *fp = fopen ("/proc/cpuinfo", "rc");
+ if (fp != NULL)
+ {
+ /* No threads use this stream. */
+ __fsetlocking (fp, FSETLOCKING_BYCALLER);
+ GET_NPROCS_CONF_PARSER (fp, buffer, result);
+ fclose (fp);
+ }
+
+ return result;
+}
+#else
+/* As far as I know Linux has no separate numbers for configured and
+ available processors. So make the `get_nprocs_conf' function an
+ alias. */
+strong_alias (__get_nprocs, __get_nprocs_conf)
+#endif
+weak_alias (__get_nprocs_conf, get_nprocs_conf)
+
+/* General function to get information about memory status from proc
+ filesystem. */
+static long int
+internal_function
+phys_pages_info (const char *format)
+{
+ char buffer[8192];
+ long int result = -1;
+
+ /* If we haven't found an appropriate entry return 1. */
+ FILE *fp = fopen ("/proc/meminfo", "rc");
+ if (fp != NULL)
+ {
+ /* No threads use this stream. */
+ __fsetlocking (fp, FSETLOCKING_BYCALLER);
+
+ result = 0;
+ /* Read all lines and count the lines starting with the
+ string "processor". We don't have to fear extremely long
+ lines since the kernel will not generate them. 8192
+ bytes are really enough. */
+ while (fgets_unlocked (buffer, sizeof buffer, fp) != NULL)
+ if (sscanf (buffer, format, &result) == 1)
+ {
+ result /= (__getpagesize () / 1024);
+ break;
+ }
+
+ fclose (fp);
+ }
+
+ if (result == -1)
+ /* We cannot get the needed value: signal an error. */
+ __set_errno (ENOSYS);
+
+ return result;
+}
+
+
+/* Return the number of pages of physical memory in the system. There
+ is currently (as of version 2.0.21) no system call to determine the
+ number. It is planned for the 2.1.x series to add this, though.
+
+ One possibility to implement it for systems using Linux 2.0 is to
+ examine the pseudo file /proc/cpuinfo. Here we have one entry for
+ each processor.
+
+ But not all systems have support for the /proc filesystem. If it
+ is not available we return -1 as an error signal. */
+long int
+__get_phys_pages ()
+{
+ /* XXX Here will come a test for the new system call. */
+
+ return phys_pages_info ("MemTotal: %ld kB");
+}
+weak_alias (__get_phys_pages, get_phys_pages)
+
+
+/* Return the number of available pages of physical memory in the
+ system. There is currently (as of version 2.0.21) no system call
+ to determine the number. It is planned for the 2.1.x series to add
+ this, though.
+
+ One possibility to implement it for systems using Linux 2.0 is to
+ examine the pseudo file /proc/cpuinfo. Here we have one entry for
+ each processor.
+
+ But not all systems have support for the /proc filesystem. If it
+ is not available we return -1 as an error signal. */
+long int
+__get_avphys_pages ()
+{
+ /* XXX Here will come a test for the new system call. */
+
+ return phys_pages_info ("MemFree: %ld kB");
+}
+weak_alias (__get_avphys_pages, get_avphys_pages)
diff --git a/libc/sysdeps/unix/sysv/linux/grantpt.c b/libc/sysdeps/unix/sysv/linux/grantpt.c
new file mode 100644
index 000000000..b894b8b63
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/grantpt.c
@@ -0,0 +1,81 @@
+/* Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <sys/statfs.h>
+
+#include "linux_fsinfo.h"
+
+/* Prototype for function that changes ownership and access permission
+ for slave pseudo terminals that do not live on a `devpts'
+ filesystem. */
+static int __unix_grantpt (int fd);
+
+/* Prototype for private function that gets the name of the slave
+ pseudo terminal in a safe way. */
+static int pts_name (int fd, char **pts, size_t buf_len);
+
+/* Change the ownership and access permission of the slave pseudo
+ terminal associated with the master pseudo terminal specified
+ by FD. */
+int
+grantpt (int fd)
+{
+ struct statfs fsbuf;
+#ifdef PATH_MAX
+ char _buf[PATH_MAX];
+#else
+ char _buf[512];
+#endif
+ char *buf = _buf;
+
+ if (__builtin_expect (pts_name (fd, &buf, sizeof (_buf)), 0))
+ {
+ int save_errno = errno;
+
+ /* Check, if the file descriptor is valid. pts_name returns the
+ wrong errno number, so we cannot use that. */
+ if (__libc_fcntl (fd, F_GETFD) == -1 && errno == EBADF)
+ return -1;
+
+ /* If the filedescriptor is no TTY, grantpt has to set errno
+ to EINVAL. */
+ if (save_errno == ENOTTY)
+ __set_errno (EINVAL);
+ else
+ __set_errno (save_errno);
+
+ return -1;
+ }
+
+ if (__statfs (buf, &fsbuf) < 0)
+ return -1;
+
+ /* If the slave pseudo terminal lives on a `devpts' filesystem, the
+ ownership and access permission are already set. */
+ if (fsbuf.f_type == DEVPTS_SUPER_MAGIC || fsbuf.f_type == DEVFS_SUPER_MAGIC)
+ return 0;
+
+ return __unix_grantpt (fd);
+}
+
+#define grantpt static __unix_grantpt
+#include <sysdeps/unix/grantpt.c>
diff --git a/libc/sysdeps/unix/sysv/linux/i386/Makefile b/libc/sysdeps/unix/sysv/linux/i386/Makefile
new file mode 100644
index 000000000..9e8497563
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/Makefile
@@ -0,0 +1,18 @@
+ifeq ($(subdir),misc)
+sysdep_routines += ioperm iopl vm86 call_pselect6
+sysdep_headers += sys/elf.h sys/perm.h sys/reg.h sys/vm86.h sys/debugreg.h sys/io.h
+endif
+
+ifeq ($(subdir),elf)
+sysdep-others += lddlibc4
+install-bin += lddlibc4
+
+endif
+
+ifeq ($(subdir),resource)
+sysdep_routines += oldgetrlimit64
+endif
+
+ifeq ($(subdir),stdlib)
+gen-as-const-headers += ucontext_i.sym
+endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/Versions b/libc/sysdeps/unix/sysv/linux/i386/Versions
new file mode 100644
index 000000000..abd1d152d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/Versions
@@ -0,0 +1,47 @@
+libc {
+ GLIBC_2.0 {
+ # Exception handling support functions from libgcc
+ __register_frame; __register_frame_table; __deregister_frame;
+ __frame_state_for; __register_frame_info_table;
+
+ ioperm; iopl;
+
+ vm86;
+ }
+ GLIBC_2.1 {
+ modify_ldt;
+ }
+ GLIBC_2.2 {
+ # functions used in other libraries
+ __xstat64; __fxstat64; __lxstat64;
+
+ # a*
+ alphasort64;
+
+ # g*
+ glob64;
+
+ # New rlimit interface
+ getrlimit; setrlimit; getrlimit64;
+
+ # r*
+ readdir64; readdir64_r;
+
+ # s*
+ scandir64;
+
+ # v*
+ versionsort64;
+ }
+ GLIBC_2.3.3 {
+ # p*
+ posix_fadvise64; posix_fallocate64;
+ }
+ GLIBC_2.3.4 {
+ # v*
+ vm86;
+ }
+ GLIBC_PRIVATE {
+ __modify_ldt;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/i386/_exit.S b/libc/sysdeps/unix/sysv/linux/i386/_exit.S
new file mode 100644
index 000000000..5c2e58840
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/_exit.S
@@ -0,0 +1,44 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ .type _exit,@function
+ .global _exit
+_exit:
+ movl 4(%esp), %ebx
+
+ /* Try the new syscall first. */
+#ifdef __NR_exit_group
+ movl $__NR_exit_group, %eax
+ ENTER_KERNEL
+#endif
+
+ /* Not available. Now the old one. */
+ movl $__NR_exit, %eax
+ /* Don't bother using ENTER_KERNEL here. If the exit_group
+ syscall is not available AT_SYSINFO isn't either. */
+ int $0x80
+
+ /* This must not fail. Be sure we don't return. */
+ hlt
+ .size _exit,.-_exit
+
+libc_hidden_def (_exit)
+weak_alias (_exit, _Exit)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/alphasort64.c b/libc/sysdeps/unix/sysv/linux/i386/alphasort64.c
new file mode 100644
index 000000000..221aedc16
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/alphasort64.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1992, 1997, 1998, 2000, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dirent.h>
+#include <string.h>
+
+int
+__alphasort64 (const void *a, const void *b)
+{
+ return strcoll ((*(const struct dirent64 **) a)->d_name,
+ (*(const struct dirent64 **) b)->d_name);
+}
+
+#include <shlib-compat.h>
+
+versioned_symbol (libc, __alphasort64, alphasort64, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+int
+__old_alphasort64 (const void *a, const void *b);
+
+int
+attribute_compat_text_section
+__old_alphasort64 (const void *a, const void *b)
+{
+ return strcoll ((*(const struct __old_dirent64 **) a)->d_name,
+ (*(const struct __old_dirent64 **) b)->d_name);
+}
+
+compat_symbol (libc, __old_alphasort64, alphasort64, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/bits/a.out.h b/libc/sysdeps/unix/sysv/linux/i386/bits/a.out.h
new file mode 100644
index 000000000..0fb52c381
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/bits/a.out.h
@@ -0,0 +1,3 @@
+#ifndef __A_OUT_GNU_H__
+# error "Never use <bits/a.out.h> directly; include <a.out.h> instead."
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/bits/environments.h b/libc/sysdeps/unix/sysv/linux/i386/bits/environments.h
new file mode 100644
index 000000000..16f7732aa
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/bits/environments.h
@@ -0,0 +1,62 @@
+/* Copyright (C) 1999, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _UNISTD_H
+# error "Never include this file directly. Use <unistd.h> instead"
+#endif
+
+/* This header should define the following symbols under the described
+ situations. A value `1' means that the model is always supported,
+ `-1' means it is never supported. Undefined means it cannot be
+ statically decided.
+
+ _POSIX_V6_ILP32_OFF32 32bit int, long, pointers, and off_t type
+ _POSIX_V6_ILP32_OFFBIG 32bit int, long, and pointers and larger off_t type
+
+ _POSIX_V6_LP64_OFF32 64bit long and pointers and 32bit off_t type
+ _POSIX_V6_LPBIG_OFFBIG 64bit long and pointers and large off_t type
+
+ The macros _XBS5_ILP32_OFF32, _XBS5_ILP32_OFFBIG, _XBS5_LP64_OFF32, and
+ _XBS5_LPBIG_OFFBIG were used in previous versions of the Unix standard
+ and are available only for compatibility.
+*/
+
+/* By default we have 32-bit wide `int', `long int', pointers and `off_t'
+ and all platforms support LFS. */
+#define _POSIX_V6_ILP32_OFF32 1
+#define _POSIX_V6_ILP32_OFFBIG 1
+#define _XBS5_ILP32_OFF32 1
+#define _XBS5_ILP32_OFFBIG 1
+
+/* We optionally provide an environment with the above size but an 64-bit
+ side `off_t'. Therefore we don't define _XBS5_ILP32_OFFBIG. */
+
+/* Environments with 64-bit wide pointers can be provided,
+ so these macros aren't defined:
+ # undef _POSIX_V6_LP64_OFF64
+ # undef _POSIX_V6_LPBIG_OFFBIG
+ # undef _XBS5_LP64_OFF64
+ # undef _XBS5_LPBIG_OFFBIG
+ and sysconf tests for it at runtime. */
+
+#define __ILP32_OFF32_CFLAGS "-m32"
+#define __ILP32_OFFBIG_CFLAGS "-m32 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+#define __ILP32_OFF32_LDFLAGS "-m32"
+#define __ILP32_OFFBIG_LDFLAGS "-m32"
+#define __LP64_OFF64_CFLAGS "-m64"
+#define __LP64_OFF64_LDFLAGS "-m64"
diff --git a/libc/sysdeps/unix/sysv/linux/i386/bits/fcntl.h b/libc/sysdeps/unix/sysv/linux/i386/bits/fcntl.h
new file mode 100644
index 000000000..1f7ac0f25
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/bits/fcntl.h
@@ -0,0 +1,236 @@
+/* O_*, F_*, FD_* bit values for Linux.
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#include <sys/types.h>
+#ifdef __USE_GNU
+# include <bits/uio.h>
+#endif
+
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_ACCMODE 0003
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+#define O_CREAT 0100 /* not fcntl */
+#define O_EXCL 0200 /* not fcntl */
+#define O_NOCTTY 0400 /* not fcntl */
+#define O_TRUNC 01000 /* not fcntl */
+#define O_APPEND 02000
+#define O_NONBLOCK 04000
+#define O_NDELAY O_NONBLOCK
+#define O_SYNC 010000
+#define O_FSYNC O_SYNC
+#define O_ASYNC 020000
+
+#ifdef __USE_GNU
+# define O_DIRECT 040000 /* Direct disk access. */
+# define O_DIRECTORY 0200000 /* Must be a directory. */
+# define O_NOFOLLOW 0400000 /* Do not follow links. */
+# define O_NOATIME 01000000 /* Do not set atime. */
+#endif
+
+/* For now Linux has synchronisity options for data and read operations.
+ We define the symbols here but let them do the same as O_SYNC since
+ this is a superset. */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC O_SYNC /* Synchronize data. */
+# define O_RSYNC O_SYNC /* Synchronize read operations. */
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define O_LARGEFILE 0100000
+#endif
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#ifndef __USE_FILE_OFFSET64
+# define F_GETLK 5 /* Get record locking info. */
+# define F_SETLK 6 /* Set record locking info (non-blocking). */
+# define F_SETLKW 7 /* Set record locking info (blocking). */
+#else
+# define F_GETLK F_GETLK64 /* Get record locking info. */
+# define F_SETLK F_SETLK64 /* Set record locking info (non-blocking).*/
+# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */
+#endif
+#define F_GETLK64 12 /* Get record locking info. */
+#define F_SETLK64 13 /* Set record locking info (non-blocking). */
+#define F_SETLKW64 14 /* Set record locking info (blocking). */
+
+#if defined __USE_BSD || defined __USE_UNIX98
+# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */
+# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETSIG 10 /* Set number of signal to be sent. */
+# define F_GETSIG 11 /* Get number of signal to be sent. */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETLEASE 1024 /* Set a lease. */
+# define F_GETLEASE 1025 /* Enquire what lease is active. */
+# define F_NOTIFY 1026 /* Request notfications on a directory. */
+#endif
+
+/* For F_[GET|SET]FD. */
+#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
+#define F_RDLCK 0 /* Read lock. */
+#define F_WRLCK 1 /* Write lock. */
+#define F_UNLCK 2 /* Remove lock. */
+
+/* For old implementation of bsd flock(). */
+#define F_EXLCK 4 /* or 3 */
+#define F_SHLCK 8 /* or 4 */
+
+#ifdef __USE_BSD
+/* Operations for bsd flock(), also used by the kernel implementation. */
+# define LOCK_SH 1 /* shared lock */
+# define LOCK_EX 2 /* exclusive lock */
+# define LOCK_NB 4 /* or'd with one of the above to prevent
+ blocking */
+# define LOCK_UN 8 /* remove lock */
+#endif
+
+#ifdef __USE_GNU
+# define LOCK_MAND 32 /* This is a mandatory flock: */
+# define LOCK_READ 64 /* ... which allows concurrent read operations. */
+# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */
+# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */
+#endif
+
+#ifdef __USE_GNU
+/* Types of directory notifications that may be requested with F_NOTIFY. */
+# define DN_ACCESS 0x00000001 /* File accessed. */
+# define DN_MODIFY 0x00000002 /* File modified. */
+# define DN_CREATE 0x00000004 /* File created. */
+# define DN_DELETE 0x00000008 /* File removed. */
+# define DN_RENAME 0x00000010 /* File renamed. */
+# define DN_ATTRIB 0x00000020 /* File changed attibutes. */
+# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */
+#endif
+
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+#ifndef __USE_FILE_OFFSET64
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+#else
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+#endif
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+#endif
+
+/* Define some more compatibility macros to be backward compatible with
+ BSD systems which did not managed to hide these kernel macros. */
+#ifdef __USE_BSD
+# define FAPPEND O_APPEND
+# define FFSYNC O_FSYNC
+# define FASYNC O_ASYNC
+# define FNONBLOCK O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif /* Use BSD. */
+
+/* Advise to `posix_fadvise'. */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
+# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
+#endif
+
+
+#ifdef __USE_GNU
+/* Flags for SYNC_FILE_RANGE. */
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+
+/* Flags for SPLICE and VMSPLICE. */
+# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */
+# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing
+ (but we may still block on the fd
+ we splice from/to). */
+# define SPLICE_F_MORE 4 /* Expect more data. */
+# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
+#endif
+
+__BEGIN_DECLS
+
+#ifdef __USE_GNU
+
+/* Provide kernel hint to read ahead. */
+extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
+ __THROW;
+
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice address range into a pipe. */
+extern int vmsplice (int __fdout, const struct iovec *__iov, size_t __count,
+ unsigned int __flags);
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/i386/bits/mman.h b/libc/sysdeps/unix/sysv/linux/i386/bits/mman.h
new file mode 100644
index 000000000..00cb98239
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/bits/mman.h
@@ -0,0 +1,103 @@
+/* Definitions for POSIX memory map interface. Linux/i386 version.
+ Copyright (C) 1997, 2000, 2003, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MMAN_H
+# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
+#endif
+
+/* The following definitions basically come from the kernel headers.
+ But the kernel header is not namespace clean. */
+
+
+/* Protections are chosen from these bits, OR'd together. The
+ implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ without PROT_READ. The only guarantees are that no writing will be
+ allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
+
+#define PROT_READ 0x1 /* Page can be read. */
+#define PROT_WRITE 0x2 /* Page can be written. */
+#define PROT_EXEC 0x4 /* Page can be executed. */
+#define PROT_NONE 0x0 /* Page can not be accessed. */
+#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
+ growsdown vma (mprotect only). */
+#define PROT_GROWSUP 0x02000000 /* Extend change to start of
+ growsup vma (mprotect only). */
+
+/* Sharing types (must choose one and only one of these). */
+#define MAP_SHARED 0x01 /* Share changes. */
+#define MAP_PRIVATE 0x02 /* Changes are private. */
+#ifdef __USE_MISC
+# define MAP_TYPE 0x0f /* Mask for type of mapping. */
+#endif
+
+/* Other flags. */
+#define MAP_FIXED 0x10 /* Interpret addr exactly. */
+#ifdef __USE_MISC
+# define MAP_FILE 0
+# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+
+/* These are Linux-specific. */
+#ifdef __USE_MISC
+# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */
+# define MAP_DENYWRITE 0x00800 /* ETXTBSY */
+# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */
+# define MAP_LOCKED 0x02000 /* Lock the mapping. */
+# define MAP_NORESERVE 0x04000 /* Don't check for reservations. */
+# define MAP_POPULATE 0x08000 /* Populate (prefault) pagetables. */
+# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */
+#endif
+
+/* Flags to `msync'. */
+#define MS_ASYNC 1 /* Sync memory asynchronously. */
+#define MS_SYNC 4 /* Synchronous memory sync. */
+#define MS_INVALIDATE 2 /* Invalidate the caches. */
+
+/* Flags for `mlockall'. */
+#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
+#define MCL_FUTURE 2 /* Lock all additions to address
+ space. */
+
+/* Flags for `mremap'. */
+#ifdef __USE_GNU
+# define MREMAP_MAYMOVE 1
+# define MREMAP_FIXED 2
+#endif
+
+/* Advice to `madvise'. */
+#ifdef __USE_BSD
+# define MADV_NORMAL 0 /* No further special treatment. */
+# define MADV_RANDOM 1 /* Expect random page references. */
+# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define MADV_WILLNEED 3 /* Will need these pages. */
+# define MADV_DONTNEED 4 /* Don't need these pages. */
+# define MADV_REMOVE 9 /* Remove these pages and resources. */
+# define MADV_DONTFORK 10 /* Do not inherit across fork. */
+# define MADV_DOFORK 11 /* Do inherit across fork. */
+#endif
+
+/* The POSIX people had to invent similar names for the same things. */
+#ifdef __USE_XOPEN2K
+# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/bits/wchar.h b/libc/sysdeps/unix/sysv/linux/i386/bits/wchar.h
new file mode 100644
index 000000000..442a4621e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/bits/wchar.h
@@ -0,0 +1,26 @@
+/* wchar_t type related definitions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_WCHAR_H
+#define _BITS_WCHAR_H 1
+
+#define __WCHAR_MIN (-2147483647l - 1l)
+#define __WCHAR_MAX (2147483647l)
+
+#endif /* bits/wchar.h */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/bp-thunks.h b/libc/sysdeps/unix/sysv/linux/i386/bp-thunks.h
new file mode 100644
index 000000000..59a42ddef
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/bp-thunks.h
@@ -0,0 +1,4 @@
+#ifndef __ASSEMBLER__
+# include <sysdeps/generic/bp-thunks.h>
+# include <sys/vm86.h>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/brk.c b/libc/sysdeps/unix/sysv/linux/i386/brk.c
new file mode 100644
index 000000000..1d26439ed
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/brk.c
@@ -0,0 +1,53 @@
+/* brk system call for Linux/i386.
+ Copyright (C) 1995, 1996, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sysdep.h>
+
+#include <bp-checks.h>
+
+/* This must be initialized data because commons can't have aliases. */
+void *__curbrk = 0;
+
+/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt
+ to work around different old braindamage in the old Linux ELF dynamic
+ linker. */
+weak_alias (__curbrk, ___brk_addr)
+
+int
+__brk (void *addr)
+{
+ void *__unbounded newbrk;
+
+ INTERNAL_SYSCALL_DECL (err);
+ newbrk = (void *__unbounded) INTERNAL_SYSCALL (brk, err, 1,
+ __ptrvalue (addr));
+
+ __curbrk = newbrk;
+
+ if (newbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+weak_alias (__brk, brk)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/call_pselect6.S b/libc/sysdeps/unix/sysv/linux/i386/call_pselect6.S
new file mode 100644
index 000000000..a356f1dfa
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/call_pselect6.S
@@ -0,0 +1,65 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#ifdef __NR_pselect6
+ .text
+ENTRY(__call_pselect6)
+ .hidden __call_pselect6
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebp, 0)
+ cfi_rel_offset (edi, 4)
+ cfi_rel_offset (esi, 8)
+ cfi_rel_offset (ebx, 12)
+
+ movl $__NR_pselect6, %eax
+ movl 20(%esp), %ebx
+ movl 24(%esp), %ecx
+ movl 28(%esp), %edx
+ movl 32(%esp), %esi
+ movl 36(%esp), %edi
+ movl 40(%esp), %ebp
+
+ /* The syscall handling cannot handle 6 parameters. Yet. */
+ int $0x80
+
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+
+ ret
+END(__call_pselect6)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/chown.c b/libc/sysdeps/unix/sysv/linux/i386/chown.c
new file mode 100644
index 000000000..fc6a9c95a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/chown.c
@@ -0,0 +1,159 @@
+/* Copyright (C) 1998,1999,2000,2002,2003,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <shlib-compat.h>
+#include <bp-checks.h>
+
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+/*
+ In Linux 2.1.x the chown functions have been changed. A new function lchown
+ was introduced. The new chown now follows symlinks - the old chown and the
+ new lchown do not follow symlinks.
+ The new lchown function has the same number as the old chown had and the
+ new chown has a new number. When compiling with headers from Linux > 2.1.8x
+ it's impossible to run this libc with older kernels. In these cases libc
+ has therefore to route calls to chown to the old chown function.
+*/
+
+extern int __chown_is_lchown (const char *__file, uid_t __owner,
+ gid_t __group);
+extern int __real_chown (const char *__file, uid_t __owner, gid_t __group);
+
+
+#if defined __NR_lchown || __ASSUME_LCHOWN_SYSCALL > 0
+/* Running under Linux > 2.1.80. */
+
+# ifdef __NR_chown32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+# endif /* __NR_chown32 */
+
+int
+__real_chown (const char *file, uid_t owner, gid_t group)
+{
+# if __ASSUME_LCHOWN_SYSCALL == 0
+ static int __libc_old_chown;
+ int result;
+
+ if (!__libc_old_chown)
+ {
+ int saved_errno = errno;
+# ifdef __NR_chown32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+ int saved_errno = errno;
+
+ result = INLINE_SYSCALL (chown32, 3, CHECK_STRING (file), owner, group);
+ if (result == 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_chown32 */
+ if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
+ || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ result = INLINE_SYSCALL (chown, 3, CHECK_STRING (file), owner, group);
+
+ if (result >= 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_old_chown = 1;
+ }
+
+ return __lchown (file, owner, group);
+# elif __ASSUME_32BITUIDS
+ /* This implies __ASSUME_LCHOWN_SYSCALL. */
+ return INLINE_SYSCALL (chown32, 3, CHECK_STRING (file), owner, group);
+# else
+ /* !__ASSUME_32BITUIDS && ASSUME_LCHOWN_SYSCALL */
+# ifdef __NR_chown32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+ int saved_errno = errno;
+
+ result = INLINE_SYSCALL (chown32, 3, CHECK_STRING (file), owner, group);
+ if (result == 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_chown32 */
+ if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
+ || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return INLINE_SYSCALL (chown, 3, CHECK_STRING (file), owner, group);
+# endif
+}
+#endif
+
+
+#if !defined __NR_lchown && __ASSUME_LCHOWN_SYSCALL == 0
+/* Compiling under older kernels. */
+int
+__chown_is_lchown (const char *file, uid_t owner, gid_t group)
+{
+ return INLINE_SYSCALL (chown, 3, CHECK_STRING (file), owner, group);
+}
+#elif SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+/* Compiling for compatibiity. */
+int
+attribute_compat_text_section
+__chown_is_lchown (const char *file, uid_t owner, gid_t group)
+{
+ return __lchown (file, owner, group);
+}
+#endif
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+compat_symbol (libc, __chown_is_lchown, chown, GLIBC_2_0);
+#endif
+
+#ifdef __NR_lchown
+versioned_symbol (libc, __real_chown, chown, GLIBC_2_1);
+strong_alias (__real_chown, __chown)
+#else
+strong_alias (__chown_is_lchown, __chown_is_lchown21)
+versioned_symbol (libc, __chown_is_lchown21, chown, GLIBC_2_1);
+strong_alias (__chown_is_lchown, __chown)
+#endif
+libc_hidden_def (__chown)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/clone.S b/libc/sysdeps/unix/sysv/linux/i386/clone.S
new file mode 100644
index 000000000..54524ec12
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/clone.S
@@ -0,0 +1,159 @@
+/* Copyright (C) 1996-2000,02,03,04,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@tamu.edu)
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* clone() is even more special than fork() as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <asm-syntax.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+ pid_t *ptid, struct user_desc *tls, pid_t *ctid); */
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define FUNC PARMS
+#define STACK FUNC+4
+#define FLAGS STACK+PTR_SIZE
+#define ARG FLAGS+4
+#define PTID ARG+PTR_SIZE
+#define TLS PTID+PTR_SIZE
+#define CTID TLS+PTR_SIZE
+
+#define __NR_clone 120
+#define SYS_clone 120
+
+#define CLONE_VM 0x00000100
+#define CLONE_THREAD 0x00010000
+
+ .text
+ENTRY (BP_SYM (__clone))
+ /* Sanity check arguments. */
+ movl $-EINVAL,%eax
+ movl FUNC(%esp),%ecx /* no NULL function pointers */
+#ifdef PIC
+ jecxz SYSCALL_ERROR_LABEL
+#else
+ testl %ecx,%ecx
+ jz SYSCALL_ERROR_LABEL
+#endif
+ movl STACK(%esp),%ecx /* no NULL stack pointers */
+#ifdef PIC
+ jecxz SYSCALL_ERROR_LABEL
+#else
+ testl %ecx,%ecx
+ jz SYSCALL_ERROR_LABEL
+#endif
+
+ /* Insert the argument onto the new stack. Make sure the new
+ thread is started with an alignment of (mod 16). */
+ andl $0xfffffff0, %ecx
+ subl $28,%ecx
+ movl ARG(%esp),%eax /* no negative argument counts */
+ movl %eax,12(%ecx)
+
+ /* Save the function pointer as the zeroth argument.
+ It will be popped off in the child in the ebx frobbing below. */
+ movl FUNC(%esp),%eax
+ movl %eax,8(%ecx)
+ /* Don't leak any information. */
+ movl $0,4(%ecx)
+#ifndef RESET_PID
+ movl $0,(%ecx)
+#endif
+
+ /* Do the system call */
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+
+ movl TLS+12(%esp),%esi
+ cfi_rel_offset (esi, 4)
+ movl PTID+12(%esp),%edx
+ movl FLAGS+12(%esp),%ebx
+ cfi_rel_offset (ebx, 8)
+ movl CTID+12(%esp),%edi
+ cfi_rel_offset (edi, 0)
+ movl $SYS_ify(clone),%eax
+
+#ifdef RESET_PID
+ /* Remember the flag value. */
+ movl %ebx, (%ecx)
+#endif
+
+ /* End FDE now, because in the child the unwind info will be
+ wrong. */
+ cfi_endproc
+
+ int $0x80
+ popl %edi
+ popl %esi
+ popl %ebx
+
+ test %eax,%eax
+ jl SYSCALL_ERROR_LABEL
+ jz L(thread_start)
+
+L(pseudo_end):
+ ret
+
+L(thread_start):
+ /* Note: %esi is zero. */
+ movl %esi,%ebp /* terminate the stack frame */
+#ifdef RESET_PID
+ testl $CLONE_THREAD, %edi
+ je L(newpid)
+L(haspid):
+#endif
+ call *%ebx
+#ifdef PIC
+ call L(here)
+L(here):
+ popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ebx
+#endif
+ movl %eax, %ebx
+ movl $SYS_ify(exit), %eax
+ ENTER_KERNEL
+
+#ifdef RESET_PID
+ .subsection 2
+L(newpid):
+ testl $CLONE_VM, %edi
+ movl $-1, %eax
+ jne L(nomoregetpid)
+ movl $SYS_ify(getpid), %eax
+ ENTER_KERNEL
+L(nomoregetpid):
+ movl %eax, %gs:PID
+ movl %eax, %gs:TID
+ jmp L(haspid)
+ .previous
+#endif
+
+ cfi_startproc
+PSEUDO_END (BP_SYM (__clone))
+
+weak_alias (BP_SYM (__clone), BP_SYM (clone))
diff --git a/libc/sysdeps/unix/sysv/linux/i386/dl-librecon.h b/libc/sysdeps/unix/sysv/linux/i386/dl-librecon.h
new file mode 100644
index 000000000..9f5203151
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/dl-librecon.h
@@ -0,0 +1,63 @@
+/* Optional code to distinguish library flavours.
+ Copyright (C) 1998, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DL_LIBRECON_H
+
+#include <sysdeps/unix/sysv/linux/dl-librecon.h>
+
+#define DISTINGUISH_LIB_VERSIONS \
+ do \
+ { \
+ /* We have to find out whether the binary is linked against \
+ libc 5 or glibc. We do this by looking at all the DT_NEEDED \
+ entries. If one is libc.so.5 this is a libc 5 linked binary. */ \
+ if (main_map->l_info[DT_NEEDED]) \
+ { \
+ /* We have dependencies. */ \
+ const ElfW(Dyn) *d; \
+ const char *strtab; \
+ \
+ strtab = (const char *) D_PTR (main_map, l_info[DT_STRTAB]); \
+ \
+ for (d = main_map->l_ld; d->d_tag != DT_NULL; ++d) \
+ if (d->d_tag == DT_NEEDED \
+ && strcmp (strtab + d->d_un.d_val, "libc.so.5") == 0) \
+ break; \
+ \
+ /* We print a `5' or `6' depending on the outcome. */ \
+ _dl_printf (d->d_tag != DT_NULL ? "5\n" : "6\n"); \
+ } \
+ } \
+ while (0)
+
+/* Recognizing extra environment variables. */
+#define EXTRA_LD_ENVVARS \
+ case 15: \
+ if (memcmp (envline, "LIBRARY_VERSION", 15) == 0) \
+ GLRO(dl_correct_cache_id) = envline[16] == '5' ? 2 : 3; \
+ break; \
+
+/* Extra unsecure variables. The names are all stuffed in a single
+ string which means they have to be terminated with a '\0' explicitly. */
+#define EXTRA_UNSECURE_ENVVARS \
+ "LD_AOUT_LIBRARY_PATH\0" \
+ "LD_AOUT_PRELOAD\0"
+
+#endif /* dl-librecon.h */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/dl-procinfo.h b/libc/sysdeps/unix/sysv/linux/i386/dl-procinfo.h
new file mode 100644
index 000000000..d92a3b235
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/dl-procinfo.h
@@ -0,0 +1,43 @@
+/* Linux/i386 version of processor capability information handling macros.
+ Copyright (C) 1998-2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/i386/dl-procinfo.h>
+#include <ldsodefs.h>
+
+
+#undef _dl_procinfo
+static inline int
+__attribute__ ((unused))
+_dl_procinfo (int word)
+{
+ /* This table should match the information from arch/i386/kernel/setup.c
+ in the kernel sources. */
+ int i;
+
+ _dl_printf ("AT_HWCAP: ");
+
+ for (i = 0; i < _DL_HWCAP_COUNT; ++i)
+ if (word & (1 << i))
+ _dl_printf (" %s", GLRO(dl_x86_cap_flags)[i]);
+
+ _dl_printf ("\n");
+
+ return 0;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/i386/fchown.c b/libc/sysdeps/unix/sysv/linux/i386/fchown.c
new file mode 100644
index 000000000..30299c960
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/fchown.c
@@ -0,0 +1,68 @@
+/* Copyright (C) 2000, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+#ifdef __NR_fchown32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif /* __NR_fchown32 */
+
+int
+__fchown (int fd, uid_t owner, gid_t group)
+{
+#if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (fchown32, 3, fd, owner, group);
+#else
+# ifdef __NR_fchown32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+ int saved_errno = errno;
+
+ result = INLINE_SYSCALL (fchown32, 3, fd, owner, group);
+ if (result == 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_fchown32 */
+
+ if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
+ || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return INLINE_SYSCALL (fchown, 3, fd, owner, group);
+#endif
+}
+
+weak_alias (__fchown, fchown)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/fchownat.c b/libc/sysdeps/unix/sysv/linux/i386/fchownat.c
new file mode 100644
index 000000000..db5481705
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/fchownat.c
@@ -0,0 +1,196 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <shlib-compat.h>
+#include <bp-checks.h>
+
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+/*
+ In Linux 2.1.x the chown functions have been changed. A new function lchown
+ was introduced. The new chown now follows symlinks - the old chown and the
+ new lchown do not follow symlinks.
+ The new lchown function has the same number as the old chown had and the
+ new chown has a new number. When compiling with headers from Linux > 2.1.8x
+ it's impossible to run this libc with older kernels. In these cases libc
+ has therefore to route calls to chown to the old chown function.
+*/
+
+extern int __chown_is_lchown (const char *__file, uid_t __owner,
+ gid_t __group);
+extern int __real_chown (const char *__file, uid_t __owner, gid_t __group);
+
+
+#if defined __NR_lchown || __ASSUME_LCHOWN_SYSCALL > 0
+/* Running under Linux > 2.1.80. */
+
+# ifdef __NR_chown32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+# endif /* __NR_chown32 */
+#endif
+
+
+int
+fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
+{
+ int result;
+
+#ifdef __NR_fchownat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INLINE_SYSCALL (fchownat, 5, fd, file, owner, group, flag);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ if (flag & ~AT_SYMLINK_NOFOLLOW)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+# if defined __NR_lchown || __ASSUME_LCHOWN_SYSCALL > 0
+# if __ASSUME_LCHOWN_SYSCALL == 0
+ static int __libc_old_chown;
+
+# ifdef __NR_chown32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lchown32, err, 3, CHECK_STRING (file),
+ owner, group);
+ else
+ result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file),
+ owner, group);
+
+ if (!INTERNAL_SYSCALL_ERROR_P (result, err))
+ return result;
+ if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ goto fail;
+
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_chown32 */
+
+ if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
+ || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (!__libc_old_chown && (flag & AT_SYMLINK_NOFOLLOW) == 0)
+ {
+ result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner,
+ group);
+
+ if (!INTERNAL_SYSCALL_ERROR_P (result, err))
+ return result;
+ if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ goto fail;
+
+ __libc_old_chown = 1;
+ }
+
+ result = INTERNAL_SYSCALL (lchown, err, 3, CHECK_STRING (file), owner,
+ group);
+# elif __ASSUME_32BITUIDS
+ /* This implies __ASSUME_LCHOWN_SYSCALL. */
+ result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
+ group);
+# else
+ /* !__ASSUME_32BITUIDS && ASSUME_LCHOWN_SYSCALL */
+# ifdef __NR_chown32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
+ group);
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return result;
+ if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ goto fail;
+
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_chown32 */
+ if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
+ || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner, group);
+# endif
+# else
+ result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner, group);
+# endif
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ goto fail;
+
+ return result;
+
+ fail:
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
+ return -1;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/i386/fcntl.c b/libc/sysdeps/unix/sysv/linux/i386/fcntl.c
new file mode 100644
index 000000000..b27373d24
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/fcntl.c
@@ -0,0 +1,169 @@
+/* Copyright (C) 2000,2002,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <sysdep-cancel.h> /* Must come before <fcntl.h>. */
+#include <fcntl.h>
+#include <stdarg.h>
+
+#include <sys/syscall.h>
+#include <kernel-features.h>
+
+#if __ASSUME_FCNTL64 == 0
+/* This variable is shared with all files that check for fcntl64. */
+int __have_no_fcntl64;
+#endif
+
+#if defined NO_CANCELLATION && __ASSUME_FCNTL64 == 0
+# define __fcntl_nocancel __libc_fcntl
+#endif
+
+#if !defined NO_CANCELLATION || __ASSUME_FCNTL64 == 0
+int
+__fcntl_nocancel (int fd, int cmd, ...)
+{
+ va_list ap;
+ void *arg;
+
+ va_start (ap, cmd);
+ arg = va_arg (ap, void *);
+ va_end (ap);
+
+#if __ASSUME_FCNTL64 == 0
+# ifdef __NR_fcntl64
+ if (! __have_no_fcntl64)
+ {
+ int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+ if (result >= 0 || errno != ENOSYS)
+ return result;
+
+ __have_no_fcntl64 = 1;
+ }
+# endif
+ switch (cmd)
+ {
+ case F_GETLK64:
+ /* Convert arg from flock64 to flock and back. */
+ {
+ struct flock fl;
+ struct flock64 *fl64 = arg;
+ int res;
+
+ fl.l_start = (off_t)fl64->l_start;
+ /* Check if we can represent the values with the smaller type. */
+ if ((off64_t) fl.l_start != fl64->l_start)
+ {
+ eoverflow:
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+ fl.l_len = (off_t) fl64->l_len;
+ /* Check if we can represent the values with the smaller type. */
+ if ((off64_t) fl.l_len != fl64->l_len)
+ goto eoverflow;
+
+ fl.l_type = fl64->l_type;
+ fl.l_whence = fl64->l_whence;
+ fl.l_pid = fl64->l_pid;
+
+ res = INLINE_SYSCALL (fcntl, 3, fd, F_GETLK, &fl);
+ if (res != 0)
+ return res;
+ /* Everything ok, convert back. */
+ fl64->l_type = fl.l_type;
+ fl64->l_whence = fl.l_whence;
+ fl64->l_start = fl.l_start;
+ fl64->l_len = fl.l_len;
+ fl64->l_pid = fl.l_pid;
+
+ return 0;
+ }
+ case F_SETLK64:
+ case F_SETLKW64:
+ /* Try to convert arg from flock64 to flock. */
+ {
+ struct flock fl;
+ struct flock64 *fl64 = arg;
+
+ fl.l_start = (off_t) fl64->l_start;
+ /* Check if we can represent the values with the smaller type. */
+ if ((off64_t) fl.l_start != fl64->l_start)
+ goto eoverflow;
+
+ fl.l_len = (off_t)fl64->l_len;
+ /* Check if we can represent the values with the smaller type. */
+ if ((off64_t) fl.l_len != fl64->l_len)
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+ fl.l_type = fl64->l_type;
+ fl.l_whence = fl64->l_whence;
+ fl.l_pid = fl64->l_pid;
+ assert (F_SETLK - F_SETLKW == F_SETLK64 - F_SETLKW64);
+ return INLINE_SYSCALL (fcntl, 3, fd, cmd + F_SETLK - F_SETLK64, &fl);
+ }
+ default:
+ return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+ }
+ return -1;
+#else
+ return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+#endif /* !__ASSUME_FCNTL64 */
+}
+#endif /* NO_CANCELLATION || !__ASSUME_FCNTL64 */
+
+
+#ifndef __fcntl_nocancel
+int
+__libc_fcntl (int fd, int cmd, ...)
+{
+ va_list ap;
+ void *arg;
+
+ va_start (ap, cmd);
+ arg = va_arg (ap, void *);
+ va_end (ap);
+
+#if __ASSUME_FCNTL64 > 0
+ if (SINGLE_THREAD_P || (cmd != F_SETLKW && cmd != F_SETLKW64))
+ return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+#else
+ if (SINGLE_THREAD_P || (cmd != F_SETLKW && cmd != F_SETLKW64))
+ return __fcntl_nocancel (fd, cmd, arg);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = __fcntl_nocancel (fd, cmd, arg);
+#endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+#endif
+libc_hidden_def (__libc_fcntl)
+
+weak_alias (__libc_fcntl, __fcntl)
+libc_hidden_weak (__fcntl)
+weak_alias (__libc_fcntl, fcntl)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/fxstat.c b/libc/sysdeps/unix/sysv/linux/i386/fxstat.c
new file mode 100644
index 000000000..281839f96
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/fxstat.c
@@ -0,0 +1,101 @@
+/* fxstat using old-style Unix fstat system call.
+ Copyright (C) 1991,1995-1998,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ho hum, if xstat == xstat64 we must get rid of the prototype or gcc
+ will complain since they don't strictly match. */
+#define __fxstat64 __fxstat64_disable
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#include <xstatconv.h>
+
+#ifdef __NR_stat64
+# if __ASSUME_STAT64_SYSCALL == 0
+/* The variable is shared between all wrappers around *stat64 calls. */
+extern int __have_no_stat64;
+# endif
+#endif
+
+/* Get information about the file FD in BUF. */
+int
+__fxstat (int vers, int fd, struct stat *buf)
+{
+#if __ASSUME_STAT64_SYSCALL == 0
+ struct kernel_stat kbuf;
+#endif
+ int result;
+
+ if (vers == _STAT_VER_KERNEL)
+ return INLINE_SYSCALL (fstat, 2, fd, CHECK_1 ((struct kernel_stat *) buf));
+
+#if __ASSUME_STAT64_SYSCALL > 0
+ {
+ struct stat64 buf64;
+
+ result = INLINE_SYSCALL (fstat64, 2, fd, __ptrvalue (&buf64));
+ if (result == 0)
+ result = __xstat32_conv (vers, &buf64, buf);
+ return result;
+ }
+#else
+
+# if defined __NR_stat64
+ /* To support 32 bit UIDs, we have to use stat64. The normal stat call only returns
+ 16 bit UIDs. */
+ if (! __have_no_stat64)
+ {
+ struct stat64 buf64;
+
+ result = INLINE_SYSCALL (fstat64, 2, fd, __ptrvalue (&buf64));
+
+ if (result == 0)
+ result = __xstat32_conv (vers, &buf64, buf);
+
+ if (result != -1 || errno != ENOSYS)
+ return result;
+
+ __have_no_stat64 = 1;
+ }
+# endif
+
+ result = INLINE_SYSCALL (fstat, 2, fd, __ptrvalue (&kbuf));
+ if (result == 0)
+ result = __xstat_conv (vers, &kbuf, buf);
+
+ return result;
+#endif /* __ASSUME_STAT64_SYSCALL */
+}
+
+hidden_def (__fxstat)
+weak_alias (__fxstat, _fxstat);
+#ifdef XSTAT_IS_XSTAT64
+#undef __fxstat64
+strong_alias (__fxstat, __fxstat64);
+hidden_ver (__fxstat, __fxstat64)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/fxstatat.c b/libc/sysdeps/unix/sysv/linux/i386/fxstatat.c
new file mode 100644
index 000000000..94f6e8118
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/fxstatat.c
@@ -0,0 +1,176 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ho hum, if fxstatat == fxstatat64 we must get rid of the prototype or gcc
+ will complain since they don't strictly match. */
+#define __fxstatat64 __fxstatat64_disable
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#include <xstatconv.h>
+
+#ifdef __NR_stat64
+# if __ASSUME_STAT64_SYSCALL == 0
+/* The variable is shared between all wrappers around *stat64 calls. */
+extern int __have_no_stat64;
+# endif
+#endif
+
+
+/* Get information about the file NAME relative to FD in ST. */
+int
+__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
+{
+ int result;
+ INTERNAL_SYSCALL_DECL (err);
+ struct stat64 st64;
+
+#ifdef __NR_fstatat64
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, &st64, flag);
+# ifndef __ASSUME_ATFCTS
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
+ && INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return __xstat32_conv (vers, &st64, st);
+ else
+ {
+ __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
+ return -1;
+ }
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ if (__builtin_expect (flag & ~AT_SYMLINK_NOFOLLOW, 0))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+# if __ASSUME_STAT64_SYSCALL == 0
+ struct kernel_stat kst;
+# endif
+ if (vers == _STAT_VER_KERNEL)
+ {
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
+ CHECK_1 ((struct kernel_stat *) st));
+ else
+ result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
+ CHECK_1 ((struct kernel_stat *) st));
+ goto out;
+ }
+
+# if __ASSUME_STAT64_SYSCALL > 0
+
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
+ __ptrvalue (&st64));
+ else
+ result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
+ __ptrvalue (&st64));
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return __xstat32_conv (vers, &st64, st);
+# else
+# if defined __NR_stat64
+ /* To support 32 bit UIDs, we have to use stat64. The normal stat
+ call only returns 16 bit UIDs. */
+ if (! __have_no_stat64)
+ {
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
+ __ptrvalue (&st64));
+ else
+ result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
+ __ptrvalue (&st64));
+
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ result = __xstat32_conv (vers, &st64, st);
+
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1)
+ || INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ goto out;
+
+ __have_no_stat64 = 1;
+ }
+# endif
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
+ __ptrvalue (&kst));
+ else
+ result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
+ __ptrvalue (&kst));
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return __xstat_conv (vers, &kst, st);
+# endif /* __ASSUME_STAT64_SYSCALL */
+
+ out:
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ {
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
+ result = -1;
+ }
+
+ return result;
+#endif
+}
+libc_hidden_def (__fxstatat)
+#ifdef XSTAT_IS_XSTAT64
+# undef __fxstatat64
+strong_alias (__fxstatat, __fxstatat64);
+libc_hidden_ver (__fxstatat, __fxstatat64)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/get_clockfreq.c b/libc/sysdeps/unix/sysv/linux/i386/get_clockfreq.c
new file mode 100644
index 000000000..3e2b18392
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/get_clockfreq.c
@@ -0,0 +1,91 @@
+/* Get frequency of the system processor. i386/Linux version.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <libc-internal.h>
+
+
+hp_timing_t
+__get_clockfreq (void)
+{
+ /* We read the information from the /proc filesystem. It contains at
+ least one line like
+ cpu MHz : 497.840237
+ or also
+ cpu MHz : 497.841
+ We search for this line and convert the number in an integer. */
+ static hp_timing_t result;
+ int fd;
+
+ /* If this function was called before, we know the result. */
+ if (result != 0)
+ return result;
+
+ fd = open ("/proc/cpuinfo", O_RDONLY);
+ if (__builtin_expect (fd != -1, 1))
+ {
+ /* XXX AFAIK the /proc filesystem can generate "files" only up
+ to a size of 4096 bytes. */
+ char buf[4096];
+ ssize_t n;
+
+ n = read (fd, buf, sizeof buf);
+ if (__builtin_expect (n, 1) > 0)
+ {
+ char *mhz = memmem (buf, n, "cpu MHz", 7);
+
+ if (__builtin_expect (mhz != NULL, 1))
+ {
+ char *endp = buf + n;
+ int seen_decpoint = 0;
+ int ndigits = 0;
+
+ /* Search for the beginning of the string. */
+ while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
+ ++mhz;
+
+ while (mhz < endp && *mhz != '\n')
+ {
+ if (*mhz >= '0' && *mhz <= '9')
+ {
+ result *= 10;
+ result += *mhz - '0';
+ if (seen_decpoint)
+ ++ndigits;
+ }
+ else if (*mhz == '.')
+ seen_decpoint = 1;
+
+ ++mhz;
+ }
+
+ /* Compensate for missing digits at the end. */
+ while (ndigits++ < 6)
+ result *= 10;
+ }
+ }
+
+ close (fd);
+ }
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/i386/getcontext.S b/libc/sysdeps/unix/sysv/linux/i386/getcontext.S
new file mode 100644
index 000000000..fe28f1e0e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/getcontext.S
@@ -0,0 +1,85 @@
+/* Save current context.
+ Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+
+ENTRY(__getcontext)
+ /* Load address of the context data structure. */
+ movl 4(%esp), %eax
+
+ /* Return value of getcontext. EAX is the only register whose
+ value is not preserved. */
+ movl $0, oEAX(%eax)
+
+ /* Save the 32-bit register values and the return address. */
+ movl %ecx, oECX(%eax)
+ movl %edx, oEDX(%eax)
+ movl %edi, oEDI(%eax)
+ movl %esi, oESI(%eax)
+ movl %ebp, oEBP(%eax)
+ movl (%esp), %ecx
+ movl %ecx, oEIP(%eax)
+ leal 4(%esp), %ecx /* Exclude the return address. */
+ movl %ecx, oESP(%eax)
+ movl %ebx, oEBX(%eax)
+
+ /* Save the FS segment register. We don't touch the GS register
+ since it is used for threads. */
+ xorl %edx, %edx
+ movw %fs, %dx
+ movl %edx, oFS(%eax)
+
+ /* We have separate floating-point register content memory on the
+ stack. We use the __fpregs_mem block in the context. Set the
+ links up correctly. */
+ leal oFPREGSMEM(%eax), %ecx
+ movl %ecx, oFPREGS(%eax)
+ /* Save the floating-point context. */
+ fnstenv (%ecx)
+ /* And load it right back since the processor changes the mask.
+ Intel thought this opcode to be used in interrupt handlers which
+ would block all exceptions. */
+ fldenv (%ecx)
+
+ /* Save the current signal mask. */
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebx, 0)
+ leal oSIGMASK(%eax), %edx
+ xorl %ecx, %ecx
+ movl $SIG_BLOCK, %ebx
+ movl $__NR_sigprocmask, %eax
+ ENTER_KERNEL
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ cmpl $-4095, %eax /* Check %eax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+
+ /* All done, return 0 for success. */
+ xorl %eax, %eax
+L(pseudo_end):
+ ret
+PSEUDO_END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/getdents64.c b/libc/sysdeps/unix/sysv/linux/i386/getdents64.c
new file mode 100644
index 000000000..e6fcf68ad
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/getdents64.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __GETDENTS __getdents64
+#define DIRENT_TYPE struct dirent64
+
+#include <sysdeps/unix/sysv/linux/getdents.c>
+
+#include <shlib-compat.h>
+
+#undef __READDIR
+#undef __GETDENTS
+#undef DIRENT_TYPE
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+#define __GETDENTS __old_getdents64
+#define DIRENT_TYPE struct __old_dirent64
+#define kernel_dirent old_kernel_dirent
+#define kernel_dirent64 old_kernel_dirent64
+
+#include <sysdeps/unix/sysv/linux/getdents.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/getegid.c b/libc/sysdeps/unix/sysv/linux/i386/getegid.c
new file mode 100644
index 000000000..31c10cc32
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/getegid.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 2000, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+
+#ifdef __NR_getegid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids attribute_hidden;
+# endif
+#endif /* __NR_getegid32 */
+
+gid_t
+__getegid (void)
+{
+ INTERNAL_SYSCALL_DECL (err);
+#if __ASSUME_32BITUIDS > 0
+ /* No error checking. */
+ return INTERNAL_SYSCALL (getegid32, err, 0);
+#else
+# ifdef __NR_getegid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+
+ result = INTERNAL_SYSCALL (getegid32, err, 0);
+ if (! INTERNAL_SYSCALL_ERROR_P (result, err)
+ || INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ return result;
+
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_getegid32 */
+
+ /* No error checking. */
+ return INTERNAL_SYSCALL (getegid, err, 0);
+#endif
+}
+
+weak_alias (__getegid, getegid)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/geteuid.c b/libc/sysdeps/unix/sysv/linux/i386/geteuid.c
new file mode 100644
index 000000000..53f52687a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/geteuid.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 2000, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+
+#ifdef __NR_geteuid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids attribute_hidden;
+# endif
+#endif /* __NR_geteuid32 */
+
+uid_t
+__geteuid (void)
+{
+ INTERNAL_SYSCALL_DECL (err);
+#if __ASSUME_32BITUIDS > 0
+ /* No error checking. */
+ return INTERNAL_SYSCALL (geteuid32, err, 0);
+#else
+# ifdef __NR_geteuid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+
+ result = INTERNAL_SYSCALL (geteuid32, err, 0);
+ if (! INTERNAL_SYSCALL_ERROR_P (result, err)
+ || INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ return result;
+
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_geteuid32 */
+
+ /* No error checking. */
+ return INTERNAL_SYSCALL (geteuid, err, 0);
+#endif
+}
+
+weak_alias (__geteuid, geteuid)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/getgid.c b/libc/sysdeps/unix/sysv/linux/i386/getgid.c
new file mode 100644
index 000000000..7a7e38d9c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/getgid.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 2000, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_getgid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids attribute_hidden;
+# endif
+#endif /* __NR_getgid32 */
+
+gid_t
+__getgid (void)
+{
+ INTERNAL_SYSCALL_DECL (err);
+#if __ASSUME_32BITUIDS > 0
+ /* No error checking. */
+ return INTERNAL_SYSCALL (getgid32, err, 0);
+#else
+# ifdef __NR_getgid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+
+ result = INTERNAL_SYSCALL (getgid32, err, 0);
+ if (! INTERNAL_SYSCALL_ERROR_P (result, err)
+ || INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ return result;
+
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_getgid32 */
+
+ /* No error checking. */
+ return INTERNAL_SYSCALL (getgid, err, 0);
+#endif
+}
+
+weak_alias (__getgid, getgid)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/getgroups.c b/libc/sysdeps/unix/sysv/linux/i386/getgroups.c
new file mode 100644
index 000000000..b7a0a4efd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/getgroups.c
@@ -0,0 +1,81 @@
+/* Copyright (C) 1997, 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+
+#ifdef __NR_getgroups32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids attribute_hidden;
+# endif
+#endif /* __NR_getgroups32 */
+
+/* For Linux we must convert the array of groups from the format that the
+ kernel returns. */
+int
+__getgroups (int n, gid_t *groups)
+{
+#if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (getgroups32, 2, n, CHECK_N (groups, n));
+#else
+ if (__builtin_expect (n, 1) < 0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ else
+ {
+ int i, ngids;
+ __kernel_gid_t kernel_groups[n = MIN (n, __sysconf (_SC_NGROUPS_MAX))];
+# ifdef __NR_getgroups32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+ int saved_errno = errno;
+
+ result = INLINE_SYSCALL (getgroups32, 2, n, CHECK_N (groups, n));
+ if (result != -1 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_getgroups32 */
+
+ ngids = INLINE_SYSCALL (getgroups, 2, n, CHECK_N (kernel_groups, n));
+ if (n != 0 && ngids > 0)
+ for (i = 0; i < ngids; i++)
+ (__ptrvalue (groups))[i] = kernel_groups[i];
+ return ngids;
+ }
+#endif
+}
+
+weak_alias (__getgroups, getgroups)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/getmsg.c b/libc/sysdeps/unix/sysv/linux/i386/getmsg.c
new file mode 100644
index 000000000..c0efd5636
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/getmsg.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1998, 1999, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <stropts.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_getpmsg
+int
+getmsg (fildes, ctlptr, dataptr, flagsp)
+ int fildes;
+ struct strbuf *ctlptr;
+ struct strbuf *dataptr;
+ int *flagsp;
+{
+ return INLINE_SYSCALL (getpmsg, 5, fildes, ctlptr, dataptr, NULL, flagsp);
+}
+#else
+# include <streams/getmsg.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/getresgid.c b/libc/sysdeps/unix/sysv/linux/i386/getresgid.c
new file mode 100644
index 000000000..393195619
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/getresgid.c
@@ -0,0 +1,85 @@
+/* Copyright (C) 1998,2000,2002,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <linux/posix_types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_getresgid
+
+# ifdef __NR_getresgid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+# endif /* __NR_getresgid32 */
+
+
+int
+__getresgid (gid_t *rgid, gid_t *egid, gid_t *sgid)
+{
+# if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (getresgid32, 3, CHECK_1 (rgid),
+ CHECK_1 (egid), CHECK_1 (sgid));
+# else
+ __kernel_gid_t k_rgid, k_egid, k_sgid;
+ int result;
+# ifdef __NR_getresgid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int r;
+ int saved_errno = errno;
+
+ r = INLINE_SYSCALL (getresgid32, 3, CHECK_1 (rgid),
+ CHECK_1 (egid), CHECK_1 (sgid));
+ if (r == 0 || errno != ENOSYS)
+ return r;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_getresgid32 */
+
+ result = INLINE_SYSCALL (getresgid, 3, __ptrvalue (&k_rgid),
+ __ptrvalue (&k_egid), __ptrvalue (&k_sgid));
+
+ if (result == 0)
+ {
+ *rgid = (gid_t) k_rgid;
+ *egid = (gid_t) k_egid;
+ *sgid = (gid_t) k_sgid;
+ }
+
+ return result;
+# endif
+}
+libc_hidden_def (__getresgid)
+weak_alias (__getresgid, getresgid)
+
+#else
+# include <posix/getresgid.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/getresuid.c b/libc/sysdeps/unix/sysv/linux/i386/getresuid.c
new file mode 100644
index 000000000..ddd25341b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/getresuid.c
@@ -0,0 +1,84 @@
+/* Copyright (C) 1998,2000,2002,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <linux/posix_types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_getresuid
+
+# ifdef __NR_getresuid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+# endif /* __NR_getresuid32 */
+
+int
+__getresuid (uid_t *ruid, uid_t *euid, uid_t *suid)
+{
+# if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (getresuid32, 3, CHECK_1 (ruid),
+ CHECK_1 (euid), CHECK_1 (suid));
+# else
+ __kernel_uid_t k_ruid, k_euid, k_suid;
+ int result;
+# ifdef __NR_getresuid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int r;
+ int saved_errno = errno;
+
+ r = INLINE_SYSCALL (getresuid32, 3, CHECK_1 (ruid),
+ CHECK_1 (euid), CHECK_1 (suid));
+ if (r == 0 || errno != ENOSYS)
+ return r;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_getresuid32 */
+
+ result = INLINE_SYSCALL (getresuid, 3, __ptrvalue (&k_ruid),
+ __ptrvalue (&k_euid), __ptrvalue (&k_suid));
+
+ if (result == 0)
+ {
+ *ruid = (uid_t) k_ruid;
+ *euid = (uid_t) k_euid;
+ *suid = (uid_t) k_suid;
+ }
+
+ return result;
+# endif
+}
+libc_hidden_def (__getresuid)
+weak_alias (__getresuid, getresuid)
+
+#else
+# include <posix/getresuid.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/getrlimit.c b/libc/sysdeps/unix/sysv/linux/i386/getrlimit.c
new file mode 100644
index 000000000..59951ac10
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/getrlimit.c
@@ -0,0 +1,82 @@
+/* Copyright (C) 1999, 2000, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/resource.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <shlib-compat.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+extern int __new_getrlimit (enum __rlimit_resource resource,
+ struct rlimit *__unbounded rlimits);
+
+
+/* Linux 2.3.25 introduced a new system call since the types used for
+ the limits are now unsigned. */
+#if defined __NR_ugetrlimit && !defined __ASSUME_NEW_GETRLIMIT_SYSCALL
+int __have_no_new_getrlimit;
+#endif
+
+int
+__new_getrlimit (enum __rlimit_resource resource, struct rlimit *rlimits)
+{
+#ifdef __ASSUME_NEW_GETRLIMIT_SYSCALL
+ return INLINE_SYSCALL (ugetrlimit, 2, resource, CHECK_1 (rlimits));
+#else
+ int result;
+
+# ifdef __NR_ugetrlimit
+ if (__have_no_new_getrlimit <= 0)
+ {
+ result = INLINE_SYSCALL (ugetrlimit, 2, resource, CHECK_1 (rlimits));
+
+ /* If the system call is available remember this fact and return. */
+ if (result != -1 || errno != ENOSYS)
+ {
+ __have_no_new_getrlimit = -1;
+ return result;
+ }
+
+ /* Remember that the system call is not available. */
+ __have_no_new_getrlimit = 1;
+ }
+# endif
+
+ /* Fall back to the old system call. */
+ result = INLINE_SYSCALL (getrlimit, 2, resource, CHECK_1 (rlimits));
+
+ if (result == -1)
+ return result;
+
+ /* We might have to correct the limits values. Since the old values
+ were signed the infinity value is too small. */
+ if (rlimits->rlim_cur == RLIM_INFINITY >> 1)
+ rlimits->rlim_cur = RLIM_INFINITY;
+ if (rlimits->rlim_max == RLIM_INFINITY >> 1)
+ rlimits->rlim_max = RLIM_INFINITY;
+
+ return result;
+#endif
+}
+
+weak_alias (__new_getrlimit, __getrlimit);
+versioned_symbol (libc, __new_getrlimit, getrlimit, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/i386/getrlimit64.c b/libc/sysdeps/unix/sysv/linux/i386/getrlimit64.c
new file mode 100644
index 000000000..2ff175393
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/getrlimit64.c
@@ -0,0 +1,25 @@
+/* Copyright (C) 1999, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define getrlimit64 __new_getrlimit64
+
+#include <resource/getrlimit64.c>
+
+#undef getrlimit64
+#include <shlib-compat.h>
+versioned_symbol (libc, __new_getrlimit64, getrlimit64, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/i386/getuid.c b/libc/sysdeps/unix/sysv/linux/i386/getuid.c
new file mode 100644
index 000000000..d7be0c3cd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/getuid.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 2000, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_getuid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. This is the definition.
+ -1 if libc does not know yet whether kernel has 32bit uids or not.
+ 0 if it does have them.
+ 1 if it does not have them. */
+int __libc_missing_32bit_uids attribute_hidden = -1;
+# endif
+#endif /* __NR_getuid32 */
+
+uid_t
+__getuid (void)
+{
+ INTERNAL_SYSCALL_DECL (err);
+#if __ASSUME_32BITUIDS > 0
+ /* No error checking. */
+ return INTERNAL_SYSCALL (getuid32, err, 0);
+#else
+# ifdef __NR_getuid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+
+ result = INTERNAL_SYSCALL (getuid32, err, 0);
+ if (! INTERNAL_SYSCALL_ERROR_P (result, err)
+ || INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ return result;
+
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_getuid32 */
+
+ /* No error checking. */
+ return INTERNAL_SYSCALL (getuid, err, 0);
+#endif
+}
+
+weak_alias (__getuid, getuid)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/glob64.c b/libc/sysdeps/unix/sysv/linux/i386/glob64.c
new file mode 100644
index 000000000..18b7f21ae
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/glob64.c
@@ -0,0 +1,54 @@
+#include <dirent.h>
+#include <glob.h>
+#include <sys/stat.h>
+
+#define dirent dirent64
+#define __readdir(dirp) __readdir64 (dirp)
+
+#define glob_t glob64_t
+#define glob(pattern, flags, errfunc, pglob) \
+ __glob64 (pattern, flags, errfunc, pglob)
+#define globfree(pglob) globfree64 (pglob)
+
+#undef stat
+#define stat stat64
+#undef __stat
+#define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
+
+#define NO_GLOB_PATTERN_P 1
+
+#define COMPILE_GLOB64 1
+
+#include <posix/glob.c>
+
+#include "shlib-compat.h"
+
+libc_hidden_def (globfree64)
+
+versioned_symbol (libc, __glob64, glob64, GLIBC_2_2);
+libc_hidden_ver (__glob64, glob64)
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+int __old_glob64 (__const char *__pattern, int __flags,
+ int (*__errfunc) (__const char *, int),
+ glob64_t *__pglob);
+
+#undef dirent
+#define dirent __old_dirent64
+#undef __readdir
+#define __readdir(dirp) __old_readdir64 (dirp)
+#undef glob
+#define glob(pattern, flags, errfunc, pglob) \
+ __old_glob64 (pattern, flags, errfunc, pglob)
+#define glob_in_dir __old_glob_in_dir
+#define GLOB_ATTRIBUTE attribute_compat_text_section
+
+#define GLOB_ONLY_P 1
+
+#include <posix/glob.c>
+
+compat_symbol (libc, __old_glob64, glob64, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/lchown.c b/libc/sysdeps/unix/sysv/linux/i386/lchown.c
new file mode 100644
index 000000000..fbba0bf1d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/lchown.c
@@ -0,0 +1,74 @@
+/* Copyright (C) 2000,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+#ifdef __NR_lchown
+# ifdef __NR_lchown32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+# endif /* __NR_lchown32 */
+
+int
+__lchown (const char *file, uid_t owner, gid_t group)
+{
+# if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (lchown32, 3, CHECK_STRING (file), owner, group);
+# else
+# ifdef __NR_lchown32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+ int saved_errno = errno;
+
+ result = INLINE_SYSCALL (lchown32, 3, CHECK_STRING (file), owner, group);
+ if (result == 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_lchown32 */
+
+ if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
+ || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return INLINE_SYSCALL (lchown, 3, CHECK_STRING (file), owner, group);
+# endif
+}
+
+weak_alias (__lchown, lchown)
+
+#else
+# include <io/lchown.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/ldconfig.h b/libc/sysdeps/unix/sysv/linux/i386/ldconfig.h
new file mode 100644
index 000000000..671ec69be
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/ldconfig.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/ldconfig.h>
+
+#define SYSDEP_KNOWN_INTERPRETER_NAMES \
+ { "/lib/ld-linux.so.1", FLAG_ELF_LIBC5 },
+#define SYSDEP_KNOWN_LIBRARY_NAMES \
+ { "libc.so.5", FLAG_ELF_LIBC5 }, \
+ { "libm.so.5", FLAG_ELF_LIBC5 },
diff --git a/libc/sysdeps/unix/sysv/linux/i386/lockf64.c b/libc/sysdeps/unix/sysv/linux/i386/lockf64.c
new file mode 100644
index 000000000..8b568ff4a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/lockf64.c
@@ -0,0 +1,194 @@
+/* Copyright (C) 1994,1996,1997,1998,1999,2000,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sysdep.h>
+
+#include <kernel-features.h>
+
+/* lockf is a simplified interface to fcntl's locking facilities. */
+
+#ifdef __NR_fcntl64
+# if __ASSUME_FCNTL64 == 0
+/* This variable is shared with all files that check for fcntl64. The
+ declaration is in fcntl.c. */
+extern int __have_no_fcntl64;
+# endif
+#endif
+
+int
+lockf64 (int fd, int cmd, off64_t len64)
+{
+#if __ASSUME_FCNTL64 == 0
+ struct flock fl;
+ off_t len = (off_t) len64;
+#endif
+#ifdef __NR_fcntl64
+ struct flock64 fl64;
+ int cmd64;
+#endif
+
+#if __ASSUME_FCNTL64 == 0
+ memset ((char *) &fl, '\0', sizeof (fl));
+
+ /* lockf is always relative to the current file position. */
+ fl.l_whence = SEEK_CUR;
+ fl.l_start = 0;
+ fl.l_len = len;
+#endif
+#ifdef __NR_fcntl64
+# if __ASSUME_FCNTL64 == 0
+ if (!__have_no_fcntl64)
+ {
+# endif
+ memset ((char *) &fl64, '\0', sizeof (fl64));
+ fl64.l_whence = SEEK_CUR;
+ fl64.l_start = 0;
+ fl64.l_len = len64;
+# if __ASSUME_FCNTL64 == 0
+ }
+# endif
+#endif
+
+#if __ASSUME_FCNTL64 == 0 && !defined __NR_fcntl64
+ if (len64 != (off64_t) len)
+ {
+ /* We can't represent the length. */
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+#endif
+ switch (cmd)
+ {
+ case F_TEST:
+ /* Test the lock: return 0 if FD is unlocked or locked by this process;
+ return -1, set errno to EACCES, if another process holds the lock. */
+#if __ASSUME_FCNTL64 > 0
+ fl64.l_type = F_RDLCK;
+ if (INLINE_SYSCALL (fcntl64, 3, fd, F_GETLK64, &fl64) < 0)
+ return -1;
+ if (fl64.l_type == F_UNLCK || fl64.l_pid == __getpid ())
+ return 0;
+ __set_errno (EACCES);
+ return -1;
+#else
+# ifdef __NR_fcntl64
+ if (!__have_no_fcntl64)
+ {
+ int res;
+
+ fl64.l_type = F_RDLCK;
+ res = INLINE_SYSCALL (fcntl64, 3, fd, F_GETLK64, &fl64);
+ /* If errno == ENOSYS try the 32bit interface if len64 can
+ be represented with 32 bits. */
+
+ if (res == 0)
+ {
+ if (fl64.l_type == F_UNLCK || fl64.l_pid == __getpid ())
+ return 0;
+ __set_errno (EACCES);
+ return -1;
+ }
+ else if (errno == ENOSYS)
+ __have_no_fcntl64 = 1;
+ else
+ /* res < 0 && errno != ENOSYS. */
+ return -1;
+ if (len64 != (off64_t) len)
+ {
+ /* We can't represent the length. */
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+ }
+# endif
+ fl.l_type = F_RDLCK;
+ if (__fcntl (fd, F_GETLK, &fl) < 0)
+ return -1;
+ if (fl.l_type == F_UNLCK || fl.l_pid == __getpid ())
+ return 0;
+ __set_errno (EACCES);
+ return -1;
+#endif
+ case F_ULOCK:
+#if __ASSUME_FCNTL64 == 0
+ fl.l_type = F_UNLCK;
+ cmd = F_SETLK;
+#endif
+#ifdef __NR_fcntl64
+ fl64.l_type = F_UNLCK;
+ cmd64 = F_SETLK64;
+#endif
+ break;
+ case F_LOCK:
+#if __ASSUME_FCNTL64 == 0
+ fl.l_type = F_WRLCK;
+ cmd = F_SETLKW;
+#endif
+#ifdef __NR_fcntl64
+ fl64.l_type = F_WRLCK;
+ cmd64 = F_SETLKW64;
+#endif
+ break;
+ case F_TLOCK:
+#if __ASSUME_FCNTL64 == 0
+ fl.l_type = F_WRLCK;
+ cmd = F_SETLK;
+#endif
+#ifdef __NR_fcntl64
+ fl64.l_type = F_WRLCK;
+ cmd64 = F_SETLK64;
+#endif
+ break;
+
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+#if __ASSUME_FCNTL64 > 0
+ return INLINE_SYSCALL (fcntl64, 3, fd, cmd64, &fl64);
+#else
+# ifdef __NR_fcntl64
+
+ if (!__have_no_fcntl64)
+ {
+ int res = INLINE_SYSCALL (fcntl64, 3, fd, cmd64, &fl64);
+
+ /* If errno == ENOSYS try the 32bit interface if len64 can
+ be represented with 32 bits. */
+ if (res == 0 || errno != ENOSYS)
+ return res;
+
+ __have_no_fcntl64 = 1;
+
+ if (len64 != (off64_t) len)
+ {
+ /* We can't represent the length. */
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+ }
+# endif
+ return __fcntl (fd, cmd, &fl);
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/i386/lxstat.c b/libc/sysdeps/unix/sysv/linux/i386/lxstat.c
new file mode 100644
index 000000000..5cc96127b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/lxstat.c
@@ -0,0 +1,101 @@
+/* lxstat using old-style Unix lstat system call.
+ Copyright (C) 1991,1995,1996,1997,1998,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ho hum, if xstat == xstat64 we must get rid of the prototype or gcc
+ will complain since they don't strictly match. */
+#define __lxstat64 __lxstat64_disable
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#include <xstatconv.h>
+
+#ifdef __NR_stat64
+# if __ASSUME_STAT64_SYSCALL == 0
+/* The variable is shared between all wrappers around *stat64 calls. */
+extern int __have_no_stat64;
+# endif
+#endif
+
+
+/* Get information about the file NAME in BUF. */
+int
+__lxstat (int vers, const char *name, struct stat *buf)
+{
+#if __ASSUME_STAT64_SYSCALL == 0
+ struct kernel_stat kbuf;
+#endif
+ int result;
+
+ if (vers == _STAT_VER_KERNEL)
+ return INLINE_SYSCALL (lstat, 2, CHECK_STRING (name), CHECK_1 ((struct kernel_stat *) buf));
+
+#if __ASSUME_STAT64_SYSCALL > 0
+ {
+ struct stat64 buf64;
+
+ result = INLINE_SYSCALL (lstat64, 2, CHECK_STRING (name), __ptrvalue (&buf64));
+ if (result == 0)
+ result = __xstat32_conv (vers, &buf64, buf);
+ return result;
+ }
+#else
+
+# if defined __NR_stat64
+ /* To support 32 bit UIDs, we have to use stat64. The normal stat call only returns
+ 16 bit UIDs. */
+ if (! __have_no_stat64)
+ {
+ struct stat64 buf64;
+ result = INLINE_SYSCALL (lstat64, 2, CHECK_STRING (name), __ptrvalue (&buf64));
+
+ if (result == 0)
+ result = __xstat32_conv (vers, &buf64, buf);
+
+ if (result != -1 || errno != ENOSYS)
+ return result;
+
+ __have_no_stat64 = 1;
+ }
+# endif
+
+ result = INLINE_SYSCALL (lstat, 2, CHECK_STRING (name), __ptrvalue (&kbuf));
+ if (result == 0)
+ result = __xstat_conv (vers, &kbuf, buf);
+
+ return result;
+#endif
+}
+
+hidden_def (__lxstat)
+weak_alias (__lxstat, _lxstat);
+#ifdef XSTAT_IS_XSTAT64
+#undef __lxstat64
+strong_alias (__lxstat, __lxstat64);
+hidden_ver (__lxstat, __lxstat64)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/makecontext.S b/libc/sysdeps/unix/sysv/linux/i386/makecontext.S
new file mode 100644
index 000000000..12ba4e2d6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/makecontext.S
@@ -0,0 +1,117 @@
+/* Create new context.
+ Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+
+ENTRY(__makecontext)
+ movl 4(%esp), %eax
+
+ /* Load the address of the function we are supposed to run. */
+ movl 8(%esp), %ecx
+
+ /* Compute the address of the stack. The information comes from
+ to us_stack element. */
+ movl oSS_SP(%eax), %edx
+ movl %ecx, oEIP(%eax)
+ addl oSS_SIZE(%eax), %edx
+
+ /* Put the next context on the new stack (from the uc_link
+ element). */
+ movl oLINK(%eax), %ecx
+ movl %ecx, -4(%edx)
+
+ /* Remember the number of parameters for the exit handler since
+ it has to remove them. We store the number in the EBX register
+ which the function we will call must preserve. */
+ movl 12(%esp), %ecx
+ movl %ecx, oEBX(%eax)
+
+ /* Make room on the new stack for the parameters. */
+ negl %ecx
+ leal -8(%edx,%ecx,4), %edx
+ negl %ecx
+ /* Store the future stack pointer. */
+ movl %edx, oESP(%eax)
+
+ /* Copy all the parameters. */
+ jecxz 2f
+1: movl 12(%esp,%ecx,4), %eax
+ movl %eax, (%edx,%ecx,4)
+ decl %ecx
+ jnz 1b
+2:
+
+ /* If the function we call returns we must continue with the
+ context which is given in the uc_link element. To do this
+ set the return address for the function the user provides
+ to a little bit of helper code which does the magic (see
+ below). */
+#ifdef PIC
+ call 1f
+ cfi_adjust_cfa_offset (4)
+1: popl %ecx
+ cfi_adjust_cfa_offset (-4)
+ addl $L(exitcode)-1b, %ecx
+ movl %ecx, (%edx)
+#else
+ movl $L(exitcode), (%edx)
+#endif
+ /* 'makecontext' returns no value. */
+ ret
+
+ /* This is the helper code which gets called if a function which
+ is registered with 'makecontext' returns. In this case we
+ have to install the context listed in the uc_link element of
+ the context 'makecontext' manipulated at the time of the
+ 'makecontext' call. If the pointer is NULL the process must
+ terminate. */
+ cfi_endproc
+L(exitcode):
+ /* This removes the parameters passed to the function given to
+ 'makecontext' from the stack. EBX contains the number of
+ parameters (see above). */
+ leal (%esp,%ebx,4), %esp
+
+#ifdef PIC
+ call 1f
+1: popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+#endif
+ popl %eax /* This is the next context. */
+ testl %eax, %eax
+ je 2f /* If it is zero exit. */
+
+ pushl %eax
+ call JUMPTARGET(__setcontext)
+ /* If this returns (which can happen if the syscall fails) we'll
+ exit the program with the return error value (-1). */
+
+2: pushl %eax
+ call HIDDEN_JUMPTARGET(exit)
+ /* The 'exit' call should never return. In case it does cause
+ the process to terminate. */
+ hlt
+ cfi_startproc
+END(__makecontext)
+
+weak_alias (__makecontext, makecontext)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/mmap.S b/libc/sysdeps/unix/sysv/linux/i386/mmap.S
new file mode 100644
index 000000000..a1481feeb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/mmap.S
@@ -0,0 +1,107 @@
+/* Copyright (C) 1995,96,97,98,99,2000,2002,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include <kernel-features.h>
+
+#define EINVAL 22
+
+ .text
+
+ENTRY (__mmap)
+
+/* I don't think it is worthwhile trying to use mmap2 whenever it
+ is available. Only use it when we are sure the syscall exists. */
+#ifdef __ASSUME_MMAP2_SYSCALL
+
+ /* Save registers. */
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+
+ movl 20(%esp), %ebx
+ cfi_rel_offset (ebx, 8)
+ movl 24(%esp), %ecx
+ movl 28(%esp), %edx
+ movl 32(%esp), %esi
+ cfi_rel_offset (esi, 4)
+ movl 36(%esp), %edi
+ cfi_rel_offset (edi, 0)
+ movl 40(%esp), %ebp
+ cfi_rel_offset (ebp, 12)
+ testl $0xfff, %ebp
+ movl $-EINVAL, %eax
+ jne L(skip)
+ shrl $12, %ebp /* mmap2 takes the offset in pages. */
+
+ movl $SYS_ify(mmap2), %eax /* System call number in %eax. */
+
+ /* Do the system call trap. */
+ ENTER_KERNEL
+L(skip):
+ /* Restore registers. */
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+
+#else
+
+ /* Save registers. */
+ movl %ebx, %edx
+ cfi_register (ebx, edx)
+
+ movl $SYS_ify(mmap), %eax /* System call number in %eax. */
+
+ lea 4(%esp), %ebx /* Address of args is 1st arg. */
+
+ /* Do the system call trap. */
+ int $0x80
+
+ /* Restore registers. */
+ movl %edx, %ebx
+ cfi_restore (ebx)
+
+#endif
+
+ /* If 0 > %eax > -4096 there was an error. */
+ cmpl $-4096, %eax
+ ja SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+L(pseudo_end):
+ ret
+
+PSEUDO_END (__mmap)
+
+weak_alias (__mmap, mmap)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/mmap64.S b/libc/sysdeps/unix/sysv/linux/i386/mmap64.S
new file mode 100644
index 000000000..f53e6e8c6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/mmap64.S
@@ -0,0 +1,170 @@
+/* Copyright (C) 1995,96,97,98,99,2000,2002,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+#include <kernel-features.h>
+
+#define EINVAL 22
+#define ENOSYS 38
+
+#define SVRSP 16 /* saved register space */
+#define PARMS LINKAGE+SVRSP /* space for 4 saved regs */
+#define ADDR PARMS
+#define LEN ADDR+PTR_SIZE
+#define PROT LEN+4
+#define FLAGS PROT+4
+#define FD FLAGS+4
+#define OFFLO FD+4
+#define OFFHI OFFLO+4
+
+ .text
+ENTRY (BP_SYM (__mmap64))
+
+#ifdef __NR_mmap2
+
+ /* Save registers. */
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+
+ movl OFFLO(%esp), %edx
+ movl OFFHI(%esp), %ecx
+ testl $0xfff, %edx
+ jne L(einval)
+ shrdl $12, %ecx, %edx /* mmap2 takes the offset in pages. */
+ shrl $12, %ecx
+ jne L(einval)
+ movl %edx, %ebp
+ cfi_rel_offset (ebp, 12)
+
+ movl ADDR(%esp), %ebx
+ cfi_rel_offset (ebx, 8)
+ movl LEN(%esp), %ecx
+ movl PROT(%esp), %edx
+ movl FLAGS(%esp), %esi
+ cfi_rel_offset (esi, 4)
+ movl FD(%esp), %edi
+ cfi_rel_offset (edi, 0)
+
+ movl $SYS_ify(mmap2), %eax /* System call number in %eax. */
+
+ /* Do the system call trap. */
+L(do_syscall):
+ ENTER_KERNEL
+
+ /* Restore registers. */
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+
+#ifndef __ASSUME_MMAP2_SYSCALL
+2:
+ cmp $-ENOSYS, %eax
+ je 3f
+#endif
+
+ /* If 0 > %eax > -4096 there was an error. */
+ cmpl $-4096, %eax
+ ja SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+L(pseudo_end):
+ ret
+
+ cfi_adjust_cfa_offset (16)
+ cfi_rel_offset (ebp, 12)
+ cfi_rel_offset (ebx, 8)
+ cfi_rel_offset (esi, 4)
+ cfi_rel_offset (edi, 0)
+ /* This means the offset value is too large. */
+L(einval):
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ movl $-EINVAL, %eax
+ jmp SYSCALL_ERROR_LABEL
+#endif
+
+#if !defined __ASSUME_MMAP2_SYSCALL || !defined __NR_mmap2
+3:
+ /* Save registers. */
+ movl %ebx, %edx
+ cfi_register (ebx, edx)
+
+ cmpl $0, OFFHI-SVRSP(%esp)
+ jne L(einval2)
+
+ movl $SYS_ify(mmap), %eax /* System call number in %eax. */
+
+ lea ADDR-SVRSP(%esp), %ebx /* Address of args is 1st arg. */
+
+ /* Do the system call trap. */
+ ENTER_KERNEL
+
+ /* Restore registers. */
+ movl %edx, %ebx
+ cfi_restore (ebx)
+
+ /* If 0 > %eax > -4096 there was an error. */
+ cmpl $-4096, %eax
+ ja SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+#ifndef __NR_mmap2
+L(pseudo_end):
+#endif
+ ret
+
+ cfi_register (ebx, edx)
+L(einval2):
+ movl %edx, %ebx
+ cfi_restore (ebx)
+ movl $-EINVAL, %eax
+ jmp SYSCALL_ERROR_LABEL
+#endif
+
+PSEUDO_END (BP_SYM (__mmap64))
+
+weak_alias (BP_SYM (__mmap64), BP_SYM (mmap64))
diff --git a/libc/sysdeps/unix/sysv/linux/i386/msgctl.c b/libc/sysdeps/unix/sysv/linux/i386/msgctl.c
new file mode 100644
index 000000000..afecc49dd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/msgctl.c
@@ -0,0 +1,159 @@
+/* Copyright (C) 1995,1997,1998,2000,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/msg.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+#include <shlib-compat.h>
+
+struct __old_msqid_ds
+{
+ struct __old_ipc_perm msg_perm; /* structure describing operation permission */
+ struct msg *__unbounded __msg_first; /* pointer to first message on queue */
+ struct msg *__unbounded __msg_last; /* pointer to last message on queue */
+ __time_t msg_stime; /* time of last msgsnd command */
+ __time_t msg_rtime; /* time of last msgrcv command */
+ __time_t msg_ctime; /* time of last change */
+ struct wait_queue *__unbounded __wwait; /* ??? */
+ struct wait_queue *__unbounded __rwait; /* ??? */
+ unsigned short int __msg_cbytes; /* current number of bytes on queue */
+ unsigned short int msg_qnum; /* number of messages currently on queue */
+ unsigned short int msg_qbytes; /* max number of bytes allowed on queue */
+ __ipc_pid_t msg_lspid; /* pid of last msgsnd() */
+ __ipc_pid_t msg_lrpid; /* pid of last msgrcv() */
+};
+
+/* Allows to control internal state and destruction of message queue
+ objects. */
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int __old_msgctl (int, int, struct __old_msqid_ds *);
+#endif
+int __new_msgctl (int, int, struct msqid_ds *);
+
+#ifdef __NR_getuid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int
+attribute_compat_text_section
+__old_msgctl (int msqid, int cmd, struct __old_msqid_ds *buf)
+{
+ return INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
+ msqid, cmd, 0, CHECK_1 (buf));
+}
+compat_symbol (libc, __old_msgctl, msgctl, GLIBC_2_0);
+#endif
+
+int
+__new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
+{
+#if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
+ msqid, cmd | __IPC_64, 0, CHECK_1 (buf));
+#else
+ switch (cmd) {
+ case MSG_STAT:
+ case IPC_STAT:
+ case IPC_SET:
+ break;
+ default:
+ return INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
+ msqid, cmd, 0, CHECK_1 (buf));
+ }
+
+ {
+ int result;
+ struct __old_msqid_ds old;
+
+#ifdef __NR_getuid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ if (__libc_missing_32bit_uids < 0)
+ {
+ int save_errno = errno;
+
+ /* Test presence of new IPC by testing for getuid32 syscall. */
+ result = INLINE_SYSCALL (getuid32, 0);
+ if (result == -1 && errno == ENOSYS)
+ __libc_missing_32bit_uids = 1;
+ else
+ __libc_missing_32bit_uids = 0;
+ __set_errno(save_errno);
+ }
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
+ msqid, cmd | __IPC_64, 0, CHECK_1 (buf));
+ return result;
+ }
+ }
+#endif
+ if (cmd == IPC_SET)
+ {
+ old.msg_perm.uid = buf->msg_perm.uid;
+ old.msg_perm.gid = buf->msg_perm.gid;
+ old.msg_perm.mode = buf->msg_perm.mode;
+ old.msg_qbytes = buf->msg_qbytes;
+ if (old.msg_perm.uid != buf->msg_perm.uid ||
+ old.msg_perm.gid != buf->msg_perm.gid ||
+ old.msg_qbytes != buf->msg_qbytes)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ }
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
+ msqid, cmd, 0, __ptrvalue (&old));
+ if (result != -1 && cmd != IPC_SET)
+ {
+ memset(buf, 0, sizeof(*buf));
+ buf->msg_perm.__key = old.msg_perm.__key;
+ buf->msg_perm.uid = old.msg_perm.uid;
+ buf->msg_perm.gid = old.msg_perm.gid;
+ buf->msg_perm.cuid = old.msg_perm.cuid;
+ buf->msg_perm.cgid = old.msg_perm.cgid;
+ buf->msg_perm.mode = old.msg_perm.mode;
+ buf->msg_perm.__seq = old.msg_perm.__seq;
+ buf->msg_stime = old.msg_stime;
+ buf->msg_rtime = old.msg_rtime;
+ buf->msg_ctime = old.msg_ctime;
+ buf->__msg_cbytes = old.__msg_cbytes;
+ buf->msg_qnum = old.msg_qnum;
+ buf->msg_qbytes = old.msg_qbytes;
+ buf->msg_lspid = old.msg_lspid;
+ buf->msg_lrpid = old.msg_lrpid;
+ }
+ return result;
+ }
+#endif
+}
+
+versioned_symbol (libc, __new_msgctl, msgctl, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/i386/olddirent.h b/libc/sysdeps/unix/sysv/linux/i386/olddirent.h
new file mode 100644
index 000000000..f9a79b235
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/olddirent.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __OLD_DIRENT_H
+#define __OLD_DIRENT_H 1
+
+#include <dirent.h>
+
+struct __old_dirent64
+ {
+ __ino_t d_ino;
+ __off64_t d_off;
+ unsigned short int d_reclen;
+ unsigned char d_type;
+ char d_name[256]; /* We must not include limits.h! */
+ };
+
+/* Now define the internal interfaces. */
+extern struct __old_dirent64 *__old_readdir64 (DIR *__dirp);
+extern int __old_readdir64_r (DIR *__dirp, struct __old_dirent64 *__entry,
+ struct __old_dirent64 **__result);
+extern __ssize_t __old_getdents64 (int __fd, char *__buf, size_t __nbytes)
+ internal_function;
+int __old_scandir64 (__const char * __dir,
+ struct __old_dirent64 *** __namelist,
+ int (*__selector) (__const struct __old_dirent64 *),
+ int (*__cmp) (__const void *, __const void *));
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c b/libc/sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c
new file mode 100644
index 000000000..3947e5988
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1991, 1995-1999, 2000, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This is a compatibility file. If we don't build the libc with
+ versioning don't compile this file. */
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <errno.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+
+extern int __new_getrlimit (enum __rlimit_resource, struct rlimit *);
+extern int __old_getrlimit64 (enum __rlimit_resource resource,
+ struct rlimit64 *rlimits);
+
+
+/* Put the soft and hard limits for RESOURCE in *RLIMITS.
+ Returns 0 if successful, -1 if not (and sets errno). */
+int
+attribute_compat_text_section
+__old_getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits)
+{
+ struct rlimit rlimits32;
+
+ if (__new_getrlimit (resource, &rlimits32) < 0)
+ return -1;
+
+ if (rlimits32.rlim_cur == RLIM_INFINITY)
+ rlimits->rlim_cur = RLIM64_INFINITY >> 1;
+ else
+ rlimits->rlim_cur = rlimits32.rlim_cur;
+ if (rlimits32.rlim_max == RLIM_INFINITY)
+ rlimits->rlim_max = RLIM64_INFINITY >> 1;
+ else
+ rlimits->rlim_max = rlimits32.rlim_max;
+
+ return 0;
+}
+
+compat_symbol (libc, __old_getrlimit64, getrlimit64, GLIBC_2_1);
+
+#endif /* SHLIB_COMPAT */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/posix_fadvise64.S b/libc/sysdeps/unix/sysv/linux/i386/posix_fadvise64.S
new file mode 100644
index 000000000..092a3bfb9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/posix_fadvise64.S
@@ -0,0 +1,162 @@
+/* Copyright (C) 1995-2000,2002,2003,2004,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+#include <kernel-features.h>
+
+#define EINVAL 22
+#define ENOSYS 38
+#define EOVERFLOW 75
+
+#define SVRSP 16 /* saved register space */
+#define PARMS LINKAGE+SVRSP /* space for 4 saved regs */
+#define FD PARMS
+#define OFFLO FD+4
+#define OFFHI OFFLO+4
+#define LENLO OFFHI+4
+#define LENHI LENLO+4
+#define FLAGS LENHI+4
+
+ .text
+ENTRY (BP_SYM (__posix_fadvise64_l64))
+
+#ifdef __NR_fadvise64_64
+
+ /* Save registers. */
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+
+ movl FD(%esp), %ebx
+ cfi_rel_offset (ebx, 8)
+ movl OFFLO(%esp), %ecx
+ movl OFFHI(%esp), %edx
+ movl LENLO(%esp), %esi
+ cfi_rel_offset (esi, 4)
+ movl LENHI(%esp), %edi
+ cfi_rel_offset (edi, 0)
+ movl FLAGS(%esp), %ebp
+ cfi_rel_offset (ebp, 12)
+
+ movl $SYS_ify(fadvise64_64), %eax
+ ENTER_KERNEL
+
+ /* Restore registers. */
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+
+#ifndef __ASSUME_FADVISE64_64_SYSCALL
+ cmpl $-ENOSYS, %eax
+ je 1f
+#endif
+
+ /* The function returns zero, or the error number. So all we
+ have to do is negate the value passed back from the kernel. */
+ /* If 0 > %eax > -4096 there was an error. */
+ negl %eax
+
+ /* Successful; return the syscall's value. */
+ ret
+#endif
+
+#if defined __NR_fadvise64 \
+ && (!defined __ASSUME_FADVISE64_64_SYSCALL || !defined __NR_fadvise64_64)
+1: /* Save registers. */
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+
+ /* Overflow check. */
+ cmpl $0, LENHI(%esp)
+ movl $-EOVERFLOW, %eax
+ jne L(overflow)
+
+ movl FD(%esp), %ebx
+ cfi_rel_offset (ebx, 8)
+ movl OFFLO(%esp), %ecx
+ movl OFFHI(%esp), %edx
+ movl LENLO(%esp), %esi
+ cfi_rel_offset (esi, 4)
+ movl FLAGS(%esp), %edi
+ cfi_rel_offset (edi, 0)
+
+ movl $SYS_ify(fadvise64), %eax
+ ENTER_KERNEL
+
+ /* Restore registers. */
+L(overflow):
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+
+ /* If 0 > %eax > -4096 there was an error. */
+ negl %eax
+
+ /* Successful; return the syscall's value. */
+ ret
+#else
+ movl $ENOSYS, %eax
+ ret
+#endif
+
+END (BP_SYM (__posix_fadvise64_l64))
+
+#ifdef __NR_fadvise64
+ .section .text.compat, "ax"
+ENTRY (__posix_fadvise64_l32)
+ DO_CALL (fadvise64, 5)
+ negl %eax
+ ret
+PSEUDO_END_ERRVAL (__posix_fadvise64_l32)
+#else
+ENTRY (BP_SYM (__posix_fadvise64_l32))
+ movl $ENOSYS, %eax
+ ret
+END (BP_SYM (__posix_fadvise64_l32))
+#endif
+
+default_symbol_version (__posix_fadvise64_l64, posix_fadvise64, GLIBC_2.3.3)
+symbol_version (__posix_fadvise64_l32, posix_fadvise64, GLIBC_2.2)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/profil-counter.h b/libc/sysdeps/unix/sysv/linux/i386/profil-counter.h
new file mode 100644
index 000000000..d592a7bd6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/profil-counter.h
@@ -0,0 +1,32 @@
+/* Low-level statistical profiling support function. Linux/i386 version.
+ Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+#include <sigcontextinfo.h>
+
+static void
+profil_counter (int signo, const SIGCONTEXT scp)
+{
+ profil_count ((void *) GET_PC (scp));
+
+ /* This is a hack to prevent the compiler from implementing the
+ above function call as a sibcall. The sibcall would overwrite
+ the signal context. */
+ asm volatile ("");
+}
diff --git a/libc/sysdeps/unix/sysv/linux/i386/pselect.c b/libc/sysdeps/unix/sysv/linux/i386/pselect.c
new file mode 100644
index 000000000..264660878
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/pselect.c
@@ -0,0 +1,18 @@
+#include <sys/select.h>
+
+extern int __call_pselect6 (int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, const struct timespec *timeout,
+ void *data) attribute_hidden;
+
+
+#define CALL_PSELECT6(nfds, readfds, writefds, exceptfds, timeout, data) \
+ ({ int r = __call_pselect6 (nfds, readfds, writefds, exceptfds, timeout, \
+ data); \
+ if (r < 0 && r > -4096) \
+ { \
+ __set_errno (-r); \
+ r = -1; \
+ } \
+ r; })
+
+#include "../pselect.c"
diff --git a/libc/sysdeps/unix/sysv/linux/i386/putmsg.c b/libc/sysdeps/unix/sysv/linux/i386/putmsg.c
new file mode 100644
index 000000000..04fd159b7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/putmsg.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1998, 1999, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <stropts.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_putpmsg
+int
+putmsg (fildes, ctlptr, dataptr, flags)
+ int fildes;
+ const struct strbuf *ctlptr;
+ const struct strbuf *dataptr;
+ int flags;
+{
+ return INLINE_SYSCALL (putpmsg, 5, fildes, ctlptr, dataptr, -1, flags);
+}
+#else
+# include <streams/putmsg.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/readdir64.c b/libc/sysdeps/unix/sysv/linux/i386/readdir64.c
new file mode 100644
index 000000000..8d3908869
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/readdir64.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __READDIR __readdir64
+#define __GETDENTS __getdents64
+#define DIRENT_TYPE struct dirent64
+
+#include <sysdeps/unix/readdir.c>
+
+#include <shlib-compat.h>
+
+#undef __READDIR
+#undef __GETDENTS
+#undef DIRENT_TYPE
+
+versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+#define __READDIR attribute_compat_text_section __old_readdir64
+#define __GETDENTS __old_getdents64
+#define DIRENT_TYPE struct __old_dirent64
+
+#include <sysdeps/unix/readdir.c>
+
+compat_symbol (libc, __old_readdir64, readdir64, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/readdir64_r.c b/libc/sysdeps/unix/sysv/linux/i386/readdir64_r.c
new file mode 100644
index 000000000..c6da57b75
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/readdir64_r.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __READDIR_R __readdir64_r
+#define __GETDENTS __getdents64
+#define DIRENT_TYPE struct dirent64
+
+#include <sysdeps/unix/readdir_r.c>
+
+#undef __READDIR_R
+#undef __GETDENTS
+#undef DIRENT_TYPE
+
+#include <shlib-compat.h>
+
+versioned_symbol (libc, __readdir64_r, readdir64_r, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+#define __READDIR_R attribute_compat_text_section __old_readdir64_r
+#define __GETDENTS __old_getdents64
+#define DIRENT_TYPE struct __old_dirent64
+
+#include <sysdeps/unix/readdir_r.c>
+
+compat_symbol (libc, __old_readdir64_r, readdir64_r, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/readelflib.c b/libc/sysdeps/unix/sysv/linux/i386/readelflib.c
new file mode 100644
index 000000000..a6374e61d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/readelflib.c
@@ -0,0 +1,82 @@
+/* Copyright (C) 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
+ Jakub Jelinek <jakub@redhat.com>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+int process_elf32_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+int process_elf64_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+
+/* Returns 0 if everything is ok, != 0 in case of error. */
+int
+process_elf_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname, void *file_contents,
+ size_t file_length)
+{
+ ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
+ int ret;
+
+ if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+ return process_elf32_file (file_name, lib, flag, osversion, soname,
+ file_contents, file_length);
+ else
+ {
+ switch (elf_header->e_machine)
+ {
+ case EM_IA_64:
+ case EM_X86_64:
+ break;
+ default:
+ error (0, 0, _("%s is for unknown machine %d.\n"),
+ file_name, elf_header->e_machine);
+ return 1;
+ }
+
+ ret = process_elf64_file (file_name, lib, flag, osversion, soname,
+ file_contents, file_length);
+ /* IA64/X86-64 64bit libraries are always libc.so.6+. */
+ if (!ret)
+ switch (elf_header->e_machine)
+ {
+ case EM_IA_64:
+ *flag = FLAG_IA64_LIB64|FLAG_ELF_LIBC6;
+ break;
+ case EM_X86_64:
+ *flag = FLAG_X8664_LIB64|FLAG_ELF_LIBC6;
+ break;
+ }
+
+ return ret;
+ }
+}
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf32_file
+#define __ELF_NATIVE_CLASS 32
+#include "elf/readelflib.c"
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf64_file
+#define __ELF_NATIVE_CLASS 64
+#include "elf/readelflib.c"
diff --git a/libc/sysdeps/unix/sysv/linux/i386/register-dump.h b/libc/sysdeps/unix/sysv/linux/i386/register-dump.h
new file mode 100644
index 000000000..05f295ecb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/register-dump.h
@@ -0,0 +1,256 @@
+/* Dump registers.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/uio.h>
+#include <stdio-common/_itoa.h>
+
+/* We will print the register dump in this format:
+
+ EAX: XXXXXXXX EBX: XXXXXXXX ECX: XXXXXXXX EDX: XXXXXXXX
+ ESI: XXXXXXXX EDI: XXXXXXXX EBP: XXXXXXXX ESP: XXXXXXXX
+
+ EIP: XXXXXXXX EFLAGS: XXXXXXXX
+
+ CS: XXXX DS: XXXX ES: XXXX FS: XXXX GS: XXXX SS: XXXX
+
+ Trap: XXXXXXXX Error: XXXXXXXX OldMask: XXXXXXXX
+ ESP/SIGNAL: XXXXXXXX CR2: XXXXXXXX
+
+ FPUCW: XXXXXXXX FPUSW: XXXXXXXX TAG: XXXXXXXX
+ IPOFF: XXXXXXXX CSSEL: XXXX DATAOFF: XXXXXXXX DATASEL: XXXX
+
+ ST(0) XXXX XXXXXXXXXXXXXXXX ST(1) XXXX XXXXXXXXXXXXXXXX
+ ST(2) XXXX XXXXXXXXXXXXXXXX ST(3) XXXX XXXXXXXXXXXXXXXX
+ ST(4) XXXX XXXXXXXXXXXXXXXX ST(5) XXXX XXXXXXXXXXXXXXXX
+ ST(6) XXXX XXXXXXXXXXXXXXXX ST(7) XXXX XXXXXXXXXXXXXXXX
+
+ */
+
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
+{
+ char *cp = _itoa_word (value, buf + len, 16, 0);
+ while (cp > buf)
+ *--cp = '0';
+}
+
+static void
+register_dump (int fd, struct sigcontext *ctx)
+{
+ char regs[21][8];
+ char fpregs[31][8];
+ struct iovec iov[97];
+ size_t nr = 0;
+
+#define ADD_STRING(str) \
+ iov[nr].iov_base = (char *) str; \
+ iov[nr].iov_len = strlen (str); \
+ ++nr
+#define ADD_MEM(str, len) \
+ iov[nr].iov_base = str; \
+ iov[nr].iov_len = len; \
+ ++nr
+
+ /* Generate strings of register contents. */
+ hexvalue (ctx->eax, regs[0], 8);
+ hexvalue (ctx->ebx, regs[1], 8);
+ hexvalue (ctx->ecx, regs[2], 8);
+ hexvalue (ctx->edx, regs[3], 8);
+ hexvalue (ctx->esi, regs[4], 8);
+ hexvalue (ctx->edi, regs[5], 8);
+ hexvalue (ctx->ebp, regs[6], 8);
+ hexvalue (ctx->esp, regs[7], 8);
+ hexvalue (ctx->eip, regs[8], 8);
+ hexvalue (ctx->eflags, regs[9], 8);
+ hexvalue (ctx->cs, regs[10], 4);
+ hexvalue (ctx->ds, regs[11], 4);
+ hexvalue (ctx->es, regs[12], 4);
+ hexvalue (ctx->fs, regs[13], 4);
+ hexvalue (ctx->gs, regs[14], 4);
+ hexvalue (ctx->ss, regs[15], 4);
+ hexvalue (ctx->trapno, regs[16], 8);
+ hexvalue (ctx->err, regs[17], 8);
+ hexvalue (ctx->oldmask, regs[18], 8);
+ hexvalue (ctx->esp_at_signal, regs[19], 8);
+ hexvalue (ctx->cr2, regs[20], 8);
+
+ /* Generate the output. */
+ ADD_STRING ("Register dump:\n\n EAX: ");
+ ADD_MEM (regs[0], 8);
+ ADD_STRING (" EBX: ");
+ ADD_MEM (regs[1], 8);
+ ADD_STRING (" ECX: ");
+ ADD_MEM (regs[2], 8);
+ ADD_STRING (" EDX: ");
+ ADD_MEM (regs[3], 8);
+ ADD_STRING ("\n ESI: ");
+ ADD_MEM (regs[4], 8);
+ ADD_STRING (" EDI: ");
+ ADD_MEM (regs[5], 8);
+ ADD_STRING (" EBP: ");
+ ADD_MEM (regs[6], 8);
+ ADD_STRING (" ESP: ");
+ ADD_MEM (regs[7], 8);
+ ADD_STRING ("\n\n EIP: ");
+ ADD_MEM (regs[8], 8);
+ ADD_STRING (" EFLAGS: ");
+ ADD_MEM (regs[9], 8);
+ ADD_STRING ("\n\n CS: ");
+ ADD_MEM (regs[10], 4);
+ ADD_STRING (" DS: ");
+ ADD_MEM (regs[11], 4);
+ ADD_STRING (" ES: ");
+ ADD_MEM (regs[12], 4);
+ ADD_STRING (" FS: ");
+ ADD_MEM (regs[13], 4);
+ ADD_STRING (" GS: ");
+ ADD_MEM (regs[14], 4);
+ ADD_STRING (" SS: ");
+ ADD_MEM (regs[15], 4);
+ ADD_STRING ("\n\n Trap: ");
+ ADD_MEM (regs[16], 8);
+ ADD_STRING (" Error: ");
+ ADD_MEM (regs[17], 8);
+ ADD_STRING (" OldMask: ");
+ ADD_MEM (regs[18], 8);
+ ADD_STRING ("\n ESP/signal: ");
+ ADD_MEM (regs[19], 8);
+ ADD_STRING (" CR2: ");
+ ADD_MEM (regs[20], 8);
+
+ if (ctx->fpstate != NULL)
+ {
+
+ /* Generate output for the FPU control/status registers. */
+ hexvalue (ctx->fpstate->cw, fpregs[0], 8);
+ hexvalue (ctx->fpstate->sw, fpregs[1], 8);
+ hexvalue (ctx->fpstate->tag, fpregs[2], 8);
+ hexvalue (ctx->fpstate->ipoff, fpregs[3], 8);
+ hexvalue (ctx->fpstate->cssel, fpregs[4], 4);
+ hexvalue (ctx->fpstate->dataoff, fpregs[5], 8);
+ hexvalue (ctx->fpstate->datasel, fpregs[6], 4);
+
+ ADD_STRING ("\n\n FPUCW: ");
+ ADD_MEM (fpregs[0], 8);
+ ADD_STRING (" FPUSW: ");
+ ADD_MEM (fpregs[1], 8);
+ ADD_STRING (" TAG: ");
+ ADD_MEM (fpregs[2], 8);
+ ADD_STRING ("\n IPOFF: ");
+ ADD_MEM (fpregs[3], 8);
+ ADD_STRING (" CSSEL: ");
+ ADD_MEM (fpregs[4], 4);
+ ADD_STRING (" DATAOFF: ");
+ ADD_MEM (fpregs[5], 8);
+ ADD_STRING (" DATASEL: ");
+ ADD_MEM (fpregs[6], 4);
+
+ /* Now the real FPU registers. */
+ hexvalue (ctx->fpstate->_st[0].exponent, fpregs[7], 8);
+ hexvalue (ctx->fpstate->_st[0].significand[3] << 16
+ | ctx->fpstate->_st[0].significand[2], fpregs[8], 8);
+ hexvalue (ctx->fpstate->_st[0].significand[1] << 16
+ | ctx->fpstate->_st[0].significand[0], fpregs[9], 8);
+ hexvalue (ctx->fpstate->_st[1].exponent, fpregs[10], 8);
+ hexvalue (ctx->fpstate->_st[1].significand[3] << 16
+ | ctx->fpstate->_st[1].significand[2], fpregs[11], 8);
+ hexvalue (ctx->fpstate->_st[1].significand[1] << 16
+ | ctx->fpstate->_st[1].significand[0], fpregs[12], 8);
+ hexvalue (ctx->fpstate->_st[2].exponent, fpregs[13], 8);
+ hexvalue (ctx->fpstate->_st[2].significand[3] << 16
+ | ctx->fpstate->_st[2].significand[2], fpregs[14], 8);
+ hexvalue (ctx->fpstate->_st[2].significand[1] << 16
+ | ctx->fpstate->_st[2].significand[0], fpregs[15], 8);
+ hexvalue (ctx->fpstate->_st[3].exponent, fpregs[16], 8);
+ hexvalue (ctx->fpstate->_st[3].significand[3] << 16
+ | ctx->fpstate->_st[3].significand[2], fpregs[17], 8);
+ hexvalue (ctx->fpstate->_st[3].significand[1] << 16
+ | ctx->fpstate->_st[3].significand[0], fpregs[18], 8);
+ hexvalue (ctx->fpstate->_st[4].exponent, fpregs[19], 8);
+ hexvalue (ctx->fpstate->_st[4].significand[3] << 16
+ | ctx->fpstate->_st[4].significand[2], fpregs[20], 8);
+ hexvalue (ctx->fpstate->_st[4].significand[1] << 16
+ | ctx->fpstate->_st[4].significand[0], fpregs[21], 8);
+ hexvalue (ctx->fpstate->_st[5].exponent, fpregs[22], 8);
+ hexvalue (ctx->fpstate->_st[5].significand[3] << 16
+ | ctx->fpstate->_st[5].significand[2], fpregs[23], 8);
+ hexvalue (ctx->fpstate->_st[5].significand[1] << 16
+ | ctx->fpstate->_st[5].significand[0], fpregs[24], 8);
+ hexvalue (ctx->fpstate->_st[6].exponent, fpregs[25], 8);
+ hexvalue (ctx->fpstate->_st[6].significand[3] << 16
+ | ctx->fpstate->_st[6].significand[2], fpregs[26], 8);
+ hexvalue (ctx->fpstate->_st[6].significand[1] << 16
+ | ctx->fpstate->_st[6].significand[0], fpregs[27], 8);
+ hexvalue (ctx->fpstate->_st[7].exponent, fpregs[28], 8);
+ hexvalue (ctx->fpstate->_st[7].significand[3] << 16
+ | ctx->fpstate->_st[7].significand[2], fpregs[29], 8);
+ hexvalue (ctx->fpstate->_st[7].significand[1] << 16
+ | ctx->fpstate->_st[7].significand[0], fpregs[30], 8);
+
+ ADD_STRING ("\n\n ST(0) ");
+ ADD_MEM (fpregs[7], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[8], 8);
+ ADD_MEM (fpregs[9], 8);
+ ADD_STRING (" ST(1) ");
+ ADD_MEM (fpregs[10], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[11], 8);
+ ADD_MEM (fpregs[12], 8);
+ ADD_STRING ("\n ST(2) ");
+ ADD_MEM (fpregs[13], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[14], 8);
+ ADD_MEM (fpregs[15], 8);
+ ADD_STRING (" ST(3) ");
+ ADD_MEM (fpregs[16], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[17], 8);
+ ADD_MEM (fpregs[18], 8);
+ ADD_STRING ("\n ST(4) ");
+ ADD_MEM (fpregs[19], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[20], 8);
+ ADD_MEM (fpregs[21], 8);
+ ADD_STRING (" ST(5) ");
+ ADD_MEM (fpregs[22], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[23], 8);
+ ADD_MEM (fpregs[24], 8);
+ ADD_STRING ("\n ST(6) ");
+ ADD_MEM (fpregs[25], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[26], 8);
+ ADD_MEM (fpregs[27], 8);
+ ADD_STRING (" ST(7) ");
+ ADD_MEM (fpregs[28], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[29], 8);
+ ADD_MEM (fpregs[30], 8);
+ }
+
+ ADD_STRING ("\n");
+
+ /* Write the stuff out. */
+ writev (fd, iov, nr);
+}
+
+
+#define REGISTER_DUMP register_dump (fd, &ctx)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/scandir64.c b/libc/sysdeps/unix/sysv/linux/i386/scandir64.c
new file mode 100644
index 000000000..690be813b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/scandir64.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dirent.h>
+
+#define SCANDIR __scandir64
+#define READDIR __readdir64
+#define DIRENT_TYPE struct dirent64
+
+#include <dirent/scandir.c>
+
+#undef SCANDIR
+#undef READDIR
+#undef DIRENT_TYPE
+
+#include <shlib-compat.h>
+
+versioned_symbol (libc, __scandir64, scandir64, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+#define SCANDIR attribute_compat_text_section __old_scandir64
+#define READDIR __old_readdir64
+#define DIRENT_TYPE struct __old_dirent64
+
+#include <dirent/scandir.c>
+
+compat_symbol (libc, __old_scandir64, scandir64, GLIBC_2_1);
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/semctl.c b/libc/sysdeps/unix/sysv/linux/i386/semctl.c
new file mode 100644
index 000000000..1693cd47c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/semctl.c
@@ -0,0 +1,185 @@
+/* Copyright (C) 1995,1997,1998,2000,2003,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/sem.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+#include <shlib-compat.h>
+
+struct __old_semid_ds
+{
+ struct __old_ipc_perm sem_perm; /* operation permission struct */
+ __time_t sem_otime; /* last semop() time */
+ __time_t sem_ctime; /* last time changed by semctl() */
+ struct sem *__sembase; /* ptr to first semaphore in array */
+ struct sem_queue *__sem_pending; /* pending operations */
+ struct sem_queue *__sem_pending_last; /* last pending operation */
+ struct sem_undo *__undo; /* ondo requests on this array */
+ unsigned short int sem_nsems; /* number of semaphores in set */
+};
+
+/* Define a `union semun' suitable for Linux here. */
+union semun
+{
+ int val; /* value for SETVAL */
+ struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
+ unsigned short int *array; /* array for GETALL & SETALL */
+ struct seminfo *__buf; /* buffer for IPC_INFO */
+ struct __old_semid_ds *__old_buf;
+};
+
+#include <bp-checks.h>
+#include <bp-semctl.h> /* definition of CHECK_SEMCTL needs union semum */
+
+#ifdef __NR_getuid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif
+
+/* Return identifier for array of NSEMS semaphores associated with
+ KEY. */
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int __old_semctl (int semid, int semnum, int cmd, ...);
+#endif
+int __new_semctl (int semid, int semnum, int cmd, ...);
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int
+attribute_compat_text_section
+__old_semctl (int semid, int semnum, int cmd, ...)
+{
+ union semun arg;
+ va_list ap;
+
+ va_start (ap, cmd);
+
+ /* Get the argument. */
+ arg = va_arg (ap, union semun);
+
+ va_end (ap);
+
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
+ CHECK_SEMCTL (&arg, semid, cmd));
+}
+compat_symbol (libc, __old_semctl, semctl, GLIBC_2_0);
+#endif
+
+int
+__new_semctl (int semid, int semnum, int cmd, ...)
+{
+ union semun arg;
+ va_list ap;
+
+ va_start (ap, cmd);
+
+ /* Get the argument. */
+ arg = va_arg (ap, union semun);
+
+ va_end (ap);
+
+#if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd | __IPC_64,
+ CHECK_SEMCTL (&arg, semid, cmd | __IPC_64));
+#else
+ switch (cmd) {
+ case SEM_STAT:
+ case IPC_STAT:
+ case IPC_SET:
+ break;
+ default:
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
+ CHECK_SEMCTL (&arg, semid, cmd));
+ }
+
+ {
+ int result;
+ struct __old_semid_ds old;
+ struct semid_ds *buf;
+
+#ifdef __NR_getuid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ if (__libc_missing_32bit_uids < 0)
+ {
+ int save_errno = errno;
+
+ /* Test presence of new IPC by testing for getuid32 syscall. */
+ result = INLINE_SYSCALL (getuid32, 0);
+ if (result == -1 && errno == ENOSYS)
+ __libc_missing_32bit_uids = 1;
+ else
+ __libc_missing_32bit_uids = 0;
+ __set_errno(save_errno);
+ }
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd | __IPC_64,
+ CHECK_SEMCTL (&arg, semid, cmd | __IPC_64));
+ return result;
+ }
+ }
+#endif
+
+ buf = arg.buf;
+ arg.__old_buf = &old;
+ if (cmd == IPC_SET)
+ {
+ old.sem_perm.uid = buf->sem_perm.uid;
+ old.sem_perm.gid = buf->sem_perm.gid;
+ old.sem_perm.mode = buf->sem_perm.mode;
+ if (old.sem_perm.uid != buf->sem_perm.uid ||
+ old.sem_perm.gid != buf->sem_perm.gid)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ }
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
+ CHECK_SEMCTL (&arg, semid, cmd));
+ if (result != -1 && cmd != IPC_SET)
+ {
+ memset(buf, 0, sizeof(*buf));
+ buf->sem_perm.__key = old.sem_perm.__key;
+ buf->sem_perm.uid = old.sem_perm.uid;
+ buf->sem_perm.gid = old.sem_perm.gid;
+ buf->sem_perm.cuid = old.sem_perm.cuid;
+ buf->sem_perm.cgid = old.sem_perm.cgid;
+ buf->sem_perm.mode = old.sem_perm.mode;
+ buf->sem_perm.__seq = old.sem_perm.__seq;
+ buf->sem_otime = old.sem_otime;
+ buf->sem_ctime = old.sem_ctime;
+ buf->sem_nsems = old.sem_nsems;
+ }
+ return result;
+ }
+#endif
+}
+
+versioned_symbol (libc, __new_semctl, semctl, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/i386/semtimedop.S b/libc/sysdeps/unix/sysv/linux/i386/semtimedop.S
new file mode 100644
index 000000000..0893c6a65
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/semtimedop.S
@@ -0,0 +1,75 @@
+/* Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#define SYSOP_semtimedop 4
+
+#define SVRSP 12 /* saved register space */
+#define PARMS LINKAGE+SVRSP /* space for 3 saved regs */
+#define SEMID PARMS
+#define SOPS SEMID+4
+#define NSOPS SOPS+PTR_SIZE
+#define TIMEOUT NSOPS+4
+
+ .text
+ENTRY (BP_SYM (semtimedop))
+
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+
+ movl $SYSOP_semtimedop, %ebx
+ cfi_rel_offset (ebx, 4)
+ movl SEMID(%esp), %ecx
+ movl NSOPS(%esp), %edx
+ movl SOPS(%esp), %edi
+ cfi_rel_offset (edi, 0)
+ movl TIMEOUT(%esp), %ebp
+ cfi_rel_offset (ebp, 8)
+ movl $__NR_ipc, %eax
+
+ ENTER_KERNEL
+
+ /* Restore registers. */
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+
+ /* If 0 > %eax > -4096 there was an error. */
+ cmpl $-4096, %eax
+ ja SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+L(pseudo_end):
+ ret
+
+#ifdef PIC
+ .align 4
+#endif
+PSEUDO_END (BP_SYM (semtimedop))
diff --git a/libc/sysdeps/unix/sysv/linux/i386/setcontext.S b/libc/sysdeps/unix/sysv/linux/i386/setcontext.S
new file mode 100644
index 000000000..bf2d7d2ba
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/setcontext.S
@@ -0,0 +1,97 @@
+/* Install given context.
+ Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+
+ENTRY(__setcontext)
+ /* Load address of the context data structure. */
+ movl 4(%esp), %eax
+
+ /* Get the current signal mask. Note that we preserve EBX in case
+ the system call fails and we return from the function with an
+ error. */
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ xorl %edx, %edx
+ leal oSIGMASK(%eax), %ecx
+ movl $SIG_SETMASK, %ebx
+ cfi_rel_offset (ebx, 0)
+ movl $__NR_sigprocmask, %eax
+ ENTER_KERNEL
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ cmpl $-4095, %eax /* Check %eax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+
+ /* EAX was modified, reload it. */
+ movl 4(%esp), %eax
+
+ /* Restore the floating-point context. Not the registers, only the
+ rest. */
+ movl oFPREGS(%eax), %ecx
+ fldenv (%ecx)
+
+ /* Restore the FS segment register. We don't touch the GS register
+ since it is used for threads. */
+ movl oFS(%eax), %ecx
+ movw %cx, %fs
+
+ /* Fetch the address to return to. */
+ movl oEIP(%eax), %ecx
+
+ /* Load the new stack pointer. */
+ cfi_def_cfa (eax, 0)
+ cfi_offset (edi, oEDI)
+ cfi_offset (esi, oESI)
+ cfi_offset (ebp, oEBP)
+ cfi_offset (ebx, oEBX)
+ cfi_offset (edx, oEDX)
+ cfi_offset (ecx, oECX)
+ movl oESP(%eax), %esp
+
+ /* Push the return address on the new stack so we can return there. */
+ pushl %ecx
+
+ /* Load the values of all the 32-bit registers (except ESP).
+ Since we are loading from EAX, it must be last. */
+ movl oEDI(%eax), %edi
+ movl oESI(%eax), %esi
+ movl oEBP(%eax), %ebp
+ movl oEBX(%eax), %ebx
+ movl oEDX(%eax), %edx
+ movl oECX(%eax), %ecx
+ movl oEAX(%eax), %eax
+
+ /* End FDE here, we fall into another context. */
+ cfi_endproc
+ cfi_startproc
+
+ /* The following 'ret' will pop the address of the code and jump
+ to it. */
+
+L(pseudo_end):
+ ret
+PSEUDO_END(__setcontext)
+
+weak_alias (__setcontext, setcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/setegid.c b/libc/sysdeps/unix/sysv/linux/i386/setegid.c
new file mode 100644
index 000000000..755bc360a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/setegid.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 1995-1998,2000,2002,2003,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+#include <kernel-features.h>
+
+
+#ifdef __NR_setresgid
+extern int __setresgid (uid_t rgid, uid_t egid, uid_t sgid);
+#endif
+
+int
+setegid (gid)
+ gid_t gid;
+{
+ int result;
+
+ if (gid == (gid_t) ~0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+#if __ASSUME_32BITUIDS > 0
+ result = INLINE_SETXID_SYSCALL (setresgid32, 3, -1, gid, -1);
+#else
+ /* First try the syscall. */
+# ifdef __NR_setresgid
+ result = __setresgid (-1, gid, -1);
+# if __ASSUME_SETRESGID_SYSCALL > 0
+ if (0)
+# else
+ if (result == -1 && errno == ENOSYS)
+# endif
+ /* No system call available. Use emulation. This may not work
+ since `setregid' also sets the saved user ID when GID is not
+ equal to the real user ID, making it impossible to switch back. */
+# endif
+ result = __setregid (-1, gid);
+#endif
+
+ return result;
+}
+libc_hidden_def (setegid)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/seteuid.c b/libc/sysdeps/unix/sysv/linux/i386/seteuid.c
new file mode 100644
index 000000000..6de173521
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/seteuid.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 1998,2000,2002,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+#include <kernel-features.h>
+
+
+#ifdef __NR_setresuid
+extern int __setresuid (uid_t ruid, uid_t euid, uid_t suid);
+#endif
+
+int
+seteuid (uid_t uid)
+{
+ int result;
+
+ if (uid == (uid_t) ~0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+#if __ASSUME_32BITUIDS > 0
+ result = INLINE_SETXID_SYSCALL (setresuid32, 3, -1, uid, -1);
+#else
+ /* First try the syscall. */
+# ifdef __NR_setresuid
+ result = __setresuid (-1, uid, -1);
+# if __ASSUME_SETRESUID_SYSCALL > 0
+ if (0)
+# else
+ if (result == -1 && errno == ENOSYS)
+# endif
+ /* No system call available. Use emulation. This may not work
+ since `setreuid' also sets the saved user ID when UID is not
+ equal to the real user ID, making it impossible to switch back. */
+# endif
+ result = __setreuid (-1, uid);
+#endif
+
+ return result;
+}
+libc_hidden_def (seteuid)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/setfsgid.c b/libc/sysdeps/unix/sysv/linux/i386/setfsgid.c
new file mode 100644
index 000000000..7296d433c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/setfsgid.c
@@ -0,0 +1,70 @@
+/* Copyright (C) 1998, 2000, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/fsuid.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+
+#ifdef __NR_setfsgid
+
+# ifdef __NR_setfsgid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids attribute_hidden;
+# endif
+# endif /* __NR_setfsgid32 */
+
+int
+setfsgid (gid_t gid)
+{
+ INTERNAL_SYSCALL_DECL (err);
+# if __ASSUME_32BITUIDS > 0
+ /* No error checking. */
+ return INTERNAL_SYSCALL (setfsgid32, err, 1, gid);
+# else
+# ifdef __NR_setfsgid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+
+ result = INTERNAL_SYSCALL (setfsgid32, err, 1, gid);
+ if (! INTERNAL_SYSCALL_ERROR_P (result, err)
+ || INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ return result;
+
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_setfsgid32 */
+ if (gid != (gid_t) ((__kernel_gid_t) gid))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* No error checking. */
+ return INTERNAL_SYSCALL (setfsgid, err, 1, gid);
+# endif
+}
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/setfsuid.c b/libc/sysdeps/unix/sysv/linux/i386/setfsuid.c
new file mode 100644
index 000000000..65ed35348
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/setfsuid.c
@@ -0,0 +1,71 @@
+/* Copyright (C) 1998, 2000, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/fsuid.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+#ifdef __NR_setfsuid
+
+# ifdef __NR_setfsuid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids attribute_hidden;
+# endif
+# endif /* __NR_setfsuid32 */
+
+int
+setfsuid (uid_t uid)
+{
+ INTERNAL_SYSCALL_DECL (err);
+# if __ASSUME_32BITUIDS > 0
+ /* No error checking. */
+ return INTERNAL_SYSCALL (setfsuid32, err, 1, uid);
+# else
+# ifdef __NR_setfsuid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+
+ result = INTERNAL_SYSCALL (setfsuid32, err, 1, uid);
+ if (! INTERNAL_SYSCALL_ERROR_P (result, err)
+ || INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ return result;
+
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_setfsuid32 */
+
+ if (uid != (uid_t) ((__kernel_uid_t) uid))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* No error checking. */
+ return INTERNAL_SYSCALL (setfsuid, err, 1, uid);
+# endif
+}
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/setgid.c b/libc/sysdeps/unix/sysv/linux/i386/setgid.c
new file mode 100644
index 000000000..208ef25d0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/setgid.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 1998, 2000, 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+
+#ifdef __NR_setgid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif /* __NR_setgid32 */
+
+int
+__setgid (gid_t gid)
+{
+ int result;
+
+#if __ASSUME_32BITUIDS > 0
+ result = INLINE_SETXID_SYSCALL (setgid32, 1, gid);
+#else
+# ifdef __NR_setgid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int saved_errno = errno;
+
+ result = INLINE_SETXID_SYSCALL (setgid32, 1, gid);
+
+ if (result == 0)
+ goto out;
+ if (errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_setgid32 */
+
+ if (gid == (gid_t) ~0
+ || gid != (gid_t) ((__kernel_gid_t) gid))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ result = INLINE_SETXID_SYSCALL (setgid, 1, gid);
+# ifdef __NR_setgid32
+ out:
+# endif
+#endif
+
+ return result;
+}
+#ifndef __setgid
+weak_alias (__setgid, setgid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/setgroups.c b/libc/sysdeps/unix/sysv/linux/i386/setgroups.c
new file mode 100644
index 000000000..10f5b7c91
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/setgroups.c
@@ -0,0 +1,87 @@
+/* Copyright (C) 1997,1998,2000,2002,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <grp.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+
+#ifdef __NR_setgroups32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif /* __NR_setgroups32 */
+
+/* Set the group set for the current user to GROUPS (N of them). For
+ Linux we must convert the array of groups into the format that the
+ kernel expects. */
+int
+setgroups (size_t n, const gid_t *groups)
+{
+#if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (setgroups32, 2, n, CHECK_N (groups, n));
+#else
+ if (n > (size_t) __sysconf (_SC_NGROUPS_MAX))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ else
+ {
+ size_t i;
+ __kernel_gid_t kernel_groups[n];
+
+# ifdef __NR_setgroups32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+ int saved_errno = errno;
+
+ result = INLINE_SYSCALL (setgroups32, 2, n, CHECK_N (groups, n));
+ if (result == 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_setgroups32 */
+ for (i = 0; i < n; i++)
+ {
+ kernel_groups[i] = (__ptrvalue (groups))[i];
+ if (groups[i] != (gid_t) ((__kernel_gid_t) groups[i]))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ }
+
+ return INLINE_SYSCALL (setgroups, 2, n, CHECK_N (kernel_groups, n));
+ }
+#endif
+}
+libc_hidden_def (setgroups)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/setregid.c b/libc/sysdeps/unix/sysv/linux/i386/setregid.c
new file mode 100644
index 000000000..05e448c6c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/setregid.c
@@ -0,0 +1,75 @@
+/* Copyright (C) 1998,2000,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+
+#ifdef __NR_setregid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif /* __NR_setregid32 */
+
+int
+__setregid (gid_t rgid, gid_t egid)
+{
+ int result;
+
+#if __ASSUME_32BITUIDS > 0
+ result = INLINE_SETXID_SYSCALL (setregid32, 2, rgid, egid);
+#else
+# ifdef __NR_setregid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int saved_errno = errno;
+
+ result = INLINE_SETXID_SYSCALL (setregid32, 2, rgid, egid);
+
+ if (result == 0)
+ goto out;
+ if (errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_setregid32 */
+ if (((rgid + 1) > (gid_t) ((__kernel_gid_t) -1U))
+ || ((egid + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ result = INLINE_SETXID_SYSCALL (setregid, 2, rgid, egid);
+# ifdef __NR_setregid32
+ out:
+# endif
+#endif
+
+ return result;
+}
+#ifndef __setregid
+weak_alias (__setregid, setregid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/setresgid.c b/libc/sysdeps/unix/sysv/linux/i386/setresgid.c
new file mode 100644
index 000000000..d0750bb20
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/setresgid.c
@@ -0,0 +1,86 @@
+/* Copyright (C) 1998,2000,2002,2003,2004,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+
+#if defined __NR_setresgid || defined __NR_setresgid32
+
+# ifdef __NR_setresgid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+# endif /* __NR_setresgid32 */
+
+int
+__setresgid (gid_t rgid, gid_t egid, gid_t sgid)
+{
+ int result;
+
+# if __ASSUME_32BITUIDS > 0 || !defined __NR_setresgid
+ result = INLINE_SETXID_SYSCALL (setresgid32, 3, rgid, egid, sgid);
+# else
+# ifdef __NR_setresgid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int saved_errno = errno;
+
+ result = INLINE_SETXID_SYSCALL (setresgid32, 3, rgid, egid, sgid);
+ if (result == 0)
+ goto out;
+ if (errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_setresgid32 */
+
+ if (((rgid + 1) > (gid_t) ((__kernel_gid_t) -1U))
+ || ((egid + 1) > (gid_t) ((__kernel_gid_t) -1U))
+ || ((sgid + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ result = INLINE_SETXID_SYSCALL (setresgid, 3, rgid, egid, sgid);
+# ifdef __NR_setresgid32
+ out:
+# endif
+# endif
+
+ return result;
+}
+libc_hidden_def (__setresgid)
+#ifndef __setresgid
+weak_alias (__setresgid, setresgid)
+#endif
+
+#else
+
+#include <posix/setresgid.c>
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/setresuid.c b/libc/sysdeps/unix/sysv/linux/i386/setresuid.c
new file mode 100644
index 000000000..0a676e53a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/setresuid.c
@@ -0,0 +1,86 @@
+/* Copyright (C) 1998,2000,2002,2003,2004,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+
+#if defined __NR_setresuid || defined __NR_setresuid32
+
+# ifdef __NR_setresuid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+# endif /* __NR_setresuid32 */
+
+int
+__setresuid (uid_t ruid, uid_t euid, uid_t suid)
+{
+ int result;
+
+# if __ASSUME_32BITUIDS > 0 || !defined __NR_setresuid
+ result = INLINE_SETXID_SYSCALL (setresuid32, 3, ruid, euid, suid);
+# else
+# ifdef __NR_setresuid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int saved_errno = errno;
+
+ result = INLINE_SETXID_SYSCALL (setresuid32, 3, ruid, euid, suid);
+ if (result == 0)
+ goto out;
+ if (errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_setresuid32 */
+
+ if (((ruid + 1) > (uid_t) ((__kernel_uid_t) -1U))
+ || ((euid + 1) > (uid_t) ((__kernel_uid_t) -1U))
+ || ((suid + 1) > (uid_t) ((__kernel_uid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ result = INLINE_SETXID_SYSCALL (setresuid, 3, ruid, euid, suid);
+# ifdef __NR_setresuid32
+ out:
+# endif
+# endif
+
+ return result;
+}
+libc_hidden_def (__setresuid)
+#ifndef __setresuid
+weak_alias (__setresuid, setresuid)
+#endif
+
+#else
+
+#include <posix/setresuid.c>
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/setreuid.c b/libc/sysdeps/unix/sysv/linux/i386/setreuid.c
new file mode 100644
index 000000000..1ea449616
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/setreuid.c
@@ -0,0 +1,75 @@
+/* Copyright (C) 1998,2000,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+
+#ifdef __NR_setreuid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif /* __NR_setreuid32 */
+
+int
+__setreuid (uid_t ruid, uid_t euid)
+{
+ int result;
+
+#if __ASSUME_32BITUIDS > 0
+ result = INLINE_SETXID_SYSCALL (setreuid32, 2, ruid, euid);
+#else
+# ifdef __NR_setreuid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int saved_errno = errno;
+
+ result = INLINE_SETXID_SYSCALL (setreuid32, 2, ruid, euid);
+
+ if (result == 0)
+ goto out;
+ if (errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_setreuid32 */
+ if (((ruid + 1) > (uid_t) ((__kernel_uid_t) -1U))
+ || ((euid + 1) > (uid_t) ((__kernel_uid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ result = INLINE_SETXID_SYSCALL (setreuid, 2, ruid, euid);
+# ifdef __NR_setreuid32
+ out:
+# endif
+#endif
+
+ return result;
+}
+#ifndef __setreuid
+weak_alias (__setreuid, setreuid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/setrlimit.c b/libc/sysdeps/unix/sysv/linux/i386/setrlimit.c
new file mode 100644
index 000000000..e7e517d91
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/setrlimit.c
@@ -0,0 +1,78 @@
+/* Copyright (C) 1999, 2000, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/param.h>
+#include <sys/resource.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <shlib-compat.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+extern int __new_setrlimit (enum __rlimit_resource resource,
+ const struct rlimit *__unboundedrlimits);
+
+/* Linux 2.3.25 introduced a new system call since the types used for
+ the limits are now unsigned. */
+#if defined __NR_ugetrlimit && !defined __ASSUME_NEW_GETRLIMIT_SYSCALL
+extern int __have_no_new_getrlimit; /* from getrlimit.c */
+#endif
+
+int
+__new_setrlimit (enum __rlimit_resource resource, const struct rlimit *rlimits)
+{
+#ifdef __ASSUME_NEW_GETRLIMIT_SYSCALL
+ return INLINE_SYSCALL (setrlimit, 2, resource, CHECK_1 (rlimits));
+#else
+ struct rlimit rlimits_small;
+
+# ifdef __NR_ugetrlimit
+ if (__have_no_new_getrlimit == 0)
+ {
+ /* Check if the new ugetrlimit syscall exists. We must do this
+ first because older kernels don't reject negative rlimit
+ values in setrlimit. */
+ int result = INLINE_SYSCALL (ugetrlimit, 2, resource, __ptrvalue (&rlimits_small));
+ if (result != -1 || errno != ENOSYS)
+ /* The syscall exists. */
+ __have_no_new_getrlimit = -1;
+ else
+ /* The syscall does not exist. */
+ __have_no_new_getrlimit = 1;
+ }
+ if (__have_no_new_getrlimit < 0)
+ return INLINE_SYSCALL (setrlimit, 2, resource, CHECK_1 (rlimits));
+# endif
+
+ /* We might have to correct the limits values. Since the old values
+ were signed the new values might be too large. */
+ rlimits_small.rlim_cur = MIN ((unsigned long int) rlimits->rlim_cur,
+ RLIM_INFINITY >> 1);
+ rlimits_small.rlim_max = MIN ((unsigned long int) rlimits->rlim_max,
+ RLIM_INFINITY >> 1);
+
+ /* Use the adjusted values. */
+ return INLINE_SYSCALL (setrlimit, 2, resource, __ptrvalue (&rlimits_small));
+#endif
+}
+
+weak_alias (__new_setrlimit, __setrlimit);
+versioned_symbol (libc, __new_setrlimit, setrlimit, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/i386/setuid.c b/libc/sysdeps/unix/sysv/linux/i386/setuid.c
new file mode 100644
index 000000000..21c5bcd61
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/setuid.c
@@ -0,0 +1,75 @@
+/* Copyright (C) 1998,2000,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+
+#ifdef __NR_setuid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif /* __NR_setuid32 */
+
+int
+__setuid (uid_t uid)
+{
+ int result;
+
+#if __ASSUME_32BITUIDS > 0 && defined __NR_setuid32
+ result = INLINE_SETXID_SYSCALL (setuid32, 1, uid);
+#else
+# ifdef __NR_setuid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int saved_errno = errno;
+
+ result = INLINE_SETXID_SYSCALL (setuid32, 1, uid);
+ if (result == 0)
+ goto out;
+ if (errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_setuid32 */
+
+ if (uid == (uid_t) ~0
+ || uid != (uid_t) ((__kernel_uid_t) uid))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ result = INLINE_SETXID_SYSCALL (setuid, 1, uid);
+# ifdef __NR_setuid32
+ out:
+# endif
+#endif
+
+ return result;
+}
+#ifndef __setuid
+weak_alias (__setuid, setuid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/shmctl.c b/libc/sysdeps/unix/sysv/linux/i386/shmctl.c
new file mode 100644
index 000000000..2cc039996
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/shmctl.c
@@ -0,0 +1,178 @@
+/* Copyright (C) 1995,1997,1998,2000,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/shm.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <bits/wordsize.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+#include <shlib-compat.h>
+
+struct __old_shmid_ds
+{
+ struct __old_ipc_perm shm_perm; /* operation permission struct */
+ int shm_segsz; /* size of segment in bytes */
+ __time_t shm_atime; /* time of last shmat() */
+ __time_t shm_dtime; /* time of last shmdt() */
+ __time_t shm_ctime; /* time of last change by shmctl() */
+ __ipc_pid_t shm_cpid; /* pid of creator */
+ __ipc_pid_t shm_lpid; /* pid of last shmop */
+ unsigned short int shm_nattch; /* number of current attaches */
+ unsigned short int __shm_npages; /* size of segment (pages) */
+ unsigned long int *__unbounded __shm_pages; /* array of ptrs to frames -> SHMMAX */
+ struct vm_area_struct *__unbounded __attaches; /* descriptors for attaches */
+};
+
+struct __old_shminfo
+{
+ int shmmax;
+ int shmmin;
+ int shmmni;
+ int shmseg;
+ int shmall;
+};
+
+#ifdef __NR_getuid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif
+
+/* Provide operations to control over shared memory segments. */
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int __old_shmctl (int, int, struct __old_shmid_ds *);
+#endif
+int __new_shmctl (int, int, struct shmid_ds *);
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int
+attribute_compat_text_section
+__old_shmctl (int shmid, int cmd, struct __old_shmid_ds *buf)
+{
+ return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl,
+ shmid, cmd, 0, CHECK_1 (buf));
+}
+compat_symbol (libc, __old_shmctl, shmctl, GLIBC_2_0);
+#endif
+
+int
+__new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
+{
+#if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl,
+ shmid, cmd | __IPC_64, 0, CHECK_1 (buf));
+#else
+ switch (cmd) {
+ case SHM_STAT:
+ case IPC_STAT:
+ case IPC_SET:
+# if __WORDSIZE != 32
+ case IPC_INFO:
+# endif
+ break;
+ default:
+ return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl,
+ shmid, cmd, 0, CHECK_1 (buf));
+ }
+
+ {
+ struct __old_shmid_ds old;
+ int result;
+
+# ifdef __NR_getuid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ if (__libc_missing_32bit_uids < 0)
+ {
+ int save_errno = errno;
+
+ /* Test presence of new IPC by testing for getuid32 syscall. */
+ result = INLINE_SYSCALL (getuid32, 0);
+ if (result == -1 && errno == ENOSYS)
+ __libc_missing_32bit_uids = 1;
+ else
+ __libc_missing_32bit_uids = 0;
+ __set_errno(save_errno);
+ }
+ if (__libc_missing_32bit_uids <= 0)
+ return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl,
+ shmid, cmd | __IPC_64, 0, CHECK_1 (buf));
+ }
+# endif
+
+ if (cmd == IPC_SET)
+ {
+ old.shm_perm.uid = buf->shm_perm.uid;
+ old.shm_perm.gid = buf->shm_perm.gid;
+ old.shm_perm.mode = buf->shm_perm.mode;
+ if (old.shm_perm.uid != buf->shm_perm.uid ||
+ old.shm_perm.gid != buf->shm_perm.gid)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ }
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_shmctl,
+ shmid, cmd, 0, __ptrvalue (&old));
+ if (result != -1 && (cmd == SHM_STAT || cmd == IPC_STAT))
+ {
+ memset(buf, 0, sizeof(*buf));
+ buf->shm_perm.__key = old.shm_perm.__key;
+ buf->shm_perm.uid = old.shm_perm.uid;
+ buf->shm_perm.gid = old.shm_perm.gid;
+ buf->shm_perm.cuid = old.shm_perm.cuid;
+ buf->shm_perm.cgid = old.shm_perm.cgid;
+ buf->shm_perm.mode = old.shm_perm.mode;
+ buf->shm_perm.__seq = old.shm_perm.__seq;
+ buf->shm_atime = old.shm_atime;
+ buf->shm_dtime = old.shm_dtime;
+ buf->shm_ctime = old.shm_ctime;
+ buf->shm_segsz = old.shm_segsz;
+ buf->shm_nattch = old.shm_nattch;
+ buf->shm_cpid = old.shm_cpid;
+ buf->shm_lpid = old.shm_lpid;
+ }
+# if __WORDSIZE != 32
+ else if (result != -1 && cmd == IPC_INFO)
+ {
+ struct __old_shminfo *oldi = (struct __old_shminfo *)&old;
+ struct shminfo *i = (struct shminfo *)buf;
+
+ memset(i, 0, sizeof(*i));
+ i->shmmax = oldi->shmmax;
+ i->shmmin = oldi->shmmin;
+ i->shmmni = oldi->shmmni;
+ i->shmseg = oldi->shmseg;
+ i->shmall = oldi->shmall;
+ }
+# endif
+ return result;
+ }
+#endif
+}
+
+versioned_symbol (libc, __new_shmctl, shmctl, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sigaction.c b/libc/sysdeps/unix/sysv/linux/i386/sigaction.c
new file mode 100644
index 000000000..299574dac
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sigaction.c
@@ -0,0 +1,204 @@
+/* POSIX.1 `sigaction' call for Linux/i386.
+ Copyright (C) 1991,1995-2000,2002-2004,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <errno.h>
+#include <stddef.h>
+#include <signal.h>
+#include <string.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <ldsodefs.h>
+
+#include <kernel-features.h>
+
+/* The difference here is that the sigaction structure used in the
+ kernel is not the same as we use in the libc. Therefore we must
+ translate it here. */
+#include <kernel_sigaction.h>
+
+/* We do not globally define the SA_RESTORER flag so do it here. */
+#define SA_RESTORER 0x04000000
+
+
+#if __ASSUME_REALTIME_SIGNALS == 0
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. */
+int __libc_missing_rt_sigs;
+#endif
+
+/* Using the hidden attribute here does not change the code but it
+ helps to avoid warnings. */
+#if defined HAVE_HIDDEN && defined HAVE_VISIBILITY_ATTRIBUTE \
+ && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE
+# ifdef __NR_rt_sigaction
+extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
+# endif
+extern void restore (void) asm ("__restore") attribute_hidden;
+#else
+# ifdef __NR_rt_sigaction
+static void restore_rt (void) asm ("__restore_rt");
+# endif
+static void restore (void) asm ("__restore");
+#endif
+
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+ If OACT is not NULL, put the old action for SIG in *OACT. */
+int
+__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+{
+#if __ASSUME_REALTIME_SIGNALS == 0
+ struct old_kernel_sigaction k_newact, k_oldact;
+#endif
+ int result;
+
+#ifdef __NR_rt_sigaction
+
+ /* First try the RT signals. */
+# if __ASSUME_REALTIME_SIGNALS == 0
+ if (!__libc_missing_rt_sigs)
+# endif
+ {
+ struct kernel_sigaction kact, koact;
+# if __ASSUME_REALTIME_SIGNALS == 0
+ int saved_errno = errno;
+# endif
+
+ if (act)
+ {
+ kact.k_sa_handler = act->sa_handler;
+ kact.sa_flags = act->sa_flags;
+ memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
+
+ if (GLRO(dl_sysinfo_dso) == NULL)
+ {
+ kact.sa_flags |= SA_RESTORER;
+
+ kact.sa_restorer = ((act->sa_flags & SA_SIGINFO)
+ ? &restore_rt : &restore);
+ }
+ }
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ result = INLINE_SYSCALL (rt_sigaction, 4,
+ sig, act ? __ptrvalue (&kact) : NULL,
+ oact ? __ptrvalue (&koact) : NULL, _NSIG / 8);
+
+# if __ASSUME_REALTIME_SIGNALS == 0
+ if (result >= 0 || errno != ENOSYS)
+# endif
+ {
+ if (oact && result >= 0)
+ {
+ oact->sa_handler = koact.k_sa_handler;
+ memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t));
+ oact->sa_flags = koact.sa_flags;
+ oact->sa_restorer = koact.sa_restorer;
+ }
+ return result;
+ }
+
+# if __ASSUME_REALTIME_SIGNALS == 0
+ __set_errno (saved_errno);
+ __libc_missing_rt_sigs = 1;
+# endif
+ }
+#endif
+
+#if __ASSUME_REALTIME_SIGNALS == 0
+ if (act)
+ {
+ k_newact.k_sa_handler = act->sa_handler;
+ k_newact.sa_mask = act->sa_mask.__val[0];
+ k_newact.sa_flags = act->sa_flags | SA_RESTORER;
+
+ k_newact.sa_restorer = &restore;
+ }
+
+ result = INLINE_SYSCALL (sigaction, 3, sig,
+ act ? __ptrvalue (&k_newact) : 0,
+ oact ? __ptrvalue (&k_oldact) : 0);
+
+ if (result < 0)
+ return -1;
+
+ if (oact)
+ {
+ oact->sa_handler = k_oldact.k_sa_handler;
+ oact->sa_mask.__val[0] = k_oldact.sa_mask;
+ oact->sa_flags = k_oldact.sa_flags;
+ oact->sa_restorer = k_oldact.sa_restorer;
+ }
+
+ return 0;
+#endif
+}
+libc_hidden_def (__libc_sigaction)
+
+#ifdef WRAPPER_INCLUDE
+# include WRAPPER_INCLUDE
+#endif
+
+#ifndef LIBC_SIGACTION
+weak_alias (__libc_sigaction, __sigaction)
+libc_hidden_weak (__sigaction)
+weak_alias (__libc_sigaction, sigaction)
+#endif
+
+/* NOTE: Please think twice before making any changes to the bits of
+ code below. GDB needs some intimate knowledge about it to
+ recognize them as signal trampolines, and make backtraces through
+ signal handlers work right. Important are both the names
+ (__restore and __restore_rt) and the exact instruction sequence.
+ If you ever feel the need to make any changes, please notify the
+ appropriate GDB maintainer. */
+
+#define RESTORE(name, syscall) RESTORE2 (name, syscall)
+#define RESTORE2(name, syscall) \
+asm \
+ ( \
+ ".text\n" \
+ " .align 16\n" \
+ "__" #name ":\n" \
+ " movl $" #syscall ", %eax\n" \
+ " int $0x80" \
+ );
+
+#ifdef __NR_rt_sigaction
+/* The return code for realtime-signals. */
+RESTORE (restore_rt, __NR_rt_sigreturn)
+#endif
+
+/* For the boring old signals. */
+#undef RESTORE2
+#define RESTORE2(name, syscall) \
+asm \
+ ( \
+ ".text\n" \
+ " .align 8\n" \
+ "__" #name ":\n" \
+ " popl %eax\n" \
+ " movl $" #syscall ", %eax\n" \
+ " int $0x80" \
+ );
+
+RESTORE (restore, __NR_sigreturn)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h b/libc/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h
new file mode 100644
index 000000000..6530ba6f3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define SIGCONTEXT struct sigcontext
+#define SIGCONTEXT_EXTRA_ARGS
+#define GET_PC(ctx) ((void *) ctx.eip)
+#define GET_FRAME(ctx) ((void *) ctx.ebp)
+#define GET_STACK(ctx) ((void *) ctx.esp_at_signal)
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+do { \
+ int __tmp1, __tmp2, __tmp3, __tmp4; \
+ __asm __volatile ("movl\t%%esp, %%edi\n\t" \
+ "andl\t$-16, %%esp\n\t" \
+ "subl\t%8, %%esp\n\t" \
+ "movl\t%%edi, %c8-4(%%esp)\n\t" \
+ "movl\t%1, 0(%%esp)\n\t" \
+ "leal\t4(%%esp), %%edi\n\t" \
+ "cld\n\t" \
+ "rep\tmovsl\n\t" \
+ "call\t*%0\n\t" \
+ "cld\n\t" \
+ "movl\t%9, %%ecx\n\t" \
+ "subl\t%%edi, %%esi\n\t" \
+ "leal\t4(%%esp,%%esi,1), %%edi\n\t" \
+ "leal\t4(%%esp), %%esi\n\t" \
+ "rep\tmovsl\n\t" \
+ "movl\t%c8-4(%%esp), %%esp\n\t" \
+ : "=a" (__tmp1), "=d" (__tmp2), "=S" (__tmp3), \
+ "=c" (__tmp4) \
+ : "0" (handler), "1" (signo), "2" (&ctx), \
+ "3" (sizeof (struct sigcontext) / 4), \
+ "n" ((sizeof (struct sigcontext) + 19) & ~15), \
+ "i" (sizeof (struct sigcontext) / 4) \
+ : "cc", "edi"); \
+} while (0)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/socket.S b/libc/sysdeps/unix/sysv/linux/i386/socket.S
new file mode 100644
index 000000000..7c8ac29b8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/socket.S
@@ -0,0 +1,124 @@
+/* Copyright (C) 1995-1998,2002,2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep-cancel.h>
+#include <socketcall.h>
+#include <tls.h>
+
+#define P(a, b) P2(a, b)
+#define P2(a, b) a##b
+
+ .text
+/* The socket-oriented system calls are handled unusally in Linux.
+ They are all gated through the single `socketcall' system call number.
+ `socketcall' takes two arguments: the first is the subcode, specifying
+ which socket function is being called; and the second is a pointer to
+ the arguments to the specific function.
+
+ The .S files for the other calls just #define socket and #include this. */
+
+#ifndef __socket
+# ifndef NO_WEAK_ALIAS
+# define __socket P(__,socket)
+# else
+# define __socket socket
+# endif
+#endif
+
+.globl __socket
+ENTRY (__socket)
+#if defined NEED_CANCELLATION && defined CENABLE
+ SINGLE_THREAD_P
+ jne 1f
+#endif
+
+ /* Save registers. */
+ movl %ebx, %edx
+ cfi_register (3, 2)
+
+ movl $SYS_ify(socketcall), %eax /* System call number in %eax. */
+
+ /* Use ## so `socket' is a separate token that might be #define'd. */
+ movl $P(SOCKOP_,socket), %ebx /* Subcode is first arg to syscall. */
+ lea 4(%esp), %ecx /* Address of args is 2nd arg. */
+
+ /* Do the system call trap. */
+ ENTER_KERNEL
+
+ /* Restore registers. */
+ movl %edx, %ebx
+ cfi_restore (3)
+
+ /* %eax is < 0 if there was an error. */
+ cmpl $-125, %eax
+ jae SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+L(pseudo_end):
+ ret
+
+
+#if defined NEED_CANCELLATION && defined CENABLE
+ /* We need one more register. */
+1: pushl %esi
+ cfi_adjust_cfa_offset(4)
+
+ /* Enable asynchronous cancellation. */
+ CENABLE
+ movl %eax, %esi
+ cfi_offset(6, -8) /* %esi */
+
+ /* Save registers. */
+ movl %ebx, %edx
+ cfi_register (3, 2)
+
+ movl $SYS_ify(socketcall), %eax /* System call number in %eax. */
+
+ /* Use ## so `socket' is a separate token that might be #define'd. */
+ movl $P(SOCKOP_,socket), %ebx /* Subcode is first arg to syscall. */
+ lea 8(%esp), %ecx /* Address of args is 2nd arg. */
+
+ /* Do the system call trap. */
+ ENTER_KERNEL
+
+ /* Restore registers. */
+ movl %edx, %ebx
+ cfi_restore (3)
+
+ /* Restore the cancellation. */
+ xchgl %esi, %eax
+ CDISABLE
+
+ /* Restore registers. */
+ movl %esi, %eax
+ popl %esi
+ cfi_restore (6)
+ cfi_adjust_cfa_offset(-4)
+
+ /* %eax is < 0 if there was an error. */
+ cmpl $-125, %eax
+ jae SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+ ret
+#endif
+PSEUDO_END (__socket)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__socket, socket)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/swapcontext.S b/libc/sysdeps/unix/sysv/linux/i386/swapcontext.S
new file mode 100644
index 000000000..27c16200b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/swapcontext.S
@@ -0,0 +1,112 @@
+/* Save current context and install the given one.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+
+ENTRY(__swapcontext)
+ /* Load address of the context data structure we save in. */
+ movl 4(%esp), %eax
+
+ /* Return value of swapcontext. EAX is the only register whose
+ value is not preserved. */
+ movl $0, oEAX(%eax)
+
+ /* Save the 32-bit register values and the return address. */
+ movl %ecx, oECX(%eax)
+ movl %edx, oEDX(%eax)
+ movl %edi, oEDI(%eax)
+ movl %esi, oESI(%eax)
+ movl %ebp, oEBP(%eax)
+ movl (%esp), %ecx
+ movl %ecx, oEIP(%eax)
+ leal 4(%esp), %ecx
+ movl %ecx, oESP(%eax)
+ movl %ebx, oEBX(%eax)
+
+ /* Save the FS segment register. */
+ xorl %edx, %edx
+ movw %fs, %dx
+ movl %edx, oFS(%eax)
+
+ /* We have separate floating-point register content memory on the
+ stack. We use the __fpregs_mem block in the context. Set the
+ links up correctly. */
+ leal oFPREGSMEM(%eax), %ecx
+ movl %ecx, oFPREGS(%eax)
+ /* Save the floating-point context. */
+ fnstenv (%ecx)
+
+ /* Load address of the context data structure we have to load. */
+ movl 8(%esp), %ecx
+
+ /* Save the current signal mask and install the new one. */
+ pushl %ebx
+ leal oSIGMASK(%eax), %edx
+ leal oSIGMASK(%ecx), %ecx
+ movl $SIG_SETMASK, %ebx
+ movl $__NR_sigprocmask, %eax
+ ENTER_KERNEL
+ popl %ebx
+ cmpl $-4095, %eax /* Check %eax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+
+ /* EAX was modified, reload it. */
+ movl 8(%esp), %eax
+
+ /* Restore the floating-point context. Not the registers, only the
+ rest. */
+ movl oFPREGS(%eax), %ecx
+ fldenv (%ecx)
+
+ /* Restore the FS segment register. We don't touch the GS register
+ since it is used for threads. */
+ movl oFS(%eax), %edx
+ movw %dx, %fs
+
+ /* Fetch the address to return to. */
+ movl oEIP(%eax), %ecx
+
+ /* Load the new stack pointer. */
+ movl oESP(%eax), %esp
+
+ /* Push the return address on the new stack so we can return there. */
+ pushl %ecx
+
+ /* Load the values of all the 32-bit registers (except ESP).
+ Since we are loading from EAX, it must be last. */
+ movl oEDI(%eax), %edi
+ movl oESI(%eax), %esi
+ movl oEBP(%eax), %ebp
+ movl oEBX(%eax), %ebx
+ movl oEDX(%eax), %edx
+ movl oECX(%eax), %ecx
+ movl oEAX(%eax), %eax
+
+ /* The following 'ret' will pop the address of the code and jump
+ to it. */
+
+L(pseudo_end):
+ ret
+PSEUDO_END(__swapcontext)
+
+weak_alias (__swapcontext, swapcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sync_file_range.S b/libc/sysdeps/unix/sysv/linux/i386/sync_file_range.S
new file mode 100644
index 000000000..f39e8a00d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sync_file_range.S
@@ -0,0 +1,72 @@
+/* Selective file content synch'ing.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+
+ .text
+ENTRY (sync_file_range)
+#ifdef __NR_sync_file_range
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+
+ movl 20(%esp), %ebx
+ cfi_rel_offset (ebx, 12)
+ movl 24(%esp), %ecx
+ movl 28(%esp), %edx
+ movl 32(%esp), %esi
+ cfi_rel_offset (esi, 8)
+ movl 36(%esp), %edi
+ cfi_rel_offset (edi, 4)
+ movl 40(%esp), %ebp
+ cfi_rel_offset (ebp, 0)
+
+ movl $SYS_ify(sync_file_range), %eax
+ ENTER_KERNEL
+
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+
+ cmpl $-4095, %eax
+ jae SYSCALL_ERROR_LABEL
+L(pseudo_end):
+ ret
+#else
+ movl $-ENOSYS, %eax
+ jmp SYSCALL_ERROR_LABEL
+#endif
+PSEUDO_END (sync_file_range)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sys/debugreg.h b/libc/sysdeps/unix/sysv/linux/i386/sys/debugreg.h
new file mode 100644
index 000000000..c99c94359
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sys/debugreg.h
@@ -0,0 +1,91 @@
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_DEBUGREG_H
+#define _SYS_DEBUGREG_H 1
+
+/* Indicate the register numbers for a number of the specific
+ debug registers. Registers 0-3 contain the addresses we wish to trap on */
+#define DR_FIRSTADDR 0 /* u_debugreg[DR_FIRSTADDR] */
+#define DR_LASTADDR 3 /* u_debugreg[DR_LASTADDR] */
+
+#define DR_STATUS 6 /* u_debugreg[DR_STATUS] */
+#define DR_CONTROL 7 /* u_debugreg[DR_CONTROL] */
+
+/* Define a few things for the status register. We can use this to determine
+ which debugging register was responsible for the trap. The other bits
+ are either reserved or not of interest to us. */
+
+#define DR_TRAP0 (0x1) /* db0 */
+#define DR_TRAP1 (0x2) /* db1 */
+#define DR_TRAP2 (0x4) /* db2 */
+#define DR_TRAP3 (0x8) /* db3 */
+
+#define DR_STEP (0x4000) /* single-step */
+#define DR_SWITCH (0x8000) /* task switch */
+
+/* Now define a bunch of things for manipulating the control register.
+ The top two bytes of the control register consist of 4 fields of 4
+ bits - each field corresponds to one of the four debug registers,
+ and indicates what types of access we trap on, and how large the data
+ field is that we are looking at */
+
+#define DR_CONTROL_SHIFT 16 /* Skip this many bits in ctl register */
+#define DR_CONTROL_SIZE 4 /* 4 control bits per register */
+
+#define DR_RW_EXECUTE (0x0) /* Settings for the access types to trap on */
+#define DR_RW_WRITE (0x1)
+#define DR_RW_READ (0x3)
+
+#define DR_LEN_1 (0x0) /* Settings for data length to trap on */
+#define DR_LEN_2 (0x4)
+#define DR_LEN_4 (0xC)
+
+/* The low byte to the control register determine which registers are
+ enabled. There are 4 fields of two bits. One bit is "local", meaning
+ that the processor will reset the bit after a task switch and the other
+ is global meaning that we have to explicitly reset the bit. With linux,
+ you can use either one, since we explicitly zero the register when we enter
+ kernel mode. */
+
+#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit */
+#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit */
+#define DR_ENABLE_SIZE 2 /* 2 enable bits per register */
+
+#define DR_LOCAL_ENABLE_MASK (0x55) /* Set local bits for all 4 regs */
+#define DR_GLOBAL_ENABLE_MASK (0xAA) /* Set global bits for all 4 regs */
+
+/* The second byte to the control register has a few special things.
+
+ On the i386, you should set the DR_LOCAL_SLOWDOWN or
+ DR_GLOBAL_SLOWDOWN bits if you want to know exactly which
+ instruction triggered the watchpoint. Setting these bits causes
+ the processor to run more slowly, but leaving them clear makes it
+ treat watchpoint hits as imprecise exceptions, so you can't
+ reliably determine which instruction caused the hit.
+
+ The i486 and all later IA-32 processors ignore DR_LOCAL_SLOWDOWN
+ and DR_GLOBAL_SLOWDOWN. They always report the exception
+ precisely, except in some rare cases, which the user can't do
+ anything about. */
+
+#define DR_CONTROL_RESERVED (0xFC00) /* Reserved by Intel */
+#define DR_LOCAL_SLOWDOWN (0x100) /* Local slow the pipeline */
+#define DR_GLOBAL_SLOWDOWN (0x200) /* Global slow the pipeline */
+
+#endif /* sys/debugreg.h */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sys/elf.h b/libc/sysdeps/unix/sysv/linux/i386/sys/elf.h
new file mode 100644
index 000000000..d959cdca1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sys/elf.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_ELF_H
+#define _SYS_ELF_H 1
+
+#warning "This header is obsolete; use <sys/procfs.h> instead."
+
+#include <sys/procfs.h>
+
+#endif /* _SYS_ELF_H */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sys/io.h b/libc/sysdeps/unix/sysv/linux/i386/sys/io.h
new file mode 100644
index 000000000..39a7877f7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sys/io.h
@@ -0,0 +1,181 @@
+/* Copyright (C) 1996, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IO_H
+#define _SYS_IO_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* If TURN_ON is TRUE, request for permission to do direct i/o on the
+ port numbers in the range [FROM,FROM+NUM-1]. Otherwise, turn I/O
+ permission off for that range. This call requires root privileges.
+
+ Portability note: not all Linux platforms support this call. Most
+ platforms based on the PC I/O architecture probably will, however.
+ E.g., Linux/Alpha for Alpha PCs supports this. */
+extern int ioperm (unsigned long int __from, unsigned long int __num,
+ int __turn_on) __THROW;
+
+/* Set the I/O privilege level to LEVEL. If LEVEL>3, permission to
+ access any I/O port is granted. This call requires root
+ privileges. */
+extern int iopl (int __level) __THROW;
+
+#if defined __GNUC__ && __GNUC__ >= 2
+
+static __inline unsigned char
+inb (unsigned short int port)
+{
+ unsigned char _v;
+
+ __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned char
+inb_p (unsigned short int port)
+{
+ unsigned char _v;
+
+ __asm__ __volatile__ ("inb %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned short int
+inw (unsigned short int port)
+{
+ unsigned short _v;
+
+ __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned short int
+inw_p (unsigned short int port)
+{
+ unsigned short int _v;
+
+ __asm__ __volatile__ ("inw %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned int
+inl (unsigned short int port)
+{
+ unsigned int _v;
+
+ __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned int
+inl_p (unsigned short int port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("inl %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline void
+outb (unsigned char value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port));
+}
+
+static __inline void
+outb_p (unsigned char value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outb %b0,%w1\noutb %%al,$0x80": :"a" (value),
+ "Nd" (port));
+}
+
+static __inline void
+outw (unsigned short int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port));
+
+}
+
+static __inline void
+outw_p (unsigned short int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outw %w0,%w1\noutb %%al,$0x80": :"a" (value),
+ "Nd" (port));
+}
+
+static __inline void
+outl (unsigned int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port));
+}
+
+static __inline void
+outl_p (unsigned int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outl %0,%w1\noutb %%al,$0x80": :"a" (value),
+ "Nd" (port));
+}
+
+static __inline void
+insb (unsigned short int port, void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; insb":"=D" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+insw (unsigned short int port, void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; insw":"=D" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+insl (unsigned short int port, void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; insl":"=D" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+outsb (unsigned short int port, const void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; outsb":"=S" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+outsw (unsigned short int port, const void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; outsw":"=S" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+outsl (unsigned short int port, const void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; outsl":"=S" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+#endif /* GNU C */
+
+__END_DECLS
+#endif /* _SYS_IO_H */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sys/perm.h b/libc/sysdeps/unix/sysv/linux/i386/sys/perm.h
new file mode 100644
index 000000000..e389e6679
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sys/perm.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 1996, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PERM_H
+
+#define _SYS_PERM_H 1
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Set port input/output permissions. */
+extern int ioperm (unsigned long int __from, unsigned long int __num,
+ int __turn_on) __THROW;
+
+
+/* Change I/O privilege level. */
+extern int iopl (int __level) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_PERM_H */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sys/procfs.h b/libc/sysdeps/unix/sysv/linux/i386/sys/procfs.h
new file mode 100644
index 000000000..f0be43309
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sys/procfs.h
@@ -0,0 +1,131 @@
+/* Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H 1
+
+/* This is somewhat modelled after the file of the same name on SVR4
+ systems. It provides a definition of the core file format for ELF
+ used on Linux. It doesn't have anything to do with the /proc file
+ system, even though Linux has one.
+
+ Anyway, the whole purpose of this file is for GDB and GDB only.
+ Don't read too much into it. Don't use it for anything other than
+ GDB unless you know what you are doing. */
+
+#include <features.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+__BEGIN_DECLS
+
+/* Type for a general-purpose register. */
+typedef unsigned long elf_greg_t;
+
+/* And the whole bunch of them. We could have used `struct
+ user_regs_struct' directly in the typedef, but tradition says that
+ the register set is an array, which does have some peculiar
+ semantics, so leave it that way. */
+#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* Register set for the floating-point registers. */
+typedef struct user_fpregs_struct elf_fpregset_t;
+
+/* Register set for the extended floating-point registers. Includes
+ the Pentium III SSE registers in addition to the classic
+ floating-point stuff. */
+typedef struct user_fpxregs_struct elf_fpxregset_t;
+
+
+/* Signal info. */
+struct elf_siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_code; /* Extra code. */
+ int si_errno; /* Errno. */
+ };
+
+
+/* Definitions to generate Intel SVR4-like core files. These mostly
+ have the same names as the SVR4 types with "elf_" tacked on the
+ front to prevent clashes with Linux definitions, and the typedef
+ forms have been avoided. This is mostly like the SVR4 structure,
+ but more Linuxy, with things that Linux does not support and which
+ GDB doesn't really use excluded. */
+
+struct elf_prstatus
+ {
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned long int pr_sigpend; /* Set of pending signals. */
+ unsigned long int pr_sighold; /* Set of held signals. */
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct timeval pr_utime; /* User time. */
+ struct timeval pr_stime; /* System time. */
+ struct timeval pr_cutime; /* Cumulative user time. */
+ struct timeval pr_cstime; /* Cumulative system time. */
+ elf_gregset_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+#define ELF_PRARGSZ (80) /* Number of chars for args. */
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long int pr_flag; /* Flags. */
+ unsigned short int pr_uid;
+ unsigned short int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+
+/* The rest of this file provides the types for emulation of the
+ Solaris <proc_service.h> interfaces that should be implemented by
+ users of libthread_db. */
+
+/* Addresses. */
+typedef void *psaddr_t;
+
+/* Register sets. Linux has different names. */
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+ therefore have only one PID type. */
+typedef __pid_t lwpid_t;
+
+/* Process status and info. In the end we do provide typedefs for them. */
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif /* sys/procfs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sys/reg.h b/libc/sysdeps/unix/sysv/linux/i386/sys/reg.h
new file mode 100644
index 000000000..39003c45b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sys/reg.h
@@ -0,0 +1,43 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_REG_H
+#define _SYS_REG_H 1
+
+/* Index into an array of 4 byte integers returned from ptrace for
+ * location of the users' stored general purpose registers. */
+
+#define EBX 0
+#define ECX 1
+#define EDX 2
+#define ESI 3
+#define EDI 4
+#define EBP 5
+#define EAX 6
+#define DS 7
+#define ES 8
+#define FS 9
+#define GS 10
+#define ORIG_EAX 11
+#define EIP 12
+#define CS 13
+#define EFL 14
+#define UESP 15
+#define SS 16
+
+#endif /* _SYS_REG_H */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sys/ucontext.h b/libc/sysdeps/unix/sysv/linux/i386/sys/ucontext.h
new file mode 100644
index 000000000..d6474c722
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sys/ucontext.h
@@ -0,0 +1,129 @@
+/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+
+/* We need the signal context definitions even if they are not used
+ included in <signal.h>. */
+#include <bits/sigcontext.h>
+
+
+/* Type for general register. */
+typedef int greg_t;
+
+/* Number of general registers. */
+#define NGREG 19
+
+/* Container for all general registers. */
+typedef greg_t gregset_t[NGREG];
+
+#ifdef __USE_GNU
+/* Number of each register is the `gregset_t' array. */
+enum
+{
+ REG_GS = 0,
+# define REG_GS REG_GS
+ REG_FS,
+# define REG_FS REG_FS
+ REG_ES,
+# define REG_ES REG_ES
+ REG_DS,
+# define REG_DS REG_DS
+ REG_EDI,
+# define REG_EDI REG_EDI
+ REG_ESI,
+# define REG_ESI REG_ESI
+ REG_EBP,
+# define REG_EBP REG_EBP
+ REG_ESP,
+# define REG_ESP REG_ESP
+ REG_EBX,
+# define REG_EBX REG_EBX
+ REG_EDX,
+# define REG_EDX REG_EDX
+ REG_ECX,
+# define REG_ECX REG_ECX
+ REG_EAX,
+# define REG_EAX REG_EAX
+ REG_TRAPNO,
+# define REG_TRAPNO REG_TRAPNO
+ REG_ERR,
+# define REG_ERR REG_ERR
+ REG_EIP,
+# define REG_EIP REG_EIP
+ REG_CS,
+# define REG_CS REG_CS
+ REG_EFL,
+# define REG_EFL REG_EFL
+ REG_UESP,
+# define REG_UESP REG_UESP
+ REG_SS
+# define REG_SS REG_SS
+};
+#endif
+
+/* Definitions taken from the kernel headers. */
+struct _libc_fpreg
+{
+ unsigned short int significand[4];
+ unsigned short int exponent;
+};
+
+struct _libc_fpstate
+{
+ unsigned long int cw;
+ unsigned long int sw;
+ unsigned long int tag;
+ unsigned long int ipoff;
+ unsigned long int cssel;
+ unsigned long int dataoff;
+ unsigned long int datasel;
+ struct _libc_fpreg _st[8];
+ unsigned long int status;
+};
+
+/* Structure to describe FPU registers. */
+typedef struct _libc_fpstate *fpregset_t;
+
+/* Context to describe whole processor state. */
+typedef struct
+ {
+ gregset_t gregs;
+ /* Due to Linux's history we have to use a pointer here. The SysV/i386
+ ABI requires a struct with the values. */
+ fpregset_t fpregs;
+ unsigned long int oldmask;
+ unsigned long int cr2;
+ } mcontext_t;
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ __sigset_t uc_sigmask;
+ struct _libc_fpstate __fpregs_mem;
+ } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sys/user.h b/libc/sysdeps/unix/sysv/linux/i386/sys/user.h
new file mode 100644
index 000000000..aca46e7d3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sys/user.h
@@ -0,0 +1,103 @@
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H 1
+
+/* The whole purpose of this file is for GDB and GDB only. Don't read
+ too much into it. Don't use it for anything other than GDB unless
+ you know what you are doing. */
+
+struct user_fpregs_struct
+{
+ long int cwd;
+ long int swd;
+ long int twd;
+ long int fip;
+ long int fcs;
+ long int foo;
+ long int fos;
+ long int st_space [20];
+};
+
+struct user_fpxregs_struct
+{
+ unsigned short int cwd;
+ unsigned short int swd;
+ unsigned short int twd;
+ unsigned short int fop;
+ long int fip;
+ long int fcs;
+ long int foo;
+ long int fos;
+ long int mxcsr;
+ long int reserved;
+ long int st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
+ long int xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
+ long int padding[56];
+};
+
+struct user_regs_struct
+{
+ long int ebx;
+ long int ecx;
+ long int edx;
+ long int esi;
+ long int edi;
+ long int ebp;
+ long int eax;
+ long int xds;
+ long int xes;
+ long int xfs;
+ long int xgs;
+ long int orig_eax;
+ long int eip;
+ long int xcs;
+ long int eflags;
+ long int esp;
+ long int xss;
+};
+
+struct user
+{
+ struct user_regs_struct regs;
+ int u_fpvalid;
+ struct user_fpregs_struct i387;
+ unsigned long int u_tsize;
+ unsigned long int u_dsize;
+ unsigned long int u_ssize;
+ unsigned long start_code;
+ unsigned long start_stack;
+ long int signal;
+ int reserved;
+ struct user_regs_struct* u_ar0;
+ struct user_fpregs_struct* u_fpstate;
+ unsigned long int magic;
+ char u_comm [32];
+ int u_debugreg [8];
+};
+
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif /* _SYS_USER_H */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sys/vm86.h b/libc/sysdeps/unix/sysv/linux/i386/sys/vm86.h
new file mode 100644
index 000000000..4c5152c2e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sys/vm86.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 1996, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_VM86_H
+
+#define _SYS_VM86_H 1
+#include <features.h>
+
+/* Get constants and data types from kernel header file. */
+#include <asm/vm86.h>
+
+__BEGIN_DECLS
+
+/* Enter virtual 8086 mode. */
+extern int vm86 (unsigned long int __subfunction,
+ struct vm86plus_struct *__info) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_VM86_H */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/syscall.S b/libc/sysdeps/unix/sysv/linux/i386/syscall.S
new file mode 100644
index 000000000..b569650b2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/syscall.S
@@ -0,0 +1,37 @@
+/* Copyright (C) 1995, 1996, 1998, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* Please consult the file sysdeps/unix/sysv/linux/i386/sysdep.h for
+ more information about the value -4095 used below.*/
+
+ .text
+ENTRY (syscall)
+
+ PUSHARGS_6 /* Save register contents. */
+ _DOARGS_6(44) /* Load arguments. */
+ movl 20(%esp), %eax /* Load syscall number into %eax. */
+ ENTER_KERNEL /* Do the system call. */
+ POPARGS_6 /* Restore register contents. */
+ cmpl $-4095, %eax /* Check %eax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+L(pseudo_end):
+ ret /* Return to caller. */
+
+PSEUDO_END (syscall)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/syscalls.list b/libc/sysdeps/unix/sysv/linux/i386/syscalls.list
new file mode 100644
index 000000000..3ff3a73aa
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/syscalls.list
@@ -0,0 +1,8 @@
+# File name Caller Syscall name Args Strong name Weak names
+
+modify_ldt EXTRA modify_ldt i:ipi __modify_ldt modify_ldt
+vm86old EXTRA vm86old i:p __vm86old vm86@GLIBC_2.0
+vm86 - vm86 i:ip __vm86 vm86@@GLIBC_2.3.4
+oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0
+oldsetrlimit EXTRA setrlimit i:ip __old_setrlimit setrlimit@GLIBC_2.0
+waitpid - waitpid Ci:ipi __waitpid waitpid __libc_waitpid
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sysconf.c b/libc/sysdeps/unix/sysv/linux/i386/sysconf.c
new file mode 100644
index 000000000..25b9ba734
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sysconf.c
@@ -0,0 +1,410 @@
+/* Get file-specific information about a file. Linux version.
+ Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <hp-timing.h>
+
+static long int linux_sysconf (int name);
+
+
+static long int __attribute__ ((noinline))
+handle_i486 (int name)
+{
+ /* The processor only has a unified level 1 cache of 8k. */
+ switch (name)
+ {
+ case _SC_LEVEL1_ICACHE_SIZE:
+ case _SC_LEVEL1_DCACHE_SIZE:
+ return 8 * 1024;
+
+ case _SC_LEVEL1_ICACHE_ASSOC:
+ case _SC_LEVEL1_DCACHE_ASSOC:
+ // XXX Anybody know this?
+ return 0;
+
+ case _SC_LEVEL1_ICACHE_LINESIZE:
+ case _SC_LEVEL1_DCACHE_LINESIZE:
+ // XXX Anybody know for sure?
+ return 16;
+
+ case _SC_LEVEL2_CACHE_SIZE:
+ case _SC_LEVEL2_CACHE_ASSOC:
+ case _SC_LEVEL2_CACHE_LINESIZE:
+ case _SC_LEVEL3_CACHE_SIZE:
+ case _SC_LEVEL3_CACHE_ASSOC:
+ case _SC_LEVEL3_CACHE_LINESIZE:
+ case _SC_LEVEL4_CACHE_SIZE:
+ case _SC_LEVEL4_CACHE_ASSOC:
+ /* Not available. */
+ break;
+
+ default:
+ assert (! "cannot happen");
+ }
+
+ return -1;
+}
+
+
+static const struct intel_02_cache_info
+{
+ unsigned int idx;
+ int name;
+ long int size;
+ long int assoc;
+ long int linesize;
+} intel_02_known[] =
+ {
+ { 0x06, _SC_LEVEL1_ICACHE_SIZE, 8192, 4, 32 },
+ { 0x08, _SC_LEVEL1_ICACHE_SIZE, 16384, 4, 32 },
+ { 0x0a, _SC_LEVEL1_DCACHE_SIZE, 8192, 2, 32 },
+ { 0x0c, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 32 },
+ { 0x22, _SC_LEVEL3_CACHE_SIZE, 524288, 4, 64 },
+ { 0x23, _SC_LEVEL3_CACHE_SIZE, 1048576, 8, 64 },
+ { 0x25, _SC_LEVEL3_CACHE_SIZE, 2097152, 8, 64 },
+ { 0x29, _SC_LEVEL3_CACHE_SIZE, 4194304, 8, 64 },
+ { 0x2c, _SC_LEVEL1_DCACHE_SIZE, 32768, 8, 64 },
+ { 0x30, _SC_LEVEL1_ICACHE_SIZE, 32768, 8, 64 },
+ { 0x39, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 64 },
+ { 0x3a, _SC_LEVEL2_CACHE_SIZE, 196608, 6, 64 },
+ { 0x3b, _SC_LEVEL2_CACHE_SIZE, 131072, 2, 64 },
+ { 0x3c, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 64 },
+ { 0x3d, _SC_LEVEL2_CACHE_SIZE, 393216, 6, 64 },
+ { 0x3e, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 },
+ { 0x41, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 32 },
+ { 0x42, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 32 },
+ { 0x43, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 32 },
+ { 0x44, _SC_LEVEL2_CACHE_SIZE, 1048576, 4, 32 },
+ { 0x45, _SC_LEVEL2_CACHE_SIZE, 2097152, 4, 32 },
+ { 0x46, _SC_LEVEL3_CACHE_SIZE, 4194304, 4, 64 },
+ { 0x47, _SC_LEVEL3_CACHE_SIZE, 8388608, 8, 64 },
+ { 0x49, _SC_LEVEL3_CACHE_SIZE, 4194304, 16, 64 },
+ { 0x4a, _SC_LEVEL3_CACHE_SIZE, 6291456, 12, 64 },
+ { 0x4b, _SC_LEVEL3_CACHE_SIZE, 8388608, 16, 64 },
+ { 0x4c, _SC_LEVEL3_CACHE_SIZE, 12582912, 12, 64 },
+ { 0x4d, _SC_LEVEL3_CACHE_SIZE, 16777216, 16, 64 },
+ { 0x60, _SC_LEVEL1_DCACHE_SIZE, 16384, 8, 64 },
+ { 0x66, _SC_LEVEL1_DCACHE_SIZE, 8192, 4, 64 },
+ { 0x67, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 64 },
+ { 0x68, _SC_LEVEL1_DCACHE_SIZE, 32768, 4, 64 },
+ { 0x78, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 },
+ { 0x79, _SC_LEVEL2_CACHE_SIZE, 131072, 8, 64 },
+ { 0x7a, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 64 },
+ { 0x7b, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 64 },
+ { 0x7c, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 },
+ { 0x7d, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 64 },
+ { 0x7f, _SC_LEVEL2_CACHE_SIZE, 524288, 2, 64 },
+ { 0x82, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 32 },
+ { 0x83, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 32 },
+ { 0x84, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 32 },
+ { 0x85, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 32 },
+ { 0x86, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 },
+ { 0x87, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 },
+ };
+#define nintel_02_known (sizeof (intel_02_known) / sizeof (intel_02_known[0]))
+
+
+static int
+intel_02_known_compare (const void *p1, const void *p2)
+{
+ const struct intel_02_cache_info *i1;
+ const struct intel_02_cache_info *i2;
+
+ i1 = (const struct intel_02_cache_info *) p1;
+ i2 = (const struct intel_02_cache_info *) p2;
+
+ if (i1->idx == i2->idx)
+ return 0;
+
+ return i1->idx < i2->idx ? -1 : 1;
+}
+
+
+static long int
+intel_check_word (int name, unsigned int value, bool *has_level_2,
+ bool *no_level_2_or_3)
+{
+ if ((value & 0x80000000) != 0)
+ /* The register value is reserved. */
+ return 0;
+
+ /* Fold the name. The _SC_ constants are always in the order SIZE,
+ ASSOC, LINESIZE. */
+ int folded_name = (_SC_LEVEL1_ICACHE_SIZE
+ + ((name - _SC_LEVEL1_ICACHE_SIZE) / 3) * 3);
+
+ while (value != 0)
+ {
+ unsigned int byte = value & 0xff;
+
+ if (byte == 0x40)
+ {
+ *no_level_2_or_3 = true;
+
+ if (folded_name == _SC_LEVEL3_CACHE_SIZE)
+ /* No need to look further. */
+ break;
+ }
+ else
+ {
+ struct intel_02_cache_info *found;
+ struct intel_02_cache_info search;
+
+ search.idx = byte;
+ found = bsearch (&search, intel_02_known, nintel_02_known,
+ sizeof (intel_02_known[0]), intel_02_known_compare);
+ if (found != NULL)
+ {
+ if (found->name == folded_name)
+ {
+ unsigned int offset = name - folded_name;
+
+ if (offset == 0)
+ /* Cache size. */
+ return found->size;
+ if (offset == 1)
+ return found->assoc;
+
+ assert (offset == 2);
+ return found->linesize;
+ }
+
+ if (found->name == _SC_LEVEL2_CACHE_SIZE)
+ *has_level_2 = true;
+ }
+ }
+
+ /* Next byte for the next round. */
+ value >>= 8;
+ }
+
+ /* Nothing found. */
+ return 0;
+}
+
+
+static long int __attribute__ ((noinline))
+handle_intel (int name, unsigned int maxidx)
+{
+ if (maxidx < 2)
+ {
+ // XXX Do such processors exist? When we know we can fill in some
+ // values.
+ return 0;
+ }
+
+ /* OK, we can use the CPUID instruction to get all info about the
+ caches. */
+ unsigned int cnt = 0;
+ unsigned int max = 1;
+ long int result = 0;
+ bool no_level_2_or_3 = false;
+ bool has_level_2 = false;
+ while (cnt++ < max)
+ {
+ unsigned int eax;
+ unsigned int ebx;
+ unsigned int ecx;
+ unsigned int edx;
+ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+ : "0" (2));
+
+ /* The low byte of EAX in the first round contain the number of
+ rounds we have to make. At least one, the one we are already
+ doing. */
+ if (cnt == 1)
+ {
+ max = eax & 0xff;
+ eax &= 0xffffff00;
+ }
+
+ /* Process the individual registers' value. */
+ result = intel_check_word (name, eax, &has_level_2, &no_level_2_or_3);
+ if (result != 0)
+ return result;
+
+ result = intel_check_word (name, ebx, &has_level_2, &no_level_2_or_3);
+ if (result != 0)
+ return result;
+
+ result = intel_check_word (name, ecx, &has_level_2, &no_level_2_or_3);
+ if (result != 0)
+ return result;
+
+ result = intel_check_word (name, edx, &has_level_2, &no_level_2_or_3);
+ if (result != 0)
+ return result;
+ }
+
+ if (name >= _SC_LEVEL2_CACHE_SIZE && name <= _SC_LEVEL3_CACHE_LINESIZE
+ && no_level_2_or_3)
+ return -1;
+
+ return 0;
+}
+
+
+static long int __attribute__ ((noinline))
+handle_amd (int name)
+{
+ unsigned int eax;
+ unsigned int ebx;
+ unsigned int ecx;
+ unsigned int edx;
+ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+ : "0" (0x80000000));
+
+ if (name >= _SC_LEVEL3_CACHE_SIZE)
+ return 0;
+
+ unsigned int fn = 0x80000005 + (name >= _SC_LEVEL2_CACHE_SIZE);
+ if (eax < fn)
+ return 0;
+
+ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+ : "0" (fn));
+
+ if (name < _SC_LEVEL1_DCACHE_SIZE)
+ {
+ name += _SC_LEVEL1_DCACHE_SIZE - _SC_LEVEL1_ICACHE_SIZE;
+ ecx = edx;
+ }
+
+ switch (name)
+ {
+ case _SC_LEVEL1_DCACHE_SIZE:
+ return (ecx >> 14) & 0x3fc00;
+ case _SC_LEVEL1_DCACHE_ASSOC:
+ ecx >>= 16;
+ if ((ecx & 0xff) == 0xff)
+ /* Fully associative. */
+ return (ecx << 2) & 0x3fc00;
+ return ecx & 0xff;
+ case _SC_LEVEL1_DCACHE_LINESIZE:
+ return ecx & 0xff;
+ case _SC_LEVEL2_CACHE_SIZE:
+ return (ecx & 0xf000) == 0 ? 0 : (ecx >> 6) & 0x3fffc00;
+ case _SC_LEVEL2_CACHE_ASSOC:
+ ecx >>= 12;
+ switch (ecx & 0xf)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ return ecx & 0xf;
+ case 6:
+ return 8;
+ case 8:
+ return 16;
+ case 0xf:
+ return (ecx << 6) & 0x3fffc00;
+ default:
+ return 0;
+ }
+ case _SC_LEVEL2_CACHE_LINESIZE:
+ return (ecx & 0xf000) == 0 ? 0 : ecx & 0xff;
+ default:
+ assert (! "cannot happen");
+ }
+ return -1;
+}
+
+
+static int
+i386_i486_test (void)
+{
+ int eflags;
+ int ac;
+ asm volatile ("pushfl;\n\t"
+ "popl %0;\n\t"
+ "movl $0x240000, %1;\n\t"
+ "xorl %0, %1;\n\t"
+ "pushl %1;\n\t"
+ "popfl;\n\t"
+ "pushfl;\n\t"
+ "popl %1;\n\t"
+ "xorl %0, %1;\n\t"
+ "pushl %0;\n\t"
+ "popfl"
+ : "=r" (eflags), "=r" (ac));
+
+ return ac;
+}
+
+
+/* Get the value of the system variable NAME. */
+long int
+__sysconf (int name)
+{
+ /* All the remainder, except the cache information, is handled in
+ the generic code. */
+ if (name < _SC_LEVEL1_ICACHE_SIZE || name > _SC_LEVEL4_CACHE_LINESIZE)
+ return linux_sysconf (name);
+
+ /* Recognize i386 and compatible. These don't have any cache on
+ board. */
+ int ac = i386_i486_test ();
+
+ if (ac == 0)
+ /* This is an i386. */
+ // XXX Is this true for all brands?
+ return -1;
+
+ /* Detect i486, the last Intel processor without CPUID. */
+ if ((ac & (1 << 21)) == 0)
+ {
+ /* No CPUID. */
+ // XXX Fill in info about other brands. For now only Intel.
+ return handle_i486 (name);
+ }
+
+ /* Find out what brand of processor. */
+ unsigned int eax;
+ unsigned int ebx;
+ unsigned int ecx;
+ unsigned int edx;
+ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+ : "0" (0));
+
+ /* This spells out "GenuineIntel". */
+ if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)
+ return handle_intel (name, eax);
+
+ /* This spells out "AuthenticAMD". */
+ if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
+ return handle_amd (name);
+
+ // XXX Fill in more vendors.
+
+ /* CPU not known, we have no information. */
+ return 0;
+}
+
+/* Now the generic Linux version. */
+#undef __sysconf
+#define __sysconf static linux_sysconf
+#include "../sysconf.c"
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sysdep.S b/libc/sysdeps/unix/sysv/linux/i386/sysdep.S
new file mode 100644
index 000000000..b8df43cd7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sysdep.S
@@ -0,0 +1,41 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* The following code is only used in the shared library when we
+ compile the reentrant version. Otherwise each system call defines
+ each own version. */
+
+#ifndef PIC
+
+/* The syscall stubs jump here when they detect an error.
+ The code for Linux is almost identical to the canonical Unix/i386
+ code, except that the error number in %eax is negated. */
+
+#undef CALL_MCOUNT
+#define CALL_MCOUNT /* Don't insert the profiling call, it clobbers %eax. */
+
+ .text
+ENTRY (__syscall_error)
+ negl %eax
+
+#define __syscall_error __syscall_error_1
+#include <sysdeps/unix/i386/sysdep.S>
+
+#endif /* !PIC */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/sysdep.h b/libc/sysdeps/unix/sysv/linux/i386/sysdep.h
new file mode 100644
index 000000000..90423d843
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -0,0 +1,581 @@
+/* Copyright (C) 1992,1993,1995-2000,2002-2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINUX_I386_SYSDEP_H
+#define _LINUX_I386_SYSDEP_H 1
+
+/* There is some commonality. */
+#include <sysdeps/unix/i386/sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */
+#include <dl-sysdep.h>
+#include <tls.h>
+
+
+/* For Linux we can use the system call table in the header file
+ /usr/include/asm/unistd.h
+ of the kernel. But these symbols do not follow the SYS_* syntax
+ so we have to redefine the `SYS_ify' macro here. */
+#undef SYS_ify
+#define SYS_ify(syscall_name) __NR_##syscall_name
+
+#if defined USE_DL_SYSINFO \
+ && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# define I386_USE_SYSENTER 1
+#else
+# undef I386_USE_SYSENTER
+#endif
+
+#ifdef __ASSEMBLER__
+
+/* Linux uses a negative return value to indicate syscall errors,
+ unlike most Unices, which use the condition codes' carry flag.
+
+ Since version 2.1 the return value of a system call might be
+ negative even if the call succeeded. E.g., the `lseek' system call
+ might return a large offset. Therefore we must not anymore test
+ for < 0, but test for a real error by making sure the value in %eax
+ is a real error number. Linus said he will make sure the no syscall
+ returns a value in -1 .. -4095 as a valid result so we can savely
+ test with -4095. */
+
+/* We don't want the label for the error handle to be global when we define
+ it here. */
+#ifdef PIC
+# define SYSCALL_ERROR_LABEL 0f
+#else
+# define SYSCALL_ERROR_LABEL syscall_error
+#endif
+
+#undef PSEUDO
+#define PSEUDO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ cmpl $-4095, %eax; \
+ jae SYSCALL_ERROR_LABEL; \
+ L(pseudo_end):
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ SYSCALL_ERROR_HANDLER \
+ END (name)
+
+#undef PSEUDO_NOERRNO
+#define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args)
+
+#undef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(name) \
+ END (name)
+
+#define ret_NOERRNO ret
+
+/* The function has to return the error code. */
+#undef PSEUDO_ERRVAL
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ negl %eax
+
+#undef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(name) \
+ END (name)
+
+#define ret_ERRVAL ret
+
+#ifndef PIC
+# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
+#else
+
+# if RTLD_PRIVATE_ERRNO
+# define SYSCALL_ERROR_HANDLER \
+0:SETUP_PIC_REG(cx); \
+ addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
+ xorl %edx, %edx; \
+ subl %eax, %edx; \
+ movl %edx, rtld_errno@GOTOFF(%ecx); \
+ orl $-1, %eax; \
+ jmp L(pseudo_end);
+
+# elif defined _LIBC_REENTRANT
+
+# if USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+# define SYSCALL_ERROR_HANDLER \
+0:SETUP_PIC_REG (cx); \
+ addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
+ movl SYSCALL_ERROR_ERRNO@GOTNTPOFF(%ecx), %ecx; \
+ xorl %edx, %edx; \
+ subl %eax, %edx; \
+ SYSCALL_ERROR_HANDLER_TLS_STORE (%edx, %ecx); \
+ orl $-1, %eax; \
+ jmp L(pseudo_end);
+# ifndef NO_TLS_DIRECT_SEG_REFS
+# define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff) \
+ movl src, %gs:(destoff)
+# else
+# define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff) \
+ addl %gs:0, destoff; \
+ movl src, (destoff)
+# endif
+# else
+# define SYSCALL_ERROR_HANDLER \
+0:pushl %ebx; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (ebx, 0); \
+ SETUP_PIC_REG (bx); \
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx; \
+ xorl %edx, %edx; \
+ subl %eax, %edx; \
+ pushl %edx; \
+ cfi_adjust_cfa_offset (4); \
+ PUSH_ERRNO_LOCATION_RETURN; \
+ call BP_SYM (__errno_location)@PLT; \
+ POP_ERRNO_LOCATION_RETURN; \
+ popl %ecx; \
+ cfi_adjust_cfa_offset (-4); \
+ popl %ebx; \
+ cfi_adjust_cfa_offset (-4); \
+ cfi_restore (ebx); \
+ movl %ecx, (%eax); \
+ orl $-1, %eax; \
+ jmp L(pseudo_end);
+/* A quick note: it is assumed that the call to `__errno_location' does
+ not modify the stack! */
+# endif
+# else
+/* Store (- %eax) into errno through the GOT. */
+# define SYSCALL_ERROR_HANDLER \
+0:SETUP_PIC_REG(cx); \
+ addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
+ xorl %edx, %edx; \
+ subl %eax, %edx; \
+ movl errno@GOT(%ecx), %ecx; \
+ movl %edx, (%ecx); \
+ orl $-1, %eax; \
+ jmp L(pseudo_end);
+# endif /* _LIBC_REENTRANT */
+#endif /* PIC */
+
+
+/* The original calling convention for system calls on Linux/i386 is
+ to use int $0x80. */
+#ifdef I386_USE_SYSENTER
+# ifdef SHARED
+# define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
+# else
+# define ENTER_KERNEL call *_dl_sysinfo
+# endif
+#else
+# define ENTER_KERNEL int $0x80
+#endif
+
+/* Linux takes system call arguments in registers:
+
+ syscall number %eax call-clobbered
+ arg 1 %ebx call-saved
+ arg 2 %ecx call-clobbered
+ arg 3 %edx call-clobbered
+ arg 4 %esi call-saved
+ arg 5 %edi call-saved
+
+ The stack layout upon entering the function is:
+
+ 20(%esp) Arg# 5
+ 16(%esp) Arg# 4
+ 12(%esp) Arg# 3
+ 8(%esp) Arg# 2
+ 4(%esp) Arg# 1
+ (%esp) Return address
+
+ (Of course a function with say 3 arguments does not have entries for
+ arguments 4 and 5.)
+
+ The following code tries hard to be optimal. A general assumption
+ (which is true according to the data books I have) is that
+
+ 2 * xchg is more expensive than pushl + movl + popl
+
+ Beside this a neat trick is used. The calling conventions for Linux
+ tell that among the registers used for parameters %ecx and %edx need
+ not be saved. Beside this we may clobber this registers even when
+ they are not used for parameter passing.
+
+ As a result one can see below that we save the content of the %ebx
+ register in the %edx register when we have less than 3 arguments
+ (2 * movl is less expensive than pushl + popl).
+
+ Second unlike for the other registers we don't save the content of
+ %ecx and %edx when we have more than 1 and 2 registers resp.
+
+ The code below might look a bit long but we have to take care for
+ the pipelined processors (i586). Here the `pushl' and `popl'
+ instructions are marked as NP (not pairable) but the exception is
+ two consecutive of these instruction. This gives no penalty on
+ other processors though. */
+
+#undef DO_CALL
+#define DO_CALL(syscall_name, args) \
+ PUSHARGS_##args \
+ DOARGS_##args \
+ movl $SYS_ify (syscall_name), %eax; \
+ ENTER_KERNEL \
+ POPARGS_##args
+
+#define PUSHARGS_0 /* No arguments to push. */
+#define DOARGS_0 /* No arguments to frob. */
+#define POPARGS_0 /* No arguments to pop. */
+#define _PUSHARGS_0 /* No arguments to push. */
+#define _DOARGS_0(n) /* No arguments to frob. */
+#define _POPARGS_0 /* No arguments to pop. */
+
+#define PUSHARGS_1 movl %ebx, %edx; L(SAVEBX1): PUSHARGS_0
+#define DOARGS_1 _DOARGS_1 (4)
+#define POPARGS_1 POPARGS_0; movl %edx, %ebx; L(RESTBX1):
+#define _PUSHARGS_1 pushl %ebx; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (ebx, 0); L(PUSHBX1): _PUSHARGS_0
+#define _DOARGS_1(n) movl n(%esp), %ebx; _DOARGS_0(n-4)
+#define _POPARGS_1 _POPARGS_0; popl %ebx; cfi_adjust_cfa_offset (-4); \
+ cfi_restore (ebx); L(POPBX1):
+
+#define PUSHARGS_2 PUSHARGS_1
+#define DOARGS_2 _DOARGS_2 (8)
+#define POPARGS_2 POPARGS_1
+#define _PUSHARGS_2 _PUSHARGS_1
+#define _DOARGS_2(n) movl n(%esp), %ecx; _DOARGS_1 (n-4)
+#define _POPARGS_2 _POPARGS_1
+
+#define PUSHARGS_3 _PUSHARGS_2
+#define DOARGS_3 _DOARGS_3 (16)
+#define POPARGS_3 _POPARGS_3
+#define _PUSHARGS_3 _PUSHARGS_2
+#define _DOARGS_3(n) movl n(%esp), %edx; _DOARGS_2 (n-4)
+#define _POPARGS_3 _POPARGS_2
+
+#define PUSHARGS_4 _PUSHARGS_4
+#define DOARGS_4 _DOARGS_4 (24)
+#define POPARGS_4 _POPARGS_4
+#define _PUSHARGS_4 pushl %esi; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (esi, 0); L(PUSHSI1): _PUSHARGS_3
+#define _DOARGS_4(n) movl n(%esp), %esi; _DOARGS_3 (n-4)
+#define _POPARGS_4 _POPARGS_3; popl %esi; cfi_adjust_cfa_offset (-4); \
+ cfi_restore (esi); L(POPSI1):
+
+#define PUSHARGS_5 _PUSHARGS_5
+#define DOARGS_5 _DOARGS_5 (32)
+#define POPARGS_5 _POPARGS_5
+#define _PUSHARGS_5 pushl %edi; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (edi, 0); L(PUSHDI1): _PUSHARGS_4
+#define _DOARGS_5(n) movl n(%esp), %edi; _DOARGS_4 (n-4)
+#define _POPARGS_5 _POPARGS_4; popl %edi; cfi_adjust_cfa_offset (-4); \
+ cfi_restore (edi); L(POPDI1):
+
+#define PUSHARGS_6 _PUSHARGS_6
+#define DOARGS_6 _DOARGS_6 (36)
+#define POPARGS_6 _POPARGS_6
+#define _PUSHARGS_6 pushl %ebp; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (ebp, 0); L(PUSHBP1): _PUSHARGS_5
+#define _DOARGS_6(n) movl n(%esp), %ebp; _DOARGS_5 (n-4)
+#define _POPARGS_6 _POPARGS_5; popl %ebp; cfi_adjust_cfa_offset (-4); \
+ cfi_restore (ebp); L(POPBP1):
+
+#else /* !__ASSEMBLER__ */
+
+/* We need some help from the assembler to generate optimal code. We
+ define some macros here which later will be used. */
+asm (".L__X'%ebx = 1\n\t"
+ ".L__X'%ecx = 2\n\t"
+ ".L__X'%edx = 2\n\t"
+ ".L__X'%eax = 3\n\t"
+ ".L__X'%esi = 3\n\t"
+ ".L__X'%edi = 3\n\t"
+ ".L__X'%ebp = 3\n\t"
+ ".L__X'%esp = 3\n\t"
+ ".macro bpushl name reg\n\t"
+ ".if 1 - \\name\n\t"
+ ".if 2 - \\name\n\t"
+ "error\n\t"
+ ".else\n\t"
+ "xchgl \\reg, %ebx\n\t"
+ ".endif\n\t"
+ ".endif\n\t"
+ ".endm\n\t"
+ ".macro bpopl name reg\n\t"
+ ".if 1 - \\name\n\t"
+ ".if 2 - \\name\n\t"
+ "error\n\t"
+ ".else\n\t"
+ "xchgl \\reg, %ebx\n\t"
+ ".endif\n\t"
+ ".endif\n\t"
+ ".endm\n\t");
+
+/* Define a macro which expands inline into the wrapper code for a system
+ call. */
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+ ({ \
+ unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args); \
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0)) \
+ { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, )); \
+ resultvar = 0xffffffff; \
+ } \
+ (int) resultvar; })
+
+/* Define a macro which expands inline into the wrapper code for a system
+ call. This use is for internal calls that do not need to handle errors
+ normally. It will never touch errno. This returns just what the kernel
+ gave back.
+
+ The _NCS variant allows non-constant syscall numbers but it is not
+ possible to use more than four parameters. */
+#undef INTERNAL_SYSCALL
+#ifdef I386_USE_SYSENTER
+# ifdef SHARED
+# define INTERNAL_SYSCALL(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_##nr \
+ "movl %1, %%eax\n\t" \
+ "call *%%gs:%P2\n\t" \
+ RESTOREARGS_##nr \
+ : "=a" (resultvar) \
+ : "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \
+ ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_##nr \
+ "call *%%gs:%P2\n\t" \
+ RESTOREARGS_##nr \
+ : "=a" (resultvar) \
+ : "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \
+ ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
+# else
+# define INTERNAL_SYSCALL(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_##nr \
+ "movl %1, %%eax\n\t" \
+ "call *_dl_sysinfo\n\t" \
+ RESTOREARGS_##nr \
+ : "=a" (resultvar) \
+ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_##nr \
+ "call *_dl_sysinfo\n\t" \
+ RESTOREARGS_##nr \
+ : "=a" (resultvar) \
+ : "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
+# endif
+#else
+# define INTERNAL_SYSCALL(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_##nr \
+ "movl %1, %%eax\n\t" \
+ "int $0x80\n\t" \
+ RESTOREARGS_##nr \
+ : "=a" (resultvar) \
+ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_##nr \
+ "int $0x80\n\t" \
+ RESTOREARGS_##nr \
+ : "=a" (resultvar) \
+ : "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
+#endif
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((unsigned int) (val) >= 0xfffff001u)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+
+#define LOADARGS_0
+#ifdef __PIC__
+# if defined I386_USE_SYSENTER && defined SHARED
+# define LOADARGS_1 \
+ "bpushl .L__X'%k3, %k3\n\t"
+# define LOADARGS_5 \
+ "movl %%ebx, %4\n\t" \
+ "movl %3, %%ebx\n\t"
+# else
+# define LOADARGS_1 \
+ "bpushl .L__X'%k2, %k2\n\t"
+# define LOADARGS_5 \
+ "movl %%ebx, %3\n\t" \
+ "movl %2, %%ebx\n\t"
+# endif
+# define LOADARGS_2 LOADARGS_1
+# define LOADARGS_3 \
+ "xchgl %%ebx, %%edi\n\t"
+# define LOADARGS_4 LOADARGS_3
+#else
+# define LOADARGS_1
+# define LOADARGS_2
+# define LOADARGS_3
+# define LOADARGS_4
+# define LOADARGS_5
+#endif
+
+#define RESTOREARGS_0
+#ifdef __PIC__
+# if defined I386_USE_SYSENTER && defined SHARED
+# define RESTOREARGS_1 \
+ "bpopl .L__X'%k3, %k3\n\t"
+# define RESTOREARGS_5 \
+ "movl %4, %%ebx"
+# else
+# define RESTOREARGS_1 \
+ "bpopl .L__X'%k2, %k2\n\t"
+# define RESTOREARGS_5 \
+ "movl %3, %%ebx"
+# endif
+# define RESTOREARGS_2 RESTOREARGS_1
+# define RESTOREARGS_3 \
+ "xchgl %%edi, %%ebx\n\t"
+# define RESTOREARGS_4 RESTOREARGS_3
+#else
+# define RESTOREARGS_1
+# define RESTOREARGS_2
+# define RESTOREARGS_3
+# define RESTOREARGS_4
+# define RESTOREARGS_5
+#endif
+
+#define ASMFMT_0()
+#ifdef __PIC__
+# define ASMFMT_1(arg1) \
+ , "cd" (arg1)
+# define ASMFMT_2(arg1, arg2) \
+ , "d" (arg1), "c" (arg2)
+# define ASMFMT_3(arg1, arg2, arg3) \
+ , "D" (arg1), "c" (arg2), "d" (arg3)
+# define ASMFMT_4(arg1, arg2, arg3, arg4) \
+ , "D" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
+# define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
+ , "0" (arg1), "m" (_xv), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
+#else
+# define ASMFMT_1(arg1) \
+ , "b" (arg1)
+# define ASMFMT_2(arg1, arg2) \
+ , "b" (arg1), "c" (arg2)
+# define ASMFMT_3(arg1, arg2, arg3) \
+ , "b" (arg1), "c" (arg2), "d" (arg3)
+# define ASMFMT_4(arg1, arg2, arg3, arg4) \
+ , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
+# define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
+ , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
+#endif
+
+#define EXTRAVAR_0
+#define EXTRAVAR_1
+#define EXTRAVAR_2
+#define EXTRAVAR_3
+#define EXTRAVAR_4
+#ifdef __PIC__
+# define EXTRAVAR_5 int _xv;
+#else
+# define EXTRAVAR_5
+#endif
+
+/* Consistency check for position-independent code. */
+#ifdef __PIC__
+# define check_consistency() \
+ ({ int __res; \
+ __asm__ __volatile__ \
+ ("call __i686.get_pc_thunk.cx;" \
+ "addl $_GLOBAL_OFFSET_TABLE_, %%ecx;" \
+ "subl %%ebx, %%ecx;" \
+ "je 1f;" \
+ "ud2;" \
+ "1:\n" \
+ ".section .gnu.linkonce.t.__i686.get_pc_thunk.cx,\"ax\",@progbits;" \
+ ".globl __i686.get_pc_thunk.cx;" \
+ ".hidden __i686.get_pc_thunk.cx;" \
+ ".type __i686.get_pc_thunk.cx,@function;" \
+ "__i686.get_pc_thunk.cx:" \
+ "movl (%%esp), %%ecx;" \
+ "ret;" \
+ ".previous" \
+ : "=c" (__res)); \
+ __res; })
+#endif
+
+#endif /* __ASSEMBLER__ */
+
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. Using a global variable
+ is too complicated here since we have no PC-relative addressing mode. */
+#else
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(reg) xorl %gs:POINTER_GUARD, reg
+# define PTR_DEMANGLE(reg) PTR_MANGLE (reg)
+# else
+# define PTR_MANGLE(var) asm ("xorl %%gs:%c2, %0" \
+ : "=r" (var) \
+ : "0" (var), \
+ "i" (offsetof (tcbhead_t, \
+ pointer_guard)))
+# define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#endif
+
+#endif /* linux/i386/sysdep.h */
diff --git a/libc/sysdeps/unix/sysv/linux/i386/ucontext_i.sym b/libc/sysdeps/unix/sysv/linux/i386/ucontext_i.sym
new file mode 100644
index 000000000..b11a5509c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/ucontext_i.sym
@@ -0,0 +1,30 @@
+#include <stddef.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+--
+
+SIG_BLOCK
+SIG_SETMASK
+
+#define ucontext(member) offsetof (ucontext_t, member)
+#define mcontext(member) ucontext (uc_mcontext.member)
+#define mreg(reg) mcontext (gregs[REG_##reg])
+
+oLINK ucontext (uc_link)
+oSS_SP ucontext (uc_stack.ss_sp)
+oSS_SIZE ucontext (uc_stack.ss_size)
+oGS mreg (GS)
+oFS mreg (FS)
+oEDI mreg (EDI)
+oESI mreg (ESI)
+oEBP mreg (EBP)
+oESP mreg (ESP)
+oEBX mreg (EBX)
+oEDX mreg (EDX)
+oECX mreg (ECX)
+oEAX mreg (EAX)
+oEIP mreg (EIP)
+oFPREGS mcontext (fpregs)
+oSIGMASK ucontext (uc_sigmask)
+oFPREGSMEM ucontext (__fpregs_mem)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/versionsort64.c b/libc/sysdeps/unix/sysv/linux/i386/versionsort64.c
new file mode 100644
index 000000000..3efce692f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/versionsort64.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1992, 1997, 1998, 2000, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dirent.h>
+#include <string.h>
+
+int
+__versionsort64 (const void *a, const void *b)
+{
+ return __strverscmp ((*(const struct dirent64 **) a)->d_name,
+ (*(const struct dirent64 **) b)->d_name);
+}
+
+#include <shlib-compat.h>
+
+versioned_symbol (libc, __versionsort64, versionsort64, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+int
+__old_versionsort64 (const void *a, const void *b);
+
+int
+attribute_compat_text_section
+__old_versionsort64 (const void *a, const void *b)
+{
+ return __strverscmp ((*(const struct __old_dirent64 **) a)->d_name,
+ (*(const struct __old_dirent64 **) b)->d_name);
+}
+
+compat_symbol (libc, __old_versionsort64, versionsort64, GLIBC_2_1);
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/i386/vfork.S b/libc/sysdeps/unix/sysv/linux/i386/vfork.S
new file mode 100644
index 000000000..eefd4b49c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/vfork.S
@@ -0,0 +1,88 @@
+/* Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Schwab <schwab@gnu.org>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+
+#ifdef __NR_vfork
+
+ /* Pop the return PC value into ECX. */
+ popl %ecx
+ cfi_adjust_cfa_offset (-4)
+
+#ifdef SAVE_PID
+ SAVE_PID
+#endif
+
+ /* Stuff the syscall number in EAX and enter into the kernel. */
+ movl $SYS_ify (vfork), %eax
+ int $0x80
+
+ /* Jump to the return PC. Don't jump directly since this
+ disturbs the branch target cache. Instead push the return
+ address back on the stack. */
+ pushl %ecx
+ cfi_adjust_cfa_offset (4)
+
+#ifdef RESTORE_PID
+ RESTORE_PID
+#endif
+
+ cmpl $-4095, %eax
+ /* Branch forward if it failed. */
+# ifdef __ASSUME_VFORK_SYSCALL
+ jae SYSCALL_ERROR_LABEL
+.Lpseudo_end:
+# else
+ jae .Lerror
+# endif
+
+ ret
+
+# ifndef __ASSUME_VFORK_SYSCALL
+.Lerror:
+ /* Check if vfork syscall is known at all. */
+ cmpl $-ENOSYS, %eax
+ jne SYSCALL_ERROR_LABEL
+# endif
+#endif
+
+#ifndef __ASSUME_VFORK_SYSCALL
+ /* If we don't have vfork, fork is close enough. */
+
+ movl $SYS_ify (fork), %eax
+ int $0x80
+ cmpl $-4095, %eax
+ jae SYSCALL_ERROR_LABEL
+.Lpseudo_end:
+ ret
+#endif
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libc/sysdeps/unix/sysv/linux/i386/xstat.c b/libc/sysdeps/unix/sysv/linux/i386/xstat.c
new file mode 100644
index 000000000..d27ecd312
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/i386/xstat.c
@@ -0,0 +1,99 @@
+/* xstat using old-style Unix stat system call.
+ Copyright (C) 1991,95,96,97,98,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ho hum, if xstat == xstat64 we must get rid of the prototype or gcc
+ will complain since they don't strictly match. */
+#define __xstat64 __xstat64_disable
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#include <xstatconv.h>
+
+#ifdef __NR_stat64
+# if __ASSUME_STAT64_SYSCALL == 0
+/* The variable is shared between all wrappers around *stat64 calls. */
+extern int __have_no_stat64;
+# endif
+#endif
+
+
+/* Get information about the file NAME in BUF. */
+int
+__xstat (int vers, const char *name, struct stat *buf)
+{
+#if __ASSUME_STAT64_SYSCALL == 0
+ struct kernel_stat kbuf;
+#endif
+ int result;
+
+ if (vers == _STAT_VER_KERNEL)
+ return INLINE_SYSCALL (stat, 2, CHECK_STRING (name), CHECK_1 ((struct kernel_stat *) buf));
+
+#if __ASSUME_STAT64_SYSCALL > 0
+ {
+ struct stat64 buf64;
+
+ result = INLINE_SYSCALL (stat64, 2, CHECK_STRING (name), __ptrvalue (&buf64));
+ if (result == 0)
+ result = __xstat32_conv (vers, &buf64, buf);
+ return result;
+ }
+#else
+# if defined __NR_stat64
+ /* To support 32 bit UIDs, we have to use stat64. The normal stat call only returns
+ 16 bit UIDs. */
+ if (! __have_no_stat64)
+ {
+ struct stat64 buf64;
+
+ result = INLINE_SYSCALL (stat64, 2, CHECK_STRING (name), __ptrvalue (&buf64));
+
+ if (result == 0)
+ result = __xstat32_conv (vers, &buf64, buf);
+
+ if (result != -1 || errno != ENOSYS)
+ return result;
+
+ __have_no_stat64 = 1;
+ }
+# endif
+ result = INLINE_SYSCALL (stat, 2, CHECK_STRING (name), __ptrvalue (&kbuf));
+ if (result == 0)
+ result = __xstat_conv (vers, &kbuf, buf);
+
+ return result;
+#endif /* __ASSUME_STAT64_SYSCALL */
+}
+hidden_def (__xstat)
+weak_alias (__xstat, _xstat);
+#ifdef XSTAT_IS_XSTAT64
+# undef __xstat64
+strong_alias (__xstat, __xstat64);
+hidden_ver (__xstat, __xstat64)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/Implies b/libc/sysdeps/unix/sysv/linux/ia64/Implies
new file mode 100644
index 000000000..8d91c8009
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/Implies
@@ -0,0 +1 @@
+unix/sysv/linux/wordsize-64
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/Makefile b/libc/sysdeps/unix/sysv/linux/ia64/Makefile
new file mode 100644
index 000000000..d9a35a7c6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/Makefile
@@ -0,0 +1,27 @@
+ifeq ($(subdir),misc)
+sysdep_headers += sys/rse.h
+endif
+
+ifeq ($(subdir),stdlib)
+sysdep_routines += __start_context
+gen-as-const-headers += sigcontext-offsets.sym
+endif
+
+ifeq ($(subdir),misc)
+sysdep_headers += sys/io.h
+sysdep_routines += ioperm clone2
+endif
+
+ifeq ($(subdir),elf)
+sysdep-dl-routines += dl-static
+sysdep_routines += $(sysdep-dl-routines)
+sysdep-rtld-routines += $(sysdep-dl-routines)
+endif
+
+ifeq ($(subdir),rt)
+librt-routines += rt-sysdep
+endif
+
+# This is a crude attempt to silence the compiler which complains about
+# then 'current' definition in the kernel headers.
+CPPFLAGS += -D_ASM_IA64_CURRENT_H
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/Versions b/libc/sysdeps/unix/sysv/linux/ia64/Versions
new file mode 100644
index 000000000..13d710a07
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/Versions
@@ -0,0 +1,25 @@
+ld {
+ GLIBC_PRIVATE {
+ _dl_var_init;
+ }
+}
+libc {
+ GLIBC_2.2 {
+ ioperm; iopl;
+ inb; inw; inl;
+ _inb; _inw; _inl;
+ outb; outw; _outl;
+ _outb; _outw; _outl;
+ pciconfig_read; pciconfig_write;
+
+ # linuxthreads
+ __clone2;
+ }
+ GLIBC_2.2.2 {
+ # w*
+ wordexp;
+ }
+ GLIBC_2.2.6 {
+ getunwind;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S b/libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S
new file mode 100644
index 000000000..aa18fadf9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S
@@ -0,0 +1,163 @@
+/* Copyright (C) 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA.
+
+ Note that __sigsetjmp() did NOT flush the register stack. Instead,
+ we do it here since __longjmp() is usually much less frequently
+ invoked than __sigsetjmp(). The only difficulty is that __sigsetjmp()
+ didn't (and wouldn't be able to) save ar.rnat either. This is a problem
+ because if we're not careful, we could end up loading random NaT bits.
+ There are two cases:
+
+ (i) ar.bsp < ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+ ar.rnat contains the desired bits---preserve ar.rnat
+ across loadrs and write to ar.bspstore
+
+ (ii) ar.bsp >= ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+ The desired ar.rnat is stored in
+ ia64_rse_rnat_addr(jmpbuf.ar_bsp). Load those
+ bits into ar.rnat after setting ar.bspstore. */
+
+#include <sysdep.h>
+#include <features.h>
+
+# define pPos p6 /* is rotate count positive? */
+# define pNeg p7 /* is rotate count negative? */
+
+
+ /* __longjmp(__jmp_buf buf, int val) */
+
+LEAF(__longjmp)
+ alloc r8=ar.pfs,2,1,0,0
+ mov r27=ar.rsc
+ add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr
+ ;;
+ ld8 r8=[r2],-16 // r8 <- orig_jmp_buf_addr
+ mov r10=ar.bsp
+ and r11=~0x3,r27 // clear ar.rsc.mode
+ ;;
+ flushrs // flush dirty regs to backing store (must be first in insn grp)
+ ld8 r23=[r2],8 // r23 <- jmpbuf.ar_bsp
+ sub r8=r8,in0 // r8 <- &orig_jmpbuf - &jmpbuf
+ ;;
+ ld8 r25=[r2] // r25 <- jmpbuf.ar_unat
+ extr.u r8=r8,3,6 // r8 <- (&orig_jmpbuf - &jmpbuf)/8 & 0x3f
+ ;;
+ cmp.lt pNeg,pPos=r8,r0
+ mov r2=in0
+ ;;
+(pPos) mov r16=r8
+(pNeg) add r16=64,r8
+(pPos) sub r17=64,r8
+(pNeg) sub r17=r0,r8
+ ;;
+ mov ar.rsc=r11 // put RSE in enforced lazy mode
+ shr.u r8=r25,r16
+ add r3=8,in0 // r3 <- &jmpbuf.r1
+ shl r9=r25,r17
+ ;;
+ or r25=r8,r9
+ ;;
+ mov r26=ar.rnat
+ mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12)
+ ;;
+ ld8.fill.nta sp=[r2],16 // r12 (sp)
+ ld8.fill.nta gp=[r3],16 // r1 (gp)
+ dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+ ;;
+ ld8.nta r16=[r2],16 // caller's unat
+ ld8.nta r17=[r3],16 // fpsr
+ ;;
+ ld8.fill.nta r4=[r2],16 // r4
+ ld8.fill.nta r5=[r3],16 // r5 (gp)
+ cmp.geu p8,p0=r10,r11 // p8 <- (ar.bsp >= jmpbuf.ar_bsp)
+ ;;
+ ld8.fill.nta r6=[r2],16 // r6
+ ld8.fill.nta r7=[r3],16 // r7
+ ;;
+ mov ar.unat=r16 // restore caller's unat
+ mov ar.fpsr=r17 // restore fpsr
+ ;;
+ ld8.nta r16=[r2],16 // b0
+ ld8.nta r17=[r3],16 // b1
+ ;;
+(p8) ld8 r26=[r11] // r26 <- *ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+ mov ar.bspstore=r23 // restore ar.bspstore
+ ;;
+ ld8.nta r18=[r2],16 // b2
+ ld8.nta r19=[r3],16 // b3
+ ;;
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (r16, r24)
+#endif
+ ld8.nta r20=[r2],16 // b4
+ ld8.nta r21=[r3],16 // b5
+ ;;
+ ld8.nta r11=[r2],16 // ar.pfs
+ ld8.nta r22=[r3],56 // ar.lc
+ ;;
+ ld8.nta r24=[r2],32 // pr
+ mov b0=r16
+ ;;
+ ldf.fill.nta f2=[r2],32
+ ldf.fill.nta f3=[r3],32
+ mov b1=r17
+ ;;
+ ldf.fill.nta f4=[r2],32
+ ldf.fill.nta f5=[r3],32
+ mov b2=r18
+ ;;
+ ldf.fill.nta f16=[r2],32
+ ldf.fill.nta f17=[r3],32
+ mov b3=r19
+ ;;
+ ldf.fill.nta f18=[r2],32
+ ldf.fill.nta f19=[r3],32
+ mov b4=r20
+ ;;
+ ldf.fill.nta f20=[r2],32
+ ldf.fill.nta f21=[r3],32
+ mov b5=r21
+ ;;
+ ldf.fill.nta f22=[r2],32
+ ldf.fill.nta f23=[r3],32
+ mov ar.lc=r22
+ ;;
+ ldf.fill.nta f24=[r2],32
+ ldf.fill.nta f25=[r3],32
+ cmp.eq p8,p9=0,in1
+ ;;
+ ldf.fill.nta f26=[r2],32
+ ldf.fill.nta f27=[r3],32
+ mov ar.pfs=r11
+ ;;
+ ldf.fill.nta f28=[r2],32
+ ldf.fill.nta f29=[r3],32
+ ;;
+ ldf.fill.nta f30=[r2]
+ ldf.fill.nta f31=[r3]
+(p8) mov r8=1
+
+ mov ar.rnat=r26 // restore ar.rnat
+ ;;
+ mov ar.rsc=r27 // restore ar.rsc
+(p9) mov r8=in1
+
+ invala // virt. -> phys. regnum mapping may change
+ mov pr=r24,-1
+ ret
+END(__longjmp)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/__start_context.S b/libc/sysdeps/unix/sysv/linux/ia64/__start_context.S
new file mode 100644
index 000000000..519bd252b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/__start_context.S
@@ -0,0 +1,52 @@
+/* Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <features.h>
+
+/* When a context set up by __makecontext() is activated, control
+ transfers to __start_context. When we get here:
+
+ b1 = entry point of function to call
+ in0 = address of UCP to resume after function returns
+ in1 = global pointer for __start_context
+ out0 .. outN = arguments for function */
+
+ENTRY(__start_context)
+ .prologue
+ alloc r2 = ar.pfs, 2, 0, 8, 0
+
+ .save rp, r4 // terminate call chain with a NULL rp
+ mov r4 = r0
+ ;;
+
+ .body
+ br.call.sptk rp = b1
+1:
+ mov gp = in1 // restore gp
+ cmp.ne p6,p0 = in0, r0 // uc_link != 0 ?
+ ;;
+(p6) mov out0 = in0
+(p6) br.call.sptk rp = __setcontext
+.Lexit:
+ mov out0 = 0
+ br.call.sptk rp = HIDDEN_JUMPTARGET(exit)
+
+1: br.cond.sptk .Lexit
+END(__start_context)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/endian.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/endian.h
new file mode 100644
index 000000000..98a5e2399
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/endian.h
@@ -0,0 +1,7 @@
+/* Linux/ia64 is little-endian. */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/fcntl.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/fcntl.h
new file mode 100644
index 000000000..ef66d465d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/fcntl.h
@@ -0,0 +1,230 @@
+/* O_*, F_*, FD_* bit values for Linux/IA64.
+ Copyright (C) 1999, 2000, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+
+#include <sys/types.h>
+#ifdef __USE_GNU
+# include <bits/uio.h>
+#endif
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_ACCMODE 0003
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+#define O_CREAT 0100 /* not fcntl */
+#define O_EXCL 0200 /* not fcntl */
+#define O_NOCTTY 0400 /* not fcntl */
+#define O_TRUNC 01000 /* not fcntl */
+#define O_APPEND 02000
+#define O_NONBLOCK 04000
+#define O_NDELAY O_NONBLOCK
+#define O_SYNC 010000
+#define O_FSYNC O_SYNC
+#define O_ASYNC 020000
+
+#ifdef __USE_GNU
+# define O_DIRECT 040000
+# define O_DIRECTORY 0200000 /* must be a directory */
+# define O_NOFOLLOW 0400000 /* don't follow links */
+# define O_NOATIME 01000000 /* Do not set atime. */
+#endif
+
+#ifdef __USE_LARGEFILE64
+/* Not necessary, files are always with 64bit off_t. */
+# define O_LARGEFILE 0
+#endif
+
+/* For now Linux has synchronisity options for data and read operations.
+ We define the symbols here but let them do the same as O_SYNC since
+ this is a superset. */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC O_SYNC /* Synchronize data. */
+# define O_RSYNC O_SYNC /* Synchronize read operations. */
+#endif
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#define F_GETLK 5 /* Get record locking info. */
+#define F_SETLK 6 /* Set record locking info (non-blocking). */
+#define F_SETLKW 7 /* Set record locking info (blocking). */
+
+/* Not necessary, we always have 64-bit offsets. */
+#define F_GETLK64 5 /* Get record locking info. */
+#define F_SETLK64 6 /* Set record locking info (non-blocking). */
+#define F_SETLKW64 7 /* Set record locking info (blocking). */
+
+#if defined __USE_BSD || defined __USE_UNIX98
+# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */
+# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETSIG 10 /* Set number of signal to be sent. */
+# define F_GETSIG 11 /* Get number of signal to be sent. */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETLEASE 1024 /* Set a lease. */
+# define F_GETLEASE 1025 /* Enquire what lease is active. */
+# define F_NOTIFY 1026 /* Request notfications on a directory. */
+#endif
+
+/* For F_[GET|SET]FD. */
+#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
+#define F_RDLCK 0 /* Read lock. */
+#define F_WRLCK 1 /* Write lock. */
+#define F_UNLCK 2 /* Remove lock. */
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK 4 /* or 3 */
+#define F_SHLCK 8 /* or 4 */
+
+#ifdef __USE_BSD
+/* Operations for bsd flock(), also used by the kernel implementation */
+# define LOCK_SH 1 /* shared lock */
+# define LOCK_EX 2 /* exclusive lock */
+# define LOCK_NB 4 /* or'd with one of the above to prevent
+ blocking */
+# define LOCK_UN 8 /* remove lock */
+#endif
+
+#ifdef __USE_GNU
+# define LOCK_MAND 32 /* This is a mandatory flock: */
+# define LOCK_READ 64 /* ... which allows concurrent read operations. */
+# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */
+# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */
+#endif
+
+
+#ifdef __USE_GNU
+/* Types of directory notifications that may be requested with F_NOTIFY. */
+# define DN_ACCESS 0x00000001 /* File accessed. */
+# define DN_MODIFY 0x00000002 /* File modified. */
+# define DN_CREATE 0x00000004 /* File created. */
+# define DN_DELETE 0x00000008 /* File removed. */
+# define DN_RENAME 0x00000010 /* File renamed. */
+# define DN_ATTRIB 0x00000020 /* File changed attibutes. */
+# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */
+#endif
+
+/* We don't need to support __USE_FILE_OFFSET64. */
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+#endif
+
+
+/* Define some more compatibility macros to be backward compatible with
+ BSD systems which did not managed to hide these kernel macros. */
+#ifdef __USE_BSD
+# define FAPPEND O_APPEND
+# define FFSYNC O_FSYNC
+# define FASYNC O_ASYNC
+# define FNONBLOCK O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif /* Use BSD. */
+
+/* Advise to `posix_fadvise'. */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
+# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
+#endif
+
+
+#ifdef __USE_GNU
+/* Flags for SYNC_FILE_RANGE. */
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+
+/* Flags for SPLICE and VMSPLICE. */
+# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */
+# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing
+ (but we may still block on the fd
+ we splice from/to). */
+# define SPLICE_F_MORE 4 /* Expect more data. */
+# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
+#endif
+
+__BEGIN_DECLS
+
+#ifdef __USE_GNU
+
+/* Provide kernel hint to read ahead. */
+extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
+ __THROW;
+
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice address range into a pipe. */
+extern int vmsplice (int __fdout, const struct iovec *__iov, size_t __count,
+ unsigned int __flags);
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/ipc.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/ipc.h
new file mode 100644
index 000000000..858c332f1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/ipc.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IPC_H
+# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
+#endif
+
+#include <sys/types.h>
+
+/* Mode bits for `msgget', `semget', and `shmget'. */
+#define IPC_CREAT 01000 /* Create key if key does not exist. */
+#define IPC_EXCL 02000 /* Fail if key exists. */
+#define IPC_NOWAIT 04000 /* Return error on wait. */
+
+/* Control commands for `msgctl', `semctl', and `shmctl'. */
+#define IPC_RMID 0 /* Remove identifier. */
+#define IPC_SET 1 /* Set `ipc_perm' options. */
+#define IPC_STAT 2 /* Get `ipc_perm' options. */
+#define IPC_INFO 3 /* See ipcs. */
+
+/* Special key values. */
+#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
+
+
+/* Data structure used to pass permission information to IPC operations. */
+struct ipc_perm
+ {
+ __key_t __key; /* Key. */
+ __uid_t uid; /* Owner's user ID. */
+ __gid_t gid; /* Owner's group ID. */
+ __uid_t cuid; /* Creator's user ID. */
+ __gid_t cgid; /* Creator's group ID. */
+ __mode_t mode; /* Read/write permission. */
+ unsigned short int __seq; /* Sequence number. */
+ unsigned short int __pad1;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ };
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/mman.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/mman.h
new file mode 100644
index 000000000..a27a30fc0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/mman.h
@@ -0,0 +1,104 @@
+/* Definitions for POSIX memory map interface. Linux/ia64 version.
+ Copyright (C) 1997,1998,2000,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MMAN_H
+# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
+#endif
+
+/* The following definitions basically come from the kernel headers.
+ But the kernel header is not namespace clean. */
+
+
+/* Protections are chosen from these bits, OR'd together. The
+ implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ without PROT_READ. The only guarantees are that no writing will be
+ allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
+
+#define PROT_READ 0x1 /* Page can be read. */
+#define PROT_WRITE 0x2 /* Page can be written. */
+#define PROT_EXEC 0x4 /* Page can be executed. */
+#define PROT_NONE 0x0 /* Page can not be accessed. */
+#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
+ growsdown vma (mprotect only). */
+#define PROT_GROWSUP 0x02000000 /* Extend change to start of
+ growsup vma (mprotect only). */
+
+/* Sharing types (must choose one and only one of these). */
+#define MAP_SHARED 0x01 /* Share changes. */
+#define MAP_PRIVATE 0x02 /* Changes are private. */
+#ifdef __USE_MISC
+# define MAP_TYPE 0x0f /* Mask for type of mapping. */
+#endif
+
+/* Other flags. */
+#define MAP_FIXED 0x10 /* Interpret addr exactly. */
+#ifdef __USE_MISC
+# define MAP_FILE 0
+# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+
+/* These are Linux-specific. */
+#ifdef __USE_MISC
+# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */
+# define MAP_GROWSUP 0x00200 /* Register stack-like segment */
+# define MAP_DENYWRITE 0x00800 /* ETXTBSY */
+# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */
+# define MAP_LOCKED 0x02000 /* Lock the mapping. */
+# define MAP_NORESERVE 0x04000 /* Don't check for reservations. */
+# define MAP_POPULATE 0x08000 /* Populate (prefault) pagetables. */
+# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */
+#endif
+
+/* Flags to `msync'. */
+#define MS_ASYNC 0x1 /* Sync memory asynchronously. */
+#define MS_INVALIDATE 0x2 /* Invalidate the caches. */
+#define MS_SYNC 0x4 /* Synchronous memory sync. */
+
+/* Flags for `mlockall'. */
+#define MCL_CURRENT 0x1 /* Lock all currently mapped pages. */
+#define MCL_FUTURE 0x2 /* Lock all additions to address
+ space. */
+
+/* Flags for `mremap'. */
+#ifdef __USE_GNU
+# define MREMAP_MAYMOVE 1
+# define MREMAP_FIXED 2
+#endif
+
+/* Advice to `madvise'. */
+#ifdef __USE_BSD
+# define MADV_NORMAL 0 /* No further special treatment. */
+# define MADV_RANDOM 1 /* Expect random page references. */
+# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define MADV_WILLNEED 3 /* Will need these pages. */
+# define MADV_DONTNEED 4 /* Don't need these pages. */
+# define MADV_REMOVE 9 /* Remove these pages and resources. */
+# define MADV_DONTFORK 10 /* Do not inherit across fork. */
+# define MADV_DOFORK 11 /* Do inherit across fork. */
+#endif
+
+/* The POSIX people had to invent similar names for the same things. */
+#ifdef __USE_XOPEN2K
+# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/msq.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/msq.h
new file mode 100644
index 000000000..cd268eea3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/msq.h
@@ -0,0 +1,69 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contribute by David Mosberger-Tang <davidm@hpl.hp.com>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MSG_H
+#error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+#include <sys/types.h>
+
+/* Define options for message queue functions. */
+#define MSG_NOERROR 010000 /* no error if message is too big */
+#define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+
+
+/* Structure of record for one message inside the kernel.
+ The type `struct __msg' is opaque. */
+struct msqid_ds
+{
+ struct ipc_perm msg_perm; /* structure describing operation permission */
+ __time_t msg_stime; /* time of last msgsnd command */
+ __time_t msg_rtime; /* time of last msgrcv command */
+ __time_t msg_ctime; /* time of last change */
+ unsigned long int __msg_cbytes; /* current number of bytes on queue */
+ unsigned long int msg_qnum; /* number of messages currently on queue */
+ unsigned long int msg_qbytes; /* max number of bytes allowed on queue */
+ __pid_t msg_lspid; /* pid of last msgsnd() */
+ __pid_t msg_lrpid; /* pid of last msgrcv() */
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+};
+
+#ifdef __USE_MISC
+
+# define msg_cbytes __msg_cbytes
+
+/* ipcs ctl commands */
+# define MSG_STAT 11
+# define MSG_INFO 12
+
+/* buffer for msgctl calls IPC_INFO, MSG_INFO */
+struct msginfo
+ {
+ int msgpool;
+ int msgmap;
+ int msgmax;
+ int msgmnb;
+ int msgmni;
+ int msgssz;
+ int msgtql;
+ unsigned short int msgseg;
+ };
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/sem.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/sem.h
new file mode 100644
index 000000000..449f1ecc4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/sem.h
@@ -0,0 +1,87 @@
+/* Copyright (C) 2000
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SEM_H
+# error "Never include <bits/sem.h> directly; use <sys/sem.h> instead."
+#endif
+
+#include <sys/types.h>
+
+/* Flags for `semop'. */
+#define SEM_UNDO 0x1000 /* undo the operation on exit */
+
+/* Commands for `semctl'. */
+#define GETPID 11 /* get sempid */
+#define GETVAL 12 /* get semval */
+#define GETALL 13 /* get all semval's */
+#define GETNCNT 14 /* get semncnt */
+#define GETZCNT 15 /* get semzcnt */
+#define SETVAL 16 /* set semval */
+#define SETALL 17 /* set all semval's */
+
+
+/* Data structure describing a set of semaphores. */
+struct semid_ds
+{
+ struct ipc_perm sem_perm; /* operation permission struct */
+ __time_t sem_otime; /* last semop() time */
+ __time_t sem_ctime; /* last time changed by semctl() */
+ unsigned long int sem_nsems; /* number of semaphores in set */
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+};
+
+/* The user should define a union like the following to use it for arguments
+ for `semctl'.
+
+ union semun
+ {
+ int val; <= value for SETVAL
+ struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET
+ unsigned short int *array; <= array for GETALL & SETALL
+ struct seminfo *__buf; <= buffer for IPC_INFO
+ };
+
+ Previous versions of this file used to define this union but this is
+ incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether
+ one must define the union or not. */
+#define _SEM_SEMUN_UNDEFINED 1
+
+#ifdef __USE_MISC
+
+/* ipcs ctl cmds */
+# define SEM_STAT 18
+# define SEM_INFO 19
+
+struct seminfo
+{
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvmx;
+ int semaem;
+};
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/setjmp.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/setjmp.h
new file mode 100644
index 000000000..8bd675e4e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/setjmp.h
@@ -0,0 +1,35 @@
+/* Define the machine-dependent type `jmp_buf'. Linux/IA-64 version.
+ Copyright (C) 1999,2000,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H 1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+/* User code must not depend on the internal representation of jmp_buf. */
+
+#define _JBLEN 70
+
+/* the __jmp_buf element type should be __float80 per ABI... */
+typedef long __jmp_buf[_JBLEN] __attribute__ ((aligned (16))); /* guarantees 128-bit alignment! */
+
+#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/shm.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/shm.h
new file mode 100644
index 000000000..7f38f2dd7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/shm.h
@@ -0,0 +1,94 @@
+/* Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <sys/types.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+/* Segment low boundary address multiple. */
+#define SHMLBA (1024 * 1024)
+
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a set of semaphores. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+ size_t shm_segsz; /* size of segment in bytes */
+ __time_t shm_atime; /* time of last shmat() */
+ __time_t shm_dtime; /* time of last shmdt() */
+ __time_t shm_ctime; /* time of last change by shmctl() */
+ __pid_t shm_cpid; /* pid of creator */
+ __pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */
+# define SHM_NORESERVE 010000 /* don't check for reservations */
+
+struct shminfo
+ {
+ unsigned long int shmmax;
+ unsigned long int shmmin;
+ unsigned long int shmmni;
+ unsigned long int shmseg;
+ unsigned long int shmall;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ unsigned long int __unused3;
+ unsigned long int __unused4;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/sigaction.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/sigaction.h
new file mode 100644
index 000000000..11599d520
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/sigaction.h
@@ -0,0 +1,73 @@
+/* Definitions for Linux/ia64 sigaction.
+ Copyright (C) 1996, 1997, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIGNAL_H
+# error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
+#endif
+
+/* Structure describing the action to be taken when a signal arrives. */
+struct sigaction
+ {
+ /* Signal handler. */
+#ifdef __USE_POSIX199309
+ union
+ {
+ /* Used if SA_SIGINFO is not set. */
+ __sighandler_t sa_handler;
+ /* Used if SA_SIGINFO is set. */
+ void (*sa_sigaction) (int, siginfo_t *, void *);
+ }
+ __sigaction_handler;
+# define sa_handler __sigaction_handler.sa_handler
+# define sa_sigaction __sigaction_handler.sa_sigaction
+#else
+ __sighandler_t sa_handler;
+#endif
+
+ /* Special flags. */
+ unsigned long int sa_flags;
+
+ /* Additional set of signals to be blocked. */
+ __sigset_t sa_mask;
+ };
+
+/* Bits in `sa_flags'. */
+#define SA_NOCLDSTOP 0x00000001 /* Don't send SIGCHLD when children stop. */
+#define SA_NOCLDWAIT 0x00000002 /* Don't create zombie on child death. */
+#define SA_SIGINFO 0x00000004
+#if defined __USE_UNIX98 || defined __USE_MISC
+# define SA_ONSTACK 0x08000000 /* Use signal stack by using `sa_restorer'. */
+# define SA_RESTART 0x10000000 /* Restart syscall on signal return. */
+# define SA_NODEFER 0x40000000 /* Don't automatically block the signal
+ when its handler is being executed. */
+# define SA_RESETHAND 0x80000000 /* Reset to SIG_DFL on entry to handler. */
+#endif
+#ifdef __USE_MISC
+# define SA_INTERRUPT 0x20000000 /* Historic no-op. */
+
+/* Some aliases for the SA_ constants. */
+# define SA_NOMASK SA_NODEFER
+# define SA_ONESHOT SA_RESETHAND
+# define SA_STACK SA_ONSTACK
+#endif
+
+/* Values for the HOW argument to `sigprocmask'. */
+#define SIG_BLOCK 0 /* for blocking signals */
+#define SIG_UNBLOCK 1 /* for unblocking signals */
+#define SIG_SETMASK 2 /* for setting the signal mask */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
new file mode 100644
index 000000000..72c60ec24
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
@@ -0,0 +1,79 @@
+/* Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jes Sorensen <jes@linuxcare.com>, July 2000
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
+# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
+#endif
+
+#ifndef _BITS_SIGCONTEXT_H
+#define _BITS_SIGCONTEXT_H 1
+
+#include <bits/sigstack.h>
+
+struct ia64_fpreg
+ {
+ union
+ {
+ unsigned long bits[2];
+ } u;
+ } __attribute__ ((aligned (16)));
+
+struct sigcontext
+{
+ unsigned long int sc_flags; /* see manifest constants below */
+ unsigned long int sc_nat; /* bit i == 1 iff scratch reg gr[i] is a NaT */
+ stack_t sc_stack; /* previously active stack */
+
+ unsigned long int sc_ip; /* instruction pointer */
+ unsigned long int sc_cfm; /* current frame marker */
+ unsigned long int sc_um; /* user mask bits */
+ unsigned long int sc_ar_rsc; /* register stack configuration register */
+ unsigned long int sc_ar_bsp; /* backing store pointer */
+ unsigned long int sc_ar_rnat; /* RSE NaT collection register */
+ unsigned long int sc_ar_ccv; /* compare & exchange compare value register */
+ unsigned long int sc_ar_unat; /* ar.unat of interrupted context */
+ unsigned long int sc_ar_fpsr; /* floating-point status register */
+ unsigned long int sc_ar_pfs; /* previous function state */
+ unsigned long int sc_ar_lc; /* loop count register */
+ unsigned long int sc_pr; /* predicate registers */
+ unsigned long int sc_br[8]; /* branch registers */
+ unsigned long int sc_gr[32]; /* general registers (static partition) */
+ struct ia64_fpreg sc_fr[128]; /* floating-point registers */
+ unsigned long int sc_rbs_base;/* NULL or new base of sighandler's rbs */
+ unsigned long int sc_loadrs; /* see description above */
+ unsigned long int sc_ar25; /* cmp8xchg16 uses this */
+ unsigned long int sc_ar26; /* rsvd for scratch use */
+ unsigned long int sc_rsvd[12];/* reserved for future use */
+
+ /* sc_mask is actually an sigset_t but we don't want to
+ * include the kernel headers here. */
+ unsigned long int sc_mask; /* signal mask to restore after handler returns */
+};
+
+/* sc_flag bit definitions. */
+#define IA64_SC_FLAG_ONSTACK_BIT 0 /* is handler running on signal stack? */
+#define IA64_SC_FLAG_IN_SYSCALL_BIT 1 /* did signal interrupt a syscall? */
+#define IA64_SC_FLAG_FPH_VALID_BIT 2 /* is state in f[32]-f[127] valid? */
+
+#define IA64_SC_FLAG_ONSTACK (1 << IA64_SC_FLAG_ONSTACK_BIT)
+#define IA64_SC_FLAG_IN_SYSCALL (1 << IA64_SC_FLAG_IN_SYSCALL_BIT)
+#define IA64_SC_FLAG_FPH_VALID (1 << IA64_SC_FLAG_FPH_VALID_BIT)
+
+#endif /* _BITS_SIGCONTEXT_H */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h
new file mode 100644
index 000000000..66310c65b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h
@@ -0,0 +1,339 @@
+/* siginfo_t, sigevent and constants. Linux/ia64 version.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _SIGNAL_H && !defined __need_siginfo_t \
+ && !defined __need_sigevent_t
+# error "Never include this file directly. Use <signal.h> instead"
+#endif
+
+#if (!defined __have_sigval_t \
+ && (defined _SIGNAL_H || defined __need_siginfo_t \
+ || defined __need_sigevent_t))
+# define __have_sigval_t 1
+
+/* Type for data associated with a signal. */
+typedef union sigval
+ {
+ int sival_int;
+ void *sival_ptr;
+ } sigval_t;
+#endif
+
+#if (!defined __have_siginfo_t \
+ && (defined _SIGNAL_H || defined __need_siginfo_t))
+# define __have_siginfo_t 1
+
+# define __SI_MAX_SIZE 128
+# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
+
+typedef struct siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_errno; /* If non-zero, an errno value associated with
+ this signal, as defined in <errno.h>. */
+ int si_code; /* Signal code. */
+ int __pad0; /* Explicit padding. */
+
+ union
+ {
+ int _pad[__SI_PAD_SIZE];
+
+ /* kill(). */
+ struct
+ {
+ __pid_t si_pid; /* Sending process ID. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ } _kill;
+
+ /* POSIX.1b timers. */
+ struct
+ {
+ int si_tid; /* Timer ID. */
+ int si_overrun; /* Overrun count. */
+ sigval_t si_sigval; /* Signal value. */
+ } _timer;
+
+ /* POSIX.1b signals. */
+ struct
+ {
+ __pid_t si_pid; /* Sending process ID. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ sigval_t si_sigval; /* Signal value. */
+ } _rt;
+
+ /* SIGCHLD. */
+ struct
+ {
+ __pid_t si_pid; /* Which child. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ int si_status; /* Exit value or signal. */
+ __clock_t si_utime;
+ __clock_t si_stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
+ struct
+ {
+ void *si_addr; /* Faulting insn/memory ref. */
+ int _si_imm;
+ unsigned int _si_flags;
+ unsigned long int _si_isr;
+ } _sigfault;
+
+ /* SIGPOLL. */
+ struct
+ {
+ long int si_band; /* Band event for SIGPOLL. */
+ int si_fd;
+ } _sigpoll;
+ } _sifields;
+ } siginfo_t;
+
+
+/* X/Open requires some more fields with fixed names. */
+# define si_pid _sifields._kill.si_pid
+# define si_uid _sifields._kill.si_uid
+# define si_timerid _sifields._timer.si_tid
+# define si_overrun _sifields._timer.si_overrun
+# define si_status _sifields._sigchld.si_status
+# define si_utime _sifields._sigchld.si_utime
+# define si_stime _sifields._sigchld.si_stime
+# define si_value _sifields._rt.si_sigval
+# define si_int _sifields._rt.si_sigval.sival_int
+# define si_ptr _sifields._rt.si_sigval.sival_ptr
+# define si_addr _sifields._sigfault.si_addr
+# define si_band _sifields._sigpoll.si_band
+# define si_fd _sifields._sigpoll.si_fd
+
+# ifdef __USE_GNU
+# define si_imm _sifields._sigfault._si_imm
+# define si_segvflags _sifields._sigfault._si_flags
+# define si_isr _sifields._sigfault._si_isr
+# endif
+
+/* Values for `si_code'. Positive values are reserved for kernel-generated
+ signals. */
+enum
+{
+ SI_ASYNCNL = -60, /* Sent by asynch name lookup completion. */
+# define SI_ASYNCNL SI_ASYNCNL
+ SI_TKILL = -6, /* Sent by tkill. */
+# define SI_TKILL SI_TKILL
+ SI_SIGIO, /* Sent by queued SIGIO. */
+# define SI_SIGIO SI_SIGIO
+ SI_ASYNCIO, /* Sent by AIO completion. */
+# define SI_ASYNCIO SI_ASYNCIO
+ SI_MESGQ, /* Sent by real time mesq state change. */
+# define SI_MESGQ SI_MESGQ
+ SI_TIMER, /* Sent by timer expiration. */
+# define SI_TIMER SI_TIMER
+ SI_QUEUE, /* Sent by sigqueue. */
+# define SI_QUEUE SI_QUEUE
+ SI_USER, /* Sent by kill, sigsend, raise. */
+# define SI_USER SI_USER
+ SI_KERNEL = 0x80 /* Send by kernel. */
+#define SI_KERNEL SI_KERNEL
+};
+
+
+/* `si_code' values for SIGILL signal. */
+enum
+{
+ ILL_ILLOPC = 1, /* Illegal opcode. */
+# define ILL_ILLOPC ILL_ILLOPC
+ ILL_ILLOPN, /* Illegal operand. */
+# define ILL_ILLOPN ILL_ILLOPN
+ ILL_ILLADR, /* Illegal addressing mode. */
+# define ILL_ILLADR ILL_ILLADR
+ ILL_ILLTRP, /* Illegal trap. */
+# define ILL_ILLTRP ILL_ILLTRP
+ ILL_PRVOPC, /* Privileged opcode. */
+# define ILL_PRVOPC ILL_PRVOPC
+ ILL_PRVREG, /* Privileged register. */
+# define ILL_PRVREG ILL_PRVREG
+ ILL_COPROC, /* Coprocessor error. */
+# define ILL_COPROC ILL_COPROC
+ ILL_BADSTK, /* Internal stack error. */
+# define ILL_BADSTK ILL_BADSTK
+ ILL_BADIADDR /* Unimplemented instruction address. */
+# define ILL_BADIADDR ILL_BADIADDR
+
+# ifdef __USE_GNU
+ , ILL_BREAK
+# define ILL_BREAK ILL_BREAK
+# endif
+};
+
+/* `si_code' values for SIGFPE signal. */
+enum
+{
+ FPE_INTDIV = 1, /* Integer divide by zero. */
+# define FPE_INTDIV FPE_INTDIV
+ FPE_INTOVF, /* Integer overflow. */
+# define FPE_INTOVF FPE_INTOVF
+ FPE_FLTDIV, /* Floating point divide by zero. */
+# define FPE_FLTDIV FPE_FLTDIV
+ FPE_FLTOVF, /* Floating point overflow. */
+# define FPE_FLTOVF FPE_FLTOVF
+ FPE_FLTUND, /* Floating point underflow. */
+# define FPE_FLTUND FPE_FLTUND
+ FPE_FLTRES, /* Floating point inexact result. */
+# define FPE_FLTRES FPE_FLTRES
+ FPE_FLTINV, /* Floating point invalid operation. */
+# define FPE_FLTINV FPE_FLTINV
+ FPE_FLTSUB /* Subscript out of range. */
+# define FPE_FLTSUB FPE_FLTSUB
+# ifdef __USE_GNU
+ , FPE_DECOVF
+# define FPE_DECOVF FPE_DECOVF
+ , FPE_DECDIV
+# define FPE_DECDIV FPE_DECDIV
+ , FPE_DECERR
+# define FPE_DECERR FPE_DECERR
+ , FPE_INVASC
+# define FPE_INVASC FPE_INVASC
+ , FPE_INVDEC
+# define FPE_INVDEC FPE_INVDEC
+# endif
+};
+
+/* `si_code' values for SIGSEGV signal. */
+enum
+{
+ SEGV_MAPERR = 1, /* Address not mapped to object. */
+# define SEGV_MAPERR SEGV_MAPERR
+ SEGV_ACCERR /* Invalid permissions for mapped object. */
+# define SEGV_ACCERR SEGV_ACCERR
+# ifdef __USE_GNU
+ , SEGV_PSTKOVF /* Paragraph stack overflow. */
+# define SEGV_PSTKOVF SEGV_PSTKOVF
+# endif
+};
+
+/* `si_code' values for SIGBUS signal. */
+enum
+{
+ BUS_ADRALN = 1, /* Invalid address alignment. */
+# define BUS_ADRALN BUS_ADRALN
+ BUS_ADRERR, /* Non-existant physical address. */
+# define BUS_ADRERR BUS_ADRERR
+ BUS_OBJERR /* Object specific hardware error. */
+# define BUS_OBJERR BUS_OBJERR
+};
+
+/* `si_code' values for SIGTRAP signal. */
+enum
+{
+ TRAP_BRKPT = 1, /* Process breakpoint. */
+# define TRAP_BRKPT TRAP_BRKPT
+ TRAP_TRACE /* Process trace trap. */
+# define TRAP_TRACE TRAP_TRACE
+
+# ifdef __USE_GNU
+ , TRAP_BRANCH
+# define TRAP_BRANCH TRAP_BRANCH
+ , TRAP_HWBKPT
+# define TRAP_HWBKPT TRAP_HWBKPT
+# endif
+};
+
+/* `si_code' values for SIGCHLD signal. */
+enum
+{
+ CLD_EXITED = 1, /* Child has exited. */
+# define CLD_EXITED CLD_EXITED
+ CLD_KILLED, /* Child was killed. */
+# define CLD_KILLED CLD_KILLED
+ CLD_DUMPED, /* Child terminated abnormally. */
+# define CLD_DUMPED CLD_DUMPED
+ CLD_TRAPPED, /* Traced child has trapped. */
+# define CLD_TRAPPED CLD_TRAPPED
+ CLD_STOPPED, /* Child has stopped. */
+# define CLD_STOPPED CLD_STOPPED
+ CLD_CONTINUED /* Stopped child has continued. */
+# define CLD_CONTINUED CLD_CONTINUED
+};
+
+/* `si_code' values for SIGPOLL signal. */
+enum
+{
+ POLL_IN = 1, /* Data input available. */
+# define POLL_IN POLL_IN
+ POLL_OUT, /* Output buffers available. */
+# define POLL_OUT POLL_OUT
+ POLL_MSG, /* Input message available. */
+# define POLL_MSG POLL_MSG
+ POLL_ERR, /* I/O error. */
+# define POLL_ERR POLL_ERR
+ POLL_PRI, /* High priority input available. */
+# define POLL_PRI POLL_PRI
+ POLL_HUP /* Device disconnected. */
+# define POLL_HUP POLL_HUP
+};
+
+# undef __need_siginfo_t
+#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
+
+
+#if (defined _SIGNAL_H || defined __need_sigevent_t) \
+ && !defined __have_sigevent_t
+# define __have_sigevent_t 1
+
+/* Structure to transport application-defined values with signals. */
+# define __SIGEV_MAX_SIZE 64
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4)
+
+typedef struct sigevent
+ {
+ sigval_t sigev_value;
+ int sigev_signo;
+ int sigev_notify;
+
+ union
+ {
+ int _pad[__SIGEV_PAD_SIZE];
+
+ struct
+ {
+ void (*_function) (sigval_t); /* Function to start. */
+ void *_attribute; /* Really pthread_attr_t. */
+ } _sigev_thread;
+ } _sigev_un;
+ } sigevent_t;
+
+/* POSIX names to access some of the members. */
+# define sigev_notify_function _sigev_un._sigev_thread._function
+# define sigev_notify_attributes _sigev_un._sigev_thread._attribute
+
+/* `sigev_notify' values. */
+enum
+{
+ SIGEV_SIGNAL = 0, /* Notify via signal. */
+# define SIGEV_SIGNAL SIGEV_SIGNAL
+ SIGEV_NONE, /* Other notification: meaningless. */
+# define SIGEV_NONE SIGEV_NONE
+ SIGEV_THREAD, /* Deliver via thread creation. */
+# define SIGEV_THREAD SIGEV_THREAD
+
+ SIGEV_THREAD_ID = 4 /* Send signal to specific thread. */
+#define SIGEV_THREAD_ID SIGEV_THREAD_ID
+};
+
+#endif /* have _SIGNAL_H. */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/sigstack.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/sigstack.h
new file mode 100644
index 000000000..c9c9d2fed
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/sigstack.h
@@ -0,0 +1,63 @@
+/* sigstack, sigaltstack definitions.
+ Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIGNAL_H
+# error "Never include this file directly. Use <signal.h> instead"
+#endif
+
+#ifndef _SIGSTACK_H
+#define _SIGSTACK_H 1
+
+/* Structure describing a signal stack (obsolete). */
+struct sigstack
+ {
+ __ptr_t ss_sp; /* Signal stack pointer. */
+ int ss_onstack; /* Nonzero if executing on this stack. */
+ };
+
+
+/* Possible values for `ss_flags.'. */
+enum
+{
+ SS_ONSTACK = 1,
+#define SS_ONSTACK SS_ONSTACK
+ SS_DISABLE
+#define SS_DISABLE SS_DISABLE
+};
+
+/* Minimum stack size for a signal handler.
+
+ Yes, this should be 131072 but the constant got defined incorrectly
+ in the kernel and we have to live with it. Users should in any case
+ use SIGSTKSZ as the size user-supplied buffers should have. */
+#define MINSIGSTKSZ 131027
+
+/* System default stack size. */
+#define SIGSTKSZ 262144
+
+
+/* Alternate, preferred interface. */
+typedef struct sigaltstack
+ {
+ __ptr_t ss_sp;
+ int ss_flags;
+ size_t ss_size;
+ } stack_t;
+
+#endif /* bits/sigstack.h */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/stat.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/stat.h
new file mode 100644
index 000000000..f6b6671c0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/stat.h
@@ -0,0 +1,140 @@
+/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+/* Versions of the `struct stat' data structure. */
+#define _STAT_VER_KERNEL 0
+#define _STAT_VER_LINUX 1
+#define _STAT_VER _STAT_VER_LINUX
+
+/* Versions of the `xmknod' interface. */
+#define _MKNOD_VER_LINUX 0
+
+struct stat
+ {
+ __dev_t st_dev; /* Device. */
+ __ino_t st_ino; /* File serial number. */
+ __nlink_t st_nlink; /* Link count. */
+ __mode_t st_mode; /* File mode. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ int pad0;
+ __dev_t st_rdev; /* Device number, if device. */
+ __off_t st_size; /* Size of file, in bytes. */
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ __blkcnt_t st_blocks; /* Nr. 512-byte blocks allocated. */
+ long int __unused[3];
+ };
+
+#ifdef __USE_LARGEFILE64
+/* Note stat64 is the same shape as stat. */
+struct stat64
+ {
+ __dev_t st_dev; /* Device. */
+ __ino64_t st_ino; /* File serial number. */
+ __nlink_t st_nlink; /* Link count. */
+ __mode_t st_mode; /* File mode. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ int pad0;
+ __dev_t st_rdev; /* Device number, if device. */
+ __off_t st_size; /* Size of file, in bytes. */
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */
+ long int __unused[3];
+ };
+#endif
+
+/* Tell code we have these members. */
+#define _STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+/* Nanosecond resolution time values are supported. */
+#define _STATBUF_ST_NSEC
+
+/* Encoding of the file mode. */
+
+#define __S_IFMT 0170000 /* These bits determine file type. */
+
+/* File types. */
+#define __S_IFDIR 0040000 /* Directory. */
+#define __S_IFCHR 0020000 /* Character device. */
+#define __S_IFBLK 0060000 /* Block device. */
+#define __S_IFREG 0100000 /* Regular file. */
+#define __S_IFIFO 0010000 /* FIFO. */
+#define __S_IFLNK 0120000 /* Symbolic link. */
+#define __S_IFSOCK 0140000 /* Socket. */
+
+/* POSIX.1b objects. Note that these macros always evaluate to zero. But
+ they do it by enforcing the correct use of the macros. */
+#define __S_TYPEISMQ(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
+
+/* Protection bits. */
+
+#define __S_ISUID 04000 /* Set user ID on execution. */
+#define __S_ISGID 02000 /* Set group ID on execution. */
+#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
+#define __S_IREAD 0400 /* Read by owner. */
+#define __S_IWRITE 0200 /* Write by owner. */
+#define __S_IEXEC 0100 /* Execute by owner. */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/brk.S b/libc/sysdeps/unix/sysv/linux/ia64/brk.S
new file mode 100644
index 000000000..0e4114a33
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/brk.S
@@ -0,0 +1,52 @@
+/* brk system call for Linux/ia64
+ Copyright (C) 1999,2000,2001,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Written by Stephane Eranian <eranian@hpl.hp.com> and
+ Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include <asm/unistd.h>
+#include <asm/errno.h>
+
+ .global __curbrk
+ .type __curbrk,@object
+ .size __curbrk,8
+ .data
+ .align 8
+__curbrk:
+ data8 0
+
+weak_alias (__curbrk, ___brk_addr)
+
+LEAF(__brk)
+ .regstk 1, 0, 0, 0
+ DO_CALL(__NR_brk)
+ cmp.ltu p6, p0 = ret0, in0
+ addl r9 = @ltoff(__curbrk), gp
+ ;;
+ ld8 r9 = [r9]
+(p6) mov ret0 = ENOMEM
+(p6) br.cond.spnt.few __syscall_error
+ ;;
+ st8 [r9] = ret0
+ mov ret0 = 0
+ ret
+END(__brk)
+
+weak_alias (__brk, brk)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bsd-_setjmp.S b/libc/sysdeps/unix/sysv/linux/ia64/bsd-_setjmp.S
new file mode 100644
index 000000000..4e6a2da56
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bsd-_setjmp.S
@@ -0,0 +1 @@
+/* _setjmp is in setjmp.S */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bsd-setjmp.S b/libc/sysdeps/unix/sysv/linux/ia64/bsd-setjmp.S
new file mode 100644
index 000000000..1da848d2f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/bsd-setjmp.S
@@ -0,0 +1 @@
+/* setjmp is in setjmp.S */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c b/libc/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c
new file mode 100644
index 000000000..2f3985153
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c
@@ -0,0 +1,32 @@
+/* clock_getcpuclockid -- Get a clockid_t for process CPU time. Linux/IA64
+ Copyright (C) 2000,2001,2003,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+
+#include "has_cpuclock.c"
+
+#define HAS_CPUCLOCK (has_cpuclock () > 0)
+
+#include <sysdeps/unix/sysv/linux/clock_getcpuclockid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/clone.S b/libc/sysdeps/unix/sysv/linux/ia64/clone.S
new file mode 100644
index 000000000..0cfaeab64
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/clone.S
@@ -0,0 +1 @@
+/* clone is not supported under Linux/ia64, use clone2. */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/clone2.S b/libc/sysdeps/unix/sysv/linux/ia64/clone2.S
new file mode 100644
index 000000000..d38eb201a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/clone2.S
@@ -0,0 +1,106 @@
+/* Copyright (C) 2000, 2001, 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#include <sysdep.h>
+#include <asm/errno.h>
+
+
+/* int __clone2(int (*fn) (void *arg), void *child_stack_base, */
+/* size_t child_stack_size, int flags, void *arg, */
+/* pid_t *parent_tid, void *tls, pid_t *child_tid) */
+
+#define CHILD p8
+#define PARENT p9
+
+ENTRY(__clone2)
+ .prologue
+ alloc r2=ar.pfs,8,1,6,0
+ cmp.eq p6,p0=0,in0
+ cmp.eq p7,p0=0,in1
+ mov r8=EINVAL
+ mov out0=in3 /* Flags are first syscall argument. */
+ mov out1=in1 /* Stack address. */
+(p6) br.cond.spnt.many __syscall_error /* no NULL function pointers */
+(p7) br.cond.spnt.many __syscall_error /* no NULL stack pointers */
+ ;;
+ mov out2=in2 /* Stack size. */
+ mov out3=in5 /* Parent TID Pointer */
+ mov out4=in7 /* Child TID Pointer */
+ mov out5=in6 /* TLS pointer */
+ /*
+ * clone2() is special: the child cannot execute br.ret right
+ * after the system call returns, because it starts out
+ * executing on an empty stack. Because of this, we can't use
+ * the new (lightweight) syscall convention here. Instead, we
+ * just fall back on always using "break".
+ *
+ * Furthermore, since the child starts with an empty stack, we
+ * need to avoid unwinding past invalid memory. To that end,
+ * we'll pretend now that __clone2() is the end of the
+ * call-chain. This is wrong for the parent, but only until
+ * it returns from clone2() but it's better than the
+ * alternative.
+ */
+ mov r15=SYS_ify (clone2)
+ .save rp, r0
+ break __BREAK_SYSCALL
+ .body
+ cmp.eq p6,p0=-1,r10
+ cmp.eq CHILD,PARENT=0,r8 /* Are we the child? */
+(p6) br.cond.spnt.many __syscall_error
+ ;;
+(CHILD) mov loc0=gp
+(PARENT) ret
+ ;;
+#ifdef RESET_PID
+ tbit.nz p6,p0=in3,16 /* CLONE_THREAD */
+ tbit.z p7,p10=in3,8 /* CLONE_VM */
+(p6) br.cond.dptk 1f
+ ;;
+ mov r15=SYS_ify (getpid)
+(p10) addl r8=-1,r0
+(p7) break __BREAK_SYSCALL
+ ;;
+ add r9=PID,r13
+ add r10=TID,r13
+ ;;
+ st4 [r9]=r8
+ st4 [r10]=r8
+ ;;
+#endif
+1: ld8 out1=[in0],8 /* Retrieve code pointer. */
+ mov out0=in4 /* Pass proper argument to fn */
+ ;;
+ ld8 gp=[in0] /* Load function gp. */
+ mov b6=out1
+ br.call.dptk.many rp=b6 /* Call fn(arg) in the child */
+ ;;
+ mov out0=r8 /* Argument to _exit */
+ mov gp=loc0
+ .globl HIDDEN_JUMPTARGET(_exit)
+ br.call.dpnt.many rp=HIDDEN_JUMPTARGET(_exit)
+ /* call _exit with result from fn. */
+ ret /* Not reached. */
+PSEUDO_END(__clone2)
+
+/* For now we leave __clone undefined. This is unlikely to be a */
+/* problem, since at least the i386 __clone in glibc always failed */
+/* with a 0 sp (eventhough the kernel explicitly handled it). */
+/* Thus all such calls needed to pass an explicit sp, and as a result, */
+/* would be unlikely to work on ia64. */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/dl-brk.S b/libc/sysdeps/unix/sysv/linux/ia64/dl-brk.S
new file mode 100644
index 000000000..eeb96544e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/dl-brk.S
@@ -0,0 +1 @@
+#include <brk.S>
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/dl-cache.h b/libc/sysdeps/unix/sysv/linux/ia64/dl-cache.h
new file mode 100644
index 000000000..b8e279058
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/dl-cache.h
@@ -0,0 +1,25 @@
+/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define _DL_CACHE_DEFAULT_ID 0x203
+
+#define _dl_cache_check_flags(flags) \
+ ((flags) == _DL_CACHE_DEFAULT_ID)
+
+#include_next <dl-cache.h>
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/dl-static.c b/libc/sysdeps/unix/sysv/linux/ia64/dl-static.c
new file mode 100644
index 000000000..4efc07703
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/dl-static.c
@@ -0,0 +1,69 @@
+/* Variable initialization. IA-64 version.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ldsodefs.h>
+
+#ifdef SHARED
+
+void
+_dl_var_init (void *array[])
+{
+ /* It has to match "variables" below. */
+ enum
+ {
+ DL_PAGESIZE = 0,
+ DL_CLKTCK
+ };
+
+ GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]);
+ GLRO(dl_clktck) = *((int *) array[DL_CLKTCK]);
+}
+
+#else
+#include <bits/libc-lock.h>
+
+__libc_lock_define_initialized_recursive (static, _dl_static_lock)
+
+static void *variables[] =
+{
+ &GLRO(dl_pagesize),
+ &GLRO(dl_clktck)
+};
+
+void
+_dl_static_init (struct link_map *map)
+{
+ const ElfW(Sym) *ref = NULL;
+ lookup_t loadbase;
+ void (*f) (void *[]);
+
+ __libc_lock_lock_recursive (_dl_static_lock);
+
+ loadbase = _dl_lookup_symbol_x ("_dl_var_init", map, &ref,
+ map->l_local_scope, NULL, 0, 1, NULL);
+ if (ref != NULL)
+ {
+ f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref);
+ f (variables);
+ }
+
+ __libc_lock_unlock_recursive (_dl_static_lock);
+}
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/fork.S b/libc/sysdeps/unix/sysv/linux/ia64/fork.S
new file mode 100644
index 000000000..0a57ab0d1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/fork.S
@@ -0,0 +1,41 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#include <sysdep.h>
+#define _SIGNAL_H
+#include <bits/signum.h>
+
+/* pid_t fork(void); */
+/* Implemented as a clone system call with parameters SIGCHLD and 0 */
+
+ENTRY(__libc_fork)
+ alloc r2=ar.pfs,0,0,2,0
+ mov out0=SIGCHLD /* Return SIGCHLD when child finishes */
+ /* no other clone flags; nothing shared */
+ mov out1=0 /* Standard sp value. */
+ ;;
+ DO_CALL (SYS_ify (clone))
+ cmp.eq p6,p0=-1,r10
+(p6) br.cond.spnt.few __syscall_error
+ ret
+PSEUDO_END(__libc_fork)
+
+weak_alias (__libc_fork, __fork)
+libc_hidden_def (__fork)
+weak_alias (__libc_fork, fork)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c b/libc/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c
new file mode 100644
index 000000000..48abfc13f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c
@@ -0,0 +1,89 @@
+/* Get frequency of the system processor. IA-64/Linux version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <libc-internal.h>
+
+
+hp_timing_t
+__get_clockfreq (void)
+{
+ /* We read the information from the /proc filesystem. It contains at
+ least one line like
+ itc MHz : 733.390988
+ We search for this line and convert the number in an integer. */
+ static hp_timing_t result;
+ int fd;
+
+ /* If this function was called before, we know the result. */
+ if (result != 0)
+ return result;
+
+ fd = open ("/proc/cpuinfo", O_RDONLY);
+ if (__builtin_expect (fd != -1, 1))
+ {
+ /* XXX AFAIK the /proc filesystem can generate "files" only up
+ to a size of 4096 bytes. */
+ char buf[4096];
+ ssize_t n;
+
+ n = read (fd, buf, sizeof buf);
+ if (__builtin_expect (n, 1) > 0)
+ {
+ char *mhz = memmem (buf, n, "itc MHz", 7);
+
+ if (__builtin_expect (mhz != NULL, 1))
+ {
+ char *endp = buf + n;
+ int seen_decpoint = 0;
+ int ndigits = 0;
+
+ /* Search for the beginning of the string. */
+ while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
+ ++mhz;
+
+ while (mhz < endp && *mhz != '\n')
+ {
+ if (*mhz >= '0' && *mhz <= '9')
+ {
+ result *= 10;
+ result += *mhz - '0';
+ if (seen_decpoint)
+ ++ndigits;
+ }
+ else if (*mhz == '.')
+ seen_decpoint = 1;
+
+ ++mhz;
+ }
+
+ /* Compensate for missing digits at the end. */
+ while (ndigits++ < 6)
+ result *= 10;
+ }
+ }
+
+ close (fd);
+ }
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/getclktck.c b/libc/sysdeps/unix/sysv/linux/ia64/getclktck.c
new file mode 100644
index 000000000..6636bbe68
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/getclktck.c
@@ -0,0 +1,2 @@
+#define SYSTEM_CLK_TCK 1024
+#include <sysdeps/unix/sysv/linux/getclktck.c>
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/getcontext.S b/libc/sysdeps/unix/sysv/linux/ia64/getcontext.S
new file mode 100644
index 000000000..4e18bace2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/getcontext.S
@@ -0,0 +1,158 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <features.h>
+
+#include "ucontext_i.h"
+
+/* __getcontext (ucontext_t *ucp)
+
+ Saves the machine context in UCP such that when it is activated,
+ it appears as if __getcontext() returned again. The only difference
+ is that on a first return, r9 contains 1 and on a subsequent
+ return, it contains 0.
+
+ This implementation in intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to save anything
+ other than the PRESERVED state. */
+
+ENTRY(__getcontext)
+ .prologue
+ .body
+ alloc r11 = ar.pfs, 1, 0, 4, 0
+
+ // sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask):
+
+ mov r3 = SC_MASK
+ mov out0 = SIG_BLOCK
+
+ flushrs // save dirty partition on rbs
+ mov out1 = 0
+ add out2 = r3, in0
+
+ mov out3 = 8 // sizeof kernel sigset_t
+ DO_CALL(__NR_rt_sigprocmask)
+
+ mov.m rFPSR = ar.fpsr
+ mov.m rRSC = ar.rsc
+ add r2 = SC_GR+1*8, r32
+ ;;
+ mov.m rBSP = ar.bsp
+ .prologue
+ .save ar.unat, rUNAT
+ mov.m rUNAT = ar.unat
+ .body
+ add r3 = SC_GR+4*8, r32
+ ;;
+
+.mem.offset 0,0; st8.spill [r2] = r1, (5*8 - 1*8)
+.mem.offset 8,0; st8.spill [r3] = r4, 16
+ mov rPFS = r11
+ ;;
+.mem.offset 0,0; st8.spill [r2] = r5, 16
+.mem.offset 8,0; st8.spill [r3] = r6, 48
+ and rTMP = ~0x3, rRSC
+ ;;
+.mem.offset 0,0; st8.spill [r2] = r7, (SC_FR+2*16-(SC_GR+7*8))
+.mem.offset 8,0; st8.spill [r3] = sp, (SC_FR+3*16-(SC_GR+12*8))
+ ;;
+ mov.m ar.rsc = rTMP // put RSE into enforced lazy mode
+ mov.m rNAT = ar.unat
+ mov.i rLC = ar.lc
+ ;;
+ mov.m rRNAT = ar.rnat
+ mov.m ar.rsc = rRSC // restore RSE mode
+ mov rPR = pr
+
+ /*
+ * Rotate NaT bits by rPOS positions to the right:
+ */
+ stf.spill [r2] = f2, 32
+ stf.spill [r3] = f3, 32
+ add rPOS = SC_GR, r32 // rPOS <- &sc_gr[0]
+ ;;
+ stf.spill [r2] = f4, (16*16-4*16)
+ stf.spill [r3] = f5, (17*16-5*16)
+ extr.u rPOS = rPOS, 3, 6 // get NaT bit number for r0
+ ;;
+ stf.spill [r2] = f16, 32
+ stf.spill [r3] = f17, 32
+ sub rCPOS = 64, rPOS
+ ;;
+ stf.spill [r2] = f18, 32
+ stf.spill [r3] = f19, 32
+ shr.u rTMP = rNAT, rPOS
+ ;;
+ stf.spill [r2] = f20, 32
+ stf.spill [r3] = f21, 32
+ shl rNAT = rNAT, rCPOS
+ ;;
+ stf.spill [r2] = f22, 32
+ stf.spill [r3] = f23, 32
+ or rNAT = rNAT, rTMP
+ ;;
+ stf.spill [r2] = f24, 32
+ stf.spill [r3] = f25, 32
+ mov r8 = 0
+ ;;
+ stf.spill [r2] = f26, 32
+ stf.spill [r3] = f27, 32
+ mov r9 = 1
+ ;;
+ stf.spill [r2] = f28, 32
+ stf.spill [r3] = f29, 32
+ mov rB0 = b0
+ ;;
+ stf.spill [r2] = f30, 32
+ stf.spill [r3] = f31, 32
+ mov rB1 = b1
+ ;;
+ mov ar.unat = rUNAT // we're done spilling integer regs; restore caller's UNaT
+ add r2 = SC_NAT, r32
+ add r3 = SC_BSP, r32
+ ;;
+ st8 [r2] = rNAT, (SC_RNAT-SC_NAT)
+ st8 [r3] = rBSP, (SC_UNAT-SC_BSP)
+ mov rB2 = b2
+ ;;
+ st8 [r2] = rRNAT, (SC_FPSR-SC_RNAT)
+ st8 [r3] = rUNAT, (SC_PFS-SC_UNAT)
+ mov rB3 = b3
+ ;;
+ st8 [r2] = rFPSR, (SC_LC-SC_FPSR)
+ st8 [r3] = rPFS, (SC_PR-SC_PFS)
+ mov rB4 = b4
+ ;;
+ st8 [r2] = rLC, (SC_BR+0*8-SC_LC)
+ st8 [r3] = rPR, (SC_BR+1*8-SC_PR)
+ mov rB5 = b5
+ ;;
+ st8 [r2] = rB0, 16
+ st8 [r3] = rB1, 16
+ ;;
+ st8 [r2] = rB2, 16
+ st8 [r3] = rB3, 16
+ ;;
+ st8 [r2] = rB4
+ st8 [r3] = rB5
+ ret
+END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/getpagesize.c b/libc/sysdeps/unix/sysv/linux/ia64/getpagesize.c
new file mode 100644
index 000000000..1155dfdad
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/getpagesize.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#include <ldsodefs.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Return the system page size. The return value will depend on how
+ the kernel is configured. A program must use this call to
+ determine the page size to ensure proper alignment for calls such
+ as mmap and friends. --davidm 99/11/30 */
+
+int
+__getpagesize ()
+{
+ assert (GLRO(dl_pagesize) != 0);
+ return GLRO(dl_pagesize);
+}
+libc_hidden_def (__getpagesize)
+weak_alias (__getpagesize, getpagesize)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c b/libc/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c
new file mode 100644
index 000000000..39511cd2c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <not-cancel.h>
+
+static int itc_usable;
+
+static int
+has_cpuclock (void)
+{
+ if (__builtin_expect (itc_usable == 0, 0))
+ {
+ int newval = 1;
+ int fd = open_not_cancel_2 ("/proc/sal/itc_drift", O_RDONLY);
+ if (__builtin_expect (fd != -1, 1))
+ {
+ char buf[16];
+ /* We expect the file to contain a single digit followed by
+ a newline. If the format changes we better not rely on
+ the file content. */
+ if (read_not_cancel (fd, buf, sizeof buf) != 2
+ || buf[0] != '0' || buf[1] != '\n')
+ newval = -1;
+
+ close_not_cancel_no_status (fd);
+ }
+
+ itc_usable = newval;
+ }
+
+ return itc_usable;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/ioperm.c b/libc/sysdeps/unix/sysv/linux/ia64/ioperm.c
new file mode 100644
index 000000000..89a0a36d3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/ioperm.c
@@ -0,0 +1,217 @@
+/* Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* I/O access is restricted to ISA port space (ports 0..65535).
+ Modern devices hopefully are sane enough not to put any performance
+ critical registers in i/o space.
+
+ On the first call to ioperm() or iopl(), the entire (E)ISA port
+ space is mapped into the virtual address space at address io.base.
+ mprotect() calls are then used to enable/disable access to ports.
+ Per 4KB page, there are 4 I/O ports. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#define MAX_PORT 0x10000
+
+/*
+ * Memory fence w/accept. This should never be used in code that is
+ * not IA-64 specific.
+ */
+#define __ia64_mf_a() __asm__ __volatile__ ("mf.a" ::: "memory")
+
+static struct
+ {
+ unsigned long int base;
+ unsigned long int page_mask;
+ }
+io;
+
+__inline__ unsigned long int
+io_offset (unsigned long int port)
+{
+ return ((port >> 2) << 12) | (port & 0xfff);
+}
+
+int
+_ioperm (unsigned long int from, unsigned long int num, int turn_on)
+{
+#if 0
+ unsigned long int addr, len, base;
+#endif
+ unsigned long int base;
+ int prot;
+
+ /* this test isn't as silly as it may look like; consider overflows! */
+ if (from >= MAX_PORT || from + num > MAX_PORT)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (turn_on)
+ {
+ if (!io.base)
+ {
+ unsigned long phys_io_base, len;
+ int fd;
+
+ io.page_mask = ~(__getpagesize() - 1);
+
+ /* get I/O base physical address from ar.k0 as per PRM: */
+ __asm__ ("mov %0=ar.k0" : "=r"(phys_io_base));
+
+ /* The O_SYNC flag tells the /dev/mem driver to map the
+ memory uncached: */
+ fd = __open ("/dev/mem", O_RDWR | O_SYNC);
+ if (fd < 0)
+ return -1;
+
+ len = io_offset (MAX_PORT);
+#if 1
+ /* see comment below */
+ base = (unsigned long int) __mmap (0, len, PROT_READ | PROT_WRITE, MAP_SHARED,
+ fd, phys_io_base);
+#else
+ base = (unsigned long int) __mmap (0, len, PROT_NONE, MAP_SHARED,
+ fd, phys_io_base);
+#endif
+ __close (fd);
+
+ if ((long) base == -1)
+ return -1;
+
+ io.base = base;
+ }
+ prot = PROT_READ | PROT_WRITE;
+ }
+ else
+ {
+ if (!io.base)
+ return 0; /* never was turned on... */
+
+ prot = PROT_NONE;
+ }
+#if 0
+ /* We can't do mprotect because that would cause us to lose the
+ uncached flag that the /dev/mem driver turned on. A MAP_UNCACHED
+ flag seems so much cleaner... */
+ addr = (io.base + io_offset (from)) & io.page_mask;
+ len = io.base + io_offset (from + num) - addr;
+ return mprotect ((void *) addr, len, prot);
+#else
+ return 0;
+#endif
+}
+
+int
+_iopl (unsigned int level)
+{
+ if (level > 3)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ if (level)
+ {
+ int retval = _ioperm (0, MAX_PORT, 1);
+ /* Match the documented error returns of the x86 version. */
+ if (retval < 0 && errno == EACCES)
+ __set_errno (EPERM);
+ return retval;
+ }
+ return 0;
+}
+
+unsigned int
+_inb (unsigned long int port)
+{
+ volatile unsigned char *addr = (void *) io.base + io_offset (port);
+ unsigned char ret;
+
+ ret = *addr;
+ __ia64_mf_a();
+ return ret;
+}
+
+unsigned int
+_inw (unsigned long int port)
+{
+ volatile unsigned short *addr = (void *) io.base + io_offset (port);
+ unsigned short ret;
+
+ ret = *addr;
+ __ia64_mf_a();
+ return ret;
+}
+
+unsigned int
+_inl (unsigned long int port)
+{
+ volatile unsigned int *addr = (void *) io.base + io_offset (port);
+ unsigned int ret;
+
+ ret = *addr;
+ __ia64_mf_a();
+ return ret;
+}
+
+void
+_outb (unsigned char val, unsigned long int port)
+{
+ volatile unsigned char *addr = (void *) io.base + io_offset (port);
+
+ *addr = val;
+ __ia64_mf_a();
+}
+
+void
+_outw (unsigned short val, unsigned long int port)
+{
+ volatile unsigned short *addr = (void *) io.base + io_offset (port);
+
+ *addr = val;
+ __ia64_mf_a();
+}
+
+void
+_outl (unsigned int val, unsigned long int port)
+{
+ volatile unsigned int *addr = (void *) io.base + io_offset (port);
+
+ *addr = val;
+ __ia64_mf_a();
+}
+
+weak_alias (_ioperm, ioperm);
+weak_alias (_iopl, iopl);
+weak_alias (_inb, inb);
+weak_alias (_inw, inw);
+weak_alias (_inl, inl);
+weak_alias (_outb, outb);
+weak_alias (_outw, outw);
+weak_alias (_outl, outl);
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/kernel_stat.h b/libc/sysdeps/unix/sysv/linux/ia64/kernel_stat.h
new file mode 100644
index 000000000..ef11dc94d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/kernel_stat.h
@@ -0,0 +1,21 @@
+/* Definition of `struct stat' used in the kernel.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define STAT_IS_KERNEL_STAT 1
+#define XSTAT_IS_XSTAT64 1
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/ldconfig.h b/libc/sysdeps/unix/sysv/linux/ia64/ldconfig.h
new file mode 100644
index 000000000..af194898b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/ldconfig.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/ldconfig.h>
+
+#define SYSDEP_KNOWN_INTERPRETER_NAMES \
+ { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 },
+#define SYSDEP_KNOWN_LIBRARY_NAMES \
+ { "libc.so.6", FLAG_ELF_LIBC6 }, \
+ { "libm.so.6", FLAG_ELF_LIBC6 },
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed b/libc/sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed
new file mode 100644
index 000000000..535d1671e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed
@@ -0,0 +1 @@
+s_^\(RTLDLIST=\)\([^ ]*\)-ia64\(\.so\.[0-9.]*\)[ ]*$_\1"\2-ia64\3 \2\3"_
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/ldsodefs.h b/libc/sysdeps/unix/sysv/linux/ia64/ldsodefs.h
new file mode 100644
index 000000000..31af62491
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/ldsodefs.h
@@ -0,0 +1,33 @@
+/* Run-time dynamic linker data structures for loaded ELF shared objects. IA64.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LDSODEFS_H
+
+/* Get the real definitions. */
+#include_next <ldsodefs.h>
+
+/* Now define our stuff. */
+
+/* We need special support to initialize DSO loaded for statically linked
+ binaries. */
+extern void _dl_static_init (struct link_map *map);
+#undef DL_STATIC_INIT
+#define DL_STATIC_INIT(map) _dl_static_init (map)
+
+#endif /* ldsodefs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/makecontext.c b/libc/sysdeps/unix/sysv/linux/ia64/makecontext.c
new file mode 100644
index 000000000..d7a2a9f15
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/makecontext.c
@@ -0,0 +1,93 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <libintl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <sys/rse.h>
+
+
+struct fdesc
+ {
+ unsigned long ip;
+ unsigned long gp;
+ };
+
+#define PUSH(val) \
+do { \
+ if (ia64_rse_is_rnat_slot (rbs)) \
+ *rbs++ = 0; \
+ *rbs++ = (val); \
+} while (0)
+
+
+/* This implementation can handle an ARGC value of at most 8 and
+ values can be passed only in integer registers (r32-r39). */
+
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+ struct sigcontext *sc = &ucp->uc_mcontext;
+ extern void __start_context (ucontext_t *link, long gp, ...);
+ unsigned long stack_start, stack_end;
+ va_list ap;
+ long *rbs;
+ int i;
+
+ stack_start = (long) sc->sc_stack.ss_sp;
+ stack_end = (long) sc->sc_stack.ss_sp + sc->sc_stack.ss_size;
+
+ stack_start = (stack_start + 7) & -8;
+ stack_end = stack_end & -16;
+
+ if (argc > 8)
+ {
+ fprintf (stderr, _("\
+makecontext: does not know how to handle more than 8 arguments\n"));
+ exit (-1);
+ }
+
+ /* set the entry point and global pointer: */
+ sc->sc_br[0] = ((struct fdesc *) &__start_context)->ip;
+ sc->sc_br[1] = ((struct fdesc *) func)->ip;
+ sc->sc_gr[1] = ((struct fdesc *) func)->gp;
+
+ /* set up the call frame: */
+ sc->sc_ar_pfs = ((sc->sc_ar_pfs & ~0x3fffffffffUL)
+ | (argc + 2) | ((argc + 2) << 7));
+ rbs = (long *) stack_start;
+ PUSH((long) ucp->uc_link);
+ PUSH(((struct fdesc *) &__start_context)->gp);
+ va_start (ap, argc);
+ for (i = 0; i < argc; ++i)
+ PUSH(va_arg (ap, long));
+ va_end (ap);
+
+ /* set the memory and register stack pointers: */
+ sc->sc_ar_bsp = (long) rbs;
+ sc->sc_gr[12] = stack_end - 16;
+
+ /* clear the NaT bits for r1 and r12: */
+ sc->sc_nat &= ~((1 << 1) | (1 << 12));
+ sc->sc_ar_rnat = 0;
+}
+
+weak_alias (__makecontext, makecontext)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/pipe.S b/libc/sysdeps/unix/sysv/linux/ia64/pipe.S
new file mode 100644
index 000000000..60624df3c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/pipe.S
@@ -0,0 +1,38 @@
+/* Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger <davidm@hpl.hp.com>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* __pipe is a special syscall since it returns two values. */
+
+#include <sysdep.h>
+
+ENTRY(__pipe)
+ .regstk 1,0,0,0
+ DO_CALL (SYS_ify (pipe))
+ cmp.ne p6,p0=-1,r10
+ ;;
+(p6) st4 [in0]=r8,4
+(p6) mov ret0=0
+ ;;
+(p6) st4 [in0]=r9
+(p6) ret
+ br.cond.spnt.few __syscall_error
+PSEUDO_END(__pipe)
+
+libc_hidden_def (__pipe)
+weak_alias (__pipe, pipe)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/profil-counter.h b/libc/sysdeps/unix/sysv/linux/ia64/profil-counter.h
new file mode 100644
index 000000000..bc9a8433f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/profil-counter.h
@@ -0,0 +1,32 @@
+/* Machine-dependent SIGPROF signal handler. IA-64 version.
+ Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* In many Unix systems signal handlers are called like this
+ and the interrupted PC is easily findable in the `struct sigcontext'. */
+
+static void
+profil_counter (int signr, siginfo_t *si, struct sigcontext *scp)
+{
+ unsigned long ip = scp->sc_ip & ~0X3ULL, slot = scp->sc_ip & 0x3ull;
+
+ /* Note: Linux/ia64 encodes the slot number in bits 0 and 1. We
+ want to multiply the slot number by four so we can use bins of
+ width 4 to get accurate instruction-level profiling. */
+ profil_count ((void *) (ip + 4*slot));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/readelflib.c b/libc/sysdeps/unix/sysv/linux/ia64/readelflib.c
new file mode 100644
index 000000000..7a10d23c9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/readelflib.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2000, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+int process_elf32_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+int process_elf64_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+
+/* Returns 0 if everything is ok, != 0 in case of error. */
+int
+process_elf_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length)
+{
+ ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
+ int ret;
+
+ if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+ return process_elf32_file (file_name, lib, flag, osversion, soname,
+ file_contents, file_length);
+ else
+ {
+ ret = process_elf64_file (file_name, lib, flag, osversion, soname,
+ file_contents, file_length);
+ /* Intel 64bit libraries are always libc.so.6+. */
+ if (!ret)
+ *flag = FLAG_IA64_LIB64|FLAG_ELF_LIBC6;
+ return ret;
+ }
+}
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf32_file
+#define __ELF_NATIVE_CLASS 32
+#include "elf/readelflib.c"
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf64_file
+#define __ELF_NATIVE_CLASS 64
+#include "elf/readelflib.c"
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/register-dump.h b/libc/sysdeps/unix/sysv/linux/ia64/register-dump.h
new file mode 100644
index 000000000..513db974f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/register-dump.h
@@ -0,0 +1,182 @@
+/* Dump registers.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <sys/uio.h>
+#include <stdio-common/_itoa.h>
+
+/* We will print the register dump in this format:
+
+ GP: XXXXXXXXXXXXXXXX R2: XXXXXXXXXXXXXXXX R3: XXXXXXXXXXXXXXXX
+ R8: XXXXXXXXXXXXXXXX R9: XXXXXXXXXXXXXXXX R10: XXXXXXXXXXXXXXXX
+ R11: XXXXXXXXXXXXXXXX SP: XXXXXXXXXXXXXXXX TP: XXXXXXXXXXXXXXXX
+ R14: XXXXXXXXXXXXXXXX R15: XXXXXXXXXXXXXXXX R16: XXXXXXXXXXXXXXXX
+ R17: XXXXXXXXXXXXXXXX R18: XXXXXXXXXXXXXXXX R19: XXXXXXXXXXXXXXXX
+ R20: XXXXXXXXXXXXXXXX R21: XXXXXXXXXXXXXXXX R22: XXXXXXXXXXXXXXXX
+ R23: XXXXXXXXXXXXXXXX R24: XXXXXXXXXXXXXXXX R25: XXXXXXXXXXXXXXXX
+ R26: XXXXXXXXXXXXXXXX R27: XXXXXXXXXXXXXXXX R28: XXXXXXXXXXXXXXXX
+ R29: XXXXXXXXXXXXXXXX R30: XXXXXXXXXXXXXXXX R31: XXXXXXXXXXXXXXXX
+
+ RP: XXXXXXXXXXXXXXXX B6: XXXXXXXXXXXXXXXX B7: XXXXXXXXXXXXXXXX
+
+ IP: XXXXXXXXXXXXXXXX RSC: XXXXXXXXXXXXXXXX PR: XXXXXXXXXXXXXXXX
+ PFS: XXXXXXXXXXXXXXXX UNAT: XXXXXXXXXXXXXXXX CFM: XXXXXXXXXXXXXXXX
+ CCV: XXXXXXXXXXXXXXXX FPSR: XXXXXXXXXXXXXXXX
+
+ F32: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX F33: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ F34: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX F35: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+...
+ F124: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX F125: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ F126: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX F127: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ */
+
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
+{
+ char *cp = _itoa_word (value, buf + len, 16, 0);
+ while (cp > buf)
+ *--cp = '0';
+}
+
+static void
+regvalue (unsigned long int *value, char letter, int regno, char *buf)
+{
+ int n = regno >= 100 ? 3 : regno >= 10 ? 2 : 1;
+ buf[0] = ' ';
+ buf[1] = letter;
+ _itoa_word (regno, buf + 2 + n, 10, 0);
+ buf[2 + n] = ':';
+ for (++n; n <= 4; ++n)
+ buf[2 + n] = ' ';
+ hexvalue (value[0], buf + 7, 16);
+ if (letter == 'F')
+ {
+ hexvalue (value[1], buf + 7 + 16, 16);
+ buf[7 + 32] = '\n';
+ }
+ else
+ buf[7 + 16] = '\n';
+}
+
+static void
+register_dump (int fd, struct sigcontext *ctx)
+{
+ char gpregs[32 - 5][8 + 16];
+ char fpregs[128 - 32][8 + 32];
+ char bpregs[3][8 + 16];
+ char spregs[8][16];
+ struct iovec iov[146];
+ size_t nr = 0;
+ int i;
+
+#define ADD_STRING(str) \
+ do \
+ { \
+ iov[nr].iov_base = (char *) str; \
+ iov[nr].iov_len = strlen (str); \
+ ++nr; \
+ } \
+ while (0)
+#define ADD_MEM(str, len) \
+ do \
+ { \
+ iov[nr].iov_base = str; \
+ iov[nr].iov_len = len; \
+ ++nr; \
+ } \
+ while (0)
+
+ /* Generate strings of register contents. */
+ for (i = 1; i < 4; ++i)
+ {
+ regvalue (&ctx->sc_gr[i], 'R', i, gpregs[i - 1]);
+ if (ctx->sc_nat & (1L << i))
+ memcpy (gpregs[i - 1] + 7, "NaT ", 16);
+ }
+ for (i = 8; i < 32; ++i)
+ {
+ regvalue (&ctx->sc_gr[i], 'R', i, gpregs[i - 5]);
+ if (ctx->sc_nat & (1L << i))
+ memcpy (gpregs[i - 1] + 7, "NaT ", 16);
+ }
+ memcpy (gpregs[0] + 1, "GP:", 3);
+ memcpy (gpregs[7] + 1, "SP: ", 4);
+ memcpy (gpregs[8] + 1, "TP: ", 4);
+
+ regvalue (&ctx->sc_br[0], 'B', 0, bpregs[0]);
+ regvalue (&ctx->sc_br[6], 'B', 6, bpregs[1]);
+ regvalue (&ctx->sc_br[7], 'B', 7, bpregs[2]);
+ memcpy (bpregs[0] + 1, "RP:", 3);
+
+ if (ctx->sc_flags & IA64_SC_FLAG_FPH_VALID)
+ for (i = 32; i < 128; ++i)
+ regvalue (&ctx->sc_fr[i].u.bits[0], 'F', i, fpregs[i - 32]);
+
+ hexvalue (ctx->sc_ip, spregs[0], sizeof (spregs[0]));
+ hexvalue (ctx->sc_ar_rsc, spregs[1], sizeof (spregs[1]));
+ hexvalue (ctx->sc_pr, spregs[2], sizeof (spregs[2]));
+ hexvalue (ctx->sc_ar_pfs, spregs[3], sizeof (spregs[3]));
+ hexvalue (ctx->sc_ar_unat, spregs[4], sizeof (spregs[4]));
+ hexvalue (ctx->sc_cfm, spregs[5], sizeof (spregs[5]));
+ hexvalue (ctx->sc_ar_ccv, spregs[6], sizeof (spregs[6]));
+ hexvalue (ctx->sc_ar_fpsr, spregs[7], sizeof (spregs[7]));
+
+ /* Generate the output. */
+ ADD_STRING ("Register dump:\n\n");
+
+ for (i = 0; i < 32 - 5; ++i)
+ ADD_MEM (gpregs[i], sizeof (gpregs[0]) - 1 + ((i % 3) == 2));
+ ADD_STRING ("\n");
+
+ for (i = 0; i < 3; ++i)
+ ADD_MEM (bpregs[i], sizeof (bpregs[0]) - 1);
+
+ ADD_STRING ("\n\n IP: ");
+ ADD_MEM (spregs[0], sizeof (spregs[0]));
+ ADD_STRING (" RSC: ");
+ ADD_MEM (spregs[1], sizeof (spregs[0]));
+ ADD_STRING (" PR: ");
+ ADD_MEM (spregs[2], sizeof (spregs[0]));
+ ADD_STRING ("\n PFS: ");
+ ADD_MEM (spregs[3], sizeof (spregs[0]));
+ ADD_STRING (" UNAT: ");
+ ADD_MEM (spregs[4], sizeof (spregs[0]));
+ ADD_STRING (" CFM: ");
+ ADD_MEM (spregs[5], sizeof (spregs[0]));
+ ADD_STRING ("\n CCV: ");
+ ADD_MEM (spregs[6], sizeof (spregs[0]));
+ ADD_STRING (" FPSR: ");
+ ADD_MEM (spregs[7], sizeof (spregs[0]));
+ ADD_STRING ("\n");
+
+ if (ctx->sc_flags & IA64_SC_FLAG_FPH_VALID)
+ {
+ ADD_STRING ("\n");
+
+ for (i = 0; i < 128 - 32; ++i)
+ ADD_MEM (fpregs[i], sizeof (fpregs[0]) - 1 + (i & 1));
+ }
+
+ /* Write the stuff out. */
+ writev (fd, iov, nr);
+}
+
+
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/rt-sysdep.S b/libc/sysdeps/unix/sysv/linux/ia64/rt-sysdep.S
new file mode 100644
index 000000000..f966bf1e5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/rt-sysdep.S
@@ -0,0 +1 @@
+#include <sysdep.S>
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/setcontext.S b/libc/sysdeps/unix/sysv/linux/ia64/setcontext.S
new file mode 100644
index 000000000..ef0a93c0c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/setcontext.S
@@ -0,0 +1,153 @@
+/* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <features.h>
+
+#include "ucontext_i.h"
+
+/* __setcontext (const ucontext_t *ucp)
+
+ Restores the machine context in UCP and thereby resumes execution
+ in that context.
+
+ This implementation in intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to restore anything
+ other than the PRESERVED state. */
+
+ENTRY(__setcontext)
+ .prologue
+ .body
+ alloc r11 = ar.pfs, 1, 0, 4, 0
+
+ // sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL):
+
+ mov r3 = SC_MASK
+ mov out0 = SIG_SETMASK
+ ;;
+ add out1 = r3, in0
+ mov out2 = 0
+ mov out3 = 8 // sizeof kernel sigset_t
+
+ invala
+ DO_CALL(__NR_rt_sigprocmask)
+ add r2 = SC_NAT, r32
+
+ add r3 = SC_RNAT, r32 // r3 <- &sc_ar_rnat
+ add rPOS = SC_GR, r32 // rPOS <- &sc_gr[0]
+ ;;
+ ld8 rNAT = [r2], (SC_BSP-SC_NAT)
+ extr.u rPOS = rPOS, 3, 6 // get NaT bit number for r0
+ ;;
+ ld8 rBSP = [r2], (SC_UNAT-SC_BSP)
+ ld8 rRNAT = [r3], (SC_FPSR-SC_RNAT)
+ /*
+ * Rotate NaT bits by rPOS positions to the left:
+ */
+ sub rCPOS = 64, rPOS
+ ;;
+ ld8 rUNAT = [r2], (SC_PFS-SC_UNAT)
+ ld8 rFPSR = [r3], (SC_LC-SC_FPSR)
+ shl rTMP = rNAT, rPOS
+ ;;
+ ld8 rPFS = [r2], (SC_PR-SC_PFS)
+ ld8 rLC = [r3], (SC_BR+0*8-SC_LC)
+ shr.u rNAT = rNAT, rCPOS
+ ;;
+ ld8 rPR = [r2], (SC_BR+1*8-SC_PR)
+ ld8 rB0 = [r3], 16
+ or rNAT = rNAT, rTMP
+ ;;
+ ld8 rB1 = [r2], 16
+ ld8 rB2 = [r3], 16
+ ;;
+ mov.m ar.unat = rNAT
+ mov.m rRSC = ar.rsc
+ ;;
+ ld8 rB3 = [r2], 16
+ ld8 rB4 = [r3], (SC_GR+1*8-(SC_BR+4*8))
+ ;;
+ ld8 rB5 = [r2], (SC_GR+4*8-(SC_BR+5*8))
+ ld8.fill r1 = [r3], (5*8 - 1*8)
+ ;;
+ ld8.fill r4 = [r2], 16
+ ld8.fill r5 = [r3], 16
+ mov b0 = rB0
+ ;;
+ ld8.fill r6 = [r2], 48
+ ld8.fill r7 = [r3], (SC_FR+2*16-(SC_GR+7*8))
+ ;;
+ ld8.fill sp = [r2], (SC_FR+3*16-(SC_GR+12*8))
+ mov.m ar.fpsr = rFPSR
+ mov.i ar.pfs = rPFS
+ ;;
+ ldf.fill f3 = [r2], 16
+ ldf.fill f2 = [r3], 48
+ mov b1 = rB1
+ ;;
+ ldf.fill f4 = [r2], (16*16-4*16)
+ ldf.fill f5 = [r3], (17*16-5*16)
+ mov b2 = rB2
+ ;;
+ ldf.fill f16 = [r2], 32
+ ldf.fill f17 = [r3], 32
+ mov b3 = rB3
+ ;;
+ ldf.fill f18 = [r2], 32
+ ldf.fill f19 = [r3], 32
+ mov b4 = rB4
+ ;;
+ ldf.fill f20 = [r2], 32
+ ldf.fill f21 = [r3], 32
+ mov b5 = rB5
+ ;;
+ ldf.fill f22 = [r2], 32
+ ldf.fill f23 = [r3], 32
+ mov r8 = 0
+ ;;
+ ldf.fill f24 = [r2], 32
+ ldf.fill f25 = [r3], 32
+ mov r9 = 0
+ ;;
+ ldf.fill f26 = [r2], 32
+ ldf.fill f27 = [r3], 32
+ dep rTMP = 0, rRSC, 16, 14 // clear ar.rsc.loadrs
+ ;;
+ ldf.fill f28 = [r2], 32
+ ldf.fill f29 = [r3], 32
+ and rTMP = ~0x3, rTMP // clear ar.rsc.mode
+ ;;
+ ldf.fill f30 = [r2], 32
+ ldf.fill f31 = [r3], 32
+ mov pr = rPR, -1
+ ;;
+ mov.m ar.rsc = rTMP // put RSE into enforced lazy mode
+ ;;
+ loadrs // drop dirty partition
+ ;;
+ mov.m ar.bspstore = rBSP
+ mov.m ar.unat = rUNAT
+ mov.i ar.lc = rLC
+ ;;
+ mov.m ar.rnat = rRNAT
+ mov.m ar.rsc = rRSC
+ ret
+END(__setcontext)
+
+weak_alias (__setcontext, setcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/setjmp.S b/libc/sysdeps/unix/sysv/linux/ia64/setjmp.S
new file mode 100644
index 000000000..53f80d203
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/setjmp.S
@@ -0,0 +1,199 @@
+/* Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005
+ Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA.
+
+ The layout of the jmp_buf is as follows. This is subject to change
+ and user-code should never depend on the particular layout of
+ jmp_buf!
+
+
+ offset: description:
+ ------- ------------
+ 0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS)
+ 0x008 r1 (gp)
+ 0x010 caller's unat
+ 0x018 fpsr
+ 0x020 r4
+ 0x028 r5
+ 0x030 r6
+ 0x038 r7
+ 0x040 rp (b0)
+ 0x048 b1
+ 0x050 b2
+ 0x058 b3
+ 0x060 b4
+ 0x068 b5
+ 0x070 ar.pfs
+ 0x078 ar.lc
+ 0x080 pr
+ 0x088 ar.bsp ; unchangeable (see __longjmp.S)
+ 0x090 ar.unat
+ 0x098 &__jmp_buf ; address of the jmpbuf (needed to locate NaT bits in unat)
+ 0x0a0 f2
+ 0x0b0 f3
+ 0x0c0 f4
+ 0x0d0 f5
+ 0x0e0 f16
+ 0x0f0 f17
+ 0x100 f18
+ 0x110 f19
+ 0x120 f20
+ 0x130 f21
+ 0x130 f22
+ 0x140 f23
+ 0x150 f24
+ 0x160 f25
+ 0x170 f26
+ 0x180 f27
+ 0x190 f28
+ 0x1a0 f29
+ 0x1b0 f30
+ 0x1c0 f31 */
+
+#include <sysdep.h>
+#include <features.h>
+
+ /* The following two entry points are the traditional entry points: */
+
+LEAF(setjmp)
+ alloc r8=ar.pfs,2,0,0,0
+ mov in1=1
+ br.cond.sptk.many _GI___sigsetjmp
+END(setjmp)
+
+LEAF(_setjmp)
+ alloc r8=ar.pfs,2,0,0,0
+ mov in1=0
+ br.cond.sptk.many _GI___sigsetjmp
+END(_setjmp)
+libc_hidden_def (_setjmp)
+
+ /* __sigsetjmp(__jmp_buf buf, int savemask) */
+
+ENTRY(__sigsetjmp)
+ .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
+ alloc loc1=ar.pfs,2,5,2,0
+ .save ar.unat, loc2
+ mov loc2=ar.unat
+ ;;
+ mov r17=ar.fpsr
+ mov r2=in0
+ add r3=8,in0
+ ;;
+.mem.offset 8,0; st8.spill.nta [r2]=sp,16 // r12 (sp)
+.mem.offset 0,0; st8.spill.nta [r3]=gp,16 // r1 (gp)
+ ;;
+ st8.nta [r2]=loc2,16 // save caller's unat
+ st8.nta [r3]=r17,16 // save fpsr
+ add r8=0xa0,in0
+ ;;
+.mem.offset 8,0; st8.spill.nta [r2]=r4,16 // r4
+.mem.offset 0,0; st8.spill.nta [r3]=r5,16 // r5
+ add r9=0xb0,in0
+ ;;
+ stf.spill.nta [r8]=f2,32
+ stf.spill.nta [r9]=f3,32
+ mov loc0=rp
+ .body
+ ;;
+ stf.spill.nta [r8]=f4,32
+ stf.spill.nta [r9]=f5,32
+ mov r17=b1
+ ;;
+ stf.spill.nta [r8]=f16,32
+ stf.spill.nta [r9]=f17,32
+ mov r18=b2
+ ;;
+ stf.spill.nta [r8]=f18,32
+ stf.spill.nta [r9]=f19,32
+ mov r19=b3
+ ;;
+ stf.spill.nta [r8]=f20,32
+ stf.spill.nta [r9]=f21,32
+ mov r20=b4
+ ;;
+ stf.spill.nta [r8]=f22,32
+ stf.spill.nta [r9]=f23,32
+ mov r21=b5
+ ;;
+ stf.spill.nta [r8]=f24,32
+ stf.spill.nta [r9]=f25,32
+ mov r22=ar.lc
+ ;;
+ stf.spill.nta [r8]=f26,32
+ stf.spill.nta [r9]=f27,32
+ mov r24=pr
+ ;;
+ stf.spill.nta [r8]=f28,32
+ stf.spill.nta [r9]=f29,32
+#ifdef PTR_MANGLE
+ mov loc3=loc0
+ ;;
+ PTR_MANGLE (loc3, loc4)
+#else
+ ;;
+#endif
+ stf.spill.nta [r8]=f30
+ stf.spill.nta [r9]=f31
+
+.mem.offset 8,0; st8.spill.nta [r2]=r6,16 // r6
+.mem.offset 0,0; st8.spill.nta [r3]=r7,16 // r7
+ ;;
+ mov r23=ar.bsp
+ mov r25=ar.unat
+ mov out0=in0
+
+#ifdef PTR_MANGLE
+ st8.nta [r2]=loc3,16 // b0
+#else
+ st8.nta [r2]=loc0,16 // b0
+#endif
+ st8.nta [r3]=r17,16 // b1
+ mov out1=in1
+ ;;
+ st8.nta [r2]=r18,16 // b2
+ st8.nta [r3]=r19,16 // b3
+ ;;
+ st8.nta [r2]=r20,16 // b4
+ st8.nta [r3]=r21,16 // b5
+ ;;
+ st8.nta [r2]=loc1,16 // ar.pfs
+ st8.nta [r3]=r22,16 // ar.lc
+ ;;
+ st8.nta [r2]=r24,16 // pr
+ st8.nta [r3]=r23,16 // ar.bsp
+ ;;
+ st8.nta [r2]=r25 // ar.unat
+ st8.nta [r3]=in0 // &__jmp_buf
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ /* In ld.so we never save the signal mask. */
+ ;;
+#else
+ br.call.dpnt.few rp=__sigjmp_save
+#endif
+.ret0: // force a new bundle ::q
+ mov.m ar.unat=loc2 // restore caller's unat
+ mov rp=loc0
+ mov ar.pfs=loc1
+ mov r8=0
+ ret
+END(__sigsetjmp)
+strong_alias(__sigsetjmp, _GI___sigsetjmp)
+
+weak_extern(_setjmp)
+weak_extern(setjmp)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sigaction.c b/libc/sysdeps/unix/sysv/linux/ia64/sigaction.c
new file mode 100644
index 000000000..fdbc93f0e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sigaction.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1997-2000,2002,2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Linux/IA64 specific sigaction
+ Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Linux/ia64 only has rt signals, thus we do not even want to try falling
+ back to the old style signals as the default Linux handler does. */
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. This is the definition. */
+
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+ If OACT is not NULL, put the old action for SIG in *OACT. */
+int
+__libc_sigaction (sig, act, oact)
+ int sig;
+ const struct sigaction *act;
+ struct sigaction *oact;
+{
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ return INLINE_SYSCALL (rt_sigaction, 4, sig,
+ CHECK_1_NULL_OK (act), CHECK_1_NULL_OK (oact), _NSIG / 8);
+}
+libc_hidden_def (__libc_sigaction)
+
+#ifdef WRAPPER_INCLUDE
+# include WRAPPER_INCLUDE
+#endif
+
+#ifndef LIBC_SIGACTION
+weak_alias (__libc_sigaction, __sigaction)
+libc_hidden_def (__sigaction)
+weak_alias (__libc_sigaction, sigaction)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sigcontext-offsets.sym b/libc/sysdeps/unix/sysv/linux/ia64/sigcontext-offsets.sym
new file mode 100644
index 000000000..943e68a66
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sigcontext-offsets.sym
@@ -0,0 +1,16 @@
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+--
+SC_NAT offsetof (struct sigcontext, sc_nat)
+SC_BSP offsetof (struct sigcontext, sc_ar_bsp)
+SC_RNAT offsetof (struct sigcontext, sc_ar_rnat)
+SC_UNAT offsetof (struct sigcontext, sc_ar_unat)
+SC_FPSR offsetof (struct sigcontext, sc_ar_fpsr)
+SC_PFS offsetof (struct sigcontext, sc_ar_pfs)
+SC_LC offsetof (struct sigcontext, sc_ar_lc)
+SC_PR offsetof (struct sigcontext, sc_pr)
+SC_BR offsetof (struct sigcontext, sc_br)
+SC_GR offsetof (struct sigcontext, sc_gr)
+SC_FR offsetof (struct sigcontext, sc_fr)
+SC_MASK offsetof (struct sigcontext, sc_mask)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h b/libc/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h
new file mode 100644
index 000000000..51c11e6b4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define SIGCONTEXT siginfo_t *_si, struct sigcontext *
+#define SIGCONTEXT_EXTRA_ARGS _si,
+#define GET_PC(ctx) ((ctx)->sc_ip)
+#define GET_FRAME(ctx) ((void *) 0)
+#define GET_STACK(ctx) ((void *) 0)
+
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sigpending.c b/libc/sysdeps/unix/sysv/linux/ia64/sigpending.c
new file mode 100644
index 000000000..ae75a5516
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sigpending.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1997, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Linux/ia64 only has rt signals, thus we do not even want to try falling
+ back to the old style signals as the default Linux handler does. */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Change the set of blocked signals to SET,
+ wait until a signal arrives, and restore the set of blocked signals. */
+int
+sigpending (set)
+ sigset_t *set;
+{
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ return INLINE_SYSCALL (rt_sigpending, 2, CHECK_SIGSET (set), _NSIG / 8);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sigprocmask.c b/libc/sysdeps/unix/sysv/linux/ia64/sigprocmask.c
new file mode 100644
index 000000000..ba8b05386
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sigprocmask.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1997, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Linux/IA64 specific sigprocmask
+ Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Linux/ia64 only has rt signals, thus we do not even want to try falling
+ back to the old style signals as the default Linux handler does. */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Get and/or change the set of blocked signals. */
+int
+__sigprocmask (how, set, oset)
+ int how;
+ const sigset_t *set;
+ sigset_t *oset;
+{
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ return INLINE_SYSCALL (rt_sigprocmask, 4, how, CHECK_SIGSET (set),
+ CHECK_SIGSET_NULL_OK (oset), _NSIG / 8);
+}
+weak_alias (__sigprocmask, sigprocmask)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/swapcontext.c b/libc/sysdeps/unix/sysv/linux/ia64/swapcontext.c
new file mode 100644
index 000000000..1b9fbdb6a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/swapcontext.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ucontext.h>
+
+struct rv
+ {
+ long retval;
+ long first_return;
+ };
+
+extern struct rv __getcontext (ucontext_t *__ucp) __THROW;
+extern int __setcontext (__const ucontext_t *__ucp) __THROW;
+
+int
+__swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
+{
+ struct rv rv = __getcontext (oucp);
+ if (rv.first_return)
+ __setcontext (ucp);
+ return 0;
+}
+
+weak_alias (__swapcontext, swapcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sys/io.h b/libc/sysdeps/unix/sysv/linux/ia64/sys/io.h
new file mode 100644
index 000000000..14736ff1c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sys/io.h
@@ -0,0 +1,68 @@
+/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IO_H
+#define _SYS_IO_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* If TURN_ON is TRUE, request for permission to do direct i/o on the
+ port numbers in the range [FROM,FROM+NUM-1]. Otherwise, turn I/O
+ permission off for that range. This call requires root privileges.
+
+ Portability note: not all Linux platforms support this call. Most
+ platforms based on the PC I/O architecture probably will, however.
+ E.g., Linux/Alpha for Alpha PCs supports this. */
+extern int ioperm (unsigned long int __from, unsigned long int __num,
+ int __turn_on);
+
+/* Set the I/O privilege level to LEVEL. If LEVEL>3, permission to
+ access any I/O port is granted. This call requires root
+ privileges. */
+extern int iopl (int __level);
+
+extern unsigned int _inb (unsigned long int __port);
+extern unsigned int _inb (unsigned long int __port);
+extern unsigned int _inw (unsigned long int __port);
+extern unsigned int _inl (unsigned long int __port);
+extern void _outb (unsigned char __val, unsigned long int __port);
+extern void _outw (unsigned short __val, unsigned long int __port);
+extern void _outl (unsigned int __val, unsigned long int __port);
+
+#define inb _inb
+#define inw _inw
+#define inl _inl
+#define outb _outb
+#define outw _outw
+#define outl _outl
+
+/* Access PCI space protected from machine checks. */
+extern int pciconfig_read (unsigned long int __bus, unsigned long int __dfn,
+ unsigned long int __off, unsigned long int __len,
+ unsigned char *__buf);
+
+extern int pciconfig_write (unsigned long int __bus, unsigned long int __dfn,
+ unsigned long int __off, unsigned long int __len,
+ unsigned char *__buf);
+
+__END_DECLS
+
+#endif /* _SYS_IO_H */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sys/procfs.h b/libc/sysdeps/unix/sysv/linux/ia64/sys/procfs.h
new file mode 100644
index 000000000..b5196b997
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sys/procfs.h
@@ -0,0 +1,130 @@
+/* Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H 1
+
+/* This is somehow modelled after the file of the same name on SysVr4
+ systems. It provides a definition of the core file format for ELF
+ used on Linux. */
+
+#include <features.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ucontext.h>
+#include <sys/user.h>
+
+__BEGIN_DECLS
+
+struct elf_siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_code; /* Extra code. */
+ int si_errno; /* Errno. */
+ };
+
+/* We really need just 72 but let's leave some headroom... */
+#define ELF_NGREG 128
+/* f0 and f1 could be omitted, but so what... */
+#define ELF_NFPREG 128
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct ia64_fpreg elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+typedef elf_greg_t greg_t;
+typedef elf_gregset_t gregset_t;
+typedef elf_fpregset_t fpregset_t;
+#define NGREG ELF_NGREG
+
+/* Definitions to generate Intel SVR4-like core files. These mostly
+ have the same names as the SVR4 types with "elf_" tacked on the
+ front to prevent clashes with linux definitions, and the typedef
+ forms have been avoided. This is mostly like the SVR4 structure,
+ but more Linuxy, with things that Linux does not support and which
+ gdb doesn't really use excluded. Fields present but not used are
+ marked with "XXX". */
+struct elf_prstatus
+ {
+#if 0
+ long int pr_flags; /* XXX Process flags. */
+ short int pr_why; /* XXX Reason for process halt. */
+ short int pr_what; /* XXX More detailed reason. */
+#endif
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned long int pr_sigpend; /* Set of pending signals. */
+ unsigned long int pr_sighold; /* Set of held signals. */
+#if 0
+ struct sigaltstack pr_altstack; /* Alternate stack info. */
+ struct sigaction pr_action; /* Signal action for current sig. */
+#endif
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct timeval pr_utime; /* User time. */
+ struct timeval pr_stime; /* System time. */
+ struct timeval pr_cutime; /* Cumulative user time. */
+ struct timeval pr_cstime; /* Cumulative system time. */
+#if 0
+ long int pr_instr; /* Current instruction. */
+#endif
+ elf_gregset_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+#define ELF_PRARGSZ (80) /* Number of chars for args */
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long int pr_flag; /* Flags. */
+ unsigned int pr_uid;
+ unsigned int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+/* Addresses. */
+typedef void *psaddr_t;
+
+/* Register sets. Linux has different names. */
+typedef gregset_t prgregset_t;
+typedef fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+ therefore habe only ine PID type. */
+typedef __pid_t lwpid_t;
+
+
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif /* sys/procfs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sys/ptrace.h b/libc/sysdeps/unix/sysv/linux/ia64/sys/ptrace.h
new file mode 100644
index 000000000..986c4b2d3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sys/ptrace.h
@@ -0,0 +1,135 @@
+/* `ptrace' debugger support interface. Linux/ia64 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PTRACE_H
+#define _SYS_PTRACE_H 1
+
+#include <features.h>
+#include <sys/ucontext.h>
+
+__BEGIN_DECLS
+
+/* Type of the REQUEST argument to `ptrace.' */
+enum __ptrace_request
+{
+ /* Indicate that the process making this request should be traced.
+ All signals received by this process can be intercepted by its
+ parent, and its parent can use the other `ptrace' requests. */
+ PTRACE_TRACEME = 0,
+#define PT_TRACE_ME PTRACE_TRACEME
+
+ /* Return the word in the process's text space at address ADDR. */
+ PTRACE_PEEKTEXT = 1,
+#define PT_READ_I PTRACE_PEEKTEXT
+
+ /* Return the word in the process's data space at address ADDR. */
+ PTRACE_PEEKDATA = 2,
+#define PT_READ_D PTRACE_PEEKDATA
+
+ /* Return the word in the process's user area at offset ADDR. */
+ PTRACE_PEEKUSER = 3,
+#define PT_READ_U PTRACE_PEEKUSER
+
+ /* Write the word DATA into the process's text space at address ADDR. */
+ PTRACE_POKETEXT = 4,
+#define PT_WRITE_I PTRACE_POKETEXT
+
+ /* Write the word DATA into the process's data space at address ADDR. */
+ PTRACE_POKEDATA = 5,
+#define PT_WRITE_D PTRACE_POKEDATA
+
+ /* Write the word DATA into the process's user area at offset ADDR. */
+ PTRACE_POKEUSER = 6,
+#define PT_WRITE_U PTRACE_POKEUSER
+
+ /* Continue the process. */
+ PTRACE_CONT = 7,
+#define PT_CONTINUE PTRACE_CONT
+
+ /* Kill the process. */
+ PTRACE_KILL = 8,
+#define PT_KILL PTRACE_KILL
+
+ /* Single step the process.
+ This is not supported on all machines. */
+ PTRACE_SINGLESTEP = 9,
+#define PT_STEP PTRACE_SINGLESTEP
+
+ /* Execute process until next taken branch. */
+ PTRACE_SINGLEBLOCK = 12,
+#define PT_STEPBLOCK PTRACE_SINGLEBLOCK
+
+ /* Get siginfo for process. */
+ PTRACE_GETSIGINFO = 13,
+#define PT_GETSIGINFO PTRACE_GETSIGINFO
+
+ /* Set new siginfo for process. */
+ PTRACE_SETSIGINFO = 14,
+#define PT_GETSIGINFO PTRACE_GETSIGINFO
+
+ /* Attach to a process that is already running. */
+ PTRACE_ATTACH = 16,
+#define PT_ATTACH PTRACE_ATTACH
+
+ /* Detach from a process attached to with PTRACE_ATTACH. */
+ PTRACE_DETACH = 17,
+#define PT_DETACH PTRACE_DETACH
+
+ /* Get all registers (pt_all_user_regs) in one shot */
+ PTRACE_GETREGS = 18,
+#define PT_GETREGS PTRACE_GETREGS
+
+ /* Set all registers (pt_all_user_regs) in one shot */
+ PTRACE_SETREGS = 19,
+#define PT_SETREGS PTRACE_SETREGS
+
+ /* Continue and stop at the next (return from) syscall. */
+ PTRACE_SYSCALL = 24
+#define PT_SYSCALL PTRACE_SYSCALL
+};
+
+/* pt_all_user_regs is used for PTRACE_GETREGS/PTRACE_SETREGS. */
+struct pt_all_user_regs
+ {
+ unsigned long nat;
+ unsigned long cr_iip;
+ unsigned long cfm;
+ unsigned long cr_ipsr;
+ unsigned long pr;
+
+ unsigned long gr[32];
+ unsigned long br[8];
+ unsigned long ar[128];
+ struct ia64_fpreg fr[128];
+ };
+
+/* Perform process tracing functions. REQUEST is one of the values
+ above, and determines the action to be taken.
+ For all requests except PTRACE_TRACEME, PID specifies the process to be
+ traced.
+
+ PID and the other arguments described above for the various requests should
+ appear (those that are used for the particular request) as:
+ pid_t PID, void *ADDR, int DATA, void *ADDR2
+ after REQUEST. */
+extern long int ptrace (enum __ptrace_request __request, ...) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_PTRACE_H */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sys/rse.h b/libc/sysdeps/unix/sysv/linux/ia64/sys/rse.h
new file mode 100644
index 000000000..1d1c803d3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sys/rse.h
@@ -0,0 +1,78 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _ia64_rse_h
+#define _ia64_rse_h
+
+#include <features.h>
+
+/* Register stack engine related helper functions. This file may be
+ used in applications, so be careful about the name-space and give
+ some consideration to non-GNU C compilers (though __inline is
+ fine). */
+
+static __inline unsigned long
+ia64_rse_slot_num (unsigned long *addr)
+{
+ return (((unsigned long) addr) >> 3) & 0x3f;
+}
+
+/* Return TRUE if ADDR is the address of an RNAT slot. */
+
+static __inline unsigned long
+ia64_rse_is_rnat_slot (unsigned long *addr)
+{
+ return ia64_rse_slot_num (addr) == 0x3f;
+}
+
+/* Returns the address of the RNAT slot that covers the slot at
+ address SLOT_ADDR. */
+
+static __inline unsigned long *
+ia64_rse_rnat_addr (unsigned long *slot_addr)
+{
+ return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3));
+}
+
+/* Calcuate the number of registers in the dirty partition starting at
+ BSPSTORE with a size of DIRTY bytes. This isn't simply DIRTY
+ divided by eight because the 64th slot is used to store ar.rnat. */
+
+static __inline unsigned long
+ia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp)
+{
+ unsigned long slots = (bsp - bspstore);
+
+ return slots - (ia64_rse_slot_num(bspstore) + slots)/0x40;
+}
+
+/* The inverse of the above: given bspstore and the number of
+ registers, calculate ar.bsp. */
+
+static __inline unsigned long *
+ia64_rse_skip_regs (unsigned long *addr, long num_regs)
+{
+ long delta = ia64_rse_slot_num(addr) + num_regs;
+
+ if (num_regs < 0)
+ delta -= 0x3e;
+ return addr + num_regs + delta/0x3f;
+}
+
+#endif /* _ia64_rse_h */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sys/ucontext.h b/libc/sysdeps/unix/sysv/linux/ia64/sys/ucontext.h
new file mode 100644
index 000000000..17dc85f99
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sys/ucontext.h
@@ -0,0 +1,66 @@
+/* Copyright (C) 1998, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+
+#include <bits/sigcontext.h>
+
+/*
+ * These are here mostly for backwards compatibility with older Unices.
+ * IA-64 Linux does not distinguish between "struct sigcontext" and
+ * "ucontext_t" as all the necessary info is inside the former.
+ */
+
+typedef struct sigcontext mcontext_t;
+
+#if defined __cplusplus && __GNUC_PREREQ (3, 5)
+# define _SC_GR0_OFFSET \
+ __builtin_offsetof (struct sigcontext, sc_gr[0])
+#elif defined __GNUC__
+# define _SC_GR0_OFFSET \
+ (((char *) &((struct sigcontext *) 0)->sc_gr[0]) - (char *) 0)
+#else
+# define _SC_GR0_OFFSET 0xc8 /* pray that this is correct... */
+#endif
+
+typedef struct ucontext
+ {
+ union
+ {
+ mcontext_t _mc;
+ struct
+ {
+ unsigned long _pad[_SC_GR0_OFFSET/8];
+ struct ucontext *_link; /* this should overlay sc_gr[0] */
+ }
+ _uc;
+ }
+ _u;
+ }
+ucontext_t;
+
+#define uc_mcontext _u._mc
+#define uc_sigmask _u._mc.sc_mask
+#define uc_stack _u._mc.sc_stack
+#define uc_link _u._uc._link
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sys/user.h b/libc/sysdeps/unix/sysv/linux/ia64/sys/user.h
new file mode 100644
index 000000000..039218761
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sys/user.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H 1
+
+#include <features.h>
+#include <sys/types.h>
+
+/* This definition comes directly from the kernel headers. If
+ anything changes in them this header has to be changed, too. */
+
+
+/* The definition in the kernel has the comment "XXX fix me". */
+#define EF_SIZE 3072
+
+
+struct user
+{
+ unsigned long int regs[EF_SIZE / 8 + 32]; /* Integer and fp regs. */
+ size_t u_tsize; /* Text size (pages). */
+ size_t u_dsize; /* Data size (pages). */
+ size_t u_ssize; /* Stack size (pages). */
+ unsigned long int start_code; /* Text starting address. */
+ unsigned long int start_data; /* Data starting address. */
+ unsigned long int start_stack; /* Stack starting address. */
+ long int signal; /* Signal causing core dump. */
+ struct regs *u_ar0; /* Help gdb find registers. */
+ unsigned long int magic; /* Identifies a core file. */
+ char u_comm[32]; /* User command name. */
+};
+
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_DATA_START_ADDR (u.start_data)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif /* sys/user.h */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/syscall.S b/libc/sysdeps/unix/sysv/linux/ia64/syscall.S
new file mode 100644
index 000000000..c638cc865
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/syscall.S
@@ -0,0 +1,30 @@
+/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jes Sorensen <Jes.Sorensen@cern.ch>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY(syscall)
+ alloc r2=ar.pfs,1,0,8,0
+ mov r15=r32 /* syscall number */
+ break __BREAK_SYSCALL
+ ;;
+ cmp.ne p6,p0=-1,r10 /* r10 = -1 on error */
+(p6) ret
+ br.cond.spnt.few __syscall_error
+PSEUDO_END(syscall)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/syscalls.list b/libc/sysdeps/unix/sysv/linux/ia64/syscalls.list
new file mode 100644
index 000000000..c55c70ef5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/syscalls.list
@@ -0,0 +1,50 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+umount2 - umount 2 __umount2 umount2
+
+getpriority - getpriority i:ii __getpriority getpriority
+
+# semaphore and shm system calls
+msgctl - msgctl i:iip __msgctl msgctl
+msgget - msgget i:ii __msgget msgget
+msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
+msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
+shmat - shmat i:ipi __shmat shmat
+shmctl - shmctl i:iip __shmctl shmctl
+shmdt - shmdt i:s __shmdt shmdt
+shmget - shmget i:iii __shmget shmget
+semop - semop i:ipi __semop semop
+semtimedop - semtimedop i:ipip semtimedop
+semget - semget i:iii __semget semget
+semctl - semctl i:iiii __semctl semctl
+
+# proper socket implementations:
+accept - accept Ci:iBN __libc_accept __accept accept
+bind - bind i:ipi __bind bind
+connect - connect Ci:ipi __libc_connect __connect_internal __connect connect
+getpeername - getpeername i:ipp __getpeername getpeername
+getsockname - getsockname i:ipp __getsockname getsockname
+getsockopt - getsockopt i:iiiBN __getsockopt getsockopt
+listen - listen i:ii __listen listen
+recv - recv Ci:ibni __libc_recv __recv recv
+recvfrom - recvfrom Ci:ibniBN __libc_recvfrom __recvfrom recvfrom
+recvmsg - recvmsg Ci:ipi __libc_recvmsg __recvmsg recvmsg
+send - send Ci:ibni __libc_send __send send
+sendmsg - sendmsg Ci:ipi __libc_sendmsg __sendmsg sendmsg
+sendto - sendto Ci:ibnibn __libc_sendto __sendto sendto
+setsockopt - setsockopt i:iiibn __setsockopt setsockopt
+shutdown - shutdown i:ii __shutdown shutdown
+socket - socket i:iii __socket socket
+socketpair - socketpair i:iiif __socketpair socketpair
+
+# DIG-compliant access to PCI configuration space:
+pciconfig_read EXTRA pciconfig_read 5 pciconfig_read
+pciconfig_write EXTRA pciconfig_write 5 pciconfig_write
+
+ptrace - ptrace 4 __ptrace ptrace
+
+
+# System calls with wrappers.
+
+# IA-64 specific
+getunwind EXTRA getunwind i:pi getunwind
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sysconf.c b/libc/sysdeps/unix/sysv/linux/ia64/sysconf.c
new file mode 100644
index 000000000..4b5d1ce2c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sysconf.c
@@ -0,0 +1,45 @@
+/* Get file-specific information about a file. Linux version.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+#include "has_cpuclock.c"
+
+static long int linux_sysconf (int name);
+
+
+/* Get the value of the system variable NAME. */
+long int
+__sysconf (int name)
+{
+ if (name == _SC_CPUTIME || name == _SC_THREAD_CPUTIME)
+ return has_cpuclock () ? 200112L : -1;
+
+ /* Everything else is handled by the more general code. */
+ return linux_sysconf (name);
+}
+
+/* Now the generic Linux version. */
+#undef __sysconf
+#define __sysconf static linux_sysconf
+#include "../sysconf.c"
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sysdep.S b/libc/sysdeps/unix/sysv/linux/ia64/sysdep.S
new file mode 100644
index 000000000..3633dd4b7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sysdep.S
@@ -0,0 +1,89 @@
+/* Copyright (C) 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <features.h>
+#include <tls.h>
+
+ENTRY(__syscall_error)
+#if RTLD_PRIVATE_ERRNO
+ /*
+ * Note that the gp has to be set properly for this to work.
+ * As long as all syscalls are in the same load unit
+ * (executable or shared library) as this routine, we should
+ * be fine. Otherwise, we would have to first load the global
+ * pointer register from __gp.
+ */
+ addl r2=@gprel(rtld_errno),gp
+ ;;
+ st4 [r2]=r8
+ mov r8=-1
+#elif USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+ addl r2=@ltoff(@tprel(SYSCALL_ERROR_ERRNO)), gp;;
+ ld8 r2=[r2]
+ mov r3=r8;;
+ mov r8=-1
+ add r2=r2,r13;;
+ st4 [r2]=r3
+#elif defined _LIBC_REENTRANT
+ .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(0)
+ alloc r33=ar.pfs, 0, 4, 0, 0
+ mov r32=rp
+ .body
+ mov r35=r8
+ mov r34=r1
+ ;;
+ br.call.sptk.many b0 = __errno_location
+.Lret0: /* force new bundle */
+ st4 [r8]=r35
+ mov r1=r34
+ mov rp=r32
+ mov r8=-1
+ mov ar.pfs=r33
+#else /* _LIBC_REENTRANT */
+ /*
+ * Note that the gp has to be set properly for this to work.
+ * As long as all syscalls are in the same load unit
+ * (executable or shared library) as this routine, we should
+ * be fine. Otherwise, we would have to first load the global
+ * pointer register from __gp.
+ */
+ addl r2=@ltoff(errno),gp
+ ;;
+ ld8 r2=[r2]
+ mov r3=r8
+ mov r8=-1
+ ;;
+ st4 [r2]=r3
+#endif /* _LIBC_REENTRANT */
+ ret // ret is #define'd in syscall.h!
+END(__syscall_error)
+
+ENTRY(__ia64_syscall)
+ mov r15=r37 /* syscall number */
+ break __BREAK_SYSCALL
+ cmp.eq p6,p0=-1,r10 /* r10 = -1 on error */
+(p6) br.cond.spnt.few __syscall_error
+ ret
+PSEUDO_END(__ia64_syscall)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/sysdep.h b/libc/sysdeps/unix/sysv/linux/ia64/sysdep.h
new file mode 100644
index 000000000..dd7a5b1b1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/sysdep.h
@@ -0,0 +1,384 @@
+/* Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
+ Based on code originally written by David Mosberger-Tang
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINUX_IA64_SYSDEP_H
+#define _LINUX_IA64_SYSDEP_H 1
+
+#include <sysdeps/unix/sysdep.h>
+#include <sysdeps/ia64/sysdep.h>
+#include <dl-sysdep.h>
+#include <tls.h>
+
+/* As of GAS v2.4.90.0.7, including a ".align" directive inside a
+ function will cause bad unwind info to be emitted (GAS doesn't know
+ how to account for the padding introduced by the .align directive).
+ Turning on this macro will work around this bug by introducing the
+ necessary padding explicitly. */
+#define GAS_ALIGN_BREAKS_UNWIND_INFO
+
+/* For Linux we can use the system call table in the header file
+ /usr/include/asm/unistd.h
+ of the kernel. But these symbols do not follow the SYS_* syntax
+ so we have to redefine the `SYS_ify' macro here. */
+#undef SYS_ify
+#ifdef __STDC__
+# define SYS_ify(syscall_name) __NR_##syscall_name
+#else
+# define SYS_ify(syscall_name) __NR_/**/syscall_name
+#endif
+
+/* This is a kludge to make syscalls.list find these under the names
+ pread and pwrite, since some kernel headers define those names
+ and some define the *64 names for the same system calls. */
+#if !defined __NR_pread && defined __NR_pread64
+# define __NR_pread __NR_pread64
+#endif
+#if !defined __NR_pwrite && defined __NR_pwrite64
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+/* This is to help the old kernel headers where __NR_semtimedop is not
+ available. */
+#ifndef __NR_semtimedop
+# define __NR_semtimedop 1247
+#endif
+
+#if defined USE_DL_SYSINFO \
+ && (!defined NOT_IN_libc \
+ || defined IS_IN_libpthread || defined IS_IN_librt)
+# define IA64_USE_NEW_STUB
+#else
+# undef IA64_USE_NEW_STUB
+#endif
+
+#ifdef __ASSEMBLER__
+
+#undef CALL_MCOUNT
+#ifdef PROF
+# define CALL_MCOUNT \
+ .data; \
+1: data8 0; /* XXX fixme: use .xdata8 once labels work */ \
+ .previous; \
+ .prologue; \
+ .save ar.pfs, r40; \
+ alloc out0 = ar.pfs, 8, 0, 4, 0; \
+ mov out1 = gp; \
+ .save rp, out2; \
+ mov out2 = rp; \
+ .body; \
+ ;; \
+ addl out3 = @ltoff(1b), gp; \
+ br.call.sptk.many rp = _mcount \
+ ;;
+#else
+# define CALL_MCOUNT /* Do nothing. */
+#endif
+
+/* Linux uses a negative return value to indicate syscall errors, unlike
+ most Unices, which use the condition codes' carry flag.
+
+ Since version 2.1 the return value of a system call might be negative
+ even if the call succeeded. E.g., the `lseek' system call might return
+ a large offset. Therefore we must not anymore test for < 0, but test
+ for a real error by making sure the value in %d0 is a real error
+ number. Linus said he will make sure the no syscall returns a value
+ in -1 .. -4095 as a valid result so we can savely test with -4095. */
+
+/* We don't want the label for the error handler to be visible in the symbol
+ table when we define it here. */
+#define SYSCALL_ERROR_LABEL __syscall_error
+
+#undef PSEUDO
+#define PSEUDO(name, syscall_name, args) \
+ ENTRY(name) \
+ DO_CALL (SYS_ify(syscall_name)); \
+ cmp.eq p6,p0=-1,r10; \
+(p6) br.cond.spnt.few __syscall_error;
+
+#define DO_CALL_VIA_BREAK(num) \
+ mov r15=num; \
+ break __BREAK_SYSCALL
+
+#ifdef IA64_USE_NEW_STUB
+# ifdef SHARED
+# define DO_CALL(num) \
+ .prologue; \
+ adds r2 = SYSINFO_OFFSET, r13;; \
+ ld8 r2 = [r2]; \
+ .save ar.pfs, r11; \
+ mov r11 = ar.pfs;; \
+ .body; \
+ mov r15 = num; \
+ mov b7 = r2; \
+ br.call.sptk.many b6 = b7;; \
+ .restore sp; \
+ mov ar.pfs = r11; \
+ .prologue; \
+ .body
+# else /* !SHARED */
+# define DO_CALL(num) \
+ .prologue; \
+ mov r15 = num; \
+ movl r2 = _dl_sysinfo;; \
+ ld8 r2 = [r2]; \
+ .save ar.pfs, r11; \
+ mov r11 = ar.pfs;; \
+ .body; \
+ mov b7 = r2; \
+ br.call.sptk.many b6 = b7;; \
+ .restore sp; \
+ mov ar.pfs = r11; \
+ .prologue; \
+ .body
+# endif
+#else
+# define DO_CALL(num) DO_CALL_VIA_BREAK(num)
+#endif
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) .endp C_SYMBOL_NAME(name);
+
+#undef PSEUDO_NOERRNO
+#define PSEUDO_NOERRNO(name, syscall_name, args) \
+ ENTRY(name) \
+ DO_CALL (SYS_ify(syscall_name));
+
+#undef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(name) .endp C_SYMBOL_NAME(name);
+
+#undef PSEUDO_ERRVAL
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ ENTRY(name) \
+ DO_CALL (SYS_ify(syscall_name)); \
+ cmp.eq p6,p0=-1,r10; \
+(p6) mov r10=r8;
+
+
+#undef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(name) .endp C_SYMBOL_NAME(name);
+
+#undef END
+#define END(name) \
+ .size C_SYMBOL_NAME(name), . - C_SYMBOL_NAME(name) ; \
+ .endp C_SYMBOL_NAME(name)
+
+#define ret br.ret.sptk.few b0
+#define ret_NOERRNO ret
+#define ret_ERRVAL ret
+
+#else /* not __ASSEMBLER__ */
+
+#define BREAK_INSN_1(num) "break " #num ";;\n\t"
+#define BREAK_INSN(num) BREAK_INSN_1(num)
+
+/* On IA-64 we have stacked registers for passing arguments. The
+ "out" registers end up being the called function's "in"
+ registers.
+
+ Also, since we have plenty of registers we have two return values
+ from a syscall. r10 is set to -1 on error, whilst r8 contains the
+ (non-negative) errno on error or the return value on success.
+ */
+
+#ifdef IA64_USE_NEW_STUB
+
+# define DO_INLINE_SYSCALL_NCS(name, nr, args...) \
+ LOAD_ARGS_##nr (args) \
+ register long _r8 __asm ("r8"); \
+ register long _r10 __asm ("r10"); \
+ register long _r15 __asm ("r15") = name; \
+ register void *_b7 __asm ("b7") = ((tcbhead_t *)__thread_self)->__private;\
+ long _retval; \
+ LOAD_REGS_##nr \
+ /* \
+ * Don't specify any unwind info here. We mark ar.pfs as \
+ * clobbered. This will force the compiler to save ar.pfs \
+ * somewhere and emit appropriate unwind info for that save. \
+ */ \
+ __asm __volatile ("br.call.sptk.many b6=%0;;\n" \
+ : "=b"(_b7), "=r" (_r8), "=r" (_r10), "=r" (_r15) \
+ ASM_OUTARGS_##nr \
+ : "0" (_b7), "3" (_r15) ASM_ARGS_##nr \
+ : "memory", "ar.pfs" ASM_CLOBBERS_##nr); \
+ _retval = _r8;
+
+#else /* !IA64_USE_NEW_STUB */
+
+# define DO_INLINE_SYSCALL_NCS(name, nr, args...) \
+ LOAD_ARGS_##nr (args) \
+ register long _r8 asm ("r8"); \
+ register long _r10 asm ("r10"); \
+ register long _r15 asm ("r15") = name; \
+ long _retval; \
+ LOAD_REGS_##nr \
+ __asm __volatile (BREAK_INSN (__BREAK_SYSCALL) \
+ : "=r" (_r8), "=r" (_r10), "=r" (_r15) \
+ ASM_OUTARGS_##nr \
+ : "2" (_r15) ASM_ARGS_##nr \
+ : "memory" ASM_CLOBBERS_##nr); \
+ _retval = _r8;
+
+#endif /* !IA64_USE_NEW_STUB */
+
+#define DO_INLINE_SYSCALL(name, nr, args...) \
+ DO_INLINE_SYSCALL_NCS (__NR_##name, nr, ##args)
+
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+ ({ \
+ DO_INLINE_SYSCALL_NCS (__NR_##name, nr, args) \
+ if (_r10 == -1) \
+ { \
+ __set_errno (_retval); \
+ _retval = -1; \
+ } \
+ _retval; })
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) long int err
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ DO_INLINE_SYSCALL_NCS (name, nr, args) \
+ err = _r10; \
+ _retval; })
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) (err == -1)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) (val)
+
+#define LOAD_ARGS_0()
+#define LOAD_REGS_0
+#define LOAD_ARGS_1(a1) \
+ long _arg1 = (long) (a1); \
+ LOAD_ARGS_0 ()
+#define LOAD_REGS_1 \
+ register long _out0 asm ("out0") = _arg1; \
+ LOAD_REGS_0
+#define LOAD_ARGS_2(a1, a2) \
+ long _arg2 = (long) (a2); \
+ LOAD_ARGS_1 (a1)
+#define LOAD_REGS_2 \
+ register long _out1 asm ("out1") = _arg2; \
+ LOAD_REGS_1
+#define LOAD_ARGS_3(a1, a2, a3) \
+ long _arg3 = (long) (a3); \
+ LOAD_ARGS_2 (a1, a2)
+#define LOAD_REGS_3 \
+ register long _out2 asm ("out2") = _arg3; \
+ LOAD_REGS_2
+#define LOAD_ARGS_4(a1, a2, a3, a4) \
+ long _arg4 = (long) (a4); \
+ LOAD_ARGS_3 (a1, a2, a3)
+#define LOAD_REGS_4 \
+ register long _out3 asm ("out3") = _arg4; \
+ LOAD_REGS_3
+#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
+ long _arg5 = (long) (a5); \
+ LOAD_ARGS_4 (a1, a2, a3, a4)
+#define LOAD_REGS_5 \
+ register long _out4 asm ("out4") = _arg5; \
+ LOAD_REGS_4
+#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
+ long _arg6 = (long) (a6); \
+ LOAD_ARGS_5 (a1, a2, a3, a4, a5)
+#define LOAD_REGS_6 \
+ register long _out5 asm ("out5") = _arg6; \
+ LOAD_REGS_5
+
+#define ASM_OUTARGS_0
+#define ASM_OUTARGS_1 ASM_OUTARGS_0, "=r" (_out0)
+#define ASM_OUTARGS_2 ASM_OUTARGS_1, "=r" (_out1)
+#define ASM_OUTARGS_3 ASM_OUTARGS_2, "=r" (_out2)
+#define ASM_OUTARGS_4 ASM_OUTARGS_3, "=r" (_out3)
+#define ASM_OUTARGS_5 ASM_OUTARGS_4, "=r" (_out4)
+#define ASM_OUTARGS_6 ASM_OUTARGS_5, "=r" (_out5)
+
+#ifdef IA64_USE_NEW_STUB
+#define ASM_ARGS_0
+#define ASM_ARGS_1 ASM_ARGS_0, "4" (_out0)
+#define ASM_ARGS_2 ASM_ARGS_1, "5" (_out1)
+#define ASM_ARGS_3 ASM_ARGS_2, "6" (_out2)
+#define ASM_ARGS_4 ASM_ARGS_3, "7" (_out3)
+#define ASM_ARGS_5 ASM_ARGS_4, "8" (_out4)
+#define ASM_ARGS_6 ASM_ARGS_5, "9" (_out5)
+#else
+#define ASM_ARGS_0
+#define ASM_ARGS_1 ASM_ARGS_0, "3" (_out0)
+#define ASM_ARGS_2 ASM_ARGS_1, "4" (_out1)
+#define ASM_ARGS_3 ASM_ARGS_2, "5" (_out2)
+#define ASM_ARGS_4 ASM_ARGS_3, "6" (_out3)
+#define ASM_ARGS_5 ASM_ARGS_4, "7" (_out4)
+#define ASM_ARGS_6 ASM_ARGS_5, "8" (_out5)
+#endif
+
+#define ASM_CLOBBERS_0 ASM_CLOBBERS_1, "out0"
+#define ASM_CLOBBERS_1 ASM_CLOBBERS_2, "out1"
+#define ASM_CLOBBERS_2 ASM_CLOBBERS_3, "out2"
+#define ASM_CLOBBERS_3 ASM_CLOBBERS_4, "out3"
+#define ASM_CLOBBERS_4 ASM_CLOBBERS_5, "out4"
+#define ASM_CLOBBERS_5 ASM_CLOBBERS_6, "out5"
+#define ASM_CLOBBERS_6_COMMON , "out6", "out7", \
+ /* Non-stacked integer registers, minus r8, r10, r15. */ \
+ "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \
+ "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \
+ "r28", "r29", "r30", "r31", \
+ /* Predicate registers. */ \
+ "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \
+ /* Non-rotating fp registers. */ \
+ "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ /* Branch registers. */ \
+ "b6"
+
+#ifdef IA64_USE_NEW_STUB
+# define ASM_CLOBBERS_6 ASM_CLOBBERS_6_COMMON
+#else
+# define ASM_CLOBBERS_6 ASM_CLOBBERS_6_COMMON , "b7"
+#endif
+
+#endif /* not __ASSEMBLER__ */
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. */
+#else
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(reg, tmpreg) \
+ add tmpreg=-16,r13 \
+ ;; \
+ ld8 tmpreg=[tmpreg] \
+ ;; \
+ xor reg=reg, tmpreg
+# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg)
+# else
+# define PTR_MANGLE(var) \
+ (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+# define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#endif
+
+#endif /* linux/ia64/sysdep.h */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/system.c b/libc/sysdeps/unix/sysv/linux/ia64/system.c
new file mode 100644
index 000000000..413ff27b3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/system.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <kernel-features.h>
+
+/* We have to and actually can handle cancelable system(). The big
+ problem: we have to kill the child process if necessary. To do
+ this a cleanup handler has to be registered and is has to be able
+ to find the PID of the child. The main problem is to reliable have
+ the PID when needed. It is not necessary for the parent thread to
+ return. It might still be in the kernel when the cancellation
+ request comes. Therefore we have to use the clone() calls ability
+ to have the kernel write the PID into the user-level variable. */
+#ifdef __ASSUME_CLONE_THREAD_FLAGS
+# define FORK() \
+ INLINE_SYSCALL (clone2, 6, CLONE_PARENT_SETTID | SIGCHLD, NULL, 0, \
+ &pid, NULL, NULL)
+#endif
+
+#include "../system.c"
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/ucontext_i.h b/libc/sysdeps/unix/sysv/linux/ia64/ucontext_i.h
new file mode 100644
index 000000000..e2a4d3c2b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/ucontext_i.h
@@ -0,0 +1,47 @@
+/* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Constants shared between setcontext() and getcontext(). Don't
+ install this header file. */
+
+#define SIG_BLOCK 0
+#define SIG_UNBLOCK 1
+#define SIG_SETMASK 2
+
+#include <sigcontext-offsets.h>
+
+#define rTMP r16
+#define rPOS r16
+#define rCPOS r17
+#define rNAT r18
+
+#define rB5 r18
+#define rB4 r19
+#define rB3 r20
+#define rB2 r21
+#define rB1 r22
+#define rB0 r23
+#define rRSC r24
+#define rBSP r25
+#define rRNAT r26
+#define rUNAT r27
+#define rFPSR r28
+#define rPFS r29
+#define rLC r30
+#define rPR r31
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/umount.c b/libc/sysdeps/unix/sysv/linux/ia64/umount.c
new file mode 100644
index 000000000..462ace325
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/umount.c
@@ -0,0 +1,31 @@
+/* umount system call for Linux/ia64.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/mount.h>
+#include <errno.h>
+
+#include <sysdep.h>
+#include <bp-checks.h>
+
+/* Unmount a filesystem. */
+int
+umount (const char *special_file)
+{
+ return INLINE_SYSCALL (umount, 2, CHECK_STRING (special_file), 0);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c b/libc/sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c
new file mode 100644
index 000000000..15d12abfc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/unwind-dw2-fde.c
@@ -0,0 +1 @@
+/* Linux/ia64 does not need unwind table registry. */
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/vfork.S b/libc/sysdeps/unix/sysv/linux/ia64/vfork.S
new file mode 100644
index 000000000..086fce938
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/vfork.S
@@ -0,0 +1,44 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#include <sysdep.h>
+#define _SIGNAL_H
+#include <bits/signum.h>
+
+/* The following are defined in linux/sched.h, which unfortunately */
+/* is not safe for inclusion in an assembly file. */
+#define CLONE_VM 0x00000100 /* set if VM shared between processes */
+#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
+
+/* pid_t vfork(void); */
+/* Implemented as __clone_syscall(CLONE_VFORK | CLONE_VM | SIGCHLD, 0) */
+
+ENTRY(__vfork)
+ alloc r2=ar.pfs,0,0,2,0
+ mov out0=CLONE_VM+CLONE_VFORK+SIGCHLD
+ mov out1=0 /* Standard sp value. */
+ ;;
+ DO_CALL_VIA_BREAK (SYS_ify (clone))
+ cmp.eq p6,p0=-1,r10
+(p6) br.cond.spnt.few __syscall_error
+ ret
+PSEUDO_END(__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/wordexp.c b/libc/sysdeps/unix/sysv/linux/ia64/wordexp.c
new file mode 100644
index 000000000..2e3d5bc2e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ia64/wordexp.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/alpha/wordexp.c>
diff --git a/libc/sysdeps/unix/sysv/linux/if_index.c b/libc/sysdeps/unix/sysv/linux/if_index.c
new file mode 100644
index 000000000..66f0ac131
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/if_index.c
@@ -0,0 +1,474 @@
+/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <alloca.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <bits/libc-lock.h>
+#include <not-cancel.h>
+
+#include "netlinkaccess.h"
+
+
+/* Variable to signal whether SIOCGIFCONF is not available. */
+# if __ASSUME_SIOCGIFNAME == 0
+static int old_siocgifconf;
+#else
+# define old_siocgifconf 0
+#endif
+
+
+unsigned int
+if_nametoindex (const char *ifname)
+{
+#ifndef SIOCGIFINDEX
+ __set_errno (ENOSYS);
+ return 0;
+#else
+ struct ifreq ifr;
+ int fd = __opensock ();
+
+ if (fd < 0)
+ return 0;
+
+ strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+ if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
+ {
+ int saved_errno = errno;
+ close_not_cancel_no_status (fd);
+ if (saved_errno == EINVAL)
+ __set_errno (ENOSYS);
+ return 0;
+ }
+ close_not_cancel_no_status (fd);
+ return ifr.ifr_ifindex;
+#endif
+}
+libc_hidden_def (if_nametoindex)
+
+
+void
+if_freenameindex (struct if_nameindex *ifn)
+{
+ struct if_nameindex *ptr = ifn;
+ while (ptr->if_name || ptr->if_index)
+ {
+ free (ptr->if_name);
+ ++ptr;
+ }
+ free (ifn);
+}
+libc_hidden_def (if_freenameindex)
+
+
+#if __ASSUME_NETLINK_SUPPORT == 0
+static struct if_nameindex *
+if_nameindex_ioctl (void)
+{
+ int fd = __opensock ();
+ struct ifconf ifc;
+ unsigned int nifs, i;
+ int rq_len;
+ struct if_nameindex *idx = NULL;
+# define RQ_IFS 4
+
+ if (fd < 0)
+ return NULL;
+
+ ifc.ifc_buf = NULL;
+
+ /* We may be able to get the needed buffer size directly, rather than
+ guessing. */
+ if (! old_siocgifconf)
+ {
+ ifc.ifc_buf = NULL;
+ ifc.ifc_len = 0;
+ if (__ioctl (fd, SIOCGIFCONF, &ifc) < 0 || ifc.ifc_len == 0)
+ {
+# if __ASSUME_SIOCGIFNAME == 0
+ old_siocgifconf = 1;
+# endif
+ rq_len = RQ_IFS * sizeof (struct ifreq);
+ }
+ else
+ rq_len = ifc.ifc_len;
+ }
+ else
+ rq_len = RQ_IFS * sizeof (struct ifreq);
+
+ /* Read all the interfaces out of the kernel. */
+ ifc.ifc_buf = alloca (rq_len);
+ ifc.ifc_len = rq_len;
+ while (1)
+ {
+ if (__ioctl (fd, SIOCGIFCONF, &ifc) < 0)
+ {
+ close_not_cancel_no_status (fd);
+ return NULL;
+ }
+ if (ifc.ifc_len < rq_len || ! old_siocgifconf)
+ break;
+
+ ifc.ifc_buf = extend_alloca (ifc.ifc_buf, rq_len, 2 * rq_len);
+ ifc.ifc_len = rq_len;
+ }
+
+ nifs = ifc.ifc_len / sizeof (struct ifreq);
+
+ idx = malloc ((nifs + 1) * sizeof (struct if_nameindex));
+ if (idx == NULL)
+ {
+ close_not_cancel_no_status (fd);
+ __set_errno (ENOBUFS);
+ return NULL;
+ }
+
+ for (i = 0; i < nifs; ++i)
+ {
+ struct ifreq *ifr = &ifc.ifc_req[i];
+ idx[i].if_name = __strdup (ifr->ifr_name);
+ if (idx[i].if_name == NULL
+ || __ioctl (fd, SIOCGIFINDEX, ifr) < 0)
+ {
+ int saved_errno = errno;
+ unsigned int j;
+
+ for (j = 0; j < i; ++j)
+ free (idx[j].if_name);
+ free (idx);
+ close_not_cancel_no_status (fd);
+ if (saved_errno == EINVAL)
+ saved_errno = ENOSYS;
+ else if (saved_errno == ENOMEM)
+ saved_errno = ENOBUFS;
+ __set_errno (saved_errno);
+ return NULL;
+ }
+ idx[i].if_index = ifr->ifr_ifindex;
+ }
+
+ idx[i].if_index = 0;
+ idx[i].if_name = NULL;
+
+ close_not_cancel_no_status (fd);
+ return idx;
+}
+#endif
+
+
+static struct if_nameindex *
+if_nameindex_netlink (void)
+{
+ struct netlink_handle nh = { 0, 0, 0, NULL, NULL };
+ struct if_nameindex *idx = NULL;
+
+ if (__no_netlink_support || __netlink_open (&nh) < 0)
+ return NULL;
+
+
+ /* Tell the kernel that we wish to get a list of all
+ active interfaces. Collect all data for every interface. */
+ if (__netlink_request (&nh, RTM_GETLINK) < 0)
+ goto exit_free;
+
+ /* Count the interfaces. */
+ unsigned int nifs = 0;
+ for (struct netlink_res *nlp = nh.nlm_list; nlp; nlp = nlp->next)
+ {
+ struct nlmsghdr *nlh;
+ size_t size = nlp->size;
+
+ if (nlp->nlh == NULL)
+ continue;
+
+ /* Walk through all entries we got from the kernel and look, which
+ message type they contain. */
+ for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
+ {
+ /* Check if the message is what we want. */
+ if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
+ continue;
+
+ if (nlh->nlmsg_type == NLMSG_DONE)
+ break; /* ok */
+
+ if (nlh->nlmsg_type == RTM_NEWLINK)
+ ++nifs;
+ }
+ }
+
+ idx = malloc ((nifs + 1) * sizeof (struct if_nameindex));
+ if (idx == NULL)
+ {
+ nomem:
+ __set_errno (ENOBUFS);
+ goto exit_free;
+ }
+
+ /* Add the interfaces. */
+ nifs = 0;
+ for (struct netlink_res *nlp = nh.nlm_list; nlp; nlp = nlp->next)
+ {
+ struct nlmsghdr *nlh;
+ size_t size = nlp->size;
+
+ if (nlp->nlh == NULL)
+ continue;
+
+ /* Walk through all entries we got from the kernel and look, which
+ message type they contain. */
+ for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
+ {
+ /* Check if the message is what we want. */
+ if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
+ continue;
+
+ if (nlh->nlmsg_type == NLMSG_DONE)
+ break; /* ok */
+
+ if (nlh->nlmsg_type == RTM_NEWLINK)
+ {
+ struct ifinfomsg *ifim = (struct ifinfomsg *) NLMSG_DATA (nlh);
+ struct rtattr *rta = IFLA_RTA (ifim);
+ size_t rtasize = IFLA_PAYLOAD (nlh);
+
+ idx[nifs].if_index = ifim->ifi_index;
+
+ while (RTA_OK (rta, rtasize))
+ {
+ char *rta_data = RTA_DATA (rta);
+ size_t rta_payload = RTA_PAYLOAD (rta);
+
+ if (rta->rta_type == IFLA_IFNAME)
+ {
+ idx[nifs].if_name = __strndup (rta_data, rta_payload);
+ if (idx[nifs].if_name == NULL)
+ {
+ idx[nifs].if_index = 0;
+ if_freenameindex (idx);
+ idx = NULL;
+ goto nomem;
+ }
+ break;
+ }
+
+ rta = RTA_NEXT (rta, rtasize);
+ }
+
+ ++nifs;
+ }
+ }
+ }
+
+ idx[nifs].if_index = 0;
+ idx[nifs].if_name = NULL;
+
+ exit_free:
+ __netlink_free_handle (&nh);
+ __netlink_close (&nh);
+
+ return idx;
+}
+
+
+struct if_nameindex *
+if_nameindex (void)
+{
+#ifndef SIOCGIFINDEX
+ __set_errno (ENOSYS);
+ return NULL;
+#else
+ struct if_nameindex *result = if_nameindex_netlink ();
+# if __ASSUME_NETLINK_SUPPORT == 0
+ if (__no_netlink_support)
+ result = if_nameindex_ioctl ();
+# endif
+ return result;
+#endif
+}
+libc_hidden_def (if_nameindex)
+
+
+char *
+if_indextoname (unsigned int ifindex, char *ifname)
+{
+#if !defined SIOCGIFINDEX && __ASSUME_SIOCGIFNAME == 0
+ __set_errno (ENOSYS);
+ return NULL;
+#else
+# if __ASSUME_SIOCGIFNAME == 0
+ struct if_nameindex *idx;
+ struct if_nameindex *p;
+ char *result = NULL;
+# endif
+
+# if defined SIOCGIFNAME || __ASSUME_SIOCGIFNAME > 0
+ /* We may be able to do the conversion directly, rather than searching a
+ list. This ioctl is not present in kernels before version 2.1.50. */
+ struct ifreq ifr;
+ int fd;
+# if __ASSUME_SIOCGIFNAME == 0
+ static int siocgifname_works_not;
+
+ if (!siocgifname_works_not)
+# endif
+ {
+# if __ASSUME_SIOCGIFNAME == 0
+ int serrno = errno;
+# endif
+ int status;
+
+ fd = __opensock ();
+
+ if (fd < 0)
+ return NULL;
+
+ ifr.ifr_ifindex = ifindex;
+ status = __ioctl (fd, SIOCGIFNAME, &ifr);
+
+ close_not_cancel_no_status (fd);
+
+ if (status < 0)
+ {
+# if __ASSUME_SIOCGIFNAME == 0
+ if (errno == EINVAL)
+ siocgifname_works_not = 1; /* Don't make the same mistake twice. */
+ else
+# endif
+ {
+ if (errno == ENODEV)
+ /* POSIX requires ENXIO. */
+ __set_errno (ENXIO);
+
+ return NULL;
+ }
+ }
+ else
+ return strncpy (ifname, ifr.ifr_name, IFNAMSIZ);
+
+# if __ASSUME_SIOCGIFNAME == 0
+ __set_errno (serrno);
+# endif
+ }
+# endif
+
+# if __ASSUME_SIOCGIFNAME == 0
+ idx = if_nameindex ();
+
+ if (idx != NULL)
+ {
+ for (p = idx; p->if_index || p->if_name; ++p)
+ if (p->if_index == ifindex)
+ {
+ result = strncpy (ifname, p->if_name, IFNAMSIZ);
+ break;
+ }
+
+ if_freenameindex (idx);
+
+ if (result == NULL)
+ __set_errno (ENXIO);
+ }
+ return result;
+# endif
+#endif
+}
+libc_hidden_def (if_indextoname)
+
+
+#if 0
+void
+internal_function
+__protocol_available (int *have_inet, int *have_inet6)
+{
+ int fd = __opensock ();
+ unsigned int nifs;
+ int rq_len;
+ struct ifconf ifc;
+# define RQ_IFS 4
+
+ /* Wirst case assumption. */
+ *have_inet = 0;
+ *have_inet6 = 0;
+
+ if (fd < 0)
+ /* We cannot open the socket. No networking at all? */
+ return;
+
+ /* We may be able to get the needed buffer size directly, rather than
+ guessing. */
+ if (! old_siocgifconf)
+ {
+ ifc.ifc_buf = NULL;
+ ifc.ifc_len = 0;
+ if (__ioctl (fd, SIOCGIFCONF, &ifc) < 0 || ifc.ifc_len == 0)
+ {
+# if __ASSUME_SIOCGIFNAME == 0
+ old_siocgifconf = 1;
+# endif
+ rq_len = RQ_IFS * sizeof (struct ifreq);
+ }
+ else
+ rq_len = ifc.ifc_len;
+ }
+ else
+ rq_len = RQ_IFS * sizeof (struct ifreq);
+
+ /* Read all the interfaces out of the kernel. */
+ do
+ {
+ ifc.ifc_buf = alloca (ifc.ifc_len = rq_len);
+ if (__ioctl (fd, SIOCGIFCONF, &ifc) < 0)
+ {
+ close_not_cancel_no_status (fd);
+ return;
+ }
+ rq_len *= 2;
+ }
+ while (ifc.ifc_len == rq_len && old_siocgifconf);
+
+ nifs = ifc.ifc_len / sizeof (struct ifreq);
+
+ /* Go through all the interfaces and get the address. */
+ while (nifs-- > 0)
+ if (__ioctl (fd, SIOCGIFADDR, &ifc.ifc_req[nifs]) >= 0)
+ {
+ /* We successfully got information about this interface. Now
+ test whether it is an IPv4 or IPv6 address. */
+ if (ifc.ifc_req[nifs].ifr_addr.sa_family == AF_INET)
+ *have_inet = 1;
+ else if (ifc.ifc_req[nifs].ifr_addr.sa_family == AF_INET6)
+ *have_inet6 = 1;
+
+ /* Note, this is & not &&. It works since the values are always
+ 0 or 1. */
+ if (*have_inet & *have_inet6)
+ /* We can stop early. */
+ break;
+ }
+
+ close_not_cancel_no_status (fd);
+}
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/ifaddrs.c b/libc/sysdeps/unix/sysv/linux/ifaddrs.c
new file mode 100644
index 000000000..82495de03
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ifaddrs.c
@@ -0,0 +1,863 @@
+/* getifaddrs -- get names and addresses of all network interfaces
+ Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <alloca.h>
+#include <assert.h>
+#include <errno.h>
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netpacket/packet.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sysdep.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "netlinkaccess.h"
+
+
+/* We don't know if we have NETLINK support compiled in in our
+ Kernel, so include the old implementation as fallback. */
+#if __ASSUME_NETLINK_SUPPORT == 0
+int __no_netlink_support attribute_hidden;
+
+# define getifaddrs fallback_getifaddrs
+# include "sysdeps/gnu/ifaddrs.c"
+# undef getifaddrs
+#endif
+
+
+/* struct to hold the data for one ifaddrs entry, so we can allocate
+ everything at once. */
+struct ifaddrs_storage
+{
+ struct ifaddrs ifa;
+ union
+ {
+ /* Save space for the biggest of the four used sockaddr types and
+ avoid a lot of casts. */
+ struct sockaddr sa;
+ struct sockaddr_ll sl;
+ struct sockaddr_in s4;
+ struct sockaddr_in6 s6;
+ } addr, netmask, broadaddr;
+ char name[IF_NAMESIZE + 1];
+};
+
+
+void
+__netlink_free_handle (struct netlink_handle *h)
+{
+ struct netlink_res *ptr;
+ int saved_errno = errno;
+
+ ptr = h->nlm_list;
+ while (ptr != NULL)
+ {
+ struct netlink_res *tmpptr;
+
+ tmpptr = ptr->next;
+ free (ptr);
+ ptr = tmpptr;
+ }
+
+ __set_errno (saved_errno);
+}
+
+
+static int
+__netlink_sendreq (struct netlink_handle *h, int type)
+{
+ struct req
+ {
+ struct nlmsghdr nlh;
+ struct rtgenmsg g;
+ char pad[0];
+ } req;
+ struct sockaddr_nl nladdr;
+
+ if (h->seq == 0)
+ h->seq = time (NULL);
+
+ req.nlh.nlmsg_len = sizeof (req);
+ req.nlh.nlmsg_type = type;
+ req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
+ req.nlh.nlmsg_pid = 0;
+ req.nlh.nlmsg_seq = h->seq;
+ req.g.rtgen_family = AF_UNSPEC;
+ if (sizeof (req) != offsetof (struct req, pad))
+ memset (req.pad, '\0', sizeof (req) - offsetof (struct req, pad));
+
+ memset (&nladdr, '\0', sizeof (nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ return TEMP_FAILURE_RETRY (__sendto (h->fd, (void *) &req, sizeof (req), 0,
+ (struct sockaddr *) &nladdr,
+ sizeof (nladdr)));
+}
+
+
+int
+__netlink_request (struct netlink_handle *h, int type)
+{
+ struct netlink_res *nlm_next;
+ struct netlink_res **new_nlm_list;
+ static volatile size_t buf_size = 4096;
+ char *buf;
+ struct sockaddr_nl nladdr;
+ struct nlmsghdr *nlmh;
+ ssize_t read_len;
+ bool done = false;
+ bool use_malloc = false;
+
+ if (__netlink_sendreq (h, type) < 0)
+ return -1;
+
+ size_t this_buf_size = buf_size;
+ if (__libc_use_alloca (this_buf_size))
+ buf = alloca (this_buf_size);
+ else
+ {
+ buf = malloc (this_buf_size);
+ if (buf != NULL)
+ use_malloc = true;
+ else
+ goto out_fail;
+ }
+
+ struct iovec iov = { buf, this_buf_size };
+
+ if (h->nlm_list != NULL)
+ new_nlm_list = &h->end_ptr->next;
+ else
+ new_nlm_list = &h->nlm_list;
+
+ while (! done)
+ {
+ struct msghdr msg =
+ {
+ (void *) &nladdr, sizeof (nladdr),
+ &iov, 1,
+ NULL, 0,
+ 0
+ };
+
+ read_len = TEMP_FAILURE_RETRY (__recvmsg (h->fd, &msg, 0));
+ if (read_len < 0)
+ goto out_fail;
+
+ if (nladdr.nl_pid != 0)
+ continue;
+
+ if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0))
+ {
+ if (this_buf_size >= SIZE_MAX / 2)
+ goto out_fail;
+
+ nlm_next = *new_nlm_list;
+ while (nlm_next != NULL)
+ {
+ struct netlink_res *tmpptr;
+
+ tmpptr = nlm_next->next;
+ free (nlm_next);
+ nlm_next = tmpptr;
+ }
+ *new_nlm_list = NULL;
+
+ if (__libc_use_alloca (2 * this_buf_size))
+ buf = extend_alloca (buf, this_buf_size, 2 * this_buf_size);
+ else
+ {
+ this_buf_size *= 2;
+
+ char *new_buf = realloc (use_malloc ? buf : NULL, this_buf_size);
+ if (new_buf == NULL)
+ goto out_fail;
+ new_buf = buf;
+
+ use_malloc = true;
+ }
+ buf_size = this_buf_size;
+
+ iov.iov_base = buf;
+ iov.iov_len = this_buf_size;
+
+ /* Increase sequence number, so that we can distinguish
+ between old and new request messages. */
+ h->seq++;
+
+ if (__netlink_sendreq (h, type) < 0)
+ goto out_fail;
+
+ continue;
+ }
+
+ size_t count = 0;
+ size_t remaining_len = read_len;
+ for (nlmh = (struct nlmsghdr *) buf;
+ NLMSG_OK (nlmh, remaining_len);
+ nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, remaining_len))
+ {
+ if ((pid_t) nlmh->nlmsg_pid != h->pid
+ || nlmh->nlmsg_seq != h->seq)
+ continue;
+
+ ++count;
+ if (nlmh->nlmsg_type == NLMSG_DONE)
+ {
+ /* We found the end, leave the loop. */
+ done = true;
+ break;
+ }
+ if (nlmh->nlmsg_type == NLMSG_ERROR)
+ {
+ struct nlmsgerr *nlerr = (struct nlmsgerr *) NLMSG_DATA (nlmh);
+ if (nlmh->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
+ errno = EIO;
+ else
+ errno = -nlerr->error;
+ goto out_fail;
+ }
+ }
+
+ /* If there was nothing with the expected nlmsg_pid and nlmsg_seq,
+ there is no point to record it. */
+ if (count == 0)
+ continue;
+
+ nlm_next = (struct netlink_res *) malloc (sizeof (struct netlink_res)
+ + read_len);
+ if (nlm_next == NULL)
+ goto out_fail;
+ nlm_next->next = NULL;
+ nlm_next->nlh = memcpy (nlm_next + 1, buf, read_len);
+ nlm_next->size = read_len;
+ nlm_next->seq = h->seq;
+ if (h->nlm_list == NULL)
+ h->nlm_list = nlm_next;
+ else
+ h->end_ptr->next = nlm_next;
+ h->end_ptr = nlm_next;
+ }
+
+ if (use_malloc)
+ free (buf);
+ return 0;
+
+out_fail:
+ if (use_malloc)
+ free (buf);
+ return -1;
+}
+
+
+void
+__netlink_close (struct netlink_handle *h)
+{
+ /* Don't modify errno. */
+ INTERNAL_SYSCALL_DECL (err);
+ (void) INTERNAL_SYSCALL (close, err, 1, h->fd);
+}
+
+
+/* Open a NETLINK socket. */
+int
+__netlink_open (struct netlink_handle *h)
+{
+ struct sockaddr_nl nladdr;
+
+ h->fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (h->fd < 0)
+ goto out;
+
+ memset (&nladdr, '\0', sizeof (nladdr));
+ nladdr.nl_family = AF_NETLINK;
+ if (__bind (h->fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) < 0)
+ {
+ close_and_out:
+ __netlink_close (h);
+ out:
+#if __ASSUME_NETLINK_SUPPORT == 0
+ __no_netlink_support = 1;
+#endif
+ return -1;
+ }
+ /* Determine the ID the kernel assigned for this netlink connection.
+ It is not necessarily the PID if there is more than one socket
+ open. */
+ socklen_t addr_len = sizeof (nladdr);
+ if (__getsockname (h->fd, (struct sockaddr *) &nladdr, &addr_len) < 0)
+ goto close_and_out;
+ h->pid = nladdr.nl_pid;
+ return 0;
+}
+
+
+/* We know the number of RTM_NEWLINK entries, so we reserve the first
+ # of entries for this type. All RTM_NEWADDR entries have an index
+ pointer to the RTM_NEWLINK entry. To find the entry, create
+ a table to map kernel index entries to our index numbers.
+ Since we get at first all RTM_NEWLINK entries, it can never happen
+ that a RTM_NEWADDR index is not known to this map. */
+static int
+internal_function
+map_newlink (int index, struct ifaddrs_storage *ifas, int *map, int max)
+{
+ int i;
+
+ for (i = 0; i < max; i++)
+ {
+ if (map[i] == -1)
+ {
+ map[i] = index;
+ if (i > 0)
+ ifas[i - 1].ifa.ifa_next = &ifas[i].ifa;
+ return i;
+ }
+ else if (map[i] == index)
+ return i;
+ }
+ /* This should never be reached. If this will be reached, we have
+ a very big problem. */
+ abort ();
+}
+
+
+/* Create a linked list of `struct ifaddrs' structures, one for each
+ network interface on the host machine. If successful, store the
+ list in *IFAP and return 0. On errors, return -1 and set `errno'. */
+int
+getifaddrs (struct ifaddrs **ifap)
+{
+ struct netlink_handle nh = { 0, 0, 0, NULL, NULL };
+ struct netlink_res *nlp;
+ struct ifaddrs_storage *ifas;
+ unsigned int i, newlink, newaddr, newaddr_idx;
+ int *map_newlink_data;
+ size_t ifa_data_size = 0; /* Size to allocate for all ifa_data. */
+ char *ifa_data_ptr; /* Pointer to the unused part of memory for
+ ifa_data. */
+ int result = 0;
+
+ *ifap = NULL;
+
+ if (! __no_netlink_support && __netlink_open (&nh) < 0)
+ {
+#if __ASSUME_NETLINK_SUPPORT != 0
+ return -1;
+#endif
+ }
+
+#if __ASSUME_NETLINK_SUPPORT == 0
+ if (__no_netlink_support)
+ return fallback_getifaddrs (ifap);
+#endif
+
+ /* Tell the kernel that we wish to get a list of all
+ active interfaces, collect all data for every interface. */
+ if (__netlink_request (&nh, RTM_GETLINK) < 0)
+ {
+ result = -1;
+ goto exit_free;
+ }
+
+ /* Now ask the kernel for all addresses which are assigned
+ to an interface and collect all data for every interface.
+ Since we store the addresses after the interfaces in the
+ list, we will later always find the interface before the
+ corresponding addresses. */
+ ++nh.seq;
+ if (__netlink_request (&nh, RTM_GETADDR) < 0)
+ {
+ result = -1;
+ goto exit_free;
+ }
+
+ /* Count all RTM_NEWLINK and RTM_NEWADDR entries to allocate
+ enough memory. */
+ newlink = newaddr = 0;
+ for (nlp = nh.nlm_list; nlp; nlp = nlp->next)
+ {
+ struct nlmsghdr *nlh;
+ size_t size = nlp->size;
+
+ if (nlp->nlh == NULL)
+ continue;
+
+ /* Walk through all entries we got from the kernel and look, which
+ message type they contain. */
+ for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
+ {
+ /* Check if the message is what we want. */
+ if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
+ continue;
+
+ if (nlh->nlmsg_type == NLMSG_DONE)
+ break; /* ok */
+
+ if (nlh->nlmsg_type == RTM_NEWLINK)
+ {
+ /* A RTM_NEWLINK message can have IFLA_STATS data. We need to
+ know the size before creating the list to allocate enough
+ memory. */
+ struct ifinfomsg *ifim = (struct ifinfomsg *) NLMSG_DATA (nlh);
+ struct rtattr *rta = IFLA_RTA (ifim);
+ size_t rtasize = IFLA_PAYLOAD (nlh);
+
+ while (RTA_OK (rta, rtasize))
+ {
+ size_t rta_payload = RTA_PAYLOAD (rta);
+
+ if (rta->rta_type == IFLA_STATS)
+ {
+ ifa_data_size += rta_payload;
+ break;
+ }
+ else
+ rta = RTA_NEXT (rta, rtasize);
+ }
+ ++newlink;
+ }
+ else if (nlh->nlmsg_type == RTM_NEWADDR)
+ ++newaddr;
+ }
+ }
+
+ /* Return if no interface is up. */
+ if ((newlink + newaddr) == 0)
+ goto exit_free;
+
+ /* Allocate memory for all entries we have and initialize next
+ pointer. */
+ ifas = (struct ifaddrs_storage *) calloc (1,
+ (newlink + newaddr)
+ * sizeof (struct ifaddrs_storage)
+ + ifa_data_size);
+ if (ifas == NULL)
+ {
+ result = -1;
+ goto exit_free;
+ }
+
+ /* Table for mapping kernel index to entry in our list. */
+ map_newlink_data = alloca (newlink * sizeof (int));
+ memset (map_newlink_data, '\xff', newlink * sizeof (int));
+
+ ifa_data_ptr = (char *) &ifas[newlink + newaddr];
+ newaddr_idx = 0; /* Counter for newaddr index. */
+
+ /* Walk through the list of data we got from the kernel. */
+ for (nlp = nh.nlm_list; nlp; nlp = nlp->next)
+ {
+ struct nlmsghdr *nlh;
+ size_t size = nlp->size;
+
+ if (nlp->nlh == NULL)
+ continue;
+
+ /* Walk through one message and look at the type: If it is our
+ message, we need RTM_NEWLINK/RTM_NEWADDR and stop if we reach
+ the end or we find the end marker (in this case we ignore the
+ following data. */
+ for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
+ {
+ int ifa_index = 0;
+
+ /* Check if the message is the one we want */
+ if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
+ continue;
+
+ if (nlh->nlmsg_type == NLMSG_DONE)
+ break; /* ok */
+
+ if (nlh->nlmsg_type == RTM_NEWLINK)
+ {
+ /* We found a new interface. Now extract everything from the
+ interface data we got and need. */
+ struct ifinfomsg *ifim = (struct ifinfomsg *) NLMSG_DATA (nlh);
+ struct rtattr *rta = IFLA_RTA (ifim);
+ size_t rtasize = IFLA_PAYLOAD (nlh);
+
+ /* Interfaces are stored in the first "newlink" entries
+ of our list, starting in the order as we got from the
+ kernel. */
+ ifa_index = map_newlink (ifim->ifi_index - 1, ifas,
+ map_newlink_data, newlink);
+ ifas[ifa_index].ifa.ifa_flags = ifim->ifi_flags;
+
+ while (RTA_OK (rta, rtasize))
+ {
+ char *rta_data = RTA_DATA (rta);
+ size_t rta_payload = RTA_PAYLOAD (rta);
+
+ switch (rta->rta_type)
+ {
+ case IFLA_ADDRESS:
+ if (rta_payload <= sizeof (ifas[ifa_index].addr))
+ {
+ ifas[ifa_index].addr.sl.sll_family = AF_PACKET;
+ memcpy (ifas[ifa_index].addr.sl.sll_addr,
+ (char *) rta_data, rta_payload);
+ ifas[ifa_index].addr.sl.sll_halen = rta_payload;
+ ifas[ifa_index].addr.sl.sll_ifindex
+ = ifim->ifi_index;
+ ifas[ifa_index].addr.sl.sll_hatype = ifim->ifi_type;
+
+ ifas[ifa_index].ifa.ifa_addr
+ = &ifas[ifa_index].addr.sa;
+ }
+ break;
+
+ case IFLA_BROADCAST:
+ if (rta_payload <= sizeof (ifas[ifa_index].broadaddr))
+ {
+ ifas[ifa_index].broadaddr.sl.sll_family = AF_PACKET;
+ memcpy (ifas[ifa_index].broadaddr.sl.sll_addr,
+ (char *) rta_data, rta_payload);
+ ifas[ifa_index].broadaddr.sl.sll_halen = rta_payload;
+ ifas[ifa_index].broadaddr.sl.sll_ifindex
+ = ifim->ifi_index;
+ ifas[ifa_index].broadaddr.sl.sll_hatype
+ = ifim->ifi_type;
+
+ ifas[ifa_index].ifa.ifa_broadaddr
+ = &ifas[ifa_index].broadaddr.sa;
+ }
+ break;
+
+ case IFLA_IFNAME: /* Name of Interface */
+ if ((rta_payload + 1) <= sizeof (ifas[ifa_index].name))
+ {
+ ifas[ifa_index].ifa.ifa_name = ifas[ifa_index].name;
+ *(char *) __mempcpy (ifas[ifa_index].name, rta_data,
+ rta_payload) = '\0';
+ }
+ break;
+
+ case IFLA_STATS: /* Statistics of Interface */
+ ifas[ifa_index].ifa.ifa_data = ifa_data_ptr;
+ ifa_data_ptr += rta_payload;
+ memcpy (ifas[ifa_index].ifa.ifa_data, rta_data,
+ rta_payload);
+ break;
+
+ case IFLA_UNSPEC:
+ break;
+ case IFLA_MTU:
+ break;
+ case IFLA_LINK:
+ break;
+ case IFLA_QDISC:
+ break;
+ default:
+ break;
+ }
+
+ rta = RTA_NEXT (rta, rtasize);
+ }
+ }
+ else if (nlh->nlmsg_type == RTM_NEWADDR)
+ {
+ struct ifaddrmsg *ifam = (struct ifaddrmsg *) NLMSG_DATA (nlh);
+ struct rtattr *rta = IFA_RTA (ifam);
+ size_t rtasize = IFA_PAYLOAD (nlh);
+
+ /* New Addresses are stored in the order we got them from
+ the kernel after the interfaces. Theoretically it is possible
+ that we have holes in the interface part of the list,
+ but we always have already the interface for this address. */
+ ifa_index = newlink + newaddr_idx;
+ ifas[ifa_index].ifa.ifa_flags
+ = ifas[map_newlink (ifam->ifa_index - 1, ifas,
+ map_newlink_data, newlink)].ifa.ifa_flags;
+ if (ifa_index > 0)
+ ifas[ifa_index - 1].ifa.ifa_next = &ifas[ifa_index].ifa;
+ ++newaddr_idx;
+
+ while (RTA_OK (rta, rtasize))
+ {
+ char *rta_data = RTA_DATA (rta);
+ size_t rta_payload = RTA_PAYLOAD (rta);
+
+ switch (rta->rta_type)
+ {
+ case IFA_ADDRESS:
+ {
+ struct sockaddr *sa;
+
+ if (ifas[ifa_index].ifa.ifa_addr != NULL)
+ {
+ /* In a point-to-poing network IFA_ADDRESS
+ contains the destination address, local
+ address is supplied in IFA_LOCAL attribute.
+ destination address and broadcast address
+ are stored in an union, so it doesn't matter
+ which name we use. */
+ ifas[ifa_index].ifa.ifa_broadaddr
+ = &ifas[ifa_index].broadaddr.sa;
+ sa = &ifas[ifa_index].broadaddr.sa;
+ }
+ else
+ {
+ ifas[ifa_index].ifa.ifa_addr
+ = &ifas[ifa_index].addr.sa;
+ sa = &ifas[ifa_index].addr.sa;
+ }
+
+ sa->sa_family = ifam->ifa_family;
+
+ switch (ifam->ifa_family)
+ {
+ case AF_INET:
+ /* Size must match that of an address for IPv4. */
+ if (rta_payload == 4)
+ memcpy (&((struct sockaddr_in *) sa)->sin_addr,
+ rta_data, rta_payload);
+ break;
+
+ case AF_INET6:
+ /* Size must match that of an address for IPv6. */
+ if (rta_payload == 16)
+ {
+ memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr,
+ rta_data, rta_payload);
+ if (IN6_IS_ADDR_LINKLOCAL (rta_data)
+ || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
+ ((struct sockaddr_in6 *) sa)->sin6_scope_id
+ = ifam->ifa_index;
+ }
+ break;
+
+ default:
+ if (rta_payload <= sizeof (ifas[ifa_index].addr))
+ memcpy (sa->sa_data, rta_data, rta_payload);
+ break;
+ }
+ }
+ break;
+
+ case IFA_LOCAL:
+ if (ifas[ifa_index].ifa.ifa_addr != NULL)
+ {
+ /* If ifa_addr is set and we get IFA_LOCAL,
+ assume we have a point-to-point network.
+ Move address to correct field. */
+ ifas[ifa_index].broadaddr = ifas[ifa_index].addr;
+ ifas[ifa_index].ifa.ifa_broadaddr
+ = &ifas[ifa_index].broadaddr.sa;
+ memset (&ifas[ifa_index].addr, '\0',
+ sizeof (ifas[ifa_index].addr));
+ }
+
+ ifas[ifa_index].ifa.ifa_addr = &ifas[ifa_index].addr.sa;
+ ifas[ifa_index].ifa.ifa_addr->sa_family
+ = ifam->ifa_family;
+
+ switch (ifam->ifa_family)
+ {
+ case AF_INET:
+ /* Size must match that of an address for IPv4. */
+ if (rta_payload == 4)
+ memcpy (&ifas[ifa_index].addr.s4.sin_addr,
+ rta_data, rta_payload);
+ break;
+
+ case AF_INET6:
+ /* Size must match that of an address for IPv6. */
+ if (rta_payload == 16)
+ {
+ memcpy (&ifas[ifa_index].addr.s6.sin6_addr,
+ rta_data, rta_payload);
+ if (IN6_IS_ADDR_LINKLOCAL (rta_data)
+ || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
+ ifas[ifa_index].addr.s6.sin6_scope_id =
+ ifam->ifa_index;
+ }
+ break;
+
+ default:
+ if (rta_payload <= sizeof (ifas[ifa_index].addr))
+ memcpy (ifas[ifa_index].addr.sa.sa_data,
+ rta_data, rta_payload);
+ break;
+ }
+ break;
+
+ case IFA_BROADCAST:
+ /* We get IFA_BROADCAST, so IFA_LOCAL was too much. */
+ if (ifas[ifa_index].ifa.ifa_broadaddr != NULL)
+ memset (&ifas[ifa_index].broadaddr, '\0',
+ sizeof (ifas[ifa_index].broadaddr));
+
+ ifas[ifa_index].ifa.ifa_broadaddr
+ = &ifas[ifa_index].broadaddr.sa;
+ ifas[ifa_index].ifa.ifa_broadaddr->sa_family
+ = ifam->ifa_family;
+
+ switch (ifam->ifa_family)
+ {
+ case AF_INET:
+ /* Size must match that of an address for IPv4. */
+ if (rta_payload == 4)
+ memcpy (&ifas[ifa_index].broadaddr.s4.sin_addr,
+ rta_data, rta_payload);
+ break;
+
+ case AF_INET6:
+ /* Size must match that of an address for IPv6. */
+ if (rta_payload == 16)
+ {
+ memcpy (&ifas[ifa_index].broadaddr.s6.sin6_addr,
+ rta_data, rta_payload);
+ if (IN6_IS_ADDR_LINKLOCAL (rta_data)
+ || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
+ ifas[ifa_index].broadaddr.s6.sin6_scope_id
+ = ifam->ifa_index;
+ }
+ break;
+
+ default:
+ if (rta_payload <= sizeof (ifas[ifa_index].addr))
+ memcpy (&ifas[ifa_index].broadaddr.sa.sa_data,
+ rta_data, rta_payload);
+ break;
+ }
+ break;
+
+ case IFA_LABEL:
+ if (rta_payload + 1 <= sizeof (ifas[ifa_index].name))
+ {
+ ifas[ifa_index].ifa.ifa_name = ifas[ifa_index].name;
+ *(char *) __mempcpy (ifas[ifa_index].name, rta_data,
+ rta_payload) = '\0';
+ }
+ else
+ abort ();
+ break;
+
+ case IFA_UNSPEC:
+ break;
+ case IFA_CACHEINFO:
+ break;
+ default:
+ break;
+ }
+
+ rta = RTA_NEXT (rta, rtasize);
+ }
+
+ /* If we didn't get the interface name with the
+ address, use the name from the interface entry. */
+ if (ifas[ifa_index].ifa.ifa_name == NULL)
+ ifas[ifa_index].ifa.ifa_name
+ = ifas[map_newlink (ifam->ifa_index - 1, ifas,
+ map_newlink_data, newlink)].ifa.ifa_name;
+
+ /* Calculate the netmask. */
+ if (ifas[ifa_index].ifa.ifa_addr
+ && ifas[ifa_index].ifa.ifa_addr->sa_family != AF_UNSPEC
+ && ifas[ifa_index].ifa.ifa_addr->sa_family != AF_PACKET)
+ {
+ uint32_t max_prefixlen = 0;
+ char *cp = NULL;
+
+ ifas[ifa_index].ifa.ifa_netmask
+ = &ifas[ifa_index].netmask.sa;
+
+ switch (ifas[ifa_index].ifa.ifa_addr->sa_family)
+ {
+ case AF_INET:
+ cp = (char *) &ifas[ifa_index].netmask.s4.sin_addr;
+ max_prefixlen = 32;
+ break;
+
+ case AF_INET6:
+ cp = (char *) &ifas[ifa_index].netmask.s6.sin6_addr;
+ max_prefixlen = 128;
+ break;
+ }
+
+ ifas[ifa_index].ifa.ifa_netmask->sa_family
+ = ifas[ifa_index].ifa.ifa_addr->sa_family;
+
+ if (cp != NULL)
+ {
+ char c;
+ unsigned int preflen;
+
+ if ((max_prefixlen > 0) &&
+ (ifam->ifa_prefixlen > max_prefixlen))
+ preflen = max_prefixlen;
+ else
+ preflen = ifam->ifa_prefixlen;
+
+ for (i = 0; i < (preflen / 8); i++)
+ *cp++ = 0xff;
+ c = 0xff;
+ c <<= (8 - (preflen % 8));
+ *cp = c;
+ }
+ }
+ }
+ }
+ }
+
+ assert (ifa_data_ptr <= (char *) &ifas[newlink + newaddr] + ifa_data_size);
+
+ if (newaddr_idx > 0)
+ {
+ for (i = 0; i < newlink; ++i)
+ if (map_newlink_data[i] == -1)
+ {
+ /* We have fewer links then we anticipated. Adjust the
+ forward pointer to the first address entry. */
+ ifas[i - 1].ifa.ifa_next = &ifas[newlink].ifa;
+ }
+
+ if (i == 0 && newlink > 0)
+ /* No valid link, but we allocated memory. We have to
+ populate the first entry. */
+ memmove (ifas, &ifas[newlink], sizeof (struct ifaddrs_storage));
+ }
+
+ *ifap = &ifas[0].ifa;
+
+ exit_free:
+ __netlink_free_handle (&nh);
+ __netlink_close (&nh);
+
+ return result;
+}
+libc_hidden_def (getifaddrs)
+
+
+#if __ASSUME_NETLINK_SUPPORT != 0
+void
+freeifaddrs (struct ifaddrs *ifa)
+{
+ free (ifa);
+}
+libc_hidden_def (freeifaddrs)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/ifreq.c b/libc/sysdeps/unix/sysv/linux/ifreq.c
new file mode 100644
index 000000000..d7e442c27
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ifreq.c
@@ -0,0 +1,101 @@
+/* Copyright (C) 1999,2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "ifreq.h"
+#include <kernel-features.h>
+
+/* Variable to signal whether SIOCGIFCONF is not available. */
+#if __ASSUME_SIOCGIFNAME == 0 || 1
+static int old_siocgifconf;
+#else
+# define old_siocgifconf 0
+#endif
+
+
+void
+__ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd)
+{
+ int fd = sockfd;
+ struct ifconf ifc;
+ int rq_len;
+ int nifs;
+# define RQ_IFS 4
+
+ if (fd < 0)
+ fd = __opensock ();
+ if (fd < 0)
+ {
+ *num_ifs = 0;
+ *ifreqs = NULL;
+ return;
+ }
+
+ ifc.ifc_buf = NULL;
+
+ /* We may be able to get the needed buffer size directly, rather than
+ guessing. */
+ if (! old_siocgifconf)
+ {
+ ifc.ifc_buf = NULL;
+ ifc.ifc_len = 0;
+ if (__ioctl (fd, SIOCGIFCONF, &ifc) < 0 || ifc.ifc_len == 0)
+ {
+# if __ASSUME_SIOCGIFNAME == 0
+ old_siocgifconf = 1;
+# endif
+ rq_len = RQ_IFS * sizeof (struct ifreq);
+ }
+ else
+ rq_len = ifc.ifc_len;
+ }
+ else
+ rq_len = RQ_IFS * sizeof (struct ifreq);
+
+ /* Read all the interfaces out of the kernel. */
+ while (1)
+ {
+ ifc.ifc_len = rq_len;
+ void *newp = realloc (ifc.ifc_buf, ifc.ifc_len);
+ if (newp == NULL
+ || (ifc.ifc_buf = newp, __ioctl (fd, SIOCGIFCONF, &ifc)) < 0)
+ {
+ free (ifc.ifc_buf);
+
+ if (fd != sockfd)
+ __close (fd);
+
+ *num_ifs = 0;
+ *ifreqs = NULL;
+ return;
+ }
+
+ if (!old_siocgifconf || ifc.ifc_len < rq_len)
+ break;
+
+ rq_len *= 2;
+ }
+
+ nifs = ifc.ifc_len / sizeof (struct ifreq);
+
+ if (fd != sockfd)
+ __close (fd);
+
+ *num_ifs = nifs;
+ *ifreqs = realloc (ifc.ifc_buf, nifs * sizeof (struct ifreq));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/init-first.c b/libc/sysdeps/unix/sysv/linux/init-first.c
new file mode 100644
index 000000000..b061a848c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/init-first.c
@@ -0,0 +1,109 @@
+/* Initialization code run first thing by the ELF startup code. Linux version.
+ Copyright (C) 1995-2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sysdep.h>
+#include <fpu_control.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <libc-internal.h>
+
+#include <ldsodefs.h>
+
+/* Set nonzero if we have to be prepared for more then one libc being
+ used in the process. Safe assumption if initializer never runs. */
+int __libc_multiple_libcs attribute_hidden = 1;
+
+/* Remember the command line argument and enviroment contents for
+ later calls of initializers for dynamic libraries. */
+int __libc_argc attribute_hidden;
+char **__libc_argv attribute_hidden;
+
+
+void
+__libc_init_first (int argc, char **argv, char **envp)
+{
+#ifdef SHARED
+ /* For DSOs we do not need __libc_init_first but instead _init. */
+}
+
+void
+attribute_hidden
+_init (int argc, char **argv, char **envp)
+{
+#endif
+#ifdef USE_NONOPTION_FLAGS
+ extern void __getopt_clean_environment (char **);
+#endif
+
+ __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up;
+
+ /* Make sure we don't initialize twice. */
+ if (!__libc_multiple_libcs)
+ {
+ /* Set the FPU control word to the proper default value if the
+ kernel would use a different value. (In a static program we
+ don't have this information.) */
+#ifdef SHARED
+ if (__fpu_control != GLRO(dl_fpu_control))
+#endif
+ __setfpucw (__fpu_control);
+ }
+
+ /* Save the command-line arguments. */
+ __libc_argc = argc;
+ __libc_argv = argv;
+ __environ = envp;
+
+#ifndef SHARED
+ __libc_init_secure ();
+
+ /* First the initialization which normally would be done by the
+ dynamic linker. */
+ _dl_non_dynamic_init ();
+#endif
+
+ __init_misc (argc, argv, envp);
+
+#ifdef USE_NONOPTION_FLAGS
+ /* This is a hack to make the special getopt in GNU libc working. */
+ __getopt_clean_environment (envp);
+#endif
+
+#ifdef SHARED
+ __libc_global_ctors ();
+#endif
+}
+
+
+/* This function is defined here so that if this file ever gets into
+ ld.so we will get a link error. Having this file silently included
+ in ld.so causes disaster, because the _init definition above will
+ cause ld.so to gain an init function, which is not a cool thing. */
+
+extern void _dl_start (void) __attribute__ ((noreturn));
+
+void
+_dl_start (void)
+{
+ abort ();
+}
diff --git a/libc/sysdeps/unix/sysv/linux/internal_statvfs.c b/libc/sysdeps/unix/sysv/linux/internal_statvfs.c
new file mode 100644
index 000000000..73317ecaf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/internal_statvfs.c
@@ -0,0 +1,239 @@
+/* Copyright (C) 1998-2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <mntent.h>
+#include <paths.h>
+#include <stdbool.h>
+#include <stdio_ext.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+#include "linux_fsinfo.h"
+
+
+#ifndef STATFS
+# define STATFS statfs
+# define STATVFS statvfs
+# define INTERNAL_STATVFS __internal_statvfs
+
+
+int
+__statvfs_getflags (const char *name, int fstype, struct stat64 *st)
+{
+ if (st == NULL)
+ return 0;
+
+ const char *fsname = NULL;
+ const char *fsname2 = NULL;
+
+ /* Map the filesystem type we got from the statfs call to a string. */
+ switch (fstype)
+ {
+ case EXT2_SUPER_MAGIC:
+ fsname = "ext3";
+ fsname2 = "ext2";
+ break;
+ case DEVPTS_SUPER_MAGIC:
+ fsname= "devpts";
+ break;
+ case SHMFS_SUPER_MAGIC:
+ fsname = "tmpfs";
+ break;
+ case PROC_SUPER_MAGIC:
+ fsname = "proc";
+ break;
+ case USBDEVFS_SUPER_MAGIC:
+ fsname = "usbdevfs";
+ break;
+ case AUTOFS_SUPER_MAGIC:
+ fsname = "autofs";
+ break;
+ case NFS_SUPER_MAGIC:
+ fsname = "nfs";
+ break;
+ case SYSFS_MAGIC:
+ fsname = "sysfs";
+ break;
+ case REISERFS_SUPER_MAGIC:
+ fsname = "reiserfs";
+ break;
+ case XFS_SUPER_MAGIC:
+ fsname = "xfs";
+ break;
+ case JFS_SUPER_MAGIC:
+ fsname = "jfs";
+ break;
+ case HPFS_SUPER_MAGIC:
+ fsname = "hpfs";
+ break;
+ case DEVFS_SUPER_MAGIC:
+ fsname = "devfs";
+ break;
+ case ISOFS_SUPER_MAGIC:
+ fsname = "iso9660";
+ break;
+ case MSDOS_SUPER_MAGIC:
+ fsname = "msdos";
+ break;
+ case NTFS_SUPER_MAGIC:
+ fsname = "ntfs";
+ break;
+ }
+
+ FILE *mtab = __setmntent ("/proc/mounts", "r");
+ if (mtab == NULL)
+ mtab = __setmntent (_PATH_MOUNTED, "r");
+
+ int result = 0;
+ if (mtab != NULL)
+ {
+ bool success = false;
+ struct mntent mntbuf;
+ char tmpbuf[1024];
+
+ /* No locking needed. */
+ (void) __fsetlocking (mtab, FSETLOCKING_BYCALLER);
+
+ again:
+ while (__getmntent_r (mtab, &mntbuf, tmpbuf, sizeof (tmpbuf)))
+ {
+ /* In a first round we look for a given mount point, if
+ we have a name. */
+ if (name != NULL && strcmp (name, mntbuf.mnt_dir) != 0)
+ continue;
+ /* We need to look at the entry only if the filesystem
+ name matches. If we have a filesystem name. */
+ else if (fsname != NULL
+ && strcmp (fsname, mntbuf.mnt_type) != 0
+ && (fsname2 == NULL
+ || strcmp (fsname2, mntbuf.mnt_type) != 0))
+ continue;
+
+ /* Find out about the device the current entry is for. */
+ struct stat64 fsst;
+ if (stat64 (mntbuf.mnt_dir, &fsst) >= 0
+ && st->st_dev == fsst.st_dev)
+ {
+ /* Bingo, we found the entry for the device FD is on.
+ Now interpret the option string. */
+ char *cp = mntbuf.mnt_opts;
+ char *opt;
+
+ while ((opt = strsep (&cp, ",")) != NULL)
+ if (strcmp (opt, "ro") == 0)
+ result |= ST_RDONLY;
+ else if (strcmp (opt, "nosuid") == 0)
+ result |= ST_NOSUID;
+ else if (strcmp (opt, "noexec") == 0)
+ result |= ST_NOEXEC;
+ else if (strcmp (opt, "nodev") == 0)
+ result |= ST_NODEV;
+ else if (strcmp (opt, "sync") == 0)
+ result |= ST_SYNCHRONOUS;
+ else if (strcmp (opt, "mand") == 0)
+ result |= ST_MANDLOCK;
+ else if (strcmp (opt, "noatime") == 0)
+ result |= ST_NOATIME;
+ else if (strcmp (opt, "nodiratime") == 0)
+ result |= ST_NODIRATIME;
+
+ /* We can stop looking for more entries. */
+ success = true;
+ break;
+ }
+ }
+ /* Maybe the kernel names for the filesystems changed or the
+ statvfs call got a name which was not the mount point. Check
+ again, this time without checking for name matches first. */
+ if (! success && (name != NULL || fsname != NULL))
+ {
+ if (name != NULL)
+ /* Try without a mount point name. */
+ name = NULL;
+ else
+ {
+ /* Try without a filesystem name. */
+ assert (fsname != NULL);
+ fsname = fsname2 = NULL;
+ }
+
+ /* It is not strictly allowed to use rewind here. But
+ this code is part of the implementation so it is
+ acceptable. */
+ rewind (mtab);
+
+ goto again;
+ }
+
+ /* Close the file. */
+ __endmntent (mtab);
+ }
+
+ return result;
+}
+#else
+extern int __statvfs_getflags (const char *name, int fstype,
+ struct stat64 *st);
+#endif
+
+
+void
+INTERNAL_STATVFS (const char *name, struct STATVFS *buf,
+ struct STATFS *fsbuf, struct stat64 *st)
+{
+ /* Now fill in the fields we have information for. */
+ buf->f_bsize = fsbuf->f_bsize;
+ /* Linux has the f_frsize size only in later version of the kernel.
+ If the value is not filled in use f_bsize. */
+ buf->f_frsize = fsbuf->f_frsize ?: fsbuf->f_bsize;
+ buf->f_blocks = fsbuf->f_blocks;
+ buf->f_bfree = fsbuf->f_bfree;
+ buf->f_bavail = fsbuf->f_bavail;
+ buf->f_files = fsbuf->f_files;
+ buf->f_ffree = fsbuf->f_ffree;
+ if (sizeof (buf->f_fsid) == sizeof (fsbuf->f_fsid))
+ buf->f_fsid = (fsbuf->f_fsid.__val[0]
+ | ((unsigned long int) fsbuf->f_fsid.__val[1]
+ << (8 * (sizeof (buf->f_fsid)
+ - sizeof (fsbuf->f_fsid.__val[0])))));
+ else
+ /* We cannot help here. The statvfs element is not large enough to
+ contain both words of the statfs f_fsid field. */
+ buf->f_fsid = fsbuf->f_fsid.__val[0];
+#ifdef _STATVFSBUF_F_UNUSED
+ buf->__f_unused = 0;
+#endif
+ buf->f_namemax = fsbuf->f_namelen;
+ memset (buf->__f_spare, '\0', sizeof (buf->__f_spare));
+
+ /* What remains to do is to fill the fields f_favail and f_flag. */
+
+ /* XXX I have no idea how to compute f_favail. Any idea??? */
+ buf->f_favail = buf->f_ffree;
+
+ /* Determining the flags is tricky. We have to read /proc/mounts or
+ the /etc/mtab file and search for the entry which matches the given
+ file. The way we can test for matching filesystem is using the
+ device number. */
+ buf->f_flag = __statvfs_getflags (name, fsbuf->f_type, st);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/internal_statvfs64.c b/libc/sysdeps/unix/sysv/linux/internal_statvfs64.c
new file mode 100644
index 000000000..49e7689f8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/internal_statvfs64.c
@@ -0,0 +1,4 @@
+#define STATFS statfs64
+#define STATVFS statvfs64
+#define INTERNAL_STATVFS __internal_statvfs64
+#include "internal_statvfs.c"
diff --git a/libc/sysdeps/unix/sysv/linux/ipc_priv.h b/libc/sysdeps/unix/sysv/linux/ipc_priv.h
new file mode 100644
index 000000000..20ba1a206
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ipc_priv.h
@@ -0,0 +1,47 @@
+/* Copyright (C) 1995-1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/ipc.h>
+
+#define __IPC_64 0x100
+
+struct __old_ipc_perm
+{
+ __key_t __key; /* Key. */
+ unsigned short int uid; /* Owner's user ID. */
+ unsigned short int gid; /* Owner's group ID. */
+ unsigned short int cuid; /* Creator's user ID. */
+ unsigned short int cgid; /* Creator's group ID. */
+ unsigned short int mode; /* Read/write permission. */
+ unsigned short int __seq; /* Sequence number. */
+};
+
+
+/* The codes for the functions to use the ipc syscall multiplexer. */
+#define IPCOP_semop 1
+#define IPCOP_semget 2
+#define IPCOP_semctl 3
+#define IPCOP_semtimedop 4
+#define IPCOP_msgsnd 11
+#define IPCOP_msgrcv 12
+#define IPCOP_msgget 13
+#define IPCOP_msgctl 14
+#define IPCOP_shmat 21
+#define IPCOP_shmdt 22
+#define IPCOP_shmget 23
+#define IPCOP_shmctl 24
diff --git a/libc/sysdeps/unix/sysv/linux/kernel-features.h b/libc/sysdeps/unix/sysv/linux/kernel-features.h
new file mode 100644
index 000000000..e54f675db
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/kernel-features.h
@@ -0,0 +1,460 @@
+/* Set flags signalling availability of kernel features based on given
+ kernel version number.
+ Copyright (C) 1999-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file must not contain any C code. At least it must be protected
+ to allow using the file also in assembler files. */
+
+#ifndef __LINUX_KERNEL_VERSION
+/* We assume the worst; all kernels should be supported. */
+# define __LINUX_KERNEL_VERSION 0
+#endif
+
+/* We assume for __LINUX_KERNEL_VERSION the same encoding used in
+ linux/version.h. I.e., the major, minor, and subminor all get a
+ byte with the major number being in the highest byte. This means
+ we can do numeric comparisons.
+
+ In the following we will define certain symbols depending on
+ whether the describes kernel feature is available in the kernel
+ version given by __LINUX_KERNEL_VERSION. We are not always exactly
+ recording the correct versions in which the features were
+ introduced. If somebody cares these values can afterwards be
+ corrected. Most of the numbers here are set corresponding to
+ 2.2.0. */
+
+/* `getcwd' system call. */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_GETCWD_SYSCALL 1
+#endif
+
+/* Real-time signal became usable in 2.1.70. */
+#if __LINUX_KERNEL_VERSION >= 131398
+# define __ASSUME_REALTIME_SIGNALS 1
+#endif
+
+/* When were the `pread'/`pwrite' syscalls introduced? */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_PREAD_SYSCALL 1
+# define __ASSUME_PWRITE_SYSCALL 1
+#endif
+
+/* When was `poll' introduced? */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_POLL_SYSCALL 1
+#endif
+
+/* The `lchown' syscall was introduced in 2.1.80. */
+#if __LINUX_KERNEL_VERSION >= 131408
+# define __ASSUME_LCHOWN_SYSCALL 1
+#endif
+
+/* When did the `setresuid' sysall became available? */
+#if __LINUX_KERNEL_VERSION >= 131584 && !defined __sparc__
+# define __ASSUME_SETRESUID_SYSCALL 1
+#endif
+
+/* The SIOCGIFNAME ioctl is available starting with 2.1.50. */
+#if __LINUX_KERNEL_VERSION >= 131408
+# define __ASSUME_SIOCGIFNAME 1
+#endif
+
+/* MSG_NOSIGNAL was at least available with Linux 2.2.0. */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_MSG_NOSIGNAL 1
+#endif
+
+/* The sendfile syscall was introduced in 2.2.0. */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_SENDFILE 1
+#endif
+
+/* Only very old kernels had no real symlinks for terminal descriptors
+ in /proc/self/fd. */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_PROC_SELF_FD_SYMLINK 1
+#endif
+
+/* On x86 another `getrlimit' syscall was added in 2.3.25. */
+#if __LINUX_KERNEL_VERSION >= 131865 && defined __i386__
+# define __ASSUME_NEW_GETRLIMIT_SYSCALL 1
+#endif
+
+/* On x86 the truncate64/ftruncate64 syscalls were introduced in 2.3.31. */
+#if __LINUX_KERNEL_VERSION >= 131871 && defined __i386__
+# define __ASSUME_TRUNCATE64_SYSCALL 1
+#endif
+
+/* On x86 the mmap2 syscall was introduced in 2.3.31. */
+#if __LINUX_KERNEL_VERSION >= 131871 && defined __i386__
+# define __ASSUME_MMAP2_SYSCALL 1
+#endif
+
+/* On x86 the stat64/lstat64/fstat64 syscalls were introduced in 2.3.34. */
+#if __LINUX_KERNEL_VERSION >= 131874 && defined __i386__
+# define __ASSUME_STAT64_SYSCALL 1
+#endif
+
+/* On sparc the truncate64/ftruncate64/mmap2/stat64/lstat64/fstat64
+ syscalls were introduced in 2.3.35. */
+#if __LINUX_KERNEL_VERSION >= 131875 \
+ && (defined __sparc__ && !defined __arch64__)
+# define __ASSUME_TRUNCATE64_SYSCALL 1
+# define __ASSUME_MMAP2_SYSCALL 1
+# define __ASSUME_STAT64_SYSCALL 1
+#endif
+
+/* I know for sure that getrlimit are in 2.3.35 on powerpc. */
+#if __LINUX_KERNEL_VERSION >= 131875 && defined __powerpc__
+# define __ASSUME_NEW_GETRLIMIT_SYSCALL 1
+#endif
+
+/* I know for sure that these are in 2.3.35 on powerpc. But PowerPC64 does not
+ support separate 64-bit syscalls, already 64-bit */
+#if __LINUX_KERNEL_VERSION >= 131875 && defined __powerpc__ \
+ && !defined __powerpc64__
+# define __ASSUME_TRUNCATE64_SYSCALL 1
+# define __ASSUME_STAT64_SYSCALL 1
+#endif
+
+/* Linux 2.3.39 introduced 32bit UID/GIDs. Some platforms had 32
+ bit type all along. */
+#if __LINUX_KERNEL_VERSION >= 131879 || defined __powerpc__
+# define __ASSUME_32BITUIDS 1
+#endif
+
+/* Linux 2.3.39 sparc added setresuid. */
+#if __LINUX_KERNEL_VERSION >= 131879 && defined __sparc__
+# define __ASSUME_SETRESUID_SYSCALL 1
+#endif
+
+#if __LINUX_KERNEL_VERSION >= 131879
+# define __ASSUME_SETRESGID_SYSCALL 1
+#endif
+
+/* Linux 2.3.39 introduced IPC64. Except for powerpc. */
+#if __LINUX_KERNEL_VERSION >= 131879 && !defined __powerpc__
+# define __ASSUME_IPC64 1
+#endif
+
+/* We can use the LDTs for threading with Linux 2.3.99 and newer. */
+#if __LINUX_KERNEL_VERSION >= 131939
+# define __ASSUME_LDT_WORKS 1
+#endif
+
+/* Linux 2.4.0 on PPC introduced a correct IPC64. But PowerPC64 does not
+ support a separate 64-bit sys call, already 64-bit */
+#if __LINUX_KERNEL_VERSION >= 132096 && defined __powerpc__ \
+ && !defined __powerpc64__
+# define __ASSUME_IPC64 1
+#endif
+
+/* SH kernels got stat64, mmap2, and truncate64 during 2.4.0-test. */
+#if __LINUX_KERNEL_VERSION >= 132096 && defined __sh__
+# define __ASSUME_TRUNCATE64_SYSCALL 1
+# define __ASSUME_MMAP2_SYSCALL 1
+# define __ASSUME_STAT64_SYSCALL 1
+#endif
+
+/* The changed st_ino field appeared in 2.4.0-test6. But we cannot
+ distinguish this version from other 2.4.0 releases. Therefore play
+ save and assume it available is for 2.4.1 and up. However, SH is lame,
+ and still does not have a 64-bit inode field. */
+#if __LINUX_KERNEL_VERSION >= 132097 && !defined __alpha__ && !defined __sh__
+# define __ASSUME_ST_INO_64_BIT 1
+#endif
+
+/* To support locking of large files a new fcntl() syscall was introduced
+ in 2.4.0-test7. We test for 2.4.1 for the earliest version we know
+ the syscall is available. */
+#if __LINUX_KERNEL_VERSION >= 132097 && (defined __i386__ || defined __sparc__)
+# define __ASSUME_FCNTL64 1
+#endif
+
+/* The AT_CLKTCK auxiliary vector entry was introduction in the 2.4.0
+ series. */
+#if __LINUX_KERNEL_VERSION >= 132097
+# define __ASSUME_AT_CLKTCK 1
+#endif
+
+/* Arm got fcntl64 in 2.4.4, PowerPC and SH have it also in 2.4.4 (I
+ don't know when it got introduced). But PowerPC64 does not support
+ separate FCNTL64 call, FCNTL is already 64-bit */
+#if __LINUX_KERNEL_VERSION >= 132100 \
+ && (defined __powerpc__ || defined __sh__) \
+ && !defined __powerpc64__
+# define __ASSUME_FCNTL64 1
+#endif
+
+/* The getdents64 syscall was introduced in 2.4.0-test7. We test for
+ 2.4.1 for the earliest version we know the syscall is available. */
+#if __LINUX_KERNEL_VERSION >= 132097
+# define __ASSUME_GETDENTS64_SYSCALL 1
+#endif
+
+/* When did O_DIRECTORY became available? Early in 2.3 but when?
+ Be safe, use 2.3.99. */
+#if __LINUX_KERNEL_VERSION >= 131939
+# define __ASSUME_O_DIRECTORY 1
+#endif
+
+/* Starting with one of the 2.4.0 pre-releases the Linux kernel passes
+ up the page size information. */
+#if __LINUX_KERNEL_VERSION >= 132097
+# define __ASSUME_AT_PAGESIZE 1
+#endif
+
+/* Starting with at least 2.4.0 the kernel passes the uid/gid unconditionally
+ up to the child. */
+#if __LINUX_KERNEL_VERSION >= 132097
+# define __ASSUME_AT_XID 1
+#endif
+
+/* Starting with 2.4.5 kernels PPC passes the AUXV in the standard way
+ and the vfork syscall made it into the official kernel. */
+#if __LINUX_KERNEL_VERSION >= (132096+5) && defined __powerpc__
+# define __ASSUME_STD_AUXV 1
+# define __ASSUME_VFORK_SYSCALL 1
+#endif
+
+/* Starting with 2.4.5 kernels the mmap2 syscall made it into the official
+ kernel. But PowerPC64 does not support a separate MMAP2 call. */
+#if __LINUX_KERNEL_VERSION >= (132096+5) && defined __powerpc__ \
+ && !defined __powerpc64__
+# define __ASSUME_MMAP2_SYSCALL 1
+#endif
+
+/* Starting with 2.4.21 PowerPC implements the new prctl syscall.
+ This allows applications to get/set the Floating Point Exception Mode. */
+#if __LINUX_KERNEL_VERSION >= (132096+21) && defined __powerpc__
+# define __ASSUME_NEW_PRCTL_SYSCALL 1
+#endif
+
+/* Starting with 2.4.21 the PowerPC32 clone syscall works as expected. */
+#if __LINUX_KERNEL_VERSION >= (132096+21) && defined __powerpc__ \
+ && !defined __powerpc64__
+# define __ASSUME_FIXED_CLONE_SYSCALL 1
+#endif
+
+/* Starting with 2.4.21 PowerPC64 implements the new rt_sigreturn syscall.
+ The new rt_sigreturn takes an ucontext pointer allowing rt_sigreturn
+ to be used in the set/swapcontext implementation. */
+#if __LINUX_KERNEL_VERSION >= (132096+21) && defined __powerpc64__
+# define __ASSUME_NEW_RT_SIGRETURN_SYSCALL 1
+#endif
+
+/* On x86, the set_thread_area syscall was introduced in 2.5.29, but its
+ semantics was changed in 2.5.30, and again after 2.5.31. */
+#if __LINUX_KERNEL_VERSION >= 132384 && defined __i386__
+# define __ASSUME_SET_THREAD_AREA_SYSCALL 1
+#endif
+
+/* The vfork syscall on x86 and arm was definitely available in 2.4. */
+#if __LINUX_KERNEL_VERSION >= 132097 && defined __i386__
+# define __ASSUME_VFORK_SYSCALL 1
+#endif
+
+/* Alpha switched to a 64-bit timeval sometime before 2.2.0. */
+#if __LINUX_KERNEL_VERSION >= 131584 && defined __alpha__
+# define __ASSUME_TIMEVAL64 1
+#endif
+
+/* The late 2.5 kernels saw a lot of new CLONE_* flags. Summarize
+ their availability with one define. The changes were made first
+ for i386 and the have to be done separately for the other archs.
+ For i386 we pick 2.5.50 as the first version with support.
+ For ia64, s390*, PPC, x86-64, and SH we pick 2.5.64 as the first
+ version with support. */
+#if ((__LINUX_KERNEL_VERSION >= 132402 && defined __i386__) \
+ || (__LINUX_KERNEL_VERSION >= 132416 \
+ && (defined __ia64__ || defined __s390__ \
+ || defined __powerpc__ || defined __x86_64__ || defined __sh__)))
+# define __ASSUME_CLONE_THREAD_FLAGS 1
+#endif
+
+/* Beginning with 2.5.63 support for realtime and monotonic clocks and
+ timers based on them is available. */
+#if __LINUX_KERNEL_VERSION >= 132415
+# define __ASSUME_POSIX_TIMERS 1
+#endif
+
+/* Beginning with 2.6.12 the clock and timer supports CPU clocks. */
+#if __LINUX_KERNEL_VERSION >= 0x2060c
+# define __ASSUME_POSIX_CPU_TIMERS 1
+#endif
+
+/* With kernel 2.4.17 we always have netlink support. */
+#if __LINUX_KERNEL_VERSION >= (132096+17)
+# define __ASSUME_NETLINK_SUPPORT 1
+#endif
+
+/* The requeue futex functionality was introduced in 2.5.70. */
+#if __LINUX_KERNEL_VERSION >= 132422
+# define __ASSUME_FUTEX_REQUEUE 1
+#endif
+
+/* The statfs64 syscalls are available in 2.5.74. */
+#if __LINUX_KERNEL_VERSION >= 132426
+# define __ASSUME_STATFS64 1
+#endif
+
+/* Starting with at least 2.5.74 the kernel passes the setuid-like exec
+ flag unconditionally up to the child. */
+#if __LINUX_KERNEL_VERSION >= 132426
+# define __ASSUME_AT_SECURE 1
+#endif
+
+/* Starting with the 2.5.75 kernel the kernel fills in the correct value
+ in the si_pid field passed as part of the siginfo_t struct to signal
+ handlers. */
+#if __LINUX_KERNEL_VERSION >= 132427
+# define __ASSUME_CORRECT_SI_PID 1
+#endif
+
+/* The tgkill syscall was instroduced for i386 in 2.5.75. For Alpha
+ it was introduced in 2.6.0-test1 which unfortunately cannot be
+ distinguished from 2.6.0. On x86-64, ppc, and ppc64 it was
+ introduced in 2.6.0-test3. */
+#if (__LINUX_KERNEL_VERSION >= 132427 && defined __i386__) \
+ || (__LINUX_KERNEL_VERSION >= 132609 && defined __alpha__) \
+ || (__LINUX_KERNEL_VERSION >= 132609 && defined __x86_64__) \
+ || (__LINUX_KERNEL_VERSION >= 132609 && defined __powerpc__) \
+ || (__LINUX_KERNEL_VERSION >= 132609 && defined __sh__)
+# define __ASSUME_TGKILL 1
+#endif
+
+/* The utimes syscall has been available for some architectures
+ forever. For x86 it was introduced after 2.5.75, for x86-64,
+ ppc, and ppc64 it was introduced in 2.6.0-test3. */
+#if defined __alpha__ || defined __ia64__ \
+ || defined __sparc__ \
+ || (__LINUX_KERNEL_VERSION > 132427 && defined __i386__) \
+ || (__LINUX_KERNEL_VERSION > 132609 && defined __x86_64__) \
+ || (__LINUX_KERNEL_VERSION >= 132609 && defined __powerpc__) \
+ || (__LINUX_KERNEL_VERSION >= 132609 && defined __sh__)
+# define __ASSUME_UTIMES 1
+#endif
+
+// XXX Disabled for now since the semantics we want is not achieved.
+#if 0
+/* The CLONE_STOPPED flag was introduced in the 2.6.0-test1 series. */
+#if __LINUX_KERNEL_VERSION >= 132609
+# define __ASSUME_CLONE_STOPPED 1
+#endif
+#endif
+
+/* The fixed version of the posix_fadvise64 syscall appeared in
+ 2.6.0-test3. At least for x86. Powerpc support appeared in
+ 2.6.2, but for 32-bit userspace only. */
+#if (__LINUX_KERNEL_VERSION >= 132609 && defined __i386__) \
+ || (__LINUX_KERNEL_VERSION >= 132610 && defined __powerpc__ \
+ && !defined __powerpc64__)
+# define __ASSUME_FADVISE64_64_SYSCALL 1
+#endif
+
+/* The PROT_GROWSDOWN/PROT_GROWSUP flags were introduced in the 2.6.0-test
+ series. */
+#if __LINUX_KERNEL_VERSION >= 132609
+# define __ASSUME_PROT_GROWSUPDOWN 1
+#endif
+
+/* Starting with 2.6.0 PowerPC adds signal/swapcontext support for Vector
+ SIMD (AKA Altivec, VMX) instructions and register state. This changes
+ the overall size of the sigcontext and adds the swapcontext syscall. */
+#if __LINUX_KERNEL_VERSION >= 132608 && defined __powerpc__
+# define __ASSUME_SWAPCONTEXT_SYSCALL 1
+#endif
+
+/* The CLONE_DETACHED flag is not necessary in 2.6.2 kernels, it is
+ implied. */
+#if __LINUX_KERNEL_VERSION >= 132610
+# define __ASSUME_NO_CLONE_DETACHED 1
+#endif
+
+/* Starting with version 2.6.4-rc1 the getdents syscall returns d_type
+ information as well and in between 2.6.5 and 2.6.8 most compat wrappers
+ were fixed too. Except s390{,x} which was fixed in 2.6.11. */
+#if (__LINUX_KERNEL_VERSION >= 0x020608 && !defined __s390__) \
+ || (__LINUX_KERNEL_VERSION >= 0x02060b && defined __s390__)
+# define __ASSUME_GETDENTS32_D_TYPE 1
+#endif
+
+/* Starting with version 2.5.3, the initial location returned by `brk'
+ after exec is always rounded up to the next page. */
+#if __LINUX_KERNEL_VERSION >= 132355
+# define __ASSUME_BRK_PAGE_ROUNDED 1
+#endif
+
+/* Starting with version 2.6.9, the waitid system call is available.
+ Except for powerpc{,64} and s390{,x}, where it is available in 2.6.12. */
+#if (__LINUX_KERNEL_VERSION >= 0x020609 \
+ && !defined __powerpc__ && !defined __s390__) \
+ || (__LINUX_KERNEL_VERSION >= 0x02060c \
+ && (defined __powerpc__ || defined __s390__))
+# define __ASSUME_WAITID_SYSCALL 1
+#endif
+
+/* Starting with version 2.6.9, SSI_IEEE_RAISE_EXCEPTION exists. */
+#if __LINUX_KERNEL_VERSION >= 0x020609 && defined __alpha__
+#define __ASSUME_IEEE_RAISE_EXCEPTION 1
+#endif
+
+/* On sparc64 stat64/lstat64/fstat64 syscalls were introduced in 2.6.12. */
+#if __LINUX_KERNEL_VERSION >= 0x02060c && defined __sparc__ \
+ && defined __arch64__
+# define __ASSUME_STAT64_SYSCALL 1
+#endif
+
+/* Early kernel used "shm" as the filesystem name for the filesystem used
+ for shm_open etc. Later it is "tmpfs". 2.4.20 is a safe bet for the
+ cutover. */
+#if __LINUX_KERNEL_VERSION >= 0x02041a
+# define __ASSUME_TMPFS_NAME 1
+#endif
+
+/* pselect was introduced just after 2.6.16-rc1. Due to the way the
+ kernel versions are advertised we can only rely on 2.6.17 to have
+ the code. */
+#if __LINUX_KERNEL_VERSION >= 0x020611 && !defined __x86_64__
+# define __ASSUME_PSELECT 1
+#endif
+
+/* ppoll was introduced just after 2.6.16-rc1. Due to the way the
+ kernel versions are advertised we can only rely on 2.6.17 to have
+ the code. */
+#if __LINUX_KERNEL_VERSION >= 0x020611 && !defined __x86_64__
+# define __ASSUME_PPOLL 1
+#endif
+
+/* The *at syscalls were introduced just after 2.6.16-rc1. Due to the way the
+ kernel versions are advertised we can only rely on 2.6.17 to have
+ the code. */
+#if __LINUX_KERNEL_VERSION >= 0x020611
+# define __ASSUME_ATFCTS 1
+#endif
+
+/* Support for inter-process robust mutexes was added in 2.6.17. */
+#if __LINUX_KERNEL_VERSION >= 0x020611
+# define __ASSUME_SET_ROBUST_LIST 1
+#endif
+
+/* Support for PI futexes was added in 2.6.18. */
+#if __LINUX_KERNEL_VERSION >= 0x020612
+# define __ASSUME_FUTEX_LOCK_PI 1
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/kernel-posix-cpu-timers.h b/libc/sysdeps/unix/sysv/linux/kernel-posix-cpu-timers.h
new file mode 100644
index 000000000..164a90dde
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/kernel-posix-cpu-timers.h
@@ -0,0 +1,18 @@
+/* Parameters for the Linux kernel ABI for CPU clocks. */
+
+#define CPUCLOCK_PID(clock) ((pid_t) ~((clock) >> 3))
+#define CPUCLOCK_PERTHREAD(clock) \
+ (((clock) & (clockid_t) CPUCLOCK_PERTHREAD_MASK) != 0)
+#define CPUCLOCK_PID_MASK 7
+#define CPUCLOCK_PERTHREAD_MASK 4
+#define CPUCLOCK_WHICH(clock) ((clock) & (clockid_t) CPUCLOCK_CLOCK_MASK)
+#define CPUCLOCK_CLOCK_MASK 3
+#define CPUCLOCK_PROF 0
+#define CPUCLOCK_VIRT 1
+#define CPUCLOCK_SCHED 2
+#define CPUCLOCK_MAX 3
+
+#define MAKE_PROCESS_CPUCLOCK(pid, clock) \
+ ((~(clockid_t) (pid) << 3) | (clockid_t) (clock))
+#define MAKE_THREAD_CPUCLOCK(tid, clock) \
+ MAKE_PROCESS_CPUCLOCK((tid), (clock) | CPUCLOCK_PERTHREAD_MASK)
diff --git a/libc/sysdeps/unix/sysv/linux/kernel_sigaction.h b/libc/sysdeps/unix/sysv/linux/kernel_sigaction.h
new file mode 100644
index 000000000..d005cbce9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/kernel_sigaction.h
@@ -0,0 +1,19 @@
+/* This is the sigaction structure from the Linux 2.1.20 kernel. */
+
+#define HAVE_SA_RESTORER
+
+struct old_kernel_sigaction {
+ __sighandler_t k_sa_handler;
+ unsigned long sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer) (void);
+};
+
+/* This is the sigaction structure from the Linux 2.1.68 kernel. */
+
+struct kernel_sigaction {
+ __sighandler_t k_sa_handler;
+ unsigned long sa_flags;
+ void (*sa_restorer) (void);
+ sigset_t sa_mask;
+};
diff --git a/libc/sysdeps/unix/sysv/linux/kernel_stat.h b/libc/sysdeps/unix/sysv/linux/kernel_stat.h
new file mode 100644
index 000000000..9f8434caa
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/kernel_stat.h
@@ -0,0 +1,35 @@
+/* Definition of `struct stat' used in the kernel.. */
+struct kernel_stat
+ {
+ unsigned short int st_dev;
+ unsigned short int __pad1;
+#define _HAVE___PAD1
+ unsigned long int st_ino;
+ unsigned short int st_mode;
+ unsigned short int st_nlink;
+ unsigned short int st_uid;
+ unsigned short int st_gid;
+ unsigned short int st_rdev;
+ unsigned short int __pad2;
+#define _HAVE___PAD2
+ unsigned long int st_size;
+ unsigned long int st_blksize;
+ unsigned long int st_blocks;
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+ unsigned long int __unused4;
+#define _HAVE___UNUSED4
+ unsigned long int __unused5;
+#define _HAVE___UNUSED5
+ };
+
+#define _HAVE_STAT___UNUSED4
+#define _HAVE_STAT___UNUSED5
+#define _HAVE_STAT___PAD1
+#define _HAVE_STAT___PAD2
+#define _HAVE_STAT_NSEC
+#define _HAVE_STAT64___PAD1
+#define _HAVE_STAT64___PAD2
+#define _HAVE_STAT64___ST_INO
+#define _HAVE_STAT64_NSEC
diff --git a/libc/sysdeps/unix/sysv/linux/kernel_termios.h b/libc/sysdeps/unix/sysv/linux/kernel_termios.h
new file mode 100644
index 000000000..872ee36b9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/kernel_termios.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _KERNEL_TERMIOS_H
+#define _KERNEL_TERMIOS_H 1
+/* The following corresponds to the values from the Linux 2.1.20 kernel. */
+
+#define __KERNEL_NCCS 19
+
+struct __kernel_termios
+ {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[__KERNEL_NCCS]; /* control characters */
+ };
+
+#endif /* kernel_termios.h */
diff --git a/libc/sysdeps/unix/sysv/linux/ldd-rewrite.sed b/libc/sysdeps/unix/sysv/linux/ldd-rewrite.sed
new file mode 100644
index 000000000..7b8b6bdee
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ldd-rewrite.sed
@@ -0,0 +1,11 @@
+/Maybe extra code for non-ELF binaries/a\
+ file=$1\
+ # Run the ldd stub.\
+ lddlibc4 "$file"\
+ # Test the result.\
+ if test $? -lt 3; then\
+ return 0;\
+ fi\
+ # In case of an error punt.
+/LD_TRACE_LOADED_OBJECTS=1/a\
+add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out"
diff --git a/libc/sysdeps/unix/sysv/linux/lddlibc4.c b/libc/sysdeps/unix/sysv/linux/lddlibc4.c
new file mode 100644
index 000000000..7683ec2ef
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/lddlibc4.c
@@ -0,0 +1,88 @@
+/* Stub for ldd script to print Linux libc4 dependencies.
+ Copyright (C) 1998, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This code is based on the `ldd' program code from the Linux ld.so
+ package. */
+
+#include <a.out.h>
+#include <errno.h>
+#include <error.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Get libc version number. */
+#include "../version.h"
+
+#define PACKAGE _libc_intl_domainname
+
+
+int
+main (int argc, char *argv[])
+{
+ const char *filename;
+ size_t filename_len;
+ struct exec exec;
+ char *buf;
+ FILE *fp;
+
+ /* Set locale via LC_ALL. */
+ setlocale (LC_ALL, "");
+
+ /* Set the text message domain. */
+ textdomain (PACKAGE);
+
+ /* We expect exactly one argument. */
+ if (argc != 2)
+ return 1;
+
+ filename = argv[1];
+
+ /* First see whether this is really an a.out binary. */
+ fp = fopen (filename, "rb");
+ if (fp == NULL)
+ error (2, errno, gettext ("cannot open `%s'"), filename);
+
+ /* Read the program header. */
+ if (fread (&exec, sizeof exec, 1, fp) < 1)
+ error (2, errno, gettext ("cannot read header from `%s'"), filename);
+
+ /* Test for the magic numbers. */
+ if (N_MAGIC (exec) != ZMAGIC && N_MAGIC (exec) != QMAGIC
+ && N_MAGIC (exec) != OMAGIC)
+ exit (3);
+
+ /* We don't need the file open anymore. */
+ fclose (fp);
+
+ /* We must put `__LDD_ARGV0=<program-name>' in the environment. */
+ filename_len = strlen (filename);
+ buf = (char *) alloca (sizeof "__LDD_ARGV0=" + filename_len);
+ mempcpy (mempcpy (buf, "__LDD_ARGV0=", sizeof "__LDD_ARGV0=" - 1),
+ filename, filename_len + 1);
+ /* ...and put the value in the environment. */
+ putenv (buf);
+
+ /* Now we can execute the binary. */
+ return execv (filename, &argv[argc]) ? 4 : 0;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/ldsodefs.h b/libc/sysdeps/unix/sysv/linux/ldsodefs.h
new file mode 100644
index 000000000..0bdca3c3f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ldsodefs.h
@@ -0,0 +1,56 @@
+/* Run-time dynamic linker data structures for loaded ELF shared objects.
+ Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LDSODEFS_H
+
+#include <kernel-features.h>
+
+/* Get the real definitions. */
+#include_next <ldsodefs.h>
+
+/* Now define our stuff. */
+
+/* We have the auxiliary vector. */
+#define HAVE_AUX_VECTOR
+
+/* Used by static binaries to check the auxiliary vector. */
+extern void _dl_aux_init (ElfW(auxv_t) *av) internal_function;
+
+/* Initialization which is normally done by the dynamic linker. */
+extern void _dl_non_dynamic_init (void) internal_function;
+
+/* We can assume that the kernel always provides the AT_UID, AT_EUID,
+ AT_GID, and AT_EGID values in the auxiliary vector from 2.4.0 or so on. */
+#if __ASSUME_AT_XID
+# define HAVE_AUX_XID
+#endif
+
+/* We can assume that the kernel always provides the AT_SECURE value
+ in the auxiliary vector from 2.5.74 or so on. */
+#if __ASSUME_AT_SECURE
+# define HAVE_AUX_SECURE
+#endif
+
+/* Starting with one of the 2.4.0 pre-releases the Linux kernel passes
+ up the page size information. */
+#if __ASSUME_AT_PAGESIZE
+# define HAVE_AUX_PAGESIZE
+#endif
+
+#endif /* ldsodefs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/libc_fatal.c b/libc/sysdeps/unix/sysv/linux/libc_fatal.c
new file mode 100644
index 000000000..c7fac6ab5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/libc_fatal.c
@@ -0,0 +1,183 @@
+/* Copyright (C) 1993-1995,1997,2000,2002-2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysdep.h>
+#include <unistd.h>
+#include <sys/syslog.h>
+#include <execinfo.h>
+
+/* Abort with an error message. */
+#include <not-cancel.h>
+
+#ifdef FATAL_PREPARE_INCLUDE
+#include FATAL_PREPARE_INCLUDE
+#endif
+
+struct str_list
+{
+ const char *str;
+ size_t len;
+ struct str_list *next;
+};
+
+
+/* Abort with an error message. */
+void
+__libc_message (int do_abort, const char *fmt, ...)
+{
+ va_list ap;
+ va_list ap_copy;
+ int fd = -1;
+
+ va_start (ap, fmt);
+ va_copy (ap_copy, ap);
+
+#ifdef FATAL_PREPARE
+ FATAL_PREPARE;
+#endif
+
+ /* Open a descriptor for /dev/tty unless the user explicitly
+ requests errors on standard error. */
+ const char *on_2 = __secure_getenv ("LIBC_FATAL_STDERR_");
+ if (on_2 == NULL || *on_2 == '\0')
+ fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
+
+ if (fd == -1)
+ fd = STDERR_FILENO;
+
+ struct str_list *list = NULL;
+ int nlist = 0;
+
+ const char *cp = fmt;
+ while (*cp != '\0')
+ {
+ /* Find the next "%s" or the end of the string. */
+ const char *next = cp;
+ while (next[0] != '%' || next[1] != 's')
+ {
+ next = __strchrnul (next + 1, '%');
+
+ if (next[0] == '\0')
+ break;
+ }
+
+ /* Determine what to print. */
+ const char *str;
+ size_t len;
+ if (cp[0] == '%' && cp[1] == 's')
+ {
+ str = va_arg (ap, const char *);
+ len = strlen (str);
+ cp += 2;
+ }
+ else
+ {
+ str = cp;
+ len = next - cp;
+ cp = next;
+ }
+
+ struct str_list *newp = alloca (sizeof (struct str_list));
+ newp->str = str;
+ newp->len = len;
+ newp->next = list;
+ list = newp;
+ ++nlist;
+ }
+
+ bool written = false;
+ if (nlist > 0)
+ {
+ struct iovec *iov = alloca (nlist * sizeof (struct iovec));
+ ssize_t total = 0;
+
+ for (int cnt = nlist - 1; cnt >= 0; --cnt)
+ {
+ iov[cnt].iov_base = (void *) list->str;
+ iov[cnt].iov_len = list->len;
+ total += list->len;
+ list = list->next;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+ ssize_t cnt;
+ do
+ cnt = INTERNAL_SYSCALL (writev, err, 3, fd, iov, nlist);
+ while (INTERNAL_SYSCALL_ERROR_P (cnt, err)
+ && INTERNAL_SYSCALL_ERRNO (cnt, err) == EINTR);
+
+ if (cnt == total)
+ written = true;
+ }
+
+ va_end (ap);
+
+ /* If we had no success writing the message, use syslog. */
+ if (! written)
+ vsyslog (LOG_ERR, fmt, ap_copy);
+
+ va_end (ap_copy);
+
+ if (do_abort)
+ {
+ if (do_abort > 1 && written)
+ {
+ void *addrs[64];
+#define naddrs (sizeof (addrs) / sizeof (addrs[0]))
+ int n = __backtrace (addrs, naddrs);
+ if (n > 2)
+ {
+#define strnsize(str) str, strlen (str)
+#define writestr(str) write_not_cancel (fd, str)
+ writestr (strnsize ("======= Backtrace: =========\n"));
+ __backtrace_symbols_fd (addrs + 1, n - 1, fd);
+
+ writestr (strnsize ("======= Memory map: ========\n"));
+ int fd2 = open_not_cancel_2 ("/proc/self/maps", O_RDONLY);
+ char buf[1024];
+ ssize_t n2;
+ while ((n2 = read_not_cancel (fd2, buf, sizeof (buf))) > 0)
+ if (write_not_cancel (fd, buf, n2) != n2)
+ break;
+ close_not_cancel_no_status (fd2);
+ }
+ }
+
+ /* Terminate the process. */
+ abort ();
+ }
+}
+
+
+void
+__libc_fatal (message)
+ const char *message;
+{
+ /* The loop is added only to keep gcc happy. */
+ while (1)
+ __libc_message (1, "%s", message);
+}
+libc_hidden_def (__libc_fatal)
diff --git a/libc/sysdeps/unix/sysv/linux/linkat.c b/libc/sysdeps/unix/sysv/linux/linkat.c
new file mode 100644
index 000000000..cfd0e1822
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/linkat.c
@@ -0,0 +1,115 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <sysdep.h>
+#include <unistd.h>
+#include <kernel-features.h>
+
+
+/* Make a link to FROM named TO but relative paths in TO and FROM are
+ interpreted relative to FROMFD and TOFD respectively. */
+int
+linkat (fromfd, from, tofd, to, flags)
+ int fromfd;
+ const char *from;
+ int tofd;
+ const char *to;
+ int flags;
+{
+ int result;
+
+#ifdef __NR_linkat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INLINE_SYSCALL (linkat, 5, fromfd, from, tofd, to, flags);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ /* Without kernel support we cannot handle AT_SYMLINK_FOLLOW. */
+ if (flags != 0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ char *buffrom = NULL;
+
+ if (fromfd != AT_FDCWD && from[0] != '/')
+ {
+ size_t filelen = strlen (from);
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buffrom = alloca (buflen);
+
+ __snprintf (buffrom, buflen, procfd, fromfd, from);
+ from = buffrom;
+ }
+
+ char *bufto = NULL;
+
+ if (tofd != AT_FDCWD && to[0] != '/')
+ {
+ size_t filelen = strlen (to);
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ bufto = alloca (buflen);
+
+ __snprintf (bufto, buflen, procfd, tofd, to);
+ to = bufto;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+ result = INTERNAL_SYSCALL (link, err, 2, from, to);
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ {
+ __atfct_seterrno_2 (INTERNAL_SYSCALL_ERRNO (result, err), tofd, bufto,
+ fromfd, buffrom);
+ result = -1;
+ }
+
+ return result;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/linux_fsinfo.h b/libc/sysdeps/unix/sysv/linux/linux_fsinfo.h
new file mode 100644
index 000000000..8c6591ada
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/linux_fsinfo.h
@@ -0,0 +1,156 @@
+/* Constants from kernel header for various FSes.
+ Copyright (C) 1998,1999,2000,2001,2002,2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINUX_FSINFO_H
+#define _LINUX_FSINFO_H 1
+
+/* These definitions come from the kernel headers. But we cannot
+ include the headers here because of type clashes. If new
+ filesystem types will become available we have to add the
+ appropriate definitions here.*/
+
+/* Constants that identify the `adfs' filesystem. */
+#define ADFS_SUPER_MAGIC 0xadf5
+
+/* Constants that identify the `affs' filesystem. */
+#define AFFS_SUPER_MAGIC 0xadff
+
+/* Constants that identify the `autofs' filesystem. */
+#define AUTOFS_SUPER_MAGIC 0x187
+
+/* Constants that identify the `bfs' filesystem. */
+#define BFS_MAGIC 0x1BADFACE
+
+/* Constants that identify the `coda' filesystem. */
+#define CODA_SUPER_MAGIC 0x73757245
+
+/* Constants that identify the `coherent' filesystem. */
+#define COH_SUPER_MAGIC 0x012ff7b7
+
+/* Constant that identifies the `ramfs' filesystem. */
+#define CRAMFS_MAGIC 0x28cd3d45
+
+/* Constant that identifies the `devfs' filesystem. */
+#define DEVFS_SUPER_MAGIC 0x1373
+
+/* Constant that identifies the `devpts' filesystem. */
+#define DEVPTS_SUPER_MAGIC 0x1cd1
+
+/* Constant that identifies the `efs' filesystem. */
+#define EFS_SUPER_MAGIC 0x414A53
+#define EFS_MAGIC 0x072959
+
+/* Constant that identifies the `ext2' and `ext3' filesystems. */
+#define EXT2_SUPER_MAGIC 0xef53
+
+/* Constant that identifies the `hpfs' filesystem. */
+#define HPFS_SUPER_MAGIC 0xf995e849
+
+/* Constant that identifies the `iso9660' filesystem. */
+#define ISOFS_SUPER_MAGIC 0x9660
+
+/* Constant that identifies the `jffs' filesystem. */
+#define JFFS_SUPER_MAGIC 0x07c0
+
+/* Constant that identifies the `jffs2' filesystem. */
+#define JFFS2_SUPER_MAGIC 0x72b6
+
+/* Constant that identifies the `jfs' filesystem. */
+#define JFS_SUPER_MAGIC 0x3153464a
+
+/* Constants that identify the `minix2' filesystem. */
+#define MINIX2_SUPER_MAGIC 0x2468
+#define MINIX2_SUPER_MAGIC2 0x2478
+
+/* Constants that identify the `minix' filesystem. */
+#define MINIX_SUPER_MAGIC 0x137f
+#define MINIX_SUPER_MAGIC2 0x138F
+
+/* Constants that identify the `msdos' filesystem. */
+#define MSDOS_SUPER_MAGIC 0x4d44
+
+/* Constants that identify the `ncp' filesystem. */
+#define NCP_SUPER_MAGIC 0x564c
+
+/* Constants that identify the `nfs' filesystem. */
+#define NFS_SUPER_MAGIC 0x6969
+
+/* Constants that identify the `ntfs' filesystem. */
+#define NTFS_SUPER_MAGIC 0x5346544e
+
+/* Constants that identify the `proc' filesystem. */
+#define PROC_SUPER_MAGIC 0x9fa0
+
+/* Constant that identifies the `usbdevfs' filesystem. */
+#define USBDEVFS_SUPER_MAGIC 0x9fa2
+
+/* Constants that identify the `qnx4' filesystem. */
+#define QNX4_SUPER_MAGIC 0x002f
+
+/* Constants that identify the `reiser' filesystem. */
+#define REISERFS_SUPER_MAGIC 0x52654973
+
+/* Constant that identifies the `romfs' filesystem. */
+#define ROMFS_SUPER_MAGIC 0x7275
+
+/* Constants that identify the `smb' filesystem. */
+#define SMB_SUPER_MAGIC 0x517b
+
+/* Constants that identify the `sysV' filesystem. */
+#define SYSV2_SUPER_MAGIC 0x012ff7b6
+#define SYSV4_SUPER_MAGIC 0x012ff7b5
+
+/* Constants that identify the `udf' filesystem. */
+#define UDF_SUPER_MAGIC 0x15013346
+
+/* Constants that identify the `ufs' filesystem. */
+#define UFS_MAGIC 0x00011954
+#define UFS_CIGAM 0x54190100 /* byteswapped MAGIC */
+
+/* Constants that identify the `xenix' filesystem. */
+#define XENIX_SUPER_MAGIC 0x012ff7b4
+
+/* Constant that identifies the `shm' filesystem. */
+#define SHMFS_SUPER_MAGIC 0x01021994
+
+/* Constants that identify the `xfs' filesystem. */
+#define XFS_SUPER_MAGIC 0x58465342
+
+/* Constants that identify the `vxfs' filesystem. */
+#define VXFS_SUPER_MAGIC 0xa501fcf5
+
+/* Constants that identify the `sysfs´ filesystem. */
+#define SYSFS_MAGIC 0x62656572
+
+/* Maximum link counts. */
+#define COH_LINK_MAX 10000
+#define EXT2_LINK_MAX 32000
+#define MINIX2_LINK_MAX 65530
+#define MINIX_LINK_MAX 250
+#define REISERFS_LINK_MAX 64535
+#define SYSV_LINK_MAX 126 /* 127? 251? */
+#define UFS_LINK_MAX EXT2_LINK_MAX
+#define XENIX_LINK_MAX 126 /* ?? */
+#define XFS_LINK_MAX 2147483647
+
+/* The Linux kernel header mentioned this as a kind of generic value. */
+#define LINUX_LINK_MAX 127
+
+
+#endif /* linux_fsinfo.h */
diff --git a/libc/sysdeps/unix/sysv/linux/listen.S b/libc/sysdeps/unix/sysv/linux/listen.S
new file mode 100644
index 000000000..bed6a05f2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/listen.S
@@ -0,0 +1,5 @@
+#define socket listen
+#define NARGS 2
+#define NO_WEAK_ALIAS 1
+#include <socket.S>
+weak_alias (listen, __listen)
diff --git a/libc/sysdeps/unix/sysv/linux/llseek.c b/libc/sysdeps/unix/sysv/linux/llseek.c
new file mode 100644
index 000000000..25c7bf2b5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/llseek.c
@@ -0,0 +1,47 @@
+/* Long-long seek operation.
+ Copyright (C) 1996-2000,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Seek to OFFSET on FD, starting from WHENCE. */
+extern loff_t __llseek (int fd, loff_t offset, int whence);
+
+loff_t
+__llseek (int fd, loff_t offset, int whence)
+{
+ loff_t retval;
+
+ return (loff_t) (INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 32),
+ (off_t) (offset & 0xffffffff),
+ __ptrvalue (&retval), whence) ?: retval);
+}
+weak_alias (__llseek, llseek)
+strong_alias (__llseek, __libc_lseek64)
+strong_alias (__llseek, __lseek64)
+weak_alias (__llseek, lseek64)
+
+/* llseek doesn't have a prototype. Since the second parameter is a
+ 64bit type, this results in wrong behaviour if no prototype is
+ provided. */
+link_warning (llseek, "\
+the `llseek' function may be dangerous; use `lseek64' instead.")
diff --git a/libc/sysdeps/unix/sysv/linux/local-setxid.h b/libc/sysdeps/unix/sysv/linux/local-setxid.h
new file mode 100644
index 000000000..057968798
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/local-setxid.h
@@ -0,0 +1,23 @@
+/* SETxID functions which only have to change the local thread and
+ none of the possible other threads. */
+#include <kernel-features.h>
+#include <sysdep.h>
+
+/* If we can use the syscall directly, use it. */
+#if __ASSUME_32BITUIDS > 0 && defined __NR_setresuid32
+# define local_seteuid(id) INLINE_SYSCALL (setresuid32, 3, -1, id, -1)
+#elif __ASSUME_SETRESUID_SYSCALL > 0
+# define local_seteuid(id) INLINE_SYSCALL (setresuid, 3, -1, id, -1)
+#else
+# define local_seteuid(id) seteuid (id)
+#endif
+
+
+/* If we can use the syscall directly, use it. */
+#if __ASSUME_32BITUIDS > 0 && defined __NR_setresgid32
+# define local_setegid(id) INLINE_SYSCALL (setresgid32, 3, -1, id, -1)
+#elif __ASSUME_SETRESGID_SYSCALL > 0
+# define local_setegid(id) INLINE_SYSCALL (setresgid, 3, -1, id, -1)
+#else
+# define local_setegid(id) setegid (id)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/lseek64.c b/libc/sysdeps/unix/sysv/linux/lseek64.c
new file mode 100644
index 000000000..d81e98fb5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/lseek64.c
@@ -0,0 +1 @@
+/* We don't need a definition since the llseek function is what we need. */
diff --git a/libc/sysdeps/unix/sysv/linux/lxstat.c b/libc/sysdeps/unix/sysv/linux/lxstat.c
new file mode 100644
index 000000000..f49c25236
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/lxstat.c
@@ -0,0 +1,64 @@
+/* lxstat using old-style Unix lstat system call.
+ Copyright (C) 1991,1995-1998,2000,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ho hum, if xstat == xstat64 we must get rid of the prototype or gcc
+ will complain since they don't strictly match. */
+#define __lxstat64 __lxstat64_disable
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <xstatconv.h>
+
+/* Get information about the file NAME in BUF. */
+int
+__lxstat (int vers, const char *name, struct stat *buf)
+{
+ if (vers == _STAT_VER_KERNEL)
+ return INLINE_SYSCALL (lstat, 2, CHECK_STRING (name),
+ CHECK_1 ((struct kernel_stat *) buf));
+
+#ifdef STAT_IS_KERNEL_STAT
+ errno = EINVAL;
+ return -1;
+#else
+ struct kernel_stat kbuf;
+ int result;
+
+ result = INLINE_SYSCALL (lstat, 2, CHECK_STRING (name), __ptrvalue (&kbuf));
+ if (result == 0)
+ result = __xstat_conv (vers, &kbuf, buf);
+
+ return result;
+#endif
+}
+
+hidden_def (__lxstat)
+weak_alias (__lxstat, _lxstat);
+#ifdef XSTAT_IS_XSTAT64
+#undef __lxstat64
+strong_alias (__lxstat, __lxstat64);
+hidden_ver (__lxstat, __lxstat64)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/lxstat64.c b/libc/sysdeps/unix/sysv/linux/lxstat64.c
new file mode 100644
index 000000000..7444dfe0d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/lxstat64.c
@@ -0,0 +1,93 @@
+/* lxstat64 using old-style Unix lstat system call.
+ Copyright (C) 1997-2002,2003,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if __ASSUME_STAT64_SYSCALL == 0
+# include <xstatconv.h>
+#endif
+
+#ifdef __NR_lstat64
+# if __ASSUME_STAT64_SYSCALL == 0
+/* The variable is shared between all wrappers around *stat64 calls. */
+extern int __have_no_stat64;
+# endif
+#endif
+
+/* Get information about the file NAME in BUF. */
+int
+___lxstat64 (int vers, const char *name, struct stat64 *buf)
+{
+ int result;
+#ifdef __ASSUME_STAT64_SYSCALL
+ result = INLINE_SYSCALL (lstat64, 2, CHECK_STRING (name), CHECK_1 (buf));
+# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+ if (__builtin_expect (!result, 1) && buf->__st_ino != (__ino_t) buf->st_ino)
+ buf->st_ino = buf->__st_ino;
+# endif
+ return result;
+#else
+ struct kernel_stat kbuf;
+# ifdef __NR_lstat64
+ if (! __have_no_stat64)
+ {
+ int saved_errno = errno;
+ result = INLINE_SYSCALL (lstat64, 2, CHECK_STRING (name), CHECK_1 (buf));
+
+ if (result != -1 || errno != ENOSYS)
+ {
+# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+ if (!result && buf->__st_ino != (__ino_t) buf->st_ino)
+ buf->st_ino = buf->__st_ino;
+# endif
+ return result;
+ }
+
+ __set_errno (saved_errno);
+ __have_no_stat64 = 1;
+ }
+# endif
+ result = INLINE_SYSCALL (lstat, 2, CHECK_STRING (name), __ptrvalue (&kbuf));
+ if (result == 0)
+ result = __xstat64_conv (vers, &kbuf, buf);
+
+ return result;
+#endif
+}
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+versioned_symbol (libc, ___lxstat64, __lxstat64, GLIBC_2_2);
+strong_alias (___lxstat64, __old__lxstat64)
+compat_symbol (libc, __old__lxstat64, __lxstat64, GLIBC_2_1);
+hidden_ver (___lxstat64, __lxstat64)
+#else
+strong_alias (___lxstat64, __lxstat64);
+hidden_def (__lxstat64)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/makedev.c b/libc/sysdeps/unix/sysv/linux/makedev.c
new file mode 100644
index 000000000..93b7012da
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/makedev.c
@@ -0,0 +1,41 @@
+/* Definitions of functions to access `dev_t' values.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <endian.h>
+#include <sys/sysmacros.h>
+
+unsigned int
+gnu_dev_major (unsigned long long int dev)
+{
+ return ((dev >> 8) & 0xfff) | ((unsigned int) (dev >> 32) & ~0xfff);
+}
+
+unsigned int
+gnu_dev_minor (unsigned long long int dev)
+{
+ return (dev & 0xff) | ((unsigned int) (dev >> 12) & ~0xff);
+}
+
+unsigned long long int
+gnu_dev_makedev (unsigned int major, unsigned int minor)
+{
+ return ((minor & 0xff) | ((major & 0xfff) << 8)
+ | (((unsigned long long int) (minor & ~0xff)) << 12)
+ | (((unsigned long long int) (major & ~0xfff)) << 32));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/mkdirat.c b/libc/sysdeps/unix/sysv/linux/mkdirat.c
new file mode 100644
index 000000000..3c190085c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/mkdirat.c
@@ -0,0 +1,86 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <kernel-features.h>
+#include <sysdep-cancel.h>
+
+
+/* Create a new directory with permission bits MODE. But interpret
+ relative PATH names relative to the directory associated with FD. */
+int
+mkdirat (fd, file, mode)
+ int fd;
+ const char *file;
+ mode_t mode;
+{
+ int res;
+
+#ifdef __NR_mkdirat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ res = INLINE_SYSCALL (mkdirat, 3, fd, file, mode);
+# ifndef __ASSUME_ATFCTS
+ if (res == -1 && res == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return res;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+ res = INTERNAL_SYSCALL (mkdir, err, 2, file, mode);
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
+ {
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (res, err), fd, buf);
+ res = -1;
+ }
+
+ return res;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/mmap64.c b/libc/sysdeps/unix/sysv/linux/mmap64.c
new file mode 100644
index 000000000..d3c68cd10
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/mmap64.c
@@ -0,0 +1,89 @@
+/* Copyright (C) 1999,2000,2001,2002,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_mmap2
+
+/* This is always 12, even on architectures where PAGE_SHIFT != 12. */
+# ifndef MMAP2_PAGE_SHIFT
+# define MMAP2_PAGE_SHIFT 12
+# endif
+
+# ifndef __ASSUME_MMAP2_SYSCALL
+static int have_no_mmap2;
+# endif
+#endif
+
+
+void *
+__mmap64 (void *addr, size_t len, int prot, int flags, int fd, off64_t offset)
+{
+#ifdef __NR_mmap2
+ if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
+ {
+ __set_errno (EINVAL);
+ return MAP_FAILED;
+ }
+# ifndef __ASSUME_MMAP2_SYSCALL
+ if (! have_no_mmap2)
+# endif
+ {
+# ifndef __ASSUME_MMAP2_SYSCALL
+ int saved_errno = errno;
+# endif
+ void *result;
+ __ptrvalue (result) = (void *__unbounded)
+ INLINE_SYSCALL (mmap2, 6, __ptrvalue (addr),
+ len, prot, flags, fd,
+ (off_t) (offset >> MMAP2_PAGE_SHIFT));
+# if __BOUNDED_POINTERS__
+ __ptrlow (result) = __ptrvalue (result);
+ __ptrhigh (result) = __ptrvalue (result) + len;
+# endif
+# ifndef __ASSUME_MMAP2_SYSCALL
+ if (result != MAP_FAILED || errno != ENOSYS)
+# endif
+ return result;
+
+# ifndef __ASSUME_MMAP2_SYSCALL
+ __set_errno (saved_errno);
+ have_no_mmap2 = 1;
+# endif
+ }
+#endif
+#ifndef __ASSUME_MMAP2_SYSCALL
+ if (offset != (off_t) offset || (offset + len) != (off_t) (offset + len))
+ {
+ __set_errno (EINVAL);
+ return MAP_FAILED;
+ }
+
+ return __mmap (addr, len, prot, flags, fd, (off_t) offset);
+#endif
+}
+weak_alias (__mmap64, mmap64)
diff --git a/libc/sysdeps/unix/sysv/linux/mq_close.c b/libc/sysdeps/unix/sysv/linux/mq_close.c
new file mode 100644
index 000000000..008e8eeb9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/mq_close.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <mqueue.h>
+#include <sysdep.h>
+
+#ifdef __NR_mq_open
+
+/* Removes the association between message queue descriptor MQDES and its
+ message queue. */
+int
+mq_close (mqd_t mqdes)
+{
+ return INLINE_SYSCALL (close, 1, mqdes);
+}
+
+#else
+# include <rt/mq_close.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/mq_getattr.c b/libc/sysdeps/unix/sysv/linux/mq_getattr.c
new file mode 100644
index 000000000..d25df7bcf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/mq_getattr.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <mqueue.h>
+#include <stddef.h>
+#include <sysdep.h>
+
+#ifdef __NR_mq_getsetattr
+
+/* Query status and attributes of message queue MQDES. */
+int
+mq_getattr (mqd_t mqdes, struct mq_attr *mqstat)
+{
+ return mq_setattr (mqdes, NULL, mqstat);
+}
+
+#else
+# include <rt/mq_getattr.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/mq_notify.c b/libc/sysdeps/unix/sysv/linux/mq_notify.c
new file mode 100644
index 000000000..4eba28a30
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/mq_notify.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <mqueue.h>
+#include <stddef.h>
+#include <sysdep.h>
+
+#ifdef __NR_mq_notify
+
+/* Register notification upon message arrival to an empty message queue
+ MQDES. */
+int
+mq_notify (mqd_t mqdes, const struct sigevent *notification)
+{
+ /* mq_notify which handles SIGEV_THREAD is included in the thread
+ add-on. */
+ if (notification != NULL
+ && notification->sigev_notify == SIGEV_THREAD)
+ {
+ __set_errno (ENOSYS);
+ return -1;
+ }
+ return INLINE_SYSCALL (mq_notify, 2, mqdes, notification);
+}
+
+#else
+# include <rt/mq_notify.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/mq_open.c b/libc/sysdeps/unix/sysv/linux/mq_open.c
new file mode 100644
index 000000000..eac6e0123
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/mq_open.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <mqueue.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <sysdep.h>
+
+#ifdef __NR_mq_open
+
+/* Establish connection between a process and a message queue NAME and
+ return message queue descriptor or (mqd_t) -1 on error. OFLAG determines
+ the type of access used. If O_CREAT is on OFLAG, the third argument is
+ taken as a `mode_t', the mode of the created message queue, and the fourth
+ argument is taken as `struct mq_attr *', pointer to message queue
+ attributes. If the fourth argument is NULL, default attributes are
+ used. */
+mqd_t
+mq_open (const char *name, int oflag, ...)
+{
+ if (name[0] != '/')
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ mode_t mode = 0;
+ struct mq_attr *attr = NULL;
+ if (oflag & O_CREAT)
+ {
+ va_list ap;
+
+ va_start (ap, oflag);
+ mode = va_arg (ap, mode_t);
+ attr = va_arg (ap, struct mq_attr *);
+ va_end (ap);
+ }
+
+ return INLINE_SYSCALL (mq_open, 4, name + 1, oflag, mode, attr);
+}
+
+#else
+# include <rt/mq_open.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/mq_receive.c b/libc/sysdeps/unix/sysv/linux/mq_receive.c
new file mode 100644
index 000000000..218650802
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/mq_receive.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <mqueue.h>
+#include <stddef.h>
+#include <sysdep.h>
+
+#ifdef __NR_mq_timedreceive
+
+/* Receive the oldest from highest priority messages in message queue
+ MQDES. */
+ssize_t
+mq_receive (mqd_t mqdes, char *msg_ptr, size_t msg_len,
+ unsigned int *msg_prio)
+{
+ return mq_timedreceive (mqdes, msg_ptr, msg_len, msg_prio, NULL);
+}
+
+#else
+# include <rt/mq_receive.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/mq_send.c b/libc/sysdeps/unix/sysv/linux/mq_send.c
new file mode 100644
index 000000000..83b9f8df4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/mq_send.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <mqueue.h>
+#include <stddef.h>
+#include <sysdep.h>
+
+#ifdef __NR_mq_timedsend
+
+/* Add message pointed by MSG_PTR to message queue MQDES. */
+int
+mq_send (mqd_t mqdes, const char *msg_ptr, size_t msg_len,
+ unsigned int msg_prio)
+{
+ return mq_timedsend (mqdes, msg_ptr, msg_len, msg_prio, NULL);
+}
+
+#else
+# include <rt/mq_send.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/mq_unlink.c b/libc/sysdeps/unix/sysv/linux/mq_unlink.c
new file mode 100644
index 000000000..bef39a4ae
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/mq_unlink.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <mqueue.h>
+#include <sysdep.h>
+
+#ifdef __NR_mq_unlink
+
+/* Remove message queue named NAME. */
+int
+mq_unlink (const char *name)
+{
+ if (name[0] != '/')
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+ int ret = INTERNAL_SYSCALL (mq_unlink, err, 1, name + 1);
+
+ /* While unlink can return either EPERM or EACCES, mq_unlink should
+ return just EACCES. */
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (ret, err), 0))
+ {
+ ret = INTERNAL_SYSCALL_ERRNO (ret, err);
+ if (ret == EPERM)
+ ret = EACCES;
+ __set_errno (ret);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+#else
+# include <rt/mq_unlink.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/msgctl.c b/libc/sysdeps/unix/sysv/linux/msgctl.c
new file mode 100644
index 000000000..86fd34cf8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/msgctl.c
@@ -0,0 +1,135 @@
+/* Copyright (C) 1995,1997,1998,2000,2002,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/msg.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <shlib-compat.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+struct __old_msqid_ds
+{
+ struct __old_ipc_perm msg_perm; /* structure describing operation permission */
+ struct msg *__unbounded __msg_first; /* pointer to first message on queue */
+ struct msg *__unbounded __msg_last; /* pointer to last message on queue */
+ __time_t msg_stime; /* time of last msgsnd command */
+ __time_t msg_rtime; /* time of last msgrcv command */
+ __time_t msg_ctime; /* time of last change */
+ struct wait_queue *__unbounded __wwait; /* ??? */
+ struct wait_queue *__unbounded __rwait; /* ??? */
+ unsigned short int __msg_cbytes; /* current number of bytes on queue */
+ unsigned short int msg_qnum; /* number of messages currently on queue */
+ unsigned short int msg_qbytes; /* max number of bytes allowed on queue */
+ __ipc_pid_t msg_lspid; /* pid of last msgsnd() */
+ __ipc_pid_t msg_lrpid; /* pid of last msgrcv() */
+};
+
+/* Allows to control internal state and destruction of message queue
+ objects. */
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int __old_msgctl (int, int, struct __old_msqid_ds *);
+#endif
+int __new_msgctl (int, int, struct msqid_ds *);
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int
+attribute_compat_text_section
+__old_msgctl (int msqid, int cmd, struct __old_msqid_ds *buf)
+{
+ return INLINE_SYSCALL (ipc, 5, IPCOP_msgctl, msqid, cmd, 0, CHECK_1 (buf));
+}
+compat_symbol (libc, __old_msgctl, msgctl, GLIBC_2_0);
+#endif
+
+int
+__new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
+{
+#if __ASSUME_IPC64 > 0
+ return INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
+ msqid, cmd | __IPC_64, 0, CHECK_1 (buf));
+#else
+ switch (cmd) {
+ case MSG_STAT:
+ case IPC_STAT:
+ case IPC_SET:
+ break;
+ default:
+ return INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
+ msqid, cmd, 0, CHECK_1 (buf));
+ }
+
+ {
+ int result;
+ struct __old_msqid_ds old;
+
+ /* Unfortunately there is no way how to find out for sure whether
+ we should use old or new msgctl. */
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
+ msqid, cmd | __IPC_64, 0, CHECK_1 (buf));
+ if (result != -1 || errno != EINVAL)
+ return result;
+
+ if (cmd == IPC_SET)
+ {
+ old.msg_perm.uid = buf->msg_perm.uid;
+ old.msg_perm.gid = buf->msg_perm.gid;
+ old.msg_perm.mode = buf->msg_perm.mode;
+ old.msg_qbytes = buf->msg_qbytes;
+ if (old.msg_perm.uid != buf->msg_perm.uid ||
+ old.msg_perm.gid != buf->msg_perm.gid ||
+ old.msg_qbytes != buf->msg_qbytes)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ }
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
+ msqid, cmd, 0, __ptrvalue (&old));
+ if (result != -1 && cmd != IPC_SET)
+ {
+ memset(buf, 0, sizeof(*buf));
+ buf->msg_perm.__key = old.msg_perm.__key;
+ buf->msg_perm.uid = old.msg_perm.uid;
+ buf->msg_perm.gid = old.msg_perm.gid;
+ buf->msg_perm.cuid = old.msg_perm.cuid;
+ buf->msg_perm.cgid = old.msg_perm.cgid;
+ buf->msg_perm.mode = old.msg_perm.mode;
+ buf->msg_perm.__seq = old.msg_perm.__seq;
+ buf->msg_stime = old.msg_stime;
+ buf->msg_rtime = old.msg_rtime;
+ buf->msg_ctime = old.msg_ctime;
+ buf->__msg_cbytes = old.__msg_cbytes;
+ buf->msg_qnum = old.msg_qnum;
+ buf->msg_qbytes = old.msg_qbytes;
+ buf->msg_lspid = old.msg_lspid;
+ buf->msg_lrpid = old.msg_lrpid;
+ }
+ return result;
+ }
+#endif
+}
+
+versioned_symbol (libc, __new_msgctl, msgctl, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/msgget.c b/libc/sysdeps/unix/sysv/linux/msgget.c
new file mode 100644
index 000000000..a4a8290b7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/msgget.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1995, 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/msg.h>
+#include <ipc_priv.h>
+#include <stdlib.h> /* for definition of NULL */
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Return descriptor for message queue associated with KEY. The MSGFLG
+ parameter describes how to proceed with clashing of key values. */
+
+int
+msgget (key, msgflg)
+ key_t key;
+ int msgflg;
+{
+ return INLINE_SYSCALL (ipc, 5, IPCOP_msgget, key, msgflg, 0, NULL);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/msgrcv.c b/libc/sysdeps/unix/sysv/linux/msgrcv.c
new file mode 100644
index 000000000..71e7c7aea
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/msgrcv.c
@@ -0,0 +1,66 @@
+/* Copyright (C) 1995,1997,1998,2000,2002,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/msg.h>
+#include <ipc_priv.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+
+#include <bp-checks.h>
+
+/* Kludge to work around Linux' restriction of only up to five
+ arguments to a system call. */
+struct ipc_kludge
+ {
+ void *__unbounded msgp;
+ long int msgtyp;
+ };
+
+
+ssize_t
+__libc_msgrcv (msqid, msgp, msgsz, msgtyp, msgflg)
+ int msqid;
+ void *msgp;
+ size_t msgsz;
+ long int msgtyp;
+ int msgflg;
+{
+ /* The problem here is that Linux' calling convention only allows up to
+ fives parameters to a system call. */
+ struct ipc_kludge tmp;
+
+ tmp.msgp = CHECK_N (msgp, msgsz);
+ tmp.msgtyp = msgtyp;
+
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (ipc, 5, IPCOP_msgrcv, msqid, msgsz, msgflg,
+ __ptrvalue (&tmp));
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = INLINE_SYSCALL (ipc, 5, IPCOP_msgrcv, msqid, msgsz, msgflg,
+ __ptrvalue (&tmp));
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+weak_alias (__libc_msgrcv, msgrcv)
diff --git a/libc/sysdeps/unix/sysv/linux/msgsnd.c b/libc/sysdeps/unix/sysv/linux/msgsnd.c
new file mode 100644
index 000000000..c2031be71
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/msgsnd.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1995,1997,1998,1999,2000,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/msg.h>
+#include <ipc_priv.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+
+#include <bp-checks.h>
+
+int
+__libc_msgsnd (msqid, msgp, msgsz, msgflg)
+ int msqid;
+ const void *msgp;
+ size_t msgsz;
+ int msgflg;
+{
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (ipc, 5, IPCOP_msgsnd, msqid, msgsz,
+ msgflg, (void *) CHECK_N (msgp, msgsz));
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (ipc, 5, IPCOP_msgsnd, msqid, msgsz,
+ msgflg, (void *) CHECK_N (msgp, msgsz));
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+weak_alias (__libc_msgsnd, msgsnd)
diff --git a/libc/sysdeps/unix/sysv/linux/net/ethernet.h b/libc/sysdeps/unix/sysv/linux/net/ethernet.h
new file mode 100644
index 000000000..7ca8e8348
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/net/ethernet.h
@@ -0,0 +1,76 @@
+/* Copyright (C) 1997, 1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Based on the FreeBSD version of this file. Curiously, that file
+ lacks a copyright in the header. */
+
+#ifndef __NET_ETHERNET_H
+#define __NET_ETHERNET_H 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <linux/if_ether.h> /* IEEE 802.3 Ethernet constants */
+
+__BEGIN_DECLS
+
+/* This is a name for the 48 bit ethernet address available on many
+ systems. */
+struct ether_addr
+{
+ u_int8_t ether_addr_octet[ETH_ALEN];
+} __attribute__ ((__packed__));
+
+/* 10Mb/s ethernet header */
+struct ether_header
+{
+ u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
+ u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */
+ u_int16_t ether_type; /* packet type ID field */
+} __attribute__ ((__packed__));
+
+/* Ethernet protocol ID's */
+#define ETHERTYPE_PUP 0x0200 /* Xerox PUP */
+#define ETHERTYPE_IP 0x0800 /* IP */
+#define ETHERTYPE_ARP 0x0806 /* Address resolution */
+#define ETHERTYPE_REVARP 0x8035 /* Reverse ARP */
+
+#define ETHER_ADDR_LEN ETH_ALEN /* size of ethernet addr */
+#define ETHER_TYPE_LEN 2 /* bytes in type field */
+#define ETHER_CRC_LEN 4 /* bytes in CRC field */
+#define ETHER_HDR_LEN ETH_HLEN /* total octets in header */
+#define ETHER_MIN_LEN (ETH_ZLEN + ETHER_CRC_LEN) /* min packet length */
+#define ETHER_MAX_LEN (ETH_FRAME_LEN + ETHER_CRC_LEN) /* max packet length */
+
+/* make sure ethenet length is valid */
+#define ETHER_IS_VALID_LEN(foo) \
+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHERMTU ETH_DATA_LEN
+#define ETHERMIN (ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
+
+__END_DECLS
+
+#endif /* net/ethernet.h */
diff --git a/libc/sysdeps/unix/sysv/linux/net/if_arp.h b/libc/sysdeps/unix/sysv/linux/net/if_arp.h
new file mode 100644
index 000000000..9608652ee
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/net/if_arp.h
@@ -0,0 +1,182 @@
+/* Definitions for Address Resolution Protocol.
+ Copyright (C) 1997,1999,2001,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Based on the 4.4BSD and Linux version of this file. */
+
+#ifndef _NET_IF_ARP_H
+
+#define _NET_IF_ARP_H 1
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+__BEGIN_DECLS
+
+/* Some internals from deep down in the kernel. */
+#define MAX_ADDR_LEN 7
+
+
+/* This structure defines an ethernet arp header. */
+
+/* ARP protocol opcodes. */
+#define ARPOP_REQUEST 1 /* ARP request. */
+#define ARPOP_REPLY 2 /* ARP reply. */
+#define ARPOP_RREQUEST 3 /* RARP request. */
+#define ARPOP_RREPLY 4 /* RARP reply. */
+#define ARPOP_InREQUEST 8 /* InARP request. */
+#define ARPOP_InREPLY 9 /* InARP reply. */
+#define ARPOP_NAK 10 /* (ATM)ARP NAK. */
+
+/* See RFC 826 for protocol description. ARP packets are variable
+ in size; the arphdr structure defines the fixed-length portion.
+ Protocol type values are the same as those for 10 Mb/s Ethernet.
+ It is followed by the variable-sized fields ar_sha, arp_spa,
+ arp_tha and arp_tpa in that order, according to the lengths
+ specified. Field names used correspond to RFC 826. */
+
+struct arphdr
+ {
+ unsigned short int ar_hrd; /* Format of hardware address. */
+ unsigned short int ar_pro; /* Format of protocol address. */
+ unsigned char ar_hln; /* Length of hardware address. */
+ unsigned char ar_pln; /* Length of protocol address. */
+ unsigned short int ar_op; /* ARP opcode (command). */
+#if 0
+ /* Ethernet looks like this : This bit is variable sized
+ however... */
+ unsigned char __ar_sha[ETH_ALEN]; /* Sender hardware address. */
+ unsigned char __ar_sip[4]; /* Sender IP address. */
+ unsigned char __ar_tha[ETH_ALEN]; /* Target hardware address. */
+ unsigned char __ar_tip[4]; /* Target IP address. */
+#endif
+ };
+
+
+/* ARP protocol HARDWARE identifiers. */
+#define ARPHRD_NETROM 0 /* From KA9Q: NET/ROM pseudo. */
+#define ARPHRD_ETHER 1 /* Ethernet 10/100Mbps. */
+#define ARPHRD_EETHER 2 /* Experimental Ethernet. */
+#define ARPHRD_AX25 3 /* AX.25 Level 2. */
+#define ARPHRD_PRONET 4 /* PROnet token ring. */
+#define ARPHRD_CHAOS 5 /* Chaosnet. */
+#define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB. */
+#define ARPHRD_ARCNET 7 /* ARCnet. */
+#define ARPHRD_APPLETLK 8 /* APPLEtalk. */
+#define ARPHRD_DLCI 15 /* Frame Relay DLCI. */
+#define ARPHRD_ATM 19 /* ATM. */
+#define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id). */
+#define ARPHRD_IEEE1394 24 /* IEEE 1394 IPv4 - RFC 2734. */
+#define ARPHRD_EUI64 27 /* EUI-64. */
+#define ARPHRD_INFINIBAND 32 /* InfiniBand. */
+
+/* Dummy types for non ARP hardware */
+#define ARPHRD_SLIP 256
+#define ARPHRD_CSLIP 257
+#define ARPHRD_SLIP6 258
+#define ARPHRD_CSLIP6 259
+#define ARPHRD_RSRVD 260 /* Notional KISS type. */
+#define ARPHRD_ADAPT 264
+#define ARPHRD_ROSE 270
+#define ARPHRD_X25 271 /* CCITT X.25. */
+#define ARPHRD_HWX25 272 /* Boards with X.25 in firmware. */
+#define ARPHRD_PPP 512
+#define ARPHRD_CISCO 513 /* Cisco HDLC. */
+#define ARPHRD_HDLC ARPHRD_CISCO
+#define ARPHRD_LAPB 516 /* LAPB. */
+#define ARPHRD_DDCMP 517 /* Digital's DDCMP. */
+#define ARPHRD_RAWHDLC 518 /* Raw HDLC. */
+
+#define ARPHRD_TUNNEL 768 /* IPIP tunnel. */
+#define ARPHRD_TUNNEL6 769 /* IPIP6 tunnel. */
+#define ARPHRD_FRAD 770 /* Frame Relay Access Device. */
+#define ARPHRD_SKIP 771 /* SKIP vif. */
+#define ARPHRD_LOOPBACK 772 /* Loopback device. */
+#define ARPHRD_LOCALTLK 773 /* Localtalk device. */
+#define ARPHRD_FDDI 774 /* Fiber Distributed Data Interface. */
+#define ARPHRD_BIF 775 /* AP1000 BIF. */
+#define ARPHRD_SIT 776 /* sit0 device - IPv6-in-IPv4. */
+#define ARPHRD_IPDDP 777 /* IP-in-DDP tunnel. */
+#define ARPHRD_IPGRE 778 /* GRE over IP. */
+#define ARPHRD_PIMREG 779 /* PIMSM register interface. */
+#define ARPHRD_HIPPI 780 /* High Performance Parallel I'face. */
+#define ARPHRD_ASH 781 /* (Nexus Electronics) Ash. */
+#define ARPHRD_ECONET 782 /* Acorn Econet. */
+#define ARPHRD_IRDA 783 /* Linux-IrDA. */
+#define ARPHRD_FCPP 784 /* Point to point fibrechanel. */
+#define ARPHRD_FCAL 785 /* Fibrechanel arbitrated loop. */
+#define ARPHRD_FCPL 786 /* Fibrechanel public loop. */
+#define ARPHRD_FCFABRIC 787 /* Fibrechanel fabric. */
+#define ARPHRD_IEEE802_TR 800 /* Magic type ident for TR. */
+#define ARPHRD_IEEE80211 801 /* IEEE 802.11. */
+#define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header. */
+#define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header. */
+
+#define ARPHRD_VOID 0xFFFF /* Void type, nothing is known. */
+#define ARPHRD_NONE 0xFFFE /* Zero header length. */
+
+
+/* ARP ioctl request. */
+struct arpreq
+ {
+ struct sockaddr arp_pa; /* Protocol address. */
+ struct sockaddr arp_ha; /* Hardware address. */
+ int arp_flags; /* Flags. */
+ struct sockaddr arp_netmask; /* Netmask (only for proxy arps). */
+ char arp_dev[16];
+ };
+
+struct arpreq_old
+ {
+ struct sockaddr arp_pa; /* Protocol address. */
+ struct sockaddr arp_ha; /* Hardware address. */
+ int arp_flags; /* Flags. */
+ struct sockaddr arp_netmask; /* Netmask (only for proxy arps). */
+ };
+
+/* ARP Flag values. */
+#define ATF_COM 0x02 /* Completed entry (ha valid). */
+#define ATF_PERM 0x04 /* Permanent entry. */
+#define ATF_PUBL 0x08 /* Publish entry. */
+#define ATF_USETRAILERS 0x10 /* Has requested trailers. */
+#define ATF_NETMASK 0x20 /* Want to use a netmask (only
+ for proxy entries). */
+#define ATF_DONTPUB 0x40 /* Don't answer this addresses. */
+#define ATF_MAGIC 0x80 /* Automatically added entry. */
+
+
+/* Support for the user space arp daemon, arpd. */
+#define ARPD_UPDATE 0x01
+#define ARPD_LOOKUP 0x02
+#define ARPD_FLUSH 0x03
+
+struct arpd_request
+ {
+ unsigned short int req; /* Request type. */
+ u_int32_t ip; /* IP address of entry. */
+ unsigned long int dev; /* Device entry is tied to. */
+ unsigned long int stamp;
+ unsigned long int updated;
+ unsigned char ha[MAX_ADDR_LEN]; /* Hardware address. */
+ };
+
+__END_DECLS
+
+#endif /* net/if_arp.h */
diff --git a/libc/sysdeps/unix/sysv/linux/net/if_packet.h b/libc/sysdeps/unix/sysv/linux/net/if_packet.h
new file mode 100644
index 000000000..e5184e7f1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/net/if_packet.h
@@ -0,0 +1,37 @@
+/* Definitions for use with Linux SOCK_PACKET sockets.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __IF_PACKET_H
+#define __IF_PACKET_H
+
+#include <features.h>
+#include <bits/sockaddr.h>
+
+/* This is the SOCK_PACKET address structure as used in Linux 2.0.
+ From Linux 2.1 the AF_PACKET interface is preferred and you should
+ consider using it in place of this one. */
+
+struct sockaddr_pkt
+ {
+ __SOCKADDR_COMMON (spkt_);
+ unsigned char spkt_device[14];
+ unsigned short spkt_protocol;
+ };
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/net/if_ppp.h b/libc/sysdeps/unix/sysv/linux/net/if_ppp.h
new file mode 100644
index 000000000..bf5ec8387
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/net/if_ppp.h
@@ -0,0 +1,169 @@
+/* From: if_ppp.h,v 1.3 1995/06/12 11:36:50 paulus Exp */
+
+/*
+ * if_ppp.h - Point-to-Point Protocol definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon University.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY 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 UNIVERSITY 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.
+ *
+ */
+
+/*
+ * ==FILEVERSION 960926==
+ *
+ * NOTE TO MAINTAINERS:
+ * If you modify this file at all, please set the above date.
+ * if_ppp.h is shipped with a PPP distribution as well as with the kernel;
+ * if everyone increases the FILEVERSION number above, then scripts
+ * can do the right thing when deciding whether to install a new if_ppp.h
+ * file. Don't change the format of that line otherwise, so the
+ * installation script can recognize it.
+ */
+
+
+#ifndef __NET_IF_PPP_H
+#define __NET_IF_PPP_H 1
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <net/ppp_defs.h>
+
+__BEGIN_DECLS
+
+/*
+ * Packet sizes
+ */
+
+#define PPP_MTU 1500 /* Default MTU (size of Info field) */
+#define PPP_MAXMRU 65000 /* Largest MRU we allow */
+#define PPP_VERSION "2.2.0"
+#define PPP_MAGIC 0x5002 /* Magic value for the ppp structure */
+#define PROTO_IPX 0x002b /* protocol numbers */
+#define PROTO_DNA_RT 0x0027 /* DNA Routing */
+
+
+/*
+ * Bit definitions for flags.
+ */
+
+#define SC_COMP_PROT 0x00000001 /* protocol compression (output) */
+#define SC_COMP_AC 0x00000002 /* header compression (output) */
+#define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */
+#define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */
+#define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */
+#define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */
+#define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */
+#define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */
+#define SC_ENABLE_IP 0x00000100 /* IP packets may be exchanged */
+#define SC_COMP_RUN 0x00001000 /* compressor has been inited */
+#define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */
+#define SC_DEBUG 0x00010000 /* enable debug messages */
+#define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */
+#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */
+#define SC_LOG_RAWIN 0x00080000 /* log all chars received */
+#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */
+#define SC_MASK 0x0fE0ffff /* bits that user can change */
+
+/* state bits */
+#define SC_ESCAPED 0x80000000 /* saw a PPP_ESCAPE */
+#define SC_FLUSH 0x40000000 /* flush input until next PPP_FLAG */
+#define SC_VJ_RESET 0x20000000 /* Need to reset the VJ decompressor */
+#define SC_XMIT_BUSY 0x10000000 /* ppp_write_wakeup is active */
+#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */
+#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */
+#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */
+#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */
+#define SC_DC_FERROR 0x00800000 /* fatal decomp error detected */
+#define SC_DC_ERROR 0x00400000 /* non-fatal decomp error detected */
+
+/*
+ * Ioctl definitions.
+ */
+
+struct npioctl {
+ int protocol; /* PPP protocol, e.g. PPP_IP */
+ enum NPmode mode;
+};
+
+/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */
+struct ppp_option_data {
+ u_int8_t *ptr;
+ u_int32_t length;
+ int transmit;
+};
+
+struct ifpppstatsreq {
+ struct ifreq b;
+ struct ppp_stats stats; /* statistic information */
+};
+
+struct ifpppcstatsreq {
+ struct ifreq b;
+ struct ppp_comp_stats stats;
+};
+
+#define ifr__name b.ifr_ifrn.ifrn_name
+#define stats_ptr b.ifr_ifru.ifru_data
+
+/*
+ * Ioctl definitions.
+ */
+
+#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */
+#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */
+#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */
+#define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */
+#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */
+#define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */
+#define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */
+#define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */
+#define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */
+#define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */
+#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */
+#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */
+#define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */
+#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data)
+#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */
+#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */
+#define PPPIOCGDEBUG _IOR('t', 65, int) /* Read debug level */
+#define PPPIOCSDEBUG _IOW('t', 64, int) /* Set debug level */
+#define PPPIOCGIDLE _IOR('t', 63, struct ppp_idle) /* get idle time */
+
+#define SIOCGPPPSTATS (SIOCDEVPRIVATE + 0)
+#define SIOCGPPPVER (SIOCDEVPRIVATE + 1) /* NEVER change this!! */
+#define SIOCGPPPCSTATS (SIOCDEVPRIVATE + 2)
+
+#if !defined(ifr_mtu)
+#define ifr_mtu ifr_ifru.ifru_metric
+#endif
+
+__END_DECLS
+
+#endif /* net/if_ppp.h */
diff --git a/libc/sysdeps/unix/sysv/linux/net/if_shaper.h b/libc/sysdeps/unix/sysv/linux/net/if_shaper.h
new file mode 100644
index 000000000..7060af31e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/net/if_shaper.h
@@ -0,0 +1,59 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NET_IF_SHAPER_H
+#define _NET_IF_SHAPER_H 1
+
+#include <features.h>
+#include <sys/types.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+
+__BEGIN_DECLS
+
+#define SHAPER_QLEN 10
+/*
+ * This is a bit speed dependant (read it shouldnt be a constant!)
+ *
+ * 5 is about right for 28.8 upwards. Below that double for every
+ * halving of speed or so. - ie about 20 for 9600 baud.
+ */
+#define SHAPER_LATENCY (5 * HZ)
+#define SHAPER_MAXSLIP 2
+#define SHAPER_BURST (HZ / 50) /* Good for >128K then */
+
+#define SHAPER_SET_DEV 0x0001
+#define SHAPER_SET_SPEED 0x0002
+#define SHAPER_GET_DEV 0x0003
+#define SHAPER_GET_SPEED 0x0004
+
+struct shaperconf
+{
+ u_int16_t ss_cmd;
+ union
+ {
+ char ssu_name[14];
+ u_int32_t ssu_speed;
+ } ss_u;
+#define ss_speed ss_u.ssu_speed
+#define ss_name ss_u.ssu_name
+};
+
+__END_DECLS
+
+#endif /* net/if_shaper.h */
diff --git a/libc/sysdeps/unix/sysv/linux/net/if_slip.h b/libc/sysdeps/unix/sysv/linux/net/if_slip.h
new file mode 100644
index 000000000..66bd7f30a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/net/if_slip.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NET_IF_SLIP_H
+#define _NET_IF_SLIP_H 1
+
+/* We can use the kernel header. */
+#include <linux/if_slip.h>
+
+#endif /* net/if_slip.h. */
diff --git a/libc/sysdeps/unix/sysv/linux/net/ppp-comp.h b/libc/sysdeps/unix/sysv/linux/net/ppp-comp.h
new file mode 100644
index 000000000..4a992d542
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/net/ppp-comp.h
@@ -0,0 +1 @@
+#include <linux/ppp-comp.h>
diff --git a/libc/sysdeps/unix/sysv/linux/net/ppp_defs.h b/libc/sysdeps/unix/sysv/linux/net/ppp_defs.h
new file mode 100644
index 000000000..f8924c4f2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/net/ppp_defs.h
@@ -0,0 +1,10 @@
+#ifndef _NET_PPP_DEFS_H
+#define _NET_PPP_DEFS_H 1
+
+#define __need_time_t
+#include <time.h>
+
+#include <asm/types.h>
+#include <linux/ppp_defs.h>
+
+#endif /* net/ppp_defs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/net/route.h b/libc/sysdeps/unix/sysv/linux/net/route.h
new file mode 100644
index 000000000..da5c810c7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/net/route.h
@@ -0,0 +1,145 @@
+/* Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Based on the 4.4BSD and Linux version of this file. */
+
+#ifndef _NET_ROUTE_H
+#define _NET_ROUTE_H 1
+
+#include <features.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <bits/wordsize.h>
+
+
+/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */
+struct rtentry
+ {
+ unsigned long int rt_pad1;
+ struct sockaddr rt_dst; /* Target address. */
+ struct sockaddr rt_gateway; /* Gateway addr (RTF_GATEWAY). */
+ struct sockaddr rt_genmask; /* Target network mask (IP). */
+ unsigned short int rt_flags;
+ short int rt_pad2;
+ unsigned long int rt_pad3;
+ unsigned char rt_tos;
+ unsigned char rt_class;
+#if __WORDSIZE == 64
+ short int rt_pad4[3];
+#else
+ short int rt_pad4;
+#endif
+ short int rt_metric; /* +1 for binary compatibility! */
+ char *rt_dev; /* Forcing the device at add. */
+ unsigned long int rt_mtu; /* Per route MTU/Window. */
+ unsigned long int rt_window; /* Window clamping. */
+ unsigned short int rt_irtt; /* Initial RTT. */
+ };
+/* Compatibility hack. */
+#define rt_mss rt_mtu
+
+
+struct in6_rtmsg
+ {
+ struct in6_addr rtmsg_dst;
+ struct in6_addr rtmsg_src;
+ struct in6_addr rtmsg_gateway;
+ u_int32_t rtmsg_type;
+ u_int16_t rtmsg_dst_len;
+ u_int16_t rtmsg_src_len;
+ u_int32_t rtmsg_metric;
+ unsigned long int rtmsg_info;
+ u_int32_t rtmsg_flags;
+ int rtmsg_ifindex;
+ };
+
+
+#define RTF_UP 0x0001 /* Route usable. */
+#define RTF_GATEWAY 0x0002 /* Destination is a gateway. */
+
+#define RTF_HOST 0x0004 /* Host entry (net otherwise). */
+#define RTF_REINSTATE 0x0008 /* Reinstate route after timeout. */
+#define RTF_DYNAMIC 0x0010 /* Created dyn. (by redirect). */
+#define RTF_MODIFIED 0x0020 /* Modified dyn. (by redirect). */
+#define RTF_MTU 0x0040 /* Specific MTU for this route. */
+#define RTF_MSS RTF_MTU /* Compatibility. */
+#define RTF_WINDOW 0x0080 /* Per route window clamping. */
+#define RTF_IRTT 0x0100 /* Initial round trip time. */
+#define RTF_REJECT 0x0200 /* Reject route. */
+#define RTF_STATIC 0x0400 /* Manually injected route. */
+#define RTF_XRESOLVE 0x0800 /* External resolver. */
+#define RTF_NOFORWARD 0x1000 /* Forwarding inhibited. */
+#define RTF_THROW 0x2000 /* Go to next class. */
+#define RTF_NOPMTUDISC 0x4000 /* Do not send packets with DF. */
+
+/* for IPv6 */
+#define RTF_DEFAULT 0x00010000 /* default - learned via ND */
+#define RTF_ALLONLINK 0x00020000 /* fallback, no routers on link */
+#define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */
+
+#define RTF_LINKRT 0x00100000 /* link specific - device match */
+#define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */
+
+#define RTF_CACHE 0x01000000 /* cache entry */
+#define RTF_FLOW 0x02000000 /* flow significant route */
+#define RTF_POLICY 0x04000000 /* policy route */
+
+#define RTCF_VALVE 0x00200000
+#define RTCF_MASQ 0x00400000
+#define RTCF_NAT 0x00800000
+#define RTCF_DOREDIRECT 0x01000000
+#define RTCF_LOG 0x02000000
+#define RTCF_DIRECTSRC 0x04000000
+
+#define RTF_LOCAL 0x80000000
+#define RTF_INTERFACE 0x40000000
+#define RTF_MULTICAST 0x20000000
+#define RTF_BROADCAST 0x10000000
+#define RTF_NAT 0x08000000
+
+#define RTF_ADDRCLASSMASK 0xF8000000
+#define RT_ADDRCLASS(flags) ((__u_int32_t) flags >> 23)
+
+#define RT_TOS(tos) ((tos) & IPTOS_TOS_MASK)
+
+#define RT_LOCALADDR(flags) ((flags & RTF_ADDRCLASSMASK) \
+ == (RTF_LOCAL|RTF_INTERFACE))
+
+#define RT_CLASS_UNSPEC 0
+#define RT_CLASS_DEFAULT 253
+
+#define RT_CLASS_MAIN 254
+#define RT_CLASS_LOCAL 255
+#define RT_CLASS_MAX 255
+
+
+#define RTMSG_ACK NLMSG_ACK
+#define RTMSG_OVERRUN NLMSG_OVERRUN
+
+#define RTMSG_NEWDEVICE 0x11
+#define RTMSG_DELDEVICE 0x12
+#define RTMSG_NEWROUTE 0x21
+#define RTMSG_DELROUTE 0x22
+#define RTMSG_NEWRULE 0x31
+#define RTMSG_DELRULE 0x32
+#define RTMSG_CONTROL 0x40
+
+#define RTMSG_AR_FAILED 0x51 /* Address Resolution failed. */
+
+#endif /* net/route.h */
diff --git a/libc/sysdeps/unix/sysv/linux/netash/ash.h b/libc/sysdeps/unix/sysv/linux/netash/ash.h
new file mode 100644
index 000000000..712c0aafd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/netash/ash.h
@@ -0,0 +1,40 @@
+/* Definitions for use with Linux AF_ASH sockets.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NETASH_ASH_H
+#define _NETASH_ASH_H 1
+
+#include <features.h>
+#include <bits/sockaddr.h>
+
+struct sockaddr_ash
+ {
+ __SOCKADDR_COMMON (sash_); /* Common data: address family etc. */
+ int sash_ifindex; /* Interface to use. */
+ unsigned char sash_channel; /* Realtime or control. */
+ unsigned int sash_plen;
+ unsigned char sash_prefix[16];
+ };
+
+/* Values for `channel' member. */
+#define ASH_CHANNEL_ANY 0
+#define ASH_CHANNEL_CONTROL 1
+#define ASH_CHANNEL_REALTIME 2
+
+#endif /* netash/ash.h */
diff --git a/libc/sysdeps/unix/sysv/linux/netatalk/at.h b/libc/sysdeps/unix/sysv/linux/netatalk/at.h
new file mode 100644
index 000000000..2668fc93b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/netatalk/at.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991, 1992, 1993, 1995, 1996, 1997, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NETATALK_AT_H
+#define _NETATALK_AT_H 1
+
+#include <asm/types.h>
+#include <bits/sockaddr.h>
+#include <linux/atalk.h>
+#include <sys/socket.h>
+
+#define SOL_ATALK 258 /* sockopt level for atalk */
+
+#endif /* netatalk/at.h */
diff --git a/libc/sysdeps/unix/sysv/linux/netax25/ax25.h b/libc/sysdeps/unix/sysv/linux/netax25/ax25.h
new file mode 100644
index 000000000..ce3c7abc9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/netax25/ax25.h
@@ -0,0 +1,171 @@
+/* Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NETAX25_AX25_H
+#define _NETAX25_AX25_H 1
+
+#include <features.h>
+#include <bits/sockaddr.h>
+
+/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx. */
+#define SOL_AX25 257
+
+/* AX.25 flags: */
+#define AX25_WINDOW 1
+#define AX25_T1 2
+#define AX25_T2 5
+#define AX25_T3 4
+#define AX25_N2 3
+#define AX25_BACKOFF 6
+#define AX25_EXTSEQ 7
+#define AX25_PIDINCL 8
+#define AX25_IDLE 9
+#define AX25_PACLEN 10
+#define AX25_IPMAXQUEUE 11
+#define AX25_IAMDIGI 12
+#define AX25_KILL 99
+
+/* AX.25 socket ioctls: */
+#define SIOCAX25GETUID (SIOCPROTOPRIVATE)
+#define SIOCAX25ADDUID (SIOCPROTOPRIVATE+1)
+#define SIOCAX25DELUID (SIOCPROTOPRIVATE+2)
+#define SIOCAX25NOUID (SIOCPROTOPRIVATE+3)
+#define SIOCAX25BPQADDR (SIOCPROTOPRIVATE+4)
+#define SIOCAX25GETPARMS (SIOCPROTOPRIVATE+5)
+#define SIOCAX25SETPARMS (SIOCPROTOPRIVATE+6)
+#define SIOCAX25OPTRT (SIOCPROTOPRIVATE+7)
+#define SIOCAX25CTLCON (SIOCPROTOPRIVATE+8)
+#define SIOCAX25GETINFO (SIOCPROTOPRIVATE+9)
+#define SIOCAX25ADDFWD (SIOCPROTOPRIVATE+10)
+#define SIOCAX25DELFWD (SIOCPROTOPRIVATE+11)
+
+/* unknown: */
+#define AX25_NOUID_DEFAULT 0
+#define AX25_NOUID_BLOCK 1
+#define AX25_SET_RT_IPMODE 2
+
+/* Digipeating flags: */
+#define AX25_DIGI_INBAND 0x01 /* Allow digipeating within port */
+#define AX25_DIGI_XBAND 0x02 /* Allow digipeating across ports */
+
+/* Maximim number of digipeaters: */
+#define AX25_MAX_DIGIS 8
+
+
+typedef struct
+ {
+ char ax25_call[7]; /* 6 call + SSID (shifted ascii) */
+ }
+ax25_address;
+
+struct sockaddr_ax25
+ {
+ sa_family_t sax25_family;
+ ax25_address sax25_call;
+ int sax25_ndigis;
+ };
+
+/*
+ * The sockaddr struct with the digipeater adresses:
+ */
+struct full_sockaddr_ax25
+ {
+ struct sockaddr_ax25 fsa_ax25;
+ ax25_address fsa_digipeater[AX25_MAX_DIGIS];
+ };
+#define sax25_uid sax25_ndigis
+
+struct ax25_routes_struct
+ {
+ ax25_address port_addr;
+ ax25_address dest_addr;
+ unsigned char digi_count;
+ ax25_address digi_addr[AX25_MAX_DIGIS];
+ };
+
+/* The AX.25 ioctl structure: */
+struct ax25_ctl_struct
+ {
+ ax25_address port_addr;
+ ax25_address source_addr;
+ ax25_address dest_addr;
+ unsigned int cmd;
+ unsigned long arg;
+ unsigned char digi_count;
+ ax25_address digi_addr[AX25_MAX_DIGIS];
+ };
+
+struct ax25_info_struct
+ {
+ unsigned int n2, n2count;
+ unsigned int t1, t1timer;
+ unsigned int t2, t2timer;
+ unsigned int t3, t3timer;
+ unsigned int idle, idletimer;
+ unsigned int state;
+ unsigned int rcv_q, snd_q;
+ };
+
+struct ax25_fwd_struct
+ {
+ ax25_address port_from;
+ ax25_address port_to;
+ };
+
+/* AX.25 route structure: */
+struct ax25_route_opt_struct
+ {
+ ax25_address port_addr;
+ ax25_address dest_addr;
+ int cmd;
+ int arg;
+ };
+
+/* AX.25 BPQ stuff: */
+struct ax25_bpqaddr_struct
+ {
+ char dev[16];
+ ax25_address addr;
+ };
+
+/* Definitions for the AX.25 `values' fields: */
+#define AX25_VALUES_IPDEFMODE 0 /* 'D'=DG 'V'=VC */
+#define AX25_VALUES_AXDEFMODE 1 /* 8=Normal 128=Extended Seq Nos */
+#define AX25_VALUES_NETROM 2 /* Allow NET/ROM - 0=No 1=Yes */
+#define AX25_VALUES_TEXT 3 /* Allow PID=Text - 0=No 1=Yes */
+#define AX25_VALUES_BACKOFF 4 /* 'E'=Exponential 'L'=Linear */
+#define AX25_VALUES_CONMODE 5 /* Allow connected modes - 0=No 1=Yes */
+#define AX25_VALUES_WINDOW 6 /* Default window size for standard AX.25 */
+#define AX25_VALUES_EWINDOW 7 /* Default window size for extended AX.25 */
+#define AX25_VALUES_T1 8 /* Default T1 timeout value */
+#define AX25_VALUES_T2 9 /* Default T2 timeout value */
+#define AX25_VALUES_T3 10 /* Default T3 timeout value */
+#define AX25_VALUES_N2 11 /* Default N2 value */
+#define AX25_VALUES_DIGI 12 /* Digipeat mode */
+#define AX25_VALUES_IDLE 13 /* mode vc idle timer */
+#define AX25_VALUES_PACLEN 14 /* AX.25 MTU */
+#define AX25_VALUES_IPMAXQUEUE 15 /* Maximum number of buffers enqueued */
+#define AX25_MAX_VALUES 20
+
+struct ax25_parms_struct
+ {
+ ax25_address port_addr;
+ unsigned short values[AX25_MAX_VALUES];
+ };
+
+#endif /* netax25/ax25.h */
diff --git a/libc/sysdeps/unix/sysv/linux/neteconet/ec.h b/libc/sysdeps/unix/sysv/linux/neteconet/ec.h
new file mode 100644
index 000000000..f21601ca0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/neteconet/ec.h
@@ -0,0 +1,52 @@
+/* Definitions for use with Linux AF_ECONET sockets.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NETECONET_EC_H
+#define _NETECONET_EC_H 1
+
+#include <features.h>
+#include <bits/sockaddr.h>
+
+struct ec_addr
+ {
+ unsigned char station; /* Station number. */
+ unsigned char net; /* Network number. */
+ };
+
+struct sockaddr_ec
+ {
+ __SOCKADDR_COMMON (sec_);
+ unsigned char port; /* Port number. */
+ unsigned char cb; /* Control/flag byte. */
+ unsigned char type; /* Type of message. */
+ struct ec_addr addr;
+ unsigned long cookie;
+ };
+
+#define ECTYPE_PACKET_RECEIVED 0 /* Packet received */
+#define ECTYPE_TRANSMIT_STATUS 0x10 /* Transmit completed */
+
+#define ECTYPE_TRANSMIT_OK 1
+#define ECTYPE_TRANSMIT_NOT_LISTENING 2
+#define ECTYPE_TRANSMIT_NET_ERROR 3
+#define ECTYPE_TRANSMIT_NO_CLOCK 4
+#define ECTYPE_TRANSMIT_LINE_JAMMED 5
+#define ECTYPE_TRANSMIT_NOT_PRESENT 6
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/netinet/if_ether.h b/libc/sysdeps/unix/sysv/linux/netinet/if_ether.h
new file mode 100644
index 000000000..aadb59bea
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/netinet/if_ether.h
@@ -0,0 +1,105 @@
+/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __NETINET_IF_ETHER_H
+
+#define __NETINET_IF_ETHER_H 1
+#include <features.h>
+#include <sys/types.h>
+
+/* Get definitions from kernel header file. */
+#include <linux/if_ether.h>
+
+#ifdef __USE_BSD
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)if_ether.h 8.3 (Berkeley) 5/2/95
+ * $FreeBSD$
+ */
+
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+
+__BEGIN_DECLS
+/*
+ * Ethernet Address Resolution Protocol.
+ *
+ * See RFC 826 for protocol description. Structure below is adapted
+ * to resolving internet addresses. Field names used correspond to
+ * RFC 826.
+ */
+struct ether_arp {
+ struct arphdr ea_hdr; /* fixed-size header */
+ u_int8_t arp_sha[ETH_ALEN]; /* sender hardware address */
+ u_int8_t arp_spa[4]; /* sender protocol address */
+ u_int8_t arp_tha[ETH_ALEN]; /* target hardware address */
+ u_int8_t arp_tpa[4]; /* target protocol address */
+};
+#define arp_hrd ea_hdr.ar_hrd
+#define arp_pro ea_hdr.ar_pro
+#define arp_hln ea_hdr.ar_hln
+#define arp_pln ea_hdr.ar_pln
+#define arp_op ea_hdr.ar_op
+
+/*
+ * Macro to map an IP multicast address to an Ethernet multicast address.
+ * The high-order 25 bits of the Ethernet address are statically assigned,
+ * and the low-order 23 bits are taken from the low end of the IP address.
+ */
+#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
+ /* struct in_addr *ipaddr; */ \
+ /* u_char enaddr[ETH_ALEN]; */ \
+{ \
+ (enaddr)[0] = 0x01; \
+ (enaddr)[1] = 0x00; \
+ (enaddr)[2] = 0x5e; \
+ (enaddr)[3] = ((u_int8_t *)ipaddr)[1] & 0x7f; \
+ (enaddr)[4] = ((u_int8_t *)ipaddr)[2]; \
+ (enaddr)[5] = ((u_int8_t *)ipaddr)[3]; \
+}
+
+__END_DECLS
+#endif /* __USE_BSD */
+
+#endif /* netinet/if_ether.h */
diff --git a/libc/sysdeps/unix/sysv/linux/netinet/if_fddi.h b/libc/sysdeps/unix/sysv/linux/netinet/if_fddi.h
new file mode 100644
index 000000000..1a0ec927d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/netinet/if_fddi.h
@@ -0,0 +1,37 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NETINET_IF_FDDI_H
+#define _NETINET_IF_FDDI_H 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <asm/types.h>
+
+#include <linux/if_fddi.h>
+
+#ifdef __USE_BSD
+
+struct fddi_header {
+ u_int8_t fddi_fc; /* Frame Control (FC) value */
+ u_int8_t fddi_dhost[FDDI_K_ALEN]; /* Destination host */
+ u_int8_t fddi_shost[FDDI_K_ALEN]; /* Source host */
+};
+#endif
+
+#endif /* netinet/if_fddi.h */
diff --git a/libc/sysdeps/unix/sysv/linux/netinet/if_tr.h b/libc/sysdeps/unix/sysv/linux/netinet/if_tr.h
new file mode 100644
index 000000000..45c39115f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/netinet/if_tr.h
@@ -0,0 +1,111 @@
+/* Copyright (C) 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NETINET_IF_TR_H
+#define _NETINET_IF_TR_H 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+/* IEEE 802.5 Token-Ring magic constants. The frame sizes omit the preamble
+ and FCS/CRC (frame check sequence). */
+#define TR_ALEN 6 /* Octets in one token-ring addr */
+#define TR_HLEN (sizeof (struct trh_hdr) + sizeof (struct trllc))
+#define AC 0x10
+#define LLC_FRAME 0x40
+
+/* LLC and SNAP constants */
+#define EXTENDED_SAP 0xAA
+#define UI_CMD 0x03
+
+/* This is an Token-Ring frame header. */
+struct trh_hdr
+{
+ u_int8_t ac; /* access control field */
+ u_int8_t fc; /* frame control field */
+ u_int8_t daddr[TR_ALEN]; /* destination address */
+ u_int8_t saddr[TR_ALEN]; /* source address */
+ u_int16_t rcf; /* route control field */
+ u_int16_t rseg[8]; /* routing registers */
+};
+
+/* This is an Token-Ring LLC structure */
+struct trllc
+{
+ u_int8_t dsap; /* destination SAP */
+ u_int8_t ssap; /* source SAP */
+ u_int8_t llc; /* LLC control field */
+ u_int8_t protid[3]; /* protocol id */
+ u_int16_t ethertype; /* ether type field */
+};
+
+/* Token-Ring statistics collection data. */
+struct tr_statistics
+{
+ unsigned long rx_packets; /* total packets received */
+ unsigned long tx_packets; /* total packets transmitted */
+ unsigned long rx_bytes; /* total bytes received */
+ unsigned long tx_bytes; /* total bytes transmitted */
+ unsigned long rx_errors; /* bad packets received */
+ unsigned long tx_errors; /* packet transmit problems */
+ unsigned long rx_dropped; /* no space in linux buffers */
+ unsigned long tx_dropped; /* no space available in linux */
+ unsigned long multicast; /* multicast packets received */
+ unsigned long transmit_collision;
+
+ /* detailed Token-Ring errors. See IBM Token-Ring Network
+ Architecture for more info */
+
+ unsigned long line_errors;
+ unsigned long internal_errors;
+ unsigned long burst_errors;
+ unsigned long A_C_errors;
+ unsigned long abort_delimiters;
+ unsigned long lost_frames;
+ unsigned long recv_congest_count;
+ unsigned long frame_copied_errors;
+ unsigned long frequency_errors;
+ unsigned long token_errors;
+ unsigned long dummy1;
+};
+
+/* source routing stuff */
+#define TR_RII 0x80
+#define TR_RCF_DIR_BIT 0x80
+#define TR_RCF_LEN_MASK 0x1f00
+#define TR_RCF_BROADCAST 0x8000 /* all-routes broadcast */
+#define TR_RCF_LIMITED_BROADCAST 0xC000 /* single-route broadcast */
+#define TR_RCF_FRAME2K 0x20
+#define TR_RCF_BROADCAST_MASK 0xC000
+#define TR_MAXRIFLEN 18
+
+#ifdef __USE_BSD
+
+struct trn_hdr
+{
+ u_int8_t trn_ac; /* access control field */
+ u_int8_t trn_fc; /* field control field */
+ u_int8_t trn_dhost[TR_ALEN]; /* destination host */
+ u_int8_t trn_shost[TR_ALEN]; /* source host */
+ u_int16_t trn_rcf; /* route control field */
+ u_int16_t trn_rseg[8]; /* routing registers */
+};
+
+#endif
+
+#endif /* netinet/if_tr.h */
diff --git a/libc/sysdeps/unix/sysv/linux/netipx/ipx.h b/libc/sysdeps/unix/sysv/linux/netipx/ipx.h
new file mode 100644
index 000000000..7eb42ef55
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/netipx/ipx.h
@@ -0,0 +1,113 @@
+/* Copyright (C) 1991, 92, 93, 95, 96, 97, 98 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __NETIPX_IPX_H
+#define __NETIPX_IPX_H 1
+
+#include <features.h>
+
+#include <sys/types.h>
+#include <bits/sockaddr.h>
+
+__BEGIN_DECLS
+
+#define SOL_IPX 256 /* sockopt level */
+
+#define IPX_TYPE 1
+#define IPX_NODE_LEN 6
+#define IPX_MTU 576
+
+struct sockaddr_ipx
+ {
+ sa_family_t sipx_family;
+ u_int16_t sipx_port;
+ u_int32_t sipx_network;
+ unsigned char sipx_node[IPX_NODE_LEN];
+ u_int8_t sipx_type;
+ unsigned char sipx_zero; /* 16 byte fill */
+ };
+
+/*
+ * So we can fit the extra info for SIOCSIFADDR into the address nicely
+ */
+
+#define sipx_special sipx_port
+#define sipx_action sipx_zero
+#define IPX_DLTITF 0
+#define IPX_CRTITF 1
+
+typedef struct ipx_route_definition
+ {
+ unsigned long ipx_network;
+ unsigned long ipx_router_network;
+ unsigned char ipx_router_node[IPX_NODE_LEN];
+ }
+ipx_route_definition;
+
+typedef struct ipx_interface_definition
+ {
+ unsigned long ipx_network;
+ unsigned char ipx_device[16];
+ unsigned char ipx_dlink_type;
+#define IPX_FRAME_NONE 0
+#define IPX_FRAME_SNAP 1
+#define IPX_FRAME_8022 2
+#define IPX_FRAME_ETHERII 3
+#define IPX_FRAME_8023 4
+#define IPX_FRAME_TR_8022 5
+ unsigned char ipx_special;
+#define IPX_SPECIAL_NONE 0
+#define IPX_PRIMARY 1
+#define IPX_INTERNAL 2
+ unsigned char ipx_node[IPX_NODE_LEN];
+ }
+ipx_interface_definition;
+
+typedef struct ipx_config_data
+ {
+ unsigned char ipxcfg_auto_select_primary;
+ unsigned char ipxcfg_auto_create_interfaces;
+ }
+ipx_config_data;
+
+/*
+ * OLD Route Definition for backward compatibility.
+ */
+
+struct ipx_route_def
+ {
+ unsigned long ipx_network;
+ unsigned long ipx_router_network;
+#define IPX_ROUTE_NO_ROUTER 0
+ unsigned char ipx_router_node[IPX_NODE_LEN];
+ unsigned char ipx_device[16];
+ unsigned short ipx_flags;
+#define IPX_RT_SNAP 8
+#define IPX_RT_8022 4
+#define IPX_RT_BLUEBOOK 2
+#define IPX_RT_ROUTED 1
+ };
+
+#define SIOCAIPXITFCRT (SIOCPROTOPRIVATE)
+#define SIOCAIPXPRISLT (SIOCPROTOPRIVATE + 1)
+#define SIOCIPXCFGDATA (SIOCPROTOPRIVATE + 2)
+#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE + 3)
+
+__END_DECLS
+
+#endif /* netipx/ipx.h */
diff --git a/libc/sysdeps/unix/sysv/linux/netlinkaccess.h b/libc/sysdeps/unix/sysv/linux/netlinkaccess.h
new file mode 100644
index 000000000..92310b77d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/netlinkaccess.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NETLINKACCESS_H
+#define _NETLINKACCESS_H 1
+
+#include <asm/types.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <kernel-features.h>
+
+
+struct netlink_res
+{
+ struct netlink_res *next;
+ struct nlmsghdr *nlh;
+ size_t size; /* Size of response. */
+ uint32_t seq; /* sequential number we used. */
+};
+
+
+struct netlink_handle
+{
+ int fd; /* Netlink file descriptor. */
+ pid_t pid; /* Process ID. */
+ uint32_t seq; /* The sequence number we use currently. */
+ struct netlink_res *nlm_list; /* Pointer to list of responses. */
+ struct netlink_res *end_ptr; /* For faster append of new entries. */
+};
+
+
+#if __ASSUME_NETLINK_SUPPORT == 0
+extern int __no_netlink_support attribute_hidden;
+#else
+# define __no_netlink_support 0
+#endif
+
+
+extern int __netlink_open (struct netlink_handle *h);
+extern void __netlink_close (struct netlink_handle *h);
+extern void __netlink_free_handle (struct netlink_handle *h);
+extern int __netlink_request (struct netlink_handle *h, int type);
+
+
+#endif /* netlinkaccess.h */
diff --git a/libc/sysdeps/unix/sysv/linux/netpacket/packet.h b/libc/sysdeps/unix/sysv/linux/netpacket/packet.h
new file mode 100644
index 000000000..6c634282f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/netpacket/packet.h
@@ -0,0 +1,64 @@
+/* Definitions for use with Linux AF_PACKET sockets.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __NETPACKET_PACKET_H
+#define __NETPACKET_PACKET_H 1
+
+struct sockaddr_ll
+ {
+ unsigned short int sll_family;
+ unsigned short int sll_protocol;
+ int sll_ifindex;
+ unsigned short int sll_hatype;
+ unsigned char sll_pkttype;
+ unsigned char sll_halen;
+ unsigned char sll_addr[8];
+ };
+
+/* Packet types. */
+
+#define PACKET_HOST 0 /* To us. */
+#define PACKET_BROADCAST 1 /* To all. */
+#define PACKET_MULTICAST 2 /* To group. */
+#define PACKET_OTHERHOST 3 /* To someone else. */
+#define PACKET_OUTGOING 4 /* Originated by us . */
+#define PACKET_LOOPBACK 5
+#define PACKET_FASTROUTE 6
+
+/* Packet socket options. */
+
+#define PACKET_ADD_MEMBERSHIP 1
+#define PACKET_DROP_MEMBERSHIP 2
+#define PACKET_RECV_OUTPUT 3
+#define PACKET_RX_RING 5
+#define PACKET_STATISTICS 6
+
+struct packet_mreq
+ {
+ int mr_ifindex;
+ unsigned short int mr_type;
+ unsigned short int mr_alen;
+ unsigned char mr_address[8];
+ };
+
+#define PACKET_MR_MULTICAST 0
+#define PACKET_MR_PROMISC 1
+#define PACKET_MR_ALLMULTI 2
+
+#endif /* netpacket/packet.h */
diff --git a/libc/sysdeps/unix/sysv/linux/netrom/netrom.h b/libc/sysdeps/unix/sysv/linux/netrom/netrom.h
new file mode 100644
index 000000000..4984772ad
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/netrom/netrom.h
@@ -0,0 +1,84 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _NETROM_NETROM_H
+#define _NETROM_NETROM_H 1
+
+#include <netax25/ax25.h>
+
+/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx. */
+#define SOL_NETROM 259
+
+/* NetRom control values: */
+#define NETROM_T1 1
+#define NETROM_T2 2
+#define NETROM_N2 3
+#define NETROM_PACLEN 5
+#define NETROM_T4 6
+#define NETROM_IDLE 7
+
+#define NETROM_KILL 99
+
+/* Type of route: */
+#define NETROM_NEIGH 0
+#define NETROM_NODE 1
+
+struct nr_route_struct
+ {
+ int type;
+ ax25_address callsign;
+ char device[16];
+ unsigned int quality;
+ char mnemonic[7];
+ ax25_address neighbour;
+ unsigned int obs_count;
+ unsigned int ndigis;
+ ax25_address digipeaters[AX25_MAX_DIGIS];
+ };
+
+/* NetRom socket ioctls: */
+#define SIOCNRGETPARMS (SIOCPROTOPRIVATE+0)
+#define SIOCNRSETPARMS (SIOCPROTOPRIVATE+1)
+#define SIOCNRDECOBS (SIOCPROTOPRIVATE+2)
+#define SIOCNRRTCTL (SIOCPROTOPRIVATE+3)
+#define SIOCNRCTLCON (SIOCPROTOPRIVATE+4)
+
+/* NetRom parameter structure: */
+struct nr_parms_struct
+ {
+ unsigned int quality;
+ unsigned int obs_count;
+ unsigned int ttl;
+ unsigned int timeout;
+ unsigned int ack_delay;
+ unsigned int busy_delay;
+ unsigned int tries;
+ unsigned int window;
+ unsigned int paclen;
+ };
+
+/* NetRom control structure: */
+struct nr_ctl_struct
+ {
+ unsigned char index;
+ unsigned char id;
+ unsigned int cmd;
+ unsigned long arg;
+ };
+
+#endif /* netrom/netrom.h */
diff --git a/libc/sysdeps/unix/sysv/linux/netrose/rose.h b/libc/sysdeps/unix/sysv/linux/netrose/rose.h
new file mode 100644
index 000000000..e4ba7d701
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/netrose/rose.h
@@ -0,0 +1,116 @@
+/* Definitions for Rose packet radio address family.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* What follows is copied from the 2.1.93 <linux/rose.h>. */
+
+#ifndef _NETROSE_ROSE_H
+#define _NETROSE_ROSE_H 1
+
+/* Socket level values. */
+#define SOL_ROSE 260
+
+
+/* These are the public elements of the Linux kernel Rose
+ implementation. For kernel AX.25 see the file ax25.h. This file
+ requires ax25.h for the definition of the ax25_address structure. */
+#define ROSE_MTU 251
+
+#define ROSE_MAX_DIGIS 6
+
+#define ROSE_DEFER 1
+#define ROSE_T1 2
+#define ROSE_T2 3
+#define ROSE_T3 4
+#define ROSE_IDLE 5
+#define ROSE_QBITINCL 6
+#define ROSE_HOLDBACK 7
+
+#define SIOCRSGCAUSE (SIOCPROTOPRIVATE + 0)
+#define SIOCRSSCAUSE (SIOCPROTOPRIVATE + 1)
+#define SIOCRSL2CALL (SIOCPROTOPRIVATE + 2)
+#define SIOCRSSL2CALL (SIOCPROTOPRIVATE + 2)
+#define SIOCRSACCEPT (SIOCPROTOPRIVATE + 3)
+#define SIOCRSCLRRT (SIOCPROTOPRIVATE + 4)
+#define SIOCRSGL2CALL (SIOCPROTOPRIVATE + 5)
+#define SIOCRSGFACILITIES (SIOCPROTOPRIVATE + 6)
+
+#define ROSE_DTE_ORIGINATED 0x00
+#define ROSE_NUMBER_BUSY 0x01
+#define ROSE_INVALID_FACILITY 0x03
+#define ROSE_NETWORK_CONGESTION 0x05
+#define ROSE_OUT_OF_ORDER 0x09
+#define ROSE_ACCESS_BARRED 0x0B
+#define ROSE_NOT_OBTAINABLE 0x0D
+#define ROSE_REMOTE_PROCEDURE 0x11
+#define ROSE_LOCAL_PROCEDURE 0x13
+#define ROSE_SHIP_ABSENT 0x39
+
+
+typedef struct
+{
+ char rose_addr[5];
+} rose_address;
+
+struct sockaddr_rose
+{
+ sa_family_t srose_family;
+ rose_address srose_addr;
+ ax25_address srose_call;
+ int srose_ndigis;
+ ax25_address srose_digi;
+};
+
+struct full_sockaddr_rose
+{
+ sa_family_t srose_family;
+ rose_address srose_addr;
+ ax25_address srose_call;
+ unsigned int srose_ndigis;
+ ax25_address srose_digis[ROSE_MAX_DIGIS];
+};
+
+struct rose_route_struct
+{
+ rose_address address;
+ unsigned short int mask;
+ ax25_address neighbour;
+ char device[16];
+ unsigned char ndigis;
+ ax25_address digipeaters[AX25_MAX_DIGIS];
+};
+
+struct rose_cause_struct
+{
+ unsigned char cause;
+ unsigned char diagnostic;
+};
+
+struct rose_facilities_struct
+{
+ rose_address source_addr, dest_addr;
+ ax25_address source_call, dest_call;
+ unsigned char source_ndigis, dest_ndigis;
+ ax25_address source_digis[ROSE_MAX_DIGIS];
+ ax25_address dest_digis[ROSE_MAX_DIGIS];
+ unsigned int rand;
+ rose_address fail_addr;
+ ax25_address fail_call;
+};
+
+#endif /* netrose/rose.h */
diff --git a/libc/sysdeps/unix/sysv/linux/nfs/nfs.h b/libc/sysdeps/unix/sysv/linux/nfs/nfs.h
new file mode 100644
index 000000000..61e4b656d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/nfs/nfs.h
@@ -0,0 +1 @@
+#include <linux/nfs.h>
diff --git a/libc/sysdeps/unix/sysv/linux/nice.c b/libc/sysdeps/unix/sysv/linux/nice.c
new file mode 100644
index 000000000..46a6da80c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/nice.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/nice.c>
diff --git a/libc/sysdeps/unix/sysv/linux/not-cancel.h b/libc/sysdeps/unix/sysv/linux/not-cancel.h
new file mode 100644
index 000000000..80d33be29
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/not-cancel.h
@@ -0,0 +1,105 @@
+/* Uncancelable versions of cancelable interfaces. Linux version.
+ Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <sysdep.h>
+
+/* Uncancelable open. */
+#define open_not_cancel(name, flags, mode) \
+ INLINE_SYSCALL (open, 3, (const char *) (name), (flags), (mode))
+#define open_not_cancel_2(name, flags) \
+ INLINE_SYSCALL (open, 2, (const char *) (name), (flags))
+
+/* Uncancelable openat. */
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+extern int __openat_nocancel (int fd, const char *fname, int oflag,
+ mode_t mode) attribute_hidden;
+extern int __openat64_nocancel (int fd, const char *fname, int oflag,
+ mode_t mode) attribute_hidden;
+#else
+# define __openat_nocancel(fd, fname, oflag, mode) \
+ openat (fd, fname, oflag, mode)
+# define __openat64_nocancel(fd, fname, oflag, mode) \
+ openat64 (fd, fname, oflag, mode)
+#endif
+
+#define openat_not_cancel(fd, fname, oflag, mode) \
+ __openat_nocancel (fd, fname, oflag, mode)
+#define openat_not_cancel_3(fd, fname, oflag) \
+ __openat_nocancel (fd, fname, oflag, 0)
+#define openat64_not_cancel(fd, fname, oflag, mode) \
+ __openat64_nocancel (fd, fname, oflag, mode)
+#define openat64_not_cancel_3(fd, fname, oflag) \
+ __openat64_nocancel (fd, fname, oflag, 0)
+
+/* Uncancelable close. */
+#define close_not_cancel(fd) \
+ INLINE_SYSCALL (close, 1, fd)
+#define close_not_cancel_no_status(fd) \
+ (void) ({ INTERNAL_SYSCALL_DECL (err); \
+ INTERNAL_SYSCALL (close, err, 1, (fd)); })
+
+/* Uncancelable read. */
+#define read_not_cancel(fd, buf, n) \
+ INLINE_SYSCALL (read, 3, (fd), (buf), (n))
+
+/* Uncancelable write. */
+#define write_not_cancel(fd, buf, n) \
+ INLINE_SYSCALL (write, 3, (fd), (buf), (n))
+
+/* Uncancelable writev. */
+#define writev_not_cancel_no_status(fd, iov, n) \
+ (void) ({ INTERNAL_SYSCALL_DECL (err); \
+ INTERNAL_SYSCALL (writev, err, 3, (fd), (iov), (n)); })
+
+/* Uncancelable fcntl. */
+#define fcntl_not_cancel(fd, cmd, val) \
+ __fcntl_nocancel (fd, cmd, val)
+
+/* Uncancelable waitpid. */
+#ifdef __NR_waitpid
+# define waitpid_not_cancel(pid, stat_loc, options) \
+ INLINE_SYSCALL (waitpid, 3, pid, stat_loc, options)
+#else
+# define waitpid_not_cancel(pid, stat_loc, options) \
+ INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL)
+#endif
+
+/* Uncancelable pause. */
+#ifdef __NR_pause
+# define pause_not_cancel() \
+ INLINE_SYSCALL (pause, 0)
+#else
+# define pause_not_cancel() \
+ __pause_nocancel ()
+#endif
+
+/* Uncancelable nanosleep. */
+#ifdef __NR_nanosleep
+# define nanosleep_not_cancel(requested_time, remaining) \
+ INLINE_SYSCALL (nanosleep, 2, requested_time, remaining)
+#else
+# define nanosleep_not_cancel(requested_time, remaining) \
+ __nanosleep_nocancel (requested_time, remaining)
+#endif
+
+/* Uncancelable sigsuspend. */
+#define sigsuspend_not_cancel(set) \
+ __sigsuspend_nocancel (set)
diff --git a/libc/sysdeps/unix/sysv/linux/nscd_setup_thread.c b/libc/sysdeps/unix/sysv/linux/nscd_setup_thread.c
new file mode 100644
index 000000000..1589c24ea
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/nscd_setup_thread.c
@@ -0,0 +1,47 @@
+/* Setup of nscd worker threads. Linux verison.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2 as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <unistd.h>
+#include <nscd.h>
+#include <sysdep.h>
+
+
+void
+setup_thread (struct database_dyn *db)
+{
+#ifdef __NR_set_tid_address
+ /* Only supported when NPTL is used. */
+ char buf[100];
+ if (confstr (_CS_GNU_LIBPTHREAD_VERSION, buf, sizeof (buf)) >= sizeof (buf)
+ || strncmp (buf, "NPTL", 4) != 0)
+ return;
+
+ /* Do not try this at home, kids. We play with the SETTID address
+ even thought the process is multi-threaded. This can only work
+ since none of the threads ever terminates. */
+ INTERNAL_SYSCALL_DECL (err);
+ int r = INTERNAL_SYSCALL (set_tid_address, err, 1,
+ &db->head->nscd_certainly_running);
+ if (!INTERNAL_SYSCALL_ERROR_P (r, err))
+ /* We know the kernel can reset this field when nscd terminates.
+ So, set the field to a nonzero value which indicates that nscd
+ is certainly running and clients can skip the test. */
+ db->head->nscd_certainly_running = 1;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/ntp_gettime.c b/libc/sysdeps/unix/sysv/linux/ntp_gettime.c
new file mode 100644
index 000000000..f78f1682f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ntp_gettime.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/timex.h>
+
+#ifndef MOD_OFFSET
+# define modes mode
+#endif
+
+
+extern int INTUSE(__adjtimex) (struct timex *__ntx);
+
+
+int
+ntp_gettime (ntv)
+ struct ntptimeval *ntv;
+{
+ struct timex tntx;
+ int result;
+
+ tntx.modes = 0;
+ result = INTUSE(__adjtimex) (&tntx);
+ ntv->time = tntx.time;
+ ntv->maxerror = tntx.maxerror;
+ ntv->esterror = tntx.esterror;
+ return result;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/open64.c b/libc/sysdeps/unix/sysv/linux/open64.c
new file mode 100644
index 000000000..5fb5363e1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/open64.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1991,1995-1997,1999,2000,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <bp-sym.h>
+#include <sysdep-cancel.h>
+
+/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
+ a third argument is the file protection. */
+int
+__libc_open64 (const char *file, int oflag, ...)
+{
+ int mode = 0;
+
+ if (oflag & O_CREAT)
+ {
+ va_list arg;
+ va_start (arg, oflag);
+ mode = va_arg (arg, int);
+ va_end (arg);
+ }
+
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (open, 3, file, oflag | O_LARGEFILE, mode);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (open, 3, file, oflag | O_LARGEFILE, mode);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+weak_alias (__libc_open64, BP_SYM (__open64))
+libc_hidden_weak (BP_SYM (__open64))
+weak_alias (__libc_open64, BP_SYM (open64))
diff --git a/libc/sysdeps/unix/sysv/linux/openat.c b/libc/sysdeps/unix/sysv/linux/openat.c
new file mode 100644
index 000000000..7dfe36742
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/openat.c
@@ -0,0 +1,173 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <kernel-features.h>
+#include <sysdep-cancel.h>
+#include <not-cancel.h>
+
+
+#if !defined OPENAT && !defined __ASSUME_ATFCTS
+# define OPENAT openat
+
+/* Set errno after a failed call. If BUF is not null,
+ it is a /proc/self/fd/ path name we just tried to use. */
+void
+attribute_hidden
+__atfct_seterrno (int errval, int fd, const char *buf)
+{
+ if (buf != NULL)
+ {
+ struct stat64 st;
+
+ if (errval == ENOTDIR || errval == ENOENT)
+ {
+ /* This can mean either the file descriptor is invalid or
+ /proc is not mounted. */
+ if (__fxstat64 (_STAT_VER, fd, &st) != 0)
+ /* errno is already set correctly. */
+ return;
+
+ /* If /proc is not mounted there is nothing we can do. */
+ if ((errval != ENOTDIR || S_ISDIR (st.st_mode))
+ && (__xstat64 (_STAT_VER, "/proc/self/fd", &st) != 0
+ || !S_ISDIR (st.st_mode)))
+ errval = ENOSYS;
+ }
+ }
+
+ __set_errno (errval);
+}
+
+int __have_atfcts;
+#endif
+
+
+#define OPENAT_NOT_CANCEL CONCAT (OPENAT)
+#define CONCAT(name) CONCAT2 (name)
+#define CONCAT2(name) __##name##_nocancel
+
+
+int
+OPENAT_NOT_CANCEL (fd, file, oflag, mode)
+ int fd;
+ const char *file;
+ int oflag;
+ mode_t mode;
+{
+
+ /* We have to add the O_LARGEFILE flag for openat64. */
+#ifdef MORE_OFLAGS
+ oflag |= MORE_OFLAGS;
+#endif
+
+ INTERNAL_SYSCALL_DECL (err);
+ int res;
+
+#ifdef __NR_openat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ res = INLINE_SYSCALL (openat, 4, fd, file, oflag, mode);
+
+# ifndef __ASSUME_ATFCTS
+ if (res == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return res;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ /* Note: snprintf cannot be canceled. */
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ res = INTERNAL_SYSCALL (open, err, 3, file, oflag, mode);
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
+ {
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (res, err), fd, buf);
+ res = -1;
+ }
+
+ return res;
+#endif
+}
+
+#define UNDERIZE(name) UNDERIZE_1 (name)
+#define UNDERIZE_1(name) __##name
+#define __OPENAT UNDERIZE (OPENAT)
+
+
+/* Open FILE with access OFLAG. Interpret relative paths relative to
+ the directory associated with FD. If OFLAG includes O_CREAT, a
+ third argument is the file protection. */
+int
+__OPENAT (fd, file, oflag)
+ int fd;
+ const char *file;
+ int oflag;
+{
+ mode_t mode = 0;
+ if (oflag & O_CREAT)
+ {
+ va_list arg;
+ va_start (arg, oflag);
+ mode = va_arg (arg, mode_t);
+ va_end (arg);
+ }
+
+ if (SINGLE_THREAD_P)
+ return OPENAT_NOT_CANCEL (fd, file, oflag, mode);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int res = OPENAT_NOT_CANCEL (fd, file, oflag, mode);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return res;
+}
+libc_hidden_def (__OPENAT)
+weak_alias (__OPENAT, OPENAT)
diff --git a/libc/sysdeps/unix/sysv/linux/openat64.c b/libc/sysdeps/unix/sysv/linux/openat64.c
new file mode 100644
index 000000000..9e7a2b373
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/openat64.c
@@ -0,0 +1,4 @@
+#define OPENAT openat64
+#define MORE_OFLAGS O_LARGEFILE
+
+#include "openat.c"
diff --git a/libc/sysdeps/unix/sysv/linux/opendir.c b/libc/sysdeps/unix/sysv/linux/opendir.c
new file mode 100644
index 000000000..c7671dc17
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/opendir.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <kernel-features.h>
+
+
+#ifdef __ASSUME_O_DIRECTORY
+# define O_DIRECTORY_WORKS 1
+#endif
+
+#include <sysdeps/unix/opendir.c>
diff --git a/libc/sysdeps/unix/sysv/linux/opensock.c b/libc/sysdeps/unix/sysv/linux/opensock.c
new file mode 100644
index 000000000..225298078
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/opensock.c
@@ -0,0 +1,119 @@
+/* Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+/* Return a socket of any type. The socket can be used in subsequent
+ ioctl calls to talk to the kernel. */
+int internal_function
+__opensock (void)
+{
+ static int last_family; /* Available socket family we will use. */
+ static int last_type;
+ static const struct
+ {
+ int family;
+ const char procname[15];
+ } afs[] =
+ {
+ /* The 2.2 kernels cannot handle ioctl(SIOCGIFCONF) on AF_UNIX sockets.
+ Give the kernel a chance to user inet sockets on old kernels. */
+#if __LINUX_KERNEL_VERSION < 132096
+ { AF_INET, "" },
+ { AF_UNIX, "net/unix" },
+#else
+ { AF_UNIX, "net/unix" },
+ { AF_INET, "" },
+#endif
+ { AF_INET6, "net/if_inet6" },
+ { AF_AX25, "net/ax25" },
+ { AF_NETROM, "net/nr" },
+ { AF_ROSE, "net/rose" },
+ { AF_IPX, "net/ipx" },
+ { AF_APPLETALK, "net/appletalk" },
+ { AF_ECONET, "sys/net/econet" },
+ { AF_ASH, "sys/net/ash" },
+ { AF_X25, "net/x25" }
+ };
+#define nafs (sizeof (afs) / sizeof (afs[0]))
+ char fname[sizeof "/proc/" + 14];
+ int result;
+ int has_proc;
+ size_t cnt;
+
+ /* We already know which family to use from the last call. Use it
+ again. */
+ if (last_family != 0)
+ {
+ assert (last_type != 0);
+
+ result = __socket (last_family, last_type, 0);
+ if (result != -1 || errno != EAFNOSUPPORT)
+ /* Maybe the socket type isn't supported anymore (module is
+ unloaded). In this case again try to find the type. */
+ return result;
+
+ /* Reset the values. They seem not valid anymore. */
+ last_family = 0;
+ last_type = 0;
+ }
+
+ /* Check whether the /proc filesystem is available. */
+ has_proc = __access ("/proc/net", R_OK) != -1;
+ strcpy (fname, "/proc/");
+
+ /* Iterate over the interface families and find one which is
+ available. */
+ for (cnt = 0; cnt < nafs; ++cnt)
+ {
+ int type = SOCK_DGRAM;
+
+ if (has_proc && afs[cnt].procname[0] != '\0')
+ {
+ strcpy (fname + 6, afs[cnt].procname);
+ if (__access (fname, R_OK) == -1)
+ /* The /proc entry is not available. I.e., we cannot
+ create a socket of this type (without loading the
+ module). Don't look for it since this might trigger
+ loading the module. */
+ continue;
+ }
+
+ if (afs[cnt].family == AF_NETROM || afs[cnt].family == AF_X25)
+ type = SOCK_SEQPACKET;
+
+ result = __socket (afs[cnt].family, type, 0);
+ if (result != -1)
+ {
+ /* Found an available family. */
+ last_type = type;
+ last_family = afs[cnt].family;
+ return result;
+ }
+ }
+
+ /* None of the protocol families is available. It is unclear what kind
+ of error is returned. ENOENT seems like a reasonable choice. */
+ __set_errno (ENOENT);
+ return -1;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/pathconf.c b/libc/sysdeps/unix/sysv/linux/pathconf.c
new file mode 100644
index 000000000..e12a08434
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/pathconf.c
@@ -0,0 +1,181 @@
+/* Get file-specific information about a file. Linux version.
+ Copyright (C) 1991,1995,1996,1998-2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <errno.h>
+#include "pathconf.h"
+#include "linux_fsinfo.h"
+
+static long int posix_pathconf (const char *file, int name);
+
+/* Define this first, so it can be inlined. */
+#define __pathconf static posix_pathconf
+#include <sysdeps/posix/pathconf.c>
+
+
+/* Get file-specific information about FILE. */
+long int
+__pathconf (const char *file, int name)
+{
+ struct statfs fsbuf;
+
+ switch (name)
+ {
+ case _PC_LINK_MAX:
+ return __statfs_link_max (__statfs (file, &fsbuf), &fsbuf);
+
+ case _PC_FILESIZEBITS:
+ return __statfs_filesize_max (__statfs (file, &fsbuf), &fsbuf);
+
+ case _PC_2_SYMLINKS:
+ return __statfs_symlinks (__statfs (file, &fsbuf), &fsbuf);
+
+ default:
+ return posix_pathconf (file, name);
+ }
+}
+
+
+/* Used like: return statfs_link_max (__statfs (name, &buf), &buf); */
+long int
+__statfs_link_max (int result, const struct statfs *fsbuf)
+{
+ if (result < 0)
+ {
+ if (errno == ENOSYS)
+ /* Not possible, return the default value. */
+ return LINUX_LINK_MAX;
+
+ /* Some error occured. */
+ return -1;
+ }
+
+ switch (fsbuf->f_type)
+ {
+ case EXT2_SUPER_MAGIC:
+ return EXT2_LINK_MAX;
+
+ case MINIX_SUPER_MAGIC:
+ case MINIX_SUPER_MAGIC2:
+ return MINIX_LINK_MAX;
+
+ case MINIX2_SUPER_MAGIC:
+ case MINIX2_SUPER_MAGIC2:
+ return MINIX2_LINK_MAX;
+
+ case XENIX_SUPER_MAGIC:
+ return XENIX_LINK_MAX;
+
+ case SYSV4_SUPER_MAGIC:
+ case SYSV2_SUPER_MAGIC:
+ return SYSV_LINK_MAX;
+
+ case COH_SUPER_MAGIC:
+ return COH_LINK_MAX;
+
+ case UFS_MAGIC:
+ case UFS_CIGAM:
+ return UFS_LINK_MAX;
+
+ case REISERFS_SUPER_MAGIC:
+ return REISERFS_LINK_MAX;
+
+ case XFS_SUPER_MAGIC:
+ return XFS_LINK_MAX;
+
+ default:
+ return LINUX_LINK_MAX;
+ }
+}
+
+
+/* Used like: return statfs_filesize_max (__statfs (name, &buf), &buf); */
+long int
+__statfs_filesize_max (int result, const struct statfs *fsbuf)
+{
+ if (result < 0)
+ {
+ if (errno == ENOSYS)
+ /* Not possible, return the default value. */
+ return 32;
+
+ /* Some error occured. */
+ return -1;
+ }
+
+ switch (fsbuf->f_type)
+ {
+ case EXT2_SUPER_MAGIC:
+ case UFS_MAGIC:
+ case UFS_CIGAM:
+ case REISERFS_SUPER_MAGIC:
+ case XFS_SUPER_MAGIC:
+ case SMB_SUPER_MAGIC:
+ case NTFS_SUPER_MAGIC:
+ case UDF_SUPER_MAGIC:
+ case JFS_SUPER_MAGIC:
+ case VXFS_SUPER_MAGIC:
+ return 64;
+
+ case MSDOS_SUPER_MAGIC:
+ case JFFS_SUPER_MAGIC:
+ case JFFS2_SUPER_MAGIC:
+ case NCP_SUPER_MAGIC:
+ case ROMFS_SUPER_MAGIC:
+ return 32;
+
+ default:
+ return 32;
+ }
+}
+
+
+/* Used like: return statfs_link_max (__statfs (name, &buf), &buf); */
+long int
+__statfs_symlinks (int result, const struct statfs *fsbuf)
+{
+ if (result < 0)
+ {
+ if (errno == ENOSYS)
+ /* Not possible, return the default value. */
+ return 1;
+
+ /* Some error occured. */
+ return -1;
+ }
+
+ switch (fsbuf->f_type)
+ {
+ case ADFS_SUPER_MAGIC:
+ case BFS_MAGIC:
+ case CRAMFS_MAGIC:
+ case DEVPTS_SUPER_MAGIC:
+ case EFS_SUPER_MAGIC:
+ case EFS_MAGIC:
+ case MSDOS_SUPER_MAGIC:
+ case NTFS_SUPER_MAGIC:
+ case QNX4_SUPER_MAGIC:
+ case ROMFS_SUPER_MAGIC:
+ /* No symlink support. */
+ return 0;
+
+ default:
+ return 1;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/pathconf.h b/libc/sysdeps/unix/sysv/linux/pathconf.h
new file mode 100644
index 000000000..20e23685e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/pathconf.h
@@ -0,0 +1,34 @@
+/* Common parts of Linux implementation of pathconf and fpathconf.
+ Copyright (C) 1991,1995,1996,1998-2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/statfs.h>
+
+
+/* Used like: return statfs_link_max (__statfs (name, &buf), &buf); */
+extern long int __statfs_link_max (int result, const struct statfs *fsbuf);
+
+
+/* Used like: return statfs_filesize_max (__statfs (name, &buf), &buf); */
+extern long int __statfs_filesize_max (int result, const struct statfs *fsbuf);
+
+
+/* Used like: return statfs_link_max (__statfs (name, &buf), &buf); */
+extern long int __statfs_symlinks (int result, const struct statfs *fsbuf);
diff --git a/libc/sysdeps/unix/sysv/linux/paths.h b/libc/sysdeps/unix/sysv/linux/paths.h
new file mode 100644
index 000000000..fb2c77e99
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/paths.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)paths.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _PATHS_H_
+#define _PATHS_H_
+
+/* Default search path. */
+#define _PATH_DEFPATH "/usr/bin:/bin"
+/* All standard utilities path. */
+#define _PATH_STDPATH \
+ "/usr/bin:/bin:/usr/sbin:/sbin"
+
+#define _PATH_BSHELL "/bin/sh"
+#define _PATH_CONSOLE "/dev/console"
+#define _PATH_CSHELL "/bin/csh"
+#define _PATH_DEVDB "/var/run/dev.db"
+#define _PATH_DEVNULL "/dev/null"
+#define _PATH_DRUM "/dev/drum"
+#define _PATH_KLOG "/proc/kmsg"
+#define _PATH_KMEM "/dev/kmem"
+#define _PATH_LASTLOG "/var/log/lastlog"
+#define _PATH_MAILDIR "/var/mail"
+#define _PATH_MAN "/usr/share/man"
+#define _PATH_MEM "/dev/mem"
+#define _PATH_MNTTAB "/etc/fstab"
+#define _PATH_MOUNTED "/etc/mtab"
+#define _PATH_NOLOGIN "/etc/nologin"
+#define _PATH_PRESERVE "/var/lib"
+#define _PATH_RWHODIR "/var/spool/rwho"
+#define _PATH_SENDMAIL "/usr/sbin/sendmail"
+#define _PATH_SHADOW "/etc/shadow"
+#define _PATH_SHELLS "/etc/shells"
+#define _PATH_TTY "/dev/tty"
+#define _PATH_UNIX "/boot/vmlinux"
+#define _PATH_UTMP "/var/run/utmp"
+#define _PATH_VI "/usr/bin/vi"
+#define _PATH_WTMP "/var/log/wtmp"
+
+/* Provide trailing slash, since mostly used for building pathnames. */
+#define _PATH_DEV "/dev/"
+#define _PATH_TMP "/tmp/"
+#define _PATH_VARDB "/var/db/"
+#define _PATH_VARRUN "/var/run/"
+#define _PATH_VARTMP "/var/tmp/"
+
+#endif /* !_PATHS_H_ */
diff --git a/libc/sysdeps/unix/sysv/linux/poll.c b/libc/sysdeps/unix/sysv/linux/poll.c
new file mode 100644
index 000000000..a745fbcbc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/poll.c
@@ -0,0 +1,105 @@
+/* Poll system call, with emulation if it is not available.
+ Copyright (C) 1997,1998,1999,2000,2001,2002,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/poll.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_poll || __ASSUME_POLL_SYSCALL > 0
+
+# if __ASSUME_POLL_SYSCALL == 0
+static int __emulate_poll (struct pollfd *fds, nfds_t nfds,
+ int timeout) internal_function;
+# endif
+
+
+# if __ASSUME_POLL_SYSCALL == 0
+/* For loser kernels. */
+static int
+loser_poll (struct pollfd *fds, nfds_t nfds, int timeout)
+{
+ static int must_emulate;
+
+ if (!must_emulate)
+ {
+ int errno_saved = errno;
+ int retval = INLINE_SYSCALL (poll, 3, CHECK_N (fds, nfds), nfds,
+ timeout);
+
+ if (retval >= 0 || errno != ENOSYS)
+ return retval;
+
+ __set_errno (errno_saved);
+ must_emulate = 1;
+ }
+
+ return __emulate_poll (fds, nfds, timeout);
+}
+# endif
+
+
+/* The real implementation. */
+int
+__poll (fds, nfds, timeout)
+ struct pollfd *fds;
+ nfds_t nfds;
+ int timeout;
+{
+# if __ASSUME_POLL_SYSCALL == 0
+ if (SINGLE_THREAD_P)
+ return loser_poll (CHECK_N (fds, nfds), nfds, timeout);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = loser_poll (CHECK_N (fds, nfds), nfds, timeout);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+# else
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (poll, 3, CHECK_N (fds, nfds), nfds, timeout);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (poll, 3, CHECK_N (fds, nfds), nfds, timeout);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+# endif
+}
+libc_hidden_def (__poll)
+weak_alias (__poll, poll)
+strong_alias (__poll, __libc_poll)
+
+/* Get the emulation code. */
+# define __poll(fds, nfds, timeout) \
+ static internal_function __emulate_poll (fds, nfds, timeout)
+#endif
+
+#if __ASSUME_POLL_SYSCALL == 0
+# include <sysdeps/unix/bsd/poll.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/posix_fadvise.c b/libc/sysdeps/unix/sysv/linux/posix_fadvise.c
new file mode 100644
index 000000000..30a6d9e5b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/posix_fadvise.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sysdep.h>
+
+/* Advice the system about the expected behaviour of the application with
+ respect to the file associated with FD. */
+
+int
+posix_fadvise (int fd, off_t offset, off_t len, int advise)
+{
+#ifdef __NR_fadvise64
+ INTERNAL_SYSCALL_DECL (err);
+ int ret = INTERNAL_SYSCALL (fadvise64, err, 5, fd,
+ __LONG_LONG_PAIR (offset >> 31, offset), len,
+ advise);
+ if (INTERNAL_SYSCALL_ERROR_P (ret, err))
+ return INTERNAL_SYSCALL_ERRNO (ret, err);
+ return 0;
+#else
+ return ENOSYS;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/posix_fadvise64.c b/libc/sysdeps/unix/sysv/linux/posix_fadvise64.c
new file mode 100644
index 000000000..3555ae835
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/posix_fadvise64.c
@@ -0,0 +1,82 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sysdep.h>
+#include <kernel-features.h>
+
+int __posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise);
+int __posix_fadvise64_l32 (int fd, off64_t offset, size_t len, int advise);
+
+/* Advice the system about the expected behaviour of the application with
+ respect to the file associated with FD. */
+
+int
+__posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise)
+{
+#ifdef __NR_fadvise64_64
+ INTERNAL_SYSCALL_DECL (err);
+ int ret = INTERNAL_SYSCALL (fadvise64_64, err, 6, fd,
+ __LONG_LONG_PAIR ((long) (offset >> 32),
+ (long) offset),
+ __LONG_LONG_PAIR ((long) (len >> 32),
+ (long) len),
+ advise);
+ if (!INTERNAL_SYSCALL_ERROR_P (ret, err))
+ return 0;
+# ifndef __ASSUME_FADVISE64_64_SYSCALL
+ if (INTERNAL_SYSCALL_ERRNO (ret, err) != ENOSYS)
+# endif
+ return INTERNAL_SYSCALL_ERRNO (ret, err);
+#endif
+#ifndef __ASSUME_FADVISE64_64_SYSCALL
+# ifdef __NR_fadvise64
+ if (len != (off_t) len)
+ return EOVERFLOW;
+
+ INTERNAL_SYSCALL_DECL (err2);
+ int ret2 = INTERNAL_SYSCALL (fadvise64, err2, 5, fd,
+ __LONG_LONG_PAIR ((long) (offset >> 32),
+ (long) offset),
+ (off_t) len, advise);
+ if (!INTERNAL_SYSCALL_ERROR_P (ret2, err2))
+ return 0;
+ return INTERNAL_SYSCALL_ERRNO (ret2, err2);
+# else
+ return ENOSYS;
+# endif
+#endif
+}
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_2, GLIBC_2_3_3)
+
+int
+attribute_compat_text_section
+__posix_fadvise64_l32 (int fd, off64_t offset, size_t len, int advise)
+{
+ return __posix_fadvise64_l64 (fd, offset, len, advise);
+}
+
+versioned_symbol (libc, __posix_fadvise64_l64, posix_fadvise64, GLIBC_2_3_3);
+compat_symbol (libc, __posix_fadvise64_l32, posix_fadvise64, GLIBC_2_2);
+#else
+strong_alias (__posix_fadvise64_l64, posix_fadvise64);
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/Implies b/libc/sysdeps/unix/sysv/linux/powerpc/Implies
new file mode 100644
index 000000000..ff27cdb56
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/Implies
@@ -0,0 +1,4 @@
+# Make sure these routines come before ldbl-opt.
+ieee754/ldbl-128ibm
+# These supply the ABI compatibility for when long double was double.
+ieee754/ldbl-opt
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/Makefile b/libc/sysdeps/unix/sysv/linux/powerpc/Makefile
new file mode 100644
index 000000000..ecd805795
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -0,0 +1,12 @@
+64bit-predefine = __powerpc64__
+ifeq ($(subdir),rt)
+librt-routines += rt-sysdep
+endif
+
+ifeq ($(subdir),stdlib)
+gen-as-const-headers += ucontext_i.sym
+endif
+
+ifeq ($(subdir),elf)
+routines += dl-vdso
+endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/Versions b/libc/sysdeps/unix/sysv/linux/powerpc/Versions
new file mode 100644
index 000000000..1ef53b9e9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/Versions
@@ -0,0 +1,7 @@
+libc {
+ GLIBC_PRIVATE {
+ __vdso_get_tbfreq;
+ __vdso_clock_gettime;
+ __vdso_clock_getres;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-dirent.h b/libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-dirent.h
new file mode 100644
index 000000000..c18e9fa4b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-dirent.h
@@ -0,0 +1,19 @@
+#include "aix-types.h"
+
+struct aixdirent
+ {
+ aixino_t d_ino;
+ aixoff_t d_off;
+ unsigned short int d_reclen;
+ unsigned short int d_namlen;
+ char d_name[256]; /* We must not include limits.h! */
+ };
+
+struct aixdirent64
+ {
+ aixino64_t d_ino;
+ aixoff64_t d_off;
+ unsigned short int d_reclen;
+ unsigned short int d_namlen;
+ char d_name[256]; /* We must not include limits.h! */
+ };
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-errno.h b/libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-errno.h
new file mode 100644
index 000000000..0df33d4e9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-errno.h
@@ -0,0 +1,125 @@
+/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define AIX_EPERM 1
+#define AIX_ENOENT 2
+#define AIX_ESRCH 3
+#define AIX_EINTR 4
+#define AIX_EIO 5
+#define AIX_ENXIO 6
+#define AIX_E2BIG 7
+#define AIX_ENOEXEC 8
+#define AIX_EBADF 9
+#define AIX_ECHILD 10
+#define AIX_EAGAIN 11
+#define AIX_ENOMEM 12
+#define AIX_EACCES 13
+#define AIX_EFAULT 14
+#define AIX_ENOTBLK 15
+#define AIX_EBUSY 16
+#define AIX_EEXIST 17
+#define AIX_EXDEV 18
+#define AIX_ENODEV 19
+#define AIX_ENOTDIR 20
+#define AIX_EISDIR 21
+#define AIX_EINVAL 22
+#define AIX_ENFILE 23
+#define AIX_EMFILE 24
+#define AIX_ENOTTY 25
+#define AIX_ETXTBSY 26
+#define AIX_EFBIG 27
+#define AIX_ENOSPC 28
+#define AIX_ESPIPE 29
+#define AIX_EROFS 30
+#define AIX_EMLINK 31
+#define AIX_EPIPE 32
+#define AIX_EDOM 33
+#define AIX_ERANGE 34
+#define AIX_ENOMSG 35
+#define AIX_EIDRM 36
+#define AIX_ECHRNG 37
+#define AIX_EL2NSYNC 38
+#define AIX_EL3HLT 39
+#define AIX_EL3RST 40
+#define AIX_ELNRNG 41
+#define AIX_EUNATCH 42
+#define AIX_ENOCSI 43
+#define AIX_EL2HLT 44
+#define AIX_EDEADLK 45
+#define AIX_ENOTREADY 46
+#define AIX_EWRPROTECT 47
+#define AIX_EFORMAT 48
+#define AIX_ENOLCK 49
+#define AIX_ENOCONNECT 50
+#define AIX_ESTALE 52
+#define AIX_EDIST 53
+#define AIX_EWOULDBLOCK 54
+#define AIX_EINPROGRESS 55
+#define AIX_EALREADY 56
+#define AIX_ENOTSOCK 57
+#define AIX_EDESTADDRREQ 58
+#define AIX_EMSGSIZE 59
+#define AIX_EPROTOTYPE 60
+#define AIX_ENOPROTOOPT 61
+#define AIX_EPROTONOSUPPORT 62
+#define AIX_ESOCKTNOSUPPORT 63
+#define AIX_EOPNOTSUPP 64
+#define AIX_EPFNOSUPPORT 65
+#define AIX_EAFNOSUPPORT 66
+#define AIX_EADDRINUSE 67
+#define AIX_EADDRNOTAVAIL 68
+#define AIX_ENETDOWN 69
+#define AIX_ENETUNREACH 70
+#define AIX_ENETRESET 71
+#define AIX_ECONNABORTED 72
+#define AIX_ECONNRESET 73
+#define AIX_ENOBUFS 74
+#define AIX_EISCONN 75
+#define AIX_ENOTCONN 76
+#define AIX_ESHUTDOWN 77
+#define AIX_ETIMEDOUT 78
+#define AIX_ECONNREFUSED 79
+#define AIX_EHOSTDOWN 80
+#define AIX_EHOSTUNREACH 81
+#define AIX_ERESTART 82
+#define AIX_EPROCLIM 83
+#define AIX_EUSERS 84
+#define AIX_ELOOP 85
+#define AIX_ENAMETOOLONG 86
+#define AIX_EDQUOT 88
+#define AIX_ECORRUPT 89
+#define AIX_EREMOTE 93
+#define AIX_ENOSYS 109
+#define AIX_EMEDIA 110
+#define AIX_ESOFT 111
+#define AIX_ENOATTR 112
+#define AIX_ESAD 113
+#define AIX_ENOTRUST 114
+#define AIX_ETOOMANYREFS 115
+#define AIX_EILSEQ 116
+#define AIX_ECANCELED 117
+#define AIX_ENOSR 118
+#define AIX_ETIME 119
+#define AIX_EBADMSG 120
+#define AIX_EPROTO 121
+#define AIX_ENODATA 122
+#define AIX_ENOSTR 123
+#define AIX_ENOTSUP 124
+#define AIX_EMULTIHOP 125
+#define AIX_ENOLINK 126
+#define AIX_EOVERFLOW 127
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-stat.h b/libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-stat.h
new file mode 100644
index 000000000..dc5ad5f73
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-stat.h
@@ -0,0 +1,76 @@
+/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+struct aixstat
+ {
+ aixdev_t st_dev;
+ aixino_t st_ino;
+ aixmode_t st_mode;
+ aixnlink_t st_nlink;
+ unsigned short int st_flag;
+ aixuid_t st_uid;
+ aixgid_t st_gid;
+ aixdev_t st_rdev;
+ aixoff_t st_size;
+ aixtime_t st_atime;
+ unsigned long int __unused1;
+ aixtime_t st_mtime;
+ unsigned long int __unused2;
+ aixtime_t st_ctime;
+ unsigned long int __unused3;
+ aixblksize_t st_blksize;
+ aixblkcnt_t st_blocks;
+ int st_vfstype;
+ unsigned int st_vfs;
+ unsigned int st_type;
+ unsigned int st_gen;
+
+#define _STATBUF_RESERVED_SPACE 9
+ unsigned int st_reserved[_STATBUF_RESERVED_SPACE];
+ };
+
+struct aixstat64
+ {
+ aixdev_t st_dev;
+ aixino64_t st_ino;
+ aixmode_t st_mode;
+ aixnlink_t st_nlink;
+ unsigned short int st_flag;
+ aixuid_t st_uid;
+ aixgid_t st_gid;
+ aixdev_t st_rdev;
+ int st_ssize;
+ aixtime_t st_atime;
+ unsigned long int __unused1;
+ aixtime_t st_mtime;
+ unsigned long int __unused2;
+ aixtime_t st_ctime;
+ unsigned long int __unused3;
+ aixblksize_t st_blksize;
+ aixblkcnt64_t st_blocks;
+ int st_vfstype;
+ unsigned int st_vfs;
+ unsigned int st_type;
+ unsigned int st_gen;
+ unsigned int st_reserved[_STATBUF_RESERVED_SPACE];
+ unsigned int st_padto_ll;
+ aixoff64_t st_size;
+ };
+
+#define aix_major(x) (int) ((unsigned int) (x) >> 16)
+#define aix_minor(x) (int) ((x) & 0xFFFF)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-termios.h b/libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-termios.h
new file mode 100644
index 000000000..5f3e953ab
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/aix/aix-termios.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "aix-types.h"
+
+#define AIX_NCCS 16
+struct aixtermios
+{
+ aixtcflag_t c_iflag;
+ aixtcflag_t c_oflag;
+ aixtcflag_t c_cflag;
+ aixtcflag_t c_lflag;
+ aixcc_t c_line;
+ aixcc_t c_cc[AIX_NCCS];
+ aixspeed_t c_ispeed;
+ aixspeed_t c_ospeed;
+};
+
+#define AIX_VINTR 0
+#define AIX_VQUIT 1
+#define AIX_VERASE 2
+#define AIX_VKILL 3
+#define AIX_VEOF 4
+#define AIX_VEOL 5
+#define AIX_VEOL2 6
+#define AIX_VSTART 7
+#define AIX_VSTOP 8
+#define AIX_VSUSP 9
+#define AIX_VDSUSP 10
+#define AIX_VREPRINT 11
+#define AIX_VDISCRD 12
+#define AIX_VWERSE 13
+#define AIX_VLNEXT 14
+
+#define AIX_IUCLC 0x00000800
+#define AIX_IXANY 0x00001000
+#define AIX_IMAXBE 0x00010000
+
+#define AIX_OLCUC 0x00000002
+#define AIX_ONLCR 0x00000004
+#define AIX_TABDLY 0x00000c00
+#define AIX_TAB0 0x00000000
+#define AIX_TAB1 0x00000400
+#define AIX_TAB2 0x00000800
+#define AIX_TAB3 0x00000c00
+#define AIX_BSDLY 0x00001000
+#define AIX_BS0 0x00000000
+#define AIX_BS1 0x00001000
+#define AIX_FFDLY 0x00002000
+#define AIX_FF0 0x00000000
+#define AIX_FF1 0x00002000
+#define AIX_NLDLY 0x00004000
+#define AIX_NL0 0x00000000
+#define AIX_NL1 0x00004000
+#define AIX_VTDLY 0x00008000
+#define AIX_VT0 0x00000000
+#define AIX_VT1 0x00008000
+
+#define AIX_CBAUD 0x0000000f
+#define AIX_CSIZE 0x00000030
+#define AIX_CS5 0x00000000
+#define AIX_CS6 0x00000010
+#define AIX_CS7 0x00000020
+#define AIX_CS8 0x00000030
+#define AIX_CSTOPB 0x00000040
+#define AIX_CREAD 0x00000080
+#define AIX_PARENB 0x00000100
+#define AIX_PARODD 0x00000200
+#define AIX_HUPCL 0x00000400
+#define AIX_CLOCAL 0x00000800
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/aix/direntconv.c b/libc/sysdeps/unix/sysv/linux/powerpc/aix/direntconv.c
new file mode 100644
index 000000000..ff4041b7e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/aix/direntconv.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dirent.h>
+#include <string.h>
+#include "linux-dirent.h"
+
+#ifndef DT_UNKNOWN
+# define DT_UNKNOWN 0
+#endif
+
+
+void
+__dirent_aix_to_linux (const struct aixdirent *aixdir,
+ struct dirent *linuxdir)
+{
+ linuxdir->d_ino = aixdir->d_ino;
+ linuxdir->d_off = aixdir->d_off;
+ linuxdir->d_reclen = aixdir->d_reclen;
+ linuxdir->d_type = DT_UNKNOWN;
+ memcpy (linuxdir->d_name, aixdir->d_name, aixdir->d_namlen + 1);
+}
+
+
+void
+__dirent64_aix_to_linux (const struct aixdirent64 *aixdir,
+ struct dirent64 *linuxdir)
+{
+ linuxdir->d_ino = aixdir->d_ino;
+ linuxdir->d_off = aixdir->d_off;
+ linuxdir->d_reclen = aixdir->d_reclen;
+ linuxdir->d_type = DT_UNKNOWN;
+ memcpy (linuxdir->d_name, aixdir->d_name, aixdir->d_namlen + 1);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/aix/errnoconv.c b/libc/sysdeps/unix/sysv/linux/powerpc/aix/errnoconv.c
new file mode 100644
index 000000000..efa0df786
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/aix/errnoconv.c
@@ -0,0 +1,143 @@
+/* Convert the error number the AIX kernel returns to what the Linux
+ application expects.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include "linux-errno.h"
+
+
+static int mapping[] =
+{
+ [AIX_EPERM] = EPERM,
+ [AIX_ENOENT] = ENOENT,
+ [AIX_ESRCH] = ESRCH,
+ [AIX_EINTR] = EINTR,
+ [AIX_EIO] = EIO,
+ [AIX_ENXIO] = ENXIO,
+ [AIX_E2BIG] = E2BIG,
+ [AIX_ENOEXEC] = ENOEXEC,
+ [AIX_EBADF] = EBADF,
+ [AIX_ECHILD] = ECHILD,
+ [AIX_EAGAIN] = EAGAIN,
+ [AIX_ENOMEM] = ENOMEM,
+ [AIX_EACCES] = EACCES,
+ [AIX_EFAULT] = EFAULT,
+ [AIX_ENOTBLK] = ENOTBLK,
+ [AIX_EBUSY] = EBUSY,
+ [AIX_EEXIST] = EEXIST,
+ [AIX_EXDEV] = EXDEV,
+ [AIX_ENODEV] = ENODEV,
+ [AIX_ENOTDIR] = ENOTDIR,
+ [AIX_EISDIR] = EISDIR,
+ [AIX_EINVAL] = EINVAL,
+ [AIX_ENFILE] = ENFILE,
+ [AIX_EMFILE] = EMFILE,
+ [AIX_ENOTTY] = ENOTTY,
+ [AIX_ETXTBSY] = ETXTBSY,
+ [AIX_EFBIG] = EFBIG,
+ [AIX_ENOSPC] = ENOSPC,
+ [AIX_EIDRM] = EIDRM,
+ [AIX_ECHRNG] = ECHRNG,
+ [AIX_EL2NSYNC] = EL2NSYNC,
+ [AIX_EL3HLT] = EL3HLT,
+ [AIX_EL3RST] = EL3RST,
+ [AIX_ELNRNG] = ELNRNG,
+ [AIX_EUNATCH] = EUNATCH,
+ [AIX_ENOCSI] = ENOCSI,
+ [AIX_EL2HLT] = EL2HLT,
+ [AIX_EDEADLK] = EDEADLK,
+ [AIX_ENOTREADY] = ENOTREADY,
+ // EWPROTECT: no Linux equivalent
+ // EFORMAT: no Linux equivalent
+ [AIX_ENOLCK] = ENOLCK,
+ // ENOCONNECT: No Linux equivalent
+ [AIX_ESTALE] = ESTALE,
+ // EDIST: no Linux equivalent
+ [54] = EAGAIN, // EWOULDBLOCK
+ [AIX_EINPROGRESS] = EINPROGRESS,
+ [AIX_EALREADY] = EALREADY,
+ [AIX_ENOTSOCK] = ENOTSOCK,
+ [AIX_EDESTADDRREQ] = EDESTADDRREQ,
+ [AIX_EMSGSIZE] = EMSGSIZE,
+ [AIX_EPROTOTYPE] = EPROTOTYPE,
+ [AIX_ENOPROTOOPT] = ENOPROTOOPT,
+ [AIX_EPROTONOSUPPORT] = EPROTONOSUPPORT,
+ [AIX_ESOCKTNOSUPPORT] = ESOCKTNOSUPPORT,
+ [AIX_EOPNOTSUPP] = EOPNOTSUPP,
+ [AIX_EPFNOSUPPORT] = EPFNOSUPPORT,
+ [AIX_EAFNOSUPPORT] = EAFNOSUPPORT,
+ [AIX_EADDRINUSE] = EADDRINUSE,
+ [AIX_EADDRNOTAVAIL] = EADDRNOTAVAIL,
+ [AIX_ENETDOWN] = ENETDOWN,
+ [AIX_ENETUNREACH] = ENETUNREACH,
+ [AIX_ENETRESET] = ENETRESET,
+ [AIX_ECONNABORTED] = ECONNABORTED,
+ [AIX_ECONNRESET] = ECONNRESET,
+ [AIX_ENOBUFS] = ENOBUFS,
+ [AIX_EISCONN] = EISCONN,
+ [AIX_ENOTCONN] = ENOTCONN,
+ [AIX_ESHUTDOWN] = ESHUTDOWN,
+ [AIX_ETIMEDOUT] = ETIMEDOUT,
+ [AIX_ECONNREFUSED] = ECONNREFUSED,
+ [AIX_EHOSTDOWN] = EHOSTDOWN,
+ [AIX_EHOSTUNREACH] = EHOSTUNREACH,
+ [AIX_ERESTART] = ERESTART,
+ [AIX_EPROCLIM] = EPROCLIM,
+ [AIX_EUSERS] = EUSERS,
+ [AIX_ELOOP] = ELOOP,
+ [AIX_ENAMETOOLONG] = ENAMETOOLONG,
+ [87] = ENOTEMPTY, // ENOTEMPTY
+ [AIX_EDQUOT] = EDQUOT,
+ [AIX_ECORRUPT] = ECORRUPT,
+ [AIX_EREMOTE] = EREMOTE,
+ [AIX_ENOSYS] = ENOSYS,
+ [AIX_EMEDIA] = EMEDIA,
+ [AIX_ESOFT] = ESOFT,
+ [AIX_ENOATTR] = ENOATTR,
+ [AIX_ESAD] = ESAD,
+ // ENOTRUST: no Linux equivalent
+ [AIX_ETOOMANYREFS] = ETOOMANYREFS,
+ [AIX_EILSEQ] = EILSEQ,
+ [AIX_ECANCELED] = ECANCELED,
+ [AIX_ENOSR] = ENOSR,
+ [AIX_ETIME] = ETIME,
+ [AIX_EBADMSG] = EBADMSG,
+ [AIX_EPROTO] = EPROTO,
+ [AIX_ENODATA] = ENODATA,
+ [AIX_ENOSTR] = ENOSTR,
+ [AIX_ENOTSUP] = ENOTSUP,
+ [AIX_EMULTIHOP] = EMULTIHOP,
+ [AIX_ENOLINK] = ENOLINK,
+ [AIX_EOVERFLOW] = EOVERFLOW
+};
+
+
+int
+__errno_aix_to_linux (int err)
+{
+ int conv;
+
+ if (err >= 0 && err < (sizeof (mapping) / sizeof (mapping[0]))
+ && ((conv = mapping[err]) != 0 || err == 0))
+ return conv;
+
+ /* The error value is not known. Create a special value which can
+ be easily recognized as an invalid result. */
+ return 512 + err;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/aix/statconv.c b/libc/sysdeps/unix/sysv/linux/powerpc/aix/statconv.c
new file mode 100644
index 000000000..0d7b5f780
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/aix/statconv.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+void
+__stat_aix_to_linux (const struct aixstat *aixstat, struct stat *linuxstat)
+{
+ linuxstat->st_dev = makedev (aix_major (aixstat->st_dev),
+ aix_minor (aixstat->st_dev));
+ linuxstat->st_ino = aixstat->st_ino;
+ /* The following assumes that the mode values are the same on AIX
+ and Linux which is true in the moment. */
+ linuxstat->st_mode = aixstat->st_mode;
+ linuxstat->st_nlink = aixstat->st_nlink;
+ /* There is no st_flag field in Linux. */
+ linuxstat->st_uid = aixstat->st_uid;
+ linuxstat->st_gid = aixstat->st_gid;
+ linuxstat->st_rdev = makedev (aix_major (aixstat->st_rdev),
+ aix_minor (aixstat->st_rdev));
+ linuxstat->st_size = aixstat->st_size;
+ linuxstat->st_atime = aixstat->st_atime;
+ linuxstat->st_mtime = aixstat->st_mtime;
+ linuxstat->st_ctime = aixstat->st_ctime;
+ linuxstat->st_blksize = aixstat->st_blksize;
+ linuxstat->st_blocks = aixstat->st_blocks;
+ /* There is no st_vfstype in Linux. */
+ /* There is no st_vfs in Linux. */
+ /* There is no st_type in Linux. */
+ /* There is no st_gen in Linux. */
+
+ /* File in the padding values with repeatable values. */
+ linuxstat->__pad1 = 0;
+ linuxstat->__pad2 = 0;
+ linuxstat->__unused1 = 0;
+ linuxstat->__unused2 = 0;
+ linuxstat->__unused3 = 0;
+ linuxstat->__unused4 = 0;
+ linuxstat->__unused5 = 0;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/aix/tcgetattr.c b/libc/sysdeps/unix/sysv/linux/powerpc/aix/tcgetattr.c
new file mode 100644
index 000000000..c095c7c85
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/aix/tcgetattr.c
@@ -0,0 +1,156 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <termios.h>
+#include "aix-termios.h"
+
+int
+tcgetattr (fd, linuxtermios_p)
+ int fd;
+ struct termios *linuxtermios_p;
+{
+ struct aixtermios aixtermios;
+ int result;
+
+ result = /* make syscall */;
+
+ if (result != -1)
+ {
+ /* Convert the result. */
+
+ linuxtermios_p->c_cc[VINTR] = aixtermios.c_cc[AIX_VINTR];
+ linuxtermios_p->c_cc[VQUIT] = aixtermios.c_cc[AIX_VQUIT];
+ linuxtermios_p->c_cc[VERASE] = aixtermios.c_cc[AIX_VERASE];
+ linuxtermios_p->c_cc[VKILL] = aixtermios.c_cc[AIX_VKILL];
+ linuxtermios_p->c_cc[VEOF] = aixtermios.c_cc[AIX_VEOF];
+ // XXX VMIN has the same value as VEOF !?
+ linuxtermios_p->c_cc[VEOL] = aixtermios.c_cc[AIX_VEOL];
+ // XXX VTIME has the same value as VEOL !?
+ linuxtermios_p->c_cc[VEOL2] = aixtermios.c_cc[AIX_VEOL2];
+ linuxtermios_p->c_cc[VSTART] = aixtermios.c_cc[AIX_VSTART];
+ linuxtermios_p->c_cc[VSTOP] = aixtermios.c_cc[AIX_VSTOP];
+ linuxtermios_p->c_cc[VSUSP] = aixtermios.c_cc[AIX_VSUSP];
+ // XXX No Linux equivalent for VDSUSP !?
+ linuxtermios_p->c_cc[VREPRINT] = aixtermios.c_cc[AIX_VREPRINT];
+ linuxtermios_p->c_cc[VDISCARD] = aixtermios.c_cc[AIX_VDISCARD];
+ linuxtermios_p->c_cc[VWERASE] = aixtermios.c_cc[AIX_VWERASE];
+ linuxtermios_p->c_cc[VLNEXT] = aixtermios.c_cc[AIX_VLNEXT];
+
+ linuxtermios_p->c_cflag = aixtermios.c_c_flag & AIX_CBAUD;
+
+ /* Only the IUCLC, IXANY, and IMAXBEL values are different in the
+ c_iflag member. */
+ linuxtermios_p->c_iflag = aixtermios.c_iflag & 0x7ff;
+ if (aixtermios.c_iflag & AIX_IXANY)
+ linuxtermios_p->c_iflag |= IXANY;
+ if (aixtermios.c_iflag & AIX_IUCLC)
+ linuxtermios_p->c_iflag |= IUCLC;
+ if (aixtermios.c_iflag & AIX_IMAXBEL)
+ linuxtermios_p->c_iflag |= IMAXBEL;
+
+ /* Many of the c_oflag files differ. Bummer. */
+ linuxtermios_p->c_oflag = (aixtermios.c_oflag
+ & (OPOST | OCRNL | ONOCR | ONLRET | OFILL
+ | OFDEL | TABDLY));
+ if (aixtermios.c_oflag & AIX_OLCUC)
+ linuxtermios_p->c_oflag |= OLCUC;
+ if (aixtermios.c_oflag & AIX_ONLCR)
+ linuxtermios_p->c_oflag |= ONLCR;
+ if (aixtermiosc_oflag & AIX_NLDLY)
+ linuxtermios_p->c_oflag |= NL1;
+
+ if (aixtermiosc_oflag.c_oflag & AIX_TABDLY)
+ {
+#define offset 2
+#if AIX_TAB1 << offset != TAB1 || AIX_TAB3 << offset != TAB3
+# error "Check the offset"
+#endif
+ linuxtermios_p->c_oflag |= (aixtermios.c_oflag >> offset) & TABDLY;
+#undef offset
+ }
+ if (aixtermios.c_oflag & AIX_FFDLY)
+ linuxtermios_p->c_oflag |= FF1;
+ if (aixtermios.c_oflag & AIX_BSDLY)
+ linuxtermios_p->c_oflag |= BS1;
+ if (aixtermios.c_oflag & AIX_VTDLY)
+ linuxtermios_p->c_oflag |= VT1;
+
+ /* A lot of the c_cflag member is also different. */
+ if (aixtermios.c_cflag & AIX_CSIZE)
+ {
+#define offset 4
+#if CSIZE >> offset != AIX_CSIZE
+# error "Check the offset"
+#endif
+ linuxtermios_p->c_cflag |= (aixtermios.c_cflag >> offset) & CSIZE;
+#undef offset
+ }
+
+ if (aixtermios.c_cflag & AIX_STOPB)
+ linuxtermios_p->c_cflag |= STOPB;
+ if (aixtermios.c_cflag & AIX_CREAD)
+ linuxtermios_p->c_cflag |= CREAD;
+ if (aixtermios.cflag & AIX_PARENB)
+ linuxtermios_p->c_cflag |= PARENB;
+ if (aixtermios.cflag & AIX_PARODD)
+ linuxtermios_p->c_cflag |= PARODD;
+ if (aixtermios.c_cflag & AIX_HUPCL)
+ linuxtermios_p->c_cflag |= HUPCL;
+ if (aixtermios.c_cflag & AIX_CLOCAL)
+ linuxtermios_p->c_cflag |= CLOCAL;
+
+ /* The c_lflag is information is also different. */
+ aixtermios.c_lflag = 0;
+ if (aixtermios.c_lflag & AIX_ISIG)
+ linuxtermios_p->c_lflag |= ISIG;
+ if (aixtermios.c_lflag & AIX_ICANON)
+ linuxtermios_p->c_lflag |= ICANON;
+ if (aixtermios.c_lflag & AIX_XCASE)
+ linuxtermios_p->c_lflag |= XCASE;
+ if (aixtermios.c_lflag & AIX_ECHO)
+ linuxtermios_p->c_lflag |= ECHO;
+ if (aixtermios.c_lflag & AIX_ECHOE)
+ linuxtermios_p->c_lflag |= ECHOE;
+ if (aixtermios.c_lflag & AIX_ECHOK)
+ linuxtermios_p->c_lflag |= ECHOK;
+ if (aixtermios.c_lflag & AIX_ECHONL)
+ linuxtermios_p->c_lflag |= ECHONL;
+ if (aixtermios.c_lflag & AIX_NOFLSH)
+ linuxtermios_p->c_lflag |= NOFLSH;
+ if (aixtermios.c_lflag & AIX_TOSTOP)
+ linuxtermios_p->c_lflag |= TOSTOP;
+ if (aixtermios.c_lflag & AIX_ECHOCTL)
+ linuxtermios_p->c_lflag |= ECHOCTL;
+ if (aixtermios.c_lflag & AIX_ECHOPRT)
+ linuxtermios_p->c_lflag |= ECHOPRT;
+ if (aixtermios.c_lflag & AIX_ECHOKE)
+ linuxtermios_p->c_lflag |= ECHOKE;
+ if (aixtermios.c_lflag & AIX_FLUSHO)
+ linuxtermios_p->c_lflag |= FLUSHO;
+ if (aixtermios.c_lflag & AIX_PENDIN)
+ linuxtermios_p->c_lflag |= PENDIN;
+ if (aixtermios->c_lflag & AIX_IEXTEN)
+ linuxtermios_p->c_lflag |= IEXTEN;
+ }
+ else
+ // Convert error here or in syscall.
+ ;
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/aix/tcsetattr.c b/libc/sysdeps/unix/sysv/linux/powerpc/aix/tcsetattr.c
new file mode 100644
index 000000000..3f9d29808
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/aix/tcsetattr.c
@@ -0,0 +1,171 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <termios.h>
+#include "aix-termios.h"
+
+int
+tcsetattr (fd, optional_actions, linuxtermios_p)
+ int fd;
+ int optional_actions;
+ const struct termios *linuxtermios_p;
+{
+ struct aixtermios aixtermios;
+ int result;
+
+ /* `optional_actions' does not have to be changed, AIX uses the
+ same values as Linux. */
+
+ aixtermios.c_cc[AIX_VINTR] = linuxtermios_p->c_cc[VINTR];
+ aixtermios.c_cc[AIX_VQUIT] = linuxtermios_p->c_cc[VQUIT];
+ aixtermios.c_cc[AIX_VERASE] = linuxtermios_p->c_cc[VERASE];
+ aixtermios.c_cc[AIX_VKILL] = linuxtermios_p->c_cc[VKILL];
+ aixtermios.c_cc[AIX_VEOF] = linuxtermios_p->c_cc[VEOF];
+ // XXX VMIN has the same value as VEOF !?
+ aixtermios.c_cc[AIX_VEOL] = linuxtermios_p->c_cc[VEOL];
+ // XXX VTIME has the same value as VEOL !?
+ aixtermios.c_cc[AIX_VEOL2] = linuxtermios_p->c_cc[VEOL2];
+ aixtermios.c_cc[AIX_VSTART] = linuxtermios_p->c_cc[VSTART];
+ aixtermios.c_cc[AIX_VSTOP] = linuxtermios_p->c_cc[VSTOP];
+ aixtermios.c_cc[AIX_VSUSP] = linuxtermios_p->c_cc[VSUSP];
+ aixtermios.c_cc[AIX_VDSUSP] = 0; // XXX No Linux equivalent !?
+ aixtermios.c_cc[AIX_VREPRINT] = linuxtermios_p->c_cc[VREPRINT];
+ aixtermios.c_cc[AIX_VDISCARD] = linuxtermios_p->c_cc[VDISCARD];
+ aixtermios.c_cc[AIX_VWERASE] = linuxtermios_p->c_cc[VWERASE];
+ aixtermios.c_cc[AIX_VLNEXT] = linuxtermios_p->c_cc[VLNEXT];
+
+ /* AIX has not all the speeds (the high one) Linux supports. The
+ symbol names and values used for the speeds are fortunately the
+ same. */
+ if ((linuxtermios_p->c_cflag & CBAUD) > B38400)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ aixtermios.c_c_flag = linuxtermios_p->c_cflag & CBAUD;
+
+ /* Only the IUCLC, IXANY, and IMAXBEL values are different in the
+ c_iflag member. */
+ aixtermios.c_iflag = linuxtermios_p->c_iflag & 0x7ff;
+ if (linuxtermios_p->c_iflag & IXANY)
+ aixtermios.c_iflag |= AIX_IXANY;
+ if (linuxtermios_p->c_iflag & IUCLC)
+ aixtermios.c_iflag |= AIX_IUCLC;
+ if (linuxtermios_p->c_iflag & IMAXBEL)
+ aixtermios.c_iflag |= AIX_IMAXBEL;
+
+ /* Many of the c_oflag files differ. Bummer. */
+ aixtermios.c_oflag = (linuxtermios_p->c_oflag
+ & (OPOST | OCRNL | ONOCR | ONLRET | OFILL
+ | OFDEL | TABDLY));
+ if (linuxtermios_p->c_oflag & OLCUC)
+ aixtermios.c_oflag |= AIX_OLCUC;
+ if (linuxtermios_p->c_oflag & ONLCR)
+ aixtermios.c_oflag |= AIX_ONLCR;
+ if (linuxtermios_p->c_oflag & NLDLY)
+ {
+ if ((linuxtermios_p->c_oflag & NLDLY) >= NL2)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (linuxtermios_p->c_oflag & NLDLY)
+ aixtermios.c_oflag |= AIX_NL1;
+ }
+ if (linuxtermios_p->c_oflag & TABDLY)
+ {
+#define offset 2
+#if TAB1 >> offset != AIX_TAB1 || TAB3 >> offset != AIX_TAB3
+# error "Check the offset"
+#endif
+ aixtermios.c_oflag |= (linuxtermios_p->c_oflag >> offset) & AIX_TABDLY;
+#undef offset
+ }
+ if (linuxtermios_p->c_oflag & FFDLY)
+ aixtermios.c_oflag |= AIX_FF1;
+ if (linuxtermios_p->c_oflag & BSDLY)
+ aixtermios.c_oflag |= AIX_BS1;
+ if (linuxtermios_p->c_oflag & VTDLY)
+ aixtermios.c_oflag |= AIX_VT1;
+
+ /* A lot of the c_cflag member is also different. */
+ if (linuxtermios_p->c_cflag & CSIZE)
+ {
+#define offset 4
+#if CSIZE >> offset != AIX_CSIZE
+# error "Check the offset"
+#endif
+ aixtermios.c_cflag |= (linuxtermios_p->c_cflag >> offset) & AIX_CSIZE;
+#undef offset
+ }
+
+ if (linuxtermios_p->c_cflag & STOPB)
+ aixtermios.c_cflag |= AIX_STOPB;
+ if (linuxtermios_p->c_cflag & CREAD)
+ aixtermios.c_cflag |= AIX_CREAD;
+ if (linuxtermios_p->c_cflag & PARENB)
+ aixtermios.c_cflag |= AIX_PARENB;
+ if (linuxtermios_p->c_cflag & PARODD)
+ aixtermios.c_cflag |= AIX_PARODD;
+ if (linuxtermios_p->c_cflag & HUPCL)
+ aixtermios.c_cflag |= AIX_HUPCL;
+ if (linuxtermios_p->c_cflag & CLOCAL)
+ aixtermios.c_cflag |= AIX_CLOCAL;
+
+ /* The c_lflag is information is also different. */
+ aixtermios.c_lflag = 0;
+ if (linuxtermios_p->c_lflag & ISIG)
+ aixtermios.c_lflag |= AIX_ISIG;
+ if (linuxtermios_p->c_lflag & ICANON)
+ aixtermios.c_lflag |= AIX_ICANON;
+ if (linuxtermios_p->c_lflag & XCASE)
+ aixtermios.c_lflag |= AIX_XCASE;
+ if (linuxtermios_p->c_lflag & ECHO)
+ aixtermios.c_lflag |= AIX_ECHO;
+ if (linuxtermios_p->c_lflag & ECHOE)
+ aixtermios.c_lflag |= AIX_ECHOE;
+ if (linuxtermios_p->c_lflag & ECHOK)
+ aixtermios.c_lflag |= AIX_ECHOK;
+ if (linuxtermios_p->c_lflag & ECHONL)
+ aixtermios.c_lflag |= AIX_ECHONL;
+ if (linuxtermios_p->c_lflag & NOFLSH)
+ aixtermios.c_lflag |= AIX_NOFLSH;
+ if (linuxtermios_p->c_lflag & TOSTOP)
+ aixtermios.c_lflag |= AIX_TOSTOP;
+ if (linuxtermios_p->c_lflag & ECHOCTL)
+ aixtermios.c_lflag |= AIX_ECHOCTL;
+ if (linuxtermios_p->c_lflag & ECHOPRT)
+ aixtermios.c_lflag |= AIX_ECHOPRT;
+ if (linuxtermios_p->c_lflag & ECHOKE)
+ aixtermios.c_lflag |= AIX_ECHOKE;
+ if (linuxtermios_p->c_lflag & FLUSHO)
+ aixtermios.c_lflag |= AIX_FLUSHO;
+ if (linuxtermios_p->c_lflag & PENDIN)
+ aixtermios.c_lflag |= AIX_PENDIN;
+ if (linuxtermios_p->c_lflag & IEXTEN)
+ aixtermios.c_lflag |= AIX_IEXTEN;
+
+ result = /* XXX syscall */;
+
+ // Convert error here or in syscall.
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/environments.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/environments.h
new file mode 100644
index 000000000..a51a564cb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/environments.h
@@ -0,0 +1,87 @@
+/* Copyright (C) 1999, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _UNISTD_H
+# error "Never include this file directly. Use <unistd.h> instead"
+#endif
+
+#include <bits/wordsize.h>
+
+/* This header should define the following symbols under the described
+ situations. A value `1' means that the model is always supported,
+ `-1' means it is never supported. Undefined means it cannot be
+ statically decided.
+
+ _POSIX_V6_ILP32_OFF32 32bit int, long, pointers, and off_t type
+ _POSIX_V6_ILP32_OFFBIG 32bit int, long, and pointers and larger off_t type
+
+ _POSIX_V6_LP64_OFF32 64bit long and pointers and 32bit off_t type
+ _POSIX_V6_LPBIG_OFFBIG 64bit long and pointers and large off_t type
+
+ The macros _XBS5_ILP32_OFF32, _XBS5_ILP32_OFFBIG, _XBS5_LP64_OFF32, and
+ _XBS5_LPBIG_OFFBIG were used in previous versions of the Unix standard
+ and are available only for compatibility.
+*/
+
+#if __WORDSIZE == 64
+
+/* Environments with 32-bit wide pointers are optionally provided.
+ Therefore following macros aren't defined:
+ # undef _POSIX_V6_ILP32_OFF32
+ # undef _POSIX_V6_ILP32_OFFBIG
+ # undef _XBS5_ILP32_OFF32
+ # undef _XBS5_ILP32_OFFBIG
+ and users need to check at runtime. */
+
+/* We also have no use (for now) for an environment with bigger pointers
+ and offsets. */
+# define _POSIX_V6_LPBIG_OFFBIG -1
+# define _XBS5_LPBIG_OFFBIG -1
+
+/* By default we have 64-bit wide `long int', pointers and `off_t'. */
+# define _POSIX_V6_LP64_OFF64 1
+# define _XBS5_LP64_OFF64 1
+
+#else /* __WORDSIZE == 32 */
+
+/* By default we have 32-bit wide `int', `long int', pointers and `off_t'
+ and all platforms support LFS. */
+# define _POSIX_V6_ILP32_OFF32 1
+# define _POSIX_V6_ILP32_OFFBIG 1
+# define _XBS5_ILP32_OFF32 1
+# define _XBS5_ILP32_OFFBIG 1
+
+/* We optionally provide an environment with the above size but an 64-bit
+ side `off_t'. Therefore we don't define _XBS5_ILP32_OFFBIG. */
+
+/* Environments with 64-bit wide pointers can be provided,
+ so these macros aren't defined:
+ # undef _POSIX_V6_LP64_OFF64
+ # undef _POSIX_V6_LPBIG_OFFBIG
+ # undef _XBS5_LP64_OFF64
+ # undef _XBS5_LPBIG_OFFBIG
+ and sysconf tests for it at runtime. */
+
+#endif /* __WORDSIZE == 32 */
+
+#define __ILP32_OFF32_CFLAGS "-m32"
+#define __ILP32_OFFBIG_CFLAGS "-m32 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+#define __ILP32_OFF32_LDFLAGS "-m32"
+#define __ILP32_OFFBIG_LDFLAGS "-m32"
+#define __LP64_OFF64_CFLAGS "-m64"
+#define __LP64_OFF64_LDFLAGS "-m64"
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
new file mode 100644
index 000000000..57fc7bd98
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
@@ -0,0 +1,236 @@
+/* O_*, F_*, FD_* bit values for Linux/PowerPC.
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2003, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#include <sys/types.h>
+#ifdef __USE_GNU
+# include <bits/uio.h>
+#endif
+
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_ACCMODE 0003
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+#define O_CREAT 0100 /* not fcntl */
+#define O_EXCL 0200 /* not fcntl */
+#define O_NOCTTY 0400 /* not fcntl */
+#define O_TRUNC 01000 /* not fcntl */
+#define O_APPEND 02000
+#define O_NONBLOCK 04000
+#define O_NDELAY O_NONBLOCK
+#define O_SYNC 010000
+#define O_FSYNC O_SYNC
+#define O_ASYNC 020000
+
+#ifdef __USE_GNU
+# define O_DIRECT 0400000 /* Direct disk access. */
+# define O_DIRECTORY 040000 /* Must be a directory. */
+# define O_NOFOLLOW 0100000 /* Do not follow links. */
+# define O_NOATIME 01000000 /* Do not set atime. */
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define O_LARGEFILE 0200000
+#endif
+
+/* For now Linux has synchronisity options for data and read operations.
+ We define the symbols here but let them do the same as O_SYNC since
+ this is a superset. */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC O_SYNC /* Synchronize data. */
+# define O_RSYNC O_SYNC /* Synchronize read operations. */
+#endif
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#ifndef __USE_FILE_OFFSET64
+# define F_GETLK 5 /* Get record locking info. */
+# define F_SETLK 6 /* Set record locking info (non-blocking). */
+# define F_SETLKW 7 /* Set record locking info (blocking). */
+#else
+# define F_GETLK F_GETLK64 /* Get record locking info. */
+# define F_SETLK F_SETLK64 /* Set record locking info (non-blocking).*/
+# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */
+#endif
+#define F_GETLK64 12 /* Get record locking info. */
+#define F_SETLK64 13 /* Set record locking info (non-blocking). */
+#define F_SETLKW64 14 /* Set record locking info (blocking). */
+
+#if defined __USE_BSD || defined __USE_UNIX98
+# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */
+# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETSIG 10 /* Set number of signal to be sent. */
+# define F_GETSIG 11 /* Get number of signal to be sent. */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETLEASE 1024 /* Set a lease. */
+# define F_GETLEASE 1025 /* Enquire what lease is active. */
+# define F_NOTIFY 1026 /* Request notfications on a directory. */
+#endif
+
+/* For F_[GET|SET]FD. */
+#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
+#define F_RDLCK 0 /* Read lock. */
+#define F_WRLCK 1 /* Write lock. */
+#define F_UNLCK 2 /* Remove lock. */
+
+/* For old implementation of bsd flock(). */
+#define F_EXLCK 4 /* or 3 */
+#define F_SHLCK 8 /* or 4 */
+
+#ifdef __USE_BSD
+/* Operations for bsd flock(), also used by the kernel implementation. */
+# define LOCK_SH 1 /* shared lock */
+# define LOCK_EX 2 /* exclusive lock */
+# define LOCK_NB 4 /* or'd with one of the above to prevent
+ blocking */
+# define LOCK_UN 8 /* remove lock */
+#endif
+
+#ifdef __USE_GNU
+# define LOCK_MAND 32 /* This is a mandatory flock: */
+# define LOCK_READ 64 /* ... which allows concurrent read operations. */
+# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */
+# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */
+#endif
+
+#ifdef __USE_GNU
+/* Types of directory notifications that may be requested with F_NOTIFY. */
+# define DN_ACCESS 0x00000001 /* File accessed. */
+# define DN_MODIFY 0x00000002 /* File modified. */
+# define DN_CREATE 0x00000004 /* File created. */
+# define DN_DELETE 0x00000008 /* File removed. */
+# define DN_RENAME 0x00000010 /* File renamed. */
+# define DN_ATTRIB 0x00000020 /* File changed attibutes. */
+# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */
+#endif
+
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+#ifndef __USE_FILE_OFFSET64
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+#else
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+#endif
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+#endif
+
+/* Define some more compatibility macros to be backward compatible with
+ BSD systems which did not managed to hide these kernel macros. */
+#ifdef __USE_BSD
+# define FAPPEND O_APPEND
+# define FFSYNC O_FSYNC
+# define FASYNC O_ASYNC
+# define FNONBLOCK O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif /* Use BSD. */
+
+/* Advise to `posix_fadvise'. */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
+# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
+#endif
+
+
+#ifdef __USE_GNU
+/* Flags for SYNC_FILE_RANGE. */
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+
+/* Flags for SPLICE and VMSPLICE. */
+# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */
+# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing
+ (but we may still block on the fd
+ we splice from/to). */
+# define SPLICE_F_MORE 4 /* Expect more data. */
+# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
+#endif
+
+__BEGIN_DECLS
+
+#ifdef __USE_GNU
+
+/* Provide kernel hint to read ahead. */
+extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
+ __THROW;
+
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice address range into a pipe. */
+extern int vmsplice (int __fdout, const struct iovec *__iov, size_t __count,
+ unsigned int __flags);
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/ioctl-types.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/ioctl-types.h
new file mode 100644
index 000000000..87b8265af
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/ioctl-types.h
@@ -0,0 +1,5 @@
+#ifndef _SYS_IOCTL_H
+# error "Never use <bits/ioctl-types.h> directly; include <sys/ioctl.h> instead."
+#endif
+
+#include <termios.h>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/ipc.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/ipc.h
new file mode 100644
index 000000000..1ba99347c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/ipc.h
@@ -0,0 +1,79 @@
+/* Copyright (C) 1995-1999, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IPC_H
+# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Mode bits for `msgget', `semget', and `shmget'. */
+#define IPC_CREAT 01000 /* Create key if key does not exist. */
+#define IPC_EXCL 02000 /* Fail if key exists. */
+#define IPC_NOWAIT 04000 /* Return error on wait. */
+
+/* Control commands for `msgctl', `semctl', and `shmctl'. */
+#define IPC_RMID 0 /* Remove identifier. */
+#define IPC_SET 1 /* Set `ipc_perm' options. */
+#define IPC_STAT 2 /* Get `ipc_perm' options. */
+#ifdef __USE_GNU
+# define IPC_INFO 3 /* See ipcs. */
+#endif
+
+/* Special key values. */
+#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
+
+
+/* Data structure used to pass permission information to IPC operations. */
+struct ipc_perm
+ {
+ __key_t __key; /* Key. */
+ __uid_t uid; /* Owner's user ID. */
+ __gid_t gid; /* Owner's group ID. */
+ __uid_t cuid; /* Creator's user ID. */
+ __gid_t cgid; /* Creator's group ID. */
+ __mode_t mode; /* Read/write permission. */
+ __uint32_t __seq; /* Sequence number. */
+ __uint32_t __pad1;
+ __uint64_t __unused1;
+ __uint64_t __unused2;
+ };
+
+
+__BEGIN_DECLS
+
+/* The actual system call: all functions are multiplexed by this. */
+extern int __ipc (int __call, int __first, int __second, int __third,
+ void *__ptr) __THROW;
+
+__END_DECLS
+
+#ifdef __USE_GNU
+/* The codes for the functions to use the multiplexer `__ipc'. */
+# define IPCOP_semop 1
+# define IPCOP_semget 2
+# define IPCOP_semctl 3
+# define IPCOP_msgsnd 11
+# define IPCOP_msgrcv 12
+# define IPCOP_msgget 13
+# define IPCOP_msgctl 14
+# define IPCOP_shmat 21
+# define IPCOP_shmdt 22
+# define IPCOP_shmget 23
+# define IPCOP_shmctl 24
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
new file mode 100644
index 000000000..f20a5a175
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
@@ -0,0 +1,36 @@
+/* Resolve function pointers to VDSO functions.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#ifdef SHARED
+
+extern void *__vdso_gettimeofday;
+
+extern void *__vdso_clock_gettime;
+
+extern void *__vdso_clock_getres;
+
+extern void *__vdso_get_tbfreq;
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/mman.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
new file mode 100644
index 000000000..e03ab7ff8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
@@ -0,0 +1,104 @@
+/* Definitions for POSIX memory map interface. Linux/PowerPC version.
+ Copyright (C) 1997, 2000, 2003, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MMAN_H
+# error "Never use <bits/mman.h> directly; iclude <sys/mman.h> instead."
+#endif
+
+/* The following definitions basically come from the kernel headers.
+ But the kernel header is not namespace clean. */
+
+
+/* Protections are chosen from these bits, OR'd together. The
+ implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ without PROT_READ. The only guarantees are that no writing will be
+ allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
+
+#define PROT_READ 0x1 /* Page can be read. */
+#define PROT_WRITE 0x2 /* Page can be written. */
+#define PROT_EXEC 0x4 /* Page can be executed. */
+#define PROT_NONE 0x0 /* Page can not be accessed. */
+#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
+ growsdown vma (mprotect only). */
+#define PROT_GROWSUP 0x02000000 /* Extend change to start of
+ growsup vma (mprotect only). */
+
+/* Sharing types (must choose one and only one of these). */
+#define MAP_SHARED 0x001 /* Share changes. */
+#define MAP_PRIVATE 0x002 /* Changes are private. */
+#ifdef __USE_MISC
+# define MAP_TYPE 0x00f /* Mask for type of mapping. */
+#endif
+
+/* Other flags. */
+#define MAP_FIXED 0x010 /* Interpret addr exactly. */
+#ifdef __USE_MISC
+# define MAP_FILE 0x000
+# define MAP_ANONYMOUS 0x020 /* Don't use a file. */
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+
+/* These are Linux-specific. */
+#ifdef __USE_MISC
+# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */
+# define MAP_DENYWRITE 0x00800 /* ETXTBSY */
+# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */
+# define MAP_LOCKED 0x00080 /* Lock the mapping. */
+# define MAP_NORESERVE 0x00040 /* Don't check for reservations. */
+# define MAP_POPULATE 0x08000 /* Populate (prefault) pagetables. */
+# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */
+#endif
+
+/* Flags to `msync'. */
+#define MS_ASYNC 1 /* Sync memory asynchronously. */
+#define MS_SYNC 4 /* Synchronous memory sync. */
+#define MS_INVALIDATE 2 /* Invalidate the caches. */
+
+/* Flags for `mlockall'. */
+#define MCL_CURRENT 0x2000 /* Lock all currently mapped pages. */
+#define MCL_FUTURE 0x4000 /* Lock all additions to address
+ space. */
+
+
+/* Flags for `mremap'. */
+#ifdef __USE_GNU
+# define MREMAP_MAYMOVE 1
+# define MREMAP_FIXED 2
+#endif
+
+/* Advice to `madvise'. */
+#ifdef __USE_BSD
+# define MADV_NORMAL 0 /* No further special treatment. */
+# define MADV_RANDOM 1 /* Expect random page references. */
+# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define MADV_WILLNEED 3 /* Will need these pages. */
+# define MADV_DONTNEED 4 /* Don't need these pages. */
+# define MADV_REMOVE 9 /* Remove these pages and resources. */
+# define MADV_DONTFORK 10 /* Do not inherit across fork. */
+# define MADV_DOFORK 11 /* Do inherit across fork. */
+#endif
+
+/* The POSIX people had to invent similar names for the same things. */
+#ifdef __USE_XOPEN2K
+# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/msq.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/msq.h
new file mode 100644
index 000000000..f19884437
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/msq.h
@@ -0,0 +1,83 @@
+/* Copyright (C) 1995, 1996, 1997, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Define options for message queue functions. */
+#define MSG_NOERROR 010000 /* no error if message is too big */
+#ifdef __USE_GNU
+# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+#endif
+
+/* Types used in the structure definition. */
+typedef unsigned long int msgqnum_t;
+typedef unsigned long int msglen_t;
+
+
+/* Structure of record for one message inside the kernel.
+ The type `struct msg' is opaque. */
+struct msqid_ds
+{
+ struct ipc_perm msg_perm; /* structure describing operation permission */
+#if __WORDSIZE == 32
+ unsigned int __unused1;
+#endif
+ __time_t msg_stime; /* time of last msgsnd command */
+#if __WORDSIZE == 32
+ unsigned int __unused2;
+#endif
+ __time_t msg_rtime; /* time of last msgrcv command */
+#if __WORDSIZE == 32
+ unsigned int __unused3;
+#endif
+ __time_t msg_ctime; /* time of last change */
+ unsigned long __msg_cbytes; /* current number of bytes on queue */
+ msgqnum_t msg_qnum; /* number of messages currently on queue */
+ msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+ __pid_t msg_lspid; /* pid of last msgsnd() */
+ __pid_t msg_lrpid; /* pid of last msgrcv() */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+#ifdef __USE_MISC
+
+# define msg_cbytes __msg_cbytes
+
+/* ipcs ctl commands */
+# define MSG_STAT 11
+# define MSG_INFO 12
+
+/* buffer for msgctl calls IPC_INFO, MSG_INFO */
+struct msginfo
+ {
+ int msgpool;
+ int msgmap;
+ int msgmax;
+ int msgmnb;
+ int msgmni;
+ int msgssz;
+ int msgtql;
+ unsigned short int msgseg;
+ };
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/sem.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/sem.h
new file mode 100644
index 000000000..1c648cd19
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/sem.h
@@ -0,0 +1,92 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SEM_H
+# error "Never include <bits/sem.h> directly; use <sys/sem.h> instead."
+#endif
+
+#include <sys/types.h>
+
+/* Flags for `semop'. */
+#define SEM_UNDO 0x1000 /* undo the operation on exit */
+
+/* Commands for `semctl'. */
+#define GETPID 11 /* get sempid */
+#define GETVAL 12 /* get semval */
+#define GETALL 13 /* get all semval's */
+#define GETNCNT 14 /* get semncnt */
+#define GETZCNT 15 /* get semzcnt */
+#define SETVAL 16 /* set semval */
+#define SETALL 17 /* set all semval's */
+
+
+/* Data structure describing a set of semaphores. */
+struct semid_ds
+{
+ struct ipc_perm sem_perm; /* operation permission struct */
+#if __WORDSIZE == 32
+ unsigned int __unused1;
+#endif
+ __time_t sem_otime; /* last semop() time */
+#if __WORDSIZE == 32
+ unsigned int __unused2;
+#endif
+ __time_t sem_ctime; /* last time changed by semctl() */
+ unsigned long int sem_nsems; /* number of semaphores in set */
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+/* The user should define a union like the following to use it for arguments
+ for `semctl'.
+
+ union semun
+ {
+ int val; <= value for SETVAL
+ struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET
+ unsigned short int *array; <= array for GETALL & SETALL
+ struct seminfo *__buf; <= buffer for IPC_INFO
+ };
+
+ Previous versions of this file used to define this union but this is
+ incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether
+ one must define the union or not. */
+#define _SEM_SEMUN_UNDEFINED 1
+
+#ifdef __USE_MISC
+
+/* ipcs ctl cmds */
+# define SEM_STAT 18
+# define SEM_INFO 19
+
+struct seminfo
+{
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvmx;
+ int semaem;
+};
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/shm.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/shm.h
new file mode 100644
index 000000000..62560c0ca
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/shm.h
@@ -0,0 +1,113 @@
+/* Copyright (C) 1995, 1996, 1997, 2000, 2002, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple. */
+#define SHMLBA (__getpagesize ())
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a set of semaphores. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+#if __WORDSIZE == 32
+ unsigned int __unused1;
+#endif
+ __time_t shm_atime; /* time of last shmat() */
+#if __WORDSIZE == 32
+ unsigned int __unused2;
+#endif
+ __time_t shm_dtime; /* time of last shmdt() */
+#if __WORDSIZE == 32
+ unsigned int __unused3;
+#endif
+ __time_t shm_ctime; /* time of last change by shmctl() */
+#if __WORDSIZE == 32
+ unsigned int __unused4;
+#endif
+ size_t shm_segsz; /* size of segment in bytes */
+ __pid_t shm_cpid; /* pid of creator */
+ __pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned long __unused5;
+ unsigned long __unused6;
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */
+# define SHM_NORESERVE 010000 /* don't check for reservations */
+
+struct shminfo
+ {
+ unsigned long int shmmax;
+ unsigned long int shmmin;
+ unsigned long int shmmni;
+ unsigned long int shmseg;
+ unsigned long int shmall;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ unsigned long int __unused3;
+ unsigned long int __unused4;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/stat.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/stat.h
new file mode 100644
index 000000000..b020504d0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/stat.h
@@ -0,0 +1,267 @@
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+/* Versions of the `struct stat' data structure. */
+#define _STAT_VER_LINUX_OLD 1
+#define _STAT_VER_KERNEL 1
+#define _STAT_VER_SVR4 2
+#define _STAT_VER_LINUX 3
+#if __WORDSIZE == 32
+# define _STAT_VER _STAT_VER_LINUX
+#else
+# define _STAT_VER _STAT_VER_KERNEL
+#endif
+
+/* Versions of the `xmknod' interface. */
+#define _MKNOD_VER_LINUX 1
+#define _MKNOD_VER_SVR4 2
+#define _MKNOD_VER _MKNOD_VER_LINUX /* The bits defined below. */
+
+
+#if __WORDSIZE == 32
+
+struct stat
+ {
+ __dev_t st_dev; /* Device. */
+# ifndef __USE_FILE_OFFSET64
+ unsigned short int __pad1;
+ __ino_t st_ino; /* File serial number. */
+# else
+ __ino64_t st_ino; /* File serial number. */
+# endif
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned short int __pad2;
+# ifndef __USE_FILE_OFFSET64
+ __off_t st_size; /* Size of file, in bytes. */
+# else
+ __off64_t st_size; /* Size of file, in bytes. */
+# endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+# ifndef __USE_FILE_OFFSET64
+ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
+# else
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+# endif
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+ };
+
+
+# ifdef __USE_LARGEFILE64
+struct stat64
+ {
+ __dev_t st_dev; /* Device. */
+ __ino64_t st_ino; /* File serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned short int __pad2;
+ __off64_t st_size; /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+ };
+# endif /* __USE_LARGEFILE64 */
+
+#else /* __WORDSIZE == 32 */
+
+struct stat
+ {
+ __dev_t st_dev; /* Device. */
+# ifndef __USE_FILE_OFFSET64
+ __ino_t st_ino; /* File serial number. */
+# else
+ __ino64_t st_ino; /* File serial number. */
+# endif
+ __nlink_t st_nlink; /* Link count. */
+ __mode_t st_mode; /* File mode. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ int __pad2;
+ __dev_t st_rdev; /* Device number, if device. */
+# ifndef __USE_FILE_OFFSET64
+ __off_t st_size; /* Size of file, in bytes. */
+# else
+ __off64_t st_size; /* Size of file, in bytes. */
+# endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+# ifndef __USE_FILE_OFFSET64
+ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
+# else
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+# endif
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+ unsigned long int __unused6;
+ };
+
+# ifdef __USE_LARGEFILE64
+struct stat64
+ {
+ __dev_t st_dev; /* Device. */
+ __ino64_t st_ino; /* File serial number. */
+ __nlink_t st_nlink; /* Link count. */
+ __mode_t st_mode; /* File mode. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ int __pad2;
+ __dev_t st_rdev; /* Device number, if device. */
+ __off64_t st_size; /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+ unsigned long int __unused6;
+ };
+# endif /* __USE_LARGEFILE64 */
+#endif
+
+
+/* Tell code we have these members. */
+#define _STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+/* Nanosecond resolution time values are supported. */
+#define _STATBUF_ST_NSEC
+
+/* Encoding of the file mode. */
+
+#define __S_IFMT 0170000 /* These bits determine file type. */
+
+/* File types. */
+#define __S_IFDIR 0040000 /* Directory. */
+#define __S_IFCHR 0020000 /* Character device. */
+#define __S_IFBLK 0060000 /* Block device. */
+#define __S_IFREG 0100000 /* Regular file. */
+#define __S_IFIFO 0010000 /* FIFO. */
+#define __S_IFLNK 0120000 /* Symbolic link. */
+#define __S_IFSOCK 0140000 /* Socket. */
+
+/* POSIX.1b objects. Note that these macros always evaluate to zero. But
+ they do it by enforcing the correct use of the macros. */
+#define __S_TYPEISMQ(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
+
+/* Protection bits. */
+
+#define __S_ISUID 04000 /* Set user ID on execution. */
+#define __S_ISGID 02000 /* Set group ID on execution. */
+#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
+#define __S_IREAD 0400 /* Read by owner. */
+#define __S_IWRITE 0200 /* Write by owner. */
+#define __S_IEXEC 0100 /* Execute by owner. */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/termios.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/termios.h
new file mode 100644
index 000000000..7aac02dc5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/termios.h
@@ -0,0 +1,319 @@
+/* Copyright (C) 1997,1999,2001,2003,2004,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _TERMIOS_H
+# error "Never include <bits/termios.h> directly; use <termios.h> instead."
+#endif
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+/*
+ * termios type and macro definitions. Be careful about adding stuff
+ * to this file since it's used in GNU libc and there are strict rules
+ * concerning namespace pollution.
+ */
+
+#define NCCS 32
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline (== c_cc[19]) */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
+#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VMIN 5
+#define VEOL 6
+#define VTIME 7
+#define VEOL2 8
+#define VSWTC 9
+
+#define VWERASE 10
+#define VREPRINT 11
+#define VSUSP 12
+#define VSTART 13
+#define VSTOP 14
+#define VLNEXT 15
+#define VDISCARD 16
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IXON 0001000
+#define IXOFF 0002000
+#define IXANY 0004000
+#define IUCLC 0010000
+#define IMAXBEL 0020000
+#define IUTF8 0040000
+
+/* c_oflag bits */
+#define OPOST 0000001
+#define ONLCR 0000002
+#define OLCUC 0000004
+
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+
+#define OFILL 00000100
+#define OFDEL 00000200
+#if defined __USE_MISC || defined __USE_XOPEN
+# define NLDLY 00001400
+# define NL0 00000000
+# define NL1 00000400
+# define NL2 00001000
+# define NL3 00001400
+# define TABDLY 00006000
+# define TAB0 00000000
+# define TAB1 00002000
+# define TAB2 00004000
+# define TAB3 00006000
+# define CRDLY 00030000
+# define CR0 00000000
+# define CR1 00010000
+# define CR2 00020000
+# define CR3 00030000
+# define FFDLY 00040000
+# define FF0 00000000
+# define FF1 00040000
+# define BSDLY 00100000
+# define BS0 00000000
+# define BS1 00100000
+#endif
+#define VTDLY 00200000
+#define VT0 00000000
+#define VT1 00200000
+
+#ifdef __USE_MISC
+# define XTABS 00006000
+#endif
+
+/* c_cflag bit meaning */
+#ifdef __USE_MISC
+# define CBAUD 0000377
+#endif
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#ifdef __USE_MISC
+# define EXTA B19200
+# define EXTB B38400
+# define CBAUDEX 0000020
+#endif
+#define B57600 00020
+#define B115200 00021
+#define B230400 00022
+#define B460800 00023
+#define B500000 00024
+#define B576000 00025
+#define B921600 00026
+#define B1000000 00027
+#define B1152000 00030
+#define B1500000 00031
+#define B2000000 00032
+#define B2500000 00033
+#define B3000000 00034
+#define B3500000 00035
+#define B4000000 00036
+#define __MAX_BAUD B4000000
+
+#define CSIZE 00001400
+#define CS5 00000000
+#define CS6 00000400
+#define CS7 00001000
+#define CS8 00001400
+
+#define CSTOPB 00002000
+#define CREAD 00004000
+#define PARENB 00010000
+#define PARODD 00020000
+#define HUPCL 00040000
+
+#define CLOCAL 00100000
+#ifdef __USE_MISC
+# define CMSPAR 010000000000 /* mark or space (stick) parity */
+# define CRTSCTS 020000000000 /* flow control */
+#endif
+
+/* c_lflag bits */
+#define ISIG 0x00000080
+#define ICANON 0x00000100
+#if defined __USE_MISC || defined __USE_XOPEN
+# define XCASE 0x00004000
+#endif
+#define ECHO 0x00000008
+#define ECHOE 0x00000002
+#define ECHOK 0x00000004
+#define ECHONL 0x00000010
+#define NOFLSH 0x80000000
+#define TOSTOP 0x00400000
+#ifdef __USE_MISC
+# define ECHOCTL 0x00000040
+# define ECHOPRT 0x00000020
+# define ECHOKE 0x00000001
+# define FLUSHO 0x00800000
+# define PENDIN 0x20000000
+#endif
+#define IEXTEN 0x00000400
+
+/* Values for the ACTION argument to `tcflow'. */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* Values for the QUEUE_SELECTOR argument to `tcflush'. */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+struct sgttyb {
+ char sg_ispeed;
+ char sg_ospeed;
+ char sg_erase;
+ char sg_kill;
+ short sg_flags;
+};
+
+struct tchars {
+ char t_intrc;
+ char t_quitc;
+ char t_startc;
+ char t_stopc;
+ char t_eofc;
+ char t_brkc;
+};
+
+struct ltchars {
+ char t_suspc;
+ char t_dsuspc;
+ char t_rprntc;
+ char t_flushc;
+ char t_werasc;
+ char t_lnextc;
+};
+
+/* Used for packet mode */
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 10
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+/* c_cc characters */
+#define _VINTR 0
+#define _VQUIT 1
+#define _VERASE 2
+#define _VKILL 3
+#define _VEOF 4
+#define _VMIN 5
+#define _VEOL 6
+#define _VTIME 7
+#define _VEOL2 8
+#define _VSWTC 9
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+
+/* line disciplines */
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6 /* X.25 async */
+#define N_6PACK 7
+#define N_MASC 8 /* Mobitex module */
+#define N_R3964 9 /* Simatic R3964 module */
+#define N_PROFIBUS_FDL 10 /* Profibus */
+#define N_IRDA 11 /* Linux IR */
+#define N_SMSBLOCK 12 /* SMS block mode */
+#define N_HDLC 13 /* synchronous HDLC */
+#define N_SYNC_PPP 14 /* synchronous PPP */
+#define N_HCI 15 /* Bluetooth HCI UART */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h b/libc/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h
new file mode 100644
index 000000000..cf934234f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h
@@ -0,0 +1,19 @@
+/* Determine the wordsize from the preprocessor defines. */
+
+#if defined __powerpc64__
+# define __WORDSIZE 64
+# define __WORDSIZE_COMPAT32 1
+#else
+# define __WORDSIZE 32
+#endif
+
+#if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL
+
+/* Signal the glibc ABI didn't used to have a `long double'.
+ The changes all the `long double' function variants to be redirects
+ to the double functions. */
+# define __LONG_DOUBLE_MATH_OPTIONAL 1
+# ifndef __LONG_DOUBLE_128__
+# define __NO_LONG_DOUBLE_MATH 1
+# endif
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/chown.c b/libc/sysdeps/unix/sysv/linux/powerpc/chown.c
new file mode 100644
index 000000000..fdcbd3683
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/chown.c
@@ -0,0 +1,132 @@
+/* chown() compatibility.
+ Copyright (C) 1998, 2000, 2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sysdep.h>
+#include <stdlib.h>
+
+#include <kernel-features.h>
+
+/*
+ In Linux 2.1.x the chown functions have been changed. A new function lchown
+ was introduced. The new chown now follows symlinks - the old chown and the
+ new lchown do not follow symlinks.
+ This file emulates chown() under the old kernels.
+*/
+
+int
+__chown (const char *file, uid_t owner, gid_t group)
+{
+#if __ASSUME_LCHOWN_SYSCALL
+ return INLINE_SYSCALL (chown, 3, file, owner, group);
+#else
+ int err;
+ int old_errno;
+ char link[PATH_MAX + 2];
+ char path[2 * PATH_MAX + 4];
+ int loopct;
+ size_t filelen;
+ static int libc_old_chown = 0 /* -1=old linux, 1=new linux, 0=unknown */;
+
+ if (libc_old_chown == 1)
+ return INLINE_SYSCALL (chown, 3, __ptrvalue (file), owner, group);
+
+ old_errno = errno;
+
+# ifdef __NR_lchown
+ if (libc_old_chown == 0)
+ {
+ err = INLINE_SYSCALL (chown, 3, __ptrvalue (file), owner, group);
+ if (err != -1 || errno != ENOSYS)
+ {
+ libc_old_chown = 1;
+ return err;
+ }
+ libc_old_chown = -1;
+ }
+# endif
+
+ err = __readlink (file, link, PATH_MAX + 1);
+ if (err == -1)
+ {
+ __set_errno (old_errno);
+ return __lchown (file, owner, group);
+ }
+
+ filelen = strlen (file) + 1;
+ if (filelen > sizeof (path))
+ {
+ __set_errno (ENAMETOOLONG);
+ return -1;
+ }
+ memcpy (path, file, filelen);
+
+ /* 'The system has an arbitrary limit...' In practise, we'll hit
+ ENAMETOOLONG before this, usually. */
+ for (loopct = 0; loopct < 128; ++loopct)
+ {
+ size_t linklen;
+
+ if (err >= PATH_MAX + 1)
+ {
+ __set_errno (ENAMETOOLONG);
+ return -1;
+ }
+
+ link[err] = 0; /* Null-terminate string, just-in-case. */
+
+ linklen = strlen (link) + 1;
+
+ if (link[0] == '/')
+ memcpy (path, link, linklen);
+ else
+ {
+ filelen = strlen (path);
+
+ while (filelen > 1 && path[filelen - 1] == '/')
+ --filelen;
+ while (filelen > 0 && path[filelen - 1] != '/')
+ --filelen;
+ if (filelen + linklen > sizeof (path))
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+ memcpy (path + filelen, link, linklen);
+ }
+
+ err = __readlink (path, link, PATH_MAX + 1);
+
+ if (err == -1)
+ {
+ __set_errno (old_errno);
+ return __lchown (path, owner, group);
+ }
+ }
+ __set_errno (ELOOP);
+ return -1;
+#endif
+}
+libc_hidden_def (__chown)
+
+#include <shlib-compat.h>
+versioned_symbol (libc, __chown, chown, GLIBC_2_1);
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/configure b/libc/sysdeps/unix/sysv/linux/powerpc/configure
new file mode 100644
index 000000000..070bf5cae
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/configure
@@ -0,0 +1,135 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/unix/sysv/linux/powerpc/.
+
+
+echo "$as_me:$LINENO: checking whether $CC $CFLAGS -mlong-double-128 uses IBM extended format" >&5
+echo $ECHO_N "checking whether $CC $CFLAGS -mlong-double-128 uses IBM extended format... $ECHO_C" >&6
+if test "${libc_cv_mlong_double_128ibm+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -mlong-double-128"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <float.h>
+int
+main ()
+{
+
+#if LDBL_MANT_DIG != 106
+# error "compiler doesn't implement IBM extended format of long double"
+#endif
+long double foobar (long double x) { return x; }
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_mlong_double_128ibm=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+libc_cv_mlong_double_128ibm=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+CFLAGS="$save_CFLAGS"
+fi
+echo "$as_me:$LINENO: result: $libc_cv_mlong_double_128ibm" >&5
+echo "${ECHO_T}$libc_cv_mlong_double_128ibm" >&6
+
+if test "$libc_cv_mlong_double_128ibm" = no; then
+ echo "$as_me:$LINENO: checking whether $CC $CFLAGS supports -mabi=ibmlongdouble" >&5
+echo $ECHO_N "checking whether $CC $CFLAGS supports -mabi=ibmlongdouble... $ECHO_C" >&6
+if test "${libc_cv_mabi_ibmlongdouble+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mlong-double-128 -mabi=ibmlongdouble"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <float.h>
+int
+main ()
+{
+
+#if LDBL_MANT_DIG != 106
+# error "compiler doesn't implement IBM extended format of long double"
+#endif
+long double foobar (long double x) { return x; }
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_mabi_ibmlongdouble=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+libc_cv_mabi_ibmlongdouble=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="$save_CFLAGS"
+fi
+echo "$as_me:$LINENO: result: $libc_cv_mabi_ibmlongdouble" >&5
+echo "${ECHO_T}$libc_cv_mabi_ibmlongdouble" >&6
+
+ if test "$libc_cv_mabi_ibmlongdouble" = yes; then
+ CFLAGS="$CFLAGS -mabi=ibmlongdouble"
+ else
+ { { echo "$as_me:$LINENO: error: this configuration requires -mlong-double-128 IBM extended format support" >&5
+echo "$as_me: error: this configuration requires -mlong-double-128 IBM extended format support" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/configure.in b/libc/sysdeps/unix/sysv/linux/powerpc/configure.in
new file mode 100644
index 000000000..1768ab1f9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/configure.in
@@ -0,0 +1,37 @@
+sinclude(./aclocal.m4)dnl Autoconf lossage
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/unix/sysv/linux/powerpc/.
+
+AC_CACHE_CHECK(whether $CC $CFLAGS -mlong-double-128 uses IBM extended format,
+ libc_cv_mlong_double_128ibm, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -mlong-double-128"
+AC_TRY_COMPILE([#include <float.h>], [
+#if LDBL_MANT_DIG != 106
+# error "compiler doesn't implement IBM extended format of long double"
+#endif
+long double foobar (long double x) { return x; }],
+ libc_cv_mlong_double_128ibm=yes,
+ libc_cv_mlong_double_128ibm=no)
+CFLAGS="$save_CFLAGS"])
+
+if test "$libc_cv_mlong_double_128ibm" = no; then
+ AC_CACHE_CHECK(whether $CC $CFLAGS supports -mabi=ibmlongdouble,
+ libc_cv_mabi_ibmlongdouble, [dnl
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mlong-double-128 -mabi=ibmlongdouble"
+ AC_TRY_COMPILE([#include <float.h>], [
+#if LDBL_MANT_DIG != 106
+# error "compiler doesn't implement IBM extended format of long double"
+#endif
+long double foobar (long double x) { return x; }],
+ libc_cv_mabi_ibmlongdouble=yes,
+ libc_cv_mabi_ibmlongdouble=no)
+ CFLAGS="$save_CFLAGS"])
+
+ if test "$libc_cv_mabi_ibmlongdouble" = yes; then
+ CFLAGS="$CFLAGS -mabi=ibmlongdouble"
+ else
+ AC_MSG_ERROR([this configuration requires -mlong-double-128 IBM extended format support])
+ fi
+fi
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/dl-brk.S b/libc/sysdeps/unix/sysv/linux/powerpc/dl-brk.S
new file mode 100644
index 000000000..eeb96544e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/dl-brk.S
@@ -0,0 +1 @@
+#include <brk.S>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/dl-cache.h b/libc/sysdeps/unix/sysv/linux/powerpc/dl-cache.h
new file mode 100644
index 000000000..766bba426
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/dl-cache.h
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/sparc/dl-cache.h>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c b/libc/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
new file mode 100644
index 000000000..7c02c6898
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
@@ -0,0 +1,71 @@
+/* Operating system support for run-time dynamic linker. Linux/PPC version.
+ Copyright (C) 1997, 1998, 2001, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <config.h>
+#include <kernel-features.h>
+#include <ldsodefs.h>
+
+extern int __cache_line_size;
+weak_extern (__cache_line_size)
+
+/* Scan the Aux Vector for the "Data Cache Block Size" entry. If found
+ verify that the static extern __cache_line_size is defined by checking
+ for not NULL. If it is defined then assign the cache block size
+ value to __cache_line_size. */
+#define DL_PLATFORM_AUXV \
+ case AT_DCACHEBSIZE: \
+ { \
+ int *cls = & __cache_line_size; \
+ if (cls != NULL) \
+ *cls = av->a_un.a_val; \
+ } \
+ break;
+
+#ifndef __ASSUME_STD_AUXV
+
+/* The PowerPC's auxiliary argument block gets aligned to a 16-byte
+ boundary. This is history and impossible to change compatibly. */
+
+#define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp) \
+ do { \
+ char **_tmp; \
+ size_t _test; \
+ (argc) = *(long int *) cookie; \
+ (argv) = (char **) cookie + 1; \
+ (envp) = (argv) + (argc) + 1; \
+ for (_tmp = (envp); *_tmp; ++_tmp) \
+ continue; \
+ /* The following '++' is important! */ \
+ ++_tmp; \
+ \
+ _test = (size_t)_tmp; \
+ _test = (_test + 0xf) & ~0xf; \
+ /* Under some circumstances, MkLinux (up to at least DR3a5) \
+ omits the padding. To work around this, we make a \
+ basic sanity check of the argument vector. Of \
+ course, this means that in future, the argument \
+ vector will have to be laid out to allow for this \
+ test :-(. */ \
+ if (((ElfW(auxv_t) *)_test)->a_type <= 0x10) \
+ _tmp = (char **)_test; \
+ (auxp) = (ElfW(auxv_t) *) _tmp; \
+ } while (0)
+#endif
+
+#include <sysdeps/unix/sysv/linux/dl-sysdep.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/dl-vdso.c b/libc/sysdeps/unix/sysv/linux/powerpc/dl-vdso.c
new file mode 100644
index 000000000..e1be09773
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/dl-vdso.c
@@ -0,0 +1,59 @@
+/* ELF symbol resolve functions for VDSO objects.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "config.h"
+#include <dl-hash.h>
+#include <ldsodefs.h>
+
+
+void *
+internal_function
+_dl_vdso_vsym (const char *name, const char *version)
+{
+ struct link_map *map = GLRO (dl_sysinfo_map);
+ void *value = NULL;
+
+
+ if (map != NULL)
+ {
+ /* Use a WEAK REF so we don't error out if the symbol is not found. */
+ ElfW (Sym) wsym;
+ memset (&wsym, 0, sizeof (ElfW (Sym)));
+ wsym.st_info = (unsigned char) ELFW (ST_INFO (STB_WEAK, STT_NOTYPE));
+
+ /* Compute hash value to the version string. */
+ struct r_found_version vers;
+ vers.name = version;
+ vers.hidden = 1;
+ vers.hash = _dl_elf_hash (version);
+ /* We don't have a specific file where the symbol can be found. */
+ vers.filename = NULL;
+
+ /* Search the scope of the vdso map. */
+ const ElfW (Sym) *ref = &wsym;
+ lookup_t result = GLRO (dl_lookup_symbol_x) (name, map, &ref,
+ map->l_local_scope,
+ &vers, 0, 0, NULL);
+
+ if (ref != NULL)
+ value = DL_SYMBOL_ADDRESS (result, ref);
+ }
+
+ return value;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/dl-vdso.h b/libc/sysdeps/unix/sysv/linux/powerpc/dl-vdso.h
new file mode 100644
index 000000000..a7dcb2e5f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/dl-vdso.h
@@ -0,0 +1,27 @@
+/* ELF symbol resolve functions for VDSO objects.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DL_VDSO_H
+#define _DL_VDSO_H 1
+
+/* Functions for resolving symbols in the VDSO link map. */
+extern void *_dl_vdso_vsym (const char *name, const char *version)
+ internal_function attribute_hidden;
+
+#endif /* dl-vdso.h */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/fchownat.c b/libc/sysdeps/unix/sysv/linux/powerpc/fchownat.c
new file mode 100644
index 000000000..f1b9b4db4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/fchownat.c
@@ -0,0 +1,223 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sysdep.h>
+#include <stdlib.h>
+
+#include <kernel-features.h>
+
+/*
+ In Linux 2.1.x the chown functions have been changed. A new function lchown
+ was introduced. The new chown now follows symlinks - the old chown and the
+ new lchown do not follow symlinks.
+ This file emulates chown() under the old kernels.
+*/
+
+int
+fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
+{
+ int result;
+
+#ifdef __NR_fchownat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INLINE_SYSCALL (fchownat, 5, fd, file, owner, group, flag);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ if (flag & ~AT_SYMLINK_NOFOLLOW)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+# if __ASSUME_LCHOWN_SYSCALL
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lchown, err, 3, file, owner, group);
+ else
+ result = INTERNAL_SYSCALL (chown, err, 3, file, owner, group);
+# else
+ char link[PATH_MAX + 2];
+ char path[2 * PATH_MAX + 4];
+ int loopct;
+ size_t filelen;
+ static int libc_old_chown = 0 /* -1=old linux, 1=new linux, 0=unknown */;
+
+ if (libc_old_chown == 1)
+ {
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lchown, err, 3, __ptrvalue (file), owner,
+ group);
+ else
+ result = INTERNAL_SYSCALL (chown, err, 3, __ptrvalue (file), owner,
+ group);
+ goto out;
+ }
+
+# ifdef __NR_lchown
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ {
+ result = INTERNAL_SYSCALL (lchown, err, 3, __ptrvalue (file), owner,
+ group);
+ goto out;
+ }
+
+ if (libc_old_chown == 0)
+ {
+ result = INTERNAL_SYSCALL (chown, err, 3, __ptrvalue (file), owner,
+ group);
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return result;
+ if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ {
+ libc_old_chown = 1;
+ goto fail;
+ }
+ libc_old_chown = -1;
+ }
+# else
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ {
+ result = INTERNAL_SYSCALL (chown, err, 3, __ptrvalue (file), owner,
+ group);
+ goto out;
+ }
+# endif
+
+ result = __readlink (file, link, PATH_MAX + 1);
+ if (result == -1)
+ {
+# ifdef __NR_lchown
+ result = INTERNAL_SYSCALL (lchown, err, 3, __ptrvalue (file), owner,
+ group);
+# else
+ result = INTERNAL_SYSCALL (chown, err, 3, __ptrvalue (file), owner,
+ group);
+# endif
+ goto out;
+ }
+
+ filelen = strlen (file) + 1;
+ if (filelen > sizeof (path))
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+ memcpy (path, file, filelen);
+
+ /* 'The system has an arbitrary limit...' In practise, we'll hit
+ ENAMETOOLONG before this, usually. */
+ for (loopct = 0; loopct < 128; ++loopct)
+ {
+ size_t linklen;
+
+ if (result >= PATH_MAX + 1)
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ link[result] = 0; /* Null-terminate string, just-in-case. */
+
+ linklen = strlen (link) + 1;
+
+ if (link[0] == '/')
+ memcpy (path, link, linklen);
+ else
+ {
+ filelen = strlen (path);
+
+ while (filelen > 1 && path[filelen - 1] == '/')
+ --filelen;
+ while (filelen > 0 && path[filelen - 1] != '/')
+ --filelen;
+ if (filelen + linklen > sizeof (path))
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+ memcpy (path + filelen, link, linklen);
+ }
+
+ result = __readlink (path, link, PATH_MAX + 1);
+
+ if (result == -1)
+ {
+# ifdef __NR_lchown
+ result = INTERNAL_SYSCALL (lchown, err, 3, path, owner, group);
+# else
+ result = INTERNAL_SYSCALL (chown, err, 3, path, owner, group);
+# endif
+ goto out;
+ }
+ }
+ __set_errno (ELOOP);
+ return -1;
+
+ out:
+# endif
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ {
+# if !__ASSUME_LCHOWN_SYSCALL
+ fail:
+# endif
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
+ result = -1;
+ }
+
+ return result;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c b/libc/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c
new file mode 100644
index 000000000..6d2e766aa
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c
@@ -0,0 +1,117 @@
+/* Get frequency of the system processor. powerpc/Linux version.
+ Copyright (C) 2000, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <libc-internal.h>
+#include <sysdep.h>
+#include <bits/libc-vdso.h>
+
+hp_timing_t
+__get_clockfreq (void)
+{
+ /* We read the information from the /proc filesystem. /proc/cpuinfo
+ contains at least one line like:
+ timebase : 33333333
+ We search for this line and convert the number into an integer. */
+ static hp_timing_t timebase_freq;
+ hp_timing_t result = 0L;
+
+ /* If this function was called before, we know the result. */
+ if (timebase_freq != 0)
+ return timebase_freq;
+
+ /* If we can use the vDSO to obtain the timebase even better. */
+#ifdef SHARED
+ INTERNAL_SYSCALL_DECL (err);
+ timebase_freq = INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, 0);
+ if (INTERNAL_SYSCALL_ERROR_P (timebase_freq, err)
+ && INTERNAL_SYSCALL_ERRNO (timebase_freq, err) == ENOSYS)
+#endif
+ {
+ int fd = open ("/proc/cpuinfo", O_RDONLY);
+
+ if (__builtin_expect (fd != -1, 1))
+ {
+ /* The timebase will be in the 1st 1024 bytes for systems with up
+ to 8 processors. If the first read returns less then 1024
+ bytes read, we have the whole cpuinfo and can start the scan.
+ Otherwise we will have to read more to insure we have the
+ timebase value in the scan. */
+ char buf[1024];
+ ssize_t n;
+
+ n = read (fd, buf, sizeof (buf));
+ if (n == sizeof (buf))
+ {
+ /* We are here because the 1st read returned exactly sizeof
+ (buf) bytes. This implies that we are not at EOF and may
+ not have read the timebase value yet. So we need to read
+ more bytes until we know we have EOF. We copy the lower
+ half of buf to the upper half and read sizeof (buf)/2
+ bytes into the lower half of buf and repeat until we
+ reach EOF. We can assume that the timebase will be in
+ the last 512 bytes of cpuinfo, so two 512 byte half_bufs
+ will be sufficient to contain the timebase and will
+ handle the case where the timebase spans the half_buf
+ boundry. */
+ const ssize_t half_buf = sizeof (buf) / 2;
+ while (n >= half_buf)
+ {
+ memcpy (buf, buf + half_buf, half_buf);
+ n = read (fd, buf + half_buf, half_buf);
+ }
+ if (n >= 0)
+ n += half_buf;
+ }
+
+ if (__builtin_expect (n, 1) > 0)
+ {
+ char *mhz = memmem (buf, n, "timebase", 7);
+
+ if (__builtin_expect (mhz != NULL, 1))
+ {
+ char *endp = buf + n;
+
+ /* Search for the beginning of the string. */
+ while (mhz < endp && (*mhz < '0' || *mhz > '9')
+ && *mhz != '\n')
+ ++mhz;
+
+ while (mhz < endp && *mhz != '\n')
+ {
+ if (*mhz >= '0' && *mhz <= '9')
+ {
+ result *= 10;
+ result += *mhz - '0';
+ }
+
+ ++mhz;
+ }
+ }
+ timebase_freq = result;
+ }
+ close (fd);
+ }
+ }
+
+ return timebase_freq;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/getdents64.c b/libc/sysdeps/unix/sysv/linux/powerpc/getdents64.c
new file mode 100644
index 000000000..0c75fb5a0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/getdents64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getdents64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/getmsg.c b/libc/sysdeps/unix/sysv/linux/powerpc/getmsg.c
new file mode 100644
index 000000000..3a1fa0852
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/getmsg.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getmsg.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/getrlimit.c b/libc/sysdeps/unix/sysv/linux/powerpc/getrlimit.c
new file mode 100644
index 000000000..fc06dbd64
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/getrlimit.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getrlimit.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/getrlimit64.c b/libc/sysdeps/unix/sysv/linux/powerpc/getrlimit64.c
new file mode 100644
index 000000000..fef018f47
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/getrlimit64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getrlimit64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
new file mode 100644
index 000000000..b381baa28
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bp-checks.h>
+#include <stddef.h>
+#include <sys/time.h>
+#include <time.h>
+#include <hp-timing.h>
+
+#undef __gettimeofday
+#include <bits/libc-vdso.h>
+
+/* Get the current time of day and timezone information,
+ putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
+ Returns 0 on success, -1 on errors. */
+
+int
+__gettimeofday (tv, tz)
+ struct timeval *tv;
+ struct timezone *tz;
+{
+ return INLINE_VSYSCALL (gettimeofday, 2, CHECK_1 (tv), CHECK_1 (tz));
+}
+
+INTDEF (__gettimeofday)
+weak_alias (__gettimeofday, gettimeofday)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/ioctl.c b/libc/sysdeps/unix/sysv/linux/powerpc/ioctl.c
new file mode 100644
index 000000000..88ea9ff08
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/ioctl.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1998, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdarg.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sysdep.h>
+
+/* The user-visible size of struct termios has changed. Catch ioctl calls
+ using the new-style struct termios, and translate them to old-style. */
+
+int
+__ioctl (int fd, unsigned long int request, ...)
+{
+ void *arg;
+ va_list ap;
+ int result;
+
+ va_start (ap, request);
+ arg = va_arg (ap, void *);
+
+ switch (request)
+ {
+ case TCGETS:
+ result = __tcgetattr (fd, (struct termios *) arg);
+ break;
+
+ case TCSETS:
+ result = tcsetattr (fd, TCSANOW, (struct termios *) arg);
+ break;
+
+ case TCSETSW:
+ result = tcsetattr (fd, TCSADRAIN, (struct termios *) arg);
+ break;
+
+ case TCSETSF:
+ result = tcsetattr (fd, TCSAFLUSH, (struct termios *) arg);
+ break;
+
+ default:
+ result = INLINE_SYSCALL (ioctl, 3, fd, request, arg);
+ break;
+ }
+
+ va_end (ap);
+
+ return result;
+}
+weak_alias (__ioctl, ioctl)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/ipc_priv.h b/libc/sysdeps/unix/sysv/linux/powerpc/ipc_priv.h
new file mode 100644
index 000000000..9b85386a7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/ipc_priv.h
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/alpha/ipc_priv.h>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/kernel_termios.h b/libc/sysdeps/unix/sysv/linux/powerpc/kernel_termios.h
new file mode 100644
index 000000000..4892cb56a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/kernel_termios.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _KERNEL_TERMIOS_H
+#define _KERNEL_TERMIOS_H 1
+
+/* We need the definition of tcflag_t, cc_t, and speed_t. */
+#include <termios.h>
+
+#define __KERNEL_NCCS 19
+
+struct __kernel_termios
+ {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_cc[__KERNEL_NCCS]; /* control characters */
+ cc_t c_line; /* line discipline */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+ };
+
+#define _HAVE_C_ISPEED 1
+#define _HAVE_C_OSPEED 1
+
+/* We have the kernel termios structure, so we can presume this code knows
+ what it's doing... */
+
+#undef TCGETS
+#undef TCSETS
+#undef TCSETSW
+#undef TCSETSF
+#define TCGETS _IOR ('t', 19, struct __kernel_termios)
+#define TCSETS _IOW ('t', 20, struct __kernel_termios)
+#define TCSETSW _IOW ('t', 21, struct __kernel_termios)
+#define TCSETSF _IOW ('t', 22, struct __kernel_termios)
+
+#endif /* kernel_termios.h */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/lchown.S b/libc/sysdeps/unix/sysv/linux/powerpc/lchown.S
new file mode 100644
index 000000000..78f892ee3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/lchown.S
@@ -0,0 +1,39 @@
+/* lchown system call.
+ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Some old kernel headers call lchown() 'chown'. The number is
+ the same. */
+
+#include <sysdep.h>
+
+#ifdef __NR_lchown
+ PSEUDO (__lchown, lchown, 3)
+#else
+ PSEUDO (__lchown, chown, 3)
+#endif
+ ret
+ PSEUDO_END(__lchown)
+ weak_alias (__lchown, lchown)
+
+#ifdef SHARED
+#include <shlib-compat.h>
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+compat_symbol (libc, __lchown, chown, GLIBC_2_0)
+# endif
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/ldconfig.h b/libc/sysdeps/unix/sysv/linux/powerpc/ldconfig.h
new file mode 100644
index 000000000..ad67f3fcf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/ldconfig.h
@@ -0,0 +1,27 @@
+/* ldconfig default paths and libraries. Linux/PowerPC version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/ldconfig.h>
+
+#define SYSDEP_KNOWN_INTERPRETER_NAMES \
+ { "/lib/ld.so.1", FLAG_ELF_LIBC6 }, \
+ { "/lib64/ld64.so.1", FLAG_ELF_LIBC6 },
+#define SYSDEP_KNOWN_LIBRARY_NAMES \
+ { "libc.so.6", FLAG_ELF_LIBC6 }, \
+ { "libm.so.6", FLAG_ELF_LIBC6 },
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/ldd-rewrite.sed b/libc/sysdeps/unix/sysv/linux/powerpc/ldd-rewrite.sed
new file mode 100644
index 000000000..9039b6954
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/ldd-rewrite.sed
@@ -0,0 +1,15 @@
+/LD_TRACE_LOADED_OBJECTS=1/a\
+add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out"
+
+# ldd is generated from elf/ldd.bash.in with the name
+# of ld.so as generated in Makeconfig
+
+# that name is replaced by a pair referring to both
+# the 32bit and 64bit dynamic linker.
+
+# /lib(64|)/*(64|).so* is replaced with /lib/*.so* and /lib64/*64.so*
+# this works for /lib64/ld64.so.x and /lib/ld.so.x as input
+s_lib64_lib_
+s_64\.so_\.so_
+s_^RTLDLIST=\(.*lib\)\(/[^/]*\)\(\.so\.[0-9.]*\)[[:blank:]]*$_RTLDLIST="\1\2\3 \164\264\3"_
+
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/libc/sysdeps/unix/sysv/linux/powerpc/libc-start.c
new file mode 100644
index 000000000..a8005c116
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/libc-start.c
@@ -0,0 +1,130 @@
+/* Copyright (C) 1998,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <bp-start.h>
+#include <bp-sym.h>
+
+extern int __cache_line_size;
+weak_extern (__cache_line_size)
+/* The main work is done in the generic function. */
+#define LIBC_START_MAIN generic_start_main
+#define LIBC_START_DISABLE_INLINE
+#define LIBC_START_MAIN_AUXVEC_ARG
+#define MAIN_AUXVEC_ARG
+#define INIT_MAIN_ARGS
+#include <csu/libc-start.c>
+
+struct startup_info
+ {
+ void *__unbounded sda_base;
+ int (*main) (int, char **, char **, void *);
+ int (*init) (int, char **, char **, void *);
+ void (*fini) (void);
+ };
+
+
+#ifdef SHARED
+# include <sys/time.h>
+# include <dl-vdso.h>
+# undef __gettimeofday
+# undef __clock_gettime
+# undef __clock_getres
+# include <bits/libc-vdso.h>
+
+void *__vdso_gettimeofday;
+void *__vdso_clock_gettime;
+void *__vdso_clock_getres;
+void *__vdso_get_tbfreq;
+
+static inline void _libc_vdso_platform_setup (void)
+ {
+ __vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday",
+ "LINUX_2.6.15");
+
+ __vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime",
+ "LINUX_2.6.15");
+
+ __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres",
+ "LINUX_2.6.15");
+
+ __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_vdso_get_tbfreq",
+ "LINUX_2.6.15");
+ }
+#endif
+
+int
+/* GKM FIXME: GCC: this should get __BP_ prefix by virtue of the
+ BPs in the arglist of startup_info.main and startup_info.init. */
+ BP_SYM (__libc_start_main) (int argc, char *__unbounded *__unbounded ubp_av,
+ char *__unbounded *__unbounded ubp_ev,
+ ElfW (auxv_t) * __unbounded auxvec,
+ void (*rtld_fini) (void),
+ struct startup_info *__unbounded stinfo,
+ char *__unbounded *__unbounded stack_on_entry)
+{
+#if __BOUNDED_POINTERS__
+ char **argv;
+#else
+# define argv ubp_av
+#endif
+
+ /* the PPC SVR4 ABI says that the top thing on the stack will
+ be a NULL pointer, so if not we assume that we're being called
+ as a statically-linked program by Linux... */
+ if (*stack_on_entry != NULL)
+ {
+ char *__unbounded * __unbounded temp;
+ /* ...in which case, we have argc as the top thing on the
+ stack, followed by argv (NULL-terminated), envp (likewise),
+ and the auxilary vector. */
+ /* 32/64-bit agnostic load from stack */
+ argc = *(long int *__unbounded) stack_on_entry;
+ ubp_av = stack_on_entry + 1;
+ ubp_ev = ubp_av + argc + 1;
+#ifdef HAVE_AUX_VECTOR
+ temp = ubp_ev;
+ while (*temp != NULL)
+ ++temp;
+ auxvec = (ElfW (auxv_t) *)++ temp;
+#endif
+ rtld_fini = NULL;
+ }
+
+ /* Initialize the __cache_line_size variable from the aux vector. */
+ for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av)
+ switch (av->a_type)
+ {
+ case AT_DCACHEBSIZE:
+ {
+ int *cls = &__cache_line_size;
+ if (cls != NULL)
+ *cls = av->a_un.a_val;
+ }
+ break;
+ }
+#ifdef SHARED
+ /* Resolve and initialize function pointers for VDSO functions. */
+ _libc_vdso_platform_setup ();
+#endif
+ return generic_start_main (stinfo->main, argc, ubp_av, auxvec,
+ stinfo->init, stinfo->fini, rtld_fini,
+ stack_on_entry);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/nldbl-abi.h b/libc/sysdeps/unix/sysv/linux/powerpc/nldbl-abi.h
new file mode 100644
index 000000000..bd985cc59
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/nldbl-abi.h
@@ -0,0 +1,8 @@
+/* ABI version for long double switch.
+ This is used by the Versions and math_ldbl_opt.h files in
+ sysdeps/ieee754/ldbl-opt/. It gives the ABI version where
+ long double == double was replaced with proper long double
+ for libm *l functions and libc functions using long double. */
+
+#define NLDBL_VERSION GLIBC_2.4
+#define LONG_DOUBLE_COMPAT_VERSION GLIBC_2_4
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/oldgetrlimit64.c b/libc/sysdeps/unix/sysv/linux/powerpc/oldgetrlimit64.c
new file mode 100644
index 000000000..4c27e957b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/oldgetrlimit64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile
new file mode 100644
index 000000000..966a7689e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),resource)
+sysdep_routines += oldgetrlimit64
+endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions
new file mode 100644
index 000000000..181d70150
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions
@@ -0,0 +1,30 @@
+libc {
+ GLIBC_2.0 {
+ # Exception handling support functions from libgcc
+ __register_frame; __register_frame_table; __deregister_frame;
+ __frame_state_for; __register_frame_info_table;
+ }
+ GLIBC_2.2 {
+ # functions used in other libraries
+ __xstat64; __fxstat64; __lxstat64;
+
+ # g*
+ glob64;
+
+ # New rlimit interface
+ getrlimit; setrlimit; getrlimit64; setrlimit64;
+
+ # r*
+ readdir64; readdir64_r;
+
+ # s*
+ scandir64;
+ }
+ GLIBC_2.3.3 {
+ posix_fadvise64; posix_fallocate64;
+ setcontext; getcontext; swapcontext; makecontext;
+ }
+ GLIBC_2.3.4 {
+ setcontext; getcontext; swapcontext; makecontext;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S
new file mode 100644
index 000000000..e94583494
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S
@@ -0,0 +1,64 @@
+/* brk system call for Linux/ppc.
+ Copyright (C) 1995-97, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+ .comm __curbrk,4,4
+ .section ".text"
+ENTRY (BP_SYM (__brk))
+ DISCARD_BOUNDS (r3) /* the bounds are meaningless, so toss 'em */
+ mflr r0
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ stw r3,8(r1)
+ stw r0,20(r1)
+ cfi_offset (lr, 4)
+ DO_CALL(SYS_ify(brk))
+ lwz r6,8(r1)
+#ifdef PIC
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r5
+ addis r5,r5,__curbrk-1b@ha
+ stw r3,__curbrk-1b@l(r5)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r5
+ lwz r5,__curbrk@got(r5)
+ stw r3,0(r5)
+# endif
+#else
+ lis r4,__curbrk@ha
+ stw r3,__curbrk@l(r4)
+#endif
+ lwz r0,20(r1)
+ cmplw r6,r3
+ addi r1,r1,16
+ mtlr r0
+ li r3,0
+ blelr+
+ li r3,ENOMEM
+ b __syscall_error@local
+END (BP_SYM (__brk))
+
+weak_alias (BP_SYM (__brk), BP_SYM (brk))
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
new file mode 100644
index 000000000..37b777799
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
@@ -0,0 +1,149 @@
+/* Wrapper around clone system call.
+ Copyright (C) 1997,98,99,2000,02,04,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <kernel-features.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+#define CLONE_VM 0x00000100
+#define CLONE_THREAD 0x00010000
+
+
+/* This is the only really unusual system call in PPC linux, but not
+ because of any weirdness in the system call itself; because of
+ all the freaky stuff we have to do to make the call useful. */
+
+/* int [r3] clone(int (*fn)(void *arg) [r3], void *child_stack [r4],
+ int flags [r5], void *arg [r6], void *parent_tid [r7],
+ void *tls [r8], void *child_tid [r9]); */
+
+ENTRY (BP_SYM (__clone))
+ /* GKM FIXME: add bounds checks, where sensible. */
+ DISCARD_BOUNDS (r4)
+ DISCARD_BOUNDS (r6)
+
+ /* Check for child_stack == NULL || fn == NULL. */
+ cmpwi cr0,r4,0
+ cmpwi cr1,r3,0
+ cror cr0*4+eq,cr1*4+eq,cr0*4+eq
+ beq- cr0,L(badargs)
+
+ /* Set up stack frame for parent. */
+ stwu r1,-32(r1)
+ cfi_adjust_cfa_offset (32)
+#ifdef RESET_PID
+ stmw r28,16(r1)
+#else
+# ifndef __ASSUME_FIXED_CLONE_SYSCALL
+ stmw r29,16(r1)
+# else
+ stmw r30,16(r1)
+# endif
+#endif
+
+ /* Set up stack frame for child. */
+ clrrwi r4,r4,4
+ li r0,0
+ stwu r0,-16(r4)
+
+ /* Save fn, args, stack across syscall. */
+ mr r30,r3 /* Function in r30. */
+#ifndef __ASSUME_FIXED_CLONE_SYSCALL
+ mr r29,r4 /* Stack pointer in r29. */
+#endif
+#ifdef RESET_PID
+ mr r28,r5
+#endif
+ mr r31,r6 /* Argument in r31. */
+
+ /* 'flags' argument is first parameter to clone syscall. (The other
+ argument is the stack pointer, already in r4.) */
+ mr r3,r5
+
+ /* Move the parent_tid, child_tid and tls arguments. */
+ mr r5,r7
+ mr r6,r8
+ mr r7,r9
+
+ /* End FDE now, because in the child the unwind info will be
+ wrong. */
+ cfi_endproc
+
+ /* Do the call. */
+ DO_CALL(SYS_ify(clone))
+
+ /* Check for child process. */
+ cmpwi cr1,r3,0
+ crandc cr1*4+eq,cr1*4+eq,cr0*4+so
+ bne- cr1,L(parent) /* The '-' is to minimise the race. */
+
+#ifndef __ASSUME_FIXED_CLONE_SYSCALL
+ /* On at least mklinux DR3a5, clone() doesn't actually change
+ the stack pointer. I'm pretty sure this is a bug, because
+ it adds a race condition if a signal is sent to a thread
+ just after it is created (in the previous three instructions). */
+ mr r1,r29
+#endif
+
+#ifdef RESET_PID
+ andis. r0,r28,CLONE_THREAD>>16
+ bne+ r0,L(oldpid)
+ andi. r0,r28,CLONE_VM
+ li r3,-1
+ bne- r0,L(nomoregetpid)
+ DO_CALL(SYS_ify(getpid))
+L(nomoregetpid):
+ stw r3,TID(r2)
+ stw r3,PID(r2)
+L(oldpid):
+#endif
+
+ /* Call procedure. */
+ mtctr r30
+ mr r3,r31
+ bctrl
+ /* Call _exit with result from procedure. */
+ b HIDDEN_JUMPTARGET(_exit)
+
+L(parent):
+ /* Parent. Restore registers & return. */
+#ifdef RESET_PID
+ lmw r28,16(r1)
+#else
+# ifndef __ASSUME_FIXED_CLONE_SYSCALL
+ lmw r29,16(r1)
+# else
+ lmw r30,16(r1)
+# endif
+#endif
+ addi r1,r1,32
+ bnslr+
+ b __syscall_error@local
+
+L(badargs):
+ li r3,EINVAL
+ b __syscall_error@local
+
+ cfi_startproc
+END (BP_SYM (__clone))
+
+weak_alias (BP_SYM (__clone), BP_SYM (clone))
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fcntl.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fcntl.c
new file mode 100644
index 000000000..ea951bc4f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fcntl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fcntl.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_nomask.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_nomask.c
new file mode 100644
index 000000000..8d3b9ad1f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_nomask.c
@@ -0,0 +1,68 @@
+/* Procedure definition for FE_NOMASK_ENV for Linux/ppc.
+ Copyright (C) 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sysdep.h>
+#include <sys/prctl.h>
+#include <kernel-features.h>
+
+#if __ASSUME_NEW_PRCTL_SYSCALL == 0
+/* This is rather fiddly under Linux. We don't have direct access,
+ and there is no system call, but we can change the bits
+ in a signal handler's context... */
+
+static struct sigaction oact;
+
+static void
+fe_nomask_handler (int signum, struct sigcontext *sc)
+{
+ sc->regs->msr |= 0x900ul; /* FE0 | FE1 */
+ sigaction (SIGUSR1, &oact, NULL);
+}
+#endif
+
+const fenv_t *
+__fe_nomask_env (void)
+{
+#if __ASSUME_NEW_PRCTL_SYSCALL == 0
+# if defined PR_SET_FPEXC && defined PR_FP_EXC_PRECISE
+ int result = INLINE_SYSCALL (prctl, 2, PR_SET_FPEXC, PR_FP_EXC_PRECISE);
+
+ if (result == -1 && errno == EINVAL)
+# endif
+ {
+ struct sigaction act;
+
+ act.sa_handler = (sighandler_t) fe_nomask_handler;
+ sigemptyset (&act.sa_mask);
+ act.sa_flags = 0;
+
+ sigaction (SIGUSR1, &act, &oact);
+ raise (SIGUSR1);
+ }
+#else
+ INTERNAL_SYSCALL_DECL (err);
+ INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, PR_FP_EXC_PRECISE);
+#endif
+
+ return FE_ENABLED_ENV;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/Implies b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/Implies
new file mode 100644
index 000000000..9f70f795b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/Implies
@@ -0,0 +1,2 @@
+# Override ldbl-opt with powerpc32 specific routines.
+powerpc/powerpc32/fpu
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c
new file mode 100644
index 000000000..e83f7f04b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c
@@ -0,0 +1,78 @@
+/* Copyright (C) 1997-2002,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_ftruncate64
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+/* The variable is shared between all wrappers around *truncate64 calls. */
+extern int __have_no_truncate64;
+#endif
+
+
+/* Truncate the file FD refers to to LENGTH bytes. */
+int
+__ftruncate64 (fd, length)
+ int fd;
+ off64_t length;
+{
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ if (! __have_no_truncate64)
+#endif
+ {
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ int saved_errno = errno;
+#endif
+ /* On PPC32 64bit values are aligned in odd/even register pairs. */
+ int result = INLINE_SYSCALL (ftruncate64, 4, fd, 0,
+ (long) (length >> 32),
+ (long) length);
+
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ if (result != -1 || errno != ENOSYS)
+#endif
+ return result;
+
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ __set_errno (saved_errno);
+ __have_no_truncate64 = 1;
+#endif
+ }
+
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ if ((off_t) length != length)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ return __ftruncate (fd, (off_t) length);
+#endif
+}
+weak_alias (__ftruncate64, ftruncate64)
+
+#else
+/* Use the generic implementation. */
+# include <misc/ftruncate64.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstat.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstat.c
new file mode 100644
index 000000000..4f219f0b9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fxstat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstatat.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstatat.c
new file mode 100644
index 000000000..0f8b3135d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstatat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fxstatat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S
new file mode 100644
index 000000000..c28c34664
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S
@@ -0,0 +1,286 @@
+/* Save current context, powerpc32 common.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/* This is the common implementation of getcontext for powerpc32.
+ It not complete in itself should be included in to a framework that
+ defines:
+ __CONTEXT_FUNC_NAME
+ and if appropriate:
+ __CONTEXT_ENABLE_FPRS
+ __CONTEXT_ENABLE_VRS
+ Any archecture that implements the Vector unit is assumed to also
+ implement the floating unit. */
+
+/* Stack frame offsets. */
+#define _FRAME_BACKCHAIN 0
+#define _FRAME_LR_SAVE 4
+#define _FRAME_PARM_SAVE1 8
+#define _FRAME_PARM_SAVE2 12
+#define _FRAME_PARM_SAVE3 16
+#define _FRAME_PARM_SAVE4 20
+
+#ifdef __CONTEXT_ENABLE_VRS
+ .machine "altivec"
+#endif
+ENTRY(__CONTEXT_FUNC_NAME)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+/* Insure that the _UC_REGS start on a quadword boundary. */
+ stw r3,_FRAME_PARM_SAVE1(r1)
+ addi r3,r3,_UC_REG_SPACE+12
+ clrrwi r3,r3,4
+
+/* Save the general purpose registers */
+ stw r0,_UC_GREGS+(PT_R0*4)(r3)
+ mflr r0
+ stw r2,_UC_GREGS+(PT_R2*4)(r3)
+ stw r4,_UC_GREGS+(PT_R4*4)(r3)
+/* Set the callers LR_SAVE, and the ucontext LR and NIP to the callers
+ return address. */
+ stw r0,_UC_GREGS+(PT_LNK*4)(r3)
+ stw r0,_UC_GREGS+(PT_NIP*4)(r3)
+ stw r0,_FRAME_LR_SAVE+16(r1)
+ cfi_offset (lr, _FRAME_LR_SAVE)
+ stw r5,_UC_GREGS+(PT_R5*4)(r3)
+ stw r6,_UC_GREGS+(PT_R6*4)(r3)
+ stw r7,_UC_GREGS+(PT_R7*4)(r3)
+ stw r8,_UC_GREGS+(PT_R8*4)(r3)
+ stw r9,_UC_GREGS+(PT_R9*4)(r3)
+ stw r10,_UC_GREGS+(PT_R10*4)(r3)
+ stw r11,_UC_GREGS+(PT_R11*4)(r3)
+ stw r12,_UC_GREGS+(PT_R12*4)(r3)
+ stw r13,_UC_GREGS+(PT_R13*4)(r3)
+ stw r14,_UC_GREGS+(PT_R14*4)(r3)
+ stw r15,_UC_GREGS+(PT_R15*4)(r3)
+ stw r16,_UC_GREGS+(PT_R16*4)(r3)
+ stw r17,_UC_GREGS+(PT_R17*4)(r3)
+ stw r18,_UC_GREGS+(PT_R18*4)(r3)
+ stw r19,_UC_GREGS+(PT_R19*4)(r3)
+ stw r20,_UC_GREGS+(PT_R20*4)(r3)
+ stw r21,_UC_GREGS+(PT_R21*4)(r3)
+ stw r22,_UC_GREGS+(PT_R22*4)(r3)
+ stw r23,_UC_GREGS+(PT_R23*4)(r3)
+ stw r24,_UC_GREGS+(PT_R24*4)(r3)
+ stw r25,_UC_GREGS+(PT_R25*4)(r3)
+ stw r26,_UC_GREGS+(PT_R26*4)(r3)
+ stw r27,_UC_GREGS+(PT_R27*4)(r3)
+ stw r28,_UC_GREGS+(PT_R28*4)(r3)
+ stw r29,_UC_GREGS+(PT_R29*4)(r3)
+ stw r30,_UC_GREGS+(PT_R30*4)(r3)
+ stw r31,_UC_GREGS+(PT_R31*4)(r3)
+/* Save the value of R1. We had to push the stack before we
+ had the address of uc_reg_space. So compute the address of
+ the callers stack pointer and save it as R1. */
+ addi r8,r1,16
+ li r0,0
+/* Save the count, exception and condition registers. */
+ mfctr r11
+ mfxer r10
+ mfcr r9
+ stw r8,_UC_GREGS+(PT_R1*4)(r3)
+ stw r11,_UC_GREGS+(PT_CTR*4)(r3)
+ stw r10,_UC_GREGS+(PT_XER*4)(r3)
+ stw r9,_UC_GREGS+(PT_CCR*4)(r3)
+/* Set the return value of getcontext to "success". R3 is the only
+ register whose value is not preserved in the saved context. */
+ stw r0,_UC_GREGS+(PT_R3*4)(r3)
+
+/* Zero fill fields that can't be set in user state. */
+ stw r0,_UC_GREGS+(PT_MSR*4)(r3)
+ stw r0,_UC_GREGS+(PT_MQ*4)(r3)
+
+#ifdef __CONTEXT_ENABLE_FPRS
+/* Save the floating-point registers */
+ stfd fp0,_UC_FREGS+(0*8)(r3)
+ stfd fp1,_UC_FREGS+(1*8)(r3)
+ stfd fp2,_UC_FREGS+(2*8)(r3)
+ stfd fp3,_UC_FREGS+(3*8)(r3)
+ stfd fp4,_UC_FREGS+(4*8)(r3)
+ stfd fp5,_UC_FREGS+(5*8)(r3)
+ stfd fp6,_UC_FREGS+(6*8)(r3)
+ stfd fp7,_UC_FREGS+(7*8)(r3)
+ stfd fp8,_UC_FREGS+(8*8)(r3)
+ stfd fp9,_UC_FREGS+(9*8)(r3)
+ stfd fp10,_UC_FREGS+(10*8)(r3)
+ stfd fp11,_UC_FREGS+(11*8)(r3)
+ stfd fp12,_UC_FREGS+(12*8)(r3)
+ stfd fp13,_UC_FREGS+(13*8)(r3)
+ stfd fp14,_UC_FREGS+(14*8)(r3)
+ stfd fp15,_UC_FREGS+(15*8)(r3)
+ stfd fp16,_UC_FREGS+(16*8)(r3)
+ stfd fp17,_UC_FREGS+(17*8)(r3)
+ stfd fp18,_UC_FREGS+(18*8)(r3)
+ stfd fp19,_UC_FREGS+(19*8)(r3)
+ stfd fp20,_UC_FREGS+(20*8)(r3)
+ stfd fp21,_UC_FREGS+(21*8)(r3)
+ stfd fp22,_UC_FREGS+(22*8)(r3)
+ stfd fp23,_UC_FREGS+(23*8)(r3)
+ stfd fp24,_UC_FREGS+(24*8)(r3)
+ stfd fp25,_UC_FREGS+(25*8)(r3)
+ stfd fp26,_UC_FREGS+(26*8)(r3)
+ stfd fp27,_UC_FREGS+(27*8)(r3)
+ stfd fp28,_UC_FREGS+(28*8)(r3)
+ stfd fp29,_UC_FREGS+(29*8)(r3)
+ mffs fp0
+ stfd fp30,_UC_FREGS+(30*8)(r3)
+ stfd fp31,_UC_FREGS+(31*8)(r3)
+ stfd fp0,_UC_FREGS+(32*8)(r3)
+
+# ifdef __CONTEXT_ENABLE_VRS
+# ifdef PIC
+ mflr r8
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r7
+ addis r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r7
+# endif
+# ifdef SHARED
+ lwz r7,_rtld_global_ro@got(r7)
+ mtlr r8
+ lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7)
+# else
+ lwz r7,_dl_hwcap@got(r7)
+ mtlr r8
+ lwz r7,0(r7)
+# endif
+# else
+ lis r7,_dl_hwcap@ha
+ lwz r7,_dl_hwcap@l(r7)
+# endif
+ andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+
+ la r10,(_UC_VREGS)(r3)
+ la r9,(_UC_VREGS+16)(r3)
+
+ beq 2f /* L(no_vec) */
+/* address of the combined VSCR/VSAVE quadword. */
+ la r8,(_UC_VREGS+512)(r3)
+
+/* Save the vector registers */
+ stvx v0,0,r10
+ stvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+/* We need to get the Vector Status and Control Register early to avoid
+ store order problems later with the VSAVE register that shares the
+ same quadword. */
+ mfvscr v0
+
+ stvx v2,0,r10
+ stvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v0,0,r8
+
+ stvx v4,0,r10
+ stvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v6,0,r10
+ stvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v8,0,r10
+ stvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v10,0,r10
+ stvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v12,0,r10
+ stvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v14,0,r10
+ stvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v16,0,r10
+ stvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v18,0,r10
+ stvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v20,0,r10
+ stvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v22,0,r10
+ stvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v24,0,r10
+ stvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v26,0,r10
+ stvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v28,0,r10
+ stvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mfspr r0,VRSAVE
+ stvx v30,0,r10
+ stvx v31,0,r9
+
+ stw r0,0(r8)
+
+2: /* L(no_vec): */
+# endif
+#endif
+/* We need to set up parms and call sigprocmask which will clobber
+ volatile registers. So before the call we need to retrieve the
+ original ucontext ptr (parm1) from stack and store the UC_REGS_PTR
+ (current R3). */
+ lwz r12,_FRAME_PARM_SAVE1(r1)
+ li r4,0
+ stw r3,_UC_REGS_PTR(r12)
+ addi r5,r12,_UC_SIGMASK
+ li r3,SIG_BLOCK
+ bl __sigprocmask@local
+
+ lwz r0,_FRAME_LR_SAVE+16(r1)
+ addi r1,r1,16
+ mtlr r0
+ blr
+END(__CONTEXT_FUNC_NAME)
+
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S
new file mode 100644
index 000000000..dad107403
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S
@@ -0,0 +1,84 @@
+/* Save current context.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+#include <shlib-compat.h>
+#include <kernel-features.h>
+
+#define __ASSEMBLY__
+#include <asm/ptrace.h>
+#include "ucontext_i.h"
+
+#define __CONTEXT_FUNC_NAME __getcontext
+#define __CONTEXT_ENABLE_FPRS 1
+#define __CONTEXT_ENABLE_VRS 1
+
+/* Size of ucontext in GLIBC_2.3.4 and later. */
+#define _UC_SIZE_2_3_4 1184
+
+#ifdef __ASSUME_SWAPCONTEXT_SYSCALL
+ .section ".text";
+ENTRY (__getcontext)
+ li r4,0
+ li r5,_UC_SIZE_2_3_4;
+ DO_CALL (SYS_ify (swapcontext));
+ bso- cr0,1f
+/* the kernel does not set the return code for the success case */
+ li r3,0
+ blr
+1:
+ b __syscall_error@local
+END(__getcontext)
+#else
+# include "getcontext-common.S"
+#endif
+
+versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_4)
+
+#if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)
+ compat_text_section
+
+# undef __CONTEXT_FUNC_NAME
+# define __CONTEXT_FUNC_NAME __novec_getcontext
+# undef __CONTEXT_ENABLE_VRS
+
+# clude "getcontext-common.S"
+
+ .previous
+
+compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3_3)
+
+#endif
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
+
+# define _ERRNO_H 1
+# include <bits/errno.h>
+
+ compat_text_section
+ENTRY (__getcontext_stub)
+ li r3,ENOSYS
+ b __syscall_error@local
+END (__getcontext_stub)
+ .previous
+
+compat_symbol (libc, __getcontext_stub, getcontext, GLIBC_2_1)
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c
new file mode 100644
index 000000000..82a9a296a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h
new file mode 100644
index 000000000..65f3aa40e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h
@@ -0,0 +1,49 @@
+/* Definition of `struct stat' used in the kernel.
+ Copyright (C) 1997, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+struct kernel_stat
+ {
+ unsigned int st_dev;
+ unsigned int st_ino;
+ unsigned int st_mode;
+ unsigned short st_nlink;
+ unsigned int st_uid;
+ unsigned int st_gid;
+ unsigned int st_rdev;
+ unsigned long int st_size;
+ unsigned long int st_blksize;
+ unsigned long int st_blocks;
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+ unsigned long int __unused4;
+#define _HAVE___UNUSED4
+ unsigned long int __unused5;
+#define _HAVE___UNUSED5
+ };
+
+#define _HAVE_STAT___UNUSED4
+#define _HAVE_STAT___UNUSED5
+#define _HAVE_STAT___PAD1
+#define _HAVE_STAT___PAD2
+#define _HAVE_STAT_NSEC
+#define _HAVE_STAT64___UNUSED4
+#define _HAVE_STAT64___UNUSED5
+#define _HAVE_STAT64___PAD2
+#define _HAVE_STAT64_NSEC
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/lockf64.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/lockf64.c
new file mode 100644
index 000000000..a88f5a784
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/lockf64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/lockf64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/lxstat.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/lxstat.c
new file mode 100644
index 000000000..2371cd971
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/lxstat.c
@@ -0,0 +1,2 @@
+#include <sysdeps/unix/sysv/linux/i386/lxstat.c>
+
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S
new file mode 100644
index 000000000..208a375ef
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S
@@ -0,0 +1,219 @@
+/* Set up a context to call a function.
+ Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <shlib-compat.h>
+
+#define __ASSEMBLY__
+#include <asm/ptrace.h>
+#include "ucontext_i.h"
+
+ENTRY(__makecontext)
+ /* Set up the first 7 args to the function in its registers */
+ addi r11,r3,_UC_REG_SPACE+12
+ clrrwi r11,r11,4
+ stw r11,_UC_REGS_PTR(r3)
+ stw r6,_UC_GREGS+(PT_R3*4)(r11)
+ stw r7,_UC_GREGS+(PT_R4*4)(r11)
+ stw r8,_UC_GREGS+(PT_R5*4)(r11)
+ stw r9,_UC_GREGS+(PT_R6*4)(r11)
+ stw r10,_UC_GREGS+(PT_R7*4)(r11)
+ lwz r8,8(r1)
+ lwz r9,12(r1)
+ stw r8,_UC_GREGS+(PT_R8*4)(r11)
+ stw r9,_UC_GREGS+(PT_R9*4)(r11)
+
+ /* Set the NIP to the start of the function */
+ stw r4,_UC_GREGS+(PT_NIP*4)(r11)
+
+ /* Set the function's r31 to ucp->uc_link for the exitcode below. */
+ lwz r7,_UC_LINK(r3)
+ stw r7,_UC_GREGS+(PT_R31*4)(r11)
+
+ /* Set the function's LR to point to the exitcode below. */
+#ifdef PIC
+ mflr r0
+ cfi_register(lr,r0)
+ bl 1f
+1: mflr r6
+ addi r6,r6,L(exitcode)-1b
+ mtlr r0
+ cfi_same_value (lr)
+#else
+ lis r6,L(exitcode)@ha
+ addi r6,r6,L(exitcode)@l
+#endif
+ stw r6,_UC_GREGS+(PT_LNK*4)(r11)
+
+ /*
+ * Set up the stack frame for the function.
+ * If we have more than 5 args to the function (8 args to makecontext),
+ * there will be some arguments on the stack which have to end up
+ * in registers. If there are more than 8 args to the function,
+ * we have to copy (argc - 8) args from our stack to the functions'
+ * stack (and allow space for them in the frame).
+ */
+ lwz r4,_UC_STACK_SP(r3)
+ lwz r8,_UC_STACK_SIZE(r3)
+ add r4,r4,r8
+ rlwinm r4,r4,0,0,27 /* round down to 16-byte boundary */
+ addi r7,r4,-16 /* stack frame for fn's caller */
+ cmpwi r5,8
+ blt 2f /* less than 8 args is easy */
+ lwz r10,16(r1)
+ stw r10,_UC_GREGS+(PT_R10*4)(r11)
+ beq 2f /* if exactly 8 args */
+ subi r9,r5,3
+ subi r5,r5,8
+ rlwinm r9,r9,2,0,27
+ subf r7,r9,r4
+ mtctr r5 /* copy the 9th and following args */
+ addi r6,r1,16
+ addi r8,r7,4
+3: lwzu r10,4(r6)
+ stwu r10,4(r8)
+ bdnz 3b
+2: stw r7,_UC_GREGS+(PT_R1*4)(r11)
+ li r6,0
+ stw r6,0(r7)
+
+ blr
+
+/*
+ * If the function returns, it comes here. We put ucp->uc_link in
+ * r31, which is a callee-saved register. We have to continue with
+ * the context that r31 points to, or exit if it is 0.
+ */
+L(exitcode):
+ mr. r3,r31
+ beq 4f
+ bl __setcontext@local
+4: bl HIDDEN_JUMPTARGET(exit)
+ b 4b
+
+END(__makecontext)
+
+versioned_symbol (libc, __makecontext, makecontext, GLIBC_2_3_4)
+
+#if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)
+
+ compat_text_section
+ENTRY(__novec_makecontext)
+ /* Set up the first 7 args to the function in its registers */
+ addi r11,r3,_UC_REG_SPACE
+ stw r11,_UC_REGS_PTR(r3)
+ stw r6,_UC_GREGS+(PT_R3*4)(r11)
+ stw r7,_UC_GREGS+(PT_R4*4)(r11)
+ stw r8,_UC_GREGS+(PT_R5*4)(r11)
+ stw r9,_UC_GREGS+(PT_R6*4)(r11)
+ stw r10,_UC_GREGS+(PT_R7*4)(r11)
+ lwz r8,8(r1)
+ lwz r9,12(r1)
+ stw r8,_UC_GREGS+(PT_R8*4)(r11)
+ stw r9,_UC_GREGS+(PT_R9*4)(r11)
+
+ /* Set the NIP to the start of the function */
+ stw r4,_UC_GREGS+(PT_NIP*4)(r11)
+
+ /* Set the function's r31 to ucp->uc_link for the exitcode below. */
+ lwz r7,_UC_LINK(r3)
+ stw r7,_UC_GREGS+(PT_R31*4)(r11)
+
+ /* Set the function's LR to point to the exitcode below. */
+#ifdef PIC
+ mflr r0
+ cfi_register(lr,r0)
+ bl 1f
+1: mflr r6
+ addi r6,r6,L(novec_exitcode)-1b
+ mtlr r0
+ cfi_same_value (lr)
+#else
+ lis r6,L(novec_exitcode)@ha
+ addi r6,r6,L(novec_exitcode)@l
+#endif
+ stw r6,_UC_GREGS+(PT_LNK*4)(r11)
+
+ /*
+ * Set up the stack frame for the function.
+ * If we have more than 5 args to the function (8 args to makecontext),
+ * there will be some arguments on the stack which have to end up
+ * in registers. If there are more than 8 args to the function,
+ * we have to copy (argc - 8) args from our stack to the functions'
+ * stack (and allow space for them in the frame).
+ */
+ lwz r4,_UC_STACK_SP(r3)
+ lwz r8,_UC_STACK_SIZE(r3)
+ add r4,r4,r8
+ rlwinm r4,r4,0,0,27 /* round down to 16-byte boundary */
+ addi r7,r4,-16 /* stack frame for fn's caller */
+ cmpwi r5,8
+ blt 2f /* less than 8 args is easy */
+ lwz r10,16(r1)
+ stw r10,_UC_GREGS+(PT_R10*4)(r11)
+ beq 2f /* if exactly 8 args */
+ subi r9,r5,3
+ subi r5,r5,8
+ rlwinm r9,r9,2,0,27
+ subf r7,r9,r4
+ mtctr r5 /* copy the 9th and following args */
+ addi r6,r1,16
+ addi r8,r7,4
+3: lwzu r10,4(r6)
+ stwu r10,4(r8)
+ bdnz 3b
+2: stw r7,_UC_GREGS+(PT_R1*4)(r11)
+ li r6,0
+ stw r6,0(r7)
+
+ blr
+
+/*
+ * If the function returns, it comes here. We put ucp->uc_link in
+ * r31, which is a callee-saved register. We have to continue with
+ * the context that r31 points to, or exit if it is 0.
+ */
+L(novec_exitcode):
+ mr. r3,r31
+ beq 4f
+ bl __novec_setcontext@local
+4: bl HIDDEN_JUMPTARGET(exit)
+ b 4b
+
+END(__novec_makecontext)
+ .previous
+
+compat_symbol (libc, __novec_makecontext, makecontext, GLIBC_2_3_3)
+#endif
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
+
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+ compat_text_section
+ENTRY (__makecontext_stub)
+ li r3,ENOSYS
+ b __syscall_error@local
+END (__makecontext_stub)
+ .previous
+
+compat_symbol (libc, __makecontext_stub, makecontext, GLIBC_2_1)
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/posix_fadvise.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/posix_fadvise.c
new file mode 100644
index 000000000..15b705402
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/posix_fadvise.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sysdep.h>
+
+/* Advice the system about the expected behaviour of the application with
+ respect to the file associated with FD. */
+
+int
+posix_fadvise (int fd, off_t offset, off_t len, int advise)
+{
+#ifdef __NR_fadvise64
+ INTERNAL_SYSCALL_DECL (err);
+ int ret = INTERNAL_SYSCALL (fadvise64, err, 6, fd, 0,
+ __LONG_LONG_PAIR (offset >> 31, offset), len,
+ advise);
+ if (INTERNAL_SYSCALL_ERROR_P (ret, err))
+ return INTERNAL_SYSCALL_ERRNO (ret, err);
+ return 0;
+#else
+ return ENOSYS;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/posix_fadvise64.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/posix_fadvise64.c
new file mode 100644
index 000000000..c97bbbe87
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/posix_fadvise64.c
@@ -0,0 +1,78 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sysdep.h>
+#include <kernel-features.h>
+
+int __posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise);
+int __posix_fadvise64_l32 (int fd, off64_t offset, size_t len, int advise);
+
+/* Advice the system about the expected behaviour of the application with
+ respect to the file associated with FD. */
+
+int
+__posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise)
+{
+#ifdef __NR_fadvise64_64
+ INTERNAL_SYSCALL_DECL (err);
+ int ret = INTERNAL_SYSCALL (fadvise64_64, err, 6, fd, advise,
+ __LONG_LONG_PAIR ((long)(offset >> 32), (long)offset),
+ __LONG_LONG_PAIR ((long)(len >> 32), (long)len));
+ if (!INTERNAL_SYSCALL_ERROR_P (ret, err))
+ return 0;
+# ifndef __ASSUME_FADVISE64_64_SYSCALL
+ if (INTERNAL_SYSCALL_ERRNO (ret, err) != ENOSYS)
+# endif
+ return INTERNAL_SYSCALL_ERRNO (ret, err);
+#endif
+#ifndef __ASSUME_FADVISE64_64_SYSCALL
+# ifdef __NR_fadvise64
+ if (len != (off_t) len)
+ return EOVERFLOW;
+
+ INTERNAL_SYSCALL_DECL (err2);
+ int ret2 = INTERNAL_SYSCALL (fadvise64, err2, 6, fd, 0,
+ __LONG_LONG_PAIR ((long)(offset >> 32), (long)offset),
+ (off_t) len, advise);
+ if (!INTERNAL_SYSCALL_ERROR_P (ret2, err2))
+ return 0;
+ return INTERNAL_SYSCALL_ERRNO (ret2, err2);
+# else
+ return ENOSYS;
+# endif
+#endif
+}
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_2, GLIBC_2_3_3)
+
+int
+attribute_compat_text_section
+__posix_fadvise64_l32 (int fd, off64_t offset, size_t len, int advise)
+{
+ return __posix_fadvise64_l64 (fd, offset, len, advise);
+}
+
+versioned_symbol (libc, __posix_fadvise64_l64, posix_fadvise64, GLIBC_2_3_3);
+compat_symbol (libc, __posix_fadvise64_l32, posix_fadvise64, GLIBC_2_2);
+#else
+strong_alias (__posix_fadvise64_l64, posix_fadvise64);
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c
new file mode 100644
index 000000000..4d9fa263c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c
@@ -0,0 +1,87 @@
+/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
+
+# if __ASSUME_PREAD_SYSCALL == 0
+static ssize_t __emulate_pread (int fd, void *buf, size_t count,
+ off_t offset) internal_function;
+# endif
+
+
+ssize_t
+__libc_pread (fd, buf, count, offset)
+ int fd;
+ void *buf;
+ size_t count;
+ off_t offset;
+{
+ ssize_t result;
+
+ if (SINGLE_THREAD_P)
+ {
+ /* On PPC32 64bit values are aligned in odd/even register pairs. */
+ result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count,
+ 0, offset >> 31, offset);
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread (fd, buf, count, offset);
+# endif
+
+ return result;
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* On PPC32 64bit values are aligned in odd/even register pairs. */
+ result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count,
+ 0, offset >> 31, offset);
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread (fd, buf, count, offset);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+strong_alias (__libc_pread, __pread)
+weak_alias (__libc_pread, pread)
+
+# define __libc_pread(fd, buf, count, offset) \
+ static internal_function __emulate_pread (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c
new file mode 100644
index 000000000..9527554e9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c
@@ -0,0 +1,88 @@
+/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
+
+# if __ASSUME_PREAD_SYSCALL == 0
+static ssize_t __emulate_pread64 (int fd, void *buf, size_t count,
+ off64_t offset) internal_function;
+# endif
+
+
+ssize_t
+__libc_pread64 (fd, buf, count, offset)
+ int fd;
+ void *buf;
+ size_t count;
+ off64_t offset;
+{
+ ssize_t result;
+
+ if (SINGLE_THREAD_P)
+ {
+ /* On PPC32 64bit values are aligned in odd/even register pairs. */
+ result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count,
+ 0, (long) (offset >> 32),
+ (long) offset);
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread64 (fd, buf, count, offset);
+# endif
+
+ return result;
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* On PPC32 64bit values are aligned in odd/even register pairs. */
+ result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count,
+ 0, (long) (offset >> 32),
+ (long) offset);
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread64 (fd, buf, count, offset);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+weak_alias (__libc_pread64, __pread64)
+weak_alias (__libc_pread64, pread64)
+
+# define __libc_pread64(fd, buf, count, offset) \
+ static internal_function __emulate_pread64 (fd, buf, count, offset)
+#endif
+
+# if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread64.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c
new file mode 100644
index 000000000..32383f430
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c
@@ -0,0 +1,87 @@
+/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
+
+# if __ASSUME_PWRITE_SYSCALL == 0
+static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count,
+ off_t offset) internal_function;
+# endif
+
+
+ssize_t
+__libc_pwrite (fd, buf, count, offset)
+ int fd;
+ const void *buf;
+ size_t count;
+ off_t offset;
+{
+ ssize_t result;
+
+ if (SINGLE_THREAD_P)
+ {
+ /* On PPC32 64bit values are aligned in odd/even register pairs. */
+ result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count,
+ 0, offset >> 31, offset);
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite (fd, buf, count, offset);
+# endif
+
+ return result;
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* On PPC32 64bit values are aligned in odd/even register pairs. */
+ result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count,
+ 0, offset >> 31, offset);
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite (fd, buf, count, offset);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+strong_alias (__libc_pwrite, __pwrite)
+weak_alias (__libc_pwrite, pwrite)
+
+# define __libc_pwrite(fd, buf, count, offset) \
+ static internal_function __emulate_pwrite (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c
new file mode 100644
index 000000000..acc250a88
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c
@@ -0,0 +1,89 @@
+/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
+
+# if __ASSUME_PWRITE_SYSCALL == 0
+static ssize_t __emulate_pwrite64 (int fd, const void *buf, size_t count,
+ off64_t offset) internal_function;
+# endif
+
+
+ssize_t
+__libc_pwrite64 (fd, buf, count, offset)
+ int fd;
+ const void *buf;
+ size_t count;
+ off64_t offset;
+{
+ ssize_t result;
+
+ if (SINGLE_THREAD_P)
+ {
+ /* On PPC32 64bit values are aligned in odd/even register pairs. */
+ result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count,
+ 0, (long) (offset >> 32),
+ (long) offset);
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite64 (fd, buf, count, offset);
+# endif
+
+ return result;
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* On PPC32 64bit values are aligned in odd/even register pairs. */
+ result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count,
+ 0, (long) (offset >> 32),
+ (long) offset);
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite64 (fd, buf, count, offset);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+weak_alias (__libc_pwrite64, __pwrite64)
+libc_hidden_weak (__pwrite64)
+weak_alias (__libc_pwrite64, pwrite64)
+
+# define __libc_pwrite64(fd, buf, count, offset) \
+ static internal_function __emulate_pwrite64 (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite64.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S
new file mode 100644
index 000000000..40a7a24f1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S
@@ -0,0 +1,293 @@
+/* Jump to a new context powerpc32 common.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/* This is the common implementation of setcontext for powerpc32.
+ It not complete in itself should be included in to a framework that
+ defines:
+ __CONTEXT_FUNC_NAME
+ and if appropriate:
+ __CONTEXT_ENABLE_FPRS
+ __CONTEXT_ENABLE_VRS
+ Any archecture that implements the Vector unit is assumed to also
+ implement the floating unit. */
+
+/* Stack frame offsets. */
+#define _FRAME_BACKCHAIN 0
+#define _FRAME_LR_SAVE 4
+#define _FRAME_PARM_SAVE1 8
+#define _FRAME_PARM_SAVE2 12
+#define _FRAME_PARM_SAVE3 16
+#define _FRAME_PARM_SAVE4 20
+
+#ifdef __CONTEXT_ENABLE_VRS
+ .machine "altivec"
+#endif
+ENTRY(__CONTEXT_FUNC_NAME)
+ mflr r0
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ stw r0,20(r1)
+ cfi_offset (lr, _FRAME_LR_SAVE)
+ stw r31,12(r1)
+ cfi_offset(r31,-4)
+ lwz r31,_UC_REGS_PTR(r3)
+
+ /*
+ * If this ucontext refers to the point where we were interrupted
+ * by a signal, we have to use the rt_sigreturn system call to
+ * return to the context so we get both LR and CTR restored.
+ *
+ * Otherwise, the context we are restoring is either just after
+ * a procedure call (getcontext/swapcontext) or at the beginning
+ * of a procedure call (makecontext), so we don't need to restore
+ * r0, xer, ctr. We don't restore r2 since it will be used as
+ * the TLS pointer.
+ */
+ lwz r0,_UC_GREGS+(PT_MSR*4)(r31)
+ cmpwi r0,0
+ bne 4f /* L(do_sigret) */
+
+ /* Restore the signal mask */
+ li r5,0
+ addi r4,r3,_UC_SIGMASK
+ li r3,SIG_SETMASK
+ bl __sigprocmask@local
+ cmpwi r3,0
+ bne 3f /* L(error_exit) */
+
+#ifdef __CONTEXT_ENABLE_FPRS
+# ifdef __CONTEXT_ENABLE_VRS
+# ifdef PIC
+ mflr r8
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r7
+ addis r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r7
+# endif
+# ifdef SHARED
+ lwz r7,_rtld_global_ro@got(r7)
+ mtlr r8
+ lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7)
+# else
+ lwz r7,_dl_hwcap@got(r7)
+ mtlr r8
+ lwz r7,0(r7)
+# endif
+# else
+ lis r7,_dl_hwcap@ha
+ lwz r7,_dl_hwcap@l(r7)
+# endif
+ andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ la r10,(_UC_VREGS)(r31)
+ beq 2f /* L(has_no_vec) */
+
+ lwz r0,(32*16)(r10)
+ li r9,(32*16)
+ cmpwi r0,0
+ mtspr VRSAVE,r0
+ beq 2f /* L(has_no_vec) */
+
+ lvx v19,r9,r10
+ la r9,(16)(r10)
+
+ lvx v0,0,r10
+ lvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mtvscr v19
+ lvx v2,0,r10
+ lvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v4,0,r10
+ lvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v6,0,r10
+ lvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v8,0,r10
+ lvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v12,0,r10
+ lvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v14,0,r10
+ lvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v16,0,r10
+ lvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v18,0,r10
+ lvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v20,0,r10
+ lvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v22,0,r10
+ lvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v24,0,r10
+ lvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v26,0,r10
+ lvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v28,0,r10
+ lvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v30,0,r10
+ lvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+
+2: /* L(has_no_vec): */
+# endif /* __CONTEXT_ENABLE_VRS */
+ /* Restore the floating-point registers */
+ lfd fp31,_UC_FREGS+(32*8)(r31)
+ lfd fp0,_UC_FREGS+(0*8)(r31)
+ mtfsf 0xff,fp31
+ lfd fp1,_UC_FREGS+(1*8)(r31)
+ lfd fp2,_UC_FREGS+(2*8)(r31)
+ lfd fp3,_UC_FREGS+(3*8)(r31)
+ lfd fp4,_UC_FREGS+(4*8)(r31)
+ lfd fp5,_UC_FREGS+(5*8)(r31)
+ lfd fp6,_UC_FREGS+(6*8)(r31)
+ lfd fp7,_UC_FREGS+(7*8)(r31)
+ lfd fp8,_UC_FREGS+(8*8)(r31)
+ lfd fp9,_UC_FREGS+(9*8)(r31)
+ lfd fp10,_UC_FREGS+(10*8)(r31)
+ lfd fp11,_UC_FREGS+(11*8)(r31)
+ lfd fp12,_UC_FREGS+(12*8)(r31)
+ lfd fp13,_UC_FREGS+(13*8)(r31)
+ lfd fp14,_UC_FREGS+(14*8)(r31)
+ lfd fp15,_UC_FREGS+(15*8)(r31)
+ lfd fp16,_UC_FREGS+(16*8)(r31)
+ lfd fp17,_UC_FREGS+(17*8)(r31)
+ lfd fp18,_UC_FREGS+(18*8)(r31)
+ lfd fp19,_UC_FREGS+(19*8)(r31)
+ lfd fp20,_UC_FREGS+(20*8)(r31)
+ lfd fp21,_UC_FREGS+(21*8)(r31)
+ lfd fp22,_UC_FREGS+(22*8)(r31)
+ lfd fp23,_UC_FREGS+(23*8)(r31)
+ lfd fp24,_UC_FREGS+(24*8)(r31)
+ lfd fp25,_UC_FREGS+(25*8)(r31)
+ lfd fp26,_UC_FREGS+(26*8)(r31)
+ lfd fp27,_UC_FREGS+(27*8)(r31)
+ lfd fp28,_UC_FREGS+(28*8)(r31)
+ lfd fp29,_UC_FREGS+(29*8)(r31)
+ lfd fp30,_UC_FREGS+(30*8)(r31)
+ lfd fp31,_UC_FREGS+(31*8)(r31)
+#endif /* __CONTEXT_ENABLE_FPRS */
+
+ /* Restore LR and CCR, and set CTR to the NIP value */
+ lwz r3,_UC_GREGS+(PT_LNK*4)(r31)
+ lwz r4,_UC_GREGS+(PT_NIP*4)(r31)
+ lwz r5,_UC_GREGS+(PT_CCR*4)(r31)
+ mtlr r3
+ mtctr r4
+ mtcr r5
+
+ /* Restore the general registers */
+ lwz r1,_UC_GREGS+(PT_R1*4)(r31)
+ lwz r3,_UC_GREGS+(PT_R3*4)(r31)
+ lwz r4,_UC_GREGS+(PT_R4*4)(r31)
+ lwz r5,_UC_GREGS+(PT_R5*4)(r31)
+ lwz r6,_UC_GREGS+(PT_R6*4)(r31)
+ lwz r7,_UC_GREGS+(PT_R7*4)(r31)
+ lwz r8,_UC_GREGS+(PT_R8*4)(r31)
+ lwz r9,_UC_GREGS+(PT_R9*4)(r31)
+ lwz r10,_UC_GREGS+(PT_R10*4)(r31)
+ lwz r11,_UC_GREGS+(PT_R11*4)(r31)
+ lwz r12,_UC_GREGS+(PT_R12*4)(r31)
+ lwz r13,_UC_GREGS+(PT_R13*4)(r31)
+ lwz r14,_UC_GREGS+(PT_R14*4)(r31)
+ lwz r15,_UC_GREGS+(PT_R15*4)(r31)
+ lwz r16,_UC_GREGS+(PT_R16*4)(r31)
+ lwz r17,_UC_GREGS+(PT_R17*4)(r31)
+ lwz r18,_UC_GREGS+(PT_R18*4)(r31)
+ lwz r19,_UC_GREGS+(PT_R19*4)(r31)
+ lwz r20,_UC_GREGS+(PT_R20*4)(r31)
+ lwz r21,_UC_GREGS+(PT_R21*4)(r31)
+ lwz r22,_UC_GREGS+(PT_R22*4)(r31)
+ lwz r23,_UC_GREGS+(PT_R23*4)(r31)
+ lwz r24,_UC_GREGS+(PT_R24*4)(r31)
+ lwz r25,_UC_GREGS+(PT_R25*4)(r31)
+ lwz r26,_UC_GREGS+(PT_R26*4)(r31)
+ lwz r27,_UC_GREGS+(PT_R27*4)(r31)
+ lwz r28,_UC_GREGS+(PT_R28*4)(r31)
+ lwz r29,_UC_GREGS+(PT_R29*4)(r31)
+ lwz r30,_UC_GREGS+(PT_R30*4)(r31)
+ lwz r31,_UC_GREGS+(PT_R31*4)(r31)
+
+ bctr
+
+3: /* L(error_exit): */
+ lwz r31,12(r1)
+ lwz r0,20(r1)
+ addi r1,r1,16
+ mtlr r0
+ blr
+
+
+4: /* L(do_sigret): */
+ addi r1,r3,-0xd0
+ li r0,SYS_ify(rt_sigreturn)
+ sc
+ /* NOTREACHED */
+
+END (__CONTEXT_FUNC_NAME)
+
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
new file mode 100644
index 000000000..7e9213c2d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
@@ -0,0 +1,85 @@
+/* Jump to a new context.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+#include <shlib-compat.h>
+
+#define __ASSEMBLY__
+#include <asm/ptrace.h>
+#include "ucontext_i.h"
+
+#define __CONTEXT_FUNC_NAME __setcontext
+#define __CONTEXT_ENABLE_FPRS 1
+#define __CONTEXT_ENABLE_VRS 1
+
+/* Size of ucontext in GLIBC_2.3.4 and later. */
+#define _UC_SIZE_2_3_4 1184
+
+#ifdef __ASSUME_SWAPCONTEXT_SYSCALL
+ .section ".text";
+ENTRY (__setcontext)
+ mr r4,r3
+ li r3,0
+ li r5,_UC_SIZE_2_3_4;
+ DO_CALL (SYS_ify (swapcontext));
+ bso- cr0,1f
+/* the kernel does not set the return code for the success case */
+ li r3,0
+ blr
+1:
+ b __syscall_error@local
+END(__setcontext)
+#else
+# include "setcontext-common.S"
+#endif
+
+versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_4)
+
+#if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)
+
+ compat_text_section
+
+# undef __CONTEXT_FUNC_NAME
+# define __CONTEXT_FUNC_NAME __novec_setcontext
+# undef __CONTEXT_ENABLE_VRS
+
+# include "setcontext-common.S"
+
+ .previous
+
+compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3_3)
+
+#endif
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_3)
+
+# define _ERRNO_H 1
+# include <bits/errno.h>
+
+ compat_text_section
+ENTRY (__setcontext_stub)
+ li r3,ENOSYS
+ b __syscall_error@local
+END (__setcontext_stub)
+ .previous
+
+compat_symbol (libc, __setcontext_stub, setcontext, GLIBC_2_0)
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S
new file mode 100644
index 000000000..0bb5bef78
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S
@@ -0,0 +1,121 @@
+/* Copyright (C) 1995,96,97,99, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep-cancel.h>
+#include <socketcall.h>
+
+#define P(a, b) P2(a, b)
+#define P2(a, b) a##b
+
+/* The socket-oriented system calls are handled unusally in Linux.
+ They are all gated through the single `socketcall' system call number.
+ `socketcall' takes two arguments: the first is the subcode, specifying
+ which socket function is being called; and the second is a pointer to
+ the arguments to the specific function.
+
+ The .S files for the other calls just #define socket and #include this.
+ They also #define a 'number-of-arguments' word in NARGS, which
+ defaults to 3. */
+
+#ifndef NARGS
+#ifdef socket
+#error NARGS not defined
+#endif
+#define NARGS 3
+#endif
+
+/* 0(r1) and 4(r1) are reserved by the ABI, 8(r1), 12(r1), 16(r1) are used
+ for temp saves. 44(r1) is used to save r30. */
+#define stackblock 20
+
+#ifndef __socket
+# ifndef NO_WEAK_ALIAS
+# define __socket P(__,socket)
+# else
+# define __socket socket
+# endif
+#endif
+
+ .text
+ENTRY(__socket)
+ stwu r1,-48(r1)
+ cfi_adjust_cfa_offset(48)
+#if NARGS >= 1
+ stw r3,stackblock(r1)
+#endif
+#if NARGS >= 2
+ stw r4,4+stackblock(r1)
+#endif
+#if NARGS >= 3
+ stw r5,8+stackblock(r1)
+#endif
+#if NARGS >= 4
+ stw r6,12+stackblock(r1)
+#endif
+#if NARGS >= 5
+ stw r7,16+stackblock(r1)
+#endif
+#if NARGS >= 6
+ stw r8,20+stackblock(r1)
+#endif
+#if NARGS >= 7
+#error too many arguments!
+#endif
+
+#if defined NEED_CANCELLATION && defined CENABLE
+ SINGLE_THREAD_P
+ bne- .Lsocket_cancel
+#endif
+
+ li r3,P(SOCKOP_,socket)
+ addi r4,r1,stackblock
+ DO_CALL(SYS_ify(socketcall))
+ addi r1,r1,48
+ PSEUDO_RET
+
+#if defined NEED_CANCELLATION && defined CENABLE
+.Lsocket_cancel:
+ mflr r9
+ stw r9,52(r1)
+ cfi_offset (lr, 4)
+ CGOTSETUP
+ CENABLE
+ stw r3,16(r1)
+ li r3,P(SOCKOP_,socket)
+ addi r4,r1,stackblock
+ DO_CALL(SYS_ify(socketcall))
+ mfcr r0
+ stw r3,8(r1)
+ stw r0,12(r1)
+ lwz r3,16(r1)
+ CDISABLE
+ lwz r4,52(r1)
+ lwz r0,12(r1)
+ lwz r3,8(r1)
+ CGOTRESTORE
+ mtlr r4
+ mtcr r0
+ addi r1,r1,48
+ PSEUDO_RET
+#endif
+
+PSEUDO_END (__socket)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__socket, socket)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S
new file mode 100644
index 000000000..0c7b945ed
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S
@@ -0,0 +1,517 @@
+/* Save current context and jump to a new context.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/* This is the common implementation of setcontext for powerpc32.
+ It not complete in itself should be included in to a framework that
+ defines:
+ __CONTEXT_FUNC_NAME
+ and if appropriate:
+ __CONTEXT_ENABLE_FPRS
+ __CONTEXT_ENABLE_VRS
+ Any archecture that implements the Vector unit is assumed to also
+ implement the floating unit. */
+
+/* Stack frame offsets. */
+#define _FRAME_BACKCHAIN 0
+#define _FRAME_LR_SAVE 4
+#define _FRAME_PARM_SAVE1 8
+#define _FRAME_PARM_SAVE2 12
+#define _FRAME_PARM_SAVE3 16
+#define _FRAME_PARM_SAVE4 20
+
+#ifdef __CONTEXT_ENABLE_VRS
+ .machine "altivec"
+#endif
+ENTRY(__CONTEXT_FUNC_NAME)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+/* Insure that the _UC_REGS start on a quadword boundary. */
+ stw r3,_FRAME_PARM_SAVE1(r1)
+ addi r3,r3,_UC_REG_SPACE+12
+ stw r4,_FRAME_PARM_SAVE2(r1) /* new context pointer */
+ clrrwi r3,r3,4
+
+/* Save the general purpose registers */
+ stw r0,_UC_GREGS+(PT_R0*4)(r3)
+ mflr r0
+ stw r2,_UC_GREGS+(PT_R2*4)(r3)
+ stw r4,_UC_GREGS+(PT_R4*4)(r3)
+/* Set the callers LR_SAVE, and the ucontext LR and NIP to the callers
+ return address. */
+ stw r0,_UC_GREGS+(PT_LNK*4)(r3)
+ stw r0,_UC_GREGS+(PT_NIP*4)(r3)
+ stw r0,_FRAME_LR_SAVE+16(r1)
+ cfi_offset (lr, _FRAME_LR_SAVE)
+ stw r5,_UC_GREGS+(PT_R5*4)(r3)
+ stw r6,_UC_GREGS+(PT_R6*4)(r3)
+ stw r7,_UC_GREGS+(PT_R7*4)(r3)
+ stw r8,_UC_GREGS+(PT_R8*4)(r3)
+ stw r9,_UC_GREGS+(PT_R9*4)(r3)
+ stw r10,_UC_GREGS+(PT_R10*4)(r3)
+ stw r11,_UC_GREGS+(PT_R11*4)(r3)
+ stw r12,_UC_GREGS+(PT_R12*4)(r3)
+ stw r13,_UC_GREGS+(PT_R13*4)(r3)
+ stw r14,_UC_GREGS+(PT_R14*4)(r3)
+ stw r15,_UC_GREGS+(PT_R15*4)(r3)
+ stw r16,_UC_GREGS+(PT_R16*4)(r3)
+ stw r17,_UC_GREGS+(PT_R17*4)(r3)
+ stw r18,_UC_GREGS+(PT_R18*4)(r3)
+ stw r19,_UC_GREGS+(PT_R19*4)(r3)
+ stw r20,_UC_GREGS+(PT_R20*4)(r3)
+ stw r21,_UC_GREGS+(PT_R21*4)(r3)
+ stw r22,_UC_GREGS+(PT_R22*4)(r3)
+ stw r23,_UC_GREGS+(PT_R23*4)(r3)
+ stw r24,_UC_GREGS+(PT_R24*4)(r3)
+ stw r25,_UC_GREGS+(PT_R25*4)(r3)
+ stw r26,_UC_GREGS+(PT_R26*4)(r3)
+ stw r27,_UC_GREGS+(PT_R27*4)(r3)
+ stw r28,_UC_GREGS+(PT_R28*4)(r3)
+ stw r29,_UC_GREGS+(PT_R29*4)(r3)
+ stw r30,_UC_GREGS+(PT_R30*4)(r3)
+ stw r31,_UC_GREGS+(PT_R31*4)(r3)
+
+/* Save the value of R1. We had to push the stack before we
+ had the address of uc_reg_space. So compute the address of
+ the callers stack pointer and save it as R1. */
+ addi r8,r1,16
+ li r0,0
+/* Save the count, exception and condition registers. */
+ mfctr r11
+ mfxer r10
+ mfcr r9
+ stw r8,_UC_GREGS+(PT_R1*4)(r3)
+ stw r11,_UC_GREGS+(PT_CTR*4)(r3)
+ stw r10,_UC_GREGS+(PT_XER*4)(r3)
+ stw r9,_UC_GREGS+(PT_CCR*4)(r3)
+/* Set the return value of getcontext to "success". R3 is the only
+ register whose value is not preserved in the saved context. */
+ stw r0,_UC_GREGS+(PT_R3*4)(r3)
+
+ /* Zero fill fields that can't be set in user state. */
+ stw r0,_UC_GREGS+(PT_MSR*4)(r3)
+ stw r0,_UC_GREGS+(PT_MQ*4)(r3)
+
+#ifdef __CONTEXT_ENABLE_FPRS
+ /* Save the floating-point registers */
+ stfd fp0,_UC_FREGS+(0*8)(r3)
+ stfd fp1,_UC_FREGS+(1*8)(r3)
+ stfd fp2,_UC_FREGS+(2*8)(r3)
+ stfd fp3,_UC_FREGS+(3*8)(r3)
+ stfd fp4,_UC_FREGS+(4*8)(r3)
+ stfd fp5,_UC_FREGS+(5*8)(r3)
+ stfd fp6,_UC_FREGS+(6*8)(r3)
+ stfd fp7,_UC_FREGS+(7*8)(r3)
+ stfd fp8,_UC_FREGS+(8*8)(r3)
+ stfd fp9,_UC_FREGS+(9*8)(r3)
+ stfd fp10,_UC_FREGS+(10*8)(r3)
+ stfd fp11,_UC_FREGS+(11*8)(r3)
+ stfd fp12,_UC_FREGS+(12*8)(r3)
+ stfd fp13,_UC_FREGS+(13*8)(r3)
+ stfd fp14,_UC_FREGS+(14*8)(r3)
+ stfd fp15,_UC_FREGS+(15*8)(r3)
+ stfd fp16,_UC_FREGS+(16*8)(r3)
+ stfd fp17,_UC_FREGS+(17*8)(r3)
+ stfd fp18,_UC_FREGS+(18*8)(r3)
+ stfd fp19,_UC_FREGS+(19*8)(r3)
+ stfd fp20,_UC_FREGS+(20*8)(r3)
+ stfd fp21,_UC_FREGS+(21*8)(r3)
+ stfd fp22,_UC_FREGS+(22*8)(r3)
+ stfd fp23,_UC_FREGS+(23*8)(r3)
+ stfd fp24,_UC_FREGS+(24*8)(r3)
+ stfd fp25,_UC_FREGS+(25*8)(r3)
+ stfd fp26,_UC_FREGS+(26*8)(r3)
+ stfd fp27,_UC_FREGS+(27*8)(r3)
+ stfd fp28,_UC_FREGS+(28*8)(r3)
+ stfd fp29,_UC_FREGS+(29*8)(r3)
+ mffs fp0
+ stfd fp30,_UC_FREGS+(30*8)(r3)
+ stfd fp31,_UC_FREGS+(31*8)(r3)
+ stfd fp0,_UC_FREGS+(32*8)(r3)
+
+# ifdef __CONTEXT_ENABLE_VRS
+# ifdef PIC
+ mflr r8
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r7
+ addis r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r7
+# endif
+# ifdef SHARED
+ lwz r7,_rtld_global_ro@got(r7)
+ mtlr r8
+ lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7)
+# else
+ lwz r7,_dl_hwcap@got(r7)
+ mtlr r8
+ lwz r7,0(r7)
+# endif
+# else
+ lis r7,_dl_hwcap@ha
+ lwz r7,_dl_hwcap@l(r7)
+# endif
+ andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+
+ la r10,(_UC_VREGS)(r3)
+ la r9,(_UC_VREGS+16)(r3)
+
+/* beq L(no_vec)*/
+ beq 2f
+/* address of the combined VSCR/VSAVE quadword. */
+ la r8,(_UC_VREGS+512)(r3)
+
+/* Save the vector registers */
+ stvx v0,0,r10
+ stvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+/* We need to get the Vector Status and Control Register early to avoid
+ store order problems later with the VSAVE register that shares the
+ same quadword. */
+ mfvscr v0
+
+ stvx v2,0,r10
+ stvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v0,0,r8
+
+ stvx v4,0,r10
+ stvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v6,0,r10
+ stvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v8,0,r10
+ stvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v10,0,r10
+ stvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v12,0,r10
+ stvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v14,0,r10
+ stvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v16,0,r10
+ stvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v18,0,r10
+ stvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v20,0,r10
+ stvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v22,0,r10
+ stvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v24,0,r10
+ stvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v26,0,r10
+ stvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v28,0,r10
+ stvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mfvscr v0
+ stvx v30,0,r10
+ stvx v31,0,r9
+ stw r0,0(r8)
+
+2: /*L(no_vec):*/
+# endif /* __CONTEXT_ENABLE_VRS */
+#endif /* __CONTEXT_ENABLE_FPRS */
+
+/* Restore ucontext (parm1) from stack. */
+ lwz r12,_FRAME_PARM_SAVE1(r1)
+ li r4,0
+ stw r3,_UC_REGS_PTR(r12)
+ addi r5,r12,_UC_SIGMASK
+ li r3,SIG_SETMASK
+ bl __sigprocmask@local
+ cmpwi r3,0
+ bne 3f /* L(error_exit) */
+
+ /*
+ * If the new ucontext refers to the point where we were interrupted
+ * by a signal, we have to use the rt_sigreturn system call to
+ * return to the context so we get both LR and CTR restored.
+ *
+ * Otherwise, the context we are restoring is either just after
+ * a procedure call (getcontext/swapcontext) or at the beginning
+ * of a procedure call (makecontext), so we don't need to restore
+ * r0, xer, ctr. We don't restore r2 since it will be used as
+ * the TLS pointer.
+ */
+ lwz r4,_FRAME_PARM_SAVE2(r1)
+ lwz r31,_UC_REGS_PTR(r4)
+ lwz r0,_UC_GREGS+(PT_MSR*4)(r31)
+ cmpwi r0,0
+ bne 4f /* L(do_sigret) */
+
+#ifdef __CONTEXT_ENABLE_FPRS
+# ifdef __CONTEXT_ENABLE_VRS
+
+# ifdef PIC
+ mflr r8
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,5f
+5: mflr r7
+ addis r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r7
+# endif
+ mtlr r8
+# ifdef SHARED
+ lwz r7,_rtld_global_ro@got(r7)
+ lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7)
+# else
+ lwz r7,_dl_hwcap@got(r7)
+ lwz r7,0(r7)
+# endif
+# else
+ lis r7,_dl_hwcap@ha
+ lwz r7,_dl_hwcap@l(r7)
+# endif
+ andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ la r10,(_UC_VREGS)(r31)
+ beq 6f /* L(has_no_vec) */
+
+ lwz r0,(32*16)(r10)
+ li r9,(32*16)
+ cmpwi r0,0
+ mtspr VRSAVE,r0
+ beq 6f /* L(has_no_vec) */
+
+ lvx v19,r9,r10
+ la r9,(16)(r10)
+
+ lvx v0,0,r10
+ lvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mtvscr v19
+ lvx v2,0,r10
+ lvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v4,0,r10
+ lvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v6,0,r10
+ lvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v8,0,r10
+ lvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v12,0,r10
+ lvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v14,0,r10
+ lvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v16,0,r10
+ lvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v18,0,r10
+ lvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v20,0,r10
+ lvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v22,0,r10
+ lvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v24,0,r10
+ lvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v26,0,r10
+ lvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v28,0,r10
+ lvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v30,0,r10
+ lvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+
+6: /* L(has_no_vec): */
+# endif /* __CONTEXT_ENABLE_VRS */
+ /* Restore the floating-point registers */
+ lfd fp31,_UC_FREGS+(32*8)(r31)
+ lfd fp0,_UC_FREGS+(0*8)(r31)
+ mtfsf 0xff,fp31
+ lfd fp1,_UC_FREGS+(1*8)(r31)
+ lfd fp2,_UC_FREGS+(2*8)(r31)
+ lfd fp3,_UC_FREGS+(3*8)(r31)
+ lfd fp4,_UC_FREGS+(4*8)(r31)
+ lfd fp5,_UC_FREGS+(5*8)(r31)
+ lfd fp6,_UC_FREGS+(6*8)(r31)
+ lfd fp7,_UC_FREGS+(7*8)(r31)
+ lfd fp8,_UC_FREGS+(8*8)(r31)
+ lfd fp9,_UC_FREGS+(9*8)(r31)
+ lfd fp10,_UC_FREGS+(10*8)(r31)
+ lfd fp11,_UC_FREGS+(11*8)(r31)
+ lfd fp12,_UC_FREGS+(12*8)(r31)
+ lfd fp13,_UC_FREGS+(13*8)(r31)
+ lfd fp14,_UC_FREGS+(14*8)(r31)
+ lfd fp15,_UC_FREGS+(15*8)(r31)
+ lfd fp16,_UC_FREGS+(16*8)(r31)
+ lfd fp17,_UC_FREGS+(17*8)(r31)
+ lfd fp18,_UC_FREGS+(18*8)(r31)
+ lfd fp19,_UC_FREGS+(19*8)(r31)
+ lfd fp20,_UC_FREGS+(20*8)(r31)
+ lfd fp21,_UC_FREGS+(21*8)(r31)
+ lfd fp22,_UC_FREGS+(22*8)(r31)
+ lfd fp23,_UC_FREGS+(23*8)(r31)
+ lfd fp24,_UC_FREGS+(24*8)(r31)
+ lfd fp25,_UC_FREGS+(25*8)(r31)
+ lfd fp26,_UC_FREGS+(26*8)(r31)
+ lfd fp27,_UC_FREGS+(27*8)(r31)
+ lfd fp28,_UC_FREGS+(28*8)(r31)
+ lfd fp29,_UC_FREGS+(29*8)(r31)
+ lfd fp30,_UC_FREGS+(30*8)(r31)
+ lfd fp31,_UC_FREGS+(31*8)(r31)
+#endif /* __CONTEXT_ENABLE_FPRS */
+
+ /* Restore LR and CCR, and set CTR to the NIP value */
+ lwz r3,_UC_GREGS+(PT_LNK*4)(r31)
+ lwz r4,_UC_GREGS+(PT_NIP*4)(r31)
+ lwz r5,_UC_GREGS+(PT_CCR*4)(r31)
+ mtlr r3
+ mtctr r4
+ mtcr r5
+
+ /* Restore the general registers */
+ lwz r3,_UC_GREGS+(PT_R3*4)(r31)
+ lwz r4,_UC_GREGS+(PT_R4*4)(r31)
+ lwz r5,_UC_GREGS+(PT_R5*4)(r31)
+ lwz r6,_UC_GREGS+(PT_R6*4)(r31)
+ lwz r7,_UC_GREGS+(PT_R7*4)(r31)
+ lwz r8,_UC_GREGS+(PT_R8*4)(r31)
+ lwz r9,_UC_GREGS+(PT_R9*4)(r31)
+ lwz r10,_UC_GREGS+(PT_R10*4)(r31)
+ lwz r11,_UC_GREGS+(PT_R11*4)(r31)
+ lwz r12,_UC_GREGS+(PT_R12*4)(r31)
+ lwz r13,_UC_GREGS+(PT_R13*4)(r31)
+ lwz r14,_UC_GREGS+(PT_R14*4)(r31)
+ lwz r15,_UC_GREGS+(PT_R15*4)(r31)
+ lwz r16,_UC_GREGS+(PT_R16*4)(r31)
+ lwz r17,_UC_GREGS+(PT_R17*4)(r31)
+ lwz r18,_UC_GREGS+(PT_R18*4)(r31)
+ lwz r19,_UC_GREGS+(PT_R19*4)(r31)
+ lwz r20,_UC_GREGS+(PT_R20*4)(r31)
+ lwz r21,_UC_GREGS+(PT_R21*4)(r31)
+ lwz r22,_UC_GREGS+(PT_R22*4)(r31)
+ lwz r23,_UC_GREGS+(PT_R23*4)(r31)
+ lwz r24,_UC_GREGS+(PT_R24*4)(r31)
+ lwz r25,_UC_GREGS+(PT_R25*4)(r31)
+ lwz r26,_UC_GREGS+(PT_R26*4)(r31)
+ lwz r27,_UC_GREGS+(PT_R27*4)(r31)
+ lwz r28,_UC_GREGS+(PT_R28*4)(r31)
+ lwz r29,_UC_GREGS+(PT_R29*4)(r31)
+ lwz r30,_UC_GREGS+(PT_R30*4)(r31)
+ lwz r1,_UC_GREGS+(PT_R1*4)(r31)
+ lwz r31,_UC_GREGS+(PT_R31*4)(r31)
+
+ bctr
+
+3:/*L(error_exit):*/
+ lwz r0,_FRAME_LR_SAVE+16(r1)
+ addi r1,r1,16
+ mtlr r0
+ blr
+
+4:/*L(do_sigret):*/
+ addi r1,r4,-0xd0
+ li r0,SYS_ify(rt_sigreturn)
+ sc
+ /* NOTREACHED */
+
+END(__CONTEXT_FUNC_NAME)
+
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S
new file mode 100644
index 000000000..0605f3d10
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S
@@ -0,0 +1,84 @@
+/* Save current context and jump to a new context.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+#include <shlib-compat.h>
+#include <kernel-features.h>
+
+#define __ASSEMBLY__
+#include <asm/ptrace.h>
+#include "ucontext_i.h"
+
+#define __CONTEXT_FUNC_NAME __swapcontext
+#define __CONTEXT_ENABLE_FPRS 1
+#define __CONTEXT_ENABLE_VRS 1
+
+/* Size of ucontext in GLIBC_2.3.4 and later. */
+#define _UC_SIZE_2_3_4 1184
+
+#ifdef __ASSUME_SWAPCONTEXT_SYSCALL
+ .section ".text";
+ENTRY (__swapcontext)
+ li r5,_UC_SIZE_2_3_4;
+ DO_CALL (SYS_ify (swapcontext));
+ bso- cr0,1f
+/* the kernel does not set the return code for the success case */
+ li r3,0
+ blr
+1:
+ b __syscall_error@local
+END(__swapcontext)
+#else
+# include "swapcontext-common.S"
+#endif
+
+versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_4)
+
+#if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)
+
+ compat_text_section
+
+# undef __CONTEXT_FUNC_NAME
+# define __CONTEXT_FUNC_NAME __novec_swapcontext
+# undef __CONTEXT_ENABLE_VRS
+
+# include "swapcontext-common.S"
+
+ .previous
+
+compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3_3)
+
+#endif
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
+
+# define _ERRNO_H 1
+# include <bits/errno.h>
+
+ compat_text_section
+ENTRY (__swapcontext_stub)
+ li r3,ENOSYS
+ b __syscall_error@local
+END (__swapcontext_stub)
+ .previous
+
+compat_symbol (libc, __swapcontext_stub, swapcontext, GLIBC_2_1)
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list
new file mode 100644
index 000000000..82025b485
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list
@@ -0,0 +1,5 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+# System calls with wrappers.
+oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0
+oldsetrlimit EXTRA setrlimit i:ip __old_setrlimit setrlimit@GLIBC_2.0
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
new file mode 100644
index 000000000..470da5aa6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
@@ -0,0 +1,297 @@
+/* Copyright (C) 1992,1997-2003,2004,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINUX_POWERPC_SYSDEP_H
+#define _LINUX_POWERPC_SYSDEP_H 1
+
+#include <sysdeps/unix/powerpc/sysdep.h>
+#include <tls.h>
+
+/* Some systen calls got renamed over time, but retained the same semantics.
+ Handle them here so they can be catched by both C and assembler stubs in
+ glibc. */
+
+#ifdef __NR_pread64
+# ifdef __NR_pread
+# error "__NR_pread and __NR_pread64 both defined???"
+# endif
+# define __NR_pread __NR_pread64
+#endif
+
+#ifdef __NR_pwrite64
+# ifdef __NR_pwrite
+# error "__NR_pwrite and __NR_pwrite64 both defined???"
+# endif
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+/* For Linux we can use the system call table in the header file
+ /usr/include/asm/unistd.h
+ of the kernel. But these symbols do not follow the SYS_* syntax
+ so we have to redefine the `SYS_ify' macro here. */
+#undef SYS_ify
+#ifdef __STDC__
+# define SYS_ify(syscall_name) __NR_##syscall_name
+#else
+# define SYS_ify(syscall_name) __NR_/**/syscall_name
+#endif
+
+#ifndef __ASSEMBLER__
+
+# include <errno.h>
+
+# ifdef SHARED
+# define INLINE_VSYSCALL(name, nr, args...) \
+ ({ \
+ __label__ out; \
+ __label__ iserr; \
+ INTERNAL_SYSCALL_DECL (sc_err); \
+ long int sc_ret; \
+ \
+ if (__vdso_##name != NULL) \
+ { \
+ sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, nr, ##args); \
+ if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
+ goto out; \
+ if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS) \
+ goto iserr; \
+ } \
+ \
+ sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, ##args); \
+ if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
+ { \
+ iserr: \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \
+ sc_ret = -1L; \
+ } \
+ out: \
+ sc_ret; \
+ })
+# else
+# define INLINE_VSYSCALL(name, nr, args...) \
+ INLINE_SYSCALL (name, nr, ##args)
+# endif
+
+# ifdef SHARED
+# define INTERNAL_VSYSCALL(name, err, nr, args...) \
+ ({ \
+ __label__ out; \
+ long int v_ret; \
+ \
+ if (__vdso_##name != NULL) \
+ { \
+ v_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \
+ if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err) \
+ || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS) \
+ goto out; \
+ } \
+ v_ret = INTERNAL_SYSCALL (name, err, nr, ##args); \
+ out: \
+ v_ret; \
+ })
+# else
+# define INTERNAL_VSYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL (name, err, nr, ##args)
+# endif
+
+# define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \
+ ({ \
+ long int sc_ret = ENOSYS; \
+ \
+ if (__vdso_##name != NULL) \
+ sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \
+ else \
+ err = 1 << 28; \
+ sc_ret; \
+ })
+
+/* List of system calls which are supported as vsyscalls. */
+# define HAVE_CLOCK_GETRES_VSYSCALL 1
+# define HAVE_CLOCK_GETTIME_VSYSCALL 1
+
+/* Define a macro which expands inline into the wrapper code for a VDSO
+ call. This use is for internal calls that do not need to handle errors
+ normally. It will never touch errno.
+ On powerpc a system call basically clobbers the same registers like a
+ function call, with the exception of LR (which is needed for the
+ "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
+ an error return status). */
+# define INTERNAL_VSYSCALL_NCS(funcptr, err, nr, args...) \
+ ({ \
+ register void *r0 __asm__ ("r0"); \
+ register long int r3 __asm__ ("r3"); \
+ register long int r4 __asm__ ("r4"); \
+ register long int r5 __asm__ ("r5"); \
+ register long int r6 __asm__ ("r6"); \
+ register long int r7 __asm__ ("r7"); \
+ register long int r8 __asm__ ("r8"); \
+ register long int r9 __asm__ ("r9"); \
+ register long int r10 __asm__ ("r10"); \
+ register long int r11 __asm__ ("r11"); \
+ register long int r12 __asm__ ("r12"); \
+ LOADARGS_##nr (funcptr, args); \
+ __asm__ __volatile__ \
+ ("mtctr %0\n\t" \
+ "bctrl\n\t" \
+ "mfcr %0" \
+ : "=&r" (r0), \
+ "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \
+ "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \
+ : ASM_INPUT_##nr \
+ : "cr0", "ctr", "lr", "memory"); \
+ err = (long int) r0; \
+ (int) r3; \
+ })
+
+# undef INLINE_SYSCALL
+# define INLINE_SYSCALL(name, nr, args...) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (sc_err); \
+ long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \
+ if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
+ { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \
+ sc_ret = -1L; \
+ } \
+ sc_ret; \
+ })
+
+/* Define a macro which expands inline into the wrapper code for a system
+ call. This use is for internal calls that do not need to handle errors
+ normally. It will never touch errno.
+ On powerpc a system call basically clobbers the same registers like a
+ function call, with the exception of LR (which is needed for the
+ "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
+ an error return status). */
+
+# undef INTERNAL_SYSCALL_DECL
+# define INTERNAL_SYSCALL_DECL(err) long int err
+
+# undef INTERNAL_SYSCALL
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ register long int r0 __asm__ ("r0"); \
+ register long int r3 __asm__ ("r3"); \
+ register long int r4 __asm__ ("r4"); \
+ register long int r5 __asm__ ("r5"); \
+ register long int r6 __asm__ ("r6"); \
+ register long int r7 __asm__ ("r7"); \
+ register long int r8 __asm__ ("r8"); \
+ register long int r9 __asm__ ("r9"); \
+ register long int r10 __asm__ ("r10"); \
+ register long int r11 __asm__ ("r11"); \
+ register long int r12 __asm__ ("r12"); \
+ LOADARGS_##nr(name, args); \
+ __asm__ __volatile__ \
+ ("sc \n\t" \
+ "mfcr %0" \
+ : "=&r" (r0), \
+ "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \
+ "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \
+ : ASM_INPUT_##nr \
+ : "cr0", "ctr", "memory"); \
+ err = r0; \
+ (int) r3; \
+ })
+# define INTERNAL_SYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
+
+# undef INTERNAL_SYSCALL_ERROR_P
+# define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((void) (val), __builtin_expect ((err) & (1 << 28), 0))
+
+# undef INTERNAL_SYSCALL_ERRNO
+# define INTERNAL_SYSCALL_ERRNO(val, err) (val)
+
+# define LOADARGS_0(name, dummy) \
+ r0 = name
+# define LOADARGS_1(name, __arg1) \
+ long int arg1 = (long int) (__arg1); \
+ LOADARGS_0(name, 0); \
+ extern void __illegally_sized_syscall_arg1 (void); \
+ if (__builtin_classify_type (__arg1) != 5 && sizeof (__arg1) > 4) \
+ __illegally_sized_syscall_arg1 (); \
+ r3 = arg1
+# define LOADARGS_2(name, __arg1, __arg2) \
+ long int arg2 = (long int) (__arg2); \
+ LOADARGS_1(name, __arg1); \
+ extern void __illegally_sized_syscall_arg2 (void); \
+ if (__builtin_classify_type (__arg2) != 5 && sizeof (__arg2) > 4) \
+ __illegally_sized_syscall_arg2 (); \
+ r4 = arg2
+# define LOADARGS_3(name, __arg1, __arg2, __arg3) \
+ long int arg3 = (long int) (__arg3); \
+ LOADARGS_2(name, __arg1, __arg2); \
+ extern void __illegally_sized_syscall_arg3 (void); \
+ if (__builtin_classify_type (__arg3) != 5 && sizeof (__arg3) > 4) \
+ __illegally_sized_syscall_arg3 (); \
+ r5 = arg3
+# define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
+ long int arg4 = (long int) (__arg4); \
+ LOADARGS_3(name, __arg1, __arg2, __arg3); \
+ extern void __illegally_sized_syscall_arg4 (void); \
+ if (__builtin_classify_type (__arg4) != 5 && sizeof (__arg4) > 4) \
+ __illegally_sized_syscall_arg4 (); \
+ r6 = arg4
+# define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
+ long int arg5 = (long int) (__arg5); \
+ LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
+ extern void __illegally_sized_syscall_arg5 (void); \
+ if (__builtin_classify_type (__arg5) != 5 && sizeof (__arg5) > 4) \
+ __illegally_sized_syscall_arg5 (); \
+ r7 = arg5
+# define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
+ long int arg6 = (long int) (__arg6); \
+ LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
+ extern void __illegally_sized_syscall_arg6 (void); \
+ if (__builtin_classify_type (__arg6) != 5 && sizeof (__arg6) > 4) \
+ __illegally_sized_syscall_arg6 (); \
+ r8 = arg6
+
+# define ASM_INPUT_0 "0" (r0)
+# define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
+# define ASM_INPUT_2 ASM_INPUT_1, "2" (r4)
+# define ASM_INPUT_3 ASM_INPUT_2, "3" (r5)
+# define ASM_INPUT_4 ASM_INPUT_3, "4" (r6)
+# define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
+# define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
+
+#endif /* __ASSEMBLER__ */
+
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. */
+#else
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(reg, tmpreg) \
+ lwz tmpreg,POINTER_GUARD(r2); \
+ xor reg,tmpreg,reg
+# define PTR_MANGLE2(reg, tmpreg) \
+ xor reg,tmpreg,reg
+# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg)
+# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg)
+# else
+# define PTR_MANGLE(var) \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+# define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#endif
+
+#endif /* linux/powerpc/powerpc32/sysdep.h */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c
new file mode 100644
index 000000000..f107e8437
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c
@@ -0,0 +1,79 @@
+/* Copyright (C) 1997,1998,1999,2000,2002,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_truncate64
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+/* The variable is shared between all wrappers around *truncate64 calls. */
+int __have_no_truncate64;
+#endif
+
+
+/* Truncate the file FD refers to to LENGTH bytes. */
+int
+truncate64 (path, length)
+ const char *path;
+ off64_t length;
+{
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ if (! __have_no_truncate64)
+#endif
+ {
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ int saved_errno = errno;
+#endif
+ /* On PPC32 64bit values are aligned in odd/even register pairs. */
+ int result = INLINE_SYSCALL (truncate64, 4, CHECK_STRING (path), 0,
+ (long) (length >> 32),
+ (long) length);
+
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ if (result != -1 || errno != ENOSYS)
+#endif
+ return result;
+
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ __set_errno (saved_errno);
+ __have_no_truncate64 = 1;
+#endif
+ }
+
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ if ((off_t) length != length)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ return __truncate (path, (off_t) length);
+#endif
+}
+
+#else
+/* Use the generic implementation. */
+# include <misc/truncate64.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.sym b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.sym
new file mode 100644
index 000000000..293761f26
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.sym
@@ -0,0 +1,26 @@
+#include <stddef.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+--
+
+SIG_BLOCK
+SIG_SETMASK
+
+-- Offsets in ucontext_t.
+#define ucontext(member) offsetof (ucontext_t, member)
+_UC_LINK ucontext (uc_link)
+_UC_STACK_SP ucontext (uc_stack.ss_sp)
+_UC_STACK_SIZE ucontext (uc_stack.ss_size)
+_UC_REGS_PTR ucontext (uc_mcontext.uc_regs)
+_UC_SIGMASK ucontext (uc_sigmask)
+_UC_REG_SPACE ucontext (uc_reg_space)
+
+-- Offsets in mcontext_t.
+#define mcontext(member) offsetof (mcontext_t, member)
+_UC_GREGS mcontext (gregs)
+_UC_FREGS mcontext (fpregs)
+_UC_VREGS mcontext (vrregs)
+_UC_VREGS mcontext (vrregs)
+_UC_VSCR mcontext (vrregs.vscr)
+_UC_VRSAVE mcontext (vrregs.vrsave)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S
new file mode 100644
index 000000000..66a149f10
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S
@@ -0,0 +1,59 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+
+#ifdef __NR_vfork
+
+ DO_CALL (SYS_ify (vfork))
+
+# ifdef __ASSUME_VFORK_SYSCALL
+ PSEUDO_RET
+# else
+ bnslr+
+ /* Check if vfork syscall is known at all. */
+ cmpwi r3,ENOSYS
+ bne- .Lsyscall_error
+
+# endif
+#endif
+
+#ifndef __ASSUME_VFORK_SYSCALL
+ /* If we don't have vfork, fork is close enough. */
+
+ DO_CALL (SYS_ify (fork))
+ bnslr+
+
+.Lsyscall_error:
+ b __syscall_error@local
+#endif
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/xstat.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/xstat.c
new file mode 100644
index 000000000..e9869f550
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/xstat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/xstat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Implies b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Implies
new file mode 100644
index 000000000..8d91c8009
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Implies
@@ -0,0 +1 @@
+unix/sysv/linux/wordsize-64
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
new file mode 100644
index 000000000..8334741ae
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions
@@ -0,0 +1,22 @@
+libc {
+ GLIBC_2.2 {
+ # functions used in other libraries
+
+ # g*
+ glob64;
+
+ # New rlimit interface
+ getrlimit; setrlimit; getrlimit64; setrlimit64;
+
+ # r*
+ readdir64; readdir64_r;
+
+ # s*
+ scandir64;
+ }
+ GLIBC_2.3.4 {
+ getcontext;
+ setcontext;
+ swapcontext;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
new file mode 100644
index 000000000..f2ac00d4c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
@@ -0,0 +1,50 @@
+/* brk system call for Linux. PowerPC64 version.
+ Copyright (C) 1995,96,97,99, 2000,02, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+ .comm __curbrk,8,8
+ .section ".toc","aw"
+.LC__curbrk:
+ .tc __curbrk[TC],__curbrk
+ .section ".text"
+ENTRY (BP_SYM (__brk))
+ CALL_MCOUNT 1
+ DISCARD_BOUNDS (r3) /* the bounds are meaningless, so toss 'em. */
+
+ stdu r1,-64(r1)
+ cfi_adjust_cfa_offset (64)
+ std r3,48(r1)
+ DO_CALL(SYS_ify(brk))
+ ld r6,48(r1)
+ ld r5,.LC__curbrk@toc(r2)
+ std r3,0(r5)
+ cmpld r6,r3
+ addi r1,r1,64
+ li r3,0
+ blelr+
+ li r3,ENOMEM
+ b JUMPTARGET(__syscall_error)
+END (BP_SYM (__brk))
+
+weak_alias (BP_SYM (__brk), BP_SYM (brk))
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
new file mode 100644
index 000000000..f1a55e64d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
@@ -0,0 +1,143 @@
+/* Wrapper around clone system call. PowerPC64 version.
+ Copyright (C) 1997,98,99,2000,02,04, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+#define CLONE_VM 0x00000100
+#define CLONE_THREAD 0x00010000
+
+/* This is the only really unusual system call in PPC linux, but not
+ because of any weirdness in the system call itself; because of
+ all the freaky stuff we have to do to make the call useful. */
+
+/* int [r3] clone(int (*fn)(void *arg) [r3], void *child_stack [r4],
+ int flags [r5], void *arg [r6], void *parent_tid [r7],
+ void *tls [r8], void *child_tid [r9]); */
+
+ENTRY (BP_SYM (__clone))
+ CALL_MCOUNT 7
+ /* GKM FIXME: add bounds checks, where sensible. */
+ DISCARD_BOUNDS (r4)
+ DISCARD_BOUNDS (r6)
+
+ /* Check for child_stack == NULL || fn == NULL. */
+ cmpdi cr0,r4,0
+ cmpdi cr1,r3,0
+ cror cr0*4+eq,cr1*4+eq,cr0*4+eq
+ beq- cr0,L(badargs)
+
+ /* Set up stack frame for parent. */
+ stdu r1,-80(r1)
+ cfi_adjust_cfa_offset (80)
+ std r29,56(r1)
+ std r30,64(r1)
+ std r31,72(r1)
+ cfi_offset(r29,-56)
+ cfi_offset(r30,-64)
+ cfi_offset(r31,-72)
+#ifdef RESET_PID
+ std r28,48(r1)
+ cfi_offset(r28,-48)
+#endif
+
+ /* Set up stack frame for child. */
+ clrrdi r4,r4,4
+ li r0,0
+ stdu r0,-48(r4) /* min stack frame is 48 bytes per ABI */
+
+ /* Save fn, args, stack across syscall. */
+ mr r29,r3 /* Function in r29. */
+ mr r30,r4 /* Stack pointer in r30. */
+#ifdef RESET_PID
+ mr r28,r5 /* Flags in r28. */
+#endif
+ mr r31,r6 /* Argument in r31. */
+
+ /* 'flags' argument is first parameter to clone syscall. (The other
+ argument is the stack pointer, already in r4.) */
+ mr r3,r5
+ /* Move the parent_tid, child_tid and tls arguments. */
+ mr r5,r7
+ mr r6,r8
+ mr r7,r9
+
+ /* End FDE now, because in the child the unwind info will be
+ wrong. */
+ cfi_endproc
+
+ /* Do the call. */
+ DO_CALL(SYS_ify(clone))
+
+ /* Check for child process. */
+ cmpdi cr1,r3,0
+ crandc cr1*4+eq,cr1*4+eq,cr0*4+so
+ bne- cr1,L(parent) /* The '-' is to minimise the race. */
+
+#ifdef RESET_PID
+ andis. r0,r28,CLONE_THREAD>>16
+ bne+ cr0,L(oldpid)
+ andi. r0,r28,CLONE_VM
+ li r3,-1
+ bne- cr0,L(nomoregetpid)
+ DO_CALL(SYS_ify(getpid))
+L(nomoregetpid):
+ stw r3,TID(r13)
+ stw r3,PID(r13)
+L(oldpid):
+#endif
+
+ std r2,40(r1)
+ /* Call procedure. */
+ ld r0,0(r29)
+ ld r2,8(r29)
+ mtctr r0
+ mr r3,r31
+ bctrl
+ ld r2,40(r1)
+ /* Call _exit with result from procedure. */
+#ifdef SHARED
+ b JUMPTARGET(__GI__exit)
+#else
+ b JUMPTARGET(_exit)
+#endif
+
+L(parent):
+ /* Parent. Restore registers & return. */
+#ifdef RESET_PID
+ ld r28,48(r1)
+#endif
+ ld r31,72(r1)
+ ld r30,64(r1)
+ ld r29,56(r1)
+ addi r1,r1,80
+ bnslr+
+ b JUMPTARGET(__syscall_error)
+
+L(badargs):
+ li r3,EINVAL
+ b JUMPTARGET(__syscall_error)
+
+ cfi_startproc
+END (BP_SYM (__clone))
+
+weak_alias (BP_SYM (__clone), BP_SYM (clone))
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/dl-cache.h b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/dl-cache.h
new file mode 100644
index 000000000..c12655834
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/dl-cache.h
@@ -0,0 +1,25 @@
+/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define _DL_CACHE_DEFAULT_ID 0x503
+
+#define _dl_cache_check_flags(flags) \
+ ((flags) == _DL_CACHE_DEFAULT_ID)
+
+#include_next <dl-cache.h>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c
new file mode 100644
index 000000000..e7ec85de6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <sysdep-cancel.h> /* Must come before <fcntl.h>. */
+#include <fcntl.h>
+#include <stdarg.h>
+
+#include <sys/syscall.h>
+
+
+#ifndef NO_CANCELLATION
+int
+__fcntl_nocancel (int fd, int cmd, ...)
+{
+ va_list ap;
+ void *arg;
+
+ va_start (ap, cmd);
+ arg = va_arg (ap, void *);
+ va_end (ap);
+
+ return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+}
+#endif
+
+
+int
+__libc_fcntl (int fd, int cmd, ...)
+{
+ va_list ap;
+ void *arg;
+
+ va_start (ap, cmd);
+ arg = va_arg (ap, void *);
+ va_end (ap);
+
+ if (cmd >= F_GETLK64 && cmd <= F_SETLKW64)
+ cmd -= F_GETLK64 - F_GETLK;
+
+ if (SINGLE_THREAD_P || cmd != F_SETLKW)
+ return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+libc_hidden_def (__libc_fcntl)
+
+weak_alias (__libc_fcntl, __fcntl)
+libc_hidden_weak (__fcntl)
+weak_alias (__libc_fcntl, fcntl)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_nomask.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_nomask.c
new file mode 100644
index 000000000..62f735514
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_nomask.c
@@ -0,0 +1,43 @@
+/* Procedure definition for FE_NOMASK_ENV for Linux/ppc64.
+ Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <errno.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <sys/prctl.h>
+#include <kernel-features.h>
+
+const fenv_t *
+__fe_nomask_env (void)
+{
+#if defined PR_SET_FPEXC && defined PR_FP_EXC_PRECISE
+ int result;
+ INTERNAL_SYSCALL_DECL (err);
+ result = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, PR_FP_EXC_PRECISE);
+# ifndef __ASSUME_NEW_PRCTL_SYSCALL
+ if (INTERNAL_SYSCALL_ERROR_P (result, err)
+ && INTERNAL_SYSCALL_ERRNO (result, err) == EINVAL)
+ __set_errno (ENOSYS);
+# endif
+#else
+ __set_errno (ENOSYS);
+#endif
+ return FE_ENABLED_ENV;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies
new file mode 100644
index 000000000..6243d2ef2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies
@@ -0,0 +1,2 @@
+# Override ldbl-opt with powerpc64 specific routines.
+powerpc/powerpc64/fpu
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S
new file mode 100644
index 000000000..8d7c959ff
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S
@@ -0,0 +1,411 @@
+/* Save current context.
+ Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+#include <shlib-compat.h>
+#include <kernel-features.h>
+
+#define __ASSEMBLY__
+#include <asm/ptrace.h>
+#include <asm/errno.h>
+#include "ucontext_i.h"
+
+
+#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
+ENTRY(__novec_getcontext)
+ CALL_MCOUNT 1
+#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
+ std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
+ std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
+ mflr r0
+ std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
+ std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
+ std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
+ std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
+ std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
+ std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
+ std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
+ std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
+ std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
+ std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
+ std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
+ std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
+ std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
+ std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
+ std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
+ std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
+ std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
+ std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
+ std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
+ std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
+ std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
+ std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
+ std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
+ std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
+ std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
+ std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
+ std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
+ std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
+ mfctr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
+ mfxer r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
+ mfcr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
+
+ /* Set the return value of swapcontext to "success". R3 is the only
+ register whose value is not preserved in the saved context. */
+ li r0,0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
+
+ /* Zero fill fields that can't be set in user state or are unused. */
+ std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
+
+ /* Set the PT_REGS pointer to the address of sigcontext's gp_regs
+ field. Struct pt_regs and elf_gregset_t are the same thing.
+ We kept the regs field for backwards compatibility with
+ libraries built before we extended sigcontext. */
+ addi r0,r3,SIGCONTEXT_GP_REGS
+ std r0,SIGCONTEXT_PT_REGS(r3)
+
+ stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
+ stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
+ stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
+ stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
+ stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
+ stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
+ stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
+ stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
+ stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
+ stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
+ stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
+ stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
+ stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
+ stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
+ stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
+ stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
+ stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
+ stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
+ stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
+ stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
+ stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
+ stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
+ stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
+ stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
+ stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
+ stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
+ stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
+ stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
+ stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
+ stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
+ mffs fp0
+ stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
+ stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
+ stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
+
+ addi r5,r3,UCONTEXT_SIGMASK
+ li r4,0
+ li r3,SIG_BLOCK
+ bl JUMPTARGET(__sigprocmask)
+ nop
+#else
+ /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
+ mflr r0
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset(128)
+ li r3,ENOSYS
+ bl JUMPTARGET(__syscall_error)
+ nop
+ li r3,-1
+#endif
+
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ blr
+PSEUDO_END(__novec_getcontext)
+
+compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3)
+
+#endif
+
+ .section ".toc","aw"
+.LC__dl_hwcap:
+#ifdef SHARED
+ .tc _rtld_global_ro[TC],_rtld_global_ro
+#else
+ .tc _dl_hwcap[TC],_dl_hwcap
+#endif
+ .section ".text"
+
+ .machine "altivec"
+ENTRY(__getcontext)
+ CALL_MCOUNT 1
+#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
+ std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
+ std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
+ mflr r0
+ std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
+ std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
+ std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
+ std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
+ std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
+ std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
+ std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
+ std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
+ std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
+ std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
+ std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
+ std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
+ std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
+ std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
+ std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
+ std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
+ std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
+ std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
+ std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
+ std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
+ std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
+ std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
+ std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
+ std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
+ std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
+ std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
+ std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
+ std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
+ mfctr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
+ mfxer r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
+ mfcr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
+
+ /* Set the return value of swapcontext to "success". R3 is the only
+ register whose value is not preserved in the saved context. */
+ li r0,0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
+
+ /* Zero fill fields that can't be set in user state or are unused. */
+ std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
+
+ /* Set the PT_REGS pointer to the address of sigcontext's gp_regs
+ field. Struct pt_regs and elf_gregset_t are the same thing.
+ We kept the regs field for backwards compatibility with
+ libraries built before we extended sigcontext. */
+ addi r0,r3,SIGCONTEXT_GP_REGS
+ std r0,SIGCONTEXT_PT_REGS(r3)
+
+ stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
+ stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
+ stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
+ stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
+ stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
+ stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
+ stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
+ stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
+ stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
+ stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
+ stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
+ stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
+ stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
+ stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
+ stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
+ stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
+ stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
+ stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
+ stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
+ stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
+ stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
+ stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
+ stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
+ stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
+ stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
+ stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
+ stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
+ stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
+ stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
+ stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
+ mffs fp0
+ stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
+ stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
+ stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
+
+ ld r5,.LC__dl_hwcap@toc(r2)
+# ifdef SHARED
+/* Load _rtld-global._dl_hwcap. */
+ ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
+# else
+ ld r5,0(r5) /* Load extern _dl_hwcap. */
+# endif
+ la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
+ la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
+
+ andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+
+ clrrdi r10,r10,4
+ beq L(has_no_vec)
+ clrrdi r9,r9,4
+ mr r5,r10 /* Capture *v_regs value in r5. */
+
+ stvx v0,0,r10
+ stvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v2,0,r10
+ stvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v4,0,r10
+ stvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v6,0,r10
+ stvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v8,0,r10
+ stvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v10,0,r10
+ stvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v12,0,r10
+ stvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v14,0,r10
+ stvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v16,0,r10
+ stvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v18,0,r10
+ stvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v20,0,r10
+ stvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v22,0,r10
+ stvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v24,0,r10
+ stvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v26,0,r10
+ stvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v28,0,r10
+ stvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v30,0,r10
+ stvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mfvscr v0
+ mfspr r0,VRSAVE
+ stvx v0,0,r10
+ stw r0,0(9)
+
+L(has_no_vec):
+/*
+ Store either a NULL or a quadword aligned pointer to the Vector register
+ array into *v_regs.
+*/
+ std r5,(SIGCONTEXT_V_REGS_PTR)(r3)
+
+ addi r5,r3,UCONTEXT_SIGMASK
+ li r4,0
+ li r3,SIG_BLOCK
+ bl JUMPTARGET(__sigprocmask)
+ nop
+#else
+ /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
+ mflr r0
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ li r3,ENOSYS
+ bl JUMPTARGET(__syscall_error)
+ nop
+ li r3,-1
+#endif
+
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ blr
+PSEUDO_END(__getcontext)
+
+versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_4)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/kernel_stat.h b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/kernel_stat.h
new file mode 100644
index 000000000..8a43ea4a1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/kernel_stat.h
@@ -0,0 +1,21 @@
+/* Definition of `struct stat' used in the kernel.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define STAT_IS_KERNEL_STAT 1
+#define XSTAT_IS_XSTAT64 1
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h
new file mode 100644
index 000000000..1ead3dd63
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h
@@ -0,0 +1,77 @@
+/* Run-time dynamic linker data structures for loaded ELF shared objects.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LDSODEFS_H
+
+/* Get the real definitions. */
+#include_next <ldsodefs.h>
+
+/* Now define our stuff. */
+
+static __always_inline bool
+_dl_ppc64_is_opd_sym (const struct link_map *l, const ElfW(Sym) *sym)
+{
+ return (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC
+ && l->l_addr + sym->st_value >= (ElfW(Addr)) l->l_ld
+ && l->l_addr + sym->st_value < l->l_map_end
+ && sym->st_size != 0);
+}
+
+static __always_inline bool
+_dl_ppc64_addr_sym_match (const struct link_map *l, const ElfW(Sym) *sym,
+ const ElfW(Sym) *matchsym, ElfW(Addr) addr)
+{
+ ElfW(Addr) value = l->l_addr + sym->st_value;
+ if (_dl_ppc64_is_opd_sym (l, sym))
+ {
+ if (addr < value || addr >= value + 24)
+ {
+ value = *(ElfW(Addr) *) value;
+ if (addr < value || addr >= value + sym->st_size)
+ return false;
+ }
+ }
+ else if (sym->st_size == 0)
+ {
+ if (addr != value)
+ return false;
+ }
+ else if (addr < value || addr >= value + sym->st_size)
+ return false;
+
+ if (matchsym == NULL)
+ return true;
+
+ ElfW(Addr) matchvalue = l->l_addr + matchsym->st_value;
+ if (_dl_ppc64_is_opd_sym (l, matchsym)
+ && (addr < matchvalue || addr > matchvalue + 24))
+ matchvalue = *(ElfW(Addr) *) matchvalue;
+
+ return matchvalue < value;
+}
+
+/* If this is a function symbol defined past the end of our dynamic
+ section, then it must be a function descriptor. Allow these symbols
+ to match their associated function code range as well as the
+ descriptor addresses. */
+#undef DL_ADDR_SYM_MATCH
+#define DL_ADDR_SYM_MATCH(L, SYM, MATCHSYM, ADDR) \
+ _dl_ppc64_addr_sym_match (L, SYM, MATCHSYM, ADDR)
+
+#endif /* ldsodefs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
new file mode 100644
index 000000000..4a82802d9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
@@ -0,0 +1,187 @@
+/* Create new context.
+ Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <kernel-features.h>
+
+#define __ASSEMBLY__
+#include <asm/ptrace.h>
+#include "ucontext_i.h"
+#include <asm/errno.h>
+
+ENTRY(__makecontext)
+ CALL_MCOUNT 3
+#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
+ /* Save parameters into the parameter save area of callers frame. */
+ std r3,FRAME_PARM1_SAVE(r1) /* ucontext_t *ucp */
+ std r4,FRAME_PARM2_SAVE(r1) /* void (*func)(void) */
+ std r5,FRAME_PARM3_SAVE(r1) /* int argc */
+ std r6,FRAME_PARM4_SAVE(r1) /* ... */
+ std r7,FRAME_PARM5_SAVE(r1)
+ std r8,FRAME_PARM6_SAVE(r1)
+ std r9,FRAME_PARM7_SAVE(r1)
+ std r10,FRAME_PARM8_SAVE(r1)
+ mflr r0
+ /* Get the address of the target functions first parameter. */
+ addi r6,r1,FRAME_PARM4_SAVE
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+
+ /* Get the ucontexts stack pointer and size. Compute the top of stack
+ and round down to a quadword boundary. Then stack a dummy frame
+ with a null back chain. We store the context pointer in the frames
+ "compiler double word" field so we can recover if is the function
+ returns. Finally save the callers link register and TOC pointer
+ into this frame so the debugger can display a backtrace.
+ */
+ ld r7,UCONTEXT_STACK_SP(r3)
+ ld r0,UCONTEXT_STACK_SIZE(r3)
+ add r7,r7,r0
+ clrrdi r7,r7,4
+ li r0,0
+ stdu r0,-64(r7)
+ std r3,FRAME_PARM1_SAVE(r7) /* Store context in dummy parm1. */
+ mflr r0
+ std r2,FRAME_TOC_SAVE(r7) /* Store the TOC pointer for later. */
+ std r0,FRAME_LR_SAVE(r7)
+
+ /* Now we need to stack another frame to hold the parameter save area
+ for the function. We need to allocate a frame with the minimum 48
+ byte header and 8 parameter register. However if there are more
+ than 8 parameters addition space is need to hold all the parameters.
+ The total size it rounded up to a quadword multiple then a frame is
+ stacked. This address is stored in the ucontext as GPR 1. */
+
+ cmpdi cr1,r5,8
+ sldi r8,r5,3
+ bgt cr1,L(gt8)
+ li r8,64
+L(gt8):
+ addi r8,r8,FRAME_PARM_SAVE+8 /* Add header plus rounding factor. */
+ clrrdi r8,r8,4 /* Round down to quadword. */
+
+ subf r8,r8,r7
+ std r7,0(r8) /* Stack the frame. */
+ std r8,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
+
+ /* Now we need to copy the target functions parameters. The functions
+ parameters are saved in the parameter save area. We skip over the
+ first three parameters and copy up to 8 double word into the
+ SIGCONTEXT_GP_REGS starting with R3. If there are more than 8
+ parameters then doublewords 8-N are copied into the parameter
+ save area of the context frame. */
+ cmpdi r5,0
+ beq L(noparms)
+ mr r0,r5
+ ble cr1,L(le8)
+ li r0,8
+L(le8):
+ mtctr r0
+ addi r7,r6,-8
+ addi r9,r3,(SIGCONTEXT_GP_REGS+(PT_R3*8)-8)
+L(parmloop2):
+ ldu r0,8(r7)
+ stdu r0,8(r9)
+ bdnz L(parmloop2)
+
+ addi r0,r5,-8
+ ble cr1,L(noparms)
+ mtctr r0
+ addi r9,r8,FRAME_PARM9_SAVE-8
+L(parmloop):
+ ldu r0,8(r7)
+ stdu r0,8(r9)
+ bdnz L(parmloop)
+
+L(noparms):
+
+ /* Load the function address and TOC from the function descriptor
+ and store them in the ucontext as NIP and r2. Store the 3rd
+ field of the function descriptor into the ucontext as r11 in case
+ the calling language needs the "environment pointer". */
+ ld r0,0(r4)
+ ld r10,8(r4);
+ ld r9,16(r4);
+ std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
+ std r10,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
+ std r9,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
+
+ /* If the target function returns we need to do some cleanup. We use a
+ code trick to get the address of our cleanup function into the link
+ register. Do not add any code between here and L(exitcode). */
+ bl L(gotexitcodeaddr);
+
+ /* This is the helper code which gets called if a function which
+ is registered with 'makecontext' returns. In this case we
+ have to install the context listed in the uc_link element of
+ the context 'makecontext' manipulated at the time of the
+ 'makecontext' call. If the pointer is NULL the process must
+ terminate. */
+L(exitcode):
+ /* Recover the ucontext and TOC from the dummy frame. */
+ ld r1,FRAME_BACKCHAIN(r1) /* Unstack the parameter save area frame. */
+ ld r3,FRAME_PARM1_SAVE(r1)
+ ld r2,FRAME_TOC_SAVE(r1)
+ ld r3,UCONTEXT_LINK(r3) /* Load the resume context. */
+ cmpdi r3,0
+ beq L(BADSTATUS)
+ bl JUMPTARGET(__setcontext)
+ nop
+
+L(BADSTATUS):
+/* If setcontext returns (which can happen if the syscall fails) we will
+ exit the program with error status (-1). */
+ li r3,-1
+#ifdef SHARED
+ b JUMPTARGET(__GI_exit);
+#else
+ b JUMPTARGET(exit);
+#endif
+
+ /* The address of the exit code is in the link register. Store the lr
+ in the ucontext as LNK so the target function will return to our
+ exit code. */
+L(gotexitcodeaddr):
+ mflr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ blr
+#else
+ /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
+ mflr r0
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ li r3,ENOSYS
+ bl JUMPTARGET(__syscall_error)
+ nop
+ li r3,-1
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ blr
+#endif
+END(__makecontext)
+
+weak_alias (__makecontext, makecontext)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c
new file mode 100644
index 000000000..315d1195e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c
@@ -0,0 +1,85 @@
+/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
+
+# if __ASSUME_PREAD_SYSCALL == 0
+static ssize_t __emulate_pread (int fd, void *buf, size_t count,
+ off_t offset) internal_function;
+# endif
+
+
+ssize_t
+__libc_pread (fd, buf, count, offset)
+ int fd;
+ void *buf;
+ size_t count;
+ off_t offset;
+{
+ ssize_t result;
+
+ if (SINGLE_THREAD_P)
+ {
+ result = INLINE_SYSCALL (pread, 4, fd, CHECK_N (buf, count), count,
+ offset);
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread (fd, buf, count, offset);
+# endif
+
+ return result;
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ result = INLINE_SYSCALL (pread, 4, fd, CHECK_N (buf, count), count,
+ offset);
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread (fd, buf, count, offset);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+strong_alias (__libc_pread, __pread)
+weak_alias (__libc_pread, pread)
+
+# define __libc_pread(fd, buf, count, offset) \
+ static internal_function __emulate_pread (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c
new file mode 100644
index 000000000..f775e1f1e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c
@@ -0,0 +1,84 @@
+/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
+
+# if __ASSUME_PREAD_SYSCALL == 0
+static ssize_t __emulate_pread64 (int fd, void *buf, size_t count,
+ off64_t offset) internal_function;
+# endif
+
+
+ssize_t
+__libc_pread64 (fd, buf, count, offset)
+ int fd;
+ void *buf;
+ size_t count;
+ off64_t offset;
+{
+ ssize_t result;
+
+ if (SINGLE_THREAD_P)
+ {
+ result = INLINE_SYSCALL (pread, 4, fd, CHECK_N (buf, count), count,
+ offset);
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread64 (fd, buf, count, offset);
+# endif
+
+ return result;
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ result = INLINE_SYSCALL (pread, 4, fd, CHECK_N (buf, count), count,
+ offset);
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread64 (fd, buf, count, offset);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+weak_alias (__libc_pread64, __pread64)
+weak_alias (__libc_pread64, pread64)
+
+# define __libc_pread64(fd, buf, count, offset) \
+ static internal_function __emulate_pread64 (fd, buf, count, offset)
+#endif
+
+# if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread64.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c
new file mode 100644
index 000000000..0f509154e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c
@@ -0,0 +1,85 @@
+/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
+
+# if __ASSUME_PWRITE_SYSCALL == 0
+static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count,
+ off_t offset) internal_function;
+# endif
+
+
+ssize_t
+__libc_pwrite (fd, buf, count, offset)
+ int fd;
+ const void *buf;
+ size_t count;
+ off_t offset;
+{
+ ssize_t result;
+
+ if (SINGLE_THREAD_P)
+ {
+ result = INLINE_SYSCALL (pwrite, 4, fd, CHECK_N (buf, count), count,
+ offset);
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite (fd, buf, count, offset);
+# endif
+
+ return result;
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ result = INLINE_SYSCALL (pwrite, 4, fd, CHECK_N (buf, count), count,
+ offset);
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite (fd, buf, count, offset);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+strong_alias (__libc_pwrite, __pwrite)
+weak_alias (__libc_pwrite, pwrite)
+
+# define __libc_pwrite(fd, buf, count, offset) \
+ static internal_function __emulate_pwrite (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c
new file mode 100644
index 000000000..22224324a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c
@@ -0,0 +1,85 @@
+/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
+
+# if __ASSUME_PWRITE_SYSCALL == 0
+static ssize_t __emulate_pwrite64 (int fd, const void *buf, size_t count,
+ off64_t offset) internal_function;
+# endif
+
+
+ssize_t
+__libc_pwrite64 (fd, buf, count, offset)
+ int fd;
+ const void *buf;
+ size_t count;
+ off64_t offset;
+{
+ ssize_t result;
+
+ if (SINGLE_THREAD_P)
+ {
+ result = INLINE_SYSCALL (pwrite, 4, fd, CHECK_N (buf, count), count,
+ offset);
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite64 (fd, buf, count, offset);
+# endif
+
+ return result;
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ result = INLINE_SYSCALL (pwrite, 4, fd, CHECK_N (buf, count), count,
+ offset);
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite64 (fd, buf, count, offset);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+weak_alias (__libc_pwrite64, __pwrite64)
+libc_hidden_weak (__pwrite64)
+weak_alias (__libc_pwrite64, pwrite64)
+
+# define __libc_pwrite64(fd, buf, count, offset) \
+ static internal_function __emulate_pwrite64 (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite64.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
new file mode 100644
index 000000000..48e9af363
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
@@ -0,0 +1,469 @@
+/* Switch to context.
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+#include <shlib-compat.h>
+#include <kernel-features.h>
+
+#define __ASSEMBLY__
+#include <asm/ptrace.h>
+#include "ucontext_i.h"
+#include <asm/errno.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
+ENTRY(__novec_setcontext)
+ CALL_MCOUNT 1
+#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
+ mflr r0
+ std r31,-8(1)
+ cfi_offset(r31,-8)
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ mr r31,r3
+
+/*
+ * If this ucontext refers to the point where we were interrupted
+ * by a signal, we have to use the rt_sigreturn system call to
+ * return to the context so we get both LR and CTR restored.
+ *
+ * Otherwise, the context we are restoring is either just after
+ * a procedure call (getcontext/swapcontext) or at the beginning
+ * of a procedure call (makecontext), so we don't need to restore
+ * msr and ctr. We don't restore r13 since it will be used as
+ * the TLS pointer. */
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
+ cmpdi r0,0
+ bne L(nv_do_sigret)
+
+ li r5,0
+ addi r4,r3,UCONTEXT_SIGMASK
+ li r3,SIG_SETMASK
+ bl JUMPTARGET(__sigprocmask)
+ nop
+ cmpdi r3,0
+ bne L(nv_error_exit)
+
+ lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
+ lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
+ lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
+ mtfsf 0xff,fp0
+ lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
+ lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
+ lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
+ lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
+ lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
+ lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
+ lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
+ lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
+ lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
+ lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
+ lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
+ lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
+ lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
+ lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
+ lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
+ lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
+ lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
+ lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
+ lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
+ lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
+ lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
+ lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
+ lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
+ lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
+ lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
+ lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
+ lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
+ lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
+ lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
+ lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
+
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
+ ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
+ mtlr r0
+ ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
+ ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
+ mtxer r0
+ ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
+ ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
+ mtcr r0
+ ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
+ ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
+ ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
+ ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
+ ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
+ ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
+ ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
+ /* Don't reload the thread ID or TLS pointer (r13). */
+ ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
+ ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
+ ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
+ ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
+ ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
+ ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
+ ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
+ ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
+ ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
+ ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
+ ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
+ ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
+ ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
+ ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
+ ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
+ ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
+ ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
+
+ /* Now we branch to the "Next Instruction Pointer" from the saved
+ context. With the powerpc64 instruction set there is no good way to
+ do this (from user state) without clobbering either the LR or CTR.
+ The makecontext and swapcontext functions depend on the callers
+ LR being preserved so we use the CTR. */
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
+ mtctr r0
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
+ ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
+ bctr
+
+L(nv_error_exit):
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ ld r31,-8(r1)
+ blr
+
+ /* At this point we assume that the ucontext was created by a
+ rt_signal and we should use rt_sigreturn to restore the original
+ state. As of the 2.4.21 kernel the ucontext is the first thing
+ (offset 0) in the rt_signal frame and rt_sigreturn expects the
+ ucontext address in R1. Normally the rt-signal trampoline handles
+ this by popping dummy frame before the rt_signal syscall. In our
+ case the stack may not be in its original (signal handler return with
+ R1 pointing at the dummy frame) state. We do have the ucontext
+ address in R3, so simply copy R3 to R1 before the syscall. */
+L(nv_do_sigret):
+ mr r1,r3,
+ li r0,SYS_ify(rt_sigreturn)
+ sc
+ /* No return. */
+#else
+ /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
+ mflr r0
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset(lr,FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset(128)
+ li r3,ENOSYS
+ bl JUMPTARGET(__syscall_error)
+ nop
+ li r3,-1
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ blr
+#endif
+
+PSEUDO_END(__novec_setcontext)
+
+compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3)
+
+#endif
+
+ .section ".toc","aw"
+.LC__dl_hwcap:
+#ifdef SHARED
+ .tc _rtld_global_ro[TC],_rtld_global_ro
+#else
+ .tc _dl_hwcap[TC],_dl_hwcap
+#endif
+ .section ".text"
+
+ .machine "altivec"
+ENTRY(__setcontext)
+ CALL_MCOUNT 1
+#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
+ mflr r0
+ std r31,-8(1)
+ cfi_offset(r31,-8)
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ mr r31,r3
+
+/*
+ * If this ucontext refers to the point where we were interrupted
+ * by a signal, we have to use the rt_sigreturn system call to
+ * return to the context so we get both LR and CTR restored.
+ *
+ * Otherwise, the context we are restoring is either just after
+ * a procedure call (getcontext/swapcontext) or at the beginning
+ * of a procedure call (makecontext), so we don't need to restore
+ * msr and ctr. We don't restore r13 since it will be used as
+ * the TLS pointer. */
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
+ cmpdi r0,0
+ bne L(do_sigret)
+
+ li r5,0
+ addi r4,r3,UCONTEXT_SIGMASK
+ li r3,SIG_SETMASK
+ bl JUMPTARGET(__sigprocmask)
+ nop
+ cmpdi r3,0
+ bne L(error_exit)
+
+ ld r5,.LC__dl_hwcap@toc(r2)
+ ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
+# ifdef SHARED
+/* Load _rtld-global._dl_hwcap. */
+ ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
+# else
+ ld r5,0(r5) /* Load extern _dl_hwcap. */
+# endif
+ andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ beq L(has_no_vec)
+
+ cmpdi r10,0
+ beq L(has_no_vec)
+ lwz r0,(33*16)(r10)
+
+ li r9,(16*32)
+ mtspr VRSAVE,r0
+ cmpwi r0,0
+ beq L(has_no_vec)
+
+ lvx v19,r9,r10
+ la r9,(16)(r10)
+
+ lvx v0,0,r10
+ lvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mtvscr v19
+ lvx v2,0,r10
+ lvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v4,0,r10
+ lvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v6,0,r10
+ lvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v8,0,r10
+ lvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v12,0,r10
+ lvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v14,0,r10
+ lvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v16,0,r10
+ lvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v18,0,r10
+ lvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v20,0,r10
+ lvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v22,0,r10
+ lvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v24,0,r10
+ lvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v26,0,r10
+ lvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v28,0,r10
+ lvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v30,0,r10
+ lvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+L(has_no_vec):
+ lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
+ lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
+ lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
+ mtfsf 0xff,fp0
+ lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
+ lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
+ lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
+ lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
+ lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
+ lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
+ lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
+ lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
+ lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
+ lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
+ lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
+ lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
+ lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
+ lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
+ lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
+ lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
+ lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
+ lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
+ lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
+ lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
+ lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
+ lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
+ lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
+ lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
+ lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
+ lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
+ lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
+ lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
+ lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
+ lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
+
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
+ ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
+ mtlr r0
+ ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
+ ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
+ mtxer r0
+ ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
+ ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
+ ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
+ ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
+ ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
+ ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
+ mtcr r0
+ ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
+ ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
+ ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
+ /* Don't reload the thread ID or TLS pointer (r13). */
+ ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
+ ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
+ ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
+ ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
+ ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
+ ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
+ ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
+ ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
+ ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
+ ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
+ ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
+ ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
+ ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
+ ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
+ ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
+ ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
+ ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
+
+ /* Now we branch to the "Next Instruction Pointer" from the saved
+ context. With the powerpc64 instruction set there is no good way to
+ do this (from user state) without clobbering either the LR or CTR.
+ The makecontext and swapcontext functions depend on the callers
+ LR being preserved so we use the CTR. */
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
+ mtctr r0
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
+ ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
+ bctr
+
+L(error_exit):
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ ld r31,-8(r1)
+ blr
+
+ /* At this point we assume that the ucontext was created by a
+ rt_signal and we should use rt_sigreturn to restore the original
+ state. As of the 2.4.21 kernel the ucontext is the first thing
+ (offset 0) in the rt_signal frame and rt_sigreturn expects the
+ ucontext address in R1. Normally the rt-signal trampoline handles
+ this by popping dummy frame before the rt_signal syscall. In our
+ case the stack may not be in its original (signal handler return with
+ R1 pointing at the dummy frame) state. We do have the ucontext
+ address in R3, so simply copy R3 to R1 before the syscall. */
+L(do_sigret):
+ mr r1,r3,
+ li r0,SYS_ify(rt_sigreturn)
+ sc
+ /* No return. */
+#else
+ /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
+ mflr r0
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ li r3,ENOSYS
+ bl JUMPTARGET(__syscall_error)
+ nop
+ li r3,-1
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ blr
+#endif
+
+PSEUDO_END(__setcontext)
+
+versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_4)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
new file mode 100644
index 000000000..15d8e84c1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
@@ -0,0 +1,123 @@
+/* Copyright (C) 1995,96,97,99, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 51 Franklin Street,
+ Fifth Floor, Boston MA 02110-1301, USA. */
+
+#include <sysdep-cancel.h>
+#include <socketcall.h>
+
+#define P(a, b) P2(a, b)
+#define P2(a, b) a##b
+
+/* The socket-oriented system calls are handled unusally in Linux.
+ They are all gated through the single `socketcall' system call number.
+ `socketcall' takes two arguments: the first is the subcode, specifying
+ which socket function is being called; and the second is a pointer to
+ the arguments to the specific function.
+
+ The .S files for the other calls just #define socket and #include this.
+ They also #define a 'number-of-arguments' word in NARGS, which
+ defaults to 3. */
+
+#ifndef NARGS
+#ifdef socket
+#error NARGS not defined
+#endif
+#define NARGS 3
+#endif
+
+#define stackblock 80 /* offset to socket parm area. */
+
+#ifndef __socket
+# ifndef NO_WEAK_ALIAS
+# define __socket P(__,socket)
+# else
+# define __socket socket
+# endif
+#endif
+
+ .text
+ENTRY(__socket)
+ CALL_MCOUNT NARGS
+ stdu r1,-144(r1)
+ cfi_adjust_cfa_offset(144)
+#if NARGS >= 1
+ std r3,stackblock(r1)
+#endif
+#if NARGS >= 2
+ std r4,8+stackblock(r1)
+#endif
+#if NARGS >= 3
+ std r5,16+stackblock(r1)
+#endif
+#if NARGS >= 4
+ std r6,24+stackblock(r1)
+#endif
+#if NARGS >= 5
+ std r7,32+stackblock(r1)
+#endif
+#if NARGS >= 6
+ std r8,40+stackblock(r1)
+#endif
+#if NARGS >= 7
+ std r9,48+stackblock(r1)
+#endif
+#if NARGS >= 8
+ std r10,56+stackblock(r1)
+#endif
+#if NARGS >= 9
+#error too many arguments!
+#endif
+
+#if defined NEED_CANCELLATION && defined CENABLE
+ SINGLE_THREAD_P
+ bne- .Lsocket_cancel
+#endif
+
+ li r3,P(SOCKOP_,socket)
+ addi r4,r1,stackblock
+ DO_CALL(SYS_ify(socketcall))
+ addi r1,r1,144
+ PSEUDO_RET
+
+#if defined NEED_CANCELLATION && defined CENABLE
+.Lsocket_cancel:
+ mflr r9
+ std r9,144+16(r1)
+ cfi_offset (lr, 16)
+ CENABLE
+ std r3,72(r1)
+ li r3,P(SOCKOP_,socket)
+ addi r4,r1,stackblock
+ DO_CALL(SYS_ify(socketcall))
+ mfcr r0
+ std r3,64(r1)
+ std r0,8(r1)
+ ld r3,72(r1)
+ CDISABLE
+ ld r4,144+16(r1)
+ ld r0,8(r1)
+ ld r3,64(r1)
+ mtlr r4
+ mtcr r0
+ addi r1,r1,144
+ PSEUDO_RET
+#endif
+PSEUDO_END (__socket)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__socket, socket)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
new file mode 100644
index 000000000..936d641b6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
@@ -0,0 +1,769 @@
+/* Save current context and install the given one.
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+#include <shlib-compat.h>
+#include <kernel-features.h>
+
+#define __ASSEMBLY__
+#include <asm/ptrace.h>
+#include "ucontext_i.h"
+#include <asm/errno.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
+ENTRY(__novec_swapcontext)
+ CALL_MCOUNT 2
+#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
+ std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
+ std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
+ mflr r0
+ std r31,-8(1)
+ cfi_offset(r31,-8)
+ std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
+ std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
+ std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
+ std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
+ std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
+ std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
+ std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
+ std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
+ std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
+ std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
+ std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
+ std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
+ std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
+ std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
+ std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
+ std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
+ std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
+ std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
+ std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
+ std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
+ std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
+ std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
+ std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
+ std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
+ std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
+ std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
+ std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
+ std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
+ mfctr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
+ mfxer r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
+ mfcr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
+
+ /* Set the return value of swapcontext to "success". R3 is the only
+ register whose value is not preserved in the saved context. */
+ li r0,0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
+
+ /* Zero fill fields that can't be set in user state or are unused. */
+ std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
+
+ /* Set the PT_REGS pointer to the address of sigcontext gp_regs
+ field. Struct pt_regs and elf_gregset_t are the same thing.
+ We kept the regs field for backwards compatibility with
+ libraries built before we extended sigcontext. */
+ addi r0,r3,SIGCONTEXT_GP_REGS
+ std r0,SIGCONTEXT_PT_REGS(r3)
+
+ stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
+ stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
+ stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
+ stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
+ stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
+ stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
+ stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
+ stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
+ stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
+ stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
+ stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
+ stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
+ stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
+ stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
+ stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
+ stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
+ stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
+ stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
+ stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
+ stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
+ stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
+ stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
+ stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
+ stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
+ stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
+ stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
+ stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
+ stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
+ stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
+ stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
+ mffs fp0
+ stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
+ stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
+ stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
+
+ mr r31,r4
+ addi r5,r3,UCONTEXT_SIGMASK
+ addi r4,r4,UCONTEXT_SIGMASK
+ li r3,SIG_SETMASK
+ bl JUMPTARGET(__sigprocmask)
+ nop
+ cmpdi r3,0
+ bne L(nv_error_exit)
+
+/*
+ * If this new ucontext refers to the point where we were interrupted
+ * by a signal, we have to use the rt_sigreturn system call to
+ * return to the context so we get both LR and CTR restored.
+ *
+ * Otherwise, the context we are restoring is either just after
+ * a procedure call (getcontext/swapcontext) or at the beginning
+ * of a procedure call (makecontext), so we don't need to restore
+ * msr and ctr. We don't restore r13 since it will be used as
+ * the TLS pointer. */
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
+ cmpdi r0,0
+ bne L(nv_do_sigret)
+
+ lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
+ lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
+ lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
+ mtfsf 0xff,fp0
+ lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
+ lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
+ lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
+ lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
+ lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
+ lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
+ lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
+ lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
+ lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
+ lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
+ lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
+ lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
+ lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
+ lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
+ lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
+ lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
+ lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
+ lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
+ lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
+ lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
+ lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
+ lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
+ lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
+ lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
+ lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
+ lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
+ lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
+ lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
+ lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
+ lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
+
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
+ ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
+ mtlr r0
+ ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
+ ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
+ mtxer r0
+ ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
+ ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
+ mtcr r0
+ ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
+ ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
+ ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
+ ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
+ ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
+ ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
+ ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
+ /* Don't reload the thread ID or TLS pointer (r13). */
+ ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
+ ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
+ ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
+ ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
+ ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
+ ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
+ ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
+ ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
+ ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
+ ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
+ ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
+ ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
+ ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
+ ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
+ ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
+ ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
+ ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
+
+ /* Now we branch to the "Next Instruction Pointer" from the saved
+ context. With the powerpc64 instruction set there is no good way to
+ do this (from user state) without clobbering either the LR or CTR.
+ The makecontext and swapcontext functions depend on the callers
+ LR being preserved so we use the CTR. */
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
+ mtctr r0
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
+ ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
+ bctr
+
+L(nv_error_exit):
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ ld r31,-8(r1)
+ blr
+
+ /* At this point we assume that the ucontext was created by a
+ rt_signal and we should use rt_sigreturn to restore the original
+ state. As of the 2.4.21 kernel the ucontext is the first thing
+ (offset 0) in the rt_signal frame and rt_sigreturn expects the
+ ucontext address in R1. Normally the rt-signal trampoline handles
+ this by popping dummy frame before the rt_signal syscall. In our
+ case the stack may not be in its original (signal handler return with
+ R1 pointing at the dummy frame) state. We do have the ucontext
+ address in R3, so simply copy R3 to R1 before the syscall. */
+L(nv_do_sigret):
+ mr r1,r3,
+ li r0,SYS_ify(rt_sigreturn)
+ sc
+ /* No return. */
+#else
+ /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
+ mflr r0
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset(lr,FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ li r3,ENOSYS
+ bl JUMPTARGET(__syscall_error)
+ nop
+ li r3,-1
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ blr
+#endif
+
+PSEUDO_END(__novec_swapcontext)
+
+compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3)
+
+#endif
+
+ .section ".toc","aw"
+.LC__dl_hwcap:
+#ifdef SHARED
+ .tc _rtld_global_ro[TC],_rtld_global_ro
+#else
+ .tc _dl_hwcap[TC],_dl_hwcap
+#endif
+ .section ".text"
+
+ .machine "altivec"
+ENTRY(__swapcontext)
+ CALL_MCOUNT 2
+#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
+ std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
+ std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
+ mflr r0
+ std r31,-8(1)
+ cfi_offset(r31,-8)
+ std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset(128)
+ std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
+ std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
+ std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
+ std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
+ std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
+ std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
+ std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
+ std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
+ std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
+ std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
+ std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
+ std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
+ std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
+ std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
+ std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
+ std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
+ std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
+ std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
+ std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
+ std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
+ std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
+ std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
+ std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
+ std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
+ std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
+ std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
+ std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
+ std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
+ mfctr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
+ mfxer r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
+ mfcr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
+
+ /* Set the return value of swapcontext to "success". R3 is the only
+ register whose value is not preserved in the saved context. */
+ li r0,0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
+
+ /* Zero fill fields that can't be set in user state or are unused. */
+ std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
+
+ /* Set the PT_REGS pointer to the address of sigcontext gp_regs
+ field. Struct pt_regs and elf_gregset_t are the same thing.
+ We kept the regs field for backwards compatibility with
+ libraries built before we extended sigcontext. */
+ addi r0,r3,SIGCONTEXT_GP_REGS
+ std r0,SIGCONTEXT_PT_REGS(r3)
+
+ stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
+ stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
+ stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
+ stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
+ stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
+ stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
+ stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
+ stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
+ stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
+ stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
+ stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
+ stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
+ stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
+ stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
+ stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
+ stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
+ stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
+ stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
+ stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
+ stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
+ stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
+ stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
+ stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
+ stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
+ stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
+ stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
+ stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
+ stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
+ stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
+ stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
+ mffs fp0
+ stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
+ stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
+ stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
+
+ ld r8,.LC__dl_hwcap@toc(r2)
+#ifdef SHARED
+/* Load _rtld-global._dl_hwcap. */
+ ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
+#else
+ ld r8,0(r8) /* Load extern _dl_hwcap. */
+#endif
+ la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
+ la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
+
+ andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+
+ clrrdi r10,r10,4
+ beq L(has_no_vec)
+
+ clrrdi r9,r9,4
+ mr r8,r10 /* Capture *v_regs value in r5. */
+
+ stvx v0,0,r10
+ stvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v2,0,r10
+ stvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v4,0,r10
+ stvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v6,0,r10
+ stvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v8,0,r10
+ stvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v10,0,r10
+ stvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v12,0,r10
+ stvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v14,0,r10
+ stvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v16,0,r10
+ stvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v18,0,r10
+ stvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v20,0,r10
+ stvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v22,0,r10
+ stvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v24,0,r10
+ stvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v26,0,r10
+ stvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v28,0,r10
+ stvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v30,0,r10
+ stvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mfvscr v0
+ mfspr r0,VRSAVE
+ stvx v0,0,r10
+ stw r0,0(r9)
+
+L(has_no_vec):
+/*
+ Store either a NULL or a quadword aligned pointer to the Vector register
+ array into *v_regs.
+*/
+ std r8,(SIGCONTEXT_V_REGS_PTR)(r3)
+
+ mr r31,r4
+ addi r5,r3,UCONTEXT_SIGMASK
+ addi r4,r4,UCONTEXT_SIGMASK
+ li r3,SIG_SETMASK
+ bl JUMPTARGET(__sigprocmask)
+ nop
+ cmpdi r3,0
+ bne L(error_exit)
+
+/*
+ * If this new ucontext refers to the point where we were interrupted
+ * by a signal, we have to use the rt_sigreturn system call to
+ * return to the context so we get both LR and CTR restored.
+ *
+ * Otherwise, the context we are restoring is either just after
+ * a procedure call (getcontext/swapcontext) or at the beginning
+ * of a procedure call (makecontext), so we don't need to restore
+ * msr and ctr. We don't restore r13 since it will be used as
+ * the TLS pointer. */
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
+ cmpdi r0,0
+ bne L(do_sigret)
+
+ ld r8,.LC__dl_hwcap@toc(r2)
+ ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
+# ifdef SHARED
+/* Load _rtld-global._dl_hwcap. */
+ ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
+# else
+ ld r8,0(r8) /* Load extern _dl_hwcap. */
+# endif
+ andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ beq L(has_no_vec2)
+
+ cmpdi r10,0
+ beq L(has_no_vec2)
+ lwz r0,(33*16)(r10)
+
+ li r9,(16*32)
+ mtspr VRSAVE,r0
+ cmpwi r0,0
+ beq L(has_no_vec2)
+
+ lvx v19,r9,r10
+ la r9,(16)(r10)
+
+ lvx v0,0,r10
+ lvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mtvscr v19
+ lvx v2,0,r10
+ lvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v4,0,r10
+ lvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v6,0,r10
+ lvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v8,0,r10
+ lvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v12,0,r10
+ lvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v14,0,r10
+ lvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v16,0,r10
+ lvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v18,0,r10
+ lvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v20,0,r10
+ lvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v22,0,r10
+ lvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v24,0,r10
+ lvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v26,0,r10
+ lvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v28,0,r10
+ lvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v30,0,r10
+ lvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+L(has_no_vec2):
+
+ lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
+ lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
+ lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
+ mtfsf 0xff,fp0
+ lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
+ lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
+ lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
+ lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
+ lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
+ lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
+ lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
+ lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
+ lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
+ lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
+ lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
+ lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
+ lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
+ lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
+ lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
+ lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
+ lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
+ lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
+ lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
+ lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
+ lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
+ lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
+ lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
+ lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
+ lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
+ lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
+ lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
+ lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
+ lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
+ lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
+
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
+ ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
+ mtlr r0
+ ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
+ ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
+ mtxer r0
+ ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
+ ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
+ ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
+ ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
+ ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
+ ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
+ mtcr r0
+ ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
+ ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
+ ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
+ /* Don't reload the thread ID or TLS pointer (r13). */
+ ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
+ ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
+ ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
+ ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
+ ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
+ ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
+ ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
+ ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
+ ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
+ ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
+ ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
+ ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
+ ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
+ ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
+ ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
+ ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
+ ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
+
+ /* Now we branch to the "Next Instruction Pointer" from the saved
+ context. With the powerpc64 instruction set there is no good way to
+ do this (from user state) without clobbering either the LR or CTR.
+ The makecontext and swapcontext functions depend on the callers
+ LR being preserved so we use the CTR. */
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
+ mtctr r0
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
+ ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
+ bctr
+
+L(error_exit):
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ ld r31,-8(r1)
+ blr
+
+ /* At this point we assume that the ucontext was created by a
+ rt_signal and we should use rt_sigreturn to restore the original
+ state. As of the 2.4.21 kernel the ucontext is the first thing
+ (offset 0) in the rt_signal frame and rt_sigreturn expects the
+ ucontext address in R1. Normally the rt-signal trampoline handles
+ this by popping dummy frame before the rt_signal syscall. In our
+ case the stack may not be in its original (signal handler return with
+ R1 pointing at the dummy frame) state. We do have the ucontext
+ address in R3, so simply copy R3 to R1 before the syscall. */
+L(do_sigret):
+ mr r1,r3,
+ li r0,SYS_ify(rt_sigreturn)
+ sc
+ /* No return. */
+#else
+ /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
+ mflr r0
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ li r3,ENOSYS
+ bl JUMPTARGET(__syscall_error)
+ nop
+ li r3,-1
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ blr
+#endif
+
+PSEUDO_END(__swapcontext)
+
+versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_4)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list
new file mode 100644
index 000000000..aee60bf9d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list
@@ -0,0 +1,3 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+getrlimit - ugetrlimit i:ip __getrlimit getrlimit getrlimit64
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
new file mode 100644
index 000000000..fd67f5698
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
@@ -0,0 +1,311 @@
+/* Copyright (C) 1992,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Alan Modra <amodra@bigpond.net.au> rewrote the INLINE_SYSCALL macro */
+
+#ifndef _LINUX_POWERPC_SYSDEP_H
+#define _LINUX_POWERPC_SYSDEP_H 1
+
+#include <sysdeps/unix/powerpc/sysdep.h>
+#include <tls.h>
+
+/* Define __set_errno() for INLINE_SYSCALL macro below. */
+#ifndef __ASSEMBLER__
+#include <errno.h>
+#endif
+
+/* Some systen calls got renamed over time, but retained the same semantics.
+ Handle them here so they can be catched by both C and assembler stubs in
+ glibc. */
+
+#ifdef __NR_pread64
+# ifdef __NR_pread
+# error "__NR_pread and __NR_pread64 both defined???"
+# endif
+# define __NR_pread __NR_pread64
+#endif
+
+#ifdef __NR_pwrite64
+# ifdef __NR_pwrite
+# error "__NR_pwrite and __NR_pwrite64 both defined???"
+# endif
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+/* For Linux we can use the system call table in the header file
+ /usr/include/asm/unistd.h
+ of the kernel. But these symbols do not follow the SYS_* syntax
+ so we have to redefine the `SYS_ify' macro here. */
+#undef SYS_ify
+#ifdef __STDC__
+# define SYS_ify(syscall_name) __NR_##syscall_name
+#else
+# define SYS_ify(syscall_name) __NR_/**/syscall_name
+#endif
+
+#ifdef __ASSEMBLER__
+
+/* This seems to always be the case on PPC. */
+# define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+# define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+# define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+#endif /* __ASSEMBLER__ */
+
+/* This version is for kernels that implement system calls that
+ behave like function calls as far as register saving.
+ It falls back to the syscall in the case that the vDSO doesn't
+ exist or fails for ENOSYS */
+#ifdef SHARED
+# define INLINE_VSYSCALL(name, nr, args...) \
+ ({ \
+ __label__ out; \
+ __label__ iserr; \
+ INTERNAL_SYSCALL_DECL (sc_err); \
+ long int sc_ret; \
+ \
+ if (__vdso_##name != NULL) \
+ { \
+ sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, nr, ##args); \
+ if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
+ goto out; \
+ if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS) \
+ goto iserr; \
+ } \
+ \
+ sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, ##args); \
+ if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
+ { \
+ iserr: \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \
+ sc_ret = -1L; \
+ } \
+ out: \
+ sc_ret; \
+ })
+#else
+# define INLINE_VSYSCALL(name, nr, args...) \
+ INLINE_SYSCALL (name, nr, ##args)
+#endif
+
+#ifdef SHARED
+# define INTERNAL_VSYSCALL(name, err, nr, args...) \
+ ({ \
+ __label__ out; \
+ long int v_ret; \
+ \
+ if (__vdso_##name != NULL) \
+ { \
+ v_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \
+ if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err) \
+ || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS) \
+ goto out; \
+ } \
+ v_ret = INTERNAL_SYSCALL (name, err, nr, ##args); \
+ out: \
+ v_ret; \
+ })
+#else
+# define INTERNAL_VSYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL (name, err, nr, ##args)
+#endif
+
+/* This version is for internal uses when there is no desire
+ to set errno */
+#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \
+ ({ \
+ long int sc_ret = ENOSYS; \
+ \
+ if (__vdso_##name != NULL) \
+ sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \
+ else \
+ err = 1 << 28; \
+ sc_ret; \
+ })
+
+/* List of system calls which are supported as vsyscalls. */
+#define HAVE_CLOCK_GETRES_VSYSCALL 1
+#define HAVE_CLOCK_GETTIME_VSYSCALL 1
+
+/* Define a macro which expands inline into the wrapper code for a system
+ call. This use is for internal calls that do not need to handle errors
+ normally. It will never touch errno. This returns just what the kernel
+ gave back in the non-error (CR0.SO cleared) case, otherwise (CR0.SO set)
+ the negation of the return value in the kernel gets reverted. */
+
+#define INTERNAL_VSYSCALL_NCS(funcptr, err, nr, args...) \
+ ({ \
+ register void *r0 __asm__ ("r0"); \
+ register long int r3 __asm__ ("r3"); \
+ register long int r4 __asm__ ("r4"); \
+ register long int r5 __asm__ ("r5"); \
+ register long int r6 __asm__ ("r6"); \
+ register long int r7 __asm__ ("r7"); \
+ register long int r8 __asm__ ("r8"); \
+ LOADARGS_##nr (funcptr, args); \
+ __asm__ __volatile__ \
+ ("mtctr %0\n\t" \
+ "bctrl\n\t" \
+ "mfcr %0\n\t" \
+ "0:" \
+ : "=&r" (r0), \
+ "=&r" (r3), "=&r" (r4), "=&r" (r5), \
+ "=&r" (r6), "=&r" (r7), "=&r" (r8) \
+ : ASM_INPUT_##nr \
+ : "r9", "r10", "r11", "r12", \
+ "cr0", "ctr", "lr", "memory"); \
+ err = (long int) r0; \
+ (int) r3; \
+ })
+
+#undef INLINE_SYSCALL
+
+/* This version is for kernels that implement system calls that
+ behave like function calls as far as register saving. */
+#define INLINE_SYSCALL(name, nr, args...) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (sc_err); \
+ long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \
+ if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
+ { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \
+ sc_ret = -1L; \
+ } \
+ sc_ret; \
+ })
+
+/* Define a macro which expands inline into the wrapper code for a system
+ call. This use is for internal calls that do not need to handle errors
+ normally. It will never touch errno. This returns just what the kernel
+ gave back in the non-error (CR0.SO cleared) case, otherwise (CR0.SO set)
+ the negation of the return value in the kernel gets reverted. */
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ register long int r0 __asm__ ("r0"); \
+ register long int r3 __asm__ ("r3"); \
+ register long int r4 __asm__ ("r4"); \
+ register long int r5 __asm__ ("r5"); \
+ register long int r6 __asm__ ("r6"); \
+ register long int r7 __asm__ ("r7"); \
+ register long int r8 __asm__ ("r8"); \
+ LOADARGS_##nr (name, ##args); \
+ __asm__ __volatile__ \
+ ("sc\n\t" \
+ "mfcr %0\n\t" \
+ "0:" \
+ : "=&r" (r0), \
+ "=&r" (r3), "=&r" (r4), "=&r" (r5), \
+ "=&r" (r6), "=&r" (r7), "=&r" (r8) \
+ : ASM_INPUT_##nr \
+ : "r9", "r10", "r11", "r12", \
+ "cr0", "ctr", "memory"); \
+ err = r0; \
+ (int) r3; \
+ })
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, args)
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) long int err
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((void) (val), __builtin_expect ((err) & (1 << 28), 0))
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) (val)
+
+#define LOADARGS_0(name, dummy) \
+ r0 = name
+#define LOADARGS_1(name, __arg1) \
+ long int arg1 = (long int) (__arg1); \
+ LOADARGS_0(name, 0); \
+ extern void __illegally_sized_syscall_arg1 (void); \
+ if (__builtin_classify_type (__arg1) != 5 && sizeof (__arg1) > 8) \
+ __illegally_sized_syscall_arg1 (); \
+ r3 = arg1
+#define LOADARGS_2(name, __arg1, __arg2) \
+ long int arg2 = (long int) (__arg2); \
+ LOADARGS_1(name, __arg1); \
+ extern void __illegally_sized_syscall_arg2 (void); \
+ if (__builtin_classify_type (__arg2) != 5 && sizeof (__arg2) > 8) \
+ __illegally_sized_syscall_arg2 (); \
+ r4 = arg2
+#define LOADARGS_3(name, __arg1, __arg2, __arg3) \
+ long int arg3 = (long int) (__arg3); \
+ LOADARGS_2(name, __arg1, __arg2); \
+ extern void __illegally_sized_syscall_arg3 (void); \
+ if (__builtin_classify_type (__arg3) != 5 && sizeof (__arg3) > 8) \
+ __illegally_sized_syscall_arg3 (); \
+ r5 = arg3
+#define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
+ long int arg4 = (long int) (__arg4); \
+ LOADARGS_3(name, __arg1, __arg2, __arg3); \
+ extern void __illegally_sized_syscall_arg4 (void); \
+ if (__builtin_classify_type (__arg4) != 5 && sizeof (__arg4) > 8) \
+ __illegally_sized_syscall_arg4 (); \
+ r6 = arg4
+#define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
+ long int arg5 = (long int) (__arg5); \
+ LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
+ extern void __illegally_sized_syscall_arg5 (void); \
+ if (__builtin_classify_type (__arg5) != 5 && sizeof (__arg5) > 8) \
+ __illegally_sized_syscall_arg5 (); \
+ r7 = arg5
+#define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
+ long int arg6 = (long int) (__arg6); \
+ LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
+ extern void __illegally_sized_syscall_arg6 (void); \
+ if (__builtin_classify_type (__arg6) != 5 && sizeof (__arg6) > 8) \
+ __illegally_sized_syscall_arg6 (); \
+ r8 = arg6
+
+#define ASM_INPUT_0 "0" (r0)
+#define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
+#define ASM_INPUT_2 ASM_INPUT_1, "2" (r4)
+#define ASM_INPUT_3 ASM_INPUT_2, "3" (r5)
+#define ASM_INPUT_4 ASM_INPUT_3, "4" (r6)
+#define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
+#define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
+
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. */
+#else
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(reg, tmpreg) \
+ ld tmpreg,POINTER_GUARD(r13); \
+ xor reg,tmpreg,reg
+# define PTR_MANGLE2(reg, tmpreg) \
+ xor reg,tmpreg,reg
+# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg)
+# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg)
+# else
+# define PTR_MANGLE(var) \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+# define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#endif
+
+#endif /* linux/powerpc/powerpc64/sysdep.h */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym
new file mode 100644
index 000000000..a35418d9d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym
@@ -0,0 +1,50 @@
+#include <stddef.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+--
+
+SIG_BLOCK
+SIG_SETMASK
+
+
+-- Offsets of the fields in the powerpc64 ABI stack frame.
+-- XXX Do these correspond to some struct?
+
+FRAME_BACKCHAIN 0
+FRAME_CR_SAVE 8
+FRAME_LR_SAVE 16
+FRAME_COMPILER_DW 24
+FRAME_LINKER_DW 32
+FRAME_TOC_SAVE 40
+FRAME_PARM_SAVE 48
+FRAME_PARM1_SAVE 48
+FRAME_PARM2_SAVE 56
+FRAME_PARM3_SAVE 64
+FRAME_PARM4_SAVE 72
+FRAME_PARM5_SAVE 80
+FRAME_PARM6_SAVE 88
+FRAME_PARM7_SAVE 96
+FRAME_PARM8_SAVE 104
+FRAME_PARM9_SAVE 112
+
+
+-- Offsets of the fields in the ucontext_t structure.
+#define ucontext(member) offsetof (ucontext_t, member)
+#define mcontext(member) ucontext (uc_mcontext.member)
+
+UCONTEXT_LINK ucontext (uc_link)
+UCONTEXT_STACK ucontext (uc_stack)
+UCONTEXT_STACK_SP ucontext (uc_stack.ss_sp)
+UCONTEXT_STACK_FLAGS ucontext (uc_stack.ss_flags)
+UCONTEXT_STACK_SIZE ucontext (uc_stack.ss_size)
+UCONTEXT_SIGMASK ucontext (uc_sigmask)
+UCONTEXT_MCONTEXT ucontext (uc_mcontext)
+SIGCONTEXT_SIGNAL mcontext (signal)
+SIGCONTEXT_HANDLER mcontext (handler)
+SIGCONTEXT_OLDMASK mcontext (oldmask)
+SIGCONTEXT_PT_REGS mcontext (regs)
+SIGCONTEXT_GP_REGS mcontext (gp_regs)
+SIGCONTEXT_FP_REGS mcontext (fp_regs)
+SIGCONTEXT_V_REGS_PTR mcontext (v_regs)
+SIGCONTEXT_V_RESERVE mcontext (vmx_reserve)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/umount.c b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/umount.c
new file mode 100644
index 000000000..e10b40f96
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/umount.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/x86_64/umount.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S
new file mode 100644
index 000000000..2f5df38cf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S
@@ -0,0 +1,57 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+ CALL_MCOUNT 0
+
+#ifdef __NR_vfork
+
+ DO_CALL (SYS_ify (vfork))
+
+# ifdef __ASSUME_VFORK_SYSCALL
+ PSEUDO_RET
+# else
+ bnslr+
+ /* Check if vfork syscall is known at all. */
+ cmpdi r3,ENOSYS
+ bne JUMPTARGET(__syscall_error)
+
+# endif
+#endif
+
+#ifndef __ASSUME_VFORK_SYSCALL
+ /* If we don't have vfork, fork is close enough. */
+
+ DO_CALL (SYS_ify (fork))
+ PSEUDO_RET
+#endif
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/profil-counter.h b/libc/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
new file mode 100644
index 000000000..8a6a0bcf3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
@@ -0,0 +1,2 @@
+/* We can use the ix86 version. */
+#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/putmsg.c b/libc/sysdeps/unix/sysv/linux/powerpc/putmsg.c
new file mode 100644
index 000000000..ebc1680ca
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/putmsg.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/putmsg.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/readdir64.c b/libc/sysdeps/unix/sysv/linux/powerpc/readdir64.c
new file mode 100644
index 000000000..2ea26dd40
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/readdir64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/readdir64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/readdir64_r.c b/libc/sysdeps/unix/sysv/linux/powerpc/readdir64_r.c
new file mode 100644
index 000000000..9f54f897e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/readdir64_r.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/readdir64_r.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/readelflib.c b/libc/sysdeps/unix/sysv/linux/powerpc/readelflib.c
new file mode 100644
index 000000000..3c6b2daf8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/readelflib.c
@@ -0,0 +1,61 @@
+/* Special checks on libraries for ldconfig. Linux/PowerPC version.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+int process_elf32_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+int process_elf64_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+
+/* Returns 0 if everything is ok, != 0 in case of error. */
+int
+process_elf_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname, void *file_contents,
+ size_t file_length)
+{
+ ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
+ int ret;
+
+ if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+ return process_elf32_file (file_name, lib, flag, osversion, soname,
+ file_contents, file_length);
+ else
+ {
+ ret = process_elf64_file (file_name, lib, flag, osversion, soname,
+ file_contents, file_length);
+ /* PowerPC 64bit libraries are always libc.so.6+. */
+ if (!ret)
+ *flag = FLAG_POWERPC_LIB64|FLAG_ELF_LIBC6;
+ return ret;
+ }
+}
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf32_file
+#define __ELF_NATIVE_CLASS 32
+#include "elf/readelflib.c"
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf64_file
+#define __ELF_NATIVE_CLASS 64
+#include "elf/readelflib.c"
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/rt-sysdep.c b/libc/sysdeps/unix/sysv/linux/powerpc/rt-sysdep.c
new file mode 100644
index 000000000..3ff55952e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/rt-sysdep.c
@@ -0,0 +1 @@
+#include <sysdep.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/scandir64.c b/libc/sysdeps/unix/sysv/linux/powerpc/scandir64.c
new file mode 100644
index 000000000..506fd8877
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/scandir64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/scandir64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/setrlimit.c b/libc/sysdeps/unix/sysv/linux/powerpc/setrlimit.c
new file mode 100644
index 000000000..bfaef74c3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/setrlimit.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setrlimit.c>
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h b/libc/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h
new file mode 100644
index 000000000..138a15cfa
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+
+#define SIGCONTEXT struct sigcontext *
+#define SIGCONTEXT_EXTRA_ARGS
+#define GET_PC(ctx) ((void *)((ctx)->regs->nip))
+#define GET_FRAME(ctx) (*(void **)((ctx)->regs->gpr[1]))
+#define GET_STACK(ctx) ((void *)((ctx)->regs->gpr[1]))
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/sys/procfs.h b/libc/sysdeps/unix/sysv/linux/powerpc/sys/procfs.h
new file mode 100644
index 000000000..577689f18
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/sys/procfs.h
@@ -0,0 +1,140 @@
+/* Copyright (C) 1996, 1997, 1999, 2002, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H 1
+
+/* This is somehow modelled after the file of the same name on SysVr4
+ systems. It provides a definition of the core file format for ELF
+ used on Linux. */
+
+#include <features.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ucontext.h>
+#include <sys/user.h>
+
+__BEGIN_DECLS
+
+/* These definitions are normally provided by ucontext.h via
+ asm/sigcontext.h, asm/ptrace.h, and asm/elf.h. Otherwise we define
+ them here. */
+#if !defined __PPC64_ELF_H && !defined _ASM_POWERPC_ELF_H
+#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
+#define ELF_NFPREG 33 /* includes fpscr */
+#if __WORDSIZE == 32
+# define ELF_NVRREG 33 /* includes vscr */
+#else
+# define ELF_NVRREG 34 /* includes vscr */
+#endif
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+/* Altivec registers */
+typedef struct {
+ unsigned int u[4];
+} __attribute__ ((aligned (16))) elf_vrreg_t;
+typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
+#endif
+
+struct elf_siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_code; /* Extra code. */
+ int si_errno; /* Errno. */
+ };
+
+
+/* Definitions to generate Intel SVR4-like core files. These mostly
+ have the same names as the SVR4 types with "elf_" tacked on the
+ front to prevent clashes with linux definitions, and the typedef
+ forms have been avoided. This is mostly like the SVR4 structure,
+ but more Linuxy, with things that Linux does not support and which
+ gdb doesn't really use excluded. Fields present but not used are
+ marked with "XXX". */
+struct elf_prstatus
+ {
+#if 0
+ long int pr_flags; /* XXX Process flags. */
+ short int pr_why; /* XXX Reason for process halt. */
+ short int pr_what; /* XXX More detailed reason. */
+#endif
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned long int pr_sigpend; /* Set of pending signals. */
+ unsigned long int pr_sighold; /* Set of held signals. */
+#if 0
+ struct sigaltstack pr_altstack; /* Alternate stack info. */
+ struct sigaction pr_action; /* Signal action for current sig. */
+#endif
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct timeval pr_utime; /* User time. */
+ struct timeval pr_stime; /* System time. */
+ struct timeval pr_cutime; /* Cumulative user time. */
+ struct timeval pr_cstime; /* Cumulative system time. */
+#if 0
+ long int pr_instr; /* Current instruction. */
+#endif
+ elf_gregset_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+#define ELF_PRARGSZ (80) /* Number of chars for args */
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long int pr_flag; /* Flags. */
+ __uid_t pr_uid;
+ __gid_t pr_gid;
+ __pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+/* Addresses. */
+typedef void *psaddr_t;
+
+/* Register sets. Linux has different names. */
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+ therefore habe only ine PID type. */
+typedef __pid_t lwpid_t;
+
+
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif /* sys/procfs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h b/libc/sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h
new file mode 100644
index 000000000..91a87307f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h
@@ -0,0 +1,99 @@
+/* `ptrace' debugger support interface. Linux version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PTRACE_H
+#define _SYS_PTRACE_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Type of the REQUEST argument to `ptrace.' */
+enum __ptrace_request
+{
+ /* Indicate that the process making this request should be traced.
+ All signals received by this process can be intercepted by its
+ parent, and its parent can use the other `ptrace' requests. */
+ PTRACE_TRACEME = 0,
+#define PT_TRACE_ME PTRACE_TRACEME
+
+ /* Return the word in the process's text space at address ADDR. */
+ PTRACE_PEEKTEXT = 1,
+#define PT_READ_I PTRACE_PEEKTEXT
+
+ /* Return the word in the process's data space at address ADDR. */
+ PTRACE_PEEKDATA = 2,
+#define PT_READ_D PTRACE_PEEKDATA
+
+ /* Return the word in the process's user area at offset ADDR. */
+ PTRACE_PEEKUSER = 3,
+#define PT_READ_U PTRACE_PEEKUSER
+
+ /* Write the word DATA into the process's text space at address ADDR. */
+ PTRACE_POKETEXT = 4,
+#define PT_WRITE_I PTRACE_POKETEXT
+
+ /* Write the word DATA into the process's data space at address ADDR. */
+ PTRACE_POKEDATA = 5,
+#define PT_WRITE_D PTRACE_POKEDATA
+
+ /* Write the word DATA into the process's user area at offset ADDR. */
+ PTRACE_POKEUSER = 6,
+#define PT_WRITE_U PTRACE_POKEUSER
+
+ /* Continue the process. */
+ PTRACE_CONT = 7,
+#define PT_CONTINUE PTRACE_CONT
+
+ /* Kill the process. */
+ PTRACE_KILL = 8,
+#define PT_KILL PTRACE_KILL
+
+ /* Single step the process.
+ This is not supported on all machines. */
+ PTRACE_SINGLESTEP = 9,
+#define PT_STEP PTRACE_SINGLESTEP
+
+ /* Attach to a process that is already running. */
+ PTRACE_ATTACH = 16,
+#define PT_ATTACH PTRACE_ATTACH
+
+ /* Detach from a process attached to with PTRACE_ATTACH. */
+ PTRACE_DETACH = 17,
+#define PT_DETACH PTRACE_DETACH
+
+ /* Continue and stop at the next (return from) syscall. */
+ PTRACE_SYSCALL = 24
+#define PT_SYSCALL PTRACE_SYSCALL
+};
+
+/* Perform process tracing functions. REQUEST is one of the values
+ above, and determines the action to be taken.
+ For all requests except PTRACE_TRACEME, PID specifies the process to be
+ traced.
+
+ PID and the other arguments described above for the various requests should
+ appear (those that are used for the particular request) as:
+ pid_t PID, void *ADDR, int DATA, void *ADDR2
+ after REQUEST. */
+extern long int ptrace (enum __ptrace_request __request, ...) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_PTRACE_H */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h b/libc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h
new file mode 100644
index 000000000..9eb50aa96
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h
@@ -0,0 +1,177 @@
+/* Copyright (C) 1998, 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+
+/* We need the signal context definitions even if they are not used
+ included in <signal.h>. */
+#include <bits/sigcontext.h>
+
+#if __WORDSIZE == 32
+
+/* Number of general registers. */
+# define NGREG 48
+
+/* Container for all general registers. */
+typedef unsigned long gregset_t[NGREG];
+
+/* Container for floating-point registers and status */
+typedef struct _libc_fpstate
+{
+ double fpregs[32];
+ double fpscr;
+ unsigned int _pad[2];
+} fpregset_t;
+
+/* Container for Altivec/VMX registers and status.
+ Needs to be aligned on a 16-byte boundary. */
+typedef struct _libc_vrstate
+{
+ unsigned int vrregs[32][4];
+ unsigned int vrsave;
+ unsigned int _pad[2];
+ unsigned int vscr;
+} vrregset_t;
+
+/* Context to describe whole processor state. */
+typedef struct
+{
+ gregset_t gregs;
+ fpregset_t fpregs;
+ vrregset_t vrregs __attribute__((__aligned__(16)));
+} mcontext_t;
+
+#else
+
+/* For 64-bit kernels with Altivec support, a machine context is exactly
+ * a sigcontext. For older kernel (without Altivec) the sigcontext matches
+ * the mcontext upto but not including the v_regs field. For kernels that
+ * don't AT_HWCAP or return AT_HWCAP without PPC_FEATURE_HAS_ALTIVEC the
+ * v_regs field may not exit and should not be referenced. The v_regd field
+ * can be refernced safely only after verifying that PPC_FEATURE_HAS_ALTIVEC
+ * is set in AT_HWCAP. */
+
+/* Number of general registers. */
+# define NGREG 48 /* includes r0-r31, nip, msr, lr, etc. */
+# define NFPREG 33 /* includes fp0-fp31 &fpscr. */
+# define NVRREG 34 /* includes v0-v31, vscr, & vrsave in split vectors */
+
+typedef unsigned long gregset_t[NGREG];
+typedef double fpregset_t[NFPREG];
+
+/* Container for Altivec/VMX Vector Status and Control Register. Only 32-bits
+ but can only be copied to/from a 128-bit vector register. So we allocated
+ a whole quadword speedup save/restore. */
+typedef struct _libc_vscr
+{
+ unsigned int __pad[3];
+ unsigned int vscr_word;
+} vscr_t;
+
+/* Container for Altivec/VMX registers and status.
+ Must to be aligned on a 16-byte boundary. */
+typedef struct _libc_vrstate
+{
+ unsigned int vrregs[32][4];
+ vscr_t vscr;
+ unsigned int vrsave;
+ unsigned int __pad[3];
+} vrregset_t __attribute__((__aligned__(16)));
+
+typedef struct {
+ unsigned long __unused[4];
+ int signal;
+ int __pad0;
+ unsigned long handler;
+ unsigned long oldmask;
+ struct pt_regs *regs;
+ gregset_t gp_regs;
+ fpregset_t fp_regs;
+/*
+ * To maintain compatibility with current implementations the sigcontext is
+ * extended by appending a pointer (v_regs) to a quadword type (elf_vrreg_t)
+ * followed by an unstructured (vmx_reserve) field of 69 doublewords. This
+ * allows the array of vector registers to be quadword aligned independent of
+ * the alignment of the containing sigcontext or ucontext. It is the
+ * responsibility of the code setting the sigcontext to set this pointer to
+ * either NULL (if this processor does not support the VMX feature) or the
+ * address of the first quadword within the allocated (vmx_reserve) area.
+ *
+ * The pointer (v_regs) of vector type (elf_vrreg_t) is essentually
+ * an array of 34 quadword entries. The entries with
+ * indexes 0-31 contain the corresponding vector registers. The entry with
+ * index 32 contains the vscr as the last word (offset 12) within the
+ * quadword. This allows the vscr to be stored as either a quadword (since
+ * it must be copied via a vector register to/from storage) or as a word.
+ * The entry with index 33 contains the vrsave as the first word (offset 0)
+ * within the quadword.
+ */
+ vrregset_t *v_regs;
+ long vmx_reserve[NVRREG+NVRREG+1];
+} mcontext_t;
+
+#endif
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+#if __WORDSIZE == 32
+ /*
+ * These fields are set up this way to maximize source and
+ * binary compatibility with code written for the old
+ * ucontext_t definition, which didn't include space for the
+ * registers.
+ *
+ * Different versions of the kernel have stored the registers on
+ * signal delivery at different offsets from the ucontext struct.
+ * Programs should thus use the uc_mcontext.uc_regs pointer to
+ * find where the registers are actually stored. The registers
+ * will be stored within the ucontext_t struct but not necessarily
+ * at a fixed address. As a side-effect, this lets us achieve
+ * 16-byte alignment for the register storage space if the
+ * Altivec registers are to be saved, without requiring 16-byte
+ * alignment on the whole ucontext_t.
+ *
+ * The uc_mcontext.regs field is included for source compatibility
+ * with programs written against the older ucontext_t definition,
+ * and its name should therefore not change. The uc_pad field
+ * is for binary compatibility with programs compiled against the
+ * old ucontext_t; it ensures that uc_mcontext.regs and uc_sigmask
+ * are at the same offset as previously.
+ */
+ int uc_pad[7];
+ union uc_regs_ptr {
+ struct pt_regs *regs;
+ mcontext_t *uc_regs;
+ } uc_mcontext;
+ sigset_t uc_sigmask;
+ char uc_reg_space[sizeof(mcontext_t) + 12]; /* last for extensibility */
+#else /* 64-bit */
+ sigset_t uc_sigmask;
+ mcontext_t uc_mcontext; /* last for extensibility */
+#endif
+ } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/sys/user.h b/libc/sysdeps/unix/sysv/linux/powerpc/sys/user.h
new file mode 100644
index 000000000..e8a8aaa95
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/sys/user.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_USER_H
+
+#define _SYS_USER_H 1
+#include <features.h>
+
+#include <asm/ptrace.h>
+
+struct user {
+ struct pt_regs regs; /* entire machine state */
+ size_t u_tsize; /* text size (pages) */
+ size_t u_dsize; /* data size (pages) */
+ size_t u_ssize; /* stack size (pages) */
+ unsigned long start_code; /* text starting address */
+ unsigned long start_data; /* data starting address */
+ unsigned long start_stack; /* stack starting address */
+ long int signal; /* signal causing core dump */
+ struct regs * u_ar0; /* help gdb find registers */
+ unsigned long magic; /* identifies a core file */
+ char u_comm[32]; /* user command name */
+};
+
+#endif /* sys/user.h */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/syscall.S b/libc/sysdeps/unix/sysv/linux/powerpc/syscall.S
new file mode 100644
index 000000000..aab3c5300
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/syscall.S
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991, 1992, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY (syscall)
+ mr r0,r3
+ mr r3,r4
+ mr r4,r5
+ mr r5,r6
+ mr r6,r7
+ mr r7,r8
+ mr r8,r9
+ sc
+ PSEUDO_RET
+PSEUDO_END (syscall)
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/syscalls.list b/libc/sysdeps/unix/sysv/linux/powerpc/syscalls.list
new file mode 100644
index 000000000..a6665936e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/syscalls.list
@@ -0,0 +1,3 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+waitpid - waitpid Ci:ipi __waitpid waitpid __libc_waitpid
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/sysdep.c b/libc/sysdeps/unix/sysv/linux/powerpc/sysdep.c
new file mode 100644
index 000000000..f16c4c938
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/sysdep.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <errno.h>
+
+/* This routine is jumped to by all the syscall handlers, to stash
+ an error number into errno. */
+int
+__syscall_error (int err_no)
+{
+ __set_errno (err_no);
+ return -1;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/ppoll.c b/libc/sysdeps/unix/sysv/linux/ppoll.c
new file mode 100644
index 000000000..cfc86ba80
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ppoll.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/poll.h>
+#include <kernel-features.h>
+#include <sysdep-cancel.h>
+
+
+#ifdef __NR_ppoll
+static int __generic_ppoll (struct pollfd *fds, nfds_t nfds,
+ const struct timespec *timeout,
+ const sigset_t *sigmask);
+
+
+int
+ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
+ const sigset_t *sigmask)
+{
+ /* The Linux kernel can in some situations update the timeout value.
+ We do not want that so use a local variable. */
+ struct timespec tval;
+ if (timeout != NULL)
+ {
+ tval = *timeout;
+ timeout = &tval;
+ }
+
+ int result;
+
+ if (SINGLE_THREAD_P)
+ result = INLINE_SYSCALL (ppoll, 5, fds, nfds, timeout, sigmask, _NSIG / 8);
+ else
+ {
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ result = INLINE_SYSCALL (ppoll, 5, fds, nfds, timeout, sigmask,
+ _NSIG / 8);
+
+ LIBC_CANCEL_RESET (oldtype);
+ }
+
+# ifndef __ASSUME_PPOLL
+ if (result == -1 && errno == ENOSYS)
+ result = __generic_ppoll (fds, nfds, timeout, sigmask);
+# endif
+
+ return result;
+}
+
+# ifndef __ASSUME_PPOLL
+# define ppoll static __generic_ppoll
+# endif
+#endif
+
+#ifndef __ASSUME_PPOLL
+# include <io/ppoll.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/pread.c b/libc/sysdeps/unix/sysv/linux/pread.c
new file mode 100644
index 000000000..d459e98f2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/pread.c
@@ -0,0 +1,96 @@
+/* Copyright (C) 1997-2000,2002,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <endian.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_pread
+# error "__NR_pread and __NR_pread64 both defined???"
+# endif
+# define __NR_pread __NR_pread64
+#endif
+
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
+
+# if __ASSUME_PREAD_SYSCALL == 0
+static ssize_t __emulate_pread (int fd, void *buf, size_t count,
+ off_t offset) internal_function;
+# endif
+
+
+static ssize_t
+#ifdef NO_CANCELLATION
+inline __attribute ((always_inline))
+#endif
+do_pread (int fd, void *buf, size_t count, off_t offset)
+{
+ ssize_t result;
+
+ /* First try the syscall. */
+ assert (sizeof (offset) == 4);
+ result = INLINE_SYSCALL (pread, 5, fd, CHECK_N (buf, count), count,
+ __LONG_LONG_PAIR (offset >> 31, offset));
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread (fd, buf, count, offset);
+# endif
+
+ return result;
+}
+
+
+ssize_t
+__libc_pread (fd, buf, count, offset)
+ int fd;
+ void *buf;
+ size_t count;
+ off_t offset;
+{
+ if (SINGLE_THREAD_P)
+ return do_pread (fd, buf, count, offset);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = do_pread (fd, buf, count, offset);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+strong_alias (__libc_pread, __pread)
+weak_alias (__libc_pread, pread)
+
+# define __libc_pread(fd, buf, count, offset) \
+ static internal_function __emulate_pread (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/pread64.c b/libc/sysdeps/unix/sysv/linux/pread64.c
new file mode 100644
index 000000000..07d8b68ac
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/pread64.c
@@ -0,0 +1,93 @@
+/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <endian.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_pread
+# error "__NR_pread and __NR_pread64 both defined???"
+# endif
+# define __NR_pread __NR_pread64
+#endif
+
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
+
+# if __ASSUME_PREAD_SYSCALL == 0
+static ssize_t __emulate_pread64 (int fd, void *buf, size_t count,
+ off64_t offset) internal_function;
+# endif
+
+
+static ssize_t
+do_pread64 (int fd, void *buf, size_t count, off64_t offset)
+{
+ ssize_t result;
+
+ /* First try the syscall. */
+ result = INLINE_SYSCALL (pread, 5, fd, CHECK_N (buf, count), count,
+ __LONG_LONG_PAIR ((off_t) (offset >> 32),
+ (off_t) (offset & 0xffffffff)));
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread64 (fd, buf, count, offset);
+# endif
+
+ return result;
+}
+
+
+ssize_t
+__libc_pread64 (fd, buf, count, offset)
+ int fd;
+ void *buf;
+ size_t count;
+ off64_t offset;
+{
+ if (SINGLE_THREAD_P)
+ return do_pread64 (fd, buf, count, offset);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = do_pread64 (fd, buf, count, offset);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+weak_alias (__libc_pread64, __pread64)
+weak_alias (__libc_pread64, pread64)
+
+# define __libc_pread64(fd, buf, count, offset) \
+ static internal_function __emulate_pread64 (fd, buf, count, offset)
+#endif
+
+# if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread64.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/prof-freq.c b/libc/sysdeps/unix/sysv/linux/prof-freq.c
new file mode 100644
index 000000000..49ec257e7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/prof-freq.c
@@ -0,0 +1,51 @@
+/* Determine realtime clock frequency.
+ Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/time.h>
+#include <libc-internal.h>
+#include <kernel-features.h>
+#include <ldsodefs.h>
+
+
+int
+__profile_frequency (void)
+{
+#ifdef __ASSUME_AT_CLKTCK
+ return GLRO(dl_clktck);
+#else
+ if (GLRO(dl_clktck) != 0)
+ return GLRO(dl_clktck);
+
+ struct itimerval tim;
+
+ tim.it_interval.tv_sec = 0;
+ tim.it_interval.tv_usec = 1;
+ tim.it_value.tv_sec = 0;
+ tim.it_value.tv_usec = 0;
+
+ __setitimer (ITIMER_REAL, &tim, 0);
+ __setitimer (ITIMER_REAL, 0, &tim);
+
+ if (tim.it_interval.tv_usec < 2)
+ return 0;
+
+ return 1000000 / tim.it_interval.tv_usec;
+#endif
+}
+libc_hidden_def (__profile_frequency)
diff --git a/libc/sysdeps/unix/sysv/linux/profil.c b/libc/sysdeps/unix/sysv/linux/profil.c
new file mode 100644
index 000000000..5918ecebf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/profil.c
@@ -0,0 +1,3 @@
+/* Linux defines the profil system call but doesn't actually implement
+ it. Use the generic posix implementation. */
+#include <sysdeps/posix/profil.c>
diff --git a/libc/sysdeps/unix/sysv/linux/pselect.c b/libc/sysdeps/unix/sysv/linux/pselect.c
new file mode 100644
index 000000000..0dd744f52
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/pselect.c
@@ -0,0 +1,100 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/poll.h>
+#include <kernel-features.h>
+#include <sysdep-cancel.h>
+
+
+#ifdef __NR_pselect6
+static int __generic_pselect (int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds,
+ const struct timespec *timeout,
+ const sigset_t *sigmask);
+
+
+int
+__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ const struct timespec *timeout, const sigset_t *sigmask)
+{
+ /* The Linux kernel can in some situations update the timeout value.
+ We do not want that so use a local variable. */
+ struct timespec tval;
+ if (timeout != NULL)
+ {
+ tval = *timeout;
+ timeout = &tval;
+ }
+
+ /* Note: the system call expects 7 values but on most architectures
+ we can only pass in 6 directly. If there is an architecture with
+ support for more parameters a new version of this file needs to
+ be created. */
+ struct
+ {
+ const sigset_t *ss;
+ size_t ss_len;
+ } data;
+
+ data.ss = sigmask;
+ data.ss_len = _NSIG / 8;
+
+ int result;
+
+#ifndef CALL_PSELECT6
+# define CALL_PSELECT6(nfds, readfds, writefds, exceptfds, timeout, data) \
+ INLINE_SYSCALL (pselect6, 6, nfds, readfds, writefds, exceptfds, \
+ timeout, data)
+#endif
+
+ if (SINGLE_THREAD_P)
+ result = CALL_PSELECT6 (nfds, readfds, writefds, exceptfds, timeout,
+ &data);
+ else
+ {
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ result = CALL_PSELECT6 (nfds, readfds, writefds, exceptfds, timeout,
+ &data);
+
+ LIBC_CANCEL_RESET (oldtype);
+ }
+
+# ifndef __ASSUME_PSELECT
+ if (result == -1 && errno == ENOSYS)
+ result = __generic_pselect (nfds, readfds, writefds, exceptfds, timeout,
+ sigmask);
+# endif
+
+ return result;
+}
+weak_alias (__pselect, pselect)
+strong_alias (__pselect, __libc_pselect)
+
+# ifndef __ASSUME_PSELECT
+# define __pselect static __generic_pselect
+# endif
+#endif
+
+#ifndef __ASSUME_PSELECT
+# include <misc/pselect.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/ptrace.c b/libc/sysdeps/unix/sysv/linux/ptrace.c
new file mode 100644
index 000000000..e33eee0ee
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ptrace.c
@@ -0,0 +1,113 @@
+/* Copyright (C) 1995,1996,1997,1998,2000,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/user.h>
+#include <stdarg.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+long int
+ptrace (enum __ptrace_request request, ...)
+{
+ long int res, ret;
+ va_list ap;
+ pid_t pid;
+ void *addr, *data;
+
+ va_start (ap, request);
+ pid = va_arg (ap, pid_t);
+ addr = va_arg (ap, void *);
+ data = va_arg (ap, void *);
+ va_end (ap);
+
+ if (request > 0 && request < 4)
+ data = &ret;
+
+#if __BOUNDED_POINTERS__
+ switch (request)
+ {
+ case PTRACE_PEEKTEXT:
+ case PTRACE_PEEKDATA:
+ case PTRACE_PEEKUSER:
+ case PTRACE_POKETEXT:
+ case PTRACE_POKEDATA:
+ case PTRACE_POKEUSER:
+ (void) CHECK_1 ((int *) addr);
+ (void) CHECK_1 ((int *) data);
+ break;
+
+ case PTRACE_GETREGS:
+ case PTRACE_SETREGS:
+#ifdef __i386__
+ (void) CHECK_1 ((struct user_regs_struct *) data);
+#else
+ /* We don't know the size of data, so the best we can do is ensure
+ that `data' is valid for at least one word. */
+ (void) CHECK_1 ((int *) data);
+#endif
+ break;
+
+ case PTRACE_GETFPREGS:
+ case PTRACE_SETFPREGS:
+#ifdef __i386__
+ (void) CHECK_1 ((struct user_fpregs_struct *) data);
+#else
+ /* We don't know the size of data, so the best we can do is ensure
+ that `data' is valid for at least one word. */
+ (void) CHECK_1 ((int *) data);
+#endif
+ break;
+
+ case PTRACE_GETFPXREGS:
+ case PTRACE_SETFPXREGS:
+#ifdef __i386__
+ (void) CHECK_1 ((struct user_fpxregs_struct *) data);
+#else
+ /* We don't know the size of data, so the best we can do is ensure
+ that `data' is valid for at least one word. */
+ (void) CHECK_1 ((int *) data);
+#endif
+ break;
+
+ case PTRACE_TRACEME:
+ case PTRACE_CONT:
+ case PTRACE_KILL:
+ case PTRACE_SINGLESTEP:
+ case PTRACE_ATTACH:
+ case PTRACE_DETACH:
+ case PTRACE_SYSCALL:
+ /* Neither `data' nor `addr' needs any checks. */
+ break;
+ };
+#endif
+
+ res = INLINE_SYSCALL (ptrace, 4, request, pid,
+ __ptrvalue (addr), __ptrvalue (data));
+ if (res >= 0 && request > 0 && request < 4)
+ {
+ __set_errno (0);
+ return ret;
+ }
+
+ return res;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/ptsname.c b/libc/sysdeps/unix/sysv/linux/ptsname.c
new file mode 100644
index 000000000..9c364b18b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ptsname.c
@@ -0,0 +1,167 @@
+/* Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <paths.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <stdio-common/_itoa.h>
+
+/* Check if DEV corresponds to a master pseudo terminal device. */
+#define MASTER_P(Dev) \
+ (major ((Dev)) == 2 \
+ || (major ((Dev)) == 4 && minor ((Dev)) >= 128 && minor ((Dev)) < 192) \
+ || (major ((Dev)) >= 128 && major ((Dev)) < 136))
+
+/* Check if DEV corresponds to a slave pseudo terminal device. */
+#define SLAVE_P(Dev) \
+ (major ((Dev)) == 3 \
+ || (major ((Dev)) == 4 && minor ((Dev)) >= 192 && minor ((Dev)) < 256) \
+ || (major ((Dev)) >= 136 && major ((Dev)) < 144))
+
+/* Note that major number 4 corresponds to the old BSD style pseudo
+ terminal devices. As of Linux 2.1.115 these are no longer
+ supported. They have been replaced by major numbers 2 (masters)
+ and 3 (slaves). */
+
+/* Directory where we can find the slave pty nodes. */
+#define _PATH_DEVPTS "/dev/pts/"
+
+/* The are declared in getpt.c. */
+extern const char __libc_ptyname1[] attribute_hidden;
+extern const char __libc_ptyname2[] attribute_hidden;
+
+/* Static buffer for `ptsname'. */
+static char buffer[sizeof (_PATH_DEVPTS) + 20];
+
+
+/* Return the pathname of the pseudo terminal slave assoicated with
+ the master FD is open on, or NULL on errors.
+ The returned storage is good until the next call to this function. */
+char *
+ptsname (int fd)
+{
+ return __ptsname_r (fd, buffer, sizeof (buffer)) != 0 ? NULL : buffer;
+}
+
+
+/* Store at most BUFLEN characters of the pathname of the slave pseudo
+ terminal associated with the master FD is open on in BUF.
+ Return 0 on success, otherwise an error number. */
+int
+__ptsname_r (int fd, char *buf, size_t buflen)
+{
+ int save_errno = errno;
+ struct stat64 st;
+ unsigned int ptyno;
+
+ if (buf == NULL)
+ {
+ __set_errno (EINVAL);
+ return EINVAL;
+ }
+
+ if (!__isatty (fd))
+ {
+ __set_errno (ENOTTY);
+ return ENOTTY;
+ }
+
+#ifdef TIOCGPTN
+ if (__ioctl (fd, TIOCGPTN, &ptyno) == 0)
+ {
+ /* Buffer we use to print the number in. For a maximum size for
+ `int' of 8 bytes we never need more than 20 digits. */
+ char numbuf[21];
+ const char *devpts = _PATH_DEVPTS;
+ const size_t devptslen = strlen (_PATH_DEVPTS);
+ char *p;
+
+ numbuf[sizeof (numbuf) - 1] = '\0';
+ p = _itoa_word (ptyno, &numbuf[sizeof (numbuf) - 1], 10, 0);
+
+ if (buflen < devptslen + (&numbuf[sizeof (numbuf)] - p))
+ {
+ __set_errno (ERANGE);
+ return ERANGE;
+ }
+
+ memcpy (__stpcpy (buf, devpts), p, &numbuf[sizeof (numbuf)] - p);
+ }
+ else if (errno == EINVAL)
+#endif
+ {
+ char *p;
+
+ if (buflen < strlen (_PATH_TTY) + 3)
+ {
+ __set_errno (ERANGE);
+ return ERANGE;
+ }
+
+ if (__fxstat64 (_STAT_VER, fd, &st) < 0)
+ return errno;
+
+ /* Check if FD really is a master pseudo terminal. */
+ if (! MASTER_P (st.st_rdev))
+ {
+ __set_errno (ENOTTY);
+ return ENOTTY;
+ }
+
+ ptyno = minor (st.st_rdev);
+ /* This is for the old BSD pseudo terminals. As of Linux
+ 2.1.115 these are no longer supported. */
+ if (major (st.st_rdev) == 4)
+ ptyno -= 128;
+
+ if (ptyno / 16 >= strlen (__libc_ptyname1))
+ {
+ __set_errno (ENOTTY);
+ return ENOTTY;
+ }
+
+ p = __stpcpy (buf, _PATH_TTY);
+ p[0] = __libc_ptyname1[ptyno / 16];
+ p[1] = __libc_ptyname2[ptyno % 16];
+ p[2] = '\0';
+ }
+
+ if (__xstat64 (_STAT_VER, buf, &st) < 0)
+ return errno;
+
+ /* Check if the name we're about to return really corresponds to a
+ slave pseudo terminal. */
+ if (! S_ISCHR (st.st_mode) || ! SLAVE_P (st.st_rdev))
+ {
+ /* This really is a configuration problem. */
+ __set_errno (ENOTTY);
+ return ENOTTY;
+ }
+
+ __set_errno (save_errno);
+ return 0;
+}
+weak_alias (__ptsname_r, ptsname_r)
diff --git a/libc/sysdeps/unix/sysv/linux/pwrite.c b/libc/sysdeps/unix/sysv/linux/pwrite.c
new file mode 100644
index 000000000..7afb81451
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/pwrite.c
@@ -0,0 +1,96 @@
+/* Copyright (C) 1997-2000,2002,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <endian.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_pwrite
+# error "__NR_pwrite and __NR_pwrite64 both defined???"
+# endif
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
+
+# if __ASSUME_PWRITE_SYSCALL == 0
+static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count,
+ off_t offset) internal_function;
+# endif
+
+
+static ssize_t
+#ifdef NO_CANCELLATION
+inline __attribute ((always_inline))
+#endif
+do_pwrite (int fd, const void *buf, size_t count, off_t offset)
+{
+ ssize_t result;
+
+ /* First try the syscall. */
+ assert (sizeof (offset) == 4);
+ result = INLINE_SYSCALL (pwrite, 5, fd, CHECK_N (buf, count), count,
+ __LONG_LONG_PAIR (offset >> 31, offset));
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite (fd, buf, count, offset);
+# endif
+
+ return result;
+}
+
+
+ssize_t
+__libc_pwrite (fd, buf, count, offset)
+ int fd;
+ const void *buf;
+ size_t count;
+ off_t offset;
+{
+ if (SINGLE_THREAD_P)
+ return do_pwrite (fd, buf, count, offset);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = do_pwrite (fd, buf, count, offset);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+strong_alias (__libc_pwrite, __pwrite)
+weak_alias (__libc_pwrite, pwrite)
+
+# define __libc_pwrite(fd, buf, count, offset) \
+ static internal_function __emulate_pwrite (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/pwrite64.c b/libc/sysdeps/unix/sysv/linux/pwrite64.c
new file mode 100644
index 000000000..a0a6a0831
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/pwrite64.c
@@ -0,0 +1,94 @@
+/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <endian.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_pwrite
+# error "__NR_pwrite and __NR_pwrite64 both defined???"
+# endif
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
+
+# if __ASSUME_PWRITE_SYSCALL == 0
+static ssize_t __emulate_pwrite64 (int fd, const void *buf, size_t count,
+ off64_t offset) internal_function;
+# endif
+
+
+static ssize_t
+do_pwrite64 (int fd, const void *buf, size_t count, off64_t offset)
+{
+ ssize_t result;
+
+ /* First try the syscall. */
+ result = INLINE_SYSCALL (pwrite, 5, fd, CHECK_N (buf, count), count,
+ __LONG_LONG_PAIR ((off_t) (offset >> 32),
+ (off_t) (offset & 0xffffffff)));
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite64 (fd, buf, count, offset);
+# endif
+
+ return result;
+}
+
+
+ssize_t
+__libc_pwrite64 (fd, buf, count, offset)
+ int fd;
+ const void *buf;
+ size_t count;
+ off64_t offset;
+{
+ if (SINGLE_THREAD_P)
+ return do_pwrite64 (fd, buf, count, offset);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = do_pwrite64 (fd, buf, count, offset);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+weak_alias (__libc_pwrite64, __pwrite64)
+libc_hidden_weak (__pwrite64)
+weak_alias (__libc_pwrite64, pwrite64)
+
+# define __libc_pwrite64(fd, buf, count, offset) \
+ static internal_function __emulate_pwrite64 (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite64.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/readahead.c b/libc/sysdeps/unix/sysv/linux/readahead.c
new file mode 100644
index 000000000..dc628b2b2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/readahead.c
@@ -0,0 +1,48 @@
+/* Provide kernel hint to read ahead.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+
+#ifdef __NR_readahead
+
+ssize_t
+__readahead (int fd, off64_t offset, size_t count)
+{
+ return INLINE_SYSCALL (readahead, 4, fd, (off_t) (offset >> 32),
+ (off_t) (offset & 0xffffffff), count);
+}
+#else
+ssize_t
+__readahead (int fd, off64_t offset, size_t count)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+stub_warning (readahead)
+
+# include <stub-tag.h>
+#endif
+
+weak_alias (__readahead, readahead)
diff --git a/libc/sysdeps/unix/sysv/linux/readdir64.c b/libc/sysdeps/unix/sysv/linux/readdir64.c
new file mode 100644
index 000000000..e2c500239
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/readdir64.c
@@ -0,0 +1,7 @@
+#define __READDIR __readdir64
+#define __GETDENTS __getdents64
+#define DIRENT_TYPE struct dirent64
+
+#include <sysdeps/unix/readdir.c>
+
+weak_alias (__readdir64, readdir64)
diff --git a/libc/sysdeps/unix/sysv/linux/readdir64_r.c b/libc/sysdeps/unix/sysv/linux/readdir64_r.c
new file mode 100644
index 000000000..bce56124e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/readdir64_r.c
@@ -0,0 +1,7 @@
+#define __READDIR_R __readdir64_r
+#define __GETDENTS __getdents64
+#define DIRENT_TYPE struct dirent64
+
+#include <sysdeps/unix/readdir_r.c>
+
+weak_alias (__readdir64_r, readdir64_r)
diff --git a/libc/sysdeps/unix/sysv/linux/readlinkat.c b/libc/sysdeps/unix/sysv/linux/readlinkat.c
new file mode 100644
index 000000000..136159650
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/readlinkat.c
@@ -0,0 +1,90 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysdep.h>
+#include <unistd.h>
+#include <kernel-features.h>
+
+
+/* Read the contents of the symbolic link PATH relative to FD into no
+ more than LEN bytes of BUF. */
+ssize_t
+readlinkat (fd, path, buf, len)
+ int fd;
+ const char *path;
+ char *buf;
+ size_t len;
+{
+ int result;
+
+#ifdef __NR_readlinkat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INLINE_SYSCALL (readlinkat, 4, fd, path, buf, len);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ char *pathbuf = NULL;
+
+ if (fd != AT_FDCWD && path[0] != '/')
+ {
+ size_t pathlen = strlen (path);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + pathlen;
+ pathbuf = __alloca (buflen);
+
+ __snprintf (pathbuf, buflen, procfd, fd, path);
+ path = pathbuf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+ result = INTERNAL_SYSCALL (readlink, err, 3, path, buf, len);
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ {
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, pathbuf);
+ result = -1;
+ }
+
+ return result;
+#endif
+}
+libc_hidden_def (readlinkat)
diff --git a/libc/sysdeps/unix/sysv/linux/readonly-area.c b/libc/sysdeps/unix/sysv/linux/readonly-area.c
new file mode 100644
index 000000000..69e926a7a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/readonly-area.c
@@ -0,0 +1,103 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include "libio/libioP.h"
+
+/* Return 1 if the whole area PTR .. PTR+SIZE is not writable.
+ Return -1 if it is writable. */
+
+int
+__readonly_area (const char *ptr, size_t size)
+{
+ const void *ptr_end = ptr + size;
+
+ FILE *fp = fopen ("/proc/self/maps", "rc");
+ if (fp == NULL)
+ {
+ /* It is the system administrator's choice to not have /proc
+ available to this process (e.g., because it runs in a chroot
+ environment. Don't fail in this case. */
+ if (errno == ENOENT
+ /* The kernel has a bug in that a process is denied access
+ to the /proc filesystem if it is set[ug]id. There has
+ been no willingness to change this in the kernel so
+ far. */
+ || errno == EACCES)
+ return 1;
+ return -1;
+ }
+
+ /* We need no locking. */
+ __fsetlocking (fp, FSETLOCKING_BYCALLER);
+
+ char *line = NULL;
+ size_t linelen = 0;
+
+ while (! feof_unlocked (fp))
+ {
+ if (_IO_getdelim (&line, &linelen, '\n', fp) <= 0)
+ break;
+
+ char *p;
+ uintptr_t from = strtoul (line, &p, 16);
+
+ if (p == line || *p++ != '-')
+ break;
+
+ char *q;
+ uintptr_t to = strtoul (p, &q, 16);
+
+ if (q == p || *q++ != ' ')
+ break;
+
+ if (from < (uintptr_t) ptr_end && to > (uintptr_t) ptr)
+ {
+ /* Found an entry that at least partially covers the area. */
+ if (*q++ != 'r' || *q++ != '-')
+ break;
+
+ if (from <= (uintptr_t) ptr && to >= (uintptr_t) ptr_end)
+ {
+ size = 0;
+ break;
+ }
+ else if (from <= (uintptr_t) ptr)
+ size -= to - (uintptr_t) ptr;
+ else if (to >= (uintptr_t) ptr_end)
+ size -= (uintptr_t) ptr_end - from;
+ else
+ size -= to - from;
+
+ if (!size)
+ break;
+ }
+ }
+
+ fclose (fp);
+ free (line);
+
+ /* If the whole area between ptr and ptr_end is covered by read-only
+ VMAs, return 1. Otherwise return -1. */
+ return size == 0 ? 1 : -1;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/readv.c b/libc/sysdeps/unix/sysv/linux/readv.c
new file mode 100644
index 000000000..250c00a07
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/readv.c
@@ -0,0 +1,76 @@
+/* readv supports all Linux kernels >= 2.0.
+ Copyright (C) 1997,1998,2000,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/param.h>
+#include <sys/uio.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+static ssize_t __atomic_readv_replacement (int, __const struct iovec *,
+ int) internal_function;
+
+
+/* Not all versions of the kernel support the large number of records. */
+#ifndef UIO_FASTIOV
+# define UIO_FASTIOV 8 /* 8 is a safe number. */
+#endif
+
+
+/* We should deal with kernel which have a smaller UIO_FASTIOV as well
+ as a very big count. */
+static ssize_t
+do_readv (int fd, const struct iovec *vector, int count)
+{
+ ssize_t bytes_read;
+
+ bytes_read = INLINE_SYSCALL (readv, 3, fd, CHECK_N (vector, count), count);
+
+ if (bytes_read >= 0 || errno != EINVAL || count <= UIO_FASTIOV)
+ return bytes_read;
+
+ return __atomic_readv_replacement (fd, vector, count);
+}
+
+
+ssize_t
+__libc_readv (fd, vector, count)
+ int fd;
+ const struct iovec *vector;
+ int count;
+{
+ if (SINGLE_THREAD_P)
+ return do_readv (fd, vector, count);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_readv (fd, vector, count);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+strong_alias (__libc_readv, __readv)
+weak_alias (__libc_readv, readv)
+
+#define __libc_readv static internal_function __atomic_readv_replacement
+#include <sysdeps/posix/readv.c>
diff --git a/libc/sysdeps/unix/sysv/linux/reboot.c b/libc/sysdeps/unix/sysv/linux/reboot.c
new file mode 100644
index 000000000..e936f0456
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/reboot.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1996, 1997, 1998, 1999, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/reboot.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Call kernel with additional two arguments the syscall requires. */
+int
+reboot (int howto)
+{
+ return INLINE_SYSCALL (reboot, 3, (int) 0xfee1dead, 672274793, howto);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/recv.S b/libc/sysdeps/unix/sysv/linux/recv.S
new file mode 100644
index 000000000..331844abc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/recv.S
@@ -0,0 +1,6 @@
+#define socket recv
+#define __socket __libc_recv
+#define NARGS 4
+#define NEED_CANCELLATION
+#include <socket.S>
+weak_alias (__libc_recv, __recv)
diff --git a/libc/sysdeps/unix/sysv/linux/recvfrom.S b/libc/sysdeps/unix/sysv/linux/recvfrom.S
new file mode 100644
index 000000000..ccbb0a75d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/recvfrom.S
@@ -0,0 +1,6 @@
+#define socket recvfrom
+#define __socket __libc_recvfrom
+#define NARGS 6
+#define NEED_CANCELLATION
+#include <socket.S>
+weak_alias (__libc_recvfrom, __recvfrom)
diff --git a/libc/sysdeps/unix/sysv/linux/recvmsg.S b/libc/sysdeps/unix/sysv/linux/recvmsg.S
new file mode 100644
index 000000000..d44bc39f9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/recvmsg.S
@@ -0,0 +1,6 @@
+#define socket recvmsg
+#define __socket __libc_recvmsg
+#define NARGS 3
+#define NEED_CANCELLATION
+#include <socket.S>
+weak_alias (__libc_recvmsg, __recvmsg)
diff --git a/libc/sysdeps/unix/sysv/linux/renameat.c b/libc/sysdeps/unix/sysv/linux/renameat.c
new file mode 100644
index 000000000..86bb75a7b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/renameat.c
@@ -0,0 +1,184 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <kernel-features.h>
+#include <sysdep.h>
+
+
+#ifndef __ASSUME_ATFCTS
+void
+attribute_hidden
+__atfct_seterrno_2 (int errval, int fd1, const char *buf1, int fd2,
+ const char *buf2)
+{
+ if (buf1 != NULL || buf2 != NULL)
+ {
+ struct stat64 st;
+
+ if (errval == ENOTDIR)
+ {
+ /* This can mean either the file descriptor is invalid or
+ /proc is not mounted. */
+ if (buf1 != NULL)
+ {
+ if (__fxstat64 (_STAT_VER, fd1, &st) != 0)
+ /* errno is already set correctly. */
+ return;
+
+ /* If /proc is not mounted there is nothing we can do. */
+ if (S_ISDIR (st.st_mode)
+ && (__xstat64 (_STAT_VER, "/proc/self/fd", &st) != 0
+ || !S_ISDIR (st.st_mode)))
+ {
+ errval = ENOSYS;
+ goto out;
+ }
+ }
+
+ if (buf2 != NULL)
+ {
+ if (__fxstat64 (_STAT_VER, fd2, &st) != 0)
+ /* errno is already set correctly. */
+ return;
+
+ /* If /proc is not mounted there is nothing we can do. */
+ if (S_ISDIR (st.st_mode)
+ && (__xstat64 (_STAT_VER, "/proc/self/fd", &st) != 0
+ || !S_ISDIR (st.st_mode)))
+ errval = ENOSYS;
+ }
+ }
+ else if (errval == ENOENT)
+ {
+ /* This could mean the file descriptor is not valid. We
+ reuse BUF for the stat call. Find the slash after the
+ file descriptor number. */
+ if (buf1 != NULL)
+ {
+ *(char *) strchr (buf1 + sizeof "/proc/self/fd", '/') = '\0';
+
+ int e = __lxstat64 (_STAT_VER, buf1, &st);
+ if ((e == -1 && errno == ENOENT)
+ ||(e == 0 && !S_ISLNK (st.st_mode)))
+ {
+ errval = EBADF;
+ goto out;
+ }
+ }
+
+ if (buf2 != NULL)
+ {
+ *(char *) strchr (buf2 + sizeof "/proc/self/fd", '/') = '\0';
+
+ int e = __lxstat64 (_STAT_VER, buf2, &st);
+ if ((e == -1 && errno == ENOENT)
+ ||(e == 0 && !S_ISLNK (st.st_mode)))
+ errval = EBADF;
+ }
+ }
+ }
+
+ out:
+ __set_errno (errval);
+}
+#endif
+
+
+/* Rename the file OLD relative to OLDFD to NEW relative to NEWFD. */
+int
+renameat (oldfd, old, newfd, new)
+ int oldfd;
+ const char *old;
+ int newfd;
+ const char *new;
+{
+ int result;
+
+#ifdef __NR_renameat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INLINE_SYSCALL (renameat, 4, oldfd, old, newfd, new);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ char *bufold = NULL;
+
+ if (oldfd != AT_FDCWD && old[0] != '/')
+ {
+ size_t filelen = strlen (old);
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ bufold = alloca (buflen);
+
+ __snprintf (bufold, buflen, procfd, oldfd, old);
+ old = bufold;
+ }
+
+ char *bufnew = NULL;
+
+ if (newfd != AT_FDCWD && new[0] != '/')
+ {
+ size_t filelen = strlen (new);
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ bufnew = alloca (buflen);
+
+ __snprintf (bufnew, buflen, procfd, newfd, new);
+ new = bufnew;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+ result = INTERNAL_SYSCALL (rename, err, 2, old, new);
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ {
+ __atfct_seterrno_2 (INTERNAL_SYSCALL_ERRNO (result, err), newfd, bufnew,
+ oldfd, bufold);
+ result = -1;
+ }
+
+ return result;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/s390/Implies b/libc/sysdeps/unix/sysv/linux/s390/Implies
new file mode 100644
index 000000000..efda9d27c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/Implies
@@ -0,0 +1,3 @@
+# These supply the ABI compatibility for when long double was double.
+ieee754/ldbl-64-128
+ieee754/ldbl-opt
diff --git a/libc/sysdeps/unix/sysv/linux/s390/Makefile b/libc/sysdeps/unix/sysv/linux/s390/Makefile
new file mode 100644
index 000000000..5c5381871
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/Makefile
@@ -0,0 +1,8 @@
+64bit-predefine = __s390x__
+ifeq ($(subdir),rt)
+librt-routines += rt-sysdep
+endif
+
+ifeq ($(subdir),stdlib)
+gen-as-const-headers += ucontext_i.sym
+endif
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/elfclass.h b/libc/sysdeps/unix/sysv/linux/s390/bits/elfclass.h
new file mode 100644
index 000000000..dd3d02809
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/elfclass.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file specifies the native word size of the machine, which indicates
+ the ELF file class used for executables and shared objects on this
+ machine. */
+
+#ifndef _LINK_H
+# error "Never use <bits/elfclass.h> directly; include <link.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#define __ELF_NATIVE_CLASS __WORDSIZE
+
+#if __WORDSIZE == 64
+/* 64 bit Linux for S/390 is exceptional as it has .hash section with
+ 64 bit entries. */
+typedef uint64_t Elf_Symndx;
+#else
+/* 32 bit Linux for S/390 has normal .hash section entries with 32 bits. */
+typedef uint32_t Elf_Symndx;
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/environments.h b/libc/sysdeps/unix/sysv/linux/s390/bits/environments.h
new file mode 100644
index 000000000..713d21c9a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/environments.h
@@ -0,0 +1,87 @@
+/* Copyright (C) 1999, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _UNISTD_H
+# error "Never include this file directly. Use <unistd.h> instead"
+#endif
+
+#include <bits/wordsize.h>
+
+/* This header should define the following symbols under the described
+ situations. A value `1' means that the model is always supported,
+ `-1' means it is never supported. Undefined means it cannot be
+ statically decided.
+
+ _POSIX_V6_ILP32_OFF32 32bit int, long, pointers, and off_t type
+ _POSIX_V6_ILP32_OFFBIG 32bit int, long, and pointers and larger off_t type
+
+ _POSIX_V6_LP64_OFF32 64bit long and pointers and 32bit off_t type
+ _POSIX_V6_LPBIG_OFFBIG 64bit long and pointers and large off_t type
+
+ The macros _XBS5_ILP32_OFF32, _XBS5_ILP32_OFFBIG, _XBS5_LP64_OFF32, and
+ _XBS5_LPBIG_OFFBIG were used in previous versions of the Unix standard
+ and are available only for compatibility.
+*/
+
+#if __WORDSIZE == 64
+
+/* Environments with 32-bit wide pointers are optionally provided.
+ Therefore following macros aren't defined:
+ # undef _POSIX_V6_ILP32_OFF32
+ # undef _POSIX_V6_ILP32_OFFBIG
+ # undef _XBS5_ILP32_OFF32
+ # undef _XBS5_ILP32_OFFBIG
+ and users need to check at runtime. */
+
+/* We also have no use (for now) for an environment with bigger pointers
+ and offsets. */
+# define _POSIX_V6_LPBIG_OFFBIG -1
+# define _XBS5_LPBIG_OFFBIG -1
+
+/* By default we have 64-bit wide `long int', pointers and `off_t'. */
+# define _POSIX_V6_LP64_OFF64 1
+# define _XBS5_LP64_OFF64 1
+
+#else /* __WORDSIZE == 32 */
+
+/* By default we have 32-bit wide `int', `long int', pointers and `off_t'
+ and all platforms support LFS. */
+# define _POSIX_V6_ILP32_OFF32 1
+# define _POSIX_V6_ILP32_OFFBIG 1
+# define _XBS5_ILP32_OFF32 1
+# define _XBS5_ILP32_OFFBIG 1
+
+/* We optionally provide an environment with the above size but an 64-bit
+ side `off_t'. Therefore we don't define _XBS5_ILP32_OFFBIG. */
+
+/* Environments with 64-bit wide pointers can be provided,
+ so these macros aren't defined:
+ # undef _POSIX_V6_LP64_OFF64
+ # undef _POSIX_V6_LPBIG_OFFBIG
+ # undef _XBS5_LP64_OFF64
+ # undef _XBS5_LPBIG_OFFBIG
+ and sysconf tests for it at runtime. */
+
+#endif /* __WORDSIZE == 32 */
+
+#define __ILP32_OFF32_CFLAGS "-m31"
+#define __ILP32_OFFBIG_CFLAGS "-m31 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+#define __ILP32_OFF32_LDFLAGS "-m31"
+#define __ILP32_OFFBIG_LDFLAGS "-m31"
+#define __LP64_OFF64_CFLAGS "-m64"
+#define __LP64_OFF64_LDFLAGS "-m64"
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/fcntl.h b/libc/sysdeps/unix/sysv/linux/s390/bits/fcntl.h
new file mode 100644
index 000000000..e5a917dbf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/fcntl.h
@@ -0,0 +1,256 @@
+/* O_*, F_*, FD_* bit values for Linux.
+ Copyright (C) 2000, 2001, 2002, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#include <sys/types.h>
+#include <bits/wordsize.h>
+#ifdef __USE_GNU
+# include <bits/uio.h>
+#endif
+
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_ACCMODE 0003
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+#define O_CREAT 0100 /* not fcntl */
+#define O_EXCL 0200 /* not fcntl */
+#define O_NOCTTY 0400 /* not fcntl */
+#define O_TRUNC 01000 /* not fcntl */
+#define O_APPEND 02000
+#define O_NONBLOCK 04000
+#define O_NDELAY O_NONBLOCK
+#define O_SYNC 010000
+#define O_FSYNC O_SYNC
+#define O_ASYNC 020000
+
+#ifdef __USE_GNU
+# define O_DIRECT 040000 /* Direct disk access. */
+# define O_DIRECTORY 0200000 /* Must be a directory. */
+# define O_NOFOLLOW 0400000 /* Do not follow links. */
+# define O_NOATIME 01000000 /* Do not set atime. */
+#endif
+
+#ifdef __USE_LARGEFILE64
+# if __WORDSIZE == 64
+/* Not necessary, files are always with 64bit off_t. */
+# define O_LARGEFILE 0
+# else
+# define O_LARGEFILE 0100000
+# endif
+#endif
+
+/* For now Linux has synchronisity options for data and read operations.
+ We define the symbols here but let them do the same as O_SYNC since
+ this is a superset. */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC O_SYNC /* Synchronize data. */
+# define O_RSYNC O_SYNC /* Synchronize read operations. */
+#endif
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#if __WORDSIZE == 64
+# define F_GETLK 5 /* Get record locking info. */
+# define F_SETLK 6 /* Set record locking info (non-blocking). */
+# define F_SETLKW 7 /* Set record locking info (blocking). */
+/* Not necessary, we always have 64-bit offsets. */
+# define F_GETLK64 5 /* Get record locking info. */
+# define F_SETLK64 6 /* Set record locking info (non-blocking). */
+# define F_SETLKW64 7 /* Set record locking info (blocking). */
+#else
+# ifndef __USE_FILE_OFFSET64
+# define F_GETLK 5 /* Get record locking info. */
+# define F_SETLK 6 /* Set record locking info (non-blocking). */
+# define F_SETLKW 7 /* Set record locking info (blocking). */
+# else
+# define F_GETLK F_GETLK64 /* Get record locking info. */
+# define F_SETLK F_SETLK64 /* Set record locking info (non-blocking).*/
+# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */
+# endif
+# define F_GETLK64 12 /* Get record locking info. */
+# define F_SETLK64 13 /* Set record locking info (non-blocking). */
+# define F_SETLKW64 14 /* Set record locking info (blocking). */
+#endif
+
+#if defined __USE_BSD || defined __USE_UNIX98
+# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */
+# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETSIG 10 /* Set number of signal to be sent. */
+# define F_GETSIG 11 /* Get number of signal to be sent. */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETLEASE 1024 /* Set a lease. */
+# define F_GETLEASE 1025 /* Enquire what lease is active. */
+# define F_NOTIFY 1026 /* Request notfications on a directory. */
+#endif
+
+/* For F_[GET|SET]FD. */
+#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
+#define F_RDLCK 0 /* Read lock. */
+#define F_WRLCK 1 /* Write lock. */
+#define F_UNLCK 2 /* Remove lock. */
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK 4 /* or 3 */
+#define F_SHLCK 8 /* or 4 */
+
+#ifdef __USE_BSD
+/* Operations for bsd flock(), also used by the kernel implementation */
+# define LOCK_SH 1 /* shared lock */
+# define LOCK_EX 2 /* exclusive lock */
+# define LOCK_NB 4 /* or'd with one of the above to prevent
+ blocking */
+# define LOCK_UN 8 /* remove lock */
+#endif
+
+#ifdef __USE_GNU
+# define LOCK_MAND 32 /* This is a mandatory flock: */
+# define LOCK_READ 64 /* ... which allows concurrent read operations. */
+# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */
+# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */
+#endif
+
+#ifdef __USE_GNU
+/* Types of directory notifications that may be requested with F_NOTIFY. */
+# define DN_ACCESS 0x00000001 /* File accessed. */
+# define DN_MODIFY 0x00000002 /* File modified. */
+# define DN_CREATE 0x00000004 /* File created. */
+# define DN_DELETE 0x00000008 /* File removed. */
+# define DN_RENAME 0x00000010 /* File renamed. */
+# define DN_ATTRIB 0x00000020 /* File changed attibutes. */
+# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */
+#endif
+
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+#else
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+#endif
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+#endif
+
+/* Define some more compatibility macros to be backward compatible with
+ BSD systems which did not managed to hide these kernel macros. */
+#ifdef __USE_BSD
+# define FAPPEND O_APPEND
+# define FFSYNC O_FSYNC
+# define FASYNC O_ASYNC
+# define FNONBLOCK O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif /* Use BSD. */
+
+/* Advise to `posix_fadvise'. */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
+# if __WORDSIZE == 64
+# define POSIX_FADV_DONTNEED 6 /* Don't need these pages. */
+# define POSIX_FADV_NOREUSE 7 /* Data will be accessed once. */
+# else
+# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
+# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
+# endif
+#endif
+
+
+#ifdef __USE_GNU
+/* Flags for SYNC_FILE_RANGE. */
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+
+/* Flags for SPLICE and VMSPLICE. */
+# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */
+# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing
+ (but we may still block on the fd
+ we splice from/to). */
+# define SPLICE_F_MORE 4 /* Expect more data. */
+# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
+#endif
+
+__BEGIN_DECLS
+
+#ifdef __USE_GNU
+
+/* Provide kernel hint to read ahead. */
+extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
+ __THROW;
+
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice address range into a pipe. */
+extern int vmsplice (int __fdout, const struct iovec *__iov, size_t __count,
+ unsigned int __flags);
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/ipc.h b/libc/sysdeps/unix/sysv/linux/s390/bits/ipc.h
new file mode 100644
index 000000000..e3a82d0c4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/ipc.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IPC_H
+# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* Mode bits for `msgget', `semget', and `shmget'. */
+#define IPC_CREAT 01000 /* Create key if key does not exist. */
+#define IPC_EXCL 02000 /* Fail if key exists. */
+#define IPC_NOWAIT 04000 /* Return error on wait. */
+
+/* Control commands for `msgctl', `semctl', and `shmctl'. */
+#define IPC_RMID 0 /* Remove identifier. */
+#define IPC_SET 1 /* Set `ipc_perm' options. */
+#define IPC_STAT 2 /* Get `ipc_perm' options. */
+#ifdef __USE_GNU
+#define IPC_INFO 3 /* See ipcs. */
+#endif
+
+/* Special key values. */
+#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
+
+
+/* Data structure used to pass permission information to IPC operations. */
+struct ipc_perm
+ {
+ __key_t __key; /* Key. */
+ __uid_t uid; /* Owner's user ID. */
+ __gid_t gid; /* Owner's group ID. */
+ __uid_t cuid; /* Creator's user ID. */
+ __gid_t cgid; /* Creator's group ID. */
+#if __WORDSIZE == 64
+ __mode_t mode; /* Read/write permission. */
+#else
+ unsigned short int mode; /* Read/write permission. */
+ unsigned short int __pad1;
+#endif
+ unsigned short int __seq; /* Sequence number. */
+ unsigned short int __pad2;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ };
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/mman.h b/libc/sysdeps/unix/sysv/linux/s390/bits/mman.h
new file mode 100644
index 000000000..d25531c28
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/mman.h
@@ -0,0 +1,104 @@
+/* Definitions for POSIX memory map interface. Linux/s390 version.
+ Copyright (C) 2000,2001,2002,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MMAN_H
+# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
+#endif
+
+/* The following definitions basically come from the kernel headers.
+ But the kernel header is not namespace clean. */
+
+
+/* Protections are chosen from these bits, OR'd together. The
+ implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ without PROT_READ. The only guarantees are that no writing will be
+ allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
+
+#define PROT_READ 0x1 /* Page can be read. */
+#define PROT_WRITE 0x2 /* Page can be written. */
+#define PROT_EXEC 0x4 /* Page can be executed. */
+#define PROT_NONE 0x0 /* Page can not be accessed. */
+#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
+ growsdown vma (mprotect only). */
+#define PROT_GROWSUP 0x02000000 /* Extend change to start of
+ growsup vma (mprotect only). */
+
+/* Sharing types (must choose one and only one of these). */
+#define MAP_SHARED 0x01 /* Share changes. */
+#define MAP_PRIVATE 0x02 /* Changes are private. */
+#ifdef __USE_MISC
+# define MAP_TYPE 0x0f /* Mask for type of mapping. */
+#endif
+
+/* Other flags. */
+#define MAP_FIXED 0x10 /* Interpret addr exactly. */
+#ifdef __USE_MISC
+# define MAP_FILE 0
+# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+
+/* These are Linux-specific. */
+#ifdef __USE_MISC
+# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */
+# define MAP_GROWSUP 0x00200 /* Register stack-like segment */
+# define MAP_DENYWRITE 0x00800 /* ETXTBSY */
+# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */
+# define MAP_LOCKED 0x02000 /* Lock the mapping. */
+# define MAP_NORESERVE 0x04000 /* Don't check for reservations. */
+# define MAP_POPULATE 0x08000 /* Populate (prefault) pagetables. */
+# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */
+#endif
+
+/* Flags to `msync'. */
+#define MS_ASYNC 1 /* Sync memory asynchronously. */
+#define MS_SYNC 4 /* Synchronous memory sync. */
+#define MS_INVALIDATE 2 /* Invalidate the caches. */
+
+/* Flags for `mlockall'. */
+#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
+#define MCL_FUTURE 2 /* Lock all additions to address
+ space. */
+
+/* Flags for `mremap'. */
+#ifdef __USE_GNU
+# define MREMAP_MAYMOVE 1
+# define MREMAP_FIXED 2
+#endif
+
+/* Advice to `madvise'. */
+#ifdef __USE_BSD
+# define MADV_NORMAL 0 /* No further special treatment. */
+# define MADV_RANDOM 1 /* Expect random page references. */
+# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define MADV_WILLNEED 3 /* Will need these pages. */
+# define MADV_DONTNEED 4 /* Don't need these pages. */
+# define MADV_REMOVE 9 /* Remove these pages and resources. */
+# define MADV_DONTFORK 10 /* Do not inherit across fork. */
+# define MADV_DOFORK 11 /* Do inherit across fork. */
+#endif
+
+/* The POSIX people had to invent similar names for the same things. */
+#ifdef __USE_XOPEN2K
+# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/msq.h b/libc/sysdeps/unix/sysv/linux/s390/bits/msq.h
new file mode 100644
index 000000000..ecdd03e17
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/msq.h
@@ -0,0 +1,84 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* Define options for message queue functions. */
+#define MSG_NOERROR 010000 /* no error if message is too big */
+#ifdef __USE_GNU
+# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+#endif
+
+/* Types used in the structure definition. */
+typedef unsigned long int msgqnum_t;
+typedef unsigned long int msglen_t;
+
+
+/* Structure of record for one message inside the kernel.
+ The type `struct msg' is opaque. */
+struct msqid_ds
+{
+ struct ipc_perm msg_perm; /* structure describing operation permission */
+ __time_t msg_stime; /* time of last msgsnd command */
+#if __WORDSIZE != 64
+ unsigned long int __unused1;
+#endif
+ __time_t msg_rtime; /* time of last msgrcv command */
+#if __WORDSIZE != 64
+ unsigned long int __unused2;
+#endif
+ __time_t msg_ctime; /* time of last change */
+#if __WORDSIZE != 64
+ unsigned long int __unused3;
+#endif
+ unsigned long int __msg_cbytes; /* current number of bytes on queue */
+ msgqnum_t msg_qnum; /* number of messages currently on queue */
+ msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+ __pid_t msg_lspid; /* pid of last msgsnd() */
+ __pid_t msg_lrpid; /* pid of last msgrcv() */
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+};
+
+#ifdef __USE_MISC
+
+# define msg_cbytes __msg_cbytes
+
+/* ipcs ctl commands */
+# define MSG_STAT 11
+# define MSG_INFO 12
+
+/* buffer for msgctl calls IPC_INFO, MSG_INFO */
+struct msginfo
+ {
+ int msgpool;
+ int msgmap;
+ int msgmax;
+ int msgmnb;
+ int msgmni;
+ int msgssz;
+ int msgtql;
+ unsigned short int msgseg;
+ };
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/sem.h b/libc/sysdeps/unix/sysv/linux/s390/bits/sem.h
new file mode 100644
index 000000000..1fb152c3a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/sem.h
@@ -0,0 +1,92 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SEM_H
+# error "Never include <bits/sem.h> directly; use <sys/sem.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* Flags for `semop'. */
+#define SEM_UNDO 0x1000 /* undo the operation on exit */
+
+/* Commands for `semctl'. */
+#define GETPID 11 /* get sempid */
+#define GETVAL 12 /* get semval */
+#define GETALL 13 /* get all semval's */
+#define GETNCNT 14 /* get semncnt */
+#define GETZCNT 15 /* get semzcnt */
+#define SETVAL 16 /* set semval */
+#define SETALL 17 /* set all semval's */
+
+
+/* Data structure describing a set of semaphores. */
+struct semid_ds
+{
+ struct ipc_perm sem_perm; /* operation permission struct */
+ __time_t sem_otime; /* last semop() time */
+#if __WORDSIZE != 64
+ unsigned long int __unused1;
+#endif
+ __time_t sem_ctime; /* last time changed by semctl() */
+#if __WORDSIZE != 64
+ unsigned long int __unused2;
+#endif
+ unsigned long int sem_nsems; /* number of semaphores in set */
+ unsigned long int __unused3;
+ unsigned long int __unused4;
+};
+
+/* The user should define a union like the following to use it for arguments
+ for `semctl'.
+
+ union semun
+ {
+ int val; <= value for SETVAL
+ struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET
+ unsigned short int *array; <= array for GETALL & SETALL
+ struct seminfo *__buf; <= buffer for IPC_INFO
+ };
+
+ Previous versions of this file used to define this union but this is
+ incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether
+ one must define the union or not. */
+#define _SEM_SEMUN_UNDEFINED 1
+
+#ifdef __USE_MISC
+
+/* ipcs ctl cmds */
+# define SEM_STAT 18
+# define SEM_INFO 19
+
+struct seminfo
+{
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvmx;
+ int semaem;
+};
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/shm.h b/libc/sysdeps/unix/sysv/linux/s390/bits/shm.h
new file mode 100644
index 000000000..d88ed36ef
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/shm.h
@@ -0,0 +1,110 @@
+/* Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple. */
+#define SHMLBA (__getpagesize ())
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a set of semaphores. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+ size_t shm_segsz; /* size of segment in bytes */
+ __time_t shm_atime; /* time of last shmat() */
+#if __WORDSIZE != 64
+ unsigned long int __unused1;
+#endif
+ __time_t shm_dtime; /* time of last shmdt() */
+#if __WORDSIZE != 64
+ unsigned long int __unused2;
+#endif
+ __time_t shm_ctime; /* time of last change by shmctl() */
+#if __WORDSIZE != 64
+ unsigned long int __unused3;
+#endif
+ __pid_t shm_cpid; /* pid of creator */
+ __pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */
+# define SHM_NORESERVE 010000 /* don't check for reservations */
+
+struct shminfo
+ {
+ unsigned long int shmmax;
+ unsigned long int shmmin;
+ unsigned long int shmmni;
+ unsigned long int shmseg;
+ unsigned long int shmall;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ unsigned long int __unused3;
+ unsigned long int __unused4;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/sigaction.h b/libc/sysdeps/unix/sysv/linux/s390/bits/sigaction.h
new file mode 100644
index 000000000..308cb5bd7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/sigaction.h
@@ -0,0 +1,110 @@
+/* Definitions for 31 & 64 bit S/390 sigaction.
+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIGNAL_H
+# error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+/* Structure describing the action to be taken when a signal arrives. */
+struct sigaction
+ {
+ /* Signal handler. */
+#ifdef __USE_POSIX199309
+ union
+ {
+ /* Used if SA_SIGINFO is not set. */
+ __sighandler_t sa_handler;
+ /* Used if SA_SIGINFO is set. */
+ void (*sa_sigaction) (int, siginfo_t *, void *);
+ }
+ __sigaction_handler;
+# define sa_handler __sigaction_handler.sa_handler
+# define sa_sigaction __sigaction_handler.sa_sigaction
+#else
+ __sighandler_t sa_handler;
+#endif
+
+ /* Special flags. */
+ unsigned long int sa_flags;
+
+ /* Restore handler. */
+ void (*sa_restorer) (void);
+
+ /* Additional set of signals to be blocked. */
+ __sigset_t sa_mask;
+ };
+#else
+/* Structure describing the action to be taken when a signal arrives. */
+struct sigaction
+ {
+ /* Signal handler. */
+#ifdef __USE_POSIX199309
+ union
+ {
+ /* Used if SA_SIGINFO is not set. */
+ __sighandler_t sa_handler;
+ /* Used if SA_SIGINFO is set. */
+ void (*sa_sigaction) (int, siginfo_t *, void *);
+ }
+ __sigaction_handler;
+# define sa_handler __sigaction_handler.sa_handler
+# define sa_sigaction __sigaction_handler.sa_sigaction
+#else
+ __sighandler_t sa_handler;
+#endif
+
+ /* Additional set of signals to be blocked. */
+ __sigset_t sa_mask;
+
+ /* Special flags. */
+ int sa_flags;
+
+ /* Restore handler. */
+ void (*sa_restorer) (void);
+ };
+#endif
+
+/* Bits in `sa_flags'. */
+#define SA_NOCLDSTOP 1 /* Don't send SIGCHLD when children stop. */
+#define SA_NOCLDWAIT 2 /* Don't create zombie on child death. */
+#define SA_SIGINFO 4 /* Invoke signal-catching function with
+ three arguments instead of one. */
+#if defined __USE_UNIX98 || defined __USE_MISC
+# define SA_ONSTACK 0x08000000 /* Use signal stack by using `sa_restorer'. */
+# define SA_RESTART 0x10000000 /* Restart syscall on signal return. */
+# define SA_NODEFER 0x40000000 /* Don't automatically block the signal when
+ its handler is being executed. */
+# define SA_RESETHAND 0x80000000 /* Reset to SIG_DFL on entry to handler. */
+#endif
+#ifdef __USE_MISC
+# define SA_INTERRUPT 0x20000000 /* Historical no-op. */
+
+/* Some aliases for the SA_ constants. */
+# define SA_NOMASK SA_NODEFER
+# define SA_ONESHOT SA_RESETHAND
+# define SA_STACK SA_ONSTACK
+#endif
+
+/* Values for the HOW argument to `sigprocmask'. */
+#define SIG_BLOCK 0 /* Block signals. */
+#define SIG_UNBLOCK 1 /* Unblock signals. */
+#define SIG_SETMASK 2 /* Set the set of blocked signals. */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/siginfo.h b/libc/sysdeps/unix/sysv/linux/s390/bits/siginfo.h
new file mode 100644
index 000000000..0b7985313
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/siginfo.h
@@ -0,0 +1,311 @@
+/* siginfo_t, sigevent and constants. S/390 version.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _SIGNAL_H && !defined __need_siginfo_t \
+ && !defined __need_sigevent_t
+# error "Never include this file directly. Use <signal.h> instead"
+#endif
+
+#include <bits/wordsize.h>
+
+#if (!defined __have_sigval_t \
+ && (defined _SIGNAL_H || defined __need_siginfo_t \
+ || defined __need_sigevent_t))
+# define __have_sigval_t 1
+
+/* Type for data associated with a signal. */
+typedef union sigval
+ {
+ int sival_int;
+ void *sival_ptr;
+ } sigval_t;
+#endif
+
+#if (!defined __have_siginfo_t \
+ && (defined _SIGNAL_H || defined __need_siginfo_t))
+# define __have_siginfo_t 1
+
+# define __SI_MAX_SIZE 128
+# if __WORDSIZE == 64
+# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
+# else
+# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
+# endif
+
+typedef struct siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_errno; /* If non-zero, an errno value associated with
+ this signal, as defined in <errno.h>. */
+ int si_code; /* Signal code. */
+
+ union
+ {
+ int _pad[__SI_PAD_SIZE];
+
+ /* kill(). */
+ struct
+ {
+ __pid_t si_pid; /* Sending process ID. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ } _kill;
+
+ /* POSIX.1b timers. */
+ struct
+ {
+ int si_tid; /* Timer ID. */
+ int si_overrun; /* Overrun count. */
+ sigval_t si_sigval; /* Signal value. */
+ } _timer;
+
+ /* POSIX.1b signals. */
+ struct
+ {
+ __pid_t si_pid; /* Sending process ID. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ sigval_t si_sigval; /* Signal value. */
+ } _rt;
+
+ /* SIGCHLD. */
+ struct
+ {
+ __pid_t si_pid; /* Which child. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ int si_status; /* Exit value or signal. */
+ __clock_t si_utime;
+ __clock_t si_stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
+ struct
+ {
+ void *si_addr; /* Faulting insn/memory ref. */
+ int si_trapno;
+ } _sigfault;
+
+ /* SIGPOLL. */
+ struct
+ {
+ long int si_band; /* Band event for SIGPOLL. */
+ int si_fd;
+ } _sigpoll;
+ } _sifields;
+ } siginfo_t;
+
+
+/* X/Open requires some more fields with fixed names. */
+# define si_pid _sifields._kill.si_pid
+# define si_uid _sifields._kill.si_uid
+# define si_timerid _sifields._timer.si_tid
+# define si_overrun _sifields._timer.si_overrun
+# define si_status _sifields._sigchld.si_status
+# define si_utime _sifields._sigchld.si_utime
+# define si_stime _sifields._sigchld.si_stime
+# define si_value _sifields._rt.si_sigval
+# define si_int _sifields._rt.si_sigval.sival_int
+# define si_ptr _sifields._rt.si_sigval.sival_ptr
+# define si_addr _sifields._sigfault.si_addr
+# define si_trapno _sifields._sigfault.si_trapno
+# define si_band _sifields._sigpoll.si_band
+# define si_fd _sifields._sigpoll.si_fd
+
+
+/* Values for `si_code'. Positive values are reserved for kernel-generated
+ signals. */
+enum
+{
+ SI_ASYNCNL = -60, /* Sent by asynch name lookup completion. */
+# define SI_ASYNCNL SI_ASYNCNL
+ SI_TKILL = -6, /* Sent by tkill. */
+# define SI_TKILL SI_TKILL
+ SI_SIGIO, /* Sent by queued SIGIO. */
+# define SI_SIGIO SI_SIGIO
+ SI_ASYNCIO, /* Sent by AIO completion. */
+# define SI_ASYNCIO SI_ASYNCIO
+ SI_MESGQ, /* Sent by real time mesq state change. */
+# define SI_MESGQ SI_MESGQ
+ SI_TIMER, /* Sent by timer expiration. */
+# define SI_TIMER SI_TIMER
+ SI_QUEUE, /* Sent by sigqueue. */
+# define SI_QUEUE SI_QUEUE
+ SI_USER, /* Sent by kill, sigsend, raise. */
+# define SI_USER SI_USER
+ SI_KERNEL = 0x80 /* Send by kernel. */
+#define SI_KERNEL SI_KERNEL
+};
+
+
+/* `si_code' values for SIGILL signal. */
+enum
+{
+ ILL_ILLOPC = 1, /* Illegal opcode. */
+# define ILL_ILLOPC ILL_ILLOPC
+ ILL_ILLOPN, /* Illegal operand. */
+# define ILL_ILLOPN ILL_ILLOPN
+ ILL_ILLADR, /* Illegal addressing mode. */
+# define ILL_ILLADR ILL_ILLADR
+ ILL_ILLTRP, /* Illegal trap. */
+# define ILL_ILLTRP ILL_ILLTRP
+ ILL_PRVOPC, /* Privileged opcode. */
+# define ILL_PRVOPC ILL_PRVOPC
+ ILL_PRVREG, /* Privileged register. */
+# define ILL_PRVREG ILL_PRVREG
+ ILL_COPROC, /* Coprocessor error. */
+# define ILL_COPROC ILL_COPROC
+ ILL_BADSTK /* Internal stack error. */
+# define ILL_BADSTK ILL_BADSTK
+};
+
+/* `si_code' values for SIGFPE signal. */
+enum
+{
+ FPE_INTDIV = 1, /* Integer divide by zero. */
+# define FPE_INTDIV FPE_INTDIV
+ FPE_INTOVF, /* Integer overflow. */
+# define FPE_INTOVF FPE_INTOVF
+ FPE_FLTDIV, /* Floating point divide by zero. */
+# define FPE_FLTDIV FPE_FLTDIV
+ FPE_FLTOVF, /* Floating point overflow. */
+# define FPE_FLTOVF FPE_FLTOVF
+ FPE_FLTUND, /* Floating point underflow. */
+# define FPE_FLTUND FPE_FLTUND
+ FPE_FLTRES, /* Floating point inexact result. */
+# define FPE_FLTRES FPE_FLTRES
+ FPE_FLTINV, /* Floating point invalid operation. */
+# define FPE_FLTINV FPE_FLTINV
+ FPE_FLTSUB /* Subscript out of range. */
+# define FPE_FLTSUB FPE_FLTSUB
+};
+
+/* `si_code' values for SIGSEGV signal. */
+enum
+{
+ SEGV_MAPERR = 1, /* Address not mapped to object. */
+# define SEGV_MAPERR SEGV_MAPERR
+ SEGV_ACCERR /* Invalid permissions for mapped object. */
+# define SEGV_ACCERR SEGV_ACCERR
+};
+
+/* `si_code' values for SIGBUS signal. */
+enum
+{
+ BUS_ADRALN = 1, /* Invalid address alignment. */
+# define BUS_ADRALN BUS_ADRALN
+ BUS_ADRERR, /* Non-existant physical address. */
+# define BUS_ADRERR BUS_ADRERR
+ BUS_OBJERR /* Object specific hardware error. */
+# define BUS_OBJERR BUS_OBJERR
+};
+
+/* `si_code' values for SIGTRAP signal. */
+enum
+{
+ TRAP_BRKPT = 1, /* Process breakpoint. */
+# define TRAP_BRKPT TRAP_BRKPT
+ TRAP_TRACE /* Process trace trap. */
+# define TRAP_TRACE TRAP_TRACE
+};
+
+/* `si_code' values for SIGCHLD signal. */
+enum
+{
+ CLD_EXITED = 1, /* Child has exited. */
+# define CLD_EXITED CLD_EXITED
+ CLD_KILLED, /* Child was killed. */
+# define CLD_KILLED CLD_KILLED
+ CLD_DUMPED, /* Child terminated abnormally. */
+# define CLD_DUMPED CLD_DUMPED
+ CLD_TRAPPED, /* Traced child has trapped. */
+# define CLD_TRAPPED CLD_TRAPPED
+ CLD_STOPPED, /* Child has stopped. */
+# define CLD_STOPPED CLD_STOPPED
+ CLD_CONTINUED /* Stopped child has continued. */
+# define CLD_CONTINUED CLD_CONTINUED
+};
+
+/* `si_code' values for SIGPOLL signal. */
+enum
+{
+ POLL_IN = 1, /* Data input available. */
+# define POLL_IN POLL_IN
+ POLL_OUT, /* Output buffers available. */
+# define POLL_OUT POLL_OUT
+ POLL_MSG, /* Input message available. */
+# define POLL_MSG POLL_MSG
+ POLL_ERR, /* I/O error. */
+# define POLL_ERR POLL_ERR
+ POLL_PRI, /* High priority input available. */
+# define POLL_PRI POLL_PRI
+ POLL_HUP /* Device disconnected. */
+# define POLL_HUP POLL_HUP
+};
+
+# undef __need_siginfo_t
+#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
+
+
+#if (defined _SIGNAL_H || defined __need_sigevent_t) \
+ && !defined __have_sigevent_t
+# define __have_sigevent_t 1
+
+/* Structure to transport application-defined values with signals. */
+# define __SIGEV_MAX_SIZE 64
+# if __WORDSIZE == 64
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4)
+# else
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 3)
+# endif
+
+typedef struct sigevent
+ {
+ sigval_t sigev_value;
+ int sigev_signo;
+ int sigev_notify;
+
+ union
+ {
+ int _pad[__SIGEV_PAD_SIZE];
+
+ struct
+ {
+ void (*_function) (sigval_t); /* Function to start. */
+ void *_attribute; /* Really pthread_attr_t. */
+ } _sigev_thread;
+ } _sigev_un;
+ } sigevent_t;
+
+/* POSIX names to access some of the members. */
+# define sigev_notify_function _sigev_un._sigev_thread._function
+# define sigev_notify_attributes _sigev_un._sigev_thread._attribute
+
+/* `sigev_notify' values. */
+enum
+{
+ SIGEV_SIGNAL = 0, /* Notify via signal. */
+# define SIGEV_SIGNAL SIGEV_SIGNAL
+ SIGEV_NONE, /* Other notification: meaningless. */
+# define SIGEV_NONE SIGEV_NONE
+ SIGEV_THREAD, /* Deliver via thread creation. */
+# define SIGEV_THREAD SIGEV_THREAD
+
+ SIGEV_THREAD_ID = 4 /* Send signal to specific thread. */
+#define SIGEV_THREAD_ID SIGEV_THREAD_ID
+};
+
+#endif /* have _SIGNAL_H. */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/stat.h b/libc/sysdeps/unix/sysv/linux/s390/bits/stat.h
new file mode 100644
index 000000000..c8ff532d4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/stat.h
@@ -0,0 +1,256 @@
+/* Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+/* Versions of the `struct stat' data structure. */
+# define _STAT_VER_KERNEL 0
+# define _STAT_VER_LINUX 1
+# define _STAT_VER _STAT_VER_LINUX
+
+/* Versions of the `xmknod' interface. */
+#define _MKNOD_VER_LINUX 0
+#else
+/* Versions of the `struct stat' data structure. */
+# define _STAT_VER_LINUX_OLD 1
+# define _STAT_VER_KERNEL 1
+# define _STAT_VER_SVR4 2
+# define _STAT_VER_LINUX 3
+# define _STAT_VER _STAT_VER_LINUX
+
+/* Versions of the `xmknod' interface. */
+# define _MKNOD_VER_LINUX 1
+# define _MKNOD_VER_SVR4 2
+# define _MKNOD_VER _MKNOD_VER_LINUX
+#endif
+
+#if __WORDSIZE == 64
+struct stat
+ {
+ __dev_t st_dev; /* Device. */
+ __ino_t st_ino; /* File serial number. */
+ __nlink_t st_nlink; /* Link count. */
+ __mode_t st_mode; /* File mode. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ int pad0;
+ __dev_t st_rdev; /* Device number, if device. */
+ __off_t st_size; /* Size of file, in bytes. */
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ __blkcnt_t st_blocks; /* Nr. 512-byte blocks allocated. */
+ long int __unused[3];
+ };
+#else
+struct stat
+ {
+ __dev_t st_dev; /* Device. */
+ unsigned int __pad1;
+# ifndef __USE_FILE_OFFSET64
+ __ino_t st_ino; /* File serial number. */
+# else
+ __ino_t __st_ino; /* 32bit file serial number. */
+# endif
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned int __pad2;
+# ifndef __USE_FILE_OFFSET64
+ __off_t st_size; /* Size of file, in bytes. */
+# else
+ __off64_t st_size; /* Size of file, in bytes. */
+# endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+# ifndef __USE_FILE_OFFSET64
+ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
+# else
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+# endif
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+# ifndef __USE_FILE_OFFSET64
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+# else
+ __ino64_t st_ino; /* File serial number. */
+# endif
+ };
+#endif
+
+#ifdef __USE_LARGEFILE64
+# if __WORDSIZE == 64
+/* Note stat64 is the same shape as stat. */
+struct stat64
+ {
+ __dev_t st_dev; /* Device. */
+ __ino64_t st_ino; /* File serial number. */
+ __nlink_t st_nlink; /* Link count. */
+ __mode_t st_mode; /* File mode. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ int pad0;
+ __dev_t st_rdev; /* Device number, if device. */
+ __off_t st_size; /* Size of file, in bytes. */
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */
+ long int __unused[3];
+ };
+# else
+struct stat64
+ {
+ __dev_t st_dev; /* Device. */
+ unsigned int __pad1;
+
+ __ino_t __st_ino; /* 32bit file serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned int __pad2;
+ __off64_t st_size; /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+ __ino64_t st_ino; /* File serial number. */
+ };
+# endif
+#endif
+
+/* Tell code we have these members. */
+#define _STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+/* Nanosecond resolution time values are supported. */
+#define _STATBUF_ST_NSEC
+
+/* Encoding of the file mode. */
+
+#define __S_IFMT 0170000 /* These bits determine file type. */
+
+/* File types. */
+#define __S_IFDIR 0040000 /* Directory. */
+#define __S_IFCHR 0020000 /* Character device. */
+#define __S_IFBLK 0060000 /* Block device. */
+#define __S_IFREG 0100000 /* Regular file. */
+#define __S_IFIFO 0010000 /* FIFO. */
+#define __S_IFLNK 0120000 /* Symbolic link. */
+#define __S_IFSOCK 0140000 /* Socket. */
+
+/* POSIX.1b objects. Note that these macros always evaluate to zero. But
+ they do it by enforcing the correct use of the macros. */
+#define __S_TYPEISMQ(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
+
+/* Protection bits. */
+
+#define __S_ISUID 04000 /* Set user ID on execution. */
+#define __S_ISGID 02000 /* Set group ID on execution. */
+#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
+#define __S_IREAD 0400 /* Read by owner. */
+#define __S_IWRITE 0200 /* Write by owner. */
+#define __S_IEXEC 0100 /* Execute by owner. */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/statfs.h b/libc/sysdeps/unix/sysv/linux/s390/bits/statfs.h
new file mode 100644
index 000000000..d838e6bf4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/statfs.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 1997, 1998, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STATFS_H
+# error "Never include <bits/statfs.h> directly; use <sys/statfs.h> instead."
+#endif
+
+#include <bits/types.h> /* for __fsid_t and __fsblkcnt_t. */
+
+struct statfs
+ {
+ int f_type;
+ int f_bsize;
+#ifndef __USE_FILE_OFFSET64
+ __fsblkcnt_t f_blocks;
+ __fsblkcnt_t f_bfree;
+ __fsblkcnt_t f_bavail;
+ __fsfilcnt_t f_files;
+ __fsfilcnt_t f_ffree;
+#else
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsfilcnt64_t f_files;
+ __fsfilcnt64_t f_ffree;
+#endif
+ __fsid_t f_fsid;
+ int f_namelen;
+ int f_frsize;
+ int f_spare[5];
+ };
+
+#ifdef __USE_LARGEFILE64
+struct statfs64
+ {
+ int f_type;
+ int f_bsize;
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsfilcnt64_t f_files;
+ __fsfilcnt64_t f_ffree;
+ __fsid_t f_fsid;
+ int f_namelen;
+ int f_frsize;
+ int f_spare[5];
+ };
+#endif
+
+/* Tell code we have this member. */
+#define _STATFS_F_NAMELEN
+#define _STATFS_F_FRSIZE
diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h b/libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h
new file mode 100644
index 000000000..2d9cd8779
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h
@@ -0,0 +1,72 @@
+/* bits/typesizes.h -- underlying types for *_t. Linux/s390 version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_TYPES_H
+# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef _BITS_TYPESIZES_H
+#define _BITS_TYPESIZES_H 1
+
+/* See <bits/types.h> for the meaning of these macros. This file exists so
+ that <bits/types.h> need not vary across different GNU platforms. */
+
+#define __DEV_T_TYPE __UQUAD_TYPE
+#define __UID_T_TYPE __U32_TYPE
+#define __GID_T_TYPE __U32_TYPE
+#define __INO_T_TYPE __ULONGWORD_TYPE
+#define __INO64_T_TYPE __UQUAD_TYPE
+#define __MODE_T_TYPE __U32_TYPE
+#define __NLINK_T_TYPE __UWORD_TYPE
+#define __OFF_T_TYPE __SLONGWORD_TYPE
+#define __OFF64_T_TYPE __SQUAD_TYPE
+#define __PID_T_TYPE __S32_TYPE
+#define __RLIM_T_TYPE __ULONGWORD_TYPE
+#define __RLIM64_T_TYPE __UQUAD_TYPE
+#define __BLKCNT_T_TYPE __SLONGWORD_TYPE
+#define __BLKCNT64_T_TYPE __SQUAD_TYPE
+#define __FSBLKCNT_T_TYPE __ULONGWORD_TYPE
+#define __FSBLKCNT64_T_TYPE __UQUAD_TYPE
+#define __FSFILCNT_T_TYPE __ULONGWORD_TYPE
+#define __FSFILCNT64_T_TYPE __UQUAD_TYPE
+#define __ID_T_TYPE __U32_TYPE
+#define __CLOCK_T_TYPE __SLONGWORD_TYPE
+#define __TIME_T_TYPE __SLONGWORD_TYPE
+#define __USECONDS_T_TYPE __U32_TYPE
+#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
+#define __DADDR_T_TYPE __S32_TYPE
+#define __SWBLK_T_TYPE __SLONGWORD_TYPE
+#define __KEY_T_TYPE __S32_TYPE
+#define __CLOCKID_T_TYPE __S32_TYPE
+#define __TIMER_T_TYPE void *
+#define __BLKSIZE_T_TYPE __SLONGWORD_TYPE
+#define __FSID_T_TYPE struct { int __val[2]; }
+#if defined __GNUC__ && __GNUC__ <= 2
+/* Compatibility with g++ 2.95.x. */
+#define __SSIZE_T_TYPE __SWORD_TYPE
+#else
+/* size_t is unsigned long int on s390 -m31. */
+#define __SSIZE_T_TYPE __SLONGWORD_TYPE
+#endif
+
+/* Number of descriptors that can fit in an `fd_set'. */
+#define __FD_SETSIZE 1024
+
+
+#endif /* bits/typesizes.h */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/brk.c b/libc/sysdeps/unix/sysv/linux/s390/brk.c
new file mode 100644
index 000000000..ae6af2178
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/brk.c
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sysdep.h>
+
+void *__curbrk = 0;
+
+/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt
+ to work around different old braindamage in the old Linux/x86 ELF
+ dynamic linker. Sigh. */
+weak_alias (__curbrk, ___brk_addr)
+
+int
+__brk (void *addr)
+{
+ void *newbrk;
+
+ {
+ register void *__addr asm("2") = addr;
+
+ asm ("svc %b1\n\t" /* call sys_brk */
+ : "=d" (__addr)
+ : "I" (SYS_ify(brk)), "r" (__addr)
+ : "cc", "memory" );
+ newbrk = __addr;
+ }
+ __curbrk = newbrk;
+
+ if (newbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+weak_alias (__brk, brk)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/dl-cache.h b/libc/sysdeps/unix/sysv/linux/s390/dl-cache.h
new file mode 100644
index 000000000..766bba426
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/dl-cache.h
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/sparc/dl-cache.h>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/fpu/Implies b/libc/sysdeps/unix/sysv/linux/s390/fpu/Implies
new file mode 100644
index 000000000..3a8e22598
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/fpu/Implies
@@ -0,0 +1,2 @@
+# Override ldbl-opt with s390 specific routines.
+s390/fpu
diff --git a/libc/sysdeps/unix/sysv/linux/s390/ldconfig.h b/libc/sysdeps/unix/sysv/linux/s390/ldconfig.h
new file mode 100644
index 000000000..4a472671b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/ldconfig.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/ldconfig.h>
+
+#define SYSDEP_KNOWN_INTERPRETER_NAMES \
+ { "/lib/ld.so.1", FLAG_ELF_LIBC6 }, \
+ { "/lib/ld64.so.1", FLAG_ELF_LIBC6 },
+#define SYSDEP_KNOWN_LIBRARY_NAMES \
+ { "libc.so.6", FLAG_ELF_LIBC6 }, \
+ { "libm.so.6", FLAG_ELF_LIBC6 },
diff --git a/libc/sysdeps/unix/sysv/linux/s390/ldd-rewrite.sed b/libc/sysdeps/unix/sysv/linux/s390/ldd-rewrite.sed
new file mode 100644
index 000000000..6b4f1bfca
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/ldd-rewrite.sed
@@ -0,0 +1,15 @@
+/LD_TRACE_LOADED_OBJECTS=1/a\
+add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out"
+
+# ldd is generated from elf/ldd.bash.in with the name
+# of ld.so as generated in Makeconfig
+
+# that name is replaced by a pair referring to both
+# the 32bit and 64bit dynamic linker.
+
+# /lib(64|)/*(64|).so* is replaced with /lib/*.so* and /lib/*64.so*
+# this works for /lib64/ld64.so.x and /lib/ld.so.x as input
+s_lib64_lib_
+s_64\.so_\.so_
+s_^RTLDLIST=\(.*lib\)\(/[^/]*\)\(\.so\.[0-9.]*\)[[:blank:]]*$_RTLDLIST="\1\2\3 \1\264\3"_
+
diff --git a/libc/sysdeps/unix/sysv/linux/s390/nldbl-abi.h b/libc/sysdeps/unix/sysv/linux/s390/nldbl-abi.h
new file mode 100644
index 000000000..bd985cc59
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/nldbl-abi.h
@@ -0,0 +1,8 @@
+/* ABI version for long double switch.
+ This is used by the Versions and math_ldbl_opt.h files in
+ sysdeps/ieee754/ldbl-opt/. It gives the ABI version where
+ long double == double was replaced with proper long double
+ for libm *l functions and libc functions using long double. */
+
+#define NLDBL_VERSION GLIBC_2.4
+#define LONG_DOUBLE_COMPAT_VERSION GLIBC_2_4
diff --git a/libc/sysdeps/unix/sysv/linux/s390/readelflib.c b/libc/sysdeps/unix/sysv/linux/s390/readelflib.c
new file mode 100644
index 000000000..2782bc1e0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/readelflib.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+int process_elf32_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+int process_elf64_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+
+/* Returns 0 if everything is ok, != 0 in case of error. */
+int
+process_elf_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname, void *file_contents,
+ size_t file_length)
+{
+ ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
+ int ret;
+
+ if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+ return process_elf32_file (file_name, lib, flag, osversion, soname,
+ file_contents, file_length);
+ else
+ {
+ ret = process_elf64_file (file_name, lib, flag, osversion, soname,
+ file_contents, file_length);
+ /* S/390 64bit libraries are always libc.so.6+. */
+ if (!ret)
+ *flag = FLAG_S390_LIB64|FLAG_ELF_LIBC6;
+ return ret;
+ }
+}
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf32_file
+#define __ELF_NATIVE_CLASS 32
+#include "elf/readelflib.c"
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf64_file
+#define __ELF_NATIVE_CLASS 64
+#include "elf/readelflib.c"
diff --git a/libc/sysdeps/unix/sysv/linux/s390/rt-sysdep.S b/libc/sysdeps/unix/sysv/linux/s390/rt-sysdep.S
new file mode 100644
index 000000000..f966bf1e5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/rt-sysdep.S
@@ -0,0 +1 @@
+#include <sysdep.S>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/Makefile b/libc/sysdeps/unix/sysv/linux/s390/s390-32/Makefile
new file mode 100644
index 000000000..359c863c0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/Makefile
@@ -0,0 +1,15 @@
+ifeq ($(subdir),misc)
+sysdep_headers += sys/elf.h
+endif
+
+ifeq ($(subdir),resource)
+sysdep_routines += oldgetrlimit64
+endif
+
+ifeq ($(subdir),elf)
+ifeq (yes,$(build-shared))
+# This is needed to support g++ v2 and v3.
+sysdep_routines += framestate
+shared-only-routines += framestate
+endif
+endif
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/Versions b/libc/sysdeps/unix/sysv/linux/s390/s390-32/Versions
new file mode 100644
index 000000000..8d6a660cb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/Versions
@@ -0,0 +1,29 @@
+libc {
+ GLIBC_2.0 {
+ # Exception handling support functions from libgcc
+ __register_frame; __register_frame_table; __deregister_frame;
+ __frame_state_for; __register_frame_info_table;
+ }
+ GLIBC_2.2 {
+ # functions used in other libraries
+ __xstat64; __fxstat64; __lxstat64;
+
+ # a*
+ alphasort64;
+
+ # New rlimit interface
+ getrlimit; setrlimit; getrlimit64;
+
+ # r*
+ readdir64; readdir64_r;
+
+ # s*
+ scandir64;
+
+ # v*
+ versionsort64;
+ }
+ GLIBC_2.3.3 {
+ posix_fadvise64; posix_fallocate64;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/alphasort64.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/alphasort64.c
new file mode 100644
index 000000000..0b5ae47d2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/alphasort64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/alphasort64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/chown.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/chown.c
new file mode 100644
index 000000000..5909ba8a4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/chown.c
@@ -0,0 +1,120 @@
+/* Copyright (C) 2000,2001,2002,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <shlib-compat.h>
+#include <bp-checks.h>
+
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+/*
+ In Linux 2.1.x the chown functions have been changed. A new function lchown
+ was introduced. The new chown now follows symlinks - the old chown and the
+ new lchown do not follow symlinks.
+ The new lchown function has the same number as the old chown had and the
+ new chown has a new number. When compiling with headers from Linux > 2.1.8x
+ it's impossible to run this libc with older kernels. In these cases libc
+ has therefore to route calls to chown to the old chown function.
+*/
+
+/* Running under Linux > 2.1.80. */
+
+#ifdef __NR_chown32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif /* __NR_chown32 */
+
+int
+__real_chown (const char *file, uid_t owner, gid_t group)
+{
+#if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (chown32, 3, CHECK_STRING (file), owner, group);
+#else
+ static int __libc_old_chown;
+ int result;
+
+ if (!__libc_old_chown)
+ {
+ int saved_errno = errno;
+# ifdef __NR_chown32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+ int saved_errno = errno;
+
+ result = INLINE_SYSCALL (chown32, 3, CHECK_STRING (file), owner, group);
+ if (result == 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_chown32 */
+ if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
+ || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ result = INLINE_SYSCALL (chown, 3, CHECK_STRING (file), owner, group);
+
+ if (result >= 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_old_chown = 1;
+ }
+
+ return __lchown (file, owner, group);
+#endif
+}
+
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+/* Compiling for compatibiity. */
+int
+attribute_compat_text_section
+__chown_is_lchown (const char *file, uid_t owner, gid_t group)
+{
+ return __lchown (file, owner, group);
+}
+#endif
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+strong_alias (__chown_is_lchown, _chown_is_lchown)
+compat_symbol (libc, __chown_is_lchown, __chown, GLIBC_2_0);
+compat_symbol (libc, _chown_is_lchown, chown, GLIBC_2_0);
+
+strong_alias (__real_chown, _real_chown)
+versioned_symbol (libc, __real_chown, __chown, GLIBC_2_1);
+versioned_symbol (libc, _real_chown, chown, GLIBC_2_1);
+libc_hidden_ver (__real_chown, __chown)
+#else
+strong_alias (__real_chown, __chown)
+libc_hidden_def (__chown)
+weak_alias (__real_chown, chown)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/clone.S b/libc/sysdeps/unix/sysv/linux/s390/s390-32/clone.S
new file mode 100644
index 000000000..70f695a95
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/clone.S
@@ -0,0 +1,76 @@
+/* Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* clone is even more special than fork as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#include <sysdep.h>
+#include <tls.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+/* int __clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+ pid_t *parent_tid, void *tls, pid_t *child_tid); */
+/* sys_clone (void *child_stack, unsigned long flags,
+ pid_t *parent_tid, pid_t *child_tid, void *tls); */
+
+ .text
+ENTRY(__clone)
+ st %r6,24(%r15) /* store %r6 to save area */
+ cfi_offset (%r6, -72)
+ lr %r0,%r5 /* move *arg out of the way */
+ ltr %r1,%r2 /* check fn and move to %r1 */
+ jz error /* no NULL function pointers */
+ ltr %r2,%r3 /* check child_stack and move to %r2 */
+ jz error /* no NULL stack pointers */
+ lr %r3,%r4 /* move flags to %r3 */
+ lr %r4,%r6 /* move parent_tid to %r4 */
+ l %r5,100(%r15) /* load child_tid from stack */
+ l %r6,96(%r15) /* load tls from stack */
+ svc SYS_ify(clone)
+ ltr %r2,%r2 /* check return code */
+ jz thread_start
+ l %r6,24(%r15) /* restore %r6 */
+ jm SYSCALL_ERROR_LABEL
+ br %r14
+error:
+ lhi %r2,-EINVAL
+ j SYSCALL_ERROR_LABEL
+PSEUDO_END (__clone)
+
+thread_start:
+#ifdef RESET_PID
+ tmh %r3,1 /* CLONE_THREAD == 0x00010000 */
+ jne 1f
+ lhi %r2,-1
+ tml %r3,256 /* CLONE_VM == 0x00000100 */
+ jne 2f
+ svc SYS_ify(getpid)
+2: ear %r3,%a0
+ st %r2,PID(%r3)
+ st %r2,TID(%r3)
+1:
+#endif
+ /* fn is in gpr 1, arg in gpr 0 */
+ lr %r2,%r0 /* set first parameter to void *arg */
+ ahi %r15,-96 /* make room on the stack for the save area */
+ xc 0(4,%r15),0(%r15)
+ basr %r14,%r1 /* jump to fn */
+ DO_CALL (exit, 1)
+weak_alias (__clone, clone)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/fchown.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/fchown.c
new file mode 100644
index 000000000..3a69ecc9e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/fchown.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fchown.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c
new file mode 100644
index 000000000..abc06b07d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c
@@ -0,0 +1,159 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <shlib-compat.h>
+#include <bp-checks.h>
+
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+/*
+ In Linux 2.1.x the chown functions have been changed. A new function lchown
+ was introduced. The new chown now follows symlinks - the old chown and the
+ new lchown do not follow symlinks.
+ The new lchown function has the same number as the old chown had and the
+ new chown has a new number. When compiling with headers from Linux > 2.1.8x
+ it's impossible to run this libc with older kernels. In these cases libc
+ has therefore to route calls to chown to the old chown function.
+*/
+
+/* Running under Linux > 2.1.80. */
+
+#ifdef __NR_chown32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif /* __NR_chown32 */
+
+int
+fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
+{
+ int result;
+
+#ifdef __NR_fchownat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INLINE_SYSCALL (fchownat, 5, fd, file, owner, group, flag);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ if (flag & ~AT_SYMLINK_NOFOLLOW)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+# if __ASSUME_32BITUIDS > 0
+ result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
+ group);
+# else
+ static int __libc_old_chown;
+
+# ifdef __NR_chown32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lchown32, err, 3, CHECK_STRING (file),
+ owner, group);
+ else
+ result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file),
+ owner, group);
+
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return result;
+ if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ goto fail;
+
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_chown32 */
+ if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
+ || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (!__libc_old_chown && (flag & AT_SYMLINK_NOFOLLOW) == 0)
+ {
+ result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner,
+ group);
+
+ if (!INTERNAL_SYSCALL_ERROR_P (result, err))
+ return result;
+ if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ goto fail;
+
+ __libc_old_chown = 1;
+ }
+
+ result = INTERNAL_SYSCALL (lchown, err, 3, CHECK_STRING (file), owner,
+ group);
+# endif
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ {
+ fail:
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
+ result = -1;
+ }
+
+ return result;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/fcntl.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/fcntl.c
new file mode 100644
index 000000000..ea951bc4f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/fcntl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fcntl.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/fxstat.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/fxstat.c
new file mode 100644
index 000000000..4f219f0b9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/fxstat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fxstat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/fxstatat.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/fxstatat.c
new file mode 100644
index 000000000..0f8b3135d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/fxstatat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fxstatat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S
new file mode 100644
index 000000000..3b38d1948
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S
@@ -0,0 +1,75 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <features.h>
+
+#include "ucontext_i.h"
+
+/* __getcontext (const ucontext_t *ucp)
+
+ Saves the machine context in UCP such that when it is activated,
+ it appears as if __getcontext() returned again.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to save anything
+ other than the PRESERVED state. */
+
+ENTRY(__getcontext)
+ lr %r5,%r2
+
+ /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */
+ la %r2,SIG_BLOCK
+ slr %r3,%r3
+ la %r4,SC_MASK(%r5)
+ svc SYS_ify(rt_sigprocmask)
+
+ /* Store fpu context. */
+ stfpc SC_FPC(%r5)
+ std %f0,SC_FPRS(%r5)
+ std %f1,SC_FPRS+8(%r5)
+ std %f2,SC_FPRS+16(%r5)
+ std %f3,SC_FPRS+24(%r5)
+ std %f4,SC_FPRS+32(%r5)
+ std %f5,SC_FPRS+40(%r5)
+ std %f6,SC_FPRS+48(%r5)
+ std %f7,SC_FPRS+56(%r5)
+ std %f8,SC_FPRS+64(%r5)
+ std %f9,SC_FPRS+72(%r5)
+ std %f10,SC_FPRS+80(%r5)
+ std %f11,SC_FPRS+88(%r5)
+ std %f12,SC_FPRS+96(%r5)
+ std %f13,SC_FPRS+104(%r5)
+ std %f14,SC_FPRS+112(%r5)
+ std %f15,SC_FPRS+120(%r5)
+
+ /* Set __getcontext return value to 0. */
+ slr %r2,%r2
+
+ /* Store access registers. */
+ stam %a0,%a15,SC_ACRS(%r5)
+
+ /* Store general purpose registers. */
+ stm %r0,%r15,SC_GPRS(%r5)
+
+ /* Return. */
+ br %r14
+END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/getdents64.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getdents64.c
new file mode 100644
index 000000000..0c75fb5a0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getdents64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getdents64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/getegid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getegid.c
new file mode 100644
index 000000000..37b4b4a53
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getegid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getegid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/geteuid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/geteuid.c
new file mode 100644
index 000000000..ebcb555b5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/geteuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/geteuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/getgid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getgid.c
new file mode 100644
index 000000000..0a4d6061f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/getgroups.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getgroups.c
new file mode 100644
index 000000000..20a716610
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getgroups.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getgroups.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/getresgid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getresgid.c
new file mode 100644
index 000000000..b703a414c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getresgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getresgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/getresuid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getresuid.c
new file mode 100644
index 000000000..0b14cefe3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getresuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getresuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/getrlimit.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getrlimit.c
new file mode 100644
index 000000000..fc06dbd64
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getrlimit.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getrlimit.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/getrlimit64.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getrlimit64.c
new file mode 100644
index 000000000..fef018f47
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getrlimit64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getrlimit64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/getuid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getuid.c
new file mode 100644
index 000000000..d682c79a4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/lchown.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/lchown.c
new file mode 100644
index 000000000..1e64a0ef7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/lchown.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 2000, 2001, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+# ifdef __NR_lchown32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+# endif /* __NR_lchown32 */
+
+int
+__lchown (const char *file, uid_t owner, gid_t group)
+{
+# if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (lchown32, 3, CHECK_STRING (file), owner, group);
+# else
+# ifdef __NR_lchown32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+ int saved_errno = errno;
+
+ result = INLINE_SYSCALL (lchown32, 3, CHECK_STRING (file), owner, group);
+ if (result == 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_lchown32 */
+
+ if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
+ || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return INLINE_SYSCALL (lchown, 3, CHECK_STRING (file), owner, group);
+# endif
+}
+
+weak_alias (__lchown, lchown)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/lockf64.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/lockf64.c
new file mode 100644
index 000000000..a88f5a784
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/lockf64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/lockf64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/lxstat.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/lxstat.c
new file mode 100644
index 000000000..0efa0aea4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/lxstat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/lxstat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c
new file mode 100644
index 000000000..29c8640e9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c
@@ -0,0 +1,101 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <libintl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+
+/* This implementation can handle any ARGC value but only
+ normal integer type parameters. Parameters of type float,
+ double, complex and structure with sizes 0, 2, 4 or 8
+ won't work.
+ makecontext sets up a stack and the registers for the
+ context. The stack looks like this:
+ size offset
+ %r15 -> +-----------------------+
+ 4 | back chain (zero) | 0
+ 4 | reserved | 4
+ 88 | save area for (*func) | 8
+ +-----------------------+
+ n | overflow parameters | 96
+ +-----------------------+
+ 8 | trampoline | 96+n
+ +-----------------------+
+ The registers are set up like this:
+ %r2-%r6: parameters 1 to 5
+ %r7 : (*func) pointer
+ %r8 : uc_link from ucontext structure
+ %r9 : address of setcontext
+ %r14 : return address to uc_link trampoline
+ %r15 : stack pointer.
+
+ The trampoline looks like this:
+ basr %r14,%r7
+ lr %r2,%r8
+ br %r9. */
+
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+ unsigned long *sp;
+ va_list ap;
+ int i;
+
+ sp = (long *) (((long) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & -8L);
+
+ /* Setup the trampoline. */
+ *--sp = 0x07f90000;
+ *--sp = 0x0de71828;
+
+ /* Set the return address to trampoline. */
+ ucp->uc_mcontext.gregs[14] = (long) sp;
+
+ /* Set register parameters. */
+ va_start (ap, argc);
+ for (i = 0; (i < argc) && (i < 5); i++)
+ ucp->uc_mcontext.gregs[2+i] = va_arg (ap, long);
+
+ /* The remaining arguments go to the overflow area. */
+ if (argc > 5) {
+ sp -= argc - 5;
+ for (i = 5; i < argc; i++)
+ sp[i] = va_arg(ap, long);
+ }
+ va_end (ap);
+
+ /* Make room for the save area and set the backchain. */
+ sp -= 24;
+ *sp = 0;
+
+ /* Pass (*func) to __start_context in %r7. */
+ ucp->uc_mcontext.gregs[7] = (long) func;
+
+ /* Pass ucp->uc_link to __start_context in %r8. */
+ ucp->uc_mcontext.gregs[8] = (long) ucp->uc_link;
+
+ /* Pass address of setcontext in %r9. */
+ ucp->uc_mcontext.gregs[9] = (long) &setcontext;
+
+ /* Set stack pointer. */
+ ucp->uc_mcontext.gregs[15] = (long) sp;
+}
+
+weak_alias (__makecontext, makecontext)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S b/libc/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S
new file mode 100644
index 000000000..c0d7cd459
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S
@@ -0,0 +1,84 @@
+/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#define EINVAL 22
+
+ .text
+ENTRY(__mmap)
+ /* Save registers and setup stack frame. */
+ stm %r6,%r15,24(%r15)
+ cfi_offset (%r15, -36)
+ cfi_offset (%r14, -40)
+ cfi_offset (%r13, -44)
+ cfi_offset (%r12, -48)
+ cfi_offset (%r11, -52)
+ cfi_offset (%r10, -56)
+ cfi_offset (%r9, -60)
+ cfi_offset (%r8, -64)
+ cfi_offset (%r7, -68)
+ cfi_offset (%r6, -72)
+ lr %r1,%r15
+ ahi %r15,-120 /* buy stack space */
+ cfi_adjust_cfa_offset (120)
+ st %r1,0(%r15) /* store back chain */
+
+ /* Store parameters on stack, because old_mmap/mmap2
+ * take only one parameter: a pointer to the parameter area
+ */
+ st %r6,0x70(%r15) /* Store 'fd'. */
+ st %r5,0x6C(%r15) /* Store 'flags'. */
+ st %r4,0x68(%r15) /* Store 'prot'. */
+ st %r3,0x64(%r15) /* Store 'length'. */
+ st %r2,0x60(%r15) /* Store 'start'. */
+ l %r1,216(%r15) /* Load offset. */
+
+#ifdef __ASSUME_MMAP2_SYSCALL
+ /* I don't think it is worthwhile trying to use mmap2 whenever
+ * it is available. Only use it when we are sure the syscall
+ * exists. */
+ tml %r1,0x0fff /* Offset page aligned ? */
+ lhi %r2,-EINVAL
+ jnz 1f /* No -> EINVAL. */
+ srl %r1,12 /* mmap2 takes the offset in pages. */
+ st %r1,0x74(%r15) /* Store page offset. */
+ la %r2,0x60(%r15) /* Load address of parameter list. */
+ svc SYS_ify(mmap2) /* Do the system call trap. */
+#else
+ st %r1,0x74(%r15) /* Store offset unmodified. */
+ la %r2,0x60(%r15) /* Load address of parameter list. */
+ svc SYS_ify(mmap) /* Do the system call trap. */
+#endif
+
+1: l %r15,0(%r15) /* Load back chain. */
+ cfi_adjust_cfa_offset (-120)
+ lm %r6,%r15,24(%r15) /* Load registers. */
+
+ /* check gpr 2 for error */
+ lhi %r0,-4096
+ clr %r2,%r0
+ jnl SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+ br %r14
+
+PSEUDO_END (__mmap)
+
+weak_alias (__mmap, mmap)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S b/libc/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S
new file mode 100644
index 000000000..aba4ac34e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S
@@ -0,0 +1,113 @@
+/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#define EINVAL 22
+#define ENOSYS 38
+
+ .text
+ENTRY(__mmap64)
+ /* Save registers and setup stack frame. */
+ stm %r6,%r15,24(%r15)
+ cfi_offset (%r15, -36)
+ cfi_offset (%r14, -40)
+ cfi_offset (%r13, -44)
+ cfi_offset (%r12, -48)
+ cfi_offset (%r11, -52)
+ cfi_offset (%r10, -56)
+ cfi_offset (%r9, -60)
+ cfi_offset (%r8, -64)
+ cfi_offset (%r7, -68)
+ cfi_offset (%r6, -72)
+ lr %r1,%r15
+ ahi %r15,-120 /* Buy stack space. */
+ cfi_adjust_cfa_offset (120)
+ st %r1,0(%r15) /* Store back chain. */
+
+ /* Store parameters on stack, because mmap2 and old_mmap
+ * take only one parameter: a pointer to the parameter area. */
+ st %r6,0x70(%r15) /* Store 'fd'. */
+ st %r5,0x6C(%r15) /* Store 'flags'. */
+ st %r4,0x68(%r15) /* Store 'prot'. */
+ st %r3,0x64(%r15) /* Store 'length'. */
+ st %r2,0x60(%r15) /* Store 'start'. */
+
+#ifdef __NR_mmap2
+ lm %r0,%r1,216(%r15) /* Load 64 bit offset. */
+ tml %r1,0x0fff /* Offset page aligned ? */
+ jnz 2f /* No -> EINVAL. */
+ srdl %r0,12 /* mmap2 takes the offset in pages. */
+ ltr %r0,%r0 /* Offset > 2^44 ? */
+ jnz 2f
+ st %r1,0x74(%r15) /* Store page offset. */
+
+ la %r2,0x60(%r15) /* Load address of parameter list. */
+ svc SYS_ify(mmap2) /* Do the system call trap. */
+
+#ifndef __ASSUME_MMAP2_SYSCALL
+ chi %r2,-ENOSYS
+ je 1f
+#endif
+
+ l %r15,0(%r15) /* Load back chain. */
+ cfi_adjust_cfa_offset (-120)
+ lm %r6,%r15,24(%r15) /* Load registers. */
+
+ /* Check gpr 2 for error. */
+ lhi %r0,-4096
+ clr %r2,%r0
+ jnl SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+ br %r14
+
+#endif
+
+#if !defined __ASSUME_MMAP2_SYSCALL || !defined __NR_mmap2
+1: lm %r0,%r1,216(%r15) /* Load 64 bit offset. */
+ st %r1,0x74(%r15) /* Store lower word of offset. */
+ ltr %r0,%r0 /* Offset > 2^32 ? */
+ jnz 2f
+ alr %r1,%r3 /* Add length to offset. */
+ brc 3,2f /* Carry -> EINVAL. */
+
+ la %r2,0x60(%r15) /* Load address of parameter list. */
+ svc SYS_ify(mmap) /* Do the system call trap. */
+
+ l %r15,0(%r15) /* Load back chain. */
+ lm %r6,%r15,24(%r15) /* Load registers. */
+
+ /* Check gpr 2 for error. */
+ lhi %r0,-4096
+ clr %r2,%r0
+ jnl SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+ br %r14
+#endif
+
+2: lhi %r2,-EINVAL
+ l %r15,0(%r15) /* Load back chain. */
+ lm %r6,%r15,24(%r15) /* Load registers. */
+ j SYSCALL_ERROR_LABEL
+
+PSEUDO_END (__mmap64)
+
+weak_alias (__mmap64, mmap64)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/msgctl.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/msgctl.c
new file mode 100644
index 000000000..9f9b8431a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/msgctl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/msgctl.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/oldgetrlimit64.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/oldgetrlimit64.c
new file mode 100644
index 000000000..4c27e957b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/oldgetrlimit64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c
new file mode 100644
index 000000000..e0fed24af
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/posix_fadvise64.c
@@ -0,0 +1,91 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sysdep.h>
+#include <kernel-features.h>
+
+int __posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise);
+int __posix_fadvise64_l32 (int fd, off64_t offset, size_t len, int advise);
+
+/* Advice the system about the expected behaviour of the application with
+ respect to the file associated with FD. */
+
+struct fadvise64_64_layout
+{
+ int fd;
+ off64_t offset;
+ off64_t len;
+ int advise;
+};
+
+int
+__posix_fadvise64_l64 (int fd, off64_t offset, off64_t len, int advise)
+{
+#ifdef __NR_fadvise64_64
+ struct fadvise64_64_layout parameters;
+ INTERNAL_SYSCALL_DECL (err);
+
+ parameters.fd = fd;
+ parameters.offset = offset;
+ parameters.len = len;
+ parameters.advise = advise;
+ int ret = INTERNAL_SYSCALL (fadvise64_64, err, 1, &parameters);
+ if (!INTERNAL_SYSCALL_ERROR_P (ret, err))
+ return 0;
+# ifndef __ASSUME_FADVISE64_64_SYSCALL
+ if (INTERNAL_SYSCALL_ERRNO (ret, err) != ENOSYS)
+# endif
+ return INTERNAL_SYSCALL_ERRNO (ret, err);
+#endif
+#ifndef __ASSUME_FADVISE64_64_SYSCALL
+# ifdef __NR_fadvise64
+ if (len != (off_t) len)
+ return EOVERFLOW;
+
+ INTERNAL_SYSCALL_DECL (err2);
+ int ret2 = INTERNAL_SYSCALL (fadvise64, err2, 5, fd,
+ __LONG_LONG_PAIR ((long) (offset >> 32),
+ (long) offset),
+ (off_t) len, advise);
+ if (!INTERNAL_SYSCALL_ERROR_P (ret2, err2))
+ return 0;
+ return INTERNAL_SYSCALL_ERRNO (ret2, err2);
+# else
+ return ENOSYS;
+# endif
+#endif
+}
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_2, GLIBC_2_3_3)
+
+int
+attribute_compat_text_section
+__posix_fadvise64_l32 (int fd, off64_t offset, size_t len, int advise)
+{
+ return __posix_fadvise64_l64 (fd, offset, len, advise);
+}
+
+versioned_symbol (libc, __posix_fadvise64_l64, posix_fadvise64, GLIBC_2_3_3);
+compat_symbol (libc, __posix_fadvise64_l32, posix_fadvise64, GLIBC_2_2);
+#else
+strong_alias (__posix_fadvise64_l64, posix_fadvise64);
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h b/libc/sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h
new file mode 100644
index 000000000..d913dbb61
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h
@@ -0,0 +1,27 @@
+/* Low-level statistical profiling support function. Linux/s390 version.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+#include <sigcontextinfo.h>
+
+static void
+profil_counter (int signo, SIGCONTEXT scp)
+{
+ profil_count((void *) ((unsigned long) GET_PC (scp) & 0x7fffffffUL));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/readdir64.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/readdir64.c
new file mode 100644
index 000000000..2ea26dd40
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/readdir64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/readdir64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/readdir64_r.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/readdir64_r.c
new file mode 100644
index 000000000..9f54f897e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/readdir64_r.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/readdir64_r.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/register-dump.h b/libc/sysdeps/unix/sysv/linux/s390/s390-32/register-dump.h
new file mode 100644
index 000000000..2030bfef3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/register-dump.h
@@ -0,0 +1,130 @@
+/* Dump registers.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/uio.h>
+#include <stdio-common/_itoa.h>
+
+/* We will print the register dump in this format:
+
+ GPR0: XXXXXXXX GPR1: XXXXXXXX GPR2: XXXXXXXX GPR3: XXXXXXXX
+ GPR4: XXXXXXXX GPR5: XXXXXXXX GPR6: XXXXXXXX GPR7: XXXXXXXX
+ GPR8: XXXXXXXX GPR9: XXXXXXXX GPRA: XXXXXXXX GPRB: XXXXXXXX
+ GPRC: XXXXXXXX GPRD: XXXXXXXX GPRE: XXXXXXXX GPRF: XXXXXXXX
+
+ PSW.MASK: XXXXXXXX PSW.ADDR: XXXXXXXX
+
+ ST(0) XXXX XXXXXXXXXXXXXXXX ST(1) XXXX XXXXXXXXXXXXXXXX
+ ST(2) XXXX XXXXXXXXXXXXXXXX ST(3) XXXX XXXXXXXXXXXXXXXX
+ ST(4) XXXX XXXXXXXXXXXXXXXX ST(5) XXXX XXXXXXXXXXXXXXXX
+ ST(6) XXXX XXXXXXXXXXXXXXXX ST(7) XXXX XXXXXXXXXXXXXXXX
+
+ */
+
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
+{
+ char *cp = _itoa_word (value, buf + len, 16, 0);
+ while (cp > buf)
+ *--cp = '0';
+}
+
+static void
+register_dump (int fd, struct sigcontext *ctx)
+{
+ char regs[19][8];
+ struct iovec iov[40];
+ size_t nr = 0;
+
+#define ADD_STRING(str) \
+ iov[nr].iov_base = (char *) str; \
+ iov[nr].iov_len = strlen (str); \
+ ++nr
+#define ADD_MEM(str, len) \
+ iov[nr].iov_base = str; \
+ iov[nr].iov_len = len; \
+ ++nr
+
+ /* Generate strings of register contents. */
+ hexvalue (ctx->sregs->regs.gprs[0], regs[0], 8);
+ hexvalue (ctx->sregs->regs.gprs[1], regs[1], 8);
+ hexvalue (ctx->sregs->regs.gprs[2], regs[2], 8);
+ hexvalue (ctx->sregs->regs.gprs[3], regs[3], 8);
+ hexvalue (ctx->sregs->regs.gprs[4], regs[4], 8);
+ hexvalue (ctx->sregs->regs.gprs[5], regs[5], 8);
+ hexvalue (ctx->sregs->regs.gprs[6], regs[6], 8);
+ hexvalue (ctx->sregs->regs.gprs[7], regs[7], 8);
+ hexvalue (ctx->sregs->regs.gprs[8], regs[8], 8);
+ hexvalue (ctx->sregs->regs.gprs[9], regs[9], 8);
+ hexvalue (ctx->sregs->regs.gprs[10], regs[10], 8);
+ hexvalue (ctx->sregs->regs.gprs[11], regs[11], 8);
+ hexvalue (ctx->sregs->regs.gprs[12], regs[12], 8);
+ hexvalue (ctx->sregs->regs.gprs[13], regs[13], 8);
+ hexvalue (ctx->sregs->regs.gprs[14], regs[14], 8);
+ hexvalue (ctx->sregs->regs.gprs[15], regs[15], 8);
+ hexvalue (ctx->sregs->regs.psw.mask, regs[16], 8);
+ hexvalue (ctx->sregs->regs.psw.addr, regs[17], 8);
+
+ /* Generate the output. */
+ ADD_STRING ("Register dump:\n\n GPR0: ");
+ ADD_MEM (regs[0], 8);
+ ADD_STRING (" GPR1: ");
+ ADD_MEM (regs[1], 8);
+ ADD_STRING (" GPR2: ");
+ ADD_MEM (regs[2], 8);
+ ADD_STRING (" GPR3: ");
+ ADD_MEM (regs[3], 8);
+ ADD_STRING ("\n GPR4: ");
+ ADD_MEM (regs[4], 8);
+ ADD_STRING (" GPR5: ");
+ ADD_MEM (regs[5], 8);
+ ADD_STRING (" GPR6: ");
+ ADD_MEM (regs[6], 8);
+ ADD_STRING (" GPR7: ");
+ ADD_MEM (regs[7], 8);
+ ADD_STRING ("\n GPR8: ");
+ ADD_MEM (regs[8], 8);
+ ADD_STRING (" GPR9: ");
+ ADD_MEM (regs[9], 8);
+ ADD_STRING (" GPRA: ");
+ ADD_MEM (regs[10], 8);
+ ADD_STRING (" GPRB: ");
+ ADD_MEM (regs[11], 8);
+ ADD_STRING ("\n GPRC: ");
+ ADD_MEM (regs[12], 8);
+ ADD_STRING (" GPRD: ");
+ ADD_MEM (regs[13], 8);
+ ADD_STRING (" GPRE: ");
+ ADD_MEM (regs[14], 8);
+ ADD_STRING (" GPRF: ");
+ ADD_MEM (regs[15], 8);
+ ADD_STRING ("\n\n PSW.MASK: ");
+ ADD_MEM (regs[16], 8);
+ ADD_STRING (" PSW.ADDR: ");
+ ADD_MEM (regs[17], 8);
+ ADD_STRING (" TRAP: ");
+ ADD_MEM (regs[18], 4);
+ ADD_STRING ("\n");
+
+ /* Write the stuff out. */
+ writev (fd, iov, nr);
+}
+
+
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/scandir64.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/scandir64.c
new file mode 100644
index 000000000..506fd8877
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/scandir64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/scandir64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/semctl.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/semctl.c
new file mode 100644
index 000000000..e9b1a483c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/semctl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/semctl.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S
new file mode 100644
index 000000000..cce8d2973
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S
@@ -0,0 +1,72 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <features.h>
+
+#include "ucontext_i.h"
+
+/* __setcontext (const ucontext_t *ucp)
+
+ Restores the machine context in UCP and thereby resumes execution
+ in that context.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to restore anything
+ other than the PRESERVED state. */
+
+ENTRY(__setcontext)
+ lr %r5,%r2
+
+ /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */
+ la %r2,SIG_BLOCK
+ la %r3,SC_MASK(%r5)
+ slr %r4,%r4
+ svc SYS_ify(rt_sigprocmask)
+
+ /* Load fpu context. */
+ lfpc SC_FPC(%r5)
+ ld %f0,SC_FPRS(%r5)
+ ld %f1,SC_FPRS+8(%r5)
+ ld %f2,SC_FPRS+16(%r5)
+ ld %f3,SC_FPRS+24(%r5)
+ ld %f4,SC_FPRS+32(%r5)
+ ld %f5,SC_FPRS+40(%r5)
+ ld %f6,SC_FPRS+48(%r5)
+ ld %f7,SC_FPRS+56(%r5)
+ ld %f8,SC_FPRS+64(%r5)
+ ld %f9,SC_FPRS+72(%r5)
+ ld %f10,SC_FPRS+80(%r5)
+ ld %f11,SC_FPRS+88(%r5)
+ ld %f12,SC_FPRS+96(%r5)
+ ld %f13,SC_FPRS+104(%r5)
+ ld %f14,SC_FPRS+112(%r5)
+ ld %f15,SC_FPRS+120(%r5)
+
+ /* Don't touch %a0, used for thread purposes. */
+ lam %a1,%a15,SC_ACRS+4(%r5)
+
+ /* Load general purpose registers. */
+ lm %r0,%r15,SC_GPRS(%r5)
+
+ /* Return. */
+ br %r14
+END(__setcontext)
+
+weak_alias (__setcontext, setcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setegid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setegid.c
new file mode 100644
index 000000000..2e3a54c89
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setegid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setegid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/seteuid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/seteuid.c
new file mode 100644
index 000000000..18e41d08c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/seteuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/seteuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setfsgid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setfsgid.c
new file mode 100644
index 000000000..088671256
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setfsgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setfsgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setfsuid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setfsuid.c
new file mode 100644
index 000000000..a9f22eb8a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setfsuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setfsuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setgid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setgid.c
new file mode 100644
index 000000000..377021d9e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setgroups.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setgroups.c
new file mode 100644
index 000000000..0e7086278
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setgroups.c
@@ -0,0 +1,2 @@
+/* We also have to rewrite the kernel gid_t to the user land type. */
+#include <sysdeps/unix/sysv/linux/i386/setgroups.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setregid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setregid.c
new file mode 100644
index 000000000..99c57ad20
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setregid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setregid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setresgid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setresgid.c
new file mode 100644
index 000000000..daca1a483
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setresgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setresgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setresuid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setresuid.c
new file mode 100644
index 000000000..3aeabe9ad
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setresuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setresuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setreuid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setreuid.c
new file mode 100644
index 000000000..8ad61226e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setreuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setreuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setrlimit.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setrlimit.c
new file mode 100644
index 000000000..bfaef74c3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setrlimit.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setrlimit.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setuid.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setuid.c
new file mode 100644
index 000000000..c8fa23e35
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setuid.c
@@ -0,0 +1,2 @@
+#include <sysdeps/unix/sysv/linux/i386/setuid.c>
+
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/shmctl.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/shmctl.c
new file mode 100644
index 000000000..7eac6380d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/shmctl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/shmctl.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/socket.S b/libc/sysdeps/unix/sysv/linux/s390/s390-32/socket.S
new file mode 100644
index 000000000..bc0153324
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/socket.S
@@ -0,0 +1,143 @@
+/* Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep-cancel.h>
+#include <socketcall.h>
+
+/* &%/$&!! preprocessor */
+#define P(a, b) P2(a, b)
+#define P2(a, b) a##b
+
+ .text
+/* The socket-oriented system calls are handled unusally in Linux.
+ They are all gated through the single `socketcall' system call number.
+ `socketcall' takes two arguments: the first is the subcode, specifying
+ which socket function is being called; and the second is a pointer to
+ the arguments to the specific function.
+
+ The .S files for the other calls just #define socket and #include this. */
+
+#ifndef __socket
+#ifndef NO_WEAK_ALIAS
+#define __socket P(__,socket)
+#else
+#define __socket socket
+#endif
+#endif
+
+#ifndef NARGS /* the socket.o object is compiled directly ... */
+#define NARGS 3
+#endif
+
+.globl __socket
+ENTRY(__socket)
+ /* Save registers and setup stack. */
+ stm %r6,%r15,24(%r15) /* save registers */
+ cfi_offset (%r15, -36)
+ cfi_offset (%r14, -40)
+ cfi_offset (%r13, -44)
+ cfi_offset (%r12, -48)
+ cfi_offset (%r11, -52)
+ cfi_offset (%r10, -56)
+ cfi_offset (%r9, -60)
+ cfi_offset (%r8, -64)
+ cfi_offset (%r7, -68)
+ cfi_offset (%r6, -72)
+ lr %r1,%r15
+ l %r0,4(0,%r15) /* load eos */
+ ahi %r15,-120 /* buy stack space */
+ cfi_adjust_cfa_offset (120)
+ st %r1,0(0,%r15) /* store back chain */
+ st %r0,4(0,%r15) /* store eos */
+
+ /* Reorder arguments */
+#if (NARGS >= 6)
+ mvc 0x74(4,%r15),216(%r15) /* move between parameter lists */
+#endif
+#if (NARGS >= 5)
+ st %r6,0x70(0,%r15) /* store into parameter list */
+#endif
+#if (NARGS >= 4)
+ st %r5,0x6C(0,%r15) /* store into parameter list */
+#endif
+#if (NARGS >= 3)
+ st %r4,0x68(0,%r15) /* store into parameter list */
+#endif
+#if (NARGS >= 2)
+ st %r3,0x64(0,%r15) /* store into parameter list */
+ st %r2,0x60(0,%r15)
+#endif
+
+#if defined NEED_CANCELLATION && defined CENABLE
+ SINGLE_THREAD_P (%r4)
+ jne L(socket_cancel)
+#endif
+
+ /* load subcode for socket syscall */
+ lhi %r2,P(SOCKOP_,socket)
+ la %r3,0x60(0,%r15) /* load address of parameter list */
+
+ /* Do the system call trap. */
+ svc SYS_ify(socketcall)
+
+4:
+ l %r15,0(0,%r15) /* load back chain */
+ lm %r6,15,24(%r15) /* load registers */
+
+ /* gpr2 is < 0 if there was an error. */
+ lhi %r0,-125
+ clr %r2,%r0
+ jnl SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+ br %r14
+
+#if defined NEED_CANCELLATION && defined CENABLE
+L(socket_cancel):
+ basr %r13,0
+1: l %r1,2f-1b(%r13)
+ /* call CENABLE. */
+ bas %r14,0(%r13,%r1)
+ lr %r0,%r2
+
+ /* load subcode for socket syscall */
+ lhi %r2,P(SOCKOP_,socket)
+ la %r3,0x60(0,%r15) /* load address of parameter list */
+
+ /* Do the system call trap. */
+ svc SYS_ify(socketcall)
+
+ l %r3,3f-1b(%r13)
+ lr %r12,%r2
+ lr %r2,%r0
+ /* call CDISABLE. */
+ bas %r14,0(%r13,%r3)
+ lr %r2,%r12
+ j 4b
+
+2: .long CENABLE-1b
+3: .long CDISABLE-1b
+#endif
+
+ SYSCALL_ERROR_HANDLER
+END (__socket)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__socket, socket)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S b/libc/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
new file mode 100644
index 000000000..bf70f11cc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
@@ -0,0 +1,108 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <features.h>
+
+#include "ucontext_i.h"
+
+/* __swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
+
+ Saves the machine context in oucp such that when it is activated,
+ it appears as if __swapcontextt() returned again, restores the
+ machine context in ucp and thereby resumes execution in that
+ context.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to save anything
+ other than the PRESERVED state. */
+
+ENTRY(__swapcontext)
+ lr %r1,%r2
+ lr %r5,%r3
+
+ /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */
+ la %r2,SIG_BLOCK
+ slr %r3,%r3
+ la %r4,SC_MASK(%r1)
+ svc SYS_ify(rt_sigprocmask)
+
+ /* Store fpu context. */
+ stfpc SC_FPC(%r1)
+ std %f0,SC_FPRS(%r1)
+ std %f1,SC_FPRS+8(%r1)
+ std %f2,SC_FPRS+16(%r1)
+ std %f3,SC_FPRS+24(%r1)
+ std %f4,SC_FPRS+32(%r1)
+ std %f5,SC_FPRS+40(%r1)
+ std %f6,SC_FPRS+48(%r1)
+ std %f7,SC_FPRS+56(%r1)
+ std %f8,SC_FPRS+64(%r1)
+ std %f9,SC_FPRS+72(%r1)
+ std %f10,SC_FPRS+80(%r1)
+ std %f11,SC_FPRS+88(%r1)
+ std %f12,SC_FPRS+96(%r1)
+ std %f13,SC_FPRS+104(%r1)
+ std %f14,SC_FPRS+112(%r1)
+ std %f15,SC_FPRS+120(%r1)
+
+ /* Set __swapcontext return value to 0. */
+ slr %r2,%r2
+
+ /* Store access registers. */
+ stam %a0,%a15,SC_ACRS(%r1)
+
+ /* Store general purpose registers. */
+ stm %r0,%r15,SC_GPRS(%r1)
+
+ /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */
+ la %r2,SIG_BLOCK
+ la %r3,SC_MASK(%r5)
+ slr %r4,%r4
+ svc SYS_ify(rt_sigprocmask)
+
+ /* Load fpu context. */
+ lfpc SC_FPC(%r5)
+ ld %f0,SC_FPRS(%r5)
+ ld %f1,SC_FPRS+8(%r5)
+ ld %f2,SC_FPRS+16(%r5)
+ ld %f3,SC_FPRS+24(%r5)
+ ld %f4,SC_FPRS+32(%r5)
+ ld %f5,SC_FPRS+40(%r5)
+ ld %f6,SC_FPRS+48(%r5)
+ ld %f7,SC_FPRS+56(%r5)
+ ld %f8,SC_FPRS+64(%r5)
+ ld %f9,SC_FPRS+72(%r5)
+ ld %f10,SC_FPRS+80(%r5)
+ ld %f11,SC_FPRS+88(%r5)
+ ld %f12,SC_FPRS+96(%r5)
+ ld %f13,SC_FPRS+104(%r5)
+ ld %f14,SC_FPRS+112(%r5)
+ ld %f15,SC_FPRS+120(%r5)
+
+ /* Don't touch %a0, used for thread purposes. */
+ lam %a1,%a15,SC_ACRS+4(%r5)
+
+ /* Load general purpose registers. */
+ lm %r0,%r15,SC_GPRS(%r5)
+
+ /* Return. */
+ br %r14
+END(__swapcontext)
+weak_alias (__swapcontext, swapcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/syscall.S b/libc/sysdeps/unix/sysv/linux/s390/s390-32/syscall.S
new file mode 100644
index 000000000..b7e173689
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/syscall.S
@@ -0,0 +1,68 @@
+/* Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* Please consult the file sysdeps/unix/sysv/linux/s390/sysdep.h for
+ more information about the value -4095 used below.*/
+
+ENTRY (syscall)
+ /* Save registers and setup stack. */
+ stm %r6,%r15,24(%r15) /* save registers */
+ cfi_offset (%r15, -36)
+ cfi_offset (%r14, -40)
+ cfi_offset (%r13, -44)
+ cfi_offset (%r12, -48)
+ cfi_offset (%r11, -52)
+ cfi_offset (%r10, -56)
+ cfi_offset (%r9, -60)
+ cfi_offset (%r8, -64)
+ cfi_offset (%r7, -68)
+ cfi_offset (%r6, -72)
+ lr %r1,%r15
+ l %r0,4(0,%r15) /* load eos */
+ ahi %r15,-96 /* buy stack space */
+ cfi_adjust_cfa_offset (96)
+ st %r1,0(0,%r15) /* store back chain */
+ st %r0,4(0,%r15) /* store eos */
+
+ lr %r1,%r2 /* move syscall number */
+ lr %r2,%r3 /* first parameter */
+ lr %r3,%r4 /* second parameter */
+ lr %r4,%r5 /* third parameter */
+ lr %r5,%r6 /* fourth parameter */
+ l %r6,192(%r15) /* fifth parameter */
+ l %r7,196(%r15) /* sixth parameter */
+
+ basr %r8,0
+0: cl %r1,4f-0b(%r8) /* svc number < 256? */
+ jl 2f
+1: svc 0
+ j 3f
+2: ex %r1,1b-0b(%r8) /* lsb of R1 is subsituted as SVC number */
+3: l %r15,0(%r15) /* load back chain */
+ cfi_adjust_cfa_offset (-96)
+ lm %r6,15,24(%r15) /* load registers */
+
+ lhi %r0,-4095
+ clr %r2,%r0 /* check R2 for error */
+ jnl SYSCALL_ERROR_LABEL
+ br %r14 /* return to caller */
+4: .long 256
+PSEUDO_END (syscall)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list b/libc/sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list
new file mode 100644
index 000000000..0e7685730
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list
@@ -0,0 +1,5 @@
+# File name Caller Syscall name Args Strong name Weak names
+
+oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0
+oldsetrlimit EXTRA setrlimit i:ip __old_setrlimit setrlimit@GLIBC_2.0
+vfork - vfork 0 __vfork vfork
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S b/libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S
new file mode 100644
index 000000000..2a1dad069
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S
@@ -0,0 +1,137 @@
+/* Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tls.h>
+
+/* The following code is only used in the shared library when we
+ compile the reentrant version. Otherwise each system call defines
+ each own version. */
+
+/* The syscall stubs jump here when they detect an error. */
+
+#undef CALL_MCOUNT
+#define CALL_MCOUNT
+
+ .text
+ENTRY(__syscall_error)
+#ifndef PIC
+# if USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+ basr %r1,0
+0: l %r1,1f-0b(%r1)
+ ear %r3,%a0
+ lcr %r2,%r2
+ st %r2,0(%r1,%r3)
+ lhi %r2,-1
+ br %r14
+1: .long SYSCALL_ERROR_ERRNO@ntpoff
+# elif !defined _LIBC_REENTRANT
+ basr %r1,0
+0: l %r1,1f-0b(%r1)
+ lcr %r2,%r2
+ st %r2,0(%r1)
+ lhi %r2,-1
+ br %r14
+1: .long errno
+# else
+ stm %r13,%r15,52(%r15)
+ cfi_offset (%r15, -36)
+ cfi_offset (%r14, -40)
+ cfi_offset (%r13, -44)
+ lr %r0,%r15
+ ahi %r15,-96
+ cfi_adjust_cfa_offset (96)
+ lcr %r13,%r2
+ st %r0,0(%r15)
+ basr %r1,0
+0: l %r1,1f-0b(%r1)
+ basr %r14,%r1
+ st %r13,0(%r2)
+ lm %r13,%r15,148(%r15)
+ cfi_adjust_cfa_offset (-96)
+ lhi %r2,-1
+ br %r14
+1: .long __errno_location
+#endif
+#else
+# if RTLD_PRIVATE_ERRNO
+ basr %r1,0
+0: al %r1,1f-0b(%r1)
+ lcr %r2,%r2
+ st %r2,0(%r1)
+ lhi %r2,-1
+ br %r14
+1: .long rtld_errno - 0b
+# elif USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+ basr %r1,0
+0: al %r1,1f-0b(%r1)
+ ear %r3,%a0
+ l %r1,SYSCALL_ERROR_ERRNO@gotntpoff(%r1)
+ lcr %r2,%r2
+ st %r2,0(%r1,%r3)
+ lhi %r2,-1
+ br %r14
+1: .long _GLOBAL_OFFSET_TABLE_-0b
+# elif !defined _LIBC_REENTRANT
+ basr %r1,0
+0: al %r1,1f-0b(%r1)
+ l %r1,errno@GOT(%r1)
+ lcr %r2,%r2
+ st %r2,0(0,%r1)
+ lhi %r2,-1
+ br %r14
+1: .long _GLOBAL_OFFSET_TABLE_-0b
+# else
+ stm %r11,%r15,44(%r15)
+ cfi_offset (%r15, -36)
+ cfi_offset (%r14, -40)
+ cfi_offset (%r13, -44)
+ cfi_offset (%r12, -48)
+ cfi_offset (%r11, -52)
+ lr %r0,%r15
+ ahi %r15,-96
+ cfi_adjust_cfa_offset (96)
+ lcr %r11,%r2
+ st %r0,0(%r15)
+ basr %r13,0
+0: l %r12,1f-0b(%r13)
+ l %r1,2f-0b(%r13)
+ la %r12,0(%r12,%r13)
+ bas %r14,0(%r1,%r13)
+ st %r11,0(%r2)
+ lm %r11,%r15,140(%r15)
+ cfi_adjust_cfa_offset (-96)
+ lhi %r2,-1
+ br %r14
+1: .long _GLOBAL_OFFSET_TABLE_-0b
+2: .long __errno_location@PLT-0b
+# endif
+#endif
+
+END (__syscall_error)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h b/libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
new file mode 100644
index 000000000..b86072bd3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
@@ -0,0 +1,301 @@
+/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINUX_S390_SYSDEP_H
+#define _LINUX_S390_SYSDEP_H
+
+#include <sysdeps/s390/s390-32/sysdep.h>
+#include <sysdeps/unix/sysdep.h>
+#include <dl-sysdep.h> /* For RTLD_PRIVATE_ERRNO. */
+#include <tls.h>
+
+/* For Linux we can use the system call table in the header file
+ /usr/include/asm/unistd.h
+ of the kernel. But these symbols do not follow the SYS_* syntax
+ so we have to redefine the `SYS_ify' macro here. */
+/* in newer 2.1 kernels __NR_syscall is missing so we define it here */
+#define __NR_syscall 0
+
+#undef SYS_ify
+#define SYS_ify(syscall_name) __NR_##syscall_name
+
+#ifdef __ASSEMBLER__
+
+/* Linux uses a negative return value to indicate syscall errors, unlike
+ most Unices, which use the condition codes' carry flag.
+
+ Since version 2.1 the return value of a system call might be negative
+ even if the call succeeded. E.g., the `lseek' system call might return
+ a large offset. Therefore we must not anymore test for < 0, but test
+ for a real error by making sure the value in gpr2 is a real error
+ number. Linus said he will make sure the no syscall returns a value
+ in -1 .. -4095 as a valid result so we can savely test with -4095. */
+
+#undef PSEUDO
+#define PSEUDO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ lhi %r4,-4095 ; \
+ clr %r2,%r4 ; \
+ jnl SYSCALL_ERROR_LABEL
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ SYSCALL_ERROR_HANDLER; \
+ END (name)
+
+#undef PSEUDO_NOERRNO
+#define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args)
+
+#undef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(name) \
+ END (name)
+
+#undef PSEUDO_ERRVAL
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ lcr %r2,%r2
+
+#undef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(name) \
+ END (name)
+
+#ifndef PIC
+# define SYSCALL_ERROR_LABEL 0f
+# define SYSCALL_ERROR_HANDLER \
+0: basr %r1,0; \
+1: l %r1,2f-1b(%r1); \
+ br %r1; \
+2: .long syscall_error
+#else
+# if RTLD_PRIVATE_ERRNO
+# define SYSCALL_ERROR_LABEL 0f
+# define SYSCALL_ERROR_HANDLER \
+0: basr %r1,0; \
+1: al %r1,2f-1b(%r1); \
+ lcr %r2,%r2; \
+ st %r2,0(%r1); \
+ lhi %r2,-1; \
+ br %r14; \
+2: .long rtld_errno-1b
+# elif defined _LIBC_REENTRANT
+# if USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+# define SYSCALL_ERROR_LABEL 0f
+# define SYSCALL_ERROR_HANDLER \
+0: lcr %r0,%r2; \
+ basr %r1,0; \
+1: al %r1,2f-1b(%r1); \
+ l %r1,SYSCALL_ERROR_ERRNO@gotntpoff(%r1); \
+ ear %r2,%a0; \
+ st %r0,0(%r1,%r2); \
+ lhi %r2,-1; \
+ br %r14; \
+2: .long _GLOBAL_OFFSET_TABLE_-1b
+# else
+# define SYSCALL_ERROR_LABEL 0f
+# define SYSCALL_ERROR_HANDLER \
+0: basr %r1,0; \
+1: al %r1,2f-1b(%r1); \
+ br %r1; \
+2: .long syscall_error@plt-1b
+# endif
+# else
+# define SYSCALL_ERROR_LABEL 0f
+# define SYSCALL_ERROR_HANDLER \
+0: basr %r1,0; \
+1: al %r1,2f-1b(%r1); \
+ l %r1,errno@GOT(%r1); \
+ lcr %r2,%r2; \
+ st %r2,0(%r1); \
+ lhi %r2,-1; \
+ br %r14; \
+2: .long _GLOBAL_OFFSET_TABLE_-1b
+# endif /* _LIBC_REENTRANT */
+#endif /* PIC */
+
+/* Linux takes system call arguments in registers:
+
+ syscall number 1 call-clobbered
+ arg 1 2 call-clobbered
+ arg 2 3 call-clobbered
+ arg 3 4 call-clobbered
+ arg 4 5 call-clobbered
+ arg 5 6 call-saved
+ arg 6 7 call-saved
+
+ (Of course a function with say 3 arguments does not have entries for
+ arguments 4 and 5.)
+ For system calls with 6 parameters a stack operation is required
+ to load the 6th parameter to register 7. Call saved register 7 is
+ moved to register 0 and back to avoid an additional stack frame.
+ */
+
+#define DO_CALL(syscall, args) \
+ .if args > 5; \
+ lr %r0,%r7; \
+ l %r7,96(%r15); \
+ .endif; \
+ .if SYS_ify (syscall) < 256; \
+ svc SYS_ify (syscall); \
+ .else; \
+ lhi %r1,SYS_ify (syscall); \
+ svc 0; \
+ .endif; \
+ .if args > 5; \
+ lr %r7,%r0; \
+ .endif
+
+#define ret \
+ br 14
+
+#define ret_NOERRNO \
+ br 14
+
+#define ret_ERRVAL \
+ br 14
+
+#endif /* __ASSEMBLER__ */
+
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+ ({ \
+ unsigned int _ret = INTERNAL_SYSCALL (name, , nr, args); \
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_ret, ), 0)) \
+ { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (_ret, )); \
+ _ret = 0xffffffff; \
+ } \
+ (int) _ret; })
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+#undef INTERNAL_SYSCALL_DIRECT
+#define INTERNAL_SYSCALL_DIRECT(name, err, nr, args...) \
+ ({ \
+ DECLARGS_##nr(args) \
+ register int _ret asm("2"); \
+ asm volatile ( \
+ "svc %b1\n\t" \
+ : "=d" (_ret) \
+ : "i" (__NR_##name) ASMFMT_##nr \
+ : "memory" ); \
+ _ret; })
+
+#undef INTERNAL_SYSCALL_SVC0
+#define INTERNAL_SYSCALL_SVC0(name, err, nr, args...) \
+ ({ \
+ DECLARGS_##nr(args) \
+ register unsigned long _nr asm("1") = (unsigned long)(__NR_##name); \
+ register int _ret asm("2"); \
+ asm volatile ( \
+ "svc 0\n\t" \
+ : "=d" (_ret) \
+ : "d" (_nr) ASMFMT_##nr \
+ : "memory" ); \
+ _ret; })
+
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(no, err, nr, args...) \
+ ({ \
+ DECLARGS_##nr(args) \
+ register unsigned long _nr asm("1") = (unsigned long)(no); \
+ register int _ret asm("2"); \
+ asm volatile ( \
+ "svc 0\n\t" \
+ : "=d" (_ret) \
+ : "d" (_nr) ASMFMT_##nr \
+ : "memory" ); \
+ _ret; })
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ (((__NR_##name) < 256) ? \
+ INTERNAL_SYSCALL_DIRECT(name, err, nr, args) : \
+ INTERNAL_SYSCALL_SVC0(name, err,nr, args))
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((unsigned int) (val) >= 0xfffff001u)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+
+#define DECLARGS_0()
+#define DECLARGS_1(arg1) \
+ register unsigned long gpr2 asm ("2") = (unsigned long)(arg1);
+#define DECLARGS_2(arg1, arg2) \
+ DECLARGS_1(arg1) \
+ register unsigned long gpr3 asm ("3") = (unsigned long)(arg2);
+#define DECLARGS_3(arg1, arg2, arg3) \
+ DECLARGS_2(arg1, arg2) \
+ register unsigned long gpr4 asm ("4") = (unsigned long)(arg3);
+#define DECLARGS_4(arg1, arg2, arg3, arg4) \
+ DECLARGS_3(arg1, arg2, arg3) \
+ register unsigned long gpr5 asm ("5") = (unsigned long)(arg4);
+#define DECLARGS_5(arg1, arg2, arg3, arg4, arg5) \
+ DECLARGS_4(arg1, arg2, arg3, arg4) \
+ register unsigned long gpr6 asm ("6") = (unsigned long)(arg5);
+#define DECLARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
+ DECLARGS_5(arg1, arg2, arg3, arg4, arg5) \
+ register unsigned long gpr7 asm ("7") = (unsigned long)(arg6);
+
+#define ASMFMT_0
+#define ASMFMT_1 , "0" (gpr2)
+#define ASMFMT_2 , "0" (gpr2), "d" (gpr3)
+#define ASMFMT_3 , "0" (gpr2), "d" (gpr3), "d" (gpr4)
+#define ASMFMT_4 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5)
+#define ASMFMT_5 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6)
+#define ASMFMT_6 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6), "d" (gpr7)
+
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. */
+#else
+/* For the time being just use stack_guard rather than a separate
+ pointer_guard. */
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(reg, tmpreg) \
+ ear tmpreg,%a0; \
+ x reg,STACK_GUARD(tmpreg)
+# define PTR_MANGLE2(reg, tmpreg) \
+ x reg,STACK_GUARD(tmpreg)
+# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg)
+# else
+# define PTR_MANGLE(var) \
+ (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+# define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#endif
+
+#endif /* _LINUX_S390_SYSDEP_H */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/versionsort64.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/versionsort64.c
new file mode 100644
index 000000000..144b691e5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/versionsort64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/versionsort64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/xstat.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/xstat.c
new file mode 100644
index 000000000..e9869f550
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/xstat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/xstat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/Implies b/libc/sysdeps/unix/sysv/linux/s390/s390-64/Implies
new file mode 100644
index 000000000..8d91c8009
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/Implies
@@ -0,0 +1 @@
+unix/sysv/linux/wordsize-64
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/Makefile b/libc/sysdeps/unix/sysv/linux/s390/s390-64/Makefile
new file mode 100644
index 000000000..283361b3f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/Makefile
@@ -0,0 +1,11 @@
+ifeq ($(subdir),misc)
+sysdep_headers += sys/elf.h
+endif
+
+ifeq ($(subdir),elf)
+ifeq (yes,$(build-shared))
+# This is needed to support g++ v2 and v3.
+sysdep_routines += framestate
+shared-only-routines += framestate
+endif
+endif
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/Versions b/libc/sysdeps/unix/sysv/linux/s390/s390-64/Versions
new file mode 100644
index 000000000..83092db48
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/Versions
@@ -0,0 +1,7 @@
+libc {
+ GLIBC_2.2 {
+ # Exception handling support functions from libgcc
+ __register_frame; __register_frame_table; __deregister_frame;
+ __frame_state_for; __register_frame_info_table;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/clone.S b/libc/sysdeps/unix/sysv/linux/s390/s390-64/clone.S
new file mode 100644
index 000000000..cdc6716a1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/clone.S
@@ -0,0 +1,79 @@
+/* Wrapper around clone system call. 64 bit S/390 version.
+ Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* clone is even more special than fork as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#include <sysdep.h>
+#include <tls.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+/* int __clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+ pid_t *parent_tid, void *tls, pid_t *child_tid); */
+/* sys_clone (void *child_stack, unsigned long flags,
+ pid_t *parent_tid, pid_t *child_tid, void *tls); */
+
+ .text
+ENTRY(__clone)
+ stg %r6,48(%r15) /* store %r6 to save area */
+ cfi_offset (%r6,-112)
+ lgr %r0,%r5 /* move *arg out of the way */
+ ltgr %r1,%r2 /* check fn and move to %r1 */
+ jz error /* no NULL function pointers */
+ ltgr %r2,%r3 /* check child_stack and move to %r2 */
+ jz error /* no NULL stack pointers */
+ lgr %r3,%r4 /* move flags to %r3 */
+ lgr %r4,%r6 /* move parent_tid to %r4 */
+ lg %r5,168(%r15) /* load child_tid from stack */
+ lg %r6,160(%r15) /* load tls from stack */
+ svc SYS_ify(clone)
+ ltgr %r2,%r2 /* check return code */
+ jz thread_start
+ lg %r6,48(%r15) /* restore %r6 */
+ jgm SYSCALL_ERROR_LABEL
+ br %r14
+error:
+ lghi %r2,-EINVAL
+ jg SYSCALL_ERROR_LABEL
+PSEUDO_END (__clone)
+
+thread_start:
+#ifdef RESET_PID
+ tmh %r3,1 /* CLONE_THREAD == 0x00010000 */
+ jne 1f
+ lhi %r2,-1
+ tml %r3,256 /* CLONE_VM == 0x00000100 */
+ jne 2f
+ svc SYS_ify(getpid)
+2: ear %r3,%a0
+ sllg %r3,%r3,32
+ ear %r3,%a1
+ st %r2,PID(%r3)
+ st %r2,TID(%r3)
+1:
+#endif
+ /* fn is in gpr 1, arg in gpr 0 */
+ lgr %r2,%r0 /* set first parameter to void *arg */
+ aghi %r15,-160 /* make room on the stack for the save area */
+ xc 0(8,%r15),0(%r15)
+ basr %r14,%r1 /* jump to fn */
+ DO_CALL (exit, 1)
+weak_alias (__clone, clone)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/dl-cache.h b/libc/sysdeps/unix/sysv/linux/s390/s390-64/dl-cache.h
new file mode 100644
index 000000000..14e1c662b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/dl-cache.h
@@ -0,0 +1,25 @@
+/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define _DL_CACHE_DEFAULT_ID 0x403
+
+#define _dl_cache_check_flags(flags) \
+ ((flags) == _DL_CACHE_DEFAULT_ID)
+
+#include_next <dl-cache.h>
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S b/libc/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S
new file mode 100644
index 000000000..8889b5359
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S
@@ -0,0 +1,75 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <features.h>
+
+#include "ucontext_i.h"
+
+/* __getcontext (const ucontext_t *ucp)
+
+ Saves the machine context in UCP such that when it is activated,
+ it appears as if __getcontext() returned again.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to save anything
+ other than the PRESERVED state. */
+
+ENTRY(__getcontext)
+ lgr %r5,%r2
+
+ /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */
+ la %r2,SIG_BLOCK
+ slgr %r3,%r3
+ la %r4,SC_MASK(%r5)
+ svc SYS_ify(rt_sigprocmask)
+
+ /* Store fpu context. */
+ stfpc SC_FPC(%r5)
+ std %f0,SC_FPRS(%r5)
+ std %f1,SC_FPRS+8(%r5)
+ std %f2,SC_FPRS+16(%r5)
+ std %f3,SC_FPRS+24(%r5)
+ std %f4,SC_FPRS+32(%r5)
+ std %f5,SC_FPRS+40(%r5)
+ std %f6,SC_FPRS+48(%r5)
+ std %f7,SC_FPRS+56(%r5)
+ std %f8,SC_FPRS+64(%r5)
+ std %f9,SC_FPRS+72(%r5)
+ std %f10,SC_FPRS+80(%r5)
+ std %f11,SC_FPRS+88(%r5)
+ std %f12,SC_FPRS+96(%r5)
+ std %f13,SC_FPRS+104(%r5)
+ std %f14,SC_FPRS+112(%r5)
+ std %f15,SC_FPRS+120(%r5)
+
+ /* Set __getcontext return value to 0. */
+ slgr %r2,%r2
+
+ /* Store access registers. */
+ stam %a0,%a15,SC_ACRS(%r5)
+
+ /* Store general purpose registers. */
+ stmg %r0,%r15,SC_GPRS(%r5)
+
+ /* Return. */
+ br %r14
+END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h b/libc/sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h
new file mode 100644
index 000000000..ef11dc94d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/kernel_stat.h
@@ -0,0 +1,21 @@
+/* Definition of `struct stat' used in the kernel.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define STAT_IS_KERNEL_STAT 1
+#define XSTAT_IS_XSTAT64 1
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c b/libc/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c
new file mode 100644
index 000000000..cdff9a4f2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c
@@ -0,0 +1,100 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <libintl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+
+/* This implementation can handle any ARGC value but only
+ normal integer type parameters. Parameters of type float,
+ double, complex and structure with sizes 0, 2, 4 or 8
+ won't work.
+ makecontext sets up a stack and the registers for the
+ user context. The stack looks like this:
+ size offset
+ %r15 -> +-----------------------+
+ 8 | back chain (zero) | 0
+ 8 | reserved | 8
+ 144 | save area for (*func) | 16
+ +-----------------------+
+ n | overflow parameters | 160
+ +-----------------------+
+ 8 | trampoline | 160+n
+ +-----------------------+
+ The registers are set up like this:
+ %r2-%r6: parameters 1 to 5
+ %r7 : (*func) pointer
+ %r8 : uc_link from ucontext structure
+ %r9 : address of setcontext
+ %r14 : return address to uc_link trampoline
+ %r15 : stack pointer.
+
+ The trampoline looks like this:
+ basr %r14,%r7
+ lgr %r2,%r8
+ br %r9. */
+
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+ unsigned long *sp;
+ va_list ap;
+ int i;
+
+ sp = (long *) (((long) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & -8L);
+
+ /* Setup the trampoline. */
+ *--sp = 0x0de7b904002807f9;
+
+ /* Set the return address to trampoline. */
+ ucp->uc_mcontext.gregs[14] = (long) sp;
+
+ /* Set register parameters. */
+ va_start (ap, argc);
+ for (i = 0; (i < argc) && (i < 5); i++)
+ ucp->uc_mcontext.gregs[2+i] = va_arg (ap, long);
+
+ /* The remaining arguments go to the overflow area. */
+ if (argc > 5) {
+ sp -= argc - 5;
+ for (i = 5; i < argc; i++)
+ sp[i] = va_arg(ap, long);
+ }
+ va_end (ap);
+
+ /* Make room for the save area and set the backchain. */
+ sp -= 20;
+ *sp = 0;
+
+ /* Pass (*func) to __start_context in %r7. */
+ ucp->uc_mcontext.gregs[7] = (long) func;
+
+ /* Pass ucp->uc_link to __start_context in %r8. */
+ ucp->uc_mcontext.gregs[8] = (long) ucp->uc_link;
+
+ /* Pass address of setcontext in %r9. */
+ ucp->uc_mcontext.gregs[9] = (long) &setcontext;
+
+ /* Set stack pointer. */
+ ucp->uc_mcontext.gregs[15] = (long) sp;
+}
+
+weak_alias (__makecontext, makecontext)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/mmap.S b/libc/sysdeps/unix/sysv/linux/s390/s390-64/mmap.S
new file mode 100644
index 000000000..443d432e1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/mmap.S
@@ -0,0 +1,79 @@
+/* Wrapper around mmap system call. 64 bit S/390 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#define EINVAL 22
+
+ .text
+
+ENTRY(__mmap)
+ /* Save registers and setup stack frame. */
+ stmg %r6,%r15,48(%r15)
+ cfi_offset (%r15,-40)
+ cfi_offset (%r14,-48)
+ cfi_offset (%r13,-56)
+ cfi_offset (%r12,-64)
+ cfi_offset (%r11,-72)
+ cfi_offset (%r10,-80)
+ cfi_offset (%r9,-88)
+ cfi_offset (%r8,-96)
+ cfi_offset (%r7,-104)
+ cfi_offset (%r6,-112)
+ lgr %r1,%r15
+ lg %r0,8(%r15) /* Load eos. */
+ aghi %r15,-208 /* Buy stack space. */
+ cfi_adjust_cfa_offset (208)
+ stg %r1,0(%r15) /* Store back chain. */
+ stg %r0,8(%r15) /* Store eos. */
+
+ /* Store parameters on stack, because old_mmap
+ takes only one parameter: a pointer to the parameter area. */
+ mvc 200(8,%r15),368(%r15) /* Move 'offset'. */
+ lgfr %r6,%r6
+ stg %r6,192(%r15) /* Store 'fd'. */
+ lgfr %r5,%r5
+ stg %r5,184(%r15) /* Store 'flags'. */
+ lgfr %r4,%r4
+ stg %r4,176(%r15) /* Store 'prot'. */
+ stg %r3,168(%r15) /* Store 'length'. */
+ stg %r2,160(%r15) /* Store 'start'. */
+
+ la %r2,160(%r15) /* Load address of parameter list. */
+ /* Do the system call trap. */
+ svc SYS_ify(mmap)
+
+ lg %r15,0(%r15) /* Load back chain. */
+ cfi_adjust_cfa_offset (-208)
+ lmg %r6,%r15,48(%r15) /* Load registers. */
+
+ /* Check gpr 2 for error. */
+ lghi %r0,-4096
+ clgr %r2,%r0
+ jgnl SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+ br %r14
+
+PSEUDO_END (__mmap)
+
+weak_alias (__mmap, mmap)
+weak_alias (__mmap, mmap64)
+weak_alias (__mmap, __mmap64)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h b/libc/sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h
new file mode 100644
index 000000000..d151b529b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h
@@ -0,0 +1,27 @@
+/* Low-level statistical profiling support function. Linux/s390 version.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+#include <sigcontextinfo.h>
+
+static void
+profil_counter (int signo, SIGCONTEXT scp)
+{
+ profil_count ((void *) GET_PC (scp));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/register-dump.h b/libc/sysdeps/unix/sysv/linux/s390/s390-64/register-dump.h
new file mode 100644
index 000000000..d705dd76d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/register-dump.h
@@ -0,0 +1,133 @@
+/* Dump registers. 64 bit S/390 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/uio.h>
+#include <stdio-common/_itoa.h>
+
+/* We will print the register dump in this format:
+
+ GPR0: XXXXXXXXXXXXXXXX GPR1: XXXXXXXXXXXXXXXX
+ GPR2: XXXXXXXXXXXXXXXX GPR3: XXXXXXXXXXXXXXXX
+ GPR4: XXXXXXXXXXXXXXXX GPR5: XXXXXXXXXXXXXXXX
+ GPR6: XXXXXXXXXXXXXXXX GPR7: XXXXXXXXXXXXXXXX
+ GPR8: XXXXXXXXXXXXXXXX GPR9: XXXXXXXXXXXXXXXX
+ GPRA: XXXXXXXXXXXXXXXX GPRB: XXXXXXXXXXXXXXXX
+ GPRC: XXXXXXXXXXXXXXXX GPRD: XXXXXXXXXXXXXXXX
+ GPRE: XXXXXXXXXXXXXXXX GPRF: XXXXXXXXXXXXXXXX
+
+ PSW.MASK: XXXXXXXXXXXXXXXX PSW.ADDR: XXXXXXXXXXXXXXXX
+
+ ST(0) XXXX XXXXXXXXXXXXXXXX ST(1) XXXX XXXXXXXXXXXXXXXX
+ ST(2) XXXX XXXXXXXXXXXXXXXX ST(3) XXXX XXXXXXXXXXXXXXXX
+ ST(4) XXXX XXXXXXXXXXXXXXXX ST(5) XXXX XXXXXXXXXXXXXXXX
+ ST(6) XXXX XXXXXXXXXXXXXXXX ST(7) XXXX XXXXXXXXXXXXXXXX
+ */
+
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
+{
+ char *cp = _itoa_word (value, buf + len, 16, 0);
+ while (cp > buf)
+ *--cp = '0';
+}
+
+static void
+register_dump (int fd, struct sigcontext *ctx)
+{
+ char regs[19][16];
+ struct iovec iov[40];
+ size_t nr = 0;
+
+#define ADD_STRING(str) \
+ iov[nr].iov_base = (char *) str; \
+ iov[nr].iov_len = strlen (str); \
+ ++nr
+#define ADD_MEM(str, len) \
+ iov[nr].iov_base = str; \
+ iov[nr].iov_len = len; \
+ ++nr
+
+ /* Generate strings of register contents. */
+ hexvalue (ctx->sregs->regs.gprs[0], regs[0], 16);
+ hexvalue (ctx->sregs->regs.gprs[1], regs[1], 16);
+ hexvalue (ctx->sregs->regs.gprs[2], regs[2], 16);
+ hexvalue (ctx->sregs->regs.gprs[3], regs[3], 16);
+ hexvalue (ctx->sregs->regs.gprs[4], regs[4], 16);
+ hexvalue (ctx->sregs->regs.gprs[5], regs[5], 16);
+ hexvalue (ctx->sregs->regs.gprs[6], regs[6], 16);
+ hexvalue (ctx->sregs->regs.gprs[7], regs[7], 16);
+ hexvalue (ctx->sregs->regs.gprs[8], regs[8], 16);
+ hexvalue (ctx->sregs->regs.gprs[9], regs[9], 16);
+ hexvalue (ctx->sregs->regs.gprs[10], regs[10], 16);
+ hexvalue (ctx->sregs->regs.gprs[11], regs[11], 16);
+ hexvalue (ctx->sregs->regs.gprs[12], regs[12], 16);
+ hexvalue (ctx->sregs->regs.gprs[13], regs[13], 16);
+ hexvalue (ctx->sregs->regs.gprs[14], regs[14], 16);
+ hexvalue (ctx->sregs->regs.gprs[15], regs[15], 16);
+ hexvalue (ctx->sregs->regs.psw.mask, regs[16], 16);
+ hexvalue (ctx->sregs->regs.psw.addr, regs[17], 16);
+
+ /* Generate the output. */
+ ADD_STRING ("Register dump:\n\n GPR0: ");
+ ADD_MEM (regs[0], 16);
+ ADD_STRING (" GPR1: ");
+ ADD_MEM (regs[1], 16);
+ ADD_STRING (" GPR2: ");
+ ADD_MEM (regs[2], 16);
+ ADD_STRING (" GPR3: ");
+ ADD_MEM (regs[3], 16);
+ ADD_STRING ("\n GPR4: ");
+ ADD_MEM (regs[4], 16);
+ ADD_STRING (" GPR5: ");
+ ADD_MEM (regs[5], 16);
+ ADD_STRING (" GPR6: ");
+ ADD_MEM (regs[6], 16);
+ ADD_STRING (" GPR7: ");
+ ADD_MEM (regs[7], 16);
+ ADD_STRING ("\n GPR8: ");
+ ADD_MEM (regs[8], 16);
+ ADD_STRING (" GPR9: ");
+ ADD_MEM (regs[9], 16);
+ ADD_STRING (" GPRA: ");
+ ADD_MEM (regs[10], 16);
+ ADD_STRING (" GPRB: ");
+ ADD_MEM (regs[11], 16);
+ ADD_STRING ("\n GPRC: ");
+ ADD_MEM (regs[12], 16);
+ ADD_STRING (" GPRD: ");
+ ADD_MEM (regs[13], 16);
+ ADD_STRING (" GPRE: ");
+ ADD_MEM (regs[14], 16);
+ ADD_STRING (" GPRF: ");
+ ADD_MEM (regs[15], 16);
+ ADD_STRING ("\n\n PSW.MASK: ");
+ ADD_MEM (regs[16], 16);
+ ADD_STRING (" PSW.ADDR: ");
+ ADD_MEM (regs[17], 16);
+ ADD_STRING (" TRAP: ");
+ ADD_MEM (regs[18], 4);
+ ADD_STRING ("\n");
+
+ /* Write the stuff out. */
+ writev (fd, iov, nr);
+}
+
+
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S b/libc/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S
new file mode 100644
index 000000000..7beca847c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S
@@ -0,0 +1,72 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <features.h>
+
+#include "ucontext_i.h"
+
+/* __setcontext (const ucontext_t *ucp)
+
+ Restores the machine context in UCP and thereby resumes execution
+ in that context.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to restore anything
+ other than the PRESERVED state. */
+
+ENTRY(__setcontext)
+ lgr %r5,%r2
+
+ /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */
+ la %r2,SIG_BLOCK
+ la %r3,SC_MASK(%r5)
+ slgr %r4,%r4
+ svc SYS_ify(rt_sigprocmask)
+
+ /* Load fpu context. */
+ lfpc SC_FPC(%r5)
+ ld %f0,SC_FPRS(%r5)
+ ld %f1,SC_FPRS+8(%r5)
+ ld %f2,SC_FPRS+16(%r5)
+ ld %f3,SC_FPRS+24(%r5)
+ ld %f4,SC_FPRS+32(%r5)
+ ld %f5,SC_FPRS+40(%r5)
+ ld %f6,SC_FPRS+48(%r5)
+ ld %f7,SC_FPRS+56(%r5)
+ ld %f8,SC_FPRS+64(%r5)
+ ld %f9,SC_FPRS+72(%r5)
+ ld %f10,SC_FPRS+80(%r5)
+ ld %f11,SC_FPRS+88(%r5)
+ ld %f12,SC_FPRS+96(%r5)
+ ld %f13,SC_FPRS+104(%r5)
+ ld %f14,SC_FPRS+112(%r5)
+ ld %f15,SC_FPRS+120(%r5)
+
+ /* Don't touch %a0 and %a1, used for thread purposes. */
+ lam %a2,%a15,SC_ACRS+8(%r5)
+
+ /* Load general purpose registers. */
+ lmg %r0,%r15,SC_GPRS(%r5)
+
+ /* Return. */
+ br %r14
+END(__setcontext)
+
+weak_alias (__setcontext, setcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c b/libc/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c
new file mode 100644
index 000000000..eff4f1785
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* 64 bit Linux for S/390 only has rt signals, thus we do not even want to try
+ falling back to the old style signals as the default Linux handler does. */
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. This is the definition. */
+
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+ If OACT is not NULL, put the old action for SIG in *OACT. */
+int
+__libc_sigaction (sig, act, oact)
+ int sig;
+ const struct sigaction *act;
+ struct sigaction *oact;
+{
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ return INLINE_SYSCALL (rt_sigaction, 4, sig, act, oact, _NSIG / 8);
+}
+libc_hidden_def (__libc_sigaction)
+
+#ifdef WRAPPER_INCLUDE
+# include WRAPPER_INCLUDE
+#endif
+
+#ifndef LIBC_SIGACTION
+weak_alias (__libc_sigaction, __sigaction)
+libc_hidden_weak (__sigaction)
+weak_alias (__libc_sigaction, sigaction)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/sigpending.c b/libc/sysdeps/unix/sysv/linux/s390/s390-64/sigpending.c
new file mode 100644
index 000000000..808687436
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/sigpending.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* 64 bit Linux for S/390 only has rt signals, thus we do not even want to try
+ falling back to the old style signals as the default Linux handler does. */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Change the set of blocked signals to SET,
+ wait until a signal arrives, and restore the set of blocked signals. */
+int
+sigpending (set)
+ sigset_t *set;
+{
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ return INLINE_SYSCALL (rt_sigpending, 2, set, _NSIG / 8);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/sigprocmask.c b/libc/sysdeps/unix/sysv/linux/s390/s390-64/sigprocmask.c
new file mode 100644
index 000000000..a6dd9159a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/sigprocmask.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* 64 bit Linux for S/390 only has rt signals, thus we do not even want to try
+ falling back to the old style signals as the default Linux handler does. */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Get and/or change the set of blocked signals. */
+int
+__sigprocmask (how, set, oset)
+ int how;
+ const sigset_t *set;
+ sigset_t *oset;
+{
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ return INLINE_SYSCALL (rt_sigprocmask, 4, how, set, oset, _NSIG / 8);
+}
+weak_alias (__sigprocmask, sigprocmask)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/socket.S b/libc/sysdeps/unix/sysv/linux/s390/s390-64/socket.S
new file mode 100644
index 000000000..d4c3a1c4e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/socket.S
@@ -0,0 +1,137 @@
+/* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep-cancel.h>
+#include <socketcall.h>
+
+/* &%/$&!! preprocessor */
+#define P(a, b) P2(a, b)
+#define P2(a, b) a##b
+
+ .text
+/* The socket-oriented system calls are handled unusally in Linux.
+ They are all gated through the single `socketcall' system call number.
+ `socketcall' takes two arguments: the first is the subcode, specifying
+ which socket function is being called; and the second is a pointer to
+ the arguments to the specific function.
+
+ The .S files for the other calls just #define socket and #include this. */
+
+#ifndef __socket
+#ifndef NO_WEAK_ALIAS
+#define __socket P(__,socket)
+#else
+#define __socket socket
+#endif
+#endif
+
+#ifndef NARGS /* The socket.o object is compiled directly ... */
+#define NARGS 3
+#endif
+
+.globl __socket
+ENTRY(__socket)
+ /* Save registers and setup stack. */
+ stmg %r6,%r15,48(%r15) /* Save registers. */
+ cfi_offset (%r15,-40)
+ cfi_offset (%r14,-48)
+ cfi_offset (%r13,-56)
+ cfi_offset (%r12,-64)
+ cfi_offset (%r11,-72)
+ cfi_offset (%r10,-80)
+ cfi_offset (%r9,-88)
+ cfi_offset (%r8,-96)
+ cfi_offset (%r7,-104)
+ cfi_offset (%r6,-112)
+ lgr %r1,%r15
+ lg %r0,8(%r15) /* Load eos. */
+ ahi %r15,-208 /* Buy stack space. */
+ cfi_adjust_cfa_offset (208)
+ stg %r1,0(%r15) /* Store back chain. */
+ stg %r0,8(%r15) /* Store eos. */
+
+ /* Reorder arguments. */
+#if (NARGS >= 6)
+ mvc 200(8,%r15),368(%r15) /* Move between parameter lists. */
+#endif
+#if (NARGS >= 5)
+ stg %r6,192(%r15) /* Store into parameter list. */
+#endif
+#if (NARGS >= 4)
+ stg %r5,184(%r15) /* Store into parameter list. */
+#endif
+#if (NARGS >= 3)
+ stg %r4,176(%r15) /* Store into parameter list. */
+#endif
+#if (NARGS >= 2)
+ stg %r3,168(%r15) /* Store into parameter list. */
+ stg %r2,160(%r15)
+#endif
+
+#if defined NEED_CANCELLATION && defined CENABLE
+ SINGLE_THREAD_P
+ jne L(socket_cancel)
+#endif
+
+ /* Load subcode for socket syscall. */
+ lghi %r2,P(SOCKOP_,socket)
+ la %r3,160(%r15) /* Load address of parameter list. */
+
+ /* Do the system call trap. */
+ svc SYS_ify(socketcall)
+
+4:
+ lg %r15,0(%r15) /* Load back chain. */
+ lmg %r6,15,48(%r15) /* Load registers. */
+
+ /* gpr2 is < 0 if there was an error. */
+ lghi %r0,-125
+ clgr %r2,%r0
+ jgnl SYSCALL_ERROR_LABEL
+
+ /* Successful; return the syscall's value. */
+ br %r14
+
+#if defined NEED_CANCELLATION && defined CENABLE
+L(socket_cancel):
+ brasl %r14,CENABLE
+ lr %r0,%r2
+
+ /* Load subcode for socket syscall. */
+ lghi %r2,P(SOCKOP_,socket)
+ la %r3,160(%r15) /* Load address of parameter list. */
+
+ /* Do the system call trap. */
+ svc SYS_ify(socketcall)
+
+ lgr %r12,%r2
+ lr %r2,%r0
+ brasl %r14,CDISABLE
+
+ lgr %r2,%r12
+ j 4b
+#endif
+
+ SYSCALL_ERROR_HANDLER
+END (__socket)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__socket, socket)
+#endif
+
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S b/libc/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S
new file mode 100644
index 000000000..cb96fd3b6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S
@@ -0,0 +1,108 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <features.h>
+
+#include "ucontext_i.h"
+
+/* __swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
+
+ Saves the machine context in oucp such that when it is activated,
+ it appears as if __swapcontextt() returned again, restores the
+ machine context in ucp and thereby resumes execution in that
+ context.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to save anything
+ other than the PRESERVED state. */
+
+ENTRY(__swapcontext)
+ lgr %r1,%r2
+ lgr %r5,%r3
+
+ /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */
+ la %r2,SIG_BLOCK
+ slgr %r3,%r3
+ la %r4,SC_MASK(%r1)
+ svc SYS_ify(rt_sigprocmask)
+
+ /* Store fpu context. */
+ stfpc SC_FPC(%r1)
+ std %f0,SC_FPRS(%r1)
+ std %f1,SC_FPRS+8(%r1)
+ std %f2,SC_FPRS+16(%r1)
+ std %f3,SC_FPRS+24(%r1)
+ std %f4,SC_FPRS+32(%r1)
+ std %f5,SC_FPRS+40(%r1)
+ std %f6,SC_FPRS+48(%r1)
+ std %f7,SC_FPRS+56(%r1)
+ std %f8,SC_FPRS+64(%r1)
+ std %f9,SC_FPRS+72(%r1)
+ std %f10,SC_FPRS+80(%r1)
+ std %f11,SC_FPRS+88(%r1)
+ std %f12,SC_FPRS+96(%r1)
+ std %f13,SC_FPRS+104(%r1)
+ std %f14,SC_FPRS+112(%r1)
+ std %f15,SC_FPRS+120(%r1)
+
+ /* Set __swapcontext return value to 0. */
+ slgr %r2,%r2
+
+ /* Store access registers. */
+ stam %a0,%a15,SC_ACRS(%r1)
+
+ /* Store general purpose registers. */
+ stmg %r0,%r15,SC_GPRS(%r1)
+
+ /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */
+ la %r2,SIG_BLOCK
+ la %r3,SC_MASK(%r5)
+ slgr %r4,%r4
+ svc SYS_ify(rt_sigprocmask)
+
+ /* Load fpu context. */
+ lfpc SC_FPC(%r5)
+ ld %f0,SC_FPRS(%r5)
+ ld %f1,SC_FPRS+8(%r5)
+ ld %f2,SC_FPRS+16(%r5)
+ ld %f3,SC_FPRS+24(%r5)
+ ld %f4,SC_FPRS+32(%r5)
+ ld %f5,SC_FPRS+40(%r5)
+ ld %f6,SC_FPRS+48(%r5)
+ ld %f7,SC_FPRS+56(%r5)
+ ld %f8,SC_FPRS+64(%r5)
+ ld %f9,SC_FPRS+72(%r5)
+ ld %f10,SC_FPRS+80(%r5)
+ ld %f11,SC_FPRS+88(%r5)
+ ld %f12,SC_FPRS+96(%r5)
+ ld %f13,SC_FPRS+104(%r5)
+ ld %f14,SC_FPRS+112(%r5)
+ ld %f15,SC_FPRS+120(%r5)
+
+ /* Don't touch %a0 and %a1, used for thread purposes. */
+ lam %a2,%a15,SC_ACRS+8(%r5)
+
+ /* Load general purpose registers. */
+ lmg %r0,%r15,SC_GPRS(%r5)
+
+ /* Return. */
+ br %r14
+END(__swapcontext)
+weak_alias (__swapcontext, swapcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/syscall.S b/libc/sysdeps/unix/sysv/linux/s390/s390-64/syscall.S
new file mode 100644
index 000000000..31b55d73f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/syscall.S
@@ -0,0 +1,69 @@
+/* Copyright (C) 2001, 2006 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* Please consult the file sysdeps/unix/sysv/linux/s390/sysdep.h for
+ more information about the value -4095 used below.*/
+
+ENTRY (syscall)
+ /* Save registers and setup stack. */
+ stmg %r6,%r15,48(%r15) /* Save registers. */
+ cfi_offset (%r15,-40)
+ cfi_offset (%r14,-48)
+ cfi_offset (%r13,-56)
+ cfi_offset (%r12,-64)
+ cfi_offset (%r11,-72)
+ cfi_offset (%r10,-80)
+ cfi_offset (%r9,-88)
+ cfi_offset (%r8,-96)
+ cfi_offset (%r7,-104)
+ cfi_offset (%r6,-112)
+ lgr %r1,%r15
+ lg %r0,8(%r15) /* Load eos. */
+ aghi %r15,-160 /* Buy stack space. */
+ cfi_adjust_cfa_offset (160)
+ stg %r1,0(%r15) /* Store back chain. */
+ stg %r0,8(%r15) /* Store eos. */
+
+ lgr %r1,%r2 /* Move syscall number. */
+ lgr %r2,%r3 /* First parameter. */
+ lgr %r3,%r4 /* Second parameter. */
+ lgr %r4,%r5 /* Third parameter. */
+ lgr %r5,%r6 /* Fourth parameter. */
+ lg %r6,320(%r15) /* Fifth parameter. */
+ lg %r7,328(%r15) /* Sixth parameter. */
+
+ basr %r8,0
+0: clg %r1,4f-0b(%r8) /* svc number < 256? */
+ jl 2f
+1: svc 0
+ j 3f
+2: ex %r1,1b-0b(%r8) /* lsb of R1 is subsituted as SVC number */
+3: lg %r15,0(%r15) /* load back chain */
+ cfi_adjust_cfa_offset (-160)
+ lmg %r6,15,48(%r15) /* Load registers. */
+
+ lghi %r0,-4095
+ clgr %r2,%r0 /* Check R2 for error. */
+ jgnl SYSCALL_ERROR_LABEL
+ br %r14 /* Return to caller. */
+4: .quad 256
+PSEUDO_END (syscall)
+
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list b/libc/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list
new file mode 100644
index 000000000..791ab9ba5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list
@@ -0,0 +1,35 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+vfork - vfork 0 __vfork vfork
+
+# semaphore and shm system calls
+msgctl - msgctl i:iip __msgctl msgctl
+msgget - msgget i:ii __msgget msgget
+msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
+msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
+shmat - shmat i:ipi __shmat shmat
+shmctl - shmctl i:iip __shmctl shmctl
+shmdt - shmdt i:s __shmdt shmdt
+shmget - shmget i:iii __shmget shmget
+semop - semop i:ipi __semop semop
+semget - semget i:iii __semget semget
+semctl - semctl i:iiii __semctl semctl
+
+# proper socket implementations:
+accept - accept Ci:iBN __libc_accept __accept accept
+bind - bind i:ipi __bind bind
+connect - connect Ci:ipi __libc_connect __connect_internal __connect connect
+getpeername - getpeername i:ipp __getpeername getpeername
+getsockname - getsockname i:ipp __getsockname getsockname
+getsockopt - getsockopt i:iiiBN __getsockopt getsockopt
+listen - listen i:ii __listen listen
+recv - recv Ci:ibni __libc_recv __recv recv
+recvfrom - recvfrom Ci:ibniBN __libc_recvfrom __recvfrom recvfrom
+recvmsg - recvmsg Ci:ipi __libc_recvmsg __recvmsg recvmsg
+send - send Ci:ibni __libc_send __send send
+sendmsg - sendmsg Ci:ipi __libc_sendmsg __sendmsg sendmsg
+sendto - sendto Ci:ibnibn __libc_sendto __sendto sendto
+setsockopt - setsockopt i:iiibn __setsockopt setsockopt
+shutdown - shutdown i:ii __shutdown shutdown
+socket - socket i:iii __socket socket
+socketpair - socketpair i:iiif __socketpair socketpair
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S b/libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S
new file mode 100644
index 000000000..bb61e894f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S
@@ -0,0 +1,123 @@
+/* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tls.h>
+
+
+/* The following code is only used in the shared library when we
+ compile the reentrant version. Otherwise each system call defines
+ each own version. */
+
+/* The syscall stubs jump here when they detect an error. */
+
+#undef CALL_MCOUNT
+#define CALL_MCOUNT
+
+.text
+ENTRY(__syscall_error)
+#ifndef PIC
+# if USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+ basr %r1,0
+0: lg %r1,1f-0b(%r1)
+ ear %r3,%a0
+ sllg %r3,%r3,32
+ ear %r3,%a1
+ lcr %r2,%r2
+ st %r2,0(%r1,%r3)
+ lghi %r2,-1
+ br %r14
+1: .quad SYSCALL_ERROR_ERRNO@ntpoff
+# elif !defined _LIBC_REENTRANT
+ larl %r1,errno
+ lcr %r2,%r2
+ st %r2,0(%r1)
+ lghi %r2,-1
+ br %r14
+# else
+ stmg %r13,%r15,104(%r15)
+ cfi_offset (%r15,-40)
+ cfi_offset (%r14,-48)
+ cfi_offset (%r13,-56)
+ lgr %r0,%r15
+ aghi %r15,-160
+ cfi_adjust_cfa_offset (160)
+ lcr %r13,%r2
+ stg %r0,0(%r15)
+ brasl %r14,__errno_location
+ st %r13,0(%r2)
+ lmg %r13,%r15,264(%r15)
+ cfi_adjust_cfa_offset (-160)
+ lghi %r2,-1
+ br %r14
+#endif
+#else
+# if RTLD_PRIVATE_ERRNO
+ larl %r1,rtld_errno
+ lcr %r2,%r2
+ st %r2,0(%r1)
+ lghi %r2,-1
+ br %r14
+# elif USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+ larl %r1,_GLOBAL_OFFSET_TABLE_
+ lg %r1,SYSCALL_ERROR_ERRNO@gotntpoff(%r1)
+ ear %r3,%a0
+ sllg %r3,%r3,32
+ ear %r3,%a1
+ lcr %r2,%r2
+ st %r2,0(%r1,%r3)
+ lghi %r2,-1
+ br %r14
+# elif !defined _LIBC_REENTRANT
+ larl %r1,_GLOBAL_OFFSET_TABLE_
+ lg %r1,errno@GOT(%r1)
+ lcr %r2,%r2
+ st %r2,0(%r1)
+ lghi %r2,-1
+ br %r14
+# else
+ stmg %r13,%r15,104(%r15)
+ cfi_offset (%r15,-40)
+ cfi_offset (%r14,-48)
+ cfi_offset (%r13,-56)
+ lgr %r0,%r15
+ aghi %r15,-160
+ cfi_adjust_cfa_offset (160)
+ lcr %r13,%r2
+ stg %r0,0(%r15)
+ brasl %r14,__errno_location@PLT
+ st %r13,0(%r2)
+ lmg %r13,%r15,264(%r15)
+ cfi_adjust_cfa_offset (-160)
+ lghi %r2,-1
+ br %r14
+# endif
+#endif
+
+END (__syscall_error)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h b/libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
new file mode 100644
index 000000000..9ddec8e04
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
@@ -0,0 +1,304 @@
+/* Assembler macros for 64 bit S/390.
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINUX_S390_SYSDEP_H
+#define _LINUX_S390_SYSDEP_H
+
+#include <sysdeps/s390/s390-64/sysdep.h>
+#include <sysdeps/unix/sysdep.h>
+#include <dl-sysdep.h> /* For RTLD_PRIVATE_ERRNO. */
+#include <tls.h>
+
+/* For Linux we can use the system call table in the header file
+ /usr/include/asm/unistd.h
+ of the kernel. But these symbols do not follow the SYS_* syntax
+ so we have to redefine the `SYS_ify' macro here. */
+/* In newer 2.1 kernels __NR_syscall is missing so we define it here. */
+#define __NR_syscall 0
+
+/*
+ * Newer kernel versions redefined __NR_pread and __NR_pwrite to
+ * __NR_pread64 and __NR_pwrite64.
+ */
+#ifndef __NR_pread
+# define __NR_pread __NR_pread64
+#endif
+#ifndef __NR_pwrite
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+#undef SYS_ify
+#define SYS_ify(syscall_name) __NR_##syscall_name
+
+#ifdef __ASSEMBLER__
+
+/* Linux uses a negative return value to indicate syscall errors, unlike
+ most Unices, which use the condition codes' carry flag.
+
+ Since version 2.1 the return value of a system call might be negative
+ even if the call succeeded. E.g., the `lseek' system call might return
+ a large offset. Therefore we must not anymore test for < 0, but test
+ for a real error by making sure the value in gpr2 is a real error
+ number. Linus said he will make sure the no syscall returns a value
+ in -1 .. -4095 as a valid result so we can savely test with -4095. */
+
+#undef PSEUDO
+#define PSEUDO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ lghi %r4,-4095 ; \
+ clgr %r2,%r4 ; \
+ jgnl SYSCALL_ERROR_LABEL
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ SYSCALL_ERROR_HANDLER; \
+ END (name)
+
+#undef PSEUDO_NOERRNO
+#define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args)
+
+#undef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(name) \
+ SYSCALL_ERROR_HANDLER; \
+ END (name)
+
+#undef PSEUDO_ERRVAL
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ lcgr %r2,%r2
+
+#undef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(name) \
+ SYSCALL_ERROR_HANDLER; \
+ END (name)
+
+#ifndef PIC
+# define SYSCALL_ERROR_LABEL syscall_error
+# define SYSCALL_ERROR_HANDLER
+#else
+# if RTLD_PRIVATE_ERRNO
+# define SYSCALL_ERROR_LABEL 0f
+# define SYSCALL_ERROR_HANDLER \
+0: larl %r1,rtld_errno; \
+ lcr %r2,%r2; \
+ st %r2,0(%r1); \
+ lghi %r2,-1; \
+ br %r14
+# elif defined _LIBC_REENTRANT
+# if USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+# define SYSCALL_ERROR_LABEL 0f
+# define SYSCALL_ERROR_HANDLER \
+0: lcr %r0,%r2; \
+ larl %r1,SYSCALL_ERROR_ERRNO@indntpoff; \
+ lg %r1,0(%r1); \
+ ear %r2,%a0; \
+ sllg %r2,%r2,32; \
+ ear %r2,%a1; \
+ st %r0,0(%r1,%r2); \
+ lghi %r2,-1; \
+ br %r14
+# else
+# define SYSCALL_ERROR_LABEL syscall_error@plt
+# define SYSCALL_ERROR_HANDLER
+# endif
+# else
+# define SYSCALL_ERROR_LABEL 0f
+# define SYSCALL_ERROR_HANDLER \
+0: larl %r1,_GLOBAL_OFFSET_TABLE_; \
+ lg %r1,errno@GOT(%r1); \
+ lcr %r2,%r2; \
+ st %r2,0(%r1); \
+ lghi %r2,-1; \
+ br %r14
+# endif /* _LIBC_REENTRANT */
+#endif /* PIC */
+
+/* Linux takes system call arguments in registers:
+
+ syscall number 1 call-clobbered
+ arg 1 2 call-clobbered
+ arg 2 3 call-clobbered
+ arg 3 4 call-clobbered
+ arg 4 5 call-clobbered
+ arg 5 6 call-saved
+ arg 6 7 call-saved
+
+ (Of course a function with say 3 arguments does not have entries for
+ arguments 4 and 5.)
+ For system calls with 6 parameters a stack operation is required
+ to load the 6th parameter to register 7. Call saved register 7 is
+ moved to register 0 and back to avoid an additional stack frame.
+ */
+
+#define DO_CALL(syscall, args) \
+ .if args > 5; \
+ lgr %r0,%r7; \
+ lg %r7,160(%r15); \
+ .endif; \
+ .if SYS_ify (syscall) < 256; \
+ svc SYS_ify (syscall); \
+ .else; \
+ lghi %r1,SYS_ify (syscall); \
+ svc 0; \
+ .endif; \
+ .if args > 5; \
+ lgr %r7,%r0; \
+ .endif
+
+#define ret \
+ br 14
+
+#define ret_NOERRNO \
+ br 14
+
+#define ret_ERRVAL \
+ br 14
+
+#endif /* __ASSEMBLER__ */
+
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+ ({ \
+ long _ret = INTERNAL_SYSCALL (name, , nr, args); \
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_ret, ), 0)) \
+ { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (_ret, )); \
+ _ret = -1; \
+ } \
+ _ret; })
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+#undef INTERNAL_SYSCALL_DIRECT
+#define INTERNAL_SYSCALL_DIRECT(name, err, nr, args...) \
+ ({ \
+ DECLARGS_##nr(args) \
+ register long _ret asm("2"); \
+ asm volatile ( \
+ "svc %b1\n\t" \
+ : "=d" (_ret) \
+ : "i" (__NR_##name) ASMFMT_##nr \
+ : "memory" ); \
+ _ret; })
+
+#undef INTERNAL_SYSCALL_SVC0
+#define INTERNAL_SYSCALL_SVC0(name, err, nr, args...) \
+ ({ \
+ DECLARGS_##nr(args) \
+ register unsigned long _nr asm("1") = (unsigned long)(__NR_##name); \
+ register long _ret asm("2"); \
+ asm volatile ( \
+ "svc 0\n\t" \
+ : "=d" (_ret) \
+ : "d" (_nr) ASMFMT_##nr \
+ : "memory" ); \
+ _ret; })
+
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(no, err, nr, args...) \
+ ({ \
+ DECLARGS_##nr(args) \
+ register unsigned long _nr asm("1") = (unsigned long)(no); \
+ register long _ret asm("2"); \
+ asm volatile ( \
+ "svc 0\n\t" \
+ : "=d" (_ret) \
+ : "d" (_nr) ASMFMT_##nr \
+ : "memory" ); \
+ _ret; })
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ (((__NR_##name) < 256) ? \
+ INTERNAL_SYSCALL_DIRECT(name, err, nr, args) : \
+ INTERNAL_SYSCALL_SVC0(name, err,nr, args))
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((unsigned long) (val) >= -4095UL)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+
+#define DECLARGS_0()
+#define DECLARGS_1(arg1) \
+ register unsigned long gpr2 asm ("2") = (unsigned long)(arg1);
+#define DECLARGS_2(arg1, arg2) \
+ DECLARGS_1(arg1) \
+ register unsigned long gpr3 asm ("3") = (unsigned long)(arg2);
+#define DECLARGS_3(arg1, arg2, arg3) \
+ DECLARGS_2(arg1, arg2) \
+ register unsigned long gpr4 asm ("4") = (unsigned long)(arg3);
+#define DECLARGS_4(arg1, arg2, arg3, arg4) \
+ DECLARGS_3(arg1, arg2, arg3) \
+ register unsigned long gpr5 asm ("5") = (unsigned long)(arg4);
+#define DECLARGS_5(arg1, arg2, arg3, arg4, arg5) \
+ DECLARGS_4(arg1, arg2, arg3, arg4) \
+ register unsigned long gpr6 asm ("6") = (unsigned long)(arg5);
+#define DECLARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
+ DECLARGS_5(arg1, arg2, arg3, arg4, arg5) \
+ register unsigned long gpr7 asm ("7") = (unsigned long)(arg6);
+
+#define ASMFMT_0
+#define ASMFMT_1 , "0" (gpr2)
+#define ASMFMT_2 , "0" (gpr2), "d" (gpr3)
+#define ASMFMT_3 , "0" (gpr2), "d" (gpr3), "d" (gpr4)
+#define ASMFMT_4 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5)
+#define ASMFMT_5 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6)
+#define ASMFMT_6 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6), "d" (gpr7)
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. */
+#else
+/* For the time being just use stack_guard rather than a separate
+ pointer_guard. */
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(reg, tmpreg) \
+ ear tmpreg,%a0; \
+ sllg tmpreg,tmpreg,32; \
+ ear tmpreg,%a1; \
+ xg reg,STACK_GUARD(tmpreg)
+# define PTR_MANGLE2(reg, tmpreg) \
+ xg reg,STACK_GUARD(tmpreg)
+# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg)
+# else
+# define PTR_MANGLE(var) \
+ (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+# define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#endif
+
+#endif /* _LINUX_S390_SYSDEP_H */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/semtimedop.c b/libc/sysdeps/unix/sysv/linux/s390/semtimedop.c
new file mode 100644
index 000000000..d8990dd02
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/semtimedop.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/sem.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Perform user-defined atomical operation of array of semaphores. */
+
+int
+semtimedop (semid, sops, nsops, timeout)
+ int semid;
+ struct sembuf *sops;
+ size_t nsops;
+ const struct timespec *timeout;
+{
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semtimedop,
+ semid, (int) nsops, timeout, sops);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h b/libc/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h
new file mode 100644
index 000000000..ef9126471
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+
+#define SIGCONTEXT struct sigcontext *
+#define SIGCONTEXT_EXTRA_ARGS
+#define GET_PC(ctx) ((void *)((ctx)->sregs->regs.psw.addr))
+#define GET_FRAME(ctx) (*(void **)((ctx)->sregs->regs.gprs[11]))
+#define GET_STACK(ctx) ((void *)((ctx)->sregs->regs.gprs[15]))
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/libc/sysdeps/unix/sysv/linux/s390/sys/elf.h b/libc/sysdeps/unix/sysv/linux/s390/sys/elf.h
new file mode 100644
index 000000000..431b79b44
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/sys/elf.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_ELF_H
+#define _SYS_ELF_H 1
+
+#warning "This header is obsolete; use <sys/procfs.h> instead."
+
+#include <sys/procfs.h>
+
+#endif /* _SYS_ELF_H */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/sys/procfs.h b/libc/sysdeps/unix/sysv/linux/s390/sys/procfs.h
new file mode 100644
index 000000000..9c6caacae
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/sys/procfs.h
@@ -0,0 +1,176 @@
+/* Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H 1
+
+/* This is somewhat modelled after the file of the same name on SVR4
+ systems. It provides a definition of the core file format for ELF
+ used on Linux. It doesn't have anything to do with the /proc file
+ system, even though Linux has one.
+
+ Anyway, the whole purpose of this file is for GDB and GDB only.
+ Don't read too much into it. Don't use it for anything other than
+ GDB unless you know what you are doing. */
+
+#include <features.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/ucontext.h>
+
+__BEGIN_DECLS
+
+typedef greg_t elf_greg_t;
+#define ELF_NGREG NGREG
+typedef gregset_t elf_gregset_t;
+typedef fpreg_t elf_fpreg_t;
+typedef fpregset_t elf_fpregset_t;
+
+/* Signal info. */
+struct elf_siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_code; /* Extra code. */
+ int si_errno; /* Errno. */
+ };
+
+
+/* Definitions to generate Intel SVR4-like core files. These mostly
+ have the same names as the SVR4 types with "elf_" tacked on the
+ front to prevent clashes with Linux definitions, and the typedef
+ forms have been avoided. This is mostly like the SVR4 structure,
+ but more Linuxy, with things that Linux does not support and which
+ GDB doesn't really use excluded. */
+
+struct elf_prstatus
+ {
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned long int pr_sigpend; /* Set of pending signals. */
+ unsigned long int pr_sighold; /* Set of held signals. */
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct timeval pr_utime; /* User time. */
+ struct timeval pr_stime; /* System time. */
+ struct timeval pr_cutime; /* Cumulative user time. */
+ struct timeval pr_cstime; /* Cumulative system time. */
+ elf_gregset_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+#define ELF_PRARGSZ (80) /* Number of chars for args. */
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long int pr_flag; /* Flags. */
+#if __WORDSIZE == 64
+ unsigned int pr_uid;
+ unsigned int pr_gid;
+#else
+ unsigned short int pr_uid;
+ unsigned short int pr_gid;
+#endif
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+/* The rest of this file provides the types for emulation of the
+ Solaris <proc_service.h> interfaces that should be implemented by
+ users of libthread_db. */
+
+/* Addresses. */
+typedef void *psaddr_t;
+
+/* Register sets. Linux has different names. */
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+ therefore have only one PID type. */
+typedef __pid_t lwpid_t;
+
+/* Process status and info. In the end we do provide typedefs for them. */
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+#if __WORDSIZE == 64
+
+/* Provide 32-bit variants so that BFD can read 32-bit
+ core files. */
+#define ELF_NGREG32 36
+typedef unsigned int elf_greg_t32;
+typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG32];
+typedef elf_fpregset_t elf_fpregset_t32;
+
+struct elf_prstatus32
+ {
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned int pr_sigpend; /* Set of pending signals. */
+ unsigned int pr_sighold; /* Set of held signals. */
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct
+ {
+ int tv_sec, tv_usec;
+ } pr_utime, /* User time. */
+ pr_stime, /* System time. */
+ pr_cutime, /* Cumulative user time. */
+ pr_cstime; /* Cumulative system time. */
+ elf_gregset_t32 pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+struct elf_prpsinfo32
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned int pr_flag; /* Flags. */
+ unsigned short int pr_uid;
+ unsigned short int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+typedef elf_gregset_t32 prgregset32_t;
+typedef elf_fpregset_t32 prfpregset32_t;
+
+typedef struct elf_prstatus32 prstatus32_t;
+typedef struct elf_prpsinfo32 prpsinfo32_t;
+
+#endif
+
+__END_DECLS
+
+#endif /* sys/procfs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/sys/ptrace.h b/libc/sysdeps/unix/sysv/linux/s390/sys/ptrace.h
new file mode 100644
index 000000000..d26cf114e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/sys/ptrace.h
@@ -0,0 +1,138 @@
+/* `ptrace' debugger support interface. Linux version.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PTRACE_H
+#define _SYS_PTRACE_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+#ifdef _LINUX_PTRACE_H
+/* Kludge to stop stuff gdb & strace compiles from getting upset
+ */
+#undef PTRACE_TRACEME
+#undef PTRACE_PEEKTEXT
+#undef PTRACE_PEEKDATA
+#undef PTRACE_PEEKUSR
+#undef PTRACE_POKETEXT
+#undef PTRACE_POKEDATA
+#undef PTRACE_POKEUSR
+#undef PTRACE_CONT
+#undef PTRACE_KILL
+#undef PTRACE_SINGLESTEP
+
+#undef PTRACE_ATTACH
+#undef PTRACE_DETACH
+
+#undef PTRACE_SYSCALL
+#endif
+/* Type of the REQUEST argument to `ptrace.' */
+enum __ptrace_request
+{
+ /* Indicate that the process making this request should be traced.
+ All signals received by this process can be intercepted by its
+ parent, and its parent can use the other `ptrace' requests. */
+ PTRACE_TRACEME = 0,
+#define PT_TRACE_ME PTRACE_TRACEME
+
+ /* Return the word in the process's text space at address ADDR. */
+ PTRACE_PEEKTEXT = 1,
+#define PT_READ_I PTRACE_PEEKTEXT
+
+ /* Return the word in the process's data space at address ADDR. */
+ PTRACE_PEEKDATA = 2,
+#define PT_READ_D PTRACE_PEEKDATA
+
+ /* Return the word in the process's user area at offset ADDR. */
+ PTRACE_PEEKUSER = 3,
+#define PT_READ_U PTRACE_PEEKUSER
+
+ /* Write the word DATA into the process's text space at address ADDR. */
+ PTRACE_POKETEXT = 4,
+#define PT_WRITE_I PTRACE_POKETEXT
+
+ /* Write the word DATA into the process's data space at address ADDR. */
+ PTRACE_POKEDATA = 5,
+#define PT_WRITE_D PTRACE_POKEDATA
+
+ /* Write the word DATA into the process's user area at offset ADDR. */
+ PTRACE_POKEUSER = 6,
+#define PT_WRITE_U PTRACE_POKEUSER
+
+ /* Continue the process. */
+ PTRACE_CONT = 7,
+#define PT_CONTINUE PTRACE_CONT
+
+ /* Kill the process. */
+ PTRACE_KILL = 8,
+#define PT_KILL PTRACE_KILL
+
+ /* Single step the process.
+ This is not supported on all machines. */
+ PTRACE_SINGLESTEP = 9,
+#define PT_STEP PTRACE_SINGLESTEP
+
+ /* Get all general purpose registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_GETREGS = 12,
+#define PT_GETREGS PTRACE_GETREGS
+
+ /* Set all general purpose registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_SETREGS = 13,
+#define PT_SETREGS PTRACE_SETREGS
+
+ /* Get all floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_GETFPREGS = 14,
+#define PT_GETFPREGS PTRACE_GETFPREGS
+
+ /* Set all floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_SETFPREGS = 15,
+#define PT_SETFPREGS PTRACE_SETFPREGS
+
+ /* Attach to a process that is already running. */
+ PTRACE_ATTACH = 16,
+#define PT_ATTACH PTRACE_ATTACH
+
+ /* Detach from a process attached to with PTRACE_ATTACH. */
+ PTRACE_DETACH = 17,
+#define PT_DETACH PTRACE_DETACH
+
+ /* Continue and stop at the next (return from) syscall. */
+ PTRACE_SYSCALL = 24
+#define PT_SYSCALL PTRACE_SYSCALL
+};
+
+/* Perform process tracing functions. REQUEST is one of the values
+ above, and determines the action to be taken.
+ For all requests except PTRACE_TRACEME, PID specifies the process to be
+ traced.
+
+ PID and the other arguments described above for the various requests should
+ appear (those that are used for the particular request) as:
+ pid_t PID, void *ADDR, int DATA, void *ADDR2
+ after REQUEST. */
+extern long int ptrace (enum __ptrace_request __request, ...);
+
+__END_DECLS
+
+#endif /* _SYS_PTRACE_H */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/sys/ucontext.h b/libc/sysdeps/unix/sysv/linux/s390/sys/ucontext.h
new file mode 100644
index 000000000..4e32361c3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/sys/ucontext.h
@@ -0,0 +1,88 @@
+/* Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+/* Forward definition to avoid parse errors */
+struct ucontext;
+typedef struct ucontext ucontext_t;
+#include <features.h>
+#include <signal.h>
+
+/* We need the signal context definitions even if they are not used
+ included in <signal.h>. */
+#include <bits/sigcontext.h>
+
+/* Type for a program status word. */
+typedef struct
+{
+ unsigned long mask;
+ unsigned long addr;
+} __attribute__ ((aligned(8))) __psw_t;
+
+/* Type for a general-purpose register. */
+typedef unsigned long greg_t;
+
+/* And the whole bunch of them. We should have used `struct s390_regs',
+ but to avoid name space pollution and since the tradition says that
+ the register set is an array, we make gregset_t a simple array
+ that has the same size as s390_regs. This is needed for the
+ elf_prstatus structure. */
+#if __WORDSIZE == 64
+# define NGREG 27
+#else
+# define NGREG 36
+#endif
+/* Must match kernels psw_t alignment. */
+typedef greg_t gregset_t[NGREG] __attribute__ ((aligned(8)));
+
+typedef union
+ {
+ double d;
+ float f;
+ } fpreg_t;
+
+/* Register set for the floating-point registers. */
+typedef struct
+ {
+ unsigned int fpc;
+ fpreg_t fprs[16];
+ } fpregset_t;
+
+/* Context to describe whole processor state. */
+typedef struct
+ {
+ __psw_t psw;
+ unsigned long gregs[16];
+ unsigned int aregs[16];
+ fpregset_t fpregs;
+ } mcontext_t;
+
+/* Userlevel context. */
+struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ __sigset_t uc_sigmask;
+ };
+
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/sys/user.h b/libc/sysdeps/unix/sysv/linux/s390/sys/user.h
new file mode 100644
index 000000000..f00caea84
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/sys/user.h
@@ -0,0 +1,83 @@
+/* Copyright (C) 2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H 1
+
+/* The whole purpose of this file is for GDB and GDB only. Don't read
+ too much into it. Don't use it for anything other than GDB unless
+ you know what you are doing. */
+
+struct _user_psw_struct
+{
+ unsigned long mask;
+ unsigned long addr;
+};
+
+struct _user_fpregs_struct
+{
+ unsigned int fpc;
+ double fprs[16];
+};
+
+struct _user_per_struct
+{
+ unsigned long control_regs[3];
+ unsigned single_step : 1;
+ unsigned instruction_fetch : 1;
+ unsigned : 30;
+ unsigned long starting_addr;
+ unsigned long ending_addr;
+ unsigned short perc_atmid;
+ unsigned long address;
+ unsigned char access_id;
+};
+
+struct _user_regs_struct
+{
+ struct _user_psw_struct psw; /* Program status word. */
+ unsigned long gprs[16]; /* General purpose registers. */
+ unsigned int acrs[16]; /* Access registers. */
+ unsigned long orig_gpr2; /* Original gpr2. */
+ struct _user_fpregs_struct fp_regs; /* Floating point registers. */
+ struct _user_per_struct per_info; /* Hardware tracing registers. */
+ unsigned long ieee_instruction_pointer;
+};
+
+struct user {
+ struct _user_regs_struct regs; /* User registers. */
+ unsigned long int u_tsize; /* Text segment size (pages). */
+ unsigned long int u_dsize; /* Data segment size (pages). */
+ unsigned long int u_ssize; /* Stack segment size (pages). */
+ unsigned long start_code; /* Starting address of text. */
+ unsigned long start_stack; /* Starting address of stack area. */
+ long int signal; /* Signal causing the core dump. */
+ struct _user_regs_struct *u_ar0; /* Help gdb find registers. */
+ unsigned long magic; /* Identifies a core file. */
+ char u_comm[32]; /* User command naem. */
+};
+
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif /* _SYS_USER_H */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/system.c b/libc/sysdeps/unix/sysv/linux/s390/system.c
new file mode 100644
index 000000000..13a1331ad
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/system.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <kernel-features.h>
+
+/* We have to and actually can handle cancelable system(). The big
+ problem: we have to kill the child process if necessary. To do
+ this a cleanup handler has to be registered and is has to be able
+ to find the PID of the child. The main problem is to reliable have
+ the PID when needed. It is not necessary for the parent thread to
+ return. It might still be in the kernel when the cancellation
+ request comes. Therefore we have to use the clone() calls ability
+ to have the kernel write the PID into the user-level variable. */
+#ifdef __ASSUME_CLONE_THREAD_FLAGS
+# define FORK() \
+ INLINE_SYSCALL (clone, 3, 0, CLONE_PARENT_SETTID | SIGCHLD, &pid)
+#endif
+
+#include "../system.c"
diff --git a/libc/sysdeps/unix/sysv/linux/s390/ucontext_i.sym b/libc/sysdeps/unix/sysv/linux/s390/ucontext_i.sym
new file mode 100644
index 000000000..525b54300
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/ucontext_i.sym
@@ -0,0 +1,23 @@
+#include <stddef.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+--
+
+SIG_BLOCK
+SIG_UNBLOCK
+SIG_SETMASK
+
+#define ucontext(member) offsetof (ucontext_t, member)
+#define mcontext(member) ucontext (uc_mcontext.member)
+
+SC_FLGS ucontext (uc_flags)
+SC_LINK ucontext (uc_link)
+SC_STCK ucontext (uc_stack.ss_sp)
+SC_STSZ ucontext (uc_stack.ss_size)
+SC_PSW mcontext (psw)
+SC_GPRS mcontext (gregs)
+SC_ACRS mcontext (aregs)
+SC_FPC mcontext (fpregs.fpc)
+SC_FPRS mcontext (fpregs.fprs)
+SC_MASK ucontext (uc_sigmask)
diff --git a/libc/sysdeps/unix/sysv/linux/sa_len.c b/libc/sysdeps/unix/sysv/linux/sa_len.c
new file mode 100644
index 000000000..ae5616bf4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sa_len.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/socket.h>
+
+#include <netash/ash.h>
+#include <netatalk/at.h>
+#include <netax25/ax25.h>
+#include <neteconet/ec.h>
+#include <netinet/in.h>
+#include <netipx/ipx.h>
+#include <netpacket/packet.h>
+#include <netrose/rose.h>
+#include <sys/un.h>
+
+int
+__libc_sa_len (sa_family_t af)
+{
+ switch (af)
+ {
+ case AF_APPLETALK:
+ return sizeof (struct sockaddr_at);
+ case AF_ASH:
+ return sizeof (struct sockaddr_ash);
+ case AF_AX25:
+ return sizeof (struct sockaddr_ax25);
+ case AF_ECONET:
+ return sizeof (struct sockaddr_ec);
+ case AF_INET:
+ return sizeof (struct sockaddr_in);
+ case AF_INET6:
+ return sizeof (struct sockaddr_in6);
+ case AF_IPX:
+ return sizeof (struct sockaddr_ipx);
+ case AF_LOCAL:
+ return sizeof (struct sockaddr_un);
+ case AF_PACKET:
+ return sizeof (struct sockaddr_ll);
+ case AF_ROSE:
+ return sizeof (struct sockaddr_rose);
+ }
+ return 0;
+}
+INTDEF(__libc_sa_len)
diff --git a/libc/sysdeps/unix/sysv/linux/sched_getaffinity.c b/libc/sysdeps/unix/sysv/linux/sched_getaffinity.c
new file mode 100644
index 000000000..ab171123b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sched_getaffinity.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sched.h>
+#include <string.h>
+#include <sysdep.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <shlib-compat.h>
+
+
+#ifdef __NR_sched_getaffinity
+int
+__sched_getaffinity_new (pid_t pid, size_t cpusetsize, cpu_set_t *cpuset)
+{
+ int res = INLINE_SYSCALL (sched_getaffinity, 3, pid,
+ MIN (INT_MAX, cpusetsize), cpuset);
+ if (res != -1)
+ {
+ /* Clean the rest of the memory the kernel didn't do. */
+ memset ((char *) cpuset + res, '\0', cpusetsize - res);
+
+ res = 0;
+ }
+ return res;
+}
+versioned_symbol (libc, __sched_getaffinity_new, sched_getaffinity,
+ GLIBC_2_3_4);
+
+
+# if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)
+int
+attribute_compat_text_section
+__sched_getaffinity_old (pid_t pid, cpu_set_t *cpuset)
+{
+ /* The old interface by default assumed a 1024 processor bitmap. */
+ return __sched_getaffinity_new (pid, 128, cpuset);
+}
+compat_symbol (libc, __sched_getaffinity_old, sched_getaffinity, GLIBC_2_3_3);
+# endif
+#else
+# include <posix/sched_getaffinity.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sched_setaffinity.c b/libc/sysdeps/unix/sysv/linux/sched_setaffinity.c
new file mode 100644
index 000000000..ccd3c8f51
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sched_setaffinity.c
@@ -0,0 +1,88 @@
+/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sched.h>
+#include <string.h>
+#include <sysdep.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <shlib-compat.h>
+#include <alloca.h>
+
+
+#ifdef __NR_sched_setaffinity
+static size_t __kernel_cpumask_size;
+
+
+int
+__sched_setaffinity_new (pid_t pid, size_t cpusetsize, const cpu_set_t *cpuset)
+{
+ if (__builtin_expect (__kernel_cpumask_size == 0, 0))
+ {
+ INTERNAL_SYSCALL_DECL (err);
+ int res;
+
+ size_t psize = 128;
+ void *p = alloca (psize);
+
+ while (res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, getpid (),
+ psize, p),
+ INTERNAL_SYSCALL_ERROR_P (res, err)
+ && INTERNAL_SYSCALL_ERRNO (res, err) == EINVAL)
+ p = extend_alloca (p, psize, 2 * psize);
+
+ if (res == 0 || INTERNAL_SYSCALL_ERROR_P (res, err))
+ {
+ __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
+ return -1;
+ }
+
+ __kernel_cpumask_size = res;
+ }
+
+ /* We now know the size of the kernel cpumask_t. Make sure the user
+ does not request to set a bit beyond that. */
+ for (size_t cnt = __kernel_cpumask_size; cnt < cpusetsize; ++cnt)
+ if (((char *) cpuset)[cnt] != '\0')
+ {
+ /* Found a nonzero byte. This means the user request cannot be
+ fulfilled. */
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return INLINE_SYSCALL (sched_setaffinity, 3, pid, cpusetsize, cpuset);
+}
+versioned_symbol (libc, __sched_setaffinity_new, sched_setaffinity,
+ GLIBC_2_3_4);
+
+
+# if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)
+int
+attribute_compat_text_section
+__sched_setaffinity_old (pid_t pid, const cpu_set_t *cpuset)
+{
+ /* The old interface by default assumed a 1024 processor bitmap. */
+ return __sched_setaffinity_new (pid, 128, cpuset);
+}
+compat_symbol (libc, __sched_setaffinity_old, sched_setaffinity, GLIBC_2_3_3);
+# endif
+#else
+# include <posix/sched_setaffinity.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/scsi/scsi.h b/libc/sysdeps/unix/sysv/linux/scsi/scsi.h
new file mode 100644
index 000000000..49ab75806
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/scsi/scsi.h
@@ -0,0 +1,226 @@
+/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * This header file contains public constants and structures used by
+ * the scsi code for linux.
+ */
+
+#ifndef _SCSI_SCSI_H
+#define _SCSI_SCSI_H 1
+
+#include <features.h>
+
+/*
+ * SCSI opcodes
+ */
+
+#define TEST_UNIT_READY 0x00
+#define REZERO_UNIT 0x01
+#define REQUEST_SENSE 0x03
+#define FORMAT_UNIT 0x04
+#define READ_BLOCK_LIMITS 0x05
+#define REASSIGN_BLOCKS 0x07
+#define READ_6 0x08
+#define WRITE_6 0x0a
+#define SEEK_6 0x0b
+#define READ_REVERSE 0x0f
+#define WRITE_FILEMARKS 0x10
+#define SPACE 0x11
+#define INQUIRY 0x12
+#define RECOVER_BUFFERED_DATA 0x14
+#define MODE_SELECT 0x15
+#define RESERVE 0x16
+#define RELEASE 0x17
+#define COPY 0x18
+#define ERASE 0x19
+#define MODE_SENSE 0x1a
+#define START_STOP 0x1b
+#define RECEIVE_DIAGNOSTIC 0x1c
+#define SEND_DIAGNOSTIC 0x1d
+#define ALLOW_MEDIUM_REMOVAL 0x1e
+
+#define SET_WINDOW 0x24
+#define READ_CAPACITY 0x25
+#define READ_10 0x28
+#define WRITE_10 0x2a
+#define SEEK_10 0x2b
+#define WRITE_VERIFY 0x2e
+#define VERIFY 0x2f
+#define SEARCH_HIGH 0x30
+#define SEARCH_EQUAL 0x31
+#define SEARCH_LOW 0x32
+#define SET_LIMITS 0x33
+#define PRE_FETCH 0x34
+#define READ_POSITION 0x34
+#define SYNCHRONIZE_CACHE 0x35
+#define LOCK_UNLOCK_CACHE 0x36
+#define READ_DEFECT_DATA 0x37
+#define MEDIUM_SCAN 0x38
+#define COMPARE 0x39
+#define COPY_VERIFY 0x3a
+#define WRITE_BUFFER 0x3b
+#define READ_BUFFER 0x3c
+#define UPDATE_BLOCK 0x3d
+#define READ_LONG 0x3e
+#define WRITE_LONG 0x3f
+#define CHANGE_DEFINITION 0x40
+#define WRITE_SAME 0x41
+#define READ_TOC 0x43
+#define LOG_SELECT 0x4c
+#define LOG_SENSE 0x4d
+#define MODE_SELECT_10 0x55
+#define RESERVE_10 0x56
+#define RELEASE_10 0x57
+#define MODE_SENSE_10 0x5a
+#define PERSISTENT_RESERVE_IN 0x5e
+#define PERSISTENT_RESERVE_OUT 0x5f
+#define MOVE_MEDIUM 0xa5
+#define READ_12 0xa8
+#define WRITE_12 0xaa
+#define WRITE_VERIFY_12 0xae
+#define SEARCH_HIGH_12 0xb0
+#define SEARCH_EQUAL_12 0xb1
+#define SEARCH_LOW_12 0xb2
+#define READ_ELEMENT_STATUS 0xb8
+#define SEND_VOLUME_TAG 0xb6
+#define WRITE_LONG_2 0xea
+
+/*
+ * Status codes
+ */
+
+#define GOOD 0x00
+#define CHECK_CONDITION 0x01
+#define CONDITION_GOOD 0x02
+#define BUSY 0x04
+#define INTERMEDIATE_GOOD 0x08
+#define INTERMEDIATE_C_GOOD 0x0a
+#define RESERVATION_CONFLICT 0x0c
+#define COMMAND_TERMINATED 0x11
+#define QUEUE_FULL 0x14
+
+#define STATUS_MASK 0x3e
+
+/*
+ * SENSE KEYS
+ */
+
+#define NO_SENSE 0x00
+#define RECOVERED_ERROR 0x01
+#define NOT_READY 0x02
+#define MEDIUM_ERROR 0x03
+#define HARDWARE_ERROR 0x04
+#define ILLEGAL_REQUEST 0x05
+#define UNIT_ATTENTION 0x06
+#define DATA_PROTECT 0x07
+#define BLANK_CHECK 0x08
+#define COPY_ABORTED 0x0a
+#define ABORTED_COMMAND 0x0b
+#define VOLUME_OVERFLOW 0x0d
+#define MISCOMPARE 0x0e
+
+
+/*
+ * DEVICE TYPES
+ */
+
+#define TYPE_DISK 0x00
+#define TYPE_TAPE 0x01
+#define TYPE_PROCESSOR 0x03 /* HP scanners use this */
+#define TYPE_WORM 0x04 /* Treated as ROM by our system */
+#define TYPE_ROM 0x05
+#define TYPE_SCANNER 0x06
+#define TYPE_MOD 0x07 /* Magneto-optical disk -
+ * - treated as TYPE_DISK */
+#define TYPE_MEDIUM_CHANGER 0x08
+#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */
+#define TYPE_NO_LUN 0x7f
+
+/*
+ * standard mode-select header prepended to all mode-select commands
+ *
+ * moved here from cdrom.h -- kraxel
+ */
+
+struct ccs_modesel_head
+ {
+ unsigned char _r1; /* reserved. */
+ unsigned char medium; /* device-specific medium type. */
+ unsigned char _r2; /* reserved. */
+ unsigned char block_desc_length; /* block descriptor length. */
+ unsigned char density; /* device-specific density code. */
+ unsigned char number_blocks_hi; /* number of blocks in this block
+ desc. */
+ unsigned char number_blocks_med;
+ unsigned char number_blocks_lo;
+ unsigned char _r3;
+ unsigned char block_length_hi; /* block length for blocks in this
+ desc. */
+ unsigned char block_length_med;
+ unsigned char block_length_lo;
+ };
+
+/*
+ * MESSAGE CODES
+ */
+
+#define COMMAND_COMPLETE 0x00
+#define EXTENDED_MESSAGE 0x01
+#define EXTENDED_MODIFY_DATA_POINTER 0x00
+#define EXTENDED_SDTR 0x01
+#define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */
+#define EXTENDED_WDTR 0x03
+#define SAVE_POINTERS 0x02
+#define RESTORE_POINTERS 0x03
+#define DISCONNECT 0x04
+#define INITIATOR_ERROR 0x05
+#define ABORT 0x06
+#define MESSAGE_REJECT 0x07
+#define NOP 0x08
+#define MSG_PARITY_ERROR 0x09
+#define LINKED_CMD_COMPLETE 0x0a
+#define LINKED_FLG_CMD_COMPLETE 0x0b
+#define BUS_DEVICE_RESET 0x0c
+
+#define INITIATE_RECOVERY 0x0f /* SCSI-II only */
+#define RELEASE_RECOVERY 0x10 /* SCSI-II only */
+
+#define SIMPLE_QUEUE_TAG 0x20
+#define HEAD_OF_QUEUE_TAG 0x21
+#define ORDERED_QUEUE_TAG 0x22
+
+/*
+ * Here are some scsi specific ioctl commands which are sometimes useful.
+ */
+/* These are a few other constants only used by scsi devices. */
+
+#define SCSI_IOCTL_GET_IDLUN 0x5382
+
+/* Used to turn on and off tagged queuing for scsi devices. */
+
+#define SCSI_IOCTL_TAGGED_ENABLE 0x5383
+#define SCSI_IOCTL_TAGGED_DISABLE 0x5384
+
+/* Used to obtain the host number of a device. */
+#define SCSI_IOCTL_PROBE_HOST 0x5385
+
+/* Used to get the bus number for a device. */
+#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386
+
+#endif /* scsi/scsi.h */
diff --git a/libc/sysdeps/unix/sysv/linux/scsi/scsi_ioctl.h b/libc/sysdeps/unix/sysv/linux/scsi/scsi_ioctl.h
new file mode 100644
index 000000000..11f016179
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/scsi/scsi_ioctl.h
@@ -0,0 +1,34 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SCSI_IOCTL_H
+#define _SCSI_IOCTL_H
+
+/* IOCTLs for SCSI. */
+#define SCSI_IOCTL_SEND_COMMAND 1 /* Send a command to the SCSI host. */
+#define SCSI_IOCTL_TEST_UNIT_READY 2 /* Test if unit is ready. */
+#define SCSI_IOCTL_BENCHMARK_COMMAND 3
+#define SCSI_IOCTL_SYNC 4 /* Request synchronous parameters. */
+#define SCSI_IOCTL_START_UNIT 5
+#define SCSI_IOCTL_STOP_UNIT 6
+#define SCSI_IOCTL_DOORLOCK 0x5380 /* Lock the eject mechanism. */
+#define SCSI_IOCTL_DOORUNLOCK 0x5381 /* Unlock the mechanism. */
+
+#endif
+
+
diff --git a/libc/sysdeps/unix/sysv/linux/scsi/sg.h b/libc/sysdeps/unix/sysv/linux/scsi/sg.h
new file mode 100644
index 000000000..b0dc0ad7d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/scsi/sg.h
@@ -0,0 +1,275 @@
+/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ History:
+ Started: Aug 9 by Lawrence Foard (entropy@world.std.com), to allow user
+ process control of SCSI devices.
+ Development Sponsored by Killy Corp. NY NY
+*/
+
+#ifndef _SCSI_SG_H
+#define _SCSI_SG_H 1
+
+#include <features.h>
+
+
+/* New interface introduced in the 3.x SG drivers follows */
+
+/* Same structure as used by readv() Linux system call. It defines one
+ scatter-gather element. */
+typedef struct sg_iovec
+{
+ void * iov_base; /* Starting address */
+ size_t iov_len; /* Length in bytes */
+} sg_iovec_t;
+
+
+typedef struct sg_io_hdr
+{
+ int interface_id; /* [i] 'S' for SCSI generic (required) */
+ int dxfer_direction; /* [i] data transfer direction */
+ unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
+ unsigned char mx_sb_len; /* [i] max length to write to sbp */
+ unsigned short int iovec_count; /* [i] 0 implies no scatter gather */
+ unsigned int dxfer_len; /* [i] byte count of data transfer */
+ void * dxferp; /* [i], [*io] points to data transfer memory
+ or scatter gather list */
+ unsigned char * cmdp; /* [i], [*i] points to command to perform */
+ unsigned char * sbp; /* [i], [*o] points to sense_buffer memory */
+ unsigned int timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
+ unsigned int flags; /* [i] 0 -> default, see SG_FLAG... */
+ int pack_id; /* [i->o] unused internally (normally) */
+ void * usr_ptr; /* [i->o] unused internally */
+ unsigned char status; /* [o] scsi status */
+ unsigned char masked_status;/* [o] shifted, masked scsi status */
+ unsigned char msg_status; /* [o] messaging level data (optional) */
+ unsigned char sb_len_wr; /* [o] byte count actually written to sbp */
+ unsigned short int host_status; /* [o] errors from host adapter */
+ unsigned short int driver_status;/* [o] errors from software driver */
+ int resid; /* [o] dxfer_len - actual_transferred */
+ unsigned int duration; /* [o] time taken by cmd (unit: millisec) */
+ unsigned int info; /* [o] auxiliary information */
+} sg_io_hdr_t;
+
+
+/* Use negative values to flag difference from original sg_header structure. */
+#define SG_DXFER_NONE -1 /* e.g. a SCSI Test Unit Ready command */
+#define SG_DXFER_TO_DEV -2 /* e.g. a SCSI WRITE command */
+#define SG_DXFER_FROM_DEV -3 /* e.g. a SCSI READ command */
+#define SG_DXFER_TO_FROM_DEV -4 /* treated like SG_DXFER_FROM_DEV with the
+ additional property than during indirect
+ IO the user buffer is copied into the
+ kernel buffers before the transfer */
+
+
+/* following flag values can be "or"-ed together */
+#define SG_FLAG_DIRECT_IO 1 /* default is indirect IO */
+#define SG_FLAG_LUN_INHIBIT 2 /* default is to put device's lun into */
+ /* the 2nd byte of SCSI command */
+#define SG_FLAG_NO_DXFER 0x10000 /* no transfer of kernel buffers to/from */
+ /* user space (debug indirect IO) */
+
+/* The following 'info' values are "or"-ed together. */
+#define SG_INFO_OK_MASK 0x1
+#define SG_INFO_OK 0x0 /* no sense, host nor driver "noise" */
+#define SG_INFO_CHECK 0x1 /* something abnormal happened */
+
+#define SG_INFO_DIRECT_IO_MASK 0x6
+#define SG_INFO_INDIRECT_IO 0x0 /* data xfer via kernel buffers (or no xfer) */
+#define SG_INFO_DIRECT_IO 0x2 /* direct IO requested and performed */
+#define SG_INFO_MIXED_IO 0x4 /* part direct, part indirect IO */
+
+
+/* Request information about a specific SG device, used by
+ SG_GET_SCSI_ID ioctl (). */
+struct sg_scsi_id {
+ /* Host number as in "scsi<n>" where 'n' is one of 0, 1, 2 etc. */
+ int host_no;
+ int channel;
+ /* SCSI id of target device. */
+ int scsi_id;
+ int lun;
+ /* TYPE_... defined in <scsi/scsi.h>. */
+ int scsi_type;
+ /* Host (adapter) maximum commands per lun. */
+ short int h_cmd_per_lun;
+ /* Device (or adapter) maximum queue length. */
+ short int d_queue_depth;
+ /* Unused, set to 0 for now. */
+ int unused[2];
+};
+
+/* Used by SG_GET_REQUEST_TABLE ioctl(). */
+typedef struct sg_req_info {
+ char req_state; /* 0 -> not used, 1 -> written, 2 -> ready to read */
+ char orphan; /* 0 -> normal request, 1 -> from interruped SG_IO */
+ char sg_io_owned; /* 0 -> complete with read(), 1 -> owned by SG_IO */
+ char problem; /* 0 -> no problem detected, 1 -> error to report */
+ int pack_id; /* pack_id associated with request */
+ void * usr_ptr; /* user provided pointer (in new interface) */
+ unsigned int duration; /* millisecs elapsed since written (req_state==1)
+ or request duration (req_state==2) */
+ int unused;
+} sg_req_info_t;
+
+
+/* IOCTLs: Those ioctls that are relevant to the SG 3.x drivers follow.
+ [Those that only apply to the SG 2.x drivers are at the end of the file.]
+ (_GET_s yield result via 'int *' 3rd argument unless otherwise indicated) */
+
+#define SG_EMULATED_HOST 0x2203 /* true for emulated host adapter (ATAPI) */
+
+/* Used to configure SCSI command transformation layer for ATAPI devices */
+/* Only supported by the ide-scsi driver */
+#define SG_SET_TRANSFORM 0x2204 /* N.B. 3rd arg is not pointer but value: */
+ /* 3rd arg = 0 to disable transform, 1 to enable it */
+#define SG_GET_TRANSFORM 0x2205
+
+#define SG_SET_RESERVED_SIZE 0x2275 /* request a new reserved buffer size */
+#define SG_GET_RESERVED_SIZE 0x2272 /* actual size of reserved buffer */
+
+/* The following ioctl has a 'sg_scsi_id_t *' object as its 3rd argument. */
+#define SG_GET_SCSI_ID 0x2276 /* Yields fd's bus, chan, dev, lun + type */
+/* SCSI id information can also be obtained from SCSI_IOCTL_GET_IDLUN */
+
+/* Override host setting and always DMA using low memory ( <16MB on i386) */
+#define SG_SET_FORCE_LOW_DMA 0x2279 /* 0-> use adapter setting, 1-> force */
+#define SG_GET_LOW_DMA 0x227a /* 0-> use all ram for dma; 1-> low dma ram */
+
+/* When SG_SET_FORCE_PACK_ID set to 1, pack_id is input to read() which
+ tries to fetch a packet with a matching pack_id, waits, or returns EAGAIN.
+ If pack_id is -1 then read oldest waiting. When ...FORCE_PACK_ID set to 0
+ then pack_id ignored by read() and oldest readable fetched. */
+#define SG_SET_FORCE_PACK_ID 0x227b
+#define SG_GET_PACK_ID 0x227c /* Yields oldest readable pack_id (or -1) */
+
+#define SG_GET_NUM_WAITING 0x227d /* Number of commands awaiting read() */
+
+/* Yields max scatter gather tablesize allowed by current host adapter */
+#define SG_GET_SG_TABLESIZE 0x227F /* 0 implies can't do scatter gather */
+
+#define SG_GET_VERSION_NUM 0x2282 /* Example: version 2.1.34 yields 20134 */
+
+/* Returns -EBUSY if occupied. 3rd argument pointer to int (see next) */
+#define SG_SCSI_RESET 0x2284
+/* Associated values that can be given to SG_SCSI_RESET follow */
+#define SG_SCSI_RESET_NOTHING 0
+#define SG_SCSI_RESET_DEVICE 1
+#define SG_SCSI_RESET_BUS 2
+#define SG_SCSI_RESET_HOST 3
+
+/* synchronous SCSI command ioctl, (only in version 3 interface) */
+#define SG_IO 0x2285 /* similar effect as write() followed by read() */
+
+#define SG_GET_REQUEST_TABLE 0x2286 /* yields table of active requests */
+
+/* How to treat EINTR during SG_IO ioctl(), only in SG 3.x series */
+#define SG_SET_KEEP_ORPHAN 0x2287 /* 1 -> hold for read(), 0 -> drop (def) */
+#define SG_GET_KEEP_ORPHAN 0x2288
+
+
+#define SG_SCATTER_SZ (8 * 4096) /* PAGE_SIZE not available to user */
+/* Largest size (in bytes) a single scatter-gather list element can have.
+ The value must be a power of 2 and <= (PAGE_SIZE * 32) [131072 bytes on
+ i386]. The minimum value is PAGE_SIZE. If scatter-gather not supported
+ by adapter then this value is the largest data block that can be
+ read/written by a single scsi command. The user can find the value of
+ PAGE_SIZE by calling getpagesize() defined in unistd.h . */
+
+#define SG_DEFAULT_RETRIES 1
+
+/* Defaults, commented if they differ from original sg driver */
+#define SG_DEF_FORCE_LOW_DMA 0 /* was 1 -> memory below 16MB on i386 */
+#define SG_DEF_FORCE_PACK_ID 0
+#define SG_DEF_KEEP_ORPHAN 0
+#define SG_DEF_RESERVED_SIZE SG_SCATTER_SZ /* load time option */
+
+/* maximum outstanding requests, write() yields EDOM if exceeded */
+#define SG_MAX_QUEUE 16
+
+#define SG_BIG_BUFF SG_DEF_RESERVED_SIZE /* for backward compatibility */
+
+/* Alternate style type names, "..._t" variants preferred */
+typedef struct sg_io_hdr Sg_io_hdr;
+typedef struct sg_io_vec Sg_io_vec;
+typedef struct sg_scsi_id Sg_scsi_id;
+typedef struct sg_req_info Sg_req_info;
+
+
+/* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */
+/* The older SG interface based on the 'sg_header' structure follows. */
+/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
+
+#define SG_MAX_SENSE 16 /* this only applies to the sg_header interface */
+
+struct sg_header
+ {
+ /* Length of incoming packet (including header). */
+ int pack_len;
+ /* Maximal length of expected reply. */
+ int reply_len;
+ /* Id number of packet. */
+ int pack_id;
+ /* 0==ok, otherwise error number. */
+ int result;
+ /* Force 12 byte command length for group 6 & 7 commands. */
+ unsigned int twelve_byte:1;
+ /* SCSI status from target. */
+ unsigned int target_status:5;
+ /* Host status (see "DID" codes). */
+ unsigned int host_status:8;
+ /* Driver status+suggestion. */
+ unsigned int driver_status:8;
+ /* Unused. */
+ unsigned int other_flags:10;
+ /* Output in 3 cases:
+ when target_status is CHECK_CONDITION or
+ when target_status is COMMAND_TERMINATED or
+ when (driver_status & DRIVER_SENSE) is true. */
+ unsigned char sense_buffer[SG_MAX_SENSE];
+ };
+
+
+/* IOCTLs: The following are not required (or ignored) when the sg_io_hdr_t
+ interface is used. They are kept for backward compatibility with
+ the original and version 2 drivers. */
+
+#define SG_SET_TIMEOUT 0x2201 /* Set timeout; *(int *)arg==timeout. */
+#define SG_GET_TIMEOUT 0x2202 /* Get timeout; return timeout. */
+
+/* Get/set command queuing state per fd (default is SG_DEF_COMMAND_Q). */
+#define SG_GET_COMMAND_Q 0x2270 /* Yields 0 (queuing off) or 1 (on). */
+#define SG_SET_COMMAND_Q 0x2271 /* Change queuing state with 0 or 1. */
+
+/* Turn on error sense trace (1..8), dump this device to log/console (9)
+ or dump all sg device states ( >9 ) to log/console. */
+#define SG_SET_DEBUG 0x227e /* 0 -> turn off debug */
+
+#define SG_NEXT_CMD_LEN 0x2283 /* Override SCSI command length with given
+ number on the next write() on this file
+ descriptor. */
+
+/* Defaults, commented if they differ from original sg driver */
+#define SG_DEFAULT_TIMEOUT (60*HZ) /* HZ == 'jiffies in 1 second' */
+#define SG_DEF_COMMAND_Q 0 /* command queuing is always on when
+ the new interface is used */
+#define SG_DEF_UNDERRUN_FLAG 0
+
+
+#endif /* scsi/sg.h */
diff --git a/libc/sysdeps/unix/sysv/linux/segfault.c b/libc/sysdeps/unix/sysv/linux/segfault.c
new file mode 100644
index 000000000..a417df9c4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/segfault.c
@@ -0,0 +1,2 @@
+#define HAVE_PROC_SELF 1
+#include <debug/segfault.c>
diff --git a/libc/sysdeps/unix/sysv/linux/semctl.c b/libc/sysdeps/unix/sysv/linux/semctl.c
new file mode 100644
index 000000000..2f5471f8f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/semctl.c
@@ -0,0 +1,192 @@
+/* Copyright (C) 1995,1997,1998,2000,2003,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/sem.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <shlib-compat.h>
+
+#include <kernel-features.h>
+
+struct __old_semid_ds
+{
+ struct __old_ipc_perm sem_perm; /* operation permission struct */
+ __time_t sem_otime; /* last semop() time */
+ __time_t sem_ctime; /* last time changed by semctl() */
+ struct sem *__unbounded __sembase; /* ptr to first semaphore in array */
+ struct sem_queue *__unbounded __sem_pending; /* pending operations */
+ struct sem_queue *__unbounded __sem_pending_last; /* last pending operation */
+ struct sem_undo *__unbounded __undo; /* ondo requests on this array */
+ unsigned short int sem_nsems; /* number of semaphores in set */
+};
+
+/* Define a `union semun' suitable for Linux here. */
+union semun
+{
+ int val; /* value for SETVAL */
+ struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
+ unsigned short int *array; /* array for GETALL & SETALL */
+ struct seminfo *__buf; /* buffer for IPC_INFO */
+ struct __old_semid_ds *__old_buf;
+};
+
+#include <bp-checks.h>
+#include <bp-semctl.h> /* definition of CHECK_SEMCTL needs union semum */
+
+/* Return identifier for array of NSEMS semaphores associated with
+ KEY. */
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int __old_semctl (int semid, int semnum, int cmd, ...);
+#endif
+int __new_semctl (int semid, int semnum, int cmd, ...);
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int
+attribute_compat_text_section
+__old_semctl (int semid, int semnum, int cmd, ...)
+{
+ union semun arg;
+ va_list ap;
+
+ va_start (ap, cmd);
+
+ /* Get the argument only if required. */
+ arg.buf = NULL;
+ switch (cmd)
+ {
+ case SETVAL: /* arg.val */
+ case GETALL: /* arg.array */
+ case SETALL:
+ case IPC_STAT: /* arg.buf */
+ case IPC_SET:
+ case SEM_STAT:
+ case IPC_INFO: /* arg.__buf */
+ case SEM_INFO:
+ va_start (ap, cmd);
+ arg = va_arg (ap, union semun);
+ va_end (ap);
+ break;
+ }
+
+ va_end (ap);
+
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
+ CHECK_SEMCTL (&arg, semid, cmd));
+}
+compat_symbol (libc, __old_semctl, semctl, GLIBC_2_0);
+#endif
+
+int
+__new_semctl (int semid, int semnum, int cmd, ...)
+{
+ union semun arg;
+ va_list ap;
+
+ va_start (ap, cmd);
+
+ /* Get the argument only if required. */
+ arg.buf = NULL;
+ switch (cmd)
+ {
+ case SETVAL: /* arg.val */
+ case GETALL: /* arg.array */
+ case SETALL:
+ case IPC_STAT: /* arg.buf */
+ case IPC_SET:
+ case SEM_STAT:
+ case IPC_INFO: /* arg.__buf */
+ case SEM_INFO:
+ va_start (ap, cmd);
+ arg = va_arg (ap, union semun);
+ va_end (ap);
+ break;
+ }
+
+ va_end (ap);
+
+#if __ASSUME_IPC64 > 0
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd | __IPC_64,
+ CHECK_SEMCTL (&arg, semid, cmd | __IPC_64));
+#else
+ switch (cmd)
+ {
+ case SEM_STAT:
+ case IPC_STAT:
+ case IPC_SET:
+ break;
+ default:
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
+ CHECK_SEMCTL (&arg, semid, cmd));
+ }
+
+ {
+ int save_errno = errno, result;
+ struct __old_semid_ds old;
+ struct semid_ds *buf;
+
+ /* Unfortunately there is no way how to find out for sure whether
+ we should use old or new semctl. */
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd | __IPC_64,
+ CHECK_SEMCTL (&arg, semid, cmd | __IPC_64));
+ if (result != -1 || errno != EINVAL)
+ return result;
+
+ __set_errno(save_errno);
+ buf = arg.buf;
+ arg.__old_buf = &old;
+ if (cmd == IPC_SET)
+ {
+ old.sem_perm.uid = buf->sem_perm.uid;
+ old.sem_perm.gid = buf->sem_perm.gid;
+ old.sem_perm.mode = buf->sem_perm.mode;
+ if (old.sem_perm.uid != buf->sem_perm.uid ||
+ old.sem_perm.gid != buf->sem_perm.gid)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ }
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
+ CHECK_SEMCTL (&arg, semid, cmd));
+ if (result != -1 && cmd != IPC_SET)
+ {
+ memset(buf, 0, sizeof(*buf));
+ buf->sem_perm.__key = old.sem_perm.__key;
+ buf->sem_perm.uid = old.sem_perm.uid;
+ buf->sem_perm.gid = old.sem_perm.gid;
+ buf->sem_perm.cuid = old.sem_perm.cuid;
+ buf->sem_perm.cgid = old.sem_perm.cgid;
+ buf->sem_perm.mode = old.sem_perm.mode;
+ buf->sem_perm.__seq = old.sem_perm.__seq;
+ buf->sem_otime = old.sem_otime;
+ buf->sem_ctime = old.sem_ctime;
+ buf->sem_nsems = old.sem_nsems;
+ }
+ return result;
+ }
+#endif
+}
+
+versioned_symbol (libc, __new_semctl, semctl, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/semget.c b/libc/sysdeps/unix/sysv/linux/semget.c
new file mode 100644
index 000000000..639bb0229
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/semget.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1995, 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/sem.h>
+#include <ipc_priv.h>
+#include <stdlib.h> /* for definition of NULL */
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Return identifier for array of NSEMS semaphores associated with
+ KEY. */
+
+int
+semget (key, nsems, semflg)
+ key_t key;
+ int nsems;
+ int semflg;
+{
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semget, key, nsems, semflg, NULL);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/semop.c b/libc/sysdeps/unix/sysv/linux/semop.c
new file mode 100644
index 000000000..4bf297661
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/semop.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1995, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/sem.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Perform user-defined atomical operation of array of semaphores. */
+
+int
+semop (semid, sops, nsops)
+ int semid;
+ struct sembuf *sops;
+ size_t nsops;
+{
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semop,
+ semid, (int) nsops, 0, CHECK_N (sops, nsops));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/semtimedop.c b/libc/sysdeps/unix/sysv/linux/semtimedop.c
new file mode 100644
index 000000000..b37284181
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/semtimedop.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1995, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/sem.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Perform user-defined atomical operation of array of semaphores. */
+
+int
+semtimedop (semid, sops, nsops, timeout)
+ int semid;
+ struct sembuf *sops;
+ size_t nsops;
+ const struct timespec *timeout;
+{
+ return INLINE_SYSCALL (ipc, 6, IPCOP_semtimedop,
+ semid, (int) nsops, 0, CHECK_N (sops, nsops),
+ timeout);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/send.S b/libc/sysdeps/unix/sysv/linux/send.S
new file mode 100644
index 000000000..259748f44
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/send.S
@@ -0,0 +1,7 @@
+#define socket send
+#define __socket __libc_send
+#define NARGS 4
+#define NEED_CANCELLATION
+#include <socket.S>
+weak_alias (__libc_send, __send)
+libc_hidden_def (__send)
diff --git a/libc/sysdeps/unix/sysv/linux/sendmsg.S b/libc/sysdeps/unix/sysv/linux/sendmsg.S
new file mode 100644
index 000000000..a220894cc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sendmsg.S
@@ -0,0 +1,6 @@
+#define socket sendmsg
+#define __socket __libc_sendmsg
+#define NARGS 3
+#define NEED_CANCELLATION
+#include <socket.S>
+weak_alias (__libc_sendmsg, __sendmsg)
diff --git a/libc/sysdeps/unix/sysv/linux/sendto.S b/libc/sysdeps/unix/sysv/linux/sendto.S
new file mode 100644
index 000000000..a65e44fb6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sendto.S
@@ -0,0 +1,6 @@
+#define socket sendto
+#define __socket __libc_sendto
+#define NARGS 6
+#define NEED_CANCELLATION
+#include <socket.S>
+weak_alias (__libc_sendto, __sendto)
diff --git a/libc/sysdeps/unix/sysv/linux/setegid.c b/libc/sysdeps/unix/sysv/linux/setegid.c
new file mode 100644
index 000000000..c0400aa12
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/setegid.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 1998,2000,2002,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+#include <kernel-features.h>
+
+
+#if defined __NR_setresgid || __ASSUME_SETRESGID_SYSCALL > 0
+
+extern int __setresgid (gid_t rgid, gid_t egid, gid_t sgid);
+
+int
+setegid (gid_t gid)
+{
+ int result;
+
+ if (gid == (gid_t) ~0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+# if __ASSUME_32BITUIDS > 0 && defined __NR_setresgid32
+ result = INLINE_SETXID_SYSCALL (setresgid32, 3, -1, gid, -1);
+# else
+ /* First try the syscall. */
+ result = INLINE_SETXID_SYSCALL (setresgid, 3, -1, gid, -1);
+# if __ASSUME_SETRESGID_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use emulation. This may not work
+ since `setregid' also sets the saved group ID when GID is not
+ equal to the real group ID, making it impossible to switch back. */
+ result = __setregid (-1, gid);
+# endif
+# endif
+
+ return result;
+}
+#ifndef setegid
+libc_hidden_def (setegid)
+#endif
+#else
+# include <sysdeps/unix/bsd/setegid.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/seteuid.c b/libc/sysdeps/unix/sysv/linux/seteuid.c
new file mode 100644
index 000000000..4a1a29eaa
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/seteuid.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 1998,1999,2002,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+#include <kernel-features.h>
+
+
+#if defined __NR_setresuid || __ASSUME_SETRESUID_SYSCALL > 0
+
+extern int __setresuid (uid_t ruid, uid_t euid, uid_t suid);
+
+int
+seteuid (uid_t uid)
+{
+ int result;
+
+ if (uid == (uid_t) ~0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+# if __ASSUME_32BITUIDS > 0 && defined __NR_setresuid32
+ result = INLINE_SETXID_SYSCALL (setresuid32, 3, -1, uid, -1);
+# else
+ /* First try the syscall. */
+ result = INLINE_SETXID_SYSCALL (setresuid, 3, -1, uid, -1);
+# if __ASSUME_SETRESUID_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use emulation. This may not work
+ since `setreuid' also sets the saved user ID when UID is not
+ equal to the real user ID, making it impossible to switch back. */
+ result = __setreuid (-1, uid);
+# endif
+# endif
+
+ return result;
+}
+#ifndef seteuid
+libc_hidden_def (seteuid)
+#endif
+#else
+# include <sysdeps/unix/bsd/seteuid.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/setgid.c b/libc/sysdeps/unix/sysv/linux/setgid.c
new file mode 100644
index 000000000..1411f5365
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/setgid.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+
+
+int
+__setgid (gid_t gid)
+{
+ return INLINE_SETXID_SYSCALL (setgid, 1, gid);
+}
+#ifndef __setgid
+weak_alias (__setgid, setgid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sethostid.c b/libc/sysdeps/unix/sysv/linux/sethostid.c
new file mode 100644
index 000000000..eb71b74a1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sethostid.c
@@ -0,0 +1,2 @@
+#define SET_PROCEDURE 1
+#include "gethostid.c"
diff --git a/libc/sysdeps/unix/sysv/linux/setipv4sourcefilter.c b/libc/sysdeps/unix/sysv/linux/setipv4sourcefilter.c
new file mode 100644
index 000000000..050d0a3e9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/setipv4sourcefilter.c
@@ -0,0 +1,65 @@
+/* Set IPv4 source filter. Linux version.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <alloca.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+
+int
+setipv4sourcefilter (int s, struct in_addr interface, struct in_addr group,
+ uint32_t fmode, uint32_t numsrc,
+ const struct in_addr *slist)
+{
+ /* We have to create an struct ip_msfilter object which we can pass
+ to the kernel. */
+ size_t needed = IP_MSFILTER_SIZE (numsrc);
+ int use_alloca = __libc_use_alloca (needed);
+
+ struct ip_msfilter *imsf;
+ if (use_alloca)
+ imsf = (struct ip_msfilter *) alloca (needed);
+ else
+ {
+ imsf = (struct ip_msfilter *) malloc (needed);
+ if (imsf == NULL)
+ return -1;
+ }
+
+ imsf->imsf_multiaddr = group;
+ imsf->imsf_interface = interface;
+ imsf->imsf_fmode = fmode;
+ imsf->imsf_numsrc = numsrc;
+ memcpy (imsf->imsf_slist, slist, numsrc * sizeof (struct in_addr));
+
+ int result = __setsockopt (s, SOL_IP, IP_MSFILTER, imsf, needed);
+
+ if (! use_alloca)
+ {
+ int save_errno = errno;
+ free (imsf);
+ __set_errno (save_errno);
+ }
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/setregid.c b/libc/sysdeps/unix/sysv/linux/setregid.c
new file mode 100644
index 000000000..df79eae91
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/setregid.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+
+
+int
+__setregid (gid_t rgid, gid_t egid)
+{
+ return INLINE_SETXID_SYSCALL (setregid, 2, rgid, egid);
+}
+#ifndef __setregid
+weak_alias (__setregid, setregid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/setresgid.c b/libc/sysdeps/unix/sysv/linux/setresgid.c
new file mode 100644
index 000000000..d6c9758d7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/setresgid.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+
+
+int
+__setresgid (gid_t rgid, gid_t egid, gid_t sgid)
+{
+ return INLINE_SETXID_SYSCALL (setresgid, 3, rgid, egid, sgid);
+}
+libc_hidden_def (__setresgid)
+#ifndef __setresgid
+weak_alias (__setresgid, setresgid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/setresuid.c b/libc/sysdeps/unix/sysv/linux/setresuid.c
new file mode 100644
index 000000000..e7feeefce
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/setresuid.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+
+
+int
+__setresuid (uid_t ruid, uid_t euid, uid_t suid)
+{
+ return INLINE_SETXID_SYSCALL (setresuid, 3, ruid, euid, suid);
+}
+libc_hidden_def (__setresuid)
+#ifndef __setresuid
+weak_alias (__setresuid, setresuid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/setreuid.c b/libc/sysdeps/unix/sysv/linux/setreuid.c
new file mode 100644
index 000000000..ce30d3c69
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/setreuid.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+
+
+int
+__setreuid (uid_t ruid, uid_t euid)
+{
+ return INLINE_SETXID_SYSCALL (setreuid, 2, ruid, euid);
+}
+#ifndef __setreuid
+weak_alias (__setreuid, setreuid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/setsockopt.S b/libc/sysdeps/unix/sysv/linux/setsockopt.S
new file mode 100644
index 000000000..4e40ccba5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/setsockopt.S
@@ -0,0 +1,5 @@
+#define socket setsockopt
+#define NARGS 5
+#define NO_WEAK_ALIAS 1
+#include <socket.S>
+weak_alias (setsockopt, __setsockopt)
diff --git a/libc/sysdeps/unix/sysv/linux/setsourcefilter.c b/libc/sysdeps/unix/sysv/linux/setsourcefilter.c
new file mode 100644
index 000000000..dc223de84
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/setsourcefilter.c
@@ -0,0 +1,78 @@
+/* Set source filter. Linux version.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <alloca.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+
+/* Defined in getsourcefilter.c. */
+extern int __get_sol (int af, socklen_t len);
+
+
+int
+setsourcefilter (int s, uint32_t interface, const struct sockaddr *group,
+ socklen_t grouplen, uint32_t fmode, uint32_t numsrc,
+ const struct sockaddr_storage *slist)
+{
+ /* We have to create an struct ip_msfilter object which we can pass
+ to the kernel. */
+ size_t needed = GROUP_FILTER_SIZE (numsrc);
+ int use_alloca = __libc_use_alloca (needed);
+
+ struct group_filter *gf;
+ if (use_alloca)
+ gf = (struct group_filter *) alloca (needed);
+ else
+ {
+ gf = (struct group_filter *) malloc (needed);
+ if (gf == NULL)
+ return -1;
+ }
+
+ gf->gf_interface = interface;
+ memcpy (&gf->gf_group, group, grouplen);
+ gf->gf_fmode = fmode;
+ gf->gf_numsrc = numsrc;
+ memcpy (gf->gf_slist, slist, numsrc * sizeof (struct sockaddr_storage));
+
+ /* We need to provide the appropriate socket level value. */
+ int result;
+ int sol = __get_sol (group->sa_family, grouplen);
+ if (sol == -1)
+ {
+ __set_errno (EINVAL);
+ result = -1;
+ }
+ else
+ result = __setsockopt (s, sol, MCAST_MSFILTER, gf, needed);
+
+ if (! use_alloca)
+ {
+ int save_errno = errno;
+ free (gf);
+ __set_errno (save_errno);
+ }
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/setuid.c b/libc/sysdeps/unix/sysv/linux/setuid.c
new file mode 100644
index 000000000..a523dfdbd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/setuid.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <setxid.h>
+
+int
+__setuid (uid_t uid)
+{
+ return INLINE_SETXID_SYSCALL (setuid, 1, uid);
+}
+#ifndef __setuid
+weak_alias (__setuid, setuid)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sh/Makefile b/libc/sysdeps/unix/sysv/linux/sh/Makefile
new file mode 100644
index 000000000..6d72cb029
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/Makefile
@@ -0,0 +1,11 @@
+ifeq ($(subdir),io)
+sysdep_routines += pipe
+endif
+
+ifeq ($(subdir),misc)
+sysdep_headers += sys/io.h
+endif
+
+ifeq ($(subdir),stdlib)
+gen-as-const-headers += ucontext_i.sym
+endif
diff --git a/libc/sysdeps/unix/sysv/linux/sh/Versions b/libc/sysdeps/unix/sysv/linux/sh/Versions
new file mode 100644
index 000000000..763be6022
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/Versions
@@ -0,0 +1,27 @@
+libc {
+ GLIBC_2.2 {
+ # functions used in other libraries
+ __xstat64; __fxstat64; __lxstat64;
+
+ # a*
+ alphasort64;
+
+ # g*
+ glob64;
+
+ # New rlimit interface
+ getrlimit; setrlimit; getrlimit64;
+
+ # r*
+ readdir64; readdir64_r;
+
+ # s*
+ scandir64;
+
+ # v*
+ versionsort64;
+ }
+ GLIBC_2.3.3 {
+ posix_fadvise64; posix_fallocate64;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sh/bits/atomic.h b/libc/sysdeps/unix/sysv/linux/sh/bits/atomic.h
new file mode 100644
index 000000000..a0e5918f0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/bits/atomic.h
@@ -0,0 +1,419 @@
+/* Atomic operations used inside libc. Linux/SH version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+/* SH kernel has implemented a gUSA ("g" User Space Atomicity) support
+ for the user space atomicity. The atomicity macros use this scheme.
+
+ Reference:
+ Niibe Yutaka, "gUSA: Simple and Efficient User Space Atomicity
+ Emulation with Little Kernel Modification", Linux Conference 2002,
+ Japan. http://lc.linux.or.jp/lc2002/papers/niibe0919h.pdf (in
+ Japanese).
+
+ B.N. Bershad, D. Redell, and J. Ellis, "Fast Mutual Exclusion for
+ Uniprocessors", Proceedings of the Fifth Architectural Support for
+ Programming Languages and Operating Systems (ASPLOS), pp. 223-233,
+ October 1992. http://www.cs.washington.edu/homes/bershad/Papers/Rcs.ps
+
+ SuperH ABI:
+ r15: -(size of atomic instruction sequence) < 0
+ r0: end point
+ r1: saved stack pointer
+*/
+
+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+ ({ __typeof (*(mem)) __result; \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.b @%1,%0\n\
+ cmp/eq %0,%3\n\
+ bf 1f\n\
+ mov.b %2,@%1\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
+ : "r0", "r1", "t", "memory"); \
+ __result; })
+
+#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+ ({ __typeof (*(mem)) __result; \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.w @%1,%0\n\
+ cmp/eq %0,%3\n\
+ bf 1f\n\
+ mov.w %2,@%1\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
+ : "r0", "r1", "t", "memory"); \
+ __result; })
+
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ ({ __typeof (*(mem)) __result; \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%1,%0\n\
+ cmp/eq %0,%3\n\
+ bf 1f\n\
+ mov.l %2,@%1\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
+ : "r0", "r1", "t", "memory"); \
+ __result; })
+
+/* XXX We do not really need 64-bit compare-and-exchange. At least
+ not in the moment. Using it would mean causing portability
+ problems since not many other 32-bit architectures have support for
+ such an operation. So don't define any code for now. */
+
+# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ (abort (), (__typeof (*mem)) 0)
+
+#define atomic_exchange_and_add(mem, value) \
+ ({ __typeof (*(mem)) __result, __tmp, __value = (value); \
+ if (sizeof (*(mem)) == 1) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.b @%2,%0\n\
+ add %0,%1\n\
+ mov.b %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
+ : "r0", "r1", "memory"); \
+ else if (sizeof (*(mem)) == 2) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.w @%2,%0\n\
+ add %0,%1\n\
+ mov.w %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
+ : "r0", "r1", "memory"); \
+ else if (sizeof (*(mem)) == 4) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.l @%2,%0\n\
+ add %0,%1\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
+ : "r0", "r1", "memory"); \
+ else \
+ { \
+ __typeof (mem) memp = (mem); \
+ do \
+ __result = *memp; \
+ while (__arch_compare_and_exchange_val_64_acq \
+ (memp, __result + __value, __result) == __result); \
+ (void) __value; \
+ } \
+ __result; })
+
+#define atomic_add(mem, value) \
+ (void) ({ __typeof (*(mem)) __tmp, __value = (value); \
+ if (sizeof (*(mem)) == 1) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.b @%1,r2\n\
+ add r2,%0\n\
+ mov.b %0,@%1\n\
+ 1: mov r1,r15"\
+ : "=&r" (__tmp) : "r" (mem), "0" (__value) \
+ : "r0", "r1", "r2", "memory"); \
+ else if (sizeof (*(mem)) == 2) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.w @%1,r2\n\
+ add r2,%0\n\
+ mov.w %0,@%1\n\
+ 1: mov r1,r15"\
+ : "=&r" (__tmp) : "r" (mem), "0" (__value) \
+ : "r0", "r1", "r2", "memory"); \
+ else if (sizeof (*(mem)) == 4) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.l @%1,r2\n\
+ add r2,%0\n\
+ mov.l %0,@%1\n\
+ 1: mov r1,r15"\
+ : "=&r" (__tmp) : "r" (mem), "0" (__value) \
+ : "r0", "r1", "r2", "memory"); \
+ else \
+ { \
+ __typeof (*(mem)) oldval; \
+ __typeof (mem) memp = (mem); \
+ do \
+ oldval = *memp; \
+ while (__arch_compare_and_exchange_val_64_acq \
+ (memp, oldval + __value, oldval) == oldval); \
+ (void) __value; \
+ } \
+ })
+
+#define atomic_add_negative(mem, value) \
+ ({ unsigned char __result; \
+ __typeof (*(mem)) __tmp, __value = (value); \
+ if (sizeof (*(mem)) == 1) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.b @%2,r2\n\
+ add r2,%1\n\
+ mov.b %1,@%2\n\
+ 1: mov r1,r15\n\
+ shal %1\n\
+ movt %0"\
+ : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
+ : "r0", "r1", "r2", "t", "memory"); \
+ else if (sizeof (*(mem)) == 2) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.w @%2,r2\n\
+ add r2,%1\n\
+ mov.w %1,@%2\n\
+ 1: mov r1,r15\n\
+ shal %1\n\
+ movt %0"\
+ : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
+ : "r0", "r1", "r2", "t", "memory"); \
+ else if (sizeof (*(mem)) == 4) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.l @%2,r2\n\
+ add r2,%1\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15\n\
+ shal %1\n\
+ movt %0"\
+ : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
+ : "r0", "r1", "r2", "t", "memory"); \
+ else \
+ abort (); \
+ __result; })
+
+#define atomic_add_zero(mem, value) \
+ ({ unsigned char __result; \
+ __typeof (*(mem)) __tmp, __value = (value); \
+ if (sizeof (*(mem)) == 1) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.b @%2,r2\n\
+ add r2,%1\n\
+ mov.b %1,@%2\n\
+ 1: mov r1,r15\n\
+ tst %1,%1\n\
+ movt %0"\
+ : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
+ : "r0", "r1", "r2", "t", "memory"); \
+ else if (sizeof (*(mem)) == 2) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.w @%2,r2\n\
+ add r2,%1\n\
+ mov.w %1,@%2\n\
+ 1: mov r1,r15\n\
+ tst %1,%1\n\
+ movt %0"\
+ : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
+ : "r0", "r1", "r2", "t", "memory"); \
+ else if (sizeof (*(mem)) == 4) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.l @%2,r2\n\
+ add r2,%1\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15\n\
+ tst %1,%1\n\
+ movt %0"\
+ : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
+ : "r0", "r1", "r2", "t", "memory"); \
+ else \
+ abort (); \
+ __result; })
+
+#define atomic_increment_and_test(mem) atomic_add_zero((mem), 1)
+#define atomic_decrement_and_test(mem) atomic_add_zero((mem), -1)
+
+#define atomic_bit_set(mem, bit) \
+ (void) ({ unsigned int __mask = 1 << (bit); \
+ if (sizeof (*(mem)) == 1) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.b @%0,r2\n\
+ or %1,r2\n\
+ mov.b r2,@%0\n\
+ 1: mov r1,r15"\
+ : : "r" (mem), "r" (__mask) \
+ : "r0", "r1", "r2", "memory"); \
+ else if (sizeof (*(mem)) == 2) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.w @%0,r2\n\
+ or %1,r2\n\
+ mov.w r2,@%0\n\
+ 1: mov r1,r15"\
+ : : "r" (mem), "r" (__mask) \
+ : "r0", "r1", "r2", "memory"); \
+ else if (sizeof (*(mem)) == 4) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.l @%0,r2\n\
+ or %1,r2\n\
+ mov.l r2,@%0\n\
+ 1: mov r1,r15"\
+ : : "r" (mem), "r" (__mask) \
+ : "r0", "r1", "r2", "memory"); \
+ else \
+ abort (); \
+ })
+
+#define atomic_bit_test_set(mem, bit) \
+ ({ unsigned int __mask = 1 << (bit); \
+ unsigned int __result = __mask; \
+ if (sizeof (*(mem)) == 1) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.b @%2,r2\n\
+ or r2,%1\n\
+ and r2,%0\n\
+ mov.b %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result), "=&r" (__mask) \
+ : "r" (mem), "0" (__result), "1" (__mask) \
+ : "r0", "r1", "r2", "memory"); \
+ else if (sizeof (*(mem)) == 2) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.w @%2,r2\n\
+ or r2,%1\n\
+ and r2,%0\n\
+ mov.w %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result), "=&r" (__mask) \
+ : "r" (mem), "0" (__result), "1" (__mask) \
+ : "r0", "r1", "r2", "memory"); \
+ else if (sizeof (*(mem)) == 4) \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%2,r2\n\
+ or r2,%1\n\
+ and r2,%0\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result), "=&r" (__mask) \
+ : "r" (mem), "0" (__result), "1" (__mask) \
+ : "r0", "r1", "r2", "memory"); \
+ else \
+ abort (); \
+ __result; })
diff --git a/libc/sysdeps/unix/sysv/linux/sh/bits/fcntl.h b/libc/sysdeps/unix/sysv/linux/sh/bits/fcntl.h
new file mode 100644
index 000000000..1f7ac0f25
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/bits/fcntl.h
@@ -0,0 +1,236 @@
+/* O_*, F_*, FD_* bit values for Linux.
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#include <sys/types.h>
+#ifdef __USE_GNU
+# include <bits/uio.h>
+#endif
+
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_ACCMODE 0003
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+#define O_CREAT 0100 /* not fcntl */
+#define O_EXCL 0200 /* not fcntl */
+#define O_NOCTTY 0400 /* not fcntl */
+#define O_TRUNC 01000 /* not fcntl */
+#define O_APPEND 02000
+#define O_NONBLOCK 04000
+#define O_NDELAY O_NONBLOCK
+#define O_SYNC 010000
+#define O_FSYNC O_SYNC
+#define O_ASYNC 020000
+
+#ifdef __USE_GNU
+# define O_DIRECT 040000 /* Direct disk access. */
+# define O_DIRECTORY 0200000 /* Must be a directory. */
+# define O_NOFOLLOW 0400000 /* Do not follow links. */
+# define O_NOATIME 01000000 /* Do not set atime. */
+#endif
+
+/* For now Linux has synchronisity options for data and read operations.
+ We define the symbols here but let them do the same as O_SYNC since
+ this is a superset. */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC O_SYNC /* Synchronize data. */
+# define O_RSYNC O_SYNC /* Synchronize read operations. */
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define O_LARGEFILE 0100000
+#endif
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#ifndef __USE_FILE_OFFSET64
+# define F_GETLK 5 /* Get record locking info. */
+# define F_SETLK 6 /* Set record locking info (non-blocking). */
+# define F_SETLKW 7 /* Set record locking info (blocking). */
+#else
+# define F_GETLK F_GETLK64 /* Get record locking info. */
+# define F_SETLK F_SETLK64 /* Set record locking info (non-blocking).*/
+# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */
+#endif
+#define F_GETLK64 12 /* Get record locking info. */
+#define F_SETLK64 13 /* Set record locking info (non-blocking). */
+#define F_SETLKW64 14 /* Set record locking info (blocking). */
+
+#if defined __USE_BSD || defined __USE_UNIX98
+# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */
+# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETSIG 10 /* Set number of signal to be sent. */
+# define F_GETSIG 11 /* Get number of signal to be sent. */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETLEASE 1024 /* Set a lease. */
+# define F_GETLEASE 1025 /* Enquire what lease is active. */
+# define F_NOTIFY 1026 /* Request notfications on a directory. */
+#endif
+
+/* For F_[GET|SET]FD. */
+#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
+#define F_RDLCK 0 /* Read lock. */
+#define F_WRLCK 1 /* Write lock. */
+#define F_UNLCK 2 /* Remove lock. */
+
+/* For old implementation of bsd flock(). */
+#define F_EXLCK 4 /* or 3 */
+#define F_SHLCK 8 /* or 4 */
+
+#ifdef __USE_BSD
+/* Operations for bsd flock(), also used by the kernel implementation. */
+# define LOCK_SH 1 /* shared lock */
+# define LOCK_EX 2 /* exclusive lock */
+# define LOCK_NB 4 /* or'd with one of the above to prevent
+ blocking */
+# define LOCK_UN 8 /* remove lock */
+#endif
+
+#ifdef __USE_GNU
+# define LOCK_MAND 32 /* This is a mandatory flock: */
+# define LOCK_READ 64 /* ... which allows concurrent read operations. */
+# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */
+# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */
+#endif
+
+#ifdef __USE_GNU
+/* Types of directory notifications that may be requested with F_NOTIFY. */
+# define DN_ACCESS 0x00000001 /* File accessed. */
+# define DN_MODIFY 0x00000002 /* File modified. */
+# define DN_CREATE 0x00000004 /* File created. */
+# define DN_DELETE 0x00000008 /* File removed. */
+# define DN_RENAME 0x00000010 /* File renamed. */
+# define DN_ATTRIB 0x00000020 /* File changed attibutes. */
+# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */
+#endif
+
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+#ifndef __USE_FILE_OFFSET64
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+#else
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+#endif
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+#endif
+
+/* Define some more compatibility macros to be backward compatible with
+ BSD systems which did not managed to hide these kernel macros. */
+#ifdef __USE_BSD
+# define FAPPEND O_APPEND
+# define FFSYNC O_FSYNC
+# define FASYNC O_ASYNC
+# define FNONBLOCK O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif /* Use BSD. */
+
+/* Advise to `posix_fadvise'. */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
+# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
+#endif
+
+
+#ifdef __USE_GNU
+/* Flags for SYNC_FILE_RANGE. */
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+
+/* Flags for SPLICE and VMSPLICE. */
+# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */
+# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing
+ (but we may still block on the fd
+ we splice from/to). */
+# define SPLICE_F_MORE 4 /* Expect more data. */
+# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
+#endif
+
+__BEGIN_DECLS
+
+#ifdef __USE_GNU
+
+/* Provide kernel hint to read ahead. */
+extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
+ __THROW;
+
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice address range into a pipe. */
+extern int vmsplice (int __fdout, const struct iovec *__iov, size_t __count,
+ unsigned int __flags);
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/sh/bits/mman.h b/libc/sysdeps/unix/sysv/linux/sh/bits/mman.h
new file mode 100644
index 000000000..7a6b572a4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/bits/mman.h
@@ -0,0 +1,103 @@
+/* Definitions for POSIX memory map interface. Linux/SH version.
+ Copyright (C) 1997,1999,2000,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MMAN_H
+# error "Never include this file directly. Use <sys/mman.h> instead"
+#endif
+
+/* The following definitions basically come from the kernel headers.
+ But the kernel header is not namespace clean. */
+
+
+/* Protections are chosen from these bits, OR'd together. The
+ implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ without PROT_READ. The only guarantees are that no writing will be
+ allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
+
+#define PROT_READ 0x1 /* Page can be read. */
+#define PROT_WRITE 0x2 /* Page can be written. */
+#define PROT_EXEC 0x4 /* Page can be executed. */
+#define PROT_NONE 0x0 /* Page can not be accessed. */
+#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
+ growsdown vma (mprotect only). */
+#define PROT_GROWSUP 0x02000000 /* Extend change to start of
+ growsup vma (mprotect only). */
+
+/* Sharing types (must choose one and only one of these). */
+#define MAP_SHARED 0x01 /* Share changes. */
+#define MAP_PRIVATE 0x02 /* Changes are private. */
+#ifdef __USE_MISC
+# define MAP_TYPE 0x0f /* Mask for type of mapping. */
+#endif
+
+/* Other flags. */
+#define MAP_FIXED 0x10 /* Interpret addr exactly. */
+#ifdef __USE_MISC
+# define MAP_FILE 0
+# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+
+/* These are Linux-specific. */
+#ifdef __USE_MISC
+# define MAP_GROWSDOWN 0x0100 /* Stack-like segment. */
+# define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+# define MAP_EXECUTABLE 0x1000 /* Mark it as an executable. */
+# define MAP_LOCKED 0x2000 /* Lock the mapping. */
+# define MAP_NORESERVE 0x4000 /* Don't check for reservations. */
+# define MAP_POPULATE 0x8000 /* Populate (prefault) pagetables. */
+# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */
+#endif
+
+/* Flags to `msync'. */
+#define MS_ASYNC 1 /* Sync memory asynchronously. */
+#define MS_SYNC 4 /* Synchronous memory sync. */
+#define MS_INVALIDATE 2 /* Invalidate the caches. */
+
+/* Flags for `mlockall'. */
+#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
+#define MCL_FUTURE 2 /* Lock all additions to address
+ space. */
+
+/* Flags for `mremap'. */
+#ifdef __USE_GNU
+# define MREMAP_MAYMOVE 1
+# define MREMAP_FIXED 2
+#endif
+
+/* Advice to `madvise'. */
+#ifdef __USE_BSD
+# define MADV_NORMAL 0 /* No further special treatment. */
+# define MADV_RANDOM 1 /* Expect random page references. */
+# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define MADV_WILLNEED 3 /* Will need these pages. */
+# define MADV_DONTNEED 4 /* Don't need these pages. */
+# define MADV_REMOVE 9 /* Remove these pages and resources. */
+# define MADV_DONTFORK 10 /* Do not inherit across fork. */
+# define MADV_DOFORK 11 /* Do inherit across fork. */
+#endif
+
+/* The POSIX people had to invent similar names for the same things. */
+#ifdef __USE_XOPEN2K
+# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sh/brk.c b/libc/sysdeps/unix/sysv/linux/sh/brk.c
new file mode 100644
index 000000000..0524478b5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/brk.c
@@ -0,0 +1,48 @@
+/* brk system call for Linux/SH.
+ Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sysdep.h>
+
+/* This must be initialized data because commons can't have aliases. */
+void *__curbrk = 0;
+
+int
+__brk (void *addr)
+{
+ void *newbrk;
+ register long r3 asm ("%r3") = SYS_ify (brk);
+ register long r4 asm ("%r4") = (long)addr;
+
+ asm volatile ("trapa #0x11\n\t" SYSCALL_INST_PAD
+ : "=z"(newbrk)
+ : "r" (r3), "r" (r4));
+
+ __curbrk = newbrk;
+
+ if (newbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+weak_alias (__brk, brk)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/chown.c b/libc/sysdeps/unix/sysv/linux/sh/chown.c
new file mode 100644
index 000000000..e7193dc23
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/chown.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 1998,2000,2002,2003,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+#ifdef __NR_chown32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif /* __NR_chown32 */
+
+int
+__chown (const char *file, uid_t owner, gid_t group)
+{
+#if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (chown32, 3, CHECK_STRING (file), owner, group);
+#else
+# ifdef __NR_chown32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ int result;
+ int saved_errno = errno;
+
+ result = INLINE_SYSCALL (chown32, 3, CHECK_STRING (file), owner, group);
+ if (result == 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_chown32 */
+
+ if (((owner + 1) > (gid_t) ((__kernel_uid_t) -1U))
+ || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return INLINE_SYSCALL (chown, 3, CHECK_STRING (file), owner, group);
+#endif
+}
+libc_hidden_def (__chown)
+weak_alias (__chown, chown)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/clone.S b/libc/sysdeps/unix/sysv/linux/sh/clone.S
new file mode 100644
index 000000000..7941c6b3a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/clone.S
@@ -0,0 +1,132 @@
+/* Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* clone() is even more special than fork() as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#ifdef RESET_PID
+#include <tcb-offsets.h>
+#endif
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+ pid_t *ptid, void *tls, pid_t *ctid); */
+
+ .text
+ENTRY(__clone)
+ /* sanity check arguments. */
+ tst r4, r4
+ bf/s 1f
+ tst r5, r5
+ bf/s 1f
+ mov #-EINVAL,r0
+ bra .Lsyscall_error
+ nop
+1:
+ /* insert the args onto the new stack */
+ mov.l r7, @-r5
+ /* save the function pointer as the 0th element */
+ mov.l r4, @-r5
+
+ /* do the system call */
+ mov r6, r4
+ mov.l @r15, r6
+ mov.l @(8,r15), r7
+ mov.l @(4,r15), r0
+ mov #+SYS_ify(clone), r3
+ trapa #0x15
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lclone_end
+.Lsyscall_error:
+ SYSCALL_ERROR_HANDLER
+.Lclone_end:
+ tst r0, r0
+ bt 2f
+.Lpseudo_end:
+ rts
+ nop
+2:
+ /* terminate the stack frame */
+ mov #0, r14
+#ifdef RESET_PID
+ mov r4, r0
+ shlr16 r0
+ tst #1, r0 // CLONE_THREAD = (1 << 16)
+ bf/s 4f
+ mov r4, r0
+ /* new pid */
+ shlr8 r0
+ tst #1, r0 // CLONE_VM = (1 << 8)
+ bf/s 3f
+ mov #-1, r0
+ mov #+SYS_ify(getpid), r3
+ trapa #0x15
+3:
+ stc gbr, r1
+ mov.w .Lpidoff, r2
+ add r1, r2
+ mov.l r0, @r2
+ mov.w .Ltidoff, r2
+ add r1, r2
+ mov.l r0, @r2
+4:
+#endif
+ /* thread starts */
+ mov.l @r15, r1
+ jsr @r1
+ mov.l @(4,r15), r4
+
+ /* we are done, passing the return value through r0 */
+ mov.l .L3, r1
+#ifdef SHARED
+ mov.l r12, @-r15
+ sts.l pr, @-r15
+ mov r0, r4
+ mova .LG, r0
+ mov.l .LG, r12
+ add r0, r12
+ mova .L3, r0
+ add r0, r1
+ jsr @r1
+ nop
+ lds.l @r15+, pr
+ rts
+ mov.l @r15+, r12
+#else
+ jmp @r1
+ mov r0, r4
+#endif
+ .align 2
+.LG:
+ .long _GLOBAL_OFFSET_TABLE_
+.L3:
+ .long PLTJMP(C_SYMBOL_NAME(_exit))
+#ifdef RESET_PID
+.Lpidoff:
+ .word PID - TLS_PRE_TCB_SIZE
+.Ltidoff:
+ .word TID - TLS_PRE_TCB_SIZE
+#endif
+PSEUDO_END (__clone)
+
+weak_alias (__clone, clone)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/fchown.c b/libc/sysdeps/unix/sysv/linux/sh/fchown.c
new file mode 100644
index 000000000..3a69ecc9e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/fchown.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fchown.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/fchownat.c b/libc/sysdeps/unix/sysv/linux/sh/fchownat.c
new file mode 100644
index 000000000..61df787c2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/fchownat.c
@@ -0,0 +1,140 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <linux/posix_types.h>
+#include <kernel-features.h>
+
+#ifdef __NR_chown32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif /* __NR_chown32 */
+
+int
+fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
+{
+ int result;
+
+#ifdef __NR_fchownat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INLINE_SYSCALL (fchownat, 5, fd, file, owner, group, flag);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ if (flag & ~AT_SYMLINK_NOFOLLOW)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+# if __ASSUME_32BITUIDS > 0
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lchown32, err, 3, CHECK_STRING (file), owner,
+ group);
+ else
+ result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
+ group);
+# else
+# ifdef __NR_chown32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lchown32, err, 3, CHECK_STRING (file),
+ owner, group);
+ else
+ result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
+ group);
+
+ if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
+ return result;
+ if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
+ goto fail;
+
+ __libc_missing_32bit_uids = 1;
+ }
+# endif /* __NR_chown32 */
+
+ if (((owner + 1) > (gid_t) ((__kernel_uid_t) -1U))
+ || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ result = INTERNAL_SYSCALL (lchown, err, 3, CHECK_STRING (file), owner,
+ group);
+ else
+ result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner,
+ group);
+# endif
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ {
+ fail:
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
+ result = -1;
+ }
+
+ return result;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sh/fcntl.c b/libc/sysdeps/unix/sysv/linux/sh/fcntl.c
new file mode 100644
index 000000000..ea951bc4f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/fcntl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fcntl.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/fxstat.c b/libc/sysdeps/unix/sysv/linux/sh/fxstat.c
new file mode 100644
index 000000000..4f219f0b9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/fxstat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fxstat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/fxstatat.c b/libc/sysdeps/unix/sysv/linux/sh/fxstatat.c
new file mode 100644
index 000000000..0f8b3135d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/fxstatat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fxstatat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/getegid.c b/libc/sysdeps/unix/sysv/linux/sh/getegid.c
new file mode 100644
index 000000000..37b4b4a53
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/getegid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getegid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/geteuid.c b/libc/sysdeps/unix/sysv/linux/sh/geteuid.c
new file mode 100644
index 000000000..ebcb555b5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/geteuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/geteuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/getgroups.c b/libc/sysdeps/unix/sysv/linux/sh/getgroups.c
new file mode 100644
index 000000000..102ea24e1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/getgroups.c
@@ -0,0 +1,2 @@
+/* We also have to rewrite the kernel gid_t to the user land type. */
+#include <sysdeps/unix/sysv/linux/i386/getgroups.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/getresgid.c b/libc/sysdeps/unix/sysv/linux/sh/getresgid.c
new file mode 100644
index 000000000..b703a414c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/getresgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getresgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/getresuid.c b/libc/sysdeps/unix/sysv/linux/sh/getresuid.c
new file mode 100644
index 000000000..0b14cefe3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/getresuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getresuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/getrlimit.c b/libc/sysdeps/unix/sysv/linux/sh/getrlimit.c
new file mode 100644
index 000000000..fc06dbd64
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/getrlimit.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getrlimit.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/getrlimit64.c b/libc/sysdeps/unix/sysv/linux/sh/getrlimit64.c
new file mode 100644
index 000000000..fef018f47
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/getrlimit64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getrlimit64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/getuid.c b/libc/sysdeps/unix/sysv/linux/sh/getuid.c
new file mode 100644
index 000000000..d682c79a4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/getuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/lchown.c b/libc/sysdeps/unix/sysv/linux/sh/lchown.c
new file mode 100644
index 000000000..c89de99ba
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/lchown.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/lchown.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/lockf64.c b/libc/sysdeps/unix/sysv/linux/sh/lockf64.c
new file mode 100644
index 000000000..a88f5a784
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/lockf64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/lockf64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/lxstat.c b/libc/sysdeps/unix/sysv/linux/sh/lxstat.c
new file mode 100644
index 000000000..2371cd971
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/lxstat.c
@@ -0,0 +1,2 @@
+#include <sysdeps/unix/sysv/linux/i386/lxstat.c>
+
diff --git a/libc/sysdeps/unix/sysv/linux/sh/makecontext.S b/libc/sysdeps/unix/sysv/linux/sh/makecontext.S
new file mode 100644
index 000000000..877d78d39
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/makecontext.S
@@ -0,0 +1,145 @@
+/* Create new context.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+/* void __makecontext (struct ucontext *ucp, void (*func)(), int argc, ...);
+ __makecontext sets up a stack and registers for context to run a given
+ function. The registers are set up like this:
+ r4-r7: parameters 1 to 4
+ r8 : uc_link from ucontext structure
+ pc : (*func) pointer
+ pr : address of exitcode
+ r15 : stack pointer for func. */
+
+ .text
+ .align 5
+ENTRY(__makecontext)
+ mov #4, r3
+ mov.l @(oSS_SP,r4), r1
+ mov.l @(oSS_SIZE,r4), r2
+ add r1, r2
+ cmp/gt r6, r3
+ bf/s 1f
+ shlr2 r2
+ sub r6, r2
+ add r3, r2
+1:
+ shll2 r2
+ mov #oR15, r0
+ mov.l @(oLINK,r4), r1
+ mov.l r2, @(r0,r4)
+ mov.l r1, @(oR8,r4)
+ mov #oPC, r0
+ mov.l r5, @(r0,r4)
+
+ cmp/pl r6
+ bf/s .L1
+ dt r6
+ mov.l r7, @(oR4,r4)
+ cmp/pl r6
+ bf/s .L1
+ dt r6
+ mov.l @(0,r15), r1
+ mov.l r1, @(oR5,r4)
+ cmp/pl r6
+ bf/s .L1
+ dt r6
+ mov.l @(4,r15), r1
+ mov.l r1, @(oR6,r4)
+ cmp/pl r6
+ bf/s .L1
+ dt r6
+ mov.l @(8,r15), r1
+ mov.l r1, @(oR7,r4)
+ mov #12,r0
+.L0:
+ cmp/pl r6
+ bf/s .L1
+ dt r6
+ mov.l @(r0,r15), r1
+ mov.l r1, @r2
+ add #4, r0
+ bra .L0
+ add #4, r2
+.L1:
+#ifdef PIC
+ mova .Lexitcode, r0
+#else
+ mov.l .L2, r0
+#endif
+ add #oPR, r4
+ rts
+ mov.l r0, @r4
+#ifndef PIC
+ .align 2
+.L2:
+ .long .Lexitcode
+#endif
+ cfi_endproc
+
+ .align 5
+.Lexitcode:
+ tst r8, r8
+ bt/s 2f
+ mov r8, r4
+#ifdef PIC
+ mova .Lgot, r0
+ mov.l .Lgot, r12
+ add r0, r12
+ mov.l .L3, r1
+ bsrf r1
+.LPCS0:
+ nop
+#else
+ mov.l .L3, r1
+ jsr @r1
+ nop
+#endif
+2:
+ mov.l .L4, r1
+#ifdef PIC
+ add r12, r1
+#endif
+ jsr @r1
+ mov r0, r4
+0:
+ bra 0b
+ nop
+
+ .align 2
+#ifdef PIC
+.Lgot:
+ .long _GLOBAL_OFFSET_TABLE_
+.L3:
+ .long __setcontext@PLT-(.LPCS0+2-(.))
+.L4:
+ .long HIDDEN_JUMPTARGET(exit)@GOTOFF
+#else
+.L3:
+ .long __setcontext
+.L4:
+ .long HIDDEN_JUMPTARGET(exit)
+#endif
+ cfi_startproc
+PSEUDO_END(__makecontext)
+
+weak_alias (__makecontext, makecontext)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/msgctl.c b/libc/sysdeps/unix/sysv/linux/sh/msgctl.c
new file mode 100644
index 000000000..9f9b8431a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/msgctl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/msgctl.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/pipe.S b/libc/sysdeps/unix/sysv/linux/sh/pipe.S
new file mode 100644
index 000000000..2b5cf77d1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/pipe.S
@@ -0,0 +1,43 @@
+/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY (__libc_pipe)
+ mov #+__NR_pipe, r3
+ trapa #0x10
+ mov r0, r3
+ mov #-12, r2
+ shad r2, r3
+ not r3, r3 // r1=0 means r0 = -1 to -4095
+ tst r3, r3 // i.e. error in linux
+ bt 1f
+ mov.l r0, @r4
+ mov.l r1, @(4, r4)
+ rts
+ mov #0, r0
+1:
+ SYSCALL_ERROR_HANDLER
+.Lpseudo_end:
+ rts
+ nop
+PSEUDO_END (__libc_pipe)
+
+weak_alias (__libc_pipe, __pipe)
+libc_hidden_def (__pipe)
+weak_alias (__libc_pipe, pipe)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/pread.c b/libc/sysdeps/unix/sysv/linux/sh/pread.c
new file mode 100644
index 000000000..0186e40c9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/pread.c
@@ -0,0 +1,93 @@
+/* Copyright (C) 1997, 1998, 2000, 2002, 2003, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+#include <endian.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_pread
+# error "__NR_pread and __NR_pread64 both defined???"
+# endif
+# define __NR_pread __NR_pread64
+#endif
+
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
+
+# if __ASSUME_PREAD_SYSCALL == 0
+static ssize_t __emulate_pread (int fd, void *buf, size_t count,
+ off_t offset) internal_function;
+# endif
+
+ssize_t
+__libc_pread (fd, buf, count, offset)
+ int fd;
+ void *buf;
+ size_t count;
+ off_t offset;
+{
+ ssize_t result;
+
+ if (SINGLE_THREAD_P)
+ {
+ /* First try the syscall. */
+ result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count, 0,
+ __LONG_LONG_PAIR (offset >> 31, offset));
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread (fd, buf, count, offset);
+# endif
+ return result;
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* First try the syscall. */
+ result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count, 0,
+ __LONG_LONG_PAIR (offset >> 31, offset));
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread (fd, buf, count, offset);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+strong_alias (__libc_pread, __pread)
+weak_alias (__libc_pread, pread)
+
+# define __libc_pread(fd, buf, count, offset) \
+ static internal_function __emulate_pread (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sh/pread64.c b/libc/sysdeps/unix/sysv/linux/sh/pread64.c
new file mode 100644
index 000000000..f23d61909
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/pread64.c
@@ -0,0 +1,94 @@
+/* Copyright (C) 1997, 1998, 2000, 2002, 2003, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <endian.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_pread
+# error "__NR_pread and __NR_pread64 both defined???"
+# endif
+# define __NR_pread __NR_pread64
+#endif
+
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
+
+# if __ASSUME_PREAD_SYSCALL == 0
+static ssize_t __emulate_pread64 (int fd, void *buf, size_t count,
+ off64_t offset) internal_function;
+# endif
+
+ssize_t
+__libc_pread64 (fd, buf, count, offset)
+ int fd;
+ void *buf;
+ size_t count;
+ off64_t offset;
+{
+ ssize_t result;
+
+ if (SINGLE_THREAD_P)
+ {
+ /* First try the syscall. */
+ result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count, 0,
+ __LONG_LONG_PAIR ((off_t) (offset >> 32),
+ (off_t) (offset & 0xffffffff)));
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread64 (fd, buf, count, offset);
+# endif
+ return result;
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* First try the syscall. */
+ result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count, 0,
+ __LONG_LONG_PAIR ((off_t) (offset >> 32),
+ (off_t) (offset & 0xffffffff)));
+# if __ASSUME_PREAD_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pread64 (fd, buf, count, offset);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+weak_alias (__libc_pread64, __pread64)
+weak_alias (__libc_pread64, pread64)
+
+# define __libc_pread64(fd, buf, count, offset) \
+ static internal_function __emulate_pread64 (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread64.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sh/profil-counter.h b/libc/sysdeps/unix/sysv/linux/sh/profil-counter.h
new file mode 100644
index 000000000..ae1b97828
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/profil-counter.h
@@ -0,0 +1,33 @@
+/* Low-level statistical profiling support function. Linux/SH version.
+ Copyright (C) 1996, 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+
+static void
+profil_counter (int signo, int _a2, int _a3, int _a4, struct sigcontext sc)
+{
+ void *pc;
+ pc = (void *) sc.sc_pc;
+ profil_count (pc);
+
+ /* This is a hack to prevent the compiler from implementing the
+ above function call as a sibcall. The sibcall would overwrite
+ the signal context. */
+ asm volatile ("");
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sh/pwrite.c b/libc/sysdeps/unix/sysv/linux/sh/pwrite.c
new file mode 100644
index 000000000..f0e2bc7e0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/pwrite.c
@@ -0,0 +1,93 @@
+/* Copyright (C) 1997, 1998, 2000, 2002, 2003, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+#include <endian.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_pwrite
+# error "__NR_pwrite and __NR_pwrite64 both defined???"
+# endif
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
+
+# if __ASSUME_PWRITE_SYSCALL == 0
+static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count,
+ off_t offset) internal_function;
+# endif
+
+ssize_t
+__libc_pwrite (fd, buf, count, offset)
+ int fd;
+ const void *buf;
+ size_t count;
+ off_t offset;
+{
+ ssize_t result;
+
+ if (SINGLE_THREAD_P)
+ {
+ /* First try the syscall. */
+ result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count, 0,
+ __LONG_LONG_PAIR (offset >> 31, offset));
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite (fd, buf, count, offset);
+# endif
+ return result;
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* First try the syscall. */
+ result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count, 0,
+ __LONG_LONG_PAIR (offset >> 31, offset));
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite (fd, buf, count, offset);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+strong_alias (__libc_pwrite, __pwrite)
+weak_alias (__libc_pwrite, pwrite)
+
+# define __libc_pwrite(fd, buf, count, offset) \
+ static internal_function __emulate_pwrite (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sh/pwrite64.c b/libc/sysdeps/unix/sysv/linux/sh/pwrite64.c
new file mode 100644
index 000000000..eb1e50728
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/pwrite64.c
@@ -0,0 +1,96 @@
+/* Copyright (C) 1997, 1998, 2000, 2002, 2003, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ralf Baechle <ralf@gnu.org>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <endian.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_pwrite
+# error "__NR_pwrite and __NR_pwrite64 both defined???"
+# endif
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
+
+# if __ASSUME_PWRITE_SYSCALL == 0
+static ssize_t __emulate_pwrite64 (int fd, const void *buf, size_t count,
+ off64_t offset) internal_function;
+# endif
+
+ssize_t
+__libc_pwrite64 (fd, buf, count, offset)
+ int fd;
+ const void *buf;
+ size_t count;
+ off64_t offset;
+{
+ ssize_t result;
+
+ if (SINGLE_THREAD_P)
+ {
+ /* First try the syscall. */
+ result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count, 0,
+ __LONG_LONG_PAIR ((off_t) (offset >> 32),
+ (off_t) (offset & 0xffffffff)));
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite64 (fd, buf, count, offset);
+# endif
+
+ return result;
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* First try the syscall. */
+ result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count, 0,
+ __LONG_LONG_PAIR ((off_t) (offset >> 32),
+ (off_t) (offset & 0xffffffff)));
+# if __ASSUME_PWRITE_SYSCALL == 0
+ if (result == -1 && errno == ENOSYS)
+ /* No system call available. Use the emulation. */
+ result = __emulate_pwrite64 (fd, buf, count, offset);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+weak_alias (__libc_pwrite64, __pwrite64)
+libc_hidden_weak (__pwrite64)
+weak_alias (__libc_pwrite64, pwrite64)
+
+# define __libc_pwrite64(fd, buf, count, offset) \
+ static internal_function __emulate_pwrite64 (fd, buf, count, offset)
+#endif
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite64.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sh/semctl.c b/libc/sysdeps/unix/sysv/linux/sh/semctl.c
new file mode 100644
index 000000000..e9b1a483c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/semctl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/semctl.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/setegid.c b/libc/sysdeps/unix/sysv/linux/sh/setegid.c
new file mode 100644
index 000000000..2e3a54c89
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/setegid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setegid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/seteuid.c b/libc/sysdeps/unix/sysv/linux/sh/seteuid.c
new file mode 100644
index 000000000..18e41d08c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/seteuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/seteuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/setfsgid.c b/libc/sysdeps/unix/sysv/linux/sh/setfsgid.c
new file mode 100644
index 000000000..088671256
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/setfsgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setfsgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/setfsuid.c b/libc/sysdeps/unix/sysv/linux/sh/setfsuid.c
new file mode 100644
index 000000000..a9f22eb8a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/setfsuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setfsuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/setgid.c b/libc/sysdeps/unix/sysv/linux/sh/setgid.c
new file mode 100644
index 000000000..377021d9e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/setgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/setgroups.c b/libc/sysdeps/unix/sysv/linux/sh/setgroups.c
new file mode 100644
index 000000000..0e7086278
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/setgroups.c
@@ -0,0 +1,2 @@
+/* We also have to rewrite the kernel gid_t to the user land type. */
+#include <sysdeps/unix/sysv/linux/i386/setgroups.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/setregid.c b/libc/sysdeps/unix/sysv/linux/sh/setregid.c
new file mode 100644
index 000000000..99c57ad20
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/setregid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setregid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/setresgid.c b/libc/sysdeps/unix/sysv/linux/sh/setresgid.c
new file mode 100644
index 000000000..daca1a483
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/setresgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setresgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/setresuid.c b/libc/sysdeps/unix/sysv/linux/sh/setresuid.c
new file mode 100644
index 000000000..3aeabe9ad
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/setresuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setresuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/setreuid.c b/libc/sysdeps/unix/sysv/linux/sh/setreuid.c
new file mode 100644
index 000000000..8ad61226e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/setreuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setreuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/setrlimit.c b/libc/sysdeps/unix/sysv/linux/sh/setrlimit.c
new file mode 100644
index 000000000..bfaef74c3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/setrlimit.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setrlimit.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/setuid.c b/libc/sysdeps/unix/sysv/linux/sh/setuid.c
new file mode 100644
index 000000000..de394379b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/setuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh3/getcontext.S b/libc/sysdeps/unix/sysv/linux/sh/sh3/getcontext.S
new file mode 100644
index 000000000..66b3daaa3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh3/getcontext.S
@@ -0,0 +1,88 @@
+/* Save current context.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+/* int __getcontext (ucontext_t *uc); */
+
+ .text
+ .align 5
+ENTRY(__getcontext)
+
+ /* Return value of getcontext. R0 is the only register whose
+ value is not preserved. */
+ mov #0, r0
+ mov.l r0, @(oR0,r4)
+ mov.l r1, @(oR1,r4)
+ mov.l r2, @(oR2,r4)
+ mov.l r3, @(oR3,r4)
+ mov.l r4, @(oR4,r4)
+ mov.l r5, @(oR5,r4)
+ mov.l r6, @(oR6,r4)
+ mov.l r7, @(oR7,r4)
+ mov r4, r0
+ add #(oMACL+4), r0
+ sts.l macl, @-r0
+ sts.l mach, @-r0
+ stc.l gbr, @-r0
+
+ /* Save T flag to SR. */
+ movt r1
+ mov.l r1, @-r0
+ sts.l pr, @-r0
+
+ /* The return address of getcontext is the restart pc. */
+ sts.l pr, @-r0
+
+ mov.l r15, @-r0
+ mov.l r14, @-r0
+ mov.l r13, @-r0
+ mov.l r12, @-r0
+ mov.l r11, @-r0
+ mov.l r10, @-r0
+ mov.l r9, @-r0
+ mov.l r8, @-r0
+
+ /* sigprocmask (SIG_BLOCK, NULL, &uc->uc_sigmask). */
+ mov r4, r6
+ add #oSIGMASK, r6
+ mov #SIG_BLOCK, r4
+ mov #0, r5
+ mov #+SYS_ify(sigprocmask), r3
+ trapa #0x13
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lgetcontext_end
+.Lsyscall_error:
+ SYSCALL_ERROR_HANDLER
+.Lgetcontext_end:
+ /* All done, return 0 for success. */
+ mov #0, r0
+.Lpseudo_end:
+ rts
+ nop
+
+PSEUDO_END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh3/register-dump.h b/libc/sysdeps/unix/sysv/linux/sh/sh3/register-dump.h
new file mode 100644
index 000000000..561f3b3e8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh3/register-dump.h
@@ -0,0 +1,151 @@
+/* Dump registers.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/uio.h>
+#include <stdio-common/_itoa.h>
+
+/* We will print the register dump in this format:
+
+ R0: XXXXXXXX R1: XXXXXXXX R2: XXXXXXXX R3: XXXXXXXX
+ R4: XXXXXXXX R5: XXXXXXXX R6: XXXXXXXX R7: XXXXXXXX
+ R8: XXXXXXXX R9: XXXXXXXX R10: XXXXXXXX R11: XXXXXXXX
+ R12: XXXXXXXX R13: XXXXXXXX R14: XXXXXXXX R15: XXXXXXXX
+
+MACL: XXXXXXXX MACH: XXXXXXXX
+
+ PC: XXXXXXXX PR: XXXXXXXX GBR: XXXXXXXX SR: XXXXXXXX
+
+ FR0: XXXXXXXX FR1: XXXXXXXX FR2: XXXXXXXX FR3: XXXXXXXX
+ FR4: XXXXXXXX FR5: XXXXXXXX FR6: XXXXXXXX FR7: XXXXXXXX
+ FR8: XXXXXXXX FR9: XXXXXXXX FR10: XXXXXXXX FR11: XXXXXXXX
+FR12: XXXXXXXX FR13: XXXXXXXX FR14: XXXXXXXX FR15: XXXXXXXX
+
+ XR0: XXXXXXXX XR1: XXXXXXXX XR2: XXXXXXXX XR3: XXXXXXXX
+ XR4: XXXXXXXX XR5: XXXXXXXX XR6: XXXXXXXX XR7: XXXXXXXX
+ XR8: XXXXXXXX XR9: XXXXXXXX XR10: XXXXXXXX XR11: XXXXXXXX
+XR12: XXXXXXXX XR13: XXXXXXXX XR14: XXXXXXXX XR15: XXXXXXXX
+
+FPSCR: XXXXXXXX FPUL: XXXXXXXX
+
+ */
+
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
+{
+ char *cp = _itoa_word (value, buf + len, 16, 0);
+ while (cp > buf)
+ *--cp = '0';
+}
+
+static void
+register_dump (int fd, struct sigcontext *ctx)
+{
+ char regs[22][8];
+ struct iovec iov[112];
+ size_t nr = 0;
+
+#define ADD_STRING(str) \
+ iov[nr].iov_base = (char *) str; \
+ iov[nr].iov_len = strlen (str); \
+ ++nr
+#define ADD_MEM(str, len) \
+ iov[nr].iov_base = str; \
+ iov[nr].iov_len = len; \
+ ++nr
+
+ /* Generate strings of register contents. */
+ hexvalue (ctx->sc_regs[0], regs[0], 8);
+ hexvalue (ctx->sc_regs[1], regs[1], 8);
+ hexvalue (ctx->sc_regs[2], regs[2], 8);
+ hexvalue (ctx->sc_regs[3], regs[3], 8);
+ hexvalue (ctx->sc_regs[4], regs[4], 8);
+ hexvalue (ctx->sc_regs[5], regs[5], 8);
+ hexvalue (ctx->sc_regs[6], regs[6], 8);
+ hexvalue (ctx->sc_regs[7], regs[7], 8);
+ hexvalue (ctx->sc_regs[8], regs[8], 8);
+ hexvalue (ctx->sc_regs[9], regs[9], 8);
+ hexvalue (ctx->sc_regs[10], regs[10], 8);
+ hexvalue (ctx->sc_regs[11], regs[11], 8);
+ hexvalue (ctx->sc_regs[12], regs[12], 8);
+ hexvalue (ctx->sc_regs[13], regs[13], 8);
+ hexvalue (ctx->sc_regs[14], regs[14], 8);
+ hexvalue (ctx->sc_regs[15], regs[15], 8);
+ hexvalue (ctx->sc_macl, regs[16], 8);
+ hexvalue (ctx->sc_mach, regs[17], 8);
+ hexvalue (ctx->sc_pc, regs[18], 8);
+ hexvalue (ctx->sc_pr, regs[19], 8);
+ hexvalue (ctx->sc_gbr, regs[20], 8);
+ hexvalue (ctx->sc_sr, regs[21], 8);
+
+ /* Generate the output. */
+ ADD_STRING ("Register dump:\n\n R0: ");
+ ADD_MEM (regs[0], 8);
+ ADD_STRING (" R1: ");
+ ADD_MEM (regs[1], 8);
+ ADD_STRING (" R2: ");
+ ADD_MEM (regs[2], 8);
+ ADD_STRING (" R3: ");
+ ADD_MEM (regs[3], 8);
+ ADD_STRING ("\n R4: ");
+ ADD_MEM (regs[4], 8);
+ ADD_STRING (" R5: ");
+ ADD_MEM (regs[5], 8);
+ ADD_STRING (" R6: ");
+ ADD_MEM (regs[6], 8);
+ ADD_STRING (" R7: ");
+ ADD_MEM (regs[7], 8);
+ ADD_STRING ("\n R8: ");
+ ADD_MEM (regs[8], 8);
+ ADD_STRING (" R9: ");
+ ADD_MEM (regs[9], 8);
+ ADD_STRING (" R10: ");
+ ADD_MEM (regs[10], 8);
+ ADD_STRING (" R11: ");
+ ADD_MEM (regs[11], 8);
+ ADD_STRING ("\n R12: ");
+ ADD_MEM (regs[12], 8);
+ ADD_STRING (" R13: ");
+ ADD_MEM (regs[13], 8);
+ ADD_STRING (" R14: ");
+ ADD_MEM (regs[14], 8);
+ ADD_STRING (" R15: ");
+ ADD_MEM (regs[15], 8);
+
+ ADD_STRING ("\n\nMACL: ");
+ ADD_MEM (regs[16], 8);
+ ADD_STRING (" MACH: ");
+ ADD_MEM (regs[17], 8);
+
+ ADD_STRING ("\n\n PC: ");
+ ADD_MEM (regs[18], 8);
+ ADD_STRING (" PR: ");
+ ADD_MEM (regs[19], 8);
+ ADD_STRING (" GBR: ");
+ ADD_MEM (regs[20], 8);
+ ADD_STRING (" SR: ");
+ ADD_MEM (regs[21], 8);
+
+ ADD_STRING ("\n");
+
+ /* Write the stuff out. */
+ writev (fd, iov, nr);
+}
+
+
+#define REGISTER_DUMP register_dump (fd, &ctx)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh3/setcontext.S b/libc/sysdeps/unix/sysv/linux/sh/sh3/setcontext.S
new file mode 100644
index 000000000..3136267ac
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh3/setcontext.S
@@ -0,0 +1,99 @@
+/* Install given context.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+/* int __setcontext (const ucontext_t *uc); */
+
+ .text
+ .align 5
+ENTRY(__setcontext)
+
+ mov r4, r8
+
+ /* sigprocmask (SIG_SETMASK, &uc->uc_sigmask, NULL). */
+ mov r4, r5
+ add #oSIGMASK, r5
+ mov #SIG_SETMASK, r4
+ mov #0, r6
+ mov #+SYS_ify(sigprocmask), r3
+ trapa #0x13
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lsetcontext_restore
+.Lsyscall_error:
+ SYSCALL_ERROR_HANDLER
+.Lpseudo_end:
+ rts
+ nop
+
+.Lsetcontext_restore:
+ mov r8, r0
+ add #(oPC), r0
+ mov.l @r0+, r2
+ lds.l @r0+, pr
+
+ /* Restore T frag. */
+ mov.l @r0+, r1
+ shlr r1
+ /* Skip GBR which is used for thread pointer. */
+ add #4, r0
+
+ lds.l @r0+, mach
+ lds.l @r0+, macl
+
+ mov r8, r0
+ add #(oR9), r0
+ mov.l @r0+, r9
+ mov.l @r0+, r10
+ mov.l @r0+, r11
+ mov.l @r0+, r12
+ mov.l @r0+, r13
+ mov.l @r0+, r14
+ mov.l @r0+, r15
+
+ mov r8, r0
+ mov.l @(oR0,r0), r1
+ mov.l r1, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r1, 0)
+ mov.l r2, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r2, 0)
+
+ mov.l @(oR1,r0), r1
+ mov.l @(oR2,r0), r2
+ mov.l @(oR3,r0), r3
+ mov.l @(oR4,r0), r4
+ mov.l @(oR5,r0), r5
+ mov.l @(oR6,r0), r6
+ mov.l @(oR7,r0), r7
+ mov.l @(oR8,r0), r8
+ mov.l @r15+, r0
+ jmp @r0
+ mov.l @r15+, r0
+
+PSEUDO_END(__setcontext)
+
+weak_alias (__setcontext, setcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh3/swapcontext.S b/libc/sysdeps/unix/sysv/linux/sh/sh3/swapcontext.S
new file mode 100644
index 000000000..64035e554
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh3/swapcontext.S
@@ -0,0 +1,132 @@
+/* Save current context and install the given one.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+/* int __swapcontext (ucontext_t *ouc, const ucontext_t *uc); */
+
+ .text
+ .align 5
+ENTRY(__swapcontext)
+
+ /* Return value of getcontext. R0 is the only register whose
+ value is not preserved. */
+ mov #0, r0
+ mov.l r0, @(oR0,r4)
+ mov.l r1, @(oR1,r4)
+ mov.l r2, @(oR2,r4)
+ mov.l r3, @(oR3,r4)
+ mov.l r4, @(oR4,r4)
+ mov.l r5, @(oR5,r4)
+ mov.l r6, @(oR6,r4)
+ mov.l r7, @(oR7,r4)
+ mov r4, r0
+ add #(oMACL+4), r0
+ sts.l macl, @-r0
+ sts.l mach, @-r0
+ stc.l gbr, @-r0
+
+ /* Save T flag to SR. */
+ movt r1
+ mov.l r1, @-r0
+ sts.l pr, @-r0
+
+ /* The return address of getcontext is the restart pc. */
+ sts.l pr, @-r0
+
+ mov.l r15, @-r0
+ mov.l r14, @-r0
+ mov.l r13, @-r0
+ mov.l r12, @-r0
+ mov.l r11, @-r0
+ mov.l r10, @-r0
+ mov.l r9, @-r0
+ mov.l r8, @-r0
+
+ mov r5, r8
+
+ /* sigprocmask (SIG_SETMASK, &uc->uc_sigmask, &ouc->uc_sigmask). */
+ add #oSIGMASK, r5
+ mov r4, r6
+ add #oSIGMASK, r6
+ mov #SIG_SETMASK, r4
+ mov #+SYS_ify(sigprocmask), r3
+ trapa #0x13
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lswapcontext_restore
+.Lsyscall_error:
+ SYSCALL_ERROR_HANDLER
+.Lpseudo_end:
+ rts
+ nop
+.Lswapcontext_restore:
+ mov r8, r0
+ add #(oPC), r0
+ mov.l @r0+, r2
+ lds.l @r0+, pr
+
+ /* Restore T frag. */
+ mov.l @r0+, r1
+ shlr r1
+ /* Skip GBR which is used for thread pointer. */
+ add #4, r0
+
+ lds.l @r0+, mach
+ lds.l @r0+, macl
+
+ mov r8, r0
+ add #(oR9), r0
+ mov.l @r0+, r9
+ mov.l @r0+, r10
+ mov.l @r0+, r11
+ mov.l @r0+, r12
+ mov.l @r0+, r13
+ mov.l @r0+, r14
+ mov.l @r0+, r15
+
+ mov r8, r0
+ mov.l @(oR0,r0), r1
+ mov.l r1, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r1, 0)
+ mov.l r2, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r2, 0)
+
+ mov.l @(oR1,r0), r1
+ mov.l @(oR2,r0), r2
+ mov.l @(oR3,r0), r3
+ mov.l @(oR4,r0), r4
+ mov.l @(oR5,r0), r5
+ mov.l @(oR6,r0), r6
+ mov.l @(oR7,r0), r7
+ mov.l @(oR8,r0), r8
+ mov.l @r15+, r0
+ jmp @r0
+ mov.l @r15+, r0
+
+PSEUDO_END(__swapcontext)
+
+weak_alias (__swapcontext, swapcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh3/sys/ucontext.h b/libc/sysdeps/unix/sysv/linux/sh/sh3/sys/ucontext.h
new file mode 100644
index 000000000..946df0dfd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh3/sys/ucontext.h
@@ -0,0 +1,102 @@
+/* Copyright (C) 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Where is System V/SH ABI? */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+
+/* We need the signal context definitions even if they are not used
+ included in <signal.h>. */
+#include <bits/sigcontext.h>
+
+
+typedef int greg_t;
+
+/* Number of general registers. */
+#define NFPREG 16
+
+/* Container for all general registers. */
+typedef greg_t gregset_t[NFPREG];
+
+#ifdef __USE_GNU
+/* Number of each register is the `gregset_t' array. */
+enum
+{
+ R0 = 0,
+#define R0 R0
+ R1 = 1,
+#define R1 R1
+ R2 = 2,
+#define R2 R2
+ R3 = 3,
+#define R3 R3
+ R4 = 4,
+#define R4 R4
+ R5 = 5,
+#define R5 R5
+ R6 = 6,
+#define R6 R6
+ R7 = 7,
+#define R7 R7
+ R8 = 8,
+#define R8 R8
+ R9 = 9,
+#define R9 R9
+ R10 = 10,
+#define R10 R10
+ R11 = 11,
+#define R11 R11
+ R12 = 12,
+#define R12 R12
+ R13 = 13,
+#define R13 R13
+ R14 = 14,
+#define R14 R14
+ R15 = 15,
+#define R15 R15
+};
+#endif
+
+/* Context to describe whole processor state. */
+typedef struct
+ {
+ unsigned int oldmask;
+ gregset_t gregs;
+ unsigned int pc;
+ unsigned int pr;
+ unsigned int sr;
+ unsigned int gbr;
+ unsigned int mach;
+ unsigned int macl;
+ } mcontext_t;
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ __sigset_t uc_sigmask;
+ } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh3/ucontext_i.sym b/libc/sysdeps/unix/sysv/linux/sh/sh3/ucontext_i.sym
new file mode 100644
index 000000000..17397c551
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh3/ucontext_i.sym
@@ -0,0 +1,38 @@
+#include <stddef.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+--
+
+SIG_BLOCK
+SIG_SETMASK
+
+#define ucontext(member) offsetof (ucontext_t, member)
+#define mcontext(member) ucontext (uc_mcontext.member)
+
+oLINK ucontext (uc_link)
+oSS_SP ucontext (uc_stack.ss_sp)
+oSS_SIZE ucontext (uc_stack.ss_size)
+oR0 mcontext (gregs[R0])
+oR1 mcontext (gregs[R1])
+oR2 mcontext (gregs[R2])
+oR3 mcontext (gregs[R3])
+oR4 mcontext (gregs[R4])
+oR5 mcontext (gregs[R5])
+oR6 mcontext (gregs[R6])
+oR7 mcontext (gregs[R7])
+oR8 mcontext (gregs[R8])
+oR9 mcontext (gregs[R9])
+oR10 mcontext (gregs[R10])
+oR11 mcontext (gregs[R11])
+oR12 mcontext (gregs[R12])
+oR13 mcontext (gregs[R13])
+oR14 mcontext (gregs[R14])
+oR15 mcontext (gregs[R15])
+oPC mcontext (pc)
+oPR mcontext (pr)
+oSR mcontext (sr)
+oGBR mcontext (gbr)
+oMACH mcontext (mach)
+oMACL mcontext (macl)
+oSIGMASK ucontext (uc_sigmask)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh4/getcontext.S b/libc/sysdeps/unix/sysv/linux/sh/sh4/getcontext.S
new file mode 100644
index 000000000..68bc235bc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh4/getcontext.S
@@ -0,0 +1,131 @@
+/* Save current context.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+/* int __getcontext (ucontext_t *uc); */
+
+ .text
+ .align 5
+ENTRY(__getcontext)
+
+ /* Return value of getcontext. R0 is the only register whose
+ value is not preserved. */
+ mov #0, r0
+ mov.l r0, @(oR0,r4)
+ mov.l r1, @(oR1,r4)
+ mov.l r2, @(oR2,r4)
+ mov.l r3, @(oR3,r4)
+ mov.l r4, @(oR4,r4)
+ mov.l r5, @(oR5,r4)
+ mov.l r6, @(oR6,r4)
+ mov.l r7, @(oR7,r4)
+ mov r4, r0
+ add #(oMACL+4), r0
+ sts.l macl, @-r0
+ sts.l mach, @-r0
+ stc.l gbr, @-r0
+
+ /* Save T flag to SR. */
+ movt r1
+ mov.l r1, @-r0
+ sts.l pr, @-r0
+
+ /* The return address of getcontext is the restart pc. */
+ sts.l pr, @-r0
+
+ mov.l r15, @-r0
+ mov.l r14, @-r0
+ mov.l r13, @-r0
+ mov.l r12, @-r0
+ mov.l r11, @-r0
+ mov.l r10, @-r0
+ mov.l r9, @-r0
+ mov.l r8, @-r0
+
+ mov r4, r0
+ /* We need 2 add instruction because oFPUL+4 > 127. */
+ add #124,r0
+ add #(oFPUL+4-124),r0
+ sts.l fpul, @-r0
+ sts.l fpscr, @-r0
+ frchg
+ fmov.s fr15, @-r0
+ fmov.s fr14, @-r0
+ fmov.s fr13, @-r0
+ fmov.s fr12, @-r0
+ fmov.s fr11, @-r0
+ fmov.s fr10, @-r0
+ fmov.s fr9, @-r0
+ fmov.s fr8, @-r0
+ fmov.s fr7, @-r0
+ fmov.s fr6, @-r0
+ fmov.s fr5, @-r0
+ fmov.s fr4, @-r0
+ fmov.s fr3, @-r0
+ fmov.s fr2, @-r0
+ fmov.s fr1, @-r0
+ fmov.s fr0, @-r0
+ frchg
+ fmov.s fr15, @-r0
+ fmov.s fr14, @-r0
+ fmov.s fr13, @-r0
+ fmov.s fr12, @-r0
+ fmov.s fr11, @-r0
+ fmov.s fr10, @-r0
+ fmov.s fr9, @-r0
+ fmov.s fr8, @-r0
+ fmov.s fr7, @-r0
+ fmov.s fr6, @-r0
+ fmov.s fr5, @-r0
+ fmov.s fr4, @-r0
+ fmov.s fr3, @-r0
+ fmov.s fr2, @-r0
+ fmov.s fr1, @-r0
+ fmov.s fr0, @-r0
+
+ /* sigprocmask (SIG_BLOCK, NULL, &uc->uc_sigmask). */
+ mov r4, r6
+ /* We need 2 add instruction because oSIGMASK > 127. */
+ add #(oSIGMASK/2), r6
+ add #(oSIGMASK/2), r6
+ mov #SIG_BLOCK, r4
+ mov #0, r5
+ mov #+SYS_ify(sigprocmask), r3
+ trapa #0x13
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lgetcontext_end
+.Lsyscall_error:
+ SYSCALL_ERROR_HANDLER
+.Lgetcontext_end:
+ /* All done, return 0 for success. */
+ mov #0, r0
+.Lpseudo_end:
+ rts
+ nop
+
+PSEUDO_END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh4/register-dump.h b/libc/sysdeps/unix/sysv/linux/sh/sh4/register-dump.h
new file mode 100644
index 000000000..d09ad2a37
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh4/register-dump.h
@@ -0,0 +1,262 @@
+/* Dump registers.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/uio.h>
+#include <stdio-common/_itoa.h>
+
+/* We will print the register dump in this format:
+
+ R0: XXXXXXXX R1: XXXXXXXX R2: XXXXXXXX R3: XXXXXXXX
+ R4: XXXXXXXX R5: XXXXXXXX R6: XXXXXXXX R7: XXXXXXXX
+ R8: XXXXXXXX R9: XXXXXXXX R10: XXXXXXXX R11: XXXXXXXX
+ R12: XXXXXXXX R13: XXXXXXXX R14: XXXXXXXX R15: XXXXXXXX
+
+MACL: XXXXXXXX MACH: XXXXXXXX
+
+ PC: XXXXXXXX PR: XXXXXXXX GBR: XXXXXXXX SR: XXXXXXXX
+
+ FR0: XXXXXXXX FR1: XXXXXXXX FR2: XXXXXXXX FR3: XXXXXXXX
+ FR4: XXXXXXXX FR5: XXXXXXXX FR6: XXXXXXXX FR7: XXXXXXXX
+ FR8: XXXXXXXX FR9: XXXXXXXX FR10: XXXXXXXX FR11: XXXXXXXX
+FR12: XXXXXXXX FR13: XXXXXXXX FR14: XXXXXXXX FR15: XXXXXXXX
+
+ XR0: XXXXXXXX XR1: XXXXXXXX XR2: XXXXXXXX XR3: XXXXXXXX
+ XR4: XXXXXXXX XR5: XXXXXXXX XR6: XXXXXXXX XR7: XXXXXXXX
+ XR8: XXXXXXXX XR9: XXXXXXXX XR10: XXXXXXXX XR11: XXXXXXXX
+XR12: XXXXXXXX XR13: XXXXXXXX XR14: XXXXXXXX XR15: XXXXXXXX
+
+FPSCR: XXXXXXXX FPUL: XXXXXXXX
+
+ */
+
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
+{
+ char *cp = _itoa_word (value, buf + len, 16, 0);
+ while (cp > buf)
+ *--cp = '0';
+}
+
+static void
+register_dump (int fd, struct sigcontext *ctx)
+{
+ char regs[22][8];
+ char fpregs[34][8];
+ struct iovec iov[112];
+ size_t nr = 0;
+
+#define ADD_STRING(str) \
+ iov[nr].iov_base = (char *) str; \
+ iov[nr].iov_len = strlen (str); \
+ ++nr
+#define ADD_MEM(str, len) \
+ iov[nr].iov_base = str; \
+ iov[nr].iov_len = len; \
+ ++nr
+
+ /* Generate strings of register contents. */
+ hexvalue (ctx->sc_regs[0], regs[0], 8);
+ hexvalue (ctx->sc_regs[1], regs[1], 8);
+ hexvalue (ctx->sc_regs[2], regs[2], 8);
+ hexvalue (ctx->sc_regs[3], regs[3], 8);
+ hexvalue (ctx->sc_regs[4], regs[4], 8);
+ hexvalue (ctx->sc_regs[5], regs[5], 8);
+ hexvalue (ctx->sc_regs[6], regs[6], 8);
+ hexvalue (ctx->sc_regs[7], regs[7], 8);
+ hexvalue (ctx->sc_regs[8], regs[8], 8);
+ hexvalue (ctx->sc_regs[9], regs[9], 8);
+ hexvalue (ctx->sc_regs[10], regs[10], 8);
+ hexvalue (ctx->sc_regs[11], regs[11], 8);
+ hexvalue (ctx->sc_regs[12], regs[12], 8);
+ hexvalue (ctx->sc_regs[13], regs[13], 8);
+ hexvalue (ctx->sc_regs[14], regs[14], 8);
+ hexvalue (ctx->sc_regs[15], regs[15], 8);
+ hexvalue (ctx->sc_macl, regs[16], 8);
+ hexvalue (ctx->sc_mach, regs[17], 8);
+ hexvalue (ctx->sc_pc, regs[18], 8);
+ hexvalue (ctx->sc_pr, regs[19], 8);
+ hexvalue (ctx->sc_gbr, regs[20], 8);
+ hexvalue (ctx->sc_sr, regs[21], 8);
+
+ /* Generate the output. */
+ ADD_STRING ("Register dump:\n\n R0: ");
+ ADD_MEM (regs[0], 8);
+ ADD_STRING (" R1: ");
+ ADD_MEM (regs[1], 8);
+ ADD_STRING (" R2: ");
+ ADD_MEM (regs[2], 8);
+ ADD_STRING (" R3: ");
+ ADD_MEM (regs[3], 8);
+ ADD_STRING ("\n R4: ");
+ ADD_MEM (regs[4], 8);
+ ADD_STRING (" R5: ");
+ ADD_MEM (regs[5], 8);
+ ADD_STRING (" R6: ");
+ ADD_MEM (regs[6], 8);
+ ADD_STRING (" R7: ");
+ ADD_MEM (regs[7], 8);
+ ADD_STRING ("\n R8: ");
+ ADD_MEM (regs[8], 8);
+ ADD_STRING (" R9: ");
+ ADD_MEM (regs[9], 8);
+ ADD_STRING (" R10: ");
+ ADD_MEM (regs[10], 8);
+ ADD_STRING (" R11: ");
+ ADD_MEM (regs[11], 8);
+ ADD_STRING ("\n R12: ");
+ ADD_MEM (regs[12], 8);
+ ADD_STRING (" R13: ");
+ ADD_MEM (regs[13], 8);
+ ADD_STRING (" R14: ");
+ ADD_MEM (regs[14], 8);
+ ADD_STRING (" R15: ");
+ ADD_MEM (regs[15], 8);
+
+ ADD_STRING ("\n\nMACL: ");
+ ADD_MEM (regs[16], 8);
+ ADD_STRING (" MACH: ");
+ ADD_MEM (regs[17], 8);
+
+ ADD_STRING ("\n\n PC: ");
+ ADD_MEM (regs[18], 8);
+ ADD_STRING (" PR: ");
+ ADD_MEM (regs[19], 8);
+ ADD_STRING (" GBR: ");
+ ADD_MEM (regs[20], 8);
+ ADD_STRING (" SR: ");
+ ADD_MEM (regs[21], 8);
+
+ ADD_STRING ("\n");
+
+ if (ctx->sc_ownedfp != NULL)
+ {
+ hexvalue (ctx->sc_fpregs[0], fpregs[0], 8);
+ hexvalue (ctx->sc_fpregs[1], fpregs[1], 8);
+ hexvalue (ctx->sc_fpregs[2], fpregs[2], 8);
+ hexvalue (ctx->sc_fpregs[3], fpregs[3], 8);
+ hexvalue (ctx->sc_fpregs[4], fpregs[4], 8);
+ hexvalue (ctx->sc_fpregs[5], fpregs[5], 8);
+ hexvalue (ctx->sc_fpregs[6], fpregs[6], 8);
+ hexvalue (ctx->sc_fpregs[7], fpregs[7], 8);
+ hexvalue (ctx->sc_fpregs[8], fpregs[8], 8);
+ hexvalue (ctx->sc_fpregs[9], fpregs[9], 8);
+ hexvalue (ctx->sc_fpregs[10], fpregs[10], 8);
+ hexvalue (ctx->sc_fpregs[11], fpregs[11], 8);
+ hexvalue (ctx->sc_fpregs[12], fpregs[12], 8);
+ hexvalue (ctx->sc_fpregs[13], fpregs[13], 8);
+ hexvalue (ctx->sc_fpregs[14], fpregs[14], 8);
+ hexvalue (ctx->sc_fpregs[15], fpregs[15], 8);
+ hexvalue (ctx->sc_xfpregs[0], fpregs[16], 8);
+ hexvalue (ctx->sc_xfpregs[1], fpregs[17], 8);
+ hexvalue (ctx->sc_xfpregs[2], fpregs[18], 8);
+ hexvalue (ctx->sc_xfpregs[3], fpregs[19], 8);
+ hexvalue (ctx->sc_xfpregs[4], fpregs[20], 8);
+ hexvalue (ctx->sc_xfpregs[5], fpregs[21], 8);
+ hexvalue (ctx->sc_xfpregs[6], fpregs[22], 8);
+ hexvalue (ctx->sc_xfpregs[7], fpregs[23], 8);
+ hexvalue (ctx->sc_xfpregs[8], fpregs[24], 8);
+ hexvalue (ctx->sc_xfpregs[9], fpregs[25], 8);
+ hexvalue (ctx->sc_xfpregs[10], fpregs[26], 8);
+ hexvalue (ctx->sc_xfpregs[11], fpregs[27], 8);
+ hexvalue (ctx->sc_xfpregs[12], fpregs[28], 8);
+ hexvalue (ctx->sc_xfpregs[13], fpregs[29], 8);
+ hexvalue (ctx->sc_xfpregs[14], fpregs[30], 8);
+ hexvalue (ctx->sc_xfpregs[15], fpregs[31], 8);
+ hexvalue (ctx->sc_fpscr, fpregs[32], 8);
+ hexvalue (ctx->sc_fpul, fpregs[33], 8);
+
+ ADD_STRING ("\n\n FR0: ");
+ ADD_MEM (fpregs[0], 8);
+ ADD_STRING (" FR1: ");
+ ADD_MEM (fpregs[1], 8);
+ ADD_STRING (" FR2: ");
+ ADD_MEM (fpregs[2], 8);
+ ADD_STRING (" FR3: ");
+ ADD_MEM (fpregs[3], 8);
+ ADD_STRING ("\n FR4: ");
+ ADD_MEM (fpregs[4], 8);
+ ADD_STRING (" FR5: ");
+ ADD_MEM (fpregs[5], 8);
+ ADD_STRING (" FR6: ");
+ ADD_MEM (fpregs[6], 8);
+ ADD_STRING (" FR7: ");
+ ADD_MEM (fpregs[7], 8);
+ ADD_STRING ("\n FR8: ");
+ ADD_MEM (fpregs[8], 8);
+ ADD_STRING (" FR9: ");
+ ADD_MEM (fpregs[9], 8);
+ ADD_STRING (" FR10: ");
+ ADD_MEM (fpregs[10], 8);
+ ADD_STRING (" FR11: ");
+ ADD_MEM (fpregs[11], 8);
+ ADD_STRING ("\nFR12: ");
+ ADD_MEM (fpregs[12], 8);
+ ADD_STRING (" FR13: ");
+ ADD_MEM (fpregs[13], 8);
+ ADD_STRING (" FR14: ");
+ ADD_MEM (fpregs[14], 8);
+ ADD_STRING (" FR15: ");
+ ADD_MEM (fpregs[15], 8);
+ ADD_STRING ("\n\n XR0: ");
+ ADD_MEM (fpregs[16], 8);
+ ADD_STRING (" XR1: ");
+ ADD_MEM (fpregs[17], 8);
+ ADD_STRING (" XR2: ");
+ ADD_MEM (fpregs[18], 8);
+ ADD_STRING (" XR3: ");
+ ADD_MEM (fpregs[19], 8);
+ ADD_STRING ("\n XR4: ");
+ ADD_MEM (fpregs[20], 8);
+ ADD_STRING (" XR5: ");
+ ADD_MEM (fpregs[21], 8);
+ ADD_STRING (" XR6: ");
+ ADD_MEM (fpregs[22], 8);
+ ADD_STRING (" XR7: ");
+ ADD_MEM (fpregs[23], 8);
+ ADD_STRING ("\n XR8: ");
+ ADD_MEM (fpregs[24], 8);
+ ADD_STRING (" XR9: ");
+ ADD_MEM (fpregs[25], 8);
+ ADD_STRING (" XR10: ");
+ ADD_MEM (fpregs[26], 8);
+ ADD_STRING (" XR11: ");
+ ADD_MEM (fpregs[27], 8);
+ ADD_STRING ("\nXR12: ");
+ ADD_MEM (fpregs[28], 8);
+ ADD_STRING (" XR13: ");
+ ADD_MEM (fpregs[29], 8);
+ ADD_STRING (" XR14: ");
+ ADD_MEM (fpregs[30], 8);
+ ADD_STRING (" XR15: ");
+ ADD_MEM (fpregs[31], 8);
+
+ ADD_STRING ("\n\nFPSCR: ");
+ ADD_MEM (fpregs[32], 8);
+ ADD_STRING (" FPUL: ");
+ ADD_MEM (fpregs[33], 8);
+
+ ADD_STRING ("\n");
+ }
+
+ /* Write the stuff out. */
+ writev (fd, iov, nr);
+}
+
+
+#define REGISTER_DUMP register_dump (fd, &ctx)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh4/setcontext.S b/libc/sysdeps/unix/sysv/linux/sh/sh4/setcontext.S
new file mode 100644
index 000000000..2bc546d1a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh4/setcontext.S
@@ -0,0 +1,139 @@
+/* Install given context.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+/* int __setcontext (const ucontext_t *uc); */
+
+ .text
+ .align 5
+ENTRY(__setcontext)
+
+ mov r4, r8
+
+ /* sigprocmask (SIG_SETMASK, &uc->uc_sigmask, NULL). */
+ mov r4, r5
+ add #(oSIGMASK/2), r5
+ add #(oSIGMASK/2), r5
+ mov #SIG_SETMASK, r4
+ mov #0, r6
+ mov #+SYS_ify(sigprocmask), r3
+ trapa #0x13
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lsetcontext_restore
+.Lsyscall_error:
+ SYSCALL_ERROR_HANDLER
+.Lpseudo_end:
+ rts
+ nop
+
+.Lsetcontext_restore:
+ mov r8, r0
+ add #(oFR0),r0
+ fmov.s @r0+, fr0
+ fmov.s @r0+, fr1
+ fmov.s @r0+, fr2
+ fmov.s @r0+, fr3
+ fmov.s @r0+, fr4
+ fmov.s @r0+, fr5
+ fmov.s @r0+, fr6
+ fmov.s @r0+, fr7
+ fmov.s @r0+, fr8
+ fmov.s @r0+, fr9
+ fmov.s @r0+, fr10
+ fmov.s @r0+, fr11
+ fmov.s @r0+, fr12
+ fmov.s @r0+, fr13
+ fmov.s @r0+, fr14
+ fmov.s @r0+, fr15
+ frchg
+ fmov.s @r0+, fr0
+ fmov.s @r0+, fr1
+ fmov.s @r0+, fr2
+ fmov.s @r0+, fr3
+ fmov.s @r0+, fr4
+ fmov.s @r0+, fr5
+ fmov.s @r0+, fr6
+ fmov.s @r0+, fr7
+ fmov.s @r0+, fr8
+ fmov.s @r0+, fr9
+ fmov.s @r0+, fr10
+ fmov.s @r0+, fr11
+ fmov.s @r0+, fr12
+ fmov.s @r0+, fr13
+ fmov.s @r0+, fr14
+ fmov.s @r0+, fr15
+ frchg
+ lds.l @r0+, fpscr
+ lds.l @r0+, fpul
+
+ mov r8, r0
+ add #(oPC), r0
+ mov.l @r0+, r2
+ lds.l @r0+, pr
+
+ /* Restore T frag. */
+ mov.l @r0+, r1
+ shlr r1
+ /* Skip GBR which is used for thread pointer. */
+ add #4, r0
+
+ lds.l @r0+, mach
+ lds.l @r0+, macl
+
+ mov r8, r0
+ add #(oR9), r0
+ mov.l @r0+, r9
+ mov.l @r0+, r10
+ mov.l @r0+, r11
+ mov.l @r0+, r12
+ mov.l @r0+, r13
+ mov.l @r0+, r14
+ mov.l @r0+, r15
+
+ mov r8, r0
+ mov.l @(oR0,r0), r1
+ mov.l r1, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r1, 0)
+ mov.l r2, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r2, 0)
+
+ mov.l @(oR1,r0), r1
+ mov.l @(oR2,r0), r2
+ mov.l @(oR3,r0), r3
+ mov.l @(oR4,r0), r4
+ mov.l @(oR5,r0), r5
+ mov.l @(oR6,r0), r6
+ mov.l @(oR7,r0), r7
+ mov.l @(oR8,r0), r8
+ mov.l @r15+, r0
+ jmp @r0
+ mov.l @r15+, r0
+
+PSEUDO_END(__setcontext)
+
+weak_alias (__setcontext, setcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S b/libc/sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S
new file mode 100644
index 000000000..1aeca1b1a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S
@@ -0,0 +1,214 @@
+/* Save current context and install the given one.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+/* int __swapcontext (ucontext_t *ouc, const ucontext_t *uc); */
+
+ .text
+ .align 5
+ENTRY(__swapcontext)
+
+ /* Return value of getcontext. R0 is the only register whose
+ value is not preserved. */
+ mov #0, r0
+ mov.l r0, @(oR0,r4)
+ mov.l r1, @(oR1,r4)
+ mov.l r2, @(oR2,r4)
+ mov.l r3, @(oR3,r4)
+ mov.l r4, @(oR4,r4)
+ mov.l r5, @(oR5,r4)
+ mov.l r6, @(oR6,r4)
+ mov.l r7, @(oR7,r4)
+ mov r4, r0
+ add #(oMACL+4), r0
+ sts.l macl, @-r0
+ sts.l mach, @-r0
+ stc.l gbr, @-r0
+
+ /* Save T flag to SR. */
+ movt r1
+ mov.l r1, @-r0
+ sts.l pr, @-r0
+
+ /* The return address of getcontext is the restart pc. */
+ sts.l pr, @-r0
+
+ mov.l r15, @-r0
+ mov.l r14, @-r0
+ mov.l r13, @-r0
+ mov.l r12, @-r0
+ mov.l r11, @-r0
+ mov.l r10, @-r0
+ mov.l r9, @-r0
+ mov.l r8, @-r0
+
+ mov r4, r0
+ /* We need 2 add instruction because oFPUL+4 >= 127. */
+ add #124,r0
+ add #(oFPUL+4-124),r0
+ sts.l fpul, @-r0
+ sts.l fpscr, @-r0
+ frchg
+ fmov.s fr15, @-r0
+ fmov.s fr14, @-r0
+ fmov.s fr13, @-r0
+ fmov.s fr12, @-r0
+ fmov.s fr11, @-r0
+ fmov.s fr10, @-r0
+ fmov.s fr9, @-r0
+ fmov.s fr8, @-r0
+ fmov.s fr7, @-r0
+ fmov.s fr6, @-r0
+ fmov.s fr5, @-r0
+ fmov.s fr4, @-r0
+ fmov.s fr3, @-r0
+ fmov.s fr2, @-r0
+ fmov.s fr1, @-r0
+ fmov.s fr0, @-r0
+ frchg
+ fmov.s fr15, @-r0
+ fmov.s fr14, @-r0
+ fmov.s fr13, @-r0
+ fmov.s fr12, @-r0
+ fmov.s fr11, @-r0
+ fmov.s fr10, @-r0
+ fmov.s fr9, @-r0
+ fmov.s fr8, @-r0
+ fmov.s fr7, @-r0
+ fmov.s fr6, @-r0
+ fmov.s fr5, @-r0
+ fmov.s fr4, @-r0
+ fmov.s fr3, @-r0
+ fmov.s fr2, @-r0
+ fmov.s fr1, @-r0
+ fmov.s fr0, @-r0
+
+ mov r5, r8
+
+ /* sigprocmask (SIG_SETMASK, &uc->uc_sigmask, &ouc->uc_sigmask). */
+ mov #oSIGMASK, r1
+ extu.b r1, r1
+ add r1, r5
+ mov r4, r6
+ add r1, r6
+ mov #SIG_SETMASK, r4
+ mov #+SYS_ify(sigprocmask), r3
+ trapa #0x13
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lswapcontext_restore
+.Lsyscall_error:
+ SYSCALL_ERROR_HANDLER
+.Lpseudo_end:
+ rts
+ nop
+.Lswapcontext_restore:
+ mov r8, r0
+ add #(oFR0),r0
+ fmov.s @r0+, fr0
+ fmov.s @r0+, fr1
+ fmov.s @r0+, fr2
+ fmov.s @r0+, fr3
+ fmov.s @r0+, fr4
+ fmov.s @r0+, fr5
+ fmov.s @r0+, fr6
+ fmov.s @r0+, fr7
+ fmov.s @r0+, fr8
+ fmov.s @r0+, fr9
+ fmov.s @r0+, fr10
+ fmov.s @r0+, fr11
+ fmov.s @r0+, fr12
+ fmov.s @r0+, fr13
+ fmov.s @r0+, fr14
+ fmov.s @r0+, fr15
+ frchg
+ fmov.s @r0+, fr0
+ fmov.s @r0+, fr1
+ fmov.s @r0+, fr2
+ fmov.s @r0+, fr3
+ fmov.s @r0+, fr4
+ fmov.s @r0+, fr5
+ fmov.s @r0+, fr6
+ fmov.s @r0+, fr7
+ fmov.s @r0+, fr8
+ fmov.s @r0+, fr9
+ fmov.s @r0+, fr10
+ fmov.s @r0+, fr11
+ fmov.s @r0+, fr12
+ fmov.s @r0+, fr13
+ fmov.s @r0+, fr14
+ fmov.s @r0+, fr15
+ frchg
+ lds.l @r0+, fpscr
+ lds.l @r0+, fpul
+
+ mov r8, r0
+ add #(oPC), r0
+ mov.l @r0+, r2
+ lds.l @r0+, pr
+
+ /* Restore T frag. */
+ mov.l @r0+, r1
+ shlr r1
+ /* Skip GBR which is used for thread pointer. */
+ add #4, r0
+
+ lds.l @r0+, mach
+ lds.l @r0+, macl
+
+ mov r8, r0
+ add #(oR9), r0
+ mov.l @r0+, r9
+ mov.l @r0+, r10
+ mov.l @r0+, r11
+ mov.l @r0+, r12
+ mov.l @r0+, r13
+ mov.l @r0+, r14
+ mov.l @r0+, r15
+
+ mov r8, r0
+ mov.l @(oR0,r0), r1
+ mov.l r1, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r1, 0)
+ mov.l r2, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r2, 0)
+
+ mov.l @(oR1,r0), r1
+ mov.l @(oR2,r0), r2
+ mov.l @(oR3,r0), r3
+ mov.l @(oR4,r0), r4
+ mov.l @(oR5,r0), r5
+ mov.l @(oR6,r0), r6
+ mov.l @(oR7,r0), r7
+ mov.l @(oR8,r0), r8
+ mov.l @r15+, r0
+ jmp @r0
+ mov.l @r15+, r0
+
+PSEUDO_END(__swapcontext)
+
+weak_alias (__swapcontext, swapcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh4/sys/ucontext.h b/libc/sysdeps/unix/sysv/linux/sh/sh4/sys/ucontext.h
new file mode 100644
index 000000000..cd831a7a2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh4/sys/ucontext.h
@@ -0,0 +1,115 @@
+/* Copyright (C) 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Where is System V/SH ABI? */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+
+/* We need the signal context definitions even if they are not used
+ included in <signal.h>. */
+#include <bits/sigcontext.h>
+
+
+typedef int greg_t;
+
+/* Number of general registers. */
+#define NFPREG 16
+
+/* Container for all general registers. */
+typedef greg_t gregset_t[NFPREG];
+
+#ifdef __USE_GNU
+/* Number of each register is the `gregset_t' array. */
+enum
+{
+ R0 = 0,
+#define R0 R0
+ R1 = 1,
+#define R1 R1
+ R2 = 2,
+#define R2 R2
+ R3 = 3,
+#define R3 R3
+ R4 = 4,
+#define R4 R4
+ R5 = 5,
+#define R5 R5
+ R6 = 6,
+#define R6 R6
+ R7 = 7,
+#define R7 R7
+ R8 = 8,
+#define R8 R8
+ R9 = 9,
+#define R9 R9
+ R10 = 10,
+#define R10 R10
+ R11 = 11,
+#define R11 R11
+ R12 = 12,
+#define R12 R12
+ R13 = 13,
+#define R13 R13
+ R14 = 14,
+#define R14 R14
+ R15 = 15,
+#define R15 R15
+};
+#endif
+
+typedef int freg_t;
+
+/* Number of FPU registers. */
+#define NFPREG 16
+
+/* Structure to describe FPU registers. */
+typedef freg_t fpregset_t[NFPREG];
+
+/* Context to describe whole processor state. */
+typedef struct
+ {
+ unsigned int oldmask;
+ gregset_t gregs;
+ unsigned int pc;
+ unsigned int pr;
+ unsigned int sr;
+ unsigned int gbr;
+ unsigned int mach;
+ unsigned int macl;
+ fpregset_t fpregs;
+ fpregset_t xfpregs;
+ unsigned int fpscr;
+ unsigned int fpul;
+ unsigned int ownedfp;
+ } mcontext_t;
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ __sigset_t uc_sigmask;
+ } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh4/sysdep.h b/libc/sysdeps/unix/sysv/linux/sh/sh4/sysdep.h
new file mode 100644
index 000000000..852f8eed7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh4/sysdep.h
@@ -0,0 +1,4 @@
+/* 4 instruction cycles not accessing cache and TLB are needed after
+ trapa instruction to avoid an SH-4 silicon bug. */
+#define NEED_SYSCALL_INST_PAD
+#include <sysdeps/unix/sysv/linux/sh/sysdep.h>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sh4/ucontext_i.sym b/libc/sysdeps/unix/sysv/linux/sh/sh4/ucontext_i.sym
new file mode 100644
index 000000000..65633fbcf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sh4/ucontext_i.sym
@@ -0,0 +1,73 @@
+#include <stddef.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+--
+
+SIG_BLOCK
+SIG_SETMASK
+
+#define ucontext(member) offsetof (ucontext_t, member)
+#define mcontext(member) ucontext (uc_mcontext.member)
+
+oLINK ucontext (uc_link)
+oSS_SP ucontext (uc_stack.ss_sp)
+oSS_SIZE ucontext (uc_stack.ss_size)
+oR0 mcontext (gregs[R0])
+oR1 mcontext (gregs[R1])
+oR2 mcontext (gregs[R2])
+oR3 mcontext (gregs[R3])
+oR4 mcontext (gregs[R4])
+oR5 mcontext (gregs[R5])
+oR6 mcontext (gregs[R6])
+oR7 mcontext (gregs[R7])
+oR8 mcontext (gregs[R8])
+oR9 mcontext (gregs[R9])
+oR10 mcontext (gregs[R10])
+oR11 mcontext (gregs[R11])
+oR12 mcontext (gregs[R12])
+oR13 mcontext (gregs[R13])
+oR14 mcontext (gregs[R14])
+oR15 mcontext (gregs[R15])
+oPC mcontext (pc)
+oPR mcontext (pr)
+oSR mcontext (sr)
+oGBR mcontext (gbr)
+oMACH mcontext (mach)
+oMACL mcontext (macl)
+oFR0 mcontext (fpregs[0])
+oFR1 mcontext (fpregs[1])
+oFR2 mcontext (fpregs[2])
+oFR3 mcontext (fpregs[3])
+oFR4 mcontext (fpregs[4])
+oFR5 mcontext (fpregs[5])
+oFR6 mcontext (fpregs[6])
+oFR7 mcontext (fpregs[7])
+oFR8 mcontext (fpregs[8])
+oFR9 mcontext (fpregs[9])
+oFR10 mcontext (fpregs[10])
+oFR11 mcontext (fpregs[11])
+oFR12 mcontext (fpregs[12])
+oFR13 mcontext (fpregs[13])
+oFR14 mcontext (fpregs[14])
+oFR15 mcontext (fpregs[15])
+oXFR0 mcontext (xfpregs[0])
+oXFR1 mcontext (xfpregs[1])
+oXFR2 mcontext (xfpregs[2])
+oXFR3 mcontext (xfpregs[3])
+oXFR4 mcontext (xfpregs[4])
+oXFR5 mcontext (xfpregs[5])
+oXFR6 mcontext (xfpregs[6])
+oXFR7 mcontext (xfpregs[7])
+oXFR8 mcontext (xfpregs[8])
+oXFR9 mcontext (xfpregs[9])
+oXFR10 mcontext (xfpregs[10])
+oXFR11 mcontext (xfpregs[11])
+oXFR12 mcontext (xfpregs[12])
+oXFR13 mcontext (xfpregs[13])
+oXFR14 mcontext (xfpregs[14])
+oXFR15 mcontext (xfpregs[15])
+oFPSCR mcontext (fpscr)
+oFPUL mcontext (fpul)
+oOWNEDFP mcontext (ownedfp)
+oSIGMASK ucontext (uc_sigmask)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/shmctl.c b/libc/sysdeps/unix/sysv/linux/sh/shmctl.c
new file mode 100644
index 000000000..7eac6380d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/shmctl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/shmctl.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h b/libc/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h
new file mode 100644
index 000000000..3e1f3e949
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Philip Blundell <philb@gnu.org>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define SIGCONTEXT int _a2, int _a3, int _a4, struct sigcontext
+
+#define SIGCONTEXT_EXTRA_ARGS _a2, _a3, _a4,
+#define GET_PC(ctx) ((void *) ctx.sc_pc)
+#define GET_FRAME(ctx) ((void *) ctx.sc_regs[14])
+#define GET_STACK(ctx) ((void *) ctx.sc_regs[15])
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/libc/sysdeps/unix/sysv/linux/sh/socket.S b/libc/sysdeps/unix/sysv/linux/sh/socket.S
new file mode 100644
index 000000000..c83b0f260
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/socket.S
@@ -0,0 +1,180 @@
+/* Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep-cancel.h>
+#include <socketcall.h>
+#include <tls.h>
+
+#define P(a, b) P2(a, b)
+#define P2(a, b) a##b
+
+ .text
+/* The socket-oriented system calls are handled unusally in Linux.
+ They are all gated through the single `socketcall' system call number.
+ `socketcall' takes two arguments: the first is the subcode, specifying
+ which socket function is being called; and the second is a pointer to
+ the arguments to the specific function.
+
+ The .S files for the other calls just #define socket and #include this. */
+
+#ifndef __socket
+#ifndef NO_WEAK_ALIAS
+#define __socket P(__,socket)
+#else
+#define __socket socket
+#endif
+#endif
+
+#define PUSHARGS_1 mov.l r4,@-r15; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (r4, 0)
+#define PUSHARGS_2 mov.l r5,@-r15; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (r5, 0); \
+ PUSHARGS_1
+#define PUSHARGS_3 mov.l r6,@-r15; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (r6, 0); \
+ PUSHARGS_2
+#define PUSHARGS_4 mov.l r7,@-r15; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (r7, 0); \
+ PUSHARGS_3
+#define PUSHARGS_5 PUSHARGS_4 /* Caller has already pushed arg 5 */
+#define PUSHARGS_6 PUSHARGS_4 /* Caller has already pushed arg 5,6 */
+
+#define POPARGS_1 add #4,r15; cfi_adjust_cfa_offset (-4)
+#define POPARGS_2 add #8,r15; cfi_adjust_cfa_offset (-8)
+#define POPARGS_3 add #12,r15; cfi_adjust_cfa_offset (-12)
+#define POPARGS_4 add #16,r15; cfi_adjust_cfa_offset (-16)
+#define POPARGS_5 POPARGS_4
+#define POPARGS_6 POPARGS_4
+
+#define ADJUSTCFI_1 cfi_adjust_cfa_offset (4); \
+ cfi_offset (r4, -4)
+#define ADJUSTCFI_2 cfi_adjust_cfa_offset (8); \
+ cfi_offset (r4, -4); \
+ cfi_offset (r5, -8)
+#define ADJUSTCFI_3 cfi_adjust_cfa_offset (12); \
+ cfi_offset (r4, -4); \
+ cfi_offset (r5, -8); \
+ cfi_offset (r6, -12)
+#define ADJUSTCFI_4 cfi_adjust_cfa_offset (16); \
+ cfi_offset (r4, -4); \
+ cfi_offset (r5, -8); \
+ cfi_offset (r6, -12); \
+ cfi_offset (r7, -16)
+#define ADJUSTCFI_5 ADJUSTCFI_4
+#define ADJUSTCFI_6 ADJUSTCFI_4
+
+#ifndef NARGS
+/* If we were called with no wrapper, this is really socket(). */
+#define NARGS 3
+#endif
+
+.globl __socket
+ENTRY (__socket)
+ /* This will not work in the case of a socket call being interrupted
+ by a signal. If the signal handler uses any stack the arguments
+ to socket will be trashed. The results of a restart of any
+ socket call are then unpredictable. */
+
+ /* Push args onto the stack. */
+ P(PUSHARGS_,NARGS)
+
+#if defined NEED_CANCELLATION && defined CENABLE
+ SINGLE_THREAD_P
+ bf .Lsocket_cancel
+#endif
+
+ /* Do the system call trap. */
+ mov #+P(SOCKOP_,socket), r4
+ mov r15, r5
+ mov.l .L1,r3
+ trapa #0x12
+
+ /* Pop args off the stack */
+ P(POPARGS_,NARGS)
+
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lpseudo_end
+.Lsyscall_error:
+ SYSCALL_ERROR_HANDLER
+.Lpseudo_end:
+ /* Successful; return the syscall's value. */
+ rts
+ nop
+
+#if defined NEED_CANCELLATION && defined CENABLE
+.Lsocket_cancel:
+ /* Enable asynchronous cancellation. */
+ P(ADJUSTCFI_,NARGS)
+ sts.l pr,@-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (pr, 0)
+ CENABLE
+ lds.l @r15+,pr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (pr)
+
+ /* Do the system call trap. */
+ mov #+P(SOCKOP_,socket), r4
+ mov r15, r5
+ mov.l .L1,r3
+ trapa #0x12
+
+ sts.l pr,@-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (pr, 0)
+ mov.l r0,@-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (r0, 0)
+ CDISABLE
+ mov.l @r15+,r0
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (r0)
+ lds.l @r15+,pr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (pr)
+
+ /* Pop args off the stack */
+ P(POPARGS_,NARGS)
+
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lpseudo_end
+ bra .Lsyscall_error
+ nop
+#endif
+
+ .align 2
+.L1:
+ .long SYS_ify(socketcall)
+
+PSEUDO_END (__socket)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__socket, socket)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sys/io.h b/libc/sysdeps/unix/sysv/linux/sh/sys/io.h
new file mode 100644
index 000000000..6fdc44ff8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sys/io.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IO_H
+
+#define _SYS_IO_H 1
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* If TURN_ON is TRUE, request for permission to do direct i/o on the
+ port numbers in the range [FROM,FROM+NUM-1]. Otherwise, turn I/O
+ permission off for that range. This call requires root privileges. */
+extern int ioperm (unsigned long int __from, unsigned long int __num,
+ int __turn_on) __THROW;
+
+/* Set the I/O privilege level to LEVEL. If LEVEL is nonzero,
+ permission to access any I/O port is granted. This call requires
+ root privileges. */
+extern int iopl (int __level) __THROW;
+
+/* The functions that actually perform reads and writes. */
+extern unsigned char inb (unsigned long int port) __THROW;
+extern unsigned short int inw (unsigned long int port) __THROW;
+extern unsigned long int inl (unsigned long int port) __THROW;
+
+extern void outb (unsigned char value, unsigned long int port) __THROW;
+extern void outw (unsigned short value, unsigned long int port) __THROW;
+extern void outl (unsigned long value, unsigned long int port) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_IO_H */
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sys/procfs.h b/libc/sysdeps/unix/sysv/linux/sh/sys/procfs.h
new file mode 100644
index 000000000..8651ccb34
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sys/procfs.h
@@ -0,0 +1,115 @@
+/* Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H 1
+
+/* This is somehow modelled after the file of the same name on SysVr4
+ systems. It provides a definition of the core file format for ELF
+ used on Linux. */
+
+#include <features.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ucontext.h>
+#include <sys/user.h>
+#include <asm/elf.h>
+
+__BEGIN_DECLS
+
+struct elf_siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_code; /* Extra code. */
+ int si_errno; /* Errno. */
+ };
+
+/* Definitions to generate Intel SVR4-like core files. These mostly
+ have the same names as the SVR4 types with "elf_" tacked on the
+ front to prevent clashes with linux definitions, and the typedef
+ forms have been avoided. This is mostly like the SVR4 structure,
+ but more Linuxy, with things that Linux does not support and which
+ gdb doesn't really use excluded. Fields present but not used are
+ marked with "XXX". */
+struct elf_prstatus
+ {
+#if 0
+ long int pr_flags; /* XXX Process flags. */
+ short int pr_why; /* XXX Reason for process halt. */
+ short int pr_what; /* XXX More detailed reason. */
+#endif
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned long int pr_sigpend; /* Set of pending signals. */
+ unsigned long int pr_sighold; /* Set of held signals. */
+#if 0
+ struct sigaltstack pr_altstack; /* Alternate stack info. */
+ struct sigaction pr_action; /* Signal action for current sig. */
+#endif
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct timeval pr_utime; /* User time. */
+ struct timeval pr_stime; /* System time. */
+ struct timeval pr_cutime; /* Cumulative user time. */
+ struct timeval pr_cstime; /* Cumulative system time. */
+#if 0
+ long int pr_instr; /* Current instruction. */
+#endif
+ elf_gregset_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+#define ELF_PRARGSZ (80) /* Number of chars for args */
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long int pr_flag; /* Flags. */
+ unsigned short int pr_uid;
+ unsigned short int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+/* Addresses. */
+typedef void *psaddr_t;
+
+/* Register sets. Linux has different names. */
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+ therefore habe only ine PID type. */
+typedef __pid_t lwpid_t;
+
+
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif /* sys/procfs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sys/user.h b/libc/sysdeps/unix/sysv/linux/sh/sys/user.h
new file mode 100644
index 000000000..7f31bb62d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sys/user.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H 1
+
+#include <features.h>
+
+#include <asm/user.h>
+
+#undef start_thread
+
+#endif /* sys/user.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sh/syscall.S b/libc/sysdeps/unix/sysv/linux/sh/syscall.S
new file mode 100644
index 000000000..afa16c2fb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/syscall.S
@@ -0,0 +1,44 @@
+/* Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ENTRY (__syscall)
+ mov r4, r3 // syscall number
+ mov r5, r4 // p1
+ mov r6, r5 // p2
+ mov r7, r6 // p3
+ mov.l @r15, r7 // p4
+ mov.l @(4,r15), r0 // p5
+ mov.l @(8,r15), r1 // p6
+ mov.l @(12,r15), r2 // p7
+ trapa #0x17
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lpseudo_end
+ SYSCALL_ERROR_HANDLER
+.Lpseudo_end:
+ rts
+ nop
+
+PSEUDO_END (__syscall)
+
+weak_alias (__syscall, syscall)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/syscalls.list b/libc/sysdeps/unix/sysv/linux/sh/syscalls.list
new file mode 100644
index 000000000..a6665936e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/syscalls.list
@@ -0,0 +1,3 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+waitpid - waitpid Ci:ipi __waitpid waitpid __libc_waitpid
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sysdep.S b/libc/sysdeps/unix/sysv/linux/sh/sysdep.S
new file mode 100644
index 000000000..176d99aab
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sysdep.S
@@ -0,0 +1,34 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* The syscall stubs jump here when they detect an error.
+ The code for Linux is almost identical to the canonical Unix
+ code, except that the error number in R0 is negated. */
+
+#undef CALL_MCOUNT
+#define CALL_MCOUNT /* Don't insert the profiling call, it clobbers R0. */
+
+ENTRY (__syscall_error)
+ neg r4, r0
+ cfi_endproc
+
+#define __syscall_error __syscall_error_1
+#include <sysdeps/unix/sh/sysdep.S>
diff --git a/libc/sysdeps/unix/sysv/linux/sh/sysdep.h b/libc/sysdeps/unix/sysv/linux/sh/sysdep.h
new file mode 100644
index 000000000..f0be37edc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/sysdep.h
@@ -0,0 +1,391 @@
+/* Copyright (C) 1992,1993,1995,1996,1997,1998,1999,2000,2002,2003,2004,
+ 2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995.
+ Changed by Kaz Kojima, <kkojima@rr.iij4u.or.jp>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINUX_SH_SYSDEP_H
+#define _LINUX_SH_SYSDEP_H 1
+
+/* There is some commonality. */
+#include <sysdeps/unix/sh/sysdep.h>
+#include <tls.h>
+
+/* For Linux we can use the system call table in the header file
+ /usr/include/asm/unistd.h
+ of the kernel. But these symbols do not follow the SYS_* syntax
+ so we have to redefine the `SYS_ify' macro here. */
+#undef SYS_ify
+#define SYS_ify(syscall_name) (__NR_##syscall_name)
+
+
+#ifdef __ASSEMBLER__
+
+/* Linux uses a negative return value to indicate syscall errors,
+ unlike most Unices, which use the condition codes' carry flag.
+
+ Since version 2.1 the return value of a system call might be
+ negative even if the call succeeded. E.g., the `lseek' system call
+ might return a large offset. Therefore we must not anymore test
+ for < 0, but test for a real error by making sure the value in R0
+ is a real error number. Linus said he will make sure the no syscall
+ returns a value in -1 .. -4095 as a valid result so we can savely
+ test with -4095. */
+
+#define _IMM1 #-1
+#define _IMM12 #-12
+#undef PSEUDO
+#define PSEUDO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name); \
+ DO_CALL (syscall_name, args); \
+ mov r0,r1; \
+ mov _IMM12,r2; \
+ shad r2,r1; \
+ not r1,r1; \
+ tst r1,r1; \
+ bf .Lpseudo_end; \
+ SYSCALL_ERROR_HANDLER; \
+ .Lpseudo_end:
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
+
+#undef PSEUDO_NOERRNO
+#define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name); \
+ DO_CALL (syscall_name, args)
+
+#undef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(name) \
+ END (name)
+
+#define ret_NOERRNO ret
+
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .text; \
+ ENTRY (name); \
+ DO_CALL (syscall_name, args);
+
+#undef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(name) \
+ END (name)
+
+#define ret_ERRVAL ret
+
+#ifndef PIC
+# define SYSCALL_ERROR_HANDLER \
+ mov.l 0f,r1; \
+ jmp @r1; \
+ mov r0,r4; \
+ .align 2; \
+ 0: .long __syscall_error
+#else
+# if RTLD_PRIVATE_ERRNO
+# define SYSCALL_ERROR_HANDLER \
+ neg r0,r1; \
+ mov.l 0f,r12; \
+ mova 0f,r0; \
+ add r0,r12; \
+ mov.l 1f,r0; \
+ mov.l r1,@(r0,r12); \
+ bra .Lpseudo_end; \
+ mov _IMM1,r0; \
+ .align 2; \
+ 0: .long _GLOBAL_OFFSET_TABLE_; \
+ 1: .long rtld_errno@GOTOFF
+
+# elif defined _LIBC_REENTRANT
+
+# if USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+# define SYSCALL_ERROR_HANDLER \
+ neg r0,r1; \
+ mov r12,r2; \
+ mov.l 0f,r12; \
+ mova 0f,r0; \
+ add r0,r12; \
+ mov.l 1f,r0; \
+ stc gbr, r4; \
+ mov.l @(r0,r12),r0; \
+ mov r2,r12; \
+ add r4,r0; \
+ mov.l r1,@r0; \
+ bra .Lpseudo_end; \
+ mov _IMM1,r0; \
+ .align 2; \
+ 0: .long _GLOBAL_OFFSET_TABLE_; \
+ 1: .long SYSCALL_ERROR_ERRNO@GOTTPOFF
+# else
+# define SYSCALL_ERROR_HANDLER \
+ neg r0,r1; \
+ mov.l r14,@-r15; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (r14, 0); \
+ mov.l r12,@-r15; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (r12, 0); \
+ mov.l r1,@-r15; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (r1, 0); \
+ mov.l 0f,r12; \
+ mova 0f,r0; \
+ add r0,r12; \
+ sts.l pr,@-r15; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (pr, 0); \
+ mov r15,r14; \
+ cfi_def_cfa_register (r14); \
+ mov.l 1f,r1; \
+ bsrf r1; \
+ nop; \
+ 2: mov r14,r15; \
+ lds.l @r15+,pr; \
+ mov.l @r15+,r1; \
+ mov.l r1,@r0; \
+ mov.l @r15+,r12; \
+ mov.l @r15+,r14; \
+ bra .Lpseudo_end; \
+ mov _IMM1,r0; \
+ .align 2; \
+ 0: .long _GLOBAL_OFFSET_TABLE_; \
+ 1: .long PLTJMP(C_SYMBOL_NAME(__errno_location))-(2b-.)
+/* A quick note: it is assumed that the call to `__errno_location' does
+ not modify the stack! */
+# endif
+# else
+/* Store (-r0) into errno through the GOT. */
+# define SYSCALL_ERROR_HANDLER \
+ neg r0,r1; \
+ mov r12,r2; \
+ mov.l 0f,r12; \
+ mova 0f,r0; \
+ add r0,r12; \
+ mov.l 1f,r0; \
+ mov.l @(r0,r12),r0; \
+ mov r2,r12; \
+ mov.l r1,@r0; \
+ bra .Lpseudo_end; \
+ mov _IMM1,r0; \
+ .align 2; \
+ 0: .long _GLOBAL_OFFSET_TABLE_; \
+ 1: .long errno@GOT
+# endif /* _LIBC_REENTRANT */
+#endif /* PIC */
+
+# ifdef NEED_SYSCALL_INST_PAD
+# define SYSCALL_INST_PAD \
+ or r0,r0; or r0,r0; or r0,r0; or r0,r0; or r0,r0
+# else
+# define SYSCALL_INST_PAD
+# endif
+
+#define SYSCALL_INST0 trapa #0x10
+#define SYSCALL_INST1 trapa #0x11
+#define SYSCALL_INST2 trapa #0x12
+#define SYSCALL_INST3 trapa #0x13
+#define SYSCALL_INST4 trapa #0x14
+#define SYSCALL_INST5 mov.l @(0,r15),r0; trapa #0x15
+#define SYSCALL_INST6 mov.l @(0,r15),r0; mov.l @(4,r15),r1; trapa #0x16
+
+#undef DO_CALL
+#define DO_CALL(syscall_name, args) \
+ mov.l 1f,r3; \
+ SYSCALL_INST##args; \
+ SYSCALL_INST_PAD; \
+ bra 2f; \
+ nop; \
+ .align 2; \
+ 1: .long SYS_ify (syscall_name); \
+ 2:
+
+#else /* not __ASSEMBLER__ */
+
+#define SYSCALL_INST_STR0 "trapa #0x10\n\t"
+#define SYSCALL_INST_STR1 "trapa #0x11\n\t"
+#define SYSCALL_INST_STR2 "trapa #0x12\n\t"
+#define SYSCALL_INST_STR3 "trapa #0x13\n\t"
+#define SYSCALL_INST_STR4 "trapa #0x14\n\t"
+#define SYSCALL_INST_STR5 "trapa #0x15\n\t"
+#define SYSCALL_INST_STR6 "trapa #0x16\n\t"
+
+# ifdef NEED_SYSCALL_INST_PAD
+# define SYSCALL_INST_PAD "\
+ or r0,r0; or r0,r0; or r0,r0; or r0,r0; or r0,r0"
+# else
+# define SYSCALL_INST_PAD
+# endif
+
+#define ASMFMT_0
+#define ASMFMT_1 \
+ , "r" (r4)
+#define ASMFMT_2 \
+ , "r" (r4), "r" (r5)
+#define ASMFMT_3 \
+ , "r" (r4), "r" (r5), "r" (r6)
+#define ASMFMT_4 \
+ , "r" (r4), "r" (r5), "r" (r6), "r" (r7)
+#define ASMFMT_5 \
+ , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0)
+#define ASMFMT_6 \
+ , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0), "r" (r1)
+#define ASMFMT_7 \
+ , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0), "r" (r1), "r" (r2)
+
+#define SUBSTITUTE_ARGS_0()
+#define SUBSTITUTE_ARGS_1(arg1) \
+ long int _arg1 = (long int) (arg1); \
+ register long int r4 asm ("%r4") = (long int) (_arg1)
+#define SUBSTITUTE_ARGS_2(arg1, arg2) \
+ long int _arg1 = (long int) (arg1); \
+ long int _arg2 = (long int) (arg2); \
+ register long int r4 asm ("%r4") = (long int) (_arg1); \
+ register long int r5 asm ("%r5") = (long int) (_arg2)
+#define SUBSTITUTE_ARGS_3(arg1, arg2, arg3) \
+ long int _arg1 = (long int) (arg1); \
+ long int _arg2 = (long int) (arg2); \
+ long int _arg3 = (long int) (arg3); \
+ register long int r4 asm ("%r4") = (long int) (_arg1); \
+ register long int r5 asm ("%r5") = (long int) (_arg2); \
+ register long int r6 asm ("%r6") = (long int) (_arg3)
+#define SUBSTITUTE_ARGS_4(arg1, arg2, arg3, arg4) \
+ long int _arg1 = (long int) (arg1); \
+ long int _arg2 = (long int) (arg2); \
+ long int _arg3 = (long int) (arg3); \
+ long int _arg4 = (long int) (arg4); \
+ register long int r4 asm ("%r4") = (long int) (_arg1); \
+ register long int r5 asm ("%r5") = (long int) (_arg2); \
+ register long int r6 asm ("%r6") = (long int) (_arg3); \
+ register long int r7 asm ("%r7") = (long int) (_arg4)
+#define SUBSTITUTE_ARGS_5(arg1, arg2, arg3, arg4, arg5) \
+ long int _arg1 = (long int) (arg1); \
+ long int _arg2 = (long int) (arg2); \
+ long int _arg3 = (long int) (arg3); \
+ long int _arg4 = (long int) (arg4); \
+ long int _arg5 = (long int) (arg5); \
+ register long int r4 asm ("%r4") = (long int) (_arg1); \
+ register long int r5 asm ("%r5") = (long int) (_arg2); \
+ register long int r6 asm ("%r6") = (long int) (_arg3); \
+ register long int r7 asm ("%r7") = (long int) (_arg4); \
+ register long int r0 asm ("%r0") = (long int) (_arg5)
+#define SUBSTITUTE_ARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
+ long int _arg1 = (long int) (arg1); \
+ long int _arg2 = (long int) (arg2); \
+ long int _arg3 = (long int) (arg3); \
+ long int _arg4 = (long int) (arg4); \
+ long int _arg5 = (long int) (arg5); \
+ long int _arg6 = (long int) (arg6); \
+ register long int r4 asm ("%r4") = (long int)(_arg1); \
+ register long int r5 asm ("%r5") = (long int) (_arg2); \
+ register long int r6 asm ("%r6") = (long int) (_arg3); \
+ register long int r7 asm ("%r7") = (long int) (_arg4); \
+ register long int r0 asm ("%r0") = (long int) (_arg5); \
+ register long int r1 asm ("%r1") = (long int) (_arg6)
+#define SUBSTITUTE_ARGS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+ long int _arg1 = (long int) (arg1); \
+ long int _arg2 = (long int) (arg2); \
+ long int _arg3 = (long int) (arg3); \
+ long int _arg4 = (long int) (arg4); \
+ long int _arg5 = (long int) (arg5); \
+ long int _arg6 = (long int) (arg6); \
+ long int _arg7 = (long int) (arg7); \
+ register long int r4 asm ("%r4") = (long int) (_arg1); \
+ register long int r5 asm ("%r5") = (long int) (_arg2); \
+ register long int r6 asm ("%r6") = (long int) (_arg3); \
+ register long int r7 asm ("%r7") = (long int) (_arg4); \
+ register long int r0 asm ("%r0") = (long int) (_arg5); \
+ register long int r1 asm ("%r1") = (long int) (_arg6); \
+ register long int r2 asm ("%r2") = (long int) (_arg7)
+
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+ ({ \
+ unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args); \
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0)) \
+ { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, )); \
+ resultvar = 0xffffffff; \
+ } \
+ (int) resultvar; })
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ ({ \
+ unsigned long int resultvar; \
+ register long int r3 asm ("%r3") = SYS_ify (name); \
+ SUBSTITUTE_ARGS_##nr(args); \
+ \
+ asm volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD \
+ : "=z" (resultvar) \
+ : "r" (r3) ASMFMT_##nr \
+ : "memory"); \
+ \
+ (int) resultvar; })
+
+/* The _NCS variant allows non-constant syscall numbers. */
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ unsigned long int resultvar; \
+ register long int r3 asm ("%r3") = (name); \
+ SUBSTITUTE_ARGS_##nr(args); \
+ \
+ asm volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD \
+ : "=z" (resultvar) \
+ : "r" (r3) ASMFMT_##nr \
+ : "memory"); \
+ \
+ (int) resultvar; })
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((unsigned int) (val) >= 0xfffff001u)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+
+#endif /* __ASSEMBLER__ */
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. Using a global variable
+ is too complicated here since we have no PC-relative addressing mode. */
+#else
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(reg, tmp) \
+ stc gbr,tmp; mov.l @(POINTER_GUARD,tmp),tmp; xor tmp,reg
+# define PTR_MANGLE2(reg, tmp) xor tmp,reg
+# define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp)
+# define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp)
+# else
+# define PTR_MANGLE(var) \
+ (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+# define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#endif
+
+#endif /* linux/sh/sysdep.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sh/vfork.S b/libc/sysdeps/unix/sysv/linux/sh/vfork.S
new file mode 100644
index 000000000..e926e3b19
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/vfork.S
@@ -0,0 +1,71 @@
+/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+
+#ifdef __NR_vfork
+ mov.w .L3, r3
+ trapa #0x10
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf 1f
+ mov.w .L1, r1
+ cmp/eq r1, r0
+ bt 2f
+ bra .Lsyscall_error
+ nop
+.L1:
+ .word -ENOSYS
+.L3: .word __NR_vfork
+1:
+ rts
+ nop
+2:
+#endif
+
+ /* If we don't have vfork, fork is close enough. */
+ mov #+__NR_fork, r3
+ trapa #0x10
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lpseudo_end
+.Lsyscall_error:
+ SYSCALL_ERROR_HANDLER
+.Lpseudo_end:
+ rts
+ nop
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libc/sysdeps/unix/sysv/linux/sh/xstat.c b/libc/sysdeps/unix/sysv/linux/sh/xstat.c
new file mode 100644
index 000000000..e9869f550
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sh/xstat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/xstat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/shm_open.c b/libc/sysdeps/unix/sysv/linux/shm_open.c
new file mode 100644
index 000000000..0d40632e5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/shm_open.c
@@ -0,0 +1,248 @@
+/* Copyright (C) 2000,2001,2002,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <mntent.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/statfs.h>
+#include <bits/libc-lock.h>
+#include "linux_fsinfo.h"
+
+#include <kernel-features.h>
+
+
+/* Mount point of the shared memory filesystem. */
+static struct
+{
+ char *dir;
+ size_t dirlen;
+} mountpoint;
+
+/* This is the default directory. */
+static const char defaultdir[] = "/dev/shm/";
+
+/* Protect the `mountpoint' variable above. */
+__libc_once_define (static, once);
+
+
+/* Determine where the shmfs is mounted (if at all). */
+static void
+where_is_shmfs (void)
+{
+ char buf[512];
+ struct statfs f;
+ struct mntent resmem;
+ struct mntent *mp;
+ FILE *fp;
+
+ /* The canonical place is /dev/shm. This is at least what the
+ documentation tells everybody to do. */
+ if (__statfs (defaultdir, &f) == 0 && f.f_type == SHMFS_SUPER_MAGIC)
+ {
+ /* It is in the normal place. */
+ mountpoint.dir = (char *) defaultdir;
+ mountpoint.dirlen = sizeof (defaultdir) - 1;
+
+ return;
+ }
+
+ /* OK, do it the hard way. Look through the /proc/mounts file and if
+ this does not exist through /etc/fstab to find the mount point. */
+ fp = __setmntent ("/proc/mounts", "r");
+ if (__builtin_expect (fp == NULL, 0))
+ {
+ fp = __setmntent (_PATH_MNTTAB, "r");
+ if (__builtin_expect (fp == NULL, 0))
+ /* There is nothing we can do. Blind guesses are not helpful. */
+ return;
+ }
+
+ /* Now read the entries. */
+ while ((mp = __getmntent_r (fp, &resmem, buf, sizeof buf)) != NULL)
+ /* The original name is "shm" but this got changed in early Linux
+ 2.4.x to "tmpfs". */
+ if (strcmp (mp->mnt_type, "tmpfs") == 0
+#ifndef __ASSUME_TMPFS_NAME
+ || strcmp (mp->mnt_type, "shm") == 0
+#endif
+ )
+ {
+ /* Found it. There might be more than one place where the
+ filesystem is mounted but one is enough for us. */
+ size_t namelen;
+
+ /* First make sure this really is the correct entry. At least
+ some versions of the kernel give wrong information because
+ of the implicit mount of the shmfs for SysV IPC. */
+ if (__statfs (mp->mnt_dir, &f) != 0 || f.f_type != SHMFS_SUPER_MAGIC)
+ continue;
+
+ namelen = strlen (mp->mnt_dir);
+
+ if (namelen == 0)
+ /* Hum, maybe some crippled entry. Keep on searching. */
+ continue;
+
+ mountpoint.dir = (char *) malloc (namelen + 2);
+ if (mountpoint.dir != NULL)
+ {
+ char *cp = __mempcpy (mountpoint.dir, mp->mnt_dir, namelen);
+ if (cp[-1] != '/')
+ *cp++ = '/';
+ *cp = '\0';
+ mountpoint.dirlen = cp - mountpoint.dir;
+ }
+
+ break;
+ }
+
+ /* Close the stream. */
+ __endmntent (fp);
+}
+
+
+/* Open shared memory object. This implementation assumes the shmfs
+ implementation introduced in the late 2.3.x kernel series to be
+ available. Normally the filesystem will be mounted at /dev/shm but
+ we fall back on searching for the actual mount point should opening
+ such a file fail. */
+int
+shm_open (const char *name, int oflag, mode_t mode)
+{
+ size_t namelen;
+ char *fname;
+ int fd;
+
+ /* Determine where the shmfs is mounted. */
+ __libc_once (once, where_is_shmfs);
+
+ /* If we don't know the mount points there is nothing we can do. Ever. */
+ if (mountpoint.dir == NULL)
+ {
+ __set_errno (ENOSYS);
+ return -1;
+ }
+
+ /* Construct the filename. */
+ while (name[0] == '/')
+ ++name;
+
+ if (name[0] == '\0')
+ {
+ /* The name "/" is not supported. */
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ namelen = strlen (name);
+ fname = (char *) alloca (mountpoint.dirlen + namelen + 1);
+ __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen),
+ name, namelen + 1);
+
+ /* And get the file descriptor.
+ XXX Maybe we should test each descriptor whether it really is for a
+ file on the shmfs. If this is what should be done the whole function
+ should be revamped since we can determine whether shmfs is available
+ while trying to open the file, all in one turn. */
+ fd = open (fname, oflag | O_NOFOLLOW, mode);
+ if (fd != -1)
+ {
+ /* We got a descriptor. Now set the FD_CLOEXEC bit. */
+ int flags = fcntl (fd, F_GETFD, 0);
+
+ if (__builtin_expect (flags, 0) >= 0)
+ {
+ flags |= FD_CLOEXEC;
+ flags = fcntl (fd, F_SETFD, flags);
+ }
+
+ if (flags == -1)
+ {
+ /* Something went wrong. We cannot return the descriptor. */
+ int save_errno = errno;
+ close (fd);
+ fd = -1;
+ __set_errno (save_errno);
+ }
+ }
+ else if (__builtin_expect (errno == EISDIR, 0))
+ /* It might be better to fold this error with EINVAL since
+ directory names are just another example for unsuitable shared
+ object names and the standard does not mention EISDIR. */
+ __set_errno (EINVAL);
+
+ return fd;
+}
+
+
+/* Unlink a shared memory object. */
+int
+shm_unlink (const char *name)
+{
+ size_t namelen;
+ char *fname;
+
+ /* Determine where the shmfs is mounted. */
+ __libc_once (once, where_is_shmfs);
+
+ if (mountpoint.dir == NULL)
+ {
+ /* We cannot find the shmfs. If `name' is really a shared
+ memory object it must have been created by another process
+ and we have no idea where that process found the mountpoint. */
+ __set_errno (ENOENT);
+ return -1;
+ }
+
+ /* Construct the filename. */
+ while (name[0] == '/')
+ ++name;
+
+ if (name[0] == '\0')
+ {
+ /* The name "/" is not supported. */
+ __set_errno (ENOENT);
+ return -1;
+ }
+
+ namelen = strlen (name);
+ fname = (char *) alloca (mountpoint.dirlen + namelen + 1);
+ __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen),
+ name, namelen + 1);
+
+ /* And remove the file. */
+ int ret = unlink (fname);
+ if (ret < 0 && errno == EPERM)
+ __set_errno (EACCES);
+ return ret;
+}
+
+
+/* Make sure the table is freed if we want to free everything before
+ exiting. */
+libc_freeres_fn (freeit)
+{
+ if (mountpoint.dir != defaultdir)
+ free (mountpoint.dir);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/shm_unlink.c b/libc/sysdeps/unix/sysv/linux/shm_unlink.c
new file mode 100644
index 000000000..55cece276
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/shm_unlink.c
@@ -0,0 +1 @@
+/* This function is for technical reason defined in shm_open.c. */
diff --git a/libc/sysdeps/unix/sysv/linux/shmat.c b/libc/sysdeps/unix/sysv/linux/shmat.c
new file mode 100644
index 000000000..2c243007f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/shmat.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1995,1997,1998,1999,2000,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/shm.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Attach the shared memory segment associated with SHMID to the data
+ segment of the calling process. SHMADDR and SHMFLG determine how
+ and where the segment is attached. */
+
+void *
+shmat (shmid, shmaddr, shmflg)
+ int shmid;
+ const void *shmaddr;
+ int shmflg;
+{
+ void *__unbounded result;
+ void *__unbounded raddr;
+
+#if __BOUNDED_POINTERS__
+ size_t length = ~0;
+ struct shmid_ds shmds;
+ /* It's unfortunate that we need to make another system call to get
+ the shared memory segment length... */
+ if (shmctl (shmid, IPC_STAT, &shmds) == 0)
+ length = shmds.shm_segsz;
+#endif
+
+ result = (void *__unbounded) INLINE_SYSCALL (ipc, 5, IPCOP_shmat,
+ shmid, shmflg,
+ (long int) __ptrvalue (&raddr),
+ __ptrvalue ((void *) shmaddr));
+ if ((unsigned long) result <= -(unsigned long) SHMLBA)
+ result = raddr;
+
+ return BOUNDED_N (result, length);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/shmctl.c b/libc/sysdeps/unix/sysv/linux/shmctl.c
new file mode 100644
index 000000000..0fbddd920
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/shmctl.c
@@ -0,0 +1,161 @@
+/* Copyright (C) 1995,1997,1998,2000,2003,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/shm.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <bits/wordsize.h>
+#include <shlib-compat.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+struct __old_shmid_ds
+{
+ struct __old_ipc_perm shm_perm; /* operation permission struct */
+ int shm_segsz; /* size of segment in bytes */
+ __time_t shm_atime; /* time of last shmat() */
+ __time_t shm_dtime; /* time of last shmdt() */
+ __time_t shm_ctime; /* time of last change by shmctl() */
+ __ipc_pid_t shm_cpid; /* pid of creator */
+ __ipc_pid_t shm_lpid; /* pid of last shmop */
+ unsigned short int shm_nattch; /* number of current attaches */
+ unsigned short int __shm_npages; /* size of segment (pages) */
+ unsigned long int *__unbounded __shm_pages; /* array of ptrs to frames -> SHMMAX */
+ struct vm_area_struct *__unbounded __attaches; /* descriptors for attaches */
+};
+
+struct __old_shminfo
+{
+ int shmmax;
+ int shmmin;
+ int shmmni;
+ int shmseg;
+ int shmall;
+};
+
+/* Provide operations to control over shared memory segments. */
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int __old_shmctl (int, int, struct __old_shmid_ds *);
+#endif
+int __new_shmctl (int, int, struct shmid_ds *);
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int
+attribute_compat_text_section
+__old_shmctl (int shmid, int cmd, struct __old_shmid_ds *buf)
+{
+ return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid,
+ cmd, 0, CHECK_1_NULL_OK (buf));
+}
+compat_symbol (libc, __old_shmctl, shmctl, GLIBC_2_0);
+#endif
+
+int
+__new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
+{
+#if __ASSUME_IPC64 > 0
+ return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd | __IPC_64, 0,
+ CHECK_1 (buf));
+#else
+ switch (cmd) {
+ case SHM_STAT:
+ case IPC_STAT:
+ case IPC_SET:
+#if __WORDSIZE != 32
+ case IPC_INFO:
+#endif
+ break;
+ default:
+ return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd, 0,
+ CHECK_1 (buf));
+ }
+
+ {
+ int save_errno = errno, result;
+ union
+ {
+ struct __old_shmid_ds ds;
+ struct __old_shminfo info;
+ } old;
+
+ /* Unfortunately there is no way how to find out for sure whether
+ we should use old or new shmctl. */
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd | __IPC_64, 0,
+ CHECK_1 (buf));
+ if (result != -1 || errno != EINVAL)
+ return result;
+
+ __set_errno(save_errno);
+ if (cmd == IPC_SET)
+ {
+ old.ds.shm_perm.uid = buf->shm_perm.uid;
+ old.ds.shm_perm.gid = buf->shm_perm.gid;
+ old.ds.shm_perm.mode = buf->shm_perm.mode;
+ if (old.ds.shm_perm.uid != buf->shm_perm.uid ||
+ old.ds.shm_perm.gid != buf->shm_perm.gid)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ }
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd, 0,
+ __ptrvalue (&old.ds));
+ if (result != -1 && (cmd == SHM_STAT || cmd == IPC_STAT))
+ {
+ memset(buf, 0, sizeof(*buf));
+ buf->shm_perm.__key = old.ds.shm_perm.__key;
+ buf->shm_perm.uid = old.ds.shm_perm.uid;
+ buf->shm_perm.gid = old.ds.shm_perm.gid;
+ buf->shm_perm.cuid = old.ds.shm_perm.cuid;
+ buf->shm_perm.cgid = old.ds.shm_perm.cgid;
+ buf->shm_perm.mode = old.ds.shm_perm.mode;
+ buf->shm_perm.__seq = old.ds.shm_perm.__seq;
+ buf->shm_atime = old.ds.shm_atime;
+ buf->shm_dtime = old.ds.shm_dtime;
+ buf->shm_ctime = old.ds.shm_ctime;
+ buf->shm_segsz = old.ds.shm_segsz;
+ buf->shm_nattch = old.ds.shm_nattch;
+ buf->shm_cpid = old.ds.shm_cpid;
+ buf->shm_lpid = old.ds.shm_lpid;
+ }
+#if __WORDSIZE != 32
+ else if (result != -1 && cmd == IPC_INFO)
+ {
+ struct shminfo *i = (struct shminfo *)buf;
+
+ memset(i, 0, sizeof(*i));
+ i->shmmax = old.info.shmmax;
+ i->shmmin = old.info.shmmin;
+ i->shmmni = old.info.shmmni;
+ i->shmseg = old.info.shmseg;
+ i->shmall = old.info.shmall;
+ }
+#endif
+ return result;
+ }
+#endif
+}
+
+versioned_symbol (libc, __new_shmctl, shmctl, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/shmdt.c b/libc/sysdeps/unix/sysv/linux/shmdt.c
new file mode 100644
index 000000000..413c85202
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/shmdt.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1995, 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/shm.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Detach shared memory segment starting at address specified by SHMADDR
+ from the caller's data segment. */
+
+int
+shmdt (shmaddr)
+ const void *shmaddr;
+{
+ return INLINE_SYSCALL (ipc, 5, IPCOP_shmdt, 0, 0, 0, __ptrvalue ((void *) shmaddr));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/shmget.c b/libc/sysdeps/unix/sysv/linux/shmget.c
new file mode 100644
index 000000000..c8d509f26
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/shmget.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1995, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/shm.h>
+#include <ipc_priv.h>
+#include <stdlib.h> /* for definition of NULL */
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Return an identifier for an shared memory segment of at least size SIZE
+ which is associated with KEY. */
+
+int
+shmget (key, size, shmflg)
+ key_t key;
+ size_t size;
+ int shmflg;
+{
+ return INLINE_SYSCALL (ipc, 5, IPCOP_shmget, key, size, shmflg, NULL);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/shutdown.S b/libc/sysdeps/unix/sysv/linux/shutdown.S
new file mode 100644
index 000000000..e2462d0ec
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/shutdown.S
@@ -0,0 +1,3 @@
+#define socket shutdown
+#define NARGS 2
+#include <socket.S>
diff --git a/libc/sysdeps/unix/sysv/linux/sigaction.c b/libc/sysdeps/unix/sysv/linux/sigaction.c
new file mode 100644
index 000000000..7b44598c0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sigaction.c
@@ -0,0 +1,140 @@
+/* Copyright (C) 1997-2000,2002,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+/* The difference here is that the sigaction structure used in the
+ kernel is not the same as we use in the libc. Therefore we must
+ translate it here. */
+#include <kernel_sigaction.h>
+
+#if __ASSUME_REALTIME_SIGNALS == 0
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. This is the definition. */
+int __libc_missing_rt_sigs;
+#endif
+
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+ If OACT is not NULL, put the old action for SIG in *OACT. */
+int
+__libc_sigaction (sig, act, oact)
+ int sig;
+ const struct sigaction *act;
+ struct sigaction *oact;
+{
+#if __ASSUME_REALTIME_SIGNALS == 0
+ struct old_kernel_sigaction k_sigact, k_osigact;
+#endif
+ int result;
+
+#if defined __NR_rt_sigaction || __ASSUME_REALTIME_SIGNALS > 0
+ /* First try the RT signals. */
+# if __ASSUME_REALTIME_SIGNALS == 0
+ if (!__libc_missing_rt_sigs)
+# endif
+ {
+ struct kernel_sigaction kact, koact;
+ /* Save the current error value for later. We need not do this
+ if we are guaranteed to have realtime signals. */
+# if __ASSUME_REALTIME_SIGNALS == 0
+ int saved_errno = errno;
+# endif
+
+ if (act)
+ {
+ kact.k_sa_handler = act->sa_handler;
+ memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
+ kact.sa_flags = act->sa_flags;
+# ifdef HAVE_SA_RESTORER
+ kact.sa_restorer = act->sa_restorer;
+# endif
+ }
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ result = INLINE_SYSCALL (rt_sigaction, 4, sig,
+ act ? __ptrvalue (&kact) : NULL,
+ oact ? __ptrvalue (&koact) : NULL, _NSIG / 8);
+
+# if __ASSUME_REALTIME_SIGNALS == 0
+ if (result >= 0 || errno != ENOSYS)
+# endif
+ {
+ if (oact && result >= 0)
+ {
+ oact->sa_handler = koact.k_sa_handler;
+ memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t));
+ oact->sa_flags = koact.sa_flags;
+# ifdef HAVE_SA_RESTORER
+ oact->sa_restorer = koact.sa_restorer;
+# endif
+ }
+ return result;
+ }
+
+# if __ASSUME_REALTIME_SIGNALS == 0
+ __set_errno (saved_errno);
+ __libc_missing_rt_sigs = 1;
+# endif
+ }
+#endif
+
+#if __ASSUME_REALTIME_SIGNALS == 0
+ if (act)
+ {
+ k_sigact.k_sa_handler = act->sa_handler;
+ k_sigact.sa_mask = act->sa_mask.__val[0];
+ k_sigact.sa_flags = act->sa_flags;
+# ifdef HAVE_SA_RESTORER
+ k_sigact.sa_restorer = act->sa_restorer;
+# endif
+ }
+ result = INLINE_SYSCALL (sigaction, 3, sig,
+ act ? __ptrvalue (&k_sigact) : NULL,
+ oact ? __ptrvalue (&k_osigact) : NULL);
+ if (oact && result >= 0)
+ {
+ oact->sa_handler = k_osigact.k_sa_handler;
+ oact->sa_mask.__val[0] = k_osigact.sa_mask;
+ oact->sa_flags = k_osigact.sa_flags;
+# ifdef HAVE_SA_RESTORER
+ oact->sa_restorer = k_osigact.sa_restorer;
+# endif
+ }
+ return result;
+#endif
+}
+libc_hidden_def (__libc_sigaction)
+
+#ifdef WRAPPER_INCLUDE
+# include WRAPPER_INCLUDE
+#endif
+
+#ifndef LIBC_SIGACTION
+weak_alias (__libc_sigaction, __sigaction)
+libc_hidden_weak (__sigaction)
+weak_alias (__libc_sigaction, sigaction)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/siglist.h b/libc/sysdeps/unix/sysv/linux/siglist.h
new file mode 100644
index 000000000..cc2b49ed2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/siglist.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 1996,1997,1998,1999,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file is included multiple times. */
+
+#include_next <siglist.h> /* Get the canonical list. */
+
+#define OLD_SIGLIST_SIZE 32 /* For GLIBC_2.0 binary compatibility. */
+
+#define OLD2_SIGLIST_SIZE 64 /* For GLIBC_2.1 binary compatibility. */
diff --git a/libc/sysdeps/unix/sysv/linux/signal.c b/libc/sysdeps/unix/sysv/linux/signal.c
new file mode 100644
index 000000000..bc4e4e844
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/signal.c
@@ -0,0 +1,3 @@
+/* We need this file since otherwise `signal' would be handled as a
+ system call. */
+#include <sysdeps/posix/signal.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sigpending.c b/libc/sysdeps/unix/sysv/linux/sigpending.c
new file mode 100644
index 000000000..f0036c113
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sigpending.c
@@ -0,0 +1,64 @@
+/* Copyright (C) 1997,1998,1999,2000,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. The definition is in sigaction.c. */
+extern int __libc_missing_rt_sigs;
+
+
+/* Change the set of blocked signals to SET,
+ wait until a signal arrives, and restore the set of blocked signals. */
+int
+sigpending (set)
+ sigset_t *set;
+{
+#if __ASSUME_REALTIME_SIGNALS > 0
+ return INLINE_SYSCALL (rt_sigpending, 2, CHECK_SIGSET (set), _NSIG / 8);
+#else
+# ifdef __NR_rt_sigpending
+ /* First try the RT signals. */
+ if (!__libc_missing_rt_sigs)
+ {
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ int saved_errno = errno;
+ int result = INLINE_SYSCALL (rt_sigpending, 2, CHECK_SIGSET (set), _NSIG / 8);
+
+ if (result >= 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_rt_sigs = 1;
+ }
+# endif
+
+ return INLINE_SYSCALL (sigpending, 1, CHECK_SIGSET (set));
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sigprocmask.c b/libc/sysdeps/unix/sysv/linux/sigprocmask.c
new file mode 100644
index 000000000..1b13ea74d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sigprocmask.c
@@ -0,0 +1,91 @@
+/* Copyright (C) 1997-2001,2003,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h> /* Neede for string function builtin redirection. */
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. The definition is in sigaction.c. */
+extern int __libc_missing_rt_sigs;
+
+
+/* Get and/or change the set of blocked signals. */
+int
+__sigprocmask (how, set, oset)
+ int how;
+ const sigset_t *set;
+ sigset_t *oset;
+{
+#ifdef SIGCANCEL
+ sigset_t local_newmask;
+
+ /* The only thing we have to make sure here is that SIGCANCEL and
+ SIGSETXID are not blocked. */
+ if (set != NULL
+ && (__builtin_expect (__sigismember (set, SIGCANCEL), 0)
+# ifdef SIGSETXID
+ || __builtin_expect (__sigismember (set, SIGSETXID), 0)
+# endif
+ ))
+ {
+ local_newmask = *set;
+ __sigdelset (&local_newmask, SIGCANCEL);
+# ifdef SIGSETXID
+ __sigdelset (&local_newmask, SIGSETXID);
+# endif
+ set = &local_newmask;
+ }
+#endif
+
+#if __ASSUME_REALTIME_SIGNALS > 0
+ return INLINE_SYSCALL (rt_sigprocmask, 4, how, CHECK_SIGSET_NULL_OK (set),
+ CHECK_SIGSET_NULL_OK (oset), _NSIG / 8);
+#else
+# ifdef __NR_rt_sigprocmask
+ /* First try the RT signals. */
+ if (!__libc_missing_rt_sigs)
+ {
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ int saved_errno = errno;
+ int result = INLINE_SYSCALL (rt_sigprocmask, 4, how,
+ CHECK_SIGSET_NULL_OK (set),
+ CHECK_SIGSET_NULL_OK (oset), _NSIG / 8);
+
+ if (result >= 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_rt_sigs = 1;
+ }
+# endif
+
+ return INLINE_SYSCALL (sigprocmask, 3, how, CHECK_SIGSET_NULL_OK (set),
+ CHECK_SIGSET_NULL_OK (oset));
+#endif
+}
+weak_alias (__sigprocmask, sigprocmask)
diff --git a/libc/sysdeps/unix/sysv/linux/sigqueue.c b/libc/sysdeps/unix/sysv/linux/sigqueue.c
new file mode 100644
index 000000000..22a8036b6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sigqueue.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 1997, 1998, 2000, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_rt_sigqueueinfo
+/* Return any pending signal or wait for one for the given time. */
+int
+__sigqueue (pid, sig, val)
+ pid_t pid;
+ int sig;
+ const union sigval val;
+{
+ siginfo_t info;
+
+ /* First, clear the siginfo_t structure, so that we don't pass our
+ stack content to other tasks. */
+ memset (&info, 0, sizeof (siginfo_t));
+ /* We must pass the information about the data in a siginfo_t value. */
+ info.si_signo = sig;
+ info.si_code = SI_QUEUE;
+ info.si_pid = __getpid ();
+ info.si_uid = __getuid ();
+ info.si_value = val;
+
+ return INLINE_SYSCALL (rt_sigqueueinfo, 3, pid, sig, __ptrvalue (&info));
+}
+weak_alias (__sigqueue, sigqueue)
+#else
+# include <signal/sigqueue.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sigreturn.c b/libc/sysdeps/unix/sysv/linux/sigreturn.c
new file mode 100644
index 000000000..626b1eb8a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sigreturn.c
@@ -0,0 +1,3 @@
+/* The sigreturn syscall cannot be explicitly called on Linux, only
+ implicitly by returning from a signal handler. */
+#include <signal/sigreturn.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sigset-cvt-mask.h b/libc/sysdeps/unix/sysv/linux/sigset-cvt-mask.h
new file mode 100644
index 000000000..ca4774dbd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sigset-cvt-mask.h
@@ -0,0 +1,44 @@
+/* Convert between lowlevel sigmask and libc representation of sigset_t.
+ Linux version.
+ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Joe Keane <jgk@jgk.org>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+static inline int __attribute__ ((unused))
+sigset_set_old_mask (sigset_t *set, int mask)
+{
+ unsigned long int *ptr;
+ int cnt;
+
+ ptr = &set->__val[0];
+
+ *ptr++ = (unsigned int) mask;
+
+ cnt = _SIGSET_NWORDS - 2;
+ do
+ *ptr++ = 0ul;
+ while (--cnt >= 0);
+
+ return 0;
+}
+
+static inline int __attribute__ ((unused))
+sigset_get_old_mask (const sigset_t *set)
+{
+ return (unsigned int) set->__val[0];
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sigstack.c b/libc/sysdeps/unix/sysv/linux/sigstack.c
new file mode 100644
index 000000000..76d212698
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sigstack.c
@@ -0,0 +1,69 @@
+/* Emulate sigstack function using sigaltstack.
+ Copyright (C) 1998, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+#include <stddef.h>
+#include <sys/syscall.h>
+
+
+#ifdef __NR_sigaltstack
+int
+sigstack (ss, oss)
+ struct sigstack *ss;
+ struct sigstack *oss;
+{
+ stack_t sas;
+ stack_t *sasp = NULL;
+ stack_t osas;
+ stack_t *osasp = oss == NULL ? NULL : &osas;
+ int result;
+
+ if (ss != NULL)
+ {
+ /* We have to convert the information. */
+ sas.ss_sp = ss->ss_sp;
+ sas.ss_flags = ss->ss_onstack ? SS_ONSTACK : 0;
+
+ /* For the size of the stack we have no value we can pass to the
+ kernel. This is why this function should not be used. We simply
+ assume that all the memory down to address zero (in case the stack
+ grows down) is available. */
+ sas.ss_size = ss->ss_sp - NULL;
+
+ sasp = &sas;
+ }
+
+ /* Call the kernel. */
+ result = __sigaltstack (sasp, osasp);
+
+ /* Convert the result, if wanted and possible. */
+ if (result == 0 && oss != NULL)
+ {
+ oss->ss_sp = osas.ss_sp;
+ oss->ss_onstack = (osas.ss_flags & SS_ONSTACK) != 0;
+ }
+
+ return result;
+}
+
+link_warning (sigstack, "the `sigstack' function is dangerous. `sigaltstack' should be used instead.")
+#else
+# include <signal/sigstack.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sigsuspend.c b/libc/sysdeps/unix/sysv/linux/sigsuspend.c
new file mode 100644
index 000000000..adbdfddfd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sigsuspend.c
@@ -0,0 +1,95 @@
+/* Copyright (C) 1996,1997,1998,1999,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+
+#if !__ASSUME_REALTIME_SIGNALS
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. The definition is in sigaction.c. */
+extern int __libc_missing_rt_sigs;
+
+
+static int
+do_sigsuspend (const sigset_t *set)
+{
+# ifdef __NR_rt_sigsuspend
+ /* First try the RT signals. */
+ if (!__libc_missing_rt_sigs)
+ {
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ int saved_errno = errno;
+ int result = INLINE_SYSCALL (rt_sigsuspend, 2,
+ CHECK_SIGSET (set), _NSIG / 8);
+ if (result >= 0 || errno != ENOSYS)
+ return result;
+
+ __set_errno (saved_errno);
+ __libc_missing_rt_sigs = 1;
+ }
+# endif
+
+ return INLINE_SYSCALL (sigsuspend, 3, 0, 0, set->__val[0]);
+}
+#else
+static inline int __attribute__ ((always_inline))
+do_sigsuspend (const sigset_t *set)
+{
+ return INLINE_SYSCALL (rt_sigsuspend, 2, CHECK_SIGSET (set), _NSIG / 8);
+}
+#endif
+
+/* Change the set of blocked signals to SET,
+ wait until a signal arrives, and restore the set of blocked signals. */
+int
+__sigsuspend (set)
+ const sigset_t *set;
+{
+ if (SINGLE_THREAD_P)
+ return do_sigsuspend (set);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_sigsuspend (set);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+libc_hidden_def (__sigsuspend)
+weak_alias (__sigsuspend, sigsuspend)
+strong_alias (__sigsuspend, __libc_sigsuspend)
+
+#ifndef NO_CANCELLATION
+int
+__sigsuspend_nocancel (set)
+ const sigset_t *set;
+{
+ return do_sigsuspend (set);
+}
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sigtimedwait.c b/libc/sysdeps/unix/sysv/linux/sigtimedwait.c
new file mode 100644
index 000000000..879565276
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sigtimedwait.c
@@ -0,0 +1,93 @@
+/* Copyright (C) 1997,1998,2000,2002,2003,2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#ifdef __NR_rt_sigtimedwait
+
+static int
+do_sigtimedwait (const sigset_t *set, siginfo_t *info,
+ const struct timespec *timeout)
+{
+#ifdef SIGCANCEL
+ sigset_t tmpset;
+ if (set != NULL
+ && (__builtin_expect (__sigismember (set, SIGCANCEL), 0)
+# ifdef SIGSETXID
+ || __builtin_expect (__sigismember (set, SIGSETXID), 0)
+# endif
+ ))
+ {
+ /* Create a temporary mask without the bit for SIGCANCEL set. */
+ // We are not copying more than we have to.
+ memcpy (&tmpset, set, _NSIG / 8);
+ __sigdelset (&tmpset, SIGCANCEL);
+# ifdef SIGSETXID
+ __sigdelset (&tmpset, SIGSETXID);
+# endif
+ set = &tmpset;
+ }
+#endif
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ int result = INLINE_SYSCALL (rt_sigtimedwait, 4, CHECK_SIGSET (set),
+ CHECK_1 (info), timeout, _NSIG / 8);
+
+ /* The kernel generates a SI_TKILL code in si_code in case tkill is
+ used. tkill is transparently used in raise(). Since having
+ SI_TKILL as a code is useful in general we fold the results
+ here. */
+ if (result != -1 && info != NULL && info->si_code == SI_TKILL)
+ info->si_code = SI_USER;
+
+ return result;
+}
+
+
+/* Return any pending signal or wait for one for the given time. */
+int
+__sigtimedwait (set, info, timeout)
+ const sigset_t *set;
+ siginfo_t *info;
+ const struct timespec *timeout;
+{
+ if (SINGLE_THREAD_P)
+ return do_sigtimedwait (set, info, timeout);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ int result = do_sigtimedwait (set, info, timeout);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+libc_hidden_def (__sigtimedwait)
+weak_alias (__sigtimedwait, sigtimedwait)
+#else
+# include <signal/sigtimedwait.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sigwait.c b/libc/sysdeps/unix/sysv/linux/sigwait.c
new file mode 100644
index 000000000..279ca0203
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sigwait.c
@@ -0,0 +1,111 @@
+/* Copyright (C) 1997,1998,2000,2002-2004,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#define __need_NULL
+#include <stddef.h>
+#include <string.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#ifdef __NR_rt_sigtimedwait
+
+/* Return any pending signal or wait for one for the given time. */
+static int
+do_sigwait (const sigset_t *set, int *sig)
+{
+ int ret;
+
+#ifdef SIGCANCEL
+ sigset_t tmpset;
+ if (set != NULL
+ && (__builtin_expect (__sigismember (set, SIGCANCEL), 0)
+# ifdef SIGSETXID
+ || __builtin_expect (__sigismember (set, SIGSETXID), 0)
+# endif
+ ))
+ {
+ /* Create a temporary mask without the bit for SIGCANCEL set. */
+ // We are not copying more than we have to.
+ memcpy (&tmpset, set, _NSIG / 8);
+ __sigdelset (&tmpset, SIGCANCEL);
+# ifdef SIGSETXID
+ __sigdelset (&tmpset, SIGSETXID);
+# endif
+ set = &tmpset;
+ }
+#endif
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+#ifdef INTERNAL_SYSCALL
+ INTERNAL_SYSCALL_DECL (err);
+ do
+ ret = INTERNAL_SYSCALL (rt_sigtimedwait, err, 4, CHECK_SIGSET (set),
+ NULL, NULL, _NSIG / 8);
+ while (INTERNAL_SYSCALL_ERROR_P (ret, err)
+ && INTERNAL_SYSCALL_ERRNO (ret, err) == EINTR);
+ if (! INTERNAL_SYSCALL_ERROR_P (ret, err))
+ {
+ *sig = ret;
+ ret = 0;
+ }
+ else
+ ret = INTERNAL_SYSCALL_ERRNO (ret, err);
+#else
+ do
+ ret = INLINE_SYSCALL (rt_sigtimedwait, 4, CHECK_SIGSET (set),
+ NULL, NULL, _NSIG / 8);
+ while (ret == -1 && errno == EINTR);
+ if (ret != -1)
+ {
+ *sig = ret;
+ ret = 0;
+ }
+ else
+ ret = errno;
+#endif
+
+ return ret;
+}
+
+int
+__sigwait (set, sig)
+ const sigset_t *set;
+ int *sig;
+{
+ if (SINGLE_THREAD_P)
+ return do_sigwait (set, sig);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = do_sigwait (set, sig);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+libc_hidden_def (__sigwait)
+weak_alias (__sigwait, sigwait)
+#else
+# include <sysdeps/posix/sigwait.c>
+#endif
+strong_alias (__sigwait, __libc_sigwait)
diff --git a/libc/sysdeps/unix/sysv/linux/sigwaitinfo.c b/libc/sysdeps/unix/sysv/linux/sigwaitinfo.c
new file mode 100644
index 000000000..80790df9e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sigwaitinfo.c
@@ -0,0 +1,94 @@
+/* Copyright (C) 1997,1998,2000,2002,2003,2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#define __need_NULL
+#include <stddef.h>
+#include <string.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#ifdef __NR_rt_sigtimedwait
+
+static int
+do_sigwaitinfo (const sigset_t *set, siginfo_t *info)
+{
+#ifdef SIGCANCEL
+ sigset_t tmpset;
+ if (set != NULL
+ && (__builtin_expect (__sigismember (set, SIGCANCEL), 0)
+# ifdef SIGSETXID
+ || __builtin_expect (__sigismember (set, SIGSETXID), 0)
+# endif
+ ))
+ {
+ /* Create a temporary mask without the bit for SIGCANCEL set. */
+ // We are not copying more than we have to.
+ memcpy (&tmpset, set, _NSIG / 8);
+ __sigdelset (&tmpset, SIGCANCEL);
+# ifdef SIGSETXID
+ __sigdelset (&tmpset, SIGSETXID);
+# endif
+ set = &tmpset;
+ }
+#endif
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ int result = INLINE_SYSCALL (rt_sigtimedwait, 4, CHECK_SIGSET (set),
+ CHECK_1 (info), NULL, _NSIG / 8);
+
+ /* The kernel generates a SI_TKILL code in si_code in case tkill is
+ used. tkill is transparently used in raise(). Since having
+ SI_TKILL as a code is useful in general we fold the results
+ here. */
+ if (result != -1 && info != NULL && info->si_code == SI_TKILL)
+ info->si_code = SI_USER;
+
+ return result;
+}
+
+
+/* Return any pending signal or wait for one for the given time. */
+int
+__sigwaitinfo (set, info)
+ const sigset_t *set;
+ siginfo_t *info;
+{
+ if (SINGLE_THREAD_P)
+ return do_sigwaitinfo (set, info);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ int result = do_sigwaitinfo (set, info);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+libc_hidden_def (__sigwaitinfo)
+weak_alias (__sigwaitinfo, sigwaitinfo)
+#else
+# include <signal/sigwaitinfo.c>
+#endif
+strong_alias (__sigwaitinfo, __libc_sigwaitinfo)
diff --git a/libc/sysdeps/unix/sysv/linux/sizes.h b/libc/sysdeps/unix/sysv/linux/sizes.h
new file mode 100644
index 000000000..18673e2fc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sizes.h
@@ -0,0 +1,24 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIZES_H
+#define _SIZES_H 1
+
+#define PTR_SIZE_STR "4"
+
+#endif /* sizes.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sleep.c b/libc/sysdeps/unix/sysv/linux/sleep.c
new file mode 100644
index 000000000..0e41a1133
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sleep.c
@@ -0,0 +1,149 @@
+/* Implementation of the POSIX sleep function using nanosleep.
+ Copyright (C) 1996,1997,1998,1999,2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <time.h>
+#include <signal.h>
+#include <string.h> /* For the real memset prototype. */
+#include <unistd.h>
+#include <sys/param.h>
+
+
+#if 0
+static void
+cl (void *arg)
+{
+ (void) __sigprocmask (SIG_SETMASK, arg, (sigset_t *) NULL);
+}
+#endif
+
+
+/* We are going to use the `nanosleep' syscall of the kernel. But the
+ kernel does not implement the stupid SysV SIGCHLD vs. SIG_IGN
+ behaviour for this syscall. Therefore we have to emulate it here. */
+unsigned int
+__sleep (unsigned int seconds)
+{
+ const unsigned int max
+ = (unsigned int) (((unsigned long int) (~((time_t) 0))) >> 1);
+ struct timespec ts;
+ sigset_t set, oset;
+ unsigned int result;
+
+ /* This is not necessary but some buggy programs depend on this. */
+ if (__builtin_expect (seconds == 0, 0))
+ {
+#ifdef CANCELLATION_P
+ CANCELLATION_P (THREAD_SELF);
+#endif
+ return 0;
+ }
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ again:
+ if (sizeof (ts.tv_sec) <= sizeof (seconds))
+ {
+ /* Since SECONDS is unsigned assigning the value to .tv_sec can
+ overflow it. In this case we have to wait in steps. */
+ ts.tv_sec += MIN (seconds, max);
+ seconds -= (unsigned int) ts.tv_sec;
+ }
+ else
+ {
+ ts.tv_sec = (time_t) seconds;
+ seconds = 0;
+ }
+
+ /* Linux will wake up the system call, nanosleep, when SIGCHLD
+ arrives even if SIGCHLD is ignored. We have to deal with it
+ in libc. We block SIGCHLD first. */
+ __sigemptyset (&set);
+ __sigaddset (&set, SIGCHLD);
+ if (__sigprocmask (SIG_BLOCK, &set, &oset))
+ return -1;
+
+ /* If SIGCHLD is already blocked, we don't have to do anything. */
+ if (!__sigismember (&oset, SIGCHLD))
+ {
+ int saved_errno;
+ struct sigaction oact;
+
+ __sigemptyset (&set);
+ __sigaddset (&set, SIGCHLD);
+
+ /* We get the signal handler for SIGCHLD. */
+ if (__sigaction (SIGCHLD, (struct sigaction *) NULL, &oact) < 0)
+ {
+ saved_errno = errno;
+ /* Restore the original signal mask. */
+ (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);
+ __set_errno (saved_errno);
+ return -1;
+ }
+
+ /* Note the sleep() is a cancellation point. But since we call
+ nanosleep() which itself is a cancellation point we do not
+ have to do anything here. */
+ if (oact.sa_handler == SIG_IGN)
+ {
+ //__libc_cleanup_push (cl, &oset);
+
+ /* We should leave SIGCHLD blocked. */
+ while (1)
+ {
+ result = __nanosleep (&ts, &ts);
+
+ if (result != 0 || seconds == 0)
+ break;
+
+ if (sizeof (ts.tv_sec) <= sizeof (seconds))
+ {
+ ts.tv_sec = MIN (seconds, max);
+ seconds -= (unsigned int) ts.tv_nsec;
+ }
+ }
+
+ //__libc_cleanup_pop (0);
+
+ saved_errno = errno;
+ /* Restore the original signal mask. */
+ (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);
+ __set_errno (saved_errno);
+
+ goto out;
+ }
+
+ /* We should unblock SIGCHLD. Restore the original signal mask. */
+ (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);
+ }
+
+ result = __nanosleep (&ts, &ts);
+ if (result == 0 && seconds != 0)
+ goto again;
+
+ out:
+ if (result != 0)
+ /* Round remaining time. */
+ result = seconds + (unsigned int) ts.tv_sec + (ts.tv_nsec >= 500000000L);
+
+ return result;
+}
+weak_alias (__sleep, sleep)
diff --git a/libc/sysdeps/unix/sysv/linux/socketcall.h b/libc/sysdeps/unix/sysv/linux/socketcall.h
new file mode 100644
index 000000000..d836534f3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/socketcall.h
@@ -0,0 +1,48 @@
+/* ID for functions called via socketcall system call.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SOCKETCALL_H
+
+#define _SYS_SOCKETCALL_H 1
+
+/* Define unique numbers for the operations permitted on socket. Linux
+ uses a single system call for all these functions. The relevant code
+ file is /usr/include/linux/net.h.
+ We cannot use a enum here because the values are used in assembler
+ code. */
+
+#define SOCKOP_socket 1
+#define SOCKOP_bind 2
+#define SOCKOP_connect 3
+#define SOCKOP_listen 4
+#define SOCKOP_accept 5
+#define SOCKOP_getsockname 6
+#define SOCKOP_getpeername 7
+#define SOCKOP_socketpair 8
+#define SOCKOP_send 9
+#define SOCKOP_recv 10
+#define SOCKOP_sendto 11
+#define SOCKOP_recvfrom 12
+#define SOCKOP_shutdown 13
+#define SOCKOP_setsockopt 14
+#define SOCKOP_getsockopt 15
+#define SOCKOP_sendmsg 16
+#define SOCKOP_recvmsg 17
+
+#endif /* _SYS_SOCKETCALL_H */
diff --git a/libc/sysdeps/unix/sysv/linux/socketpair.S b/libc/sysdeps/unix/sysv/linux/socketpair.S
new file mode 100644
index 000000000..c954ad1a4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/socketpair.S
@@ -0,0 +1,3 @@
+#define socket socketpair
+#define NARGS 4
+#include <socket.S>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/Makefile b/libc/sysdeps/unix/sysv/linux/sparc/Makefile
new file mode 100644
index 000000000..9cb2a634d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/Makefile
@@ -0,0 +1,5 @@
+64bit-predefine = __sparc_v9__ __arch64__
+
+ifeq ($(subdir),rt)
+librt-routines += rt-sysdep
+endif
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/Versions b/libc/sysdeps/unix/sysv/linux/sparc/Versions
new file mode 100644
index 000000000..be3d2b96c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/Versions
@@ -0,0 +1,28 @@
+libc {
+ # The comment lines with "#errlist-compat" are magic; see errlist-compat.awk.
+ # When you get an error from errlist-compat.awk, you need to add a new
+ # version here.
+
+ GLIBC_2.0 {
+ #errlist-compat 127
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_2.1 {
+ #errlist-compat 127
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_2.3 {
+ #errlist-compat 128
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_2.4 {
+ #errlist-compat 134
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+}
+librt {
+ GLIBC_2.3 {
+ # AIO functions.
+ aio_cancel; aio_cancel64;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/a.out.h b/libc/sysdeps/unix/sysv/linux/sparc/a.out.h
new file mode 100644
index 000000000..6ea7065e1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/a.out.h
@@ -0,0 +1,174 @@
+#ifndef __A_OUT_GNU_H__
+#define __A_OUT_GNU_H__
+
+#include <bits/a.out.h>
+
+#define __GNU_EXEC_MACROS__
+
+struct exec
+{
+ unsigned char a_dynamic:1; /* A __DYNAMIC is in this image. */
+ unsigned char a_toolversion:7;
+ unsigned char a_machtype;
+ unsigned short a_info;
+ unsigned int a_text; /* Length of text, in bytes. */
+ unsigned int a_data; /* Length of data, in bytes. */
+ unsigned int a_bss; /* Length of bss, in bytes. */
+ unsigned int a_syms; /* Length of symbol table, in bytes. */
+ unsigned int a_entry; /* Where program begins. */
+ unsigned int a_trsize;
+ unsigned int a_drsize;
+};
+
+enum machine_type
+{
+ M_OLDSUN2 = 0,
+ M_68010 = 1,
+ M_68020 = 2,
+ M_SPARC = 3,
+ M_386 = 100,
+ M_MIPS1 = 151,
+ M_MIPS2 = 152
+};
+
+#define N_MAGIC(exec) ((exec).a_info & 0xffff)
+#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
+#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
+#define N_SET_INFO(exec, magic, type, flags) \
+ ((exec).a_info = ((magic) & 0xffff) \
+ | (((int)(type) & 0xff) << 16) \
+ | (((flags) & 0xff) << 24))
+#define N_SET_MAGIC(exec, magic) \
+ ((exec).a_info = ((exec).a_info & 0xffff0000) | ((magic) & 0xffff))
+#define N_SET_MACHTYPE(exec, machtype) \
+ ((exec).a_info = \
+ ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
+#define N_SET_FLAGS(exec, flags) \
+ ((exec).a_info = \
+ ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
+
+/* Code indicating object file or impure executable. */
+#define OMAGIC 0407
+/* Code indicating pure executable. */
+#define NMAGIC 0410
+/* Code indicating demand-paged executable. */
+#define ZMAGIC 0413
+/* This indicates a demand-paged executable with the header in the text.
+ The first page is unmapped to help trap NULL pointer references. */
+#define QMAGIC 0314
+/* Code indicating core file. */
+#define CMAGIC 0421
+
+#define N_TRSIZE(a) ((a).a_trsize)
+#define N_DRSIZE(a) ((a).a_drsize)
+#define N_SYMSIZE(a) ((a).a_syms)
+#define N_BADMAG(x) \
+ (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC && N_MAGIC(x) != QMAGIC)
+#define _N_HDROFF(x) (1024 - sizeof (struct exec))
+#define N_TXTOFF(x) \
+ (N_MAGIC(x) == ZMAGIC ? 0 : sizeof (struct exec))
+#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
+#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
+#define N_DRELOFF(x) (N_TRELOFF(x) + N_TRSIZE(x))
+#define N_SYMOFF(x) \
+ (N_TXTOFF(x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize)
+#define N_STROFF(x) (N_SYMOFF(x) + N_SYMSIZE(x))
+
+#define SPARC_PGSIZE 0x2000
+
+/* Address of text segment in memory after it is loaded. */
+#define N_TXTADDR(x) \
+ (unsigned long)(((N_MAGIC(x) == ZMAGIC) && ((x).a_entry < SPARC_PGSIZE)) \
+ ? 0 : SPARC_PGSIZE)
+
+/* Address of data segment in memory after it is loaded. */
+#define SEGMENT_SIZE SPARC_PGSIZE
+
+#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1))
+#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
+
+#define N_DATADDR(x) \
+ (N_MAGIC(x)==OMAGIC \
+ ? (N_TXTADDR(x) + (x).a_text) \
+ : (unsigned long)(_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
+#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
+
+#if !defined (N_NLIST_DECLARED)
+struct nlist
+{
+ union
+ {
+ char *n_name;
+ struct nlist *n_next;
+ long n_strx;
+ } n_un;
+ unsigned char n_type;
+ char n_other;
+ short n_desc;
+ unsigned long n_value;
+};
+#endif /* no N_NLIST_DECLARED. */
+
+#define N_UNDF 0
+#define N_ABS 2
+#define N_TEXT 4
+#define N_DATA 6
+#define N_BSS 8
+#define N_FN 15
+#define N_EXT 1
+#define N_TYPE 036
+#define N_STAB 0340
+#define N_INDR 0xa
+#define N_SETA 0x14 /* Absolute set element symbol. */
+#define N_SETT 0x16 /* Text set element symbol. */
+#define N_SETD 0x18 /* Data set element symbol. */
+#define N_SETB 0x1A /* Bss set element symbol. */
+#define N_SETV 0x1C /* Pointer to set vector in data area. */
+
+#if !defined (N_RELOCATION_INFO_DECLARED)
+enum reloc_type
+{
+ RELOC_8,
+ RELOC_16,
+ RELOC_32,
+ RELOC_DISP8,
+ RELOC_DISP16,
+ RELOC_DISP32,
+ RELOC_WDISP30,
+ RELOC_WDISP22,
+ RELOC_HI22,
+ RELOC_22,
+ RELOC_13,
+ RELOC_LO10,
+ RELOC_SFA_BASE,
+ RELOC_SFA_OFF13,
+ RELOC_BASE10,
+ RELOC_BASE13,
+ RELOC_BASE22,
+ RELOC_PC10,
+ RELOC_PC22,
+ RELOC_JMP_TBL,
+ RELOC_SEGOFF16,
+ RELOC_GLOB_DAT,
+ RELOC_JMP_SLOT,
+ RELOC_RELATIVE
+};
+
+/* This structure describes a single relocation to be performed.
+ The text-relocation section of the file is a vector of these structures,
+ all of which apply to the text section.
+ Likewise, the data-relocation section applies to the data section. */
+
+struct relocation_info
+{
+ unsigned int r_address;
+ unsigned int r_index:24;
+ unsigned int r_extern:1;
+ int r_pad:2;
+ enum reloc_type r_type:5;
+ int r_addend;
+};
+#endif /* no N_RELOCATION_INFO_DECLARED. */
+
+#endif /* __A_OUT_GNU_H__ */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/a.out.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/a.out.h
new file mode 100644
index 000000000..228a8d41a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/a.out.h
@@ -0,0 +1,13 @@
+#ifndef __A_OUT_GNU_H__
+# error "Never use <bits/a.out.h> directly; include <a.out.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+
+/* Signal to users of this header that this architecture really doesn't
+ support a.out binary format. */
+#define __NO_A_OUT_SUPPORT 1
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/environments.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/environments.h
new file mode 100644
index 000000000..a51a564cb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/environments.h
@@ -0,0 +1,87 @@
+/* Copyright (C) 1999, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _UNISTD_H
+# error "Never include this file directly. Use <unistd.h> instead"
+#endif
+
+#include <bits/wordsize.h>
+
+/* This header should define the following symbols under the described
+ situations. A value `1' means that the model is always supported,
+ `-1' means it is never supported. Undefined means it cannot be
+ statically decided.
+
+ _POSIX_V6_ILP32_OFF32 32bit int, long, pointers, and off_t type
+ _POSIX_V6_ILP32_OFFBIG 32bit int, long, and pointers and larger off_t type
+
+ _POSIX_V6_LP64_OFF32 64bit long and pointers and 32bit off_t type
+ _POSIX_V6_LPBIG_OFFBIG 64bit long and pointers and large off_t type
+
+ The macros _XBS5_ILP32_OFF32, _XBS5_ILP32_OFFBIG, _XBS5_LP64_OFF32, and
+ _XBS5_LPBIG_OFFBIG were used in previous versions of the Unix standard
+ and are available only for compatibility.
+*/
+
+#if __WORDSIZE == 64
+
+/* Environments with 32-bit wide pointers are optionally provided.
+ Therefore following macros aren't defined:
+ # undef _POSIX_V6_ILP32_OFF32
+ # undef _POSIX_V6_ILP32_OFFBIG
+ # undef _XBS5_ILP32_OFF32
+ # undef _XBS5_ILP32_OFFBIG
+ and users need to check at runtime. */
+
+/* We also have no use (for now) for an environment with bigger pointers
+ and offsets. */
+# define _POSIX_V6_LPBIG_OFFBIG -1
+# define _XBS5_LPBIG_OFFBIG -1
+
+/* By default we have 64-bit wide `long int', pointers and `off_t'. */
+# define _POSIX_V6_LP64_OFF64 1
+# define _XBS5_LP64_OFF64 1
+
+#else /* __WORDSIZE == 32 */
+
+/* By default we have 32-bit wide `int', `long int', pointers and `off_t'
+ and all platforms support LFS. */
+# define _POSIX_V6_ILP32_OFF32 1
+# define _POSIX_V6_ILP32_OFFBIG 1
+# define _XBS5_ILP32_OFF32 1
+# define _XBS5_ILP32_OFFBIG 1
+
+/* We optionally provide an environment with the above size but an 64-bit
+ side `off_t'. Therefore we don't define _XBS5_ILP32_OFFBIG. */
+
+/* Environments with 64-bit wide pointers can be provided,
+ so these macros aren't defined:
+ # undef _POSIX_V6_LP64_OFF64
+ # undef _POSIX_V6_LPBIG_OFFBIG
+ # undef _XBS5_LP64_OFF64
+ # undef _XBS5_LPBIG_OFFBIG
+ and sysconf tests for it at runtime. */
+
+#endif /* __WORDSIZE == 32 */
+
+#define __ILP32_OFF32_CFLAGS "-m32"
+#define __ILP32_OFFBIG_CFLAGS "-m32 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+#define __ILP32_OFF32_LDFLAGS "-m32"
+#define __ILP32_OFFBIG_LDFLAGS "-m32"
+#define __LP64_OFF64_CFLAGS "-m64"
+#define __LP64_OFF64_LDFLAGS "-m64"
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/errno.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/errno.h
new file mode 100644
index 000000000..02e200c08
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/errno.h
@@ -0,0 +1,58 @@
+/* Error constants. Linux/Sparc specific version.
+ Copyright (C) 1996,1997,1998,1999,2002,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef _ERRNO_H
+
+# undef EDOM
+# undef EILSEQ
+# undef ERANGE
+# include <linux/errno.h>
+
+/* Linux has no ENOTSUP error code. */
+# define ENOTSUP EOPNOTSUPP
+
+# ifndef ECANCELED
+# define ECANCELED 127
+# endif
+
+/* Support for error codes to support robust mutexes was added later, too. */
+# ifndef EOWNERDEAD
+# define EOWNERDEAD 132
+# define ENOTRECOVERABLE 133
+# endif
+
+# ifndef __ASSEMBLER__
+/* Function to get address of global `errno' variable. */
+extern int *__errno_location (void) __THROW __attribute__ ((__const__));
+
+# if !defined _LIBC || defined _LIBC_REENTRANT
+/* When using threads, errno is a per-thread value. */
+# define errno (*__errno_location ())
+# endif
+# endif /* !__ASSEMBLER__ */
+#endif /* _ERRNO_H */
+
+#if !defined _ERRNO_H && defined __need_Emath
+/* This is ugly but the kernel header is not clean enough. We must
+ define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
+ defined. */
+# define EDOM 33 /* Math argument out of domain of function. */
+# define EILSEQ 122 /* Illegal byte sequence. */
+# define ERANGE 34 /* Math result not representable. */
+#endif /* !_ERRNO_H && __need_Emath */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h
new file mode 100644
index 000000000..a965d3165
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h
@@ -0,0 +1,255 @@
+/* O_*, F_*, FD_* bit values for Linux/SPARC.
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2003, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#include <sys/types.h>
+#include <bits/wordsize.h>
+#ifdef __USE_GNU
+# include <bits/uio.h>
+#endif
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_RDONLY 0x0000
+#define O_WRONLY 0x0001
+#define O_RDWR 0x0002
+#define O_ACCMODE 0x0003
+#define O_APPEND 0x0008
+#define O_ASYNC 0x0040
+#define O_CREAT 0x0200 /* not fcntl */
+#define O_TRUNC 0x0400 /* not fcntl */
+#define O_EXCL 0x0800 /* not fcntl */
+#define O_SYNC 0x2000
+#define O_NONBLOCK 0x4000
+#define O_NDELAY (0x0004 | O_NONBLOCK)
+#define O_NOCTTY 0x8000 /* not fcntl */
+
+#ifdef __USE_GNU
+# define O_DIRECTORY 0x10000 /* must be a directory */
+# define O_NOFOLLOW 0x20000 /* don't follow links */
+# define O_DIRECT 0x100000 /* direct disk access hint */
+# define O_NOATIME 0x200000 /* Do not set atime. */
+#endif
+
+#ifdef __USE_LARGEFILE64
+# if __WORDSIZE == 64
+# define O_LARGEFILE 0
+# else
+# define O_LARGEFILE 0x40000
+# endif
+#endif
+
+/* For now Linux has no synchronisity options for data and read
+ operations. We define the symbols here but let them do the same as
+ O_SYNC since this is a superset. */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC O_SYNC /* Synchronize data. */
+# define O_RSYNC O_SYNC /* Synchronize read operations. */
+#endif
+
+/* For now Linux has synchronisity options for data and read operations.
+ We define the symbols here but let them do the same as O_SYNC since
+ this is a superset. */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC O_SYNC /* Synchronize data. */
+# define O_RSYNC O_SYNC /* Synchronize read operations. */
+#endif
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#if defined __USE_BSD || defined __USE_UNIX98
+# define F_GETOWN 5 /* Get owner of socket (receiver of SIGIO). */
+# define F_SETOWN 6 /* Set owner of socket (receiver of SIGIO). */
+#endif
+#ifndef __USE_FILE_OFFSET64
+# define F_GETLK 7 /* Get record locking info. */
+# define F_SETLK 8 /* Set record locking info (non-blocking). */
+# define F_SETLKW 9 /* Set record locking info (blocking). */
+#else
+# define F_GETLK F_GETLK64 /* Get record locking info. */
+# define F_SETLK F_SETLK64 /* Set record locking info (non-blocking).*/
+# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETSIG 10 /* Set number of signal to be sent. */
+# define F_GETSIG 11 /* Get number of signal to be sent. */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETLEASE 1024 /* Set a lease. */
+# define F_GETLEASE 1025 /* Enquire what lease is active. */
+# define F_NOTIFY 1026 /* Request notfications on a directory. */
+#endif
+
+#if __WORDSIZE == 64
+# define F_GETLK64 7 /* Get record locking info. */
+# define F_SETLK64 8 /* Set record locking info (non-blocking). */
+# define F_SETLKW64 9 /* Set record locking info (blocking). */
+#else
+# define F_GETLK64 12 /* Get record locking info. */
+# define F_SETLK64 13 /* Set record locking info (non-blocking). */
+# define F_SETLKW64 14 /* Set record locking info (blocking). */
+#endif
+
+/* for F_[GET|SET]FD */
+#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
+#define F_RDLCK 1 /* Read lock. */
+#define F_WRLCK 2 /* Write lock. */
+#define F_UNLCK 3 /* Remove lock. */
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK 4 /* or 3 */
+#define F_SHLCK 8 /* or 4 */
+
+#ifdef __USE_BSD
+/* Operations for bsd flock(), also used by the kernel implementation */
+# define LOCK_SH 1 /* shared lock */
+# define LOCK_EX 2 /* exclusive lock */
+# define LOCK_NB 4 /* or'd with one of the above to prevent
+ blocking */
+# define LOCK_UN 8 /* remove lock */
+#endif
+
+#ifdef __USE_GNU
+# define LOCK_MAND 32 /* This is a mandatory flock: */
+# define LOCK_READ 64 /* ... which allows concurrent read operations. */
+# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */
+# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */
+#endif
+
+#ifdef __USE_GNU
+/* Types of directory notifications that may be requested with F_NOTIFY. */
+# define DN_ACCESS 0x00000001 /* File accessed. */
+# define DN_MODIFY 0x00000002 /* File modified. */
+# define DN_CREATE 0x00000004 /* File created. */
+# define DN_DELETE 0x00000008 /* File removed. */
+# define DN_RENAME 0x00000010 /* File renamed. */
+# define DN_ATTRIB 0x00000020 /* File changed attibutes. */
+# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */
+#endif
+
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+#ifndef __USE_FILE_OFFSET64
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+#else
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+#endif
+ __pid_t l_pid; /* Process holding the lock. */
+ short int __unused;
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ short int __unused;
+ };
+#endif
+
+/* Define some more compatibility macros to be backward compatible with
+ BSD systems which did not managed to hide these kernel macros. */
+#ifdef __USE_BSD
+# define FAPPEND O_APPEND
+# define FFSYNC O_FSYNC
+# define FASYNC O_ASYNC
+# define FNONBLOCK O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif /* Use BSD. */
+
+/* Advise to `posix_fadvise'. */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
+# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
+#endif
+
+
+#ifdef __USE_GNU
+/* Flags for SYNC_FILE_RANGE. */
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+
+/* Flags for SPLICE and VMSPLICE. */
+# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */
+# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing
+ (but we may still block on the fd
+ we splice from/to). */
+# define SPLICE_F_MORE 4 /* Expect more data. */
+# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
+#endif
+
+__BEGIN_DECLS
+
+#ifdef __USE_GNU
+
+/* Provide kernel hint to read ahead. */
+extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
+ __THROW;
+
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice address range into a pipe. */
+extern int vmsplice (int __fdout, const struct iovec *__iov, size_t __count,
+ unsigned int __flags);
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
new file mode 100644
index 000000000..e86c503f2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
@@ -0,0 +1,37 @@
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IOCTL_H
+# error "Never use <bits/ioctls.h> directly; include <sys/ioctl.h> instead."
+#endif
+
+/* Use the definitions from the kernel header files. */
+#include <asm/ioctls.h>
+
+/* Oh well, this is necessary since the kernel data structure is
+ different from the user-level version. */
+#undef TCGETS
+#undef TCSETS
+#undef TCSETSW
+#undef TCSETSF
+#define TCGETS _IOR ('T', 8, char[36])
+#define TCSETS _IOW ('T', 9, char[36])
+#define TCSETSW _IOW ('T', 10, char[36])
+#define TCSETSF _IOW ('T', 11, char[36])
+
+#include <linux/sockios.h>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/ipc.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/ipc.h
new file mode 100644
index 000000000..988dc125d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/ipc.h
@@ -0,0 +1,62 @@
+/* Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IPC_H
+# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* Mode bits for `msgget', `semget', and `shmget'. */
+#define IPC_CREAT 01000 /* Create key if key does not exist. */
+#define IPC_EXCL 02000 /* Fail if key exists. */
+#define IPC_NOWAIT 04000 /* Return error on wait. */
+
+/* Control commands for `msgctl', `semctl', and `shmctl'. */
+#define IPC_RMID 0 /* Remove identifier. */
+#define IPC_SET 1 /* Set `ipc_perm' options. */
+#define IPC_STAT 2 /* Get `ipc_perm' options. */
+#ifdef __USE_GNU
+# define IPC_INFO 3 /* See ipcs. */
+#endif
+
+/* Special key values. */
+#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
+
+
+/* Data structure used to pass permission information to IPC operations. */
+struct ipc_perm
+ {
+ __key_t __key; /* Key. */
+ __uid_t uid; /* Owner's user ID. */
+ __gid_t gid; /* Owner's group ID. */
+ __uid_t cuid; /* Creator's user ID. */
+ __gid_t cgid; /* Creator's group ID. */
+#if __WORDSIZE == 32
+ unsigned short int __pad1;
+ unsigned short int mode; /* Read/write permission. */
+ unsigned short int __pad2;
+#else
+ __mode_t mode; /* Read/write permission. */
+ unsigned short int __pad1;
+#endif
+ unsigned short int __seq; /* Sequence number. */
+ unsigned long long int __unused1;
+ unsigned long long int __unused2;
+ };
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/mman.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/mman.h
new file mode 100644
index 000000000..be2b7eb28
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/mman.h
@@ -0,0 +1,106 @@
+/* Definitions for POSIX memory map interface. Linux/SPARC version.
+ Copyright (C) 1997,1999,2000,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MMAN_H
+# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
+#endif
+
+/* The following definitions basically come from the kernel headers.
+ But the kernel header is not namespace clean. */
+
+
+/* Protections are chosen from these bits, OR'd together. The
+ implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ without PROT_READ. The only guarantees are that no writing will be
+ allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
+
+#define PROT_READ 0x1 /* Page can be read. */
+#define PROT_WRITE 0x2 /* Page can be written. */
+#define PROT_EXEC 0x4 /* Page can be executed. */
+#define PROT_NONE 0x0 /* Page can not be accessed. */
+#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
+ growsdown vma (mprotect only). */
+#define PROT_GROWSUP 0x02000000 /* Extend change to start of
+ growsup vma (mprotect only). */
+
+/* Sharing types (must choose one and only one of these). */
+#define MAP_SHARED 0x01 /* Share changes. */
+#define MAP_PRIVATE 0x02 /* Changes are private. */
+#ifdef __USE_MISC
+# define MAP_TYPE 0x0f /* Mask for type of mapping. */
+#endif
+
+/* Other flags. */
+#define MAP_FIXED 0x10 /* Interpret addr exactly. */
+#ifdef __USE_MISC
+# define MAP_FILE 0x00
+# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
+# define MAP_ANON MAP_ANONYMOUS
+# define MAP_RENAME MAP_ANONYMOUS
+#endif
+
+/* These are Linux-specific. */
+#ifdef __USE_MISC
+# define MAP_GROWSDOWN 0x0200 /* Stack-like segment. */
+# define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+# define MAP_EXECUTABLE 0x1000 /* Mark it as an executable. */
+# define MAP_LOCKED 0x0100 /* Lock the mapping. */
+# define MAP_NORESERVE 0x0040 /* Don't check for reservations. */
+# define _MAP_NEW 0x80000000 /* Binary compatibility with SunOS. */
+# define MAP_POPULATE 0x8000 /* Populate (prefault) pagetables. */
+# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */
+#endif
+
+/* Flags to `msync'. */
+#define MS_ASYNC 1 /* Sync memory asynchronously. */
+#define MS_SYNC 4 /* Synchronous memory sync. */
+#define MS_INVALIDATE 2 /* Invalidate the caches. */
+
+/* Flags for `mlockall'. */
+#define MCL_CURRENT 0x2000 /* Lock all currently mapped pages. */
+#define MCL_FUTURE 0x4000 /* Lock all additions to address
+ space. */
+
+/* Flags for `mremap'. */
+#ifdef __USE_GNU
+# define MREMAP_MAYMOVE 1
+# define MREMAP_FIXED 2
+#endif
+
+/* Advice to `madvise'. */
+#ifdef __USE_BSD
+# define MADV_NORMAL 0 /* No further special treatment. */
+# define MADV_RANDOM 1 /* Expect random page references. */
+# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define MADV_WILLNEED 3 /* Will need these pages. */
+# define MADV_DONTNEED 4 /* Don't need these pages. */
+# define MADV_FREE 5 /* Content can be freed (Solaris). */
+# define MADV_REMOVE 9 /* Remove these pages and resources. */
+# define MADV_DONTFORK 10 /* Do not inherit across fork. */
+# define MADV_DOFORK 11 /* Do inherit across fork. */
+#endif
+
+/* The POSIX people had to invent similar names for the same things. */
+#ifdef __USE_XOPEN2K
+# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/msq.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/msq.h
new file mode 100644
index 000000000..1268dc858
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/msq.h
@@ -0,0 +1,84 @@
+/* Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* Define options for message queue functions. */
+#define MSG_NOERROR 010000 /* no error if message is too big */
+#ifdef __USE_GNU
+# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+#endif
+
+/* Types used in the structure definition. */
+typedef unsigned long int msgqnum_t;
+typedef unsigned long int msglen_t;
+
+
+/* Structure of record for one message inside the kernel.
+ The type `struct msg' is opaque. */
+struct msqid_ds
+{
+ struct ipc_perm msg_perm; /* structure describing operation permission */
+#if __WORDSIZE == 32
+ unsigned int __pad1;
+#endif
+ __time_t msg_stime; /* time of last msgsnd command */
+#if __WORDSIZE == 32
+ unsigned int __pad2;
+#endif
+ __time_t msg_rtime; /* time of last msgrcv command */
+#if __WORDSIZE == 32
+ unsigned int __pad3;
+#endif
+ __time_t msg_ctime; /* time of last change */
+ unsigned long int __msg_cbytes; /* current number of bytes on queue */
+ msgqnum_t msg_qnum; /* number of messages currently on queue */
+ msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+ __pid_t msg_lspid; /* pid of last msgsnd() */
+ __pid_t msg_lrpid; /* pid of last msgrcv() */
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+};
+
+#ifdef __USE_MISC
+
+# define msg_cbytes __msg_cbytes
+
+/* ipcs ctl commands */
+# define MSG_STAT 11
+# define MSG_INFO 12
+
+/* buffer for msgctl calls IPC_INFO, MSG_INFO */
+struct msginfo
+ {
+ int msgpool;
+ int msgmap;
+ int msgmax;
+ int msgmnb;
+ int msgmni;
+ int msgssz;
+ int msgtql;
+ unsigned short int msgseg;
+ };
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/poll.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/poll.h
new file mode 100644
index 000000000..53b94bc50
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/poll.h
@@ -0,0 +1,50 @@
+/* Copyright (C) 1997, 2001, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_POLL_H
+# error "Never use <bits/poll.h> directly; include <sys/poll.h> instead."
+#endif
+
+/* Event types that can be polled for. These bits may be set in `events'
+ to indicate the interesting event types; they will appear in `revents'
+ to indicate the status of the file descriptor. */
+#define POLLIN 0x001 /* There is data to read. */
+#define POLLPRI 0x002 /* There is urgent data to read. */
+#define POLLOUT 0x004 /* Writing now will not block. */
+
+#ifdef __USE_XOPEN
+/* These values are defined in XPG4.2. */
+# define POLLRDNORM 0x040 /* Normal data may be read. */
+# define POLLRDBAND 0x080 /* Priority data may be read. */
+# define POLLWRNORM POLLOUT /* Writing now will not block. */
+# define POLLWRBAND 0x100 /* Priority data may be written. */
+#endif
+
+#ifdef __USE_GNU
+/* These are extensions for Linux. */
+# define POLLMSG 0x200
+# define POLLREMOVE 0x400
+# define POLLRDHUP 0x800
+#endif
+
+/* Event types always implicitly polled for. These bits need not be set in
+ `events', but they will appear in `revents' to indicate the status of
+ the file descriptor. */
+#define POLLERR 0x008 /* Error condition. */
+#define POLLHUP 0x010 /* Hung up. */
+#define POLLNVAL 0x020 /* Invalid polling request. */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/resource.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/resource.h
new file mode 100644
index 000000000..3f2c60014
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/resource.h
@@ -0,0 +1,241 @@
+/* Bit values & structures for resource limits. Linux/SPARC version.
+ Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2004, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_RESOURCE_H
+# error "Never use <bits/resource.h> directly; include <sys/resource.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Transmute defines to enumerations. The macro re-definitions are
+ necessary because some programs want to test for operating system
+ features with #ifdef RUSAGE_SELF. In ISO C the reflexive
+ definition is a no-op. */
+
+/* Kinds of resource limit. */
+enum __rlimit_resource
+{
+ /* Per-process CPU limit, in seconds. */
+ RLIMIT_CPU = 0,
+#define RLIMIT_CPU RLIMIT_CPU
+
+ /* Largest file that can be created, in bytes. */
+ RLIMIT_FSIZE = 1,
+#define RLIMIT_FSIZE RLIMIT_FSIZE
+
+ /* Maximum size of data segment, in bytes. */
+ RLIMIT_DATA = 2,
+#define RLIMIT_DATA RLIMIT_DATA
+
+ /* Maximum size of stack segment, in bytes. */
+ RLIMIT_STACK = 3,
+#define RLIMIT_STACK RLIMIT_STACK
+
+ /* Largest core file that can be created, in bytes. */
+ RLIMIT_CORE = 4,
+#define RLIMIT_CORE RLIMIT_CORE
+
+ /* Largest resident set size, in bytes.
+ This affects swapping; processes that are exceeding their
+ resident set size will be more likely to have physical memory
+ taken from them. */
+ __RLIMIT_RSS = 5,
+#define RLIMIT_RSS __RLIMIT_RSS
+
+ /* Number of open files. */
+ RLIMIT_NOFILE = 6,
+ __RLIMIT_OFILE = RLIMIT_NOFILE, /* BSD name for same. */
+#define RLIMIT_NOFILE RLIMIT_NOFILE
+#define RLIMIT_OFILE __RLIMIT_OFILE
+
+ /* Address space limit (?) */
+ RLIMIT_AS = 9,
+#define RLIMIT_AS RLIMIT_AS
+
+ /* Number of processes. */
+ __RLIMIT_NPROC = 7,
+#define RLIMIT_NPROC __RLIMIT_NPROC
+
+ /* Locked-in-memory address space. */
+ __RLIMIT_MEMLOCK = 8,
+#define RLIMIT_MEMLOCK __RLIMIT_MEMLOCK
+
+ /* Maximum number of file locks. */
+ __RLIMIT_LOCKS = 10,
+#define RLIMIT_LOCKS __RLIMIT_LOCKS
+
+ /* Maximum number of pending signals. */
+ __RLIMIT_SIGPENDING = 11,
+#define RLIMIT_SIGPENDING __RLIMIT_SIGPENDING
+
+ /* Maximum bytes in POSIX message queues. */
+ __RLIMIT_MSGQUEUE = 12,
+#define RLIMIT_MSGQUEUE __RLIMIT_MSGQUEUE
+
+ /* Maximum nice priority allowed to raise to.
+ Nice levels 19 .. -20 correspond to 0 .. 39
+ values of this resource limit. */
+ __RLIMIT_NICE = 13,
+#define RLIMIT_NICE __RLIMIT_NICE
+
+ /* Maximum realtime priority allowed for non-priviledged
+ processes. */
+ __RLIMIT_RTPRIO = 14,
+#define RLIMIT_RTPRIO __RLIMIT_RTPRIO
+
+ __RLIMIT_NLIMITS = 15,
+ __RLIM_NLIMITS = __RLIMIT_NLIMITS
+#define RLIMIT_NLIMITS __RLIMIT_NLIMITS
+#define RLIM_NLIMITS __RLIM_NLIMITS
+};
+
+/* Value to indicate that there is no limit. */
+#if __WORDSIZE == 64
+
+#ifndef __USE_FILE_OFFSET64
+# define RLIM_INFINITY ((unsigned long int)(~0UL))
+#else
+# define RLIM_INFINITY 0xffffffffffffffffuLL
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define RLIM64_INFINITY 0xffffffffffffffffuLL
+#endif
+
+#else
+
+#ifndef __USE_FILE_OFFSET64
+# define RLIM_INFINITY ((long int)(~0UL >> 1))
+#else
+# define RLIM_INFINITY 0x7fffffffffffffffLL
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define RLIM64_INFINITY 0x7fffffffffffffffLL
+#endif
+
+#endif
+
+/* We can represent all limits. */
+#define RLIM_SAVED_MAX RLIM_INFINITY
+#define RLIM_SAVED_CUR RLIM_INFINITY
+
+
+/* Type for resource quantity measurement. */
+#ifndef __USE_FILE_OFFSET64
+typedef __rlim_t rlim_t;
+#else
+typedef __rlim64_t rlim_t;
+#endif
+#ifdef __USE_LARGEFILE64
+typedef __rlim64_t rlim64_t;
+#endif
+
+struct rlimit
+ {
+ /* The current (soft) limit. */
+ rlim_t rlim_cur;
+ /* The hard limit. */
+ rlim_t rlim_max;
+ };
+
+#ifdef __USE_LARGEFILE64
+struct rlimit64
+ {
+ /* The current (soft) limit. */
+ rlim64_t rlim_cur;
+ /* The hard limit. */
+ rlim64_t rlim_max;
+ };
+#endif
+
+/* Whose usage statistics do you want? */
+enum __rusage_who
+{
+ /* The calling process. */
+ RUSAGE_SELF = 0,
+#define RUSAGE_SELF RUSAGE_SELF
+
+ /* All of its terminated child processes. */
+ RUSAGE_CHILDREN = -1
+#define RUSAGE_CHILDREN RUSAGE_CHILDREN
+};
+
+#define __need_timeval
+#include <bits/time.h> /* For `struct timeval'. */
+
+/* Structure which says how much of each resource has been used. */
+struct rusage
+ {
+ /* Total amount of user time used. */
+ struct timeval ru_utime;
+ /* Total amount of system time used. */
+ struct timeval ru_stime;
+ /* Maximum resident set size (in kilobytes). */
+ long int ru_maxrss;
+ /* Amount of sharing of text segment memory
+ with other processes (kilobyte-seconds). */
+ long int ru_ixrss;
+ /* Amount of data segment memory used (kilobyte-seconds). */
+ long int ru_idrss;
+ /* Amount of stack memory used (kilobyte-seconds). */
+ long int ru_isrss;
+ /* Number of soft page faults (i.e. those serviced by reclaiming
+ a page from the list of pages awaiting reallocation. */
+ long int ru_minflt;
+ /* Number of hard page faults (i.e. those that required I/O). */
+ long int ru_majflt;
+ /* Number of times a process was swapped out of physical memory. */
+ long int ru_nswap;
+ /* Number of input operations via the file system. Note: This
+ and `ru_oublock' do not include operations with the cache. */
+ long int ru_inblock;
+ /* Number of output operations via the file system. */
+ long int ru_oublock;
+ /* Number of IPC messages sent. */
+ long int ru_msgsnd;
+ /* Number of IPC messages received. */
+ long int ru_msgrcv;
+ /* Number of signals delivered. */
+ long int ru_nsignals;
+ /* Number of voluntary context switches, i.e. because the process
+ gave up the process before it had to (usually to wait for some
+ resource to be available). */
+ long int ru_nvcsw;
+ /* Number of involuntary context switches, i.e. a higher priority process
+ became runnable or the current process used up its time slice. */
+ long int ru_nivcsw;
+ };
+
+/* Priority limits. */
+#define PRIO_MIN -20 /* Minimum priority a process can have. */
+#define PRIO_MAX 20 /* Maximum priority a process can have. */
+
+/* The type of the WHICH argument to `getpriority' and `setpriority',
+ indicating what flavor of entity the WHO argument specifies. */
+enum __priority_which
+{
+ PRIO_PROCESS = 0, /* WHO is a process ID. */
+#define PRIO_PROCESS PRIO_PROCESS
+ PRIO_PGRP = 1, /* WHO is a process group ID. */
+#define PRIO_PGRP PRIO_PGRP
+ PRIO_USER = 2 /* WHO is a user ID. */
+#define PRIO_USER PRIO_USER
+};
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/sem.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/sem.h
new file mode 100644
index 000000000..288076510
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/sem.h
@@ -0,0 +1,92 @@
+/* Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SEM_H
+# error "Never include <bits/sem.h> directly; use <sys/sem.h> instead."
+#endif
+
+#include <sys/types.h>
+#include <bits/wordsize.h>
+
+/* Flags for `semop'. */
+#define SEM_UNDO 0x1000 /* undo the operation on exit */
+
+/* Commands for `semctl'. */
+#define GETPID 11 /* get sempid */
+#define GETVAL 12 /* get semval */
+#define GETALL 13 /* get all semval's */
+#define GETNCNT 14 /* get semncnt */
+#define GETZCNT 15 /* get semzcnt */
+#define SETVAL 16 /* set semval */
+#define SETALL 17 /* set all semval's */
+
+
+/* Data structure describing a set of semaphores. */
+struct semid_ds
+{
+ struct ipc_perm sem_perm; /* operation permission struct */
+#if __WORDSIZE == 32
+ unsigned int __pad1;
+#endif
+ __time_t sem_otime; /* last semop() time */
+#if __WORDSIZE == 32
+ unsigned int __pad2;
+#endif
+ __time_t sem_ctime; /* last time changed by semctl() */
+ unsigned long int sem_nsems; /* number of semaphores in set */
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+};
+
+/* The user should define a union like the following to use it for arguments
+ for `semctl'.
+
+ union semun
+ {
+ int val; <= value for SETVAL
+ struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET
+ unsigned short int *array; <= array for GETALL & SETALL
+ struct seminfo *__buf; <= buffer for IPC_INFO
+ };
+
+ Previous versions of this file used to define this union but this is
+ incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether
+ one must define the union or not. */
+#define _SEM_SEMUN_UNDEFINED 1
+
+#ifdef __USE_MISC
+
+/* ipcs ctl cmds */
+# define SEM_STAT 18
+# define SEM_INFO 19
+
+struct seminfo
+{
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvmx;
+ int semaem;
+};
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/setjmp.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/setjmp.h
new file mode 100644
index 000000000..b44cc0fcd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/setjmp.h
@@ -0,0 +1,69 @@
+/* Copyright (C) 1997, 1999, 2000, 2003, 2005, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H 1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+
+#ifndef _ASM
+typedef struct __sparc64_jmp_buf
+ {
+ struct __sparc64_jmp_buf *uc_link;
+ unsigned long uc_flags;
+ unsigned long uc_sigmask;
+ struct __sparc64_jmp_buf_mcontext
+ {
+ unsigned long mc_gregs[19];
+ unsigned long mc_fp;
+ unsigned long mc_i7;
+ struct __sparc64_jmp_buf_fpu
+ {
+ union
+ {
+ unsigned int sregs[32];
+ unsigned long dregs[32];
+ long double qregs[16];
+ } mcfpu_fpregs;
+ unsigned long mcfpu_fprs;
+ unsigned long mcfpu_gsr;
+ void *mcfpu_fq;
+ unsigned char mcfpu_qcnt;
+ unsigned char mcfpu_qentsz;
+ unsigned char mcfpu_enab;
+ } mc_fpregs;
+ } uc_mcontext;
+ } __jmp_buf[1];
+#endif
+
+#else
+
+#ifndef _ASM
+typedef int __jmp_buf[3];
+#endif
+
+#endif
+
+#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/shm.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/shm.h
new file mode 100644
index 000000000..03decb110
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/shm.h
@@ -0,0 +1,111 @@
+/* Copyright (C) 1995, 1996, 1997, 2000, 2002, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple. */
+#define SHMLBA (__getpagesize ())
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a set of semaphores. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+#if __WORDSIZE == 32
+ unsigned int __pad1;
+#endif
+ __time_t shm_atime; /* time of last shmat() */
+#if __WORDSIZE == 32
+ unsigned int __pad2;
+#endif
+ __time_t shm_dtime; /* time of last shmdt() */
+#if __WORDSIZE == 32
+ unsigned int __pad3;
+#endif
+ __time_t shm_ctime; /* time of last change by shmctl() */
+ size_t shm_segsz; /* size of segment in bytes */
+ __pid_t shm_cpid; /* pid of creator */
+ __pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */
+# define SHM_NORESERVE 010000 /* don't check for reservations */
+
+struct shminfo
+ {
+ unsigned long shmmax;
+ unsigned long shmmin;
+ unsigned long shmmni;
+ unsigned long shmseg;
+ unsigned long shmall;
+ unsigned long __unused1;
+ unsigned long __unused2;
+ unsigned long __unused3;
+ unsigned long __unused4;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/sigaction.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/sigaction.h
new file mode 100644
index 000000000..ee4196764
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/sigaction.h
@@ -0,0 +1,76 @@
+/* The proper definitions for Linux/SPARC sigaction.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIGNAL_H
+# error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
+#endif
+
+/* Structure describing the action to be taken when a signal arrives. */
+struct sigaction
+ {
+ /* Signal handler. */
+#ifdef __USE_POSIX199309
+ union
+ {
+ /* Used if SA_SIGINFO is not set. */
+ __sighandler_t sa_handler;
+ /* Used if SA_SIGINFO is set. */
+ void (*sa_sigaction) (int, siginfo_t *, void *);
+ }
+ __sigaction_handler;
+# define sa_handler __sigaction_handler.sa_handler
+# define sa_sigaction __sigaction_handler.sa_sigaction
+#else
+ __sighandler_t sa_handler;
+#endif
+
+ /* Additional set of signals to be blocked. */
+ __sigset_t sa_mask;
+
+ /* Special flags. */
+ unsigned long sa_flags;
+
+ /* Not used by Linux/Sparc yet. */
+ void (*sa_restorer) (void);
+ };
+
+
+/* Bits in `sa_flags'. */
+#define SA_NOCLDSTOP 0x00000008 /* Don't send SIGCHLD when children stop. */
+#define SA_NOCLDWAIT 0x00000100 /* Don't create zombie on child death. */
+#define SA_SIGINFO 0x00000200 /* Invoke signal-catching function with
+ three arguments instead of one. */
+#if defined __USE_UNIX98 || defined __USE_MISC
+# define SA_ONSTACK 0x00000001 /* Use signal stack by using `sa_restorer'. */
+# define SA_RESTART 0x00000002 /* Restart syscall on signal return. */
+# define SA_INTERRUPT 0x00000010 /* Historical no-op. */
+# define SA_NOMASK 0x00000020 /* Don't automatically block the signal when
+ its handler is being executed. */
+# define SA_ONESHOT 0x00000004 /* Reset to SIG_DFL on entry to handler. */
+
+/* Some aliases for the SA_ constants. */
+# define SA_NODEFER SA_NOMASK
+# define SA_RESETHAND SA_ONESHOT
+# define SA_STACK SA_ONSTACK
+#endif
+
+/* Values for the HOW argument to `sigprocmask'. */
+#define SIG_BLOCK 1 /* Block signals. */
+#define SIG_UNBLOCK 2 /* Unblock signals. */
+#define SIG_SETMASK 4 /* Set the set of blocked signals. */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/sigcontext.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/sigcontext.h
new file mode 100644
index 000000000..42eca544e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/sigcontext.h
@@ -0,0 +1,78 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
+# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 32
+
+/* It is quite hard to choose what to put here, because
+ Linux/sparc32 had at least 3 totally incompatible
+ signal stack layouts.
+ This one is for the "new" style signals, which are
+ now delivered unless SA_SIGINFO is requested. */
+
+struct sigcontext
+ {
+ struct
+ {
+ unsigned int psr;
+ unsigned int pc;
+ unsigned int npc;
+ unsigned int y;
+ unsigned int u_regs[16]; /* globals and ins */
+ } si_regs;
+ int si_mask;
+ };
+
+#else /* sparc64 */
+
+typedef struct
+ {
+ unsigned int si_float_regs [64];
+ unsigned long si_fsr;
+ unsigned long si_gsr;
+ unsigned long si_fprs;
+ } __siginfo_fpu_t;
+
+struct sigcontext
+ {
+ char sigc_info[128];
+ struct
+ {
+ unsigned long u_regs[16]; /* globals and ins */
+ unsigned long tstate;
+ unsigned long tpc;
+ unsigned long tnpc;
+ unsigned int y;
+ unsigned int fprs;
+ } sigc_regs;
+ __siginfo_fpu_t * sigc_fpu_save;
+ struct
+ {
+ void * ss_sp;
+ int ss_flags;
+ unsigned long ss_size;
+ } sigc_stack;
+ unsigned long sigc_mask;
+};
+
+#endif /* sparc64 */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/siginfo.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/siginfo.h
new file mode 100644
index 000000000..7ff1971c2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/siginfo.h
@@ -0,0 +1,318 @@
+/* siginfo_t, sigevent and constants. Linux/SPARC version.
+ Copyright (C) 1997-2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _SIGNAL_H && !defined __need_siginfo_t \
+ && !defined __need_sigevent_t
+# error "Never include this file directly. Use <signal.h> instead"
+#endif
+
+#include <bits/wordsize.h>
+
+#if (!defined __have_sigval_t \
+ && (defined _SIGNAL_H || defined __need_siginfo_t \
+ || defined __need_sigevent_t))
+# define __have_sigval_t 1
+
+/* Type for data associated with a signal. */
+typedef union sigval
+ {
+ int sival_int;
+ void *sival_ptr;
+ } sigval_t;
+#endif
+
+#if (!defined __have_siginfo_t \
+ && (defined _SIGNAL_H || defined __need_siginfo_t))
+# define __have_siginfo_t 1
+
+# define __SI_MAX_SIZE 128
+# if __WORDSIZE == 64
+# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
+# else
+# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
+# endif
+
+typedef struct siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_errno; /* If non-zero, an errno value associated with
+ this signal, as defined in <errno.h>. */
+ int si_code; /* Signal code. */
+
+ union
+ {
+ int _pad[__SI_PAD_SIZE];
+
+ /* kill(). */
+ struct
+ {
+ __pid_t si_pid; /* Sending process ID. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ } _kill;
+
+ /* POSIX.1b timers. */
+ struct
+ {
+ int si_tid; /* Timer ID. */
+ int si_overrun; /* Overrun count. */
+ sigval_t si_sigval; /* Signal value. */
+ } _timer;
+
+ /* POSIX.1b signals. */
+ struct
+ {
+ __pid_t si_pid; /* Sending process ID. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ sigval_t si_sigval; /* Signal value. */
+ } _rt;
+
+ /* SIGCHLD. */
+ struct
+ {
+ __pid_t si_pid; /* Which child. */
+ __uid_t si_uid; /* Real user ID of sending process. */
+ int si_status; /* Exit value or signal. */
+ __clock_t si_utime;
+ __clock_t si_stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
+ struct
+ {
+ void *si_addr; /* Faulting insn/memory ref. */
+ int si_trapno;
+ } _sigfault;
+
+ /* SIGPOLL. */
+ struct
+ {
+ int si_band; /* Band event for SIGPOLL. */
+ int si_fd;
+ } _sigpoll;
+ } _sifields;
+ } siginfo_t;
+
+
+/* X/Open requires some more fields with fixed names. */
+# define si_pid _sifields._kill.si_pid
+# define si_uid _sifields._kill.si_uid
+# define si_timerid _sifields._timer.si_tid
+# define si_overrun _sifields._timer.si_overrun
+# define si_status _sifields._sigchld.si_status
+# define si_utime _sifields._sigchld.si_utime
+# define si_stime _sifields._sigchld.si_stime
+# define si_value _sifields._rt.si_sigval
+# define si_int _sifields._rt.si_sigval.sival_int
+# define si_ptr _sifields._rt.si_sigval.sival_ptr
+# define si_addr _sifields._sigfault.si_addr
+# define si_trapno _sifields._sigfault.si_trapno
+# define si_band _sifields._sigpoll.si_band
+# define si_fd _sifields._sigpoll.si_fd
+
+
+/* Values for `si_code'. Positive values are reserved for kernel-generated
+ signals. */
+enum
+{
+ SI_ASYNCNL = -60, /* Sent by asynch name lookup completion. */
+# define SI_ASYNCNL SI_ASYNCNL
+ SI_TKILL = -6, /* Sent by tkill. */
+# define SI_TKILL SI_TKILL
+ SI_SIGIO, /* Sent by queued SIGIO. */
+# define SI_SIGIO SI_SIGIO
+ SI_ASYNCIO, /* Sent by AIO completion. */
+# define SI_ASYNCIO SI_ASYNCIO
+ SI_MESGQ, /* Sent by real time mesq state change. */
+# define SI_MESGQ SI_MESGQ
+ SI_TIMER, /* Sent by timer expiration. */
+# define SI_TIMER SI_TIMER
+ SI_QUEUE, /* Sent by sigqueue. */
+# define SI_QUEUE SI_QUEUE
+ SI_USER, /* Sent by kill, sigsend, raise. */
+# define SI_USER SI_USER
+ SI_KERNEL = 0x80 /* Send by kernel. */
+#define SI_KERNEL SI_KERNEL
+};
+
+
+/* `si_code' values for SIGILL signal. */
+enum
+{
+ ILL_ILLOPC = 1, /* Illegal opcode. */
+# define ILL_ILLOPC ILL_ILLOPC
+ ILL_ILLOPN, /* Illegal operand. */
+# define ILL_ILLOPN ILL_ILLOPN
+ ILL_ILLADR, /* Illegal addressing mode. */
+# define ILL_ILLADR ILL_ILLADR
+ ILL_ILLTRP, /* Illegal trap. */
+# define ILL_ILLTRP ILL_ILLTRP
+ ILL_PRVOPC, /* Privileged opcode. */
+# define ILL_PRVOPC ILL_PRVOPC
+ ILL_PRVREG, /* Privileged register. */
+# define ILL_PRVREG ILL_PRVREG
+ ILL_COPROC, /* Coprocessor error. */
+# define ILL_COPROC ILL_COPROC
+ ILL_BADSTK /* Internal stack error. */
+# define ILL_BADSTK ILL_BADSTK
+};
+
+/* `si_code' values for SIGFPE signal. */
+enum
+{
+ FPE_INTDIV = 1, /* Integer divide by zero. */
+# define FPE_INTDIV FPE_INTDIV
+ FPE_INTOVF, /* Integer overflow. */
+# define FPE_INTOVF FPE_INTOVF
+ FPE_FLTDIV, /* Floating point divide by zero. */
+# define FPE_FLTDIV FPE_FLTDIV
+ FPE_FLTOVF, /* Floating point overflow. */
+# define FPE_FLTOVF FPE_FLTOVF
+ FPE_FLTUND, /* Floating point underflow. */
+# define FPE_FLTUND FPE_FLTUND
+ FPE_FLTRES, /* Floating point inexact result. */
+# define FPE_FLTRES FPE_FLTRES
+ FPE_FLTINV, /* Floating point invalid operation. */
+# define FPE_FLTINV FPE_FLTINV
+ FPE_FLTSUB /* Subscript out of range. */
+# define FPE_FLTSUB FPE_FLTSUB
+};
+
+/* `si_code' values for SIGSEGV signal. */
+enum
+{
+ SEGV_MAPERR = 1, /* Address not mapped to object. */
+# define SEGV_MAPERR SEGV_MAPERR
+ SEGV_ACCERR /* Invalid permissions for mapped object. */
+# define SEGV_ACCERR SEGV_ACCERR
+};
+
+/* `si_code' values for SIGBUS signal. */
+enum
+{
+ BUS_ADRALN = 1, /* Invalid address alignment. */
+# define BUS_ADRALN BUS_ADRALN
+ BUS_ADRERR, /* Non-existant physical address. */
+# define BUS_ADRERR BUS_ADRERR
+ BUS_OBJERR /* Object specific hardware error. */
+# define BUS_OBJERR BUS_OBJERR
+};
+
+/* `si_code' values for SIGTRAP signal. */
+enum
+{
+ TRAP_BRKPT = 1, /* Process breakpoint. */
+# define TRAP_BRKPT TRAP_BRKPT
+ TRAP_TRACE /* Process trace trap. */
+# define TRAP_TRACE TRAP_TRACE
+};
+
+/* `si_code' values for SIGCHLD signal. */
+enum
+{
+ CLD_EXITED = 1, /* Child has exited. */
+# define CLD_EXITED CLD_EXITED
+ CLD_KILLED, /* Child was killed. */
+# define CLD_KILLED CLD_KILLED
+ CLD_DUMPED, /* Child terminated abnormally. */
+# define CLD_DUMPED CLD_DUMPED
+ CLD_TRAPPED, /* Traced child has trapped. */
+# define CLD_TRAPPED CLD_TRAPPED
+ CLD_STOPPED, /* Child has stopped. */
+# define CLD_STOPPED CLD_STOPPED
+ CLD_CONTINUED /* Stopped child has continued. */
+# define CLD_CONTINUED CLD_CONTINUED
+};
+
+/* `si_code' values for SIGPOLL signal. */
+enum
+{
+ POLL_IN = 1, /* Data input available. */
+# define POLL_IN POLL_IN
+ POLL_OUT, /* Output buffers available. */
+# define POLL_OUT POLL_OUT
+ POLL_MSG, /* Input message available. */
+# define POLL_MSG POLL_MSG
+ POLL_ERR, /* I/O error. */
+# define POLL_ERR POLL_ERR
+ POLL_PRI, /* High priority input available. */
+# define POLL_PRI POLL_PRI
+ POLL_HUP /* Device disconnected. */
+# define POLL_HUP POLL_HUP
+};
+
+/* `si_code' values for SIGEMT signal. */
+enum
+{
+ EMT_TAGOVF = 1 /* Tag overflow. */
+# define EMT_TAGOVF EMT_TAGOVF
+};
+
+# undef __need_siginfo_t
+#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
+
+
+#if (defined _SIGNAL_H || defined __need_sigevent_t) \
+ && !defined __have_sigevent_t
+# define __have_sigevent_t 1
+
+/* Structure to transport application-defined values with signals. */
+# define __SIGEV_MAX_SIZE 64
+# if __WORDSIZE == 64
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4)
+# else
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 3)
+# endif
+
+typedef struct sigevent
+ {
+ sigval_t sigev_value;
+ int sigev_signo;
+ int sigev_notify;
+
+ union
+ {
+ int _pad[__SIGEV_PAD_SIZE];
+
+ struct
+ {
+ void (*_function) (sigval_t); /* Function to start. */
+ void *_attribute; /* Really pthread_attr_t. */
+ } _sigev_thread;
+ } _sigev_un;
+ } sigevent_t;
+
+/* POSIX names to access some of the members. */
+# define sigev_notify_function _sigev_un._sigev_thread._function
+# define sigev_notify_attributes _sigev_un._sigev_thread._attribute
+
+/* `sigev_notify' values. */
+enum
+{
+ SIGEV_SIGNAL = 0, /* Notify via signal. */
+# define SIGEV_SIGNAL SIGEV_SIGNAL
+ SIGEV_NONE, /* Other notification: meaningless. */
+# define SIGEV_NONE SIGEV_NONE
+ SIGEV_THREAD, /* Deliver via thread creation. */
+# define SIGEV_THREAD SIGEV_THREAD
+
+ SIGEV_THREAD_ID = 4 /* Send signal to specific thread. */
+#define SIGEV_THREAD_ID SIGEV_THREAD_ID
+};
+
+#endif /* have _SIGNAL_H. */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/signum.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/signum.h
new file mode 100644
index 000000000..6b58ec29d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/signum.h
@@ -0,0 +1,84 @@
+/* Signal number definitions. Linux/SPARC version.
+ Copyright (C) 1996, 1997, 1998, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef _SIGNAL_H
+
+/* Fake signal functions. */
+#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
+#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
+#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
+
+#ifdef __USE_UNIX98
+# define SIG_HOLD ((__sighandler_t) 2) /* Add signal to hold mask. */
+#endif
+
+/*
+ * Linux/SPARC has different signal numbers that Linux/i386: I'm trying
+ * to make it OSF/1 binary compatible, at least for normal binaries.
+ */
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGEMT 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGBUS 10
+#define SIGSEGV 11
+#define SIGSYS 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGURG 16
+
+/* SunOS values which deviate from the Linux/i386 ones */
+#define SIGSTOP 17
+#define SIGTSTP 18
+#define SIGCONT 19
+#define SIGCHLD 20
+#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGIO 23
+#define SIGPOLL SIGIO /* SysV name for SIGIO */
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGLOST 29
+#define SIGPWR SIGLOST
+#define SIGUSR1 30
+#define SIGUSR2 31
+
+#define _NSIG 65 /* Biggest signal number + 1
+ (including real-time signals). */
+
+#define SIGRTMIN (__libc_current_sigrtmin ())
+#define SIGRTMAX (__libc_current_sigrtmax ())
+
+/* These are the hard limits of the kernel. These values should not be
+ used directly at user level. */
+#define __SIGRTMIN 32
+#define __SIGRTMAX (_NSIG - 1)
+
+#endif /* <signal.h> included. */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/sigstack.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/sigstack.h
new file mode 100644
index 000000000..df4653949
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/sigstack.h
@@ -0,0 +1,55 @@
+/* sigstack, sigaltstack definitions.
+ Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIGNAL_H
+# error "Never include this file directly. Use <signal.h> instead"
+#endif
+
+
+/* Structure describing a signal stack (obsolete). */
+struct sigstack
+ {
+ void *ss_sp; /* Signal stack pointer. */
+ int ss_onstack; /* Nonzero if executing on this stack. */
+ };
+
+
+/* Possible values for `ss_flags.'. */
+enum
+{
+ SS_ONSTACK = 1,
+#define SS_ONSTACK SS_ONSTACK
+ SS_DISABLE
+#define SS_DISABLE SS_DISABLE
+};
+
+/* Minimum stack size for a signal handler. */
+#define MINSIGSTKSZ 4096
+
+/* System default stack size. */
+#define SIGSTKSZ 16384
+
+
+/* Alternate, preferred interface. */
+typedef struct sigaltstack
+ {
+ void *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+ } stack_t;
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/stat.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/stat.h
new file mode 100644
index 000000000..2fccb14cf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/stat.h
@@ -0,0 +1,165 @@
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+/* Versions of the `struct stat' data structure. */
+#define _STAT_VER_LINUX_OLD 1
+#define _STAT_VER_KERNEL 1
+#define _STAT_VER_SVR4 2
+#define _STAT_VER_LINUX 3
+#define _STAT_VER _STAT_VER_LINUX /* The one defined below. */
+
+/* Versions of the `xmknod' interface. */
+#define _MKNOD_VER_LINUX 1
+#define _MKNOD_VER_SVR4 2
+#define _MKNOD_VER _MKNOD_VER_LINUX /* The bits defined below. */
+
+
+struct stat
+ {
+ __dev_t st_dev; /* Device. */
+#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
+ unsigned short int __pad1;
+ __ino_t st_ino; /* File serial number. */
+#else
+ __ino64_t st_ino; /* File serial number. */
+#endif
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned short int __pad2;
+#ifndef __USE_FILE_OFFSET64
+ __off_t st_size; /* Size of file, in bytes. */
+#else
+ __off64_t st_size; /* Size of file, in bytes. */
+#endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+#ifndef __USE_FILE_OFFSET64
+ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
+#else
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+#endif
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+ };
+
+#ifdef __USE_LARGEFILE64
+struct stat64
+ {
+ __dev_t st_dev; /* Device. */
+#if __WORDSIZE == 64
+ unsigned short int __pad1;
+#endif
+ __ino64_t st_ino; /* File serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned short int __pad2;
+ __off64_t st_size; /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+ };
+#endif
+
+/* Tell code we have these members. */
+#define _STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+/* Nanosecond resolution time values are supported. */
+#define _STATBUF_ST_NSEC
+
+/* Encoding of the file mode. */
+
+#define __S_IFMT 0170000 /* These bits determine file type. */
+
+/* File types. */
+#define __S_IFDIR 0040000 /* Directory. */
+#define __S_IFCHR 0020000 /* Character device. */
+#define __S_IFBLK 0060000 /* Block device. */
+#define __S_IFREG 0100000 /* Regular file. */
+#define __S_IFIFO 0010000 /* FIFO. */
+#define __S_IFLNK 0120000 /* Symbolic link. */
+#define __S_IFSOCK 0140000 /* Socket. */
+
+/* POSIX.1b objects. Note that these macros always evaluate to zero. But
+ they do it by enforcing the correct use of the macros. */
+#define __S_TYPEISMQ(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
+
+/* Protection bits. */
+
+#define __S_ISUID 04000 /* Set user ID on execution. */
+#define __S_ISGID 02000 /* Set group ID on execution. */
+#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
+#define __S_IREAD 0400 /* Read by owner. */
+#define __S_IWRITE 0200 /* Write by owner. */
+#define __S_IEXEC 0100 /* Execute by owner. */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/termios.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/termios.h
new file mode 100644
index 000000000..cea13227f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/termios.h
@@ -0,0 +1,233 @@
+/* termios type and macro definitions. Linux/SPARC version.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _TERMIOS_H
+# error "Never include <bits/termios.h> directly; use <termios.h> instead."
+#endif
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 17
+struct termios
+ {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ };
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VEOL 5
+#define VEOL2 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VDSUSP 11 /* SunOS POSIX nicety I do believe... */
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+
+/* User apps assume vmin/vtime is shared with eof/eol */
+#define VMIN VEOF
+#define VTIME VEOL
+
+/* c_iflag bits */
+#define IGNBRK 0x00000001
+#define BRKINT 0x00000002
+#define IGNPAR 0x00000004
+#define PARMRK 0x00000008
+#define INPCK 0x00000010
+#define ISTRIP 0x00000020
+#define INLCR 0x00000040
+#define IGNCR 0x00000080
+#define ICRNL 0x00000100
+#define IUCLC 0x00000200
+#define IXON 0x00000400
+#define IXANY 0x00000800
+#define IXOFF 0x00001000
+#define IMAXBEL 0x00002000
+#define IUTF8 0x00004000
+
+/* c_oflag bits */
+#define OPOST 0x00000001
+#define OLCUC 0x00000002
+#define ONLCR 0x00000004
+#define OCRNL 0x00000008
+#define ONOCR 0x00000010
+#define ONLRET 0x00000020
+#define OFILL 0x00000040
+#define OFDEL 0x00000080
+#if defined __USE_MISC || defined __USE_XOPEN
+# define NLDLY 0x00000100
+# define NL0 0x00000000
+# define NL1 0x00000100
+# define CRDLY 0x00000600
+# define CR0 0x00000000
+# define CR1 0x00000200
+# define CR2 0x00000400
+# define CR3 0x00000600
+# define TABDLY 0x00001800
+# define TAB0 0x00000000
+# define TAB1 0x00000800
+# define TAB2 0x00001000
+# define TAB3 0x00001800
+# define BSDLY 0x00002000
+# define BS0 0x00000000
+# define BS1 0x00002000
+#define FFDLY 0x00008000
+#define FF0 0x00000000
+#define FF1 0x00008000
+#endif
+#define VTDLY 0x00004000
+#define VT0 0x00000000
+#define VT1 0x00004000
+#define PAGEOUT 0x00010000 /* SUNOS specific */
+#define WRAP 0x00020000 /* SUNOS specific */
+
+#ifdef __USE_MISC
+# define XTABS 0x00001800
+#endif
+
+/* c_cflag bit meaning */
+#ifdef __USE_MISC
+# define CBAUD 0x0000100f
+#endif
+#define B0 0x00000000 /* hang up */
+#define B50 0x00000001
+#define B75 0x00000002
+#define B110 0x00000003
+#define B134 0x00000004
+#define B150 0x00000005
+#define B200 0x00000006
+#define B300 0x00000007
+#define B600 0x00000008
+#define B1200 0x00000009
+#define B1800 0x0000000a
+#define B2400 0x0000000b
+#define B4800 0x0000000c
+#define B9600 0x0000000d
+#define B19200 0x0000000e
+#define B38400 0x0000000f
+#ifdef __USE_MISC
+# define EXTA B19200
+# define EXTB B38400
+#endif
+#define CSIZE 0x00000030
+#define CS5 0x00000000
+#define CS6 0x00000010
+#define CS7 0x00000020
+#define CS8 0x00000030
+#define CSTOPB 0x00000040
+#define CREAD 0x00000080
+#define PARENB 0x00000100
+#define PARODD 0x00000200
+#define HUPCL 0x00000400
+#define CLOCAL 0x00000800
+#ifdef __USE_MISC
+# define CBAUDEX 0x00001000
+#endif
+#define B57600 0x00001001
+#define B115200 0x00001002
+#define B230400 0x00001003
+#define B460800 0x00001004
+#define B76800 0x00001005
+#define B153600 0x00001006
+#define B307200 0x00001007
+#define B614400 0x00001008
+#define B921600 0x00001009
+#define B500000 0x0000100a
+#define B576000 0x0000100b
+#define B1000000 0x0000100c
+#define B1152000 0x0000100d
+#define B1500000 0x0000100e
+#define B2000000 0x0000100f
+#define __MAX_BAUD B2000000
+
+#ifdef __USE_MISC
+# define CIBAUD 0x100f0000 /* input baud rate (not used) */
+# define CMSPAR 0x40000000 /* mark or space (stick) parity */
+# define CRTSCTS 0x80000000 /* flow control */
+#endif
+
+/* c_lflag bits */
+#define ISIG 0x00000001
+#define ICANON 0x00000002
+#if defined __USE_MISC || defined __USE_XOPEN
+# define XCASE 0x00000004
+#endif
+#define ECHO 0x00000008
+#define ECHOE 0x00000010
+#define ECHOK 0x00000020
+#define ECHONL 0x00000040
+#define NOFLSH 0x00000080
+#define TOSTOP 0x00000100
+#ifdef __USE_MISC
+# define ECHOCTL 0x00000200
+# define ECHOPRT 0x00000400
+# define ECHOKE 0x00000800
+# define DEFECHO 0x00001000 /* SUNOS thing, what is it? */
+# define FLUSHO 0x00002000
+# define PENDIN 0x00004000
+#endif
+#define IEXTEN 0x00008000
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h
new file mode 100644
index 000000000..b0dd1bd89
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h
@@ -0,0 +1,66 @@
+/* bits/typesizes.h -- underlying types for *_t. Linux/SPARC version.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_TYPES_H
+# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef _BITS_TYPESIZES_H
+#define _BITS_TYPESIZES_H 1
+
+/* See <bits/types.h> for the meaning of these macros. This file exists so
+ that <bits/types.h> need not vary across different GNU platforms. */
+
+#define __DEV_T_TYPE __UQUAD_TYPE
+#define __UID_T_TYPE __U32_TYPE
+#define __GID_T_TYPE __U32_TYPE
+#define __INO_T_TYPE __ULONGWORD_TYPE
+#define __INO64_T_TYPE __UQUAD_TYPE
+#define __MODE_T_TYPE __U32_TYPE
+#define __NLINK_T_TYPE __U32_TYPE
+#define __OFF_T_TYPE __SLONGWORD_TYPE
+#define __OFF64_T_TYPE __SQUAD_TYPE
+#define __PID_T_TYPE __S32_TYPE
+#define __RLIM_T_TYPE __ULONGWORD_TYPE
+#define __RLIM64_T_TYPE __UQUAD_TYPE
+#define __BLKCNT_T_TYPE __SLONGWORD_TYPE
+#define __BLKCNT64_T_TYPE __SQUAD_TYPE
+#define __FSBLKCNT_T_TYPE __ULONGWORD_TYPE
+#define __FSBLKCNT64_T_TYPE __UQUAD_TYPE
+#define __FSFILCNT_T_TYPE __ULONGWORD_TYPE
+#define __FSFILCNT64_T_TYPE __UQUAD_TYPE
+#define __ID_T_TYPE __U32_TYPE
+#define __CLOCK_T_TYPE __SLONGWORD_TYPE
+#define __TIME_T_TYPE __SLONGWORD_TYPE
+#define __USECONDS_T_TYPE __U32_TYPE
+#define __SUSECONDS_T_TYPE __S32_TYPE
+#define __DADDR_T_TYPE __S32_TYPE
+#define __SWBLK_T_TYPE __SLONGWORD_TYPE
+#define __KEY_T_TYPE __S32_TYPE
+#define __CLOCKID_T_TYPE __S32_TYPE
+#define __TIMER_T_TYPE void *
+#define __BLKSIZE_T_TYPE __SLONGWORD_TYPE
+#define __FSID_T_TYPE struct { int __val[2]; }
+#define __SSIZE_T_TYPE __SWORD_TYPE
+
+/* Number of descriptors that can fit in an `fd_set'. */
+#define __FD_SETSIZE 1024
+
+
+#endif /* bits/typesizes.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h
new file mode 100644
index 000000000..2d958d29e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h
@@ -0,0 +1,20 @@
+/* Determine the wordsize from the preprocessor defines. */
+
+#if defined __arch64__ || defined __sparcv9
+# define __WORDSIZE 64
+#else
+# define __WORDSIZE 32
+#endif
+
+#if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL
+
+# if __WORDSIZE == 32
+/* Signal that in 32bit ABI we didn't used to have a `long double'.
+ The changes all the `long double' function variants to be redirects
+ to the double functions. */
+# define __LONG_DOUBLE_MATH_OPTIONAL 1
+# ifndef __LONG_DOUBLE_128__
+# define __NO_LONG_DOUBLE_MATH 1
+# endif
+# endif
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/dl-cache.h b/libc/sysdeps/unix/sysv/linux/sparc/dl-cache.h
new file mode 100644
index 000000000..df134b7e6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/dl-cache.h
@@ -0,0 +1,39 @@
+/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define add_system_dir(dir) \
+ do \
+ { \
+ size_t len = strlen (dir); \
+ char path[len + 3]; \
+ memcpy (path, dir, len + 1); \
+ if (len >= 6 && ! memcmp (path + len - 6, "/lib64", 6)) \
+ { \
+ len -= 2; \
+ path[len] = '\0'; \
+ } \
+ add_dir (path); \
+ if (len >= 4 && ! memcmp (path + len - 4, "/lib", 4)) \
+ { \
+ memcpy (path + len, "64", 3); \
+ add_dir (path); \
+ } \
+ } while (0)
+
+#include <sysdeps/generic/dl-cache.h>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/fork.S b/libc/sysdeps/unix/sysv/linux/sparc/fork.S
new file mode 100644
index 000000000..2459b8c8c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/fork.S
@@ -0,0 +1,30 @@
+/* Copyright (C) 1997, 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+PSEUDO (__libc_fork, fork, 0)
+ sub %o1, 1, %o1
+ retl
+ and %o0, %o1, %o0
+PSEUDO_END (__libc_fork)
+
+weak_alias (__libc_fork, __fork)
+libc_hidden_def (__fork)
+weak_alias (__libc_fork, fork)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/getsysstats.c b/libc/sysdeps/unix/sysv/linux/sparc/getsysstats.c
new file mode 100644
index 000000000..f064b372f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/getsysstats.c
@@ -0,0 +1,55 @@
+/* Determine various system internal values, Linux/Sparc version.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Schwab <schwab@suse.de> and
+ Jakub Jelinek <jj@ultra.linux.cz>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* We need to define a special parser for /proc/cpuinfo. */
+#define GET_NPROCS_PARSER(FP, BUFFER, RESULT) \
+ do \
+ { \
+ (RESULT) = 0; \
+ /* Find the line that contains the information about the number of \
+ active cpus. We don't have to fear extremely long lines since \
+ the kernel will not generate them. 8192 bytes are really \
+ enough. */ \
+ while (fgets_unlocked (BUFFER, sizeof (BUFFER), FP) != NULL) \
+ if (sscanf (BUFFER, "ncpus active : %d", &(RESULT)) == 1) \
+ break; \
+ } \
+ while (0)
+
+
+/* On the Sparc we can distinguish between the number of configured and
+ active cpus. */
+#define GET_NPROCS_CONF_PARSER(FP, BUFFER, RESULT) \
+ do \
+ { \
+ (RESULT) = 0; \
+ /* Find the line that contains the information about the number of \
+ probed cpus. We don't have to fear extremely long lines since \
+ the kernel will not generate them. 8192 bytes are really \
+ enough. */ \
+ while (fgets_unlocked ((BUFFER), sizeof (BUFFER), (FP)) != NULL) \
+ if (sscanf (buffer, "ncpus probed : %d", &(RESULT)) == 1) \
+ break; \
+ } \
+ while (0)
+
+#include <sysdeps/unix/sysv/linux/getsysstats.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/kernel_termios.h b/libc/sysdeps/unix/sysv/linux/sparc/kernel_termios.h
new file mode 100644
index 000000000..e66d53a18
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/kernel_termios.h
@@ -0,0 +1,38 @@
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _KERNEL_TERMIOS_H
+#define _KERNEL_TERMIOS_H 1
+/* The following corresponds to the values from the Linux 2.1.20 kernel. */
+
+/* We need the definition of tcflag_t, cc_t, and speed_t. */
+#include <termios.h>
+
+#define __KERNEL_NCCS 17
+
+struct __kernel_termios
+ {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[__KERNEL_NCCS]; /* control characters */
+ };
+
+#endif /* kernel_termios.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/ldd-rewrite.sed b/libc/sysdeps/unix/sysv/linux/sparc/ldd-rewrite.sed
new file mode 100644
index 000000000..7dc2698fa
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/ldd-rewrite.sed
@@ -0,0 +1,3 @@
+/LD_TRACE_LOADED_OBJECTS=1/a\
+add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out"
+s_^\(RTLDLIST=\)\(.*lib\)\(\|64\)\(/[^/]*\.so\.[0-9.]*\)[ ]*$_\1"\2\4 \264\4"_
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/readelflib.c b/libc/sysdeps/unix/sysv/linux/sparc/readelflib.c
new file mode 100644
index 000000000..e12fbc782
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/readelflib.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 1999, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
+ Jakub Jelinek <jakub@redhat.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+int process_elf32_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+int process_elf64_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+
+/* Returns 0 if everything is ok, != 0 in case of error. */
+int
+process_elf_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname, void *file_contents,
+ size_t file_length)
+{
+ ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
+ int ret;
+
+ if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+ return process_elf32_file (file_name, lib, flag, osversion, soname,
+ file_contents, file_length);
+ else
+ {
+ ret = process_elf64_file (file_name, lib, flag, osversion, soname,
+ file_contents, file_length);
+ /* Sparc 64bit libraries are always libc.so.6+. */
+ if (!ret)
+ *flag = FLAG_SPARC_LIB64|FLAG_ELF_LIBC6;
+ return ret;
+ }
+}
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf32_file
+#define __ELF_NATIVE_CLASS 32
+#include "elf/readelflib.c"
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf64_file
+#define __ELF_NATIVE_CLASS 64
+#include "elf/readelflib.c"
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/rt-sysdep.c b/libc/sysdeps/unix/sysv/linux/sparc/rt-sysdep.c
new file mode 100644
index 000000000..3ff55952e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/rt-sysdep.c
@@ -0,0 +1 @@
+#include <sysdep.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/Implies b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/Implies
new file mode 100644
index 000000000..efda9d27c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/Implies
@@ -0,0 +1,3 @@
+# These supply the ABI compatibility for when long double was double.
+ieee754/ldbl-64-128
+ieee754/ldbl-opt
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile
new file mode 100644
index 000000000..cd1b3fb79
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile
@@ -0,0 +1,21 @@
+asm-CPPFLAGS = -D__ASSEMBLY__
+ASFLAGS-.os += -fPIC
+LD += -melf32_sparc
+
+# When I get this to work, this is the right thing
+ifeq ($(subdir),elf)
+CFLAGS-rtld.c += -mcpu=v8
+#rtld-routines += dl-sysdepsparc
+sysdep-others += lddlibc4
+install-bin += lddlibc4
+endif # elf
+
+ifeq ($(subdir),math)
+# These 2 routines are normally in libgcc{.a,_s.so.1}.
+# However, sparc32 -mlong-double-128 libgcc relies on
+# glibc providing _Q_* routines and without these files
+# glibc relies on __multc3/__divtc3 only provided
+# by libgcc if configured with -mlong-double-128.
+# Provide these routines here as well.
+libm-routines += multc3 divtc3
+endif # math
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/Versions b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/Versions
new file mode 100644
index 000000000..c585af360
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/Versions
@@ -0,0 +1,23 @@
+libc {
+ GLIBC_2.0 {
+ # Exception handling support functions from libgcc
+ __register_frame; __register_frame_table; __deregister_frame;
+ __frame_state_for; __register_frame_info_table;
+ }
+ GLIBC_2.2 {
+ # functions used in other libraries
+ __xstat64; __fxstat64; __lxstat64;
+
+ # g*
+ glob64;
+
+ # r*
+ readdir64; readdir64_r;
+
+ # s*
+ scandir64;
+ }
+ GLIBC_2.3.3 {
+ posix_fadvise64; posix_fallocate64;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/brk.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/brk.c
new file mode 100644
index 000000000..bc0735994
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/brk.c
@@ -0,0 +1,55 @@
+/* brk system call for Linux/SPARC.
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx)
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sysdep.h>
+
+/* This must be initialized data because commons can't have aliases. */
+void *__curbrk = 0;
+
+/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt
+ to work around different old braindamage in the old Linux ELF dynamic
+ linker. */
+weak_alias (__curbrk, ___brk_addr)
+
+int
+__brk (void *addr)
+{
+ void *newbrk;
+
+ {
+ register void *o0 __asm__("%o0") = addr;
+ register int g1 __asm__("%g1") = __NR_brk;
+ __asm ("t 0x10" : "=r"(o0) : "r"(g1), "0"(o0) : "cc");
+ newbrk = o0;
+ }
+
+ __curbrk = newbrk;
+
+ if (newbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+weak_alias (__brk, brk)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/chown.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/chown.c
new file mode 100644
index 000000000..374131695
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/chown.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/sh/chown.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
new file mode 100644
index 000000000..f91fc4f62
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
@@ -0,0 +1,109 @@
+/* Copyright (C) 1996, 1997, 1998, 2000, 2003, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@tamu.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* clone() is even more special than fork() as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#include <asm/errno.h>
+#include <asm/unistd.h>
+#include <tcb-offsets.h>
+#include <sysdep.h>
+
+#define CLONE_VM 0x00000100
+#define CLONE_THREAD 0x00010000
+
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+ pid_t *ptid, void *tls, pid_t *ctid); */
+
+ .text
+ENTRY (__clone)
+ save %sp,-96,%sp
+ cfi_def_cfa_register(%fp)
+ cfi_window_save
+ cfi_register(%o7, %i7)
+
+ /* sanity check arguments */
+ orcc %i0,%g0,%g2
+ be .Lerror
+ orcc %i1,%g0,%o1
+ be .Lerror
+ mov %i2,%o0
+
+ /* The child_stack is the top of the stack, allocate one
+ whole stack frame from that as this is what the kernel
+ expects. */
+ sub %o1, 96, %o1
+ mov %i3, %g3
+ mov %i2, %g4
+
+ /* ptid */
+ mov %i4,%o2
+ /* tls */
+ mov %i5,%o3
+ /* ctid */
+ ld [%fp+92],%o4
+
+ /* Do the system call */
+ set __NR_clone,%g1
+ ta 0x10
+ bcs .Lerror
+ tst %o1
+ bne __thread_start
+ nop
+ jmpl %i7 + 8, %g0
+ restore %o0,%g0,%o0
+
+.Lerror:
+ call __errno_location
+ or %g0,EINVAL,%i0
+ st %i0,[%o0]
+ jmpl %i7 + 8, %g0
+ restore %g0,-1,%o0
+END(__clone)
+
+ .type __thread_start,@function
+__thread_start:
+ cfi_startproc
+
+#ifdef RESET_PID
+ sethi %hi(CLONE_THREAD), %l0
+ andcc %g4, %l0, %g0
+ bne 1f
+ andcc %g4, CLONE_VM, %g0
+ bne,a 2f
+ mov -1,%o0
+ set __NR_getpid,%g1
+ ta 0x10
+2:
+ st %o0,[%g7 + PID]
+ st %o0,[%g7 + TID]
+1:
+#endif
+ mov %g0, %fp /* terminate backtrace */
+ call %g2
+ mov %g3,%o0
+ call _exit,0
+ nop
+
+ cfi_endproc
+
+ .size __thread_start, .-__thread_start
+
+weak_alias (__clone, clone)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fchown.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fchown.c
new file mode 100644
index 000000000..3a69ecc9e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fchown.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fchown.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c
new file mode 100644
index 000000000..7ba5bf44a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/sh/fchownat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fcntl.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fcntl.c
new file mode 100644
index 000000000..ea951bc4f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fcntl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fcntl.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Implies b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Implies
new file mode 100644
index 000000000..dbcd1e9e6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Implies
@@ -0,0 +1,2 @@
+# We must list this here to move it ahead of the ldbl-opt code.
+sparc/sparc32/fpu
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fxstat.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fxstat.c
new file mode 100644
index 000000000..4f219f0b9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fxstat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fxstat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fxstatat.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fxstatat.c
new file mode 100644
index 000000000..0f8b3135d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/fxstatat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fxstatat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getdents64.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getdents64.c
new file mode 100644
index 000000000..0c75fb5a0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getdents64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getdents64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getegid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getegid.c
new file mode 100644
index 000000000..37b4b4a53
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getegid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getegid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/geteuid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/geteuid.c
new file mode 100644
index 000000000..ebcb555b5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/geteuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/geteuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getgid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getgid.c
new file mode 100644
index 000000000..0a4d6061f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getgroups.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getgroups.c
new file mode 100644
index 000000000..102ea24e1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getgroups.c
@@ -0,0 +1,2 @@
+/* We also have to rewrite the kernel gid_t to the user land type. */
+#include <sysdeps/unix/sysv/linux/i386/getgroups.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c
new file mode 100644
index 000000000..4760daff2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getpagesize.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1997, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <sys/param.h>
+#include <ldsodefs.h>
+#include <sysdep.h>
+
+/* Return the system page size. This value will either be 4k or 8k depending
+ on whether or not we are running on Sparc v9 machine. */
+
+/* If we are not a static program, this value is collected from the system
+ via the AT_PAGESZ auxiliary argument. If we are a static program, we
+ use the getpagesize system call. */
+
+int
+__getpagesize ()
+{
+ int ret = GLRO(dl_pagesize);
+ if (ret == 0)
+ {
+ INTERNAL_SYSCALL_DECL (err);
+ ret = INTERNAL_SYSCALL (getpagesize, err, 0);
+#ifndef SHARED
+ GLRO(dl_pagesize) = ret;
+#endif
+ }
+ return ret;
+}
+libc_hidden_def (__getpagesize)
+weak_alias (__getpagesize, getpagesize)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getuid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getuid.c
new file mode 100644
index 000000000..d682c79a4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/getuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c
new file mode 100644
index 000000000..82a9a296a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
new file mode 100644
index 000000000..a0da019c5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
@@ -0,0 +1,32 @@
+/* Definition of `struct stat' used in the kernel */
+struct kernel_stat
+ {
+ unsigned short int st_dev;
+ unsigned long int st_ino;
+ unsigned short int st_mode;
+ short int st_nlink;
+ unsigned short int st_uid;
+ unsigned short int st_gid;
+ unsigned short int st_rdev;
+ long int st_size;
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+ long int st_blksize;
+ long int st_blocks;
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+ };
+
+#define _HAVE___UNUSED4
+#define _HAVE___UNUSED5
+
+#define _HAVE_STAT___UNUSED4
+#define _HAVE_STAT___UNUSED5
+#define _HAVE_STAT___PAD1
+#define _HAVE_STAT___PAD2
+#define _HAVE_STAT64___UNUSED4
+#define _HAVE_STAT64___UNUSED5
+#define _HAVE_STAT64___PAD2
+#define _HAVE_STAT_NSEC
+#define _HAVE_STAT64_NSEC
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/lchown.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/lchown.c
new file mode 100644
index 000000000..c89de99ba
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/lchown.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/lchown.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/lockf64.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/lockf64.c
new file mode 100644
index 000000000..a88f5a784
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/lockf64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/lockf64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/lxstat.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/lxstat.c
new file mode 100644
index 000000000..2371cd971
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/lxstat.c
@@ -0,0 +1,2 @@
+#include <sysdeps/unix/sysv/linux/i386/lxstat.c>
+
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/msgctl.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/msgctl.c
new file mode 100644
index 000000000..9f9b8431a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/msgctl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/msgctl.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/nldbl-abi.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/nldbl-abi.h
new file mode 100644
index 000000000..bd985cc59
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/nldbl-abi.h
@@ -0,0 +1,8 @@
+/* ABI version for long double switch.
+ This is used by the Versions and math_ldbl_opt.h files in
+ sysdeps/ieee754/ldbl-opt/. It gives the ABI version where
+ long double == double was replaced with proper long double
+ for libm *l functions and libc functions using long double. */
+
+#define NLDBL_VERSION GLIBC_2.4
+#define LONG_DOUBLE_COMPAT_VERSION GLIBC_2_4
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S
new file mode 100644
index 000000000..dbe087261
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S
@@ -0,0 +1,40 @@
+/* Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ .globl __syscall_error
+ENTRY(__libc_pipe)
+ mov %o0, %o2 /* Save PIPEDES. */
+ mov SYS_ify(pipe),%g1
+ ta 0x10
+ bcc 1f
+ mov %o7, %g1
+ call __syscall_error
+ mov %g1, %o7
+1: st %o0, [%o2] /* PIPEDES[0] = %o0; */
+ st %o1, [%o2 + 4] /* PIPEDES[1] = %o1; */
+ retl
+ clr %o0
+END(__libc_pipe)
+
+weak_alias (__libc_pipe, __pipe)
+libc_hidden_def (__pipe)
+weak_alias (__libc_pipe, pipe)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h
new file mode 100644
index 000000000..1e22e8cce
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h
@@ -0,0 +1,26 @@
+/* Low-level statistical profiling support function. Linux/SPARC version.
+ Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+
+void
+profil_counter (int signo, struct sigcontext *si)
+{
+ profil_count ((void *) si->si_regs.pc);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64.c
new file mode 100644
index 000000000..2ea26dd40
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/readdir64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64_r.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64_r.c
new file mode 100644
index 000000000..9f54f897e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64_r.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/readdir64_r.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h
new file mode 100644
index 000000000..2d3fa4277
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h
@@ -0,0 +1,336 @@
+/* Dump registers.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/uio.h>
+#include <stdio-common/_itoa.h>
+
+/* We will print the register dump in this format:
+
+ PSR: XXXXXXXX PC: XXXXXXXX NPC: XXXXXXXX Y: XXXXXXXX
+ g0: 00000000 g1: XXXXXXXX g2: XXXXXXXX g3: XXXXXXXX
+ g4: XXXXXXXX g5: XXXXXXXX g6: XXXXXXXX g7: XXXXXXXX
+ o0: XXXXXXXX o1: XXXXXXXX o2: XXXXXXXX o3: XXXXXXXX
+ o4: XXXXXXXX o5: XXXXXXXX sp: XXXXXXXX o7: XXXXXXXX
+ l0: XXXXXXXX l1: XXXXXXXX l2: XXXXXXXX l3: XXXXXXXX
+ l4: XXXXXXXX l5: XXXXXXXX l6: XXXXXXXX l7: XXXXXXXX
+ i0: XXXXXXXX i1: XXXXXXXX i2: XXXXXXXX i3: XXXXXXXX
+ i4: XXXXXXXX i5: XXXXXXXX fp: XXXXXXXX i7: XXXXXXXX
+
+ followed on sun4, sun4c, sun4d, sun4m by:
+
+ Old mask: XXXXXXXX FSR: XXXXXXXX FPQ: XXXXXXXX
+ f0: XXXXXXXXXXXXXXXX f2: XXXXXXXXXXXXXXXX f4: XXXXXXXXXXXXXXXX
+ f6: XXXXXXXXXXXXXXXX f8: XXXXXXXXXXXXXXXX f10: XXXXXXXXXXXXXXXX
+ f12: XXXXXXXXXXXXXXXX f14: XXXXXXXXXXXXXXXX f16: XXXXXXXXXXXXXXXX
+ f18: XXXXXXXXXXXXXXXX f20: XXXXXXXXXXXXXXXX f22: XXXXXXXXXXXXXXXX
+ f24: XXXXXXXXXXXXXXXX f26: XXXXXXXXXXXXXXXX f28: XXXXXXXXXXXXXXXX
+ f30: XXXXXXXXXXXXXXXX
+
+ and on sun4u by:
+
+ Old mask: XXXXXXXX XFSR: XXXXXXXXXXXXXXXX GSR: XX FPRS: X
+ f0: XXXXXXXXXXXXXXXX f2: XXXXXXXXXXXXXXXX f4: XXXXXXXXXXXXXXXX
+ f6: XXXXXXXXXXXXXXXX f8: XXXXXXXXXXXXXXXX f10: XXXXXXXXXXXXXXXX
+ f12: XXXXXXXXXXXXXXXX f14: XXXXXXXXXXXXXXXX f16: XXXXXXXXXXXXXXXX
+ f18: XXXXXXXXXXXXXXXX f20: XXXXXXXXXXXXXXXX f22: XXXXXXXXXXXXXXXX
+ f24: XXXXXXXXXXXXXXXX f26: XXXXXXXXXXXXXXXX f28: XXXXXXXXXXXXXXXX
+ f30: XXXXXXXXXXXXXXXX f32: XXXXXXXXXXXXXXXX f34: XXXXXXXXXXXXXXXX
+ f36: XXXXXXXXXXXXXXXX f38: XXXXXXXXXXXXXXXX f40: XXXXXXXXXXXXXXXX
+ f42: XXXXXXXXXXXXXXXX f44: XXXXXXXXXXXXXXXX f46: XXXXXXXXXXXXXXXX
+ f48: XXXXXXXXXXXXXXXX f50: XXXXXXXXXXXXXXXX f52: XXXXXXXXXXXXXXXX
+ f54: XXXXXXXXXXXXXXXX f56: XXXXXXXXXXXXXXXX f58: XXXXXXXXXXXXXXXX
+ f60: XXXXXXXXXXXXXXXX f62: XXXXXXXXXXXXXXXX
+
+ */
+
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
+{
+ char *cp = _itoa_word (value, buf + len, 16, 0);
+ while (cp > buf)
+ *--cp = '0';
+}
+
+struct __siginfo_sparc32_fpu
+{
+ unsigned int si_float_regs[32];
+ unsigned int si_fsr;
+ unsigned int si_fpq;
+};
+struct __siginfo_sparc64_fpu
+{
+ unsigned int si_float_regs[64];
+ unsigned int si_xfsr;
+ unsigned int si_fsr;
+ unsigned int _pad1;
+ unsigned int si_gsr;
+ unsigned int _pad2;
+ unsigned int si_fprs;
+};
+
+static void
+register_dump (int fd, SIGCONTEXT ctx)
+{
+ char regs[36][8];
+ char fregs[68][8];
+ struct iovec iov[150];
+ size_t nr = 0;
+ int i;
+ unsigned int *r = (unsigned int *)
+ ctx->si_regs.u_regs[14];
+
+#define ADD_STRING(str) \
+ iov[nr].iov_base = (char *) str; \
+ iov[nr].iov_len = strlen (str); \
+ ++nr
+#define ADD_MEM(str, len) \
+ iov[nr].iov_base = str; \
+ iov[nr].iov_len = len; \
+ ++nr
+
+ /* Generate strings of register contents. */
+ hexvalue (ctx->si_regs.psr, regs[0], 8);
+ hexvalue (ctx->si_regs.pc, regs[1], 8);
+ hexvalue (ctx->si_regs.npc, regs[2], 8);
+ hexvalue (ctx->si_regs.y, regs[3], 8);
+ for (i = 1; i <= 15; i++)
+ hexvalue (ctx->si_regs.u_regs[i], regs[3+i], 8);
+ for (i = 0; i <= 15; i++)
+ hexvalue (r[i], regs[19+i], 8);
+ hexvalue (ctx->si_mask, regs[35], 8);
+
+ /* Generate the output. */
+ ADD_STRING ("Register dump:\n\n PSR: ");
+ ADD_MEM (regs[0], 8);
+ ADD_STRING (" PC: ");
+ ADD_MEM (regs[1], 8);
+ ADD_STRING (" NPC: ");
+ ADD_MEM (regs[2], 8);
+ ADD_STRING (" Y: ");
+ ADD_MEM (regs[3], 8);
+ ADD_STRING ("\n g0: 00000000 g1: ");
+ ADD_MEM (regs[4], 8);
+ ADD_STRING (" g2: ");
+ ADD_MEM (regs[5], 8);
+ ADD_STRING (" g3: ");
+ ADD_MEM (regs[6], 8);
+ ADD_STRING ("\n g4: ");
+ ADD_MEM (regs[7], 8);
+ ADD_STRING (" g5: ");
+ ADD_MEM (regs[8], 8);
+ ADD_STRING (" g6: ");
+ ADD_MEM (regs[9], 8);
+ ADD_STRING (" g7: ");
+ ADD_MEM (regs[10], 8);
+ ADD_STRING ("\n o0: ");
+ ADD_MEM (regs[11], 8);
+ ADD_STRING (" o1: ");
+ ADD_MEM (regs[12], 8);
+ ADD_STRING (" o2: ");
+ ADD_MEM (regs[13], 8);
+ ADD_STRING (" o3: ");
+ ADD_MEM (regs[14], 8);
+ ADD_STRING ("\n o4: ");
+ ADD_MEM (regs[15], 8);
+ ADD_STRING (" o5: ");
+ ADD_MEM (regs[16], 8);
+ ADD_STRING (" sp: ");
+ ADD_MEM (regs[17], 8);
+ ADD_STRING (" o7: ");
+ ADD_MEM (regs[18], 8);
+ ADD_STRING ("\n l0: ");
+ ADD_MEM (regs[19], 8);
+ ADD_STRING (" l1: ");
+ ADD_MEM (regs[20], 8);
+ ADD_STRING (" l2: ");
+ ADD_MEM (regs[21], 8);
+ ADD_STRING (" l3: ");
+ ADD_MEM (regs[22], 8);
+ ADD_STRING ("\n l4: ");
+ ADD_MEM (regs[23], 8);
+ ADD_STRING (" l5: ");
+ ADD_MEM (regs[24], 8);
+ ADD_STRING (" l6: ");
+ ADD_MEM (regs[25], 8);
+ ADD_STRING (" l7: ");
+ ADD_MEM (regs[26], 8);
+ ADD_STRING ("\n i0: ");
+ ADD_MEM (regs[27], 8);
+ ADD_STRING (" i1: ");
+ ADD_MEM (regs[28], 8);
+ ADD_STRING (" i2: ");
+ ADD_MEM (regs[29], 8);
+ ADD_STRING (" i3: ");
+ ADD_MEM (regs[30], 8);
+ ADD_STRING ("\n i4: ");
+ ADD_MEM (regs[31], 8);
+ ADD_STRING (" i5: ");
+ ADD_MEM (regs[32], 8);
+ ADD_STRING (" fp: ");
+ ADD_MEM (regs[33], 8);
+ ADD_STRING (" i7: ");
+ ADD_MEM (regs[34], 8);
+ ADD_STRING ("\n\n Old mask: ");
+ ADD_MEM (regs[35], 8);
+
+ if ((ctx->si_regs.psr & 0xff000000) == 0xff000000)
+ {
+ struct __siginfo_sparc64_fpu *f;
+
+ f = *(struct __siginfo_sparc64_fpu **) (ctx + 1);
+ if (f != NULL)
+ {
+ for (i = 0; i < 64; i++)
+ hexvalue (f->si_float_regs[i], fregs[i], 8);
+ hexvalue (f->si_xfsr, fregs[64], 8);
+ hexvalue (f->si_fsr, fregs[65], 8);
+ hexvalue (f->si_gsr, fregs[66], 2);
+ hexvalue (f->si_fprs, fregs[67], 1);
+ ADD_STRING (" XFSR: ");
+ ADD_MEM (fregs[64], 8);
+ ADD_MEM (fregs[65], 8);
+ ADD_STRING (" GSR: ");
+ ADD_MEM (fregs[66], 2);
+ ADD_STRING (" FPRS: ");
+ ADD_MEM (fregs[67], 1);
+ ADD_STRING ("\n f0: ");
+ ADD_MEM (fregs[0], 16);
+ ADD_STRING (" f2: ");
+ ADD_MEM (fregs[2], 16);
+ ADD_STRING (" f4: ");
+ ADD_MEM (fregs[4], 16);
+ ADD_STRING ("\n f6: ");
+ ADD_MEM (fregs[6], 16);
+ ADD_STRING (" f8: ");
+ ADD_MEM (fregs[8], 16);
+ ADD_STRING (" f10: ");
+ ADD_MEM (fregs[10], 16);
+ ADD_STRING ("\n f12: ");
+ ADD_MEM (fregs[12], 16);
+ ADD_STRING (" f14: ");
+ ADD_MEM (fregs[14], 16);
+ ADD_STRING (" f16: ");
+ ADD_MEM (fregs[16], 16);
+ ADD_STRING ("\n f18: ");
+ ADD_MEM (fregs[18], 16);
+ ADD_STRING (" f20: ");
+ ADD_MEM (fregs[20], 16);
+ ADD_STRING (" f22: ");
+ ADD_MEM (fregs[22], 16);
+ ADD_STRING ("\n f24: ");
+ ADD_MEM (fregs[24], 16);
+ ADD_STRING (" f26: ");
+ ADD_MEM (fregs[26], 16);
+ ADD_STRING (" f28: ");
+ ADD_MEM (fregs[28], 16);
+ ADD_STRING ("\n f30: ");
+ ADD_MEM (fregs[30], 16);
+ ADD_STRING (" f32: ");
+ ADD_MEM (fregs[32], 16);
+ ADD_STRING (" f34: ");
+ ADD_MEM (fregs[34], 16);
+ ADD_STRING ("\n f36: ");
+ ADD_MEM (fregs[36], 16);
+ ADD_STRING (" f38: ");
+ ADD_MEM (fregs[38], 16);
+ ADD_STRING (" f40: ");
+ ADD_MEM (fregs[40], 16);
+ ADD_STRING ("\n f42: ");
+ ADD_MEM (fregs[42], 16);
+ ADD_STRING (" f44: ");
+ ADD_MEM (fregs[44], 16);
+ ADD_STRING (" f46: ");
+ ADD_MEM (fregs[46], 16);
+ ADD_STRING ("\n f48: ");
+ ADD_MEM (fregs[48], 16);
+ ADD_STRING (" f50: ");
+ ADD_MEM (fregs[50], 16);
+ ADD_STRING (" f52: ");
+ ADD_MEM (fregs[52], 16);
+ ADD_STRING ("\n f54: ");
+ ADD_MEM (fregs[54], 16);
+ ADD_STRING (" f56: ");
+ ADD_MEM (fregs[56], 16);
+ ADD_STRING (" f58: ");
+ ADD_MEM (fregs[58], 16);
+ ADD_STRING ("\n f60: ");
+ ADD_MEM (fregs[60], 16);
+ ADD_STRING (" f62: ");
+ ADD_MEM (fregs[62], 16);
+ }
+ }
+ else
+ {
+ struct __siginfo_sparc32_fpu *f;
+
+ f = *(struct __siginfo_sparc32_fpu **) (ctx + 1);
+ if (f != NULL)
+ {
+ for (i = 0; i < 32; i++)
+ hexvalue (f->si_float_regs[i], fregs[i], 8);
+ hexvalue (f->si_fsr, fregs[64], 8);
+ hexvalue (f->si_fpq, fregs[65], 8);
+ ADD_STRING (" FSR: ");
+ ADD_MEM (fregs[64], 8);
+ ADD_STRING (" FPQ: ");
+ ADD_MEM (fregs[65], 8);
+ ADD_STRING ("\n f0: ");
+ ADD_MEM (fregs[0], 16);
+ ADD_STRING (" f2: ");
+ ADD_MEM (fregs[2], 16);
+ ADD_STRING (" f4: ");
+ ADD_MEM (fregs[4], 16);
+ ADD_STRING ("\n f6: ");
+ ADD_MEM (fregs[6], 16);
+ ADD_STRING (" f8: ");
+ ADD_MEM (fregs[8], 16);
+ ADD_STRING (" f10: ");
+ ADD_MEM (fregs[10], 16);
+ ADD_STRING ("\n f12: ");
+ ADD_MEM (fregs[12], 16);
+ ADD_STRING (" f14: ");
+ ADD_MEM (fregs[14], 16);
+ ADD_STRING (" f16: ");
+ ADD_MEM (fregs[16], 16);
+ ADD_STRING ("\n f18: ");
+ ADD_MEM (fregs[18], 16);
+ ADD_STRING (" f20: ");
+ ADD_MEM (fregs[20], 16);
+ ADD_STRING (" f22: ");
+ ADD_MEM (fregs[22], 16);
+ ADD_STRING ("\n f24: ");
+ ADD_MEM (fregs[24], 16);
+ ADD_STRING (" f26: ");
+ ADD_MEM (fregs[26], 16);
+ ADD_STRING (" f28: ");
+ ADD_MEM (fregs[28], 16);
+ ADD_STRING ("\n f30: ");
+ ADD_MEM (fregs[30], 16);
+ }
+ }
+
+ ADD_STRING ("\n");
+
+ /* Write the stuff out. */
+ writev (fd, iov, nr);
+}
+
+
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c
new file mode 100644
index 000000000..506fd8877
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/scandir64.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/semctl.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/semctl.c
new file mode 100644
index 000000000..64d47b34c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/semctl.c
@@ -0,0 +1,208 @@
+/* Semctl for architectures where word sized unions are passed indirectly
+ Copyright (C) 1995,1997,1998,2000,2002,2003,2004,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/sem.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <string.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+#include <shlib-compat.h>
+
+struct __old_semid_ds
+{
+ struct __old_ipc_perm sem_perm; /* operation permission struct */
+ __time_t sem_otime; /* last semop() time */
+ __time_t sem_ctime; /* last time changed by semctl() */
+ struct sem *__sembase; /* ptr to first semaphore in array */
+ struct sem_queue *__sem_pending; /* pending operations */
+ struct sem_queue *__sem_pending_last; /* last pending operation */
+ struct sem_undo *__undo; /* ondo requests on this array */
+ unsigned short int sem_nsems; /* number of semaphores in set */
+};
+
+/* Define a `union semun' suitable for Linux here. */
+union semun
+{
+ int val; /* value for SETVAL */
+ struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
+ unsigned short int *array; /* array for GETALL & SETALL */
+ struct seminfo *__buf; /* buffer for IPC_INFO */
+ struct __old_semid_ds *__old_buf;
+};
+
+#include <bp-checks.h>
+#include <bp-semctl.h> /* definition of CHECK_SEMCTL needs union semum */
+
+#ifdef __NR_getuid32
+# if __ASSUME_32BITUIDS == 0
+/* This variable is shared with all files that need to check for 32bit
+ uids. */
+extern int __libc_missing_32bit_uids;
+# endif
+#endif
+
+/* Return identifier for array of NSEMS semaphores associated with
+ KEY. */
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int __old_semctl (int semid, int semnum, int cmd, ...);
+#endif
+int __new_semctl (int semid, int semnum, int cmd, ...);
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+int
+attribute_compat_text_section
+__old_semctl (int semid, int semnum, int cmd, ...)
+{
+ union semun arg;
+ va_list ap;
+
+ /* Get the argument only if required. */
+ arg.buf = NULL;
+ switch (cmd)
+ {
+ case SETVAL: /* arg.val */
+ case GETALL: /* arg.array */
+ case SETALL:
+ case IPC_STAT: /* arg.buf */
+ case IPC_SET:
+ case SEM_STAT:
+ case IPC_INFO: /* arg.__buf */
+ case SEM_INFO:
+ va_start (ap, cmd);
+ arg = va_arg (ap, union semun);
+ va_end (ap);
+ break;
+ }
+
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
+ CHECK_SEMCTL (&arg, semid, cmd));
+}
+compat_symbol (libc, __old_semctl, semctl, GLIBC_2_0);
+#endif
+
+int
+__new_semctl (int semid, int semnum, int cmd, ...)
+{
+ union semun arg;
+ va_list ap;
+
+ /* Get the argument only if required. */
+ arg.buf = NULL;
+ switch (cmd)
+ {
+ case SETVAL: /* arg.val */
+ case GETALL: /* arg.array */
+ case SETALL:
+ case IPC_STAT: /* arg.buf */
+ case IPC_SET:
+ case SEM_STAT:
+ case IPC_INFO: /* arg.__buf */
+ case SEM_INFO:
+ va_start (ap, cmd);
+ arg = va_arg (ap, union semun);
+ va_end (ap);
+ break;
+ }
+
+#if __ASSUME_32BITUIDS > 0
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd | __IPC_64,
+ CHECK_SEMCTL (&arg, semid, cmd | __IPC_64));
+#else
+ switch (cmd) {
+ case SEM_STAT:
+ case IPC_STAT:
+ case IPC_SET:
+ break;
+ default:
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
+ CHECK_SEMCTL (&arg, semid, cmd));
+ }
+
+ {
+ int result;
+ struct __old_semid_ds old;
+ struct semid_ds *buf;
+
+#ifdef __NR_getuid32
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ if (__libc_missing_32bit_uids < 0)
+ {
+ int save_errno = errno;
+
+ /* Test presence of new IPC by testing for getuid32 syscall. */
+ result = INLINE_SYSCALL (getuid32, 0);
+ if (result == -1 && errno == ENOSYS)
+ __libc_missing_32bit_uids = 1;
+ else
+ __libc_missing_32bit_uids = 0;
+ __set_errno(save_errno);
+ }
+ if (__libc_missing_32bit_uids <= 0)
+ {
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd | __IPC_64,
+ CHECK_SEMCTL (&arg, semid, cmd | __IPC_64));
+ return result;
+ }
+ }
+#endif
+
+ buf = arg.buf;
+ arg.__old_buf = &old;
+ if (cmd == IPC_SET)
+ {
+ old.sem_perm.uid = buf->sem_perm.uid;
+ old.sem_perm.gid = buf->sem_perm.gid;
+ old.sem_perm.mode = buf->sem_perm.mode;
+ if (old.sem_perm.uid != buf->sem_perm.uid ||
+ old.sem_perm.gid != buf->sem_perm.gid)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ }
+ result = INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
+ CHECK_SEMCTL (&arg, semid, cmd));
+ if (result != -1 && cmd != IPC_SET)
+ {
+ memset(buf, 0, sizeof(*buf));
+ buf->sem_perm.__key = old.sem_perm.__key;
+ buf->sem_perm.uid = old.sem_perm.uid;
+ buf->sem_perm.gid = old.sem_perm.gid;
+ buf->sem_perm.cuid = old.sem_perm.cuid;
+ buf->sem_perm.cgid = old.sem_perm.cgid;
+ buf->sem_perm.mode = old.sem_perm.mode;
+ buf->sem_perm.__seq = old.sem_perm.__seq;
+ buf->sem_otime = old.sem_otime;
+ buf->sem_ctime = old.sem_ctime;
+ buf->sem_nsems = old.sem_nsems;
+ }
+ return result;
+ }
+#endif
+}
+
+versioned_symbol (libc, __new_semctl, semctl, GLIBC_2_2);
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c
new file mode 100644
index 000000000..2e3a54c89
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setegid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c
new file mode 100644
index 000000000..18e41d08c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/seteuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setfsgid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setfsgid.c
new file mode 100644
index 000000000..088671256
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setfsgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setfsgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setfsuid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setfsuid.c
new file mode 100644
index 000000000..a9f22eb8a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setfsuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setfsuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setgid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setgid.c
new file mode 100644
index 000000000..377021d9e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setgroups.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setgroups.c
new file mode 100644
index 000000000..0e7086278
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setgroups.c
@@ -0,0 +1,2 @@
+/* We also have to rewrite the kernel gid_t to the user land type. */
+#include <sysdeps/unix/sysv/linux/i386/setgroups.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setregid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setregid.c
new file mode 100644
index 000000000..99c57ad20
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setregid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setregid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c
new file mode 100644
index 000000000..daca1a483
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setresgid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c
new file mode 100644
index 000000000..3aeabe9ad
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setresuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setreuid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setreuid.c
new file mode 100644
index 000000000..8ad61226e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setreuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setreuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setuid.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setuid.c
new file mode 100644
index 000000000..de394379b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/setuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setuid.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/shmctl.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/shmctl.c
new file mode 100644
index 000000000..7eac6380d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/shmctl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/shmctl.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
new file mode 100644
index 000000000..3be801a93
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
@@ -0,0 +1,161 @@
+/* POSIX.1 sigaction call for Linux/SPARC.
+ Copyright (C) 1997-2000,2002,2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx), 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <syscall.h>
+#include <sys/signal.h>
+#include <errno.h>
+#include <kernel_sigaction.h>
+#include <sysdep.h>
+
+static void __rt_sigreturn_stub (void);
+static void __sigreturn_stub (void);
+
+/* The variable is shared between all wrappers around signal handling
+ functions which have RT equivalents. */
+int __libc_missing_rt_sigs;
+
+int
+__libc_sigaction (int sig, __const struct sigaction *act,
+ struct sigaction *oact)
+{
+ struct old_kernel_sigaction k_sigact, k_osigact;
+ int ret;
+
+#ifdef __NR_rt_sigaction
+ /* First try the RT signals. */
+ if (!__libc_missing_rt_sigs)
+ {
+ struct kernel_sigaction kact, koact;
+ unsigned long stub = 0;
+ int saved_errno = errno;
+
+ if (act)
+ {
+ kact.k_sa_handler = act->sa_handler;
+ memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
+ if (((kact.sa_flags = act->sa_flags) & SA_SIGINFO) != 0)
+ stub = (unsigned long) &__rt_sigreturn_stub;
+ else
+ stub = (unsigned long) &__sigreturn_stub;
+ stub -= 8;
+ kact.sa_restorer = NULL;
+ }
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ ret = INLINE_SYSCALL (rt_sigaction, 5, sig, act ? &kact : 0,
+ oact ? &koact : 0, stub, _NSIG / 8);
+
+ if (ret >= 0 || errno != ENOSYS)
+ {
+ if (oact && ret >= 0)
+ {
+ oact->sa_handler = koact.k_sa_handler;
+ memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t));
+ oact->sa_flags = koact.sa_flags;
+ oact->sa_restorer = koact.sa_restorer;
+ }
+ return ret;
+ }
+
+ __set_errno (saved_errno);
+ __libc_missing_rt_sigs = 1;
+ }
+#endif
+
+ /* Magic to tell the kernel we are using "new-style" signals, in that
+ the signal table is not kept in userspace. Not the same as the
+ really-new-style rt signals. */
+ sig = -sig;
+
+ if (act)
+ {
+ k_sigact.k_sa_handler = act->sa_handler;
+ k_sigact.sa_mask = act->sa_mask.__val[0];
+ k_sigact.sa_flags = act->sa_flags;
+ k_sigact.sa_restorer = NULL;
+ }
+
+ {
+ register int r_syscallnr __asm__("%g1") = __NR_sigaction;
+ register int r_sig __asm__("%o0") = sig;
+ register struct old_kernel_sigaction *r_act __asm__("%o1");
+ register struct old_kernel_sigaction *r_oact __asm__("%o2");
+
+ r_act = act ? &k_sigact : NULL;
+ r_oact = oact ? &k_osigact : NULL;
+
+ __asm__ __volatile__("t 0x10\n\t"
+ "bcc 1f\n\t"
+ " nop\n\t"
+ "sub %%g0,%%o0,%%o0\n"
+ "1:"
+ : "=r"(r_sig)
+ : "r"(r_syscallnr), "r"(r_act), "r"(r_oact),
+ "0"(r_sig));
+
+ ret = r_sig;
+ }
+
+ if (ret >= 0)
+ {
+ if (oact)
+ {
+ oact->sa_handler = k_osigact.k_sa_handler;
+ oact->sa_mask.__val[0] = k_osigact.sa_mask;
+ oact->sa_flags = k_osigact.sa_flags;
+ oact->sa_restorer = NULL;
+ }
+ return ret;
+ }
+
+ __set_errno (-ret);
+ return -1;
+}
+libc_hidden_def (__libc_sigaction)
+
+#ifdef WRAPPER_INCLUDE
+# include WRAPPER_INCLUDE
+#endif
+
+#ifndef LIBC_SIGACTION
+weak_alias (__libc_sigaction, __sigaction);
+libc_hidden_weak (__sigaction)
+weak_alias (__libc_sigaction, sigaction);
+#endif
+
+static void
+__rt_sigreturn_stub (void)
+{
+ __asm__ ("mov %0, %%g1\n\t"
+ "ta 0x10\n\t"
+ : /* no outputs */
+ : "i" (__NR_rt_sigreturn));
+}
+
+static void
+__sigreturn_stub (void)
+{
+ __asm__ ("mov %0, %%g1\n\t"
+ "ta 0x10\n\t"
+ : /* no outputs */
+ : "i" (__NR_sigreturn));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
new file mode 100644
index 000000000..2c2770d07
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define SIGCONTEXT struct sigcontext *
+#define SIGCONTEXT_EXTRA_ARGS
+#define GET_PC(__ctx) ((void *) ((__ctx)->si_regs.pc))
+#define ADVANCE_STACK_FRAME(__next) \
+ ((void *) (((unsigned *)(__next))+14))
+
+#define GET_STACK(__ctx) ((void *) (__ctx)->si_regs.u_regs[14])
+#define GET_FRAME(__ctx) ADVANCE_STACK_FRAME (GET_STACK(__ctx))
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
new file mode 100644
index 000000000..71a63d5b7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
@@ -0,0 +1,117 @@
+/* Copyright (C) 1997, 1998, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep-cancel.h>
+#include <socketcall.h>
+
+#define P(a, b) P2(a, b)
+#define P2(a, b) a##b
+
+#ifndef NARGS
+#ifdef socket
+#error NARGS not defined
+#endif
+#define NARGS 3
+#endif
+
+ .text
+/* The socket-oriented system calls are handled unusually in Linux.
+ They are all gated through the single `socketcall' system call number.
+ `socketcall' takes two arguments: the first is the subcode, specifying
+ which socket function is being called; and the second is a pointer to
+ the arguments to the specific function.
+
+ The .S files for the other calls just #define socket and #include this. */
+
+#ifndef __socket
+# ifndef NO_WEAK_ALIAS
+# define __socket P(__,socket)
+# else
+# define __socket socket
+# endif
+#endif
+
+ .globl __syscall_error
+ENTRY (__socket)
+
+ /* Drop up to 6 arguments (recvfrom) into the memory allocated by
+ the caller for varargs, since that's really what we have. */
+ st %o0, [%sp + 68 + 0]
+ st %o1, [%sp + 68 + 4]
+#if NARGS > 2
+ st %o2, [%sp + 68 + 8]
+#if NARGS > 3
+ st %o3, [%sp + 68 + 12]
+#if NARGS > 4
+ st %o4, [%sp + 68 + 16]
+#if NARGS > 5
+ st %o5, [%sp + 68 + 20]
+#endif
+#endif
+#endif
+#endif
+
+#if defined NEED_CANCELLATION && defined CENABLE
+ SINGLE_THREAD_P
+ cmp %g1, 0
+ bne .Lsocket_cancel
+#endif
+ mov P(SOCKOP_,socket), %o0 /* arg 1: socket subfunction */
+ add %sp, 68, %o1 /* arg 2: parameter block */
+ LOADSYSCALL(socketcall)
+ t 0x10
+ bcc 1f
+ mov %o7, %g1
+ call __syscall_error
+ mov %g1, %o7
+1: jmpl %o7 + 8, %g0
+ nop
+
+#if defined NEED_CANCELLATION && defined CENABLE
+.Lsocket_cancel:
+ save %sp, -96, %sp
+ cfi_def_cfa_register(%fp)
+ cfi_window_save
+ cfi_register(%o7, %i7)
+ CENABLE
+ nop
+ mov %o0, %l0
+ add %sp, 68 + 96, %o1
+ mov P(SOCKOP_,socket), %o0
+ LOADSYSCALL(socketcall)
+ t 0x10
+ bcc 1f
+ mov %o0, %l1
+ CDISABLE;
+ mov %l0, %o0;
+ call __syscall_error;
+ mov %l1, %o0;
+ b 1f
+ mov -1, %l1;
+1: CDISABLE
+ mov %l0, %o0
+2: jmpl %i7 + 8, %g0
+ restore %g0, %l1, %o0
+#endif
+
+END (__socket)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__socket, socket)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/get_clockfreq.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/get_clockfreq.c
new file mode 100644
index 000000000..4191085d1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/get_clockfreq.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S
new file mode 100644
index 000000000..161074552
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991, 1992, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ .globl __syscall_error
+ENTRY(syscall)
+ mov %o0, %g1
+ mov %o1, %o0
+ mov %o2, %o1
+ mov %o3, %o2
+ mov %o4, %o3
+ mov %o5, %o4
+ ta 0x10
+ bcc 1f
+ mov %o7, %g1
+ call __syscall_error
+ mov %g1, %o7
+1: retl
+ nop
+END(syscall)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list
new file mode 100644
index 000000000..2bfe376a3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list
@@ -0,0 +1,6 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+setrlimit - setrlimit 2 __setrlimit setrlimit
+getrlimit - getrlimit 2 __getrlimit getrlimit
+getresuid - getresuid32 3 getresuid
+getresgid - getresgid32 3 getresgid
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
new file mode 100644
index 000000000..c808a97fc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
@@ -0,0 +1,160 @@
+/* Copyright (C) 1997, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, January 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINUX_SPARC32_SYSDEP_H
+#define _LINUX_SPARC32_SYSDEP_H 1
+
+#include <sysdeps/unix/sparc/sysdep.h>
+
+#ifdef IS_IN_rtld
+# include <dl-sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */
+#endif
+#include <tls.h>
+
+#undef SYS_ify
+#define SYS_ify(syscall_name) __NR_##syscall_name
+
+#ifdef __ASSEMBLER__
+
+#define LOADSYSCALL(x) mov __NR_##x, %g1
+
+/* Linux/SPARC uses a different trap number */
+#undef PSEUDO
+#undef PSEUDO_NOERRNO
+#undef PSEUDO_ERRVAL
+#undef PSEUDO_END
+#undef ENTRY
+#undef END
+#undef LOC
+
+#define ENTRY(name) \
+ .align 4; \
+ .global C_SYMBOL_NAME(name); \
+ .type name, @function; \
+C_LABEL(name) \
+ cfi_startproc;
+
+#define END(name) \
+ cfi_endproc; \
+ .size name, . - name
+
+#define LOC(name) .L##name
+
+ /* If the offset to __syscall_error fits into a signed 22-bit
+ * immediate branch offset, the linker will relax the call into
+ * a normal branch.
+ */
+#define PSEUDO(name, syscall_name, args) \
+ .text; \
+ .globl __syscall_error; \
+ENTRY(name); \
+ LOADSYSCALL(syscall_name); \
+ ta 0x10; \
+ bcc 1f; \
+ mov %o7, %g1; \
+ call __syscall_error; \
+ mov %g1, %o7; \
+1:
+
+#define PSEUDO_NOERRNO(name, syscall_name, args)\
+ .text; \
+ENTRY(name); \
+ LOADSYSCALL(syscall_name); \
+ ta 0x10;
+
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .text; \
+ENTRY(name); \
+ LOADSYSCALL(syscall_name); \
+ ta 0x10;
+
+#define PSEUDO_END(name) \
+ END(name)
+
+#else /* __ASSEMBLER__ */
+
+#define __SYSCALL_STRING \
+ "ta 0x10;" \
+ "bcs 2f;" \
+ " nop;" \
+ "1:" \
+ ".subsection 2;" \
+ "2:" \
+ "save %%sp, -192, %%sp;" \
+ "call __errno_location;" \
+ " nop;" \
+ "st %%i0,[%%o0];" \
+ "ba 1b;" \
+ " restore %%g0, -1, %%o0;" \
+ ".previous;"
+
+#define __CLONE_SYSCALL_STRING \
+ "ta 0x10;" \
+ "bcs 2f;" \
+ " sub %%o1, 1, %%o1;" \
+ "and %%o0, %%o1, %%o0;" \
+ "1:" \
+ ".subsection 2;" \
+ "2:" \
+ "save %%sp, -192, %%sp;" \
+ "call __errno_location;" \
+ " nop;" \
+ "st %%i0, [%%o0];" \
+ "ba 1b;" \
+ " restore %%g0, -1, %%o0;" \
+ ".previous;"
+
+#define __INTERNAL_SYSCALL_STRING \
+ "ta 0x10;" \
+ "bcs,a 1f;" \
+ " sub %%g0, %%o0, %%o0;" \
+ "1:"
+
+#define __SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6", \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
+ "cc", "memory"
+
+#include <sysdeps/unix/sysv/linux/sparc/sysdep.h>
+
+#endif /* __ASSEMBLER__ */
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. */
+#else
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(dreg, reg, tmpreg) \
+ ld [%g7 + POINTER_GUARD], tmpreg; \
+ xor reg, tmpreg, dreg
+# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg)
+# define PTR_MANGLE2(dreg, reg, tmpreg) \
+ xor reg, tmpreg, dreg
+# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg)
+# else
+# define PTR_MANGLE(var) \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+# define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#endif
+
+#endif /* linux/sparc/sysdep.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc32/xstat.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/xstat.c
new file mode 100644
index 000000000..e9869f550
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc32/xstat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/xstat.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/Implies b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/Implies
new file mode 100644
index 000000000..8d91c8009
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/Implies
@@ -0,0 +1 @@
+unix/sysv/linux/wordsize-64
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
new file mode 100644
index 000000000..df4533af6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
@@ -0,0 +1,2 @@
+sysdep-CFLAGS += -fcall-used-g6
+LD += -melf64_sparc
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/Versions b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/Versions
new file mode 100644
index 000000000..cfcc15b11
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/Versions
@@ -0,0 +1,11 @@
+libc {
+ GLIBC_2.0 {
+ # Exception handling support functions from libgcc
+ __register_frame; __register_frame_table; __deregister_frame;
+ __frame_state_for; __register_frame_info_table;
+ }
+ GLIBC_2.2.2 {
+ # w*
+ wordexp;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/__longjmp.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/__longjmp.S
new file mode 100644
index 000000000..3107179fd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/__longjmp.S
@@ -0,0 +1 @@
+/* There is no need for __longjmp what with setcontext. */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
new file mode 100644
index 000000000..134ce789f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
@@ -0,0 +1,98 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* __brk is a special syscall under Linux since it never returns an
+ error. Instead, the error condition is indicated by returning the old
+ break value (instead of the new, requested one). */
+
+#include <sysdep.h>
+#define _ERRNO_H
+#include <bits/errno.h>
+
+#ifdef PIC
+.section .bss
+ .align 8
+ .globl __curbrk
+__curbrk: .skip 8
+ .type __curbrk,@object
+ .size __curbrk,8
+#else
+.common __curbrk, 8, 8
+#endif
+
+ .text
+ENTRY (__brk)
+ save %sp, -192, %sp
+ cfi_def_cfa_register(%fp)
+ cfi_window_save
+ cfi_register(%o7, %i7)
+#ifdef PIC
+1: call 2f
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
+2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
+ add %l7, %o7, %l7
+#endif
+
+ LOADSYSCALL(brk)
+ mov %i0, %o0
+
+ ta 0x6d
+
+ /* All the ways we can fail... */
+ bcs,pn %xcc, .Lerr1
+ nop
+ brz,pt %i0, .Lok
+ subcc %i0, %o0, %g0
+ bne,pn %xcc, .Lerr0
+ nop
+
+ /* Update __curbrk and return cleanly. */
+.Lok: sethi %hi(__curbrk), %g1
+ or %g1, %lo(__curbrk), %g1
+#ifdef PIC
+ ldx [%l7+%g1], %g1
+#endif
+ stx %o0, [%g1]
+ mov %g0, %i0
+
+ /* Don't use "ret" cause the preprocessor will eat it. */
+ jmpl %i7+8, %g0
+ restore
+
+ /* What a horrible way to die. */
+.Lerr0: set ENOMEM, %o0
+.Lerr1:
+#ifndef _LIBC_REENTRANT
+ sethi %hi(errno), %g1
+ or %g1, %lo(errno), %g1
+#ifdef PIC
+ ldx [%l7+%g1], %g1
+#endif
+ st %o0, [%g1]
+#else
+ call __errno_location
+ mov %o0,%l1
+ st %l1, [%o0]
+#endif
+ sub %g0, 1, %i0
+ jmpl %i7+8, %g0
+ restore
+END (__brk)
+
+weak_alias (__brk, brk)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-_setjmp.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-_setjmp.S
new file mode 100644
index 000000000..4e6a2da56
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-_setjmp.S
@@ -0,0 +1 @@
+/* _setjmp is in setjmp.S */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-setjmp.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-setjmp.S
new file mode 100644
index 000000000..1da848d2f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/bsd-setjmp.S
@@ -0,0 +1 @@
+/* setjmp is in setjmp.S */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
new file mode 100644
index 000000000..ebfce9e2c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
@@ -0,0 +1,121 @@
+/* Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@tamu.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* clone() is even more special than fork() as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#include <asm/errno.h>
+#include <asm/unistd.h>
+#include <tcb-offsets.h>
+#include <sysdep.h>
+
+#define CLONE_VM 0x00000100
+#define CLONE_THREAD 0x00010000
+
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+ pid_t *ptid, void *tls, pid_t *ctid); */
+
+ .register %g2,#scratch
+ .register %g3,#scratch
+
+ .text
+
+ENTRY (__clone)
+ save %sp, -192, %sp
+ cfi_def_cfa_register(%fp)
+ cfi_window_save
+ cfi_register(%o7, %i7)
+
+ /* sanity check arguments */
+ brz,pn %i0, 99f /* fn non-NULL? */
+ mov %i0, %g2
+ brz,pn %i1, 99f /* child_stack non-NULL? */
+ mov %i2, %o0 /* clone flags */
+
+ /* The child_stack is the top of the stack, allocate one
+ whole stack frame from that as this is what the kernel
+ expects. Also, subtract STACK_BIAS. */
+ sub %i1, 192 + 0x7ff, %o1
+ mov %i3, %g3
+ mov %i2, %g4
+
+ mov %i4,%o2 /* PTID */
+ mov %i5,%o3 /* TLS */
+ ldx [%fp+0x7ff+176],%o4 /* CTID */
+
+ /* Do the system call */
+ set __NR_clone, %g1
+ ta 0x6d
+ bcs,pn %xcc, 99f
+ nop
+ brnz,pn %o1, __thread_start
+ nop
+ jmpl %i7 + 8, %g0
+ restore %o0, %g0, %o0
+99:
+#ifndef _LIBC_REENTRANT
+#ifdef PIC
+ call 1f
+ sethi %hi(_GLOBAL_OFFSET_TABLE_-(99b-.)), %l7
+1: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(99b-.)), %l7
+ add %l7, %o7, %l7
+ set EINVAL, %i0
+ sethi %hi(errno), %g2
+ or %g2, %lo(errno), %g2
+ st %i0, [%l7+%g2]
+#else
+ sethi %hi(errno), %g2
+ set EINVAL, %i0
+ st %i0, [%g2+%lo(errno)]
+#endif
+#else
+ call __errno_location
+ nop
+ st %i0, [%o0]
+#endif
+ jmpl %i7 + 8, %g0
+ restore %g0,-1,%o0
+END(__clone)
+
+ .type __thread_start,@function
+__thread_start:
+ cfi_startproc
+#ifdef RESET_PID
+ sethi %hi(CLONE_THREAD), %l0
+ andcc %g4, %l0, %g0
+ bne,pt %icc, 1f
+ andcc %g4, CLONE_VM, %g0
+ bne,a,pn %icc, 2f
+ mov -1,%o0
+ set __NR_getpid,%g1
+ ta 0x6d
+2: st %o0,[%g7 + PID]
+ st %o0,[%g7 + TID]
+1:
+#endif
+ mov %g0, %fp /* terminate backtrace */
+ call %g2
+ mov %g3,%o0
+ call _exit,0
+ nop
+ cfi_endproc
+
+ .size __thread_start, .-__thread_start
+
+weak_alias (__clone, clone)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/dl-brk.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/dl-brk.S
new file mode 100644
index 000000000..eeb96544e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/dl-brk.S
@@ -0,0 +1 @@
+#include <brk.S>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/dl-cache.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/dl-cache.h
new file mode 100644
index 000000000..131cbb8fb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/dl-cache.h
@@ -0,0 +1,25 @@
+/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define _DL_CACHE_DEFAULT_ID 0x103
+
+#define _dl_cache_check_flags(flags) \
+ ((flags) == _DL_CACHE_DEFAULT_ID)
+
+#include_next <dl-cache.h>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/fxstat.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/fxstat.c
new file mode 100644
index 000000000..6b374777b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/fxstat.c
@@ -0,0 +1 @@
+#include "../../fxstat.c"
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/fxstatat.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/fxstatat.c
new file mode 100644
index 000000000..db08af8e0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/fxstatat.c
@@ -0,0 +1 @@
+#include "../../i386/fxstatat.c"
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c
new file mode 100644
index 000000000..e2d31a2e4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c
@@ -0,0 +1,238 @@
+/* Get frequency of the system processor. sparc64 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <libc-internal.h>
+#include <asm/openpromio.h>
+
+static hp_timing_t
+__get_clockfreq_via_cpuinfo (void)
+{
+ hp_timing_t result;
+ int fd;
+
+ result = 0;
+
+ fd = open ("/proc/cpuinfo", O_RDONLY);
+ if (fd != -1)
+ {
+ char buf[8192];
+ ssize_t n;
+
+ n = read (fd, buf, sizeof buf);
+ if (n > 0)
+ {
+ char *mhz = memmem (buf, n, "Cpu0ClkTck", 7);
+
+ if (mhz != NULL)
+ {
+ char *endp = buf + n;
+
+ /* Search for the beginning of the string. */
+ while (mhz < endp
+ && (*mhz < '0' || *mhz > '9')
+ && (*mhz < 'a' || *mhz > 'f')
+ && *mhz != '\n')
+ ++mhz;
+
+ while (mhz < endp && *mhz != '\n')
+ {
+ if ((*mhz >= '0' && *mhz <= '9') ||
+ (*mhz >= 'a' && *mhz <= 'f'))
+ {
+ result <<= 4;
+ if (*mhz >= '0' && *mhz <= '9')
+ result += *mhz - '0';
+ else
+ result += (*mhz - 'a') + 10;
+ }
+ ++mhz;
+ }
+ }
+ }
+
+ close (fd);
+ }
+
+ return result;
+}
+
+static hp_timing_t
+__get_clockfreq_via_proc_openprom (void)
+{
+ hp_timing_t result;
+ int obp_fd;
+
+ result = 0;
+
+ obp_fd = open ("/proc/openprom", O_RDONLY);
+ if (obp_fd != -1)
+ {
+ unsigned long int buf[4096 / sizeof (unsigned long int)];
+ struct dirent *dirp = (struct dirent *) buf;
+ off_t dbase = (off_t) 0;
+ ssize_t len;
+
+ while ((len = getdirentries (obp_fd, (char *) dirp,
+ sizeof (buf), &dbase)) > 0)
+ {
+ struct dirent *this_dirp = dirp;
+
+ while (len > 0)
+ {
+ char node[strlen ("/proc/openprom/")
+ + _D_ALLOC_NAMLEN (this_dirp)
+ + strlen ("/clock-frequency")];
+ char *prop;
+ int fd;
+
+ /* Note that
+ strlen("/clock-frequency") > strlen("/device_type")
+ */
+ __stpcpy (prop = __stpcpy (__stpcpy (node, "/proc/openprom/"),
+ this_dirp->d_name),
+ "/device_type");
+ fd = open (node, O_RDONLY);
+ if (fd != -1)
+ {
+ char type_string[128];
+ int ret;
+
+ ret = read (fd, type_string, sizeof (type_string));
+ if (ret > 0 && strncmp (type_string, "'cpu'", 5) == 0)
+ {
+ int clkfreq_fd;
+
+ __stpcpy (prop, "/clock-frequency");
+ clkfreq_fd = open (node, O_RDONLY);
+ if (fd != -1)
+ {
+ if (read (clkfreq_fd, type_string,
+ sizeof (type_string)) > 0)
+ result = (hp_timing_t)
+ strtoull (type_string, NULL, 16);
+ close (clkfreq_fd);
+ }
+ }
+ close (fd);
+ }
+
+ if (result != 0)
+ break;
+
+ len -= this_dirp->d_reclen;
+ this_dirp = (struct dirent *)
+ ((char *) this_dirp + this_dirp->d_reclen);
+ }
+ if (result != 0)
+ break;
+ }
+ close (obp_fd);
+ }
+
+ return result;
+}
+
+static hp_timing_t
+__get_clockfreq_via_dev_openprom (void)
+{
+ hp_timing_t result;
+ int obp_dev_fd;
+
+ result = 0;
+
+ obp_dev_fd = open ("/dev/openprom", O_RDONLY);
+ if (obp_dev_fd != -1)
+ {
+ char obp_buf[8192];
+ struct openpromio *obp_cmd = (struct openpromio *)obp_buf;
+ int ret;
+
+ obp_cmd->oprom_size =
+ sizeof (obp_buf) - sizeof (unsigned int);
+ *(int *) obp_cmd->oprom_array = 0;
+ ret = ioctl (obp_dev_fd, OPROMCHILD, (char *) obp_cmd);
+ if (ret == 0)
+ {
+ int cur_node = *(int *) obp_cmd->oprom_array;
+
+ while (cur_node != 0 && cur_node != -1)
+ {
+ obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int);
+ strcpy (obp_cmd->oprom_array, "device_type");
+ ret = ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd);
+ if (ret == 0
+ && strncmp (obp_cmd->oprom_array, "cpu", 3) == 0)
+ {
+ obp_cmd->oprom_size = (sizeof (obp_buf)
+ - sizeof (unsigned int));
+ strcpy (obp_cmd->oprom_array, "clock-frequency");
+ ret = ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd);
+ if (ret == 0)
+ result =
+ (hp_timing_t) *(unsigned int *) obp_cmd->oprom_array;
+ }
+ obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int);
+ *(int *) obp_cmd->oprom_array = cur_node;
+ ret = ioctl (obp_dev_fd, OPROMNEXT, (char *) obp_cmd);
+ if (ret < 0)
+ break;
+ cur_node = *(int *)obp_cmd->oprom_array;
+ }
+ }
+ }
+
+ return result;
+}
+
+hp_timing_t
+__get_clockfreq (void)
+{
+ static hp_timing_t result;
+
+ /* If this function was called before, we know the result. */
+ if (result != 0)
+ return result;
+
+ /* We first read the information from the /proc/cpuinfo file.
+ It contains at least one line like
+ Cpu0ClkTick : 000000002cb41780
+ We search for this line and convert the number in an integer. */
+ result = __get_clockfreq_via_cpuinfo ();
+ if (result != 0)
+ return result;
+
+ /* If that did not work, try to find an OpenPROM node
+ with device_type equal to 'cpu' using /dev/openprom
+ and fetch the clock-frequency property from there. */
+ result = __get_clockfreq_via_dev_openprom ();
+ if (result != 0)
+ return result;
+
+ /* Finally, try the same lookup as above but using /proc/openprom. */
+ result = __get_clockfreq_via_proc_openprom ();
+
+ return result;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/getcontext.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/getcontext.S
new file mode 100644
index 000000000..e6f5b55d6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/getcontext.S
@@ -0,0 +1,65 @@
+/* Copyright (C) 1997, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@tamu.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "ucontext_i.h"
+
+/* int getcontext(ucontext_t *); */
+
+ENTRY(__getcontext)
+
+ ldx [%o0 + UC_LINK], %o1 /* Preserve uc_link field, the
+ trap clears it. */
+ ta 0x6e
+1:
+ ldx [%o0 + UC_M_PC], %o2
+ ldx [%o0 + UC_M_NPC], %o3
+ ldx [%o0 + __UC_SIGMASK], %o4
+ stx %o1, [%o0 + UC_LINK]
+ add %o2, 2f - 1b, %o2
+ stx %o2, [%o0 + UC_M_PC]
+ add %o3, 2f - 1b, %o3
+ stx %o3, [%o0 + UC_M_NPC]
+#if SIGMASK_WORDS == 16
+ stx %o4, [%o0 + UC_SIGMASK]
+ stx %g0, [%o0 + UC_SIGMASK + 8]
+ stx %g0, [%o0 + UC_SIGMASK + 16]
+ stx %g0, [%o0 + UC_SIGMASK + 24]
+ stx %g0, [%o0 + UC_SIGMASK + 32]
+ stx %g0, [%o0 + UC_SIGMASK + 40]
+ stx %g0, [%o0 + UC_SIGMASK + 48]
+ stx %g0, [%o0 + UC_SIGMASK + 56]
+ stx %g0, [%o0 + UC_SIGMASK + 64]
+ stx %g0, [%o0 + UC_SIGMASK + 72]
+ stx %g0, [%o0 + UC_SIGMASK + 80]
+ stx %g0, [%o0 + UC_SIGMASK + 88]
+ stx %g0, [%o0 + UC_SIGMASK + 96]
+ stx %g0, [%o0 + UC_SIGMASK + 104]
+ stx %g0, [%o0 + UC_SIGMASK + 112]
+ stx %g0, [%o0 + UC_SIGMASK + 120]
+#else
+# error Adjust __getcontext
+#endif
+2:
+ retl
+ clr %o0
+
+END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
new file mode 100644
index 000000000..a4e411d13
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
@@ -0,0 +1,47 @@
+/* Definition of `struct stat' used in the kernel */
+struct kernel_stat
+ {
+ unsigned int st_dev;
+ unsigned long int st_ino;
+ unsigned int st_mode;
+ short int st_nlink;
+ unsigned int st_uid;
+ unsigned int st_gid;
+ unsigned int st_rdev;
+ long int st_size;
+ long int st_atime_sec;
+ long int st_mtime_sec;
+ long int st_ctime_sec;
+ long int st_blksize;
+ long int st_blocks;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ };
+
+/* Definition of `struct stat64' used in the kernel. */
+struct kernel_stat64
+ {
+ unsigned long int st_dev;
+ unsigned long int st_ino;
+ unsigned long int st_nlink;
+
+ unsigned int st_mode;
+ unsigned int st_uid;
+ unsigned int st_gid;
+ unsigned int __pad0;
+
+ unsigned long int st_rdev;
+ long int st_size;
+ long int st_blksize;
+ long int st_blocks;
+
+ unsigned long int st_atime_sec;
+ unsigned long int st_atime_nsec;
+ unsigned long int st_mtime_sec;
+ unsigned long int st_mtime_nsec;
+ unsigned long int st_ctime_sec;
+ unsigned long int st_ctime_nsec;
+ long int __unused[3];
+ };
+
+#define XSTAT_IS_XSTAT64 1
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
new file mode 100644
index 000000000..88dc54e85
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
@@ -0,0 +1,52 @@
+/* Copyright (C) 1997, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@tamu.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* longjmp is implemented in terms of the setcontext trap on Linux/Sparc64. */
+
+#include <sysdep.h>
+
+/* Offsets into the jmp_buf structure. */
+
+#define O_mask_was_saved 512
+#define O_gregs 32
+#define O_g1 (O_gregs + 4*8)
+
+
+/* void longjmp (sigjmp_buf env, int val) */
+
+ENTRY(__libc_siglongjmp)
+
+ /* Modify the context with the value we want to return. */
+ movre %o1, 1, %o1
+ stx %o1, [%o0 + O_g1]
+
+ /* Let setcontext know if we want to modify the current sigmask. */
+ ld [%o0 + O_mask_was_saved], %o1
+
+ /* And bamf back to where we belong! */
+ ta 0x6f
+
+END(__libc_siglongjmp)
+
+strong_alias(__libc_siglongjmp, __longjmp)
+strong_alias(__libc_siglongjmp, __libc_longjmp)
+libc_hidden_def (__libc_longjmp)
+weak_alias (__libc_siglongjmp, longjmp)
+weak_alias (__libc_siglongjmp, _longjmp)
+weak_alias (__libc_siglongjmp, siglongjmp)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/lxstat.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/lxstat.c
new file mode 100644
index 000000000..7f1e98e43
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/lxstat.c
@@ -0,0 +1 @@
+#include "../../i386/lxstat.c"
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c
new file mode 100644
index 000000000..52406dcce
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+ extern void __makecontext_ret (void);
+ unsigned long *sp, *topsp;
+ va_list ap;
+ int i;
+
+ sp = (long *) ((long) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
+ sp -= (argc > 6 ? argc : 6) + 32;
+ sp = (long *) (((long) sp) & -16L);
+ topsp = sp + (argc > 6 ? argc : 6) + 16;
+
+ ucp->uc_mcontext.mc_gregs[MC_PC] = (long) func;
+ ucp->uc_mcontext.mc_gregs[MC_NPC] = ((long) func) + 4;
+ ucp->uc_mcontext.mc_gregs[MC_O6] = ((long) sp) - 0x7ff;
+ ucp->uc_mcontext.mc_gregs[MC_O7] = ((long) __makecontext_ret) - 8;
+ ucp->uc_mcontext.mc_fp = ((long) topsp) - 0x7ff;
+ ucp->uc_mcontext.mc_i7 = 0;
+ topsp[14] = 0;
+ topsp[15] = 0;
+ sp[8] = (long) ucp->uc_link;
+ va_start (ap, argc);
+ for (i = 0; i < argc; ++i)
+ if (i < 6)
+ ucp->uc_mcontext.mc_gregs[MC_O0 + i] = va_arg (ap, long);
+ else
+ sp[16 + i] = va_arg (ap, long);
+ va_end (ap);
+}
+
+asm (" \n\
+ .text \n\
+ .type __makecontext_ret, #function \n\
+__makecontext_ret: \n\
+ mov 1, %o1 \n\
+ call __setcontext \n\
+ mov %i0, %o0 \n\
+ unimp 0 \n\
+ .size __makecontext_ret, .-__makecontext_ret \n\
+ ");
+
+weak_alias (__makecontext, makecontext)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/msgctl.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/msgctl.c
new file mode 100644
index 000000000..06a54a92b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/msgctl.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1995, 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/msg.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Allows to control internal state and destruction of message queue
+ objects. */
+
+int
+msgctl (msqid, cmd, buf)
+ int msqid;
+ int cmd;
+ struct msqid_ds *buf;
+{
+ return INLINE_SYSCALL (ipc, 5, IPCOP_msgctl, msqid, cmd, 0, CHECK_1 (buf));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c
new file mode 100644
index 000000000..2ec5bd39a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c
@@ -0,0 +1 @@
+#include <sysdeps/posix/pause.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
new file mode 100644
index 000000000..14f244e62
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
@@ -0,0 +1,41 @@
+/* Copyright (C) 1997, 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+
+ .globl __syscall_error
+ENTRY(__libc_pipe)
+ mov %o0, %o2 /* Save PIPEDES. */
+ LOADSYSCALL(pipe)
+ ta 0x6d
+ bcc,pt %xcc, 1f
+ mov %o7, %g1
+ call __syscall_error
+ mov %g1, %o7
+1: st %o0, [%o2] /* PIPEDES[0] = %o0; */
+ st %o1, [%o2 + 4] /* PIPEDES[1] = %o1; */
+ retl
+ clr %o0
+END(__libc_pipe)
+
+weak_alias (__libc_pipe, __pipe)
+libc_hidden_def (__pipe)
+weak_alias (__libc_pipe, pipe)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h
new file mode 100644
index 000000000..813bc2ca8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h
@@ -0,0 +1,26 @@
+/* Low-level statistical profiling support function. Linux/Sparc64 version.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+
+void
+profil_counter (int signo, struct sigcontext *si)
+{
+ profil_count ((void *) si->sigc_regs.tpc);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h
new file mode 100644
index 000000000..69265a284
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h
@@ -0,0 +1,257 @@
+/* Dump registers.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/uio.h>
+#include <stdio-common/_itoa.h>
+
+/* We will print the register dump in this format:
+
+ TSTATE: XXXXXXXXXXXXXXXX TPC: XXXXXXXXXXXXXXXX TNPC: XXXXXXXXXXXXXXXX
+ Y: XXXXXXXX
+ g0: 0000000000000000 g1: XXXXXXXXXXXXXXXX g2: XXXXXXXXXXXXXXXX
+ g3: XXXXXXXXXXXXXXXX g4: XXXXXXXXXXXXXXXX g5: XXXXXXXXXXXXXXXX
+ g6: XXXXXXXXXXXXXXXX g7: XXXXXXXXXXXXXXXX
+ o0: XXXXXXXXXXXXXXXX o1: XXXXXXXXXXXXXXXX o2: XXXXXXXXXXXXXXXX
+ o3: XXXXXXXXXXXXXXXX o4: XXXXXXXXXXXXXXXX o5: XXXXXXXXXXXXXXXX
+ sp: XXXXXXXXXXXXXXXX o7: XXXXXXXXXXXXXXXX
+ l0: XXXXXXXXXXXXXXXX l1: XXXXXXXXXXXXXXXX l2: XXXXXXXXXXXXXXXX
+ l3: XXXXXXXXXXXXXXXX l4: XXXXXXXXXXXXXXXX l5: XXXXXXXXXXXXXXXX
+ l6: XXXXXXXXXXXXXXXX l7: XXXXXXXXXXXXXXXX
+ i0: XXXXXXXXXXXXXXXX i1: XXXXXXXXXXXXXXXX i2: XXXXXXXXXXXXXXXX
+ i3: XXXXXXXXXXXXXXXX i4: XXXXXXXXXXXXXXXX i5: XXXXXXXXXXXXXXXX
+ fp: XXXXXXXXXXXXXXXX i7: XXXXXXXXXXXXXXXX
+
+ Mask: XXXXXXXXXXXXXXXX XFSR: XXXXXXXXXXXXXXXX GSR: XX FPRS: X
+ f0: XXXXXXXXXXXXXXXX f2: XXXXXXXXXXXXXXXX f4: XXXXXXXXXXXXXXXX
+ f6: XXXXXXXXXXXXXXXX f8: XXXXXXXXXXXXXXXX f10: XXXXXXXXXXXXXXXX
+ f12: XXXXXXXXXXXXXXXX f14: XXXXXXXXXXXXXXXX f16: XXXXXXXXXXXXXXXX
+ f18: XXXXXXXXXXXXXXXX f20: XXXXXXXXXXXXXXXX f22: XXXXXXXXXXXXXXXX
+ f24: XXXXXXXXXXXXXXXX f26: XXXXXXXXXXXXXXXX f28: XXXXXXXXXXXXXXXX
+ f30: XXXXXXXXXXXXXXXX f32: XXXXXXXXXXXXXXXX f34: XXXXXXXXXXXXXXXX
+ f36: XXXXXXXXXXXXXXXX f38: XXXXXXXXXXXXXXXX f40: XXXXXXXXXXXXXXXX
+ f42: XXXXXXXXXXXXXXXX f44: XXXXXXXXXXXXXXXX f46: XXXXXXXXXXXXXXXX
+ f48: XXXXXXXXXXXXXXXX f50: XXXXXXXXXXXXXXXX f52: XXXXXXXXXXXXXXXX
+ f54: XXXXXXXXXXXXXXXX f56: XXXXXXXXXXXXXXXX f58: XXXXXXXXXXXXXXXX
+ f60: XXXXXXXXXXXXXXXX f62: XXXXXXXXXXXXXXXX
+
+ */
+
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
+{
+ char *cp = _itoa_word (value, buf + len, 16, 0);
+ while (cp > buf)
+ *--cp = '0';
+}
+
+static void
+register_dump (int fd, SIGCONTEXT ctx)
+{
+ char regs[36][16];
+ char fregs[68][8];
+ struct iovec iov[150];
+ size_t nr = 0;
+ int i;
+ unsigned long *r = (unsigned long *)
+ (ctx->sigc_regs.u_regs[14] + STACK_BIAS);
+ __siginfo_fpu_t *f;
+
+#define ADD_STRING(str) \
+ iov[nr].iov_base = (char *) str; \
+ iov[nr].iov_len = strlen (str); \
+ ++nr
+#define ADD_MEM(str, len) \
+ iov[nr].iov_base = str; \
+ iov[nr].iov_len = len; \
+ ++nr
+
+ /* Generate strings of register contents. */
+ hexvalue (ctx->sigc_regs.tstate, regs[0], 16);
+ hexvalue (ctx->sigc_regs.tpc, regs[1], 16);
+ hexvalue (ctx->sigc_regs.tnpc, regs[2], 16);
+ hexvalue (ctx->sigc_regs.y, regs[3], 8);
+ for (i = 1; i <= 15; i++)
+ hexvalue (ctx->sigc_regs.u_regs[i], regs[3+i], 16);
+ for (i = 0; i <= 15; i++)
+ hexvalue (r[i], regs[19+i], 16);
+ hexvalue (ctx->sigc_mask, regs[35], 16);
+
+ /* Generate the output. */
+ ADD_STRING ("Register dump:\n\n TSTATE: ");
+ ADD_MEM (regs[0], 16);
+ ADD_STRING (" TPC: ");
+ ADD_MEM (regs[1], 16);
+ ADD_STRING (" TNPC: ");
+ ADD_MEM (regs[2], 16);
+ ADD_STRING ("\n Y: ");
+ ADD_MEM (regs[3], 8);
+ ADD_STRING ("\n g0: 0000000000000000 g1: ");
+ ADD_MEM (regs[4], 16);
+ ADD_STRING (" g2: ");
+ ADD_MEM (regs[5], 16);
+ ADD_STRING ("\n g3: ");
+ ADD_MEM (regs[6], 16);
+ ADD_STRING (" g4: ");
+ ADD_MEM (regs[7], 16);
+ ADD_STRING (" g5: ");
+ ADD_MEM (regs[8], 16);
+ ADD_STRING ("\n g6: ");
+ ADD_MEM (regs[9], 16);
+ ADD_STRING (" g7: ");
+ ADD_MEM (regs[10], 16);
+ ADD_STRING ("\n o0: ");
+ ADD_MEM (regs[11], 16);
+ ADD_STRING (" o1: ");
+ ADD_MEM (regs[12], 16);
+ ADD_STRING (" o2: ");
+ ADD_MEM (regs[13], 16);
+ ADD_STRING ("\n o3: ");
+ ADD_MEM (regs[14], 16);
+ ADD_STRING (" o4: ");
+ ADD_MEM (regs[15], 16);
+ ADD_STRING (" o5: ");
+ ADD_MEM (regs[16], 16);
+ ADD_STRING ("\n sp: ");
+ ADD_MEM (regs[17], 16);
+ ADD_STRING (" o7: ");
+ ADD_MEM (regs[18], 16);
+ ADD_STRING ("\n l0: ");
+ ADD_MEM (regs[19], 16);
+ ADD_STRING (" l1: ");
+ ADD_MEM (regs[20], 16);
+ ADD_STRING (" l2: ");
+ ADD_MEM (regs[21], 16);
+ ADD_STRING ("\n l3: ");
+ ADD_MEM (regs[22], 16);
+ ADD_STRING (" l4: ");
+ ADD_MEM (regs[23], 16);
+ ADD_STRING (" l5: ");
+ ADD_MEM (regs[24], 16);
+ ADD_STRING ("\n l6: ");
+ ADD_MEM (regs[25], 16);
+ ADD_STRING (" l7: ");
+ ADD_MEM (regs[26], 16);
+ ADD_STRING ("\n i0: ");
+ ADD_MEM (regs[27], 16);
+ ADD_STRING (" i1: ");
+ ADD_MEM (regs[28], 16);
+ ADD_STRING (" i2: ");
+ ADD_MEM (regs[29], 16);
+ ADD_STRING ("\n i3: ");
+ ADD_MEM (regs[30], 16);
+ ADD_STRING (" i4: ");
+ ADD_MEM (regs[31], 16);
+ ADD_STRING (" i5: ");
+ ADD_MEM (regs[32], 16);
+ ADD_STRING ("\n fp: ");
+ ADD_MEM (regs[33], 16);
+ ADD_STRING (" i7: ");
+ ADD_MEM (regs[34], 16);
+ ADD_STRING ("\n\n Mask: ");
+ ADD_MEM (regs[35], 16);
+
+ f = ctx->sigc_fpu_save;
+ if (f != NULL)
+ {
+ for (i = 0; i < 64; i++)
+ hexvalue (f->si_float_regs[i], fregs[i], 8);
+ hexvalue (f->si_fsr, fregs[64], 16);
+ hexvalue (f->si_gsr, fregs[66], 2);
+ hexvalue (f->si_fprs, fregs[67], 1);
+ ADD_STRING (" XFSR: ");
+ ADD_MEM (fregs[64], 16);
+ ADD_STRING (" GSR: ");
+ ADD_MEM (fregs[66], 2);
+ ADD_STRING (" FPRS: ");
+ ADD_MEM (fregs[67], 1);
+ ADD_STRING ("\n f0: ");
+ ADD_MEM (fregs[0], 16);
+ ADD_STRING (" f2: ");
+ ADD_MEM (fregs[2], 16);
+ ADD_STRING (" f4: ");
+ ADD_MEM (fregs[4], 16);
+ ADD_STRING ("\n f6: ");
+ ADD_MEM (fregs[6], 16);
+ ADD_STRING (" f8: ");
+ ADD_MEM (fregs[8], 16);
+ ADD_STRING (" f10: ");
+ ADD_MEM (fregs[10], 16);
+ ADD_STRING ("\n f12: ");
+ ADD_MEM (fregs[12], 16);
+ ADD_STRING (" f14: ");
+ ADD_MEM (fregs[14], 16);
+ ADD_STRING (" f16: ");
+ ADD_MEM (fregs[16], 16);
+ ADD_STRING ("\n f18: ");
+ ADD_MEM (fregs[18], 16);
+ ADD_STRING (" f20: ");
+ ADD_MEM (fregs[20], 16);
+ ADD_STRING (" f22: ");
+ ADD_MEM (fregs[22], 16);
+ ADD_STRING ("\n f24: ");
+ ADD_MEM (fregs[24], 16);
+ ADD_STRING (" f26: ");
+ ADD_MEM (fregs[26], 16);
+ ADD_STRING (" f28: ");
+ ADD_MEM (fregs[28], 16);
+ ADD_STRING ("\n f30: ");
+ ADD_MEM (fregs[30], 16);
+ ADD_STRING (" f32: ");
+ ADD_MEM (fregs[32], 16);
+ ADD_STRING (" f34: ");
+ ADD_MEM (fregs[34], 16);
+ ADD_STRING ("\n f36: ");
+ ADD_MEM (fregs[36], 16);
+ ADD_STRING (" f38: ");
+ ADD_MEM (fregs[38], 16);
+ ADD_STRING (" f40: ");
+ ADD_MEM (fregs[40], 16);
+ ADD_STRING ("\n f42: ");
+ ADD_MEM (fregs[42], 16);
+ ADD_STRING (" f44: ");
+ ADD_MEM (fregs[44], 16);
+ ADD_STRING (" f46: ");
+ ADD_MEM (fregs[46], 16);
+ ADD_STRING ("\n f48: ");
+ ADD_MEM (fregs[48], 16);
+ ADD_STRING (" f50: ");
+ ADD_MEM (fregs[50], 16);
+ ADD_STRING (" f52: ");
+ ADD_MEM (fregs[52], 16);
+ ADD_STRING ("\n f54: ");
+ ADD_MEM (fregs[54], 16);
+ ADD_STRING (" f56: ");
+ ADD_MEM (fregs[56], 16);
+ ADD_STRING (" f58: ");
+ ADD_MEM (fregs[58], 16);
+ ADD_STRING ("\n f60: ");
+ ADD_MEM (fregs[60], 16);
+ ADD_STRING (" f62: ");
+ ADD_MEM (fregs[62], 16);
+ }
+
+ ADD_STRING ("\n");
+
+ /* Write the stuff out. */
+ writev (fd, iov, nr);
+}
+
+
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/semctl.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/semctl.c
new file mode 100644
index 000000000..057e28782
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/semctl.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1995, 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/sem.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Define a `union semun' suitable for Linux here. */
+union semun
+{
+ int val; /* value for SETVAL */
+ struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
+ unsigned short int *array; /* array for GETALL & SETALL */
+ struct seminfo *__buf; /* buffer for IPC_INFO */
+};
+
+#include <bp-checks.h>
+#include <bp-semctl.h> /* definition of CHECK_SEMCTL needs union semum */
+
+/* Return identifier for array of NSEMS semaphores associated with
+ KEY. */
+
+int
+semctl (int semid, int semnum, int cmd, ...)
+{
+ union semun arg;
+ va_list ap;
+
+ va_start (ap, cmd);
+
+ /* Get the argument. */
+ arg = va_arg (ap, union semun);
+
+ va_end (ap);
+
+ return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
+ CHECK_SEMCTL (&arg, semid, cmd));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S
new file mode 100644
index 000000000..90d47c18f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S
@@ -0,0 +1,39 @@
+/* Copyright (C) 1997, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@tamu.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "ucontext_i.h"
+
+/* int setcontext(ucontext_t *ctx); */
+.weak setcontext
+ENTRY(setcontext)
+
+ ba,pt %xcc, 1f
+ mov 1, %o1
+
+END(setcontext)
+
+/* int __setcontext(ucontext_t *ctx, int restoremask); */
+ENTRY(__setcontext)
+
+1: ldx [%o0 + UC_SIGMASK], %o2
+ stx %o2, [%o0 + __UC_SIGMASK]
+ ta 0x6f
+
+END(__setcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S
new file mode 100644
index 000000000..ab1690bb4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S
@@ -0,0 +1,67 @@
+/* Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson (rth@tamu.edu).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* __sigsetjmp is implemented in terms of the getcontext trap on
+ Linux/Sparc64. */
+
+#include <sysdep.h>
+
+/* Offsets into the jmp_buf structure. */
+
+#define O_mask_was_saved 512
+#define O_gregs 32
+#define O_g1 (O_gregs + 4*8)
+
+/* int _setjmp(jmp_buf) */
+
+ENTRY(_setjmp)
+ ba __sigsetjmp_local
+ set 0, %o1
+END(_setjmp)
+libc_hidden_def (_setjmp)
+
+/* int setjmp(jmp_buf) */
+
+ENTRY(setjmp)
+ ba,pt %xcc, __sigsetjmp_local
+ set 1, %o1
+END(setjmp)
+
+/* int __sigsetjmp(jmp_buf, savemask) */
+
+ENTRY(__sigsetjmp)
+__sigsetjmp_local:
+
+ /* Record whether the user is intending to save the sigmask. */
+ st %o1, [%o0 + O_mask_was_saved]
+
+ /* Load up our return value, as longjmp is going to override
+ the jmp_buf on its way back. */
+ mov %g0, %g1
+
+ /* And call getcontext! */
+ ta 0x6e
+
+ retl
+ mov %g1, %o0
+
+END(__sigsetjmp)
+
+weak_extern(_setjmp)
+weak_extern(setjmp)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/shmctl.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/shmctl.c
new file mode 100644
index 000000000..797b3500f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/shmctl.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1995, 1997, 1998, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/shm.h>
+#include <ipc_priv.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Provide operations to control over shared memory segments. */
+
+int
+shmctl (shmid, cmd, buf)
+ int shmid;
+ int cmd;
+ struct shmid_ds *buf;
+{
+ return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd, 0, CHECK_1 (buf));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c
new file mode 100644
index 000000000..b5e35f4e4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c
@@ -0,0 +1,85 @@
+/* POSIX.1 sigaction call for Linux/SPARC64.
+ Copyright (C) 1997-2000,2002,2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx) and
+ Jakub Jelinek (jj@ultra.linux.cz).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <syscall.h>
+#include <sysdep.h>
+#include <sys/signal.h>
+#include <errno.h>
+
+#include <kernel_sigaction.h>
+
+/* SPARC 64bit userland requires a kernel that has rt signals anyway. */
+
+static void __rt_sigreturn_stub (void);
+
+int
+__libc_sigaction (int sig, __const struct sigaction *act,
+ struct sigaction *oact)
+{
+ int ret;
+ struct kernel_sigaction kact, koact;
+ unsigned long stub = ((unsigned long) &__rt_sigreturn_stub) - 8;
+
+ if (act)
+ {
+ kact.k_sa_handler = act->sa_handler;
+ memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
+ kact.sa_flags = act->sa_flags;
+ kact.sa_restorer = NULL;
+ }
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ ret = INLINE_SYSCALL (rt_sigaction, 5, sig,
+ act ? __ptrvalue (&kact) : 0,
+ oact ? __ptrvalue (&koact) : 0, stub, _NSIG / 8);
+
+ if (oact && ret >= 0)
+ {
+ oact->sa_handler = koact.k_sa_handler;
+ memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t));
+ oact->sa_flags = koact.sa_flags;
+ oact->sa_restorer = koact.sa_restorer;
+ }
+
+ return ret;
+}
+libc_hidden_def (__libc_sigaction)
+
+#ifdef WRAPPER_INCLUDE
+# include WRAPPER_INCLUDE
+#endif
+
+#ifndef LIBC_SIGACTION
+weak_alias (__libc_sigaction, __sigaction);
+libc_hidden_weak (__sigaction)
+weak_alias (__libc_sigaction, sigaction);
+#endif
+
+static void
+__rt_sigreturn_stub (void)
+{
+ __asm__ ("mov %0, %%g1\n\t"
+ "ta 0x6d\n\t"
+ : /* no outputs */
+ : "i" (__NR_rt_sigreturn));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h
new file mode 100644
index 000000000..47e0d27f8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef STACK_BIAS
+#define STACK_BIAS 2047
+#endif
+#define SIGCONTEXT struct sigcontext *
+#define SIGCONTEXT_EXTRA_ARGS
+#define GET_PC(__ctx) ((void *) ((__ctx)->sigc_regs.tpc))
+#define ADVANCE_STACK_FRAME(__next) \
+ ((void *) (((unsigned long *) (((unsigned long int) (__next)) \
+ + STACK_BIAS))+14))
+#define GET_STACK(__ctx) ((void *) ((__ctx)->sigc_regs.u_regs[14]))
+#define GET_FRAME(__ctx) ADVANCE_STACK_FRAME (GET_STACK (__ctx))
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigjmp.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigjmp.S
new file mode 100644
index 000000000..940ccbcf6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigjmp.S
@@ -0,0 +1 @@
+/* There is no need for __sigjmp_save what with getcontext. */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigpending.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigpending.c
new file mode 100644
index 000000000..016a28534
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigpending.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1997, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Change the set of blocked signals to SET,
+ wait until a signal arrives, and restore the set of blocked signals. */
+int
+sigpending (set)
+ sigset_t *set;
+{
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ return INLINE_SYSCALL (rt_sigpending, 2, CHECK_SIGSET (set), _NSIG / 8);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigprocmask.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigprocmask.c
new file mode 100644
index 000000000..d077b9be4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sigprocmask.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1997, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Get and/or change the set of blocked signals. */
+int
+__sigprocmask (how, set, oset)
+ int how;
+ const sigset_t *set;
+ sigset_t *oset;
+{
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ return INLINE_SYSCALL (rt_sigprocmask, 4, how, CHECK_SIGSET (set),
+ CHECK_SIGSET_NULL_OK (oset), _NSIG / 8);
+}
+weak_alias (__sigprocmask, sigprocmask)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sizes.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sizes.h
new file mode 100644
index 000000000..0c7f4d5d2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sizes.h
@@ -0,0 +1,24 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SIZES_H
+#define _SIZES_H 1
+
+#define PTR_SIZE_STR "8"
+
+#endif /* sizes.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S
new file mode 100644
index 000000000..353705b4a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S
@@ -0,0 +1,119 @@
+/* Copyright (C) 1997, 1998, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep-cancel.h>
+#include <socketcall.h>
+
+#define P(a, b) P2(a, b)
+#define P2(a, b) a##b
+
+#ifndef NARGS
+#ifdef socket
+#error NARGS not defined
+#endif
+#define NARGS 3
+#endif
+
+ .text
+/* The socket-oriented system calls are handled unusually in Linux.
+ They are all gated through the single `socketcall' system call number.
+ `socketcall' takes two arguments: the first is the subcode, specifying
+ which socket function is being called; and the second is a pointer to
+ the arguments to the specific function.
+
+ The .S files for the other calls just #define socket and #include this. */
+
+#ifndef __socket
+# ifndef NO_WEAK_ALIAS
+# define __socket P(__,socket)
+# else
+# define __socket socket
+# endif
+#endif
+
+ .globl __syscall_error
+ENTRY(__socket)
+
+ /* Drop up to 6 arguments (recvfrom) into the memory allocated by
+ the caller for varargs, since that's really what we have. */
+ stx %o0, [%sp + STACK_BIAS + 128 + 0]
+ stx %o1, [%sp + STACK_BIAS + 128 + 8]
+#if NARGS > 2
+ stx %o2, [%sp + STACK_BIAS + 128 + 16]
+#if NARGS > 3
+ stx %o3, [%sp + STACK_BIAS + 128 + 24]
+#if NARGS > 4
+ stx %o4, [%sp + STACK_BIAS + 128 + 32]
+#if NARGS > 5
+ stx %o5, [%sp + STACK_BIAS + 128 + 40]
+#endif
+#endif
+#endif
+#endif
+
+#if defined NEED_CANCELLATION && defined CENABLE
+ SINGLE_THREAD_P
+ cmp %g1, 0
+ bne .Lsocket_cancel
+#endif
+ mov P(SOCKOP_,socket), %o0 /* arg 1: socket subfunction */
+ add %sp, STACK_BIAS + 128, %o1 /* arg 2: parameter block */
+ LOADSYSCALL(socketcall)
+ ta 0x6d
+
+ bcc,pt %xcc, 1f
+ mov %o7, %g1
+ call __syscall_error
+ mov %g1, %o7
+1: retl
+ nop
+
+#if defined NEED_CANCELLATION && defined CENABLE
+.Lsocket_cancel:
+ save %sp, -160, %sp
+ cfi_def_cfa_register (%fp)
+ cfi_window_save
+ cfi_register (%o7, %i7)
+ CENABLE
+ nop
+ mov %o0, %l0
+ add %sp, 160 + STACK_BIAS + 128, %o1
+ mov P(SOCKOP_,socket), %o0
+ LOADSYSCALL(socketcall)
+ ta 0x6d
+
+ bcc,pt %xcc, 1f
+ mov %o0, %l1
+ CDISABLE;
+ mov %l0, %o0;
+ call __syscall_error;
+ mov %l1, %o0;
+ ba,pt %xcc, 2f
+ mov -1, %l1;
+1: CDISABLE
+ mov %l0, %o0
+2: jmpl %i7 + 8, %g0
+ restore %g0, %l1, %o0
+#endif
+
+END(__socket)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__socket, socket)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/swapcontext.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/swapcontext.c
new file mode 100644
index 000000000..ac6fd5bc6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/swapcontext.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ucontext.h>
+
+extern int __getcontext (ucontext_t *ucp);
+extern int __setcontext (const ucontext_t *ucp, int restoremask);
+
+int
+__swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
+{
+ extern void __swapcontext_ret (void);
+ /* Save the current machine context to oucp. */
+ __getcontext (oucp);
+ /* Modify oucp to skip the __setcontext call on reactivation. */
+ oucp->uc_mcontext.mc_gregs[MC_PC] = (long) __swapcontext_ret;
+ oucp->uc_mcontext.mc_gregs[MC_NPC] = ((long) __swapcontext_ret) + 4;
+ /* Restore the machine context in ucp. */
+ __setcontext (ucp, 1);
+ return 0;
+}
+
+asm (" \n\
+ .text \n\
+ .type __swapcontext_ret, #function \n\
+__swapcontext_ret: \n\
+ return %i7 + 8 \n\
+ clr %o0 \n\
+ .size __swapcontext_ret, .-__swapcontext_ret \n\
+ ");
+
+weak_alias (__swapcontext, swapcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
new file mode 100644
index 000000000..27487d8ed
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
@@ -0,0 +1,39 @@
+/* Copyright (C) 1997, 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+ .text
+
+ .globl __syscall_error
+ENTRY(syscall)
+ mov %o0,%g1
+ mov %o1,%o0
+ mov %o2,%o1
+ mov %o3,%o2
+ mov %o4,%o3
+ mov %o5,%o4
+
+ ta 0x6d
+
+ bcc,pt %xcc, 1f
+ mov %o7, %g1
+ call __syscall_error
+ mov %g1, %o7
+1: retl
+ nop
+END(syscall)
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list
new file mode 100644
index 000000000..ca2953c6b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/syscalls.list
@@ -0,0 +1,20 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+# Override select.S in parent directory:
+select - select C:5 __select select
+accept - accept C:3 __libc_accept __accept accept
+bind - bind 3 __bind bind
+connect - connect C:3 __libc_connect __connect_internal __connect connect
+getpeername - getpeername 3 __getpeername getpeername
+getsockname - getsockname 3 __getsockname getsockname
+getsockopt - getsockopt 5 __getsockopt getsockopt
+listen - listen 2 __listen listen
+recv - recv C:4 __libc_recv __recv recv
+recvfrom - recvfrom C:6 __libc_recvfrom __recvfrom recvfrom
+recvmsg - recvmsg C:3 __libc_recvmsg __recvmsg recvmsg
+send - send C:4 __libc_send __send send
+sendmsg - sendmsg C:3 __libc_sendmsg __sendmsg sendmsg
+sendto - sendto C:6 __libc_sendto __sendto sendto
+setsockopt - setsockopt 5 __setsockopt setsockopt
+shutdown - shutdown 2 __shutdown shutdown
+socketpair - socketpair 4 __socketpair socketpair
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
new file mode 100644
index 000000000..f156f9241
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
@@ -0,0 +1,175 @@
+/* Copyright (C) 1997, 2000, 2002, 2003, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINUX_SPARC64_SYSDEP_H
+#define _LINUX_SPARC64_SYSDEP_H 1
+
+#include <sysdeps/unix/sysdep.h>
+
+#ifdef IS_IN_rtld
+# include <dl-sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */
+#endif
+#include <tls.h>
+
+#undef SYS_ify
+#define SYS_ify(syscall_name) __NR_##syscall_name
+
+/* This is a kludge to make syscalls.list find these under the names
+ pread and pwrite, since some kernel headers define those names
+ and some define the *64 names for the same system calls. */
+#if !defined __NR_pread && defined __NR_pread64
+# define __NR_pread __NR_pread64
+#endif
+#if !defined __NR_pwrite && defined __NR_pwrite64
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+#ifdef __ASSEMBLER__
+
+#define LOADSYSCALL(x) mov __NR_##x, %g1
+
+/* Linux/SPARC uses a different trap number */
+#undef PSEUDO
+#undef PSEUDO_NOERRNO
+#undef PSEUDO_ERRVAL
+#undef PSEUDO_END
+#undef ENTRY
+#undef END
+
+#define ENTRY(name) \
+ .align 4; \
+ .global C_SYMBOL_NAME(name); \
+ .type name, @function; \
+C_LABEL(name) \
+ cfi_startproc;
+
+#define END(name) \
+ cfi_endproc; \
+ .size name, . - name
+
+ /* If the offset to __syscall_error fits into a signed 22-bit
+ * immediate branch offset, the linker will relax the call into
+ * a normal branch.
+ */
+#define PSEUDO(name, syscall_name, args) \
+ .text; \
+ .globl __syscall_error; \
+ENTRY(name); \
+ LOADSYSCALL(syscall_name); \
+ ta 0x6d; \
+ bcc,pt %xcc, 1f; \
+ mov %o7, %g1; \
+ call __syscall_error; \
+ mov %g1, %o7; \
+1:
+
+#define PSEUDO_NOERRNO(name, syscall_name, args)\
+ .text; \
+ENTRY(name); \
+ LOADSYSCALL(syscall_name); \
+ ta 0x6d;
+
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .text; \
+ENTRY(name); \
+ LOADSYSCALL(syscall_name); \
+ ta 0x6d;
+
+#define PSEUDO_END(name) \
+ END(name)
+
+
+/* Careful here! This "ret" define can interfere; use jmpl if unsure. */
+#define ret retl; nop
+#define ret_NOERRNO retl; nop
+#define ret_ERRVAL retl; nop
+#define r0 %o0
+#define r1 %o1
+#define MOVE(x,y) mov x, y
+
+#else /* __ASSEMBLER__ */
+
+#define __SYSCALL_STRING \
+ "ta 0x6d;" \
+ "bcc,pt %%xcc, 1f;" \
+ " nop;" \
+ "save %%sp, -192, %%sp;" \
+ "call __errno_location;" \
+ " nop;" \
+ "st %%i0,[%%o0];" \
+ "restore %%g0, -1, %%o0;" \
+ "1:"
+
+#define __CLONE_SYSCALL_STRING \
+ "ta 0x6d;" \
+ "bcc,pt %%xcc, 1f;" \
+ " sub %%o1, 1, %%o1;" \
+ "save %%sp, -192, %%sp;" \
+ "call __errno_location;" \
+ " mov -1, %%i1;" \
+ "st %%i0,[%%o0];" \
+ "restore %%g0, -1, %%o0;" \
+ "1:" \
+ "and %%o0, %%o1, %%o0"
+
+#define __INTERNAL_SYSCALL_STRING \
+ "ta 0x6d;" \
+ "bcs,a,pt %%xcc, 1f;" \
+ " sub %%g0, %%o0, %%o0;" \
+ "1:"
+
+#define __SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6", \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
+ "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \
+ "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", \
+ "cc", "memory"
+
+#include <sysdeps/unix/sysv/linux/sparc/sysdep.h>
+
+#endif /* __ASSEMBLER__ */
+
+/* This is the offset from the %sp to the backing store above the
+ register windows. So if you poke stack memory directly you add this. */
+#define STACK_BIAS 2047
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. */
+#else
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(dreg, reg, tmpreg) \
+ ldx [%g7 + POINTER_GUARD], tmpreg; \
+ xor reg, tmpreg, dreg
+# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg)
+# define PTR_MANGLE2(dreg, reg, tmpreg) \
+ xor reg, tmpreg, dreg
+# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg)
+# else
+# define PTR_MANGLE(var) \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+# define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#endif
+
+#endif /* linux/sparc64/sysdep.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/time.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/time.c
new file mode 100644
index 000000000..3a64ef195
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/time.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/time.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/ucontext_i.h b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/ucontext_i.h
new file mode 100644
index 000000000..03db063c8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/ucontext_i.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Constants shared between setcontext() and getcontext(). Don't
+ install this header file. */
+
+#define UC_LINK 0
+#define __UC_SIGMASK 16
+#define UC_M_PC 40
+#define UC_M_NPC 48
+#define UC_SIGMASK 536
+#define SIGMASK_WORDS 16
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/wordexp.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/wordexp.c
new file mode 100644
index 000000000..2e3d5bc2e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/wordexp.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/alpha/wordexp.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c
new file mode 100644
index 000000000..9f4c02c78
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c
@@ -0,0 +1,8 @@
+#include "../../i386/xstat.c"
+
+#ifdef __NR_stat64
+# if __ASSUME_STAT64_SYSCALL == 0
+/* The variable is shared between all wrappers around *stat{,64} calls. */
+int __have_no_stat64;
+# endif
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sparc64/xstatconv.c b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/xstatconv.c
new file mode 100644
index 000000000..d3f49eea4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sparc64/xstatconv.c
@@ -0,0 +1,127 @@
+/* Convert between the kernel's `struct stat' format, and libc's.
+ Copyright (C) 1991, 1995, 1996, 1997, 2000, 2002, 2003, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+#include <string.h>
+#include <kernel-features.h>
+
+int
+__xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
+{
+ switch (vers)
+ {
+ case _STAT_VER_KERNEL:
+ /* Nothing to do. The struct is in the form the kernel expects.
+ We should have short-circuted before we got here, but for
+ completeness... */
+ *(struct kernel_stat *) ubuf = *kbuf;
+ break;
+
+ case _STAT_VER_LINUX:
+ {
+ struct stat *buf = ubuf;
+
+ /* Convert to current kernel version of `struct stat'. */
+ buf->st_dev = kbuf->st_dev;
+ buf->__pad1 = 0;
+ buf->st_ino = kbuf->st_ino;
+ buf->st_mode = kbuf->st_mode;
+ buf->st_nlink = kbuf->st_nlink;
+ buf->st_uid = kbuf->st_uid;
+ buf->st_gid = kbuf->st_gid;
+ buf->st_rdev = kbuf->st_rdev;
+ buf->__pad2 = 0;
+ buf->st_size = kbuf->st_size;
+ buf->st_blksize = kbuf->st_blksize;
+ buf->st_blocks = kbuf->st_blocks;
+ buf->st_atim.tv_sec = kbuf->st_atime_sec;
+ buf->st_atim.tv_nsec = 0;
+ buf->st_mtim.tv_sec = kbuf->st_mtime_sec;
+ buf->st_mtim.tv_nsec = 0;
+ buf->st_ctim.tv_sec = kbuf->st_ctime_sec;
+ buf->st_ctim.tv_nsec = 0;
+ buf->__unused4 = 0;
+ buf->__unused5 = 0;
+ }
+ break;
+
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+__xstat32_conv (int vers, struct stat64 *sbuf, struct stat *buf)
+{
+ struct kernel_stat64 *kbuf;
+
+ /* *stat64 syscalls on sparc64 really fill in struct kernel_stat64,
+ rather than struct stat64. But it is the same size as
+ struct kernel_stat64, so use this hack so that we can reuse
+ i386 {,f,l}xstat{,at}.c routines. */
+ __asm ("" : "=r" (kbuf) : "0" (sbuf));
+ assert (sizeof (struct stat) == sizeof (struct stat64));
+ assert (sizeof (struct stat64) >= sizeof (struct kernel_stat64));
+
+ switch (vers)
+ {
+ case _STAT_VER_LINUX:
+ {
+ /* Convert current kernel version of `struct stat64' to
+ `struct stat'. */
+ buf->st_dev = kbuf->st_dev;
+ buf->__pad1 = 0;
+ buf->st_ino = kbuf->st_ino;
+ buf->st_mode = kbuf->st_mode;
+ buf->st_nlink = kbuf->st_nlink;
+ buf->st_uid = kbuf->st_uid;
+ buf->st_gid = kbuf->st_gid;
+ buf->st_rdev = kbuf->st_rdev;
+ buf->__pad2 = 0;
+ buf->st_size = kbuf->st_size;
+ buf->st_blksize = kbuf->st_blksize;
+ buf->st_blocks = kbuf->st_blocks;
+ buf->st_atim.tv_sec = kbuf->st_atime_sec;
+ buf->st_atim.tv_nsec = kbuf->st_atime_nsec;
+ buf->st_mtim.tv_sec = kbuf->st_mtime_sec;
+ buf->st_mtim.tv_nsec = kbuf->st_mtime_nsec;
+ buf->st_ctim.tv_sec = kbuf->st_ctime_sec;
+ buf->st_ctim.tv_nsec = kbuf->st_ctime_nsec;
+ buf->__unused4 = 0;
+ buf->__unused5 = 0;
+ }
+ break;
+
+ /* If struct stat64 is different from struct stat then
+ _STAT_VER_KERNEL does not make sense. */
+ case _STAT_VER_KERNEL:
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sys/procfs.h b/libc/sysdeps/unix/sysv/linux/sparc/sys/procfs.h
new file mode 100644
index 000000000..2827b1ec3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sys/procfs.h
@@ -0,0 +1,211 @@
+/* Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H 1
+
+/* This is somehow modelled after the file of the same name on SysVr4
+ systems. It provides a definition of the core file format for ELF
+ used on Linux. */
+
+#include <features.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ucontext.h>
+#include <sys/user.h>
+#include <bits/wordsize.h>
+
+__BEGIN_DECLS
+
+#if __WORDSIZE == 64
+
+#define ELF_NGREG 36
+
+typedef struct
+ {
+ unsigned long pr_regs[32];
+ unsigned long pr_fsr;
+ unsigned long pr_gsr;
+ unsigned long pr_fprs;
+ } elf_fpregset_t;
+
+#else /* sparc32 */
+
+#define ELF_NGREG 38
+
+typedef struct
+ {
+ union
+ {
+ unsigned long pr_regs[32];
+ double pr_dregs[16];
+ } pr_fr;
+ unsigned long __unused;
+ unsigned long pr_fsr;
+ unsigned char pr_qcnt;
+ unsigned char pr_q_entrysize;
+ unsigned char pr_en;
+ unsigned int pr_q[64];
+ } elf_fpregset_t;
+
+#endif /* sparc32 */
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+struct elf_siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_code; /* Extra code. */
+ int si_errno; /* Errno. */
+ };
+
+/* Definitions to generate Intel SVR4-like core files. These mostly
+ have the same names as the SVR4 types with "elf_" tacked on the
+ front to prevent clashes with linux definitions, and the typedef
+ forms have been avoided. This is mostly like the SVR4 structure,
+ but more Linuxy, with things that Linux does not support and which
+ gdb doesn't really use excluded. Fields present but not used are
+ marked with "XXX". */
+struct elf_prstatus
+ {
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned long int pr_sigpend; /* Set of pending signals. */
+ unsigned long int pr_sighold; /* Set of held signals. */
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct timeval pr_utime; /* User time. */
+ struct timeval pr_stime; /* System time. */
+ struct timeval pr_cutime; /* Cumulative user time. */
+ struct timeval pr_cstime; /* Cumulative system time. */
+ elf_gregset_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+#define ELF_PRARGSZ (80) /* Number of chars for args */
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long int pr_flag; /* Flags. */
+#if __WORDSIZE == 64
+ unsigned int pr_uid;
+ unsigned int pr_gid;
+#else
+ unsigned short int pr_uid;
+ unsigned short int pr_gid;
+#endif
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+/* Addresses. */
+typedef void *psaddr_t;
+
+/* Register sets. Linux has different names. */
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+ therefore have only one PID type. */
+typedef __pid_t lwpid_t;
+
+
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+#if __WORDSIZE == 64
+
+/* Provide 32-bit variants so that BFD can read 32-bit
+ core files. */
+#define ELF_NGREG32 38
+typedef struct
+ {
+ union
+ {
+ unsigned int pr_regs[32];
+ double pr_dregs[16];
+ } pr_fr;
+ unsigned int __unused;
+ unsigned int pr_fsr;
+ unsigned char pr_qcnt;
+ unsigned char pr_q_entrysize;
+ unsigned char pr_en;
+ unsigned int pr_q[64];
+ } elf_fpregset_t32;
+
+typedef unsigned int elf_greg_t32;
+typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG32];
+
+struct elf_prstatus32
+ {
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned int pr_sigpend; /* Set of pending signals. */
+ unsigned int pr_sighold; /* Set of held signals. */
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct
+ {
+ int tv_sec, tv_usec;
+ } pr_utime, /* User time. */
+ pr_stime, /* System time. */
+ pr_cutime, /* Cumulative user time. */
+ pr_cstime; /* Cumulative system time. */
+ elf_gregset_t32 pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+struct elf_prpsinfo32
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned int pr_flag; /* Flags. */
+ unsigned short int pr_uid;
+ unsigned short int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+typedef elf_gregset_t32 prgregset32_t;
+typedef elf_fpregset_t32 prfpregset32_t;
+
+typedef struct elf_prstatus32 prstatus32_t;
+typedef struct elf_prpsinfo32 prpsinfo32_t;
+
+#endif /* sparc64 */
+
+__END_DECLS
+
+#endif /* sys/procfs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sys/ptrace.h b/libc/sysdeps/unix/sysv/linux/sparc/sys/ptrace.h
new file mode 100644
index 000000000..d573f0e99
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sys/ptrace.h
@@ -0,0 +1,183 @@
+/* `ptrace' debugger support interface. Linux/SPARC version.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PTRACE_H
+#define _SYS_PTRACE_H 1
+
+#include <features.h>
+
+#include <bits/wordsize.h>
+
+/* Linux/SPARC kernels up to 2.3.18 do not care much
+ about what namespace polution, so use a kludge now. */
+#undef PTRACE_GETREGS
+#undef PTRACE_SETREGS
+#undef PTRACE_GETFPREGS
+#undef PTRACE_SETFPREGS
+#undef PTRACE_READDATA
+#undef PTRACE_WRITEDATA
+#undef PTRACE_READTEXT
+#undef PTRACE_WRITETEXT
+#undef PTRACE_SUNDETACH
+
+__BEGIN_DECLS
+
+/* Type of the REQUEST argument to `ptrace.' */
+enum __ptrace_request
+{
+ /* Indicate that the process making this request should be traced.
+ All signals received by this process can be intercepted by its
+ parent, and its parent can use the other `ptrace' requests. */
+ PTRACE_TRACEME = 0,
+#define PT_TRACE_ME PTRACE_TRACEME
+
+ /* Return the word in the process's text space at address ADDR. */
+ PTRACE_PEEKTEXT = 1,
+#define PT_READ_I PTRACE_PEEKTEXT
+
+ /* Return the word in the process's data space at address ADDR. */
+ PTRACE_PEEKDATA = 2,
+#define PT_READ_D PTRACE_PEEKDATA
+
+ /* Return the word in the process's user area at offset ADDR. */
+ PTRACE_PEEKUSER = 3,
+#define PT_READ_U PTRACE_PEEKUSER
+
+ /* Write the word DATA into the process's text space at address ADDR. */
+ PTRACE_POKETEXT = 4,
+#define PT_WRITE_I PTRACE_POKETEXT
+
+ /* Write the word DATA into the process's data space at address ADDR. */
+ PTRACE_POKEDATA = 5,
+#define PT_WRITE_D PTRACE_POKEDATA
+
+ /* Write the word DATA into the process's user area at offset ADDR. */
+ PTRACE_POKEUSER = 6,
+#define PT_WRITE_U PTRACE_POKEUSER
+
+ /* Continue the process. */
+ PTRACE_CONT = 7,
+#define PT_CONTINUE PTRACE_CONT
+
+ /* Kill the process. */
+ PTRACE_KILL = 8,
+#define PT_KILL PTRACE_KILL
+
+ /* Single step the process.
+ This is not supported on all machines. */
+ PTRACE_SINGLESTEP = 9,
+#define PT_STEP PTRACE_SINGLESTEP
+
+ /* Detach from a process attached to with PTRACE_ATTACH. */
+ PTRACE_DETACH = 11,
+#define PT_DETACH PTRACE_DETACH
+
+ /* This define is needed for older programs which were
+ trying to work around sparc-linux ptrace nastiness. */
+#define PTRACE_SUNDETACH PTRACE_DETACH
+
+#if __WORDSIZE == 32
+
+ /* Get all general purpose registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_GETREGS = 12,
+#define PT_GETREGS PTRACE_GETREGS
+
+ /* Set all general purpose registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_SETREGS = 13,
+#define PT_SETREGS PTRACE_SETREGS
+
+ /* Get all floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_GETFPREGS = 14,
+#define PT_GETFPREGS PTRACE_GETFPREGS
+
+ /* Set all floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_SETFPREGS = 15,
+#define PT_SETFPREGS PTRACE_SETFPREGS
+
+#endif
+
+ /* Attach to a process that is already running. */
+ PTRACE_ATTACH = 16,
+#define PT_ATTACH PTRACE_ATTACH
+
+ /* Write several bytes at a time. */
+ PTRACE_WRITEDATA = 17,
+#define PTRACE_WRITEDATA PTRACE_WRITEDATA
+
+ /* Read several bytes at a time. */
+ PTRACE_READTEXT = 18,
+#define PTRACE_READTEXT PTRACE_READTEXT
+#define PTRACE_READDATA PTRACE_READTEXT
+
+ /* Write several bytes at a time. */
+ PTRACE_WRITETEXT = 19,
+#define PTRACE_WRITETEXT PTRACE_WRITETEXT
+
+#if __WORDSIZE == 64
+
+ /* Get all general purpose registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_GETREGS = 22,
+#define PT_GETREGS PTRACE_GETREGS
+
+ /* Set all general purpose registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_SETREGS = 23,
+#define PT_SETREGS PTRACE_SETREGS
+
+#endif
+
+ /* Continue and stop at the next (return from) syscall. */
+ PTRACE_SYSCALL = 24
+#define PTRACE_SYSCALL PTRACE_SYSCALL
+
+#if __WORDSIZE == 64
+
+ ,
+ /* Get all floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_GETFPREGS = 25,
+#define PT_GETFPREGS PTRACE_GETFPREGS
+
+ /* Set all floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_SETFPREGS = 26
+#define PT_SETFPREGS PTRACE_SETFPREGS
+
+#endif
+};
+
+/* Perform process tracing functions. REQUEST is one of the values
+ above, and determines the action to be taken.
+ For all requests except PTRACE_TRACEME, PID specifies the process to be
+ traced.
+
+ PID and the other arguments described above for the various requests should
+ appear (those that are used for the particular request) as:
+ pid_t PID, void *ADDR, int DATA, void *ADDR2
+ after REQUEST. */
+extern long int ptrace (enum __ptrace_request __request, ...) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_PTRACE_H */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sys/trap.h b/libc/sysdeps/unix/sysv/linux/sparc/sys/trap.h
new file mode 100644
index 000000000..99b9c60e0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sys/trap.h
@@ -0,0 +1,7 @@
+/* Include Linux/SPARC specific trap definitions. */
+#ifndef _SYS_TRAP_H
+#define _SYS_TRAP_H 1
+
+#include <asm/traps.h>
+
+#endif /* sys/trap.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sys/ucontext.h b/libc/sysdeps/unix/sysv/linux/sparc/sys/ucontext.h
new file mode 100644
index 000000000..b1102b04c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sys/ucontext.h
@@ -0,0 +1,270 @@
+/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+
+#define MC_TSTATE 0
+#define MC_PC 1
+#define MC_NPC 2
+#define MC_Y 3
+#define MC_G1 4
+#define MC_G2 5
+#define MC_G3 6
+#define MC_G4 7
+#define MC_G5 8
+#define MC_G6 9
+#define MC_G7 10
+#define MC_O0 11
+#define MC_O1 12
+#define MC_O2 13
+#define MC_O3 14
+#define MC_O4 15
+#define MC_O5 16
+#define MC_O6 17
+#define MC_O7 18
+#define MC_NGREG 19
+
+typedef unsigned long mc_greg_t;
+typedef mc_greg_t mc_gregset_t[MC_NGREG];
+
+#define MC_MAXFPQ 16
+struct mc_fq {
+ unsigned long *mcfq_addr;
+ unsigned int mcfq_insn;
+};
+
+struct mc_fpu {
+ union {
+ unsigned int sregs[32];
+ unsigned long dregs[32];
+ long double qregs[16];
+ } mcfpu_fregs;
+ unsigned long mcfpu_fsr;
+ unsigned long mcfpu_fprs;
+ unsigned long mcfpu_gsr;
+ struct mc_fq *mcfpu_fq;
+ unsigned char mcfpu_qcnt;
+ unsigned char mcfpu_qentsz;
+ unsigned char mcfpu_enab;
+};
+typedef struct mc_fpu mc_fpu_t;
+
+typedef struct {
+ mc_gregset_t mc_gregs;
+ mc_greg_t mc_fp;
+ mc_greg_t mc_i7;
+ mc_fpu_t mc_fpregs;
+} mcontext_t;
+
+typedef struct ucontext {
+ struct ucontext *uc_link;
+ unsigned long uc_flags;
+ unsigned long __uc_sigmask;
+ mcontext_t uc_mcontext;
+ stack_t uc_stack;
+ __sigset_t uc_sigmask;
+} ucontext_t;
+
+#endif /* __WORDISIZE == 64 */
+
+/*
+ * Location of the users' stored registers relative to R0.
+ * Usage is as an index into a gregset_t array or as u.u_ar0[XX].
+ */
+#define REG_PSR (0)
+#define REG_PC (1)
+#define REG_nPC (2)
+#define REG_Y (3)
+#define REG_G1 (4)
+#define REG_G2 (5)
+#define REG_G3 (6)
+#define REG_G4 (7)
+#define REG_G5 (8)
+#define REG_G6 (9)
+#define REG_G7 (10)
+#define REG_O0 (11)
+#define REG_O1 (12)
+#define REG_O2 (13)
+#define REG_O3 (14)
+#define REG_O4 (15)
+#define REG_O5 (16)
+#define REG_O6 (17)
+#define REG_O7 (18)
+
+/*
+ * A gregset_t is defined as an array type for compatibility with the reference
+ * source. This is important due to differences in the way the C language
+ * treats arrays and structures as parameters.
+ *
+ * Note that NGREG is really (sizeof (struct regs) / sizeof (greg_t)),
+ * but that the ABI defines it absolutely to be 21 (resp. 19).
+ */
+
+#if __WORDSIZE == 64
+
+#define REG_ASI (19)
+#define REG_FPRS (20)
+
+#define NGREG 21
+typedef long greg_t;
+
+#else /* __WORDSIZE == 32 */
+
+#define NGREG 19
+typedef int greg_t;
+
+#endif /* __WORDSIZE == 32 */
+
+typedef greg_t gregset_t[NGREG];
+
+/*
+ * The following structures define how a register window can appear on the
+ * stack. This structure is available (when required) through the `gwins'
+ * field of an mcontext (nested within ucontext). SPARC_MAXWINDOW is the
+ * maximum number of outstanding regiters window defined in the SPARC
+ * architecture (*not* implementation).
+ */
+#define SPARC_MAXREGWINDOW 31 /* max windows in SPARC arch. */
+struct rwindow
+ {
+ greg_t rw_local[8]; /* locals */
+ greg_t rw_in[8]; /* ins */
+ };
+
+#define rw_fp rw_in[6] /* frame pointer */
+#define rw_rtn rw_in[7] /* return address */
+
+typedef struct gwindows
+ {
+ int wbcnt;
+ int *spbuf[SPARC_MAXREGWINDOW];
+ struct rwindow wbuf[SPARC_MAXREGWINDOW];
+ } gwindows_t;
+
+/*
+ * Floating point definitions.
+ */
+
+#define MAXFPQ 16 /* max # of fpu queue entries currently supported */
+
+/*
+ * struct fq defines the minimal format of a floating point instruction queue
+ * entry. The size of entries in the floating point queue are implementation
+ * dependent. The union FQu is guarenteed to be the first field in any ABI
+ * conformant system implementation. Any additional fields provided by an
+ * implementation should not be used applications designed to be ABI conformant. */
+
+struct fpq
+ {
+ unsigned long *fpq_addr; /* address */
+ unsigned long fpq_instr; /* instruction */
+ };
+
+struct fq
+ {
+ union /* FPU inst/addr queue */
+ {
+ double whole;
+ struct fpq fpq;
+ } FQu;
+ };
+
+#define FPU_REGS_TYPE unsigned
+#define FPU_DREGS_TYPE unsigned long long
+#define V7_FPU_FSR_TYPE unsigned
+#define V9_FPU_FSR_TYPE unsigned long long
+#define V9_FPU_FPRS_TYPE unsigned
+
+#if __WORDSIZE == 64
+
+typedef struct fpu
+ {
+ union { /* FPU floating point regs */
+ unsigned fpu_regs[32]; /* 32 singles */
+ double fpu_dregs[16]; /* 32 doubles */
+ long double fpu_qregs[16]; /* 16 quads */
+ } fpu_fr;
+ struct fq *fpu_q; /* ptr to array of FQ entries */
+ unsigned long fpu_fsr; /* FPU status register */
+ unsigned char fpu_qcnt; /* # of entries in saved FQ */
+ unsigned char fpu_q_entrysize; /* # of bytes per FQ entry */
+ unsigned char fpu_en; /* flag signifying fpu in use */
+ } fpregset_t;
+
+#else /* __WORDSIZE == 32 */
+
+typedef struct fpu
+ {
+ union { /* FPU floating point regs */
+ unsigned long long fpu_regs[32]; /* 32 singles */
+ double fpu_dregs[16]; /* 16 doubles */
+ } fpu_fr;
+ struct fq *fpu_q; /* ptr to array of FQ entries */
+ unsigned fpu_fsr; /* FPU status register */
+ unsigned char fpu_qcnt; /* # of entries in saved FQ */
+ unsigned char fpu_q_entrysize; /* # of bytes per FQ entry */
+ unsigned char fpu_en; /* flag signifying fpu in use */
+ } fpregset_t;
+
+/*
+ * The following structure is for associating extra register state with
+ * the ucontext structure and is kept within the uc_mcontext filler area.
+ *
+ * If (xrs_id == XRS_ID) then the xrs_ptr field is a valid pointer to
+ * extra register state. The exact format of the extra register state
+ * pointed to by xrs_ptr is platform-dependent.
+ *
+ * Note: a platform may or may not manage extra register state.
+ */
+typedef struct
+ {
+ unsigned int xrs_id; /* indicates xrs_ptr validity */
+ void * xrs_ptr; /* ptr to extra reg state */
+ } xrs_t;
+
+#define XRS_ID 0x78727300 /* the string "xrs" */
+
+typedef struct
+ {
+ gregset_t gregs; /* general register set */
+ gwindows_t *gwins; /* POSSIBLE pointer to register windows */
+ fpregset_t fpregs; /* floating point register set */
+ xrs_t xrs; /* POSSIBLE extra register state association */
+ long filler[19];
+ } mcontext_t;
+
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ __sigset_t uc_sigmask;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ } ucontext_t;
+
+#endif /* __WORDSIZE == 32 */
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sys/user.h b/libc/sysdeps/unix/sysv/linux/sparc/sys/user.h
new file mode 100644
index 000000000..2aad01b0f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sys/user.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H 1
+
+struct sunos_regs
+{
+ unsigned int psr, pc, npc, y;
+ unsigned int regs[15];
+};
+
+struct sunos_fpqueue
+{
+ unsigned int *addr;
+ unsigned int inst;
+};
+
+struct sunos_fp
+{
+ union
+ {
+ unsigned int regs[32];
+ double reg_dbls[16];
+ } fregs;
+ unsigned int fsr;
+ unsigned int flags;
+ unsigned int extra;
+ unsigned int fpq_count;
+ struct sunos_fpqueue fpq[16];
+};
+
+struct sunos_fpu
+{
+ struct sunos_fp fpstatus;
+};
+
+/* The SunOS core file header layout. */
+struct user {
+ unsigned int magic;
+ unsigned int len;
+ struct sunos_regs regs;
+ struct
+ {
+ unsigned char a_dynamic :1;
+ unsigned char a_toolversion :7;
+ unsigned char a_machtype;
+ unsigned short a_info;
+ unsigned int a_text;
+ unsigned int a_data;
+ unsigned int a_bss;
+ unsigned int a_syms;
+ unsigned int a_entry;
+ unsigned int a_trsize;
+ unsigned int a_drsize;
+ } uexec;
+ int signal;
+ size_t u_tsize;
+ size_t u_dsize;
+ size_t u_ssize;
+ char u_comm[17];
+ struct sunos_fpu fpu;
+ unsigned int sigcode;
+};
+
+#define NBPG 0x2000
+#define UPAGES 1
+#define SUNOS_CORE_MAGIC 0x080456
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/syscalls.list b/libc/sysdeps/unix/sysv/linux/sparc/syscalls.list
new file mode 100644
index 000000000..a6665936e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/syscalls.list
@@ -0,0 +1,3 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+waitpid - waitpid Ci:ipi __waitpid waitpid __libc_waitpid
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sysdep.c b/libc/sysdeps/unix/sysv/linux/sparc/sysdep.c
new file mode 100644
index 000000000..f86414570
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sysdep.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/powerpc/sysdep.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sysdep.h b/libc/sysdeps/unix/sysv/linux/sparc/sysdep.h
new file mode 100644
index 000000000..a60937976
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sysdep.h
@@ -0,0 +1,153 @@
+/* Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINUX_SPARC_SYSDEP_H
+#define _LINUX_SPARC_SYSDEP_H 1
+
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+ inline_syscall##nr(__SYSCALL_STRING, __NR_##name, args)
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ inline_syscall##nr(__INTERNAL_SYSCALL_STRING, __NR_##name, args)
+
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ inline_syscall##nr(__INTERNAL_SYSCALL_STRING, name, args)
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((unsigned long) (val) >= -515L)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+
+#define inline_syscall0(string,name,dummy...) \
+({ \
+ register long __o0 __asm__ ("o0"); \
+ register long __g1 __asm__ ("g1") = name; \
+ __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \
+ "0" (__g1) : \
+ __SYSCALL_CLOBBERS); \
+ __o0; \
+})
+
+#define inline_syscall1(string,name,arg1) \
+({ \
+ register long __o0 __asm__ ("o0") = (long)(arg1); \
+ register long __g1 __asm__ ("g1") = name; \
+ __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \
+ "0" (__g1), "1" (__o0) : \
+ __SYSCALL_CLOBBERS); \
+ __o0; \
+})
+
+#define inline_syscall2(string,name,arg1,arg2) \
+({ \
+ register long __o0 __asm__ ("o0") = (long)(arg1); \
+ register long __o1 __asm__ ("o1") = (long)(arg2); \
+ register long __g1 __asm__ ("g1") = name; \
+ __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \
+ "0" (__g1), "1" (__o0), "r" (__o1) : \
+ __SYSCALL_CLOBBERS); \
+ __o0; \
+})
+
+#define inline_syscall3(string,name,arg1,arg2,arg3) \
+({ \
+ register long __o0 __asm__ ("o0") = (long)(arg1); \
+ register long __o1 __asm__ ("o1") = (long)(arg2); \
+ register long __o2 __asm__ ("o2") = (long)(arg3); \
+ register long __g1 __asm__ ("g1") = name; \
+ __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \
+ "0" (__g1), "1" (__o0), "r" (__o1), \
+ "r" (__o2) : \
+ __SYSCALL_CLOBBERS); \
+ __o0; \
+})
+
+#define inline_syscall4(string,name,arg1,arg2,arg3,arg4) \
+({ \
+ register long __o0 __asm__ ("o0") = (long)(arg1); \
+ register long __o1 __asm__ ("o1") = (long)(arg2); \
+ register long __o2 __asm__ ("o2") = (long)(arg3); \
+ register long __o3 __asm__ ("o3") = (long)(arg4); \
+ register long __g1 __asm__ ("g1") = name; \
+ __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \
+ "0" (__g1), "1" (__o0), "r" (__o1), \
+ "r" (__o2), "r" (__o3) : \
+ __SYSCALL_CLOBBERS); \
+ __o0; \
+})
+
+#define inline_syscall5(string,name,arg1,arg2,arg3,arg4,arg5) \
+({ \
+ register long __o0 __asm__ ("o0") = (long)(arg1); \
+ register long __o1 __asm__ ("o1") = (long)(arg2); \
+ register long __o2 __asm__ ("o2") = (long)(arg3); \
+ register long __o3 __asm__ ("o3") = (long)(arg4); \
+ register long __o4 __asm__ ("o4") = (long)(arg5); \
+ register long __g1 __asm__ ("g1") = name; \
+ __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \
+ "0" (__g1), "1" (__o0), "r" (__o1), \
+ "r" (__o2), "r" (__o3), "r" (__o4) : \
+ __SYSCALL_CLOBBERS); \
+ __o0; \
+})
+
+#define inline_syscall6(string,name,arg1,arg2,arg3,arg4,arg5,arg6) \
+({ \
+ register long __o0 __asm__ ("o0") = (long)(arg1); \
+ register long __o1 __asm__ ("o1") = (long)(arg2); \
+ register long __o2 __asm__ ("o2") = (long)(arg3); \
+ register long __o3 __asm__ ("o3") = (long)(arg4); \
+ register long __o4 __asm__ ("o4") = (long)(arg5); \
+ register long __o5 __asm__ ("o5") = (long)(arg6); \
+ register long __g1 __asm__ ("g1") = name; \
+ __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \
+ "0" (__g1), "1" (__o0), "r" (__o1), \
+ "r" (__o2), "r" (__o3), "r" (__o4), \
+ "r" (__o5) : \
+ __SYSCALL_CLOBBERS); \
+ __o0; \
+})
+
+#define INLINE_CLONE_SYSCALL(arg1,arg2,arg3,arg4,arg5) \
+({ \
+ register long __o0 __asm__ ("o0") = (long)(arg1); \
+ register long __o1 __asm__ ("o1") = (long)(arg2); \
+ register long __o2 __asm__ ("o2") = (long)(arg3); \
+ register long __o3 __asm__ ("o3") = (long)(arg4); \
+ register long __o4 __asm__ ("o4") = (long)(arg5); \
+ register long __g1 __asm__ ("g1") = __NR_clone; \
+ __asm __volatile (__CLONE_SYSCALL_STRING : \
+ "=r" (__g1), "=r" (__o0), "=r" (__o1) : \
+ "0" (__g1), "1" (__o0), "2" (__o1), \
+ "r" (__o2), "r" (__o3), "r" (__o4) : \
+ __SYSCALL_CLOBBERS); \
+ __o0; \
+})
+
+
+
+#endif /* _LINUX_SPARC_SYSDEP_H */
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/system.c b/libc/sysdeps/unix/sysv/linux/sparc/system.c
new file mode 100644
index 000000000..22bef622d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/system.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <kernel-features.h>
+
+/* We have to and actually can handle cancelable system(). The big
+ problem: we have to kill the child process if necessary. To do
+ this a cleanup handler has to be registered and is has to be able
+ to find the PID of the child. The main problem is to reliable have
+ the PID when needed. It is not necessary for the parent thread to
+ return. It might still be in the kernel when the cancellation
+ request comes. Therefore we have to use the clone() calls ability
+ to have the kernel write the PID into the user-level variable. */
+#ifdef __ASSUME_CLONE_THREAD_FLAGS
+# define FORK() \
+ INLINE_CLONE_SYSCALL (CLONE_PARENT_SETTID | SIGCHLD, 0, &pid, NULL, NULL)
+#endif
+
+#include "../system.c"
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/vfork.S b/libc/sysdeps/unix/sysv/linux/sparc/vfork.S
new file mode 100644
index 000000000..eda860e46
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sparc/vfork.S
@@ -0,0 +1,29 @@
+/* Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jj@ultra.linux.cz>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+PSEUDO (__vfork, vfork, 0)
+ sub %o1, 1, %o1
+ retl
+ and %o0, %o1, %o0
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+weak_alias (__vfork, vfork)
diff --git a/libc/sysdeps/unix/sysv/linux/speed.c b/libc/sysdeps/unix/sysv/linux/speed.c
new file mode 100644
index 000000000..ba394cb05
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/speed.c
@@ -0,0 +1,111 @@
+/* `struct termios' speed frobnication functions. Linux version.
+ Copyright (C) 1991,1992,1993,1995,1996,1997,1998,2000,2002,2003
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <errno.h>
+#include <termios.h>
+
+
+/* This is a gross hack around a kernel bug. If the cfsetispeed functions
+ is called with the SPEED argument set to zero this means use the same
+ speed as for output. But we don't have independent input and output
+ speeds and therefore cannot record this.
+
+ We use an unused bit in the `c_iflag' field to keep track of this
+ use of `cfsetispeed'. The value here must correspond to the one used
+ in `tcsetattr.c'. */
+#define IBAUD0 020000000000
+
+
+/* Return the output baud rate stored in *TERMIOS_P. */
+speed_t
+cfgetospeed (termios_p)
+ const struct termios *termios_p;
+{
+ return termios_p->c_cflag & (CBAUD | CBAUDEX);
+}
+
+/* Return the input baud rate stored in *TERMIOS_P.
+ Although for Linux there is no difference between input and output
+ speed, the numerical 0 is a special case for the input baud rate. It
+ should set the input baud rate to the output baud rate. */
+speed_t
+cfgetispeed (termios_p)
+ const struct termios *termios_p;
+{
+ return ((termios_p->c_iflag & IBAUD0)
+ ? 0 : termios_p->c_cflag & (CBAUD | CBAUDEX));
+}
+
+/* Set the output baud rate stored in *TERMIOS_P to SPEED. */
+int
+cfsetospeed (termios_p, speed)
+ struct termios *termios_p;
+ speed_t speed;
+{
+ if ((speed & ~CBAUD) != 0
+ && (speed < B57600 || speed > __MAX_BAUD))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+#ifdef _HAVE_STRUCT_TERMIOS_C_OSPEED
+ termios_p->c_ospeed = speed;
+#endif
+ termios_p->c_cflag &= ~(CBAUD | CBAUDEX);
+ termios_p->c_cflag |= speed;
+
+ return 0;
+}
+libc_hidden_def (cfsetospeed)
+
+
+/* Set the input baud rate stored in *TERMIOS_P to SPEED.
+ Although for Linux there is no difference between input and output
+ speed, the numerical 0 is a special case for the input baud rate. It
+ should set the input baud rate to the output baud rate. */
+int
+cfsetispeed (termios_p, speed)
+ struct termios *termios_p;
+ speed_t speed;
+{
+ if ((speed & ~CBAUD) != 0
+ && (speed < B57600 || speed > __MAX_BAUD))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+#ifdef _HAVE_STRUCT_TERMIOS_C_ISPEED
+ termios_p->c_ispeed = speed;
+#endif
+ if (speed == 0)
+ termios_p->c_iflag |= IBAUD0;
+ else
+ {
+ termios_p->c_iflag &= ~IBAUD0;
+ termios_p->c_cflag &= ~(CBAUD | CBAUDEX);
+ termios_p->c_cflag |= speed;
+ }
+
+ return 0;
+}
+libc_hidden_def (cfsetispeed)
diff --git a/libc/sysdeps/unix/sysv/linux/statfs64.c b/libc/sysdeps/unix/sysv/linux/statfs64.c
new file mode 100644
index 000000000..9ccc7a7d6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/statfs64.c
@@ -0,0 +1,74 @@
+/* Return information about the filesystem on which FILE resides.
+ Copyright (C) 1996-2000,2003,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/statfs.h>
+#include <stddef.h>
+#include <sysdep.h>
+
+
+# if __ASSUME_STATFS64 == 0
+int __no_statfs64 attribute_hidden;
+#endif
+
+/* Return information about the filesystem on which FILE resides. */
+int
+__statfs64 (const char *file, struct statfs64 *buf)
+{
+#ifdef __NR_statfs64
+# if __ASSUME_STATFS64 == 0
+ if (! __no_statfs64)
+# endif
+ {
+ int result = INLINE_SYSCALL (statfs64, 3, file, sizeof (*buf), buf);
+
+# if __ASSUME_STATFS64 == 0
+ if (result == 0 || errno != ENOSYS)
+# endif
+ return result;
+
+# if __ASSUME_STATFS64 == 0
+ __no_statfs64 = 1;
+# endif
+ }
+#endif
+
+#if __ASSUME_STATFS64 == 0
+ struct statfs buf32;
+
+ if (__statfs (file, &buf32) < 0)
+ return -1;
+
+ buf->f_type = buf32.f_type;
+ buf->f_bsize = buf32.f_bsize;
+ buf->f_blocks = buf32.f_blocks;
+ buf->f_bfree = buf32.f_bfree;
+ buf->f_bavail = buf32.f_bavail;
+ buf->f_files = buf32.f_files;
+ buf->f_ffree = buf32.f_ffree;
+ buf->f_fsid = buf32.f_fsid;
+ buf->f_namelen = buf32.f_namelen;
+ buf->f_frsize = buf32.f_frsize;
+ memcpy (buf->f_spare, buf32.f_spare, sizeof (buf32.f_spare));
+
+ return 0;
+#endif
+}
+weak_alias (__statfs64, statfs64)
diff --git a/libc/sysdeps/unix/sysv/linux/statvfs.c b/libc/sysdeps/unix/sysv/linux/statvfs.c
new file mode 100644
index 000000000..51d4f4fd0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/statvfs.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+extern void __internal_statvfs (const char *name, struct statvfs *buf,
+ struct statfs *fsbuf, struct stat64 *st);
+
+
+int
+statvfs (const char *file, struct statvfs *buf)
+{
+ struct statfs fsbuf;
+ struct stat64 st;
+
+ /* Get as much information as possible from the system. */
+ if (__statfs (file, &fsbuf) < 0)
+ return -1;
+
+ /* Convert the result. */
+ __internal_statvfs (file, buf, &fsbuf,
+ stat64 (file, &st) == -1 ? NULL : &st);
+
+ /* We signal success if the statfs call succeeded. */
+ return 0;
+}
+libc_hidden_def (statvfs)
diff --git a/libc/sysdeps/unix/sysv/linux/statvfs64.c b/libc/sysdeps/unix/sysv/linux/statvfs64.c
new file mode 100644
index 000000000..bcef1d3af
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/statvfs64.c
@@ -0,0 +1,74 @@
+/* Return information about the filesystem on which FILE resides.
+ Copyright (C) 1998, 2000, 2001, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+#include <kernel-features.h>
+
+
+extern void __internal_statvfs64 (const char *name, struct statvfs64 *buf,
+ struct statfs64 *fsbuf, struct stat64 *st);
+
+
+/* Return information about the filesystem on which FILE resides. */
+int
+__statvfs64 (const char *file, struct statvfs64 *buf)
+{
+ struct statfs64 fsbuf;
+ int res = __statfs64 (file, &fsbuf);
+
+#ifndef __ASSUME_STATFS64
+ if (res < 0 && errno == ENOSYS)
+ {
+ struct statvfs buf32;
+
+ res = statvfs (file, &buf32);
+ if (res == 0)
+ {
+ buf->f_bsize = buf32.f_bsize;
+ buf->f_frsize = buf32.f_frsize;
+ buf->f_blocks = buf32.f_blocks;
+ buf->f_bfree = buf32.f_bfree;
+ buf->f_bavail = buf32.f_bavail;
+ buf->f_files = buf32.f_files;
+ buf->f_ffree = buf32.f_ffree;
+ buf->f_favail = buf32.f_favail;
+ buf->f_fsid = buf32.f_fsid;
+ buf->f_flag = buf32.f_flag;
+ buf->f_namemax = buf32.f_namemax;
+ memcpy (buf->__f_spare, buf32.__f_spare, sizeof (buf32.__f_spare));
+ }
+ }
+#endif
+
+ if (res == 0)
+ {
+ /* Convert the result. */
+ struct stat64 st;
+ __internal_statvfs64 (file, buf, &fsbuf,
+ stat64 (file, &st) == -1 ? NULL : &st);
+ }
+
+ return res;
+}
+weak_alias (__statvfs64, statvfs64)
diff --git a/libc/sysdeps/unix/sysv/linux/symlinkat.c b/libc/sysdeps/unix/sysv/linux/symlinkat.c
new file mode 100644
index 000000000..4cfc924bf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/symlinkat.c
@@ -0,0 +1,87 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysdep.h>
+#include <unistd.h>
+#include <kernel-features.h>
+
+
+/* Make a symbolic link to FROM named TO relative to TOFD. */
+int
+symlinkat (from, tofd, to)
+ const char *from;
+ int tofd;
+ const char *to;
+{
+ int result;
+
+#ifdef __NR_symlinkat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INLINE_SYSCALL (symlinkat, 3, from, tofd, to);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ char *buf = NULL;
+
+ if (tofd != AT_FDCWD && to[0] != '/')
+ {
+ size_t tolen = strlen (to);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + tolen;
+ buf = __alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, tofd, to);
+ to = buf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+ result = INTERNAL_SYSCALL (symlink, err, 2, from, to);
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ {
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), tofd, buf);
+ result = -1;
+ }
+
+ return result;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/sync_file_range.c b/libc/sysdeps/unix/sysv/linux/sync_file_range.c
new file mode 100644
index 000000000..7519bb7fe
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sync_file_range.c
@@ -0,0 +1,47 @@
+/* Selective file content synch'ing.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+
+#ifdef __NR_sync_file_range
+int
+sync_file_range (int fd, __off64_t from, __off64_t to, int flags)
+{
+ return INLINE_SYSCALL (sync_file_range, 6, fd,
+ __LONG_LONG_PAIR ((long) (from >> 32), (long) from),
+ __LONG_LONG_PAIR ((long) (to >> 32), (long) to),
+ flags);
+}
+#else
+int
+sync_file_range (int fd, __off64_t from, __off64_t to, int flags)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+stub_warning (sync_file_range)
+
+# include <stub-tag.h>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sys/acct.h b/libc/sysdeps/unix/sysv/linux/sys/acct.h
new file mode 100644
index 000000000..9ee8564f7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/acct.h
@@ -0,0 +1,77 @@
+/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_ACCT_H
+#define _SYS_ACCT_H 1
+
+#include <features.h>
+
+#define __need_time_t
+#include <time.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+#define ACCT_COMM 16
+
+/*
+ comp_t is a 16-bit "floating" point number with a 3-bit base 8
+ exponent and a 13-bit fraction. See linux/kernel/acct.c for the
+ specific encoding system used.
+*/
+
+typedef u_int16_t comp_t;
+
+struct acct
+ {
+ char ac_flag; /* Accounting flags. */
+ u_int16_t ac_uid; /* Accounting user ID. */
+ u_int16_t ac_gid; /* Accounting group ID. */
+ u_int16_t ac_tty; /* Controlling tty. */
+ u_int32_t ac_btime; /* Beginning time. */
+ comp_t ac_utime; /* Accounting user time. */
+ comp_t ac_stime; /* Accounting system time. */
+ comp_t ac_etime; /* Accounting elapsed time. */
+ comp_t ac_mem; /* Accounting average memory usage. */
+ comp_t ac_io; /* Accounting chars transferred. */
+ comp_t ac_rw; /* Accounting blocks read or written. */
+ comp_t ac_minflt; /* Accounting minor pagefaults. */
+ comp_t ac_majflt; /* Accounting major pagefaults. */
+ comp_t ac_swaps; /* Accounting number of swaps. */
+ u_int32_t ac_exitcode; /* Accounting process exitcode. */
+ char ac_comm[ACCT_COMM+1]; /* Accounting command name. */
+ char ac_pad[10]; /* Accounting padding bytes. */
+ };
+
+enum
+ {
+ AFORK = 0x01, /* Has executed fork, but no exec. */
+ ASU = 0x02, /* Used super-user privileges. */
+ ACORE = 0x08, /* Dumped core. */
+ AXSIG = 0x10 /* Killed by a signal. */
+ };
+
+#define AHZ 100
+
+
+/* Switch process accounting on and off. */
+extern int acct (__const char *__filename) __THROW;
+
+__END_DECLS
+
+#endif /* sys/acct.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/epoll.h b/libc/sysdeps/unix/sysv/linux/sys/epoll.h
new file mode 100644
index 000000000..68f173a04
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/epoll.h
@@ -0,0 +1,110 @@
+/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_EPOLL_H
+#define _SYS_EPOLL_H 1
+
+#include <stdint.h>
+#include <sys/types.h>
+
+
+enum EPOLL_EVENTS
+ {
+ EPOLLIN = 0x001,
+#define EPOLLIN EPOLLIN
+ EPOLLPRI = 0x002,
+#define EPOLLPRI EPOLLPRI
+ EPOLLOUT = 0x004,
+#define EPOLLOUT EPOLLOUT
+ EPOLLRDNORM = 0x040,
+#define EPOLLRDNORM EPOLLRDNORM
+ EPOLLRDBAND = 0x080,
+#define EPOLLRDBAND EPOLLRDBAND
+ EPOLLWRNORM = 0x100,
+#define EPOLLWRNORM EPOLLWRNORM
+ EPOLLWRBAND = 0x200,
+#define EPOLLWRBAND EPOLLWRBAND
+ EPOLLMSG = 0x400,
+#define EPOLLMSG EPOLLMSG
+ EPOLLERR = 0x008,
+#define EPOLLERR EPOLLERR
+ EPOLLHUP = 0x010,
+#define EPOLLHUP EPOLLHUP
+ EPOLLONESHOT = (1 << 30),
+#define EPOLLONESHOT EPOLLONESHOT
+ EPOLLET = (1 << 31)
+#define EPOLLET EPOLLET
+ };
+
+
+/* Valid opcodes ( "op" parameter ) to issue to epoll_ctl(). */
+#define EPOLL_CTL_ADD 1 /* Add a file decriptor to the interface. */
+#define EPOLL_CTL_DEL 2 /* Remove a file decriptor from the interface. */
+#define EPOLL_CTL_MOD 3 /* Change file decriptor epoll_event structure. */
+
+
+typedef union epoll_data
+{
+ void *ptr;
+ int fd;
+ uint32_t u32;
+ uint64_t u64;
+} epoll_data_t;
+
+struct epoll_event
+{
+ uint32_t events; /* Epoll events */
+ epoll_data_t data; /* User data variable */
+};
+
+
+__BEGIN_DECLS
+
+/* Creates an epoll instance. Returns an fd for the new instance.
+ The "size" parameter is a hint specifying the number of file
+ descriptors to be associated with the new instance. The fd
+ returned by epoll_create() should be closed with close(). */
+extern int epoll_create (int __size) __THROW;
+
+
+/* Manipulate an epoll instance "epfd". Returns 0 in case of success,
+ -1 in case of error ( the "errno" variable will contain the
+ specific error code ) The "op" parameter is one of the EPOLL_CTL_*
+ constants defined above. The "fd" parameter is the target of the
+ operation. The "event" parameter describes which events the caller
+ is interested in and any associated user data. */
+extern int epoll_ctl (int __epfd, int __op, int __fd,
+ struct epoll_event *__event) __THROW;
+
+
+/* Wait for events on an epoll instance "epfd". Returns the number of
+ triggered events returned in "events" buffer. Or -1 in case of
+ error with the "errno" variable set to the specific error code. The
+ "events" parameter is a buffer that will contain triggered
+ events. The "maxevents" is the maximum number of events to be
+ returned ( usually size of "events" ). The "timeout" parameter
+ specifies the maximum wait time in milliseconds (-1 == infinite).
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int epoll_wait (int __epfd, struct epoll_event *__events,
+ int __maxevents, int __timeout);
+
+__END_DECLS
+
+#endif /* sys/epoll.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/fsuid.h b/libc/sysdeps/unix/sysv/linux/sys/fsuid.h
new file mode 100644
index 000000000..4ecb19918
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/fsuid.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_FSUID_H
+#define _SYS_FSUID_H 1
+
+#include <features.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+/* Change uid used for file access control to UID, without affecting
+ other privileges (such as who can send signals at the process). */
+extern int setfsuid (__uid_t __uid) __THROW;
+
+/* Ditto for group id. */
+extern int setfsgid (__gid_t __gid) __THROW;
+
+__END_DECLS
+
+#endif /* fsuid.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/inotify.h b/libc/sysdeps/unix/sysv/linux/sys/inotify.h
new file mode 100644
index 000000000..0131db9d3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/inotify.h
@@ -0,0 +1,92 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_INOTIFY_H
+#define _SYS_INOTIFY_H 1
+
+#include <stdint.h>
+
+
+/* Structure describing an inotify event. */
+struct inotify_event
+{
+ int wd; /* Watch descriptor. */
+ uint32_t mask; /* Watch mask. */
+ uint32_t cookie; /* Cookie to synchronize two events. */
+ uint32_t len; /* Length (including NULs) of name. */
+ char name __flexarr; /* Name. */
+};
+
+
+/* Supported events suitable for MASK parameter of INOTIFY_ADD_WATCH. */
+#define IN_ACCESS 0x00000001 /* File was accessed. */
+#define IN_MODIFY 0x00000002 /* File was modified. */
+#define IN_ATTRIB 0x00000004 /* Metadata changed. */
+#define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed. */
+#define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed. */
+#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* Close. */
+#define IN_OPEN 0x00000020 /* File was opened. */
+#define IN_MOVED_FROM 0x00000040 /* File was moved from X. */
+#define IN_MOVED_TO 0x00000080 /* File was moved to Y. */
+#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* Moves. */
+#define IN_CREATE 0x00000100 /* Subfile was created. */
+#define IN_DELETE 0x00000200 /* Subfile was deleted. */
+#define IN_DELETE_SELF 0x00000400 /* Self was deleted. */
+#define IN_MOVE_SELF 0x00000800 /* Self was moved. */
+
+/* Events sent by the kernel. */
+#define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted. */
+#define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed. */
+#define IN_IGNORED 0x00008000 /* File was ignored. */
+
+/* Helper events. */
+#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* Close. */
+#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* Moves. */
+
+/* Special flags. */
+#define IN_ONLYDIR 0x01000000 /* Only watch the path if it is a
+ directory. */
+#define IN_DONT_FOLLOW 0x02000000 /* Do not follow a sym link. */
+#define IN_MASK_ADD 0x20000000 /* Add to the mask of an already
+ existing watch. */
+#define IN_ISDIR 0x40000000 /* Event occurred against dir. */
+#define IN_ONESHOT 0x80000000 /* Only send event once. */
+
+/* All events which a program can wait on. */
+#define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE \
+ | IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM \
+ | IN_MOVED_TO | IN_CREATE | IN_DELETE \
+ | IN_DELETE_SELF | IN_MOVE_SELF)
+
+
+__BEGIN_DECLS
+
+/* Create and initialize inotify instance. */
+extern int inotify_init (void) __THROW;
+
+/* Add watch of object NAME to inotify instance FD. Notify about
+ events specified by MASK. */
+extern int inotify_add_watch (int __fd, const char *__name, uint32_t __mask)
+ __THROW;
+
+/* Remove the watch specified by WD from the inotify instance FD. */
+extern int inotify_rm_watch (int __fd, uint32_t __wd) __THROW;
+
+__END_DECLS
+
+#endif /* sys/inotify.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/kd.h b/libc/sysdeps/unix/sysv/linux/sys/kd.h
new file mode 100644
index 000000000..d459c079e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/kd.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_KD_H
+#define _SYS_KD_H 1
+
+/* Make sure the <linux/types.h> header is not loaded. */
+#ifndef _LINUX_TYPES_H
+# define _LINUX_TYPES_H 1
+# define __undef_LINUX_TYPES_H
+#endif
+
+#include <linux/kd.h>
+
+#ifdef __undef_LINUX_TYPES_H
+# undef _LINUX_TYPES_H
+# undef __undef_LINUX_TYPES_H
+#endif
+
+#endif /* sys/kd.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/kdaemon.h b/libc/sysdeps/unix/sysv/linux/sys/kdaemon.h
new file mode 100644
index 000000000..61491f93d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/kdaemon.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 1996, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Interfaces to control the various kernel daemons. */
+
+#ifndef _SYS_KDAEMON_H
+
+#define _SYS_KDAEMON_H 1
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Start, flush, or tune the kernel's buffer flushing daemon. */
+extern int bdflush (int __func, long int __data) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_KDAEMON_H */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/klog.h b/libc/sysdeps/unix/sysv/linux/sys/klog.h
new file mode 100644
index 000000000..35f5fe40e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/klog.h
@@ -0,0 +1,34 @@
+/* Copyright (C) 1996, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_KLOG_H
+
+#define _SYS_KLOG_H 1
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Control the kernel's logging facility. This corresponds exactly to
+ the kernel's syslog system call, but that name is easily confused
+ with the user-level syslog facility, which is something completely
+ different. */
+extern int klogctl (int __type, char *__bufp, int __len) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_KLOG_H */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/mount.h b/libc/sysdeps/unix/sysv/linux/sys/mount.h
new file mode 100644
index 000000000..b30554987
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/mount.h
@@ -0,0 +1,119 @@
+/* Header file for mounting/unmount Linux filesystems.
+ Copyright (C) 1996,1997,1998,1999,2000,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This is taken from /usr/include/linux/fs.h. */
+
+#ifndef _SYS_MOUNT_H
+#define _SYS_MOUNT_H 1
+
+#include <features.h>
+#include <sys/ioctl.h>
+
+#define BLOCK_SIZE 1024
+#define BLOCK_SIZE_BITS 10
+
+
+/* These are the fs-independent mount-flags: up to 16 flags are
+ supported */
+enum
+{
+ MS_RDONLY = 1, /* Mount read-only. */
+#define MS_RDONLY MS_RDONLY
+ MS_NOSUID = 2, /* Ignore suid and sgid bits. */
+#define MS_NOSUID MS_NOSUID
+ MS_NODEV = 4, /* Disallow access to device special files. */
+#define MS_NODEV MS_NODEV
+ MS_NOEXEC = 8, /* Disallow program execution. */
+#define MS_NOEXEC MS_NOEXEC
+ MS_SYNCHRONOUS = 16, /* Writes are synced at once. */
+#define MS_SYNCHRONOUS MS_SYNCHRONOUS
+ MS_REMOUNT = 32, /* Alter flags of a mounted FS. */
+#define MS_REMOUNT MS_REMOUNT
+ MS_MANDLOCK = 64, /* Allow mandatory locks on an FS. */
+#define MS_MANDLOCK MS_MANDLOCK
+ S_WRITE = 128, /* Write on file/directory/symlink. */
+#define S_WRITE S_WRITE
+ S_APPEND = 256, /* Append-only file. */
+#define S_APPEND S_APPEND
+ S_IMMUTABLE = 512, /* Immutable file. */
+#define S_IMMUTABLE S_IMMUTABLE
+ MS_NOATIME = 1024, /* Do not update access times. */
+#define MS_NOATIME MS_NOATIME
+ MS_NODIRATIME = 2048, /* Do not update directory access times. */
+#define MS_NODIRATIME MS_NODIRATIME
+ MS_BIND = 4096, /* Bind directory at different place. */
+#define MS_BIND MS_BIND
+};
+
+/* Flags that can be altered by MS_REMOUNT */
+#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME \
+ |MS_NODIRATIME)
+
+
+/* Magic mount flag number. Has to be or-ed to the flag values. */
+
+#define MS_MGC_VAL 0xc0ed0000 /* Magic flag number to indicate "new" flags */
+#define MS_MGC_MSK 0xffff0000 /* Magic flag number mask */
+
+
+/* The read-only stuff doesn't really belong here, but any other place
+ is probably as bad and I don't want to create yet another include
+ file. */
+
+#define BLKROSET _IO(0x12, 93) /* Set device read-only (0 = read-write). */
+#define BLKROGET _IO(0x12, 94) /* Get read-only status (0 = read_write). */
+#define BLKRRPART _IO(0x12, 95) /* Re-read partition table. */
+#define BLKGETSIZE _IO(0x12, 96) /* Return device size. */
+#define BLKFLSBUF _IO(0x12, 97) /* Flush buffer cache. */
+#define BLKRASET _IO(0x12, 98) /* Set read ahead for block device. */
+#define BLKRAGET _IO(0x12, 99) /* Get current read ahead setting. */
+#define BLKFRASET _IO(0x12,100) /* Set filesystem read-ahead. */
+#define BLKFRAGET _IO(0x12,101) /* Get filesystem read-ahead. */
+#define BLKSECTSET _IO(0x12,102) /* Set max sectors per request. */
+#define BLKSECTGET _IO(0x12,103) /* Get max sectors per request. */
+#define BLKSSZGET _IO(0x12,104) /* Get block device sector size. */
+#define BLKBSZGET _IOR(0x12,112,size_t)
+#define BLKBSZSET _IOW(0x12,113,size_t)
+#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size. */
+
+
+/* Possible value for FLAGS parameter of `umount2'. */
+enum
+{
+ MNT_FORCE = 1 /* Force unmounting. */
+#define MNT_FORCE MNT_FORCE
+};
+
+
+__BEGIN_DECLS
+
+/* Mount a filesystem. */
+extern int mount (__const char *__special_file, __const char *__dir,
+ __const char *__fstype, unsigned long int __rwflag,
+ __const void *__data) __THROW;
+
+/* Unmount a filesystem. */
+extern int umount (__const char *__special_file) __THROW;
+
+/* Unmount a filesystem. Force unmounting if FLAGS is set to MNT_FORCE. */
+extern int umount2 (__const char *__special_file, int __flags) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_MOUNT_H */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/param.h b/libc/sysdeps/unix/sysv/linux/sys/param.h
new file mode 100644
index 000000000..0b0424eb9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/param.h
@@ -0,0 +1,72 @@
+/* Copyright (C) 1995,1996,1997,2000,2001,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PARAM_H
+#define _SYS_PARAM_H 1
+
+#include <limits.h>
+#include <linux/limits.h>
+#include <linux/param.h>
+
+/* BSD names for some <limits.h> values. */
+
+#define NBBY CHAR_BIT
+#ifndef NGROUPS
+# define NGROUPS NGROUPS_MAX
+#endif
+#define MAXSYMLINKS 20
+#define CANBSIZ MAX_CANON
+#define NCARGS ARG_MAX
+#define MAXPATHLEN PATH_MAX
+/* The following is not really correct but it is a value we used for a
+ long time and which seems to be usable. People should not use NOFILE
+ anyway. */
+#define NOFILE 256
+
+
+#include <sys/types.h>
+
+/* Bit map related macros. */
+#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
+#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
+#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+
+/* Macros for counting and rounding. */
+#ifndef howmany
+# define howmany(x, y) (((x) + ((y) - 1)) / (y))
+#endif
+#ifdef __GNUC__
+# define roundup(x, y) (__builtin_constant_p (y) && powerof2 (y) \
+ ? (((x) + (y) - 1) & ~((y) - 1)) \
+ : ((((x) + ((y) - 1)) / (y)) * (y)))
+#else
+# define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
+#endif
+#define powerof2(x) ((((x) - 1) & (x)) == 0)
+
+/* Macros for min/max. */
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
+
+/* Unit of `st_blocks'. */
+#define DEV_BSIZE 512
+
+
+#endif /* sys/param.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/pci.h b/libc/sysdeps/unix/sysv/linux/sys/pci.h
new file mode 100644
index 000000000..fb26269b4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/pci.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PCI_H
+#define _SYS_PCI_H 1
+
+/* We use the constants from the kernel. */
+#include <linux/pci.h>
+
+#endif /* sys/pci.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/personality.h b/libc/sysdeps/unix/sysv/linux/sys/personality.h
new file mode 100644
index 000000000..5d14a9bc8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/personality.h
@@ -0,0 +1,73 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Taken verbatim from Linux 2.4 (include/linux/personality.h). */
+
+#ifndef _SYS_PERSONALITY_H
+#define _SYS_PERSONALITY_H 1
+
+#include <features.h>
+
+/* Flags for bug emulation.
+ These occupy the top three bytes. */
+enum
+ {
+ MMAP_PAGE_ZERO = 0x0100000,
+ ADDR_LIMIT_32BIT = 0x0800000,
+ SHORT_INODE = 0x1000000,
+ WHOLE_SECONDS = 0x2000000,
+ STICKY_TIMEOUTS = 0x4000000,
+ };
+
+/* Personality types.
+
+ These go in the low byte. Avoid using the top bit, it will
+ conflict with error returns. */
+enum
+ {
+ PER_LINUX = 0x0000,
+ PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT,
+ PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+ PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
+ PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE,
+ PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
+ PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
+ PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS,
+ PER_BSD = 0x0006,
+ PER_SUNOS = 0x0006 | STICKY_TIMEOUTS,
+ PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
+ PER_LINUX32 = 0x0008,
+ PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS, /* IRIX5 32-bit */
+ PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS, /* IRIX6 new 32-bit */
+ PER_IRIX64 = 0x000b | STICKY_TIMEOUTS, /* IRIX6 64-bit */
+ PER_RISCOS = 0x000c,
+ PER_SOLARIS = 0x000d | STICKY_TIMEOUTS,
+ PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+ PER_HPUX = 0x000f,
+ PER_OSF4 = 0x0010,
+ PER_MASK = 0x00ff,
+ };
+
+__BEGIN_DECLS
+
+/* Set different ABIs (personalities). */
+extern int personality (unsigned long int __persona) __THROW;
+
+__END_DECLS
+
+#endif /* sys/personality.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/prctl.h b/libc/sysdeps/unix/sysv/linux/sys/prctl.h
new file mode 100644
index 000000000..7e9b72d3a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/prctl.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PRCTL_H
+#define _SYS_PRCTL_H 1
+
+#include <features.h>
+#include <linux/prctl.h> /* The magic values come from here */
+
+__BEGIN_DECLS
+
+/* Control process execution. */
+extern int prctl (int __option, ...) __THROW;
+
+__END_DECLS
+
+#endif /* sys/prctl.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/procfs.h b/libc/sysdeps/unix/sysv/linux/sys/procfs.h
new file mode 100644
index 000000000..619bb2d06
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/procfs.h
@@ -0,0 +1,115 @@
+/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H 1
+
+/* This is somehow modelled after the file of the same name on SysVr4
+ systems. It provides a definition of the core file format for ELF
+ used on Linux. */
+
+#include <features.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ucontext.h>
+#include <sys/user.h>
+#include <asm/elf.h>
+
+__BEGIN_DECLS
+
+struct elf_siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_code; /* Extra code. */
+ int si_errno; /* Errno. */
+ };
+
+/* Definitions to generate Intel SVR4-like core files. These mostly
+ have the same names as the SVR4 types with "elf_" tacked on the
+ front to prevent clashes with linux definitions, and the typedef
+ forms have been avoided. This is mostly like the SVR4 structure,
+ but more Linuxy, with things that Linux does not support and which
+ gdb doesn't really use excluded. Fields present but not used are
+ marked with "XXX". */
+struct elf_prstatus
+ {
+#if 0
+ long int pr_flags; /* XXX Process flags. */
+ short int pr_why; /* XXX Reason for process halt. */
+ short int pr_what; /* XXX More detailed reason. */
+#endif
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned long int pr_sigpend; /* Set of pending signals. */
+ unsigned long int pr_sighold; /* Set of held signals. */
+#if 0
+ struct sigaltstack pr_altstack; /* Alternate stack info. */
+ struct sigaction pr_action; /* Signal action for current sig. */
+#endif
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct timeval pr_utime; /* User time. */
+ struct timeval pr_stime; /* System time. */
+ struct timeval pr_cutime; /* Cumulative user time. */
+ struct timeval pr_cstime; /* Cumulative system time. */
+#if 0
+ long int pr_instr; /* Current instruction. */
+#endif
+ elf_gregset_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+#define ELF_PRARGSZ (80) /* Number of chars for args */
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long int pr_flag; /* Flags. */
+ unsigned short int pr_uid;
+ unsigned short int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+/* Addresses. */
+typedef void *psaddr_t;
+
+/* Register sets. Linux has different names. */
+typedef gregset_t prgregset_t;
+typedef fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+ therefore habe only ine PID type. */
+typedef __pid_t lwpid_t;
+
+
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif /* sys/procfs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/ptrace.h b/libc/sysdeps/unix/sysv/linux/sys/ptrace.h
new file mode 100644
index 000000000..b4aec4f20
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/ptrace.h
@@ -0,0 +1,129 @@
+/* `ptrace' debugger support interface. Linux version.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PTRACE_H
+#define _SYS_PTRACE_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Type of the REQUEST argument to `ptrace.' */
+enum __ptrace_request
+{
+ /* Indicate that the process making this request should be traced.
+ All signals received by this process can be intercepted by its
+ parent, and its parent can use the other `ptrace' requests. */
+ PTRACE_TRACEME = 0,
+#define PT_TRACE_ME PTRACE_TRACEME
+
+ /* Return the word in the process's text space at address ADDR. */
+ PTRACE_PEEKTEXT = 1,
+#define PT_READ_I PTRACE_PEEKTEXT
+
+ /* Return the word in the process's data space at address ADDR. */
+ PTRACE_PEEKDATA = 2,
+#define PT_READ_D PTRACE_PEEKDATA
+
+ /* Return the word in the process's user area at offset ADDR. */
+ PTRACE_PEEKUSER = 3,
+#define PT_READ_U PTRACE_PEEKUSER
+
+ /* Write the word DATA into the process's text space at address ADDR. */
+ PTRACE_POKETEXT = 4,
+#define PT_WRITE_I PTRACE_POKETEXT
+
+ /* Write the word DATA into the process's data space at address ADDR. */
+ PTRACE_POKEDATA = 5,
+#define PT_WRITE_D PTRACE_POKEDATA
+
+ /* Write the word DATA into the process's user area at offset ADDR. */
+ PTRACE_POKEUSER = 6,
+#define PT_WRITE_U PTRACE_POKEUSER
+
+ /* Continue the process. */
+ PTRACE_CONT = 7,
+#define PT_CONTINUE PTRACE_CONT
+
+ /* Kill the process. */
+ PTRACE_KILL = 8,
+#define PT_KILL PTRACE_KILL
+
+ /* Single step the process.
+ This is not supported on all machines. */
+ PTRACE_SINGLESTEP = 9,
+#define PT_STEP PTRACE_SINGLESTEP
+
+ /* Get all general purpose registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_GETREGS = 12,
+#define PT_GETREGS PTRACE_GETREGS
+
+ /* Set all general purpose registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_SETREGS = 13,
+#define PT_SETREGS PTRACE_SETREGS
+
+ /* Get all floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_GETFPREGS = 14,
+#define PT_GETFPREGS PTRACE_GETFPREGS
+
+ /* Set all floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_SETFPREGS = 15,
+#define PT_SETFPREGS PTRACE_SETFPREGS
+
+ /* Attach to a process that is already running. */
+ PTRACE_ATTACH = 16,
+#define PT_ATTACH PTRACE_ATTACH
+
+ /* Detach from a process attached to with PTRACE_ATTACH. */
+ PTRACE_DETACH = 17,
+#define PT_DETACH PTRACE_DETACH
+
+ /* Get all extended floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_GETFPXREGS = 18,
+#define PT_GETFPXREGS PTRACE_GETFPXREGS
+
+ /* Set all extended floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_SETFPXREGS = 19,
+#define PT_SETFPXREGS PTRACE_SETFPXREGS
+
+ /* Continue and stop at the next (return from) syscall. */
+ PTRACE_SYSCALL = 24
+#define PT_SYSCALL PTRACE_SYSCALL
+};
+
+/* Perform process tracing functions. REQUEST is one of the values
+ above, and determines the action to be taken.
+ For all requests except PTRACE_TRACEME, PID specifies the process to be
+ traced.
+
+ PID and the other arguments described above for the various requests should
+ appear (those that are used for the particular request) as:
+ pid_t PID, void *ADDR, int DATA, void *ADDR2
+ after REQUEST. */
+extern long int ptrace (enum __ptrace_request __request, ...) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_PTRACE_H */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/quota.h b/libc/sysdeps/unix/sysv/linux/sys/quota.h
new file mode 100644
index 000000000..5aa0ec07d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/quota.h
@@ -0,0 +1,225 @@
+/* This just represents the non-kernel parts of <linux/quota.h>.
+ *
+ * here's the corresponding copyright:
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Elz at The University of Melbourne.
+ *
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+#ifndef _SYS_QUOTA_H
+#define _SYS_QUOTA_H 1
+
+#include <features.h>
+#include <sys/types.h>
+
+/*
+ * Select between different incompatible quota versions.
+ * Default to the version used by Linux kernel version 2.4.22
+ * or later. */
+#ifndef _LINUX_QUOTA_VERSION
+# define _LINUX_QUOTA_VERSION 2
+#endif
+
+/*
+ * Convert diskblocks to blocks and the other way around.
+ * currently only to fool the BSD source. :-)
+ */
+#define dbtob(num) ((num) << 10)
+#define btodb(num) ((num) >> 10)
+
+/*
+ * Convert count of filesystem blocks to diskquota blocks, meant
+ * for filesystems where i_blksize != BLOCK_SIZE
+ */
+#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / BLOCK_SIZE)
+
+/*
+ * Definitions for disk quotas imposed on the average user
+ * (big brother finally hits Linux).
+ *
+ * The following constants define the amount of time given a user
+ * before the soft limits are treated as hard limits (usually resulting
+ * in an allocation failure). The timer is started when the user crosses
+ * their soft limit, it is reset when they go below their soft limit.
+ */
+#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */
+#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */
+
+#define MAXQUOTAS 2
+#define USRQUOTA 0 /* element used for user quotas */
+#define GRPQUOTA 1 /* element used for group quotas */
+
+/*
+ * Definitions for the default names of the quotas files.
+ */
+#define INITQFNAMES { \
+ "user", /* USRQUOTA */ \
+ "group", /* GRPQUOTA */ \
+ "undefined", \
+};
+
+#define QUOTAFILENAME "quota"
+#define QUOTAGROUP "staff"
+
+#define NR_DQHASH 43 /* Just an arbitrary number any suggestions ? */
+#define NR_DQUOTS 256 /* Number of quotas active at one time */
+
+/*
+ * Command definitions for the 'quotactl' system call.
+ * The commands are broken into a main command defined below
+ * and a subcommand that is used to convey the type of
+ * quota that is being manipulated (see above).
+ */
+#define SUBCMDMASK 0x00ff
+#define SUBCMDSHIFT 8
+#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
+
+#if _LINUX_QUOTA_VERSION < 2
+# define Q_QUOTAON 0x0100 /* enable quotas */
+# define Q_QUOTAOFF 0x0200 /* disable quotas */
+# define Q_GETQUOTA 0x0300 /* get limits and usage */
+# define Q_SETQUOTA 0x0400 /* set limits and usage */
+# define Q_SETUSE 0x0500 /* set usage */
+# define Q_SYNC 0x0600 /* sync disk copy of a filesystems quotas */
+# define Q_SETQLIM 0x0700 /* set limits */
+# define Q_GETSTATS 0x0800 /* get collected stats */
+# define Q_RSQUASH 0x1000 /* set root_squash option */
+#else
+# define Q_SYNC 0x800001 /* sync disk copy of a filesystems quotas */
+# define Q_QUOTAON 0x800002 /* turn quotas on */
+# define Q_QUOTAOFF 0x800003 /* turn quotas off */
+# define Q_GETFMT 0x800004 /* get quota format used on given filesystem */
+# define Q_GETINFO 0x800005 /* get information about quota files */
+# define Q_SETINFO 0x800006 /* set information about quota files */
+# define Q_GETQUOTA 0x800007 /* get user quota structure */
+# define Q_SETQUOTA 0x800008 /* set user quota structure */
+#endif
+
+/*
+ * The following structure defines the format of the disk quota file
+ * (as it appears on disk) - the file is an array of these structures
+ * indexed by user or group number.
+ */
+#if _LINUX_QUOTA_VERSION < 2
+struct dqblk
+ {
+ u_int32_t dqb_bhardlimit; /* absolute limit on disk blks alloc */
+ u_int32_t dqb_bsoftlimit; /* preferred limit on disk blks */
+ u_int32_t dqb_curblocks; /* current block count */
+ u_int32_t dqb_ihardlimit; /* maximum # allocated inodes */
+ u_int32_t dqb_isoftlimit; /* preferred inode limit */
+ u_int32_t dqb_curinodes; /* current # allocated inodes */
+ time_t dqb_btime; /* time limit for excessive disk use */
+ time_t dqb_itime; /* time limit for excessive files */
+ };
+#else
+
+/* Flags that indicate which fields in dqblk structure are valid. */
+#define QIF_BLIMITS 1
+#define QIF_SPACE 2
+#define QIF_ILIMITS 4
+#define QIF_INODES 8
+#define QIF_BTIME 16
+#define QIF_ITIME 32
+#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
+#define QIF_USAGE (QIF_SPACE | QIF_INODES)
+#define QIF_TIMES (QIF_BTIME | QIF_ITIME)
+#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
+
+struct dqblk
+ {
+ u_int64_t dqb_bhardlimit; /* absolute limit on disk quota blocks alloc */
+ u_int64_t dqb_bsoftlimit; /* preferred limit on disk quota blocks */
+ u_int64_t dqb_curspace; /* current quota block count */
+ u_int64_t dqb_ihardlimit; /* maximum # allocated inodes */
+ u_int64_t dqb_isoftlimit; /* preferred inode limit */
+ u_int64_t dqb_curinodes; /* current # allocated inodes */
+ u_int64_t dqb_btime; /* time limit for excessive disk use */
+ u_int64_t dqb_itime; /* time limit for excessive files */
+ u_int32_t dqb_valid; /* bitmask of QIF_* constants */
+ };
+#endif
+
+/*
+ * Shorthand notation.
+ */
+#define dq_bhardlimit dq_dqb.dqb_bhardlimit
+#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit
+#if _LINUX_QUOTA_VERSION < 2
+# define dq_curblocks dq_dqb.dqb_curblocks
+#else
+# define dq_curspace dq_dqb.dqb_curspace
+# define dq_valid dq_dqb.dqb_valid
+#endif
+#define dq_ihardlimit dq_dqb.dqb_ihardlimit
+#define dq_isoftlimit dq_dqb.dqb_isoftlimit
+#define dq_curinodes dq_dqb.dqb_curinodes
+#define dq_btime dq_dqb.dqb_btime
+#define dq_itime dq_dqb.dqb_itime
+
+#define dqoff(UID) ((loff_t)((UID) * sizeof (struct dqblk)))
+
+#if _LINUX_QUOTA_VERSION < 2
+struct dqstats
+ {
+ u_int32_t lookups;
+ u_int32_t drops;
+ u_int32_t reads;
+ u_int32_t writes;
+ u_int32_t cache_hits;
+ u_int32_t pages_allocated;
+ u_int32_t allocated_dquots;
+ u_int32_t free_dquots;
+ u_int32_t syncs;
+ };
+#else
+
+/* Flags that indicate which fields in dqinfo structure are valid. */
+# define IIF_BGRACE 1
+# define IIF_IGRACE 2
+# define IIF_FLAGS 4
+# define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
+
+struct dqinfo
+ {
+ u_int64_t dqi_bgrace;
+ u_int64_t dqi_igrace;
+ u_int32_t dqi_flags;
+ u_int32_t dqi_valid;
+ };
+#endif
+
+__BEGIN_DECLS
+
+extern int quotactl (int __cmd, const char *__special, int __id,
+ caddr_t __addr) __THROW;
+
+__END_DECLS
+
+#endif /* sys/quota.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/raw.h b/libc/sysdeps/unix/sysv/linux/sys/raw.h
new file mode 100644
index 000000000..642f78ce5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/raw.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_RAW_H
+#define _SYS_RAW_H 1
+
+#include <stdint.h>
+#include <sys/ioctl.h>
+
+/* The major device number for raw devices. */
+#define RAW_MAJOR 162
+
+/* `ioctl' commands for raw devices. */
+#define RAW_SETBIND _IO(0xac, 0)
+#define RAW_GETBIND _IO(0xac, 1)
+
+struct raw_config_request
+{
+ int raw_minor;
+ uint64_t block_major;
+ uint64_t block_minor;
+};
+
+#endif /* sys/raw.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/reboot.h b/libc/sysdeps/unix/sysv/linux/sys/reboot.h
new file mode 100644
index 000000000..2a719c7a3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/reboot.h
@@ -0,0 +1,49 @@
+/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file should define RB_* macros to be used as flag
+ bits in the argument to the `reboot' system call. */
+
+#ifndef _SYS_REBOOT_H
+#define _SYS_REBOOT_H 1
+
+#include <features.h>
+
+/* Perform a hard reset now. */
+#define RB_AUTOBOOT 0x01234567
+
+/* Halt the system. */
+#define RB_HALT_SYSTEM 0xcdef0123
+
+/* Enable reboot using Ctrl-Alt-Delete keystroke. */
+#define RB_ENABLE_CAD 0x89abcdef
+
+/* Disable reboot using Ctrl-Alt-Delete keystroke. */
+#define RB_DISABLE_CAD 0
+
+/* Stop system and switch power off if possible. */
+#define RB_POWER_OFF 0x4321fedc
+
+__BEGIN_DECLS
+
+/* Reboot or halt the system. */
+extern int reboot (int __howto) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_REBOOT_H */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/soundcard.h b/libc/sysdeps/unix/sysv/linux/sys/soundcard.h
new file mode 100644
index 000000000..fade986fe
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/soundcard.h
@@ -0,0 +1 @@
+#include <linux/soundcard.h>
diff --git a/libc/sysdeps/unix/sysv/linux/sys/swap.h b/libc/sysdeps/unix/sysv/linux/sys/swap.h
new file mode 100644
index 000000000..b6e7bef5d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/swap.h
@@ -0,0 +1,43 @@
+/* Calls to enable and disable swapping on specified locations. Linux version.
+ Copyright (C) 1996, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SWAP_H
+
+#define _SYS_SWAP_H 1
+#include <features.h>
+
+/* The swap priority is encoded as:
+ (prio << SWAP_FLAG_PRIO_SHIFT) & SWAP_FLAG_PRIO_MASK
+*/
+#define SWAP_FLAG_PREFER 0x8000 /* Set if swap priority is specified. */
+#define SWAP_FLAG_PRIO_MASK 0x7fff
+#define SWAP_FLAG_PRIO_SHIFT 0
+
+__BEGIN_DECLS
+
+/* Make the block special device PATH available to the system for swapping.
+ This call is restricted to the super-user. */
+extern int swapon (__const char *__path, int __flags) __THROW;
+
+/* Stop using block special device PATH for swapping. */
+extern int swapoff (__const char *__path) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_SWAP_H */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/syscall.h b/libc/sysdeps/unix/sysv/linux/sys/syscall.h
new file mode 100644
index 000000000..445ca3763
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/syscall.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYSCALL_H
+#define _SYSCALL_H 1
+
+/* This file should list the numbers of the system the system knows.
+ But instead of duplicating this we use the information available
+ from the kernel sources. */
+#include <asm/unistd.h>
+
+#ifndef _LIBC
+/* The Linux kernel header file defines macros `__NR_<name>', but some
+ programs expect the traditional form `SYS_<name>'. So in building libc
+ we scan the kernel's list and produce <bits/syscall.h> with macros for
+ all the `SYS_' names. */
+# include <bits/syscall.h>
+#endif
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sys/sysctl.h b/libc/sysdeps/unix/sysv/linux/sys/sysctl.h
new file mode 100644
index 000000000..110efaa76
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/sysctl.h
@@ -0,0 +1,72 @@
+/* Copyright (C) 1996, 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SYSCTL_H
+#define _SYS_SYSCTL_H 1
+
+#include <features.h>
+#define __need_size_t
+#include <stddef.h>
+/* Prevent more kernel headers than necessary to be included. */
+#ifndef _LINUX_KERNEL_H
+# define _LINUX_KERNEL_H 1
+# define __undef_LINUX_KERNEL_H
+#endif
+#ifndef _LINUX_TYPES_H
+# define _LINUX_TYPES_H 1
+# define __undef_LINUX_TYPES_H
+#endif
+#ifndef _LINUX_LIST_H
+# define _LINUX_LIST_H 1
+# define __undef_LINUX_LIST_H
+#endif
+#ifndef __LINUX_COMPILER_H
+# define __LINUX_COMPILER_H 1
+# define __user
+# define __undef__LINUX_COMPILER_H
+#endif
+
+#include <linux/sysctl.h>
+
+#ifdef __undef_LINUX_KERNEL_H
+# undef _LINUX_KERNEL_H
+# undef __undef_LINUX_KERNEL_H
+#endif
+#ifdef __undef_LINUX_TYPES_H
+# undef _LINUX_TYPES_H
+# undef __undef_LINUX_TYPES_H
+#endif
+#ifdef __undef_LINUX_LIST_H
+# undef _LINUX_LIST_H
+# undef __undef_LINUX_LIST_H
+#endif
+#ifdef __undef__LINUX_COMPILER_H
+# undef __LINUX_COMPILER_H
+# undef __user
+# undef __undef__LINUX_COMPILER_H
+#endif
+
+__BEGIN_DECLS
+
+/* Read or write system parameters. */
+extern int sysctl (int *__name, int __nlen, void *__oldval,
+ size_t *__oldlenp, void *__newval, size_t __newlen) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_SYSCTL_H */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/sysinfo.h b/libc/sysdeps/unix/sysv/linux/sys/sysinfo.h
new file mode 100644
index 000000000..a6727b21e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/sysinfo.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 1996, 1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SYSINFO_H
+#define _SYS_SYSINFO_H 1
+
+#include <features.h>
+
+/* Get sysinfo structure from kernel header. */
+#include <linux/kernel.h>
+
+__BEGIN_DECLS
+
+/* Returns information on overall system statistics. */
+extern int sysinfo (struct sysinfo *__info) __THROW;
+
+
+/* Return number of configured processors. */
+extern int get_nprocs_conf (void) __THROW;
+
+/* Return number of available processors. */
+extern int get_nprocs (void) __THROW;
+
+
+/* Return number of physical pages of memory in the system. */
+extern long int get_phys_pages (void) __THROW;
+
+/* Return number of available physical pages of memory in the system. */
+extern long int get_avphys_pages (void) __THROW;
+
+__END_DECLS
+
+#endif /* sys/sysinfo.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/sysmacros.h b/libc/sysdeps/unix/sysv/linux/sys/sysmacros.h
new file mode 100644
index 000000000..179642ff4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/sysmacros.h
@@ -0,0 +1,69 @@
+/* Definitions of macros to access `dev_t' values.
+ Copyright (C) 1996, 1997, 1999, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SYSMACROS_H
+#define _SYS_SYSMACROS_H 1
+
+#include <features.h>
+
+/* If the compiler does not know long long it is out of luck. We are
+ not going to hack weird hacks to support the dev_t representation
+ they need. */
+#ifdef __GLIBC_HAVE_LONG_LONG
+__extension__
+extern __inline unsigned int gnu_dev_major (unsigned long long int __dev)
+ __THROW;
+__extension__
+extern __inline unsigned int gnu_dev_minor (unsigned long long int __dev)
+ __THROW;
+__extension__
+extern __inline unsigned long long int gnu_dev_makedev (unsigned int __major,
+ unsigned int __minor)
+ __THROW;
+
+# if defined __GNUC__ && __GNUC__ >= 2
+__extension__ extern __inline unsigned int
+__NTH (gnu_dev_major (unsigned long long int __dev))
+{
+ return ((__dev >> 8) & 0xfff) | ((unsigned int) (__dev >> 32) & ~0xfff);
+}
+
+__extension__ extern __inline unsigned int
+__NTH (gnu_dev_minor (unsigned long long int __dev))
+{
+ return (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff);
+}
+
+__extension__ extern __inline unsigned long long int
+__NTH (gnu_dev_makedev (unsigned int __major, unsigned int __minor))
+{
+ return ((__minor & 0xff) | ((__major & 0xfff) << 8)
+ | (((unsigned long long int) (__minor & ~0xff)) << 12)
+ | (((unsigned long long int) (__major & ~0xfff)) << 32));
+}
+# endif
+
+
+/* Access the functions with their traditional names. */
+# define major(dev) gnu_dev_major (dev)
+# define minor(dev) gnu_dev_minor (dev)
+# define makedev(maj, min) gnu_dev_makedev (maj, min)
+#endif
+
+#endif /* sys/sysmacros.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/timex.h b/libc/sysdeps/unix/sysv/linux/sys/timex.h
new file mode 100644
index 000000000..773a5ab8d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/timex.h
@@ -0,0 +1,127 @@
+/* Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_TIMEX_H
+#define _SYS_TIMEX_H 1
+
+#include <features.h>
+#include <sys/time.h>
+
+/* These definitions from linux/timex.h as of 2.2.0. */
+
+struct ntptimeval
+{
+ struct timeval time; /* current time (ro) */
+ long int maxerror; /* maximum error (us) (ro) */
+ long int esterror; /* estimated error (us) (ro) */
+};
+
+struct timex
+{
+ unsigned int modes; /* mode selector */
+ long int offset; /* time offset (usec) */
+ long int freq; /* frequency offset (scaled ppm) */
+ long int maxerror; /* maximum error (usec) */
+ long int esterror; /* estimated error (usec) */
+ int status; /* clock command/status */
+ long int constant; /* pll time constant */
+ long int precision; /* clock precision (usec) (read only) */
+ long int tolerance; /* clock frequency tolerance (ppm) (read only) */
+ struct timeval time; /* (read only) */
+ long int tick; /* (modified) usecs between clock ticks */
+
+ long int ppsfreq; /* pps frequency (scaled ppm) (ro) */
+ long int jitter; /* pps jitter (us) (ro) */
+ int shift; /* interval duration (s) (shift) (ro) */
+ long int stabil; /* pps stability (scaled ppm) (ro) */
+ long int jitcnt; /* jitter limit exceeded (ro) */
+ long int calcnt; /* calibration intervals (ro) */
+ long int errcnt; /* calibration errors (ro) */
+ long int stbcnt; /* stability limit exceeded (ro) */
+
+ /* ??? */
+ int :32; int :32; int :32; int :32;
+ int :32; int :32; int :32; int :32;
+ int :32; int :32; int :32; int :32;
+};
+
+/* Mode codes (timex.mode) */
+#define ADJ_OFFSET 0x0001 /* time offset */
+#define ADJ_FREQUENCY 0x0002 /* frequency offset */
+#define ADJ_MAXERROR 0x0004 /* maximum time error */
+#define ADJ_ESTERROR 0x0008 /* estimated time error */
+#define ADJ_STATUS 0x0010 /* clock status */
+#define ADJ_TIMECONST 0x0020 /* pll time constant */
+#define ADJ_TICK 0x4000 /* tick value */
+#define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */
+
+/* xntp 3.4 compatibility names */
+#define MOD_OFFSET ADJ_OFFSET
+#define MOD_FREQUENCY ADJ_FREQUENCY
+#define MOD_MAXERROR ADJ_MAXERROR
+#define MOD_ESTERROR ADJ_ESTERROR
+#define MOD_STATUS ADJ_STATUS
+#define MOD_TIMECONST ADJ_TIMECONST
+#define MOD_CLKB ADJ_TICK
+#define MOD_CLKA ADJ_OFFSET_SINGLESHOT /* 0x8000 in original */
+
+
+/* Status codes (timex.status) */
+#define STA_PLL 0x0001 /* enable PLL updates (rw) */
+#define STA_PPSFREQ 0x0002 /* enable PPS freq discipline (rw) */
+#define STA_PPSTIME 0x0004 /* enable PPS time discipline (rw) */
+#define STA_FLL 0x0008 /* select frequency-lock mode (rw) */
+
+#define STA_INS 0x0010 /* insert leap (rw) */
+#define STA_DEL 0x0020 /* delete leap (rw) */
+#define STA_UNSYNC 0x0040 /* clock unsynchronized (rw) */
+#define STA_FREQHOLD 0x0080 /* hold frequency (rw) */
+
+#define STA_PPSSIGNAL 0x0100 /* PPS signal present (ro) */
+#define STA_PPSJITTER 0x0200 /* PPS signal jitter exceeded (ro) */
+#define STA_PPSWANDER 0x0400 /* PPS signal wander exceeded (ro) */
+#define STA_PPSERROR 0x0800 /* PPS signal calibration error (ro) */
+
+#define STA_CLOCKERR 0x1000 /* clock hardware fault (ro) */
+
+#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \
+ STA_PPSERROR | STA_CLOCKERR) /* read-only bits */
+
+/* Clock states (time_state) */
+#define TIME_OK 0 /* clock synchronized, no leap second */
+#define TIME_INS 1 /* insert leap second */
+#define TIME_DEL 2 /* delete leap second */
+#define TIME_OOP 3 /* leap second in progress */
+#define TIME_WAIT 4 /* leap second has occurred */
+#define TIME_ERROR 5 /* clock not synchronized */
+#define TIME_BAD TIME_ERROR /* bw compat */
+
+/* Maximum time constant of the PLL. */
+#define MAXTC 6
+
+__BEGIN_DECLS
+
+extern int __adjtimex (struct timex *__ntx) __THROW;
+extern int adjtimex (struct timex *__ntx) __THROW;
+
+extern int ntp_gettime (struct ntptimeval *__ntv) __THROW;
+extern int ntp_adjtime (struct timex *__tntx) __THROW;
+
+__END_DECLS
+
+#endif /* sys/timex.h */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/ttydefaults.h b/libc/sysdeps/unix/sysv/linux/sys/ttydefaults.h
new file mode 100644
index 000000000..9be168b83
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/ttydefaults.h
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)ttydefaults.h 8.4 (Berkeley) 1/21/94
+ */
+
+/*
+ * System wide defaults for terminal state. Linux version.
+ */
+#ifndef _SYS_TTYDEFAULTS_H_
+#define _SYS_TTYDEFAULTS_H_
+
+/*
+ * Defaults on "first" open.
+ */
+#define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY)
+#define TTYDEF_OFLAG (OPOST | ONLCR | XTABS)
+#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)
+#define TTYDEF_CFLAG (CREAD | CS7 | PARENB | HUPCL)
+#define TTYDEF_SPEED (B9600)
+
+/*
+ * Control Character Defaults
+ */
+#define CTRL(x) (x&037)
+#define CEOF CTRL('d')
+#ifdef _POSIX_VDISABLE
+# define CEOL _POSIX_VDISABLE
+#else
+# define CEOL '\0' /* XXX avoid _POSIX_VDISABLE */
+#endif
+#define CERASE 0177
+#define CINTR CTRL('c')
+#ifdef _POSIX_VDISABLE
+# define CSTATUS _POSIX_VDISABLE
+#else
+# define CSTATUS '\0' /* XXX avoid _POSIX_VDISABLE */
+#endif
+#define CKILL CTRL('u')
+#define CMIN 1
+#define CQUIT 034 /* FS, ^\ */
+#define CSUSP CTRL('z')
+#define CTIME 0
+#define CDSUSP CTRL('y')
+#define CSTART CTRL('q')
+#define CSTOP CTRL('s')
+#define CLNEXT CTRL('v')
+#define CDISCARD CTRL('o')
+#define CWERASE CTRL('w')
+#define CREPRINT CTRL('r')
+#define CEOT CEOF
+/* compat */
+#define CBRK CEOL
+#define CRPRNT CREPRINT
+#define CFLUSH CDISCARD
+
+/* PROTECTED INCLUSION ENDS HERE */
+#endif /* !_SYS_TTYDEFAULTS_H_ */
+
+/*
+ * #define TTYDEFCHARS to include an array of default control characters.
+ */
+#ifdef TTYDEFCHARS
+cc_t ttydefchars[NCCS] = {
+ CEOF, CEOL, CEOL, CERASE, CWERASE, CKILL, CREPRINT,
+ _POSIX_VDISABLE, CINTR, CQUIT, CSUSP, CDSUSP, CSTART, CSTOP, CLNEXT,
+ CDISCARD, CMIN, CTIME, CSTATUS, _POSIX_VDISABLE
+};
+#undef TTYDEFCHARS
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sys/ultrasound.h b/libc/sysdeps/unix/sysv/linux/sys/ultrasound.h
new file mode 100644
index 000000000..a65c385bc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/ultrasound.h
@@ -0,0 +1 @@
+#include <linux/ultrasound.h>
diff --git a/libc/sysdeps/unix/sysv/linux/sys/user.h b/libc/sysdeps/unix/sysv/linux/sys/user.h
new file mode 100644
index 000000000..30e9b57ab
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/user.h
@@ -0,0 +1 @@
+#include <linux/user.h>
diff --git a/libc/sysdeps/unix/sysv/linux/sys/vt.h b/libc/sysdeps/unix/sysv/linux/sys/vt.h
new file mode 100644
index 000000000..834abfbc8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sys/vt.h
@@ -0,0 +1 @@
+#include <linux/vt.h>
diff --git a/libc/sysdeps/unix/sysv/linux/syscalls.list b/libc/sysdeps/unix/sysv/linux/syscalls.list
new file mode 100644
index 000000000..afb6d8097
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/syscalls.list
@@ -0,0 +1,97 @@
+# File name Caller Syscall name Args Strong name Weak names
+
+adjtimex adjtime adjtimex i:p __adjtimex adjtimex ntp_adjtime __adjtimex_internal
+bdflush EXTRA bdflush i:ii bdflush
+capget EXTRA capget i:pp capget
+capset EXTRA capset i:pp capset
+creat - creat Ci:si __libc_creat creat
+create_module EXTRA create_module 3 create_module
+delete_module EXTRA delete_module 3 delete_module
+epoll_create EXTRA epoll_create i:i epoll_create
+epoll_ctl EXTRA epoll_ctl i:iiip epoll_ctl
+epoll_wait EXTRA epoll_wait Ci:ipii epoll_wait
+fdatasync - fdatasync i:i fdatasync
+flock - flock i:ii __flock flock
+fork - fork i: __libc_fork __fork fork
+get_kernel_syms EXTRA get_kernel_syms i:p get_kernel_syms
+getegid - getegid Ei: __getegid getegid
+geteuid - geteuid Ei: __geteuid geteuid
+getpgid - getpgid i:i __getpgid getpgid
+getpgrp - getpgrp Ei: getpgrp
+getpmsg - getpmsg i:ipppp getpmsg
+getppid - getppid Ei: __getppid getppid
+getresuid - getresuid i:ppp getresuid
+getresgid - getresgid i:ppp getresgid
+getsid - getsid i:i getsid
+init_module EXTRA init_module 5 init_module
+inotify_add_watch EXTRA inotify_add_watch i:isi inotify_add_watch
+inotify_init EXTRA inotify_init i: inotify_init
+inotify_rm_watch EXTRA inotify_rm_watch i:ii inotify_rm_watch
+ioperm - ioperm i:iii ioperm
+iopl - iopl i:i iopl
+klogctl EXTRA syslog i:isi klogctl
+lchown - lchown i:sii __lchown lchown
+posix_madvise - madvise Vi:pii posix_madvise
+madvise - madvise i:pii madvise
+mincore - mincore i:anV mincore
+mlock - mlock i:bn mlock
+mlockall - mlockall i:i mlockall
+mmap - mmap b:aniiii __mmap mmap
+mount EXTRA mount i:sssip __mount mount
+mremap EXTRA mremap b:ainip __mremap mremap
+munlock - munlock i:ai munlock
+munlockall - munlockall i: munlockall
+nanosleep - nanosleep Ci:pp __libc_nanosleep __nanosleep nanosleep
+nfsservctl EXTRA nfsservctl i:ipp nfsservctl
+pause - pause Ci: __libc_pause pause
+personality init-first personality i:i __personality personality
+pipe - pipe i:f __pipe pipe
+pivot_root EXTRA pivot_root i:ss pivot_root
+prctl EXTRA prctl i:iiiii __prctl prctl
+putpmsg - putpmsg i:ippii putpmsg
+query_module EXTRA query_module i:sipip query_module
+quotactl EXTRA quotactl i:isip quotactl
+remap_file_pages - remap_file_pages i:piiii __remap_file_pages remap_file_pages
+sched_getp - sched_getparam i:ip __sched_getparam sched_getparam
+sched_gets - sched_getscheduler i:i __sched_getscheduler sched_getscheduler
+sched_primax - sched_get_priority_max i:i __sched_get_priority_max sched_get_priority_max
+sched_primin - sched_get_priority_min i:i __sched_get_priority_min sched_get_priority_min
+sched_rr_gi - sched_rr_get_interval i:ip __sched_rr_get_interval sched_rr_get_interval
+sched_setp - sched_setparam i:ip __sched_setparam sched_setparam
+sched_sets - sched_setscheduler i:iip __sched_setscheduler sched_setscheduler
+sched_yield - sched_yield i: __sched_yield sched_yield
+select - _newselect Ci:iPPPP __select __libc_select select
+sendfile - sendfile i:iipi sendfile
+sendfile64 - sendfile64 i:iipi sendfile64
+setfsgid EXTRA setfsgid i:i setfsgid
+setfsuid EXTRA setfsuid i:i setfsuid
+setpgid - setpgid i:ii __setpgid setpgid
+sigaltstack - sigaltstack i:PP __sigaltstack sigaltstack
+splice EXTRA splice i:iiii splice
+sysinfo EXTRA sysinfo i:p sysinfo
+swapon - swapon i:si __swapon swapon
+swapoff - swapoff i:s __swapoff swapoff
+tee EXTRA tee i:iiii tee
+unshare EXTRA unshare i:i unshare
+uselib EXTRA uselib i:s uselib
+vmsplice EXTRA vmsplice i:iPii vmsplice
+wait4 - wait4 i:iWiP __wait4 wait4
+
+chown - chown i:sii __libc_chown __chown chown
+
+setxattr - setxattr i:sspii setxattr
+lsetxattr - lsetxattr i:sspii lsetxattr
+fsetxattr - fsetxattr i:ispii fsetxattr
+getxattr - getxattr i:sspi getxattr
+lgetxattr - lgetxattr i:sspi lgetxattr
+fgetxattr - fgetxattr i:ispi fgetxattr
+listxattr - listxattr i:ssi listxattr
+llistxattr - llistxattr i:ssi llistxattr
+flistxattr - flistxattr i:isi flistxattr
+removexattr - removexattr i:ss removexattr
+lremovexattr - lremovexattr i:ss lremovexattr
+fremovexattr - fremovexattr i:is fremovexattr
+
+mq_timedsend - mq_timedsend Ci:ipiip __GI_mq_timedsend mq_timedsend
+mq_timedreceive - mq_timedreceive Ci:ipipp __GI_mq_timedreceive mq_timedreceive
+mq_setattr - mq_getsetattr i:ipp __GI_mq_setattr mq_setattr
diff --git a/libc/sysdeps/unix/sysv/linux/sysconf.c b/libc/sysdeps/unix/sysv/linux/sysconf.c
new file mode 100644
index 000000000..f9f6f1bfa
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sysconf.c
@@ -0,0 +1,118 @@
+/* Get file-specific information about a file. Linux version.
+ Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sysdep.h>
+#include <time.h>
+#include <unistd.h>
+#include <not-cancel.h>
+
+static long int posix_sysconf (int name);
+
+
+/* Get the value of the system variable NAME. */
+long int
+__sysconf (int name)
+{
+ const char *procfname = NULL;
+
+ switch (name)
+ {
+#ifdef __NR_clock_getres
+ case _SC_MONOTONIC_CLOCK:
+ /* Check using the clock_getres system call. */
+ {
+ struct timespec ts;
+ INTERNAL_SYSCALL_DECL (err);
+ int r;
+ r = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts);
+ return INTERNAL_SYSCALL_ERROR_P (r, err) ? -1 : _POSIX_VERSION;
+ }
+#endif
+
+#if defined __NR_clock_getres || HP_TIMING_AVAIL
+ case _SC_CPUTIME:
+ case _SC_THREAD_CPUTIME:
+ {
+ /* If we have HP_TIMING, we will fall back on that if the system
+ call does not work, so we support it either way. */
+# if !HP_TIMING_AVAIL
+ /* Check using the clock_getres system call. */
+ struct timespec ts;
+ INTERNAL_SYSCALL_DECL (err);
+ int r = INTERNAL_SYSCALL (clock_getres, err, 2,
+ (name == _SC_CPUTIME
+ ? CLOCK_PROCESS_CPUTIME_ID
+ : CLOCK_THREAD_CPUTIME_ID),
+ &ts);
+ if (INTERNAL_SYSCALL_ERROR_P (r, err))
+ return -1;
+# endif
+ return _POSIX_VERSION;
+ }
+#endif
+
+ case _SC_NGROUPS_MAX:
+ /* Try to read the information from the /proc/sys/kernel/ngroups_max
+ file. */
+ procfname = "/proc/sys/kernel/ngroups_max";
+ break;
+
+ case _SC_SIGQUEUE_MAX:
+ /* The /proc/sys/kernel/rtsig-max file contains the answer. */
+ procfname = "/proc/sys/kernel/rtsig-max";
+ break;
+
+ default:
+ break;
+ }
+
+ if (procfname != NULL)
+ {
+ int fd = open_not_cancel_2 (procfname, O_RDONLY);
+ if (fd != -1)
+ {
+ /* This is more than enough, the file contains a single integer. */
+ char buf[32];
+ ssize_t n;
+ n = TEMP_FAILURE_RETRY (read_not_cancel (fd, buf, sizeof (buf) - 1));
+ close_not_cancel_no_status (fd);
+
+ if (n > 0)
+ {
+ /* Terminate the string. */
+ buf[n] = '\0';
+
+ char *endp;
+ long int res = strtol (buf, &endp, 10);
+ if (endp != buf && (*endp == '\0' || *endp == '\n'))
+ return res;
+ }
+ }
+ }
+
+ return posix_sysconf (name);
+}
+
+/* Now the POSIX version. */
+#undef __sysconf
+#define __sysconf static posix_sysconf
+#include <sysdeps/posix/sysconf.c>
diff --git a/libc/sysdeps/unix/sysv/linux/sysctl.c b/libc/sysdeps/unix/sysv/linux/sysctl.c
new file mode 100644
index 000000000..637fca596
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/sysctl.c
@@ -0,0 +1,49 @@
+/* Read or write system information. Linux version.
+ Copyright (C) 1996-2000,2002,2003,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h> /* For the real memset prototype. */
+#include <sys/sysctl.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+int
+__sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
+ void *newval, size_t newlen)
+{
+ /* GKM FIXME: force __sysctl_args decl to have unbounded pointers. */
+ struct __sysctl_args args =
+ {
+ .name = name,
+ .nlen = nlen,
+ .oldval = oldval,
+ .oldlenp = oldlenp,
+ .newval = newval,
+ .newlen = newlen
+ };
+ (void) CHECK_N (name, nlen);
+ (void) CHECK_N (oldval, *oldlenp);
+ (void) CHECK_N (newval, newlen);
+
+ return INLINE_SYSCALL (_sysctl, 1, __ptrvalue (&args));
+}
+libc_hidden_def (__sysctl)
+weak_alias (__sysctl, sysctl)
diff --git a/libc/sysdeps/unix/sysv/linux/syslog.c b/libc/sysdeps/unix/sysv/linux/syslog.c
new file mode 100644
index 000000000..145e22b52
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/syslog.c
@@ -0,0 +1,10 @@
+#include <kernel-features.h>
+
+#if __ASSUME_MSG_NOSIGNAL
+# define NO_SIGPIPE
+# define send_flags MSG_NOSIGNAL
+#else
+# define send_flags 0
+#endif
+
+#include <misc/syslog.c>
diff --git a/libc/sysdeps/unix/sysv/linux/system.c b/libc/sysdeps/unix/sysv/linux/system.c
new file mode 100644
index 000000000..c5b389ea2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/system.c
@@ -0,0 +1,78 @@
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sched.h>
+#include <signal.h>
+#include <string.h> /* For the real memset prototype. */
+#include <sysdep.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <bits/libc-lock.h>
+#include <kernel-features.h>
+
+/* We have to and actually can handle cancelable system(). The big
+ problem: we have to kill the child process if necessary. To do
+ this a cleanup handler has to be registered and is has to be able
+ to find the PID of the child. The main problem is to reliable have
+ the PID when needed. It is not necessary for the parent thread to
+ return. It might still be in the kernel when the cancellation
+ request comes. Therefore we have to use the clone() calls ability
+ to have the kernel write the PID into the user-level variable. */
+#if defined __ASSUME_CLONE_THREAD_FLAGS && !defined FORK
+# define FORK() \
+ INLINE_SYSCALL (clone, 3, CLONE_PARENT_SETTID | SIGCHLD, 0, &pid)
+#endif
+
+#ifdef _LIBC_REENTRANT
+static void cancel_handler (void *arg);
+
+# define CLEANUP_HANDLER \
+ __libc_cleanup_region_start (1, cancel_handler, &pid)
+
+# define CLEANUP_RESET \
+ __libc_cleanup_region_end (0)
+#endif
+
+
+/* Linux has waitpid(), so override the generic unix version. */
+#include <sysdeps/posix/system.c>
+
+
+#ifdef _LIBC_REENTRANT
+/* The cancellation handler. */
+static void
+cancel_handler (void *arg)
+{
+ pid_t child = *(pid_t *) arg;
+
+ INTERNAL_SYSCALL_DECL (err);
+ INTERNAL_SYSCALL (kill, err, 2, child, SIGKILL);
+
+ TEMP_FAILURE_RETRY (__waitpid (child, NULL, 0));
+
+ DO_LOCK ();
+
+ if (SUB_REF () == 0)
+ {
+ (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
+ (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
+ }
+
+ DO_UNLOCK ();
+}
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/tcdrain.c b/libc/sysdeps/unix/sysv/linux/tcdrain.c
new file mode 100644
index 000000000..4868565ed
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/tcdrain.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sysdep-cancel.h>
+
+/* Wait for pending output to be written on FD. */
+int
+__libc_tcdrain (int fd)
+{
+ if (SINGLE_THREAD_P)
+ /* With an argument of 1, TCSBRK for output to be drain. */
+ return INLINE_SYSCALL (ioctl, 3, fd, TCSBRK, 1);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* With an argument of 1, TCSBRK for output to be drain. */
+ int result = INLINE_SYSCALL (ioctl, 3, fd, TCSBRK, 1);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+weak_alias (__libc_tcdrain, tcdrain)
diff --git a/libc/sysdeps/unix/sysv/linux/tcflow.c b/libc/sysdeps/unix/sysv/linux/tcflow.c
new file mode 100644
index 000000000..6e7237027
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/tcflow.c
@@ -0,0 +1,31 @@
+/* tcflow -- Suspend or restart transmission on termios file descriptor.
+ Copyright (C) 1993,1997,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+/* Suspend or restart transmission on FD. */
+int
+tcflow (fd, action)
+ int fd;
+ int action;
+{
+ return __ioctl (fd, TCXONC, action);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/tcflush.c b/libc/sysdeps/unix/sysv/linux/tcflush.c
new file mode 100644
index 000000000..cae419f4a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/tcflush.c
@@ -0,0 +1,31 @@
+/* tcflush -- Flush pending data on termios file descriptor. Linux version.
+ Copyright (C) 1993,1997,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+/* Flush pending data on FD. */
+int
+tcflush (fd, queue_selector)
+ int fd;
+ int queue_selector;
+{
+ return __ioctl (fd, TCFLSH, queue_selector);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/tcgetattr.c b/libc/sysdeps/unix/sysv/linux/tcgetattr.c
new file mode 100644
index 000000000..28e3e535b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/tcgetattr.c
@@ -0,0 +1,82 @@
+/* Copyright (C) 1992,1995,1997,1998,2003,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sysdep.h>
+
+/* The difference here is that the termios structure used in the
+ kernel is not the same as we use in the libc. Therefore we must
+ translate it here. */
+#include <kernel_termios.h>
+
+/* Put the state of FD into *TERMIOS_P. */
+int
+__tcgetattr (fd, termios_p)
+ int fd;
+ struct termios *termios_p;
+{
+ struct __kernel_termios k_termios;
+ int retval;
+
+ retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios);
+
+ if (__builtin_expect (retval == 0, 1))
+ {
+ termios_p->c_iflag = k_termios.c_iflag;
+ termios_p->c_oflag = k_termios.c_oflag;
+ termios_p->c_cflag = k_termios.c_cflag;
+ termios_p->c_lflag = k_termios.c_lflag;
+ termios_p->c_line = k_termios.c_line;
+#ifdef _HAVE_STRUCT_TERMIOS_C_ISPEED
+# ifdef _HAVE_C_ISPEED
+ termios_p->c_ispeed = k_termios.c_ispeed;
+# else
+ termios_p->c_ispeed = k_termios.c_cflag & (CBAUD | CBAUDEX);
+# endif
+#endif
+#ifdef _HAVE_STRUCT_TERMIOS_C_OSPEED
+# ifdef _HAVE_C_OSPEED
+ termios_p->c_ospeed = k_termios.c_ospeed;
+# else
+ termios_p->c_ospeed = k_termios.c_cflag & (CBAUD | CBAUDEX);
+# endif
+#endif
+ if (sizeof (cc_t) == 1 || _POSIX_VDISABLE == 0
+ || (unsigned char) _POSIX_VDISABLE == (unsigned char) -1)
+ memset (__mempcpy (&termios_p->c_cc[0], &k_termios.c_cc[0],
+ __KERNEL_NCCS * sizeof (cc_t)),
+ _POSIX_VDISABLE, (NCCS - __KERNEL_NCCS) * sizeof (cc_t));
+ else
+ {
+ memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0],
+ __KERNEL_NCCS * sizeof (cc_t));
+
+ for (size_t cnt = __KERNEL_NCCS; cnt < NCCS; ++cnt)
+ termios_p->c_cc[cnt] = _POSIX_VDISABLE;
+ }
+ }
+
+ return retval;
+}
+
+weak_alias (__tcgetattr, tcgetattr)
diff --git a/libc/sysdeps/unix/sysv/linux/tcgetpgrp.c b/libc/sysdeps/unix/sysv/linux/tcgetpgrp.c
new file mode 100644
index 000000000..d899fc78f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/tcgetpgrp.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/bsd/tcgetpgrp.c>
diff --git a/libc/sysdeps/unix/sysv/linux/tcsetattr.c b/libc/sysdeps/unix/sysv/linux/tcsetattr.c
new file mode 100644
index 000000000..f73ec8883
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/tcsetattr.c
@@ -0,0 +1,85 @@
+/* Copyright (C) 1993,1996,1997,1998,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sysdep.h>
+
+/* The difference here is that the termios structure used in the
+ kernel is not the same as we use in the libc. Therefore we must
+ translate it here. */
+#include <kernel_termios.h>
+
+
+/* This is a gross hack around a kernel bug. If the cfsetispeed functions
+ is called with the SPEED argument set to zero this means use the same
+ speed as for output. But we don't have independent input and output
+ speeds and therefore cannot record this.
+
+ We use an unused bit in the `c_iflag' field to keep track of this
+ use of `cfsetispeed'. The value here must correspond to the one used
+ in `speed.c'. */
+#define IBAUD0 020000000000
+
+
+/* Set the state of FD to *TERMIOS_P. */
+int
+tcsetattr (fd, optional_actions, termios_p)
+ int fd;
+ int optional_actions;
+ const struct termios *termios_p;
+{
+ struct __kernel_termios k_termios;
+ unsigned long int cmd;
+
+ switch (optional_actions)
+ {
+ case TCSANOW:
+ cmd = TCSETS;
+ break;
+ case TCSADRAIN:
+ cmd = TCSETSW;
+ break;
+ case TCSAFLUSH:
+ cmd = TCSETSF;
+ break;
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ k_termios.c_iflag = termios_p->c_iflag & ~IBAUD0;
+ k_termios.c_oflag = termios_p->c_oflag;
+ k_termios.c_cflag = termios_p->c_cflag;
+ k_termios.c_lflag = termios_p->c_lflag;
+ k_termios.c_line = termios_p->c_line;
+#if defined _HAVE_C_ISPEED && defined _HAVE_STRUCT_TERMIOS_C_ISPEED
+ k_termios.c_ispeed = termios_p->c_ispeed;
+#endif
+#if defined _HAVE_C_OSPEED && defined _HAVE_STRUCT_TERMIOS_C_OSPEED
+ k_termios.c_ospeed = termios_p->c_ospeed;
+#endif
+ memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0],
+ __KERNEL_NCCS * sizeof (cc_t));
+
+ return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
+}
+libc_hidden_def (tcsetattr)
diff --git a/libc/sysdeps/unix/sysv/linux/tcsetpgrp.c b/libc/sysdeps/unix/sysv/linux/tcsetpgrp.c
new file mode 100644
index 000000000..e4d483390
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/tcsetpgrp.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/bsd/tcsetpgrp.c>
diff --git a/libc/sysdeps/unix/sysv/linux/termio.h b/libc/sysdeps/unix/sysv/linux/termio.h
new file mode 100644
index 000000000..0e610f0c5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/termio.h
@@ -0,0 +1,6 @@
+/* Compatible <termio.h> for old `struct termio' ioctl interface.
+ This is obsolete; use the POSIX.1 `struct termios' interface
+ defined in <termios.h> instead. */
+
+#include <termios.h>
+#include <sys/ioctl.h>
diff --git a/libc/sysdeps/unix/sysv/linux/testrtsig.h b/libc/sysdeps/unix/sysv/linux/testrtsig.h
new file mode 100644
index 000000000..f823a3f5a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/testrtsig.h
@@ -0,0 +1,36 @@
+/* Test whether RT signals are really available.
+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <sys/utsname.h>
+
+#include <kernel-features.h>
+
+static int
+kernel_has_rtsig (void)
+{
+#if __ASSUME_REALTIME_SIGNALS
+ return 1;
+#else
+ struct utsname name;
+
+ return uname (&name) == 0 && __strverscmp (name.release, "2.1.70") >= 0;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/time.c b/libc/sysdeps/unix/sysv/linux/time.c
new file mode 100644
index 000000000..83667906d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/time.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <time.h>
+
+#include <sysdep.h>
+
+#ifdef __NR_time
+
+time_t
+time (t)
+ time_t *t;
+{
+ INTERNAL_SYSCALL_DECL (err);
+ time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
+ /* There cannot be any error. */
+ if (t != NULL)
+ *t = res;
+ return res;
+}
+libc_hidden_def (time)
+
+#else
+
+# include <sysdeps/unix/time.c>
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/truncate64.c b/libc/sysdeps/unix/sysv/linux/truncate64.c
new file mode 100644
index 000000000..f43cffe01
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/truncate64.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 1997-2000,2003,2004,2005,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <endian.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#ifdef __NR_truncate64
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+/* The variable is shared between all wrappers around *truncate64 calls. */
+int __have_no_truncate64;
+#endif
+
+/* Truncate the file FD refers to to LENGTH bytes. */
+int
+truncate64 (const char *path, off64_t length)
+{
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ if (! __have_no_truncate64)
+#endif
+ {
+ unsigned int low = length & 0xffffffff;
+ unsigned int high = length >> 32;
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ int saved_errno = errno;
+#endif
+ int result = INLINE_SYSCALL (truncate64, 3, CHECK_STRING (path),
+ __LONG_LONG_PAIR (high, low));
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ if (result != -1 || errno != ENOSYS)
+#endif
+ return result;
+
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ __set_errno (saved_errno);
+ __have_no_truncate64 = 1;
+#endif
+ }
+
+#ifndef __ASSUME_TRUNCATE64_SYSCALL
+ if ((off_t) length != length)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ return __truncate (path, (off_t) length);
+#endif
+}
+
+#else
+/* Use the generic implementation. */
+# include <misc/truncate64.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/tst-clone.c b/libc/sysdeps/unix/sysv/linux/tst-clone.c
new file mode 100644
index 000000000..8e249c2f0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/tst-clone.c
@@ -0,0 +1,56 @@
+/* Test for proper error/errno handling in clone.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* BZ #2386 */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sched.h>
+
+int child_fn(void *arg)
+{
+ puts ("FAIL: in child_fn(); should not be here");
+ exit(1);
+}
+
+static int
+do_test (void)
+{
+ int result;
+
+#ifdef __ia64__
+ result = __clone2(child_fn, NULL, 0, 0, NULL, NULL, NULL);
+#else
+ result = clone(child_fn, NULL, (int) NULL, NULL);
+#endif
+
+ if (errno != EINVAL || result != -1)
+ {
+ printf ("FAIL: clone()=%d (wanted -1) errno=%d (wanted %d)\n",
+ result, errno, EINVAL);
+ return 1;
+ }
+
+ puts ("All OK");
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/libc/sysdeps/unix/sysv/linux/ttyname.c b/libc/sysdeps/unix/sysv/linux/ttyname.c
new file mode 100644
index 000000000..aed0fd8e0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ttyname.c
@@ -0,0 +1,200 @@
+/* Copyright (C) 1991,92,93,1996-2002,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <stdio-common/_itoa.h>
+#include <kernel-features.h>
+
+#if 0
+/* Is this used anywhere? It is not exported. */
+char *__ttyname;
+#endif
+
+static char *getttyname (const char *dev, dev_t mydev,
+ ino64_t myino, int save, int *dostat)
+ internal_function;
+
+
+libc_freeres_ptr (static char *getttyname_name);
+
+static char *
+internal_function attribute_compat_text_section
+getttyname (const char *dev, dev_t mydev, ino64_t myino, int save, int *dostat)
+{
+ static size_t namelen;
+ struct stat64 st;
+ DIR *dirstream;
+ struct dirent64 *d;
+ size_t devlen = strlen (dev) + 1;
+
+ dirstream = __opendir (dev);
+ if (dirstream == NULL)
+ {
+ *dostat = -1;
+ return NULL;
+ }
+
+ while ((d = __readdir64 (dirstream)) != NULL)
+ if ((d->d_fileno == myino || *dostat)
+ && strcmp (d->d_name, "stdin")
+ && strcmp (d->d_name, "stdout")
+ && strcmp (d->d_name, "stderr"))
+ {
+ size_t dlen = _D_ALLOC_NAMLEN (d);
+ if (devlen + dlen > namelen)
+ {
+ free (getttyname_name);
+ namelen = 2 * (devlen + dlen); /* Big enough. */
+ getttyname_name = malloc (namelen);
+ if (! getttyname_name)
+ {
+ *dostat = -1;
+ /* Perhaps it helps to free the directory stream buffer. */
+ (void) __closedir (dirstream);
+ return NULL;
+ }
+ *((char *) __mempcpy (getttyname_name, dev, devlen - 1)) = '/';
+ }
+ memcpy (&getttyname_name[devlen], d->d_name, dlen);
+ if (__xstat64 (_STAT_VER, getttyname_name, &st) == 0
+#ifdef _STATBUF_ST_RDEV
+ && S_ISCHR (st.st_mode) && st.st_rdev == mydev
+#else
+ && d->d_fileno == myino && st.st_dev == mydev
+#endif
+ )
+ {
+ (void) __closedir (dirstream);
+#if 0
+ __ttyname = getttyname_name;
+#endif
+ __set_errno (save);
+ return getttyname_name;
+ }
+ }
+
+ (void) __closedir (dirstream);
+ __set_errno (save);
+ return NULL;
+}
+
+
+/* Static buffer in `ttyname'. */
+libc_freeres_ptr (static char *ttyname_buf);
+
+
+/* Return the pathname of the terminal FD is open on, or NULL on errors.
+ The returned storage is good only until the next call to this function. */
+char *
+ttyname (int fd)
+{
+ static size_t buflen;
+ char procname[30];
+ struct stat64 st, st1;
+ int dostat = 0;
+ char *name;
+ int save = errno;
+
+ if (__builtin_expect (!__isatty (fd), 0))
+ {
+ __set_errno (ENOTTY);
+ return NULL;
+ }
+
+ /* We try using the /proc filesystem. */
+ *_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0';
+
+ if (buflen == 0)
+ {
+ buflen = 4095;
+ ttyname_buf = (char *) malloc (buflen + 1);
+ if (ttyname_buf == NULL)
+ {
+ buflen = 0;
+ return NULL;
+ }
+ }
+
+ ssize_t len = __readlink (procname, ttyname_buf, buflen);
+ if (__builtin_expect (len == -1 && errno == ENOENT, 0))
+ {
+ __set_errno (EBADF);
+ return NULL;
+ }
+
+ if (__builtin_expect (len != -1
+#ifndef __ASSUME_PROC_SELF_FD_SYMLINK
+ /* This is for Linux 2.0. */
+ && ttyname_buf[0] != '['
+#endif
+ , 1))
+ {
+ if ((size_t) len >= buflen)
+ return NULL;
+ /* readlink need not terminate the string. */
+ ttyname_buf[len] = '\0';
+ return ttyname_buf;
+ }
+
+ if (__fxstat64 (_STAT_VER, fd, &st) < 0)
+ return NULL;
+
+ if (__xstat64 (_STAT_VER, "/dev/pts", &st1) == 0 && S_ISDIR (st1.st_mode))
+ {
+#ifdef _STATBUF_ST_RDEV
+ name = getttyname ("/dev/pts", st.st_rdev, st.st_ino, save, &dostat);
+#else
+ name = getttyname ("/dev/pts", st.st_dev, st.st_ino, save, &dostat);
+#endif
+ }
+ else
+ {
+ __set_errno (save);
+ name = NULL;
+ }
+
+ if (!name && dostat != -1)
+ {
+#ifdef _STATBUF_ST_RDEV
+ name = getttyname ("/dev", st.st_rdev, st.st_ino, save, &dostat);
+#else
+ name = getttyname ("/dev", st.st_dev, st.st_ino, save, &dostat);
+#endif
+ }
+
+ if (!name && dostat != -1)
+ {
+ dostat = 1;
+#ifdef _STATBUF_ST_RDEV
+ name = getttyname ("/dev", st.st_rdev, st.st_ino, save, &dostat);
+#else
+ name = getttyname ("/dev", st.st_dev, st.st_ino, save, &dostat);
+#endif
+ }
+
+ return name;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/ttyname_r.c b/libc/sysdeps/unix/sysv/linux/ttyname_r.c
new file mode 100644
index 000000000..bd415f167
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ttyname_r.c
@@ -0,0 +1,203 @@
+/* Copyright (C) 1991,92,93,1995-2001,2003,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <stdio-common/_itoa.h>
+#include <kernel-features.h>
+
+static int getttyname_r (char *buf, size_t buflen,
+ dev_t mydev, ino64_t myino, int save,
+ int *dostat) internal_function;
+
+static int
+internal_function attribute_compat_text_section
+getttyname_r (char *buf, size_t buflen, dev_t mydev, ino64_t myino,
+ int save, int *dostat)
+{
+ struct stat64 st;
+ DIR *dirstream;
+ struct dirent64 *d;
+ size_t devlen = strlen (buf);
+
+ dirstream = __opendir (buf);
+ if (dirstream == NULL)
+ {
+ *dostat = -1;
+ return errno;
+ }
+
+ while ((d = __readdir64 (dirstream)) != NULL)
+ if ((d->d_fileno == myino || *dostat)
+ && strcmp (d->d_name, "stdin")
+ && strcmp (d->d_name, "stdout")
+ && strcmp (d->d_name, "stderr"))
+ {
+ char *cp;
+ size_t needed = _D_EXACT_NAMLEN (d) + 1;
+
+ if (needed > buflen)
+ {
+ *dostat = -1;
+ (void) __closedir (dirstream);
+ __set_errno (ERANGE);
+ return ERANGE;
+ }
+
+ cp = __stpncpy (buf + devlen, d->d_name, needed);
+ cp[0] = '\0';
+
+ if (__xstat64 (_STAT_VER, buf, &st) == 0
+#ifdef _STATBUF_ST_RDEV
+ && S_ISCHR (st.st_mode) && st.st_rdev == mydev
+#else
+ && d->d_fileno == myino && st.st_dev == mydev
+#endif
+ )
+ {
+ (void) __closedir (dirstream);
+ __set_errno (save);
+ return 0;
+ }
+ }
+
+ (void) __closedir (dirstream);
+ __set_errno (save);
+ /* It is not clear what to return in this case. `isatty' says FD
+ refers to a TTY but no entry in /dev has this inode. */
+ return ENOTTY;
+}
+
+/* Store at most BUFLEN character of the pathname of the terminal FD is
+ open on in BUF. Return 0 on success, otherwise an error number. */
+int
+__ttyname_r (int fd, char *buf, size_t buflen)
+{
+ char procname[30];
+ struct stat64 st, st1;
+ int dostat = 0;
+ int save = errno;
+
+ /* Test for the absolute minimal size. This makes life easier inside
+ the loop. */
+ if (!buf)
+ {
+ __set_errno (EINVAL);
+ return EINVAL;
+ }
+
+ if (buflen < sizeof ("/dev/pts/"))
+ {
+ __set_errno (ERANGE);
+ return ERANGE;
+ }
+
+ if (__builtin_expect (!__isatty (fd), 0))
+ {
+ __set_errno (ENOTTY);
+ return ENOTTY;
+ }
+
+ /* We try using the /proc filesystem. */
+ *_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0';
+
+ ssize_t ret = __readlink (procname, buf, buflen - 1);
+ if (__builtin_expect (ret == -1 && errno == ENOENT, 0))
+ {
+ __set_errno (EBADF);
+ return EBADF;
+ }
+
+ if (__builtin_expect (ret == -1 && errno == ENAMETOOLONG, 0))
+ {
+ __set_errno (ERANGE);
+ return ERANGE;
+ }
+
+ if (__builtin_expect (ret != -1
+#ifndef __ASSUME_PROC_SELF_FD_SYMLINK
+ /* This is for Linux 2.0. */
+ && buf[0] != '['
+#endif
+ , 1))
+ {
+ buf[ret] = '\0';
+ return 0;
+ }
+
+ if (__fxstat64 (_STAT_VER, fd, &st) < 0)
+ return errno;
+
+ /* Prepare the result buffer. */
+ memcpy (buf, "/dev/pts/", sizeof ("/dev/pts/"));
+ buflen -= sizeof ("/dev/pts/") - 1;
+
+ if (__xstat64 (_STAT_VER, buf, &st1) == 0 && S_ISDIR (st1.st_mode))
+ {
+#ifdef _STATBUF_ST_RDEV
+ ret = getttyname_r (buf, buflen, st.st_rdev, st.st_ino, save,
+ &dostat);
+#else
+ ret = getttyname_r (buf, buflen, st.st_dev, st.st_ino, save,
+ &dostat);
+#endif
+ }
+ else
+ {
+ __set_errno (save);
+ ret = ENOENT;
+ }
+
+ if (ret && dostat != -1)
+ {
+ buf[sizeof ("/dev/") - 1] = '\0';
+ buflen += sizeof ("pts/") - 1;
+#ifdef _STATBUF_ST_RDEV
+ ret = getttyname_r (buf, buflen, st.st_rdev, st.st_ino, save,
+ &dostat);
+#else
+ ret = getttyname_r (buf, buflen, st.st_dev, st.st_ino, save,
+ &dostat);
+#endif
+ }
+
+ if (ret && dostat != -1)
+ {
+ buf[sizeof ("/dev/") - 1] = '\0';
+ dostat = 1;
+#ifdef _STATBUF_ST_RDEV
+ ret = getttyname_r (buf, buflen, st.st_rdev, st.st_ino,
+ save, &dostat);
+#else
+ ret = getttyname_r (buf, buflen, st.st_dev, st.st_ino,
+ save, &dostat);
+#endif
+ }
+
+ return ret;
+}
+
+weak_alias (__ttyname_r, ttyname_r)
diff --git a/libc/sysdeps/unix/sysv/linux/ualarm.c b/libc/sysdeps/unix/sysv/linux/ualarm.c
new file mode 100644
index 000000000..5522f5889
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ualarm.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/bsd/ualarm.c>
diff --git a/libc/sysdeps/unix/sysv/linux/ulimit.c b/libc/sysdeps/unix/sysv/linux/ulimit.c
new file mode 100644
index 000000000..9c309c371
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ulimit.c
@@ -0,0 +1,86 @@
+/* Copyright (C) 1991,92,1994-1998,2000,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <sysdep.h>
+#include <ulimit.h>
+#include <unistd.h>
+#include <sys/resource.h>
+
+/* Function depends on CMD:
+ 1 = Return the limit on the size of a file, in units of 512 bytes.
+ 2 = Set the limit on the size of a file to NEWLIMIT. Only the
+ super-user can increase the limit.
+ 3 = illegal due to shared libraries; normally is
+ (Return the maximum possible address of the data segment.)
+ 4 = Return the maximum number of files that the calling process
+ can open.
+ Returns -1 on errors. */
+long int
+__ulimit (int cmd, ...)
+{
+ struct rlimit limit;
+ va_list va;
+ long int result = -1;
+
+ va_start (va, cmd);
+
+ switch (cmd)
+ {
+ case UL_GETFSIZE:
+ /* Get limit on file size. */
+ if (__getrlimit (RLIMIT_FSIZE, &limit) == 0)
+ /* Convert from bytes to 512 byte units. */
+ result = limit.rlim_cur / 512;
+ break;
+
+ case UL_SETFSIZE:
+ /* Set limit on file size. */
+ {
+ long int newlimit = va_arg (va, long int);
+
+ if ((rlim_t) newlimit > RLIM_INFINITY / 512)
+ {
+ limit.rlim_cur = RLIM_INFINITY;
+ limit.rlim_max = RLIM_INFINITY;
+ }
+ else
+ {
+ limit.rlim_cur = newlimit * 512;
+ limit.rlim_max = newlimit * 512;
+ }
+
+ result = __setrlimit (RLIMIT_FSIZE, &limit);
+ }
+ break;
+
+ case __UL_GETOPENMAX:
+ result = __sysconf (_SC_OPEN_MAX);
+ break;
+
+ default:
+ __set_errno (EINVAL);
+ }
+
+ va_end (va);
+
+ return result;
+}
+
+weak_alias (__ulimit, ulimit);
diff --git a/libc/sysdeps/unix/sysv/linux/umount.S b/libc/sysdeps/unix/sysv/linux/umount.S
new file mode 100644
index 000000000..e18463e2e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/umount.S
@@ -0,0 +1,12 @@
+/* This hack is necessary since the kernel people are making "strange"
+ changes. They simply rename old system calls. */
+
+#include <sysdep.h>
+#ifdef __NR_oldumount
+PSEUDO (__umount, oldumount, 1)
+#else
+PSEUDO (__umount, umount, 1)
+#endif
+ ret
+PSEUDO_END(__umount)
+weak_alias (__umount, umount)
diff --git a/libc/sysdeps/unix/sysv/linux/umount2.S b/libc/sysdeps/unix/sysv/linux/umount2.S
new file mode 100644
index 000000000..92241bbf9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/umount2.S
@@ -0,0 +1,13 @@
+/* umount system call with two parameters. */
+
+#include <sysdep.h>
+#if defined __NR_oldumount || defined __NR_umount2
+#ifdef __NR_oldumount
+PSEUDO (__umount2, umount, 2)
+#else
+PSEUDO (__umount2, umount2, 2)
+#endif
+ ret
+PSEUDO_END(__umount2)
+weak_alias (__umount2, umount2)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/unlinkat.c b/libc/sysdeps/unix/sysv/linux/unlinkat.c
new file mode 100644
index 000000000..0a07a8a87
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/unlinkat.c
@@ -0,0 +1,97 @@
+/* unlinkat -- Remove a link by relative name.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysdep.h>
+#include <unistd.h>
+#include <kernel-features.h>
+
+
+/* Remove the link named NAME. */
+int
+unlinkat (fd, file, flag)
+ int fd;
+ const char *file;
+ int flag;
+{
+ int result;
+
+#ifdef __NR_unlinkat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ result = INLINE_SYSCALL (unlinkat, 3, fd, file, flag);
+# ifndef __ASSUME_ATFCTS
+ if (result == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return result;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ if (flag & ~AT_REMOVEDIR)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = __alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+ if (flag & AT_REMOVEDIR)
+ result = INTERNAL_SYSCALL (rmdir, err, 1, file);
+ else
+ result = INTERNAL_SYSCALL (unlink, err, 1, file);
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
+ {
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
+ result = -1;
+ }
+
+ return result;
+#endif
+}
diff --git a/libc/sysdeps/unix/sysv/linux/unlockpt.c b/libc/sysdeps/unix/sysv/linux/unlockpt.c
new file mode 100644
index 000000000..c5044efe5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/unlockpt.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+
+
+/* Unlock the slave pseudo terminal associated with the master pseudo
+ terminal specified by FD. */
+int
+unlockpt (int fd)
+{
+#ifdef TIOCSPTLCK
+ int save_errno = errno;
+ int unlock = 0;
+
+ if (__ioctl (fd, TIOCSPTLCK, &unlock))
+ {
+ if (errno == EINVAL)
+ {
+ __set_errno (save_errno);
+ return 0;
+ }
+ else
+ return -1;
+ }
+#endif
+ /* If we have no TIOCSPTLCK ioctl, all slave pseudo terminals are
+ unlocked by default. */
+ return 0;
+}
diff --git a/libc/sysdeps/unix/sysv/linux/updwtmp.c b/libc/sysdeps/unix/sysv/linux/updwtmp.c
new file mode 100644
index 000000000..d4d3f2cb7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/updwtmp.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1998, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <unistd.h>
+
+#define TRANSFORM_UTMP_FILE_NAME(file_name) \
+ ((strcmp (file_name, _PATH_UTMP) == 0 \
+ && __access (_PATH_UTMP "x", F_OK) == 0) ? (_PATH_UTMP "x") : \
+ ((strcmp (file_name, _PATH_WTMP) == 0 \
+ && __access ( _PATH_WTMP "x", F_OK) == 0) ? (_PATH_WTMP "x") : \
+ ((strcmp (file_name, _PATH_UTMP "x") == 0 \
+ && __access (_PATH_UTMP "x", F_OK) != 0) ? _PATH_UTMP : \
+ ((strcmp (file_name, _PATH_WTMP "x") == 0 \
+ && __access (_PATH_WTMP "x", F_OK) != 0) ? _PATH_WTMP : \
+ file_name))))
+
+#include <login/updwtmp.c>
diff --git a/libc/sysdeps/unix/sysv/linux/usleep.c b/libc/sysdeps/unix/sysv/linux/usleep.c
new file mode 100644
index 000000000..f770c5788
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/usleep.c
@@ -0,0 +1,34 @@
+/* Implementation of the BSD usleep function using nanosleep.
+ Copyright (C) 1996, 1997, 1999, 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <time.h>
+#include <unistd.h>
+
+int
+usleep (useconds_t useconds)
+{
+ struct timespec ts = { .tv_sec = (long int) (useconds / 1000000),
+ .tv_nsec = (long int) (useconds % 1000000) * 1000ul };
+
+ /* Note the usleep() is a cancellation point. But since we call
+ nanosleep() which itself is a cancellation point we do not have
+ to do anything here. */
+ return __nanosleep (&ts, NULL);
+}
diff --git a/libc/sysdeps/unix/sysv/linux/ustat.c b/libc/sysdeps/unix/sysv/linux/ustat.c
new file mode 100644
index 000000000..6ac30d8d8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/ustat.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1997, 1998, 2000, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/ustat.h>
+#include <sys/sysmacros.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+int
+ustat (dev_t dev, struct ustat *ubuf)
+{
+ unsigned long long int k_dev;
+
+ /* We must convert the value to dev_t type used by the kernel. */
+ k_dev = dev & ((1ULL << 32) - 1);
+ if (k_dev != dev)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return INLINE_SYSCALL (ustat, 2, (unsigned int) k_dev, CHECK_1 (ubuf));
+}
diff --git a/libc/sysdeps/unix/sysv/linux/utimes.c b/libc/sysdeps/unix/sysv/linux/utimes.c
new file mode 100644
index 000000000..a6095aaea
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/utimes.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 1995, 1997, 2000, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <utime.h>
+#include <sys/time.h>
+#include <sysdep.h>
+#include <kernel-features.h>
+
+
+/* Change the access time of FILE to TVP[0] and
+ the modification time of FILE to TVP[1]. */
+int
+__utimes (const char *file, const struct timeval tvp[2])
+{
+#ifdef __NR_utimes
+ int result = INLINE_SYSCALL (utimes, 2, file, tvp);
+# ifndef __ASSUME_UTIMES
+ if (result != -1 || errno != ENOSYS)
+# endif
+ return result;
+#endif
+
+ /* The utimes() syscall does not exist or is not available in the
+ used kernel. Use utime(). For this we have to convert to the
+ data format utime() expects. */
+#ifndef __ASSUME_UTIMES
+ struct utimbuf buf;
+ struct utimbuf *times;
+
+ if (tvp != NULL)
+ {
+ times = &buf;
+ buf.actime = tvp[0].tv_sec + tvp[0].tv_usec / 1000000;
+ buf.modtime = tvp[1].tv_sec + tvp[1].tv_usec / 1000000;
+ }
+ else
+ times = NULL;
+
+ return INLINE_SYSCALL (utime, 2, file, times);
+#endif
+}
+
+weak_alias (__utimes, utimes)
diff --git a/libc/sysdeps/unix/sysv/linux/utmp_file.c b/libc/sysdeps/unix/sysv/linux/utmp_file.c
new file mode 100644
index 000000000..958619a03
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/utmp_file.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1998, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <unistd.h>
+
+#define TRANSFORM_UTMP_FILE_NAME(file_name) \
+ ((strcmp (file_name, _PATH_UTMP) == 0 \
+ && __access (_PATH_UTMP "x", F_OK) == 0) ? (_PATH_UTMP "x") : \
+ ((strcmp (file_name, _PATH_WTMP) == 0 \
+ && __access ( _PATH_WTMP "x", F_OK) == 0) ? (_PATH_WTMP "x") : \
+ ((strcmp (file_name, _PATH_UTMP "x") == 0 \
+ && __access (_PATH_UTMP "x", F_OK) != 0) ? _PATH_UTMP : \
+ ((strcmp (file_name, _PATH_WTMP "x") == 0 \
+ && __access (_PATH_WTMP "x", F_OK) != 0) ? _PATH_WTMP : \
+ file_name))))
+
+#include <login/utmp_file.c>
diff --git a/libc/sysdeps/unix/sysv/linux/vfork.c b/libc/sysdeps/unix/sysv/linux/vfork.c
new file mode 100644
index 000000000..c8c13d0fd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/vfork.c
@@ -0,0 +1 @@
+#include <posix/vfork.c>
diff --git a/libc/sysdeps/unix/sysv/linux/wait.c b/libc/sysdeps/unix/sysv/linux/wait.c
new file mode 100644
index 000000000..39d1066dd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wait.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991,1995,1996,1997,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/wait.h>
+#include <errno.h>
+#include <sys/resource.h>
+#include <stddef.h>
+#include <sysdep-cancel.h>
+
+/* Wait for a child to die. When one does, put its status in *STAT_LOC
+ and return its process ID. For errors, return (pid_t) -1. */
+pid_t
+__libc_wait (__WAIT_STATUS_DEFN stat_loc)
+{
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (wait4, 4, WAIT_ANY, stat_loc, 0,
+ (struct rusage *) NULL);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ pid_t result = INLINE_SYSCALL (wait4, 4, WAIT_ANY, stat_loc, 0,
+ (struct rusage *) NULL);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+weak_alias (__libc_wait, __wait)
+weak_alias (__libc_wait, wait)
diff --git a/libc/sysdeps/unix/sysv/linux/wait3.c b/libc/sysdeps/unix/sysv/linux/wait3.c
new file mode 100644
index 000000000..0b3bdee77
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wait3.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/bsd/bsd4.4/wait3.c>
diff --git a/libc/sysdeps/unix/sysv/linux/waitid.c b/libc/sysdeps/unix/sysv/linux/waitid.c
new file mode 100644
index 000000000..71d5d3aa1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/waitid.c
@@ -0,0 +1,71 @@
+/* Linux implementation of waitid.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <kernel-features.h>
+#include <sysdep.h>
+
+
+#ifdef __NR_waitid
+
+# if __ASSUME_WAITID_SYSCALL > 0
+
+static inline int
+do_waitid (idtype_t idtype, id_t id, siginfo_t *infop, int options)
+{
+ /* The unused fifth argument is a `struct rusage *' that we could
+ pass if we were using waitid to simulate wait3/wait4. */
+ return INLINE_SYSCALL (waitid, 5, idtype, id, infop, options, NULL);
+}
+# define NO_DO_WAITID
+
+# else
+
+static int do_compat_waitid (idtype_t idtype, id_t id,
+ siginfo_t *infop, int options);
+# define DO_WAITID do_compat_waitid
+
+static int
+do_waitid (idtype_t idtype, id_t id, siginfo_t *infop, int options)
+{
+ static int waitid_works;
+ if (waitid_works > 0)
+ return INLINE_SYSCALL (waitid, 5, idtype, id, infop, options, NULL);
+ if (waitid_works == 0)
+ {
+ int result = INLINE_SYSCALL (waitid, 5,
+ idtype, id, infop, options, NULL);
+ if (result < 0 && errno == ENOSYS)
+ waitid_works = -1;
+ else
+ {
+ waitid_works = 1;
+ return result;
+ }
+ }
+ return do_compat_waitid (idtype, id, infop, options);
+}
+
+# endif
+
+#endif
+
+#include "sysdeps/posix/waitid.c"
diff --git a/libc/sysdeps/unix/sysv/linux/waitpid.c b/libc/sysdeps/unix/sysv/linux/waitpid.c
new file mode 100644
index 000000000..32b01c0a5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/waitpid.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 1991,92,95,96,97,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep-cancel.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+
+__pid_t
+__libc_waitpid (__pid_t pid, int *stat_loc, int options)
+{
+ if (SINGLE_THREAD_P)
+ {
+#ifdef __NR_waitpid
+ return INLINE_SYSCALL (waitpid, 3, pid, stat_loc, options);
+#else
+ return INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL);
+#endif
+ }
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+#ifdef __NR_waitpid
+ int result = INLINE_SYSCALL (waitpid, 3, pid, stat_loc, options);
+#else
+ int result = INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL);
+#endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+weak_alias (__libc_waitpid, __waitpid)
+libc_hidden_weak (__waitpid)
+weak_alias (__libc_waitpid, waitpid)
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/fstatfs64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/fstatfs64.c
new file mode 100644
index 000000000..2be4e59ba
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/fstatfs64.c
@@ -0,0 +1 @@
+/* fstatfs64 is the same as fstatfs. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/fstatvfs.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/fstatvfs.c
new file mode 100644
index 000000000..d04bcd4b5
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/fstatvfs.c
@@ -0,0 +1,5 @@
+#define __fstatvfs64(file, buf) __no_fstatvfs64(file, buf)
+#define fstatvfs64(file, buf) no_fstatvfs64(file, buf)
+#include "../fstatvfs.c"
+strong_alias (fstatvfs, __fstatvfs64)
+weak_alias (fstatvfs, fstatvfs64)
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/fstatvfs64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/fstatvfs64.c
new file mode 100644
index 000000000..60f3dfec6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/fstatvfs64.c
@@ -0,0 +1 @@
+/* fstatvfs64 is the same as fstatvfs. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/ftruncate64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/ftruncate64.c
new file mode 100644
index 000000000..673a8b525
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/ftruncate64.c
@@ -0,0 +1 @@
+/* ftruncate64 is the same as ftruncate. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/fxstat.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/fxstat.c
new file mode 100644
index 000000000..5d69eb830
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/fxstat.c
@@ -0,0 +1,48 @@
+/* fxstat using old-style Unix fstat system call.
+ Copyright (C) 1991, 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ho hum, since xstat == xstat64 we must get rid of the prototype or gcc
+ will complain since they don't strictly match. */
+#define __fxstat64 __fxstat64_disable
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Get information about the file FD in BUF. */
+int
+__fxstat (int vers, int fd, struct stat *buf)
+{
+ if (vers == _STAT_VER_KERNEL || vers == _STAT_VER_LINUX)
+ return INLINE_SYSCALL (fstat, 2, fd, CHECK_1 (buf));
+
+ __set_errno (EINVAL);
+ return -1;
+}
+
+hidden_def (__fxstat)
+weak_alias (__fxstat, _fxstat);
+#undef __fxstat64
+strong_alias (__fxstat, __fxstat64);
+hidden_ver (__fxstat, __fxstat64)
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/fxstat64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/fxstat64.c
new file mode 100644
index 000000000..9eff9ebeb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/fxstat64.c
@@ -0,0 +1 @@
+/* fxstat64 is in fxstat.c */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c
new file mode 100644
index 000000000..8b1c932ba
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c
@@ -0,0 +1,109 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ho hum, since fxstatat == fxstatat64 we must get rid of the
+ prototype or gcc will complain since they don't strictly match. */
+#define __fxstatat64 __fxstatat64_disable
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+
+/* Get information about the file NAME relative to FD in ST. */
+int
+__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
+{
+ if (vers != _STAT_VER_KERNEL && vers != _STAT_VER_LINUX)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ int res;
+
+#ifdef __NR_newfstatat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ res = INLINE_SYSCALL (newfstatat, 4, fd, file, st, flag);
+# ifndef __ASSUME_ATFCTS
+ if (res == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return res;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ res = INTERNAL_SYSCALL (lstat, err, 2, file, CHECK_1 (st));
+ else
+ res = INTERNAL_SYSCALL (stat, err, 2, file, CHECK_1 (st));
+
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
+ {
+ __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (res, err), fd, buf);
+ res = -1;
+ }
+
+ return res;
+#endif
+}
+libc_hidden_def (__fxstatat)
+#undef __fxstatat64
+strong_alias (__fxstatat, __fxstatat64);
+strong_alias (__fxstatat64, __GI___fxstatat64)
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/fxstatat64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/fxstatat64.c
new file mode 100644
index 000000000..05e7f413b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/fxstatat64.c
@@ -0,0 +1 @@
+/* fxstatat64 is in fxstatat.c */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/getdents.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/getdents.c
new file mode 100644
index 000000000..5ea4c572a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/getdents.c
@@ -0,0 +1,4 @@
+#define __getdents64 __no___getdents64_decl
+#include <sysdeps/unix/sysv/linux/getdents.c>
+#undef __getdents64
+weak_alias (__getdents, __getdents64);
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/getdents64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/getdents64.c
new file mode 100644
index 000000000..0df2c8f4c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/getdents64.c
@@ -0,0 +1 @@
+/* getdents64 is in getdents.c */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/getrlimit64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/getrlimit64.c
new file mode 100644
index 000000000..9feab0e6b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/getrlimit64.c
@@ -0,0 +1 @@
+/* getrlimit64 is the same as getrlimit. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/glob64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/glob64.c
new file mode 100644
index 000000000..33918ea6a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/glob64.c
@@ -0,0 +1 @@
+/* glob64 is in glob.c */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/internal_statvfs64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/internal_statvfs64.c
new file mode 100644
index 000000000..d2a3509c6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/internal_statvfs64.c
@@ -0,0 +1 @@
+/* Nothing. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/lxstat.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/lxstat.c
new file mode 100644
index 000000000..2b937760e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/lxstat.c
@@ -0,0 +1,48 @@
+/* lxstat using old-style Unix lstat system call.
+ Copyright (C) 1991, 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ho hum, since xstat == xstat64 we must get rid of the prototype or gcc
+ will complain since they don't strictly match. */
+#define __lxstat64 __lxstat64_disable
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Get information about the file FD in BUF. */
+int
+__lxstat (int vers, const char *name, struct stat *buf)
+{
+ if (vers == _STAT_VER_KERNEL || vers == _STAT_VER_LINUX)
+ return INLINE_SYSCALL (lstat, 2, CHECK_STRING (name), CHECK_1 (buf));
+
+ __set_errno (EINVAL);
+ return -1;
+}
+
+hidden_def (__lxstat)
+weak_alias (__lxstat, _lxstat);
+#undef __lxstat64
+strong_alias (__lxstat, __lxstat64);
+hidden_ver (__lxstat, __lxstat64)
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/lxstat64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/lxstat64.c
new file mode 100644
index 000000000..bb5dbd0ff
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/lxstat64.c
@@ -0,0 +1 @@
+/* lxstat64 is in lxstat.c */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/mmap64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/mmap64.c
new file mode 100644
index 000000000..0dbd384a6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/mmap64.c
@@ -0,0 +1 @@
+/* mmap64 is the same as mmap. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/posix_fadvise.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/posix_fadvise.c
new file mode 100644
index 000000000..b23074804
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/posix_fadvise.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define posix_fadvise64 __no_posix_fadvise64
+#include <errno.h>
+#include <fcntl.h>
+#include <sysdep.h>
+#undef posix_fadvise64
+
+/* Advice the system about the expected behaviour of the application with
+ respect to the file associated with FD. */
+
+int
+posix_fadvise (int fd, off_t offset, off_t len, int advise)
+{
+#ifdef __NR_fadvise64
+ INTERNAL_SYSCALL_DECL (err);
+ int ret = INTERNAL_SYSCALL (fadvise64, err, 4, fd, offset, len, advise);
+ if (INTERNAL_SYSCALL_ERROR_P (ret, err))
+ return INTERNAL_SYSCALL_ERRNO (ret, err);
+ return 0;
+#else
+ return ENOSYS;
+#endif
+}
+strong_alias (posix_fadvise, posix_fadvise64)
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/posix_fadvise64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/posix_fadvise64.c
new file mode 100644
index 000000000..c9f72c4ce
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/posix_fadvise64.c
@@ -0,0 +1 @@
+/* posix_fadvise64 is in posix_fadvise.c */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/pread64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/pread64.c
new file mode 100644
index 000000000..b7f298dea
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/pread64.c
@@ -0,0 +1 @@
+/* Empty since the pread syscall is equivalent. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/pwrite64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/pwrite64.c
new file mode 100644
index 000000000..b7f298dea
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/pwrite64.c
@@ -0,0 +1 @@
+/* Empty since the pread syscall is equivalent. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/readdir.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/readdir.c
new file mode 100644
index 000000000..300ebb262
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/readdir.c
@@ -0,0 +1,7 @@
+#define readdir64 __no_readdir64_decl
+#define __readdir64 __no___readdir64_decl
+#include <sysdeps/unix/readdir.c>
+#undef __readdir64
+strong_alias (__readdir, __readdir64)
+#undef readdir64
+weak_alias (__readdir, readdir64)
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/readdir64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/readdir64.c
new file mode 100644
index 000000000..9796431dc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/readdir64.c
@@ -0,0 +1 @@
+/* readdir64 is in readdir.c */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/readdir64_r.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/readdir64_r.c
new file mode 100644
index 000000000..b8fe9a31b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/readdir64_r.c
@@ -0,0 +1 @@
+/* readdir64_r is in readdir_r.c */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c
new file mode 100644
index 000000000..adb92db6a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c
@@ -0,0 +1,4 @@
+#define readdir64_r __no_readdir64_r_decl
+#include <sysdeps/unix/readdir_r.c>
+#undef readdir64_r
+weak_alias (__readdir_r, readdir64_r)
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/sendfile64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/sendfile64.c
new file mode 100644
index 000000000..4c451bd09
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/sendfile64.c
@@ -0,0 +1 @@
+/* sendfile64 is alias of sendfile syscall. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/setrlimit64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/setrlimit64.c
new file mode 100644
index 000000000..8edcff008
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/setrlimit64.c
@@ -0,0 +1 @@
+/* setrlimit64 is the same as setrlimit. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/statfs64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/statfs64.c
new file mode 100644
index 000000000..06bc68826
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/statfs64.c
@@ -0,0 +1 @@
+/* statfs64 is the same as statfs. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/statvfs.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/statvfs.c
new file mode 100644
index 000000000..f369976cc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/statvfs.c
@@ -0,0 +1,5 @@
+#define __statvfs64(file, buf) __no_statvfs64(file, buf)
+#define statvfs64(file, buf) no_statvfs64(file, buf)
+#include "../statvfs.c"
+strong_alias (statvfs, __statvfs64)
+weak_alias (statvfs, statvfs64)
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/statvfs64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/statvfs64.c
new file mode 100644
index 000000000..510015e42
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/statvfs64.c
@@ -0,0 +1 @@
+/* statvfs64 is the same as statvfs. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list b/libc/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
new file mode 100644
index 000000000..d377db968
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
@@ -0,0 +1,17 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+# Whee! 64-bit systems naturally implement llseek.
+llseek EXTRA lseek Ci:iii __libc_lseek __lseek lseek __libc_lseek64 __llseek llseek __lseek64 lseek64
+lseek llseek -
+pread - pread Ci:ibni __libc_pread __libc_pread64 __pread pread __pread64 pread64
+pwrite - pwrite Ci:ibni __libc_pwrite __libc_pwrite64 __pwrite pwrite __pwrite64 pwrite64
+fstatfs - fstatfs i:ip __fstatfs fstatfs fstatfs64 __fstatfs64
+statfs - statfs i:sp __statfs statfs statfs64
+mmap - mmap b:aniiii __mmap mmap __mmap64 mmap64
+ftruncate - ftruncate i:ii __ftruncate ftruncate ftruncate64 __ftruncate64
+truncate - truncate i:si truncate truncate64
+getrlimit - getrlimit i:ip __getrlimit getrlimit getrlimit64
+setrlimit - setrlimit i:ip __setrlimit setrlimit setrlimit64
+readahead - readahead i:iii __readahead readahead
+sendfile - sendfile i:iipi sendfile sendfile64
+sync_file_range - sync_file_range i:iiii sync_file_range
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/truncate64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/truncate64.c
new file mode 100644
index 000000000..899976887
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/truncate64.c
@@ -0,0 +1 @@
+/* truncate64 is the same as truncate. */
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/xstat.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/xstat.c
new file mode 100644
index 000000000..38f32b664
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/xstat.c
@@ -0,0 +1,47 @@
+/* xstat using old-style Unix stat system call.
+ Copyright (C) 1991, 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ho hum, since xstat == xstat64 we must get rid of the prototype or gcc
+ will complain since they don't strictly match. */
+#define __xstat64 __xstat64_disable
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Get information about the file NAME in BUF. */
+int
+__xstat (int vers, const char *name, struct stat *buf)
+{
+ if (vers == _STAT_VER_KERNEL || vers == _STAT_VER_LINUX)
+ return INLINE_SYSCALL (stat, 2, name, CHECK_1 (buf));
+
+ __set_errno (EINVAL);
+ return -1;
+}
+hidden_def (__xstat)
+weak_alias (__xstat, _xstat);
+#undef __xstat64
+strong_alias (__xstat, __xstat64);
+hidden_ver (__xstat, __xstat64)
diff --git a/libc/sysdeps/unix/sysv/linux/wordsize-64/xstat64.c b/libc/sysdeps/unix/sysv/linux/wordsize-64/xstat64.c
new file mode 100644
index 000000000..e7acd3b45
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/wordsize-64/xstat64.c
@@ -0,0 +1 @@
+/* xstat64 is in xstat.c */
diff --git a/libc/sysdeps/unix/sysv/linux/writev.c b/libc/sysdeps/unix/sysv/linux/writev.c
new file mode 100644
index 000000000..05978665f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/writev.c
@@ -0,0 +1,75 @@
+/* writev supports all Linux kernels >= 2.0.
+ Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/param.h>
+#include <sys/uio.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+static ssize_t __atomic_writev_replacement (int, const struct iovec *,
+ int) internal_function;
+
+
+/* Not all versions of the kernel support the large number of records. */
+#ifndef UIO_FASTIOV
+# define UIO_FASTIOV 8 /* 8 is a safe number. */
+#endif
+
+
+/* We should deal with kernel which have a smaller UIO_FASTIOV as well
+ as a very big count. */
+static ssize_t
+do_writev (int fd, const struct iovec *vector, int count)
+{
+ ssize_t bytes_written;
+
+ bytes_written = INLINE_SYSCALL (writev, 3, fd, CHECK_N (vector, count), count);
+
+ if (bytes_written >= 0 || errno != EINVAL || count <= UIO_FASTIOV)
+ return bytes_written;
+
+ return __atomic_writev_replacement (fd, vector, count);
+}
+
+ssize_t
+__libc_writev (fd, vector, count)
+ int fd;
+ const struct iovec *vector;
+ int count;
+{
+ if (SINGLE_THREAD_P)
+ return do_writev (fd, vector, count);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = do_writev (fd, vector, count);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+strong_alias (__libc_writev, __writev)
+weak_alias (__libc_writev, writev)
+
+#define __libc_writev static internal_function __atomic_writev_replacement
+#include <sysdeps/posix/writev.c>
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/Implies b/libc/sysdeps/unix/sysv/linux/x86_64/Implies
new file mode 100644
index 000000000..8d91c8009
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/Implies
@@ -0,0 +1 @@
+unix/sysv/linux/wordsize-64
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/Makefile b/libc/sysdeps/unix/sysv/linux/x86_64/Makefile
new file mode 100644
index 000000000..0f2036723
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -0,0 +1,15 @@
+32bit-predefine = __i386__
+64bit-predefine = __x86_64__
+
+ifeq ($(subdir),misc)
+sysdep_routines += ioperm iopl
+sysdep_headers += sys/perm.h sys/reg.h sys/debugreg.h sys/io.h
+endif
+
+ifeq ($(subdir),stdlib)
+sysdep_routines += __start_context
+endif
+
+ifeq ($(subdir),stdlib)
+gen-as-const-headers += ucontext_i.sym
+endif
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/Versions b/libc/sysdeps/unix/sysv/linux/x86_64/Versions
new file mode 100644
index 000000000..fd1b3cc29
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/Versions
@@ -0,0 +1,9 @@
+libc {
+ GLIBC_2.2.5 {
+ arch_prctl; __arch_prctl;
+
+ ioperm; iopl;
+
+ modify_ldt;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/__start_context.S b/libc/sysdeps/unix/sysv/linux/x86_64/__start_context.S
new file mode 100644
index 000000000..37d391760
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/__start_context.S
@@ -0,0 +1,49 @@
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* This is the helper code which gets called if a function which is
+ registered with 'makecontext' returns. In this case we have to
+ install the context listed in the uc_link element of the context
+ 'makecontext' manipulated at the time of the 'makecontext' call.
+ If the pointer is NULL the process must terminate. */
+
+
+ENTRY(__start_context)
+ /* This removes the parameters passed to the function given to
+ 'makecontext' from the stack. RBX contains the address
+ on the stack pointer for the next context. */
+ movq %rbx, %rsp
+
+ popq %rdi /* This is the next context. */
+ cfi_adjust_cfa_offset(-8)
+ testq %rdi, %rdi
+ je 2f /* If it is zero exit. */
+
+ call JUMPTARGET(__setcontext)
+ /* If this returns (which can happen if the syscall fails) we'll
+ exit the program with the return error value (-1). */
+
+2: movq %rax,%rdi
+ call HIDDEN_JUMPTARGET(exit)
+ /* The 'exit' call should never return. In case it does cause
+ the process to terminate. */
+ hlt
+END(__start_context)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/a.out.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/a.out.h
new file mode 100644
index 000000000..228a8d41a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/a.out.h
@@ -0,0 +1,13 @@
+#ifndef __A_OUT_GNU_H__
+# error "Never use <bits/a.out.h> directly; include <a.out.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+
+/* Signal to users of this header that this architecture really doesn't
+ support a.out binary format. */
+#define __NO_A_OUT_SUPPORT 1
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/environments.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/environments.h
new file mode 100644
index 000000000..a51a564cb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/environments.h
@@ -0,0 +1,87 @@
+/* Copyright (C) 1999, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _UNISTD_H
+# error "Never include this file directly. Use <unistd.h> instead"
+#endif
+
+#include <bits/wordsize.h>
+
+/* This header should define the following symbols under the described
+ situations. A value `1' means that the model is always supported,
+ `-1' means it is never supported. Undefined means it cannot be
+ statically decided.
+
+ _POSIX_V6_ILP32_OFF32 32bit int, long, pointers, and off_t type
+ _POSIX_V6_ILP32_OFFBIG 32bit int, long, and pointers and larger off_t type
+
+ _POSIX_V6_LP64_OFF32 64bit long and pointers and 32bit off_t type
+ _POSIX_V6_LPBIG_OFFBIG 64bit long and pointers and large off_t type
+
+ The macros _XBS5_ILP32_OFF32, _XBS5_ILP32_OFFBIG, _XBS5_LP64_OFF32, and
+ _XBS5_LPBIG_OFFBIG were used in previous versions of the Unix standard
+ and are available only for compatibility.
+*/
+
+#if __WORDSIZE == 64
+
+/* Environments with 32-bit wide pointers are optionally provided.
+ Therefore following macros aren't defined:
+ # undef _POSIX_V6_ILP32_OFF32
+ # undef _POSIX_V6_ILP32_OFFBIG
+ # undef _XBS5_ILP32_OFF32
+ # undef _XBS5_ILP32_OFFBIG
+ and users need to check at runtime. */
+
+/* We also have no use (for now) for an environment with bigger pointers
+ and offsets. */
+# define _POSIX_V6_LPBIG_OFFBIG -1
+# define _XBS5_LPBIG_OFFBIG -1
+
+/* By default we have 64-bit wide `long int', pointers and `off_t'. */
+# define _POSIX_V6_LP64_OFF64 1
+# define _XBS5_LP64_OFF64 1
+
+#else /* __WORDSIZE == 32 */
+
+/* By default we have 32-bit wide `int', `long int', pointers and `off_t'
+ and all platforms support LFS. */
+# define _POSIX_V6_ILP32_OFF32 1
+# define _POSIX_V6_ILP32_OFFBIG 1
+# define _XBS5_ILP32_OFF32 1
+# define _XBS5_ILP32_OFFBIG 1
+
+/* We optionally provide an environment with the above size but an 64-bit
+ side `off_t'. Therefore we don't define _XBS5_ILP32_OFFBIG. */
+
+/* Environments with 64-bit wide pointers can be provided,
+ so these macros aren't defined:
+ # undef _POSIX_V6_LP64_OFF64
+ # undef _POSIX_V6_LPBIG_OFFBIG
+ # undef _XBS5_LP64_OFF64
+ # undef _XBS5_LPBIG_OFFBIG
+ and sysconf tests for it at runtime. */
+
+#endif /* __WORDSIZE == 32 */
+
+#define __ILP32_OFF32_CFLAGS "-m32"
+#define __ILP32_OFFBIG_CFLAGS "-m32 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+#define __ILP32_OFF32_LDFLAGS "-m32"
+#define __ILP32_OFFBIG_LDFLAGS "-m32"
+#define __LP64_OFF64_CFLAGS "-m64"
+#define __LP64_OFF64_LDFLAGS "-m64"
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h
new file mode 100644
index 000000000..4f10f2222
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h
@@ -0,0 +1,250 @@
+/* O_*, F_*, FD_* bit values for Linux/x86-64.
+ Copyright (C) 2001, 2002, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#include <sys/types.h>
+#include <bits/wordsize.h>
+#ifdef __USE_GNU
+# include <bits/uio.h>
+#endif
+
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_ACCMODE 0003
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+#define O_CREAT 0100 /* not fcntl */
+#define O_EXCL 0200 /* not fcntl */
+#define O_NOCTTY 0400 /* not fcntl */
+#define O_TRUNC 01000 /* not fcntl */
+#define O_APPEND 02000
+#define O_NONBLOCK 04000
+#define O_NDELAY O_NONBLOCK
+#define O_SYNC 010000
+#define O_FSYNC O_SYNC
+#define O_ASYNC 020000
+
+#ifdef __USE_GNU
+# define O_DIRECT 040000 /* Direct disk access. */
+# define O_DIRECTORY 0200000 /* Must be a directory. */
+# define O_NOFOLLOW 0400000 /* Do not follow links. */
+# define O_NOATIME 01000000 /* Do not set atime. */
+#endif
+
+/* For now Linux has synchronisity options for data and read operations.
+ We define the symbols here but let them do the same as O_SYNC since
+ this is a superset. */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC O_SYNC /* Synchronize data. */
+# define O_RSYNC O_SYNC /* Synchronize read operations. */
+#endif
+
+#ifdef __USE_LARGEFILE64
+# if __WORDSIZE == 64
+# define O_LARGEFILE 0
+# else
+# define O_LARGEFILE 0100000
+# endif
+#endif
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#if __WORDSIZE == 64
+# define F_GETLK 5 /* Get record locking info. */
+# define F_SETLK 6 /* Set record locking info (non-blocking). */
+# define F_SETLKW 7 /* Set record locking info (blocking). */
+/* Not necessary, we always have 64-bit offsets. */
+# define F_GETLK64 5 /* Get record locking info. */
+# define F_SETLK64 6 /* Set record locking info (non-blocking). */
+# define F_SETLKW64 7 /* Set record locking info (blocking). */
+#else
+# ifndef __USE_FILE_OFFSET64
+# define F_GETLK 5 /* Get record locking info. */
+# define F_SETLK 6 /* Set record locking info (non-blocking). */
+# define F_SETLKW 7 /* Set record locking info (blocking). */
+# else
+# define F_GETLK F_GETLK64 /* Get record locking info. */
+# define F_SETLK F_SETLK64 /* Set record locking info (non-blocking).*/
+# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */
+# endif
+# define F_GETLK64 12 /* Get record locking info. */
+# define F_SETLK64 13 /* Set record locking info (non-blocking). */
+# define F_SETLKW64 14 /* Set record locking info (blocking). */
+#endif
+
+#if defined __USE_BSD || defined __USE_UNIX98
+# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */
+# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETSIG 10 /* Set number of signal to be sent. */
+# define F_GETSIG 11 /* Get number of signal to be sent. */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETLEASE 1024 /* Set a lease. */
+# define F_GETLEASE 1025 /* Enquire what lease is active. */
+# define F_NOTIFY 1026 /* Request notfications on a directory. */
+#endif
+
+/* For F_[GET|SET]FD. */
+#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
+#define F_RDLCK 0 /* Read lock. */
+#define F_WRLCK 1 /* Write lock. */
+#define F_UNLCK 2 /* Remove lock. */
+
+/* For old implementation of bsd flock(). */
+#define F_EXLCK 4 /* or 3 */
+#define F_SHLCK 8 /* or 4 */
+
+#ifdef __USE_BSD
+/* Operations for bsd flock(), also used by the kernel implementation. */
+# define LOCK_SH 1 /* shared lock */
+# define LOCK_EX 2 /* exclusive lock */
+# define LOCK_NB 4 /* or'd with one of the above to prevent
+ blocking */
+# define LOCK_UN 8 /* remove lock */
+#endif
+
+#ifdef __USE_GNU
+# define LOCK_MAND 32 /* This is a mandatory flock: */
+# define LOCK_READ 64 /* ... which allows concurrent read operations. */
+# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */
+# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */
+#endif
+
+#ifdef __USE_GNU
+/* Types of directory notifications that may be requested with F_NOTIFY. */
+# define DN_ACCESS 0x00000001 /* File accessed. */
+# define DN_MODIFY 0x00000002 /* File modified. */
+# define DN_CREATE 0x00000004 /* File created. */
+# define DN_DELETE 0x00000008 /* File removed. */
+# define DN_RENAME 0x00000010 /* File renamed. */
+# define DN_ATTRIB 0x00000020 /* File changed attibutes. */
+# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */
+#endif
+
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+#ifndef __USE_FILE_OFFSET64
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+#else
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+#endif
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+#endif
+
+/* Define some more compatibility macros to be backward compatible with
+ BSD systems which did not managed to hide these kernel macros. */
+#ifdef __USE_BSD
+# define FAPPEND O_APPEND
+# define FFSYNC O_FSYNC
+# define FASYNC O_ASYNC
+# define FNONBLOCK O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif /* Use BSD. */
+
+/* Advise to `posix_fadvise'. */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
+# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
+#endif
+
+
+#ifdef __USE_GNU
+/* Flags for SYNC_FILE_RANGE. */
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+
+/* Flags for SPLICE and VMSPLICE. */
+# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */
+# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing
+ (but we may still block on the fd
+ we splice from/to). */
+# define SPLICE_F_MORE 4 /* Expect more data. */
+# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
+#endif
+
+__BEGIN_DECLS
+
+#ifdef __USE_GNU
+
+/* Provide kernel hint to read ahead. */
+extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
+ __THROW;
+
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice address range into a pipe. */
+extern int vmsplice (int __fdout, const struct iovec *__iov, size_t __count,
+ unsigned int __flags);
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/mman.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/mman.h
new file mode 100644
index 000000000..535c9edcf
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/mman.h
@@ -0,0 +1,104 @@
+/* Definitions for POSIX memory map interface. Linux/x86_64 version.
+ Copyright (C) 2001, 2003, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MMAN_H
+# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
+#endif
+
+/* The following definitions basically come from the kernel headers.
+ But the kernel header is not namespace clean. */
+
+
+/* Protections are chosen from these bits, OR'd together. The
+ implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ without PROT_READ. The only guarantees are that no writing will be
+ allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
+
+#define PROT_READ 0x1 /* Page can be read. */
+#define PROT_WRITE 0x2 /* Page can be written. */
+#define PROT_EXEC 0x4 /* Page can be executed. */
+#define PROT_NONE 0x0 /* Page can not be accessed. */
+#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
+ growsdown vma (mprotect only). */
+#define PROT_GROWSUP 0x02000000 /* Extend change to start of
+ growsup vma (mprotect only). */
+
+/* Sharing types (must choose one and only one of these). */
+#define MAP_SHARED 0x01 /* Share changes. */
+#define MAP_PRIVATE 0x02 /* Changes are private. */
+#ifdef __USE_MISC
+# define MAP_TYPE 0x0f /* Mask for type of mapping. */
+#endif
+
+/* Other flags. */
+#define MAP_FIXED 0x10 /* Interpret addr exactly. */
+#ifdef __USE_MISC
+# define MAP_FILE 0
+# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
+# define MAP_ANON MAP_ANONYMOUS
+# define MAP_32BIT 0x40 /* Only give out 32-bit addresses. */
+#endif
+
+/* These are Linux-specific. */
+#ifdef __USE_MISC
+# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */
+# define MAP_DENYWRITE 0x00800 /* ETXTBSY */
+# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */
+# define MAP_LOCKED 0x02000 /* Lock the mapping. */
+# define MAP_NORESERVE 0x04000 /* Don't check for reservations. */
+# define MAP_POPULATE 0x08000 /* Populate (prefault) pagetables. */
+# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */
+#endif
+
+/* Flags to `msync'. */
+#define MS_ASYNC 1 /* Sync memory asynchronously. */
+#define MS_SYNC 4 /* Synchronous memory sync. */
+#define MS_INVALIDATE 2 /* Invalidate the caches. */
+
+/* Flags for `mlockall'. */
+#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
+#define MCL_FUTURE 2 /* Lock all additions to address
+ space. */
+
+/* Flags for `mremap'. */
+#ifdef __USE_GNU
+# define MREMAP_MAYMOVE 1
+# define MREMAP_FIXED 2
+#endif
+
+/* Advice to `madvise'. */
+#ifdef __USE_BSD
+# define MADV_NORMAL 0 /* No further special treatment. */
+# define MADV_RANDOM 1 /* Expect random page references. */
+# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define MADV_WILLNEED 3 /* Will need these pages. */
+# define MADV_DONTNEED 4 /* Don't need these pages. */
+# define MADV_REMOVE 9 /* Remove these pages and resources. */
+# define MADV_DONTFORK 10 /* Do not inherit across fork. */
+# define MADV_DOFORK 11 /* Do inherit across fork. */
+#endif
+
+/* The POSIX people had to invent similar names for the same things. */
+#ifdef __USE_XOPEN2K
+# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/msq.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/msq.h
new file mode 100644
index 000000000..422218a5f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/msq.h
@@ -0,0 +1,83 @@
+/* Copyright (C) 1995, 1996, 1997, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* Define options for message queue functions. */
+#define MSG_NOERROR 010000 /* no error if message is too big */
+#ifdef __USE_GNU
+# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+#endif
+
+/* Types used in the structure definition. */
+typedef unsigned long int msgqnum_t;
+typedef unsigned long int msglen_t;
+
+/* Structure of record for one message inside the kernel.
+ The type `struct msg' is opaque. */
+struct msqid_ds
+{
+ struct ipc_perm msg_perm; /* structure describing operation permission */
+ __time_t msg_stime; /* time of last msgsnd command */
+#if __WORDSIZE == 32
+ unsigned long int __unused1;
+#endif
+ __time_t msg_rtime; /* time of last msgrcv command */
+#if __WORDSIZE == 32
+ unsigned long int __unused2;
+#endif
+ __time_t msg_ctime; /* time of last change */
+#if __WORDSIZE == 32
+ unsigned long int __unused3;
+#endif
+ unsigned long int __msg_cbytes; /* current number of bytes on queue */
+ msgqnum_t msg_qnum; /* number of messages currently on queue */
+ msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+ __pid_t msg_lspid; /* pid of last msgsnd() */
+ __pid_t msg_lrpid; /* pid of last msgrcv() */
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+};
+
+#ifdef __USE_MISC
+
+# define msg_cbytes __msg_cbytes
+
+/* ipcs ctl commands */
+# define MSG_STAT 11
+# define MSG_INFO 12
+
+/* buffer for msgctl calls IPC_INFO, MSG_INFO */
+struct msginfo
+ {
+ int msgpool;
+ int msgmap;
+ int msgmax;
+ int msgmnb;
+ int msgmni;
+ int msgssz;
+ int msgtql;
+ unsigned short int msgseg;
+ };
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/sem.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/sem.h
new file mode 100644
index 000000000..9b1d993ee
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/sem.h
@@ -0,0 +1,87 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SEM_H
+# error "Never include <bits/sem.h> directly; use <sys/sem.h> instead."
+#endif
+
+#include <sys/types.h>
+
+/* Flags for `semop'. */
+#define SEM_UNDO 0x1000 /* undo the operation on exit */
+
+/* Commands for `semctl'. */
+#define GETPID 11 /* get sempid */
+#define GETVAL 12 /* get semval */
+#define GETALL 13 /* get all semval's */
+#define GETNCNT 14 /* get semncnt */
+#define GETZCNT 15 /* get semzcnt */
+#define SETVAL 16 /* set semval */
+#define SETALL 17 /* set all semval's */
+
+
+/* Data structure describing a set of semaphores. */
+struct semid_ds
+{
+ struct ipc_perm sem_perm; /* operation permission struct */
+ __time_t sem_otime; /* last semop() time */
+ unsigned long int __unused1;
+ __time_t sem_ctime; /* last time changed by semctl() */
+ unsigned long int __unused2;
+ unsigned long int sem_nsems; /* number of semaphores in set */
+ unsigned long int __unused3;
+ unsigned long int __unused4;
+};
+
+/* The user should define a union like the following to use it for arguments
+ for `semctl'.
+
+ union semun
+ {
+ int val; <= value for SETVAL
+ struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET
+ unsigned short int *array; <= array for GETALL & SETALL
+ struct seminfo *__buf; <= buffer for IPC_INFO
+ };
+
+ Previous versions of this file used to define this union but this is
+ incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether
+ one must define the union or not. */
+#define _SEM_SEMUN_UNDEFINED 1
+
+#ifdef __USE_MISC
+
+/* ipcs ctl cmds */
+# define SEM_STAT 18
+# define SEM_INFO 19
+
+struct seminfo
+{
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvmx;
+ int semaem;
+};
+
+#endif /* __USE_MISC */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/shm.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/shm.h
new file mode 100644
index 000000000..3d8c05d21
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/shm.h
@@ -0,0 +1,110 @@
+/* Copyright (C) 1995, 1996, 1997, 2000, 2002, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple. */
+#define SHMLBA (__getpagesize ())
+extern int __getpagesize (void) __THROW __attribute__ ((__const__));
+
+
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a set of semaphores. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+ size_t shm_segsz; /* size of segment in bytes */
+ __time_t shm_atime; /* time of last shmat() */
+#if __WORDSIZE == 32
+ unsigned long int __unused1;
+#endif
+ __time_t shm_dtime; /* time of last shmdt() */
+#if __WORDSIZE == 32
+ unsigned long int __unused2;
+#endif
+ __time_t shm_ctime; /* time of last change by shmctl() */
+#if __WORDSIZE == 32
+ unsigned long int __unused3;
+#endif
+ __pid_t shm_cpid; /* pid of creator */
+ __pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */
+# define SHM_NORESERVE 010000 /* don't check for reservations */
+
+struct shminfo
+ {
+ unsigned long int shmmax;
+ unsigned long int shmmin;
+ unsigned long int shmmni;
+ unsigned long int shmseg;
+ unsigned long int shmall;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+ unsigned long int __unused3;
+ unsigned long int __unused4;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
+
+__END_DECLS
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/sigcontext.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/sigcontext.h
new file mode 100644
index 000000000..c0d5fe72d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/sigcontext.h
@@ -0,0 +1,159 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_SIGCONTEXT_H
+#define _BITS_SIGCONTEXT_H 1
+
+#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
+# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+struct _fpreg
+{
+ unsigned short significand[4];
+ unsigned short exponent;
+};
+
+struct _fpxreg
+{
+ unsigned short significand[4];
+ unsigned short exponent;
+ unsigned short padding[3];
+};
+
+struct _xmmreg
+{
+ __uint32_t element[4];
+};
+
+
+
+#if __WORDSIZE == 32
+
+struct _fpstate
+{
+ /* Regular FPU environment. */
+ __uint32_t cw;
+ __uint32_t sw;
+ __uint32_t tag;
+ __uint32_t ipoff;
+ __uint32_t cssel;
+ __uint32_t dataoff;
+ __uint32_t datasel;
+ struct _fpreg _st[8];
+ unsigned short status;
+ unsigned short magic;
+
+ /* FXSR FPU environment. */
+ __uint32_t _fxsr_env[6];
+ __uint32_t mxcsr;
+ __uint32_t reserved;
+ struct _fpxreg _fxsr_st[8];
+ struct _xmmreg _xmm[8];
+ __uint32_t padding[56];
+};
+
+#ifndef sigcontext_struct
+/* Kernel headers before 2.1.1 define a struct sigcontext_struct, but
+ we need sigcontext. Some packages have come to rely on
+ sigcontext_struct being defined on 32-bit x86, so define this for
+ their benefit. */
+# define sigcontext_struct sigcontext
+#endif
+
+struct sigcontext
+{
+ unsigned short gs, __gsh;
+ unsigned short fs, __fsh;
+ unsigned short es, __esh;
+ unsigned short ds, __dsh;
+ unsigned long edi;
+ unsigned long esi;
+ unsigned long ebp;
+ unsigned long esp;
+ unsigned long ebx;
+ unsigned long edx;
+ unsigned long ecx;
+ unsigned long eax;
+ unsigned long trapno;
+ unsigned long err;
+ unsigned long eip;
+ unsigned short cs, __csh;
+ unsigned long eflags;
+ unsigned long esp_at_signal;
+ unsigned short ss, __ssh;
+ struct _fpstate * fpstate;
+ unsigned long oldmask;
+ unsigned long cr2;
+};
+
+#else /* __WORDSIZE == 64 */
+
+struct _fpstate
+{
+ /* FPU environment matching the 64-bit FXSAVE layout. */
+ __uint16_t cwd;
+ __uint16_t swd;
+ __uint16_t ftw;
+ __uint16_t fop;
+ __uint64_t rip;
+ __uint64_t rdp;
+ __uint32_t mxcsr;
+ __uint32_t mxcr_mask;
+ struct _fpxreg _st[8];
+ struct _xmmreg _xmm[16];
+ __uint32_t padding[24];
+};
+
+struct sigcontext
+{
+ unsigned long r8;
+ unsigned long r9;
+ unsigned long r10;
+ unsigned long r11;
+ unsigned long r12;
+ unsigned long r13;
+ unsigned long r14;
+ unsigned long r15;
+ unsigned long rdi;
+ unsigned long rsi;
+ unsigned long rbp;
+ unsigned long rbx;
+ unsigned long rdx;
+ unsigned long rax;
+ unsigned long rcx;
+ unsigned long rsp;
+ unsigned long rip;
+ unsigned long eflags;
+ unsigned short cs;
+ unsigned short gs;
+ unsigned short fs;
+ unsigned short __pad0;
+ unsigned long err;
+ unsigned long trapno;
+ unsigned long oldmask;
+ unsigned long cr2;
+ struct _fpstate * fpstate;
+ unsigned long __reserved1 [8];
+};
+
+#endif /* __WORDSIZE == 64 */
+
+#endif /* _BITS_SIGCONTEXT_H */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/stat.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/stat.h
new file mode 100644
index 000000000..e756d7e8c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/stat.h
@@ -0,0 +1,203 @@
+/* Copyright (C) 1999,2000,2001,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+/* Versions of the `struct stat' data structure. */
+#define _STAT_VER_KERNEL 0
+
+#if __WORDSIZE == 32
+# define _STAT_VER_SVR4 2
+# define _STAT_VER_LINUX 3
+
+/* i386 versions of the `xmknod' interface. */
+# define _MKNOD_VER_LINUX 1
+# define _MKNOD_VER_SVR4 2
+# define _MKNOD_VER _MKNOD_VER_LINUX /* The bits defined below. */
+#else
+# define _STAT_VER_LINUX 1
+
+/* x86-64 versions of the `xmknod' interface. */
+# define _MKNOD_VER_LINUX 0
+#endif
+
+#define _STAT_VER _STAT_VER_LINUX
+
+struct stat
+ {
+ __dev_t st_dev; /* Device. */
+#if __WORDSIZE == 32
+ unsigned short int __pad1;
+#endif
+#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
+ __ino_t st_ino; /* File serial number. */
+#else
+ __ino_t __st_ino; /* 32bit file serial number. */
+#endif
+#if __WORDSIZE == 32
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+#else
+ __nlink_t st_nlink; /* Link count. */
+ __mode_t st_mode; /* File mode. */
+#endif
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+#if __WORDSIZE == 64
+ int pad0;
+#endif
+ __dev_t st_rdev; /* Device number, if device. */
+#if __WORDSIZE == 32
+ unsigned short int __pad2;
+#endif
+#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
+ __off_t st_size; /* Size of file, in bytes. */
+#else
+ __off64_t st_size; /* Size of file, in bytes. */
+#endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
+ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
+#else
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+#endif
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+#if __WORDSIZE == 64
+ long int __unused[3];
+#else
+# ifndef __USE_FILE_OFFSET64
+ unsigned long int __unused4;
+ unsigned long int __unused5;
+# else
+ __ino64_t st_ino; /* File serial number. */
+# endif
+#endif
+ };
+
+#ifdef __USE_LARGEFILE64
+/* Note stat64 has the same shape as stat for x86-64. */
+struct stat64
+ {
+ __dev_t st_dev; /* Device. */
+#if __WORDSIZE == 64
+ __ino64_t st_ino; /* File serial number. */
+ __nlink_t st_nlink; /* Link count. */
+ __mode_t st_mode; /* File mode. */
+#else
+ unsigned int __pad1;
+ __ino_t __st_ino; /* 32bit file serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+#endif
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+#if __WORDSIZE == 64
+ int pad0;
+ __dev_t st_rdev; /* Device number, if device. */
+ __off_t st_size; /* Size of file, in bytes. */
+#else
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned int __pad2;
+ __off64_t st_size; /* Size of file, in bytes. */
+#endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+#if __WORDSIZE == 64
+ long int __unused[3];
+#else
+ __ino64_t st_ino; /* File serial number. */
+#endif
+ };
+#endif
+
+/* Tell code we have these members. */
+#define _STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+/* Nanosecond resolution time values are supported. */
+#define _STATBUF_ST_NSEC
+
+/* Encoding of the file mode. */
+
+#define __S_IFMT 0170000 /* These bits determine file type. */
+
+/* File types. */
+#define __S_IFDIR 0040000 /* Directory. */
+#define __S_IFCHR 0020000 /* Character device. */
+#define __S_IFBLK 0060000 /* Block device. */
+#define __S_IFREG 0100000 /* Regular file. */
+#define __S_IFIFO 0010000 /* FIFO. */
+#define __S_IFLNK 0120000 /* Symbolic link. */
+#define __S_IFSOCK 0140000 /* Socket. */
+
+/* POSIX.1b objects. Note that these macros always evaluate to zero. But
+ they do it by enforcing the correct use of the macros. */
+#define __S_TYPEISMQ(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
+
+/* Protection bits. */
+
+#define __S_ISUID 04000 /* Set user ID on execution. */
+#define __S_ISGID 02000 /* Set group ID on execution. */
+#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
+#define __S_IREAD 0400 /* Read by owner. */
+#define __S_IWRITE 0200 /* Write by owner. */
+#define __S_IEXEC 0100 /* Execute by owner. */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/brk.c b/libc/sysdeps/unix/sysv/linux/x86_64/brk.c
new file mode 100644
index 000000000..8b18c4dbb
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/brk.c
@@ -0,0 +1,42 @@
+/* brk system call for Linux/x86_64.
+ Copyright (C) 1995, 1996, 2000, 2001, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sysdep.h>
+
+/* This must be initialized data because commons can't have aliases. */
+void *__curbrk = 0;
+
+int
+__brk (void *addr)
+{
+ void *newbrk;
+
+ __curbrk = newbrk = (void *) INLINE_SYSCALL (brk, 1, addr);
+
+ if (newbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+weak_alias (__brk, brk)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/clone.S b/libc/sysdeps/unix/sysv/linux/x86_64/clone.S
new file mode 100644
index 000000000..8a12b0903
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/clone.S
@@ -0,0 +1,120 @@
+/* Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* clone() is even more special than fork() as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <asm-syntax.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+#define CLONE_VM 0x00000100
+#define CLONE_THREAD 0x00010000
+
+/* The userland implementation is:
+ int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg),
+ the kernel entry is:
+ int clone (long flags, void *child_stack).
+
+ The parameters are passed in register and on the stack from userland:
+ rdi: fn
+ rsi: child_stack
+ rdx: flags
+ rcx: arg
+ r8d: TID field in parent
+ r9d: thread pointer
+%esp+8: TID field in child
+
+ The kernel expects:
+ rax: system call number
+ rdi: flags
+ rsi: child_stack
+ rdx: TID field in parent
+ r10: TID field in child
+ r8: thread pointer */
+
+
+ .text
+ENTRY (BP_SYM (__clone))
+ /* Sanity check arguments. */
+ movq $-EINVAL,%rax
+ testq %rdi,%rdi /* no NULL function pointers */
+ jz SYSCALL_ERROR_LABEL
+ testq %rsi,%rsi /* no NULL stack pointers */
+ jz SYSCALL_ERROR_LABEL
+
+ /* Insert the argument onto the new stack. */
+ subq $16,%rsi
+ movq %rcx,8(%rsi)
+
+ /* Save the function pointer. It will be popped off in the
+ child in the ebx frobbing below. */
+ movq %rdi,0(%rsi)
+
+ /* Do the system call. */
+ movq %rdx, %rdi
+ movq %r8, %rdx
+ movq %r9, %r8
+ movq 8(%rsp), %r10
+ movl $SYS_ify(clone),%eax
+
+ /* End FDE now, because in the child the unwind info will be
+ wrong. */
+ cfi_endproc;
+ syscall
+
+ testq %rax,%rax
+ jl SYSCALL_ERROR_LABEL
+ jz L(thread_start)
+
+L(pseudo_end):
+ ret
+
+L(thread_start):
+ /* Clear the frame pointer. The ABI suggests this be done, to mark
+ the outermost frame obviously. */
+ xorl %ebp, %ebp
+
+#ifdef RESET_PID
+ testq $CLONE_THREAD, %rdi
+ jne 1f
+ testq $CLONE_VM, %rdi
+ movl $-1, %eax
+ jne 2f
+ movl $SYS_ify(getpid), %eax
+ syscall
+2: movl %eax, %fs:PID
+ movl %eax, %fs:TID
+1:
+#endif
+
+ /* Set up arguments for the function call. */
+ popq %rax /* Function to call. */
+ popq %rdi /* Argument. */
+ call *%rax
+ /* Call exit with return value from function call. */
+ movq %rax, %rdi
+ call HIDDEN_JUMPTARGET (_exit)
+
+ cfi_startproc;
+PSEUDO_END (BP_SYM (__clone))
+
+weak_alias (BP_SYM (__clone), BP_SYM (clone))
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/dl-cache.h b/libc/sysdeps/unix/sysv/linux/x86_64/dl-cache.h
new file mode 100644
index 000000000..cb647abf8
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/dl-cache.h
@@ -0,0 +1,25 @@
+/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
+ Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define _DL_CACHE_DEFAULT_ID 0x303
+
+#define _dl_cache_check_flags(flags) \
+ ((flags) == _DL_CACHE_DEFAULT_ID)
+
+#include <sysdeps/unix/sysv/linux/sparc/dl-cache.h>
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c b/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c
new file mode 100644
index 000000000..6662a94d0
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c
@@ -0,0 +1,5 @@
+#ifdef IS_IN_ldconfig
+# include <sysdeps/i386/dl-procinfo.c>
+#else
+# include <sysdeps/generic/dl-procinfo.c>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h b/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h
new file mode 100644
index 000000000..31455204c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h
@@ -0,0 +1,5 @@
+#ifdef IS_IN_ldconfig
+# include <sysdeps/unix/sysv/linux/i386/dl-procinfo.h>
+#else
+# include <sysdeps/generic/dl-procinfo.h>
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/get_clockfreq.c b/libc/sysdeps/unix/sysv/linux/x86_64/get_clockfreq.c
new file mode 100644
index 000000000..a58d40a9c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/get_clockfreq.c
@@ -0,0 +1 @@
+#include "../i386/get_clockfreq.c"
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/libc/sysdeps/unix/sysv/linux/x86_64/getcontext.S
new file mode 100644
index 000000000..4bbc7a4d2
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/getcontext.S
@@ -0,0 +1,88 @@
+/* Save current context.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+/* int __getcontext (ucontext_t *ucp)
+
+ Saves the machine context in UCP such that when it is activated,
+ it appears as if __getcontext() returned again.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to save anything
+ other than the PRESERVED state. */
+
+
+ENTRY(__getcontext)
+ /* Save the preserved registers, the registers used for passing
+ args, and the return address. */
+ movq %rbx, oRBX(%rdi)
+ movq %rbp, oRBP(%rdi)
+ movq %r12, oR12(%rdi)
+ movq %r13, oR13(%rdi)
+ movq %r14, oR14(%rdi)
+ movq %r15, oR15(%rdi)
+
+ movq %rdi, oRDI(%rdi)
+ movq %rsi, oRSI(%rdi)
+ movq %rdx, oRDX(%rdi)
+ movq %rcx, oRCX(%rdi)
+ movq %r8, oR8(%rdi)
+ movq %r9, oR9(%rdi)
+
+ movq (%rsp), %rcx
+ movq %rcx, oRIP(%rdi)
+ leaq 8(%rsp), %rcx /* Exclude the return address. */
+ movq %rcx, oRSP(%rdi)
+
+ /* We have separate floating-point register content memory on the
+ stack. We use the __fpregs_mem block in the context. Set the
+ links up correctly. */
+
+ leaq oFPREGSMEM(%rdi), %rcx
+ movq %rcx, oFPREGS(%rdi)
+ /* Save the floating-point environment. */
+ fnstenv (%rcx)
+ stmxcsr oMXCSR(%rdi)
+
+ /* Save the current signal mask with
+ rt_sigprocmask (SIG_BLOCK, NULL, set,_NSIG/8). */
+ leaq oSIGMASK(%rdi), %rdx
+ xorl %esi,%esi
+#if SIG_BLOCK == 0
+ xorl %edi, %edi
+#else
+ movl $SIG_BLOCK, %edi
+#endif
+ movl $_NSIG8,%r10d
+ movl $__NR_rt_sigprocmask, %eax
+ syscall
+ cmpq $-4095, %rax /* Check %rax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+
+ /* All done, return 0 for success. */
+ xorl %eax, %eax
+L(pseudo_end):
+ ret
+PSEUDO_END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S b/libc/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S
new file mode 100644
index 000000000..84a99b040
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S
@@ -0,0 +1,44 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+/* For the calculation see asm/vsyscall.h. */
+#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
+
+
+ENTRY (__gettimeofday)
+ /* Align stack. */
+ sub $0x8, %rsp
+ cfi_adjust_cfa_offset(8)
+ movq $VSYSCALL_ADDR_vgettimeofday, %rax
+ callq *%rax
+ /* Check error return. */
+ cmpl $-4095, %eax
+ jae SYSCALL_ERROR_LABEL
+
+L(pseudo_end):
+ add $0x8, %rsp
+ cfi_adjust_cfa_offset(-8)
+ ret
+PSEUDO_END(__gettimeofday)
+
+strong_alias (__gettimeofday, __gettimeofday_internal)
+weak_alias (__gettimeofday, gettimeofday)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h b/libc/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h
new file mode 100644
index 000000000..ef11dc94d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h
@@ -0,0 +1,21 @@
+/* Definition of `struct stat' used in the kernel.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define STAT_IS_KERNEL_STAT 1
+#define XSTAT_IS_XSTAT64 1
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/ldconfig.h b/libc/sysdeps/unix/sysv/linux/x86_64/ldconfig.h
new file mode 100644
index 000000000..f7f64eb1e
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/ldconfig.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/ldconfig.h>
+
+#define SYSDEP_KNOWN_INTERPRETER_NAMES \
+ { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
+ { "/lib64/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 },
+#define SYSDEP_KNOWN_LIBRARY_NAMES \
+ { "libc.so.6", FLAG_ELF_LIBC6 }, \
+ { "libm.so.6", FLAG_ELF_LIBC6 },
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed b/libc/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed
new file mode 100644
index 000000000..3f1530d31
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed
@@ -0,0 +1,3 @@
+/LD_TRACE_LOADED_OBJECTS=1/a\
+add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out"
+s_^\(RTLDLIST=\)\(.*lib\)\(\|64\)\(/[^/]*\)\(-x86-64\)\(\.so\.[0-9.]*\)[ ]*$_\1"\2\4\6 \264\4\5\6"_
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/makecontext.c b/libc/sysdeps/unix/sysv/linux/x86_64/makecontext.c
new file mode 100644
index 000000000..5deea7d1b
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/makecontext.c
@@ -0,0 +1,113 @@
+/* Create new context.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <ucontext.h>
+
+#include "ucontext_i.h"
+
+/* This implementation can handle any ARGC value but only
+ normal integer parameters.
+ makecontext sets up a stack and the registers for the
+ user context. The stack looks like this:
+ +-----------------------+
+ | next context |
+ +-----------------------+
+ | parameter 7-n |
+ +-----------------------+
+ | trampoline address |
+ %rsp -> +-----------------------+
+
+ The registers are set up like this:
+ %rdi,%rsi,%rdx,%rcx,%r8,%r9: parameter 1 to 6
+ %rbx : address of next context
+ %rsp : stack pointer.
+*/
+
+/* XXX: This implementation currently only handles integer arguments.
+ To handle long int and pointer arguments the va_arg arguments needs
+ to be changed to long and also the stdlib/tst-setcontext.c file needs
+ to be changed to pass long arguments to makecontext. */
+
+
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+ extern void __start_context (void);
+ unsigned long int *sp, idx_uc_link;
+ va_list ap;
+ int i;
+
+ /* Generate room on stack for parameter if needed and uc_link. */
+ sp = (unsigned long int *) ((uintptr_t) ucp->uc_stack.ss_sp
+ + ucp->uc_stack.ss_size);
+ sp -= (argc > 6 ? argc - 6 : 0) + 1;
+ /* Align stack and make space for trampoline address. */
+ sp = (unsigned long int *) ((((uintptr_t) sp) & -16L) - 8);
+
+ idx_uc_link = (argc > 6 ? argc - 6 : 0) + 1;
+
+ /* Setup context ucp. */
+ /* Address to jump to. */
+ ucp->uc_mcontext.gregs[REG_RIP] = (long int) func;
+ /* Setup rbx.*/
+ ucp->uc_mcontext.gregs[REG_RBX] = (long int) &sp[idx_uc_link];
+ ucp->uc_mcontext.gregs[REG_RSP] = (long int) sp;
+
+ /* Setup stack. */
+ sp[0] = (unsigned long int) &__start_context;
+ sp[idx_uc_link] = (unsigned long int) ucp->uc_link;
+
+ va_start (ap, argc);
+ /* Handle arguments. */
+ for (i = 0; i < argc; ++i)
+ switch (i)
+ {
+ case 0:
+ ucp->uc_mcontext.gregs [REG_RDI] = va_arg (ap, int);
+ break;
+ case 1:
+ ucp->uc_mcontext.gregs [REG_RSI] = va_arg (ap, int);
+ break;
+ case 2:
+ ucp->uc_mcontext.gregs [REG_RDX] = va_arg (ap, int);
+ break;
+ case 3:
+ ucp->uc_mcontext.gregs [REG_RCX] = va_arg (ap, int);
+ break;
+ case 4:
+ ucp->uc_mcontext.gregs [REG_R8] = va_arg (ap, int);
+ break;
+ case 5:
+ ucp->uc_mcontext.gregs [REG_R9] = va_arg (ap, int);
+ break;
+ default:
+ /* Put value on stack. */
+ sp[(i - 5)] = va_arg (ap, int);
+ break;
+ }
+ va_end (ap);
+
+}
+
+
+weak_alias (__makecontext, makecontext)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/profil-counter.h b/libc/sysdeps/unix/sysv/linux/x86_64/profil-counter.h
new file mode 100644
index 000000000..0b244175a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/profil-counter.h
@@ -0,0 +1,32 @@
+/* Low-level statistical profiling support function. Linux/x86-64 version.
+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <signal.h>
+#include <sigcontextinfo.h>
+
+static void
+profil_counter (int signo, SIGCONTEXT scp)
+{
+ profil_count ((void *) GET_PC (scp));
+
+ /* This is a hack to prevent the compiler from implementing the
+ above function call as a sibcall. The sibcall would overwrite
+ the signal context. */
+ asm volatile ("");
+}
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/readelflib.c b/libc/sysdeps/unix/sysv/linux/x86_64/readelflib.c
new file mode 100644
index 000000000..5a49af3fa
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/readelflib.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
+ Jakub Jelinek <jakub@redhat.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+int process_elf32_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+int process_elf64_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname,
+ void *file_contents, size_t file_length);
+
+/* Returns 0 if everything is ok, != 0 in case of error. */
+int
+process_elf_file (const char *file_name, const char *lib, int *flag,
+ unsigned int *osversion, char **soname, void *file_contents,
+ size_t file_length)
+{
+ ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents;
+ int ret;
+
+ if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+ return process_elf32_file (file_name, lib, flag, osversion, soname,
+ file_contents, file_length);
+ else
+ {
+ ret = process_elf64_file (file_name, lib, flag, osversion, soname,
+ file_contents, file_length);
+ /* x86-64 64bit libraries are always libc.so.6+. */
+ if (!ret)
+ *flag = FLAG_X8664_LIB64|FLAG_ELF_LIBC6;
+ return ret;
+ }
+}
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf32_file
+#define __ELF_NATIVE_CLASS 32
+#include "elf/readelflib.c"
+
+#undef __ELF_NATIVE_CLASS
+#undef process_elf_file
+#define process_elf_file process_elf64_file
+#define __ELF_NATIVE_CLASS 64
+#include "elf/readelflib.c"
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/recv.c b/libc/sysdeps/unix/sysv/linux/x86_64/recv.c
new file mode 100644
index 000000000..2fa1794d3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/recv.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <sysdep-cancel.h>
+
+/* Read N bytes into BUF from socket FD.
+ Returns the number read or -1 for errors. */
+
+ssize_t
+__libc_recv (int fd, void *buf, size_t n, int flags)
+{
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (recvfrom, 6, fd, buf, n, flags, NULL, NULL);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = INLINE_SYSCALL (recvfrom, 6, fd, buf, n, flags, NULL, NULL);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+weak_alias (__libc_recv, __recv)
+weak_alias (__recv, recv)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/register-dump.h b/libc/sysdeps/unix/sysv/linux/x86_64/register-dump.h
new file mode 100644
index 000000000..50f589d0d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/register-dump.h
@@ -0,0 +1,346 @@
+/* Dump registers.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/uio.h>
+#include <stdio-common/_itoa.h>
+
+/* We will print the register dump in this format:
+
+ RAX: XXXXXXXXXXXXXXXX RBX: XXXXXXXXXXXXXXXX RCX: XXXXXXXXXXXXXXXX
+ RDX: XXXXXXXXXXXXXXXX RSI: XXXXXXXXXXXXXXXX RDI: XXXXXXXXXXXXXXXX
+ RBP: XXXXXXXXXXXXXXXX R8 : XXXXXXXXXXXXXXXX R9 : XXXXXXXXXXXXXXXX
+ R10: XXXXXXXXXXXXXXXX R11: XXXXXXXXXXXXXXXX R12: XXXXXXXXXXXXXXXX
+ R13: XXXXXXXXXXXXXXXX R14: XXXXXXXXXXXXXXXX R15: XXXXXXXXXXXXXXXX
+ RSP: XXXXXXXXXXXXXXXX
+
+ RIP: XXXXXXXXXXXXXXXX EFLAGS: XXXXXXXX
+
+ CS: XXXX DS: XXXX ES: XXXX FS: XXXX GS: XXXX
+
+ Trap: XXXXXXXX Error: XXXXXXXX OldMask: XXXXXXXX
+ RSP/SIGNAL: XXXXXXXXXXXXXXXX CR2: XXXXXXXX
+
+ FPUCW: XXXXXXXX FPUSW: XXXXXXXX TAG: XXXXXXXX
+ IPOFF: XXXXXXXX CSSEL: XXXX DATAOFF: XXXXXXXX DATASEL: XXXX
+
+ ST(0) XXXX XXXXXXXXXXXXXXXX ST(1) XXXX XXXXXXXXXXXXXXXX
+ ST(2) XXXX XXXXXXXXXXXXXXXX ST(3) XXXX XXXXXXXXXXXXXXXX
+ ST(4) XXXX XXXXXXXXXXXXXXXX ST(5) XXXX XXXXXXXXXXXXXXXX
+ ST(6) XXXX XXXXXXXXXXXXXXXX ST(7) XXXX XXXXXXXXXXXXXXXX
+
+ mxcsr: XXXX
+ XMM0 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM1 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ XMM2 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM3 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ XMM4 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM5 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ XMM6 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM7 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ XMM8 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM9 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ XMM10: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM11: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ XMM12: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM13: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ XMM14: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM15: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+
+ */
+
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
+{
+ char *cp = _itoa_word (value, buf + len, 16, 0);
+ while (cp > buf)
+ *--cp = '0';
+}
+
+static void
+register_dump (int fd, struct ucontext *ctx)
+{
+ char regs[25][16];
+ char fpregs[30][8];
+ char xmmregs[16][32];
+ struct iovec iov[147];
+ size_t nr = 0;
+ int i;
+
+#define ADD_STRING(str) \
+ iov[nr].iov_base = (char *) str; \
+ iov[nr].iov_len = strlen (str); \
+ ++nr
+#define ADD_MEM(str, len) \
+ iov[nr].iov_base = str; \
+ iov[nr].iov_len = len; \
+ ++nr
+
+ /* Generate strings of register contents. */
+ hexvalue (ctx->uc_mcontext.gregs[REG_RAX], regs[0], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_RBX], regs[1], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_RCX], regs[2], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_RDX], regs[3], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_RSI], regs[4], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_RDI], regs[5], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_RBP], regs[6], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_R8], regs[7], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_R9], regs[8], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_R10], regs[9], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_R11], regs[10], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_R12], regs[11], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_R13], regs[12], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_R14], regs[13], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_R15], regs[14], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_RSP], regs[15], 16);
+ hexvalue (ctx->uc_mcontext.gregs[REG_RIP], regs[16], 16);
+
+ hexvalue (ctx->uc_mcontext.gregs[REG_EFL], regs[17], 8);
+ hexvalue (ctx->uc_mcontext.gregs[REG_CSGSFS] & 0xffff, regs[18], 4);
+ hexvalue ((ctx->uc_mcontext.gregs[REG_CSGSFS] >> 16) & 0xffff, regs[19], 4);
+ hexvalue ((ctx->uc_mcontext.gregs[REG_CSGSFS] >> 32) & 0xffff, regs[20], 4);
+ /* hexvalue (ctx->ss, regs[23], 4); */
+ hexvalue (ctx->uc_mcontext.gregs[REG_TRAPNO], regs[21], 8);
+ hexvalue (ctx->uc_mcontext.gregs[REG_ERR], regs[22], 8);
+ hexvalue (ctx->uc_mcontext.gregs[REG_OLDMASK], regs[23], 8);
+ hexvalue (ctx->uc_mcontext.gregs[REG_CR2], regs[24], 8);
+
+ /* Generate the output. */
+ ADD_STRING ("Register dump:\n\n RAX: ");
+ ADD_MEM (regs[0], 16);
+ ADD_STRING (" RBX: ");
+ ADD_MEM (regs[1], 16);
+ ADD_STRING (" RCX: ");
+ ADD_MEM (regs[2], 16);
+ ADD_STRING ("\n RDX: ");
+ ADD_MEM (regs[3], 16);
+ ADD_STRING (" RSI: ");
+ ADD_MEM (regs[4], 16);
+ ADD_STRING (" RDI: ");
+ ADD_MEM (regs[5], 16);
+ ADD_STRING ("\n RBP: ");
+ ADD_MEM (regs[6], 16);
+ ADD_STRING (" R8 : ");
+ ADD_MEM (regs[7], 16);
+ ADD_STRING (" R9 : ");
+ ADD_MEM (regs[8], 16);
+ ADD_STRING ("\n R10: ");
+ ADD_MEM (regs[9], 16);
+ ADD_STRING (" R11: ");
+ ADD_MEM (regs[10], 16);
+ ADD_STRING (" R12: ");
+ ADD_MEM (regs[11], 16);
+ ADD_STRING ("\n R13: ");
+ ADD_MEM (regs[12], 16);
+ ADD_STRING (" R14: ");
+ ADD_MEM (regs[13], 16);
+ ADD_STRING (" R15: ");
+ ADD_MEM (regs[14], 16);
+ ADD_STRING ("\n RSP: ");
+ ADD_MEM (regs[15], 16);
+ ADD_STRING ("\n\n RIP: ");
+ ADD_MEM (regs[16], 16);
+ ADD_STRING (" EFLAGS: ");
+ ADD_MEM (regs[17], 8);
+ ADD_STRING ("\n\n CS: ");
+ ADD_MEM (regs[18], 4);
+ ADD_STRING (" FS: ");
+ ADD_MEM (regs[19], 4);
+ ADD_STRING (" GS: ");
+ ADD_MEM (regs[20], 4);
+ /*
+ ADD_STRING (" SS: ");
+ ADD_MEM (regs[23], 4);
+ */
+ ADD_STRING ("\n\n Trap: ");
+ ADD_MEM (regs[21], 8);
+ ADD_STRING (" Error: ");
+ ADD_MEM (regs[22], 8);
+ ADD_STRING (" OldMask: ");
+ ADD_MEM (regs[23], 8);
+ ADD_STRING (" CR2: ");
+ ADD_MEM (regs[24], 8);
+
+ if (ctx->uc_mcontext.fpregs != NULL)
+ {
+
+ /* Generate output for the FPU control/status registers. */
+ hexvalue (ctx->uc_mcontext.fpregs->cwd, fpregs[0], 8);
+ hexvalue (ctx->uc_mcontext.fpregs->swd, fpregs[1], 8);
+ hexvalue (ctx->uc_mcontext.fpregs->ftw, fpregs[2], 8);
+ hexvalue (ctx->uc_mcontext.fpregs->rip, fpregs[3], 8);
+ hexvalue (ctx->uc_mcontext.fpregs->rdp, fpregs[4], 8);
+
+ ADD_STRING ("\n\n FPUCW: ");
+ ADD_MEM (fpregs[0], 8);
+ ADD_STRING (" FPUSW: ");
+ ADD_MEM (fpregs[1], 8);
+ ADD_STRING (" TAG: ");
+ ADD_MEM (fpregs[2], 8);
+ ADD_STRING ("\n RIP: ");
+ ADD_MEM (fpregs[3], 8);
+ ADD_STRING (" RDP: ");
+ ADD_MEM (fpregs[4], 8);
+
+ /* Now the real FPU registers. */
+ hexvalue (ctx->uc_mcontext.fpregs->_st[0].exponent, fpregs[5], 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[0].significand[3] << 16
+ | ctx->uc_mcontext.fpregs->_st[0].significand[2], fpregs[6],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[0].significand[1] << 16
+ | ctx->uc_mcontext.fpregs->_st[0].significand[0], fpregs[7],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[1].exponent, fpregs[8], 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[1].significand[3] << 16
+ | ctx->uc_mcontext.fpregs->_st[1].significand[2], fpregs[9],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[1].significand[1] << 16
+ | ctx->uc_mcontext.fpregs->_st[1].significand[0], fpregs[10],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[2].exponent, fpregs[11], 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[2].significand[3] << 16
+ | ctx->uc_mcontext.fpregs->_st[2].significand[2], fpregs[12],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[2].significand[1] << 16
+ | ctx->uc_mcontext.fpregs->_st[2].significand[0], fpregs[13],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[3].exponent, fpregs[14], 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[3].significand[3] << 16
+ | ctx->uc_mcontext.fpregs->_st[3].significand[2], fpregs[15],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[3].significand[1] << 16
+ | ctx->uc_mcontext.fpregs->_st[3].significand[0], fpregs[16],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[4].exponent, fpregs[17], 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[4].significand[3] << 16
+ | ctx->uc_mcontext.fpregs->_st[4].significand[2], fpregs[18],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[4].significand[1] << 16
+ | ctx->uc_mcontext.fpregs->_st[4].significand[0], fpregs[19],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[5].exponent, fpregs[20], 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[5].significand[3] << 16
+ | ctx->uc_mcontext.fpregs->_st[5].significand[2], fpregs[21],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[5].significand[1] << 16
+ | ctx->uc_mcontext.fpregs->_st[5].significand[0], fpregs[22],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[6].exponent, fpregs[23], 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[6].significand[3] << 16
+ | ctx->uc_mcontext.fpregs->_st[6].significand[2], fpregs[24],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[6].significand[1] << 16
+ | ctx->uc_mcontext.fpregs->_st[6].significand[0], fpregs[25],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[7].exponent, fpregs[26], 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[7].significand[3] << 16
+ | ctx->uc_mcontext.fpregs->_st[7].significand[2], fpregs[27],
+ 8);
+ hexvalue (ctx->uc_mcontext.fpregs->_st[7].significand[1] << 16
+ | ctx->uc_mcontext.fpregs->_st[7].significand[0], fpregs[28],
+ 8);
+
+ hexvalue (ctx->uc_mcontext.fpregs->mxcsr, fpregs[29], 4);
+
+ for (i = 0; i < 16; i++)
+ hexvalue (ctx->uc_mcontext.fpregs->_xmm[i].element[3] << 24
+ | ctx->uc_mcontext.fpregs->_xmm[i].element[2] << 16
+ | ctx->uc_mcontext.fpregs->_xmm[i].element[1] << 8
+ | ctx->uc_mcontext.fpregs->_xmm[i].element[0], xmmregs[i],
+ 32);
+
+
+ ADD_STRING ("\n\n ST(0) ");
+ ADD_MEM (fpregs[5], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[6], 8);
+ ADD_MEM (fpregs[7], 8);
+ ADD_STRING (" ST(1) ");
+ ADD_MEM (fpregs[8], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[9], 8);
+ ADD_MEM (fpregs[10], 8);
+ ADD_STRING ("\n ST(2) ");
+ ADD_MEM (fpregs[11], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[12], 8);
+ ADD_MEM (fpregs[13], 8);
+ ADD_STRING (" ST(3) ");
+ ADD_MEM (fpregs[14], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[15], 8);
+ ADD_MEM (fpregs[16], 8);
+ ADD_STRING ("\n ST(4) ");
+ ADD_MEM (fpregs[17], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[18], 8);
+ ADD_MEM (fpregs[19], 8);
+ ADD_STRING (" ST(5) ");
+ ADD_MEM (fpregs[20], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[21], 8);
+ ADD_MEM (fpregs[22], 8);
+ ADD_STRING ("\n ST(6) ");
+ ADD_MEM (fpregs[23], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[24], 8);
+ ADD_MEM (fpregs[25], 8);
+ ADD_STRING (" ST(7) ");
+ ADD_MEM (fpregs[27], 4);
+ ADD_STRING (" ");
+ ADD_MEM (fpregs[27], 8);
+ ADD_MEM (fpregs[28], 8);
+
+ ADD_STRING ("\n mxcsr: ");
+ ADD_MEM (fpregs[29], 4);
+
+ ADD_STRING ("\n XMM0: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING (" XMM1: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING ("\n XMM2: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING (" XMM3: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING ("\n XMM4: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING (" XMM5: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING ("\n XMM6: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING (" XMM7: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING ("\n XMM8: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING (" XMM9: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING ("\n XMM10: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING (" XMM11: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING ("\n XMM12: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING (" XMM13: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING ("\n XMM14: ");
+ ADD_MEM (xmmregs[0], 32);
+ ADD_STRING (" XMM15: ");
+ ADD_MEM (xmmregs[0], 32);
+
+ }
+
+ ADD_STRING ("\n");
+
+ /* Write the stuff out. */
+ writev (fd, iov, nr);
+}
+
+
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/send.c b/libc/sysdeps/unix/sysv/linux/x86_64/send.c
new file mode 100644
index 000000000..c484ce69f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/send.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <sysdep-cancel.h>
+
+/* Send N bytes of BUF to socket FD. Returns the number sent or -1. */
+ssize_t
+__libc_send (int fd, const void *buf, size_t n, int flags)
+{
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (sendto, 6, fd, buf, n, flags, NULL, NULL);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ ssize_t result = INLINE_SYSCALL (sendto, 6, fd, buf, n, flags, NULL, NULL);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+
+weak_alias (__libc_send, __send)
+libc_hidden_weak (__send)
+weak_alias (__send, send)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/setcontext.S b/libc/sysdeps/unix/sysv/linux/x86_64/setcontext.S
new file mode 100644
index 000000000..61fc07f44
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/setcontext.S
@@ -0,0 +1,105 @@
+/* Install given context.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+
+/* int __setcontext (const ucontext_t *ucp)
+
+ Restores the machine context in UCP and thereby resumes execution
+ in that context.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to restore anything
+ other than the PRESERVED state. */
+
+ENTRY(__setcontext)
+ /* Save argument since syscall will destroy it. */
+ pushq %rdi
+ cfi_adjust_cfa_offset(8)
+
+ /* Set the signal mask with
+ rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8). */
+ leaq oSIGMASK(%rdi), %rsi
+ xorl %edx, %edx
+ movl $SIG_SETMASK, %edi
+ movl $_NSIG8,%r10d
+ movl $__NR_rt_sigprocmask, %eax
+ syscall
+ popq %rdi /* Reload %rdi, adjust stack. */
+ cfi_adjust_cfa_offset(-8)
+ cmpq $-4095, %rax /* Check %rax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+
+ /* Restore the floating-point context. Not the registers, only the
+ rest. */
+ movq oFPREGS(%rdi), %rcx
+ fldenv (%rcx)
+ ldmxcsr oMXCSR(%rdi)
+
+
+ /* Load the new stack pointer, the preserved registers and
+ registers used for passing args. */
+ cfi_def_cfa(%rdi, 0)
+ cfi_offset(%rbx,oRBX)
+ cfi_offset(%rbp,oRBP)
+ cfi_offset(%r12,oR12)
+ cfi_offset(%r13,oR13)
+ cfi_offset(%r14,oR14)
+ cfi_offset(%r15,oR15)
+ cfi_offset(%rsp,oRSP)
+ cfi_offset(%rip,oRIP)
+
+ movq oRSP(%rdi), %rsp
+ movq oRBX(%rdi), %rbx
+ movq oRBP(%rdi), %rbp
+ movq oR12(%rdi), %r12
+ movq oR13(%rdi), %r13
+ movq oR14(%rdi), %r14
+ movq oR15(%rdi), %r15
+
+ /* The following ret should return to the address set with
+ getcontext. Therefore push the address on the stack. */
+ movq oRIP(%rdi), %rcx
+ pushq %rcx
+
+ movq oRSI(%rdi), %rsi
+ movq oRDX(%rdi), %rdx
+ movq oRCX(%rdi), %rcx
+ movq oR8(%rdi), %r8
+ movq oR9(%rdi), %r9
+
+ /* Setup finally %rdi. */
+ movq oRDI(%rdi), %rdi
+
+ /* End FDE here, we fall into another context. */
+ cfi_endproc
+ cfi_startproc
+
+ /* Clear rax to indicate success. */
+ xorl %eax, %eax
+
+L(pseudo_end):
+ ret
+PSEUDO_END(__setcontext)
+
+weak_alias (__setcontext, setcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/libc/sysdeps/unix/sysv/linux/x86_64/sigaction.c
new file mode 100644
index 000000000..d6f4558ce
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sigaction.c
@@ -0,0 +1,112 @@
+/* POSIX.1 `sigaction' call for Linux/x86-64.
+ Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <errno.h>
+#include <stddef.h>
+#include <signal.h>
+#include <string.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+/* The difference here is that the sigaction structure used in the
+ kernel is not the same as we use in the libc. Therefore we must
+ translate it here. */
+#include <kernel_sigaction.h>
+
+/* We do not globally define the SA_RESTORER flag so do it here. */
+#define SA_RESTORER 0x04000000
+
+/* Using the hidden attribute here does not change the code but it
+ helps to avoid warnings. */
+#if defined HAVE_HIDDEN && defined HAVE_VISIBILITY_ATTRIBUTE \
+ && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE
+extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
+#else
+static void restore_rt (void) asm ("__restore_rt");
+#endif
+
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+ If OACT is not NULL, put the old action for SIG in *OACT. */
+int
+__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+{
+ int result;
+ struct kernel_sigaction kact, koact;
+
+ if (act)
+ {
+ kact.k_sa_handler = act->sa_handler;
+ memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
+ kact.sa_flags = act->sa_flags | SA_RESTORER;
+
+ kact.sa_restorer = &restore_rt;
+ }
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ result = INLINE_SYSCALL (rt_sigaction, 4,
+ sig, act ? __ptrvalue (&kact) : NULL,
+ oact ? __ptrvalue (&koact) : NULL, _NSIG / 8);
+ if (oact && result >= 0)
+ {
+ oact->sa_handler = koact.k_sa_handler;
+ memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t));
+ oact->sa_flags = koact.sa_flags;
+ oact->sa_restorer = koact.sa_restorer;
+ }
+ return result;
+}
+libc_hidden_def (__libc_sigaction)
+
+#ifdef WRAPPER_INCLUDE
+# include WRAPPER_INCLUDE
+#endif
+
+#ifndef LIBC_SIGACTION
+weak_alias (__libc_sigaction, __sigaction)
+libc_hidden_weak (__sigaction)
+weak_alias (__libc_sigaction, sigaction)
+#endif
+
+/* NOTE: Please think twice before making any changes to the bits of
+ code below. GDB needs some intimate knowledge about it to
+ recognize them as signal trampolines, and make backtraces through
+ signal handlers work right. Important are both the names
+ (__restore_rt) and the exact instruction sequence.
+ If you ever feel the need to make any changes, please notify the
+ appropriate GDB maintainer. */
+
+#define RESTORE(name, syscall) RESTORE2 (name, syscall)
+# define RESTORE2(name, syscall) \
+asm \
+ ( \
+ ".align 16\n" \
+ CFI_STARTPROC "\n" \
+ "__" #name ":\n" \
+ " movq $" #syscall ", %rax\n" \
+ " syscall\n" \
+ CFI_ENDPROC "\n" \
+ );
+/* The return code for realtime-signals. */
+RESTORE (restore_rt, __NR_rt_sigreturn)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h b/libc/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h
new file mode 100644
index 000000000..11493c580
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define SIGCONTEXT siginfo_t *_si, struct ucontext *
+#define SIGCONTEXT_EXTRA_ARGS _si,
+#define GET_PC(ctx) ((void *) (ctx)->uc_mcontext.gregs[REG_RIP])
+#define GET_FRAME(ctx) ((void *) (ctx)->uc_mcontext.gregs[REG_RBP])
+#define GET_STACK(ctx) ((void *) (ctx)->uc_mcontext.gregs[REG_RSP])
+
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sigpending.c b/libc/sysdeps/unix/sysv/linux/x86_64/sigpending.c
new file mode 100644
index 000000000..c7ddb1fbd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sigpending.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/ia64/sigpending.c>
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sigprocmask.c b/libc/sysdeps/unix/sysv/linux/x86_64/sigprocmask.c
new file mode 100644
index 000000000..bc0927f45
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sigprocmask.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/ia64/sigprocmask.c>
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/libc/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
new file mode 100644
index 000000000..fc7996ccd
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
@@ -0,0 +1,123 @@
+/* Save current context and install the given one.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+
+/* int __swapcontext (ucontext_t *oucp, const ucontext_t *ucp);
+
+ Saves the machine context in oucp such that when it is activated,
+ it appears as if __swapcontextt() returned again, restores the
+ machine context in ucp and thereby resumes execution in that
+ context.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to save anything
+ other than the PRESERVED state. */
+
+ENTRY(__swapcontext)
+ /* Save the preserved registers, the registers used for passing args,
+ and the return address. */
+ movq %rbx, oRBX(%rdi)
+ movq %rbp, oRBP(%rdi)
+ movq %r12, oR12(%rdi)
+ movq %r13, oR13(%rdi)
+ movq %r14, oR14(%rdi)
+ movq %r15, oR15(%rdi)
+
+ movq %rdi, oRDI(%rdi)
+ movq %rsi, oRSI(%rdi)
+ movq %rdx, oRDX(%rdi)
+ movq %rcx, oRCX(%rdi)
+ movq %r8, oR8(%rdi)
+ movq %r9, oR9(%rdi)
+
+ movq (%rsp), %rcx
+ movq %rcx, oRIP(%rdi)
+ leaq 8(%rsp), %rcx /* Exclude the return address. */
+ movq %rcx, oRSP(%rdi)
+
+ /* We have separate floating-point register content memory on the
+ stack. We use the __fpregs_mem block in the context. Set the
+ links up correctly. */
+ leaq oFPREGSMEM(%rdi), %rcx
+ movq %rcx, oFPREGS(%rdi)
+ /* Save the floating-point environment. */
+ fnstenv (%rcx)
+ stmxcsr oMXCSR(%rdi)
+
+
+ /* The syscall destroys some registers, save them. */
+ movq %rsi, %r12
+
+ /* Save the current signal mask and install the new one with
+ rt_sigprocmask (SIG_BLOCK, newset, oldset,_NSIG/8). */
+ leaq oSIGMASK(%rdi), %rdx
+ leaq oSIGMASK(%rsi), %rsi
+ movl $SIG_SETMASK, %edi
+ movl $_NSIG8,%r10d
+ movl $__NR_rt_sigprocmask, %eax
+ syscall
+ cmpq $-4095, %rax /* Check %rax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+
+ /* Restore destroyed registers. */
+ movq %r12, %rsi
+
+ /* Restore the floating-point context. Not the registers, only the
+ rest. */
+ movq oFPREGS(%rsi), %rcx
+ fldenv (%rcx)
+ ldmxcsr oMXCSR(%rsi)
+
+ /* Load the new stack pointer and the preserved registers. */
+ movq oRSP(%rsi), %rsp
+ movq oRBX(%rsi), %rbx
+ movq oRBP(%rsi), %rbp
+ movq oR12(%rsi), %r12
+ movq oR13(%rsi), %r13
+ movq oR14(%rsi), %r14
+ movq oR15(%rsi), %r15
+
+ /* The following ret should return to the address set with
+ getcontext. Therefore push the address on the stack. */
+ movq oRIP(%rsi), %rcx
+ pushq %rcx
+
+ /* Setup registers used for passing args. */
+ movq oRDI(%rsi), %rdi
+ movq oRDX(%rsi), %rdx
+ movq oRCX(%rsi), %rcx
+ movq oR8(%rsi), %r8
+ movq oR9(%rsi), %r9
+
+ /* Setup finally %rsi. */
+ movq oRSI(%rsi), %rsi
+
+ /* Clear rax to indicate success. */
+ xorl %eax, %eax
+
+L(pseudo_end):
+ ret
+PSEUDO_END(__swapcontext)
+
+weak_alias (__swapcontext, swapcontext)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/debugreg.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/debugreg.h
new file mode 100644
index 000000000..8abbf7546
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/debugreg.h
@@ -0,0 +1,88 @@
+/* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_DEBUGREG_H
+#define _SYS_DEBUGREG_H 1
+#include <bits/wordsize.h>
+
+/* Indicate the register numbers for a number of the specific
+ debug registers. Registers 0-3 contain the addresses we wish to trap on */
+#define DR_FIRSTADDR 0 /* u_debugreg[DR_FIRSTADDR] */
+#define DR_LASTADDR 3 /* u_debugreg[DR_LASTADDR] */
+
+#define DR_STATUS 6 /* u_debugreg[DR_STATUS] */
+#define DR_CONTROL 7 /* u_debugreg[DR_CONTROL] */
+
+/* Define a few things for the status register. We can use this to determine
+ which debugging register was responsible for the trap. The other bits
+ are either reserved or not of interest to us. */
+
+#define DR_TRAP0 (0x1) /* db0 */
+#define DR_TRAP1 (0x2) /* db1 */
+#define DR_TRAP2 (0x4) /* db2 */
+#define DR_TRAP3 (0x8) /* db3 */
+
+#define DR_STEP (0x4000) /* single-step */
+#define DR_SWITCH (0x8000) /* task switch */
+
+/* Now define a bunch of things for manipulating the control register.
+ The top two bytes of the control register consist of 4 fields of 4
+ bits - each field corresponds to one of the four debug registers,
+ and indicates what types of access we trap on, and how large the data
+ field is that we are looking at */
+
+#define DR_CONTROL_SHIFT 16 /* Skip this many bits in ctl register */
+#define DR_CONTROL_SIZE 4 /* 4 control bits per register */
+
+#define DR_RW_EXECUTE (0x0) /* Settings for the access types to trap on */
+#define DR_RW_WRITE (0x1)
+#define DR_RW_READ (0x3)
+
+#define DR_LEN_1 (0x0) /* Settings for data length to trap on */
+#define DR_LEN_2 (0x4)
+#define DR_LEN_4 (0xC)
+#define DR_LEN_8 (0x8)
+
+/* The low byte to the control register determine which registers are
+ enabled. There are 4 fields of two bits. One bit is "local", meaning
+ that the processor will reset the bit after a task switch and the other
+ is global meaning that we have to explicitly reset the bit. With linux,
+ you can use either one, since we explicitly zero the register when we enter
+ kernel mode. */
+
+#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit */
+#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit */
+#define DR_ENABLE_SIZE 2 /* 2 enable bits per register */
+
+#define DR_LOCAL_ENABLE_MASK (0x55) /* Set local bits for all 4 regs */
+#define DR_GLOBAL_ENABLE_MASK (0xAA) /* Set global bits for all 4 regs */
+
+/* The second byte to the control register has a few special
+ things. */
+
+
+
+#if __WORDSIZE == 64
+# define DR_CONTROL_RESERVED (0xFFFFFFFF0000FC00UL) /* Reserved */
+#else
+# define DR_CONTROL_RESERVED (0x00FC00U) /* Reserved */
+#endif
+#define DR_LOCAL_SLOWDOWN (0x100) /* Local slow the pipeline */
+#define DR_GLOBAL_SLOWDOWN (0x200) /* Global slow the pipeline */
+
+#endif /* sys/debugreg.h */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h
new file mode 100644
index 000000000..02672d3c7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h
@@ -0,0 +1,110 @@
+/* Copyright (C) 2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_EPOLL_H
+#define _SYS_EPOLL_H 1
+
+#include <stdint.h>
+#include <sys/types.h>
+
+
+enum EPOLL_EVENTS
+ {
+ EPOLLIN = 0x001,
+#define EPOLLIN EPOLLIN
+ EPOLLPRI = 0x002,
+#define EPOLLPRI EPOLLPRI
+ EPOLLOUT = 0x004,
+#define EPOLLOUT EPOLLOUT
+ EPOLLRDNORM = 0x040,
+#define EPOLLRDNORM EPOLLRDNORM
+ EPOLLRDBAND = 0x080,
+#define EPOLLRDBAND EPOLLRDBAND
+ EPOLLWRNORM = 0x100,
+#define EPOLLWRNORM EPOLLWRNORM
+ EPOLLWRBAND = 0x200,
+#define EPOLLWRBAND EPOLLWRBAND
+ EPOLLMSG = 0x400,
+#define EPOLLMSG EPOLLMSG
+ EPOLLERR = 0x008,
+#define EPOLLERR EPOLLERR
+ EPOLLHUP = 0x010,
+#define EPOLLHUP EPOLLHUP
+ EPOLLONESHOT = (1 << 30),
+#define EPOLLONESHOT EPOLLONESHOT
+ EPOLLET = (1 << 31)
+#define EPOLLET EPOLLET
+ };
+
+
+/* Valid opcodes ( "op" parameter ) to issue to epoll_ctl(). */
+#define EPOLL_CTL_ADD 1 /* Add a file decriptor to the interface. */
+#define EPOLL_CTL_DEL 2 /* Remove a file decriptor from the interface. */
+#define EPOLL_CTL_MOD 3 /* Change file decriptor epoll_event structure. */
+
+
+typedef union epoll_data
+{
+ void *ptr;
+ int fd;
+ uint32_t u32;
+ uint64_t u64;
+} epoll_data_t;
+
+struct epoll_event
+{
+ uint32_t events; /* Epoll events */
+ epoll_data_t data; /* User data variable */
+} __attribute__ ((__packed__));
+
+
+__BEGIN_DECLS
+
+/* Creates an epoll instance. Returns an fd for the new instance.
+ The "size" parameter is a hint specifying the number of file
+ descriptors to be associated with the new instance. The fd
+ returned by epoll_create() should be closed with close(). */
+extern int epoll_create (int __size) __THROW;
+
+
+/* Manipulate an epoll instance "epfd". Returns 0 in case of success,
+ -1 in case of error ( the "errno" variable will contain the
+ specific error code ) The "op" parameter is one of the EPOLL_CTL_*
+ constants defined above. The "fd" parameter is the target of the
+ operation. The "event" parameter describes which events the caller
+ is interested in and any associated user data. */
+extern int epoll_ctl (int __epfd, int __op, int __fd,
+ struct epoll_event *__event) __THROW;
+
+
+/* Wait for events on an epoll instance "epfd". Returns the number of
+ triggered events returned in "events" buffer. Or -1 in case of
+ error with the "errno" variable set to the specific error code. The
+ "events" parameter is a buffer that will contain triggered
+ events. The "maxevents" is the maximum number of events to be
+ returned ( usually size of "events" ). The "timeout" parameter
+ specifies the maximum wait time in milliseconds (-1 == infinite).
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int epoll_wait (int __epfd, struct epoll_event *__events,
+ int __maxevents, int __timeout);
+
+__END_DECLS
+
+#endif /* sys/epoll.h */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/io.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/io.h
new file mode 100644
index 000000000..802a0dfb4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/io.h
@@ -0,0 +1,181 @@
+/* Copyright (C) 1996, 2000, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_IO_H
+#define _SYS_IO_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* If TURN_ON is TRUE, request for permission to do direct i/o on the
+ port numbers in the range [FROM,FROM+NUM-1]. Otherwise, turn I/O
+ permission off for that range. This call requires root privileges.
+
+ Portability note: not all Linux platforms support this call. Most
+ platforms based on the PC I/O architecture probably will, however.
+ E.g., Linux/Alpha for Alpha PCs supports this. */
+extern int ioperm (unsigned long int __from, unsigned long int __num,
+ int __turn_on) __THROW;
+
+/* Set the I/O privilege level to LEVEL. If LEVEL>3, permission to
+ access any I/O port is granted. This call requires root
+ privileges. */
+extern int iopl (int __level) __THROW;
+
+#if defined __GNUC__ && __GNUC__ >= 2
+
+static __inline unsigned char
+inb (unsigned short int port)
+{
+ unsigned char _v;
+
+ __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned char
+inb_p (unsigned short int port)
+{
+ unsigned char _v;
+
+ __asm__ __volatile__ ("inb %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned short int
+inw (unsigned short int port)
+{
+ unsigned short _v;
+
+ __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned short int
+inw_p (unsigned short int port)
+{
+ unsigned short int _v;
+
+ __asm__ __volatile__ ("inw %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned int
+inl (unsigned short int port)
+{
+ unsigned int _v;
+
+ __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned int
+inl_p (unsigned short int port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("inl %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline void
+outb (unsigned char value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port));
+}
+
+static __inline void
+outb_p (unsigned char value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outb %b0,%w1\noutb %%al,$0x80": :"a" (value),
+ "Nd" (port));
+}
+
+static __inline void
+outw (unsigned short int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port));
+
+}
+
+static __inline void
+outw_p (unsigned short int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outw %w0,%w1\noutb %%al,$0x80": :"a" (value),
+ "Nd" (port));
+}
+
+static __inline void
+outl (unsigned int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port));
+}
+
+static __inline void
+outl_p (unsigned int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outl %0,%w1\noutb %%al,$0x80": :"a" (value),
+ "Nd" (port));
+}
+
+static __inline void
+insb (unsigned short int port, void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; insb":"=D" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+insw (unsigned short int port, void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; insw":"=D" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+insl (unsigned short int port, void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; insl":"=D" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+outsb (unsigned short int port, const void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; outsb":"=S" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+outsw (unsigned short int port, const void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; outsw":"=S" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+outsl (unsigned short int port, const void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; outsl":"=S" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+#endif /* GNU C */
+
+__END_DECLS
+#endif /* _SYS_IO_H */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/perm.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/perm.h
new file mode 100644
index 000000000..382fa92ee
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/perm.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 1996, 1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PERM_H
+
+#define _SYS_PERM_H 1
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Set port input/output permissions. */
+extern int ioperm (unsigned long int __from, unsigned long int __num,
+ int __turn_on) __THROW;
+
+
+/* Change I/O privilege level. */
+extern int iopl (int __level) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_PERM_H */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/procfs.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/procfs.h
new file mode 100644
index 000000000..853d7db49
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/procfs.h
@@ -0,0 +1,142 @@
+/* Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H 1
+
+/* This is somewhat modelled after the file of the same name on SVR4
+ systems. It provides a definition of the core file format for ELF
+ used on Linux. It doesn't have anything to do with the /proc file
+ system, even though Linux has one.
+
+ Anyway, the whole purpose of this file is for GDB and GDB only.
+ Don't read too much into it. Don't use it for anything other than
+ GDB unless you know what you are doing. */
+
+#include <features.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+__BEGIN_DECLS
+
+/* Type for a general-purpose register. */
+typedef unsigned long elf_greg_t;
+
+/* And the whole bunch of them. We could have used `struct
+ user_regs_struct' directly in the typedef, but tradition says that
+ the register set is an array, which does have some peculiar
+ semantics, so leave it that way. */
+#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+#if __WORDSIZE == 32
+/* Register set for the floating-point registers. */
+typedef struct user_fpregs_struct elf_fpregset_t;
+
+/* Register set for the extended floating-point registers. Includes
+ the Pentium III SSE registers in addition to the classic
+ floating-point stuff. */
+typedef struct user_fpxregs_struct elf_fpxregset_t;
+#else
+/* Register set for the extended floating-point registers. Includes
+ the Pentium III SSE registers in addition to the classic
+ floating-point stuff. */
+typedef struct user_fpregs_struct elf_fpregset_t;
+#endif
+
+/* Signal info. */
+struct elf_siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_code; /* Extra code. */
+ int si_errno; /* Errno. */
+ };
+
+
+/* Definitions to generate Intel SVR4-like core files. These mostly
+ have the same names as the SVR4 types with "elf_" tacked on the
+ front to prevent clashes with Linux definitions, and the typedef
+ forms have been avoided. This is mostly like the SVR4 structure,
+ but more Linuxy, with things that Linux does not support and which
+ GDB doesn't really use excluded. */
+
+struct elf_prstatus
+ {
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned long int pr_sigpend; /* Set of pending signals. */
+ unsigned long int pr_sighold; /* Set of held signals. */
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct timeval pr_utime; /* User time. */
+ struct timeval pr_stime; /* System time. */
+ struct timeval pr_cutime; /* Cumulative user time. */
+ struct timeval pr_cstime; /* Cumulative system time. */
+ elf_gregset_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+#define ELF_PRARGSZ (80) /* Number of chars for args. */
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long int pr_flag; /* Flags. */
+#if __WORDSIZE == 32
+ unsigned short int pr_uid;
+ unsigned short int pr_gid;
+#else
+ unsigned int pr_uid;
+ unsigned int pr_gid;
+#endif
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+
+/* The rest of this file provides the types for emulation of the
+ Solaris <proc_service.h> interfaces that should be implemented by
+ users of libthread_db. */
+
+/* Addresses. */
+typedef void *psaddr_t;
+
+/* Register sets. Linux has different names. */
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+ therefore have only one PID type. */
+typedef __pid_t lwpid_t;
+
+/* Process status and info. In the end we do provide typedefs for them. */
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif /* sys/procfs.h */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/reg.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/reg.h
new file mode 100644
index 000000000..acb71a2bc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/reg.h
@@ -0,0 +1,79 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_REG_H
+#define _SYS_REG_H 1
+#include <bits/wordsize.h>
+
+
+#if __WORDSIZE == 64
+/* Index into an array of 8 byte longs returned from ptrace for
+ location of the users' stored general purpose registers. */
+
+# define R15 0
+# define R14 1
+# define R13 2
+# define R12 3
+# define RBP 4
+# define RBX 5
+# define R11 6
+# define R10 7
+# define R9 8
+# define R8 9
+# define RAX 10
+# define RCX 11
+# define RDX 12
+# define RSI 13
+# define RDI 14
+# define ORIG_RAX 15
+# define RIP 16
+# define CS 17
+# define EFLAGS 18
+# define RSP 19
+# define SS 20
+# define FS_BASE 21
+# define GS_BASE 22
+# define DS 23
+# define ES 24
+# define FS 25
+# define GS 26
+#else
+
+/* Index into an array of 4 byte integers returned from ptrace for
+ * location of the users' stored general purpose registers. */
+
+# define EBX 0
+# define ECX 1
+# define EDX 2
+# define ESI 3
+# define EDI 4
+# define EBP 5
+# define EAX 6
+# define DS 7
+# define ES 8
+# define FS 9
+# define GS 10
+# define ORIG_EAX 11
+# define EIP 12
+# define CS 13
+# define EFL 14
+# define UESP 15
+# define SS 16
+#endif
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/ucontext.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/ucontext.h
new file mode 100644
index 000000000..b59cd292f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/ucontext.h
@@ -0,0 +1,248 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+#include <bits/wordsize.h>
+
+/* We need the signal context definitions even if they are not used
+ included in <signal.h>. */
+#include <bits/sigcontext.h>
+
+#if __WORDSIZE == 64
+
+/* Type for general register. */
+typedef long int greg_t;
+
+/* Number of general registers. */
+#define NGREG 23
+
+/* Container for all general registers. */
+typedef greg_t gregset_t[NGREG];
+
+#ifdef __USE_GNU
+/* Number of each register in the `gregset_t' array. */
+enum
+{
+ REG_R8 = 0,
+# define REG_R8 REG_R8
+ REG_R9,
+# define REG_R9 REG_R9
+ REG_R10,
+# define REG_R10 REG_R10
+ REG_R11,
+# define REG_R11 REG_R11
+ REG_R12,
+# define REG_R12 REG_R12
+ REG_R13,
+# define REG_R13 REG_R13
+ REG_R14,
+# define REG_R14 REG_R14
+ REG_R15,
+# define REG_R15 REG_R15
+ REG_RDI,
+# define REG_RDI REG_RDI
+ REG_RSI,
+# define REG_RSI REG_RSI
+ REG_RBP,
+# define REG_RBP REG_RBP
+ REG_RBX,
+# define REG_RBX REG_RBX
+ REG_RDX,
+# define REG_RDX REG_RDX
+ REG_RAX,
+# define REG_RAX REG_RAX
+ REG_RCX,
+# define REG_RCX REG_RCX
+ REG_RSP,
+# define REG_RSP REG_RSP
+ REG_RIP,
+# define REG_RIP REG_RIP
+ REG_EFL,
+# define REG_EFL REG_EFL
+ REG_CSGSFS, /* Actually short cs, gs, fs, __pad0. */
+# define REG_CSGSFS REG_CSGSFS
+ REG_ERR,
+# define REG_ERR REG_ERR
+ REG_TRAPNO,
+# define REG_TRAPNO REG_TRAPNO
+ REG_OLDMASK,
+# define REG_OLDMASK REG_OLDMASK
+ REG_CR2
+# define REG_CR2 REG_CR2
+};
+#endif
+
+struct _libc_fpxreg
+{
+ unsigned short int significand[4];
+ unsigned short int exponent;
+ unsigned short int padding[3];
+};
+
+struct _libc_xmmreg
+{
+ __uint32_t element[4];
+};
+
+struct _libc_fpstate
+{
+ /* 64-bit FXSAVE format. */
+ __uint16_t cwd;
+ __uint16_t swd;
+ __uint16_t ftw;
+ __uint16_t fop;
+ __uint64_t rip;
+ __uint64_t rdp;
+ __uint32_t mxcsr;
+ __uint32_t mxcr_mask;
+ struct _libc_fpxreg _st[8];
+ struct _libc_xmmreg _xmm[16];
+ __uint32_t padding[24];
+};
+
+/* Structure to describe FPU registers. */
+typedef struct _libc_fpstate *fpregset_t;
+
+/* Context to describe whole processor state. */
+typedef struct
+ {
+ gregset_t gregs;
+ /* Note that fpregs is a pointer. */
+ fpregset_t fpregs;
+ unsigned long __reserved1 [8];
+} mcontext_t;
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ __sigset_t uc_sigmask;
+ struct _libc_fpstate __fpregs_mem;
+ } ucontext_t;
+
+#else /* __WORDSIZE == 32 */
+
+/* Type for general register. */
+typedef int greg_t;
+
+/* Number of general registers. */
+#define NGREG 19
+
+/* Container for all general registers. */
+typedef greg_t gregset_t[NGREG];
+
+#ifdef __USE_GNU
+/* Number of each register is the `gregset_t' array. */
+enum
+{
+ REG_GS = 0,
+# define REG_GS REG_GS
+ REG_FS,
+# define REG_FS REG_FS
+ REG_ES,
+# define REG_ES REG_ES
+ REG_DS,
+# define REG_DS REG_DS
+ REG_EDI,
+# define REG_EDI REG_EDI
+ REG_ESI,
+# define REG_ESI REG_ESI
+ REG_EBP,
+# define REG_EBP REG_EBP
+ REG_ESP,
+# define REG_ESP REG_ESP
+ REG_EBX,
+# define REG_EBX REG_EBX
+ REG_EDX,
+# define REG_EDX REG_EDX
+ REG_ECX,
+# define REG_ECX REG_ECX
+ REG_EAX,
+# define REG_EAX REG_EAX
+ REG_TRAPNO,
+# define REG_TRAPNO REG_TRAPNO
+ REG_ERR,
+# define REG_ERR REG_ERR
+ REG_EIP,
+# define REG_EIP REG_EIP
+ REG_CS,
+# define REG_CS REG_CS
+ REG_EFL,
+# define REG_EFL REG_EFL
+ REG_UESP,
+# define REG_UESP REG_UESP
+ REG_SS
+# define REG_SS REG_SS
+};
+#endif
+
+/* Definitions taken from the kernel headers. */
+struct _libc_fpreg
+{
+ unsigned short int significand[4];
+ unsigned short int exponent;
+};
+
+struct _libc_fpstate
+{
+ unsigned long int cw;
+ unsigned long int sw;
+ unsigned long int tag;
+ unsigned long int ipoff;
+ unsigned long int cssel;
+ unsigned long int dataoff;
+ unsigned long int datasel;
+ struct _libc_fpreg _st[8];
+ unsigned long int status;
+};
+
+/* Structure to describe FPU registers. */
+typedef struct _libc_fpstate *fpregset_t;
+
+/* Context to describe whole processor state. */
+typedef struct
+ {
+ gregset_t gregs;
+ /* Due to Linux's history we have to use a pointer here. The SysV/i386
+ ABI requires a struct with the values. */
+ fpregset_t fpregs;
+ unsigned long int oldmask;
+ unsigned long int cr2;
+ } mcontext_t;
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ __sigset_t uc_sigmask;
+ struct _libc_fpstate __fpregs_mem;
+ } ucontext_t;
+
+#endif /* __WORDSIZE == 32 */
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/user.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/user.h
new file mode 100644
index 000000000..ceadcf478
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/user.h
@@ -0,0 +1,175 @@
+/* Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H 1
+
+/* The whole purpose of this file is for GDB and GDB only. Don't read
+ too much into it. Don't use it for anything other than GDB unless
+ you know what you are doing. */
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+
+struct user_fpregs_struct
+{
+ __uint16_t cwd;
+ __uint16_t swd;
+ __uint16_t ftw;
+ __uint16_t fop;
+ __uint64_t rip;
+ __uint64_t rdp;
+ __uint32_t mxcsr;
+ __uint32_t mxcr_mask;
+ __uint32_t st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
+ __uint32_t xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */
+ __uint32_t padding[24];
+};
+
+struct user_regs_struct
+{
+ unsigned long r15;
+ unsigned long r14;
+ unsigned long r13;
+ unsigned long r12;
+ unsigned long rbp;
+ unsigned long rbx;
+ unsigned long r11;
+ unsigned long r10;
+ unsigned long r9;
+ unsigned long r8;
+ unsigned long rax;
+ unsigned long rcx;
+ unsigned long rdx;
+ unsigned long rsi;
+ unsigned long rdi;
+ unsigned long orig_rax;
+ unsigned long rip;
+ unsigned long cs;
+ unsigned long eflags;
+ unsigned long rsp;
+ unsigned long ss;
+ unsigned long fs_base;
+ unsigned long gs_base;
+ unsigned long ds;
+ unsigned long es;
+ unsigned long fs;
+ unsigned long gs;
+};
+
+struct user
+{
+ struct user_regs_struct regs;
+ int u_fpvalid;
+ struct user_fpregs_struct i387;
+ unsigned long int u_tsize;
+ unsigned long int u_dsize;
+ unsigned long int u_ssize;
+ unsigned long start_code;
+ unsigned long start_stack;
+ long int signal;
+ int reserved;
+ struct user_regs_struct* u_ar0;
+ struct user_fpregs_struct* u_fpstate;
+ unsigned long int magic;
+ char u_comm [32];
+ unsigned long int u_debugreg [8];
+};
+
+#else
+/* These are the 32-bit x86 structures. */
+struct user_fpregs_struct
+{
+ long int cwd;
+ long int swd;
+ long int twd;
+ long int fip;
+ long int fcs;
+ long int foo;
+ long int fos;
+ long int st_space [20];
+};
+
+struct user_fpxregs_struct
+{
+ unsigned short int cwd;
+ unsigned short int swd;
+ unsigned short int twd;
+ unsigned short int fop;
+ long int fip;
+ long int fcs;
+ long int foo;
+ long int fos;
+ long int mxcsr;
+ long int reserved;
+ long int st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
+ long int xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
+ long int padding[56];
+};
+
+struct user_regs_struct
+{
+ long int ebx;
+ long int ecx;
+ long int edx;
+ long int esi;
+ long int edi;
+ long int ebp;
+ long int eax;
+ long int xds;
+ long int xes;
+ long int xfs;
+ long int xgs;
+ long int orig_eax;
+ long int eip;
+ long int xcs;
+ long int eflags;
+ long int esp;
+ long int xss;
+};
+
+struct user
+{
+ struct user_regs_struct regs;
+ int u_fpvalid;
+ struct user_fpregs_struct i387;
+ unsigned long int u_tsize;
+ unsigned long int u_dsize;
+ unsigned long int u_ssize;
+ unsigned long start_code;
+ unsigned long start_stack;
+ long int signal;
+ int reserved;
+ struct user_regs_struct* u_ar0;
+ struct user_fpregs_struct* u_fpstate;
+ unsigned long int magic;
+ char u_comm [32];
+ int u_debugreg [8];
+};
+#endif /* __WORDSIZE */
+
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif /* _SYS_USER_H */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/syscall.S b/libc/sysdeps/unix/sysv/linux/x86_64/syscall.S
new file mode 100644
index 000000000..cf49dbcd1
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/syscall.S
@@ -0,0 +1,44 @@
+/* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* Please consult the file sysdeps/unix/sysv/linux/x86-64/sysdep.h for
+ more information about the value -4095 used below. */
+
+/* Usage: long syscall (syscall_number, arg1, arg2, arg3, arg4, arg5, arg6)
+ We need to do some arg shifting, the syscall_number will be in
+ rax. */
+
+
+ .text
+ENTRY (syscall)
+ movq %rdi, %rax /* Syscall number -> rax. */
+ movq %rsi, %rdi /* shift arg1 - arg5. */
+ movq %rdx, %rsi
+ movq %rcx, %rdx
+ movq %r8, %r10
+ movq %r9, %r8
+ movq 8(%rsp),%r9 /* arg6 is on the stack. */
+ syscall /* Do the system call. */
+ cmpq $-4095, %rax /* Check %rax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+L(pseudo_end):
+ ret /* Return to caller. */
+
+PSEUDO_END (syscall)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/syscalls.list b/libc/sysdeps/unix/sysv/linux/x86_64/syscalls.list
new file mode 100644
index 000000000..a9d40446d
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/syscalls.list
@@ -0,0 +1,36 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+arch_prctl EXTRA arch_prctl i:ii __arch_prctl arch_prctl
+modify_ldt EXTRA modify_ldt i:ipi __modify_ldt modify_ldt
+
+# semaphore and shm system calls
+msgctl - msgctl i:iip __msgctl msgctl
+msgget - msgget i:ii __msgget msgget
+msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
+msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
+shmat - shmat i:ipi __shmat shmat
+shmctl - shmctl i:iip __shmctl shmctl
+shmdt - shmdt i:s __shmdt shmdt
+shmget - shmget i:iii __shmget shmget
+semop - semop i:ipi __semop semop
+semtimedop - semtimedop i:ipip semtimedop
+semget - semget i:iii __semget semget
+semctl - semctl i:iiii __semctl semctl
+
+
+# proper socket implementations:
+accept - accept Ci:iBN __libc_accept __accept accept
+bind - bind i:ipi __bind bind
+connect - connect Ci:ipi __libc_connect __connect_internal __connect connect
+getpeername - getpeername i:ipp __getpeername getpeername
+getsockname - getsockname i:ipp __getsockname getsockname
+getsockopt - getsockopt i:iiiBN __getsockopt getsockopt
+listen - listen i:ii __listen listen
+recvfrom - recvfrom Ci:ibniBN __libc_recvfrom __recvfrom recvfrom
+recvmsg - recvmsg Ci:ipi __libc_recvmsg __recvmsg recvmsg
+sendmsg - sendmsg Ci:ipi __libc_sendmsg __sendmsg sendmsg
+sendto - sendto Ci:ibnibn __libc_sendto __sendto sendto
+setsockopt - setsockopt i:iiibn __setsockopt setsockopt
+shutdown - shutdown i:ii __shutdown shutdown
+socket - socket i:iii __socket socket
+socketpair - socketpair i:iiif __socketpair socketpair
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sysconf.c b/libc/sysdeps/unix/sysv/linux/x86_64/sysconf.c
new file mode 100644
index 000000000..726c5e33a
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sysconf.c
@@ -0,0 +1,326 @@
+/* Get file-specific information about a file. Linux version.
+ Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+static long int linux_sysconf (int name);
+
+
+static const struct intel_02_cache_info
+{
+ unsigned int idx;
+ int name;
+ long int size;
+ long int assoc;
+ long int linesize;
+} intel_02_known[] =
+ {
+ { 0x06, _SC_LEVEL1_ICACHE_SIZE, 8192, 4, 32 },
+ { 0x08, _SC_LEVEL1_ICACHE_SIZE, 16384, 4, 32 },
+ { 0x0a, _SC_LEVEL1_DCACHE_SIZE, 8192, 2, 32 },
+ { 0x0c, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 32 },
+ { 0x22, _SC_LEVEL3_CACHE_SIZE, 524288, 4, 64 },
+ { 0x23, _SC_LEVEL3_CACHE_SIZE, 1048576, 8, 64 },
+ { 0x25, _SC_LEVEL3_CACHE_SIZE, 2097152, 8, 64 },
+ { 0x29, _SC_LEVEL3_CACHE_SIZE, 4194304, 8, 64 },
+ { 0x2c, _SC_LEVEL1_DCACHE_SIZE, 32768, 8, 64 },
+ { 0x30, _SC_LEVEL1_ICACHE_SIZE, 32768, 8, 64 },
+ { 0x39, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 64 },
+ { 0x3a, _SC_LEVEL2_CACHE_SIZE, 196608, 6, 64 },
+ { 0x3b, _SC_LEVEL2_CACHE_SIZE, 131072, 2, 64 },
+ { 0x3c, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 64 },
+ { 0x3d, _SC_LEVEL2_CACHE_SIZE, 393216, 6, 64 },
+ { 0x3e, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 },
+ { 0x41, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 32 },
+ { 0x42, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 32 },
+ { 0x43, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 32 },
+ { 0x44, _SC_LEVEL2_CACHE_SIZE, 1048576, 4, 32 },
+ { 0x45, _SC_LEVEL2_CACHE_SIZE, 2097152, 4, 32 },
+ { 0x46, _SC_LEVEL3_CACHE_SIZE, 4194304, 4, 64 },
+ { 0x47, _SC_LEVEL3_CACHE_SIZE, 8388608, 8, 64 },
+ { 0x49, _SC_LEVEL3_CACHE_SIZE, 4194304, 16, 64 },
+ { 0x4a, _SC_LEVEL3_CACHE_SIZE, 6291456, 12, 64 },
+ { 0x4b, _SC_LEVEL3_CACHE_SIZE, 8388608, 16, 64 },
+ { 0x4c, _SC_LEVEL3_CACHE_SIZE, 12582912, 12, 64 },
+ { 0x4d, _SC_LEVEL3_CACHE_SIZE, 16777216, 16, 64 },
+ { 0x60, _SC_LEVEL1_DCACHE_SIZE, 16384, 8, 64 },
+ { 0x66, _SC_LEVEL1_DCACHE_SIZE, 8192, 4, 64 },
+ { 0x67, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 64 },
+ { 0x68, _SC_LEVEL1_DCACHE_SIZE, 32768, 4, 64 },
+ { 0x78, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 },
+ { 0x79, _SC_LEVEL2_CACHE_SIZE, 131072, 8, 64 },
+ { 0x7a, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 64 },
+ { 0x7b, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 64 },
+ { 0x7c, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 },
+ { 0x7d, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 64 },
+ { 0x7f, _SC_LEVEL2_CACHE_SIZE, 524288, 2, 64 },
+ { 0x82, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 32 },
+ { 0x83, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 32 },
+ { 0x84, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 32 },
+ { 0x85, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 32 },
+ { 0x86, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 },
+ { 0x87, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 },
+ };
+#define nintel_02_known (sizeof (intel_02_known) / sizeof (intel_02_known[0]))
+
+
+static int
+intel_02_known_compare (const void *p1, const void *p2)
+{
+ const struct intel_02_cache_info *i1;
+ const struct intel_02_cache_info *i2;
+
+ i1 = (const struct intel_02_cache_info *) p1;
+ i2 = (const struct intel_02_cache_info *) p2;
+
+ if (i1->idx == i2->idx)
+ return 0;
+
+ return i1->idx < i2->idx ? -1 : 1;
+}
+
+
+static long int
+intel_check_word (int name, unsigned int value, bool *has_level_2,
+ bool *no_level_2_or_3)
+{
+ if ((value & 0x80000000) != 0)
+ /* The register value is reserved. */
+ return 0;
+
+ /* Fold the name. The _SC_ constants are always in the order SIZE,
+ ASSOC, LINESIZE. */
+ int folded_name = (_SC_LEVEL1_ICACHE_SIZE
+ + ((name - _SC_LEVEL1_ICACHE_SIZE) / 3) * 3);
+
+ while (value != 0)
+ {
+ unsigned int byte = value & 0xff;
+
+ if (byte == 0x40)
+ {
+ *no_level_2_or_3 = true;
+
+ if (folded_name == _SC_LEVEL3_CACHE_SIZE)
+ /* No need to look further. */
+ break;
+ }
+ else
+ {
+ struct intel_02_cache_info *found;
+ struct intel_02_cache_info search;
+
+ search.idx = byte;
+ found = bsearch (&search, intel_02_known, nintel_02_known,
+ sizeof (intel_02_known[0]), intel_02_known_compare);
+ if (found != NULL)
+ {
+ if (found->name == folded_name)
+ {
+ unsigned int offset = name - folded_name;
+
+ if (offset == 0)
+ /* Cache size. */
+ return found->size;
+ if (offset == 1)
+ return found->assoc;
+
+ assert (offset == 2);
+ return found->linesize;
+ }
+
+ if (found->name == _SC_LEVEL2_CACHE_SIZE)
+ *has_level_2 = true;
+ }
+ }
+
+ /* Next byte for the next round. */
+ value >>= 8;
+ }
+
+ /* Nothing found. */
+ return 0;
+}
+
+
+static long int __attribute__ ((noinline))
+handle_intel (int name, unsigned int maxidx)
+{
+ assert (maxidx >= 2);
+
+ /* OK, we can use the CPUID instruction to get all info about the
+ caches. */
+ unsigned int cnt = 0;
+ unsigned int max = 1;
+ long int result = 0;
+ bool no_level_2_or_3 = false;
+ bool has_level_2 = false;
+ while (cnt++ < max)
+ {
+ unsigned int eax;
+ unsigned int ebx;
+ unsigned int ecx;
+ unsigned int edx;
+ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+ : "0" (2));
+
+ /* The low byte of EAX in the first round contain the number of
+ rounds we have to make. At least one, the one we are already
+ doing. */
+ if (cnt == 1)
+ {
+ max = eax & 0xff;
+ eax &= 0xffffff00;
+ }
+
+ /* Process the individual registers' value. */
+ result = intel_check_word (name, eax, &has_level_2, &no_level_2_or_3);
+ if (result != 0)
+ return result;
+
+ result = intel_check_word (name, ebx, &has_level_2, &no_level_2_or_3);
+ if (result != 0)
+ return result;
+
+ result = intel_check_word (name, ecx, &has_level_2, &no_level_2_or_3);
+ if (result != 0)
+ return result;
+
+ result = intel_check_word (name, edx, &has_level_2, &no_level_2_or_3);
+ if (result != 0)
+ return result;
+ }
+
+ if (name >= _SC_LEVEL2_CACHE_SIZE && name <= _SC_LEVEL3_CACHE_LINESIZE
+ && no_level_2_or_3)
+ return -1;
+
+ return 0;
+}
+
+
+static long int __attribute__ ((noinline))
+handle_amd (int name)
+{
+ unsigned int eax;
+ unsigned int ebx;
+ unsigned int ecx;
+ unsigned int edx;
+ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+ : "0" (0x80000000));
+
+ if (name >= _SC_LEVEL3_CACHE_SIZE)
+ return 0;
+
+ unsigned int fn = 0x80000005 + (name >= _SC_LEVEL2_CACHE_SIZE);
+ if (eax < fn)
+ return 0;
+
+ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+ : "0" (fn));
+
+ if (name < _SC_LEVEL1_DCACHE_SIZE)
+ {
+ name += _SC_LEVEL1_DCACHE_SIZE - _SC_LEVEL1_ICACHE_SIZE;
+ ecx = edx;
+ }
+
+ switch (name)
+ {
+ case _SC_LEVEL1_DCACHE_SIZE:
+ return (ecx >> 14) & 0x3fc00;
+ case _SC_LEVEL1_DCACHE_ASSOC:
+ ecx >>= 16;
+ if ((ecx & 0xff) == 0xff)
+ /* Fully associative. */
+ return (ecx << 2) & 0x3fc00;
+ return ecx & 0xff;
+ case _SC_LEVEL1_DCACHE_LINESIZE:
+ return ecx & 0xff;
+ case _SC_LEVEL2_CACHE_SIZE:
+ return (ecx & 0xf000) == 0 ? 0 : (ecx >> 6) & 0x3fffc00;
+ case _SC_LEVEL2_CACHE_ASSOC:
+ ecx >>= 12;
+ switch (ecx & 0xf)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ return ecx & 0xf;
+ case 6:
+ return 8;
+ case 8:
+ return 16;
+ case 0xf:
+ return (ecx << 6) & 0x3fffc00;
+ default:
+ return 0;
+ }
+ case _SC_LEVEL2_CACHE_LINESIZE:
+ return (ecx & 0xf000) == 0 ? 0 : ecx & 0xff;
+ default:
+ assert (! "cannot happen");
+ }
+ return -1;
+}
+
+
+/* Get the value of the system variable NAME. */
+long int
+__sysconf (int name)
+{
+ /* We only handle the cache information here (for now). */
+ if (name < _SC_LEVEL1_ICACHE_SIZE || name > _SC_LEVEL4_CACHE_LINESIZE)
+ return linux_sysconf (name);
+
+ /* Find out what brand of processor. */
+ unsigned int eax;
+ unsigned int ebx;
+ unsigned int ecx;
+ unsigned int edx;
+ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+ : "0" (0));
+
+ /* This spells out "GenuineIntel". */
+ if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)
+ return handle_intel (name, eax);
+
+ /* This spells out "AuthenticAMD". */
+ if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
+ return handle_amd (name);
+
+ // XXX Fill in more vendors.
+
+ /* CPU not known, we have no information. */
+ return 0;
+}
+
+/* Now the generic Linux version. */
+#undef __sysconf
+#define __sysconf static linux_sysconf
+#include "../sysconf.c"
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.S b/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.S
new file mode 100644
index 000000000..5b72cef20
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.S
@@ -0,0 +1,41 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* The following code is only used in the shared library when we
+ compile the reentrant version. Otherwise each system call defines
+ each own version. */
+
+#ifndef PIC
+
+/* The syscall stubs jump here when they detect an error.
+ The code for Linux is almost identical to the canonical Unix
+ code, except that the error number in %rax is negated. */
+
+#undef CALL_MCOUNT
+#define CALL_MCOUNT /* Don't insert the profiling call, it clobbers %rax. */
+
+ .text
+ENTRY (__syscall_error)
+ negq %rax
+
+#define __syscall_error __syscall_error_1
+#include <sysdeps/unix/x86_64/sysdep.S>
+
+#endif /* !PIC */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h
new file mode 100644
index 000000000..5dfffca45
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -0,0 +1,341 @@
+/* Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINUX_X86_64_SYSDEP_H
+#define _LINUX_X86_64_SYSDEP_H 1
+
+/* There is some commonality. */
+#include <sysdeps/unix/x86_64/sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+#include <tls.h>
+
+#ifdef IS_IN_rtld
+# include <dl-sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */
+#endif
+
+/* For Linux we can use the system call table in the header file
+ /usr/include/asm/unistd.h
+ of the kernel. But these symbols do not follow the SYS_* syntax
+ so we have to redefine the `SYS_ify' macro here. */
+#undef SYS_ify
+#define SYS_ify(syscall_name) __NR_##syscall_name
+
+/* This is a kludge to make syscalls.list find these under the names
+ pread and pwrite, since some kernel headers define those names
+ and some define the *64 names for the same system calls. */
+#if !defined __NR_pread && defined __NR_pread64
+# define __NR_pread __NR_pread64
+#endif
+#if !defined __NR_pwrite && defined __NR_pwrite64
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+/* This is to help the old kernel headers where __NR_semtimedop is not
+ available. */
+#ifndef __NR_semtimedop
+# define __NR_semtimedop 220
+#endif
+
+
+#ifdef __ASSEMBLER__
+
+/* Linux uses a negative return value to indicate syscall errors,
+ unlike most Unices, which use the condition codes' carry flag.
+
+ Since version 2.1 the return value of a system call might be
+ negative even if the call succeeded. E.g., the `lseek' system call
+ might return a large offset. Therefore we must not anymore test
+ for < 0, but test for a real error by making sure the value in %eax
+ is a real error number. Linus said he will make sure the no syscall
+ returns a value in -1 .. -4095 as a valid result so we can savely
+ test with -4095. */
+
+/* We don't want the label for the error handle to be global when we define
+ it here. */
+#ifdef PIC
+# define SYSCALL_ERROR_LABEL 0f
+#else
+# define SYSCALL_ERROR_LABEL syscall_error
+#endif
+
+#undef PSEUDO
+#define PSEUDO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ cmpq $-4095, %rax; \
+ jae SYSCALL_ERROR_LABEL; \
+ L(pseudo_end):
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ SYSCALL_ERROR_HANDLER \
+ END (name)
+
+#undef PSEUDO_NOERRNO
+#define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args)
+
+#undef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(name) \
+ END (name)
+
+#define ret_NOERRNO ret
+
+#undef PSEUDO_ERRVAL
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ negq %rax
+
+#undef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(name) \
+ END (name)
+
+#define ret_ERRVAL ret
+
+#ifndef PIC
+#define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
+#elif RTLD_PRIVATE_ERRNO
+# define SYSCALL_ERROR_HANDLER \
+0: \
+ leaq rtld_errno(%rip), %rcx; \
+ xorl %edx, %edx; \
+ subq %rax, %rdx; \
+ movl %edx, (%rcx); \
+ orq $-1, %rax; \
+ jmp L(pseudo_end);
+#elif USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+# define SYSCALL_ERROR_HANDLER \
+0: \
+ movq SYSCALL_ERROR_ERRNO@GOTTPOFF(%rip), %rcx;\
+ xorl %edx, %edx; \
+ subq %rax, %rdx; \
+ movl %edx, %fs:(%rcx); \
+ orq $-1, %rax; \
+ jmp L(pseudo_end);
+#elif defined _LIBC_REENTRANT
+/* Store (- %rax) into errno through the GOT.
+ Note that errno occupies only 4 bytes. */
+# define SYSCALL_ERROR_HANDLER \
+0: \
+ xorl %edx, %edx; \
+ subq %rax, %rdx; \
+ pushq %rdx; \
+ cfi_adjust_cfa_offset(8); \
+ PUSH_ERRNO_LOCATION_RETURN; \
+ call BP_SYM (__errno_location)@PLT; \
+ POP_ERRNO_LOCATION_RETURN; \
+ popq %rdx; \
+ cfi_adjust_cfa_offset(-8); \
+ movl %edx, (%rax); \
+ orq $-1, %rax; \
+ jmp L(pseudo_end);
+
+/* A quick note: it is assumed that the call to `__errno_location' does
+ not modify the stack! */
+#else /* Not _LIBC_REENTRANT. */
+# define SYSCALL_ERROR_HANDLER \
+0:movq errno@GOTPCREL(%RIP), %rcx; \
+ xorl %edx, %edx; \
+ subq %rax, %rdx; \
+ movl %edx, (%rcx); \
+ orq $-1, %rax; \
+ jmp L(pseudo_end);
+#endif /* PIC */
+
+/* The Linux/x86-64 kernel expects the system call parameters in
+ registers according to the following table:
+
+ syscall number rax
+ arg 1 rdi
+ arg 2 rsi
+ arg 3 rdx
+ arg 4 r10
+ arg 5 r8
+ arg 6 r9
+
+ The Linux kernel uses and destroys internally these registers:
+ return address from
+ syscall rcx
+ additionally clobered: r12-r15,rbx,rbp
+ eflags from syscall r11
+
+ Normal function call, including calls to the system call stub
+ functions in the libc, get the first six parameters passed in
+ registers and the seventh parameter and later on the stack. The
+ register use is as follows:
+
+ system call number in the DO_CALL macro
+ arg 1 rdi
+ arg 2 rsi
+ arg 3 rdx
+ arg 4 rcx
+ arg 5 r8
+ arg 6 r9
+
+ We have to take care that the stack is aligned to 16 bytes. When
+ called the stack is not aligned since the return address has just
+ been pushed.
+
+
+ Syscalls of more than 6 arguments are not supported. */
+
+#undef DO_CALL
+#define DO_CALL(syscall_name, args) \
+ DOARGS_##args \
+ movl $SYS_ify (syscall_name), %eax; \
+ syscall;
+
+#define DOARGS_0 /* nothing */
+#define DOARGS_1 /* nothing */
+#define DOARGS_2 /* nothing */
+#define DOARGS_3 /* nothing */
+#define DOARGS_4 movq %rcx, %r10;
+#define DOARGS_5 DOARGS_4
+#define DOARGS_6 DOARGS_5
+
+#else /* !__ASSEMBLER__ */
+/* Define a macro which expands inline into the wrapper code for a system
+ call. */
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+ ({ \
+ unsigned long resultvar = INTERNAL_SYSCALL (name, , nr, args); \
+ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0)) \
+ { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, )); \
+ resultvar = (unsigned long) -1; \
+ } \
+ (long) resultvar; })
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ unsigned long resultvar; \
+ LOAD_ARGS_##nr (args) \
+ LOAD_REGS_##nr \
+ asm volatile ( \
+ "syscall\n\t" \
+ : "=a" (resultvar) \
+ : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \
+ (long) resultvar; })
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((unsigned long) (val) >= -4095L)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+
+#define LOAD_ARGS_0()
+#define LOAD_REGS_0
+#define ASM_ARGS_0
+
+#define LOAD_ARGS_1(a1) \
+ long int __arg1 = (long) (a1); \
+ LOAD_ARGS_0 ()
+#define LOAD_REGS_1 \
+ register long int _a1 asm ("rdi") = __arg1; \
+ LOAD_REGS_0
+#define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1)
+
+#define LOAD_ARGS_2(a1, a2) \
+ long int __arg2 = (long) (a2); \
+ LOAD_ARGS_1 (a1)
+#define LOAD_REGS_2 \
+ register long int _a2 asm ("rsi") = __arg2; \
+ LOAD_REGS_1
+#define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2)
+
+#define LOAD_ARGS_3(a1, a2, a3) \
+ long int __arg3 = (long) (a3); \
+ LOAD_ARGS_2 (a1, a2)
+#define LOAD_REGS_3 \
+ register long int _a3 asm ("rdx") = __arg3; \
+ LOAD_REGS_2
+#define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3)
+
+#define LOAD_ARGS_4(a1, a2, a3, a4) \
+ long int __arg4 = (long) (a4); \
+ LOAD_ARGS_3 (a1, a2, a3)
+#define LOAD_REGS_4 \
+ register long int _a4 asm ("r10") = __arg4; \
+ LOAD_REGS_3
+#define ASM_ARGS_4 ASM_ARGS_3, "r" (_a4)
+
+#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
+ long int __arg5 = (long) (a5); \
+ LOAD_ARGS_4 (a1, a2, a3, a4)
+#define LOAD_REGS_5 \
+ register long int _a5 asm ("r8") = __arg5; \
+ LOAD_REGS_4
+#define ASM_ARGS_5 ASM_ARGS_4, "r" (_a5)
+
+#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
+ long int __arg6 = (long) (a6); \
+ LOAD_ARGS_5 (a1, a2, a3, a4, a5)
+#define LOAD_REGS_6 \
+ register long int _a6 asm ("r9") = __arg6; \
+ LOAD_REGS_5
+#define ASM_ARGS_6 ASM_ARGS_5, "r" (_a6)
+
+#endif /* __ASSEMBLER__ */
+
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. */
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(reg) xorq __pointer_chk_guard_local(%rip), reg
+# define PTR_DEMANGLE(reg) PTR_MANGLE (reg)
+# else
+# define PTR_MANGLE(reg) asm ("xorq __pointer_chk_guard_local(%%rip), %0"\
+ : "=r" (reg) : "0" (reg))
+# define PTR_DEMANGLE(reg) PTR_MANGLE (reg)
+# endif
+#else
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(reg) xorq %fs:POINTER_GUARD, reg
+# define PTR_DEMANGLE(reg) PTR_MANGLE (reg)
+# else
+# define PTR_MANGLE(var) asm ("xorq %%fs:%c2, %0" \
+ : "=r" (var) \
+ : "0" (var), \
+ "i" (offsetof (tcbhead_t, \
+ pointer_guard)))
+# define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# endif
+#endif
+
+#endif /* linux/x86_64/sysdep.h */
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/time.S b/libc/sysdeps/unix/sysv/linux/x86_64/time.S
new file mode 100644
index 000000000..e3f326876
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/time.S
@@ -0,0 +1,42 @@
+/* Copyright (C) 2001,02, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+/* For the calculation see asm/vsyscall.h. */
+#define VSYSCALL_ADDR_vtime 0xffffffffff600400
+
+
+/* Return the current time as a `time_t' and also put it in *T if T is
+ not NULL. Time is represented as seconds from Jan 1 00:00:00 1970. */
+
+ENTRY (time)
+ /* Align stack. */
+ sub $0x8, %rsp
+ cfi_adjust_cfa_offset(8)
+
+ movq $VSYSCALL_ADDR_vtime, %rax
+ callq *%rax
+
+ add $0x8, %rsp
+ cfi_adjust_cfa_offset(-8)
+ ret
+PSEUDO_END_NOERRNO(time)
+libc_hidden_def (time)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym b/libc/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
new file mode 100644
index 000000000..b3cfe9aa4
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
@@ -0,0 +1,34 @@
+#include <stddef.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+--
+
+SIG_BLOCK
+SIG_SETMASK
+
+_NSIG8 (_NSIG / 8)
+
+#define ucontext(member) offsetof (ucontext_t, member)
+#define mcontext(member) ucontext (uc_mcontext.member)
+#define mreg(reg) mcontext (gregs[REG_##reg])
+
+oRBP mreg (RBP)
+oRSP mreg (RSP)
+oRBX mreg (RBX)
+oR8 mreg (R8)
+oR9 mreg (R9)
+oR12 mreg (R12)
+oR13 mreg (R13)
+oR14 mreg (R14)
+oR15 mreg (R15)
+oRDI mreg (RDI)
+oRSI mreg (RSI)
+oRDX mreg (RDX)
+oRAX mreg (RAX)
+oRCX mreg (RCX)
+oRIP mreg (RIP)
+oFPREGS mcontext (fpregs)
+oSIGMASK ucontext (uc_sigmask)
+oFPREGSMEM ucontext (__fpregs_mem)
+oMXCSR ucontext (__fpregs_mem.mxcsr)
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/umount.c b/libc/sysdeps/unix/sysv/linux/x86_64/umount.c
new file mode 100644
index 000000000..a17c5c579
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/umount.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Since we don't have an oldumount system call, do what the kernel
+ does down here. */
+
+extern long int __umount2 (const char *name, int flags);
+
+long int
+__umount (const char *name)
+{
+ return __umount2 (name, 0);
+}
+
+weak_alias (__umount, umount);
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/vfork.S b/libc/sysdeps/unix/sysv/linux/x86_64/vfork.S
new file mode 100644
index 000000000..4bad38892
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/x86_64/vfork.S
@@ -0,0 +1,61 @@
+/* Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+
+ /* Pop the return PC value into RDI. We need a register that
+ is preserved by the syscall and that we're allowed to destroy. */
+ popq %rdi
+ cfi_adjust_cfa_offset(-8)
+
+#ifdef SAVE_PID
+ SAVE_PID
+#endif
+
+ /* Stuff the syscall number in RAX and enter into the kernel. */
+ movl $SYS_ify (vfork), %eax
+ syscall
+
+ /* Push back the return PC. */
+ pushq %rdi
+ cfi_adjust_cfa_offset(8)
+
+#ifdef RESTORE_PID
+ RESTORE_PID
+#endif
+
+ cmpl $-4095, %eax
+ jae SYSCALL_ERROR_LABEL /* Branch forward if it failed. */
+
+ /* Normal return. */
+.Lpseudo_end:
+ ret
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libc/sysdeps/unix/sysv/linux/xmknod.c b/libc/sysdeps/unix/sysv/linux/xmknod.c
new file mode 100644
index 000000000..38d902e65
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/xmknod.c
@@ -0,0 +1,57 @@
+/* xmknod call using old-style Unix mknod system call.
+ Copyright (C) 1991, 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2003
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+/* Create a device file named PATH, with permission and special bits MODE
+ and device number DEV (which can be constructed from major and minor
+ device numbers with the `makedev' macro above). */
+int
+__xmknod (int vers, const char *path, mode_t mode, dev_t *dev)
+{
+ unsigned long long int k_dev;
+
+ if (vers != _MKNOD_VER)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* We must convert the value to dev_t type used by the kernel. */
+ k_dev = (*dev) & ((1ULL << 32) - 1);
+ if (k_dev != *dev)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return INLINE_SYSCALL (mknod, 3, CHECK_STRING (path), mode,
+ (unsigned int) k_dev);
+}
+
+weak_alias (__xmknod, _xmknod)
+libc_hidden_def (__xmknod)
diff --git a/libc/sysdeps/unix/sysv/linux/xmknodat.c b/libc/sysdeps/unix/sysv/linux/xmknodat.c
new file mode 100644
index 000000000..ef27b686c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/xmknodat.c
@@ -0,0 +1,95 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+
+#include <sysdep.h>
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+
+/* Create a device file named PATH relative to FD, with permission and
+ special bits MODE and device number DEV (which can be constructed
+ from major and minor device numbers with the `makedev' macro above). */
+int
+__xmknodat (int vers, int fd, const char *file, mode_t mode, dev_t *dev)
+{
+ if (vers != _MKNOD_VER)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* We must convert the value to dev_t type used by the kernel. */
+ unsigned long long int k_dev = (*dev) & ((1ULL << 32) - 1);
+ if (k_dev != *dev)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+#ifdef __NR_mknodat
+# ifndef __ASSUME_ATFCTS
+ if (__have_atfcts >= 0)
+# endif
+ {
+ int res = INLINE_SYSCALL (mknodat, 4, fd, file, mode,
+ (unsigned int) k_dev);
+# ifndef __ASSUME_ATFCTS
+ if (res == -1 && errno == ENOSYS)
+ __have_atfcts = -1;
+ else
+# endif
+ return res;
+ }
+#endif
+
+#ifndef __ASSUME_ATFCTS
+ char *buf = NULL;
+
+ if (fd != AT_FDCWD && file[0] != '/')
+ {
+ size_t filelen = strlen (file);
+ static const char procfd[] = "/proc/self/fd/%d/%s";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number
+ - the file name provided.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd, file);
+ file = buf;
+ }
+
+ return INLINE_SYSCALL (mknod, 3, CHECK_STRING (file), mode,
+ (unsigned int) k_dev);
+#endif
+}
+
+libc_hidden_def (__xmknodat)
diff --git a/libc/sysdeps/unix/sysv/linux/xstat.c b/libc/sysdeps/unix/sysv/linux/xstat.c
new file mode 100644
index 000000000..60138ee93
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/xstat.c
@@ -0,0 +1,64 @@
+/* xstat using old-style Unix stat system call.
+ Copyright (C) 1991,1995-1998,2000,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ho hum, if xstat == xstat64 we must get rid of the prototype or gcc
+ will complain since they don't strictly match. */
+#define __xstat64 __xstat64_disable
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <xstatconv.h>
+
+/* Get information about the file NAME in BUF. */
+int
+__xstat (int vers, const char *name, struct stat *buf)
+{
+ if (vers == _STAT_VER_KERNEL)
+ return INLINE_SYSCALL (stat, 2, CHECK_STRING (name),
+ CHECK_1 ((struct kernel_stat *) buf));
+
+#ifdef STAT_IS_KERNEL_STAT
+ errno = EINVAL;
+ return -1;
+#else
+ struct kernel_stat kbuf;
+ int result;
+
+ result = INLINE_SYSCALL (stat, 2, CHECK_STRING (name),
+ __ptrvalue (&kbuf));
+ if (result == 0)
+ result = __xstat_conv (vers, &kbuf, buf);
+
+ return result;
+#endif
+}
+hidden_def (__xstat)
+weak_alias (__xstat, _xstat);
+#ifdef XSTAT_IS_XSTAT64
+#undef __xstat64
+strong_alias (__xstat, __xstat64);
+hidden_ver (__xstat, __xstat64)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/xstat64.c b/libc/sysdeps/unix/sysv/linux/xstat64.c
new file mode 100644
index 000000000..096aac813
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/xstat64.c
@@ -0,0 +1,97 @@
+/* xstat64 using old-style Unix stat system call.
+ Copyright (C) 1991,1995-2002,2003,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#if __ASSUME_STAT64_SYSCALL == 0
+# include <xstatconv.h>
+#endif
+
+#ifdef __NR_stat64
+# if __ASSUME_STAT64_SYSCALL == 0
+/* The variable is shared between all wrappers around *stat64 calls.
+ This is the definition. */
+int __have_no_stat64;
+# endif
+#endif
+
+/* Get information about the file NAME in BUF. */
+
+int
+___xstat64 (int vers, const char *name, struct stat64 *buf)
+{
+ int result;
+#if __ASSUME_STAT64_SYSCALL > 0
+ result = INLINE_SYSCALL (stat64, 2, CHECK_STRING (name), CHECK_1 (buf));
+# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+ if (__builtin_expect (!result, 1) && buf->__st_ino != (__ino_t) buf->st_ino)
+ buf->st_ino = buf->__st_ino;
+# endif
+ return result;
+#else
+ struct kernel_stat kbuf;
+# if defined __NR_stat64
+ if (! __have_no_stat64)
+ {
+ int saved_errno = errno;
+ result = INLINE_SYSCALL (stat64, 2, CHECK_STRING (name), CHECK_1 (buf));
+
+ if (result != -1 || errno != ENOSYS)
+ {
+# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+ if (!result && buf->__st_ino != (__ino_t) buf->st_ino)
+ buf->st_ino = buf->__st_ino;
+# endif
+ return result;
+ }
+
+ __set_errno (saved_errno);
+ __have_no_stat64 = 1;
+ }
+# endif
+
+ result = INLINE_SYSCALL (stat, 2, CHECK_STRING (name), __ptrvalue (&kbuf));
+ if (result == 0)
+ result = __xstat64_conv (vers, &kbuf, buf);
+
+ return result;
+#endif
+}
+
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+versioned_symbol (libc, ___xstat64, __xstat64, GLIBC_2_2);
+strong_alias (___xstat64, __old__xstat64)
+compat_symbol (libc, __old__xstat64, __xstat64, GLIBC_2_1);
+hidden_ver (___xstat64, __xstat64)
+#else
+strong_alias (___xstat64, __xstat64)
+hidden_def (__xstat64)
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/xstatconv.c b/libc/sysdeps/unix/sysv/linux/xstatconv.c
new file mode 100644
index 000000000..805e33978
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/xstatconv.c
@@ -0,0 +1,285 @@
+/* Convert between the kernel's `struct stat' format, and libc's.
+ Copyright (C) 1991,1995-1997,2000,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#ifdef STAT_IS_KERNEL_STAT
+
+/* Dummy. */
+struct kernel_stat;
+
+#else
+
+#include <string.h>
+
+
+#if !defined __ASSUME_STAT64_SYSCALL || defined XSTAT_IS_XSTAT64
+int
+__xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
+{
+ switch (vers)
+ {
+ case _STAT_VER_KERNEL:
+ /* Nothing to do. The struct is in the form the kernel expects.
+ We should have short-circuted before we got here, but for
+ completeness... */
+ *(struct kernel_stat *) ubuf = *kbuf;
+ break;
+
+ case _STAT_VER_LINUX:
+ {
+ struct stat *buf = ubuf;
+
+ /* Convert to current kernel version of `struct stat'. */
+ buf->st_dev = kbuf->st_dev;
+#ifdef _HAVE_STAT___PAD1
+ buf->__pad1 = 0;
+#endif
+ buf->st_ino = kbuf->st_ino;
+ buf->st_mode = kbuf->st_mode;
+ buf->st_nlink = kbuf->st_nlink;
+ buf->st_uid = kbuf->st_uid;
+ buf->st_gid = kbuf->st_gid;
+ buf->st_rdev = kbuf->st_rdev;
+#ifdef _HAVE_STAT___PAD2
+ buf->__pad2 = 0;
+#endif
+ buf->st_size = kbuf->st_size;
+ buf->st_blksize = kbuf->st_blksize;
+ buf->st_blocks = kbuf->st_blocks;
+#ifdef _HAVE_STAT_NSEC
+ buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
+ buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
+ buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
+ buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
+ buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
+ buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
+#else
+ buf->st_atime = kbuf->st_atime;
+ buf->st_mtime = kbuf->st_mtime;
+ buf->st_ctime = kbuf->st_ctime;
+#endif
+#ifdef _HAVE_STAT___UNUSED1
+ buf->__unused1 = 0;
+#endif
+#ifdef _HAVE_STAT___UNUSED2
+ buf->__unused2 = 0;
+#endif
+#ifdef _HAVE_STAT___UNUSED3
+ buf->__unused3 = 0;
+#endif
+#ifdef _HAVE_STAT___UNUSED4
+ buf->__unused4 = 0;
+#endif
+#ifdef _HAVE_STAT___UNUSED5
+ buf->__unused5 = 0;
+#endif
+ }
+ break;
+
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
+int
+__xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
+{
+#ifdef XSTAT_IS_XSTAT64
+ return __xstat_conv (vers, kbuf, ubuf);
+#else
+ switch (vers)
+ {
+ case _STAT_VER_LINUX:
+ {
+ struct stat64 *buf = ubuf;
+
+ /* Convert to current kernel version of `struct stat64'. */
+ buf->st_dev = kbuf->st_dev;
+#ifdef _HAVE_STAT64___PAD1
+ buf->__pad1 = 0;
+#endif
+ buf->st_ino = kbuf->st_ino;
+#ifdef _HAVE_STAT64___ST_INO
+ buf->__st_ino = kbuf->st_ino;
+#endif
+ buf->st_mode = kbuf->st_mode;
+ buf->st_nlink = kbuf->st_nlink;
+ buf->st_uid = kbuf->st_uid;
+ buf->st_gid = kbuf->st_gid;
+ buf->st_rdev = kbuf->st_rdev;
+#ifdef _HAVE_STAT64___PAD2
+ buf->__pad2 = 0;
+#endif
+ buf->st_size = kbuf->st_size;
+ buf->st_blksize = kbuf->st_blksize;
+ buf->st_blocks = kbuf->st_blocks;
+#ifdef _HAVE_STAT64_NSEC
+ buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
+ buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
+ buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
+ buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
+ buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
+ buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
+#else
+ buf->st_atime = kbuf->st_atime;
+ buf->st_mtime = kbuf->st_mtime;
+ buf->st_ctime = kbuf->st_ctime;
+#endif
+#ifdef _HAVE_STAT64___UNUSED1
+ buf->__unused1 = 0;
+#endif
+#ifdef _HAVE_STAT64___UNUSED2
+ buf->__unused2 = 0;
+#endif
+#ifdef _HAVE_STAT64___UNUSED3
+ buf->__unused3 = 0;
+#endif
+#ifdef _HAVE_STAT64___UNUSED4
+ buf->__unused4 = 0;
+#endif
+#ifdef _HAVE_STAT64___UNUSED5
+ buf->__unused5 = 0;
+#endif
+ }
+ break;
+
+ /* If struct stat64 is different from struct stat then
+ _STAT_VER_KERNEL does not make sense. */
+ case _STAT_VER_KERNEL:
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return 0;
+#endif
+}
+
+int
+__xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf)
+{
+ switch (vers)
+ {
+ case _STAT_VER_LINUX:
+ {
+ /* Convert current kernel version of `struct stat64' to
+ `struct stat'. */
+ buf->st_dev = kbuf->st_dev;
+#ifdef _HAVE_STAT___PAD1
+ buf->__pad1 = 0;
+#endif
+#ifdef _HAVE_STAT64___ST_INO
+# if __ASSUME_ST_INO_64_BIT == 0
+ if (kbuf->st_ino == 0)
+ buf->st_ino = kbuf->__st_ino;
+ else
+# endif
+ {
+ buf->st_ino = kbuf->st_ino;
+ if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino)
+ && buf->st_ino != kbuf->st_ino)
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+ }
+#else
+ buf->st_ino = kbuf->st_ino;
+ if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino)
+ && buf->st_ino != kbuf->st_ino)
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+#endif
+ buf->st_mode = kbuf->st_mode;
+ buf->st_nlink = kbuf->st_nlink;
+ buf->st_uid = kbuf->st_uid;
+ buf->st_gid = kbuf->st_gid;
+ buf->st_rdev = kbuf->st_rdev;
+#ifdef _HAVE_STAT___PAD2
+ buf->__pad2 = 0;
+#endif
+ buf->st_size = kbuf->st_size;
+ /* Check for overflow. */
+ if (sizeof (buf->st_size) != sizeof (kbuf->st_size)
+ && buf->st_size != kbuf->st_size)
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+ buf->st_blksize = kbuf->st_blksize;
+ buf->st_blocks = kbuf->st_blocks;
+ /* Check for overflow. */
+ if (sizeof (buf->st_blocks) != sizeof (kbuf->st_blocks)
+ && buf->st_blocks != kbuf->st_blocks)
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+#ifdef _HAVE_STAT_NSEC
+ buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
+ buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
+ buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
+ buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
+ buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
+ buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
+#else
+ buf->st_atime = kbuf->st_atime;
+ buf->st_mtime = kbuf->st_mtime;
+ buf->st_ctime = kbuf->st_ctime;
+#endif
+
+#ifdef _HAVE_STAT___UNUSED1
+ buf->__unused1 = 0;
+#endif
+#ifdef _HAVE_STAT___UNUSED2
+ buf->__unused2 = 0;
+#endif
+#ifdef _HAVE_STAT___UNUSED3
+ buf->__unused3 = 0;
+#endif
+#ifdef _HAVE_STAT___UNUSED4
+ buf->__unused4 = 0;
+#endif
+#ifdef _HAVE_STAT___UNUSED5
+ buf->__unused5 = 0;
+#endif
+ }
+ break;
+
+ /* If struct stat64 is different from struct stat then
+ _STAT_VER_KERNEL does not make sense. */
+ case _STAT_VER_KERNEL:
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/xstatconv.h b/libc/sysdeps/unix/sysv/linux/xstatconv.h
new file mode 100644
index 000000000..7e3662043
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/xstatconv.h
@@ -0,0 +1,27 @@
+/* Convert between the kernel's `struct stat' format, and libc's.
+ Copyright (C) 1991,1995-1997,2000,2002,2003,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <kernel-features.h>
+
+#ifndef STAT_IS_KERNEL_STAT
+extern int __xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf);
+extern int __xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf);
+#endif
+extern int __xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf);
diff --git a/libc/sysdeps/unix/sysv/setrlimit.c b/libc/sysdeps/unix/sysv/setrlimit.c
new file mode 100644
index 000000000..06e2efb18
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/setrlimit.c
@@ -0,0 +1,57 @@
+/* setrlimit function for systems with ulimit system call (SYSV).
+ Copyright (C) 1991, 1992, 1996, 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This only implements those functions which are available via ulimit. */
+
+#include <sys/resource.h>
+#include <stddef.h>
+#include <errno.h>
+
+/* Set the soft and hard limits for RESOURCE to *RLIMITS.
+ Only the super-user can increase hard limits.
+ Return 0 if successful, -1 if not (and sets errno). */
+int
+setrlimit (resource, rlimits)
+ enum __rlimit_resource resource;
+ const struct rlimit *rlimits;
+{
+ if (rlimits == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ switch (resource)
+ {
+ case RLIMIT_FSIZE:
+ return __ulimit (2, rlimits->rlim_cur);
+
+ case RLIMIT_DATA:
+ case RLIMIT_CPU:
+ case RLIMIT_STACK:
+ case RLIMIT_CORE:
+ case RLIMIT_RSS:
+ __set_errno (ENOSYS);
+ return -1;
+
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/settimeofday.c b/libc/sysdeps/unix/sysv/settimeofday.c
new file mode 100644
index 000000000..e2c4102ef
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/settimeofday.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1992, 1995, 1996, 1997, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+
+/* Set the current time of day and timezone information.
+ This call is restricted to the super-user. */
+int
+__settimeofday (tv, tz)
+ const struct timeval *tv;
+ const struct timezone *tz;
+{
+ time_t when;
+
+ if (tv == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (tz != NULL || tv->tv_usec % 1000000 != 0)
+ {
+ __set_errno (ENOSYS);
+ return -1;
+ }
+
+ when = tv->tv_sec + (tv->tv_usec / 1000000);
+ return stime (&when);
+}
+
+weak_alias (__settimeofday, settimeofday)
diff --git a/libc/sysdeps/unix/sysv/sigaction.c b/libc/sysdeps/unix/sysv/sigaction.c
new file mode 100644
index 000000000..e90b2a854
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/sigaction.c
@@ -0,0 +1,84 @@
+/* Copyright (C) 1992,1994,1995,1996,1997,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <errno.h>
+#include <stddef.h>
+#include <signal.h>
+
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+ If OACT is not NULL, put the old action for SIG in *OACT. */
+int
+__sigaction (sig, act, oact)
+ int sig;
+ const struct sigaction *act;
+ struct sigaction *oact;
+{
+ sighandler_t handler;
+ int save;
+
+ if (sig <= 0 || sig >= NSIG)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (act == NULL)
+ {
+ if (oact == NULL)
+ return 0;
+ /* Race condition, but this is the only way to do it. */
+ handler = signal (sig, SIG_IGN);
+ if (handler == SIG_ERR)
+ return -1;
+ save = errno;
+ (void) signal (sig, handler);
+ __set_errno (save);
+ }
+ else
+ {
+ int i;
+
+ if (act->sa_flags != 0)
+ {
+ unimplemented:
+ __set_errno (ENOSYS);
+ return -1;
+ }
+
+ for (i = 1; i < NSIG; ++i)
+ if (__sigismember (&act->sa_mask, i))
+ goto unimplemented;
+
+ handler = signal (sig, act->sa_handler);
+ if (handler == SIG_ERR)
+ return -1;
+ }
+
+ if (oact != NULL)
+ {
+ oact->sa_handler = handler;
+ __sigemptyset (&oact->sa_mask);
+ oact->sa_flags = 0;
+ }
+
+ return 0;
+}
+libc_hidden_def (__sigaction)
+weak_alias (__sigaction, sigaction)
diff --git a/libc/sysdeps/unix/sysv/syscalls.list b/libc/sysdeps/unix/sysv/syscalls.list
new file mode 100644
index 000000000..436d05eb9
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/syscalls.list
@@ -0,0 +1,16 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+alarm - alarm i:i alarm
+ftime - ftime i:p ftime
+nice - nice i:i nice
+pause - pause Ci: pause
+poll - poll Ci:pii poll
+s_getdents getdents getdents i:ipi __getdents
+setrlimit - setrlimit i:ip __setrlimit setrlimit
+settimeofday - settimeofday i:PP __settimeofday settimeofday
+signal - signal i:ii signal
+stime - stime i:p stime
+time - time Ei:P time
+times - times i:p __times times
+ulimit - ulimit i:ii ulimit
+utime - utime i:sP utime
diff --git a/libc/sysdeps/unix/sysv/sysv_termio.h b/libc/sysdeps/unix/sysv/sysv_termio.h
new file mode 100644
index 000000000..ebede410c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/sysv_termio.h
@@ -0,0 +1,155 @@
+/* Copyright (C) 1992, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* In various parts of this file we define the System V values for
+ things as _SYSV_<whatever>. Those are the values that System V
+ uses for termio, and also (SVR4) termios. Not necessarily the
+ same as the GNU termios that the library user sees. */
+
+/* Number of elements of c_cc. termio only. */
+#define _SYSV_NCC 8
+
+#define _SYSV_VINTR 0
+#define _SYSV_VQUIT 1
+#define _SYSV_VERASE 2
+#define _SYSV_VKILL 3
+#define _SYSV_VEOF 4
+/* This field means VEOF if ICANON, VMIN if not. */
+#define _SYSV_VMIN 4
+#define _SYSV_VEOL 5
+/* This field means VEOL if ICANON, VTIME if not. */
+#define _SYSV_VTIME 5
+#define _SYSV_VEOL2 6
+
+/* Flags in c_iflag. */
+#define _SYSV_IGNBRK 1
+#define _SYSV_BRKINT 2
+#define _SYSV_IGNPAR 4
+#define _SYSV_PARMRK 8
+#define _SYSV_INPCK 0x10
+#define _SYSV_ISTRIP 0x20
+#define _SYSV_INLCR 0x40
+#define _SYSV_IGNCR 0x80
+#define _SYSV_ICRNL 0x100
+#define _SYSV_IUCLC 0x200
+#define _SYSV_IXON 0x400
+#define _SYSV_IXANY 0x800
+#define _SYSV_IXOFF 0x1000
+#define _SYSV_IMAXBEL 0x2000
+
+/* Flags in c_cflag. */
+#define _SYSV_CBAUD 0xf
+#define _SYSV_CIBAUD 0xf0000 /* termios only. */
+#define _SYSV_IBSHIFT 16
+/* Values for CBAUD and CIBAUD. */
+#define _SYSV_B0 0
+#define _SYSV_B50 1
+#define _SYSV_B75 2
+#define _SYSV_B110 3
+#define _SYSV_B134 4
+#define _SYSV_B150 5
+#define _SYSV_B200 6
+#define _SYSV_B300 7
+#define _SYSV_B600 8
+#define _SYSV_B1200 9
+#define _SYSV_B1800 10
+#define _SYSV_B2400 11
+#define _SYSV_B4800 12
+#define _SYSV_B9600 13
+#define _SYSV_B19200 14
+#define _SYSV_B38400 15
+
+#define _SYSV_CS5 0
+#define _SYSV_CS6 0x10
+#define _SYSV_CS7 0x20
+#define _SYSV_CS8 0x30
+#define _SYSV_CSIZE 0x30
+#define _SYSV_CSTOPB 0x40
+#define _SYSV_CREAD 0x80
+#define _SYSV_PARENB 0x100
+#define _SYSV_PARODD 0x200
+#define _SYSV_HUPCL 0x400
+#define _SYSV_CLOCAL 0x800
+
+/* Flags in c_lflag. */
+#define _SYSV_ISIG 1
+#define _SYSV_ICANON 2
+#define _SYSV_ECHO 8
+#define _SYSV_ECHOE 0x10
+#define _SYSV_ECHOK 0x20
+#define _SYSV_ECHONL 0x40
+#define _SYSV_NOFLSH 0x80
+#define _SYSV_TOSTOP 0x100
+#define _SYSV_ECHOCTL 0x200
+#define _SYSV_ECHOPRT 0x400
+#define _SYSV_ECHOKE 0x800
+#define _SYSV_FLUSHO 0x2000
+#define _SYSV_PENDIN 0x4000
+#define _SYSV_IEXTEN 0x8000
+
+/* Flags in c_oflag. */
+#define _SYSV_OPOST 1
+#define _SYSV_OLCUC 2
+#define _SYSV_ONLCR 4
+#define _SYSV_NLDLY 0x100
+#define _SYSV_NL0 0
+#define _SYSV_NL1 0x100
+#define _SYSV_CRDLY 0x600
+#define _SYSV_CR0 0
+#define _SYSV_CR1 0x200
+#define _SYSV_CR2 0x400
+#define _SYSV_CR3 0x600
+#define _SYSV_TABDLY 0x1800
+#define _SYSV_TAB0 0
+#define _SYSV_TAB1 0x0800
+#define _SYSV_TAB2 0x1000
+/* TAB3 is an obsolete name for XTABS. But we provide it since some
+ programs expect it to exist. */
+#define _SYSV_TAB3 0x1800
+#define _SYSV_XTABS 0x1800
+#define _SYSV_BSDLY 0x2000
+#define _SYSV_BS0 0
+#define _SYSV_BS1 0x2000
+#define _SYSV_VTDLY 0x4000
+#define _SYSV_VT0 0
+#define _SYSV_VT1 0x4000
+#define _SYSV_FFDLY 0x8000
+#define _SYSV_FF0 0
+#define _SYSV_FF1 0x8000
+
+/* ioctl's. */
+
+#define _TCGETA 0x5401
+#define _TCSETA 0x5402
+#define _TCSETAW 0x5403
+#define _TCSETAF 0x5404
+#define _TCSBRK 0x5405
+#define _TCXONC 0x5406
+#define _TCFLSH 0x5407
+#define _TIOCGPGRP 0x7414
+#define _TIOCSPGRP 0x7415
+
+struct __sysv_termio
+ {
+ unsigned short c_iflag;
+ unsigned short c_oflag;
+ unsigned short c_cflag;
+ unsigned short c_lflag;
+ char c_line;
+ unsigned char c_cc[_SYSV_NCC];
+ };
diff --git a/libc/sysdeps/unix/sysv/tcdrain.c b/libc/sysdeps/unix/sysv/tcdrain.c
new file mode 100644
index 000000000..2f44fd156
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/tcdrain.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1992, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sysv_termio.h>
+#include <sys/ioctl.h>
+
+/* Wait for pending output to be written on FD. */
+int
+__libc_tcdrain (int fd)
+{
+ /* With an argument of 1, TCSBRK just waits for output to drain. */
+ return __ioctl (fd, _TCSBRK, 1);
+}
+weak_alias (__libc_tcdrain, tcdrain)
diff --git a/libc/sysdeps/unix/sysv/tcflow.c b/libc/sysdeps/unix/sysv/tcflow.c
new file mode 100644
index 000000000..dc67d0664
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/tcflow.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1992, 1996, 1997, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+#include <sysv_termio.h>
+
+/* Suspend or restart transmission on FD. */
+int
+tcflow (fd, action)
+ int fd;
+ int action;
+{
+ switch (action)
+ {
+ case TCOOFF:
+ return __ioctl (fd, _TCXONC, 0);
+ case TCOON:
+ return __ioctl (fd, _TCXONC, 1);
+ case TCIOFF:
+ return __ioctl (fd, _TCXONC, 2);
+ case TCION:
+ return __ioctl (fd, _TCXONC, 3);
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/tcflush.c b/libc/sysdeps/unix/sysv/tcflush.c
new file mode 100644
index 000000000..a98f13327
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/tcflush.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1992, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+#include <sysv_termio.h>
+
+/* Flush pending data on FD. */
+int
+tcflush (fd, queue_selector)
+ int fd;
+ int queue_selector;
+{
+ switch (queue_selector)
+ {
+ case TCIFLUSH:
+ return __ioctl (fd, _TCFLSH, 0);
+ case TCOFLUSH:
+ return __ioctl (fd, _TCFLSH, 1);
+ case TCIOFLUSH:
+ return __ioctl (fd, _TCFLSH, 2);
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+}
diff --git a/libc/sysdeps/unix/sysv/tcgetattr.c b/libc/sysdeps/unix/sysv/tcgetattr.c
new file mode 100644
index 000000000..8cc912300
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/tcgetattr.c
@@ -0,0 +1,171 @@
+/* Copyright (C) 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sysv_termio.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+/* Put the state of FD into *TERMIOS_P. */
+int
+__tcgetattr (fd, termios_p)
+ int fd;
+ struct termios *termios_p;
+{
+ struct __sysv_termio buf;
+ int termio_speed;
+
+ if (termios_p == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (__ioctl (fd, _TCGETA, &buf) < 0)
+ return -1;
+
+ termio_speed = buf.c_cflag & _SYSV_CBAUD;
+ termios_p->__ospeed =
+ (termio_speed == _SYSV_B0 ? 0 :
+ termio_speed == _SYSV_B50 ? 50 :
+ termio_speed == _SYSV_B75 ? 75 :
+ termio_speed == _SYSV_B110 ? 110 :
+ termio_speed == _SYSV_B134 ? 134 :
+ termio_speed == _SYSV_B150 ? 150 :
+ termio_speed == _SYSV_B200 ? 200 :
+ termio_speed == _SYSV_B300 ? 300 :
+ termio_speed == _SYSV_B600 ? 600 :
+ termio_speed == _SYSV_B1200 ? 1200 :
+ termio_speed == _SYSV_B1800 ? 1800 :
+ termio_speed == _SYSV_B2400 ? 2400 :
+ termio_speed == _SYSV_B4800 ? 4800 :
+ termio_speed == _SYSV_B9600 ? 9600 :
+ termio_speed == _SYSV_B19200 ? 19200 :
+ termio_speed == _SYSV_B38400 ? 38400 :
+ -1);
+ termios_p->__ispeed = termios_p->__ospeed;
+
+ termios_p->c_iflag = 0;
+ if (buf.c_iflag & _SYSV_IGNBRK)
+ termios_p->c_iflag |= IGNBRK;
+ if (buf.c_iflag & _SYSV_BRKINT)
+ termios_p->c_iflag |= BRKINT;
+ if (buf.c_iflag & _SYSV_IGNPAR)
+ termios_p->c_iflag |= IGNPAR;
+ if (buf.c_iflag & _SYSV_PARMRK)
+ termios_p->c_iflag |= PARMRK;
+ if (buf.c_iflag & _SYSV_INPCK)
+ termios_p->c_iflag |= INPCK;
+ if (buf.c_iflag & _SYSV_ISTRIP)
+ termios_p->c_iflag |= ISTRIP;
+ if (buf.c_iflag & _SYSV_INLCR)
+ termios_p->c_iflag |= INLCR;
+ if (buf.c_iflag & _SYSV_IGNCR)
+ termios_p->c_iflag |= IGNCR;
+ if (buf.c_iflag & _SYSV_ICRNL)
+ termios_p->c_iflag |= ICRNL;
+ if (buf.c_iflag & _SYSV_IXON)
+ termios_p->c_iflag |= IXON;
+ if (buf.c_iflag & _SYSV_IXOFF)
+ termios_p->c_iflag |= IXOFF;
+ if (buf.c_iflag & _SYSV_IXANY)
+ termios_p->c_iflag |= IXANY;
+ if (buf.c_iflag & _SYSV_IMAXBEL)
+ termios_p->c_iflag |= IMAXBEL;
+
+ termios_p->c_oflag = 0;
+ if (buf.c_oflag & OPOST)
+ termios_p->c_oflag |= OPOST;
+ if (buf.c_oflag & ONLCR)
+ termios_p->c_oflag |= ONLCR;
+ termios_p->c_cflag = 0;
+ switch (buf.c_cflag & _SYSV_CSIZE)
+ {
+ case _SYSV_CS5:
+ termios_p->c_cflag |= CS5;
+ break;
+ case _SYSV_CS6:
+ termios_p->c_cflag |= CS6;
+ break;
+ case _SYSV_CS7:
+ termios_p->c_cflag |= CS7;
+ break;
+ case _SYSV_CS8:
+ termios_p->c_cflag |= CS8;
+ break;
+ }
+ if (buf.c_cflag & _SYSV_CSTOPB)
+ termios_p->c_cflag |= CSTOPB;
+ if (buf.c_cflag & _SYSV_CREAD)
+ termios_p->c_cflag |= CREAD;
+ if (buf.c_cflag & _SYSV_PARENB)
+ termios_p->c_cflag |= PARENB;
+ if (buf.c_cflag & _SYSV_PARODD)
+ termios_p->c_cflag |= PARODD;
+ if (buf.c_cflag & _SYSV_HUPCL)
+ termios_p->c_cflag |= HUPCL;
+ if (buf.c_cflag & _SYSV_CLOCAL)
+ termios_p->c_cflag |= CLOCAL;
+ termios_p->c_lflag = 0;
+ if (buf.c_lflag & _SYSV_ISIG)
+ termios_p->c_lflag |= _ISIG;
+ if (buf.c_lflag & _SYSV_ICANON)
+ termios_p->c_lflag |= _ICANON;
+ if (buf.c_lflag & _SYSV_ECHO)
+ termios_p->c_lflag |= _ECHO;
+ if (buf.c_lflag & _SYSV_ECHOE)
+ termios_p->c_lflag |= _ECHOE;
+ if (buf.c_lflag & _SYSV_ECHOK)
+ termios_p->c_lflag |= _ECHOK;
+ if (buf.c_lflag & _SYSV_ECHONL)
+ termios_p->c_lflag |= _ECHONL;
+ if (buf.c_lflag & _SYSV_NOFLSH)
+ termios_p->c_lflag |= _NOFLSH;
+ if (buf.c_lflag & _SYSV_TOSTOP)
+ termios_p->c_lflag |= _TOSTOP;
+ if (buf.c_lflag & _SYSV_ECHOKE)
+ termios_p->c_lflag |= ECHOKE;
+ if (buf.c_lflag & _SYSV_ECHOPRT)
+ termios_p->c_lflag |= ECHOPRT;
+ if (buf.c_lflag & _SYSV_ECHOCTL)
+ termios_p->c_lflag |= ECHOCTL;
+ if (buf.c_lflag & _SYSV_FLUSHO)
+ termios_p->c_lflag |= FLUSHO;
+ if (buf.c_lflag & _SYSV_PENDIN)
+ termios_p->c_lflag |= PENDIN;
+ if (buf.c_lflag & _SYSV_IEXTEN)
+ termios_p->c_lflag |= IEXTEN;
+
+ termios_p->c_cc[VEOF] = buf.c_cc[_SYSV_VEOF];
+ termios_p->c_cc[VEOL] = buf.c_cc[_SYSV_VEOL];
+ termios_p->c_cc[VEOL2] = buf.c_cc[_SYSV_VEOL2];
+ termios_p->c_cc[VERASE] = buf.c_cc[_SYSV_VERASE];
+ termios_p->c_cc[VKILL] = buf.c_cc[_SYSV_VKILL];
+ termios_p->c_cc[VINTR] = buf.c_cc[_SYSV_VINTR];
+ termios_p->c_cc[VQUIT] = buf.c_cc[_SYSV_VQUIT];
+ termios_p->c_cc[VSTART] = '\021'; /* XON (^Q). */
+ termios_p->c_cc[VSTOP] = '\023'; /* XOFF (^S). */
+ termios_p->c_cc[VSUSP] = '\0'; /* System V release 3 lacks job control. */
+ termios_p->c_cc[VMIN] = buf.c_cc[_SYSV_VMIN];
+ termios_p->c_cc[VTIME] = buf.c_cc[_SYSV_VTIME];
+
+ return 0;
+}
+
+weak_alias (__tcgetattr, tcgetattr)
diff --git a/libc/sysdeps/unix/sysv/tcgetpgrp.c b/libc/sysdeps/unix/sysv/tcgetpgrp.c
new file mode 100644
index 000000000..4f64eac63
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/tcgetpgrp.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1992, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <termios.h>
+#include <sysv_termio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+/* Return the foreground process group ID of FD. */
+pid_t
+tcgetpgrp (fd)
+ int fd;
+{
+ int pgrp;
+ if (__ioctl (fd, _TIOCGPGRP, &pgrp) < 0)
+ return (pid_t) -1;
+ return (pid_t) pgrp;
+}
+libc_hidden_def (tcgetpgrp)
diff --git a/libc/sysdeps/unix/sysv/tcsendbrk.c b/libc/sysdeps/unix/sysv/tcsendbrk.c
new file mode 100644
index 000000000..f67e623e7
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/tcsendbrk.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1992, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <signal.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sysv_termio.h>
+#include <sys/ioctl.h>
+
+/* Send zero bits on FD. */
+int
+tcsendbreak (fd, duration)
+ int fd;
+ int duration;
+{
+ /* The break lasts 0.25 to 0.5 seconds if DURATION is zero,
+ and an implementation-defined period if DURATION is nonzero.
+ We define a positive DURATION to be number of milliseconds to break. */
+ if (duration <= 0)
+ return __ioctl (fd, _TCSBRK, 0);
+
+ /* ioctl can't send a break of any other duration for us.
+ This could be changed to use trickery (e.g. lower speed and
+ send a '\0') to send the break, but for now just return an error. */
+ __set_errno (EINVAL);
+ return -1;
+}
diff --git a/libc/sysdeps/unix/sysv/tcsetattr.c b/libc/sysdeps/unix/sysv/tcsetattr.c
new file mode 100644
index 000000000..d39ac76a3
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/tcsetattr.c
@@ -0,0 +1,210 @@
+/* Copyright (C) 1992, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+#include <sysv_termio.h>
+
+
+const speed_t __unix_speeds[] =
+ {
+ 0,
+ 50,
+ 75,
+ 110,
+ 134,
+ 150,
+ 200,
+ 300,
+ 600,
+ 1200,
+ 1800,
+ 2400,
+ 4800,
+ 9600,
+ 19200,
+ 38400,
+ };
+
+
+/* Set the state of FD to *TERMIOS_P. */
+int
+tcsetattr (fd, optional_actions, termios_p)
+ int fd;
+ int optional_actions;
+ const struct termios *termios_p;
+{
+ struct __sysv_termio buf;
+ int ioctl_function;
+ size_t i;
+
+ if (termios_p == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ switch (optional_actions)
+ {
+ case TCSANOW:
+ ioctl_function = _TCSETA;
+ break;
+ case TCSADRAIN:
+ ioctl_function = _TCSETAW;
+ break;
+ case TCSAFLUSH:
+ ioctl_function = _TCSETAF;
+ break;
+ default:
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (termios_p->__ispeed != termios_p->__ospeed)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+ buf.c_cflag = -1;
+ for (i = 0; i <= sizeof (__unix_speeds) / sizeof (__unix_speeds[0]); ++i)
+ {
+ if (__unix_speeds[i] == termios_p->__ispeed)
+ buf.c_cflag = i;
+ }
+ if (buf.c_cflag == -1)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ buf.c_iflag = 0;
+ if (termios_p->c_iflag & IGNBRK)
+ buf.c_iflag |= _SYSV_IGNBRK;
+ if (termios_p->c_iflag & BRKINT)
+ buf.c_iflag |= _SYSV_BRKINT;
+ if (termios_p->c_iflag & IGNPAR)
+ buf.c_iflag |= _SYSV_IGNPAR;
+ if (termios_p->c_iflag & PARMRK)
+ buf.c_iflag |= _SYSV_PARMRK;
+ if (termios_p->c_iflag & INPCK)
+ buf.c_iflag |= _SYSV_INPCK;
+ if (termios_p->c_iflag & ISTRIP)
+ buf.c_iflag |= _SYSV_ISTRIP;
+ if (termios_p->c_iflag & INLCR)
+ buf.c_iflag |= _SYSV_INLCR;
+ if (termios_p->c_iflag & IGNCR)
+ buf.c_iflag |= _SYSV_IGNCR;
+ if (termios_p->c_iflag & ICRNL)
+ buf.c_iflag |= _SYSV_ICRNL;
+ if (termios_p->c_iflag & IXON)
+ buf.c_iflag |= _SYSV_IXON;
+ if (termios_p->c_iflag & IXOFF)
+ buf.c_iflag |= _SYSV_IXOFF;
+ if (termios_p->c_iflag & IXANY)
+ buf.c_iflag |= _SYSV_IXANY;
+ if (termios_p->c_iflag & IMAXBEL)
+ buf.c_iflag |= _SYSV_IMAXBEL;
+
+ buf.c_oflag = 0;
+ if (termios_p->c_oflag & OPOST)
+ buf.c_oflag |= _SYSV_OPOST;
+ if (termios_p->c_oflag & ONLCR)
+ buf.c_oflag |= _SYSV_ONLCR;
+
+ /* So far, buf.c_cflag contains the speed in CBAUD. */
+ if (termios_p->c_cflag & CSTOPB)
+ buf.c_cflag |= _SYSV_CSTOPB;
+ if (termios_p->c_cflag & CREAD)
+ buf.c_cflag |= _SYSV_CREAD;
+ if (termios_p->c_cflag & PARENB)
+ buf.c_cflag |= _SYSV_PARENB;
+ if (termios_p->c_cflag & PARODD)
+ buf.c_cflag |= _SYSV_PARODD;
+ if (termios_p->c_cflag & HUPCL)
+ buf.c_cflag |= _SYSV_HUPCL;
+ if (termios_p->c_cflag & CLOCAL)
+ buf.c_cflag |= _SYSV_CLOCAL;
+ switch (termios_p->c_cflag & CSIZE)
+ {
+ case CS5:
+ buf.c_cflag |= _SYSV_CS5;
+ break;
+ case CS6:
+ buf.c_cflag |= _SYSV_CS6;
+ break;
+ case CS7:
+ buf.c_cflag |= _SYSV_CS7;
+ break;
+ case CS8:
+ buf.c_cflag |= _SYSV_CS8;
+ break;
+ }
+
+ buf.c_lflag = 0;
+ if (termios_p->c_lflag & ISIG)
+ buf.c_lflag |= _SYSV_ISIG;
+ if (termios_p->c_lflag & ICANON)
+ buf.c_lflag |= _SYSV_ICANON;
+ if (termios_p->c_lflag & ECHO)
+ buf.c_lflag |= _SYSV_ECHO;
+ if (termios_p->c_lflag & ECHOE)
+ buf.c_lflag |= _SYSV_ECHOE;
+ if (termios_p->c_lflag & ECHOK)
+ buf.c_lflag |= _SYSV_ECHOK;
+ if (termios_p->c_lflag & ECHONL)
+ buf.c_lflag |= _SYSV_ECHONL;
+ if (termios_p->c_lflag & NOFLSH)
+ buf.c_lflag |= _SYSV_NOFLSH;
+ if (termios_p->c_lflag & TOSTOP)
+ buf.c_lflag |= _SYSV_TOSTOP;
+ if (termios_p->c_lflag & ECHOCTL)
+ buf.c_lflag |= _SYSV_ECHOCTL;
+ if (termios_p->c_lflag & ECHOPRT)
+ buf.c_lflag |= _SYSV_ECHOPRT;
+ if (termios_p->c_lflag & ECHOKE)
+ buf.c_lflag |= _SYSV_ECHOKE;
+ if (termios_p->c_lflag & FLUSHO)
+ buf.c_lflag |= _SYSV_FLUSHO;
+ if (termios_p->c_lflag & PENDIN)
+ buf.c_lflag |= _SYSV_PENDIN;
+ if (termios_p->c_lflag & IEXTEN)
+ buf.c_lflag |= _SYSV_IEXTEN;
+
+ buf.c_cc[_SYSV_VINTR] = termios_p->c_cc[VINTR];
+ buf.c_cc[_SYSV_VQUIT] = termios_p->c_cc[VQUIT];
+ buf.c_cc[_SYSV_VERASE] = termios_p->c_cc[VERASE];
+ buf.c_cc[_SYSV_VKILL] = termios_p->c_cc[VKILL];
+ if (buf.c_lflag & _SYSV_ICANON)
+ {
+ buf.c_cc[_SYSV_VEOF] = termios_p->c_cc[VEOF];
+ buf.c_cc[_SYSV_VEOL] = termios_p->c_cc[VEOL];
+ }
+ else
+ {
+ buf.c_cc[_SYSV_VMIN] = termios_p->c_cc[VMIN];
+ buf.c_cc[_SYSV_VTIME] = termios_p->c_cc[VTIME];
+ }
+ buf.c_cc[_SYSV_VEOL2] = termios_p->c_cc[VEOL2];
+
+ if (__ioctl (fd, ioctl_function, &buf) < 0)
+ return -1;
+ return 0;
+}
+libc_hidden_def (tcsetattr)
diff --git a/libc/sysdeps/unix/sysv/tcsetpgrp.c b/libc/sysdeps/unix/sysv/tcsetpgrp.c
new file mode 100644
index 000000000..5bcaee76f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/tcsetpgrp.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1992, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <sysv_termio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+/* Set the foreground process group ID of FD set PGRP_ID. */
+int
+tcsetpgrp (fd, pgrp_id)
+ int fd;
+ pid_t pgrp_id;
+{
+ return __ioctl (fd, _TIOCSPGRP, &pgrp_id);
+}
diff --git a/libc/sysdeps/unix/telldir.c b/libc/sysdeps/unix/telldir.c
new file mode 100644
index 000000000..cb9efcfa3
--- /dev/null
+++ b/libc/sysdeps/unix/telldir.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dirent.h>
+
+#include <dirstream.h>
+
+/* Return the current position of DIRP. */
+long int
+telldir (DIR *dirp)
+{
+ return dirp->filepos;
+}
diff --git a/libc/sysdeps/unix/time.c b/libc/sysdeps/unix/time.c
new file mode 100644
index 000000000..f31ee9634
--- /dev/null
+++ b/libc/sysdeps/unix/time.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991,92,97,2001,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stddef.h> /* For NULL. */
+#include <time.h>
+#include <sys/time.h>
+
+
+/* Return the current time as a `time_t' and also put it in *T if T is
+ not NULL. Time is represented as seconds from Jan 1 00:00:00 1970. */
+time_t
+time (t)
+ time_t *t;
+{
+ struct timeval tv;
+ time_t result;
+
+ if (__gettimeofday (&tv, (struct timezone *) NULL))
+ result = (time_t) -1;
+ else
+ result = (time_t) tv.tv_sec;
+
+ if (t != NULL)
+ *t = result;
+ return result;
+}
+libc_hidden_def (time)
diff --git a/libc/sysdeps/unix/utime.c b/libc/sysdeps/unix/utime.c
new file mode 100644
index 000000000..4a1815b2c
--- /dev/null
+++ b/libc/sysdeps/unix/utime.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 1991,94,97,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <errno.h>
+#include <utime.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+
+/* Set the access and modification times of FILE to those given in TIMES.
+ If TIMES is NULL, set them to the current time. */
+int
+utime (file, times)
+ const char *file;
+ const struct utimbuf *times;
+{
+ struct timeval timevals[2];
+ struct timeval *tvp;
+
+ if (times != NULL)
+ {
+ timevals[0].tv_sec = (time_t) times->actime;
+ timevals[0].tv_usec = 0L;
+ timevals[1].tv_sec = (time_t) times->modtime;
+ timevals[1].tv_usec = 0L;
+ tvp = timevals;
+ }
+ else
+ tvp = NULL;
+
+ return __utimes (file, tvp);
+}
+libc_hidden_def (utime)
diff --git a/libc/sysdeps/unix/x86_64/sysdep.S b/libc/sysdeps/unix/x86_64/sysdep.S
new file mode 100644
index 000000000..aca81fef2
--- /dev/null
+++ b/libc/sysdeps/unix/x86_64/sysdep.S
@@ -0,0 +1,90 @@
+/* Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H
+#include <bits/errno.h>
+#include <bp-asm.h>
+#include <bp-sym.h>
+#include <tls.h>
+
+#ifdef IS_IN_rtld
+# include <dl-sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */
+#endif
+
+.globl C_SYMBOL_NAME(errno)
+.globl syscall_error
+
+#undef syscall_error
+#ifdef NO_UNDERSCORES
+__syscall_error:
+#else
+syscall_error:
+#endif
+#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN
+ /* We translate the system's EWOULDBLOCK error into EAGAIN.
+ The GNU C library always defines EWOULDBLOCK==EAGAIN.
+ EWOULDBLOCK_sys is the original number. */
+ cmpq $EWOULDBLOCK_sys, %rax /* Is it the old EWOULDBLOCK? */
+ jne notb /* Branch if not. */
+ movl $EAGAIN, %eax /* Yes; translate it to EAGAIN. */
+notb:
+#endif
+#if USE___THREAD
+# ifdef PIC
+ movq C_SYMBOL_NAME(errno@GOTTPOFF)(%rip), %rcx
+ movl %eax, %fs:0(%rcx)
+# else
+ movl %eax, %fs:C_SYMBOL_NAME(errno@TPOFF)
+# endif
+#elif !defined PIC
+# ifndef _LIBC_REENTRANT
+ movl %eax, C_SYMBOL_NAME(errno)
+# else
+ pushq %rax
+ cfi_adjust_cfa_offset(8)
+ PUSH_ERRNO_LOCATION_RETURN
+ call BP_SYM (__errno_location)
+ POP_ERRNO_LOCATION_RETURN
+ popq %rcx
+ cfi_adjust_cfa_offset(-8)
+ movl %ecx, (%rax)
+# endif
+#else
+# if RTLD_PRIVATE_ERRNO
+ leaq rtld_errno(%rip), %rcx
+ movl %eax, (%rcx)
+# elif !defined _LIBC_REENTRANT
+ movq C_SYMBOL_NAME(errno)@GOTPCREL(%rip), %rcx
+ movl %eax, (%rcx)
+# else
+ pushq %rax
+ cfi_adjust_cfa_offset(8)
+ PUSH_ERRNO_LOCATION_RETURN
+ call C_SYMBOL_NAME (BP_SYM (__errno_location)@PLT)
+ POP_ERRNO_LOCATION_RETURN
+ popq %rcx
+ cfi_adjust_cfa_offset(-8)
+ movl %ecx, (%rax)
+# endif
+#endif
+ movq $-1, %rax
+ ret
+
+#undef __syscall_error
+END (__syscall_error)
diff --git a/libc/sysdeps/unix/x86_64/sysdep.h b/libc/sysdeps/unix/x86_64/sysdep.h
new file mode 100644
index 000000000..95e456c17
--- /dev/null
+++ b/libc/sysdeps/unix/x86_64/sysdep.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 92, 93, 95, 96, 97, 2000, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/unix/sysdep.h>
+#include <sysdeps/x86_64/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+/* This is defined as a separate macro so that other sysdep.h files
+ can include this one and then redefine DO_CALL. */
+
+#define DO_CALL(syscall_name, args) \
+ lea SYS_ify (syscall_name), %rax; \
+ syscall
+
+#define r0 %rax /* Normal return-value register. */
+#define r1 %rbx /* Secondary return-value register. */
+#define MOVE(x,y) movq x, y
+
+#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/unix/xmknod.c b/libc/sysdeps/unix/xmknod.c
new file mode 100644
index 000000000..92f420f72
--- /dev/null
+++ b/libc/sysdeps/unix/xmknod.c
@@ -0,0 +1,42 @@
+/* xmknod call using old-style Unix mknod system call.
+ Copyright (C) 1991,1993,1995,1996,1997,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+extern int __syscall_mknod (const char *, mode_t, dev_t);
+
+/* Create a device file named PATH, with permission and special bits MODE
+ and device number DEV (which can be constructed from major and minor
+ device numbers with the `makedev' macro above). */
+int
+__xmknod (int vers, const char *path, mode_t mode, dev_t *dev)
+{
+ if (vers != _MKNOD_VER)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return __syscall_mknod (path, mode, *dev);
+}
+
+weak_alias (__xmknod, _xmknod)
+libc_hidden_def (__xmknod)
diff --git a/libc/sysdeps/unix/xstat.c b/libc/sysdeps/unix/xstat.c
new file mode 100644
index 000000000..f54c3d4df
--- /dev/null
+++ b/libc/sysdeps/unix/xstat.c
@@ -0,0 +1,39 @@
+/* xstat using old-style Unix stat system call.
+ Copyright (C) 1991,1995,1996,1997,2000,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <bp-checks.h>
+
+extern int __syscall_stat (const char *__unbounded, struct stat *__unbounded);
+
+int
+__xstat (int vers, const char *file, struct stat *buf)
+{
+ if (vers != _STAT_VER)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return __syscall_stat (CHECK_STRING (file), CHECK_1 (buf));
+}
+hidden_def (__xstat)
+weak_alias (__xstat, _xstat)
diff --git a/libc/sysdeps/wordsize-32/Makefile b/libc/sysdeps/wordsize-32/Makefile
new file mode 100644
index 000000000..82beac44e
--- /dev/null
+++ b/libc/sysdeps/wordsize-32/Makefile
@@ -0,0 +1,7 @@
+ifeq ($(subdir),csu)
+ifeq (yes,$(build-shared))
+sysdep_routines += divdi3
+shared-only-routines += divdi3
+CPPFLAGS-divdi3.c = -Din_divdi3_c
+endif
+endif
diff --git a/libc/sysdeps/wordsize-32/Versions b/libc/sysdeps/wordsize-32/Versions
new file mode 100644
index 000000000..e95029006
--- /dev/null
+++ b/libc/sysdeps/wordsize-32/Versions
@@ -0,0 +1,7 @@
+libc {
+ GLIBC_2.3 {
+ # These were erroneously omitted for 64-bit platforms in 2.3
+ # and so we don't put them in locale/Versions.
+ strtoll_l; strtoull_l;
+ }
+}
diff --git a/libc/sysdeps/wordsize-32/bits/wordsize.h b/libc/sysdeps/wordsize-32/bits/wordsize.h
new file mode 100644
index 000000000..ba643b60a
--- /dev/null
+++ b/libc/sysdeps/wordsize-32/bits/wordsize.h
@@ -0,0 +1,19 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __WORDSIZE 32
diff --git a/libc/sysdeps/wordsize-32/divdi3.c b/libc/sysdeps/wordsize-32/divdi3.c
new file mode 100644
index 000000000..8fa634384
--- /dev/null
+++ b/libc/sysdeps/wordsize-32/divdi3.c
@@ -0,0 +1,344 @@
+/* 64-bit multiplication and division
+ Copyright (C) 1989, 1992-1999,2000,2001,2002,2003,2004,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <endian.h>
+#include <stdlib.h>
+#include <bits/wordsize.h>
+
+#if __WORDSIZE != 32
+#error This is for 32-bit targets only
+#endif
+
+typedef unsigned int UQItype __attribute__ ((mode (QI)));
+typedef int SItype __attribute__ ((mode (SI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef int DItype __attribute__ ((mode (DI)));
+typedef unsigned int UDItype __attribute__ ((mode (DI)));
+#define Wtype SItype
+#define HWtype SItype
+#define DWtype DItype
+#define UWtype USItype
+#define UHWtype USItype
+#define UDWtype UDItype
+#define W_TYPE_SIZE 32
+
+#include <stdlib/longlong.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+struct DWstruct { Wtype high, low;};
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+struct DWstruct { Wtype low, high;};
+#else
+#error Unhandled endianity
+#endif
+typedef union { struct DWstruct s; DWtype ll; } DWunion;
+
+/* Prototypes of exported functions. */
+extern DWtype __divdi3 (DWtype u, DWtype v);
+extern DWtype __moddi3 (DWtype u, DWtype v);
+extern UDWtype __udivdi3 (UDWtype u, UDWtype v);
+extern UDWtype __umoddi3 (UDWtype u, UDWtype v);
+
+static UDWtype
+__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
+{
+ DWunion ww;
+ DWunion nn, dd;
+ DWunion rr;
+ UWtype d0, d1, n0, n1, n2;
+ UWtype q0, q1;
+ UWtype b, bm;
+
+ nn.ll = n;
+ dd.ll = d;
+
+ d0 = dd.s.low;
+ d1 = dd.s.high;
+ n0 = nn.s.low;
+ n1 = nn.s.high;
+
+#if !UDIV_NEEDS_NORMALIZATION
+ if (d1 == 0)
+ {
+ if (d0 > n1)
+ {
+ /* 0q = nn / 0D */
+
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+ q1 = 0;
+
+ /* Remainder in n0. */
+ }
+ else
+ {
+ /* qq = NN / 0d */
+
+ if (d0 == 0)
+ d0 = 1 / d0; /* Divide intentionally by zero. */
+
+ udiv_qrnnd (q1, n1, 0, n1, d0);
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+
+ /* Remainder in n0. */
+ }
+
+ if (rp != 0)
+ {
+ rr.s.low = n0;
+ rr.s.high = 0;
+ *rp = rr.ll;
+ }
+ }
+
+#else /* UDIV_NEEDS_NORMALIZATION */
+
+ if (d1 == 0)
+ {
+ if (d0 > n1)
+ {
+ /* 0q = nn / 0D */
+
+ count_leading_zeros (bm, d0);
+
+ if (bm != 0)
+ {
+ /* Normalize, i.e. make the most significant bit of the
+ denominator set. */
+
+ d0 = d0 << bm;
+ n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
+ n0 = n0 << bm;
+ }
+
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+ q1 = 0;
+
+ /* Remainder in n0 >> bm. */
+ }
+ else
+ {
+ /* qq = NN / 0d */
+
+ if (d0 == 0)
+ d0 = 1 / d0; /* Divide intentionally by zero. */
+
+ count_leading_zeros (bm, d0);
+
+ if (bm == 0)
+ {
+ /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+ conclude (the most significant bit of n1 is set) /\ (the
+ leading quotient digit q1 = 1).
+
+ This special case is necessary, not an optimization.
+ (Shifts counts of W_TYPE_SIZE are undefined.) */
+
+ n1 -= d0;
+ q1 = 1;
+ }
+ else
+ {
+ /* Normalize. */
+
+ b = W_TYPE_SIZE - bm;
+
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd (q1, n1, n2, n1, d0);
+ }
+
+ /* n1 != d0... */
+
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+
+ /* Remainder in n0 >> bm. */
+ }
+
+ if (rp != 0)
+ {
+ rr.s.low = n0 >> bm;
+ rr.s.high = 0;
+ *rp = rr.ll;
+ }
+ }
+#endif /* UDIV_NEEDS_NORMALIZATION */
+
+ else
+ {
+ if (d1 > n1)
+ {
+ /* 00 = nn / DD */
+
+ q0 = 0;
+ q1 = 0;
+
+ /* Remainder in n1n0. */
+ if (rp != 0)
+ {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ }
+ else
+ {
+ /* 0q = NN / dd */
+
+ count_leading_zeros (bm, d1);
+ if (bm == 0)
+ {
+ /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+ conclude (the most significant bit of n1 is set) /\ (the
+ quotient digit q0 = 0 or 1).
+
+ This special case is necessary, not an optimization. */
+
+ /* The condition on the next line takes advantage of that
+ n1 >= d1 (true due to program flow). */
+ if (n1 > d1 || n0 >= d0)
+ {
+ q0 = 1;
+ sub_ddmmss (n1, n0, n1, n0, d1, d0);
+ }
+ else
+ q0 = 0;
+
+ q1 = 0;
+
+ if (rp != 0)
+ {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ }
+ else
+ {
+ UWtype m1, m0;
+ /* Normalize. */
+
+ b = W_TYPE_SIZE - bm;
+
+ d1 = (d1 << bm) | (d0 >> b);
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd (q0, n1, n2, n1, d1);
+ umul_ppmm (m1, m0, q0, d0);
+
+ if (m1 > n1 || (m1 == n1 && m0 > n0))
+ {
+ q0--;
+ sub_ddmmss (m1, m0, m1, m0, d1, d0);
+ }
+
+ q1 = 0;
+
+ /* Remainder in (n1n0 - m1m0) >> bm. */
+ if (rp != 0)
+ {
+ sub_ddmmss (n1, n0, n1, n0, m1, m0);
+ rr.s.low = (n1 << b) | (n0 >> bm);
+ rr.s.high = n1 >> bm;
+ *rp = rr.ll;
+ }
+ }
+ }
+ }
+
+ ww.s.low = q0;
+ ww.s.high = q1;
+ return ww.ll;
+}
+
+DWtype
+__divdi3 (DWtype u, DWtype v)
+{
+ Wtype c = 0;
+ DWtype w;
+
+ if (u < 0)
+ {
+ c = ~c;
+ u = -u;
+ }
+ if (v < 0)
+ {
+ c = ~c;
+ v = -v;
+ }
+ w = __udivmoddi4 (u, v, NULL);
+ if (c)
+ w = -w;
+ return w;
+}
+strong_alias (__divdi3, __divdi3_internal)
+
+DWtype
+__moddi3 (DWtype u, DWtype v)
+{
+ Wtype c = 0;
+ DWtype w;
+
+ if (u < 0)
+ {
+ c = ~c;
+ u = -u;
+ }
+ if (v < 0)
+ v = -v;
+ __udivmoddi4 (u, v, (UDWtype *) &w);
+ if (c)
+ w = -w;
+ return w;
+}
+strong_alias (__moddi3, __moddi3_internal)
+
+UDWtype
+__udivdi3 (UDWtype u, UDWtype v)
+{
+ return __udivmoddi4 (u, v, NULL);
+}
+strong_alias (__udivdi3, __udivdi3_internal)
+
+UDWtype
+__umoddi3 (UDWtype u, UDWtype v)
+{
+ UDWtype w;
+
+ __udivmoddi4 (u, v, &w);
+ return w;
+}
+strong_alias (__umoddi3, __umoddi3_internal)
+
+/* We declare these with compat_symbol so that they are not visible at
+ link time. Programs must use the functions from libgcc. */
+#if defined HAVE_ELF && defined SHARED && defined DO_VERSIONING
+# include <shlib-compat.h>
+compat_symbol (libc, __divdi3, __divdi3, GLIBC_2_0);
+compat_symbol (libc, __moddi3, __moddi3, GLIBC_2_0);
+compat_symbol (libc, __udivdi3, __udivdi3, GLIBC_2_0);
+compat_symbol (libc, __umoddi3, __umoddi3, GLIBC_2_0);
+#endif
diff --git a/libc/sysdeps/wordsize-32/llabs.c b/libc/sysdeps/wordsize-32/llabs.c
new file mode 100644
index 000000000..04a93f4ea
--- /dev/null
+++ b/libc/sysdeps/wordsize-32/llabs.c
@@ -0,0 +1,23 @@
+/* Copyright (C) 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <inttypes.h>
+
+#include <stdlib/llabs.c>
+
+weak_alias (llabs, imaxabs)
diff --git a/libc/sysdeps/wordsize-32/lldiv.c b/libc/sysdeps/wordsize-32/lldiv.c
new file mode 100644
index 000000000..1d543ba0f
--- /dev/null
+++ b/libc/sysdeps/wordsize-32/lldiv.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1999, 2000, 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ugly trick ahead to make the alias work. */
+#define imaxdiv __libc_imaxdiv
+
+#include <inttypes.h>
+
+#include <stdlib/lldiv.c>
+
+#undef imaxdiv
+weak_alias (lldiv, imaxdiv)
diff --git a/libc/sysdeps/wordsize-32/strtoimax.c b/libc/sysdeps/wordsize-32/strtoimax.c
new file mode 100644
index 000000000..97c9b5f7a
--- /dev/null
+++ b/libc/sysdeps/wordsize-32/strtoimax.c
@@ -0,0 +1,28 @@
+/* Convert string to maximal integer.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+intmax_t
+strtoimax (const char *__restrict nptr, char **__restrict endptr, int base)
+{
+ return __strtoll_internal (nptr, endptr, base, 0);
+}
diff --git a/libc/sysdeps/wordsize-32/strtoumax.c b/libc/sysdeps/wordsize-32/strtoumax.c
new file mode 100644
index 000000000..f3d08a491
--- /dev/null
+++ b/libc/sysdeps/wordsize-32/strtoumax.c
@@ -0,0 +1,28 @@
+/* Convert string to maximal unsigned integer.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+uintmax_t
+strtoumax (const char *__restrict nptr, char **__restrict endptr, int base)
+{
+ return __strtoull_internal (nptr, endptr, base, 0);
+}
diff --git a/libc/sysdeps/wordsize-32/symbol-hacks.h b/libc/sysdeps/wordsize-32/symbol-hacks.h
new file mode 100644
index 000000000..c167cb947
--- /dev/null
+++ b/libc/sysdeps/wordsize-32/symbol-hacks.h
@@ -0,0 +1,30 @@
+/* Hacks needed for symbol manipulation.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* A very dirty trick: gcc emits references to __divdi3, __udivdi3,
+ __moddi3, and __umoddi3. These functions are exported and
+ therefore we get PLTs. Unnecessarily so. Changing gcc is a big
+ task which might not be worth it so we play tricks with the
+ assembler. */
+#if !defined __ASSEMBLER__ && !defined in_divdi3_c && !defined NOT_IN_libc && defined SHARED
+asm ("__divdi3 = __divdi3_internal");
+asm ("__udivdi3 = __udivdi3_internal");
+asm ("__moddi3 = __moddi3_internal");
+asm ("__umoddi3 = __umoddi3_internal");
+#endif
diff --git a/libc/sysdeps/wordsize-32/wcstoimax.c b/libc/sysdeps/wordsize-32/wcstoimax.c
new file mode 100644
index 000000000..750769a17
--- /dev/null
+++ b/libc/sysdeps/wordsize-32/wcstoimax.c
@@ -0,0 +1,29 @@
+/* Convert wide-character string to maximal integer.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <inttypes.h>
+#include <wchar.h>
+
+intmax_t
+wcstoimax (const wchar_t *__restrict nptr, wchar_t **__restrict endptr,
+ int base)
+{
+ return __wcstoll_internal (nptr, endptr, base, 0);
+}
diff --git a/libc/sysdeps/wordsize-32/wcstoumax.c b/libc/sysdeps/wordsize-32/wcstoumax.c
new file mode 100644
index 000000000..6def28b20
--- /dev/null
+++ b/libc/sysdeps/wordsize-32/wcstoumax.c
@@ -0,0 +1,29 @@
+/* Convert wide-character string to maximal unsigned integer.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <inttypes.h>
+#include <wchar.h>
+
+uintmax_t
+wcstoumax (const wchar_t *__restrict nptr, wchar_t **__restrict endptr,
+ int base)
+{
+ return __wcstoull_internal (nptr, endptr, base, 0);
+}
diff --git a/libc/sysdeps/wordsize-64/Versions b/libc/sysdeps/wordsize-64/Versions
new file mode 100644
index 000000000..0d13186ac
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/Versions
@@ -0,0 +1,6 @@
+libc {
+ GLIBC_2.3.3 {
+ # These were erroneously omitted for 64-bit platforms in 2.3.
+ strtoll_l; strtoull_l;
+ }
+}
diff --git a/libc/sysdeps/wordsize-64/bits/wordsize.h b/libc/sysdeps/wordsize-64/bits/wordsize.h
new file mode 100644
index 000000000..dd698fa97
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/bits/wordsize.h
@@ -0,0 +1,19 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __WORDSIZE 64
diff --git a/libc/sysdeps/wordsize-64/glob.c b/libc/sysdeps/wordsize-64/glob.c
new file mode 100644
index 000000000..082faf1c7
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/glob.c
@@ -0,0 +1,8 @@
+#define glob64 __no_glob64_decl
+#define globfree64 __no_globfree64_decl
+#include <posix/glob.c>
+#undef glob64
+#undef globfree64
+weak_alias (glob, glob64)
+weak_alias (globfree, globfree64)
+libc_hidden_ver (globfree, globfree64)
diff --git a/libc/sysdeps/wordsize-64/labs.c b/libc/sysdeps/wordsize-64/labs.c
new file mode 100644
index 000000000..5162ec5b1
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/labs.c
@@ -0,0 +1,23 @@
+/* Copyright (C) 1999, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <inttypes.h>
+
+#include <stdlib/labs.c>
+
+weak_alias (labs, imaxabs)
diff --git a/libc/sysdeps/wordsize-64/ldiv.c b/libc/sysdeps/wordsize-64/ldiv.c
new file mode 100644
index 000000000..e4681a3b8
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/ldiv.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1999, 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Ugly trick ahead to make the alias work. */
+#define imaxdiv __libc_imaxdiv
+
+#include <inttypes.h>
+
+#include <stdlib/ldiv.c>
+
+#undef imaxdiv
+weak_alias (ldiv, imaxdiv)
diff --git a/libc/sysdeps/wordsize-64/strtoimax.c b/libc/sysdeps/wordsize-64/strtoimax.c
new file mode 100644
index 000000000..39edd6e92
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/strtoimax.c
@@ -0,0 +1,28 @@
+/* Convert string to maximal integer.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+intmax_t
+strtoimax (const char *__restrict nptr, char **__restrict endptr, int base)
+{
+ return __strtol_internal (nptr, endptr, base, 0);
+}
diff --git a/libc/sysdeps/wordsize-64/strtol.c b/libc/sysdeps/wordsize-64/strtol.c
new file mode 100644
index 000000000..2e1b22934
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/strtol.c
@@ -0,0 +1,14 @@
+/* We have to irritate the compiler a bit. */
+#define __strtoll_internal __strtoll_internal_XXX
+#define strtoll strtoll_XXX
+#define strtoq strtoq_XXX
+
+#include <stdlib/strtol.c>
+
+#undef __strtoll_internal
+#undef strtoll
+#undef strtoq
+strong_alias (__strtol_internal, __strtoll_internal)
+libc_hidden_ver (__strtol_internal, __strtoll_internal)
+weak_alias (strtol, strtoll)
+weak_alias (strtol, strtoq)
diff --git a/libc/sysdeps/wordsize-64/strtol_l.c b/libc/sysdeps/wordsize-64/strtol_l.c
new file mode 100644
index 000000000..b2cd102ad
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/strtol_l.c
@@ -0,0 +1,14 @@
+/* We have to irritate the compiler a bit. */
+#define ____strtoll_l_internal ____strtoll_l_internal_XXX
+#define __strtoll_l __strtoll_l_XXX
+#define strtoll_l strtoll_l_XXX
+
+#include <stdlib/strtol_l.c>
+
+#undef ____strtoll_l_internal
+#undef __strtoll_l
+#undef strtoll_l
+strong_alias (____strtol_l_internal, ____strtoll_l_internal)
+libc_hidden_ver (____strtol_l_internal, ____strtoll_l_internal)
+weak_alias (__strtol_l, __strtoll_l)
+weak_alias (__strtol_l, strtoll_l)
diff --git a/libc/sysdeps/wordsize-64/strtoll.c b/libc/sysdeps/wordsize-64/strtoll.c
new file mode 100644
index 000000000..c943e6af3
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/strtoll.c
@@ -0,0 +1 @@
+/* Not needed, it's the same as strtol. */
diff --git a/libc/sysdeps/wordsize-64/strtoll_l.c b/libc/sysdeps/wordsize-64/strtoll_l.c
new file mode 100644
index 000000000..5a5d0d0c6
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/strtoll_l.c
@@ -0,0 +1 @@
+/* Not needed, it's the same as __strtol_l. */
diff --git a/libc/sysdeps/wordsize-64/strtoul.c b/libc/sysdeps/wordsize-64/strtoul.c
new file mode 100644
index 000000000..401882ce0
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/strtoul.c
@@ -0,0 +1,14 @@
+/* We have to irritate the compiler a bit. */
+#define __strtoull_internal __strtoull_internal_XXX
+#define strtoull strtoull_XXX
+#define strtouq strtouq_XXX
+
+#include <stdlib/strtoul.c>
+
+#undef __strtoull_internal
+#undef strtoull
+#undef strtouq
+strong_alias (__strtoul_internal, __strtoull_internal)
+libc_hidden_ver (__strtoul_internal, __strtoull_internal)
+weak_alias (strtoul, strtoull)
+weak_alias (strtoul, strtouq)
diff --git a/libc/sysdeps/wordsize-64/strtoul_l.c b/libc/sysdeps/wordsize-64/strtoul_l.c
new file mode 100644
index 000000000..80cca332b
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/strtoul_l.c
@@ -0,0 +1,14 @@
+/* We have to irritate the compiler a bit. */
+#define ____strtoull_l_internal ____strtoull_l_internal_XXX
+#define __strtoull_l __strtoull_l_XXX
+#define strtoull_l strtoull_l_XXX
+
+#include <stdlib/strtoul_l.c>
+
+#undef ____strtoull_l_internal
+#undef __strtoull_l
+#undef strtoull_l
+strong_alias (____strtoul_l_internal, ____strtoull_l_internal)
+libc_hidden_ver (____strtoul_l_internal, ____strtoull_l_internal)
+weak_alias (__strtoul_l, __strtoull_l)
+weak_alias (__strtoul_l, strtoull_l)
diff --git a/libc/sysdeps/wordsize-64/strtoull.c b/libc/sysdeps/wordsize-64/strtoull.c
new file mode 100644
index 000000000..c472bde1e
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/strtoull.c
@@ -0,0 +1 @@
+/* Not needed, it's the same as strtoul. */
diff --git a/libc/sysdeps/wordsize-64/strtoull_l.c b/libc/sysdeps/wordsize-64/strtoull_l.c
new file mode 100644
index 000000000..c33466bb0
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/strtoull_l.c
@@ -0,0 +1 @@
+/* Not needed, it's the same as __strtoul_l. */
diff --git a/libc/sysdeps/wordsize-64/strtoumax.c b/libc/sysdeps/wordsize-64/strtoumax.c
new file mode 100644
index 000000000..70f1e0fe2
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/strtoumax.c
@@ -0,0 +1,28 @@
+/* Convert string to maximal unsigned integer.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+uintmax_t
+strtoumax (const char *__restrict nptr, char **__restrict endptr, int base)
+{
+ return __strtoul_internal (nptr, endptr, base, 0);
+}
diff --git a/libc/sysdeps/wordsize-64/wcstoimax.c b/libc/sysdeps/wordsize-64/wcstoimax.c
new file mode 100644
index 000000000..f80d3800b
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/wcstoimax.c
@@ -0,0 +1,29 @@
+/* Convert wide-character string to maximal integer.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <inttypes.h>
+#include <wchar.h>
+
+intmax_t
+wcstoimax (const wchar_t *__restrict nptr, wchar_t **__restrict endptr,
+ int base)
+{
+ return __wcstol_internal (nptr, endptr, base, 0);
+}
diff --git a/libc/sysdeps/wordsize-64/wcstol.c b/libc/sysdeps/wordsize-64/wcstol.c
new file mode 100644
index 000000000..b10895a82
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/wcstol.c
@@ -0,0 +1,14 @@
+/* We have to irritate the compiler a bit. */
+#define __wcstoll_internal __wcstoll_internal_XXX
+#define wcstoll wcstoll_XXX
+#define wcstoq wcstoq_XXX
+
+#include <wcsmbs/wcstol.c>
+
+#undef __wcstoll_internal
+#undef wcstoll
+#undef wcstoq
+strong_alias (__wcstol_internal, __wcstoll_internal)
+libc_hidden_ver (__wcstol_internal, __wcstoll_internal)
+weak_alias (wcstol, wcstoll)
+weak_alias (wcstol, wcstoq)
diff --git a/libc/sysdeps/wordsize-64/wcstol_l.c b/libc/sysdeps/wordsize-64/wcstol_l.c
new file mode 100644
index 000000000..4f48f60c6
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/wcstol_l.c
@@ -0,0 +1,13 @@
+/* We have to irritate the compiler a bit. */
+#define ____wcstoll_l_internal ____wcstoll_l_internal_XXX
+#define __wcstoll_l ___wcstoll_l_XXX
+#define wcstoll_l __wcstoll_l_XX
+
+#include <wcsmbs/wcstol_l.c>
+
+#undef ____wcstoll_l_internal
+#undef __wcstoll_l
+#undef wcstoll_l
+strong_alias (____wcstol_l_internal, ____wcstoll_l_internal)
+weak_alias (__wcstol_l, __wcstoll_l)
+weak_alias (__wcstol_l, wcstoll_l)
diff --git a/libc/sysdeps/wordsize-64/wcstoll.c b/libc/sysdeps/wordsize-64/wcstoll.c
new file mode 100644
index 000000000..476ce3e28
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/wcstoll.c
@@ -0,0 +1 @@
+/* Not needed, it's the same as wcstol. */
diff --git a/libc/sysdeps/wordsize-64/wcstoll_l.c b/libc/sysdeps/wordsize-64/wcstoll_l.c
new file mode 100644
index 000000000..e47f6365f
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/wcstoll_l.c
@@ -0,0 +1 @@
+/* Not needed, it's the same as wcstol_l. */
diff --git a/libc/sysdeps/wordsize-64/wcstoul.c b/libc/sysdeps/wordsize-64/wcstoul.c
new file mode 100644
index 000000000..2becb8074
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/wcstoul.c
@@ -0,0 +1,14 @@
+/* We have to irritate the compiler a bit. */
+#define __wcstoull_internal __wcstoull_internal_XXX
+#define wcstoull wcstoull_XXX
+#define wcstouq wcstouq_XXX
+
+#include <wcsmbs/wcstoul.c>
+
+#undef __wcstoull_internal
+#undef wcstoull
+#undef wcstouq
+strong_alias (__wcstoul_internal, __wcstoull_internal)
+libc_hidden_ver (__wcstoul_internal, __wcstoull_internal)
+weak_alias (wcstoul, wcstoull)
+weak_alias (wcstoul, wcstouq)
diff --git a/libc/sysdeps/wordsize-64/wcstoul_l.c b/libc/sysdeps/wordsize-64/wcstoul_l.c
new file mode 100644
index 000000000..c376fa0e8
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/wcstoul_l.c
@@ -0,0 +1,13 @@
+/* We have to irritate the compiler a bit. */
+#define ____wcstoull_l_internal ____wcstoull_l_internal_XXX
+#define __wcstoull_l ___wcstoull_l_XXX
+#define wcstoull_l __wcstoull_l_XXX
+
+#include <wcsmbs/wcstoul_l.c>
+
+#undef ____wcstoull_l_internal
+#undef __wcstoull_l
+#undef wcstoull_l
+strong_alias (____wcstoul_l_internal, ____wcstoull_l_internal)
+weak_alias (__wcstoul_l, __wcstoull_l)
+weak_alias (__wcstoul_l, wcstoull_l)
diff --git a/libc/sysdeps/wordsize-64/wcstoull.c b/libc/sysdeps/wordsize-64/wcstoull.c
new file mode 100644
index 000000000..4776c3a07
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/wcstoull.c
@@ -0,0 +1 @@
+/* Not needed, it's the same as wcstoul. */
diff --git a/libc/sysdeps/wordsize-64/wcstoull_l.c b/libc/sysdeps/wordsize-64/wcstoull_l.c
new file mode 100644
index 000000000..2c9aaa073
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/wcstoull_l.c
@@ -0,0 +1 @@
+/* Not needed, it's the same as wcstoul_l. */
diff --git a/libc/sysdeps/wordsize-64/wcstoumax.c b/libc/sysdeps/wordsize-64/wcstoumax.c
new file mode 100644
index 000000000..a0372d027
--- /dev/null
+++ b/libc/sysdeps/wordsize-64/wcstoumax.c
@@ -0,0 +1,29 @@
+/* Convert wide-character string to maximal unsigned integer.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <inttypes.h>
+#include <wchar.h>
+
+uintmax_t
+wcstoumax (const wchar_t *__restrict nptr, wchar_t **__restrict endptr,
+ int base)
+{
+ return __wcstoul_internal (nptr, endptr, base, 0);
+}
diff --git a/libc/sysdeps/x86_64/Implies b/libc/sysdeps/x86_64/Implies
new file mode 100644
index 000000000..2b8412b0b
--- /dev/null
+++ b/libc/sysdeps/x86_64/Implies
@@ -0,0 +1,4 @@
+wordsize-64
+ieee754/ldbl-96
+ieee754/dbl-64
+ieee754/flt-32
diff --git a/libc/sysdeps/x86_64/Makefile b/libc/sysdeps/x86_64/Makefile
new file mode 100644
index 000000000..65b7aa94c
--- /dev/null
+++ b/libc/sysdeps/x86_64/Makefile
@@ -0,0 +1,11 @@
+# The i387 `long double' is a distinct type we support.
+long-double-fcts = yes
+
+ifeq ($(subdir),csu)
+sysdep_routines += hp-timing
+elide-routines.os += hp-timing
+endif
+
+ifeq ($(subdir),gmon)
+sysdep_routines += _mcount
+endif
diff --git a/libc/sysdeps/x86_64/Versions b/libc/sysdeps/x86_64/Versions
new file mode 100644
index 000000000..253a65f04
--- /dev/null
+++ b/libc/sysdeps/x86_64/Versions
@@ -0,0 +1,7 @@
+libm {
+ GLIBC_2.1 {
+ # A generic bug got this omitted from other configurations' version
+ # sets, but we always had it.
+ exp2l;
+ }
+}
diff --git a/libc/sysdeps/x86_64/__longjmp.S b/libc/sysdeps/x86_64/__longjmp.S
new file mode 100644
index 000000000..a68e7a8a4
--- /dev/null
+++ b/libc/sysdeps/x86_64/__longjmp.S
@@ -0,0 +1,57 @@
+/* Copyright (C) 2001,2004,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+#include <asm-syntax.h>
+
+/* Jump to the position specified by ENV, causing the
+ setjmp call there to return VAL, or 1 if VAL is 0.
+ void __longjmp (__jmp_buf env, int val). */
+ENTRY(__longjmp)
+ /* Restore registers. */
+ movq (JB_RSP*8)(%rdi),%r8
+ movq (JB_RBP*8)(%rdi),%r9
+ movq (JB_PC*8)(%rdi),%rdx
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (%r8)
+ PTR_DEMANGLE (%r9)
+ PTR_DEMANGLE (%rdx)
+#endif
+ /* We add unwind information for the target here. */
+ cfi_def_cfa(%rdi, 0)
+ cfi_register(%rsp,%r8)
+ cfi_register(%rbp,%r9)
+ cfi_register(%rip,%rdx)
+ cfi_offset(%rbx,JB_RBX*8)
+ cfi_offset(%rbp,JB_RBP*8)
+ cfi_offset(%r12,JB_R12*8)
+ cfi_offset(%r13,JB_R13*8)
+ cfi_offset(%r14,JB_R14*8)
+ cfi_offset(%r15,JB_R15*8)
+ movq (JB_RBX*8)(%rdi),%rbx
+ movq (JB_R12*8)(%rdi),%r12
+ movq (JB_R13*8)(%rdi),%r13
+ movq (JB_R14*8)(%rdi),%r14
+ movq (JB_R15*8)(%rdi),%r15
+ /* Set return value for setjmp. */
+ mov %esi, %eax
+ movq %r8,%rsp
+ movq %r9,%rbp
+ jmpq *%rdx
+END (BP_SYM (__longjmp))
diff --git a/libc/sysdeps/x86_64/_mcount.S b/libc/sysdeps/x86_64/_mcount.S
new file mode 100644
index 000000000..c005932c0
--- /dev/null
+++ b/libc/sysdeps/x86_64/_mcount.S
@@ -0,0 +1,67 @@
+/* Machine-specific calling sequence for `mcount' profiling function. x86-64 version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Andreas Jaeger <aj@suse.de>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Assembly stub to invoke _mcount(). Compiler generated code calls
+ this stub after executing a function's prologue and without saving any
+ registers. It is therefore necessary to preserve %rcx, %rdx, %rsi, %rdi,
+ %r8, %r9 as they may contain function arguments. */
+
+#include <sysdep.h>
+
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(_mcount)
+ ASM_TYPE_DIRECTIVE(C_SYMBOL_NAME(_mcount), @function)
+ .align ALIGNARG(4)
+C_LABEL(_mcount)
+ /* Allocate space for 7 registers. */
+ subq $56,%rsp
+ movq %rax,(%rsp)
+ movq %rcx,8(%rsp)
+ movq %rdx,16(%rsp)
+ movq %rsi,24(%rsp)
+ movq %rdi,32(%rsp)
+ movq %r8,40(%rsp)
+ movq %r9,48(%rsp)
+
+ /* Setup parameter for __mcount_internal. */
+ /* selfpc is the return address on the stack. */
+ movq 56(%rsp),%rsi
+ /* Get frompc via the frame pointer. */
+ movq 8(%rbp),%rdi
+#ifdef PIC
+ call C_SYMBOL_NAME(__mcount_internal)@PLT
+#else
+ call C_SYMBOL_NAME(__mcount_internal)
+#endif
+ /* Pop the saved registers. Please note that `mcount' has no
+ return value. */
+ movq 48(%rsp),%r9
+ movq 40(%rsp),%r8
+ movq 32(%rsp),%rdi
+ movq 24(%rsp),%rsi
+ movq 16(%rsp),%rdx
+ movq 8(%rsp),%rcx
+ movq (%rsp),%rax
+ addq $56,%rsp
+ ret
+
+ ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(_mcount))
+
+#undef mcount
+weak_alias (_mcount, mcount)
diff --git a/libc/sysdeps/x86_64/abort-instr.h b/libc/sysdeps/x86_64/abort-instr.h
new file mode 100644
index 000000000..810f10379
--- /dev/null
+++ b/libc/sysdeps/x86_64/abort-instr.h
@@ -0,0 +1,2 @@
+/* An instruction which should crash any program is `hlt'. */
+#define ABORT_INSTRUCTION asm ("hlt")
diff --git a/libc/sysdeps/x86_64/backtrace.c b/libc/sysdeps/x86_64/backtrace.c
new file mode 100644
index 000000000..ee7bf615d
--- /dev/null
+++ b/libc/sysdeps/x86_64/backtrace.c
@@ -0,0 +1 @@
+#include "../ia64/backtrace.c"
diff --git a/libc/sysdeps/x86_64/bits/atomic.h b/libc/sysdeps/x86_64/bits/atomic.h
new file mode 100644
index 000000000..133a68d19
--- /dev/null
+++ b/libc/sysdeps/x86_64/bits/atomic.h
@@ -0,0 +1,324 @@
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+
+#ifndef LOCK_PREFIX
+# ifdef UP
+# define LOCK_PREFIX /* nothing */
+# else
+# define LOCK_PREFIX "lock;"
+# endif
+#endif
+
+
+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile (LOCK_PREFIX "cmpxchgb %b2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "q" (newval), "m" (*mem), "0" (oldval)); \
+ ret; })
+
+#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile (LOCK_PREFIX "cmpxchgw %w2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "r" (newval), "m" (*mem), "0" (oldval)); \
+ ret; })
+
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile (LOCK_PREFIX "cmpxchgl %2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "r" (newval), "m" (*mem), "0" (oldval)); \
+ ret; })
+
+#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile (LOCK_PREFIX "cmpxchgq %q2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "r" ((long) (newval)), "m" (*mem), \
+ "0" ((long) (oldval))); \
+ ret; })
+
+
+/* Note that we need no lock prefix. */
+#define atomic_exchange_acq(mem, newvalue) \
+ ({ __typeof (*mem) result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile ("xchgb %b0, %1" \
+ : "=r" (result), "=m" (*mem) \
+ : "0" (newvalue), "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile ("xchgw %w0, %1" \
+ : "=r" (result), "=m" (*mem) \
+ : "0" (newvalue), "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile ("xchgl %0, %1" \
+ : "=r" (result), "=m" (*mem) \
+ : "0" (newvalue), "m" (*mem)); \
+ else \
+ __asm __volatile ("xchgq %q0, %1" \
+ : "=r" (result), "=m" (*mem) \
+ : "0" ((long) (newvalue)), "m" (*mem)); \
+ result; })
+
+
+#define atomic_exchange_and_add(mem, value) \
+ ({ __typeof (*mem) result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "xaddb %b0, %1" \
+ : "=r" (result), "=m" (*mem) \
+ : "0" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "xaddw %w0, %1" \
+ : "=r" (result), "=m" (*mem) \
+ : "0" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "xaddl %0, %1" \
+ : "=r" (result), "=m" (*mem) \
+ : "0" (value), "m" (*mem)); \
+ else \
+ __asm __volatile (LOCK_PREFIX "xaddq %q0, %1" \
+ : "=r" (result), "=m" (*mem) \
+ : "0" ((long) (value)), "m" (*mem)); \
+ result; })
+
+
+#define atomic_add(mem, value) \
+ (void) ({ if (__builtin_constant_p (value) && (value) == 1) \
+ atomic_increment (mem); \
+ else if (__builtin_constant_p (value) && (value) == 1) \
+ atomic_decrement (mem); \
+ else if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "addb %b1, %0" \
+ : "=m" (*mem) \
+ : "ir" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "addw %w1, %0" \
+ : "=m" (*mem) \
+ : "ir" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "addl %1, %0" \
+ : "=m" (*mem) \
+ : "ir" (value), "m" (*mem)); \
+ else \
+ __asm __volatile (LOCK_PREFIX "addq %q1, %0" \
+ : "=m" (*mem) \
+ : "ir" ((long) (value)), "m" (*mem)); \
+ })
+
+
+#define atomic_add_negative(mem, value) \
+ ({ unsigned char __result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "addb %b2, %0; sets %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "addw %w2, %0; sets %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "addl %2, %0; sets %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" (value), "m" (*mem)); \
+ else \
+ __asm __volatile (LOCK_PREFIX "addq %q2, %0; sets %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" ((long) (value)), "m" (*mem)); \
+ __result; })
+
+
+#define atomic_add_zero(mem, value) \
+ ({ unsigned char __result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "addb %b2, %0; setz %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "addw %w2, %0; setz %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" (value), "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "addl %2, %0; setz %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" (value), "m" (*mem)); \
+ else \
+ __asm __volatile (LOCK_PREFIX "addq %q2, %0; setz %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "ir" ((long) (value)), "m" (*mem)); \
+ __result; })
+
+
+#define atomic_increment(mem) \
+ (void) ({ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "incb %b0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "incw %w0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "incl %0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ else \
+ __asm __volatile (LOCK_PREFIX "incq %q0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ })
+
+
+#define atomic_increment_and_test(mem) \
+ ({ unsigned char __result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "incb %b0; sete %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "incw %w0; sete %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "incl %0; sete %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ else \
+ __asm __volatile (LOCK_PREFIX "incq %q0; sete %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ __result; })
+
+
+#define atomic_decrement(mem) \
+ (void) ({ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "decb %b0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "decw %w0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "decl %0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ else \
+ __asm __volatile (LOCK_PREFIX "decq %q0" \
+ : "=m" (*mem) \
+ : "m" (*mem)); \
+ })
+
+
+#define atomic_decrement_and_test(mem) \
+ ({ unsigned char __result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "decb %b0; sete %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "decw %w0; sete %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "decl %0; sete %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ else \
+ __asm __volatile (LOCK_PREFIX "decq %q0; sete %1" \
+ : "=m" (*mem), "=qm" (__result) \
+ : "m" (*mem)); \
+ __result; })
+
+
+#define atomic_bit_set(mem, bit) \
+ (void) ({ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "orb %b2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "ir" (1L << (bit))); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "orw %w2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "ir" (1L << (bit))); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "orl %2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "ir" (1L << (bit))); \
+ else if (__builtin_constant_p (bit) && (bit) < 32) \
+ __asm __volatile (LOCK_PREFIX "orq %2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "i" (1L << (bit))); \
+ else \
+ __asm __volatile (LOCK_PREFIX "orq %q2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "r" (1UL << (bit))); \
+ })
+
+
+#define atomic_bit_test_set(mem, bit) \
+ ({ unsigned char __result; \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "btsb %3, %1; setc %0" \
+ : "=q" (__result), "=m" (*mem) \
+ : "m" (*mem), "ir" (bit)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "btsw %3, %1; setc %0" \
+ : "=q" (__result), "=m" (*mem) \
+ : "m" (*mem), "ir" (bit)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "btsl %3, %1; setc %0" \
+ : "=q" (__result), "=m" (*mem) \
+ : "m" (*mem), "ir" (bit)); \
+ else \
+ __asm __volatile (LOCK_PREFIX "btsq %3, %1; setc %0" \
+ : "=q" (__result), "=m" (*mem) \
+ : "m" (*mem), "ir" (bit)); \
+ __result; })
+
+
+#define atomic_delay() asm ("rep; nop")
diff --git a/libc/sysdeps/x86_64/bits/byteswap.h b/libc/sysdeps/x86_64/bits/byteswap.h
new file mode 100644
index 000000000..e1c861c75
--- /dev/null
+++ b/libc/sysdeps/x86_64/bits/byteswap.h
@@ -0,0 +1,133 @@
+/* Macros to swap the order of bytes in integer values.
+ Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
+# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
+#endif
+
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H 1
+
+#include <bits/wordsize.h>
+
+/* Swap bytes in 16 bit value. */
+#define __bswap_constant_16(x) \
+ ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+# define __bswap_16(x) \
+ (__extension__ \
+ ({ register unsigned short int __v, __x = (x); \
+ if (__builtin_constant_p (__x)) \
+ __v = __bswap_constant_16 (__x); \
+ else \
+ __asm__ ("rorw $8, %w0" \
+ : "=r" (__v) \
+ : "0" (__x) \
+ : "cc"); \
+ __v; }))
+#else
+/* This is better than nothing. */
+# define __bswap_16(x) \
+ (__extension__ \
+ ({ register unsigned short int __x = (x); __bswap_constant_16 (__x); }))
+#endif
+
+
+/* Swap bytes in 32 bit value. */
+#define __bswap_constant_32(x) \
+ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
+ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+
+#if defined __GNUC__ && __GNUC__ >= 2
+# if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__ \
+ || defined __pentiumpro__ || defined __pentium4__ \
+ || defined __k8__ || defined __athlon__ \
+ || defined __k6__)
+/* To swap the bytes in a word the i486 processors and up provide the
+ `bswap' opcode. On i386 we have to use three instructions. */
+# define __bswap_32(x) \
+ (__extension__ \
+ ({ register unsigned int __v, __x = (x); \
+ if (__builtin_constant_p (__x)) \
+ __v = __bswap_constant_32 (__x); \
+ else \
+ __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \
+ __v; }))
+# else
+# define __bswap_32(x) \
+ (__extension__ \
+ ({ register unsigned int __v, __x = (x); \
+ if (__builtin_constant_p (__x)) \
+ __v = __bswap_constant_32 (__x); \
+ else \
+ __asm__ ("rorw $8, %w0;" \
+ "rorl $16, %0;" \
+ "rorw $8, %w0" \
+ : "=r" (__v) \
+ : "0" (__x) \
+ : "cc"); \
+ __v; }))
+# endif
+#else
+# define __bswap_32(x) \
+ (__extension__ \
+ ({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
+#endif
+
+
+#if defined __GNUC__ && __GNUC__ >= 2
+/* Swap bytes in 64 bit value. */
+# define __bswap_constant_64(x) \
+ ((((x) & 0xff00000000000000ull) >> 56) \
+ | (((x) & 0x00ff000000000000ull) >> 40) \
+ | (((x) & 0x0000ff0000000000ull) >> 24) \
+ | (((x) & 0x000000ff00000000ull) >> 8) \
+ | (((x) & 0x00000000ff000000ull) << 8) \
+ | (((x) & 0x0000000000ff0000ull) << 24) \
+ | (((x) & 0x000000000000ff00ull) << 40) \
+ | (((x) & 0x00000000000000ffull) << 56))
+
+# if __WORDSIZE == 64
+# define __bswap_64(x) \
+ (__extension__ \
+ ({ register unsigned long __v, __x = (x); \
+ if (__builtin_constant_p (__x)) \
+ __v = __bswap_constant_64 (__x); \
+ else \
+ __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); \
+ __v; }))
+# else
+# define __bswap_64(x) \
+ (__extension__ \
+ ({ union { __extension__ unsigned long long int __ll; \
+ unsigned int __l[2]; } __w, __r; \
+ if (__builtin_constant_p (x)) \
+ __r.__ll = __bswap_constant_64 (x); \
+ else \
+ { \
+ __w.__ll = (x); \
+ __r.__l[0] = __bswap_32 (__w.__l[1]); \
+ __r.__l[1] = __bswap_32 (__w.__l[0]); \
+ } \
+ __r.__ll; }))
+# endif
+#endif
+
+#endif /* _BITS_BYTESWAP_H */
diff --git a/libc/sysdeps/x86_64/bits/endian.h b/libc/sysdeps/x86_64/bits/endian.h
new file mode 100644
index 000000000..2f59eada2
--- /dev/null
+++ b/libc/sysdeps/x86_64/bits/endian.h
@@ -0,0 +1,7 @@
+/* x86_64 is little-endian. */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
diff --git a/libc/sysdeps/x86_64/bits/link.h b/libc/sysdeps/x86_64/bits/link.h
new file mode 100644
index 000000000..2890c2d88
--- /dev/null
+++ b/libc/sysdeps/x86_64/bits/link.h
@@ -0,0 +1,117 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+
+#if __ELF_NATIVE_CLASS == 32
+/* Registers for entry into PLT on IA-32. */
+typedef struct La_i86_regs
+{
+ uint32_t lr_edx;
+ uint32_t lr_ecx;
+ uint32_t lr_eax;
+ uint32_t lr_ebp;
+ uint32_t lr_esp;
+} La_i86_regs;
+
+/* Return values for calls from PLT on IA-32. */
+typedef struct La_i86_retval
+{
+ uint32_t lrv_eax;
+ uint32_t lrv_edx;
+ long double lrv_st0;
+ long double lrv_st1;
+} La_i86_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf32_Addr la_i86_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_i86_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_i86_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_i86_regs *__inregs,
+ La_i86_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
+
+#else
+
+/* Registers for entry into PLT on x86-64. */
+# if __GNUC_PREREQ (4,0)
+typedef float La_x86_64_xmm __attribute__ ((__vector_size__ (16)));
+# else
+typedef float La_x86_64_xmm __attribute__ ((__mode__ (__V4SF__)));
+# endif
+
+typedef struct La_x86_64_regs
+{
+ uint64_t lr_rdx;
+ uint64_t lr_r8;
+ uint64_t lr_r9;
+ uint64_t lr_rcx;
+ uint64_t lr_rsi;
+ uint64_t lr_rdi;
+ uint64_t lr_rbp;
+ uint64_t lr_rsp;
+ La_x86_64_xmm lr_xmm[8];
+} La_x86_64_regs;
+
+/* Return values for calls from PLT on x86-64. */
+typedef struct La_x86_64_retval
+{
+ uint64_t lrv_rax;
+ uint64_t lrv_rdx;
+ La_x86_64_xmm lrv_xmm0;
+ La_x86_64_xmm lrv_xmm1;
+ long double lrv_st0;
+ long double lrv_st1;
+} La_x86_64_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf64_Addr la_x86_64_gnu_pltenter (Elf64_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_x86_64_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_x86_64_gnu_pltexit (Elf64_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_x86_64_regs *__inregs,
+ La_x86_64_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
+
+#endif
diff --git a/libc/sysdeps/x86_64/bits/linkmap.h b/libc/sysdeps/x86_64/bits/linkmap.h
new file mode 100644
index 000000000..8ea715715
--- /dev/null
+++ b/libc/sysdeps/x86_64/bits/linkmap.h
@@ -0,0 +1,14 @@
+#if __WORDSIZE == 64
+struct link_map_machine
+ {
+ Elf64_Addr plt; /* Address of .plt + 0x16 */
+ Elf64_Addr gotplt; /* Address of .got + 0x18 */
+ };
+
+#else
+struct link_map_machine
+ {
+ Elf32_Addr plt; /* Address of .plt + 0x16 */
+ Elf32_Addr gotplt; /* Address of .got + 0x0c */
+ };
+#endif
diff --git a/libc/sysdeps/x86_64/bits/mathdef.h b/libc/sysdeps/x86_64/bits/mathdef.h
new file mode 100644
index 000000000..7b1618959
--- /dev/null
+++ b/libc/sysdeps/x86_64/bits/mathdef.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
+# include <bits/wordsize.h>
+
+# if __WORDSIZE == 64 || (defined __FLT_EVAL_METHOD__ && __FLT_EVAL_METHOD__ == 0)
+/* The x86-64 architecture computes values with the precission of the
+ used type. Similarly for -m32 -mfpmath=sse. */
+typedef float float_t; /* `float' expressions are evaluated as `float'. */
+typedef double double_t; /* `double' expressions are evaluated
+ as `double'. */
+# else
+/* The ix87 FPUs evaluate all values in the 80 bit floating-point format
+ which is also available for the user as `long double'. Therefore we
+ define: */
+typedef long double float_t; /* `float' expressions are evaluated as
+ `long double'. */
+typedef long double double_t; /* `double' expressions are evaluated as
+ `long double'. */
+# endif
+
+/* The values returned by `ilogb' for 0 and NaN respectively. */
+# define FP_ILOGB0 (-2147483647 - 1)
+# define FP_ILOGBNAN (-2147483647 - 1)
+
+#endif /* ISO C99 */
diff --git a/libc/sysdeps/x86_64/bits/setjmp.h b/libc/sysdeps/x86_64/bits/setjmp.h
new file mode 100644
index 000000000..c9b98b2e3
--- /dev/null
+++ b/libc/sysdeps/x86_64/bits/setjmp.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2001,2002,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Define the machine-dependent type `jmp_buf'. x86-64 version. */
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H 1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#ifndef _ASM
+
+# if __WORDSIZE == 64
+typedef long int __jmp_buf[8];
+# else
+typedef int __jmp_buf[6];
+# endif
+
+#endif
+
+#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/x86_64/bits/string.h b/libc/sysdeps/x86_64/bits/string.h
new file mode 100644
index 000000000..708ce78d6
--- /dev/null
+++ b/libc/sysdeps/x86_64/bits/string.h
@@ -0,0 +1,26 @@
+/* Optimized, inlined string functions. AMD x86-64 version.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _STRING_H
+# error "Never use <bits/string.h> directly; include <string.h> instead."
+#endif
+
+/* Currently the only purpose of this file is to tell the generic inline
+ macros that unaligned memory access is possible for x86-64. */
+#define _STRING_ARCH_unaligned 1
diff --git a/libc/sysdeps/x86_64/bits/wordsize.h b/libc/sysdeps/x86_64/bits/wordsize.h
new file mode 100644
index 000000000..a40a0d816
--- /dev/null
+++ b/libc/sysdeps/x86_64/bits/wordsize.h
@@ -0,0 +1,8 @@
+/* Determine the wordsize from the preprocessor defines. */
+
+#if defined __x86_64__
+# define __WORDSIZE 64
+# define __WORDSIZE_COMPAT32 1
+#else
+# define __WORDSIZE 32
+#endif
diff --git a/libc/sysdeps/x86_64/bits/xtitypes.h b/libc/sysdeps/x86_64/bits/xtitypes.h
new file mode 100644
index 000000000..c28b698e3
--- /dev/null
+++ b/libc/sysdeps/x86_64/bits/xtitypes.h
@@ -0,0 +1,34 @@
+/* bits/xtitypes.h -- Define some types used by <bits/stropts.h>. x86-64.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _STROPTS_H
+# error "Never include <bits/xtitypes.h> directly; use <stropts.h> instead."
+#endif
+
+#ifndef _BITS_XTITYPES_H
+#define _BITS_XTITYPES_H 1
+
+#include <bits/types.h>
+
+/* This type is used by some structs in <bits/stropts.h>. */
+typedef __SLONG32_TYPE __t_scalar_t;
+typedef __ULONG32_TYPE __t_uscalar_t;
+
+
+#endif /* bits/xtitypes.h */
diff --git a/libc/sysdeps/x86_64/bp-asm.h b/libc/sysdeps/x86_64/bp-asm.h
new file mode 100644
index 000000000..ff140ce18
--- /dev/null
+++ b/libc/sysdeps/x86_64/bp-asm.h
@@ -0,0 +1,141 @@
+/* Bounded-pointer definitions for x86-64 assembler.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _bp_asm_h_
+# define _bp_asm_h_ 1
+
+# if __ASSEMBLER__
+
+# if __BOUNDED_POINTERS__
+
+/* Bounded pointers occupy three words. */
+# define PTR_SIZE 24
+/* Bounded pointer return values are passed back through a hidden
+ argument that points to caller-allocate space. The hidden arg
+ occupies one word on the stack. */
+# define RTN_SIZE 6
+/* Although the caller pushes the hidden arg, the callee is
+ responsible for popping it. */
+# define RET_PTR ret $RTN_SIZE
+/* Maintain frame pointer chain in leaf assembler functions for the benefit
+ of debugging stack traces when bounds violations occur. */
+# define ENTER pushq %rbp; movq %rsp, %rbp
+# define LEAVE movq %rbp, %rsp; popq %rbp
+/* Stack space overhead of procedure-call linkage: return address and
+ frame pointer. */
+# define LINKAGE 16
+/* Stack offset of return address after calling ENTER. */
+# define PCOFF 8
+
+/* Int 5 is the "bound range" exception also raised by the "bound"
+ instruction. */
+# define BOUNDS_VIOLATED int $5
+
+# define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM) \
+ cmpq 8+BP_MEM, VAL_REG; \
+ jae 0f; /* continue if value >= low */ \
+ BOUNDS_VIOLATED; \
+ 0:
+
+# define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc) \
+ cmpq 16+BP_MEM, VAL_REG; \
+ Jcc 0f; /* continue if value < high */ \
+ BOUNDS_VIOLATED; \
+ 0:
+
+# define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM) \
+ cmpq 8+BP_MEM, VAL_REG; \
+ jb 1f; /* die if value < low */ \
+ cmpq 16+BP_MEM, VAL_REG; \
+ jb 0f; /* continue if value < high */ \
+ 1: BOUNDS_VIOLATED; \
+ 0:
+
+# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH) \
+ CHECK_BOUNDS_LOW(VAL_REG, BP_MEM); \
+ addl LENGTH, VAL_REG; \
+ cmpq 16+BP_MEM, VAL_REG; \
+ jbe 0f; /* continue if value <= high */ \
+ BOUNDS_VIOLATED; \
+ 0: subq LENGTH, VAL_REG /* restore value */
+
+/* Take bounds from BP_MEM and affix them to the pointer
+ value in %rax, stuffing all into memory at RTN(%esp).
+ Use %rdx as a scratch register. */
+
+# define RETURN_BOUNDED_POINTER(BP_MEM) \
+ movq RTN(%rsp), %rdx; \
+ movq %rax, 0(%rdx); \
+ movq 8+BP_MEM, %rax; \
+ movq %rax, 4(%rdx); \
+ movq 16+BP_MEM, %rax; \
+ movq %rax, 8(%rdx)
+
+# define RETURN_NULL_BOUNDED_POINTER \
+ movl RTN(%rsp), %rdx; \
+ movl %rax, 0(%rdx); \
+ movl %rax, 4(%rdx); \
+ movl %rax, 8(%rdx)
+
+/* The caller of __errno_location is responsible for allocating space
+ for the three-word BP return-value and passing pushing its address
+ as an implicit first argument. */
+# define PUSH_ERRNO_LOCATION_RETURN \
+ subl $16, %esp; \
+ subl $8, %esp; \
+ pushq %rsp
+
+/* __errno_location is responsible for popping the implicit first
+ argument, but we must pop the space for the BP itself. We also
+ dereference the return value in order to dig out the pointer value. */
+# define POP_ERRNO_LOCATION_RETURN \
+ popq %rax; \
+ addq $16, %rsp
+
+# else /* !__BOUNDED_POINTERS__ */
+
+/* Unbounded pointers occupy one word. */
+# define PTR_SIZE 8
+/* Unbounded pointer return values are passed back in the register %rax. */
+# define RTN_SIZE 0
+/* Use simple return instruction for unbounded pointer values. */
+# define RET_PTR ret
+/* Don't maintain frame pointer chain for leaf assembler functions. */
+# define ENTER
+# define LEAVE
+/* Stack space overhead of procedure-call linkage: return address only. */
+# define LINKAGE 8
+/* Stack offset of return address after calling ENTER. */
+# define PCOFF 0
+
+# define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM)
+# define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc)
+# define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM)
+# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH)
+# define RETURN_BOUNDED_POINTER(BP_MEM)
+
+# define RETURN_NULL_BOUNDED_POINTER
+
+# define PUSH_ERRNO_LOCATION_RETURN
+# define POP_ERRNO_LOCATION_RETURN
+
+# endif /* !__BOUNDED_POINTERS__ */
+
+# endif /* __ASSEMBLER__ */
+
+#endif /* _bp_asm_h_ */
diff --git a/libc/sysdeps/x86_64/bsd-_setjmp.S b/libc/sysdeps/x86_64/bsd-_setjmp.S
new file mode 100644
index 000000000..838fae70f
--- /dev/null
+++ b/libc/sysdeps/x86_64/bsd-_setjmp.S
@@ -0,0 +1,41 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. x86-64 version.
+ Copyright (C) 1994-1997, 2000, 2001, 2002, 2003, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#include <sysdep.h>
+#define _ASM
+#define _SETJMP_H
+#include <bits/setjmp.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+ENTRY (BP_SYM (_setjmp))
+ /* Set up arguments, we only need to set the second arg. */
+ xorl %esi, %esi
+#ifdef PIC
+ jmp HIDDEN_JUMPTARGET (__sigsetjmp)
+#else
+ jmp BP_SYM (__sigsetjmp)
+#endif
+END (BP_SYM (_setjmp))
+libc_hidden_def (_setjmp)
diff --git a/libc/sysdeps/x86_64/bsd-setjmp.S b/libc/sysdeps/x86_64/bsd-setjmp.S
new file mode 100644
index 000000000..216c503cc
--- /dev/null
+++ b/libc/sysdeps/x86_64/bsd-setjmp.S
@@ -0,0 +1,40 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. x86-64 version.
+ Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#include <sysdep.h>
+#define _ASM
+#define _SETJMP_H
+#include <bits/setjmp.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+ENTRY (BP_SYM (setjmp))
+ /* Set up arguments, we only need to set the 2nd arg. */
+ movl $1, %esi
+#ifdef PIC
+ jmp HIDDEN_JUMPTARGET (__sigsetjmp)
+#else
+ jmp BP_SYM (__sigsetjmp)
+#endif
+END (BP_SYM (setjmp))
diff --git a/libc/sysdeps/x86_64/bzero.S b/libc/sysdeps/x86_64/bzero.S
new file mode 100644
index 000000000..2688f456b
--- /dev/null
+++ b/libc/sysdeps/x86_64/bzero.S
@@ -0,0 +1,3 @@
+#define memset __bzero
+#include <sysdeps/x86_64/memset.S>
+weak_alias (__bzero, bzero)
diff --git a/libc/sysdeps/x86_64/dl-machine.h b/libc/sysdeps/x86_64/dl-machine.h
new file mode 100644
index 000000000..73e271775
--- /dev/null
+++ b/libc/sysdeps/x86_64/dl-machine.h
@@ -0,0 +1,442 @@
+/* Machine-dependent ELF dynamic relocation inline functions. x86-64 version.
+ Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "x86_64"
+
+#include <sys/param.h>
+#include <sysdep.h>
+#include <tls.h>
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int __attribute__ ((unused))
+elf_machine_matches_host (const Elf64_Ehdr *ehdr)
+{
+ return ehdr->e_machine == EM_X86_64;
+}
+
+
+/* Return the link-time address of _DYNAMIC. Conveniently, this is the
+ first element of the GOT. This must be inlined in a function which
+ uses global data. */
+static inline Elf64_Addr __attribute__ ((unused))
+elf_machine_dynamic (void)
+{
+ Elf64_Addr addr;
+
+ /* This works because we have our GOT address available in the small PIC
+ model. */
+ addr = (Elf64_Addr) &_DYNAMIC;
+
+ return addr;
+}
+
+
+/* Return the run-time load address of the shared object. */
+static inline Elf64_Addr __attribute__ ((unused))
+elf_machine_load_address (void)
+{
+ Elf64_Addr addr;
+
+ /* The easy way is just the same as on x86:
+ leaq _dl_start, %0
+ leaq _dl_start(%%rip), %1
+ subq %0, %1
+ but this does not work with binutils since we then have
+ a R_X86_64_32S relocation in a shared lib.
+
+ Instead we store the address of _dl_start in the data section
+ and compare it with the current value that we can get via
+ an RIP relative addressing mode. Note that this is the address
+ of _dl_start before any relocation performed at runtime. In case
+ the binary is prelinked the resulting "address" is actually a
+ load offset which is zero if the binary was loaded at the address
+ it is prelinked for. */
+
+ asm ("leaq _dl_start(%%rip), %0\n\t"
+ "subq 1f(%%rip), %0\n\t"
+ ".section\t.data.rel.ro\n"
+ "1:\t.quad _dl_start\n\t"
+ ".previous\n\t"
+ : "=r" (addr) : : "cc");
+
+ return addr;
+}
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int __attribute__ ((unused, always_inline))
+elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+{
+ Elf64_Addr *got;
+ extern void _dl_runtime_resolve (Elf64_Word) attribute_hidden;
+ extern void _dl_runtime_profile (Elf64_Word) attribute_hidden;
+
+ if (l->l_info[DT_JMPREL] && lazy)
+ {
+ /* The GOT entries for functions in the PLT have not yet been filled
+ in. Their initial contents will arrange when called to push an
+ offset into the .rel.plt section, push _GLOBAL_OFFSET_TABLE_[1],
+ and then jump to _GLOBAL_OFFSET_TABLE[2]. */
+ got = (Elf64_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
+ /* If a library is prelinked but we have to relocate anyway,
+ we have to be able to undo the prelinking of .got.plt.
+ The prelinker saved us here address of .plt + 0x16. */
+ if (got[1])
+ {
+ l->l_mach.plt = got[1] + l->l_addr;
+ l->l_mach.gotplt = (Elf64_Addr) &got[3];
+ }
+ got[1] = (Elf64_Addr) l; /* Identify this shared object. */
+
+ /* The got[2] entry contains the address of a function which gets
+ called to get the address of a so far unresolved function and
+ jump to it. The profiling extension of the dynamic linker allows
+ to intercept the calls to collect information. In this case we
+ don't store the address in the GOT so that all future calls also
+ end in this function. */
+ if (__builtin_expect (profile, 0))
+ {
+ got[2] = (Elf64_Addr) &_dl_runtime_profile;
+
+ if (GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), l))
+ /* This is the object we are looking for. Say that we really
+ want profiling and the timers are started. */
+ GL(dl_profile_map) = l;
+ }
+ else
+ /* This function will get called to fix up the GOT entry indicated by
+ the offset on the stack, and then jump to the resolved address. */
+ got[2] = (Elf64_Addr) &_dl_runtime_resolve;
+ }
+
+ return lazy;
+}
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+#define RTLD_START asm ("\n\
+.text\n\
+ .align 16\n\
+.globl _start\n\
+.globl _dl_start_user\n\
+_start:\n\
+ movq %rsp, %rdi\n\
+ call _dl_start\n\
+_dl_start_user:\n\
+ # Save the user entry point address in %r12.\n\
+ movq %rax, %r12\n\
+ # See if we were run as a command with the executable file\n\
+ # name as an extra leading argument.\n\
+ movl _dl_skip_args(%rip), %eax\n\
+ # Pop the original argument count.\n\
+ popq %rdx\n\
+ # Adjust the stack pointer to skip _dl_skip_args words.\n\
+ leaq (%rsp,%rax,8), %rsp\n\
+ # Subtract _dl_skip_args from argc.\n\
+ subl %eax, %edx\n\
+ # Push argc back on the stack.\n\
+ pushq %rdx\n\
+ # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\
+ # argc -> rsi\n\
+ movq %rdx, %rsi\n\
+ # Save %rsp value in %r13.\n\
+ movq %rsp, %r13\n\
+ # And align stack for the _dl_init_internal call. \n\
+ andq $-16, %rsp\n\
+ # _dl_loaded -> rdi\n\
+ movq _rtld_local(%rip), %rdi\n\
+ # env -> rcx\n\
+ leaq 16(%r13,%rdx,8), %rcx\n\
+ # argv -> rdx\n\
+ leaq 8(%r13), %rdx\n\
+ # Clear %rbp to mark outermost frame obviously even for constructors.\n\
+ xorl %ebp, %ebp\n\
+ # Call the function to run the initializers.\n\
+ call _dl_init_internal@PLT\n\
+ # Pass our finalizer function to the user in %rdx, as per ELF ABI.\n\
+ leaq _dl_fini(%rip), %rdx\n\
+ # And make sure %rsp points to argc stored on the stack.\n\
+ movq %r13, %rsp\n\
+ # Jump to the user's entry point.\n\
+ jmp *%r12\n\
+.previous\n\
+");
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+# define elf_machine_type_class(type) \
+ ((((type) == R_X86_64_JUMP_SLOT \
+ || (type) == R_X86_64_DTPMOD64 \
+ || (type) == R_X86_64_DTPOFF64 || (type) == R_X86_64_TPOFF64) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_X86_64_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+# define elf_machine_type_class(type) \
+ ((((type) == R_X86_64_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_X86_64_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
+
+/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
+#define ELF_MACHINE_JMP_SLOT R_X86_64_JUMP_SLOT
+
+/* The x86-64 never uses Elf64_Rel relocations. */
+#define ELF_MACHINE_NO_REL 1
+
+/* We define an initialization functions. This is called very early in
+ _dl_sysdep_start. */
+#define DL_PLATFORM_INIT dl_platform_init ()
+
+static inline void __attribute__ ((unused))
+dl_platform_init (void)
+{
+ if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
+ /* Avoid an empty string which would disturb us. */
+ GLRO(dl_platform) = NULL;
+}
+
+static inline Elf64_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf64_Rela *reloc,
+ Elf64_Addr *reloc_addr, Elf64_Addr value)
+{
+ return *reloc_addr = value;
+}
+
+/* Return the final value of a plt relocation. On x86-64 the
+ JUMP_SLOT relocation ignores the addend. */
+static inline Elf64_Addr
+elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
+ Elf64_Addr value)
+{
+ return value;
+}
+
+
+/* Names of the architecture-specific auditing callback functions. */
+#define ARCH_LA_PLTENTER x86_64_gnu_pltenter
+#define ARCH_LA_PLTEXIT x86_64_gnu_pltexit
+
+#endif /* !dl_machine_h */
+
+#ifdef RESOLVE_MAP
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+ MAP is the object containing the reloc. */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
+ const Elf64_Sym *sym, const struct r_found_version *version,
+ void *const reloc_addr_arg)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+ const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
+
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+ if (__builtin_expect (r_type == R_X86_64_RELATIVE, 0))
+ {
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+ /* This is defined in rtld.c, but nowhere in the static libc.a;
+ make the reference weak so static programs can still link.
+ This declaration cannot be done when compiling rtld.c
+ (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the
+ common defn for _dl_rtld_map, which is incompatible with a
+ weak decl in the same file. */
+# ifndef SHARED
+ weak_extern (GL(dl_rtld_map));
+# endif
+ if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
+# endif
+ *reloc_addr = map->l_addr + reloc->r_addend;
+ }
+ else
+#endif
+ if (__builtin_expect (r_type == R_X86_64_NONE, 0))
+ return;
+ else
+ {
+#ifndef RTLD_BOOTSTRAP
+ const Elf64_Sym *const refsym = sym;
+#endif
+ struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+ Elf64_Addr value = (sym == NULL ? 0
+ : (Elf64_Addr) sym_map->l_addr + sym->st_value);
+
+#if defined RTLD_BOOTSTRAP && !USE___THREAD
+ assert (r_type == R_X86_64_GLOB_DAT || r_type == R_X86_64_JUMP_SLOT);
+ *reloc_addr = value + reloc->r_addend;
+#else
+ switch (r_type)
+ {
+ case R_X86_64_GLOB_DAT:
+ case R_X86_64_JUMP_SLOT:
+ *reloc_addr = value + reloc->r_addend;
+ break;
+
+#if defined USE_TLS && !defined RESOLVE_CONFLICT_FIND_MAP
+ case R_X86_64_DTPMOD64:
+# ifdef RTLD_BOOTSTRAP
+ /* During startup the dynamic linker is always the module
+ with index 1.
+ XXX If this relocation is necessary move before RESOLVE
+ call. */
+ *reloc_addr = 1;
+# else
+ /* Get the information from the link map returned by the
+ resolve function. */
+ if (sym_map != NULL)
+ *reloc_addr = sym_map->l_tls_modid;
+# endif
+ break;
+ case R_X86_64_DTPOFF64:
+# ifndef RTLD_BOOTSTRAP
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ if (sym != NULL)
+ *reloc_addr = sym->st_value + reloc->r_addend;
+# endif
+ break;
+ case R_X86_64_TPOFF64:
+ /* The offset is negative, forward from the thread pointer. */
+# ifndef RTLD_BOOTSTRAP
+ if (sym != NULL)
+# endif
+ {
+# ifndef RTLD_BOOTSTRAP
+ CHECK_STATIC_TLS (map, sym_map);
+# endif
+ /* We know the offset of the object the symbol is contained in.
+ It is a negative value which will be added to the
+ thread pointer. */
+ *reloc_addr = (sym->st_value + reloc->r_addend
+ - sym_map->l_tls_offset);
+ }
+ break;
+#endif /* use TLS */
+
+#ifndef RTLD_BOOTSTRAP
+ case R_X86_64_64:
+ *reloc_addr = value + reloc->r_addend;
+ break;
+ case R_X86_64_32:
+ *(unsigned int *) reloc_addr = value + reloc->r_addend;
+ if (value + reloc->r_addend > UINT_MAX)
+ {
+ const char *strtab;
+
+ strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
+
+ _dl_error_printf ("\
+%s: Symbol `%s' causes overflow in R_X86_64_32 relocation\n",
+ rtld_progname ?: "<program name unknown>",
+ strtab + refsym->st_name);
+ }
+ break;
+# ifndef RESOLVE_CONFLICT_FIND_MAP
+ /* Not needed for dl-conflict.c. */
+ case R_X86_64_PC32:
+ *(unsigned int *) reloc_addr = value + reloc->r_addend
+ - (Elf64_Addr) reloc_addr;
+ if (value + reloc->r_addend - (Elf64_Addr) reloc_addr
+ != (int)(value + reloc->r_addend - (Elf64_Addr) reloc_addr))
+ {
+ const char *strtab;
+
+ strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
+
+ _dl_error_printf ("\
+%s: Symbol `%s' causes overflow in R_X86_64_PC32 relocation\n",
+ rtld_progname ?: "<program name unknown>",
+ strtab + refsym->st_name);
+ }
+ break;
+ case R_X86_64_COPY:
+ if (sym == NULL)
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
+ if (__builtin_expect (sym->st_size > refsym->st_size, 0)
+ || (__builtin_expect (sym->st_size < refsym->st_size, 0)
+ && GLRO(dl_verbose)))
+ {
+ const char *strtab;
+
+ strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
+ _dl_error_printf ("\
+%s: Symbol `%s' has different size in shared object, consider re-linking\n",
+ rtld_progname ?: "<program name unknown>",
+ strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr_arg, (void *) value,
+ MIN (sym->st_size, refsym->st_size));
+ break;
+# endif
+ default:
+ _dl_reloc_bad_type (map, r_type, 0);
+ break;
+#endif
+ }
+#endif
+ }
+}
+
+auto inline void
+__attribute ((always_inline))
+elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ Elf64_Addr *const reloc_addr = reloc_addr_arg;
+ assert (ELF64_R_TYPE (reloc->r_info) == R_X86_64_RELATIVE);
+ *reloc_addr = l_addr + reloc->r_addend;
+}
+
+auto inline void
+__attribute ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf64_Addr l_addr, const Elf64_Rela *reloc)
+{
+ Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
+ const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
+
+ /* Check for unexpected PLT reloc type. */
+ if (__builtin_expect (r_type == R_X86_64_JUMP_SLOT, 1))
+ {
+ if (__builtin_expect (map->l_mach.plt, 0) == 0)
+ *reloc_addr += l_addr;
+ else
+ *reloc_addr =
+ map->l_mach.plt
+ + (((Elf64_Addr) reloc_addr) - map->l_mach.gotplt) * 2;
+ }
+ else
+ _dl_reloc_bad_type (map, r_type, 1);
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/libc/sysdeps/x86_64/dl-tls.h b/libc/sysdeps/x86_64/dl-tls.h
new file mode 100644
index 000000000..3e4768dc1
--- /dev/null
+++ b/libc/sysdeps/x86_64/dl-tls.h
@@ -0,0 +1,29 @@
+/* Thread-local storage handling in the ELF dynamic linker. x86-64 version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+/* Type used for the representation of TLS information in the GOT. */
+typedef struct
+{
+ unsigned long int ti_module;
+ unsigned long int ti_offset;
+} tls_index;
+
+
+extern void *__tls_get_addr (tls_index *ti);
diff --git a/libc/sysdeps/x86_64/dl-trampoline.S b/libc/sysdeps/x86_64/dl-trampoline.S
new file mode 100644
index 000000000..c1686dae1
--- /dev/null
+++ b/libc/sysdeps/x86_64/dl-trampoline.S
@@ -0,0 +1,189 @@
+/* PLT trampolines. x86-64 version.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ .globl _dl_runtime_resolve
+ .type _dl_runtime_resolve, @function
+ .align 16
+ cfi_startproc
+_dl_runtime_resolve:
+ subq $56,%rsp
+ cfi_adjust_cfa_offset(72) # Incorporate PLT
+ movq %rax,(%rsp) # Preserve registers otherwise clobbered.
+ movq %rcx, 8(%rsp)
+ movq %rdx, 16(%rsp)
+ movq %rsi, 24(%rsp)
+ movq %rdi, 32(%rsp)
+ movq %r8, 40(%rsp)
+ movq %r9, 48(%rsp)
+ movq 64(%rsp), %rsi # Copy args pushed by PLT in register.
+ movq %rsi, %r11 # Multiply by 24
+ addq %r11, %rsi
+ addq %r11, %rsi
+ shlq $3, %rsi
+ movq 56(%rsp), %rdi # %rdi: link_map, %rsi: reloc_offset
+ call _dl_fixup # Call resolver.
+ movq %rax, %r11 # Save return value
+ movq 48(%rsp), %r9 # Get register content back.
+ movq 40(%rsp), %r8
+ movq 32(%rsp), %rdi
+ movq 24(%rsp), %rsi
+ movq 16(%rsp), %rdx
+ movq 8(%rsp), %rcx
+ movq (%rsp), %rax
+ addq $72, %rsp # Adjust stack(PLT did 2 pushes)
+ cfi_adjust_cfa_offset(-72)
+ jmp *%r11 # Jump to function address.
+ cfi_endproc
+ .size _dl_runtime_resolve, .-_dl_runtime_resolve
+
+
+#ifndef PROF
+ .globl _dl_runtime_profile
+ .type _dl_runtime_profile, @function
+ .align 16
+ cfi_startproc
+_dl_runtime_profile:
+ subq $80, %rsp
+ cfi_adjust_cfa_offset(96) # Incorporate PLT
+ movq %rax, (%rsp) # Preserve registers otherwise clobbered.
+ movq %rdx, 8(%rsp)
+ movq %r8, 16(%rsp)
+ movq %r9, 24(%rsp)
+ movq %rcx, 32(%rsp)
+ movq %rsi, 40(%rsp)
+ movq %rdi, 48(%rsp)
+ movq %rbp, 56(%rsp) # Information for auditors.
+ leaq 96(%rsp), %rax
+ movq %rax, 64(%rsp)
+ leaq 8(%rsp), %rcx
+ movq 96(%rsp), %rdx # Load return address if needed
+ movq 88(%rsp), %rsi # Copy args pushed by PLT in register.
+ movq %rsi,%r11 # Multiply by 24
+ addq %r11,%rsi
+ addq %r11,%rsi
+ shlq $3, %rsi
+ movq 80(%rsp), %rdi # %rdi: link_map, %rsi: reloc_offset
+ leaq 72(%rsp), %r8
+ call _dl_profile_fixup # Call resolver.
+ movq %rax, %r11 # Save return value
+ movq 8(%rsp), %rdx # Get back register content.
+ movq 16(%rsp), %r8
+ movq 24(%rsp), %r9
+ movq (%rsp),%rax
+ movq 72(%rsp), %r10
+ testq %r10, %r10
+ jns 1f
+ movq 32(%rsp), %rcx
+ movq 40(%rsp), %rsi
+ movq 48(%rsp), %rdi
+ addq $96,%rsp # Adjust stack
+ cfi_adjust_cfa_offset (-96)
+ jmp *%r11 # Jump to function address.
+
+ /*
+ +96 return address
+ +88 PLT2
+ +80 PLT1
+ +72 free
+ +64 %rsp
+ +56 %rbp
+ +48 %rdi
+ +40 %rsi
+ +32 %rcx
+ +24 %r9
+ +16 %r8
+ +8 %rdx
+ %esp %rax
+ */
+ cfi_adjust_cfa_offset (96)
+1: movq %rbx, 72(%rsp)
+ cfi_rel_offset (1, 72)
+ leaq 104(%rsp), %rsi
+ movq %rsp, %rbx
+ cfi_def_cfa_register (1)
+ subq %r10, %rsp
+ movq %rsp, %rdi
+ movq %r10, %rcx
+ shrq $3, %rcx
+ rep
+ movsq
+ andq $0xfffffffffffffff0, %rsp
+ movq 32(%rbx), %rcx
+ movq 40(%rbx), %rsi
+ movq 48(%rbx), %rdi
+ call *%r11
+ movq %rbx, %rsp
+ cfi_def_cfa_register (7)
+ subq $72, %rsp
+ cfi_adjust_cfa_offset (72)
+ movq %rsp, %rcx
+ movq %rax, (%rcx)
+ movq %rdx, 8(%rcx)
+ /* Even though the stack is correctly aligned to allow using movaps
+ we use movups. Some callers might provide an incorrectly aligned
+ stack and we do not want to have it blow up here. */
+ movups %xmm0, 16(%rcx)
+ movups %xmm1, 32(%rcx)
+ fstpt 48(%rcx)
+ fstpt 64(%rcx)
+ /*
+ +168 return address
+ +160 PLT2
+ +152 PLT1
+ +144 free
+ +136 %rsp
+ +128 %rbp
+ +120 %rdi
+ +112 %rsi
+ +104 %rcx
+ +96 %r9
+ +88 %r8
+ +80 %rdx
+ +64 %st1 result
+ +48 %st result
+ +32 %xmm1 result
+ +16 %xmm0 result
+ +8 %rdx result
+ %esp %rax result
+ */
+ leaq 80(%rsp), %rdx
+ movq 144(%rsp), %rbx
+ cfi_restore (1)
+ movq 160(%rsp), %rsi # Copy args pushed by PLT in register.
+ movq %rsi,%r11 # Multiply by 24
+ addq %r11,%rsi
+ addq %r11,%rsi
+ shlq $3, %rsi
+ movq 152(%rsp), %rdi # %rdi: link_map, %rsi: reloc_offset
+ call _dl_call_pltexit
+ movq (%rsp), %rax
+ movq 8(%rsp), %rdx
+ movups 16(%rsp), %xmm0
+ movups 32(%rsp), %xmm1
+ fldt 64(%rsp)
+ fldt 48(%rsp)
+ addq $168, %rsp
+ cfi_adjust_cfa_offset (-168)
+ retq
+ cfi_endproc
+ .size _dl_runtime_profile, .-_dl_runtime_profile
+#endif
diff --git a/libc/sysdeps/x86_64/elf/configure b/libc/sysdeps/x86_64/elf/configure
new file mode 100755
index 000000000..24eff6284
--- /dev/null
+++ b/libc/sysdeps/x86_64/elf/configure
@@ -0,0 +1,49 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/x86_64/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and linker.
+echo "$as_me:$LINENO: checking for x86-64 TLS support" >&5
+echo $ECHO_N "checking for x86-64 TLS support... $ECHO_C" >&6
+if test "${libc_cv_x86_64_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<\EOF
+ .section ".tdata", "awT", @progbits
+ .globl foo
+foo: .quad 1
+ .section ".tbss", "awT", @nobits
+ .globl bar
+bar: .skip 8
+ .text
+baz: leaq bar@TLSLD(%rip), %rdi
+ leaq bar@DTPOFF(%rax), %rcx
+ addq foo@GOTTPOFF(%rip), %rax
+ movq $bar@TPOFF, %rdx
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ libc_cv_x86_64_tls=yes
+else
+ libc_cv_x86_64_tls=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_x86_64_tls" >&5
+echo "${ECHO_T}$libc_cv_x86_64_tls" >&6
+if test $libc_cv_x86_64_tls = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+cat >>confdefs.h <<\_ACEOF
+#define PI_STATIC_AND_HIDDEN 1
+_ACEOF
+
diff --git a/libc/sysdeps/x86_64/elf/configure.in b/libc/sysdeps/x86_64/elf/configure.in
new file mode 100644
index 000000000..9cb59d009
--- /dev/null
+++ b/libc/sysdeps/x86_64/elf/configure.in
@@ -0,0 +1,34 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/x86_64/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and linker.
+AC_CACHE_CHECK(for x86-64 TLS support, libc_cv_x86_64_tls, [dnl
+cat > conftest.s <<\EOF
+ .section ".tdata", "awT", @progbits
+ .globl foo
+foo: .quad 1
+ .section ".tbss", "awT", @nobits
+ .globl bar
+bar: .skip 8
+ .text
+baz: leaq bar@TLSLD(%rip), %rdi
+ leaq bar@DTPOFF(%rax), %rcx
+ addq foo@GOTTPOFF(%rip), %rax
+ movq $bar@TPOFF, %rdx
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_x86_64_tls=yes
+else
+ libc_cv_x86_64_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_x86_64_tls = yes; then
+ AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
+dnl It is always possible to access static and hidden symbols in an
+dnl position independent way.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
diff --git a/libc/sysdeps/x86_64/elf/initfini.c b/libc/sysdeps/x86_64/elf/initfini.c
new file mode 100644
index 000000000..30161d52e
--- /dev/null
+++ b/libc/sysdeps/x86_64/elf/initfini.c
@@ -0,0 +1,108 @@
+/* Special .init and .fini section support for x86-64.
+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file is compiled into assembly code which is then munged by a sed
+ script into two files: crti.s and crtn.s.
+
+ * crti.s puts a function prologue at the beginning of the
+ .init and .fini sections and defines global symbols for
+ those addresses, so they can be called as functions.
+
+ * crtn.s puts the corresponding function epilogues
+ in the .init and .fini sections. */
+
+__asm__ ("\n\
+#include \"defs.h\"\n\
+\n\
+/*@HEADER_ENDS*/\n\
+\n\
+/*@_init_PROLOG_BEGINS*/\n\
+ .align 4\n\
+ .type call_gmon_start,@function\n\
+call_gmon_start:\n\
+ subq $8, %rsp\n\
+ movq __gmon_start__@GOTPCREL(%rip), %rax\n\
+ testq %rax, %rax\n\
+ je .L22\n\
+ call *%rax\n\
+.L22:\n\
+ addq $8, %rsp\n\
+ ret\n\
+\n\
+ .section .init\n\
+ .align 4\n\
+.globl _init\n\
+ .type _init,@function\n\
+_init:\n\
+ subq $8, %rsp\n\
+ call call_gmon_start\n\
+ ALIGN\n\
+ END_INIT\n\
+\n\
+/*@_init_PROLOG_ENDS*/\n\
+\n\
+/*@_init_EPILOG_BEGINS*/\n\
+ .section .init\n\
+ addq $8, %rsp\n\
+ ret\n\
+ END_INIT\n\
+\n\
+/*@_init_EPILOG_ENDS*/\n\
+\n\
+/*@_fini_PROLOG_BEGINS*/\n\
+ .section .fini\n\
+ .align 4\n\
+.globl _fini\n\
+ .type _fini,@function\n\
+_fini:\n\
+ subq $8, %rsp\n\
+ ALIGN\n\
+ END_FINI\n\
+\n\
+/*@_fini_PROLOG_ENDS*/\n\
+ call i_am_not_a_leaf@PLT\n\
+\n\
+/*@_fini_EPILOG_BEGINS*/\n\
+ .section .fini\n\
+ addq $8, %rsp\n\
+ ret\n\
+ END_FINI\n\
+\n\
+/*@_fini_EPILOG_ENDS*/\n\
+\n\
+/*@TRAILER_BEGINS*/\n\
+ .weak __gmon_start__\n\
+");
diff --git a/libc/sysdeps/x86_64/elf/start.S b/libc/sysdeps/x86_64/elf/start.S
new file mode 100644
index 000000000..3c2caf9d0
--- /dev/null
+++ b/libc/sysdeps/x86_64/elf/start.S
@@ -0,0 +1,124 @@
+/* Startup code compliant to the ELF x86-64 ABI.
+ Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This is the canonical entry point, usually the first thing in the text
+ segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
+ point runs, most registers' values are unspecified, except for:
+
+ %rdx Contains a function pointer to be registered with `atexit'.
+ This is how the dynamic linker arranges to have DT_FINI
+ functions called for shared libraries that have been loaded
+ before this code runs.
+
+ %rsp The stack contains the arguments and environment:
+ 0(%rsp) argc
+ 8(%rsp) argv[0]
+ ...
+ (8*argc)(%rsp) NULL
+ (8*(argc+1))(%rsp) envp[0]
+ ...
+ NULL
+*/
+
+#include "bp-sym.h"
+
+ .text
+ .globl _start
+ .type _start,@function
+_start:
+ /* Clear the frame pointer. The ABI suggests this be done, to mark
+ the outermost frame obviously. */
+ xorl %ebp, %ebp
+
+ /* Extract the arguments as encoded on the stack and set up
+ the arguments for __libc_start_main (int (*main) (int, char **, char **),
+ int argc, char *argv,
+ void (*init) (void), void (*fini) (void),
+ void (*rtld_fini) (void), void *stack_end).
+ The arguments are passed via registers and on the stack:
+ main: %rdi
+ argc: %rsi
+ argv: %rdx
+ init: %rcx
+ fini: %r8
+ rtld_fini: %r9
+ stack_end: stack. */
+
+ movq %rdx, %r9 /* Address of the shared library termination
+ function. */
+ popq %rsi /* Pop the argument count. */
+ movq %rsp, %rdx /* argv starts just at the current stack top. */
+ /* Align the stack to a 16 byte boundary to follow the ABI. */
+ andq $~15, %rsp
+
+ pushq %rax /* Push garbage because we push 8 more bytes. */
+
+ /* Provide the highest stack address to the user code (for stacks
+ which grow downwards). */
+ pushq %rsp
+
+#ifdef SHARED
+ /* Pass address of our own entry points to .fini and .init. */
+ movq __libc_csu_fini@GOTPCREL(%rip), %r8
+ movq __libc_csu_init@GOTPCREL(%rip), %rcx
+
+ movq BP_SYM (main)@GOTPCREL(%rip), %rdi
+
+ /* Call the user's main function, and exit with its value.
+ But let the libc call main. */
+ call BP_SYM (__libc_start_main)@PLT
+#else
+ /* Pass address of our own entry points to .fini and .init. */
+ movq $__libc_csu_fini, %r8
+ movq $__libc_csu_init, %rcx
+
+ movq $BP_SYM (main), %rdi
+
+ /* Call the user's main function, and exit with its value.
+ But let the libc call main. */
+ call BP_SYM (__libc_start_main)
+#endif
+
+ hlt /* Crash if somehow `exit' does return. */
+
+/* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+ .long 0
+ .weak data_start
+ data_start = __data_start
diff --git a/libc/sysdeps/x86_64/ffs.c b/libc/sysdeps/x86_64/ffs.c
new file mode 100644
index 000000000..b7e512c05
--- /dev/null
+++ b/libc/sysdeps/x86_64/ffs.c
@@ -0,0 +1,39 @@
+/* ffs -- find first set bit in a word, counted from least significant end.
+ For AMD x86-64.
+ This file is part of the GNU C Library.
+ Copyright (C) 1991,92,93,94,97,98,2001,2004 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+
+#undef ffs
+
+int
+__ffs (int x)
+{
+ int cnt;
+ int tmp;
+
+ asm ("bsfl %2,%0\n" /* Count low bits in X and store in %1. */
+ "cmovel %1,%0\n" /* If number was zero, use -1 as result. */
+ : "=&r" (cnt), "=r" (tmp) : "rm" (x), "1" (-1));
+
+ return cnt + 1;
+}
+weak_alias (__ffs, ffs)
+libc_hidden_builtin_def (ffs)
diff --git a/libc/sysdeps/x86_64/ffsll.c b/libc/sysdeps/x86_64/ffsll.c
new file mode 100644
index 000000000..7213c0363
--- /dev/null
+++ b/libc/sysdeps/x86_64/ffsll.c
@@ -0,0 +1,41 @@
+/* ffsll -- find first set bit in a word, counted from least significant end.
+ For AMD x86-64.
+ This file is part of the GNU C Library.
+ Copyright (C) 1991,92,93,94,97,98,2001 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define ffsl __something_else
+#include <string.h>
+
+#undef ffsll
+
+int
+ffsll (long long int x)
+{
+ long long int cnt;
+ long long int tmp;
+
+ asm ("bsfq %2,%0\n" /* Count low bits in X and store in %1. */
+ "cmoveq %1,%0\n" /* If number was zero, use -1 as result. */
+ : "=&r" (cnt), "=r" (tmp) : "rm" (x), "1" (-1));
+
+ return cnt + 1;
+}
+
+#undef ffsl
+weak_alias (ffsll, ffsl)
diff --git a/libc/sysdeps/x86_64/fpu/bits/fenv.h b/libc/sysdeps/x86_64/fpu/bits/fenv.h
new file mode 100644
index 000000000..11859f00c
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/bits/fenv.h
@@ -0,0 +1,97 @@
+/* Copyright (C) 1997,1998,1999,2000,2001,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+
+/* Define bits representing the exception. We use the bit positions
+ of the appropriate bits in the FPU control word. */
+enum
+ {
+ FE_INVALID = 0x01,
+#define FE_INVALID FE_INVALID
+ __FE_DENORM = 0x02,
+ FE_DIVBYZERO = 0x04,
+#define FE_DIVBYZERO FE_DIVBYZERO
+ FE_OVERFLOW = 0x08,
+#define FE_OVERFLOW FE_OVERFLOW
+ FE_UNDERFLOW = 0x10,
+#define FE_UNDERFLOW FE_UNDERFLOW
+ FE_INEXACT = 0x20
+#define FE_INEXACT FE_INEXACT
+ };
+
+#define FE_ALL_EXCEPT \
+ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+/* The ix87 FPU supports all of the four defined rounding modes. We
+ use again the bit positions in the FPU control word as the values
+ for the appropriate macros. */
+enum
+ {
+ FE_TONEAREST = 0,
+#define FE_TONEAREST FE_TONEAREST
+ FE_DOWNWARD = 0x400,
+#define FE_DOWNWARD FE_DOWNWARD
+ FE_UPWARD = 0x800,
+#define FE_UPWARD FE_UPWARD
+ FE_TOWARDZERO = 0xc00
+#define FE_TOWARDZERO FE_TOWARDZERO
+ };
+
+
+/* Type representing exception flags. */
+typedef unsigned short int fexcept_t;
+
+
+/* Type representing floating-point environment. This structure
+ corresponds to the layout of the block written by the `fstenv'
+ instruction and has additional fields for the contents of the MXCSR
+ register as written by the `stmxcsr' instruction. */
+typedef struct
+ {
+ unsigned short int __control_word;
+ unsigned short int __unused1;
+ unsigned short int __status_word;
+ unsigned short int __unused2;
+ unsigned short int __tags;
+ unsigned short int __unused3;
+ unsigned int __eip;
+ unsigned short int __cs_selector;
+ unsigned int __opcode:11;
+ unsigned int __unused4:5;
+ unsigned int __data_offset;
+ unsigned short int __data_selector;
+ unsigned short int __unused5;
+#if __WORDSIZE == 64
+ unsigned int __mxcsr;
+#endif
+ }
+fenv_t;
+
+/* If the default argument is used we use this value. */
+#define FE_DFL_ENV ((__const fenv_t *) -1)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exception is masked. */
+# define FE_NOMASK_ENV ((__const fenv_t *) -2)
+#endif
diff --git a/libc/sysdeps/x86_64/fpu/bits/mathinline.h b/libc/sysdeps/x86_64/fpu/bits/mathinline.h
new file mode 100644
index 000000000..39d11b678
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/bits/mathinline.h
@@ -0,0 +1,53 @@
+/* Inline math functions for x86-64.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MATH_H
+# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
+#endif
+
+#ifdef __cplusplus
+# define __MATH_INLINE __inline
+#else
+# define __MATH_INLINE extern __inline
+#endif
+
+
+#if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2
+
+/* Test for negative number. Used in the signbit() macro. */
+__MATH_INLINE int
+__NTH (__signbitf (float __x))
+{
+ __extension__ union { float __f; int __i; } __u = { __f: __x };
+ return __u.__i < 0;
+}
+__MATH_INLINE int
+__NTH (__signbit (double __x))
+{
+ __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
+ return __u.__i[1] < 0;
+}
+__MATH_INLINE int
+__NTH (__signbitl (long double __x))
+{
+ __extension__ union { long double __l; int __i[3]; } __u = { __l: __x };
+ return (__u.__i[2] & 0x8000) != 0;
+}
+#endif
diff --git a/libc/sysdeps/x86_64/fpu/e_acosl.c b/libc/sysdeps/x86_64/fpu/e_acosl.c
new file mode 100644
index 000000000..1ef6d3c94
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_acosl.c
@@ -0,0 +1 @@
+#include "sysdeps/i386/fpu/e_acosl.c"
diff --git a/libc/sysdeps/x86_64/fpu/e_atan2l.c b/libc/sysdeps/x86_64/fpu/e_atan2l.c
new file mode 100644
index 000000000..bbd549f30
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_atan2l.c
@@ -0,0 +1,2 @@
+#include "sysdeps/i386/fpu/e_atan2l.c"
+
diff --git a/libc/sysdeps/x86_64/fpu/e_exp2l.S b/libc/sysdeps/x86_64/fpu/e_exp2l.S
new file mode 100644
index 000000000..336b98909
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_exp2l.S
@@ -0,0 +1,38 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__ieee754_exp2l)
+ fldt 8(%rsp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+ fld %st
+ frndint /* int(x) */
+ fsubr %st,%st(1) /* fract(x) */
+ fxch
+ f2xm1 /* 2^(fract(x)) - 1 */
+ fld1
+ faddp /* 2^(fract(x)) */
+ fscale /* e^x */
+ fstp %st(1)
+ ret
+
+1: testl $0x200, %eax /* Test sign. */
+ jz 2f /* If positive, jump. */
+ fstp %st
+ fldz /* Set result to 0. */
+2: ret
+END (__ieee754_exp2l)
diff --git a/libc/sysdeps/x86_64/fpu/e_expl.c b/libc/sysdeps/x86_64/fpu/e_expl.c
new file mode 100644
index 000000000..5042e02db
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_expl.c
@@ -0,0 +1 @@
+#include "sysdeps/i386/fpu/e_expl.c"
diff --git a/libc/sysdeps/x86_64/fpu/e_fmodl.S b/libc/sysdeps/x86_64/fpu/e_fmodl.S
new file mode 100644
index 000000000..2967bf224
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_fmodl.S
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__ieee754_fmodl)
+ fldt 24(%rsp)
+ fldt 8(%rsp)
+1: fprem
+ fstsw %ax
+ and $04,%ah
+ jnz 1b
+ fstp %st(1)
+ ret
+END (__ieee754_fmodl)
diff --git a/libc/sysdeps/x86_64/fpu/e_log10l.S b/libc/sysdeps/x86_64/fpu/e_log10l.S
new file mode 100644
index 000000000..b4343bef4
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_log10l.S
@@ -0,0 +1,66 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##(%rip)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_log10l)
+ fldlg2 // log10(2)
+ fldt 8(%rsp) // x : log10(2)
+ fxam
+ fnstsw
+ fld %st // x : x : log10(2)
+ andb $1,%ah
+ jnz 3f // in case x is NaN or ±Inf
+4: fsubl MO(one) // x-1 : x : log10(2)
+ fld %st // x-1 : x-1 : x : log10(2)
+ fabs // |x-1| : x-1 : x : log10(2)
+ fcompl MO(limit) // x-1 : x : log10(2)
+ fnstsw // x-1 : x : log10(2)
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : log10(2)
+ fyl2xp1 // log10(x)
+ ret
+
+2: fstp %st(0) // x : log10(2)
+ fyl2x // log10(x)
+ ret
+
+3: jp 4b // in case x is ±Inf
+ fstp %st(1)
+ fstp %st(1)
+ ret
+END(__ieee754_log10l)
diff --git a/libc/sysdeps/x86_64/fpu/e_log2l.S b/libc/sysdeps/x86_64/fpu/e_log2l.S
new file mode 100644
index 000000000..7a89b94d9
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_log2l.S
@@ -0,0 +1,63 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##(%rip)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_log2l)
+ fldl MO(one)
+ fldt 8(%rsp) // x : 1
+ fxam
+ fnstsw
+ fld %st // x : x : 1
+ andb $1,%ah
+ jnz 3f // in case x is NaN or ±Inf
+4: fsub %st(2), %st // x-1 : x : 1
+ fld %st // x-1 : x-1 : x : 1
+ fabs // |x-1| : x-1 : x : 1
+ fcompl MO(limit) // x-1 : x : 1
+ fnstsw // x-1 : x : 1
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : 1
+ fyl2xp1 // log(x)
+ ret
+
+2: fstp %st(0) // x : 1
+ fyl2x // log(x)
+ ret
+
+3: jp 4b // in case x is ±Inf
+ fstp %st(1)
+ fstp %st(1)
+ ret
+END (__ieee754_log2l)
diff --git a/libc/sysdeps/x86_64/fpu/e_logl.S b/libc/sysdeps/x86_64/fpu/e_logl.S
new file mode 100644
index 000000000..a0bed663c
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_logl.S
@@ -0,0 +1,56 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##(%rip)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_logl)
+ fldln2 // log(2)
+ fldt 8(%rsp) // x : log(2)
+ fld %st // x : x : log(2)
+ fsubl MO(one) // x-1 : x : log(2)
+ fld %st // x-1 : x-1 : x : log(2)
+ fabs // |x-1| : x-1 : x : log(2)
+ fcompl MO(limit) // x-1 : x : log(2)
+ fnstsw // x-1 : x : log(2)
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : log(2)
+ fyl2xp1 // log(x)
+ ret
+
+2: fstp %st(0) // x : log(2)
+ fyl2x // log(x)
+ ret
+END (__ieee754_logl)
diff --git a/libc/sysdeps/x86_64/fpu/e_powl.S b/libc/sysdeps/x86_64/fpu/e_powl.S
new file mode 100644
index 000000000..85f4deb3c
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_powl.S
@@ -0,0 +1,338 @@
+/* ix87 specific implementation of pow function.
+ Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(infinity,@object)
+inf_zero:
+infinity:
+ .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f
+ ASM_SIZE_DIRECTIVE(infinity)
+ ASM_TYPE_DIRECTIVE(zero,@object)
+zero: .double 0.0
+ ASM_SIZE_DIRECTIVE(zero)
+ ASM_TYPE_DIRECTIVE(minf_mzero,@object)
+minf_mzero:
+minfinity:
+ .byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff
+mzero:
+ .byte 0, 0, 0, 0, 0, 0, 0, 0x80
+ ASM_SIZE_DIRECTIVE(minf_mzero)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+ ASM_TYPE_DIRECTIVE(p63,@object)
+p63:
+ .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43
+ ASM_SIZE_DIRECTIVE(p63)
+
+#ifdef PIC
+#define MO(op) op##(%rip)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_powl)
+ fldt 24(%rsp) // y
+ fxam
+
+
+ fnstsw
+ movb %ah, %dl
+ andb $0x45, %ah
+ cmpb $0x40, %ah // is y == 0 ?
+ je 11f
+
+ cmpb $0x05, %ah // is y == ±inf ?
+ je 12f
+
+ cmpb $0x01, %ah // is y == NaN ?
+ je 30f
+
+ fldt 8(%rsp) // x : y
+
+ fxam
+ fnstsw
+ movb %ah, %dh
+ andb $0x45, %ah
+ cmpb $0x40, %ah
+ je 20f // x is ±0
+
+ cmpb $0x05, %ah
+ je 15f // x is ±inf
+
+ fxch // y : x
+
+ /* fistpll raises invalid exception for |y| >= 1L<<63. */
+ fldl MO(p63) // 1L<<63 : y : x
+ fld %st(1) // y : 1L<<63 : y : x
+ fabs // |y| : 1L<<63 : y : x
+ fcomip %st(1), %st // 1L<<63 : y : x
+ fstp %st(0) // y : x
+ jnc 2f
+
+ /* First see whether `y' is a natural number. In this case we
+ can use a more precise algorithm. */
+ fld %st // y : y : x
+ fistpll -8(%rsp) // y : x
+ fildll -8(%rsp) // int(y) : y : x
+ fucomip %st(1),%st // y : x
+ jne 2f
+
+ /* OK, we have an integer value for y. */
+ mov -8(%rsp),%eax
+ mov -4(%rsp),%edx
+ orl $0, %edx
+ fstp %st(0) // x
+ jns 4f // y >= 0, jump
+ fdivrl MO(one) // 1/x (now referred to as x)
+ negl %eax
+ adcl $0, %edx
+ negl %edx
+4: fldl MO(one) // 1 : x
+ fxch
+
+6: shrdl $1, %edx, %eax
+ jnc 5f
+ fxch
+ fmul %st(1) // x : ST*x
+ fxch
+5: fmul %st(0), %st // x*x : ST*x
+ shrl $1, %edx
+ movl %eax, %ecx
+ orl %edx, %ecx
+ jnz 6b
+ fstp %st(0) // ST*x
+ ret
+
+ /* y is ±NAN */
+30: fldt 8(%rsp) // x : y
+ fldl MO(one) // 1.0 : x : y
+ fucomip %st(1),%st // x : y
+ je 31f
+ fxch // y : x
+31: fstp %st(1)
+ ret
+
+ .align ALIGNARG(4)
+2: /* y is a real number. */
+ fxch // x : y
+ fldl MO(one) // 1.0 : x : y
+ fld %st(1) // x : 1.0 : x : y
+ fsub %st(1) // x-1 : 1.0 : x : y
+ fabs // |x-1| : 1.0 : x : y
+ fcompl MO(limit) // 1.0 : x : y
+ fnstsw
+ fxch // x : 1.0 : y
+ test $4500,%eax
+ jz 7f
+ fsub %st(1) // x-1 : 1.0 : y
+ fyl2xp1 // log2(x) : y
+ jmp 8f
+
+7: fyl2x // log2(x) : y
+8: fmul %st(1) // y*log2(x) : y
+ fxam
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x05, %ah // is y*log2(x) == ±inf ?
+ je 28f
+ fst %st(1) // y*log2(x) : y*log2(x)
+ frndint // int(y*log2(x)) : y*log2(x)
+ fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x))
+ fxch // fract(y*log2(x)) : int(y*log2(x))
+ f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x))
+ faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x))
+ fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x))
+ fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x))
+ ret
+
+28: fstp %st(1) // y*log2(x)
+ fldl MO(one) // 1 : y*log2(x)
+ fscale // 2^(y*log2(x)) : y*log2(x)
+ fstp %st(1) // 2^(y*log2(x))
+ ret
+
+ // pow(x,±0) = 1
+ .align ALIGNARG(4)
+11: fstp %st(0) // pop y
+ fldl MO(one)
+ ret
+
+ // y == ±inf
+ .align ALIGNARG(4)
+12: fstp %st(0) // pop y
+ fldt 8(%rsp) // x
+ fabs
+ fcompl MO(one) // < 1, == 1, or > 1
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x45, %ah
+ je 13f // jump if x is NaN
+
+ cmpb $0x40, %ah
+ je 14f // jump if |x| == 1
+
+ shlb $1, %ah
+ xorb %ah, %dl
+ andl $2, %edx
+#ifdef PIC
+ lea inf_zero(%rip),%rcx
+ fldl (%rcx, %rdx, 4)
+#else
+ fldl inf_zero(,%rdx, 4)
+#endif
+ ret
+
+ .align ALIGNARG(4)
+14: fldl MO(one)
+ ret
+
+ .align ALIGNARG(4)
+13: fldt 8(%rsp) // load x == NaN
+ ret
+
+ .align ALIGNARG(4)
+ // x is ±inf
+15: fstp %st(0) // y
+ testb $2, %dh
+ jz 16f // jump if x == +inf
+
+ // We must find out whether y is an odd integer.
+ fld %st // y : y
+ fistpll -8(%rsp) // y
+ fildll -8(%rsp) // int(y) : y
+ fucomip %st(1),%st
+ ffreep %st // <empty>
+ jne 17f
+
+ // OK, the value is an integer, but is it odd?
+ mov -8(%rsp), %eax
+ mov -4(%rsp), %edx
+ andb $1, %al
+ jz 18f // jump if not odd
+ // It's an odd integer.
+ shrl $31, %edx
+#ifdef PIC
+ lea minf_mzero(%rip),%rcx
+ fldl (%rcx, %rdx, 8)
+#else
+ fldl minf_mzero(,%rdx, 8)
+#endif
+ ret
+
+ .align ALIGNARG(4)
+16: fcompl MO(zero)
+ fnstsw
+ shrl $5, %eax
+ andl $8, %eax
+#ifdef PIC
+ lea inf_zero(%rip),%rcx
+ fldl (%rcx, %rax, 1)
+#else
+ fldl inf_zero(,%rax, 1)
+#endif
+ ret
+
+ .align ALIGNARG(4)
+17: shll $30, %edx // sign bit for y in right position
+18: shrl $31, %edx
+#ifdef PIC
+ lea inf_zero(%rip),%rcx
+ fldl (%rcx, %rdx, 8)
+#else
+ fldl inf_zero(,%rdx, 8)
+#endif
+ ret
+
+ .align ALIGNARG(4)
+ // x is ±0
+20: fstp %st(0) // y
+ testb $2, %dl
+ jz 21f // y > 0
+
+ // x is ±0 and y is < 0. We must find out whether y is an odd integer.
+ testb $2, %dh
+ jz 25f
+
+ fld %st // y : y
+ fistpll -8(%rsp) // y
+ fildll -8(%rsp) // int(y) : y
+ fucomip %st(1),%st
+ ffreep %st // <empty>
+ jne 26f
+
+ // OK, the value is an integer, but is it odd?
+ mov -8(%rsp),%eax
+ mov -4(%rsp),%edx
+ andb $1, %al
+ jz 27f // jump if not odd
+ // It's an odd integer.
+ // Raise divide-by-zero exception and get minus infinity value.
+ fldl MO(one)
+ fdivl MO(zero)
+ fchs
+ ret
+
+25: fstp %st(0)
+26:
+27: // Raise divide-by-zero exception and get infinity value.
+ fldl MO(one)
+ fdivl MO(zero)
+ ret
+
+ .align ALIGNARG(4)
+ // x is ±0 and y is > 0. We must find out whether y is an odd integer.
+21: testb $2, %dh
+ jz 22f
+
+ fld %st // y : y
+ fistpll -8(%rsp) // y
+ fildll -8(%rsp) // int(y) : y
+ fucomip %st(1),%st
+ ffreep %st // <empty>
+ jne 23f
+
+ // OK, the value is an integer, but is it odd?
+ mov -8(%rsp),%eax
+ mov -4(%rsp),%edx
+ andb $1, %al
+ jz 24f // jump if not odd
+ // It's an odd integer.
+ fldl MO(mzero)
+ ret
+
+22: fstp %st(0)
+23:
+24: fldl MO(zero)
+ ret
+
+END(__ieee754_powl)
diff --git a/libc/sysdeps/x86_64/fpu/e_rem_pio2l.c b/libc/sysdeps/x86_64/fpu/e_rem_pio2l.c
new file mode 100644
index 000000000..1347b0468
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_rem_pio2l.c
@@ -0,0 +1,3 @@
+/* Empty. This file is only meant to avoid compiling the file with the
+ same name in the libm-ieee754 directory. The code is not used since
+ there is an assembler version for all users of this file. */
diff --git a/libc/sysdeps/x86_64/fpu/e_remainderl.S b/libc/sysdeps/x86_64/fpu/e_remainderl.S
new file mode 100644
index 000000000..480b1cad8
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_remainderl.S
@@ -0,0 +1,20 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__ieee754_remainderl)
+ fldt 24(%rsp)
+ fldt 8(%rsp)
+1: fprem1
+ fstsw %ax
+ testl $0x400,%eax
+ jnz 1b
+ fstp %st(1)
+ ret
+END (__ieee754_remainderl)
diff --git a/libc/sysdeps/x86_64/fpu/e_scalbl.S b/libc/sysdeps/x86_64/fpu/e_scalbl.S
new file mode 100644
index 000000000..6b229705b
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_scalbl.S
@@ -0,0 +1,100 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>
+ *
+ * Correct handling of y==-inf <drepper@gnu>
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(zero_nan,@object)
+zero_nan:
+ .double 0.0
+nan: .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+minus_zero:
+ .byte 0, 0, 0, 0, 0, 0, 0, 0x80
+ .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
+ ASM_SIZE_DIRECTIVE(zero_nan)
+
+
+#ifdef PIC
+#define MO(op) op##(%rip)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__ieee754_scalbl)
+ fldt 24(%rsp)
+ fxam
+ fnstsw
+ fldt 8(%rsp)
+ andl $0x4700, %eax
+ cmpl $0x0700, %eax
+ je 1f
+ andl $0x4500, %eax
+ cmpl $0x0100, %eax
+ je 2f
+ fxam
+ fnstsw
+ andl $0x4500, %eax
+ cmpl $0x0100, %eax
+ je 3f
+ fld %st(1)
+ frndint
+ fcomip %st(2), %st
+ jne 4f
+ fscale
+ fstp %st(1)
+ ret
+
+ /* y is -inf */
+1: fxam
+ fnstsw
+ movl 16(%rsp), %edx
+ shrl $5, %eax
+ fstp %st
+ fstp %st
+ andl $0x8000, %edx
+ andl $8, %eax
+ jnz 4f
+ shrl $11, %edx
+ addl %edx, %eax
+#ifdef PIC
+ lea zero_nan(%rip),%rdx
+ fldl (%rdx,%rax,1)
+#else
+ fldl zero_nan(%rax, 1)
+#endif
+ ret
+
+ /* The result is NaN, but we must not raise an exception.
+ So use a variable. */
+2: fstp %st
+ fstp %st
+ fldl MO(nan)
+ ret
+
+ /* The first parameter is a NaN. Return it. */
+3: fstp %st(1)
+ ret
+
+ /* Return NaN and raise the invalid exception. */
+4: fstp %st
+ fstp %st
+ fldz
+ fdiv %st
+ ret
+END(__ieee754_scalbl)
diff --git a/libc/sysdeps/x86_64/fpu/e_sqrt.c b/libc/sysdeps/x86_64/fpu/e_sqrt.c
new file mode 100644
index 000000000..d588a8b10
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_sqrt.c
@@ -0,0 +1,30 @@
+/* Square root of floating point number.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math_private.h>
+
+double
+__ieee754_sqrt (double x)
+{
+ double res;
+
+ asm ("sqrtsd %0, %1" : "=x" (res) : "x" (x));
+
+ return res;
+}
diff --git a/libc/sysdeps/x86_64/fpu/e_sqrtf.c b/libc/sysdeps/x86_64/fpu/e_sqrtf.c
new file mode 100644
index 000000000..f7801f05d
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_sqrtf.c
@@ -0,0 +1,30 @@
+/* Square root of floating point number.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math_private.h>
+
+float
+__ieee754_sqrtf (float x)
+{
+ float res;
+
+ asm ("sqrtss %0, %1" : "=x" (res) : "x" (x));
+
+ return res;
+}
diff --git a/libc/sysdeps/x86_64/fpu/e_sqrtl.c b/libc/sysdeps/x86_64/fpu/e_sqrtl.c
new file mode 100644
index 000000000..90e4e164e
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/e_sqrtl.c
@@ -0,0 +1 @@
+#include "sysdeps/i386/fpu/e_sqrtl.c"
diff --git a/libc/sysdeps/x86_64/fpu/fclrexcpt.c b/libc/sysdeps/x86_64/fpu/fclrexcpt.c
new file mode 100644
index 000000000..4fc3bfbdc
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/fclrexcpt.c
@@ -0,0 +1,52 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+feclearexcept (int excepts)
+{
+ fenv_t temp;
+ unsigned int mxcsr;
+
+ /* Mask out unsupported bits/exceptions. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Bah, we have to clear selected exceptions. Since there is no
+ `fldsw' instruction we have to do it the hard way. */
+ __asm__ ("fnstenv %0" : "=m" (*&temp));
+
+ /* Clear the relevant bits. */
+ temp.__status_word &= excepts ^ FE_ALL_EXCEPT;
+
+ /* Put the new data in effect. */
+ __asm__ ("fldenv %0" : : "m" (*&temp));
+
+ /* And the same procedure for SSE. */
+ __asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
+
+ /* Clear the relevant bits. */
+ mxcsr &= ~excepts;
+
+ /* And put them into effect. */
+ __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
+
+ /* Success. */
+ return 0;
+}
diff --git a/libc/sysdeps/x86_64/fpu/fedisblxcpt.c b/libc/sysdeps/x86_64/fpu/fedisblxcpt.c
new file mode 100644
index 000000000..e8157da12
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/fedisblxcpt.c
@@ -0,0 +1,49 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fedisableexcept (int excepts)
+{
+ unsigned short int new_exc, old_exc;
+ unsigned int new, old;
+
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Get the current control word of the x87 FPU. */
+ __asm__ ("fstcw %0" : "=m" (*&new_exc));
+
+ old_exc = (~new_exc) & FE_ALL_EXCEPT;
+
+ new_exc |= excepts;
+ __asm__ ("fldcw %0" : : "m" (*&new_exc));
+
+ /* And now the same for the SSE MXCSR register. */
+ __asm__ ("stmxcsr %0" : "=m" (*&new));
+
+ /* The SSE exception masks are shifted by 7 bits. */
+ old = (~new) & (FE_ALL_EXCEPT << 7);
+
+ new |= excepts << 7;
+ __asm__ ("ldmxcsr %0" : : "m" (*&new));
+
+ return old_exc;
+}
diff --git a/libc/sysdeps/x86_64/fpu/feenablxcpt.c b/libc/sysdeps/x86_64/fpu/feenablxcpt.c
new file mode 100644
index 000000000..43259d0cf
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/feenablxcpt.c
@@ -0,0 +1,49 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+feenableexcept (int excepts)
+{
+ unsigned short int new_exc, old_exc;
+ unsigned int new, old;
+
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Get the current control word of the x87 FPU. */
+ __asm__ ("fstcw %0" : "=m" (*&new_exc));
+
+ old_exc = (~new_exc) & FE_ALL_EXCEPT;
+
+ new_exc &= ~excepts;
+ __asm__ ("fldcw %0" : : "m" (*&new_exc));
+
+ /* And now the same for the SSE MXCSR register. */
+ __asm__ ("stmxcsr %0" : "=m" (*&new));
+
+ /* The SSE exception masks are shifted by 7 bits. */
+ old = (~new) & (FE_ALL_EXCEPT << 7);
+
+ new &= ~(excepts << 7);
+ __asm__ ("ldmxcsr %0" : : "m" (*&new));
+
+ return old_exc;
+}
diff --git a/libc/sysdeps/x86_64/fpu/fegetenv.c b/libc/sysdeps/x86_64/fpu/fegetenv.c
new file mode 100644
index 000000000..fa5a8dadc
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/fegetenv.c
@@ -0,0 +1,30 @@
+/* Store current floating-point environment.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetenv (fenv_t *envp)
+{
+ __asm__ ("fnstenv %0\n"
+ "stmxcsr %1" : "=m" (*envp), "=m" (envp->__mxcsr));
+
+ /* Success. */
+ return 0;
+}
diff --git a/libc/sysdeps/x86_64/fpu/fegetexcept.c b/libc/sysdeps/x86_64/fpu/fegetexcept.c
new file mode 100644
index 000000000..04df4b66a
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/fegetexcept.c
@@ -0,0 +1,32 @@
+/* Get enabled floating-point exceptions.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2001.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetexcept (void)
+{
+ unsigned short int exc;
+
+ /* Get the current control word. */
+ __asm__ ("fstcw %0" : "=m" (*&exc));
+
+ return (~exc) & FE_ALL_EXCEPT;
+}
diff --git a/libc/sysdeps/x86_64/fpu/fegetround.c b/libc/sysdeps/x86_64/fpu/fegetround.c
new file mode 100644
index 000000000..f237b18d1
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/fegetround.c
@@ -0,0 +1,33 @@
+/* Return current rounding direction.
+ Copyright (C) 1997, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetround (void)
+{
+ int cw;
+ /* We only check the x87 FPU unit. The SSE unit should be the same
+ - and if it's not the same there's no way to signal it. */
+
+ __asm__ ("fnstcw %0" : "=m" (*&cw));
+
+ return cw & 0xc00;
+}
diff --git a/libc/sysdeps/x86_64/fpu/feholdexcpt.c b/libc/sysdeps/x86_64/fpu/feholdexcpt.c
new file mode 100644
index 000000000..a9b21a3c2
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/feholdexcpt.c
@@ -0,0 +1,42 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ unsigned short int work;
+ unsigned int mxcsr;
+
+ /* Store the environment. */
+ __asm__ ("fnstenv %0\n"
+ "stmxcsr %1" : "=m" (*envp), "=m" (envp->__mxcsr));
+
+ /* Now set all exceptions to non-stop, first the x87 FPU. */
+ work = envp->__control_word | 0x3f;
+ __asm__ ("fldcw %0" : : "m" (*&work));
+
+ /* Set the SSE MXCSR register. */
+ mxcsr = envp->__mxcsr | 0x1f80;
+ __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
+
+ return 0;
+}
+libm_hidden_def (feholdexcept)
diff --git a/libc/sysdeps/x86_64/fpu/fesetenv.c b/libc/sysdeps/x86_64/fpu/fesetenv.c
new file mode 100644
index 000000000..8a3b7a074
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/fesetenv.c
@@ -0,0 +1,89 @@
+/* Install given floating-point environment.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <assert.h>
+
+
+int
+fesetenv (const fenv_t *envp)
+{
+ fenv_t temp;
+
+ /* Install the environment specified by ENVP. But there are a few
+ values which we do not want to come from the saved environment.
+ Therefore, we get the current environment and replace the values
+ we want to use from the environment specified by the parameter. */
+ __asm__ ("fnstenv %0\n"
+ "stmxcsr %1" : "=m" (*&temp), "=m" (*&temp.__mxcsr));
+
+ if (envp == FE_DFL_ENV)
+ {
+ temp.__control_word |= FE_ALL_EXCEPT;
+ temp.__control_word &= ~FE_TOWARDZERO;
+ temp.__status_word &= ~FE_ALL_EXCEPT;
+ temp.__eip = 0;
+ temp.__cs_selector = 0;
+ temp.__opcode = 0;
+ temp.__data_offset = 0;
+ temp.__data_selector = 0;
+ /* Set mask for SSE MXCSR. */
+ temp.__mxcsr |= (FE_ALL_EXCEPT << 7);
+ /* Set rounding to FE_TONEAREST. */
+ temp.__mxcsr &= ~ 0x6000;
+ temp.__mxcsr |= (FE_TONEAREST << 3);
+ }
+ else if (envp == FE_NOMASK_ENV)
+ {
+ temp.__control_word &= ~(FE_ALL_EXCEPT | FE_TOWARDZERO);
+ temp.__status_word &= ~FE_ALL_EXCEPT;
+ temp.__eip = 0;
+ temp.__cs_selector = 0;
+ temp.__opcode = 0;
+ temp.__data_offset = 0;
+ temp.__data_selector = 0;
+ /* Set mask for SSE MXCSR. */
+ /* Set rounding to FE_TONEAREST. */
+ temp.__mxcsr &= ~ 0x6000;
+ temp.__mxcsr |= (FE_TONEAREST << 3);
+ /* Do not mask exceptions. */
+ temp.__mxcsr &= ~(FE_ALL_EXCEPT << 7);
+ }
+ else
+ {
+ temp.__control_word &= ~(FE_ALL_EXCEPT | FE_TOWARDZERO);
+ temp.__control_word |= (envp->__control_word
+ & (FE_ALL_EXCEPT | FE_TOWARDZERO));
+ temp.__status_word &= ~FE_ALL_EXCEPT;
+ temp.__status_word |= envp->__status_word & FE_ALL_EXCEPT;
+ temp.__eip = envp->__eip;
+ temp.__cs_selector = envp->__cs_selector;
+ temp.__opcode = envp->__opcode;
+ temp.__data_offset = envp->__data_offset;
+ temp.__data_selector = envp->__data_selector;
+ temp.__mxcsr = envp->__mxcsr;
+ }
+
+ __asm__ ("fldenv %0\n"
+ "ldmxcsr %1" : : "m" (temp), "m" (temp.__mxcsr));
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (fesetenv)
diff --git a/libc/sysdeps/x86_64/fpu/fesetround.c b/libc/sysdeps/x86_64/fpu/fesetround.c
new file mode 100644
index 000000000..408116eee
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/fesetround.c
@@ -0,0 +1,47 @@
+/* Set current rounding direction.
+ Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fesetround (int round)
+{
+ unsigned short int cw;
+ int mxcsr;
+
+ if ((round & ~0xc00) != 0)
+ /* ROUND is no valid rounding mode. */
+ return 1;
+
+ /* First set the x87 FPU. */
+ asm ("fnstcw %0" : "=m" (*&cw));
+ cw &= ~0xc00;
+ cw |= round;
+ asm ("fldcw %0" : : "m" (*&cw));
+
+ /* And now the MSCSR register for SSE, the precision is at different bit
+ positions in the different units, we need to shift it 3 bits. */
+ asm ("stmxcsr %0" : "=m" (*&mxcsr));
+ mxcsr &= ~ 0x6000;
+ mxcsr |= round << 3;
+ asm ("ldmxcsr %0" : : "m" (*&mxcsr));
+
+ return 0;
+}
+libm_hidden_def (fesetround)
diff --git a/libc/sysdeps/x86_64/fpu/fgetexcptflg.c b/libc/sysdeps/x86_64/fpu/fgetexcptflg.c
new file mode 100644
index 000000000..f0681dc9d
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/fgetexcptflg.c
@@ -0,0 +1,36 @@
+/* Store current representation for exceptions.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ fexcept_t temp;
+ unsigned int mxscr;
+
+ /* Get the current exceptions for the x87 FPU and SSE unit. */
+ __asm__ ("fnstsw %0\n"
+ "stmxcsr %1" : "=m" (*&temp), "=m" (*&mxscr));
+
+ *flagp = (temp | mxscr) & FE_ALL_EXCEPT & excepts;
+
+ /* Success. */
+ return 0;
+}
diff --git a/libc/sysdeps/x86_64/fpu/fraiseexcpt.c b/libc/sysdeps/x86_64/fpu/fraiseexcpt.c
new file mode 100644
index 000000000..d1d3c0330
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/fraiseexcpt.c
@@ -0,0 +1,120 @@
+/* Raise given exceptions.
+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <math.h>
+
+int
+feraiseexcept (int excepts)
+{
+ /* Raise exceptions represented by EXPECTS. But we must raise only
+ one signal at a time. It is important that if the overflow/underflow
+ exception and the inexact exception are given at the same time,
+ the overflow/underflow exception follows the inexact exception. */
+
+ /* First: invalid exception. */
+ if ((FE_INVALID & excepts) != 0)
+ {
+ /* One example of a invalid operation is 0.0 / 0.0. */
+ float f = 0.0;
+
+ __asm__ __volatile__ ("divss %0, %0 " : : "x" (f));
+ (void) &f;
+ }
+
+ /* Next: division by zero. */
+ if ((FE_DIVBYZERO & excepts) != 0)
+ {
+ float f = 1.0;
+ float g = 0.0;
+
+ __asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));
+ (void) &f;
+ }
+
+ /* Next: overflow. */
+ if ((FE_OVERFLOW & excepts) != 0)
+ {
+ /* XXX: Is it ok to only set the x87 FPU? */
+ /* There is no way to raise only the overflow flag. Do it the
+ hard way. */
+ fenv_t temp;
+
+ /* Bah, we have to clear selected exceptions. Since there is no
+ `fldsw' instruction we have to do it the hard way. */
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
+
+ /* Set the relevant bits. */
+ temp.__status_word |= FE_OVERFLOW;
+
+ /* Put the new data in effect. */
+ __asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
+
+ /* And raise the exception. */
+ __asm__ __volatile__ ("fwait");
+ }
+
+ /* Next: underflow. */
+ if ((FE_UNDERFLOW & excepts) != 0)
+ {
+ /* XXX: Is it ok to only set the x87 FPU? */
+ /* There is no way to raise only the underflow flag. Do it the
+ hard way. */
+ fenv_t temp;
+
+ /* Bah, we have to clear selected exceptions. Since there is no
+ `fldsw' instruction we have to do it the hard way. */
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
+
+ /* Set the relevant bits. */
+ temp.__status_word |= FE_UNDERFLOW;
+
+ /* Put the new data in effect. */
+ __asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
+
+ /* And raise the exception. */
+ __asm__ __volatile__ ("fwait");
+ }
+
+ /* Last: inexact. */
+ if ((FE_INEXACT & excepts) != 0)
+ {
+ /* XXX: Is it ok to only set the x87 FPU? */
+ /* There is no way to raise only the inexact flag. Do it the
+ hard way. */
+ fenv_t temp;
+
+ /* Bah, we have to clear selected exceptions. Since there is no
+ `fldsw' instruction we have to do it the hard way. */
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
+
+ /* Set the relevant bits. */
+ temp.__status_word |= FE_INEXACT;
+
+ /* Put the new data in effect. */
+ __asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
+
+ /* And raise the exception. */
+ __asm__ __volatile__ ("fwait");
+ }
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (feraiseexcept)
diff --git a/libc/sysdeps/x86_64/fpu/fsetexcptflg.c b/libc/sysdeps/x86_64/fpu/fsetexcptflg.c
new file mode 100644
index 000000000..fe1d40685
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/fsetexcptflg.c
@@ -0,0 +1,54 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <math.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fenv_t temp;
+ unsigned int mxcsr;
+
+ /* XXX: Do we really need to set both the exception in both units?
+ Shouldn't it be enough to set only the SSE unit? */
+
+ /* Get the current x87 FPU environment. We have to do this since we
+ cannot separately set the status word. */
+ __asm__ ("fnstenv %0" : "=m" (*&temp));
+
+ temp.__status_word &= ~(excepts & FE_ALL_EXCEPT);
+ temp.__status_word |= *flagp & excepts & FE_ALL_EXCEPT;
+
+ /* Store the new status word (along with the rest of the environment.
+ Possibly new exceptions are set but they won't get executed unless
+ the next floating-point instruction. */
+ __asm__ ("fldenv %0" : : "m" (*&temp));
+
+ /* And now the same for SSE. */
+ __asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
+
+ mxcsr &= ~(excepts & FE_ALL_EXCEPT);
+ mxcsr |= *flagp & excepts & FE_ALL_EXCEPT;
+
+ __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
+
+ /* Success. */
+ return 0;
+}
diff --git a/libc/sysdeps/x86_64/fpu/ftestexcept.c b/libc/sysdeps/x86_64/fpu/ftestexcept.c
new file mode 100644
index 000000000..091c25157
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/ftestexcept.c
@@ -0,0 +1,33 @@
+/* Test exception in current environment.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fetestexcept (int excepts)
+{
+ int temp;
+ unsigned int mxscr;
+
+ /* Get current exceptions. */
+ __asm__ ("fnstsw %0\n"
+ "stmxcsr %1" : "=m" (*&temp), "=m" (*&mxscr));
+
+ return (temp | mxscr) & excepts & FE_ALL_EXCEPT;
+}
diff --git a/libc/sysdeps/x86_64/fpu/libm-test-ulps b/libc/sysdeps/x86_64/fpu/libm-test-ulps
new file mode 100644
index 000000000..0ced4be7b
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/libm-test-ulps
@@ -0,0 +1,1308 @@
+# Begin of automatic generation
+
+# acos
+Test "acos (0.75) == 0.722734247813415611178377352641333362":
+ildouble: 1
+ldouble: 1
+
+# asin
+Test "asin (-0.5) == -pi/6":
+ildouble: 1
+ldouble: 1
+Test "asin (-1.0) == -pi/2":
+ildouble: 1
+ldouble: 1
+Test "asin (0.5) == pi/6":
+ildouble: 1
+ldouble: 1
+Test "asin (0.75) == 0.848062078981481008052944338998418080":
+ildouble: 1
+ldouble: 1
+Test "asin (1.0) == pi/2":
+ildouble: 1
+ldouble: 1
+
+# atan2
+Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025":
+float: 1
+ifloat: 1
+Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025":
+float: 1
+ifloat: 1
+Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772":
+float: 1
+ifloat: 1
+
+# atanh
+Test "atanh (0.75) == 0.972955074527656652552676371721589865":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# cacos
+Test "Imaginary part of: cacos (0.75 + 1.25 i) == 1.11752014915610270578240049553777969 - 1.13239363160530819522266333696834467 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+# cacosh
+Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+ildouble: 6
+ldouble: 6
+Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 1
+ldouble: 1
+Test "Real part of: cacosh (0.75 + 1.25 i) == 1.13239363160530819522266333696834467 + 1.11752014915610270578240049553777969 i":
+ildouble: 1
+ldouble: 1
+
+# casin
+Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+# casinh
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 5
+ldouble: 5
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 5
+ldouble: 5
+Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ldouble: 1
+ildouble: 1
+
+# catan
+Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+float: 3
+ifloat: 3
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+float: 4
+ifloat: 4
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 4
+idouble: 4
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+float: 4
+ifloat: 4
+Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+float: 6
+ifloat: 6
+
+# cbrt
+Test "cbrt (-0.001) == -0.1":
+ildouble: 1
+ldouble: 1
+Test "cbrt (-27.0) == -3.0":
+double: 1
+idouble: 1
+Test "cbrt (0.75) == 0.908560296416069829445605878163630251":
+double: 1
+idouble: 1
+Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# ccos
+Test "Real part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+ildouble: 1
+ldouble: 1
+float: 1
+ifloat: 1
+
+# ccosh
+Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+float: 1
+ifloat: 1
+
+# cexp
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+float: 1
+ifloat: 1
+Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+ildouble: 1
+ldouble: 1
+
+# clog
+Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+float: 3
+ifloat: 3
+Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# cos
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "cos (pi/2) == 0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "cos (0.80190127184058835) == 0.69534156199418473":
+double: 1
+idouble: 1
+
+# cpow
+Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+ldouble: 1
+ildouble: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+ildouble: 5
+ldouble: 5
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+ildouble: 2
+ldouble: 2
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 3
+ldouble: 3
+Test "Real part of: cpow (2 + 0 i, 10 + 0 i) == 1024.0 + 0.0 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# csin
+Test "Real part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csin (-2 - 3 i) == -9.15449914691142957346729954460983256 + 4.16890695996656435075481305885375484 i":
+double: 1
+idouble: 1
+
+# csinh
+Test "Real part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+
+# csqrt
+Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+
+# ctan
+Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+double: 1
+idouble: 1
+ildouble: 439
+ldouble: 439
+Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Real part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+float: 2
+ifloat: 2
+ildouble: 5
+ldouble: 5
+double: 1
+idouble: 1
+Test "Imaginary part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+ildouble: 25
+ldouble: 25
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+ifloat: 1
+Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+ildouble: 1
+ldouble: 1
+double: 1
+idouble: 1
+
+# erf
+Test "erf (1.25) == 0.922900128256458230136523481197281140":
+double: 1
+idouble: 1
+
+# erfc
+Test "erfc (1.25) == 0.0770998717435417698634765188027188596":
+ildouble: 1
+ldouble: 1
+Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
+double: 1
+idouble: 1
+Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# exp10
+Test "exp10 (-1) == 0.1":
+ildouble: 1
+ldouble: 1
+float: 1
+ifloat: 1
+double: 2
+idouble: 2
+Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+ildouble: 2
+ldouble: 2
+float: 1
+ifloat: 1
+double: 1
+idouble: 1
+Test "exp10 (3) == 1000":
+ildouble: 8
+ldouble: 8
+float: 2
+ifloat: 2
+double: 6
+idouble: 6
+
+# expm1
+Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+double: 1
+idouble: 1
+Test "expm1 (1) == M_El - 1.0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# gamma
+Test "gamma (-0.5) == log(2*sqrt(pi))":
+ildouble: 1
+ldouble: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+
+# j0
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "j0 (0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+# j1
+Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# jn
+Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (0, 0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, -1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "jn (10, 1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 2
+ldouble: 2
+Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+float: 4
+ifloat: 4
+ildouble: 1
+ldouble: 1
+Test "jn (3, -1.0) == -0.0195633539826684059189053216217515083":
+ildouble: 1
+ldouble: 1
+Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 1.0) == 0.0195633539826684059189053216217515083":
+ildouble: 1
+ldouble: 1
+Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# lgamma
+Test "lgamma (-0.5) == log(2*sqrt(pi))":
+ildouble: 1
+ldouble: 1
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# log10
+Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+ildouble: 1
+ldouble: 1
+float: 2
+ifloat: 2
+double: 1
+idouble: 1
+Test "log10 (e) == log10(e)":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# log1p
+Test "log1p (-0.25) == -0.287682072451780927439219005993827432":
+float: 1
+ifloat: 1
+
+# sincos
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
+float: 1
+ifloat: 1
+Test "sincos (0.80190127184058835, &sin_res, &cos_res) puts 0.69534156199418473 in cos_res":
+double: 1
+idouble: 1
+
+# tan
+Test "tan (pi/4) == 1":
+double: 1
+idouble: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+ifloat: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "tgamma (4) == 6":
+ildouble: 1
+ldouble: 1
+
+# y0
+Test "y0 (0.125) == -1.38968062514384052915582277745018693":
+ildouble: 1
+ldouble: 1
+Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# y1
+Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "y1 (1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+# yn
+Test "yn (0, 0.125) == -1.38968062514384052915582277745018693":
+ildouble: 1
+ldouble: 1
+Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "yn (1, 2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+double: 1
+idouble: 1
+ildouble: 2
+ldouble: 2
+Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 4
+ldouble: 4
+Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+double: 1
+idouble: 1
+Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+double: 2
+idouble: 2
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+double: 1
+idouble: 1
+
+# Maximal error of functions:
+Function: "acos":
+ildouble: 1
+ldouble: 1
+
+Function: "asin":
+ildouble: 1
+ldouble: 1
+
+Function: "atan2":
+float: 1
+ifloat: 1
+
+Function: "atanh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "cacos":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cacosh":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+ildouble: 6
+ldouble: 6
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "casin":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 5
+ldouble: 5
+
+Function: Real part of "catan":
+float: 4
+ifloat: 4
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "catanh":
+double: 4
+idouble: 4
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catanh":
+float: 6
+ifloat: 6
+
+Function: "cbrt":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccos":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cexp":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "cexp":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "clog":
+float: 3
+ifloat: 3
+
+Function: Real part of "clog10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cpow":
+double: 2
+float: 5
+idouble: 2
+ifloat: 5
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csin":
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csqrt":
+float: 1
+ifloat: 1
+
+Function: Real part of "ctan":
+double: 1
+idouble: 1
+ildouble: 439
+ldouble: 439
+
+Function: Imaginary part of "ctan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "ctanh":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "ctanh":
+float: 1
+ifloat: 1
+ildouble: 25
+ldouble: 25
+double: 1
+idouble: 1
+
+Function: "erf":
+double: 1
+idouble: 1
+
+Function: "erfc":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "exp10":
+ildouble: 8
+ldouble: 8
+float: 2
+ifloat: 2
+double: 6
+idouble: 6
+
+Function: "expm1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "gamma":
+ildouble: 1
+ldouble: 1
+
+Function: "hypot":
+float: 1
+ifloat: 1
+
+Function: "j0":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "jn":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 2
+ldouble: 2
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log10":
+float: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+double: 1
+idouble: 1
+
+Function: "log1p":
+float: 1
+ifloat: 1
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "tan":
+double: 1
+idouble: 1
+
+Function: "tgamma":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+# end of automatic generation
diff --git a/libc/sysdeps/x86_64/fpu/math_ldbl.h b/libc/sysdeps/x86_64/fpu/math_ldbl.h
new file mode 100644
index 000000000..b9ff8dada
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/math_ldbl.h
@@ -0,0 +1,79 @@
+#ifndef _MATH_PRIVATE_H_
+#error "Never use <math_ldbl.h> directly; include <math_private.h> instead."
+#endif
+
+/* A union which permits us to convert between a long double and
+ three 32 bit ints. */
+
+typedef union
+{
+ long double value;
+ struct
+ {
+ u_int32_t lsw;
+ u_int32_t msw;
+ int sign_exponent:16;
+ unsigned int empty1:16;
+ unsigned int empty0:32;
+ } parts;
+} ieee_long_double_shape_type;
+
+/* Get three 32 bit ints from a double. */
+
+#define GET_LDOUBLE_WORDS(exp,ix0,ix1,d) \
+do { \
+ ieee_long_double_shape_type ew_u; \
+ ew_u.value = (d); \
+ (exp) = ew_u.parts.sign_exponent; \
+ (ix0) = ew_u.parts.msw; \
+ (ix1) = ew_u.parts.lsw; \
+} while (0)
+
+/* Set a double from two 32 bit ints. */
+
+#define SET_LDOUBLE_WORDS(d,exp,ix0,ix1) \
+do { \
+ ieee_long_double_shape_type iw_u; \
+ iw_u.parts.sign_exponent = (exp); \
+ iw_u.parts.msw = (ix0); \
+ iw_u.parts.lsw = (ix1); \
+ (d) = iw_u.value; \
+} while (0)
+
+/* Get the more significant 32 bits of a long double mantissa. */
+
+#define GET_LDOUBLE_MSW(v,d) \
+do { \
+ ieee_long_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ (v) = sh_u.parts.msw; \
+} while (0)
+
+/* Set the more significant 32 bits of a long double mantissa from an int. */
+
+#define SET_LDOUBLE_MSW(d,v) \
+do { \
+ ieee_long_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ sh_u.parts.msw = (v); \
+ (d) = sh_u.value; \
+} while (0)
+
+/* Get int from the exponent of a long double. */
+
+#define GET_LDOUBLE_EXP(exp,d) \
+do { \
+ ieee_long_double_shape_type ge_u; \
+ ge_u.value = (d); \
+ (exp) = ge_u.parts.sign_exponent; \
+} while (0)
+
+/* Set exponent of a long double from an int. */
+
+#define SET_LDOUBLE_EXP(d,exp) \
+do { \
+ ieee_long_double_shape_type se_u; \
+ se_u.value = (d); \
+ se_u.parts.sign_exponent = (exp); \
+ (d) = se_u.value; \
+} while (0)
diff --git a/libc/sysdeps/x86_64/fpu/printf_fphex.c b/libc/sysdeps/x86_64/fpu/printf_fphex.c
new file mode 100644
index 000000000..b701b20b8
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/printf_fphex.c
@@ -0,0 +1,92 @@
+/* Print floating point number in hexadecimal notation according to ISO C99.
+ Copyright (C) 1997,1998,1999,2000,2001,2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef LONG_DOUBLE_DENORM_BIAS
+# define LONG_DOUBLE_DENORM_BIAS (IEEE854_LONG_DOUBLE_BIAS - 1)
+#endif
+
+#define PRINT_FPHEX_LONG_DOUBLE \
+do { \
+ /* The "strange" 80 bit format on ix86 and m68k has an explicit \
+ leading digit in the 64 bit mantissa. */ \
+ unsigned long long int num; \
+ \
+ \
+ num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \
+ | fpnum.ldbl.ieee.mantissa1); \
+ \
+ zero_mantissa = num == 0; \
+ \
+ if (sizeof (unsigned long int) > 6) \
+ { \
+ numstr = _itoa_word (num, numbuf + sizeof numbuf, 16, \
+ info->spec == 'A'); \
+ wnumstr = _itowa_word (num, \
+ wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),\
+ 16, info->spec == 'A'); \
+ } \
+ else \
+ { \
+ numstr = _itoa (num, numbuf + sizeof numbuf, 16, info->spec == 'A');\
+ wnumstr = _itowa (num, \
+ wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t), \
+ 16, info->spec == 'A'); \
+ } \
+ \
+ /* Fill with zeroes. */ \
+ while (numstr > numbuf + (sizeof numbuf - 64 / 4)) \
+ { \
+ *--numstr = '0'; \
+ *--wnumstr = L'0'; \
+ } \
+ \
+ /* We use a full nibble for the leading digit. */ \
+ leading = *numstr++; \
+ \
+ /* We have 3 bits from the mantissa in the leading nibble. \
+ Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'. */ \
+ exponent = fpnum.ldbl.ieee.exponent; \
+ \
+ if (exponent == 0) \
+ { \
+ if (zero_mantissa) \
+ expnegative = 0; \
+ else \
+ { \
+ /* This is a denormalized number. */ \
+ expnegative = 1; \
+ /* This is a hook for the m68k long double format, where the \
+ exponent bias is the same for normalized and denormalized \
+ numbers. */ \
+ exponent = LONG_DOUBLE_DENORM_BIAS + 3; \
+ } \
+ } \
+ else if (exponent >= IEEE854_LONG_DOUBLE_BIAS + 3) \
+ { \
+ expnegative = 0; \
+ exponent -= IEEE854_LONG_DOUBLE_BIAS + 3; \
+ } \
+ else \
+ { \
+ expnegative = 1; \
+ exponent = -(exponent - (IEEE854_LONG_DOUBLE_BIAS + 3)); \
+ } \
+} while (0)
+
+#include <stdio-common/printf_fphex.c>
diff --git a/libc/sysdeps/x86_64/fpu/s_atanl.c b/libc/sysdeps/x86_64/fpu/s_atanl.c
new file mode 100644
index 000000000..fd4a455b5
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_atanl.c
@@ -0,0 +1 @@
+#include "sysdeps/i386/fpu/s_atanl.c"
diff --git a/libc/sysdeps/x86_64/fpu/s_ceill.S b/libc/sysdeps/x86_64/fpu/s_ceill.S
new file mode 100644
index 000000000..efc8dd995
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_ceill.S
@@ -0,0 +1,31 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Changes for x86-64 by Andreas Jaeger <aj@suse.de>
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+
+ENTRY(__ceill)
+ fldt 8(%rsp)
+
+ fstcw -4(%rsp) /* store fpu control word */
+
+ /* We use here %edx although only the low 1 bits are defined.
+ But none of the operations should care and they are faster
+ than the 16 bit operations. */
+ movl $0x0800,%edx /* round towards +oo */
+ orl -4(%rsp),%edx
+ andl $0xfbff,%edx
+ movl %edx,-8(%rsp)
+ fldcw -8(%rsp) /* load modified control word */
+
+ frndint /* round */
+
+ fldcw -4(%rsp) /* restore original control word */
+
+ ret
+END (__ceill)
+weak_alias (__ceill, ceill)
diff --git a/libc/sysdeps/x86_64/fpu/s_copysign.S b/libc/sysdeps/x86_64/fpu/s_copysign.S
new file mode 100644
index 000000000..f1ebcf8bf
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_copysign.S
@@ -0,0 +1,52 @@
+/* copy sign, double version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(signmask,@object)
+signmask:
+ .byte 0, 0, 0, 0, 0, 0, 0, 0x80
+ .byte 0, 0, 0, 0, 0, 0, 0, 0
+othermask:
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
+ .byte 0, 0, 0, 0, 0, 0, 0, 0
+ ASM_SIZE_DIRECTIVE(othermask)
+
+#ifdef PIC
+#define MO(op) op##(%rip)
+#else
+#define MO(op) op
+#endif
+
+ENTRY(__copysign)
+ andpd MO(othermask),%xmm0
+ andpd MO(signmask),%xmm1
+ orpd %xmm1,%xmm0
+ ret
+END (__copysign)
+
+weak_alias (__copysign, copysign)
diff --git a/libc/sysdeps/x86_64/fpu/s_copysignf.S b/libc/sysdeps/x86_64/fpu/s_copysignf.S
new file mode 100644
index 000000000..f5dc5f78a
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_copysignf.S
@@ -0,0 +1,49 @@
+/* copy sign, double version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(mask,@object)
+mask:
+ .byte 0xff, 0xff, 0xff, 0x7f
+ ASM_SIZE_DIRECTIVE(mask)
+
+#ifdef PIC
+#define MO(op) op##(%rip)
+#else
+#define MO(op) op
+#endif
+
+ENTRY(__copysignf)
+ movss MO(mask),%xmm3
+ andps %xmm3,%xmm0
+ andnps %xmm1,%xmm3
+ orps %xmm3,%xmm0
+ retq
+END (__copysignf)
+
+weak_alias (__copysignf, copysignf)
diff --git a/libc/sysdeps/x86_64/fpu/s_copysignl.S b/libc/sysdeps/x86_64/fpu/s_copysignl.S
new file mode 100644
index 000000000..2ffd612d6
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_copysignl.S
@@ -0,0 +1,22 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>.
+ * Adopted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__copysignl)
+ movl 32(%rsp),%edx
+ movl 16(%rsp),%eax
+ andl $0x8000,%edx
+ andl $0x7fff,%eax
+ orl %edx,%eax
+ movl %eax,16(%rsp)
+ fldt 8(%rsp)
+ ret
+END (__copysignl)
+weak_alias (__copysignl, copysignl)
diff --git a/libc/sysdeps/x86_64/fpu/s_cosl.S b/libc/sysdeps/x86_64/fpu/s_cosl.S
new file mode 100644
index 000000000..6636fb5ec
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_cosl.S
@@ -0,0 +1,32 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__cosl)
+ fldt 8(%rsp)
+ fcos
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ ret
+ .align ALIGNARG(4)
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fcos
+ ret
+END (__cosl)
+weak_alias (__cosl, cosl)
diff --git a/libc/sysdeps/x86_64/fpu/s_expm1l.S b/libc/sysdeps/x86_64/fpu/s_expm1l.S
new file mode 100644
index 000000000..b4f5a3efd
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_expm1l.S
@@ -0,0 +1,84 @@
+/* ix87 specific implementation of exp(x)-1.
+ Copyright (C) 1996, 1997, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+ Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>.
+ Corrections by H.J. Lu (hjl@gnu.ai.mit.edu), 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+ /* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(minus1,@object)
+minus1: .double -1.0
+ ASM_SIZE_DIRECTIVE(minus1)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ ASM_TYPE_DIRECTIVE(l2e,@object)
+l2e: .tfloat 1.442695040888963407359924681002
+ ASM_SIZE_DIRECTIVE(l2e)
+
+#ifdef PIC
+#define MO(op) op##(%rip)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__expm1l)
+ fldt 8(%rsp) // x
+ fxam // Is NaN or +-Inf?
+ fstsw %ax
+ movb $0x45, %ch
+ andb %ah, %ch
+ cmpb $0x40, %ch
+ je 3f // If +-0, jump.
+ cmpb $0x05, %ch
+ je 2f // If +-Inf, jump.
+
+ fldt MO(l2e) // log2(e) : x
+ fmulp // log2(e)*x
+ fld %st // log2(e)*x : log2(e)*x
+ frndint // int(log2(e)*x) : log2(e)*x
+ fsubr %st, %st(1) // int(log2(e)*x) : fract(log2(e)*x)
+ fxch // fract(log2(e)*x) : int(log2(e)*x)
+ f2xm1 // 2^fract(log2(e)*x)-1 : int(log2(e)*x)
+ fscale // 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x)
+ fxch // int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fldl MO(one) // 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fscale // 2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fsubrl MO(one) // 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fstp %st(1) // 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
+ fsubrp %st, %st(1) // 2^(log2(e)*x)
+ ret
+
+2: testl $0x200, %eax // Test sign.
+ jz 3f // If positive, jump.
+ fstp %st
+ fldl MO(minus1) // Set result to -1.0.
+3: ret
+END(__expm1l)
+libm_hidden_def (__expm1l)
+weak_alias (__expm1l, expm1l)
diff --git a/libc/sysdeps/x86_64/fpu/s_fabs.c b/libc/sysdeps/x86_64/fpu/s_fabs.c
new file mode 100644
index 000000000..e5f70b784
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_fabs.c
@@ -0,0 +1,27 @@
+/* Absolute value of floating point number.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+double
+__fabs (double x)
+{
+ return __builtin_fabs (x);
+}
+weak_alias (__fabs, fabs)
diff --git a/libc/sysdeps/x86_64/fpu/s_fabsf.c b/libc/sysdeps/x86_64/fpu/s_fabsf.c
new file mode 100644
index 000000000..5e58c1131
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_fabsf.c
@@ -0,0 +1,27 @@
+/* Absolute value of floating point number.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <math.h>
+
+float
+__fabsf (float x)
+{
+ return __builtin_fabsf (x);
+}
+weak_alias (__fabsf, fabsf)
diff --git a/libc/sysdeps/x86_64/fpu/s_fabsl.S b/libc/sysdeps/x86_64/fpu/s_fabsl.S
new file mode 100644
index 000000000..3bee0f244
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_fabsl.S
@@ -0,0 +1,28 @@
+/* Absolute value of floating point number.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fabsl)
+ fldt 8(%rsp)
+ fabs
+ ret
+END(__fabsl)
+weak_alias (__fabsl, fabsl)
diff --git a/libc/sysdeps/x86_64/fpu/s_fdiml.S b/libc/sysdeps/x86_64/fpu/s_fdiml.S
new file mode 100644
index 000000000..d63ca00ef
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_fdiml.S
@@ -0,0 +1,44 @@
+/* Compute positive difference.
+ Copyright (C) 1997, 1998, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fdiml)
+ fldt 8(%rsp) // x
+ fldt 24(%rsp) // x : y
+
+ fucomi %st(1), %st
+ jp 1f
+
+ jc 3f
+ fstp %st(1)
+ fldz
+ jmp 2f
+
+3: fsubrp %st, %st(1)
+ ret
+
+1: fucomi %st(0), %st
+ fcmovnu %st(1), %st
+2: fstp %st(1)
+ ret
+END(__fdiml)
+weak_alias (__fdiml, fdiml)
diff --git a/libc/sysdeps/x86_64/fpu/s_finitel.S b/libc/sysdeps/x86_64/fpu/s_finitel.S
new file mode 100644
index 000000000..9e4979690
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_finitel.S
@@ -0,0 +1,16 @@
+/*
+ * Written by Joe Keane <jgk@jgk.org>.
+ * Adopted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__finitel)
+ movl 16(%rsp),%eax
+ orl $0xffff8000, %eax
+ incl %eax
+ shrl $31, %eax
+ ret
+END (__finitel)
+weak_alias (__finitel, finitel)
+hidden_def (__finitel)
diff --git a/libc/sysdeps/x86_64/fpu/s_floorl.S b/libc/sysdeps/x86_64/fpu/s_floorl.S
new file mode 100644
index 000000000..f9ecc388d
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_floorl.S
@@ -0,0 +1,30 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Changes for x86-64 by Andreas Jaeger <aj@suse.de>=09
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__floorl)
+ fldt 8(%rsp)
+
+ fstcw -4(%rsp) /* store fpu control word */
+
+ /* We use here %edx although only the low 1 bits are defined.
+ But none of the operations should care and they are faster
+ than the 16 bit operations. */
+ movl $0x400,%edx /* round towards -oo */
+ orl -4(%rsp),%edx
+ andl $0xf7ff,%edx
+ movl %edx,-8(%rsp)
+ fldcw -8(%rsp) /* load modified control word */
+
+ frndint /* round */
+
+ fldcw -4(%rsp) /* restore original control word */
+
+ ret
+END (__floorl)
+weak_alias (__floorl, floorl)
diff --git a/libc/sysdeps/x86_64/fpu/s_fmax.S b/libc/sysdeps/x86_64/fpu/s_fmax.S
new file mode 100644
index 000000000..b55d6f84c
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_fmax.S
@@ -0,0 +1,36 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmax)
+ ucomisd %xmm0, %xmm1
+ jp 1f // jump if unordered
+ maxsd %xmm1, %xmm0
+ jmp 2f
+
+1: ucomisd %xmm1, %xmm1 // Is xmm1 a NaN?
+ jp 2f // then return xmm0
+ movsd %xmm1, %xmm0 // otherwise return xmm1
+
+2: ret
+END(__fmax)
+weak_alias (__fmax, fmax)
diff --git a/libc/sysdeps/x86_64/fpu/s_fmaxf.S b/libc/sysdeps/x86_64/fpu/s_fmaxf.S
new file mode 100644
index 000000000..20d6fdd06
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_fmaxf.S
@@ -0,0 +1,36 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmaxf)
+ ucomiss %xmm0, %xmm1
+ jp 1f // jump if unordered
+ maxss %xmm1, %xmm0
+ jmp 2f
+
+1: ucomiss %xmm1, %xmm1 // Is xmm1 a NaN?
+ jp 2f // then return xmm0
+ movss %xmm1, %xmm0 // otherwise return xmm1
+
+2: ret
+END(__fmaxf)
+weak_alias (__fmaxf, fmaxf)
diff --git a/libc/sysdeps/x86_64/fpu/s_fmaxl.S b/libc/sysdeps/x86_64/fpu/s_fmaxl.S
new file mode 100644
index 000000000..557ef3a17
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_fmaxl.S
@@ -0,0 +1,40 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmaxl)
+ fldt 8(%rsp) // x
+ fldt 24(%rsp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fxch
+
+ fucomi %st(1), %st
+ fcmovb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fmaxl)
+weak_alias (__fmaxl, fmaxl)
diff --git a/libc/sysdeps/x86_64/fpu/s_fmin.S b/libc/sysdeps/x86_64/fpu/s_fmin.S
new file mode 100644
index 000000000..37a3daaab
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_fmin.S
@@ -0,0 +1,36 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmin)
+ ucomisd %xmm0, %xmm1
+ jp 1f // jump if unordered
+ minsd %xmm1, %xmm0
+ jmp 2f
+
+1: ucomisd %xmm1, %xmm1 // Is xmm1 a NaN?
+ jp 2f // then return xmm0
+ movsd %xmm1, %xmm0 // otherwise return xmm1
+
+2: ret
+END(__fmin)
+weak_alias (__fmin, fmin)
diff --git a/libc/sysdeps/x86_64/fpu/s_fminf.S b/libc/sysdeps/x86_64/fpu/s_fminf.S
new file mode 100644
index 000000000..8e6f04bc0
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_fminf.S
@@ -0,0 +1,36 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fminf)
+ ucomiss %xmm0, %xmm1
+ jp 1f // jump if unordered
+ minss %xmm1, %xmm0
+ jmp 2f
+
+1: ucomiss %xmm1, %xmm1 // Is xmm1 a NaN?
+ jp 2f // then return xmm0
+ movss %xmm1, %xmm0 // otherwise return xmm1
+
+2: ret
+END(__fminf)
+weak_alias (__fminf, fminf)
diff --git a/libc/sysdeps/x86_64/fpu/s_fminl.S b/libc/sysdeps/x86_64/fpu/s_fminl.S
new file mode 100644
index 000000000..cbe58f1b2
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_fminl.S
@@ -0,0 +1,38 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997, 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fminl)
+ fldt 8(%rsp) // x
+ fldt 24(%rsp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fucomi %st(1), %st
+ fcmovnb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fminl)
+weak_alias (__fminl, fminl)
diff --git a/libc/sysdeps/x86_64/fpu/s_fpclassifyl.c b/libc/sysdeps/x86_64/fpu/s_fpclassifyl.c
new file mode 100644
index 000000000..856854b0f
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_fpclassifyl.c
@@ -0,0 +1,2 @@
+#include <sysdeps/i386/fpu/s_fpclassifyl.c>
+
diff --git a/libc/sysdeps/x86_64/fpu/s_ilogbl.S b/libc/sysdeps/x86_64/fpu/s_ilogbl.S
new file mode 100644
index 000000000..f59040c11
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_ilogbl.S
@@ -0,0 +1,35 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__ilogbl)
+ fldt 8(%rsp)
+/* I added the following ugly construct because ilogb(+-Inf) is
+ required to return INT_MAX in ISO C99.
+ -- jakub@redhat.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+
+ fxtract
+ fstp %st
+
+ fistpl -4(%rsp)
+ fwait
+ movl -4(%rsp),%eax
+
+ ret
+
+1: fstp %st
+ movl $0x7fffffff, %eax
+ ret
+END (__ilogbl)
+weak_alias (__ilogbl, ilogbl)
diff --git a/libc/sysdeps/x86_64/fpu/s_isinfl.c b/libc/sysdeps/x86_64/fpu/s_isinfl.c
new file mode 100644
index 000000000..ca818b5e9
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_isinfl.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/fpu/s_isinfl.c>
diff --git a/libc/sysdeps/x86_64/fpu/s_isnanl.c b/libc/sysdeps/x86_64/fpu/s_isnanl.c
new file mode 100644
index 000000000..06e69c3ae
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_isnanl.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/fpu/s_isnanl.c>
diff --git a/libc/sysdeps/x86_64/fpu/s_llrint.S b/libc/sysdeps/x86_64/fpu/s_llrint.S
new file mode 100644
index 000000000..d496e4685
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_llrint.S
@@ -0,0 +1,31 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.d>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__llrint)
+ cvtsd2si %xmm0,%rax
+ ret
+END(__llrint)
+weak_alias (__llrint, llrint)
+strong_alias (__llrint, __lrint)
+weak_alias (__llrint, lrint)
diff --git a/libc/sysdeps/x86_64/fpu/s_llrintf.S b/libc/sysdeps/x86_64/fpu/s_llrintf.S
new file mode 100644
index 000000000..2e818b70a
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_llrintf.S
@@ -0,0 +1,31 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.d>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__llrintf)
+ cvtss2si %xmm0,%rax
+ ret
+END(__llrintf)
+weak_alias (__llrintf, llrintf)
+strong_alias (__llrintf, __lrintf)
+weak_alias (__llrintf, lrintf)
diff --git a/libc/sysdeps/x86_64/fpu/s_llrintl.S b/libc/sysdeps/x86_64/fpu/s_llrintl.S
new file mode 100644
index 000000000..2886dbe49
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_llrintl.S
@@ -0,0 +1,34 @@
+/* Round argument to nearest integral value according to current rounding
+ direction.
+ Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__llrintl)
+ fldt 8(%rsp)
+ fistpll -8(%rsp)
+ fwait
+ movq -8(%rsp),%rax
+ ret
+END(__llrintl)
+weak_alias (__llrintl, llrintl)
+strong_alias (__llrintl, __lrintl)
+weak_alias (__llrintl, lrintl)
+
diff --git a/libc/sysdeps/x86_64/fpu/s_log1pl.S b/libc/sysdeps/x86_64/fpu/s_log1pl.S
new file mode 100644
index 000000000..7fbd0e5aa
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_log1pl.S
@@ -0,0 +1,71 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: s_log1p.S,v 1.7 1995/05/09 00:10:58 jtc Exp $")
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ /* The fyl2xp1 can only be used for values in
+ -1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
+ 0.29 is a safe value.
+ */
+limit: .tfloat 0.29
+ /* Please note: we use a double value here. Since 1.0 has
+ an exact representation this does not effect the accuracy
+ but it helps to optimize the code. */
+one: .double 1.0
+
+/*
+ * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
+ * otherwise fyl2x with the needed extra computation.
+ */
+#ifdef PIC
+#define MO(op) op##(%rip)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__log1pl)
+ fldln2
+
+ fldt 8(%rsp)
+
+ fxam
+ fnstsw
+ fld %st
+ andb $1,%ah
+ jnz 3f // in case x is NaN or ±Inf
+4:
+ fabs
+ fldt MO(limit)
+ fcompp
+ fnstsw
+ andb $1,%ah
+ jz 2f
+
+ faddl MO(one)
+ fyl2x
+ ret
+
+2: fyl2xp1
+ ret
+
+3: jp 4b // in case x is ±Inf
+ fstp %st(1)
+ fstp %st(1)
+ ret
+
+END (__log1pl)
+weak_alias (__log1pl, log1pl)
diff --git a/libc/sysdeps/x86_64/fpu/s_logbl.c b/libc/sysdeps/x86_64/fpu/s_logbl.c
new file mode 100644
index 000000000..4791ba64e
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_logbl.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/fpu/s_logbl.c>
diff --git a/libc/sysdeps/x86_64/fpu/s_lrint.S b/libc/sysdeps/x86_64/fpu/s_lrint.S
new file mode 100644
index 000000000..dfc31359a
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_lrint.S
@@ -0,0 +1 @@
+/* Not needed, see s_llrint.S. */
diff --git a/libc/sysdeps/x86_64/fpu/s_lrintf.S b/libc/sysdeps/x86_64/fpu/s_lrintf.S
new file mode 100644
index 000000000..fcdc4dca9
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_lrintf.S
@@ -0,0 +1 @@
+/* Not needed, see s_llrintf.S. */
diff --git a/libc/sysdeps/x86_64/fpu/s_lrintl.S b/libc/sysdeps/x86_64/fpu/s_lrintl.S
new file mode 100644
index 000000000..ef9c45d00
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_lrintl.S
@@ -0,0 +1 @@
+/* Not needed, see s_llrintl.S. */
diff --git a/libc/sysdeps/x86_64/fpu/s_nearbyintl.S b/libc/sysdeps/x86_64/fpu/s_nearbyintl.S
new file mode 100644
index 000000000..dab2750a2
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_nearbyintl.S
@@ -0,0 +1,21 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+/* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>. */
+
+#include <machine/asm.h>
+
+ENTRY(__nearbyintl)
+ fldt 8(%rsp)
+ fnstcw -4(%rsp)
+ movl -4(%rsp), %eax
+ orl $0x20, %eax
+ movl %eax, -8(%rsp)
+ fldcw -8(%rsp)
+ frndint
+ fclex
+ fldcw -4(%rsp)
+ ret
+END (__nearbyintl)
+weak_alias (__nearbyintl, nearbyintl)
diff --git a/libc/sysdeps/x86_64/fpu/s_nextafterl.c b/libc/sysdeps/x86_64/fpu/s_nextafterl.c
new file mode 100644
index 000000000..f59f16848
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_nextafterl.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/fpu/s_nextafterl.c>
diff --git a/libc/sysdeps/x86_64/fpu/s_nexttoward.c b/libc/sysdeps/x86_64/fpu/s_nexttoward.c
new file mode 100644
index 000000000..aee2bb589
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_nexttoward.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/fpu/s_nexttoward.c>
diff --git a/libc/sysdeps/x86_64/fpu/s_nexttowardf.c b/libc/sysdeps/x86_64/fpu/s_nexttowardf.c
new file mode 100644
index 000000000..55e95f691
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_nexttowardf.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/fpu/s_nexttowardf.c>
diff --git a/libc/sysdeps/x86_64/fpu/s_rintl.c b/libc/sysdeps/x86_64/fpu/s_rintl.c
new file mode 100644
index 000000000..1cad42e92
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_rintl.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/fpu/s_rintl.c>
diff --git a/libc/sysdeps/x86_64/fpu/s_scalbnl.S b/libc/sysdeps/x86_64/fpu/s_scalbnl.S
new file mode 100644
index 000000000..d0e9301ee
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_scalbnl.S
@@ -0,0 +1,18 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Changes for long double by Ulrich Drepper <drepper@cygnus.com>
+ * Changes for x86-64 by Andreas Jaeger <aj@suse.de>=09
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__scalbnl)
+ movl %edi,-4(%rsp)
+ fildl -4(%rsp)
+ fldt 8(%rsp)
+ fscale
+ fstp %st(1)
+ ret
+END (__scalbnl)
+weak_alias (__scalbnl, scalbnl)
diff --git a/libc/sysdeps/x86_64/fpu/s_significandl.c b/libc/sysdeps/x86_64/fpu/s_significandl.c
new file mode 100644
index 000000000..a4ad98616
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_significandl.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/fpu/s_significandl.c>
diff --git a/libc/sysdeps/x86_64/fpu/s_sincos.S b/libc/sysdeps/x86_64/fpu/s_sincos.S
new file mode 100644
index 000000000..9a3361534
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_sincos.S
@@ -0,0 +1,61 @@
+/* Compute sine and cosine of argument.
+ Copyright (C) 1997, 2000, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define ANGLE PARMS
+#define SINP ANGLE+12
+#define COSP SINP+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__sincos))
+ ENTER
+
+ movsd %xmm0, -8(%rsp)
+ fldl -8(%rsp)
+ fsincos
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ fstpl (%rsi)
+ fstpl (%rdi)
+
+ LEAVE
+ retq
+
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fsincos
+ fstpl (%rsi)
+ fstpl (%rdi)
+
+ LEAVE
+ retq
+END (BP_SYM (__sincos))
+weak_alias (BP_SYM (__sincos), BP_SYM (sincos))
diff --git a/libc/sysdeps/x86_64/fpu/s_sincosl.S b/libc/sysdeps/x86_64/fpu/s_sincosl.S
new file mode 100644
index 000000000..b17eabe76
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_sincosl.S
@@ -0,0 +1,60 @@
+/* Compute sine and cosine of argument.
+ Copyright (C) 1997, 2000, 2001, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define ANGLE PARMS
+#define SINP ANGLE+12
+#define COSP SINP+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (__sincosl))
+ ENTER
+
+ fldt 8(%rsp)
+ fsincos
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ fstpt (%rsi)
+ fstpt (%rdi)
+
+ LEAVE
+ retq
+
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fsincos
+ fstpt (%rsi)
+ fstpt (%rdi)
+
+ LEAVE
+ retq
+END (BP_SYM (__sincosl))
+weak_alias (BP_SYM (__sincosl), BP_SYM (sincosl))
diff --git a/libc/sysdeps/x86_64/fpu/s_sinl.S b/libc/sysdeps/x86_64/fpu/s_sinl.S
new file mode 100644
index 000000000..181f112f4
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_sinl.S
@@ -0,0 +1,30 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__sinl)
+ fldt 8(%rsp)
+ fsin
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ ret
+ .align ALIGNARG(4)
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fsin
+ ret
+END (__sinl)
+weak_alias (__sinl, sinl)
diff --git a/libc/sysdeps/x86_64/fpu/s_tanl.S b/libc/sysdeps/x86_64/fpu/s_tanl.S
new file mode 100644
index 000000000..674e908ac
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_tanl.S
@@ -0,0 +1,33 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: $")
+
+ENTRY(__tanl)
+ fldt 8(%rsp)
+ fptan
+ fnstsw %ax
+ testl $0x400,%eax
+ jnz 1f
+ fstp %st(0)
+ ret
+1: fldpi
+ fadd %st(0)
+ fxch %st(1)
+2: fprem1
+ fstsw %ax
+ testl $0x400,%eax
+ jnz 2b
+ fstp %st(1)
+ fptan
+ fstp %st(0)
+ ret
+END (__tanl)
+weak_alias (__tanl, tanl)
diff --git a/libc/sysdeps/x86_64/fpu/s_truncl.S b/libc/sysdeps/x86_64/fpu/s_truncl.S
new file mode 100644
index 000000000..61acf9a25
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu/s_truncl.S
@@ -0,0 +1,34 @@
+/* Truncate long double value.
+ Copyright (C) 1997, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <machine/asm.h>
+
+ENTRY(__truncl)
+ fldt 8(%rsp)
+ fstcw -4(%rsp)
+ movl $0xc00, %edx
+ orl -4(%rsp), %edx
+ movl %edx, -8(%rsp)
+ fldcw -8(%rsp)
+ frndint
+ fldcw -4(%rsp)
+ ret
+END(__truncl)
+weak_alias (__truncl, truncl)
diff --git a/libc/sysdeps/x86_64/fpu_control.h b/libc/sysdeps/x86_64/fpu_control.h
new file mode 100644
index 000000000..3eae48e0d
--- /dev/null
+++ b/libc/sysdeps/x86_64/fpu_control.h
@@ -0,0 +1,101 @@
+/* FPU control word bits. x86-64 version.
+ Copyright (C) 1993,1995,1996,1997,1998,2000,2001,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Olaf Flebbe.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H 1
+
+/* Note that this file sets on x86-64 only the x87 FPU, it does not
+ touch the SSE unit. */
+
+/* Here is the dirty part. Set up your 387 through the control word
+ * (cw) register.
+ *
+ * 15-13 12 11-10 9-8 7-6 5 4 3 2 1 0
+ * | reserved | IC | RC | PC | reserved | PM | UM | OM | ZM | DM | IM
+ *
+ * IM: Invalid operation mask
+ * DM: Denormalized operand mask
+ * ZM: Zero-divide mask
+ * OM: Overflow mask
+ * UM: Underflow mask
+ * PM: Precision (inexact result) mask
+ *
+ * Mask bit is 1 means no interrupt.
+ *
+ * PC: Precision control
+ * 11 - round to extended precision
+ * 10 - round to double precision
+ * 00 - round to single precision
+ *
+ * RC: Rounding control
+ * 00 - rounding to nearest
+ * 01 - rounding down (toward - infinity)
+ * 10 - rounding up (toward + infinity)
+ * 11 - rounding toward zero
+ *
+ * IC: Infinity control
+ * That is for 8087 and 80287 only.
+ *
+ * The hardware default is 0x037f which we use.
+ */
+
+#include <features.h>
+
+/* masking of interrupts */
+#define _FPU_MASK_IM 0x01
+#define _FPU_MASK_DM 0x02
+#define _FPU_MASK_ZM 0x04
+#define _FPU_MASK_OM 0x08
+#define _FPU_MASK_UM 0x10
+#define _FPU_MASK_PM 0x20
+
+/* precision control */
+#define _FPU_EXTENDED 0x300 /* libm requires double extended precision. */
+#define _FPU_DOUBLE 0x200
+#define _FPU_SINGLE 0x0
+
+/* rounding control */
+#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
+#define _FPU_RC_DOWN 0x400
+#define _FPU_RC_UP 0x800
+#define _FPU_RC_ZERO 0xC00
+
+#define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */
+
+
+/* The fdlibm code requires strict IEEE double precision arithmetic,
+ and no interrupts for exceptions, rounding to nearest. */
+
+#define _FPU_DEFAULT 0x037f
+
+/* IEEE: same as above. */
+#define _FPU_IEEE 0x037f
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
+
+/* Macros for accessing the hardware control word. */
+#define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
+#define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* fpu_control.h */
diff --git a/libc/sysdeps/x86_64/hp-timing.c b/libc/sysdeps/x86_64/hp-timing.c
new file mode 100644
index 000000000..289ca4c3c
--- /dev/null
+++ b/libc/sysdeps/x86_64/hp-timing.c
@@ -0,0 +1,2 @@
+/* We can use the i686 implementation without changes. */
+#include <sysdeps/i386/i686/hp-timing.c>
diff --git a/libc/sysdeps/x86_64/hp-timing.h b/libc/sysdeps/x86_64/hp-timing.h
new file mode 100644
index 000000000..59a29abd4
--- /dev/null
+++ b/libc/sysdeps/x86_64/hp-timing.h
@@ -0,0 +1,41 @@
+/* High precision, low overhead timing functions. x86-64 version.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _HP_TIMING_H
+
+/* We can use some of the i686 implementation without changes. */
+# include <sysdeps/i386/i686/hp-timing.h>
+
+/* The "=A" constraint used in 32-bit mode does not work in 64-bit mode. */
+# undef HP_TIMING_NOW
+# define HP_TIMING_NOW(Var) \
+ ({ unsigned int _hi, _lo; \
+ asm volatile ("rdtsc" : "=a" (_lo), "=d" (_hi)); \
+ (Var) = ((unsigned long long int) _hi << 32) | _lo; })
+
+/* The funny business for 32-bit mode is not required here. */
+# undef HP_TIMING_ACCUM
+# define HP_TIMING_ACCUM(Sum, Diff) \
+ do { \
+ hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \
+ __asm__ __volatile__ ("lock; addq %1, %0" \
+ : "=m" (Sum) : "r" (__diff), "m" (Sum)); \
+ } while (0)
+
+#endif /* hp-timing.h */
diff --git a/libc/sysdeps/x86_64/htonl.S b/libc/sysdeps/x86_64/htonl.S
new file mode 100644
index 000000000..5aba9b3f2
--- /dev/null
+++ b/libc/sysdeps/x86_64/htonl.S
@@ -0,0 +1,35 @@
+/* Change byte order in word. For AMD x86-64.
+ Copyright (C) 1997, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+/*
+ INPUT PARAMETERS:
+ word %rdi
+*/
+
+ .text
+ENTRY (htonl)
+ movl %edi, %eax
+ bswap %eax
+ ret
+END (htonl)
+
+weak_alias (htonl, ntohl)
diff --git a/libc/sysdeps/x86_64/jmpbuf-offsets.h b/libc/sysdeps/x86_64/jmpbuf-offsets.h
new file mode 100644
index 000000000..46c776801
--- /dev/null
+++ b/libc/sysdeps/x86_64/jmpbuf-offsets.h
@@ -0,0 +1,30 @@
+/* Private macros for accessing __jmp_buf contents. x86-64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* We only need to save callee-saved registers plus stackpointer and
+ program counter. */
+#define JB_RBX 0
+#define JB_RBP 1
+#define JB_R12 2
+#define JB_R13 3
+#define JB_R14 4
+#define JB_R15 5
+#define JB_RSP 6
+#define JB_PC 7
+#define JB_SIZE (8*8)
diff --git a/libc/sysdeps/x86_64/jmpbuf-unwind.h b/libc/sysdeps/x86_64/jmpbuf-unwind.h
new file mode 100644
index 000000000..299a4a8d1
--- /dev/null
+++ b/libc/sysdeps/x86_64/jmpbuf-unwind.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <stdint.h>
+#include <unwind.h>
+#include <sysdep.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame
+ containing a local variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \
+ ((void *) (address) < (void *) demangle ((jmpbuf)[JB_RSP]))
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+static inline uintptr_t __attribute__ ((unused))
+_jmpbuf_sp (__jmp_buf regs)
+{
+ uintptr_t sp = regs[JB_RSP];
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (sp);
+#endif
+ return sp;
+}
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj))
+
+/* We use the normal longjmp for unwinding. */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/libc/sysdeps/x86_64/machine-gmon.h b/libc/sysdeps/x86_64/machine-gmon.h
new file mode 100644
index 000000000..d90d13d91
--- /dev/null
+++ b/libc/sysdeps/x86_64/machine-gmon.h
@@ -0,0 +1,39 @@
+/* x86-64-specific implementation of profiling support.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+/* We need a special version of the `mcount' function since for x86-64
+ so that we do not use __builtin_return_address (N) and avoid
+ clobbering of register. */
+
+
+/* We must not pollute the global namespace. */
+#define mcount_internal __mcount_internal
+
+void mcount_internal (u_long frompc, u_long selfpc);
+
+#define _MCOUNT_DECL(frompc, selfpc) \
+void mcount_internal (u_long frompc, u_long selfpc)
+
+
+/* Define MCOUNT as empty since we have the implementation in another
+ file. */
+#define MCOUNT
diff --git a/libc/sysdeps/x86_64/memcpy.S b/libc/sysdeps/x86_64/memcpy.S
new file mode 100644
index 000000000..5f06198b5
--- /dev/null
+++ b/libc/sysdeps/x86_64/memcpy.S
@@ -0,0 +1,101 @@
+/* Highly optimized version for x86-64.
+ Copyright (C) 1997, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Based on i586 version contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+/* BEWARE: `#ifdef memcpy' means that memcpy is redefined as `mempcpy',
+ and the return value is the byte after the last one copied in
+ the destination. */
+#define MEMPCPY_P (defined memcpy)
+
+ .text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__memcpy_chk)
+ cmpq %rdx, %rcx
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memcpy_chk)
+#endif
+ENTRY (BP_SYM (memcpy))
+ /* Cutoff for the big loop is a size of 32 bytes since otherwise
+ the loop will never be entered. */
+ cmpq $32, %rdx
+ movq %rdx, %rcx
+#if !MEMPCPY_P
+ movq %rdi, %r10 /* Save value. */
+#endif
+
+ /* We need this in any case. */
+ cld
+
+ jbe 1f
+
+ /* Align destination. */
+ movq %rdi, %rax
+ negq %rax
+ andq $7, %rax
+ subq %rax, %rcx
+ xchgq %rax, %rcx
+
+ rep; movsb
+
+ movq %rax, %rcx
+ subq $32, %rcx
+ js 2f
+
+ .p2align 4
+3:
+
+ /* Now correct the loop counter. Please note that in the following
+ code the flags are not changed anymore. */
+ subq $32, %rcx
+
+ movq (%rsi), %rax
+ movq 8(%rsi), %rdx
+ movq 16(%rsi), %r8
+ movq 24(%rsi), %r9
+ movq %rax, (%rdi)
+ movq %rdx, 8(%rdi)
+ movq %r8, 16(%rdi)
+ movq %r9, 24(%rdi)
+
+ leaq 32(%rsi), %rsi
+ leaq 32(%rdi), %rdi
+
+ jns 3b
+
+ /* Correct extra loop counter modification. */
+2: addq $32, %rcx
+1: rep; movsb
+
+#if MEMPCPY_P
+ movq %rdi, %rax /* Set return value. */
+#else
+ movq %r10, %rax /* Set return value. */
+
+#endif
+ ret
+
+END (BP_SYM (memcpy))
+#if !MEMPCPY_P
+libc_hidden_builtin_def (memcpy)
+#endif
diff --git a/libc/sysdeps/x86_64/memcpy_chk.S b/libc/sysdeps/x86_64/memcpy_chk.S
new file mode 100644
index 000000000..c5251ea2d
--- /dev/null
+++ b/libc/sysdeps/x86_64/memcpy_chk.S
@@ -0,0 +1,34 @@
+/* Checking memcpy for x86-64.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memcpy.S.
+ For libc.a, this is a separate source to avoid
+ memcpy bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memcpy_chk)
+ cmpq %rdx, %rcx
+ jb __chk_fail
+ jmp memcpy
+END (__memcpy_chk)
+#endif
diff --git a/libc/sysdeps/x86_64/mempcpy.S b/libc/sysdeps/x86_64/mempcpy.S
new file mode 100644
index 000000000..4558a1699
--- /dev/null
+++ b/libc/sysdeps/x86_64/mempcpy.S
@@ -0,0 +1,7 @@
+#define memcpy __mempcpy
+#define __memcpy_chk __mempcpy_chk
+#include <sysdeps/x86_64/memcpy.S>
+
+libc_hidden_def (BP_SYM (__mempcpy))
+weak_alias (BP_SYM (__mempcpy), BP_SYM (mempcpy))
+libc_hidden_builtin_def (mempcpy)
diff --git a/libc/sysdeps/x86_64/mempcpy_chk.S b/libc/sysdeps/x86_64/mempcpy_chk.S
new file mode 100644
index 000000000..c333a4adb
--- /dev/null
+++ b/libc/sysdeps/x86_64/mempcpy_chk.S
@@ -0,0 +1,34 @@
+/* Checking mempcpy for x86-64.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memcpy.S.
+ For libc.a, this is a separate source to avoid
+ mempcpy bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__mempcpy_chk)
+ cmpq %rdx, %rcx
+ jb __chk_fail
+ jmp mempcpy
+END (__mempcpy_chk)
+#endif
diff --git a/libc/sysdeps/x86_64/memset.S b/libc/sysdeps/x86_64/memset.S
new file mode 100644
index 000000000..1c421c75f
--- /dev/null
+++ b/libc/sysdeps/x86_64/memset.S
@@ -0,0 +1,146 @@
+/* memset/bzero -- set memory area to CH/0
+ Optimized version for x86-64.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+/* BEWARE: `#ifdef memset' means that memset is redefined as `bzero' */
+#define BZERO_P (defined memset)
+
+/* This is somehow experimental and could made dependend on the cache
+ size. */
+#define LARGE $120000
+
+ .text
+#if !BZERO_P && defined PIC && !defined NOT_IN_libc
+ENTRY (__memset_chk)
+ cmpq %rdx, %rcx
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memset_chk)
+#endif
+ENTRY (memset)
+#if BZERO_P
+ mov %rsi,%rdx /* Adjust parameter. */
+ xorl %esi,%esi /* Fill with 0s. */
+#endif
+ cmp $0x7,%rdx /* Check for small length. */
+ mov %rdi,%rcx /* Save ptr as return value. */
+ jbe 7f
+
+#if BZERO_P
+ mov %rsi,%r8 /* Just copy 0. */
+#else
+ /* Populate 8 bit data to full 64-bit. */
+ movabs $0x0101010101010101,%r8
+ movzbl %sil,%eax
+ imul %rax,%r8
+#endif
+ test $0x7,%edi /* Check for alignment. */
+ je 2f
+
+ .p2align 4
+1: /* Align ptr to 8 byte. */
+ mov %sil,(%rcx)
+ dec %rdx
+ inc %rcx
+ test $0x7,%ecx
+ jne 1b
+
+2: /* Check for really large regions. */
+ mov %rdx,%rax
+ shr $0x6,%rax
+ je 4f
+ cmp LARGE, %rdx
+ jae 11f
+
+ .p2align 4
+3: /* Copy 64 bytes. */
+ mov %r8,(%rcx)
+ mov %r8,0x8(%rcx)
+ mov %r8,0x10(%rcx)
+ mov %r8,0x18(%rcx)
+ mov %r8,0x20(%rcx)
+ mov %r8,0x28(%rcx)
+ mov %r8,0x30(%rcx)
+ mov %r8,0x38(%rcx)
+ add $0x40,%rcx
+ dec %rax
+ jne 3b
+
+4: /* Copy final bytes. */
+ and $0x3f,%edx
+ mov %rdx,%rax
+ shr $0x3,%rax
+ je 6f
+
+5: /* First in chunks of 8 bytes. */
+ mov %r8,(%rcx)
+ add $0x8,%rcx
+ dec %rax
+ jne 5b
+6:
+ and $0x7,%edx
+7:
+ test %rdx,%rdx
+ je 9f
+8: /* And finally as bytes (up to 7). */
+ mov %sil,(%rcx)
+ inc %rcx
+ dec %rdx
+ jne 8b
+9:
+#if BZERO_P
+ nop
+#else
+ /* Load result (only if used as memset). */
+ mov %rdi,%rax /* start address of destination is result */
+#endif
+ retq
+
+ .p2align 4
+11: /* Copy 64 bytes without polluting the cache. */
+ /* We could use movntdq %xmm0,(%rcx) here to further
+ speed up for large cases but let's not use XMM registers. */
+ movnti %r8,(%rcx)
+ movnti %r8,0x8(%rcx)
+ movnti %r8,0x10(%rcx)
+ movnti %r8,0x18(%rcx)
+ movnti %r8,0x20(%rcx)
+ movnti %r8,0x28(%rcx)
+ movnti %r8,0x30(%rcx)
+ movnti %r8,0x38(%rcx)
+ add $0x40,%rcx
+ dec %rax
+ jne 11b
+ jmp 4b
+
+END (memset)
+#if !BZERO_P
+libc_hidden_builtin_def (memset)
+#endif
+
+#if !BZERO_P && defined PIC && !defined NOT_IN_libc
+strong_alias (__memset_chk, __memset_zero_constant_len_parameter)
+ .section .gnu.warning.__memset_zero_constant_len_parameter
+ .string "memset used with constant zero length parameter; this could be due to transposed parameters"
+#endif
diff --git a/libc/sysdeps/x86_64/memset_chk.S b/libc/sysdeps/x86_64/memset_chk.S
new file mode 100644
index 000000000..c1c8c23f9
--- /dev/null
+++ b/libc/sysdeps/x86_64/memset_chk.S
@@ -0,0 +1,34 @@
+/* Checking memset for x86-64.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memset.S.
+ For libc.a, this is a separate source to avoid
+ memset bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memset_chk)
+ cmpq %rdx, %rcx
+ jb __chk_fail
+ jmp memset
+END (__memset_chk)
+#endif
diff --git a/libc/sysdeps/x86_64/memusage.h b/libc/sysdeps/x86_64/memusage.h
new file mode 100644
index 000000000..d267cf573
--- /dev/null
+++ b/libc/sysdeps/x86_64/memusage.h
@@ -0,0 +1,22 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("rsp"); stack_ptr; })
+#define GETTIME(low,high) asm ("rdtsc" : "=a" (low), "=d" (high))
+
+#include <sysdeps/generic/memusage.h>
diff --git a/libc/sysdeps/x86_64/setjmp.S b/libc/sysdeps/x86_64/setjmp.S
new file mode 100644
index 000000000..a66b0e61e
--- /dev/null
+++ b/libc/sysdeps/x86_64/setjmp.S
@@ -0,0 +1,62 @@
+/* setjmp for x86-64.
+ Copyright (C) 2001, 2003, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+#include <asm-syntax.h>
+
+ENTRY (__sigsetjmp)
+ /* Save registers. */
+ movq %rbx, (JB_RBX*8)(%rdi)
+#ifdef PTR_MANGLE
+ movq %rbp, %rax
+ PTR_MANGLE (%rax)
+ movq %rax, (JB_RBP*8)(%rdi)
+#else
+ movq %rbp, (JB_RBP*8)(%rdi)
+#endif
+ movq %r12, (JB_R12*8)(%rdi)
+ movq %r13, (JB_R13*8)(%rdi)
+ movq %r14, (JB_R14*8)(%rdi)
+ movq %r15, (JB_R15*8)(%rdi)
+ leaq 8(%rsp), %rdx /* Save SP as it will be after we return. */
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%rdx)
+#endif
+ movq %rdx, (JB_RSP*8)(%rdi)
+ movq (%rsp), %rax /* Save PC we are returning to now. */
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%rax)
+#endif
+ movq %rax, (JB_PC*8)(%rdi)
+
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ /* In ld.so we never save the signal mask. */
+ xorl %eax, %eax
+ retq
+#else
+ /* Make a tail call to __sigjmp_save; it takes the same args. */
+# ifdef PIC
+ jmp C_SYMBOL_NAME (BP_SYM (__sigjmp_save))@PLT
+# else
+ jmp BP_SYM (__sigjmp_save)
+# endif
+#endif
+END (BP_SYM (__sigsetjmp))
+hidden_def (__sigsetjmp)
diff --git a/libc/sysdeps/x86_64/soft-fp/sfp-machine.h b/libc/sysdeps/x86_64/soft-fp/sfp-machine.h
new file mode 100644
index 000000000..77df02380
--- /dev/null
+++ b/libc/sysdeps/x86_64/soft-fp/sfp-machine.h
@@ -0,0 +1,51 @@
+#define _FP_W_TYPE_SIZE 64
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+#define __FP_CLZ(r, x) \
+ do { \
+ __asm__("bsrq %1,%0" : "=r"(r) : "g"(x) : "cc"); \
+ r ^= 63; \
+ } while (0)
+
+#define _FP_NANFRAC_S _FP_QNANBIT_S
+#define _FP_NANFRAC_D _FP_QNANBIT_D, 0
+#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S 1
+#define _FP_NANSIGN_D 1
+#define _FP_NANSIGN_Q 1
+
+#define _FP_KEEPNANFRACP 1
+/* Here is something Intel misdesigned: the specs don't define
+ the case where we have two NaNs with same mantissas, but
+ different sign. Different operations pick up different NaNs.
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if (_FP_FRAC_GT_##wc(X, Y) \
+ || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ } \
+ else \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,Y); \
+ } \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+#define FP_EX_INVALID (1 << 0)
+#define FP_EX_DENORM (1 << 1)
+#define FP_EX_DIVZERO (1 << 2)
+#define FP_EX_OVERFLOW (1 << 3)
+#define FP_EX_UNDERFLOW (1 << 4)
+#define FP_EX_INEXACT (1 << 5)
+
+#define FP_RND_NEAREST 0
+#define FP_RND_ZERO 3
+#define FP_RND_PINF 2
+#define FP_RND_MINF 1
+
diff --git a/libc/sysdeps/x86_64/stackinfo.h b/libc/sysdeps/x86_64/stackinfo.h
new file mode 100644
index 000000000..60668d10b
--- /dev/null
+++ b/libc/sysdeps/x86_64/stackinfo.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file contains a bit of information about the stack allocation
+ of the processor. */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H 1
+
+/* On x86_64 the stack grows down. */
+#define _STACK_GROWS_DOWN 1
+
+#endif /* stackinfo.h */
diff --git a/libc/sysdeps/x86_64/stpcpy.S b/libc/sysdeps/x86_64/stpcpy.S
new file mode 100644
index 000000000..ec23de141
--- /dev/null
+++ b/libc/sysdeps/x86_64/stpcpy.S
@@ -0,0 +1,8 @@
+#define USE_AS_STPCPY
+#define STRCPY __stpcpy
+
+#include <sysdeps/x86_64/strcpy.S>
+
+weak_alias (__stpcpy, stpcpy)
+libc_hidden_def (__stpcpy)
+libc_hidden_builtin_def (stpcpy)
diff --git a/libc/sysdeps/x86_64/stpcpy_chk.S b/libc/sysdeps/x86_64/stpcpy_chk.S
new file mode 100644
index 000000000..905e8d7ee
--- /dev/null
+++ b/libc/sysdeps/x86_64/stpcpy_chk.S
@@ -0,0 +1,3 @@
+#define USE_AS_STPCPY_CHK
+#define STRCPY_CHK __stpcpy_chk
+#include <sysdeps/x86_64/strcpy_chk.S>
diff --git a/libc/sysdeps/x86_64/strcat.S b/libc/sysdeps/x86_64/strcat.S
new file mode 100644
index 000000000..11b266969
--- /dev/null
+++ b/libc/sysdeps/x86_64/strcat.S
@@ -0,0 +1,260 @@
+/* strcat(dest, src) -- Append SRC on the end of DEST.
+ Optimized for x86-64.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+
+ .text
+ENTRY (BP_SYM (strcat))
+ movq %rdi, %rcx /* Dest. register. */
+ andl $7, %ecx /* mask alignment bits */
+ movq %rdi, %rax /* Duplicate destination pointer. */
+ movq $0xfefefefefefefeff,%r8
+
+ /* First step: Find end of destination. */
+ jz 4f /* aligned => start loop */
+
+ neg %ecx /* We need to align to 8 bytes. */
+ addl $8,%ecx
+ /* Search the first bytes directly. */
+0: cmpb $0x0,(%rax) /* is byte NUL? */
+ je 2f /* yes => start copy */
+ incq %rax /* increment pointer */
+ decl %ecx
+ jnz 0b
+
+
+
+ /* Now the source is aligned. Scan for NUL byte. */
+ .p2align 4
+4:
+ /* First unroll. */
+ movq (%rax), %rcx /* get double word (= 8 bytes) in question */
+ addq $8,%rax /* adjust pointer for next word */
+ movq %r8, %rdx /* magic value */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 3f /* found NUL => return pointer */
+
+ /* Second unroll. */
+ movq (%rax), %rcx /* get double word (= 8 bytes) in question */
+ addq $8,%rax /* adjust pointer for next word */
+ movq %r8, %rdx /* magic value */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 3f /* found NUL => return pointer */
+
+ /* Third unroll. */
+ movq (%rax), %rcx /* get double word (= 8 bytes) in question */
+ addq $8,%rax /* adjust pointer for next word */
+ movq %r8, %rdx /* magic value */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 3f /* found NUL => return pointer */
+
+ /* Fourth unroll. */
+ movq (%rax), %rcx /* get double word (= 8 bytes) in question */
+ addq $8,%rax /* adjust pointer for next word */
+ movq %r8, %rdx /* magic value */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jz 4b /* no NUL found => continue loop */
+
+ .p2align 4 /* Align, it's a jump target. */
+3: subq $8,%rax /* correct pointer increment. */
+
+ testb %cl, %cl /* is first byte NUL? */
+ jz 2f /* yes => return */
+ incq %rax /* increment pointer */
+
+ testb %ch, %ch /* is second byte NUL? */
+ jz 2f /* yes => return */
+ incq %rax /* increment pointer */
+
+ testl $0x00ff0000, %ecx /* is third byte NUL? */
+ jz 2f /* yes => return pointer */
+ incq %rax /* increment pointer */
+
+ testl $0xff000000, %ecx /* is fourth byte NUL? */
+ jz 2f /* yes => return pointer */
+ incq %rax /* increment pointer */
+
+ shrq $32, %rcx /* look at other half. */
+
+ testb %cl, %cl /* is first byte NUL? */
+ jz 2f /* yes => return */
+ incq %rax /* increment pointer */
+
+ testb %ch, %ch /* is second byte NUL? */
+ jz 2f /* yes => return */
+ incq %rax /* increment pointer */
+
+ testl $0xff0000, %ecx /* is third byte NUL? */
+ jz 2f /* yes => return pointer */
+ incq %rax /* increment pointer */
+
+2:
+ /* Second step: Copy source to destination. */
+
+ movq %rsi, %rcx /* duplicate */
+ andl $7,%ecx /* mask alignment bits */
+ movq %rax, %rdx /* move around */
+ jz 22f /* aligned => start loop */
+
+ neg %ecx /* align to 8 bytes. */
+ addl $8, %ecx
+ /* Align the source pointer. */
+21:
+ movb (%rsi), %al /* Fetch a byte */
+ testb %al, %al /* Is it NUL? */
+ movb %al, (%rdx) /* Store it */
+ jz 24f /* If it was NUL, done! */
+ incq %rsi
+ incq %rdx
+ decl %ecx
+ jnz 21b
+
+ /* Now the sources is aligned. Unfortunatly we cannot force
+ to have both source and destination aligned, so ignore the
+ alignment of the destination. */
+ .p2align 4
+22:
+ /* 1st unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 23f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 23f /* found NUL => return pointer */
+
+ movq %rax, (%rdx) /* Write value to destination. */
+ addq $8, %rdx /* Adjust pointer. */
+
+ /* 2nd unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 23f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 23f /* found NUL => return pointer */
+
+ movq %rax, (%rdx) /* Write value to destination. */
+ addq $8, %rdx /* Adjust pointer. */
+
+ /* 3rd unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 23f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 23f /* found NUL => return pointer */
+
+ movq %rax, (%rdx) /* Write value to destination. */
+ addq $8, %rdx /* Adjust pointer. */
+
+ /* 4th unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 23f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 23f /* found NUL => return pointer */
+
+ movq %rax, (%rdx) /* Write value to destination. */
+ addq $8, %rdx /* Adjust pointer. */
+ jmp 22b /* Next iteration. */
+
+ /* Do the last few bytes. %rax contains the value to write.
+ The loop is unrolled twice. */
+ .p2align 4
+23:
+ movb %al, (%rdx) /* 1st byte. */
+ testb %al, %al /* Is it NUL. */
+ jz 24f /* yes, finish. */
+ incq %rdx /* Increment destination. */
+ movb %ah, (%rdx) /* 2nd byte. */
+ testb %ah, %ah /* Is it NUL?. */
+ jz 24f /* yes, finish. */
+ incq %rdx /* Increment destination. */
+ shrq $16, %rax /* Shift... */
+ jmp 23b /* and look at next two bytes in %rax. */
+
+
+24:
+ movq %rdi, %rax /* Source is return value. */
+ retq
+END (BP_SYM (strcat))
+libc_hidden_builtin_def (strcat)
diff --git a/libc/sysdeps/x86_64/strchr.S b/libc/sysdeps/x86_64/strchr.S
new file mode 100644
index 000000000..893469797
--- /dev/null
+++ b/libc/sysdeps/x86_64/strchr.S
@@ -0,0 +1,291 @@
+/* strchr (str, ch) -- Return pointer to first occurrence of CH in STR.
+ For AMD x86-64.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+
+ .text
+ENTRY (BP_SYM (strchr))
+
+ /* Before we start with the main loop we process single bytes
+ until the source pointer is aligned. This has two reasons:
+ 1. aligned 64-bit memory access is faster
+ and (more important)
+ 2. we process in the main loop 64 bit in one step although
+ we don't know the end of the string. But accessing at
+ 8-byte alignment guarantees that we never access illegal
+ memory if this would not also be done by the trivial
+ implementation (this is because all processor inherent
+ boundaries are multiples of 8). */
+
+ movq %rdi, %rdx
+ andl $7, %edx /* Mask alignment bits */
+ movq %rdi, %rax /* duplicate destination. */
+ jz 1f /* aligned => start loop */
+ neg %edx
+ addl $8, %edx /* Align to 8 bytes. */
+
+ /* Search the first bytes directly. */
+0: movb (%rax), %cl /* load byte */
+ cmpb %cl,%sil /* compare byte. */
+ je 6f /* target found */
+ testb %cl,%cl /* is byte NUL? */
+ je 7f /* yes => return NULL */
+ incq %rax /* increment pointer */
+ decl %edx
+ jnz 0b
+
+
+1:
+ /* At the moment %rsi contains C. What we need for the
+ algorithm is C in all bytes of the register. Avoid
+ operations on 16 bit words because these require an
+ prefix byte (and one more cycle). */
+ /* Populate 8 bit data to full 64-bit. */
+ movabs $0x0101010101010101,%r9
+ movzbl %sil,%edx
+ imul %rdx,%r9
+
+ movq $0xfefefefefefefeff, %r8 /* Save magic. */
+
+ /* We exit the loop if adding MAGIC_BITS to LONGWORD fails to
+ change any of the hole bits of LONGWORD.
+
+ 1) Is this safe? Will it catch all the zero bytes?
+ Suppose there is a byte with all zeros. Any carry bits
+ propagating from its left will fall into the hole at its
+ least significant bit and stop. Since there will be no
+ carry from its most significant bit, the LSB of the
+ byte to the left will be unchanged, and the zero will be
+ detected.
+
+ 2) Is this worthwhile? Will it ignore everything except
+ zero bytes? Suppose every byte of QUARDWORD has a bit set
+ somewhere. There will be a carry into bit 8. If bit 8
+ is set, this will carry into bit 16. If bit 8 is clear,
+ one of bits 9-15 must be set, so there will be a carry
+ into bit 16. Similarly, there will be a carry into bit
+ 24 tec.. If one of bits 54-63 is set, there will be a carry
+ into bit 64 (=carry flag), so all of the hole bits will
+ be changed.
+
+ 3) But wait! Aren't we looking for C, not zero?
+ Good point. So what we do is XOR LONGWORD with a longword,
+ each of whose bytes is C. This turns each byte that is C
+ into a zero. */
+
+ .p2align 4
+4:
+ /* Main Loop is unrolled 4 times. */
+ /* First unroll. */
+ movq (%rax), %rcx /* get double word (= 8 bytes) in question */
+ addq $8,%rax /* adjust pointer for next word */
+ movq %r8, %rdx /* magic value */
+ xorq %r9, %rcx /* XOR with qword c|...|c => bytes of str == c
+ are now 0 */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 3f /* found c => return pointer */
+
+ /* The quadword we looked at does not contain the value we're looking
+ for. Let's search now whether we have reached the end of the
+ string. */
+ xorq %r9, %rcx /* restore original dword without reload */
+ movq %r8, %rdx /* magic value */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 7f /* highest byte is NUL => return NULL */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 7f /* found NUL => return NULL */
+
+ /* Second unroll. */
+ movq (%rax), %rcx /* get double word (= 8 bytes) in question */
+ addq $8,%rax /* adjust pointer for next word */
+ movq %r8, %rdx /* magic value */
+ xorq %r9, %rcx /* XOR with qword c|...|c => bytes of str == c
+ are now 0 */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 3f /* found c => return pointer */
+
+ /* The quadword we looked at does not contain the value we're looking
+ for. Let's search now whether we have reached the end of the
+ string. */
+ xorq %r9, %rcx /* restore original dword without reload */
+ movq %r8, %rdx /* magic value */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 7f /* highest byte is NUL => return NULL */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 7f /* found NUL => return NULL */
+ /* Third unroll. */
+ movq (%rax), %rcx /* get double word (= 8 bytes) in question */
+ addq $8,%rax /* adjust pointer for next word */
+ movq %r8, %rdx /* magic value */
+ xorq %r9, %rcx /* XOR with qword c|...|c => bytes of str == c
+ are now 0 */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 3f /* found c => return pointer */
+
+ /* The quadword we looked at does not contain the value we're looking
+ for. Let's search now whether we have reached the end of the
+ string. */
+ xorq %r9, %rcx /* restore original dword without reload */
+ movq %r8, %rdx /* magic value */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 7f /* highest byte is NUL => return NULL */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 7f /* found NUL => return NULL */
+ /* Fourth unroll. */
+ movq (%rax), %rcx /* get double word (= 8 bytes) in question */
+ addq $8,%rax /* adjust pointer for next word */
+ movq %r8, %rdx /* magic value */
+ xorq %r9, %rcx /* XOR with qword c|...|c => bytes of str == c
+ are now 0 */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 3f /* found c => return pointer */
+
+ /* The quadword we looked at does not contain the value we're looking
+ for. Let's search now whether we have reached the end of the
+ string. */
+ xorq %r9, %rcx /* restore original dword without reload */
+ movq %r8, %rdx /* magic value */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 7f /* highest byte is NUL => return NULL */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jz 4b /* no NUL found => restart loop */
+
+
+7: /* Return NULL. */
+ xorl %eax, %eax
+ retq
+
+
+ /* We now scan for the byte in which the character was matched.
+ But we have to take care of the case that a NUL char is
+ found before this in the dword. Note that we XORed %rcx
+ with the byte we're looking for, therefore the tests below look
+ reversed. */
+
+
+ .p2align 4 /* Align, it's a jump target. */
+3: movq %r9,%rdx /* move to %rdx so that we can access bytes */
+ subq $8,%rax /* correct pointer increment. */
+ testb %cl, %cl /* is first byte C? */
+ jz 6f /* yes => return pointer */
+ cmpb %dl, %cl /* is first byte NUL? */
+ je 7b /* yes => return NULL */
+ incq %rax /* increment pointer */
+
+ testb %ch, %ch /* is second byte C? */
+ jz 6f /* yes => return pointer */
+ cmpb %dl, %ch /* is second byte NUL? */
+ je 7b /* yes => return NULL? */
+ incq %rax /* increment pointer */
+
+ shrq $16, %rcx /* make upper bytes accessible */
+ testb %cl, %cl /* is third byte C? */
+ jz 6f /* yes => return pointer */
+ cmpb %dl, %cl /* is third byte NUL? */
+ je 7b /* yes => return NULL */
+ incq %rax /* increment pointer */
+
+ testb %ch, %ch /* is fourth byte C? */
+ jz 6f /* yes => return pointer */
+ cmpb %dl, %ch /* is fourth byte NUL? */
+ je 7b /* yes => return NULL? */
+ incq %rax /* increment pointer */
+
+ shrq $16, %rcx /* make upper bytes accessible */
+ testb %cl, %cl /* is fifth byte C? */
+ jz 6f /* yes => return pointer */
+ cmpb %dl, %cl /* is fifth byte NUL? */
+ je 7b /* yes => return NULL */
+ incq %rax /* increment pointer */
+
+ testb %ch, %ch /* is sixth byte C? */
+ jz 6f /* yes => return pointer */
+ cmpb %dl, %ch /* is sixth byte NUL? */
+ je 7b /* yes => return NULL? */
+ incq %rax /* increment pointer */
+
+ shrq $16, %rcx /* make upper bytes accessible */
+ testb %cl, %cl /* is seventh byte C? */
+ jz 6f /* yes => return pointer */
+ cmpb %dl, %cl /* is seventh byte NUL? */
+ je 7b /* yes => return NULL */
+
+ /* It must be in the eigth byte and it cannot be NUL. */
+ incq %rax
+
+6:
+ nop
+ retq
+END (BP_SYM (strchr))
+
+weak_alias (BP_SYM (strchr), BP_SYM (index))
+libc_hidden_builtin_def (strchr)
diff --git a/libc/sysdeps/x86_64/strcmp.S b/libc/sysdeps/x86_64/strcmp.S
new file mode 100644
index 000000000..119b88e40
--- /dev/null
+++ b/libc/sysdeps/x86_64/strcmp.S
@@ -0,0 +1,45 @@
+/* Highly optimized version for x86-64.
+ Copyright (C) 1999, 2000, 2002, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Based on i686 version contributed by Ulrich Drepper
+ <drepper@cygnus.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+ .text
+ENTRY (BP_SYM (strcmp))
+L(oop): movb (%rdi), %al
+ cmpb (%rsi), %al
+ jne L(neq)
+ incq %rdi
+ incq %rsi
+ testb %al, %al
+ jnz L(oop)
+
+ xorl %eax, %eax
+ ret
+
+L(neq): movl $1, %eax
+ movl $-1, %ecx
+ cmovbl %ecx, %eax
+ ret
+END (BP_SYM (strcmp))
+libc_hidden_builtin_def (strcmp)
diff --git a/libc/sysdeps/x86_64/strcpy.S b/libc/sysdeps/x86_64/strcpy.S
new file mode 100644
index 000000000..a76787a13
--- /dev/null
+++ b/libc/sysdeps/x86_64/strcpy.S
@@ -0,0 +1,159 @@
+/* strcpy/stpcpy implementation for x86-64.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#ifndef USE_AS_STPCPY
+# define STRCPY strcpy
+#endif
+
+ .text
+ENTRY (BP_SYM (STRCPY))
+ movq %rsi, %rcx /* Source register. */
+ andl $7, %ecx /* mask alignment bits */
+ movq %rdi, %rdx /* Duplicate destination pointer. */
+
+ jz 5f /* aligned => start loop */
+
+ neg %ecx /* We need to align to 8 bytes. */
+ addl $8,%ecx
+ /* Search the first bytes directly. */
+0:
+ movb (%rsi), %al /* Fetch a byte */
+ testb %al, %al /* Is it NUL? */
+ movb %al, (%rdx) /* Store it */
+ jz 4f /* If it was NUL, done! */
+ incq %rsi
+ incq %rdx
+ decl %ecx
+ jnz 0b
+
+5:
+ movq $0xfefefefefefefeff,%r8
+
+ /* Now the sources is aligned. Unfortunatly we cannot force
+ to have both source and destination aligned, so ignore the
+ alignment of the destination. */
+ .p2align 4
+1:
+ /* 1st unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ movq %rax, (%rdx) /* Write value to destination. */
+ addq $8, %rdx /* Adjust pointer. */
+
+ /* 2nd unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ movq %rax, (%rdx) /* Write value to destination. */
+ addq $8, %rdx /* Adjust pointer. */
+
+ /* 3rd unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ movq %rax, (%rdx) /* Write value to destination. */
+ addq $8, %rdx /* Adjust pointer. */
+
+ /* 4th unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ movq %rax, (%rdx) /* Write value to destination. */
+ addq $8, %rdx /* Adjust pointer. */
+ jmp 1b /* Next iteration. */
+
+ /* Do the last few bytes. %rax contains the value to write.
+ The loop is unrolled twice. */
+ .p2align 4
+3:
+ /* Note that stpcpy needs to return with the value of the NUL
+ byte. */
+ movb %al, (%rdx) /* 1st byte. */
+ testb %al, %al /* Is it NUL. */
+ jz 4f /* yes, finish. */
+ incq %rdx /* Increment destination. */
+ movb %ah, (%rdx) /* 2nd byte. */
+ testb %ah, %ah /* Is it NUL?. */
+ jz 4f /* yes, finish. */
+ incq %rdx /* Increment destination. */
+ shrq $16, %rax /* Shift... */
+ jmp 3b /* and look at next two bytes in %rax. */
+
+4:
+#ifdef USE_AS_STPCPY
+ movq %rdx, %rax /* Destination is return value. */
+#else
+ movq %rdi, %rax /* Source is return value. */
+#endif
+ retq
+END (BP_SYM (STRCPY))
+#ifndef USE_AS_STPCPY
+libc_hidden_builtin_def (strcpy)
+#endif
diff --git a/libc/sysdeps/x86_64/strcpy_chk.S b/libc/sysdeps/x86_64/strcpy_chk.S
new file mode 100644
index 000000000..364331553
--- /dev/null
+++ b/libc/sysdeps/x86_64/strcpy_chk.S
@@ -0,0 +1,211 @@
+/* strcpy/stpcpy checking implementation for x86-64.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2002.
+ Adopted into checking version by Jakub Jelinek <jakub@redhat.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#ifndef USE_AS_STPCPY_CHK
+# define STRCPY_CHK __strcpy_chk
+#endif
+
+ .text
+ENTRY (STRCPY_CHK)
+ movq %rsi, %rcx /* Source register. */
+ andl $7, %ecx /* mask alignment bits */
+#ifndef USE_AS_STPCPY_CHK
+ movq %rdi, %r10 /* Duplicate destination pointer. */
+#endif
+ jz 5f /* aligned => start loop */
+
+ cmpq $8, %rdx /* Check if only few bytes left in
+ destination. */
+ jb 50f
+
+ subq $8, %rcx /* We need to align to 8 bytes. */
+ addq %rcx, %rdx /* Subtract count of stored bytes
+ in the cycle below from destlen. */
+
+ /* Search the first bytes directly. */
+0:
+ movb (%rsi), %al /* Fetch a byte */
+ testb %al, %al /* Is it NUL? */
+ movb %al, (%rdi) /* Store it */
+ jz 4f /* If it was NUL, done! */
+ incq %rsi
+ incq %rdi
+ incl %ecx
+ jnz 0b
+
+5:
+ movq $0xfefefefefefefeff,%r8
+ cmpq $32, %rdx /* Are there enough bytes in destination
+ for the next unrolled round? */
+ jb 60f /* If not, avoid the unrolled loop. */
+
+ /* Now the sources is aligned. Unfortunatly we cannot force
+ to have both source and destination aligned, so ignore the
+ alignment of the destination. */
+ .p2align 4
+1:
+ /* 1st unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ movq %rax, (%rdi) /* Write value to destination. */
+ addq $8, %rdi /* Adjust pointer. */
+
+ /* 2nd unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ movq %rax, (%rdi) /* Write value to destination. */
+ addq $8, %rdi /* Adjust pointer. */
+
+ /* 3rd unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ movq %rax, (%rdi) /* Write value to destination. */
+ addq $8, %rdi /* Adjust pointer. */
+
+ /* 4th unroll. */
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ subq $32, %rdx /* Adjust destlen. */
+ movq %rax, (%rdi) /* Write value to destination. */
+ addq $8, %rdi /* Adjust pointer. */
+ cmpq $32, %rdx /* Are there enough bytes in destination
+ for the next unrolled round? */
+ jae 1b /* Next iteration. */
+
+60:
+ cmpq $8, %rdx /* Are there enough bytes in destination
+ for the next unrolled round? */
+ jb 50f /* Now, copy and check byte by byte. */
+
+ movq (%rsi), %rax /* Read double word (8 bytes). */
+ addq $8, %rsi /* Adjust pointer for next word. */
+ movq %rax, %r9 /* Save a copy for NUL finding. */
+ addq %r8, %r9 /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rax, %r9 /* (word+magic)^word */
+ orq %r8, %r9 /* set all non-carry bits */
+ incq %r9 /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+
+ jnz 3f /* found NUL => return pointer */
+
+ subq $8, %rdx /* Adjust destlen. */
+ movq %rax, (%rdi) /* Write value to destination. */
+ addq $8, %rdi /* Adjust pointer. */
+ jmp 60b /* Next iteration. */
+
+ /* Do the last few bytes. %rax contains the value to write.
+ The loop is unrolled twice. */
+ .p2align 4
+3:
+ /* Note that stpcpy needs to return with the value of the NUL
+ byte. */
+ movb %al, (%rdi) /* 1st byte. */
+ testb %al, %al /* Is it NUL. */
+ jz 4f /* yes, finish. */
+ incq %rdi /* Increment destination. */
+ movb %ah, (%rdi) /* 2nd byte. */
+ testb %ah, %ah /* Is it NUL?. */
+ jz 4f /* yes, finish. */
+ incq %rdi /* Increment destination. */
+ shrq $16, %rax /* Shift... */
+ jmp 3b /* and look at next two bytes in %rax. */
+
+51:
+ /* Search the bytes directly, checking for overflows. */
+ incq %rsi
+ incq %rdi
+ decq %rdx
+ jz HIDDEN_JUMPTARGET (__chk_fail)
+52:
+ movb (%rsi), %al /* Fetch a byte */
+ testb %al, %al /* Is it NUL? */
+ movb %al, (%rdi) /* Store it */
+ jnz 51b /* If it was NUL, done! */
+4:
+#ifdef USE_AS_STPCPY_CHK
+ movq %rdi, %rax /* Destination is return value. */
+#else
+ movq %r10, %rax /* Source is return value. */
+#endif
+ retq
+
+50:
+ testq %rdx, %rdx
+ jnz 52b
+ jmp HIDDEN_JUMPTARGET (__chk_fail)
+
+END (STRCPY_CHK)
diff --git a/libc/sysdeps/x86_64/strcspn.S b/libc/sysdeps/x86_64/strcspn.S
new file mode 100644
index 000000000..467201388
--- /dev/null
+++ b/libc/sysdeps/x86_64/strcspn.S
@@ -0,0 +1,127 @@
+/* strcspn (str, ss) -- Return the length of the initial segment of STR
+ which contains no characters from SS.
+ For AMD x86-64.
+ Copyright (C) 1994-1997, 2000, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>.
+ Bug fixes by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>.
+ Adopted for x86-64 by Andreas Jaeger <aj@suse.de>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+/* BEWARE: `#ifdef strcspn' means that strcspn is redefined as `strpbrk' */
+#define STRPBRK_P (defined strcspn)
+
+ .text
+ENTRY (strcspn)
+
+ movq %rdi, %rdx /* Save SRC. */
+
+ /* First we create a table with flags for all possible characters.
+ For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
+ supported by the C string functions we have 256 characters.
+ Before inserting marks for the stop characters we clear the whole
+ table. */
+ movq %rdi, %r8 /* Save value. */
+ subq $256, %rsp /* Make space for 256 bytes. */
+ cfi_adjust_cfa_offset(256)
+ movl $32, %ecx /* 32*8 bytes = 256 bytes. */
+ movq %rsp, %rdi
+ xorl %eax, %eax /* We store 0s. */
+ cld
+ rep
+ stosq
+
+ movq %rsi, %rax /* Setup skipset. */
+
+/* For understanding the following code remember that %rcx == 0 now.
+ Although all the following instruction only modify %cl we always
+ have a correct zero-extended 64-bit value in %rcx. */
+
+ .p2align 4
+L(2): movb (%rax), %cl /* get byte from skipset */
+ testb %cl, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%rsp,%rcx) /* set corresponding byte in skipset table */
+
+ movb 1(%rax), %cl /* get byte from skipset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%rsp,%rcx) /* set corresponding byte in skipset table */
+
+ movb 2(%rax), %cl /* get byte from skipset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%rsp,%rcx) /* set corresponding byte in skipset table */
+
+ movb 3(%rax), %cl /* get byte from skipset */
+ addq $4, %rax /* increment skipset pointer */
+ movb %cl, (%rsp,%rcx) /* set corresponding byte in skipset table */
+ testb $0xff, %cl /* is NUL char? */
+ jnz L(2) /* no => process next dword from skipset */
+
+L(1): leaq -4(%rdx), %rax /* prepare loop */
+
+ /* We use a neat trick for the following loop. Normally we would
+ have to test for two termination conditions
+ 1. a character in the skipset was found
+ and
+ 2. the end of the string was found
+ But as a sign that the character is in the skipset we store its
+ value in the table. But the value of NUL is NUL so the loop
+ terminates for NUL in every case. */
+
+ .p2align 4
+L(3): addq $4, %rax /* adjust pointer for full loop round */
+
+ movb (%rax), %cl /* get byte from string */
+ cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */
+ je L(4) /* yes => return */
+
+ movb 1(%rax), %cl /* get byte from string */
+ cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */
+ je L(5) /* yes => return */
+
+ movb 2(%rax), %cl /* get byte from string */
+ cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */
+ jz L(6) /* yes => return */
+
+ movb 3(%rax), %cl /* get byte from string */
+ cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */
+ jne L(3) /* no => start loop again */
+
+ incq %rax /* adjust pointer */
+L(6): incq %rax
+L(5): incq %rax
+
+L(4): addq $256, %rsp /* remove skipset */
+ cfi_adjust_cfa_offset(-256)
+#if STRPBRK_P
+ xorl %edx,%edx
+ orb %cl, %cl /* was last character NUL? */
+ cmovzq %rdx, %rax /* Yes: return NULL */
+#else
+ subq %rdx, %rax /* we have to return the number of valid
+ characters, so compute distance to first
+ non-valid character */
+#endif
+ ret
+END (strcspn)
+libc_hidden_builtin_def (strcspn)
diff --git a/libc/sysdeps/x86_64/strlen.S b/libc/sysdeps/x86_64/strlen.S
new file mode 100644
index 000000000..fd950edaa
--- /dev/null
+++ b/libc/sysdeps/x86_64/strlen.S
@@ -0,0 +1,139 @@
+/* strlen(str) -- determine the length of the string STR.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Based on i486 version contributed by Ulrich Drepper <drepper@redhat.com>.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+
+ .text
+ENTRY (strlen)
+ movq %rdi, %rcx /* Duplicate source pointer. */
+ andl $7, %ecx /* mask alignment bits */
+ movq %rdi, %rax /* duplicate destination. */
+ jz 1f /* aligned => start loop */
+
+ neg %ecx /* We need to align to 8 bytes. */
+ addl $8,%ecx
+ /* Search the first bytes directly. */
+0: cmpb $0x0,(%rax) /* is byte NUL? */
+ je 2f /* yes => return */
+ incq %rax /* increment pointer */
+ decl %ecx
+ jnz 0b
+
+1: movq $0xfefefefefefefeff,%r8 /* Save magic. */
+
+ .p2align 4 /* Align loop. */
+4: /* Main Loop is unrolled 4 times. */
+ /* First unroll. */
+ movq (%rax), %rcx /* get double word (= 8 bytes) in question */
+ addq $8,%rax /* adjust pointer for next word */
+ movq %r8, %rdx /* magic value */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 3f /* found NUL => return pointer */
+
+ /* Second unroll. */
+ movq (%rax), %rcx /* get double word (= 8 bytes) in question */
+ addq $8,%rax /* adjust pointer for next word */
+ movq %r8, %rdx /* magic value */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 3f /* found NUL => return pointer */
+
+ /* Third unroll. */
+ movq (%rax), %rcx /* get double word (= 8 bytes) in question */
+ addq $8,%rax /* adjust pointer for next word */
+ movq %r8, %rdx /* magic value */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jnz 3f /* found NUL => return pointer */
+
+ /* Fourth unroll. */
+ movq (%rax), %rcx /* get double word (= 8 bytes) in question */
+ addq $8,%rax /* adjust pointer for next word */
+ movq %r8, %rdx /* magic value */
+ addq %rcx, %rdx /* add the magic value to the word. We get
+ carry bits reported for each byte which
+ is *not* 0 */
+ jnc 3f /* highest byte is NUL => return pointer */
+ xorq %rcx, %rdx /* (word+magic)^word */
+ orq %r8, %rdx /* set all non-carry bits */
+ incq %rdx /* add 1: if one carry bit was *not* set
+ the addition will not result in 0. */
+ jz 4b /* no NUL found => continue loop */
+
+ .p2align 4 /* Align, it's a jump target. */
+3: subq $8,%rax /* correct pointer increment. */
+
+ testb %cl, %cl /* is first byte NUL? */
+ jz 2f /* yes => return */
+ incq %rax /* increment pointer */
+
+ testb %ch, %ch /* is second byte NUL? */
+ jz 2f /* yes => return */
+ incq %rax /* increment pointer */
+
+ testl $0x00ff0000, %ecx /* is third byte NUL? */
+ jz 2f /* yes => return pointer */
+ incq %rax /* increment pointer */
+
+ testl $0xff000000, %ecx /* is fourth byte NUL? */
+ jz 2f /* yes => return pointer */
+ incq %rax /* increment pointer */
+
+ shrq $32, %rcx /* look at other half. */
+
+ testb %cl, %cl /* is first byte NUL? */
+ jz 2f /* yes => return */
+ incq %rax /* increment pointer */
+
+ testb %ch, %ch /* is second byte NUL? */
+ jz 2f /* yes => return */
+ incq %rax /* increment pointer */
+
+ testl $0xff0000, %ecx /* is third byte NUL? */
+ jz 2f /* yes => return pointer */
+ incq %rax /* increment pointer */
+2:
+ subq %rdi, %rax /* compute difference to string start */
+ ret
+END (strlen)
+libc_hidden_builtin_def (strlen)
diff --git a/libc/sysdeps/x86_64/strpbrk.S b/libc/sysdeps/x86_64/strpbrk.S
new file mode 100644
index 000000000..9b97ada84
--- /dev/null
+++ b/libc/sysdeps/x86_64/strpbrk.S
@@ -0,0 +1,2 @@
+#define strcspn strpbrk
+#include <sysdeps/x86_64/strcspn.S>
diff --git a/libc/sysdeps/x86_64/strspn.S b/libc/sysdeps/x86_64/strspn.S
new file mode 100644
index 000000000..54aac18d6
--- /dev/null
+++ b/libc/sysdeps/x86_64/strspn.S
@@ -0,0 +1,117 @@
+/* strspn (str, ss) -- Return the length of the initial segment of STR
+ which contains only characters from SS.
+ For AMD x86-64.
+ Copyright (C) 1994-1997, 2000, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>.
+ Bug fixes by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>.
+ Adopted for x86-64 by Andreas Jaeger <aj@suse.de>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY (strspn)
+
+ movq %rdi, %rdx /* Save SRC. */
+
+ /* First we create a table with flags for all possible characters.
+ For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
+ supported by the C string functions we have 256 characters.
+ Before inserting marks for the stop characters we clear the whole
+ table. */
+ movq %rdi, %r8 /* Save value. */
+ subq $256, %rsp /* Make space for 256 bytes. */
+ cfi_adjust_cfa_offset(256)
+ movl $32, %ecx /* 32*8 bytes = 256 bytes. */
+ movq %rsp, %rdi
+ xorl %eax, %eax /* We store 0s. */
+ cld
+ rep
+ stosq
+
+ movq %rsi, %rax /* Setup stopset. */
+
+/* For understanding the following code remember that %rcx == 0 now.
+ Although all the following instruction only modify %cl we always
+ have a correct zero-extended 64-bit value in %rcx. */
+
+ .p2align 4
+L(2): movb (%rax), %cl /* get byte from stopset */
+ testb %cl, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */
+
+ movb 1(%rax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */
+
+ movb 2(%rax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */
+
+ movb 3(%rax), %cl /* get byte from stopset */
+ addq $4, %rax /* increment stopset pointer */
+ movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */
+ testb $0xff, %cl /* is NUL char? */
+ jnz L(2) /* no => process next dword from stopset */
+
+L(1): leaq -4(%rdx), %rax /* prepare loop */
+
+ /* We use a neat trick for the following loop. Normally we would
+ have to test for two termination conditions
+ 1. a character in the stopset was found
+ and
+ 2. the end of the string was found
+ But as a sign that the character is in the stopset we store its
+ value in the table. But the value of NUL is NUL so the loop
+ terminates for NUL in every case. */
+
+ .p2align 4
+L(3): addq $4, %rax /* adjust pointer for full loop round */
+
+ movb (%rax), %cl /* get byte from string */
+ testb %cl, (%rsp,%rcx) /* is it contained in skipset? */
+ jz L(4) /* no => return */
+
+ movb 1(%rax), %cl /* get byte from string */
+ testb %cl, (%rsp,%rcx) /* is it contained in skipset? */
+ jz L(5) /* no => return */
+
+ movb 2(%rax), %cl /* get byte from string */
+ testb %cl, (%rsp,%rcx) /* is it contained in skipset? */
+ jz L(6) /* no => return */
+
+ movb 3(%rax), %cl /* get byte from string */
+ testb %cl, (%rsp,%rcx) /* is it contained in skipset? */
+ jnz L(3) /* yes => start loop again */
+
+ incq %rax /* adjust pointer */
+L(6): incq %rax
+L(5): incq %rax
+
+L(4): addq $256, %rsp /* remove stopset */
+ cfi_adjust_cfa_offset(-256)
+ subq %rdx, %rax /* we have to return the number of valid
+ characters, so compute distance to first
+ non-valid character */
+ ret
+END (strspn)
+libc_hidden_builtin_def (strspn)
diff --git a/libc/sysdeps/x86_64/strtok.S b/libc/sysdeps/x86_64/strtok.S
new file mode 100644
index 000000000..4037f0b85
--- /dev/null
+++ b/libc/sysdeps/x86_64/strtok.S
@@ -0,0 +1,212 @@
+/* strtok (str, delim) -- Return next DELIM separated token from STR.
+ For AMD x86-64.
+ Copyright (C) 1998,2000-2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Based on i686 version contributed by Ulrich Drepper
+ <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+/* This file can be used for the strtok and strtok_r functions:
+
+ strtok:
+ INPUT PARAMETER:
+ str %rdi
+ delim %rsi
+
+ strtok_r:
+ INPUT PARAMETER:
+ str %rdi
+ delim %rsi
+ save_ptr %rdx
+
+ We do a common implementation here. */
+
+#ifdef USE_AS_STRTOK_R
+# define SAVE_PTR (%r9)
+#else
+ .bss
+ .local save_ptr
+ ASM_TYPE_DIRECTIVE (save_ptr, @object)
+ .size save_ptr, 8
+save_ptr:
+ .space 8
+
+# ifdef PIC
+# define SAVE_PTR save_ptr(%rip)
+# else
+# define SAVE_PTR save_ptr
+# endif
+
+# define FUNCTION strtok
+#endif
+
+ .text
+ENTRY (BP_SYM (FUNCTION))
+ /* First we create a table with flags for all possible characters.
+ For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
+ supported by the C string functions we have 256 characters.
+ Before inserting marks for the stop characters we clear the whole
+ table. */
+ movq %rdi, %r8 /* Save value. */
+ subq $256, %rsp /* Make space for 256 bytes. */
+ cfi_adjust_cfa_offset(256)
+ movl $32, %ecx /* 32*8 bytes = 256 bytes. */
+ movq %rsp, %rdi
+ xorl %eax, %eax /* We store 0s. */
+ cld
+ rep
+ stosq
+
+ /* Note: %rcx = 0 !!! */
+
+#ifdef USE_AS_STRTOK_R
+ /* The value is stored in the third argument. */
+ movq %rdx, %rax
+ movq %rdx, %r9 /* Save value - see def. of SAVE_PTR. */
+ movq (%rax), %rax
+#else
+ /* The value is in the local variable defined above. But
+ we have to take care for PIC code. */
+ movq SAVE_PTR, %rax
+#endif
+ movq %r8, %rdx /* Get start of string. */
+
+ /* If the pointer is NULL we have to use the stored value of
+ the last run. */
+ cmpq $0, %rdx
+ cmove %rax, %rdx
+ testq %rdx, %rdx
+ jz L(returnNULL)
+ movq %rsi, %rax /* Get start of delimiter set. */
+
+/* For understanding the following code remember that %rcx == 0 now.
+ Although all the following instruction only modify %cl we always
+ have a correct zero-extended 64-bit value in %rcx. */
+
+L(2): movb (%rax), %cl /* get byte from stopset */
+ testb %cl, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */
+
+ movb 1(%rax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */
+
+ movb 2(%rax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1) /* yes => start compare loop */
+ movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */
+
+ movb 3(%rax), %cl /* get byte from stopset */
+ addq $4, %rax /* increment stopset pointer */
+ movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */
+ testb $0xff, %cl /* is NUL char? */
+ jnz L(2) /* no => process next dword from stopset */
+
+L(1):
+
+ leaq -4(%rdx), %rax /* prepare loop */
+
+ /* We use a neat trick for the following loop. Normally we would
+ have to test for two termination conditions
+ 1. a character in the stopset was found
+ and
+ 2. the end of the string was found
+ As a sign that the character is in the stopset we store its
+ value in the table. The value of NUL is NUL so the loop
+ terminates for NUL in every case. */
+
+L(3): addq $4, %rax /* adjust pointer for full loop round */
+
+ movb (%rax), %cl /* get byte from string */
+ testb %cl, (%rsp,%rcx) /* is it contained in stopset? */
+ jz L(4) /* no => start of token */
+
+ movb 1(%rax), %cl /* get byte from string */
+ testb %cl, (%rsp,%rcx) /* is it contained in stopset? */
+ jz L(5) /* no => start of token */
+
+ movb 2(%rax), %cl /* get byte from string */
+ testb %cl, (%rsp,%rcx) /* is it contained in stopset? */
+ jz L(6) /* no => start of token */
+
+ movb 3(%rax), %cl /* get byte from string */
+ testb %cl, (%rsp,%rcx) /* is it contained in stopset? */
+ jnz L(3) /* yes => start of loop */
+
+ incq %rax /* adjust pointer */
+L(6): incq %rax
+L(5): incq %rax
+
+ /* Now we have to terminate the string. */
+
+L(4): leaq -4(%rax), %rdx /* We use %rDX for the next run. */
+
+L(7): addq $4, %rdx /* adjust pointer for full loop round */
+
+ movb (%rdx), %cl /* get byte from string */
+ cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */
+ je L(8) /* yes => return */
+
+ movb 1(%rdx), %cl /* get byte from string */
+ cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */
+ je L(9) /* yes => return */
+
+ movb 2(%rdx), %cl /* get byte from string */
+ cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */
+ je L(10) /* yes => return */
+
+ movb 3(%rdx), %cl /* get byte from string */
+ cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */
+ jne L(7) /* no => start loop again */
+
+ incq %rdx /* adjust pointer */
+L(10): incq %rdx
+L(9): incq %rdx
+
+L(8): cmpq %rax, %rdx
+ je L(returnNULL) /* There was no token anymore. */
+
+ movb $0, (%rdx) /* Terminate string. */
+
+ /* Are we at end of string? */
+ cmpb $0, %cl
+ leaq 1(%rdx), %rcx
+ cmovne %rcx, %rdx
+
+ /* Store the pointer to the next character. */
+ movq %rdx, SAVE_PTR
+
+L(epilogue):
+ /* Remove the stopset table. */
+ addq $256, %rsp
+ cfi_adjust_cfa_offset(-256)
+ retq
+
+L(returnNULL):
+ xorl %eax, %eax
+ /* Store the pointer to the next character. */
+ movq %rdx, SAVE_PTR
+ jmp L(epilogue)
+
+END (BP_SYM (FUNCTION))
diff --git a/libc/sysdeps/x86_64/strtok_r.S b/libc/sysdeps/x86_64/strtok_r.S
new file mode 100644
index 000000000..8ce0089c7
--- /dev/null
+++ b/libc/sysdeps/x86_64/strtok_r.S
@@ -0,0 +1,5 @@
+#define FUNCTION __strtok_r
+#define USE_AS_STRTOK_R 1
+#include <sysdeps/x86_64/strtok.S>
+weak_alias (BP_SYM (__strtok_r), BP_SYM (strtok_r))
+strong_alias (BP_SYM (__strtok_r), BP_SYM (__GI___strtok_r))
diff --git a/libc/sysdeps/x86_64/sysdep.h b/libc/sysdeps/x86_64/sysdep.h
new file mode 100644
index 000000000..122270f91
--- /dev/null
+++ b/libc/sysdeps/x86_64/sysdep.h
@@ -0,0 +1,114 @@
+/* Assembler macros for x86-64.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdeps/generic/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+/* Syntactic details of assembler. */
+
+#ifdef HAVE_ELF
+
+/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */
+#define ALIGNARG(log2) 1<<log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
+
+/* In ELF C symbols are asm symbols. */
+#undef NO_UNDERSCORES
+#define NO_UNDERSCORES
+
+#else
+
+#define ALIGNARG(log2) log2
+#define ASM_TYPE_DIRECTIVE(name,type) /* Nothing is specified. */
+#define ASM_SIZE_DIRECTIVE(name) /* Nothing is specified. */
+
+#endif
+
+
+/* Define an entry point visible from C. */
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(4); \
+ C_LABEL(name) \
+ cfi_startproc; \
+ CALL_MCOUNT
+
+#undef END
+#define END(name) \
+ cfi_endproc; \
+ ASM_SIZE_DIRECTIVE(name)
+
+/* If compiled for profiling, call `mcount' at the start of each function. */
+#ifdef PROF
+/* The mcount code relies on a normal frame pointer being on the stack
+ to locate our caller, so push one just for its benefit. */
+#define CALL_MCOUNT \
+ pushq %rbp; \
+ cfi_adjust_cfa_offset(8); \
+ movq %rsp, %rbp; \
+ cfi_def_cfa_register(%rbp); \
+ call JUMPTARGET(mcount); \
+ popq %rbp; \
+ cfi_def_cfa(rsp,8);
+#else
+#define CALL_MCOUNT /* Do nothing. */
+#endif
+
+#ifdef NO_UNDERSCORES
+/* Since C identifiers are not normally prefixed with an underscore
+ on this system, the asm identifier `syscall_error' intrudes on the
+ C name space. Make sure we use an innocuous name. */
+#define syscall_error __syscall_error
+#define mcount _mcount
+#endif
+
+#define PSEUDO(name, syscall_name, args) \
+lose: \
+ jmp JUMPTARGET(syscall_error) \
+ .globl syscall_error; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ jb lose
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
+
+#undef JUMPTARGET
+#ifdef PIC
+#define JUMPTARGET(name) name##@PLT
+#else
+#define JUMPTARGET(name) name
+#endif
+
+/* Local label name for asm code. */
+#ifndef L
+# ifdef HAVE_ELF
+/* ELF-like local names start with `.L'. */
+# define L(name) .L##name
+# else
+# define L(name) name
+# endif
+#endif
+
+#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/x86_64/tst-stack-align.h b/libc/sysdeps/x86_64/tst-stack-align.h
new file mode 100644
index 000000000..a89f092c5
--- /dev/null
+++ b/libc/sysdeps/x86_64/tst-stack-align.h
@@ -0,0 +1,47 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#define TEST_STACK_ALIGN() \
+ ({ \
+ /* AMD64 ABI mandates 16byte aligned stack. \
+ Unfortunately, current GCC doesn't support __int128 or __float128 \
+ types, so use aligned attribute instead. */ \
+ struct _S \
+ { \
+ int _i __attribute__((aligned (16))); \
+ int _pad[3]; \
+ } _s = { ._i = 18 }; \
+ double _d = 12.0; \
+ long double _ld = 15.0; \
+ int _ret = 0; \
+ printf ("__int128: %d %p %zu\n", _s._i, &_s, __alignof (_s)); \
+ if ((((uintptr_t) &_s) & (__alignof (_s) - 1)) != 0) \
+ _ret = 1; \
+ \
+ printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
+ if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
+ _ret = 1; \
+ \
+ printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
+ if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
+ _ret = 1; \
+ _ret; \
+ })